From 35b7b1f1a61c61cc5c2b1beaa5ecd02b5d402d07 Mon Sep 17 00:00:00 2001 From: mathusummut Date: Sun, 6 May 2018 00:01:36 +0200 Subject: [PATCH] Fixed the god-awful indentation --- source/g3d_viewer/main.cpp | 4549 ++-- source/g3d_viewer/main.h | 329 +- source/g3d_viewer/renderer.cpp | 1004 +- source/g3d_viewer/renderer.h | 242 +- source/glest_game/ai/ai.cpp | 4032 ++-- source/glest_game/ai/ai.h | 693 +- source/glest_game/ai/ai_interface.cpp | 2959 ++- source/glest_game/ai/ai_interface.h | 528 +- source/glest_game/ai/ai_rule.cpp | 6862 +++--- source/glest_game/ai/ai_rule.h | 1221 +- source/glest_game/ai/path_finder.cpp | 3930 ++- source/glest_game/ai/path_finder.h | 1349 +- source/glest_game/facilities/auto_test.cpp | 155 +- source/glest_game/facilities/auto_test.h | 88 +- source/glest_game/facilities/components.cpp | 2153 +- source/glest_game/facilities/components.h | 1062 +- source/glest_game/facilities/game_util.cpp | 626 +- source/glest_game/facilities/game_util.h | 51 +- source/glest_game/facilities/logger.cpp | 579 +- source/glest_game/facilities/logger.h | 132 +- source/glest_game/game/chat_manager.cpp | 1480 +- source/glest_game/game/chat_manager.h | 376 +- source/glest_game/game/commander.cpp | 3804 ++- source/glest_game/game/commander.h | 296 +- source/glest_game/game/console.cpp | 514 +- source/glest_game/game/console.h | 467 +- source/glest_game/game/game.cpp | 19847 ++++++++-------- source/glest_game/game/game.h | 1035 +- source/glest_game/game/game_camera.cpp | 1540 +- source/glest_game/game/game_camera.h | 378 +- source/glest_game/game/game_constants.h | 599 +- source/glest_game/game/game_settings.h | 3288 ++- source/glest_game/game/script_manager.cpp | 13539 +++++------ source/glest_game/game/script_manager.h | 2109 +- source/glest_game/game/stats.cpp | 630 +- source/glest_game/game/stats.h | 680 +- source/glest_game/global/config.cpp | 2131 +- source/glest_game/global/config.h | 225 +- source/glest_game/global/core_data.cpp | 3623 ++- source/glest_game/global/core_data.h | 567 +- source/glest_game/global/lang.cpp | 1859 +- source/glest_game/global/lang.h | 148 +- source/glest_game/global/metrics.cpp | 167 +- source/glest_game/global/metrics.h | 154 +- source/glest_game/graphics/particle_type.cpp | 1112 +- source/glest_game/graphics/particle_type.h | 246 +- source/glest_game/graphics/renderer.cpp | 19722 ++++++++------- source/glest_game/graphics/renderer.h | 1242 +- .../graphics/unit_particle_type.cpp | 665 +- .../glest_game/graphics/unit_particle_type.h | 135 +- source/glest_game/gui/display.cpp | 313 +- source/glest_game/gui/display.h | 200 +- source/glest_game/gui/gui.cpp | 2501 +- source/glest_game/gui/gui.h | 378 +- source/glest_game/gui/selection.cpp | 761 +- source/glest_game/gui/selection.h | 164 +- source/glest_game/main/battle_end.cpp | 2076 +- source/glest_game/main/battle_end.h | 96 +- source/glest_game/main/intro.cpp | 2079 +- source/glest_game/main/intro.h | 266 +- source/glest_game/main/main.cpp | 16763 ++++++------- source/glest_game/main/main.h | 156 +- source/glest_game/main/program.cpp | 3015 ++- source/glest_game/main/program.h | 773 +- source/glest_game/menu/main_menu.cpp | 1371 +- source/glest_game/menu/main_menu.h | 255 +- source/glest_game/menu/menu_background.cpp | 489 +- source/glest_game/menu/menu_background.h | 356 +- source/glest_game/menu/menu_state_about.cpp | 626 +- source/glest_game/menu/menu_state_about.h | 80 +- .../menu/menu_state_connected_game.cpp | 17216 +++++++------- .../menu/menu_state_connected_game.h | 601 +- .../menu/menu_state_custom_game.cpp | 13237 +++++------ .../glest_game/menu/menu_state_custom_game.h | 749 +- .../menu/menu_state_custom_game_update.cpp | 2372 +- .../menu/menu_state_graphic_info.cpp | 308 +- .../glest_game/menu/menu_state_graphic_info.h | 76 +- .../glest_game/menu/menu_state_join_game.cpp | 1918 +- source/glest_game/menu/menu_state_join_game.h | 163 +- .../glest_game/menu/menu_state_keysetup.cpp | 1587 +- source/glest_game/menu/menu_state_keysetup.h | 129 +- .../glest_game/menu/menu_state_load_game.cpp | 972 +- source/glest_game/menu/menu_state_load_game.h | 98 +- .../menu/menu_state_masterserver.cpp | 3505 ++- .../glest_game/menu/menu_state_masterserver.h | 218 +- source/glest_game/menu/menu_state_mods.cpp | 7561 +++--- source/glest_game/menu/menu_state_mods.h | 330 +- .../glest_game/menu/menu_state_new_game.cpp | 270 +- source/glest_game/menu/menu_state_new_game.h | 50 +- source/glest_game/menu/menu_state_options.cpp | 2842 ++- source/glest_game/menu/menu_state_options.h | 158 +- .../menu/menu_state_options_graphics.cpp | 2157 +- .../menu/menu_state_options_graphics.h | 162 +- .../menu/menu_state_options_network.cpp | 1178 +- .../menu/menu_state_options_network.h | 106 +- .../menu/menu_state_options_sound.cpp | 870 +- .../menu/menu_state_options_sound.h | 86 +- source/glest_game/menu/menu_state_root.cpp | 2085 +- source/glest_game/menu/menu_state_root.h | 110 +- .../glest_game/menu/menu_state_scenario.cpp | 1276 +- source/glest_game/menu/menu_state_scenario.h | 109 +- source/glest_game/menu/server_line.cpp | 534 +- source/glest_game/menu/server_line.h | 102 +- .../glest_game/network/client_interface.cpp | 4094 ++-- source/glest_game/network/client_interface.h | 299 +- source/glest_game/network/connection_slot.cpp | 2794 ++- source/glest_game/network/connection_slot.h | 591 +- source/glest_game/network/masterserver_info.h | 194 +- .../glest_game/network/network_interface.cpp | 1065 +- source/glest_game/network/network_interface.h | 831 +- source/glest_game/network/network_manager.cpp | 227 +- source/glest_game/network/network_manager.h | 52 +- source/glest_game/network/network_message.cpp | 6712 +++--- source/glest_game/network/network_message.h | 1982 +- .../glest_game/network/network_protocol.cpp | 1061 +- source/glest_game/network/network_protocol.h | 10 +- source/glest_game/network/network_types.cpp | 327 +- source/glest_game/network/network_types.h | 254 +- .../glest_game/network/server_interface.cpp | 6095 +++-- source/glest_game/network/server_interface.h | 522 +- source/glest_game/sound/sound_container.cpp | 48 +- source/glest_game/sound/sound_container.h | 62 +- source/glest_game/sound/sound_renderer.cpp | 447 +- source/glest_game/sound/sound_renderer.h | 116 +- source/glest_game/steam/steam.cpp | 568 +- source/glest_game/steam/steam.h | 155 +- source/glest_game/steamshim/steamshim_child.c | 592 +- source/glest_game/steamshim/steamshim_child.h | 78 +- source/glest_game/type_instances/command.cpp | 457 +- source/glest_game/type_instances/command.h | 190 +- source/glest_game/type_instances/faction.cpp | 6488 +++-- source/glest_game/type_instances/faction.h | 959 +- source/glest_game/type_instances/object.cpp | 636 +- source/glest_game/type_instances/object.h | 233 +- source/glest_game/type_instances/resource.cpp | 251 +- source/glest_game/type_instances/resource.h | 86 +- source/glest_game/type_instances/unit.cpp | 15300 ++++++------ source/glest_game/type_instances/unit.h | 2155 +- source/glest_game/type_instances/upgrade.cpp | 595 +- source/glest_game/type_instances/upgrade.h | 307 +- source/glest_game/types/command_type.cpp | 3013 ++- source/glest_game/types/command_type.h | 1320 +- source/glest_game/types/damage_multiplier.cpp | 179 +- source/glest_game/types/damage_multiplier.h | 154 +- source/glest_game/types/element_type.cpp | 367 +- source/glest_game/types/element_type.h | 214 +- source/glest_game/types/faction_type.cpp | 2907 ++- source/glest_game/types/faction_type.h | 374 +- source/glest_game/types/object_type.cpp | 106 +- source/glest_game/types/object_type.h | 132 +- source/glest_game/types/projectile_type.cpp | 261 +- source/glest_game/types/projectile_type.h | 184 +- source/glest_game/types/resource_type.cpp | 562 +- source/glest_game/types/resource_type.h | 164 +- source/glest_game/types/skill_type.cpp | 3824 ++- source/glest_game/types/skill_type.h | 1395 +- source/glest_game/types/tech_tree.cpp | 1418 +- source/glest_game/types/tech_tree.h | 215 +- .../glest_game/types/tileset_model_type.cpp | 57 +- source/glest_game/types/tileset_model_type.h | 156 +- source/glest_game/types/unit_type.cpp | 3516 ++- source/glest_game/types/unit_type.h | 982 +- source/glest_game/types/upgrade_type.cpp | 4699 ++-- source/glest_game/types/upgrade_type.h | 921 +- source/glest_game/world/map.cpp | 3622 ++- source/glest_game/world/map.h | 1264 +- source/glest_game/world/minimap.cpp | 515 +- source/glest_game/world/minimap.h | 116 +- source/glest_game/world/scenario.cpp | 1186 +- source/glest_game/world/scenario.h | 239 +- source/glest_game/world/surface_atlas.cpp | 213 +- source/glest_game/world/surface_atlas.h | 116 +- source/glest_game/world/tileset.cpp | 1013 +- source/glest_game/world/tileset.h | 408 +- source/glest_game/world/time_flow.cpp | 288 +- source/glest_game/world/time_flow.h | 86 +- source/glest_game/world/unit_updater.cpp | 6221 +++-- source/glest_game/world/unit_updater.h | 270 +- source/glest_game/world/water_effects.cpp | 92 +- source/glest_game/world/water_effects.h | 100 +- source/glest_game/world/world.cpp | 5783 +++-- source/glest_game/world/world.h | 580 +- source/glest_map_editor/main.cpp | 3037 ++- source/glest_map_editor/main.h | 586 +- source/glest_map_editor/program.cpp | 1181 +- source/glest_map_editor/program.h | 237 +- .../include/compression/compression_utils.h | 14 +- source/shared_lib/include/feathery_ftp/ftp.h | 37 +- .../include/feathery_ftp/ftpConfig.h | 80 +- .../shared_lib/include/feathery_ftp/ftpIfc.h | 20 +- .../include/feathery_ftp/ftpTypes.h | 30 +- .../shared_lib/include/graphics/BMPReader.h | 16 +- .../shared_lib/include/graphics/FileReader.h | 639 +- .../include/graphics/ImageReaders.h | 26 +- .../shared_lib/include/graphics/JPGReader.h | 16 +- .../shared_lib/include/graphics/PNGReader.h | 26 +- .../shared_lib/include/graphics/TGAReader.h | 26 +- source/shared_lib/include/graphics/buffer.h | 80 +- source/shared_lib/include/graphics/camera.h | 62 +- source/shared_lib/include/graphics/context.h | 99 +- source/shared_lib/include/graphics/font.h | 233 +- .../include/graphics/font_manager.h | 44 +- .../shared_lib/include/graphics/font_text.h | 5 +- .../include/graphics/gl/base_renderer.h | 28 +- .../include/graphics/gl/context_gl.h | 49 +- .../shared_lib/include/graphics/gl/font_gl.h | 78 +- .../include/graphics/gl/font_textFTGL.h | 57 +- .../graphics/gl/graphics_factory_basic_gl.h | 52 +- .../include/graphics/gl/graphics_factory_gl.h | 96 +- .../shared_lib/include/graphics/gl/model_gl.h | 32 +- .../include/graphics/gl/model_renderer_gl.h | 56 +- .../shared_lib/include/graphics/gl/opengl.h | 84 +- .../graphics/gl/particle_renderer_gl.h | 58 +- .../include/graphics/gl/shader_gl.h | 142 +- .../include/graphics/gl/text_renderer_gl.h | 157 +- .../include/graphics/gl/texture_gl.h | 192 +- .../include/graphics/graphics_factory.h | 161 +- .../include/graphics/graphics_interface.h | 102 +- .../include/graphics/interpolation.h | 58 +- .../shared_lib/include/graphics/math_util.h | 528 +- source/shared_lib/include/graphics/matrix.h | 254 +- source/shared_lib/include/graphics/model.h | 626 +- .../include/graphics/model_header.h | 154 +- .../include/graphics/model_manager.h | 48 +- .../include/graphics/model_renderer.h | 92 +- source/shared_lib/include/graphics/particle.h | 1435 +- .../include/graphics/particle_renderer.h | 35 +- source/shared_lib/include/graphics/pixmap.h | 669 +- .../shared_lib/include/graphics/quaternion.h | 154 +- source/shared_lib/include/graphics/shader.h | 110 +- .../include/graphics/shader_manager.h | 50 +- .../include/graphics/text_renderer.h | 61 +- source/shared_lib/include/graphics/texture.h | 339 +- .../include/graphics/texture_manager.h | 76 +- source/shared_lib/include/graphics/vec.h | 1489 +- .../include/graphics/video_player.h | 107 +- source/shared_lib/include/lua/lua_script.h | 140 +- source/shared_lib/include/map/map_preview.h | 408 +- .../include/platform/common/base_thread.h | 239 +- .../include/platform/common/byte_order.h | 108 +- .../include/platform/common/cache_manager.h | 186 +- .../platform/common/common_scoped_ptr.h | 2 +- .../include/platform/common/platform_common.h | 460 +- .../include/platform/common/simple_threads.h | 269 +- .../include/platform/common/streflop_cond.h | 2 +- .../include/platform/miniupnpc/bsdqueue.h | 178 +- .../include/platform/miniupnpc/codelength.h | 32 +- .../platform/miniupnpc/connecthostport.h | 8 +- .../include/platform/miniupnpc/declspec.h | 12 +- .../platform/miniupnpc/igd_desc_parse.h | 4 +- .../include/platform/miniupnpc/minisoap.h | 4 +- .../include/platform/miniupnpc/minissdpc.h | 36 +- .../include/platform/miniupnpc/miniupnpc.h | 200 +- .../platform/miniupnpc/miniupnpc_declspec.h | 24 +- .../platform/miniupnpc/miniupnpcstrings.h | 2 +- .../include/platform/miniupnpc/miniwget.h | 8 +- .../include/platform/miniupnpc/minixml.h | 12 +- .../platform/miniupnpc/portlistingparse.h | 80 +- .../include/platform/miniupnpc/receivedata.h | 10 +- .../include/platform/miniupnpc/upnpcommands.h | 588 +- .../include/platform/miniupnpc/upnpdev.h | 22 +- .../include/platform/miniupnpc/upnperrors.h | 8 +- .../platform/miniupnpc/upnpreplyparse.h | 64 +- .../include/platform/posix/ircclient.h | 198 +- .../include/platform/posix/miniftpclient.h | 224 +- .../include/platform/posix/miniftpserver.h | 73 +- .../include/platform/posix/socket.h | 527 +- .../shared_lib/include/platform/sdl/gl_wrap.h | 88 +- .../include/platform/sdl/platform_main.h | 447 +- .../include/platform/sdl/sdl_private.h | 14 +- .../shared_lib/include/platform/sdl/thread.h | 944 +- .../shared_lib/include/platform/sdl/window.h | 481 +- .../include/platform/sdl/window_gl.h | 70 +- .../shared_lib/include/platform/win32/glob.h | 99 +- .../platform/win32/platform_definitions.h | 6 +- source/shared_lib/include/sound/sound.h | 192 +- .../shared_lib/include/sound/sound_factory.h | 25 +- .../include/sound/sound_factory_none.h | 22 +- .../include/sound/sound_file_loader.h | 143 +- .../include/sound/sound_interface.h | 46 +- .../shared_lib/include/sound/sound_player.h | 71 +- source/shared_lib/include/streflop/FPUCheck.h | 49 +- .../shared_lib/include/streflop/FPUSettings.h | 721 +- .../include/streflop/IntegerTypes.h | 182 +- source/shared_lib/include/streflop/Random.h | 330 +- source/shared_lib/include/streflop/SMath.h | 1309 +- .../include/streflop/SoftFloatWrapper.h | 336 +- source/shared_lib/include/streflop/System.h | 34 +- .../include/streflop/X87DenormalSquasher.h | 169 +- source/shared_lib/include/streflop/streflop.h | 84 +- .../shared_lib/include/streflop/streflopC.h | 12 +- source/shared_lib/include/util/checksum.h | 66 +- source/shared_lib/include/util/conversion.h | 42 +- source/shared_lib/include/util/factory.h | 111 +- source/shared_lib/include/util/gen_uuid.h | 557 +- source/shared_lib/include/util/leak_dumper.h | 258 +- source/shared_lib/include/util/profiler.h | 112 +- source/shared_lib/include/util/properties.h | 170 +- source/shared_lib/include/util/randomgen.h | 62 +- source/shared_lib/include/util/string_utils.h | 81 +- source/shared_lib/include/util/util.h | 444 +- source/shared_lib/include/xml/xml_parser.h | 308 +- .../sources/compression/compression_utils.cpp | 563 +- .../sources/feathery_ftp/ftpAccount.c | 77 +- .../shared_lib/sources/feathery_ftp/ftpCmds.c | 1062 +- .../shared_lib/sources/feathery_ftp/ftpLib.c | 111 +- .../sources/feathery_ftp/ftpRuntime.c | 155 +- .../sources/feathery_ftp/ftpServer.c | 7 +- .../sources/feathery_ftp/ftpSession.c | 269 +- .../sources/feathery_ftp/ftpTargetPosix.c | 374 +- .../sources/feathery_ftp/ftpTargetWin32.c | 407 +- .../shared_lib/sources/graphics/BMPReader.cpp | 337 +- .../sources/graphics/ImageReaders.cpp | 32 +- .../shared_lib/sources/graphics/JPGReader.cpp | 408 +- .../shared_lib/sources/graphics/PNGReader.cpp | 676 +- .../shared_lib/sources/graphics/TGAReader.cpp | 660 +- source/shared_lib/sources/graphics/buffer.cpp | 98 +- source/shared_lib/sources/graphics/camera.cpp | 60 +- .../shared_lib/sources/graphics/context.cpp | 28 +- source/shared_lib/sources/graphics/font.cpp | 1126 +- .../sources/graphics/font_manager.cpp | 114 +- .../shared_lib/sources/graphics/font_text.cpp | 35 +- .../sources/graphics/gl/base_renderer.cpp | 365 +- .../sources/graphics/gl/context_gl.cpp | 52 +- .../sources/graphics/gl/font_gl.cpp | 118 +- .../sources/graphics/gl/font_textFTGL.cpp | 760 +- .../sources/graphics/gl/model_gl.cpp | 20 +- .../sources/graphics/gl/model_renderer_gl.cpp | 697 +- .../shared_lib/sources/graphics/gl/opengl.cpp | 296 +- .../graphics/gl/particle_renderer_gl.cpp | 545 +- .../sources/graphics/gl/shader_gl.cpp | 456 +- .../sources/graphics/gl/text_renderer_gl.cpp | 1251 +- .../sources/graphics/gl/texture_gl.cpp | 2505 +- .../sources/graphics/graphics_interface.cpp | 42 +- .../sources/graphics/interpolation.cpp | 181 +- source/shared_lib/sources/graphics/model.cpp | 4379 ++-- .../sources/graphics/model_manager.cpp | 140 +- .../shared_lib/sources/graphics/particle.cpp | 4759 ++-- source/shared_lib/sources/graphics/pixmap.cpp | 2953 ++- .../sources/graphics/quaternion.cpp | 276 +- source/shared_lib/sources/graphics/shader.cpp | 42 +- .../sources/graphics/shader_manager.cpp | 122 +- .../shared_lib/sources/graphics/texture.cpp | 538 +- .../sources/graphics/texture_manager.cpp | 240 +- .../sources/graphics/video_player.cpp | 2497 +- source/shared_lib/sources/lua/lua_script.cpp | 2039 +- source/shared_lib/sources/map/map_preview.cpp | 2173 +- .../sources/platform/common/base_thread.cpp | 646 +- .../sources/platform/common/byte_order.cpp | 6 +- .../sources/platform/common/cache_manager.cpp | 20 +- .../platform/common/platform_common.cpp | 4305 ++-- .../platform/common/simple_threads.cpp | 1338 +- .../platform/miniupnpc/connecthostport.c | 91 +- .../platform/miniupnpc/igd_desc_parse.c | 68 +- .../sources/platform/miniupnpc/minisoap.c | 74 +- .../sources/platform/miniupnpc/minissdpc.c | 351 +- .../sources/platform/miniupnpc/miniupnpc.c | 359 +- .../sources/platform/miniupnpc/miniwget.c | 345 +- .../sources/platform/miniupnpc/minixml.c | 141 +- .../sources/platform/miniupnpc/minixmlvalid.c | 56 +- .../platform/miniupnpc/portlistingparse.c | 119 +- .../sources/platform/miniupnpc/receivedata.c | 63 +- .../sources/platform/miniupnpc/upnpc.c | 698 +- .../sources/platform/miniupnpc/upnpcommands.c | 593 +- .../sources/platform/miniupnpc/upnpdev.c | 10 +- .../sources/platform/miniupnpc/upnperrors.c | 179 +- .../platform/miniupnpc/upnpreplyparse.c | 140 +- .../sources/platform/posix/ircclient.cpp | 2071 +- .../sources/platform/posix/miniftpclient.cpp | 2123 +- .../sources/platform/posix/miniftpserver.cpp | 459 +- .../sources/platform/posix/socket.cpp | 5922 +++-- .../sources/platform/sdl/gl_wrap.cpp | 620 +- .../sources/platform/sdl/thread.cpp | 1667 +- .../sources/platform/sdl/window.cpp | 2146 +- .../sources/platform/sdl/window_gl.cpp | 310 +- .../platform/win32/factory_repository.cpp | 55 +- .../sources/platform/win32/gl_wrap_billy.cpp | 304 +- .../sources/platform/win32/glob.cpp | 610 +- .../sources/platform/win32/platform_util.cpp | 748 +- .../sound/openal/sound_player_openal.cpp | 1229 +- source/shared_lib/sources/sound/sound.cpp | 242 +- .../sources/sound/sound_file_loader.cpp | 437 +- .../sources/sound/sound_interface.cpp | 34 +- .../shared_lib/sources/sound/sound_player.cpp | 22 +- .../sources/streflop/libm/flt-32/e_acosf.cpp | 134 +- .../sources/streflop/libm/flt-32/e_acoshf.cpp | 70 +- .../sources/streflop/libm/flt-32/e_asinf.cpp | 164 +- .../sources/streflop/libm/flt-32/e_atan2f.cpp | 160 +- .../sources/streflop/libm/flt-32/e_atanhf.cpp | 66 +- .../sources/streflop/libm/flt-32/e_coshf.cpp | 94 +- .../sources/streflop/libm/flt-32/e_exp2f.cpp | 152 +- .../sources/streflop/libm/flt-32/e_expf.cpp | 150 +- .../sources/streflop/libm/flt-32/e_fmodf.cpp | 167 +- .../streflop/libm/flt-32/e_gammaf_r.cpp | 52 +- .../sources/streflop/libm/flt-32/e_hypotf.cpp | 144 +- .../sources/streflop/libm/flt-32/e_j0f.cpp | 794 +- .../sources/streflop/libm/flt-32/e_j1f.cpp | 818 +- .../sources/streflop/libm/flt-32/e_jnf.cpp | 348 +- .../streflop/libm/flt-32/e_lgammaf_r.cpp | 431 +- .../sources/streflop/libm/flt-32/e_log10f.cpp | 78 +- .../sources/streflop/libm/flt-32/e_log2f.cpp | 128 +- .../sources/streflop/libm/flt-32/e_logf.cpp | 146 +- .../sources/streflop/libm/flt-32/e_powf.cpp | 460 +- .../streflop/libm/flt-32/e_rem_pio2f.cpp | 337 +- .../streflop/libm/flt-32/e_remainderf.cpp | 94 +- .../sources/streflop/libm/flt-32/e_sinhf.cpp | 86 +- .../sources/streflop/libm/flt-32/e_sqrtf.cpp | 146 +- .../sources/streflop/libm/flt-32/k_cosf.cpp | 84 +- .../streflop/libm/flt-32/k_rem_pio2f.cpp | 363 +- .../sources/streflop/libm/flt-32/k_sinf.cpp | 68 +- .../sources/streflop/libm/flt-32/k_tanf.cpp | 163 +- .../sources/streflop/libm/flt-32/s_asinhf.cpp | 72 +- .../sources/streflop/libm/flt-32/s_atanf.cpp | 205 +- .../sources/streflop/libm/flt-32/s_cbrtf.cpp | 39 +- .../sources/streflop/libm/flt-32/s_ceilf.cpp | 79 +- .../streflop/libm/flt-32/s_copysignf.cpp | 40 +- .../sources/streflop/libm/flt-32/s_cosf.cpp | 68 +- .../sources/streflop/libm/flt-32/s_erff.cpp | 392 +- .../sources/streflop/libm/flt-32/s_expm1f.cpp | 213 +- .../sources/streflop/libm/flt-32/s_fabsf.cpp | 36 +- .../streflop/libm/flt-32/s_finitef.cpp | 36 +- .../sources/streflop/libm/flt-32/s_floorf.cpp | 80 +- .../streflop/libm/flt-32/s_fpclassifyf.cpp | 31 +- .../sources/streflop/libm/flt-32/s_frexpf.cpp | 62 +- .../sources/streflop/libm/flt-32/s_ilogbf.cpp | 59 +- .../sources/streflop/libm/flt-32/s_isinff.cpp | 23 +- .../sources/streflop/libm/flt-32/s_isnanf.cpp | 40 +- .../sources/streflop/libm/flt-32/s_ldexpf.cpp | 38 +- .../streflop/libm/flt-32/s_llrintf.cpp | 69 +- .../streflop/libm/flt-32/s_llroundf.cpp | 55 +- .../sources/streflop/libm/flt-32/s_log1pf.cpp | 177 +- .../sources/streflop/libm/flt-32/s_logbf.cpp | 46 +- .../sources/streflop/libm/flt-32/s_lrintf.cpp | 69 +- .../streflop/libm/flt-32/s_lroundf.cpp | 55 +- .../sources/streflop/libm/flt-32/s_modff.cpp | 86 +- .../streflop/libm/flt-32/s_nearbyintf.cpp | 114 +- .../streflop/libm/flt-32/s_nextafterf.cpp | 114 +- .../streflop/libm/flt-32/s_remquof.cpp | 133 +- .../sources/streflop/libm/flt-32/s_rintf.cpp | 100 +- .../sources/streflop/libm/flt-32/s_roundf.cpp | 77 +- .../streflop/libm/flt-32/s_scalblnf.cpp | 90 +- .../streflop/libm/flt-32/s_scalbnf.cpp | 90 +- .../streflop/libm/flt-32/s_signbitf.cpp | 13 +- .../streflop/libm/flt-32/s_sincosf.cpp | 83 +- .../sources/streflop/libm/flt-32/s_sinf.cpp | 64 +- .../sources/streflop/libm/flt-32/s_tanf.cpp | 54 +- .../sources/streflop/libm/flt-32/s_tanhf.cpp | 86 +- .../sources/streflop/libm/flt-32/s_truncf.cpp | 46 +- .../sources/streflop/libm/flt-32/w_expf.cpp | 6 +- source/shared_lib/sources/util/checksum.cpp | 780 +- source/shared_lib/sources/util/conversion.cpp | 463 +- .../shared_lib/sources/util/leak_dumper.cpp | 26 +- source/shared_lib/sources/util/profiler.cpp | 170 +- source/shared_lib/sources/util/properties.cpp | 1072 +- source/shared_lib/sources/util/randomgen.cpp | 160 +- .../shared_lib/sources/util/string_utils.cpp | 591 +- source/shared_lib/sources/util/util.cpp | 1907 +- source/shared_lib/sources/xml/xml_parser.cpp | 2062 +- source/tools/glexemel/g2xml.c | 148 +- 459 files changed, 204893 insertions(+), 217545 deletions(-) diff --git a/source/g3d_viewer/main.cpp b/source/g3d_viewer/main.cpp index eccbfaabe..ebd52ce1b 100644 --- a/source/g3d_viewer/main.cpp +++ b/source/g3d_viewer/main.cpp @@ -43,15 +43,15 @@ #endif #ifndef WIN32 - #define stricmp strcasecmp - #define strnicmp strncasecmp - #define _strnicmp strncasecmp +#define stricmp strcasecmp +#define strnicmp strncasecmp +#define _strnicmp strncasecmp #endif #if wxCHECK_VERSION(2, 9, 1) - #define WX2CHR(x) (x.mb_str()) +#define WX2CHR(x) (x.mb_str()) #else - #define WX2CHR(x) (wxConvCurrent->cWX2MB(x)) +#define WX2CHR(x) (wxConvCurrent->cWX2MB(x)) #endif using namespace Shared::Platform; @@ -73,395 +73,398 @@ const char *folderDelimiter = "/"; //int GameConstants::updateFps= 40; //int GameConstants::cameraFps= 100; -const string g3dviewerVersionString= "v0.8.01"; +const string g3dviewerVersionString = "v0.8.01"; // Because g3d should always support alpha transparency string fileFormat = "png"; -namespace Glest { namespace Game { +namespace Glest { + namespace Game { -string getGameReadWritePath(const string &lookupKey) { - string path = ""; - if(path == "" && getenv("GLESTHOME") != NULL) { - path = safeCharPtrCopy(getenv("GLESTHOME"),8096); - if(path != "" && EndsWith(path, "/") == false && EndsWith(path, "\\") == false) { - path += "/"; - } + string getGameReadWritePath(const string &lookupKey) { + string path = ""; + if (path == "" && getenv("GLESTHOME") != NULL) { + path = safeCharPtrCopy(getenv("GLESTHOME"), 8096); + if (path != "" && EndsWith(path, "/") == false && EndsWith(path, "\\") == false) { + path += "/"; + } - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path to be used for read/write files [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str()); - } - - return path; -} -}} - -namespace Shared{ namespace G3dViewer{ - -// =============================================== -// class Global functions -// =============================================== - -wxString ToUnicode(const char* str) { - return wxString(str, wxConvUTF8); -} - -wxString ToUnicode(const string& str) { - return wxString(str.c_str(), wxConvUTF8); -} - -const wxChar *GAME_ARGS[] = { - wxT("--help"), - wxT("--auto-screenshot"), - wxT("--load-unit"), - wxT("--load-model"), - wxT("--load-model-animation-value"), - wxT("--load-particle"), - wxT("--load-projectile-particle"), - wxT("--load-splash-particle"), - wxT("--load-particle-loop-value"), - wxT("--zoom-value"), - wxT("--rotate-x-value"), - wxT("--rotate-y-value"), - wxT("--screenshot-format"), - wxT("--verbose"), -}; - -enum GAME_ARG_TYPE { - GAME_ARG_HELP = 0, - GAME_ARG_AUTO_SCREENSHOT, - GAME_ARG_LOAD_UNIT, - GAME_ARG_LOAD_MODEL, - GAME_ARG_LOAD_MODEL_ANIMATION_VALUE, - GAME_ARG_LOAD_PARTICLE, - GAME_ARG_LOAD_PARTICLE_PROJECTILE, - GAME_ARG_LOAD_PARTICLE_SPLASH, - GAME_ARG_LOAD_PARTICLE_LOOP_VALUE, - GAME_ARG_ZOOM_VALUE, - GAME_ARG_ROTATE_X_VALUE, - GAME_ARG_ROTATE_Y_VALUE, - GAME_ARG_SCREENSHOT_FORMAT, - GAME_ARG_VERBOSE, -}; - -bool hasCommandArgument(int argc, wxChar** argv,const string &argName, - int *foundIndex=NULL, int startLookupIndex=1, - bool useArgParamLen=false) { - bool result = false; - - if(foundIndex != NULL) { - *foundIndex = -1; - } - size_t compareLen = strlen(argName.c_str()); - - for(int idx = startLookupIndex; idx < argc; idx++) { - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(argv[idx]); - //printf("tmp_buf [%s]\n",(const char *)tmp_buf); - if(useArgParamLen == true) { - compareLen = strlen(tmp_buf); - } - if(_strnicmp(argName.c_str(),tmp_buf,compareLen) == 0) { - result = true; - if(foundIndex != NULL) { - *foundIndex = idx; + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path to be used for read/write files [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str()); } - break; + return path; } } - return result; } -void printParameterHelp(const char *argv0, bool foundInvalidArgs) { - if(foundInvalidArgs == true) { - printf("\n"); - } +namespace Shared { + namespace G3dViewer { - // "================================================================================" - printf("\n%s %s, [Using %s]\n",extractFileFromDirectoryPath(argv0).c_str(),g3dviewerVersionString.c_str(),(const char *)wxConvCurrent->cWX2MB(wxVERSION_STRING)); + // =============================================== + // class Global functions + // =============================================== - printf("\nDisplays glest 3D-models and unit/projectile/splash particle systems.\n"); - printf("\nRotate with left mouse button. Zoom with right mouse button or mousewheel."); - printf("\nUse ctrl to load more than one particle system."); - printf("\nPress R to restart particles, this also reloads all files if they are changed."); + wxString ToUnicode(const char* str) { + return wxString(str, wxConvUTF8); + } - //printf("\n\noptionally you may use any of the following:\n"); - printf("\n\n%s [G3D FILE], usage",extractFileFromDirectoryPath(argv0).c_str()); - printf("\n\nCommandline Parameter: Description:"); - printf("\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); - printf("\n\n%s \t\tDisplays this help text.",(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_HELP])); + wxString ToUnicode(const string& str) { + return wxString(str.c_str(), wxConvUTF8); + } - // "================================================================================" - printf("\n\n%s=x \t\tAuto load the unit / skill information specified",(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_UNIT])); - printf("\n\n \tin path/filename x."); - printf("\n\n \tWhere x is a g3d filename to load separated with a"); - printf("\n\n \tcomma and one or more skill names to try loading."); - printf("\n\n \texample:"); - printf("\n\n \t%s %s=techs/megapack/factions/",extractFileFromDirectoryPath(argv0).c_str(),(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_UNIT])); - printf("\n\n \ttech/units/battle_machine,attack_skill,stop_skill"); + const wxChar *GAME_ARGS[] = { + wxT("--help"), + wxT("--auto-screenshot"), + wxT("--load-unit"), + wxT("--load-model"), + wxT("--load-model-animation-value"), + wxT("--load-particle"), + wxT("--load-projectile-particle"), + wxT("--load-splash-particle"), + wxT("--load-particle-loop-value"), + wxT("--zoom-value"), + wxT("--rotate-x-value"), + wxT("--rotate-y-value"), + wxT("--screenshot-format"), + wxT("--verbose"), + }; - printf("\n\n%s=x \tAuto load the model specified in path/filename x.",(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL])); - printf("\n\n \tWhere x is a g3d filename to load."); - printf("\n\n \texample:"); - printf("\n\n \t%s %s=techs/megapack/factions/",extractFileFromDirectoryPath(argv0).c_str(),(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL])); - printf("\n\n \ttech/units/battle_machine/models/battle_machine_dying.g3d"); + enum GAME_ARG_TYPE { + GAME_ARG_HELP = 0, + GAME_ARG_AUTO_SCREENSHOT, + GAME_ARG_LOAD_UNIT, + GAME_ARG_LOAD_MODEL, + GAME_ARG_LOAD_MODEL_ANIMATION_VALUE, + GAME_ARG_LOAD_PARTICLE, + GAME_ARG_LOAD_PARTICLE_PROJECTILE, + GAME_ARG_LOAD_PARTICLE_SPLASH, + GAME_ARG_LOAD_PARTICLE_LOOP_VALUE, + GAME_ARG_ZOOM_VALUE, + GAME_ARG_ROTATE_X_VALUE, + GAME_ARG_ROTATE_Y_VALUE, + GAME_ARG_SCREENSHOT_FORMAT, + GAME_ARG_VERBOSE, + }; - printf("\n\n%s=x ",(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL_ANIMATION_VALUE])); - printf("\n\n \tAnimation value when loading a model."); - printf("\n\n \tWhere x is a decimal value from -1.0 to 1.0"); - printf("\n\n \texample:"); - printf("\n\n \t%s %s=0.5",extractFileFromDirectoryPath(argv0).c_str(),(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL_ANIMATION_VALUE])); + bool hasCommandArgument(int argc, wxChar** argv, const string &argName, + int *foundIndex = NULL, int startLookupIndex = 1, + bool useArgParamLen = false) { + bool result = false; - // "================================================================================" - printf("\n\n%s=x \tAutomatically takes a screenshot of the items you",(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_AUTO_SCREENSHOT])); - printf("\n\n \tare loading."); - printf("\n\n \tWhere x is a comma-delimited list of one or more"); - printf("\n\n \t of the optional settings:"); - printf("\n\n \t transparent, enable_grid, enable_wireframe,"); - printf("\n\n \t enable_normals, disable_grid, disable_wireframe,"); - printf("\n\n \t disable_normals, saveas-, resize-wxh"); - printf("\n\n \texample:"); - printf("\n\n \t%s %s=transparent,",extractFileFromDirectoryPath(argv0).c_str(),(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_AUTO_SCREENSHOT])); - printf("\n\n \tdisable_grid,saveas-test.png,resize-800x600"); - printf("\n\n \t%s=techs/megapack/factions/tech/units/",(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL])); - printf("\n\n \tbattle_machine/models/battle_machine_dying.g3d"); + if (foundIndex != NULL) { + *foundIndex = -1; + } + size_t compareLen = strlen(argName.c_str()); - // "================================================================================" - printf("\n\n%s=x \tAuto load the particle specified in path/filename x.",(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE])); - printf("\n\n \tWhere x is a Particle XML filename to load."); - printf("\n\n \texample:"); - printf("\n\n \t%s %s=techs/megapack/factions/",extractFileFromDirectoryPath(argv0).c_str(),(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE])); - printf("\n\n \tpersian/units/genie/glow_particles.xml"); + for (int idx = startLookupIndex; idx < argc; idx++) { + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(argv[idx]); + //printf("tmp_buf [%s]\n",(const char *)tmp_buf); + if (useArgParamLen == true) { + compareLen = strlen(tmp_buf); + } + if (_strnicmp(argName.c_str(), tmp_buf, compareLen) == 0) { + result = true; + if (foundIndex != NULL) { + *foundIndex = idx; + } - printf("\n\n%s=x ",(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_PROJECTILE])); - printf("\n\n \tAuto load the projectile particle specified in"); - printf("\n\n \tpath/filename x."); - printf("\n\n \tWhere x is a Projectile Particle Definition XML"); - printf("\n\n \t filename to load."); - printf("\n\n \texample:"); - printf("\n\n \t%s %s=techs/megapack/",extractFileFromDirectoryPath(argv0).c_str(),(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_PROJECTILE])); - printf("\n\n \tfactions/persian/units/genie/particle_proj.xml"); + break; + } + } + return result; + } - printf("\n\n%s=x ",(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_SPLASH])); - printf("\n\n \tAuto load the splash particle specified in"); - printf("\n\n \tpath/filename x."); - printf("\n\n \tWhere x is a Splash Particle Definition XML"); - printf("\n\n \t filename to load."); - printf("\n\n \texample:"); - printf("\n\n \t%s %s=techs/megapack/",extractFileFromDirectoryPath(argv0).c_str(),(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_SPLASH])); - printf("\n\n \tfactions/persian/units/genie/particle_splash.xml"); + void printParameterHelp(const char *argv0, bool foundInvalidArgs) { + if (foundInvalidArgs == true) { + printf("\n"); + } - printf("\n\n%s=x ",(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_LOOP_VALUE])); - printf("\n\n \tParticle loop value when loading one or more"); - printf("\n\n \tparticles."); - printf("\n\n \tWhere x is an integer value from 1 to particle count."); - printf("\n\n \texample:"); - printf("\n\n \t%s %s=25",extractFileFromDirectoryPath(argv0).c_str(),(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_LOOP_VALUE])); + // "================================================================================" + printf("\n%s %s, [Using %s]\n", extractFileFromDirectoryPath(argv0).c_str(), g3dviewerVersionString.c_str(), (const char *) wxConvCurrent->cWX2MB(wxVERSION_STRING)); - printf("\n\n%s=x \tZoom value when loading a model.",(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ZOOM_VALUE])); - printf("\n\n \tWhere x is a decimal value from 0.1 to 10.0"); - printf("\n\n \texample:"); - printf("\n\n \t%s %s=4.2",extractFileFromDirectoryPath(argv0).c_str(),(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ZOOM_VALUE])); + printf("\nDisplays glest 3D-models and unit/projectile/splash particle systems.\n"); + printf("\nRotate with left mouse button. Zoom with right mouse button or mousewheel."); + printf("\nUse ctrl to load more than one particle system."); + printf("\nPress R to restart particles, this also reloads all files if they are changed."); - printf("\n\n%s=x \tX Coordinate Rotation value when loading a model.",(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_X_VALUE])); - printf("\n\n \tWhere x is a decimal value from -10.0 to 10.0"); - printf("\n\n \texample:"); - printf("\n\n \t%s %s=2.2",extractFileFromDirectoryPath(argv0).c_str(),(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_X_VALUE])); + //printf("\n\noptionally you may use any of the following:\n"); + printf("\n\n%s [G3D FILE], usage", extractFileFromDirectoryPath(argv0).c_str()); + printf("\n\nCommandline Parameter: Description:"); + printf("\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); + printf("\n\n%s \t\tDisplays this help text.", (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_HELP])); - printf("\n\n%s=x \tY Coordinate Rotation value when loading a model.",(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_Y_VALUE])); - printf("\n\n \tWhere x is a decimal value from -10.0 to 10.0"); - printf("\n\n \texample:"); - printf("\n\n \t%s %s=2.2",extractFileFromDirectoryPath(argv0).c_str(),(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_Y_VALUE])); + // "================================================================================" + printf("\n\n%s=x \t\tAuto load the unit / skill information specified", (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_UNIT])); + printf("\n\n \tin path/filename x."); + printf("\n\n \tWhere x is a g3d filename to load separated with a"); + printf("\n\n \tcomma and one or more skill names to try loading."); + printf("\n\n \texample:"); + printf("\n\n \t%s %s=techs/megapack/factions/", extractFileFromDirectoryPath(argv0).c_str(), (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_UNIT])); + printf("\n\n \ttech/units/battle_machine,attack_skill,stop_skill"); - printf("\n\n%s=x \tSpecify which image format to use for screenshots.",(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_SCREENSHOT_FORMAT])); - printf("\n\n \tWhere x is one of the following supported formats:"); - printf("\n\n \t png,jpg,tga,bmp"); - printf("\n\n \t*NOTE: png is the default (and supports transparency)"); - printf("\n\n \texample:"); - printf("\n\n \t%s %s=jpg",extractFileFromDirectoryPath(argv0).c_str(),(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_SCREENSHOT_FORMAT])); + printf("\n\n%s=x \tAuto load the model specified in path/filename x.", (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL])); + printf("\n\n \tWhere x is a g3d filename to load."); + printf("\n\n \texample:"); + printf("\n\n \t%s %s=techs/megapack/factions/", extractFileFromDirectoryPath(argv0).c_str(), (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL])); + printf("\n\n \ttech/units/battle_machine/models/battle_machine_dying.g3d"); - printf("\n\n"); -} + printf("\n\n%s=x ", (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL_ANIMATION_VALUE])); + printf("\n\n \tAnimation value when loading a model."); + printf("\n\n \tWhere x is a decimal value from -1.0 to 1.0"); + printf("\n\n \texample:"); + printf("\n\n \t%s %s=0.5", extractFileFromDirectoryPath(argv0).c_str(), (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL_ANIMATION_VALUE])); -bool autoScreenShotAndExit = false; -vector autoScreenShotParams; -std::pair overrideSize(0,0); + // "================================================================================" + printf("\n\n%s=x \tAutomatically takes a screenshot of the items you", (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_AUTO_SCREENSHOT])); + printf("\n\n \tare loading."); + printf("\n\n \tWhere x is a comma-delimited list of one or more"); + printf("\n\n \t of the optional settings:"); + printf("\n\n \t transparent, enable_grid, enable_wireframe,"); + printf("\n\n \t enable_normals, disable_grid, disable_wireframe,"); + printf("\n\n \t disable_normals, saveas-, resize-wxh"); + printf("\n\n \texample:"); + printf("\n\n \t%s %s=transparent,", extractFileFromDirectoryPath(argv0).c_str(), (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_AUTO_SCREENSHOT])); + printf("\n\n \tdisable_grid,saveas-test.png,resize-800x600"); + printf("\n\n \t%s=techs/megapack/factions/tech/units/", (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL])); + printf("\n\n \tbattle_machine/models/battle_machine_dying.g3d"); -// =============================================== -// class MainWindow -// =============================================== + // "================================================================================" + printf("\n\n%s=x \tAuto load the particle specified in path/filename x.", (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE])); + printf("\n\n \tWhere x is a Particle XML filename to load."); + printf("\n\n \texample:"); + printf("\n\n \t%s %s=techs/megapack/factions/", extractFileFromDirectoryPath(argv0).c_str(), (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE])); + printf("\n\n \tpersian/units/genie/glow_particles.xml"); -const string MainWindow::winHeader= "G3D viewer " + g3dviewerVersionString; + printf("\n\n%s=x ", (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_PROJECTILE])); + printf("\n\n \tAuto load the projectile particle specified in"); + printf("\n\n \tpath/filename x."); + printf("\n\n \tWhere x is a Projectile Particle Definition XML"); + printf("\n\n \t filename to load."); + printf("\n\n \texample:"); + printf("\n\n \t%s %s=techs/megapack/", extractFileFromDirectoryPath(argv0).c_str(), (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_PROJECTILE])); + printf("\n\n \tfactions/persian/units/genie/particle_proj.xml"); -const float defaultspeed = 0.025f; + printf("\n\n%s=x ", (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_SPLASH])); + printf("\n\n \tAuto load the splash particle specified in"); + printf("\n\n \tpath/filename x."); + printf("\n\n \tWhere x is a Splash Particle Definition XML"); + printf("\n\n \t filename to load."); + printf("\n\n \texample:"); + printf("\n\n \t%s %s=techs/megapack/", extractFileFromDirectoryPath(argv0).c_str(), (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_SPLASH])); + printf("\n\n \tfactions/persian/units/genie/particle_splash.xml"); -MainWindow::MainWindow( std::pair > unitToLoad, - const string modelPath, - const string particlePath, - const string projectileParticlePath, - const string splashParticlePath, - float defaultAnimation, - int defaultParticleLoopStart, - float defaultZoom,float defaultXRot, float defaultYRot, - string appPath) - : wxFrame(NULL, -1, ToUnicode(winHeader), - wxPoint(Renderer::windowX, Renderer::windowY), - wxSize(Renderer::windowW, Renderer::windowH)), - glCanvas(NULL), - renderer(NULL), - timer(NULL), - menu(NULL), - fileDialog(NULL), - colorPicker(NULL), - model(NULL), - initTextureManager(true), - startupSettingsInited(false) + printf("\n\n%s=x ", (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_LOOP_VALUE])); + printf("\n\n \tParticle loop value when loading one or more"); + printf("\n\n \tparticles."); + printf("\n\n \tWhere x is an integer value from 1 to particle count."); + printf("\n\n \texample:"); + printf("\n\n \t%s %s=25", extractFileFromDirectoryPath(argv0).c_str(), (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_LOOP_VALUE])); -{ - this->appPath = appPath; - Properties::setApplicationPath(executable_path(appPath)); + printf("\n\n%s=x \tZoom value when loading a model.", (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ZOOM_VALUE])); + printf("\n\n \tWhere x is a decimal value from 0.1 to 10.0"); + printf("\n\n \texample:"); + printf("\n\n \t%s %s=4.2", extractFileFromDirectoryPath(argv0).c_str(), (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ZOOM_VALUE])); - lastanim = 0; - model= NULL; + printf("\n\n%s=x \tX Coordinate Rotation value when loading a model.", (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_X_VALUE])); + printf("\n\n \tWhere x is a decimal value from -10.0 to 10.0"); + printf("\n\n \texample:"); + printf("\n\n \t%s %s=2.2", extractFileFromDirectoryPath(argv0).c_str(), (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_X_VALUE])); - Config &config = Config::getInstance(); + printf("\n\n%s=x \tY Coordinate Rotation value when loading a model.", (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_Y_VALUE])); + printf("\n\n \tWhere x is a decimal value from -10.0 to 10.0"); + printf("\n\n \texample:"); + printf("\n\n \t%s %s=2.2", extractFileFromDirectoryPath(argv0).c_str(), (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_Y_VALUE])); - isControlKeyPressed = false; + printf("\n\n%s=x \tSpecify which image format to use for screenshots.", (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_SCREENSHOT_FORMAT])); + printf("\n\n \tWhere x is one of the following supported formats:"); + printf("\n\n \t png,jpg,tga,bmp"); + printf("\n\n \t*NOTE: png is the default (and supports transparency)"); + printf("\n\n \texample:"); + printf("\n\n \t%s %s=jpg", extractFileFromDirectoryPath(argv0).c_str(), (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_SCREENSHOT_FORMAT])); - initGlCanvas(); + printf("\n\n"); + } + + bool autoScreenShotAndExit = false; + vector autoScreenShotParams; + std::pair overrideSize(0, 0); + + // =============================================== + // class MainWindow + // =============================================== + + const string MainWindow::winHeader = "G3D viewer " + g3dviewerVersionString; + + const float defaultspeed = 0.025f; + + MainWindow::MainWindow(std::pair > unitToLoad, + const string modelPath, + const string particlePath, + const string projectileParticlePath, + const string splashParticlePath, + float defaultAnimation, + int defaultParticleLoopStart, + float defaultZoom, float defaultXRot, float defaultYRot, + string appPath) + : wxFrame(NULL, -1, ToUnicode(winHeader), + wxPoint(Renderer::windowX, Renderer::windowY), + wxSize(Renderer::windowW, Renderer::windowH)), + glCanvas(NULL), + renderer(NULL), + timer(NULL), + menu(NULL), + fileDialog(NULL), + colorPicker(NULL), + model(NULL), + initTextureManager(true), + startupSettingsInited(false) + + { + this->appPath = appPath; + Properties::setApplicationPath(executable_path(appPath)); + + lastanim = 0; + model = NULL; + + Config &config = Config::getInstance(); + + isControlKeyPressed = false; + + initGlCanvas(); #if wxCHECK_VERSION(2, 9, 1) #else - glCanvas->SetCurrent(); + glCanvas->SetCurrent(); #endif - unitPath = unitToLoad; + unitPath = unitToLoad; - if(modelPath != "") { - this->modelPathList.push_back(modelPath); - printf("Startup Adding model [%s] list size " MG_SIZE_T_SPECIFIER "\n",modelPath.c_str(),this->modelPathList.size()); - } - if(particlePath != "") { - this->particlePathList.push_back(particlePath); - } - if(projectileParticlePath != "") { - this->particleProjectilePathList.push_back(projectileParticlePath); - } - if(splashParticlePath != "") { - this->particleSplashPathList.push_back(splashParticlePath); - } + if (modelPath != "") { + this->modelPathList.push_back(modelPath); + printf("Startup Adding model [%s] list size " MG_SIZE_T_SPECIFIER "\n", modelPath.c_str(), this->modelPathList.size()); + } + if (particlePath != "") { + this->particlePathList.push_back(particlePath); + } + if (projectileParticlePath != "") { + this->particleProjectilePathList.push_back(projectileParticlePath); + } + if (splashParticlePath != "") { + this->particleSplashPathList.push_back(splashParticlePath); + } - resetAnimation = false; - anim = defaultAnimation; - particleLoopStart = defaultParticleLoopStart; - resetAnim = anim; - resetParticleLoopStart = particleLoopStart; - rotX= defaultXRot; - rotY= defaultYRot; - zoom= defaultZoom; - playerColor= Renderer::pcRed; + resetAnimation = false; + anim = defaultAnimation; + particleLoopStart = defaultParticleLoopStart; + resetAnim = anim; + resetParticleLoopStart = particleLoopStart; + rotX = defaultXRot; + rotY = defaultYRot; + zoom = defaultZoom; + playerColor = Renderer::pcRed; - speed= defaultspeed; + speed = defaultspeed; - //getGlPlatformExtensions(); - menu= new wxMenuBar(); + //getGlPlatformExtensions(); + menu = new wxMenuBar(); - //menu - menuFile= new wxMenu(); - menuFile->Append(miFileLoad, wxT("&Load G3d model\tCtrl+L"), wxT("Load 3D model")); - menuFile->Append(miFileLoadParticleXML, wxT("Load &Particle XML\tCtrl+P"), wxT("Press ctrl before menu for keeping current particles")); - menuFile->Append(miFileLoadProjectileParticleXML, wxT("Load Pro&jectile Particle XML\tCtrl+J"), wxT("Press ctrl before menu for keeping current projectile particles")); - menuFile->Append(miFileLoadSplashParticleXML, wxT("Load &Splash Particle XML\tCtrl+S"), wxT("Press ctrl before menu for keeping current splash particles")); - menuFile->Append(miFileClearAll, wxT("&Clear All\tCtrl+C")); - menuFile->AppendCheckItem(miFileToggleScreenshotTransparent, wxT("&Transparent Screenshots\tCtrl+T")); - menuFile->Append(miFileSaveScreenshot, wxT("Sa&ve a Screenshot\tCtrl+V")); - menuFile->AppendSeparator(); - menuFile->Append(wxID_EXIT); - menu->Append(menuFile, wxT("&File")); + //menu + menuFile = new wxMenu(); + menuFile->Append(miFileLoad, wxT("&Load G3d model\tCtrl+L"), wxT("Load 3D model")); + menuFile->Append(miFileLoadParticleXML, wxT("Load &Particle XML\tCtrl+P"), wxT("Press ctrl before menu for keeping current particles")); + menuFile->Append(miFileLoadProjectileParticleXML, wxT("Load Pro&jectile Particle XML\tCtrl+J"), wxT("Press ctrl before menu for keeping current projectile particles")); + menuFile->Append(miFileLoadSplashParticleXML, wxT("Load &Splash Particle XML\tCtrl+S"), wxT("Press ctrl before menu for keeping current splash particles")); + menuFile->Append(miFileClearAll, wxT("&Clear All\tCtrl+C")); + menuFile->AppendCheckItem(miFileToggleScreenshotTransparent, wxT("&Transparent Screenshots\tCtrl+T")); + menuFile->Append(miFileSaveScreenshot, wxT("Sa&ve a Screenshot\tCtrl+V")); + menuFile->AppendSeparator(); + menuFile->Append(wxID_EXIT); + menu->Append(menuFile, wxT("&File")); - //mode - menuMode= new wxMenu(); - menuMode->AppendCheckItem(miModeNormals, wxT("&Normals")); - menuMode->AppendCheckItem(miModeWireframe, wxT("&Wireframe")); - menuMode->AppendCheckItem(miModeGrid, wxT("&Grid")); - menu->Append(menuMode, wxT("&Mode")); + //mode + menuMode = new wxMenu(); + menuMode->AppendCheckItem(miModeNormals, wxT("&Normals")); + menuMode->AppendCheckItem(miModeWireframe, wxT("&Wireframe")); + menuMode->AppendCheckItem(miModeGrid, wxT("&Grid")); + menu->Append(menuMode, wxT("&Mode")); - //mode - menuSpeed= new wxMenu(); - menuSpeed->Append(miSpeedSlower, wxT("&Slower\t-")); - menuSpeed->Append(miSpeedFaster, wxT("&Faster\t+")); - menuSpeed->AppendSeparator(); - menuSpeed->Append(miRestart, wxT("&Restart particles\tR"), wxT("Restart particle animations, this also reloads model and particle files if they are changed")); - menu->Append(menuSpeed, wxT("&Speed")); + //mode + menuSpeed = new wxMenu(); + menuSpeed->Append(miSpeedSlower, wxT("&Slower\t-")); + menuSpeed->Append(miSpeedFaster, wxT("&Faster\t+")); + menuSpeed->AppendSeparator(); + menuSpeed->Append(miRestart, wxT("&Restart particles\tR"), wxT("Restart particle animations, this also reloads model and particle files if they are changed")); + menu->Append(menuSpeed, wxT("&Speed")); - //custom color - menuCustomColor= new wxMenu(); - menuCustomColor->Append(miChangeBackgroundColor, wxT("Change Background Color")); - menuCustomColor->AppendCheckItem(miColorRed, wxT("&Red\t0")); - menuCustomColor->AppendCheckItem(miColorBlue, wxT("&Blue\t1")); - menuCustomColor->AppendCheckItem(miColorGreen, wxT("&Green\t2")); - menuCustomColor->AppendCheckItem(miColorYellow, wxT("&Yellow\t3")); - menuCustomColor->AppendCheckItem(miColorWhite, wxT("&White\t4")); - menuCustomColor->AppendCheckItem(miColorCyan, wxT("&Cyan\t5")); - menuCustomColor->AppendCheckItem(miColorOrange, wxT("&Orange\t6")); - menuCustomColor->AppendCheckItem(miColorMagenta, wxT("&Pink\t7")); // it is called Pink everywhere else so... - menu->Append(menuCustomColor, wxT("&Custom Color")); + //custom color + menuCustomColor = new wxMenu(); + menuCustomColor->Append(miChangeBackgroundColor, wxT("Change Background Color")); + menuCustomColor->AppendCheckItem(miColorRed, wxT("&Red\t0")); + menuCustomColor->AppendCheckItem(miColorBlue, wxT("&Blue\t1")); + menuCustomColor->AppendCheckItem(miColorGreen, wxT("&Green\t2")); + menuCustomColor->AppendCheckItem(miColorYellow, wxT("&Yellow\t3")); + menuCustomColor->AppendCheckItem(miColorWhite, wxT("&White\t4")); + menuCustomColor->AppendCheckItem(miColorCyan, wxT("&Cyan\t5")); + menuCustomColor->AppendCheckItem(miColorOrange, wxT("&Orange\t6")); + menuCustomColor->AppendCheckItem(miColorMagenta, wxT("&Pink\t7")); // it is called Pink everywhere else so... + menu->Append(menuCustomColor, wxT("&Custom Color")); - menuMode->Check(miModeGrid, true); - menuCustomColor->Check(miColorRed, true); + menuMode->Check(miModeGrid, true); + menuCustomColor->Check(miColorRed, true); - SetMenuBar(menu); + SetMenuBar(menu); - //misc - backBrightness= 0.3f; - gridBrightness= 1.0f; - lightBrightness= 0.3f; - lastX= 0; - lastY= 0; + //misc + backBrightness = 0.3f; + gridBrightness = 1.0f; + lightBrightness = 0.3f; + lastX = 0; + lastY = 0; - statusbarText=""; - CreateStatusBar(); + statusbarText = ""; + CreateStatusBar(); - this->Layout(); + this->Layout(); - wxInitAllImageHandlers(); + wxInitAllImageHandlers(); #ifdef WIN32 #if defined(__MINGW32__) - wxIcon icon(ToUnicode("IDI_ICON1")); + wxIcon icon(ToUnicode("IDI_ICON1")); #else - wxIcon icon(L"IDI_ICON1"); + wxIcon icon(L"IDI_ICON1"); #endif #else - wxIcon icon; - string iniFilePath = extractDirectoryPathFromFile(config.getFileName(false)); - string icon_file = iniFilePath + "g3dviewer.ico"; - std::ifstream testFile(icon_file.c_str()); - if(testFile.good()) { - testFile.close(); - icon.LoadFile(ToUnicode(icon_file.c_str()),wxBITMAP_TYPE_ICO); - } + wxIcon icon; + string iniFilePath = extractDirectoryPathFromFile(config.getFileName(false)); + string icon_file = iniFilePath + "g3dviewer.ico"; + std::ifstream testFile(icon_file.c_str()); + if (testFile.good()) { + testFile.close(); + icon.LoadFile(ToUnicode(icon_file.c_str()), wxBITMAP_TYPE_ICO); + } #endif - SetIcon(icon); + SetIcon(icon); - fileDialog = new wxFileDialog(this); - if(modelPath != "") { - fileDialog->SetPath(ToUnicode(modelPath)); - } - string userData = config.getString("UserData_Root",""); - if(userData != "") { - endPathWithSlash(userData); - } - string defaultPath = userData + "techs/"; - fileDialog->SetDirectory(ToUnicode(defaultPath.c_str())); + fileDialog = new wxFileDialog(this); + if (modelPath != "") { + fileDialog->SetPath(ToUnicode(modelPath)); + } + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + string defaultPath = userData + "techs/"; + fileDialog->SetDirectory(ToUnicode(defaultPath.c_str())); - if(glCanvas != NULL) { - glCanvas->SetFocus(); - } + if (glCanvas != NULL) { + glCanvas->SetFocus(); + } - // For windows register g3d file extension to launch this app + // For windows register g3d file extension to launch this app #if defined(WIN32) && !defined(__MINGW32__) // example from: http://stackoverflow.com/questions/1387769/create-registry-entry-to-associate-file-extension-with-application-in-c //[HKEY_CURRENT_USER\Software\Classes\blergcorp.blergapp.v1\shell\open\command] @@ -470,2160 +473,2096 @@ MainWindow::MainWindow( std::pair > unitToLoad, //@="blergcorp.blergapp.v1" //Open the registry key. - wstring subKey = L"Software\\Classes\\zetaglest.g3d\\shell\\open\\command"; - HKEY keyHandle; - DWORD dwDisposition; - RegCreateKeyEx(HKEY_CURRENT_USER,subKey.c_str(),0, NULL, 0, KEY_ALL_ACCESS, NULL, &keyHandle, &dwDisposition); - //Set the value. - auto_ptr wstr(Ansi2WideString(appPath.c_str())); + wstring subKey = L"Software\\Classes\\zetaglest.g3d\\shell\\open\\command"; + HKEY keyHandle; + DWORD dwDisposition; + RegCreateKeyEx(HKEY_CURRENT_USER, subKey.c_str(), 0, NULL, 0, KEY_ALL_ACCESS, NULL, &keyHandle, &dwDisposition); + //Set the value. + auto_ptr wstr(Ansi2WideString(appPath.c_str())); - wstring launchApp = wstring(wstr.get()) + L" \"%1\""; - DWORD len = (launchApp.size() + 1) * sizeof(wchar_t); - RegSetValueEx(keyHandle, NULL, 0, REG_SZ, (PBYTE)launchApp.c_str(), len); - RegCloseKey(keyHandle); + wstring launchApp = wstring(wstr.get()) + L" \"%1\""; + DWORD len = (launchApp.size() + 1) * sizeof(wchar_t); + RegSetValueEx(keyHandle, NULL, 0, REG_SZ, (PBYTE) launchApp.c_str(), len); + RegCloseKey(keyHandle); - subKey = L"Software\\Classes\\.g3d"; - RegCreateKeyEx(HKEY_CURRENT_USER,subKey.c_str(),0, NULL, 0, KEY_ALL_ACCESS, NULL, &keyHandle, &dwDisposition); - //Set the value. - launchApp = L"zetaglest.g3d"; - len = (launchApp.size() + 1) * sizeof(wchar_t); - RegSetValueEx(keyHandle, NULL, 0, REG_SZ, (PBYTE)launchApp.c_str(), len); - RegCloseKey(keyHandle); + subKey = L"Software\\Classes\\.g3d"; + RegCreateKeyEx(HKEY_CURRENT_USER, subKey.c_str(), 0, NULL, 0, KEY_ALL_ACCESS, NULL, &keyHandle, &dwDisposition); + //Set the value. + launchApp = L"zetaglest.g3d"; + len = (launchApp.size() + 1) * sizeof(wchar_t); + RegSetValueEx(keyHandle, NULL, 0, REG_SZ, (PBYTE) launchApp.c_str(), len); + RegCloseKey(keyHandle); #endif -} + } -void MainWindow::setupTimer() { - timer = new wxTimer(this); - timer->Start(100); -} + void MainWindow::setupTimer() { + timer = new wxTimer(this); + timer->Start(100); + } -void MainWindow::setupStartupSettings() { + void MainWindow::setupStartupSettings() { - //printf("In setupStartupSettings #1\n"); - if(glCanvas == NULL) { - initGlCanvas(); + //printf("In setupStartupSettings #1\n"); + if (glCanvas == NULL) { + initGlCanvas(); #if wxCHECK_VERSION(2, 9, 1) #else - glCanvas->SetCurrent(); + glCanvas->SetCurrent(); #endif - } - glCanvas->setCurrentGLContext(); - //printf("In setupStartupSettings #2\n"); + } + glCanvas->setCurrentGLContext(); + //printf("In setupStartupSettings #2\n"); - GLuint err = glewInit(); - if (GLEW_OK != err) { - fprintf(stderr, "Error [main]: glewInit failed: %s\n", glewGetErrorString(err)); - //return 1; - throw std::runtime_error((char *)glewGetErrorString(err)); - } + GLuint err = glewInit(); + if (GLEW_OK != err) { + fprintf(stderr, "Error [main]: glewInit failed: %s\n", glewGetErrorString(err)); + //return 1; + throw std::runtime_error((char *) glewGetErrorString(err)); + } - renderer= Renderer::getInstance(); + renderer = Renderer::getInstance(); - for(unsigned int i = 0; i < autoScreenShotParams.size(); ++i) { - if(autoScreenShotParams[i] == "transparent") { - printf("Screenshot option [%s]\n",autoScreenShotParams[i].c_str()); - menuFile->Check(miFileToggleScreenshotTransparent,true); - float alpha = 0.0f; - renderer->setAlphaColor(alpha); + for (unsigned int i = 0; i < autoScreenShotParams.size(); ++i) { + if (autoScreenShotParams[i] == "transparent") { + printf("Screenshot option [%s]\n", autoScreenShotParams[i].c_str()); + menuFile->Check(miFileToggleScreenshotTransparent, true); + float alpha = 0.0f; + renderer->setAlphaColor(alpha); + } + if (autoScreenShotParams[i] == "enable_grid") { + printf("Screenshot option [%s]\n", autoScreenShotParams[i].c_str()); + menuMode->Check(miModeGrid, true); + if (renderer->getGrid() == false) { + renderer->toggleGrid(); + } + } + if (autoScreenShotParams[i] == "enable_wireframe") { + printf("Screenshot option [%s]\n", autoScreenShotParams[i].c_str()); + menuMode->Check(miModeWireframe, true); + if (renderer->getWireframe() == false) { + renderer->toggleWireframe(); + } + } + if (autoScreenShotParams[i] == "enable_normals") { + printf("Screenshot option [%s]\n", autoScreenShotParams[i].c_str()); + menuMode->Check(miModeNormals, true); + if (renderer->getNormals() == false) { + renderer->toggleNormals(); + } + } + if (autoScreenShotParams[i] == "disable_grid") { + printf("Screenshot option [%s]\n", autoScreenShotParams[i].c_str()); + menuMode->Check(miModeGrid, false); + if (renderer->getGrid() == true) { + renderer->toggleGrid(); + } + } + if (autoScreenShotParams[i] == "enable_wireframe") { + printf("Screenshot option [%s]\n", autoScreenShotParams[i].c_str()); + menuMode->Check(miModeWireframe, false); + if (renderer->getWireframe() == true) { + renderer->toggleWireframe(); + } + } + if (autoScreenShotParams[i] == "enable_normals") { + printf("Screenshot option [%s]\n", autoScreenShotParams[i].c_str()); + menuMode->Check(miModeNormals, false); + if (renderer->getNormals() == true) { + renderer->toggleNormals(); + } + } + } + renderer->init(); + + wxCommandEvent event; + onMenuRestart(event); } - if(autoScreenShotParams[i] == "enable_grid") { - printf("Screenshot option [%s]\n",autoScreenShotParams[i].c_str()); - menuMode->Check(miModeGrid,true); - if(renderer->getGrid() == false) { - renderer->toggleGrid(); + + MainWindow::~MainWindow() { + delete timer; + timer = NULL; + + delete fileDialog; + fileDialog = NULL; + + //delete model; + //model = NULL; + if (renderer) renderer->end(); + + delete renderer; + renderer = NULL; + + if (glCanvas) { + glCanvas->Destroy(); + } + glCanvas = NULL; + + } + + void MainWindow::initGlCanvas() { + if (glCanvas == NULL) { + int args[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_MIN_ALPHA, 8 }; // to prevent flicker + glCanvas = new GlCanvas(this, args); } } - if(autoScreenShotParams[i] == "enable_wireframe") { - printf("Screenshot option [%s]\n",autoScreenShotParams[i].c_str()); - menuMode->Check(miModeWireframe,true); - if(renderer->getWireframe() == false) { - renderer->toggleWireframe(); - } - } - if(autoScreenShotParams[i] == "enable_normals") { - printf("Screenshot option [%s]\n",autoScreenShotParams[i].c_str()); - menuMode->Check(miModeNormals,true); - if(renderer->getNormals() == false) { - renderer->toggleNormals(); - } - } - if(autoScreenShotParams[i] == "disable_grid") { - printf("Screenshot option [%s]\n",autoScreenShotParams[i].c_str()); - menuMode->Check(miModeGrid,false); - if(renderer->getGrid() == true) { - renderer->toggleGrid(); - } - } - if(autoScreenShotParams[i] == "enable_wireframe") { - printf("Screenshot option [%s]\n",autoScreenShotParams[i].c_str()); - menuMode->Check(miModeWireframe,false); - if(renderer->getWireframe() == true) { - renderer->toggleWireframe(); - } - } - if(autoScreenShotParams[i] == "enable_normals") { - printf("Screenshot option [%s]\n",autoScreenShotParams[i].c_str()); - menuMode->Check(miModeNormals,false); - if(renderer->getNormals() == true) { - renderer->toggleNormals(); - } - } - } - renderer->init(); - wxCommandEvent event; - onMenuRestart(event); -} - -MainWindow::~MainWindow(){ - delete timer; - timer = NULL; - - delete fileDialog; - fileDialog = NULL; - - //delete model; - //model = NULL; - if(renderer) renderer->end(); - - delete renderer; - renderer = NULL; - - if(glCanvas) { - glCanvas->Destroy(); - } - glCanvas = NULL; - -} - -void MainWindow::initGlCanvas(){ - if(glCanvas == NULL) { - int args[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_MIN_ALPHA, 8 }; // to prevent flicker - glCanvas = new GlCanvas(this, args); - } -} - -void MainWindow::init() { + void MainWindow::init() { #if wxCHECK_VERSION(2, 9, 3) #elif wxCHECK_VERSION(2, 9, 1) #else - glCanvas->SetCurrent(); - //printf("setcurrent #2\n"); + glCanvas->SetCurrent(); + //printf("setcurrent #2\n"); #endif -} - -void MainWindow::onPaint(wxPaintEvent &event) { - if(!IsShown()) { - event.Skip(); - return; - } - - bool isFirstWindowShownEvent = !startupSettingsInited ; - if(startupSettingsInited == false) { - startupSettingsInited = true; - setupStartupSettings(); - } - glCanvas->setCurrentGLContext(); - - static float autoScreenshotRender = -1; - if(autoScreenShotAndExit == true && autoScreenshotRender >= 0) { - anim = autoScreenshotRender; - } - // notice that we use GetSize() here and not GetClientSize() because - // the latter doesn't return correct results for the minimized windows - // (at least not under Windows) - int viewportW = GetClientSize().x; - int viewportH = GetClientSize().y; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%d x %d\n",viewportW,viewportH); - - if(viewportW == 0 && viewportH == 0) { - printf("#1 %d x %d\n",viewportW,viewportH); - - viewportW = GetSize().x; - viewportH = GetSize().y; - - if(viewportH > 0) { - //viewportH -= menu->GetSize().y; - viewportH -= 22; } - printf("#2 %d x %d\n",viewportW,viewportH); - } + void MainWindow::onPaint(wxPaintEvent &event) { + if (!IsShown()) { + event.Skip(); + return; + } + + bool isFirstWindowShownEvent = !startupSettingsInited; + if (startupSettingsInited == false) { + startupSettingsInited = true; + setupStartupSettings(); + } + glCanvas->setCurrentGLContext(); + + static float autoScreenshotRender = -1; + if (autoScreenShotAndExit == true && autoScreenshotRender >= 0) { + anim = autoScreenshotRender; + } + // notice that we use GetSize() here and not GetClientSize() because + // the latter doesn't return correct results for the minimized windows + // (at least not under Windows) + int viewportW = GetClientSize().x; + int viewportH = GetClientSize().y; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%d x %d\n", viewportW, viewportH); + + if (viewportW == 0 && viewportH == 0) { + printf("#1 %d x %d\n", viewportW, viewportH); + + viewportW = GetSize().x; + viewportH = GetSize().y; + + if (viewportH > 0) { + //viewportH -= menu->GetSize().y; + viewportH -= 22; + } + + printf("#2 %d x %d\n", viewportW, viewportH); + } #if defined(WIN32) - renderer->reset(viewportW, viewportH, playerColor); + renderer->reset(viewportW, viewportH, playerColor); #else - renderer->reset(viewportW, viewportH, playerColor); + renderer->reset(viewportW, viewportH, playerColor); #endif - renderer->transform(rotX, rotY, zoom); - renderer->renderGrid(); + renderer->transform(rotX, rotY, zoom); + renderer->renderGrid(); - //printf("anim [%f] particleLoopStart [%d]\n",anim,particleLoopStart); + //printf("anim [%f] particleLoopStart [%d]\n",anim,particleLoopStart); - string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); - GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); + string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); + GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); - renderer->renderTheModel(model, anim); + renderer->renderTheModel(model, anim); - int updateLoops = particleLoopStart; - particleLoopStart = 1; + int updateLoops = particleLoopStart; + particleLoopStart = 1; - if(resetAnimation == true || ((anim - lastanim) >= defaultspeed*2)) { - //printf("anim [%f] [%f] [%f]\n",anim,lastanim,speed); + if (resetAnimation == true || ((anim - lastanim) >= defaultspeed * 2)) { + //printf("anim [%f] [%f] [%f]\n",anim,lastanim,speed); - for(int i=0; i< updateLoops; ++i) { - renderer->updateParticleManager(); + for (int i = 0; i < updateLoops; ++i) { + renderer->updateParticleManager(); + } + } + + renderer->renderParticleManager(); + + if (isFirstWindowShownEvent) { + this->Refresh(); + glCanvas->Refresh(); + glCanvas->SetFocus(); + } + + bool haveLoadedParticles = (particleProjectilePathList.empty() == false || particleSplashPathList.empty() == false); + + if (autoScreenShotAndExit == true && viewportW > 0 && viewportH > 0) { + printf("Auto exiting app...\n"); + fflush(stdout); + + autoScreenShotAndExit = false; + + saveScreenshot(); + Close(); + return; + } + + glCanvas->SwapBuffers(); + + if (autoScreenShotAndExit == true && viewportW == 0 && viewportH == 0) { + autoScreenshotRender = anim; + + printf("Auto exiting desired but waiting for w x h > 0...\n"); + + return; + } + if ((modelPathList.empty() == false) && resetAnimation && haveLoadedParticles) { + if (anim >= resetAnim && resetAnim > 0) { + printf("RESETTING EVERYTHING [%f][%f]...\n", anim, resetAnim); + fflush(stdout); + + resetAnimation = false; + particleLoopStart = resetParticleLoopStart; + + wxCommandEvent event; + if (unitPath.first != "") { + //onMenuFileClearAll(event); + + modelPathList.clear(); + particlePathList.clear(); + particleProjectilePathList.clear(); + particleSplashPathList.clear(); // as above + + onMenuRestart(event); + } else { + onMenuRestart(event); + } + } + } else if (modelPathList.empty() == true && haveLoadedParticles) { + if (renderer->hasActiveParticleSystem(ParticleSystem::pst_ProjectileParticleSystem) == false && + renderer->hasActiveParticleSystem(ParticleSystem::pst_SplashParticleSystem) == false) { + + printf("RESETTING PARTICLES...\n"); + fflush(stdout); + + resetAnimation = false; + anim = 0.f; + particleLoopStart = resetParticleLoopStart; + + wxCommandEvent event; + onMenuRestart(event); + } + } + + lastanim = anim; } - } - renderer->renderParticleManager(); + void MainWindow::onClose(wxCloseEvent &event) { + // release memory first (from onMenuFileClearAll) - if(isFirstWindowShownEvent) { - this->Refresh(); - glCanvas->Refresh(); - glCanvas->SetFocus(); - } + //printf("OnClose START\n"); + //fflush(stdout); - bool haveLoadedParticles = (particleProjectilePathList.empty() == false || particleSplashPathList.empty() == false); + modelPathList.clear(); + particlePathList.clear(); + particleProjectilePathList.clear(); + particleSplashPathList.clear(); // as above - if(autoScreenShotAndExit == true && viewportW > 0 && viewportH > 0) { - printf("Auto exiting app...\n"); - fflush(stdout); + if (timer) timer->Stop(); - autoScreenShotAndExit = false; + unitParticleSystems.clear(); + unitParticleSystemTypes.clear(); - saveScreenshot(); - Close(); - return; - } + projectileParticleSystems.clear(); + projectileParticleSystemTypes.clear(); + splashParticleSystems.clear(); // as above + splashParticleSystemTypes.clear(); - glCanvas->SwapBuffers(); + //delete model; + //model = NULL; + if (renderer) renderer->end(); - if(autoScreenShotAndExit == true && viewportW == 0 && viewportH == 0) { - autoScreenshotRender = anim; + //printf("OnClose about to END\n"); + //fflush(stdout); - printf("Auto exiting desired but waiting for w x h > 0...\n"); + delete timer; + timer = NULL; - return; - } - if((modelPathList.empty() == false) && resetAnimation && haveLoadedParticles) { - if(anim >= resetAnim && resetAnim > 0) { - printf("RESETTING EVERYTHING [%f][%f]...\n",anim,resetAnim); - fflush(stdout); + //delete model; + //model = NULL; - resetAnimation = false; - particleLoopStart = resetParticleLoopStart; + delete renderer; + renderer = NULL; - wxCommandEvent event; - if(unitPath.first != "") { - //onMenuFileClearAll(event); + //delete glCanvas; + if (glCanvas) { + glCanvas->Destroy(); + } + glCanvas = NULL; + + this->Destroy(); + } + + // for the mousewheel + void MainWindow::onMouseWheelDown(wxMouseEvent &event) { + try { + wxPaintEvent paintEvent; + zoom *= 1.1f; + zoom = clamp(zoom, 0.1f, 10.0f); + + string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); + GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); + + onPaint(paintEvent); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMouseWheelUp(wxMouseEvent &event) { + try { + wxPaintEvent paintEvent; + zoom *= 0.90909f; + zoom = clamp(zoom, 0.1f, 10.0f); + + string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); + GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); + + onPaint(paintEvent); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + + void MainWindow::onMouseMove(wxMouseEvent &event) { + try { + int x = event.GetX(); + int y = event.GetY(); + wxPaintEvent paintEvent; + + if (event.LeftIsDown()) { + rotX += clamp(lastX - x, -10, 10); + rotY += clamp(lastY - y, -10, 10); + + string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); + GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); + + onPaint(paintEvent); + } else if (event.RightIsDown()) { + zoom *= 1.0f + (lastX - x + lastY - y) / 100.0f; + zoom = clamp(zoom, 0.1f, 10.0f); + + string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); + GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); + + onPaint(paintEvent); + } + + lastX = x; + lastY = y; + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuFileLoad(wxCommandEvent &event) { + try { + //string fileName; + fileDialog->SetWildcard(wxT("G3D files (*.g3d)|*.g3d;*.G3D")); + fileDialog->SetMessage(wxT("Selecting Glest Model for current view.")); + + if (fileDialog->ShowModal() == wxID_OK) { + modelPathList.clear(); + string file; +#ifdef WIN32 + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(fileDialog->GetPath()); + file = tmp_buf; + + auto_ptr wstr(Ansi2WideString(file.c_str())); + file = utf8_encode(wstr.get()); +#else + file = (const char*) wxFNCONV(fileDialog->GetPath().c_str()); +#endif + + //loadModel((const char*)wxFNCONV(fileDialog->GetPath().c_str())); + loadModel(file); + } + isControlKeyPressed = false; + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuFileLoadParticleXML(wxCommandEvent &event) { + try { + //string fileName; + fileDialog->SetWildcard(wxT("XML files (*.xml)|*.xml")); + + if (isControlKeyPressed == true) { + fileDialog->SetMessage(wxT("Adding ZetaGlest particle to current view.")); + } else { + fileDialog->SetMessage(wxT("Selecting ZetaGlest particle for current view.")); + } + + if (fileDialog->ShowModal() == wxID_OK) { + //string path = (const char*)wxFNCONV(fileDialog->GetPath().c_str()); + string file; +#ifdef WIN32 + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(fileDialog->GetPath()); + file = tmp_buf; + auto_ptr wstr(Ansi2WideString(file.c_str())); + file = utf8_encode(wstr.get()); +#else + file = (const char*) wxFNCONV(fileDialog->GetPath().c_str()); +#endif + + loadParticle(file); + } + isControlKeyPressed = false; + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuFileLoadProjectileParticleXML(wxCommandEvent &event) { + try { + //string fileName; + fileDialog->SetWildcard(wxT("XML files (*.xml)|*.xml")); + + if (isControlKeyPressed == true) { + fileDialog->SetMessage(wxT("Adding ZetaGlest projectile particle to current view.")); + } else { + fileDialog->SetMessage(wxT("Selecting ZetaGlest projectile particle for current view.")); + } + + if (fileDialog->ShowModal() == wxID_OK) { + //string path = (const char*)wxFNCONV(fileDialog->GetPath().c_str()); + string file; +#ifdef WIN32 + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(fileDialog->GetPath()); + file = tmp_buf; + auto_ptr wstr(Ansi2WideString(file.c_str())); + file = utf8_encode(wstr.get()); +#else + file = (const char*) wxFNCONV(fileDialog->GetPath().c_str()); +#endif + + loadProjectileParticle(file); + } + isControlKeyPressed = false; + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuFileLoadSplashParticleXML(wxCommandEvent &event) { + try { + //string fileName; + fileDialog->SetWildcard(wxT("XML files (*.xml)|*.xml")); + + if (isControlKeyPressed == true) { + fileDialog->SetMessage(wxT("Adding ZetaGlest splash particle to current view.")); + } else { + fileDialog->SetMessage(wxT("Selecting ZetaGlest splash particle for current view.")); + } + + if (fileDialog->ShowModal() == wxID_OK) { + //string path = (const char*)wxFNCONV(fileDialog->GetPath().c_str()); + string file; +#ifdef WIN32 + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(fileDialog->GetPath()); + file = tmp_buf; + + auto_ptr wstr(Ansi2WideString(file.c_str())); + file = utf8_encode(wstr.get()); +#else + file = (const char*) wxFNCONV(fileDialog->GetPath().c_str()); +#endif + + loadSplashParticle(file); + } + isControlKeyPressed = false; + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } // is it possible to join loadParticle(), loadProjectileParticle() and loadSplashParticle() to one method? + + + void MainWindow::OnChangeColor(wxCommandEvent &event) { + try { + //wxColour color = colorPicker->GetColour(); + wxColourData data; + data.SetChooseFull(true); + for (int i = 0; i < 16; i++) { + wxColour colour(i * 16, i * 16, i * 16); + data.SetCustomColour(i, colour); + } + + wxColourDialog dialog(this, &data); + if (dialog.ShowModal() == wxID_OK) { + wxColourData retData = dialog.GetColourData(); + wxColour col = retData.GetColour(); + renderer->setBackgroundColor(col.Red() / 255.0f, col.Green() / 255.0f, col.Blue() / 255.0f); + } + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenumFileToggleScreenshotTransparent(wxCommandEvent &event) { + try { + float alpha = (event.IsChecked() == true ? 0.0f : 1.0f); + renderer->setAlphaColor(alpha); + //printf("alpha = %f\n",alpha); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::saveScreenshot() { + try { + int autoSaveScreenshotIndex = -1; + for (unsigned int i = 0; i < autoScreenShotParams.size(); ++i) { + if (_strnicmp(autoScreenShotParams[i].c_str(), "saveas-", 7) == 0) { + printf("Screenshot option [%s]\n", autoScreenShotParams[i].c_str()); + autoSaveScreenshotIndex = i; + break; + } + } + if (autoSaveScreenshotIndex >= 0) { + string saveAsFilename = autoScreenShotParams[autoSaveScreenshotIndex]; + saveAsFilename.erase(0, 7); +#ifdef WIN32 + FILE*f = _wfopen(utf8_decode(saveAsFilename).c_str(), L"rb"); +#else + FILE *f = fopen(saveAsFilename.c_str(), "rb"); +#endif + if (f == NULL) { + renderer->saveScreen(saveAsFilename.c_str(), &overrideSize); + } else { + if (f) { + fclose(f); + } + } + } else { + //string screenShotsPath = extractDirectoryPathFromFile(appPath) + string("screens/"); + string userData = Config::getInstance().getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + string screenShotsPath = userData + string("screens/"); + printf("screenShotsPath [%s]\n", screenShotsPath.c_str()); + + if (isdir(screenShotsPath.c_str()) == false) { + createDirectoryPaths(screenShotsPath); + } + + string path = screenShotsPath; + if (isdir(path.c_str()) == true) { + //Config &config= Config::getInstance(); + //string fileFormat = config.getString("ScreenShotFileType","jpg"); + + for (int i = 0; i < 5000; ++i) { + path = screenShotsPath; + path += string("screen") + intToStr(i) + string(".") + fileFormat; +#ifdef WIN32 + FILE*f = _wfopen(utf8_decode(path).c_str(), L"rb"); +#else + FILE *f = fopen(path.c_str(), "rb"); +#endif + if (f == NULL) { + renderer->saveScreen(path, &overrideSize); + break; + } else { + if (f) { + fclose(f); + } + } + } + } + } + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuFileSaveScreenshot(wxCommandEvent &event) { + saveScreenshot(); + } + + void MainWindow::onMenuFileClearAll(wxCommandEvent &event) { + try { + //printf("Start onMenuFileClearAll\n"); + //fflush(stdout); modelPathList.clear(); particlePathList.clear(); particleProjectilePathList.clear(); particleSplashPathList.clear(); // as above - onMenuRestart(event); - } - else { - onMenuRestart(event); + if (timer) timer->Stop(); + if (renderer) renderer->end(); + + unitParticleSystems.clear(); + unitParticleSystemTypes.clear(); + + projectileParticleSystems.clear(); + projectileParticleSystemTypes.clear(); + splashParticleSystems.clear(); // as above + splashParticleSystemTypes.clear(); + + //delete model; + //model = NULL; + if (model != NULL && renderer != NULL) renderer->endModel(rsGlobal, model); + model = NULL; + + loadUnit("", ""); + loadModel(""); + loadParticle(""); + loadProjectileParticle(""); + loadSplashParticle(""); // as above + + GetStatusBar()->SetStatusText(ToUnicode(statusbarText.c_str())); + isControlKeyPressed = false; + + //printf("END onMenuFileClearAll\n"); + //fflush(stdout); + + if (timer) timer->Start(100); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); } } - } - else if(modelPathList.empty() == true && haveLoadedParticles) { - if(renderer->hasActiveParticleSystem(ParticleSystem::pst_ProjectileParticleSystem) == false && - renderer->hasActiveParticleSystem(ParticleSystem::pst_SplashParticleSystem) == false) { - printf("RESETTING PARTICLES...\n"); - fflush(stdout); - - resetAnimation = false; - anim = 0.f; - particleLoopStart = resetParticleLoopStart; - - wxCommandEvent event; - onMenuRestart(event); + void MainWindow::onMenuFileExit(wxCommandEvent &event) { + Close(); } - } - lastanim = anim; -} + void MainWindow::loadUnit(string path, string skillName) { + if (path != "" && fileExists(path) == true) { + // std::cout << "Clearing list..." << std::endl; + this->unitPath.first = path; + this->unitPath.second.push_back(skillName); + } -void MainWindow::onClose(wxCloseEvent &event){ - // release memory first (from onMenuFileClearAll) + try { + if (this->unitPath.first != "") { + if (timer) timer->Stop(); + if (renderer) renderer->end(); - //printf("OnClose START\n"); - //fflush(stdout); + string titlestring = winHeader; - modelPathList.clear(); - particlePathList.clear(); - particleProjectilePathList.clear(); - particleSplashPathList.clear(); // as above + string unitPath = this->unitPath.first; + string dir = unitPath; + string name = lastDir(dir); + string path = dir + "/" + name + ".xml"; - if(timer) timer->Stop(); + titlestring = unitPath + " - " + titlestring; - unitParticleSystems.clear(); - unitParticleSystemTypes.clear(); + std::string unitXML = path; - projectileParticleSystems.clear(); - projectileParticleSystemTypes.clear(); - splashParticleSystems.clear(); // as above - splashParticleSystemTypes.clear(); + string skillModelFile = ""; + string skillParticleFile = ""; + string skillParticleProjectileFile = ""; + string skillParticleSplashFile = ""; + bool fileFound = fileExists(unitXML); - //delete model; - //model = NULL; - if(renderer) renderer->end(); + printf("Loading unit from file [%s] fileFound = %d\n", unitXML.c_str(), fileFound); - //printf("OnClose about to END\n"); - //fflush(stdout); + if (fileFound == true) { + XmlTree xmlTree; + xmlTree.load(unitXML, Properties::getTagReplacementValues()); + const XmlNode *unitNode = xmlTree.getRootNode(); - delete timer; - timer = NULL; + bool foundSkillName = false; + for (unsigned int skillIdx = 0; foundSkillName == false && skillIdx < this->unitPath.second.size(); ++skillIdx) { + string lookipForSkillName = this->unitPath.second[skillIdx]; - //delete model; - //model = NULL; + const XmlNode *skillsNode = unitNode->getChild("skills"); + for (unsigned int i = 0; foundSkillName == false && i < skillsNode->getChildCount(); ++i) { + const XmlNode *sn = skillsNode->getChild("skill", i); + //const XmlNode *typeNode= sn->getChild("type"); + const XmlNode *nameNode = sn->getChild("name"); + string skillXmlName = nameNode->getAttribute("value")->getRestrictedValue(); + if (skillXmlName == lookipForSkillName) { + printf("Found skill [%s]\n", lookipForSkillName.c_str()); + foundSkillName = true; - delete renderer; - renderer = NULL; + if (sn->getChild("animation") != NULL) { + skillModelFile = sn->getChild("animation")->getAttribute("path")->getRestrictedValue(unitPath + '/'); + printf("Found skill model [%s]\n", skillModelFile.c_str()); + } - //delete glCanvas; - if(glCanvas) { - glCanvas->Destroy(); - } - glCanvas = NULL; + if (sn->hasChild("particles") == true) { + const XmlNode *particlesNode = sn->getChild("particles"); + //for(int j = 0; particlesNode != NULL && particlesNode->getAttribute("value")->getRestrictedValue() == "true" && + // j < particlesNode->getChildCount(); ++j) { + if (particlesNode != NULL && particlesNode->getAttribute("value")->getRestrictedValue() == "true" && + particlesNode->hasChild("particle-file") == true) { + const XmlNode *pf = particlesNode->getChild("particle-file"); + if (pf != NULL) { + skillParticleFile = unitPath + '/' + pf->getAttribute("path")->getRestrictedValue(); + printf("Found skill particle [%s]\n", skillParticleFile.c_str()); + } + } + } + if (sn->hasChild("projectile") == true) { + const XmlNode *particlesProjectileNode = sn->getChild("projectile"); + //for(int j = 0; particlesProjectileNode != NULL && particlesProjectileNode->getAttribute("value")->getRestrictedValue() == "true" && + // j < particlesProjectileNode->getChildCount(); ++j) { + if (particlesProjectileNode != NULL && particlesProjectileNode->getAttribute("value")->getRestrictedValue() == "true" && + particlesProjectileNode->hasChild("particle") == true) { + const XmlNode *pf = particlesProjectileNode->getChild("particle"); + if (pf != NULL && pf->getAttribute("value")->getRestrictedValue() == "true") { + skillParticleProjectileFile = unitPath + '/' + pf->getAttribute("path")->getRestrictedValue(); + printf("Found skill skill projectile particle [%s]\n", skillParticleProjectileFile.c_str()); + } + } + } + if (sn->hasChild("splash") == true) { + const XmlNode *particlesSplashNode = sn->getChild("splash"); + //for(int j = 0; particlesSplashNode != NULL && particlesSplashNode->getAttribute("value")->getRestrictedValue() == "true" && + // j < particlesSplashNode->getChildCount(); ++j) { + if (particlesSplashNode != NULL && particlesSplashNode->getAttribute("value")->getRestrictedValue() == "true" && + particlesSplashNode->hasChild("particle") == true) { + const XmlNode *pf = particlesSplashNode->getChild("particle"); + if (pf != NULL && pf->getAttribute("value")->getRestrictedValue() == "true") { + skillParticleSplashFile = unitPath + '/' + pf->getAttribute("path")->getRestrictedValue(); + printf("Found skill skill splash particle [%s]\n", skillParticleSplashFile.c_str()); + } + } + } + } + } + } - this->Destroy(); -} - -// for the mousewheel -void MainWindow::onMouseWheelDown(wxMouseEvent &event) { - try { - wxPaintEvent paintEvent; - zoom*= 1.1f; - zoom= clamp(zoom, 0.1f, 10.0f); - - string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); - GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); - - onPaint(paintEvent); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMouseWheelUp(wxMouseEvent &event) { - try { - wxPaintEvent paintEvent; - zoom*= 0.90909f; - zoom= clamp(zoom, 0.1f, 10.0f); - - string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); - GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); - - onPaint(paintEvent); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - - -void MainWindow::onMouseMove(wxMouseEvent &event){ - try { - int x= event.GetX(); - int y= event.GetY(); - wxPaintEvent paintEvent; - - if(event.LeftIsDown()){ - rotX+= clamp(lastX-x, -10, 10); - rotY+= clamp(lastY-y, -10, 10); - - string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); - GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); - - onPaint(paintEvent); + if (skillModelFile != "") { + this->modelPathList.push_back(skillModelFile); + printf("Added skill model [%s]\n", skillModelFile.c_str()); + } + if (skillParticleFile != "") { + this->particlePathList.push_back(skillParticleFile); + printf("Added skill particle [%s]\n", skillParticleFile.c_str()); + } + if (skillParticleProjectileFile != "") { + this->particleProjectilePathList.push_back(skillParticleProjectileFile); + printf("Added skill projectile particle [%s]\n", skillParticleProjectileFile.c_str()); + } + if (skillParticleSplashFile != "") { + this->particleSplashPathList.push_back(skillParticleSplashFile); + printf("Added skill splash particle [%s]\n", skillParticleSplashFile.c_str()); + } + } + SetTitle(ToUnicode(titlestring)); + } + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Not a ZetaGlest particle XML file, or broken"), wxOK | wxICON_ERROR).ShowModal(); + } } - else if(event.RightIsDown()){ - zoom*= 1.0f+(lastX-x+lastY-y)/100.0f; - zoom= clamp(zoom, 0.1f, 10.0f); - string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); - GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); + void MainWindow::loadModel(string path) { + try { + if (path != "" && fileExists(path) == true) { + this->modelPathList.push_back(path); + printf("Adding model [%s] list size " MG_SIZE_T_SPECIFIER "\n", path.c_str(), this->modelPathList.size()); + } + string titlestring = winHeader; + for (unsigned int idx = 0; idx < this->modelPathList.size(); idx++) { + string modelPath = this->modelPathList[idx]; + + //printf("Loading model [%s] %u of " MG_SIZE_T_SPECIFIER "\n",modelPath.c_str(),idx, this->modelPathList.size()); + + if (timer) timer->Stop(); + //delete model; + if (model != NULL && renderer != NULL) renderer->endModel(rsGlobal, model); + model = NULL; + model = renderer ? renderer->newModel(rsGlobal, modelPath) : NULL; + + statusbarText = getModelInfo(); + string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); + GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); + if (timer) timer->Start(100); + titlestring = extractFileFromDirectoryPath(modelPath) + " - " + titlestring; + } + SetTitle(ToUnicode(titlestring)); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::loadParticle(string path) { + if (timer) timer->Stop(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, path.c_str()); + if (path != "" && fileExists(path) == true) { + renderer->end(); + unitParticleSystems.clear(); + unitParticleSystemTypes.clear(); + + if (isControlKeyPressed == true) { + // std::cout << "Adding to list..." << std::endl; + this->particlePathList.push_back(path); + } else { + // std::cout << "Clearing list..." << std::endl; + this->particlePathList.clear(); + this->particlePathList.push_back(path); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] added file [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, path.c_str()); + } + + try { + if (this->particlePathList.empty() == false) { + string titlestring = winHeader; + for (unsigned int idx = 0; idx < this->particlePathList.size(); idx++) { + string particlePath = this->particlePathList[idx]; + string dir = extractDirectoryPathFromFile(particlePath); + + size_t pos = dir.find_last_of(folderDelimiter); + if (pos == dir.length() - 1 && dir.length() > 0) { + dir.erase(dir.length() - 1); + } + + particlePath = extractFileFromDirectoryPath(particlePath); + titlestring = particlePath + " - " + titlestring; + + std::string unitXML = dir + folderDelimiter + extractFileFromDirectoryPath(dir) + ".xml"; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] looking for unit XML [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, unitXML.c_str()); + + //int size = -1; + //int height = -1; + int size = 0; + int height = 0; + + if (fileExists(unitXML) == true) { + { + XmlTree xmlTree; + xmlTree.load(unitXML, Properties::getTagReplacementValues()); + const XmlNode *unitNode = xmlTree.getRootNode(); + const XmlNode *parametersNode = unitNode->getChild("parameters"); + //size + size = parametersNode->getChild("size")->getAttribute("value")->getIntValue(); + //height + height = parametersNode->getChild("height")->getAttribute("value")->getIntValue(); + } + + // std::cout << "About to load [" << particlePath << "] from [" << dir << "] unit [" << unitXML << "]" << std::endl; + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] unit XML NOT FOUND [%s] using default position values\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, unitXML.c_str()); + + size = 1; + height = 1; + } + + std::map > > loadedFileList; + UnitParticleSystemType *unitParticleSystemType = new UnitParticleSystemType(); + unitParticleSystemType->load(NULL, dir, dir + folderDelimiter + particlePath, //### if we knew which particle it was, we could be more accurate + renderer, loadedFileList, "g3dviewer", ""); + unitParticleSystemTypes.push_back(unitParticleSystemType); + + for (std::vector::const_iterator it = unitParticleSystemTypes.begin(); it != unitParticleSystemTypes.end(); ++it) { + UnitParticleSystem *ups = new UnitParticleSystem(200); + + ups->setParticleType((*it)); + (*it)->setValues(ups); + if (size > 0) { + //getCurrVectorFlat() + Vec3f(0.f, type->getHeight()/2.f, 0.f); + Vec3f vec = Vec3f(0.f, height / 2.f, 0.f); + ups->setPos(vec); + } + //ups->setFactionColor(getFaction()->getTexture()->getPixmap()->getPixel3f(0,0)); + ups->setFactionColor(renderer->getPlayerColorTexture(playerColor)->getPixmap()->getPixel3f(0, 0)); + unitParticleSystems.push_back(ups); + renderer->manageParticleSystem(ups); + + ups->setVisible(true); + } + + if (path != "" && fileExists(path) == true) { + renderer->initModelManager(); + if (initTextureManager) { + renderer->initTextureManager(); + } + } + + } + SetTitle(ToUnicode(titlestring)); + } + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Not a Mega-Glest particle XML file, or broken"), wxOK | wxICON_ERROR).ShowModal(); + } + if (timer) timer->Start(100); + } + + void MainWindow::loadProjectileParticle(string path) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s] particleProjectilePathList.size() = " MG_SIZE_T_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, path.c_str(), this->particleProjectilePathList.size()); + + if (timer) timer->Stop(); + if (path != "" && fileExists(path) == true) { + renderer->end(); + projectileParticleSystems.clear(); + projectileParticleSystemTypes.clear(); + + if (isControlKeyPressed == true) { + // std::cout << "Adding to list..." << std::endl; + this->particleProjectilePathList.push_back(path); + } else { + // std::cout << "Clearing list..." << std::endl; + this->particleProjectilePathList.clear(); + this->particleProjectilePathList.push_back(path); + } + } + + try { + if (this->particleProjectilePathList.empty() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("this->particleProjectilePathList.size() = " MG_SIZE_T_SPECIFIER "\n", this->particleProjectilePathList.size()); + + string titlestring = winHeader; + for (unsigned int idx = 0; idx < this->particleProjectilePathList.size(); idx++) { + string particlePath = this->particleProjectilePathList[idx]; + string dir = extractDirectoryPathFromFile(particlePath); + + size_t pos = dir.find_last_of(folderDelimiter); + if (pos == dir.length() - 1) { + dir.erase(dir.length() - 1); + } + + particlePath = extractFileFromDirectoryPath(particlePath); + titlestring = particlePath + " - " + titlestring; + + std::string unitXML = dir + folderDelimiter + extractFileFromDirectoryPath(dir) + ".xml"; + + int size = 1; + int height = 1; + + if (fileExists(unitXML) == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] loading [%s] idx = %u\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, unitXML.c_str(), idx); + + XmlTree xmlTree; + xmlTree.load(unitXML, Properties::getTagReplacementValues()); + const XmlNode *unitNode = xmlTree.getRootNode(); + const XmlNode *parametersNode = unitNode->getChild("parameters"); + //size + size = parametersNode->getChild("size")->getAttribute("value")->getIntValue(); + //height + height = parametersNode->getChild("height")->getAttribute("value")->getIntValue(); + } + + // std::cout << "About to load [" << particlePath << "] from [" << dir << "] unit [" << unitXML << "]" << std::endl; + + string particleFile = dir + folderDelimiter + particlePath; + { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] loading [%s] idx = %u\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, particleFile.c_str(), idx); + XmlTree xmlTree; + xmlTree.load(particleFile, Properties::getTagReplacementValues()); + //const XmlNode *particleSystemNode= xmlTree.getRootNode(); + + // std::cout << "Loaded successfully, loading values..." << std::endl; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] loading [%s] idx = %u\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, particleFile.c_str(), idx); + std::map > > loadedFileList; + ParticleSystemTypeProjectile *projectileParticleSystemType = new ParticleSystemTypeProjectile(); + projectileParticleSystemType->load(NULL, dir, //### we don't know if there are overrides in the unit XML + particleFile, renderer, loadedFileList, + "g3dviewer", ""); + + // std::cout << "Values loaded, about to read..." << std::endl; + + projectileParticleSystemTypes.push_back(projectileParticleSystemType); + + for (std::vector::const_iterator it = projectileParticleSystemTypes.begin(); + it != projectileParticleSystemTypes.end(); ++it) { + + ProjectileParticleSystem *ps = (*it)->create(NULL); + + if (size > 0) { + Vec3f vec = Vec3f(0.f, height / 2.f, 0.f); + //ps->setPos(vec); + + Vec3f vec2 = Vec3f(size * 2.f, height * 2.f, height * 2.f); + ps->setPath(vec, vec2); + } + ps->setFactionColor(renderer->getPlayerColorTexture(playerColor)->getPixmap()->getPixel3f(0, 0)); + + projectileParticleSystems.push_back(ps); + + ps->setVisible(true); + renderer->manageParticleSystem(ps); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] loaded [%s] idx = %u\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, particleFile.c_str(), idx); + } + SetTitle(ToUnicode(titlestring)); + + if (path != "" && fileExists(path) == true) { + renderer->initModelManager(); + if (initTextureManager) { + renderer->initTextureManager(); + } + } + } + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Not a ZetaGlest projectile particle XML file, or broken"), wxOK | wxICON_ERROR).ShowModal(); + } + if (timer) timer->Start(100); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] after load [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, path.c_str()); + } + + void MainWindow::loadSplashParticle(string path) { // uses ParticleSystemTypeSplash::load (and own list...) + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s] particleSplashPathList.size() = " MG_SIZE_T_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, path.c_str(), this->particleSplashPathList.size()); + + if (timer) timer->Stop(); + if (path != "" && fileExists(path) == true) { + renderer->end(); + splashParticleSystems.clear(); + splashParticleSystemTypes.clear(); + + if (isControlKeyPressed == true) { + // std::cout << "Adding to list..." << std::endl; + this->particleSplashPathList.push_back(path); + } else { + // std::cout << "Clearing list..." << std::endl; + this->particleSplashPathList.clear(); + this->particleSplashPathList.push_back(path); + } + } + + try { + if (this->particleSplashPathList.empty() == false) { + string titlestring = winHeader; + for (unsigned int idx = 0; idx < this->particleSplashPathList.size(); idx++) { + string particlePath = this->particleSplashPathList[idx]; + string dir = extractDirectoryPathFromFile(particlePath); + + size_t pos = dir.find_last_of(folderDelimiter); + if (pos == dir.length() - 1) { + dir.erase(dir.length() - 1); + } + + particlePath = extractFileFromDirectoryPath(particlePath); + titlestring = particlePath + " - " + titlestring; + + std::string unitXML = dir + folderDelimiter + extractFileFromDirectoryPath(dir) + ".xml"; + + int size = 1; + //int height = 1; + + if (fileExists(unitXML) == true) { + XmlTree xmlTree; + xmlTree.load(unitXML, Properties::getTagReplacementValues()); + const XmlNode *unitNode = xmlTree.getRootNode(); + const XmlNode *parametersNode = unitNode->getChild("parameters"); + //size + size = parametersNode->getChild("size")->getAttribute("value")->getIntValue(); + //height + //height= parametersNode->getChild("height")->getAttribute("value")->getIntValue(); + } + + // std::cout << "About to load [" << particlePath << "] from [" << dir << "] unit [" << unitXML << "]" << std::endl; + + { + XmlTree xmlTree; + xmlTree.load(dir + folderDelimiter + particlePath, Properties::getTagReplacementValues()); + //const XmlNode *particleSystemNode= xmlTree.getRootNode(); + // std::cout << "Loaded successfully, loading values..." << std::endl; + } + + std::map > > loadedFileList; + ParticleSystemTypeSplash *splashParticleSystemType = new ParticleSystemTypeSplash(); + splashParticleSystemType->load(NULL, dir, dir + folderDelimiter + particlePath, renderer, //### we don't know if there are overrides in the unit XML + loadedFileList, "g3dviewer", ""); // <---- only that must be splash... + + // std::cout << "Values loaded, about to read..." << std::endl; + + splashParticleSystemTypes.push_back(splashParticleSystemType); + + //ParticleSystemTypeSplash + for (std::vector::const_iterator it = splashParticleSystemTypes.begin(); it != splashParticleSystemTypes.end(); ++it) { + + SplashParticleSystem *ps = (*it)->create(NULL); + + if (size > 0) { + //Vec3f vec = Vec3f(0.f, height / 2.f, 0.f); + //ps->setPos(vec); + + //Vec3f vec2 = Vec3f(size * 2.f, height * 2.f, height * 2.f); // <------- removed relative projectile + //ps->setPath(vec, vec2); // <------- removed relative projectile + } + ps->setFactionColor(renderer->getPlayerColorTexture(playerColor)->getPixmap()->getPixel3f(0, 0)); + + splashParticleSystems.push_back(ps); + + ps->setVisible(true); + renderer->manageParticleSystem(ps); + } + } + SetTitle(ToUnicode(titlestring)); + + if (path != "" && fileExists(path) == true) { + renderer->initModelManager(); + if (initTextureManager) { + renderer->initTextureManager(); + } + } + } + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Not a ZetaGlest projectile particle XML file, or broken"), wxOK | wxICON_ERROR).ShowModal(); + } + if (timer) timer->Start(100); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] after load [%s] particleSplashPathList.size() = " MG_SIZE_T_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, path.c_str(), this->particleSplashPathList.size()); + } + + void MainWindow::onMenuModeNormals(wxCommandEvent &event) { + try { + renderer->toggleNormals(); + menuMode->Check(miModeNormals, renderer->getNormals()); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuModeWireframe(wxCommandEvent &event) { + try { + renderer->toggleWireframe(); + menuMode->Check(miModeWireframe, renderer->getWireframe()); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuModeGrid(wxCommandEvent &event) { + try { + renderer->toggleGrid(); + menuMode->Check(miModeGrid, renderer->getGrid()); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuSpeedSlower(wxCommandEvent &event) { + try { + speed /= 1.5f; + if (speed < 0) { + speed = 0; + } + + string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); + GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuSpeedFaster(wxCommandEvent &event) { + try { + speed *= 1.5f; + if (speed > 1) { + speed = 1; + } + + string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); + GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + // set menu checkboxes to what player color is used + void MainWindow::onMenuColorRed(wxCommandEvent &event) { + try { + playerColor = Renderer::pcRed; + menuCustomColor->Check(miColorRed, true); + menuCustomColor->Check(miColorBlue, false); + menuCustomColor->Check(miColorGreen, false); + menuCustomColor->Check(miColorYellow, false); + menuCustomColor->Check(miColorWhite, false); + menuCustomColor->Check(miColorCyan, false); + menuCustomColor->Check(miColorOrange, false); + menuCustomColor->Check(miColorMagenta, false); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuColorBlue(wxCommandEvent &event) { + try { + playerColor = Renderer::pcBlue; + menuCustomColor->Check(miColorRed, false); + menuCustomColor->Check(miColorBlue, true); + menuCustomColor->Check(miColorGreen, false); + menuCustomColor->Check(miColorYellow, false); + menuCustomColor->Check(miColorWhite, false); + menuCustomColor->Check(miColorCyan, false); + menuCustomColor->Check(miColorOrange, false); + menuCustomColor->Check(miColorMagenta, false); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuColorGreen(wxCommandEvent &event) { + try { + playerColor = Renderer::pcGreen; + menuCustomColor->Check(miColorRed, false); + menuCustomColor->Check(miColorBlue, false); + menuCustomColor->Check(miColorGreen, true); + menuCustomColor->Check(miColorYellow, false); + menuCustomColor->Check(miColorWhite, false); + menuCustomColor->Check(miColorCyan, false); + menuCustomColor->Check(miColorOrange, false); + menuCustomColor->Check(miColorMagenta, false); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuColorYellow(wxCommandEvent &event) { + try { + playerColor = Renderer::pcYellow; + menuCustomColor->Check(miColorRed, false); + menuCustomColor->Check(miColorBlue, false); + menuCustomColor->Check(miColorGreen, false); + menuCustomColor->Check(miColorYellow, true); + menuCustomColor->Check(miColorWhite, false); + menuCustomColor->Check(miColorCyan, false); + menuCustomColor->Check(miColorOrange, false); + menuCustomColor->Check(miColorMagenta, false); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuColorWhite(wxCommandEvent &event) { + try { + playerColor = Renderer::pcWhite; + menuCustomColor->Check(miColorRed, false); + menuCustomColor->Check(miColorBlue, false); + menuCustomColor->Check(miColorGreen, false); + menuCustomColor->Check(miColorYellow, false); + menuCustomColor->Check(miColorWhite, true); + menuCustomColor->Check(miColorCyan, false); + menuCustomColor->Check(miColorOrange, false); + menuCustomColor->Check(miColorMagenta, false); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuColorCyan(wxCommandEvent &event) { + try { + playerColor = Renderer::pcCyan; + menuCustomColor->Check(miColorRed, false); + menuCustomColor->Check(miColorBlue, false); + menuCustomColor->Check(miColorGreen, false); + menuCustomColor->Check(miColorYellow, false); + menuCustomColor->Check(miColorWhite, false); + menuCustomColor->Check(miColorCyan, true); + menuCustomColor->Check(miColorOrange, false); + menuCustomColor->Check(miColorMagenta, false); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuColorOrange(wxCommandEvent &event) { + try { + playerColor = Renderer::pcOrange; + menuCustomColor->Check(miColorRed, false); + menuCustomColor->Check(miColorBlue, false); + menuCustomColor->Check(miColorGreen, false); + menuCustomColor->Check(miColorYellow, false); + menuCustomColor->Check(miColorWhite, false); + menuCustomColor->Check(miColorCyan, false); + menuCustomColor->Check(miColorOrange, true); + menuCustomColor->Check(miColorMagenta, false); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + void MainWindow::onMenuColorMagenta(wxCommandEvent &event) { + try { + playerColor = Renderer::pcMagenta; + menuCustomColor->Check(miColorRed, false); + menuCustomColor->Check(miColorBlue, false); + menuCustomColor->Check(miColorGreen, false); + menuCustomColor->Check(miColorYellow, false); + menuCustomColor->Check(miColorWhite, false); + menuCustomColor->Check(miColorCyan, false); + menuCustomColor->Check(miColorOrange, false); + menuCustomColor->Check(miColorMagenta, true); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); + } + } + + + void MainWindow::onTimer(wxTimerEvent &event) { + anim = anim + speed; + if (anim > 1.0f) { + anim -= 1.f; + resetAnimation = true; + } + wxPaintEvent paintEvent; onPaint(paintEvent); } - lastX= x; - lastY= y; - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} + string MainWindow::getModelInfo() { + string str; -void MainWindow::onMenuFileLoad(wxCommandEvent &event){ - try { - //string fileName; - fileDialog->SetWildcard(wxT("G3D files (*.g3d)|*.g3d;*.G3D")); - fileDialog->SetMessage(wxT("Selecting Glest Model for current view.")); - - if(fileDialog->ShowModal()==wxID_OK){ - modelPathList.clear(); - string file; -#ifdef WIN32 - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(fileDialog->GetPath()); - file = tmp_buf; - - auto_ptr wstr(Ansi2WideString(file.c_str())); - file = utf8_encode(wstr.get()); -#else - file = (const char*)wxFNCONV(fileDialog->GetPath().c_str()); -#endif - - //loadModel((const char*)wxFNCONV(fileDialog->GetPath().c_str())); - loadModel(file); - } - isControlKeyPressed = false; - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuFileLoadParticleXML(wxCommandEvent &event){ - try { - //string fileName; - fileDialog->SetWildcard(wxT("XML files (*.xml)|*.xml")); - - if(isControlKeyPressed == true) { - fileDialog->SetMessage(wxT("Adding ZetaGlest particle to current view.")); - } - else { - fileDialog->SetMessage(wxT("Selecting ZetaGlest particle for current view.")); - } - - if(fileDialog->ShowModal()==wxID_OK){ - //string path = (const char*)wxFNCONV(fileDialog->GetPath().c_str()); - string file; -#ifdef WIN32 - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(fileDialog->GetPath()); - file = tmp_buf; - auto_ptr wstr(Ansi2WideString(file.c_str())); - file = utf8_encode(wstr.get()); -#else - file = (const char*)wxFNCONV(fileDialog->GetPath().c_str()); -#endif - - loadParticle(file); - } - isControlKeyPressed = false; - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuFileLoadProjectileParticleXML(wxCommandEvent &event){ - try { - //string fileName; - fileDialog->SetWildcard(wxT("XML files (*.xml)|*.xml")); - - if(isControlKeyPressed == true) { - fileDialog->SetMessage(wxT("Adding ZetaGlest projectile particle to current view.")); - } - else { - fileDialog->SetMessage(wxT("Selecting ZetaGlest projectile particle for current view.")); - } - - if(fileDialog->ShowModal()==wxID_OK){ - //string path = (const char*)wxFNCONV(fileDialog->GetPath().c_str()); - string file; -#ifdef WIN32 - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(fileDialog->GetPath()); - file = tmp_buf; - auto_ptr wstr(Ansi2WideString(file.c_str())); - file = utf8_encode(wstr.get()); -#else - file = (const char*)wxFNCONV(fileDialog->GetPath().c_str()); -#endif - - loadProjectileParticle(file); - } - isControlKeyPressed = false; - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuFileLoadSplashParticleXML(wxCommandEvent &event){ - try { - //string fileName; - fileDialog->SetWildcard(wxT("XML files (*.xml)|*.xml")); - - if(isControlKeyPressed == true) { - fileDialog->SetMessage(wxT("Adding ZetaGlest splash particle to current view.")); - } - else { - fileDialog->SetMessage(wxT("Selecting ZetaGlest splash particle for current view.")); - } - - if(fileDialog->ShowModal()==wxID_OK){ - //string path = (const char*)wxFNCONV(fileDialog->GetPath().c_str()); - string file; -#ifdef WIN32 - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(fileDialog->GetPath()); - file = tmp_buf; - - auto_ptr wstr(Ansi2WideString(file.c_str())); - file = utf8_encode(wstr.get()); -#else - file = (const char*)wxFNCONV(fileDialog->GetPath().c_str()); -#endif - - loadSplashParticle(file); - } - isControlKeyPressed = false; - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} // is it possible to join loadParticle(), loadProjectileParticle() and loadSplashParticle() to one method? - - -void MainWindow::OnChangeColor(wxCommandEvent &event) { - try { - //wxColour color = colorPicker->GetColour(); - wxColourData data; - data.SetChooseFull(true); - for (int i = 0; i < 16; i++) - { - wxColour colour(i*16, i*16, i*16); - data.SetCustomColour(i, colour); - } - - wxColourDialog dialog(this, &data); - if (dialog.ShowModal() == wxID_OK) - { - wxColourData retData = dialog.GetColourData(); - wxColour col = retData.GetColour(); - renderer->setBackgroundColor(col.Red()/255.0f, col.Green()/255.0f, col.Blue()/255.0f); - } - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenumFileToggleScreenshotTransparent(wxCommandEvent &event) { - try { - float alpha = (event.IsChecked() == true ? 0.0f : 1.0f); - renderer->setAlphaColor(alpha); - //printf("alpha = %f\n",alpha); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::saveScreenshot() { - try { - int autoSaveScreenshotIndex = -1; - for(unsigned int i = 0; i < autoScreenShotParams.size(); ++i) { - if(_strnicmp(autoScreenShotParams[i].c_str(),"saveas-",7) == 0) { - printf("Screenshot option [%s]\n",autoScreenShotParams[i].c_str()); - autoSaveScreenshotIndex = i; - break; - } - } - if(autoSaveScreenshotIndex >= 0) { - string saveAsFilename = autoScreenShotParams[autoSaveScreenshotIndex]; - saveAsFilename.erase(0,7); -#ifdef WIN32 - FILE*f = _wfopen(utf8_decode(saveAsFilename).c_str(), L"rb"); -#else - FILE *f= fopen(saveAsFilename.c_str(), "rb"); -#endif - if(f == NULL) { - renderer->saveScreen(saveAsFilename.c_str(),&overrideSize); + if (model != NULL) { + str += "Meshes: " + intToStr(model->getMeshCount()); + str += ", Vertices: " + intToStr(model->getVertexCount()); + str += ", Triangles: " + intToStr(model->getTriangleCount()); + str += ", Version: " + intToStr(model->getFileVersion()); } - else { - if(f) { - fclose(f); + + return str; + } + + void MainWindow::onKeyDown(wxKeyEvent &e) { + + try { + // std::cout << "e.ControlDown() = " << e.ControlDown() << " e.GetKeyCode() = " << e.GetKeyCode() << " isCtrl = " << (e.GetKeyCode() == WXK_CONTROL) << std::endl; + + // Note: This ctrl-key handling is buggy since it never resets when ctrl is released later, so I reset it at end of loadcommands for now. + if (e.ControlDown() == true || e.GetKeyCode() == WXK_CONTROL) { + isControlKeyPressed = true; + } else { + isControlKeyPressed = false; } - } - } - else { - //string screenShotsPath = extractDirectoryPathFromFile(appPath) + string("screens/"); - string userData = Config::getInstance().getString("UserData_Root",""); - if(userData != "") { - endPathWithSlash(userData); - } - string screenShotsPath = userData + string("screens/"); - printf("screenShotsPath [%s]\n",screenShotsPath.c_str()); - if(isdir(screenShotsPath.c_str()) == false) { - createDirectoryPaths(screenShotsPath); - } + // std::cout << "isControlKeyPressed = " << isControlKeyPressed << std::endl; - string path = screenShotsPath; - if(isdir(path.c_str()) == true) { - //Config &config= Config::getInstance(); - //string fileFormat = config.getString("ScreenShotFileType","jpg"); - for(int i=0; i < 5000; ++i) { - path = screenShotsPath; - path += string("screen") + intToStr(i) + string(".") + fileFormat; -#ifdef WIN32 - FILE*f= _wfopen(utf8_decode(path).c_str(), L"rb"); -#else - FILE *f= fopen(path.c_str(), "rb"); -#endif - if(f == NULL) { - renderer->saveScreen(path,&overrideSize); - break; + // here also because + and - hotkeys don't work for numpad automaticly + if (e.GetKeyCode() == 388) { + speed *= 1.5f; //numpad+ + if (speed > 1.0) { + speed = 1.0; } - else { - if(f) { - fclose(f); - } + + string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); + GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); + + } else if (e.GetKeyCode() == 390) { + speed /= 1.5f; //numpad- + if (speed < 0) { + speed = 0; } - } - } - } - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} + string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); + GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); + } else if (e.GetKeyCode() == 'W') { + glClearColor(0.6f, 0.6f, 0.6f, 1.0f); //w key //backgroundcolor constant 0.3 -> 0.6 -void MainWindow::onMenuFileSaveScreenshot(wxCommandEvent &event) { - saveScreenshot(); -} - -void MainWindow::onMenuFileClearAll(wxCommandEvent &event) { - try { - //printf("Start onMenuFileClearAll\n"); - //fflush(stdout); - - modelPathList.clear(); - particlePathList.clear(); - particleProjectilePathList.clear(); - particleSplashPathList.clear(); // as above - - if(timer) timer->Stop(); - if(renderer) renderer->end(); - - unitParticleSystems.clear(); - unitParticleSystemTypes.clear(); - - projectileParticleSystems.clear(); - projectileParticleSystemTypes.clear(); - splashParticleSystems.clear(); // as above - splashParticleSystemTypes.clear(); - - //delete model; - //model = NULL; - if(model != NULL && renderer != NULL) renderer->endModel(rsGlobal, model); - model = NULL; - - loadUnit("",""); - loadModel(""); - loadParticle(""); - loadProjectileParticle(""); - loadSplashParticle(""); // as above - - GetStatusBar()->SetStatusText(ToUnicode(statusbarText.c_str())); - isControlKeyPressed = false; - - //printf("END onMenuFileClearAll\n"); - //fflush(stdout); - - if(timer) timer->Start(100); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuFileExit(wxCommandEvent &event) { - Close(); -} - -void MainWindow::loadUnit(string path, string skillName) { - if(path != "" && fileExists(path) == true) { - // std::cout << "Clearing list..." << std::endl; - this->unitPath.first = path; - this->unitPath.second.push_back(skillName); - } - - try{ - if(this->unitPath.first != "") { - if(timer) timer->Stop(); - if(renderer) renderer->end(); - - string titlestring = winHeader; - - string unitPath = this->unitPath.first; - string dir = unitPath; - string name= lastDir(dir); - string path= dir + "/" + name + ".xml"; - - titlestring = unitPath + " - "+ titlestring; - - std::string unitXML = path; - - string skillModelFile = ""; - string skillParticleFile = ""; - string skillParticleProjectileFile = ""; - string skillParticleSplashFile = ""; - bool fileFound = fileExists(unitXML); - - printf("Loading unit from file [%s] fileFound = %d\n",unitXML.c_str(),fileFound); - - if(fileFound == true) { - XmlTree xmlTree; - xmlTree.load(unitXML,Properties::getTagReplacementValues()); - const XmlNode *unitNode= xmlTree.getRootNode(); - - bool foundSkillName = false; - for(unsigned int skillIdx = 0; foundSkillName == false && skillIdx < this->unitPath.second.size(); ++skillIdx) { - string lookipForSkillName = this->unitPath.second[skillIdx]; - - const XmlNode *skillsNode= unitNode->getChild("skills"); - for(unsigned int i = 0; foundSkillName == false && i < skillsNode->getChildCount(); ++i) { - const XmlNode *sn= skillsNode->getChild("skill", i); - //const XmlNode *typeNode= sn->getChild("type"); - const XmlNode *nameNode= sn->getChild("name"); - string skillXmlName = nameNode->getAttribute("value")->getRestrictedValue(); - if(skillXmlName == lookipForSkillName) { - printf("Found skill [%s]\n",lookipForSkillName.c_str()); - foundSkillName = true; - - if(sn->getChild("animation") != NULL) { - skillModelFile = sn->getChild("animation")->getAttribute("path")->getRestrictedValue(unitPath + '/'); - printf("Found skill model [%s]\n",skillModelFile.c_str()); - } - - if(sn->hasChild("particles") == true) { - const XmlNode *particlesNode= sn->getChild("particles"); - //for(int j = 0; particlesNode != NULL && particlesNode->getAttribute("value")->getRestrictedValue() == "true" && - // j < particlesNode->getChildCount(); ++j) { - if(particlesNode != NULL && particlesNode->getAttribute("value")->getRestrictedValue() == "true" && - particlesNode->hasChild("particle-file") == true) { - const XmlNode *pf= particlesNode->getChild("particle-file"); - if(pf != NULL) { - skillParticleFile = unitPath + '/' + pf->getAttribute("path")->getRestrictedValue(); - printf("Found skill particle [%s]\n",skillParticleFile.c_str()); - } - } - } - if(sn->hasChild("projectile") == true) { - const XmlNode *particlesProjectileNode= sn->getChild("projectile"); - //for(int j = 0; particlesProjectileNode != NULL && particlesProjectileNode->getAttribute("value")->getRestrictedValue() == "true" && - // j < particlesProjectileNode->getChildCount(); ++j) { - if(particlesProjectileNode != NULL && particlesProjectileNode->getAttribute("value")->getRestrictedValue() == "true" && - particlesProjectileNode->hasChild("particle") == true) { - const XmlNode *pf= particlesProjectileNode->getChild("particle"); - if(pf != NULL && pf->getAttribute("value")->getRestrictedValue() == "true") { - skillParticleProjectileFile = unitPath + '/' + pf->getAttribute("path")->getRestrictedValue(); - printf("Found skill skill projectile particle [%s]\n",skillParticleProjectileFile.c_str()); - } - } - } - if(sn->hasChild("splash") == true) { - const XmlNode *particlesSplashNode= sn->getChild("splash"); - //for(int j = 0; particlesSplashNode != NULL && particlesSplashNode->getAttribute("value")->getRestrictedValue() == "true" && - // j < particlesSplashNode->getChildCount(); ++j) { - if(particlesSplashNode != NULL && particlesSplashNode->getAttribute("value")->getRestrictedValue() == "true" && - particlesSplashNode->hasChild("particle") == true) { - const XmlNode *pf= particlesSplashNode->getChild("particle"); - if(pf != NULL && pf->getAttribute("value")->getRestrictedValue() == "true") { - skillParticleSplashFile = unitPath + '/' + pf->getAttribute("path")->getRestrictedValue(); - printf("Found skill skill splash particle [%s]\n",skillParticleSplashFile.c_str()); - } - } - } - } - } - } - - if(skillModelFile != "") { - this->modelPathList.push_back(skillModelFile); - printf("Added skill model [%s]\n",skillModelFile.c_str()); - } - if(skillParticleFile != "") { - this->particlePathList.push_back(skillParticleFile); - printf("Added skill particle [%s]\n",skillParticleFile.c_str()); - } - if(skillParticleProjectileFile != "") { - this->particleProjectilePathList.push_back(skillParticleProjectileFile); - printf("Added skill projectile particle [%s]\n",skillParticleProjectileFile.c_str()); - } - if(skillParticleSplashFile != "") { - this->particleSplashPathList.push_back(skillParticleSplashFile); - printf("Added skill splash particle [%s]\n",skillParticleSplashFile.c_str()); - } - } - SetTitle(ToUnicode(titlestring)); - } - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Not a ZetaGlest particle XML file, or broken"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::loadModel(string path) { - try { - if(path != "" && fileExists(path) == true) { - this->modelPathList.push_back(path); - printf("Adding model [%s] list size " MG_SIZE_T_SPECIFIER "\n",path.c_str(),this->modelPathList.size()); - } - - string titlestring=winHeader; - for(unsigned int idx =0; idx < this->modelPathList.size(); idx++) { - string modelPath = this->modelPathList[idx]; - - //printf("Loading model [%s] %u of " MG_SIZE_T_SPECIFIER "\n",modelPath.c_str(),idx, this->modelPathList.size()); - - if(timer) timer->Stop(); - //delete model; - if(model != NULL && renderer != NULL) renderer->endModel(rsGlobal, model); - model = NULL; - model = renderer? renderer->newModel(rsGlobal, modelPath): NULL; - - statusbarText = getModelInfo(); - string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); - GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); - if(timer) timer->Start(100); - titlestring = extractFileFromDirectoryPath(modelPath) + " - "+ titlestring; - } - SetTitle(ToUnicode(titlestring)); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::loadParticle(string path) { - if(timer) timer->Stop(); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str()); - if(path != "" && fileExists(path) == true) { - renderer->end(); - unitParticleSystems.clear(); - unitParticleSystemTypes.clear(); - - if(isControlKeyPressed == true) { - // std::cout << "Adding to list..." << std::endl; - this->particlePathList.push_back(path); - } - else { - // std::cout << "Clearing list..." << std::endl; - this->particlePathList.clear(); - this->particlePathList.push_back(path); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] added file [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str()); - } - - try { - if(this->particlePathList.empty() == false) { - string titlestring=winHeader; - for(unsigned int idx = 0; idx < this->particlePathList.size(); idx++) { - string particlePath = this->particlePathList[idx]; - string dir= extractDirectoryPathFromFile(particlePath); - - size_t pos = dir.find_last_of(folderDelimiter); - if(pos == dir.length() - 1 && dir.length() > 0) { - dir.erase(dir.length() -1); - } - - particlePath= extractFileFromDirectoryPath(particlePath); - titlestring = particlePath + " - "+ titlestring; - - std::string unitXML = dir + folderDelimiter + extractFileFromDirectoryPath(dir) + ".xml"; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] looking for unit XML [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,unitXML.c_str()); - - //int size = -1; - //int height = -1; - int size = 0; - int height= 0; - - if(fileExists(unitXML) == true) { - { - XmlTree xmlTree; - xmlTree.load(unitXML,Properties::getTagReplacementValues()); - const XmlNode *unitNode= xmlTree.getRootNode(); - const XmlNode *parametersNode= unitNode->getChild("parameters"); - //size - size= parametersNode->getChild("size")->getAttribute("value")->getIntValue(); - //height - height= parametersNode->getChild("height")->getAttribute("value")->getIntValue(); } - // std::cout << "About to load [" << particlePath << "] from [" << dir << "] unit [" << unitXML << "]" << std::endl; - } - else { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] unit XML NOT FOUND [%s] using default position values\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,unitXML.c_str()); - - size = 1; - height= 1; - } - - std::map > > loadedFileList; - UnitParticleSystemType *unitParticleSystemType = new UnitParticleSystemType(); - unitParticleSystemType->load(NULL, dir, dir + folderDelimiter + particlePath, //### if we knew which particle it was, we could be more accurate - renderer,loadedFileList,"g3dviewer",""); - unitParticleSystemTypes.push_back(unitParticleSystemType); - - for(std::vector::const_iterator it= unitParticleSystemTypes.begin(); it != unitParticleSystemTypes.end(); ++it) { - UnitParticleSystem *ups= new UnitParticleSystem(200); - - ups->setParticleType((*it)); - (*it)->setValues(ups); - if(size > 0) { - //getCurrVectorFlat() + Vec3f(0.f, type->getHeight()/2.f, 0.f); - Vec3f vec = Vec3f(0.f, height / 2.f, 0.f); - ups->setPos(vec); - } - //ups->setFactionColor(getFaction()->getTexture()->getPixmap()->getPixel3f(0,0)); - ups->setFactionColor(renderer->getPlayerColorTexture(playerColor)->getPixmap()->getPixel3f(0,0)); - unitParticleSystems.push_back(ups); - renderer->manageParticleSystem(ups); - - ups->setVisible(true); - } - - if(path != "" && fileExists(path) == true) { - renderer->initModelManager(); - if(initTextureManager) { - renderer->initTextureManager(); - } - } - - } - SetTitle(ToUnicode(titlestring)); - } - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Not a Mega-Glest particle XML file, or broken"), wxOK | wxICON_ERROR).ShowModal(); - } - if(timer) timer->Start(100); -} - -void MainWindow::loadProjectileParticle(string path) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s] particleProjectilePathList.size() = " MG_SIZE_T_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),this->particleProjectilePathList.size()); - - if(timer) timer->Stop(); - if(path != "" && fileExists(path) == true) { - renderer->end(); - projectileParticleSystems.clear(); - projectileParticleSystemTypes.clear(); - - if(isControlKeyPressed == true) { - // std::cout << "Adding to list..." << std::endl; - this->particleProjectilePathList.push_back(path); - } - else { - // std::cout << "Clearing list..." << std::endl; - this->particleProjectilePathList.clear(); - this->particleProjectilePathList.push_back(path); - } - } - - try { - if(this->particleProjectilePathList.empty() == false) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("this->particleProjectilePathList.size() = " MG_SIZE_T_SPECIFIER "\n",this->particleProjectilePathList.size()); - - string titlestring=winHeader; - for(unsigned int idx = 0; idx < this->particleProjectilePathList.size(); idx++) { - string particlePath = this->particleProjectilePathList[idx]; - string dir= extractDirectoryPathFromFile(particlePath); - - size_t pos = dir.find_last_of(folderDelimiter); - if(pos == dir.length()-1) { - dir.erase(dir.length() -1); - } - - particlePath= extractFileFromDirectoryPath(particlePath); - titlestring = particlePath + " - "+ titlestring; - - std::string unitXML = dir + folderDelimiter + extractFileFromDirectoryPath(dir) + ".xml"; - - int size = 1; - int height = 1; - - if(fileExists(unitXML) == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] loading [%s] idx = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,unitXML.c_str(),idx); - - XmlTree xmlTree; - xmlTree.load(unitXML,Properties::getTagReplacementValues()); - const XmlNode *unitNode= xmlTree.getRootNode(); - const XmlNode *parametersNode= unitNode->getChild("parameters"); - //size - size= parametersNode->getChild("size")->getAttribute("value")->getIntValue(); - //height - height= parametersNode->getChild("height")->getAttribute("value")->getIntValue(); - } - - // std::cout << "About to load [" << particlePath << "] from [" << dir << "] unit [" << unitXML << "]" << std::endl; - - string particleFile = dir + folderDelimiter + particlePath; - { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] loading [%s] idx = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,particleFile.c_str(),idx); - XmlTree xmlTree; - xmlTree.load(particleFile,Properties::getTagReplacementValues()); - //const XmlNode *particleSystemNode= xmlTree.getRootNode(); - - // std::cout << "Loaded successfully, loading values..." << std::endl; - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] loading [%s] idx = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,particleFile.c_str(),idx); - std::map > > loadedFileList; - ParticleSystemTypeProjectile *projectileParticleSystemType= new ParticleSystemTypeProjectile(); - projectileParticleSystemType->load(NULL, dir, //### we don't know if there are overrides in the unit XML - particleFile,renderer, loadedFileList, - "g3dviewer",""); - - // std::cout << "Values loaded, about to read..." << std::endl; - - projectileParticleSystemTypes.push_back(projectileParticleSystemType); - - for(std::vector::const_iterator it= projectileParticleSystemTypes.begin(); - it != projectileParticleSystemTypes.end(); ++it) { - - ProjectileParticleSystem *ps = (*it)->create(NULL); - - if(size > 0) { - Vec3f vec = Vec3f(0.f, height / 2.f, 0.f); - //ps->setPos(vec); - - Vec3f vec2 = Vec3f(size * 2.f, height * 2.f, height * 2.f); - ps->setPath(vec, vec2); + // some posibility to adjust brightness: + /* + else if (e.GetKeyCode() == 322) { // Ins - Grid + gridBrightness += 0.1f; if (gridBrightness >1.0) gridBrightness =1.0; } - ps->setFactionColor(renderer->getPlayerColorTexture(playerColor)->getPixmap()->getPixel3f(0,0)); - - projectileParticleSystems.push_back(ps); - - ps->setVisible(true); - renderer->manageParticleSystem(ps); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] loaded [%s] idx = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,particleFile.c_str(),idx); - } - SetTitle(ToUnicode(titlestring)); - - if(path != "" && fileExists(path) == true) { - renderer->initModelManager(); - if(initTextureManager) { - renderer->initTextureManager(); - } - } - } - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Not a ZetaGlest projectile particle XML file, or broken"), wxOK | wxICON_ERROR).ShowModal(); - } - if(timer) timer->Start(100); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] after load [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str()); -} - -void MainWindow::loadSplashParticle(string path) { // uses ParticleSystemTypeSplash::load (and own list...) - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s] particleSplashPathList.size() = " MG_SIZE_T_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),this->particleSplashPathList.size()); - - if(timer) timer->Stop(); - if(path != "" && fileExists(path) == true) { - renderer->end(); - splashParticleSystems.clear(); - splashParticleSystemTypes.clear(); - - if(isControlKeyPressed == true) { - // std::cout << "Adding to list..." << std::endl; - this->particleSplashPathList.push_back(path); - } - else { - // std::cout << "Clearing list..." << std::endl; - this->particleSplashPathList.clear(); - this->particleSplashPathList.push_back(path); - } - } - - try { - if(this->particleSplashPathList.empty() == false) { - string titlestring=winHeader; - for(unsigned int idx = 0; idx < this->particleSplashPathList.size(); idx++) { - string particlePath = this->particleSplashPathList[idx]; - string dir= extractDirectoryPathFromFile(particlePath); - - size_t pos = dir.find_last_of(folderDelimiter); - if(pos == dir.length()-1) { - dir.erase(dir.length() -1); - } - - particlePath= extractFileFromDirectoryPath(particlePath); - titlestring = particlePath + " - "+ titlestring; - - std::string unitXML = dir + folderDelimiter + extractFileFromDirectoryPath(dir) + ".xml"; - - int size = 1; - //int height = 1; - - if(fileExists(unitXML) == true) { - XmlTree xmlTree; - xmlTree.load(unitXML,Properties::getTagReplacementValues()); - const XmlNode *unitNode= xmlTree.getRootNode(); - const XmlNode *parametersNode= unitNode->getChild("parameters"); - //size - size= parametersNode->getChild("size")->getAttribute("value")->getIntValue(); - //height - //height= parametersNode->getChild("height")->getAttribute("value")->getIntValue(); - } - - // std::cout << "About to load [" << particlePath << "] from [" << dir << "] unit [" << unitXML << "]" << std::endl; - - { - XmlTree xmlTree; - xmlTree.load(dir + folderDelimiter + particlePath,Properties::getTagReplacementValues()); - //const XmlNode *particleSystemNode= xmlTree.getRootNode(); - // std::cout << "Loaded successfully, loading values..." << std::endl; - } - - std::map > > loadedFileList; - ParticleSystemTypeSplash *splashParticleSystemType= new ParticleSystemTypeSplash(); - splashParticleSystemType->load(NULL, dir, dir + folderDelimiter + particlePath,renderer, //### we don't know if there are overrides in the unit XML - loadedFileList,"g3dviewer",""); // <---- only that must be splash... - - // std::cout << "Values loaded, about to read..." << std::endl; - - splashParticleSystemTypes.push_back(splashParticleSystemType); - - //ParticleSystemTypeSplash - for(std::vector::const_iterator it= splashParticleSystemTypes.begin(); it != splashParticleSystemTypes.end(); ++it) { - - SplashParticleSystem *ps = (*it)->create(NULL); - - if(size > 0) { - //Vec3f vec = Vec3f(0.f, height / 2.f, 0.f); - //ps->setPos(vec); - - //Vec3f vec2 = Vec3f(size * 2.f, height * 2.f, height * 2.f); // <------- removed relative projectile - //ps->setPath(vec, vec2); // <------- removed relative projectile + else if (e.GetKeyCode() == 127) { // Del + gridBrightness -= 0.1f; if (gridBrightness <0) gridBrightness =0; + } + */ + else if (e.GetKeyCode() == 313) { // Home - Background + backBrightness += 0.1f; if (backBrightness > 1.0) backBrightness = 1.0; + glClearColor(backBrightness, backBrightness, backBrightness, 1.0f); + } else if (e.GetKeyCode() == 312) { // End + backBrightness -= 0.1f; if (backBrightness < 0) backBrightness = 0; + glClearColor(backBrightness, backBrightness, backBrightness, 1.0f); + } else if (e.GetKeyCode() == 366) { // PgUp - Lightning of model + lightBrightness += 0.1f; if (lightBrightness > 1.0) lightBrightness = 1.0; + Vec4f ambientNEW = Vec4f(lightBrightness, lightBrightness, lightBrightness, 1.0f); + glLightfv(GL_LIGHT0, GL_AMBIENT, ambientNEW.ptr()); + } else if (e.GetKeyCode() == 367) { // pgDn + lightBrightness -= 0.1f; if (lightBrightness < 0) lightBrightness = 0; + Vec4f ambientNEW = Vec4f(lightBrightness, lightBrightness, lightBrightness, 1.0f); + glLightfv(GL_LIGHT0, GL_AMBIENT, ambientNEW.ptr()); } - ps->setFactionColor(renderer->getPlayerColorTexture(playerColor)->getPixmap()->getPixel3f(0,0)); - splashParticleSystems.push_back(ps); - - ps->setVisible(true); - renderer->manageParticleSystem(ps); + std::cout << "pressed " << e.GetKeyCode() << std::endl; + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); } } - SetTitle(ToUnicode(titlestring)); - if(path != "" && fileExists(path) == true) { - renderer->initModelManager(); - if(initTextureManager) { - renderer->initTextureManager(); - } - } - } - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Not a ZetaGlest projectile particle XML file, or broken"), wxOK | wxICON_ERROR).ShowModal(); - } - if(timer) timer->Start(100); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] after load [%s] particleSplashPathList.size() = " MG_SIZE_T_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),this->particleSplashPathList.size()); -} + void MainWindow::onMenuRestart(wxCommandEvent &event) { + try { + // std::cout << "pressed R (restart particle animation)" << std::endl; + if (timer) timer->Stop(); + if (renderer) renderer->end(); -void MainWindow::onMenuModeNormals(wxCommandEvent &event){ - try { - renderer->toggleNormals(); - menuMode->Check(miModeNormals, renderer->getNormals()); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} + unitParticleSystems.clear(); + unitParticleSystemTypes.clear(); + projectileParticleSystems.clear(); + projectileParticleSystemTypes.clear(); + splashParticleSystems.clear(); // as above + splashParticleSystemTypes.clear(); -void MainWindow::onMenuModeWireframe(wxCommandEvent &event){ - try { - renderer->toggleWireframe(); - menuMode->Check(miModeWireframe, renderer->getWireframe()); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} + loadUnit("", ""); + loadModel(""); + loadParticle(""); + loadProjectileParticle(""); + loadSplashParticle(""); // as above -void MainWindow::onMenuModeGrid(wxCommandEvent &event){ - try { - renderer->toggleGrid(); - menuMode->Check(miModeGrid, renderer->getGrid()); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuSpeedSlower(wxCommandEvent &event){ - try { - speed /= 1.5f; - if(speed < 0) { - speed = 0; - } - - string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); - GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuSpeedFaster(wxCommandEvent &event){ - try { - speed *= 1.5f; - if(speed > 1) { - speed = 1; - } - - string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0 ) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); - GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -// set menu checkboxes to what player color is used -void MainWindow::onMenuColorRed(wxCommandEvent &event) { - try { - playerColor= Renderer::pcRed; - menuCustomColor->Check(miColorRed, true); - menuCustomColor->Check(miColorBlue, false); - menuCustomColor->Check(miColorGreen, false); - menuCustomColor->Check(miColorYellow, false); - menuCustomColor->Check(miColorWhite, false); - menuCustomColor->Check(miColorCyan, false); - menuCustomColor->Check(miColorOrange, false); - menuCustomColor->Check(miColorMagenta, false); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuColorBlue(wxCommandEvent &event) { - try { - playerColor= Renderer::pcBlue; - menuCustomColor->Check(miColorRed, false); - menuCustomColor->Check(miColorBlue, true); - menuCustomColor->Check(miColorGreen, false); - menuCustomColor->Check(miColorYellow, false); - menuCustomColor->Check(miColorWhite, false); - menuCustomColor->Check(miColorCyan, false); - menuCustomColor->Check(miColorOrange, false); - menuCustomColor->Check(miColorMagenta, false); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuColorGreen(wxCommandEvent &event) { - try { - playerColor= Renderer::pcGreen; - menuCustomColor->Check(miColorRed, false); - menuCustomColor->Check(miColorBlue, false); - menuCustomColor->Check(miColorGreen, true); - menuCustomColor->Check(miColorYellow, false); - menuCustomColor->Check(miColorWhite, false); - menuCustomColor->Check(miColorCyan, false); - menuCustomColor->Check(miColorOrange, false); - menuCustomColor->Check(miColorMagenta, false); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuColorYellow(wxCommandEvent &event) { - try { - playerColor= Renderer::pcYellow; - menuCustomColor->Check(miColorRed, false); - menuCustomColor->Check(miColorBlue, false); - menuCustomColor->Check(miColorGreen, false); - menuCustomColor->Check(miColorYellow, true); - menuCustomColor->Check(miColorWhite, false); - menuCustomColor->Check(miColorCyan, false); - menuCustomColor->Check(miColorOrange, false); - menuCustomColor->Check(miColorMagenta, false); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuColorWhite(wxCommandEvent &event) { - try { - playerColor= Renderer::pcWhite; - menuCustomColor->Check(miColorRed, false); - menuCustomColor->Check(miColorBlue, false); - menuCustomColor->Check(miColorGreen, false); - menuCustomColor->Check(miColorYellow, false); - menuCustomColor->Check(miColorWhite, true); - menuCustomColor->Check(miColorCyan, false); - menuCustomColor->Check(miColorOrange, false); - menuCustomColor->Check(miColorMagenta, false); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuColorCyan(wxCommandEvent &event) { - try { - playerColor= Renderer::pcCyan; - menuCustomColor->Check(miColorRed, false); - menuCustomColor->Check(miColorBlue, false); - menuCustomColor->Check(miColorGreen, false); - menuCustomColor->Check(miColorYellow, false); - menuCustomColor->Check(miColorWhite, false); - menuCustomColor->Check(miColorCyan, true); - menuCustomColor->Check(miColorOrange, false); - menuCustomColor->Check(miColorMagenta, false); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuColorOrange(wxCommandEvent &event) { - try { - playerColor= Renderer::pcOrange; - menuCustomColor->Check(miColorRed, false); - menuCustomColor->Check(miColorBlue, false); - menuCustomColor->Check(miColorGreen, false); - menuCustomColor->Check(miColorYellow, false); - menuCustomColor->Check(miColorWhite, false); - menuCustomColor->Check(miColorCyan, false); - menuCustomColor->Check(miColorOrange, true); - menuCustomColor->Check(miColorMagenta, false); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuColorMagenta(wxCommandEvent &event) { - try { - playerColor= Renderer::pcMagenta; - menuCustomColor->Check(miColorRed, false); - menuCustomColor->Check(miColorBlue, false); - menuCustomColor->Check(miColorGreen, false); - menuCustomColor->Check(miColorYellow, false); - menuCustomColor->Check(miColorWhite, false); - menuCustomColor->Check(miColorCyan, false); - menuCustomColor->Check(miColorOrange, false); - menuCustomColor->Check(miColorMagenta, true); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} - - -void MainWindow::onTimer(wxTimerEvent &event) { - anim = anim + speed; - if(anim > 1.0f){ - anim -= 1.f; - resetAnimation = true; - } - wxPaintEvent paintEvent; - onPaint(paintEvent); -} - -string MainWindow::getModelInfo() { - string str; - - if(model != NULL) { - str+= "Meshes: "+intToStr(model->getMeshCount()); - str+= ", Vertices: "+intToStr(model->getVertexCount()); - str+= ", Triangles: "+intToStr(model->getTriangleCount()); - str+= ", Version: "+intToStr(model->getFileVersion()); - } - - return str; -} - -void MainWindow::onKeyDown(wxKeyEvent &e) { - - try { - // std::cout << "e.ControlDown() = " << e.ControlDown() << " e.GetKeyCode() = " << e.GetKeyCode() << " isCtrl = " << (e.GetKeyCode() == WXK_CONTROL) << std::endl; - - // Note: This ctrl-key handling is buggy since it never resets when ctrl is released later, so I reset it at end of loadcommands for now. - if(e.ControlDown() == true || e.GetKeyCode() == WXK_CONTROL) { - isControlKeyPressed = true; - } - else { - isControlKeyPressed = false; - } - - // std::cout << "isControlKeyPressed = " << isControlKeyPressed << std::endl; - - - // here also because + and - hotkeys don't work for numpad automaticly - if (e.GetKeyCode() == 388) { - speed *= 1.5f; //numpad+ - if(speed > 1.0) { - speed = 1.0; + renderer->initModelManager(); + if (initTextureManager) { + renderer->initTextureManager(); + } + if (timer) timer->Start(100); + } catch (std::runtime_error &e) { + std::cout << e.what() << std::endl; + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); } - - string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); - GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); - - } - else if (e.GetKeyCode() == 390) { - speed /= 1.5f; //numpad- - if(speed < 0) { - speed = 0; - } - string statusTextValue = statusbarText + " animation speed: " + floatToStr(speed * 1000.0) + " anim value: " + floatToStr(anim) + " zoom: " + floatToStr(zoom) + " rotX: " + floatToStr(rotX) + " rotY: " + floatToStr(rotY); - GetStatusBar()->SetStatusText(ToUnicode(statusTextValue.c_str())); - } - else if (e.GetKeyCode() == 'W') { - glClearColor(0.6f, 0.6f, 0.6f, 1.0f); //w key //backgroundcolor constant 0.3 -> 0.6 - } - // some posibility to adjust brightness: - /* - else if (e.GetKeyCode() == 322) { // Ins - Grid - gridBrightness += 0.1f; if (gridBrightness >1.0) gridBrightness =1.0; - } - else if (e.GetKeyCode() == 127) { // Del - gridBrightness -= 0.1f; if (gridBrightness <0) gridBrightness =0; - } - */ - else if (e.GetKeyCode() == 313) { // Home - Background - backBrightness += 0.1f; if (backBrightness >1.0) backBrightness=1.0; - glClearColor(backBrightness, backBrightness, backBrightness, 1.0f); - } - else if (e.GetKeyCode() == 312) { // End - backBrightness -= 0.1f; if (backBrightness<0) backBrightness=0; - glClearColor(backBrightness, backBrightness, backBrightness, 1.0f); - } - else if (e.GetKeyCode() == 366) { // PgUp - Lightning of model - lightBrightness += 0.1f; if (lightBrightness >1.0) lightBrightness =1.0; - Vec4f ambientNEW= Vec4f(lightBrightness, lightBrightness, lightBrightness, 1.0f); - glLightfv(GL_LIGHT0,GL_AMBIENT, ambientNEW.ptr()); - } - else if (e.GetKeyCode() == 367) { // pgDn - lightBrightness -= 0.1f; if (lightBrightness <0) lightBrightness =0; - Vec4f ambientNEW= Vec4f(lightBrightness, lightBrightness, lightBrightness, 1.0f); - glLightfv(GL_LIGHT0,GL_AMBIENT, ambientNEW.ptr()); - } + BEGIN_EVENT_TABLE(MainWindow, wxFrame) + EVT_TIMER(-1, MainWindow::onTimer) + EVT_CLOSE(MainWindow::onClose) + EVT_MENU(miFileLoad, MainWindow::onMenuFileLoad) + EVT_MENU(miFileLoadParticleXML, MainWindow::onMenuFileLoadParticleXML) + EVT_MENU(miFileLoadProjectileParticleXML, MainWindow::onMenuFileLoadProjectileParticleXML) + EVT_MENU(miFileLoadSplashParticleXML, MainWindow::onMenuFileLoadSplashParticleXML) + EVT_MENU(miFileClearAll, MainWindow::onMenuFileClearAll) + EVT_MENU(miFileToggleScreenshotTransparent, MainWindow::onMenumFileToggleScreenshotTransparent) + EVT_MENU(miFileSaveScreenshot, MainWindow::onMenuFileSaveScreenshot) + EVT_MENU(wxID_EXIT, MainWindow::onMenuFileExit) - std::cout << "pressed " << e.GetKeyCode() << std::endl; - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} + EVT_MENU(miModeWireframe, MainWindow::onMenuModeWireframe) + EVT_MENU(miModeNormals, MainWindow::onMenuModeNormals) + EVT_MENU(miModeGrid, MainWindow::onMenuModeGrid) -void MainWindow::onMenuRestart(wxCommandEvent &event) { - try { - // std::cout << "pressed R (restart particle animation)" << std::endl; - if(timer) timer->Stop(); - if(renderer) renderer->end(); + EVT_MENU(miSpeedFaster, MainWindow::onMenuSpeedFaster) + EVT_MENU(miSpeedSlower, MainWindow::onMenuSpeedSlower) + EVT_MENU(miRestart, MainWindow::onMenuRestart) - unitParticleSystems.clear(); - unitParticleSystemTypes.clear(); - projectileParticleSystems.clear(); - projectileParticleSystemTypes.clear(); - splashParticleSystems.clear(); // as above - splashParticleSystemTypes.clear(); + EVT_MENU(miColorRed, MainWindow::onMenuColorRed) + EVT_MENU(miColorBlue, MainWindow::onMenuColorBlue) + EVT_MENU(miColorGreen, MainWindow::onMenuColorGreen) + EVT_MENU(miColorYellow, MainWindow::onMenuColorYellow) + EVT_MENU(miColorWhite, MainWindow::onMenuColorWhite) + EVT_MENU(miColorCyan, MainWindow::onMenuColorCyan) + EVT_MENU(miColorOrange, MainWindow::onMenuColorOrange) + EVT_MENU(miColorMagenta, MainWindow::onMenuColorMagenta) - loadUnit("", ""); - loadModel(""); - loadParticle(""); - loadProjectileParticle(""); - loadSplashParticle(""); // as above + EVT_MENU(miChangeBackgroundColor, MainWindow::OnChangeColor) + END_EVENT_TABLE() - renderer->initModelManager(); - if(initTextureManager) { - renderer->initTextureManager(); - } - if(timer) timer->Start(100); - } - catch(std::runtime_error &e) { - std::cout << e.what() << std::endl; - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Error"), wxOK | wxICON_ERROR).ShowModal(); - } -} + // ===================================================== + // class GlCanvas + // ===================================================== -BEGIN_EVENT_TABLE(MainWindow, wxFrame) - EVT_TIMER(-1, MainWindow::onTimer) - EVT_CLOSE(MainWindow::onClose) - EVT_MENU(miFileLoad, MainWindow::onMenuFileLoad) - EVT_MENU(miFileLoadParticleXML, MainWindow::onMenuFileLoadParticleXML) - EVT_MENU(miFileLoadProjectileParticleXML, MainWindow::onMenuFileLoadProjectileParticleXML) - EVT_MENU(miFileLoadSplashParticleXML, MainWindow::onMenuFileLoadSplashParticleXML) - EVT_MENU(miFileClearAll, MainWindow::onMenuFileClearAll) - EVT_MENU(miFileToggleScreenshotTransparent, MainWindow::onMenumFileToggleScreenshotTransparent) - EVT_MENU(miFileSaveScreenshot, MainWindow::onMenuFileSaveScreenshot) - EVT_MENU(wxID_EXIT, MainWindow::onMenuFileExit) - - EVT_MENU(miModeWireframe, MainWindow::onMenuModeWireframe) - EVT_MENU(miModeNormals, MainWindow::onMenuModeNormals) - EVT_MENU(miModeGrid, MainWindow::onMenuModeGrid) - - EVT_MENU(miSpeedFaster, MainWindow::onMenuSpeedFaster) - EVT_MENU(miSpeedSlower, MainWindow::onMenuSpeedSlower) - EVT_MENU(miRestart, MainWindow::onMenuRestart) - - EVT_MENU(miColorRed, MainWindow::onMenuColorRed) - EVT_MENU(miColorBlue, MainWindow::onMenuColorBlue) - EVT_MENU(miColorGreen, MainWindow::onMenuColorGreen) - EVT_MENU(miColorYellow, MainWindow::onMenuColorYellow) - EVT_MENU(miColorWhite, MainWindow::onMenuColorWhite) - EVT_MENU(miColorCyan, MainWindow::onMenuColorCyan) - EVT_MENU(miColorOrange, MainWindow::onMenuColorOrange) - EVT_MENU(miColorMagenta, MainWindow::onMenuColorMagenta) - - EVT_MENU(miChangeBackgroundColor, MainWindow::OnChangeColor) -END_EVENT_TABLE() - -// ===================================================== -// class GlCanvas -// ===================================================== - -void translateCoords(wxWindow *wnd, int &x, int &y) { + void translateCoords(wxWindow *wnd, int &x, int &y) { #ifdef WIN32 - int cx, cy; - wnd->GetPosition(&cx, &cy); - x += cx; - y += cy; + int cx, cy; + wnd->GetPosition(&cx, &cy); + x += cx; + y += cy; #endif -} + } -// to prevent flicker -GlCanvas::GlCanvas(MainWindow * mainWindow, int *args) + // to prevent flicker + GlCanvas::GlCanvas(MainWindow * mainWindow, int *args) #if wxCHECK_VERSION(2, 9, 1) - : wxGLCanvas(mainWindow, wxID_ANY, args, wxDefaultPosition, mainWindow->GetClientSize(), wxFULL_REPAINT_ON_RESIZE, wxT("GLCanvas")) { - this->context = new wxGLContext(this); + : wxGLCanvas(mainWindow, wxID_ANY, args, wxDefaultPosition, mainWindow->GetClientSize(), wxFULL_REPAINT_ON_RESIZE, wxT("GLCanvas")) { + this->context = new wxGLContext(this); #else - : wxGLCanvas(mainWindow, -1, wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas"), args) { - this->context = NULL; + : wxGLCanvas(mainWindow, -1, wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas"), args) { + this->context = NULL; #endif - this->mainWindow = mainWindow; -} + this->mainWindow = mainWindow; + } -GlCanvas::~GlCanvas() { - if(this->context) { - delete this->context; - } - this->context = NULL; -} + GlCanvas::~GlCanvas() { + if (this->context) { + delete this->context; + } + this->context = NULL; + } -void GlCanvas::setCurrentGLContext() { + void GlCanvas::setCurrentGLContext() { #ifndef __APPLE__ #if wxCHECK_VERSION(3, 0, 0) - //printf("Setting glcontext 3x!\n"); + //printf("Setting glcontext 3x!\n"); - //if(!IsShown()) {} - if(this->context == NULL) { - //printf("Make new ctx!\n"); - this->context = new wxGLContext(this); - //printf("Set ctx [%p]\n",this->context); - } + //if(!IsShown()) {} + if (this->context == NULL) { + //printf("Make new ctx!\n"); + this->context = new wxGLContext(this); + //printf("Set ctx [%p]\n",this->context); + } #elif wxCHECK_VERSION(2, 9, 1) - //printf("Setting glcontext 29x!\n"); + //printf("Setting glcontext 29x!\n"); - //if(!IsShown()) {} - if(this->context == NULL) { - this->context = new wxGLContext(this); - //printf("Set ctx [%p]\n",this->context); - } + //if(!IsShown()) {} + if (this->context == NULL) { + this->context = new wxGLContext(this); + //printf("Set ctx [%p]\n",this->context); + } #endif - //printf("Set ctx [%p]\n",this->context); - if(this->context) { - wxGLCanvas::SetCurrent(*this->context); - //printf("Set ctx2 [%p]\n",this->context); - } + //printf("Set ctx [%p]\n",this->context); + if (this->context) { + wxGLCanvas::SetCurrent(*this->context); + //printf("Set ctx2 [%p]\n",this->context); + } #else - this->SetCurrent(); + this->SetCurrent(); #endif -} + } -// for the mousewheel -void GlCanvas::onMouseWheel(wxMouseEvent &event) { - if(event.GetWheelRotation()>0) mainWindow->onMouseWheelDown(event); - else mainWindow->onMouseWheelUp(event); -} + // for the mousewheel + void GlCanvas::onMouseWheel(wxMouseEvent &event) { + if (event.GetWheelRotation() > 0) mainWindow->onMouseWheelDown(event); + else mainWindow->onMouseWheelUp(event); + } -void GlCanvas::onMouseMove(wxMouseEvent &event){ - mainWindow->onMouseMove(event); -} + void GlCanvas::onMouseMove(wxMouseEvent &event) { + mainWindow->onMouseMove(event); + } -void GlCanvas::onKeyDown(wxKeyEvent &event) { - int x, y; - event.GetPosition(&x, &y); - translateCoords(this, x, y); - mainWindow->onKeyDown(event); -} + void GlCanvas::onKeyDown(wxKeyEvent &event) { + int x, y; + event.GetPosition(&x, &y); + translateCoords(this, x, y); + mainWindow->onKeyDown(event); + } -void GlCanvas::OnSize(wxSizeEvent&event) { + void GlCanvas::OnSize(wxSizeEvent&event) { - //printf("OnSize %dx%d\n",event.m_size.GetWidth(),event.m_size.GetHeight()); - Update(); -} + //printf("OnSize %dx%d\n",event.m_size.GetWidth(),event.m_size.GetHeight()); + Update(); + } -// EVT_SPIN_DOWN(GlCanvas::onMouseDown) -// EVT_SPIN_UP(GlCanvas::onMouseDown) -// EVT_MIDDLE_DOWN(GlCanvas::onMouseWheel) -// EVT_MIDDLE_UP(GlCanvas::onMouseWheel) + // EVT_SPIN_DOWN(GlCanvas::onMouseDown) + // EVT_SPIN_UP(GlCanvas::onMouseDown) + // EVT_MIDDLE_DOWN(GlCanvas::onMouseWheel) + // EVT_MIDDLE_UP(GlCanvas::onMouseWheel) -BEGIN_EVENT_TABLE(GlCanvas, wxGLCanvas) - EVT_MOUSEWHEEL(GlCanvas::onMouseWheel) - EVT_MOTION(GlCanvas::onMouseMove) - EVT_KEY_DOWN(GlCanvas::onKeyDown) - EVT_SIZE(GlCanvas::OnSize) -END_EVENT_TABLE() + BEGIN_EVENT_TABLE(GlCanvas, wxGLCanvas) + EVT_MOUSEWHEEL(GlCanvas::onMouseWheel) + EVT_MOTION(GlCanvas::onMouseMove) + EVT_KEY_DOWN(GlCanvas::onKeyDown) + EVT_SIZE(GlCanvas::OnSize) + END_EVENT_TABLE() -// =============================================== -// class App -// =============================================== + // =============================================== + // class App + // =============================================== -bool App::OnInit() { - SystemFlags::VERBOSE_MODE_ENABLED = false; + bool App::OnInit() { + SystemFlags::VERBOSE_MODE_ENABLED = false; #if defined(wxMAJOR_VERSION) && defined(wxMINOR_VERSION) && defined(wxRELEASE_NUMBER) && defined(wxSUBRELEASE_NUMBER) - printf("Using wxWidgets version [%d.%d.%d.%d]\n",wxMAJOR_VERSION,wxMINOR_VERSION,wxRELEASE_NUMBER,wxSUBRELEASE_NUMBER); + printf("Using wxWidgets version [%d.%d.%d.%d]\n", wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER, wxSUBRELEASE_NUMBER); #endif - string modelPath=""; - string particlePath=""; - string projectileParticlePath=""; - string splashParticlePath=""; + string modelPath = ""; + string particlePath = ""; + string projectileParticlePath = ""; + string splashParticlePath = ""; - bool foundInvalidArgs = false; - const int knownArgCount = sizeof(GAME_ARGS) / sizeof(GAME_ARGS[0]); - for(int idx = 1; idx < argc; ++idx) { + bool foundInvalidArgs = false; + const int knownArgCount = sizeof(GAME_ARGS) / sizeof(GAME_ARGS[0]); + for (int idx = 1; idx < argc; ++idx) { #if wxCHECK_VERSION(2, 9, 1) - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(argv[idx].wc_str()); + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(argv[idx].wc_str()); #else - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(argv[idx]); + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(argv[idx]); #endif -if( hasCommandArgument(knownArgCount, (wxChar**)&GAME_ARGS[0], (const char *)tmp_buf, NULL, 0, true) == false && - argv[idx][0] == '-') { - foundInvalidArgs = true; + if (hasCommandArgument(knownArgCount, (wxChar**) &GAME_ARGS[0], (const char *) tmp_buf, NULL, 0, true) == false && + argv[idx][0] == '-') { + foundInvalidArgs = true; - printf("\nInvalid argument: %s",(const char*)tmp_buf); - } - } - - if(foundInvalidArgs == true || - hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_HELP])) == true) { - printParameterHelp(static_cast(WX2CHR(argv[0])), foundInvalidArgs); - return false; - } - - if(hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_VERBOSE])) == true) { - SystemFlags::VERBOSE_MODE_ENABLED = true; - } - - if(hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_AUTO_SCREENSHOT])) == true) { - autoScreenShotAndExit = true; - - const wxWX2MBbuf param = (const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_AUTO_SCREENSHOT]); - //printf("param = [%s]\n",(const char*)param); - - int foundParamIndIndex = -1; - hasCommandArgument(argc, argv,string((const char*)param) + string("="),&foundParamIndIndex); - if(foundParamIndIndex < 0) { - hasCommandArgument(argc, argv,(const char*)param,&foundParamIndIndex); - } - //printf("foundParamIndIndex = %d\n",foundParamIndIndex); -#if wxCHECK_VERSION(2, 9, 1) - string options = argv[foundParamIndIndex].ToStdString(); -#else - string options = (const char *)wxConvCurrent->cWX2MB(argv[foundParamIndIndex]); -#endif - vector paramPartTokens; - Tokenize(options,paramPartTokens,"="); - if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { - string optionsValue = paramPartTokens[1]; - - autoScreenShotParams.clear(); - Tokenize(optionsValue,autoScreenShotParams,","); - - for(unsigned int i = 0; i < autoScreenShotParams.size(); ++i) { - -#ifdef WIN32 - auto_ptr wstr(Ansi2WideString(autoScreenShotParams[i].c_str())); - autoScreenShotParams[i] = utf8_encode(wstr.get()); -#endif - - if(_strnicmp(autoScreenShotParams[i].c_str(),"resize-",7) == 0) { - printf("Screenshot option [%s]\n",autoScreenShotParams[i].c_str()); - - string resize = autoScreenShotParams[i]; - resize = resize.erase(0,7); - vector values; - Tokenize(resize,values,"x"); - overrideSize.first = strToInt(values[0]); - overrideSize.second = strToInt(values[1]); - - Renderer::windowX= 0; - Renderer::windowY= 0; - Renderer::windowW = overrideSize.first; - Renderer::windowH = overrideSize.second + 25; + printf("\nInvalid argument: %s", (const char*) tmp_buf); } } - } - } - std::pair > unitToLoad; - if(hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_UNIT])) == true) { - const wxWX2MBbuf param = (const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_UNIT]); - //printf("param = [%s]\n",(const char*)param); + if (foundInvalidArgs == true || + hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_HELP])) == true) { + printParameterHelp(static_cast(WX2CHR(argv[0])), foundInvalidArgs); + return false; + } - int foundParamIndIndex = -1; - hasCommandArgument(argc, argv,string((const char*)param) + string("="),&foundParamIndIndex); - if(foundParamIndIndex < 0) { - hasCommandArgument(argc, argv,(const char*)param,&foundParamIndIndex); - } - //printf("foundParamIndIndex = %d\n",foundParamIndIndex); - string customPath = static_cast(WX2CHR(argv[foundParamIndIndex])); - vector paramPartTokens; - Tokenize(customPath,paramPartTokens,"="); - if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { - string customPathValue = paramPartTokens[1]; - std::vector delimitedList; - Tokenize(customPathValue,delimitedList,","); + if (hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_VERBOSE])) == true) { + SystemFlags::VERBOSE_MODE_ENABLED = true; + } - if(delimitedList.size() >= 2) { - unitToLoad.first = delimitedList[0]; - #ifdef WIN32 - auto_ptr wstr(Ansi2WideString(unitToLoad.first.c_str())); - unitToLoad.first = utf8_encode(wstr.get()); - #endif + if (hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_AUTO_SCREENSHOT])) == true) { + autoScreenShotAndExit = true; - for(unsigned int i = 1; i < delimitedList.size(); ++i) { - string value = delimitedList[i]; - #ifdef WIN32 - auto_ptr wstr(Ansi2WideString(value.c_str())); - value = utf8_encode(wstr.get()); - #endif + const wxWX2MBbuf param = (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_AUTO_SCREENSHOT]); + //printf("param = [%s]\n",(const char*)param); - unitToLoad.second.push_back(value); - } - } - else { - printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", static_cast(WX2CHR(argv[foundParamIndIndex])), (paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); - printParameterHelp(WX2CHR(argv[0]),false); - return false; - } - - } - else { - printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", static_cast(WX2CHR(argv[foundParamIndIndex])),(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); - printParameterHelp(WX2CHR(argv[0]),false); - return false; - } - } - - if(hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL])) == true && - hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL_ANIMATION_VALUE])) == false) { - const wxWX2MBbuf param = (const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL]); - //printf("param = [%s]\n",(const char*)param); - - int foundParamIndIndex = -1; - hasCommandArgument(argc, argv,string((const char*)param) + string("="),&foundParamIndIndex); - if(foundParamIndIndex < 0) { - hasCommandArgument(argc, argv,(const char*)param,&foundParamIndIndex); - } - //printf("foundParamIndIndex = %d\n",foundParamIndIndex); - string customPath = (const char*)WX2CHR(argv[foundParamIndIndex]); - vector paramPartTokens; - Tokenize(customPath,paramPartTokens,"="); - if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { - string customPathValue = paramPartTokens[1]; - modelPath = customPathValue; - #ifdef WIN32 - auto_ptr wstr(Ansi2WideString(modelPath.c_str())); - modelPath = utf8_encode(wstr.get()); - #endif - - } - else { - printf("\nInvalid path specified on commandline [%s] value [%s]\n\n",(const char*)WX2CHR(argv[foundParamIndIndex]),(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); - printParameterHelp(WX2CHR(argv[0]),false); - return false; - } - } - - if(hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE])) == true && - hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_LOOP_VALUE])) == false) { - const wxWX2MBbuf param = (const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE]); - //printf("param = [%s]\n",(const char*)param); - - int foundParamIndIndex = -1; - hasCommandArgument(argc, argv,string((const char*)param) + string("="),&foundParamIndIndex); - if(foundParamIndIndex < 0) { - hasCommandArgument(argc, argv,(const char*)param,&foundParamIndIndex); - } - //printf("foundParamIndIndex = %d\n",foundParamIndIndex); - string customPath = (const char*)WX2CHR(argv[foundParamIndIndex]); - vector paramPartTokens; - Tokenize(customPath,paramPartTokens,"="); - if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { - string customPathValue = paramPartTokens[1]; - particlePath = customPathValue; - #ifdef WIN32 - auto_ptr wstr(Ansi2WideString(particlePath.c_str())); - particlePath = utf8_encode(wstr.get()); - #endif - } - else { - printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", (const char*)WX2CHR(argv[foundParamIndIndex]),(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); - printParameterHelp(WX2CHR(argv[0]),false); - return false; - } - } - - if(hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_PROJECTILE])) == true) { - const wxWX2MBbuf param = (const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_PROJECTILE]); - //printf("param = [%s]\n",(const char*)param); - - int foundParamIndIndex = -1; - hasCommandArgument(argc, argv,string((const char*)param) + string("="),&foundParamIndIndex); - if(foundParamIndIndex < 0) { - hasCommandArgument(argc, argv,(const char*)param,&foundParamIndIndex); - } - //printf("foundParamIndIndex = %d\n",foundParamIndIndex); - string customPath = (const char*)WX2CHR(argv[foundParamIndIndex]); - vector paramPartTokens; - Tokenize(customPath,paramPartTokens,"="); - if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { - string customPathValue = paramPartTokens[1]; - projectileParticlePath = customPathValue; - #ifdef WIN32 - auto_ptr wstr(Ansi2WideString(projectileParticlePath.c_str())); - projectileParticlePath = utf8_encode(wstr.get()); - #endif - } - else { - printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", (const char*)WX2CHR(argv[foundParamIndIndex]),(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); - printParameterHelp(WX2CHR(argv[0]),false); - return false; - } - } - - if(hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_SPLASH])) == true) { - const wxWX2MBbuf param = (const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_SPLASH]); - //printf("param = [%s]\n",(const char*)param); - - int foundParamIndIndex = -1; - hasCommandArgument(argc, argv,string((const char*)param) + string("="),&foundParamIndIndex); - if(foundParamIndIndex < 0) { - hasCommandArgument(argc, argv,(const char*)param,&foundParamIndIndex); - } - //printf("foundParamIndIndex = %d\n",foundParamIndIndex); - string customPath = (const char*)WX2CHR(argv[foundParamIndIndex]); - vector paramPartTokens; - Tokenize(customPath,paramPartTokens,"="); - if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { - string customPathValue = paramPartTokens[1]; - splashParticlePath = customPathValue; - #ifdef WIN32 - auto_ptr wstr(Ansi2WideString(splashParticlePath.c_str())); - splashParticlePath = utf8_encode(wstr.get()); - #endif - } - else { - printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", (const char*)WX2CHR(argv[foundParamIndIndex]),(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); - printParameterHelp(WX2CHR(argv[0]),false); - return false; - } - } - - float newAnimValue = 0.0f; - if(hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL_ANIMATION_VALUE])) == true) { - const wxWX2MBbuf param = (const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL_ANIMATION_VALUE]); - - int foundParamIndIndex = -1; - hasCommandArgument(argc, argv,string((const char*)param) + string("="),&foundParamIndIndex); - if(foundParamIndIndex < 0) { - hasCommandArgument(argc, argv,(const char*)param,&foundParamIndIndex); - } - //printf("foundParamIndIndex = %d\n",foundParamIndIndex); - string value = (const char*)WX2CHR(argv[foundParamIndIndex]); - vector paramPartTokens; - Tokenize(value,paramPartTokens,"="); - if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { - newAnimValue = strToFloat(paramPartTokens[1]); - printf("newAnimValue = %f\n",newAnimValue); - } - else { - printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", (const char*)WX2CHR(argv[foundParamIndIndex]),(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); - printParameterHelp(WX2CHR(argv[0]),false); - return false; - } - } - - int newParticleLoopValue = 1; - if(hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_LOOP_VALUE])) == true) { - const wxWX2MBbuf param = (const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_LOOP_VALUE]); - - int foundParamIndIndex = -1; - hasCommandArgument(argc, argv,string((const char*)param) + string("="),&foundParamIndIndex); - if(foundParamIndIndex < 0) { - hasCommandArgument(argc, argv,(const char*)param,&foundParamIndIndex); - } - //printf("foundParamIndIndex = %d\n",foundParamIndIndex); - string value = (const char*)WX2CHR(argv[foundParamIndIndex]); - vector paramPartTokens; - Tokenize(value,paramPartTokens,"="); - if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { - newParticleLoopValue = strToInt(paramPartTokens[1]); - //printf("newParticleLoopValue = %d\n",newParticleLoopValue); - } - else { - printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", (const char*)WX2CHR(argv[foundParamIndIndex]),(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); - printParameterHelp(WX2CHR(argv[0]),false); - return false; - } - } - - float newZoomValue = 1.0f; - if(hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ZOOM_VALUE])) == true) { - const wxWX2MBbuf param = (const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ZOOM_VALUE]); - - int foundParamIndIndex = -1; - hasCommandArgument(argc, argv,string((const char*)param) + string("="),&foundParamIndIndex); - if(foundParamIndIndex < 0) { - hasCommandArgument(argc, argv,(const char*)param,&foundParamIndIndex); - } - //printf("foundParamIndIndex = %d\n",foundParamIndIndex); - string value = (const char*)WX2CHR(argv[foundParamIndIndex]); - vector paramPartTokens; - Tokenize(value,paramPartTokens,"="); - if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { - newZoomValue = strToFloat(paramPartTokens[1]); - //printf("newAnimValue = %f\n",newAnimValue); - } - else { - printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", (const char*)WX2CHR(argv[foundParamIndIndex]),(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); - printParameterHelp(WX2CHR(argv[0]),false); - return false; - } - } - - float newXRotValue = 0.0f; - if(hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_X_VALUE])) == true) { - const wxWX2MBbuf param = (const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_X_VALUE]); - - int foundParamIndIndex = -1; - hasCommandArgument(argc, argv,string((const char*)param) + string("="),&foundParamIndIndex); - if(foundParamIndIndex < 0) { - hasCommandArgument(argc, argv,(const char*)param,&foundParamIndIndex); - } - //printf("foundParamIndIndex = %d\n",foundParamIndIndex); - string value = (const char*)WX2CHR(argv[foundParamIndIndex]); - vector paramPartTokens; - Tokenize(value,paramPartTokens,"="); - if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { - newXRotValue = strToFloat(paramPartTokens[1]); - //printf("newAnimValue = %f\n",newAnimValue); - } - else { - printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", (const char*)WX2CHR(argv[foundParamIndIndex]),(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); - printParameterHelp(WX2CHR(argv[0]),false); - return false; - } - } - - float newYRotValue = 0.0f; - if(hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_Y_VALUE])) == true) { - const wxWX2MBbuf param = (const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_Y_VALUE]); - - int foundParamIndIndex = -1; - hasCommandArgument(argc, argv,string((const char*)param) + string("="),&foundParamIndIndex); - if(foundParamIndIndex < 0) { - hasCommandArgument(argc, argv,(const char*)param,&foundParamIndIndex); - } - //printf("foundParamIndIndex = %d\n",foundParamIndIndex); - string value = static_cast(WX2CHR(argv[foundParamIndIndex])); - vector paramPartTokens; - Tokenize(value,paramPartTokens,"="); - if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { - newYRotValue = strToFloat(paramPartTokens[1]); - //printf("newAnimValue = %f\n",newAnimValue); - } - else { - printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", static_cast(WX2CHR(argv[foundParamIndIndex])),(paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); - printParameterHelp(WX2CHR(argv[0]),false); - return false; - } - } - - if(hasCommandArgument(argc, argv,(const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_SCREENSHOT_FORMAT])) == true) { - const wxWX2MBbuf param = (const char *)wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_SCREENSHOT_FORMAT]); - - int foundParamIndIndex = -1; - hasCommandArgument(argc, argv,string((const char*)param) + string("="),&foundParamIndIndex); - if(foundParamIndIndex < 0) { - hasCommandArgument(argc, argv,(const char*)param,&foundParamIndIndex); - } - //printf("foundParamIndIndex = %d\n",foundParamIndIndex); - string value = static_cast(WX2CHR(argv[foundParamIndIndex])); - vector paramPartTokens; - Tokenize(value,paramPartTokens,"="); - if(paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { - fileFormat = paramPartTokens[1]; - } - else { - printf("\nInvalid value specified on commandline [%s] value [%s]\n\n", static_cast(WX2CHR(argv[foundParamIndIndex])), (paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); - printParameterHelp(WX2CHR(argv[0]),false); - return false; - } - } - - if(argc == 2 && argv[1][0] != '-') { - -//#if defined(__MINGW32__) -#ifdef WIN32 - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(argv[1])); - modelPath = tmp_buf; - auto_ptr wstr(Ansi2WideString(modelPath.c_str())); - modelPath = utf8_encode(wstr.get()); + int foundParamIndIndex = -1; + hasCommandArgument(argc, argv, string((const char*) param) + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, (const char*) param, &foundParamIndIndex); + } + //printf("foundParamIndIndex = %d\n",foundParamIndIndex); +#if wxCHECK_VERSION(2, 9, 1) + string options = argv[foundParamIndIndex].ToStdString(); #else - modelPath = static_cast(WX2CHR(argv[1])); + string options = (const char *) wxConvCurrent->cWX2MB(argv[foundParamIndIndex]); +#endif + vector paramPartTokens; + Tokenize(options, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string optionsValue = paramPartTokens[1]; + + autoScreenShotParams.clear(); + Tokenize(optionsValue, autoScreenShotParams, ","); + + for (unsigned int i = 0; i < autoScreenShotParams.size(); ++i) { + +#ifdef WIN32 + auto_ptr wstr(Ansi2WideString(autoScreenShotParams[i].c_str())); + autoScreenShotParams[i] = utf8_encode(wstr.get()); #endif -//#else -// modelPath = wxFNCONV(argv[1]); -//#endif + if (_strnicmp(autoScreenShotParams[i].c_str(), "resize-", 7) == 0) { + printf("Screenshot option [%s]\n", autoScreenShotParams[i].c_str()); - } + string resize = autoScreenShotParams[i]; + resize = resize.erase(0, 7); + vector values; + Tokenize(resize, values, "x"); + overrideSize.first = strToInt(values[0]); + overrideSize.second = strToInt(values[1]); -//#if defined(__MINGW32__) -// const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(argv[0])); -// appPath = tmp_buf; -//#else -// appPath = wxFNCONV(argv[0]); -//#endif -// printf("appPath [%s]\n",argv[0]); + Renderer::windowX = 0; + Renderer::windowY = 0; + Renderer::windowW = overrideSize.first; + Renderer::windowH = overrideSize.second + 25; + } + } + } + } - wxString exe_path = wxStandardPaths::Get().GetExecutablePath(); - //wxString path_separator = wxFileName::GetPathSeparator(); - //exe_path = exe_path.BeforeLast(path_separator[0]); - //exe_path += path_separator; + std::pair > unitToLoad; + if (hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_UNIT])) == true) { + const wxWX2MBbuf param = (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_UNIT]); + //printf("param = [%s]\n",(const char*)param); -//#if defined(__MINGW32__) + int foundParamIndIndex = -1; + hasCommandArgument(argc, argv, string((const char*) param) + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, (const char*) param, &foundParamIndIndex); + } + //printf("foundParamIndIndex = %d\n",foundParamIndIndex); + string customPath = static_cast(WX2CHR(argv[foundParamIndIndex])); + vector paramPartTokens; + Tokenize(customPath, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string customPathValue = paramPartTokens[1]; + std::vector delimitedList; + Tokenize(customPathValue, delimitedList, ","); + + if (delimitedList.size() >= 2) { + unitToLoad.first = delimitedList[0]; #ifdef WIN32 - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(exe_path)); - string appPath = tmp_buf; - - auto_ptr wstr(Ansi2WideString(appPath.c_str())); - appPath = utf8_encode(wstr.get()); -#else - string appPath(static_cast(WX2CHR(exe_path))); + auto_ptr wstr(Ansi2WideString(unitToLoad.first.c_str())); + unitToLoad.first = utf8_encode(wstr.get()); #endif -//#else -// appPath = wxFNCONV(exe_path); -//#endif + for (unsigned int i = 1; i < delimitedList.size(); ++i) { + string value = delimitedList[i]; +#ifdef WIN32 + auto_ptr wstr(Ansi2WideString(value.c_str())); + value = utf8_encode(wstr.get()); +#endif -// printf("#2 appPath [%s]\n",appPath.c_str()); + unitToLoad.second.push_back(value); + } + } else { + printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", static_cast(WX2CHR(argv[foundParamIndIndex])), (paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(WX2CHR(argv[0]), false); + return false; + } - mainWindow= new MainWindow( unitToLoad, - modelPath, - particlePath, - projectileParticlePath, - splashParticlePath, - newAnimValue, - newParticleLoopValue, - newZoomValue, - newXRotValue, - newYRotValue, - appPath); - if(autoScreenShotAndExit == true) { + } else { + printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", static_cast(WX2CHR(argv[foundParamIndIndex])), (paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(WX2CHR(argv[0]), false); + return false; + } + } + + if (hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL])) == true && + hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL_ANIMATION_VALUE])) == false) { + const wxWX2MBbuf param = (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL]); + //printf("param = [%s]\n",(const char*)param); + + int foundParamIndIndex = -1; + hasCommandArgument(argc, argv, string((const char*) param) + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, (const char*) param, &foundParamIndIndex); + } + //printf("foundParamIndIndex = %d\n",foundParamIndIndex); + string customPath = (const char*) WX2CHR(argv[foundParamIndIndex]); + vector paramPartTokens; + Tokenize(customPath, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string customPathValue = paramPartTokens[1]; + modelPath = customPathValue; +#ifdef WIN32 + auto_ptr wstr(Ansi2WideString(modelPath.c_str())); + modelPath = utf8_encode(wstr.get()); +#endif + + } else { + printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", (const char*) WX2CHR(argv[foundParamIndIndex]), (paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(WX2CHR(argv[0]), false); + return false; + } + } + + if (hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE])) == true && + hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_LOOP_VALUE])) == false) { + const wxWX2MBbuf param = (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE]); + //printf("param = [%s]\n",(const char*)param); + + int foundParamIndIndex = -1; + hasCommandArgument(argc, argv, string((const char*) param) + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, (const char*) param, &foundParamIndIndex); + } + //printf("foundParamIndIndex = %d\n",foundParamIndIndex); + string customPath = (const char*) WX2CHR(argv[foundParamIndIndex]); + vector paramPartTokens; + Tokenize(customPath, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string customPathValue = paramPartTokens[1]; + particlePath = customPathValue; +#ifdef WIN32 + auto_ptr wstr(Ansi2WideString(particlePath.c_str())); + particlePath = utf8_encode(wstr.get()); +#endif + } else { + printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", (const char*) WX2CHR(argv[foundParamIndIndex]), (paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(WX2CHR(argv[0]), false); + return false; + } + } + + if (hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_PROJECTILE])) == true) { + const wxWX2MBbuf param = (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_PROJECTILE]); + //printf("param = [%s]\n",(const char*)param); + + int foundParamIndIndex = -1; + hasCommandArgument(argc, argv, string((const char*) param) + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, (const char*) param, &foundParamIndIndex); + } + //printf("foundParamIndIndex = %d\n",foundParamIndIndex); + string customPath = (const char*) WX2CHR(argv[foundParamIndIndex]); + vector paramPartTokens; + Tokenize(customPath, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string customPathValue = paramPartTokens[1]; + projectileParticlePath = customPathValue; +#ifdef WIN32 + auto_ptr wstr(Ansi2WideString(projectileParticlePath.c_str())); + projectileParticlePath = utf8_encode(wstr.get()); +#endif + } else { + printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", (const char*) WX2CHR(argv[foundParamIndIndex]), (paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(WX2CHR(argv[0]), false); + return false; + } + } + + if (hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_SPLASH])) == true) { + const wxWX2MBbuf param = (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_SPLASH]); + //printf("param = [%s]\n",(const char*)param); + + int foundParamIndIndex = -1; + hasCommandArgument(argc, argv, string((const char*) param) + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, (const char*) param, &foundParamIndIndex); + } + //printf("foundParamIndIndex = %d\n",foundParamIndIndex); + string customPath = (const char*) WX2CHR(argv[foundParamIndIndex]); + vector paramPartTokens; + Tokenize(customPath, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string customPathValue = paramPartTokens[1]; + splashParticlePath = customPathValue; +#ifdef WIN32 + auto_ptr wstr(Ansi2WideString(splashParticlePath.c_str())); + splashParticlePath = utf8_encode(wstr.get()); +#endif + } else { + printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", (const char*) WX2CHR(argv[foundParamIndIndex]), (paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(WX2CHR(argv[0]), false); + return false; + } + } + + float newAnimValue = 0.0f; + if (hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL_ANIMATION_VALUE])) == true) { + const wxWX2MBbuf param = (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_MODEL_ANIMATION_VALUE]); + + int foundParamIndIndex = -1; + hasCommandArgument(argc, argv, string((const char*) param) + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, (const char*) param, &foundParamIndIndex); + } + //printf("foundParamIndIndex = %d\n",foundParamIndIndex); + string value = (const char*) WX2CHR(argv[foundParamIndIndex]); + vector paramPartTokens; + Tokenize(value, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + newAnimValue = strToFloat(paramPartTokens[1]); + printf("newAnimValue = %f\n", newAnimValue); + } else { + printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", (const char*) WX2CHR(argv[foundParamIndIndex]), (paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(WX2CHR(argv[0]), false); + return false; + } + } + + int newParticleLoopValue = 1; + if (hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_LOOP_VALUE])) == true) { + const wxWX2MBbuf param = (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_LOAD_PARTICLE_LOOP_VALUE]); + + int foundParamIndIndex = -1; + hasCommandArgument(argc, argv, string((const char*) param) + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, (const char*) param, &foundParamIndIndex); + } + //printf("foundParamIndIndex = %d\n",foundParamIndIndex); + string value = (const char*) WX2CHR(argv[foundParamIndIndex]); + vector paramPartTokens; + Tokenize(value, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + newParticleLoopValue = strToInt(paramPartTokens[1]); + //printf("newParticleLoopValue = %d\n",newParticleLoopValue); + } else { + printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", (const char*) WX2CHR(argv[foundParamIndIndex]), (paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(WX2CHR(argv[0]), false); + return false; + } + } + + float newZoomValue = 1.0f; + if (hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ZOOM_VALUE])) == true) { + const wxWX2MBbuf param = (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ZOOM_VALUE]); + + int foundParamIndIndex = -1; + hasCommandArgument(argc, argv, string((const char*) param) + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, (const char*) param, &foundParamIndIndex); + } + //printf("foundParamIndIndex = %d\n",foundParamIndIndex); + string value = (const char*) WX2CHR(argv[foundParamIndIndex]); + vector paramPartTokens; + Tokenize(value, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + newZoomValue = strToFloat(paramPartTokens[1]); + //printf("newAnimValue = %f\n",newAnimValue); + } else { + printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", (const char*) WX2CHR(argv[foundParamIndIndex]), (paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(WX2CHR(argv[0]), false); + return false; + } + } + + float newXRotValue = 0.0f; + if (hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_X_VALUE])) == true) { + const wxWX2MBbuf param = (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_X_VALUE]); + + int foundParamIndIndex = -1; + hasCommandArgument(argc, argv, string((const char*) param) + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, (const char*) param, &foundParamIndIndex); + } + //printf("foundParamIndIndex = %d\n",foundParamIndIndex); + string value = (const char*) WX2CHR(argv[foundParamIndIndex]); + vector paramPartTokens; + Tokenize(value, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + newXRotValue = strToFloat(paramPartTokens[1]); + //printf("newAnimValue = %f\n",newAnimValue); + } else { + printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", (const char*) WX2CHR(argv[foundParamIndIndex]), (paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(WX2CHR(argv[0]), false); + return false; + } + } + + float newYRotValue = 0.0f; + if (hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_Y_VALUE])) == true) { + const wxWX2MBbuf param = (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_ROTATE_Y_VALUE]); + + int foundParamIndIndex = -1; + hasCommandArgument(argc, argv, string((const char*) param) + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, (const char*) param, &foundParamIndIndex); + } + //printf("foundParamIndIndex = %d\n",foundParamIndIndex); + string value = static_cast(WX2CHR(argv[foundParamIndIndex])); + vector paramPartTokens; + Tokenize(value, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + newYRotValue = strToFloat(paramPartTokens[1]); + //printf("newAnimValue = %f\n",newAnimValue); + } else { + printf("\nInvalid path specified on commandline [%s] value [%s]\n\n", static_cast(WX2CHR(argv[foundParamIndIndex])), (paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(WX2CHR(argv[0]), false); + return false; + } + } + + if (hasCommandArgument(argc, argv, (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_SCREENSHOT_FORMAT])) == true) { + const wxWX2MBbuf param = (const char *) wxConvCurrent->cWX2MB(GAME_ARGS[GAME_ARG_SCREENSHOT_FORMAT]); + + int foundParamIndIndex = -1; + hasCommandArgument(argc, argv, string((const char*) param) + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, (const char*) param, &foundParamIndIndex); + } + //printf("foundParamIndIndex = %d\n",foundParamIndIndex); + string value = static_cast(WX2CHR(argv[foundParamIndIndex])); + vector paramPartTokens; + Tokenize(value, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + fileFormat = paramPartTokens[1]; + } else { + printf("\nInvalid value specified on commandline [%s] value [%s]\n\n", static_cast(WX2CHR(argv[foundParamIndIndex])), (paramPartTokens.size() >= 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(WX2CHR(argv[0]), false); + return false; + } + } + + if (argc == 2 && argv[1][0] != '-') { + + //#if defined(__MINGW32__) +#ifdef WIN32 + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(argv[1])); + modelPath = tmp_buf; + auto_ptr wstr(Ansi2WideString(modelPath.c_str())); + modelPath = utf8_encode(wstr.get()); +#else + modelPath = static_cast(WX2CHR(argv[1])); +#endif + + //#else + // modelPath = wxFNCONV(argv[1]); + //#endif + + } + + //#if defined(__MINGW32__) + // const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(argv[0])); + // appPath = tmp_buf; + //#else + // appPath = wxFNCONV(argv[0]); + //#endif + // printf("appPath [%s]\n",argv[0]); + + wxString exe_path = wxStandardPaths::Get().GetExecutablePath(); + //wxString path_separator = wxFileName::GetPathSeparator(); + //exe_path = exe_path.BeforeLast(path_separator[0]); + //exe_path += path_separator; + + //#if defined(__MINGW32__) +#ifdef WIN32 + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(exe_path)); + string appPath = tmp_buf; + + auto_ptr wstr(Ansi2WideString(appPath.c_str())); + appPath = utf8_encode(wstr.get()); +#else + string appPath(static_cast(WX2CHR(exe_path))); +#endif + + //#else + // appPath = wxFNCONV(exe_path); + //#endif + + // printf("#2 appPath [%s]\n",appPath.c_str()); + + mainWindow = new MainWindow(unitToLoad, + modelPath, + particlePath, + projectileParticlePath, + splashParticlePath, + newAnimValue, + newParticleLoopValue, + newZoomValue, + newXRotValue, + newYRotValue, + appPath); + if (autoScreenShotAndExit == true) { #if !defined(WIN32) - mainWindow->Iconize(true); + mainWindow->Iconize(true); #endif - } - mainWindow->Show(); - mainWindow->init(); - mainWindow->Update(); - mainWindow->setupTimer(); + } + mainWindow->Show(); + mainWindow->init(); + mainWindow->Update(); + mainWindow->setupTimer(); - return true; -} + return true; + } -int App::MainLoop(){ - try{ - return wxApp::MainLoop(); - } - catch(const exception &e){ - wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Exception"), wxOK | wxICON_ERROR).ShowModal(); - return 1; - } - return 0; -} + int App::MainLoop() { + try { + return wxApp::MainLoop(); + } catch (const exception &e) { + wxMessageDialog(NULL, ToUnicode(e.what()), ToUnicode("Exception"), wxOK | wxICON_ERROR).ShowModal(); + return 1; + } + return 0; + } -int App::OnExit(){ - SystemFlags::Close(); - SystemFlags::SHUTDOWN_PROGRAM_MODE=true; + int App::OnExit() { + SystemFlags::Close(); + SystemFlags::SHUTDOWN_PROGRAM_MODE = true; - return 0; -} + return 0; + } -}}//end namespace + } + }//end namespace IMPLEMENT_APP_CONSOLE(Shared::G3dViewer::App) diff --git a/source/g3d_viewer/main.h b/source/g3d_viewer/main.h index d1af96318..02ab8e126 100644 --- a/source/g3d_viewer/main.h +++ b/source/g3d_viewer/main.h @@ -13,8 +13,8 @@ #define _SHADER_G3DVIEWER_MAIN_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -32,203 +32,208 @@ using std::string; using namespace Glest::Game; -namespace Shared{ namespace G3dViewer{ +namespace Shared { + namespace G3dViewer { -class GlCanvas; + class GlCanvas; -// =============================== -// class MainWindow -// =============================== + // =============================== + // class MainWindow + // =============================== -class MainWindow: public wxFrame{ -private: - DECLARE_EVENT_TABLE() + class MainWindow : public wxFrame { + private: + DECLARE_EVENT_TABLE() -public: - static const string versionString; - static const string winHeader; + public: + static const string versionString; + static const string winHeader; - enum MenuId{ - miFileLoad, - miFileLoadParticleXML, - miFileLoadProjectileParticleXML, - miFileLoadSplashParticleXML, - miFileClearAll, - miFileToggleScreenshotTransparent, - miFileSaveScreenshot, - miModeWireframe, - miModeNormals, - miModeGrid, - miSpeedSlower, - miSpeedFaster, - miRestart, - miChangeBackgroundColor, - miColorRed, - miColorBlue, - miColorGreen, - miColorYellow, - miColorWhite, - miColorCyan, - miColorOrange, - miColorMagenta - }; + enum MenuId { + miFileLoad, + miFileLoadParticleXML, + miFileLoadProjectileParticleXML, + miFileLoadSplashParticleXML, + miFileClearAll, + miFileToggleScreenshotTransparent, + miFileSaveScreenshot, + miModeWireframe, + miModeNormals, + miModeGrid, + miSpeedSlower, + miSpeedFaster, + miRestart, + miChangeBackgroundColor, + miColorRed, + miColorBlue, + miColorGreen, + miColorYellow, + miColorWhite, + miColorCyan, + miColorOrange, + miColorMagenta + }; -private: - GlCanvas *glCanvas; - Renderer *renderer; + private: + GlCanvas *glCanvas; + Renderer *renderer; - wxTimer *timer; + wxTimer *timer; - wxMenuBar *menu; - wxMenu *menuFile; - wxMenu *menuMode; - wxMenu *menuSpeed; - wxMenu *menuCustomColor; - wxFileDialog *fileDialog; + wxMenuBar *menu; + wxMenu *menuFile; + wxMenu *menuMode; + wxMenu *menuSpeed; + wxMenu *menuCustomColor; + wxFileDialog *fileDialog; - wxColourDialog *colorPicker; + wxColourDialog *colorPicker; - Model *model; + Model *model; - std::pair > unitPath; - std::vector modelPathList; - std::vector particlePathList; - std::vector particleProjectilePathList; - std::vector particleSplashPathList; // as above + std::pair > unitPath; + std::vector modelPathList; + std::vector particlePathList; + std::vector particleProjectilePathList; + std::vector particleSplashPathList; // as above - bool resetAnimation; - float resetAnim; - int resetParticleLoopStart; + bool resetAnimation; + float resetAnim; + int resetParticleLoopStart; - float speed; - float anim; - float lastanim; - int particleLoopStart; - float rotX, rotY, zoom; - float backBrightness, gridBrightness, lightBrightness; - int lastX, lastY; - Renderer::PlayerColor playerColor; - bool initTextureManager; + float speed; + float anim; + float lastanim; + int particleLoopStart; + float rotX, rotY, zoom; + float backBrightness, gridBrightness, lightBrightness; + int lastX, lastY; + Renderer::PlayerColor playerColor; + bool initTextureManager; - std::vector unitParticleSystemTypes; - std::vector unitParticleSystems; + std::vector unitParticleSystemTypes; + std::vector unitParticleSystems; - std::vector projectileParticleSystemTypes; - std::vector projectileParticleSystems; - std::vector splashParticleSystemTypes; // as above - std::vector splashParticleSystems; - string statusbarText; + std::vector projectileParticleSystemTypes; + std::vector projectileParticleSystems; + std::vector splashParticleSystemTypes; // as above + std::vector splashParticleSystems; + string statusbarText; - bool isControlKeyPressed; + bool isControlKeyPressed; - string appPath; + string appPath; - bool startupSettingsInited; + bool startupSettingsInited; - void initGlCanvas(); - void loadUnit(string path, string skillName); - void loadModel(string path); - void loadParticle(string path); - void loadProjectileParticle(string path); - void loadSplashParticle(string path); + void initGlCanvas(); + void loadUnit(string path, string skillName); + void loadModel(string path); + void loadParticle(string path); + void loadProjectileParticle(string path); + void loadSplashParticle(string path); - void saveScreenshot(); + void saveScreenshot(); -public: - MainWindow( std::pair > unitToLoad, - const string modelPath,const string particlePath, - const string projectileParticlePath,const string splashParticlePath, - float defaultAnimation,int defaultParticleLoopStart, - float defaultZoom,float defaultXRot, float defaultYRot, + public: + MainWindow(std::pair > unitToLoad, + const string modelPath, const string particlePath, + const string projectileParticlePath, const string splashParticlePath, + float defaultAnimation, int defaultParticleLoopStart, + float defaultZoom, float defaultXRot, float defaultYRot, string appPath); - ~MainWindow(); - void init(); + ~MainWindow(); + void init(); - void Notify(); + void Notify(); - void onPaint(wxPaintEvent &event); - void onClose(wxCloseEvent &event); - void onMenuFileLoad(wxCommandEvent &event); - void onMenuFileLoadParticleXML(wxCommandEvent &event); - void onMenuFileLoadProjectileParticleXML(wxCommandEvent &event); - void onMenuFileLoadSplashParticleXML(wxCommandEvent &event); - void onMenuFileClearAll(wxCommandEvent &event); - void onMenumFileToggleScreenshotTransparent(wxCommandEvent &event); - void onMenuFileSaveScreenshot(wxCommandEvent &event); - void onMenuFileExit(wxCommandEvent &event); - void onMenuModeNormals(wxCommandEvent &event); - void onMenuModeWireframe(wxCommandEvent &event); - void onMenuModeGrid(wxCommandEvent &event); - void onMenuSpeedSlower(wxCommandEvent &event); - void onMenuSpeedFaster(wxCommandEvent &event); - void onMenuRestart(wxCommandEvent &event); - void OnChangeColor(wxCommandEvent &event); - void onMenuColorRed(wxCommandEvent &event); - void onMenuColorBlue(wxCommandEvent &event); - void onMenuColorGreen(wxCommandEvent &event); - void onMenuColorYellow(wxCommandEvent &event); - void onMenuColorWhite(wxCommandEvent &event); - void onMenuColorCyan(wxCommandEvent &event); - void onMenuColorOrange(wxCommandEvent &event); - void onMenuColorMagenta(wxCommandEvent &event); - void onMouseWheelDown(wxMouseEvent &event); - void onMouseWheelUp(wxMouseEvent &event); - void onMouseMove(wxMouseEvent &event); - void onTimer(wxTimerEvent &event); + void onPaint(wxPaintEvent &event); + void onClose(wxCloseEvent &event); + void onMenuFileLoad(wxCommandEvent &event); + void onMenuFileLoadParticleXML(wxCommandEvent &event); + void onMenuFileLoadProjectileParticleXML(wxCommandEvent &event); + void onMenuFileLoadSplashParticleXML(wxCommandEvent &event); + void onMenuFileClearAll(wxCommandEvent &event); + void onMenumFileToggleScreenshotTransparent(wxCommandEvent &event); + void onMenuFileSaveScreenshot(wxCommandEvent &event); + void onMenuFileExit(wxCommandEvent &event); + void onMenuModeNormals(wxCommandEvent &event); + void onMenuModeWireframe(wxCommandEvent &event); + void onMenuModeGrid(wxCommandEvent &event); + void onMenuSpeedSlower(wxCommandEvent &event); + void onMenuSpeedFaster(wxCommandEvent &event); + void onMenuRestart(wxCommandEvent &event); + void OnChangeColor(wxCommandEvent &event); + void onMenuColorRed(wxCommandEvent &event); + void onMenuColorBlue(wxCommandEvent &event); + void onMenuColorGreen(wxCommandEvent &event); + void onMenuColorYellow(wxCommandEvent &event); + void onMenuColorWhite(wxCommandEvent &event); + void onMenuColorCyan(wxCommandEvent &event); + void onMenuColorOrange(wxCommandEvent &event); + void onMenuColorMagenta(wxCommandEvent &event); + void onMouseWheelDown(wxMouseEvent &event); + void onMouseWheelUp(wxMouseEvent &event); + void onMouseMove(wxMouseEvent &event); + void onTimer(wxTimerEvent &event); - void onKeyDown(wxKeyEvent &e); + void onKeyDown(wxKeyEvent &e); - string getModelInfo(); + string getModelInfo(); - void setupTimer(); - void setupStartupSettings(); -}; + void setupTimer(); + void setupStartupSettings(); + }; -// ===================================================== -// class GlCanvas -// ===================================================== + // ===================================================== + // class GlCanvas + // ===================================================== -class GlCanvas: public wxGLCanvas { -private: - DECLARE_EVENT_TABLE() + class GlCanvas : public wxGLCanvas { + private: + DECLARE_EVENT_TABLE() -public: - GlCanvas(MainWindow *mainWindow, int *args); - ~GlCanvas(); + public: + GlCanvas(MainWindow *mainWindow, int *args); + ~GlCanvas(); - void onMouseWheel(wxMouseEvent &event); - void onMouseMove(wxMouseEvent &event); - void onPaint(wxPaintEvent &event); - void onKeyDown(wxKeyEvent &event); - void OnSize(wxSizeEvent&); - void setCurrentGLContext(); + void onMouseWheel(wxMouseEvent &event); + void onMouseMove(wxMouseEvent &event); + void onPaint(wxPaintEvent &event); + void onKeyDown(wxKeyEvent &event); + void OnSize(wxSizeEvent&); + void setCurrentGLContext(); - wxGLContext * getCtx() { return context; } -private: - MainWindow *mainWindow; - wxGLContext *context; -}; + wxGLContext * getCtx() { + return context; + } + private: + MainWindow *mainWindow; + wxGLContext *context; + }; -// =============================== -// class App -// =============================== + // =============================== + // class App + // =============================== -class App: public wxApp{ -private: - MainWindow *mainWindow; + class App : public wxApp { + private: + MainWindow *mainWindow; + + public: + App() : wxApp() { + mainWindow = NULL; + } + virtual ~App() { + } + virtual bool OnInit(); + virtual int MainLoop(); + virtual int OnExit(); + }; -public: - App() : wxApp() { - mainWindow = NULL; } - virtual ~App() {} - virtual bool OnInit(); - virtual int MainLoop(); - virtual int OnExit(); -}; - -}}//end namespace +}//end namespace DECLARE_APP(Shared::G3dViewer::App) diff --git a/source/g3d_viewer/renderer.cpp b/source/g3d_viewer/renderer.cpp index a8a09d44d..df1771e0f 100644 --- a/source/g3d_viewer/renderer.cpp +++ b/source/g3d_viewer/renderer.cpp @@ -22,534 +22,534 @@ using namespace Shared::Graphics::Gl; using namespace Glest::Game; using namespace Shared::Util; -namespace Shared{ namespace G3dViewer{ +namespace Shared { + namespace G3dViewer { -int Renderer::windowX= 100; -int Renderer::windowY= 100; -int Renderer::windowW= 640; -int Renderer::windowH= 480; + int Renderer::windowX = 100; + int Renderer::windowY = 100; + int Renderer::windowW = 640; + int Renderer::windowH = 480; -// =============================================== -// class MeshCallbackTeamColor -// =============================================== + // =============================================== + // class MeshCallbackTeamColor + // =============================================== -void MeshCallbackTeamColor::execute(const Mesh *mesh){ + void MeshCallbackTeamColor::execute(const Mesh *mesh) { - //team color - if(mesh->getCustomTexture() && teamTexture!=NULL){ - //texture 0 - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + //team color + if (mesh->getCustomTexture() && teamTexture != NULL) { + //texture 0 + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - //set color to interpolation - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); + //set color to interpolation + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE1); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE1); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); - //set alpha to 1 - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); + //set alpha to 1 + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); - //texture 1 - glActiveTexture(GL_TEXTURE1); - glMultiTexCoord2f(GL_TEXTURE1, 0.f, 0.f); - glEnable(GL_TEXTURE_2D); + //texture 1 + glActiveTexture(GL_TEXTURE1); + glMultiTexCoord2f(GL_TEXTURE1, 0.f, 0.f); + glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, static_cast(teamTexture)->getHandle()); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glBindTexture(GL_TEXTURE_2D, static_cast(teamTexture)->getHandle()); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); - //set alpha to 1 - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); + //set alpha to 1 + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); - glActiveTexture(GL_TEXTURE0); - } - else{ - glActiveTexture(GL_TEXTURE1); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - } -} - -// =============================================== -// class Renderer -// =============================================== - -Renderer::Renderer() { - normals= false; - wireframe= false; - grid= true; - modelRenderer = NULL; - textureManager = NULL; - particleRenderer = NULL; - modelManager = NULL; - width=0; - height=0; - red = 0.3f; - green = 0.3f; - blue = 0.3f; - alpha = 1.0f; - - customTextureRed=NULL; - customTextureBlue=NULL; - customTextureGreen=NULL; - customTextureYellow=NULL; - customTextureWhite=NULL; - customTextureCyan=NULL; - customTextureOrange=NULL; - customTextureMagenta=NULL; - particleManager=NULL; -} - -Renderer::~Renderer() { - delete modelRenderer; - delete textureManager; - delete particleRenderer; - - //resources - delete particleManager; - delete modelManager; - - if(GraphicsInterface::getInstance().getFactory() != NULL) { - delete GraphicsInterface::getInstance().getFactory(); - GraphicsInterface::getInstance().setFactory(NULL); - } -} - -Renderer * Renderer::getInstance() { - static Renderer * renderer = new Renderer(); - return renderer; -} - -void Renderer::transform(float rotX, float rotY, float zoom) { - assertGl(); - - glMatrixMode(GL_MODELVIEW); - glRotatef(rotY, 1.0f, 0.0f, 0.0f); - glRotatef(rotX, 0.0f, 1.0f, 0.0f); - glScalef(zoom, zoom, zoom); - Vec4f pos(-8.0f, 5.0f, 10.0f, 0.0f); - glLightfv(GL_LIGHT0,GL_POSITION, pos.ptr()); - - assertGl(); -} - -void Renderer::checkGlCaps() { - - if(glActiveTexture == NULL) { - string message; - - message += "Your system supports OpenGL version \""; - message += getGlVersion() + string("\"\n"); - message += "ZetaGlest needs a version that supports\n"; - message += "glActiveTexture (OpenGL 1.3) or the ARB_multitexture extension."; - - throw megaglest_runtime_error(message.c_str()); - } - - //opengl 1.3 - //if(!isGlVersionSupported(1, 3, 0)) { - if(glewIsSupported("GL_VERSION_1_3") == false) { - string message; - - message += "Your system supports OpenGL version \""; - message += getGlVersion() + string("\"\n"); - message += "ZetaGlest needs at least version 1.3 to work\n"; - message += "You may solve this problem by installing your latest video card drivers"; - - throw megaglest_runtime_error(message.c_str()); - } - - //opengl 1.4 or extension - //if(isGlVersionSupported(1, 4, 0) == false) { - if(glewIsSupported("GL_VERSION_1_4") == false) { - checkExtension("GL_ARB_texture_env_crossbar", "ZetaGlest"); - } -} - -void Renderer::checkExtension(const string &extension, const string &msg) { - if(isGlExtensionSupported(extension.c_str()) == false) { - string str= "OpenGL extension not supported: " + extension + ", required for " + msg; - throw megaglest_runtime_error(str); - } -} - -Texture2D * Renderer::getNewTexture2D() { - Texture2D *newTexture = textureManager->newTexture2D(); - return newTexture; -} - -Model * Renderer::newModel(ResourceScope rs,const string &path,bool deletePixMapAfterLoad,std::map > > *loadedFileList, string *sourceLoader) { - return modelManager->newModel(path,deletePixMapAfterLoad,loadedFileList,sourceLoader); -} - -void Renderer::endModel(ResourceScope rs,Model *model) { - modelManager->endModel(model); -} - -void Renderer::init() { - assertGl(); - - GraphicsFactory *gf= GraphicsInterface::getInstance().getFactory(); - if(gf == NULL) { - gf= new GraphicsFactoryGl(); - GraphicsInterface::getInstance().setFactory(gf); - } - - Config &config = Config::getInstance(); - if(config.getBool("CheckGlCaps")){ - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - checkGlCaps(); - } - - if(glActiveTexture == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error: glActiveTexture == NULL\nglActiveTexture is only supported if the GL version is 1.3 or greater,\nor if the ARB_multitexture extension is supported!"); - throw megaglest_runtime_error(szBuf); - } - - modelRenderer= gf->newModelRenderer(); - textureManager= gf->newTextureManager(); - particleRenderer= gf->newParticleRenderer(); - - //resources - particleManager= gf->newParticleManager(); - - modelManager = gf->newModelManager(); - modelManager->setTextureManager(textureManager); - - //red tex - customTextureRed= textureManager->newTexture2D(); - customTextureRed->getPixmap()->init(1, 1, 3); - customTextureRed->getPixmap()->setPixel(0, 0, Vec3f(1.f, 0.f, 0.f)); - - //blue tex - customTextureBlue= textureManager->newTexture2D(); - customTextureBlue->getPixmap()->init(1, 1, 3); - customTextureBlue->getPixmap()->setPixel(0, 0, Vec3f(0.f, 0.f, 1.f)); - - //green tex - customTextureGreen= textureManager->newTexture2D(); - customTextureGreen->getPixmap()->init(1, 1, 3); - customTextureGreen->getPixmap()->setPixel(0, 0, Vec3f(0.f, 0.5f, 0.f)); - - //yellow tex - customTextureYellow= textureManager->newTexture2D(); - customTextureYellow->getPixmap()->init(1, 1, 3); - customTextureYellow->getPixmap()->setPixel(0, 0, Vec3f(1.f, 1.f, 0.f)); - - //white tex - customTextureWhite= textureManager->newTexture2D(); - customTextureWhite->getPixmap()->init(1, 1, 3); - customTextureWhite->getPixmap()->setPixel(0, 0, Vec3f(1.f, 1.f, 1.f)); - - //cyan tex - customTextureCyan= textureManager->newTexture2D(); - customTextureCyan->getPixmap()->init(1, 1, 3); - customTextureCyan->getPixmap()->setPixel(0, 0, Vec3f(0.f, 1.f, 0.8f)); - - //orange tex - customTextureOrange= textureManager->newTexture2D(); - customTextureOrange->getPixmap()->init(1, 1, 3); - customTextureOrange->getPixmap()->setPixel(0, 0, Vec3f(1.f, 0.5f, 0.f)); - - //magenta tex - customTextureMagenta= textureManager->newTexture2D(); - customTextureMagenta->getPixmap()->init(1, 1, 3); - customTextureMagenta->getPixmap()->setPixel(0, 0, Vec3f(1.f, 0.5f, 1.f)); - - glClearColor(red, green, blue, alpha); //backgroundcolor constant 0.3 - //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - /* once the GL context is valid : */ - //GLint alpha_bits; - //glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); - //printf("#1 The framebuffer uses %d bit(s) per the alpha component\n", alpha_bits); - - glEnable(GL_TEXTURE_2D); - glFrontFace(GL_CW); - glEnable(GL_CULL_FACE); - glEnable(GL_DEPTH_TEST); - glEnable(GL_ALPHA_TEST); - //glAlphaFunc(GL_GREATER, 0.5f); - glAlphaFunc(GL_GREATER, 0.0f); - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - - Vec4f diffuse= Vec4f(1.0f, 1.0f, 1.0f, 1.0f); - Vec4f ambient= Vec4f(0.3f, 0.3f, 0.3f, 1.0f); - Vec4f specular= Vec4f(0.1f, 0.1f, 0.1f, 1.0f); - - glLightfv(GL_LIGHT0,GL_AMBIENT, ambient.ptr()); - glLightfv(GL_LIGHT0,GL_DIFFUSE, diffuse.ptr()); - glLightfv(GL_LIGHT0,GL_SPECULAR, specular.ptr()); - - glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - glEnable(GL_COLOR_MATERIAL); - - assertGl(); -} - -void Renderer::reset(int w, int h, PlayerColor playerColor) { - assertGl(); - - width=w; - height=h; - - //glClearColor(red, green, blue, alpha); //backgroundcolor constant 0.3 - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - /* once the GL context is valid : */ - //GLint alpha_bits; - //glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); - //printf("#2 The framebuffer uses %d bit(s) per the alpha component\n", alpha_bits); - - glViewport(0, 0, w, h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(60.0f, static_cast(w)/h, 1.0f, 200.0f); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef(0, -1.5, -5); - - Texture2D *customTexture=NULL; - switch(playerColor) { - case pcRed: - customTexture= customTextureRed; - break; - case pcBlue: - customTexture= customTextureBlue; - break; - case pcGreen: - customTexture= customTextureGreen; - break; - case pcYellow: - customTexture= customTextureYellow; - break; - case pcWhite: - customTexture= customTextureWhite; - break; - case pcCyan: - customTexture= customTextureCyan; - break; - case pcOrange: - customTexture= customTextureOrange; - break; - case pcMagenta: - customTexture= customTextureMagenta; - break; - default: - assert(false); - break; - } - meshCallbackTeamColor.setTeamTexture(customTexture); - - if(wireframe) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); - glDisable(GL_LIGHT0); - } - else { - glEnable(GL_TEXTURE_2D); - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } - - assertGl(); -} - -void Renderer::renderGrid() { - if(grid) { - float i=0; - - assertGl(); - - glPushAttrib(GL_ENABLE_BIT); - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); - - glBegin(GL_LINES); - glColor3f(1.0f, 1.0f, 1.0f); // gridcolor constant - for(i=-10.0f; i<=10.0f; i+=1.0f) { - glVertex3f(i, 0.0f, 10.0f); - glVertex3f(i, 0.0f, -10.0f); + glActiveTexture(GL_TEXTURE0); + } else { + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } } - for(i=-10.0f; i<=10.0f; i+=1.0f) { - glVertex3f(10.f, 0.0f, i); - glVertex3f(-10.f, 0.0f, i); + + // =============================================== + // class Renderer + // =============================================== + + Renderer::Renderer() { + normals = false; + wireframe = false; + grid = true; + modelRenderer = NULL; + textureManager = NULL; + particleRenderer = NULL; + modelManager = NULL; + width = 0; + height = 0; + red = 0.3f; + green = 0.3f; + blue = 0.3f; + alpha = 1.0f; + + customTextureRed = NULL; + customTextureBlue = NULL; + customTextureGreen = NULL; + customTextureYellow = NULL; + customTextureWhite = NULL; + customTextureCyan = NULL; + customTextureOrange = NULL; + customTextureMagenta = NULL; + particleManager = NULL; } - glEnd(); - glPopAttrib(); + Renderer::~Renderer() { + delete modelRenderer; + delete textureManager; + delete particleRenderer; - assertGl(); - } -} + //resources + delete particleManager; + delete modelManager; -void Renderer::toggleNormals() { - normals= normals? false: true; -} + if (GraphicsInterface::getInstance().getFactory() != NULL) { + delete GraphicsInterface::getInstance().getFactory(); + GraphicsInterface::getInstance().setFactory(NULL); + } + } -void Renderer::toggleWireframe() { - wireframe= wireframe? false: true; -} + Renderer * Renderer::getInstance() { + static Renderer * renderer = new Renderer(); + return renderer; + } -void Renderer::toggleGrid() { - grid= grid? false: true; -} + void Renderer::transform(float rotX, float rotY, float zoom) { + assertGl(); -void Renderer::renderTheModel(Model *model, float f) { - if(model != NULL){ - modelRenderer->begin(true, true, !wireframe, false, &meshCallbackTeamColor); - model->updateInterpolationData(f, true); - modelRenderer->render(model); + glMatrixMode(GL_MODELVIEW); + glRotatef(rotY, 1.0f, 0.0f, 0.0f); + glRotatef(rotX, 0.0f, 1.0f, 0.0f); + glScalef(zoom, zoom, zoom); + Vec4f pos(-8.0f, 5.0f, 10.0f, 0.0f); + glLightfv(GL_LIGHT0, GL_POSITION, pos.ptr()); - if(normals) { - glPushAttrib(GL_ENABLE_BIT); - glDisable(GL_LIGHTING); - glDisable(GL_TEXTURE_2D); - glColor3f(1.0f, 1.0f, 1.0f); //normalscolor constant - modelRenderer->renderNormalsOnly(model); + assertGl(); + } + + void Renderer::checkGlCaps() { + + if (glActiveTexture == NULL) { + string message; + + message += "Your system supports OpenGL version \""; + message += getGlVersion() + string("\"\n"); + message += "ZetaGlest needs a version that supports\n"; + message += "glActiveTexture (OpenGL 1.3) or the ARB_multitexture extension."; + + throw megaglest_runtime_error(message.c_str()); + } + + //opengl 1.3 + //if(!isGlVersionSupported(1, 3, 0)) { + if (glewIsSupported("GL_VERSION_1_3") == false) { + string message; + + message += "Your system supports OpenGL version \""; + message += getGlVersion() + string("\"\n"); + message += "ZetaGlest needs at least version 1.3 to work\n"; + message += "You may solve this problem by installing your latest video card drivers"; + + throw megaglest_runtime_error(message.c_str()); + } + + //opengl 1.4 or extension + //if(isGlVersionSupported(1, 4, 0) == false) { + if (glewIsSupported("GL_VERSION_1_4") == false) { + checkExtension("GL_ARB_texture_env_crossbar", "ZetaGlest"); + } + } + + void Renderer::checkExtension(const string &extension, const string &msg) { + if (isGlExtensionSupported(extension.c_str()) == false) { + string str = "OpenGL extension not supported: " + extension + ", required for " + msg; + throw megaglest_runtime_error(str); + } + } + + Texture2D * Renderer::getNewTexture2D() { + Texture2D *newTexture = textureManager->newTexture2D(); + return newTexture; + } + + Model * Renderer::newModel(ResourceScope rs, const string &path, bool deletePixMapAfterLoad, std::map > > *loadedFileList, string *sourceLoader) { + return modelManager->newModel(path, deletePixMapAfterLoad, loadedFileList, sourceLoader); + } + + void Renderer::endModel(ResourceScope rs, Model *model) { + modelManager->endModel(model); + } + + void Renderer::init() { + assertGl(); + + GraphicsFactory *gf = GraphicsInterface::getInstance().getFactory(); + if (gf == NULL) { + gf = new GraphicsFactoryGl(); + GraphicsInterface::getInstance().setFactory(gf); + } + + Config &config = Config::getInstance(); + if (config.getBool("CheckGlCaps")) { + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + checkGlCaps(); + } + + if (glActiveTexture == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error: glActiveTexture == NULL\nglActiveTexture is only supported if the GL version is 1.3 or greater,\nor if the ARB_multitexture extension is supported!"); + throw megaglest_runtime_error(szBuf); + } + + modelRenderer = gf->newModelRenderer(); + textureManager = gf->newTextureManager(); + particleRenderer = gf->newParticleRenderer(); + + //resources + particleManager = gf->newParticleManager(); + + modelManager = gf->newModelManager(); + modelManager->setTextureManager(textureManager); + + //red tex + customTextureRed = textureManager->newTexture2D(); + customTextureRed->getPixmap()->init(1, 1, 3); + customTextureRed->getPixmap()->setPixel(0, 0, Vec3f(1.f, 0.f, 0.f)); + + //blue tex + customTextureBlue = textureManager->newTexture2D(); + customTextureBlue->getPixmap()->init(1, 1, 3); + customTextureBlue->getPixmap()->setPixel(0, 0, Vec3f(0.f, 0.f, 1.f)); + + //green tex + customTextureGreen = textureManager->newTexture2D(); + customTextureGreen->getPixmap()->init(1, 1, 3); + customTextureGreen->getPixmap()->setPixel(0, 0, Vec3f(0.f, 0.5f, 0.f)); + + //yellow tex + customTextureYellow = textureManager->newTexture2D(); + customTextureYellow->getPixmap()->init(1, 1, 3); + customTextureYellow->getPixmap()->setPixel(0, 0, Vec3f(1.f, 1.f, 0.f)); + + //white tex + customTextureWhite = textureManager->newTexture2D(); + customTextureWhite->getPixmap()->init(1, 1, 3); + customTextureWhite->getPixmap()->setPixel(0, 0, Vec3f(1.f, 1.f, 1.f)); + + //cyan tex + customTextureCyan = textureManager->newTexture2D(); + customTextureCyan->getPixmap()->init(1, 1, 3); + customTextureCyan->getPixmap()->setPixel(0, 0, Vec3f(0.f, 1.f, 0.8f)); + + //orange tex + customTextureOrange = textureManager->newTexture2D(); + customTextureOrange->getPixmap()->init(1, 1, 3); + customTextureOrange->getPixmap()->setPixel(0, 0, Vec3f(1.f, 0.5f, 0.f)); + + //magenta tex + customTextureMagenta = textureManager->newTexture2D(); + customTextureMagenta->getPixmap()->init(1, 1, 3); + customTextureMagenta->getPixmap()->setPixel(0, 0, Vec3f(1.f, 0.5f, 1.f)); + + glClearColor(red, green, blue, alpha); //backgroundcolor constant 0.3 + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* once the GL context is valid : */ + //GLint alpha_bits; + //glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); + //printf("#1 The framebuffer uses %d bit(s) per the alpha component\n", alpha_bits); + + glEnable(GL_TEXTURE_2D); + glFrontFace(GL_CW); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glEnable(GL_ALPHA_TEST); + //glAlphaFunc(GL_GREATER, 0.5f); + glAlphaFunc(GL_GREATER, 0.0f); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + Vec4f diffuse = Vec4f(1.0f, 1.0f, 1.0f, 1.0f); + Vec4f ambient = Vec4f(0.3f, 0.3f, 0.3f, 1.0f); + Vec4f specular = Vec4f(0.1f, 0.1f, 0.1f, 1.0f); + + glLightfv(GL_LIGHT0, GL_AMBIENT, ambient.ptr()); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse.ptr()); + glLightfv(GL_LIGHT0, GL_SPECULAR, specular.ptr()); + + glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + + assertGl(); + } + + void Renderer::reset(int w, int h, PlayerColor playerColor) { + assertGl(); + + width = w; + height = h; + + //glClearColor(red, green, blue, alpha); //backgroundcolor constant 0.3 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* once the GL context is valid : */ + //GLint alpha_bits; + //glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); + //printf("#2 The framebuffer uses %d bit(s) per the alpha component\n", alpha_bits); + + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60.0f, static_cast(w) / h, 1.0f, 200.0f); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, -1.5, -5); + + Texture2D *customTexture = NULL; + switch (playerColor) { + case pcRed: + customTexture = customTextureRed; + break; + case pcBlue: + customTexture = customTextureBlue; + break; + case pcGreen: + customTexture = customTextureGreen; + break; + case pcYellow: + customTexture = customTextureYellow; + break; + case pcWhite: + customTexture = customTextureWhite; + break; + case pcCyan: + customTexture = customTextureCyan; + break; + case pcOrange: + customTexture = customTextureOrange; + break; + case pcMagenta: + customTexture = customTextureMagenta; + break; + default: + assert(false); + break; + } + meshCallbackTeamColor.setTeamTexture(customTexture); + + if (wireframe) { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + glDisable(GL_LIGHT0); + } else { + glEnable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + + assertGl(); + } + + void Renderer::renderGrid() { + if (grid) { + float i = 0; + + assertGl(); + + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + + glBegin(GL_LINES); + glColor3f(1.0f, 1.0f, 1.0f); // gridcolor constant + for (i = -10.0f; i <= 10.0f; i += 1.0f) { + glVertex3f(i, 0.0f, 10.0f); + glVertex3f(i, 0.0f, -10.0f); + } + for (i = -10.0f; i <= 10.0f; i += 1.0f) { + glVertex3f(10.f, 0.0f, i); + glVertex3f(-10.f, 0.0f, i); + } + glEnd(); + + glPopAttrib(); + + assertGl(); + } + } + + void Renderer::toggleNormals() { + normals = normals ? false : true; + } + + void Renderer::toggleWireframe() { + wireframe = wireframe ? false : true; + } + + void Renderer::toggleGrid() { + grid = grid ? false : true; + } + + void Renderer::renderTheModel(Model *model, float f) { + if (model != NULL) { + modelRenderer->begin(true, true, !wireframe, false, &meshCallbackTeamColor); + model->updateInterpolationData(f, true); + modelRenderer->render(model); + + if (normals) { + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glColor3f(1.0f, 1.0f, 1.0f); //normalscolor constant + modelRenderer->renderNormalsOnly(model); + glPopAttrib(); + } + + modelRenderer->end(); + } + } + + void Renderer::manageParticleSystem(ParticleSystem *particleSystem) { + particleManager->manage(particleSystem); + } + + void Renderer::updateParticleManager() { + particleManager->update(); + } + + bool Renderer::hasActiveParticleSystem(ParticleSystem::ParticleSystemType type) const { + return particleManager->hasActiveParticleSystem(type); + } + + void Renderer::renderParticleManager() { + glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + glDepthFunc(GL_LESS); + particleRenderer->renderManager(particleManager, modelRenderer); glPopAttrib(); } - modelRenderer->end(); + Texture2D * Renderer::getPlayerColorTexture(PlayerColor playerColor) { + Texture2D *customTexture = NULL; + switch (playerColor) { + case pcRed: + customTexture = customTextureRed; + break; + case pcBlue: + customTexture = customTextureBlue; + break; + case pcGreen: + customTexture = customTextureGreen; + break; + case pcYellow: + customTexture = customTextureYellow; + break; + case pcWhite: + customTexture = customTextureWhite; + break; + case pcCyan: + customTexture = customTextureCyan; + break; + case pcOrange: + customTexture = customTextureOrange; + break; + case pcMagenta: + customTexture = customTextureMagenta; + break; + default: + throw megaglest_runtime_error("Unknown playercolor: " + intToStr(playerColor)); + break; + } + + return customTexture; + } + + void Renderer::initTextureManager() { + textureManager->init(); + } + + void Renderer::initModelManager() { + modelManager->init(); + } + + void Renderer::end() { + //delete resources + //textureManager->end(); + particleManager->end(); + modelManager->end(); + } + + void Renderer::setBackgroundColor(float red, float green, float blue) { + this->red = red; + this->green = green; + this->blue = blue; + + glClearColor(red, green, blue, alpha); //backgroundcolor constant 0.3 + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* once the GL context is valid : */ + //GLint alpha_bits; + //glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); + //printf("#3 The framebuffer uses %d bit(s) per the alpha component\n", alpha_bits); + } + + void Renderer::setAlphaColor(float alpha) { + this->alpha = alpha; + + glClearColor(red, green, blue, alpha); //backgroundcolor constant 0.3 + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* once the GL context is valid : */ + //GLint alpha_bits; + //glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); + //printf("#3.1 The framebuffer uses %d bit(s) per the alpha component\n", alpha_bits); + } + + void Renderer::saveScreen(const string &path, std::pair *overrideSize) { + Pixmap2D *pixmapScreenShot = new Pixmap2D(width, height, 4); + //glFinish(); + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + glReadPixels(0, 0, pixmapScreenShot->getW(), pixmapScreenShot->getH(), + GL_RGBA, GL_UNSIGNED_BYTE, pixmapScreenShot->getPixels()); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + //if(overrideSize != NULL && overrideSize->first > 0 && overrideSize->second > 0) { + // pixmapScreenShot->Scale(GL_RGBA,overrideSize->first,overrideSize->second); + //} + + pixmapScreenShot->save(path); + delete pixmapScreenShot; + } + } -} - -void Renderer::manageParticleSystem(ParticleSystem *particleSystem) { - particleManager->manage(particleSystem); -} - -void Renderer::updateParticleManager() { - particleManager->update(); -} - -bool Renderer::hasActiveParticleSystem(ParticleSystem::ParticleSystemType type) const { - return particleManager->hasActiveParticleSystem(type); -} - -void Renderer::renderParticleManager() { - glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - glDepthFunc(GL_LESS); - particleRenderer->renderManager(particleManager, modelRenderer); - glPopAttrib(); -} - -Texture2D * Renderer::getPlayerColorTexture(PlayerColor playerColor) { - Texture2D *customTexture=NULL; - switch(playerColor){ - case pcRed: - customTexture= customTextureRed; - break; - case pcBlue: - customTexture= customTextureBlue; - break; - case pcGreen: - customTexture= customTextureGreen; - break; - case pcYellow: - customTexture= customTextureYellow; - break; - case pcWhite: - customTexture= customTextureWhite; - break; - case pcCyan: - customTexture= customTextureCyan; - break; - case pcOrange: - customTexture= customTextureOrange; - break; - case pcMagenta: - customTexture= customTextureMagenta; - break; - default: - throw megaglest_runtime_error("Unknown playercolor: " + intToStr(playerColor)); - break; - } - - return customTexture; -} - -void Renderer::initTextureManager() { - textureManager->init(); -} - -void Renderer::initModelManager() { - modelManager->init(); -} - -void Renderer::end() { - //delete resources - //textureManager->end(); - particleManager->end(); - modelManager->end(); -} - -void Renderer::setBackgroundColor(float red, float green, float blue) { - this->red = red; - this->green = green; - this->blue = blue; - - glClearColor(red, green, blue, alpha); //backgroundcolor constant 0.3 - //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - /* once the GL context is valid : */ - //GLint alpha_bits; - //glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); - //printf("#3 The framebuffer uses %d bit(s) per the alpha component\n", alpha_bits); -} - -void Renderer::setAlphaColor(float alpha) { - this->alpha= alpha; - - glClearColor(red, green, blue, alpha); //backgroundcolor constant 0.3 - //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - /* once the GL context is valid : */ - //GLint alpha_bits; - //glGetIntegerv(GL_ALPHA_BITS, &alpha_bits); - //printf("#3.1 The framebuffer uses %d bit(s) per the alpha component\n", alpha_bits); -} - -void Renderer::saveScreen(const string &path,std::pair *overrideSize) { - Pixmap2D *pixmapScreenShot = new Pixmap2D(width, height, 4); - //glFinish(); - - glPixelStorei(GL_PACK_ALIGNMENT, 1); - - glReadPixels(0, 0, pixmapScreenShot->getW(), pixmapScreenShot->getH(), - GL_RGBA, GL_UNSIGNED_BYTE, pixmapScreenShot->getPixels()); - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - //if(overrideSize != NULL && overrideSize->first > 0 && overrideSize->second > 0) { - // pixmapScreenShot->Scale(GL_RGBA,overrideSize->first,overrideSize->second); - //} - - pixmapScreenShot->save(path); - delete pixmapScreenShot; -} - -}}//end namespace +}//end namespace diff --git a/source/g3d_viewer/renderer.h b/source/g3d_viewer/renderer.h index f9a881461..93a60d419 100644 --- a/source/g3d_viewer/renderer.h +++ b/source/g3d_viewer/renderer.h @@ -13,8 +13,8 @@ #define _SHADER_G3DVIEWER_RENDERER_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include "model_renderer.h" @@ -45,122 +45,134 @@ using Shared::Graphics::Texture; using namespace Shared::Graphics; -namespace Shared{ namespace G3dViewer{ +namespace Shared { + namespace G3dViewer { -// =============================================== -// class MeshCallbackTeamColor -// =============================================== + // =============================================== + // class MeshCallbackTeamColor + // =============================================== -class MeshCallbackTeamColor: public MeshCallback{ -private: - const Texture *teamTexture; + class MeshCallbackTeamColor : public MeshCallback { + private: + const Texture *teamTexture; + + public: + MeshCallbackTeamColor() : MeshCallback() { + teamTexture = NULL; + } + void setTeamTexture(const Texture *teamTexture) { + this->teamTexture = teamTexture; + } + virtual void execute(const Mesh *mesh); + }; + + // =============================== + // class Renderer + // =============================== + + class Renderer : public RendererInterface { + public: + static int windowX; + static int windowY; + static int windowW; + static int windowH; + + public: + enum PlayerColor { + pcRed, + pcBlue, + pcGreen, + pcYellow, + pcWhite, + pcCyan, + pcOrange, + pcMagenta + }; + + private: + bool wireframe; + bool normals; + bool grid; + + int width; + int height; + + ModelRenderer *modelRenderer; + TextureManager *textureManager; + ParticleRenderer *particleRenderer; + + ParticleManager *particleManager; + ModelManager *modelManager; + + Texture2D *customTextureRed; + Texture2D *customTextureBlue; + Texture2D *customTextureGreen; + Texture2D *customTextureYellow; + Texture2D *customTextureWhite; + Texture2D *customTextureCyan; + Texture2D *customTextureOrange; + Texture2D *customTextureMagenta; + MeshCallbackTeamColor meshCallbackTeamColor; + + float red; + float green; + float blue; + float alpha; + + Renderer(); + void checkGlCaps(); + void checkExtension(const string &extension, const string &msg); + + public: + virtual ~Renderer(); + static Renderer *getInstance(); + + void init(); + void reset(int w, int h, PlayerColor playerColor); + void transform(float rotX, float rotY, float zoom); + void renderGrid(); + + bool getNormals() const { + return normals; + } + bool getWireframe() const { + return wireframe; + } + bool getGrid() const { + return grid; + } + + void toggleNormals(); + void toggleWireframe(); + void toggleGrid(); + + void renderTheModel(Model *model, float f); + + void manageParticleSystem(ParticleSystem *particleSystem); + void updateParticleManager(); + void renderParticleManager(); + Texture2D *getPlayerColorTexture(PlayerColor playerColor); + + Texture2D * getNewTexture2D(); + + Model *newModel(ResourceScope rs, const string &path, bool deletePixMapAfterLoad = false, std::map > > *loadedFileList = NULL, string *sourceLoader = NULL); + void endModel(ResourceScope rs, Model *model); + Texture2D *newTexture2D(ResourceScope rs) { + return getNewTexture2D(); + } + + void initTextureManager(); + void initModelManager(); + + void end(); + + void setBackgroundColor(float red, float green, float blue); + void setAlphaColor(float alpha); + void saveScreen(const string &path, std::pair *overrideSize); + bool hasActiveParticleSystem(ParticleSystem::ParticleSystemType typeName) const; + }; -public: - MeshCallbackTeamColor() : MeshCallback() { - teamTexture = NULL; } - void setTeamTexture(const Texture *teamTexture) {this->teamTexture= teamTexture;} - virtual void execute(const Mesh *mesh); -}; - -// =============================== -// class Renderer -// =============================== - -class Renderer : public RendererInterface { -public: - static int windowX; - static int windowY; - static int windowW; - static int windowH; - -public: - enum PlayerColor{ - pcRed, - pcBlue, - pcGreen, - pcYellow, - pcWhite, - pcCyan, - pcOrange, - pcMagenta - }; - -private: - bool wireframe; - bool normals; - bool grid; - - int width; - int height; - - ModelRenderer *modelRenderer; - TextureManager *textureManager; - ParticleRenderer *particleRenderer; - - ParticleManager *particleManager; - ModelManager *modelManager; - - Texture2D *customTextureRed; - Texture2D *customTextureBlue; - Texture2D *customTextureGreen; - Texture2D *customTextureYellow; - Texture2D *customTextureWhite; - Texture2D *customTextureCyan; - Texture2D *customTextureOrange; - Texture2D *customTextureMagenta; - MeshCallbackTeamColor meshCallbackTeamColor; - - float red; - float green; - float blue; - float alpha; - - Renderer(); - void checkGlCaps(); - void checkExtension(const string &extension, const string &msg); - -public: - virtual ~Renderer(); - static Renderer *getInstance(); - - void init(); - void reset(int w, int h, PlayerColor playerColor); - void transform(float rotX, float rotY, float zoom); - void renderGrid(); - - bool getNormals() const {return normals;} - bool getWireframe() const {return wireframe;} - bool getGrid() const {return grid;} - - void toggleNormals(); - void toggleWireframe(); - void toggleGrid(); - - void renderTheModel(Model *model, float f); - - void manageParticleSystem(ParticleSystem *particleSystem); - void updateParticleManager(); - void renderParticleManager(); - Texture2D *getPlayerColorTexture(PlayerColor playerColor); - - Texture2D * getNewTexture2D(); - - Model *newModel(ResourceScope rs,const string &path,bool deletePixMapAfterLoad=false,std::map > > *loadedFileList=NULL, string *sourceLoader=NULL); - void endModel(ResourceScope rs,Model *model); - Texture2D *newTexture2D(ResourceScope rs) { return getNewTexture2D(); } - - void initTextureManager(); - void initModelManager(); - - void end(); - - void setBackgroundColor(float red, float green, float blue); - void setAlphaColor(float alpha); - void saveScreen(const string &path,std::pair *overrideSize); - bool hasActiveParticleSystem(ParticleSystem::ParticleSystemType typeName) const; -}; - -}}//end namespace +}//end namespace #endif diff --git a/source/glest_game/ai/ai.cpp b/source/glest_game/ai/ai.cpp index 207dd37f3..bcacc82a3 100644 --- a/source/glest_game/ai/ai.cpp +++ b/source/glest_game/ai/ai.cpp @@ -19,2148 +19,1896 @@ #include "leak_dumper.h" using namespace - Shared::Graphics; +Shared::Graphics; using namespace - Shared::Util; +Shared::Util; namespace - Glest -{ - namespace - Game - { - - Task::Task () - { - taskClass = tcProduce; - } - -//void Task::saveGame(XmlNode *rootNode) const { -// std::map mapTagReplacements; -// XmlNode *taskNode = rootNode->addChild("Task"); -//} - -// ===================================================== -// class ProduceTask -// ===================================================== - ProduceTask::ProduceTask (): - Task () - { - taskClass = tcProduce; - unitType = NULL; - resourceType = NULL; - unitClass = ucWarrior; - } - - ProduceTask::ProduceTask (UnitClass unitClass): - Task () - { - taskClass = tcProduce; - this->unitClass = unitClass; - unitType = NULL; - resourceType = NULL; - } - - ProduceTask::ProduceTask (const UnitType * unitType): - Task () - { - taskClass = tcProduce; - this->unitType = unitType; - resourceType = NULL; - unitClass = ucWarrior; - } - - ProduceTask::ProduceTask (const ResourceType * resourceType): - Task () - { - taskClass = tcProduce; - unitType = NULL; - unitClass = ucWarrior; - this->resourceType = resourceType; - } - - string - ProduceTask::toString () const - { - string - str = "Produce "; - if (unitType != NULL) - { - str += unitType->getName (false); - } - return - str; - } - - void - ProduceTask::saveGame (XmlNode * rootNode) const - { - std::map < - string, - string > - mapTagReplacements; - XmlNode * - taskNode = rootNode->addChild ("Task"); - taskNode-> - addAttribute ("taskClass", intToStr (taskClass), mapTagReplacements); - XmlNode * - produceTaskNode = taskNode->addChild ("ProduceTask"); - -// UnitClass unitClass; - produceTaskNode-> - addAttribute ("unitClass", intToStr (unitClass), mapTagReplacements); -// const UnitType *unitType; - if (unitType != NULL) - { - produceTaskNode->addAttribute ("unitType", - unitType->getName (false), - mapTagReplacements); - } -// const ResourceType *resourceType; - if (resourceType != NULL) - { - produceTaskNode->addAttribute ("resourceType", - resourceType->getName (false), - mapTagReplacements); - } - } - - ProduceTask * - ProduceTask::loadGame (const XmlNode * rootNode, Faction * faction) - { - const XmlNode * - produceTaskNode = rootNode->getChild ("ProduceTask"); - - ProduceTask * - newTask = new ProduceTask (); - // UnitClass unitClass; - newTask->unitClass = - static_cast < UnitClass > - (produceTaskNode->getAttribute ("unitClass")->getIntValue ()); - // const UnitType *unitType; - if (produceTaskNode->hasAttribute ("unitType")) - { - string - unitTypeName = - produceTaskNode->getAttribute ("unitType")->getValue (); - newTask->unitType = faction->getType ()->getUnitType (unitTypeName); - } - // const ResourceType *resourceType; - if (produceTaskNode->hasAttribute ("resourceType")) - { - string - resourceTypeName = - produceTaskNode->getAttribute ("resourceType")->getValue (); - newTask->resourceType = - faction->getTechTree ()->getResourceType (resourceTypeName); - } - - return newTask; - } - -// ===================================================== -// class BuildTask -// ===================================================== - BuildTask::BuildTask () - { - taskClass = tcBuild; - this->unitType = NULL; - resourceType = NULL; - forcePos = false; - } - - BuildTask::BuildTask (const UnitType * unitType) - { - taskClass = tcBuild; - this->unitType = unitType; - resourceType = NULL; - forcePos = false; - } - - BuildTask::BuildTask (const ResourceType * resourceType) - { - taskClass = tcBuild; - unitType = NULL; - this->resourceType = resourceType; - forcePos = false; - } - - BuildTask::BuildTask (const UnitType * unitType, const Vec2i & pos) - { - taskClass = tcBuild; - this->unitType = unitType; - resourceType = NULL; - forcePos = true; - this->pos = pos; - } - - string - BuildTask::toString () const - { - string - str = "Build "; - if (unitType != NULL) - { - str += unitType->getName (false); - } - return - str; - } - - void - BuildTask::saveGame (XmlNode * rootNode) const - { - std::map < - string, - string > - mapTagReplacements; - XmlNode * - taskNode = rootNode->addChild ("Task"); - taskNode-> - addAttribute ("taskClass", intToStr (taskClass), mapTagReplacements); - XmlNode * - buildTaskNode = taskNode->addChild ("BuildTask"); - -// const UnitType *unitType; - if (unitType != NULL) - { - buildTaskNode->addAttribute ("unitType", unitType->getName (false), - mapTagReplacements); - } -// const ResourceType *resourceType; - if (resourceType != NULL) - { - buildTaskNode->addAttribute ("resourceType", - resourceType->getName (), - mapTagReplacements); - } -// bool forcePos; - buildTaskNode->addAttribute ("forcePos", intToStr (forcePos), - mapTagReplacements); -// Vec2i pos; - buildTaskNode->addAttribute ("pos", pos.getString (), - mapTagReplacements); - } - - BuildTask * - BuildTask::loadGame (const XmlNode * rootNode, Faction * faction) - { - const XmlNode * - buildTaskNode = rootNode->getChild ("BuildTask"); - - BuildTask * - newTask = new BuildTask (); - if (buildTaskNode->hasAttribute ("unitType")) - { - string - unitTypeName = - buildTaskNode->getAttribute ("unitType")->getValue (); - newTask->unitType = faction->getType ()->getUnitType (unitTypeName); - } - if (buildTaskNode->hasAttribute ("resourceType")) - { - string - resourceTypeName = - buildTaskNode->getAttribute ("resourceType")->getValue (); - newTask->resourceType = - faction->getTechTree ()->getResourceType (resourceTypeName); - } - - newTask->forcePos = - buildTaskNode->getAttribute ("forcePos")->getIntValue () != 0; - newTask->pos = - Vec2i::strToVec2 (buildTaskNode->getAttribute ("pos")->getValue ()); - - return newTask; - } - -// ===================================================== -// class UpgradeTask -// ===================================================== - UpgradeTask::UpgradeTask () - { - taskClass = tcUpgrade; - this->upgradeType = NULL; - } - - UpgradeTask::UpgradeTask (const UpgradeType * upgradeType) - { - taskClass = tcUpgrade; - this->upgradeType = upgradeType; - } - - string - UpgradeTask::toString () const - { - string - str = "Build "; - if (upgradeType != NULL) - { - str += upgradeType->getName (); - } - return - str; - } - - void - UpgradeTask::saveGame (XmlNode * rootNode) const - { - std::map < - string, - string > - mapTagReplacements; - XmlNode * - taskNode = rootNode->addChild ("Task"); - taskNode-> - addAttribute ("taskClass", intToStr (taskClass), mapTagReplacements); - XmlNode * - upgradeTaskNode = taskNode->addChild ("UpgradeTask"); - - if (upgradeType != NULL) - { - //upgradeType->saveGame(upgradeTaskNode); - upgradeTaskNode->addAttribute ("upgradeType", - upgradeType->getName (), - mapTagReplacements); - } - } - - UpgradeTask * - UpgradeTask::loadGame (const XmlNode * rootNode, Faction * faction) - { - const XmlNode * - upgradeTaskNode = rootNode->getChild ("UpgradeTask"); - - UpgradeTask * - newTask = new UpgradeTask (); - if (upgradeTaskNode->hasAttribute ("upgradeType")) - { - string - upgradeTypeName = - upgradeTaskNode->getAttribute ("upgradeType")->getValue (); - newTask->upgradeType = - faction->getType ()->getUpgradeType (upgradeTypeName); - } - return newTask; - } - -// ===================================================== -// class Ai -// ===================================================== - - void - Ai::init (AiInterface * aiInterface, int useStartLocation) - { - this->aiInterface = aiInterface; - - Faction * - faction = this->aiInterface->getMyFaction (); - if (faction->getAIBehaviorStaticOverideValue (aibsvcMaxBuildRadius) != - INT_MAX) - { - maxBuildRadius = - faction->getAIBehaviorStaticOverideValue (aibsvcMaxBuildRadius); - //printf("Discovered overriden static value for AI, maxBuildRadius = %d\n",maxBuildRadius); - } - if (faction->getAIBehaviorStaticOverideValue (aibsvcMinMinWarriors) != - INT_MAX) - { - minMinWarriors = - faction->getAIBehaviorStaticOverideValue (aibsvcMinMinWarriors); - //printf("Discovered overriden static value for AI, minMinWarriors = %d\n",minMinWarriors); - } - if (faction-> - getAIBehaviorStaticOverideValue (aibsvcMinMinWarriorsExpandCpuEasy) - != INT_MAX) - { - minMinWarriorsExpandCpuEasy = - faction-> - getAIBehaviorStaticOverideValue - (aibsvcMinMinWarriorsExpandCpuEasy); - //printf("Discovered overriden static value for AI, minMinWarriorsExpandCpuEasy = %d\n",minMinWarriorsExpandCpuEasy); - } - if (faction-> - getAIBehaviorStaticOverideValue (aibsvcMinMinWarriorsExpandCpuZeta) - != INT_MAX) - { - minMinWarriorsExpandCpuZeta = - faction-> - getAIBehaviorStaticOverideValue - (aibsvcMinMinWarriorsExpandCpuZeta); - //printf("Discovered overriden static value for AI, minMinWarriorsExpandCpuZeta = %d\n",minMinWarriorsExpandCpuZeta); - } - if (faction-> - getAIBehaviorStaticOverideValue (aibsvcMinMinWarriorsExpandCpuUltra) - != INT_MAX) - { - minMinWarriorsExpandCpuUltra = - faction-> - getAIBehaviorStaticOverideValue - (aibsvcMinMinWarriorsExpandCpuUltra); - //printf("Discovered overriden static value for AI, minMinWarriorsExpandCpuUltra = %d\n",minMinWarriorsExpandCpuUltra); - } - if (faction-> - getAIBehaviorStaticOverideValue - (aibsvcMinMinWarriorsExpandCpuNormal) != INT_MAX) - { - minMinWarriorsExpandCpuNormal = - faction-> - getAIBehaviorStaticOverideValue - (aibsvcMinMinWarriorsExpandCpuNormal); - //printf("Discovered overriden static value for AI, minMinWarriorsExpandCpuNormal = %d\n",minMinWarriorsExpandCpuNormal); - } - if (faction->getAIBehaviorStaticOverideValue (aibsvcMaxMinWarriors) != - INT_MAX) - { - maxMinWarriors = - faction->getAIBehaviorStaticOverideValue (aibsvcMaxMinWarriors); - //printf("Discovered overriden static value for AI, maxMinWarriors = %d\n",maxMinWarriors); - } - if (faction->getAIBehaviorStaticOverideValue (aibsvcMaxExpansions) != - INT_MAX) - { - maxExpansions = - faction->getAIBehaviorStaticOverideValue (aibsvcMaxExpansions); - //printf("Discovered overriden static value for AI, maxExpansions = %d\n",maxExpansions); - } - if (faction->getAIBehaviorStaticOverideValue (aibsvcVillageRadius) != - INT_MAX) - { - villageRadius = - faction->getAIBehaviorStaticOverideValue (aibsvcVillageRadius); - //printf("Discovered overriden static value for AI, villageRadius = %d\n",villageRadius); - } - if (faction-> - getAIBehaviorStaticOverideValue (aibsvcScoutResourceRange) != - INT_MAX) - { - scoutResourceRange = - faction-> - getAIBehaviorStaticOverideValue (aibsvcScoutResourceRange); - //printf("Discovered overriden static value for AI, scoutResourceRange = %d\n",scoutResourceRange); - } - if (faction-> - getAIBehaviorStaticOverideValue (aibsvcMinWorkerAttackersHarvesting) - != INT_MAX) - { - minWorkerAttackersHarvesting = - faction-> - getAIBehaviorStaticOverideValue - (aibsvcMinWorkerAttackersHarvesting); - //printf("Discovered overriden static value for AI, scoutResourceRange = %d\n",scoutResourceRange); - } - if (faction->getAIBehaviorStaticOverideValue (aibsvcMinBuildSpacing) != - INT_MAX) - { - minBuildSpacing = - faction->getAIBehaviorStaticOverideValue (aibsvcMinBuildSpacing); - //printf("Discovered overriden static value for AI, scoutResourceRange = %d\n",scoutResourceRange); - } - - if (useStartLocation == -1) - { - startLoc = - random.randRange (0, aiInterface->getMapMaxPlayers () - 1); - } - else - { - startLoc = useStartLocation; - } - minWarriors = minMinWarriors; - randomMinWarriorsReached = false; - //add ai rules - aiRules.clear (); - aiRules.push_back (new AiRuleWorkerHarvest (this)); - aiRules.push_back (new AiRuleRefreshHarvester (this)); - aiRules.push_back (new AiRuleScoutPatrol (this)); - aiRules.push_back (new AiRuleUnBlock (this)); - aiRules.push_back (new AiRuleReturnBase (this)); - aiRules.push_back (new AiRuleMassiveAttack (this)); - aiRules.push_back (new AiRuleAddTasks (this)); - aiRules.push_back (new AiRuleProduceResourceProducer (this)); - aiRules.push_back (new AiRuleBuildOneFarm (this)); - aiRules.push_back (new AiRuleProduce (this)); - aiRules.push_back (new AiRuleBuild (this)); - aiRules.push_back (new AiRuleUpgrade (this)); - aiRules.push_back (new AiRuleExpand (this)); - aiRules.push_back (new AiRuleRepair (this)); - aiRules.push_back (new AiRuleRepair (this)); - } - - Ai::~Ai () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] deleting AI aiInterface [%p]\n", - __FILE__, __FUNCTION__, __LINE__, - aiInterface); - deleteValues (tasks.begin (), tasks.end ()); - tasks.clear (); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] deleting AI aiInterface [%p]\n", - __FILE__, __FUNCTION__, __LINE__, - aiInterface); - - deleteValues (aiRules.begin (), aiRules.end ()); - aiRules.clear (); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] deleting AI aiInterface [%p]\n", - __FILE__, __FUNCTION__, __LINE__, - aiInterface); - - aiInterface = NULL; - } - - RandomGen * - Ai::getRandom () - { -// if(Thread::isCurrentThreadMainThread() == false) { -// throw megaglest_runtime_error("Invalid access to AI random from outside main thread current id = " + -// intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId())); -// } - return &random; - } - - void - Ai::update () - { - - Chrono - chrono; - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled) - chrono.start (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [START]\n", - __FILE__, __FUNCTION__, __LINE__, - chrono.getMillis ()); - - if (aiInterface->getMyFaction ()->getFirstSwitchTeamVote () != NULL) - { - const SwitchTeamVote * - vote = aiInterface->getMyFaction ()->getFirstSwitchTeamVote (); - aiInterface->getMyFaction ()-> - setCurrentSwitchTeamVoteFactionIndex (vote->factionIndex); - - factionSwitchTeamRequestCount[vote->factionIndex]++; - int - factionSwitchTeamRequestCountCurrent = - factionSwitchTeamRequestCount[vote->factionIndex]; - - //int allowJoinTeam = random.randRange(0, 100); - //srand(time(NULL) + aiInterface->getMyFaction()->getIndex()); - Chrono - seed (true); - srand ((unsigned int) seed.getCurTicks () + - aiInterface->getMyFaction ()->getIndex ()); - - int - allowJoinTeam = rand () % 100; - - SwitchTeamVote * - voteResult = - aiInterface->getMyFaction ()->getSwitchTeamVote (vote-> - factionIndex); - voteResult->voted = true; - voteResult->allowSwitchTeam = false; - - const GameSettings * - settings = aiInterface->getWorld ()->getGameSettings (); - - // If AI player already lost game they cannot vote - if (aiInterface->getWorld ()-> - factionLostGame (aiInterface->getFactionIndex ()) == true) - { - voteResult->allowSwitchTeam = true; - } - else - { - // Can only ask the AI player 2 times max per game - if (factionSwitchTeamRequestCountCurrent <= 2) - { - // x% chance the AI will answer yes - if (settings->getAiAcceptSwitchTeamPercentChance () >= 100) - { - voteResult->allowSwitchTeam = true; - } - else if (settings->getAiAcceptSwitchTeamPercentChance () <= - 0) - { - voteResult->allowSwitchTeam = false; - } - else - { - voteResult->allowSwitchTeam = - (allowJoinTeam >= - (100 - - settings->getAiAcceptSwitchTeamPercentChance ())); - } - } - } - - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "AI for faction# %d voted %s [%d] CountCurrent [%d] PercentChance [%d]", - aiInterface->getMyFaction ()->getIndex (), - (voteResult->allowSwitchTeam ? "Yes" : "No"), - allowJoinTeam, factionSwitchTeamRequestCountCurrent, - settings->getAiAcceptSwitchTeamPercentChance ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] %s\n", __FILE__, - __FUNCTION__, __LINE__, szBuf); - - aiInterface->printLog (3, szBuf); - - aiInterface->giveCommandSwitchTeamVote (aiInterface-> - getMyFaction (), - voteResult); - } - - //process ai rules - for (unsigned int ruleIdx = 0; ruleIdx < aiRules.size (); ++ruleIdx) - { - AiRule * - rule = aiRules[ruleIdx]; - if (rule == NULL) - { - throw - megaglest_runtime_error ("rule == NULL"); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [ruleIdx = %d]\n", - __FILE__, __FUNCTION__, __LINE__, - chrono.getMillis (), ruleIdx); - // Determines wether to process AI rules. Whether a particular rule is processed, is weighted by getTestInterval(). - // Values returned by getTestInterval() are defined in ai_rule.h. - if ((aiInterface->getTimer () % - (rule->getTestInterval () * GameConstants::updateFps / - 1000)) == 0) - { - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [ruleIdx = %d, before rule->test()]\n", - __FILE__, __FUNCTION__, __LINE__, - chrono.getMillis (), ruleIdx); - - //printf("Testing AI Faction # %d RULE Name[%s]\n",aiInterface->getFactionIndex(),rule->getName().c_str()); - - // Test to see if AI can execute rule e.g. is there a worker available to for harvesting wood? - if (rule->test ()) - { - if (outputAIBehaviourToConsole ()) - printf - ("\n\nYYYYY Executing AI Faction # %d RULE Name[%s]\n\n", - aiInterface->getFactionIndex (), - rule->getName ().c_str ()); - - aiInterface->printLog (3, - intToStr (1000 * - aiInterface->getTimer () / - GameConstants::updateFps) + - ": Executing rule: " + - rule->getName () + '\n'); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [ruleIdx = %d, before rule->execute() [%s]]\n", - __FILE__, __FUNCTION__, - __LINE__, chrono.getMillis (), - ruleIdx, - rule->getName ().c_str ()); - // Execute the rule. - rule->execute (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [ruleIdx = %d, after rule->execute() [%s]]\n", - __FILE__, __FUNCTION__, - __LINE__, chrono.getMillis (), - ruleIdx, - rule->getName ().c_str ()); - } - } - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [END]\n", - __FILE__, __FUNCTION__, __LINE__, - chrono.getMillis ()); - } - - -// ==================== state requests ==================== - - int - Ai::getCountOfType (const UnitType * ut) - { - int - count = 0; - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - if (ut == aiInterface->getMyUnit (i)->getType ()) - { - count++; - } - } - return count; - } - - int - Ai::getCountOfClass (UnitClass uc, - UnitClass * additionalUnitClassToExcludeFromCount) - { - int - count = 0; - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - if (aiInterface->getMyUnit (i)->getType ()->isOfClass (uc)) - { - // Skip unit if it ALSO contains the exclusion unit class type - if (additionalUnitClassToExcludeFromCount != NULL) - { - if (aiInterface->getMyUnit (i)->getType ()-> - isOfClass (*additionalUnitClassToExcludeFromCount)) - { - continue; - } - } - ++count; - } - } - return count; - } - - float - Ai::getRatioOfClass (UnitClass uc, - UnitClass * additionalUnitClassToExcludeFromCount) - { - if (aiInterface->getMyUnitCount () == 0) - { - return 0; - } - else - { - //return static_cast(getCountOfClass(uc,additionalUnitClassToExcludeFromCount)) / aiInterface->getMyUnitCount(); - return truncateDecimal < float >(static_cast < - float - >(getCountOfClass - (uc, - additionalUnitClassToExcludeFromCount)) - / aiInterface->getMyUnitCount (), - 6); - } - } - - const ResourceType * - Ai::getNeededResource (int unitIndex) - { - int - amount = INT_MAX; - const ResourceType * - neededResource = NULL; - const TechTree * - tt = aiInterface->getTechTree (); - const Unit * - unit = aiInterface->getMyUnit (unitIndex); - - for (int i = 0; i < tt->getResourceTypeCount (); ++i) - { - const ResourceType * - rt = tt->getResourceType (i); - const Resource * - r = aiInterface->getResource (rt); - - if (rt->getClass () != rcStatic && rt->getClass () != rcConsumable) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Examining resource [%s] amount [%d] (previous amount [%d]", - rt->getName ().c_str (), r->getAmount (), amount); - aiInterface->printLog (3, szBuf); - } - - if (rt->getClass () != rcStatic && rt->getClass () != rcConsumable - && r->getAmount () < amount) - { - - // Only have up to x units going for this resource so we can focus - // on other needed resources for other units - const int - maxUnitsToHarvestResource = 5; - - vector < int > - unitsGettingResource = findUnitsHarvestingResourceType (rt); - if ((int) unitsGettingResource.size () <= - maxUnitsToHarvestResource) - { - // Now MAKE SURE the unit has a harvest command for this resource - // AND that the resource is within eye-sight to avoid units - // standing around doing nothing. - const HarvestCommandType * - hct = - unit->getType ()->getFirstHarvestCommand (rt, - unit-> - getFaction ()); - Vec2i - resPos; - if (hct != NULL - && aiInterface->getNearestSightedResource (rt, - aiInterface-> - getHomeLocation - (), resPos, - false)) - { - amount = r->getAmount (); - neededResource = rt; - } - } - } - } - - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Unit [%d - %s] looking for resources (not static or consumable)", - unit->getId (), unit->getType ()->getName (false).c_str ()); - aiInterface->printLog (3, szBuf); - snprintf (szBuf, 8096, "[resource type count %d] Needed resource [%s].", - tt->getResourceTypeCount (), - (neededResource != - NULL ? neededResource->getName ().c_str () : "")); - aiInterface->printLog (3, szBuf); - - return neededResource; - } - - bool - Ai::beingAttacked (Vec2i & pos, Field & field, int radius) - { - const Unit * - enemy = aiInterface->getFirstOnSightEnemyUnit (pos, field, radius); - return (enemy != NULL); - } - - bool - Ai::isStableBase () - { - UnitClass - ucWorkerType = ucWorker; - if (getCountOfClass (ucWarrior, &ucWorkerType) > minWarriors) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Base is stable [minWarriors = %d found = %d]", - minWarriors, ucWorkerType); - aiInterface->printLog (4, szBuf); - - return true; - } - else - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Base is NOT stable [minWarriors = %d found = %d]", - minWarriors, ucWorkerType); - aiInterface->printLog (4, szBuf); - - return false; - } - } - - bool - Ai::findAbleUnit (int *unitIndex, CommandClass ability, bool idleOnly) - { - vector < int > - units; - - *unitIndex = -1; - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - const Unit * - unit = aiInterface->getMyUnit (i); - if (unit->getType ()->isCommandable () - && unit->getType ()->hasCommandClass (ability)) - { - if (!idleOnly || !unit->anyCommand () - || unit->getCurrCommand ()->getCommandType ()-> - getClass () == ccStop) - { - units.push_back (i); - } - } - } - - if (units.empty ()) - { - return false; - } - else - { - *unitIndex = units[random.randRange (0, (int) units.size () - 1)]; - return true; - } - } - - vector < int > - Ai::findUnitsHarvestingResourceType (const ResourceType * rt) - { - vector < int > - units; - - Map * - map = aiInterface->getMap (); - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - const Unit * - unit = aiInterface->getMyUnit (i); - if (unit->getType ()->isCommandable ()) - { - if (unit->getType ()->hasCommandClass (ccHarvest)) - { - if (unit->anyCommand () - && unit->getCurrCommand ()->getCommandType ()-> - getClass () == ccHarvest) - { - Command * - command = unit->getCurrCommand (); - const HarvestCommandType * - hct = dynamic_cast < const - HarvestCommandType * >(command->getCommandType ()); - if (hct != NULL) - { - const Vec2i - unitTargetPos = unit->getTargetPos (); - SurfaceCell * - sc = - map-> - getSurfaceCell (Map:: - toSurfCoords (unitTargetPos)); - Resource * - r = sc->getResource (); - if (r != NULL && r->getType () == rt) - { - units.push_back (i); - } - } - } - } - else if (unit->getType ()->hasCommandClass (ccProduce)) - { - if (unit->anyCommand () - && unit->getCurrCommand ()->getCommandType ()-> - getClass () == ccProduce) - { - Command * - command = unit->getCurrCommand (); - const ProduceCommandType * - pct = dynamic_cast < const - ProduceCommandType * >(command->getCommandType ()); - if (pct != NULL) - { - const UnitType * - ut = pct->getProducedUnit (); - if (ut != NULL) - { - const Resource * - r = ut->getCost (rt); - if (r != NULL) - { - if (r != NULL && r->getAmount () < 0) - { - units.push_back (i); - } - } - } - } - } - } - else if (unit->getType ()->hasCommandClass (ccBuild)) - { - if (unit->anyCommand () - && unit->getCurrCommand ()->getCommandType ()-> - getClass () == ccBuild) - { - Command * - command = unit->getCurrCommand (); - const BuildCommandType * - bct = dynamic_cast < const - BuildCommandType * >(command->getCommandType ()); - if (bct != NULL) - { - for (int j = 0; j < bct->getBuildingCount (); ++j) - { - const UnitType * - ut = bct->getBuilding (j); - if (ut != NULL) - { - const Resource * - r = ut->getCost (rt); - if (r != NULL) - { - if (r != NULL && r->getAmount () < 0) - { - units.push_back (i); - break; - } - } - } - } - } - } - } - } - } - - return units; - } - -//vector Ai::findUnitsDoingCommand(CommandClass currentCommand) { -// vector units; -// -// for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) { -// const Unit *unit= aiInterface->getMyUnit(i); -// if(unit->getType()->isCommandable() && unit->getType()->hasCommandClass(currentCommand)) { -// if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == currentCommand) { -// units.push_back(i); -// } -// } -// } -// -// return units; -//} - - bool - Ai::findAbleUnit (int *unitIndex, CommandClass ability, - CommandClass currentCommand) - { - vector < int > - units; - - *unitIndex = -1; - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - const Unit * - unit = aiInterface->getMyUnit (i); - if (unit->getType ()->isCommandable () - && unit->getType ()->hasCommandClass (ability)) - { - if (unit->anyCommand () - && unit->getCurrCommand ()->getCommandType ()-> - getClass () == currentCommand) - { - units.push_back (i); - } - } - } - - if (units.empty ()) - { - return false; - } - else - { - *unitIndex = units[random.randRange (0, (int) units.size () - 1)]; - return true; - } - } - - bool - Ai::findPosForBuilding (const UnitType * building, - const Vec2i & searchPos, Vec2i & outPos) - { - - for (int currRadius = 0; currRadius < maxBuildRadius; ++currRadius) - { - for (int i = searchPos.x - currRadius; i < searchPos.x + currRadius; - ++i) - { - for (int j = searchPos.y - currRadius; - j < searchPos.y + currRadius; ++j) - { - outPos = Vec2i (i, j); - if (aiInterface-> - isFreeCells (outPos - Vec2i (minBuildSpacing), - building->getAiBuildSize () + - minBuildSpacing * 2, fLand)) - { - int - aiBuildSizeDiff = - building->getAiBuildSize () - building->getSize (); - if (aiBuildSizeDiff > 0) - { - int - halfSize = aiBuildSizeDiff / 2; - outPos.x += halfSize; - outPos.y += halfSize; - } - return true; - } - } - } - } - - return false; - - } - - -// ==================== tasks ==================== - - void - Ai::addTask (const Task * task) - { - tasks.push_back (task); - aiInterface->printLog (2, "Task added: " + task->toString ()); - } - - void - Ai::addPriorityTask (const Task * task) - { - deleteValues (tasks.begin (), tasks.end ()); - tasks.clear (); - - tasks.push_back (task); - aiInterface->printLog (2, "Priority Task added: " + task->toString ()); - } - - bool - Ai::anyTask () - { - return !tasks.empty (); - } - - const Task * - Ai::getTask () const - { - if (tasks.empty ()) - { - return NULL; - } - else - { - return tasks.front (); - } - } - - void - Ai::removeTask (const Task * task) - { - aiInterface->printLog (2, "Task removed: " + task->toString ()); - tasks.remove (task); - delete - task; - } - - void - Ai::retryTask (const Task * task) - { - tasks.remove (task); - tasks.push_back (task); - } -// ==================== expansions ==================== - - void - Ai::addExpansion (const Vec2i & pos) - { - - //check if there is a nearby expansion - for (Positions::iterator it = expansionPositions.begin (); - it != expansionPositions.end (); ++it) - { - if ((*it).dist (pos) < villageRadius) - { - return; - } - } - - //add expansion - expansionPositions.push_front (pos); - - //remove expansion if queue is list is full - if ((int) expansionPositions.size () > maxExpansions) - { - expansionPositions.pop_back (); - } - } - - Vec2i - Ai::getRandomHomePosition () - { - - if (expansionPositions.empty () || random.randRange (0, 1) == 0) - { - return aiInterface->getHomeLocation (); - } - - return expansionPositions[random. - randRange (0, - (int) expansionPositions.size () - - 1)]; - } - -// ==================== actions ==================== - - void - Ai::sendScoutPatrol () - { - - Vec2i - pos; - int - unit; - bool - possibleTargetFound = false; - - bool - ultraResourceAttack = (aiInterface->getControlType () == ctCpuUltra - || aiInterface->getControlType () == - ctNetworkCpuUltra) - && random.randRange (0, 2) == 1; - bool - megaResourceAttack = (aiInterface->getControlType () == ctCpuZeta - || aiInterface->getControlType () == - ctNetworkCpuZeta) - && random.randRange (0, 1) == 1; - - if (megaResourceAttack || ultraResourceAttack) - { - Map * - map = aiInterface->getMap (); - - const TechTree * - tt = aiInterface->getTechTree (); - const ResourceType * - rt = tt->getResourceType (0); - int - tryCount = 0; - int - height = map->getH (); - int - width = map->getW (); - - for (int i = 0; i < tt->getResourceTypeCount (); ++i) - { - const ResourceType * - rt_ = tt->getResourceType (i); - //const Resource *r= aiInterface->getResource(rt); - - if (rt_->getClass () == rcTech) - { - rt = rt_; - break; - } - } - //printf("looking for resource %s\n",rt->getName().c_str()); - while (possibleTargetFound == false) - { - tryCount++; - if (tryCount == 4) - { - //printf("no target found\n"); - break; - } - pos = - Vec2i (random.randRange (2, width - 2), - random.randRange (2, height - 2)); - if (map->isInside (pos) - && map->isInsideSurface (map->toSurfCoords (pos))) - { - //printf("is inside map\n"); - // find first resource in this area - Vec2i - resPos; - if (aiInterface-> - isResourceInRegion (pos, rt, resPos, - scoutResourceRange)) - { - // found a possible target. - pos = resPos; - //printf("lets try the new target\n"); - possibleTargetFound = true; - break; - } - } - //else printf("is outside map\n"); - } - } - - std::vector < Vec2i > warningEnemyList = - aiInterface->getEnemyWarningPositionList (); - if ((possibleTargetFound == false) - && (warningEnemyList.empty () == false)) - { - //for(int i = (int)warningEnemyList.size() - 1; i <= 0; --i) { - //Vec2i &checkPos = warningEnemyList[i]; - Vec2i & checkPos = warningEnemyList[0]; - if (random.randRange (0, 1) == 1) - { - pos = checkPos; - possibleTargetFound = true; - warningEnemyList.clear (); - } - else - { - aiInterface->removeEnemyWarningPositionFromList (checkPos); - } - //break; - //} - } - - if (possibleTargetFound == false) - { - startLoc = (startLoc + 1) % aiInterface->getMapMaxPlayers (); - pos = aiInterface->getStartLocation (startLoc); - //printf("normal target used\n"); - } - - if (aiInterface->getHomeLocation () != pos) - { - if (findAbleUnit (&unit, ccAttack, false)) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - aiInterface->giveCommand (unit, ccAttack, pos); - aiInterface->printLog (2, - "Scout patrol sent to: " + - intToStr (pos.x) + "," + - intToStr (pos.y) + "\n"); - } - } - } - - void - Ai::massiveAttack (const Vec2i & pos, Field field, bool ultraAttack) - { - int - producerWarriorCount = 0; - int - maxProducerWarriors = random.randRange (1, 11); - int - unitCount = aiInterface->getMyUnitCount (); - int - unitGroupCommandId = -1; - - int - attackerWorkersHarvestingCount = 0; - for (int i = 0; i < unitCount; ++i) - { - bool - isWarrior = false; - bool - productionInProgress = false; - const Unit * - unit = aiInterface->getMyUnit (i); - const AttackCommandType * - act = unit->getType ()->getFirstAttackCommand (field); - - if (aiInterface->getControlType () == ctCpuZeta || - aiInterface->getControlType () == ctNetworkCpuZeta) - { - if (producerWarriorCount > maxProducerWarriors) - { - if (unit->getCommandSize () > 0 && - unit->getCurrCommand ()->getCommandType () != NULL - && (unit->getCurrCommand ()->getCommandType ()-> - getClass () == ccBuild - || unit->getCurrCommand ()->getCommandType ()-> - getClass () == ccMorph - || unit->getCurrCommand ()->getCommandType ()-> - getClass () == ccProduce)) - { - productionInProgress = true; - isWarrior = false; - producerWarriorCount++; - } - else - { - isWarrior = - !unit->getType ()->hasCommandClass (ccHarvest); - } - - } - else - { - isWarrior = !unit->getType ()->hasCommandClass (ccHarvest) - && !unit->getType ()->hasCommandClass (ccProduce); - } - } - else - { - isWarrior = !unit->getType ()->hasCommandClass (ccHarvest) - && !unit->getType ()->hasCommandClass (ccProduce); - } - - bool - alreadyAttacking = - (unit->getCurrSkill ()->getClass () == scAttack); - - bool - unitSignalledToAttack = false; - if (alreadyAttacking == false - && unit->getType ()->hasSkillClass (scAttack) - && (aiInterface->getControlType () == ctCpuUltra - || aiInterface->getControlType () == ctCpuZeta - || aiInterface->getControlType () == ctNetworkCpuUltra - || aiInterface->getControlType () == ctNetworkCpuZeta)) - { - //printf("~~~~~~~~ Unit [%s - %d] checking if unit is being attacked\n",unit->getFullName().c_str(),unit->getId()); - - std::pair < bool, Unit * >beingAttacked = - aiInterface->getWorld ()->getUnitUpdater ()-> - unitBeingAttacked (unit); - if (beingAttacked.first == true) - { - Unit * - enemy = beingAttacked.second; - const AttackCommandType * - act_forenemy = - unit->getType ()->getFirstAttackCommand (enemy-> - getCurrField ()); - - //printf("~~~~~~~~ Unit [%s - %d] attacked by enemy [%s - %d] act_forenemy [%p] enemy->getCurrField() = %d\n",unit->getFullName().c_str(),unit->getId(),enemy->getFullName().c_str(),enemy->getId(),act_forenemy,enemy->getCurrField()); - - if (act_forenemy != NULL) - { - bool - shouldAttack = true; - if (unit->getType ()->hasSkillClass (scHarvest)) - { - shouldAttack = - (attackerWorkersHarvestingCount > - minWorkerAttackersHarvesting); - if (shouldAttack == false) - { - attackerWorkersHarvestingCount++; - } - } - if (shouldAttack) - { - if (unitGroupCommandId == -1) - { - unitGroupCommandId = - aiInterface->getWorld ()-> - getNextCommandGroupId (); - } - - aiInterface->giveCommand (i, act_forenemy, - beingAttacked.second-> - getPos (), - unitGroupCommandId); - unitSignalledToAttack = true; - } - } - else - { - const AttackStoppedCommandType * - asct_forenemy = - unit->getType ()-> - getFirstAttackStoppedCommand (enemy->getCurrField ()); - //printf("~~~~~~~~ Unit [%s - %d] found enemy [%s - %d] asct_forenemy [%p] enemy->getCurrField() = %d\n",unit->getFullName().c_str(),unit->getId(),enemy->getFullName().c_str(),enemy->getId(),asct_forenemy,enemy->getCurrField()); - if (asct_forenemy != NULL) - { - bool - shouldAttack = true; - if (unit->getType ()->hasSkillClass (scHarvest)) - { - shouldAttack = - (attackerWorkersHarvestingCount > - minWorkerAttackersHarvesting); - if (shouldAttack == false) - { - attackerWorkersHarvestingCount++; - } - } - if (shouldAttack) - { -// printf("~~~~~~~~ Unit [%s - %d] WILL AttackStoppedCommand [%s - %d]\n", unit->getFullName().c_str(), -// unit->getId(), enemy->getFullName().c_str(), enemy->getId()); - - if (unitGroupCommandId == -1) - { - unitGroupCommandId = - aiInterface->getWorld ()-> - getNextCommandGroupId (); - } - - aiInterface->giveCommand (i, asct_forenemy, - beingAttacked.second-> - getCenteredPos (), - unitGroupCommandId); - unitSignalledToAttack = true; - } - } - } - } - } - if (alreadyAttacking == false && act != NULL - && (ultraAttack || isWarrior) && unitSignalledToAttack == false) - { - bool - shouldAttack = true; - if (unit->getType ()->hasSkillClass (scHarvest)) - { - shouldAttack = - (attackerWorkersHarvestingCount > - minWorkerAttackersHarvesting); - if (shouldAttack == false) - { - attackerWorkersHarvestingCount++; - } - } - - // Zeta CPU does not send ( far away ) units which are currently producing something - if (aiInterface->getControlType () == ctCpuZeta - || aiInterface->getControlType () == ctNetworkCpuZeta) - { - if (!isWarrior) - { - if (!productionInProgress) - { - shouldAttack = false; - //printf("no attack \n "); - } - } - } - if (shouldAttack) - { - if (unitGroupCommandId == -1) - { - unitGroupCommandId = - aiInterface->getWorld ()->getNextCommandGroupId (); - } - - aiInterface->giveCommand (i, act, pos, unitGroupCommandId); - } - } - } - - if (aiInterface->getControlType () == ctCpuEasy || - aiInterface->getControlType () == ctNetworkCpuEasy) - { - minWarriors += minMinWarriorsExpandCpuEasy; - } - else if (aiInterface->getControlType () == ctCpuZeta || - aiInterface->getControlType () == ctNetworkCpuZeta) - { - minWarriors += minMinWarriorsExpandCpuZeta; - if (minWarriors > maxMinWarriors - 1 || randomMinWarriorsReached) - { - randomMinWarriorsReached = true; - minWarriors = - random.randRange (maxMinWarriors - 10, maxMinWarriors * 2); - } - } - else if (minWarriors < maxMinWarriors) - { - if (aiInterface->getControlType () == ctCpuUltra || - aiInterface->getControlType () == ctNetworkCpuUltra) - { - minWarriors += minMinWarriorsExpandCpuUltra; - } - else - { - minWarriors += minMinWarriorsExpandCpuNormal; - } - } - aiInterface->printLog (2, - "Massive attack to pos: " + intToStr (pos.x) + - ", " + intToStr (pos.y) + "\n"); - } - - void - Ai::returnBase (int unitIndex) - { - Vec2i - pos; - //std::pair r(crFailUndefined,""); - //aiInterface->getFactionIndex(); - pos = Vec2i (random.randRange (-villageRadius, villageRadius), - random.randRange (-villageRadius, villageRadius)) + - getRandomHomePosition (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - //r= aiInterface->giveCommand(unitIndex, ccMove, pos); - aiInterface->giveCommand (unitIndex, ccMove, pos); - - //aiInterface->printLog(1, "Order return to base pos:" + intToStr(pos.x)+", "+intToStr(pos.y)+": "+rrToStr(r)+"\n"); - } - - void - Ai::harvest (int unitIndex) - { - const ResourceType * - rt = getNeededResource (unitIndex); - if (rt != NULL) - { - const HarvestCommandType * - hct = - aiInterface->getMyUnit (unitIndex)->getType ()-> - getFirstHarvestCommand (rt, - aiInterface->getMyUnit (unitIndex)-> - getFaction ()); - - Vec2i - resPos; - if (hct != NULL - && aiInterface->getNearestSightedResource (rt, - aiInterface-> - getHomeLocation (), - resPos, false)) - { - resPos = - resPos + Vec2i (random.randRange (-2, 2), - random.randRange (-2, 2)); - aiInterface->giveCommand (unitIndex, hct, resPos, -1); - //aiInterface->printLog(4, "Order harvest pos:" + intToStr(resPos.x)+", "+intToStr(resPos.y)+": "+rrToStr(r)+"\n"); - } - } - } - - bool - Ai::haveBlockedUnits () - { - Chrono - chrono; - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled) - chrono.start (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [START]\n", - __FILE__, __FUNCTION__, __LINE__, - chrono.getMillis ()); - - int - unitCount = aiInterface->getMyUnitCount (); - Map * - map = aiInterface->getMap (); - //If there is no close store - for (int j = 0; j < unitCount; ++j) - { - const Unit * - u = aiInterface->getMyUnit (j); - const UnitType * - ut = u->getType (); - - // If this building is a store - if (u->isAlive () && ut->isMobile () && u->getPath () != NULL - && (u->getPath ()->isBlocked () - || u->getPath ()->getBlockCount ())) - { - Vec2i - unitPos = u->getPosNotThreadSafe (); - - //printf("#1 AI found blocked unit [%d - %s]\n",u->getId(),u->getFullName().c_str()); - - int - failureCount = 0; - int - cellCount = 0; - - for (int i = -1; i <= 1; ++i) - { - for (int j = -1; j <= 1; ++j) - { - Vec2i - pos = unitPos + Vec2i (i, j); - if (map->isInside (pos) - && map->isInsideSurface (map->toSurfCoords (pos))) - { - if (pos != unitPos) - { - bool - canUnitMoveToCell = - map->aproxCanMove (u, unitPos, pos); - if (canUnitMoveToCell == false) - { - failureCount++; - } - cellCount++; - } - } - } - } - bool - unitImmediatelyBlocked = (failureCount == cellCount); - //printf("#1 unitImmediatelyBlocked = %d, failureCount = %d, cellCount = %d\n",unitImmediatelyBlocked,failureCount,cellCount); - - if (unitImmediatelyBlocked) - { - //printf("#1 AI unit IS BLOCKED [%d - %s]\n",u->getId(),u->getFullName().c_str()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [START]\n", - __FILE__, __FUNCTION__, - __LINE__, chrono.getMillis ()); - return true; - } - } - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [START]\n", - __FILE__, __FUNCTION__, __LINE__, - chrono.getMillis ()); - return false; - } - - bool - Ai::getAdjacentUnits (std::map < float, std::map < int, - const Unit * > >&signalAdjacentUnits, - const Unit * unit) - { - //printf("In getAdjacentUnits...\n"); - - bool - result = false; - Map * - map = aiInterface->getMap (); - Vec2i - unitPos = unit->getPosNotThreadSafe (); - for (int i = -1; i <= 1; ++i) - { - for (int j = -1; j <= 1; ++j) - { - Vec2i - pos = unitPos + Vec2i (i, j); - if (map->isInside (pos) - && map->isInsideSurface (map->toSurfCoords (pos))) - { - if (pos != unitPos) - { - Unit * - adjacentUnit = - map->getCell (pos)->getUnit (unit->getCurrField ()); - if (adjacentUnit != NULL - && adjacentUnit->getFactionIndex () == - unit->getFactionIndex ()) - { - if (adjacentUnit->getType ()->isMobile () - && adjacentUnit->getPath () != NULL) - { - //signalAdjacentUnits.push_back(adjacentUnit); - float - dist = unitPos.dist (adjacentUnit->getPos ()); - - std::map < float, - std::map < int, const Unit *> >::iterator - iterFind1 = signalAdjacentUnits.find (dist); - if (iterFind1 == signalAdjacentUnits.end ()) - { - signalAdjacentUnits[dist][adjacentUnit-> - getId ()] = - adjacentUnit; - - getAdjacentUnits (signalAdjacentUnits, - adjacentUnit); - result = true; - } - else - { - std::map < int, const Unit *>::iterator - iterFind2 = - iterFind1->second.find (adjacentUnit-> - getId ()); - if (iterFind2 == iterFind1->second.end ()) - { - signalAdjacentUnits[dist][adjacentUnit-> - getId ()] = - adjacentUnit; - getAdjacentUnits (signalAdjacentUnits, - adjacentUnit); - result = true; - } - } - } - } - } - } - } - } - return result; - } - - void - Ai::unblockUnits () - { - Chrono - chrono; - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled) - chrono.start (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [START]\n", - __FILE__, __FUNCTION__, __LINE__, - chrono.getMillis ()); - - int - unitCount = aiInterface->getMyUnitCount (); - Map * - map = aiInterface->getMap (); - // Find blocked units and move surrounding units out of the way - std::map < float, - std::map < int, const Unit *> > - signalAdjacentUnits; - for (int idx = 0; idx < unitCount; ++idx) - { - const Unit * - u = aiInterface->getMyUnit (idx); - const UnitType * - ut = u->getType (); - - // If this building is a store - if (u->isAlive () && ut->isMobile () && u->getPath () != NULL - && (u->getPath ()->isBlocked () - || u->getPath ()->getBlockCount ())) - { - Vec2i - unitPos = u->getPosNotThreadSafe (); - - //printf("#2 AI found blocked unit [%d - %s]\n",u->getId(),u->getFullName().c_str()); - - //int failureCount = 0; - //int cellCount = 0; - - for (int i = -1; i <= 1; ++i) - { - for (int j = -1; j <= 1; ++j) - { - Vec2i - pos = unitPos + Vec2i (i, j); - if (map->isInside (pos) - && map->isInsideSurface (map->toSurfCoords (pos))) - { - if (pos != unitPos) - { - bool - canUnitMoveToCell = - map->aproxCanMove (u, unitPos, pos); - if (canUnitMoveToCell == false) - { - //failureCount++; - getAdjacentUnits (signalAdjacentUnits, u); - } - //cellCount++; - } - } - } - } - //bool unitImmediatelyBlocked = (failureCount == cellCount); - //printf("#2 unitImmediatelyBlocked = %d, failureCount = %d, cellCount = %d, signalAdjacentUnits.size() = %d\n",unitImmediatelyBlocked,failureCount,cellCount,signalAdjacentUnits.size()); - } - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [START]\n", - __FILE__, __FUNCTION__, __LINE__, - chrono.getMillis ()); - - if (signalAdjacentUnits.empty () == false) - { - //printf("#2 AI units ARE BLOCKED about to unblock\n"); - - int - unitGroupCommandId = -1; - - for (std::map < float, std::map < int, - const Unit * > >::reverse_iterator iterMap = - signalAdjacentUnits.rbegin (); - iterMap != signalAdjacentUnits.rend (); ++iterMap) - { - - for (std::map < int, const Unit * >::iterator iterMap2 = - iterMap->second.begin (); - iterMap2 != iterMap->second.end (); ++iterMap2) - { - //int idx = iterMap2->first; - const Unit * - adjacentUnit = iterMap2->second; - if (adjacentUnit != NULL - && adjacentUnit->getType ()-> - getFirstCtOfClass (ccMove) != NULL) - { - const CommandType * - ct = - adjacentUnit->getType ()->getFirstCtOfClass (ccMove); - - for (int moveAttempt = 1; moveAttempt <= villageRadius; - ++moveAttempt) - { - Vec2i - pos = - Vec2i (random. - randRange (-villageRadius * 2, - villageRadius * 2), - random.randRange (-villageRadius * 2, - villageRadius * 2)) + - adjacentUnit->getPosNotThreadSafe (); - - bool - canUnitMoveToCell = - map->aproxCanMove (adjacentUnit, - adjacentUnit-> - getPosNotThreadSafe (), pos); - if (canUnitMoveToCell == true) - { - - if (ct != NULL) - { - if (unitGroupCommandId == -1) - { - unitGroupCommandId = - aiInterface->getWorld ()-> - getNextCommandGroupId (); - } - - //std::pair r = aiInterface->giveCommand(adjacentUnit,ct, pos, unitGroupCommandId); - aiInterface->giveCommand (adjacentUnit, ct, - pos, - unitGroupCommandId); - } - } - } - } - } - } - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [START]\n", - __FILE__, __FUNCTION__, __LINE__, - chrono.getMillis ()); - } - - bool - Ai::outputAIBehaviourToConsole () const - { - return - false; - } - - void - Ai::saveGame (XmlNode * rootNode) const - { - std::map < - string, - string > - mapTagReplacements; - XmlNode * - aiNode = rootNode->addChild ("Ai"); - -// AiInterface *aiInterface; -// AiRules aiRules; -// int startLoc; - aiNode-> - addAttribute ("startLoc", intToStr (startLoc), mapTagReplacements); -// bool randomMinWarriorsReached; - aiNode-> - addAttribute ("randomMinWarriorsReached", - intToStr (randomMinWarriorsReached), mapTagReplacements); -// Tasks tasks; - for (Tasks::const_iterator it = tasks.begin (); it != tasks.end (); - ++it) - { - (*it)->saveGame (aiNode); - } -// Positions expansionPositions; - for (Positions::const_iterator it = expansionPositions.begin (); - it != expansionPositions.end (); ++it) - { - XmlNode * - expansionPositionsNode = aiNode->addChild ("expansionPositions"); - expansionPositionsNode->addAttribute ("pos", (*it).getString (), - mapTagReplacements); - } - -// RandomGen random; - aiNode->addAttribute ("random", intToStr (random.getLastNumber ()), - mapTagReplacements); -// std::map factionSwitchTeamRequestCount; - -// int maxBuildRadius; - aiNode->addAttribute ("maxBuildRadius", intToStr (maxBuildRadius), - mapTagReplacements); -// int minMinWarriors; - aiNode->addAttribute ("minMinWarriors", intToStr (minMinWarriors), - mapTagReplacements); -// int minMinWarriorsExpandCpuEasy; - aiNode->addAttribute ("minMinWarriorsExpandCpuEasy", - intToStr (minMinWarriorsExpandCpuEasy), - mapTagReplacements); -// int minMinWarriorsExpandCpuZeta; - aiNode->addAttribute ("minMinWarriorsExpandCpuZeta", - intToStr (minMinWarriorsExpandCpuZeta), - mapTagReplacements); -// int minMinWarriorsExpandCpuUltra; - aiNode->addAttribute ("minMinWarriorsExpandCpuUltra", - intToStr (minMinWarriorsExpandCpuUltra), - mapTagReplacements); -// int minMinWarriorsExpandCpuNormal; - aiNode->addAttribute ("minMinWarriorsExpandCpuNormal", - intToStr (minMinWarriorsExpandCpuNormal), - mapTagReplacements); -// int maxMinWarriors; - aiNode->addAttribute ("maxMinWarriors", intToStr (maxMinWarriors), - mapTagReplacements); -// int maxExpansions; - aiNode->addAttribute ("maxExpansions", intToStr (maxExpansions), - mapTagReplacements); -// int villageRadius; - aiNode->addAttribute ("villageRadius", intToStr (villageRadius), - mapTagReplacements); -// int scoutResourceRange; - aiNode->addAttribute ("scoutResourceRange", - intToStr (scoutResourceRange), - mapTagReplacements); -// int minWorkerAttackersHarvesting; - aiNode->addAttribute ("minWorkerAttackersHarvesting", - intToStr (minWorkerAttackersHarvesting), - mapTagReplacements); - } - - void - Ai::loadGame (const XmlNode * rootNode, Faction * faction) - { - const XmlNode * - aiNode = rootNode->getChild ("Ai"); - - startLoc = aiNode->getAttribute ("startLoc")->getIntValue (); - randomMinWarriorsReached = - aiNode->getAttribute ("randomMinWarriorsReached")->getIntValue () != - 0; - - vector < XmlNode * >taskNodeList = aiNode->getChildList ("Task"); - for (unsigned int i = 0; i < taskNodeList.size (); ++i) - { - XmlNode * - taskNode = taskNodeList[i]; - TaskClass - taskClass = - static_cast < TaskClass > - (taskNode->getAttribute ("taskClass")->getIntValue ()); - switch (taskClass) - { - case tcProduce: - { - ProduceTask * - newTask = ProduceTask::loadGame (taskNode, faction); - tasks.push_back (newTask); - } - break; - case tcBuild: - { - BuildTask * - newTask = BuildTask::loadGame (taskNode, faction); - tasks.push_back (newTask); - } - break; - case tcUpgrade: - { - UpgradeTask * - newTask = UpgradeTask::loadGame (taskNode, faction); - tasks.push_back (newTask); - } - break; - } - } - - vector < XmlNode * >expansionPositionsNodeList = - aiNode->getChildList ("expansionPositions"); - for (unsigned int i = 0; i < expansionPositionsNodeList.size (); ++i) - { - XmlNode * - expansionPositionsNode = expansionPositionsNodeList[i]; - Vec2i - pos = - Vec2i::strToVec2 (expansionPositionsNode->getAttribute ("pos")-> - getValue ()); - expansionPositions.push_back (pos); - } - - // RandomGen random; - random.setLastNumber (aiNode->getAttribute ("random")->getIntValue ()); - // std::map factionSwitchTeamRequestCount; - - // int maxBuildRadius; - maxBuildRadius = - aiNode->getAttribute ("maxBuildRadius")->getIntValue (); - // int minMinWarriors; - minMinWarriors = - aiNode->getAttribute ("minMinWarriors")->getIntValue (); - // int minMinWarriorsExpandCpuEasy; - minMinWarriorsExpandCpuEasy = - aiNode->getAttribute ("minMinWarriorsExpandCpuEasy")->getIntValue (); - // int minMinWarriorsExpandCpZeta; - minMinWarriorsExpandCpuZeta = - aiNode->getAttribute ("minMinWarriorsExpandCpuZeta")->getIntValue (); - // int minMinWarriorsExpandCpuUltra; - minMinWarriorsExpandCpuUltra = - aiNode->getAttribute ("minMinWarriorsExpandCpuUltra")->getIntValue (); - // int minMinWarriorsExpandCpuNormal; - minMinWarriorsExpandCpuNormal = - aiNode->getAttribute ("minMinWarriorsExpandCpuNormal")-> - getIntValue (); - // int maxMinWarriors; - maxMinWarriors = - aiNode->getAttribute ("maxMinWarriors")->getIntValue (); - // int maxExpansions; - maxExpansions = aiNode->getAttribute ("maxExpansions")->getIntValue (); - // int villageRadius; - villageRadius = aiNode->getAttribute ("villageRadius")->getIntValue (); - // int scoutResourceRange; - scoutResourceRange = - aiNode->getAttribute ("scoutResourceRange")->getIntValue (); - // int minWorkerAttackersHarvesting; - minWorkerAttackersHarvesting = - aiNode->getAttribute ("minWorkerAttackersHarvesting")->getIntValue (); - } - -}} //end namespace + Glest { + namespace + Game { + + Task::Task() { + taskClass = tcProduce; + } + + //void Task::saveGame(XmlNode *rootNode) const { + // std::map mapTagReplacements; + // XmlNode *taskNode = rootNode->addChild("Task"); + //} + + // ===================================================== + // class ProduceTask + // ===================================================== + ProduceTask::ProduceTask() : + Task() { + taskClass = tcProduce; + unitType = NULL; + resourceType = NULL; + unitClass = ucWarrior; + } + + ProduceTask::ProduceTask(UnitClass unitClass) : + Task() { + taskClass = tcProduce; + this->unitClass = unitClass; + unitType = NULL; + resourceType = NULL; + } + + ProduceTask::ProduceTask(const UnitType * unitType) : + Task() { + taskClass = tcProduce; + this->unitType = unitType; + resourceType = NULL; + unitClass = ucWarrior; + } + + ProduceTask::ProduceTask(const ResourceType * resourceType) : + Task() { + taskClass = tcProduce; + unitType = NULL; + unitClass = ucWarrior; + this->resourceType = resourceType; + } + + string + ProduceTask::toString() const { + string + str = "Produce "; + if (unitType != NULL) { + str += unitType->getName(false); + } + return + str; + } + + void + ProduceTask::saveGame(XmlNode * rootNode) const { + std::map < + string, + string > + mapTagReplacements; + XmlNode * + taskNode = rootNode->addChild("Task"); + taskNode-> + addAttribute("taskClass", intToStr(taskClass), mapTagReplacements); + XmlNode * + produceTaskNode = taskNode->addChild("ProduceTask"); + + // UnitClass unitClass; + produceTaskNode-> + addAttribute("unitClass", intToStr(unitClass), mapTagReplacements); + // const UnitType *unitType; + if (unitType != NULL) { + produceTaskNode->addAttribute("unitType", + unitType->getName(false), + mapTagReplacements); + } + // const ResourceType *resourceType; + if (resourceType != NULL) { + produceTaskNode->addAttribute("resourceType", + resourceType->getName(false), + mapTagReplacements); + } + } + + ProduceTask * + ProduceTask::loadGame(const XmlNode * rootNode, Faction * faction) { + const XmlNode * + produceTaskNode = rootNode->getChild("ProduceTask"); + + ProduceTask * + newTask = new ProduceTask(); + // UnitClass unitClass; + newTask->unitClass = + static_cast + (produceTaskNode->getAttribute("unitClass")->getIntValue()); + // const UnitType *unitType; + if (produceTaskNode->hasAttribute("unitType")) { + string + unitTypeName = + produceTaskNode->getAttribute("unitType")->getValue(); + newTask->unitType = faction->getType()->getUnitType(unitTypeName); + } + // const ResourceType *resourceType; + if (produceTaskNode->hasAttribute("resourceType")) { + string + resourceTypeName = + produceTaskNode->getAttribute("resourceType")->getValue(); + newTask->resourceType = + faction->getTechTree()->getResourceType(resourceTypeName); + } + + return newTask; + } + + // ===================================================== + // class BuildTask + // ===================================================== + BuildTask::BuildTask() { + taskClass = tcBuild; + this->unitType = NULL; + resourceType = NULL; + forcePos = false; + } + + BuildTask::BuildTask(const UnitType * unitType) { + taskClass = tcBuild; + this->unitType = unitType; + resourceType = NULL; + forcePos = false; + } + + BuildTask::BuildTask(const ResourceType * resourceType) { + taskClass = tcBuild; + unitType = NULL; + this->resourceType = resourceType; + forcePos = false; + } + + BuildTask::BuildTask(const UnitType * unitType, const Vec2i & pos) { + taskClass = tcBuild; + this->unitType = unitType; + resourceType = NULL; + forcePos = true; + this->pos = pos; + } + + string + BuildTask::toString() const { + string + str = "Build "; + if (unitType != NULL) { + str += unitType->getName(false); + } + return + str; + } + + void + BuildTask::saveGame(XmlNode * rootNode) const { + std::map < + string, + string > + mapTagReplacements; + XmlNode * + taskNode = rootNode->addChild("Task"); + taskNode-> + addAttribute("taskClass", intToStr(taskClass), mapTagReplacements); + XmlNode * + buildTaskNode = taskNode->addChild("BuildTask"); + + // const UnitType *unitType; + if (unitType != NULL) { + buildTaskNode->addAttribute("unitType", unitType->getName(false), + mapTagReplacements); + } + // const ResourceType *resourceType; + if (resourceType != NULL) { + buildTaskNode->addAttribute("resourceType", + resourceType->getName(), + mapTagReplacements); + } + // bool forcePos; + buildTaskNode->addAttribute("forcePos", intToStr(forcePos), + mapTagReplacements); + // Vec2i pos; + buildTaskNode->addAttribute("pos", pos.getString(), + mapTagReplacements); + } + + BuildTask * + BuildTask::loadGame(const XmlNode * rootNode, Faction * faction) { + const XmlNode * + buildTaskNode = rootNode->getChild("BuildTask"); + + BuildTask * + newTask = new BuildTask(); + if (buildTaskNode->hasAttribute("unitType")) { + string + unitTypeName = + buildTaskNode->getAttribute("unitType")->getValue(); + newTask->unitType = faction->getType()->getUnitType(unitTypeName); + } + if (buildTaskNode->hasAttribute("resourceType")) { + string + resourceTypeName = + buildTaskNode->getAttribute("resourceType")->getValue(); + newTask->resourceType = + faction->getTechTree()->getResourceType(resourceTypeName); + } + + newTask->forcePos = + buildTaskNode->getAttribute("forcePos")->getIntValue() != 0; + newTask->pos = + Vec2i::strToVec2(buildTaskNode->getAttribute("pos")->getValue()); + + return newTask; + } + + // ===================================================== + // class UpgradeTask + // ===================================================== + UpgradeTask::UpgradeTask() { + taskClass = tcUpgrade; + this->upgradeType = NULL; + } + + UpgradeTask::UpgradeTask(const UpgradeType * upgradeType) { + taskClass = tcUpgrade; + this->upgradeType = upgradeType; + } + + string + UpgradeTask::toString() const { + string + str = "Build "; + if (upgradeType != NULL) { + str += upgradeType->getName(); + } + return + str; + } + + void + UpgradeTask::saveGame(XmlNode * rootNode) const { + std::map < + string, + string > + mapTagReplacements; + XmlNode * + taskNode = rootNode->addChild("Task"); + taskNode-> + addAttribute("taskClass", intToStr(taskClass), mapTagReplacements); + XmlNode * + upgradeTaskNode = taskNode->addChild("UpgradeTask"); + + if (upgradeType != NULL) { + //upgradeType->saveGame(upgradeTaskNode); + upgradeTaskNode->addAttribute("upgradeType", + upgradeType->getName(), + mapTagReplacements); + } + } + + UpgradeTask * + UpgradeTask::loadGame(const XmlNode * rootNode, Faction * faction) { + const XmlNode * + upgradeTaskNode = rootNode->getChild("UpgradeTask"); + + UpgradeTask * + newTask = new UpgradeTask(); + if (upgradeTaskNode->hasAttribute("upgradeType")) { + string + upgradeTypeName = + upgradeTaskNode->getAttribute("upgradeType")->getValue(); + newTask->upgradeType = + faction->getType()->getUpgradeType(upgradeTypeName); + } + return newTask; + } + + // ===================================================== + // class Ai + // ===================================================== + + void + Ai::init(AiInterface * aiInterface, int useStartLocation) { + this->aiInterface = aiInterface; + + Faction * + faction = this->aiInterface->getMyFaction(); + if (faction->getAIBehaviorStaticOverideValue(aibsvcMaxBuildRadius) != + INT_MAX) { + maxBuildRadius = + faction->getAIBehaviorStaticOverideValue(aibsvcMaxBuildRadius); + //printf("Discovered overriden static value for AI, maxBuildRadius = %d\n",maxBuildRadius); + } + if (faction->getAIBehaviorStaticOverideValue(aibsvcMinMinWarriors) != + INT_MAX) { + minMinWarriors = + faction->getAIBehaviorStaticOverideValue(aibsvcMinMinWarriors); + //printf("Discovered overriden static value for AI, minMinWarriors = %d\n",minMinWarriors); + } + if (faction-> + getAIBehaviorStaticOverideValue(aibsvcMinMinWarriorsExpandCpuEasy) + != INT_MAX) { + minMinWarriorsExpandCpuEasy = + faction-> + getAIBehaviorStaticOverideValue + (aibsvcMinMinWarriorsExpandCpuEasy); + //printf("Discovered overriden static value for AI, minMinWarriorsExpandCpuEasy = %d\n",minMinWarriorsExpandCpuEasy); + } + if (faction-> + getAIBehaviorStaticOverideValue(aibsvcMinMinWarriorsExpandCpuZeta) + != INT_MAX) { + minMinWarriorsExpandCpuZeta = + faction-> + getAIBehaviorStaticOverideValue + (aibsvcMinMinWarriorsExpandCpuZeta); + //printf("Discovered overriden static value for AI, minMinWarriorsExpandCpuZeta = %d\n",minMinWarriorsExpandCpuZeta); + } + if (faction-> + getAIBehaviorStaticOverideValue(aibsvcMinMinWarriorsExpandCpuUltra) + != INT_MAX) { + minMinWarriorsExpandCpuUltra = + faction-> + getAIBehaviorStaticOverideValue + (aibsvcMinMinWarriorsExpandCpuUltra); + //printf("Discovered overriden static value for AI, minMinWarriorsExpandCpuUltra = %d\n",minMinWarriorsExpandCpuUltra); + } + if (faction-> + getAIBehaviorStaticOverideValue + (aibsvcMinMinWarriorsExpandCpuNormal) != INT_MAX) { + minMinWarriorsExpandCpuNormal = + faction-> + getAIBehaviorStaticOverideValue + (aibsvcMinMinWarriorsExpandCpuNormal); + //printf("Discovered overriden static value for AI, minMinWarriorsExpandCpuNormal = %d\n",minMinWarriorsExpandCpuNormal); + } + if (faction->getAIBehaviorStaticOverideValue(aibsvcMaxMinWarriors) != + INT_MAX) { + maxMinWarriors = + faction->getAIBehaviorStaticOverideValue(aibsvcMaxMinWarriors); + //printf("Discovered overriden static value for AI, maxMinWarriors = %d\n",maxMinWarriors); + } + if (faction->getAIBehaviorStaticOverideValue(aibsvcMaxExpansions) != + INT_MAX) { + maxExpansions = + faction->getAIBehaviorStaticOverideValue(aibsvcMaxExpansions); + //printf("Discovered overriden static value for AI, maxExpansions = %d\n",maxExpansions); + } + if (faction->getAIBehaviorStaticOverideValue(aibsvcVillageRadius) != + INT_MAX) { + villageRadius = + faction->getAIBehaviorStaticOverideValue(aibsvcVillageRadius); + //printf("Discovered overriden static value for AI, villageRadius = %d\n",villageRadius); + } + if (faction-> + getAIBehaviorStaticOverideValue(aibsvcScoutResourceRange) != + INT_MAX) { + scoutResourceRange = + faction-> + getAIBehaviorStaticOverideValue(aibsvcScoutResourceRange); + //printf("Discovered overriden static value for AI, scoutResourceRange = %d\n",scoutResourceRange); + } + if (faction-> + getAIBehaviorStaticOverideValue(aibsvcMinWorkerAttackersHarvesting) + != INT_MAX) { + minWorkerAttackersHarvesting = + faction-> + getAIBehaviorStaticOverideValue + (aibsvcMinWorkerAttackersHarvesting); + //printf("Discovered overriden static value for AI, scoutResourceRange = %d\n",scoutResourceRange); + } + if (faction->getAIBehaviorStaticOverideValue(aibsvcMinBuildSpacing) != + INT_MAX) { + minBuildSpacing = + faction->getAIBehaviorStaticOverideValue(aibsvcMinBuildSpacing); + //printf("Discovered overriden static value for AI, scoutResourceRange = %d\n",scoutResourceRange); + } + + if (useStartLocation == -1) { + startLoc = + random.randRange(0, aiInterface->getMapMaxPlayers() - 1); + } else { + startLoc = useStartLocation; + } + minWarriors = minMinWarriors; + randomMinWarriorsReached = false; + //add ai rules + aiRules.clear(); + aiRules.push_back(new AiRuleWorkerHarvest(this)); + aiRules.push_back(new AiRuleRefreshHarvester(this)); + aiRules.push_back(new AiRuleScoutPatrol(this)); + aiRules.push_back(new AiRuleUnBlock(this)); + aiRules.push_back(new AiRuleReturnBase(this)); + aiRules.push_back(new AiRuleMassiveAttack(this)); + aiRules.push_back(new AiRuleAddTasks(this)); + aiRules.push_back(new AiRuleProduceResourceProducer(this)); + aiRules.push_back(new AiRuleBuildOneFarm(this)); + aiRules.push_back(new AiRuleProduce(this)); + aiRules.push_back(new AiRuleBuild(this)); + aiRules.push_back(new AiRuleUpgrade(this)); + aiRules.push_back(new AiRuleExpand(this)); + aiRules.push_back(new AiRuleRepair(this)); + aiRules.push_back(new AiRuleRepair(this)); + } + + Ai::~Ai() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] deleting AI aiInterface [%p]\n", + __FILE__, __FUNCTION__, __LINE__, + aiInterface); + deleteValues(tasks.begin(), tasks.end()); + tasks.clear(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] deleting AI aiInterface [%p]\n", + __FILE__, __FUNCTION__, __LINE__, + aiInterface); + + deleteValues(aiRules.begin(), aiRules.end()); + aiRules.clear(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] deleting AI aiInterface [%p]\n", + __FILE__, __FUNCTION__, __LINE__, + aiInterface); + + aiInterface = NULL; + } + + RandomGen * + Ai::getRandom() { + // if(Thread::isCurrentThreadMainThread() == false) { + // throw megaglest_runtime_error("Invalid access to AI random from outside main thread current id = " + + // intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId())); + // } + return &random; + } + + void + Ai::update() { + + Chrono + chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled) + chrono.start(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [START]\n", + __FILE__, __FUNCTION__, __LINE__, + chrono.getMillis()); + + if (aiInterface->getMyFaction()->getFirstSwitchTeamVote() != NULL) { + const SwitchTeamVote * + vote = aiInterface->getMyFaction()->getFirstSwitchTeamVote(); + aiInterface->getMyFaction()-> + setCurrentSwitchTeamVoteFactionIndex(vote->factionIndex); + + factionSwitchTeamRequestCount[vote->factionIndex]++; + int + factionSwitchTeamRequestCountCurrent = + factionSwitchTeamRequestCount[vote->factionIndex]; + + //int allowJoinTeam = random.randRange(0, 100); + //srand(time(NULL) + aiInterface->getMyFaction()->getIndex()); + Chrono + seed(true); + srand((unsigned int) seed.getCurTicks() + + aiInterface->getMyFaction()->getIndex()); + + int + allowJoinTeam = rand() % 100; + + SwitchTeamVote * + voteResult = + aiInterface->getMyFaction()->getSwitchTeamVote(vote-> + factionIndex); + voteResult->voted = true; + voteResult->allowSwitchTeam = false; + + const GameSettings * + settings = aiInterface->getWorld()->getGameSettings(); + + // If AI player already lost game they cannot vote + if (aiInterface->getWorld()-> + factionLostGame(aiInterface->getFactionIndex()) == true) { + voteResult->allowSwitchTeam = true; + } else { + // Can only ask the AI player 2 times max per game + if (factionSwitchTeamRequestCountCurrent <= 2) { + // x% chance the AI will answer yes + if (settings->getAiAcceptSwitchTeamPercentChance() >= 100) { + voteResult->allowSwitchTeam = true; + } else if (settings->getAiAcceptSwitchTeamPercentChance() <= + 0) { + voteResult->allowSwitchTeam = false; + } else { + voteResult->allowSwitchTeam = + (allowJoinTeam >= + (100 - + settings->getAiAcceptSwitchTeamPercentChance())); + } + } + } + + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "AI for faction# %d voted %s [%d] CountCurrent [%d] PercentChance [%d]", + aiInterface->getMyFaction()->getIndex(), + (voteResult->allowSwitchTeam ? "Yes" : "No"), + allowJoinTeam, factionSwitchTeamRequestCountCurrent, + settings->getAiAcceptSwitchTeamPercentChance()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] %s\n", __FILE__, + __FUNCTION__, __LINE__, szBuf); + + aiInterface->printLog(3, szBuf); + + aiInterface->giveCommandSwitchTeamVote(aiInterface-> + getMyFaction(), + voteResult); + } + + //process ai rules + for (unsigned int ruleIdx = 0; ruleIdx < aiRules.size(); ++ruleIdx) { + AiRule * + rule = aiRules[ruleIdx]; + if (rule == NULL) { + throw + megaglest_runtime_error("rule == NULL"); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [ruleIdx = %d]\n", + __FILE__, __FUNCTION__, __LINE__, + chrono.getMillis(), ruleIdx); + // Determines wether to process AI rules. Whether a particular rule is processed, is weighted by getTestInterval(). + // Values returned by getTestInterval() are defined in ai_rule.h. + if ((aiInterface->getTimer() % + (rule->getTestInterval() * GameConstants::updateFps / + 1000)) == 0) { + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [ruleIdx = %d, before rule->test()]\n", + __FILE__, __FUNCTION__, __LINE__, + chrono.getMillis(), ruleIdx); + + //printf("Testing AI Faction # %d RULE Name[%s]\n",aiInterface->getFactionIndex(),rule->getName().c_str()); + + // Test to see if AI can execute rule e.g. is there a worker available to for harvesting wood? + if (rule->test()) { + if (outputAIBehaviourToConsole()) + printf + ("\n\nYYYYY Executing AI Faction # %d RULE Name[%s]\n\n", + aiInterface->getFactionIndex(), + rule->getName().c_str()); + + aiInterface->printLog(3, + intToStr(1000 * + aiInterface->getTimer() / + GameConstants::updateFps) + + ": Executing rule: " + + rule->getName() + '\n'); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [ruleIdx = %d, before rule->execute() [%s]]\n", + __FILE__, __FUNCTION__, + __LINE__, chrono.getMillis(), + ruleIdx, + rule->getName().c_str()); + // Execute the rule. + rule->execute(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [ruleIdx = %d, after rule->execute() [%s]]\n", + __FILE__, __FUNCTION__, + __LINE__, chrono.getMillis(), + ruleIdx, + rule->getName().c_str()); + } + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [END]\n", + __FILE__, __FUNCTION__, __LINE__, + chrono.getMillis()); + } + + + // ==================== state requests ==================== + + int + Ai::getCountOfType(const UnitType * ut) { + int + count = 0; + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + if (ut == aiInterface->getMyUnit(i)->getType()) { + count++; + } + } + return count; + } + + int + Ai::getCountOfClass(UnitClass uc, + UnitClass * additionalUnitClassToExcludeFromCount) { + int + count = 0; + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + if (aiInterface->getMyUnit(i)->getType()->isOfClass(uc)) { + // Skip unit if it ALSO contains the exclusion unit class type + if (additionalUnitClassToExcludeFromCount != NULL) { + if (aiInterface->getMyUnit(i)->getType()-> + isOfClass(*additionalUnitClassToExcludeFromCount)) { + continue; + } + } + ++count; + } + } + return count; + } + + float + Ai::getRatioOfClass(UnitClass uc, + UnitClass * additionalUnitClassToExcludeFromCount) { + if (aiInterface->getMyUnitCount() == 0) { + return 0; + } else { + //return static_cast(getCountOfClass(uc,additionalUnitClassToExcludeFromCount)) / aiInterface->getMyUnitCount(); + return truncateDecimal < float >(static_cast < + float + >(getCountOfClass + (uc, + additionalUnitClassToExcludeFromCount)) + / aiInterface->getMyUnitCount(), + 6); + } + } + + const ResourceType * + Ai::getNeededResource(int unitIndex) { + int + amount = INT_MAX; + const ResourceType * + neededResource = NULL; + const TechTree * + tt = aiInterface->getTechTree(); + const Unit * + unit = aiInterface->getMyUnit(unitIndex); + + for (int i = 0; i < tt->getResourceTypeCount(); ++i) { + const ResourceType * + rt = tt->getResourceType(i); + const Resource * + r = aiInterface->getResource(rt); + + if (rt->getClass() != rcStatic && rt->getClass() != rcConsumable) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Examining resource [%s] amount [%d] (previous amount [%d]", + rt->getName().c_str(), r->getAmount(), amount); + aiInterface->printLog(3, szBuf); + } + + if (rt->getClass() != rcStatic && rt->getClass() != rcConsumable + && r->getAmount() < amount) { + + // Only have up to x units going for this resource so we can focus + // on other needed resources for other units + const int + maxUnitsToHarvestResource = 5; + + vector < int > + unitsGettingResource = findUnitsHarvestingResourceType(rt); + if ((int) unitsGettingResource.size() <= + maxUnitsToHarvestResource) { + // Now MAKE SURE the unit has a harvest command for this resource + // AND that the resource is within eye-sight to avoid units + // standing around doing nothing. + const HarvestCommandType * + hct = + unit->getType()->getFirstHarvestCommand(rt, + unit-> + getFaction()); + Vec2i + resPos; + if (hct != NULL + && aiInterface->getNearestSightedResource(rt, + aiInterface-> + getHomeLocation + (), resPos, + false)) { + amount = r->getAmount(); + neededResource = rt; + } + } + } + } + + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Unit [%d - %s] looking for resources (not static or consumable)", + unit->getId(), unit->getType()->getName(false).c_str()); + aiInterface->printLog(3, szBuf); + snprintf(szBuf, 8096, "[resource type count %d] Needed resource [%s].", + tt->getResourceTypeCount(), + (neededResource != + NULL ? neededResource->getName().c_str() : "")); + aiInterface->printLog(3, szBuf); + + return neededResource; + } + + bool + Ai::beingAttacked(Vec2i & pos, Field & field, int radius) { + const Unit * + enemy = aiInterface->getFirstOnSightEnemyUnit(pos, field, radius); + return (enemy != NULL); + } + + bool + Ai::isStableBase() { + UnitClass + ucWorkerType = ucWorker; + if (getCountOfClass(ucWarrior, &ucWorkerType) > minWarriors) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Base is stable [minWarriors = %d found = %d]", + minWarriors, ucWorkerType); + aiInterface->printLog(4, szBuf); + + return true; + } else { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Base is NOT stable [minWarriors = %d found = %d]", + minWarriors, ucWorkerType); + aiInterface->printLog(4, szBuf); + + return false; + } + } + + bool + Ai::findAbleUnit(int *unitIndex, CommandClass ability, bool idleOnly) { + vector < int > + units; + + *unitIndex = -1; + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + const Unit * + unit = aiInterface->getMyUnit(i); + if (unit->getType()->isCommandable() + && unit->getType()->hasCommandClass(ability)) { + if (!idleOnly || !unit->anyCommand() + || unit->getCurrCommand()->getCommandType()-> + getClass() == ccStop) { + units.push_back(i); + } + } + } + + if (units.empty()) { + return false; + } else { + *unitIndex = units[random.randRange(0, (int) units.size() - 1)]; + return true; + } + } + + vector < int > + Ai::findUnitsHarvestingResourceType(const ResourceType * rt) { + vector < int > + units; + + Map * + map = aiInterface->getMap(); + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + const Unit * + unit = aiInterface->getMyUnit(i); + if (unit->getType()->isCommandable()) { + if (unit->getType()->hasCommandClass(ccHarvest)) { + if (unit->anyCommand() + && unit->getCurrCommand()->getCommandType()-> + getClass() == ccHarvest) { + Command * + command = unit->getCurrCommand(); + const HarvestCommandType * + hct = dynamic_cast (command->getCommandType()); + if (hct != NULL) { + const Vec2i + unitTargetPos = unit->getTargetPos(); + SurfaceCell * + sc = + map-> + getSurfaceCell(Map:: + toSurfCoords(unitTargetPos)); + Resource * + r = sc->getResource(); + if (r != NULL && r->getType() == rt) { + units.push_back(i); + } + } + } + } else if (unit->getType()->hasCommandClass(ccProduce)) { + if (unit->anyCommand() + && unit->getCurrCommand()->getCommandType()-> + getClass() == ccProduce) { + Command * + command = unit->getCurrCommand(); + const ProduceCommandType * + pct = dynamic_cast (command->getCommandType()); + if (pct != NULL) { + const UnitType * + ut = pct->getProducedUnit(); + if (ut != NULL) { + const Resource * + r = ut->getCost(rt); + if (r != NULL) { + if (r != NULL && r->getAmount() < 0) { + units.push_back(i); + } + } + } + } + } + } else if (unit->getType()->hasCommandClass(ccBuild)) { + if (unit->anyCommand() + && unit->getCurrCommand()->getCommandType()-> + getClass() == ccBuild) { + Command * + command = unit->getCurrCommand(); + const BuildCommandType * + bct = dynamic_cast (command->getCommandType()); + if (bct != NULL) { + for (int j = 0; j < bct->getBuildingCount(); ++j) { + const UnitType * + ut = bct->getBuilding(j); + if (ut != NULL) { + const Resource * + r = ut->getCost(rt); + if (r != NULL) { + if (r != NULL && r->getAmount() < 0) { + units.push_back(i); + break; + } + } + } + } + } + } + } + } + } + + return units; + } + + //vector Ai::findUnitsDoingCommand(CommandClass currentCommand) { + // vector units; + // + // for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + // const Unit *unit= aiInterface->getMyUnit(i); + // if(unit->getType()->isCommandable() && unit->getType()->hasCommandClass(currentCommand)) { + // if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == currentCommand) { + // units.push_back(i); + // } + // } + // } + // + // return units; + //} + + bool + Ai::findAbleUnit(int *unitIndex, CommandClass ability, + CommandClass currentCommand) { + vector < int > + units; + + *unitIndex = -1; + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + const Unit * + unit = aiInterface->getMyUnit(i); + if (unit->getType()->isCommandable() + && unit->getType()->hasCommandClass(ability)) { + if (unit->anyCommand() + && unit->getCurrCommand()->getCommandType()-> + getClass() == currentCommand) { + units.push_back(i); + } + } + } + + if (units.empty()) { + return false; + } else { + *unitIndex = units[random.randRange(0, (int) units.size() - 1)]; + return true; + } + } + + bool + Ai::findPosForBuilding(const UnitType * building, + const Vec2i & searchPos, Vec2i & outPos) { + + for (int currRadius = 0; currRadius < maxBuildRadius; ++currRadius) { + for (int i = searchPos.x - currRadius; i < searchPos.x + currRadius; + ++i) { + for (int j = searchPos.y - currRadius; + j < searchPos.y + currRadius; ++j) { + outPos = Vec2i(i, j); + if (aiInterface-> + isFreeCells(outPos - Vec2i(minBuildSpacing), + building->getAiBuildSize() + + minBuildSpacing * 2, fLand)) { + int + aiBuildSizeDiff = + building->getAiBuildSize() - building->getSize(); + if (aiBuildSizeDiff > 0) { + int + halfSize = aiBuildSizeDiff / 2; + outPos.x += halfSize; + outPos.y += halfSize; + } + return true; + } + } + } + } + + return false; + + } + + + // ==================== tasks ==================== + + void + Ai::addTask(const Task * task) { + tasks.push_back(task); + aiInterface->printLog(2, "Task added: " + task->toString()); + } + + void + Ai::addPriorityTask(const Task * task) { + deleteValues(tasks.begin(), tasks.end()); + tasks.clear(); + + tasks.push_back(task); + aiInterface->printLog(2, "Priority Task added: " + task->toString()); + } + + bool + Ai::anyTask() { + return !tasks.empty(); + } + + const Task * + Ai::getTask() const { + if (tasks.empty()) { + return NULL; + } else { + return tasks.front(); + } + } + + void + Ai::removeTask(const Task * task) { + aiInterface->printLog(2, "Task removed: " + task->toString()); + tasks.remove(task); + delete + task; + } + + void + Ai::retryTask(const Task * task) { + tasks.remove(task); + tasks.push_back(task); + } + // ==================== expansions ==================== + + void + Ai::addExpansion(const Vec2i & pos) { + + //check if there is a nearby expansion + for (Positions::iterator it = expansionPositions.begin(); + it != expansionPositions.end(); ++it) { + if ((*it).dist(pos) < villageRadius) { + return; + } + } + + //add expansion + expansionPositions.push_front(pos); + + //remove expansion if queue is list is full + if ((int) expansionPositions.size() > maxExpansions) { + expansionPositions.pop_back(); + } + } + + Vec2i + Ai::getRandomHomePosition() { + + if (expansionPositions.empty() || random.randRange(0, 1) == 0) { + return aiInterface->getHomeLocation(); + } + + return expansionPositions[random. + randRange(0, + (int) expansionPositions.size() - + 1)]; + } + + // ==================== actions ==================== + + void + Ai::sendScoutPatrol() { + + Vec2i + pos; + int + unit; + bool + possibleTargetFound = false; + + bool + ultraResourceAttack = (aiInterface->getControlType() == ctCpuUltra + || aiInterface->getControlType() == + ctNetworkCpuUltra) + && random.randRange(0, 2) == 1; + bool + megaResourceAttack = (aiInterface->getControlType() == ctCpuZeta + || aiInterface->getControlType() == + ctNetworkCpuZeta) + && random.randRange(0, 1) == 1; + + if (megaResourceAttack || ultraResourceAttack) { + Map * + map = aiInterface->getMap(); + + const TechTree * + tt = aiInterface->getTechTree(); + const ResourceType * + rt = tt->getResourceType(0); + int + tryCount = 0; + int + height = map->getH(); + int + width = map->getW(); + + for (int i = 0; i < tt->getResourceTypeCount(); ++i) { + const ResourceType * + rt_ = tt->getResourceType(i); + //const Resource *r= aiInterface->getResource(rt); + + if (rt_->getClass() == rcTech) { + rt = rt_; + break; + } + } + //printf("looking for resource %s\n",rt->getName().c_str()); + while (possibleTargetFound == false) { + tryCount++; + if (tryCount == 4) { + //printf("no target found\n"); + break; + } + pos = + Vec2i(random.randRange(2, width - 2), + random.randRange(2, height - 2)); + if (map->isInside(pos) + && map->isInsideSurface(map->toSurfCoords(pos))) { + //printf("is inside map\n"); + // find first resource in this area + Vec2i + resPos; + if (aiInterface-> + isResourceInRegion(pos, rt, resPos, + scoutResourceRange)) { + // found a possible target. + pos = resPos; + //printf("lets try the new target\n"); + possibleTargetFound = true; + break; + } + } + //else printf("is outside map\n"); + } + } + + std::vector < Vec2i > warningEnemyList = + aiInterface->getEnemyWarningPositionList(); + if ((possibleTargetFound == false) + && (warningEnemyList.empty() == false)) { + //for(int i = (int)warningEnemyList.size() - 1; i <= 0; --i) { + //Vec2i &checkPos = warningEnemyList[i]; + Vec2i & checkPos = warningEnemyList[0]; + if (random.randRange(0, 1) == 1) { + pos = checkPos; + possibleTargetFound = true; + warningEnemyList.clear(); + } else { + aiInterface->removeEnemyWarningPositionFromList(checkPos); + } + //break; + //} + } + + if (possibleTargetFound == false) { + startLoc = (startLoc + 1) % aiInterface->getMapMaxPlayers(); + pos = aiInterface->getStartLocation(startLoc); + //printf("normal target used\n"); + } + + if (aiInterface->getHomeLocation() != pos) { + if (findAbleUnit(&unit, ccAttack, false)) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + aiInterface->giveCommand(unit, ccAttack, pos); + aiInterface->printLog(2, + "Scout patrol sent to: " + + intToStr(pos.x) + "," + + intToStr(pos.y) + "\n"); + } + } + } + + void + Ai::massiveAttack(const Vec2i & pos, Field field, bool ultraAttack) { + int + producerWarriorCount = 0; + int + maxProducerWarriors = random.randRange(1, 11); + int + unitCount = aiInterface->getMyUnitCount(); + int + unitGroupCommandId = -1; + + int + attackerWorkersHarvestingCount = 0; + for (int i = 0; i < unitCount; ++i) { + bool + isWarrior = false; + bool + productionInProgress = false; + const Unit * + unit = aiInterface->getMyUnit(i); + const AttackCommandType * + act = unit->getType()->getFirstAttackCommand(field); + + if (aiInterface->getControlType() == ctCpuZeta || + aiInterface->getControlType() == ctNetworkCpuZeta) { + if (producerWarriorCount > maxProducerWarriors) { + if (unit->getCommandSize() > 0 && + unit->getCurrCommand()->getCommandType() != NULL + && (unit->getCurrCommand()->getCommandType()-> + getClass() == ccBuild + || unit->getCurrCommand()->getCommandType()-> + getClass() == ccMorph + || unit->getCurrCommand()->getCommandType()-> + getClass() == ccProduce)) { + productionInProgress = true; + isWarrior = false; + producerWarriorCount++; + } else { + isWarrior = + !unit->getType()->hasCommandClass(ccHarvest); + } + + } else { + isWarrior = !unit->getType()->hasCommandClass(ccHarvest) + && !unit->getType()->hasCommandClass(ccProduce); + } + } else { + isWarrior = !unit->getType()->hasCommandClass(ccHarvest) + && !unit->getType()->hasCommandClass(ccProduce); + } + + bool + alreadyAttacking = + (unit->getCurrSkill()->getClass() == scAttack); + + bool + unitSignalledToAttack = false; + if (alreadyAttacking == false + && unit->getType()->hasSkillClass(scAttack) + && (aiInterface->getControlType() == ctCpuUltra + || aiInterface->getControlType() == ctCpuZeta + || aiInterface->getControlType() == ctNetworkCpuUltra + || aiInterface->getControlType() == ctNetworkCpuZeta)) { + //printf("~~~~~~~~ Unit [%s - %d] checking if unit is being attacked\n",unit->getFullName().c_str(),unit->getId()); + + std::pair < bool, Unit * >beingAttacked = + aiInterface->getWorld()->getUnitUpdater()-> + unitBeingAttacked(unit); + if (beingAttacked.first == true) { + Unit * + enemy = beingAttacked.second; + const AttackCommandType * + act_forenemy = + unit->getType()->getFirstAttackCommand(enemy-> + getCurrField()); + + //printf("~~~~~~~~ Unit [%s - %d] attacked by enemy [%s - %d] act_forenemy [%p] enemy->getCurrField() = %d\n",unit->getFullName().c_str(),unit->getId(),enemy->getFullName().c_str(),enemy->getId(),act_forenemy,enemy->getCurrField()); + + if (act_forenemy != NULL) { + bool + shouldAttack = true; + if (unit->getType()->hasSkillClass(scHarvest)) { + shouldAttack = + (attackerWorkersHarvestingCount > + minWorkerAttackersHarvesting); + if (shouldAttack == false) { + attackerWorkersHarvestingCount++; + } + } + if (shouldAttack) { + if (unitGroupCommandId == -1) { + unitGroupCommandId = + aiInterface->getWorld()-> + getNextCommandGroupId(); + } + + aiInterface->giveCommand(i, act_forenemy, + beingAttacked.second-> + getPos(), + unitGroupCommandId); + unitSignalledToAttack = true; + } + } else { + const AttackStoppedCommandType * + asct_forenemy = + unit->getType()-> + getFirstAttackStoppedCommand(enemy->getCurrField()); + //printf("~~~~~~~~ Unit [%s - %d] found enemy [%s - %d] asct_forenemy [%p] enemy->getCurrField() = %d\n",unit->getFullName().c_str(),unit->getId(),enemy->getFullName().c_str(),enemy->getId(),asct_forenemy,enemy->getCurrField()); + if (asct_forenemy != NULL) { + bool + shouldAttack = true; + if (unit->getType()->hasSkillClass(scHarvest)) { + shouldAttack = + (attackerWorkersHarvestingCount > + minWorkerAttackersHarvesting); + if (shouldAttack == false) { + attackerWorkersHarvestingCount++; + } + } + if (shouldAttack) { + // printf("~~~~~~~~ Unit [%s - %d] WILL AttackStoppedCommand [%s - %d]\n", unit->getFullName().c_str(), + // unit->getId(), enemy->getFullName().c_str(), enemy->getId()); + + if (unitGroupCommandId == -1) { + unitGroupCommandId = + aiInterface->getWorld()-> + getNextCommandGroupId(); + } + + aiInterface->giveCommand(i, asct_forenemy, + beingAttacked.second-> + getCenteredPos(), + unitGroupCommandId); + unitSignalledToAttack = true; + } + } + } + } + } + if (alreadyAttacking == false && act != NULL + && (ultraAttack || isWarrior) && unitSignalledToAttack == false) { + bool + shouldAttack = true; + if (unit->getType()->hasSkillClass(scHarvest)) { + shouldAttack = + (attackerWorkersHarvestingCount > + minWorkerAttackersHarvesting); + if (shouldAttack == false) { + attackerWorkersHarvestingCount++; + } + } + + // Zeta CPU does not send ( far away ) units which are currently producing something + if (aiInterface->getControlType() == ctCpuZeta + || aiInterface->getControlType() == ctNetworkCpuZeta) { + if (!isWarrior) { + if (!productionInProgress) { + shouldAttack = false; + //printf("no attack \n "); + } + } + } + if (shouldAttack) { + if (unitGroupCommandId == -1) { + unitGroupCommandId = + aiInterface->getWorld()->getNextCommandGroupId(); + } + + aiInterface->giveCommand(i, act, pos, unitGroupCommandId); + } + } + } + + if (aiInterface->getControlType() == ctCpuEasy || + aiInterface->getControlType() == ctNetworkCpuEasy) { + minWarriors += minMinWarriorsExpandCpuEasy; + } else if (aiInterface->getControlType() == ctCpuZeta || + aiInterface->getControlType() == ctNetworkCpuZeta) { + minWarriors += minMinWarriorsExpandCpuZeta; + if (minWarriors > maxMinWarriors - 1 || randomMinWarriorsReached) { + randomMinWarriorsReached = true; + minWarriors = + random.randRange(maxMinWarriors - 10, maxMinWarriors * 2); + } + } else if (minWarriors < maxMinWarriors) { + if (aiInterface->getControlType() == ctCpuUltra || + aiInterface->getControlType() == ctNetworkCpuUltra) { + minWarriors += minMinWarriorsExpandCpuUltra; + } else { + minWarriors += minMinWarriorsExpandCpuNormal; + } + } + aiInterface->printLog(2, + "Massive attack to pos: " + intToStr(pos.x) + + ", " + intToStr(pos.y) + "\n"); + } + + void + Ai::returnBase(int unitIndex) { + Vec2i + pos; + //std::pair r(crFailUndefined,""); + //aiInterface->getFactionIndex(); + pos = Vec2i(random.randRange(-villageRadius, villageRadius), + random.randRange(-villageRadius, villageRadius)) + + getRandomHomePosition(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + //r= aiInterface->giveCommand(unitIndex, ccMove, pos); + aiInterface->giveCommand(unitIndex, ccMove, pos); + + //aiInterface->printLog(1, "Order return to base pos:" + intToStr(pos.x)+", "+intToStr(pos.y)+": "+rrToStr(r)+"\n"); + } + + void + Ai::harvest(int unitIndex) { + const ResourceType * + rt = getNeededResource(unitIndex); + if (rt != NULL) { + const HarvestCommandType * + hct = + aiInterface->getMyUnit(unitIndex)->getType()-> + getFirstHarvestCommand(rt, + aiInterface->getMyUnit(unitIndex)-> + getFaction()); + + Vec2i + resPos; + if (hct != NULL + && aiInterface->getNearestSightedResource(rt, + aiInterface-> + getHomeLocation(), + resPos, false)) { + resPos = + resPos + Vec2i(random.randRange(-2, 2), + random.randRange(-2, 2)); + aiInterface->giveCommand(unitIndex, hct, resPos, -1); + //aiInterface->printLog(4, "Order harvest pos:" + intToStr(resPos.x)+", "+intToStr(resPos.y)+": "+rrToStr(r)+"\n"); + } + } + } + + bool + Ai::haveBlockedUnits() { + Chrono + chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled) + chrono.start(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [START]\n", + __FILE__, __FUNCTION__, __LINE__, + chrono.getMillis()); + + int + unitCount = aiInterface->getMyUnitCount(); + Map * + map = aiInterface->getMap(); + //If there is no close store + for (int j = 0; j < unitCount; ++j) { + const Unit * + u = aiInterface->getMyUnit(j); + const UnitType * + ut = u->getType(); + + // If this building is a store + if (u->isAlive() && ut->isMobile() && u->getPath() != NULL + && (u->getPath()->isBlocked() + || u->getPath()->getBlockCount())) { + Vec2i + unitPos = u->getPosNotThreadSafe(); + + //printf("#1 AI found blocked unit [%d - %s]\n",u->getId(),u->getFullName().c_str()); + + int + failureCount = 0; + int + cellCount = 0; + + for (int i = -1; i <= 1; ++i) { + for (int j = -1; j <= 1; ++j) { + Vec2i + pos = unitPos + Vec2i(i, j); + if (map->isInside(pos) + && map->isInsideSurface(map->toSurfCoords(pos))) { + if (pos != unitPos) { + bool + canUnitMoveToCell = + map->aproxCanMove(u, unitPos, pos); + if (canUnitMoveToCell == false) { + failureCount++; + } + cellCount++; + } + } + } + } + bool + unitImmediatelyBlocked = (failureCount == cellCount); + //printf("#1 unitImmediatelyBlocked = %d, failureCount = %d, cellCount = %d\n",unitImmediatelyBlocked,failureCount,cellCount); + + if (unitImmediatelyBlocked) { + //printf("#1 AI unit IS BLOCKED [%d - %s]\n",u->getId(),u->getFullName().c_str()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [START]\n", + __FILE__, __FUNCTION__, + __LINE__, chrono.getMillis()); + return true; + } + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [START]\n", + __FILE__, __FUNCTION__, __LINE__, + chrono.getMillis()); + return false; + } + + bool + Ai::getAdjacentUnits(std::map < float, std::map < int, + const Unit * > >&signalAdjacentUnits, + const Unit * unit) { + //printf("In getAdjacentUnits...\n"); + + bool + result = false; + Map * + map = aiInterface->getMap(); + Vec2i + unitPos = unit->getPosNotThreadSafe(); + for (int i = -1; i <= 1; ++i) { + for (int j = -1; j <= 1; ++j) { + Vec2i + pos = unitPos + Vec2i(i, j); + if (map->isInside(pos) + && map->isInsideSurface(map->toSurfCoords(pos))) { + if (pos != unitPos) { + Unit * + adjacentUnit = + map->getCell(pos)->getUnit(unit->getCurrField()); + if (adjacentUnit != NULL + && adjacentUnit->getFactionIndex() == + unit->getFactionIndex()) { + if (adjacentUnit->getType()->isMobile() + && adjacentUnit->getPath() != NULL) { + //signalAdjacentUnits.push_back(adjacentUnit); + float + dist = unitPos.dist(adjacentUnit->getPos()); + + std::map < float, + std::map < int, const Unit *> >::iterator + iterFind1 = signalAdjacentUnits.find(dist); + if (iterFind1 == signalAdjacentUnits.end()) { + signalAdjacentUnits[dist][adjacentUnit-> + getId()] = + adjacentUnit; + + getAdjacentUnits(signalAdjacentUnits, + adjacentUnit); + result = true; + } else { + std::map < int, const Unit *>::iterator + iterFind2 = + iterFind1->second.find(adjacentUnit-> + getId()); + if (iterFind2 == iterFind1->second.end()) { + signalAdjacentUnits[dist][adjacentUnit-> + getId()] = + adjacentUnit; + getAdjacentUnits(signalAdjacentUnits, + adjacentUnit); + result = true; + } + } + } + } + } + } + } + } + return result; + } + + void + Ai::unblockUnits() { + Chrono + chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled) + chrono.start(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [START]\n", + __FILE__, __FUNCTION__, __LINE__, + chrono.getMillis()); + + int + unitCount = aiInterface->getMyUnitCount(); + Map * + map = aiInterface->getMap(); + // Find blocked units and move surrounding units out of the way + std::map < float, + std::map < int, const Unit *> > + signalAdjacentUnits; + for (int idx = 0; idx < unitCount; ++idx) { + const Unit * + u = aiInterface->getMyUnit(idx); + const UnitType * + ut = u->getType(); + + // If this building is a store + if (u->isAlive() && ut->isMobile() && u->getPath() != NULL + && (u->getPath()->isBlocked() + || u->getPath()->getBlockCount())) { + Vec2i + unitPos = u->getPosNotThreadSafe(); + + //printf("#2 AI found blocked unit [%d - %s]\n",u->getId(),u->getFullName().c_str()); + + //int failureCount = 0; + //int cellCount = 0; + + for (int i = -1; i <= 1; ++i) { + for (int j = -1; j <= 1; ++j) { + Vec2i + pos = unitPos + Vec2i(i, j); + if (map->isInside(pos) + && map->isInsideSurface(map->toSurfCoords(pos))) { + if (pos != unitPos) { + bool + canUnitMoveToCell = + map->aproxCanMove(u, unitPos, pos); + if (canUnitMoveToCell == false) { + //failureCount++; + getAdjacentUnits(signalAdjacentUnits, u); + } + //cellCount++; + } + } + } + } + //bool unitImmediatelyBlocked = (failureCount == cellCount); + //printf("#2 unitImmediatelyBlocked = %d, failureCount = %d, cellCount = %d, signalAdjacentUnits.size() = %d\n",unitImmediatelyBlocked,failureCount,cellCount,signalAdjacentUnits.size()); + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [START]\n", + __FILE__, __FUNCTION__, __LINE__, + chrono.getMillis()); + + if (signalAdjacentUnits.empty() == false) { + //printf("#2 AI units ARE BLOCKED about to unblock\n"); + + int + unitGroupCommandId = -1; + + for (std::map < float, std::map < int, + const Unit * > >::reverse_iterator iterMap = + signalAdjacentUnits.rbegin(); + iterMap != signalAdjacentUnits.rend(); ++iterMap) { + + for (std::map < int, const Unit * >::iterator iterMap2 = + iterMap->second.begin(); + iterMap2 != iterMap->second.end(); ++iterMap2) { + //int idx = iterMap2->first; + const Unit * + adjacentUnit = iterMap2->second; + if (adjacentUnit != NULL + && adjacentUnit->getType()-> + getFirstCtOfClass(ccMove) != NULL) { + const CommandType * + ct = + adjacentUnit->getType()->getFirstCtOfClass(ccMove); + + for (int moveAttempt = 1; moveAttempt <= villageRadius; + ++moveAttempt) { + Vec2i + pos = + Vec2i(random. + randRange(-villageRadius * 2, + villageRadius * 2), + random.randRange(-villageRadius * 2, + villageRadius * 2)) + + adjacentUnit->getPosNotThreadSafe(); + + bool + canUnitMoveToCell = + map->aproxCanMove(adjacentUnit, + adjacentUnit-> + getPosNotThreadSafe(), pos); + if (canUnitMoveToCell == true) { + + if (ct != NULL) { + if (unitGroupCommandId == -1) { + unitGroupCommandId = + aiInterface->getWorld()-> + getNextCommandGroupId(); + } + + //std::pair r = aiInterface->giveCommand(adjacentUnit,ct, pos, unitGroupCommandId); + aiInterface->giveCommand(adjacentUnit, ct, + pos, + unitGroupCommandId); + } + } + } + } + } + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [START]\n", + __FILE__, __FUNCTION__, __LINE__, + chrono.getMillis()); + } + + bool + Ai::outputAIBehaviourToConsole() const { + return + false; + } + + void + Ai::saveGame(XmlNode * rootNode) const { + std::map < + string, + string > + mapTagReplacements; + XmlNode * + aiNode = rootNode->addChild("Ai"); + + // AiInterface *aiInterface; + // AiRules aiRules; + // int startLoc; + aiNode-> + addAttribute("startLoc", intToStr(startLoc), mapTagReplacements); + // bool randomMinWarriorsReached; + aiNode-> + addAttribute("randomMinWarriorsReached", + intToStr(randomMinWarriorsReached), mapTagReplacements); + // Tasks tasks; + for (Tasks::const_iterator it = tasks.begin(); it != tasks.end(); + ++it) { + (*it)->saveGame(aiNode); + } + // Positions expansionPositions; + for (Positions::const_iterator it = expansionPositions.begin(); + it != expansionPositions.end(); ++it) { + XmlNode * + expansionPositionsNode = aiNode->addChild("expansionPositions"); + expansionPositionsNode->addAttribute("pos", (*it).getString(), + mapTagReplacements); + } + + // RandomGen random; + aiNode->addAttribute("random", intToStr(random.getLastNumber()), + mapTagReplacements); + // std::map factionSwitchTeamRequestCount; + + // int maxBuildRadius; + aiNode->addAttribute("maxBuildRadius", intToStr(maxBuildRadius), + mapTagReplacements); + // int minMinWarriors; + aiNode->addAttribute("minMinWarriors", intToStr(minMinWarriors), + mapTagReplacements); + // int minMinWarriorsExpandCpuEasy; + aiNode->addAttribute("minMinWarriorsExpandCpuEasy", + intToStr(minMinWarriorsExpandCpuEasy), + mapTagReplacements); + // int minMinWarriorsExpandCpuZeta; + aiNode->addAttribute("minMinWarriorsExpandCpuZeta", + intToStr(minMinWarriorsExpandCpuZeta), + mapTagReplacements); + // int minMinWarriorsExpandCpuUltra; + aiNode->addAttribute("minMinWarriorsExpandCpuUltra", + intToStr(minMinWarriorsExpandCpuUltra), + mapTagReplacements); + // int minMinWarriorsExpandCpuNormal; + aiNode->addAttribute("minMinWarriorsExpandCpuNormal", + intToStr(minMinWarriorsExpandCpuNormal), + mapTagReplacements); + // int maxMinWarriors; + aiNode->addAttribute("maxMinWarriors", intToStr(maxMinWarriors), + mapTagReplacements); + // int maxExpansions; + aiNode->addAttribute("maxExpansions", intToStr(maxExpansions), + mapTagReplacements); + // int villageRadius; + aiNode->addAttribute("villageRadius", intToStr(villageRadius), + mapTagReplacements); + // int scoutResourceRange; + aiNode->addAttribute("scoutResourceRange", + intToStr(scoutResourceRange), + mapTagReplacements); + // int minWorkerAttackersHarvesting; + aiNode->addAttribute("minWorkerAttackersHarvesting", + intToStr(minWorkerAttackersHarvesting), + mapTagReplacements); + } + + void + Ai::loadGame(const XmlNode * rootNode, Faction * faction) { + const XmlNode * + aiNode = rootNode->getChild("Ai"); + + startLoc = aiNode->getAttribute("startLoc")->getIntValue(); + randomMinWarriorsReached = + aiNode->getAttribute("randomMinWarriorsReached")->getIntValue() != + 0; + + vector < XmlNode * >taskNodeList = aiNode->getChildList("Task"); + for (unsigned int i = 0; i < taskNodeList.size(); ++i) { + XmlNode * + taskNode = taskNodeList[i]; + TaskClass + taskClass = + static_cast + (taskNode->getAttribute("taskClass")->getIntValue()); + switch (taskClass) { + case tcProduce: + { + ProduceTask * + newTask = ProduceTask::loadGame(taskNode, faction); + tasks.push_back(newTask); + } + break; + case tcBuild: + { + BuildTask * + newTask = BuildTask::loadGame(taskNode, faction); + tasks.push_back(newTask); + } + break; + case tcUpgrade: + { + UpgradeTask * + newTask = UpgradeTask::loadGame(taskNode, faction); + tasks.push_back(newTask); + } + break; + } + } + + vector < XmlNode * >expansionPositionsNodeList = + aiNode->getChildList("expansionPositions"); + for (unsigned int i = 0; i < expansionPositionsNodeList.size(); ++i) { + XmlNode * + expansionPositionsNode = expansionPositionsNodeList[i]; + Vec2i + pos = + Vec2i::strToVec2(expansionPositionsNode->getAttribute("pos")-> + getValue()); + expansionPositions.push_back(pos); + } + + // RandomGen random; + random.setLastNumber(aiNode->getAttribute("random")->getIntValue()); + // std::map factionSwitchTeamRequestCount; + + // int maxBuildRadius; + maxBuildRadius = + aiNode->getAttribute("maxBuildRadius")->getIntValue(); + // int minMinWarriors; + minMinWarriors = + aiNode->getAttribute("minMinWarriors")->getIntValue(); + // int minMinWarriorsExpandCpuEasy; + minMinWarriorsExpandCpuEasy = + aiNode->getAttribute("minMinWarriorsExpandCpuEasy")->getIntValue(); + // int minMinWarriorsExpandCpZeta; + minMinWarriorsExpandCpuZeta = + aiNode->getAttribute("minMinWarriorsExpandCpuZeta")->getIntValue(); + // int minMinWarriorsExpandCpuUltra; + minMinWarriorsExpandCpuUltra = + aiNode->getAttribute("minMinWarriorsExpandCpuUltra")->getIntValue(); + // int minMinWarriorsExpandCpuNormal; + minMinWarriorsExpandCpuNormal = + aiNode->getAttribute("minMinWarriorsExpandCpuNormal")-> + getIntValue(); + // int maxMinWarriors; + maxMinWarriors = + aiNode->getAttribute("maxMinWarriors")->getIntValue(); + // int maxExpansions; + maxExpansions = aiNode->getAttribute("maxExpansions")->getIntValue(); + // int villageRadius; + villageRadius = aiNode->getAttribute("villageRadius")->getIntValue(); + // int scoutResourceRange; + scoutResourceRange = + aiNode->getAttribute("scoutResourceRange")->getIntValue(); + // int minWorkerAttackersHarvesting; + minWorkerAttackersHarvesting = + aiNode->getAttribute("minWorkerAttackersHarvesting")->getIntValue(); + } + + } +} //end namespace diff --git a/source/glest_game/ai/ai.h b/source/glest_game/ai/ai.h index 49b560286..110d209ca 100644 --- a/source/glest_game/ai/ai.h +++ b/source/glest_game/ai/ai.h @@ -22,410 +22,389 @@ # include "leak_dumper.h" using - std::deque; +std::deque; using - std::vector; +std::vector; using - std::list; +std::list; using - Shared::Util::RandomGen; +Shared::Util::RandomGen; namespace - Glest -{ - namespace - Game - { + Glest { + namespace + Game { - class - AiInterface; - class - AiRule; + class + AiInterface; + class + AiRule; -// ===================================================== -// class Task -// -/// An action that has to be performed by the IA -// ===================================================== + // ===================================================== + // class Task + // + /// An action that has to be performed by the IA + // ===================================================== - enum TaskClass - { - tcProduce, - tcBuild, - tcUpgrade - }; + enum TaskClass { + tcProduce, + tcBuild, + tcUpgrade + }; - class - Task - { - protected: - TaskClass - taskClass; + class + Task { + protected: + TaskClass + taskClass; - public: - Task (); - virtual ~ - Task () - { - } - TaskClass - getClass () const - { - return - taskClass; - } - virtual string - toString () const = 0; + public: + Task(); + virtual ~ + Task() { + } + TaskClass + getClass() const { + return + taskClass; + } + virtual string + toString() const = 0; - virtual void - saveGame (XmlNode * rootNode) const = 0; - }; + virtual void + saveGame(XmlNode * rootNode) const = 0; + }; -// ==================== ProduceTask ==================== + // ==================== ProduceTask ==================== - class - ProduceTask: - public - Task - { - private: - UnitClass - unitClass; - const UnitType * - unitType; - const ResourceType * - resourceType; + class + ProduceTask : + public + Task { + private: + UnitClass + unitClass; + const UnitType * + unitType; + const ResourceType * + resourceType; - ProduceTask (); - public: - explicit - ProduceTask (UnitClass unitClass); - explicit - ProduceTask (const UnitType * unitType); - explicit - ProduceTask (const ResourceType * resourceType); + ProduceTask(); + public: + explicit + ProduceTask(UnitClass unitClass); + explicit + ProduceTask(const UnitType * unitType); + explicit + ProduceTask(const ResourceType * resourceType); - UnitClass - getUnitClass () const - { - return - unitClass; - } - const UnitType * - getUnitType () const - { - return - unitType; - } - const ResourceType * - getResourceType () const - { - return - resourceType; - } - virtual string - toString () const; + UnitClass + getUnitClass() const { + return + unitClass; + } + const UnitType * + getUnitType() const { + return + unitType; + } + const ResourceType * + getResourceType() const { + return + resourceType; + } + virtual string + toString() const; - virtual void - saveGame (XmlNode * rootNode) const; - static ProduceTask * - loadGame (const XmlNode * rootNode, Faction * faction); - }; + virtual void + saveGame(XmlNode * rootNode) const; + static ProduceTask * + loadGame(const XmlNode * rootNode, Faction * faction); + }; -// ==================== BuildTask ==================== + // ==================== BuildTask ==================== - class - BuildTask: - public - Task - { - private: - const UnitType * - unitType; - const ResourceType * - resourceType; - bool - forcePos; - Vec2i - pos; + class + BuildTask : + public + Task { + private: + const UnitType * + unitType; + const ResourceType * + resourceType; + bool + forcePos; + Vec2i + pos; - BuildTask (); + BuildTask(); - public: - explicit - BuildTask (const UnitType * unitType); - explicit - BuildTask (const ResourceType * resourceType); - BuildTask (const UnitType * unitType, const Vec2i & pos); + public: + explicit + BuildTask(const UnitType * unitType); + explicit + BuildTask(const ResourceType * resourceType); + BuildTask(const UnitType * unitType, const Vec2i & pos); - const UnitType * - getUnitType () const - { - return - unitType; - } - const ResourceType * - getResourceType () const - { - return - resourceType; - } - bool - getForcePos () const - { - return - forcePos; - } - Vec2i - getPos () const - { - return - pos; - } - virtual string - toString () const; + const UnitType * + getUnitType() const { + return + unitType; + } + const ResourceType * + getResourceType() const { + return + resourceType; + } + bool + getForcePos() const { + return + forcePos; + } + Vec2i + getPos() const { + return + pos; + } + virtual string + toString() const; - virtual void - saveGame (XmlNode * rootNode) const; - static BuildTask * - loadGame (const XmlNode * rootNode, Faction * faction); - }; + virtual void + saveGame(XmlNode * rootNode) const; + static BuildTask * + loadGame(const XmlNode * rootNode, Faction * faction); + }; -// ==================== UpgradeTask ==================== + // ==================== UpgradeTask ==================== - class - UpgradeTask: - public - Task - { - private: - const UpgradeType * - upgradeType; + class + UpgradeTask : + public + Task { + private: + const UpgradeType * + upgradeType; - UpgradeTask (); - public: - explicit - UpgradeTask (const UpgradeType * upgradeType); - const UpgradeType * - getUpgradeType () const - { - return - upgradeType; - } - virtual string - toString () const; + UpgradeTask(); + public: + explicit + UpgradeTask(const UpgradeType * upgradeType); + const UpgradeType * + getUpgradeType() const { + return + upgradeType; + } + virtual string + toString() const; - virtual void - saveGame (XmlNode * rootNode) const; - static UpgradeTask * - loadGame (const XmlNode * rootNode, Faction * faction); - }; + virtual void + saveGame(XmlNode * rootNode) const; + static UpgradeTask * + loadGame(const XmlNode * rootNode, Faction * faction); + }; -// =============================== -// class AI -// -/// Main AI class -// =============================== + // =============================== + // class AI + // + /// Main AI class + // =============================== - class - Ai - { - private: - int - maxBuildRadius; + class + Ai { + private: + int + maxBuildRadius; - int - minMinWarriors; - int - minMinWarriorsExpandCpuEasy; - int - minMinWarriorsExpandCpuZeta; - int - minMinWarriorsExpandCpuUltra; - int - minMinWarriorsExpandCpuNormal; - int - maxMinWarriors; + int + minMinWarriors; + int + minMinWarriorsExpandCpuEasy; + int + minMinWarriorsExpandCpuZeta; + int + minMinWarriorsExpandCpuUltra; + int + minMinWarriorsExpandCpuNormal; + int + maxMinWarriors; - int - maxExpansions; - int - villageRadius; - int - scoutResourceRange; - int - minWorkerAttackersHarvesting; - int - minBuildSpacing; + int + maxExpansions; + int + villageRadius; + int + scoutResourceRange; + int + minWorkerAttackersHarvesting; + int + minBuildSpacing; - public: - enum ResourceUsage - { - ruHarvester, - ruWarrior, - ruBuilding, - ruUpgrade - }; + public: + enum ResourceUsage { + ruHarvester, + ruWarrior, + ruBuilding, + ruUpgrade + }; - private: - typedef - vector < - AiRule * > - AiRules; - typedef - list < const Task *> - Tasks; - typedef - deque < - Vec2i > - Positions; + private: + typedef + vector < + AiRule * > + AiRules; + typedef + list < const Task *> + Tasks; + typedef + deque < + Vec2i > + Positions; - private: - AiInterface * - aiInterface; - AiRules - aiRules; - int - startLoc; - bool - randomMinWarriorsReached; - Tasks - tasks; - Positions - expansionPositions; - RandomGen - random; - std::map < int, int > - factionSwitchTeamRequestCount; - int - minWarriors; + private: + AiInterface * + aiInterface; + AiRules + aiRules; + int + startLoc; + bool + randomMinWarriorsReached; + Tasks + tasks; + Positions + expansionPositions; + RandomGen + random; + std::map < int, int > + factionSwitchTeamRequestCount; + int + minWarriors; - bool - getAdjacentUnits (std::map < float, std::map < int, - const Unit * > >&signalAdjacentUnits, - const Unit * unit); + bool + getAdjacentUnits(std::map < float, std::map < int, + const Unit * > >&signalAdjacentUnits, + const Unit * unit); - public: - Ai () - { - // Defaults that used to be static which can now be overriden - maxBuildRadius = 40; - minMinWarriors = 7; - minMinWarriorsExpandCpuEasy = 1; - minMinWarriorsExpandCpuZeta = 3; - minMinWarriorsExpandCpuUltra = 3; - minMinWarriorsExpandCpuNormal = 3; - maxMinWarriors = 20; - maxExpansions = 5; - villageRadius = 15; - scoutResourceRange = 20; - minWorkerAttackersHarvesting = 3; - minBuildSpacing = 1; + public: + Ai() { + // Defaults that used to be static which can now be overriden + maxBuildRadius = 40; + minMinWarriors = 7; + minMinWarriorsExpandCpuEasy = 1; + minMinWarriorsExpandCpuZeta = 3; + minMinWarriorsExpandCpuUltra = 3; + minMinWarriorsExpandCpuNormal = 3; + maxMinWarriors = 20; + maxExpansions = 5; + villageRadius = 15; + scoutResourceRange = 20; + minWorkerAttackersHarvesting = 3; + minBuildSpacing = 1; - aiInterface = NULL; - startLoc = -1; - randomMinWarriorsReached = false; - minWarriors = 0; - } - ~ - Ai (); + aiInterface = NULL; + startLoc = -1; + randomMinWarriorsReached = false; + minWarriors = 0; + } + ~ + Ai(); - void - init (AiInterface * aiInterface, int useStartLocation = -1); - void - update (); + void + init(AiInterface * aiInterface, int useStartLocation = -1); + void + update(); - //state requests - AiInterface * - getAiInterface () const - { - return - aiInterface; - } - RandomGen * - getRandom (); - int - getCountOfType (const UnitType * ut); + //state requests + AiInterface * + getAiInterface() const { + return + aiInterface; + } + RandomGen * + getRandom(); + int + getCountOfType(const UnitType * ut); - int - getMinWarriors () const - { - return - minWarriors; - } + int + getMinWarriors() const { + return + minWarriors; + } - int - getCountOfClass (UnitClass uc, - UnitClass * additionalUnitClassToExcludeFromCount = - NULL); - float - getRatioOfClass (UnitClass uc, - UnitClass * additionalUnitClassToExcludeFromCount = - NULL); + int + getCountOfClass(UnitClass uc, + UnitClass * additionalUnitClassToExcludeFromCount = + NULL); + float + getRatioOfClass(UnitClass uc, + UnitClass * additionalUnitClassToExcludeFromCount = + NULL); - const ResourceType * - getNeededResource (int unitIndex); - bool - isStableBase (); - bool - findPosForBuilding (const UnitType * building, const Vec2i & searchPos, - Vec2i & pos); - bool - findAbleUnit (int *unitIndex, CommandClass ability, bool idleOnly); - bool - findAbleUnit (int *unitIndex, CommandClass ability, - CommandClass currentCommand); - //vector findUnitsDoingCommand(CommandClass currentCommand); - vector < int > - findUnitsHarvestingResourceType (const ResourceType * rt); + const ResourceType * + getNeededResource(int unitIndex); + bool + isStableBase(); + bool + findPosForBuilding(const UnitType * building, const Vec2i & searchPos, + Vec2i & pos); + bool + findAbleUnit(int *unitIndex, CommandClass ability, bool idleOnly); + bool + findAbleUnit(int *unitIndex, CommandClass ability, + CommandClass currentCommand); + //vector findUnitsDoingCommand(CommandClass currentCommand); + vector < int > + findUnitsHarvestingResourceType(const ResourceType * rt); - bool - beingAttacked (Vec2i & pos, Field & field, int radius); + bool + beingAttacked(Vec2i & pos, Field & field, int radius); - //tasks - void - addTask (const Task * task); - void - addPriorityTask (const Task * task); - bool - anyTask (); - const Task * - getTask () const; - void - removeTask (const Task * task); - void - retryTask (const Task * task); + //tasks + void + addTask(const Task * task); + void + addPriorityTask(const Task * task); + bool + anyTask(); + const Task * + getTask() const; + void + removeTask(const Task * task); + void + retryTask(const Task * task); - //expansions - void - addExpansion (const Vec2i & pos); - Vec2i - getRandomHomePosition (); + //expansions + void + addExpansion(const Vec2i & pos); + Vec2i + getRandomHomePosition(); - //actions - void - sendScoutPatrol (); - void - massiveAttack (const Vec2i & pos, Field field, bool ultraAttack = - false); - void - returnBase (int unitIndex); - void - harvest (int unitIndex); - bool - haveBlockedUnits (); - void - unblockUnits (); + //actions + void + sendScoutPatrol(); + void + massiveAttack(const Vec2i & pos, Field field, bool ultraAttack = + false); + void + returnBase(int unitIndex); + void + harvest(int unitIndex); + bool + haveBlockedUnits(); + void + unblockUnits(); - bool - outputAIBehaviourToConsole () const; + bool + outputAIBehaviourToConsole() const; - void - saveGame (XmlNode * rootNode) const; - void - loadGame (const XmlNode * rootNode, Faction * faction); - }; + void + saveGame(XmlNode * rootNode) const; + void + loadGame(const XmlNode * rootNode, Faction * faction); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/ai/ai_interface.cpp b/source/glest_game/ai/ai_interface.cpp index cea7b00d2..17c62eb4c 100644 --- a/source/glest_game/ai/ai_interface.cpp +++ b/source/glest_game/ai/ai_interface.cpp @@ -35,1616 +35,1451 @@ #include "leak_dumper.h" using namespace - Shared::Util; +Shared::Util; using namespace - Shared::Graphics; +Shared::Graphics; // ===================================================== // class AiInterface // ===================================================== namespace - Glest -{ - namespace - Game - { + Glest { + namespace + Game { -// ===================================================== -// class FactionThread -// ===================================================== + // ===================================================== + // class FactionThread + // ===================================================== - AiInterfaceThread::AiInterfaceThread (AiInterface * aiIntf): - BaseThread () - { - this->masterController = NULL; - this-> - triggerIdMutex = new Mutex (CODE_AT_LINE); - this-> - aiIntf = aiIntf; - uniqueID = "AiInterfaceThread"; - } + AiInterfaceThread::AiInterfaceThread(AiInterface * aiIntf) : + BaseThread() { + this->masterController = NULL; + this-> + triggerIdMutex = new Mutex(CODE_AT_LINE); + this-> + aiIntf = aiIntf; + uniqueID = "AiInterfaceThread"; + } - AiInterfaceThread::~ - AiInterfaceThread () - { - delete - triggerIdMutex; - triggerIdMutex = NULL; - } + AiInterfaceThread::~ + AiInterfaceThread() { + delete + triggerIdMutex; + triggerIdMutex = NULL; + } - void - AiInterfaceThread::setQuitStatus (bool value) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d value = %d\n", - __FILE__, __FUNCTION__, __LINE__, value); + void + AiInterfaceThread::setQuitStatus(bool value) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d value = %d\n", + __FILE__, __FUNCTION__, __LINE__, value); - BaseThread::setQuitStatus (value); - if (value == true) - { - signal (-1); - } + BaseThread::setQuitStatus(value); + if (value == true) { + signal(-1); + } - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", __FILE__, - __FUNCTION__, __LINE__); - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", __FILE__, + __FUNCTION__, __LINE__); + } - void - AiInterfaceThread::signal (int frameIndex) - { - if (frameIndex >= 0) - { - static string - mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutex (triggerIdMutex, mutexOwnerId); - this->frameIndex.first = frameIndex; - this->frameIndex.second = false; + void + AiInterfaceThread::signal(int frameIndex) { + if (frameIndex >= 0) { + static string + mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutex(triggerIdMutex, mutexOwnerId); + this->frameIndex.first = frameIndex; + this->frameIndex.second = false; - safeMutex.ReleaseLock (); - } - semTaskSignalled.signal (); - } + safeMutex.ReleaseLock(); + } + semTaskSignalled.signal(); + } - void - AiInterfaceThread::setTaskCompleted (int frameIndex) - { - if (frameIndex >= 0) - { - static string - mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutex (triggerIdMutex, mutexOwnerId); - if (this->frameIndex.first == frameIndex) - { - this->frameIndex.second = true; - } - safeMutex.ReleaseLock (); - } - } + void + AiInterfaceThread::setTaskCompleted(int frameIndex) { + if (frameIndex >= 0) { + static string + mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutex(triggerIdMutex, mutexOwnerId); + if (this->frameIndex.first == frameIndex) { + this->frameIndex.second = true; + } + safeMutex.ReleaseLock(); + } + } - bool - AiInterfaceThread::canShutdown (bool deleteSelfIfShutdownDelayed) - { - bool - ret = (getExecutingTask () == false); - if (ret == false && deleteSelfIfShutdownDelayed == true) - { - setDeleteSelfOnExecutionDone (deleteSelfIfShutdownDelayed); - deleteSelfIfRequired (); - signalQuit (); - } + bool + AiInterfaceThread::canShutdown(bool deleteSelfIfShutdownDelayed) { + bool + ret = (getExecutingTask() == false); + if (ret == false && deleteSelfIfShutdownDelayed == true) { + setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed); + deleteSelfIfRequired(); + signalQuit(); + } - return ret; - } + return ret; + } - bool - AiInterfaceThread::isSignalCompleted (int frameIndex) - { - if (getRunningStatus () == false) - { - return true; - } - static string - mutexOwnerId = string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutex (triggerIdMutex, mutexOwnerId); - //bool result = (event != NULL ? event->eventCompleted : true); - bool - result = (this->frameIndex.first == frameIndex - && this->frameIndex.second == true); + bool + AiInterfaceThread::isSignalCompleted(int frameIndex) { + if (getRunningStatus() == false) { + return true; + } + static string + mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutex(triggerIdMutex, mutexOwnerId); + //bool result = (event != NULL ? event->eventCompleted : true); + bool + result = (this->frameIndex.first == frameIndex + && this->frameIndex.second == true); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] worker thread this = %p, this->frameIndex.first = %d, this->frameIndex.second = %d\n",__FILE__,__FUNCTION__,__LINE__,this,this->frameIndex.first,this->frameIndex.second); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] worker thread this = %p, this->frameIndex.first = %d, this->frameIndex.second = %d\n",__FILE__,__FUNCTION__,__LINE__,this,this->frameIndex.first,this->frameIndex.second); - safeMutex.ReleaseLock (); - return result; - } + safeMutex.ReleaseLock(); + return result; + } - void - AiInterfaceThread::signalQuit () - { - if (this->aiIntf != NULL) - { - MutexSafeWrapper - safeMutex (this->aiIntf->getMutex (), - string (__FILE__) + "_" + intToStr (__LINE__)); - this->aiIntf = NULL; - } + void + AiInterfaceThread::signalQuit() { + if (this->aiIntf != NULL) { + MutexSafeWrapper + safeMutex(this->aiIntf->getMutex(), + string(__FILE__) + "_" + intToStr(__LINE__)); + this->aiIntf = NULL; + } - BaseThread::signalQuit (); - } - void - AiInterfaceThread::execute () - { - RunningStatusSafeWrapper - runningStatus (this); - try - { - //setRunningStatus(true); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line: %d] ****************** STARTING worker thread this = %p\n", - __FILE__, __FUNCTION__, __LINE__, this); + BaseThread::signalQuit(); + } + void + AiInterfaceThread::execute() { + RunningStatusSafeWrapper + runningStatus(this); + try { + //setRunningStatus(true); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line: %d] ****************** STARTING worker thread this = %p\n", + __FILE__, __FUNCTION__, __LINE__, this); - //bool minorDebugPerformance = false; - Chrono - chrono; + //bool minorDebugPerformance = false; + Chrono + chrono; - //unsigned int idx = 0; - for (; this->aiIntf != NULL;) - { - if (getQuitStatus () == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - __FILE__, __FUNCTION__, __LINE__); - break; - } + //unsigned int idx = 0; + for (; this->aiIntf != NULL;) { + if (getQuitStatus() == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + __FILE__, __FUNCTION__, __LINE__); + break; + } - semTaskSignalled.waitTillSignalled (); + semTaskSignalled.waitTillSignalled(); - static string - masterSlaveOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MasterSlaveThreadControllerSafeWrapper - safeMasterController (masterController, 20000, - masterSlaveOwnerId); + static string + masterSlaveOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MasterSlaveThreadControllerSafeWrapper + safeMasterController(masterController, 20000, + masterSlaveOwnerId); - if (getQuitStatus () == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - __FILE__, __FUNCTION__, __LINE__); - break; - } + if (getQuitStatus() == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + __FILE__, __FUNCTION__, __LINE__); + break; + } - static string - mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutex (triggerIdMutex, mutexOwnerId); - bool - executeTask = (frameIndex.first >= 0); + static string + mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutex(triggerIdMutex, mutexOwnerId); + bool + executeTask = (frameIndex.first >= 0); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] frameIndex = %d this = %p executeTask = %d\n",__FILE__,__FUNCTION__,__LINE__,frameIndex.first, this, executeTask); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] frameIndex = %d this = %p executeTask = %d\n",__FILE__,__FUNCTION__,__LINE__,frameIndex.first, this, executeTask); - safeMutex.ReleaseLock (); + safeMutex.ReleaseLock(); - if (executeTask == true) - { - ExecutingTaskSafeWrapper - safeExecutingTaskMutex (this); + if (executeTask == true) { + ExecutingTaskSafeWrapper + safeExecutingTaskMutex(this); - MutexSafeWrapper - safeMutex (this->aiIntf->getMutex (), - string (__FILE__) + "_" + intToStr (__LINE__)); + MutexSafeWrapper + safeMutex(this->aiIntf->getMutex(), + string(__FILE__) + "_" + intToStr(__LINE__)); - this->aiIntf->update (); + this->aiIntf->update(); - safeMutex.ReleaseLock (); + safeMutex.ReleaseLock(); - setTaskCompleted (frameIndex.first); - } + setTaskCompleted(frameIndex.first); + } - if (getQuitStatus () == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - __FILE__, __FUNCTION__, __LINE__); - break; - } - } + if (getQuitStatus() == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + __FILE__, __FUNCTION__, __LINE__); + break; + } + } - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line: %d] ****************** ENDING worker thread this = %p\n", - __FILE__, __FUNCTION__, __LINE__, this); - } - catch (const exception & ex) - { - //setRunningStatus(false); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line: %d] ****************** ENDING worker thread this = %p\n", + __FILE__, __FUNCTION__, __LINE__, this); + } catch (const exception & ex) { + //setRunningStatus(false); - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - ex.what ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - throw - megaglest_runtime_error (ex.what ()); - } - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", __FILE__, - __FUNCTION__, __LINE__); - } + throw + megaglest_runtime_error(ex.what()); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", __FILE__, + __FUNCTION__, __LINE__); + } - AiInterface::AiInterface (Game & game, int factionIndex, int teamIndex, - int useStartLocation): - fp (NULL) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + AiInterface::AiInterface(Game & game, int factionIndex, int teamIndex, + int useStartLocation) : + fp(NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - this->aiMutex = new Mutex (CODE_AT_LINE); - this->workerThread = NULL; - this->world = game.getWorld (); - this->commander = game.getCommander (); - this->console = game.getConsole (); - this->gameSettings = game.getGameSettings (); + this->aiMutex = new Mutex(CODE_AT_LINE); + this->workerThread = NULL; + this->world = game.getWorld(); + this->commander = game.getCommander(); + this->console = game.getConsole(); + this->gameSettings = game.getGameSettings(); - this->factionIndex = factionIndex; - this->teamIndex = teamIndex; - timer = 0; + this->factionIndex = factionIndex; + this->teamIndex = teamIndex; + timer = 0; - //init ai - ai.init (this, useStartLocation); + //init ai + ai.init(this, useStartLocation); - //config - logLevel = Config::getInstance ().getInt ("AiLog"); - redir = Config::getInstance ().getBool ("AiRedir"); + //config + logLevel = Config::getInstance().getInt("AiLog"); + redir = Config::getInstance().getBool("AiRedir"); - aiLogFile = getLogFilename (); - if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) != - "") - { - aiLogFile = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - aiLogFile; - } - else - { - string - userData = Config::getInstance ().getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - aiLogFile = userData + aiLogFile; - } + aiLogFile = getLogFilename(); + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != + "") { + aiLogFile = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + aiLogFile; + } else { + string + userData = Config::getInstance().getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + aiLogFile = userData + aiLogFile; + } - //clear log file - if (logLevel > 0) - { + //clear log file + if (logLevel > 0) { #ifdef WIN32 - fp = - _wfopen (::Shared::Platform::utf8_decode (aiLogFile).c_str (), - L"wt"); + fp = + _wfopen(::Shared::Platform::utf8_decode(aiLogFile).c_str(), + L"wt"); #else - fp = fopen (aiLogFile.c_str (), "wt"); + fp = fopen(aiLogFile.c_str(), "wt"); #endif - if (fp == NULL) - { - throw - megaglest_runtime_error ("Can't open file: [" + aiLogFile + - "]"); - } - fprintf (fp, - "ZetaGlest AI log file for Tech [%s] Faction [%s] #%d\n\n", - this->gameSettings->getTech ().c_str (), - this->world->getFaction (this->factionIndex)->getType ()-> - getName ().c_str (), this->factionIndex); - } - - - if (Config::getInstance ().getBool ("EnableAIWorkerThreads", "true") == - true) - { - if (workerThread != NULL) - { - workerThread->signalQuit (); - if (workerThread->shutdownAndWait () == true) - { - delete - workerThread; - } - workerThread = NULL; - } - static string - mutexOwnerId = - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - string ("_") + intToStr (__LINE__); - this->workerThread = new AiInterfaceThread (this); - this->workerThread->setUniqueID (mutexOwnerId); - this->workerThread->start (); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - void - AiInterface::init () - { - world = NULL;; - commander = NULL;; - console = NULL;; - gameSettings = NULL;; - timer = 0; - factionIndex = 0; - teamIndex = 0; - redir = false; - logLevel = 0; - fp = NULL;; - aiMutex = NULL; - workerThread = NULL; - } - - AiInterface::~AiInterface () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] deleting AI factionIndex = %d, teamIndex = %d\n", - __FILE__, __FUNCTION__, __LINE__, - this->factionIndex, this->teamIndex); - cacheUnitHarvestResourceLookup.clear (); - - if (workerThread != NULL) - { - workerThread->signalQuit (); - sleep (0); - if (workerThread->canShutdown (true) == true && - workerThread->shutdownAndWait () == true) - { - delete - workerThread; - } - workerThread = NULL; - } - - if (fp) - { - fclose (fp); - fp = NULL; - } - - delete - aiMutex; - aiMutex = NULL; - } - - void - AiInterface::signalWorkerThread (int frameIndex) - { - if (workerThread != NULL) - { - workerThread->signal (frameIndex); - } - else - { - this->update (); - } - } - - bool - AiInterface::isWorkerThreadSignalCompleted (int frameIndex) - { - if (workerThread != NULL) - { - return workerThread->isSignalCompleted (frameIndex); - } - return true; - } - -// ==================== main ==================== - - void - AiInterface::update () - { - timer++; - ai.update (); - } - -// ==================== misc ==================== - - bool - AiInterface::isLogLevelEnabled (int level) - { - return (this->logLevel >= level); - } - - void - AiInterface::printLog (int logLevel, const string & s) - { - if (isLogLevelEnabled (logLevel) == true) - { - string - logString = "(" + intToStr (factionIndex) + ") " + s; - - MutexSafeWrapper - safeMutex (aiMutex, string (__FILE__) + "_" + intToStr (__LINE__)); - //print log to file - if (fp != NULL) - { - fprintf (fp, "%s\n", logString.c_str ()); - } - - //redirect to console - if (redir) - { - console->addLine (logString); - } - } - } - -// ==================== interaction ==================== - - Faction * - AiInterface::getMyFaction () - { - return world->getFaction (factionIndex); - } - - bool - AiInterface::executeCommandOverNetwork () - { - bool - enableServerControlledAI = - gameSettings->getEnableServerControlledAI (); - bool - isNetworkGame = gameSettings->isNetworkGame (); - NetworkRole - role = NetworkManager::getInstance ().getNetworkRole (); - Faction * - faction = world->getFaction (factionIndex); - return faction->getCpuControl (enableServerControlledAI, isNetworkGame, - role); - } - - std::pair < CommandResult, - string > - AiInterface::giveCommandSwitchTeamVote (const Faction * faction, - SwitchTeamVote * vote) - { - assert (this->gameSettings != NULL); - - commander->trySwitchTeamVote (faction, vote); - return std::pair < CommandResult, string > (crSuccess, ""); - } - - std::pair < CommandResult, - string > AiInterface::giveCommand (int unitIndex, - CommandClass commandClass, - const Vec2i & pos) - { - assert (this->gameSettings != NULL); - - std::pair < CommandResult, string > result (crFailUndefined, ""); - if (executeCommandOverNetwork () == true) - { - const Unit * - unit = getMyUnit (unitIndex); - result = - commander->tryGiveCommand (unit, - unit->getType ()-> - getFirstCtOfClass (commandClass), pos, - unit->getType (), - CardinalDir (CardinalDir::NORTH)); - return result; - } - else - { - Command * - c = - new Command (world->getFaction (factionIndex)-> - getUnit (unitIndex)->getType ()-> - getFirstCtOfClass (commandClass), pos); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - result = - world->getFaction (factionIndex)->getUnit (unitIndex)-> - giveCommand (c); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - return result; - } - } - - std::pair < CommandResult, - string > AiInterface::giveCommand (const Unit * unit, - const CommandType * commandType, - const Vec2i & pos, - int unitGroupCommandId) - { - assert (this->gameSettings != NULL); - - std::pair < CommandResult, string > result (crFailUndefined, ""); - if (unit == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] Can not find AI unit in AI factionIndex = %d. Game out of synch.", - __FILE__, __FUNCTION__, __LINE__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - const UnitType * - unitType = unit->getType (); - if (unitType == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] Can not find AI unittype with unit id: %d, AI factionIndex = %d. Game out of synch.", - __FILE__, __FUNCTION__, __LINE__, unit->getId (), - factionIndex); - throw - megaglest_runtime_error (szBuf); - } - if (commandType == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] commandType == NULL, unit id: %d, AI factionIndex = %d. Game out of synch.", - __FILE__, __FUNCTION__, __LINE__, unit->getId (), - factionIndex); - throw - megaglest_runtime_error (szBuf); - } - const CommandType * - ct = unit->getType ()->findCommandTypeById (commandType->getId ()); - if (ct == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d]\nCan not find AI command type for:\nunit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.", - __FILE__, __FUNCTION__, __LINE__, unit->getId (), - unit->getFullName (false).c_str (), - unit->getDesc (false).c_str (), - unit->getFaction ()->getIndex ()); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", - szBuf); - - std::string worldLog = world->DumpWorldToLog (); - std::string sError = - "worldLog = " + worldLog + " " + string (szBuf); - throw - megaglest_runtime_error (sError); - } - - if (executeCommandOverNetwork () == true) - { - result = commander->tryGiveCommand (unit, commandType, pos, - unit->getType (), - CardinalDir (CardinalDir:: - NORTH), false, - NULL, unitGroupCommandId); - return result; - } - else - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - Faction * - faction = world->getFaction (unit->getFactionIndex ()); - Unit * - unitToCommand = faction->findUnit (unit->getId ()); - Command * - cmd = new Command (commandType, pos); - cmd->setUnitCommandGroupId (unitGroupCommandId); - result = unitToCommand->giveCommand (cmd); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - return result; - } - } - - std::pair < CommandResult, - string > AiInterface::giveCommand (int unitIndex, - const CommandType * commandType, - const Vec2i & pos, - int unitGroupCommandId) - { - assert (this->gameSettings != NULL); - - std::pair < CommandResult, string > result (crFailUndefined, ""); - const Unit * - unit = getMyUnit (unitIndex); - if (unit == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] Can not find AI unit with index: %d, AI factionIndex = %d. Game out of synch.", - __FILE__, __FUNCTION__, __LINE__, unitIndex, - factionIndex); - throw - megaglest_runtime_error (szBuf); - } - const UnitType * - unitType = unit->getType (); - if (unitType == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] Can not find AI unittype with unit index: %d, AI factionIndex = %d. Game out of synch.", - __FILE__, __FUNCTION__, __LINE__, unitIndex, - factionIndex); - throw - megaglest_runtime_error (szBuf); - } - const CommandType * - ct = unit->getType ()->findCommandTypeById (commandType->getId ()); - if (ct == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d]\nCan not find AI command type for:\nunit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.", - __FILE__, __FUNCTION__, __LINE__, unit->getId (), - unit->getFullName (false).c_str (), - unit->getDesc (false).c_str (), - unit->getFaction ()->getIndex ()); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", - szBuf); - - std::string worldLog = world->DumpWorldToLog (); - std::string sError = - "worldLog = " + worldLog + " " + string (szBuf); - throw - megaglest_runtime_error (sError); - } - - if (executeCommandOverNetwork () == true) - { - const Unit * - unit = getMyUnit (unitIndex); - result = - commander->tryGiveCommand (unit, commandType, pos, - unit->getType (), - CardinalDir (CardinalDir::NORTH)); - return result; - } - else - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - Command * - cmd = new Command (commandType, pos); - cmd->setUnitCommandGroupId (unitGroupCommandId); - result = - world->getFaction (factionIndex)->getUnit (unitIndex)-> - giveCommand (cmd); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - return result; - } - } - - std::pair < CommandResult, - string > AiInterface::giveCommand (int unitIndex, - const CommandType * commandType, - const Vec2i & pos, - const UnitType * ut) - { - assert (this->gameSettings != NULL); - - std::pair < CommandResult, string > result (crFailUndefined, ""); - const Unit * - unit = getMyUnit (unitIndex); - if (unit == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] Can not find AI unit with index: %d, AI factionIndex = %d. Game out of synch.", - __FILE__, __FUNCTION__, __LINE__, unitIndex, - factionIndex); - throw - megaglest_runtime_error (szBuf); - } - const UnitType * - unitType = unit->getType (); - if (unitType == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] Can not find AI unittype with unit index: %d, AI factionIndex = %d. Game out of synch.", - __FILE__, __FUNCTION__, __LINE__, unitIndex, - factionIndex); - throw - megaglest_runtime_error (szBuf); - } - const CommandType * - ct = unit->getType ()->findCommandTypeById (commandType->getId ()); - if (ct == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d]\nCan not find AI command type for:\nunit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.", - __FILE__, __FUNCTION__, __LINE__, unit->getId (), - unit->getFullName (false).c_str (), - unit->getDesc (false).c_str (), - unit->getFaction ()->getIndex ()); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", - szBuf); - - std::string worldLog = world->DumpWorldToLog (); - std::string sError = - "worldLog = " + worldLog + " " + string (szBuf); - throw - megaglest_runtime_error (sError); - } - - if (executeCommandOverNetwork () == true) - { - const Unit * - unit = getMyUnit (unitIndex); - result = - commander->tryGiveCommand (unit, commandType, pos, ut, - CardinalDir (CardinalDir::NORTH)); - return result; - } - else - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - result = - world->getFaction (factionIndex)->getUnit (unitIndex)-> - giveCommand (new - Command (commandType, pos, ut, - CardinalDir (CardinalDir::NORTH))); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - return result; - } - } - - std::pair < CommandResult, - string > AiInterface::giveCommand (int unitIndex, - const CommandType * commandType, - Unit * u) - { - assert (this->gameSettings != NULL); - assert (this->commander != NULL); - - std::pair < CommandResult, string > result (crFailUndefined, ""); - const Unit * - unit = getMyUnit (unitIndex); - if (unit == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] Can not find AI unit with index: %d, AI factionIndex = %d. Game out of synch.", - __FILE__, __FUNCTION__, __LINE__, unitIndex, - factionIndex); - throw - megaglest_runtime_error (szBuf); - } - const UnitType * - unitType = unit->getType (); - if (unitType == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] Can not find AI unittype with unit index: %d, AI factionIndex = %d. Game out of synch.", - __FILE__, __FUNCTION__, __LINE__, unitIndex, - factionIndex); - throw - megaglest_runtime_error (szBuf); - } - const CommandType * - ct = - (commandType != - NULL ? unit->getType ()->findCommandTypeById (commandType-> - getId ()) : NULL); - if (ct == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d]\nCan not find AI command type for:\nunit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.", - __FILE__, __FUNCTION__, __LINE__, unit->getId (), - unit->getFullName (false).c_str (), - unit->getDesc (false).c_str (), - unit->getFaction ()->getIndex ()); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", - szBuf); - - std::string worldLog = world->DumpWorldToLog (); - std::string sError = - "worldLog = " + worldLog + " " + string (szBuf); - throw - megaglest_runtime_error (sError); - } - - if (executeCommandOverNetwork () == true) - { - Unit * - targetUnit = u; - const Unit * - unit = getMyUnit (unitIndex); - - result = - commander->tryGiveCommand (unit, commandType, Vec2i (0), - unit->getType (), - CardinalDir (CardinalDir::NORTH), - false, targetUnit); - - return result; - } - else - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - result = - world->getFaction (factionIndex)->getUnit (unitIndex)-> - giveCommand (new Command (commandType, u)); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - return result; - } - } - -// ==================== get data ==================== - - int - AiInterface::getMapMaxPlayers () - { - return world->getMaxPlayers (); - } - - Vec2i - AiInterface::getHomeLocation () - { - return world->getMap ()->getStartLocation (world-> - getFaction (factionIndex)-> - getStartLocationIndex ()); - } - - Vec2i - AiInterface::getStartLocation (int loactionIndex) - { - return world->getMap ()->getStartLocation (loactionIndex); - } - - int - AiInterface::getFactionCount () - { - return world->getFactionCount (); - } - - int - AiInterface::getMyUnitCount () const - { - return - world-> - getFaction (factionIndex)-> - getUnitCount (); - } - - int - AiInterface::getMyUpgradeCount () const - { - return - world-> - getFaction (factionIndex)-> - getUpgradeManager ()-> - getUpgradeCount (); - } - -//int AiInterface::onSightUnitCount() { -// int count=0; -// Map *map= world->getMap(); -// for(int i=0; igetFactionCount(); ++i) { -// for(int j=0; jgetFaction(i)->getUnitCount(); ++j) { -// Unit *unit = world->getFaction(i)->getUnit(j); -// SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(unit->getPos())); -// bool cannotSeeUnit = (unit->getType()->hasCellMap() == true && -// unit->getType()->getAllowEmptyCellMap() == true && -// unit->getType()->hasEmptyCellMap() == true); -// if(sc->isVisible(teamIndex) && cannotSeeUnit == false) { -// count++; -// } -// } -// } -// return count; -//} - - const Resource * - AiInterface::getResource (const ResourceType * rt) - { - return world->getFaction (factionIndex)->getResource (rt); - } - - Unit * - AiInterface::getMyUnitPtr (int unitIndex) - { - if (unitIndex < 0 - || unitIndex >= world->getFaction (factionIndex)->getUnitCount ()) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] unitIndex >= world->getFaction(factionIndex)->getUnitCount(), unitIndex = %d, world->getFaction(factionIndex)->getUnitCount() = %d", - __FILE__, __FUNCTION__, __LINE__, unitIndex, - world->getFaction (factionIndex)->getUnitCount ()); - throw - megaglest_runtime_error (szBuf); - } - - return world->getFaction (factionIndex)->getUnit (unitIndex); - } - - const Unit * - AiInterface::getMyUnit (int unitIndex) - { - return getMyUnitPtr (unitIndex); - } - -//const Unit *AiInterface::getOnSightUnit(int unitIndex) { -// -// int count=0; -// Map *map= world->getMap(); -// -// for(int i=0; igetFactionCount(); ++i) { -// for(int j=0; jgetFaction(i)->getUnitCount(); ++j) { -// Unit * unit= world->getFaction(i)->getUnit(j); -// SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(unit->getPos())); -// bool cannotSeeUnit = (unit->getType()->hasCellMap() == true && -// unit->getType()->getAllowEmptyCellMap() == true && -// unit->getType()->hasEmptyCellMap() == true); -// -// if(sc->isVisible(teamIndex) && cannotSeeUnit == false) { -// if(count==unitIndex) { -// return unit; -// } -// else { -// count ++; -// } -// } -// } -// } -// return NULL; -//} - - const FactionType * - AiInterface::getMyFactionType () - { - return world->getFaction (factionIndex)->getType (); - } - - const ControlType - AiInterface::getControlType () - { - return world->getFaction (factionIndex)->getControlType (); - } - - const TechTree * - AiInterface::getTechTree () - { - return world->getTechTree (); - } - - - bool - AiInterface::isResourceInRegion (const Vec2i & pos, - const ResourceType * rt, - Vec2i & resourcePos, int range) const - { - const Map * - map = world->getMap (); - - int - xi = 1; - int - xj = 1; - - if (rand () % 2 == 1) - { - xi = -1; - } - if (rand () % 2 == 1) - { - xj = -1; - } - for (int i = -range; i <= range; ++i) - { - for (int j = -range; j <= range; ++j) - { - int - ii = xi * i; - int - jj = xj * j; - if (map->isInside (pos.x + ii, pos.y + jj)) - { - Resource * - r = - map->getSurfaceCell (map-> - toSurfCoords (Vec2i - (pos.x + ii, - pos.y + - jj)))->getResource (); - if (r != NULL) - { - if (r->getType () == rt) - { - resourcePos = pos + Vec2i (ii, jj); - return true; - } - } - } - } - } - return false; - } - - - -//returns if there is a resource next to a unit, in "resourcePos" is stored the relative position of the resource - bool - AiInterface::isResourceNear (const Vec2i & pos, const ResourceType * rt, - Vec2i & resourcePos, Faction * faction, - bool fallbackToPeersHarvestingSameResource) - const - { - const Map * - map = world->getMap (); - int - size = 1; - for (int i = -1; i <= size; ++i) - { - for (int j = -1; j <= size; ++j) - { - if (map->isInside (pos.x + i, pos.y + j)) - { - Resource * - r = - map->getSurfaceCell (map-> - toSurfCoords (Vec2i - (pos.x + i, - pos.y + - j)))->getResource (); - if (r != NULL) - { - if (r->getType () == rt) - { - resourcePos = pos + Vec2i (i, j); - - return - true; - } - } - } - } - } - - if (fallbackToPeersHarvestingSameResource == true && faction != NULL) - { - // Look for another unit that is currently harvesting the same resource - // type right now - - // Check the faction cache for a known position where we can harvest - // this resource type - Vec2i - result = faction->getClosestResourceTypeTargetFromCache (pos, rt); - if (result.x >= 0) - { - resourcePos = result; - - if (pos.dist (resourcePos) <= size) - { - return true; - } - } - } - - return false; - } - - bool - AiInterface::getNearestSightedResource (const ResourceType * rt, - const Vec2i & pos, - Vec2i & resultPos, - bool usableResourceTypeOnly) - { - Faction * - faction = world->getFaction (factionIndex); - //float tmpDist=0; - float - nearestDist = infinity; - bool - anyResource = false; - resultPos.x = -1; - resultPos.y = -1; - - bool - canUseResourceType = (usableResourceTypeOnly == false); - if (usableResourceTypeOnly == true) - { - // can any unit harvest this resource yet? - std::map < const ResourceType *, int >::iterator - iterFind = cacheUnitHarvestResourceLookup.find (rt); - - if (iterFind != cacheUnitHarvestResourceLookup.end () && - faction->findUnit (iterFind->second) != NULL) - { - canUseResourceType = true; - } - else - { - int - unitCount = getMyUnitCount (); - for (int i = 0; i < unitCount; ++i) - { - const Unit * - unit = getMyUnit (i); - const HarvestCommandType * - hct = - unit->getType ()->getFirstHarvestCommand (rt, - unit-> - getFaction ()); - if (hct != NULL) - { - canUseResourceType = true; - cacheUnitHarvestResourceLookup[rt] = unit->getId (); - break; - } - } - } - } - - if (canUseResourceType == true) - { - bool - isResourceClose = - isResourceNear (pos, rt, resultPos, faction, true); - - // Found a resource - if (isResourceClose == true || resultPos.x >= 0) - { - anyResource = true; - } - else - { - const Map * - map = world->getMap (); - for (int i = 0; i < map->getW (); ++i) - { - for (int j = 0; j < map->getH (); ++j) - { - Vec2i - resPos = Vec2i (i, j); - Vec2i - surfPos = Map::toSurfCoords (resPos); - SurfaceCell * - sc = map->getSurfaceCell (surfPos); - - //if explored cell - if (sc != NULL && sc->isExplored (teamIndex)) - { - Resource * - r = sc->getResource (); - - //if resource cell - if (r != NULL) - { - if (r->getType () == rt) - { - float - tmpDist = pos.dist (resPos); - if (tmpDist < nearestDist) - { - anyResource = true; - nearestDist = tmpDist; - resultPos = resPos; - } - } - } - } - } - } - } - } - return anyResource; - } - - bool - AiInterface::isAlly (const Unit * unit) const - { - return - world-> - getFaction (factionIndex)-> - isAlly (unit->getFaction ()); - } - bool - AiInterface::reqsOk (const RequirableType * rt) - { - return world->getFaction (factionIndex)->reqsOk (rt); - } - - bool - AiInterface::reqsOk (const CommandType * ct) - { - return world->getFaction (factionIndex)->reqsOk (ct); - } - - bool - AiInterface::checkCosts (const ProducibleType * pt, - const CommandType * ct) - { - return world->getFaction (factionIndex)->checkCosts (pt, ct); - } - - bool - AiInterface::isFreeCells (const Vec2i & pos, int size, Field field) - { - return world->getMap ()->isFreeCells (pos, size, field); - } - - void - AiInterface::removeEnemyWarningPositionFromList (Vec2i & checkPos) - { - for (int i = (int)enemyWarningPositionList.size () - 1; i >= 0; --i) - { - Vec2i & pos = enemyWarningPositionList[i]; - - if (checkPos == pos) - { - enemyWarningPositionList.erase (enemyWarningPositionList. - begin () + i); - break; - } - } - } - - const Unit * - AiInterface::getFirstOnSightEnemyUnit (Vec2i & pos, Field & field, - int radius) - { - Map * - map = world->getMap (); - - const int - CHECK_RADIUS = 12; - const int - WARNING_ENEMY_COUNT = 6; - - for (int i = 0; i < world->getFactionCount (); ++i) - { - for (int j = 0; j < world->getFaction (i)->getUnitCount (); ++j) - { - Unit * - unit = world->getFaction (i)->getUnit (j); - SurfaceCell * - sc = - map->getSurfaceCell (Map::toSurfCoords (unit->getPos ())); - bool - cannotSeeUnit = (unit->getType ()->hasCellMap () == true && - unit->getType ()->getAllowEmptyCellMap () == - true - && unit->getType ()->hasEmptyCellMap () == - true); - - if (sc->isVisible (teamIndex) && cannotSeeUnit == false && - isAlly (unit) == false && unit->isAlive () == true) - { - pos = unit->getPos (); - field = unit->getCurrField (); - if (pos.dist (getHomeLocation ()) < radius) - { - printLog (2, - "Being attacked at pos " + intToStr (pos.x) + - "," + intToStr (pos.y) + "\n"); - - // Now check if there are more than x enemies in sight and if - // so make note of the position - int - foundEnemies = 0; - std::map < int, - bool > - foundEnemyList; - for (int aiX = pos.x - CHECK_RADIUS; - aiX < pos.x + CHECK_RADIUS; ++aiX) - { - for (int aiY = pos.y - CHECK_RADIUS; - aiY < pos.y + CHECK_RADIUS; ++aiY) - { - Vec2i - checkPos (aiX, aiY); - if (map->isInside (checkPos) - && map->isInsideSurface (map-> - toSurfCoords - (checkPos))) - { - Cell * - cAI = map->getCell (checkPos); - SurfaceCell * - scAI = - map-> - getSurfaceCell (Map:: - toSurfCoords (checkPos)); - if (scAI != NULL && cAI != NULL - && cAI->getUnit (field) != NULL - && sc->isVisible (teamIndex)) - { - const Unit * - checkUnit = cAI->getUnit (field); - if (foundEnemyList. - find (checkUnit->getId ()) == - foundEnemyList.end ()) - { - bool - cannotSeeUnitAI = - (checkUnit->getType ()-> - hasCellMap () == true - && checkUnit->getType ()-> - getAllowEmptyCellMap () == true - && checkUnit->getType ()-> - hasEmptyCellMap () == true); - if (cannotSeeUnitAI == false - && isAlly (checkUnit) == false - && checkUnit->isAlive () == - true) - { - foundEnemies++; - foundEnemyList[checkUnit-> - getId ()] = true; - } - } - } - } - } - } - if (foundEnemies >= WARNING_ENEMY_COUNT) - { - if (std:: - find (enemyWarningPositionList.begin (), - enemyWarningPositionList.end (), - pos) == enemyWarningPositionList.end ()) - { - enemyWarningPositionList.push_back (pos); - } - } - return unit; - } - } - } - } - return NULL; - } - - Map * - AiInterface::getMap () - { - Map * - map = world->getMap (); - return map; - } - - bool - AiInterface::factionUsesResourceType (const FactionType * factionType, - const ResourceType * rt) - { - bool - factionUsesResourceType = factionType->factionUsesResourceType (rt); - return factionUsesResourceType; - } - - void - AiInterface::saveGame (XmlNode * rootNode) const - { - std::map < - string, - string > - mapTagReplacements; - XmlNode * - aiInterfaceNode = rootNode->addChild ("AiInterface"); - -// World *world; -// Commander *commander; -// Console *console; -// GameSettings *gameSettings; -// -// Ai ai; - ai. - saveGame (aiInterfaceNode); -// int timer; - aiInterfaceNode-> - addAttribute ("timer", intToStr (timer), mapTagReplacements); -// int factionIndex; - aiInterfaceNode-> - addAttribute ("factionIndex", intToStr (factionIndex), - mapTagReplacements); -// int teamIndex; - aiInterfaceNode-> - addAttribute ("teamIndex", intToStr (teamIndex), mapTagReplacements); -// //config -// bool redir; - aiInterfaceNode-> - addAttribute ("redir", intToStr (redir), mapTagReplacements); -// int logLevel; - aiInterfaceNode-> - addAttribute ("logLevel", intToStr (logLevel), mapTagReplacements); -// std::map cacheUnitHarvestResourceLookup; - for (std::map < const ResourceType *, int >::const_iterator iterMap = - cacheUnitHarvestResourceLookup.begin (); - iterMap != cacheUnitHarvestResourceLookup.end (); ++iterMap) - { - XmlNode * - cacheUnitHarvestResourceLookupNode = - aiInterfaceNode->addChild ("cacheUnitHarvestResourceLookup"); - - cacheUnitHarvestResourceLookupNode-> - addAttribute ("key", iterMap->first->getName (), - mapTagReplacements); - cacheUnitHarvestResourceLookupNode-> - addAttribute ("value", intToStr (iterMap->second), - mapTagReplacements); - } - } - -// AiInterface::AiInterface(Game &game, int factionIndex, int teamIndex, int useStartLocation) { - void - AiInterface::loadGame (const XmlNode * rootNode, Faction * faction) - { - XmlNode * - aiInterfaceNode = NULL; - vector < XmlNode * >aiInterfaceNodeList = - rootNode->getChildList ("AiInterface"); - for (unsigned int i = 0; i < aiInterfaceNodeList.size (); ++i) - { - XmlNode * - node = aiInterfaceNodeList[i]; - if (node->getAttribute ("factionIndex")->getIntValue () == - faction->getIndex ()) - { - aiInterfaceNode = node; - break; - } - } - - if (aiInterfaceNode != NULL) - { - factionIndex = - aiInterfaceNode->getAttribute ("factionIndex")->getIntValue (); - teamIndex = - aiInterfaceNode->getAttribute ("teamIndex")->getIntValue (); - - ai.loadGame (aiInterfaceNode, faction); - //firstTime = timeflowNode->getAttribute("firstTime")->getFloatValue(); - - timer = aiInterfaceNode->getAttribute ("timer")->getIntValue (); - // int factionIndex; - //factionIndex = aiInterfaceNode->getAttribute("factionIndex")->getIntValue(); - // int teamIndex; - //teamIndex = aiInterfaceNode->getAttribute("teamIndex")->getIntValue(); - // //config - // bool redir; - redir = - aiInterfaceNode->getAttribute ("redir")->getIntValue () != 0; - // int logLevel; - logLevel = - aiInterfaceNode->getAttribute ("logLevel")->getIntValue (); - - // std::map cacheUnitHarvestResourceLookup; - // for(std::map::const_iterator iterMap = cacheUnitHarvestResourceLookup.begin(); - // iterMap != cacheUnitHarvestResourceLookup.end(); ++iterMap) { - // XmlNode *cacheUnitHarvestResourceLookupNode = aiInterfaceNode->addChild("cacheUnitHarvestResourceLookup"); - // - // cacheUnitHarvestResourceLookupNode->addAttribute("key",iterMap->first->getName(), mapTagReplacements); - // cacheUnitHarvestResourceLookupNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); - // } - } - } - - } + if (fp == NULL) { + throw + megaglest_runtime_error("Can't open file: [" + aiLogFile + + "]"); + } + fprintf(fp, + "ZetaGlest AI log file for Tech [%s] Faction [%s] #%d\n\n", + this->gameSettings->getTech().c_str(), + this->world->getFaction(this->factionIndex)->getType()-> + getName().c_str(), this->factionIndex); + } + + + if (Config::getInstance().getBool("EnableAIWorkerThreads", "true") == + true) { + if (workerThread != NULL) { + workerThread->signalQuit(); + if (workerThread->shutdownAndWait() == true) { + delete + workerThread; + } + workerThread = NULL; + } + static string + mutexOwnerId = + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + string("_") + intToStr(__LINE__); + this->workerThread = new AiInterfaceThread(this); + this->workerThread->setUniqueID(mutexOwnerId); + this->workerThread->start(); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + void + AiInterface::init() { + world = NULL;; + commander = NULL;; + console = NULL;; + gameSettings = NULL;; + timer = 0; + factionIndex = 0; + teamIndex = 0; + redir = false; + logLevel = 0; + fp = NULL;; + aiMutex = NULL; + workerThread = NULL; + } + + AiInterface::~AiInterface() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] deleting AI factionIndex = %d, teamIndex = %d\n", + __FILE__, __FUNCTION__, __LINE__, + this->factionIndex, this->teamIndex); + cacheUnitHarvestResourceLookup.clear(); + + if (workerThread != NULL) { + workerThread->signalQuit(); + sleep(0); + if (workerThread->canShutdown(true) == true && + workerThread->shutdownAndWait() == true) { + delete + workerThread; + } + workerThread = NULL; + } + + if (fp) { + fclose(fp); + fp = NULL; + } + + delete + aiMutex; + aiMutex = NULL; + } + + void + AiInterface::signalWorkerThread(int frameIndex) { + if (workerThread != NULL) { + workerThread->signal(frameIndex); + } else { + this->update(); + } + } + + bool + AiInterface::isWorkerThreadSignalCompleted(int frameIndex) { + if (workerThread != NULL) { + return workerThread->isSignalCompleted(frameIndex); + } + return true; + } + + // ==================== main ==================== + + void + AiInterface::update() { + timer++; + ai.update(); + } + + // ==================== misc ==================== + + bool + AiInterface::isLogLevelEnabled(int level) { + return (this->logLevel >= level); + } + + void + AiInterface::printLog(int logLevel, const string & s) { + if (isLogLevelEnabled(logLevel) == true) { + string + logString = "(" + intToStr(factionIndex) + ") " + s; + + MutexSafeWrapper + safeMutex(aiMutex, string(__FILE__) + "_" + intToStr(__LINE__)); + //print log to file + if (fp != NULL) { + fprintf(fp, "%s\n", logString.c_str()); + } + + //redirect to console + if (redir) { + console->addLine(logString); + } + } + } + + // ==================== interaction ==================== + + Faction * + AiInterface::getMyFaction() { + return world->getFaction(factionIndex); + } + + bool + AiInterface::executeCommandOverNetwork() { + bool + enableServerControlledAI = + gameSettings->getEnableServerControlledAI(); + bool + isNetworkGame = gameSettings->isNetworkGame(); + NetworkRole + role = NetworkManager::getInstance().getNetworkRole(); + Faction * + faction = world->getFaction(factionIndex); + return faction->getCpuControl(enableServerControlledAI, isNetworkGame, + role); + } + + std::pair < CommandResult, + string > + AiInterface::giveCommandSwitchTeamVote(const Faction * faction, + SwitchTeamVote * vote) { + assert(this->gameSettings != NULL); + + commander->trySwitchTeamVote(faction, vote); + return std::pair < CommandResult, string >(crSuccess, ""); + } + + std::pair < CommandResult, + string > AiInterface::giveCommand(int unitIndex, + CommandClass commandClass, + const Vec2i & pos) { + assert(this->gameSettings != NULL); + + std::pair < CommandResult, string > result(crFailUndefined, ""); + if (executeCommandOverNetwork() == true) { + const Unit * + unit = getMyUnit(unitIndex); + result = + commander->tryGiveCommand(unit, + unit->getType()-> + getFirstCtOfClass(commandClass), pos, + unit->getType(), + CardinalDir(CardinalDir::NORTH)); + return result; + } else { + Command * + c = + new Command(world->getFaction(factionIndex)-> + getUnit(unitIndex)->getType()-> + getFirstCtOfClass(commandClass), pos); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + result = + world->getFaction(factionIndex)->getUnit(unitIndex)-> + giveCommand(c); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + return result; + } + } + + std::pair < CommandResult, + string > AiInterface::giveCommand(const Unit * unit, + const CommandType * commandType, + const Vec2i & pos, + int unitGroupCommandId) { + assert(this->gameSettings != NULL); + + std::pair < CommandResult, string > result(crFailUndefined, ""); + if (unit == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] Can not find AI unit in AI factionIndex = %d. Game out of synch.", + __FILE__, __FUNCTION__, __LINE__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + const UnitType * + unitType = unit->getType(); + if (unitType == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] Can not find AI unittype with unit id: %d, AI factionIndex = %d. Game out of synch.", + __FILE__, __FUNCTION__, __LINE__, unit->getId(), + factionIndex); + throw + megaglest_runtime_error(szBuf); + } + if (commandType == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] commandType == NULL, unit id: %d, AI factionIndex = %d. Game out of synch.", + __FILE__, __FUNCTION__, __LINE__, unit->getId(), + factionIndex); + throw + megaglest_runtime_error(szBuf); + } + const CommandType * + ct = unit->getType()->findCommandTypeById(commandType->getId()); + if (ct == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d]\nCan not find AI command type for:\nunit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.", + __FILE__, __FUNCTION__, __LINE__, unit->getId(), + unit->getFullName(false).c_str(), + unit->getDesc(false).c_str(), + unit->getFaction()->getIndex()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", + szBuf); + + std::string worldLog = world->DumpWorldToLog(); + std::string sError = + "worldLog = " + worldLog + " " + string(szBuf); + throw + megaglest_runtime_error(sError); + } + + if (executeCommandOverNetwork() == true) { + result = commander->tryGiveCommand(unit, commandType, pos, + unit->getType(), + CardinalDir(CardinalDir:: + NORTH), false, + NULL, unitGroupCommandId); + return result; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + Faction * + faction = world->getFaction(unit->getFactionIndex()); + Unit * + unitToCommand = faction->findUnit(unit->getId()); + Command * + cmd = new Command(commandType, pos); + cmd->setUnitCommandGroupId(unitGroupCommandId); + result = unitToCommand->giveCommand(cmd); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + return result; + } + } + + std::pair < CommandResult, + string > AiInterface::giveCommand(int unitIndex, + const CommandType * commandType, + const Vec2i & pos, + int unitGroupCommandId) { + assert(this->gameSettings != NULL); + + std::pair < CommandResult, string > result(crFailUndefined, ""); + const Unit * + unit = getMyUnit(unitIndex); + if (unit == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] Can not find AI unit with index: %d, AI factionIndex = %d. Game out of synch.", + __FILE__, __FUNCTION__, __LINE__, unitIndex, + factionIndex); + throw + megaglest_runtime_error(szBuf); + } + const UnitType * + unitType = unit->getType(); + if (unitType == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] Can not find AI unittype with unit index: %d, AI factionIndex = %d. Game out of synch.", + __FILE__, __FUNCTION__, __LINE__, unitIndex, + factionIndex); + throw + megaglest_runtime_error(szBuf); + } + const CommandType * + ct = unit->getType()->findCommandTypeById(commandType->getId()); + if (ct == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d]\nCan not find AI command type for:\nunit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.", + __FILE__, __FUNCTION__, __LINE__, unit->getId(), + unit->getFullName(false).c_str(), + unit->getDesc(false).c_str(), + unit->getFaction()->getIndex()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", + szBuf); + + std::string worldLog = world->DumpWorldToLog(); + std::string sError = + "worldLog = " + worldLog + " " + string(szBuf); + throw + megaglest_runtime_error(sError); + } + + if (executeCommandOverNetwork() == true) { + const Unit * + unit = getMyUnit(unitIndex); + result = + commander->tryGiveCommand(unit, commandType, pos, + unit->getType(), + CardinalDir(CardinalDir::NORTH)); + return result; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + Command * + cmd = new Command(commandType, pos); + cmd->setUnitCommandGroupId(unitGroupCommandId); + result = + world->getFaction(factionIndex)->getUnit(unitIndex)-> + giveCommand(cmd); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + return result; + } + } + + std::pair < CommandResult, + string > AiInterface::giveCommand(int unitIndex, + const CommandType * commandType, + const Vec2i & pos, + const UnitType * ut) { + assert(this->gameSettings != NULL); + + std::pair < CommandResult, string > result(crFailUndefined, ""); + const Unit * + unit = getMyUnit(unitIndex); + if (unit == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] Can not find AI unit with index: %d, AI factionIndex = %d. Game out of synch.", + __FILE__, __FUNCTION__, __LINE__, unitIndex, + factionIndex); + throw + megaglest_runtime_error(szBuf); + } + const UnitType * + unitType = unit->getType(); + if (unitType == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] Can not find AI unittype with unit index: %d, AI factionIndex = %d. Game out of synch.", + __FILE__, __FUNCTION__, __LINE__, unitIndex, + factionIndex); + throw + megaglest_runtime_error(szBuf); + } + const CommandType * + ct = unit->getType()->findCommandTypeById(commandType->getId()); + if (ct == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d]\nCan not find AI command type for:\nunit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.", + __FILE__, __FUNCTION__, __LINE__, unit->getId(), + unit->getFullName(false).c_str(), + unit->getDesc(false).c_str(), + unit->getFaction()->getIndex()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", + szBuf); + + std::string worldLog = world->DumpWorldToLog(); + std::string sError = + "worldLog = " + worldLog + " " + string(szBuf); + throw + megaglest_runtime_error(sError); + } + + if (executeCommandOverNetwork() == true) { + const Unit * + unit = getMyUnit(unitIndex); + result = + commander->tryGiveCommand(unit, commandType, pos, ut, + CardinalDir(CardinalDir::NORTH)); + return result; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + result = + world->getFaction(factionIndex)->getUnit(unitIndex)-> + giveCommand(new + Command(commandType, pos, ut, + CardinalDir(CardinalDir::NORTH))); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + return result; + } + } + + std::pair < CommandResult, + string > AiInterface::giveCommand(int unitIndex, + const CommandType * commandType, + Unit * u) { + assert(this->gameSettings != NULL); + assert(this->commander != NULL); + + std::pair < CommandResult, string > result(crFailUndefined, ""); + const Unit * + unit = getMyUnit(unitIndex); + if (unit == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] Can not find AI unit with index: %d, AI factionIndex = %d. Game out of synch.", + __FILE__, __FUNCTION__, __LINE__, unitIndex, + factionIndex); + throw + megaglest_runtime_error(szBuf); + } + const UnitType * + unitType = unit->getType(); + if (unitType == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] Can not find AI unittype with unit index: %d, AI factionIndex = %d. Game out of synch.", + __FILE__, __FUNCTION__, __LINE__, unitIndex, + factionIndex); + throw + megaglest_runtime_error(szBuf); + } + const CommandType * + ct = + (commandType != + NULL ? unit->getType()->findCommandTypeById(commandType-> + getId()) : NULL); + if (ct == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d]\nCan not find AI command type for:\nunit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.", + __FILE__, __FUNCTION__, __LINE__, unit->getId(), + unit->getFullName(false).c_str(), + unit->getDesc(false).c_str(), + unit->getFaction()->getIndex()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", + szBuf); + + std::string worldLog = world->DumpWorldToLog(); + std::string sError = + "worldLog = " + worldLog + " " + string(szBuf); + throw + megaglest_runtime_error(sError); + } + + if (executeCommandOverNetwork() == true) { + Unit * + targetUnit = u; + const Unit * + unit = getMyUnit(unitIndex); + + result = + commander->tryGiveCommand(unit, commandType, Vec2i(0), + unit->getType(), + CardinalDir(CardinalDir::NORTH), + false, targetUnit); + + return result; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + result = + world->getFaction(factionIndex)->getUnit(unitIndex)-> + giveCommand(new Command(commandType, u)); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + return result; + } + } + + // ==================== get data ==================== + + int + AiInterface::getMapMaxPlayers() { + return world->getMaxPlayers(); + } + + Vec2i + AiInterface::getHomeLocation() { + return world->getMap()->getStartLocation(world-> + getFaction(factionIndex)-> + getStartLocationIndex()); + } + + Vec2i + AiInterface::getStartLocation(int loactionIndex) { + return world->getMap()->getStartLocation(loactionIndex); + } + + int + AiInterface::getFactionCount() { + return world->getFactionCount(); + } + + int + AiInterface::getMyUnitCount() const { + return + world-> + getFaction(factionIndex)-> + getUnitCount(); + } + + int + AiInterface::getMyUpgradeCount() const { + return + world-> + getFaction(factionIndex)-> + getUpgradeManager()-> + getUpgradeCount(); + } + + //int AiInterface::onSightUnitCount() { + // int count=0; + // Map *map= world->getMap(); + // for(int i=0; igetFactionCount(); ++i) { + // for(int j=0; jgetFaction(i)->getUnitCount(); ++j) { + // Unit *unit = world->getFaction(i)->getUnit(j); + // SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(unit->getPos())); + // bool cannotSeeUnit = (unit->getType()->hasCellMap() == true && + // unit->getType()->getAllowEmptyCellMap() == true && + // unit->getType()->hasEmptyCellMap() == true); + // if(sc->isVisible(teamIndex) && cannotSeeUnit == false) { + // count++; + // } + // } + // } + // return count; + //} + + const Resource * + AiInterface::getResource(const ResourceType * rt) { + return world->getFaction(factionIndex)->getResource(rt); + } + + Unit * + AiInterface::getMyUnitPtr(int unitIndex) { + if (unitIndex < 0 + || unitIndex >= world->getFaction(factionIndex)->getUnitCount()) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] unitIndex >= world->getFaction(factionIndex)->getUnitCount(), unitIndex = %d, world->getFaction(factionIndex)->getUnitCount() = %d", + __FILE__, __FUNCTION__, __LINE__, unitIndex, + world->getFaction(factionIndex)->getUnitCount()); + throw + megaglest_runtime_error(szBuf); + } + + return world->getFaction(factionIndex)->getUnit(unitIndex); + } + + const Unit * + AiInterface::getMyUnit(int unitIndex) { + return getMyUnitPtr(unitIndex); + } + + //const Unit *AiInterface::getOnSightUnit(int unitIndex) { + // + // int count=0; + // Map *map= world->getMap(); + // + // for(int i=0; igetFactionCount(); ++i) { + // for(int j=0; jgetFaction(i)->getUnitCount(); ++j) { + // Unit * unit= world->getFaction(i)->getUnit(j); + // SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(unit->getPos())); + // bool cannotSeeUnit = (unit->getType()->hasCellMap() == true && + // unit->getType()->getAllowEmptyCellMap() == true && + // unit->getType()->hasEmptyCellMap() == true); + // + // if(sc->isVisible(teamIndex) && cannotSeeUnit == false) { + // if(count==unitIndex) { + // return unit; + // } + // else { + // count ++; + // } + // } + // } + // } + // return NULL; + //} + + const FactionType * + AiInterface::getMyFactionType() { + return world->getFaction(factionIndex)->getType(); + } + + const ControlType + AiInterface::getControlType() { + return world->getFaction(factionIndex)->getControlType(); + } + + const TechTree * + AiInterface::getTechTree() { + return world->getTechTree(); + } + + + bool + AiInterface::isResourceInRegion(const Vec2i & pos, + const ResourceType * rt, + Vec2i & resourcePos, int range) const { + const Map * + map = world->getMap(); + + int + xi = 1; + int + xj = 1; + + if (rand() % 2 == 1) { + xi = -1; + } + if (rand() % 2 == 1) { + xj = -1; + } + for (int i = -range; i <= range; ++i) { + for (int j = -range; j <= range; ++j) { + int + ii = xi * i; + int + jj = xj * j; + if (map->isInside(pos.x + ii, pos.y + jj)) { + Resource * + r = + map->getSurfaceCell(map-> + toSurfCoords(Vec2i + (pos.x + ii, + pos.y + + jj)))->getResource(); + if (r != NULL) { + if (r->getType() == rt) { + resourcePos = pos + Vec2i(ii, jj); + return true; + } + } + } + } + } + return false; + } + + + + //returns if there is a resource next to a unit, in "resourcePos" is stored the relative position of the resource + bool + AiInterface::isResourceNear(const Vec2i & pos, const ResourceType * rt, + Vec2i & resourcePos, Faction * faction, + bool fallbackToPeersHarvestingSameResource) + const { + const Map * + map = world->getMap(); + int + size = 1; + for (int i = -1; i <= size; ++i) { + for (int j = -1; j <= size; ++j) { + if (map->isInside(pos.x + i, pos.y + j)) { + Resource * + r = + map->getSurfaceCell(map-> + toSurfCoords(Vec2i + (pos.x + i, + pos.y + + j)))->getResource(); + if (r != NULL) { + if (r->getType() == rt) { + resourcePos = pos + Vec2i(i, j); + + return + true; + } + } + } + } + } + + if (fallbackToPeersHarvestingSameResource == true && faction != NULL) { + // Look for another unit that is currently harvesting the same resource + // type right now + + // Check the faction cache for a known position where we can harvest + // this resource type + Vec2i + result = faction->getClosestResourceTypeTargetFromCache(pos, rt); + if (result.x >= 0) { + resourcePos = result; + + if (pos.dist(resourcePos) <= size) { + return true; + } + } + } + + return false; + } + + bool + AiInterface::getNearestSightedResource(const ResourceType * rt, + const Vec2i & pos, + Vec2i & resultPos, + bool usableResourceTypeOnly) { + Faction * + faction = world->getFaction(factionIndex); + //float tmpDist=0; + float + nearestDist = infinity; + bool + anyResource = false; + resultPos.x = -1; + resultPos.y = -1; + + bool + canUseResourceType = (usableResourceTypeOnly == false); + if (usableResourceTypeOnly == true) { + // can any unit harvest this resource yet? + std::map < const ResourceType *, int >::iterator + iterFind = cacheUnitHarvestResourceLookup.find(rt); + + if (iterFind != cacheUnitHarvestResourceLookup.end() && + faction->findUnit(iterFind->second) != NULL) { + canUseResourceType = true; + } else { + int + unitCount = getMyUnitCount(); + for (int i = 0; i < unitCount; ++i) { + const Unit * + unit = getMyUnit(i); + const HarvestCommandType * + hct = + unit->getType()->getFirstHarvestCommand(rt, + unit-> + getFaction()); + if (hct != NULL) { + canUseResourceType = true; + cacheUnitHarvestResourceLookup[rt] = unit->getId(); + break; + } + } + } + } + + if (canUseResourceType == true) { + bool + isResourceClose = + isResourceNear(pos, rt, resultPos, faction, true); + + // Found a resource + if (isResourceClose == true || resultPos.x >= 0) { + anyResource = true; + } else { + const Map * + map = world->getMap(); + for (int i = 0; i < map->getW(); ++i) { + for (int j = 0; j < map->getH(); ++j) { + Vec2i + resPos = Vec2i(i, j); + Vec2i + surfPos = Map::toSurfCoords(resPos); + SurfaceCell * + sc = map->getSurfaceCell(surfPos); + + //if explored cell + if (sc != NULL && sc->isExplored(teamIndex)) { + Resource * + r = sc->getResource(); + + //if resource cell + if (r != NULL) { + if (r->getType() == rt) { + float + tmpDist = pos.dist(resPos); + if (tmpDist < nearestDist) { + anyResource = true; + nearestDist = tmpDist; + resultPos = resPos; + } + } + } + } + } + } + } + } + return anyResource; + } + + bool + AiInterface::isAlly(const Unit * unit) const { + return + world-> + getFaction(factionIndex)-> + isAlly(unit->getFaction()); + } + bool + AiInterface::reqsOk(const RequirableType * rt) { + return world->getFaction(factionIndex)->reqsOk(rt); + } + + bool + AiInterface::reqsOk(const CommandType * ct) { + return world->getFaction(factionIndex)->reqsOk(ct); + } + + bool + AiInterface::checkCosts(const ProducibleType * pt, + const CommandType * ct) { + return world->getFaction(factionIndex)->checkCosts(pt, ct); + } + + bool + AiInterface::isFreeCells(const Vec2i & pos, int size, Field field) { + return world->getMap()->isFreeCells(pos, size, field); + } + + void + AiInterface::removeEnemyWarningPositionFromList(Vec2i & checkPos) { + for (int i = (int) enemyWarningPositionList.size() - 1; i >= 0; --i) { + Vec2i & pos = enemyWarningPositionList[i]; + + if (checkPos == pos) { + enemyWarningPositionList.erase(enemyWarningPositionList. + begin() + i); + break; + } + } + } + + const Unit * + AiInterface::getFirstOnSightEnemyUnit(Vec2i & pos, Field & field, + int radius) { + Map * + map = world->getMap(); + + const int + CHECK_RADIUS = 12; + const int + WARNING_ENEMY_COUNT = 6; + + for (int i = 0; i < world->getFactionCount(); ++i) { + for (int j = 0; j < world->getFaction(i)->getUnitCount(); ++j) { + Unit * + unit = world->getFaction(i)->getUnit(j); + SurfaceCell * + sc = + map->getSurfaceCell(Map::toSurfCoords(unit->getPos())); + bool + cannotSeeUnit = (unit->getType()->hasCellMap() == true && + unit->getType()->getAllowEmptyCellMap() == + true + && unit->getType()->hasEmptyCellMap() == + true); + + if (sc->isVisible(teamIndex) && cannotSeeUnit == false && + isAlly(unit) == false && unit->isAlive() == true) { + pos = unit->getPos(); + field = unit->getCurrField(); + if (pos.dist(getHomeLocation()) < radius) { + printLog(2, + "Being attacked at pos " + intToStr(pos.x) + + "," + intToStr(pos.y) + "\n"); + + // Now check if there are more than x enemies in sight and if + // so make note of the position + int + foundEnemies = 0; + std::map < int, + bool > + foundEnemyList; + for (int aiX = pos.x - CHECK_RADIUS; + aiX < pos.x + CHECK_RADIUS; ++aiX) { + for (int aiY = pos.y - CHECK_RADIUS; + aiY < pos.y + CHECK_RADIUS; ++aiY) { + Vec2i + checkPos(aiX, aiY); + if (map->isInside(checkPos) + && map->isInsideSurface(map-> + toSurfCoords + (checkPos))) { + Cell * + cAI = map->getCell(checkPos); + SurfaceCell * + scAI = + map-> + getSurfaceCell(Map:: + toSurfCoords(checkPos)); + if (scAI != NULL && cAI != NULL + && cAI->getUnit(field) != NULL + && sc->isVisible(teamIndex)) { + const Unit * + checkUnit = cAI->getUnit(field); + if (foundEnemyList. + find(checkUnit->getId()) == + foundEnemyList.end()) { + bool + cannotSeeUnitAI = + (checkUnit->getType()-> + hasCellMap() == true + && checkUnit->getType()-> + getAllowEmptyCellMap() == true + && checkUnit->getType()-> + hasEmptyCellMap() == true); + if (cannotSeeUnitAI == false + && isAlly(checkUnit) == false + && checkUnit->isAlive() == + true) { + foundEnemies++; + foundEnemyList[checkUnit-> + getId()] = true; + } + } + } + } + } + } + if (foundEnemies >= WARNING_ENEMY_COUNT) { + if (std:: + find(enemyWarningPositionList.begin(), + enemyWarningPositionList.end(), + pos) == enemyWarningPositionList.end()) { + enemyWarningPositionList.push_back(pos); + } + } + return unit; + } + } + } + } + return NULL; + } + + Map * + AiInterface::getMap() { + Map * + map = world->getMap(); + return map; + } + + bool + AiInterface::factionUsesResourceType(const FactionType * factionType, + const ResourceType * rt) { + bool + factionUsesResourceType = factionType->factionUsesResourceType(rt); + return factionUsesResourceType; + } + + void + AiInterface::saveGame(XmlNode * rootNode) const { + std::map < + string, + string > + mapTagReplacements; + XmlNode * + aiInterfaceNode = rootNode->addChild("AiInterface"); + + // World *world; + // Commander *commander; + // Console *console; + // GameSettings *gameSettings; + // + // Ai ai; + ai. + saveGame(aiInterfaceNode); + // int timer; + aiInterfaceNode-> + addAttribute("timer", intToStr(timer), mapTagReplacements); + // int factionIndex; + aiInterfaceNode-> + addAttribute("factionIndex", intToStr(factionIndex), + mapTagReplacements); + // int teamIndex; + aiInterfaceNode-> + addAttribute("teamIndex", intToStr(teamIndex), mapTagReplacements); + // //config + // bool redir; + aiInterfaceNode-> + addAttribute("redir", intToStr(redir), mapTagReplacements); + // int logLevel; + aiInterfaceNode-> + addAttribute("logLevel", intToStr(logLevel), mapTagReplacements); + // std::map cacheUnitHarvestResourceLookup; + for (std::map < const ResourceType *, int >::const_iterator iterMap = + cacheUnitHarvestResourceLookup.begin(); + iterMap != cacheUnitHarvestResourceLookup.end(); ++iterMap) { + XmlNode * + cacheUnitHarvestResourceLookupNode = + aiInterfaceNode->addChild("cacheUnitHarvestResourceLookup"); + + cacheUnitHarvestResourceLookupNode-> + addAttribute("key", iterMap->first->getName(), + mapTagReplacements); + cacheUnitHarvestResourceLookupNode-> + addAttribute("value", intToStr(iterMap->second), + mapTagReplacements); + } + } + + // AiInterface::AiInterface(Game &game, int factionIndex, int teamIndex, int useStartLocation) { + void + AiInterface::loadGame(const XmlNode * rootNode, Faction * faction) { + XmlNode * + aiInterfaceNode = NULL; + vector < XmlNode * >aiInterfaceNodeList = + rootNode->getChildList("AiInterface"); + for (unsigned int i = 0; i < aiInterfaceNodeList.size(); ++i) { + XmlNode * + node = aiInterfaceNodeList[i]; + if (node->getAttribute("factionIndex")->getIntValue() == + faction->getIndex()) { + aiInterfaceNode = node; + break; + } + } + + if (aiInterfaceNode != NULL) { + factionIndex = + aiInterfaceNode->getAttribute("factionIndex")->getIntValue(); + teamIndex = + aiInterfaceNode->getAttribute("teamIndex")->getIntValue(); + + ai.loadGame(aiInterfaceNode, faction); + //firstTime = timeflowNode->getAttribute("firstTime")->getFloatValue(); + + timer = aiInterfaceNode->getAttribute("timer")->getIntValue(); + // int factionIndex; + //factionIndex = aiInterfaceNode->getAttribute("factionIndex")->getIntValue(); + // int teamIndex; + //teamIndex = aiInterfaceNode->getAttribute("teamIndex")->getIntValue(); + // //config + // bool redir; + redir = + aiInterfaceNode->getAttribute("redir")->getIntValue() != 0; + // int logLevel; + logLevel = + aiInterfaceNode->getAttribute("logLevel")->getIntValue(); + + // std::map cacheUnitHarvestResourceLookup; + // for(std::map::const_iterator iterMap = cacheUnitHarvestResourceLookup.begin(); + // iterMap != cacheUnitHarvestResourceLookup.end(); ++iterMap) { + // XmlNode *cacheUnitHarvestResourceLookupNode = aiInterfaceNode->addChild("cacheUnitHarvestResourceLookup"); + // + // cacheUnitHarvestResourceLookupNode->addAttribute("key",iterMap->first->getName(), mapTagReplacements); + // cacheUnitHarvestResourceLookupNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + // } + } + } + + } } //end namespace diff --git a/source/glest_game/ai/ai_interface.h b/source/glest_game/ai/ai_interface.h index f37cb20d4..4639ed31b 100644 --- a/source/glest_game/ai/ai_interface.h +++ b/source/glest_game/ai/ai_interface.h @@ -33,309 +33,295 @@ # include "leak_dumper.h" using - Shared::Util::intToStr; +Shared::Util::intToStr; namespace - Glest -{ - namespace - Game - { + Glest { + namespace + Game { -// ===================================================== -// class AiInterface -// -/// The AI will interact with the game through this interface -// ===================================================== + // ===================================================== + // class AiInterface + // + /// The AI will interact with the game through this interface + // ===================================================== - class - AiInterfaceThread: - public - BaseThread, - public - SlaveThreadControllerInterface - { - protected: + class + AiInterfaceThread : + public + BaseThread, + public + SlaveThreadControllerInterface { + protected: - AiInterface * - aiIntf; - Semaphore - semTaskSignalled; - Mutex * - triggerIdMutex; - std::pair < int, - bool > - frameIndex; - MasterSlaveThreadController * - masterController; + AiInterface * + aiIntf; + Semaphore + semTaskSignalled; + Mutex * + triggerIdMutex; + std::pair < int, + bool > + frameIndex; + MasterSlaveThreadController * + masterController; - virtual void - setQuitStatus (bool value); - virtual void - setTaskCompleted (int frameIndex); + virtual void + setQuitStatus(bool value); + virtual void + setTaskCompleted(int frameIndex); - public: - explicit - AiInterfaceThread (AiInterface * aiIntf); - virtual ~ - AiInterfaceThread (); - virtual void - execute (); - void - signal (int frameIndex); - bool - isSignalCompleted (int frameIndex); + public: + explicit + AiInterfaceThread(AiInterface * aiIntf); + virtual ~ + AiInterfaceThread(); + virtual void + execute(); + void + signal(int frameIndex); + bool + isSignalCompleted(int frameIndex); - virtual void - setMasterController (MasterSlaveThreadController * master) - { - masterController = master; - } - virtual void - signalSlave (void *userdata) - { - signal (*((int *) (userdata))); - } + virtual void + setMasterController(MasterSlaveThreadController * master) { + masterController = master; + } + virtual void + signalSlave(void *userdata) { + signal(*((int *) (userdata))); + } - virtual void - signalQuit (); - virtual bool - canShutdown (bool deleteSelfIfShutdownDelayed = false); - }; + virtual void + signalQuit(); + virtual bool + canShutdown(bool deleteSelfIfShutdownDelayed = false); + }; - class - AiInterface - { - private: - World * - world; - Commander * - commander; - Console * - console; - GameSettings * - gameSettings; + class + AiInterface { + private: + World * + world; + Commander * + commander; + Console * + console; + GameSettings * + gameSettings; - Ai - ai; + Ai + ai; - int - timer; - int - factionIndex; - int - teamIndex; + int + timer; + int + factionIndex; + int + teamIndex; - //config - bool - redir; - int - logLevel; - std::string - aiLogFile; - FILE * - fp; + //config + bool + redir; + int + logLevel; + std::string + aiLogFile; + FILE * + fp; - std::map < const ResourceType *, int > - cacheUnitHarvestResourceLookup; + std::map < const ResourceType *, int > + cacheUnitHarvestResourceLookup; - Mutex * - aiMutex; + Mutex * + aiMutex; - AiInterfaceThread * - workerThread; - std::vector < - Vec2i > - enemyWarningPositionList; + AiInterfaceThread * + workerThread; + std::vector < + Vec2i > + enemyWarningPositionList; - public: - AiInterface (Game & game, int factionIndex, int teamIndex, - int useStartLocation = -1); - ~ - AiInterface (); + public: + AiInterface(Game & game, int factionIndex, int teamIndex, + int useStartLocation = -1); + ~ + AiInterface(); - AiInterface (const AiInterface & obj) - { - init (); - throw - megaglest_runtime_error ("class AiInterface is NOT safe to copy!"); - } - AiInterface & - operator= (const AiInterface & obj) - { - init (); - throw - megaglest_runtime_error ("class AiInterface is NOT safe to assign!"); - } + AiInterface(const AiInterface & obj) { + init(); + throw + megaglest_runtime_error("class AiInterface is NOT safe to copy!"); + } + AiInterface & + operator= (const AiInterface & obj) { + init(); + throw + megaglest_runtime_error("class AiInterface is NOT safe to assign!"); + } - //main - void - update (); + //main + void + update(); - std::vector < Vec2i > getEnemyWarningPositionList ()const - { - return - enemyWarningPositionList; - } - void - removeEnemyWarningPositionFromList (Vec2i & checkPos); + std::vector < Vec2i > getEnemyWarningPositionList()const { + return + enemyWarningPositionList; + } + void + removeEnemyWarningPositionFromList(Vec2i & checkPos); - inline Mutex * - getMutex () - { - return aiMutex; - } + inline Mutex * + getMutex() { + return aiMutex; + } - void - signalWorkerThread (int frameIndex); - bool - isWorkerThreadSignalCompleted (int frameIndex); - AiInterfaceThread * - getWorkerThread () - { - return workerThread; - } + void + signalWorkerThread(int frameIndex); + bool + isWorkerThreadSignalCompleted(int frameIndex); + AiInterfaceThread * + getWorkerThread() { + return workerThread; + } - bool - isLogLevelEnabled (int level); + bool + isLogLevelEnabled(int level); - //get - int - getTimer () const - { - return - timer; - } - int - getFactionIndex () const - { - return - factionIndex; - } + //get + int + getTimer() const { + return + timer; + } + int + getFactionIndex() const { + return + factionIndex; + } - //misc - void - printLog (int logLevel, const string & s); + //misc + void + printLog(int logLevel, const string & s); - //interact - std::pair < CommandResult, string > giveCommand (int unitIndex, - CommandClass - commandClass, - const Vec2i & pos = - Vec2i (0)); - std::pair < CommandResult, string > giveCommand (int unitIndex, - const CommandType * - commandType, - const Vec2i & pos, - const UnitType * - unitType); - std::pair < CommandResult, string > giveCommand (int unitIndex, - const CommandType * - commandType, - const Vec2i & pos, - int - unitGroupCommandId); - std::pair < CommandResult, string > giveCommand (int unitIndex, - const CommandType * - commandType, Unit * u = - NULL); - std::pair < CommandResult, string > giveCommand (const Unit * unit, - const CommandType * - commandType, - const Vec2i & pos, - int - unitGroupCommandId); + //interact + std::pair < CommandResult, string > giveCommand(int unitIndex, + CommandClass + commandClass, + const Vec2i & pos = + Vec2i(0)); + std::pair < CommandResult, string > giveCommand(int unitIndex, + const CommandType * + commandType, + const Vec2i & pos, + const UnitType * + unitType); + std::pair < CommandResult, string > giveCommand(int unitIndex, + const CommandType * + commandType, + const Vec2i & pos, + int + unitGroupCommandId); + std::pair < CommandResult, string > giveCommand(int unitIndex, + const CommandType * + commandType, Unit * u = + NULL); + std::pair < CommandResult, string > giveCommand(const Unit * unit, + const CommandType * + commandType, + const Vec2i & pos, + int + unitGroupCommandId); - std::pair < CommandResult, - string > giveCommandSwitchTeamVote (const Faction * faction, - SwitchTeamVote * vote); + std::pair < CommandResult, + string > giveCommandSwitchTeamVote(const Faction * faction, + SwitchTeamVote * vote); - //get data - const ControlType - getControlType (); - int - getMapMaxPlayers (); - Vec2i - getHomeLocation (); - Vec2i - getStartLocation (int locationIndex); - int - getFactionCount (); - int - getMyUnitCount () const; - int - getMyUpgradeCount () const; - //int onSightUnitCount(); - const Resource * - getResource (const ResourceType * rt); - const Unit * - getMyUnit (int unitIndex); - Unit * - getMyUnitPtr (int unitIndex); - //const Unit *getOnSightUnit(int unitIndex); - const FactionType * - getMyFactionType (); - Faction * - getMyFaction (); - const TechTree * - getTechTree (); - bool - isResourceInRegion (const Vec2i & pos, const ResourceType * rt, - Vec2i & resourcePos, int range) const; - bool - isResourceNear (const Vec2i & pos, const ResourceType * rt, - Vec2i & resourcePos, Faction * faction, - bool fallbackToPeersHarvestingSameResource) const; - bool - getNearestSightedResource (const ResourceType * rt, const Vec2i & pos, - Vec2i & resultPos, - bool usableResourceTypeOnly); - bool - isAlly (const Unit * unit) const; - bool - isAlly (int factionIndex) const; - bool - reqsOk (const RequirableType * rt); - bool - reqsOk (const CommandType * ct); - bool - checkCosts (const ProducibleType * pt, const CommandType * ct); - bool - isFreeCells (const Vec2i & pos, int size, Field field); - const Unit * - getFirstOnSightEnemyUnit (Vec2i & pos, Field & field, int radius); - Map * - getMap (); - World * - getWorld () - { - return world; - } + //get data + const ControlType + getControlType(); + int + getMapMaxPlayers(); + Vec2i + getHomeLocation(); + Vec2i + getStartLocation(int locationIndex); + int + getFactionCount(); + int + getMyUnitCount() const; + int + getMyUpgradeCount() const; + //int onSightUnitCount(); + const Resource * + getResource(const ResourceType * rt); + const Unit * + getMyUnit(int unitIndex); + Unit * + getMyUnitPtr(int unitIndex); + //const Unit *getOnSightUnit(int unitIndex); + const FactionType * + getMyFactionType(); + Faction * + getMyFaction(); + const TechTree * + getTechTree(); + bool + isResourceInRegion(const Vec2i & pos, const ResourceType * rt, + Vec2i & resourcePos, int range) const; + bool + isResourceNear(const Vec2i & pos, const ResourceType * rt, + Vec2i & resourcePos, Faction * faction, + bool fallbackToPeersHarvestingSameResource) const; + bool + getNearestSightedResource(const ResourceType * rt, const Vec2i & pos, + Vec2i & resultPos, + bool usableResourceTypeOnly); + bool + isAlly(const Unit * unit) const; + bool + isAlly(int factionIndex) const; + bool + reqsOk(const RequirableType * rt); + bool + reqsOk(const CommandType * ct); + bool + checkCosts(const ProducibleType * pt, const CommandType * ct); + bool + isFreeCells(const Vec2i & pos, int size, Field field); + const Unit * + getFirstOnSightEnemyUnit(Vec2i & pos, Field & field, int radius); + Map * + getMap(); + World * + getWorld() { + return world; + } - bool - factionUsesResourceType (const FactionType * factionType, - const ResourceType * rt); + bool + factionUsesResourceType(const FactionType * factionType, + const ResourceType * rt); - void - saveGame (XmlNode * rootNode) const; - void - loadGame (const XmlNode * rootNode, Faction * faction); + void + saveGame(XmlNode * rootNode) const; + void + loadGame(const XmlNode * rootNode, Faction * faction); - private: - string getLogFilename ()const - { - return - "ai" + - intToStr (factionIndex) + - ".log"; - } - bool - executeCommandOverNetwork (); + private: + string getLogFilename()const { + return + "ai" + + intToStr(factionIndex) + + ".log"; + } + bool + executeCommandOverNetwork(); - void - init (); - }; + void + init(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/ai/ai_rule.cpp b/source/glest_game/ai/ai_rule.cpp index d4a1aba92..4072a0160 100644 --- a/source/glest_game/ai/ai_rule.cpp +++ b/source/glest_game/ai/ai_rule.cpp @@ -19,3646 +19,3226 @@ #include "leak_dumper.h" using - Shared::Graphics::Vec2i; +Shared::Graphics::Vec2i; namespace - Glest -{ - namespace - Game - { - -// ===================================================== -// class AiRule -// ===================================================== - - AiRule::AiRule (Ai * ai) - { - this->ai = ai; - } - -// ===================================================== -// class AiRuleWorkerHarvest -// ===================================================== - - AiRuleWorkerHarvest::AiRuleWorkerHarvest (Ai * ai): - AiRule (ai) - { - stoppedWorkerIndex = -1; - } - - bool - AiRuleWorkerHarvest::test () - { - return ai->findAbleUnit (&stoppedWorkerIndex, ccHarvest, true); - } - - void - AiRuleWorkerHarvest::execute () - { - ai->harvest (stoppedWorkerIndex); - } - -// ===================================================== -// class AiRuleRefreshHarvester -// ===================================================== - - AiRuleRefreshHarvester::AiRuleRefreshHarvester (Ai * ai): - AiRule (ai) - { - workerIndex = -1; - } - - bool - AiRuleRefreshHarvester::test () - { - return ai->findAbleUnit (&workerIndex, ccHarvest, ccHarvest); - } - - void - AiRuleRefreshHarvester::execute () - { - ai->harvest (workerIndex); - } - -// ===================================================== -// class AiRuleScoutPatrol -// ===================================================== - - AiRuleScoutPatrol::AiRuleScoutPatrol (Ai * ai): - AiRule (ai) - { - } - - bool - AiRuleScoutPatrol::test () - { - return ai->isStableBase (); - } - - void - AiRuleScoutPatrol::execute () - { - ai->sendScoutPatrol (); - } -// ===================================================== -// class AiRuleRepair -// ===================================================== - - AiRuleRepair::AiRuleRepair (Ai * ai): - AiRule (ai) - { - damagedUnitIndex = 0; - damagedUnitIsCastle = false; - } - - double - AiRuleRepair::getMinCastleHpRatio () const - { - return - 0.6; - } - - int - AiRuleRepair::getMinUnitsToRepairCastle () - { - int - minUnitsRepairingCastle = 7; - if (ai->getCountOfClass (ucWorker) <= 6) - { - minUnitsRepairingCastle = 1; - } - else if (ai->getCountOfClass (ucWorker) <= 8) - { - minUnitsRepairingCastle = 2; - } - else if (ai->getCountOfClass (ucWorker) <= 10) - { - minUnitsRepairingCastle = 3; - } - else if (ai->getCountOfClass (ucWorker) <= 12) - { - minUnitsRepairingCastle = 5; - } - return minUnitsRepairingCastle; - } - - bool - AiRuleRepair::test () - { - AiInterface * - aiInterface = ai->getAiInterface (); - - int - minUnitsRepairingCastle = getMinUnitsToRepairCastle (); - const double - minCastleHpRatio = getMinCastleHpRatio (); - - // look for a damaged unit and give priority to the factions bases - // (units that produce workers and store resources) - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - const Unit * - u = aiInterface->getMyUnit (i); - //printf("\n\n\n\n!!!!!! Is damaged unit [%d - %s] u->getHpRatio() = %f, hp = %d, mapHp = %d\n",u->getId(),u->getType()->getName().c_str(),u->getHpRatio(),u->getHp(),u->getType()->getTotalMaxHp(u->getTotalUpgrade())); - if (u->getHpRatio () < 1.f) - { - //printf("\n\n\n\n!!!!!! Is damaged unit [%d - %s] u->getHpRatio() = %f, hp = %d, mapHp = %d\n",u->getId(),u->getType()->getName().c_str(),u->getHpRatio(),u->getHp(),u->getType()->getTotalMaxHp(u->getTotalUpgrade())); - - bool - unitCanProduceWorker = false; - for (int j = 0; unitCanProduceWorker == false && - j < u->getType ()->getCommandTypeCount (); ++j) - { - const CommandType * - ct = u->getType ()->getCommandType (j); - - //if the command is produce - if (ct->getClass () == ccProduce - || ct->getClass () == ccMorph) - { - const ProducibleType * - pt = ct->getProduced (); - if (pt != NULL) - { - const UnitType * - ut = dynamic_cast < const - UnitType * >(pt); - if (ut != NULL - && ut->hasCommandClass (ccHarvest) == true - && u->getType ()->getStoredResourceCount () > 0) - { - //printf("\n\n\n\n!!!!!! found candidate castle unit to repair [%d - %s]\n",u->getId(),u->getType()->getName().c_str()); - unitCanProduceWorker = true; - } - } - } - } - - if (unitCanProduceWorker == true) - { - int - candidatedamagedUnitIndex = -1; - int - unitCountAlreadyRepairingDamagedUnit = 0; - // Now check if any other unit is able to repair this unit - for (int i1 = 0; i1 < aiInterface->getMyUnitCount (); ++i1) - { - const Unit * - u1 = aiInterface->getMyUnit (i1); - const RepairCommandType * - rct = static_cast < const - RepairCommandType * - >(u1->getType ()->getFirstCtOfClass (ccRepair)); - //if(rct) printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can reapir damaged unit [%d]\n",u1->getId(),u1->getType()->getName().c_str(),u->getCurrSkill()->getClass(),rct->isRepairableUnitType(u->getType())); - - if (rct != NULL) - { - //printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can repair damaged unit [%d] Castles hp-ratio = %f\n",u1->getId(),u1->getType()->getName().c_str(),u1->getCurrSkill()->getClass(),rct->isRepairableUnitType(u->getType()),u->getHpRatio()); - - if (u1->getCurrSkill ()->getClass () == scStop - || u1->getCurrSkill ()->getClass () == scMove - || u->getHpRatio () <= minCastleHpRatio) - { - if (rct->isRepairableUnitType (u->getType ())) - { - candidatedamagedUnitIndex = i; - //return true; - } - } - else if (u1->getCurrSkill ()->getClass () == - scRepair) - { - Command * - cmd = u1->getCurrCommand (); - if (cmd != NULL - && cmd->getCommandType ()->getClass () == - ccRepair) - { - if (cmd->getUnit () != NULL - && cmd->getUnit ()->getId () == - u->getId ()) - { - //printf("\n\n\n\n^^^^^^^^^^ unit is ALREADY repairer unit [%d - %s]\n",u1->getId(),u1->getType()->getName().c_str()); - unitCountAlreadyRepairingDamagedUnit++; - } - } - } - } - } - - if (candidatedamagedUnitIndex >= 0 - && unitCountAlreadyRepairingDamagedUnit < - minUnitsRepairingCastle) - { - //printf("\n\n\n\n^^^^^^^^^^ AI test will repair damaged unit [%d - %s]\n",u->getId(),u->getType()->getName().c_str()); - damagedUnitIndex = candidatedamagedUnitIndex; - damagedUnitIsCastle = true; - return true; - } - } - } - } - damagedUnitIsCastle = false; - damagedUnitIndex = -1; - // Normal Repair checking - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - const Unit * - u = aiInterface->getMyUnit (i); - //printf("\n\n\n\n!!!!!! Is damaged unit [%d - %s] u->getHpRatio() = %f, hp = %d, mapHp = %d\n",u->getId(),u->getType()->getName().c_str(),u->getHpRatio(),u->getHp(),u->getType()->getTotalMaxHp(u->getTotalUpgrade())); - if (u->getHpRatio () < 1.f) - { - // Now check if any other unit is able to repair this unit - for (int i1 = 0; i1 < aiInterface->getMyUnitCount (); ++i1) - { - const Unit * - u1 = aiInterface->getMyUnit (i1); - const RepairCommandType * - rct = static_cast < const - RepairCommandType * - >(u1->getType ()->getFirstCtOfClass (ccRepair)); - //if(rct) printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can reapir damaged unit [%d]\n",u1->getId(),u1->getType()->getName().c_str(),u->getCurrSkill()->getClass(),rct->isRepairableUnitType(u->getType())); - - if (rct != NULL - && (u1->getCurrSkill ()->getClass () == scStop - || u1->getCurrSkill ()->getClass () == scMove)) - { - if (rct->isRepairableUnitType (u->getType ())) - { - damagedUnitIndex = i; - //random if return or not so we get different targets from time to time - if (ai->getRandom ()->randRange (0, 1) == 0) - return true; - } - } - } - } - } - if (damagedUnitIndex != -1) - { - return true; - } - return false; - } - - void - AiRuleRepair::execute () - { - AiInterface * - aiInterface = ai->getAiInterface (); - const Unit * - damagedUnit = aiInterface->getMyUnit (damagedUnitIndex); - //printf("\n\n\n\n###^^^^^^^^^^ Looking for repairer for damaged unit [%d - %s]\n",damagedUnit->getId(),damagedUnit->getType()->getName().c_str()); - - int - minUnitsRepairingCastle = getMinUnitsToRepairCastle (); - const double - minCastleHpRatio = getMinCastleHpRatio (); - - if (minUnitsRepairingCastle > 2) - { - if (damagedUnit->getCurrSkill ()->getClass () == scBeBuilt) - { // if build is still be build 2 helpers are enough - minUnitsRepairingCastle = 2; - } - - if (!damagedUnitIsCastle) - { - minUnitsRepairingCastle = 2; - } - } - if (aiInterface->getControlType () == ctCpuEasy || - aiInterface->getControlType () == ctNetworkCpuEasy) - { - if (!damagedUnitIsCastle) - { - // cpu easy does not repair! - minUnitsRepairingCastle = 0; - } - } - if (aiInterface->getControlType () == ctCpu || - aiInterface->getControlType () == ctNetworkCpu) - { - if (!damagedUnitIsCastle) - { - // cpu does only repair with one unit! - minUnitsRepairingCastle = 1; - } - } - int - unitCountAlreadyRepairingDamagedUnit = 0; - //printf("team %d has damaged unit\n", damagedUnit->getTeam()); - // Now check if any other unit is able to repair this unit - for (int i1 = 0; i1 < aiInterface->getMyUnitCount (); ++i1) - { - const Unit * - u1 = aiInterface->getMyUnit (i1); - const RepairCommandType * - rct = static_cast < const - RepairCommandType * - >(u1->getType ()->getFirstCtOfClass (ccRepair)); - //if(rct) printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can reapir damaged unit [%d]\n",u1->getId(),u1->getType()->getName().c_str(),u1->getCurrSkill()->getClass(),rct->isRepairableUnitType(u1->getType())); - Command * - cmd = u1->getCurrCommand (); - if (cmd != NULL && cmd->getCommandType ()->getClass () == ccRepair) - { - //if(cmd->getUnit() != NULL && cmd->getUnit()->getId() == damagedUnit->getId()) - //if(cmd->getUnit() != NULL && cmd->getPos() == damagedUnit->getPosWithCellMapSet()) - - if (rct != NULL) - { - //printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can repair damaged unit [%d] Castles hp-ratio = %f\n",u1->getId(),u1->getType()->getName().c_str(),u1->getCurrSkill()->getClass(),rct->isRepairableUnitType(u->getType()),u->getHpRatio()); - - if (((RepairCommandType *) (cmd->getCommandType ()))-> - isRepairableUnitType (damagedUnit->getType ())) - { - //printf("^^^^test^^^^^^ unit is ALREADY repairer unit [%d - %s]\nminUnitsRepairingCastle=%d\n",u1->getId(), u1->getType()->getName().c_str(), minUnitsRepairingCastle); - unitCountAlreadyRepairingDamagedUnit++; - } - } - } - } - - if (unitCountAlreadyRepairingDamagedUnit >= minUnitsRepairingCastle) - { - return; - } - - int - unitGroupCommandId = -1; - - //find a repairer and issue command - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - const Unit * - u = aiInterface->getMyUnit (i); - const RepairCommandType * - rct = static_cast < const - RepairCommandType * - >(u->getType ()->getFirstCtOfClass (ccRepair)); - //if(rct) printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can reapir damaged unit [%d]\n",u->getId(),u->getType()->getName().c_str(),u->getCurrSkill()->getClass(),rct->isRepairableUnitType(damagedUnit->getType())); - - if (rct != NULL) - { - //printf("\n\n\n\n^^^^^^^^^^ possible excute repairer unit [%d - %s] current skill [%d] can repair damaged unit [%d] Castles hp-ratio = %f\n",u->getId(),u->getType()->getName().c_str(),u->getCurrSkill()->getClass(),rct->isRepairableUnitType(damagedUnit->getType()),damagedUnit->getHpRatio()); - - if ((u->getCurrSkill ()->getClass () == scStop - || u->getCurrSkill ()->getClass () == scMove - || damagedUnit->getHpRatio () <= minCastleHpRatio)) - { - if ((u->getCurrCommand () == NULL - || (u->getCurrCommand ()->getCommandType ()-> - getClass () != ccBuild - && u->getCurrCommand ()->getCommandType ()-> - getClass () != ccProduce)) - && rct->isRepairableUnitType (damagedUnit->getType ())) - { - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - //printf("\n\n\n\n^^^^^^^^^^ AI execute will repair damaged unit [%d - %s] at pos [%s] cellmapPos [%s] using unit [%d -%s]\n",damagedUnit->getId(),damagedUnit->getType()->getName().c_str(),damagedUnit->getPos().getString().c_str(),damagedUnit->getPosWithCellMapSet().getString().c_str(),u->getId(),u->getType()->getName().c_str()); - - /* - Map *map= aiInterface->getWorld()->getMap(); - Cell *cell = map->getCell(damagedUnit->getPosWithCellMapSet()); - if(cell != NULL) { - printf("\n\n\n\n^^^^^^^^^^ cell is ok\n"); - - Unit *cellUnit = cell->getUnit(damagedUnit->getCurrField()); - if(cellUnit != NULL) { - printf("\n\n\n\n^^^^^^^^^^ cell unit [%d - %s] at pos [%s]\n",cellUnit->getId(),cellUnit->getType()->getName().c_str(),cellUnit->getPos().getString().c_str()); - } - } - */ - - //aiInterface->giveCommand(i, rct, damagedUnit->getPos()); - if (unitCountAlreadyRepairingDamagedUnit < - minUnitsRepairingCastle) - { - - if (unitGroupCommandId == -1) - { - unitGroupCommandId = - aiInterface->getWorld ()-> - getNextCommandGroupId (); - } - - aiInterface->giveCommand (i, rct, - damagedUnit-> - getPosWithCellMapSet (), - unitGroupCommandId); - if (aiInterface->isLogLevelEnabled (3) == true) - aiInterface->printLog (3, - "Repairing order issued"); - unitCountAlreadyRepairingDamagedUnit++; - // printf( - // "^^^^^^^^^^adding one unit to repair ... unitCountAlreadyRepairingDamagedUnit/minUnitsRepairingCastle=%d/%d\n", - // unitCountAlreadyRepairingDamagedUnit, minUnitsRepairingCastle); - } - - if (!damagedUnitIsCastle - || unitCountAlreadyRepairingDamagedUnit >= - minUnitsRepairingCastle) - { - return; - } - } - } - } - } - } - -// ===================================================== -// class AiRuleReturnBase -// ===================================================== - - AiRuleReturnBase::AiRuleReturnBase (Ai * ai): - AiRule (ai) - { - stoppedUnitIndex = -1; - } - - bool - AiRuleReturnBase::test () - { - return ai->findAbleUnit (&stoppedUnitIndex, ccMove, true); - } - - void - AiRuleReturnBase::execute () - { - ai->returnBase (stoppedUnitIndex); - } - -// ===================================================== -// class AiRuleMassiveAttack -// ===================================================== - - AiRuleMassiveAttack::AiRuleMassiveAttack (Ai * ai): - AiRule (ai) - { - ultraAttack = false; - field = fLand; - } - - bool - AiRuleMassiveAttack::test () - { - - if (ai->isStableBase ()) - { - ultraAttack = false; - return ai->beingAttacked (attackPos, field, INT_MAX); - } - else - { - ultraAttack = true; - return ai->beingAttacked (attackPos, field, baseRadius); - } - } - - void - AiRuleMassiveAttack::execute () - { - ai->massiveAttack (attackPos, field, ultraAttack); - } -// ===================================================== -// class AiRuleAddTasks -// ===================================================== - - AiRuleAddTasks::AiRuleAddTasks (Ai * ai): - AiRule (ai) - { - } - - bool - AiRuleAddTasks::test () - { - return !ai->anyTask () || ai->getCountOfClass (ucWorker) < 4; - } - -// This function is what triggers the AI to create new units. - void - AiRuleAddTasks::execute () - { - int - buildingCount = ai->getCountOfClass (ucBuilding); - UnitClass - ucWorkerType = ucWorker; - int - warriorCount = ai->getCountOfClass (ucWarrior, &ucWorkerType); - int - workerCount = ai->getCountOfClass (ucWorker); - int - upgradeCount = ai->getAiInterface ()->getMyUpgradeCount (); - - float - buildingRatio = ai->getRatioOfClass (ucBuilding); - float - warriorRatio = ai->getRatioOfClass (ucWarrior); - float - workerRatio = ai->getRatioOfClass (ucWorker); - - //standard tasks - if (ai->outputAIBehaviourToConsole ()) - printf - ("Add a TASK - AiRuleAddTasks adding ProduceTask(ucWorker) workerCount = %d, RULE Name[%s]\n", - workerCount, this->getName ().c_str ()); - - //emergency workers - if (workerCount < 4) - { - if (ai->outputAIBehaviourToConsole ()) - printf - ("AAA AiRuleAddTasks adding ProduceTask(ucWorker) workerCount = %d, RULE Name[%s]\n", - workerCount, this->getName ().c_str ()); - - ai->addPriorityTask (new ProduceTask (ucWorker)); - } - // The following rules are specific creation rules for different AI. - else - { - if (ai->getAiInterface ()->getControlType () == ctCpuZeta || - ai->getAiInterface ()->getControlType () == ctNetworkCpuZeta) - { - if (ai->outputAIBehaviourToConsole ()) - printf - ("AAA AiRuleAddTasks adding #1 workerCount = %d[%.2f], buildingCount = %d[%.2f] warriorCount = %d[%.2f] upgradeCount = %d RULE Name[%s]\n", - workerCount, workerRatio, buildingCount, buildingRatio, - warriorCount, warriorRatio, upgradeCount, - this->getName ().c_str ()); - - //workers - if (workerCount < 5) - ai->addTask (new ProduceTask (ucWorker)); - if (workerCount < 10) - ai->addTask (new ProduceTask (ucWorker)); - if (workerRatio < 0.20) - ai->addTask (new ProduceTask (ucWorker)); - if (workerRatio < 0.30) - ai->addTask (new ProduceTask (ucWorker)); - - //warriors - if (warriorCount < 10) - ai->addTask (new ProduceTask (ucWarrior)); - if (warriorRatio < 0.20) - ai->addTask (new ProduceTask (ucWarrior)); - if (warriorRatio < 0.30) - ai->addTask (new ProduceTask (ucWarrior)); - if (workerCount >= 10) - ai->addTask (new ProduceTask (ucWarrior)); - if (workerCount >= 15) - ai->addTask (new ProduceTask (ucWarrior)); - if (warriorCount < ai->getMinWarriors () + 2) - { - ai->addTask (new ProduceTask (ucWarrior)); - if (buildingCount > 9) - { - ai->addTask (new ProduceTask (ucWarrior)); - ai->addTask (new ProduceTask (ucWarrior)); - } - if (buildingCount > 12) - { - ai->addTask (new ProduceTask (ucWarrior)); - ai->addTask (new ProduceTask (ucWarrior)); - } - } - - //buildings - if (buildingCount < 6 || buildingRatio < 0.20) - ai->addTask (new BuildTask ((UnitType *) NULL)); - if (buildingCount < 10 && workerCount > 12) - ai->addTask (new BuildTask ((UnitType *) NULL)); - //upgrades - if (upgradeCount == 0 && workerCount > 5) - ai->addTask (new UpgradeTask ((const UpgradeType *) NULL)); - if (upgradeCount == 1 && workerCount > 10) - ai->addTask (new UpgradeTask ((const UpgradeType *) NULL)); - if (upgradeCount == 2 && workerCount > 15) - ai->addTask (new UpgradeTask ((const UpgradeType *) NULL)); - if (ai->isStableBase ()) - ai->addTask (new UpgradeTask ((const UpgradeType *) NULL)); - } - else if (ai->getAiInterface ()->getControlType () == ctCpuEasy || - ai->getAiInterface ()->getControlType () == - ctNetworkCpuEasy) - { // Easy CPU - - if (ai->outputAIBehaviourToConsole ()) - printf - ("AAA AiRuleAddTasks adding #2 workerCount = %d[%.2f], buildingCount = %d[%.2f] warriorCount = %d[%.2f] upgradeCount = %d RULE Name[%s]\n", - workerCount, workerRatio, buildingCount, buildingRatio, - warriorCount, warriorRatio, upgradeCount, - this->getName ().c_str ()); - - //workers - if (workerCount < buildingCount + 2) - ai->addTask (new ProduceTask (ucWorker)); - if (workerCount > 5 && workerRatio < 0.20) - ai->addTask (new ProduceTask (ucWorker)); - - //warriors - if (warriorCount < 10) - ai->addTask (new ProduceTask (ucWarrior)); - if (warriorRatio < 0.20) - ai->addTask (new ProduceTask (ucWarrior)); - if (warriorRatio < 0.30) - ai->addTask (new ProduceTask (ucWarrior)); - if (workerCount >= 10) - ai->addTask (new ProduceTask (ucWarrior)); - if (workerCount >= 15) - ai->addTask (new ProduceTask (ucWarrior)); - - //buildings - if (buildingCount < 6 || buildingRatio < 0.20) - ai->addTask (new BuildTask ((UnitType *) NULL)); - if (buildingCount < 10 && ai->isStableBase ()) - ai->addTask (new BuildTask ((UnitType *) NULL)); - - //upgrades - if (upgradeCount == 0 && workerCount > 6) - ai->addTask (new UpgradeTask ((const UpgradeType *) NULL)); - if (upgradeCount == 1 && workerCount > 7) - ai->addTask (new UpgradeTask ((const UpgradeType *) NULL)); - if (upgradeCount == 2 && workerCount > 9) - ai->addTask (new UpgradeTask ((const UpgradeType *) NULL)); - //if(ai->isStableBase()) ai->addTask(new UpgradeTask()); - } - else - { // normal CPU / UltraCPU ... - if (ai->outputAIBehaviourToConsole ()) - printf - ("AAA AiRuleAddTasks adding #3 workerCount = %d[%.2f], buildingCount = %d[%.2f] warriorCount = %d[%.2f] upgradeCount = %d RULE Name[%s]\n", - workerCount, workerRatio, buildingCount, buildingRatio, - warriorCount, warriorRatio, upgradeCount, - this->getName ().c_str ()); - - //workers - if (workerCount < 5) - ai->addTask (new ProduceTask (ucWorker)); - if (workerCount < 10) - ai->addTask (new ProduceTask (ucWorker)); - if (workerRatio < 0.20) - ai->addTask (new ProduceTask (ucWorker)); - if (workerRatio < 0.30) - ai->addTask (new ProduceTask (ucWorker)); - - //warriors - if (warriorCount < 10) - ai->addTask (new ProduceTask (ucWarrior)); - if (warriorRatio < 0.20) - ai->addTask (new ProduceTask (ucWarrior)); - if (warriorRatio < 0.30) - ai->addTask (new ProduceTask (ucWarrior)); - if (workerCount >= 10) - ai->addTask (new ProduceTask (ucWarrior)); - if (workerCount >= 15) - ai->addTask (new ProduceTask (ucWarrior)); - - //buildings - if (buildingCount < 6 || buildingRatio < 0.20) - ai->addTask (new BuildTask ((UnitType *) NULL)); - if (buildingCount < 10 && workerCount > 12) - ai->addTask (new BuildTask ((UnitType *) NULL)); - - //upgrades - if (upgradeCount == 0 && workerCount > 5) - ai->addTask (new UpgradeTask ((const UpgradeType *) NULL)); - if (upgradeCount == 1 && workerCount > 10) - ai->addTask (new UpgradeTask ((const UpgradeType *) NULL)); - if (upgradeCount == 2 && workerCount > 15) - ai->addTask (new UpgradeTask ((const UpgradeType *) NULL)); - if (ai->isStableBase ()) - ai->addTask (new UpgradeTask ((const UpgradeType *) NULL)); - } - } - } - -// ===================================================== -// class AiRuleBuildOneFarm -// ===================================================== - - AiRuleBuildOneFarm::AiRuleBuildOneFarm (Ai * ai): - AiRule (ai) - { - farm = NULL; - } - - bool - AiRuleBuildOneFarm::test () - { - AiInterface * - aiInterface = ai->getAiInterface (); - - //for all units - for (int i = 0; - i < aiInterface->getMyFactionType ()->getUnitTypeCount (); ++i) - { - const UnitType * - ut = aiInterface->getMyFactionType ()->getUnitType (i); - - //for all production commands - for (int j = 0; j < ut->getCommandTypeCount (); ++j) - { - const CommandType * - ct = ut->getCommandType (j); - if (ct->getClass () == ccProduce) - { - const UnitType * - producedType = static_cast < const - ProduceCommandType * >(ct)-> - getProducedUnit (); - - //for all resources - for (int k = 0; k < producedType->getCostCount (); ++k) - { - const Resource * - r = producedType->getCost (k); - - //find a food producer in the farm produced units - if (r->getAmount () < 0 - && r->getType ()->getClass () == rcConsumable - && ai->getCountOfType (ut) == 0) - { - if (aiInterface->reqsOk (ct) - && aiInterface->getMyFaction ()-> - canCreateUnit (ut, true, true, true) == true) - { - farm = ut; - //printf("AiRuleBuildOneFarm returning true, RULE Name[%s] ut [%s] producedType [%s]\n",this->getName().c_str(),ut->getName().c_str(),producedType->getName().c_str()); - - if (ai->outputAIBehaviourToConsole ()) - printf - ("AiRuleBuildOneFarm returning true, RULE Name[%s]\n", - this->getName ().c_str ()); - - return true; - } - } - } - } - } - } - return false; - } - - void - AiRuleBuildOneFarm::execute () - { - ai->addPriorityTask (new BuildTask (farm)); - } - -// ===================================================== -// class AiRuleProduceResourceProducer -// ===================================================== - - AiRuleProduceResourceProducer::AiRuleProduceResourceProducer (Ai * ai): - AiRule (ai) - { - interval = shortInterval; - rt = NULL; - newResourceBehaviour = - Config::getInstance ().getBool ("NewResourceBehaviour", "false");; - } - - bool - AiRuleProduceResourceProducer::test () - { - //emergency tasks: resource buildings - AiInterface * - aiInterface = ai->getAiInterface (); - - //consumables first - for (int i = 0; - i < aiInterface->getTechTree ()->getResourceTypeCount (); ++i) - { - rt = aiInterface->getTechTree ()->getResourceType (i); - const Resource * - r = aiInterface->getResource (rt); - - if (ai->outputAIBehaviourToConsole ()) - printf ("CONSUMABLE [%s][%d] Testing AI RULE Name[%s]\n", - rt->getName ().c_str (), r->getBalance (), - this->getName ().c_str ()); - - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "CONSUMABLE [%s][%d] Testing AI RULE Name[%s]", - rt->getName ().c_str (), r->getBalance (), - this->getName ().c_str ()); - aiInterface->printLog (4, szBuf); - } - - bool - factionUsesResourceType = - aiInterface->factionUsesResourceType (aiInterface-> - getMyFactionType (), rt); - if (factionUsesResourceType == true - && rt->getClass () == rcConsumable) - { - // The consumable balance is negative - if (r->getBalance () < 0) - { - if (newResourceBehaviour == true) - { - interval = shortInterval; - } - else - { - interval = longInterval; - } - - return true; - } - // If the consumable balance is down to 1/3 of what we need - else - { - if (r->getBalance () * 3 + r->getAmount () < 0) - { - if (newResourceBehaviour == true) - { - interval = shortInterval; - } - else - { - interval = longInterval; - } - - return true; - } - } - } - } - - int - targetStaticResourceCount = minStaticResources; - if (aiInterface->getMyFactionType ()-> - getAIBehaviorStaticOverideValue (aibsvcMinStaticResourceCount) != - INT_MAX) - { - targetStaticResourceCount = - aiInterface->getMyFactionType ()-> - getAIBehaviorStaticOverideValue (aibsvcMinStaticResourceCount); - } - - //statics second - for (int i = 0; - i < aiInterface->getTechTree ()->getResourceTypeCount (); ++i) - { - rt = aiInterface->getTechTree ()->getResourceType (i); - const Resource * - r = aiInterface->getResource (rt); - - if (ai->outputAIBehaviourToConsole ()) - printf ("STATIC [%s][%d] [min %d] Testing AI RULE Name[%s]\n", - rt->getName ().c_str (), r->getAmount (), - targetStaticResourceCount, this->getName ().c_str ()); - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "STATIC resource check [%s][%d] [min %d] Testing AI RULE Name[%s]", - rt->getName ().c_str (), r->getAmount (), - targetStaticResourceCount, this->getName ().c_str ()); - aiInterface->printLog (4, szBuf); - } - - if (rt->getClass () == rcStatic - && r->getAmount () < targetStaticResourceCount) - { - bool - factionUsesResourceType = - aiInterface->factionUsesResourceType (aiInterface-> - getMyFactionType (), - rt); - if (factionUsesResourceType == true) - { - if (newResourceBehaviour == true) - interval = shortInterval; - else - interval = longInterval; - return true; - } - } - } - - if (ai->outputAIBehaviourToConsole ()) - printf ("STATIC returning FALSE\n"); - if (aiInterface->isLogLevelEnabled (4) == true) - aiInterface->printLog (4, "Static Resource check returning FALSE"); - - if (newResourceBehaviour == true) - interval = longInterval; - else - interval = shortInterval; - return false; - } - - void - AiRuleProduceResourceProducer::execute () - { - ai->addPriorityTask (new ProduceTask (rt)); - ai->addTask (new BuildTask (rt)); - } - -// ===================================================== -// class AiRuleProduce -// ===================================================== - - AiRuleProduce::AiRuleProduce (Ai * ai): - AiRule (ai) - { - produceTask = NULL; - newResourceBehaviour = - Config::getInstance ().getBool ("NewResourceBehaviour", "false"); - } - - bool - AiRuleProduce::test () - { - const Task * - task = ai->getTask (); - - if (task == NULL || task->getClass () != tcProduce) - { - return false; - } - - produceTask = static_cast < const ProduceTask *>(task); - return true; - } - - void - AiRuleProduce::execute () - { - AiInterface * - aiInterface = ai->getAiInterface (); - if (produceTask != NULL) - { - - if (ai->outputAIBehaviourToConsole ()) - printf ("AiRuleProduce producing [%s]\n", - (produceTask->getUnitType () != - NULL ? produceTask->getUnitType ()->getName (false). - c_str () : "null")); - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "AiRuleProduce producing [%s]", - (produceTask->getUnitType () != - NULL ? produceTask->getUnitType ()->getName (false). - c_str () : "null")); - aiInterface->printLog (4, szBuf); - } - - //generic produce task, produce random unit that has the skill or produces the resource - if (produceTask->getUnitType () == NULL) - { - if (newResourceBehaviour) - { - produceGenericNew (produceTask); - } - else - produceGeneric (produceTask); - } - - //specific produce task, produce if possible, retry if not enough resources - else - { - produceSpecific (produceTask); - } - - //remove the task - ai->removeTask (produceTask); - } - } - - bool - AiRuleProduce::canUnitTypeOfferResourceType (const UnitType * ut, - const ResourceType * rt) - { - bool - unitTypeOffersResourceType = false; - - AiInterface * - aiInterface = ai->getAiInterface (); - - if (ut != NULL && rt != NULL && aiInterface != NULL - && aiInterface->reqsOk (ut)) - { - // Check of the unit 'gives' the resource - // if the unit produces the resource - const Resource * - r = ut->getCost (rt); - if (r != NULL) - { - if (ai->outputAIBehaviourToConsole ()) - printf - ("#2 produceGeneric r = [%s][%d] Testing AI RULE Name[%s]\n", - r->getDescription (false).c_str (), r->getAmount (), - this->getName ().c_str ()); - } - - if (r != NULL && r->getAmount () < 0) - { - unitTypeOffersResourceType = true; - } - else - { - // for each command check if we produce a unit that handles the resource - for (int commandIndex = 0; - commandIndex < ut->getCommandTypeCount (); ++commandIndex) - { - const CommandType * - ct = ut->getCommandType (commandIndex); - - //if the command is produce - if (ct->getClass () == ccProduce - || ct->getClass () == ccMorph) - { - const UnitType * - producedUnit = static_cast < const - UnitType * >(ct->getProduced ()); - - if (ai->outputAIBehaviourToConsole ()) - printf - ("produceGeneric [%p] Testing AI RULE Name[%s]\n", - rt, this->getName ().c_str ()); - - //if the unit produces the resource - const Resource * - r = producedUnit->getCost (rt); - if (r != NULL) - { - if (ai->outputAIBehaviourToConsole ()) - printf - ("produceGeneric r = [%s][%d] Testing AI RULE Name[%s]\n", - r->getDescription (false).c_str (), - r->getAmount (), this->getName ().c_str ()); - } - - if (r != NULL && r->getAmount () < 0) - { - unitTypeOffersResourceType = true; - break; - } - } - } - } - } - - if (aiInterface != NULL && aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "canUnitTypeOfferResourceType for unit type [%s] for resource type [%s] returned: %d", - (ut != NULL ? ut->getName (false).c_str () : "n/a"), - (rt != NULL ? rt->getName (false).c_str () : "n/a"), - unitTypeOffersResourceType); - aiInterface->printLog (4, szBuf); - } - - return unitTypeOffersResourceType; - } - - bool - AiRuleProduce::setAIProduceTaskForResourceType (const ProduceTask * pt, - AiInterface * aiInterface) - { - bool - taskAdded = false; - if (aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcResourceProducerUnits).size () > 0) - { - const - std::vector < - FactionType::PairPUnitTypeInt > & - unitList = - aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcResourceProducerUnits); - for (unsigned int i = 0; i < unitList.size (); ++i) - { - const - FactionType::PairPUnitTypeInt & - priorityUnit = unitList[i]; - const UnitType * - ut = priorityUnit.first; - if (ai->getCountOfType (ut) < priorityUnit.second && - canUnitTypeOfferResourceType (ut, - pt->getResourceType ()) == - true - && aiInterface->getMyFaction ()-> - canCreateUnit (priorityUnit.first, false, true, - true) == true) - { - ai->addTask (new ProduceTask (priorityUnit.first)); - taskAdded = true; - break; - } - } - } - - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "setAIProduceTaskForResourceType for resource type [%s] returned: %d", - pt->getResourceType ()->getName (false).c_str (), - taskAdded); - aiInterface->printLog (4, szBuf); - } - - return taskAdded; - } - - void - AiRuleProduce::addUnitTypeToCandidates (const UnitType * producedUnit, - UnitTypes & ableUnits, - UnitTypesGiveBack & - ableUnitsGiveBack, - bool unitCanGiveBackResource) - { - // if the unit is not already on the list - if (find (ableUnits.begin (), ableUnits.end (), producedUnit) == - ableUnits.end ()) - { - ableUnits.push_back (producedUnit); - ableUnitsGiveBack.push_back (unitCanGiveBackResource); - - AiInterface * - aiInterface = ai->getAiInterface (); - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "addUnitTypeToCandidates for unit type [%s] unitCanGiveBackResource = %d", - producedUnit->getName (false).c_str (), - unitCanGiveBackResource); - aiInterface->printLog (4, szBuf); - } - - } - } - - void - AiRuleProduce::produceGenericNew (const ProduceTask * pt) - { - UnitTypes - ableUnits; - UnitTypesGiveBack - ableUnitsGiveBack; - - AiInterface * - aiInterface = ai->getAiInterface (); - if (pt->getResourceType () != NULL) - { - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "****START: produceGeneric for resource type [%s]", - pt->getResourceType ()->getName (false).c_str ()); - aiInterface->printLog (4, szBuf); - } - - if (setAIProduceTaskForResourceType (pt, aiInterface) == true) - { - return; - } - } - else if (pt->getUnitClass () == ucWorker) - { - if (aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcWorkerUnits).size () > 0) - { - const - std::vector < - FactionType::PairPUnitTypeInt > & - unitList = - aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcWorkerUnits); - for (unsigned int i = 0; i < unitList.size (); ++i) - { - const - FactionType::PairPUnitTypeInt & - priorityUnit = unitList[i]; - if (ai->getCountOfType (priorityUnit.first) < - priorityUnit.second - && aiInterface->getMyFaction ()-> - canCreateUnit (priorityUnit.first, false, true, - true) == true) - { - ai->addTask (new ProduceTask (priorityUnit.first)); - return; - } - } - } - } - else if (pt->getUnitClass () == ucWarrior) - { - if (aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcWarriorUnits).size () > 0) - { - const - std::vector < - FactionType::PairPUnitTypeInt > & - unitList = - aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcWarriorUnits); - for (unsigned int i = 0; i < unitList.size (); ++i) - { - const - FactionType::PairPUnitTypeInt & - priorityUnit = unitList[i]; - if (ai->getCountOfType (priorityUnit.first) < - priorityUnit.second - && aiInterface->getMyFaction ()-> - canCreateUnit (priorityUnit.first, false, true, - true) == true) - { - ai->addTask (new ProduceTask (priorityUnit.first)); - return; - } - } - } - } - - //for each unit, produce it if possible - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - if (aiInterface->getMyUnit (i)->getCurrCommand () != NULL - && aiInterface->getMyUnit (i)->getCurrCommand ()-> - getCommandType ()->getClass () == ccBuild) - { - //skip this units as it is currently building something - continue; - } - //for each command - const UnitType * - ut = aiInterface->getMyUnit (i)->getType (); - - //bool produceIt= false; - for (int j = 0; j < ut->getCommandTypeCount (); ++j) - { - const CommandType * - ct = ut->getCommandType (j); - - //if the command is produce - //bool produceIt= false; - if (ct->getClass () == ccProduce || ct->getClass () == ccMorph) - { - const UnitType * - producedUnit = static_cast < const - UnitType * >(ct->getProduced ()); - - if (ai->outputAIBehaviourToConsole ()) - printf ("produceGeneric [%p] Testing AI RULE Name[%s]\n", - pt->getResourceType (), - this->getName ().c_str ()); - - //if the unit produces the resource - if (pt->getResourceType () != NULL) - { - const Resource * - r = producedUnit->getCost (pt->getResourceType ()); - if (r != NULL) - { - if (ai->outputAIBehaviourToConsole ()) - printf - ("produceGeneric r = [%s][%d] Testing AI RULE Name[%s]\n", - r->getDescription (false).c_str (), - r->getAmount (), this->getName ().c_str ()); - } - - if (r != NULL && r->getAmount () < 0) - { - if (aiInterface->reqsOk (ct) - && aiInterface->reqsOk (producedUnit)) - { - //produceIt= true; - addUnitTypeToCandidates (producedUnit, - ableUnits, - ableUnitsGiveBack, - false); - } - } - } - else - { - //if the unit is from the right class - if (ai->outputAIBehaviourToConsole ()) - printf - ("produceGeneric right class = [%d] Testing AI RULE Name[%s]\n", - producedUnit->isOfClass (pt->getUnitClass ()), - this->getName ().c_str ()); - - if (producedUnit->isOfClass (pt->getUnitClass ())) - { - if (aiInterface->reqsOk (ct) - && aiInterface->reqsOk (producedUnit)) - { - //produceIt= true; - addUnitTypeToCandidates (producedUnit, - ableUnits, - ableUnitsGiveBack, - false); - } - } - } - } - } - // Now check of the unit 'gives' the resource -// This is likely a unit that it BUILT by another and that is handled by a different AI task type: Build -// if(produceIt == false && pt->getResourceType() != NULL) { -// const Resource *r= ut->getCost(pt->getResourceType()); -// if(r != NULL) { -// if(ai->outputAIBehaviourToConsole()) printf("#2 produceGeneric r = [%s][%d] Testing AI RULE Name[%s]\n",r->getDescription(false).c_str(),r->getAmount(), this->getName().c_str()); -// } -// -// if(r != NULL && r->getAmount() < 0) { -// if(aiInterface->reqsOk(ut)){ -// produceIt= true; -// addUnitTypeToCandidates(ut, ableUnits,ableUnitsGiveBack, true); -// } -// } -// } - - } - - //add specific produce task - if (ableUnits.empty () == false) - { - - if (ai->outputAIBehaviourToConsole ()) - printf - ("produceGeneric !ableUnits.empty(), ableUnits.size() = [%d] Testing AI RULE Name[%s]\n", - (int) ableUnits.size (), this->getName ().c_str ()); - - // Now check if we already have at least 2 produce or morph - // resource based units, if so prefer units that give back the resource - if (pt->getResourceType () != NULL && ableUnits.size () > 1) - { - //priority for non produced units - UnitTypes - newAbleUnits; - bool - haveEnoughProducers = true; - bool - haveNonProducers = false; - for (unsigned int i = 0; i < ableUnits.size (); ++i) - { - const UnitType * - ut = ableUnits[i]; - bool - givesBack = ableUnitsGiveBack[i]; - if (givesBack == false && ai->getCountOfType (ut) < 2) - { - haveEnoughProducers = false; - } - else if (givesBack == true) - { - haveNonProducers = true; - newAbleUnits.push_back (ut); - } - - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In produceGeneric for unit type [%s] givesBack: %d count of unit type: %d", - ut->getName (false).c_str (), givesBack, - ai->getCountOfType (ut)); - aiInterface->printLog (4, szBuf); - } - - } - - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "haveEnoughProducers [%d] haveNonProducers [%d]", - haveEnoughProducers, haveNonProducers); - aiInterface->printLog (4, szBuf); - - for (unsigned int i = 0; i < ableUnits.size (); ++i) - { - const UnitType * - ut = ableUnits[i]; - snprintf (szBuf, 8096, "i: %u unit type [%s]", i, - ut->getName (false).c_str ()); - aiInterface->printLog (4, szBuf); - } - for (unsigned int i = 0; i < newAbleUnits.size (); ++i) - { - const UnitType * - ut = newAbleUnits[i]; - snprintf (szBuf, 8096, "i: %u new unit type [%s]", i, - ut->getName (false).c_str ()); - aiInterface->printLog (4, szBuf); - } - } - - if (haveEnoughProducers == true && haveNonProducers == true) - { - ableUnits = newAbleUnits; - } - } - - //priority for non produced units - for (unsigned int i = 0; i < ableUnits.size (); ++i) - { - if (ai->getCountOfType (ableUnits[i]) == 0) - { - if (ai->getRandom ()->randRange (0, 1) == 0) - { - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In produceGeneric priority adding produce task: %d of " - MG_SIZE_T_SPECIFIER " for unit type [%s]", - i, ableUnits.size (), - ableUnits[i]->getName (false).c_str ()); - aiInterface->printLog (4, szBuf); - } - - ai->addTask (new ProduceTask (ableUnits[i])); - return; - } - } - } - - //normal case - int - randomUnitTypeIndex = - ai->getRandom ()->randRange (0, (int) ableUnits.size () - 1); - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In produceGeneric randomUnitTypeIndex = %d of " - MG_SIZE_T_SPECIFIER " equals unit type [%s]", - randomUnitTypeIndex, ableUnits.size () - 1, - ableUnits[randomUnitTypeIndex]->getName (false). - c_str ()); - aiInterface->printLog (4, szBuf); - } - - const UnitType * - ut = ableUnits[randomUnitTypeIndex]; - - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "== END In produceGeneric normal adding produce task for unit type [%s]", - ut->getName (false).c_str ()); - aiInterface->printLog (4, szBuf); - } - - ai->addTask (new ProduceTask (ut)); - } - } - - void - AiRuleProduce::produceGeneric (const ProduceTask * pt) - { - typedef - vector < const UnitType *> - UnitTypes; - UnitTypes - ableUnits; - AiInterface * - aiInterface = ai->getAiInterface (); - - if (pt->getResourceType () != NULL) - { - if (aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcResourceProducerUnits).size () > 0) - { - const - std::vector < - FactionType::PairPUnitTypeInt > & - unitList = - aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcResourceProducerUnits); - for (unsigned int i = 0; i < unitList.size (); ++i) - { - const - FactionType::PairPUnitTypeInt & - priorityUnit = unitList[i]; - if (ai->getCountOfType (priorityUnit.first) < - priorityUnit.second - && aiInterface->getMyFaction ()-> - canCreateUnit (priorityUnit.first, false, true, - true) == true) - { - //if(ai->getRandom()->randRange(0, 1)==0) { - ai->addTask (new ProduceTask (priorityUnit.first)); - return; - //} - } - } - } - } - else if (pt->getUnitClass () == ucWorker) - { - if (aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcWorkerUnits).size () > 0) - { - const - std::vector < - FactionType::PairPUnitTypeInt > & - unitList = - aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcWorkerUnits); - for (unsigned int i = 0; i < unitList.size (); ++i) - { - const - FactionType::PairPUnitTypeInt & - priorityUnit = unitList[i]; - if (ai->getCountOfType (priorityUnit.first) < - priorityUnit.second - && aiInterface->getMyFaction ()-> - canCreateUnit (priorityUnit.first, false, true, - true) == true) - { - //if(ai->getRandom()->randRange(0, 1)==0) { - ai->addTask (new ProduceTask (priorityUnit.first)); - return; - //} - } - } - } - } - else if (pt->getUnitClass () == ucWarrior) - { - if (aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcWarriorUnits).size () > 0) - { - const - std::vector < - FactionType::PairPUnitTypeInt > & - unitList = - aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcWarriorUnits); - for (unsigned int i = 0; i < unitList.size (); ++i) - { - const - FactionType::PairPUnitTypeInt & - priorityUnit = unitList[i]; - if (ai->getCountOfType (priorityUnit.first) < - priorityUnit.second - && aiInterface->getMyFaction ()-> - canCreateUnit (priorityUnit.first, false, true, - true) == true) - { - //if(ai->getRandom()->randRange(0, 1)==0) { - ai->addTask (new ProduceTask (priorityUnit.first)); - return; - //} - } - } - } - } - - //for each unit, produce it if possible - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - if (aiInterface->getMyUnit (i)->getCurrCommand () != NULL - && aiInterface->getMyUnit (i)->getCurrCommand ()-> - getCommandType ()->getClass () == ccBuild) - { - //skip this units as it is currently building something - continue; - } - //for each command - const UnitType * - ut = aiInterface->getMyUnit (i)->getType (); - for (int j = 0; j < ut->getCommandTypeCount (); ++j) - { - const CommandType * - ct = ut->getCommandType (j); - - //if the command is produce - if (ct->getClass () == ccProduce || ct->getClass () == ccMorph) - { - - const UnitType * - producedUnit = static_cast < const - UnitType * >(ct->getProduced ()); - bool - produceIt = false; - - if (ai->outputAIBehaviourToConsole ()) - printf ("produceGeneric [%p] Testing AI RULE Name[%s]\n", - pt->getResourceType (), - this->getName ().c_str ()); - - //if the unit produces the resource - if (pt->getResourceType () != NULL) - { - const Resource * - r = producedUnit->getCost (pt->getResourceType ()); - - if (r != NULL) - { - if (ai->outputAIBehaviourToConsole ()) - printf - ("produceGeneric r = [%s][%d] Testing AI RULE Name[%s]\n", - r->getDescription (false).c_str (), - r->getAmount (), this->getName ().c_str ()); - } - - if (r != NULL && r->getAmount () < 0) - { - produceIt = true; - } - } - - else - { - //if the unit is from the right class - if (ai->outputAIBehaviourToConsole ()) - printf - ("produceGeneric right class = [%d] Testing AI RULE Name[%s]\n", - producedUnit->isOfClass (pt->getUnitClass ()), - this->getName ().c_str ()); - - if (producedUnit->isOfClass (pt->getUnitClass ())) - { - if (aiInterface->reqsOk (ct) - && aiInterface->reqsOk (producedUnit)) - { - produceIt = true; - } - } - } - - if (produceIt) - { - //if the unit is not already on the list - if (find - (ableUnits.begin (), ableUnits.end (), - producedUnit) == ableUnits.end ()) - { - ableUnits.push_back (producedUnit); - } - } - } - } - } - - //add specific produce task - if (ableUnits.empty () == false) - { - - if (ai->outputAIBehaviourToConsole ()) - printf - ("produceGeneric !ableUnits.empty(), ableUnits.size() = [%d] Testing AI RULE Name[%s]\n", - (int) ableUnits.size (), this->getName ().c_str ()); - - //priority for non produced units - for (unsigned int i = 0; i < ableUnits.size (); ++i) - { - if (ai->getCountOfType (ableUnits[i]) == 0) - { - if (ai->getRandom ()->randRange (0, 1) == 0) - { - ai->addTask (new ProduceTask (ableUnits[i])); - return; - } - } - } - - //normal case - ai-> - addTask (new - ProduceTask (ableUnits - [ai->getRandom ()-> - randRange (0, - (int) ableUnits.size () - 1)])); - } - } - - void - AiRuleProduce::produceSpecific (const ProduceTask * pt) - { - - AiInterface * - aiInterface = ai->getAiInterface (); - - if (ai->outputAIBehaviourToConsole ()) - printf - ("produceSpecific aiInterface->reqsOk(pt->getUnitType()) = [%s][%d] Testing AI RULE Name[%s]\n", - pt->getUnitType ()->getName ().c_str (), - aiInterface->reqsOk (pt->getUnitType ()), - this->getName ().c_str ()); - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "== START produceSpecific aiInterface->reqsOk(pt->getUnitType()) = [%s][%d] Testing AI RULE Name[%s]", - pt->getUnitType ()->getName ().c_str (), - aiInterface->reqsOk (pt->getUnitType ()), - this->getName ().c_str ()); - aiInterface->printLog (4, szBuf); - } - - //if unit meets requirements - if (aiInterface->reqsOk (pt->getUnitType ())) - { - - const CommandType * - ctypeForCostCheck = NULL; - //for each unit - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - //don't use units which are currently building - if (aiInterface->getMyUnit (i)->getCurrCommand () != NULL - && aiInterface->getMyUnit (i)->getCurrCommand ()-> - getCommandType ()->getClass () == ccBuild) - { - //skip this units as it is currently building something - continue; - } - //for each command - const UnitType * - ut = aiInterface->getMyUnit (i)->getType (); - for (int j = 0; j < ut->getCommandTypeCount (); ++j) - { - const CommandType * - ct = ut->getCommandType (j); - - //if the command is produce - if (ct->getClass () == ccProduce - || ct->getClass () == ccMorph) - { - const UnitType * - producedUnit = static_cast < const - UnitType * >(ct->getProduced ()); - - //if units match - if (producedUnit == pt->getUnitType ()) - { - - if (ai->outputAIBehaviourToConsole ()) - printf - ("produceSpecific aiInterface->reqsOk(ct) = [%d] Testing AI RULE Name[%s]\n", - aiInterface->reqsOk (ct), - this->getName ().c_str ()); - - if (aiInterface->reqsOk (ct)) - { - if (ctypeForCostCheck == NULL - || ct->getClass () == ccMorph) - { - if (ctypeForCostCheck != NULL - && ct->getClass () == ccMorph) - { - const MorphCommandType * - mct = dynamic_cast < const - MorphCommandType * >(ct); - if (mct == NULL) - { - throw - megaglest_runtime_error - ("mct == NULL"); - } - if (mct-> - getIgnoreResourceRequirements () == - true) - { - ctypeForCostCheck = ct; - } - } - else - { - ctypeForCostCheck = ct; - } - } - } - } - } - } - } - - if (ai->outputAIBehaviourToConsole ()) - printf - ("produceSpecific aiInterface->checkCosts(pt->getUnitType()) = [%d] Testing AI RULE Name[%s]\n", - aiInterface->checkCosts (pt->getUnitType (), - ctypeForCostCheck), - this->getName ().c_str ()); - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "produceSpecific aiInterface->checkCosts(pt->getUnitType()) = [%d] Testing AI RULE Name[%s]", - aiInterface->checkCosts (pt->getUnitType (), - ctypeForCostCheck), - this->getName ().c_str ()); - aiInterface->printLog (4, szBuf); - } - - //if unit doesnt meet resources retry - if (aiInterface-> - checkCosts (pt->getUnitType (), ctypeForCostCheck) == false) - { - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "Check costs FAILED."); - aiInterface->printLog (4, szBuf); - } - - ai->retryTask (pt); - return; - } - - //produce specific unit - vector < int > - producers; - // Hold a list of units which can produce or morph - // then a list of commandtypes for each unit - map < int, - vector < const CommandType *> > - producersDefaultCommandType; - const CommandType * - defCt = NULL; - - //for each unit - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - if (aiInterface->getMyUnit (i)->getCurrCommand () != NULL - && aiInterface->getMyUnit (i)->getCurrCommand ()-> - getCommandType ()->getClass () == ccBuild) - { - //skip this units as it is currently building something - continue; - } - //for each command - const UnitType * - ut = aiInterface->getMyUnit (i)->getType (); - for (int j = 0; j < ut->getCommandTypeCount (); ++j) - { - const CommandType * - ct = ut->getCommandType (j); - - //if the command is produce - if (ct->getClass () == ccProduce - || ct->getClass () == ccMorph) - { - const UnitType * - producedUnit = static_cast < const - UnitType * >(ct->getProduced ()); - - //if units match - if (producedUnit == pt->getUnitType ()) - { - - if (ai->outputAIBehaviourToConsole ()) - printf - ("produceSpecific aiInterface->reqsOk(ct) = [%d] Testing AI RULE Name[%s]\n", - aiInterface->reqsOk (ct), - this->getName ().c_str ()); - - if (aiInterface->reqsOk (ct)) - { - //defCt= ct; - producers.push_back (i); - producersDefaultCommandType[i].push_back (ct); - } - } - } - } - } - - //produce from random producer - if (producers.empty () == false) - { - - if (ai->outputAIBehaviourToConsole ()) - printf - ("produceSpecific producers.empty() = [%d] Testing AI RULE Name[%s]\n", - producers.empty (), this->getName ().c_str ()); - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "produceSpecific producers.empty() = [%d] Testing AI RULE Name[%s]", - producers.empty (), this->getName ().c_str ()); - aiInterface->printLog (4, szBuf); - } - - // Narrow down producers list to those who are not busy if possible - vector < int > - idle_producers; - for (unsigned int i = 0; i < producers.size (); ++i) - { - int - currentProducerIndex = producers[i]; - if (currentProducerIndex >= aiInterface->getMyUnitCount ()) - { - char - szBuf[8096] = ""; - printf - ("In [%s::%s Line: %d] currentProducerIndex >= aiInterface->getMyUnitCount(), currentProducerIndex = %d, aiInterface->getMyUnitCount() = %d, i = %u,producers.size() = " - MG_SIZE_T_SPECIFIER "\n", __FILE__, __FUNCTION__, - __LINE__, currentProducerIndex, - aiInterface->getMyUnitCount (), i, - producers.size ()); - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] currentProducerIndex >= aiInterface->getMyUnitCount(), currentProducerIndex = %d, aiInterface->getMyUnitCount() = %u, i = %u,producers.size() = " - MG_SIZE_T_SPECIFIER "", __FILE__, - __FUNCTION__, __LINE__, currentProducerIndex, - aiInterface->getMyUnitCount (), i, - producers.size ()); - throw - megaglest_runtime_error (szBuf); - } - - const Unit * - unit = aiInterface->getMyUnit (currentProducerIndex); - if (unit->anyCommand () == false) - { - idle_producers.push_back (currentProducerIndex); - } - } - if (idle_producers.empty () == false) - { - producers = idle_producers; - } - - if (aiInterface->getControlType () == ctCpuZeta || - aiInterface->getControlType () == ctNetworkCpuZeta) - { // zeta cpu trys to balance the commands to the producers - int - randomstart = - ai->getRandom ()->randRange (0, - (int) producers.size () - 1); - int - lowestCommandCount = 1000000; - int - currentProducerIndex = producers[randomstart]; - int - bestIndex = -1; - //int besti=0; - int - currentCommandCount = 0; - for (unsigned int i = randomstart; - i < producers.size () + randomstart; i++) - { - int - prIndex = i; - if (i >= producers.size ()) - { - prIndex = (i - (int) producers.size ()); - } - currentProducerIndex = producers[prIndex]; - - if (currentProducerIndex >= - aiInterface->getMyUnitCount ()) - { - char - szBuf[8096] = ""; - printf - ("In [%s::%s Line: %d] currentProducerIndex >= aiInterface->getMyUnitCount(), currentProducerIndex = %d, aiInterface->getMyUnitCount() = %d, i = %u,producers.size() = " - MG_SIZE_T_SPECIFIER "\n", __FILE__, __FUNCTION__, - __LINE__, currentProducerIndex, - aiInterface->getMyUnitCount (), i, - producers.size ()); - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] currentProducerIndex >= aiInterface->getMyUnitCount(), currentProducerIndex = %d, aiInterface->getMyUnitCount() = %u, i = %u,producers.size() = " - MG_SIZE_T_SPECIFIER "", __FILE__, - __FUNCTION__, __LINE__, - currentProducerIndex, - aiInterface->getMyUnitCount (), i, - producers.size ()); - throw - megaglest_runtime_error (szBuf); - } - if (prIndex >= (int) producers.size ()) - { - char - szBuf[8096] = ""; - printf - ("In [%s::%s Line: %d] prIndex >= producers.size(), currentProducerIndex = %d, i = %u,producers.size() = " - MG_SIZE_T_SPECIFIER " \n", __FILE__, - __FUNCTION__, __LINE__, prIndex, i, - producers.size ()); - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] currentProducerIndex >= producers.size(), currentProducerIndex = %d, i = %u,producers.size() = " - MG_SIZE_T_SPECIFIER "", __FILE__, - __FUNCTION__, __LINE__, - currentProducerIndex, i, - producers.size ()); - throw - megaglest_runtime_error (szBuf); - } - - currentCommandCount = - aiInterface->getMyUnit (currentProducerIndex)-> - getCommandSize (); - if (currentCommandCount == 1 - && aiInterface->getMyUnit (currentProducerIndex)-> - getCurrCommand ()->getCommandType ()->getClass () == - ccStop) - { // special for non buildings - currentCommandCount = 0; - } - if (lowestCommandCount > currentCommandCount) - { - lowestCommandCount = - aiInterface->getMyUnit (currentProducerIndex)-> - getCommandSize (); - bestIndex = currentProducerIndex; - //besti=i%(producers.size()); - } - } - if (bestIndex >= 0) - { - if (aiInterface->getMyUnit (bestIndex)-> - getCommandSize () > 2) - { - // maybe we need another producer of this kind if possible! - if (aiInterface-> - reqsOk (aiInterface->getMyUnit (bestIndex)-> - getType ())) - { - if (ai->getCountOfClass (ucBuilding) > 5) - { - ai-> - addTask (new - BuildTask (aiInterface-> - getMyUnit - (bestIndex)-> - getType ())); - } - } - // need to calculate another producer, maybe its better to produce another warrior with another producer - vector < int > - backupProducers; - // find another producer unit which is free and produce any kind of warrior. - //for each unit - for (int i = 0; i < aiInterface->getMyUnitCount (); - ++i) - { - const UnitType * - ut = aiInterface->getMyUnit (i)->getType (); - //for each command - for (int j = 0; j < ut->getCommandTypeCount (); - ++j) - { - const CommandType * - ct = ut->getCommandType (j); - //if the command is produce - if (ct->getClass () == ccProduce) - { - const UnitType * - unitType = static_cast < const - UnitType * >(ct->getProduced ()); - if (unitType->hasSkillClass (scAttack) - && !unitType-> - hasCommandClass (ccHarvest) - && aiInterface->reqsOk (ct)) - { //this can produce a warrior - backupProducers.push_back (i); - } - } - } - } - if (!backupProducers.empty ()) - { - int - randomstart = - ai->getRandom ()->randRange (0, - (int) - backupProducers. - size () - 1); - int - lowestCommandCount = 1000000; - int - currentProducerIndex = - backupProducers[randomstart]; - int - bestIndex = -1; - for (unsigned int i = randomstart; - i < backupProducers.size () + randomstart; - i++) - { - int - prIndex = i; - if (i >= backupProducers.size ()) - { - prIndex = - (i - (int) backupProducers.size ()); - } - - currentProducerIndex = - backupProducers[prIndex]; - - if (currentProducerIndex >= - aiInterface->getMyUnitCount ()) - { - char - szBuf[8096] = ""; - printf - ("In [%s::%s Line: %d] currentProducerIndex >= aiInterface->getMyUnitCount(), currentProducerIndex = %d, aiInterface->getMyUnitCount() = %d, i = %u,backupProducers.size() = " - MG_SIZE_T_SPECIFIER "\n", __FILE__, - __FUNCTION__, __LINE__, - currentProducerIndex, - aiInterface->getMyUnitCount (), i, - backupProducers.size ()); - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] currentProducerIndex >= aiInterface->getMyUnitCount(), currentProducerIndex = %d, aiInterface->getMyUnitCount() = %d, i = %u,backupProducers.size() = " - MG_SIZE_T_SPECIFIER "", - __FILE__, __FUNCTION__, - __LINE__, - currentProducerIndex, - aiInterface-> - getMyUnitCount (), i, - backupProducers.size ()); - throw - megaglest_runtime_error (szBuf); - } - if (prIndex >= - (int) backupProducers.size ()) - { - char - szBuf[8096] = ""; - printf - ("In [%s::%s Line: %d] prIndex >= backupProducers.size(), currentProducerIndex = %d, i = %u,backupProducers.size() = " - MG_SIZE_T_SPECIFIER " \n", __FILE__, - __FUNCTION__, __LINE__, prIndex, i, - backupProducers.size ()); - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] currentProducerIndex >= backupProducers.size(), currentProducerIndex = %d, i = %u,backupProducers.size() = " - MG_SIZE_T_SPECIFIER "", - __FILE__, __FUNCTION__, - __LINE__, - currentProducerIndex, i, - backupProducers.size ()); - throw - megaglest_runtime_error (szBuf); - } - - int - currentCommandCount = - aiInterface-> - getMyUnit (currentProducerIndex)-> - getCommandSize (); - if (currentCommandCount == 1 - && aiInterface-> - getMyUnit (currentProducerIndex)-> - getCurrCommand ()->getCommandType ()-> - getClass () == ccStop) - { // special for non buildings - currentCommandCount = 0; - } - if (lowestCommandCount > - currentCommandCount) - { - lowestCommandCount = - currentCommandCount; - bestIndex = currentProducerIndex; - if (lowestCommandCount == 0) - break; - } - } - // a good producer is found, lets choose a warrior production - vector < int > - productionCommandIndexes; - if (bestIndex >= 0) - { - const UnitType * - ut = - aiInterface->getMyUnit (bestIndex)-> - getType (); - for (int j = 0; - j < ut->getCommandTypeCount (); ++j) - { - const CommandType * - ct = ut->getCommandType (j); - - //if the command is produce - if (ct->getClass () == ccProduce) - { - const UnitType * - unitType = static_cast < const - UnitType * >(ct->getProduced ()); - if (unitType-> - hasSkillClass (scAttack) - && !unitType-> - hasCommandClass (ccHarvest) - && aiInterface->reqsOk (ct)) - { //this can produce a warrior - productionCommandIndexes. - push_back (j); - } - } - } - - int - commandIndex = - productionCommandIndexes[ai-> - getRandom ()-> - randRange (0, - (int) - productionCommandIndexes. - size - () - - 1)]; - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags:: - debugSystem, - "In [%s::%s Line: %d]\n", - __FILE__, - __FUNCTION__, - __LINE__); - - if (ai->outputAIBehaviourToConsole ()) - printf - ("zeta #1 produceSpecific giveCommand to unit [%s] commandType [%s]\n", - aiInterface->getMyUnit (bestIndex)-> - getType ()->getName ().c_str (), - ut->getCommandType (commandIndex)-> - getName ().c_str ()); - if (aiInterface->isLogLevelEnabled (4) == - true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "zeta #1 produceSpecific giveCommand to unit [%s] commandType [%s]", - aiInterface-> - getMyUnit (bestIndex)-> - getType ()->getName (). - c_str (), - ut-> - getCommandType - (commandIndex)->getName (). - c_str ()); - aiInterface->printLog (4, szBuf); - } - - aiInterface->giveCommand (bestIndex, - ut-> - getCommandType - (commandIndex)); - } - } - else - { // do it like normal CPU - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags:: - debugSystem, - "In [%s::%s Line: %d]\n", - __FILE__, - __FUNCTION__, - __LINE__); - defCt = NULL; - if (producersDefaultCommandType. - find (bestIndex) != - producersDefaultCommandType.end ()) - { - int - bestCommandTypeCount = - (int) - producersDefaultCommandType[bestIndex]. - size (); - int - bestCommandTypeIndex = - ai->getRandom ()->randRange (0, - bestCommandTypeCount - - 1); - - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags:: - debugSystem, - "In [%s::%s Line: %d] bestCommandTypeIndex = %d, bestCommandTypeCount = %d\n", - __FILE__, - __FUNCTION__, - __LINE__, - bestCommandTypeIndex, - bestCommandTypeCount); - - defCt = - producersDefaultCommandType[bestIndex] - [bestCommandTypeIndex]; - } - - if (ai->outputAIBehaviourToConsole ()) - printf - ("zeta #2 produceSpecific giveCommand to unit [%s] commandType [%s]\n", - aiInterface->getMyUnit (bestIndex)-> - getType ()->getName ().c_str (), - (defCt != - NULL ? defCt->getName (). - c_str () : "n/a")); - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "zeta #2 produceSpecific giveCommand to unit [%s] commandType [%s]", - aiInterface-> - getMyUnit (bestIndex)-> - getType ()->getName ().c_str (), - (defCt != - NULL ? defCt->getName (). - c_str () : "n/a")); - aiInterface->printLog (4, szBuf); - } - aiInterface->giveCommand (bestIndex, defCt); - } - } - else - { - if (currentCommandCount == 0) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags:: - debugSystem, - "In [%s::%s Line: %d]\n", - __FILE__, - __FUNCTION__, - __LINE__); - defCt = NULL; - if (producersDefaultCommandType. - find (bestIndex) != - producersDefaultCommandType.end ()) - { - //defCt = producersDefaultCommandType[bestIndex]; - int - bestCommandTypeCount = - (int) - producersDefaultCommandType[bestIndex]. - size (); - int - bestCommandTypeIndex = - ai->getRandom ()->randRange (0, - bestCommandTypeCount - - 1); - - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags:: - debugSystem, - "In [%s::%s Line: %d] bestCommandTypeIndex = %d, bestCommandTypeCount = %d\n", - __FILE__, - __FUNCTION__, - __LINE__, - bestCommandTypeIndex, - bestCommandTypeCount); - - defCt = - producersDefaultCommandType[bestIndex] - [bestCommandTypeIndex]; - } - - if (ai->outputAIBehaviourToConsole ()) - printf - ("zeta #3 produceSpecific giveCommand to unit [%s] commandType [%s]\n", - aiInterface->getMyUnit (bestIndex)-> - getType ()->getName ().c_str (), - (defCt != - NULL ? defCt->getName (). - c_str () : "n/a")); - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "zeta #3 produceSpecific giveCommand to unit [%s] commandType [%s]", - aiInterface-> - getMyUnit (bestIndex)-> - getType ()->getName ().c_str (), - (defCt != - NULL ? defCt->getName (). - c_str () : "n/a")); - aiInterface->printLog (4, szBuf); - } - - aiInterface->giveCommand (bestIndex, defCt); - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags:: - debugSystem, - "In [%s::%s Line: %d]\n", - __FILE__, __FUNCTION__, - __LINE__); - defCt = NULL; - if (producersDefaultCommandType.find (bestIndex) != - producersDefaultCommandType.end ()) - { - //defCt = producersDefaultCommandType[bestIndex]; - int - bestCommandTypeCount = - (int) producersDefaultCommandType[bestIndex]. - size (); - int - bestCommandTypeIndex = - ai->getRandom ()->randRange (0, - bestCommandTypeCount - - 1); - - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags:: - debugSystem, - "In [%s::%s Line: %d] bestCommandTypeIndex = %d, bestCommandTypeCount = %d\n", - __FILE__, - __FUNCTION__, - __LINE__, - bestCommandTypeIndex, - bestCommandTypeCount); - - defCt = - producersDefaultCommandType[bestIndex] - [bestCommandTypeIndex]; - } - if (ai->outputAIBehaviourToConsole ()) - printf - ("zeta #4 produceSpecific giveCommand to unit [%s] commandType [%s]\n", - aiInterface->getMyUnit (bestIndex)-> - getType ()->getName ().c_str (), - (defCt != - NULL ? defCt->getName ().c_str () : "n/a")); - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "zeta #4 produceSpecific giveCommand to unit [%s] commandType [%s]", - aiInterface->getMyUnit (bestIndex)-> - getType ()->getName ().c_str (), - (defCt != - NULL ? defCt->getName (). - c_str () : "n/a")); - aiInterface->printLog (4, szBuf); - } - - aiInterface->giveCommand (bestIndex, defCt); - } - } - } - else - { - int - pIndex = - ai->getRandom ()->randRange (0, - (int) producers.size () - 1); - int - producerIndex = producers[pIndex]; - defCt = NULL; - if (producersDefaultCommandType.find (producerIndex) != - producersDefaultCommandType.end ()) - { - //defCt = producersDefaultCommandType[producerIndex]; - int - bestCommandTypeCount = - (int) producersDefaultCommandType[producerIndex]. - size (); - int - bestCommandTypeIndex = - ai->getRandom ()->randRange (0, - bestCommandTypeCount - - 1); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] bestCommandTypeIndex = %d, bestCommandTypeCount = %d\n", - __FILE__, __FUNCTION__, - __LINE__, - bestCommandTypeIndex, - bestCommandTypeCount); - - defCt = - producersDefaultCommandType[producerIndex] - [bestCommandTypeIndex]; - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] producers.size() = %d, producerIndex = %d, pIndex = %d, producersDefaultCommandType.size() = %d\n", - __FILE__, __FUNCTION__, - __LINE__, producers.size (), - producerIndex, pIndex, - producersDefaultCommandType. - size ()); - - if (ai->outputAIBehaviourToConsole ()) - printf - ("produceSpecific giveCommand to unit [%s] commandType [%s]\n", - aiInterface->getMyUnit (producerIndex)->getType ()-> - getName ().c_str (), - (defCt != NULL ? defCt->getName ().c_str () : "n/a")); - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "produceSpecific giveCommand to unit [%s] commandType [%s]", - aiInterface->getMyUnit (producerIndex)-> - getType ()->getName ().c_str (), - (defCt != - NULL ? defCt->getName (). - c_str () : "(null)")); - aiInterface->printLog (4, szBuf); - } - aiInterface->giveCommand (producerIndex, defCt); - } - } - } - } - -// ======================================== -// class AiRuleBuild -// ======================================== - - AiRuleBuild::AiRuleBuild (Ai * ai): - AiRule (ai) - { - buildTask = NULL; - } - - bool - AiRuleBuild::test () - { - const Task * - task = ai->getTask (); - - if (task == NULL || task->getClass () != tcBuild) - { - return false; - } - - buildTask = static_cast < const BuildTask *>(task); - return true; - } - - - void - AiRuleBuild::execute () - { - if (buildTask != NULL) - { - if (ai->outputAIBehaviourToConsole ()) - printf ("BUILD AiRuleBuild Unit Name[%s]\n", - (buildTask->getUnitType () != - NULL ? buildTask->getUnitType ()->getName (false). - c_str () : "null")); - - //generic build task, build random building that can be built - if (buildTask->getUnitType () == NULL) - { - buildGeneric (buildTask); - } - //specific building task, build if possible, retry if not enough resources or not position - else - { - buildSpecific (buildTask); - } - - //remove the task - ai->removeTask (buildTask); - } - } - - void - AiRuleBuild::buildGeneric (const BuildTask * bt) - { - - //find buildings that can be built - AiInterface * - aiInterface = ai->getAiInterface (); - - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "== START: buildGeneric for resource type [%s]", - (bt->getResourceType () != - NULL ? bt->getResourceType ()->getName (). - c_str () : "null")); - aiInterface->printLog (4, szBuf); - } - - typedef - vector < const UnitType *> - UnitTypes; - UnitTypes - buildings; - - if (bt->getResourceType () != NULL) - { - if (aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcResourceProducerUnits).size () > 0) - { - const - std::vector < - FactionType::PairPUnitTypeInt > & - unitList = - aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcResourceProducerUnits); - for (unsigned int i = 0; i < unitList.size (); ++i) - { - const - FactionType::PairPUnitTypeInt & - priorityUnit = unitList[i]; - if (ai->getCountOfType (priorityUnit.first) < - priorityUnit.second - && aiInterface->getMyFaction ()-> - canCreateUnit (priorityUnit.first, true, false, - false) == true) - { - //if(ai->getRandom()->randRange(0, 1)==0) { - - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In buildGeneric for resource type [%s] aibcResourceProducerUnits = " - MG_SIZE_T_SPECIFIER - " priorityUnit.first: [%s]\n", - bt->getResourceType ()->getName (). - c_str (), unitList.size (), - priorityUnit.first->getName ().c_str ()); - aiInterface->printLog (4, szBuf); - } - - ai->addTask (new BuildTask (priorityUnit.first)); - return; - //} - } - } - } - } - else - { - if (aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcBuildingUnits).size () > 0) - { - const - std::vector < - FactionType::PairPUnitTypeInt > & - unitList = - aiInterface->getMyFactionType ()-> - getAIBehaviorUnits (aibcBuildingUnits); - for (unsigned int i = 0; i < unitList.size (); ++i) - { - const - FactionType::PairPUnitTypeInt & - priorityUnit = unitList[i]; - if (ai->getCountOfType (priorityUnit.first) < - priorityUnit.second - && aiInterface->getMyFaction ()-> - canCreateUnit (priorityUnit.first, true, false, - false) == true) - { - //if(ai->getRandom()->randRange(0, 1)==0) { - - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In buildGeneric for resource type [%s] aibcBuildingUnits = " - MG_SIZE_T_SPECIFIER - " priorityUnit.first: [%s]\n", - bt->getResourceType ()->getName (). - c_str (), unitList.size (), - priorityUnit.first->getName ().c_str ()); - aiInterface->printLog (4, szBuf); - } - - ai->addTask (new BuildTask (priorityUnit.first)); - return; - //} - } - } - } - } - - //for each unit - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - - //for each command - const UnitType * - ut = aiInterface->getMyUnit (i)->getType (); - for (int j = 0; j < ut->getCommandTypeCount (); ++j) - { - const CommandType * - ct = ut->getCommandType (j); - - //if the command is build - if (ct->getClass () == ccBuild) - { - const BuildCommandType * - bct = static_cast < const - BuildCommandType * >(ct); - - //for each building - for (int k = 0; k < bct->getBuildingCount (); ++k) - { - const UnitType * - building = bct->getBuilding (k); - if (aiInterface->reqsOk (bct) - && aiInterface->reqsOk (building)) - { - - //if any building, or produces resource - const ResourceType * - rt = bt->getResourceType (); - const Resource * - cost = building->getCost (rt); - if (rt == NULL - || (cost != NULL && cost->getAmount () < 0)) - { - if (find - (buildings.begin (), buildings.end (), - building) == buildings.end ()) - { - buildings.push_back (building); - } - } - } - } - } - } - } - - if (aiInterface->isLogLevelEnabled (4) == true) - { - for (int i = 0; i < (int) buildings.size (); ++i) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In buildGeneric i = %d unit type: [%s]\n", i, - buildings[i]->getName ().c_str ()); - aiInterface->printLog (4, szBuf); - } - } - - //add specific build task - buildBestBuilding (buildings); - } - - void - AiRuleBuild::buildBestBuilding (const vector < - const UnitType * >&buildings) - { - - AiInterface * - aiInterface = ai->getAiInterface (); - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "==> START buildBestBuilding buildings.size = " - MG_SIZE_T_SPECIFIER "\n", buildings.size ()); - aiInterface->printLog (4, szBuf); - } - - if (!buildings.empty ()) - { - - //build the least built building - bool - buildingFound = false; - for (int i = 0; i < 10 && !buildingFound; ++i) - { - - if (i > 0) - { - - //Defensive buildings have priority - for (int j = 0; - j < (int) buildings.size () && buildingFound == false; - ++j) - { - const UnitType * - building = buildings[j]; - if (ai->getCountOfType (building) <= i + 1 - && isDefensive (building)) - { - - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In buildBestBuilding defensive building unit type: [%s] i = %d j = %d\n", - building->getName ().c_str (), i, j); - aiInterface->printLog (4, szBuf); - } - - ai->addTask (new BuildTask (building)); - buildingFound = true; - } - } - - //Warrior producers next - for (unsigned int j = 0; - j < buildings.size () && !buildingFound; ++j) - { - const UnitType * - building = buildings[j]; - if (ai->getCountOfType (building) <= i + 1 - && isWarriorProducer (building)) - { - - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In buildBestBuilding warriorproducer building unit type: [%s] i = %d j = %u\n", - building->getName ().c_str (), i, j); - aiInterface->printLog (4, szBuf); - } - - ai->addTask (new BuildTask (building)); - buildingFound = true; - } - } - - //Resource producers next - for (unsigned int j = 0; - j < buildings.size () && !buildingFound; ++j) - { - const UnitType * - building = buildings[j]; - if (ai->getCountOfType (building) <= i + 1 - && isResourceProducer (building)) - { - - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In buildBestBuilding resourceproducer building unit type: [%s] i = %d j = %u\n", - building->getName ().c_str (), i, j); - aiInterface->printLog (4, szBuf); - } - - ai->addTask (new BuildTask (building)); - buildingFound = true; - } - } - } - - //Any building - for (unsigned int j = 0; - j < buildings.size () && !buildingFound; ++j) - { - const UnitType * - building = buildings[j]; - if (ai->getCountOfType (building) <= i) - { - - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In buildBestBuilding ANY building unit type: [%s] i = %d j = %u\n", - building->getName ().c_str (), i, j); - aiInterface->printLog (4, szBuf); - } - - ai->addTask (new BuildTask (building)); - buildingFound = true; - } - } - } - } - - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "==> END buildBestBuilding buildings.size = " - MG_SIZE_T_SPECIFIER "\n", buildings.size ()); - aiInterface->printLog (4, szBuf); - } - } - - void - AiRuleBuild::buildSpecific (const BuildTask * bt) - { - AiInterface * - aiInterface = ai->getAiInterface (); - - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "== START: buildSpecific for resource type [%s] bt->getUnitType() [%s]", - (bt->getResourceType () != - NULL ? bt->getResourceType ()->getName (). - c_str () : "null"), - (bt->getUnitType () != - NULL ? bt->getUnitType ()->getName (false). - c_str () : "null")); - aiInterface->printLog (4, szBuf); - } - - //if reqs ok - if (aiInterface->reqsOk (bt->getUnitType ())) - { - - //retry if not enough resources - if (aiInterface->checkCosts (bt->getUnitType (), NULL) == false) - { - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In buildSpecific for resource type [%s] checkcosts == false RETRYING", - (bt->getResourceType () != - NULL ? bt->getResourceType ()->getName (). - c_str () : "null")); - aiInterface->printLog (4, szBuf); - } - - ai->retryTask (bt); - return; - } - - vector < int > - builders; - // Hold a list of units which can build - // then a list of build commandtypes for each unit - map < int, - vector < const BuildCommandType *> > - buildersDefaultCommandType; - const BuildCommandType * - defBct = NULL; - - //for each unit - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - - //if the unit is not going to build - const Unit * - u = aiInterface->getMyUnit (i); - if (u->anyCommand () == false - || u->getCurrCommand ()->getCommandType ()->getClass () != - ccBuild) - { - - //for each command - const UnitType * - ut = aiInterface->getMyUnit (i)->getType (); - for (int j = 0; j < ut->getCommandTypeCount (); ++j) - { - const CommandType * - ct = ut->getCommandType (j); - - //if the command is build - if (ct->getClass () == ccBuild) - { - const BuildCommandType * - bct = static_cast < const - BuildCommandType * >(ct); - - //for each building - for (int k = 0; k < bct->getBuildingCount (); ++k) - { - const UnitType * - building = bct->getBuilding (k); - - //if building match - if (bt->getUnitType () == building) - { - if (aiInterface->reqsOk (bct)) - { - builders.push_back (i); - buildersDefaultCommandType[i]. - push_back (bct); - //defBct= bct; - } - } - } - } - } - } - } - - //use random builder to build - if (builders.empty () == false) - { - int - bIndex = - ai->getRandom ()->randRange (0, (int) builders.size () - 1); - int - builderIndex = builders[bIndex]; - Vec2i - pos; - Vec2i - searchPos = - bt->getForcePos ()? bt->getPos () : ai-> - getRandomHomePosition (); - if (bt->getForcePos () == false) - { - const int - enemySightDistanceToAvoid = 18; - vector < Unit * >enemies; - ai->getAiInterface ()->getWorld ()->getUnitUpdater ()-> - findEnemiesForCell (searchPos, - bt->getUnitType ()->getSize (), - enemySightDistanceToAvoid, - ai->getAiInterface ()-> - getMyFaction (), enemies, true); - if (enemies.empty () == false) - { - for (int i1 = 0; i1 < 25 && enemies.empty () == false; - ++i1) - { - for (int j1 = 0; - j1 < 25 && enemies.empty () == false; ++j1) - { - Vec2i - tryPos = searchPos + Vec2i (i1, j1); - - const int - spacing = 1; - if (ai->getAiInterface ()-> - isFreeCells (tryPos - Vec2i (spacing), - bt->getUnitType ()-> - getSize () + spacing * 2, - fLand)) - { - enemies.clear (); - ai->getAiInterface ()->getWorld ()-> - getUnitUpdater ()-> - findEnemiesForCell (tryPos, - bt->getUnitType ()-> - getSize (), - enemySightDistanceToAvoid, - ai-> - getAiInterface ()-> - getMyFaction (), - enemies, true); - if (enemies.empty () == true) - { - searchPos = tryPos; - } - } - } - } - } - if (enemies.empty () == false) - { - for (int i1 = -1; - i1 >= -25 && enemies.empty () == false; --i1) - { - for (int j1 = -1; - j1 >= -25 && enemies.empty () == false; --j1) - { - Vec2i - tryPos = searchPos + Vec2i (i1, j1); - - const int - spacing = 1; - if (ai->getAiInterface ()-> - isFreeCells (tryPos - Vec2i (spacing), - bt->getUnitType ()-> - getSize () + spacing * 2, - fLand)) - { - enemies.clear (); - ai->getAiInterface ()->getWorld ()-> - getUnitUpdater ()-> - findEnemiesForCell (tryPos, - bt->getUnitType ()-> - getSize (), - enemySightDistanceToAvoid, - ai-> - getAiInterface ()-> - getMyFaction (), - enemies, true); - if (enemies.empty () == true) - { - searchPos = tryPos; - } - } - } - } - } - } - - //if free pos give command, else retry - if (ai->findPosForBuilding (bt->getUnitType (), searchPos, pos)) - { - defBct = NULL; - if (buildersDefaultCommandType.find (builderIndex) != - buildersDefaultCommandType.end ()) - { - //defBct = buildersDefaultCommandType[builderIndex]; - int - bestCommandTypeCount = - (int) buildersDefaultCommandType[builderIndex]. - size (); - int - bestCommandTypeIndex = - ai->getRandom ()->randRange (0, - bestCommandTypeCount - - 1); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] bestCommandTypeIndex = %d, bestCommandTypeCount = %d\n", - __FILE__, __FUNCTION__, - __LINE__, - bestCommandTypeIndex, - bestCommandTypeCount); - - defBct = - buildersDefaultCommandType[builderIndex] - [bestCommandTypeIndex]; - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] builderIndex = %d, bIndex = %d, defBct = %p\n", - __FILE__, __FUNCTION__, - __LINE__, builderIndex, bIndex, - defBct); - - aiInterface->giveCommand (builderIndex, defBct, pos, - bt->getUnitType ()); - } - else - { - ai->retryTask (bt); - return; - } - } - } - else - { - if (aiInterface->isLogLevelEnabled (4) == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In buildSpecific for resource type [%s] reqsok == false", - (bt->getResourceType () != - NULL ? bt->getResourceType ()->getName (). - c_str () : "null")); - aiInterface->printLog (4, szBuf); - } - - } - } - - bool - AiRuleBuild::isDefensive (const UnitType * building) - { - if (ai->outputAIBehaviourToConsole ()) - printf ("BUILD isDefensive check for Unit Name[%s] result = %d\n", - building->getName (false).c_str (), - building->hasSkillClass (scAttack)); - - return building->hasSkillClass (scAttack); - } - - bool - AiRuleBuild::isResourceProducer (const UnitType * building) - { - for (int i = 0; i < building->getCostCount (); i++) - { - if (building->getCost (i)->getAmount () < 0) - { - if (ai->outputAIBehaviourToConsole ()) - printf - ("BUILD isResourceProducer check for Unit Name[%s] result = true\n", - building->getName (false).c_str ()); - - return true; - } - } - if (ai->outputAIBehaviourToConsole ()) - printf - ("BUILD isResourceProducer check for Unit Name[%s] result = false\n", - building->getName (false).c_str ()); - - return false; - } - - bool - AiRuleBuild::isWarriorProducer (const UnitType * building) - { - for (int i = 0; i < building->getCommandTypeCount (); i++) - { - const CommandType * - ct = building->getCommandType (i); - if (ct->getClass () == ccProduce) - { - const UnitType * - ut = static_cast < const - ProduceCommandType * >(ct)-> - getProducedUnit (); - - if (ut->isOfClass (ucWarrior)) - { - if (ai->outputAIBehaviourToConsole ()) - printf - ("BUILD isWarriorProducer check for Unit Name[%s] result = true\n", - building->getName (false).c_str ()); - - return true; - } - } - } - if (ai->outputAIBehaviourToConsole ()) - printf - ("BUILD isWarriorProducer check for Unit Name[%s] result = false\n", - building->getName (false).c_str ()); - - return false; - } - -// ======================================== -// class AiRuleUpgrade -// ======================================== - - AiRuleUpgrade::AiRuleUpgrade (Ai * ai): - AiRule (ai) - { - upgradeTask = NULL; - } - - bool - AiRuleUpgrade::test () - { - const Task * - task = ai->getTask (); - - if (task == NULL || task->getClass () != tcUpgrade) - { - return false; - } - - upgradeTask = static_cast < const UpgradeTask *>(task); - return true; - } - - void - AiRuleUpgrade::execute () - { - - //upgrade any upgrade - if (upgradeTask->getUpgradeType () == NULL) - { - upgradeGeneric (upgradeTask); - } - //upgrade specific upgrade - else - { - upgradeSpecific (upgradeTask); - } - - //remove the task - ai->removeTask (upgradeTask); - } - - void - AiRuleUpgrade::upgradeGeneric (const UpgradeTask * upgt) - { - - typedef - vector < const UpgradeType *> - UpgradeTypes; - AiInterface * - aiInterface = ai->getAiInterface (); - - //find upgrades that can be upgraded - UpgradeTypes - upgrades; - - if (aiInterface->getMyFactionType ()->getAIBehaviorUpgrades ().size () > - 0) - { - const - std::vector < const UpgradeType *>& - upgradeList = - aiInterface->getMyFactionType ()->getAIBehaviorUpgrades (); - for (unsigned int i = 0; i < upgradeList.size (); ++i) - { - const UpgradeType * - priorityUpgrade = upgradeList[i]; - - //for each upgrade, upgrade it if possible - for (int k = 0; k < aiInterface->getMyUnitCount (); ++k) - { - - //for each command - const UnitType * - ut = aiInterface->getMyUnit (k)->getType (); - for (int j = 0; j < ut->getCommandTypeCount (); ++j) - { - const CommandType * - ct = ut->getCommandType (j); - - //if the command is upgrade - if (ct->getClass () == ccUpgrade) - { - const UpgradeCommandType * - upgct = dynamic_cast < const - UpgradeCommandType * >(ct); - if (upgct != NULL) - { - const UpgradeType * - upgrade = upgct->getProducedUpgrade (); - if (upgrade == priorityUpgrade) - { - if (aiInterface->reqsOk (upgct) == true && - aiInterface->getMyFaction ()-> - getUpgradeManager ()-> - isUpgradingOrUpgraded (priorityUpgrade) - == false) - { - //if(ai->getRandom()->randRange(0, 1)==0) { - ai-> - addTask (new - UpgradeTask - (priorityUpgrade)); - return; - //} - } - } - } - } - } - } - } - } - - //for each upgrade, upgrade it if possible - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - - //for each command - const UnitType * - ut = aiInterface->getMyUnit (i)->getType (); - for (int j = 0; j < ut->getCommandTypeCount (); ++j) - { - const CommandType * - ct = ut->getCommandType (j); - - //if the command is upgrade - if (ct->getClass () == ccUpgrade) - { - const UpgradeCommandType * - upgct = static_cast < const - UpgradeCommandType * >(ct); - const UpgradeType * - upgrade = upgct->getProducedUpgrade (); - if (aiInterface->reqsOk (upgct)) - { - upgrades.push_back (upgrade); - } - } - } - } - - //add specific upgrade task - if (!upgrades.empty ()) - { - ai-> - addTask (new - UpgradeTask (upgrades - [ai->getRandom ()-> - randRange (0, - (int) upgrades.size () - 1)])); - } - } - - void - AiRuleUpgrade::upgradeSpecific (const UpgradeTask * upgt) - { - - AiInterface * - aiInterface = ai->getAiInterface (); - - //if reqs ok - if (aiInterface->reqsOk (upgt->getUpgradeType ())) - { - - //if resources dont meet retry - if (!aiInterface->checkCosts (upgt->getUpgradeType (), NULL)) - { - ai->retryTask (upgt); - return; - } - - //for each unit - for (int i = 0; i < aiInterface->getMyUnitCount (); ++i) - { - - //for each command - const UnitType * - ut = aiInterface->getMyUnit (i)->getType (); - for (int j = 0; j < ut->getCommandTypeCount (); ++j) - { - const CommandType * - ct = ut->getCommandType (j); - - //if the command is upgrade - if (ct->getClass () == ccUpgrade) - { - const UpgradeCommandType * - uct = static_cast < const - UpgradeCommandType * >(ct); - const UpgradeType * - producedUpgrade = uct->getProducedUpgrade (); - - //if upgrades match - if (producedUpgrade == upgt->getUpgradeType ()) - { - if (aiInterface->reqsOk (uct)) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags:: - debugSystem, - "In [%s::%s Line: %d]\n", - __FILE__, - __FUNCTION__, - __LINE__); - aiInterface->giveCommand (i, uct); - } - } - } - } - } - - } - } - -// ======================================== -// class AiRuleExpand -// ======================================== - - AiRuleExpand::AiRuleExpand (Ai * ai): - AiRule (ai) - { - storeType = NULL; - } - - bool - AiRuleExpand::test () - { - AiInterface * - aiInterface = ai->getAiInterface (); - - int - unitCount = aiInterface->getMyUnitCount (); - for (int i = 0; - i < aiInterface->getTechTree ()->getResourceTypeCount (); ++i) - { - const ResourceType * - rt = aiInterface->getTechTree ()->getResourceType (i); - if (rt->getClass () == rcTech) - { - bool - factionUsesResourceType = - aiInterface->factionUsesResourceType (aiInterface-> - getMyFactionType (), - rt); - if (factionUsesResourceType == true) - { - // If any resource sighted - if (aiInterface-> - getNearestSightedResource (rt, - aiInterface-> - getHomeLocation (), - expandPos, true)) - { - int - minDistance = INT_MAX; - storeType = NULL; - - //If there is no close store - for (int j = 0; j < unitCount; ++j) - { - const Unit * - u = aiInterface->getMyUnit (j); - const UnitType * - ut = u->getType (); - - // If this building is a store - if (ut->getStore (rt) > 0) - { - storeType = ut; - int - distance = - static_cast < - int >(u->getPosNotThreadSafe (). - dist (expandPos)); - if (distance < minDistance) - { - minDistance = distance; - } - } - } - - if (minDistance > expandDistance) - { - return true; - } - } - else - { - // send patrol to look for resource - ai->sendScoutPatrol (); - } - } - } - } - - return false; - } - - void - AiRuleExpand::execute () - { - ai->addExpansion (expandPos); - ai->addPriorityTask (new BuildTask (storeType, expandPos)); - } - - -// ======================================== -// class AiRuleUnBlock -// ======================================== - - AiRuleUnBlock::AiRuleUnBlock (Ai * ai): - AiRule (ai) - { - - } - - bool - AiRuleUnBlock::test () - { - return ai->haveBlockedUnits (); - } - - void - AiRuleUnBlock::execute () - { - ai->unblockUnits (); - } - -}} //end namespace + Glest { + namespace + Game { + + // ===================================================== + // class AiRule + // ===================================================== + + AiRule::AiRule(Ai * ai) { + this->ai = ai; + } + + // ===================================================== + // class AiRuleWorkerHarvest + // ===================================================== + + AiRuleWorkerHarvest::AiRuleWorkerHarvest(Ai * ai) : + AiRule(ai) { + stoppedWorkerIndex = -1; + } + + bool + AiRuleWorkerHarvest::test() { + return ai->findAbleUnit(&stoppedWorkerIndex, ccHarvest, true); + } + + void + AiRuleWorkerHarvest::execute() { + ai->harvest(stoppedWorkerIndex); + } + + // ===================================================== + // class AiRuleRefreshHarvester + // ===================================================== + + AiRuleRefreshHarvester::AiRuleRefreshHarvester(Ai * ai) : + AiRule(ai) { + workerIndex = -1; + } + + bool + AiRuleRefreshHarvester::test() { + return ai->findAbleUnit(&workerIndex, ccHarvest, ccHarvest); + } + + void + AiRuleRefreshHarvester::execute() { + ai->harvest(workerIndex); + } + + // ===================================================== + // class AiRuleScoutPatrol + // ===================================================== + + AiRuleScoutPatrol::AiRuleScoutPatrol(Ai * ai) : + AiRule(ai) { + } + + bool + AiRuleScoutPatrol::test() { + return ai->isStableBase(); + } + + void + AiRuleScoutPatrol::execute() { + ai->sendScoutPatrol(); + } + // ===================================================== + // class AiRuleRepair + // ===================================================== + + AiRuleRepair::AiRuleRepair(Ai * ai) : + AiRule(ai) { + damagedUnitIndex = 0; + damagedUnitIsCastle = false; + } + + double + AiRuleRepair::getMinCastleHpRatio() const { + return + 0.6; + } + + int + AiRuleRepair::getMinUnitsToRepairCastle() { + int + minUnitsRepairingCastle = 7; + if (ai->getCountOfClass(ucWorker) <= 6) { + minUnitsRepairingCastle = 1; + } else if (ai->getCountOfClass(ucWorker) <= 8) { + minUnitsRepairingCastle = 2; + } else if (ai->getCountOfClass(ucWorker) <= 10) { + minUnitsRepairingCastle = 3; + } else if (ai->getCountOfClass(ucWorker) <= 12) { + minUnitsRepairingCastle = 5; + } + return minUnitsRepairingCastle; + } + + bool + AiRuleRepair::test() { + AiInterface * + aiInterface = ai->getAiInterface(); + + int + minUnitsRepairingCastle = getMinUnitsToRepairCastle(); + const double + minCastleHpRatio = getMinCastleHpRatio(); + + // look for a damaged unit and give priority to the factions bases + // (units that produce workers and store resources) + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + const Unit * + u = aiInterface->getMyUnit(i); + //printf("\n\n\n\n!!!!!! Is damaged unit [%d - %s] u->getHpRatio() = %f, hp = %d, mapHp = %d\n",u->getId(),u->getType()->getName().c_str(),u->getHpRatio(),u->getHp(),u->getType()->getTotalMaxHp(u->getTotalUpgrade())); + if (u->getHpRatio() < 1.f) { + //printf("\n\n\n\n!!!!!! Is damaged unit [%d - %s] u->getHpRatio() = %f, hp = %d, mapHp = %d\n",u->getId(),u->getType()->getName().c_str(),u->getHpRatio(),u->getHp(),u->getType()->getTotalMaxHp(u->getTotalUpgrade())); + + bool + unitCanProduceWorker = false; + for (int j = 0; unitCanProduceWorker == false && + j < u->getType()->getCommandTypeCount(); ++j) { + const CommandType * + ct = u->getType()->getCommandType(j); + + //if the command is produce + if (ct->getClass() == ccProduce + || ct->getClass() == ccMorph) { + const ProducibleType * + pt = ct->getProduced(); + if (pt != NULL) { + const UnitType * + ut = dynamic_cast (pt); + if (ut != NULL + && ut->hasCommandClass(ccHarvest) == true + && u->getType()->getStoredResourceCount() > 0) { + //printf("\n\n\n\n!!!!!! found candidate castle unit to repair [%d - %s]\n",u->getId(),u->getType()->getName().c_str()); + unitCanProduceWorker = true; + } + } + } + } + + if (unitCanProduceWorker == true) { + int + candidatedamagedUnitIndex = -1; + int + unitCountAlreadyRepairingDamagedUnit = 0; + // Now check if any other unit is able to repair this unit + for (int i1 = 0; i1 < aiInterface->getMyUnitCount(); ++i1) { + const Unit * + u1 = aiInterface->getMyUnit(i1); + const RepairCommandType * + rct = static_cast (u1->getType()->getFirstCtOfClass(ccRepair)); + //if(rct) printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can reapir damaged unit [%d]\n",u1->getId(),u1->getType()->getName().c_str(),u->getCurrSkill()->getClass(),rct->isRepairableUnitType(u->getType())); + + if (rct != NULL) { + //printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can repair damaged unit [%d] Castles hp-ratio = %f\n",u1->getId(),u1->getType()->getName().c_str(),u1->getCurrSkill()->getClass(),rct->isRepairableUnitType(u->getType()),u->getHpRatio()); + + if (u1->getCurrSkill()->getClass() == scStop + || u1->getCurrSkill()->getClass() == scMove + || u->getHpRatio() <= minCastleHpRatio) { + if (rct->isRepairableUnitType(u->getType())) { + candidatedamagedUnitIndex = i; + //return true; + } + } else if (u1->getCurrSkill()->getClass() == + scRepair) { + Command * + cmd = u1->getCurrCommand(); + if (cmd != NULL + && cmd->getCommandType()->getClass() == + ccRepair) { + if (cmd->getUnit() != NULL + && cmd->getUnit()->getId() == + u->getId()) { + //printf("\n\n\n\n^^^^^^^^^^ unit is ALREADY repairer unit [%d - %s]\n",u1->getId(),u1->getType()->getName().c_str()); + unitCountAlreadyRepairingDamagedUnit++; + } + } + } + } + } + + if (candidatedamagedUnitIndex >= 0 + && unitCountAlreadyRepairingDamagedUnit < + minUnitsRepairingCastle) { + //printf("\n\n\n\n^^^^^^^^^^ AI test will repair damaged unit [%d - %s]\n",u->getId(),u->getType()->getName().c_str()); + damagedUnitIndex = candidatedamagedUnitIndex; + damagedUnitIsCastle = true; + return true; + } + } + } + } + damagedUnitIsCastle = false; + damagedUnitIndex = -1; + // Normal Repair checking + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + const Unit * + u = aiInterface->getMyUnit(i); + //printf("\n\n\n\n!!!!!! Is damaged unit [%d - %s] u->getHpRatio() = %f, hp = %d, mapHp = %d\n",u->getId(),u->getType()->getName().c_str(),u->getHpRatio(),u->getHp(),u->getType()->getTotalMaxHp(u->getTotalUpgrade())); + if (u->getHpRatio() < 1.f) { + // Now check if any other unit is able to repair this unit + for (int i1 = 0; i1 < aiInterface->getMyUnitCount(); ++i1) { + const Unit * + u1 = aiInterface->getMyUnit(i1); + const RepairCommandType * + rct = static_cast (u1->getType()->getFirstCtOfClass(ccRepair)); + //if(rct) printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can reapir damaged unit [%d]\n",u1->getId(),u1->getType()->getName().c_str(),u->getCurrSkill()->getClass(),rct->isRepairableUnitType(u->getType())); + + if (rct != NULL + && (u1->getCurrSkill()->getClass() == scStop + || u1->getCurrSkill()->getClass() == scMove)) { + if (rct->isRepairableUnitType(u->getType())) { + damagedUnitIndex = i; + //random if return or not so we get different targets from time to time + if (ai->getRandom()->randRange(0, 1) == 0) + return true; + } + } + } + } + } + if (damagedUnitIndex != -1) { + return true; + } + return false; + } + + void + AiRuleRepair::execute() { + AiInterface * + aiInterface = ai->getAiInterface(); + const Unit * + damagedUnit = aiInterface->getMyUnit(damagedUnitIndex); + //printf("\n\n\n\n###^^^^^^^^^^ Looking for repairer for damaged unit [%d - %s]\n",damagedUnit->getId(),damagedUnit->getType()->getName().c_str()); + + int + minUnitsRepairingCastle = getMinUnitsToRepairCastle(); + const double + minCastleHpRatio = getMinCastleHpRatio(); + + if (minUnitsRepairingCastle > 2) { + if (damagedUnit->getCurrSkill()->getClass() == scBeBuilt) { // if build is still be build 2 helpers are enough + minUnitsRepairingCastle = 2; + } + + if (!damagedUnitIsCastle) { + minUnitsRepairingCastle = 2; + } + } + if (aiInterface->getControlType() == ctCpuEasy || + aiInterface->getControlType() == ctNetworkCpuEasy) { + if (!damagedUnitIsCastle) { + // cpu easy does not repair! + minUnitsRepairingCastle = 0; + } + } + if (aiInterface->getControlType() == ctCpu || + aiInterface->getControlType() == ctNetworkCpu) { + if (!damagedUnitIsCastle) { + // cpu does only repair with one unit! + minUnitsRepairingCastle = 1; + } + } + int + unitCountAlreadyRepairingDamagedUnit = 0; + //printf("team %d has damaged unit\n", damagedUnit->getTeam()); + // Now check if any other unit is able to repair this unit + for (int i1 = 0; i1 < aiInterface->getMyUnitCount(); ++i1) { + const Unit * + u1 = aiInterface->getMyUnit(i1); + const RepairCommandType * + rct = static_cast (u1->getType()->getFirstCtOfClass(ccRepair)); + //if(rct) printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can reapir damaged unit [%d]\n",u1->getId(),u1->getType()->getName().c_str(),u1->getCurrSkill()->getClass(),rct->isRepairableUnitType(u1->getType())); + Command * + cmd = u1->getCurrCommand(); + if (cmd != NULL && cmd->getCommandType()->getClass() == ccRepair) { + //if(cmd->getUnit() != NULL && cmd->getUnit()->getId() == damagedUnit->getId()) + //if(cmd->getUnit() != NULL && cmd->getPos() == damagedUnit->getPosWithCellMapSet()) + + if (rct != NULL) { + //printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can repair damaged unit [%d] Castles hp-ratio = %f\n",u1->getId(),u1->getType()->getName().c_str(),u1->getCurrSkill()->getClass(),rct->isRepairableUnitType(u->getType()),u->getHpRatio()); + + if (((RepairCommandType *) (cmd->getCommandType()))-> + isRepairableUnitType(damagedUnit->getType())) { + //printf("^^^^test^^^^^^ unit is ALREADY repairer unit [%d - %s]\nminUnitsRepairingCastle=%d\n",u1->getId(), u1->getType()->getName().c_str(), minUnitsRepairingCastle); + unitCountAlreadyRepairingDamagedUnit++; + } + } + } + } + + if (unitCountAlreadyRepairingDamagedUnit >= minUnitsRepairingCastle) { + return; + } + + int + unitGroupCommandId = -1; + + //find a repairer and issue command + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + const Unit * + u = aiInterface->getMyUnit(i); + const RepairCommandType * + rct = static_cast (u->getType()->getFirstCtOfClass(ccRepair)); + //if(rct) printf("\n\n\n\n^^^^^^^^^^ possible repairer unit [%d - %s] current skill [%d] can reapir damaged unit [%d]\n",u->getId(),u->getType()->getName().c_str(),u->getCurrSkill()->getClass(),rct->isRepairableUnitType(damagedUnit->getType())); + + if (rct != NULL) { + //printf("\n\n\n\n^^^^^^^^^^ possible excute repairer unit [%d - %s] current skill [%d] can repair damaged unit [%d] Castles hp-ratio = %f\n",u->getId(),u->getType()->getName().c_str(),u->getCurrSkill()->getClass(),rct->isRepairableUnitType(damagedUnit->getType()),damagedUnit->getHpRatio()); + + if ((u->getCurrSkill()->getClass() == scStop + || u->getCurrSkill()->getClass() == scMove + || damagedUnit->getHpRatio() <= minCastleHpRatio)) { + if ((u->getCurrCommand() == NULL + || (u->getCurrCommand()->getCommandType()-> + getClass() != ccBuild + && u->getCurrCommand()->getCommandType()-> + getClass() != ccProduce)) + && rct->isRepairableUnitType(damagedUnit->getType())) { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //printf("\n\n\n\n^^^^^^^^^^ AI execute will repair damaged unit [%d - %s] at pos [%s] cellmapPos [%s] using unit [%d -%s]\n",damagedUnit->getId(),damagedUnit->getType()->getName().c_str(),damagedUnit->getPos().getString().c_str(),damagedUnit->getPosWithCellMapSet().getString().c_str(),u->getId(),u->getType()->getName().c_str()); + + /* + Map *map= aiInterface->getWorld()->getMap(); + Cell *cell = map->getCell(damagedUnit->getPosWithCellMapSet()); + if(cell != NULL) { + printf("\n\n\n\n^^^^^^^^^^ cell is ok\n"); + + Unit *cellUnit = cell->getUnit(damagedUnit->getCurrField()); + if(cellUnit != NULL) { + printf("\n\n\n\n^^^^^^^^^^ cell unit [%d - %s] at pos [%s]\n",cellUnit->getId(),cellUnit->getType()->getName().c_str(),cellUnit->getPos().getString().c_str()); + } + } + */ + + //aiInterface->giveCommand(i, rct, damagedUnit->getPos()); + if (unitCountAlreadyRepairingDamagedUnit < + minUnitsRepairingCastle) { + + if (unitGroupCommandId == -1) { + unitGroupCommandId = + aiInterface->getWorld()-> + getNextCommandGroupId(); + } + + aiInterface->giveCommand(i, rct, + damagedUnit-> + getPosWithCellMapSet(), + unitGroupCommandId); + if (aiInterface->isLogLevelEnabled(3) == true) + aiInterface->printLog(3, + "Repairing order issued"); + unitCountAlreadyRepairingDamagedUnit++; + // printf( + // "^^^^^^^^^^adding one unit to repair ... unitCountAlreadyRepairingDamagedUnit/minUnitsRepairingCastle=%d/%d\n", + // unitCountAlreadyRepairingDamagedUnit, minUnitsRepairingCastle); + } + + if (!damagedUnitIsCastle + || unitCountAlreadyRepairingDamagedUnit >= + minUnitsRepairingCastle) { + return; + } + } + } + } + } + } + + // ===================================================== + // class AiRuleReturnBase + // ===================================================== + + AiRuleReturnBase::AiRuleReturnBase(Ai * ai) : + AiRule(ai) { + stoppedUnitIndex = -1; + } + + bool + AiRuleReturnBase::test() { + return ai->findAbleUnit(&stoppedUnitIndex, ccMove, true); + } + + void + AiRuleReturnBase::execute() { + ai->returnBase(stoppedUnitIndex); + } + + // ===================================================== + // class AiRuleMassiveAttack + // ===================================================== + + AiRuleMassiveAttack::AiRuleMassiveAttack(Ai * ai) : + AiRule(ai) { + ultraAttack = false; + field = fLand; + } + + bool + AiRuleMassiveAttack::test() { + + if (ai->isStableBase()) { + ultraAttack = false; + return ai->beingAttacked(attackPos, field, INT_MAX); + } else { + ultraAttack = true; + return ai->beingAttacked(attackPos, field, baseRadius); + } + } + + void + AiRuleMassiveAttack::execute() { + ai->massiveAttack(attackPos, field, ultraAttack); + } + // ===================================================== + // class AiRuleAddTasks + // ===================================================== + + AiRuleAddTasks::AiRuleAddTasks(Ai * ai) : + AiRule(ai) { + } + + bool + AiRuleAddTasks::test() { + return !ai->anyTask() || ai->getCountOfClass(ucWorker) < 4; + } + + // This function is what triggers the AI to create new units. + void + AiRuleAddTasks::execute() { + int + buildingCount = ai->getCountOfClass(ucBuilding); + UnitClass + ucWorkerType = ucWorker; + int + warriorCount = ai->getCountOfClass(ucWarrior, &ucWorkerType); + int + workerCount = ai->getCountOfClass(ucWorker); + int + upgradeCount = ai->getAiInterface()->getMyUpgradeCount(); + + float + buildingRatio = ai->getRatioOfClass(ucBuilding); + float + warriorRatio = ai->getRatioOfClass(ucWarrior); + float + workerRatio = ai->getRatioOfClass(ucWorker); + + //standard tasks + if (ai->outputAIBehaviourToConsole()) + printf + ("Add a TASK - AiRuleAddTasks adding ProduceTask(ucWorker) workerCount = %d, RULE Name[%s]\n", + workerCount, this->getName().c_str()); + + //emergency workers + if (workerCount < 4) { + if (ai->outputAIBehaviourToConsole()) + printf + ("AAA AiRuleAddTasks adding ProduceTask(ucWorker) workerCount = %d, RULE Name[%s]\n", + workerCount, this->getName().c_str()); + + ai->addPriorityTask(new ProduceTask(ucWorker)); + } + // The following rules are specific creation rules for different AI. + else { + if (ai->getAiInterface()->getControlType() == ctCpuZeta || + ai->getAiInterface()->getControlType() == ctNetworkCpuZeta) { + if (ai->outputAIBehaviourToConsole()) + printf + ("AAA AiRuleAddTasks adding #1 workerCount = %d[%.2f], buildingCount = %d[%.2f] warriorCount = %d[%.2f] upgradeCount = %d RULE Name[%s]\n", + workerCount, workerRatio, buildingCount, buildingRatio, + warriorCount, warriorRatio, upgradeCount, + this->getName().c_str()); + + //workers + if (workerCount < 5) + ai->addTask(new ProduceTask(ucWorker)); + if (workerCount < 10) + ai->addTask(new ProduceTask(ucWorker)); + if (workerRatio < 0.20) + ai->addTask(new ProduceTask(ucWorker)); + if (workerRatio < 0.30) + ai->addTask(new ProduceTask(ucWorker)); + + //warriors + if (warriorCount < 10) + ai->addTask(new ProduceTask(ucWarrior)); + if (warriorRatio < 0.20) + ai->addTask(new ProduceTask(ucWarrior)); + if (warriorRatio < 0.30) + ai->addTask(new ProduceTask(ucWarrior)); + if (workerCount >= 10) + ai->addTask(new ProduceTask(ucWarrior)); + if (workerCount >= 15) + ai->addTask(new ProduceTask(ucWarrior)); + if (warriorCount < ai->getMinWarriors() + 2) { + ai->addTask(new ProduceTask(ucWarrior)); + if (buildingCount > 9) { + ai->addTask(new ProduceTask(ucWarrior)); + ai->addTask(new ProduceTask(ucWarrior)); + } + if (buildingCount > 12) { + ai->addTask(new ProduceTask(ucWarrior)); + ai->addTask(new ProduceTask(ucWarrior)); + } + } + + //buildings + if (buildingCount < 6 || buildingRatio < 0.20) + ai->addTask(new BuildTask((UnitType *) NULL)); + if (buildingCount < 10 && workerCount > 12) + ai->addTask(new BuildTask((UnitType *) NULL)); + //upgrades + if (upgradeCount == 0 && workerCount > 5) + ai->addTask(new UpgradeTask((const UpgradeType *) NULL)); + if (upgradeCount == 1 && workerCount > 10) + ai->addTask(new UpgradeTask((const UpgradeType *) NULL)); + if (upgradeCount == 2 && workerCount > 15) + ai->addTask(new UpgradeTask((const UpgradeType *) NULL)); + if (ai->isStableBase()) + ai->addTask(new UpgradeTask((const UpgradeType *) NULL)); + } else if (ai->getAiInterface()->getControlType() == ctCpuEasy || + ai->getAiInterface()->getControlType() == + ctNetworkCpuEasy) { // Easy CPU + + if (ai->outputAIBehaviourToConsole()) + printf + ("AAA AiRuleAddTasks adding #2 workerCount = %d[%.2f], buildingCount = %d[%.2f] warriorCount = %d[%.2f] upgradeCount = %d RULE Name[%s]\n", + workerCount, workerRatio, buildingCount, buildingRatio, + warriorCount, warriorRatio, upgradeCount, + this->getName().c_str()); + + //workers + if (workerCount < buildingCount + 2) + ai->addTask(new ProduceTask(ucWorker)); + if (workerCount > 5 && workerRatio < 0.20) + ai->addTask(new ProduceTask(ucWorker)); + + //warriors + if (warriorCount < 10) + ai->addTask(new ProduceTask(ucWarrior)); + if (warriorRatio < 0.20) + ai->addTask(new ProduceTask(ucWarrior)); + if (warriorRatio < 0.30) + ai->addTask(new ProduceTask(ucWarrior)); + if (workerCount >= 10) + ai->addTask(new ProduceTask(ucWarrior)); + if (workerCount >= 15) + ai->addTask(new ProduceTask(ucWarrior)); + + //buildings + if (buildingCount < 6 || buildingRatio < 0.20) + ai->addTask(new BuildTask((UnitType *) NULL)); + if (buildingCount < 10 && ai->isStableBase()) + ai->addTask(new BuildTask((UnitType *) NULL)); + + //upgrades + if (upgradeCount == 0 && workerCount > 6) + ai->addTask(new UpgradeTask((const UpgradeType *) NULL)); + if (upgradeCount == 1 && workerCount > 7) + ai->addTask(new UpgradeTask((const UpgradeType *) NULL)); + if (upgradeCount == 2 && workerCount > 9) + ai->addTask(new UpgradeTask((const UpgradeType *) NULL)); + //if(ai->isStableBase()) ai->addTask(new UpgradeTask()); + } else { // normal CPU / UltraCPU ... + if (ai->outputAIBehaviourToConsole()) + printf + ("AAA AiRuleAddTasks adding #3 workerCount = %d[%.2f], buildingCount = %d[%.2f] warriorCount = %d[%.2f] upgradeCount = %d RULE Name[%s]\n", + workerCount, workerRatio, buildingCount, buildingRatio, + warriorCount, warriorRatio, upgradeCount, + this->getName().c_str()); + + //workers + if (workerCount < 5) + ai->addTask(new ProduceTask(ucWorker)); + if (workerCount < 10) + ai->addTask(new ProduceTask(ucWorker)); + if (workerRatio < 0.20) + ai->addTask(new ProduceTask(ucWorker)); + if (workerRatio < 0.30) + ai->addTask(new ProduceTask(ucWorker)); + + //warriors + if (warriorCount < 10) + ai->addTask(new ProduceTask(ucWarrior)); + if (warriorRatio < 0.20) + ai->addTask(new ProduceTask(ucWarrior)); + if (warriorRatio < 0.30) + ai->addTask(new ProduceTask(ucWarrior)); + if (workerCount >= 10) + ai->addTask(new ProduceTask(ucWarrior)); + if (workerCount >= 15) + ai->addTask(new ProduceTask(ucWarrior)); + + //buildings + if (buildingCount < 6 || buildingRatio < 0.20) + ai->addTask(new BuildTask((UnitType *) NULL)); + if (buildingCount < 10 && workerCount > 12) + ai->addTask(new BuildTask((UnitType *) NULL)); + + //upgrades + if (upgradeCount == 0 && workerCount > 5) + ai->addTask(new UpgradeTask((const UpgradeType *) NULL)); + if (upgradeCount == 1 && workerCount > 10) + ai->addTask(new UpgradeTask((const UpgradeType *) NULL)); + if (upgradeCount == 2 && workerCount > 15) + ai->addTask(new UpgradeTask((const UpgradeType *) NULL)); + if (ai->isStableBase()) + ai->addTask(new UpgradeTask((const UpgradeType *) NULL)); + } + } + } + + // ===================================================== + // class AiRuleBuildOneFarm + // ===================================================== + + AiRuleBuildOneFarm::AiRuleBuildOneFarm(Ai * ai) : + AiRule(ai) { + farm = NULL; + } + + bool + AiRuleBuildOneFarm::test() { + AiInterface * + aiInterface = ai->getAiInterface(); + + //for all units + for (int i = 0; + i < aiInterface->getMyFactionType()->getUnitTypeCount(); ++i) { + const UnitType * + ut = aiInterface->getMyFactionType()->getUnitType(i); + + //for all production commands + for (int j = 0; j < ut->getCommandTypeCount(); ++j) { + const CommandType * + ct = ut->getCommandType(j); + if (ct->getClass() == ccProduce) { + const UnitType * + producedType = static_cast (ct)-> + getProducedUnit(); + + //for all resources + for (int k = 0; k < producedType->getCostCount(); ++k) { + const Resource * + r = producedType->getCost(k); + + //find a food producer in the farm produced units + if (r->getAmount() < 0 + && r->getType()->getClass() == rcConsumable + && ai->getCountOfType(ut) == 0) { + if (aiInterface->reqsOk(ct) + && aiInterface->getMyFaction()-> + canCreateUnit(ut, true, true, true) == true) { + farm = ut; + //printf("AiRuleBuildOneFarm returning true, RULE Name[%s] ut [%s] producedType [%s]\n",this->getName().c_str(),ut->getName().c_str(),producedType->getName().c_str()); + + if (ai->outputAIBehaviourToConsole()) + printf + ("AiRuleBuildOneFarm returning true, RULE Name[%s]\n", + this->getName().c_str()); + + return true; + } + } + } + } + } + } + return false; + } + + void + AiRuleBuildOneFarm::execute() { + ai->addPriorityTask(new BuildTask(farm)); + } + + // ===================================================== + // class AiRuleProduceResourceProducer + // ===================================================== + + AiRuleProduceResourceProducer::AiRuleProduceResourceProducer(Ai * ai) : + AiRule(ai) { + interval = shortInterval; + rt = NULL; + newResourceBehaviour = + Config::getInstance().getBool("NewResourceBehaviour", "false");; + } + + bool + AiRuleProduceResourceProducer::test() { + //emergency tasks: resource buildings + AiInterface * + aiInterface = ai->getAiInterface(); + + //consumables first + for (int i = 0; + i < aiInterface->getTechTree()->getResourceTypeCount(); ++i) { + rt = aiInterface->getTechTree()->getResourceType(i); + const Resource * + r = aiInterface->getResource(rt); + + if (ai->outputAIBehaviourToConsole()) + printf("CONSUMABLE [%s][%d] Testing AI RULE Name[%s]\n", + rt->getName().c_str(), r->getBalance(), + this->getName().c_str()); + + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "CONSUMABLE [%s][%d] Testing AI RULE Name[%s]", + rt->getName().c_str(), r->getBalance(), + this->getName().c_str()); + aiInterface->printLog(4, szBuf); + } + + bool + factionUsesResourceType = + aiInterface->factionUsesResourceType(aiInterface-> + getMyFactionType(), rt); + if (factionUsesResourceType == true + && rt->getClass() == rcConsumable) { + // The consumable balance is negative + if (r->getBalance() < 0) { + if (newResourceBehaviour == true) { + interval = shortInterval; + } else { + interval = longInterval; + } + + return true; + } + // If the consumable balance is down to 1/3 of what we need + else { + if (r->getBalance() * 3 + r->getAmount() < 0) { + if (newResourceBehaviour == true) { + interval = shortInterval; + } else { + interval = longInterval; + } + + return true; + } + } + } + } + + int + targetStaticResourceCount = minStaticResources; + if (aiInterface->getMyFactionType()-> + getAIBehaviorStaticOverideValue(aibsvcMinStaticResourceCount) != + INT_MAX) { + targetStaticResourceCount = + aiInterface->getMyFactionType()-> + getAIBehaviorStaticOverideValue(aibsvcMinStaticResourceCount); + } + + //statics second + for (int i = 0; + i < aiInterface->getTechTree()->getResourceTypeCount(); ++i) { + rt = aiInterface->getTechTree()->getResourceType(i); + const Resource * + r = aiInterface->getResource(rt); + + if (ai->outputAIBehaviourToConsole()) + printf("STATIC [%s][%d] [min %d] Testing AI RULE Name[%s]\n", + rt->getName().c_str(), r->getAmount(), + targetStaticResourceCount, this->getName().c_str()); + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "STATIC resource check [%s][%d] [min %d] Testing AI RULE Name[%s]", + rt->getName().c_str(), r->getAmount(), + targetStaticResourceCount, this->getName().c_str()); + aiInterface->printLog(4, szBuf); + } + + if (rt->getClass() == rcStatic + && r->getAmount() < targetStaticResourceCount) { + bool + factionUsesResourceType = + aiInterface->factionUsesResourceType(aiInterface-> + getMyFactionType(), + rt); + if (factionUsesResourceType == true) { + if (newResourceBehaviour == true) + interval = shortInterval; + else + interval = longInterval; + return true; + } + } + } + + if (ai->outputAIBehaviourToConsole()) + printf("STATIC returning FALSE\n"); + if (aiInterface->isLogLevelEnabled(4) == true) + aiInterface->printLog(4, "Static Resource check returning FALSE"); + + if (newResourceBehaviour == true) + interval = longInterval; + else + interval = shortInterval; + return false; + } + + void + AiRuleProduceResourceProducer::execute() { + ai->addPriorityTask(new ProduceTask(rt)); + ai->addTask(new BuildTask(rt)); + } + + // ===================================================== + // class AiRuleProduce + // ===================================================== + + AiRuleProduce::AiRuleProduce(Ai * ai) : + AiRule(ai) { + produceTask = NULL; + newResourceBehaviour = + Config::getInstance().getBool("NewResourceBehaviour", "false"); + } + + bool + AiRuleProduce::test() { + const Task * + task = ai->getTask(); + + if (task == NULL || task->getClass() != tcProduce) { + return false; + } + + produceTask = static_cast (task); + return true; + } + + void + AiRuleProduce::execute() { + AiInterface * + aiInterface = ai->getAiInterface(); + if (produceTask != NULL) { + + if (ai->outputAIBehaviourToConsole()) + printf("AiRuleProduce producing [%s]\n", + (produceTask->getUnitType() != + NULL ? produceTask->getUnitType()->getName(false). + c_str() : "null")); + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "AiRuleProduce producing [%s]", + (produceTask->getUnitType() != + NULL ? produceTask->getUnitType()->getName(false). + c_str() : "null")); + aiInterface->printLog(4, szBuf); + } + + //generic produce task, produce random unit that has the skill or produces the resource + if (produceTask->getUnitType() == NULL) { + if (newResourceBehaviour) { + produceGenericNew(produceTask); + } else + produceGeneric(produceTask); + } + + //specific produce task, produce if possible, retry if not enough resources + else { + produceSpecific(produceTask); + } + + //remove the task + ai->removeTask(produceTask); + } + } + + bool + AiRuleProduce::canUnitTypeOfferResourceType(const UnitType * ut, + const ResourceType * rt) { + bool + unitTypeOffersResourceType = false; + + AiInterface * + aiInterface = ai->getAiInterface(); + + if (ut != NULL && rt != NULL && aiInterface != NULL + && aiInterface->reqsOk(ut)) { + // Check of the unit 'gives' the resource + // if the unit produces the resource + const Resource * + r = ut->getCost(rt); + if (r != NULL) { + if (ai->outputAIBehaviourToConsole()) + printf + ("#2 produceGeneric r = [%s][%d] Testing AI RULE Name[%s]\n", + r->getDescription(false).c_str(), r->getAmount(), + this->getName().c_str()); + } + + if (r != NULL && r->getAmount() < 0) { + unitTypeOffersResourceType = true; + } else { + // for each command check if we produce a unit that handles the resource + for (int commandIndex = 0; + commandIndex < ut->getCommandTypeCount(); ++commandIndex) { + const CommandType * + ct = ut->getCommandType(commandIndex); + + //if the command is produce + if (ct->getClass() == ccProduce + || ct->getClass() == ccMorph) { + const UnitType * + producedUnit = static_cast (ct->getProduced()); + + if (ai->outputAIBehaviourToConsole()) + printf + ("produceGeneric [%p] Testing AI RULE Name[%s]\n", + rt, this->getName().c_str()); + + //if the unit produces the resource + const Resource * + r = producedUnit->getCost(rt); + if (r != NULL) { + if (ai->outputAIBehaviourToConsole()) + printf + ("produceGeneric r = [%s][%d] Testing AI RULE Name[%s]\n", + r->getDescription(false).c_str(), + r->getAmount(), this->getName().c_str()); + } + + if (r != NULL && r->getAmount() < 0) { + unitTypeOffersResourceType = true; + break; + } + } + } + } + } + + if (aiInterface != NULL && aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "canUnitTypeOfferResourceType for unit type [%s] for resource type [%s] returned: %d", + (ut != NULL ? ut->getName(false).c_str() : "n/a"), + (rt != NULL ? rt->getName(false).c_str() : "n/a"), + unitTypeOffersResourceType); + aiInterface->printLog(4, szBuf); + } + + return unitTypeOffersResourceType; + } + + bool + AiRuleProduce::setAIProduceTaskForResourceType(const ProduceTask * pt, + AiInterface * aiInterface) { + bool + taskAdded = false; + if (aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcResourceProducerUnits).size() > 0) { + const + std::vector < + FactionType::PairPUnitTypeInt > & + unitList = + aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcResourceProducerUnits); + for (unsigned int i = 0; i < unitList.size(); ++i) { + const + FactionType::PairPUnitTypeInt & + priorityUnit = unitList[i]; + const UnitType * + ut = priorityUnit.first; + if (ai->getCountOfType(ut) < priorityUnit.second && + canUnitTypeOfferResourceType(ut, + pt->getResourceType()) == + true + && aiInterface->getMyFaction()-> + canCreateUnit(priorityUnit.first, false, true, + true) == true) { + ai->addTask(new ProduceTask(priorityUnit.first)); + taskAdded = true; + break; + } + } + } + + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "setAIProduceTaskForResourceType for resource type [%s] returned: %d", + pt->getResourceType()->getName(false).c_str(), + taskAdded); + aiInterface->printLog(4, szBuf); + } + + return taskAdded; + } + + void + AiRuleProduce::addUnitTypeToCandidates(const UnitType * producedUnit, + UnitTypes & ableUnits, + UnitTypesGiveBack & + ableUnitsGiveBack, + bool unitCanGiveBackResource) { + // if the unit is not already on the list + if (find(ableUnits.begin(), ableUnits.end(), producedUnit) == + ableUnits.end()) { + ableUnits.push_back(producedUnit); + ableUnitsGiveBack.push_back(unitCanGiveBackResource); + + AiInterface * + aiInterface = ai->getAiInterface(); + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "addUnitTypeToCandidates for unit type [%s] unitCanGiveBackResource = %d", + producedUnit->getName(false).c_str(), + unitCanGiveBackResource); + aiInterface->printLog(4, szBuf); + } + + } + } + + void + AiRuleProduce::produceGenericNew(const ProduceTask * pt) { + UnitTypes + ableUnits; + UnitTypesGiveBack + ableUnitsGiveBack; + + AiInterface * + aiInterface = ai->getAiInterface(); + if (pt->getResourceType() != NULL) { + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "****START: produceGeneric for resource type [%s]", + pt->getResourceType()->getName(false).c_str()); + aiInterface->printLog(4, szBuf); + } + + if (setAIProduceTaskForResourceType(pt, aiInterface) == true) { + return; + } + } else if (pt->getUnitClass() == ucWorker) { + if (aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcWorkerUnits).size() > 0) { + const + std::vector < + FactionType::PairPUnitTypeInt > & + unitList = + aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcWorkerUnits); + for (unsigned int i = 0; i < unitList.size(); ++i) { + const + FactionType::PairPUnitTypeInt & + priorityUnit = unitList[i]; + if (ai->getCountOfType(priorityUnit.first) < + priorityUnit.second + && aiInterface->getMyFaction()-> + canCreateUnit(priorityUnit.first, false, true, + true) == true) { + ai->addTask(new ProduceTask(priorityUnit.first)); + return; + } + } + } + } else if (pt->getUnitClass() == ucWarrior) { + if (aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcWarriorUnits).size() > 0) { + const + std::vector < + FactionType::PairPUnitTypeInt > & + unitList = + aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcWarriorUnits); + for (unsigned int i = 0; i < unitList.size(); ++i) { + const + FactionType::PairPUnitTypeInt & + priorityUnit = unitList[i]; + if (ai->getCountOfType(priorityUnit.first) < + priorityUnit.second + && aiInterface->getMyFaction()-> + canCreateUnit(priorityUnit.first, false, true, + true) == true) { + ai->addTask(new ProduceTask(priorityUnit.first)); + return; + } + } + } + } + + //for each unit, produce it if possible + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + if (aiInterface->getMyUnit(i)->getCurrCommand() != NULL + && aiInterface->getMyUnit(i)->getCurrCommand()-> + getCommandType()->getClass() == ccBuild) { + //skip this units as it is currently building something + continue; + } + //for each command + const UnitType * + ut = aiInterface->getMyUnit(i)->getType(); + + //bool produceIt= false; + for (int j = 0; j < ut->getCommandTypeCount(); ++j) { + const CommandType * + ct = ut->getCommandType(j); + + //if the command is produce + //bool produceIt= false; + if (ct->getClass() == ccProduce || ct->getClass() == ccMorph) { + const UnitType * + producedUnit = static_cast (ct->getProduced()); + + if (ai->outputAIBehaviourToConsole()) + printf("produceGeneric [%p] Testing AI RULE Name[%s]\n", + pt->getResourceType(), + this->getName().c_str()); + + //if the unit produces the resource + if (pt->getResourceType() != NULL) { + const Resource * + r = producedUnit->getCost(pt->getResourceType()); + if (r != NULL) { + if (ai->outputAIBehaviourToConsole()) + printf + ("produceGeneric r = [%s][%d] Testing AI RULE Name[%s]\n", + r->getDescription(false).c_str(), + r->getAmount(), this->getName().c_str()); + } + + if (r != NULL && r->getAmount() < 0) { + if (aiInterface->reqsOk(ct) + && aiInterface->reqsOk(producedUnit)) { + //produceIt= true; + addUnitTypeToCandidates(producedUnit, + ableUnits, + ableUnitsGiveBack, + false); + } + } + } else { + //if the unit is from the right class + if (ai->outputAIBehaviourToConsole()) + printf + ("produceGeneric right class = [%d] Testing AI RULE Name[%s]\n", + producedUnit->isOfClass(pt->getUnitClass()), + this->getName().c_str()); + + if (producedUnit->isOfClass(pt->getUnitClass())) { + if (aiInterface->reqsOk(ct) + && aiInterface->reqsOk(producedUnit)) { + //produceIt= true; + addUnitTypeToCandidates(producedUnit, + ableUnits, + ableUnitsGiveBack, + false); + } + } + } + } + } + // Now check of the unit 'gives' the resource + // This is likely a unit that it BUILT by another and that is handled by a different AI task type: Build + // if(produceIt == false && pt->getResourceType() != NULL) { + // const Resource *r= ut->getCost(pt->getResourceType()); + // if(r != NULL) { + // if(ai->outputAIBehaviourToConsole()) printf("#2 produceGeneric r = [%s][%d] Testing AI RULE Name[%s]\n",r->getDescription(false).c_str(),r->getAmount(), this->getName().c_str()); + // } + // + // if(r != NULL && r->getAmount() < 0) { + // if(aiInterface->reqsOk(ut)){ + // produceIt= true; + // addUnitTypeToCandidates(ut, ableUnits,ableUnitsGiveBack, true); + // } + // } + // } + + } + + //add specific produce task + if (ableUnits.empty() == false) { + + if (ai->outputAIBehaviourToConsole()) + printf + ("produceGeneric !ableUnits.empty(), ableUnits.size() = [%d] Testing AI RULE Name[%s]\n", + (int) ableUnits.size(), this->getName().c_str()); + + // Now check if we already have at least 2 produce or morph + // resource based units, if so prefer units that give back the resource + if (pt->getResourceType() != NULL && ableUnits.size() > 1) { + //priority for non produced units + UnitTypes + newAbleUnits; + bool + haveEnoughProducers = true; + bool + haveNonProducers = false; + for (unsigned int i = 0; i < ableUnits.size(); ++i) { + const UnitType * + ut = ableUnits[i]; + bool + givesBack = ableUnitsGiveBack[i]; + if (givesBack == false && ai->getCountOfType(ut) < 2) { + haveEnoughProducers = false; + } else if (givesBack == true) { + haveNonProducers = true; + newAbleUnits.push_back(ut); + } + + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In produceGeneric for unit type [%s] givesBack: %d count of unit type: %d", + ut->getName(false).c_str(), givesBack, + ai->getCountOfType(ut)); + aiInterface->printLog(4, szBuf); + } + + } + + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "haveEnoughProducers [%d] haveNonProducers [%d]", + haveEnoughProducers, haveNonProducers); + aiInterface->printLog(4, szBuf); + + for (unsigned int i = 0; i < ableUnits.size(); ++i) { + const UnitType * + ut = ableUnits[i]; + snprintf(szBuf, 8096, "i: %u unit type [%s]", i, + ut->getName(false).c_str()); + aiInterface->printLog(4, szBuf); + } + for (unsigned int i = 0; i < newAbleUnits.size(); ++i) { + const UnitType * + ut = newAbleUnits[i]; + snprintf(szBuf, 8096, "i: %u new unit type [%s]", i, + ut->getName(false).c_str()); + aiInterface->printLog(4, szBuf); + } + } + + if (haveEnoughProducers == true && haveNonProducers == true) { + ableUnits = newAbleUnits; + } + } + + //priority for non produced units + for (unsigned int i = 0; i < ableUnits.size(); ++i) { + if (ai->getCountOfType(ableUnits[i]) == 0) { + if (ai->getRandom()->randRange(0, 1) == 0) { + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In produceGeneric priority adding produce task: %d of " + MG_SIZE_T_SPECIFIER " for unit type [%s]", + i, ableUnits.size(), + ableUnits[i]->getName(false).c_str()); + aiInterface->printLog(4, szBuf); + } + + ai->addTask(new ProduceTask(ableUnits[i])); + return; + } + } + } + + //normal case + int + randomUnitTypeIndex = + ai->getRandom()->randRange(0, (int) ableUnits.size() - 1); + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In produceGeneric randomUnitTypeIndex = %d of " + MG_SIZE_T_SPECIFIER " equals unit type [%s]", + randomUnitTypeIndex, ableUnits.size() - 1, + ableUnits[randomUnitTypeIndex]->getName(false). + c_str()); + aiInterface->printLog(4, szBuf); + } + + const UnitType * + ut = ableUnits[randomUnitTypeIndex]; + + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "== END In produceGeneric normal adding produce task for unit type [%s]", + ut->getName(false).c_str()); + aiInterface->printLog(4, szBuf); + } + + ai->addTask(new ProduceTask(ut)); + } + } + + void + AiRuleProduce::produceGeneric(const ProduceTask * pt) { + typedef + vector < const UnitType *> + UnitTypes; + UnitTypes + ableUnits; + AiInterface * + aiInterface = ai->getAiInterface(); + + if (pt->getResourceType() != NULL) { + if (aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcResourceProducerUnits).size() > 0) { + const + std::vector < + FactionType::PairPUnitTypeInt > & + unitList = + aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcResourceProducerUnits); + for (unsigned int i = 0; i < unitList.size(); ++i) { + const + FactionType::PairPUnitTypeInt & + priorityUnit = unitList[i]; + if (ai->getCountOfType(priorityUnit.first) < + priorityUnit.second + && aiInterface->getMyFaction()-> + canCreateUnit(priorityUnit.first, false, true, + true) == true) { + //if(ai->getRandom()->randRange(0, 1)==0) { + ai->addTask(new ProduceTask(priorityUnit.first)); + return; + //} + } + } + } + } else if (pt->getUnitClass() == ucWorker) { + if (aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcWorkerUnits).size() > 0) { + const + std::vector < + FactionType::PairPUnitTypeInt > & + unitList = + aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcWorkerUnits); + for (unsigned int i = 0; i < unitList.size(); ++i) { + const + FactionType::PairPUnitTypeInt & + priorityUnit = unitList[i]; + if (ai->getCountOfType(priorityUnit.first) < + priorityUnit.second + && aiInterface->getMyFaction()-> + canCreateUnit(priorityUnit.first, false, true, + true) == true) { + //if(ai->getRandom()->randRange(0, 1)==0) { + ai->addTask(new ProduceTask(priorityUnit.first)); + return; + //} + } + } + } + } else if (pt->getUnitClass() == ucWarrior) { + if (aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcWarriorUnits).size() > 0) { + const + std::vector < + FactionType::PairPUnitTypeInt > & + unitList = + aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcWarriorUnits); + for (unsigned int i = 0; i < unitList.size(); ++i) { + const + FactionType::PairPUnitTypeInt & + priorityUnit = unitList[i]; + if (ai->getCountOfType(priorityUnit.first) < + priorityUnit.second + && aiInterface->getMyFaction()-> + canCreateUnit(priorityUnit.first, false, true, + true) == true) { + //if(ai->getRandom()->randRange(0, 1)==0) { + ai->addTask(new ProduceTask(priorityUnit.first)); + return; + //} + } + } + } + } + + //for each unit, produce it if possible + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + if (aiInterface->getMyUnit(i)->getCurrCommand() != NULL + && aiInterface->getMyUnit(i)->getCurrCommand()-> + getCommandType()->getClass() == ccBuild) { + //skip this units as it is currently building something + continue; + } + //for each command + const UnitType * + ut = aiInterface->getMyUnit(i)->getType(); + for (int j = 0; j < ut->getCommandTypeCount(); ++j) { + const CommandType * + ct = ut->getCommandType(j); + + //if the command is produce + if (ct->getClass() == ccProduce || ct->getClass() == ccMorph) { + + const UnitType * + producedUnit = static_cast (ct->getProduced()); + bool + produceIt = false; + + if (ai->outputAIBehaviourToConsole()) + printf("produceGeneric [%p] Testing AI RULE Name[%s]\n", + pt->getResourceType(), + this->getName().c_str()); + + //if the unit produces the resource + if (pt->getResourceType() != NULL) { + const Resource * + r = producedUnit->getCost(pt->getResourceType()); + + if (r != NULL) { + if (ai->outputAIBehaviourToConsole()) + printf + ("produceGeneric r = [%s][%d] Testing AI RULE Name[%s]\n", + r->getDescription(false).c_str(), + r->getAmount(), this->getName().c_str()); + } + + if (r != NULL && r->getAmount() < 0) { + produceIt = true; + } + } + + else { + //if the unit is from the right class + if (ai->outputAIBehaviourToConsole()) + printf + ("produceGeneric right class = [%d] Testing AI RULE Name[%s]\n", + producedUnit->isOfClass(pt->getUnitClass()), + this->getName().c_str()); + + if (producedUnit->isOfClass(pt->getUnitClass())) { + if (aiInterface->reqsOk(ct) + && aiInterface->reqsOk(producedUnit)) { + produceIt = true; + } + } + } + + if (produceIt) { + //if the unit is not already on the list + if (find + (ableUnits.begin(), ableUnits.end(), + producedUnit) == ableUnits.end()) { + ableUnits.push_back(producedUnit); + } + } + } + } + } + + //add specific produce task + if (ableUnits.empty() == false) { + + if (ai->outputAIBehaviourToConsole()) + printf + ("produceGeneric !ableUnits.empty(), ableUnits.size() = [%d] Testing AI RULE Name[%s]\n", + (int) ableUnits.size(), this->getName().c_str()); + + //priority for non produced units + for (unsigned int i = 0; i < ableUnits.size(); ++i) { + if (ai->getCountOfType(ableUnits[i]) == 0) { + if (ai->getRandom()->randRange(0, 1) == 0) { + ai->addTask(new ProduceTask(ableUnits[i])); + return; + } + } + } + + //normal case + ai-> + addTask(new + ProduceTask(ableUnits + [ai->getRandom()-> + randRange(0, + (int) ableUnits.size() - 1)])); + } + } + + void + AiRuleProduce::produceSpecific(const ProduceTask * pt) { + + AiInterface * + aiInterface = ai->getAiInterface(); + + if (ai->outputAIBehaviourToConsole()) + printf + ("produceSpecific aiInterface->reqsOk(pt->getUnitType()) = [%s][%d] Testing AI RULE Name[%s]\n", + pt->getUnitType()->getName().c_str(), + aiInterface->reqsOk(pt->getUnitType()), + this->getName().c_str()); + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "== START produceSpecific aiInterface->reqsOk(pt->getUnitType()) = [%s][%d] Testing AI RULE Name[%s]", + pt->getUnitType()->getName().c_str(), + aiInterface->reqsOk(pt->getUnitType()), + this->getName().c_str()); + aiInterface->printLog(4, szBuf); + } + + //if unit meets requirements + if (aiInterface->reqsOk(pt->getUnitType())) { + + const CommandType * + ctypeForCostCheck = NULL; + //for each unit + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + //don't use units which are currently building + if (aiInterface->getMyUnit(i)->getCurrCommand() != NULL + && aiInterface->getMyUnit(i)->getCurrCommand()-> + getCommandType()->getClass() == ccBuild) { + //skip this units as it is currently building something + continue; + } + //for each command + const UnitType * + ut = aiInterface->getMyUnit(i)->getType(); + for (int j = 0; j < ut->getCommandTypeCount(); ++j) { + const CommandType * + ct = ut->getCommandType(j); + + //if the command is produce + if (ct->getClass() == ccProduce + || ct->getClass() == ccMorph) { + const UnitType * + producedUnit = static_cast (ct->getProduced()); + + //if units match + if (producedUnit == pt->getUnitType()) { + + if (ai->outputAIBehaviourToConsole()) + printf + ("produceSpecific aiInterface->reqsOk(ct) = [%d] Testing AI RULE Name[%s]\n", + aiInterface->reqsOk(ct), + this->getName().c_str()); + + if (aiInterface->reqsOk(ct)) { + if (ctypeForCostCheck == NULL + || ct->getClass() == ccMorph) { + if (ctypeForCostCheck != NULL + && ct->getClass() == ccMorph) { + const MorphCommandType * + mct = dynamic_cast (ct); + if (mct == NULL) { + throw + megaglest_runtime_error + ("mct == NULL"); + } + if (mct-> + getIgnoreResourceRequirements() == + true) { + ctypeForCostCheck = ct; + } + } else { + ctypeForCostCheck = ct; + } + } + } + } + } + } + } + + if (ai->outputAIBehaviourToConsole()) + printf + ("produceSpecific aiInterface->checkCosts(pt->getUnitType()) = [%d] Testing AI RULE Name[%s]\n", + aiInterface->checkCosts(pt->getUnitType(), + ctypeForCostCheck), + this->getName().c_str()); + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "produceSpecific aiInterface->checkCosts(pt->getUnitType()) = [%d] Testing AI RULE Name[%s]", + aiInterface->checkCosts(pt->getUnitType(), + ctypeForCostCheck), + this->getName().c_str()); + aiInterface->printLog(4, szBuf); + } + + //if unit doesnt meet resources retry + if (aiInterface-> + checkCosts(pt->getUnitType(), ctypeForCostCheck) == false) { + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "Check costs FAILED."); + aiInterface->printLog(4, szBuf); + } + + ai->retryTask(pt); + return; + } + + //produce specific unit + vector < int > + producers; + // Hold a list of units which can produce or morph + // then a list of commandtypes for each unit + map < int, + vector < const CommandType *> > + producersDefaultCommandType; + const CommandType * + defCt = NULL; + + //for each unit + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + if (aiInterface->getMyUnit(i)->getCurrCommand() != NULL + && aiInterface->getMyUnit(i)->getCurrCommand()-> + getCommandType()->getClass() == ccBuild) { + //skip this units as it is currently building something + continue; + } + //for each command + const UnitType * + ut = aiInterface->getMyUnit(i)->getType(); + for (int j = 0; j < ut->getCommandTypeCount(); ++j) { + const CommandType * + ct = ut->getCommandType(j); + + //if the command is produce + if (ct->getClass() == ccProduce + || ct->getClass() == ccMorph) { + const UnitType * + producedUnit = static_cast (ct->getProduced()); + + //if units match + if (producedUnit == pt->getUnitType()) { + + if (ai->outputAIBehaviourToConsole()) + printf + ("produceSpecific aiInterface->reqsOk(ct) = [%d] Testing AI RULE Name[%s]\n", + aiInterface->reqsOk(ct), + this->getName().c_str()); + + if (aiInterface->reqsOk(ct)) { + //defCt= ct; + producers.push_back(i); + producersDefaultCommandType[i].push_back(ct); + } + } + } + } + } + + //produce from random producer + if (producers.empty() == false) { + + if (ai->outputAIBehaviourToConsole()) + printf + ("produceSpecific producers.empty() = [%d] Testing AI RULE Name[%s]\n", + producers.empty(), this->getName().c_str()); + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "produceSpecific producers.empty() = [%d] Testing AI RULE Name[%s]", + producers.empty(), this->getName().c_str()); + aiInterface->printLog(4, szBuf); + } + + // Narrow down producers list to those who are not busy if possible + vector < int > + idle_producers; + for (unsigned int i = 0; i < producers.size(); ++i) { + int + currentProducerIndex = producers[i]; + if (currentProducerIndex >= aiInterface->getMyUnitCount()) { + char + szBuf[8096] = ""; + printf + ("In [%s::%s Line: %d] currentProducerIndex >= aiInterface->getMyUnitCount(), currentProducerIndex = %d, aiInterface->getMyUnitCount() = %d, i = %u,producers.size() = " + MG_SIZE_T_SPECIFIER "\n", __FILE__, __FUNCTION__, + __LINE__, currentProducerIndex, + aiInterface->getMyUnitCount(), i, + producers.size()); + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] currentProducerIndex >= aiInterface->getMyUnitCount(), currentProducerIndex = %d, aiInterface->getMyUnitCount() = %u, i = %u,producers.size() = " + MG_SIZE_T_SPECIFIER "", __FILE__, + __FUNCTION__, __LINE__, currentProducerIndex, + aiInterface->getMyUnitCount(), i, + producers.size()); + throw + megaglest_runtime_error(szBuf); + } + + const Unit * + unit = aiInterface->getMyUnit(currentProducerIndex); + if (unit->anyCommand() == false) { + idle_producers.push_back(currentProducerIndex); + } + } + if (idle_producers.empty() == false) { + producers = idle_producers; + } + + if (aiInterface->getControlType() == ctCpuZeta || + aiInterface->getControlType() == ctNetworkCpuZeta) { // zeta cpu trys to balance the commands to the producers + int + randomstart = + ai->getRandom()->randRange(0, + (int) producers.size() - 1); + int + lowestCommandCount = 1000000; + int + currentProducerIndex = producers[randomstart]; + int + bestIndex = -1; + //int besti=0; + int + currentCommandCount = 0; + for (unsigned int i = randomstart; + i < producers.size() + randomstart; i++) { + int + prIndex = i; + if (i >= producers.size()) { + prIndex = (i - (int) producers.size()); + } + currentProducerIndex = producers[prIndex]; + + if (currentProducerIndex >= + aiInterface->getMyUnitCount()) { + char + szBuf[8096] = ""; + printf + ("In [%s::%s Line: %d] currentProducerIndex >= aiInterface->getMyUnitCount(), currentProducerIndex = %d, aiInterface->getMyUnitCount() = %d, i = %u,producers.size() = " + MG_SIZE_T_SPECIFIER "\n", __FILE__, __FUNCTION__, + __LINE__, currentProducerIndex, + aiInterface->getMyUnitCount(), i, + producers.size()); + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] currentProducerIndex >= aiInterface->getMyUnitCount(), currentProducerIndex = %d, aiInterface->getMyUnitCount() = %u, i = %u,producers.size() = " + MG_SIZE_T_SPECIFIER "", __FILE__, + __FUNCTION__, __LINE__, + currentProducerIndex, + aiInterface->getMyUnitCount(), i, + producers.size()); + throw + megaglest_runtime_error(szBuf); + } + if (prIndex >= (int) producers.size()) { + char + szBuf[8096] = ""; + printf + ("In [%s::%s Line: %d] prIndex >= producers.size(), currentProducerIndex = %d, i = %u,producers.size() = " + MG_SIZE_T_SPECIFIER " \n", __FILE__, + __FUNCTION__, __LINE__, prIndex, i, + producers.size()); + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] currentProducerIndex >= producers.size(), currentProducerIndex = %d, i = %u,producers.size() = " + MG_SIZE_T_SPECIFIER "", __FILE__, + __FUNCTION__, __LINE__, + currentProducerIndex, i, + producers.size()); + throw + megaglest_runtime_error(szBuf); + } + + currentCommandCount = + aiInterface->getMyUnit(currentProducerIndex)-> + getCommandSize(); + if (currentCommandCount == 1 + && aiInterface->getMyUnit(currentProducerIndex)-> + getCurrCommand()->getCommandType()->getClass() == + ccStop) { // special for non buildings + currentCommandCount = 0; + } + if (lowestCommandCount > currentCommandCount) { + lowestCommandCount = + aiInterface->getMyUnit(currentProducerIndex)-> + getCommandSize(); + bestIndex = currentProducerIndex; + //besti=i%(producers.size()); + } + } + if (bestIndex >= 0) { + if (aiInterface->getMyUnit(bestIndex)-> + getCommandSize() > 2) { + // maybe we need another producer of this kind if possible! + if (aiInterface-> + reqsOk(aiInterface->getMyUnit(bestIndex)-> + getType())) { + if (ai->getCountOfClass(ucBuilding) > 5) { + ai-> + addTask(new + BuildTask(aiInterface-> + getMyUnit + (bestIndex)-> + getType())); + } + } + // need to calculate another producer, maybe its better to produce another warrior with another producer + vector < int > + backupProducers; + // find another producer unit which is free and produce any kind of warrior. + //for each unit + for (int i = 0; i < aiInterface->getMyUnitCount(); + ++i) { + const UnitType * + ut = aiInterface->getMyUnit(i)->getType(); + //for each command + for (int j = 0; j < ut->getCommandTypeCount(); + ++j) { + const CommandType * + ct = ut->getCommandType(j); + //if the command is produce + if (ct->getClass() == ccProduce) { + const UnitType * + unitType = static_cast (ct->getProduced()); + if (unitType->hasSkillClass(scAttack) + && !unitType-> + hasCommandClass(ccHarvest) + && aiInterface->reqsOk(ct)) { //this can produce a warrior + backupProducers.push_back(i); + } + } + } + } + if (!backupProducers.empty()) { + int + randomstart = + ai->getRandom()->randRange(0, + (int) + backupProducers. + size() - 1); + int + lowestCommandCount = 1000000; + int + currentProducerIndex = + backupProducers[randomstart]; + int + bestIndex = -1; + for (unsigned int i = randomstart; + i < backupProducers.size() + randomstart; + i++) { + int + prIndex = i; + if (i >= backupProducers.size()) { + prIndex = + (i - (int) backupProducers.size()); + } + + currentProducerIndex = + backupProducers[prIndex]; + + if (currentProducerIndex >= + aiInterface->getMyUnitCount()) { + char + szBuf[8096] = ""; + printf + ("In [%s::%s Line: %d] currentProducerIndex >= aiInterface->getMyUnitCount(), currentProducerIndex = %d, aiInterface->getMyUnitCount() = %d, i = %u,backupProducers.size() = " + MG_SIZE_T_SPECIFIER "\n", __FILE__, + __FUNCTION__, __LINE__, + currentProducerIndex, + aiInterface->getMyUnitCount(), i, + backupProducers.size()); + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] currentProducerIndex >= aiInterface->getMyUnitCount(), currentProducerIndex = %d, aiInterface->getMyUnitCount() = %d, i = %u,backupProducers.size() = " + MG_SIZE_T_SPECIFIER "", + __FILE__, __FUNCTION__, + __LINE__, + currentProducerIndex, + aiInterface-> + getMyUnitCount(), i, + backupProducers.size()); + throw + megaglest_runtime_error(szBuf); + } + if (prIndex >= + (int) backupProducers.size()) { + char + szBuf[8096] = ""; + printf + ("In [%s::%s Line: %d] prIndex >= backupProducers.size(), currentProducerIndex = %d, i = %u,backupProducers.size() = " + MG_SIZE_T_SPECIFIER " \n", __FILE__, + __FUNCTION__, __LINE__, prIndex, i, + backupProducers.size()); + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] currentProducerIndex >= backupProducers.size(), currentProducerIndex = %d, i = %u,backupProducers.size() = " + MG_SIZE_T_SPECIFIER "", + __FILE__, __FUNCTION__, + __LINE__, + currentProducerIndex, i, + backupProducers.size()); + throw + megaglest_runtime_error(szBuf); + } + + int + currentCommandCount = + aiInterface-> + getMyUnit(currentProducerIndex)-> + getCommandSize(); + if (currentCommandCount == 1 + && aiInterface-> + getMyUnit(currentProducerIndex)-> + getCurrCommand()->getCommandType()-> + getClass() == ccStop) { // special for non buildings + currentCommandCount = 0; + } + if (lowestCommandCount > + currentCommandCount) { + lowestCommandCount = + currentCommandCount; + bestIndex = currentProducerIndex; + if (lowestCommandCount == 0) + break; + } + } + // a good producer is found, lets choose a warrior production + vector < int > + productionCommandIndexes; + if (bestIndex >= 0) { + const UnitType * + ut = + aiInterface->getMyUnit(bestIndex)-> + getType(); + for (int j = 0; + j < ut->getCommandTypeCount(); ++j) { + const CommandType * + ct = ut->getCommandType(j); + + //if the command is produce + if (ct->getClass() == ccProduce) { + const UnitType * + unitType = static_cast (ct->getProduced()); + if (unitType-> + hasSkillClass(scAttack) + && !unitType-> + hasCommandClass(ccHarvest) + && aiInterface->reqsOk(ct)) { //this can produce a warrior + productionCommandIndexes. + push_back(j); + } + } + } + + int + commandIndex = + productionCommandIndexes[ai-> + getRandom()-> + randRange(0, + (int) + productionCommandIndexes. + size + () - + 1)]; + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags:: + debugSystem, + "In [%s::%s Line: %d]\n", + __FILE__, + __FUNCTION__, + __LINE__); + + if (ai->outputAIBehaviourToConsole()) + printf + ("zeta #1 produceSpecific giveCommand to unit [%s] commandType [%s]\n", + aiInterface->getMyUnit(bestIndex)-> + getType()->getName().c_str(), + ut->getCommandType(commandIndex)-> + getName().c_str()); + if (aiInterface->isLogLevelEnabled(4) == + true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "zeta #1 produceSpecific giveCommand to unit [%s] commandType [%s]", + aiInterface-> + getMyUnit(bestIndex)-> + getType()->getName(). + c_str(), + ut-> + getCommandType + (commandIndex)->getName(). + c_str()); + aiInterface->printLog(4, szBuf); + } + + aiInterface->giveCommand(bestIndex, + ut-> + getCommandType + (commandIndex)); + } + } else { // do it like normal CPU + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags:: + debugSystem, + "In [%s::%s Line: %d]\n", + __FILE__, + __FUNCTION__, + __LINE__); + defCt = NULL; + if (producersDefaultCommandType. + find(bestIndex) != + producersDefaultCommandType.end()) { + int + bestCommandTypeCount = + (int) + producersDefaultCommandType[bestIndex]. + size(); + int + bestCommandTypeIndex = + ai->getRandom()->randRange(0, + bestCommandTypeCount + - 1); + + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags:: + debugSystem, + "In [%s::%s Line: %d] bestCommandTypeIndex = %d, bestCommandTypeCount = %d\n", + __FILE__, + __FUNCTION__, + __LINE__, + bestCommandTypeIndex, + bestCommandTypeCount); + + defCt = + producersDefaultCommandType[bestIndex] + [bestCommandTypeIndex]; + } + + if (ai->outputAIBehaviourToConsole()) + printf + ("zeta #2 produceSpecific giveCommand to unit [%s] commandType [%s]\n", + aiInterface->getMyUnit(bestIndex)-> + getType()->getName().c_str(), + (defCt != + NULL ? defCt->getName(). + c_str() : "n/a")); + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "zeta #2 produceSpecific giveCommand to unit [%s] commandType [%s]", + aiInterface-> + getMyUnit(bestIndex)-> + getType()->getName().c_str(), + (defCt != + NULL ? defCt->getName(). + c_str() : "n/a")); + aiInterface->printLog(4, szBuf); + } + aiInterface->giveCommand(bestIndex, defCt); + } + } else { + if (currentCommandCount == 0) { + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags:: + debugSystem, + "In [%s::%s Line: %d]\n", + __FILE__, + __FUNCTION__, + __LINE__); + defCt = NULL; + if (producersDefaultCommandType. + find(bestIndex) != + producersDefaultCommandType.end()) { + //defCt = producersDefaultCommandType[bestIndex]; + int + bestCommandTypeCount = + (int) + producersDefaultCommandType[bestIndex]. + size(); + int + bestCommandTypeIndex = + ai->getRandom()->randRange(0, + bestCommandTypeCount + - 1); + + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags:: + debugSystem, + "In [%s::%s Line: %d] bestCommandTypeIndex = %d, bestCommandTypeCount = %d\n", + __FILE__, + __FUNCTION__, + __LINE__, + bestCommandTypeIndex, + bestCommandTypeCount); + + defCt = + producersDefaultCommandType[bestIndex] + [bestCommandTypeIndex]; + } + + if (ai->outputAIBehaviourToConsole()) + printf + ("zeta #3 produceSpecific giveCommand to unit [%s] commandType [%s]\n", + aiInterface->getMyUnit(bestIndex)-> + getType()->getName().c_str(), + (defCt != + NULL ? defCt->getName(). + c_str() : "n/a")); + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "zeta #3 produceSpecific giveCommand to unit [%s] commandType [%s]", + aiInterface-> + getMyUnit(bestIndex)-> + getType()->getName().c_str(), + (defCt != + NULL ? defCt->getName(). + c_str() : "n/a")); + aiInterface->printLog(4, szBuf); + } + + aiInterface->giveCommand(bestIndex, defCt); + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags:: + debugSystem, + "In [%s::%s Line: %d]\n", + __FILE__, __FUNCTION__, + __LINE__); + defCt = NULL; + if (producersDefaultCommandType.find(bestIndex) != + producersDefaultCommandType.end()) { + //defCt = producersDefaultCommandType[bestIndex]; + int + bestCommandTypeCount = + (int) producersDefaultCommandType[bestIndex]. + size(); + int + bestCommandTypeIndex = + ai->getRandom()->randRange(0, + bestCommandTypeCount + - 1); + + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags:: + debugSystem, + "In [%s::%s Line: %d] bestCommandTypeIndex = %d, bestCommandTypeCount = %d\n", + __FILE__, + __FUNCTION__, + __LINE__, + bestCommandTypeIndex, + bestCommandTypeCount); + + defCt = + producersDefaultCommandType[bestIndex] + [bestCommandTypeIndex]; + } + if (ai->outputAIBehaviourToConsole()) + printf + ("zeta #4 produceSpecific giveCommand to unit [%s] commandType [%s]\n", + aiInterface->getMyUnit(bestIndex)-> + getType()->getName().c_str(), + (defCt != + NULL ? defCt->getName().c_str() : "n/a")); + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "zeta #4 produceSpecific giveCommand to unit [%s] commandType [%s]", + aiInterface->getMyUnit(bestIndex)-> + getType()->getName().c_str(), + (defCt != + NULL ? defCt->getName(). + c_str() : "n/a")); + aiInterface->printLog(4, szBuf); + } + + aiInterface->giveCommand(bestIndex, defCt); + } + } + } else { + int + pIndex = + ai->getRandom()->randRange(0, + (int) producers.size() - 1); + int + producerIndex = producers[pIndex]; + defCt = NULL; + if (producersDefaultCommandType.find(producerIndex) != + producersDefaultCommandType.end()) { + //defCt = producersDefaultCommandType[producerIndex]; + int + bestCommandTypeCount = + (int) producersDefaultCommandType[producerIndex]. + size(); + int + bestCommandTypeIndex = + ai->getRandom()->randRange(0, + bestCommandTypeCount - + 1); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] bestCommandTypeIndex = %d, bestCommandTypeCount = %d\n", + __FILE__, __FUNCTION__, + __LINE__, + bestCommandTypeIndex, + bestCommandTypeCount); + + defCt = + producersDefaultCommandType[producerIndex] + [bestCommandTypeIndex]; + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] producers.size() = %d, producerIndex = %d, pIndex = %d, producersDefaultCommandType.size() = %d\n", + __FILE__, __FUNCTION__, + __LINE__, producers.size(), + producerIndex, pIndex, + producersDefaultCommandType. + size()); + + if (ai->outputAIBehaviourToConsole()) + printf + ("produceSpecific giveCommand to unit [%s] commandType [%s]\n", + aiInterface->getMyUnit(producerIndex)->getType()-> + getName().c_str(), + (defCt != NULL ? defCt->getName().c_str() : "n/a")); + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "produceSpecific giveCommand to unit [%s] commandType [%s]", + aiInterface->getMyUnit(producerIndex)-> + getType()->getName().c_str(), + (defCt != + NULL ? defCt->getName(). + c_str() : "(null)")); + aiInterface->printLog(4, szBuf); + } + aiInterface->giveCommand(producerIndex, defCt); + } + } + } + } + + // ======================================== + // class AiRuleBuild + // ======================================== + + AiRuleBuild::AiRuleBuild(Ai * ai) : + AiRule(ai) { + buildTask = NULL; + } + + bool + AiRuleBuild::test() { + const Task * + task = ai->getTask(); + + if (task == NULL || task->getClass() != tcBuild) { + return false; + } + + buildTask = static_cast (task); + return true; + } + + + void + AiRuleBuild::execute() { + if (buildTask != NULL) { + if (ai->outputAIBehaviourToConsole()) + printf("BUILD AiRuleBuild Unit Name[%s]\n", + (buildTask->getUnitType() != + NULL ? buildTask->getUnitType()->getName(false). + c_str() : "null")); + + //generic build task, build random building that can be built + if (buildTask->getUnitType() == NULL) { + buildGeneric(buildTask); + } + //specific building task, build if possible, retry if not enough resources or not position + else { + buildSpecific(buildTask); + } + + //remove the task + ai->removeTask(buildTask); + } + } + + void + AiRuleBuild::buildGeneric(const BuildTask * bt) { + + //find buildings that can be built + AiInterface * + aiInterface = ai->getAiInterface(); + + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "== START: buildGeneric for resource type [%s]", + (bt->getResourceType() != + NULL ? bt->getResourceType()->getName(). + c_str() : "null")); + aiInterface->printLog(4, szBuf); + } + + typedef + vector < const UnitType *> + UnitTypes; + UnitTypes + buildings; + + if (bt->getResourceType() != NULL) { + if (aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcResourceProducerUnits).size() > 0) { + const + std::vector < + FactionType::PairPUnitTypeInt > & + unitList = + aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcResourceProducerUnits); + for (unsigned int i = 0; i < unitList.size(); ++i) { + const + FactionType::PairPUnitTypeInt & + priorityUnit = unitList[i]; + if (ai->getCountOfType(priorityUnit.first) < + priorityUnit.second + && aiInterface->getMyFaction()-> + canCreateUnit(priorityUnit.first, true, false, + false) == true) { + //if(ai->getRandom()->randRange(0, 1)==0) { + + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In buildGeneric for resource type [%s] aibcResourceProducerUnits = " + MG_SIZE_T_SPECIFIER + " priorityUnit.first: [%s]\n", + bt->getResourceType()->getName(). + c_str(), unitList.size(), + priorityUnit.first->getName().c_str()); + aiInterface->printLog(4, szBuf); + } + + ai->addTask(new BuildTask(priorityUnit.first)); + return; + //} + } + } + } + } else { + if (aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcBuildingUnits).size() > 0) { + const + std::vector < + FactionType::PairPUnitTypeInt > & + unitList = + aiInterface->getMyFactionType()-> + getAIBehaviorUnits(aibcBuildingUnits); + for (unsigned int i = 0; i < unitList.size(); ++i) { + const + FactionType::PairPUnitTypeInt & + priorityUnit = unitList[i]; + if (ai->getCountOfType(priorityUnit.first) < + priorityUnit.second + && aiInterface->getMyFaction()-> + canCreateUnit(priorityUnit.first, true, false, + false) == true) { + //if(ai->getRandom()->randRange(0, 1)==0) { + + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In buildGeneric for resource type [%s] aibcBuildingUnits = " + MG_SIZE_T_SPECIFIER + " priorityUnit.first: [%s]\n", + bt->getResourceType()->getName(). + c_str(), unitList.size(), + priorityUnit.first->getName().c_str()); + aiInterface->printLog(4, szBuf); + } + + ai->addTask(new BuildTask(priorityUnit.first)); + return; + //} + } + } + } + } + + //for each unit + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + + //for each command + const UnitType * + ut = aiInterface->getMyUnit(i)->getType(); + for (int j = 0; j < ut->getCommandTypeCount(); ++j) { + const CommandType * + ct = ut->getCommandType(j); + + //if the command is build + if (ct->getClass() == ccBuild) { + const BuildCommandType * + bct = static_cast (ct); + + //for each building + for (int k = 0; k < bct->getBuildingCount(); ++k) { + const UnitType * + building = bct->getBuilding(k); + if (aiInterface->reqsOk(bct) + && aiInterface->reqsOk(building)) { + + //if any building, or produces resource + const ResourceType * + rt = bt->getResourceType(); + const Resource * + cost = building->getCost(rt); + if (rt == NULL + || (cost != NULL && cost->getAmount() < 0)) { + if (find + (buildings.begin(), buildings.end(), + building) == buildings.end()) { + buildings.push_back(building); + } + } + } + } + } + } + } + + if (aiInterface->isLogLevelEnabled(4) == true) { + for (int i = 0; i < (int) buildings.size(); ++i) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In buildGeneric i = %d unit type: [%s]\n", i, + buildings[i]->getName().c_str()); + aiInterface->printLog(4, szBuf); + } + } + + //add specific build task + buildBestBuilding(buildings); + } + + void + AiRuleBuild::buildBestBuilding(const vector < + const UnitType * >&buildings) { + + AiInterface * + aiInterface = ai->getAiInterface(); + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "==> START buildBestBuilding buildings.size = " + MG_SIZE_T_SPECIFIER "\n", buildings.size()); + aiInterface->printLog(4, szBuf); + } + + if (!buildings.empty()) { + + //build the least built building + bool + buildingFound = false; + for (int i = 0; i < 10 && !buildingFound; ++i) { + + if (i > 0) { + + //Defensive buildings have priority + for (int j = 0; + j < (int) buildings.size() && buildingFound == false; + ++j) { + const UnitType * + building = buildings[j]; + if (ai->getCountOfType(building) <= i + 1 + && isDefensive(building)) { + + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In buildBestBuilding defensive building unit type: [%s] i = %d j = %d\n", + building->getName().c_str(), i, j); + aiInterface->printLog(4, szBuf); + } + + ai->addTask(new BuildTask(building)); + buildingFound = true; + } + } + + //Warrior producers next + for (unsigned int j = 0; + j < buildings.size() && !buildingFound; ++j) { + const UnitType * + building = buildings[j]; + if (ai->getCountOfType(building) <= i + 1 + && isWarriorProducer(building)) { + + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In buildBestBuilding warriorproducer building unit type: [%s] i = %d j = %u\n", + building->getName().c_str(), i, j); + aiInterface->printLog(4, szBuf); + } + + ai->addTask(new BuildTask(building)); + buildingFound = true; + } + } + + //Resource producers next + for (unsigned int j = 0; + j < buildings.size() && !buildingFound; ++j) { + const UnitType * + building = buildings[j]; + if (ai->getCountOfType(building) <= i + 1 + && isResourceProducer(building)) { + + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In buildBestBuilding resourceproducer building unit type: [%s] i = %d j = %u\n", + building->getName().c_str(), i, j); + aiInterface->printLog(4, szBuf); + } + + ai->addTask(new BuildTask(building)); + buildingFound = true; + } + } + } + + //Any building + for (unsigned int j = 0; + j < buildings.size() && !buildingFound; ++j) { + const UnitType * + building = buildings[j]; + if (ai->getCountOfType(building) <= i) { + + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In buildBestBuilding ANY building unit type: [%s] i = %d j = %u\n", + building->getName().c_str(), i, j); + aiInterface->printLog(4, szBuf); + } + + ai->addTask(new BuildTask(building)); + buildingFound = true; + } + } + } + } + + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "==> END buildBestBuilding buildings.size = " + MG_SIZE_T_SPECIFIER "\n", buildings.size()); + aiInterface->printLog(4, szBuf); + } + } + + void + AiRuleBuild::buildSpecific(const BuildTask * bt) { + AiInterface * + aiInterface = ai->getAiInterface(); + + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "== START: buildSpecific for resource type [%s] bt->getUnitType() [%s]", + (bt->getResourceType() != + NULL ? bt->getResourceType()->getName(). + c_str() : "null"), + (bt->getUnitType() != + NULL ? bt->getUnitType()->getName(false). + c_str() : "null")); + aiInterface->printLog(4, szBuf); + } + + //if reqs ok + if (aiInterface->reqsOk(bt->getUnitType())) { + + //retry if not enough resources + if (aiInterface->checkCosts(bt->getUnitType(), NULL) == false) { + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In buildSpecific for resource type [%s] checkcosts == false RETRYING", + (bt->getResourceType() != + NULL ? bt->getResourceType()->getName(). + c_str() : "null")); + aiInterface->printLog(4, szBuf); + } + + ai->retryTask(bt); + return; + } + + vector < int > + builders; + // Hold a list of units which can build + // then a list of build commandtypes for each unit + map < int, + vector < const BuildCommandType *> > + buildersDefaultCommandType; + const BuildCommandType * + defBct = NULL; + + //for each unit + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + + //if the unit is not going to build + const Unit * + u = aiInterface->getMyUnit(i); + if (u->anyCommand() == false + || u->getCurrCommand()->getCommandType()->getClass() != + ccBuild) { + + //for each command + const UnitType * + ut = aiInterface->getMyUnit(i)->getType(); + for (int j = 0; j < ut->getCommandTypeCount(); ++j) { + const CommandType * + ct = ut->getCommandType(j); + + //if the command is build + if (ct->getClass() == ccBuild) { + const BuildCommandType * + bct = static_cast (ct); + + //for each building + for (int k = 0; k < bct->getBuildingCount(); ++k) { + const UnitType * + building = bct->getBuilding(k); + + //if building match + if (bt->getUnitType() == building) { + if (aiInterface->reqsOk(bct)) { + builders.push_back(i); + buildersDefaultCommandType[i]. + push_back(bct); + //defBct= bct; + } + } + } + } + } + } + } + + //use random builder to build + if (builders.empty() == false) { + int + bIndex = + ai->getRandom()->randRange(0, (int) builders.size() - 1); + int + builderIndex = builders[bIndex]; + Vec2i + pos; + Vec2i + searchPos = + bt->getForcePos() ? bt->getPos() : ai-> + getRandomHomePosition(); + if (bt->getForcePos() == false) { + const int + enemySightDistanceToAvoid = 18; + vector < Unit * >enemies; + ai->getAiInterface()->getWorld()->getUnitUpdater()-> + findEnemiesForCell(searchPos, + bt->getUnitType()->getSize(), + enemySightDistanceToAvoid, + ai->getAiInterface()-> + getMyFaction(), enemies, true); + if (enemies.empty() == false) { + for (int i1 = 0; i1 < 25 && enemies.empty() == false; + ++i1) { + for (int j1 = 0; + j1 < 25 && enemies.empty() == false; ++j1) { + Vec2i + tryPos = searchPos + Vec2i(i1, j1); + + const int + spacing = 1; + if (ai->getAiInterface()-> + isFreeCells(tryPos - Vec2i(spacing), + bt->getUnitType()-> + getSize() + spacing * 2, + fLand)) { + enemies.clear(); + ai->getAiInterface()->getWorld()-> + getUnitUpdater()-> + findEnemiesForCell(tryPos, + bt->getUnitType()-> + getSize(), + enemySightDistanceToAvoid, + ai-> + getAiInterface()-> + getMyFaction(), + enemies, true); + if (enemies.empty() == true) { + searchPos = tryPos; + } + } + } + } + } + if (enemies.empty() == false) { + for (int i1 = -1; + i1 >= -25 && enemies.empty() == false; --i1) { + for (int j1 = -1; + j1 >= -25 && enemies.empty() == false; --j1) { + Vec2i + tryPos = searchPos + Vec2i(i1, j1); + + const int + spacing = 1; + if (ai->getAiInterface()-> + isFreeCells(tryPos - Vec2i(spacing), + bt->getUnitType()-> + getSize() + spacing * 2, + fLand)) { + enemies.clear(); + ai->getAiInterface()->getWorld()-> + getUnitUpdater()-> + findEnemiesForCell(tryPos, + bt->getUnitType()-> + getSize(), + enemySightDistanceToAvoid, + ai-> + getAiInterface()-> + getMyFaction(), + enemies, true); + if (enemies.empty() == true) { + searchPos = tryPos; + } + } + } + } + } + } + + //if free pos give command, else retry + if (ai->findPosForBuilding(bt->getUnitType(), searchPos, pos)) { + defBct = NULL; + if (buildersDefaultCommandType.find(builderIndex) != + buildersDefaultCommandType.end()) { + //defBct = buildersDefaultCommandType[builderIndex]; + int + bestCommandTypeCount = + (int) buildersDefaultCommandType[builderIndex]. + size(); + int + bestCommandTypeIndex = + ai->getRandom()->randRange(0, + bestCommandTypeCount - + 1); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] bestCommandTypeIndex = %d, bestCommandTypeCount = %d\n", + __FILE__, __FUNCTION__, + __LINE__, + bestCommandTypeIndex, + bestCommandTypeCount); + + defBct = + buildersDefaultCommandType[builderIndex] + [bestCommandTypeIndex]; + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] builderIndex = %d, bIndex = %d, defBct = %p\n", + __FILE__, __FUNCTION__, + __LINE__, builderIndex, bIndex, + defBct); + + aiInterface->giveCommand(builderIndex, defBct, pos, + bt->getUnitType()); + } else { + ai->retryTask(bt); + return; + } + } + } else { + if (aiInterface->isLogLevelEnabled(4) == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In buildSpecific for resource type [%s] reqsok == false", + (bt->getResourceType() != + NULL ? bt->getResourceType()->getName(). + c_str() : "null")); + aiInterface->printLog(4, szBuf); + } + + } + } + + bool + AiRuleBuild::isDefensive(const UnitType * building) { + if (ai->outputAIBehaviourToConsole()) + printf("BUILD isDefensive check for Unit Name[%s] result = %d\n", + building->getName(false).c_str(), + building->hasSkillClass(scAttack)); + + return building->hasSkillClass(scAttack); + } + + bool + AiRuleBuild::isResourceProducer(const UnitType * building) { + for (int i = 0; i < building->getCostCount(); i++) { + if (building->getCost(i)->getAmount() < 0) { + if (ai->outputAIBehaviourToConsole()) + printf + ("BUILD isResourceProducer check for Unit Name[%s] result = true\n", + building->getName(false).c_str()); + + return true; + } + } + if (ai->outputAIBehaviourToConsole()) + printf + ("BUILD isResourceProducer check for Unit Name[%s] result = false\n", + building->getName(false).c_str()); + + return false; + } + + bool + AiRuleBuild::isWarriorProducer(const UnitType * building) { + for (int i = 0; i < building->getCommandTypeCount(); i++) { + const CommandType * + ct = building->getCommandType(i); + if (ct->getClass() == ccProduce) { + const UnitType * + ut = static_cast (ct)-> + getProducedUnit(); + + if (ut->isOfClass(ucWarrior)) { + if (ai->outputAIBehaviourToConsole()) + printf + ("BUILD isWarriorProducer check for Unit Name[%s] result = true\n", + building->getName(false).c_str()); + + return true; + } + } + } + if (ai->outputAIBehaviourToConsole()) + printf + ("BUILD isWarriorProducer check for Unit Name[%s] result = false\n", + building->getName(false).c_str()); + + return false; + } + + // ======================================== + // class AiRuleUpgrade + // ======================================== + + AiRuleUpgrade::AiRuleUpgrade(Ai * ai) : + AiRule(ai) { + upgradeTask = NULL; + } + + bool + AiRuleUpgrade::test() { + const Task * + task = ai->getTask(); + + if (task == NULL || task->getClass() != tcUpgrade) { + return false; + } + + upgradeTask = static_cast (task); + return true; + } + + void + AiRuleUpgrade::execute() { + + //upgrade any upgrade + if (upgradeTask->getUpgradeType() == NULL) { + upgradeGeneric(upgradeTask); + } + //upgrade specific upgrade + else { + upgradeSpecific(upgradeTask); + } + + //remove the task + ai->removeTask(upgradeTask); + } + + void + AiRuleUpgrade::upgradeGeneric(const UpgradeTask * upgt) { + + typedef + vector < const UpgradeType *> + UpgradeTypes; + AiInterface * + aiInterface = ai->getAiInterface(); + + //find upgrades that can be upgraded + UpgradeTypes + upgrades; + + if (aiInterface->getMyFactionType()->getAIBehaviorUpgrades().size() > + 0) { + const + std::vector < const UpgradeType *>& + upgradeList = + aiInterface->getMyFactionType()->getAIBehaviorUpgrades(); + for (unsigned int i = 0; i < upgradeList.size(); ++i) { + const UpgradeType * + priorityUpgrade = upgradeList[i]; + + //for each upgrade, upgrade it if possible + for (int k = 0; k < aiInterface->getMyUnitCount(); ++k) { + + //for each command + const UnitType * + ut = aiInterface->getMyUnit(k)->getType(); + for (int j = 0; j < ut->getCommandTypeCount(); ++j) { + const CommandType * + ct = ut->getCommandType(j); + + //if the command is upgrade + if (ct->getClass() == ccUpgrade) { + const UpgradeCommandType * + upgct = dynamic_cast (ct); + if (upgct != NULL) { + const UpgradeType * + upgrade = upgct->getProducedUpgrade(); + if (upgrade == priorityUpgrade) { + if (aiInterface->reqsOk(upgct) == true && + aiInterface->getMyFaction()-> + getUpgradeManager()-> + isUpgradingOrUpgraded(priorityUpgrade) + == false) { + //if(ai->getRandom()->randRange(0, 1)==0) { + ai-> + addTask(new + UpgradeTask + (priorityUpgrade)); + return; + //} + } + } + } + } + } + } + } + } + + //for each upgrade, upgrade it if possible + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + + //for each command + const UnitType * + ut = aiInterface->getMyUnit(i)->getType(); + for (int j = 0; j < ut->getCommandTypeCount(); ++j) { + const CommandType * + ct = ut->getCommandType(j); + + //if the command is upgrade + if (ct->getClass() == ccUpgrade) { + const UpgradeCommandType * + upgct = static_cast (ct); + const UpgradeType * + upgrade = upgct->getProducedUpgrade(); + if (aiInterface->reqsOk(upgct)) { + upgrades.push_back(upgrade); + } + } + } + } + + //add specific upgrade task + if (!upgrades.empty()) { + ai-> + addTask(new + UpgradeTask(upgrades + [ai->getRandom()-> + randRange(0, + (int) upgrades.size() - 1)])); + } + } + + void + AiRuleUpgrade::upgradeSpecific(const UpgradeTask * upgt) { + + AiInterface * + aiInterface = ai->getAiInterface(); + + //if reqs ok + if (aiInterface->reqsOk(upgt->getUpgradeType())) { + + //if resources dont meet retry + if (!aiInterface->checkCosts(upgt->getUpgradeType(), NULL)) { + ai->retryTask(upgt); + return; + } + + //for each unit + for (int i = 0; i < aiInterface->getMyUnitCount(); ++i) { + + //for each command + const UnitType * + ut = aiInterface->getMyUnit(i)->getType(); + for (int j = 0; j < ut->getCommandTypeCount(); ++j) { + const CommandType * + ct = ut->getCommandType(j); + + //if the command is upgrade + if (ct->getClass() == ccUpgrade) { + const UpgradeCommandType * + uct = static_cast (ct); + const UpgradeType * + producedUpgrade = uct->getProducedUpgrade(); + + //if upgrades match + if (producedUpgrade == upgt->getUpgradeType()) { + if (aiInterface->reqsOk(uct)) { + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags:: + debugSystem, + "In [%s::%s Line: %d]\n", + __FILE__, + __FUNCTION__, + __LINE__); + aiInterface->giveCommand(i, uct); + } + } + } + } + } + + } + } + + // ======================================== + // class AiRuleExpand + // ======================================== + + AiRuleExpand::AiRuleExpand(Ai * ai) : + AiRule(ai) { + storeType = NULL; + } + + bool + AiRuleExpand::test() { + AiInterface * + aiInterface = ai->getAiInterface(); + + int + unitCount = aiInterface->getMyUnitCount(); + for (int i = 0; + i < aiInterface->getTechTree()->getResourceTypeCount(); ++i) { + const ResourceType * + rt = aiInterface->getTechTree()->getResourceType(i); + if (rt->getClass() == rcTech) { + bool + factionUsesResourceType = + aiInterface->factionUsesResourceType(aiInterface-> + getMyFactionType(), + rt); + if (factionUsesResourceType == true) { + // If any resource sighted + if (aiInterface-> + getNearestSightedResource(rt, + aiInterface-> + getHomeLocation(), + expandPos, true)) { + int + minDistance = INT_MAX; + storeType = NULL; + + //If there is no close store + for (int j = 0; j < unitCount; ++j) { + const Unit * + u = aiInterface->getMyUnit(j); + const UnitType * + ut = u->getType(); + + // If this building is a store + if (ut->getStore(rt) > 0) { + storeType = ut; + int + distance = + static_cast < + int>(u->getPosNotThreadSafe(). + dist(expandPos)); + if (distance < minDistance) { + minDistance = distance; + } + } + } + + if (minDistance > expandDistance) { + return true; + } + } else { + // send patrol to look for resource + ai->sendScoutPatrol(); + } + } + } + } + + return false; + } + + void + AiRuleExpand::execute() { + ai->addExpansion(expandPos); + ai->addPriorityTask(new BuildTask(storeType, expandPos)); + } + + + // ======================================== + // class AiRuleUnBlock + // ======================================== + + AiRuleUnBlock::AiRuleUnBlock(Ai * ai) : + AiRule(ai) { + + } + + bool + AiRuleUnBlock::test() { + return ai->haveBlockedUnits(); + } + + void + AiRuleUnBlock::execute() { + ai->unblockUnits(); + } + + } +} //end namespace diff --git a/source/glest_game/ai/ai_rule.h b/source/glest_game/ai/ai_rule.h index 159837199..e438a814e 100644 --- a/source/glest_game/ai/ai_rule.h +++ b/source/glest_game/ai/ai_rule.h @@ -23,642 +23,597 @@ # include "leak_dumper.h" using - std::string; +std::string; using - Shared::Graphics::Vec2i; +Shared::Graphics::Vec2i; namespace - Glest -{ - namespace - Game - { - - class - Ai; - class - AiInterface; - class - Unit; - class - UnitType; - class - ProduceTask; - class - BuildTask; - class - UpgradeTask; - class - ResourceType; - -// ===================================================== -// class AiRule -// -/// An action that the AI will perform periodically -/// if the test succeeds -// ===================================================== - -// The general structure of the rules for an AI to do a task. - class - AiRule - { - protected: - Ai * - ai; - - public: - explicit - AiRule (Ai * ai); - virtual ~ - AiRule () - { - } - - virtual int - getTestInterval () const = 0; //in milliseconds - virtual string - getName () const = 0; - - virtual bool - test () = 0; - virtual void - execute () = 0; - }; - -// ===================================================== -// class AiRuleWorkerHarvest -// ===================================================== - -// The rules for AI tasks inherit from the generic AiRule class. - class - AiRuleWorkerHarvest: - public - AiRule - { - private: - int - stoppedWorkerIndex; - - public: - explicit - AiRuleWorkerHarvest (Ai * ai); - // This value returned byt getTestInterval() - // is called in ai.cpp to determine the chance the rule is executed. - virtual int - getTestInterval () const - { - return - 2000; - } - virtual string - getName () const - { - return - "Worker stopped => Order worker to harvest"; - } - - virtual bool - test (); - virtual void - execute (); - }; - -// ===================================================== -// class AiRuleRefreshHarvester -// ===================================================== - - class - AiRuleRefreshHarvester: - public - AiRule - { - private: - int - workerIndex; - - public: - explicit - AiRuleRefreshHarvester (Ai * ai); - - virtual int - getTestInterval () const - { - return - 20000; - } - virtual string - getName () const - { - return - "Worker reassigned to needed resource"; - } - - virtual bool - test (); - virtual void - execute (); - }; - -// ===================================================== -// class AiRuleScoutPatrol -// ===================================================== - - class - AiRuleScoutPatrol: - public - AiRule - { - public: - explicit - AiRuleScoutPatrol (Ai * ai); - - virtual int - getTestInterval () const - { - return - 10000; - } - virtual string - getName () const - { - return - "Base is stable => Send scout patrol"; - } - - virtual bool - test (); - virtual void - execute (); - }; - -// ===================================================== -// class AiRuleRepair -// ===================================================== - - class - AiRuleRepair: - public - AiRule - { - private: - int - damagedUnitIndex; - bool - damagedUnitIsCastle; - - int - getMinUnitsToRepairCastle (); - double - getMinCastleHpRatio () const; - - public: - explicit - AiRuleRepair (Ai * ai); - - virtual int - getTestInterval () const - { - return - 10000; - } - virtual string - getName () const - { - return - "Building Damaged => Repair"; - } - - virtual bool - test (); - virtual void - execute (); - }; - -// ===================================================== -// class AiRuleReturnBase -// ===================================================== - - class - AiRuleReturnBase: - public - AiRule - { - private: - int - stoppedUnitIndex; - public: - explicit - AiRuleReturnBase (Ai * ai); - - virtual int - getTestInterval () const - { - return - 5000; - } - virtual string - getName () const - { - return - "Stopped unit => Order return base"; - } - - virtual bool - test (); - virtual void - execute (); - }; - -// ===================================================== -// class AiRuleMassiveAttack -// ===================================================== - - class - AiRuleMassiveAttack: - public - AiRule - { - private: - static const int - baseRadius = 25; - - private: - Vec2i - attackPos; - Field - field; - bool - ultraAttack; - - public: - explicit - AiRuleMassiveAttack (Ai * ai); - - virtual int - getTestInterval () const - { - return - 1000; - } - virtual string - getName () const - { - return - "Unit under attack => Order massive attack"; - } - - virtual bool - test (); - virtual void - execute (); - }; - -// ===================================================== -// class AiRuleAddTasks -// ===================================================== - - class - AiRuleAddTasks: - public - AiRule - { - public: - explicit - AiRuleAddTasks (Ai * ai); - - virtual int - getTestInterval () const - { - return - 5000; - } - virtual string - getName () const - { - return - "Tasks empty => Add tasks"; - } - - virtual bool - test (); - virtual void - execute (); - }; - -// ===================================================== -// class AiRuleBuildOneFarm -// ===================================================== - - class - AiRuleBuildOneFarm: - public - AiRule - { - private: - const UnitType * - farm; - - public: - explicit - AiRuleBuildOneFarm (Ai * ai); - - virtual int - getTestInterval () const - { - return - 10000; - } - virtual string - getName () const - { - return - "No farms => Build one"; - } - - virtual bool - test (); - virtual void - execute (); - }; - -// ===================================================== -// class AiRuleProduceResourceProducer -// ===================================================== - - class - AiRuleProduceResourceProducer: - public - AiRule - { - private: - static const int - minStaticResources = 20; - static const int - longInterval = 60000; - static const int - shortInterval = 5000; - const ResourceType * - rt; - int - interval; - bool - newResourceBehaviour; - - public: - explicit - AiRuleProduceResourceProducer (Ai * ai); - - virtual int - getTestInterval () const - { - return - interval; - } - virtual string - getName () const - { - return - "No resources => Build Resource Producer"; - } - - virtual bool - test (); - virtual void - execute (); - }; - -// ===================================================== -// class AiRuleProduce -// ===================================================== - - class - AiRuleProduce: - public - AiRule - { - private: - const ProduceTask * - produceTask; - - typedef - vector < const UnitType *> - UnitTypes; - typedef - vector < - bool > - UnitTypesGiveBack; - bool - newResourceBehaviour; - - public: - explicit - AiRuleProduce (Ai * ai); - - virtual int - getTestInterval () const - { - return - 2000; - } - virtual string - getName () const - { - return - "Performing produce task"; - } - - virtual bool - test (); - virtual void - execute (); - - private: - void - produceGeneric (const ProduceTask * pt); - void - produceGenericNew (const ProduceTask * pt); - void - produceSpecific (const ProduceTask * pt); - bool - canUnitTypeOfferResourceType (const UnitType * ut, - const ResourceType * rt); - bool - setAIProduceTaskForResourceType (const ProduceTask * pt, - AiInterface * aiInterface); - void - addUnitTypeToCandidates (const UnitType * producedUnit, - UnitTypes & ableUnits, - UnitTypesGiveBack & ableUnitsGiveBack, - bool unitCanGiveBackResource); - }; -// ===================================================== -// class AiRuleBuild -// ===================================================== - - class - AiRuleBuild: - public - AiRule - { - private: - const BuildTask * - buildTask; - - public: - explicit - AiRuleBuild (Ai * ai); - - virtual int - getTestInterval () const - { - return - 2000; - } - virtual string - getName () const - { - return - "Performing build task"; - } - - virtual bool - test (); - virtual void - execute (); - - private: - void - buildGeneric (const BuildTask * bt); - void - buildSpecific (const BuildTask * bt); - void - buildBestBuilding (const vector < const UnitType * >&buildings); - - bool - isDefensive (const UnitType * building); - bool - isResourceProducer (const UnitType * building); - bool - isWarriorProducer (const UnitType * building); - }; - -// ===================================================== -// class AiRuleUpgrade -// ===================================================== - - class - AiRuleUpgrade: - public - AiRule - { - private: - const UpgradeTask * - upgradeTask; - - public: - explicit - AiRuleUpgrade (Ai * ai); - - virtual int - getTestInterval () const - { - return - 2000; - } - virtual string - getName () const - { - return - "Performing upgrade task"; - } - - virtual bool - test (); - virtual void - execute (); - - private: - void - upgradeSpecific (const UpgradeTask * upgt); - void - upgradeGeneric (const UpgradeTask * upgt); - }; - -// ===================================================== -// class AiRuleExpand -// ===================================================== - - class - AiRuleExpand: - public - AiRule - { - private: - static const int - expandDistance = 30; - - private: - Vec2i - expandPos; - const UnitType * - storeType; - - public: - explicit - AiRuleExpand (Ai * ai); - - virtual int - getTestInterval () const - { - return - 30000; - } - virtual string - getName () const - { - return - "Expanding"; - } - - virtual bool - test (); - virtual void - execute (); - }; - -// ===================================================== -// class AiRuleUnBlock -// ===================================================== - - class - AiRuleUnBlock: - public - AiRule - { - public: - explicit - AiRuleUnBlock (Ai * ai); - - virtual int - getTestInterval () const - { - return - 3000; - } - virtual string - getName () const - { - return - "Blocked Units => Move surrounding units"; - } - - virtual bool - test (); - virtual void - execute (); - }; - -}} //end namespace + Glest { + namespace + Game { + + class + Ai; + class + AiInterface; + class + Unit; + class + UnitType; + class + ProduceTask; + class + BuildTask; + class + UpgradeTask; + class + ResourceType; + + // ===================================================== + // class AiRule + // + /// An action that the AI will perform periodically + /// if the test succeeds + // ===================================================== + + // The general structure of the rules for an AI to do a task. + class + AiRule { + protected: + Ai * + ai; + + public: + explicit + AiRule(Ai * ai); + virtual ~ + AiRule() { + } + + virtual int + getTestInterval() const = 0; //in milliseconds + virtual string + getName() const = 0; + + virtual bool + test() = 0; + virtual void + execute() = 0; + }; + + // ===================================================== + // class AiRuleWorkerHarvest + // ===================================================== + + // The rules for AI tasks inherit from the generic AiRule class. + class + AiRuleWorkerHarvest : + public + AiRule { + private: + int + stoppedWorkerIndex; + + public: + explicit + AiRuleWorkerHarvest(Ai * ai); + // This value returned byt getTestInterval() + // is called in ai.cpp to determine the chance the rule is executed. + virtual int + getTestInterval() const { + return + 2000; + } + virtual string + getName() const { + return + "Worker stopped => Order worker to harvest"; + } + + virtual bool + test(); + virtual void + execute(); + }; + + // ===================================================== + // class AiRuleRefreshHarvester + // ===================================================== + + class + AiRuleRefreshHarvester : + public + AiRule { + private: + int + workerIndex; + + public: + explicit + AiRuleRefreshHarvester(Ai * ai); + + virtual int + getTestInterval() const { + return + 20000; + } + virtual string + getName() const { + return + "Worker reassigned to needed resource"; + } + + virtual bool + test(); + virtual void + execute(); + }; + + // ===================================================== + // class AiRuleScoutPatrol + // ===================================================== + + class + AiRuleScoutPatrol : + public + AiRule { + public: + explicit + AiRuleScoutPatrol(Ai * ai); + + virtual int + getTestInterval() const { + return + 10000; + } + virtual string + getName() const { + return + "Base is stable => Send scout patrol"; + } + + virtual bool + test(); + virtual void + execute(); + }; + + // ===================================================== + // class AiRuleRepair + // ===================================================== + + class + AiRuleRepair : + public + AiRule { + private: + int + damagedUnitIndex; + bool + damagedUnitIsCastle; + + int + getMinUnitsToRepairCastle(); + double + getMinCastleHpRatio() const; + + public: + explicit + AiRuleRepair(Ai * ai); + + virtual int + getTestInterval() const { + return + 10000; + } + virtual string + getName() const { + return + "Building Damaged => Repair"; + } + + virtual bool + test(); + virtual void + execute(); + }; + + // ===================================================== + // class AiRuleReturnBase + // ===================================================== + + class + AiRuleReturnBase : + public + AiRule { + private: + int + stoppedUnitIndex; + public: + explicit + AiRuleReturnBase(Ai * ai); + + virtual int + getTestInterval() const { + return + 5000; + } + virtual string + getName() const { + return + "Stopped unit => Order return base"; + } + + virtual bool + test(); + virtual void + execute(); + }; + + // ===================================================== + // class AiRuleMassiveAttack + // ===================================================== + + class + AiRuleMassiveAttack : + public + AiRule { + private: + static const int + baseRadius = 25; + + private: + Vec2i + attackPos; + Field + field; + bool + ultraAttack; + + public: + explicit + AiRuleMassiveAttack(Ai * ai); + + virtual int + getTestInterval() const { + return + 1000; + } + virtual string + getName() const { + return + "Unit under attack => Order massive attack"; + } + + virtual bool + test(); + virtual void + execute(); + }; + + // ===================================================== + // class AiRuleAddTasks + // ===================================================== + + class + AiRuleAddTasks : + public + AiRule { + public: + explicit + AiRuleAddTasks(Ai * ai); + + virtual int + getTestInterval() const { + return + 5000; + } + virtual string + getName() const { + return + "Tasks empty => Add tasks"; + } + + virtual bool + test(); + virtual void + execute(); + }; + + // ===================================================== + // class AiRuleBuildOneFarm + // ===================================================== + + class + AiRuleBuildOneFarm : + public + AiRule { + private: + const UnitType * + farm; + + public: + explicit + AiRuleBuildOneFarm(Ai * ai); + + virtual int + getTestInterval() const { + return + 10000; + } + virtual string + getName() const { + return + "No farms => Build one"; + } + + virtual bool + test(); + virtual void + execute(); + }; + + // ===================================================== + // class AiRuleProduceResourceProducer + // ===================================================== + + class + AiRuleProduceResourceProducer : + public + AiRule { + private: + static const int + minStaticResources = 20; + static const int + longInterval = 60000; + static const int + shortInterval = 5000; + const ResourceType * + rt; + int + interval; + bool + newResourceBehaviour; + + public: + explicit + AiRuleProduceResourceProducer(Ai * ai); + + virtual int + getTestInterval() const { + return + interval; + } + virtual string + getName() const { + return + "No resources => Build Resource Producer"; + } + + virtual bool + test(); + virtual void + execute(); + }; + + // ===================================================== + // class AiRuleProduce + // ===================================================== + + class + AiRuleProduce : + public + AiRule { + private: + const ProduceTask * + produceTask; + + typedef + vector < const UnitType *> + UnitTypes; + typedef + vector < + bool > + UnitTypesGiveBack; + bool + newResourceBehaviour; + + public: + explicit + AiRuleProduce(Ai * ai); + + virtual int + getTestInterval() const { + return + 2000; + } + virtual string + getName() const { + return + "Performing produce task"; + } + + virtual bool + test(); + virtual void + execute(); + + private: + void + produceGeneric(const ProduceTask * pt); + void + produceGenericNew(const ProduceTask * pt); + void + produceSpecific(const ProduceTask * pt); + bool + canUnitTypeOfferResourceType(const UnitType * ut, + const ResourceType * rt); + bool + setAIProduceTaskForResourceType(const ProduceTask * pt, + AiInterface * aiInterface); + void + addUnitTypeToCandidates(const UnitType * producedUnit, + UnitTypes & ableUnits, + UnitTypesGiveBack & ableUnitsGiveBack, + bool unitCanGiveBackResource); + }; + // ===================================================== + // class AiRuleBuild + // ===================================================== + + class + AiRuleBuild : + public + AiRule { + private: + const BuildTask * + buildTask; + + public: + explicit + AiRuleBuild(Ai * ai); + + virtual int + getTestInterval() const { + return + 2000; + } + virtual string + getName() const { + return + "Performing build task"; + } + + virtual bool + test(); + virtual void + execute(); + + private: + void + buildGeneric(const BuildTask * bt); + void + buildSpecific(const BuildTask * bt); + void + buildBestBuilding(const vector < const UnitType * >&buildings); + + bool + isDefensive(const UnitType * building); + bool + isResourceProducer(const UnitType * building); + bool + isWarriorProducer(const UnitType * building); + }; + + // ===================================================== + // class AiRuleUpgrade + // ===================================================== + + class + AiRuleUpgrade : + public + AiRule { + private: + const UpgradeTask * + upgradeTask; + + public: + explicit + AiRuleUpgrade(Ai * ai); + + virtual int + getTestInterval() const { + return + 2000; + } + virtual string + getName() const { + return + "Performing upgrade task"; + } + + virtual bool + test(); + virtual void + execute(); + + private: + void + upgradeSpecific(const UpgradeTask * upgt); + void + upgradeGeneric(const UpgradeTask * upgt); + }; + + // ===================================================== + // class AiRuleExpand + // ===================================================== + + class + AiRuleExpand : + public + AiRule { + private: + static const int + expandDistance = 30; + + private: + Vec2i + expandPos; + const UnitType * + storeType; + + public: + explicit + AiRuleExpand(Ai * ai); + + virtual int + getTestInterval() const { + return + 30000; + } + virtual string + getName() const { + return + "Expanding"; + } + + virtual bool + test(); + virtual void + execute(); + }; + + // ===================================================== + // class AiRuleUnBlock + // ===================================================== + + class + AiRuleUnBlock : + public + AiRule { + public: + explicit + AiRuleUnBlock(Ai * ai); + + virtual int + getTestInterval() const { + return + 3000; + } + virtual string + getName() const { + return + "Blocked Units => Move surrounding units"; + } + + virtual bool + test(); + virtual void + execute(); + }; + + } +} //end namespace #endif diff --git a/source/glest_game/ai/path_finder.cpp b/source/glest_game/ai/path_finder.cpp index c383dc71b..d03016ec7 100644 --- a/source/glest_game/ai/path_finder.cpp +++ b/source/glest_game/ai/path_finder.cpp @@ -24,2096 +24,1852 @@ using namespace std; using namespace - Shared::Graphics; +Shared::Graphics; using namespace - Shared::Util; +Shared::Util; using namespace - Shared::PlatformCommon; +Shared::PlatformCommon; using - Shared::Util::RandomGen; +Shared::Util::RandomGen; namespace - Glest -{ - namespace - Game - { - -// ===================================================== -// class PathFinder -// ===================================================== - -// ===================== PUBLIC ======================== - - const int - PathFinder::maxFreeSearchRadius = 10; - - int - PathFinder::pathFindNodesAbsoluteMax = 900; - int - PathFinder::pathFindNodesMax = 2000; - const int - PathFinder::pathFindBailoutRadius = 20; - const int - PathFinder::pathFindExtendRefreshForNodeCount = 25; - const int - PathFinder::pathFindExtendRefreshNodeCountMin = 40; - const int - PathFinder::pathFindExtendRefreshNodeCountMax = 40; - - PathFinder::PathFinder () - { - minorDebugPathfinder = false; - map = NULL; - } - - int - PathFinder::getPathFindExtendRefreshNodeCount (FactionState & faction) - { - //int refreshNodeCount = faction.random.randRange(PathFinder::pathFindExtendRefreshNodeCountMin,PathFinder::pathFindExtendRefreshNodeCountMax); - //return refreshNodeCount; - return PathFinder::pathFindExtendRefreshNodeCountMin; - } - - PathFinder::PathFinder (const Map * map) - { - minorDebugPathfinder = false; - - map = NULL; - init (map); - } - - void - PathFinder::init (const Map * map) - { - for (int factionIndex = 0; factionIndex < GameConstants::maxPlayers; - ++factionIndex) - { - FactionState & faction = factions.getFactionState (factionIndex); - - faction.nodePool.resize (pathFindNodesAbsoluteMax); - faction.useMaxNodeCount = PathFinder::pathFindNodesMax; - } - this->map = map; - } - - void - PathFinder::init () - { - minorDebugPathfinder = false; - map = NULL; - } - - PathFinder::~PathFinder () - { - for (int factionIndex = 0; factionIndex < GameConstants::maxPlayers; - ++factionIndex) - { - FactionState & faction = factions.getFactionState (factionIndex); - - faction.nodePool.clear (); - } - factions.clear (); - map = NULL; - } - - void - PathFinder::clearCaches () - { - for (int factionIndex = 0; factionIndex < GameConstants::maxPlayers; - ++factionIndex) - { - static string - mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - FactionState & faction = factions.getFactionState (factionIndex); - MutexSafeWrapper - safeMutex (faction.getMutexPreCache (), mutexOwnerId); - - faction.precachedTravelState.clear (); - faction.precachedPath.clear (); - } - } - - void - PathFinder::clearUnitPrecache (Unit * unit) - { - if (unit != NULL && factions.size () > unit->getFactionIndex ()) - { - int - factionIndex = unit->getFactionIndex (); - static string - mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - FactionState & faction = factions.getFactionState (factionIndex); - MutexSafeWrapper - safeMutex (faction.getMutexPreCache (), mutexOwnerId); - - faction.precachedTravelState[unit->getId ()] = tsImpossible; - faction.precachedPath[unit->getId ()].clear (); - } - } - - void - PathFinder::removeUnitPrecache (Unit * unit) - { - if (unit != NULL && factions.size () > unit->getFactionIndex ()) - { - int - factionIndex = unit->getFactionIndex (); - static string - mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - FactionState & faction = factions.getFactionState (factionIndex); - MutexSafeWrapper - safeMutex (faction.getMutexPreCache (), mutexOwnerId); - - if (faction.precachedTravelState.find (unit->getId ()) != - faction.precachedTravelState.end ()) - { - faction.precachedTravelState.erase (unit->getId ()); - } - if (faction.precachedPath.find (unit->getId ()) != - faction.precachedPath.end ()) - { - faction.precachedPath.erase (unit->getId ()); - } - } - } - - TravelState - PathFinder::findPath (Unit * unit, const Vec2i & finalPos, - bool * wasStuck, int frameIndex) - { - TravelState - ts = tsImpossible; - - try - { - - int - factionIndex = unit->getFactionIndex (); - FactionState & faction = factions.getFactionState (factionIndex); - static string - mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexPrecache (faction.getMutexPreCache (), mutexOwnerId); - - if (map == NULL) - { - throw - megaglest_runtime_error ("map == NULL"); - } - - unit->setCurrentPathFinderDesiredFinalPos (finalPos); - - - if (frameIndex >= 0) - { - clearUnitPrecache (unit); - } - if (unit->getFaction ()->canUnitsPathfind () == true) - { - unit->getFaction ()->addUnitToPathfindingList (unit->getId ()); - } - else - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "canUnitsPathfind() == false"); - unit->logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - - return tsBlocked; - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "[findPath] unit->getPos() [%s] finalPos [%s]", - unit->getPos ().getString ().c_str (), - finalPos.getString ().c_str ()); - unit->logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - - //route cache - if (finalPos == unit->getPos ()) - { - if (frameIndex < 0) - { - //if arrived - unit->setCurrSkill (scStop); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Unit finalPos [%s] == unit->getPos() [%s]", - finalPos.getString ().c_str (), - unit->getPos ().getString ().c_str ()); - unit-> - logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPathFinder).enabled == - true) - { - string - commandDesc = "none"; - Command * - command = unit->getCurrCommand (); - if (command != NULL && command->getCommandType () != NULL) - { - commandDesc = - command->getCommandType ()->toString (false); - } - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "State: arrived#1 at pos: %s, command [%s]", - finalPos.getString ().c_str (), - commandDesc.c_str ()); - unit->setCurrentUnitTitle (szBuf); - } - - return tsArrived; - } - - UnitPathInterface * - path = unit->getPath (); - if (path->isEmpty () == false) - { - UnitPathBasic * - basic_path = dynamic_cast < UnitPathBasic * >(path); - if (basic_path != NULL) - { - //route cache - Vec2i - pos = basic_path->pop (frameIndex < 0); - - if (map->canMove (unit, unit->getPos (), pos)) - { - if (frameIndex < 0) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugWorldSynch).enabled == - true - && SystemFlags:: - getSystemSettingType (SystemFlags:: - debugWorldSynchMax). - enabled == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "#1 map->canMove to pos [%s] from [%s]", - pos.getString ().c_str (), - unit->getPos ().getString ().c_str ()); - unit-> - logSynchData (extractFileFromDirectoryPath - (__FILE__).c_str (), __LINE__, - szBuf); - } - - unit->setTargetPos (pos, frameIndex < 0); - - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugWorldSynch).enabled == - true - && SystemFlags:: - getSystemSettingType (SystemFlags:: - debugWorldSynchMax). - enabled == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "#2 map->canMove to pos [%s] from [%s]", - pos.getString ().c_str (), - unit->getPos ().getString ().c_str ()); - unit-> - logSynchData (extractFileFromDirectoryPath - (__FILE__).c_str (), __LINE__, - szBuf); - } - - } - - return tsMoving; - } - } - else if (dynamic_cast < UnitPath * >(path) != NULL) - { - UnitPath * - advPath = dynamic_cast < UnitPath * >(path); - //route cache - Vec2i - pos = advPath->peek (); - if (map->canMove (unit, unit->getPos (), pos)) - { - if (frameIndex < 0) - { - advPath->pop (); - unit->setTargetPos (pos, frameIndex < 0); - } - - return tsMoving; - } - } - else - { - throw - megaglest_runtime_error - ("unsupported or missing path finder detected!"); - } - } - - if (path->isStuck () == true && - (unit->getLastStuckPos () == finalPos - || path->getBlockCount () > 500) - && unit-> - isLastStuckFrameWithinCurrentFrameTolerance (frameIndex >= 0) == - true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "path->isStuck() == true unit->getLastStuckPos() [%s] finalPos [%s] path->getBlockCount() [%d]", - unit->getLastStuckPos ().getString ().c_str (), - finalPos.getString ().c_str (), - path->getBlockCount ()); - unit->logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - - return tsBlocked; - } - - //route cache miss - int - maxNodeCount = -1; - if (unit->getUsePathfinderExtendedMaxNodes () == true) - { - - maxNodeCount = PathFinder::pathFindNodesAbsoluteMax; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "maxNodeCount: %d", maxNodeCount); - unit->logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - } - - bool - minorDebugPathfinderPerformance = false; - Chrono - chrono; - if (minorDebugPathfinderPerformance) - chrono.start (); - - uint32 - searched_node_count = 0; - minorDebugPathfinder = false; - if (minorDebugPathfinder) - printf - ("Legacy Pathfind Unit [%d - %s] from = %s to = %s frameIndex = %d\n", - unit->getId (), unit->getType ()->getName (false).c_str (), - unit->getPos ().getString ().c_str (), - finalPos.getString ().c_str (), frameIndex); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "calling aStar()"); - unit->logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - - ts = - aStar (unit, finalPos, false, frameIndex, maxNodeCount, - &searched_node_count); - //post actions - switch (ts) - { - case tsBlocked: - case tsArrived: - // The unit is stuck (not only blocked but unable to go anywhere for a while) - // We will try to bail out of the immediate area - if (ts == tsBlocked && unit->getInBailOutAttempt () == false && - path->isStuck () == true) - { - - if (minorDebugPathfinder) - printf - ("Pathfind Unit [%d - %s] START BAILOUT ATTEMPT frameIndex = %d\n", - unit->getId (), - unit->getType ()->getName (false).c_str (), frameIndex); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "[attempting to BAIL OUT] finalPos [%s] ts [%d]", - finalPos.getString ().c_str (), ts); - unit-> - logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - - if (wasStuck != NULL) - { - *wasStuck = true; - } - unit->setInBailOutAttempt (true); - - bool - unitImmediatelyBlocked = false; - - // First check if unit currently blocked all around them, if so don't try to pathfind - const Vec2i - unitPos = unit->getPos (); - int - failureCount = 0; - int - cellCount = 0; - - for (int i = -1; i <= 1; ++i) - { - for (int j = -1; j <= 1; ++j) - { - Vec2i - pos = unitPos + Vec2i (i, j); - if (pos != unitPos) - { - bool - canUnitMoveToCell = - map->aproxCanMove (unit, unitPos, pos); - if (canUnitMoveToCell == false) - { - failureCount++; - } - cellCount++; - } - } - } - unitImmediatelyBlocked = (failureCount == cellCount); - if (unitImmediatelyBlocked == false) - { - - int - factionIndex = unit->getFactionIndex (); - FactionState & faction = - factions.getFactionState (factionIndex); - - //if(Thread::isCurrentThreadMainThread() == false) { - // throw megaglest_runtime_error("#2 Invalid access to FactionState random from outside main thread current id = " + - // intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId())); - //} - - int - tryRadius = faction.random.randRange (1, 2); - //int tryRadius = faction.random.IRandomX(1,2); - //int tryRadius = 1; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In astar bailout() tryRadius %d", - tryRadius); - - if (frameIndex >= 0) - { - unit->logSynchDataThreaded (__FILE__, __LINE__, - szBuf); - } - else - { - unit->logSynchData (__FILE__, __LINE__, szBuf); - } - } - - // Try to bail out up to PathFinder::pathFindBailoutRadius cells away - if (tryRadius == 2) - { - for (int bailoutX = - -PathFinder::pathFindBailoutRadius; - bailoutX <= PathFinder::pathFindBailoutRadius - && ts == tsBlocked; ++bailoutX) - { - for (int bailoutY = - -PathFinder::pathFindBailoutRadius; - bailoutY <= PathFinder::pathFindBailoutRadius - && ts == tsBlocked; ++bailoutY) - { - const Vec2i - newFinalPos = - finalPos + Vec2i (bailoutX, bailoutY); - bool - canUnitMove = - map->canMove (unit, unit->getPos (), - newFinalPos); - - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugWorldSynch). - enabled == true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "[attempting to BAIL OUT] finalPos [%s] newFinalPos [%s] ts [%d] canUnitMove [%d]", - finalPos.getString ().c_str (), - newFinalPos.getString (). - c_str (), ts, canUnitMove); - unit-> - logSynchData - (extractFileFromDirectoryPath - (__FILE__).c_str (), __LINE__, szBuf); - } - - if (canUnitMove) - { - - int - maxBailoutNodeCount = - (PathFinder::pathFindBailoutRadius * 2); - - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugWorldSynch). - enabled == true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "calling aStar()"); - unit-> - logSynchData - (extractFileFromDirectoryPath - (__FILE__).c_str (), __LINE__, - szBuf); - } - - ts = - aStar (unit, newFinalPos, true, - frameIndex, maxBailoutNodeCount, - &searched_node_count); - } - } - } - } - else - { - for (int bailoutX = PathFinder::pathFindBailoutRadius; - bailoutX >= -PathFinder::pathFindBailoutRadius - && ts == tsBlocked; --bailoutX) - { - for (int bailoutY = - PathFinder::pathFindBailoutRadius; - bailoutY >= - -PathFinder::pathFindBailoutRadius - && ts == tsBlocked; --bailoutY) - { - const Vec2i - newFinalPos = - finalPos + Vec2i (bailoutX, bailoutY); - bool - canUnitMove = - map->canMove (unit, unit->getPos (), - newFinalPos); - - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugWorldSynch). - enabled == true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "[attempting to BAIL OUT] finalPos [%s] newFinalPos [%s] ts [%d] canUnitMove [%d]", - finalPos.getString ().c_str (), - newFinalPos.getString (). - c_str (), ts, canUnitMove); - unit-> - logSynchData - (extractFileFromDirectoryPath - (__FILE__).c_str (), __LINE__, szBuf); - } - - if (canUnitMove) - { - int - maxBailoutNodeCount = - (PathFinder::pathFindBailoutRadius * 2); - - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugWorldSynch). - enabled == true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "calling aStar()"); - unit-> - logSynchData - (extractFileFromDirectoryPath - (__FILE__).c_str (), __LINE__, - szBuf); - } - - ts = - aStar (unit, newFinalPos, true, - frameIndex, maxBailoutNodeCount, - &searched_node_count); - } - } - } - } - } - unit->setInBailOutAttempt (false); - - if (ts == tsBlocked) - { - unit->setLastStuckFrameToCurrentFrame (); - unit->setLastStuckPos (finalPos); - } - } - if (ts == tsArrived || ts == tsBlocked) - { - if (frameIndex < 0) - { - unit->setCurrSkill (scStop); - } - } - break; - case tsMoving: - { - if (dynamic_cast < UnitPathBasic * >(path) != NULL) - { - UnitPathBasic * - basicPath = dynamic_cast < UnitPathBasic * >(path); - Vec2i - pos; - if (frameIndex < 0 && basicPath != NULL) - { - pos = basicPath->pop (frameIndex < 0); - } - else - { - - if (faction.precachedPath[unit->getId ()].size () <= 0) - { - throw - megaglest_runtime_error - ("factions[unit->getFactionIndex()].precachedPath[unit->getId()].size() <= 0!"); - } - - pos = faction.precachedPath[unit->getId ()][0]; - - } - - if (map->canMove (unit, unit->getPos (), pos)) - { - if (frameIndex < 0) - { - unit->setTargetPos (pos, frameIndex < 0); - } - } - else - { - if (frameIndex < 0) - { - unit->setCurrSkill (scStop); - } - - if (minorDebugPathfinderPerformance - && chrono.getMillis () >= 1) - printf - ("Unit [%d - %s] astar #2 took [%lld] msecs, ts = %d searched_node_count = %d.\n", - unit->getId (), - unit->getType ()->getName (false).c_str (), - (long long int) chrono.getMillis (), ts, - searched_node_count); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "tsBlocked"); - unit-> - logSynchData (extractFileFromDirectoryPath - (__FILE__).c_str (), __LINE__, - szBuf); - } - - return tsBlocked; - } - } - else if (dynamic_cast < UnitPath * >(path) != NULL) - { - UnitPath * - advPath = dynamic_cast < UnitPath * >(path); - Vec2i - pos = advPath->peek (); - if (map->canMove (unit, unit->getPos (), pos)) - { - if (frameIndex < 0) - { - advPath->pop (); - unit->setTargetPos (pos, frameIndex < 0); - } - } - else - { - if (frameIndex < 0) - { - unit->setCurrSkill (scStop); - } - - if (minorDebugPathfinder) - printf - ("Pathfind Unit [%d - %s] INT BAILOUT ATTEMPT BLOCKED frameIndex = %d\n", - unit->getId (), - unit->getType ()->getName (false).c_str (), - frameIndex); - - if (minorDebugPathfinderPerformance - && chrono.getMillis () >= 1) - printf - ("Unit [%d - %s] astar #3 took [%lld] msecs, ts = %d searched_node_count = %d.\n", - unit->getId (), - unit->getType ()->getName (false).c_str (), - (long long int) chrono.getMillis (), ts, - searched_node_count); - return tsBlocked; - } - } - else - { - throw - megaglest_runtime_error - ("unsupported or missing path finder detected!"); - } - } - break; - - default: - break; - } - if (minorDebugPathfinderPerformance && chrono.getMillis () >= 1) - printf - ("Unit [%d - %s] astar took [%lld] msecs, ts = %d searched_node_count = %d.\n", - unit->getId (), unit->getType ()->getName (false).c_str (), - (long long int) chrono.getMillis (), ts, searched_node_count); - - } - catch (const exception & ex) - { - //setRunningStatus(false); - - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - ex.what ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - throw - megaglest_runtime_error (ex.what ()); - } - catch ( ...) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, - __FUNCTION__, __LINE__); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw - megaglest_runtime_error (szBuf); - } - - return ts; - } - -// ==================== PRIVATE ==================== - -//route a unit using A* algorithm - TravelState - PathFinder::aStar (Unit * unit, const Vec2i & targetPos, bool inBailout, - int frameIndex, int maxNodeCount, - uint32 * searched_node_count) - { - TravelState - ts = tsImpossible; - - try - { - - int - unitFactionIndex = unit->getFactionIndex (); - int - factionIndex = unit->getFactionIndex (); - FactionState & faction = factions.getFactionState (factionIndex); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true && frameIndex >= 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In aStar()"); - unit->logSynchDataThreaded (__FILE__, __LINE__, szBuf); - } - - Chrono - chrono; - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled) - chrono.start (); - - if (map == NULL) - { - throw - megaglest_runtime_error ("map == NULL"); - } - - - if (maxNodeCount < 0) - { - - int - factionIndex = unit->getFactionIndex (); - FactionState & faction = factions.getFactionState (factionIndex); - - maxNodeCount = faction.useMaxNodeCount; - } - - if (maxNodeCount >= 1 - && unit->getPathfindFailedConsecutiveFrameCount () >= 3) - { - maxNodeCount = 200; - } - - UnitPathInterface * - path = unit->getPath (); - - faction.nodePoolCount = 0; - faction.openNodesList.clear (); - faction.openPosList.clear (); - faction.closedNodesList.clear (); - - // check the pre-cache to see if we can re-use a cached path - if (frameIndex < 0) - { - - bool - foundPrecacheTravelState = - (faction.precachedTravelState.find (unit->getId ()) != - faction.precachedTravelState.end ()); - if (foundPrecacheTravelState == true) - { - -// if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { -// char szBuf[8096]=""; -// snprintf(szBuf,8096,"factions[unitFactionIndex].precachedTravelState[unit->getId()]: %d",faction.precachedTravelState[unit->getId()]); -// unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); -// } - - bool - foundPrecacheTravelStateIsMoving = - (faction.precachedTravelState[unit->getId ()] == tsMoving); - if (foundPrecacheTravelStateIsMoving == true) - { - bool - canMoveToCells = true; - - Vec2i - lastPos = unit->getPos (); - - int - unitPrecachePathSize = - (int) faction.precachedPath[unit->getId ()].size (); - - for (int i = 0; i < unitPrecachePathSize; i++) - { - - Vec2i - nodePos = faction.precachedPath[unit->getId ()][i]; - - if (map->isInside (nodePos) == false - || map->isInsideSurface (map-> - toSurfCoords (nodePos)) - == false) - { - throw - megaglest_runtime_error - ("Pathfinder invalid node path position = " + - nodePos.getString () + " i = " + intToStr (i)); - } - - if (i < unit->getPathFindRefreshCellCount () || - (unitPrecachePathSize >= - pathFindExtendRefreshForNodeCount - && i < - getPathFindExtendRefreshNodeCount (faction))) - { - - if (canUnitMoveSoon (unit, lastPos, nodePos) == - false) - { - canMoveToCells = false; - break; - } - lastPos = nodePos; - } - else - { - break; - } - } - - if (canMoveToCells == true) - { - path->clear (); - //UnitPathBasic *basicPathFinder = dynamic_cast(path); - - int - unitPrecachePathSize = - (int) faction.precachedPath[unit->getId ()].size (); - - for (int i = 0; i < unitPrecachePathSize; i++) - { - - Vec2i - nodePos = - faction.precachedPath[unit->getId ()][i]; - - if (map->isInside (nodePos) == false - || map->isInsideSurface (map-> - toSurfCoords - (nodePos)) == false) - { - throw - megaglest_runtime_error - ("Pathfinder invalid node path position = " - + nodePos.getString () + " i = " + - intToStr (i)); - } - - //if(i < pathFindRefresh || - if (i < unit->getPathFindRefreshCellCount () || - (unitPrecachePathSize >= - pathFindExtendRefreshForNodeCount - && i < - getPathFindExtendRefreshNodeCount (faction))) - { - path->add (nodePos); - } - } - unit->setUsePathfinderExtendedMaxNodes (false); - - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugWorldSynch).enabled == - true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "return factions[unitFactionIndex].precachedTravelState[unit->getId()];"); - unit-> - logSynchData (extractFileFromDirectoryPath - (__FILE__).c_str (), __LINE__, - szBuf); - } - - return faction.precachedTravelState[unit->getId ()]; - } - else - { - clearUnitPrecache (unit); - } - } - else - { - - bool - foundPrecacheTravelStateIsBlocked = - (faction.precachedTravelState[unit->getId ()] == - tsBlocked); - - if (foundPrecacheTravelStateIsBlocked == true) - { - path->incBlockCount (); - unit->setUsePathfinderExtendedMaxNodes (false); - -// if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { -// char szBuf[8096]=""; -// snprintf(szBuf,8096,"return factions[unitFactionIndex].precachedTravelState[unit->getId()];"); -// unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); -// } - - return faction.precachedTravelState[unit->getId ()]; - } - } - } - } - else - { - clearUnitPrecache (unit); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "[clearUnitPrecache]"); - unit->logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - } - - const Vec2i - unitPos = unit->getPos (); - const Vec2i - finalPos = computeNearestFreePos (unit, targetPos); - - float - dist = unitPos.dist (finalPos); - - faction.useMaxNodeCount = PathFinder::pathFindNodesMax; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled == true && chrono.getMillis () > 4) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - - //path find algorithm - - //a) push starting pos into openNodes - Node * - firstNode = newNode (faction, maxNodeCount); - if (firstNode == NULL) - { - throw - megaglest_runtime_error ("firstNode == NULL"); - } - - firstNode->next = NULL; - firstNode->prev = NULL; - firstNode->pos = unitPos; - firstNode->heuristic = heuristic (unitPos, finalPos); - firstNode->exploredCell = true; - if (faction.openNodesList.find (firstNode->heuristic) == - faction.openNodesList.end ()) - { - faction.openNodesList[firstNode->heuristic].clear (); - } - faction.openNodesList[firstNode->heuristic].push_back (firstNode); - faction.openPosList[firstNode->pos] = true; - - //b) loop - bool - pathFound = true; - bool - nodeLimitReached = false; - Node * - node = NULL; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled == true && chrono.getMillis () > 4) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - - // First check if unit currently blocked all around them, if so don't try to pathfind - if (inBailout == false && unitPos != finalPos) - { - int - failureCount = 0; - int - cellCount = 0; - - for (int i = -1; i <= 1; ++i) - { - for (int j = -1; j <= 1; ++j) - { - Vec2i - pos = unitPos + Vec2i (i, j); - if (pos != unitPos) - { - bool - canUnitMoveToCell = - canUnitMoveSoon (unit, unitPos, pos); - if (canUnitMoveToCell == false) - { - failureCount++; - } - cellCount++; - } - } - } - nodeLimitReached = (failureCount == cellCount); - pathFound = !nodeLimitReached; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "nodeLimitReached: %d failureCount: %d cellCount: %d", - nodeLimitReached, failureCount, cellCount); - unit->logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled == true && chrono.getMillis () > 1) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] **Check if dest blocked, distance for unit [%d - %s] from [%s] to [%s] is %.2f took msecs: %lld nodeLimitReached = %d, failureCount = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, unit->getId (), - unit->getFullName (false).c_str (), - unitPos.getString ().c_str (), - finalPos.getString ().c_str (), dist, - (long long int) chrono.getMillis (), - nodeLimitReached, failureCount); - - if (nodeLimitReached == false) - { - // First check if final destination blocked - failureCount = 0; - cellCount = 0; - - for (int i = -1; i <= 1; ++i) - { - for (int j = -1; j <= 1; ++j) - { - Vec2i - pos = finalPos + Vec2i (i, j); - if (pos != finalPos) - { - bool - canUnitMoveToCell = - canUnitMoveSoon (unit, pos, finalPos); - if (canUnitMoveToCell == false) - { - failureCount++; - } - cellCount++; - } - } - } - nodeLimitReached = (failureCount == cellCount); - pathFound = !nodeLimitReached; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "nodeLimitReached: %d failureCount: %d cellCount: %d", - nodeLimitReached, failureCount, cellCount); - unit-> - logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled == true && chrono.getMillis () > 1) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] **Check if dest blocked, distance for unit [%d - %s] from [%s] to [%s] is %.2f took msecs: %lld nodeLimitReached = %d, failureCount = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, unit->getId (), - unit->getFullName (false). - c_str (), - unitPos.getString ().c_str (), - finalPos.getString ().c_str (), - dist, - (long long int) chrono. - getMillis (), nodeLimitReached, - failureCount); - } - } - else - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "inBailout: %d unitPos: [%s] finalPos [%s]", - inBailout, unitPos.getString ().c_str (), - finalPos.getString ().c_str ()); - unit->logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - } - // - - // START - std::map < std::pair < Vec2i, Vec2i >, bool > canAddNode; - std::map < Vec2i, bool > closedNodes; - std::map < Vec2i, Vec2i > cameFrom; - cameFrom[unitPos] = Vec2i (-1, -1); - - // Do the a-star base pathfind work if required - int - whileLoopCount = 0; - if (nodeLimitReached == false) - { - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Calling doAStarPathSearch nodeLimitReached: %d whileLoopCount: %d unitFactionIndex: %d pathFound: %d finalPos [%s] maxNodeCount: %d frameIndex: %d", - nodeLimitReached, whileLoopCount, unitFactionIndex, - pathFound, finalPos.getString ().c_str (), - maxNodeCount, frameIndex); - unit->logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - - doAStarPathSearch (nodeLimitReached, whileLoopCount, - unitFactionIndex, pathFound, node, finalPos, - closedNodes, cameFrom, canAddNode, unit, - maxNodeCount, frameIndex); - - if (searched_node_count != NULL) - { - *searched_node_count = whileLoopCount; - } - - // Now see if the unit is eligible for pathfind max nodes boost? - if (nodeLimitReached == true) - { - unit->incrementPathfindFailedConsecutiveFrameCount (); - } - else - { - unit->resetPathfindFailedConsecutiveFrameCount (); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Calling doAStarPathSearch nodeLimitReached: %d whileLoopCount: %d unitFactionIndex: %d pathFound: %d finalPos [%s] maxNodeCount: %d pathFindNodesAbsoluteMax: %d frameIndex: %d", - nodeLimitReached, whileLoopCount, unitFactionIndex, - pathFound, finalPos.getString ().c_str (), - maxNodeCount, pathFindNodesAbsoluteMax, frameIndex); - unit->logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - - if (nodeLimitReached == true - && maxNodeCount != pathFindNodesAbsoluteMax) - { - if (unit-> - isLastPathfindFailedFrameWithinCurrentFrameTolerance () == - true) - { - if (frameIndex < 0) - { - unit->setLastPathfindFailedFrameToCurrentFrame (); - unit->setLastPathfindFailedPos (finalPos); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "calling aStar()"); - unit-> - logSynchData (extractFileFromDirectoryPath - (__FILE__).c_str (), __LINE__, szBuf); - } - - return aStar (unit, targetPos, false, frameIndex, - pathFindNodesAbsoluteMax); - } - } - } - else - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "nodeLimitReached: %d", - nodeLimitReached); - unit->logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - } - - - Node * - lastNode = node; - - //if consumed all nodes find best node (to avoid strange behaviour) - if (nodeLimitReached == true) - { - - if (faction.closedNodesList.empty () == false) - { - float - bestHeuristic = - truncateDecimal < - float >(faction.closedNodesList.begin ()->first, 6); - if (lastNode != NULL && bestHeuristic < lastNode->heuristic) - { - lastNode = - faction.closedNodesList.begin ()->second.front (); - } - } - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled == true && chrono.getMillis () > 4) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - - //check results of path finding - ts = tsImpossible; - if (pathFound == false || lastNode == firstNode) - { - if (minorDebugPathfinder) - printf - ("Legacy Pathfind Unit [%d - %s] NOT FOUND PATH count = %d frameIndex = %d\n", - unit->getId (), unit->getType ()->getName ().c_str (), - whileLoopCount, frameIndex); - - //blocked - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPathFinder).enabled == - true) - { - string - commandDesc = "none"; - Command * - command = unit->getCurrCommand (); - if (command != NULL && command->getCommandType () != NULL) - { - commandDesc = - command->getCommandType ()->toString (false); - } - - std::pair < Vec2i, int > - lastHarvest = unit->getLastHarvestResourceTarget (); - - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "State: blocked, cmd [%s] pos: [%s], dest pos: [%s], lastHarvest = [%s - %d], reason A= %d, B= %d, C= %d, D= %d, E= %d, F = %d", - commandDesc.c_str (), - unit->getPos ().getString ().c_str (), - targetPos.getString ().c_str (), - lastHarvest.first.getString ().c_str (), - lastHarvest.second, pathFound, - (lastNode == firstNode), path->getBlockCount (), - path->isBlocked (), nodeLimitReached, - path->isStuck ()); - unit->setCurrentUnitTitle (szBuf); - } - - if (frameIndex < 0) - { - unit->setUsePathfinderExtendedMaxNodes (false); - } - - ts = tsBlocked; - if (frameIndex < 0) - { - path->incBlockCount (); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled == true && chrono.getMillis () > 4) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - } - else - { - if (minorDebugPathfinder) - printf - ("Legacy Pathfind Unit [%d - %s] FOUND PATH count = %d frameIndex = %d\n", - unit->getId (), unit->getType ()->getName ().c_str (), - whileLoopCount, frameIndex); - //on the way - ts = tsMoving; - - //build next pointers - Node * - currNode = lastNode; - while (currNode->prev != NULL) - { - currNode->prev->next = currNode; - currNode = currNode->prev; - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled == true && chrono.getMillis () > 4) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - - if (frameIndex < 0) - { - if (maxNodeCount == pathFindNodesAbsoluteMax) - { - unit->setUsePathfinderExtendedMaxNodes (true); - } - else - { - unit->setUsePathfinderExtendedMaxNodes (false); - } - } - - //store path - if (frameIndex < 0) - { - path->clear (); - } - - //UnitPathBasic *basicPathFinder = dynamic_cast(path); - - currNode = firstNode; - - for (int i = 0; currNode->next != NULL; - currNode = currNode->next, i++) - { - Vec2i - nodePos = currNode->next->pos; - if (map->isInside (nodePos) == false - || map->isInsideSurface (map->toSurfCoords (nodePos)) == - false) - { - throw - megaglest_runtime_error - ("Pathfinder invalid node path position = " + - nodePos.getString () + " i = " + intToStr (i)); - } - - if (minorDebugPathfinder) - printf ("nodePos [%s]\n", nodePos.getString ().c_str ()); - - if (frameIndex >= 0) - { - faction.precachedPath[unit->getId ()].push_back (nodePos); - } - else - { - if (i < unit->getPathFindRefreshCellCount () || - (whileLoopCount >= pathFindExtendRefreshForNodeCount - && i < getPathFindExtendRefreshNodeCount (faction))) - { - path->add (nodePos); - } - } - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled == true && chrono.getMillis () > 4) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true - && SystemFlags::getSystemSettingType (SystemFlags:: - debugWorldSynchMax). - enabled == true) - { - char - szBuf[8096] = ""; - - string - pathToTake = ""; - if (frameIndex < 0) - { - vector < Vec2i > pathQueue = path->getQueue (); - for (unsigned int index = 0; index < pathQueue.size (); - ++index) - { - Vec2i & pos = pathQueue[index]; - if (pathToTake != "") - { - pathToTake += ", "; - } - pathToTake += pos.getString (); - } - } - else - { - for (unsigned int index = 0; - index < - faction.precachedPath[unit->getId ()].size (); - ++index) - { - Vec2i & pos = - faction.precachedPath[unit->getId ()][index]; - if (pathToTake != "") - { - pathToTake += ", "; - } - pathToTake += pos.getString (); - } - } - snprintf (szBuf, 8096, "Path for unit to take = %s", - pathToTake.c_str ()); - if (frameIndex < 0) - { - unit-> - logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - else - { - unit-> - logSynchDataThreaded (extractFileFromDirectoryPath - (__FILE__).c_str (), __LINE__, - szBuf); - } - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPathFinder).enabled == - true) - { - string - commandDesc = "none"; - Command * - command = unit->getCurrCommand (); - if (command != NULL && command->getCommandType () != NULL) - { - commandDesc = - command->getCommandType ()->toString (false); - } - - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "State: moving, cmd [%s] pos: %s dest pos: %s, Queue= %d", - commandDesc.c_str (), - unit->getPos ().getString ().c_str (), - targetPos.getString ().c_str (), - path->getQueueCount ()); - unit->setCurrentUnitTitle (szBuf); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled == true && chrono.getMillis () > 4) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - } - - - faction.openNodesList.clear (); - faction.openPosList.clear (); - faction.closedNodesList.clear (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled == true && chrono.getMillis () > 4) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - - if (frameIndex >= 0) - { - - FactionState & faction = factions.getFactionState (factionIndex); - faction.precachedTravelState[unit->getId ()] = ts; - } - else - { - if (SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis () >= 5) - printf - ("In [%s::%s Line: %d] astar took [%lld] msecs, ts = %d.\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, (long long int) chrono.getMillis (), - ts); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true && frameIndex < 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "return ts: %d", ts); - unit->logSynchData (extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__, szBuf); - } - - } - catch (const exception & ex) - { - - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - ex.what ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - throw - megaglest_runtime_error (ex.what ()); - } - catch ( ...) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, - __FUNCTION__, __LINE__); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw - megaglest_runtime_error (szBuf); - } - - return ts; - } - - void - PathFinder::processNearestFreePos (const Vec2i & finalPos, int i, int j, - int size, Field field, int teamIndex, - Vec2i unitPos, Vec2i & nearestPos, - float &nearestDist) - { - - try - { - Vec2i - currPos = finalPos + Vec2i (i, j); - - if (map->isAproxFreeCells (currPos, size, field, teamIndex)) - { - float - dist = currPos.dist (finalPos); - - //if nearer from finalPos - if (dist < nearestDist) - { - nearestPos = currPos; - nearestDist = dist; - } - //if the distance is the same compare distance to unit - else if (dist == nearestDist) - { - if (currPos.dist (unitPos) < nearestPos.dist (unitPos)) - { - nearestPos = currPos; - } - } - } - } - catch (const exception & ex) - { - - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - ex.what ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - throw - megaglest_runtime_error (ex.what ()); - } - catch ( ...) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, - __FUNCTION__, __LINE__); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw - megaglest_runtime_error (szBuf); - } - - } - - Vec2i - PathFinder::computeNearestFreePos (const Unit * unit, - const Vec2i & finalPos) - { - - Vec2i - nearestPos (0, 0); - try - { - - if (map == NULL) - { - throw - megaglest_runtime_error ("map == NULL"); - } - - //unit data - int - size = unit->getType ()->getSize (); - Field - field = unit->getCurrField (); - int - teamIndex = unit->getTeam (); - - //if finalPos is free return it - if (map->isAproxFreeCells (finalPos, size, field, teamIndex)) - { - return finalPos; - } - - //find nearest pos - Vec2i - unitPos = unit->getPosNotThreadSafe (); - nearestPos = unitPos; - - float - nearestDist = unitPos.dist (finalPos); - - for (int i = -maxFreeSearchRadius; i <= maxFreeSearchRadius; ++i) - { - for (int j = -maxFreeSearchRadius; j <= maxFreeSearchRadius; ++j) - { - processNearestFreePos (finalPos, i, j, size, field, teamIndex, - unitPos, nearestPos, nearestDist); - } - } - - } - catch (const exception & ex) - { - - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - ex.what ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - throw - megaglest_runtime_error (ex.what ()); - } - catch ( ...) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, - __FUNCTION__, __LINE__); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw - megaglest_runtime_error (szBuf); - } - - return nearestPos; - } - - int - PathFinder::findNodeIndex (Node * node, Nodes & nodeList) - { - int - index = -1; - if (node != NULL) - { - for (unsigned int i = 0; i < nodeList.size (); ++i) - { - Node * - curnode = nodeList[i]; - if (node == curnode) - { - index = i; - break; - } - } - } - return index; - } - - int - PathFinder::findNodeIndex (Node * node, std::vector < Node > &nodeList) - { - int - index = -1; - if (node != NULL) - { - for (unsigned int i = 0; i < nodeList.size (); ++i) - { - Node & curnode = nodeList[i]; - if (node == &curnode) - { - index = i; - break; - } - } - } - return index; - } - -//bool PathFinder::unitCannotMove(Unit *unit) { -// bool unitImmediatelyBlocked = false; -// -// try { -// // First check if unit currently blocked all around them, if so don't try to pathfind -// const Vec2i unitPos = unit->getPos(); -// int failureCount = 0; -// int cellCount = 0; -// -// for(int i = -1; i <= 1; ++i) { -// for(int j = -1; j <= 1; ++j) { -// Vec2i pos = unitPos + Vec2i(i, j); -// if(pos != unitPos) { -// bool canUnitMoveToCell = map->aproxCanMove(unit, unitPos, pos); -// if(canUnitMoveToCell == false) { -// failureCount++; -// } -// cellCount++; -// } -// } -// } -// unitImmediatelyBlocked = (failureCount == cellCount); -// -// } -// catch(const exception &ex) { -// //setRunningStatus(false); -// -// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -// -// throw megaglest_runtime_error(ex.what()); -// } -// catch(...) { -// char szBuf[8096]=""; -// snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); -// SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); -// throw megaglest_runtime_error(szBuf); -// } -// -// return unitImmediatelyBlocked; -//} - - void - PathFinder::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode * - pathfinderNode = rootNode->addChild ("PathFinder"); - - pathfinderNode->addAttribute ("pathFindNodesMax", - intToStr (pathFindNodesMax), - mapTagReplacements); - pathfinderNode->addAttribute ("pathFindNodesAbsoluteMax", - intToStr (pathFindNodesAbsoluteMax), - mapTagReplacements); - for (unsigned int i = 0; i < (unsigned int) factions.size (); ++i) - { - FactionState & factionState = factions.getFactionState (i); - XmlNode * - factionsNode = pathfinderNode->addChild ("factions"); - - for (unsigned int j = 0; - j < (unsigned int) factionState.nodePool.size (); ++j) - { - Node * - curNode = &factionState.nodePool[j]; - XmlNode * - nodePoolNode = factionsNode->addChild ("nodePool"); - - nodePoolNode->addAttribute ("pos", curNode->pos.getString (), - mapTagReplacements); - int - nextIdx = - findNodeIndex (curNode->next, factionState.nodePool); - nodePoolNode->addAttribute ("next", intToStr (nextIdx), - mapTagReplacements); - int - prevIdx = - findNodeIndex (curNode->prev, factionState.nodePool); - nodePoolNode->addAttribute ("prev", intToStr (prevIdx), - mapTagReplacements); - nodePoolNode->addAttribute ("heuristic", - floatToStr (curNode->heuristic, 6), - mapTagReplacements); - nodePoolNode->addAttribute ("exploredCell", - intToStr (curNode->exploredCell), - mapTagReplacements); - } - - factionsNode->addAttribute ("nodePoolCount", - intToStr (factionState.nodePoolCount), - mapTagReplacements); - factionsNode->addAttribute ("random", - intToStr (factionState.random. - getLastNumber ()), - mapTagReplacements); - factionsNode->addAttribute ("useMaxNodeCount", - intToStr (factionState.useMaxNodeCount), - mapTagReplacements); - } - } - - void - PathFinder::loadGame (const XmlNode * rootNode) - { - const XmlNode * - pathfinderNode = rootNode->getChild ("PathFinder"); - - vector < XmlNode * >factionsNodeList = - pathfinderNode->getChildList ("factions"); - for (unsigned int i = 0; i < (unsigned int) factionsNodeList.size (); - ++i) - { - XmlNode * - factionsNode = factionsNodeList[i]; - - FactionState & factionState = factions.getFactionState (i); - vector < XmlNode * >nodePoolListNode = - factionsNode->getChildList ("nodePool"); - for (unsigned int j = 0; - j < (unsigned int) nodePoolListNode.size () - && j < (unsigned int) pathFindNodesAbsoluteMax; ++j) - { - XmlNode * - nodePoolNode = nodePoolListNode[j]; - - Node * - curNode = &factionState.nodePool[j]; - curNode->pos = - Vec2i::strToVec2 (nodePoolNode->getAttribute ("pos")-> - getValue ()); - int - nextNode = - nodePoolNode->getAttribute ("next")->getIntValue (); - if (nextNode >= 0) - { - curNode->next = &factionState.nodePool[nextNode]; - } - else - { - curNode->next = NULL; - } - - int - prevNode = - nodePoolNode->getAttribute ("prev")->getIntValue (); - if (prevNode >= 0) - { - curNode->prev = &factionState.nodePool[prevNode]; - } - else - { - curNode->prev = NULL; - } - curNode->heuristic = - nodePoolNode->getAttribute ("heuristic")->getFloatValue (); - curNode->exploredCell = - nodePoolNode->getAttribute ("exploredCell")->getIntValue () != - 0; - } - - factionState.nodePoolCount = - factionsNode->getAttribute ("nodePoolCount")->getIntValue (); - factionState.random.setLastNumber (factionsNode-> - getAttribute ("random")-> - getIntValue ()); - factionState.useMaxNodeCount = PathFinder::pathFindNodesMax; - } - } - - } + Glest { + namespace + Game { + + // ===================================================== + // class PathFinder + // ===================================================== + + // ===================== PUBLIC ======================== + + const int + PathFinder::maxFreeSearchRadius = 10; + + int + PathFinder::pathFindNodesAbsoluteMax = 900; + int + PathFinder::pathFindNodesMax = 2000; + const int + PathFinder::pathFindBailoutRadius = 20; + const int + PathFinder::pathFindExtendRefreshForNodeCount = 25; + const int + PathFinder::pathFindExtendRefreshNodeCountMin = 40; + const int + PathFinder::pathFindExtendRefreshNodeCountMax = 40; + + PathFinder::PathFinder() { + minorDebugPathfinder = false; + map = NULL; + } + + int + PathFinder::getPathFindExtendRefreshNodeCount(FactionState & faction) { + //int refreshNodeCount = faction.random.randRange(PathFinder::pathFindExtendRefreshNodeCountMin,PathFinder::pathFindExtendRefreshNodeCountMax); + //return refreshNodeCount; + return PathFinder::pathFindExtendRefreshNodeCountMin; + } + + PathFinder::PathFinder(const Map * map) { + minorDebugPathfinder = false; + + map = NULL; + init(map); + } + + void + PathFinder::init(const Map * map) { + for (int factionIndex = 0; factionIndex < GameConstants::maxPlayers; + ++factionIndex) { + FactionState & faction = factions.getFactionState(factionIndex); + + faction.nodePool.resize(pathFindNodesAbsoluteMax); + faction.useMaxNodeCount = PathFinder::pathFindNodesMax; + } + this->map = map; + } + + void + PathFinder::init() { + minorDebugPathfinder = false; + map = NULL; + } + + PathFinder::~PathFinder() { + for (int factionIndex = 0; factionIndex < GameConstants::maxPlayers; + ++factionIndex) { + FactionState & faction = factions.getFactionState(factionIndex); + + faction.nodePool.clear(); + } + factions.clear(); + map = NULL; + } + + void + PathFinder::clearCaches() { + for (int factionIndex = 0; factionIndex < GameConstants::maxPlayers; + ++factionIndex) { + static string + mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + FactionState & faction = factions.getFactionState(factionIndex); + MutexSafeWrapper + safeMutex(faction.getMutexPreCache(), mutexOwnerId); + + faction.precachedTravelState.clear(); + faction.precachedPath.clear(); + } + } + + void + PathFinder::clearUnitPrecache(Unit * unit) { + if (unit != NULL && factions.size() > unit->getFactionIndex()) { + int + factionIndex = unit->getFactionIndex(); + static string + mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + FactionState & faction = factions.getFactionState(factionIndex); + MutexSafeWrapper + safeMutex(faction.getMutexPreCache(), mutexOwnerId); + + faction.precachedTravelState[unit->getId()] = tsImpossible; + faction.precachedPath[unit->getId()].clear(); + } + } + + void + PathFinder::removeUnitPrecache(Unit * unit) { + if (unit != NULL && factions.size() > unit->getFactionIndex()) { + int + factionIndex = unit->getFactionIndex(); + static string + mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + FactionState & faction = factions.getFactionState(factionIndex); + MutexSafeWrapper + safeMutex(faction.getMutexPreCache(), mutexOwnerId); + + if (faction.precachedTravelState.find(unit->getId()) != + faction.precachedTravelState.end()) { + faction.precachedTravelState.erase(unit->getId()); + } + if (faction.precachedPath.find(unit->getId()) != + faction.precachedPath.end()) { + faction.precachedPath.erase(unit->getId()); + } + } + } + + TravelState + PathFinder::findPath(Unit * unit, const Vec2i & finalPos, + bool * wasStuck, int frameIndex) { + TravelState + ts = tsImpossible; + + try { + + int + factionIndex = unit->getFactionIndex(); + FactionState & faction = factions.getFactionState(factionIndex); + static string + mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexPrecache(faction.getMutexPreCache(), mutexOwnerId); + + if (map == NULL) { + throw + megaglest_runtime_error("map == NULL"); + } + + unit->setCurrentPathFinderDesiredFinalPos(finalPos); + + + if (frameIndex >= 0) { + clearUnitPrecache(unit); + } + if (unit->getFaction()->canUnitsPathfind() == true) { + unit->getFaction()->addUnitToPathfindingList(unit->getId()); + } else { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "canUnitsPathfind() == false"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } + + return tsBlocked; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "[findPath] unit->getPos() [%s] finalPos [%s]", + unit->getPos().getString().c_str(), + finalPos.getString().c_str()); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } + + //route cache + if (finalPos == unit->getPos()) { + if (frameIndex < 0) { + //if arrived + unit->setCurrSkill(scStop); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Unit finalPos [%s] == unit->getPos() [%s]", + finalPos.getString().c_str(), + unit->getPos().getString().c_str()); + unit-> + logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } + + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPathFinder).enabled == + true) { + string + commandDesc = "none"; + Command * + command = unit->getCurrCommand(); + if (command != NULL && command->getCommandType() != NULL) { + commandDesc = + command->getCommandType()->toString(false); + } + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "State: arrived#1 at pos: %s, command [%s]", + finalPos.getString().c_str(), + commandDesc.c_str()); + unit->setCurrentUnitTitle(szBuf); + } + + return tsArrived; + } + + UnitPathInterface * + path = unit->getPath(); + if (path->isEmpty() == false) { + UnitPathBasic * + basic_path = dynamic_cast (path); + if (basic_path != NULL) { + //route cache + Vec2i + pos = basic_path->pop(frameIndex < 0); + + if (map->canMove(unit, unit->getPos(), pos)) { + if (frameIndex < 0) { + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugWorldSynch).enabled == + true + && SystemFlags:: + getSystemSettingType(SystemFlags:: + debugWorldSynchMax). + enabled == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "#1 map->canMove to pos [%s] from [%s]", + pos.getString().c_str(), + unit->getPos().getString().c_str()); + unit-> + logSynchData(extractFileFromDirectoryPath + (__FILE__).c_str(), __LINE__, + szBuf); + } + + unit->setTargetPos(pos, frameIndex < 0); + + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugWorldSynch).enabled == + true + && SystemFlags:: + getSystemSettingType(SystemFlags:: + debugWorldSynchMax). + enabled == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "#2 map->canMove to pos [%s] from [%s]", + pos.getString().c_str(), + unit->getPos().getString().c_str()); + unit-> + logSynchData(extractFileFromDirectoryPath + (__FILE__).c_str(), __LINE__, + szBuf); + } + + } + + return tsMoving; + } + } else if (dynamic_cast (path) != NULL) { + UnitPath * + advPath = dynamic_cast (path); + //route cache + Vec2i + pos = advPath->peek(); + if (map->canMove(unit, unit->getPos(), pos)) { + if (frameIndex < 0) { + advPath->pop(); + unit->setTargetPos(pos, frameIndex < 0); + } + + return tsMoving; + } + } else { + throw + megaglest_runtime_error + ("unsupported or missing path finder detected!"); + } + } + + if (path->isStuck() == true && + (unit->getLastStuckPos() == finalPos + || path->getBlockCount() > 500) + && unit-> + isLastStuckFrameWithinCurrentFrameTolerance(frameIndex >= 0) == + true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "path->isStuck() == true unit->getLastStuckPos() [%s] finalPos [%s] path->getBlockCount() [%d]", + unit->getLastStuckPos().getString().c_str(), + finalPos.getString().c_str(), + path->getBlockCount()); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } + + return tsBlocked; + } + + //route cache miss + int + maxNodeCount = -1; + if (unit->getUsePathfinderExtendedMaxNodes() == true) { + + maxNodeCount = PathFinder::pathFindNodesAbsoluteMax; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "maxNodeCount: %d", maxNodeCount); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } + } + + bool + minorDebugPathfinderPerformance = false; + Chrono + chrono; + if (minorDebugPathfinderPerformance) + chrono.start(); + + uint32 + searched_node_count = 0; + minorDebugPathfinder = false; + if (minorDebugPathfinder) + printf + ("Legacy Pathfind Unit [%d - %s] from = %s to = %s frameIndex = %d\n", + unit->getId(), unit->getType()->getName(false).c_str(), + unit->getPos().getString().c_str(), + finalPos.getString().c_str(), frameIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "calling aStar()"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } + + ts = + aStar(unit, finalPos, false, frameIndex, maxNodeCount, + &searched_node_count); + //post actions + switch (ts) { + case tsBlocked: + case tsArrived: + // The unit is stuck (not only blocked but unable to go anywhere for a while) + // We will try to bail out of the immediate area + if (ts == tsBlocked && unit->getInBailOutAttempt() == false && + path->isStuck() == true) { + + if (minorDebugPathfinder) + printf + ("Pathfind Unit [%d - %s] START BAILOUT ATTEMPT frameIndex = %d\n", + unit->getId(), + unit->getType()->getName(false).c_str(), frameIndex); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "[attempting to BAIL OUT] finalPos [%s] ts [%d]", + finalPos.getString().c_str(), ts); + unit-> + logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } + + if (wasStuck != NULL) { + *wasStuck = true; + } + unit->setInBailOutAttempt(true); + + bool + unitImmediatelyBlocked = false; + + // First check if unit currently blocked all around them, if so don't try to pathfind + const Vec2i + unitPos = unit->getPos(); + int + failureCount = 0; + int + cellCount = 0; + + for (int i = -1; i <= 1; ++i) { + for (int j = -1; j <= 1; ++j) { + Vec2i + pos = unitPos + Vec2i(i, j); + if (pos != unitPos) { + bool + canUnitMoveToCell = + map->aproxCanMove(unit, unitPos, pos); + if (canUnitMoveToCell == false) { + failureCount++; + } + cellCount++; + } + } + } + unitImmediatelyBlocked = (failureCount == cellCount); + if (unitImmediatelyBlocked == false) { + + int + factionIndex = unit->getFactionIndex(); + FactionState & faction = + factions.getFactionState(factionIndex); + + //if(Thread::isCurrentThreadMainThread() == false) { + // throw megaglest_runtime_error("#2 Invalid access to FactionState random from outside main thread current id = " + + // intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId())); + //} + + int + tryRadius = faction.random.randRange(1, 2); + //int tryRadius = faction.random.IRandomX(1,2); + //int tryRadius = 1; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In astar bailout() tryRadius %d", + tryRadius); + + if (frameIndex >= 0) { + unit->logSynchDataThreaded(__FILE__, __LINE__, + szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + } + + // Try to bail out up to PathFinder::pathFindBailoutRadius cells away + if (tryRadius == 2) { + for (int bailoutX = + -PathFinder::pathFindBailoutRadius; + bailoutX <= PathFinder::pathFindBailoutRadius + && ts == tsBlocked; ++bailoutX) { + for (int bailoutY = + -PathFinder::pathFindBailoutRadius; + bailoutY <= PathFinder::pathFindBailoutRadius + && ts == tsBlocked; ++bailoutY) { + const Vec2i + newFinalPos = + finalPos + Vec2i(bailoutX, bailoutY); + bool + canUnitMove = + map->canMove(unit, unit->getPos(), + newFinalPos); + + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugWorldSynch). + enabled == true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "[attempting to BAIL OUT] finalPos [%s] newFinalPos [%s] ts [%d] canUnitMove [%d]", + finalPos.getString().c_str(), + newFinalPos.getString(). + c_str(), ts, canUnitMove); + unit-> + logSynchData + (extractFileFromDirectoryPath + (__FILE__).c_str(), __LINE__, szBuf); + } + + if (canUnitMove) { + + int + maxBailoutNodeCount = + (PathFinder::pathFindBailoutRadius * 2); + + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugWorldSynch). + enabled == true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "calling aStar()"); + unit-> + logSynchData + (extractFileFromDirectoryPath + (__FILE__).c_str(), __LINE__, + szBuf); + } + + ts = + aStar(unit, newFinalPos, true, + frameIndex, maxBailoutNodeCount, + &searched_node_count); + } + } + } + } else { + for (int bailoutX = PathFinder::pathFindBailoutRadius; + bailoutX >= -PathFinder::pathFindBailoutRadius + && ts == tsBlocked; --bailoutX) { + for (int bailoutY = + PathFinder::pathFindBailoutRadius; + bailoutY >= + -PathFinder::pathFindBailoutRadius + && ts == tsBlocked; --bailoutY) { + const Vec2i + newFinalPos = + finalPos + Vec2i(bailoutX, bailoutY); + bool + canUnitMove = + map->canMove(unit, unit->getPos(), + newFinalPos); + + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugWorldSynch). + enabled == true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "[attempting to BAIL OUT] finalPos [%s] newFinalPos [%s] ts [%d] canUnitMove [%d]", + finalPos.getString().c_str(), + newFinalPos.getString(). + c_str(), ts, canUnitMove); + unit-> + logSynchData + (extractFileFromDirectoryPath + (__FILE__).c_str(), __LINE__, szBuf); + } + + if (canUnitMove) { + int + maxBailoutNodeCount = + (PathFinder::pathFindBailoutRadius * 2); + + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugWorldSynch). + enabled == true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "calling aStar()"); + unit-> + logSynchData + (extractFileFromDirectoryPath + (__FILE__).c_str(), __LINE__, + szBuf); + } + + ts = + aStar(unit, newFinalPos, true, + frameIndex, maxBailoutNodeCount, + &searched_node_count); + } + } + } + } + } + unit->setInBailOutAttempt(false); + + if (ts == tsBlocked) { + unit->setLastStuckFrameToCurrentFrame(); + unit->setLastStuckPos(finalPos); + } + } + if (ts == tsArrived || ts == tsBlocked) { + if (frameIndex < 0) { + unit->setCurrSkill(scStop); + } + } + break; + case tsMoving: + { + if (dynamic_cast (path) != NULL) { + UnitPathBasic * + basicPath = dynamic_cast (path); + Vec2i + pos; + if (frameIndex < 0 && basicPath != NULL) { + pos = basicPath->pop(frameIndex < 0); + } else { + + if (faction.precachedPath[unit->getId()].size() <= 0) { + throw + megaglest_runtime_error + ("factions[unit->getFactionIndex()].precachedPath[unit->getId()].size() <= 0!"); + } + + pos = faction.precachedPath[unit->getId()][0]; + + } + + if (map->canMove(unit, unit->getPos(), pos)) { + if (frameIndex < 0) { + unit->setTargetPos(pos, frameIndex < 0); + } + } else { + if (frameIndex < 0) { + unit->setCurrSkill(scStop); + } + + if (minorDebugPathfinderPerformance + && chrono.getMillis() >= 1) + printf + ("Unit [%d - %s] astar #2 took [%lld] msecs, ts = %d searched_node_count = %d.\n", + unit->getId(), + unit->getType()->getName(false).c_str(), + (long long int) chrono.getMillis(), ts, + searched_node_count); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "tsBlocked"); + unit-> + logSynchData(extractFileFromDirectoryPath + (__FILE__).c_str(), __LINE__, + szBuf); + } + + return tsBlocked; + } + } else if (dynamic_cast (path) != NULL) { + UnitPath * + advPath = dynamic_cast (path); + Vec2i + pos = advPath->peek(); + if (map->canMove(unit, unit->getPos(), pos)) { + if (frameIndex < 0) { + advPath->pop(); + unit->setTargetPos(pos, frameIndex < 0); + } + } else { + if (frameIndex < 0) { + unit->setCurrSkill(scStop); + } + + if (minorDebugPathfinder) + printf + ("Pathfind Unit [%d - %s] INT BAILOUT ATTEMPT BLOCKED frameIndex = %d\n", + unit->getId(), + unit->getType()->getName(false).c_str(), + frameIndex); + + if (minorDebugPathfinderPerformance + && chrono.getMillis() >= 1) + printf + ("Unit [%d - %s] astar #3 took [%lld] msecs, ts = %d searched_node_count = %d.\n", + unit->getId(), + unit->getType()->getName(false).c_str(), + (long long int) chrono.getMillis(), ts, + searched_node_count); + return tsBlocked; + } + } else { + throw + megaglest_runtime_error + ("unsupported or missing path finder detected!"); + } + } + break; + + default: + break; + } + if (minorDebugPathfinderPerformance && chrono.getMillis() >= 1) + printf + ("Unit [%d - %s] astar took [%lld] msecs, ts = %d searched_node_count = %d.\n", + unit->getId(), unit->getType()->getName(false).c_str(), + (long long int) chrono.getMillis(), ts, searched_node_count); + + } catch (const exception & ex) { + //setRunningStatus(false); + + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + throw + megaglest_runtime_error(ex.what()); + } catch (...) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, + __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw + megaglest_runtime_error(szBuf); + } + + return ts; + } + + // ==================== PRIVATE ==================== + + //route a unit using A* algorithm + TravelState + PathFinder::aStar(Unit * unit, const Vec2i & targetPos, bool inBailout, + int frameIndex, int maxNodeCount, + uint32 * searched_node_count) { + TravelState + ts = tsImpossible; + + try { + + int + unitFactionIndex = unit->getFactionIndex(); + int + factionIndex = unit->getFactionIndex(); + FactionState & faction = factions.getFactionState(factionIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true && frameIndex >= 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In aStar()"); + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } + + Chrono + chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled) + chrono.start(); + + if (map == NULL) { + throw + megaglest_runtime_error("map == NULL"); + } + + + if (maxNodeCount < 0) { + + int + factionIndex = unit->getFactionIndex(); + FactionState & faction = factions.getFactionState(factionIndex); + + maxNodeCount = faction.useMaxNodeCount; + } + + if (maxNodeCount >= 1 + && unit->getPathfindFailedConsecutiveFrameCount() >= 3) { + maxNodeCount = 200; + } + + UnitPathInterface * + path = unit->getPath(); + + faction.nodePoolCount = 0; + faction.openNodesList.clear(); + faction.openPosList.clear(); + faction.closedNodesList.clear(); + + // check the pre-cache to see if we can re-use a cached path + if (frameIndex < 0) { + + bool + foundPrecacheTravelState = + (faction.precachedTravelState.find(unit->getId()) != + faction.precachedTravelState.end()); + if (foundPrecacheTravelState == true) { + + // if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + // char szBuf[8096]=""; + // snprintf(szBuf,8096,"factions[unitFactionIndex].precachedTravelState[unit->getId()]: %d",faction.precachedTravelState[unit->getId()]); + // unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); + // } + + bool + foundPrecacheTravelStateIsMoving = + (faction.precachedTravelState[unit->getId()] == tsMoving); + if (foundPrecacheTravelStateIsMoving == true) { + bool + canMoveToCells = true; + + Vec2i + lastPos = unit->getPos(); + + int + unitPrecachePathSize = + (int) faction.precachedPath[unit->getId()].size(); + + for (int i = 0; i < unitPrecachePathSize; i++) { + + Vec2i + nodePos = faction.precachedPath[unit->getId()][i]; + + if (map->isInside(nodePos) == false + || map->isInsideSurface(map-> + toSurfCoords(nodePos)) + == false) { + throw + megaglest_runtime_error + ("Pathfinder invalid node path position = " + + nodePos.getString() + " i = " + intToStr(i)); + } + + if (i < unit->getPathFindRefreshCellCount() || + (unitPrecachePathSize >= + pathFindExtendRefreshForNodeCount + && i < + getPathFindExtendRefreshNodeCount(faction))) { + + if (canUnitMoveSoon(unit, lastPos, nodePos) == + false) { + canMoveToCells = false; + break; + } + lastPos = nodePos; + } else { + break; + } + } + + if (canMoveToCells == true) { + path->clear(); + //UnitPathBasic *basicPathFinder = dynamic_cast(path); + + int + unitPrecachePathSize = + (int) faction.precachedPath[unit->getId()].size(); + + for (int i = 0; i < unitPrecachePathSize; i++) { + + Vec2i + nodePos = + faction.precachedPath[unit->getId()][i]; + + if (map->isInside(nodePos) == false + || map->isInsideSurface(map-> + toSurfCoords + (nodePos)) == false) { + throw + megaglest_runtime_error + ("Pathfinder invalid node path position = " + + nodePos.getString() + " i = " + + intToStr(i)); + } + + //if(i < pathFindRefresh || + if (i < unit->getPathFindRefreshCellCount() || + (unitPrecachePathSize >= + pathFindExtendRefreshForNodeCount + && i < + getPathFindExtendRefreshNodeCount(faction))) { + path->add(nodePos); + } + } + unit->setUsePathfinderExtendedMaxNodes(false); + + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugWorldSynch).enabled == + true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "return factions[unitFactionIndex].precachedTravelState[unit->getId()];"); + unit-> + logSynchData(extractFileFromDirectoryPath + (__FILE__).c_str(), __LINE__, + szBuf); + } + + return faction.precachedTravelState[unit->getId()]; + } else { + clearUnitPrecache(unit); + } + } else { + + bool + foundPrecacheTravelStateIsBlocked = + (faction.precachedTravelState[unit->getId()] == + tsBlocked); + + if (foundPrecacheTravelStateIsBlocked == true) { + path->incBlockCount(); + unit->setUsePathfinderExtendedMaxNodes(false); + + // if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + // char szBuf[8096]=""; + // snprintf(szBuf,8096,"return factions[unitFactionIndex].precachedTravelState[unit->getId()];"); + // unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); + // } + + return faction.precachedTravelState[unit->getId()]; + } + } + } + } else { + clearUnitPrecache(unit); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "[clearUnitPrecache]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } + } + + const Vec2i + unitPos = unit->getPos(); + const Vec2i + finalPos = computeNearestFreePos(unit, targetPos); + + float + dist = unitPos.dist(finalPos); + + faction.useMaxNodeCount = PathFinder::pathFindNodesMax; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled == true && chrono.getMillis() > 4) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + + //path find algorithm + + //a) push starting pos into openNodes + Node * + firstNode = newNode(faction, maxNodeCount); + if (firstNode == NULL) { + throw + megaglest_runtime_error("firstNode == NULL"); + } + + firstNode->next = NULL; + firstNode->prev = NULL; + firstNode->pos = unitPos; + firstNode->heuristic = heuristic(unitPos, finalPos); + firstNode->exploredCell = true; + if (faction.openNodesList.find(firstNode->heuristic) == + faction.openNodesList.end()) { + faction.openNodesList[firstNode->heuristic].clear(); + } + faction.openNodesList[firstNode->heuristic].push_back(firstNode); + faction.openPosList[firstNode->pos] = true; + + //b) loop + bool + pathFound = true; + bool + nodeLimitReached = false; + Node * + node = NULL; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled == true && chrono.getMillis() > 4) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + + // First check if unit currently blocked all around them, if so don't try to pathfind + if (inBailout == false && unitPos != finalPos) { + int + failureCount = 0; + int + cellCount = 0; + + for (int i = -1; i <= 1; ++i) { + for (int j = -1; j <= 1; ++j) { + Vec2i + pos = unitPos + Vec2i(i, j); + if (pos != unitPos) { + bool + canUnitMoveToCell = + canUnitMoveSoon(unit, unitPos, pos); + if (canUnitMoveToCell == false) { + failureCount++; + } + cellCount++; + } + } + } + nodeLimitReached = (failureCount == cellCount); + pathFound = !nodeLimitReached; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "nodeLimitReached: %d failureCount: %d cellCount: %d", + nodeLimitReached, failureCount, cellCount); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled == true && chrono.getMillis() > 1) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] **Check if dest blocked, distance for unit [%d - %s] from [%s] to [%s] is %.2f took msecs: %lld nodeLimitReached = %d, failureCount = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, unit->getId(), + unit->getFullName(false).c_str(), + unitPos.getString().c_str(), + finalPos.getString().c_str(), dist, + (long long int) chrono.getMillis(), + nodeLimitReached, failureCount); + + if (nodeLimitReached == false) { + // First check if final destination blocked + failureCount = 0; + cellCount = 0; + + for (int i = -1; i <= 1; ++i) { + for (int j = -1; j <= 1; ++j) { + Vec2i + pos = finalPos + Vec2i(i, j); + if (pos != finalPos) { + bool + canUnitMoveToCell = + canUnitMoveSoon(unit, pos, finalPos); + if (canUnitMoveToCell == false) { + failureCount++; + } + cellCount++; + } + } + } + nodeLimitReached = (failureCount == cellCount); + pathFound = !nodeLimitReached; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "nodeLimitReached: %d failureCount: %d cellCount: %d", + nodeLimitReached, failureCount, cellCount); + unit-> + logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled == true && chrono.getMillis() > 1) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] **Check if dest blocked, distance for unit [%d - %s] from [%s] to [%s] is %.2f took msecs: %lld nodeLimitReached = %d, failureCount = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, unit->getId(), + unit->getFullName(false). + c_str(), + unitPos.getString().c_str(), + finalPos.getString().c_str(), + dist, + (long long int) chrono. + getMillis(), nodeLimitReached, + failureCount); + } + } else { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "inBailout: %d unitPos: [%s] finalPos [%s]", + inBailout, unitPos.getString().c_str(), + finalPos.getString().c_str()); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } + } + // + + // START + std::map < std::pair < Vec2i, Vec2i >, bool > canAddNode; + std::map < Vec2i, bool > closedNodes; + std::map < Vec2i, Vec2i > cameFrom; + cameFrom[unitPos] = Vec2i(-1, -1); + + // Do the a-star base pathfind work if required + int + whileLoopCount = 0; + if (nodeLimitReached == false) { + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Calling doAStarPathSearch nodeLimitReached: %d whileLoopCount: %d unitFactionIndex: %d pathFound: %d finalPos [%s] maxNodeCount: %d frameIndex: %d", + nodeLimitReached, whileLoopCount, unitFactionIndex, + pathFound, finalPos.getString().c_str(), + maxNodeCount, frameIndex); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } + + doAStarPathSearch(nodeLimitReached, whileLoopCount, + unitFactionIndex, pathFound, node, finalPos, + closedNodes, cameFrom, canAddNode, unit, + maxNodeCount, frameIndex); + + if (searched_node_count != NULL) { + *searched_node_count = whileLoopCount; + } + + // Now see if the unit is eligible for pathfind max nodes boost? + if (nodeLimitReached == true) { + unit->incrementPathfindFailedConsecutiveFrameCount(); + } else { + unit->resetPathfindFailedConsecutiveFrameCount(); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Calling doAStarPathSearch nodeLimitReached: %d whileLoopCount: %d unitFactionIndex: %d pathFound: %d finalPos [%s] maxNodeCount: %d pathFindNodesAbsoluteMax: %d frameIndex: %d", + nodeLimitReached, whileLoopCount, unitFactionIndex, + pathFound, finalPos.getString().c_str(), + maxNodeCount, pathFindNodesAbsoluteMax, frameIndex); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } + + if (nodeLimitReached == true + && maxNodeCount != pathFindNodesAbsoluteMax) { + if (unit-> + isLastPathfindFailedFrameWithinCurrentFrameTolerance() == + true) { + if (frameIndex < 0) { + unit->setLastPathfindFailedFrameToCurrentFrame(); + unit->setLastPathfindFailedPos(finalPos); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "calling aStar()"); + unit-> + logSynchData(extractFileFromDirectoryPath + (__FILE__).c_str(), __LINE__, szBuf); + } + + return aStar(unit, targetPos, false, frameIndex, + pathFindNodesAbsoluteMax); + } + } + } else { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "nodeLimitReached: %d", + nodeLimitReached); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } + } + + + Node * + lastNode = node; + + //if consumed all nodes find best node (to avoid strange behaviour) + if (nodeLimitReached == true) { + + if (faction.closedNodesList.empty() == false) { + float + bestHeuristic = + truncateDecimal < + float >(faction.closedNodesList.begin()->first, 6); + if (lastNode != NULL && bestHeuristic < lastNode->heuristic) { + lastNode = + faction.closedNodesList.begin()->second.front(); + } + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled == true && chrono.getMillis() > 4) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + + //check results of path finding + ts = tsImpossible; + if (pathFound == false || lastNode == firstNode) { + if (minorDebugPathfinder) + printf + ("Legacy Pathfind Unit [%d - %s] NOT FOUND PATH count = %d frameIndex = %d\n", + unit->getId(), unit->getType()->getName().c_str(), + whileLoopCount, frameIndex); + + //blocked + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPathFinder).enabled == + true) { + string + commandDesc = "none"; + Command * + command = unit->getCurrCommand(); + if (command != NULL && command->getCommandType() != NULL) { + commandDesc = + command->getCommandType()->toString(false); + } + + std::pair < Vec2i, int > + lastHarvest = unit->getLastHarvestResourceTarget(); + + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "State: blocked, cmd [%s] pos: [%s], dest pos: [%s], lastHarvest = [%s - %d], reason A= %d, B= %d, C= %d, D= %d, E= %d, F = %d", + commandDesc.c_str(), + unit->getPos().getString().c_str(), + targetPos.getString().c_str(), + lastHarvest.first.getString().c_str(), + lastHarvest.second, pathFound, + (lastNode == firstNode), path->getBlockCount(), + path->isBlocked(), nodeLimitReached, + path->isStuck()); + unit->setCurrentUnitTitle(szBuf); + } + + if (frameIndex < 0) { + unit->setUsePathfinderExtendedMaxNodes(false); + } + + ts = tsBlocked; + if (frameIndex < 0) { + path->incBlockCount(); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled == true && chrono.getMillis() > 4) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + } else { + if (minorDebugPathfinder) + printf + ("Legacy Pathfind Unit [%d - %s] FOUND PATH count = %d frameIndex = %d\n", + unit->getId(), unit->getType()->getName().c_str(), + whileLoopCount, frameIndex); + //on the way + ts = tsMoving; + + //build next pointers + Node * + currNode = lastNode; + while (currNode->prev != NULL) { + currNode->prev->next = currNode; + currNode = currNode->prev; + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled == true && chrono.getMillis() > 4) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + + if (frameIndex < 0) { + if (maxNodeCount == pathFindNodesAbsoluteMax) { + unit->setUsePathfinderExtendedMaxNodes(true); + } else { + unit->setUsePathfinderExtendedMaxNodes(false); + } + } + + //store path + if (frameIndex < 0) { + path->clear(); + } + + //UnitPathBasic *basicPathFinder = dynamic_cast(path); + + currNode = firstNode; + + for (int i = 0; currNode->next != NULL; + currNode = currNode->next, i++) { + Vec2i + nodePos = currNode->next->pos; + if (map->isInside(nodePos) == false + || map->isInsideSurface(map->toSurfCoords(nodePos)) == + false) { + throw + megaglest_runtime_error + ("Pathfinder invalid node path position = " + + nodePos.getString() + " i = " + intToStr(i)); + } + + if (minorDebugPathfinder) + printf("nodePos [%s]\n", nodePos.getString().c_str()); + + if (frameIndex >= 0) { + faction.precachedPath[unit->getId()].push_back(nodePos); + } else { + if (i < unit->getPathFindRefreshCellCount() || + (whileLoopCount >= pathFindExtendRefreshForNodeCount + && i < getPathFindExtendRefreshNodeCount(faction))) { + path->add(nodePos); + } + } + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled == true && chrono.getMillis() > 4) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true + && SystemFlags::getSystemSettingType(SystemFlags:: + debugWorldSynchMax). + enabled == true) { + char + szBuf[8096] = ""; + + string + pathToTake = ""; + if (frameIndex < 0) { + vector < Vec2i > pathQueue = path->getQueue(); + for (unsigned int index = 0; index < pathQueue.size(); + ++index) { + Vec2i & pos = pathQueue[index]; + if (pathToTake != "") { + pathToTake += ", "; + } + pathToTake += pos.getString(); + } + } else { + for (unsigned int index = 0; + index < + faction.precachedPath[unit->getId()].size(); + ++index) { + Vec2i & pos = + faction.precachedPath[unit->getId()][index]; + if (pathToTake != "") { + pathToTake += ", "; + } + pathToTake += pos.getString(); + } + } + snprintf(szBuf, 8096, "Path for unit to take = %s", + pathToTake.c_str()); + if (frameIndex < 0) { + unit-> + logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } else { + unit-> + logSynchDataThreaded(extractFileFromDirectoryPath + (__FILE__).c_str(), __LINE__, + szBuf); + } + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPathFinder).enabled == + true) { + string + commandDesc = "none"; + Command * + command = unit->getCurrCommand(); + if (command != NULL && command->getCommandType() != NULL) { + commandDesc = + command->getCommandType()->toString(false); + } + + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "State: moving, cmd [%s] pos: %s dest pos: %s, Queue= %d", + commandDesc.c_str(), + unit->getPos().getString().c_str(), + targetPos.getString().c_str(), + path->getQueueCount()); + unit->setCurrentUnitTitle(szBuf); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled == true && chrono.getMillis() > 4) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + } + + + faction.openNodesList.clear(); + faction.openPosList.clear(); + faction.closedNodesList.clear(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled == true && chrono.getMillis() > 4) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + + if (frameIndex >= 0) { + + FactionState & faction = factions.getFactionState(factionIndex); + faction.precachedTravelState[unit->getId()] = ts; + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 5) + printf + ("In [%s::%s Line: %d] astar took [%lld] msecs, ts = %d.\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, (long long int) chrono.getMillis(), + ts); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true && frameIndex < 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "return ts: %d", ts); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__, szBuf); + } + + } catch (const exception & ex) { + + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + throw + megaglest_runtime_error(ex.what()); + } catch (...) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, + __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw + megaglest_runtime_error(szBuf); + } + + return ts; + } + + void + PathFinder::processNearestFreePos(const Vec2i & finalPos, int i, int j, + int size, Field field, int teamIndex, + Vec2i unitPos, Vec2i & nearestPos, + float &nearestDist) { + + try { + Vec2i + currPos = finalPos + Vec2i(i, j); + + if (map->isAproxFreeCells(currPos, size, field, teamIndex)) { + float + dist = currPos.dist(finalPos); + + //if nearer from finalPos + if (dist < nearestDist) { + nearestPos = currPos; + nearestDist = dist; + } + //if the distance is the same compare distance to unit + else if (dist == nearestDist) { + if (currPos.dist(unitPos) < nearestPos.dist(unitPos)) { + nearestPos = currPos; + } + } + } + } catch (const exception & ex) { + + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + throw + megaglest_runtime_error(ex.what()); + } catch (...) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, + __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw + megaglest_runtime_error(szBuf); + } + + } + + Vec2i + PathFinder::computeNearestFreePos(const Unit * unit, + const Vec2i & finalPos) { + + Vec2i + nearestPos(0, 0); + try { + + if (map == NULL) { + throw + megaglest_runtime_error("map == NULL"); + } + + //unit data + int + size = unit->getType()->getSize(); + Field + field = unit->getCurrField(); + int + teamIndex = unit->getTeam(); + + //if finalPos is free return it + if (map->isAproxFreeCells(finalPos, size, field, teamIndex)) { + return finalPos; + } + + //find nearest pos + Vec2i + unitPos = unit->getPosNotThreadSafe(); + nearestPos = unitPos; + + float + nearestDist = unitPos.dist(finalPos); + + for (int i = -maxFreeSearchRadius; i <= maxFreeSearchRadius; ++i) { + for (int j = -maxFreeSearchRadius; j <= maxFreeSearchRadius; ++j) { + processNearestFreePos(finalPos, i, j, size, field, teamIndex, + unitPos, nearestPos, nearestDist); + } + } + + } catch (const exception & ex) { + + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + throw + megaglest_runtime_error(ex.what()); + } catch (...) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, + __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw + megaglest_runtime_error(szBuf); + } + + return nearestPos; + } + + int + PathFinder::findNodeIndex(Node * node, Nodes & nodeList) { + int + index = -1; + if (node != NULL) { + for (unsigned int i = 0; i < nodeList.size(); ++i) { + Node * + curnode = nodeList[i]; + if (node == curnode) { + index = i; + break; + } + } + } + return index; + } + + int + PathFinder::findNodeIndex(Node * node, std::vector < Node > &nodeList) { + int + index = -1; + if (node != NULL) { + for (unsigned int i = 0; i < nodeList.size(); ++i) { + Node & curnode = nodeList[i]; + if (node == &curnode) { + index = i; + break; + } + } + } + return index; + } + + //bool PathFinder::unitCannotMove(Unit *unit) { + // bool unitImmediatelyBlocked = false; + // + // try { + // // First check if unit currently blocked all around them, if so don't try to pathfind + // const Vec2i unitPos = unit->getPos(); + // int failureCount = 0; + // int cellCount = 0; + // + // for(int i = -1; i <= 1; ++i) { + // for(int j = -1; j <= 1; ++j) { + // Vec2i pos = unitPos + Vec2i(i, j); + // if(pos != unitPos) { + // bool canUnitMoveToCell = map->aproxCanMove(unit, unitPos, pos); + // if(canUnitMoveToCell == false) { + // failureCount++; + // } + // cellCount++; + // } + // } + // } + // unitImmediatelyBlocked = (failureCount == cellCount); + // + // } + // catch(const exception &ex) { + // //setRunningStatus(false); + // + // SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + // + // throw megaglest_runtime_error(ex.what()); + // } + // catch(...) { + // char szBuf[8096]=""; + // snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); + // SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); + // throw megaglest_runtime_error(szBuf); + // } + // + // return unitImmediatelyBlocked; + //} + + void + PathFinder::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode * + pathfinderNode = rootNode->addChild("PathFinder"); + + pathfinderNode->addAttribute("pathFindNodesMax", + intToStr(pathFindNodesMax), + mapTagReplacements); + pathfinderNode->addAttribute("pathFindNodesAbsoluteMax", + intToStr(pathFindNodesAbsoluteMax), + mapTagReplacements); + for (unsigned int i = 0; i < (unsigned int) factions.size(); ++i) { + FactionState & factionState = factions.getFactionState(i); + XmlNode * + factionsNode = pathfinderNode->addChild("factions"); + + for (unsigned int j = 0; + j < (unsigned int) factionState.nodePool.size(); ++j) { + Node * + curNode = &factionState.nodePool[j]; + XmlNode * + nodePoolNode = factionsNode->addChild("nodePool"); + + nodePoolNode->addAttribute("pos", curNode->pos.getString(), + mapTagReplacements); + int + nextIdx = + findNodeIndex(curNode->next, factionState.nodePool); + nodePoolNode->addAttribute("next", intToStr(nextIdx), + mapTagReplacements); + int + prevIdx = + findNodeIndex(curNode->prev, factionState.nodePool); + nodePoolNode->addAttribute("prev", intToStr(prevIdx), + mapTagReplacements); + nodePoolNode->addAttribute("heuristic", + floatToStr(curNode->heuristic, 6), + mapTagReplacements); + nodePoolNode->addAttribute("exploredCell", + intToStr(curNode->exploredCell), + mapTagReplacements); + } + + factionsNode->addAttribute("nodePoolCount", + intToStr(factionState.nodePoolCount), + mapTagReplacements); + factionsNode->addAttribute("random", + intToStr(factionState.random. + getLastNumber()), + mapTagReplacements); + factionsNode->addAttribute("useMaxNodeCount", + intToStr(factionState.useMaxNodeCount), + mapTagReplacements); + } + } + + void + PathFinder::loadGame(const XmlNode * rootNode) { + const XmlNode * + pathfinderNode = rootNode->getChild("PathFinder"); + + vector < XmlNode * >factionsNodeList = + pathfinderNode->getChildList("factions"); + for (unsigned int i = 0; i < (unsigned int) factionsNodeList.size(); + ++i) { + XmlNode * + factionsNode = factionsNodeList[i]; + + FactionState & factionState = factions.getFactionState(i); + vector < XmlNode * >nodePoolListNode = + factionsNode->getChildList("nodePool"); + for (unsigned int j = 0; + j < (unsigned int) nodePoolListNode.size() + && j < (unsigned int) pathFindNodesAbsoluteMax; ++j) { + XmlNode * + nodePoolNode = nodePoolListNode[j]; + + Node * + curNode = &factionState.nodePool[j]; + curNode->pos = + Vec2i::strToVec2(nodePoolNode->getAttribute("pos")-> + getValue()); + int + nextNode = + nodePoolNode->getAttribute("next")->getIntValue(); + if (nextNode >= 0) { + curNode->next = &factionState.nodePool[nextNode]; + } else { + curNode->next = NULL; + } + + int + prevNode = + nodePoolNode->getAttribute("prev")->getIntValue(); + if (prevNode >= 0) { + curNode->prev = &factionState.nodePool[prevNode]; + } else { + curNode->prev = NULL; + } + curNode->heuristic = + nodePoolNode->getAttribute("heuristic")->getFloatValue(); + curNode->exploredCell = + nodePoolNode->getAttribute("exploredCell")->getIntValue() != + 0; + } + + factionState.nodePoolCount = + factionsNode->getAttribute("nodePoolCount")->getIntValue(); + factionState.random.setLastNumber(factionsNode-> + getAttribute("random")-> + getIntValue()); + factionState.useMaxNodeCount = PathFinder::pathFindNodesMax; + } + } + + } } //end namespace diff --git a/source/glest_game/ai/path_finder.h b/source/glest_game/ai/path_finder.h index 7e8c1ebf1..4ef765a56 100644 --- a/source/glest_game/ai/path_finder.h +++ b/source/glest_game/ai/path_finder.h @@ -28,730 +28,637 @@ # include "leak_dumper.h" using - std::vector; +std::vector; using - Shared::Graphics::Vec2i; +Shared::Graphics::Vec2i; namespace - Glest -{ - namespace - Game - { - -// ===================================================== -// class PathFinder -// -/// Finds paths for units using a modification of the A* algorithm -// ===================================================== - - class - PathFinder - { - public: - class - BadUnitNodeList - { - public: - BadUnitNodeList () - { - unitSize = -1; - field = fLand; - } - int - unitSize; - Field - field; - std::map < - Vec2i, - std::map < - Vec2i, - bool > > - badPosList; - - inline bool - isPosBad (const Vec2i & pos1, const Vec2i & pos2) - { - bool - result = false; - - std::map < - Vec2i, - std::map < - Vec2i, - bool > >::iterator - iterFind = badPosList.find (pos1); - if (iterFind != badPosList.end ()) - { - std::map < Vec2i, bool >::iterator iterFind2 = - iterFind->second.find (pos2); - if (iterFind2 != iterFind->second.end ()) - { - result = true; - } - } - - return - result; - } - }; - - class - Node - { - public: - Node () - { - clear (); - } - void - clear () - { - pos.x = 0; - pos.y = 0; - next = NULL; - prev = NULL; - heuristic = 0.0; - exploredCell = false; - } - Vec2i - pos; - Node * - next; - Node * - prev; - float - heuristic; - bool - exploredCell; - }; - typedef - vector < - Node * > - Nodes; - - class - FactionState - { - protected: - Mutex * - factionMutexPrecache; - public: - explicit - FactionState (int factionIndex): - //factionMutexPrecache(new Mutex) { - factionMutexPrecache (NULL) - { //, random(factionIndex) { - - openPosList.clear (); - openNodesList. - clear (); - closedNodesList. - clear (); - nodePool. - clear (); - nodePoolCount = 0; - this-> - factionIndex = factionIndex; - useMaxNodeCount = 0; - - precachedTravelState. - clear (); - precachedPath. - clear (); - } - ~ - FactionState () - { - - delete - factionMutexPrecache; - factionMutexPrecache = NULL; - } - Mutex * - getMutexPreCache () - { - return factionMutexPrecache; - } - - std::map < Vec2i, bool > openPosList; - std::map < float, - Nodes > - openNodesList; - std::map < float, - Nodes > - closedNodesList; - std::vector < Node > nodePool; - - int - nodePoolCount; - int - factionIndex; - RandomGen - random; - //CRandomMersenne random; - int - useMaxNodeCount; - - std::map < int, - TravelState > - precachedTravelState; - std::map < int, - std::vector < - Vec2i > > - precachedPath; - }; - - class - FactionStateManager - { - protected: - typedef - vector < - FactionState * > - FactionStateList; - FactionStateList - factions; - - void - init () - { - for (int index = 0; index < GameConstants::maxPlayers; ++index) - { - factions.push_back (new FactionState (index)); - } - } - - public: - FactionStateManager () - { - init (); - } - ~FactionStateManager () - { - clear (); - } - - FactionState & getFactionState (int index) - { - FactionState * - faction = factions[index]; - return *faction; - } - void - clear () - { - for (unsigned int index = 0; - index < (unsigned int) factions.size (); ++index) - { - delete - factions[index]; - } - - factions.clear (); - } - int - size () - { - return (int) factions.size (); - } - }; - - public: - static const int - maxFreeSearchRadius; - - static const int - pathFindBailoutRadius; - static const int - pathFindExtendRefreshForNodeCount; - static const int - pathFindExtendRefreshNodeCountMin; - static const int - pathFindExtendRefreshNodeCountMax; - - private: - - static int - pathFindNodesMax; - static int - pathFindNodesAbsoluteMax; - - - FactionStateManager - factions; - const Map * - map; - bool - minorDebugPathfinder; - - public: - PathFinder (); - explicit - PathFinder (const Map * map); - ~PathFinder (); - - PathFinder (const PathFinder & obj) - { - init (); - throw - megaglest_runtime_error ("class PathFinder is NOT safe to copy!"); - } - PathFinder & operator= (const PathFinder & obj) - { - init (); - throw - megaglest_runtime_error ("class PathFinder is NOT safe to assign!"); - } - - void - init (const Map * map); - TravelState - findPath (Unit * unit, const Vec2i & finalPos, bool * wasStuck = - NULL, int frameIndex = -1); - void - clearUnitPrecache (Unit * unit); - void - removeUnitPrecache (Unit * unit); - void - clearCaches (); - - //bool unitCannotMove(Unit *unit); - - int - findNodeIndex (Node * node, Nodes & nodeList); - int - findNodeIndex (Node * node, std::vector < Node > &nodeList); - - void - saveGame (XmlNode * rootNode); - void - loadGame (const XmlNode * rootNode); - - private: - void - init (); - - TravelState - aStar (Unit * unit, const Vec2i & finalPos, bool inBailout, - int frameIndex, int maxNodeCount = - -1, uint32 * searched_node_count = NULL); - inline static Node * - newNode (FactionState & faction, int maxNodeCount) - { - if (faction.nodePoolCount < (int) faction.nodePool.size () && - faction.nodePoolCount < maxNodeCount) - { - Node * - node = &(faction.nodePool[faction.nodePoolCount]); - node->clear (); - faction.nodePoolCount++; - return node; - } - return NULL; - } - - Vec2i - computeNearestFreePos (const Unit * unit, const Vec2i & targetPos); - - inline static float - heuristic (const Vec2i & pos, const Vec2i & finalPos) - { - return pos.dist (finalPos); - } - - inline static bool - openPos (const Vec2i & sucPos, FactionState & faction) - { - if (faction.openPosList.find (sucPos) == faction.openPosList.end ()) - { - return false; - } - return true; - } - - inline static Node * - minHeuristicFastLookup (FactionState & faction) - { - if (faction.openNodesList.empty () == true) - { - throw - megaglest_runtime_error ("openNodesList.empty() == true"); - } - - Node * - result = faction.openNodesList.begin ()->second.front (); - faction.openNodesList.begin ()->second.erase (faction.openNodesList. - begin ()->second. - begin ()); - if (faction.openNodesList.begin ()->second.empty ()) - { - faction.openNodesList.erase (faction.openNodesList.begin ()); - } - return result; - } - - inline bool - processNode (Unit * unit, Node * node, const Vec2i finalPos, - int x, int y, bool & nodeLimitReached, int maxNodeCount) - { - bool - result = false; - Vec2i - sucPos = node->pos + Vec2i (x, y); - - int - unitFactionIndex = unit->getFactionIndex (); - FactionState & faction = factions.getFactionState (unitFactionIndex); - - bool - foundOpenPosForPos = openPos (sucPos, faction); - bool - allowUnitMoveSoon = canUnitMoveSoon (unit, node->pos, sucPos); - if (SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true - && SystemFlags::getSystemSettingType (SystemFlags:: - debugWorldSynchMax). - enabled == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In processNode() nodeLimitReached %d unitFactionIndex %d foundOpenPosForPos %d allowUnitMoveSoon %d maxNodeCount %d node->pos = %s finalPos = %s sucPos = %s faction.openPosList.size() %lu closedNodesList.size() %lu", - nodeLimitReached, unitFactionIndex, foundOpenPosForPos, - allowUnitMoveSoon, maxNodeCount, - node->pos.getString ().c_str (), - finalPos.getString ().c_str (), - sucPos.getString ().c_str (), - faction.openPosList.size (), - faction.closedNodesList.size ()); - - if (Thread::isCurrentThreadMainThread () == false) - { - unit->logSynchDataThreaded (__FILE__, __LINE__, szBuf); - } - else - { - unit->logSynchData (__FILE__, __LINE__, szBuf); - } - } - - if (foundOpenPosForPos == false && allowUnitMoveSoon) - { - //if node is not open and canMove then generate another node - Node * - sucNode = newNode (faction, maxNodeCount); - if (sucNode != NULL) - { - sucNode->pos = sucPos; - sucNode->heuristic = heuristic (sucNode->pos, finalPos); - sucNode->prev = node; - sucNode->next = NULL; - sucNode->exploredCell = - map->getSurfaceCell (Map::toSurfCoords (sucPos))-> - isExplored (unit->getTeam ()); - if (faction.openNodesList.find (sucNode->heuristic) == - faction.openNodesList.end ()) - { - faction.openNodesList[sucNode->heuristic].clear (); - } - faction.openNodesList[sucNode->heuristic].push_back (sucNode); - faction.openPosList[sucNode->pos] = true; - - result = true; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true - && SystemFlags::getSystemSettingType (SystemFlags:: - debugWorldSynchMax). - enabled == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In processNode() sucPos = %s", - sucPos.getString ().c_str ()); - - if (Thread::isCurrentThreadMainThread () == false) - { - unit->logSynchDataThreaded (__FILE__, __LINE__, - szBuf); - } - else - { - unit->logSynchData (__FILE__, __LINE__, szBuf); - } - } - - } - else - { - nodeLimitReached = true; - } - } - - return result; - } - - void - processNearestFreePos (const Vec2i & finalPos, int i, int j, int size, - Field field, int teamIndex, Vec2i unitPos, - Vec2i & nearestPos, float &nearestDist); - int - getPathFindExtendRefreshNodeCount (FactionState & faction); - - inline bool - canUnitMoveSoon (Unit * unit, const Vec2i & pos1, const Vec2i & pos2) - { - bool - result = map->aproxCanMoveSoon (unit, pos1, pos2); - return result; - } - - inline void - doAStarPathSearch (bool & nodeLimitReached, int &whileLoopCount, - int &unitFactionIndex, bool & pathFound, - Node * &node, const Vec2i & finalPos, - const std::map < Vec2i, bool > &closedNodes, - const std::map < Vec2i, Vec2i > &cameFrom, - const std::map < std::pair < Vec2i, Vec2i >, - bool > &canAddNode, Unit * &unit, int &maxNodeCount, - int curFrameIndex) - { - - if (SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true - && SystemFlags::getSystemSettingType (SystemFlags:: - debugWorldSynchMax). - enabled == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In doAStarPathSearch() nodeLimitReached %d whileLoopCount %d unitFactionIndex %d pathFound %d maxNodeCount %d", - nodeLimitReached, whileLoopCount, unitFactionIndex, - pathFound, maxNodeCount); - - if (curFrameIndex >= 0) - { - unit->logSynchDataThreaded (__FILE__, __LINE__, szBuf); - } - else - { - unit->logSynchData (__FILE__, __LINE__, szBuf); - } - } - - FactionState & faction = factions.getFactionState (unitFactionIndex); - - while (nodeLimitReached == false) - { - whileLoopCount++; - if (faction.openNodesList.empty () == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true - && SystemFlags::getSystemSettingType (SystemFlags:: - debugWorldSynchMax). - enabled == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In doAStarPathSearch() nodeLimitReached %d whileLoopCount %d unitFactionIndex %d pathFound %d maxNodeCount %d", - nodeLimitReached, whileLoopCount, - unitFactionIndex, pathFound, maxNodeCount); - - if (curFrameIndex >= 0) - { - unit->logSynchDataThreaded (__FILE__, __LINE__, - szBuf); - } - else - { - unit->logSynchData (__FILE__, __LINE__, szBuf); - } - } - - pathFound = false; - break; - } - node = minHeuristicFastLookup (faction); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true - && SystemFlags::getSystemSettingType (SystemFlags:: - debugWorldSynchMax). - enabled == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In doAStarPathSearch() nodeLimitReached %d whileLoopCount %d unitFactionIndex %d pathFound %d maxNodeCount %d node->pos = %s finalPos = %s node->exploredCell = %d", - nodeLimitReached, whileLoopCount, unitFactionIndex, - pathFound, maxNodeCount, - node->pos.getString ().c_str (), - finalPos.getString ().c_str (), node->exploredCell); - - if (curFrameIndex >= 0) - { - unit->logSynchDataThreaded (__FILE__, __LINE__, szBuf); - } - else - { - unit->logSynchData (__FILE__, __LINE__, szBuf); - } - } - - if (node->pos == finalPos || node->exploredCell == false) - { - pathFound = true; - break; - } - - if (faction.closedNodesList.find (node->heuristic) == - faction.closedNodesList.end ()) - { - faction.closedNodesList[node->heuristic].clear (); - } - faction.closedNodesList[node->heuristic].push_back (node); - faction.openPosList[node->pos] = true; - - int - failureCount = 0; - int - cellCount = 0; - -// if(Thread::isCurrentThreadMainThread() == false) { -// throw megaglest_runtime_error("#1 Invalid access to FactionState random from outside main thread current id = " + -// intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId())); -// } - - //int tryDirection = 1; - //int tryDirection = faction.random.IRandomX(1, 4); - int - tryDirection = faction.random.randRange (1, 4); - //int tryDirection = unit->getRandom(true)->randRange(1, 4); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true - && SystemFlags::getSystemSettingType (SystemFlags:: - debugWorldSynchMax). - enabled == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In doAStarPathSearch() tryDirection %d", - tryDirection); - - if (curFrameIndex >= 0) - { - unit->logSynchDataThreaded (__FILE__, __LINE__, szBuf); - } - else - { - unit->logSynchData (__FILE__, __LINE__, szBuf); - } - } - - if (tryDirection == 4) - { - for (int i = 1; i >= -1 && nodeLimitReached == false; --i) - { - for (int j = -1; j <= 1 && nodeLimitReached == false; ++j) - { - if (processNode - (unit, node, finalPos, i, j, nodeLimitReached, - maxNodeCount) == false) - { - failureCount++; - } - cellCount++; - } - } - } - else if (tryDirection == 3) - { - for (int i = -1; i <= 1 && nodeLimitReached == false; ++i) - { - for (int j = 1; j >= -1 && nodeLimitReached == false; --j) - { - if (processNode - (unit, node, finalPos, i, j, nodeLimitReached, - maxNodeCount) == false) - { - failureCount++; - } - cellCount++; - } - } - } - else if (tryDirection == 2) - { - for (int i = -1; i <= 1 && nodeLimitReached == false; ++i) - { - for (int j = -1; j <= 1 && nodeLimitReached == false; ++j) - { - if (processNode - (unit, node, finalPos, i, j, nodeLimitReached, - maxNodeCount) == false) - { - failureCount++; - } - cellCount++; - } - } - } - else - { - for (int i = 1; i >= -1 && nodeLimitReached == false; --i) - { - for (int j = 1; j >= -1 && nodeLimitReached == false; --j) - { - if (processNode - (unit, node, finalPos, i, j, nodeLimitReached, - maxNodeCount) == false) - { - failureCount++; - } - cellCount++; - } - } - } - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true - && SystemFlags::getSystemSettingType (SystemFlags:: - debugWorldSynchMax). - enabled == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In doAStarPathSearch() nodeLimitReached %d whileLoopCount %d unitFactionIndex %d pathFound %d maxNodeCount %d", - nodeLimitReached, whileLoopCount, unitFactionIndex, - pathFound, maxNodeCount); - - if (curFrameIndex >= 0) - { - unit->logSynchDataThreaded (__FILE__, __LINE__, szBuf); - } - else - { - unit->logSynchData (__FILE__, __LINE__, szBuf); - } - } - - } - - }; - - } + Glest { + namespace + Game { + + // ===================================================== + // class PathFinder + // + /// Finds paths for units using a modification of the A* algorithm + // ===================================================== + + class + PathFinder { + public: + class + BadUnitNodeList { + public: + BadUnitNodeList() { + unitSize = -1; + field = fLand; + } + int + unitSize; + Field + field; + std::map < + Vec2i, + std::map < + Vec2i, + bool > > + badPosList; + + inline bool + isPosBad(const Vec2i & pos1, const Vec2i & pos2) { + bool + result = false; + + std::map < + Vec2i, + std::map < + Vec2i, + bool > >::iterator + iterFind = badPosList.find(pos1); + if (iterFind != badPosList.end()) { + std::map < Vec2i, bool >::iterator iterFind2 = + iterFind->second.find(pos2); + if (iterFind2 != iterFind->second.end()) { + result = true; + } + } + + return + result; + } + }; + + class + Node { + public: + Node() { + clear(); + } + void + clear() { + pos.x = 0; + pos.y = 0; + next = NULL; + prev = NULL; + heuristic = 0.0; + exploredCell = false; + } + Vec2i + pos; + Node * + next; + Node * + prev; + float + heuristic; + bool + exploredCell; + }; + typedef + vector < + Node * > + Nodes; + + class + FactionState { + protected: + Mutex * + factionMutexPrecache; + public: + explicit + FactionState(int factionIndex) : + //factionMutexPrecache(new Mutex) { + factionMutexPrecache(NULL) { //, random(factionIndex) { + + openPosList.clear(); + openNodesList. + clear(); + closedNodesList. + clear(); + nodePool. + clear(); + nodePoolCount = 0; + this-> + factionIndex = factionIndex; + useMaxNodeCount = 0; + + precachedTravelState. + clear(); + precachedPath. + clear(); + } + ~ + FactionState() { + + delete + factionMutexPrecache; + factionMutexPrecache = NULL; + } + Mutex * + getMutexPreCache() { + return factionMutexPrecache; + } + + std::map < Vec2i, bool > openPosList; + std::map < float, + Nodes > + openNodesList; + std::map < float, + Nodes > + closedNodesList; + std::vector < Node > nodePool; + + int + nodePoolCount; + int + factionIndex; + RandomGen + random; + //CRandomMersenne random; + int + useMaxNodeCount; + + std::map < int, + TravelState > + precachedTravelState; + std::map < int, + std::vector < + Vec2i > > + precachedPath; + }; + + class + FactionStateManager { + protected: + typedef + vector < + FactionState * > + FactionStateList; + FactionStateList + factions; + + void + init() { + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + factions.push_back(new FactionState(index)); + } + } + + public: + FactionStateManager() { + init(); + } + ~FactionStateManager() { + clear(); + } + + FactionState & getFactionState(int index) { + FactionState * + faction = factions[index]; + return *faction; + } + void + clear() { + for (unsigned int index = 0; + index < (unsigned int) factions.size(); ++index) { + delete + factions[index]; + } + + factions.clear(); + } + int + size() { + return (int) factions.size(); + } + }; + + public: + static const int + maxFreeSearchRadius; + + static const int + pathFindBailoutRadius; + static const int + pathFindExtendRefreshForNodeCount; + static const int + pathFindExtendRefreshNodeCountMin; + static const int + pathFindExtendRefreshNodeCountMax; + + private: + + static int + pathFindNodesMax; + static int + pathFindNodesAbsoluteMax; + + + FactionStateManager + factions; + const Map * + map; + bool + minorDebugPathfinder; + + public: + PathFinder(); + explicit + PathFinder(const Map * map); + ~PathFinder(); + + PathFinder(const PathFinder & obj) { + init(); + throw + megaglest_runtime_error("class PathFinder is NOT safe to copy!"); + } + PathFinder & operator= (const PathFinder & obj) { + init(); + throw + megaglest_runtime_error("class PathFinder is NOT safe to assign!"); + } + + void + init(const Map * map); + TravelState + findPath(Unit * unit, const Vec2i & finalPos, bool * wasStuck = + NULL, int frameIndex = -1); + void + clearUnitPrecache(Unit * unit); + void + removeUnitPrecache(Unit * unit); + void + clearCaches(); + + //bool unitCannotMove(Unit *unit); + + int + findNodeIndex(Node * node, Nodes & nodeList); + int + findNodeIndex(Node * node, std::vector < Node > &nodeList); + + void + saveGame(XmlNode * rootNode); + void + loadGame(const XmlNode * rootNode); + + private: + void + init(); + + TravelState + aStar(Unit * unit, const Vec2i & finalPos, bool inBailout, + int frameIndex, int maxNodeCount = + -1, uint32 * searched_node_count = NULL); + inline static Node * + newNode(FactionState & faction, int maxNodeCount) { + if (faction.nodePoolCount < (int) faction.nodePool.size() && + faction.nodePoolCount < maxNodeCount) { + Node * + node = &(faction.nodePool[faction.nodePoolCount]); + node->clear(); + faction.nodePoolCount++; + return node; + } + return NULL; + } + + Vec2i + computeNearestFreePos(const Unit * unit, const Vec2i & targetPos); + + inline static float + heuristic(const Vec2i & pos, const Vec2i & finalPos) { + return pos.dist(finalPos); + } + + inline static bool + openPos(const Vec2i & sucPos, FactionState & faction) { + if (faction.openPosList.find(sucPos) == faction.openPosList.end()) { + return false; + } + return true; + } + + inline static Node * + minHeuristicFastLookup(FactionState & faction) { + if (faction.openNodesList.empty() == true) { + throw + megaglest_runtime_error("openNodesList.empty() == true"); + } + + Node * + result = faction.openNodesList.begin()->second.front(); + faction.openNodesList.begin()->second.erase(faction.openNodesList. + begin()->second. + begin()); + if (faction.openNodesList.begin()->second.empty()) { + faction.openNodesList.erase(faction.openNodesList.begin()); + } + return result; + } + + inline bool + processNode(Unit * unit, Node * node, const Vec2i finalPos, + int x, int y, bool & nodeLimitReached, int maxNodeCount) { + bool + result = false; + Vec2i + sucPos = node->pos + Vec2i(x, y); + + int + unitFactionIndex = unit->getFactionIndex(); + FactionState & faction = factions.getFactionState(unitFactionIndex); + + bool + foundOpenPosForPos = openPos(sucPos, faction); + bool + allowUnitMoveSoon = canUnitMoveSoon(unit, node->pos, sucPos); + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true + && SystemFlags::getSystemSettingType(SystemFlags:: + debugWorldSynchMax). + enabled == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In processNode() nodeLimitReached %d unitFactionIndex %d foundOpenPosForPos %d allowUnitMoveSoon %d maxNodeCount %d node->pos = %s finalPos = %s sucPos = %s faction.openPosList.size() %lu closedNodesList.size() %lu", + nodeLimitReached, unitFactionIndex, foundOpenPosForPos, + allowUnitMoveSoon, maxNodeCount, + node->pos.getString().c_str(), + finalPos.getString().c_str(), + sucPos.getString().c_str(), + faction.openPosList.size(), + faction.closedNodesList.size()); + + if (Thread::isCurrentThreadMainThread() == false) { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + } + + if (foundOpenPosForPos == false && allowUnitMoveSoon) { + //if node is not open and canMove then generate another node + Node * + sucNode = newNode(faction, maxNodeCount); + if (sucNode != NULL) { + sucNode->pos = sucPos; + sucNode->heuristic = heuristic(sucNode->pos, finalPos); + sucNode->prev = node; + sucNode->next = NULL; + sucNode->exploredCell = + map->getSurfaceCell(Map::toSurfCoords(sucPos))-> + isExplored(unit->getTeam()); + if (faction.openNodesList.find(sucNode->heuristic) == + faction.openNodesList.end()) { + faction.openNodesList[sucNode->heuristic].clear(); + } + faction.openNodesList[sucNode->heuristic].push_back(sucNode); + faction.openPosList[sucNode->pos] = true; + + result = true; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true + && SystemFlags::getSystemSettingType(SystemFlags:: + debugWorldSynchMax). + enabled == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In processNode() sucPos = %s", + sucPos.getString().c_str()); + + if (Thread::isCurrentThreadMainThread() == false) { + unit->logSynchDataThreaded(__FILE__, __LINE__, + szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + } + + } else { + nodeLimitReached = true; + } + } + + return result; + } + + void + processNearestFreePos(const Vec2i & finalPos, int i, int j, int size, + Field field, int teamIndex, Vec2i unitPos, + Vec2i & nearestPos, float &nearestDist); + int + getPathFindExtendRefreshNodeCount(FactionState & faction); + + inline bool + canUnitMoveSoon(Unit * unit, const Vec2i & pos1, const Vec2i & pos2) { + bool + result = map->aproxCanMoveSoon(unit, pos1, pos2); + return result; + } + + inline void + doAStarPathSearch(bool & nodeLimitReached, int &whileLoopCount, + int &unitFactionIndex, bool & pathFound, + Node * &node, const Vec2i & finalPos, + const std::map < Vec2i, bool > &closedNodes, + const std::map < Vec2i, Vec2i > &cameFrom, + const std::map < std::pair < Vec2i, Vec2i >, + bool > &canAddNode, Unit * &unit, int &maxNodeCount, + int curFrameIndex) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true + && SystemFlags::getSystemSettingType(SystemFlags:: + debugWorldSynchMax). + enabled == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In doAStarPathSearch() nodeLimitReached %d whileLoopCount %d unitFactionIndex %d pathFound %d maxNodeCount %d", + nodeLimitReached, whileLoopCount, unitFactionIndex, + pathFound, maxNodeCount); + + if (curFrameIndex >= 0) { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + } + + FactionState & faction = factions.getFactionState(unitFactionIndex); + + while (nodeLimitReached == false) { + whileLoopCount++; + if (faction.openNodesList.empty() == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true + && SystemFlags::getSystemSettingType(SystemFlags:: + debugWorldSynchMax). + enabled == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In doAStarPathSearch() nodeLimitReached %d whileLoopCount %d unitFactionIndex %d pathFound %d maxNodeCount %d", + nodeLimitReached, whileLoopCount, + unitFactionIndex, pathFound, maxNodeCount); + + if (curFrameIndex >= 0) { + unit->logSynchDataThreaded(__FILE__, __LINE__, + szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + } + + pathFound = false; + break; + } + node = minHeuristicFastLookup(faction); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true + && SystemFlags::getSystemSettingType(SystemFlags:: + debugWorldSynchMax). + enabled == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In doAStarPathSearch() nodeLimitReached %d whileLoopCount %d unitFactionIndex %d pathFound %d maxNodeCount %d node->pos = %s finalPos = %s node->exploredCell = %d", + nodeLimitReached, whileLoopCount, unitFactionIndex, + pathFound, maxNodeCount, + node->pos.getString().c_str(), + finalPos.getString().c_str(), node->exploredCell); + + if (curFrameIndex >= 0) { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + } + + if (node->pos == finalPos || node->exploredCell == false) { + pathFound = true; + break; + } + + if (faction.closedNodesList.find(node->heuristic) == + faction.closedNodesList.end()) { + faction.closedNodesList[node->heuristic].clear(); + } + faction.closedNodesList[node->heuristic].push_back(node); + faction.openPosList[node->pos] = true; + + int + failureCount = 0; + int + cellCount = 0; + + // if(Thread::isCurrentThreadMainThread() == false) { + // throw megaglest_runtime_error("#1 Invalid access to FactionState random from outside main thread current id = " + + // intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId())); + // } + + //int tryDirection = 1; + //int tryDirection = faction.random.IRandomX(1, 4); + int + tryDirection = faction.random.randRange(1, 4); + //int tryDirection = unit->getRandom(true)->randRange(1, 4); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true + && SystemFlags::getSystemSettingType(SystemFlags:: + debugWorldSynchMax). + enabled == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In doAStarPathSearch() tryDirection %d", + tryDirection); + + if (curFrameIndex >= 0) { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + } + + if (tryDirection == 4) { + for (int i = 1; i >= -1 && nodeLimitReached == false; --i) { + for (int j = -1; j <= 1 && nodeLimitReached == false; ++j) { + if (processNode + (unit, node, finalPos, i, j, nodeLimitReached, + maxNodeCount) == false) { + failureCount++; + } + cellCount++; + } + } + } else if (tryDirection == 3) { + for (int i = -1; i <= 1 && nodeLimitReached == false; ++i) { + for (int j = 1; j >= -1 && nodeLimitReached == false; --j) { + if (processNode + (unit, node, finalPos, i, j, nodeLimitReached, + maxNodeCount) == false) { + failureCount++; + } + cellCount++; + } + } + } else if (tryDirection == 2) { + for (int i = -1; i <= 1 && nodeLimitReached == false; ++i) { + for (int j = -1; j <= 1 && nodeLimitReached == false; ++j) { + if (processNode + (unit, node, finalPos, i, j, nodeLimitReached, + maxNodeCount) == false) { + failureCount++; + } + cellCount++; + } + } + } else { + for (int i = 1; i >= -1 && nodeLimitReached == false; --i) { + for (int j = 1; j >= -1 && nodeLimitReached == false; --j) { + if (processNode + (unit, node, finalPos, i, j, nodeLimitReached, + maxNodeCount) == false) { + failureCount++; + } + cellCount++; + } + } + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true + && SystemFlags::getSystemSettingType(SystemFlags:: + debugWorldSynchMax). + enabled == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In doAStarPathSearch() nodeLimitReached %d whileLoopCount %d unitFactionIndex %d pathFound %d maxNodeCount %d", + nodeLimitReached, whileLoopCount, unitFactionIndex, + pathFound, maxNodeCount); + + if (curFrameIndex >= 0) { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + } + + } + + }; + + } } //end namespace #endif diff --git a/source/glest_game/facilities/auto_test.cpp b/source/glest_game/facilities/auto_test.cpp index ff2167f02..28fdb3a72 100644 --- a/source/glest_game/facilities/auto_test.cpp +++ b/source/glest_game/facilities/auto_test.cpp @@ -23,89 +23,90 @@ #include "leak_dumper.h" -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class AutoTest -// ===================================================== + // ===================================================== + // class AutoTest + // ===================================================== -const time_t AutoTest::invalidTime = -1; -time_t AutoTest::gameTime = 60 * 20; -bool AutoTest::wantExitGame = false; + const time_t AutoTest::invalidTime = -1; + time_t AutoTest::gameTime = 60 * 20; + bool AutoTest::wantExitGame = false; -GameSettings AutoTest::gameSettings; -string AutoTest::loadGameSettingsFile = ""; + GameSettings AutoTest::gameSettings; + string AutoTest::loadGameSettingsFile = ""; -// ===================== PUBLIC ======================== + // ===================== PUBLIC ======================== -AutoTest::AutoTest() { - exitGame = false; - gameStartTime = invalidTime; - random.init(time(NULL)); -} - -AutoTest & AutoTest::getInstance() { - static AutoTest autoTest; - return autoTest; -} - -void AutoTest::updateIntro(Program *program) { - program->setState(new MainMenu(program)); -} - -void AutoTest::updateRoot(Program *program, MainMenu *mainMenu) { - mainMenu->setState(new MenuStateNewGame(program, mainMenu)); -} - -void AutoTest::updateNewGame(Program *program, MainMenu *mainMenu) { - if(loadGameSettingsFile != "") { - gameStartTime = invalidTime; - bool fileFound = CoreData::getInstance().loadGameSettingsFromFile( - loadGameSettingsFile, &gameSettings); - - if(fileFound == false) { - throw megaglest_runtime_error("Specified game settings file [" + loadGameSettingsFile + "] was NOT found!"); + AutoTest::AutoTest() { + exitGame = false; + gameStartTime = invalidTime; + random.init(time(NULL)); } - //printf("Got settings:\n%s",gameSettings.toString().c_str()); - mainMenu->setState(new MenuStateCustomGame(program, mainMenu, false, pNewGame, true, &gameSettings)); - } - else { - mainMenu->setState(new MenuStateScenario(program, mainMenu, false, - Config::getInstance().getPathListForType(ptScenarios))); - } -} -void AutoTest::updateScenario(MenuStateScenario *menuStateScenario) { - gameStartTime = invalidTime; - - int scenarioIndex = random.randRange(0, menuStateScenario->getScenarioCount()-1); - menuStateScenario->setScenario(scenarioIndex); - - menuStateScenario->launchGame(); -} - -bool AutoTest::updateGame(Game *game) { - // record start time - if(gameStartTime == invalidTime) { - gameStartTime = time(NULL); - } - - // quit if we've espend enough time in the game - if(difftime(time(NULL),gameStartTime) > gameTime) { - Program *program = game->getProgram(); - Stats endStats = game->quitGame(); - if(AutoTest::wantExitGame == true) { - exitGame = true; + AutoTest & AutoTest::getInstance() { + static AutoTest autoTest; + return autoTest; } - Game::exitGameState(program, endStats); - return true; + + void AutoTest::updateIntro(Program *program) { + program->setState(new MainMenu(program)); + } + + void AutoTest::updateRoot(Program *program, MainMenu *mainMenu) { + mainMenu->setState(new MenuStateNewGame(program, mainMenu)); + } + + void AutoTest::updateNewGame(Program *program, MainMenu *mainMenu) { + if (loadGameSettingsFile != "") { + gameStartTime = invalidTime; + bool fileFound = CoreData::getInstance().loadGameSettingsFromFile( + loadGameSettingsFile, &gameSettings); + + if (fileFound == false) { + throw megaglest_runtime_error("Specified game settings file [" + loadGameSettingsFile + "] was NOT found!"); + } + //printf("Got settings:\n%s",gameSettings.toString().c_str()); + mainMenu->setState(new MenuStateCustomGame(program, mainMenu, false, pNewGame, true, &gameSettings)); + } else { + mainMenu->setState(new MenuStateScenario(program, mainMenu, false, + Config::getInstance().getPathListForType(ptScenarios))); + } + } + + void AutoTest::updateScenario(MenuStateScenario *menuStateScenario) { + gameStartTime = invalidTime; + + int scenarioIndex = random.randRange(0, menuStateScenario->getScenarioCount() - 1); + menuStateScenario->setScenario(scenarioIndex); + + menuStateScenario->launchGame(); + } + + bool AutoTest::updateGame(Game *game) { + // record start time + if (gameStartTime == invalidTime) { + gameStartTime = time(NULL); + } + + // quit if we've espend enough time in the game + if (difftime(time(NULL), gameStartTime) > gameTime) { + Program *program = game->getProgram(); + Stats endStats = game->quitGame(); + if (AutoTest::wantExitGame == true) { + exitGame = true; + } + Game::exitGameState(program, endStats); + return true; + } + + return false; + } + + void AutoTest::updateBattleEnd(Program *program) { + program->setState(new MainMenu(program)); + } + } - - return false; -} - -void AutoTest::updateBattleEnd(Program *program) { - program->setState(new MainMenu(program)); -} - -}}//end namespace +}//end namespace diff --git a/source/glest_game/facilities/auto_test.h b/source/glest_game/facilities/auto_test.h index 73b878fc4..da6d8c891 100644 --- a/source/glest_game/facilities/auto_test.h +++ b/source/glest_game/facilities/auto_test.h @@ -13,8 +13,8 @@ #define _SHARED_UTIL_AUTO_TEST_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -26,51 +26,63 @@ using namespace std; using Shared::Util::RandomGen; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -class Program; -class MainMenu; -class MenuStateScenario; -class Game; + class Program; + class MainMenu; + class MenuStateScenario; + class Game; -// ===================================================== -// class AutoTest -// -/// Interface to write log files -// ===================================================== + // ===================================================== + // class AutoTest + // + /// Interface to write log files + // ===================================================== -class AutoTest{ -private: - int gameStartTime; - RandomGen random; - bool exitGame; - static bool wantExitGame; + class AutoTest { + private: + int gameStartTime; + RandomGen random; + bool exitGame; + static bool wantExitGame; - static GameSettings gameSettings; - static string loadGameSettingsFile; + static GameSettings gameSettings; + static string loadGameSettingsFile; - static const time_t invalidTime; - static time_t gameTime; + static const time_t invalidTime; + static time_t gameTime; -public: - static AutoTest & getInstance(); - AutoTest(); + public: + static AutoTest & getInstance(); + AutoTest(); - static void setMaxGameTime(time_t value) { gameTime = value; } - static void setWantExitGameWhenDone(bool value) { wantExitGame = value; } - static string getLoadGameSettingsFile() { return loadGameSettingsFile; } - static void setLoadGameSettingsFile(const string &filename) { loadGameSettingsFile = filename; } + static void setMaxGameTime(time_t value) { + gameTime = value; + } + static void setWantExitGameWhenDone(bool value) { + wantExitGame = value; + } + static string getLoadGameSettingsFile() { + return loadGameSettingsFile; + } + static void setLoadGameSettingsFile(const string &filename) { + loadGameSettingsFile = filename; + } - bool mustExitGame() const { return exitGame; } + bool mustExitGame() const { + return exitGame; + } - void updateIntro(Program *program); - void updateRoot(Program *program, MainMenu *mainMenu); - void updateNewGame(Program *program, MainMenu *mainMenu); - void updateScenario(MenuStateScenario *menuStateScenario); - bool updateGame(Game *game); - void updateBattleEnd(Program *program); -}; + void updateIntro(Program *program); + void updateRoot(Program *program, MainMenu *mainMenu); + void updateNewGame(Program *program, MainMenu *mainMenu); + void updateScenario(MenuStateScenario *menuStateScenario); + bool updateGame(Game *game); + void updateBattleEnd(Program *program); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/glest_game/facilities/components.cpp b/source/glest_game/facilities/components.cpp index fe581fa74..607624d57 100644 --- a/source/glest_game/facilities/components.cpp +++ b/source/glest_game/facilities/components.cpp @@ -26,1155 +26,1136 @@ using namespace std; using namespace Shared::Util; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class GraphicComponent -// ===================================================== + // ===================================================== + // class GraphicComponent + // ===================================================== -float GraphicComponent::anim= 0.f; -float GraphicComponent::fade= 0.f; -const float GraphicComponent::animSpeed= 0.02f; -const float GraphicComponent::fadeSpeed= 0.01f; -// WHITE -Vec3f GraphicComponent::customTextColor = Vec3f(1.0,1.0,1.0); + float GraphicComponent::anim = 0.f; + float GraphicComponent::fade = 0.f; + const float GraphicComponent::animSpeed = 0.02f; + const float GraphicComponent::fadeSpeed = 0.01f; + // WHITE + Vec3f GraphicComponent::customTextColor = Vec3f(1.0, 1.0, 1.0); -std::map > GraphicComponent::registeredGraphicComponentList; + std::map > GraphicComponent::registeredGraphicComponentList; -GraphicComponent::GraphicComponent(const std::string &containerName, const std::string &objName, bool registerControl) { - this->containerName = containerName; - this->instanceName = ""; - if(containerName == "" || objName == "") { - //char szBuf[8096]=""; - //snprintf(szBuf,8096,"Control not properly registered Container [%s] Control [%s]\n",containerName.c_str(),objName.c_str()); - //throw megaglest_runtime_error(szBuf); - } - if(objName != "" && registerControl) { - registerGraphicComponent(containerName,objName); - } - else { - this->instanceName = objName; - } - this->fontCallbackName = objName + "_" + getNewUUD(); - CoreData::getInstance().registerFontChangedCallback(this->getFontCallbackName(), this); + GraphicComponent::GraphicComponent(const std::string &containerName, const std::string &objName, bool registerControl) { + this->containerName = containerName; + this->instanceName = ""; + if (containerName == "" || objName == "") { + //char szBuf[8096]=""; + //snprintf(szBuf,8096,"Control not properly registered Container [%s] Control [%s]\n",containerName.c_str(),objName.c_str()); + //throw megaglest_runtime_error(szBuf); + } + if (objName != "" && registerControl) { + registerGraphicComponent(containerName, objName); + } else { + this->instanceName = objName; + } + this->fontCallbackName = objName + "_" + getNewUUD(); + CoreData::getInstance().registerFontChangedCallback(this->getFontCallbackName(), this); - enabled = true; - editable = true; - visible = true; - x = 0; - y = 0; - w = 0; - h = 0; - text = ""; - font = NULL; - font3D = NULL; - textNativeTranslation = ""; -} - -string GraphicComponent::getNewUUD() { - char uuid_str[38]; - get_uuid_string(uuid_str,sizeof(uuid_str)); - return string(uuid_str); -} - -GraphicComponent::~GraphicComponent() { - CoreData::getInstance().unRegisterFontChangedCallback(this->getFontCallbackName()); -} - -void GraphicComponent::clearRegisteredComponents(std::string containerName) { - if(containerName == "") { - GraphicComponent::registeredGraphicComponentList.clear(); - } - else { - GraphicComponent::registeredGraphicComponentList[containerName].clear(); - } -} - -void GraphicComponent::clearRegisterGraphicComponent(std::string containerName, std::string objName) { - GraphicComponent *obj = findRegisteredComponent(containerName, objName); - if(obj) { - GraphicComponent::registeredGraphicComponentList[containerName].erase(objName); - } -} - -void GraphicComponent::clearRegisterGraphicComponent(std::string containerName, std::vector objNameList) { - for(int idx = 0; idx < (int)objNameList.size(); ++idx) { - GraphicComponent::clearRegisterGraphicComponent(containerName, objNameList[idx]); - } -} - -void GraphicComponent::registerGraphicComponent(std::string containerName, std::string objName) { - // unregistered old name if we have been renamed - if(this->getInstanceName() != "") { - //printf("RENAME Register Callback detected calling: Control old [%s] new [%s]\n",this->getInstanceName().c_str(),objName.c_str()); - clearRegisterGraphicComponent(this->containerName, this->getInstanceName()); - } - else { - //printf("NEW Register Callback detected calling: Control container [%s] name [%s]\n",containerName.c_str(),objName.c_str()); - } - - if(containerName == "" || objName == "") { - //char szBuf[8096]=""; - //snprintf(szBuf,8096,"Control not properly registered Container [%s] Control [%s]\n",this->containerName.c_str(),objName.c_str()); - //throw megaglest_runtime_error(szBuf); - } - - this->containerName = containerName; - this->instanceName = objName; - registeredGraphicComponentList[containerName][objName] = this; - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] registered [%s] [%s] count = %d\n",__FILE__,__FUNCTION__,__LINE__,containerName.c_str(),instanceName.c_str(),registeredGraphicComponentList[containerName].size()); -} - -void GraphicComponent::registerGraphicComponentOnlyFontCallbacks(std::string containerName, std::string objName) { - if(this->getInstanceName() != "") { - //printf("(FONT ONLY) RENAME Register Callback detected calling: Control old [%s] new [%s]\n",this->getInstanceName().c_str(),objName.c_str()); - clearRegisterGraphicComponent(this->containerName, this->getInstanceName()); - } - else { - //printf("(FONT ONLY) NEW Register Callback detected calling: Control container [%s] name [%s]\n",containerName.c_str(),objName.c_str()); - } - - if(containerName == "" || objName == "") { - //char szBuf[8096]=""; - //snprintf(szBuf,8096,"Control not properly registered Container [%s] Control [%s]\n",this->containerName.c_str(),objName.c_str()); - //throw megaglest_runtime_error(szBuf); - } - - this->containerName = containerName; - this->instanceName = objName; -} - -GraphicComponent * GraphicComponent::findRegisteredComponent(std::string containerName, std::string objName) { - GraphicComponent *result = NULL; - - std::map >::iterator iterFind1 = GraphicComponent::registeredGraphicComponentList.find(containerName); - if(iterFind1 != GraphicComponent::registeredGraphicComponentList.end()) { - std::map::iterator iterFind2 = iterFind1->second.find(objName); - if(iterFind2 != iterFind1->second.end()) { - result = iterFind2->second; + enabled = true; + editable = true; + visible = true; + x = 0; + y = 0; + w = 0; + h = 0; + text = ""; + font = NULL; + font3D = NULL; + textNativeTranslation = ""; } - } - return result; -} -void GraphicComponent::applyAllCustomProperties(std::string containerName) { - std::map >::iterator iterFind1 = GraphicComponent::registeredGraphicComponentList.find(containerName); - if(iterFind1 != GraphicComponent::registeredGraphicComponentList.end()) { - for(std::map::iterator iterFind2 = iterFind1->second.begin(); - iterFind2 != iterFind1->second.end(); ++iterFind2) { - iterFind2->second->applyCustomProperties(containerName); + string GraphicComponent::getNewUUD() { + char uuid_str[38]; + get_uuid_string(uuid_str, sizeof(uuid_str)); + return string(uuid_str); } - } -} -void GraphicComponent::applyCustomProperties(std::string containerName) { - if(instanceName != "") { - std::map >::iterator iterFind1 = GraphicComponent::registeredGraphicComponentList.find(containerName); - if(iterFind1 != GraphicComponent::registeredGraphicComponentList.end()) { - std::map::iterator iterFind2 = iterFind1->second.find(instanceName); - if(iterFind2 != iterFind1->second.end()) { - Config &config = Config::getInstance(); + GraphicComponent::~GraphicComponent() { + CoreData::getInstance().unRegisterFontChangedCallback(this->getFontCallbackName()); + } - //string languageToken = config.getString("Lang"); - string languageToken = Lang::getInstance().getLanguage(); - - //if(dynamic_cast(iterFind2->second) != NULL) { - GraphicComponent *ctl = dynamic_cast(iterFind2->second); - - // First check default overrides - ctl->x = config.getInt(containerName + "_" + iterFind2->first + "_x",intToStr(ctl->x).c_str()); - ctl->y = config.getInt(containerName + "_" + iterFind2->first + "_y",intToStr(ctl->y).c_str()); - ctl->w = config.getInt(containerName + "_" + iterFind2->first + "_w",intToStr(ctl->w).c_str()); - ctl->h = config.getInt(containerName + "_" + iterFind2->first + "_h",intToStr(ctl->h).c_str()); - ctl->visible = config.getBool(containerName + "_" + iterFind2->first + "_visible",boolToStr(ctl->visible).c_str()); - - // Now check language specific overrides - ctl->x = config.getInt(containerName + "_" + iterFind2->first + "_x_" + languageToken, intToStr(ctl->x).c_str()); - ctl->y = config.getInt(containerName + "_" + iterFind2->first + "_y_" + languageToken, intToStr(ctl->y).c_str()); - ctl->w = config.getInt(containerName + "_" + iterFind2->first + "_w_" + languageToken, intToStr(ctl->w).c_str()); - ctl->h = config.getInt(containerName + "_" + iterFind2->first + "_h_" + languageToken, intToStr(ctl->h).c_str()); - ctl->visible = config.getBool(containerName + "_" + iterFind2->first + "_visible_" + languageToken,boolToStr(ctl->visible).c_str()); + void GraphicComponent::clearRegisteredComponents(std::string containerName) { + if (containerName == "") { + GraphicComponent::registeredGraphicComponentList.clear(); + } else { + GraphicComponent::registeredGraphicComponentList[containerName].clear(); } } - } -} -bool GraphicComponent::saveAllCustomProperties(std::string containerName) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] registered [%s] count = %d\n",__FILE__,__FUNCTION__,__LINE__,containerName.c_str(),registeredGraphicComponentList[containerName].size()); - - bool foundPropertiesToSave = false; - std::map >::iterator iterFind1 = GraphicComponent::registeredGraphicComponentList.find(containerName); - if(iterFind1 != GraphicComponent::registeredGraphicComponentList.end()) { - for(std::map::iterator iterFind2 = iterFind1->second.begin(); - iterFind2 != iterFind1->second.end(); ++iterFind2) { - bool saved = iterFind2->second->saveCustomProperties(containerName); - foundPropertiesToSave = (saved || foundPropertiesToSave); - } - } - - if(foundPropertiesToSave == true) { - Config &config = Config::getInstance(); - config.save(); - } - - return foundPropertiesToSave; -} - -bool GraphicComponent::saveCustomProperties(std::string containerName) { - bool savedChange = false; - if(instanceName != "") { - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] looking for [%s] [%s]\n",__FILE__,__FUNCTION__,__LINE__,containerName.c_str(),instanceName.c_str()); - - std::map >::iterator iterFind1 = GraphicComponent::registeredGraphicComponentList.find(containerName); - if(iterFind1 != GraphicComponent::registeredGraphicComponentList.end()) { - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] looking for [%s]\n",__FILE__,__FUNCTION__,__LINE__,instanceName.c_str()); - - std::map::iterator iterFind2 = iterFind1->second.find(instanceName); - if(iterFind2 != iterFind1->second.end()) { - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] FOUND [%s]\n",__FILE__,__FUNCTION__,__LINE__,instanceName.c_str()); - - Config &config = Config::getInstance(); - - //string languageToken = config.getString("Lang"); - - //if(dynamic_cast(iterFind2->second) != NULL) { - GraphicComponent *ctl = dynamic_cast(iterFind2->second); - - // First check default overrides - config.setInt(containerName + "_" + iterFind2->first + "_x",ctl->x); - config.setInt(containerName + "_" + iterFind2->first + "_y",ctl->y); - config.setInt(containerName + "_" + iterFind2->first + "_w",ctl->w); - config.setInt(containerName + "_" + iterFind2->first + "_h",ctl->h); - - savedChange = true; - // Now check language specific overrides - //ctl->x = config.getInt(containerName + "_" + iterFind2->first + "_x_" + languageToken, intToStr(ctl->x).c_str()); - //ctl->y = config.getInt(containerName + "_" + iterFind2->first + "_y_" + languageToken, intToStr(ctl->y).c_str()); - //ctl->w = config.getInt(containerName + "_" + iterFind2->first + "_w_" + languageToken, intToStr(ctl->w).c_str()); - //ctl->h = config.getInt(containerName + "_" + iterFind2->first + "_h_" + languageToken, intToStr(ctl->h).c_str()); - - //} + void GraphicComponent::clearRegisterGraphicComponent(std::string containerName, std::string objName) { + GraphicComponent *obj = findRegisteredComponent(containerName, objName); + if (obj) { + GraphicComponent::registeredGraphicComponentList[containerName].erase(objName); } } - } - return savedChange; -} - -void GraphicComponent::setFont(Font2D *font) { - this->font = font; - if (this->font != NULL) { - this->font2DUniqueId = font->getFontUniqueId(); - } - else { - this->font2DUniqueId = ""; - } -} - -void GraphicComponent::setFont3D(Font3D *font) { - this->font3D = font; - if (this->font3D != NULL) { - this->font3DUniqueId = font->getFontUniqueId(); - } - else { - this->font3DUniqueId = ""; - } -} - -void GraphicComponent::FontChangedCallback(std::string fontUniqueId, Font *font) { - //printf("In FontChanged for [%s] font [%p] Control 2D [%s] 3D [%s]\n", fontUniqueId.c_str(),font,this->font2DUniqueId.c_str(),this->font3DUniqueId.c_str()); - if (fontUniqueId != "") { - if (fontUniqueId == this->font2DUniqueId) { - if (font != NULL) { - this->font = (Font2D *)font; - } - else { - this->font = NULL; + void GraphicComponent::clearRegisterGraphicComponent(std::string containerName, std::vector objNameList) { + for (int idx = 0; idx < (int) objNameList.size(); ++idx) { + GraphicComponent::clearRegisterGraphicComponent(containerName, objNameList[idx]); } } - else if (fontUniqueId == this->font3DUniqueId) { - if (font != NULL) { - this->font3D = (Font3D *)font; - } - else { - this->font3D = NULL; - } - } - } -} -void GraphicComponent::reloadFonts() { - setFont(CoreData::getInstance().getMenuFontNormal()); - setFont3D(CoreData::getInstance().getMenuFontNormal3D()); -} - -void GraphicComponent::reloadFontsForRegisterGraphicComponents(std::string containerName) { - std::map >::iterator iterFind1 = GraphicComponent::registeredGraphicComponentList.find(containerName); - if(iterFind1 != GraphicComponent::registeredGraphicComponentList.end()) { - for(std::map::iterator iterFind2 = iterFind1->second.begin(); - iterFind2 != iterFind1->second.end(); ++iterFind2) { - GraphicComponent *ctl = dynamic_cast(iterFind2->second); - if(ctl) { - ctl->reloadFonts(); - } - } - } -} - -void GraphicComponent::init(int x, int y, int w, int h) { - this->x= x; - this->y= y; - this->w= w; - this->h= h; - reloadFonts(); - enabled= true; -} - -bool GraphicComponent::mouseMove(int x, int y) { - if(this->getVisible() == false) { - return false; - } - - return - x > this->x && - y > this->y && - x < this->x + w && - y < this->y + h; -} - -bool GraphicComponent::mouseClick(int x, int y){ - if(getVisible() && getEnabled() && getEditable()) - return mouseMove(x, y); - else - return false; -} - -void GraphicComponent::update(){ - fade+= fadeSpeed; - anim+= animSpeed; - if(fade>1.f) fade= 1.f; - if(anim>1.f) anim= 0.f; -} - -void GraphicComponent::resetFade(){ - fade= 0.f; -} - -// ===================================================== -// class GraphicLabel -// ===================================================== - -const int GraphicLabel::defH= 20; -const int GraphicLabel::defW= 70; - -GraphicLabel::GraphicLabel(const std::string &containerName, const std::string &objName, bool registerControl) : - GraphicComponent(containerName, objName, registerControl) { - centered = false; - wordWrap = false; - centeredW = -1; - centeredH = 1; - editable = false; - editModeEnabled = false; - maxEditWidth = -1; - maxEditRenderWidth = -1; - renderBackground = false; - backgroundColor=Vec4f(0.2f,0.2f,0.2f,0.6f); - isPassword = false; - texture = NULL; -} - -void GraphicLabel::init(int x, int y, int w, int h, bool centered, Vec3f textColor, bool wordWrap) { - GraphicComponent::init(x, y, w, h); - this->centered= centered; - this->textColor=textColor; - this->wordWrap = wordWrap; -} - -bool GraphicLabel::mouseMove(int x, int y) { - if(this->getVisible() == false) { - return false; - } - - int useWidth = w; - if(text.length() > 0 && font3D != NULL) { - float lineWidth = (font3D->getTextHandler()->Advance(text.c_str()) * Shared::Graphics::Font::scaleFontValue); - useWidth = (int)lineWidth; - } - - if(editable && useWidth this->x && - y > this->y && - x < this->x + useWidth && - y < this->y + h; -} - -bool GraphicLabel::getCenteredW() const { - bool result = (centered || centeredW == 1); - return result; -} -//void GraphicLabel::setCenteredW(bool centered) { -// centeredW = (centered ? 1 : 0); -//} - -bool GraphicLabel::getCenteredH() const { - bool result = (centered || centeredH == 1); - return result; -} -//void GraphicLabel::setCenteredH(bool centered) { -// centeredH = (centered ? 1 : 0); -//} - -// ===================================================== -// class GraphicButton -// ===================================================== - -const int GraphicButton::defH= 22; -const int GraphicButton::defW= 90; - -GraphicButton::GraphicButton(const std::string &containerName, const std::string &objName, bool registerControl) : - GraphicComponent(containerName,objName,registerControl) { - - lighted = false; - alwaysLighted = false; - useCustomTexture = false; - customTexture = NULL; -} - -void GraphicButton::init(int x, int y, int w, int h){ - GraphicComponent::init(x, y, w, h); - lighted= false; -} - -bool GraphicButton::mouseMove(int x, int y){ - if(this->getVisible() == false) { - return false; - } - - bool b= GraphicComponent::mouseMove(x, y); - lighted= b; - return b; -} - -// ===================================================== -// class GraphicListBox -// ===================================================== - -const int GraphicListBox::defH= 22; -const int GraphicListBox::defW= 140; - -GraphicListBox::GraphicListBox(const std::string &containerName, const std::string &objName) -: GraphicComponent(containerName, objName), graphButton1(containerName, objName + "_button1"), - graphButton2(containerName, objName + "_button2") { - selectedItemIndex = 0; - lighted = false; - leftControlled = false; -} - -void GraphicListBox::init(int x, int y, int w, int h, Vec3f textColor){ - GraphicComponent::init(x, y, w, h); - - this->textColor=textColor; - graphButton1.init(x, y, 22, h); - graphButton2.init(x+w-22, y, 22, h); - graphButton1.setText("<"); - graphButton2.setText(">"); - selectedItemIndex=-1; - lighted=false; -} - -const string & GraphicListBox::getTextNativeTranslation() { - if(this->translated_items.empty() == true || - this->selectedItemIndex < 0 || - this->selectedItemIndex >= (int)this->translated_items.size() || - this->items.size() != this->translated_items.size()) { - return this->text; - } - else { - return this->translated_items[this->selectedItemIndex]; - } -} - -//queryes -void GraphicListBox::pushBackItem(string item, string translated_item){ - items.push_back(item); - translated_items.push_back(translated_item); - setSelectedItemIndex(0); -} - -void GraphicListBox::setItems(const vector &items, const vector translated_items){ - this->items= items; - this->translated_items = translated_items; - if(items.empty() == false) { - setSelectedItemIndex(0); - } - else { - selectedItemIndex=-1; - setText(""); - } -} - -void GraphicListBox::setSelectedItemIndex(int index, bool errorOnMissing){ - if(errorOnMissing == true && (index < 0 || index >= (int)items.size())) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Index not found in listbox name: [%s] value index: %d size: %lu",this->instanceName.c_str(),index,(unsigned long)items.size()); - throw megaglest_runtime_error(szBuf); - } - selectedItemIndex= index; - setText(getSelectedItem()); -} - -void GraphicListBox::setLeftControlled(bool leftControlled) { - if(this->leftControlled!=leftControlled){ - this->leftControlled= leftControlled; - if(leftControlled==true) { - graphButton2.setX(x+graphButton1.getW()-4); - graphButton2.setH(graphButton2.getH()-4); - graphButton2.setW(graphButton2.getW()-4); - graphButton1.setH(graphButton1.getH()-4); - graphButton1.setW(graphButton1.getW()-4); - graphButton2.setY(graphButton2.getY()+2); - graphButton1.setY(graphButton1.getY()+2); - } - else { - graphButton2.setX(x+w-graphButton2.getW()+4); - graphButton2.setH(graphButton2.getH()+4); - graphButton2.setW(graphButton2.getW()+4); - graphButton1.setH(graphButton1.getH()+4); - graphButton1.setW(graphButton1.getW()+4); - graphButton2.setY(graphButton2.getY()-2); - graphButton1.setY(graphButton1.getY()-2); - } - } -} - -void GraphicListBox::setX(int x) { - this->x= x; - graphButton1.setX(x); - if(leftControlled==true) { - graphButton2.setX(x+graphButton1.getW()); - } - else { - graphButton2.setX(x+w-graphButton2.getW()); - } -} - -void GraphicListBox::setY(int y) { - this->y= y; - graphButton1.setY(y); - graphButton2.setY(y); -} - -void GraphicListBox::setEditable(bool editable){ - graphButton1.setEditable(editable); - graphButton2.setEditable(editable); - GraphicComponent::setEditable(editable); -} - -bool GraphicListBox::hasItem(string item) const { - bool result = false; - vector::const_iterator iter= find(items.begin(), items.end(), item); - if(iter != items.end()) { - result = true; - } - - return result; -} - -void GraphicListBox::setSelectedItem(string item, bool errorOnMissing){ - vector::iterator iter; - - iter= find(items.begin(), items.end(), item); - - if(iter==items.end()) { - if(errorOnMissing == true) { - for(int idx = 0; idx < (int)items.size(); idx++) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\ninstanceName [%s] idx = %d items[idx] = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,instanceName.c_str(),idx,items[idx].c_str()); + void GraphicComponent::registerGraphicComponent(std::string containerName, std::string objName) { + // unregistered old name if we have been renamed + if (this->getInstanceName() != "") { + //printf("RENAME Register Callback detected calling: Control old [%s] new [%s]\n",this->getInstanceName().c_str(),objName.c_str()); + clearRegisterGraphicComponent(this->containerName, this->getInstanceName()); + } else { + //printf("NEW Register Callback detected calling: Control container [%s] name [%s]\n",containerName.c_str(),objName.c_str()); } - char szBuf[8096]=""; - snprintf(szBuf,8096,"Value not found in listbox name: [%s] value: %s",this->instanceName.c_str(),item.c_str()); - throw megaglest_runtime_error(szBuf); + if (containerName == "" || objName == "") { + //char szBuf[8096]=""; + //snprintf(szBuf,8096,"Control not properly registered Container [%s] Control [%s]\n",this->containerName.c_str(),objName.c_str()); + //throw megaglest_runtime_error(szBuf); + } + + this->containerName = containerName; + this->instanceName = objName; + registeredGraphicComponentList[containerName][objName] = this; + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] registered [%s] [%s] count = %d\n",__FILE__,__FUNCTION__,__LINE__,containerName.c_str(),instanceName.c_str(),registeredGraphicComponentList[containerName].size()); } - } - else { - setSelectedItemIndex(iter-items.begin()); - } -} + void GraphicComponent::registerGraphicComponentOnlyFontCallbacks(std::string containerName, std::string objName) { + if (this->getInstanceName() != "") { + //printf("(FONT ONLY) RENAME Register Callback detected calling: Control old [%s] new [%s]\n",this->getInstanceName().c_str(),objName.c_str()); + clearRegisterGraphicComponent(this->containerName, this->getInstanceName()); + } else { + //printf("(FONT ONLY) NEW Register Callback detected calling: Control container [%s] name [%s]\n",containerName.c_str(),objName.c_str()); + } -bool GraphicListBox::mouseMove(int x, int y){ - if(this->getVisible() == false) { - return false; - } + if (containerName == "" || objName == "") { + //char szBuf[8096]=""; + //snprintf(szBuf,8096,"Control not properly registered Container [%s] Control [%s]\n",this->containerName.c_str(),objName.c_str()); + //throw megaglest_runtime_error(szBuf); + } - return - graphButton1.mouseMove(x, y) || - graphButton2.mouseMove(x, y); -} + this->containerName = containerName; + this->instanceName = objName; + } -bool GraphicListBox::mouseClick(int x, int y,string advanceToItemStartingWith) { - if(this->getVisible() == false) { - return false; - } + GraphicComponent * GraphicComponent::findRegisteredComponent(std::string containerName, std::string objName) { + GraphicComponent *result = NULL; - if(!items.empty()) { - bool b1= graphButton1.mouseClick(x, y); - bool b2= graphButton2.mouseClick(x, y); + std::map >::iterator iterFind1 = GraphicComponent::registeredGraphicComponentList.find(containerName); + if (iterFind1 != GraphicComponent::registeredGraphicComponentList.end()) { + std::map::iterator iterFind2 = iterFind1->second.find(objName); + if (iterFind2 != iterFind1->second.end()) { + result = iterFind2->second; + } + } + return result; + } - if(b1) { - bool bFound = false; - if(advanceToItemStartingWith != "") { - for(int i = selectedItemIndex - 1; i >= 0; --i) { - string item = items[i]; - if((int)translated_items.size() > i) item = translated_items[i]; - if(StartsWith(toLower(item),toLower(advanceToItemStartingWith)) == true) { - bFound = true; - selectedItemIndex = i; - break; + void GraphicComponent::applyAllCustomProperties(std::string containerName) { + std::map >::iterator iterFind1 = GraphicComponent::registeredGraphicComponentList.find(containerName); + if (iterFind1 != GraphicComponent::registeredGraphicComponentList.end()) { + for (std::map::iterator iterFind2 = iterFind1->second.begin(); + iterFind2 != iterFind1->second.end(); ++iterFind2) { + iterFind2->second->applyCustomProperties(containerName); + } + } + } + + void GraphicComponent::applyCustomProperties(std::string containerName) { + if (instanceName != "") { + std::map >::iterator iterFind1 = GraphicComponent::registeredGraphicComponentList.find(containerName); + if (iterFind1 != GraphicComponent::registeredGraphicComponentList.end()) { + std::map::iterator iterFind2 = iterFind1->second.find(instanceName); + if (iterFind2 != iterFind1->second.end()) { + Config &config = Config::getInstance(); + + //string languageToken = config.getString("Lang"); + string languageToken = Lang::getInstance().getLanguage(); + + //if(dynamic_cast(iterFind2->second) != NULL) { + GraphicComponent *ctl = dynamic_cast(iterFind2->second); + + // First check default overrides + ctl->x = config.getInt(containerName + "_" + iterFind2->first + "_x", intToStr(ctl->x).c_str()); + ctl->y = config.getInt(containerName + "_" + iterFind2->first + "_y", intToStr(ctl->y).c_str()); + ctl->w = config.getInt(containerName + "_" + iterFind2->first + "_w", intToStr(ctl->w).c_str()); + ctl->h = config.getInt(containerName + "_" + iterFind2->first + "_h", intToStr(ctl->h).c_str()); + ctl->visible = config.getBool(containerName + "_" + iterFind2->first + "_visible", boolToStr(ctl->visible).c_str()); + + // Now check language specific overrides + ctl->x = config.getInt(containerName + "_" + iterFind2->first + "_x_" + languageToken, intToStr(ctl->x).c_str()); + ctl->y = config.getInt(containerName + "_" + iterFind2->first + "_y_" + languageToken, intToStr(ctl->y).c_str()); + ctl->w = config.getInt(containerName + "_" + iterFind2->first + "_w_" + languageToken, intToStr(ctl->w).c_str()); + ctl->h = config.getInt(containerName + "_" + iterFind2->first + "_h_" + languageToken, intToStr(ctl->h).c_str()); + ctl->visible = config.getBool(containerName + "_" + iterFind2->first + "_visible_" + languageToken, boolToStr(ctl->visible).c_str()); } } - if(bFound == false) { - for(int i = (int)items.size() - 1; i >= selectedItemIndex; --i) { - string item = items[i]; - if((int)translated_items.size() > i) item = translated_items[i]; - //printf("Trying to match [%s] with item [%s]\n",advanceToItemStartingWith.c_str(),item.c_str()); - if(StartsWith(toLower(item),toLower(advanceToItemStartingWith)) == true) { - bFound = true; - selectedItemIndex = i; - break; + } + } + + bool GraphicComponent::saveAllCustomProperties(std::string containerName) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] registered [%s] count = %d\n", __FILE__, __FUNCTION__, __LINE__, containerName.c_str(), registeredGraphicComponentList[containerName].size()); + + bool foundPropertiesToSave = false; + std::map >::iterator iterFind1 = GraphicComponent::registeredGraphicComponentList.find(containerName); + if (iterFind1 != GraphicComponent::registeredGraphicComponentList.end()) { + for (std::map::iterator iterFind2 = iterFind1->second.begin(); + iterFind2 != iterFind1->second.end(); ++iterFind2) { + bool saved = iterFind2->second->saveCustomProperties(containerName); + foundPropertiesToSave = (saved || foundPropertiesToSave); + } + } + + if (foundPropertiesToSave == true) { + Config &config = Config::getInstance(); + config.save(); + } + + return foundPropertiesToSave; + } + + bool GraphicComponent::saveCustomProperties(std::string containerName) { + bool savedChange = false; + if (instanceName != "") { + + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] looking for [%s] [%s]\n", __FILE__, __FUNCTION__, __LINE__, containerName.c_str(), instanceName.c_str()); + + std::map >::iterator iterFind1 = GraphicComponent::registeredGraphicComponentList.find(containerName); + if (iterFind1 != GraphicComponent::registeredGraphicComponentList.end()) { + + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] looking for [%s]\n", __FILE__, __FUNCTION__, __LINE__, instanceName.c_str()); + + std::map::iterator iterFind2 = iterFind1->second.find(instanceName); + if (iterFind2 != iterFind1->second.end()) { + + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] FOUND [%s]\n", __FILE__, __FUNCTION__, __LINE__, instanceName.c_str()); + + Config &config = Config::getInstance(); + + //string languageToken = config.getString("Lang"); + + //if(dynamic_cast(iterFind2->second) != NULL) { + GraphicComponent *ctl = dynamic_cast(iterFind2->second); + + // First check default overrides + config.setInt(containerName + "_" + iterFind2->first + "_x", ctl->x); + config.setInt(containerName + "_" + iterFind2->first + "_y", ctl->y); + config.setInt(containerName + "_" + iterFind2->first + "_w", ctl->w); + config.setInt(containerName + "_" + iterFind2->first + "_h", ctl->h); + + savedChange = true; + // Now check language specific overrides + //ctl->x = config.getInt(containerName + "_" + iterFind2->first + "_x_" + languageToken, intToStr(ctl->x).c_str()); + //ctl->y = config.getInt(containerName + "_" + iterFind2->first + "_y_" + languageToken, intToStr(ctl->y).c_str()); + //ctl->w = config.getInt(containerName + "_" + iterFind2->first + "_w_" + languageToken, intToStr(ctl->w).c_str()); + //ctl->h = config.getInt(containerName + "_" + iterFind2->first + "_h_" + languageToken, intToStr(ctl->h).c_str()); + + //} + } + } + } + + return savedChange; + } + + void GraphicComponent::setFont(Font2D *font) { + this->font = font; + if (this->font != NULL) { + this->font2DUniqueId = font->getFontUniqueId(); + } else { + this->font2DUniqueId = ""; + } + } + + void GraphicComponent::setFont3D(Font3D *font) { + this->font3D = font; + if (this->font3D != NULL) { + this->font3DUniqueId = font->getFontUniqueId(); + } else { + this->font3DUniqueId = ""; + } + } + + void GraphicComponent::FontChangedCallback(std::string fontUniqueId, Font *font) { + //printf("In FontChanged for [%s] font [%p] Control 2D [%s] 3D [%s]\n", fontUniqueId.c_str(),font,this->font2DUniqueId.c_str(),this->font3DUniqueId.c_str()); + if (fontUniqueId != "") { + if (fontUniqueId == this->font2DUniqueId) { + if (font != NULL) { + this->font = (Font2D *) font; + } else { + this->font = NULL; + } + } else if (fontUniqueId == this->font3DUniqueId) { + if (font != NULL) { + this->font3D = (Font3D *) font; + } else { + this->font3D = NULL; + } + } + } + } + + void GraphicComponent::reloadFonts() { + setFont(CoreData::getInstance().getMenuFontNormal()); + setFont3D(CoreData::getInstance().getMenuFontNormal3D()); + } + + void GraphicComponent::reloadFontsForRegisterGraphicComponents(std::string containerName) { + std::map >::iterator iterFind1 = GraphicComponent::registeredGraphicComponentList.find(containerName); + if (iterFind1 != GraphicComponent::registeredGraphicComponentList.end()) { + for (std::map::iterator iterFind2 = iterFind1->second.begin(); + iterFind2 != iterFind1->second.end(); ++iterFind2) { + GraphicComponent *ctl = dynamic_cast(iterFind2->second); + if (ctl) { + ctl->reloadFonts(); + } + } + } + } + + void GraphicComponent::init(int x, int y, int w, int h) { + this->x = x; + this->y = y; + this->w = w; + this->h = h; + reloadFonts(); + enabled = true; + } + + bool GraphicComponent::mouseMove(int x, int y) { + if (this->getVisible() == false) { + return false; + } + + return + x > this->x && + y > this->y && + x < this->x + w && + y < this->y + h; + } + + bool GraphicComponent::mouseClick(int x, int y) { + if (getVisible() && getEnabled() && getEditable()) + return mouseMove(x, y); + else + return false; + } + + void GraphicComponent::update() { + fade += fadeSpeed; + anim += animSpeed; + if (fade > 1.f) fade = 1.f; + if (anim > 1.f) anim = 0.f; + } + + void GraphicComponent::resetFade() { + fade = 0.f; + } + + // ===================================================== + // class GraphicLabel + // ===================================================== + + const int GraphicLabel::defH = 20; + const int GraphicLabel::defW = 70; + + GraphicLabel::GraphicLabel(const std::string &containerName, const std::string &objName, bool registerControl) : + GraphicComponent(containerName, objName, registerControl) { + centered = false; + wordWrap = false; + centeredW = -1; + centeredH = 1; + editable = false; + editModeEnabled = false; + maxEditWidth = -1; + maxEditRenderWidth = -1; + renderBackground = false; + backgroundColor = Vec4f(0.2f, 0.2f, 0.2f, 0.6f); + isPassword = false; + texture = NULL; + } + + void GraphicLabel::init(int x, int y, int w, int h, bool centered, Vec3f textColor, bool wordWrap) { + GraphicComponent::init(x, y, w, h); + this->centered = centered; + this->textColor = textColor; + this->wordWrap = wordWrap; + } + + bool GraphicLabel::mouseMove(int x, int y) { + if (this->getVisible() == false) { + return false; + } + + int useWidth = w; + if (text.length() > 0 && font3D != NULL) { + float lineWidth = (font3D->getTextHandler()->Advance(text.c_str()) * Shared::Graphics::Font::scaleFontValue); + useWidth = (int) lineWidth; + } + + if (editable && useWidth < getMaxEditRenderWidth()) { + useWidth = getMaxEditRenderWidth(); + } + + return + x > this->x && + y > this->y && + x < this->x + useWidth && + y < this->y + h; + } + + bool GraphicLabel::getCenteredW() const { + bool result = (centered || centeredW == 1); + return result; + } + //void GraphicLabel::setCenteredW(bool centered) { + // centeredW = (centered ? 1 : 0); + //} + + bool GraphicLabel::getCenteredH() const { + bool result = (centered || centeredH == 1); + return result; + } + //void GraphicLabel::setCenteredH(bool centered) { + // centeredH = (centered ? 1 : 0); + //} + + // ===================================================== + // class GraphicButton + // ===================================================== + + const int GraphicButton::defH = 22; + const int GraphicButton::defW = 90; + + GraphicButton::GraphicButton(const std::string &containerName, const std::string &objName, bool registerControl) : + GraphicComponent(containerName, objName, registerControl) { + + lighted = false; + alwaysLighted = false; + useCustomTexture = false; + customTexture = NULL; + } + + void GraphicButton::init(int x, int y, int w, int h) { + GraphicComponent::init(x, y, w, h); + lighted = false; + } + + bool GraphicButton::mouseMove(int x, int y) { + if (this->getVisible() == false) { + return false; + } + + bool b = GraphicComponent::mouseMove(x, y); + lighted = b; + return b; + } + + // ===================================================== + // class GraphicListBox + // ===================================================== + + const int GraphicListBox::defH = 22; + const int GraphicListBox::defW = 140; + + GraphicListBox::GraphicListBox(const std::string &containerName, const std::string &objName) + : GraphicComponent(containerName, objName), graphButton1(containerName, objName + "_button1"), + graphButton2(containerName, objName + "_button2") { + selectedItemIndex = 0; + lighted = false; + leftControlled = false; + } + + void GraphicListBox::init(int x, int y, int w, int h, Vec3f textColor) { + GraphicComponent::init(x, y, w, h); + + this->textColor = textColor; + graphButton1.init(x, y, 22, h); + graphButton2.init(x + w - 22, y, 22, h); + graphButton1.setText("<"); + graphButton2.setText(">"); + selectedItemIndex = -1; + lighted = false; + } + + const string & GraphicListBox::getTextNativeTranslation() { + if (this->translated_items.empty() == true || + this->selectedItemIndex < 0 || + this->selectedItemIndex >= (int) this->translated_items.size() || + this->items.size() != this->translated_items.size()) { + return this->text; + } else { + return this->translated_items[this->selectedItemIndex]; + } + } + + //queryes + void GraphicListBox::pushBackItem(string item, string translated_item) { + items.push_back(item); + translated_items.push_back(translated_item); + setSelectedItemIndex(0); + } + + void GraphicListBox::setItems(const vector &items, const vector translated_items) { + this->items = items; + this->translated_items = translated_items; + if (items.empty() == false) { + setSelectedItemIndex(0); + } else { + selectedItemIndex = -1; + setText(""); + } + } + + void GraphicListBox::setSelectedItemIndex(int index, bool errorOnMissing) { + if (errorOnMissing == true && (index < 0 || index >= (int) items.size())) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Index not found in listbox name: [%s] value index: %d size: %lu", this->instanceName.c_str(), index, (unsigned long) items.size()); + throw megaglest_runtime_error(szBuf); + } + selectedItemIndex = index; + setText(getSelectedItem()); + } + + void GraphicListBox::setLeftControlled(bool leftControlled) { + if (this->leftControlled != leftControlled) { + this->leftControlled = leftControlled; + if (leftControlled == true) { + graphButton2.setX(x + graphButton1.getW() - 4); + graphButton2.setH(graphButton2.getH() - 4); + graphButton2.setW(graphButton2.getW() - 4); + graphButton1.setH(graphButton1.getH() - 4); + graphButton1.setW(graphButton1.getW() - 4); + graphButton2.setY(graphButton2.getY() + 2); + graphButton1.setY(graphButton1.getY() + 2); + } else { + graphButton2.setX(x + w - graphButton2.getW() + 4); + graphButton2.setH(graphButton2.getH() + 4); + graphButton2.setW(graphButton2.getW() + 4); + graphButton1.setH(graphButton1.getH() + 4); + graphButton1.setW(graphButton1.getW() + 4); + graphButton2.setY(graphButton2.getY() - 2); + graphButton1.setY(graphButton1.getY() - 2); + } + } + } + + void GraphicListBox::setX(int x) { + this->x = x; + graphButton1.setX(x); + if (leftControlled == true) { + graphButton2.setX(x + graphButton1.getW()); + } else { + graphButton2.setX(x + w - graphButton2.getW()); + } + } + + void GraphicListBox::setY(int y) { + this->y = y; + graphButton1.setY(y); + graphButton2.setY(y); + } + + void GraphicListBox::setEditable(bool editable) { + graphButton1.setEditable(editable); + graphButton2.setEditable(editable); + GraphicComponent::setEditable(editable); + } + + bool GraphicListBox::hasItem(string item) const { + bool result = false; + vector::const_iterator iter = find(items.begin(), items.end(), item); + if (iter != items.end()) { + result = true; + } + + return result; + } + + void GraphicListBox::setSelectedItem(string item, bool errorOnMissing) { + vector::iterator iter; + + iter = find(items.begin(), items.end(), item); + + if (iter == items.end()) { + if (errorOnMissing == true) { + for (int idx = 0; idx < (int) items.size(); idx++) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\ninstanceName [%s] idx = %d items[idx] = [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, instanceName.c_str(), idx, items[idx].c_str()); + } + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Value not found in listbox name: [%s] value: %s", this->instanceName.c_str(), item.c_str()); + throw megaglest_runtime_error(szBuf); + } + } else { + setSelectedItemIndex(iter - items.begin()); + } + + } + + bool GraphicListBox::mouseMove(int x, int y) { + if (this->getVisible() == false) { + return false; + } + + return + graphButton1.mouseMove(x, y) || + graphButton2.mouseMove(x, y); + } + + bool GraphicListBox::mouseClick(int x, int y, string advanceToItemStartingWith) { + if (this->getVisible() == false) { + return false; + } + + if (!items.empty()) { + bool b1 = graphButton1.mouseClick(x, y); + bool b2 = graphButton2.mouseClick(x, y); + + if (b1) { + bool bFound = false; + if (advanceToItemStartingWith != "") { + for (int i = selectedItemIndex - 1; i >= 0; --i) { + string item = items[i]; + if ((int) translated_items.size() > i) item = translated_items[i]; + if (StartsWith(toLower(item), toLower(advanceToItemStartingWith)) == true) { + bFound = true; + selectedItemIndex = i; + break; + } + } + if (bFound == false) { + for (int i = (int) items.size() - 1; i >= selectedItemIndex; --i) { + string item = items[i]; + if ((int) translated_items.size() > i) item = translated_items[i]; + //printf("Trying to match [%s] with item [%s]\n",advanceToItemStartingWith.c_str(),item.c_str()); + if (StartsWith(toLower(item), toLower(advanceToItemStartingWith)) == true) { + bFound = true; + selectedItemIndex = i; + break; + } + } } } - } - } - if(bFound == false) { - selectedItemIndex--; - } - if(selectedItemIndex<0){ - selectedItemIndex = (int)items.size()-1; - } - } - else if(b2) { - bool bFound = false; - if(advanceToItemStartingWith != "") { - for(int i = selectedItemIndex + 1; i < (int)items.size(); ++i) { - string item = items[i]; - if((int)translated_items.size() > i) item = translated_items[i]; - //printf("Trying to match [%s] with item [%s]\n",advanceToItemStartingWith.c_str(),item.c_str()); - if(StartsWith(toLower(item),toLower(advanceToItemStartingWith)) == true) { - bFound = true; - selectedItemIndex = i; - break; + if (bFound == false) { + selectedItemIndex--; } - } - if(bFound == false) { - for(int i = 0; i <= selectedItemIndex; ++i) { - string item = items[i]; - if((int)translated_items.size() > i) item = translated_items[i]; - //printf("Trying to match [%s] with item [%s]\n",advanceToItemStartingWith.c_str(),item.c_str()); - if(StartsWith(toLower(item),toLower(advanceToItemStartingWith)) == true) { - bFound = true; - selectedItemIndex = i; - break; + if (selectedItemIndex < 0) { + selectedItemIndex = (int) items.size() - 1; + } + } else if (b2) { + bool bFound = false; + if (advanceToItemStartingWith != "") { + for (int i = selectedItemIndex + 1; i < (int) items.size(); ++i) { + string item = items[i]; + if ((int) translated_items.size() > i) item = translated_items[i]; + //printf("Trying to match [%s] with item [%s]\n",advanceToItemStartingWith.c_str(),item.c_str()); + if (StartsWith(toLower(item), toLower(advanceToItemStartingWith)) == true) { + bFound = true; + selectedItemIndex = i; + break; + } + } + if (bFound == false) { + for (int i = 0; i <= selectedItemIndex; ++i) { + string item = items[i]; + if ((int) translated_items.size() > i) item = translated_items[i]; + //printf("Trying to match [%s] with item [%s]\n",advanceToItemStartingWith.c_str(),item.c_str()); + if (StartsWith(toLower(item), toLower(advanceToItemStartingWith)) == true) { + bFound = true; + selectedItemIndex = i; + break; + } + } } } + if (bFound == false) { + selectedItemIndex++; + } + if (selectedItemIndex >= (int) items.size()) { + selectedItemIndex = 0; + } + } + setText(getSelectedItem()); + + return b1 || b2; + } + return false; + } + + // ===================================================== + // class GraphicMessageBox + // ===================================================== + + const int GraphicMessageBox::defH = 280; + const int GraphicMessageBox::defW = 350; + + GraphicMessageBox::GraphicMessageBox(const std::string &containerName, const std::string &objName) : + GraphicComponent(containerName, objName) { + header = ""; + autoWordWrap = true; + } + + GraphicMessageBox::~GraphicMessageBox() { + removeButtons(); + } + + void GraphicMessageBox::removeButtons() { + while (!buttons.empty()) { + delete buttons.back(); + buttons.pop_back(); + } + } + + void GraphicMessageBox::init(const string &button1Str, const string &button2Str, int newWidth, int newHeight) { + init(button1Str, newWidth, newHeight); + addButton(button2Str); + } + + void GraphicMessageBox::init(const string &button1Str, int newWidth, int newHeight) { + init(newWidth, newHeight); + removeButtons(); + addButton(button1Str); + } + + void GraphicMessageBox::init(int newWidth, int newHeight) { + setFont(CoreData::getInstance().getMenuFontNormal()); + setFont3D(CoreData::getInstance().getMenuFontNormal3D()); + + h = (newHeight >= 0 ? newHeight : defH); + w = (newWidth >= 0 ? newWidth : defW); + + const Metrics &metrics = Metrics::getInstance(); + + x = (metrics.getVirtualW() - w) / 2; + y = (metrics.getVirtualH() - h) / 2; + } + + void GraphicMessageBox::addButton(const string &buttonStr, int width, int height) { + GraphicButton *newButton = new GraphicButton(containerName, instanceName + "_Button_" + buttonStr); + newButton->init(0, 0); + newButton->setText(buttonStr); + if (width != -1) { + newButton->setW(width); + } + if (height != -1) { + newButton->setH(height); + } + buttons.push_back(newButton); + alignButtons(); + } + + void GraphicMessageBox::alignButtons() { + int currXPos = 0; + int totalbuttonListLength = 0; + int buttonOffset = 5; + for (int i = 0; i < getButtonCount(); i++) { + GraphicButton *button = getButton(i); + totalbuttonListLength += button->getW(); + } + totalbuttonListLength += (getButtonCount() - 1)*buttonOffset; + currXPos = x + w / 2 - totalbuttonListLength / 2; + for (int i = 0; i < getButtonCount(); i++) { + GraphicButton *button = getButton(i); + button->setY(y + 25); + button->setX(currXPos); + currXPos += button->getW() + buttonOffset; + } + } + + void GraphicMessageBox::setX(int x) { + this->x = x; + alignButtons(); + } + + void GraphicMessageBox::setY(int y) { + this->y = y; + alignButtons(); + } + + bool GraphicMessageBox::mouseMove(int x, int y) { + if (this->getVisible() == false) { + return false; + } + for (int i = 0; i < getButtonCount(); i++) { + if (getButton(i)->mouseMove(x, y)) { + return true; } } - if(bFound == false) { - selectedItemIndex++; + return false; + } + + bool GraphicMessageBox::mouseClick(int x, int y) { + if (this->getVisible() == false) { + return false; } - if(selectedItemIndex >= (int)items.size()) { - selectedItemIndex=0; - } - } - setText(getSelectedItem()); - return b1 || b2; - } - return false; -} - -// ===================================================== -// class GraphicMessageBox -// ===================================================== - -const int GraphicMessageBox::defH= 280; -const int GraphicMessageBox::defW= 350; - -GraphicMessageBox::GraphicMessageBox(const std::string &containerName, const std::string &objName) : - GraphicComponent(containerName, objName) { - header= ""; - autoWordWrap=true; -} - -GraphicMessageBox::~GraphicMessageBox(){ - removeButtons(); -} - -void GraphicMessageBox::removeButtons(){ - while(!buttons.empty()){ - delete buttons.back(); - buttons.pop_back(); - } -} - -void GraphicMessageBox::init(const string &button1Str, const string &button2Str, int newWidth, int newHeight){ - init(button1Str, newWidth, newHeight); - addButton(button2Str); -} - -void GraphicMessageBox::init(const string &button1Str, int newWidth, int newHeight){ - init(newWidth,newHeight); - removeButtons(); - addButton(button1Str); -} - -void GraphicMessageBox::init(int newWidth, int newHeight) { - setFont(CoreData::getInstance().getMenuFontNormal()); - setFont3D(CoreData::getInstance().getMenuFontNormal3D()); - - h= (newHeight >= 0 ? newHeight : defH); - w= (newWidth >= 0 ? newWidth : defW); - - const Metrics &metrics= Metrics::getInstance(); - - x= (metrics.getVirtualW() - w) / 2; - y= (metrics.getVirtualH() - h) / 2; -} - -void GraphicMessageBox::addButton(const string &buttonStr, int width, int height){ - GraphicButton *newButton= new GraphicButton(containerName, instanceName + "_Button_" + buttonStr); - newButton->init(0, 0); - newButton->setText(buttonStr); - if(width != -1){ - newButton->setW(width); - } - if(height != -1){ - newButton->setH(height); - } - buttons.push_back(newButton); - alignButtons(); -} - -void GraphicMessageBox::alignButtons(){ - int currXPos= 0; - int totalbuttonListLength=0; - int buttonOffset=5; - for(int i= 0; i < getButtonCount(); i++){ - GraphicButton *button= getButton(i); - totalbuttonListLength+=button->getW(); - } - totalbuttonListLength+=(getButtonCount()-1)*buttonOffset; - currXPos=x+w/2-totalbuttonListLength/2; - for(int i= 0; i < getButtonCount(); i++){ - GraphicButton *button= getButton(i); - button->setY(y + 25); - button->setX(currXPos); - currXPos+=button->getW()+buttonOffset; - } -} - -void GraphicMessageBox::setX(int x){ - this->x= x; - alignButtons(); -} - -void GraphicMessageBox::setY(int y){ - this->y= y; - alignButtons(); -} - -bool GraphicMessageBox::mouseMove(int x, int y){ - if(this->getVisible() == false){ - return false; - } - for(int i= 0; i < getButtonCount(); i++){ - if(getButton(i)->mouseMove(x, y)){ - return true; - } - } - return false; -} - -bool GraphicMessageBox::mouseClick(int x, int y){ - if(this->getVisible() == false){ - return false; - } - - for(int i= 0; i < getButtonCount(); i++){ - if(getButton(i)->mouseClick(x, y)){ - return true; - } - } - return false; -} - -bool GraphicMessageBox::mouseClick(int x, int y, int &clickedButton){ - if(this->getVisible() == false){ - return false; - } - - for(int i= 0; i < getButtonCount(); i++){ - if(getButton(i)->mouseClick(x, y)){ - clickedButton=i; - return true; - } - } - return false; -} - -// ===================================================== -// class GraphicLine -// ===================================================== - -const int GraphicLine::defH= 5; -const int GraphicLine::defW= 1000; - -GraphicLine::GraphicLine(const std::string &containerName, const std::string &objName) -: GraphicComponent(containerName, objName) { - horizontal = false; -} - -void GraphicLine::init(int x, int y, int w, int h){ - GraphicComponent::init(x, y, w, h); - horizontal=true; -} - -// ===================================================== -// class GraphicCheckBox -// ===================================================== - -const int GraphicCheckBox::defH= 22; -const int GraphicCheckBox::defW= 22; - -GraphicCheckBox::GraphicCheckBox(const std::string &containerName, const std::string &objName) -: GraphicComponent(containerName, objName) { - value = false; - lighted = false; -} - -void GraphicCheckBox::init(int x, int y, int w, int h){ - GraphicComponent::init(x, y, w, h); - value=true; - lighted= false; -} - -bool GraphicCheckBox::mouseMove(int x, int y){ - if(this->getVisible() == false) { - return false; - } - - bool b= GraphicComponent::mouseMove(x, y); - lighted= b; - return b; -} - -bool GraphicCheckBox::mouseClick(int x, int y){ - bool result=GraphicComponent::mouseClick( x, y); - if(result == true) { - if(value) { - value=false; - } - else { - value=true; - } - } - return result; -} - -// ===================================================== -// class GraphicScrollBar -// ===================================================== - -const int GraphicScrollBar::defThickness=20; -const int GraphicScrollBar::defLength= 200; - -GraphicScrollBar::GraphicScrollBar(const std::string &containerName, const std::string &objName) -: GraphicComponent(containerName, objName) { - lighted = false; - activated = false; - horizontal = false; - elementCount = 0; - visibleSize = 0; - visibleStart = 0; - - // position on component for renderer - visibleCompPosStart = 0; - visibleCompPosEnd = 0; -} - -void GraphicScrollBar::init(int x, int y, bool horizontal,int length, int thickness){ - GraphicComponent::init(x, y, horizontal?length:thickness,horizontal?thickness:length ); - this->horizontal=horizontal; - this->elementCount=1; - this->visibleSize=1; - this->visibleStart=0; - this->visibleCompPosStart=0; - this->visibleCompPosEnd=length; - activated = false; - lighted = false; -} - -bool GraphicScrollBar::mouseDown(int x, int y) { - if(getVisible() && getEnabled() && getEditable()) - { - if(activated && elementCount>0) - { - if( elementCount>visibleSize) { - int pos; - if(horizontal){ - pos=x-this->x; + for (int i = 0; i < getButtonCount(); i++) { + if (getButton(i)->mouseClick(x, y)) { + return true; } - else { - // invert the clicked point ( y is from bottom to top normally ) - pos=getLength()-(y-this->y); + } + return false; + } + + bool GraphicMessageBox::mouseClick(int x, int y, int &clickedButton) { + if (this->getVisible() == false) { + return false; + } + + for (int i = 0; i < getButtonCount(); i++) { + if (getButton(i)->mouseClick(x, y)) { + clickedButton = i; + return true; } - float partSize=(float)getLength()/(float)elementCount; - float visiblePartSize=partSize*(float)visibleSize; - float startPos=((float)pos)-visiblePartSize/2; - - visibleStart=startPos/partSize; - setVisibleStart(visibleStart); - } + return false; } - } - return false; -} -void GraphicScrollBar::mouseUp(int x, int y) { - activated = false; - lighted = false; -} + // ===================================================== + // class GraphicLine + // ===================================================== -void GraphicScrollBar::setVisibleStart(int vs){ - visibleStart=vs; + const int GraphicLine::defH = 5; + const int GraphicLine::defW = 1000; - if(visibleStart>elementCount-visibleSize) { - visibleStart=elementCount-visibleSize; - } - if(visibleStart<0) { - visibleStart=0; - } - float partSize = 0.f; - if(elementCount > 0) { - partSize = (float)getLength()/(float)elementCount; - } - visibleCompPosStart=visibleStart*partSize; - visibleCompPosEnd=visibleStart*partSize+visibleSize*partSize; - if(visibleCompPosEnd>getLength()) { - visibleCompPosEnd=getLength(); - } - if(!horizontal) { - // invert the display ( y is from bottom to top normally ) - visibleCompPosStart=getLength()-visibleCompPosStart; - visibleCompPosEnd=getLength()-visibleCompPosEnd; - } -} + GraphicLine::GraphicLine(const std::string &containerName, const std::string &objName) + : GraphicComponent(containerName, objName) { + horizontal = false; + } -void GraphicScrollBar::setElementCount(int elementCount){ - this->elementCount=elementCount; - setVisibleStart(getVisibleStart()); -} + void GraphicLine::init(int x, int y, int w, int h) { + GraphicComponent::init(x, y, w, h); + horizontal = true; + } -void GraphicScrollBar::setVisibleSize(int visibleSize){ - this->visibleSize=visibleSize; - setVisibleStart(getVisibleStart()); -} + // ===================================================== + // class GraphicCheckBox + // ===================================================== + const int GraphicCheckBox::defH = 22; + const int GraphicCheckBox::defW = 22; -bool GraphicScrollBar::mouseClick(int x, int y){ - bool result=GraphicComponent::mouseClick( x, y); - if(result) { - activated = true; - lighted = true; - mouseDown( x, y); - } - return result; -} + GraphicCheckBox::GraphicCheckBox(const std::string &containerName, const std::string &objName) + : GraphicComponent(containerName, objName) { + value = false; + lighted = false; + } + void GraphicCheckBox::init(int x, int y, int w, int h) { + GraphicComponent::init(x, y, w, h); + value = true; + lighted = false; + } -bool GraphicScrollBar::mouseMove(int x, int y){ - if(this->getVisible() == false) { - return false; - } - - bool inScrollBar = GraphicComponent::mouseMove(x, y); - if (activated) { - lighted = true; - } else { - lighted = inScrollBar; - } - return inScrollBar; -} - -int GraphicScrollBar::getLength() const { - return horizontal?getW():getH(); -} - -//int GraphicScrollBar::getThickness() const { -// return horizontal?getH():getW(); -//} - -void GraphicScrollBar::arrangeComponents(vector &gcs) { - if(getElementCount()!=0 ) { - for(int i = getVisibleStart(); i <= getVisibleEnd(); ++i) { - if(horizontal){ - gcs[i]->setX(getX()+getLength()-gcs[i]->getW()-gcs[i]->getW()*(i-getVisibleStart())); - } - else { - gcs[i]->setY(getY()+getLength()-gcs[i]->getH()-gcs[i]->getH()*(i-getVisibleStart())); - } - } - } -} -// =========================================================== -// class PopupMenu -// =========================================================== - -const int PopupMenu::defH= 240; -const int PopupMenu::defW= 350; - -PopupMenu::PopupMenu(const std::string &containerName, const std::string &objName) : - GraphicComponent(containerName, objName, false) { - registerGraphicComponentOnlyFontCallbacks(containerName,objName); - - h= defH; - w= defW; -} - -PopupMenu::~PopupMenu() { - -} - -void PopupMenu::init(string menuHeader,std::vector menuItems) { - header = menuHeader; - - setFont(CoreData::getInstance().getMenuFontNormal()); - setFont3D(CoreData::getInstance().getMenuFontNormal3D()); - - buttons.clear(); - - const Metrics &metrics= Metrics::getInstance(); - - x= (metrics.getVirtualW()-w)/2; - y= (metrics.getVirtualH()-h)/2; - - int textHeight = GraphicButton::defH; - int textHeightSpacing = 6; - - int maxButtonWidth = -1; - for(unsigned int i = 0; i < menuItems.size(); ++i) { - int currentButtonWidth = -1; - if(font3D != NULL && Shared::Graphics::Font::forceLegacyFonts == false) { - FontMetrics *fontMetrics= font3D->getMetrics(); - if(fontMetrics) { - currentButtonWidth = fontMetrics->getTextWidth(menuItems[i]); + bool GraphicCheckBox::mouseMove(int x, int y) { + if (this->getVisible() == false) { + return false; } + + bool b = GraphicComponent::mouseMove(x, y); + lighted = b; + return b; } - else if(font) { - FontMetrics *fontMetrics= font->getMetrics(); - if(fontMetrics) { - currentButtonWidth = fontMetrics->getTextWidth(menuItems[i]); + + bool GraphicCheckBox::mouseClick(int x, int y) { + bool result = GraphicComponent::mouseClick(x, y); + if (result == true) { + if (value) { + value = false; + } else { + value = true; + } + } + return result; + } + + // ===================================================== + // class GraphicScrollBar + // ===================================================== + + const int GraphicScrollBar::defThickness = 20; + const int GraphicScrollBar::defLength = 200; + + GraphicScrollBar::GraphicScrollBar(const std::string &containerName, const std::string &objName) + : GraphicComponent(containerName, objName) { + lighted = false; + activated = false; + horizontal = false; + elementCount = 0; + visibleSize = 0; + visibleStart = 0; + + // position on component for renderer + visibleCompPosStart = 0; + visibleCompPosEnd = 0; + } + + void GraphicScrollBar::init(int x, int y, bool horizontal, int length, int thickness) { + GraphicComponent::init(x, y, horizontal ? length : thickness, horizontal ? thickness : length); + this->horizontal = horizontal; + this->elementCount = 1; + this->visibleSize = 1; + this->visibleStart = 0; + this->visibleCompPosStart = 0; + this->visibleCompPosEnd = length; + activated = false; + lighted = false; + } + + bool GraphicScrollBar::mouseDown(int x, int y) { + if (getVisible() && getEnabled() && getEditable()) { + if (activated && elementCount > 0) { + if (elementCount > visibleSize) { + int pos; + if (horizontal) { + pos = x - this->x; + } else { + // invert the clicked point ( y is from bottom to top normally ) + pos = getLength() - (y - this->y); + } + float partSize = (float) getLength() / (float) elementCount; + float visiblePartSize = partSize * (float) visibleSize; + float startPos = ((float) pos) - visiblePartSize / 2; + + visibleStart = startPos / partSize; + setVisibleStart(visibleStart); + + } + } + } + return false; + } + + void GraphicScrollBar::mouseUp(int x, int y) { + activated = false; + lighted = false; + } + + void GraphicScrollBar::setVisibleStart(int vs) { + visibleStart = vs; + + if (visibleStart > elementCount - visibleSize) { + visibleStart = elementCount - visibleSize; + } + if (visibleStart < 0) { + visibleStart = 0; + } + float partSize = 0.f; + if (elementCount > 0) { + partSize = (float) getLength() / (float) elementCount; + } + visibleCompPosStart = visibleStart * partSize; + visibleCompPosEnd = visibleStart * partSize + visibleSize * partSize; + if (visibleCompPosEnd > getLength()) { + visibleCompPosEnd = getLength(); + } + if (!horizontal) { + // invert the display ( y is from bottom to top normally ) + visibleCompPosStart = getLength() - visibleCompPosStart; + visibleCompPosEnd = getLength() - visibleCompPosEnd; } } - if(maxButtonWidth < 0 || currentButtonWidth > maxButtonWidth) { - maxButtonWidth = currentButtonWidth + textHeightSpacing; + void GraphicScrollBar::setElementCount(int elementCount) { + this->elementCount = elementCount; + setVisibleStart(getVisibleStart()); } - } - int yStartOffset = y + h - (textHeight * 2); - - if(maxButtonWidth >= w) { - w = maxButtonWidth + textHeightSpacing; - x= (metrics.getVirtualW()-w)/2; - } - - int offsetH = (yStartOffset - y); - int maxH = (offsetH + (((int)menuItems.size() -1 ) * (textHeight + textHeightSpacing))); - if(maxH >= h) { - h = maxH; - y= (metrics.getVirtualH()-h)/2; - yStartOffset = y + h - (textHeight * 2); - } - - for(unsigned int i = 0; i < menuItems.size(); ++i) { - GraphicButton button(containerName, instanceName + "_Popup_Button_" + menuItems[i],false); - button.registerGraphicComponentOnlyFontCallbacks(containerName, instanceName + "_Popup_Button_" + menuItems[i]); - button.init(x+(w-maxButtonWidth)/2, yStartOffset - (i*(textHeight + textHeightSpacing))); - button.setText(menuItems[i]); - button.setW(maxButtonWidth); - - buttons.push_back(button); - } -} - -void PopupMenu::setX(int x) { - this->x= x; - - for(unsigned int i = 0; i < buttons.size(); ++i) { - GraphicButton &button = buttons[i]; - button.init(x+(w-GraphicButton::defW)/4, y+25 + (i*25)); - } -} - -void PopupMenu::setY(int y) { - this->y= y; - - for(unsigned int i = 0; i < buttons.size(); ++i) { - GraphicButton &button = buttons[i]; - button.init(x+(w-GraphicButton::defW)/4, y+25 + (i*25)); - } -} - -bool PopupMenu::mouseMove(int x, int y){ - if(this->getVisible() == false) { - return false; - } - - for(unsigned int i = 0; i < buttons.size(); ++i) { - GraphicButton &button = buttons[i]; - if(button.mouseMove(x, y)) { - return true; + void GraphicScrollBar::setVisibleSize(int visibleSize) { + this->visibleSize = visibleSize; + setVisibleStart(getVisibleStart()); } - } - return false; -} -bool PopupMenu::mouseClick(int x, int y) { - if(this->getVisible() == false) { - return false; - } - - for(unsigned int i = 0; i < buttons.size(); ++i) { - GraphicButton &button = buttons[i]; - if(button.mouseClick(x, y)) { - return true; + bool GraphicScrollBar::mouseClick(int x, int y) { + bool result = GraphicComponent::mouseClick(x, y); + if (result) { + activated = true; + lighted = true; + mouseDown(x, y); + } + return result; } - } - return false; -} -std::pair PopupMenu::mouseClickedMenuItem(int x, int y) { - std::pair result; - for(unsigned int i = 0; i < buttons.size(); ++i) { - GraphicButton &button = buttons[i]; - if(button.mouseClick(x, y)) { - result.first = i; - result.second = buttons[i].getText(); - break; + + bool GraphicScrollBar::mouseMove(int x, int y) { + if (this->getVisible() == false) { + return false; + } + + bool inScrollBar = GraphicComponent::mouseMove(x, y); + if (activated) { + lighted = true; + } else { + lighted = inScrollBar; + } + return inScrollBar; } + + int GraphicScrollBar::getLength() const { + return horizontal ? getW() : getH(); + } + + //int GraphicScrollBar::getThickness() const { + // return horizontal?getH():getW(); + //} + + void GraphicScrollBar::arrangeComponents(vector &gcs) { + if (getElementCount() != 0) { + for (int i = getVisibleStart(); i <= getVisibleEnd(); ++i) { + if (horizontal) { + gcs[i]->setX(getX() + getLength() - gcs[i]->getW() - gcs[i]->getW()*(i - getVisibleStart())); + } else { + gcs[i]->setY(getY() + getLength() - gcs[i]->getH() - gcs[i]->getH()*(i - getVisibleStart())); + } + } + } + } + // =========================================================== + // class PopupMenu + // =========================================================== + + const int PopupMenu::defH = 240; + const int PopupMenu::defW = 350; + + PopupMenu::PopupMenu(const std::string &containerName, const std::string &objName) : + GraphicComponent(containerName, objName, false) { + registerGraphicComponentOnlyFontCallbacks(containerName, objName); + + h = defH; + w = defW; + } + + PopupMenu::~PopupMenu() { + + } + + void PopupMenu::init(string menuHeader, std::vector menuItems) { + header = menuHeader; + + setFont(CoreData::getInstance().getMenuFontNormal()); + setFont3D(CoreData::getInstance().getMenuFontNormal3D()); + + buttons.clear(); + + const Metrics &metrics = Metrics::getInstance(); + + x = (metrics.getVirtualW() - w) / 2; + y = (metrics.getVirtualH() - h) / 2; + + int textHeight = GraphicButton::defH; + int textHeightSpacing = 6; + + int maxButtonWidth = -1; + for (unsigned int i = 0; i < menuItems.size(); ++i) { + int currentButtonWidth = -1; + if (font3D != NULL && Shared::Graphics::Font::forceLegacyFonts == false) { + FontMetrics *fontMetrics = font3D->getMetrics(); + if (fontMetrics) { + currentButtonWidth = fontMetrics->getTextWidth(menuItems[i]); + } + } else if (font) { + FontMetrics *fontMetrics = font->getMetrics(); + if (fontMetrics) { + currentButtonWidth = fontMetrics->getTextWidth(menuItems[i]); + } + } + + if (maxButtonWidth < 0 || currentButtonWidth > maxButtonWidth) { + maxButtonWidth = currentButtonWidth + textHeightSpacing; + } + } + + int yStartOffset = y + h - (textHeight * 2); + + if (maxButtonWidth >= w) { + w = maxButtonWidth + textHeightSpacing; + x = (metrics.getVirtualW() - w) / 2; + } + + int offsetH = (yStartOffset - y); + int maxH = (offsetH + (((int) menuItems.size() - 1) * (textHeight + textHeightSpacing))); + if (maxH >= h) { + h = maxH; + y = (metrics.getVirtualH() - h) / 2; + yStartOffset = y + h - (textHeight * 2); + } + + for (unsigned int i = 0; i < menuItems.size(); ++i) { + GraphicButton button(containerName, instanceName + "_Popup_Button_" + menuItems[i], false); + button.registerGraphicComponentOnlyFontCallbacks(containerName, instanceName + "_Popup_Button_" + menuItems[i]); + button.init(x + (w - maxButtonWidth) / 2, yStartOffset - (i*(textHeight + textHeightSpacing))); + button.setText(menuItems[i]); + button.setW(maxButtonWidth); + + buttons.push_back(button); + } + } + + void PopupMenu::setX(int x) { + this->x = x; + + for (unsigned int i = 0; i < buttons.size(); ++i) { + GraphicButton &button = buttons[i]; + button.init(x + (w - GraphicButton::defW) / 4, y + 25 + (i * 25)); + } + } + + void PopupMenu::setY(int y) { + this->y = y; + + for (unsigned int i = 0; i < buttons.size(); ++i) { + GraphicButton &button = buttons[i]; + button.init(x + (w - GraphicButton::defW) / 4, y + 25 + (i * 25)); + } + } + + bool PopupMenu::mouseMove(int x, int y) { + if (this->getVisible() == false) { + return false; + } + + for (unsigned int i = 0; i < buttons.size(); ++i) { + GraphicButton &button = buttons[i]; + if (button.mouseMove(x, y)) { + return true; + } + } + + return false; + } + + bool PopupMenu::mouseClick(int x, int y) { + if (this->getVisible() == false) { + return false; + } + + for (unsigned int i = 0; i < buttons.size(); ++i) { + GraphicButton &button = buttons[i]; + if (button.mouseClick(x, y)) { + return true; + } + } + return false; + } + + std::pair PopupMenu::mouseClickedMenuItem(int x, int y) { + std::pair result; + for (unsigned int i = 0; i < buttons.size(); ++i) { + GraphicButton &button = buttons[i]; + if (button.mouseClick(x, y)) { + result.first = i; + result.second = buttons[i].getText(); + break; + } + } + + return result; + } + } - - return result; -} - -}}//end namespace +}//end namespace diff --git a/source/glest_game/facilities/components.h b/source/glest_game/facilities/components.h index 937de0d7f..7fa5a8ac1 100644 --- a/source/glest_game/facilities/components.h +++ b/source/glest_game/facilities/components.h @@ -13,8 +13,8 @@ #define _GLEST_GAME_GRAPHCOMPONENT_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -34,435 +34,631 @@ using Shared::Graphics::Font3D; using namespace Shared::Graphics; using Shared::Graphics::Vec3f; -namespace Glest{ namespace Game{ - -class GraphicComponent; - -// =========================================================== -// class GraphicComponent -// -// OpenGL renderer GUI components -// =========================================================== - -class GraphicComponent : public FontChangedCallbackInterface { -public: - static const float animSpeed; - static const float fadeSpeed; - - static std::map > registeredGraphicComponentList; - -protected: - int x, y, w, h; - string text; - string textNativeTranslation; - Font2D *font; - Font3D *font3D; - string font2DUniqueId; - string font3DUniqueId; - bool enabled; - bool editable; - bool visible; - - static float anim; - static float fade; - static Vec3f customTextColor; - - string containerName; - string instanceName; - string fontCallbackName; - - string getNewUUD(); - virtual void FontChangedCallback(std::string fontUniqueId, Font *font); - -public: - GraphicComponent(const std::string &containerName="", const std::string &objName="", bool registerControl=true); - virtual ~GraphicComponent(); - - static void setCustomTextColor(Vec3f value) { customTextColor = value; } - static Vec3f getCustomTextColor() { return customTextColor; } - - static void clearRegisteredComponents(std::string containerName=""); - static void clearRegisterGraphicComponent(std::string containerName, std::string objName); - static void clearRegisterGraphicComponent(std::string containerName, std::vector objNameList); - virtual void registerGraphicComponent(std::string containerName, std::string objName); - virtual void registerGraphicComponentOnlyFontCallbacks(std::string containerName, std::string objName); - static GraphicComponent * findRegisteredComponent(std::string containerName, std::string objName); - static void applyAllCustomProperties(std::string containerName); - virtual void applyCustomProperties(std::string containerName); - - static bool saveAllCustomProperties(std::string containerName); - virtual bool saveCustomProperties(std::string containerName); - - void init(int x, int y, int w, int h); - - string getContainerName() const { return containerName; } - string getInstanceName() const { return instanceName; } - string getFontCallbackName() const { return fontCallbackName; } - void setInstanceName(string value) { instanceName = value; } - - virtual int getX() const {return x;} - virtual int getY() const {return y;} - virtual int getW() const {return w;} - virtual int getH() const {return h;} - virtual const string &getText() const {return text;} - virtual const string &getTextNativeTranslation() { return this->textNativeTranslation;} - virtual Font2D *getFont() {return font;} - virtual Font3D *getFont3D() {return font3D;} - virtual bool getEnabled() const {return enabled;} - virtual bool getEditable() const {return editable;} - virtual bool getVisible() const {return visible;} - - virtual void setX(int x) {this->x= x;} - virtual void setY(int y) {this->y= y;} - virtual void setW(int w) {this->w= w;} - virtual void setH(int h) {this->h= h;} - virtual void setText(const string &text) {this->text= text;} - virtual void setTextNativeTranslation(const string &text) {this->textNativeTranslation= text;} - virtual void setFont(Font2D *font); - virtual void setFont3D(Font3D *font); - virtual void setEnabled(bool enabled) {this->enabled= enabled;} - virtual void setEditable(bool editable) {this->editable= editable;} - virtual void setVisible(bool value) {this->visible = value;} - - virtual void reloadFonts(); - static void reloadFontsForRegisterGraphicComponents(std::string containerName); - - virtual bool mouseMove(int x, int y); - bool mouseClick(int x, int y); - - static void update(); - static void resetFade(); - static float getAnim() {return anim;} - static float getFade() {return fade;} -}; - -// =========================================================== -// class GraphicLabel -// =========================================================== - -class GraphicLabel: public GraphicComponent { -public: - static const int defH; - static const int defW; - -private: - bool centered; - Vec3f textColor; - bool wordWrap; - - int centeredW; - int centeredH; - - bool editModeEnabled; - int maxEditWidth; - int maxEditRenderWidth; - bool renderBackground; - Vec4f backgroundColor; - - vector textCharLength; - bool isPassword; - Texture2D *texture; - -public: - GraphicLabel(const std::string &containerName="", const std::string &objName="", bool registerControl=true); - void init(int x, int y, int w=defW, int h=defH, bool centered= false, Vec3f textColor=GraphicComponent::customTextColor, bool wordWrap=false); - - virtual bool mouseMove(int x, int y); - - vector getTextCharLengthList() const { return textCharLength; } - void setTextCharLengthList(vector value) { textCharLength = value; } - void clearTextCharLengthList() { textCharLength.clear(); } - void addTextCharLengthToList(int length) { textCharLength.push_back(length); } - void deleteTextCharLengthFromList() { textCharLength.pop_back(); } - - bool getIsPassword() const { return isPassword; } - void setIsPassword(bool value) { isPassword = value; } - - bool getCentered() const {return centered;} - void setCentered(bool centered) {this->centered= centered;} - - bool getCenteredW() const; - //void setCenteredW(bool centered); - - bool getCenteredH() const; - //void setCenteredH(bool centered); - - Vec3f getTextColor() const {return textColor;} - void setTextColor(Vec3f color) {this->textColor= color;} - - bool getWordWrap() const { return wordWrap; } - void setWordWrap(bool value) { wordWrap = value; } - - void setEditModeEnabled(bool value) { editModeEnabled = value; } - bool getEditModeEnabled() const { return editModeEnabled; } - - void setMaxEditWidth(int value) { maxEditWidth = value; } - int getMaxEditWidth() const { return maxEditWidth; } - - void setRenderBackground(bool value) { renderBackground = value; } - bool getRenderBackground() const { return renderBackground; } - Vec4f getBackgroundColor() const {return backgroundColor;} - void setBackgroundColor(Vec4f color) {this->backgroundColor= color;} - - void setMaxEditRenderWidth(int value) { maxEditRenderWidth = value; } - int getMaxEditRenderWidth() const { return maxEditRenderWidth; } - - void setTexture(Texture2D *value) { texture = value; } - Texture2D *getTexture() const { return texture; } -}; - -// =========================================================== -// class GraphicButton -// =========================================================== - -class GraphicButton: public GraphicComponent { -public: - static const int defH; - static const int defW; - -private: - bool lighted; - bool alwaysLighted; - - bool useCustomTexture; - Texture *customTexture; - -public: - GraphicButton(const std::string &containerName="", const std::string &objName="", bool registerControl=true); - void init(int x, int y, int w=defW, int h=defH); - - bool getUseCustomTexture() const { return useCustomTexture; } - Texture *getCustomTexture() const { return customTexture; } - - void setUseCustomTexture(bool value) { useCustomTexture=value; } - void setCustomTexture(Texture *value) { customTexture=value; } - - bool getLighted() const {return lighted||alwaysLighted;} - void setLighted(bool lighted) {this->lighted= lighted;} - bool getAlwaysLighted() const {return alwaysLighted;} - void setAlwaysLighted(bool value) {this->alwaysLighted= value;} - virtual bool mouseMove(int x, int y); -}; - -// =========================================================== -// class GraphicListBox -// =========================================================== - -class GraphicListBox: public GraphicComponent { -public: - static const int defH; - static const int defW; - -private: - GraphicButton graphButton1, graphButton2; - vector items; - vector translated_items; - int selectedItemIndex; - bool lighted; - Vec3f textColor; - bool leftControlled; - -public: - GraphicListBox(const std::string &containerName="", const std::string &objName=""); - void init(int x, int y, int w=defW, int h=defH, Vec3f textColor=GraphicComponent::customTextColor); - - int getItemCount() const {return (int)items.size();} - string getItem(int index) const {return items[index];} - int getSelectedItemIndex() const {return selectedItemIndex;} - string getSelectedItem() const {return items[selectedItemIndex];} - GraphicButton *getButton1() {return &graphButton1;} - GraphicButton *getButton2() {return &graphButton2;} - bool getLighted() const {return lighted;} - void setLighted(bool lighted) {this->lighted= lighted;} - bool getLeftControlled() const {return leftControlled;} - void setLeftControlled(bool leftControlled); - Vec3f getTextColor() const {return textColor;} - void setTextColor(Vec3f color) {this->textColor= color;} - - void pushBackItem(string item, string translated_item=""); - void setItems(const vector &items, const vector translated_items=vector()); - void setSelectedItemIndex(int index, bool errorOnMissing=true); - void setSelectedItem(string item, bool errorOnMissing=true); - void setEditable(bool editable); - - bool hasItem(string item) const; - - virtual void setX(int x); - virtual void setY(int y); - - virtual bool mouseMove(int x, int y); - virtual bool mouseClick(int x, int y, string advanceToItemStartingWith=""); - - virtual const string &getTextNativeTranslation(); -}; - -// =========================================================== -// class GraphicMessageBox -// =========================================================== -typedef vector GraphicButtons; -class GraphicMessageBox: public GraphicComponent { -public: - static const int defH; - static const int defW; - -private: - GraphicButtons buttons; - string header; - bool autoWordWrap; - -private: - void alignButtons(); -public: - GraphicMessageBox(const std::string &containerName="", const std::string &objName=""); - virtual ~GraphicMessageBox(); - void init(const string &button1Str, const string &button2Str, int newWidth=-1,int newHeight=-1); - void init(const string &button1Str, int newWidth=-1,int newHeight=-1); - void init(int newWidth=-1,int newHeight=-1); - void removeButtons(); - void addButton(const string &buttonStr, int width=-1,int height=-1); - - bool getAutoWordWrap() const { return autoWordWrap; } - void setAutoWordWrap(bool value) { autoWordWrap = value; } - - int getButtonCount() const {return (int)buttons.size();} - GraphicButton *getButton(int index) {return buttons[index];} - string getHeader() const {return header;} - - virtual void setX(int x); - virtual void setY(int y); - - void setHeader(string header) {this->header= header;} - - virtual bool mouseMove(int x, int y); - virtual bool mouseClick(int x, int y); - bool mouseClick(int x, int y, int &clickedButton); -}; - -// =========================================================== -// class GraphicLine -// =========================================================== - -class GraphicLine: public GraphicComponent { -public: - static const int defH; - static const int defW; - -private: - bool horizontal; - -public: - GraphicLine(const std::string &containerName="", const std::string &objName=""); - void init(int x, int y, int w=defW, int h=defH); - bool getHorizontal() const {return horizontal;} - void setHorizontal(bool horizontal) {this->horizontal= horizontal;} -}; - -// =========================================================== -// class GraphicCheckBox -// =========================================================== - -class GraphicCheckBox: public GraphicComponent { -public: - static const int defH; - static const int defW; - -private: - bool value; - bool lighted; - -public: - GraphicCheckBox(const std::string &containerName="", const std::string &objName=""); - void init(int x, int y, int w=defW, int h=defH); - bool getValue() const {return value;} - void setValue(bool value) {this->value= value;} - bool getLighted() const {return lighted;} - void setLighted(bool lighted) {this->lighted= lighted;} - virtual bool mouseMove(int x, int y); - virtual bool mouseClick(int x, int y); -}; - -// =========================================================== -// class GraphicScrollBar -// =========================================================== - -class GraphicScrollBar: public GraphicComponent { -public: - static const int defLength; - static const int defThickness; - -private: - bool activated; - bool lighted; - bool horizontal; - int elementCount; - int visibleSize; - int visibleStart; - - // position on component for renderer - int visibleCompPosStart; - int visibleCompPosEnd; - -public: - GraphicScrollBar(const std::string &containerName="", const std::string &objName=""); - void init(int x, int y, bool horizontal,int length=defLength, int thickness=defThickness); - virtual bool mouseDown(int x, int y); - virtual bool mouseMove(int x, int y); - virtual void mouseUp(int x, int y); - virtual bool mouseClick(int x, int y); - - - bool getHorizontal() const {return horizontal;} - int getLength() const; - void setLength(int length) {horizontal?setW(length):setH(length);} - //int getThickness() const; - - - bool getLighted() const {return lighted;} - void setLighted(bool lighted) {this->lighted= lighted;} - - int getElementCount() const {return elementCount;} - void setElementCount(int elementCount); - int getVisibleSize() const {return visibleSize;} - void setVisibleSize(int visibleSize); - int getVisibleStart() const {return visibleStart;} - int getVisibleEnd() const {return visibleStart+visibleSize>elementCount-1?elementCount-1: visibleStart+visibleSize-1;} - void setVisibleStart(int visibleStart); - - int getVisibleCompPosStart() const {return visibleCompPosStart;} - int getVisibleCompPosEnd() const {return visibleCompPosEnd;} - void arrangeComponents(vector &gcs); -}; - -// =========================================================== -// class PopupMenu -// =========================================================== - -class PopupMenu: public GraphicComponent { -public: - static const int defH; - static const int defW; - -private: - std::vector buttons; - string header; - -public: - PopupMenu(const std::string &containerName="", const std::string &objName=""); - virtual ~PopupMenu(); - void init(string menuHeader, std::vector menuItems); - - std::vector & getMenuItems() {return buttons;} - string getHeader() const {return header;} - - virtual void setX(int x); - virtual void setY(int y); - - void setHeader(string header) {this->header= header;} - - virtual bool mouseMove(int x, int y); - virtual bool mouseClick(int x, int y); - std::pair mouseClickedMenuItem(int x, int y); -}; - -}}//end namespace +namespace Glest { + namespace Game { + + class GraphicComponent; + + // =========================================================== + // class GraphicComponent + // + // OpenGL renderer GUI components + // =========================================================== + + class GraphicComponent : public FontChangedCallbackInterface { + public: + static const float animSpeed; + static const float fadeSpeed; + + static std::map > registeredGraphicComponentList; + + protected: + int x, y, w, h; + string text; + string textNativeTranslation; + Font2D *font; + Font3D *font3D; + string font2DUniqueId; + string font3DUniqueId; + bool enabled; + bool editable; + bool visible; + + static float anim; + static float fade; + static Vec3f customTextColor; + + string containerName; + string instanceName; + string fontCallbackName; + + string getNewUUD(); + virtual void FontChangedCallback(std::string fontUniqueId, Font *font); + + public: + GraphicComponent(const std::string &containerName = "", const std::string &objName = "", bool registerControl = true); + virtual ~GraphicComponent(); + + static void setCustomTextColor(Vec3f value) { + customTextColor = value; + } + static Vec3f getCustomTextColor() { + return customTextColor; + } + + static void clearRegisteredComponents(std::string containerName = ""); + static void clearRegisterGraphicComponent(std::string containerName, std::string objName); + static void clearRegisterGraphicComponent(std::string containerName, std::vector objNameList); + virtual void registerGraphicComponent(std::string containerName, std::string objName); + virtual void registerGraphicComponentOnlyFontCallbacks(std::string containerName, std::string objName); + static GraphicComponent * findRegisteredComponent(std::string containerName, std::string objName); + static void applyAllCustomProperties(std::string containerName); + virtual void applyCustomProperties(std::string containerName); + + static bool saveAllCustomProperties(std::string containerName); + virtual bool saveCustomProperties(std::string containerName); + + void init(int x, int y, int w, int h); + + string getContainerName() const { + return containerName; + } + string getInstanceName() const { + return instanceName; + } + string getFontCallbackName() const { + return fontCallbackName; + } + void setInstanceName(string value) { + instanceName = value; + } + + virtual int getX() const { + return x; + } + virtual int getY() const { + return y; + } + virtual int getW() const { + return w; + } + virtual int getH() const { + return h; + } + virtual const string &getText() const { + return text; + } + virtual const string &getTextNativeTranslation() { + return this->textNativeTranslation; + } + virtual Font2D *getFont() { + return font; + } + virtual Font3D *getFont3D() { + return font3D; + } + virtual bool getEnabled() const { + return enabled; + } + virtual bool getEditable() const { + return editable; + } + virtual bool getVisible() const { + return visible; + } + + virtual void setX(int x) { + this->x = x; + } + virtual void setY(int y) { + this->y = y; + } + virtual void setW(int w) { + this->w = w; + } + virtual void setH(int h) { + this->h = h; + } + virtual void setText(const string &text) { + this->text = text; + } + virtual void setTextNativeTranslation(const string &text) { + this->textNativeTranslation = text; + } + virtual void setFont(Font2D *font); + virtual void setFont3D(Font3D *font); + virtual void setEnabled(bool enabled) { + this->enabled = enabled; + } + virtual void setEditable(bool editable) { + this->editable = editable; + } + virtual void setVisible(bool value) { + this->visible = value; + } + + virtual void reloadFonts(); + static void reloadFontsForRegisterGraphicComponents(std::string containerName); + + virtual bool mouseMove(int x, int y); + bool mouseClick(int x, int y); + + static void update(); + static void resetFade(); + static float getAnim() { + return anim; + } + static float getFade() { + return fade; + } + }; + + // =========================================================== + // class GraphicLabel + // =========================================================== + + class GraphicLabel : public GraphicComponent { + public: + static const int defH; + static const int defW; + + private: + bool centered; + Vec3f textColor; + bool wordWrap; + + int centeredW; + int centeredH; + + bool editModeEnabled; + int maxEditWidth; + int maxEditRenderWidth; + bool renderBackground; + Vec4f backgroundColor; + + vector textCharLength; + bool isPassword; + Texture2D *texture; + + public: + GraphicLabel(const std::string &containerName = "", const std::string &objName = "", bool registerControl = true); + void init(int x, int y, int w = defW, int h = defH, bool centered = false, Vec3f textColor = GraphicComponent::customTextColor, bool wordWrap = false); + + virtual bool mouseMove(int x, int y); + + vector getTextCharLengthList() const { + return textCharLength; + } + void setTextCharLengthList(vector value) { + textCharLength = value; + } + void clearTextCharLengthList() { + textCharLength.clear(); + } + void addTextCharLengthToList(int length) { + textCharLength.push_back(length); + } + void deleteTextCharLengthFromList() { + textCharLength.pop_back(); + } + + bool getIsPassword() const { + return isPassword; + } + void setIsPassword(bool value) { + isPassword = value; + } + + bool getCentered() const { + return centered; + } + void setCentered(bool centered) { + this->centered = centered; + } + + bool getCenteredW() const; + //void setCenteredW(bool centered); + + bool getCenteredH() const; + //void setCenteredH(bool centered); + + Vec3f getTextColor() const { + return textColor; + } + void setTextColor(Vec3f color) { + this->textColor = color; + } + + bool getWordWrap() const { + return wordWrap; + } + void setWordWrap(bool value) { + wordWrap = value; + } + + void setEditModeEnabled(bool value) { + editModeEnabled = value; + } + bool getEditModeEnabled() const { + return editModeEnabled; + } + + void setMaxEditWidth(int value) { + maxEditWidth = value; + } + int getMaxEditWidth() const { + return maxEditWidth; + } + + void setRenderBackground(bool value) { + renderBackground = value; + } + bool getRenderBackground() const { + return renderBackground; + } + Vec4f getBackgroundColor() const { + return backgroundColor; + } + void setBackgroundColor(Vec4f color) { + this->backgroundColor = color; + } + + void setMaxEditRenderWidth(int value) { + maxEditRenderWidth = value; + } + int getMaxEditRenderWidth() const { + return maxEditRenderWidth; + } + + void setTexture(Texture2D *value) { + texture = value; + } + Texture2D *getTexture() const { + return texture; + } + }; + + // =========================================================== + // class GraphicButton + // =========================================================== + + class GraphicButton : public GraphicComponent { + public: + static const int defH; + static const int defW; + + private: + bool lighted; + bool alwaysLighted; + + bool useCustomTexture; + Texture *customTexture; + + public: + GraphicButton(const std::string &containerName = "", const std::string &objName = "", bool registerControl = true); + void init(int x, int y, int w = defW, int h = defH); + + bool getUseCustomTexture() const { + return useCustomTexture; + } + Texture *getCustomTexture() const { + return customTexture; + } + + void setUseCustomTexture(bool value) { + useCustomTexture = value; + } + void setCustomTexture(Texture *value) { + customTexture = value; + } + + bool getLighted() const { + return lighted || alwaysLighted; + } + void setLighted(bool lighted) { + this->lighted = lighted; + } + bool getAlwaysLighted() const { + return alwaysLighted; + } + void setAlwaysLighted(bool value) { + this->alwaysLighted = value; + } + virtual bool mouseMove(int x, int y); + }; + + // =========================================================== + // class GraphicListBox + // =========================================================== + + class GraphicListBox : public GraphicComponent { + public: + static const int defH; + static const int defW; + + private: + GraphicButton graphButton1, graphButton2; + vector items; + vector translated_items; + int selectedItemIndex; + bool lighted; + Vec3f textColor; + bool leftControlled; + + public: + GraphicListBox(const std::string &containerName = "", const std::string &objName = ""); + void init(int x, int y, int w = defW, int h = defH, Vec3f textColor = GraphicComponent::customTextColor); + + int getItemCount() const { + return (int) items.size(); + } + string getItem(int index) const { + return items[index]; + } + int getSelectedItemIndex() const { + return selectedItemIndex; + } + string getSelectedItem() const { + return items[selectedItemIndex]; + } + GraphicButton *getButton1() { + return &graphButton1; + } + GraphicButton *getButton2() { + return &graphButton2; + } + bool getLighted() const { + return lighted; + } + void setLighted(bool lighted) { + this->lighted = lighted; + } + bool getLeftControlled() const { + return leftControlled; + } + void setLeftControlled(bool leftControlled); + Vec3f getTextColor() const { + return textColor; + } + void setTextColor(Vec3f color) { + this->textColor = color; + } + + void pushBackItem(string item, string translated_item = ""); + void setItems(const vector &items, const vector translated_items = vector()); + void setSelectedItemIndex(int index, bool errorOnMissing = true); + void setSelectedItem(string item, bool errorOnMissing = true); + void setEditable(bool editable); + + bool hasItem(string item) const; + + virtual void setX(int x); + virtual void setY(int y); + + virtual bool mouseMove(int x, int y); + virtual bool mouseClick(int x, int y, string advanceToItemStartingWith = ""); + + virtual const string &getTextNativeTranslation(); + }; + + // =========================================================== + // class GraphicMessageBox + // =========================================================== + typedef vector GraphicButtons; + class GraphicMessageBox : public GraphicComponent { + public: + static const int defH; + static const int defW; + + private: + GraphicButtons buttons; + string header; + bool autoWordWrap; + + private: + void alignButtons(); + public: + GraphicMessageBox(const std::string &containerName = "", const std::string &objName = ""); + virtual ~GraphicMessageBox(); + void init(const string &button1Str, const string &button2Str, int newWidth = -1, int newHeight = -1); + void init(const string &button1Str, int newWidth = -1, int newHeight = -1); + void init(int newWidth = -1, int newHeight = -1); + void removeButtons(); + void addButton(const string &buttonStr, int width = -1, int height = -1); + + bool getAutoWordWrap() const { + return autoWordWrap; + } + void setAutoWordWrap(bool value) { + autoWordWrap = value; + } + + int getButtonCount() const { + return (int) buttons.size(); + } + GraphicButton *getButton(int index) { + return buttons[index]; + } + string getHeader() const { + return header; + } + + virtual void setX(int x); + virtual void setY(int y); + + void setHeader(string header) { + this->header = header; + } + + virtual bool mouseMove(int x, int y); + virtual bool mouseClick(int x, int y); + bool mouseClick(int x, int y, int &clickedButton); + }; + + // =========================================================== + // class GraphicLine + // =========================================================== + + class GraphicLine : public GraphicComponent { + public: + static const int defH; + static const int defW; + + private: + bool horizontal; + + public: + GraphicLine(const std::string &containerName = "", const std::string &objName = ""); + void init(int x, int y, int w = defW, int h = defH); + bool getHorizontal() const { + return horizontal; + } + void setHorizontal(bool horizontal) { + this->horizontal = horizontal; + } + }; + + // =========================================================== + // class GraphicCheckBox + // =========================================================== + + class GraphicCheckBox : public GraphicComponent { + public: + static const int defH; + static const int defW; + + private: + bool value; + bool lighted; + + public: + GraphicCheckBox(const std::string &containerName = "", const std::string &objName = ""); + void init(int x, int y, int w = defW, int h = defH); + bool getValue() const { + return value; + } + void setValue(bool value) { + this->value = value; + } + bool getLighted() const { + return lighted; + } + void setLighted(bool lighted) { + this->lighted = lighted; + } + virtual bool mouseMove(int x, int y); + virtual bool mouseClick(int x, int y); + }; + + // =========================================================== + // class GraphicScrollBar + // =========================================================== + + class GraphicScrollBar : public GraphicComponent { + public: + static const int defLength; + static const int defThickness; + + private: + bool activated; + bool lighted; + bool horizontal; + int elementCount; + int visibleSize; + int visibleStart; + + // position on component for renderer + int visibleCompPosStart; + int visibleCompPosEnd; + + public: + GraphicScrollBar(const std::string &containerName = "", const std::string &objName = ""); + void init(int x, int y, bool horizontal, int length = defLength, int thickness = defThickness); + virtual bool mouseDown(int x, int y); + virtual bool mouseMove(int x, int y); + virtual void mouseUp(int x, int y); + virtual bool mouseClick(int x, int y); + + + bool getHorizontal() const { + return horizontal; + } + int getLength() const; + void setLength(int length) { + horizontal ? setW(length) : setH(length); + } + //int getThickness() const; + + + bool getLighted() const { + return lighted; + } + void setLighted(bool lighted) { + this->lighted = lighted; + } + + int getElementCount() const { + return elementCount; + } + void setElementCount(int elementCount); + int getVisibleSize() const { + return visibleSize; + } + void setVisibleSize(int visibleSize); + int getVisibleStart() const { + return visibleStart; + } + int getVisibleEnd() const { + return visibleStart + visibleSize > elementCount - 1 ? elementCount - 1 : visibleStart + visibleSize - 1; + } + void setVisibleStart(int visibleStart); + + int getVisibleCompPosStart() const { + return visibleCompPosStart; + } + int getVisibleCompPosEnd() const { + return visibleCompPosEnd; + } + void arrangeComponents(vector &gcs); + }; + + // =========================================================== + // class PopupMenu + // =========================================================== + + class PopupMenu : public GraphicComponent { + public: + static const int defH; + static const int defW; + + private: + std::vector buttons; + string header; + + public: + PopupMenu(const std::string &containerName = "", const std::string &objName = ""); + virtual ~PopupMenu(); + void init(string menuHeader, std::vector menuItems); + + std::vector & getMenuItems() { + return buttons; + } + string getHeader() const { + return header; + } + + virtual void setX(int x); + virtual void setY(int y); + + void setHeader(string header) { + this->header = header; + } + + virtual bool mouseMove(int x, int y); + virtual bool mouseClick(int x, int y); + std::pair mouseClickedMenuItem(int x, int y); + }; + + } +}//end namespace #endif diff --git a/source/glest_game/facilities/game_util.cpp b/source/glest_game/facilities/game_util.cpp index bb0252ec6..d7e4c1230 100644 --- a/source/glest_game/facilities/game_util.cpp +++ b/source/glest_game/facilities/game_util.cpp @@ -37,108 +37,110 @@ using namespace Shared::Util; using namespace Shared::Platform; namespace Glest { - namespace Game { + namespace Game { - const char *mailString = " https://github.com/ZetaGlest"; + const char *mailString = " https://github.com/ZetaGlest"; -// !! Use minor versions !! Only major and minor version control compatibility! -// typical version numbers look like this: v3.13-beta1.0 v3.12-dev v3.12.1 -// don't forget to update file: source/version.txt - const string glestVersionString = "v0.8.01-dev"; - const string lastCompatibleSaveGameVersionString = "v3.11.1"; + // !! Use minor versions !! Only major and minor version control compatibility! + // typical version numbers look like this: v3.13-beta1.0 v3.12-dev v3.12.1 + // don't forget to update file: source/version.txt + const string glestVersionString = "v0.8.01-dev"; + const string lastCompatibleSaveGameVersionString = "v3.11.1"; - string getCrashDumpFileName() {return "zetaglest" + glestVersionString + ".dmp";} - string getPlatformTypeNameString() { - static string platform; - if (platform == "") { + string getCrashDumpFileName() { + return "zetaglest" + glestVersionString + ".dmp"; + } + string getPlatformTypeNameString() { + static string platform; + if (platform == "") { #if defined(WIN32) # if defined(__MINGW32__) - platform = "W-Ming32"; + platform = "W-Ming32"; # else - platform = "Windows"; + platform = "Windows"; # endif #elif defined(__FreeBSD__) - platform = "FreeBSD"; + platform = "FreeBSD"; #elif defined(__NetBSD__) - platform = "NetBSD"; + platform = "NetBSD"; #elif defined(__OpenBSD__) - platform = "OpenBSD"; + platform = "OpenBSD"; #elif defined(__APPLE__) - platform = "MacOS"; + platform = "MacOS"; #elif defined(_AIX) - platform = "AIX"; + platform = "AIX"; #elif defined(__ANDROID__) - platform = "Android"; + platform = "Android"; #elif defined(__BEOS__) - platform = "BEOS"; + platform = "BEOS"; #elif defined(__gnu_linux__) - platform = "Linux"; + platform = "Linux"; #elif defined(__sun) - platform = "Solaris"; + platform = "Solaris"; #elif defined(__GNUC__) # if defined(__MINGW32__) - platform = "L-Ming32"; + platform = "L-Ming32"; # else - platform = "GNU"; + platform = "GNU"; # endif #else - platform = "???"; + platform = "???"; #endif - } - return platform; - } + } + return platform; + } - string getPlatformArchTypeNameString() { - static string platform; - if (platform == "") { + string getPlatformArchTypeNameString() { + static string platform; + if (platform == "") { #if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(_WIN64) - platform = "-X64"; + platform = "-X64"; #elif defined(_M_ALPHA) || defined(__alpha__) - platform = "-ALPHA"; + platform = "-ALPHA"; #elif defined(_M_IA64) || defined(__ia64__) - platform = "-IA64"; + platform = "-IA64"; #elif defined(_M_MRX000) || defined(__mips__) - platform = "-MIPS"; + platform = "-MIPS"; #elif defined(_M_PPC) || defined(__powerpc__) - platform = "-POWERPC"; + platform = "-POWERPC"; #elif defined(__sparc__) - platform = "-SPARC"; + platform = "-SPARC"; #elif defined(_M_ARM_FP) || defined(__arm__) || defined(_M_ARM) - platform = "-ARM"; + platform = "-ARM"; #endif - } - return platform; - } + } + return platform; + } - string getPlatformNameString() { - static string platform; - if (platform == "") { - platform = - getPlatformTypeNameString() + getPlatformArchTypeNameString(); - } - return platform; - } + string getPlatformNameString() { + static string platform; + if (platform == "") { + platform = + getPlatformTypeNameString() + getPlatformArchTypeNameString(); + } + return platform; + } - string getCompilerNameString() { - static string version = ""; - if (version == "") { + string getCompilerNameString() { + static string version = ""; + if (version == "") { #if defined(WIN32) && defined(_MSC_VER) - version = "VC++: " + intToStr(_MSC_VER); + version = "VC++: " + intToStr(_MSC_VER); #elif defined(__clang__) - version = - "Clang: " + intToStr(__clang_major__) + "." + - intToStr(__clang_minor__) + "." + - intToStr(__clang_patchlevel__); + version = + "Clang: " + intToStr(__clang_major__) + "." + + intToStr(__clang_minor__) + "." + + intToStr(__clang_patchlevel__); #elif defined(__GNUC__) # if defined(__GNUC__) @@ -151,304 +153,304 @@ namespace Glest { + __GNUC_MINOR__ * 100) # endif # endif - version = "GNUC"; + version = "GNUC"; # if defined(__MINGW32__) - version += "-MINGW"; + version += "-MINGW"; # endif - version += ": " + intToStr(__GNUC_VERSION__); + version += ": " + intToStr(__GNUC_VERSION__); #else - version = "???"; + version = "???"; #endif #if defined(DEBUG) || defined(_DEBUG) - version += " [DEBUG]"; + version += " [DEBUG]"; #endif #if defined(_M_X64) || defined(_M_IA64) || defined(_M_AMD64) || defined(__x86_64__) || defined(_WIN64) - version += " [64bit]"; + version += " [64bit]"; #endif - } - return version; - } + } + return version; + } - string getNetworkVersionString() { - static string version = ""; - if (version == "") { - version = - glestVersionString + "-" + getCompilerNameString() + "-" + - getCompileDateTime(); - } - return version; - } + string getNetworkVersionString() { + static string version = ""; + if (version == "") { + version = + glestVersionString + "-" + getCompilerNameString() + "-" + + getCompileDateTime(); + } + return version; + } - string getNetworkVersionGITString() { - static string version = ""; - if (version == "") { - version = - glestVersionString + getCompilerNameString(); - } - return version; - } + string getNetworkVersionGITString() { + static string version = ""; + if (version == "") { + version = + glestVersionString + getCompilerNameString(); + } + return version; + } - string getCompileDateTime() { - static string result = ""; -// if(result == "") { -// result = string(__DATE__) + " " + string(__TIME__); -// } - return result; - } + string getCompileDateTime() { + static string result = ""; + // if(result == "") { + // result = string(__DATE__) + " " + string(__TIME__); + // } + return result; + } - string getNetworkPlatformFreeVersionString() { - return glestVersionString; - } + string getNetworkPlatformFreeVersionString() { + return glestVersionString; + } - string getAboutString1(int i) { - //case 1: return "Built: " + string(__DATE__) + " " + GIT_Rev; - switch (i) { - case 0: - return "ZetaGlest " + glestVersionString + " (" + - "Shared Library " + sharedLibVersionString + ")"; - case 1: - return glestVersionString; - case 2: - return "Copyright 2001-2010 The Glest Team"; - case 3: - return "Copyright 2018 The ZetaGlest Team"; - } - return ""; - } + string getAboutString1(int i) { + //case 1: return "Built: " + string(__DATE__) + " " + GIT_Rev; + switch (i) { + case 0: + return "ZetaGlest " + glestVersionString + " (" + + "Shared Library " + sharedLibVersionString + ")"; + case 1: + return glestVersionString; + case 2: + return "Copyright 2001-2010 The Glest Team"; + case 3: + return "Copyright 2018 The ZetaGlest Team"; + } + return ""; + } - string getAboutString2(int i) { - switch (i) { - case 0: - return "Web: https://github.com/ZetaGlest"; - case 1: - return "Bug reports: " + string(mailString); - case 2: - return "IRC: irc://irc.freenode.net/zegaglest-dev"; - } - return ""; - } + string getAboutString2(int i) { + switch (i) { + case 0: + return "Web: https://github.com/ZetaGlest"; + case 1: + return "Bug reports: " + string(mailString); + case 2: + return "IRC: irc://irc.freenode.net/zegaglest-dev"; + } + return ""; + } - string getTeammateName(int i) { - switch (i) { - case 0: - return "Martiño Figueroa"; - //case 0: return "Martino Figueroa"; - case 1: - return "José Luis González"; - //case 1: return "Jose Luis Gonzalez"; - case 2: - return "Tucho Fernández"; - //case 2: return "Tucho Fernandez"; - case 3: - return "José Zanni"; - //case 3: return "Jose Zanni"; - case 4: - return "Félix Menéndez"; - //case 4: return "Felix Menendez"; - case 5: - return "Marcos Caruncho"; - case 6: - return "Matthias Braun"; - case 7: - return "Titus Tscharntke"; - case 8: - return "Mark Vejvoda"; - } - return ""; - } + string getTeammateName(int i) { + switch (i) { + case 0: + return "Martiño Figueroa"; + //case 0: return "Martino Figueroa"; + case 1: + return "José Luis González"; + //case 1: return "Jose Luis Gonzalez"; + case 2: + return "Tucho Fernández"; + //case 2: return "Tucho Fernandez"; + case 3: + return "José Zanni"; + //case 3: return "Jose Zanni"; + case 4: + return "Félix Menéndez"; + //case 4: return "Felix Menendez"; + case 5: + return "Marcos Caruncho"; + case 6: + return "Matthias Braun"; + case 7: + return "Titus Tscharntke"; + case 8: + return "Mark Vejvoda"; + } + return ""; + } - string getTeammateRole(int i) { - Lang & lang = Lang::getInstance(); + string getTeammateRole(int i) { + Lang & lang = Lang::getInstance(); - switch (i) { - case 0: - return lang.getString("Programming"); - case 1: - return lang.getString("SoundAndMusic"); - case 2: - return lang.getString("3dAnd2dArt"); - case 3: - return lang.getString("2dArtAndWeb"); - case 4: - return lang.getString("Animation"); - case 5: - return lang.getString("3dArt"); - case 6: - return lang.getString("LinuxPort"); - case 7: - return lang.getString("Megaglest3d2dProgramming"); - case 8: - return lang.getString("MegaglestProgramming"); - } - return ""; - } + switch (i) { + case 0: + return lang.getString("Programming"); + case 1: + return lang.getString("SoundAndMusic"); + case 2: + return lang.getString("3dAnd2dArt"); + case 3: + return lang.getString("2dArtAndWeb"); + case 4: + return lang.getString("Animation"); + case 5: + return lang.getString("3dArt"); + case 6: + return lang.getString("LinuxPort"); + case 7: + return lang.getString("Megaglest3d2dProgramming"); + case 8: + return lang.getString("MegaglestProgramming"); + } + return ""; + } - string formatString(string str) { - string outStr = str; + string formatString(string str) { + string outStr = str; - if (!outStr.empty()) { - outStr[0] = toupper(outStr[0]); - } + if (!outStr.empty()) { + outStr[0] = toupper(outStr[0]); + } - bool afterSeparator = false; - for (int i = 0; i < (int) str.size(); ++i) { - if (outStr[i] == '_') { - outStr[i] = ' '; - } else if (afterSeparator) { - outStr[i] = toupper(outStr[i]); - afterSeparator = false; - } - if (outStr[i] == '\n' || outStr[i] == '(' || outStr[i] == ' ') { - afterSeparator = true; - } - } - return outStr; - } + bool afterSeparator = false; + for (int i = 0; i < (int) str.size(); ++i) { + if (outStr[i] == '_') { + outStr[i] = ' '; + } else if (afterSeparator) { + outStr[i] = toupper(outStr[i]); + afterSeparator = false; + } + if (outStr[i] == '\n' || outStr[i] == '(' || outStr[i] == ' ') { + afterSeparator = true; + } + } + return outStr; + } - string getGameCustomCoreDataPath(string originalBasePath, - string uniqueFilePath) { - // original file path setup - if (originalBasePath != "") { - endPathWithSlash(originalBasePath); - } - // + string getGameCustomCoreDataPath(string originalBasePath, + string uniqueFilePath) { + // original file path setup + if (originalBasePath != "") { + endPathWithSlash(originalBasePath); + } + // - // mydata user data override - Config & config = Config::getInstance(); - string data_path = config.getString("UserData_Root", ""); - if (data_path != "") { - endPathWithSlash(data_path); - } - // + // mydata user data override + Config & config = Config::getInstance(); + string data_path = config.getString("UserData_Root", ""); + if (data_path != "") { + endPathWithSlash(data_path); + } + // - // if set this is the current active mod - string custom_mod_path = - config. - getCustomRuntimeProperty(Config::ACTIVE_MOD_PROPERTY_NAME); - if (custom_mod_path != "") { - endPathWithSlash(custom_mod_path); - } - // + // if set this is the current active mod + string custom_mod_path = + config. + getCustomRuntimeProperty(Config::ACTIVE_MOD_PROPERTY_NAME); + if (custom_mod_path != "") { + endPathWithSlash(custom_mod_path); + } + // - // decide which file to use - string result = ""; + // decide which file to use + string result = ""; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf("Looking for [%s] in\n#1: [%s]\n#2: [%s]\n#3: [%s]\n", - uniqueFilePath.c_str(), custom_mod_path.c_str(), - data_path.c_str(), originalBasePath.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Looking for [%s] in\n#1: [%s]\n#2: [%s]\n#3: [%s]\n", + uniqueFilePath.c_str(), custom_mod_path.c_str(), + data_path.c_str(), originalBasePath.c_str()); - if (custom_mod_path != "" && - (uniqueFilePath == "" - || fileExists(custom_mod_path + uniqueFilePath) == true)) { - result = custom_mod_path + uniqueFilePath; - } else if (data_path != "" && - (uniqueFilePath == "" - || fileExists(data_path + uniqueFilePath) == true)) { - result = data_path + uniqueFilePath; - } else { - result = originalBasePath + uniqueFilePath; - } + if (custom_mod_path != "" && + (uniqueFilePath == "" + || fileExists(custom_mod_path + uniqueFilePath) == true)) { + result = custom_mod_path + uniqueFilePath; + } else if (data_path != "" && + (uniqueFilePath == "" + || fileExists(data_path + uniqueFilePath) == true)) { + result = data_path + uniqueFilePath; + } else { + result = originalBasePath + uniqueFilePath; + } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf("result [%s]\n", result.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("result [%s]\n", result.c_str()); - return result; - } + return result; + } - string getGameReadWritePath(const string & lookupKey) { - string path = ""; + string getGameReadWritePath(const string & lookupKey) { + string path = ""; - if (lookupKey != "") { - std::map < string, string > &pathCache = - CacheManager::getCachedItem < std::map < string, - string > >(GameConstants::pathCacheLookupKey); - std::map < string, string >::const_iterator iterFind = - pathCache.find(lookupKey); - if (iterFind != pathCache.end()) { - path = iterFind->second; + if (lookupKey != "") { + std::map < string, string > &pathCache = + CacheManager::getCachedItem < std::map < string, + string > >(GameConstants::pathCacheLookupKey); + std::map < string, string >::const_iterator iterFind = + pathCache.find(lookupKey); + if (iterFind != pathCache.end()) { + path = iterFind->second; - if (path != "" && EndsWith(path, "/") == false - && EndsWith(path, "\\") == false) { - path += "/"; - } - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path to be used for [%s] files [%s]\n",__FILE__,__FUNCTION__,__LINE__,lookupKey.c_str(),path.c_str()); - } - } + if (path != "" && EndsWith(path, "/") == false + && EndsWith(path, "\\") == false) { + path += "/"; + } + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path to be used for [%s] files [%s]\n",__FILE__,__FUNCTION__,__LINE__,lookupKey.c_str(),path.c_str()); + } + } - if (path == "") { - path = safeCharPtrCopy(getenv("GLESTHOME"), 8095); - if (path != "" && EndsWith(path, "/") == false - && EndsWith(path, "\\") == false) { - path += "/"; - } - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path to be used for read/write files [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str()); - } + if (path == "") { + path = safeCharPtrCopy(getenv("GLESTHOME"), 8095); + if (path != "" && EndsWith(path, "/") == false + && EndsWith(path, "\\") == false) { + path += "/"; + } + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path to be used for read/write files [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str()); + } - return path; - } + return path; + } - void initSpecialStrings() { - getCrashDumpFileName(); - getPlatformNameString(); - getCompilerNameString(); - getNetworkVersionString(); - getNetworkVersionGITString(); - getNetworkPlatformFreeVersionString(); - getCompileDateTime(); - } + void initSpecialStrings() { + getCrashDumpFileName(); + getPlatformNameString(); + getCompilerNameString(); + getNetworkVersionString(); + getNetworkVersionGITString(); + getNetworkPlatformFreeVersionString(); + getCompileDateTime(); + } - bool upgradeFilesInTemp() { - // Get path to temp files - string tempFilePath = "temp/"; - if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != - "") { - tempFilePath = - getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + - tempFilePath; - } else { - Config & config = Config::getInstance(); - string userData = config.getString("UserData_Root", ""); - if (userData != "") { - endPathWithSlash(userData); - } - tempFilePath = userData + tempFilePath; - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf("Temp files path [%s]\n", tempFilePath.c_str()); + bool upgradeFilesInTemp() { + // Get path to temp files + string tempFilePath = "temp/"; + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != + "") { + tempFilePath = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + tempFilePath; + } else { + Config & config = Config::getInstance(); + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + tempFilePath = userData + tempFilePath; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Temp files path [%s]\n", tempFilePath.c_str()); - // Move all files into binary folder - bool anyFailures = false; - vector < string > fileList = - getFolderTreeContentsListRecursively(tempFilePath, "", false, - NULL); - for (unsigned int index = 0; index < fileList.size(); ++index) { - string fileName = fileList[index]; - string newFileName = - Properties::getApplicationPath() + - extractFileFromDirectoryPath(fileName); - bool result = renameFile(fileName, newFileName); - if (result == false) { - printf("FAILED Rename: [%s] to [%s] result = %d errno = %d\n", - fileName.c_str(), newFileName.c_str(), result, errno); + // Move all files into binary folder + bool anyFailures = false; + vector < string > fileList = + getFolderTreeContentsListRecursively(tempFilePath, "", false, + NULL); + for (unsigned int index = 0; index < fileList.size(); ++index) { + string fileName = fileList[index]; + string newFileName = + Properties::getApplicationPath() + + extractFileFromDirectoryPath(fileName); + bool result = renameFile(fileName, newFileName); + if (result == false) { + printf("FAILED Rename: [%s] to [%s] result = %d errno = %d\n", + fileName.c_str(), newFileName.c_str(), result, errno); - anyFailures = true; - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf("Rename: [%s] to [%s] result = %d\n", fileName.c_str(), - newFileName.c_str(), result); - } + anyFailures = true; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Rename: [%s] to [%s] result = %d\n", fileName.c_str(), + newFileName.c_str(), result); + } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf("Successfully updated!\n"); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Successfully updated!\n"); - return (fileList.size() > 0 && anyFailures == false); - } + return (fileList.size() > 0 && anyFailures == false); + } - } + } } //end namespace diff --git a/source/glest_game/facilities/game_util.h b/source/glest_game/facilities/game_util.h index 6bf25bebb..b46f64de8 100644 --- a/source/glest_game/facilities/game_util.h +++ b/source/glest_game/facilities/game_util.h @@ -37,35 +37,36 @@ using std::string; using Shared::Util::sharedLibVersionString; namespace Glest { - namespace Game { + namespace Game { - extern const char *mailString; - extern const string glestVersionString; - extern const string lastCompatibleSaveGameVersionString; - extern const string networkVersionString; + extern const char *mailString; + extern const string glestVersionString; + extern const string lastCompatibleSaveGameVersionString; + extern const string networkVersionString; - void initSpecialStrings(); - string getCrashDumpFileName(); - string getPlatformTypeNameString(); - string getPlatformArchTypeNameString(); - string getPlatformNameString(); - string getCompilerNameString(); - string getNetworkVersionString(); - string getNetworkVersionGITString(); - string getNetworkPlatformFreeVersionString(); - string getAboutString1(int i); - string getAboutString2(int i); - string getTeammateName(int i); - string getTeammateRole(int i); - string getCompileDateTime(); + void initSpecialStrings(); + string getCrashDumpFileName(); + string getPlatformTypeNameString(); + string getPlatformArchTypeNameString(); + string getPlatformNameString(); + string getCompilerNameString(); + string getNetworkVersionString(); + string getNetworkVersionGITString(); + string getNetworkPlatformFreeVersionString(); + string getAboutString1(int i); + string getAboutString2(int i); + string getTeammateName(int i); + string getTeammateRole(int i); + string getCompileDateTime(); - string formatString(string str); + string formatString(string str); - string getGameReadWritePath(const string & lookupKey = ""); - string getGameCustomCoreDataPath(string originalBasePath, - string uniqueFilePath); + string getGameReadWritePath(const string & lookupKey = ""); + string getGameCustomCoreDataPath(string originalBasePath, + string uniqueFilePath); - bool upgradeFilesInTemp(); + bool upgradeFilesInTemp(); -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/facilities/logger.cpp b/source/glest_game/facilities/logger.cpp index b93e15493..b92e02c59 100644 --- a/source/glest_game/facilities/logger.cpp +++ b/source/glest_game/facilities/logger.cpp @@ -28,327 +28,320 @@ using namespace std; using namespace Shared::Graphics; using namespace Shared::Util; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class Logger -// ===================================================== + // ===================================================== + // class Logger + // ===================================================== -const int Logger::logLineCount= 15; + const int Logger::logLineCount = 15; -// ===================== PUBLIC ======================== + // ===================== PUBLIC ======================== -Logger::Logger() : buttonCancel("Logger","buttonCancel"), buttonNextHint("Logger","buttonCancel") { - progress = 0; - string logs_path = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey); - if(logs_path != "") { - fileName= logs_path + "log.txt"; - } - else { - string userData = Config::getInstance().getString("UserData_Root",""); - if(userData != "") { - endPathWithSlash(userData); - } - fileName= userData + "log.txt"; - } - loadingTexture=NULL; - gameHintToShow=""; - showProgressBar = false; + Logger::Logger() : buttonCancel("Logger", "buttonCancel"), buttonNextHint("Logger", "buttonCancel") { + progress = 0; + string logs_path = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey); + if (logs_path != "") { + fileName = logs_path + "log.txt"; + } else { + string userData = Config::getInstance().getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + fileName = userData + "log.txt"; + } + loadingTexture = NULL; + gameHintToShow = ""; + showProgressBar = false; - displayColor=Vec4f(1.f,1.f,1.f,0.1f); + displayColor = Vec4f(1.f, 1.f, 1.f, 0.1f); - cancelSelected = false; - buttonCancel.setEnabled(false); + cancelSelected = false; + buttonCancel.setEnabled(false); - buttonNextHint.setEnabled(false); -} + buttonNextHint.setEnabled(false); + } -Logger::~Logger() { -} + Logger::~Logger() { + } -Logger & Logger::getInstance() { - static Logger logger; - return logger; -} + Logger & Logger::getInstance() { + static Logger logger; + return logger; + } -void Logger::add(const string str, bool renderScreen, const string statusText) { + void Logger::add(const string str, bool renderScreen, const string statusText) { #ifdef WIN32 - FILE *f= _wfopen(utf8_decode(fileName).c_str(), L"at+"); + FILE *f = _wfopen(utf8_decode(fileName).c_str(), L"at+"); #else - FILE *f = fopen(fileName.c_str(), "at+"); + FILE *f = fopen(fileName.c_str(), "at+"); #endif - if(f != NULL){ - fprintf(f, "%s\n", str.c_str()); - fclose(f); - } - this->current= str; - this->statusText = statusText; + if (f != NULL) { + fprintf(f, "%s\n", str.c_str()); + fclose(f); + } + this->current = str; + this->statusText = statusText; - if(renderScreen == true && GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - renderLoadingScreen(); - } -} + if (renderScreen == true && GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + renderLoadingScreen(); + } + } -void Logger::clear() { - string s = "Log file\n"; + void Logger::clear() { + string s = "Log file\n"; #ifdef WIN32 - FILE *f= _wfopen(utf8_decode(fileName).c_str(), L"wt+"); + FILE *f = _wfopen(utf8_decode(fileName).c_str(), L"wt+"); #else - FILE *f= fopen(fileName.c_str(), "wt+"); + FILE *f = fopen(fileName.c_str(), "wt+"); #endif - if(f == NULL){ - throw megaglest_runtime_error("Error opening log file" + fileName); - } + if (f == NULL) { + throw megaglest_runtime_error("Error opening log file" + fileName); + } - fprintf(f, "%s", s.c_str()); - fprintf(f, "\n"); + fprintf(f, "%s", s.c_str()); + fprintf(f, "\n"); - fclose(f); -} - -void Logger::loadLoadingScreen(string filepath) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(filepath == "") { - loadingTexture = NULL; - } - else { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] filepath = [%s]\n",__FILE__,__FUNCTION__,__LINE__,filepath.c_str()); - loadingTexture = Renderer::findTexture(filepath); - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - - Lang &lang = Lang::getInstance(); - buttonCancel.setText(lang.getString("Cancel")); -} - -void Logger::loadGameHints(string filePathEnglish,string filePathTranslation,bool clearList) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if((filePathEnglish == "") || (filePathTranslation == "")) { - return; - } - else { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] filePathEnglish = [%s]\n filePathTranslation = [%s]\n",__FILE__,__FUNCTION__,__LINE__,filePathEnglish.c_str(),filePathTranslation.c_str()); - gameHints.load(filePathEnglish,clearList); - gameHintsTranslation.load(filePathTranslation,clearList); - showNextHint(); - - Lang &lang = Lang::getInstance(); - buttonNextHint.setText(lang.getString("ShowNextHint","",true)); - buttonCancel.setText(lang.getString("Cancel")); - - GraphicComponent::applyAllCustomProperties("Loading"); - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } -} - -void Logger::showNextHint() { - string key=gameHints.getRandomKey(true); - string tmpString=gameHintsTranslation.getString(key,""); - if(tmpString!=""){ - gameHintToShow=tmpString; - } - else { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] key [%s] not found for [%s] hint translation\n",__FILE__,__FUNCTION__,__LINE__,key.c_str(),Lang::getInstance().getLanguage().c_str()); - tmpString=gameHints.getString(key,""); - if(tmpString!=""){ - gameHintToShow=tmpString; - } - else { - gameHintToShow="Problems to resolve hint key '"+key+"'"; - } - } - replaceAll(gameHintToShow, "\\n", "\n"); - - Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); - - vector > mergedKeySettings = configKeys.getMergedProperties(); - for(unsigned int j = 0; j < mergedKeySettings.size(); ++j) { - pair &property = mergedKeySettings[j]; - replaceAll(gameHintToShow, "#"+property.first+"#", property.second); - } - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void Logger::clearHints() { - gameHintToShow=""; - gameHints.clear(); - gameHintsTranslation.clear(); -} - -void Logger::handleMouseClick(int x, int y) { - if(buttonCancel.getEnabled() == true) { - if(buttonCancel.mouseClick(x, y)) { - cancelSelected = true; - } - } - if(buttonNextHint.getEnabled() == true && buttonNextHint.mouseClick(x,y) == true) { - showNextHint(); - //buttonNextHint.setLighted(false); - SoundRenderer &soundRenderer= SoundRenderer::getInstance(); - CoreData &coreData= CoreData::getInstance(); - soundRenderer.playFx(coreData.getClickSoundC()); - } -} - -// ==================== PRIVATE ==================== - -void Logger::renderLoadingScreen() { - - Renderer &renderer= Renderer::getInstance(); - CoreData &coreData= CoreData::getInstance(); - const Metrics &metrics= Metrics::getInstance(); - - //3d - //renderer.reset3d(); - //renderer.clearZBuffer(); - - renderer.reset2d(); - renderer.clearBuffers(); - if(loadingTexture == NULL) { - renderer.renderBackground(CoreData::getInstance().getBackgroundTexture()); - } - else { - renderer.renderBackground(loadingTexture); - } - - if(showProgressBar == true) { - if(Renderer::renderText3DEnabled) { - renderer.renderProgressBar3D( - progress, - metrics.getVirtualW() / 4, - 59 * metrics.getVirtualH() / 100, - coreData.getDisplayFontSmall3D(), - 500,""); // no string here, because it has to be language specific and does not give much information - } - else { - renderer.renderProgressBar( - progress, - metrics.getVirtualW() / 4, - 59 * metrics.getVirtualH() / 100, - coreData.getDisplayFontSmall(), - 500,""); // no string here, because it has to be language specific and does not give much information - } - } - - int xLocation = metrics.getVirtualW() / 4; - if(Renderer::renderText3DEnabled) { - - renderer.renderTextShadow3D( - state, coreData.getMenuFontBig3D(), displayColor, - xLocation, - 65 * metrics.getVirtualH() / 100, false); - - renderer.renderTextShadow3D( - current, coreData.getMenuFontNormal3D(), displayColor, - xLocation, - 62 * metrics.getVirtualH() / 100, false); - - if(this->statusText != "") { - renderer.renderTextShadow3D( - this->statusText, coreData.getMenuFontNormal3D(), displayColor, - xLocation, - 56 * metrics.getVirtualH() / 100, false); - } - } - else { - renderer.renderTextShadow( - state, coreData.getMenuFontBig(), displayColor, - xLocation, - 65 * metrics.getVirtualH() / 100, false); - - renderer.renderTextShadow( - current, coreData.getMenuFontNormal(), displayColor, - xLocation, - 62 * metrics.getVirtualH() / 100, false); - - if(this->statusText != "") { - renderer.renderTextShadow( - this->statusText, coreData.getMenuFontNormal(), displayColor, - xLocation, - 56 * metrics.getVirtualH() / 100, false); - } - } - - if(gameHintToShow != "") { - Lang &lang = Lang::getInstance(); - string hintText = lang.getString("Hint","",true); - char szBuf[8096]=""; - snprintf(szBuf,8096,hintText.c_str(),gameHintToShow.c_str()); - hintText = szBuf; - - if(Renderer::renderText3DEnabled) { - int xLocationHint = (metrics.getVirtualW() / 2) - (coreData.getMenuFontBig3D()->getMetrics()->getTextWidth(hintText) / 2); - - renderer.renderTextShadow3D( - hintText, coreData.getMenuFontBig3D(), displayColor, - //xLocation*1.5f, - xLocationHint, - 90 * metrics.getVirtualH() / 100, false); - } - else { - int xLocationHint = (metrics.getVirtualW() / 2) - (coreData.getMenuFontBig()->getMetrics()->getTextWidth(hintText) / 2); - - renderer.renderTextShadow( - hintText, coreData.getMenuFontBig(), displayColor, - //xLocation*1.5f, - xLocationHint, - 90 * metrics.getVirtualH() / 100, false); - - } - //Show next Hint - if(buttonNextHint.getEnabled() == false) { - buttonNextHint.init((metrics.getVirtualW() / 2) - (175 / 2), 90 * metrics.getVirtualH() / 100 + 20, 175); - buttonNextHint.setText(lang.getString("ShowNextHint","",true)); - buttonNextHint.setEnabled(true); - buttonNextHint.setVisible(true); - buttonNextHint.setEditable(true); + fclose(f); } - renderer.renderButton(&buttonNextHint); + void Logger::loadLoadingScreen(string filepath) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); -/* - if(Renderer::renderText3DEnabled) { - int xLocationHint = (metrics.getVirtualW() / 2) - (coreData.getMenuFontBig3D()->getMetrics()->getTextWidth(hintText) / 2); + if (filepath == "") { + loadingTexture = NULL; + } else { + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] filepath = [%s]\n", __FILE__, __FUNCTION__, __LINE__, filepath.c_str()); + loadingTexture = Renderer::findTexture(filepath); + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } - renderer.renderText3D( - lang.getString("ShowNextHint","",true), coreData.getMenuFontNormal3D(), nextHintTitleColor, - //xLocation*1.5f, - xLocationHint, - 93 * metrics.getVirtualH() / 100, false); + Lang &lang = Lang::getInstance(); + buttonCancel.setText(lang.getString("Cancel")); } - else { - int xLocationHint = (metrics.getVirtualW() / 2) - (coreData.getMenuFontBig()->getMetrics()->getTextWidth(hintText) / 2); - renderer.renderText( - lang.getString("ShowNextHint","",true), coreData.getMenuFontNormal(), nextHintTitleColor, - //xLocation*1.5f, - xLocationHint, - 93 * metrics.getVirtualH() / 100, false); + void Logger::loadGameHints(string filePathEnglish, string filePathTranslation, bool clearList) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if ((filePathEnglish == "") || (filePathTranslation == "")) { + return; + } else { + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] filePathEnglish = [%s]\n filePathTranslation = [%s]\n", __FILE__, __FUNCTION__, __LINE__, filePathEnglish.c_str(), filePathTranslation.c_str()); + gameHints.load(filePathEnglish, clearList); + gameHintsTranslation.load(filePathTranslation, clearList); + showNextHint(); + + Lang &lang = Lang::getInstance(); + buttonNextHint.setText(lang.getString("ShowNextHint", "", true)); + buttonCancel.setText(lang.getString("Cancel")); + + GraphicComponent::applyAllCustomProperties("Loading"); + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + } + + void Logger::showNextHint() { + string key = gameHints.getRandomKey(true); + string tmpString = gameHintsTranslation.getString(key, ""); + if (tmpString != "") { + gameHintToShow = tmpString; + } else { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] key [%s] not found for [%s] hint translation\n", __FILE__, __FUNCTION__, __LINE__, key.c_str(), Lang::getInstance().getLanguage().c_str()); + tmpString = gameHints.getString(key, ""); + if (tmpString != "") { + gameHintToShow = tmpString; + } else { + gameHintToShow = "Problems to resolve hint key '" + key + "'"; + } + } + replaceAll(gameHintToShow, "\\n", "\n"); + + Config &configKeys = Config::getInstance(std::pair(cfgMainKeys, cfgUserKeys)); + + vector > mergedKeySettings = configKeys.getMergedProperties(); + for (unsigned int j = 0; j < mergedKeySettings.size(); ++j) { + pair &property = mergedKeySettings[j]; + replaceAll(gameHintToShow, "#" + property.first + "#", property.second); + } + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void Logger::clearHints() { + gameHintToShow = ""; + gameHints.clear(); + gameHintsTranslation.clear(); + } + + void Logger::handleMouseClick(int x, int y) { + if (buttonCancel.getEnabled() == true) { + if (buttonCancel.mouseClick(x, y)) { + cancelSelected = true; + } + } + if (buttonNextHint.getEnabled() == true && buttonNextHint.mouseClick(x, y) == true) { + showNextHint(); + //buttonNextHint.setLighted(false); + SoundRenderer &soundRenderer = SoundRenderer::getInstance(); + CoreData &coreData = CoreData::getInstance(); + soundRenderer.playFx(coreData.getClickSoundC()); + } + } + + // ==================== PRIVATE ==================== + + void Logger::renderLoadingScreen() { + + Renderer &renderer = Renderer::getInstance(); + CoreData &coreData = CoreData::getInstance(); + const Metrics &metrics = Metrics::getInstance(); + + //3d + //renderer.reset3d(); + //renderer.clearZBuffer(); + + renderer.reset2d(); + renderer.clearBuffers(); + if (loadingTexture == NULL) { + renderer.renderBackground(CoreData::getInstance().getBackgroundTexture()); + } else { + renderer.renderBackground(loadingTexture); + } + + if (showProgressBar == true) { + if (Renderer::renderText3DEnabled) { + renderer.renderProgressBar3D( + progress, + metrics.getVirtualW() / 4, + 59 * metrics.getVirtualH() / 100, + coreData.getDisplayFontSmall3D(), + 500, ""); // no string here, because it has to be language specific and does not give much information + } else { + renderer.renderProgressBar( + progress, + metrics.getVirtualW() / 4, + 59 * metrics.getVirtualH() / 100, + coreData.getDisplayFontSmall(), + 500, ""); // no string here, because it has to be language specific and does not give much information + } + } + + int xLocation = metrics.getVirtualW() / 4; + if (Renderer::renderText3DEnabled) { + + renderer.renderTextShadow3D( + state, coreData.getMenuFontBig3D(), displayColor, + xLocation, + 65 * metrics.getVirtualH() / 100, false); + + renderer.renderTextShadow3D( + current, coreData.getMenuFontNormal3D(), displayColor, + xLocation, + 62 * metrics.getVirtualH() / 100, false); + + if (this->statusText != "") { + renderer.renderTextShadow3D( + this->statusText, coreData.getMenuFontNormal3D(), displayColor, + xLocation, + 56 * metrics.getVirtualH() / 100, false); + } + } else { + renderer.renderTextShadow( + state, coreData.getMenuFontBig(), displayColor, + xLocation, + 65 * metrics.getVirtualH() / 100, false); + + renderer.renderTextShadow( + current, coreData.getMenuFontNormal(), displayColor, + xLocation, + 62 * metrics.getVirtualH() / 100, false); + + if (this->statusText != "") { + renderer.renderTextShadow( + this->statusText, coreData.getMenuFontNormal(), displayColor, + xLocation, + 56 * metrics.getVirtualH() / 100, false); + } + } + + if (gameHintToShow != "") { + Lang &lang = Lang::getInstance(); + string hintText = lang.getString("Hint", "", true); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, hintText.c_str(), gameHintToShow.c_str()); + hintText = szBuf; + + if (Renderer::renderText3DEnabled) { + int xLocationHint = (metrics.getVirtualW() / 2) - (coreData.getMenuFontBig3D()->getMetrics()->getTextWidth(hintText) / 2); + + renderer.renderTextShadow3D( + hintText, coreData.getMenuFontBig3D(), displayColor, + //xLocation*1.5f, + xLocationHint, + 90 * metrics.getVirtualH() / 100, false); + } else { + int xLocationHint = (metrics.getVirtualW() / 2) - (coreData.getMenuFontBig()->getMetrics()->getTextWidth(hintText) / 2); + + renderer.renderTextShadow( + hintText, coreData.getMenuFontBig(), displayColor, + //xLocation*1.5f, + xLocationHint, + 90 * metrics.getVirtualH() / 100, false); + + } + //Show next Hint + if (buttonNextHint.getEnabled() == false) { + buttonNextHint.init((metrics.getVirtualW() / 2) - (175 / 2), 90 * metrics.getVirtualH() / 100 + 20, 175); + buttonNextHint.setText(lang.getString("ShowNextHint", "", true)); + buttonNextHint.setEnabled(true); + buttonNextHint.setVisible(true); + buttonNextHint.setEditable(true); + } + + renderer.renderButton(&buttonNextHint); + + /* + if(Renderer::renderText3DEnabled) { + int xLocationHint = (metrics.getVirtualW() / 2) - (coreData.getMenuFontBig3D()->getMetrics()->getTextWidth(hintText) / 2); + + renderer.renderText3D( + lang.getString("ShowNextHint","",true), coreData.getMenuFontNormal3D(), nextHintTitleColor, + //xLocation*1.5f, + xLocationHint, + 93 * metrics.getVirtualH() / 100, false); + } + else { + int xLocationHint = (metrics.getVirtualW() / 2) - (coreData.getMenuFontBig()->getMetrics()->getTextWidth(hintText) / 2); + + renderer.renderText( + lang.getString("ShowNextHint","",true), coreData.getMenuFontNormal(), nextHintTitleColor, + //xLocation*1.5f, + xLocationHint, + 93 * metrics.getVirtualH() / 100, false); + + } + */ + + } + + if (buttonCancel.getEnabled() == true) { + renderer.renderButton(&buttonCancel); + } + + renderer.swapBuffers(); + } + + void Logger::setCancelLoadingEnabled(bool value) { + Lang &lang = Lang::getInstance(); + const Metrics &metrics = Metrics::getInstance(); + //string containerName = "logger"; + //buttonCancel.registerGraphicComponent(containerName,"buttonCancel"); + buttonCancel.init((metrics.getVirtualW() / 2) - (125 / 2), 50 * metrics.getVirtualH() / 100, 125); + buttonCancel.setText(lang.getString("Cancel")); + buttonCancel.setEnabled(value); + //GraphicComponent::applyAllCustomProperties(containerName); } -*/ } - - if(buttonCancel.getEnabled() == true) { - renderer.renderButton(&buttonCancel); - } - - renderer.swapBuffers(); -} - -void Logger::setCancelLoadingEnabled(bool value) { - Lang &lang= Lang::getInstance(); - const Metrics &metrics= Metrics::getInstance(); - //string containerName = "logger"; - //buttonCancel.registerGraphicComponent(containerName,"buttonCancel"); - buttonCancel.init((metrics.getVirtualW() / 2) - (125 / 2), 50 * metrics.getVirtualH() / 100, 125); - buttonCancel.setText(lang.getString("Cancel")); - buttonCancel.setEnabled(value); - //GraphicComponent::applyAllCustomProperties(containerName); -} - -}}//end namespace +}//end namespace diff --git a/source/glest_game/facilities/logger.h b/source/glest_game/facilities/logger.h index 7728934f0..cd7940753 100644 --- a/source/glest_game/facilities/logger.h +++ b/source/glest_game/facilities/logger.h @@ -13,8 +13,8 @@ #define _SHARED_UTIL_LOGGER_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -30,74 +30,94 @@ using std::deque; using Shared::Graphics::Texture2D; using Shared::Util::Properties; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class Logger -// -/// Interface to write log files -// ===================================================== + // ===================================================== + // class Logger + // + /// Interface to write log files + // ===================================================== -class Logger { -private: - static const int logLineCount; + class Logger { + private: + static const int logLineCount; -private: - typedef deque Strings; + private: + typedef deque Strings; -private: - string fileName; - string state; - string subtitle; - string current; - Texture2D *loadingTexture; - Properties gameHints; - Properties gameHintsTranslation; - string gameHintToShow; - int progress; - bool showProgressBar; + private: + string fileName; + string state; + string subtitle; + string current; + Texture2D *loadingTexture; + Properties gameHints; + Properties gameHintsTranslation; + string gameHintToShow; + int progress; + bool showProgressBar; - string statusText; - bool cancelSelected; - GraphicButton buttonCancel; - Vec4f displayColor; - GraphicButton buttonNextHint; + string statusText; + bool cancelSelected; + GraphicButton buttonCancel; + Vec4f displayColor; + GraphicButton buttonNextHint; -private: - Logger(); - ~Logger(); + private: + Logger(); + ~Logger(); -public: - static Logger & getInstance(); + public: + static Logger & getInstance(); - //void setMasterserverMode(bool value) { masterserverMode = value; } + //void setMasterserverMode(bool value) { masterserverMode = value; } - void setFile(const string &fileName) {this->fileName= fileName;} - void setState(const string &state) {this->state= state;} - void setSubtitle(const string &subtitle) {this->subtitle= subtitle;} - void setProgress(int value) { this->progress = value; } - int getProgress() const {return progress;} - void showProgress() { showProgressBar = true;} - void hideProgress() { showProgressBar = false;} + void setFile(const string &fileName) { + this->fileName = fileName; + } + void setState(const string &state) { + this->state = state; + } + void setSubtitle(const string &subtitle) { + this->subtitle = subtitle; + } + void setProgress(int value) { + this->progress = value; + } + int getProgress() const { + return progress; + } + void showProgress() { + showProgressBar = true; + } + void hideProgress() { + showProgressBar = false; + } - void add(const string str, bool renderScreen= false, const string statusText=""); - void loadLoadingScreen(string filepath); - void loadGameHints(string filePathEnglish,string filePathTranslation,bool clearList); - void renderLoadingScreen(); + void add(const string str, bool renderScreen = false, const string statusText = ""); + void loadLoadingScreen(string filepath); + void loadGameHints(string filePathEnglish, string filePathTranslation, bool clearList); + void renderLoadingScreen(); - void setCancelLoadingEnabled(bool value); - bool getCancelLoading() const { return cancelSelected; } - void setCancelLoading(bool value) { cancelSelected = value; } - void handleMouseClick(int x, int y); - void clearHints(); + void setCancelLoadingEnabled(bool value); + bool getCancelLoading() const { + return cancelSelected; + } + void setCancelLoading(bool value) { + cancelSelected = value; + } + void handleMouseClick(int x, int y); + void clearHints(); - void clear(); + void clear(); -private: - void showNextHint(); + private: + void showNextHint(); -}; + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/glest_game/game/chat_manager.cpp b/source/glest_game/game/chat_manager.cpp index 52ca58182..ceff370e3 100644 --- a/source/glest_game/game/chat_manager.cpp +++ b/source/glest_game/game/chat_manager.cpp @@ -37,808 +37,684 @@ using namespace std; using namespace - Shared::Platform; +Shared::Platform; using namespace - Shared::Util; +Shared::Util; namespace - Glest -{ - namespace - Game - { - -// ===================================================== -// class ChatManager -// ===================================================== - - ChatManager::ChatManager () - { - console = NULL; - editEnabled = false; - teamMode = false; - thisTeamIndex = -1; - disableTeamMode = false; - xPos = 75; - yPos = 155; - maxTextLenght = 90; - textCharLength. - clear (); - text = ""; - font = CoreData::getInstance ().getConsoleFont (); - font3D = CoreData::getInstance ().getConsoleFont3D (); - inMenu = false; - customCB = NULL; - this-> - maxCustomTextLength = maxTextLenght; - } - - void - ChatManager::init (Console * console, int thisTeamIndex, - const bool inMenu, string manualPlayerNameOverride) - { - this->console = console; - this-> - thisTeamIndex = thisTeamIndex; - this-> - disableTeamMode = false; - this-> - inMenu = inMenu; - this-> - manualPlayerNameOverride = manualPlayerNameOverride; - } - - void - ChatManager::setDisableTeamMode (bool value) - { - disableTeamMode = value; - - if (disableTeamMode == true) - { - teamMode = false; - } - } - - void - ChatManager::keyUp (SDL_KeyboardEvent key) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - try - { - if (editEnabled == true) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = [%c] [%d]\n", - __FILE__, __FUNCTION__, __LINE__, - key.keysym.sym, key.keysym.sym); - - if (isKeyPressed (SDLK_ESCAPE, key, false) == true) - { - text.clear (); - textCharLength.clear (); - editEnabled = false; - - if (customCB != NULL) - { - customCB->processInputText (text, true); - customCB = NULL; - } - } - } - } - catch (const exception & ex) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d] error [%s]\n", __FILE__, - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw - megaglest_runtime_error (szBuf); - } - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - bool - ChatManager::textInput (std::string inputText) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] inputText [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - inputText.c_str ()); - - int - maxTextLenAllowed = - (customCB != NULL ? this->maxCustomTextLength : maxTextLenght); - string - textToAdd = - getTextWithLengthCheck (inputText, textCharLength.size (), - maxTextLenAllowed); - - if (editEnabled && (int) textCharLength.size () < maxTextLenAllowed - && textToAdd.size () > 0) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - appendText (textToAdd, true, true); - updateAutoCompleteBuffer (); - return true; - } - return false; - } - - string - ChatManager::getTextWithLengthCheck (string addText, int currentLength, - int maxLength) - { - string - resultText = ""; - if (addText.empty () == false) - { - int - utf8CharsAdded = 0; - for (unsigned int index = 0; index < addText.size ();) - { - int - len = getUTF8_Width (&addText[index]); - utf8CharsAdded++; - if (currentLength + utf8CharsAdded > maxLength) - { - break; - } - resultText += addText.substr (index, len); - index += len; - } - } - return resultText; - } - - void - ChatManager::keyDown (SDL_KeyboardEvent key) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = [%c] [%d]\n", - __FILE__, __FUNCTION__, __LINE__, - key.keysym.sym, key.keysym.sym); - - try - { - Lang & lang = Lang::getInstance (); - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - - //toggle team mode - if (editEnabled == false && - isKeyPressed (configKeys.getSDLKey ("ChatTeamMode"), key) == true) - { - if (disableTeamMode == true) - { - if (!inMenu) - { - console->addLine (lang. - getString - ("ChatModeDisabledToAvoidCheating")); - } - } - else - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = [%c] [%d]\n", - __FILE__, __FUNCTION__, __LINE__, - key.keysym.sym, key.keysym.sym); - - if (!inMenu) - { - if (teamMode == true) - { - teamMode = false; - console->addLine (lang.getString ("ChatMode") + ": " + - lang.getString ("All")); - } - else - { - teamMode = true; - console->addLine (lang.getString ("ChatMode") + ": " + - lang.getString ("Team")); - } - } - } - } - - - if (isKeyPressed (SDLK_RETURN, key, false) == true) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = [%c] [%d]\n", - __FILE__, __FUNCTION__, __LINE__, - key.keysym.sym, key.keysym.sym); - - SDL_keysym - keystate = key.keysym; - if (keystate.mod & (KMOD_LALT | KMOD_RALT)) - { - // alt+enter is ignored - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = [%c] [%d]\n", - __FILE__, __FUNCTION__, __LINE__, - key.keysym.sym, key.keysym.sym); - } - else - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = [%c] [%d]\n", - __FILE__, __FUNCTION__, __LINE__, - key.keysym.sym, key.keysym.sym); - - if (editEnabled == true) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = [%c] [%d]\n", - __FILE__, __FUNCTION__, - __LINE__, key.keysym.sym, - key.keysym.sym); - - GameNetworkInterface * - gameNetworkInterface = - NetworkManager::getInstance (). - getGameNetworkInterface (); - if (text.empty () == false) - { - - if (customCB == NULL) - { - //string playerName = gameNetworkInterface->getHumanPlayerName(); - int - playerIndex = - gameNetworkInterface->getHumanPlayerIndex (); - - if (this->manualPlayerNameOverride != "") - { - console->addLine (text, false, - this-> - manualPlayerNameOverride, - Vec3f (1.f, 1.f, 1.f), - teamMode); - } - else - { - console->addLine (text, false, playerIndex, - Vec3f (1.f, 1.f, 1.f), - teamMode); - } - - gameNetworkInterface->sendTextMessage ("*" + text, - teamMode ? - thisTeamIndex - : -1, - false, ""); - if (inMenu == false - && Config::getInstance (). - getBool ("ChatStaysActive", "false") == false) - { - editEnabled = false; - } - } - } - else - { - editEnabled = false; - } - - if (customCB != NULL) - { - customCB->processInputText (text, false); - editEnabled = false; - customCB = NULL; - } - - text.clear (); - textCharLength.clear (); - } - else - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = [%c] [%d]\n", - __FILE__, __FUNCTION__, - __LINE__, key.keysym.sym, - key.keysym.sym); - - switchOnEdit (); - } - } - } - else if (isKeyPressed (SDLK_TAB, key, false) == true) - { - if (text.empty () == false) - { - // First find the prefix characters to auto-complete - string - currentAutoCompleteName = ""; - - int - startPos = -1; - for (int i = (int)text.size () - 1; i >= 0; --i) - { - if (text[i] != ' ') - { - startPos = i; - } - else - { - break; - } - } - - if (startPos >= 0) - { - currentAutoCompleteName = text.substr (startPos); - } - - //printf("TAB currentAutoCompleteName [%s] lastAutoCompleteSearchText [%s]\n",currentAutoCompleteName.c_str(),lastAutoCompleteSearchText.c_str()); - string - autoCompleteName = lastAutoCompleteSearchText; - - // Now lookup the prefix for a match in playernames - string - autoCompleteResult = ""; - - int - replaceCurrentAutoCompleteName = -1; - vector < int > - matchedIndexes; - - GameNetworkInterface * - gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - const GameSettings * - settings = gameNetworkInterface->getGameSettings (); - for (unsigned int factionIndex = 0; - factionIndex < - (unsigned int) settings->getFactionCount (); - ++factionIndex) - { - string - playerName = - settings->getNetworkPlayerName (factionIndex); - if (playerName.length () > autoCompleteName.length () - && StartsWith (toLower (playerName), - toLower (autoCompleteName)) == true) - { - if (toLower (playerName) == - toLower (currentAutoCompleteName)) - { - replaceCurrentAutoCompleteName = factionIndex; - } - else - { - autoCompleteResult = - playerName.substr (autoCompleteName.length ()); - matchedIndexes.push_back (factionIndex); - } - } - } - if (matchedIndexes.empty () == false) - { - int - newMatchedIndex = -1; - for (unsigned int index = 0; - index < (unsigned int) matchedIndexes.size (); - ++index) - { - int - possibleMatchIndex = matchedIndexes[index]; - if (replaceCurrentAutoCompleteName < 0 - || possibleMatchIndex > - replaceCurrentAutoCompleteName) - { - newMatchedIndex = possibleMatchIndex; - break; - } - } - if (newMatchedIndex < 0) - { - for (unsigned int index = 0; - index < (unsigned int) matchedIndexes.size (); - ++index) - { - int - possibleMatchIndex = matchedIndexes[index]; - if (replaceCurrentAutoCompleteName < 0 - || possibleMatchIndex > - replaceCurrentAutoCompleteName) - { - newMatchedIndex = possibleMatchIndex; - break; - } - } - } - - if (newMatchedIndex >= 0) - { - autoCompleteResult = - settings->getNetworkPlayerName (newMatchedIndex). - substr (autoCompleteName.length ()); - } - } - - if (autoCompleteResult == "") - { - replaceCurrentAutoCompleteName = -1; - matchedIndexes.clear (); - for (unsigned int index = 0; - index < (unsigned int) autoCompleteTextList.size (); - ++index) - { - string - autoText = autoCompleteTextList[index]; - - //printf("CHECKING #2 autoText.length() = %d [%s] autoCompleteName.length() = %d [%s]\n",autoText.length(),autoText.c_str(),autoCompleteName.length(),currentAutoCompleteName.c_str()); - - if (autoText.length () > autoCompleteName.length () && - StartsWith (toLower (autoText), - toLower (autoCompleteName)) == true) - { - - if (toLower (autoText) == - toLower (currentAutoCompleteName)) - { - replaceCurrentAutoCompleteName = index; - //printf("CHECKING #2 REPLACE\n"); - } - else - { - autoCompleteResult = - autoText.substr (autoCompleteName. - length ()); - //printf("CHECKING #2 autoCompleteResult [%s] autoCompleteName [%s]\n",autoCompleteResult.c_str(),autoCompleteName.c_str()); - matchedIndexes.push_back (index); - } - } - } - if (matchedIndexes.empty () == false) - { - int - newMatchedIndex = -1; - for (unsigned int index = 0; - index < (unsigned int) matchedIndexes.size (); - ++index) - { - int - possibleMatchIndex = matchedIndexes[index]; - if (replaceCurrentAutoCompleteName < 0 - || possibleMatchIndex > - replaceCurrentAutoCompleteName) - { - newMatchedIndex = possibleMatchIndex; - break; - } - } - if (newMatchedIndex < 0) - { - for (unsigned int index = 0; - index < - (unsigned int) matchedIndexes.size (); - ++index) - { - int - possibleMatchIndex = matchedIndexes[index]; - if (replaceCurrentAutoCompleteName < 0 - || possibleMatchIndex > - replaceCurrentAutoCompleteName) - { - newMatchedIndex = possibleMatchIndex; - break; - } - } - } - - if (newMatchedIndex >= 0) - { - autoCompleteResult = - autoCompleteTextList[newMatchedIndex]. - substr (autoCompleteName.length ()); - } - } - } - - if (autoCompleteResult != "") - { - if (replaceCurrentAutoCompleteName >= 0) - { - deleteText ((int) currentAutoCompleteName.length (), - false); - - autoCompleteResult = - autoCompleteName + autoCompleteResult; - - //printf("REPLACE: currentAutoCompleteName [%s] autoCompleteResult [%s] text [%s]\n",currentAutoCompleteName.c_str(),autoCompleteResult.c_str(),text.c_str()); - } - else - { - //printf("ADD: currentAutoCompleteName [%s] autoCompleteResult [%s] text [%s]\n",currentAutoCompleteName.c_str(),autoCompleteResult.c_str(),text.c_str()); - } - appendText (autoCompleteResult, false, false); - } - } - } - else if (isKeyPressed (SDLK_BACKSPACE, key, false) == true) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = [%c] [%d]\n", - __FILE__, __FUNCTION__, __LINE__, - key.keysym.sym, key.keysym.sym); - - deleteText (1); - } - - } - catch (const exception & ex) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw - megaglest_runtime_error (szBuf); - } - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - void - ChatManager::keyPress (SDL_KeyboardEvent c) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = [%c] [%d]\n", - __FILE__, __FUNCTION__, __LINE__, - c.keysym.sym, c.keysym.sym); - -// no more textinput with keyPress in SDL2! -// int maxTextLenAllowed = (customCB != NULL ? this->maxCustomTextLength : maxTextLenght); -// if(editEnabled && (int)text.size() < maxTextLenAllowed) { -// SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c] [%d]\n",__FILE__,__FUNCTION__,__LINE__,c.keysym.sym,c.keysym.sym); -// //space is the first meaningful code -// wchar_t key = extractKeyPressedUnicode(c); -// wchar_t textAppend[] = { key, 0 }; -// appendText(textAppend); -// } - } - - void - ChatManager::switchOnEdit (CustomInputCallbackInterface * customCB, - int maxCustomTextLength) - { - editEnabled = true; - text.clear (); - textCharLength.clear (); - this->customCB = customCB; - if (maxCustomTextLength > 0) - { - this->maxCustomTextLength = maxCustomTextLength; - } - else - { - this->maxCustomTextLength = maxTextLenght; - } - } - - void - ChatManager::deleteText (int deleteCount, bool addToAutoCompleteBuffer) - { - if (text.empty () == false && deleteCount >= 0) - { - for (unsigned int i = 0; i < (unsigned int) deleteCount; ++i) - { - if (textCharLength.empty () == false) - { - //printf("BEFORE DEL textCharLength.size() = %d textCharLength[textCharLength.size()-1] = %d text.length() = %d\n",textCharLength.size(),textCharLength[textCharLength.size()-1],text.length()); - - if (textCharLength[textCharLength.size () - 1] > - (int) text.length ()) - { - textCharLength[(int) textCharLength.size () - 1] = - (int) text.length (); - } - for (unsigned int i = 0; - i < - (unsigned int) textCharLength[textCharLength.size () - - 1]; ++i) - { - text.erase (text.end () - 1); - } - //printf("AFTER DEL textCharLength.size() = %d textCharLength[textCharLength.size()-1] = %d text.length() = %d\n",textCharLength.size(),textCharLength[textCharLength.size()-1],text.length()); - textCharLength.pop_back (); - - if (addToAutoCompleteBuffer == true) - { - updateAutoCompleteBuffer (); - } - } - } - } - - } - - void - ChatManager::appendText (string addText, bool validateChars, - bool addToAutoCompleteBuffer) - { - - for (unsigned int index = 0; index < addText.size ();) - { - int - len = getUTF8_Width (&addText[index]); - textCharLength.push_back (len); - text += addText.substr (index, len); - index += len; - - if (addToAutoCompleteBuffer == true) - { - updateAutoCompleteBuffer (); - } - } - } - - void - ChatManager::updateAutoCompleteBuffer () - { - if (text.empty () == false) - { - int - startPos = -1; - for (int i = (int)text.size () - 1; i >= 0; --i) - { - if (text[i] != ' ') - { - startPos = i; - } - else - { - break; - } - } - - if (startPos >= 0) - { - lastAutoCompleteSearchText = text.substr (startPos); - } - } - } - - void - ChatManager::addText (string text) - { - int - maxTextLenAllowed = - (customCB != NULL ? this->maxCustomTextLength : maxTextLenght); - if (editEnabled - && (int) text.size () + (int) this->text.size () <= - maxTextLenAllowed) - { - this->text += text; - for (int i = 0; i < (int) text.size (); i++) - { - textCharLength.push_back (1); - } - } - } - - void - ChatManager::updateNetwork () - { - try - { - GameNetworkInterface * - gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - //string text; - //string sender; - //Config &config= Config::getInstance(); - - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] gameNetworkInterface->getChatText() [%s]\n",__FILE__,__FUNCTION__,__LINE__,gameNetworkInterface->getChatText().c_str()); - - if (gameNetworkInterface != NULL && - gameNetworkInterface->getChatTextList (false).empty () == false) - { - Lang & lang = Lang::getInstance (); - - std::vector < ChatMsgInfo > chatList = - gameNetworkInterface->getChatTextList (true); - for (int idx = 0; idx < (int) chatList.size (); idx++) - { - const ChatMsgInfo - msg = chatList[idx]; - int - teamIndex = msg.chatTeamIndex; - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] got nmtText [%s] for team = %d\n", - __FILE__, __FUNCTION__, - msg.chatText.c_str (), teamIndex); - - if (teamIndex == -1 || teamIndex == thisTeamIndex) - { - if (msg.targetLanguage == "" - || lang.isLanguageLocal (msg.targetLanguage) == true) - { - bool - teamMode = (teamIndex != -1 - && teamIndex == thisTeamIndex); - string - playerName = - gameNetworkInterface->getHumanPlayerName (); - if (this->manualPlayerNameOverride != "") - { - playerName = this->manualPlayerNameOverride; - } - - //printf("Network chat msg from: [%d - %s] [%s]\n",msg.chatPlayerIndex,gameNetworkInterface->getHumanPlayerName().c_str(),this->manualPlayerNameOverride.c_str()); - - if (StartsWith (msg.chatText, "*")) - { - if (msg.chatText.find (playerName) != - string::npos) - { - static PlaySoundClip snd; - SoundRenderer & soundRenderer = - SoundRenderer::getInstance (); - soundRenderer.playFx (snd.getSound (snd.sfxHighlight), - true); - } - console->addLine (msg.chatText. - substr (1, - msg.chatText.size ()), - true, msg.chatPlayerIndex, - Vec3f (1.f, 1.f, 1.f), - teamMode); - } - else - { - console->addLine (msg.chatText, true, - msg.chatPlayerIndex, Vec3f (1.f, - 1.f, - 1.f), - teamMode); - } - - } - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Added text to console\n", - __FILE__, __FUNCTION__); - } - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - //gameNetworkInterface->clearChatInfo(); - } - } - catch (const std::exception & ex) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw - megaglest_runtime_error (szBuf); - } - } - -}} //end namespace + Glest { + namespace + Game { + + // ===================================================== + // class ChatManager + // ===================================================== + + ChatManager::ChatManager() { + console = NULL; + editEnabled = false; + teamMode = false; + thisTeamIndex = -1; + disableTeamMode = false; + xPos = 75; + yPos = 155; + maxTextLenght = 90; + textCharLength. + clear(); + text = ""; + font = CoreData::getInstance().getConsoleFont(); + font3D = CoreData::getInstance().getConsoleFont3D(); + inMenu = false; + customCB = NULL; + this-> + maxCustomTextLength = maxTextLenght; + } + + void + ChatManager::init(Console * console, int thisTeamIndex, + const bool inMenu, string manualPlayerNameOverride) { + this->console = console; + this-> + thisTeamIndex = thisTeamIndex; + this-> + disableTeamMode = false; + this-> + inMenu = inMenu; + this-> + manualPlayerNameOverride = manualPlayerNameOverride; + } + + void + ChatManager::setDisableTeamMode(bool value) { + disableTeamMode = value; + + if (disableTeamMode == true) { + teamMode = false; + } + } + + void + ChatManager::keyUp(SDL_KeyboardEvent key) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + try { + if (editEnabled == true) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = [%c] [%d]\n", + __FILE__, __FUNCTION__, __LINE__, + key.keysym.sym, key.keysym.sym); + + if (isKeyPressed(SDLK_ESCAPE, key, false) == true) { + text.clear(); + textCharLength.clear(); + editEnabled = false; + + if (customCB != NULL) { + customCB->processInputText(text, true); + customCB = NULL; + } + } + } + } catch (const exception & ex) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] error [%s]\n", __FILE__, + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw + megaglest_runtime_error(szBuf); + } + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + bool + ChatManager::textInput(std::string inputText) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] inputText [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + inputText.c_str()); + + int + maxTextLenAllowed = + (customCB != NULL ? this->maxCustomTextLength : maxTextLenght); + string + textToAdd = + getTextWithLengthCheck(inputText, textCharLength.size(), + maxTextLenAllowed); + + if (editEnabled && (int) textCharLength.size() < maxTextLenAllowed + && textToAdd.size() > 0) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + appendText(textToAdd, true, true); + updateAutoCompleteBuffer(); + return true; + } + return false; + } + + string + ChatManager::getTextWithLengthCheck(string addText, int currentLength, + int maxLength) { + string + resultText = ""; + if (addText.empty() == false) { + int + utf8CharsAdded = 0; + for (unsigned int index = 0; index < addText.size();) { + int + len = getUTF8_Width(&addText[index]); + utf8CharsAdded++; + if (currentLength + utf8CharsAdded > maxLength) { + break; + } + resultText += addText.substr(index, len); + index += len; + } + } + return resultText; + } + + void + ChatManager::keyDown(SDL_KeyboardEvent key) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = [%c] [%d]\n", + __FILE__, __FUNCTION__, __LINE__, + key.keysym.sym, key.keysym.sym); + + try { + Lang & lang = Lang::getInstance(); + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + + //toggle team mode + if (editEnabled == false && + isKeyPressed(configKeys.getSDLKey("ChatTeamMode"), key) == true) { + if (disableTeamMode == true) { + if (!inMenu) { + console->addLine(lang. + getString + ("ChatModeDisabledToAvoidCheating")); + } + } else { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = [%c] [%d]\n", + __FILE__, __FUNCTION__, __LINE__, + key.keysym.sym, key.keysym.sym); + + if (!inMenu) { + if (teamMode == true) { + teamMode = false; + console->addLine(lang.getString("ChatMode") + ": " + + lang.getString("All")); + } else { + teamMode = true; + console->addLine(lang.getString("ChatMode") + ": " + + lang.getString("Team")); + } + } + } + } + + + if (isKeyPressed(SDLK_RETURN, key, false) == true) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = [%c] [%d]\n", + __FILE__, __FUNCTION__, __LINE__, + key.keysym.sym, key.keysym.sym); + + SDL_keysym + keystate = key.keysym; + if (keystate.mod & (KMOD_LALT | KMOD_RALT)) { + // alt+enter is ignored + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = [%c] [%d]\n", + __FILE__, __FUNCTION__, __LINE__, + key.keysym.sym, key.keysym.sym); + } else { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = [%c] [%d]\n", + __FILE__, __FUNCTION__, __LINE__, + key.keysym.sym, key.keysym.sym); + + if (editEnabled == true) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = [%c] [%d]\n", + __FILE__, __FUNCTION__, + __LINE__, key.keysym.sym, + key.keysym.sym); + + GameNetworkInterface * + gameNetworkInterface = + NetworkManager::getInstance(). + getGameNetworkInterface(); + if (text.empty() == false) { + + if (customCB == NULL) { + //string playerName = gameNetworkInterface->getHumanPlayerName(); + int + playerIndex = + gameNetworkInterface->getHumanPlayerIndex(); + + if (this->manualPlayerNameOverride != "") { + console->addLine(text, false, + this-> + manualPlayerNameOverride, + Vec3f(1.f, 1.f, 1.f), + teamMode); + } else { + console->addLine(text, false, playerIndex, + Vec3f(1.f, 1.f, 1.f), + teamMode); + } + + gameNetworkInterface->sendTextMessage("*" + text, + teamMode ? + thisTeamIndex + : -1, + false, ""); + if (inMenu == false + && Config::getInstance(). + getBool("ChatStaysActive", "false") == false) { + editEnabled = false; + } + } + } else { + editEnabled = false; + } + + if (customCB != NULL) { + customCB->processInputText(text, false); + editEnabled = false; + customCB = NULL; + } + + text.clear(); + textCharLength.clear(); + } else { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = [%c] [%d]\n", + __FILE__, __FUNCTION__, + __LINE__, key.keysym.sym, + key.keysym.sym); + + switchOnEdit(); + } + } + } else if (isKeyPressed(SDLK_TAB, key, false) == true) { + if (text.empty() == false) { + // First find the prefix characters to auto-complete + string + currentAutoCompleteName = ""; + + int + startPos = -1; + for (int i = (int) text.size() - 1; i >= 0; --i) { + if (text[i] != ' ') { + startPos = i; + } else { + break; + } + } + + if (startPos >= 0) { + currentAutoCompleteName = text.substr(startPos); + } + + //printf("TAB currentAutoCompleteName [%s] lastAutoCompleteSearchText [%s]\n",currentAutoCompleteName.c_str(),lastAutoCompleteSearchText.c_str()); + string + autoCompleteName = lastAutoCompleteSearchText; + + // Now lookup the prefix for a match in playernames + string + autoCompleteResult = ""; + + int + replaceCurrentAutoCompleteName = -1; + vector < int > + matchedIndexes; + + GameNetworkInterface * + gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + const GameSettings * + settings = gameNetworkInterface->getGameSettings(); + for (unsigned int factionIndex = 0; + factionIndex < + (unsigned int) settings->getFactionCount(); + ++factionIndex) { + string + playerName = + settings->getNetworkPlayerName(factionIndex); + if (playerName.length() > autoCompleteName.length() + && StartsWith(toLower(playerName), + toLower(autoCompleteName)) == true) { + if (toLower(playerName) == + toLower(currentAutoCompleteName)) { + replaceCurrentAutoCompleteName = factionIndex; + } else { + autoCompleteResult = + playerName.substr(autoCompleteName.length()); + matchedIndexes.push_back(factionIndex); + } + } + } + if (matchedIndexes.empty() == false) { + int + newMatchedIndex = -1; + for (unsigned int index = 0; + index < (unsigned int) matchedIndexes.size(); + ++index) { + int + possibleMatchIndex = matchedIndexes[index]; + if (replaceCurrentAutoCompleteName < 0 + || possibleMatchIndex > + replaceCurrentAutoCompleteName) { + newMatchedIndex = possibleMatchIndex; + break; + } + } + if (newMatchedIndex < 0) { + for (unsigned int index = 0; + index < (unsigned int) matchedIndexes.size(); + ++index) { + int + possibleMatchIndex = matchedIndexes[index]; + if (replaceCurrentAutoCompleteName < 0 + || possibleMatchIndex > + replaceCurrentAutoCompleteName) { + newMatchedIndex = possibleMatchIndex; + break; + } + } + } + + if (newMatchedIndex >= 0) { + autoCompleteResult = + settings->getNetworkPlayerName(newMatchedIndex). + substr(autoCompleteName.length()); + } + } + + if (autoCompleteResult == "") { + replaceCurrentAutoCompleteName = -1; + matchedIndexes.clear(); + for (unsigned int index = 0; + index < (unsigned int) autoCompleteTextList.size(); + ++index) { + string + autoText = autoCompleteTextList[index]; + + //printf("CHECKING #2 autoText.length() = %d [%s] autoCompleteName.length() = %d [%s]\n",autoText.length(),autoText.c_str(),autoCompleteName.length(),currentAutoCompleteName.c_str()); + + if (autoText.length() > autoCompleteName.length() && + StartsWith(toLower(autoText), + toLower(autoCompleteName)) == true) { + + if (toLower(autoText) == + toLower(currentAutoCompleteName)) { + replaceCurrentAutoCompleteName = index; + //printf("CHECKING #2 REPLACE\n"); + } else { + autoCompleteResult = + autoText.substr(autoCompleteName. + length()); + //printf("CHECKING #2 autoCompleteResult [%s] autoCompleteName [%s]\n",autoCompleteResult.c_str(),autoCompleteName.c_str()); + matchedIndexes.push_back(index); + } + } + } + if (matchedIndexes.empty() == false) { + int + newMatchedIndex = -1; + for (unsigned int index = 0; + index < (unsigned int) matchedIndexes.size(); + ++index) { + int + possibleMatchIndex = matchedIndexes[index]; + if (replaceCurrentAutoCompleteName < 0 + || possibleMatchIndex > + replaceCurrentAutoCompleteName) { + newMatchedIndex = possibleMatchIndex; + break; + } + } + if (newMatchedIndex < 0) { + for (unsigned int index = 0; + index < + (unsigned int) matchedIndexes.size(); + ++index) { + int + possibleMatchIndex = matchedIndexes[index]; + if (replaceCurrentAutoCompleteName < 0 + || possibleMatchIndex > + replaceCurrentAutoCompleteName) { + newMatchedIndex = possibleMatchIndex; + break; + } + } + } + + if (newMatchedIndex >= 0) { + autoCompleteResult = + autoCompleteTextList[newMatchedIndex]. + substr(autoCompleteName.length()); + } + } + } + + if (autoCompleteResult != "") { + if (replaceCurrentAutoCompleteName >= 0) { + deleteText((int) currentAutoCompleteName.length(), + false); + + autoCompleteResult = + autoCompleteName + autoCompleteResult; + + //printf("REPLACE: currentAutoCompleteName [%s] autoCompleteResult [%s] text [%s]\n",currentAutoCompleteName.c_str(),autoCompleteResult.c_str(),text.c_str()); + } else { + //printf("ADD: currentAutoCompleteName [%s] autoCompleteResult [%s] text [%s]\n",currentAutoCompleteName.c_str(),autoCompleteResult.c_str(),text.c_str()); + } + appendText(autoCompleteResult, false, false); + } + } + } else if (isKeyPressed(SDLK_BACKSPACE, key, false) == true) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = [%c] [%d]\n", + __FILE__, __FUNCTION__, __LINE__, + key.keysym.sym, key.keysym.sym); + + deleteText(1); + } + + } catch (const exception & ex) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw + megaglest_runtime_error(szBuf); + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + void + ChatManager::keyPress(SDL_KeyboardEvent c) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = [%c] [%d]\n", + __FILE__, __FUNCTION__, __LINE__, + c.keysym.sym, c.keysym.sym); + + // no more textinput with keyPress in SDL2! + // int maxTextLenAllowed = (customCB != NULL ? this->maxCustomTextLength : maxTextLenght); + // if(editEnabled && (int)text.size() < maxTextLenAllowed) { + // SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c] [%d]\n",__FILE__,__FUNCTION__,__LINE__,c.keysym.sym,c.keysym.sym); + // //space is the first meaningful code + // wchar_t key = extractKeyPressedUnicode(c); + // wchar_t textAppend[] = { key, 0 }; + // appendText(textAppend); + // } + } + + void + ChatManager::switchOnEdit(CustomInputCallbackInterface * customCB, + int maxCustomTextLength) { + editEnabled = true; + text.clear(); + textCharLength.clear(); + this->customCB = customCB; + if (maxCustomTextLength > 0) { + this->maxCustomTextLength = maxCustomTextLength; + } else { + this->maxCustomTextLength = maxTextLenght; + } + } + + void + ChatManager::deleteText(int deleteCount, bool addToAutoCompleteBuffer) { + if (text.empty() == false && deleteCount >= 0) { + for (unsigned int i = 0; i < (unsigned int) deleteCount; ++i) { + if (textCharLength.empty() == false) { + //printf("BEFORE DEL textCharLength.size() = %d textCharLength[textCharLength.size()-1] = %d text.length() = %d\n",textCharLength.size(),textCharLength[textCharLength.size()-1],text.length()); + + if (textCharLength[textCharLength.size() - 1] > + (int) text.length()) { + textCharLength[(int) textCharLength.size() - 1] = + (int) text.length(); + } + for (unsigned int i = 0; + i < + (unsigned int) textCharLength[textCharLength.size() - + 1]; ++i) { + text.erase(text.end() - 1); + } + //printf("AFTER DEL textCharLength.size() = %d textCharLength[textCharLength.size()-1] = %d text.length() = %d\n",textCharLength.size(),textCharLength[textCharLength.size()-1],text.length()); + textCharLength.pop_back(); + + if (addToAutoCompleteBuffer == true) { + updateAutoCompleteBuffer(); + } + } + } + } + + } + + void + ChatManager::appendText(string addText, bool validateChars, + bool addToAutoCompleteBuffer) { + + for (unsigned int index = 0; index < addText.size();) { + int + len = getUTF8_Width(&addText[index]); + textCharLength.push_back(len); + text += addText.substr(index, len); + index += len; + + if (addToAutoCompleteBuffer == true) { + updateAutoCompleteBuffer(); + } + } + } + + void + ChatManager::updateAutoCompleteBuffer() { + if (text.empty() == false) { + int + startPos = -1; + for (int i = (int) text.size() - 1; i >= 0; --i) { + if (text[i] != ' ') { + startPos = i; + } else { + break; + } + } + + if (startPos >= 0) { + lastAutoCompleteSearchText = text.substr(startPos); + } + } + } + + void + ChatManager::addText(string text) { + int + maxTextLenAllowed = + (customCB != NULL ? this->maxCustomTextLength : maxTextLenght); + if (editEnabled + && (int) text.size() + (int) this->text.size() <= + maxTextLenAllowed) { + this->text += text; + for (int i = 0; i < (int) text.size(); i++) { + textCharLength.push_back(1); + } + } + } + + void + ChatManager::updateNetwork() { + try { + GameNetworkInterface * + gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + //string text; + //string sender; + //Config &config= Config::getInstance(); + + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] gameNetworkInterface->getChatText() [%s]\n",__FILE__,__FUNCTION__,__LINE__,gameNetworkInterface->getChatText().c_str()); + + if (gameNetworkInterface != NULL && + gameNetworkInterface->getChatTextList(false).empty() == false) { + Lang & lang = Lang::getInstance(); + + std::vector < ChatMsgInfo > chatList = + gameNetworkInterface->getChatTextList(true); + for (int idx = 0; idx < (int) chatList.size(); idx++) { + const ChatMsgInfo + msg = chatList[idx]; + int + teamIndex = msg.chatTeamIndex; + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] got nmtText [%s] for team = %d\n", + __FILE__, __FUNCTION__, + msg.chatText.c_str(), teamIndex); + + if (teamIndex == -1 || teamIndex == thisTeamIndex) { + if (msg.targetLanguage == "" + || lang.isLanguageLocal(msg.targetLanguage) == true) { + bool + teamMode = (teamIndex != -1 + && teamIndex == thisTeamIndex); + string + playerName = + gameNetworkInterface->getHumanPlayerName(); + if (this->manualPlayerNameOverride != "") { + playerName = this->manualPlayerNameOverride; + } + + //printf("Network chat msg from: [%d - %s] [%s]\n",msg.chatPlayerIndex,gameNetworkInterface->getHumanPlayerName().c_str(),this->manualPlayerNameOverride.c_str()); + + if (StartsWith(msg.chatText, "*")) { + if (msg.chatText.find(playerName) != + string::npos) { + static PlaySoundClip snd; + SoundRenderer & soundRenderer = + SoundRenderer::getInstance(); + soundRenderer.playFx(snd.getSound(snd.sfxHighlight), + true); + } + console->addLine(msg.chatText. + substr(1, + msg.chatText.size()), + true, msg.chatPlayerIndex, + Vec3f(1.f, 1.f, 1.f), + teamMode); + } else { + console->addLine(msg.chatText, true, + msg.chatPlayerIndex, Vec3f(1.f, + 1.f, + 1.f), + teamMode); + } + + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Added text to console\n", + __FILE__, __FUNCTION__); + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + //gameNetworkInterface->clearChatInfo(); + } + } catch (const std::exception & ex) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw + megaglest_runtime_error(szBuf); + } + } + + } +} //end namespace diff --git a/source/glest_game/game/chat_manager.h b/source/glest_game/game/chat_manager.h index 1b0b32ee5..8a58358fb 100644 --- a/source/glest_game/game/chat_manager.h +++ b/source/glest_game/game/chat_manager.h @@ -36,225 +36,203 @@ # include "leak_dumper.h" using - std::string; +std::string; using - std::vector; +std::vector; using - Shared::Graphics::Font2D; +Shared::Graphics::Font2D; using - Shared::Graphics::Font3D; +Shared::Graphics::Font3D; namespace - Glest -{ - namespace - Game - { + Glest { + namespace + Game { - class - Console; + class + Console; -// -// This interface describes the methods a callback object must implement -// - class - CustomInputCallbackInterface - { - public: - virtual void - processInputText (string text, bool cancelled) = 0; - virtual ~ - CustomInputCallbackInterface () - { - } - }; + // + // This interface describes the methods a callback object must implement + // + class + CustomInputCallbackInterface { + public: + virtual void + processInputText(string text, bool cancelled) = 0; + virtual ~ + CustomInputCallbackInterface() { + } + }; -// ===================================================== -// class ChatManager -// ===================================================== + // ===================================================== + // class ChatManager + // ===================================================== - class - ChatManager - { + class + ChatManager { - private: - bool - editEnabled; - bool - teamMode; - bool - disableTeamMode; - Console * - console; - string - text; - vector < int > - textCharLength; - int - thisTeamIndex; - bool - inMenu; - string - manualPlayerNameOverride; - int - xPos; - int - yPos; - int - maxTextLenght; - Font2D * - font; - Font3D * - font3D; + private: + bool + editEnabled; + bool + teamMode; + bool + disableTeamMode; + Console * + console; + string + text; + vector < int > + textCharLength; + int + thisTeamIndex; + bool + inMenu; + string + manualPlayerNameOverride; + int + xPos; + int + yPos; + int + maxTextLenght; + Font2D * + font; + Font3D * + font3D; - string - lastAutoCompleteSearchText; - vector < - string > - autoCompleteTextList; + string + lastAutoCompleteSearchText; + vector < + string > + autoCompleteTextList; - CustomInputCallbackInterface * - customCB; - int - maxCustomTextLength; + CustomInputCallbackInterface * + customCB; + int + maxCustomTextLength; - string - getTextWithLengthCheck (string text, int currentLength, int maxLength); - void - appendText (string addText, bool validateChars = - true, bool addToAutoCompleteBuffer = true); - void - deleteText (int deleteCount, bool addToAutoCompleteBuffer = true); - void - updateAutoCompleteBuffer (); + string + getTextWithLengthCheck(string text, int currentLength, int maxLength); + void + appendText(string addText, bool validateChars = + true, bool addToAutoCompleteBuffer = true); + void + deleteText(int deleteCount, bool addToAutoCompleteBuffer = true); + void + updateAutoCompleteBuffer(); - public: - ChatManager (); - void - init (Console * console, int thisTeamIndex, const bool inMenu = - false, string manualPlayerNameOverride = ""); + public: + ChatManager(); + void + init(Console * console, int thisTeamIndex, const bool inMenu = + false, string manualPlayerNameOverride = ""); - bool - textInput (std::string text); - void - keyDown (SDL_KeyboardEvent key); - void - keyUp (SDL_KeyboardEvent key); - void - keyPress (SDL_KeyboardEvent c); - void - updateNetwork (); + bool + textInput(std::string text); + void + keyDown(SDL_KeyboardEvent key); + void + keyUp(SDL_KeyboardEvent key); + void + keyPress(SDL_KeyboardEvent c); + void + updateNetwork(); - bool - getEditEnabled () const - { - return - editEnabled; - } - bool - getTeamMode () const - { - return - teamMode; - } - bool - getInMenu () const - { - return - inMenu; - } - string - getText () const - { - return - text; - } - int - getXPos () const - { - return - xPos; - } - void - setXPos (int xPos) - { - this->xPos = xPos; - } - int - getYPos () const - { - return - yPos; - } - void - setYPos (int yPos) - { - this->yPos = yPos; - } - int - getMaxTextLenght () const - { - return - maxTextLenght; - } - void - setMaxTextLenght (int maxTextLenght) - { - this->maxTextLenght = maxTextLenght; - } - Font2D * - getFont () const - { - return - font; - } - Font3D * - getFont3D () const - { - return - font3D; - } - void - setFont (Font2D * font) - { - this->font = font; - } - void - setFont3D (Font3D * font) - { - this->font3D = font; - } - void - addText (string text); - void - switchOnEdit (CustomInputCallbackInterface * customCB = - NULL, int maxCustomTextLength = -1); + bool + getEditEnabled() const { + return + editEnabled; + } + bool + getTeamMode() const { + return + teamMode; + } + bool + getInMenu() const { + return + inMenu; + } + string + getText() const { + return + text; + } + int + getXPos() const { + return + xPos; + } + void + setXPos(int xPos) { + this->xPos = xPos; + } + int + getYPos() const { + return + yPos; + } + void + setYPos(int yPos) { + this->yPos = yPos; + } + int + getMaxTextLenght() const { + return + maxTextLenght; + } + void + setMaxTextLenght(int maxTextLenght) { + this->maxTextLenght = maxTextLenght; + } + Font2D * + getFont() const { + return + font; + } + Font3D * + getFont3D() const { + return + font3D; + } + void + setFont(Font2D * font) { + this->font = font; + } + void + setFont3D(Font3D * font) { + this->font3D = font; + } + void + addText(string text); + void + switchOnEdit(CustomInputCallbackInterface * customCB = + NULL, int maxCustomTextLength = -1); - bool - getDisableTeamMode () const - { - return - disableTeamMode; - } - void - setDisableTeamMode (bool value); + bool + getDisableTeamMode() const { + return + disableTeamMode; + } + void + setDisableTeamMode(bool value); - void - setAutoCompleteTextList (const vector < string > &list) - { - autoCompleteTextList = list; - } + void + setAutoCompleteTextList(const vector < string > &list) { + autoCompleteTextList = list; + } - bool - isInCustomInputMode () const - { - return - customCB != - NULL; - }; - }; + bool + isInCustomInputMode() const { + return + customCB != + NULL; + }; + }; - } + } } //end namespace #endif diff --git a/source/glest_game/game/commander.cpp b/source/glest_game/game/commander.cpp index 1f2337848..3b30e7b32 100644 --- a/source/glest_game/game/commander.cpp +++ b/source/glest_game/game/commander.cpp @@ -26,1993 +26,1827 @@ #include "game.h" using namespace - Shared::Graphics; +Shared::Graphics; using namespace - Shared::Util; +Shared::Util; using namespace - Shared::Platform; +Shared::Platform; namespace - Glest -{ - namespace - Game - { - -// ===================================================== -// class Commander -// ===================================================== - Commander::Commander () - { - this->world = NULL; - this-> - pauseNetworkCommands = false; - } - - Commander::~ - Commander () - { - } - - void - Commander::init (World * world) - { - this->world = world; - } - - bool - Commander::canSubmitCommandType (const Unit * unit, - const CommandType * commandType) const - { - bool - canSubmitCommand = true; - const MorphCommandType * - mct = dynamic_cast < const - MorphCommandType * >(commandType); - if (mct && unit->getCommandSize () > 0) - { - Command * - cur_command = unit->getCurrCommand (); - if (cur_command != NULL) - { - const MorphCommandType * - cur_mct = dynamic_cast < const - MorphCommandType * >(cur_command->getCommandType ()); - if (cur_mct && unit->getCurrSkill () - && unit->getCurrSkill ()->getClass () == scMorph) - { - const UnitType * - morphUnitType = mct->getMorphUnit (); - const UnitType * - cur_morphUnitType = cur_mct->getMorphUnit (); - - if (morphUnitType != NULL && cur_morphUnitType != NULL - && morphUnitType->getId () == - cur_morphUnitType->getId ()) - { - canSubmitCommand = false; - } - } - } - } - return - canSubmitCommand; - } - - std::pair < CommandResult, - string > Commander::tryGiveCommand (const Selection * selection, - const CommandType * commandType, - const Vec2i & pos, - const UnitType * unitType, - CardinalDir facing, bool tryQueue, - Unit * targetUnit) const - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (this->pauseNetworkCommands == true) - { - return std::pair < CommandResult, string > (crFailUndefined, ""); - } - - std::pair < - CommandResult, - string > - result (crFailUndefined, ""); - if (selection->isEmpty () == false && commandType != NULL) - { - Vec2i - refPos; - CommandResultContainer - results; - - refPos = world->getMap ()->computeRefPos (selection); - - const Unit * - builderUnit = - world->getMap ()->findClosestUnitToPos (selection, pos, unitType); - - int - builderUnitId = builderUnit->getId (); - CommandStateType - commandStateType = cst_None; - int - commandStateValue = -1; - - int - unitCommandGroupId = -1; - if (selection->getCount () > 1) - { - unitCommandGroupId = world->getNextCommandGroupId (); - } - - //give orders to all selected units - for (int i = 0; i < selection->getCount (); ++i) - { - const Unit * - unit = selection->getUnit (i); - - - std::pair < CommandResult, string > resultCur (crFailUndefined, - ""); - bool - canSubmitCommand = canSubmitCommandType (unit, commandType); - if (canSubmitCommand == true) - { - int - unitId = unit->getId (); - Vec2i - currPos = - world->getMap ()->computeDestPos (refPos, - unit-> - getPosNotThreadSafe (), - pos); - - Vec2i - usePos = currPos; - const CommandType * - useCommandtype = commandType; - if (dynamic_cast < - const BuildCommandType * >(commandType) != NULL) - { - usePos = pos; - if (builderUnit->getId () != unitId) - { - useCommandtype = - unit->getType ()-> - getFirstRepairCommand (unitType); - commandStateType = cst_linkedUnit; - commandStateValue = builderUnitId; - } - else - { - commandStateType = cst_None; - commandStateValue = -1; - } - } - - if (useCommandtype != NULL) - { - NetworkCommand - networkCommand (this->world, nctGiveCommand, unitId, - useCommandtype->getId (), usePos, - unitType->getId (), - (targetUnit != - NULL ? targetUnit->getId () : -1), - facing, tryQueue, commandStateType, - commandStateValue, unitCommandGroupId); - - //every unit is ordered to a the position - resultCur = pushNetworkCommand (&networkCommand); - } - } - - results.push_back (resultCur); - } - - return computeResult (results); - } - return std::pair < CommandResult, string > (crFailUndefined, ""); - } - - std::pair < CommandResult, - string > Commander::tryGiveCommand (const Unit * unit, - const CommandType * commandType, - const Vec2i & pos, - const UnitType * unitType, - CardinalDir facing, bool tryQueue, - Unit * targetUnit, - int unitGroupCommandId) const - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (this->pauseNetworkCommands == true) - { - return std::pair < CommandResult, string > (crFailUndefined, ""); - } - - Chrono - chrono; - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled) - chrono.start (); - - assert (this->world != NULL); - assert (unit != NULL); - assert (commandType != NULL); - assert (unitType != NULL); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - - std::pair < CommandResult, string > result (crFailUndefined, ""); - bool - canSubmitCommand = canSubmitCommandType (unit, commandType); - if (canSubmitCommand == true) - { - NetworkCommand - networkCommand (this->world, nctGiveCommand, unit->getId (), - commandType->getId (), pos, unitType->getId (), - (targetUnit != NULL ? targetUnit->getId () : -1), - facing, tryQueue, cst_None, -1, unitGroupCommandId); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - - result = pushNetworkCommand (&networkCommand); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - - return result; - } - - std::pair < CommandResult, - string > Commander::tryGiveCommand (const Selection * selection, - CommandClass commandClass, - const Vec2i & pos, - const Unit * targetUnit, - bool tryQueue) const - { - - if (this->pauseNetworkCommands == true) - { - return std::pair < CommandResult, string > (crFailUndefined, ""); - } - - std::pair < - CommandResult, - string > - result (crFailUndefined, ""); - if (selection->isEmpty () == false) - { - Vec2i - refPos, - currPos; - CommandResultContainer - results; - - refPos = world->getMap ()->computeRefPos (selection); - - int - unitCommandGroupId = -1; - if (selection->getCount () > 1) - { - unitCommandGroupId = world->getNextCommandGroupId (); - } - - //give orders to all selected units - for (int i = 0; i < selection->getCount (); ++i) - { - const Unit * - unit = selection->getUnit (i); - const CommandType * - ct = unit->getType ()->getFirstCtOfClass (commandClass); - if (ct != NULL) - { - std::pair < CommandResult, - string > resultCur (crFailUndefined, ""); - - bool - canSubmitCommand = canSubmitCommandType (unit, ct); - if (canSubmitCommand == true) - { - - int - targetId = - targetUnit == - NULL ? Unit::invalidId : targetUnit->getId (); - int - unitId = selection->getUnit (i)->getId (); - Vec2i - currPos = world->getMap ()->computeDestPos (refPos, - selection-> - getUnit - (i)-> - getPosNotThreadSafe - (), pos); - NetworkCommand - networkCommand (this->world, nctGiveCommand, - unitId, ct->getId (), currPos, -1, - targetId, -1, tryQueue, cst_None, -1, - unitCommandGroupId); - - //every unit is ordered to a different pos - resultCur = pushNetworkCommand (&networkCommand); - } - results.push_back (resultCur); - } - else - { - results.push_back (std::pair < CommandResult, - string > (crFailUndefined, "")); - } - } - return computeResult (results); - } - else - { - return std::pair < CommandResult, string > (crFailUndefined, ""); - } - } - - std::pair < CommandResult, - string > Commander::tryGiveCommand (const Selection * selection, - const CommandType * commandType, - const Vec2i & pos, - const Unit * targetUnit, - bool tryQueue) const - { - - if (this->pauseNetworkCommands == true) - { - return std::pair < CommandResult, string > (crFailUndefined, ""); - } - - std::pair < - CommandResult, - string > - result (crFailUndefined, ""); - - if (!selection->isEmpty () && commandType != NULL) - { - Vec2i - refPos; - CommandResultContainer - results; - - refPos = world->getMap ()->computeRefPos (selection); - - int - unitCommandGroupId = -1; - if (selection->getCount () > 1) - { - unitCommandGroupId = world->getNextCommandGroupId (); - } - - //give orders to all selected units - for (int i = 0; i < selection->getCount (); ++i) - { - const Unit * - unit = selection->getUnit (i); - assert (unit != NULL); - - std::pair < CommandResult, string > resultCur (crFailUndefined, - ""); - - bool - canSubmitCommand = canSubmitCommandType (unit, commandType); - if (canSubmitCommand == true) - { - int - targetId = - targetUnit == - NULL ? Unit::invalidId : targetUnit->getId (); - int - unitId = unit->getId (); - Vec2i - currPos = - world->getMap ()->computeDestPos (refPos, - unit-> - getPosNotThreadSafe (), - pos); - NetworkCommand - networkCommand (this->world, nctGiveCommand, unitId, - commandType->getId (), currPos, -1, - targetId, -1, tryQueue, cst_None, -1, - unitCommandGroupId); - - //every unit is ordered to a different position - resultCur = pushNetworkCommand (&networkCommand); - } - results.push_back (resultCur); - } - - return computeResult (results); - } - else - { - return std::pair < CommandResult, string > (crFailUndefined, ""); - } - } - -//auto command - std::pair < CommandResult, - string > Commander::tryGiveCommand (const Selection * selection, - const Vec2i & pos, - const Unit * targetUnit, - bool tryQueue, - int unitCommandGroupId) const - { - - if (this->pauseNetworkCommands == true) - { - return std::pair < CommandResult, string > (crFailUndefined, ""); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - std::pair < CommandResult, string > result (crFailUndefined, ""); - - if (selection->isEmpty () == false) - { - Vec2i - refPos, - currPos; - CommandResultContainer - results; - - if (unitCommandGroupId == -1 && selection->getCount () > 1) - { - unitCommandGroupId = world->getNextCommandGroupId (); - } - - //give orders to all selected units - refPos = world->getMap ()->computeRefPos (selection); - for (int i = 0; i < selection->getCount (); ++i) - { - //every unit is ordered to a different pos - const Unit * - unit = selection->getUnit (i); - assert (unit != NULL); - - currPos = - world->getMap ()->computeDestPos (refPos, - unit-> - getPosNotThreadSafe (), - pos); - - //get command type - const CommandType * - commandType = unit->computeCommandType (pos, targetUnit); - - //give commands - if (commandType != NULL) - { - int - targetId = - targetUnit == - NULL ? Unit::invalidId : targetUnit->getId (); - int - unitId = unit->getId (); - - std::pair < CommandResult, - string > resultCur (crFailUndefined, ""); - - bool - canSubmitCommand = - canSubmitCommandType (unit, commandType); - if (canSubmitCommand == true) - { - NetworkCommand - networkCommand (this->world, nctGiveCommand, - unitId, commandType->getId (), currPos, - -1, targetId, -1, tryQueue, cst_None, - -1, unitCommandGroupId); - resultCur = pushNetworkCommand (&networkCommand); - } - results.push_back (resultCur); - } - else if (unit->isMeetingPointSettable () == true) - { - NetworkCommand - command (this->world, nctSetMeetingPoint, - unit->getId (), -1, currPos, -1, -1, -1, false, - cst_None, -1, unitCommandGroupId); - - std::pair < CommandResult, string > resultCur = - pushNetworkCommand (&command); - results.push_back (resultCur); - } - else - { - results.push_back (std::pair < CommandResult, - string > (crFailUndefined, "")); - } - } - result = computeResult (results); - } - - return result; - } - - CommandResult - Commander::tryCancelCommand (const Selection * selection) const - { - if (this->pauseNetworkCommands == true) - { - return crFailUndefined; - } - - int - unitCommandGroupId = -1; - if (selection->getCount () > 1) - { - unitCommandGroupId = world->getNextCommandGroupId (); - } - - for (int i = 0; i < selection->getCount (); ++i) - { - NetworkCommand - command (this->world, nctCancelCommand, - selection->getUnit (i)->getId (), -1, Vec2i (0), -1, -1, - -1, false, cst_None, -1, unitCommandGroupId); - pushNetworkCommand (&command); - } - - return crSuccess; - } - - void - Commander::trySetMeetingPoint (const Unit * unit, const Vec2i & pos) const - { - if (this->pauseNetworkCommands == true) - { - return; - } - - NetworkCommand - command (this->world, nctSetMeetingPoint, unit->getId (), -1, pos); - pushNetworkCommand (&command); - } - - void - Commander::trySwitchTeam (const Faction * faction, int teamIndex) const - { - if (this->pauseNetworkCommands == true) - { - return; - } - - NetworkCommand - command (this->world, nctSwitchTeam, faction->getIndex (), teamIndex); - pushNetworkCommand (&command); - } - - void - Commander::trySwitchTeamVote (const Faction * faction, - SwitchTeamVote * vote) const - { - if (this->pauseNetworkCommands == true) - { - return; - } - - NetworkCommand - command (this->world, nctSwitchTeamVote, faction->getIndex (), - vote->factionIndex, Vec2i (0), vote->allowSwitchTeam); - pushNetworkCommand (&command); - } - - void - Commander::tryDisconnectNetworkPlayer (const Faction * faction, - int playerIndex) const - { - NetworkCommand - command (this->world, nctDisconnectNetworkPlayer, faction->getIndex (), - playerIndex); - pushNetworkCommand (&command); - } - - void - Commander::tryPauseGame (bool joinNetworkGame, bool clearCaches) const - { - NetworkCommand - command (this->world, nctPauseResume, 1); - command. - commandTypeId = (clearCaches == true ? 1 : 0); - command. - unitTypeId = (joinNetworkGame == true ? 1 : 0); - pushNetworkCommand (&command); - } - - void - Commander::tryResumeGame (bool joinNetworkGame, bool clearCaches) const - { - NetworkCommand - command (this->world, nctPauseResume, 0); - command. - commandTypeId = (clearCaches == true ? 1 : 0); - command. - unitTypeId = (joinNetworkGame == true ? 1 : 0); - pushNetworkCommand (&command); - } - - void - Commander::tryNetworkPlayerDisconnected (int factionIndex) const - { - //printf("tryNetworkPlayerDisconnected factionIndex: %d\n",factionIndex); - - //if(this->pauseNetworkCommands == true) { - // return; - //} - - NetworkCommand - command (this->world, nctPlayerStatusChange, factionIndex, - npst_Disconnected); - pushNetworkCommand (&command); - } - -// ==================== PRIVATE ==================== - - std::pair < - CommandResult, - string > - Commander::computeResult (const CommandResultContainer & results) const - { - std::pair < - CommandResult, - string > - result (crFailUndefined, ""); - switch (results.size ()) - { - case 0: - return std::pair < CommandResult, string > (crFailUndefined, ""); - case - 1: - return - results. - front (); - default:for (int i = 0; i < (int) results.size (); ++i) - { - if (results[i].first != crSuccess) - { - return std::pair < CommandResult, string > (crSomeFailed, - results[i]. - second); - } - } - break; - } - return std::pair < CommandResult, string > (crSuccess, ""); - } - - std::pair < CommandResult, - string > - Commander::pushNetworkCommand (const NetworkCommand * - networkCommand) const - { - GameNetworkInterface * - gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - std::pair < - CommandResult, - string > - result (crSuccess, ""); - - //validate unit - const Unit * - unit = NULL; - if (networkCommand->getNetworkCommandType () != nctSwitchTeam && - networkCommand->getNetworkCommandType () != nctSwitchTeamVote && - networkCommand->getNetworkCommandType () != nctPauseResume && - networkCommand->getNetworkCommandType () != nctPlayerStatusChange && - networkCommand->getNetworkCommandType () != - nctDisconnectNetworkPlayer) - { - unit = world->findUnitById (networkCommand->getUnitId ()); - if (unit == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s - %d] Command refers to non existent unit id = %d. Game out of synch.", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, networkCommand->getUnitId ()); - GameNetworkInterface * - gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - if (gameNetworkInterface != NULL) - { - char - szMsg[8096] = ""; - snprintf (szMsg, 8096, - "Player detected an error: Command refers to non existent unit id = %d. Game out of synch.", - networkCommand->getUnitId ()); - gameNetworkInterface-> - sendTextMessage (szMsg, -1, true, ""); - } - throw - megaglest_runtime_error (szBuf); - } - } - - //add the command to the interface - gameNetworkInterface->requestCommand (networkCommand); - - //calculate the result of the command - if (unit != NULL - && networkCommand->getNetworkCommandType () == nctGiveCommand) - { - //printf("In [%s::%s Line: %d] result.first = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result.first); - Command * - command = buildCommand (networkCommand); - result = unit->checkCommand (command); - delete - command; - } - return result; - } - - void - Commander::signalNetworkUpdate (Game * game) - { - updateNetwork (game); - } - - bool - Commander::getReplayCommandListForFrame (int worldFrameCount) - { - bool - haveReplyCommands = false; - if (replayCommandList.empty () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("worldFrameCount = %d replayCommandList.size() = " - MG_SIZE_T_SPECIFIER "\n", worldFrameCount, - replayCommandList.size ()); - - std::vector < NetworkCommand > replayList; - for (unsigned int i = 0; i < replayCommandList.size (); ++i) - { - std::pair < int, - NetworkCommand > & - cmd = replayCommandList[i]; - if (cmd.first <= worldFrameCount) - { - replayList.push_back (cmd.second); - haveReplyCommands = true; - } - } - if (haveReplyCommands == true) - { - replayCommandList.erase (replayCommandList.begin (), - replayCommandList.begin () + - replayList.size ()); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("worldFrameCount = %d GIVING COMMANDS replayList.size() = " - MG_SIZE_T_SPECIFIER "\n", worldFrameCount, - replayList.size ()); - for (int i = 0; i < (int) replayList.size (); ++i) - { - giveNetworkCommand (&replayList[i]); - } - GameNetworkInterface * - gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - gameNetworkInterface->setKeyframe (worldFrameCount); - } - } - return haveReplyCommands; - } - - bool - Commander::hasReplayCommandListForFrame () const - { - return (replayCommandList.empty () == false); - } - - int - Commander::getReplayCommandListForFrameCount () const - { - return (int) - replayCommandList. - size (); - } - - void - Commander::updateNetwork (Game * game) - { - if (world == NULL) - { - return; - } - NetworkManager & networkManager = NetworkManager::getInstance (); - - //check that this is a keyframe - if (game != NULL) - { - GameSettings * - gameSettings = game->getGameSettings (); - if (networkManager.isNetworkGame () == false || - (world->getFrameCount () % - gameSettings->getNetworkFramePeriod ()) == 0) - { - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] networkManager.isNetworkGame() = %d,world->getFrameCount() = %d, gameSettings->getNetworkFramePeriod() = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, - networkManager.isNetworkGame (), - world->getFrameCount (), - gameSettings-> - getNetworkFramePeriod ()); - - if (getReplayCommandListForFrame (world->getFrameCount ()) == - false) - { - GameNetworkInterface * - gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled) - perfTimer.start (); - //update the keyframe - gameNetworkInterface->updateKeyframe (world-> - getFrameCount ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled && perfTimer.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] gameNetworkInterface->updateKeyframe for %d took %lld msecs\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - world->getFrameCount (), - perfTimer.getMillis ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled) - perfTimer.start (); - //give pending commands - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("START process: %d network commands in frame: %d\n", - gameNetworkInterface->getPendingCommandCount (), - this->world->getFrameCount ()); - for (int i = 0; - i < gameNetworkInterface->getPendingCommandCount (); - ++i) - { - giveNetworkCommand (gameNetworkInterface-> - getPendingCommand (i)); - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("END process: %d network commands in frame: %d\n", - gameNetworkInterface->getPendingCommandCount (), - this->world->getFrameCount ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled && perfTimer.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] giveNetworkCommand took %lld msecs, PendingCommandCount = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - perfTimer.getMillis (), - gameNetworkInterface-> - getPendingCommandCount ()); - gameNetworkInterface->clearPendingCommands (); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Cleared network commands in frame: %d\n", - this->world->getFrameCount ()); - } - } - } - } - - void - Commander::addToReplayCommandList (NetworkCommand & command, - int worldFrameCount) - { - replayCommandList.push_back (make_pair (worldFrameCount, command)); - } - - void - Commander::giveNetworkCommand (NetworkCommand * networkCommand) const - { - Chrono - chrono; - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled) - chrono. - start (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [START]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - - - world-> - getGame ()-> - addNetworkCommandToReplayList (networkCommand, world->getFrameCount ()); - - networkCommand-> - preprocessNetworkCommand (this->world); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [after networkCommand->preprocessNetworkCommand]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - - bool - commandWasHandled = false; - // Handle special commands first (that just use network command members as placeholders) - switch (networkCommand->getNetworkCommandType ()) - { - case nctSwitchTeam: - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctSwitchTeam\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - commandWasHandled = true; - int - factionIndex = networkCommand->getUnitId (); - int - newTeam = networkCommand->getCommandTypeId (); - - // Auto join empty team or ask players to join - bool - autoJoinTeam = true; - for (int i = 0; i < world->getFactionCount (); ++i) - { - if (newTeam == world->getFaction (i)->getTeam ()) - { - autoJoinTeam = false; - break; - } - } - - if (autoJoinTeam == true) - { - Faction * - faction = world->getFaction (factionIndex); - int - oldTeam = faction->getTeam (); - faction->setTeam (newTeam); - GameSettings * - settings = world->getGameSettingsPtr (); - settings->setTeam (factionIndex, newTeam); - world->getStats ()->setTeam (factionIndex, newTeam); - - if (factionIndex == world->getThisFactionIndex ()) - { - world->setThisTeamIndex (newTeam); - GameNetworkInterface * - gameNetworkInterface = - NetworkManager::getInstance (). - getGameNetworkInterface (); - if (gameNetworkInterface != NULL) - { - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - settings->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); - ++i) - { - char - szMsg[8096] = ""; - if (lang. - hasString ("PlayerSwitchedTeam", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang. - getString ("PlayerSwitchedTeam", - languageList[i]). - c_str (), - settings-> - getNetworkPlayerName (factionIndex). - c_str (), oldTeam, newTeam); - } - else - { - snprintf (szMsg, 8096, - "Player %s switched from team# %d to team# %d.", - settings-> - getNetworkPlayerName (factionIndex). - c_str (), oldTeam, newTeam); - } - bool - localEcho = - lang.isLanguageLocal (languageList[i]); - gameNetworkInterface->sendTextMessage (szMsg, -1, - localEcho, - languageList - [i]); - } - } - world->getGame ()->reInitGUI (); - } - } - else - { - for (int i = 0; i < world->getFactionCount (); ++i) - { - if (newTeam == world->getFaction (i)->getTeam ()) - { - Faction * - faction = world->getFaction (factionIndex); - - SwitchTeamVote - vote; - vote.factionIndex = factionIndex; - vote.allowSwitchTeam = false; - vote.oldTeam = faction->getTeam (); - vote.newTeam = newTeam; - vote.voted = false; - - world->getFaction (i)->setSwitchTeamVote (vote); - } - } - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [after unit->setMeetingPos]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctSetMeetingPoint\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - break; - - case nctSwitchTeamVote: - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctSwitchTeamVote\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - commandWasHandled = true; - - int - votingFactionIndex = networkCommand->getUnitId (); - int - factionIndex = networkCommand->getCommandTypeId (); - bool - allowSwitchTeam = networkCommand->getUnitTypeId () != 0; - - Faction * - faction = world->getFaction (votingFactionIndex); - - SwitchTeamVote * - vote = faction->getSwitchTeamVote (factionIndex); - if (vote == NULL) - { - throw - megaglest_runtime_error ("vote == NULL"); - } - vote->voted = true; - vote->allowSwitchTeam = allowSwitchTeam; - - // Join the new team if > 50 % said yes - int - newTeamTotalMemberCount = 0; - int - newTeamVotedYes = 0; - int - newTeamVotedNo = 0; - - for (int i = 0; i < world->getFactionCount (); ++i) - { - if (vote->newTeam == world->getFaction (i)->getTeam ()) - { - newTeamTotalMemberCount++; - - SwitchTeamVote * - teamVote = - world->getFaction (i)->getSwitchTeamVote (factionIndex); - if (teamVote != NULL && teamVote->voted == true) - { - if (teamVote->allowSwitchTeam == true) - { - newTeamVotedYes++; - } - else - { - newTeamVotedNo++; - } - } - } - } - - // If > 50% of team vote yes, switch th eplayers team - if (newTeamTotalMemberCount > 0 && newTeamVotedYes > 0 && - static_cast < float >(newTeamVotedYes) / static_cast < - float >(newTeamTotalMemberCount) > 0.5) - { - Faction * - faction = world->getFaction (factionIndex); - int - oldTeam = faction->getTeam (); - faction->setTeam (vote->newTeam); - GameSettings * - settings = world->getGameSettingsPtr (); - settings->setTeam (factionIndex, vote->newTeam); - world->getStats ()->setTeam (factionIndex, vote->newTeam); - - if (factionIndex == world->getThisFactionIndex ()) - { - world->setThisTeamIndex (vote->newTeam); - GameNetworkInterface * - gameNetworkInterface = - NetworkManager::getInstance (). - getGameNetworkInterface (); - if (gameNetworkInterface != NULL) - { - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - settings->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); - ++i) - { - char - szMsg[8096] = ""; - if (lang. - hasString ("PlayerSwitchedTeam", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang. - getString ("PlayerSwitchedTeam", - languageList[i]). - c_str (), - settings-> - getNetworkPlayerName (factionIndex). - c_str (), oldTeam, vote->newTeam); - } - else - { - snprintf (szMsg, 8096, - "Player %s switched from team# %d to team# %d.", - settings-> - getNetworkPlayerName (factionIndex). - c_str (), oldTeam, vote->newTeam); - } - bool - localEcho = - lang.isLanguageLocal (languageList[i]); - gameNetworkInterface->sendTextMessage (szMsg, -1, - localEcho, - languageList - [i]); - } - } - world->getGame ()->reInitGUI (); - } - } - else if (newTeamTotalMemberCount == - (newTeamVotedYes + newTeamVotedNo)) - { - if (factionIndex == world->getThisFactionIndex ()) - { - GameSettings * - settings = world->getGameSettingsPtr (); - Faction * - faction = world->getFaction (factionIndex); - int - oldTeam = faction->getTeam (); - - GameNetworkInterface * - gameNetworkInterface = - NetworkManager::getInstance (). - getGameNetworkInterface (); - if (gameNetworkInterface != NULL) - { - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - settings->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); - ++i) - { - char - szMsg[8096] = ""; - if (lang. - hasString ("PlayerSwitchedTeamDenied", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang. - getString - ("PlayerSwitchedTeamDenied", - languageList[i]).c_str (), - settings-> - getNetworkPlayerName (factionIndex). - c_str (), oldTeam, vote->newTeam); - } - else - { - snprintf (szMsg, 8096, - "Player %s was denied the request to switch from team# %d to team# %d.", - settings-> - getNetworkPlayerName (factionIndex). - c_str (), oldTeam, vote->newTeam); - } - bool - localEcho = - lang.isLanguageLocal (languageList[i]); - gameNetworkInterface->sendTextMessage (szMsg, -1, - localEcho, - languageList - [i]); - } - } - } - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [after unit->setMeetingPos]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctSetMeetingPoint\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - break; - - case nctDisconnectNetworkPlayer: - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctDisconnectNetworkPlayer\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - commandWasHandled = true; - - NetworkManager & networkManager = NetworkManager::getInstance (); - NetworkRole - role = networkManager.getNetworkRole (); - //GameSettings *settings = world->getGameSettingsPtr(); - - if (role == nrServer) - { - //int factionIndex = networkCommand->getUnitId(); - int - playerIndex = networkCommand->getCommandTypeId (); - - GameNetworkInterface * - gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - if (gameNetworkInterface != NULL) - { - ServerInterface * - server = networkManager.getServerInterface (); - if (server != NULL - && server->isClientConnected (playerIndex) == true) - { - - MutexSafeWrapper - safeMutex (server->getSlotMutex (playerIndex), - CODE_AT_LINE); - ConnectionSlot * - slot = server->getSlot (playerIndex, false); - if (slot != NULL) - { - safeMutex.ReleaseLock (); - NetworkMessageQuit - networkMessageQuit; - slot->sendMessage (&networkMessageQuit); - sleep (5); - - //printf("Sending nctDisconnectNetworkPlayer\n"); - server = - networkManager.getServerInterface (false); - if (server != NULL) - { - MutexSafeWrapper - safeMutex2 (server-> - getSlotMutex (playerIndex), - CODE_AT_LINE); - slot = server->getSlot (playerIndex, false); - if (slot != NULL) - { - safeMutex2.ReleaseLock (); - slot->close (); - } - } - } - } - } - } - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctDisconnectNetworkPlayer\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - break; - - case nctPauseResume: - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctPauseResume\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - commandWasHandled = true; - - bool - pauseGame = networkCommand->getUnitId () != 0; - bool - clearCaches = (networkCommand->getCommandTypeId () == 1); - bool - joinNetworkGame = (networkCommand->getUnitTypeId () == 1); - Game * - game = this->world->getGame (); - - //printf("nctPauseResume pauseGame = %d\n",pauseGame); - game->setPaused (pauseGame, true, clearCaches, joinNetworkGame); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctPauseResume\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - break; - - case nctPlayerStatusChange: - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctPlayerStatusChange\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - commandWasHandled = true; - - int - factionIndex = networkCommand->getUnitId (); - int - playerStatus = networkCommand->getCommandTypeId (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "nctPlayerStatusChange factionIndex = %d playerStatus = %d\n", - factionIndex, playerStatus); - - //printf("#1 nctPlayerStatusChange factionIndex = %d playerStatus = %d\n",factionIndex,playerStatus); - - GameSettings * - settings = world->getGameSettingsPtr (); - if (playerStatus == npst_Disconnected) - { - //printf("Commander nctPlayerStatusChange factionIndex: %d\n",factionIndex); - - settings->setNetworkPlayerStatuses (factionIndex, - npst_Disconnected); - - //printf("nctPlayerStatusChange -> faction->getPersonalityType() = %d index [%d] control [%d] networkstatus [%d]\n", - // world->getFaction(factionIndex)->getPersonalityType(),world->getFaction(factionIndex)->getIndex(),world->getFaction(factionIndex)->getControlType(),settings->getNetworkPlayerStatuses(factionIndex)); - - //printf("#2 nctPlayerStatusChange factionIndex = %d playerStatus = %d\n",factionIndex,playerStatus); - settings->setFactionControl (factionIndex, ctCpuUltra); - settings->setResourceMultiplierIndex (factionIndex, - settings-> - getFallbackCpuMultiplier - ()); - //Game *game = this->world->getGame(); - //game->get - Faction * - faction = this->world->getFaction (factionIndex); - faction->setControlType (ctCpuUltra); - - if (!world->getGame ()->getGameOver () - && !this->world->getGame ()-> - factionLostGame (factionIndex)) - { - // use the fallback multiplier here - - // mark player as "leaver" - this->world->getStats ()-> - setPlayerLeftBeforeEnd (factionIndex, true); - // set disconnect time for endgame stats - this->world->getStats ()->setTimePlayerLeft (factionIndex, - this->world-> - getStats ()-> - getFramesToCalculatePlaytime - ()); - } - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctPlayerStatusChange\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - break; - - } - - if (commandWasHandled == false) - { - Unit * - unit = world->findUnitById (networkCommand->getUnitId ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [after world->findUnitById]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("Running command NetworkCommandType = %d, unitid = %d [%p] factionindex = %d\n", - networkCommand->getNetworkCommandType (), - networkCommand->getUnitId (), unit, - (unit != NULL ? unit->getFactionIndex () : -1)); - //execute command, if unit is still alive - if (unit != NULL) - { - switch (networkCommand->getNetworkCommandType ()) - { - case nctGiveCommand: - { - assert (networkCommand->getCommandTypeId () != - CommandType::invalidId); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctGiveCommand networkCommand->getUnitId() = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - networkCommand->getUnitId ()); - - Command * - command = buildCommand (networkCommand); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [after buildCommand]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - chrono.getMillis ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] command = %p\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - command); - - unit->giveCommand (command, - (networkCommand->getWantQueue () != - 0)); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [after unit->giveCommand]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - chrono.getMillis ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctGiveCommand networkCommand->getUnitId() = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - networkCommand->getUnitId ()); - } - break; - case nctCancelCommand: - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctCancelCommand\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__); - - unit->cancelCommand (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [after unit->cancelCommand]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - chrono.getMillis ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctCancelCommand\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__); - } - break; - case nctSetMeetingPoint: - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctSetMeetingPoint\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__); - - unit->setMeetingPos (networkCommand->getPosition ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [after unit->setMeetingPos]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - chrono.getMillis ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found nctSetMeetingPoint\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__); - } - break; - - default: - assert (false); - break; - } - } - else - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] NULL Unit for id = %d, networkCommand->getNetworkCommandType() = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, - networkCommand->getUnitId (), - networkCommand-> - getNetworkCommandType ()); - } - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld [END]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - } - -// Reconstruct a network command received. - Command * - Commander::buildCommand (const NetworkCommand * networkCommand) const - { - // Check a new command is actually being given (and not a cancel command, switch team etc.). - assert (networkCommand->getNetworkCommandType () == nctGiveCommand); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] networkCommand [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - networkCommand->toString ().c_str ()); - - // Check there is a world. - if (world == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] world == NULL for unit with id: %d", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, networkCommand->getUnitId ()); - throw - megaglest_runtime_error (szBuf); - } - - // Get the unit. - Unit * - target = NULL; - const CommandType * - ct = NULL; - const Unit * - unit = world->findUnitById (networkCommand->getUnitId ()); - - // Validate unit is in game. - if (unit == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] Can not find unit with id: %d. Game out of synch.", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, networkCommand->getUnitId ()); - SystemFlags::OutputDebug (SystemFlags::debugError, "%s\n", szBuf); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", - szBuf); - - GameNetworkInterface * - gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - if (gameNetworkInterface != NULL) - { - char - szMsg[8096] = ""; - snprintf (szMsg, 8096, - "Player detected an error: Can not find unit with id: %d. Game out of synch.", - networkCommand->getUnitId ()); - gameNetworkInterface->sendTextMessage (szMsg, -1, true, ""); - } - - throw - megaglest_runtime_error (szBuf); - } - - // Get the command type for the unit. - ct = - unit->getType ()->findCommandTypeById (networkCommand-> - getCommandTypeId ()); - - // Check that the unit from the network command is the same faction as the unit in the local game. - if (unit->getFaction ()->getIndex () != - networkCommand->getUnitFactionIndex ()) - { - - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d]\nUnit / Faction mismatch for network command = [%s]\n%s\nfor unit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.", - __FILE__, __FUNCTION__, __LINE__, - networkCommand->toString ().c_str (), - unit->getType ()->getCommandTypeListDesc ().c_str (), - unit->getId (), unit->getFullName (false).c_str (), - unit->getDesc (false).c_str (), - unit->getFaction ()->getIndex ()); - - SystemFlags::OutputDebug (SystemFlags::debugError, "%s\n", szBuf); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", - szBuf); - //std::string worldLog = world->DumpWorldToLog(); - world->DumpWorldToLog (); - - // Broadcast the error if player is still connected and print locally. - GameNetworkInterface * - gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - if (gameNetworkInterface != NULL - && gameNetworkInterface->isConnected () == true) - { - char - szMsg[8096] = ""; - snprintf (szMsg, 8096, - "Player detected an error: Unit / Faction mismatch for unitId: %d", - networkCommand->getUnitId ()); - gameNetworkInterface->sendTextMessage (szMsg, -1, true, ""); - snprintf (szMsg, 8096, - "Local faction index = %d, remote index = %d. Game out of synch.", - unit->getFaction ()->getIndex (), - networkCommand->getUnitFactionIndex ()); - gameNetworkInterface->sendTextMessage (szMsg, -1, true, ""); - - } - - // Else if it's a network game but the user disconnected, print the error locally only. - else if (gameNetworkInterface != NULL) - { - char - szMsg[8096] = ""; - snprintf (szMsg, 8096, - "Player detected an error: Connection lost, possible Unit / Faction mismatch for unitId: %d", - networkCommand->getUnitId ()); - gameNetworkInterface->sendTextMessage (szMsg, -1, true, ""); - snprintf (szMsg, 8096, - "Local faction index = %d, remote index = %d. Game out of synch.", - unit->getFaction ()->getIndex (), - networkCommand->getUnitFactionIndex ()); - gameNetworkInterface->sendTextMessage (szMsg, -1, true, ""); - } - - // Kill the game. - std::string sError = - "Error [#1]: Game is out of sync (Unit / Faction mismatch)\nplease check log files for details."; - throw - megaglest_runtime_error (sError); - } - - const UnitType * - unitType = - world->findUnitTypeById (unit->getFaction ()->getType (), - networkCommand->getUnitTypeId ()); - - // debug test! - //throw megaglest_runtime_error("Test missing command type!"); - - //validate command type - - // !!!Test out of synch behaviour - //ct = NULL; - - // Check if the command was for the unit before it morphed, if so cancel it. - bool - isCancelPreMorphCommand = false; - if (ct == NULL && unit->getPreMorphType () != NULL) - { - const CommandType * - ctPreMorph = - unit->getPreMorphType ()->findCommandTypeById (networkCommand-> - getCommandTypeId - ()); - if (ctPreMorph != NULL) - { - ct = unit->getType ()->getFirstCtOfClass (ccStop); - isCancelPreMorphCommand = true; - } - } - - // Throw an error if a valid command for the unit is still not found. - if (ct == NULL) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d]\nCan not find command type for network command = [%s]\n%s\nfor unit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nUnit Type Info:\n[%s]\nNetwork unit type:\n[%s]\nisCancelPreMorphCommand: %d\nGame out of synch.", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, - networkCommand->toString ().c_str (), - unit->getType ()->getCommandTypeListDesc ().c_str (), - unit->getId (), unit->getFullName (false).c_str (), - unit->getDesc (false).c_str (), - unit->getFaction ()->getIndex (), - unit->getType ()->toString ().c_str (), - (unitType != - NULL ? unitType->getName (false).c_str () : "null"), - isCancelPreMorphCommand); - - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", szBuf); - SystemFlags::OutputDebug (SystemFlags::debugError, "%s\n", szBuf); - world->DumpWorldToLog (); - - GameNetworkInterface * - gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - if (gameNetworkInterface != NULL) - { - char - szMsg[8096] = ""; - snprintf (szMsg, 8096, - "Player detected an error: Can not find command type: %d for unitId: %d [%s]. isCancelPreMorphCommand: %d Game out of synch.", - networkCommand->getCommandTypeId (), - networkCommand->getUnitId (), - (unitType != - NULL ? unitType->getName (false).c_str () : "null"), - isCancelPreMorphCommand); - gameNetworkInterface->sendTextMessage (szMsg, -1, true, ""); - } - - std::string sError = - "Error [#3]: Game is out of sync, please check log files for details."; - //abort(); - throw - megaglest_runtime_error (sError); - } - - CardinalDir - facing; - // Get direction of the command target unit. - if (isCancelPreMorphCommand == false) - { - // If target is a building. - if (ct->getClass () == ccBuild) - { - // Check the target building ID is valid. If not, throw an error. - /// TODO: What is happening here? The error returned does not match the condition. Why is there a constant of 4? - if (networkCommand->getTargetId () < 0 - || networkCommand->getTargetId () >= 4) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "networkCommand->getTargetId() >= 0 && networkCommand->getTargetId() < 4, [%s]", - networkCommand->toString ().c_str ()); - throw - megaglest_runtime_error (szBuf); - } - facing = CardinalDir (networkCommand->getTargetId ()); - } - // Get the target unit if the ID is valid. - else if (networkCommand->getTargetId () != Unit::invalidId) - { - target = world->findUnitById (networkCommand->getTargetId ()); - } - } - - // Create the command. - Command * - command = NULL; - if (isCancelPreMorphCommand == false) - { - if (unitType != NULL) - { - command = - new Command (ct, networkCommand->getPosition (), unitType, - facing); - } - else if (target == NULL) - { - command = new Command (ct, networkCommand->getPosition ()); - } - else - { - command = new Command (ct, target); - } - } - else - { - command = new Command (ct, NULL); - } - - // Add in any special state - CommandStateType - commandStateType = networkCommand->getCommandStateType (); - int - commandStateValue = networkCommand->getCommandStateValue (); - - command->setStateType (commandStateType); - command->setStateValue (commandStateValue); - command->setUnitCommandGroupId (networkCommand-> - getUnitCommandGroupId ()); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - //issue command - return command; - } - - } + Glest { + namespace + Game { + + // ===================================================== + // class Commander + // ===================================================== + Commander::Commander() { + this->world = NULL; + this-> + pauseNetworkCommands = false; + } + + Commander::~ + Commander() { + } + + void + Commander::init(World * world) { + this->world = world; + } + + bool + Commander::canSubmitCommandType(const Unit * unit, + const CommandType * commandType) const { + bool + canSubmitCommand = true; + const MorphCommandType * + mct = dynamic_cast (commandType); + if (mct && unit->getCommandSize() > 0) { + Command * + cur_command = unit->getCurrCommand(); + if (cur_command != NULL) { + const MorphCommandType * + cur_mct = dynamic_cast (cur_command->getCommandType()); + if (cur_mct && unit->getCurrSkill() + && unit->getCurrSkill()->getClass() == scMorph) { + const UnitType * + morphUnitType = mct->getMorphUnit(); + const UnitType * + cur_morphUnitType = cur_mct->getMorphUnit(); + + if (morphUnitType != NULL && cur_morphUnitType != NULL + && morphUnitType->getId() == + cur_morphUnitType->getId()) { + canSubmitCommand = false; + } + } + } + } + return + canSubmitCommand; + } + + std::pair < CommandResult, + string > Commander::tryGiveCommand(const Selection * selection, + const CommandType * commandType, + const Vec2i & pos, + const UnitType * unitType, + CardinalDir facing, bool tryQueue, + Unit * targetUnit) const { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (this->pauseNetworkCommands == true) { + return std::pair < CommandResult, string >(crFailUndefined, ""); + } + + std::pair < + CommandResult, + string > + result(crFailUndefined, ""); + if (selection->isEmpty() == false && commandType != NULL) { + Vec2i + refPos; + CommandResultContainer + results; + + refPos = world->getMap()->computeRefPos(selection); + + const Unit * + builderUnit = + world->getMap()->findClosestUnitToPos(selection, pos, unitType); + + int + builderUnitId = builderUnit->getId(); + CommandStateType + commandStateType = cst_None; + int + commandStateValue = -1; + + int + unitCommandGroupId = -1; + if (selection->getCount() > 1) { + unitCommandGroupId = world->getNextCommandGroupId(); + } + + //give orders to all selected units + for (int i = 0; i < selection->getCount(); ++i) { + const Unit * + unit = selection->getUnit(i); + + + std::pair < CommandResult, string > resultCur(crFailUndefined, + ""); + bool + canSubmitCommand = canSubmitCommandType(unit, commandType); + if (canSubmitCommand == true) { + int + unitId = unit->getId(); + Vec2i + currPos = + world->getMap()->computeDestPos(refPos, + unit-> + getPosNotThreadSafe(), + pos); + + Vec2i + usePos = currPos; + const CommandType * + useCommandtype = commandType; + if (dynamic_cast < + const BuildCommandType *>(commandType) != NULL) { + usePos = pos; + if (builderUnit->getId() != unitId) { + useCommandtype = + unit->getType()-> + getFirstRepairCommand(unitType); + commandStateType = cst_linkedUnit; + commandStateValue = builderUnitId; + } else { + commandStateType = cst_None; + commandStateValue = -1; + } + } + + if (useCommandtype != NULL) { + NetworkCommand + networkCommand(this->world, nctGiveCommand, unitId, + useCommandtype->getId(), usePos, + unitType->getId(), + (targetUnit != + NULL ? targetUnit->getId() : -1), + facing, tryQueue, commandStateType, + commandStateValue, unitCommandGroupId); + + //every unit is ordered to a the position + resultCur = pushNetworkCommand(&networkCommand); + } + } + + results.push_back(resultCur); + } + + return computeResult(results); + } + return std::pair < CommandResult, string >(crFailUndefined, ""); + } + + std::pair < CommandResult, + string > Commander::tryGiveCommand(const Unit * unit, + const CommandType * commandType, + const Vec2i & pos, + const UnitType * unitType, + CardinalDir facing, bool tryQueue, + Unit * targetUnit, + int unitGroupCommandId) const { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (this->pauseNetworkCommands == true) { + return std::pair < CommandResult, string >(crFailUndefined, ""); + } + + Chrono + chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled) + chrono.start(); + + assert(this->world != NULL); + assert(unit != NULL); + assert(commandType != NULL); + assert(unitType != NULL); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + + std::pair < CommandResult, string > result(crFailUndefined, ""); + bool + canSubmitCommand = canSubmitCommandType(unit, commandType); + if (canSubmitCommand == true) { + NetworkCommand + networkCommand(this->world, nctGiveCommand, unit->getId(), + commandType->getId(), pos, unitType->getId(), + (targetUnit != NULL ? targetUnit->getId() : -1), + facing, tryQueue, cst_None, -1, unitGroupCommandId); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + + result = pushNetworkCommand(&networkCommand); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + + return result; + } + + std::pair < CommandResult, + string > Commander::tryGiveCommand(const Selection * selection, + CommandClass commandClass, + const Vec2i & pos, + const Unit * targetUnit, + bool tryQueue) const { + + if (this->pauseNetworkCommands == true) { + return std::pair < CommandResult, string >(crFailUndefined, ""); + } + + std::pair < + CommandResult, + string > + result(crFailUndefined, ""); + if (selection->isEmpty() == false) { + Vec2i + refPos, + currPos; + CommandResultContainer + results; + + refPos = world->getMap()->computeRefPos(selection); + + int + unitCommandGroupId = -1; + if (selection->getCount() > 1) { + unitCommandGroupId = world->getNextCommandGroupId(); + } + + //give orders to all selected units + for (int i = 0; i < selection->getCount(); ++i) { + const Unit * + unit = selection->getUnit(i); + const CommandType * + ct = unit->getType()->getFirstCtOfClass(commandClass); + if (ct != NULL) { + std::pair < CommandResult, + string > resultCur(crFailUndefined, ""); + + bool + canSubmitCommand = canSubmitCommandType(unit, ct); + if (canSubmitCommand == true) { + + int + targetId = + targetUnit == + NULL ? Unit::invalidId : targetUnit->getId(); + int + unitId = selection->getUnit(i)->getId(); + Vec2i + currPos = world->getMap()->computeDestPos(refPos, + selection-> + getUnit + (i)-> + getPosNotThreadSafe + (), pos); + NetworkCommand + networkCommand(this->world, nctGiveCommand, + unitId, ct->getId(), currPos, -1, + targetId, -1, tryQueue, cst_None, -1, + unitCommandGroupId); + + //every unit is ordered to a different pos + resultCur = pushNetworkCommand(&networkCommand); + } + results.push_back(resultCur); + } else { + results.push_back(std::pair < CommandResult, + string >(crFailUndefined, "")); + } + } + return computeResult(results); + } else { + return std::pair < CommandResult, string >(crFailUndefined, ""); + } + } + + std::pair < CommandResult, + string > Commander::tryGiveCommand(const Selection * selection, + const CommandType * commandType, + const Vec2i & pos, + const Unit * targetUnit, + bool tryQueue) const { + + if (this->pauseNetworkCommands == true) { + return std::pair < CommandResult, string >(crFailUndefined, ""); + } + + std::pair < + CommandResult, + string > + result(crFailUndefined, ""); + + if (!selection->isEmpty() && commandType != NULL) { + Vec2i + refPos; + CommandResultContainer + results; + + refPos = world->getMap()->computeRefPos(selection); + + int + unitCommandGroupId = -1; + if (selection->getCount() > 1) { + unitCommandGroupId = world->getNextCommandGroupId(); + } + + //give orders to all selected units + for (int i = 0; i < selection->getCount(); ++i) { + const Unit * + unit = selection->getUnit(i); + assert(unit != NULL); + + std::pair < CommandResult, string > resultCur(crFailUndefined, + ""); + + bool + canSubmitCommand = canSubmitCommandType(unit, commandType); + if (canSubmitCommand == true) { + int + targetId = + targetUnit == + NULL ? Unit::invalidId : targetUnit->getId(); + int + unitId = unit->getId(); + Vec2i + currPos = + world->getMap()->computeDestPos(refPos, + unit-> + getPosNotThreadSafe(), + pos); + NetworkCommand + networkCommand(this->world, nctGiveCommand, unitId, + commandType->getId(), currPos, -1, + targetId, -1, tryQueue, cst_None, -1, + unitCommandGroupId); + + //every unit is ordered to a different position + resultCur = pushNetworkCommand(&networkCommand); + } + results.push_back(resultCur); + } + + return computeResult(results); + } else { + return std::pair < CommandResult, string >(crFailUndefined, ""); + } + } + + //auto command + std::pair < CommandResult, + string > Commander::tryGiveCommand(const Selection * selection, + const Vec2i & pos, + const Unit * targetUnit, + bool tryQueue, + int unitCommandGroupId) const { + + if (this->pauseNetworkCommands == true) { + return std::pair < CommandResult, string >(crFailUndefined, ""); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + std::pair < CommandResult, string > result(crFailUndefined, ""); + + if (selection->isEmpty() == false) { + Vec2i + refPos, + currPos; + CommandResultContainer + results; + + if (unitCommandGroupId == -1 && selection->getCount() > 1) { + unitCommandGroupId = world->getNextCommandGroupId(); + } + + //give orders to all selected units + refPos = world->getMap()->computeRefPos(selection); + for (int i = 0; i < selection->getCount(); ++i) { + //every unit is ordered to a different pos + const Unit * + unit = selection->getUnit(i); + assert(unit != NULL); + + currPos = + world->getMap()->computeDestPos(refPos, + unit-> + getPosNotThreadSafe(), + pos); + + //get command type + const CommandType * + commandType = unit->computeCommandType(pos, targetUnit); + + //give commands + if (commandType != NULL) { + int + targetId = + targetUnit == + NULL ? Unit::invalidId : targetUnit->getId(); + int + unitId = unit->getId(); + + std::pair < CommandResult, + string > resultCur(crFailUndefined, ""); + + bool + canSubmitCommand = + canSubmitCommandType(unit, commandType); + if (canSubmitCommand == true) { + NetworkCommand + networkCommand(this->world, nctGiveCommand, + unitId, commandType->getId(), currPos, + -1, targetId, -1, tryQueue, cst_None, + -1, unitCommandGroupId); + resultCur = pushNetworkCommand(&networkCommand); + } + results.push_back(resultCur); + } else if (unit->isMeetingPointSettable() == true) { + NetworkCommand + command(this->world, nctSetMeetingPoint, + unit->getId(), -1, currPos, -1, -1, -1, false, + cst_None, -1, unitCommandGroupId); + + std::pair < CommandResult, string > resultCur = + pushNetworkCommand(&command); + results.push_back(resultCur); + } else { + results.push_back(std::pair < CommandResult, + string >(crFailUndefined, "")); + } + } + result = computeResult(results); + } + + return result; + } + + CommandResult + Commander::tryCancelCommand(const Selection * selection) const { + if (this->pauseNetworkCommands == true) { + return crFailUndefined; + } + + int + unitCommandGroupId = -1; + if (selection->getCount() > 1) { + unitCommandGroupId = world->getNextCommandGroupId(); + } + + for (int i = 0; i < selection->getCount(); ++i) { + NetworkCommand + command(this->world, nctCancelCommand, + selection->getUnit(i)->getId(), -1, Vec2i(0), -1, -1, + -1, false, cst_None, -1, unitCommandGroupId); + pushNetworkCommand(&command); + } + + return crSuccess; + } + + void + Commander::trySetMeetingPoint(const Unit * unit, const Vec2i & pos) const { + if (this->pauseNetworkCommands == true) { + return; + } + + NetworkCommand + command(this->world, nctSetMeetingPoint, unit->getId(), -1, pos); + pushNetworkCommand(&command); + } + + void + Commander::trySwitchTeam(const Faction * faction, int teamIndex) const { + if (this->pauseNetworkCommands == true) { + return; + } + + NetworkCommand + command(this->world, nctSwitchTeam, faction->getIndex(), teamIndex); + pushNetworkCommand(&command); + } + + void + Commander::trySwitchTeamVote(const Faction * faction, + SwitchTeamVote * vote) const { + if (this->pauseNetworkCommands == true) { + return; + } + + NetworkCommand + command(this->world, nctSwitchTeamVote, faction->getIndex(), + vote->factionIndex, Vec2i(0), vote->allowSwitchTeam); + pushNetworkCommand(&command); + } + + void + Commander::tryDisconnectNetworkPlayer(const Faction * faction, + int playerIndex) const { + NetworkCommand + command(this->world, nctDisconnectNetworkPlayer, faction->getIndex(), + playerIndex); + pushNetworkCommand(&command); + } + + void + Commander::tryPauseGame(bool joinNetworkGame, bool clearCaches) const { + NetworkCommand + command(this->world, nctPauseResume, 1); + command. + commandTypeId = (clearCaches == true ? 1 : 0); + command. + unitTypeId = (joinNetworkGame == true ? 1 : 0); + pushNetworkCommand(&command); + } + + void + Commander::tryResumeGame(bool joinNetworkGame, bool clearCaches) const { + NetworkCommand + command(this->world, nctPauseResume, 0); + command. + commandTypeId = (clearCaches == true ? 1 : 0); + command. + unitTypeId = (joinNetworkGame == true ? 1 : 0); + pushNetworkCommand(&command); + } + + void + Commander::tryNetworkPlayerDisconnected(int factionIndex) const { + //printf("tryNetworkPlayerDisconnected factionIndex: %d\n",factionIndex); + + //if(this->pauseNetworkCommands == true) { + // return; + //} + + NetworkCommand + command(this->world, nctPlayerStatusChange, factionIndex, + npst_Disconnected); + pushNetworkCommand(&command); + } + + // ==================== PRIVATE ==================== + + std::pair < + CommandResult, + string > + Commander::computeResult(const CommandResultContainer & results) const { + std::pair < + CommandResult, + string > + result(crFailUndefined, ""); + switch (results.size()) { + case 0: + return std::pair < CommandResult, string >(crFailUndefined, ""); + case + 1: + return + results. + front(); + default:for (int i = 0; i < (int) results.size(); ++i) { + if (results[i].first != crSuccess) { + return std::pair < CommandResult, string >(crSomeFailed, + results[i]. + second); + } + } + break; + } + return std::pair < CommandResult, string >(crSuccess, ""); + } + + std::pair < CommandResult, + string > + Commander::pushNetworkCommand(const NetworkCommand * + networkCommand) const { + GameNetworkInterface * + gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + std::pair < + CommandResult, + string > + result(crSuccess, ""); + + //validate unit + const Unit * + unit = NULL; + if (networkCommand->getNetworkCommandType() != nctSwitchTeam && + networkCommand->getNetworkCommandType() != nctSwitchTeamVote && + networkCommand->getNetworkCommandType() != nctPauseResume && + networkCommand->getNetworkCommandType() != nctPlayerStatusChange && + networkCommand->getNetworkCommandType() != + nctDisconnectNetworkPlayer) { + unit = world->findUnitById(networkCommand->getUnitId()); + if (unit == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s - %d] Command refers to non existent unit id = %d. Game out of synch.", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, networkCommand->getUnitId()); + GameNetworkInterface * + gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + if (gameNetworkInterface != NULL) { + char + szMsg[8096] = ""; + snprintf(szMsg, 8096, + "Player detected an error: Command refers to non existent unit id = %d. Game out of synch.", + networkCommand->getUnitId()); + gameNetworkInterface-> + sendTextMessage(szMsg, -1, true, ""); + } + throw + megaglest_runtime_error(szBuf); + } + } + + //add the command to the interface + gameNetworkInterface->requestCommand(networkCommand); + + //calculate the result of the command + if (unit != NULL + && networkCommand->getNetworkCommandType() == nctGiveCommand) { + //printf("In [%s::%s Line: %d] result.first = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result.first); + Command * + command = buildCommand(networkCommand); + result = unit->checkCommand(command); + delete + command; + } + return result; + } + + void + Commander::signalNetworkUpdate(Game * game) { + updateNetwork(game); + } + + bool + Commander::getReplayCommandListForFrame(int worldFrameCount) { + bool + haveReplyCommands = false; + if (replayCommandList.empty() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("worldFrameCount = %d replayCommandList.size() = " + MG_SIZE_T_SPECIFIER "\n", worldFrameCount, + replayCommandList.size()); + + std::vector < NetworkCommand > replayList; + for (unsigned int i = 0; i < replayCommandList.size(); ++i) { + std::pair < int, + NetworkCommand > & + cmd = replayCommandList[i]; + if (cmd.first <= worldFrameCount) { + replayList.push_back(cmd.second); + haveReplyCommands = true; + } + } + if (haveReplyCommands == true) { + replayCommandList.erase(replayCommandList.begin(), + replayCommandList.begin() + + replayList.size()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("worldFrameCount = %d GIVING COMMANDS replayList.size() = " + MG_SIZE_T_SPECIFIER "\n", worldFrameCount, + replayList.size()); + for (int i = 0; i < (int) replayList.size(); ++i) { + giveNetworkCommand(&replayList[i]); + } + GameNetworkInterface * + gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + gameNetworkInterface->setKeyframe(worldFrameCount); + } + } + return haveReplyCommands; + } + + bool + Commander::hasReplayCommandListForFrame() const { + return (replayCommandList.empty() == false); + } + + int + Commander::getReplayCommandListForFrameCount() const { + return (int) + replayCommandList. + size(); + } + + void + Commander::updateNetwork(Game * game) { + if (world == NULL) { + return; + } + NetworkManager & networkManager = NetworkManager::getInstance(); + + //check that this is a keyframe + if (game != NULL) { + GameSettings * + gameSettings = game->getGameSettings(); + if (networkManager.isNetworkGame() == false || + (world->getFrameCount() % + gameSettings->getNetworkFramePeriod()) == 0) { + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] networkManager.isNetworkGame() = %d,world->getFrameCount() = %d, gameSettings->getNetworkFramePeriod() = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, + networkManager.isNetworkGame(), + world->getFrameCount(), + gameSettings-> + getNetworkFramePeriod()); + + if (getReplayCommandListForFrame(world->getFrameCount()) == + false) { + GameNetworkInterface * + gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled) + perfTimer.start(); + //update the keyframe + gameNetworkInterface->updateKeyframe(world-> + getFrameCount()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled && perfTimer.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] gameNetworkInterface->updateKeyframe for %d took %lld msecs\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + world->getFrameCount(), + perfTimer.getMillis()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled) + perfTimer.start(); + //give pending commands + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("START process: %d network commands in frame: %d\n", + gameNetworkInterface->getPendingCommandCount(), + this->world->getFrameCount()); + for (int i = 0; + i < gameNetworkInterface->getPendingCommandCount(); + ++i) { + giveNetworkCommand(gameNetworkInterface-> + getPendingCommand(i)); + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("END process: %d network commands in frame: %d\n", + gameNetworkInterface->getPendingCommandCount(), + this->world->getFrameCount()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled && perfTimer.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] giveNetworkCommand took %lld msecs, PendingCommandCount = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + perfTimer.getMillis(), + gameNetworkInterface-> + getPendingCommandCount()); + gameNetworkInterface->clearPendingCommands(); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Cleared network commands in frame: %d\n", + this->world->getFrameCount()); + } + } + } + } + + void + Commander::addToReplayCommandList(NetworkCommand & command, + int worldFrameCount) { + replayCommandList.push_back(make_pair(worldFrameCount, command)); + } + + void + Commander::giveNetworkCommand(NetworkCommand * networkCommand) const { + Chrono + chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled) + chrono. + start(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [START]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + + + world-> + getGame()-> + addNetworkCommandToReplayList(networkCommand, world->getFrameCount()); + + networkCommand-> + preprocessNetworkCommand(this->world); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [after networkCommand->preprocessNetworkCommand]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + + bool + commandWasHandled = false; + // Handle special commands first (that just use network command members as placeholders) + switch (networkCommand->getNetworkCommandType()) { + case nctSwitchTeam: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctSwitchTeam\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + commandWasHandled = true; + int + factionIndex = networkCommand->getUnitId(); + int + newTeam = networkCommand->getCommandTypeId(); + + // Auto join empty team or ask players to join + bool + autoJoinTeam = true; + for (int i = 0; i < world->getFactionCount(); ++i) { + if (newTeam == world->getFaction(i)->getTeam()) { + autoJoinTeam = false; + break; + } + } + + if (autoJoinTeam == true) { + Faction * + faction = world->getFaction(factionIndex); + int + oldTeam = faction->getTeam(); + faction->setTeam(newTeam); + GameSettings * + settings = world->getGameSettingsPtr(); + settings->setTeam(factionIndex, newTeam); + world->getStats()->setTeam(factionIndex, newTeam); + + if (factionIndex == world->getThisFactionIndex()) { + world->setThisTeamIndex(newTeam); + GameNetworkInterface * + gameNetworkInterface = + NetworkManager::getInstance(). + getGameNetworkInterface(); + if (gameNetworkInterface != NULL) { + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + settings->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); + ++i) { + char + szMsg[8096] = ""; + if (lang. + hasString("PlayerSwitchedTeam", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang. + getString("PlayerSwitchedTeam", + languageList[i]). + c_str(), + settings-> + getNetworkPlayerName(factionIndex). + c_str(), oldTeam, newTeam); + } else { + snprintf(szMsg, 8096, + "Player %s switched from team# %d to team# %d.", + settings-> + getNetworkPlayerName(factionIndex). + c_str(), oldTeam, newTeam); + } + bool + localEcho = + lang.isLanguageLocal(languageList[i]); + gameNetworkInterface->sendTextMessage(szMsg, -1, + localEcho, + languageList + [i]); + } + } + world->getGame()->reInitGUI(); + } + } else { + for (int i = 0; i < world->getFactionCount(); ++i) { + if (newTeam == world->getFaction(i)->getTeam()) { + Faction * + faction = world->getFaction(factionIndex); + + SwitchTeamVote + vote; + vote.factionIndex = factionIndex; + vote.allowSwitchTeam = false; + vote.oldTeam = faction->getTeam(); + vote.newTeam = newTeam; + vote.voted = false; + + world->getFaction(i)->setSwitchTeamVote(vote); + } + } + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [after unit->setMeetingPos]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctSetMeetingPoint\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + break; + + case nctSwitchTeamVote: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctSwitchTeamVote\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + commandWasHandled = true; + + int + votingFactionIndex = networkCommand->getUnitId(); + int + factionIndex = networkCommand->getCommandTypeId(); + bool + allowSwitchTeam = networkCommand->getUnitTypeId() != 0; + + Faction * + faction = world->getFaction(votingFactionIndex); + + SwitchTeamVote * + vote = faction->getSwitchTeamVote(factionIndex); + if (vote == NULL) { + throw + megaglest_runtime_error("vote == NULL"); + } + vote->voted = true; + vote->allowSwitchTeam = allowSwitchTeam; + + // Join the new team if > 50 % said yes + int + newTeamTotalMemberCount = 0; + int + newTeamVotedYes = 0; + int + newTeamVotedNo = 0; + + for (int i = 0; i < world->getFactionCount(); ++i) { + if (vote->newTeam == world->getFaction(i)->getTeam()) { + newTeamTotalMemberCount++; + + SwitchTeamVote * + teamVote = + world->getFaction(i)->getSwitchTeamVote(factionIndex); + if (teamVote != NULL && teamVote->voted == true) { + if (teamVote->allowSwitchTeam == true) { + newTeamVotedYes++; + } else { + newTeamVotedNo++; + } + } + } + } + + // If > 50% of team vote yes, switch th eplayers team + if (newTeamTotalMemberCount > 0 && newTeamVotedYes > 0 && + static_cast (newTeamVotedYes) / static_cast < + float>(newTeamTotalMemberCount) > 0.5) { + Faction * + faction = world->getFaction(factionIndex); + int + oldTeam = faction->getTeam(); + faction->setTeam(vote->newTeam); + GameSettings * + settings = world->getGameSettingsPtr(); + settings->setTeam(factionIndex, vote->newTeam); + world->getStats()->setTeam(factionIndex, vote->newTeam); + + if (factionIndex == world->getThisFactionIndex()) { + world->setThisTeamIndex(vote->newTeam); + GameNetworkInterface * + gameNetworkInterface = + NetworkManager::getInstance(). + getGameNetworkInterface(); + if (gameNetworkInterface != NULL) { + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + settings->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); + ++i) { + char + szMsg[8096] = ""; + if (lang. + hasString("PlayerSwitchedTeam", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang. + getString("PlayerSwitchedTeam", + languageList[i]). + c_str(), + settings-> + getNetworkPlayerName(factionIndex). + c_str(), oldTeam, vote->newTeam); + } else { + snprintf(szMsg, 8096, + "Player %s switched from team# %d to team# %d.", + settings-> + getNetworkPlayerName(factionIndex). + c_str(), oldTeam, vote->newTeam); + } + bool + localEcho = + lang.isLanguageLocal(languageList[i]); + gameNetworkInterface->sendTextMessage(szMsg, -1, + localEcho, + languageList + [i]); + } + } + world->getGame()->reInitGUI(); + } + } else if (newTeamTotalMemberCount == + (newTeamVotedYes + newTeamVotedNo)) { + if (factionIndex == world->getThisFactionIndex()) { + GameSettings * + settings = world->getGameSettingsPtr(); + Faction * + faction = world->getFaction(factionIndex); + int + oldTeam = faction->getTeam(); + + GameNetworkInterface * + gameNetworkInterface = + NetworkManager::getInstance(). + getGameNetworkInterface(); + if (gameNetworkInterface != NULL) { + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + settings->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); + ++i) { + char + szMsg[8096] = ""; + if (lang. + hasString("PlayerSwitchedTeamDenied", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang. + getString + ("PlayerSwitchedTeamDenied", + languageList[i]).c_str(), + settings-> + getNetworkPlayerName(factionIndex). + c_str(), oldTeam, vote->newTeam); + } else { + snprintf(szMsg, 8096, + "Player %s was denied the request to switch from team# %d to team# %d.", + settings-> + getNetworkPlayerName(factionIndex). + c_str(), oldTeam, vote->newTeam); + } + bool + localEcho = + lang.isLanguageLocal(languageList[i]); + gameNetworkInterface->sendTextMessage(szMsg, -1, + localEcho, + languageList + [i]); + } + } + } + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [after unit->setMeetingPos]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctSetMeetingPoint\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + break; + + case nctDisconnectNetworkPlayer: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctDisconnectNetworkPlayer\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + commandWasHandled = true; + + NetworkManager & networkManager = NetworkManager::getInstance(); + NetworkRole + role = networkManager.getNetworkRole(); + //GameSettings *settings = world->getGameSettingsPtr(); + + if (role == nrServer) { + //int factionIndex = networkCommand->getUnitId(); + int + playerIndex = networkCommand->getCommandTypeId(); + + GameNetworkInterface * + gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + if (gameNetworkInterface != NULL) { + ServerInterface * + server = networkManager.getServerInterface(); + if (server != NULL + && server->isClientConnected(playerIndex) == true) { + + MutexSafeWrapper + safeMutex(server->getSlotMutex(playerIndex), + CODE_AT_LINE); + ConnectionSlot * + slot = server->getSlot(playerIndex, false); + if (slot != NULL) { + safeMutex.ReleaseLock(); + NetworkMessageQuit + networkMessageQuit; + slot->sendMessage(&networkMessageQuit); + sleep(5); + + //printf("Sending nctDisconnectNetworkPlayer\n"); + server = + networkManager.getServerInterface(false); + if (server != NULL) { + MutexSafeWrapper + safeMutex2(server-> + getSlotMutex(playerIndex), + CODE_AT_LINE); + slot = server->getSlot(playerIndex, false); + if (slot != NULL) { + safeMutex2.ReleaseLock(); + slot->close(); + } + } + } + } + } + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctDisconnectNetworkPlayer\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + break; + + case nctPauseResume: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctPauseResume\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + commandWasHandled = true; + + bool + pauseGame = networkCommand->getUnitId() != 0; + bool + clearCaches = (networkCommand->getCommandTypeId() == 1); + bool + joinNetworkGame = (networkCommand->getUnitTypeId() == 1); + Game * + game = this->world->getGame(); + + //printf("nctPauseResume pauseGame = %d\n",pauseGame); + game->setPaused(pauseGame, true, clearCaches, joinNetworkGame); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctPauseResume\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + break; + + case nctPlayerStatusChange: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctPlayerStatusChange\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + commandWasHandled = true; + + int + factionIndex = networkCommand->getUnitId(); + int + playerStatus = networkCommand->getCommandTypeId(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "nctPlayerStatusChange factionIndex = %d playerStatus = %d\n", + factionIndex, playerStatus); + + //printf("#1 nctPlayerStatusChange factionIndex = %d playerStatus = %d\n",factionIndex,playerStatus); + + GameSettings * + settings = world->getGameSettingsPtr(); + if (playerStatus == npst_Disconnected) { + //printf("Commander nctPlayerStatusChange factionIndex: %d\n",factionIndex); + + settings->setNetworkPlayerStatuses(factionIndex, + npst_Disconnected); + + //printf("nctPlayerStatusChange -> faction->getPersonalityType() = %d index [%d] control [%d] networkstatus [%d]\n", + // world->getFaction(factionIndex)->getPersonalityType(),world->getFaction(factionIndex)->getIndex(),world->getFaction(factionIndex)->getControlType(),settings->getNetworkPlayerStatuses(factionIndex)); + + //printf("#2 nctPlayerStatusChange factionIndex = %d playerStatus = %d\n",factionIndex,playerStatus); + settings->setFactionControl(factionIndex, ctCpuUltra); + settings->setResourceMultiplierIndex(factionIndex, + settings-> + getFallbackCpuMultiplier + ()); + //Game *game = this->world->getGame(); + //game->get + Faction * + faction = this->world->getFaction(factionIndex); + faction->setControlType(ctCpuUltra); + + if (!world->getGame()->getGameOver() + && !this->world->getGame()-> + factionLostGame(factionIndex)) { + // use the fallback multiplier here + + // mark player as "leaver" + this->world->getStats()-> + setPlayerLeftBeforeEnd(factionIndex, true); + // set disconnect time for endgame stats + this->world->getStats()->setTimePlayerLeft(factionIndex, + this->world-> + getStats()-> + getFramesToCalculatePlaytime + ()); + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctPlayerStatusChange\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + break; + + } + + if (commandWasHandled == false) { + Unit * + unit = world->findUnitById(networkCommand->getUnitId()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [after world->findUnitById]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("Running command NetworkCommandType = %d, unitid = %d [%p] factionindex = %d\n", + networkCommand->getNetworkCommandType(), + networkCommand->getUnitId(), unit, + (unit != NULL ? unit->getFactionIndex() : -1)); + //execute command, if unit is still alive + if (unit != NULL) { + switch (networkCommand->getNetworkCommandType()) { + case nctGiveCommand: + { + assert(networkCommand->getCommandTypeId() != + CommandType::invalidId); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctGiveCommand networkCommand->getUnitId() = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + networkCommand->getUnitId()); + + Command * + command = buildCommand(networkCommand); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [after buildCommand]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + chrono.getMillis()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] command = %p\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + command); + + unit->giveCommand(command, + (networkCommand->getWantQueue() != + 0)); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [after unit->giveCommand]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + chrono.getMillis()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctGiveCommand networkCommand->getUnitId() = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + networkCommand->getUnitId()); + } + break; + case nctCancelCommand: + { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctCancelCommand\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__); + + unit->cancelCommand(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [after unit->cancelCommand]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + chrono.getMillis()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctCancelCommand\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__); + } + break; + case nctSetMeetingPoint: + { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctSetMeetingPoint\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__); + + unit->setMeetingPos(networkCommand->getPosition()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [after unit->setMeetingPos]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + chrono.getMillis()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found nctSetMeetingPoint\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__); + } + break; + + default: + assert(false); + break; + } + } else { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] NULL Unit for id = %d, networkCommand->getNetworkCommandType() = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, + networkCommand->getUnitId(), + networkCommand-> + getNetworkCommandType()); + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld [END]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + } + + // Reconstruct a network command received. + Command * + Commander::buildCommand(const NetworkCommand * networkCommand) const { + // Check a new command is actually being given (and not a cancel command, switch team etc.). + assert(networkCommand->getNetworkCommandType() == nctGiveCommand); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] networkCommand [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + networkCommand->toString().c_str()); + + // Check there is a world. + if (world == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] world == NULL for unit with id: %d", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, networkCommand->getUnitId()); + throw + megaglest_runtime_error(szBuf); + } + + // Get the unit. + Unit * + target = NULL; + const CommandType * + ct = NULL; + const Unit * + unit = world->findUnitById(networkCommand->getUnitId()); + + // Validate unit is in game. + if (unit == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] Can not find unit with id: %d. Game out of synch.", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, networkCommand->getUnitId()); + SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", + szBuf); + + GameNetworkInterface * + gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + if (gameNetworkInterface != NULL) { + char + szMsg[8096] = ""; + snprintf(szMsg, 8096, + "Player detected an error: Can not find unit with id: %d. Game out of synch.", + networkCommand->getUnitId()); + gameNetworkInterface->sendTextMessage(szMsg, -1, true, ""); + } + + throw + megaglest_runtime_error(szBuf); + } + + // Get the command type for the unit. + ct = + unit->getType()->findCommandTypeById(networkCommand-> + getCommandTypeId()); + + // Check that the unit from the network command is the same faction as the unit in the local game. + if (unit->getFaction()->getIndex() != + networkCommand->getUnitFactionIndex()) { + + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d]\nUnit / Faction mismatch for network command = [%s]\n%s\nfor unit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.", + __FILE__, __FUNCTION__, __LINE__, + networkCommand->toString().c_str(), + unit->getType()->getCommandTypeListDesc().c_str(), + unit->getId(), unit->getFullName(false).c_str(), + unit->getDesc(false).c_str(), + unit->getFaction()->getIndex()); + + SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", + szBuf); + //std::string worldLog = world->DumpWorldToLog(); + world->DumpWorldToLog(); + + // Broadcast the error if player is still connected and print locally. + GameNetworkInterface * + gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + if (gameNetworkInterface != NULL + && gameNetworkInterface->isConnected() == true) { + char + szMsg[8096] = ""; + snprintf(szMsg, 8096, + "Player detected an error: Unit / Faction mismatch for unitId: %d", + networkCommand->getUnitId()); + gameNetworkInterface->sendTextMessage(szMsg, -1, true, ""); + snprintf(szMsg, 8096, + "Local faction index = %d, remote index = %d. Game out of synch.", + unit->getFaction()->getIndex(), + networkCommand->getUnitFactionIndex()); + gameNetworkInterface->sendTextMessage(szMsg, -1, true, ""); + + } + + // Else if it's a network game but the user disconnected, print the error locally only. + else if (gameNetworkInterface != NULL) { + char + szMsg[8096] = ""; + snprintf(szMsg, 8096, + "Player detected an error: Connection lost, possible Unit / Faction mismatch for unitId: %d", + networkCommand->getUnitId()); + gameNetworkInterface->sendTextMessage(szMsg, -1, true, ""); + snprintf(szMsg, 8096, + "Local faction index = %d, remote index = %d. Game out of synch.", + unit->getFaction()->getIndex(), + networkCommand->getUnitFactionIndex()); + gameNetworkInterface->sendTextMessage(szMsg, -1, true, ""); + } + + // Kill the game. + std::string sError = + "Error [#1]: Game is out of sync (Unit / Faction mismatch)\nplease check log files for details."; + throw + megaglest_runtime_error(sError); + } + + const UnitType * + unitType = + world->findUnitTypeById(unit->getFaction()->getType(), + networkCommand->getUnitTypeId()); + + // debug test! + //throw megaglest_runtime_error("Test missing command type!"); + + //validate command type + + // !!!Test out of synch behaviour + //ct = NULL; + + // Check if the command was for the unit before it morphed, if so cancel it. + bool + isCancelPreMorphCommand = false; + if (ct == NULL && unit->getPreMorphType() != NULL) { + const CommandType * + ctPreMorph = + unit->getPreMorphType()->findCommandTypeById(networkCommand-> + getCommandTypeId + ()); + if (ctPreMorph != NULL) { + ct = unit->getType()->getFirstCtOfClass(ccStop); + isCancelPreMorphCommand = true; + } + } + + // Throw an error if a valid command for the unit is still not found. + if (ct == NULL) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d]\nCan not find command type for network command = [%s]\n%s\nfor unit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nUnit Type Info:\n[%s]\nNetwork unit type:\n[%s]\nisCancelPreMorphCommand: %d\nGame out of synch.", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, + networkCommand->toString().c_str(), + unit->getType()->getCommandTypeListDesc().c_str(), + unit->getId(), unit->getFullName(false).c_str(), + unit->getDesc(false).c_str(), + unit->getFaction()->getIndex(), + unit->getType()->toString().c_str(), + (unitType != + NULL ? unitType->getName(false).c_str() : "null"), + isCancelPreMorphCommand); + + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", szBuf); + SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", szBuf); + world->DumpWorldToLog(); + + GameNetworkInterface * + gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + if (gameNetworkInterface != NULL) { + char + szMsg[8096] = ""; + snprintf(szMsg, 8096, + "Player detected an error: Can not find command type: %d for unitId: %d [%s]. isCancelPreMorphCommand: %d Game out of synch.", + networkCommand->getCommandTypeId(), + networkCommand->getUnitId(), + (unitType != + NULL ? unitType->getName(false).c_str() : "null"), + isCancelPreMorphCommand); + gameNetworkInterface->sendTextMessage(szMsg, -1, true, ""); + } + + std::string sError = + "Error [#3]: Game is out of sync, please check log files for details."; + //abort(); + throw + megaglest_runtime_error(sError); + } + + CardinalDir + facing; + // Get direction of the command target unit. + if (isCancelPreMorphCommand == false) { + // If target is a building. + if (ct->getClass() == ccBuild) { + // Check the target building ID is valid. If not, throw an error. + /// TODO: What is happening here? The error returned does not match the condition. Why is there a constant of 4? + if (networkCommand->getTargetId() < 0 + || networkCommand->getTargetId() >= 4) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "networkCommand->getTargetId() >= 0 && networkCommand->getTargetId() < 4, [%s]", + networkCommand->toString().c_str()); + throw + megaglest_runtime_error(szBuf); + } + facing = CardinalDir(networkCommand->getTargetId()); + } + // Get the target unit if the ID is valid. + else if (networkCommand->getTargetId() != Unit::invalidId) { + target = world->findUnitById(networkCommand->getTargetId()); + } + } + + // Create the command. + Command * + command = NULL; + if (isCancelPreMorphCommand == false) { + if (unitType != NULL) { + command = + new Command(ct, networkCommand->getPosition(), unitType, + facing); + } else if (target == NULL) { + command = new Command(ct, networkCommand->getPosition()); + } else { + command = new Command(ct, target); + } + } else { + command = new Command(ct, NULL); + } + + // Add in any special state + CommandStateType + commandStateType = networkCommand->getCommandStateType(); + int + commandStateValue = networkCommand->getCommandStateValue(); + + command->setStateType(commandStateType); + command->setStateValue(commandStateValue); + command->setUnitCommandGroupId(networkCommand-> + getUnitCommandGroupId()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + //issue command + return command; + } + + } } //end namespace diff --git a/source/glest_game/game/commander.h b/source/glest_game/game/commander.h index c2f9a530d..e7821a71d 100644 --- a/source/glest_game/game/commander.h +++ b/source/glest_game/game/commander.h @@ -26,174 +26,170 @@ # include "leak_dumper.h" using - std::vector; +std::vector; namespace - Glest -{ - namespace - Game - { + Glest { + namespace + Game { - using - Shared::Graphics::Vec2i; - using - Shared::PlatformCommon::Chrono; + using + Shared::Graphics::Vec2i; + using + Shared::PlatformCommon::Chrono; - class - World; - class - Unit; - class - Command; - class - CommandType; - class - NetworkCommand; - class - Game; - class - SwitchTeamVote; + class + World; + class + Unit; + class + Command; + class + CommandType; + class + NetworkCommand; + class + Game; + class + SwitchTeamVote; -// ===================================================== -// class Commander -// -/// Gives commands to the units -// ===================================================== - class - Commander - { - private: - typedef - vector < - std::pair < - CommandResult, - string > > - CommandResultContainer; + // ===================================================== + // class Commander + // + /// Gives commands to the units + // ===================================================== + class + Commander { + private: + typedef + vector < + std::pair < + CommandResult, + string > > + CommandResultContainer; - private: - World * - world; - Chrono - perfTimer; + private: + World * + world; + Chrono + perfTimer; - std::vector < - std::pair < int, - NetworkCommand > > - replayCommandList; + std::vector < + std::pair < int, + NetworkCommand > > + replayCommandList; - bool - pauseNetworkCommands; + bool + pauseNetworkCommands; - public: - Commander (); - virtual ~ - Commander (); + public: + Commander(); + virtual ~ + Commander(); - bool - getPauseNetworkCommands () const - { - return - this-> - pauseNetworkCommands; - } - void - setPauseNetworkCommands (bool pause) - { - this->pauseNetworkCommands = pause; - } + bool + getPauseNetworkCommands() const { + return + this-> + pauseNetworkCommands; + } + void + setPauseNetworkCommands(bool pause) { + this->pauseNetworkCommands = pause; + } - void - signalNetworkUpdate (Game * game); - void - init (World * world); - void - updateNetwork (Game * game); + void + signalNetworkUpdate(Game * game); + void + init(World * world); + void + updateNetwork(Game * game); - void - addToReplayCommandList (NetworkCommand & command, int worldFrameCount); - bool - getReplayCommandListForFrame (int worldFrameCount); - bool - hasReplayCommandListForFrame () const; - int - getReplayCommandListForFrameCount () const; + void + addToReplayCommandList(NetworkCommand & command, int worldFrameCount); + bool + getReplayCommandListForFrame(int worldFrameCount); + bool + hasReplayCommandListForFrame() const; + int + getReplayCommandListForFrameCount() const; - std::pair < - CommandResult, - string > - tryGiveCommand (const Selection * selection, - const CommandType * commandType, const Vec2i & pos, - const UnitType * unitType, CardinalDir facing, - bool tryQueue, Unit * targetUnit = NULL) const; + std::pair < + CommandResult, + string > + tryGiveCommand(const Selection * selection, + const CommandType * commandType, const Vec2i & pos, + const UnitType * unitType, CardinalDir facing, + bool tryQueue, Unit * targetUnit = NULL) const; - std::pair < - CommandResult, - string > - tryGiveCommand (const Unit * unit, const CommandType * commandType, - const Vec2i & pos, const UnitType * unitType, - CardinalDir facing, bool tryQueue = - false, Unit * targetUnit = - NULL, int unitGroupCommandId = -1) const; - std::pair < - CommandResult, - string > - tryGiveCommand (const Selection * selection, CommandClass commandClass, - const Vec2i & pos = Vec2i (0), const Unit * targetUnit = - NULL, bool tryQueue = false) const; - std::pair < - CommandResult, - string > - tryGiveCommand (const Selection * selection, - const CommandType * commandType, const Vec2i & pos = - Vec2i (0), const Unit * targetUnit = - NULL, bool tryQueue = false) const; - std::pair < - CommandResult, - string > - tryGiveCommand (const Selection * selection, const Vec2i & pos, - const Unit * targetUnit = NULL, bool tryQueue = - false, int unitCommandGroupId = -1) const; - CommandResult - tryCancelCommand (const Selection * selection) const; - void - trySetMeetingPoint (const Unit * unit, const Vec2i & pos) const; - void - trySwitchTeam (const Faction * faction, int teamIndex) const; - void - trySwitchTeamVote (const Faction * faction, - SwitchTeamVote * vote) const; - void - tryDisconnectNetworkPlayer (const Faction * faction, - int playerIndex) const; + std::pair < + CommandResult, + string > + tryGiveCommand(const Unit * unit, const CommandType * commandType, + const Vec2i & pos, const UnitType * unitType, + CardinalDir facing, bool tryQueue = + false, Unit * targetUnit = + NULL, int unitGroupCommandId = -1) const; + std::pair < + CommandResult, + string > + tryGiveCommand(const Selection * selection, CommandClass commandClass, + const Vec2i & pos = Vec2i(0), const Unit * targetUnit = + NULL, bool tryQueue = false) const; + std::pair < + CommandResult, + string > + tryGiveCommand(const Selection * selection, + const CommandType * commandType, const Vec2i & pos = + Vec2i(0), const Unit * targetUnit = + NULL, bool tryQueue = false) const; + std::pair < + CommandResult, + string > + tryGiveCommand(const Selection * selection, const Vec2i & pos, + const Unit * targetUnit = NULL, bool tryQueue = + false, int unitCommandGroupId = -1) const; + CommandResult + tryCancelCommand(const Selection * selection) const; + void + trySetMeetingPoint(const Unit * unit, const Vec2i & pos) const; + void + trySwitchTeam(const Faction * faction, int teamIndex) const; + void + trySwitchTeamVote(const Faction * faction, + SwitchTeamVote * vote) const; + void + tryDisconnectNetworkPlayer(const Faction * faction, + int playerIndex) const; - void - tryPauseGame (bool joinNetworkGame, bool clearCaches) const; - void - tryResumeGame (bool joinNetworkGame, bool clearCaches) const; + void + tryPauseGame(bool joinNetworkGame, bool clearCaches) const; + void + tryResumeGame(bool joinNetworkGame, bool clearCaches) const; - void - tryNetworkPlayerDisconnected (int factionIndex) const; + void + tryNetworkPlayerDisconnected(int factionIndex) const; - Command * - buildCommand (const NetworkCommand * networkCommand) const; + Command * + buildCommand(const NetworkCommand * networkCommand) const; - private: - std::pair < - CommandResult, - string > - pushNetworkCommand (const NetworkCommand * networkCommand) const; - std::pair < - CommandResult, - string > - computeResult (const CommandResultContainer & results) const; - void - giveNetworkCommand (NetworkCommand * networkCommand) const; - bool - canSubmitCommandType (const Unit * unit, - const CommandType * commandType) const; - }; + private: + std::pair < + CommandResult, + string > + pushNetworkCommand(const NetworkCommand * networkCommand) const; + std::pair < + CommandResult, + string > + computeResult(const CommandResultContainer & results) const; + void + giveNetworkCommand(NetworkCommand * networkCommand) const; + bool + canSubmitCommandType(const Unit * unit, + const CommandType * commandType) const; + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/game/console.cpp b/source/glest_game/game/console.cpp index 2d77c230e..c77db77a0 100644 --- a/source/glest_game/game/console.cpp +++ b/source/glest_game/game/console.cpp @@ -24,323 +24,257 @@ using namespace std; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class Console -// ===================================================== + // ===================================================== + // class Console + // ===================================================== - Console::Console () - { - registerGraphicComponent ("Console", "Generic-Console"); - this->fontCallbackName = getInstanceName () + "_" + getNewUUD (); - CoreData::getInstance ().registerFontChangedCallback (this-> - getFontCallbackName - (), this); + Console::Console() { + registerGraphicComponent("Console", "Generic-Console"); + this->fontCallbackName = getInstanceName() + "_" + getNewUUD(); + CoreData::getInstance().registerFontChangedCallback(this-> + getFontCallbackName + (), this); - maxLines = Config::getInstance ().getInt ("ConsoleMaxLines"); - maxStoredLines = - Config::getInstance ().getInt ("ConsoleMaxLinesStored"); - timeout = Config::getInstance ().getInt ("ConsoleTimeout"); - timeElapsed = 0.0f; - xPos = 20; - yPos = 20; - lineHeight = - Config::getInstance ().getInt ("FontConsoleBaseSize", "18") + 2; - setFont (CoreData::getInstance ().getConsoleFont ()); - setFont3D (CoreData::getInstance ().getConsoleFont3D ()); + maxLines = Config::getInstance().getInt("ConsoleMaxLines"); + maxStoredLines = + Config::getInstance().getInt("ConsoleMaxLinesStored"); + timeout = Config::getInstance().getInt("ConsoleTimeout"); + timeElapsed = 0.0f; + xPos = 20; + yPos = 20; + lineHeight = + Config::getInstance().getInt("FontConsoleBaseSize", "18") + 2; + setFont(CoreData::getInstance().getConsoleFont()); + setFont3D(CoreData::getInstance().getConsoleFont3D()); - stringToHighlight = ""; - onlyChatMessagesInStoredLines = true; - } + stringToHighlight = ""; + onlyChatMessagesInStoredLines = true; + } - string Console::getNewUUD () - { - char uuid_str[38]; - get_uuid_string (uuid_str, sizeof (uuid_str)); - return string (uuid_str); - } + string Console::getNewUUD() { + char uuid_str[38]; + get_uuid_string(uuid_str, sizeof(uuid_str)); + return string(uuid_str); + } - Console::~Console () - { - CoreData::getInstance ().unRegisterFontChangedCallback (this-> - getFontCallbackName - ()); - } + Console::~Console() { + CoreData::getInstance().unRegisterFontChangedCallback(this-> + getFontCallbackName + ()); + } - void Console::setFont (Font2D * font) - { - this->font = font; - if (this->font != NULL) - { - this->font2DUniqueId = font->getFontUniqueId (); - } - else - { - this->font2DUniqueId = ""; - } - } + void Console::setFont(Font2D * font) { + this->font = font; + if (this->font != NULL) { + this->font2DUniqueId = font->getFontUniqueId(); + } else { + this->font2DUniqueId = ""; + } + } - void Console::setFont3D (Font3D * font) - { - this->font3D = font; - if (this->font3D != NULL) - { - this->font3DUniqueId = font->getFontUniqueId (); - } - else - { - this->font3DUniqueId = ""; - } - } + void Console::setFont3D(Font3D * font) { + this->font3D = font; + if (this->font3D != NULL) { + this->font3DUniqueId = font->getFontUniqueId(); + } else { + this->font3DUniqueId = ""; + } + } - void Console::registerGraphicComponent (const std::string & containerName, - const std::string & objName) - { - this->instanceName = objName; - } + void Console::registerGraphicComponent(const std::string & containerName, + const std::string & objName) { + this->instanceName = objName; + } - void Console::FontChangedCallback (std::string fontUniqueId, Font * font) - { - if (fontUniqueId != "") - { - if (fontUniqueId == this->font2DUniqueId) - { - if (font != NULL) - { - this->font = (Font2D *) font; - } - else - { - this->font = NULL; - } - } - else if (fontUniqueId == this->font3DUniqueId) - { - if (font != NULL) - { - this->font3D = (Font3D *) font; - } - else - { - this->font3D = NULL; - } - } - } - } + void Console::FontChangedCallback(std::string fontUniqueId, Font * font) { + if (fontUniqueId != "") { + if (fontUniqueId == this->font2DUniqueId) { + if (font != NULL) { + this->font = (Font2D *) font; + } else { + this->font = NULL; + } + } else if (fontUniqueId == this->font3DUniqueId) { + if (font != NULL) { + this->font3D = (Font3D *) font; + } else { + this->font3D = NULL; + } + } + } + } - void Console::resetFonts () - { - setFont (CoreData::getInstance ().getConsoleFont ()); - setFont3D (CoreData::getInstance ().getConsoleFont3D ()); - } + void Console::resetFonts() { + setFont(CoreData::getInstance().getConsoleFont()); + setFont3D(CoreData::getInstance().getConsoleFont3D()); + } - void Console::addStdMessage (const string & s, bool clearOtherLines) - { - if (clearOtherLines == true) - { - addLineOnly (Lang::getInstance ().getString (s)); - } - else - { - addLine (Lang::getInstance ().getString (s)); - } - } + void Console::addStdMessage(const string & s, bool clearOtherLines) { + if (clearOtherLines == true) { + addLineOnly(Lang::getInstance().getString(s)); + } else { + addLine(Lang::getInstance().getString(s)); + } + } - void Console::addStdMessage (const string & s, const string & failText, - bool clearOtherLines) - { - if (clearOtherLines == true) - { - addLineOnly (Lang::getInstance ().getString (s) + failText); - } - else - { - addLine (Lang::getInstance ().getString (s) + failText); - } - } + void Console::addStdMessage(const string & s, const string & failText, + bool clearOtherLines) { + if (clearOtherLines == true) { + addLineOnly(Lang::getInstance().getString(s) + failText); + } else { + addLine(Lang::getInstance().getString(s) + failText); + } + } - void Console::addStdScenarioMessage (const string & s, - bool clearOtherLines) - { - if (clearOtherLines == true) - { - addLineOnly (Lang::getInstance ().getScenarioString (s)); - } - else - { - addLine (Lang::getInstance ().getScenarioString (s)); - } - } + void Console::addStdScenarioMessage(const string & s, + bool clearOtherLines) { + if (clearOtherLines == true) { + addLineOnly(Lang::getInstance().getScenarioString(s)); + } else { + addLine(Lang::getInstance().getScenarioString(s)); + } + } - void Console::addLineOnly (const string & line) - { - addLine (line, false, -1, Vec3f (1.f, 1.f, 1.f), false, true); - } + void Console::addLineOnly(const string & line) { + addLine(line, false, -1, Vec3f(1.f, 1.f, 1.f), false, true); + } - void Console::addLine (const string & line, bool playSound, - int playerIndex, Vec3f textColor, bool teamMode, - bool clearOtherLines) - { - try - { - if (playSound == true) - { - SoundRenderer::getInstance ().playFx (CoreData::getInstance (). - getClickSoundA ()); - } - ConsoleLineInfo info; - info.text = line; - info.timeStamp = timeElapsed; - info.PlayerIndex = playerIndex; - info.originalPlayerName = ""; - info.color = textColor; - info.teamMode = teamMode; - if (playerIndex >= 0) - { - GameNetworkInterface *gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - if (gameNetworkInterface != NULL) - { - info.originalPlayerName = - gameNetworkInterface->getGameSettings ()-> - getNetworkPlayerNameByPlayerIndex (playerIndex); - //for(int i = 0; i < GameConstants::maxPlayers; ++i) { - // printf("i = %d, playerName = [%s]\n",i,gameNetworkInterface->getGameSettings()->getNetworkPlayerName(i).c_str()); - //} - } - } - //printf("info.PlayerIndex = %d, line [%s]\n",info.PlayerIndex,info.originalPlayerName.c_str()); + void Console::addLine(const string & line, bool playSound, + int playerIndex, Vec3f textColor, bool teamMode, + bool clearOtherLines) { + try { + if (playSound == true) { + SoundRenderer::getInstance().playFx(CoreData::getInstance(). + getClickSoundA()); + } + ConsoleLineInfo info; + info.text = line; + info.timeStamp = timeElapsed; + info.PlayerIndex = playerIndex; + info.originalPlayerName = ""; + info.color = textColor; + info.teamMode = teamMode; + if (playerIndex >= 0) { + GameNetworkInterface *gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + if (gameNetworkInterface != NULL) { + info.originalPlayerName = + gameNetworkInterface->getGameSettings()-> + getNetworkPlayerNameByPlayerIndex(playerIndex); + //for(int i = 0; i < GameConstants::maxPlayers; ++i) { + // printf("i = %d, playerName = [%s]\n",i,gameNetworkInterface->getGameSettings()->getNetworkPlayerName(i).c_str()); + //} + } + } + //printf("info.PlayerIndex = %d, line [%s]\n",info.PlayerIndex,info.originalPlayerName.c_str()); - if (clearOtherLines == true) - { - lines.clear (); - storedLines.clear (); - } - lines.insert (lines.begin (), info); - if ((int) lines.size () > maxLines) - { - lines.pop_back (); - } - if (onlyChatMessagesInStoredLines == false || info.PlayerIndex != -1) - { - storedLines.insert (storedLines.begin (), info); - if ((int) storedLines.size () > maxStoredLines) - { - storedLines.pop_back (); - } - } - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw megaglest_runtime_error (szBuf); - } - } + if (clearOtherLines == true) { + lines.clear(); + storedLines.clear(); + } + lines.insert(lines.begin(), info); + if ((int) lines.size() > maxLines) { + lines.pop_back(); + } + if (onlyChatMessagesInStoredLines == false || info.PlayerIndex != -1) { + storedLines.insert(storedLines.begin(), info); + if ((int) storedLines.size() > maxStoredLines) { + storedLines.pop_back(); + } + } + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + } - void Console::addLine (const string & line, bool playSound, - const string & playerName, Vec3f textColor, - bool teamMode) - { - try - { - if (playSound == true) - { - SoundRenderer::getInstance ().playFx (CoreData::getInstance (). - getClickSoundA ()); - } - ConsoleLineInfo info; - info.text = line; - info.timeStamp = timeElapsed; - info.PlayerIndex = -1; - info.originalPlayerName = ""; - info.color = textColor; - info.teamMode = teamMode; - if (playerName != "") - { - info.originalPlayerName = playerName; - } - //printf("info.PlayerIndex = %d, line [%s]\n",info.PlayerIndex,info.originalPlayerName.c_str()); + void Console::addLine(const string & line, bool playSound, + const string & playerName, Vec3f textColor, + bool teamMode) { + try { + if (playSound == true) { + SoundRenderer::getInstance().playFx(CoreData::getInstance(). + getClickSoundA()); + } + ConsoleLineInfo info; + info.text = line; + info.timeStamp = timeElapsed; + info.PlayerIndex = -1; + info.originalPlayerName = ""; + info.color = textColor; + info.teamMode = teamMode; + if (playerName != "") { + info.originalPlayerName = playerName; + } + //printf("info.PlayerIndex = %d, line [%s]\n",info.PlayerIndex,info.originalPlayerName.c_str()); - lines.insert (lines.begin (), info); - if ((int) lines.size () > maxLines) - { - lines.pop_back (); - } - storedLines.insert (storedLines.begin (), info); - if ((int) storedLines.size () > maxStoredLines) - { - storedLines.pop_back (); - } - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw megaglest_runtime_error (szBuf); - } - } + lines.insert(lines.begin(), info); + if ((int) lines.size() > maxLines) { + lines.pop_back(); + } + storedLines.insert(storedLines.begin(), info); + if ((int) storedLines.size() > maxStoredLines) { + storedLines.pop_back(); + } + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + } - void Console::clearStoredLines () - { - while (storedLines.empty () == false) - { - storedLines.pop_back (); - } - } + void Console::clearStoredLines() { + while (storedLines.empty() == false) { + storedLines.pop_back(); + } + } - void Console::update () - { - timeElapsed += 1.f / GameConstants::updateFps; + void Console::update() { + timeElapsed += 1.f / GameConstants::updateFps; - if (lines.empty () == false) - { - if (lines.back ().timeStamp < (timeElapsed - timeout)) - { - lines.pop_back (); - } - } - } + if (lines.empty() == false) { + if (lines.back().timeStamp < (timeElapsed - timeout)) { + lines.pop_back(); + } + } + } - bool Console::isEmpty () - { - return lines.empty (); - } + bool Console::isEmpty() { + return lines.empty(); + } -//string Console::getLine(int i) const { -// if(i < 0 || i >= (int)lines.size()) -// throw megaglest_runtime_error("i >= Lines.size()"); -// return lines[i].text; -//} + //string Console::getLine(int i) const { + // if(i < 0 || i >= (int)lines.size()) + // throw megaglest_runtime_error("i >= Lines.size()"); + // return lines[i].text; + //} -//string Console::getStoredLine(int i) const { -// if(i < 0 || i >= (int)storedLines.size()) -// throw megaglest_runtime_error("i >= storedLines.size()"); -// return storedLines[i].text; -//} + //string Console::getStoredLine(int i) const { + // if(i < 0 || i >= (int)storedLines.size()) + // throw megaglest_runtime_error("i >= storedLines.size()"); + // return storedLines[i].text; + //} - ConsoleLineInfo Console::getLineItem (int i) const - { - if (i < 0 || i >= (int) lines.size ()) - throw megaglest_runtime_error ("i >= Lines.size()"); - return lines[i]; - } + ConsoleLineInfo Console::getLineItem(int i) const { + if (i < 0 || i >= (int) lines.size()) + throw megaglest_runtime_error("i >= Lines.size()"); + return lines[i]; + } - ConsoleLineInfo Console::getStoredLineItem (int i) const - { - if (i < 0 || i >= (int) storedLines.size ()) - throw megaglest_runtime_error ("i >= storedLines.size()"); - return storedLines[i]; - } + ConsoleLineInfo Console::getStoredLineItem(int i) const { + if (i < 0 || i >= (int) storedLines.size()) + throw megaglest_runtime_error("i >= storedLines.size()"); + return storedLines[i]; + } - } + } } //end namespace diff --git a/source/glest_game/game/console.h b/source/glest_game/game/console.h index 6fcdb3265..959d8fcb2 100644 --- a/source/glest_game/game/console.h +++ b/source/glest_game/game/console.h @@ -26,275 +26,254 @@ # include "vec.h" using - std::string; +std::string; using - std::vector; +std::vector; using - std::pair; +std::pair; using namespace - std; +std; namespace - Glest -{ - namespace - Game - { + Glest { + namespace + Game { - using - Shared::Graphics::Font; - using - Shared::Graphics::Font2D; - using - Shared::Graphics::Font3D; - using - Shared::Graphics::FontChangedCallbackInterface; - using - Shared::Graphics::Vec3f; -// ===================================================== -// class Console -// -// In-game console that shows various types of messages -// ===================================================== + using + Shared::Graphics::Font; + using + Shared::Graphics::Font2D; + using + Shared::Graphics::Font3D; + using + Shared::Graphics::FontChangedCallbackInterface; + using + Shared::Graphics::Vec3f; + // ===================================================== + // class Console + // + // In-game console that shows various types of messages + // ===================================================== - class - ConsoleLineInfo - { - public: - string - text; - float - timeStamp; - int - PlayerIndex; - string - originalPlayerName; - Vec3f - color; - bool - teamMode; - }; + class + ConsoleLineInfo { + public: + string + text; + float + timeStamp; + int + PlayerIndex; + string + originalPlayerName; + Vec3f + color; + bool + teamMode; + }; - class - Console: - public - FontChangedCallbackInterface - { - private: - static const int - consoleLines = 5; + class + Console : + public + FontChangedCallbackInterface { + private: + static const int + consoleLines = 5; - public: + public: - typedef - vector < - ConsoleLineInfo > - Lines; - typedef - Lines::const_iterator - LineIterator; + typedef + vector < + ConsoleLineInfo > + Lines; + typedef + Lines::const_iterator + LineIterator; - private: - float - timeElapsed; - Lines - lines; - Lines - storedLines; - string - stringToHighlight; + private: + float + timeElapsed; + Lines + lines; + Lines + storedLines; + string + stringToHighlight; - //config - int - maxLines; - int - maxStoredLines; - float - timeout; - int - xPos; - int - yPos; - int - lineHeight; - Font2D * - font; - Font3D * - font3D; - string - font2DUniqueId; - string - font3DUniqueId; + //config + int + maxLines; + int + maxStoredLines; + float + timeout; + int + xPos; + int + yPos; + int + lineHeight; + Font2D * + font; + Font3D * + font3D; + string + font2DUniqueId; + string + font3DUniqueId; - bool - onlyChatMessagesInStoredLines; + bool + onlyChatMessagesInStoredLines; - string - instanceName; - string - fontCallbackName; + string + instanceName; + string + fontCallbackName; - string - getNewUUD (); + string + getNewUUD(); - public: + public: - Console (); - virtual ~ - Console (); + Console(); + virtual ~ + Console(); - void - registerGraphicComponent (const std::string & containerName, - const std::string & objName); - string - getInstanceName () const - { - return - instanceName; - } - void - setInstanceName (const string & value) - { - instanceName = value; - } - string - getFontCallbackName () const - { - return - fontCallbackName; - } + void + registerGraphicComponent(const std::string & containerName, + const std::string & objName); + string + getInstanceName() const { + return + instanceName; + } + void + setInstanceName(const string & value) { + instanceName = value; + } + string + getFontCallbackName() const { + return + fontCallbackName; + } - int - getStoredLineCount () const - { - return (int) - storedLines. - size (); - } - int - getLineCount () const - { - return (int) - lines. - size (); - } - bool - getOnlyChatMessagesInStoredLines () const - { - return - onlyChatMessagesInStoredLines; - } - void - setOnlyChatMessagesInStoredLines (bool value) - { - this->onlyChatMessagesInStoredLines = value; - } + int + getStoredLineCount() const { + return (int) + storedLines. + size(); + } + int + getLineCount() const { + return (int) + lines. + size(); + } + bool + getOnlyChatMessagesInStoredLines() const { + return + onlyChatMessagesInStoredLines; + } + void + setOnlyChatMessagesInStoredLines(bool value) { + this->onlyChatMessagesInStoredLines = value; + } - int - getXPos () const - { - return - xPos; - } - void - setXPos (int xPos) - { - this->xPos = xPos; - } - int - getYPos () const - { - return - yPos; - } - void - setYPos (int yPos) - { - this->yPos = yPos; - } - int - getLineHeight () const - { - return - lineHeight; - } - void - setLineHeight (int lineHeight) - { - this->lineHeight = lineHeight; - } - Font2D * - getFont () const - { - return - font; - } - Font3D * - getFont3D () const - { - return - font3D; - } - void - setFont (Font2D * font); - void - setFont3D (Font3D * font); - string - getStringToHighlight () const - { - return - stringToHighlight; - } - void - setStringToHighlight (const string & stringToHighlight) - { - this->stringToHighlight = stringToHighlight; - } - void - resetFonts (); + int + getXPos() const { + return + xPos; + } + void + setXPos(int xPos) { + this->xPos = xPos; + } + int + getYPos() const { + return + yPos; + } + void + setYPos(int yPos) { + this->yPos = yPos; + } + int + getLineHeight() const { + return + lineHeight; + } + void + setLineHeight(int lineHeight) { + this->lineHeight = lineHeight; + } + Font2D * + getFont() const { + return + font; + } + Font3D * + getFont3D() const { + return + font3D; + } + void + setFont(Font2D * font); + void + setFont3D(Font3D * font); + string + getStringToHighlight() const { + return + stringToHighlight; + } + void + setStringToHighlight(const string & stringToHighlight) { + this->stringToHighlight = stringToHighlight; + } + void + resetFonts(); - //string getLine(int i) const; - //string getStoredLine(int i) const; - ConsoleLineInfo - getLineItem (int i) const; - ConsoleLineInfo - getStoredLineItem (int i) const; + //string getLine(int i) const; + //string getStoredLine(int i) const; + ConsoleLineInfo + getLineItem(int i) const; + ConsoleLineInfo + getStoredLineItem(int i) const; - void - clearStoredLines (); - void - addStdMessage (const string & s, bool clearOtherLines = false); - void - addStdMessage (const string & s, const string & failText, - bool clearOtherLines = false); + void + clearStoredLines(); + void + addStdMessage(const string & s, bool clearOtherLines = false); + void + addStdMessage(const string & s, const string & failText, + bool clearOtherLines = false); - void - addStdScenarioMessage (const string & s, bool clearOtherLines = false); - void - addLineOnly (const string & line); - void - addLine (const string & line, bool playSound = false, int playerIndex = - -1, Vec3f textColor = Vec3f (1.f, 1.f, 1.f), bool teamMode = - false, bool clearOtherLines = false); - void - addLine (const string & line, bool playSound, const string & playerName, - Vec3f textColor = Vec3f (1.f, 1.f, 1.f), bool teamMode = - false); - void - addLine (const string & line, bool playSound, Vec3f textColor) - { - addLine (line, playSound, "", textColor, false); - } - void - update (); - bool - isEmpty (); + void + addStdScenarioMessage(const string & s, bool clearOtherLines = false); + void + addLineOnly(const string & line); + void + addLine(const string & line, bool playSound = false, int playerIndex = + -1, Vec3f textColor = Vec3f(1.f, 1.f, 1.f), bool teamMode = + false, bool clearOtherLines = false); + void + addLine(const string & line, bool playSound, const string & playerName, + Vec3f textColor = Vec3f(1.f, 1.f, 1.f), bool teamMode = + false); + void + addLine(const string & line, bool playSound, Vec3f textColor) { + addLine(line, playSound, "", textColor, false); + } + void + update(); + bool + isEmpty(); - virtual void - FontChangedCallback (std::string fontUniqueId, Font * font); - }; + virtual void + FontChangedCallback(std::string fontUniqueId, Font * font); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 3e96e1e82..a51ff28d8 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -49,10554 +49,9377 @@ using namespace Shared::Util; using namespace Shared::Platform; using namespace Shared::CompressionUtil; -namespace Glest -{ - namespace Game - { - - string GameSettings::playerDisconnectedText = ""; - Game *thisGamePtr = NULL; - -// ===================================================== -// class Game -// ===================================================== - -// ===================== PUBLIC ======================== - - const float PHOTO_MODE_MAXHEIGHT = 500.0; - - const int CREATE_NEW_TEAM = -100; - const int CANCEL_SWITCH_TEAM = -1; - - const int CANCEL_DISCONNECT_PLAYER = -1; - - const float Game::highlightTime = 0.5f; - - int fadeMusicMilliseconds = 3500; - -// Check every x seconds if we should switch disconnected players to AI - const int NETWORK_PLAYER_CONNECTION_CHECK_SECONDS = 5; - - int GAME_STATS_DUMP_INTERVAL = 60 * 10; - - Game::Game (): - ProgramState (NULL) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - - originalDisplayMsgCallback = NULL; - aiInterfaces.clear (); - videoPlayer = NULL; - playingStaticVideo = false; - - mouse2d = 0; - mouseX = 0; - mouseY = 0; - updateFps = 0; - lastUpdateFps = 0; - avgUpdateFps = 0; - framesToCatchUpAsClient = 0; - framesToSlowDownAsClient = 0; - totalRenderFps = 0; - renderFps = 0; - lastRenderFps = 0; - avgRenderFps = 0; - currentAvgRenderFpsTotal = 0; - paused = false; - networkPauseGameForLaggedClientsRequested = false; - networkResumeGameForLaggedClientsRequested = false; - pausedForJoinGame = false; - pausedBeforeJoinGame = false; - pauseRequestSent = false; - resumeRequestSent = false; - pauseStateChanged = false; - gameOver = false; - renderNetworkStatus = false; - renderInGamePerformance = false; - showFullConsole = false; - setMarker = false; - cameraDragAllowed = false; - mouseMoved = false; - scrollSpeed = 0; - camLeftButtonDown = false; - camRightButtonDown = false; - camUpButtonDown = false; - camDownButtonDown = false; - this->speed = 1; - weatherParticleSystem = NULL; - isFirstRender = false; - quitTriggeredIndicator = false; - quitPendingIndicator = false; - original_updateFps = 0; - original_cameraFps = 0; - captureAvgTestStatus = false; - updateFpsAvgTest = 0; - renderFpsAvgTest = 0; - renderExtraTeamColor = 0; - photoModeEnabled = false; - healthbarMode = hbvUndefined; - visibleHUD = false; - timeDisplay = false; - withRainEffect = false; - program = NULL; - gameStarted = false; - this->initialResumeSpeedLoops = false; - - highlightCellTexture = NULL; - lastMasterServerGameStatsDump = 0; - lastMaxUnitCalcTime = 0; - lastRenderLog2d = 0; - playerIndexDisconnect = 0; - tickCount = 0; - currentCameraFollowUnit = NULL; - - popupMenu.setEnabled (false); - popupMenu.setVisible (false); - - popupMenuSwitchTeams.setEnabled (false); - popupMenuSwitchTeams.setVisible (false); - - popupMenuDisconnectPlayer.setEnabled (false); - popupMenuDisconnectPlayer.setVisible (false); - - switchTeamConfirmMessageBox.setEnabled (false); - disconnectPlayerConfirmMessageBox.setEnabled (false); - - disconnectPlayerIndexMap.clear (); - - exitGamePopupMenuIndex = -1; - joinTeamPopupMenuIndex = -1; - pauseGamePopupMenuIndex = -1; - saveGamePopupMenuIndex = -1; - loadGamePopupMenuIndex = -1; - keyboardSetupPopupMenuIndex = -1; - disconnectPlayerPopupMenuIndex = -1; - - isMarkCellEnabled = false; - isMarkCellTextEnabled = false; - - markCellTexture = NULL; - isUnMarkCellEnabled = false; - unmarkCellTexture = NULL; - - masterserverMode = false; - currentUIState = NULL; - currentAmbientSound = NULL; - //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); - - loadGameNode = NULL; - lastworldFrameCountForReplay = -1; - lastNetworkPlayerConnectionCheck = time (NULL); - inJoinGameLoading = false; - quitGameCalled = false; - disableSpeedChange = false; - - for (int i = 0; i < GameConstants::networkSmoothInterval; i++) - { - receivedTooEarlyInFrames[i] = -1; - framesNeededToWaitForServerMessage[i] = -1; - } - - fadeMusicMilliseconds = - Config::getInstance ().getInt ("GameStartStopFadeSoundMilliseconds", - intToStr (fadeMusicMilliseconds).c_str - ()); - GAME_STATS_DUMP_INTERVAL = - Config::getInstance ().getInt ("GameStatsDumpIntervalSeconds", - intToStr - (GAME_STATS_DUMP_INTERVAL).c_str ()); - } - - void Game::resetMembers () - { - Unit::setGame (this); - gameStarted = false; - this->initialResumeSpeedLoops = false; - - original_updateFps = GameConstants::updateFps; - original_cameraFps = GameConstants::cameraFps; - GameConstants::updateFps = 40; - GameConstants::cameraFps = 100; - captureAvgTestStatus = false; - updateFpsAvgTest = 0; - renderFpsAvgTest = 0; - lastRenderLog2d = 0; - playerIndexDisconnect = 0; - lastMasterServerGameStatsDump = 0; - highlightCellTexture = NULL; - totalRenderFps = 0; - lastMaxUnitCalcTime = 0; - renderExtraTeamColor = 0; - - mouseMoved = false; - quitTriggeredIndicator = false; - quitPendingIndicator = false; - originalDisplayMsgCallback = NULL; - thisGamePtr = this; - - popupMenu.setEnabled (false); - popupMenu.setVisible (false); - - popupMenuSwitchTeams.setEnabled (false); - popupMenuSwitchTeams.setVisible (false); - - popupMenuDisconnectPlayer.setEnabled (false); - popupMenuDisconnectPlayer.setVisible (false); - - switchTeamConfirmMessageBox.setEnabled (false); - disconnectPlayerConfirmMessageBox.setEnabled (false); - - disconnectPlayerIndexMap.clear (); - - exitGamePopupMenuIndex = -1; - joinTeamPopupMenuIndex = -1; - pauseGamePopupMenuIndex = -1; - saveGamePopupMenuIndex = -1; - loadGamePopupMenuIndex = -1; - keyboardSetupPopupMenuIndex = -1; - disconnectPlayerPopupMenuIndex = -1; - - isMarkCellEnabled = false; - isMarkCellTextEnabled = false; - - markCellTexture = NULL; - isUnMarkCellEnabled = false; - unmarkCellTexture = NULL; - - currentUIState = NULL; - - scrollSpeed = Config::getInstance ().getFloat ("UiScrollSpeed", "1.5"); - photoModeEnabled = - Config::getInstance ().getBool ("PhotoMode", "false"); - healthbarMode = Config::getInstance ().getInt ("HealthBarMode", "4"); - visibleHUD = Config::getInstance ().getBool ("VisibleHud", "true"); - timeDisplay = Config::getInstance ().getBool ("TimeDisplay", "true"); - withRainEffect = Config::getInstance ().getBool ("RainEffect", "true"); - //MIN_RENDER_FPS_ALLOWED = Config::getInstance().getInt("MIN_RENDER_FPS_ALLOWED",intToStr(MIN_RENDER_FPS_ALLOWED).c_str()); - - mouseX = 0; - mouseY = 0; - mouse2d = 0; - loadingText = ""; - weatherParticleSystem = NULL; - updateFps = 0; - renderFps = 0; - lastUpdateFps = 0; - framesToCatchUpAsClient = 0; - framesToSlowDownAsClient = 0; - lastRenderFps = -1; - avgUpdateFps = -1; - avgRenderFps = -1; - currentAvgRenderFpsTotal = 0; - tickCount = 0; - paused = false; - networkPauseGameForLaggedClientsRequested = false; - networkResumeGameForLaggedClientsRequested = false; - pausedForJoinGame = false; - pausedBeforeJoinGame = false; - resumeRequestSent = false; - pauseRequestSent = false; - pauseStateChanged = false; - gameOver = false; - renderNetworkStatus = false; - renderInGamePerformance = false; - this->speed = 1; - showFullConsole = false; - setMarker = false; - cameraDragAllowed = false; - camLeftButtonDown = false; - camRightButtonDown = false; - camUpButtonDown = false; - camDownButtonDown = false; - - currentCameraFollowUnit = NULL; - currentAmbientSound = NULL; - //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); - - loadGameNode = NULL; - lastworldFrameCountForReplay = -1; - - lastNetworkPlayerConnectionCheck = time (NULL); - - inJoinGameLoading = false; - quitGameCalled = false; - disableSpeedChange = false; - - for (int i = 0; i < GameConstants::networkSmoothInterval; i++) - { - receivedTooEarlyInFrames[i] = -1; - framesNeededToWaitForServerMessage[i] = -1; - } - - - fadeMusicMilliseconds = - Config::getInstance ().getInt ("GameStartStopFadeSoundMilliseconds", - intToStr (fadeMusicMilliseconds).c_str - ()); - GAME_STATS_DUMP_INTERVAL = - Config::getInstance ().getInt ("GameStatsDumpIntervalSeconds", - intToStr - (GAME_STATS_DUMP_INTERVAL).c_str ()); - - Logger & logger = Logger::getInstance (); - logger.showProgress (); - } - - Game::Game (Program * program, const GameSettings * gameSettings, - bool masterserverMode):ProgramState (program), - lastMousePos (0), isFirstRender (true) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - this->masterserverMode = masterserverMode; - videoPlayer = NULL; - playingStaticVideo = false; - highlightCellTexture = NULL; - playerIndexDisconnect = 0; - updateFpsAvgTest = 0; - renderFpsAvgTest = 0; - cameraDragAllowed = false; - - if (this->masterserverMode == true) - { - printf ("Starting a new game...\n"); - } - - this->program = program; - resetMembers (); - this->gameSettings = *gameSettings; - - Lang::getInstance ().setAllowNativeLanguageTechtree (this-> - gameSettings.getNetworkAllowNativeLanguageTechtree - ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - void Game::endGame () - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - quitGame (); - sleep (0); - - Object::setStateCallback (NULL); - thisGamePtr = NULL; - if (originalDisplayMsgCallback != NULL) - { - NetworkInterface::setDisplayMessageFunction - (originalDisplayMsgCallback); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - Logger & logger = Logger::getInstance (); - Renderer & renderer = Renderer::getInstance (); - - logger.clearHints (); - logger.loadLoadingScreen (""); - logger.setState (Lang::getInstance ().getString ("Deleting")); - //logger.add("Game", true); - logger. - add (Lang:: - getInstance ().getString ("LogScreenGameLoading", "", true), - false); - logger.hideProgress (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - // Cannot Fade because sound files will be deleted below - SoundRenderer::getInstance ().stopAllSounds (fadeMusicMilliseconds); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -// deleteValues(aiInterfaces.begin(), aiInterfaces.end()); -// aiInterfaces.clear(); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - gui.end (); //selection must be cleared before deleting units - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -// world.end(); //must die before selection because of referencers - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] aiInterfaces.size() = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - aiInterfaces.size ()); - - // MUST DO THIS LAST!!!! Because objects above have pointers to things like - // unit particles and fade them out etc and this end method deletes the original - // object pointers. - renderer.endGame (false); - - GameConstants::updateFps = original_updateFps; - GameConstants::cameraFps = original_cameraFps; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - Unit::setGame (NULL); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] ==== END GAME ==== getCurrentPixelByteCount() = " - MG_SIZE_T_SPECIFIER "\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderer.getCurrentPixelByteCount ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled) - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "==== END GAME ====\n"); - - FileCRCPreCacheThread *&preCacheCRCThreadPtr = - CacheManager::getCachedItem < - FileCRCPreCacheThread * - >(GameConstants::preCacheThreadCacheLookupKey); - if (preCacheCRCThreadPtr != NULL) - { - preCacheCRCThreadPtr->setPauseForGame (false); - } - - //this->program->reInitGl(); - //renderer.reinitAll(); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - } - - Game::~Game () - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - quitGame (); - - Object::setStateCallback (NULL); - thisGamePtr = NULL; - if (originalDisplayMsgCallback != NULL) - { - NetworkInterface::setDisplayMessageFunction - (originalDisplayMsgCallback); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - Logger & logger = Logger::getInstance (); - Renderer & renderer = Renderer::getInstance (); - - logger.loadLoadingScreen (""); - logger.setState (Lang::getInstance ().getString ("Deleting")); - //logger.add("Game", true); - logger. - add (Lang:: - getInstance ().getString ("LogScreenGameLoading", "", true), - false); - logger.hideProgress (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - // Cannot Fade because sound files will be deleted below - SoundRenderer::getInstance ().stopAllSounds (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - masterController.clearSlaves (true); - deleteValues (aiInterfaces.begin (), aiInterfaces.end ()); - aiInterfaces.clear (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - gui.end (); //selection must be cleared before deleting units - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - world.end (); //must die before selection because of referencers - - BaseColorPickEntity::resetUniqueColors (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] aiInterfaces.size() = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - aiInterfaces.size ()); - - delete videoPlayer; - videoPlayer = NULL; - playingStaticVideo = false; - - // MUST DO THIS LAST!!!! Because objects above have pointers to things like - // unit particles and fade them out etc and this end method deletes the original - // object pointers. - renderer.endGame (true); - BaseColorPickEntity::cleanupPBO (); - - GameConstants::updateFps = original_updateFps; - GameConstants::cameraFps = original_cameraFps; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - Unit::setGame (NULL); - - Lang::getInstance ().setAllowNativeLanguageTechtree (true); - - FileCRCPreCacheThread *&preCacheCRCThreadPtr = - CacheManager::getCachedItem < - FileCRCPreCacheThread * - >(GameConstants::preCacheThreadCacheLookupKey); - if (preCacheCRCThreadPtr != NULL) - { - preCacheCRCThreadPtr->setPauseForGame (false); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] ==== END GAME ==== getCurrentPixelByteCount() = " - MG_SIZE_T_SPECIFIER "\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderer.getCurrentPixelByteCount ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled) - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "==== END GAME ====\n"); - - //this->program->reInitGl(); - //renderer.reinitAll(); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - } - - bool Game::showTranslatedTechTree ()const - { - return this->gameSettings.getNetworkAllowNativeLanguageTechtree (); - } - - bool Game::quitTriggered () - { - return quitTriggeredIndicator; - } - - Stats Game::quitAndToggleState () - { - //quitGame(); - //Program *program = game->getProgram(); - return quitGame (); - //Game::exitGameState(program, endStats); - } - -// ==================== init and load ==================== - - int Game::ErrorDisplayMessage (const char *msg, bool exitApp) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] %s\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - msg); - - if (thisGamePtr != NULL) - { - string text = msg; - thisGamePtr->showErrorMessageBox (text, "Error detected", false); - } - - return 0; - } - -//Texture2D * Game::findFactionLogoTexture(const GameSettings *settings, Logger *logger,string factionLogoFilter, bool useTechDefaultIfFilterNotFound) { -// Texture2D *result = NULL; -// string logoFilename = Game::findFactionLogoFile(settings, logger,factionLogoFilter); -// if(logoFilename == "" && factionLogoFilter != "" && useTechDefaultIfFilterNotFound == true) { -// logoFilename = Game::findFactionLogoFile(settings, logger); -// } -// -// result = Renderer::findTexture(logoFilename); -// -// return result; -//} - - string - Game::extractScenarioLogoFile (const GameSettings * settings, - string & result, bool & loadingImageUsed, - Logger * logger, - string factionLogoFilter) - { - string scenarioDir = ""; - if (settings->getScenarioDir () != "") - { - scenarioDir = settings->getScenarioDir (); - if (EndsWith (scenarioDir, ".xml") == true) - { - scenarioDir = scenarioDir.erase (scenarioDir.size () - 4, 4); - scenarioDir = - scenarioDir.erase (scenarioDir.size () - - settings->getScenario ().size (), - settings->getScenario ().size () + 1); - } - - //printf("!!! extractScenarioLogoFile scenarioDir [%s] factionLogoFilter [%s]\n",scenarioDir.c_str(),factionLogoFilter.c_str()); - - vector < string > loadScreenList; - string logoFullPathFilter = scenarioDir + factionLogoFilter; - findAll (logoFullPathFilter, loadScreenList, false, false); - if (loadScreenList.empty () == false) - { - int bestLogoIndex = 0; - - if (loadScreenList.size () > 1 - && EndsWith (factionLogoFilter, ".xml") == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\nLooking for best logo from a list of: " - MG_SIZE_T_SPECIFIER " using filter: [%s]\n", - loadScreenList.size (), logoFullPathFilter.c_str ()); - - int bestMinWidthDiff = INT_MAX; - int bestMinHeightDiff = INT_MAX; - // Now find the best texture for our screen - // Texture2D *result = preloadTexture(logoFilename); - for (unsigned int logoIndex = 0; - logoIndex < loadScreenList.size (); ++logoIndex) - { - string - senarioLogo = scenarioDir + loadScreenList[bestLogoIndex]; - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] looking for loading screen '%s'\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, senarioLogo.c_str ()); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Looking for best logo: %u [%s]\n", logoIndex, - senarioLogo.c_str ()); - - if (fileExists (senarioLogo) == true) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found loading screen '%s'\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, senarioLogo.c_str ()); - - Texture2D *checkLogo = Renderer::preloadTexture (senarioLogo); - if (checkLogo != NULL) - { - const Metrics & metrics = Metrics::getInstance (); - int - minWidthDifference = - abs (metrics.getScreenW () - - checkLogo->getPixmapConst ()->getW ()); - int - minHeightDifference = - abs (metrics.getScreenH () - - checkLogo->getPixmapConst ()->getH ()); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Logo info: %d x %d (%d,%d)\n", - checkLogo->getPixmapConst ()->getW (), - checkLogo->getPixmapConst ()->getH (), - minWidthDifference, minHeightDifference); - - if (minWidthDifference < bestMinWidthDiff) - { - bestMinWidthDiff = minWidthDifference; - - bestLogoIndex = logoIndex; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#1 New best logo is [%s]\n", - senarioLogo.c_str ()); - } - else if (minWidthDifference == bestMinWidthDiff - && minHeightDifference < bestMinHeightDiff) - { - bestMinHeightDiff = minHeightDifference; - - bestLogoIndex = logoIndex; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#2 New best logo is [%s]\n", - senarioLogo.c_str ()); - } - } - } - } - } - - string senarioLogo = scenarioDir + loadScreenList[bestLogoIndex]; - if (fileExists (senarioLogo) == true) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] found scenario loading screen '%s'\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - senarioLogo.c_str ()); - - result = senarioLogo; - if (logger != NULL) - { - logger->loadLoadingScreen (result); - } - loadingImageUsed = true; - } - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, - settings->getScenarioDir ().c_str (), - settings->getScenario ().c_str (), - scenarioDir.c_str ()); - } - return scenarioDir; - } - - string - Game::extractFactionLogoFile (bool & loadingImageUsed, - const string & factionName, - string scenarioDir, - const string & techName, Logger * logger, - string factionLogoFilter) - { - string result = ""; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] Searching for faction loading screen\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (factionName == formatString (GameConstants::OBSERVER_SLOTNAME)) - { - string - data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - const string - factionLogo = data_path + "data/core/misc_textures/observer.jpg"; - //printf("In [%s::%s Line: %d] looking for loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,factionLogo.c_str()); - - if (fileExists (factionLogo) == true) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found loading screen '%s'\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - factionLogo.c_str ()); - - result = factionLogo; - if (logger != NULL) - { - logger->loadLoadingScreen (result); - } - loadingImageUsed = true; - } - } - //else if(settings->getFactionTypeName(i) == formatString(GameConstants::RANDOMFACTION_SLOTNAME)) { - else if (factionName == - formatString (GameConstants::RANDOMFACTION_SLOTNAME)) - { - string - data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - const string - factionLogo = data_path + "data/core/misc_textures/random.jpg"; - - if (fileExists (factionLogo) == true) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found loading screen '%s'\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - factionLogo.c_str ()); - - result = factionLogo; - if (logger != NULL) - { - logger->loadLoadingScreen (result); - } - loadingImageUsed = true; - } - } - else - { - Config & config = Config::getInstance (); - vector < string > pathList = - config.getPathListForType (ptTechs, scenarioDir); - for (int idx = 0; idx < (int) pathList.size (); idx++) - { - string currentPath = pathList[idx]; - endPathWithSlash (currentPath); - //string path = currentPath + techName + "/" + "factions" + "/" + settings->getFactionTypeName(i); - string - path = - currentPath + techName + "/" + "factions" + "/" + factionName; - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] possible loading screen dir '%s'\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - path.c_str ()); - if (isdir (path.c_str ()) == true) - { - endPathWithSlash (path); - - vector < string > loadScreenList; - string logoFullPathFilter = path + factionLogoFilter; - findAll (logoFullPathFilter, loadScreenList, false, false); - if (loadScreenList.empty () == false) - { - int bestLogoIndex = 0; - - if (loadScreenList.size () > 1 - && EndsWith (factionLogoFilter, ".xml") == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\nLooking for best logo from a list of: " - MG_SIZE_T_SPECIFIER - " using filter: [%s]\n", - loadScreenList.size (), - logoFullPathFilter.c_str ()); - - - int bestMinWidthDiff = INT_MAX; - int bestMinHeightDiff = INT_MAX; - // Now find the best texture for our screen - // Texture2D *result = preloadTexture(logoFilename); - for (unsigned int logoIndex = 0; - logoIndex < - (unsigned int) loadScreenList.size (); ++logoIndex) - { - string factionLogo = path + loadScreenList[logoIndex]; - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] looking for loading screen '%s'\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - factionLogo.c_str ()); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Looking for best logo: %u [%s]\n", - logoIndex, factionLogo.c_str ()); - - if (fileExists (factionLogo) == true) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found loading screen '%s'\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - factionLogo.c_str ()); - - Texture2D *checkLogo = - Renderer::preloadTexture (factionLogo); - if (checkLogo != NULL) - { - const Metrics & metrics = Metrics::getInstance (); - int - minWidthDifference = - abs (metrics.getScreenW () - - checkLogo->getPixmapConst ()->getW ()); - int - minHeightDifference = - abs (metrics.getScreenH () - - checkLogo->getPixmapConst ()->getH ()); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("Logo info: %d x %d (%d,%d)\n", - checkLogo->getPixmapConst ()->getW (), - checkLogo->getPixmapConst ()->getH (), - minWidthDifference, minHeightDifference); - - if (minWidthDifference < bestMinWidthDiff) - { - bestMinWidthDiff = minWidthDifference; - - bestLogoIndex = logoIndex; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("#1 New best logo is [%s]\n", - factionLogo.c_str ()); - } - else if (minWidthDifference == - bestMinWidthDiff - && minHeightDifference < bestMinHeightDiff) - { - bestMinHeightDiff = minHeightDifference; - - bestLogoIndex = logoIndex; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("#2 New best logo is [%s]\n", - factionLogo.c_str ()); - } - } - } - } - } - - string factionLogo = path + loadScreenList[bestLogoIndex]; - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] looking for loading screen '%s'\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, factionLogo.c_str ()); - - if (fileExists (factionLogo) == true) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found loading screen '%s'\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, factionLogo.c_str ()); - - result = factionLogo; - if (logger != NULL) - { - logger->loadLoadingScreen (result); - } - loadingImageUsed = true; - break; - } - } - // Check if this is a linked faction - else - { - //!!! - string factionXMLFile = path + factionName + ".xml"; - - //printf("A factionXMLFile [%s]\n",factionXMLFile.c_str()); - - if (fileExists (factionXMLFile) == true) - { - XmlTree xmlTreeFaction (XML_RAPIDXML_ENGINE); - std::map < string, string > mapExtraTagReplacementValues; - xmlTreeFaction.load (factionXMLFile, - Properties::getTagReplacementValues - (&mapExtraTagReplacementValues), - true, true); - - const XmlNode *rootNode = xmlTreeFaction.getRootNode (); - - //printf("B factionXMLFile [%s] root name [%s] root first child name [%s]\n",factionXMLFile.c_str(),rootNode->getName().c_str(),rootNode->getChild(0)->getName().c_str()); - //printf("B factionXMLFile [%s] root name [%s]\n",factionXMLFile.c_str(),rootNode->getName().c_str()); - if (rootNode->hasChild ("link") == true) - { - rootNode = rootNode->getChild ("link"); - } - if (rootNode->getName () == "link" - && rootNode->hasChild ("techtree") == true) - { - const XmlNode *linkNode = rootNode; - - //printf("C factionXMLFile [%s]\n",factionXMLFile.c_str()); - - //if(linkNode->hasChild("techtree") == true) { - const XmlNode *techtreeNode = - linkNode->getChild ("techtree"); - - string - linkedTechTreeName = - techtreeNode->getAttribute ("name")->getValue (); - - //printf("D factionXMLFile [%s] linkedTechTreeName [%s]\n",factionXMLFile.c_str(),linkedTechTreeName.c_str()); - - if (linkedTechTreeName != "") - { - - string - linkedTechTreePath = - TechTree::findPath (linkedTechTreeName, pathList); - string techTreePath = linkedTechTreePath; - endPathWithSlash (techTreePath); - - string - linkedCurrentPath = - techTreePath + "factions/" + factionName; - endPathWithSlash (linkedCurrentPath); - //string linkedTmppath= linkedCurrentPath + factionName +".xml"; - - path = linkedCurrentPath; - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] possible loading screen dir '%s'\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - path.c_str ()); - - //printf("D1 idx = %d\ncurrentPath [%s]\npath [%s]\npathList[idx] [%s]\n",idx,currentPath.c_str(),path.c_str(),pathList[idx].c_str()); - - if (isdir (path.c_str ()) == true) - { - endPathWithSlash (path); - - //printf("E path [%s]\n",path.c_str()); - - loadScreenList.clear (); - findAll (path + factionLogoFilter, - loadScreenList, false, false); - if (loadScreenList.empty () == false) - { - string factionLogo = path + loadScreenList[0]; - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] looking for loading screen '%s'\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, - __LINE__, - factionLogo.c_str ()); - - //printf("F factionLogo [%s]\n",factionLogo.c_str()); - - if (fileExists (factionLogo) == true) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug - (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found loading screen '%s'\n", - extractFileFromDirectoryPath (__FILE__).c_str - (), __FUNCTION__, __LINE__, - factionLogo.c_str ()); - - result = factionLogo; - if (logger != NULL) - { - logger->loadLoadingScreen (result); - } - loadingImageUsed = true; - break; - } - } - } - } - //} - } - } - } - } - - if (loadingImageUsed == true) - { - break; - } - } - } - //break; - //} - //} - return result; - } - - string - Game::extractTechLogoFile (string scenarioDir, const string & techName, - bool & loadingImageUsed, Logger * logger, - const string & factionLogoFilter) - { - string result = ""; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] Searching for tech loading screen\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - Config & config = Config::getInstance (); - vector < string > pathList = - config.getPathListForType (ptTechs, scenarioDir); - for (int idx = 0; idx < (int) pathList.size (); idx++) - { - string currentPath = pathList[idx]; - endPathWithSlash (currentPath); - string path = currentPath + techName; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] possible loading screen dir '%s'\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, path.c_str ()); - if (isdir (path.c_str ()) == true) - { - endPathWithSlash (path); - - vector < string > loadScreenList; - findAll (path + factionLogoFilter, loadScreenList, false, false); - if (loadScreenList.empty () == false) - { - string factionLogo = path + loadScreenList[0]; - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] looking for loading screen '%s'\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, factionLogo.c_str ()); - - if (fileExists (factionLogo) == true) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found loading screen '%s'\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, factionLogo.c_str ()); - - result = factionLogo; - if (logger != NULL) - { - logger->loadLoadingScreen (result); - } - loadingImageUsed = true; - break; - } - } - } - if (loadingImageUsed == true) - { - break; - } - } - - return result; - } - - void Game::loadHudTexture (const GameSettings * settings) - { - string factionName = ""; - string techName = settings->getTech (); - string - scenarioDir = - extractDirectoryPathFromFile (settings->getScenarioDir ()); - //printf("In loadHudTexture, scenarioDir [%s]\n",scenarioDir.c_str()); - - for (int i = 0; i < settings->getFactionCount (); ++i) - { - if ((settings->getFactionControl (i) == ctHuman) - || (settings->getFactionControl (i) == ctNetwork - && settings->getThisFactionIndex () == i)) - { - factionName = settings->getFactionTypeName (i); - break; - } - } - if (factionName != "") - { - bool hudFound = false; - Config & config = Config::getInstance (); - vector < string > pathList = - config.getPathListForType (ptTechs, scenarioDir); - for (int idx = 0; hudFound == false && idx < (int) pathList.size (); - idx++) - { - string currentPath = pathList[idx]; - endPathWithSlash (currentPath); - - vector < string > hudList; - string - path = - currentPath + techName + "/" + "factions" + "/" + factionName; - endPathWithSlash (path); - findAll (path + GameConstants::HUD_SCREEN_FILE_FILTER, hudList, - false, false); - if (hudList.empty () == false) - { - for (unsigned int hudIdx = 0; - hudFound == false - && hudIdx < (unsigned int) hudList.size (); ++hudIdx) - { - string hudImageFileName = path + hudList[hudIdx]; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line: %d] looking for a HUD [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, hudImageFileName.c_str ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] looking for a HUD [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, - hudImageFileName.c_str ()); - - if (fileExists (hudImageFileName) == true) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line: %d] found HUD image [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, hudImageFileName.c_str ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] found HUD image [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, - hudImageFileName.c_str ()); - - Texture2D *texture = Renderer::findTexture (hudImageFileName); - gui.setHudTexture (texture); - hudFound = true; - //printf("Hud texture found! \n"); - break; - } - } - } - } - } - } - - string - Game::findFactionLogoFile (const GameSettings * settings, - Logger * logger, - const string & factionLogoFilter) - { - string result = ""; - if (settings == NULL) - { - result = ""; - } - else - { - string mapName = settings->getMap (); - string tilesetName = settings->getTileset (); - string techName = settings->getTech (); - string scenarioName = settings->getScenario (); - bool loadingImageUsed = false; - - if (logger != NULL) - { - logger->setState (Lang::getInstance ().getString ("Loading")); - - if (scenarioName.empty ()) - { - string - scenarioDir = - extractDirectoryPathFromFile (settings->getScenarioDir ()); - TechTree - techTree (Config:: - getInstance ().getPathListForType (ptTechs, - scenarioDir)); - - logger->setSubtitle (formatString (mapName) + " - " + - formatString (tilesetName) + " - " + - formatString (techTree.getTranslatedName - (techName))); - } - else - { - logger->setSubtitle (formatString (scenarioName)); - } - } - - //string scenarioDir = ""; - //bool skipCustomLoadScreen = false; - //if(skipCustomLoadScreen == false) { - string - scenarioDir = - extractScenarioLogoFile (settings, result, loadingImageUsed, - logger, factionLogoFilter); - //} - // try to use a faction related loading screen - //if(skipCustomLoadScreen == false && loadingImageUsed == false) { - if (loadingImageUsed == false) - { - for (int i = 0; i < settings->getFactionCount (); ++i) - { - if (settings->getFactionControl (i) == ctHuman || - (settings->getFactionControl (i) == ctNetwork - && settings->getThisFactionIndex () == i)) - { - - result = - extractFactionLogoFile (loadingImageUsed, - settings->getFactionTypeName (i), - scenarioDir, techName, logger, - factionLogoFilter); - break; - } - } - } - - // try to use a tech related loading screen - //if(skipCustomLoadScreen == false && loadingImageUsed == false){ - if (loadingImageUsed == false) - { - result = extractTechLogoFile (scenarioDir, techName, - loadingImageUsed, logger, - factionLogoFilter); - } - } - return result; - } - - vector < Texture2D * >Game::processTech (string techName) - { - vector < Texture2D * >logoFiles; - bool - enableFactionTexturePreview = - Config::getInstance ().getBool ("FactionPreview", "true"); - if (enableFactionTexturePreview) - { - //string currentTechName_factionPreview = techName; - - vector < string > factions; - vector < string > techPaths = - Config::getInstance ().getPathListForType (ptTechs); - for (int idx = 0; idx < (int) techPaths.size (); idx++) - { - string & techPath = techPaths[idx]; - endPathWithSlash (techPath); - findAll (techPath + techName + "/factions/*.", factions, false, - false); - - if (factions.empty () == false) - { - for (unsigned int factionIdx = 0; - factionIdx < (unsigned int) factions.size (); ++factionIdx) - { - bool loadingImageUsed = false; - string currentFactionName_factionPreview = factions[factionIdx]; - - string - factionLogo = - Game::extractFactionLogoFile (loadingImageUsed, - currentFactionName_factionPreview, - "", - techName, - NULL, - GameConstants::PREVIEW_SCREEN_FILE_FILTER); - - if (factionLogo == "") - { - factionLogo = - Game::extractFactionLogoFile (loadingImageUsed, - currentFactionName_factionPreview, - "", techName, NULL, - GameConstants::LOADING_SCREEN_FILE_FILTER); - } - if (factionLogo != "") - { - Texture2D *texture = Renderer::preloadTexture (factionLogo); - logoFiles.push_back (texture); - } - } - } - } - } - - return logoFiles; - } - - void Game::load () - { - load (lgt_All); - } - - void Game::load (int loadTypes) - { - bool - showPerfStats = - Config::getInstance ().getBool ("ShowPerfStats", "false"); - Chrono chronoPerf; - if (showPerfStats) - chronoPerf.start (); - char perfBuf[8096] = ""; - std::vector < string > perfList; - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - FileCRCPreCacheThread *&preCacheCRCThreadPtr = - CacheManager::getCachedItem < - FileCRCPreCacheThread * - >(GameConstants::preCacheThreadCacheLookupKey); - if (preCacheCRCThreadPtr != NULL) - { - preCacheCRCThreadPtr->setPauseForGame (true); - } - - std::map < string, vector < pair < string, string > > >loadedFileList; - originalDisplayMsgCallback = - NetworkInterface::getDisplayMessageFunction (); - NetworkInterface::setDisplayMessageFunction (ErrorDisplayMessage); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] loadTypes = %d, gameSettings = [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - loadTypes, - this->gameSettings.toString ().c_str ()); - - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - soundRenderer.stopAllSounds (fadeMusicMilliseconds); - - BaseColorPickEntity::resetUniqueColors (); - - Config & config = Config::getInstance (); - Logger & logger = Logger::getInstance (); - - string mapName = gameSettings.getMap (); - string tilesetName = gameSettings.getTileset (); - string techName = gameSettings.getTech (); - string scenarioName = gameSettings.getScenario (); - string - data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - // loadHints - - if (data_path != "") - { - endPathWithSlash (data_path); - } - - string user_data_path = config.getString ("UserData_Root", ""); - if (user_data_path != "") - { - endPathWithSlash (user_data_path); - } - - string - englishFile = - getGameCustomCoreDataPath (data_path, - "data/lang/hint/hint_" + - Lang:: - getInstance ().getDefaultLanguage () + - ".lng"); - string languageFile = - getGameCustomCoreDataPath (data_path, - "data/lang/hint/hint_" + - Lang::getInstance ().getLanguage () + - ".lng"); - string languageFileUserData = - user_data_path + "data/lang/hint/hint_" + - Lang::getInstance ().getLanguage () + ".lng"; - - if (fileExists (languageFileUserData) == true) - { - languageFile = languageFileUserData; - } - if (fileExists (languageFile) == false) - { - // if there is no language specific file use english instead - languageFile = englishFile; - } - if (fileExists (englishFile) == false) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] file [%s] not found\n", - __FILE__, __FUNCTION__, __LINE__, - englishFile.c_str ()); - } - else - { - logger.loadGameHints (englishFile, languageFile, true); - - ::Shared::Platform::Window::handleEvent (); - SDL_PumpEvents (); - } - - if ((loadTypes & lgt_FactionPreview) == lgt_FactionPreview) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - Game::findFactionLogoFile (&gameSettings, &logger); - - ::Shared::Platform::Window::handleEvent (); - SDL_PumpEvents (); - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - loadHudTexture (&gameSettings); - - const string - markCellTextureFilename = - data_path + "data/core/misc_textures/mark_cell.png"; - markCellTexture = Renderer::findTexture (markCellTextureFilename); - const string - unmarkCellTextureFilename = - data_path + "data/core/misc_textures/unmark_cell.png"; - unmarkCellTexture = Renderer::findTexture (unmarkCellTextureFilename); - const string - highlightCellTextureFilename = - data_path + "data/core/misc_textures/pointer.png"; - highlightCellTexture = - Renderer::findTexture (highlightCellTextureFilename); - - string scenarioDir = ""; - if (gameSettings.getScenarioDir () != "") - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - scenarioDir = gameSettings.getScenarioDir (); - if (EndsWith (scenarioDir, ".xml") == true) - { - scenarioDir = scenarioDir.erase (scenarioDir.size () - 4, 4); - scenarioDir = - scenarioDir.erase (scenarioDir.size () - - gameSettings.getScenario ().size (), - gameSettings.getScenario ().size () + 1); - } - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - //tileset - if ((loadTypes & lgt_TileSet) == lgt_TileSet) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - world. - loadTileset (config.getPathListForType (ptTilesets, scenarioDir), - tilesetName, &checksum, loadedFileList); - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - // give CPU time to update other things to avoid apperance of hanging - sleep (0); - ::Shared::Platform::Window::handleEvent (); - SDL_PumpEvents (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - set < string > factions; - for (int i = 0; i < gameSettings.getFactionCount (); ++i) - { - factions.insert (gameSettings.getFactionTypeName (i)); - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if ((loadTypes & lgt_TechTree) == lgt_TechTree) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - //tech, load before map because of resources - world.loadTech (config.getPathListForType (ptTechs, scenarioDir), - techName, factions, &checksum, loadedFileList); - - if (world.getTechTree () == NULL - || world.getTechTree ()->getNameUntranslated () == "") - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Line ref: %d, ERROR: Cannot find techtree: [%s]", - __LINE__, techName.c_str ()); - - throw megaglest_runtime_error (szBuf, true); - } - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - // give CPU time to update other things to avoid apperance of hanging - sleep (0); - ::Shared::Platform::Window::handleEvent (); - SDL_PumpEvents (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - //map - if ((loadTypes & lgt_Map) == lgt_Map) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - world.loadMap (Config::getMapPath (mapName, scenarioDir), &checksum); - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - // give CPU time to update other things to avoid apperance of hanging - sleep (0); - ::Shared::Platform::Window::handleEvent (); - SDL_PumpEvents (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - //scenario - if ((loadTypes & lgt_Scenario) == lgt_Scenario) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - if (scenarioName.empty () == false) - { - - bool - isTutorial = - Scenario::isGameTutorial (gameSettings.getScenarioDir ()); - //printf("Loading scenario gameSettings.getScenarioDir() [%s] scenarioName [%s] isTutorial: %d\n",gameSettings.getScenarioDir().c_str(),scenarioName.c_str(),isTutorial); - - Lang::getInstance (). - loadScenarioStrings (gameSettings.getScenarioDir (), scenarioName, - isTutorial); - - //printf("In [%s::%s Line: %d] rootNode [%p][%s]\n",__FILE__,__FUNCTION__,__LINE__,loadGameNode,(loadGameNode != NULL ? loadGameNode->getName().c_str() : "none")); - world.loadScenario (gameSettings.getScenarioDir (), &checksum, - false, loadGameNode); - } - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - // give CPU time to update other things to avoid apperance of hanging - sleep (0); - SDL_PumpEvents (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - //good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if (showPerfStats && chronoPerf.getMillis () >= 50) - { - for (unsigned int x = 0; x < perfList.size (); ++x) - { - printf ("%s", perfList[x].c_str ()); - } - } - } - - void Game::init () - { - init (false); - } - - void Game::init (bool initForPreviewOnly) - { - bool - showPerfStats = - Config::getInstance ().getBool ("ShowPerfStats", "false"); - Chrono chronoPerf; - if (showPerfStats) - chronoPerf.start (); - char perfBuf[8096] = ""; - std::vector < string > perfList; - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] initForPreviewOnly = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - initForPreviewOnly); - - Lang & lang = Lang::getInstance (); - Logger & logger = Logger::getInstance (); - CoreData & coreData = CoreData::getInstance (); - Renderer & renderer = Renderer::getInstance (); - Map *map = world.getMap (); - NetworkManager & networkManager = NetworkManager::getInstance (); - - GameSettings::playerDisconnectedText = - "*" + lang.getString ("AI") + "* "; - - if (map == NULL) - { - throw megaglest_runtime_error ("map == NULL"); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (initForPreviewOnly == false) - { - logger.setState (lang.getString ("Initializing")); - - //message box - mainMessageBox.init (lang.getString ("Yes"), lang.getString ("No")); - mainMessageBox.setEnabled (false); - - //message box - errorMessageBox.init (lang.getString ("Ok")); - errorMessageBox.setEnabled (false); - errorMessageBox.setY (20); - - - //init world, and place camera - commander.init (&world); - - // give CPU time to update other things to avoid apperance of hanging - sleep (0); - ::Shared::Platform::Window::handleEvent (); - SDL_PumpEvents (); - } - - try - { - world.init (this, gameSettings.getDefaultUnits ()); - } - catch (const megaglest_runtime_error & ex) - { - string sErrBuf = ""; - if (ex.wantStackTrace () == true) - { - char szErrBuf[8096] = ""; - snprintf (szErrBuf, 8096, "In [%s::%s %d]", __FILE__, - __FUNCTION__, __LINE__); - sErrBuf = - string (szErrBuf) + string ("\nerror [") + string (ex.what ()) + - string ("]\n"); - } - else - { - sErrBuf = ex.what (); - } - SystemFlags::OutputDebug (SystemFlags::debugError, sErrBuf.c_str ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - sErrBuf.c_str ()); - - if (errorMessageBox.getEnabled () == false) - { - ErrorDisplayMessage (ex.what (), true); - } - } - catch (const exception & ex) - { - char szErrBuf[8096] = ""; - snprintf (szErrBuf, 8096, "In [%s::%s %d]", __FILE__, __FUNCTION__, - __LINE__); - string - sErrBuf = - string (szErrBuf) + string ("\nerror [") + string (ex.what ()) + - string ("]\n"); - SystemFlags::OutputDebug (SystemFlags::debugError, sErrBuf.c_str ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - sErrBuf.c_str ()); - - if (errorMessageBox.getEnabled () == false) - { - ErrorDisplayMessage (ex.what (), true); - } - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (loadGameNode != NULL) - { - //world.getMapPtr()->loadGame(loadGameNode,&world); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (initForPreviewOnly == false) - { - // give CPU time to update other things to avoid apperance of hanging - sleep (0); - ::Shared::Platform::Window::handleEvent (); - SDL_PumpEvents (); - - gui.init (this); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - // give CPU time to update other things to avoid apperance of hanging - sleep (0); - //SDL_PumpEvents(); - - chatManager.init (&console, world.getThisTeamIndex ()); - console.clearStoredLines (); - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (this->loadGameNode == NULL) - { - initCamera (map); - } - else - { - gui.loadGame (loadGameNode, &world); - - if (inJoinGameLoading == true) - { - initCamera (map); - } - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - NetworkRole role = nrIdle; - if (initForPreviewOnly == false) - { - // give CPU time to update other things to avoid apperance of hanging - sleep (0); - ::Shared::Platform::Window::handleEvent (); - SDL_PumpEvents (); - - scriptManager.init (&world, &gameCamera, loadGameNode); - - //good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] creating AI's\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - //create AIs - - bool - enableServerControlledAI = - this->gameSettings.getEnableServerControlledAI (); - bool isNetworkGame = this->gameSettings.isNetworkGame (); - role = networkManager.getNetworkRole (); - - masterController.clearSlaves (true); - deleteValues (aiInterfaces.begin (), aiInterfaces.end ()); - - std::vector < SlaveThreadControllerInterface * >slaveThreadList; - aiInterfaces.resize (world.getFactionCount ()); - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - - //printf("Controltype = %d for index = %d\n",faction->getControlType(),i); - - if (faction->getCpuControl (enableServerControlledAI, isNetworkGame, - role) == true) - { - //printf("** Loading AI player for Controltype = %d for index = %d\n",faction->getControlType(),i); - - aiInterfaces[i] = new AiInterface (*this, i, faction->getTeam ()); - if (loadGameNode != NULL) - { - aiInterfaces[i]->loadGame (loadGameNode, faction); - } - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - Lang::getInstance ().getString - ("LogScreenGameLoadingCreatingAIFaction", "", - true).c_str (), i); - logger.add (szBuf, true); - - slaveThreadList.push_back (aiInterfaces[i]->getWorkerThread ()); - } - else - { - aiInterfaces[i] = NULL; - } - } - if (Config:: - getInstance ().getBool ("EnableNewThreadManager", - "false") == true) - { - masterController.setSlaves (slaveThreadList); - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER - "\n", extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - // give CPU time to update other things to avoid apperance of hanging - sleep (0); - ::Shared::Platform::Window::handleEvent (); - SDL_PumpEvents (); - - if (world.getFactionCount () == 1 - && world.getFaction (0)->getPersonalityType () == fpt_Observer) - { - withRainEffect = false; - } - - if (withRainEffect) - { - //weather particle systems - if (world.getTileset ()->getWeather () == wRainy) - { - logger.add (Lang::getInstance ().getString - ("LogScreenGameLoadingCreatingRainParticles", - "", true), true); - weatherParticleSystem = new RainParticleSystem (); - weatherParticleSystem->setSpeed (12.f / GameConstants::updateFps); - weatherParticleSystem->setPos (gameCamera.getPos ()); - renderer.manageParticleSystem (weatherParticleSystem, rsGame); - } - else if (world.getTileset ()->getWeather () == wSnowy) - { - logger.add (Lang::getInstance ().getString - ("LogScreenGameLoadingCreatingSnowParticles", - "", true), true); - weatherParticleSystem = new SnowParticleSystem (1200); - weatherParticleSystem->setSpeed (1.5f / GameConstants::updateFps); - weatherParticleSystem->setPos (gameCamera.getPos ()); - weatherParticleSystem->setTexture (coreData.getSnowTexture ()); - renderer.manageParticleSystem (weatherParticleSystem, rsGame); - } - } - else if (world.getTileset ()->getWeather () == wRainy) - { - world.getTileset ()->setWeather (wSunny); - } - - renderer.manageDeferredParticleSystems (); - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - //init renderer state - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Initializing renderer\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__); - logger. - add (Lang:: - getInstance ().getString ("LogScreenGameLoadingInitRenderer", "", - true), true); - - //printf("Before renderer.initGame\n"); - renderer.initGame (this, this->getGameCameraPtr ()); - //printf("After renderer.initGame\n"); - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - if (faction != NULL) - { - faction->deletePixels (); - } - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (initForPreviewOnly == false) - { - //good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - // give CPU time to update other things to avoid apperance of hanging - sleep (0); - ::Shared::Platform::Window::handleEvent (); - SDL_PumpEvents (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Waiting for network\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__); - logger. - add (Lang:: - getInstance ().getString - ("LogScreenGameLoadingWaitForNetworkPlayers", "", true), true); - networkManager.getGameNetworkInterface ()->waitUntilReady (&checksum); - - //std::string worldLog = world.DumpWorldToLog(true); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] Starting music stream\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - logger. - add (Lang:: - getInstance ().getString ("LogScreenGameLoadingStartingMusic", - "", true), true); - - if (this->masterserverMode == false) - { - if (world.getThisFaction () == NULL) - { - throw megaglest_runtime_error ("world.getThisFaction() == NULL"); - } - if (world.getThisFaction ()->getType () == NULL) - { - throw - megaglest_runtime_error - ("world.getThisFaction()->getType() == NULL"); - } - //if(world.getThisFaction()->getType()->getMusic() == NULL) { - // throw megaglest_runtime_error("world.getThisFaction()->getType()->getMusic() == NULL"); - //} - } - - //sounds - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - soundRenderer.stopAllSounds (fadeMusicMilliseconds); - soundRenderer = SoundRenderer::getInstance (); - - Tileset *tileset = world.getTileset (); - AmbientSounds *ambientSounds = tileset->getAmbientSounds (); - - //rain - if (tileset->getWeather () == wRainy - && ambientSounds->isEnabledRain ()) - { - logger. - add (Lang:: - getInstance ().getString - ("LogScreenGameLoadingStartingAmbient", "", true), true); - currentAmbientSound = ambientSounds->getRain (); - //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); - soundRenderer.playAmbient (currentAmbientSound); - } - - //snow - if (tileset->getWeather () == wSnowy - && ambientSounds->isEnabledSnow ()) - { - logger. - add (Lang:: - getInstance ().getString - ("LogScreenGameLoadingStartingAmbient", "", true), true); - currentAmbientSound = ambientSounds->getSnow (); - //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); - soundRenderer.playAmbient (currentAmbientSound); - } - - if (this->masterserverMode == false) - { - StrSound *gameMusic = - world.getThisFaction ()->getType ()->getMusic (); - soundRenderer.playMusic (gameMusic); - } - - logger. - add (Lang:: - getInstance ().getString ("LogScreenGameLoadingLaunchGame", "", - true)); - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - //throw "test"; - - logger.setCancelLoadingEnabled (false); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "================ STARTING GAME ================\n"); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPathFinder).enabled) - SystemFlags::OutputDebug (SystemFlags::debugPathFinder, - "================ STARTING GAME ================\n"); - setupPopupMenus (false); - - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - - //printf("Check for team switch to observer i = %d, team = %d [%d]\n",i,faction->getTeam(),(GameConstants::maxPlayers -1 + fpt_Observer)); - if (faction != NULL - && faction->getTeam () == - GameConstants::maxPlayers - 1 + fpt_Observer) - { - faction->setPersonalityType (fpt_Observer); - world.getStats ()->setPersonalityType (i, - faction->getPersonalityType - ()); - } - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (role == nrClient) - { - ClientInterface *clientInterface = - dynamic_cast < - ClientInterface * >(networkManager.getClientInterface ()); - if (clientInterface != NULL - && clientInterface->getResumeInGameJoin () == true) - { - - //printf("Client sending resume message to server...\n"); - - clientInterface->sendResumeGameMessage (); - //this->initialResumeSpeedLoops = true; - } - } - - printf ("Game unique identifier is: %s\n", - this->gameSettings.getGameUUID ().c_str ()); - - gameStarted = true; - - if (this->masterserverMode == true) - { - world.getStats ()->setIsMasterserverMode (true); - - printf ("New game has started...\n"); - } - - if (isFlagType1BitEnabled (ft1_network_synch_checks_verbose) == true) - { - printf ("*Note: Monitoring Network CRC VERBOSE synchronization...\n"); - } - else if (isFlagType1BitEnabled (ft1_network_synch_checks) == true) - { - printf ("*Note: Monitoring Network CRC NORMAL synchronization...\n"); - } - - //NetworkRole role = networkManager.getNetworkRole(); - if (role == nrServer) - { - networkManager.initServerInterfaces (this); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] ==== START GAME ==== getCurrentPixelByteCount() = " - MG_SIZE_T_SPECIFIER "\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderer.getCurrentPixelByteCount ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled) - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "=============================================\n"); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled) - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "==== START GAME ====\n"); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled) - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "=============================================\n"); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled) - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "Starting framecount: %d\n", - world.getFrameCount ()); - - if (showPerfStats && chronoPerf.getMillis () >= 50) - { - for (unsigned int x = 0; x < perfList.size (); ++x) - { - printf ("%s", perfList[x].c_str ()); - } - } - } - - void Game::initCamera (Map * map) - { - gameCamera.init (map->getW (), map->getH ()); - - // camera default height calculation - if (map->getCameraHeight () > 0 - && gameCamera.getCalculatedDefault () < map->getCameraHeight ()) - { - gameCamera.setCalculatedDefault (map->getCameraHeight ()); - } - else if (gameCamera.getCalculatedDefault () < - map->getMaxMapHeight () + 13.0f) - { - gameCamera.setCalculatedDefault (map->getMaxMapHeight () + 13.0f); - } - - if (world.getThisFaction () != NULL) - { - const - Vec2i & - v = - map->getStartLocation (world. - getThisFaction ()->getStartLocationIndex ()); - // This args are set in map.cpp - Map::getStartLocation() - gameCamera.setPos (Vec2f - (v.x, - v.y + gameCamera.getCalculatedDefault () / 2)); - // - // for issue 13: observer mode (wip) - // This sets the camera position the same for each player. - // The goal is to set the camera position to this for observers only - // since they don't have a StartLocationIndex - // gameCamera.setPos(Vec2f(10, 10)); - - } - } - -// ==================== update ==================== - - void Game::reInitGUI () - { - gui.init (this); - } - - void Game::setupPopupMenus (bool checkClientAdminOverrideOnly) - { - Lang & lang = Lang::getInstance (); - NetworkManager & networkManager = NetworkManager::getInstance (); - NetworkRole role = networkManager.getNetworkRole (); - ClientInterface *clientInterface = NULL; - ServerInterface *serverInterface = NULL; - - bool allowAdminMenuItems = false; - bool forceJoinInProgressUpdate = false; - if (role == nrServer) - { - allowAdminMenuItems = true; - - if (disconnectPlayerPopupMenuIndex == -1) - { - serverInterface = - dynamic_cast < - ServerInterface * >(networkManager.getServerInterface ()); - if (serverInterface != NULL && checkClientAdminOverrideOnly == true) - { - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - - MutexSafeWrapper - safeMutex (serverInterface->getSlotMutex - (faction->getStartLocationIndex ()), CODE_AT_LINE); - ConnectionSlot *slot = - serverInterface->getSlot (faction->getStartLocationIndex (), - false); - if (slot != NULL - && slot->getConnectHasHandshaked () == true - && slot->getCurrentFrameCount () <= 0) - { - //printf("Connected slot can be disconnected: %d\n",slot->getPlayerIndex()); - - forceJoinInProgressUpdate = true; - break; - } - } - } - } - } - else if (role == nrClient) - { - clientInterface = - dynamic_cast < - ClientInterface * >(networkManager.getClientInterface ()); - - if (clientInterface != NULL && - (gameSettings.getMasterserver_admin () == - clientInterface->getSessionKey () - || clientInterface->isMasterServerAdminOverride () == true)) - { - allowAdminMenuItems = true; - } - } - - if (checkClientAdminOverrideOnly == false || - forceJoinInProgressUpdate == true || - (clientInterface != NULL && - (gameSettings.getMasterserver_admin () != - clientInterface->getSessionKey () - && clientInterface->isMasterServerAdminOverride () == true))) - { - exitGamePopupMenuIndex = -1; - joinTeamPopupMenuIndex = -1; - pauseGamePopupMenuIndex = -1; - saveGamePopupMenuIndex = -1; - loadGamePopupMenuIndex = -1; - keyboardSetupPopupMenuIndex = -1; - disconnectPlayerPopupMenuIndex = -1; - - if (checkClientAdminOverrideOnly == true && clientInterface != NULL) - { - gameSettings. - setMasterserver_admin (clientInterface->getSessionKey ()); - gameSettings.setMasterserver_admin_faction_index - (clientInterface->getPlayerIndex ()); - } - //PopupMenu popupMenu; - std::vector < string > menuItems; - menuItems.push_back (" " + lang.getString ("ExitGameMenu") + " "); - exitGamePopupMenuIndex = (int) menuItems.size () - 1; - - if ((gameSettings.getFlagTypes1 () & ft1_allow_team_switching) == - ft1_allow_team_switching && world.getThisFaction () != NULL - && world.getThisFaction ()->getPersonalityType () != fpt_Observer) - { - menuItems.push_back (" " + lang.getString ("JoinOtherTeam") + - " "); - joinTeamPopupMenuIndex = (int) menuItems.size () - 1; - } - - if (allowAdminMenuItems == true) - { - menuItems.push_back (" " + lang.getString ("PauseResumeGame") + - " "); - pauseGamePopupMenuIndex = (int) menuItems.size () - 1; - - if (gameSettings.isNetworkGame () == false - || gameSettings.getScenario () != "") - { - menuItems.push_back (" " + lang.getString ("SaveGame") + " "); - saveGamePopupMenuIndex = (int) menuItems.size () - 1; - } - - if (gameSettings.isNetworkGame () == true) - { - menuItems.push_back (" " + - lang.getString ("DisconnectNetorkPlayer") + - " "); - disconnectPlayerPopupMenuIndex = (int) menuItems.size () - 1; - } - } - menuItems.push_back (" " + lang.getString ("KeyboardsetupL") + " "); - keyboardSetupPopupMenuIndex = (int) menuItems.size () - 1; - - menuItems.push_back (" " + lang.getString ("Cancel") + " "); - - popupMenu.setW (100); - popupMenu.setH (100); - popupMenu.init (" " + lang.getString ("GameMenuTitle") + " ", - menuItems); - popupMenu.setEnabled (false); - popupMenu.setVisible (false); - - popupMenuSwitchTeams.setEnabled (false); - popupMenuSwitchTeams.setVisible (false); - - popupMenuDisconnectPlayer.setEnabled (false); - popupMenuDisconnectPlayer.setVisible (false); - } - } - - void Game::processNetworkSynchChecksIfRequired () - { - bool isNetworkGame = this->gameSettings.isNetworkGame (); - if (isNetworkGame == true - && NetworkManager::getInstance ().getGameNetworkInterface () != - NULL) - { - GameSettings *settings = world.getGameSettingsPtr (); - if (settings != NULL) - { - bool calculateNetworkCRC = false; - - if (isFlagType1BitEnabled (ft1_network_synch_checks) == true || - isFlagType1BitEnabled (ft1_network_synch_checks_verbose) == - true) - { - calculateNetworkCRC = true; - } - - if (calculateNetworkCRC == true) - { - NetworkManager & networkManager = NetworkManager::getInstance (); - NetworkRole role = networkManager.getNetworkRole (); - - NetworkInterface *netIntf = - networkManager.getGameNetworkInterface (); - for (int index = 0; index < GameConstants::maxPlayers; ++index) - { - if (index < world.getFactionCount ()) - { - Faction *faction = world.getFaction (index); - netIntf->setNetworkPlayerFactionCRC (index, - faction->getCRC ().getSum - ()); - - if (settings != NULL) - { - if (isFlagType1BitEnabled - (ft1_network_synch_checks_verbose) == true) - { - faction->addCRC_DetailsForWorldFrame (world.getFrameCount - (), - role == nrServer); - } - else - if (isFlagType1BitEnabled - (ft1_network_synch_checks) == true - && world.getFrameCount () % 20 == 0) - { - faction->addCRC_DetailsForWorldFrame (world.getFrameCount - (), - role == nrServer); - } - } - } - else - { - netIntf->setNetworkPlayerFactionCRC (index, 0); - } - } - } - } - } - } - -//update - void Game::update () - { - try - { - if (currentUIState != NULL) - { - currentUIState->update (); - } - - bool - showPerfStats = - Config::getInstance ().getBool ("ShowPerfStats", "false"); - Chrono chronoPerf; - char perfBuf[8096] = ""; - std::vector < string > perfList; - if (showPerfStats) - chronoPerf.start (); - - if (showPerfStats) - { - sprintf (perfBuf, - "=============== FRAME: %d In [%s::%s] Line: %d took msecs: " - MG_I64_SPECIFIER "\n", world.getFrameCount (), - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - Chrono chronoGamePerformanceCounts; - Chrono chrono; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled) - chrono.start (); - - // a) Updates non dependent on speed - - // set game stats for host - NetworkManager & networkManager = NetworkManager::getInstance (); - NetworkRole role = networkManager.getNetworkRole (); - if (role == nrServer) - { - ServerInterface *server = - NetworkManager::getInstance ().getServerInterface (false); - if (server != NULL) - { - server->setGameStats (world.getStats ()); - } - } - - bool - pendingQuitError = (quitPendingIndicator == true || - (NetworkManager:: - getInstance ().getGameNetworkInterface () != - NULL - && NetworkManager:: - getInstance ().getGameNetworkInterface ()-> - getQuit ())); - - if (pendingQuitError == true && - (this->masterserverMode == true || - (mainMessageBox.getEnabled () == false - && errorMessageBox.getEnabled () == false))) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - quitTriggeredIndicator = true; - return; - } - - if (this->masterserverMode == false) - { - if (world.getFactionCount () > 0 - && world.getThisFaction ()->getFirstSwitchTeamVote () != NULL) - { - const SwitchTeamVote *vote = - world.getThisFaction ()->getFirstSwitchTeamVote (); - GameSettings *settings = world.getGameSettingsPtr (); - - Lang & lang = Lang::getInstance (); - - char szBuf[8096] = ""; - if (lang.hasString ("AllowPlayerJoinTeam") == true) - { - snprintf (szBuf, 8096, - lang.getString ("AllowPlayerJoinTeam").c_str (), - settings-> - getNetworkPlayerName (vote->factionIndex).c_str (), - vote->oldTeam, vote->newTeam); - } - else - { - snprintf (szBuf, 8096, - "Allow player [%s] to join your team\n(changing from team# %d to team# %d)?", - settings-> - getNetworkPlayerName (vote->factionIndex).c_str (), - vote->oldTeam, vote->newTeam); - } - - switchTeamConfirmMessageBox.setText (szBuf); - switchTeamConfirmMessageBox.init (lang.getString ("Yes"), - lang.getString ("No")); - switchTeamConfirmMessageBox.setEnabled (true); - - world. - getThisFactionPtr ()->setCurrentSwitchTeamVoteFactionIndex - (vote->factionIndex); - } - } - - //misc - updateFps++; - mouse2d = (mouse2d + 1) % Renderer::maxMouse2dAnim; - - //console - console.update (); - - // b) Updates depandant on speed - int updateLoops = getUpdateLoops (); - - // Temp speed boost when player first joins an in progress game - if (this->initialResumeSpeedLoops == true) - { - printf ("Resume In Progress Game: %d\n", __LINE__); - - this->initialResumeSpeedLoops = false; - //updateLoops = 80; - } - - chronoGamePerformanceCounts.start (); - bool - enableServerControlledAI = - this->gameSettings.getEnableServerControlledAI (); - - if (role == nrClient && updateLoops == 1 - && world.getFrameCount () >= - (gameSettings.getNetworkFramePeriod () * 2)) - { - ClientInterface *clientInterface = - dynamic_cast < - ClientInterface * >(networkManager.getClientInterface ()); - if (clientInterface != NULL) - { - uint64 - lastNetworkFrameFromServer = - clientInterface->getCachedLastPendingFrameCount (); - - ///////////////////////////////// - // TTTT new attempt to make things smoother: - /////////////// - - //////////////////////////////////////////// - //get stats of received/waiting for packages - //////////////////////////////////////////// - // calculate current receive Index slot: - int - index = ((world.getFrameCount () - - (world.getFrameCount () - % gameSettings.getNetworkFramePeriod ())) - / gameSettings.getNetworkFramePeriod ()) - % GameConstants::networkSmoothInterval; - - // clean the next frame slot - receivedTooEarlyInFrames[(index + - 1) % - GameConstants::networkSmoothInterval] = - -1; - framesNeededToWaitForServerMessage[(index + - 1) % - GameConstants::networkSmoothInterval] - = -1; - - if (receivedTooEarlyInFrames[index] == -1) - { - // we need to check if we already received something for next frame - if (lastNetworkFrameFromServer > 0 - && lastNetworkFrameFromServer > - (uint64) world.getFrameCount ()) - { - receivedTooEarlyInFrames[index] = - lastNetworkFrameFromServer - world.getFrameCount (); - } - } - if (framesNeededToWaitForServerMessage[index] == -1) - { - // calc time waiting for message in milliseconds to frames - int64 - timeClientWaitedForLastMessage = - clientInterface->getTimeClientWaitedForLastMessage (); - if (timeClientWaitedForLastMessage > 0) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("world.getFrameCount():%d index %d Client waited:%d ms\n", - world.getFrameCount (), index, - (int) timeClientWaitedForLastMessage); - framesNeededToWaitForServerMessage[index] = - timeClientWaitedForLastMessage * - GameConstants::updateFps / 1000; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("ClienttimeClientWaitedForLastMessage:%d ms which is %d frames \n", - (int) timeClientWaitedForLastMessage, - framesNeededToWaitForServerMessage[index]); - } - else - { - framesNeededToWaitForServerMessage[index] = 0; - } - } - - //////////////////////////////////////////// - //use the recorded stats of received/waiting for packages - //////////////////////////////////////////// - //lets see if the client is in front and had to wait for messages ... - - //lets see if all last recorded frames where received too early - int minimum = 0; - int allowedMaxFallback = 5; - int countOfMessagesReceivedTooEarly = 0; - int countOfMessagesReceivedTooLate = 0; - int sumOfTooLateFrames = 0; - bool cleanupStats = false; - - for (int i = 0; i < GameConstants::networkSmoothInterval; i++) - { - if (receivedTooEarlyInFrames[i] > allowedMaxFallback) - { - countOfMessagesReceivedTooEarly++; - if (minimum == 0 || minimum > receivedTooEarlyInFrames[i]) - { - minimum = receivedTooEarlyInFrames[i]; - } - } - if (framesNeededToWaitForServerMessage[i] > 0) - { - countOfMessagesReceivedTooLate++; - sumOfTooLateFrames += framesNeededToWaitForServerMessage[i]; - } - } - - if (countOfMessagesReceivedTooEarly == GameConstants::networkSmoothInterval - 1) // -1 because slot for next frame is already initialized - { // all packages where too early - // we catch up the minimum-catchupInterval of what we recorded - framesToCatchUpAsClient = minimum - allowedMaxFallback; - framesToSlowDownAsClient = 0; - cleanupStats = true; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("Worldframe %d : Client will speed up: %d frames\n", - world.getFrameCount (), framesToCatchUpAsClient); - } - else if (countOfMessagesReceivedTooLate > 3) - { - framesToSlowDownAsClient = - sumOfTooLateFrames / countOfMessagesReceivedTooLate; - framesToCatchUpAsClient = 0; - cleanupStats = true; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("Worldframe %d : Client will slow down: %d frames\n", - world.getFrameCount (), framesToSlowDownAsClient); - } - - if (cleanupStats == true) - { - // Once we decided to use the stats to do some correction, we reset/cleanup our recorded stats - for (int i = 0; i < GameConstants::networkSmoothInterval; i++) - { - receivedTooEarlyInFrames[i] = -1; - framesNeededToWaitForServerMessage[i] = -1; - } - } - } - } - // if game is paused don't try to catch up - if (updateLoops > 0) - { - // we catch up a bit smoother with updateLoops = 2 - if (framesToCatchUpAsClient > 0) - { - updateLoops = 2; - framesToCatchUpAsClient = framesToCatchUpAsClient - 1; - } - if (framesToSlowDownAsClient > 0) - { // slowdown still the hard way. - updateLoops = 0; - framesToSlowDownAsClient = framesToSlowDownAsClient - 1; - } - } - - addPerformanceCount ("CalculateNetworkUpdateLoops", - chronoGamePerformanceCounts.getMillis ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER - "\n", extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld [before ReplaceDisconnectedNetworkPlayersWithAI]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER - "\n", extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - // Check to see if we are playing a network game and if any players - // have disconnected? - bool isNetworkGame = this->gameSettings.isNetworkGame (); - - chronoGamePerformanceCounts.start (); - - ReplaceDisconnectedNetworkPlayersWithAI (isNetworkGame, role); - - addPerformanceCount ("ReplaceDisconnectedNetworkPlayersWithAI", - chronoGamePerformanceCounts.getMillis ()); - - setupPopupMenus (true); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld [after ReplaceDisconnectedNetworkPlayersWithAI]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER - "\n", extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (updateLoops > 0) - { - // update the frame based timer in the stats with at least one step - world.getStats ()->addFramesToCalculatePlaytime (); - - //update - Chrono chronoReplay; - int64 lastReplaySecond = -1; - int replayCommandsPlayed = 0; - int replayTotal = commander.getReplayCommandListForFrameCount (); - if (replayTotal > 0) - { - chronoReplay.start (); - } - - do - { - if (replayTotal > 0) - { - replayCommandsPlayed = - (replayTotal - - commander.getReplayCommandListForFrameCount ()); - } - for (int i = 0; i < updateLoops; ++i) - { - //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " - MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - //AiInterface - if (commander.hasReplayCommandListForFrame () == false) - { - chronoGamePerformanceCounts.start (); - - processNetworkSynchChecksIfRequired (); - - addPerformanceCount ("CalculateNetworkCRCSynchChecks", - chronoGamePerformanceCounts.getMillis - ()); - - const bool - newThreadManager = - Config::getInstance ().getBool ("EnableNewThreadManager", - "false"); - if (newThreadManager == true) - { - int currentFrameCount = world.getFrameCount (); - masterController.signalSlaves (¤tFrameCount); - //bool slavesCompleted = masterController.waitTillSlavesTrigger(20000); - masterController.waitTillSlavesTrigger (20000); - } - else - { - // Signal the faction threads to do any pre-processing - chronoGamePerformanceCounts.start (); - - bool hasAIPlayer = false; - for (int j = 0; j < world.getFactionCount (); ++j) - { - Faction *faction = world.getFaction (j); - - //printf("Faction Index = %d enableServerControlledAI = %d, isNetworkGame = %d, role = %d isCPU player = %d scriptManager.getPlayerModifiers(j)->getAiEnabled() = %d\n",j,enableServerControlledAI,isNetworkGame,role,faction->getCpuControl(enableServerControlledAI,isNetworkGame,role),scriptManager.getPlayerModifiers(j)->getAiEnabled()); - - if (faction->getCpuControl (enableServerControlledAI, - isNetworkGame, - role) == true - && scriptManager. - getPlayerModifiers (j)->getAiEnabled () == true) - { - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags:: - OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] [i = %d] faction = %d, factionCount = %d, took msecs: %lld [before AI updates]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, i, j, - world.getFactionCount (), - chrono.getMillis ()); - aiInterfaces[j]->signalWorkerThread (world.getFrameCount - ()); - hasAIPlayer = true; - } - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " - MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (hasAIPlayer == true) - { - //sleep(0); - - Chrono chronoAI; - chronoAI.start (); - - const int MAX_FACTION_THREAD_WAIT_MILLISECONDS = 20000; - for (; - chronoAI.getMillis () < - MAX_FACTION_THREAD_WAIT_MILLISECONDS;) - { - bool workThreadsFinished = true; - for (int j = 0; j < world.getFactionCount (); ++j) - { - Faction *faction = world.getFaction (j); - if (faction == NULL) - { - throw megaglest_runtime_error ("faction == NULL"); - } - if (faction->getCpuControl - (enableServerControlledAI, - isNetworkGame, role) == true - && - scriptManager.getPlayerModifiers (j)->getAiEnabled - () == true) - { - if (aiInterfaces[j]->isWorkerThreadSignalCompleted - (world.getFrameCount ()) == false) - { - workThreadsFinished = false; - break; - } - } - } - if (workThreadsFinished == false) - { - //sleep(0); - } - else - { - break; - } - } - } - - addPerformanceCount ("ProcessAIWorkerThreads", - chronoGamePerformanceCounts.getMillis - ()); - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " - MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - } - else - { - // Simply show a progress message while replaying commands - if (lastReplaySecond < chronoReplay.getSeconds ()) - { - lastReplaySecond = chronoReplay.getSeconds (); - Renderer & renderer = Renderer::getInstance (); - renderer.clearBuffers (); - renderer.clearZBuffer (); - renderer.reset2d (); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Please wait, loading game with replay [%d / %d]...", - replayCommandsPlayed, replayTotal); - string text = szBuf; - if (Renderer::renderText3DEnabled) - { - Font3D *font = - CoreData::getInstance ().getMenuFontBig3D (); - const Metrics & metrics = Metrics::getInstance (); - int w = metrics.getVirtualW (); - int - renderX = - (w / 2) - - (font->getMetrics ()->getTextWidth (text) / 2); - int h = metrics.getVirtualH (); - int - renderY = - (h / 2) + (font->getMetrics ()->getHeight (text) / 2); - - renderer.renderText3D (text, font, - Vec3f (1.f, 1.f, 0.f), - renderX, renderY, false); - } - else - { - Font2D *font = CoreData::getInstance ().getMenuFontBig (); - const Metrics & metrics = Metrics::getInstance (); - int w = metrics.getVirtualW (); - int renderX = (w / 2); - int h = metrics.getVirtualH (); - int renderY = (h / 2); - - renderer.renderText (text, font, - Vec3f (1.f, 1.f, 0.f), - renderX, renderY, true); - } - - renderer.swapBuffers (); - } - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " - MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld [AI updates]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - //World - chronoGamePerformanceCounts.start (); - - if (pendingQuitError == false) - world.update (); - - addPerformanceCount ("ProcessWorldUpdate", - chronoGamePerformanceCounts.getMillis ()); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld [world update i = %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis (), i); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " - MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (currentCameraFollowUnit != NULL) - { - Vec3f c = currentCameraFollowUnit->getCurrMidHeightVector (); - int rotation = currentCameraFollowUnit->getRotation (); - float angle = rotation + 180; - - c.z = c.z + 4 * std::cos (degToRad (angle)); - c.x = c.x + 4 * std::sin (degToRad (angle)); - - c.y = - c.y + - currentCameraFollowUnit->getType ()->getHeight () / - 2.f + 2.0f; - - getGameCameraPtr ()->setPos (c); - - rotation = (540 - rotation) % 360; - getGameCameraPtr ()->rotateToVH (18.0f, rotation); - - if (currentCameraFollowUnit->isAlive () == false) - { - currentCameraFollowUnit = NULL; - getGameCameraPtr ()->setState (GameCamera::sGame); - } - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " - MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - // Commander - chronoGamePerformanceCounts.start (); - - if (pendingQuitError == false) - { - commander.signalNetworkUpdate (this); - } - - addPerformanceCount ("ProcessNetworkUpdate", - chronoGamePerformanceCounts.getMillis ()); - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " - MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld [commander updateNetwork i = %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis (), i); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - //Gui - chronoGamePerformanceCounts.start (); - - gui.update (); - - addPerformanceCount ("ProcessGUIUpdate", - chronoGamePerformanceCounts.getMillis ()); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld [gui updating i = %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis (), i); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " - MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - //Particle systems - if (weatherParticleSystem != NULL) - { - weatherParticleSystem->setPos (gameCamera.getPos ()); - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld [weather particle updating i = %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis (), i); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " - MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - Renderer & renderer = Renderer::getInstance (); - - chronoGamePerformanceCounts.start (); - - renderer.updateParticleManager (rsGame, avgRenderFps); - - addPerformanceCount ("ProcessParticleManager", - chronoGamePerformanceCounts.getMillis ()); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld [particle manager updating i = %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis (), i); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " - MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - //good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - } - while (commander.hasReplayCommandListForFrame () == true); - } - //else if(role == nrClient) { - else - { - if (pendingQuitError == false) - { - commander.signalNetworkUpdate (this); - } - - if (playingStaticVideo == true) - { - if (videoPlayer->isPlaying () == false) - { - playingStaticVideo = false; - tryPauseToggle (false); - } - } - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER - "\n", extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - chronoGamePerformanceCounts.start (); - - //call the chat manager - chatManager.updateNetwork (); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld [chatManager.updateNetwork]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER - "\n", extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - updateNetworkMarkedCells (); - updateNetworkUnMarkedCells (); - updateNetworkHighligtedCells (); - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER - "\n", extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - //check for quiting status - if (NetworkManager::getInstance ().getGameNetworkInterface () != NULL - && NetworkManager::getInstance (). - getGameNetworkInterface ()->getQuit () - && mainMessageBox.getEnabled () == false - && errorMessageBox.getEnabled () == false) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - quitTriggeredIndicator = true; - return; - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER - "\n", extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - addPerformanceCount ("ProcessMiscNetwork", - chronoGamePerformanceCounts.getMillis ()); - - // START - Handle joining in progress games - if (role == nrServer) - { - - if (this->networkPauseGameForLaggedClientsRequested == true) - { - this->networkPauseGameForLaggedClientsRequested = false; - - if (getPaused () == false) - { - - printf - ("[CMDR] Pausing game for lagging client(s), current world frame [%d]\n", - world.getFrameCount ()); - commander.tryPauseGame (false, false); - } - } - else if (this->networkResumeGameForLaggedClientsRequested == true) - { - this->networkResumeGameForLaggedClientsRequested = false; - - if (getPaused () == true) - { - - printf - ("[CMDR] Resuming game after Pause for lagging client(s), current world frame [%d]\n", - world.getFrameCount ()); - commander.tryResumeGame (false, false); - } - } - - ServerInterface *server = - NetworkManager::getInstance ().getServerInterface (); - if (server->getPauseForInGameConnection () == true) - { - - bool clientNeedsGameSetup = false; - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - - MutexSafeWrapper - safeMutex (server->getSlotMutex - (faction->getStartLocationIndex ()), CODE_AT_LINE); - ConnectionSlot *slot = - server->getSlot (faction->getStartLocationIndex (), - false); - if (slot != NULL - && slot->getPauseForInGameConnection () == true) - { - clientNeedsGameSetup = true; - break; - } - } - - if (pausedForJoinGame == false || clientNeedsGameSetup == true) - { - //printf("================= Switching player pausing game\n"); - - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - - //printf("Switching player check %d from: %d connected: %d, startindex = %d, connected #2: %d\n",i,faction->getControlType(),server->isClientConnected(faction->getStartLocationIndex()),faction->getStartLocationIndex(),server->isClientConnected(i)); - //printf("Slot: %d faction name: %s\n",i,faction->getType()->getName().c_str()); - - if (faction->getControlType () != ctNetwork && - faction->getControlType () != ctHuman && - server->isClientConnected (faction->getStartLocationIndex - ()) == true) - { - - //printf("Switching player %d from: %d to %d\n",i,faction->getControlType(),ctNetwork); - //printf("Slot: %d faction name: %s GS faction: %s\n",i,faction->getType()->getName().c_str(),server->gameSettings.getFactionTypeName(i).c_str()); - - server->gameSettings.setFactionControl (i, ctNetwork); - - MutexSafeWrapper - safeMutex (server->getSlotMutex - (faction->getStartLocationIndex ()), - CODE_AT_LINE); - ConnectionSlot *slot = - server->getSlot (faction->getStartLocationIndex (), - false); - server->gameSettings.setNetworkPlayerName (i, - slot->getName - ()); - server->gameSettings.setNetworkPlayerUUID (i, - slot->getUUID - ()); - server->gameSettings.setNetworkPlayerPlatform (i, - slot->getPlatform - ()); - safeMutex.ReleaseLock (); - server->gameSettings.setNetworkPlayerStatuses (i, - npst_None); - - this->gameSettings.setFactionControl (i, ctNetwork); - this->gameSettings.setNetworkPlayerName (i, - server->gameSettings.getNetworkPlayerName - (i)); - this->gameSettings.setNetworkPlayerUUID (i, - server->gameSettings.getNetworkPlayerUUID - (i)); - this->gameSettings.setNetworkPlayerPlatform (i, - server->gameSettings.getNetworkPlayerPlatform - (i)); - this->gameSettings.setNetworkPlayerStatuses (i, npst_None); - } - } - //printf("#1 Data synch: lmap %u ltile: %d ltech: %u\n",gameSettings.getMapCRC(),gameSettings.getTilesetCRC(),gameSettings.getTechCRC()); - //printf("#2 Data synch: lmap %u ltile: %d ltech: %u\n",server->gameSettings.getMapCRC(),server->gameSettings.getTilesetCRC(),server->gameSettings.getTechCRC()); - server->broadcastGameSetup (&server->gameSettings, true); - } - - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - MutexSafeWrapper - safeMutex (server->getSlotMutex - (faction->getStartLocationIndex ()), CODE_AT_LINE); - ConnectionSlot *slot = - server->getSlot (faction->getStartLocationIndex (), - false); - if (slot != NULL - && slot->getPauseForInGameConnection () == true) - { - slot->setPauseForInGameConnection (false); - } - } - } - else if (server->getStartInGameConnectionLaunch () == true) - { - //printf("^^^ getStartInGameConnectionLaunch triggered!\n"); - - //server->setStartInGameConnectionLaunch(false); - - //this->speed = 1; - - //Lang &lang= Lang::getInstance(); - bool pauseAndSaveGameForNewClient = false; - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - - MutexSafeWrapper - safeMutex (server->getSlotMutex - (faction->getStartLocationIndex ()), CODE_AT_LINE); - ConnectionSlot *slot = - server->getSlot (faction->getStartLocationIndex (), - false); - - if (slot != NULL - && slot->getStartInGameConnectionLaunch () == true) - { - //slot->setStartInGameConnectionLaunch(false); - pauseAndSaveGameForNewClient = true; - } - if (slot != NULL && slot->getJoinGameInProgress () == true) - { - //printf("$$$ signalling client to start game [deleting AI player] factionIndex: %d slot: %d startlocation: %d!\n",i,slot->getPlayerIndex(),faction->getStartLocationIndex()); - safeMutex.ReleaseLock (); - - this->gameSettings.setFactionControl (i, ctNetwork); - this->gameSettings.setNetworkPlayerName (i, - server->gameSettings.getNetworkPlayerName - (i)); - this->gameSettings.setNetworkPlayerUUID (i, - server->gameSettings.getNetworkPlayerUUID - (i)); - this->gameSettings.setNetworkPlayerPlatform (i, - server->gameSettings.getNetworkPlayerPlatform - (i)); - - if (this->gameSettings.getNetworkPlayerStatuses (i) == - npst_Disconnected) - { - this->gameSettings.setNetworkPlayerStatuses (i, npst_None); - } - - //printf("START Purging AI player for index: %d\n",i); - masterController.clearSlaves (true); - delete aiInterfaces[i]; - aiInterfaces[i] = NULL; - //printf("END Purging AI player for index: %d\n",i); - - Faction *faction = world.getFaction (i); - faction->setControlType (ctNetwork); - //pauseAndSaveGameForNewClient = true; - } - else if ((slot == NULL || slot->isConnected () == false) - && this->gameSettings.getFactionControl (i) == - ctNetwork && aiInterfaces[i] == NULL) - { - - safeMutex.ReleaseLock (); - faction->setFactionDisconnectHandled (false); - //this->gameSettings.setNetworkPlayerName(i,lang.getString("AI") + intToStr(i+1)); - //server->gameSettings.setNetworkPlayerName(i,lang.getString("AI") + intToStr(i+1)); - } - else - { - safeMutex.ReleaseLock (); - } - } - - if (pauseAndSaveGameForNewClient == true - && pausedForJoinGame == false && pauseRequestSent == false) - { - //printf("Pausing game for join in progress game...\n"); - - commander.tryPauseGame (true, true); - pauseRequestSent = true; - return; - } - } - //else if(server->getPauseForInGameConnection() == true && paused == true && - if (pausedForJoinGame == true) - { - if (pauseStateChanged == true) - { - pauseStateChanged = false; - } - - if (server->getUnPauseForInGameConnection () == true) - { - //printf("^^^ getUnPauseForInGameConnection triggered!\n"); - - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - - MutexSafeWrapper - safeMutex (server->getSlotMutex - (faction->getStartLocationIndex ()), - CODE_AT_LINE); - ConnectionSlot *slot = - server->getSlot (faction->getStartLocationIndex (), - false); - if (slot != NULL - && slot->getUnPauseForInGameConnection () == true) - { - slot->setUnPauseForInGameConnection (false); - faction->setFactionDisconnectHandled (false); - } - } - //printf("Resuming game for join in progress game resumeRequestSent: %d...\n",resumeRequestSent); - - if (pausedBeforeJoinGame == false && resumeRequestSent == false) - { - commander.tryResumeGame (true, true); - resumeRequestSent = true; - } - } - else if (server->getStartInGameConnectionLaunch () == true) - { - bool saveNetworkGame = false; - - ServerInterface *server = - NetworkManager::getInstance ().getServerInterface (); - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - - MutexSafeWrapper - safeMutex (server->getSlotMutex - (faction->getStartLocationIndex ()), - CODE_AT_LINE); - ConnectionSlot *slot = - server->getSlot (faction->getStartLocationIndex (), - false); - if (slot != NULL - && slot->getJoinGameInProgress () == true - && slot->getStartInGameConnectionLaunch () == true - && slot->getSentSavedGameInfo () == false) - { - slot->setStartInGameConnectionLaunch (false); - - saveNetworkGame = true; - break; - } - } - - if (saveNetworkGame == true) - { - //printf("Saved network game to disk\n"); - - string - file = - this->saveGame (GameConstants::saveNetworkGameFileServer, - "temp/"); - - string saveGameFilePath = "temp/"; - string - saveGameFileCompressed = - saveGameFilePath + - string (GameConstants::saveNetworkGameFileServerCompressed); - if (getGameReadWritePath - (GameConstants::path_logs_CacheLookupKey) != "") - { - saveGameFilePath = - getGameReadWritePath - (GameConstants::path_logs_CacheLookupKey) + - saveGameFilePath; - saveGameFileCompressed = - saveGameFilePath + - string - (GameConstants::saveNetworkGameFileServerCompressed); - } - else - { - string - userData = - Config::getInstance ().getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - saveGameFilePath = userData + saveGameFilePath; - saveGameFileCompressed = - saveGameFilePath + - string - (GameConstants::saveNetworkGameFileServerCompressed); - } - - bool - compressed_result = - compressFileToZIPFile (file, saveGameFileCompressed); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("Saved game [%s] compressed to [%s] returned: %d\n", - file.c_str (), saveGameFileCompressed.c_str (), - compressed_result); - - char szBuf[8096] = ""; - Lang & lang = Lang::getInstance (); - snprintf (szBuf, 8096, - lang.getString ("GameSaved", "", - true).c_str (), file.c_str ()); - console.addLine (szBuf); - - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - - MutexSafeWrapper - safeMutex (server->getSlotMutex - (faction->getStartLocationIndex ()), - CODE_AT_LINE); - ConnectionSlot *slot = - server->getSlot (faction->getStartLocationIndex (), - false); - if (slot != NULL - && slot->getJoinGameInProgress () == true - && slot->getSentSavedGameInfo () == false) - { - - safeMutex.ReleaseLock (); - NetworkMessageReady networkMessageReady (0); - slot->sendMessage (&networkMessageReady); - - slot = - server->getSlot (faction->getStartLocationIndex (), - false); - if (slot != NULL) - { - slot->setSentSavedGameInfo (true); - } - } - } - } - } - } - //else { - // handle setting changes from clients - Map *map = world.getMap (); - //printf("switchSetupRequests != NULL\n"); - - bool - switchRequested = - switchSetupForSlots (server, 0, map->getMaxPlayers (), false); - switchRequested = switchRequested - || switchSetupForSlots (server, map->getMaxPlayers (), - GameConstants::maxPlayers, true); - - if (switchRequested == true) - { - //printf("Send new game setup from switch: %d\n",switchRequested); - - //for(int i= 0; i < gameSettings.getFactionCount(); ++i) { - //printf("#1 Faction Index: %d control: %d startlocation: %d\n",i,gameSettings.getFactionControl(i),gameSettings.getStartLocationIndex(i)); - - //printf("#2 Faction Index: %d control: %d startlocation: %d\n",i,server->gameSettings.getFactionControl(i),server->gameSettings.getStartLocationIndex(i)); - //} - - server->broadcastGameSetup (&server->gameSettings, true); - } - //} - - // Make the server wait a bit for clients to start. - if (pausedForJoinGame == false && resumeRequestSent == true) - { - resumeRequestSent = false; - //sleep(500); - } - } - // END - Handle joining in progress games - - //update auto test - if (Config::getInstance ().getBool ("AutoTest")) - { - AutoTest::getInstance ().updateGame (this); - return; - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER - "\n", extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (world.getQueuedScenario () != "") - { - string name = world.getQueuedScenario (); - bool keepFactions = world.getQueuedScenarioKeepFactions (); - world.setQueuedScenario ("", false); - - //vector results; - const - vector < - string > & - dirList = Config::getInstance ().getPathListForType (ptScenarios); - string scenarioFile = Scenario::getScenarioPath (dirList, name); - - - try - { - gameStarted = false; - - //printf("\nname [%s] scenarioFile [%s] results.size() = " MG_SIZE_T_SPECIFIER "\n",name.c_str(),scenarioFile.c_str(),results.size()); - //printf("[%s:%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - bool isTutorial = Scenario::isGameTutorial (scenarioFile); - ScenarioInfo scenarioInfo; - Scenario::loadScenarioInfo (scenarioFile, &scenarioInfo, - isTutorial); - - //printf("[%s:%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - GameSettings gameSettings; - Scenario::loadGameSettings (dirList, &scenarioInfo, - &gameSettings, scenarioFile); - - //Program *program = world->getGame()->getProgram(); - //program->setState(new Game(program, &gameSettings, false)); - - //world->end(); - - //world->getMapPtr()->end(); - //world.end(); - - if (keepFactions == false) - { - world.end (); - - world.cleanup (); - world.clearTileset (); - - SoundRenderer::getInstance ().stopAllSounds (); - - masterController.clearSlaves (true); - deleteValues (aiInterfaces.begin (), aiInterfaces.end ()); - aiInterfaces.clear (); - gui.end (); //selection must be cleared before deleting units - world.end (); //must die before selection because of referencers - - BaseColorPickEntity::resetUniqueColors (); - // MUST DO THIS LAST!!!! Because objects above have pointers to things like - // unit particles and fade them out etc and this end method deletes the original - // object pointers. - Renderer & renderer = Renderer::getInstance (); - renderer.endGame (true); - - GameConstants::updateFps = original_updateFps; - GameConstants::cameraFps = original_cameraFps; - - this->setGameSettings (&gameSettings); - this->resetMembers (); - this->load (); - this->init (); - } - else - { - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); - if (currentAmbientSound) - { - soundRenderer.stopAmbient (currentAmbientSound); - } - //soundRenderer.stopAllSounds(); - soundRenderer.stopAllSounds (fadeMusicMilliseconds); - - world.endScenario (); - BaseColorPickEntity::resetUniqueColors (); - - Renderer & renderer = Renderer::getInstance (); - renderer.endScenario (); - world.clearTileset (); - this->setGameSettings (&gameSettings); - this->load (lgt_FactionPreview | lgt_TileSet | lgt_Map | - lgt_Scenario); - try - { - world.init (this, gameSettings.getDefaultUnits (), false); - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d]\nError [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); - - if (errorMessageBox.getEnabled () == false) - { - ErrorDisplayMessage (ex.what (), true); - } - } - - world.initUnitsForScenario (); - Map *map = world.getMap (); - gameCamera.init (map->getW (), map->getH ()); - - // camera default height calculation - if (map->getCameraHeight () > 0 - && gameCamera.getCalculatedDefault () < - map->getCameraHeight ()) - { - gameCamera.setCalculatedDefault (map->getCameraHeight ()); - } - else if (gameCamera.getCalculatedDefault () < - map->getMaxMapHeight () + 13.0f) - { - gameCamera.setCalculatedDefault (map->getMaxMapHeight () + - 13.0f); - } - - scriptManager.init (&world, &gameCamera, loadGameNode); - renderer.initGame (this, this->getGameCameraPtr ()); - - //sounds - //soundRenderer.stopAllSounds(fadeMusicMilliseconds); - //soundRenderer.stopAllSounds(); - //soundRenderer= SoundRenderer::getInstance(); - - Tileset *tileset = world.getTileset (); - AmbientSounds *ambientSounds = tileset->getAmbientSounds (); - - //rain - if (tileset->getWeather () == wRainy - && ambientSounds->isEnabledRain ()) - { - //logger.add("Starting ambient stream", true); - currentAmbientSound = ambientSounds->getRain (); - //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); - soundRenderer.playAmbient (currentAmbientSound); - } - - //snow - if (tileset->getWeather () == wSnowy - && ambientSounds->isEnabledSnow ()) - { - //logger.add("Starting ambient stream", true); - currentAmbientSound = ambientSounds->getSnow (); - //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); - soundRenderer.playAmbient (currentAmbientSound); - } - - if (this->masterserverMode == false) - { - StrSound *gameMusic = - world.getThisFaction ()->getType ()->getMusic (); - soundRenderer.playMusic (gameMusic); - } - - gameStarted = true; - } - //this->init(); - - //printf("[%s:%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //Checksum checksum; - //world->loadScenario(scenarioFile, &checksum, true); - } +namespace Glest { + namespace Game { + + string GameSettings::playerDisconnectedText = ""; + Game *thisGamePtr = NULL; + + // ===================================================== + // class Game + // ===================================================== + + // ===================== PUBLIC ======================== + + const float PHOTO_MODE_MAXHEIGHT = 500.0; + + const int CREATE_NEW_TEAM = -100; + const int CANCEL_SWITCH_TEAM = -1; + + const int CANCEL_DISCONNECT_PLAYER = -1; + + const float Game::highlightTime = 0.5f; + + int fadeMusicMilliseconds = 3500; + + // Check every x seconds if we should switch disconnected players to AI + const int NETWORK_PLAYER_CONNECTION_CHECK_SECONDS = 5; + + int GAME_STATS_DUMP_INTERVAL = 60 * 10; + + Game::Game() : + ProgramState(NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + + originalDisplayMsgCallback = NULL; + aiInterfaces.clear(); + videoPlayer = NULL; + playingStaticVideo = false; + + mouse2d = 0; + mouseX = 0; + mouseY = 0; + updateFps = 0; + lastUpdateFps = 0; + avgUpdateFps = 0; + framesToCatchUpAsClient = 0; + framesToSlowDownAsClient = 0; + totalRenderFps = 0; + renderFps = 0; + lastRenderFps = 0; + avgRenderFps = 0; + currentAvgRenderFpsTotal = 0; + paused = false; + networkPauseGameForLaggedClientsRequested = false; + networkResumeGameForLaggedClientsRequested = false; + pausedForJoinGame = false; + pausedBeforeJoinGame = false; + pauseRequestSent = false; + resumeRequestSent = false; + pauseStateChanged = false; + gameOver = false; + renderNetworkStatus = false; + renderInGamePerformance = false; + showFullConsole = false; + setMarker = false; + cameraDragAllowed = false; + mouseMoved = false; + scrollSpeed = 0; + camLeftButtonDown = false; + camRightButtonDown = false; + camUpButtonDown = false; + camDownButtonDown = false; + this->speed = 1; + weatherParticleSystem = NULL; + isFirstRender = false; + quitTriggeredIndicator = false; + quitPendingIndicator = false; + original_updateFps = 0; + original_cameraFps = 0; + captureAvgTestStatus = false; + updateFpsAvgTest = 0; + renderFpsAvgTest = 0; + renderExtraTeamColor = 0; + photoModeEnabled = false; + healthbarMode = hbvUndefined; + visibleHUD = false; + timeDisplay = false; + withRainEffect = false; + program = NULL; + gameStarted = false; + this->initialResumeSpeedLoops = false; + + highlightCellTexture = NULL; + lastMasterServerGameStatsDump = 0; + lastMaxUnitCalcTime = 0; + lastRenderLog2d = 0; + playerIndexDisconnect = 0; + tickCount = 0; + currentCameraFollowUnit = NULL; + + popupMenu.setEnabled(false); + popupMenu.setVisible(false); + + popupMenuSwitchTeams.setEnabled(false); + popupMenuSwitchTeams.setVisible(false); + + popupMenuDisconnectPlayer.setEnabled(false); + popupMenuDisconnectPlayer.setVisible(false); + + switchTeamConfirmMessageBox.setEnabled(false); + disconnectPlayerConfirmMessageBox.setEnabled(false); + + disconnectPlayerIndexMap.clear(); + + exitGamePopupMenuIndex = -1; + joinTeamPopupMenuIndex = -1; + pauseGamePopupMenuIndex = -1; + saveGamePopupMenuIndex = -1; + loadGamePopupMenuIndex = -1; + keyboardSetupPopupMenuIndex = -1; + disconnectPlayerPopupMenuIndex = -1; + + isMarkCellEnabled = false; + isMarkCellTextEnabled = false; + + markCellTexture = NULL; + isUnMarkCellEnabled = false; + unmarkCellTexture = NULL; + + masterserverMode = false; + currentUIState = NULL; + currentAmbientSound = NULL; + //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); + + loadGameNode = NULL; + lastworldFrameCountForReplay = -1; + lastNetworkPlayerConnectionCheck = time(NULL); + inJoinGameLoading = false; + quitGameCalled = false; + disableSpeedChange = false; + + for (int i = 0; i < GameConstants::networkSmoothInterval; i++) { + receivedTooEarlyInFrames[i] = -1; + framesNeededToWaitForServerMessage[i] = -1; + } + + fadeMusicMilliseconds = + Config::getInstance().getInt("GameStartStopFadeSoundMilliseconds", + intToStr(fadeMusicMilliseconds).c_str + ()); + GAME_STATS_DUMP_INTERVAL = + Config::getInstance().getInt("GameStatsDumpIntervalSeconds", + intToStr + (GAME_STATS_DUMP_INTERVAL).c_str()); + } + + void Game::resetMembers() { + Unit::setGame(this); + gameStarted = false; + this->initialResumeSpeedLoops = false; + + original_updateFps = GameConstants::updateFps; + original_cameraFps = GameConstants::cameraFps; + GameConstants::updateFps = 40; + GameConstants::cameraFps = 100; + captureAvgTestStatus = false; + updateFpsAvgTest = 0; + renderFpsAvgTest = 0; + lastRenderLog2d = 0; + playerIndexDisconnect = 0; + lastMasterServerGameStatsDump = 0; + highlightCellTexture = NULL; + totalRenderFps = 0; + lastMaxUnitCalcTime = 0; + renderExtraTeamColor = 0; + + mouseMoved = false; + quitTriggeredIndicator = false; + quitPendingIndicator = false; + originalDisplayMsgCallback = NULL; + thisGamePtr = this; + + popupMenu.setEnabled(false); + popupMenu.setVisible(false); + + popupMenuSwitchTeams.setEnabled(false); + popupMenuSwitchTeams.setVisible(false); + + popupMenuDisconnectPlayer.setEnabled(false); + popupMenuDisconnectPlayer.setVisible(false); + + switchTeamConfirmMessageBox.setEnabled(false); + disconnectPlayerConfirmMessageBox.setEnabled(false); + + disconnectPlayerIndexMap.clear(); + + exitGamePopupMenuIndex = -1; + joinTeamPopupMenuIndex = -1; + pauseGamePopupMenuIndex = -1; + saveGamePopupMenuIndex = -1; + loadGamePopupMenuIndex = -1; + keyboardSetupPopupMenuIndex = -1; + disconnectPlayerPopupMenuIndex = -1; + + isMarkCellEnabled = false; + isMarkCellTextEnabled = false; + + markCellTexture = NULL; + isUnMarkCellEnabled = false; + unmarkCellTexture = NULL; + + currentUIState = NULL; + + scrollSpeed = Config::getInstance().getFloat("UiScrollSpeed", "1.5"); + photoModeEnabled = + Config::getInstance().getBool("PhotoMode", "false"); + healthbarMode = Config::getInstance().getInt("HealthBarMode", "4"); + visibleHUD = Config::getInstance().getBool("VisibleHud", "true"); + timeDisplay = Config::getInstance().getBool("TimeDisplay", "true"); + withRainEffect = Config::getInstance().getBool("RainEffect", "true"); + //MIN_RENDER_FPS_ALLOWED = Config::getInstance().getInt("MIN_RENDER_FPS_ALLOWED",intToStr(MIN_RENDER_FPS_ALLOWED).c_str()); + + mouseX = 0; + mouseY = 0; + mouse2d = 0; + loadingText = ""; + weatherParticleSystem = NULL; + updateFps = 0; + renderFps = 0; + lastUpdateFps = 0; + framesToCatchUpAsClient = 0; + framesToSlowDownAsClient = 0; + lastRenderFps = -1; + avgUpdateFps = -1; + avgRenderFps = -1; + currentAvgRenderFpsTotal = 0; + tickCount = 0; + paused = false; + networkPauseGameForLaggedClientsRequested = false; + networkResumeGameForLaggedClientsRequested = false; + pausedForJoinGame = false; + pausedBeforeJoinGame = false; + resumeRequestSent = false; + pauseRequestSent = false; + pauseStateChanged = false; + gameOver = false; + renderNetworkStatus = false; + renderInGamePerformance = false; + this->speed = 1; + showFullConsole = false; + setMarker = false; + cameraDragAllowed = false; + camLeftButtonDown = false; + camRightButtonDown = false; + camUpButtonDown = false; + camDownButtonDown = false; + + currentCameraFollowUnit = NULL; + currentAmbientSound = NULL; + //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); + + loadGameNode = NULL; + lastworldFrameCountForReplay = -1; + + lastNetworkPlayerConnectionCheck = time(NULL); + + inJoinGameLoading = false; + quitGameCalled = false; + disableSpeedChange = false; + + for (int i = 0; i < GameConstants::networkSmoothInterval; i++) { + receivedTooEarlyInFrames[i] = -1; + framesNeededToWaitForServerMessage[i] = -1; + } + + + fadeMusicMilliseconds = + Config::getInstance().getInt("GameStartStopFadeSoundMilliseconds", + intToStr(fadeMusicMilliseconds).c_str + ()); + GAME_STATS_DUMP_INTERVAL = + Config::getInstance().getInt("GameStatsDumpIntervalSeconds", + intToStr + (GAME_STATS_DUMP_INTERVAL).c_str()); + + Logger & logger = Logger::getInstance(); + logger.showProgress(); + } + + Game::Game(Program * program, const GameSettings * gameSettings, + bool masterserverMode) :ProgramState(program), + lastMousePos(0), isFirstRender(true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + this->masterserverMode = masterserverMode; + videoPlayer = NULL; + playingStaticVideo = false; + highlightCellTexture = NULL; + playerIndexDisconnect = 0; + updateFpsAvgTest = 0; + renderFpsAvgTest = 0; + cameraDragAllowed = false; + + if (this->masterserverMode == true) { + printf("Starting a new game...\n"); + } + + this->program = program; + resetMembers(); + this->gameSettings = *gameSettings; + + Lang::getInstance().setAllowNativeLanguageTechtree(this-> + gameSettings.getNetworkAllowNativeLanguageTechtree + ()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + void Game::endGame() { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + quitGame(); + sleep(0); + + Object::setStateCallback(NULL); + thisGamePtr = NULL; + if (originalDisplayMsgCallback != NULL) { + NetworkInterface::setDisplayMessageFunction + (originalDisplayMsgCallback); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + Logger & logger = Logger::getInstance(); + Renderer & renderer = Renderer::getInstance(); + + logger.clearHints(); + logger.loadLoadingScreen(""); + logger.setState(Lang::getInstance().getString("Deleting")); + //logger.add("Game", true); + logger. + add(Lang:: + getInstance().getString("LogScreenGameLoading", "", true), + false); + logger.hideProgress(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + // Cannot Fade because sound files will be deleted below + SoundRenderer::getInstance().stopAllSounds(fadeMusicMilliseconds); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + // deleteValues(aiInterfaces.begin(), aiInterfaces.end()); + // aiInterfaces.clear(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + gui.end(); //selection must be cleared before deleting units + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + // world.end(); //must die before selection because of referencers + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] aiInterfaces.size() = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + aiInterfaces.size()); + + // MUST DO THIS LAST!!!! Because objects above have pointers to things like + // unit particles and fade them out etc and this end method deletes the original + // object pointers. + renderer.endGame(false); + + GameConstants::updateFps = original_updateFps; + GameConstants::cameraFps = original_cameraFps; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + Unit::setGame(NULL); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] ==== END GAME ==== getCurrentPixelByteCount() = " + MG_SIZE_T_SPECIFIER "\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderer.getCurrentPixelByteCount()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled) + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "==== END GAME ====\n"); + + FileCRCPreCacheThread *&preCacheCRCThreadPtr = + CacheManager::getCachedItem < + FileCRCPreCacheThread * + >(GameConstants::preCacheThreadCacheLookupKey); + if (preCacheCRCThreadPtr != NULL) { + preCacheCRCThreadPtr->setPauseForGame(false); + } + + //this->program->reInitGl(); + //renderer.reinitAll(); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + } + + Game::~Game() { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + quitGame(); + + Object::setStateCallback(NULL); + thisGamePtr = NULL; + if (originalDisplayMsgCallback != NULL) { + NetworkInterface::setDisplayMessageFunction + (originalDisplayMsgCallback); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + Logger & logger = Logger::getInstance(); + Renderer & renderer = Renderer::getInstance(); + + logger.loadLoadingScreen(""); + logger.setState(Lang::getInstance().getString("Deleting")); + //logger.add("Game", true); + logger. + add(Lang:: + getInstance().getString("LogScreenGameLoading", "", true), + false); + logger.hideProgress(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + // Cannot Fade because sound files will be deleted below + SoundRenderer::getInstance().stopAllSounds(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + masterController.clearSlaves(true); + deleteValues(aiInterfaces.begin(), aiInterfaces.end()); + aiInterfaces.clear(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + gui.end(); //selection must be cleared before deleting units + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + world.end(); //must die before selection because of referencers + + BaseColorPickEntity::resetUniqueColors(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] aiInterfaces.size() = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + aiInterfaces.size()); + + delete videoPlayer; + videoPlayer = NULL; + playingStaticVideo = false; + + // MUST DO THIS LAST!!!! Because objects above have pointers to things like + // unit particles and fade them out etc and this end method deletes the original + // object pointers. + renderer.endGame(true); + BaseColorPickEntity::cleanupPBO(); + + GameConstants::updateFps = original_updateFps; + GameConstants::cameraFps = original_cameraFps; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + Unit::setGame(NULL); + + Lang::getInstance().setAllowNativeLanguageTechtree(true); + + FileCRCPreCacheThread *&preCacheCRCThreadPtr = + CacheManager::getCachedItem < + FileCRCPreCacheThread * + >(GameConstants::preCacheThreadCacheLookupKey); + if (preCacheCRCThreadPtr != NULL) { + preCacheCRCThreadPtr->setPauseForGame(false); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] ==== END GAME ==== getCurrentPixelByteCount() = " + MG_SIZE_T_SPECIFIER "\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderer.getCurrentPixelByteCount()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled) + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "==== END GAME ====\n"); + + //this->program->reInitGl(); + //renderer.reinitAll(); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + } + + bool Game::showTranslatedTechTree()const { + return this->gameSettings.getNetworkAllowNativeLanguageTechtree(); + } + + bool Game::quitTriggered() { + return quitTriggeredIndicator; + } + + Stats Game::quitAndToggleState() { + //quitGame(); + //Program *program = game->getProgram(); + return quitGame(); + //Game::exitGameState(program, endStats); + } + + // ==================== init and load ==================== + + int Game::ErrorDisplayMessage(const char *msg, bool exitApp) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] %s\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + msg); + + if (thisGamePtr != NULL) { + string text = msg; + thisGamePtr->showErrorMessageBox(text, "Error detected", false); + } + + return 0; + } + + //Texture2D * Game::findFactionLogoTexture(const GameSettings *settings, Logger *logger,string factionLogoFilter, bool useTechDefaultIfFilterNotFound) { + // Texture2D *result = NULL; + // string logoFilename = Game::findFactionLogoFile(settings, logger,factionLogoFilter); + // if(logoFilename == "" && factionLogoFilter != "" && useTechDefaultIfFilterNotFound == true) { + // logoFilename = Game::findFactionLogoFile(settings, logger); + // } + // + // result = Renderer::findTexture(logoFilename); + // + // return result; + //} + + string + Game::extractScenarioLogoFile(const GameSettings * settings, + string & result, bool & loadingImageUsed, + Logger * logger, + string factionLogoFilter) { + string scenarioDir = ""; + if (settings->getScenarioDir() != "") { + scenarioDir = settings->getScenarioDir(); + if (EndsWith(scenarioDir, ".xml") == true) { + scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4); + scenarioDir = + scenarioDir.erase(scenarioDir.size() - + settings->getScenario().size(), + settings->getScenario().size() + 1); + } + + //printf("!!! extractScenarioLogoFile scenarioDir [%s] factionLogoFilter [%s]\n",scenarioDir.c_str(),factionLogoFilter.c_str()); + + vector < string > loadScreenList; + string logoFullPathFilter = scenarioDir + factionLogoFilter; + findAll(logoFullPathFilter, loadScreenList, false, false); + if (loadScreenList.empty() == false) { + int bestLogoIndex = 0; + + if (loadScreenList.size() > 1 + && EndsWith(factionLogoFilter, ".xml") == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\nLooking for best logo from a list of: " + MG_SIZE_T_SPECIFIER " using filter: [%s]\n", + loadScreenList.size(), logoFullPathFilter.c_str()); + + int bestMinWidthDiff = INT_MAX; + int bestMinHeightDiff = INT_MAX; + // Now find the best texture for our screen + // Texture2D *result = preloadTexture(logoFilename); + for (unsigned int logoIndex = 0; + logoIndex < loadScreenList.size(); ++logoIndex) { + string + senarioLogo = scenarioDir + loadScreenList[bestLogoIndex]; + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] looking for loading screen '%s'\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, senarioLogo.c_str()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Looking for best logo: %u [%s]\n", logoIndex, + senarioLogo.c_str()); + + if (fileExists(senarioLogo) == true) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found loading screen '%s'\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, senarioLogo.c_str()); + + Texture2D *checkLogo = Renderer::preloadTexture(senarioLogo); + if (checkLogo != NULL) { + const Metrics & metrics = Metrics::getInstance(); + int + minWidthDifference = + abs(metrics.getScreenW() - + checkLogo->getPixmapConst()->getW()); + int + minHeightDifference = + abs(metrics.getScreenH() - + checkLogo->getPixmapConst()->getH()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Logo info: %d x %d (%d,%d)\n", + checkLogo->getPixmapConst()->getW(), + checkLogo->getPixmapConst()->getH(), + minWidthDifference, minHeightDifference); + + if (minWidthDifference < bestMinWidthDiff) { + bestMinWidthDiff = minWidthDifference; + + bestLogoIndex = logoIndex; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#1 New best logo is [%s]\n", + senarioLogo.c_str()); + } else if (minWidthDifference == bestMinWidthDiff + && minHeightDifference < bestMinHeightDiff) { + bestMinHeightDiff = minHeightDifference; + + bestLogoIndex = logoIndex; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#2 New best logo is [%s]\n", + senarioLogo.c_str()); + } + } + } + } + } + + string senarioLogo = scenarioDir + loadScreenList[bestLogoIndex]; + if (fileExists(senarioLogo) == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] found scenario loading screen '%s'\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + senarioLogo.c_str()); + + result = senarioLogo; + if (logger != NULL) { + logger->loadLoadingScreen(result); + } + loadingImageUsed = true; + } + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, + settings->getScenarioDir().c_str(), + settings->getScenario().c_str(), + scenarioDir.c_str()); + } + return scenarioDir; + } + + string + Game::extractFactionLogoFile(bool & loadingImageUsed, + const string & factionName, + string scenarioDir, + const string & techName, Logger * logger, + string factionLogoFilter) { + string result = ""; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] Searching for faction loading screen\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (factionName == formatString(GameConstants::OBSERVER_SLOTNAME)) { + string + data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + const string + factionLogo = data_path + "data/core/misc_textures/observer.jpg"; + //printf("In [%s::%s Line: %d] looking for loading screen '%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,factionLogo.c_str()); + + if (fileExists(factionLogo) == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found loading screen '%s'\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + factionLogo.c_str()); + + result = factionLogo; + if (logger != NULL) { + logger->loadLoadingScreen(result); + } + loadingImageUsed = true; + } + } + //else if(settings->getFactionTypeName(i) == formatString(GameConstants::RANDOMFACTION_SLOTNAME)) { + else if (factionName == + formatString(GameConstants::RANDOMFACTION_SLOTNAME)) { + string + data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + const string + factionLogo = data_path + "data/core/misc_textures/random.jpg"; + + if (fileExists(factionLogo) == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found loading screen '%s'\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + factionLogo.c_str()); + + result = factionLogo; + if (logger != NULL) { + logger->loadLoadingScreen(result); + } + loadingImageUsed = true; + } + } else { + Config & config = Config::getInstance(); + vector < string > pathList = + config.getPathListForType(ptTechs, scenarioDir); + for (int idx = 0; idx < (int) pathList.size(); idx++) { + string currentPath = pathList[idx]; + endPathWithSlash(currentPath); + //string path = currentPath + techName + "/" + "factions" + "/" + settings->getFactionTypeName(i); + string + path = + currentPath + techName + "/" + "factions" + "/" + factionName; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] possible loading screen dir '%s'\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + path.c_str()); + if (isdir(path.c_str()) == true) { + endPathWithSlash(path); + + vector < string > loadScreenList; + string logoFullPathFilter = path + factionLogoFilter; + findAll(logoFullPathFilter, loadScreenList, false, false); + if (loadScreenList.empty() == false) { + int bestLogoIndex = 0; + + if (loadScreenList.size() > 1 + && EndsWith(factionLogoFilter, ".xml") == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\nLooking for best logo from a list of: " + MG_SIZE_T_SPECIFIER + " using filter: [%s]\n", + loadScreenList.size(), + logoFullPathFilter.c_str()); + + + int bestMinWidthDiff = INT_MAX; + int bestMinHeightDiff = INT_MAX; + // Now find the best texture for our screen + // Texture2D *result = preloadTexture(logoFilename); + for (unsigned int logoIndex = 0; + logoIndex < + (unsigned int) loadScreenList.size(); ++logoIndex) { + string factionLogo = path + loadScreenList[logoIndex]; + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] looking for loading screen '%s'\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + factionLogo.c_str()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Looking for best logo: %u [%s]\n", + logoIndex, factionLogo.c_str()); + + if (fileExists(factionLogo) == true) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found loading screen '%s'\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + factionLogo.c_str()); + + Texture2D *checkLogo = + Renderer::preloadTexture(factionLogo); + if (checkLogo != NULL) { + const Metrics & metrics = Metrics::getInstance(); + int + minWidthDifference = + abs(metrics.getScreenW() - + checkLogo->getPixmapConst()->getW()); + int + minHeightDifference = + abs(metrics.getScreenH() - + checkLogo->getPixmapConst()->getH()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("Logo info: %d x %d (%d,%d)\n", + checkLogo->getPixmapConst()->getW(), + checkLogo->getPixmapConst()->getH(), + minWidthDifference, minHeightDifference); + + if (minWidthDifference < bestMinWidthDiff) { + bestMinWidthDiff = minWidthDifference; + + bestLogoIndex = logoIndex; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("#1 New best logo is [%s]\n", + factionLogo.c_str()); + } else if (minWidthDifference == + bestMinWidthDiff + && minHeightDifference < bestMinHeightDiff) { + bestMinHeightDiff = minHeightDifference; + + bestLogoIndex = logoIndex; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("#2 New best logo is [%s]\n", + factionLogo.c_str()); + } + } + } + } + } + + string factionLogo = path + loadScreenList[bestLogoIndex]; + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] looking for loading screen '%s'\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, factionLogo.c_str()); + + if (fileExists(factionLogo) == true) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found loading screen '%s'\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, factionLogo.c_str()); + + result = factionLogo; + if (logger != NULL) { + logger->loadLoadingScreen(result); + } + loadingImageUsed = true; + break; + } + } + // Check if this is a linked faction + else { + //!!! + string factionXMLFile = path + factionName + ".xml"; + + //printf("A factionXMLFile [%s]\n",factionXMLFile.c_str()); + + if (fileExists(factionXMLFile) == true) { + XmlTree xmlTreeFaction(XML_RAPIDXML_ENGINE); + std::map < string, string > mapExtraTagReplacementValues; + xmlTreeFaction.load(factionXMLFile, + Properties::getTagReplacementValues + (&mapExtraTagReplacementValues), + true, true); + + const XmlNode *rootNode = xmlTreeFaction.getRootNode(); + + //printf("B factionXMLFile [%s] root name [%s] root first child name [%s]\n",factionXMLFile.c_str(),rootNode->getName().c_str(),rootNode->getChild(0)->getName().c_str()); + //printf("B factionXMLFile [%s] root name [%s]\n",factionXMLFile.c_str(),rootNode->getName().c_str()); + if (rootNode->hasChild("link") == true) { + rootNode = rootNode->getChild("link"); + } + if (rootNode->getName() == "link" + && rootNode->hasChild("techtree") == true) { + const XmlNode *linkNode = rootNode; + + //printf("C factionXMLFile [%s]\n",factionXMLFile.c_str()); + + //if(linkNode->hasChild("techtree") == true) { + const XmlNode *techtreeNode = + linkNode->getChild("techtree"); + + string + linkedTechTreeName = + techtreeNode->getAttribute("name")->getValue(); + + //printf("D factionXMLFile [%s] linkedTechTreeName [%s]\n",factionXMLFile.c_str(),linkedTechTreeName.c_str()); + + if (linkedTechTreeName != "") { + + string + linkedTechTreePath = + TechTree::findPath(linkedTechTreeName, pathList); + string techTreePath = linkedTechTreePath; + endPathWithSlash(techTreePath); + + string + linkedCurrentPath = + techTreePath + "factions/" + factionName; + endPathWithSlash(linkedCurrentPath); + //string linkedTmppath= linkedCurrentPath + factionName +".xml"; + + path = linkedCurrentPath; + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] possible loading screen dir '%s'\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + path.c_str()); + + //printf("D1 idx = %d\ncurrentPath [%s]\npath [%s]\npathList[idx] [%s]\n",idx,currentPath.c_str(),path.c_str(),pathList[idx].c_str()); + + if (isdir(path.c_str()) == true) { + endPathWithSlash(path); + + //printf("E path [%s]\n",path.c_str()); + + loadScreenList.clear(); + findAll(path + factionLogoFilter, + loadScreenList, false, false); + if (loadScreenList.empty() == false) { + string factionLogo = path + loadScreenList[0]; + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] looking for loading screen '%s'\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, + __LINE__, + factionLogo.c_str()); + + //printf("F factionLogo [%s]\n",factionLogo.c_str()); + + if (fileExists(factionLogo) == true) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug + (SystemFlags::debugSystem, + "In [%s::%s Line: %d] found loading screen '%s'\n", + extractFileFromDirectoryPath(__FILE__).c_str + (), __FUNCTION__, __LINE__, + factionLogo.c_str()); + + result = factionLogo; + if (logger != NULL) { + logger->loadLoadingScreen(result); + } + loadingImageUsed = true; + break; + } + } + } + } + //} + } + } + } + } + + if (loadingImageUsed == true) { + break; + } + } + } + //break; + //} + //} + return result; + } + + string + Game::extractTechLogoFile(string scenarioDir, const string & techName, + bool & loadingImageUsed, Logger * logger, + const string & factionLogoFilter) { + string result = ""; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] Searching for tech loading screen\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + Config & config = Config::getInstance(); + vector < string > pathList = + config.getPathListForType(ptTechs, scenarioDir); + for (int idx = 0; idx < (int) pathList.size(); idx++) { + string currentPath = pathList[idx]; + endPathWithSlash(currentPath); + string path = currentPath + techName; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] possible loading screen dir '%s'\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, path.c_str()); + if (isdir(path.c_str()) == true) { + endPathWithSlash(path); + + vector < string > loadScreenList; + findAll(path + factionLogoFilter, loadScreenList, false, false); + if (loadScreenList.empty() == false) { + string factionLogo = path + loadScreenList[0]; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] looking for loading screen '%s'\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, factionLogo.c_str()); + + if (fileExists(factionLogo) == true) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found loading screen '%s'\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, factionLogo.c_str()); + + result = factionLogo; + if (logger != NULL) { + logger->loadLoadingScreen(result); + } + loadingImageUsed = true; + break; + } + } + } + if (loadingImageUsed == true) { + break; + } + } + + return result; + } + + void Game::loadHudTexture(const GameSettings * settings) { + string factionName = ""; + string techName = settings->getTech(); + string + scenarioDir = + extractDirectoryPathFromFile(settings->getScenarioDir()); + //printf("In loadHudTexture, scenarioDir [%s]\n",scenarioDir.c_str()); + + for (int i = 0; i < settings->getFactionCount(); ++i) { + if ((settings->getFactionControl(i) == ctHuman) + || (settings->getFactionControl(i) == ctNetwork + && settings->getThisFactionIndex() == i)) { + factionName = settings->getFactionTypeName(i); + break; + } + } + if (factionName != "") { + bool hudFound = false; + Config & config = Config::getInstance(); + vector < string > pathList = + config.getPathListForType(ptTechs, scenarioDir); + for (int idx = 0; hudFound == false && idx < (int) pathList.size(); + idx++) { + string currentPath = pathList[idx]; + endPathWithSlash(currentPath); + + vector < string > hudList; + string + path = + currentPath + techName + "/" + "factions" + "/" + factionName; + endPathWithSlash(path); + findAll(path + GameConstants::HUD_SCREEN_FILE_FILTER, hudList, + false, false); + if (hudList.empty() == false) { + for (unsigned int hudIdx = 0; + hudFound == false + && hudIdx < (unsigned int) hudList.size(); ++hudIdx) { + string hudImageFileName = path + hudList[hudIdx]; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line: %d] looking for a HUD [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, hudImageFileName.c_str()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] looking for a HUD [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, + hudImageFileName.c_str()); + + if (fileExists(hudImageFileName) == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line: %d] found HUD image [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, hudImageFileName.c_str()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] found HUD image [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, + hudImageFileName.c_str()); + + Texture2D *texture = Renderer::findTexture(hudImageFileName); + gui.setHudTexture(texture); + hudFound = true; + //printf("Hud texture found! \n"); + break; + } + } + } + } + } + } + + string + Game::findFactionLogoFile(const GameSettings * settings, + Logger * logger, + const string & factionLogoFilter) { + string result = ""; + if (settings == NULL) { + result = ""; + } else { + string mapName = settings->getMap(); + string tilesetName = settings->getTileset(); + string techName = settings->getTech(); + string scenarioName = settings->getScenario(); + bool loadingImageUsed = false; + + if (logger != NULL) { + logger->setState(Lang::getInstance().getString("Loading")); + + if (scenarioName.empty()) { + string + scenarioDir = + extractDirectoryPathFromFile(settings->getScenarioDir()); + TechTree + techTree(Config:: + getInstance().getPathListForType(ptTechs, + scenarioDir)); + + logger->setSubtitle(formatString(mapName) + " - " + + formatString(tilesetName) + " - " + + formatString(techTree.getTranslatedName + (techName))); + } else { + logger->setSubtitle(formatString(scenarioName)); + } + } + + //string scenarioDir = ""; + //bool skipCustomLoadScreen = false; + //if(skipCustomLoadScreen == false) { + string + scenarioDir = + extractScenarioLogoFile(settings, result, loadingImageUsed, + logger, factionLogoFilter); + //} + // try to use a faction related loading screen + //if(skipCustomLoadScreen == false && loadingImageUsed == false) { + if (loadingImageUsed == false) { + for (int i = 0; i < settings->getFactionCount(); ++i) { + if (settings->getFactionControl(i) == ctHuman || + (settings->getFactionControl(i) == ctNetwork + && settings->getThisFactionIndex() == i)) { + + result = + extractFactionLogoFile(loadingImageUsed, + settings->getFactionTypeName(i), + scenarioDir, techName, logger, + factionLogoFilter); + break; + } + } + } + + // try to use a tech related loading screen + //if(skipCustomLoadScreen == false && loadingImageUsed == false){ + if (loadingImageUsed == false) { + result = extractTechLogoFile(scenarioDir, techName, + loadingImageUsed, logger, + factionLogoFilter); + } + } + return result; + } + + vector < Texture2D * >Game::processTech(string techName) { + vector < Texture2D * >logoFiles; + bool + enableFactionTexturePreview = + Config::getInstance().getBool("FactionPreview", "true"); + if (enableFactionTexturePreview) { + //string currentTechName_factionPreview = techName; + + vector < string > factions; + vector < string > techPaths = + Config::getInstance().getPathListForType(ptTechs); + for (int idx = 0; idx < (int) techPaths.size(); idx++) { + string & techPath = techPaths[idx]; + endPathWithSlash(techPath); + findAll(techPath + techName + "/factions/*.", factions, false, + false); + + if (factions.empty() == false) { + for (unsigned int factionIdx = 0; + factionIdx < (unsigned int) factions.size(); ++factionIdx) { + bool loadingImageUsed = false; + string currentFactionName_factionPreview = factions[factionIdx]; + + string + factionLogo = + Game::extractFactionLogoFile(loadingImageUsed, + currentFactionName_factionPreview, + "", + techName, + NULL, + GameConstants::PREVIEW_SCREEN_FILE_FILTER); + + if (factionLogo == "") { + factionLogo = + Game::extractFactionLogoFile(loadingImageUsed, + currentFactionName_factionPreview, + "", techName, NULL, + GameConstants::LOADING_SCREEN_FILE_FILTER); + } + if (factionLogo != "") { + Texture2D *texture = Renderer::preloadTexture(factionLogo); + logoFiles.push_back(texture); + } + } + } + } + } + + return logoFiles; + } + + void Game::load() { + load(lgt_All); + } + + void Game::load(int loadTypes) { + bool + showPerfStats = + Config::getInstance().getBool("ShowPerfStats", "false"); + Chrono chronoPerf; + if (showPerfStats) + chronoPerf.start(); + char perfBuf[8096] = ""; + std::vector < string > perfList; + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + FileCRCPreCacheThread *&preCacheCRCThreadPtr = + CacheManager::getCachedItem < + FileCRCPreCacheThread * + >(GameConstants::preCacheThreadCacheLookupKey); + if (preCacheCRCThreadPtr != NULL) { + preCacheCRCThreadPtr->setPauseForGame(true); + } + + std::map < string, vector < pair < string, string > > >loadedFileList; + originalDisplayMsgCallback = + NetworkInterface::getDisplayMessageFunction(); + NetworkInterface::setDisplayMessageFunction(ErrorDisplayMessage); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] loadTypes = %d, gameSettings = [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + loadTypes, + this->gameSettings.toString().c_str()); + + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + soundRenderer.stopAllSounds(fadeMusicMilliseconds); + + BaseColorPickEntity::resetUniqueColors(); + + Config & config = Config::getInstance(); + Logger & logger = Logger::getInstance(); + + string mapName = gameSettings.getMap(); + string tilesetName = gameSettings.getTileset(); + string techName = gameSettings.getTech(); + string scenarioName = gameSettings.getScenario(); + string + data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + // loadHints + + if (data_path != "") { + endPathWithSlash(data_path); + } + + string user_data_path = config.getString("UserData_Root", ""); + if (user_data_path != "") { + endPathWithSlash(user_data_path); + } + + string + englishFile = + getGameCustomCoreDataPath(data_path, + "data/lang/hint/hint_" + + Lang:: + getInstance().getDefaultLanguage() + + ".lng"); + string languageFile = + getGameCustomCoreDataPath(data_path, + "data/lang/hint/hint_" + + Lang::getInstance().getLanguage() + + ".lng"); + string languageFileUserData = + user_data_path + "data/lang/hint/hint_" + + Lang::getInstance().getLanguage() + ".lng"; + + if (fileExists(languageFileUserData) == true) { + languageFile = languageFileUserData; + } + if (fileExists(languageFile) == false) { + // if there is no language specific file use english instead + languageFile = englishFile; + } + if (fileExists(englishFile) == false) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] file [%s] not found\n", + __FILE__, __FUNCTION__, __LINE__, + englishFile.c_str()); + } else { + logger.loadGameHints(englishFile, languageFile, true); + + ::Shared::Platform::Window::handleEvent(); + SDL_PumpEvents(); + } + + if ((loadTypes & lgt_FactionPreview) == lgt_FactionPreview) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + Game::findFactionLogoFile(&gameSettings, &logger); + + ::Shared::Platform::Window::handleEvent(); + SDL_PumpEvents(); + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + loadHudTexture(&gameSettings); + + const string + markCellTextureFilename = + data_path + "data/core/misc_textures/mark_cell.png"; + markCellTexture = Renderer::findTexture(markCellTextureFilename); + const string + unmarkCellTextureFilename = + data_path + "data/core/misc_textures/unmark_cell.png"; + unmarkCellTexture = Renderer::findTexture(unmarkCellTextureFilename); + const string + highlightCellTextureFilename = + data_path + "data/core/misc_textures/pointer.png"; + highlightCellTexture = + Renderer::findTexture(highlightCellTextureFilename); + + string scenarioDir = ""; + if (gameSettings.getScenarioDir() != "") { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + scenarioDir = gameSettings.getScenarioDir(); + if (EndsWith(scenarioDir, ".xml") == true) { + scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4); + scenarioDir = + scenarioDir.erase(scenarioDir.size() - + gameSettings.getScenario().size(), + gameSettings.getScenario().size() + 1); + } + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //tileset + if ((loadTypes & lgt_TileSet) == lgt_TileSet) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + world. + loadTileset(config.getPathListForType(ptTilesets, scenarioDir), + tilesetName, &checksum, loadedFileList); + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + // give CPU time to update other things to avoid apperance of hanging + sleep(0); + ::Shared::Platform::Window::handleEvent(); + SDL_PumpEvents(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + set < string > factions; + for (int i = 0; i < gameSettings.getFactionCount(); ++i) { + factions.insert(gameSettings.getFactionTypeName(i)); + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if ((loadTypes & lgt_TechTree) == lgt_TechTree) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //tech, load before map because of resources + world.loadTech(config.getPathListForType(ptTechs, scenarioDir), + techName, factions, &checksum, loadedFileList); + + if (world.getTechTree() == NULL + || world.getTechTree()->getNameUntranslated() == "") { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Line ref: %d, ERROR: Cannot find techtree: [%s]", + __LINE__, techName.c_str()); + + throw megaglest_runtime_error(szBuf, true); + } + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + // give CPU time to update other things to avoid apperance of hanging + sleep(0); + ::Shared::Platform::Window::handleEvent(); + SDL_PumpEvents(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //map + if ((loadTypes & lgt_Map) == lgt_Map) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + world.loadMap(Config::getMapPath(mapName, scenarioDir), &checksum); + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + // give CPU time to update other things to avoid apperance of hanging + sleep(0); + ::Shared::Platform::Window::handleEvent(); + SDL_PumpEvents(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //scenario + if ((loadTypes & lgt_Scenario) == lgt_Scenario) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + if (scenarioName.empty() == false) { + + bool + isTutorial = + Scenario::isGameTutorial(gameSettings.getScenarioDir()); + //printf("Loading scenario gameSettings.getScenarioDir() [%s] scenarioName [%s] isTutorial: %d\n",gameSettings.getScenarioDir().c_str(),scenarioName.c_str(),isTutorial); + + Lang::getInstance(). + loadScenarioStrings(gameSettings.getScenarioDir(), scenarioName, + isTutorial); + + //printf("In [%s::%s Line: %d] rootNode [%p][%s]\n",__FILE__,__FUNCTION__,__LINE__,loadGameNode,(loadGameNode != NULL ? loadGameNode->getName().c_str() : "none")); + world.loadScenario(gameSettings.getScenarioDir(), &checksum, + false, loadGameNode); + } + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + // give CPU time to update other things to avoid apperance of hanging + sleep(0); + SDL_PumpEvents(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + //good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + if (showPerfStats && chronoPerf.getMillis() >= 50) { + for (unsigned int x = 0; x < perfList.size(); ++x) { + printf("%s", perfList[x].c_str()); + } + } + } + + void Game::init() { + init(false); + } + + void Game::init(bool initForPreviewOnly) { + bool + showPerfStats = + Config::getInstance().getBool("ShowPerfStats", "false"); + Chrono chronoPerf; + if (showPerfStats) + chronoPerf.start(); + char perfBuf[8096] = ""; + std::vector < string > perfList; + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] initForPreviewOnly = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + initForPreviewOnly); + + Lang & lang = Lang::getInstance(); + Logger & logger = Logger::getInstance(); + CoreData & coreData = CoreData::getInstance(); + Renderer & renderer = Renderer::getInstance(); + Map *map = world.getMap(); + NetworkManager & networkManager = NetworkManager::getInstance(); + + GameSettings::playerDisconnectedText = + "*" + lang.getString("AI") + "* "; + + if (map == NULL) { + throw megaglest_runtime_error("map == NULL"); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (initForPreviewOnly == false) { + logger.setState(lang.getString("Initializing")); + + //message box + mainMessageBox.init(lang.getString("Yes"), lang.getString("No")); + mainMessageBox.setEnabled(false); + + //message box + errorMessageBox.init(lang.getString("Ok")); + errorMessageBox.setEnabled(false); + errorMessageBox.setY(20); + + + //init world, and place camera + commander.init(&world); + + // give CPU time to update other things to avoid apperance of hanging + sleep(0); + ::Shared::Platform::Window::handleEvent(); + SDL_PumpEvents(); + } + + try { + world.init(this, gameSettings.getDefaultUnits()); + } catch (const megaglest_runtime_error & ex) { + string sErrBuf = ""; + if (ex.wantStackTrace() == true) { + char szErrBuf[8096] = ""; + snprintf(szErrBuf, 8096, "In [%s::%s %d]", __FILE__, + __FUNCTION__, __LINE__); + sErrBuf = + string(szErrBuf) + string("\nerror [") + string(ex.what()) + + string("]\n"); + } else { + sErrBuf = ex.what(); + } + SystemFlags::OutputDebug(SystemFlags::debugError, sErrBuf.c_str()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + sErrBuf.c_str()); + + if (errorMessageBox.getEnabled() == false) { + ErrorDisplayMessage(ex.what(), true); + } + } catch (const exception & ex) { + char szErrBuf[8096] = ""; + snprintf(szErrBuf, 8096, "In [%s::%s %d]", __FILE__, __FUNCTION__, + __LINE__); + string + sErrBuf = + string(szErrBuf) + string("\nerror [") + string(ex.what()) + + string("]\n"); + SystemFlags::OutputDebug(SystemFlags::debugError, sErrBuf.c_str()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + sErrBuf.c_str()); + + if (errorMessageBox.getEnabled() == false) { + ErrorDisplayMessage(ex.what(), true); + } + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (loadGameNode != NULL) { + //world.getMapPtr()->loadGame(loadGameNode,&world); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (initForPreviewOnly == false) { + // give CPU time to update other things to avoid apperance of hanging + sleep(0); + ::Shared::Platform::Window::handleEvent(); + SDL_PumpEvents(); + + gui.init(this); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + // give CPU time to update other things to avoid apperance of hanging + sleep(0); + //SDL_PumpEvents(); + + chatManager.init(&console, world.getThisTeamIndex()); + console.clearStoredLines(); + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (this->loadGameNode == NULL) { + initCamera(map); + } else { + gui.loadGame(loadGameNode, &world); + + if (inJoinGameLoading == true) { + initCamera(map); + } + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + NetworkRole role = nrIdle; + if (initForPreviewOnly == false) { + // give CPU time to update other things to avoid apperance of hanging + sleep(0); + ::Shared::Platform::Window::handleEvent(); + SDL_PumpEvents(); + + scriptManager.init(&world, &gameCamera, loadGameNode); + + //good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] creating AI's\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //create AIs + + bool + enableServerControlledAI = + this->gameSettings.getEnableServerControlledAI(); + bool isNetworkGame = this->gameSettings.isNetworkGame(); + role = networkManager.getNetworkRole(); + + masterController.clearSlaves(true); + deleteValues(aiInterfaces.begin(), aiInterfaces.end()); + + std::vector < SlaveThreadControllerInterface * >slaveThreadList; + aiInterfaces.resize(world.getFactionCount()); + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + + //printf("Controltype = %d for index = %d\n",faction->getControlType(),i); + + if (faction->getCpuControl(enableServerControlledAI, isNetworkGame, + role) == true) { + //printf("** Loading AI player for Controltype = %d for index = %d\n",faction->getControlType(),i); + + aiInterfaces[i] = new AiInterface(*this, i, faction->getTeam()); + if (loadGameNode != NULL) { + aiInterfaces[i]->loadGame(loadGameNode, faction); + } + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + Lang::getInstance().getString + ("LogScreenGameLoadingCreatingAIFaction", "", + true).c_str(), i); + logger.add(szBuf, true); + + slaveThreadList.push_back(aiInterfaces[i]->getWorkerThread()); + } else { + aiInterfaces[i] = NULL; + } + } + if (Config:: + getInstance().getBool("EnableNewThreadManager", + "false") == true) { + masterController.setSlaves(slaveThreadList); + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER + "\n", extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + // give CPU time to update other things to avoid apperance of hanging + sleep(0); + ::Shared::Platform::Window::handleEvent(); + SDL_PumpEvents(); + + if (world.getFactionCount() == 1 + && world.getFaction(0)->getPersonalityType() == fpt_Observer) { + withRainEffect = false; + } + + if (withRainEffect) { + //weather particle systems + if (world.getTileset()->getWeather() == wRainy) { + logger.add(Lang::getInstance().getString + ("LogScreenGameLoadingCreatingRainParticles", + "", true), true); + weatherParticleSystem = new RainParticleSystem(); + weatherParticleSystem->setSpeed(12.f / GameConstants::updateFps); + weatherParticleSystem->setPos(gameCamera.getPos()); + renderer.manageParticleSystem(weatherParticleSystem, rsGame); + } else if (world.getTileset()->getWeather() == wSnowy) { + logger.add(Lang::getInstance().getString + ("LogScreenGameLoadingCreatingSnowParticles", + "", true), true); + weatherParticleSystem = new SnowParticleSystem(1200); + weatherParticleSystem->setSpeed(1.5f / GameConstants::updateFps); + weatherParticleSystem->setPos(gameCamera.getPos()); + weatherParticleSystem->setTexture(coreData.getSnowTexture()); + renderer.manageParticleSystem(weatherParticleSystem, rsGame); + } + } else if (world.getTileset()->getWeather() == wRainy) { + world.getTileset()->setWeather(wSunny); + } + + renderer.manageDeferredParticleSystems(); + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + //init renderer state + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Initializing renderer\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__); + logger. + add(Lang:: + getInstance().getString("LogScreenGameLoadingInitRenderer", "", + true), true); + + //printf("Before renderer.initGame\n"); + renderer.initGame(this, this->getGameCameraPtr()); + //printf("After renderer.initGame\n"); + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + if (faction != NULL) { + faction->deletePixels(); + } + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (initForPreviewOnly == false) { + //good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + // give CPU time to update other things to avoid apperance of hanging + sleep(0); + ::Shared::Platform::Window::handleEvent(); + SDL_PumpEvents(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Waiting for network\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__); + logger. + add(Lang:: + getInstance().getString + ("LogScreenGameLoadingWaitForNetworkPlayers", "", true), true); + networkManager.getGameNetworkInterface()->waitUntilReady(&checksum); + + //std::string worldLog = world.DumpWorldToLog(true); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] Starting music stream\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + logger. + add(Lang:: + getInstance().getString("LogScreenGameLoadingStartingMusic", + "", true), true); + + if (this->masterserverMode == false) { + if (world.getThisFaction() == NULL) { + throw megaglest_runtime_error("world.getThisFaction() == NULL"); + } + if (world.getThisFaction()->getType() == NULL) { + throw + megaglest_runtime_error + ("world.getThisFaction()->getType() == NULL"); + } + //if(world.getThisFaction()->getType()->getMusic() == NULL) { + // throw megaglest_runtime_error("world.getThisFaction()->getType()->getMusic() == NULL"); + //} + } + + //sounds + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + soundRenderer.stopAllSounds(fadeMusicMilliseconds); + soundRenderer = SoundRenderer::getInstance(); + + Tileset *tileset = world.getTileset(); + AmbientSounds *ambientSounds = tileset->getAmbientSounds(); + + //rain + if (tileset->getWeather() == wRainy + && ambientSounds->isEnabledRain()) { + logger. + add(Lang:: + getInstance().getString + ("LogScreenGameLoadingStartingAmbient", "", true), true); + currentAmbientSound = ambientSounds->getRain(); + //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); + soundRenderer.playAmbient(currentAmbientSound); + } + + //snow + if (tileset->getWeather() == wSnowy + && ambientSounds->isEnabledSnow()) { + logger. + add(Lang:: + getInstance().getString + ("LogScreenGameLoadingStartingAmbient", "", true), true); + currentAmbientSound = ambientSounds->getSnow(); + //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); + soundRenderer.playAmbient(currentAmbientSound); + } + + if (this->masterserverMode == false) { + StrSound *gameMusic = + world.getThisFaction()->getType()->getMusic(); + soundRenderer.playMusic(gameMusic); + } + + logger. + add(Lang:: + getInstance().getString("LogScreenGameLoadingLaunchGame", "", + true)); + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + //throw "test"; + + logger.setCancelLoadingEnabled(false); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "================ STARTING GAME ================\n"); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPathFinder).enabled) + SystemFlags::OutputDebug(SystemFlags::debugPathFinder, + "================ STARTING GAME ================\n"); + setupPopupMenus(false); + + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + + //printf("Check for team switch to observer i = %d, team = %d [%d]\n",i,faction->getTeam(),(GameConstants::maxPlayers -1 + fpt_Observer)); + if (faction != NULL + && faction->getTeam() == + GameConstants::maxPlayers - 1 + fpt_Observer) { + faction->setPersonalityType(fpt_Observer); + world.getStats()->setPersonalityType(i, + faction->getPersonalityType + ()); + } + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (role == nrClient) { + ClientInterface *clientInterface = + dynamic_cast < + ClientInterface *>(networkManager.getClientInterface()); + if (clientInterface != NULL + && clientInterface->getResumeInGameJoin() == true) { + + //printf("Client sending resume message to server...\n"); + + clientInterface->sendResumeGameMessage(); + //this->initialResumeSpeedLoops = true; + } + } + + printf("Game unique identifier is: %s\n", + this->gameSettings.getGameUUID().c_str()); + + gameStarted = true; + + if (this->masterserverMode == true) { + world.getStats()->setIsMasterserverMode(true); + + printf("New game has started...\n"); + } + + if (isFlagType1BitEnabled(ft1_network_synch_checks_verbose) == true) { + printf("*Note: Monitoring Network CRC VERBOSE synchronization...\n"); + } else if (isFlagType1BitEnabled(ft1_network_synch_checks) == true) { + printf("*Note: Monitoring Network CRC NORMAL synchronization...\n"); + } + + //NetworkRole role = networkManager.getNetworkRole(); + if (role == nrServer) { + networkManager.initServerInterfaces(this); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] ==== START GAME ==== getCurrentPixelByteCount() = " + MG_SIZE_T_SPECIFIER "\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderer.getCurrentPixelByteCount()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled) + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "=============================================\n"); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled) + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "==== START GAME ====\n"); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled) + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "=============================================\n"); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled) + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "Starting framecount: %d\n", + world.getFrameCount()); + + if (showPerfStats && chronoPerf.getMillis() >= 50) { + for (unsigned int x = 0; x < perfList.size(); ++x) { + printf("%s", perfList[x].c_str()); + } + } + } + + void Game::initCamera(Map * map) { + gameCamera.init(map->getW(), map->getH()); + + // camera default height calculation + if (map->getCameraHeight() > 0 + && gameCamera.getCalculatedDefault() < map->getCameraHeight()) { + gameCamera.setCalculatedDefault(map->getCameraHeight()); + } else if (gameCamera.getCalculatedDefault() < + map->getMaxMapHeight() + 13.0f) { + gameCamera.setCalculatedDefault(map->getMaxMapHeight() + 13.0f); + } + + if (world.getThisFaction() != NULL) { + const + Vec2i & + v = + map->getStartLocation(world. + getThisFaction()->getStartLocationIndex()); + // This args are set in map.cpp - Map::getStartLocation() + gameCamera.setPos(Vec2f + (v.x, + v.y + gameCamera.getCalculatedDefault() / 2)); + // + // for issue 13: observer mode (wip) + // This sets the camera position the same for each player. + // The goal is to set the camera position to this for observers only + // since they don't have a StartLocationIndex + // gameCamera.setPos(Vec2f(10, 10)); + + } + } + + // ==================== update ==================== + + void Game::reInitGUI() { + gui.init(this); + } + + void Game::setupPopupMenus(bool checkClientAdminOverrideOnly) { + Lang & lang = Lang::getInstance(); + NetworkManager & networkManager = NetworkManager::getInstance(); + NetworkRole role = networkManager.getNetworkRole(); + ClientInterface *clientInterface = NULL; + ServerInterface *serverInterface = NULL; + + bool allowAdminMenuItems = false; + bool forceJoinInProgressUpdate = false; + if (role == nrServer) { + allowAdminMenuItems = true; + + if (disconnectPlayerPopupMenuIndex == -1) { + serverInterface = + dynamic_cast < + ServerInterface *>(networkManager.getServerInterface()); + if (serverInterface != NULL && checkClientAdminOverrideOnly == true) { + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + + MutexSafeWrapper + safeMutex(serverInterface->getSlotMutex + (faction->getStartLocationIndex()), CODE_AT_LINE); + ConnectionSlot *slot = + serverInterface->getSlot(faction->getStartLocationIndex(), + false); + if (slot != NULL + && slot->getConnectHasHandshaked() == true + && slot->getCurrentFrameCount() <= 0) { + //printf("Connected slot can be disconnected: %d\n",slot->getPlayerIndex()); + + forceJoinInProgressUpdate = true; + break; + } + } + } + } + } else if (role == nrClient) { + clientInterface = + dynamic_cast < + ClientInterface *>(networkManager.getClientInterface()); + + if (clientInterface != NULL && + (gameSettings.getMasterserver_admin() == + clientInterface->getSessionKey() + || clientInterface->isMasterServerAdminOverride() == true)) { + allowAdminMenuItems = true; + } + } + + if (checkClientAdminOverrideOnly == false || + forceJoinInProgressUpdate == true || + (clientInterface != NULL && + (gameSettings.getMasterserver_admin() != + clientInterface->getSessionKey() + && clientInterface->isMasterServerAdminOverride() == true))) { + exitGamePopupMenuIndex = -1; + joinTeamPopupMenuIndex = -1; + pauseGamePopupMenuIndex = -1; + saveGamePopupMenuIndex = -1; + loadGamePopupMenuIndex = -1; + keyboardSetupPopupMenuIndex = -1; + disconnectPlayerPopupMenuIndex = -1; + + if (checkClientAdminOverrideOnly == true && clientInterface != NULL) { + gameSettings. + setMasterserver_admin(clientInterface->getSessionKey()); + gameSettings.setMasterserver_admin_faction_index + (clientInterface->getPlayerIndex()); + } + //PopupMenu popupMenu; + std::vector < string > menuItems; + menuItems.push_back(" " + lang.getString("ExitGameMenu") + " "); + exitGamePopupMenuIndex = (int) menuItems.size() - 1; + + if ((gameSettings.getFlagTypes1() & ft1_allow_team_switching) == + ft1_allow_team_switching && world.getThisFaction() != NULL + && world.getThisFaction()->getPersonalityType() != fpt_Observer) { + menuItems.push_back(" " + lang.getString("JoinOtherTeam") + + " "); + joinTeamPopupMenuIndex = (int) menuItems.size() - 1; + } + + if (allowAdminMenuItems == true) { + menuItems.push_back(" " + lang.getString("PauseResumeGame") + + " "); + pauseGamePopupMenuIndex = (int) menuItems.size() - 1; + + if (gameSettings.isNetworkGame() == false + || gameSettings.getScenario() != "") { + menuItems.push_back(" " + lang.getString("SaveGame") + " "); + saveGamePopupMenuIndex = (int) menuItems.size() - 1; + } + + if (gameSettings.isNetworkGame() == true) { + menuItems.push_back(" " + + lang.getString("DisconnectNetorkPlayer") + + " "); + disconnectPlayerPopupMenuIndex = (int) menuItems.size() - 1; + } + } + menuItems.push_back(" " + lang.getString("KeyboardsetupL") + " "); + keyboardSetupPopupMenuIndex = (int) menuItems.size() - 1; + + menuItems.push_back(" " + lang.getString("Cancel") + " "); + + popupMenu.setW(100); + popupMenu.setH(100); + popupMenu.init(" " + lang.getString("GameMenuTitle") + " ", + menuItems); + popupMenu.setEnabled(false); + popupMenu.setVisible(false); + + popupMenuSwitchTeams.setEnabled(false); + popupMenuSwitchTeams.setVisible(false); + + popupMenuDisconnectPlayer.setEnabled(false); + popupMenuDisconnectPlayer.setVisible(false); + } + } + + void Game::processNetworkSynchChecksIfRequired() { + bool isNetworkGame = this->gameSettings.isNetworkGame(); + if (isNetworkGame == true + && NetworkManager::getInstance().getGameNetworkInterface() != + NULL) { + GameSettings *settings = world.getGameSettingsPtr(); + if (settings != NULL) { + bool calculateNetworkCRC = false; + + if (isFlagType1BitEnabled(ft1_network_synch_checks) == true || + isFlagType1BitEnabled(ft1_network_synch_checks_verbose) == + true) { + calculateNetworkCRC = true; + } + + if (calculateNetworkCRC == true) { + NetworkManager & networkManager = NetworkManager::getInstance(); + NetworkRole role = networkManager.getNetworkRole(); + + NetworkInterface *netIntf = + networkManager.getGameNetworkInterface(); + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + if (index < world.getFactionCount()) { + Faction *faction = world.getFaction(index); + netIntf->setNetworkPlayerFactionCRC(index, + faction->getCRC().getSum + ()); + + if (settings != NULL) { + if (isFlagType1BitEnabled + (ft1_network_synch_checks_verbose) == true) { + faction->addCRC_DetailsForWorldFrame(world.getFrameCount + (), + role == nrServer); + } else + if (isFlagType1BitEnabled + (ft1_network_synch_checks) == true + && world.getFrameCount() % 20 == 0) { + faction->addCRC_DetailsForWorldFrame(world.getFrameCount + (), + role == nrServer); + } + } + } else { + netIntf->setNetworkPlayerFactionCRC(index, 0); + } + } + } + } + } + } + + //update + void Game::update() { + try { + if (currentUIState != NULL) { + currentUIState->update(); + } + + bool + showPerfStats = + Config::getInstance().getBool("ShowPerfStats", "false"); + Chrono chronoPerf; + char perfBuf[8096] = ""; + std::vector < string > perfList; + if (showPerfStats) + chronoPerf.start(); + + if (showPerfStats) { + sprintf(perfBuf, + "=============== FRAME: %d In [%s::%s] Line: %d took msecs: " + MG_I64_SPECIFIER "\n", world.getFrameCount(), + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + Chrono chronoGamePerformanceCounts; + Chrono chrono; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled) + chrono.start(); + + // a) Updates non dependent on speed + + // set game stats for host + NetworkManager & networkManager = NetworkManager::getInstance(); + NetworkRole role = networkManager.getNetworkRole(); + if (role == nrServer) { + ServerInterface *server = + NetworkManager::getInstance().getServerInterface(false); + if (server != NULL) { + server->setGameStats(world.getStats()); + } + } + + bool + pendingQuitError = (quitPendingIndicator == true || + (NetworkManager:: + getInstance().getGameNetworkInterface() != + NULL + && NetworkManager:: + getInstance().getGameNetworkInterface()-> + getQuit())); + + if (pendingQuitError == true && + (this->masterserverMode == true || + (mainMessageBox.getEnabled() == false + && errorMessageBox.getEnabled() == false))) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + quitTriggeredIndicator = true; + return; + } + + if (this->masterserverMode == false) { + if (world.getFactionCount() > 0 + && world.getThisFaction()->getFirstSwitchTeamVote() != NULL) { + const SwitchTeamVote *vote = + world.getThisFaction()->getFirstSwitchTeamVote(); + GameSettings *settings = world.getGameSettingsPtr(); + + Lang & lang = Lang::getInstance(); + + char szBuf[8096] = ""; + if (lang.hasString("AllowPlayerJoinTeam") == true) { + snprintf(szBuf, 8096, + lang.getString("AllowPlayerJoinTeam").c_str(), + settings-> + getNetworkPlayerName(vote->factionIndex).c_str(), + vote->oldTeam, vote->newTeam); + } else { + snprintf(szBuf, 8096, + "Allow player [%s] to join your team\n(changing from team# %d to team# %d)?", + settings-> + getNetworkPlayerName(vote->factionIndex).c_str(), + vote->oldTeam, vote->newTeam); + } + + switchTeamConfirmMessageBox.setText(szBuf); + switchTeamConfirmMessageBox.init(lang.getString("Yes"), + lang.getString("No")); + switchTeamConfirmMessageBox.setEnabled(true); + + world. + getThisFactionPtr()->setCurrentSwitchTeamVoteFactionIndex + (vote->factionIndex); + } + } + + //misc + updateFps++; + mouse2d = (mouse2d + 1) % Renderer::maxMouse2dAnim; + + //console + console.update(); + + // b) Updates depandant on speed + int updateLoops = getUpdateLoops(); + + // Temp speed boost when player first joins an in progress game + if (this->initialResumeSpeedLoops == true) { + printf("Resume In Progress Game: %d\n", __LINE__); + + this->initialResumeSpeedLoops = false; + //updateLoops = 80; + } + + chronoGamePerformanceCounts.start(); + bool + enableServerControlledAI = + this->gameSettings.getEnableServerControlledAI(); + + if (role == nrClient && updateLoops == 1 + && world.getFrameCount() >= + (gameSettings.getNetworkFramePeriod() * 2)) { + ClientInterface *clientInterface = + dynamic_cast < + ClientInterface *>(networkManager.getClientInterface()); + if (clientInterface != NULL) { + uint64 + lastNetworkFrameFromServer = + clientInterface->getCachedLastPendingFrameCount(); + + ///////////////////////////////// + // TTTT new attempt to make things smoother: + /////////////// + + //////////////////////////////////////////// + //get stats of received/waiting for packages + //////////////////////////////////////////// + // calculate current receive Index slot: + int + index = ((world.getFrameCount() + - (world.getFrameCount() + % gameSettings.getNetworkFramePeriod())) + / gameSettings.getNetworkFramePeriod()) + % GameConstants::networkSmoothInterval; + + // clean the next frame slot + receivedTooEarlyInFrames[(index + + 1) % + GameConstants::networkSmoothInterval] = + -1; + framesNeededToWaitForServerMessage[(index + + 1) % + GameConstants::networkSmoothInterval] + = -1; + + if (receivedTooEarlyInFrames[index] == -1) { + // we need to check if we already received something for next frame + if (lastNetworkFrameFromServer > 0 + && lastNetworkFrameFromServer > + (uint64) world.getFrameCount()) { + receivedTooEarlyInFrames[index] = + lastNetworkFrameFromServer - world.getFrameCount(); + } + } + if (framesNeededToWaitForServerMessage[index] == -1) { + // calc time waiting for message in milliseconds to frames + int64 + timeClientWaitedForLastMessage = + clientInterface->getTimeClientWaitedForLastMessage(); + if (timeClientWaitedForLastMessage > 0) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("world.getFrameCount():%d index %d Client waited:%d ms\n", + world.getFrameCount(), index, + (int) timeClientWaitedForLastMessage); + framesNeededToWaitForServerMessage[index] = + timeClientWaitedForLastMessage * + GameConstants::updateFps / 1000; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("ClienttimeClientWaitedForLastMessage:%d ms which is %d frames \n", + (int) timeClientWaitedForLastMessage, + framesNeededToWaitForServerMessage[index]); + } else { + framesNeededToWaitForServerMessage[index] = 0; + } + } + + //////////////////////////////////////////// + //use the recorded stats of received/waiting for packages + //////////////////////////////////////////// + //lets see if the client is in front and had to wait for messages ... + + //lets see if all last recorded frames where received too early + int minimum = 0; + int allowedMaxFallback = 5; + int countOfMessagesReceivedTooEarly = 0; + int countOfMessagesReceivedTooLate = 0; + int sumOfTooLateFrames = 0; + bool cleanupStats = false; + + for (int i = 0; i < GameConstants::networkSmoothInterval; i++) { + if (receivedTooEarlyInFrames[i] > allowedMaxFallback) { + countOfMessagesReceivedTooEarly++; + if (minimum == 0 || minimum > receivedTooEarlyInFrames[i]) { + minimum = receivedTooEarlyInFrames[i]; + } + } + if (framesNeededToWaitForServerMessage[i] > 0) { + countOfMessagesReceivedTooLate++; + sumOfTooLateFrames += framesNeededToWaitForServerMessage[i]; + } + } + + if (countOfMessagesReceivedTooEarly == GameConstants::networkSmoothInterval - 1) // -1 because slot for next frame is already initialized + { // all packages where too early + // we catch up the minimum-catchupInterval of what we recorded + framesToCatchUpAsClient = minimum - allowedMaxFallback; + framesToSlowDownAsClient = 0; + cleanupStats = true; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("Worldframe %d : Client will speed up: %d frames\n", + world.getFrameCount(), framesToCatchUpAsClient); + } else if (countOfMessagesReceivedTooLate > 3) { + framesToSlowDownAsClient = + sumOfTooLateFrames / countOfMessagesReceivedTooLate; + framesToCatchUpAsClient = 0; + cleanupStats = true; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("Worldframe %d : Client will slow down: %d frames\n", + world.getFrameCount(), framesToSlowDownAsClient); + } + + if (cleanupStats == true) { + // Once we decided to use the stats to do some correction, we reset/cleanup our recorded stats + for (int i = 0; i < GameConstants::networkSmoothInterval; i++) { + receivedTooEarlyInFrames[i] = -1; + framesNeededToWaitForServerMessage[i] = -1; + } + } + } + } + // if game is paused don't try to catch up + if (updateLoops > 0) { + // we catch up a bit smoother with updateLoops = 2 + if (framesToCatchUpAsClient > 0) { + updateLoops = 2; + framesToCatchUpAsClient = framesToCatchUpAsClient - 1; + } + if (framesToSlowDownAsClient > 0) { // slowdown still the hard way. + updateLoops = 0; + framesToSlowDownAsClient = framesToSlowDownAsClient - 1; + } + } + + addPerformanceCount("CalculateNetworkUpdateLoops", + chronoGamePerformanceCounts.getMillis()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER + "\n", extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld [before ReplaceDisconnectedNetworkPlayersWithAI]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER + "\n", extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + // Check to see if we are playing a network game and if any players + // have disconnected? + bool isNetworkGame = this->gameSettings.isNetworkGame(); + + chronoGamePerformanceCounts.start(); + + ReplaceDisconnectedNetworkPlayersWithAI(isNetworkGame, role); + + addPerformanceCount("ReplaceDisconnectedNetworkPlayersWithAI", + chronoGamePerformanceCounts.getMillis()); + + setupPopupMenus(true); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld [after ReplaceDisconnectedNetworkPlayersWithAI]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER + "\n", extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (updateLoops > 0) { + // update the frame based timer in the stats with at least one step + world.getStats()->addFramesToCalculatePlaytime(); + + //update + Chrono chronoReplay; + int64 lastReplaySecond = -1; + int replayCommandsPlayed = 0; + int replayTotal = commander.getReplayCommandListForFrameCount(); + if (replayTotal > 0) { + chronoReplay.start(); + } + + do { + if (replayTotal > 0) { + replayCommandsPlayed = + (replayTotal - + commander.getReplayCommandListForFrameCount()); + } + for (int i = 0; i < updateLoops; ++i) { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " + MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + //AiInterface + if (commander.hasReplayCommandListForFrame() == false) { + chronoGamePerformanceCounts.start(); + + processNetworkSynchChecksIfRequired(); + + addPerformanceCount("CalculateNetworkCRCSynchChecks", + chronoGamePerformanceCounts.getMillis + ()); + + const bool + newThreadManager = + Config::getInstance().getBool("EnableNewThreadManager", + "false"); + if (newThreadManager == true) { + int currentFrameCount = world.getFrameCount(); + masterController.signalSlaves(¤tFrameCount); + //bool slavesCompleted = masterController.waitTillSlavesTrigger(20000); + masterController.waitTillSlavesTrigger(20000); + } else { + // Signal the faction threads to do any pre-processing + chronoGamePerformanceCounts.start(); + + bool hasAIPlayer = false; + for (int j = 0; j < world.getFactionCount(); ++j) { + Faction *faction = world.getFaction(j); + + //printf("Faction Index = %d enableServerControlledAI = %d, isNetworkGame = %d, role = %d isCPU player = %d scriptManager.getPlayerModifiers(j)->getAiEnabled() = %d\n",j,enableServerControlledAI,isNetworkGame,role,faction->getCpuControl(enableServerControlledAI,isNetworkGame,role),scriptManager.getPlayerModifiers(j)->getAiEnabled()); + + if (faction->getCpuControl(enableServerControlledAI, + isNetworkGame, + role) == true + && scriptManager. + getPlayerModifiers(j)->getAiEnabled() == true) { + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags:: + OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] [i = %d] faction = %d, factionCount = %d, took msecs: %lld [before AI updates]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, i, j, + world.getFactionCount(), + chrono.getMillis()); + aiInterfaces[j]->signalWorkerThread(world.getFrameCount + ()); + hasAIPlayer = true; + } + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " + MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (hasAIPlayer == true) { + //sleep(0); + + Chrono chronoAI; + chronoAI.start(); + + const int MAX_FACTION_THREAD_WAIT_MILLISECONDS = 20000; + for (; + chronoAI.getMillis() < + MAX_FACTION_THREAD_WAIT_MILLISECONDS;) { + bool workThreadsFinished = true; + for (int j = 0; j < world.getFactionCount(); ++j) { + Faction *faction = world.getFaction(j); + if (faction == NULL) { + throw megaglest_runtime_error("faction == NULL"); + } + if (faction->getCpuControl + (enableServerControlledAI, + isNetworkGame, role) == true + && + scriptManager.getPlayerModifiers(j)->getAiEnabled + () == true) { + if (aiInterfaces[j]->isWorkerThreadSignalCompleted + (world.getFrameCount()) == false) { + workThreadsFinished = false; + break; + } + } + } + if (workThreadsFinished == false) { + //sleep(0); + } else { + break; + } + } + } + + addPerformanceCount("ProcessAIWorkerThreads", + chronoGamePerformanceCounts.getMillis + ()); + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " + MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + } else { + // Simply show a progress message while replaying commands + if (lastReplaySecond < chronoReplay.getSeconds()) { + lastReplaySecond = chronoReplay.getSeconds(); + Renderer & renderer = Renderer::getInstance(); + renderer.clearBuffers(); + renderer.clearZBuffer(); + renderer.reset2d(); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Please wait, loading game with replay [%d / %d]...", + replayCommandsPlayed, replayTotal); + string text = szBuf; + if (Renderer::renderText3DEnabled) { + Font3D *font = + CoreData::getInstance().getMenuFontBig3D(); + const Metrics & metrics = Metrics::getInstance(); + int w = metrics.getVirtualW(); + int + renderX = + (w / 2) - + (font->getMetrics()->getTextWidth(text) / 2); + int h = metrics.getVirtualH(); + int + renderY = + (h / 2) + (font->getMetrics()->getHeight(text) / 2); + + renderer.renderText3D(text, font, + Vec3f(1.f, 1.f, 0.f), + renderX, renderY, false); + } else { + Font2D *font = CoreData::getInstance().getMenuFontBig(); + const Metrics & metrics = Metrics::getInstance(); + int w = metrics.getVirtualW(); + int renderX = (w / 2); + int h = metrics.getVirtualH(); + int renderY = (h / 2); + + renderer.renderText(text, font, + Vec3f(1.f, 1.f, 0.f), + renderX, renderY, true); + } + + renderer.swapBuffers(); + } + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " + MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld [AI updates]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //World + chronoGamePerformanceCounts.start(); + + if (pendingQuitError == false) + world.update(); + + addPerformanceCount("ProcessWorldUpdate", + chronoGamePerformanceCounts.getMillis()); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld [world update i = %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis(), i); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " + MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (currentCameraFollowUnit != NULL) { + Vec3f c = currentCameraFollowUnit->getCurrMidHeightVector(); + int rotation = currentCameraFollowUnit->getRotation(); + float angle = rotation + 180; + + c.z = c.z + 4 * std::cos(degToRad(angle)); + c.x = c.x + 4 * std::sin(degToRad(angle)); + + c.y = + c.y + + currentCameraFollowUnit->getType()->getHeight() / + 2.f + 2.0f; + + getGameCameraPtr()->setPos(c); + + rotation = (540 - rotation) % 360; + getGameCameraPtr()->rotateToVH(18.0f, rotation); + + if (currentCameraFollowUnit->isAlive() == false) { + currentCameraFollowUnit = NULL; + getGameCameraPtr()->setState(GameCamera::sGame); + } + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " + MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + // Commander + chronoGamePerformanceCounts.start(); + + if (pendingQuitError == false) { + commander.signalNetworkUpdate(this); + } + + addPerformanceCount("ProcessNetworkUpdate", + chronoGamePerformanceCounts.getMillis()); + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " + MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld [commander updateNetwork i = %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis(), i); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //Gui + chronoGamePerformanceCounts.start(); + + gui.update(); + + addPerformanceCount("ProcessGUIUpdate", + chronoGamePerformanceCounts.getMillis()); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld [gui updating i = %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis(), i); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " + MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + //Particle systems + if (weatherParticleSystem != NULL) { + weatherParticleSystem->setPos(gameCamera.getPos()); + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld [weather particle updating i = %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis(), i); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " + MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + Renderer & renderer = Renderer::getInstance(); + + chronoGamePerformanceCounts.start(); + + renderer.updateParticleManager(rsGame, avgRenderFps); + + addPerformanceCount("ProcessParticleManager", + chronoGamePerformanceCounts.getMillis()); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld [particle manager updating i = %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis(), i); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " + MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + //good_fpu_control_registers(NULL,extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + } + } while (commander.hasReplayCommandListForFrame() == true); + } + //else if(role == nrClient) { + else { + if (pendingQuitError == false) { + commander.signalNetworkUpdate(this); + } + + if (playingStaticVideo == true) { + if (videoPlayer->isPlaying() == false) { + playingStaticVideo = false; + tryPauseToggle(false); + } + } + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER + "\n", extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + chronoGamePerformanceCounts.start(); + + //call the chat manager + chatManager.updateNetwork(); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld [chatManager.updateNetwork]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER + "\n", extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + updateNetworkMarkedCells(); + updateNetworkUnMarkedCells(); + updateNetworkHighligtedCells(); + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER + "\n", extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + //check for quiting status + if (NetworkManager::getInstance().getGameNetworkInterface() != NULL + && NetworkManager::getInstance(). + getGameNetworkInterface()->getQuit() + && mainMessageBox.getEnabled() == false + && errorMessageBox.getEnabled() == false) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + quitTriggeredIndicator = true; + return; + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER + "\n", extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + addPerformanceCount("ProcessMiscNetwork", + chronoGamePerformanceCounts.getMillis()); + + // START - Handle joining in progress games + if (role == nrServer) { + + if (this->networkPauseGameForLaggedClientsRequested == true) { + this->networkPauseGameForLaggedClientsRequested = false; + + if (getPaused() == false) { + + printf + ("[CMDR] Pausing game for lagging client(s), current world frame [%d]\n", + world.getFrameCount()); + commander.tryPauseGame(false, false); + } + } else if (this->networkResumeGameForLaggedClientsRequested == true) { + this->networkResumeGameForLaggedClientsRequested = false; + + if (getPaused() == true) { + + printf + ("[CMDR] Resuming game after Pause for lagging client(s), current world frame [%d]\n", + world.getFrameCount()); + commander.tryResumeGame(false, false); + } + } + + ServerInterface *server = + NetworkManager::getInstance().getServerInterface(); + if (server->getPauseForInGameConnection() == true) { + + bool clientNeedsGameSetup = false; + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + + MutexSafeWrapper + safeMutex(server->getSlotMutex + (faction->getStartLocationIndex()), CODE_AT_LINE); + ConnectionSlot *slot = + server->getSlot(faction->getStartLocationIndex(), + false); + if (slot != NULL + && slot->getPauseForInGameConnection() == true) { + clientNeedsGameSetup = true; + break; + } + } + + if (pausedForJoinGame == false || clientNeedsGameSetup == true) { + //printf("================= Switching player pausing game\n"); + + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + + //printf("Switching player check %d from: %d connected: %d, startindex = %d, connected #2: %d\n",i,faction->getControlType(),server->isClientConnected(faction->getStartLocationIndex()),faction->getStartLocationIndex(),server->isClientConnected(i)); + //printf("Slot: %d faction name: %s\n",i,faction->getType()->getName().c_str()); + + if (faction->getControlType() != ctNetwork && + faction->getControlType() != ctHuman && + server->isClientConnected(faction->getStartLocationIndex + ()) == true) { + + //printf("Switching player %d from: %d to %d\n",i,faction->getControlType(),ctNetwork); + //printf("Slot: %d faction name: %s GS faction: %s\n",i,faction->getType()->getName().c_str(),server->gameSettings.getFactionTypeName(i).c_str()); + + server->gameSettings.setFactionControl(i, ctNetwork); + + MutexSafeWrapper + safeMutex(server->getSlotMutex + (faction->getStartLocationIndex()), + CODE_AT_LINE); + ConnectionSlot *slot = + server->getSlot(faction->getStartLocationIndex(), + false); + server->gameSettings.setNetworkPlayerName(i, + slot->getName + ()); + server->gameSettings.setNetworkPlayerUUID(i, + slot->getUUID + ()); + server->gameSettings.setNetworkPlayerPlatform(i, + slot->getPlatform + ()); + safeMutex.ReleaseLock(); + server->gameSettings.setNetworkPlayerStatuses(i, + npst_None); + + this->gameSettings.setFactionControl(i, ctNetwork); + this->gameSettings.setNetworkPlayerName(i, + server->gameSettings.getNetworkPlayerName + (i)); + this->gameSettings.setNetworkPlayerUUID(i, + server->gameSettings.getNetworkPlayerUUID + (i)); + this->gameSettings.setNetworkPlayerPlatform(i, + server->gameSettings.getNetworkPlayerPlatform + (i)); + this->gameSettings.setNetworkPlayerStatuses(i, npst_None); + } + } + //printf("#1 Data synch: lmap %u ltile: %d ltech: %u\n",gameSettings.getMapCRC(),gameSettings.getTilesetCRC(),gameSettings.getTechCRC()); + //printf("#2 Data synch: lmap %u ltile: %d ltech: %u\n",server->gameSettings.getMapCRC(),server->gameSettings.getTilesetCRC(),server->gameSettings.getTechCRC()); + server->broadcastGameSetup(&server->gameSettings, true); + } + + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + MutexSafeWrapper + safeMutex(server->getSlotMutex + (faction->getStartLocationIndex()), CODE_AT_LINE); + ConnectionSlot *slot = + server->getSlot(faction->getStartLocationIndex(), + false); + if (slot != NULL + && slot->getPauseForInGameConnection() == true) { + slot->setPauseForInGameConnection(false); + } + } + } else if (server->getStartInGameConnectionLaunch() == true) { + //printf("^^^ getStartInGameConnectionLaunch triggered!\n"); + + //server->setStartInGameConnectionLaunch(false); + + //this->speed = 1; + + //Lang &lang= Lang::getInstance(); + bool pauseAndSaveGameForNewClient = false; + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + + MutexSafeWrapper + safeMutex(server->getSlotMutex + (faction->getStartLocationIndex()), CODE_AT_LINE); + ConnectionSlot *slot = + server->getSlot(faction->getStartLocationIndex(), + false); + + if (slot != NULL + && slot->getStartInGameConnectionLaunch() == true) { + //slot->setStartInGameConnectionLaunch(false); + pauseAndSaveGameForNewClient = true; + } + if (slot != NULL && slot->getJoinGameInProgress() == true) { + //printf("$$$ signalling client to start game [deleting AI player] factionIndex: %d slot: %d startlocation: %d!\n",i,slot->getPlayerIndex(),faction->getStartLocationIndex()); + safeMutex.ReleaseLock(); + + this->gameSettings.setFactionControl(i, ctNetwork); + this->gameSettings.setNetworkPlayerName(i, + server->gameSettings.getNetworkPlayerName + (i)); + this->gameSettings.setNetworkPlayerUUID(i, + server->gameSettings.getNetworkPlayerUUID + (i)); + this->gameSettings.setNetworkPlayerPlatform(i, + server->gameSettings.getNetworkPlayerPlatform + (i)); + + if (this->gameSettings.getNetworkPlayerStatuses(i) == + npst_Disconnected) { + this->gameSettings.setNetworkPlayerStatuses(i, npst_None); + } + + //printf("START Purging AI player for index: %d\n",i); + masterController.clearSlaves(true); + delete aiInterfaces[i]; + aiInterfaces[i] = NULL; + //printf("END Purging AI player for index: %d\n",i); + + Faction *faction = world.getFaction(i); + faction->setControlType(ctNetwork); + //pauseAndSaveGameForNewClient = true; + } else if ((slot == NULL || slot->isConnected() == false) + && this->gameSettings.getFactionControl(i) == + ctNetwork && aiInterfaces[i] == NULL) { + + safeMutex.ReleaseLock(); + faction->setFactionDisconnectHandled(false); + //this->gameSettings.setNetworkPlayerName(i,lang.getString("AI") + intToStr(i+1)); + //server->gameSettings.setNetworkPlayerName(i,lang.getString("AI") + intToStr(i+1)); + } else { + safeMutex.ReleaseLock(); + } + } + + if (pauseAndSaveGameForNewClient == true + && pausedForJoinGame == false && pauseRequestSent == false) { + //printf("Pausing game for join in progress game...\n"); + + commander.tryPauseGame(true, true); + pauseRequestSent = true; + return; + } + } + //else if(server->getPauseForInGameConnection() == true && paused == true && + if (pausedForJoinGame == true) { + if (pauseStateChanged == true) { + pauseStateChanged = false; + } + + if (server->getUnPauseForInGameConnection() == true) { + //printf("^^^ getUnPauseForInGameConnection triggered!\n"); + + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + + MutexSafeWrapper + safeMutex(server->getSlotMutex + (faction->getStartLocationIndex()), + CODE_AT_LINE); + ConnectionSlot *slot = + server->getSlot(faction->getStartLocationIndex(), + false); + if (slot != NULL + && slot->getUnPauseForInGameConnection() == true) { + slot->setUnPauseForInGameConnection(false); + faction->setFactionDisconnectHandled(false); + } + } + //printf("Resuming game for join in progress game resumeRequestSent: %d...\n",resumeRequestSent); + + if (pausedBeforeJoinGame == false && resumeRequestSent == false) { + commander.tryResumeGame(true, true); + resumeRequestSent = true; + } + } else if (server->getStartInGameConnectionLaunch() == true) { + bool saveNetworkGame = false; + + ServerInterface *server = + NetworkManager::getInstance().getServerInterface(); + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + + MutexSafeWrapper + safeMutex(server->getSlotMutex + (faction->getStartLocationIndex()), + CODE_AT_LINE); + ConnectionSlot *slot = + server->getSlot(faction->getStartLocationIndex(), + false); + if (slot != NULL + && slot->getJoinGameInProgress() == true + && slot->getStartInGameConnectionLaunch() == true + && slot->getSentSavedGameInfo() == false) { + slot->setStartInGameConnectionLaunch(false); + + saveNetworkGame = true; + break; + } + } + + if (saveNetworkGame == true) { + //printf("Saved network game to disk\n"); + + string + file = + this->saveGame(GameConstants::saveNetworkGameFileServer, + "temp/"); + + string saveGameFilePath = "temp/"; + string + saveGameFileCompressed = + saveGameFilePath + + string(GameConstants::saveNetworkGameFileServerCompressed); + if (getGameReadWritePath + (GameConstants::path_logs_CacheLookupKey) != "") { + saveGameFilePath = + getGameReadWritePath + (GameConstants::path_logs_CacheLookupKey) + + saveGameFilePath; + saveGameFileCompressed = + saveGameFilePath + + string + (GameConstants::saveNetworkGameFileServerCompressed); + } else { + string + userData = + Config::getInstance().getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + saveGameFilePath = userData + saveGameFilePath; + saveGameFileCompressed = + saveGameFilePath + + string + (GameConstants::saveNetworkGameFileServerCompressed); + } + + bool + compressed_result = + compressFileToZIPFile(file, saveGameFileCompressed); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("Saved game [%s] compressed to [%s] returned: %d\n", + file.c_str(), saveGameFileCompressed.c_str(), + compressed_result); + + char szBuf[8096] = ""; + Lang & lang = Lang::getInstance(); + snprintf(szBuf, 8096, + lang.getString("GameSaved", "", + true).c_str(), file.c_str()); + console.addLine(szBuf); + + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + + MutexSafeWrapper + safeMutex(server->getSlotMutex + (faction->getStartLocationIndex()), + CODE_AT_LINE); + ConnectionSlot *slot = + server->getSlot(faction->getStartLocationIndex(), + false); + if (slot != NULL + && slot->getJoinGameInProgress() == true + && slot->getSentSavedGameInfo() == false) { + + safeMutex.ReleaseLock(); + NetworkMessageReady networkMessageReady(0); + slot->sendMessage(&networkMessageReady); + + slot = + server->getSlot(faction->getStartLocationIndex(), + false); + if (slot != NULL) { + slot->setSentSavedGameInfo(true); + } + } + } + } + } + } + //else { + // handle setting changes from clients + Map *map = world.getMap(); + //printf("switchSetupRequests != NULL\n"); + + bool + switchRequested = + switchSetupForSlots(server, 0, map->getMaxPlayers(), false); + switchRequested = switchRequested + || switchSetupForSlots(server, map->getMaxPlayers(), + GameConstants::maxPlayers, true); + + if (switchRequested == true) { + //printf("Send new game setup from switch: %d\n",switchRequested); + + //for(int i= 0; i < gameSettings.getFactionCount(); ++i) { + //printf("#1 Faction Index: %d control: %d startlocation: %d\n",i,gameSettings.getFactionControl(i),gameSettings.getStartLocationIndex(i)); + + //printf("#2 Faction Index: %d control: %d startlocation: %d\n",i,server->gameSettings.getFactionControl(i),server->gameSettings.getStartLocationIndex(i)); + //} + + server->broadcastGameSetup(&server->gameSettings, true); + } + //} + + // Make the server wait a bit for clients to start. + if (pausedForJoinGame == false && resumeRequestSent == true) { + resumeRequestSent = false; + //sleep(500); + } + } + // END - Handle joining in progress games + + //update auto test + if (Config::getInstance().getBool("AutoTest")) { + AutoTest::getInstance().updateGame(this); + return; + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER + "\n", extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (world.getQueuedScenario() != "") { + string name = world.getQueuedScenario(); + bool keepFactions = world.getQueuedScenarioKeepFactions(); + world.setQueuedScenario("", false); + + //vector results; + const + vector < + string > & + dirList = Config::getInstance().getPathListForType(ptScenarios); + string scenarioFile = Scenario::getScenarioPath(dirList, name); + + + try { + gameStarted = false; + + //printf("\nname [%s] scenarioFile [%s] results.size() = " MG_SIZE_T_SPECIFIER "\n",name.c_str(),scenarioFile.c_str(),results.size()); + //printf("[%s:%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + bool isTutorial = Scenario::isGameTutorial(scenarioFile); + ScenarioInfo scenarioInfo; + Scenario::loadScenarioInfo(scenarioFile, &scenarioInfo, + isTutorial); + + //printf("[%s:%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + GameSettings gameSettings; + Scenario::loadGameSettings(dirList, &scenarioInfo, + &gameSettings, scenarioFile); + + //Program *program = world->getGame()->getProgram(); + //program->setState(new Game(program, &gameSettings, false)); + + //world->end(); + + //world->getMapPtr()->end(); + //world.end(); + + if (keepFactions == false) { + world.end(); + + world.cleanup(); + world.clearTileset(); + + SoundRenderer::getInstance().stopAllSounds(); + + masterController.clearSlaves(true); + deleteValues(aiInterfaces.begin(), aiInterfaces.end()); + aiInterfaces.clear(); + gui.end(); //selection must be cleared before deleting units + world.end(); //must die before selection because of referencers + + BaseColorPickEntity::resetUniqueColors(); + // MUST DO THIS LAST!!!! Because objects above have pointers to things like + // unit particles and fade them out etc and this end method deletes the original + // object pointers. + Renderer & renderer = Renderer::getInstance(); + renderer.endGame(true); + + GameConstants::updateFps = original_updateFps; + GameConstants::cameraFps = original_cameraFps; + + this->setGameSettings(&gameSettings); + this->resetMembers(); + this->load(); + this->init(); + } else { + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); + if (currentAmbientSound) { + soundRenderer.stopAmbient(currentAmbientSound); + } + //soundRenderer.stopAllSounds(); + soundRenderer.stopAllSounds(fadeMusicMilliseconds); + + world.endScenario(); + BaseColorPickEntity::resetUniqueColors(); + + Renderer & renderer = Renderer::getInstance(); + renderer.endScenario(); + world.clearTileset(); + this->setGameSettings(&gameSettings); + this->load(lgt_FactionPreview | lgt_TileSet | lgt_Map | + lgt_Scenario); + try { + world.init(this, gameSettings.getDefaultUnits(), false); + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d]\nError [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + if (errorMessageBox.getEnabled() == false) { + ErrorDisplayMessage(ex.what(), true); + } + } + + world.initUnitsForScenario(); + Map *map = world.getMap(); + gameCamera.init(map->getW(), map->getH()); + + // camera default height calculation + if (map->getCameraHeight() > 0 + && gameCamera.getCalculatedDefault() < + map->getCameraHeight()) { + gameCamera.setCalculatedDefault(map->getCameraHeight()); + } else if (gameCamera.getCalculatedDefault() < + map->getMaxMapHeight() + 13.0f) { + gameCamera.setCalculatedDefault(map->getMaxMapHeight() + + 13.0f); + } + + scriptManager.init(&world, &gameCamera, loadGameNode); + renderer.initGame(this, this->getGameCameraPtr()); + + //sounds + //soundRenderer.stopAllSounds(fadeMusicMilliseconds); + //soundRenderer.stopAllSounds(); + //soundRenderer= SoundRenderer::getInstance(); + + Tileset *tileset = world.getTileset(); + AmbientSounds *ambientSounds = tileset->getAmbientSounds(); + + //rain + if (tileset->getWeather() == wRainy + && ambientSounds->isEnabledRain()) { + //logger.add("Starting ambient stream", true); + currentAmbientSound = ambientSounds->getRain(); + //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); + soundRenderer.playAmbient(currentAmbientSound); + } + + //snow + if (tileset->getWeather() == wSnowy + && ambientSounds->isEnabledSnow()) { + //logger.add("Starting ambient stream", true); + currentAmbientSound = ambientSounds->getSnow(); + //printf("In [%s:%s] Line: %d currentAmbientSound = [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentAmbientSound); + soundRenderer.playAmbient(currentAmbientSound); + } + + if (this->masterserverMode == false) { + StrSound *gameMusic = + world.getThisFaction()->getType()->getMusic(); + soundRenderer.playMusic(gameMusic); + } + + gameStarted = true; + } + //this->init(); + + //printf("[%s:%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + //Checksum checksum; + //world->loadScenario(scenarioFile, &checksum, true); + } #if defined(WIN32) - catch (const exception) - { + catch (const exception) { #else - catch (const exception & ex) - { + catch (const exception & ex) { #endif - gameStarted = true; - totalRenderFps++; - - throw; - } - } - - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER - "\n", extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } - - if (showPerfStats && chronoPerf.getMillis () >= 50) - { - for (unsigned int x = 0; x < (unsigned int) perfList.size (); ++x) - { - printf ("%s", perfList[x].c_str ()); - } - } - } - catch (const exception & ex) - { - quitPendingIndicator = true; - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); - - //printf("#100 quitPendingIndicator = %d, errorMessageBox.getEnabled() = %d\n",quitPendingIndicator,errorMessageBox.getEnabled()); - - NetworkManager & networkManager = NetworkManager::getInstance (); - if (networkManager.getGameNetworkInterface () != NULL) - { - GameNetworkInterface *networkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - networkInterface->sendTextMessage (szBuf, -1, true, ""); - sleep (10); - networkManager.getGameNetworkInterface ()->quitGame (true); - } - if (errorMessageBox.getEnabled () == false) - { - ErrorDisplayMessage (ex.what (), true); - } - } - } - - void Game::addPerformanceCount (string key, int64 value) - { - gamePerformanceCounts[key] = value + gamePerformanceCounts[key] / 2; - } - - string Game::getGamePerformanceCounts (bool displayWarnings) const - { - if (gamePerformanceCounts.empty () == true) - { - return ""; - } - - bool displayWarningHeader = true; - bool - WARN_TO_CONSOLE = - Config::getInstance ().getBool ("PerformanceWarningEnabled", "false"); - int - WARNING_MILLIS = - Config::getInstance ().getInt ("PerformanceWarningMillis", "7"); - int - WARNING_RENDER_MILLIS = - Config::getInstance ().getInt ("PerformanceWarningRenderMillis", - "40"); - - string result = ""; - for (std::map < string, int64 >::const_iterator iterMap = - gamePerformanceCounts.begin (); - iterMap != gamePerformanceCounts.end (); ++iterMap) - { - if (iterMap->first == ProgramState::MAIN_PROGRAM_RENDER_KEY) - { - if (iterMap->second < WARNING_RENDER_MILLIS) - { - continue; - } - //else { - // printf("iterMap->second: " MG_I64_SPECIFIER " WARNING_RENDER_MILLIS = %d\n",iterMap->second,WARNING_RENDER_MILLIS); - //} - } - else if (iterMap->second < WARNING_MILLIS) - { - continue; - } - - if (result != "") - { - result += "\n"; - } - string - perfStat = - iterMap->first + " = avg millis: " + intToStr (iterMap->second); - - if (displayWarnings == true && WARN_TO_CONSOLE == true) - { - if (displayWarningHeader == true) - { - displayWarningHeader = false; - printf - ("=====================================\nPERFORMANCE WARNINGS for World Frame: %d\n", - world.getFrameCount ()); - } - - printf ("*PERFORMANCE WARNING* %s\n", perfStat.c_str ()); - } - - result += perfStat; - } - - return result; - } - - bool - Game::switchSetupForSlots (ServerInterface * &serverInterface, - int startIndex, int endIndex, - bool onlyNetworkUnassigned) - { - bool switchRequested = false; - if (serverInterface == NULL) - { - return switchRequested; - } - - MutexSafeWrapper - safeMutex (serverInterface->getSwitchSetupRequestsMutex (), - CODE_AT_LINE); - SwitchSetupRequest **switchSetupRequests = - serverInterface->getSwitchSetupRequests (); - if (switchSetupRequests == NULL) - { - return switchRequested; - } - - Map *map = world.getMap (); - for (int i = startIndex; i < endIndex; ++i) - { - if (switchSetupRequests[i] != NULL) - { - //printf("Faction Index: %d Switch slot = %d to = %d current control = %d\n",i,switchSetupRequests[i]->getCurrentSlotIndex(),switchSetupRequests[i]->getToSlotIndex(),gameSettings.getFactionControl(i)); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] switchSetupRequests[i]->getSwitchFlags() = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - switchSetupRequests[i]->getSwitchFlags - ()); - - if (onlyNetworkUnassigned == true - && gameSettings.getFactionControl (i) != ctNetworkUnassigned) - { - if (i < map->getMaxPlayers () - || (i >= map->getMaxPlayers () - && gameSettings.getFactionControl (i) != ctNetwork)) - { - continue; - } - } - - if (gameSettings.getFactionControl (i) == ctNetwork || - gameSettings.getFactionControl (i) == ctNetworkUnassigned || - //(gameSettings.getFactionControl(i) != ctClosed && gameSettings.getFactionControl(i) != ctHuman)) { - (gameSettings.getFactionControl (i) != ctHuman)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] switchSetupRequests[i]->getToFactionIndex() = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, - switchSetupRequests[i]->getToSlotIndex - ()); - - if (switchSetupRequests[i]->getToSlotIndex () != -1) - { - int newSlotIdx = switchSetupRequests[i]->getToSlotIndex (); - - //printf("switchSlot request from %d to %d\n",switchSetupRequests[i]->getCurrentSlotIndex(),switchSetupRequests[i]->getToSlotIndex()); - - int - switchSlotIdx = - switchSetupRequests[i]->getCurrentSlotIndex (); - if (serverInterface->switchSlot (switchSlotIdx, newSlotIdx)) - { - //printf("switchSlot returned true\n"); - switchRequested = true; - - int - oldFactionIndex = - gameSettings.getFactionIndexForStartLocation - (switchSlotIdx); - int newFactionIndex = - gameSettings.getFactionIndexForStartLocation (newSlotIdx); - - //printf("Switching faction for index %d [%d] to %d\n",newSlotIdx,switchSlotIdx,gameSettings.getFactionControl(newFactionIndex)); - - gameSettings.setNetworkPlayerName (oldFactionIndex, ""); - serverInterface-> - gameSettings.setNetworkPlayerName (oldFactionIndex, ""); - gameSettings.setNetworkPlayerUUID (oldFactionIndex, ""); - serverInterface-> - gameSettings.setNetworkPlayerUUID (oldFactionIndex, ""); - - gameSettings.setNetworkPlayerPlatform (oldFactionIndex, ""); - serverInterface-> - gameSettings.setNetworkPlayerPlatform (oldFactionIndex, ""); - - gameSettings.setFactionControl (newFactionIndex, ctNetwork); - serverInterface-> - gameSettings.setFactionControl (newFactionIndex, ctNetwork); - - //printf("#1a Faction Index: %d control: %d startlocation: %d\n",newFactionIndex,gameSettings.getFactionControl(newFactionIndex),gameSettings.getStartLocationIndex(newFactionIndex)); - //printf("#2a Faction Index: %d control: %d startlocation: %d\n",newFactionIndex,serverInterface->gameSettings.getFactionControl(newFactionIndex),serverInterface->gameSettings.getStartLocationIndex(newFactionIndex)); - - try - { - //if(switchSetupRequests[i]->getSelectedFactionName() != "") { - // listBoxFactions[newFactionIdx].setSelectedItem(switchSetupRequests[i]->getSelectedFactionName()); - //} - //if(switchSetupRequests[i]->getToTeam() != -1) { - // listBoxTeams[newFactionIdx].setSelectedItemIndex(switchSetupRequests[i]->getToTeam()); - //} - if (switchSetupRequests[i]->getNetworkPlayerName () != "") - { - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] i = %d, labelPlayerNames[newFactionIdx].getText() [%s] switchSetupRequests[i]->getNetworkPlayerName() [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,labelPlayerNames[newFactionIdx].getText().c_str(),switchSetupRequests[i]->getNetworkPlayerName().c_str()); - gameSettings.setNetworkPlayerName (newFactionIndex, - switchSetupRequests - [i]->getNetworkPlayerName - ()); - serverInterface-> - gameSettings.setNetworkPlayerName (newFactionIndex, - switchSetupRequests - [i]->getNetworkPlayerName - ()); - } - -// if(gameSettings.getFactionControl(switchFactionIdx) == ctNetworkUnassigned) { -// serverInterface->removeSlot(switchFactionIdx); -// //listBoxControls[switchFactionIdx].setSelectedItemIndex(ctClosed); -// gameSettings.getFactionControl(switchFactionIdx) -// -// labelPlayers[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players); -// labelPlayerNames[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players); -// listBoxControls[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players); -// listBoxFactions[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players); -// listBoxTeams[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players); -// labelNetStatus[switchSlotIdx].setVisible(switchSlotIdx+1 <= mapInfo.players); -// } - } - catch (const runtime_error & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - e.what ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] caught exception error = [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - e.what ()); - } - } - //printf("AFTER switchSlot returned\n"); - } - else - { - try - { - //if(switchSetupRequests[i]->getSelectedFactionName() != "") { - // listBoxFactions[i].setSelectedItem(switchSetupRequests[i]->getSelectedFactionName()); - //} - //if(switchSetupRequests[i]->getToTeam() != -1) { - // listBoxTeams[i].setSelectedItemIndex(switchSetupRequests[i]->getToTeam()); - //} - - if ((switchSetupRequests[i]->getSwitchFlags () & - ssrft_NetworkPlayerName) == ssrft_NetworkPlayerName) - { - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, switchSetupRequests[i]->getSwitchFlags() = %d, switchSetupRequests[i]->getNetworkPlayerName() [%s], labelPlayerNames[i].getText() [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,switchSetupRequests[i]->getSwitchFlags(),switchSetupRequests[i]->getNetworkPlayerName().c_str(),labelPlayerNames[i].getText().c_str()); - - if (switchSetupRequests[i]->getNetworkPlayerName () != - GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) - { - //labelPlayerNames[i].setText(switchSetupRequests[i]->getNetworkPlayerName()); - gameSettings.setNetworkPlayerName (i, - switchSetupRequests - [i]->getNetworkPlayerName - ()); - serverInterface->gameSettings.setNetworkPlayerName (i, - switchSetupRequests - [i]->getNetworkPlayerName - ()); - switchRequested = true; - } - else - { - //labelPlayerNames[i].setText(""); - gameSettings.setNetworkPlayerName (i, ""); - serverInterface->gameSettings.setNetworkPlayerName (i, - ""); - switchRequested = true; - } - //SetActivePlayerNameEditor(); - //switchSetupRequests[i]->clearSwitchFlag(ssrft_NetworkPlayerName); - } - } - catch (const runtime_error & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, e.what ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] caught exception error = [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, e.what ()); - } - } - } - - delete switchSetupRequests[i]; - switchSetupRequests[i] = NULL; - } - } - - return switchRequested; - } - - void Game::updateNetworkMarkedCells () - { - try - { - GameNetworkInterface *gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - - if (gameNetworkInterface != NULL && - gameNetworkInterface->getMarkedCellList (false).empty () == false) - { - - std::vector < MarkedCell > chatList = - gameNetworkInterface->getMarkedCellList (true); - for (int idx = 0; idx < (int) chatList.size (); idx++) - { - MarkedCell mc = chatList[idx]; - if (mc.getFactionIndex () >= 0) - { - mc. - setFaction ((const Faction *) - world.getFaction (mc.getFactionIndex ())); - } - - Map *map = world.getMap (); - Vec2i surfaceCellPos = map->toSurfCoords (mc.getTargetPos ()); - mapMarkedCellList[surfaceCellPos] = mc; - } - } - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw megaglest_runtime_error (szBuf); - } - } - - void Game::updateNetworkUnMarkedCells () - { - try - { - GameNetworkInterface *gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - - if (gameNetworkInterface != NULL && - gameNetworkInterface->getUnMarkedCellList (false).empty () == - false) - { - //Lang &lang= Lang::getInstance(); - - std::vector < UnMarkedCell > chatList = - gameNetworkInterface->getUnMarkedCellList (true); - for (int idx = 0; idx < (int) chatList.size (); idx++) - { - UnMarkedCell mc = chatList[idx]; - mc. - setFaction ((const Faction *) - world.getFaction (mc.getFactionIndex ())); - - Map *map = world.getMap (); - Vec2i surfaceCellPos = map->toSurfCoords (mc.getTargetPos ()); - mapMarkedCellList.erase (surfaceCellPos); - } - } - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw megaglest_runtime_error (szBuf); - } - } - - - void Game::updateNetworkHighligtedCells () - { - try - { - GameNetworkInterface *gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - - //update the current entries - for (int idx = (int)highlightedCells.size () - 1; idx >= 0; idx--) - { - MarkedCell *mc = &highlightedCells[idx]; - mc->decrementAliveCount (); - if (mc->getAliveCount () < 0) - { - highlightedCells.erase (highlightedCells.begin () + idx); - } - } - - if (gameNetworkInterface != NULL && - gameNetworkInterface->getHighlightedCellList (false).empty () == - false) - { - //Lang &lang= Lang::getInstance(); - std::vector < MarkedCell > highlighList = - gameNetworkInterface->getHighlightedCellList (true); - for (int idx = 0; idx < (int) highlighList.size (); idx++) - { - MarkedCell mc = highlighList[idx]; // I want a copy here - if (mc.getFactionIndex () >= 0) - { - mc.setFaction ((const Faction *) world.getFaction (mc.getFactionIndex ())); // set faction pointer - } - addOrReplaceInHighlightedCells (mc); - } - } - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw megaglest_runtime_error (szBuf); - } - } - - void Game::addOrReplaceInHighlightedCells (MarkedCell mc) - { - if (mc.getFactionIndex () >= 0) - { - for (int i = (int)highlightedCells.size () - 1; i >= 0; i--) - { - MarkedCell *currentMc = &highlightedCells[i]; - if (currentMc->getFactionIndex () == mc.getFactionIndex ()) - { - highlightedCells.erase (highlightedCells.begin () + i); - } - } - } - if (mc.getAliveCount () <= 0) - { - mc.setAliveCount (200); - } - highlightedCells.push_back (mc); - - if (this->masterserverMode == false) - { - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - - const Faction *faction = mc.getFaction (); - if (getWorld ()->getThisFaction () == NULL) - { - throw - megaglest_runtime_error ("getWorld()->getThisFaction() == NULL"); - } - //printf("faction [%p][%s]\n",faction,(faction != NULL ? faction->getType()->getName().c_str() : "")); - if ((faction == NULL) || - (faction->getTeam () == - getWorld ()->getThisFaction ()->getTeam ())) - { - static PlaySoundClip snd; - soundRenderer.playFx (snd.getSound (snd.sfxMarker), true); - } - } - } - - void - Game::ReplaceDisconnectedNetworkPlayersWithAI (bool isNetworkGame, - NetworkRole role) - { - if (role == nrServer && isNetworkGame == true && - difftime ((long int) time (NULL), - lastNetworkPlayerConnectionCheck) >= - NETWORK_PLAYER_CONNECTION_CHECK_SECONDS) - { - lastNetworkPlayerConnectionCheck = time (NULL); - Logger & logger = Logger::getInstance (); - ServerInterface *server = - NetworkManager::getInstance ().getServerInterface (); - - bool newAIPlayerCreated = false; - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - if (faction->getFactionDisconnectHandled () == false && - (faction->getControlType () == ctNetwork || - faction->getControlType () == ctNetworkCpuEasy || - faction->getControlType () == ctNetworkCpu || - faction->getControlType () == ctNetworkCpuUltra || - faction->getControlType () == ctNetworkCpuZeta)) - { - - if (aiInterfaces[i] == NULL && - server-> - isClientConnected (faction->getStartLocationIndex ()) == - false) - { - - if (faction->getPersonalityType () != fpt_Observer) - { - DumpCRCWorldLogIfRequired ("_faction_" + intToStr (i)); - } - - faction->setFactionDisconnectHandled (true); - - Lang & lang = Lang::getInstance (); - - bool isPlayerObserver = false; - char szBuf[8096] = ""; - if (faction->getPersonalityType () != fpt_Observer) - { - aiInterfaces[i] = - new AiInterface (*this, i, faction->getTeam (), - faction->getStartLocationIndex ()); - - snprintf (szBuf, 8096, - Lang::getInstance ().getString - ("LogScreenGameLoadingCreatingAIFaction", - "", true).c_str (), i); - logger.add (szBuf, true); - - commander.tryNetworkPlayerDisconnected (i); - - newAIPlayerCreated = true; - } - else - { - isPlayerObserver = true; - - } - - const - vector < - string > - languageList = - this->gameSettings.getUniqueNetworkPlayerLanguages (); - for (unsigned int j = 0; - j < (unsigned int) languageList.size (); ++j) - { - if (isPlayerObserver == false) - { - string - msg = - "Player #%d [%s] has disconnected, switching player to AI mode!"; - if (lang.hasString ("GameSwitchPlayerToAI", - languageList[j], true)) - { - msg = - lang.getString ("GameSwitchPlayerToAI", - languageList[j], true); - } - snprintf (szBuf, 8096, msg.c_str (), i + 1, - this->gameSettings.getNetworkPlayerName (i). - c_str ()); - } - else - { - string - msg = - "Player #%d [%s] has disconnected, but player was only an observer!"; - if (lang.hasString ("GameSwitchPlayerObserverToAI", - languageList[j], true)) - { - msg = - lang.getString ("GameSwitchPlayerObserverToAI", - languageList[j], true); - } - snprintf (szBuf, 8096, msg.c_str (), i + 1, - this->gameSettings.getNetworkPlayerName (i). - c_str ()); - } - bool localEcho = (languageList[j] == lang.getLanguage ()); - server->sendTextMessage (szBuf, -1, localEcho, - languageList[j]); - } - } - } - } - - if (newAIPlayerCreated == true - && Config::getInstance ().getBool ("EnableNewThreadManager", - "false") == true) - { - bool - enableServerControlledAI = - this->gameSettings.getEnableServerControlledAI (); - - masterController.clearSlaves (true); - - std::vector < SlaveThreadControllerInterface * >slaveThreadList; - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - if (faction->getCpuControl - (enableServerControlledAI, isNetworkGame, role) == true) - { - slaveThreadList.push_back (aiInterfaces[i]->getWorkerThread ()); - } - } - masterController.setSlaves (slaveThreadList); - } - } - } - - void Game::updateCamera () - { - if (currentUIState != NULL) - { - currentUIState->updateCamera (); - return; - } - gameCamera.update (); - } - - -// ==================== render ==================== - -//render - void Game::render () - { - // Ensure the camera starts in the right position - if (isFirstRender == true) - { - isFirstRender = false; - - if (this->loadGameNode == NULL) - { - gameCamera.setState (GameCamera::sGame); - this->restoreToStartXY (); - } - } - - canRender (); - incrementFps (); - - renderFps++; - totalRenderFps++; - - updateWorldStats (); - - //NetworkManager &networkManager= NetworkManager::getInstance(); - if (this->masterserverMode == false) - { - renderWorker (); - } - else - { - // Titi, uncomment this to watch the game on the masterserver - //renderWorker(); - - // In masterserver mode quit game if no network players left - ServerInterface *server = - NetworkManager::getInstance ().getServerInterface (); - int connectedClients = 0; - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - if (server->isClientConnected (faction->getStartLocationIndex ()) == - true) - { - connectedClients++; - } - } - - if (connectedClients == 0) - { - quitTriggeredIndicator = true; - } - else - { - string str = ""; - std::map < int, string > factionDebugInfo; - - if (difftime - ((long int) time (NULL), - lastMasterServerGameStatsDump) >= GAME_STATS_DUMP_INTERVAL) - { - lastMasterServerGameStatsDump = time (NULL); - str = getDebugStats (factionDebugInfo); - - printf ("== Current in-game stats (interval %d) ==\n%s\n", - GAME_STATS_DUMP_INTERVAL, str.c_str ()); - } - } - } - } - - void Game::renderWorker () - { - if (currentUIState != NULL) - { -// Renderer &renderer= Renderer::getInstance(); -// renderer.clearBuffers(); -// -// //3d -// renderer.reset3dMenu(); -// -// renderer.clearZBuffer(); -// //renderer.loadCameraMatrix(menuBackground.getCamera()); -// //renderer.renderMenuBackground(&menuBackground); -// renderer.renderParticleManager(rsMenu); -// -// //2d -// renderer.reset2d(); -// -// currentUIState->render(); -// -// if(renderer.isMasterserverMode() == false) { -// renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim); -// renderer.renderFPSWhenEnabled(lastFps); -// renderer.swapBuffers(); -// } - - currentUIState->render (); - return; - } - else - { - Renderer & renderer = Renderer::getInstance (); - if (renderer.getCustom3dMenu () != NULL) - { - renderer.setCustom3dMenu (NULL); - } - } - - Chrono chrono; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled) - chrono.start (); - - render3d (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %d [render3d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - render2d (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %d [render2d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - Renderer::getInstance ().swapBuffers (); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %d [swap buffers]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - } - -// ==================== tick ==================== - - void Game::removeUnitFromSelection (const Unit * unit) - { - try - { - Selection *selection = gui.getSelectionPtr (); - for (int i = 0; i < selection->getCount (); ++i) - { - const Unit *currentUnit = selection->getUnit (i); - if (currentUnit == unit) - { - selection->unSelect (i); - break; - } - } - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); - - if (errorMessageBox.getEnabled () == false) - { - ErrorDisplayMessage (ex.what (), true); - } - - //abort(); - } - } - - bool Game::addUnitToSelection (Unit * unit) - { - bool result = false; - try - { - Selection *selection = gui.getSelectionPtr (); - if (selection != NULL) - { - result = selection->select (unit, true); - } - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); - - if (errorMessageBox.getEnabled () == false) - { - ErrorDisplayMessage (ex.what (), true); - } - - //abort(); - } - - return result; - } - - void Game::addUnitToGroupSelection (Unit * unit, int groupIndex) - { - try - { - Selection *selection = gui.getSelectionPtr (); - if (selection != NULL) - { - selection->addUnitToGroup (groupIndex, unit); - } - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); - - if (errorMessageBox.getEnabled () == false) - { - ErrorDisplayMessage (ex.what (), true); - } - - //abort(); - } - } - - void Game::removeUnitFromGroupSelection (int unitId, int groupIndex) - { - try - { - Selection *selection = gui.getSelectionPtr (); - if (selection != NULL) - { - selection->removeUnitFromGroup (groupIndex, unitId); - } - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); - - if (errorMessageBox.getEnabled () == false) - { - ErrorDisplayMessage (ex.what (), true); - } - - //abort(); - } - } - - void Game::recallGroupSelection (int groupIndex) - { - try - { - Selection *selection = gui.getSelectionPtr (); - if (selection != NULL) - { - selection->recallGroup (groupIndex); - } - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); - - if (errorMessageBox.getEnabled () == false) - { - ErrorDisplayMessage (ex.what (), true); - } - - //abort(); - } - } - - void Game::tick () - { - ProgramState::tick (); - - tickCount++; - - if (avgUpdateFps == -1) - { - avgUpdateFps = updateFps; - } - else - { - avgUpdateFps = (avgUpdateFps + updateFps) / 2; - } - currentAvgRenderFpsTotal += renderFps; - - if (avgRenderFps == -1) - { - avgRenderFps = renderFps; - } - // Update the average every x game ticks - const int CHECK_AVG_FPS_EVERY_X_TICKS = 15; - if (tickCount % CHECK_AVG_FPS_EVERY_X_TICKS == 0) - { - avgRenderFps = currentAvgRenderFpsTotal / CHECK_AVG_FPS_EVERY_X_TICKS; - currentAvgRenderFpsTotal = 0; - } - - if (captureAvgTestStatus == true) - { - if (updateFpsAvgTest == -1) - { - updateFpsAvgTest = updateFps; - } - else - { - updateFpsAvgTest = (updateFpsAvgTest + updateFps) / 2; - } - if (renderFpsAvgTest == -1) - { - renderFpsAvgTest = renderFps; - } - else - { - renderFpsAvgTest = (renderFpsAvgTest + renderFps) / 2; - } - } - - lastUpdateFps = updateFps; - lastRenderFps = renderFps; - updateFps = 0; - renderFps = 0; - - //Win/lose check - checkWinner (); - gui.tick (); - } - - -// ==================== events ==================== - - int Game::getFirstUnusedTeamNumber () - { - std::map < int, bool > uniqueTeamNumbersUsed; - for (unsigned int i = 0; i < (unsigned int) world.getFactionCount (); - ++i) - { - Faction *faction = world.getFaction (i); - uniqueTeamNumbersUsed[faction->getTeam ()] = true; - } - - int result = -1; - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - if (uniqueTeamNumbersUsed.find (i) == uniqueTeamNumbersUsed.end ()) - { - result = i; - break; - } - } - - return result; - } - - void Game::setupRenderForVideo () - { - Renderer & renderer = Renderer::getInstance (); - //renderer.clearBuffers(); - //3d - //renderer.reset3dMenu(); - //renderer.clearZBuffer(); - //2d - //renderer.reset2d(); - renderer.setupRenderForVideo (); - } - - void Game::tryPauseToggle (bool pauseValue) - { - bool allowAdminMenuItems = false; - NetworkManager & networkManager = NetworkManager::getInstance (); - NetworkRole role = networkManager.getNetworkRole (); - if (role == nrServer) - { - allowAdminMenuItems = true; - } - else if (role == nrClient) - { - ClientInterface *clientInterface = - dynamic_cast < - ClientInterface * >(networkManager.getClientInterface ()); - - if (clientInterface != NULL && - gameSettings.getMasterserver_admin () == - clientInterface->getSessionKey ()) - { - allowAdminMenuItems = true; - } - } - - bool isNetworkGame = this->gameSettings.isNetworkGame (); - //printf("Try Pause allowAdminMenuItems = %d, pauseValue = %d\n",allowAdminMenuItems,pauseValue); - - if (allowAdminMenuItems) - { - if (pauseValue == true) - { - commander.tryPauseGame (false, false); - } - else - { - if (isNetworkGame == false) - { - setPaused (pauseValue, true, false, false); - } - else - { - commander.tryResumeGame (false, false); - } - } - } - } - - void Game::startMarkCell () - { - int totalMarkedCellsForPlayer = 0; - if (world.getThisFaction () != NULL) - { - for (std::map < Vec2i, MarkedCell >::iterator iterMap = - mapMarkedCellList.begin (); - iterMap != mapMarkedCellList.end (); ++iterMap) - { - MarkedCell & bm = iterMap->second; - if (bm.getPlayerIndex () == - world.getThisFaction ()->getStartLocationIndex ()) - { - totalMarkedCellsForPlayer++; - } - } - } - - const int MAX_MARKER_COUNT = 5; - if (totalMarkedCellsForPlayer < MAX_MARKER_COUNT) - { - isMarkCellEnabled = true; - } - else - { - Lang & lang = Lang::getInstance (); - console.addLine (lang.getString ("MaxMarkerCount") + " " + - intToStr (MAX_MARKER_COUNT)); - } - } - - void Game::processInputText (string text, bool cancelled) - { - isMarkCellTextEnabled = false; - - if (cancelled == false) - { - //printf("Note [%s]\n",text.c_str()); - - cellMarkedData.setNote (text); - addCellMarker (cellMarkedPos, cellMarkedData); - -// if(text.find("\\n") != text.npos) { -// replaceAll(text, "\\n", "\n"); -// } -// if(text.find("\\t") != text.npos) { -// replaceAll(text, "\\t", "\t"); -// } -// -// cellMarkedData.setNote(text); -// mapMarkedCellList[cellMarkedPos] = cellMarkedData; -// -// GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); -// -// int factionIndex = -1; -// int playerIndex = -1; -// if(cellMarkedData.getFaction() != NULL) { -// factionIndex = cellMarkedData.getFaction()->getIndex(); -// playerIndex = cellMarkedData.getFaction()->getStartLocationIndex(); -// } -// gameNetworkInterface->sendMarkCellMessage( -// cellMarkedData.getTargetPos(), -// factionIndex, -// cellMarkedData.getNote(), -// playerIndex); -// -// Renderer &renderer= Renderer::getInstance(); -// renderer.forceQuadCacheUpdate(); - } - } - - void Game::addCellMarker (Vec2i cellPos, MarkedCell cellData) - { - //printf("Note [%s]\n",text.c_str()); - - string text = cellData.getNote (); - if (text.find ("\\n") != text.npos) - { - replaceAll (text, "\\n", "\n"); - } - if (text.find ("\\t") != text.npos) - { - replaceAll (text, "\\t", "\t"); - } - - cellData.setNote (text); - mapMarkedCellList[cellPos] = cellData; - - GameNetworkInterface *gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - - int factionIndex = -1; - int playerIndex = -1; - if (cellData.getFaction () != NULL) - { - factionIndex = cellData.getFaction ()->getIndex (); - playerIndex = cellData.getFaction ()->getStartLocationIndex (); - } - - //printf("Adding Cell marker pos [%s] factionIndex [%d] note [%s] playerIndex = %d\n",cellData.getTargetPos().getString().c_str(),factionIndex,cellData.getNote().c_str(),playerIndex); - - gameNetworkInterface->sendMarkCellMessage (cellData.getTargetPos (), - factionIndex, - cellData.getNote (), - playerIndex); - - Renderer & renderer = Renderer::getInstance (); - renderer.forceQuadCacheUpdate (); - } - - void - Game::removeCellMarker (Vec2i surfaceCellPos, const Faction * faction) - { - //Vec2i surfaceCellPos = map->toSurfCoords(Vec2i(xCell,yCell)); - Map *map = world.getMap (); - SurfaceCell *sc = map->getSurfaceCell (surfaceCellPos); - Vec3f vertex = sc->getVertex (); - Vec2i targetPos (vertex.x, vertex.z); - - //printf("Remove Cell marker lookup pos [%s] factionIndex [%d]\n",surfaceCellPos.getString().c_str(),(faction != NULL ? faction->getIndex() : -1)); - - if (mapMarkedCellList.find (surfaceCellPos) != mapMarkedCellList.end ()) - { - MarkedCell mc = mapMarkedCellList[surfaceCellPos]; - if (mc.getFaction () == faction) - { - mapMarkedCellList.erase (surfaceCellPos); - GameNetworkInterface *gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - - int factionIndex = (faction != NULL ? faction->getIndex () : -1); - - //printf("Remvoing Cell marker pos [%s] factionIndex [%d] note [%s]\n",mc.getTargetPos().getString().c_str(),factionIndex,mc.getNote().c_str()); - - gameNetworkInterface->sendUnMarkCellMessage (mc.getTargetPos (), - factionIndex); - } - } - //printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size()); - - //isUnMarkCellEnabled = false; - - Renderer & renderer = Renderer::getInstance (); - //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos); - renderer.forceQuadCacheUpdate (); - } - void Game::showMarker (Vec2i cellPos, MarkedCell cellData) - { - //setMarker = true; - //if(setMarker) { - //Vec2i targetPos = cellData.targetPos; - //Vec2i screenPos(x,y-60); - //Renderer &renderer= Renderer::getInstance(); - //renderer.computePosition(screenPos, targetPos); - //Vec2i surfaceCellPos = map->toSurfCoords(targetPos); - - //MarkedCell mc(targetPos,world.getThisFaction(),"none",world.getThisFaction()->getStartLocationIndex()); - addOrReplaceInHighlightedCells (cellData); - - GameNetworkInterface *gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - gameNetworkInterface-> - sendHighlightCellMessage (cellData.getTargetPos (), - cellData.getFactionIndex ()); - //} - } - - void Game::mouseDownLeft (int x, int y) - { - if (this->masterserverMode == true) - { - return; - } - cameraDragAllowed = false; - if (currentUIState != NULL) - { - currentUIState->mouseDownLeft (x, y); - return; - } - - try - { - if (gameStarted == false || totalRenderFps <= 0) - { - Logger::getInstance ().handleMouseClick (x, y); - return; - } - - Map *map = world.getMap (); - const Metrics & metrics = Metrics::getInstance (); - NetworkManager & networkManager = NetworkManager::getInstance (); - bool messageBoxClick = false; - bool originalIsMarkCellEnabled = isMarkCellEnabled; - bool originalIsUnMarkCellEnabled = isUnMarkCellEnabled; - - if (popupMenu.mouseClick (x, y)) - { - std::pair < int, - string > result = popupMenu.mouseClickedMenuItem (x, y); - //printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first); - - //printf("popupMenu.mouseClick == true result.first = %d disconnectPlayerPopupMenuIndex = %d\n",result.first,disconnectPlayerPopupMenuIndex); - - popupMenu.setEnabled (false); - popupMenu.setVisible (false); - - // Exit game - if (result.first == exitGamePopupMenuIndex) - { - showMessageBox (Lang:: - getInstance ().getString ("ExitBattleQuestion"), - "", true); - } - else if (result.first == joinTeamPopupMenuIndex) - { - - Lang & lang = Lang::getInstance (); - switchTeamIndexMap.clear (); - std::map < int, bool > uniqueTeamNumbersUsed; - std::vector < string > menuItems; - for (unsigned int i = 0; - i < (unsigned int) world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - - if (faction->getPersonalityType () != fpt_Observer && - uniqueTeamNumbersUsed.find (faction->getTeam ()) == - uniqueTeamNumbersUsed.end ()) - { - uniqueTeamNumbersUsed[faction->getTeam ()] = true; - } - - if (faction->getPersonalityType () != fpt_Observer && - world.getThisFaction ()->getIndex () != - faction->getIndex () - && world.getThisFaction ()->getTeam () != - faction->getTeam ()) - { - char szBuf[8096] = ""; - if (lang.hasString ("JoinPlayerTeam") == true) - { - snprintf (szBuf, 8096, - (" " + - lang.getString ("JoinPlayerTeam") + - " ").c_str (), faction->getIndex (), - this->gameSettings.getNetworkPlayerName (i). - c_str (), faction->getTeam ()); - } - else - { - snprintf (szBuf, 8096, - " Join player #%d - %s on Team: %d ", - faction->getIndex (), - this->gameSettings.getNetworkPlayerName (i). - c_str (), faction->getTeam ()); - } - - menuItems.push_back (szBuf); - - switchTeamIndexMap[(int) menuItems.size () - 1] = - faction->getTeam (); - } - } - - if ((int) uniqueTeamNumbersUsed.size () < 8) - { - menuItems.push_back (" " + - lang.getString ("CreateNewTeam") + " "); - switchTeamIndexMap[(int) menuItems.size () - 1] = - CREATE_NEW_TEAM; - } - menuItems.push_back (" " + lang.getString ("Cancel") + " "); - switchTeamIndexMap[(int) menuItems.size () - 1] = - CANCEL_SWITCH_TEAM; - - popupMenuSwitchTeams.setW (100); - popupMenuSwitchTeams.setH (100); - popupMenuSwitchTeams.init (" " + - lang.getString ("SwitchTeams") + - " ", menuItems); - popupMenuSwitchTeams.setEnabled (true); - popupMenuSwitchTeams.setVisible (true); - } - else if (result.first == disconnectPlayerPopupMenuIndex) - { - Lang & lang = Lang::getInstance (); - - NetworkManager & networkManager = NetworkManager::getInstance (); - NetworkRole role = networkManager.getNetworkRole (); - ServerInterface *serverInterface = NULL; - if (role == nrServer) - { - serverInterface = - dynamic_cast < - ServerInterface * >(networkManager.getServerInterface ()); - } - disconnectPlayerIndexMap.clear (); - std::vector < string > menuItems; - for (unsigned int i = 0; - i < (unsigned int) world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - - //printf("faction->getPersonalityType() = %d index [%d,%d] control [%d] networkstatus [%d]\n",faction->getPersonalityType(),world.getThisFaction()->getIndex(),faction->getIndex(),faction->getControlType(),this->gameSettings.getNetworkPlayerStatuses(i)); - - bool isSlotJoinInProgressClient = false; - if (serverInterface != NULL) - { - - MutexSafeWrapper - safeMutex (serverInterface->getSlotMutex - (faction->getStartLocationIndex ()), - CODE_AT_LINE); - ConnectionSlot *slot = - serverInterface->getSlot (faction->getStartLocationIndex (), - false); - if (slot != NULL - && slot->getConnectHasHandshaked () == true - && slot->getCurrentFrameCount () <= 0) - { - isSlotJoinInProgressClient = true; - } - } - - //printf("isSlotJoinInProgressClient: %d [%d] [%d][%d] [%d] [%d] [%d]\n", - // isSlotJoinInProgressClient,faction->getPersonalityType(),faction->getIndex(),world.getThisFaction()->getIndex(),faction->getControlType(),this->gameSettings.getNetworkPlayerStatuses(i),i); - - if (isSlotJoinInProgressClient == true || - (faction->getPersonalityType () != fpt_Observer && - world.getThisFaction ()->getIndex () != - faction->getIndex () - && faction->getControlType () == ctNetwork - && this->gameSettings.getNetworkPlayerStatuses (i) != - npst_Disconnected)) - { - - char szBuf[8096] = ""; - if (lang.hasString ("DisconnectNetorkPlayerIndex") == true) - { - snprintf (szBuf, 8096, - (" " + - lang.getString - ("DisconnectNetorkPlayerIndex") + - " ").c_str (), - faction->getIndex () + 1, - this->gameSettings.getNetworkPlayerName (i). - c_str ()); - } - else - { - snprintf (szBuf, 8096, - " Disconnect player #%d - %s: ", - faction->getIndex () + 1, - this->gameSettings.getNetworkPlayerName (i). - c_str ()); - } - - menuItems.push_back (szBuf); - - //disconnectPlayerIndexMap[menuItems.size()-1] = faction->getStartLocationIndex(); - disconnectPlayerIndexMap[(int) menuItems.size () - - 1] = faction->getIndex (); - } - } - - menuItems.push_back (" " + lang.getString ("Cancel") + " "); - disconnectPlayerIndexMap[(int) menuItems.size () - 1] = - CANCEL_DISCONNECT_PLAYER; - - popupMenuDisconnectPlayer.setW (100); - popupMenuDisconnectPlayer.setH (100); - popupMenuDisconnectPlayer.init (" " + - lang.getString - ("DisconnectNetorkPlayer") + - " ", menuItems); - popupMenuDisconnectPlayer.setEnabled (true); - popupMenuDisconnectPlayer.setVisible (true); - } - else if (result.first == keyboardSetupPopupMenuIndex) - { - MainMenu *newMenu = new MainMenu (program); // open keyboard shortcuts setup screen - currentUIState = newMenu; - Renderer & renderer = Renderer::getInstance (); - renderer.setCustom3dMenu (newMenu); - //currentUIState->load(); - currentUIState->init (); - - // open keyboard shortcuts setup screen - newMenu->setState (new - MenuStateKeysetup (program, newMenu, - ¤tUIState)); - } - else if (result.first == pauseGamePopupMenuIndex) - { - //this->setPaused(!paused); - //printf("popup paused = %d\n",paused); - - bool allowAdminMenuItems = false; - NetworkRole role = networkManager.getNetworkRole (); - if (role == nrServer) - { - allowAdminMenuItems = true; - } - else if (role == nrClient) - { - ClientInterface *clientInterface = - dynamic_cast < - ClientInterface * >(networkManager.getClientInterface ()); - - if (clientInterface != NULL && - gameSettings.getMasterserver_admin () == - clientInterface->getSessionKey ()) - { - allowAdminMenuItems = true; - } - } - - if (allowAdminMenuItems) - { - if (getPaused () == false) - { - commander.tryPauseGame (false, false); - } - else - { - commander.tryResumeGame (false, false); - } - } - } - else if (result.first == saveGamePopupMenuIndex) - { - saveGame (); - } - //else if(result.first == markCellPopupMenuIndex) { - // startMarkCell(); - //} - //else if(result.first == unmarkCellPopupMenuIndex) { - // isUnMarkCellEnabled = true; - //} - } - else if (popupMenuSwitchTeams.mouseClick (x, y)) - { - //popupMenuSwitchTeams - std::pair < int, - string > - result = popupMenuSwitchTeams.mouseClickedMenuItem (x, y); - //printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first); - - popupMenuSwitchTeams.setEnabled (false); - popupMenuSwitchTeams.setVisible (false); - - //bool isNetworkGame = this->gameSettings.isNetworkGame(); - - int teamIndex = switchTeamIndexMap[result.first]; - switch (teamIndex) - { - case CREATE_NEW_TEAM: - { - int newTeam = getFirstUnusedTeamNumber (); - //if(isNetworkGame == true) { - const Faction *faction = world.getThisFaction (); - commander.trySwitchTeam (faction, newTeam); - //} - //else { - // const Faction *faction = world.getThisFaction(); - // commander.trySwitchTeam(faction,newTeam); - //} - } - break; - case CANCEL_SWITCH_TEAM: - break; - default: - //if(isNetworkGame == true) { - const Faction *faction = world.getThisFaction (); - commander.trySwitchTeam (faction, teamIndex); - //} - //else { - // const Faction *faction = world.getThisFaction(); - // commander.trySwitchTeam(faction,teamIndex); - //} - - break; - } - } - else if (popupMenuDisconnectPlayer.mouseClick (x, y)) - { - //popupMenuSwitchTeams - std::pair < int, - string > - result = popupMenuDisconnectPlayer.mouseClickedMenuItem (x, y); - //printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first); - - popupMenuDisconnectPlayer.setEnabled (false); - popupMenuDisconnectPlayer.setVisible (false); - - //bool isNetworkGame = this->gameSettings.isNetworkGame(); - - //int playerIndex = disconnectPlayerIndexMap[result.first]; - int factionIndex = disconnectPlayerIndexMap[result.first]; - switch (factionIndex) - { - case CANCEL_DISCONNECT_PLAYER: - break; - default: -// if(isNetworkGame == true) { -// const Faction *faction = world.getThisFaction(); -// commander.trySwitchTeam(faction,teamIndex); -// } -// else { -// const Faction *faction = world.getThisFaction(); -// commander.trySwitchTeam(faction,teamIndex); -// } - - - GameSettings * settings = world.getGameSettingsPtr (); - Lang & lang = Lang::getInstance (); - - char szBuf[8096] = ""; - if (lang.hasString ("DisconnectNetorkPlayerIndexConfirm") == true) - { - snprintf (szBuf, 8096, - (" " + - lang.getString - ("DisconnectNetorkPlayerIndexConfirm") + - " ").c_str (), factionIndex + 1, - settings-> - getNetworkPlayerName (factionIndex).c_str ()); - } - else - { - snprintf (szBuf, 8096, - " Confirm disconnection for player #%d - %s? ", - factionIndex + 1, - settings-> - getNetworkPlayerName (factionIndex).c_str ()); - } - - disconnectPlayerConfirmMessageBox.setText (szBuf); - disconnectPlayerConfirmMessageBox.init (lang.getString ("Yes"), - lang.getString ("No")); - disconnectPlayerConfirmMessageBox.setEnabled (true); - - playerIndexDisconnect = - world.getFaction (factionIndex)->getStartLocationIndex (); - - GameNetworkInterface *gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - if (gameNetworkInterface != NULL) - { - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = settings->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; - i < (unsigned int) languageList.size (); ++i) - { - char szMsg[8096] = ""; - if (lang.hasString ("DisconnectNetorkPlayerIndexConfirmed", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString - ("DisconnectNetorkPlayerIndexConfirmed", - languageList[i]).c_str (), - factionIndex + 1, - settings->getNetworkPlayerName - (factionIndex).c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Notice - Admin is warning to disconnect player #%d - %s!", - factionIndex + 1, - settings->getNetworkPlayerName - (factionIndex).c_str ()); - } - bool localEcho = lang.isLanguageLocal (languageList[i]); - gameNetworkInterface->sendTextMessage (szMsg, -1, - localEcho, - languageList[i]); - } - - sleep (10); - } - - break; - } - } - - if (switchTeamConfirmMessageBox.getEnabled () == true) - { - int button = -1; - if (switchTeamConfirmMessageBox.mouseClick (x, y, button)) - { - switchTeamConfirmMessageBox.setEnabled (false); - - SwitchTeamVote *vote = - world.getThisFactionPtr ()-> - getSwitchTeamVote (world.getThisFaction - ()->getCurrentSwitchTeamVoteFactionIndex ()); - vote->voted = true; - vote->allowSwitchTeam = (button == 0); - - const Faction *faction = world.getThisFaction (); - commander.trySwitchTeamVote (faction, vote); - } - } - else if (disconnectPlayerConfirmMessageBox.getEnabled () == true) - { - int button = -1; - if (disconnectPlayerConfirmMessageBox.mouseClick (x, y, button)) - { - disconnectPlayerConfirmMessageBox.setEnabled (false); - - if (button == 0) - { - const Faction *faction = world.getThisFaction (); - commander.tryDisconnectNetworkPlayer (faction, - playerIndexDisconnect); - } - } - } - - //scrip message box, only if the exit box is not enabled - if (mainMessageBox.getEnabled () == false && - errorMessageBox.getEnabled () == false && - scriptManager.getMessageBox ()->getEnabled ()) - { - int button = 0; - if (scriptManager.getMessageBox ()->mouseClick (x, y, button)) - { - scriptManager.onMessageBoxOk (); - messageBoxClick = true; - } - } - - //minimap panel - if (messageBoxClick == false) - { - if (metrics.isInMinimap (x, y)) - { - int xm = x - metrics.getMinimapX (); - int ym = y - metrics.getMinimapY (); - int - xCell = - static_cast < - int >(xm * - (static_cast < - float >(map->getW ()) / metrics.getMinimapW ())); - int - yCell = - static_cast < - int >(map->getH () - - ym * (static_cast < - float >(map->getH ()) / metrics.getMinimapH ())); - - if (map->isInside (xCell, yCell) - && map->isInsideSurface (map->toSurfCoords (Vec2i - (xCell, yCell)))) - { - if (gui.isSelectingPos ()) - { - gui.mouseDownLeftGraphics (xCell, yCell, true); - } - else - { - if (!setMarker) - { - cameraDragAllowed = true; - gameCamera.setPos (Vec2f - (static_cast < float >(xCell), - static_cast < float >(yCell))); - } - } - - if (setMarker) - { - Vec2i - surfaceCellPos = map->toSurfCoords (Vec2i (xCell, yCell)); - SurfaceCell *sc = map->getSurfaceCell (surfaceCellPos); - Vec3f vertex = sc->getVertex (); - Vec2i targetPos (vertex.x, vertex.z); - - MarkedCell - mc (targetPos, world.getThisFaction (), "none", - world.getThisFaction ()->getStartLocationIndex ()); - addOrReplaceInHighlightedCells (mc); - - GameNetworkInterface *gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - gameNetworkInterface-> - sendHighlightCellMessage (mc.getTargetPos (), - mc.getFaction ()->getIndex ()); - } - - - if (originalIsMarkCellEnabled == true - && isMarkCellEnabled == true) - { - Vec2i - surfaceCellPos = map->toSurfCoords (Vec2i (xCell, yCell)); - SurfaceCell *sc = map->getSurfaceCell (surfaceCellPos); - Vec3f vertex = sc->getVertex (); - Vec2i targetPos (vertex.x, vertex.z); - - MarkedCell - mc (targetPos, world.getThisFaction (), - "placeholder for note", - world.getThisFaction ()->getStartLocationIndex ()); - - //GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); - //gameNetworkInterface->sendMarkCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex(),mc.getNote()); - - //printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size()); - - isMarkCellEnabled = false; - cellMarkedData = mc; - cellMarkedPos = surfaceCellPos; - isMarkCellTextEnabled = true; - chatManager.switchOnEdit (this, 500); - - Renderer & renderer = Renderer::getInstance (); - //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos); - renderer.forceQuadCacheUpdate (); - } - if (originalIsUnMarkCellEnabled == true - && isUnMarkCellEnabled == true) - { - Vec2i - surfaceCellPos = map->toSurfCoords (Vec2i (xCell, yCell)); - SurfaceCell *sc = map->getSurfaceCell (surfaceCellPos); - Vec3f vertex = sc->getVertex (); - Vec2i targetPos (vertex.x, vertex.z); - -// if(mapMarkedCellList.find(surfaceCellPos) != mapMarkedCellList.end()) { -// MarkedCell mc = mapMarkedCellList[surfaceCellPos]; -// if(mc.getFaction() == world.getThisFaction()) { -// mapMarkedCellList.erase(surfaceCellPos); -// GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); -// gameNetworkInterface->sendUnMarkCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex()); -// } -// } - - isUnMarkCellEnabled = false; - - removeCellMarker (surfaceCellPos, world.getThisFaction ()); - //printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size()); - - Renderer & renderer = Renderer::getInstance (); - //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos); - renderer.forceQuadCacheUpdate (); - } - } - } - //display panel - else if (metrics.isInDisplay (x, y) && !gui.isSelectingPos ()) - { - int xd = x - metrics.getDisplayX (); - int yd = y - metrics.getDisplayY (); - if (gui.mouseValid (xd, yd)) - { - gui.mouseDownLeftDisplay (xd, yd); - } - else - { - gui.mouseDownLeftGraphics (x, y, false); - } - } - //graphics panel - else - { - gui.mouseDownLeftGraphics (x, y, false); - - if (setMarker) - { - Vec2i targetPos; - Vec2i screenPos (x, y - 60); - targetPos = getMouseCellPos (); - //Vec2i surfaceCellPos = map->toSurfCoords(targetPos); - - - MarkedCell - mc (targetPos, world.getThisFaction (), "none", - world.getThisFaction ()->getStartLocationIndex ()); - addOrReplaceInHighlightedCells (mc); - - GameNetworkInterface *gameNetworkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - gameNetworkInterface->sendHighlightCellMessage (mc.getTargetPos - (), - mc.getFaction - ()->getIndex - ()); - } - - if (originalIsMarkCellEnabled == true - && isMarkCellEnabled == true) - { - Vec2i targetPos; - Vec2i screenPos (x, y - 60); - targetPos = getMouseCellPos (); - Vec2i surfaceCellPos = map->toSurfCoords (targetPos); - - MarkedCell - mc (targetPos, world.getThisFaction (), - "placeholder for note", - world.getThisFaction ()->getStartLocationIndex ()); - - //printf("#2 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size()); - - isMarkCellEnabled = false; - cellMarkedData = mc; - cellMarkedPos = surfaceCellPos; - isMarkCellTextEnabled = true; - chatManager.switchOnEdit (this, 500); - - //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos); - Renderer::getInstance ().forceQuadCacheUpdate (); - } - - if (originalIsUnMarkCellEnabled == true - && isUnMarkCellEnabled == true) - { - Vec2i targetPos; - Vec2i screenPos (x, y - 35); - targetPos = getMouseCellPos (); - Vec2i surfaceCellPos = map->toSurfCoords (targetPos); - -// if(mapMarkedCellList.find(surfaceCellPos) != mapMarkedCellList.end()) { -// MarkedCell mc = mapMarkedCellList[surfaceCellPos]; -// if(mc.getFaction() == world.getThisFaction()) { -// mapMarkedCellList.erase(surfaceCellPos); -// GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); -// gameNetworkInterface->sendUnMarkCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex()); -// } -// } - - isUnMarkCellEnabled = false; - removeCellMarker (surfaceCellPos, world.getThisFaction ()); - //printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size()); - - //Renderer &renderer= Renderer::getInstance(); - //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos); - Renderer::getInstance ().forceQuadCacheUpdate (); - } - } - } - - //exit message box, has to be the last thing to do in this function - if (errorMessageBox.getEnabled () == true) - { - if (errorMessageBox.mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - //close message box - errorMessageBox.setEnabled (false); - } - } - if (mainMessageBox.getEnabled ()) - { - int button = 0; - if (mainMessageBox.mouseClick (x, y, button)) - { - if (button == 0) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - if (networkManager.getGameNetworkInterface () != NULL) - { - networkManager.getGameNetworkInterface ()->quitGame (true); - } - quitTriggeredIndicator = true; - return; - } - else - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - //close message box - mainMessageBox.setEnabled (false); - } - } - } - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); - - NetworkManager & networkManager = NetworkManager::getInstance (); - if (networkManager.getGameNetworkInterface () != NULL) - { - GameNetworkInterface *networkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - networkInterface->sendTextMessage (szBuf, -1, true, ""); - sleep (10); - networkManager.getGameNetworkInterface ()->quitGame (true); - } - ErrorDisplayMessage (ex.what (), true); - } - } - - void Game::mouseDownRight (int x, int y) - { - if (this->masterserverMode == true) - { - return; - } - - if (currentUIState != NULL) - { - currentUIState->mouseDownRight (x, y); - return; - } - - try - { - if (gameStarted == false || totalRenderFps <= 0) - { - Logger::getInstance ().handleMouseClick (x, y); - return; - } - - Map *map = world.getMap (); - const Metrics & metrics = Metrics::getInstance (); - - if (metrics.isInMinimap (x, y)) - { - int xm = x - metrics.getMinimapX (); - int ym = y - metrics.getMinimapY (); - int - xCell = - static_cast < - int >(xm * - (static_cast < - float >(map->getW ()) / metrics.getMinimapW ())); - int - yCell = - static_cast < - int >(map->getH () - - ym * (static_cast < - float >(map->getH ()) / metrics.getMinimapH ())); - - if (map->isInside (xCell, yCell) - && map-> - isInsideSurface (map->toSurfCoords (Vec2i (xCell, yCell)))) - { - gui.mouseDownRightGraphics (xCell, yCell, true); - } - } - else - { - Vec2i targetPos; - Vec2i screenPos (x, y); - targetPos = getMouseCellPos (); - if (isValidMouseCellPos () == true && - map->isInsideSurface (map->toSurfCoords (targetPos)) == true) - { - gui.mouseDownRightGraphics (x, y, false); - } - } - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] Error [%s] x = %d y = %d\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what (), x, y); - - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); - - NetworkManager & networkManager = NetworkManager::getInstance (); - if (networkManager.getGameNetworkInterface () != NULL) - { - GameNetworkInterface *networkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - networkInterface->sendTextMessage (szBuf, -1, true, ""); - sleep (10); - networkManager.getGameNetworkInterface ()->quitGame (true); - } - ErrorDisplayMessage (ex.what (), true); - } - } - - void Game::mouseUpCenter (int x, int y) - { - if (this->masterserverMode == true) - { - return; - } - - if (gameStarted == false || totalRenderFps <= 0) - { - return; - } - - if (currentUIState != NULL) - { - currentUIState->mouseUpCenter (x, y); - return; - } - - if (mouseMoved == false) - { - gameCamera.setState (GameCamera::sGame); - } - else - { - mouseMoved = false; - } - } - - void Game::mouseUpLeft (int x, int y) - { - if (this->masterserverMode == true) - { - return; - } - - try - { - if (gameStarted == false || totalRenderFps <= 0) - { - return; - } - - if (currentUIState != NULL) - { - currentUIState->mouseUpLeft (x, y); - return; - } - - gui.mouseUpLeftGraphics (x, y); - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); - - NetworkManager & networkManager = NetworkManager::getInstance (); - if (networkManager.getGameNetworkInterface () != NULL) - { - GameNetworkInterface *networkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - networkInterface->sendTextMessage (szBuf, -1, true, ""); - sleep (10); - networkManager.getGameNetworkInterface ()->quitGame (true); - } - ErrorDisplayMessage (ex.what (), true); - } - } - - void Game::mouseDoubleClickLeft (int x, int y) - { - if (this->masterserverMode == true) - { - return; - } - - try - { - if (gameStarted == false || totalRenderFps <= 0) - { - return; - } - if (currentUIState != NULL) - { - currentUIState->mouseDoubleClickLeft (x, y); - return; - } - - const Metrics & metrics = Metrics::getInstance (); - - if (metrics.isInMinimap (x, y)) - { - // no double click on minimap - } - else - { - //display panel - if (metrics.isInDisplay (x, y) && !gui.isSelectingPos ()) - { - int xd = x - metrics.getDisplayX (); - int yd = y - metrics.getDisplayY (); - if (gui.mouseValid (xd, yd)) - { - return; - } - } - //graphics panel - gui.mouseDoubleClickLeftGraphics (x, y); - } - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); - - NetworkManager & networkManager = NetworkManager::getInstance (); - if (networkManager.getGameNetworkInterface () != NULL) - { - GameNetworkInterface *networkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - networkInterface->sendTextMessage (szBuf, -1, true, ""); - sleep (10); - networkManager.getGameNetworkInterface ()->quitGame (true); - } - ErrorDisplayMessage (ex.what (), true); - } - } - - void Game::mouseMove (int x, int y, const MouseState * ms) - { - if (this->masterserverMode == true) - { - return; - } - - try - { - if (gameStarted == false || totalRenderFps <= 0) - { - return; - } - if (currentUIState != NULL) - { - currentUIState->mouseMove (x, y, ms); - return; - } - - popupMenu.mouseMove (x, y); - popupMenuSwitchTeams.mouseMove (x, y); - popupMenuDisconnectPlayer.mouseMove (x, y); - - const Metrics & metrics = Metrics::getInstance (); - - mouseX = x; - mouseY = y; - - if (ms->get (mbCenter)) - { - mouseMoved = true; - if (currentCameraFollowUnit == NULL) - { - float ymult = 0.2f; - float xmult = 0.2f; - - Vec2i oldPos =::Shared::Platform::Window::getOldMousePos (); - int - oldx = - (oldPos.x * metrics.getVirtualW () / metrics.getScreenW ()); - int - oldy = - ((metrics.getScreenH () - - oldPos.y) * metrics.getVirtualH () / metrics.getScreenH ()); - lastMousePos.x = oldx; - lastMousePos.y = oldy; - gameCamera.transitionVH (-(y - oldy) * ymult, (oldx - x) * xmult); - } - mouseX = lastMousePos.x; - mouseY = lastMousePos.y; - ::Shared::Platform::Window::revertMousePos (); - - return; - } - else if (currentCameraFollowUnit == NULL) - { - //if(Window::isKeyDown() == false) - if (!camLeftButtonDown && !camRightButtonDown && !camUpButtonDown - && !camDownButtonDown) - { - if (ms->get (mbLeft) && metrics.isInMinimap (x, y)) - { - int xm = x - metrics.getMinimapX (); - int ym = y - metrics.getMinimapY (); - - Map *map = world.getMap (); - int - xCell = - static_cast < - int >(xm * - (static_cast < - float >(map->getW ()) / metrics.getMinimapW ())); - int - yCell = - static_cast < - int >(map->getH () - - ym * (static_cast < - float >(map->getH ()) / metrics.getMinimapH ())); - - if (map->isInside (xCell, yCell) - && map->isInsideSurface (map->toSurfCoords (Vec2i - (xCell, - yCell)))) - { - if (gui.isSelectingPos ()) - { - gui.mouseDownLeftGraphics (xCell, yCell, true); - } - else - { - if (cameraDragAllowed == true) - { - gameCamera.setPos (Vec2f - (static_cast < float >(xCell), - static_cast < float >(yCell))); - } - } - } - } - else - { - bool - mouseMoveScrollsWorld = - Config::getInstance ().getBool ("MouseMoveScrollsWorld", - "true"); - if (mouseMoveScrollsWorld == true) - { - if (y < 10) - { - gameCamera.setMoveZ (-scrollSpeed); - } - else if (y > metrics.getVirtualH () - 10) - { - gameCamera.setMoveZ (scrollSpeed); - } - else - { - gameCamera.setMoveZ (0); - } - - if (x < 10) - { - gameCamera.setMoveX (-scrollSpeed); - } - else if (x > metrics.getVirtualW () - 10) - { - gameCamera.setMoveX (scrollSpeed); - } - else - { - gameCamera.setMoveX (0); - } - } - } - } - - if (switchTeamConfirmMessageBox.getEnabled () == true) - { - switchTeamConfirmMessageBox.mouseMove (x, y); - } - - if (disconnectPlayerConfirmMessageBox.getEnabled () == true) - { - disconnectPlayerConfirmMessageBox.mouseMove (x, y); - } - - if (mainMessageBox.getEnabled ()) - { - mainMessageBox.mouseMove (x, y); - } - if (errorMessageBox.getEnabled ()) - { - errorMessageBox.mouseMove (x, y); - } - if (scriptManager.getMessageBox ()->getEnabled ()) - { - scriptManager.getMessageBox ()->mouseMove (x, y); - } - //else if (saveBox) { - // saveBox->mouseMove(x, y); - //} else { - // //graphics - gui.mouseMoveGraphics (x, y); - //} - } - - //display - if (!gui.isSelecting () && !gui.isSelectingPos ()) - { - if (!gui.isSelectingPos ()) - { - if (metrics.isInDisplay (x, y)) - { - gui.mouseMoveDisplay (x - metrics.getDisplayX (), - y - metrics.getDisplayY ()); - } - else - { - gui.mouseMoveOutsideDisplay (); - } - } - } - - lastMousePos.x = mouseX; - lastMousePos.y = mouseY; - - Renderer & renderer = Renderer::getInstance (); - renderer.ccomputePosition (Vec2i (mouseX, mouseY), mouseCellPos); - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); - - NetworkManager & networkManager = NetworkManager::getInstance (); - if (networkManager.getGameNetworkInterface () != NULL) - { - GameNetworkInterface *networkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - networkInterface->sendTextMessage (szBuf, -1, true, ""); - sleep (10); - networkManager.getGameNetworkInterface ()->quitGame (true); - } - ErrorDisplayMessage (ex.what (), true); - } - } - - bool Game::isValidMouseCellPos ()const - { - if (world.getMap () == NULL) - { - return false; - } - else - { - return world.getMap ()->isInside (mouseCellPos); - } - } - - void Game::eventMouseWheel (int x, int y, int zDelta) - { - if (this->masterserverMode == true) - { - return; - } - - if (currentUIState != NULL) - { - currentUIState->eventMouseWheel (x, y, zDelta); - return; - } - - try - { - gameCamera.zoom ((float) zDelta / 60.0f); - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); - - NetworkManager & networkManager = NetworkManager::getInstance (); - if (networkManager.getGameNetworkInterface () != NULL) - { - GameNetworkInterface *networkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - networkInterface->sendTextMessage (szBuf, -1, true, ""); - sleep (10); - networkManager.getGameNetworkInterface ()->quitGame (true); - } - ErrorDisplayMessage (ex.what (), true); - } - } - - void Game::startCameraFollowUnit () - { - Selection *selection = gui.getSelectionPtr (); - if (selection->getCount () == 1) - { - Unit *currentUnit = selection->getUnitPtr (0); - if (currentUnit != NULL) - { - currentCameraFollowUnit = currentUnit; - getGameCameraPtr ()->setState (GameCamera::sUnit); - getGameCameraPtr ()-> - setPos (currentCameraFollowUnit->getCurrMidHeightVector ()); - - int rotation = currentCameraFollowUnit->getRotation (); - getGameCameraPtr ()->stop (); - getGameCameraPtr ()->rotateToVH (0.0f, (540 - rotation) % 360); - getGameCameraPtr ()->setHAng ((540 - rotation) % 360); - getGameCameraPtr ()->setVAng (0.0f); - } - } - else - { - if (currentCameraFollowUnit != NULL) - { - currentCameraFollowUnit = NULL; - } - } - } - - bool Game::textInput (std::string text) - { - if (chatManager.getEditEnabled () == true) - { - return chatManager.textInput (text); - } - return false; - } - - bool Game::sdlKeyDown (SDL_KeyboardEvent key) - { - if (this->masterserverMode == true) - { - return false; - } - if (gameStarted == false || totalRenderFps <= 0) - { - return false; - } - - if (chatManager.getEditEnabled () == true) - { - return false; - } - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - //group - for (int idx = 1; idx <= Selection::maxGroups; idx++) - { - string keyName = "GroupUnitsKey" + intToStr (idx); - - SDL_Keycode groupHotKey = configKeys.getSDLKey (keyName.c_str ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] keyName [%s] group index = %d, key = [%c] [%d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, keyName.c_str (), idx, - groupHotKey, groupHotKey); - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("input.keysym.mod = %d groupHotKey = %d key = %d (%d) [%s] isgroup = %d\n",key.keysym.mod,groupHotKey,key.keysym.sym,key.keysym.unicode,keyName.c_str(),isKeyPressed(groupHotKey,key)); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("input.keysym.mod = %d groupHotKey = %d key = (%d) [%s] isgroup = %d\n", - key.keysym.mod, groupHotKey, key.keysym.sym, keyName.c_str (), - isKeyPressed (groupHotKey, key)); - //printf(" group key check %d scancode:%d sym:%d groupHotKey=%d \n",idx,key.keysym.scancode,key.keysym.sym,groupHotKey); - if (key.keysym.sym == groupHotKey) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - //printf("IS GROUP KEY %d scancode:%d sym:%d groupHotKey=%d \n",idx,key.keysym.scancode,key.keysym.sym,groupHotKey); - gui.groupKey (idx - 1); - return true; - } - } - return false; - } - - void Game::keyDown (SDL_KeyboardEvent key) - { - if (this->masterserverMode == true) - { - return; - } - - //printf("In game checking keypress for key [%d]\n",key.keysym.sym); - - try - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = [%c] [%d] gameStarted [%d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, key.keysym.sym, key.keysym.sym, - gameStarted); - if (gameStarted == false || totalRenderFps <= 0) - { - return; - } - if (currentUIState != NULL) - { - currentUIState->keyDown (key); - return; - } - - Lang & lang = Lang::getInstance (); - bool formerChatState = chatManager.getEditEnabled (); - //send key to the chat manager - chatManager.keyDown (key); - - if (formerChatState == false && chatManager.getEditEnabled ()) - { - camUpButtonDown = false; - camDownButtonDown = false; - camLeftButtonDown = false; - camRightButtonDown = false; - - gameCamera.stopMove (); - } - - //printf("GAME KEYDOWN #1\n"); - - if (chatManager.getEditEnabled () == false) - { - //printf("GAME KEYDOWN #2\n"); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = [%d - %c]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - key.keysym.sym, key.keysym.sym); - - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] key = [%d - %c] pausegame [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,key,key,configKeys.getCharKey("PauseGame")); - - //printf("SDL [%d] key [%d][%d]\n",configKeys.getSDLKey("SetMarker"),key.keysym.unicode,key.keysym.sym); - bool setMarkerKeyAllowsModifier = false; - if (configKeys.getSDLKey ("SetMarker") == SDLK_RALT || - configKeys.getSDLKey ("SetMarker") == SDLK_LALT) - { - setMarkerKeyAllowsModifier = true; - } - - //printf("In game checking keypress for key [%d] camera left [%d]\n",key.keysym.sym,configKeys.getSDLKey("CameraModeLeft")); - - if (isKeyPressed - (configKeys.getSDLKey ("RenderInGamePerformance"), key, - false) == true) - { - renderInGamePerformance = !renderInGamePerformance; - - Config::getInstance ().setBool ("PerformanceWarningEnabled", - renderInGamePerformance, true); - } - //if(key == configKeys.getCharKey("RenderNetworkStatus")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("RenderNetworkStatus"), key, - false) == true) - { - renderNetworkStatus = !renderNetworkStatus; - } - //else if(key == configKeys.getCharKey("ShowFullConsole")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("ShowFullConsole"), key, - false) == true) - { - showFullConsole = true; - } - else - if (isKeyPressed - (configKeys.getSDLKey ("SetMarker"), key, - setMarkerKeyAllowsModifier) == true) - { - setMarker = true; - printf("%d\n", key.keysym.scancode); - } - //else if(key == configKeys.getCharKey("TogglePhotoMode")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("TogglePhotoMode"), key, - false) == true) - { - photoModeEnabled = !photoModeEnabled; - if (photoModeEnabled == true && - this->gameSettings.isNetworkGame () == false) - { - gameCamera.setMaxHeight (PHOTO_MODE_MAXHEIGHT); - } - else if (photoModeEnabled == false) - { - gameCamera.setMaxHeight (-1); - } - - } - //Toggle Healthbars - else - if (isKeyPressed - (configKeys.getSDLKey ("ToggleHealthbars"), key, - false) == true) - { - switch (healthbarMode) - { - case hbvUndefined: - healthbarMode = hbvOff; - console.addLine (lang.getString ("Healthbar2") + ": " + - lang.getString ("HealthbarsOff")); - break; - case hbvOff: - healthbarMode = hbvAlways; - console.addLine (lang.getString ("Healthbar2") + ": " + - lang.getString ("HealthbarsAlways")); - break; - case hbvAlways: - healthbarMode = hbvIfNeeded; - console.addLine (lang.getString ("Healthbar2") + ": " + - lang.getString ("HealthbarsIfNeeded")); - break; - case hbvIfNeeded: - healthbarMode = hbvSelected; - console.addLine (lang.getString ("Healthbar2") + ": " + - lang.getString ("HealthbarsSelected")); - break; - case hbvSelected: - healthbarMode = hbvSelected | hbvIfNeeded; - console.addLine (lang.getString ("Healthbar2") + ": " + - lang.getString ("HealthbarsSelectedOrNeeded")); - break; - case (hbvSelected | hbvIfNeeded): - healthbarMode = hbvUndefined; - console.addLine (lang.getString ("Healthbar2") + ": " + - lang.getString ("HealthbarsFactionDefault")); - break; - default: - printf - ("In [%s::%s Line: %d] Toggle Healthbars Hotkey - Invalid Value. Setting to default.\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - healthbarMode = hbvUndefined; - break; - } - } - //Toggle music - //else if(key == configKeys.getCharKey("ToggleMusic")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("ToggleMusic"), key, false) == true) - { - - if (this->masterserverMode == false) - { - Config & config = Config::getInstance (); - StrSound *gameMusic = - world.getThisFaction ()->getType ()->getMusic (); - if (gameMusic != NULL) - { - float - configVolume = (config.getInt ("SoundVolumeMusic") / 100.f); - float currentVolume = gameMusic->getVolume (); - if (currentVolume > 0) - { - gameMusic->setVolume (0); - console.addLine (lang.getString ("GameMusic") + - " " + lang.getString ("Off")); - } - else - { - //If the config says zero, use the default music volume - gameMusic->setVolume (configVolume ? configVolume : 0.9); - console.addLine (lang.getString ("GameMusic")); - } - } - } - } - //move camera left - //else if(key == configKeys.getCharKey("CameraModeLeft")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("CameraModeLeft"), key, false) == true) - { - gameCamera.setMoveX (-1); - camLeftButtonDown = true; - } - //move camera right - //else if(key == configKeys.getCharKey("CameraModeRight")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("CameraModeRight"), key, - false) == true) - { - gameCamera.setMoveX (1); - camRightButtonDown = true; - } - //move camera up - //else if(key == configKeys.getCharKey("CameraModeUp")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("CameraModeUp"), key, false) == true) - { - gameCamera.setMoveZ (1); - camUpButtonDown = true; - } - //move camera down - //else if(key == configKeys.getCharKey("CameraModeDown")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("CameraModeDown"), key, false) == true) - { - gameCamera.setMoveZ (-1); - camDownButtonDown = true; - } - //change camera mode - //else if(key == configKeys.getCharKey("FreeCameraMode")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("FreeCameraMode"), key, false) == true) - { - if (gameCamera.getState () == GameCamera::sFree) - { - gameCamera.setState (GameCamera::sGame); - string - stateString = - gameCamera.getState () == - GameCamera:: - sGame ? lang.getString ("GameCamera") : - lang.getString ("FreeCamera"); - console.addLine (lang.getString ("CameraModeSet") + " " + - stateString); - } - else if (gameCamera.getState () == GameCamera::sGame) - { - gameCamera.setState (GameCamera::sFree); - string - stateString = - gameCamera.getState () == - GameCamera:: - sGame ? lang.getString ("GameCamera") : - lang.getString ("FreeCamera"); - console.addLine (lang.getString ("CameraModeSet") + " " + - stateString); - } - //else ignore! - } - //reset camera mode to normal - //else if(key == configKeys.getCharKey("ResetCameraMode")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("ResetCameraMode"), key, - false) == true) - { - if (currentCameraFollowUnit != NULL) - { - currentCameraFollowUnit = NULL; - } - gameCamera.setState (GameCamera::sGame); - } - //pause - //else if(key == configKeys.getCharKey("PauseGame")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("PauseGame"), key, false) == true) - { - //printf("Toggle pause paused = %d\n",paused); - //setPaused(!paused); - - bool allowAdminMenuItems = false; - NetworkManager & networkManager = NetworkManager::getInstance (); - NetworkRole role = networkManager.getNetworkRole (); - if (role == nrServer) - { - allowAdminMenuItems = true; - } - else if (role == nrClient) - { - ClientInterface *clientInterface = - dynamic_cast < - ClientInterface * >(networkManager.getClientInterface ()); - - if (clientInterface != NULL && - gameSettings.getMasterserver_admin () == - clientInterface->getSessionKey ()) - { - allowAdminMenuItems = true; - } - } - - if (allowAdminMenuItems) - { - if (getPaused () == false) - { - commander.tryPauseGame (false, false); - } - else - { - commander.tryResumeGame (false, false); - } - } - } - else - if (isKeyPressed - (configKeys.getSDLKey ("ExtraTeamColorMarker"), key, - false) == true) - { - //printf("Toggle ExtraTeamColorMarker\n"); - toggleTeamColorMarker (); - } - //switch display color - //else if(key == configKeys.getCharKey("ChangeFontColor")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("ChangeFontColor"), key, - false) == true) - { - gui.switchToNextDisplayColor (); - } - //increment speed - //else if(key == configKeys.getCharKey("GameSpeedIncrease")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("GameSpeedIncrease"), key, - false) == true) - { - bool - speedChangesAllowed = - !NetworkManager:: - getInstance ().isNetworkGameWithConnectedClients (); - if (speedChangesAllowed) - { - incSpeed (); - } - } - //decrement speed - //else if(key == configKeys.getCharKey("GameSpeedDecrease")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("GameSpeedDecrease"), key, - false) == true) - { - bool - speedChangesAllowed = - !NetworkManager:: - getInstance ().isNetworkGameWithConnectedClients (); - if (speedChangesAllowed) - { - decSpeed (); - } - } - else - if (isKeyPressed - (configKeys.getSDLKey ("BookmarkAdd"), key, false) == true) - { - startMarkCell (); - } - else - if (isKeyPressed - (configKeys.getSDLKey ("BookmarkRemove"), key, false) == true) - { - isUnMarkCellEnabled = true; - } - else - if (isKeyPressed - (configKeys.getSDLKey ("CameraFollowSelectedUnit"), key, - false) == true) - { - startCameraFollowUnit (); - } - //exit - else - if (isKeyPressed (configKeys.getSDLKey ("ExitKey"), key, false) - == true) - { - popupMenu.setEnabled (!popupMenu.getEnabled ()); - popupMenu.setVisible (popupMenu.getEnabled ()); - } - - //hotkeys - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] gameCamera.getState() = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - gameCamera.getState ()); - - if (gameCamera.getState () != GameCamera::sFree) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, key); - - gui.hotKey (key); - } - else - { - //rotate camera leftt - //if(key == configKeys.getCharKey("CameraRotateLeft")) { - if (isKeyPressed - (configKeys.getSDLKey ("CameraRotateLeft"), key) == true) - { - gameCamera.setRotate (-1); - } - //rotate camera right - //else if(key == configKeys.getCharKey("CameraRotateRight")){ - else - if (isKeyPressed - (configKeys.getSDLKey ("CameraRotateRight"), key) == true) - { - gameCamera.setRotate (1); - } - //camera up - //else if(key == configKeys.getCharKey("CameraRotateUp")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("CameraRotateUp"), key) == true) - { - gameCamera.setMoveY (1); - } - //camera down - //else if(key == configKeys.getCharKey("CameraRotateDown")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("CameraRotateDown"), key) == true) - { - gameCamera.setMoveY (-1); - } - } - - if (isKeyPressed (configKeys.getSDLKey ("SaveGame"), key) == true) - { - saveGame (); - } - } - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); - - NetworkManager & networkManager = NetworkManager::getInstance (); - if (networkManager.getGameNetworkInterface () != NULL) - { - GameNetworkInterface *networkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - networkInterface->sendTextMessage (szBuf, -1, true, ""); - sleep (10); - networkManager.getGameNetworkInterface ()->quitGame (true); - } - ErrorDisplayMessage (ex.what (), true); - } - } - - void Game::keyUp (SDL_KeyboardEvent key) - { - if (this->masterserverMode == true) - { - return; - } - - try - { - if (gameStarted == false || totalRenderFps <= 0) - { - return; - } - if (currentUIState != NULL) - { - currentUIState->keyUp (key); - return; - } - - if (chatManager.getEditEnabled ()) - { - //send key to the chat manager - chatManager.keyUp (key); - } - else - { - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - - //if(key == configKeys.getCharKey("ShowFullConsole")) { - if (isKeyPressed (configKeys.getSDLKey ("ShowFullConsole"), key) - == true) - { - showFullConsole = false; - } - else if (isKeyPressed (configKeys.getSDLKey ("SetMarker"), key) == - true + gameStarted = true; + totalRenderFps++; + + throw; + } + } + + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER + "\n", extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (showPerfStats && chronoPerf.getMillis() >= 50) { + for (unsigned int x = 0; x < (unsigned int) perfList.size(); ++x) { + printf("%s", perfList[x].c_str()); + } + } + } catch (const exception & ex) { + quitPendingIndicator = true; + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + //printf("#100 quitPendingIndicator = %d, errorMessageBox.getEnabled() = %d\n",quitPendingIndicator,errorMessageBox.getEnabled()); + + NetworkManager & networkManager = NetworkManager::getInstance(); + if (networkManager.getGameNetworkInterface() != NULL) { + GameNetworkInterface *networkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + networkInterface->sendTextMessage(szBuf, -1, true, ""); + sleep(10); + networkManager.getGameNetworkInterface()->quitGame(true); + } + if (errorMessageBox.getEnabled() == false) { + ErrorDisplayMessage(ex.what(), true); + } + } + } + + void Game::addPerformanceCount(string key, int64 value) { + gamePerformanceCounts[key] = value + gamePerformanceCounts[key] / 2; + } + + string Game::getGamePerformanceCounts(bool displayWarnings) const { + if (gamePerformanceCounts.empty() == true) { + return ""; + } + + bool displayWarningHeader = true; + bool + WARN_TO_CONSOLE = + Config::getInstance().getBool("PerformanceWarningEnabled", "false"); + int + WARNING_MILLIS = + Config::getInstance().getInt("PerformanceWarningMillis", "7"); + int + WARNING_RENDER_MILLIS = + Config::getInstance().getInt("PerformanceWarningRenderMillis", + "40"); + + string result = ""; + for (std::map < string, int64 >::const_iterator iterMap = + gamePerformanceCounts.begin(); + iterMap != gamePerformanceCounts.end(); ++iterMap) { + if (iterMap->first == ProgramState::MAIN_PROGRAM_RENDER_KEY) { + if (iterMap->second < WARNING_RENDER_MILLIS) { + continue; + } + //else { + // printf("iterMap->second: " MG_I64_SPECIFIER " WARNING_RENDER_MILLIS = %d\n",iterMap->second,WARNING_RENDER_MILLIS); + //} + } else if (iterMap->second < WARNING_MILLIS) { + continue; + } + + if (result != "") { + result += "\n"; + } + string + perfStat = + iterMap->first + " = avg millis: " + intToStr(iterMap->second); + + if (displayWarnings == true && WARN_TO_CONSOLE == true) { + if (displayWarningHeader == true) { + displayWarningHeader = false; + printf + ("=====================================\nPERFORMANCE WARNINGS for World Frame: %d\n", + world.getFrameCount()); + } + + printf("*PERFORMANCE WARNING* %s\n", perfStat.c_str()); + } + + result += perfStat; + } + + return result; + } + + bool + Game::switchSetupForSlots(ServerInterface * &serverInterface, + int startIndex, int endIndex, + bool onlyNetworkUnassigned) { + bool switchRequested = false; + if (serverInterface == NULL) { + return switchRequested; + } + + MutexSafeWrapper + safeMutex(serverInterface->getSwitchSetupRequestsMutex(), + CODE_AT_LINE); + SwitchSetupRequest **switchSetupRequests = + serverInterface->getSwitchSetupRequests(); + if (switchSetupRequests == NULL) { + return switchRequested; + } + + Map *map = world.getMap(); + for (int i = startIndex; i < endIndex; ++i) { + if (switchSetupRequests[i] != NULL) { + //printf("Faction Index: %d Switch slot = %d to = %d current control = %d\n",i,switchSetupRequests[i]->getCurrentSlotIndex(),switchSetupRequests[i]->getToSlotIndex(),gameSettings.getFactionControl(i)); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] switchSetupRequests[i]->getSwitchFlags() = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + switchSetupRequests[i]->getSwitchFlags + ()); + + if (onlyNetworkUnassigned == true + && gameSettings.getFactionControl(i) != ctNetworkUnassigned) { + if (i < map->getMaxPlayers() + || (i >= map->getMaxPlayers() + && gameSettings.getFactionControl(i) != ctNetwork)) { + continue; + } + } + + if (gameSettings.getFactionControl(i) == ctNetwork || + gameSettings.getFactionControl(i) == ctNetworkUnassigned || + //(gameSettings.getFactionControl(i) != ctClosed && gameSettings.getFactionControl(i) != ctHuman)) { + (gameSettings.getFactionControl(i) != ctHuman)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] switchSetupRequests[i]->getToFactionIndex() = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, + switchSetupRequests[i]->getToSlotIndex + ()); + + if (switchSetupRequests[i]->getToSlotIndex() != -1) { + int newSlotIdx = switchSetupRequests[i]->getToSlotIndex(); + + //printf("switchSlot request from %d to %d\n",switchSetupRequests[i]->getCurrentSlotIndex(),switchSetupRequests[i]->getToSlotIndex()); + + int + switchSlotIdx = + switchSetupRequests[i]->getCurrentSlotIndex(); + if (serverInterface->switchSlot(switchSlotIdx, newSlotIdx)) { + //printf("switchSlot returned true\n"); + switchRequested = true; + + int + oldFactionIndex = + gameSettings.getFactionIndexForStartLocation + (switchSlotIdx); + int newFactionIndex = + gameSettings.getFactionIndexForStartLocation(newSlotIdx); + + //printf("Switching faction for index %d [%d] to %d\n",newSlotIdx,switchSlotIdx,gameSettings.getFactionControl(newFactionIndex)); + + gameSettings.setNetworkPlayerName(oldFactionIndex, ""); + serverInterface-> + gameSettings.setNetworkPlayerName(oldFactionIndex, ""); + gameSettings.setNetworkPlayerUUID(oldFactionIndex, ""); + serverInterface-> + gameSettings.setNetworkPlayerUUID(oldFactionIndex, ""); + + gameSettings.setNetworkPlayerPlatform(oldFactionIndex, ""); + serverInterface-> + gameSettings.setNetworkPlayerPlatform(oldFactionIndex, ""); + + gameSettings.setFactionControl(newFactionIndex, ctNetwork); + serverInterface-> + gameSettings.setFactionControl(newFactionIndex, ctNetwork); + + //printf("#1a Faction Index: %d control: %d startlocation: %d\n",newFactionIndex,gameSettings.getFactionControl(newFactionIndex),gameSettings.getStartLocationIndex(newFactionIndex)); + //printf("#2a Faction Index: %d control: %d startlocation: %d\n",newFactionIndex,serverInterface->gameSettings.getFactionControl(newFactionIndex),serverInterface->gameSettings.getStartLocationIndex(newFactionIndex)); + + try { + //if(switchSetupRequests[i]->getSelectedFactionName() != "") { + // listBoxFactions[newFactionIdx].setSelectedItem(switchSetupRequests[i]->getSelectedFactionName()); + //} + //if(switchSetupRequests[i]->getToTeam() != -1) { + // listBoxTeams[newFactionIdx].setSelectedItemIndex(switchSetupRequests[i]->getToTeam()); + //} + if (switchSetupRequests[i]->getNetworkPlayerName() != "") { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] i = %d, labelPlayerNames[newFactionIdx].getText() [%s] switchSetupRequests[i]->getNetworkPlayerName() [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,labelPlayerNames[newFactionIdx].getText().c_str(),switchSetupRequests[i]->getNetworkPlayerName().c_str()); + gameSettings.setNetworkPlayerName(newFactionIndex, + switchSetupRequests + [i]->getNetworkPlayerName + ()); + serverInterface-> + gameSettings.setNetworkPlayerName(newFactionIndex, + switchSetupRequests + [i]->getNetworkPlayerName + ()); + } + + // if(gameSettings.getFactionControl(switchFactionIdx) == ctNetworkUnassigned) { + // serverInterface->removeSlot(switchFactionIdx); + // //listBoxControls[switchFactionIdx].setSelectedItemIndex(ctClosed); + // gameSettings.getFactionControl(switchFactionIdx) + // + // labelPlayers[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players); + // labelPlayerNames[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players); + // listBoxControls[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players); + // listBoxFactions[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players); + // listBoxTeams[switchFactionIdx].setVisible(switchFactionIdx+1 <= mapInfo.players); + // labelNetStatus[switchSlotIdx].setVisible(switchSlotIdx+1 <= mapInfo.players); + // } + } catch (const runtime_error & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + e.what()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] caught exception error = [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + e.what()); + } + } + //printf("AFTER switchSlot returned\n"); + } else { + try { + //if(switchSetupRequests[i]->getSelectedFactionName() != "") { + // listBoxFactions[i].setSelectedItem(switchSetupRequests[i]->getSelectedFactionName()); + //} + //if(switchSetupRequests[i]->getToTeam() != -1) { + // listBoxTeams[i].setSelectedItemIndex(switchSetupRequests[i]->getToTeam()); + //} + + if ((switchSetupRequests[i]->getSwitchFlags() & + ssrft_NetworkPlayerName) == ssrft_NetworkPlayerName) { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, switchSetupRequests[i]->getSwitchFlags() = %d, switchSetupRequests[i]->getNetworkPlayerName() [%s], labelPlayerNames[i].getText() [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,switchSetupRequests[i]->getSwitchFlags(),switchSetupRequests[i]->getNetworkPlayerName().c_str(),labelPlayerNames[i].getText().c_str()); + + if (switchSetupRequests[i]->getNetworkPlayerName() != + GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) { + //labelPlayerNames[i].setText(switchSetupRequests[i]->getNetworkPlayerName()); + gameSettings.setNetworkPlayerName(i, + switchSetupRequests + [i]->getNetworkPlayerName + ()); + serverInterface->gameSettings.setNetworkPlayerName(i, + switchSetupRequests + [i]->getNetworkPlayerName + ()); + switchRequested = true; + } else { + //labelPlayerNames[i].setText(""); + gameSettings.setNetworkPlayerName(i, ""); + serverInterface->gameSettings.setNetworkPlayerName(i, + ""); + switchRequested = true; + } + //SetActivePlayerNameEditor(); + //switchSetupRequests[i]->clearSwitchFlag(ssrft_NetworkPlayerName); + } + } catch (const runtime_error & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, e.what()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] caught exception error = [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, e.what()); + } + } + } + + delete switchSetupRequests[i]; + switchSetupRequests[i] = NULL; + } + } + + return switchRequested; + } + + void Game::updateNetworkMarkedCells() { + try { + GameNetworkInterface *gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + + if (gameNetworkInterface != NULL && + gameNetworkInterface->getMarkedCellList(false).empty() == false) { + + std::vector < MarkedCell > chatList = + gameNetworkInterface->getMarkedCellList(true); + for (int idx = 0; idx < (int) chatList.size(); idx++) { + MarkedCell mc = chatList[idx]; + if (mc.getFactionIndex() >= 0) { + mc. + setFaction((const Faction *) + world.getFaction(mc.getFactionIndex())); + } + + Map *map = world.getMap(); + Vec2i surfaceCellPos = map->toSurfCoords(mc.getTargetPos()); + mapMarkedCellList[surfaceCellPos] = mc; + } + } + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + } + + void Game::updateNetworkUnMarkedCells() { + try { + GameNetworkInterface *gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + + if (gameNetworkInterface != NULL && + gameNetworkInterface->getUnMarkedCellList(false).empty() == + false) { + //Lang &lang= Lang::getInstance(); + + std::vector < UnMarkedCell > chatList = + gameNetworkInterface->getUnMarkedCellList(true); + for (int idx = 0; idx < (int) chatList.size(); idx++) { + UnMarkedCell mc = chatList[idx]; + mc. + setFaction((const Faction *) + world.getFaction(mc.getFactionIndex())); + + Map *map = world.getMap(); + Vec2i surfaceCellPos = map->toSurfCoords(mc.getTargetPos()); + mapMarkedCellList.erase(surfaceCellPos); + } + } + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + } + + + void Game::updateNetworkHighligtedCells() { + try { + GameNetworkInterface *gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + + //update the current entries + for (int idx = (int) highlightedCells.size() - 1; idx >= 0; idx--) { + MarkedCell *mc = &highlightedCells[idx]; + mc->decrementAliveCount(); + if (mc->getAliveCount() < 0) { + highlightedCells.erase(highlightedCells.begin() + idx); + } + } + + if (gameNetworkInterface != NULL && + gameNetworkInterface->getHighlightedCellList(false).empty() == + false) { + //Lang &lang= Lang::getInstance(); + std::vector < MarkedCell > highlighList = + gameNetworkInterface->getHighlightedCellList(true); + for (int idx = 0; idx < (int) highlighList.size(); idx++) { + MarkedCell mc = highlighList[idx]; // I want a copy here + if (mc.getFactionIndex() >= 0) { + mc.setFaction((const Faction *) world.getFaction(mc.getFactionIndex())); // set faction pointer + } + addOrReplaceInHighlightedCells(mc); + } + } + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + } + + void Game::addOrReplaceInHighlightedCells(MarkedCell mc) { + if (mc.getFactionIndex() >= 0) { + for (int i = (int) highlightedCells.size() - 1; i >= 0; i--) { + MarkedCell *currentMc = &highlightedCells[i]; + if (currentMc->getFactionIndex() == mc.getFactionIndex()) { + highlightedCells.erase(highlightedCells.begin() + i); + } + } + } + if (mc.getAliveCount() <= 0) { + mc.setAliveCount(200); + } + highlightedCells.push_back(mc); + + if (this->masterserverMode == false) { + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + + const Faction *faction = mc.getFaction(); + if (getWorld()->getThisFaction() == NULL) { + throw + megaglest_runtime_error("getWorld()->getThisFaction() == NULL"); + } + //printf("faction [%p][%s]\n",faction,(faction != NULL ? faction->getType()->getName().c_str() : "")); + if ((faction == NULL) || + (faction->getTeam() == + getWorld()->getThisFaction()->getTeam())) { + static PlaySoundClip snd; + soundRenderer.playFx(snd.getSound(snd.sfxMarker), true); + } + } + } + + void + Game::ReplaceDisconnectedNetworkPlayersWithAI(bool isNetworkGame, + NetworkRole role) { + if (role == nrServer && isNetworkGame == true && + difftime((long int) time(NULL), + lastNetworkPlayerConnectionCheck) >= + NETWORK_PLAYER_CONNECTION_CHECK_SECONDS) { + lastNetworkPlayerConnectionCheck = time(NULL); + Logger & logger = Logger::getInstance(); + ServerInterface *server = + NetworkManager::getInstance().getServerInterface(); + + bool newAIPlayerCreated = false; + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + if (faction->getFactionDisconnectHandled() == false && + (faction->getControlType() == ctNetwork || + faction->getControlType() == ctNetworkCpuEasy || + faction->getControlType() == ctNetworkCpu || + faction->getControlType() == ctNetworkCpuUltra || + faction->getControlType() == ctNetworkCpuZeta)) { + + if (aiInterfaces[i] == NULL && + server-> + isClientConnected(faction->getStartLocationIndex()) == + false) { + + if (faction->getPersonalityType() != fpt_Observer) { + DumpCRCWorldLogIfRequired("_faction_" + intToStr(i)); + } + + faction->setFactionDisconnectHandled(true); + + Lang & lang = Lang::getInstance(); + + bool isPlayerObserver = false; + char szBuf[8096] = ""; + if (faction->getPersonalityType() != fpt_Observer) { + aiInterfaces[i] = + new AiInterface(*this, i, faction->getTeam(), + faction->getStartLocationIndex()); + + snprintf(szBuf, 8096, + Lang::getInstance().getString + ("LogScreenGameLoadingCreatingAIFaction", + "", true).c_str(), i); + logger.add(szBuf, true); + + commander.tryNetworkPlayerDisconnected(i); + + newAIPlayerCreated = true; + } else { + isPlayerObserver = true; + + } + + const + vector < + string > + languageList = + this->gameSettings.getUniqueNetworkPlayerLanguages(); + for (unsigned int j = 0; + j < (unsigned int) languageList.size(); ++j) { + if (isPlayerObserver == false) { + string + msg = + "Player #%d [%s] has disconnected, switching player to AI mode!"; + if (lang.hasString("GameSwitchPlayerToAI", + languageList[j], true)) { + msg = + lang.getString("GameSwitchPlayerToAI", + languageList[j], true); + } + snprintf(szBuf, 8096, msg.c_str(), i + 1, + this->gameSettings.getNetworkPlayerName(i). + c_str()); + } else { + string + msg = + "Player #%d [%s] has disconnected, but player was only an observer!"; + if (lang.hasString("GameSwitchPlayerObserverToAI", + languageList[j], true)) { + msg = + lang.getString("GameSwitchPlayerObserverToAI", + languageList[j], true); + } + snprintf(szBuf, 8096, msg.c_str(), i + 1, + this->gameSettings.getNetworkPlayerName(i). + c_str()); + } + bool localEcho = (languageList[j] == lang.getLanguage()); + server->sendTextMessage(szBuf, -1, localEcho, + languageList[j]); + } + } + } + } + + if (newAIPlayerCreated == true + && Config::getInstance().getBool("EnableNewThreadManager", + "false") == true) { + bool + enableServerControlledAI = + this->gameSettings.getEnableServerControlledAI(); + + masterController.clearSlaves(true); + + std::vector < SlaveThreadControllerInterface * >slaveThreadList; + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + if (faction->getCpuControl + (enableServerControlledAI, isNetworkGame, role) == true) { + slaveThreadList.push_back(aiInterfaces[i]->getWorkerThread()); + } + } + masterController.setSlaves(slaveThreadList); + } + } + } + + void Game::updateCamera() { + if (currentUIState != NULL) { + currentUIState->updateCamera(); + return; + } + gameCamera.update(); + } + + + // ==================== render ==================== + + //render + void Game::render() { + // Ensure the camera starts in the right position + if (isFirstRender == true) { + isFirstRender = false; + + if (this->loadGameNode == NULL) { + gameCamera.setState(GameCamera::sGame); + this->restoreToStartXY(); + } + } + + canRender(); + incrementFps(); + + renderFps++; + totalRenderFps++; + + updateWorldStats(); + + //NetworkManager &networkManager= NetworkManager::getInstance(); + if (this->masterserverMode == false) { + renderWorker(); + } else { + // Titi, uncomment this to watch the game on the masterserver + //renderWorker(); + + // In masterserver mode quit game if no network players left + ServerInterface *server = + NetworkManager::getInstance().getServerInterface(); + int connectedClients = 0; + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + if (server->isClientConnected(faction->getStartLocationIndex()) == + true) { + connectedClients++; + } + } + + if (connectedClients == 0) { + quitTriggeredIndicator = true; + } else { + string str = ""; + std::map < int, string > factionDebugInfo; + + if (difftime + ((long int) time(NULL), + lastMasterServerGameStatsDump) >= GAME_STATS_DUMP_INTERVAL) { + lastMasterServerGameStatsDump = time(NULL); + str = getDebugStats(factionDebugInfo); + + printf("== Current in-game stats (interval %d) ==\n%s\n", + GAME_STATS_DUMP_INTERVAL, str.c_str()); + } + } + } + } + + void Game::renderWorker() { + if (currentUIState != NULL) { + // Renderer &renderer= Renderer::getInstance(); + // renderer.clearBuffers(); + // + // //3d + // renderer.reset3dMenu(); + // + // renderer.clearZBuffer(); + // //renderer.loadCameraMatrix(menuBackground.getCamera()); + // //renderer.renderMenuBackground(&menuBackground); + // renderer.renderParticleManager(rsMenu); + // + // //2d + // renderer.reset2d(); + // + // currentUIState->render(); + // + // if(renderer.isMasterserverMode() == false) { + // renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim); + // renderer.renderFPSWhenEnabled(lastFps); + // renderer.swapBuffers(); + // } + + currentUIState->render(); + return; + } else { + Renderer & renderer = Renderer::getInstance(); + if (renderer.getCustom3dMenu() != NULL) { + renderer.setCustom3dMenu(NULL); + } + } + + Chrono chrono; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled) + chrono.start(); + + render3d(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %d [render3d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + render2d(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %d [render2d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + Renderer::getInstance().swapBuffers(); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %d [swap buffers]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + } + + // ==================== tick ==================== + + void Game::removeUnitFromSelection(const Unit * unit) { + try { + Selection *selection = gui.getSelectionPtr(); + for (int i = 0; i < selection->getCount(); ++i) { + const Unit *currentUnit = selection->getUnit(i); + if (currentUnit == unit) { + selection->unSelect(i); + break; + } + } + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + if (errorMessageBox.getEnabled() == false) { + ErrorDisplayMessage(ex.what(), true); + } + + //abort(); + } + } + + bool Game::addUnitToSelection(Unit * unit) { + bool result = false; + try { + Selection *selection = gui.getSelectionPtr(); + if (selection != NULL) { + result = selection->select(unit, true); + } + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + if (errorMessageBox.getEnabled() == false) { + ErrorDisplayMessage(ex.what(), true); + } + + //abort(); + } + + return result; + } + + void Game::addUnitToGroupSelection(Unit * unit, int groupIndex) { + try { + Selection *selection = gui.getSelectionPtr(); + if (selection != NULL) { + selection->addUnitToGroup(groupIndex, unit); + } + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + if (errorMessageBox.getEnabled() == false) { + ErrorDisplayMessage(ex.what(), true); + } + + //abort(); + } + } + + void Game::removeUnitFromGroupSelection(int unitId, int groupIndex) { + try { + Selection *selection = gui.getSelectionPtr(); + if (selection != NULL) { + selection->removeUnitFromGroup(groupIndex, unitId); + } + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + if (errorMessageBox.getEnabled() == false) { + ErrorDisplayMessage(ex.what(), true); + } + + //abort(); + } + } + + void Game::recallGroupSelection(int groupIndex) { + try { + Selection *selection = gui.getSelectionPtr(); + if (selection != NULL) { + selection->recallGroup(groupIndex); + } + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + if (errorMessageBox.getEnabled() == false) { + ErrorDisplayMessage(ex.what(), true); + } + + //abort(); + } + } + + void Game::tick() { + ProgramState::tick(); + + tickCount++; + + if (avgUpdateFps == -1) { + avgUpdateFps = updateFps; + } else { + avgUpdateFps = (avgUpdateFps + updateFps) / 2; + } + currentAvgRenderFpsTotal += renderFps; + + if (avgRenderFps == -1) { + avgRenderFps = renderFps; + } + // Update the average every x game ticks + const int CHECK_AVG_FPS_EVERY_X_TICKS = 15; + if (tickCount % CHECK_AVG_FPS_EVERY_X_TICKS == 0) { + avgRenderFps = currentAvgRenderFpsTotal / CHECK_AVG_FPS_EVERY_X_TICKS; + currentAvgRenderFpsTotal = 0; + } + + if (captureAvgTestStatus == true) { + if (updateFpsAvgTest == -1) { + updateFpsAvgTest = updateFps; + } else { + updateFpsAvgTest = (updateFpsAvgTest + updateFps) / 2; + } + if (renderFpsAvgTest == -1) { + renderFpsAvgTest = renderFps; + } else { + renderFpsAvgTest = (renderFpsAvgTest + renderFps) / 2; + } + } + + lastUpdateFps = updateFps; + lastRenderFps = renderFps; + updateFps = 0; + renderFps = 0; + + //Win/lose check + checkWinner(); + gui.tick(); + } + + + // ==================== events ==================== + + int Game::getFirstUnusedTeamNumber() { + std::map < int, bool > uniqueTeamNumbersUsed; + for (unsigned int i = 0; i < (unsigned int) world.getFactionCount(); + ++i) { + Faction *faction = world.getFaction(i); + uniqueTeamNumbersUsed[faction->getTeam()] = true; + } + + int result = -1; + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + if (uniqueTeamNumbersUsed.find(i) == uniqueTeamNumbersUsed.end()) { + result = i; + break; + } + } + + return result; + } + + void Game::setupRenderForVideo() { + Renderer & renderer = Renderer::getInstance(); + //renderer.clearBuffers(); + //3d + //renderer.reset3dMenu(); + //renderer.clearZBuffer(); + //2d + //renderer.reset2d(); + renderer.setupRenderForVideo(); + } + + void Game::tryPauseToggle(bool pauseValue) { + bool allowAdminMenuItems = false; + NetworkManager & networkManager = NetworkManager::getInstance(); + NetworkRole role = networkManager.getNetworkRole(); + if (role == nrServer) { + allowAdminMenuItems = true; + } else if (role == nrClient) { + ClientInterface *clientInterface = + dynamic_cast < + ClientInterface *>(networkManager.getClientInterface()); + + if (clientInterface != NULL && + gameSettings.getMasterserver_admin() == + clientInterface->getSessionKey()) { + allowAdminMenuItems = true; + } + } + + bool isNetworkGame = this->gameSettings.isNetworkGame(); + //printf("Try Pause allowAdminMenuItems = %d, pauseValue = %d\n",allowAdminMenuItems,pauseValue); + + if (allowAdminMenuItems) { + if (pauseValue == true) { + commander.tryPauseGame(false, false); + } else { + if (isNetworkGame == false) { + setPaused(pauseValue, true, false, false); + } else { + commander.tryResumeGame(false, false); + } + } + } + } + + void Game::startMarkCell() { + int totalMarkedCellsForPlayer = 0; + if (world.getThisFaction() != NULL) { + for (std::map < Vec2i, MarkedCell >::iterator iterMap = + mapMarkedCellList.begin(); + iterMap != mapMarkedCellList.end(); ++iterMap) { + MarkedCell & bm = iterMap->second; + if (bm.getPlayerIndex() == + world.getThisFaction()->getStartLocationIndex()) { + totalMarkedCellsForPlayer++; + } + } + } + + const int MAX_MARKER_COUNT = 5; + if (totalMarkedCellsForPlayer < MAX_MARKER_COUNT) { + isMarkCellEnabled = true; + } else { + Lang & lang = Lang::getInstance(); + console.addLine(lang.getString("MaxMarkerCount") + " " + + intToStr(MAX_MARKER_COUNT)); + } + } + + void Game::processInputText(string text, bool cancelled) { + isMarkCellTextEnabled = false; + + if (cancelled == false) { + //printf("Note [%s]\n",text.c_str()); + + cellMarkedData.setNote(text); + addCellMarker(cellMarkedPos, cellMarkedData); + + // if(text.find("\\n") != text.npos) { + // replaceAll(text, "\\n", "\n"); + // } + // if(text.find("\\t") != text.npos) { + // replaceAll(text, "\\t", "\t"); + // } + // + // cellMarkedData.setNote(text); + // mapMarkedCellList[cellMarkedPos] = cellMarkedData; + // + // GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); + // + // int factionIndex = -1; + // int playerIndex = -1; + // if(cellMarkedData.getFaction() != NULL) { + // factionIndex = cellMarkedData.getFaction()->getIndex(); + // playerIndex = cellMarkedData.getFaction()->getStartLocationIndex(); + // } + // gameNetworkInterface->sendMarkCellMessage( + // cellMarkedData.getTargetPos(), + // factionIndex, + // cellMarkedData.getNote(), + // playerIndex); + // + // Renderer &renderer= Renderer::getInstance(); + // renderer.forceQuadCacheUpdate(); + } + } + + void Game::addCellMarker(Vec2i cellPos, MarkedCell cellData) { + //printf("Note [%s]\n",text.c_str()); + + string text = cellData.getNote(); + if (text.find("\\n") != text.npos) { + replaceAll(text, "\\n", "\n"); + } + if (text.find("\\t") != text.npos) { + replaceAll(text, "\\t", "\t"); + } + + cellData.setNote(text); + mapMarkedCellList[cellPos] = cellData; + + GameNetworkInterface *gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + + int factionIndex = -1; + int playerIndex = -1; + if (cellData.getFaction() != NULL) { + factionIndex = cellData.getFaction()->getIndex(); + playerIndex = cellData.getFaction()->getStartLocationIndex(); + } + + //printf("Adding Cell marker pos [%s] factionIndex [%d] note [%s] playerIndex = %d\n",cellData.getTargetPos().getString().c_str(),factionIndex,cellData.getNote().c_str(),playerIndex); + + gameNetworkInterface->sendMarkCellMessage(cellData.getTargetPos(), + factionIndex, + cellData.getNote(), + playerIndex); + + Renderer & renderer = Renderer::getInstance(); + renderer.forceQuadCacheUpdate(); + } + + void + Game::removeCellMarker(Vec2i surfaceCellPos, const Faction * faction) { + //Vec2i surfaceCellPos = map->toSurfCoords(Vec2i(xCell,yCell)); + Map *map = world.getMap(); + SurfaceCell *sc = map->getSurfaceCell(surfaceCellPos); + Vec3f vertex = sc->getVertex(); + Vec2i targetPos(vertex.x, vertex.z); + + //printf("Remove Cell marker lookup pos [%s] factionIndex [%d]\n",surfaceCellPos.getString().c_str(),(faction != NULL ? faction->getIndex() : -1)); + + if (mapMarkedCellList.find(surfaceCellPos) != mapMarkedCellList.end()) { + MarkedCell mc = mapMarkedCellList[surfaceCellPos]; + if (mc.getFaction() == faction) { + mapMarkedCellList.erase(surfaceCellPos); + GameNetworkInterface *gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + + int factionIndex = (faction != NULL ? faction->getIndex() : -1); + + //printf("Remvoing Cell marker pos [%s] factionIndex [%d] note [%s]\n",mc.getTargetPos().getString().c_str(),factionIndex,mc.getNote().c_str()); + + gameNetworkInterface->sendUnMarkCellMessage(mc.getTargetPos(), + factionIndex); + } + } + //printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size()); + + //isUnMarkCellEnabled = false; + + Renderer & renderer = Renderer::getInstance(); + //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos); + renderer.forceQuadCacheUpdate(); + } + void Game::showMarker(Vec2i cellPos, MarkedCell cellData) { + //setMarker = true; + //if(setMarker) { + //Vec2i targetPos = cellData.targetPos; + //Vec2i screenPos(x,y-60); + //Renderer &renderer= Renderer::getInstance(); + //renderer.computePosition(screenPos, targetPos); + //Vec2i surfaceCellPos = map->toSurfCoords(targetPos); + + //MarkedCell mc(targetPos,world.getThisFaction(),"none",world.getThisFaction()->getStartLocationIndex()); + addOrReplaceInHighlightedCells(cellData); + + GameNetworkInterface *gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + gameNetworkInterface-> + sendHighlightCellMessage(cellData.getTargetPos(), + cellData.getFactionIndex()); + //} + } + + void Game::mouseDownLeft(int x, int y) { + if (this->masterserverMode == true) { + return; + } + cameraDragAllowed = false; + if (currentUIState != NULL) { + currentUIState->mouseDownLeft(x, y); + return; + } + + try { + if (gameStarted == false || totalRenderFps <= 0) { + Logger::getInstance().handleMouseClick(x, y); + return; + } + + Map *map = world.getMap(); + const Metrics & metrics = Metrics::getInstance(); + NetworkManager & networkManager = NetworkManager::getInstance(); + bool messageBoxClick = false; + bool originalIsMarkCellEnabled = isMarkCellEnabled; + bool originalIsUnMarkCellEnabled = isUnMarkCellEnabled; + + if (popupMenu.mouseClick(x, y)) { + std::pair < int, + string > result = popupMenu.mouseClickedMenuItem(x, y); + //printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first); + + //printf("popupMenu.mouseClick == true result.first = %d disconnectPlayerPopupMenuIndex = %d\n",result.first,disconnectPlayerPopupMenuIndex); + + popupMenu.setEnabled(false); + popupMenu.setVisible(false); + + // Exit game + if (result.first == exitGamePopupMenuIndex) { + showMessageBox(Lang:: + getInstance().getString("ExitBattleQuestion"), + "", true); + } else if (result.first == joinTeamPopupMenuIndex) { + + Lang & lang = Lang::getInstance(); + switchTeamIndexMap.clear(); + std::map < int, bool > uniqueTeamNumbersUsed; + std::vector < string > menuItems; + for (unsigned int i = 0; + i < (unsigned int) world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + + if (faction->getPersonalityType() != fpt_Observer && + uniqueTeamNumbersUsed.find(faction->getTeam()) == + uniqueTeamNumbersUsed.end()) { + uniqueTeamNumbersUsed[faction->getTeam()] = true; + } + + if (faction->getPersonalityType() != fpt_Observer && + world.getThisFaction()->getIndex() != + faction->getIndex() + && world.getThisFaction()->getTeam() != + faction->getTeam()) { + char szBuf[8096] = ""; + if (lang.hasString("JoinPlayerTeam") == true) { + snprintf(szBuf, 8096, + (" " + + lang.getString("JoinPlayerTeam") + + " ").c_str(), faction->getIndex(), + this->gameSettings.getNetworkPlayerName(i). + c_str(), faction->getTeam()); + } else { + snprintf(szBuf, 8096, + " Join player #%d - %s on Team: %d ", + faction->getIndex(), + this->gameSettings.getNetworkPlayerName(i). + c_str(), faction->getTeam()); + } + + menuItems.push_back(szBuf); + + switchTeamIndexMap[(int) menuItems.size() - 1] = + faction->getTeam(); + } + } + + if ((int) uniqueTeamNumbersUsed.size() < 8) { + menuItems.push_back(" " + + lang.getString("CreateNewTeam") + " "); + switchTeamIndexMap[(int) menuItems.size() - 1] = + CREATE_NEW_TEAM; + } + menuItems.push_back(" " + lang.getString("Cancel") + " "); + switchTeamIndexMap[(int) menuItems.size() - 1] = + CANCEL_SWITCH_TEAM; + + popupMenuSwitchTeams.setW(100); + popupMenuSwitchTeams.setH(100); + popupMenuSwitchTeams.init(" " + + lang.getString("SwitchTeams") + + " ", menuItems); + popupMenuSwitchTeams.setEnabled(true); + popupMenuSwitchTeams.setVisible(true); + } else if (result.first == disconnectPlayerPopupMenuIndex) { + Lang & lang = Lang::getInstance(); + + NetworkManager & networkManager = NetworkManager::getInstance(); + NetworkRole role = networkManager.getNetworkRole(); + ServerInterface *serverInterface = NULL; + if (role == nrServer) { + serverInterface = + dynamic_cast < + ServerInterface *>(networkManager.getServerInterface()); + } + disconnectPlayerIndexMap.clear(); + std::vector < string > menuItems; + for (unsigned int i = 0; + i < (unsigned int) world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + + //printf("faction->getPersonalityType() = %d index [%d,%d] control [%d] networkstatus [%d]\n",faction->getPersonalityType(),world.getThisFaction()->getIndex(),faction->getIndex(),faction->getControlType(),this->gameSettings.getNetworkPlayerStatuses(i)); + + bool isSlotJoinInProgressClient = false; + if (serverInterface != NULL) { + + MutexSafeWrapper + safeMutex(serverInterface->getSlotMutex + (faction->getStartLocationIndex()), + CODE_AT_LINE); + ConnectionSlot *slot = + serverInterface->getSlot(faction->getStartLocationIndex(), + false); + if (slot != NULL + && slot->getConnectHasHandshaked() == true + && slot->getCurrentFrameCount() <= 0) { + isSlotJoinInProgressClient = true; + } + } + + //printf("isSlotJoinInProgressClient: %d [%d] [%d][%d] [%d] [%d] [%d]\n", + // isSlotJoinInProgressClient,faction->getPersonalityType(),faction->getIndex(),world.getThisFaction()->getIndex(),faction->getControlType(),this->gameSettings.getNetworkPlayerStatuses(i),i); + + if (isSlotJoinInProgressClient == true || + (faction->getPersonalityType() != fpt_Observer && + world.getThisFaction()->getIndex() != + faction->getIndex() + && faction->getControlType() == ctNetwork + && this->gameSettings.getNetworkPlayerStatuses(i) != + npst_Disconnected)) { + + char szBuf[8096] = ""; + if (lang.hasString("DisconnectNetorkPlayerIndex") == true) { + snprintf(szBuf, 8096, + (" " + + lang.getString + ("DisconnectNetorkPlayerIndex") + + " ").c_str(), + faction->getIndex() + 1, + this->gameSettings.getNetworkPlayerName(i). + c_str()); + } else { + snprintf(szBuf, 8096, + " Disconnect player #%d - %s: ", + faction->getIndex() + 1, + this->gameSettings.getNetworkPlayerName(i). + c_str()); + } + + menuItems.push_back(szBuf); + + //disconnectPlayerIndexMap[menuItems.size()-1] = faction->getStartLocationIndex(); + disconnectPlayerIndexMap[(int) menuItems.size() - + 1] = faction->getIndex(); + } + } + + menuItems.push_back(" " + lang.getString("Cancel") + " "); + disconnectPlayerIndexMap[(int) menuItems.size() - 1] = + CANCEL_DISCONNECT_PLAYER; + + popupMenuDisconnectPlayer.setW(100); + popupMenuDisconnectPlayer.setH(100); + popupMenuDisconnectPlayer.init(" " + + lang.getString + ("DisconnectNetorkPlayer") + + " ", menuItems); + popupMenuDisconnectPlayer.setEnabled(true); + popupMenuDisconnectPlayer.setVisible(true); + } else if (result.first == keyboardSetupPopupMenuIndex) { + MainMenu *newMenu = new MainMenu(program); // open keyboard shortcuts setup screen + currentUIState = newMenu; + Renderer & renderer = Renderer::getInstance(); + renderer.setCustom3dMenu(newMenu); + //currentUIState->load(); + currentUIState->init(); + + // open keyboard shortcuts setup screen + newMenu->setState(new + MenuStateKeysetup(program, newMenu, + ¤tUIState)); + } else if (result.first == pauseGamePopupMenuIndex) { + //this->setPaused(!paused); + //printf("popup paused = %d\n",paused); + + bool allowAdminMenuItems = false; + NetworkRole role = networkManager.getNetworkRole(); + if (role == nrServer) { + allowAdminMenuItems = true; + } else if (role == nrClient) { + ClientInterface *clientInterface = + dynamic_cast < + ClientInterface *>(networkManager.getClientInterface()); + + if (clientInterface != NULL && + gameSettings.getMasterserver_admin() == + clientInterface->getSessionKey()) { + allowAdminMenuItems = true; + } + } + + if (allowAdminMenuItems) { + if (getPaused() == false) { + commander.tryPauseGame(false, false); + } else { + commander.tryResumeGame(false, false); + } + } + } else if (result.first == saveGamePopupMenuIndex) { + saveGame(); + } + //else if(result.first == markCellPopupMenuIndex) { + // startMarkCell(); + //} + //else if(result.first == unmarkCellPopupMenuIndex) { + // isUnMarkCellEnabled = true; + //} + } else if (popupMenuSwitchTeams.mouseClick(x, y)) { + //popupMenuSwitchTeams + std::pair < int, + string > + result = popupMenuSwitchTeams.mouseClickedMenuItem(x, y); + //printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first); + + popupMenuSwitchTeams.setEnabled(false); + popupMenuSwitchTeams.setVisible(false); + + //bool isNetworkGame = this->gameSettings.isNetworkGame(); + + int teamIndex = switchTeamIndexMap[result.first]; + switch (teamIndex) { + case CREATE_NEW_TEAM: + { + int newTeam = getFirstUnusedTeamNumber(); + //if(isNetworkGame == true) { + const Faction *faction = world.getThisFaction(); + commander.trySwitchTeam(faction, newTeam); + //} + //else { + // const Faction *faction = world.getThisFaction(); + // commander.trySwitchTeam(faction,newTeam); + //} + } + break; + case CANCEL_SWITCH_TEAM: + break; + default: + //if(isNetworkGame == true) { + const Faction *faction = world.getThisFaction(); + commander.trySwitchTeam(faction, teamIndex); + //} + //else { + // const Faction *faction = world.getThisFaction(); + // commander.trySwitchTeam(faction,teamIndex); + //} + + break; + } + } else if (popupMenuDisconnectPlayer.mouseClick(x, y)) { + //popupMenuSwitchTeams + std::pair < int, + string > + result = popupMenuDisconnectPlayer.mouseClickedMenuItem(x, y); + //printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first); + + popupMenuDisconnectPlayer.setEnabled(false); + popupMenuDisconnectPlayer.setVisible(false); + + //bool isNetworkGame = this->gameSettings.isNetworkGame(); + + //int playerIndex = disconnectPlayerIndexMap[result.first]; + int factionIndex = disconnectPlayerIndexMap[result.first]; + switch (factionIndex) { + case CANCEL_DISCONNECT_PLAYER: + break; + default: + // if(isNetworkGame == true) { + // const Faction *faction = world.getThisFaction(); + // commander.trySwitchTeam(faction,teamIndex); + // } + // else { + // const Faction *faction = world.getThisFaction(); + // commander.trySwitchTeam(faction,teamIndex); + // } + + + GameSettings * settings = world.getGameSettingsPtr(); + Lang & lang = Lang::getInstance(); + + char szBuf[8096] = ""; + if (lang.hasString("DisconnectNetorkPlayerIndexConfirm") == true) { + snprintf(szBuf, 8096, + (" " + + lang.getString + ("DisconnectNetorkPlayerIndexConfirm") + + " ").c_str(), factionIndex + 1, + settings-> + getNetworkPlayerName(factionIndex).c_str()); + } else { + snprintf(szBuf, 8096, + " Confirm disconnection for player #%d - %s? ", + factionIndex + 1, + settings-> + getNetworkPlayerName(factionIndex).c_str()); + } + + disconnectPlayerConfirmMessageBox.setText(szBuf); + disconnectPlayerConfirmMessageBox.init(lang.getString("Yes"), + lang.getString("No")); + disconnectPlayerConfirmMessageBox.setEnabled(true); + + playerIndexDisconnect = + world.getFaction(factionIndex)->getStartLocationIndex(); + + GameNetworkInterface *gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + if (gameNetworkInterface != NULL) { + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = settings->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; + i < (unsigned int) languageList.size(); ++i) { + char szMsg[8096] = ""; + if (lang.hasString("DisconnectNetorkPlayerIndexConfirmed", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString + ("DisconnectNetorkPlayerIndexConfirmed", + languageList[i]).c_str(), + factionIndex + 1, + settings->getNetworkPlayerName + (factionIndex).c_str()); + } else { + snprintf(szMsg, 8096, + "Notice - Admin is warning to disconnect player #%d - %s!", + factionIndex + 1, + settings->getNetworkPlayerName + (factionIndex).c_str()); + } + bool localEcho = lang.isLanguageLocal(languageList[i]); + gameNetworkInterface->sendTextMessage(szMsg, -1, + localEcho, + languageList[i]); + } + + sleep(10); + } + + break; + } + } + + if (switchTeamConfirmMessageBox.getEnabled() == true) { + int button = -1; + if (switchTeamConfirmMessageBox.mouseClick(x, y, button)) { + switchTeamConfirmMessageBox.setEnabled(false); + + SwitchTeamVote *vote = + world.getThisFactionPtr()-> + getSwitchTeamVote(world.getThisFaction + ()->getCurrentSwitchTeamVoteFactionIndex()); + vote->voted = true; + vote->allowSwitchTeam = (button == 0); + + const Faction *faction = world.getThisFaction(); + commander.trySwitchTeamVote(faction, vote); + } + } else if (disconnectPlayerConfirmMessageBox.getEnabled() == true) { + int button = -1; + if (disconnectPlayerConfirmMessageBox.mouseClick(x, y, button)) { + disconnectPlayerConfirmMessageBox.setEnabled(false); + + if (button == 0) { + const Faction *faction = world.getThisFaction(); + commander.tryDisconnectNetworkPlayer(faction, + playerIndexDisconnect); + } + } + } + + //scrip message box, only if the exit box is not enabled + if (mainMessageBox.getEnabled() == false && + errorMessageBox.getEnabled() == false && + scriptManager.getMessageBox()->getEnabled()) { + int button = 0; + if (scriptManager.getMessageBox()->mouseClick(x, y, button)) { + scriptManager.onMessageBoxOk(); + messageBoxClick = true; + } + } + + //minimap panel + if (messageBoxClick == false) { + if (metrics.isInMinimap(x, y)) { + int xm = x - metrics.getMinimapX(); + int ym = y - metrics.getMinimapY(); + int + xCell = + static_cast < + int>(xm * + (static_cast < + float>(map->getW()) / metrics.getMinimapW())); + int + yCell = + static_cast < + int>(map->getH() - + ym * (static_cast < + float>(map->getH()) / metrics.getMinimapH())); + + if (map->isInside(xCell, yCell) + && map->isInsideSurface(map->toSurfCoords(Vec2i + (xCell, yCell)))) { + if (gui.isSelectingPos()) { + gui.mouseDownLeftGraphics(xCell, yCell, true); + } else { + if (!setMarker) { + cameraDragAllowed = true; + gameCamera.setPos(Vec2f + (static_cast (xCell), + static_cast (yCell))); + } + } + + if (setMarker) { + Vec2i + surfaceCellPos = map->toSurfCoords(Vec2i(xCell, yCell)); + SurfaceCell *sc = map->getSurfaceCell(surfaceCellPos); + Vec3f vertex = sc->getVertex(); + Vec2i targetPos(vertex.x, vertex.z); + + MarkedCell + mc(targetPos, world.getThisFaction(), "none", + world.getThisFaction()->getStartLocationIndex()); + addOrReplaceInHighlightedCells(mc); + + GameNetworkInterface *gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + gameNetworkInterface-> + sendHighlightCellMessage(mc.getTargetPos(), + mc.getFaction()->getIndex()); + } + + + if (originalIsMarkCellEnabled == true + && isMarkCellEnabled == true) { + Vec2i + surfaceCellPos = map->toSurfCoords(Vec2i(xCell, yCell)); + SurfaceCell *sc = map->getSurfaceCell(surfaceCellPos); + Vec3f vertex = sc->getVertex(); + Vec2i targetPos(vertex.x, vertex.z); + + MarkedCell + mc(targetPos, world.getThisFaction(), + "placeholder for note", + world.getThisFaction()->getStartLocationIndex()); + + //GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); + //gameNetworkInterface->sendMarkCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex(),mc.getNote()); + + //printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size()); + + isMarkCellEnabled = false; + cellMarkedData = mc; + cellMarkedPos = surfaceCellPos; + isMarkCellTextEnabled = true; + chatManager.switchOnEdit(this, 500); + + Renderer & renderer = Renderer::getInstance(); + //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos); + renderer.forceQuadCacheUpdate(); + } + if (originalIsUnMarkCellEnabled == true + && isUnMarkCellEnabled == true) { + Vec2i + surfaceCellPos = map->toSurfCoords(Vec2i(xCell, yCell)); + SurfaceCell *sc = map->getSurfaceCell(surfaceCellPos); + Vec3f vertex = sc->getVertex(); + Vec2i targetPos(vertex.x, vertex.z); + + // if(mapMarkedCellList.find(surfaceCellPos) != mapMarkedCellList.end()) { + // MarkedCell mc = mapMarkedCellList[surfaceCellPos]; + // if(mc.getFaction() == world.getThisFaction()) { + // mapMarkedCellList.erase(surfaceCellPos); + // GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); + // gameNetworkInterface->sendUnMarkCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex()); + // } + // } + + isUnMarkCellEnabled = false; + + removeCellMarker(surfaceCellPos, world.getThisFaction()); + //printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size()); + + Renderer & renderer = Renderer::getInstance(); + //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos); + renderer.forceQuadCacheUpdate(); + } + } + } + //display panel + else if (metrics.isInDisplay(x, y) && !gui.isSelectingPos()) { + int xd = x - metrics.getDisplayX(); + int yd = y - metrics.getDisplayY(); + if (gui.mouseValid(xd, yd)) { + gui.mouseDownLeftDisplay(xd, yd); + } else { + gui.mouseDownLeftGraphics(x, y, false); + } + } + //graphics panel + else { + gui.mouseDownLeftGraphics(x, y, false); + + if (setMarker) { + Vec2i targetPos; + Vec2i screenPos(x, y - 60); + targetPos = getMouseCellPos(); + //Vec2i surfaceCellPos = map->toSurfCoords(targetPos); + + + MarkedCell + mc(targetPos, world.getThisFaction(), "none", + world.getThisFaction()->getStartLocationIndex()); + addOrReplaceInHighlightedCells(mc); + + GameNetworkInterface *gameNetworkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + gameNetworkInterface->sendHighlightCellMessage(mc.getTargetPos + (), + mc.getFaction + ()->getIndex + ()); + } + + if (originalIsMarkCellEnabled == true + && isMarkCellEnabled == true) { + Vec2i targetPos; + Vec2i screenPos(x, y - 60); + targetPos = getMouseCellPos(); + Vec2i surfaceCellPos = map->toSurfCoords(targetPos); + + MarkedCell + mc(targetPos, world.getThisFaction(), + "placeholder for note", + world.getThisFaction()->getStartLocationIndex()); + + //printf("#2 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size()); + + isMarkCellEnabled = false; + cellMarkedData = mc; + cellMarkedPos = surfaceCellPos; + isMarkCellTextEnabled = true; + chatManager.switchOnEdit(this, 500); + + //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos); + Renderer::getInstance().forceQuadCacheUpdate(); + } + + if (originalIsUnMarkCellEnabled == true + && isUnMarkCellEnabled == true) { + Vec2i targetPos; + Vec2i screenPos(x, y - 35); + targetPos = getMouseCellPos(); + Vec2i surfaceCellPos = map->toSurfCoords(targetPos); + + // if(mapMarkedCellList.find(surfaceCellPos) != mapMarkedCellList.end()) { + // MarkedCell mc = mapMarkedCellList[surfaceCellPos]; + // if(mc.getFaction() == world.getThisFaction()) { + // mapMarkedCellList.erase(surfaceCellPos); + // GameNetworkInterface *gameNetworkInterface= NetworkManager::getInstance().getGameNetworkInterface(); + // gameNetworkInterface->sendUnMarkCellMessage(mc.getTargetPos(),mc.getFaction()->getIndex()); + // } + // } + + isUnMarkCellEnabled = false; + removeCellMarker(surfaceCellPos, world.getThisFaction()); + //printf("#1 ADDED in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",surfaceCellPos.getString().c_str(),mapMarkedCellList.size()); + + //Renderer &renderer= Renderer::getInstance(); + //renderer.updateMarkedCellScreenPosQuadCache(surfaceCellPos); + Renderer::getInstance().forceQuadCacheUpdate(); + } + } + } + + //exit message box, has to be the last thing to do in this function + if (errorMessageBox.getEnabled() == true) { + if (errorMessageBox.mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + //close message box + errorMessageBox.setEnabled(false); + } + } + if (mainMessageBox.getEnabled()) { + int button = 0; + if (mainMessageBox.mouseClick(x, y, button)) { + if (button == 0) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + if (networkManager.getGameNetworkInterface() != NULL) { + networkManager.getGameNetworkInterface()->quitGame(true); + } + quitTriggeredIndicator = true; + return; + } else { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + //close message box + mainMessageBox.setEnabled(false); + } + } + } + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + NetworkManager & networkManager = NetworkManager::getInstance(); + if (networkManager.getGameNetworkInterface() != NULL) { + GameNetworkInterface *networkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + networkInterface->sendTextMessage(szBuf, -1, true, ""); + sleep(10); + networkManager.getGameNetworkInterface()->quitGame(true); + } + ErrorDisplayMessage(ex.what(), true); + } + } + + void Game::mouseDownRight(int x, int y) { + if (this->masterserverMode == true) { + return; + } + + if (currentUIState != NULL) { + currentUIState->mouseDownRight(x, y); + return; + } + + try { + if (gameStarted == false || totalRenderFps <= 0) { + Logger::getInstance().handleMouseClick(x, y); + return; + } + + Map *map = world.getMap(); + const Metrics & metrics = Metrics::getInstance(); + + if (metrics.isInMinimap(x, y)) { + int xm = x - metrics.getMinimapX(); + int ym = y - metrics.getMinimapY(); + int + xCell = + static_cast < + int>(xm * + (static_cast < + float>(map->getW()) / metrics.getMinimapW())); + int + yCell = + static_cast < + int>(map->getH() - + ym * (static_cast < + float>(map->getH()) / metrics.getMinimapH())); + + if (map->isInside(xCell, yCell) + && map-> + isInsideSurface(map->toSurfCoords(Vec2i(xCell, yCell)))) { + gui.mouseDownRightGraphics(xCell, yCell, true); + } + } else { + Vec2i targetPos; + Vec2i screenPos(x, y); + targetPos = getMouseCellPos(); + if (isValidMouseCellPos() == true && + map->isInsideSurface(map->toSurfCoords(targetPos)) == true) { + gui.mouseDownRightGraphics(x, y, false); + } + } + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] Error [%s] x = %d y = %d\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what(), x, y); + + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + NetworkManager & networkManager = NetworkManager::getInstance(); + if (networkManager.getGameNetworkInterface() != NULL) { + GameNetworkInterface *networkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + networkInterface->sendTextMessage(szBuf, -1, true, ""); + sleep(10); + networkManager.getGameNetworkInterface()->quitGame(true); + } + ErrorDisplayMessage(ex.what(), true); + } + } + + void Game::mouseUpCenter(int x, int y) { + if (this->masterserverMode == true) { + return; + } + + if (gameStarted == false || totalRenderFps <= 0) { + return; + } + + if (currentUIState != NULL) { + currentUIState->mouseUpCenter(x, y); + return; + } + + if (mouseMoved == false) { + gameCamera.setState(GameCamera::sGame); + } else { + mouseMoved = false; + } + } + + void Game::mouseUpLeft(int x, int y) { + if (this->masterserverMode == true) { + return; + } + + try { + if (gameStarted == false || totalRenderFps <= 0) { + return; + } + + if (currentUIState != NULL) { + currentUIState->mouseUpLeft(x, y); + return; + } + + gui.mouseUpLeftGraphics(x, y); + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + NetworkManager & networkManager = NetworkManager::getInstance(); + if (networkManager.getGameNetworkInterface() != NULL) { + GameNetworkInterface *networkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + networkInterface->sendTextMessage(szBuf, -1, true, ""); + sleep(10); + networkManager.getGameNetworkInterface()->quitGame(true); + } + ErrorDisplayMessage(ex.what(), true); + } + } + + void Game::mouseDoubleClickLeft(int x, int y) { + if (this->masterserverMode == true) { + return; + } + + try { + if (gameStarted == false || totalRenderFps <= 0) { + return; + } + if (currentUIState != NULL) { + currentUIState->mouseDoubleClickLeft(x, y); + return; + } + + const Metrics & metrics = Metrics::getInstance(); + + if (metrics.isInMinimap(x, y)) { + // no double click on minimap + } else { + //display panel + if (metrics.isInDisplay(x, y) && !gui.isSelectingPos()) { + int xd = x - metrics.getDisplayX(); + int yd = y - metrics.getDisplayY(); + if (gui.mouseValid(xd, yd)) { + return; + } + } + //graphics panel + gui.mouseDoubleClickLeftGraphics(x, y); + } + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + NetworkManager & networkManager = NetworkManager::getInstance(); + if (networkManager.getGameNetworkInterface() != NULL) { + GameNetworkInterface *networkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + networkInterface->sendTextMessage(szBuf, -1, true, ""); + sleep(10); + networkManager.getGameNetworkInterface()->quitGame(true); + } + ErrorDisplayMessage(ex.what(), true); + } + } + + void Game::mouseMove(int x, int y, const MouseState * ms) { + if (this->masterserverMode == true) { + return; + } + + try { + if (gameStarted == false || totalRenderFps <= 0) { + return; + } + if (currentUIState != NULL) { + currentUIState->mouseMove(x, y, ms); + return; + } + + popupMenu.mouseMove(x, y); + popupMenuSwitchTeams.mouseMove(x, y); + popupMenuDisconnectPlayer.mouseMove(x, y); + + const Metrics & metrics = Metrics::getInstance(); + + mouseX = x; + mouseY = y; + + if (ms->get(mbCenter)) { + mouseMoved = true; + if (currentCameraFollowUnit == NULL) { + float ymult = 0.2f; + float xmult = 0.2f; + + Vec2i oldPos = ::Shared::Platform::Window::getOldMousePos(); + int + oldx = + (oldPos.x * metrics.getVirtualW() / metrics.getScreenW()); + int + oldy = + ((metrics.getScreenH() - + oldPos.y) * metrics.getVirtualH() / metrics.getScreenH()); + lastMousePos.x = oldx; + lastMousePos.y = oldy; + gameCamera.transitionVH(-(y - oldy) * ymult, (oldx - x) * xmult); + } + mouseX = lastMousePos.x; + mouseY = lastMousePos.y; + ::Shared::Platform::Window::revertMousePos(); + + return; + } else if (currentCameraFollowUnit == NULL) { + //if(Window::isKeyDown() == false) + if (!camLeftButtonDown && !camRightButtonDown && !camUpButtonDown + && !camDownButtonDown) { + if (ms->get(mbLeft) && metrics.isInMinimap(x, y)) { + int xm = x - metrics.getMinimapX(); + int ym = y - metrics.getMinimapY(); + + Map *map = world.getMap(); + int + xCell = + static_cast < + int>(xm * + (static_cast < + float>(map->getW()) / metrics.getMinimapW())); + int + yCell = + static_cast < + int>(map->getH() - + ym * (static_cast < + float>(map->getH()) / metrics.getMinimapH())); + + if (map->isInside(xCell, yCell) + && map->isInsideSurface(map->toSurfCoords(Vec2i + (xCell, + yCell)))) { + if (gui.isSelectingPos()) { + gui.mouseDownLeftGraphics(xCell, yCell, true); + } else { + if (cameraDragAllowed == true) { + gameCamera.setPos(Vec2f + (static_cast (xCell), + static_cast (yCell))); + } + } + } + } else { + bool + mouseMoveScrollsWorld = + Config::getInstance().getBool("MouseMoveScrollsWorld", + "true"); + if (mouseMoveScrollsWorld == true) { + if (y < 10) { + gameCamera.setMoveZ(-scrollSpeed); + } else if (y > metrics.getVirtualH() - 10) { + gameCamera.setMoveZ(scrollSpeed); + } else { + gameCamera.setMoveZ(0); + } + + if (x < 10) { + gameCamera.setMoveX(-scrollSpeed); + } else if (x > metrics.getVirtualW() - 10) { + gameCamera.setMoveX(scrollSpeed); + } else { + gameCamera.setMoveX(0); + } + } + } + } + + if (switchTeamConfirmMessageBox.getEnabled() == true) { + switchTeamConfirmMessageBox.mouseMove(x, y); + } + + if (disconnectPlayerConfirmMessageBox.getEnabled() == true) { + disconnectPlayerConfirmMessageBox.mouseMove(x, y); + } + + if (mainMessageBox.getEnabled()) { + mainMessageBox.mouseMove(x, y); + } + if (errorMessageBox.getEnabled()) { + errorMessageBox.mouseMove(x, y); + } + if (scriptManager.getMessageBox()->getEnabled()) { + scriptManager.getMessageBox()->mouseMove(x, y); + } + //else if (saveBox) { + // saveBox->mouseMove(x, y); + //} else { + // //graphics + gui.mouseMoveGraphics(x, y); + //} + } + + //display + if (!gui.isSelecting() && !gui.isSelectingPos()) { + if (!gui.isSelectingPos()) { + if (metrics.isInDisplay(x, y)) { + gui.mouseMoveDisplay(x - metrics.getDisplayX(), + y - metrics.getDisplayY()); + } else { + gui.mouseMoveOutsideDisplay(); + } + } + } + + lastMousePos.x = mouseX; + lastMousePos.y = mouseY; + + Renderer & renderer = Renderer::getInstance(); + renderer.ccomputePosition(Vec2i(mouseX, mouseY), mouseCellPos); + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + NetworkManager & networkManager = NetworkManager::getInstance(); + if (networkManager.getGameNetworkInterface() != NULL) { + GameNetworkInterface *networkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + networkInterface->sendTextMessage(szBuf, -1, true, ""); + sleep(10); + networkManager.getGameNetworkInterface()->quitGame(true); + } + ErrorDisplayMessage(ex.what(), true); + } + } + + bool Game::isValidMouseCellPos()const { + if (world.getMap() == NULL) { + return false; + } else { + return world.getMap()->isInside(mouseCellPos); + } + } + + void Game::eventMouseWheel(int x, int y, int zDelta) { + if (this->masterserverMode == true) { + return; + } + + if (currentUIState != NULL) { + currentUIState->eventMouseWheel(x, y, zDelta); + return; + } + + try { + gameCamera.zoom((float) zDelta / 60.0f); + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + NetworkManager & networkManager = NetworkManager::getInstance(); + if (networkManager.getGameNetworkInterface() != NULL) { + GameNetworkInterface *networkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + networkInterface->sendTextMessage(szBuf, -1, true, ""); + sleep(10); + networkManager.getGameNetworkInterface()->quitGame(true); + } + ErrorDisplayMessage(ex.what(), true); + } + } + + void Game::startCameraFollowUnit() { + Selection *selection = gui.getSelectionPtr(); + if (selection->getCount() == 1) { + Unit *currentUnit = selection->getUnitPtr(0); + if (currentUnit != NULL) { + currentCameraFollowUnit = currentUnit; + getGameCameraPtr()->setState(GameCamera::sUnit); + getGameCameraPtr()-> + setPos(currentCameraFollowUnit->getCurrMidHeightVector()); + + int rotation = currentCameraFollowUnit->getRotation(); + getGameCameraPtr()->stop(); + getGameCameraPtr()->rotateToVH(0.0f, (540 - rotation) % 360); + getGameCameraPtr()->setHAng((540 - rotation) % 360); + getGameCameraPtr()->setVAng(0.0f); + } + } else { + if (currentCameraFollowUnit != NULL) { + currentCameraFollowUnit = NULL; + } + } + } + + bool Game::textInput(std::string text) { + if (chatManager.getEditEnabled() == true) { + return chatManager.textInput(text); + } + return false; + } + + bool Game::sdlKeyDown(SDL_KeyboardEvent key) { + if (this->masterserverMode == true) { + return false; + } + if (gameStarted == false || totalRenderFps <= 0) { + return false; + } + + if (chatManager.getEditEnabled() == true) { + return false; + } + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + //group + for (int idx = 1; idx <= Selection::maxGroups; idx++) { + string keyName = "GroupUnitsKey" + intToStr(idx); + + SDL_Keycode groupHotKey = configKeys.getSDLKey(keyName.c_str()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] keyName [%s] group index = %d, key = [%c] [%d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, keyName.c_str(), idx, + groupHotKey, groupHotKey); + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("input.keysym.mod = %d groupHotKey = %d key = %d (%d) [%s] isgroup = %d\n",key.keysym.mod,groupHotKey,key.keysym.sym,key.keysym.unicode,keyName.c_str(),isKeyPressed(groupHotKey,key)); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("input.keysym.mod = %d groupHotKey = %d key = (%d) [%s] isgroup = %d\n", + key.keysym.mod, groupHotKey, key.keysym.sym, keyName.c_str(), + isKeyPressed(groupHotKey, key)); + //printf(" group key check %d scancode:%d sym:%d groupHotKey=%d \n",idx,key.keysym.scancode,key.keysym.sym,groupHotKey); + if (key.keysym.sym == groupHotKey) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + //printf("IS GROUP KEY %d scancode:%d sym:%d groupHotKey=%d \n",idx,key.keysym.scancode,key.keysym.sym,groupHotKey); + gui.groupKey(idx - 1); + return true; + } + } + return false; + } + + void Game::keyDown(SDL_KeyboardEvent key) { + if (this->masterserverMode == true) { + return; + } + + //printf("In game checking keypress for key [%d]\n",key.keysym.sym); + + try { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = [%c] [%d] gameStarted [%d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, key.keysym.sym, key.keysym.sym, + gameStarted); + if (gameStarted == false || totalRenderFps <= 0) { + return; + } + if (currentUIState != NULL) { + currentUIState->keyDown(key); + return; + } + + Lang & lang = Lang::getInstance(); + bool formerChatState = chatManager.getEditEnabled(); + //send key to the chat manager + chatManager.keyDown(key); + + if (formerChatState == false && chatManager.getEditEnabled()) { + camUpButtonDown = false; + camDownButtonDown = false; + camLeftButtonDown = false; + camRightButtonDown = false; + + gameCamera.stopMove(); + } + + //printf("GAME KEYDOWN #1\n"); + + if (chatManager.getEditEnabled() == false) { + //printf("GAME KEYDOWN #2\n"); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = [%d - %c]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + key.keysym.sym, key.keysym.sym); + + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] key = [%d - %c] pausegame [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,key,key,configKeys.getCharKey("PauseGame")); + + //printf("SDL [%d] key [%d][%d]\n",configKeys.getSDLKey("SetMarker"),key.keysym.unicode,key.keysym.sym); + bool setMarkerKeyAllowsModifier = false; + if (configKeys.getSDLKey("SetMarker") == SDLK_RALT || + configKeys.getSDLKey("SetMarker") == SDLK_LALT) { + setMarkerKeyAllowsModifier = true; + } + + //printf("In game checking keypress for key [%d] camera left [%d]\n",key.keysym.sym,configKeys.getSDLKey("CameraModeLeft")); + + if (isKeyPressed + (configKeys.getSDLKey("RenderInGamePerformance"), key, + false) == true) { + renderInGamePerformance = !renderInGamePerformance; + + Config::getInstance().setBool("PerformanceWarningEnabled", + renderInGamePerformance, true); + } + //if(key == configKeys.getCharKey("RenderNetworkStatus")) { + else + if (isKeyPressed + (configKeys.getSDLKey("RenderNetworkStatus"), key, + false) == true) { + renderNetworkStatus = !renderNetworkStatus; + } + //else if(key == configKeys.getCharKey("ShowFullConsole")) { + else + if (isKeyPressed + (configKeys.getSDLKey("ShowFullConsole"), key, + false) == true) { + showFullConsole = true; + } else + if (isKeyPressed + (configKeys.getSDLKey("SetMarker"), key, + setMarkerKeyAllowsModifier) == true) { + setMarker = true; + printf("%d\n", key.keysym.scancode); + } + //else if(key == configKeys.getCharKey("TogglePhotoMode")) { + else + if (isKeyPressed + (configKeys.getSDLKey("TogglePhotoMode"), key, + false) == true) { + photoModeEnabled = !photoModeEnabled; + if (photoModeEnabled == true && + this->gameSettings.isNetworkGame() == false) { + gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT); + } else if (photoModeEnabled == false) { + gameCamera.setMaxHeight(-1); + } + + } + //Toggle Healthbars + else + if (isKeyPressed + (configKeys.getSDLKey("ToggleHealthbars"), key, + false) == true) { + switch (healthbarMode) { + case hbvUndefined: + healthbarMode = hbvOff; + console.addLine(lang.getString("Healthbar2") + ": " + + lang.getString("HealthbarsOff")); + break; + case hbvOff: + healthbarMode = hbvAlways; + console.addLine(lang.getString("Healthbar2") + ": " + + lang.getString("HealthbarsAlways")); + break; + case hbvAlways: + healthbarMode = hbvIfNeeded; + console.addLine(lang.getString("Healthbar2") + ": " + + lang.getString("HealthbarsIfNeeded")); + break; + case hbvIfNeeded: + healthbarMode = hbvSelected; + console.addLine(lang.getString("Healthbar2") + ": " + + lang.getString("HealthbarsSelected")); + break; + case hbvSelected: + healthbarMode = hbvSelected | hbvIfNeeded; + console.addLine(lang.getString("Healthbar2") + ": " + + lang.getString("HealthbarsSelectedOrNeeded")); + break; + case (hbvSelected | hbvIfNeeded): + healthbarMode = hbvUndefined; + console.addLine(lang.getString("Healthbar2") + ": " + + lang.getString("HealthbarsFactionDefault")); + break; + default: + printf + ("In [%s::%s Line: %d] Toggle Healthbars Hotkey - Invalid Value. Setting to default.\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + healthbarMode = hbvUndefined; + break; + } + } + //Toggle music + //else if(key == configKeys.getCharKey("ToggleMusic")) { + else + if (isKeyPressed + (configKeys.getSDLKey("ToggleMusic"), key, false) == true) { + + if (this->masterserverMode == false) { + Config & config = Config::getInstance(); + StrSound *gameMusic = + world.getThisFaction()->getType()->getMusic(); + if (gameMusic != NULL) { + float + configVolume = (config.getInt("SoundVolumeMusic") / 100.f); + float currentVolume = gameMusic->getVolume(); + if (currentVolume > 0) { + gameMusic->setVolume(0); + console.addLine(lang.getString("GameMusic") + + " " + lang.getString("Off")); + } else { + //If the config says zero, use the default music volume + gameMusic->setVolume(configVolume ? configVolume : 0.9); + console.addLine(lang.getString("GameMusic")); + } + } + } + } + //move camera left + //else if(key == configKeys.getCharKey("CameraModeLeft")) { + else + if (isKeyPressed + (configKeys.getSDLKey("CameraModeLeft"), key, false) == true) { + gameCamera.setMoveX(-1); + camLeftButtonDown = true; + } + //move camera right + //else if(key == configKeys.getCharKey("CameraModeRight")) { + else + if (isKeyPressed + (configKeys.getSDLKey("CameraModeRight"), key, + false) == true) { + gameCamera.setMoveX(1); + camRightButtonDown = true; + } + //move camera up + //else if(key == configKeys.getCharKey("CameraModeUp")) { + else + if (isKeyPressed + (configKeys.getSDLKey("CameraModeUp"), key, false) == true) { + gameCamera.setMoveZ(1); + camUpButtonDown = true; + } + //move camera down + //else if(key == configKeys.getCharKey("CameraModeDown")) { + else + if (isKeyPressed + (configKeys.getSDLKey("CameraModeDown"), key, false) == true) { + gameCamera.setMoveZ(-1); + camDownButtonDown = true; + } + //change camera mode + //else if(key == configKeys.getCharKey("FreeCameraMode")) { + else + if (isKeyPressed + (configKeys.getSDLKey("FreeCameraMode"), key, false) == true) { + if (gameCamera.getState() == GameCamera::sFree) { + gameCamera.setState(GameCamera::sGame); + string + stateString = + gameCamera.getState() == + GameCamera:: + sGame ? lang.getString("GameCamera") : + lang.getString("FreeCamera"); + console.addLine(lang.getString("CameraModeSet") + " " + + stateString); + } else if (gameCamera.getState() == GameCamera::sGame) { + gameCamera.setState(GameCamera::sFree); + string + stateString = + gameCamera.getState() == + GameCamera:: + sGame ? lang.getString("GameCamera") : + lang.getString("FreeCamera"); + console.addLine(lang.getString("CameraModeSet") + " " + + stateString); + } + //else ignore! + } + //reset camera mode to normal + //else if(key == configKeys.getCharKey("ResetCameraMode")) { + else + if (isKeyPressed + (configKeys.getSDLKey("ResetCameraMode"), key, + false) == true) { + if (currentCameraFollowUnit != NULL) { + currentCameraFollowUnit = NULL; + } + gameCamera.setState(GameCamera::sGame); + } + //pause + //else if(key == configKeys.getCharKey("PauseGame")) { + else + if (isKeyPressed + (configKeys.getSDLKey("PauseGame"), key, false) == true) { + //printf("Toggle pause paused = %d\n",paused); + //setPaused(!paused); + + bool allowAdminMenuItems = false; + NetworkManager & networkManager = NetworkManager::getInstance(); + NetworkRole role = networkManager.getNetworkRole(); + if (role == nrServer) { + allowAdminMenuItems = true; + } else if (role == nrClient) { + ClientInterface *clientInterface = + dynamic_cast < + ClientInterface *>(networkManager.getClientInterface()); + + if (clientInterface != NULL && + gameSettings.getMasterserver_admin() == + clientInterface->getSessionKey()) { + allowAdminMenuItems = true; + } + } + + if (allowAdminMenuItems) { + if (getPaused() == false) { + commander.tryPauseGame(false, false); + } else { + commander.tryResumeGame(false, false); + } + } + } else + if (isKeyPressed + (configKeys.getSDLKey("ExtraTeamColorMarker"), key, + false) == true) { + //printf("Toggle ExtraTeamColorMarker\n"); + toggleTeamColorMarker(); + } + //switch display color + //else if(key == configKeys.getCharKey("ChangeFontColor")) { + else + if (isKeyPressed + (configKeys.getSDLKey("ChangeFontColor"), key, + false) == true) { + gui.switchToNextDisplayColor(); + } + //increment speed + //else if(key == configKeys.getCharKey("GameSpeedIncrease")) { + else + if (isKeyPressed + (configKeys.getSDLKey("GameSpeedIncrease"), key, + false) == true) { + bool + speedChangesAllowed = + !NetworkManager:: + getInstance().isNetworkGameWithConnectedClients(); + if (speedChangesAllowed) { + incSpeed(); + } + } + //decrement speed + //else if(key == configKeys.getCharKey("GameSpeedDecrease")) { + else + if (isKeyPressed + (configKeys.getSDLKey("GameSpeedDecrease"), key, + false) == true) { + bool + speedChangesAllowed = + !NetworkManager:: + getInstance().isNetworkGameWithConnectedClients(); + if (speedChangesAllowed) { + decSpeed(); + } + } else + if (isKeyPressed + (configKeys.getSDLKey("BookmarkAdd"), key, false) == true) { + startMarkCell(); + } else + if (isKeyPressed + (configKeys.getSDLKey("BookmarkRemove"), key, false) == true) { + isUnMarkCellEnabled = true; + } else + if (isKeyPressed + (configKeys.getSDLKey("CameraFollowSelectedUnit"), key, + false) == true) { + startCameraFollowUnit(); + } + //exit + else + if (isKeyPressed(configKeys.getSDLKey("ExitKey"), key, false) + == true) { + popupMenu.setEnabled(!popupMenu.getEnabled()); + popupMenu.setVisible(popupMenu.getEnabled()); + } + + //hotkeys + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] gameCamera.getState() = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + gameCamera.getState()); + + if (gameCamera.getState() != GameCamera::sFree) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, key); + + gui.hotKey(key); + } else { + //rotate camera leftt + //if(key == configKeys.getCharKey("CameraRotateLeft")) { + if (isKeyPressed + (configKeys.getSDLKey("CameraRotateLeft"), key) == true) { + gameCamera.setRotate(-1); + } + //rotate camera right + //else if(key == configKeys.getCharKey("CameraRotateRight")){ + else + if (isKeyPressed + (configKeys.getSDLKey("CameraRotateRight"), key) == true) { + gameCamera.setRotate(1); + } + //camera up + //else if(key == configKeys.getCharKey("CameraRotateUp")) { + else + if (isKeyPressed + (configKeys.getSDLKey("CameraRotateUp"), key) == true) { + gameCamera.setMoveY(1); + } + //camera down + //else if(key == configKeys.getCharKey("CameraRotateDown")) { + else + if (isKeyPressed + (configKeys.getSDLKey("CameraRotateDown"), key) == true) { + gameCamera.setMoveY(-1); + } + } + + if (isKeyPressed(configKeys.getSDLKey("SaveGame"), key) == true) { + saveGame(); + } + } + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + NetworkManager & networkManager = NetworkManager::getInstance(); + if (networkManager.getGameNetworkInterface() != NULL) { + GameNetworkInterface *networkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + networkInterface->sendTextMessage(szBuf, -1, true, ""); + sleep(10); + networkManager.getGameNetworkInterface()->quitGame(true); + } + ErrorDisplayMessage(ex.what(), true); + } + } + + void Game::keyUp(SDL_KeyboardEvent key) { + if (this->masterserverMode == true) { + return; + } + + try { + if (gameStarted == false || totalRenderFps <= 0) { + return; + } + if (currentUIState != NULL) { + currentUIState->keyUp(key); + return; + } + + if (chatManager.getEditEnabled()) { + //send key to the chat manager + chatManager.keyUp(key); + } else { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + + //if(key == configKeys.getCharKey("ShowFullConsole")) { + if (isKeyPressed(configKeys.getSDLKey("ShowFullConsole"), key) + == true) { + showFullConsole = false; + } else if (isKeyPressed(configKeys.getSDLKey("SetMarker"), key) == + true #ifdef WIN32 - || key.keysym.scancode == 5 + || key.keysym.scancode == 5 #endif - ) - { - setMarker = false; - } - //else if(key == configKeys.getCharKey("CameraRotateLeft") || - // key == configKeys.getCharKey("CameraRotateRight")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("CameraRotateLeft"), key) == true - || isKeyPressed (configKeys.getSDLKey ("CameraRotateRight"), - key) == true) - { - gameCamera.setRotate (0); - } - //else if(key == configKeys.getCharKey("CameraRotateDown") || - // key == configKeys.getCharKey("CameraRotateUp")) { - else - if (isKeyPressed - (configKeys.getSDLKey ("CameraRotateDown"), key) == true - || isKeyPressed (configKeys.getSDLKey ("CameraRotateUp"), - key) == true) - { + ) { + setMarker = false; + } + //else if(key == configKeys.getCharKey("CameraRotateLeft") || + // key == configKeys.getCharKey("CameraRotateRight")) { + else + if (isKeyPressed + (configKeys.getSDLKey("CameraRotateLeft"), key) == true + || isKeyPressed(configKeys.getSDLKey("CameraRotateRight"), + key) == true) { + gameCamera.setRotate(0); + } + //else if(key == configKeys.getCharKey("CameraRotateDown") || + // key == configKeys.getCharKey("CameraRotateUp")) { + else + if (isKeyPressed + (configKeys.getSDLKey("CameraRotateDown"), key) == true + || isKeyPressed(configKeys.getSDLKey("CameraRotateUp"), + key) == true) { - gameCamera.setMoveY (0); - } - //else if(key == configKeys.getCharKey("CameraModeUp")){ - else if (isKeyPressed (configKeys.getSDLKey ("CameraModeUp"), key) - == true) - { - gameCamera.setMoveZ (0); - camUpButtonDown = false; - calcCameraMoveZ (); - } - //else if(key == configKeys.getCharKey("CameraModeDown")){ - else - if (isKeyPressed (configKeys.getSDLKey ("CameraModeDown"), key) - == true) - { - gameCamera.setMoveZ (0); - camDownButtonDown = false; - calcCameraMoveZ (); - } - //else if(key == configKeys.getCharKey("CameraModeLeft")){ - else - if (isKeyPressed (configKeys.getSDLKey ("CameraModeLeft"), key) - == true) - { - gameCamera.setMoveX (0); - camLeftButtonDown = false; - calcCameraMoveX (); - } - //else if(key == configKeys.getCharKey("CameraModeRight")){ - else - if (isKeyPressed (configKeys.getSDLKey ("CameraModeRight"), key) - == true) - { - gameCamera.setMoveX (0); - camRightButtonDown = false; - calcCameraMoveX (); - } - } - } - catch (const exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); + gameCamera.setMoveY(0); + } + //else if(key == configKeys.getCharKey("CameraModeUp")){ + else if (isKeyPressed(configKeys.getSDLKey("CameraModeUp"), key) + == true) { + gameCamera.setMoveZ(0); + camUpButtonDown = false; + calcCameraMoveZ(); + } + //else if(key == configKeys.getCharKey("CameraModeDown")){ + else + if (isKeyPressed(configKeys.getSDLKey("CameraModeDown"), key) + == true) { + gameCamera.setMoveZ(0); + camDownButtonDown = false; + calcCameraMoveZ(); + } + //else if(key == configKeys.getCharKey("CameraModeLeft")){ + else + if (isKeyPressed(configKeys.getSDLKey("CameraModeLeft"), key) + == true) { + gameCamera.setMoveX(0); + camLeftButtonDown = false; + calcCameraMoveX(); + } + //else if(key == configKeys.getCharKey("CameraModeRight")){ + else + if (isKeyPressed(configKeys.getSDLKey("CameraModeRight"), key) + == true) { + gameCamera.setMoveX(0); + camRightButtonDown = false; + calcCameraMoveX(); + } + } + } catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); - NetworkManager & networkManager = NetworkManager::getInstance (); - if (networkManager.getGameNetworkInterface () != NULL) - { - GameNetworkInterface *networkInterface = - NetworkManager::getInstance ().getGameNetworkInterface (); - networkInterface->sendTextMessage (szBuf, -1, true, ""); - sleep (10); - networkManager.getGameNetworkInterface ()->quitGame (true); - } - ErrorDisplayMessage (ex.what (), true); - } - } + NetworkManager & networkManager = NetworkManager::getInstance(); + if (networkManager.getGameNetworkInterface() != NULL) { + GameNetworkInterface *networkInterface = + NetworkManager::getInstance().getGameNetworkInterface(); + networkInterface->sendTextMessage(szBuf, -1, true, ""); + sleep(10); + networkManager.getGameNetworkInterface()->quitGame(true); + } + ErrorDisplayMessage(ex.what(), true); + } + } - void Game::calcCameraMoveX () - { - //move camera left - if (camLeftButtonDown == true) - { - gameCamera.setMoveX (-1); - } - //move camera right - else if (camRightButtonDown == true) - { - gameCamera.setMoveX (1); - } - } - void Game::calcCameraMoveZ () - { - //move camera up - if (camUpButtonDown == true) - { - gameCamera.setMoveZ (1); - } - //move camera down - else if (camDownButtonDown == true) - { - gameCamera.setMoveZ (-1); - } + void Game::calcCameraMoveX() { + //move camera left + if (camLeftButtonDown == true) { + gameCamera.setMoveX(-1); + } + //move camera right + else if (camRightButtonDown == true) { + gameCamera.setMoveX(1); + } + } + void Game::calcCameraMoveZ() { + //move camera up + if (camUpButtonDown == true) { + gameCamera.setMoveZ(1); + } + //move camera down + else if (camDownButtonDown == true) { + gameCamera.setMoveZ(-1); + } - } + } - void Game::keyPress (SDL_KeyboardEvent c) - { - if (this->masterserverMode == true) - { - return; - } + void Game::keyPress(SDL_KeyboardEvent c) { + if (this->masterserverMode == true) { + return; + } - if (gameStarted == false || totalRenderFps <= 0) - { - return; - } - if (currentUIState != NULL) - { - currentUIState->keyPress (c); - return; - } + if (gameStarted == false || totalRenderFps <= 0) { + return; + } + if (currentUIState != NULL) { + currentUIState->keyPress(c); + return; + } - chatManager.keyPress (c); - } + chatManager.keyPress(c); + } - Stats Game::getEndGameStats () - { - Stats endStats; - endStats = *(world.getStats ()); - //NetworkManager &networkManager= NetworkManager::getInstance(); - if (this->masterserverMode == true) - { - endStats.setIsMasterserverMode (true); - } - return endStats; - } + Stats Game::getEndGameStats() { + Stats endStats; + endStats = *(world.getStats()); + //NetworkManager &networkManager= NetworkManager::getInstance(); + if (this->masterserverMode == true) { + endStats.setIsMasterserverMode(true); + } + return endStats; + } - Stats Game::quitGame () - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); + Stats Game::quitGame() { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); - if (quitGameCalled == true) - { - Stats endStats = getEndGameStats (); - return endStats; - } - quitGameCalled = true; + if (quitGameCalled == true) { + Stats endStats = getEndGameStats(); + return endStats; + } + quitGameCalled = true; - NetworkManager & networkManager = NetworkManager::getInstance (); - NetworkRole role = networkManager.getNetworkRole (); - string suffix = "_client"; - if (role == nrServer) - { - suffix = "_server"; - } - this->DumpCRCWorldLogIfRequired (suffix); + NetworkManager & networkManager = NetworkManager::getInstance(); + NetworkRole role = networkManager.getNetworkRole(); + string suffix = "_client"; + if (role == nrServer) { + suffix = "_server"; + } + this->DumpCRCWorldLogIfRequired(suffix); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled == true) - { - world.DumpWorldToLog (); - } - //printf("Check savegame\n"); - //printf("Saving...\n"); - if (Config::getInstance ().getBool ("AutoTest")) - { - this->saveGame (GameConstants::saveGameFileAutoTestDefault); - } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled == true) { + world.DumpWorldToLog(); + } + //printf("Check savegame\n"); + //printf("Saving...\n"); + if (Config::getInstance().getBool("AutoTest")) { + this->saveGame(GameConstants::saveGameFileAutoTestDefault); + } - Stats endStats = getEndGameStats (); + Stats endStats = getEndGameStats(); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); - //printf("In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - NetworkManager::getInstance ().end (); - //sleep(0); + //printf("In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + NetworkManager::getInstance().end(); + //sleep(0); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); - return endStats; - } + return endStats; + } - void Game::DumpCRCWorldLogIfRequired (string fileSuffix) - { - bool isNetworkGame = this->gameSettings.isNetworkGame (); - if (isNetworkGame == true) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("Check save world CRC to log. isNetworkGame = %d fileSuffix = %s\n", - isNetworkGame, fileSuffix.c_str ()); + void Game::DumpCRCWorldLogIfRequired(string fileSuffix) { + bool isNetworkGame = this->gameSettings.isNetworkGame(); + if (isNetworkGame == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("Check save world CRC to log. isNetworkGame = %d fileSuffix = %s\n", + isNetworkGame, fileSuffix.c_str()); - GameSettings *settings = world.getGameSettingsPtr (); - if (settings != NULL && - (isFlagType1BitEnabled (ft1_network_synch_checks_verbose) == - true - || isFlagType1BitEnabled (ft1_network_synch_checks) == true)) - { - string - debugCRCWorldLogFile = - Config::getInstance ().getString ("DebugCRCWorldLogFile", - "debugCRCWorld.log"); - debugCRCWorldLogFile += fileSuffix; + GameSettings *settings = world.getGameSettingsPtr(); + if (settings != NULL && + (isFlagType1BitEnabled(ft1_network_synch_checks_verbose) == + true + || isFlagType1BitEnabled(ft1_network_synch_checks) == true)) { + string + debugCRCWorldLogFile = + Config::getInstance().getString("DebugCRCWorldLogFile", + "debugCRCWorld.log"); + debugCRCWorldLogFile += fileSuffix; - if (getGameReadWritePath - (GameConstants::path_logs_CacheLookupKey) != "") - { - debugCRCWorldLogFile = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - debugCRCWorldLogFile; - } - else - { - string - userData = - Config::getInstance ().getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - debugCRCWorldLogFile = userData + debugCRCWorldLogFile; - } + if (getGameReadWritePath + (GameConstants::path_logs_CacheLookupKey) != "") { + debugCRCWorldLogFile = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + debugCRCWorldLogFile; + } else { + string + userData = + Config::getInstance().getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + debugCRCWorldLogFile = userData + debugCRCWorldLogFile; + } - printf ("Save to log debugCRCWorldLogFile = %s\n", - debugCRCWorldLogFile.c_str ()); + printf("Save to log debugCRCWorldLogFile = %s\n", + debugCRCWorldLogFile.c_str()); #if defined(WIN32) && !defined(__MINGW32__) - FILE *fp = - _wfopen (utf8_decode (debugCRCWorldLogFile).c_str (), L"w"); - std::ofstream logFile (fp); + FILE *fp = + _wfopen(utf8_decode(debugCRCWorldLogFile).c_str(), L"w"); + std::ofstream logFile(fp); #else - std::ofstream logFile; - logFile.open (debugCRCWorldLogFile.c_str (), - ios_base::out | ios_base::trunc); + std::ofstream logFile; + logFile.open(debugCRCWorldLogFile.c_str(), + ios_base::out | ios_base::trunc); #endif - logFile << "World CRC debug information:" << std::endl; - logFile << "============================" << std::endl; - logFile << "Software version: " << glestVersionString << "-" << - getCompilerNameString () << std::endl; - logFile << "Maximum framecount: " << world. - getFaction (0)->getCRC_DetailsForWorldFrameCount () << std::endl; + logFile << "World CRC debug information:" << std::endl; + logFile << "============================" << std::endl; + logFile << "Software version: " << glestVersionString << "-" << + getCompilerNameString() << std::endl; + logFile << "Maximum framecount: " << world. + getFaction(0)->getCRC_DetailsForWorldFrameCount() << std::endl; - for (unsigned int worldFrameIndex = 0; - worldFrameIndex < - world.getFaction (0)->getCRC_DetailsForWorldFrameCount (); - ++worldFrameIndex) - { - //factions (and their related info) - for (int i = 0; i < world.getFactionCount (); ++i) - { - logFile << "Faction detail for index: " << i << std::endl; - logFile << "--------------------------" << std::endl; + for (unsigned int worldFrameIndex = 0; + worldFrameIndex < + world.getFaction(0)->getCRC_DetailsForWorldFrameCount(); + ++worldFrameIndex) { + //factions (and their related info) + for (int i = 0; i < world.getFactionCount(); ++i) { + logFile << "Faction detail for index: " << i << std::endl; + logFile << "--------------------------" << std::endl; - std::pair < int, - string > - details = - world. - getFaction (i)->getCRC_DetailsForWorldFrameIndex - (worldFrameIndex); + std::pair < int, + string > + details = + world. + getFaction(i)->getCRC_DetailsForWorldFrameIndex + (worldFrameIndex); - logFile << string ("** world frame: ") << details.first << std:: - endl; - logFile << details.second << std::endl; - } - } + logFile << string("** world frame: ") << details.first << std:: + endl; + logFile << details.second << std::endl; + } + } - logFile.close (); + logFile.close(); #if defined(WIN32) && !defined(__MINGW32__) - if (fp) - { - fclose (fp); - } + if (fp) { + fclose(fp); + } #endif - } - } - } - - void saveStatsToSteam (Game * game, Stats & endStats) - { - Steam *steamInstance = - CacheManager::getCachedItem < - Steam * >(GameConstants::steamCacheInstanceKey); - if (steamInstance != NULL) - { - printf ("\nSTEAM detected, writing out end game stats for player!\n"); - - // Write out stats here - if (NetworkManager::getInstance ().isNetworkGame ()) - { - //printf("\nSTEAM Refresh Stats!\n"); - steamInstance->requestRefreshStats (); - for (int factionIndex = 0; - factionIndex < game->getWorld ()->getFactionCount (); - ++factionIndex) - { - if (factionIndex == game->getWorld ()->getThisFactionIndex ()) - { - //printf("\nWriting out game stats for Faction Index: %d!\n",factionIndex); - if (endStats.getVictory (factionIndex)) - { - steamInstance->setStatAsInt (EnumParser < - SteamStatName >::getString - (stat_online_wins).c_str (), - steamInstance->getStatAsInt - (EnumParser < - SteamStatName >::getString - (stat_online_wins).c_str ()) + - 1); - } - else - { - steamInstance->setStatAsInt (EnumParser < - SteamStatName >::getString - (stat_online_loses).c_str (), - steamInstance->getStatAsInt - (EnumParser < - SteamStatName >::getString - (stat_online_loses).c_str ()) + - 1); - } - steamInstance->setStatAsInt (EnumParser < - SteamStatName >::getString - (stat_online_kills).c_str (), - steamInstance->getStatAsInt - (EnumParser < - SteamStatName - >::getString - (stat_online_kills).c_str ()) + - endStats.getKills (factionIndex)); - steamInstance->setStatAsInt (EnumParser < - SteamStatName - >::getString - (stat_online_kills_enemy).c_str (), - steamInstance->getStatAsInt - (EnumParser < - SteamStatName - >::getString - (stat_online_kills_enemy).c_str - ()) + - endStats.getEnemyKills - (factionIndex)); - steamInstance->setStatAsInt (EnumParser < - SteamStatName - >::getString - (stat_online_deaths).c_str (), - steamInstance->getStatAsInt - (EnumParser < - SteamStatName - >::getString - (stat_online_deaths).c_str ()) + - endStats.getDeaths (factionIndex)); - steamInstance->setStatAsInt (EnumParser < - SteamStatName - >::getString - (stat_online_units).c_str (), - steamInstance->getStatAsInt - (EnumParser < - SteamStatName - >::getString - (stat_online_units).c_str ()) + - endStats.getUnitsProduced - (factionIndex)); - steamInstance->setStatAsInt (EnumParser < - SteamStatName - >::getString - (stat_online_resources_harvested).c_str - (), - steamInstance->getStatAsInt - (EnumParser < - SteamStatName - >::getString - (stat_online_resources_harvested).c_str - ()) + - endStats.getResourcesHarvested - (factionIndex)); - if (endStats.getPlayerLeftBeforeEnd (factionIndex)) - { - steamInstance->setStatAsInt (EnumParser < - SteamStatName >::getString - (stat_online_quit_before_end).c_str - (), - steamInstance->getStatAsInt - (EnumParser < - SteamStatName - >::getString - (stat_online_quit_before_end).c_str - ()) + 1); - } - steamInstance->setStatAsDouble (EnumParser < - SteamStatName >::getString - (stat_online_minutes_played).c_str - (), - steamInstance->getStatAsDouble - (EnumParser < - SteamStatName - >::getString - (stat_online_minutes_played).c_str - ()) + - getTimeDuationMinutes - (endStats.getFramesToCalculatePlaytime - (), GameConstants::updateFps)); - } - } - } - - // Write out achievements here - for (int factionIndex = 0; - factionIndex < game->getWorld ()->getFactionCount (); - ++factionIndex) - { - if (factionIndex == game->getWorld ()->getThisFactionIndex ()) - { - //printf("\nWriting out game stats for Faction Index: %d won status: %d\n",factionIndex,endStats.getVictory(factionIndex)); - if (endStats.getVictory (factionIndex)) - { - if (steamInstance->isUnlocked (EnumParser < - SteamAchievementName - >::getString - (ACH_WIN_ONE_GAME).c_str ()) == - false) - { - steamInstance->unlock (EnumParser < - SteamAchievementName - >::getString (ACH_WIN_ONE_GAME).c_str - ()); - } - if (NetworkManager::getInstance ().isNetworkGame ()) - { - if (steamInstance->isUnlocked (EnumParser < - SteamAchievementName - >::getString - (ACH_WIN_ONE_GAME_ONLINE).c_str - ()) == false) - { - steamInstance->unlock (EnumParser < - SteamAchievementName >::getString - (ACH_WIN_ONE_GAME_ONLINE).c_str ()); - } - } - } - } - } - - //printf("\nSTEAM Store Stats!\n"); - steamInstance->storeStats (); - //printf("\nSTEAM Refresh Stats!\n"); - steamInstance->requestRefreshStats (); - } - } - - void Game::exitGameState (Program * program, Stats & endStats) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - Game *game = dynamic_cast < Game * >(program->getState ()); - - //printf("game = %p\n",game); - - if (game) - { - game->setEndGameTeamWinnersAndLosers (); - game->endGame (); - } - - if ((game != NULL && game->isMasterserverMode () == true) || - Config::getInstance ().getBool ("AutoTest") == true) - { - printf ("Game ending with stats:\n"); - printf ("-----------------------\n"); - - string gameStats = endStats.getStats (); - printf ("%s", gameStats.c_str ()); - - printf ("-----------------------\n"); - } - - saveStatsToSteam (game, endStats); - - ProgramState *newState = new BattleEnd (program, &endStats, game); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - program->setState (newState, false); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - -// ==================== PRIVATE ==================== - - void - Game::highlightUnit (int unitId, float radius, float thickness, - Vec4f color) - { - HighlightSpecialUnitInfo info; - info.radius = radius; - info.thickness = thickness; - info.color = color; - unitHighlightList[unitId] = info; - } - - void Game::unhighlightUnit (int unitId) - { - unitHighlightList.erase (unitId); - } - -// ==================== render ==================== - - void Game::render3d () - { - Chrono chrono; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled) - chrono.start (); - - Renderer & renderer = Renderer::getInstance (); - - //init - renderer.reset3d (); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [reset3d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - -// renderer.computeVisibleQuad(); -// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [computeVisibleQuad]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis()); -// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - renderer.loadGameCameraMatrix (); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [loadGameCameraMatrix]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - renderer.computeVisibleQuad (); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [computeVisibleQuad]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - renderer.setupLighting (); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [setupLighting]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - //shadow map - renderer.renderShadowsToTexture (avgRenderFps); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderShadowsToTexture]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - //clear buffers - renderer.clearBuffers (); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d renderFps = %d took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - //surface - renderer.renderSurface (avgRenderFps); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderSurface]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - //selection circles - renderer.renderSelectionEffects (healthbarMode); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderSelectionEffects]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - // renderTeamColorCircle - if ((renderExtraTeamColor & renderTeamColorCircleBit) > 0) - { - renderer.renderTeamColorCircle (); - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderObjects]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, renderFps, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - chrono.start (); - } - - renderer.renderSpecialHighlightUnits (unitHighlightList); - - // renderTeamColorCircle - renderer.renderMorphEffects (); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderObjects]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - //objects - renderer.renderObjects (avgRenderFps); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderObjects]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - //ground units - renderer.renderUnits (false, avgRenderFps); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderUnits]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - //water - renderer.renderWater (); - renderer.renderWaterEffects (); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderWater]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - //air units - renderer.renderUnits (true, avgRenderFps); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderUnits]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - //particles - renderer.renderParticleManager (rsGame); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderParticleManager]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - //renderOnTopBars (aka Healthbars) - if (photoModeEnabled == false) - { - renderer.renderHealthBars (healthbarMode); - } - - // renderTeamColorPlane - if ((renderExtraTeamColor & renderTeamColorPlaneBit) > 0) - { - renderer.renderTeamColorPlane (); - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderObjects]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, renderFps, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled && chrono.getMillis () > 0) - chrono.start (); - } - - //mouse 3d - renderer.renderMouse3d (); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderMouse3d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - - renderer.renderUnitsToBuild (avgRenderFps); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderUnitsToBuild]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - renderFps, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - renderer.setLastRenderFps (lastRenderFps); - } - - void Game::updateWorldStats () - { - world.getStats ()->setWorldTimeElapsed (world. - getTimeFlow ()->getTime ()); - - if (difftime ((long int) time (NULL), lastMaxUnitCalcTime) >= 1) - { - lastMaxUnitCalcTime = time (NULL); - - int totalUnitcount = 0; - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - totalUnitcount += faction->getUnitCount (); - } - - if (world.getStats ()->getMaxConcurrentUnitCount () < totalUnitcount) - { - world.getStats ()->setMaxConcurrentUnitCount (totalUnitcount); - } - world. - getStats ()->setTotalEndGameConcurrentUnitCount (totalUnitcount); - world.getStats ()->setFramesPlayed (world.getFrameCount ()); - } - } - - string Game::getDebugStats (std::map < int, string > &factionDebugInfo) - { - string str = ""; - - if (this->masterserverMode == false) - { - str += - "MouseXY: " + intToStr (mouseX) + "," + intToStr (mouseY) + "\n"; - - if (world. - getMap ()->isInsideSurface (world. - getMap ()->toSurfCoords - (mouseCellPos)) == true) - { - str += - "MouseXY cell coords: " + intToStr (mouseCellPos.x) + "," + - intToStr (mouseCellPos.y) + "\n"; - } - - str += - "PosObjWord: " + intToStr (gui.getPosObjWorld ().x) + "," + - intToStr (gui.getPosObjWorld ().y) + "\n"; - } - - str += - "Render FPS: " + intToStr (lastRenderFps) + "[" + - intToStr (avgRenderFps) + "]\n"; - str += - "Update FPS: " + intToStr (lastUpdateFps) + "[" + - intToStr (avgUpdateFps) + "]\n"; - - if (this->masterserverMode == false) - { - str += - "GameCamera pos: " + floatToStr (gameCamera.getPos ().x) + "," + - floatToStr (gameCamera.getPos ().y) + "," + - floatToStr (gameCamera.getPos ().z) + "\n"; - //str+= "Cached surfacedata: " + intToStr(renderer.getCachedSurfaceDataSize())+"\n"; - } - - //intToStr(stats.getFramesToCalculatePlaytime()/GameConstants::updateFps/60 - str += - "Time: " + floatToStr (world.getTimeFlow ()->getTime (), - 2) + " [" + - floatToStr ((double) world. - getStats ()->getFramesToCalculatePlaytime () / - (float) GameConstants::updateFps / 60.0, 2) + "]\n"; - - if (SystemFlags::getThreadedLoggerRunning () == true) - { - str += - "Log buffer count: " + - intToStr (SystemFlags::getLogEntryBufferCount ()) + "\n"; - } - - str += - "UnitRangeCellsLookupItemCache: " + - world.getUnitUpdater ()->getUnitRangeCellsLookupItemCacheStats () + - "\n"; - str += - "ExploredCellsLookupItemCache: " + - world.getExploredCellsLookupItemCacheStats () + "\n"; - str += - "FowAlphaCellsLookupItemCache: " + - world.getFowAlphaCellsLookupItemCacheStats () + "\n"; - - const string - selectionType = - toLower (Config:: - getInstance ().getString ("SelectionType", - Config::colorPicking)); - str += "Selection type: " + toLower (selectionType) + "\n"; - - if (selectionType == Config::colorPicking) - { - str += - "Color picking used color list size: " + - intToStr (BaseColorPickEntity::getUsedColorIDListSize ()) + "\n"; - } - - //str+= "AllFactionsCacheStats: " + world.getAllFactionsCacheStats()+"\n"; - //str+= "AttackWarningCount: " + intToStr(world.getUnitUpdater()->getAttackWarningCount()) + "\n"; - - str += "Map: " + gameSettings.getMap () + "\n"; - str += "Tileset: " + gameSettings.getTileset () + "\n"; - str += "Techtree: " + gameSettings.getTech () + "\n"; - - if (this->masterserverMode == false) - { - Renderer & renderer = Renderer::getInstance (); - str += - "Triangle count: " + intToStr (renderer.getTriangleCount ()) + "\n"; - str += "Vertex count: " + intToStr (renderer.getPointCount ()) + "\n"; - } - - str += "Frame count:" + intToStr (world.getFrameCount ()) + "\n"; - - //visible quad - if (this->masterserverMode == false) - { - Renderer & renderer = Renderer::getInstance (); - Quad2i visibleQuad = renderer.getVisibleQuad (); - //Quad2i visibleQuadCamera= renderer.getVisibleQuadFromCamera(); - - str += "Visible quad: "; - for (int i = 0; i < 4; ++i) - { - str += - "(" + intToStr (visibleQuad.p[i].x) + "," + - intToStr (visibleQuad.p[i].y) + ") "; - } - // str+= "\n"; - // str+= "Visible quad camera: "; - // for(int i= 0; i<4; ++i){ - // str+= "(" + intToStr(visibleQuadCamera.p[i].x) + "," +intToStr(visibleQuadCamera.p[i].y) + ") "; - // } - str += "\n"; - - str += - "Visible quad area: " + floatToStr (visibleQuad.area ()) + - "\n"; - // str+= "Visible quad camera area: " + floatToStr(visibleQuadCamera.area()) +"\n"; - - // Rect2i boundingRect= visibleQuad.computeBoundingRect(); - // Rect2i scaledRect= boundingRect/Map::cellScale; - // scaledRect.clamp(0, 0, world.getMap()->getSurfaceW()-1, world.getMap()->getSurfaceH()-1); - // renderer.renderText3D("#1", coreData.getMenuFontNormal3D(), Vec3f(1.0f), scaledRect.p[0].x, scaledRect.p[0].y, false); - // renderer.renderText3D("#2", coreData.getMenuFontNormal3D(), Vec3f(1.0f), scaledRect.p[1].x, scaledRect.p[1].y, false); - } - - int totalUnitcount = 0; - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - totalUnitcount += faction->getUnitCount (); - } - - if (this->masterserverMode == false) - { - Renderer & renderer = Renderer::getInstance (); - VisibleQuadContainerCache & qCache = renderer.getQuadCache (); - int visibleUnitCount = (int) qCache.visibleQuadUnitList.size (); - str += - "Visible unit count: " + intToStr (visibleUnitCount) + - " total: " + intToStr (totalUnitcount) + "\n"; - - int visibleObjectCount = (int) qCache.visibleObjectList.size (); - str += - "Visible object count: " + intToStr (visibleObjectCount) + "\n"; - } - else - { - str += "Total unit count: " + intToStr (totalUnitcount) + "\n"; - } - - // resources - for (int i = 0; i < world.getFactionCount (); ++i) - { - string factionInfo = this->gameSettings.getNetworkPlayerName (i); - //factionInfo += " [" + this->gameSettings.getNetworkPlayerUUID(i) + "]"; - float multi = world.getStats ()->getResourceMultiplier (i); - string multiplier = "[" + floatToStr (multi, 1) + "]"; - switch (this->gameSettings.getFactionControl (i)) - { - case ctCpuEasy: - factionInfo += " CPU Easy" + multiplier; - break; - case ctCpu: - factionInfo += " CPU Normal" + multiplier; - break; - case ctCpuUltra: - factionInfo += " CPU Ultra" + multiplier; - break; - case ctCpuZeta: - factionInfo += " CPU Zeta" + multiplier; - break; - } - - factionInfo += - " [" + formatString (this->gameSettings.getFactionTypeName (i)) + - " team: " + intToStr (this->gameSettings.getTeam (i)) + "]"; - -// bool showResourceDebugInfo = true; -// if(showResourceDebugInfo == true) { -// factionInfo +=" res: "; -// for(int j = 0; j < world.getTechTree()->getResourceTypeCount(); ++j) { -// factionInfo += world.getFaction(i)->getResource(j)->getType()->getName()+":"+intToStr(world.getFaction(i)->getResource(j)->getAmount()); -// factionInfo += " "; -// } -// } - - factionDebugInfo[i] = factionInfo; - } - - return str; - } - - void Game::render2d () - { - Renderer & renderer = Renderer::getInstance (); - //Config &config= Config::getInstance(); - CoreData & coreData = CoreData::getInstance (); - - //init - renderer.reset2d (); - - //HUD - if (visibleHUD == true && photoModeEnabled == false) - { - renderer.renderHud (); - } - //display - renderer.renderDisplay (); - - //minimap - if (photoModeEnabled == false) - { - renderer.renderMinimap (); - } - - renderer.renderVisibleMarkedCells (); - renderer.renderVisibleMarkedCells (true, lastMousePos.x, - lastMousePos.y); - - //selection - renderer.renderSelectionQuad (); - - //highlighted Cells - renderer.renderHighlightedCellsOnMinimap (); - - if (switchTeamConfirmMessageBox.getEnabled () == true) - { - renderer.renderMessageBox (&switchTeamConfirmMessageBox); - } - - if (disconnectPlayerConfirmMessageBox.getEnabled () == true) - { - renderer.renderMessageBox (&disconnectPlayerConfirmMessageBox); - } - - //exit message box - if (errorMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&errorMessageBox); - } - if (mainMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&mainMessageBox); - } - - //script message box - if (mainMessageBox.getEnabled () == false && - errorMessageBox.getEnabled () == false && - scriptManager.getMessageBoxEnabled ()) - { - renderer.renderMessageBox (scriptManager.getMessageBox ()); - } - - //script display text - if (!scriptManager.getDisplayText ().empty () - && !scriptManager.getMessageBoxEnabled ()) - { - Vec4f fontColor = getGui ()->getDisplay ()->getColor (); - - if (Renderer::renderText3DEnabled == true) - { - renderer.renderText3D (scriptManager.getDisplayText (), - coreData.getMenuFontNormal3D (), - Vec3f (fontColor.x, fontColor.y, - fontColor.z), 200, 660, false); - } - else - { - renderer.renderText (scriptManager.getDisplayText (), - coreData.getMenuFontNormal (), - Vec3f (fontColor.x, fontColor.y, - fontColor.z), 200, 660, false); - } - } - - renderVideoPlayer (); - - renderer.renderPopupMenu (&popupMenu); - renderer.renderPopupMenu (&popupMenuSwitchTeams); - renderer.renderPopupMenu (&popupMenuDisconnectPlayer); - - if (program != NULL) - program->renderProgramMsgBox (); - - renderer.renderChatManager (&chatManager); - - //debug info - bool perfLogging = false; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled == true - || SystemFlags::getSystemSettingType (SystemFlags:: - debugWorldSynch).enabled == - true) - { - perfLogging = true; - } - - string str = ""; - std::map < int, string > factionDebugInfo; - - if (renderer.getShowDebugUI () == true || - (perfLogging == true - && difftime ((long int) time (NULL), lastRenderLog2d) >= 1)) - { - str = getDebugStats (factionDebugInfo); - } - - if (this->getRenderInGamePerformance () == true) - { - renderer.renderPerformanceStats (); - } - else - { - static time_t lastGamePerfCheck = time (NULL); - if (difftime ((long int) time (NULL), lastGamePerfCheck) > 3) - { - lastGamePerfCheck = time (NULL); - - getGamePerformanceCounts (true); - } - } - - if (renderer.getShowDebugUI () == true) - { - const Metrics & metrics = Metrics::getInstance (); - int mh = metrics.getMinimapH (); - - if (this->getRenderInGamePerformance () == true) - { - mh = mh + ((int) gamePerformanceCounts.size () * 14); - } - - const Vec4f fontColor = getGui ()->getDisplay ()->getColor (); - - if (Renderer::renderText3DEnabled == true) - { - renderer.renderTextShadow3D (str, - coreData.getMenuFontNormal3D (), - fontColor, 10, - metrics.getVirtualH () - mh - 60, - false); - } - else - { - renderer.renderTextShadow (str, coreData.getMenuFontNormal (), - fontColor, 10, - metrics.getVirtualH () - mh - 60, false); - } - - vector < string > lineTokens; - Tokenize (str, lineTokens, "\n"); - int - fontHeightNormal = - (Renderer::renderText3DEnabled == - true ? coreData.getMenuFontNormal3D ()-> - getMetrics ()->getHeight ("W") : coreData.getMenuFontNormal ()-> - getMetrics ()->getHeight ("W")); - int fontHeightBig = - (Renderer::renderText3DEnabled == - true ? coreData.getMenuFontBig3D ()-> - getMetrics ()->getHeight ("W") : coreData.getMenuFontBig ()-> - getMetrics ()->getHeight ("W")); - int playerPosY = (int) lineTokens.size () * fontHeightNormal; - - //printf("lineTokens.size() = %d\n",lineTokens.size()); - - for (int i = 0; i < world.getFactionCount (); ++i) - { - string factionInfo = factionDebugInfo[i]; - Vec3f - playerColor = - world.getFaction (i)->getTexture ()-> - getPixmapConst ()->getPixel3f (0, 0); - - if (Renderer::renderText3DEnabled == true) - { - renderer.renderText3D (factionInfo, - coreData.getMenuFontBig3D (), - Vec4f (playerColor.x, playerColor.y, - playerColor.z, 1.0), 10, - //metrics.getVirtualH() - mh - 90 - 280 - (i * 16), - metrics.getVirtualH () - mh - 60 - - playerPosY - fontHeightBig - - (fontHeightBig * i), false); - } - else - { - renderer.renderText (factionInfo, - coreData.getMenuFontBig (), - Vec4f (playerColor.x, playerColor.y, - playerColor.z, 1.0), 10, - //metrics.getVirtualH() - mh - 90 - 280 - (i * 16), - metrics.getVirtualH () - mh - 60 - - playerPosY - fontHeightBig - - (fontHeightBig * i), false); - } - } - - if ((renderer.getShowDebugUILevel () & debugui_unit_titles) == - debugui_unit_titles) - { - if (renderer.getAllowRenderUnitTitles () == false) - { - renderer.setAllowRenderUnitTitles (true); - } - - if (Renderer::renderText3DEnabled == true) - { - renderer.renderUnitTitles3D (coreData.getMenuFontNormal3D (), - Vec3f (1.0f)); - } - else - { - renderer.renderUnitTitles (coreData.getMenuFontNormal (), - Vec3f (1.0f)); - } - } - } - - //network status - if (renderNetworkStatus == true) - { - if (NetworkManager::getInstance ().getGameNetworkInterface () != NULL) - { - const Metrics & metrics = Metrics::getInstance (); - int mx = metrics.getMinimapX (); - //int my= metrics.getMinimapY(); - int mw = metrics.getMinimapW (); - //int mh= metrics.getMinimapH(); - const Vec4f fontColor = getGui ()->getDisplay ()->getColor (); - - if (Renderer::renderText3DEnabled == true) - { - renderer. - renderTextShadow3D (NetworkManager:: - getInstance ().getGameNetworkInterface - ()->getNetworkStatus (), - coreData.getMenuFontNormal3D (), fontColor, - mx + mw + 5, - metrics.getVirtualH () - 30 - 20, false); - } - else - { - renderer. - renderTextShadow (NetworkManager:: - getInstance ().getGameNetworkInterface - ()->getNetworkStatus (), - coreData.getMenuFontNormal (), fontColor, - mx + mw + 5, metrics.getVirtualH () - 30 - 20, - false); - } - } - } - - // clock - if (photoModeEnabled == false && timeDisplay == true) - { - renderer.renderClock (); - } - - //resource info - if (photoModeEnabled == false) - { - if (this->masterserverMode == false) - { - renderer.renderResourceStatus (); - } - renderer.renderConsole (&console, - showFullConsole ? consoleFull : - consoleNormal); - } - - //2d mouse - renderer.renderMouse2d (mouseX, mouseY, mouse2d, - gui.isSelectingPos ()? 1.f : 0.f); - - if (perfLogging == true - && difftime ((long int) time (NULL), lastRenderLog2d) >= 1) - { - lastRenderLog2d = time (NULL); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] Statistics: %s\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, str.c_str ()); - } - } - - -// ==================== misc ==================== - - void Game::checkWinner () - { - // lookup int is team #, value is players alive on team - std::map < int, int > teamsAlive = getTeamsAlive (); - - if (gameOver == false || teamsAlive.size () > 1) - { - if (gameSettings.getDefaultVictoryConditions ()) - { - checkWinnerStandard (); - } - else - { - checkWinnerScripted (); - } - } - } - - void Game::setEndGameTeamWinnersAndLosers () - { - //bool lose= false; - bool - checkTeamIndex = !(this->masterserverMode == false - && world. - getThisFaction ()->getPersonalityType () != - fpt_Observer); - - // lookup int is team #, value is players alive on team - std::map < int, int > teamsAlive; - for (int i = 0; i < world.getFactionCount (); ++i) - { - if (checkTeamIndex == false || i != world.getThisFactionIndex ()) - { - if (factionLostGame (world.getFaction (i)) == false) - { - teamsAlive[world.getFaction (i)->getTeam ()] = - teamsAlive[world.getFaction (i)->getTeam ()] + 1; - } - } - } - - // did some team win - if (teamsAlive.size () <= 1) - { - for (int i = 0; i < world.getFactionCount (); ++i) - { - if (checkTeamIndex == false || i != world.getThisFactionIndex ()) - { - if (teamsAlive.find (world.getFaction (i)->getTeam ()) != - teamsAlive.end ()) - { - world.getStats ()->setVictorious (i); - } - else if (i == world.getThisFactionIndex ()) - { - //lose= true; - } - } - } - bool firstGameOverTrigger = false; - if (gameOver == false) - { - firstGameOverTrigger = true; - gameOver = true; - } - if (this->gameSettings.isNetworkGame () == false || - this->gameSettings.getEnableObserverModeAtEndGame () == true) - { - // Let the happy winner view everything left in the world - - // This caused too much LAG for network games - if (this->gameSettings.isNetworkGame () == false) - { - Renderer::getInstance ().setPhotoMode (true); - gameCamera.setMaxHeight (PHOTO_MODE_MAXHEIGHT); - } - // END - } - - if (firstGameOverTrigger == true) - { - scriptManager.onGameOver (true); - } - - if (world.getFactionCount () == 1 - && world.getFaction (0)->getPersonalityType () == fpt_Observer) - { - //printf("!!!!!!!!!!!!!!!!!!!!"); - - //gameCamera.setMoveY(100.0); - gameCamera.zoom (-300); - //gameCamera.update(); - } -// else { -// if(lose == true) { -// showLoseMessageBox(); -// } -// else { -// showWinMessageBox(); -// } -// } - } - } - - std::map < int, int > Game::getTeamsAlive () - { - std::map < int, int > teamsAlive; - for (int factionIndex = 0; factionIndex < world.getFactionCount (); - ++factionIndex) - { - if (factionIndex != world.getThisFactionIndex ()) - { - if (factionLostGame (world.getFaction (factionIndex)) == false) - { - teamsAlive[world.getFaction (factionIndex)->getTeam ()] = - teamsAlive[world.getFaction (factionIndex)->getTeam ()] + 1; - } - } - } - // did some team win - return teamsAlive; - } - - void Game::checkWinnerStandardHeadlessOrObserver () - { - // lookup int is team #, value is players alive on team - std::map < int, int > teamsAlive = getTeamsAlive (); - - // did some team win - if (teamsAlive.size () <= 1) - { - if (this->masterserverMode == true) - { - printf ("Game finished...\n"); - } - for (int factionIndex = 0; factionIndex < world.getFactionCount (); - ++factionIndex) - { - - Faction *faction = world.getFaction (factionIndex); - if (factionIndex != world.getThisFactionIndex () && - teamsAlive.find (faction->getTeam ()) != teamsAlive.end ()) - { - - world.getStats ()->setVictorious (factionIndex); - if (this->masterserverMode == true) - { - - printf ("Player: %s is on the winning team #: %d\n", - this->gameSettings.getNetworkPlayerName (factionIndex). - c_str (), faction->getTeam ()); - } - } - } - bool wasGameOverAlready = gameOver; - gameOver = true; - - // Only need to process this once - if (wasGameOverAlready == false) - { - if (this->gameSettings.isNetworkGame () == false || - this->gameSettings.getEnableObserverModeAtEndGame () == true) - { - - // Let the happy winner view everything left in the world - // This caused too much LAG for network games - if (this->gameSettings.isNetworkGame () == false) - { - - Renderer::getInstance ().setPhotoMode (true); - gameCamera.setMaxHeight (PHOTO_MODE_MAXHEIGHT); - } - // END - } - scriptManager.onGameOver (true); - if (world.getFactionCount () == 1 && - world.getFaction (0)->getPersonalityType () == fpt_Observer) - { - gameCamera.zoom (-300); - } - else - { - showWinMessageBox (); - } - } - } - } - - void Game::checkWinnerStandardPlayer () - { - //lose - bool lose = false; - if (factionLostGame (world.getThisFaction ()) == true) - { - - bool playerLostGame = true; - // Team Shared units enabled? - if (isFlagType1BitEnabled (ft1_allow_shared_team_units) == true) - { - - // Check if all team members have lost? - for (int factionIndex = 0; - factionIndex < world.getFactionCount (); ++factionIndex) - { - - if (world.getFaction (factionIndex)->getPersonalityType () != - fpt_Observer) - { - if (world. - getFaction (factionIndex)->isAlly (world. - getThisFaction ()) == - true - && factionLostGame (world.getFaction (factionIndex)) == - false) - { - - playerLostGame = false; - break; - } - } - } - } - - if (playerLostGame == true) - { - lose = true; - for (int factionIndex = 0; - factionIndex < world.getFactionCount (); ++factionIndex) - { - - if (world.getFaction (factionIndex)->getPersonalityType () != - fpt_Observer) - { - if (world. - getFaction (factionIndex)->isAlly (world. - getThisFaction ()) == - false - && factionLostGame (world.getFaction (factionIndex)) == - false) - { - - world.getStats ()->setVictorious (factionIndex); - } - } - } - bool wasGameOverAlready = gameOver; - gameOver = true; - - // Only need to process losing once - if (wasGameOverAlready == false) - { - if (this->gameSettings.isNetworkGame () == false || - this->gameSettings.getEnableObserverModeAtEndGame () == true) - { - // Let the poor user watch everything unfold - // This caused too much LAG for network games - if (this->gameSettings.isNetworkGame () == false) - { - Renderer::getInstance ().setPhotoMode (true); - gameCamera.setMaxHeight (PHOTO_MODE_MAXHEIGHT); - } - // END - // but don't let him cheat via teamchat - chatManager.setDisableTeamMode (true); - } - scriptManager.onGameOver (!lose); - showLoseMessageBox (); - } - } - } - - //win - if (lose == false) - { - bool win = true; - for (int factionIndex = 0; factionIndex < world.getFactionCount (); - ++factionIndex) - { - - if (factionIndex != world.getThisFactionIndex ()) - { - if (world.getFaction (factionIndex)->getPersonalityType () != - fpt_Observer) - { - - if (factionLostGame (world.getFaction (factionIndex)) == - false - && world.getFaction (factionIndex)-> - isAlly (world.getThisFaction ()) == false) - { - - win = false; - } - } - } - } - - if (win) - { - for (int factionIndex = 0; - factionIndex < world.getFactionCount (); ++factionIndex) - { - if (world.getFaction (factionIndex)->getPersonalityType () != - fpt_Observer) - { - if (world. - getFaction (factionIndex)->isAlly (world.getThisFaction ())) - { - - world.getStats ()->setVictorious (factionIndex); - } - } - } - - bool wasGameOverAlready = gameOver; - gameOver = true; - - // Only need to process winning once - if (wasGameOverAlready == false) - { - if (this->gameSettings.isNetworkGame () == false || - this->gameSettings.getEnableObserverModeAtEndGame () == true) - { - // Let the happy winner view everything left in the world - - // This caused too much LAG for network games - if (this->gameSettings.isNetworkGame () == false) - { - Renderer::getInstance ().setPhotoMode (true); - gameCamera.setMaxHeight (PHOTO_MODE_MAXHEIGHT); - } - // END - } - scriptManager.onGameOver (win); - showWinMessageBox (); - } - } - } - } - - void Game::checkWinnerStandard () - { - if (world.getFactionCount () <= 0) - { - return; - } - if (this->masterserverMode == true || - world.getThisFaction ()->getPersonalityType () == fpt_Observer) - { - checkWinnerStandardHeadlessOrObserver (); - } - else - { - checkWinnerStandardPlayer (); - } - } - - void Game::checkWinnerScripted () - { - if (scriptManager.getIsGameOver ()) - { - bool wasGameOverAlready = gameOver; - gameOver = true; - - - for (int index = 0; index < world.getFactionCount (); ++index) - { - if (scriptManager.getPlayerModifiers (index)->getWinner ()) - { - - world.getStats ()->setVictorious (index); - } - } - - // Only need to process winning once - if (wasGameOverAlready == false) - { - if (this->gameSettings.isNetworkGame () == false || - this->gameSettings.getEnableObserverModeAtEndGame () == true) - { - - // Let the happy winner view everything left in the world - // This caused too much LAG for network games - if (this->gameSettings.isNetworkGame () == false) - { - Renderer::getInstance ().setPhotoMode (true); - gameCamera.setMaxHeight (PHOTO_MODE_MAXHEIGHT); - } - // END - } - - if (this->masterserverMode == true || - world.getThisFaction ()->getPersonalityType () == fpt_Observer) - { - showWinMessageBox (); - } - else - { - scriptManager. - onGameOver (scriptManager.getPlayerModifiers - (world.getThisFactionIndex ())->getWinner ()); - - if (scriptManager.getPlayerModifiers - (world.getThisFactionIndex ())->getWinner ()) - { - showWinMessageBox (); - } - else - { - showLoseMessageBox (); - } - } - } - } - } - - bool Game::isFlagType1BitEnabled (FlagTypes1 type) const - { - return ((gameSettings.getFlagTypes1 () & (uint32) type) == - (uint32) type); - } - - bool Game::factionLostGame (int factionIndex) - { - return factionLostGame (world.getFaction (factionIndex)); - } - - bool Game::factionLostGame (const Faction * faction) - { - if (faction != NULL) - { - for (int factionIndex = 0; factionIndex < faction->getUnitCount (); - ++factionIndex) - { - const UnitType *ut = faction->getUnit (factionIndex)->getType (); - if (ut->getCountInVictoryConditions () == ucvcNotSet) - { - if (faction->getUnit (factionIndex)-> - getType ()->hasSkillClass (scBeBuilt)) - { - return false; - } - } - else if (ut->getCountInVictoryConditions () == ucvcTrue) - { - return false; - } - } - } - return true; - } - -//bool Game::hasBuilding(const Faction *faction) { -// if(faction != NULL) { -// for(int i=0; igetUnitCount(); ++i) { -// if(faction->getUnit(i)->getType()->hasSkillClass(scBeBuilt)) { -// return true; -// } -// } -// } -// return false; -//} - - void Game::incSpeed () - { - if (disableSpeedChange == true) - { - return; - } - - Lang & lang = Lang::getInstance (); - - if (this->speed < Config::getInstance ().getInt ("FastSpeedLoops")) - { - if (this->speed == 0) - { - this->speed = 1; - } - else - { - this->speed++; - } - console.addLine (lang.getString ("GameSpeedSet") + " " + - ((this->speed == - 0) ? lang.getString ("Slow") : (this->speed == - 1) ? - lang.getString ("Normal") : "x" + - intToStr (this->speed))); - } - } - - void Game::decSpeed () - { - if (disableSpeedChange == true) - { - return; - } - - Lang & lang = Lang::getInstance (); - if (this->speed > 0) - { - this->speed--; - console.addLine (lang.getString ("GameSpeedSet") + " " + - ((this->speed == - 0) ? lang.getString ("Slow") : (this->speed == - 1) ? - lang.getString ("Normal") : "x" + - intToStr (this->speed))); - } - } - - void - Game::setPaused (bool value, bool forceAllowPauseStateChange, - bool clearCaches, bool joinNetworkGame) - { - bool - speedChangesAllowed = - !NetworkManager::getInstance ().isNetworkGame (); - //printf("Toggle pause value = %d, speedChangesAllowed = %d, forceAllowPauseStateChange = %d\n",value,speedChangesAllowed,forceAllowPauseStateChange); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled) - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "game.cpp line: %d setPaused value: %d clearCaches: %d forceAllowPauseStateChange: %d speedChangesAllowed: %d pausedForJoinGame: %d joinNetworkGame: %d\n", - __LINE__, value, clearCaches, - forceAllowPauseStateChange, - speedChangesAllowed, pausedForJoinGame, - joinNetworkGame); - //printf("Line: %d setPaused value: %d clearCaches: %d forceAllowPauseStateChange: %d speedChangesAllowed: %d pausedForJoinGame: %d joinNetworkGame: %d\n",__LINE__,value,clearCaches,forceAllowPauseStateChange,speedChangesAllowed,pausedForJoinGame,joinNetworkGame); - - if (forceAllowPauseStateChange == true || speedChangesAllowed == true) - { - //printf("setPaused paused = %d, value = %d\n",paused,value); - - NetworkManager & networkManager = NetworkManager::getInstance (); - - // Cannot change pause state while client is joining in progress game - if (pausedForJoinGame == true && joinNetworkGame == false && - networkManager.getNetworkRole () == nrServer) - { - - ServerInterface *server = - NetworkManager::getInstance ().getServerInterface (); - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - this->gameSettings.getUniqueNetworkPlayerLanguages (); - - bool haveClientConnectedButNoReady = false; - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - - MutexSafeWrapper - safeMutex (server->getSlotMutex - (faction->getStartLocationIndex ()), CODE_AT_LINE); - ConnectionSlot *slot = - server->getSlot (faction->getStartLocationIndex (), - false); - if (slot != NULL && slot->isConnected () == true - && slot->isReady () == false) - { - for (unsigned int i = 0; i < languageList.size (); ++i) - { - - char szMsg[8096] = ""; - if (lang.hasString ("JoinPlayerToCurrentGameLaunch", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString - ("JoinPlayerToCurrentGameLaunch", - languageList[i]).c_str (), - slot->getName ().c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Player: %s is about to join the game, please wait...", - slot->getName ().c_str ()); - } - - safeMutex.ReleaseLock (); - - bool localEcho = lang.isLanguageLocal (languageList[i]); - server->sendTextMessage (szMsg, -1, localEcho, - languageList[i]); - sleep (1); - - haveClientConnectedButNoReady = true; - } - } - } - - if (haveClientConnectedButNoReady == true) - { - return; - } - } - - Lang & lang = Lang::getInstance (); - if (value == false) - { - console.addLine (lang.getString ("GameResumed")); - - bool wasPausedForJoinGame = pausedForJoinGame; - paused = false; - pausedForJoinGame = false; - pausedBeforeJoinGame = false; - pauseStateChanged = true; - - if (clearCaches == true) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugWorldSynch).enabled) - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "game.cpp line: %d Clear Caches for resume in progress game\n", - __LINE__); - //printf("Line: %d Clear Caches for resume in progress game\n",__LINE__); - - world.clearCaches (); - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - faction->clearCaches (); - } - world.refreshAllUnitExplorations (); - } - setupPopupMenus (false); - - if (networkManager.getNetworkRole () == nrClient && - wasPausedForJoinGame == true) - { - initialResumeSpeedLoops = true; - } - - commander.setPauseNetworkCommands (false); - } - else - { - console.addLine (lang.getString ("GamePaused")); - - if (joinNetworkGame == true) - { - pausedBeforeJoinGame = paused; - } - paused = true; - pausedForJoinGame = joinNetworkGame; - pauseStateChanged = true; - - if (clearCaches == true) - { - //printf("Line: %d Clear Caches for resume in progress game\n",__LINE__); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugWorldSynch).enabled) - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "game.cpp line: %d Clear Caches for resume in progress game\n", - __LINE__); - - world.clearCaches (); - for (int i = 0; i < world.getFactionCount (); ++i) - { - Faction *faction = world.getFaction (i); - faction->clearCaches (); - } - world.refreshAllUnitExplorations (); - } - pauseRequestSent = false; - - commander.setPauseNetworkCommands (joinNetworkGame); - } - //printf("setPaused new paused = %d\n",paused); - } - } - - bool Game::getPaused () - { - bool - speedChangesAllowed = - !NetworkManager::getInstance ().isNetworkGame (); - if (speedChangesAllowed) - { - if (popupMenu.getVisible () == true - || popupMenuSwitchTeams.getVisible () == true) - { - return true; - } -// if(mainMessageBox.getEnabled() == true || errorMessageBox.getEnabled() == true){ -// return true; -// } - if (currentUIState != NULL) - { - return true; - } - } - return paused; - } - - int Game::getUpdateLoops () - { - if (commander.hasReplayCommandListForFrame () == true) - { - return 1; - } - - if (getPaused ()) - { - return 0; - } - else if (this->speed == 0) - { - return updateFps % 2 == 0 ? 1 : 0; - } - else - return this->speed; - } - - void Game::showLoseMessageBox () - { - Lang & lang = Lang::getInstance (); - - NetworkManager & networkManager = NetworkManager::getInstance (); - if (networkManager.isNetworkGame () == true - && networkManager.getNetworkRole () == nrServer) - { - showMessageBox (lang.getString ("YouLose") + " " + - lang.getString ("ExitBattleServerQuestion"), - lang.getString ("BattleOver"), false); - } - else - { - showMessageBox (lang.getString ("YouLose") + " " + - lang.getString ("ExitBattleQuestion"), - lang.getString ("BattleOver"), false); - } - } - - void Game::showWinMessageBox () - { - Lang & lang = Lang::getInstance (); - - if (this->masterserverMode == true - || world.getThisFaction ()->getPersonalityType () == fpt_Observer) - { - showMessageBox (lang.getString ("GameOver") + " " + - lang.getString ("ExitBattleQuestion"), - lang.getString ("BattleOver"), false); - } - else - { - showMessageBox (lang.getString ("YouWin") + " " + - lang.getString ("ExitBattleQuestion"), - lang.getString ("BattleOver"), false); - } - } - - void - Game::showMessageBox (const string & text, const string & header, - bool toggle) - { - if (toggle == false) - { - mainMessageBox.setEnabled (false); - } - - if (mainMessageBox.getEnabled () == false) - { - mainMessageBox.setText (text); - mainMessageBox.setHeader (header); - mainMessageBox.setEnabled (true); - } - else - { - mainMessageBox.setEnabled (false); - } - } - - void - Game::showErrorMessageBox (const string & text, const string & header, - bool toggle) - { - if (toggle == false) - { - errorMessageBox.setEnabled (false); - } - - if (errorMessageBox.getEnabled () == false) - { - errorMessageBox.setText (text); - errorMessageBox.setHeader (header); - errorMessageBox.setEnabled (true); - } - else - { - errorMessageBox.setEnabled (false); - } - } - - void Game::startPerformanceTimer () - { - captureAvgTestStatus = true; - updateFpsAvgTest = -1; - renderFpsAvgTest = -1; - } - - void Game::endPerformanceTimer () - { - captureAvgTestStatus = false; - } - - Vec2i Game::getPerformanceTimerResults () - { - Vec2i results (this->updateFpsAvgTest, this->renderFpsAvgTest); - return results; - } - - void Game::consoleAddLine (string line) - { - console.addLine (line); - } - void Game::toggleTeamColorMarker () - { - renderExtraTeamColor++; - renderExtraTeamColor = renderExtraTeamColor % 4; - } - - void - Game::addNetworkCommandToReplayList (NetworkCommand * networkCommand, - int worldFrameCount) - { - Config & config = Config::getInstance (); - if (config.getBool ("SaveCommandsForReplay", "false") == true) - { - replayCommandList.push_back (make_pair - (worldFrameCount, *networkCommand)); - } - } - - void Game::renderVideoPlayer () - { - if (videoPlayer != NULL) - { - if (videoPlayer->isPlaying () == true) - { - videoPlayer->playFrame (false); - } - else - { - delete videoPlayer; - videoPlayer = NULL; - } - } - } - - void Game::playStaticVideo (const string & playVideo) - { - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false - &&::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer () == true) - { - - //togglePauseGame(true,true); - tryPauseToggle (true); - setupRenderForVideo (); - - -// Context *c= GraphicsInterface::getInstance().getCurrentContext(); -// SDL_Surface *screen = static_cast(c)->getPlatformContextGlPtr()->getScreen(); -// -// string vlcPluginsPath = Config::getInstance().getString("VideoPlayerPluginsPath",""); -// //printf("screen->w = %d screen->h = %d screen->format->BitsPerPixel = %d\n",screen->w,screen->h,screen->format->BitsPerPixel); -// Shared::Graphics::VideoPlayer player(playVideo.c_str(), -// screen, -// 0,0, -// screen->w, -// screen->h, -// screen->format->BitsPerPixel, -// vlcPluginsPath, -// SystemFlags::VERBOSE_MODE_ENABLED); -// player.PlayVideo(); - //} - //tryPauseToggle(false); - - playStreamingVideo (playVideo); - playingStaticVideo = true; - } - } - void Game::playStreamingVideo (const string & playVideo) - { - if (videoPlayer == NULL) - { - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false - &&::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer () == - true) - { - Context *c = GraphicsInterface::getInstance ().getCurrentContext (); - PlatformContextGl *glCtx = - static_cast < ContextGl * >(c)->getPlatformContextGlPtr (); - SDL_Window *window = glCtx->getScreenWindow (); - SDL_Surface *screen = glCtx->getScreenSurface (); - - string - vlcPluginsPath = - Config::getInstance ().getString ("VideoPlayerPluginsPath", ""); - - videoPlayer = - new::Shared::Graphics::VideoPlayer (&Renderer::getInstance (), - playVideo, "", window, 0, - 0, screen->w, screen->h, - screen->format->BitsPerPixel, - false, vlcPluginsPath, - SystemFlags::VERBOSE_MODE_ENABLED); - } - } - else - { - if (videoPlayer->isPlaying () == false) - { - delete videoPlayer; - videoPlayer = NULL; - - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false - &&::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer () == - true) - { - Context *c = - GraphicsInterface::getInstance ().getCurrentContext (); - PlatformContextGl *glCtx = - static_cast < ContextGl * >(c)->getPlatformContextGlPtr (); - SDL_Window *window = glCtx->getScreenWindow (); - SDL_Surface *screen = glCtx->getScreenSurface (); - - string - vlcPluginsPath = - Config::getInstance ().getString ("VideoPlayerPluginsPath", ""); - - videoPlayer = - new::Shared::Graphics::VideoPlayer (&Renderer::getInstance (), - playVideo, "", window, - 0, 0, screen->w, - screen->h, - screen-> - format->BitsPerPixel, false, - vlcPluginsPath, - SystemFlags::VERBOSE_MODE_ENABLED); - } - } - } - - if (videoPlayer != NULL) - { - videoPlayer->initPlayer (); - } - } - void Game::stopStreamingVideo (const string & playVideo) - { - if (videoPlayer != NULL) - { - videoPlayer->StopVideo (); - } - } - - void Game::stopAllVideo () - { - if (videoPlayer != NULL) - { - videoPlayer->StopVideo (); - } - } - - bool - Game::clientLagHandler (int slotIndex, - bool networkPauseGameForLaggedClients) - { - if (networkPauseGameForLaggedClients == true) - { - printf - ("**WARNING** Detected lag from client: %d networkPauseGameForLaggedClients: %d\n", - slotIndex, networkPauseGameForLaggedClients); - } - else - { - printf - ("==> Requested Resume Game after Pause for lagging client(s)...\n"); - } - - this->networkPauseGameForLaggedClientsRequested = - networkPauseGameForLaggedClients; - this->networkResumeGameForLaggedClientsRequested = - !networkPauseGameForLaggedClients; - return true; - } - - void Game::saveGame () - { - string file = this->saveGame (GameConstants::saveGameFilePattern); - char szBuf[8096] = ""; - Lang & lang = Lang::getInstance (); - snprintf (szBuf, 8096, lang.getString ("GameSaved", "", true).c_str (), - file.c_str ()); - console.addLine (szBuf); - - Config & config = Config::getInstance (); - config.setString ("LastSavedGame", file); - config.save (); - } - - string Game::saveGame (string name, const string & path) - { - Config & config = Config::getInstance (); - // auto name file if using saved file pattern string - if (name == GameConstants::saveGameFilePattern) - { - //time_t curTime = time(NULL); - //struct tm *loctime = localtime (&curTime); - struct tm loctime = threadsafe_localtime (systemtime_now ()); - char szBuf2[100] = ""; - strftime (szBuf2, 100, "%Y%m%d_%H%M%S", &loctime); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, name.c_str (), szBuf2); - name = szBuf; - } - else if (name == GameConstants::saveGameFileAutoTestDefault) - { - //time_t curTime = time(NULL); - //struct tm *loctime = localtime (&curTime); - struct tm loctime = threadsafe_localtime (systemtime_now ()); - char szBuf2[100] = ""; - strftime (szBuf2, 100, "%Y%m%d_%H%M%S", &loctime); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, name.c_str (), szBuf2); - name = szBuf; - } - - // Save the file now - string saveGameFile = path + name; - if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) != - "") - { - saveGameFile = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - saveGameFile; - } - else - { - string userData = config.getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - saveGameFile = userData + saveGameFile; - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Saving game to [%s]\n", saveGameFile.c_str ()); - - // This condition will re-play all the commands from a replay file - // INSTEAD of saving from a saved game. - if (config.getBool ("SaveCommandsForReplay", "false") == true) - { - std::map < string, string > mapTagReplacements; - XmlTree xmlTreeSaveGame (XML_RAPIDXML_ENGINE); - - xmlTreeSaveGame.init ("zetaglest-saved-game"); - XmlNode *rootNodeReplay = xmlTreeSaveGame.getRootNode (); - - //std::map mapTagReplacements; - //time_t now = time(NULL); - //struct tm *loctime = localtime (&now); - struct tm loctime = threadsafe_localtime (systemtime_now ()); - char szBuf[4096] = ""; - strftime (szBuf, 4095, "%Y-%m-%d %H:%M:%S", &loctime); - - rootNodeReplay->addAttribute ("version", glestVersionString, - mapTagReplacements); - rootNodeReplay->addAttribute ("timestamp", szBuf, mapTagReplacements); - - XmlNode *gameNodeReplay = rootNodeReplay->addChild ("Game"); - gameSettings.saveGame (gameNodeReplay); - - gameNodeReplay->addAttribute ("LastWorldFrameCount", - intToStr (world.getFrameCount ()), - mapTagReplacements); - - for (unsigned int i = 0; i < replayCommandList.size (); ++i) - { - std::pair < int, NetworkCommand > & cmd = replayCommandList[i]; - XmlNode *networkCommandNode = cmd.second.saveGame (gameNodeReplay); - networkCommandNode->addAttribute ("worldFrameCount", - intToStr (cmd.first), - mapTagReplacements); - } - - string replayFile = saveGameFile + ".replay"; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Saving game replay commands to [%s]\n", - replayFile.c_str ()); - xmlTreeSaveGame.save (replayFile); - } - - XmlTree xmlTree; - xmlTree.init ("zetaglest-saved-game"); - XmlNode *rootNode = xmlTree.getRootNode (); - - std::map < string, string > mapTagReplacements; - //time_t now = time(NULL); - //struct tm *loctime = localtime (&now); - struct tm loctime = threadsafe_localtime (systemtime_now ()); - char szBuf[4096] = ""; - strftime (szBuf, 4095, "%Y-%m-%d %H:%M:%S", &loctime); - - rootNode->addAttribute ("version", glestVersionString, - mapTagReplacements); - rootNode->addAttribute ("timestamp", szBuf, mapTagReplacements); - - XmlNode *gameNode = rootNode->addChild ("Game"); - //World world; - world.saveGame (gameNode); - //AiInterfaces aiInterfaces; - for (unsigned int i = 0; i < aiInterfaces.size (); ++i) - { - AiInterface *aiIntf = aiInterfaces[i]; - if (aiIntf != NULL) - { - aiIntf->saveGame (gameNode); - } - } - //Gui gui; - gui.saveGame (gameNode); - //GameCamera gameCamera; - gameCamera.saveGame (gameNode); - //Commander commander; - //Console console; - //ChatManager chatManager; - //ScriptManager scriptManager; - scriptManager.saveGame (gameNode); - - //misc - //Checksum checksum; - gameNode->addAttribute ("checksum", intToStr (checksum.getSum ()), - mapTagReplacements); - //string loadingText; -// int mouse2d; - gameNode->addAttribute ("mouse2d", intToStr (mouse2d), - mapTagReplacements); -// int mouseX; - gameNode->addAttribute ("mouseX", intToStr (mouseX), - mapTagReplacements); -// int mouseY; //coords win32Api - gameNode->addAttribute ("mouseY", intToStr (mouseY), - mapTagReplacements); -// Vec2i mouseCellPos; - gameNode->addAttribute ("mouseCellPos", mouseCellPos.getString (), - mapTagReplacements); -// int updateFps, lastUpdateFps, avgUpdateFps; -// int totalRenderFps, renderFps, lastRenderFps, avgRenderFps,currentAvgRenderFpsTotal; - //Uint64 tickCount; - gameNode->addAttribute ("tickCount", intToStr (tickCount), - mapTagReplacements); - - //bool paused; - gameNode->addAttribute ("paused", intToStr (paused), - mapTagReplacements); - //bool gameOver; - gameNode->addAttribute ("gameOver", intToStr (gameOver), - mapTagReplacements); - //bool renderNetworkStatus; - //bool showFullConsole; - //bool mouseMoved; - //float scrollSpeed; - gameNode->addAttribute ("scrollSpeed", floatToStr (scrollSpeed, 6), - mapTagReplacements); - //bool camLeftButtonDown; - //bool camRightButtonDown; - //bool camUpButtonDown; - //bool camDownButtonDown; - - //Speed speed; - gameNode->addAttribute ("speed", intToStr (speed), mapTagReplacements); - - //GraphicMessageBox mainMessageBox; - //GraphicMessageBox errorMessageBox; - - //misc ptr - //ParticleSystem *weatherParticleSystem; - if (weatherParticleSystem != NULL) - { - weatherParticleSystem->saveGame (gameNode); - } - //GameSettings gameSettings; - gameSettings.saveGame (gameNode); - //Vec2i lastMousePos; - gameNode->addAttribute ("lastMousePos", lastMousePos.getString (), - mapTagReplacements); - //time_t lastRenderLog2d; - gameNode->addAttribute ("lastRenderLog2d", intToStr (lastRenderLog2d), - mapTagReplacements); - //DisplayMessageFunction originalDisplayMsgCallback; - //bool isFirstRender; - gameNode->addAttribute ("isFirstRender", intToStr (isFirstRender), - mapTagReplacements); - - //bool quitTriggeredIndicator; - //int original_updateFps; - gameNode->addAttribute ("original_updateFps", - intToStr (original_updateFps), - mapTagReplacements); - //int original_cameraFps; - gameNode->addAttribute ("original_cameraFps", - intToStr (original_cameraFps), - mapTagReplacements); - - //bool captureAvgTestStatus; - gameNode->addAttribute ("captureAvgTestStatus", - intToStr (captureAvgTestStatus), - mapTagReplacements); - //int updateFpsAvgTest; - gameNode->addAttribute ("updateFpsAvgTest", intToStr (updateFpsAvgTest), - mapTagReplacements); - //int renderFpsAvgTest; - gameNode->addAttribute ("renderFpsAvgTest", intToStr (renderFpsAvgTest), - mapTagReplacements); - - //int renderExtraTeamColor; - gameNode->addAttribute ("renderExtraTeamColor", - intToStr (renderExtraTeamColor), - mapTagReplacements); - - //static const int renderTeamColorCircleBit=1; - //static const int renderTeamColorPlaneBit=2; - - //bool photoModeEnabled; - gameNode->addAttribute ("photoModeEnabled", intToStr (photoModeEnabled), - mapTagReplacements); - //bool visibleHUD; - gameNode->addAttribute ("visibleHUD", intToStr (visibleHUD), - mapTagReplacements); - - //bool timeDisplay - gameNode->addAttribute ("timeDisplay", intToStr (timeDisplay), - mapTagReplacements); - - //bool withRainEffect; - gameNode->addAttribute ("withRainEffect", intToStr (withRainEffect), - mapTagReplacements); - //Program *program; - - //bool gameStarted; - gameNode->addAttribute ("gameStarted", intToStr (gameStarted), - mapTagReplacements); - - //time_t lastMaxUnitCalcTime; - gameNode->addAttribute ("lastMaxUnitCalcTime", - intToStr (lastMaxUnitCalcTime), - mapTagReplacements); - - //PopupMenu popupMenu; - //PopupMenu popupMenuSwitchTeams; - - //std::map switchTeamIndexMap; - //GraphicMessageBox switchTeamConfirmMessageBox; - - //int exitGamePopupMenuIndex; - //int joinTeamPopupMenuIndex; - //int pauseGamePopupMenuIndex; - //int keyboardSetupPopupMenuIndex; - //GLuint statelist3dMenu; - //ProgramState *currentUIState; - - //bool masterserverMode; - - //StrSound *currentAmbientSound; - - //time_t lastNetworkPlayerConnectionCheck; - gameNode->addAttribute ("lastNetworkPlayerConnectionCheck", - intToStr (lastNetworkPlayerConnectionCheck), - mapTagReplacements); - - //time_t lastMasterServerGameStatsDump; - gameNode->addAttribute ("lastMasterServerGameStatsDump", - intToStr (lastMasterServerGameStatsDump), - mapTagReplacements); - - XmlNode *unitHighlightListNode = - gameNode->addChild ("unitHighlightList"); - //for(unsigned int i = 0; i < unitHighlightList.size(); ++i) { - for (std::map < int, HighlightSpecialUnitInfo >::iterator iterMap = - unitHighlightList.begin (); iterMap != unitHighlightList.end (); - ++iterMap) - { - HighlightSpecialUnitInfo & info = iterMap->second; - XmlNode *infoNode = unitHighlightListNode->addChild ("info"); - infoNode->addAttribute ("unitid", intToStr (iterMap->first), - mapTagReplacements); - infoNode->addAttribute ("radius", floatToStr (info.radius, 6), - mapTagReplacements); - infoNode->addAttribute ("thickness", floatToStr (info.thickness, 6), - mapTagReplacements); - infoNode->addAttribute ("color", info.color.getString (), - mapTagReplacements); - } - - gameNode->addAttribute ("disableSpeedChange", - intToStr (disableSpeedChange), - mapTagReplacements); - - xmlTree.save (saveGameFile); - - if (masterserverMode == false) - { - // take Screenshot - string jpgFileName = saveGameFile + ".jpg"; - // menu is already disabled, last rendered screen is still with enabled one. Lets render again: - render3d (); - render2d (); - Renderer::getInstance ().saveScreen (jpgFileName, - config.getInt - ("SaveGameScreenshotWidth", - "800"), - config.getInt - ("SaveGameScreenshotHeight", - "600")); - } - - return saveGameFile; - } - - void - Game::loadGame (string name, Program * programPtr, - bool isMasterserverMode, - const GameSettings * joinGameSettings) - { - Config & config = Config::getInstance (); - // This condition will re-play all the commands from a replay file - // INSTEAD of saving from a saved game. - if (joinGameSettings == NULL - && config.getBool ("SaveCommandsForReplay", "false") == true) - { - XmlTree xmlTreeReplay (XML_RAPIDXML_ENGINE); - std::map < string, string > mapExtraTagReplacementValues; - xmlTreeReplay.load (name + ".replay", - Properties::getTagReplacementValues - (&mapExtraTagReplacementValues), true); - - const XmlNode *rootNode = xmlTreeReplay.getRootNode (); - - if (rootNode->hasChild ("zetaglest-saved-game") == true) - { - rootNode = rootNode->getChild ("zetaglest-saved-game"); - } - - //const XmlNode *versionNode= rootNode->getChild("zetaglest-saved-game"); - const XmlNode *versionNode = rootNode; - - Lang & lang = Lang::getInstance (); - string gameVer = versionNode->getAttribute ("version")->getValue (); - if (gameVer != glestVersionString - && checkVersionComptability (gameVer, - glestVersionString) == false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("SavedGameBadVersion").c_str (), - gameVer.c_str (), glestVersionString.c_str ()); - throw megaglest_runtime_error (szBuf, true); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("Found saved game version that matches your application version: [%s] --> [%s]\n", - gameVer.c_str (), glestVersionString.c_str ()); - - XmlNode *gameNode = rootNode->getChild ("Game"); - - GameSettings newGameSettingsReplay; - newGameSettingsReplay.loadGame (gameNode); - //printf("Loading scenario [%s]\n",newGameSettingsReplay.getScenarioDir().c_str()); - if (newGameSettingsReplay.getScenarioDir () != "" - && fileExists (newGameSettingsReplay.getScenarioDir ()) == false) - { - newGameSettingsReplay.setScenarioDir (Scenario::getScenarioPath - (Config:: - getInstance - ().getPathListForType - (ptScenarios), - newGameSettingsReplay.getScenario - ())); - - //printf("Loading scenario #2 [%s]\n",newGameSettingsReplay.getScenarioDir().c_str()); - } - - //GameSettings newGameSettings; - //newGameSettings.loadGame(gameNode); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Game settings loaded\n"); - - NetworkManager & networkManager = NetworkManager::getInstance (); - networkManager.end (); - networkManager.init (nrServer, true); - - Game *newGame = - new Game (programPtr, &newGameSettingsReplay, isMasterserverMode); - newGame->lastworldFrameCountForReplay = - gameNode->getAttribute ("LastWorldFrameCount")->getIntValue (); - - vector < XmlNode * >networkCommandNodeList = - gameNode->getChildList ("NetworkCommand"); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("networkCommandNodeList.size() = " MG_SIZE_T_SPECIFIER - "\n", networkCommandNodeList.size ()); - for (unsigned int i = 0; i < networkCommandNodeList.size (); ++i) - { - XmlNode *node = networkCommandNodeList[i]; - int - worldFrameCount = - node->getAttribute ("worldFrameCount")->getIntValue (); - NetworkCommand command; - command.loadGame (node); - newGame->commander.addToReplayCommandList (command, - worldFrameCount); - } - - programPtr->setState (newGame); - return; - } - - XmlTree xmlTree (XML_RAPIDXML_ENGINE); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Before load of XML\n"); - std::map < string, string > mapExtraTagReplacementValues; - xmlTree.load (name, - Properties::getTagReplacementValues - (&mapExtraTagReplacementValues), true); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("After load of XML\n"); - - const XmlNode *rootNode = xmlTree.getRootNode (); - if (rootNode->hasChild ("zetaglest-saved-game") == true) - { - rootNode = rootNode->getChild ("zetaglest-saved-game"); - } - - //const XmlNode *versionNode= rootNode->getChild("zetaglest-saved-game"); - const XmlNode *versionNode = rootNode; - - Lang & lang = Lang::getInstance (); - string gameVer = versionNode->getAttribute ("version")->getValue (); - // this is the version check for loading normal save games from menu_state_load_game - if (gameVer != glestVersionString - && - (compareMajorMinorVersion - (gameVer, lastCompatibleSaveGameVersionString) < 0 - || compareMajorMinorVersion (glestVersionString, gameVer) < 0)) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("SavedGameBadVersion").c_str (), - gameVer.c_str (), glestVersionString.c_str ()); - throw megaglest_runtime_error (szBuf, true); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("Found saved game version that matches your application version: [%s] --> [%s]\n", - gameVer.c_str (), glestVersionString.c_str ()); - - XmlNode *gameNode = rootNode->getChild ("Game"); - GameSettings newGameSettings; - if (joinGameSettings != NULL) - { - newGameSettings = *joinGameSettings; - - XmlNode *worldNode = gameNode->getChild ("World"); - XmlNode *guiNode = gameNode->getChild ("Gui"); - XmlNode *selectionNode = guiNode->getChild ("Selection"); - XmlNode *statsNode = worldNode->getChild ("Stats"); - XmlNode *minimapNode = worldNode->getChild ("Minimap"); - - if (gameVer != glestVersionString - && checkVersionComptability (gameVer, - glestVersionString) == false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("SavedGameBadVersion").c_str (), - gameVer.c_str (), glestVersionString.c_str ()); - throw megaglest_runtime_error (szBuf, true); - } - // This is explored fog of war for the host player, clear it - minimapNode->clearChild ("fowPixmap1"); - - NetworkManager & networkManager = NetworkManager::getInstance (); - //NetworkRole role = networkManager.getNetworkRole(); - ClientInterface *clientInterface = - dynamic_cast < - ClientInterface * >(networkManager.getClientInterface ()); - - for (int i = 0; i < newGameSettings.getFactionCount (); ++i) - { - //replace by network - if (newGameSettings.getFactionControl (i) == ctHuman) - { - newGameSettings.setFactionControl (i, ctNetwork); - } - - //set the faction index - if (newGameSettings.getStartLocationIndex (i) == - clientInterface->getPlayerIndex ()) - { - newGameSettings.setThisFactionIndex (i); - newGameSettings.setFactionControl (i, ctNetwork); - - worldNode-> - getAttribute ("thisFactionIndex")->setValue (intToStr (i)); - //worldNode->getAttribute("thisTeamIndex")->setValue(intToStr(newGameSettings.getTeam(i))); - - XmlNode *factionNode = worldNode->getChild ("Faction", i); - factionNode-> - getAttribute ("thisFaction")->setValue (intToStr (i)); - factionNode-> - getAttribute ("control")->setValue (intToStr (ctNetwork)); - - selectionNode-> - getAttribute ("factionIndex")->setValue (intToStr (i)); - //selectionNode->getAttribute("teamIndex")->setValue(intToStr(newGameSettings.getTeam(i))); - - statsNode-> - getAttribute ("thisFactionIndex")->setValue (intToStr (i)); - } - else - { - XmlNode *factionNode = worldNode->getChild ("Faction", i); - factionNode-> - getAttribute ("thisFaction")->setValue (intToStr (0)); - } - } - } - else - { - newGameSettings.loadGame (gameNode); - //printf("Loading scenario [%s]\n",newGameSettings.getScenarioDir().c_str()); - if (newGameSettings.getScenarioDir () != "" - && fileExists (newGameSettings.getScenarioDir ()) == false) - { - newGameSettings.setScenarioDir (Scenario::getScenarioPath - (Config:: - getInstance ().getPathListForType - (ptScenarios), - newGameSettings.getScenario ())); - - //printf("Loading scenario #2 [%s]\n",newGameSettings.getScenarioDir().c_str()); - } - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Game settings loaded\n"); - - if (joinGameSettings == NULL) - { - NetworkManager & networkManager = NetworkManager::getInstance (); - networkManager.end (); - networkManager.init (nrServer, true); - } - - Game *newGame = - new Game (programPtr, &newGameSettings, isMasterserverMode); - - newGame->loadGameNode = gameNode; - newGame->inJoinGameLoading = (joinGameSettings != NULL); - -// newGame->mouse2d = gameNode->getAttribute("mouse2d")->getIntValue(); -// int mouseX; -// newGame->mouseX = gameNode->getAttribute("mouseX")->getIntValue(); -// int mouseY; //coords win32Api -// newGame->mouseY = gameNode->getAttribute("mouseY")->getIntValue(); -// Vec2i mouseCellPos; -// newGame->mouseCellPos = Vec2i::strToVec2(gameNode->getAttribute("mouseCellPos")->getValue()); -// int updateFps, lastUpdateFps, avgUpdateFps; -// int totalRenderFps, renderFps, lastRenderFps, avgRenderFps,currentAvgRenderFpsTotal; - //Uint64 tickCount; - newGame->tickCount = - gameNode->getAttribute ("tickCount")->getIntValue (); - - //bool paused; - if (newGame->inJoinGameLoading == true) - { - newGame->paused = - gameNode->getAttribute ("paused")->getIntValue () != 0; - } - else - { - //newGame->paused = gameNode->getAttribute("paused")->getIntValue() != 0; - newGame->paused = true; - } - if (newGame->paused) - newGame->console.addLine (lang.getString ("GamePaused")); - //bool gameOver; - newGame->gameOver = - gameNode->getAttribute ("gameOver")->getIntValue () != 0; - //bool renderNetworkStatus; - //bool showFullConsole; - //bool mouseMoved; - //float scrollSpeed; -// newGame->scrollSpeed = gameNode->getAttribute("scrollSpeed")->getFloatValue(); - //bool camLeftButtonDown; - //bool camRightButtonDown; - //bool camUpButtonDown; - //bool camDownButtonDown; - - //Speed speed; - //gameNode->addAttribute("speed",intToStr(speed), mapTagReplacements); - - //GraphicMessageBox mainMessageBox; - //GraphicMessageBox errorMessageBox; - - //misc ptr - //ParticleSystem *weatherParticleSystem; -// if(weatherParticleSystem != NULL) { -// weatherParticleSystem->saveGame(gameNode); -// } - //GameSettings gameSettings; -// gameSettings.saveGame(gameNode); - //Vec2i lastMousePos; -// gameNode->addAttribute("lastMousePos",lastMousePos.getString(), mapTagReplacements); - //time_t lastRenderLog2d; -// gameNode->addAttribute("lastRenderLog2d",intToStr(lastRenderLog2d), mapTagReplacements); - //DisplayMessageFunction originalDisplayMsgCallback; - //bool isFirstRender; -// gameNode->addAttribute("isFirstRender",intToStr(isFirstRender), mapTagReplacements); - - //bool quitTriggeredIndicator; - //int original_updateFps; -// gameNode->addAttribute("original_updateFps",intToStr(original_updateFps), mapTagReplacements); - //int original_cameraFps; -// gameNode->addAttribute("original_cameraFps",intToStr(original_cameraFps), mapTagReplacements); - - //bool captureAvgTestStatus; -// gameNode->addAttribute("captureAvgTestStatus",intToStr(captureAvgTestStatus), mapTagReplacements); - //int updateFpsAvgTest; -// gameNode->addAttribute("updateFpsAvgTest",intToStr(updateFpsAvgTest), mapTagReplacements); - //int renderFpsAvgTest; -// gameNode->addAttribute("renderFpsAvgTest",intToStr(renderFpsAvgTest), mapTagReplacements); - - //int renderExtraTeamColor; - newGame->renderExtraTeamColor = - gameNode->getAttribute ("renderExtraTeamColor")->getIntValue (); - - //static const int renderTeamColorCircleBit=1; - //static const int renderTeamColorPlaneBit=2; - - //bool photoModeEnabled; - //gameNode->addAttribute("photoModeEnabled",intToStr(photoModeEnabled), mapTagReplacements); - newGame->photoModeEnabled = - gameNode->getAttribute ("photoModeEnabled")->getIntValue () != 0; - //bool visibleHUD; - //gameNode->addAttribute("visibleHUD",intToStr(visibleHUD), mapTagReplacements); - newGame->visibleHUD = - gameNode->getAttribute ("visibleHUD")->getIntValue () != 0; - newGame->timeDisplay = - gameNode->getAttribute ("timeDisplay")->getIntValue () != 0; - //bool withRainEffect; - //gameNode->addAttribute("withRainEffect",intToStr(withRainEffect), mapTagReplacements); - newGame->withRainEffect = - gameNode->getAttribute ("withRainEffect")->getIntValue () != 0; - //Program *program; - - if (joinGameSettings == NULL) - { - if (gameNode->hasChild ("unitHighlightList") == true) - { - XmlNode *unitHighlightListNode = - gameNode->getChild ("unitHighlightList"); - vector < XmlNode * >infoNodeList = - unitHighlightListNode->getChildList ("info"); - for (unsigned int i = 0; i < infoNodeList.size (); ++i) - { - XmlNode *infoNode = infoNodeList[i]; - - int unitId = infoNode->getAttribute ("radius")->getIntValue (); - HighlightSpecialUnitInfo info; - info.radius = infoNode->getAttribute ("radius")->getFloatValue (); - info.thickness = - infoNode->getAttribute ("thickness")->getFloatValue (); - info.color = - Vec4f::strToVec4 (infoNode-> - getAttribute ("color")->getValue ()); - - newGame->unitHighlightList[unitId] = info; - } - } - } - - newGame->timeDisplay = - gameNode->getAttribute ("timeDisplay")->getIntValue () != 0; - - if (gameNode->hasAttribute ("disableSpeedChange") == true) - { - newGame->disableSpeedChange = - gameNode->getAttribute ("disableSpeedChange")->getIntValue () != 0; - } - - //bool gameStarted; - //gameNode->addAttribute("gameStarted",intToStr(gameStarted), mapTagReplacements); -// newGame->gameStarted = gameNode->getAttribute("gameStarted")->getIntValue(); - - //time_t lastMaxUnitCalcTime; - //gameNode->addAttribute("lastMaxUnitCalcTime",intToStr(lastMaxUnitCalcTime), mapTagReplacements); - - //PopupMenu popupMenu; - //PopupMenu popupMenuSwitchTeams; - - //std::map switchTeamIndexMap; - //GraphicMessageBox switchTeamConfirmMessageBox; - - //int exitGamePopupMenuIndex; - //int joinTeamPopupMenuIndex; - //int pauseGamePopupMenuIndex; - //int keyboardSetupPopupMenuIndex; - //GLuint statelist3dMenu; - //ProgramState *currentUIState; - - //bool masterserverMode; - - //StrSound *currentAmbientSound; - - //time_t lastNetworkPlayerConnectionCheck; - //gameNode->addAttribute("lastNetworkPlayerConnectionCheck",intToStr(lastNetworkPlayerConnectionCheck), mapTagReplacements); - - //time_t lastMasterServerGameStatsDump; - //gameNode->addAttribute("lastMasterServerGameStatsDump",intToStr(lastMasterServerGameStatsDump), mapTagReplacements); - - if (joinGameSettings == NULL) - { - newGame->gameCamera.loadGame (gameNode); - } - - const XmlNode *worldNode = gameNode->getChild ("World"); - newGame->world.loadGame (worldNode); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Starting Game ...\n"); - programPtr->setState (newGame); - } - - } -} //end namespace + } + } + } + + void saveStatsToSteam(Game * game, Stats & endStats) { + Steam *steamInstance = + CacheManager::getCachedItem < + Steam * >(GameConstants::steamCacheInstanceKey); + if (steamInstance != NULL) { + printf("\nSTEAM detected, writing out end game stats for player!\n"); + + // Write out stats here + if (NetworkManager::getInstance().isNetworkGame()) { + //printf("\nSTEAM Refresh Stats!\n"); + steamInstance->requestRefreshStats(); + for (int factionIndex = 0; + factionIndex < game->getWorld()->getFactionCount(); + ++factionIndex) { + if (factionIndex == game->getWorld()->getThisFactionIndex()) { + //printf("\nWriting out game stats for Faction Index: %d!\n",factionIndex); + if (endStats.getVictory(factionIndex)) { + steamInstance->setStatAsInt(EnumParser < + SteamStatName >::getString + (stat_online_wins).c_str(), + steamInstance->getStatAsInt + (EnumParser < + SteamStatName >::getString + (stat_online_wins).c_str()) + + 1); + } else { + steamInstance->setStatAsInt(EnumParser < + SteamStatName >::getString + (stat_online_loses).c_str(), + steamInstance->getStatAsInt + (EnumParser < + SteamStatName >::getString + (stat_online_loses).c_str()) + + 1); + } + steamInstance->setStatAsInt(EnumParser < + SteamStatName >::getString + (stat_online_kills).c_str(), + steamInstance->getStatAsInt + (EnumParser < + SteamStatName + >::getString + (stat_online_kills).c_str()) + + endStats.getKills(factionIndex)); + steamInstance->setStatAsInt(EnumParser < + SteamStatName + >::getString + (stat_online_kills_enemy).c_str(), + steamInstance->getStatAsInt + (EnumParser < + SteamStatName + >::getString + (stat_online_kills_enemy).c_str + ()) + + endStats.getEnemyKills + (factionIndex)); + steamInstance->setStatAsInt(EnumParser < + SteamStatName + >::getString + (stat_online_deaths).c_str(), + steamInstance->getStatAsInt + (EnumParser < + SteamStatName + >::getString + (stat_online_deaths).c_str()) + + endStats.getDeaths(factionIndex)); + steamInstance->setStatAsInt(EnumParser < + SteamStatName + >::getString + (stat_online_units).c_str(), + steamInstance->getStatAsInt + (EnumParser < + SteamStatName + >::getString + (stat_online_units).c_str()) + + endStats.getUnitsProduced + (factionIndex)); + steamInstance->setStatAsInt(EnumParser < + SteamStatName + >::getString + (stat_online_resources_harvested).c_str + (), + steamInstance->getStatAsInt + (EnumParser < + SteamStatName + >::getString + (stat_online_resources_harvested).c_str + ()) + + endStats.getResourcesHarvested + (factionIndex)); + if (endStats.getPlayerLeftBeforeEnd(factionIndex)) { + steamInstance->setStatAsInt(EnumParser < + SteamStatName >::getString + (stat_online_quit_before_end).c_str + (), + steamInstance->getStatAsInt + (EnumParser < + SteamStatName + >::getString + (stat_online_quit_before_end).c_str + ()) + 1); + } + steamInstance->setStatAsDouble(EnumParser < + SteamStatName >::getString + (stat_online_minutes_played).c_str + (), + steamInstance->getStatAsDouble + (EnumParser < + SteamStatName + >::getString + (stat_online_minutes_played).c_str + ()) + + getTimeDuationMinutes + (endStats.getFramesToCalculatePlaytime + (), GameConstants::updateFps)); + } + } + } + + // Write out achievements here + for (int factionIndex = 0; + factionIndex < game->getWorld()->getFactionCount(); + ++factionIndex) { + if (factionIndex == game->getWorld()->getThisFactionIndex()) { + //printf("\nWriting out game stats for Faction Index: %d won status: %d\n",factionIndex,endStats.getVictory(factionIndex)); + if (endStats.getVictory(factionIndex)) { + if (steamInstance->isUnlocked(EnumParser < + SteamAchievementName + >::getString + (ACH_WIN_ONE_GAME).c_str()) == + false) { + steamInstance->unlock(EnumParser < + SteamAchievementName + >::getString(ACH_WIN_ONE_GAME).c_str + ()); + } + if (NetworkManager::getInstance().isNetworkGame()) { + if (steamInstance->isUnlocked(EnumParser < + SteamAchievementName + >::getString + (ACH_WIN_ONE_GAME_ONLINE).c_str + ()) == false) { + steamInstance->unlock(EnumParser < + SteamAchievementName >::getString + (ACH_WIN_ONE_GAME_ONLINE).c_str()); + } + } + } + } + } + + //printf("\nSTEAM Store Stats!\n"); + steamInstance->storeStats(); + //printf("\nSTEAM Refresh Stats!\n"); + steamInstance->requestRefreshStats(); + } + } + + void Game::exitGameState(Program * program, Stats & endStats) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + Game *game = dynamic_cast (program->getState()); + + //printf("game = %p\n",game); + + if (game) { + game->setEndGameTeamWinnersAndLosers(); + game->endGame(); + } + + if ((game != NULL && game->isMasterserverMode() == true) || + Config::getInstance().getBool("AutoTest") == true) { + printf("Game ending with stats:\n"); + printf("-----------------------\n"); + + string gameStats = endStats.getStats(); + printf("%s", gameStats.c_str()); + + printf("-----------------------\n"); + } + + saveStatsToSteam(game, endStats); + + ProgramState *newState = new BattleEnd(program, &endStats, game); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + program->setState(newState, false); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + // ==================== PRIVATE ==================== + + void + Game::highlightUnit(int unitId, float radius, float thickness, + Vec4f color) { + HighlightSpecialUnitInfo info; + info.radius = radius; + info.thickness = thickness; + info.color = color; + unitHighlightList[unitId] = info; + } + + void Game::unhighlightUnit(int unitId) { + unitHighlightList.erase(unitId); + } + + // ==================== render ==================== + + void Game::render3d() { + Chrono chrono; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled) + chrono.start(); + + Renderer & renderer = Renderer::getInstance(); + + //init + renderer.reset3d(); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [reset3d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + // renderer.computeVisibleQuad(); + // if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] renderFps = %d took msecs: %lld [computeVisibleQuad]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,renderFps,chrono.getMillis()); + // if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + renderer.loadGameCameraMatrix(); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [loadGameCameraMatrix]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + renderer.computeVisibleQuad(); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [computeVisibleQuad]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + renderer.setupLighting(); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [setupLighting]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //shadow map + renderer.renderShadowsToTexture(avgRenderFps); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderShadowsToTexture]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //clear buffers + renderer.clearBuffers(); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d renderFps = %d took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //surface + renderer.renderSurface(avgRenderFps); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderSurface]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //selection circles + renderer.renderSelectionEffects(healthbarMode); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderSelectionEffects]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + // renderTeamColorCircle + if ((renderExtraTeamColor & renderTeamColorCircleBit) > 0) { + renderer.renderTeamColorCircle(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderObjects]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, renderFps, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + chrono.start(); + } + + renderer.renderSpecialHighlightUnits(unitHighlightList); + + // renderTeamColorCircle + renderer.renderMorphEffects(); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderObjects]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //objects + renderer.renderObjects(avgRenderFps); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderObjects]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //ground units + renderer.renderUnits(false, avgRenderFps); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderUnits]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //water + renderer.renderWater(); + renderer.renderWaterEffects(); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderWater]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //air units + renderer.renderUnits(true, avgRenderFps); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderUnits]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //particles + renderer.renderParticleManager(rsGame); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderParticleManager]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //renderOnTopBars (aka Healthbars) + if (photoModeEnabled == false) { + renderer.renderHealthBars(healthbarMode); + } + + // renderTeamColorPlane + if ((renderExtraTeamColor & renderTeamColorPlaneBit) > 0) { + renderer.renderTeamColorPlane(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderObjects]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, renderFps, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled && chrono.getMillis() > 0) + chrono.start(); + } + + //mouse 3d + renderer.renderMouse3d(); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderMouse3d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + + renderer.renderUnitsToBuild(avgRenderFps); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] renderFps = %d took msecs: %lld [renderUnitsToBuild]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + renderFps, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + renderer.setLastRenderFps(lastRenderFps); + } + + void Game::updateWorldStats() { + world.getStats()->setWorldTimeElapsed(world. + getTimeFlow()->getTime()); + + if (difftime((long int) time(NULL), lastMaxUnitCalcTime) >= 1) { + lastMaxUnitCalcTime = time(NULL); + + int totalUnitcount = 0; + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + totalUnitcount += faction->getUnitCount(); + } + + if (world.getStats()->getMaxConcurrentUnitCount() < totalUnitcount) { + world.getStats()->setMaxConcurrentUnitCount(totalUnitcount); + } + world. + getStats()->setTotalEndGameConcurrentUnitCount(totalUnitcount); + world.getStats()->setFramesPlayed(world.getFrameCount()); + } + } + + string Game::getDebugStats(std::map < int, string > &factionDebugInfo) { + string str = ""; + + if (this->masterserverMode == false) { + str += + "MouseXY: " + intToStr(mouseX) + "," + intToStr(mouseY) + "\n"; + + if (world. + getMap()->isInsideSurface(world. + getMap()->toSurfCoords + (mouseCellPos)) == true) { + str += + "MouseXY cell coords: " + intToStr(mouseCellPos.x) + "," + + intToStr(mouseCellPos.y) + "\n"; + } + + str += + "PosObjWord: " + intToStr(gui.getPosObjWorld().x) + "," + + intToStr(gui.getPosObjWorld().y) + "\n"; + } + + str += + "Render FPS: " + intToStr(lastRenderFps) + "[" + + intToStr(avgRenderFps) + "]\n"; + str += + "Update FPS: " + intToStr(lastUpdateFps) + "[" + + intToStr(avgUpdateFps) + "]\n"; + + if (this->masterserverMode == false) { + str += + "GameCamera pos: " + floatToStr(gameCamera.getPos().x) + "," + + floatToStr(gameCamera.getPos().y) + "," + + floatToStr(gameCamera.getPos().z) + "\n"; + //str+= "Cached surfacedata: " + intToStr(renderer.getCachedSurfaceDataSize())+"\n"; + } + + //intToStr(stats.getFramesToCalculatePlaytime()/GameConstants::updateFps/60 + str += + "Time: " + floatToStr(world.getTimeFlow()->getTime(), + 2) + " [" + + floatToStr((double) world. + getStats()->getFramesToCalculatePlaytime() / + (float) GameConstants::updateFps / 60.0, 2) + "]\n"; + + if (SystemFlags::getThreadedLoggerRunning() == true) { + str += + "Log buffer count: " + + intToStr(SystemFlags::getLogEntryBufferCount()) + "\n"; + } + + str += + "UnitRangeCellsLookupItemCache: " + + world.getUnitUpdater()->getUnitRangeCellsLookupItemCacheStats() + + "\n"; + str += + "ExploredCellsLookupItemCache: " + + world.getExploredCellsLookupItemCacheStats() + "\n"; + str += + "FowAlphaCellsLookupItemCache: " + + world.getFowAlphaCellsLookupItemCacheStats() + "\n"; + + const string + selectionType = + toLower(Config:: + getInstance().getString("SelectionType", + Config::colorPicking)); + str += "Selection type: " + toLower(selectionType) + "\n"; + + if (selectionType == Config::colorPicking) { + str += + "Color picking used color list size: " + + intToStr(BaseColorPickEntity::getUsedColorIDListSize()) + "\n"; + } + + //str+= "AllFactionsCacheStats: " + world.getAllFactionsCacheStats()+"\n"; + //str+= "AttackWarningCount: " + intToStr(world.getUnitUpdater()->getAttackWarningCount()) + "\n"; + + str += "Map: " + gameSettings.getMap() + "\n"; + str += "Tileset: " + gameSettings.getTileset() + "\n"; + str += "Techtree: " + gameSettings.getTech() + "\n"; + + if (this->masterserverMode == false) { + Renderer & renderer = Renderer::getInstance(); + str += + "Triangle count: " + intToStr(renderer.getTriangleCount()) + "\n"; + str += "Vertex count: " + intToStr(renderer.getPointCount()) + "\n"; + } + + str += "Frame count:" + intToStr(world.getFrameCount()) + "\n"; + + //visible quad + if (this->masterserverMode == false) { + Renderer & renderer = Renderer::getInstance(); + Quad2i visibleQuad = renderer.getVisibleQuad(); + //Quad2i visibleQuadCamera= renderer.getVisibleQuadFromCamera(); + + str += "Visible quad: "; + for (int i = 0; i < 4; ++i) { + str += + "(" + intToStr(visibleQuad.p[i].x) + "," + + intToStr(visibleQuad.p[i].y) + ") "; + } + // str+= "\n"; + // str+= "Visible quad camera: "; + // for(int i= 0; i<4; ++i){ + // str+= "(" + intToStr(visibleQuadCamera.p[i].x) + "," +intToStr(visibleQuadCamera.p[i].y) + ") "; + // } + str += "\n"; + + str += + "Visible quad area: " + floatToStr(visibleQuad.area()) + + "\n"; + // str+= "Visible quad camera area: " + floatToStr(visibleQuadCamera.area()) +"\n"; + + // Rect2i boundingRect= visibleQuad.computeBoundingRect(); + // Rect2i scaledRect= boundingRect/Map::cellScale; + // scaledRect.clamp(0, 0, world.getMap()->getSurfaceW()-1, world.getMap()->getSurfaceH()-1); + // renderer.renderText3D("#1", coreData.getMenuFontNormal3D(), Vec3f(1.0f), scaledRect.p[0].x, scaledRect.p[0].y, false); + // renderer.renderText3D("#2", coreData.getMenuFontNormal3D(), Vec3f(1.0f), scaledRect.p[1].x, scaledRect.p[1].y, false); + } + + int totalUnitcount = 0; + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + totalUnitcount += faction->getUnitCount(); + } + + if (this->masterserverMode == false) { + Renderer & renderer = Renderer::getInstance(); + VisibleQuadContainerCache & qCache = renderer.getQuadCache(); + int visibleUnitCount = (int) qCache.visibleQuadUnitList.size(); + str += + "Visible unit count: " + intToStr(visibleUnitCount) + + " total: " + intToStr(totalUnitcount) + "\n"; + + int visibleObjectCount = (int) qCache.visibleObjectList.size(); + str += + "Visible object count: " + intToStr(visibleObjectCount) + "\n"; + } else { + str += "Total unit count: " + intToStr(totalUnitcount) + "\n"; + } + + // resources + for (int i = 0; i < world.getFactionCount(); ++i) { + string factionInfo = this->gameSettings.getNetworkPlayerName(i); + //factionInfo += " [" + this->gameSettings.getNetworkPlayerUUID(i) + "]"; + float multi = world.getStats()->getResourceMultiplier(i); + string multiplier = "[" + floatToStr(multi, 1) + "]"; + switch (this->gameSettings.getFactionControl(i)) { + case ctCpuEasy: + factionInfo += " CPU Easy" + multiplier; + break; + case ctCpu: + factionInfo += " CPU Normal" + multiplier; + break; + case ctCpuUltra: + factionInfo += " CPU Ultra" + multiplier; + break; + case ctCpuZeta: + factionInfo += " CPU Zeta" + multiplier; + break; + } + + factionInfo += + " [" + formatString(this->gameSettings.getFactionTypeName(i)) + + " team: " + intToStr(this->gameSettings.getTeam(i)) + "]"; + + // bool showResourceDebugInfo = true; + // if(showResourceDebugInfo == true) { + // factionInfo +=" res: "; + // for(int j = 0; j < world.getTechTree()->getResourceTypeCount(); ++j) { + // factionInfo += world.getFaction(i)->getResource(j)->getType()->getName()+":"+intToStr(world.getFaction(i)->getResource(j)->getAmount()); + // factionInfo += " "; + // } + // } + + factionDebugInfo[i] = factionInfo; + } + + return str; + } + + void Game::render2d() { + Renderer & renderer = Renderer::getInstance(); + //Config &config= Config::getInstance(); + CoreData & coreData = CoreData::getInstance(); + + //init + renderer.reset2d(); + + //HUD + if (visibleHUD == true && photoModeEnabled == false) { + renderer.renderHud(); + } + //display + renderer.renderDisplay(); + + //minimap + if (photoModeEnabled == false) { + renderer.renderMinimap(); + } + + renderer.renderVisibleMarkedCells(); + renderer.renderVisibleMarkedCells(true, lastMousePos.x, + lastMousePos.y); + + //selection + renderer.renderSelectionQuad(); + + //highlighted Cells + renderer.renderHighlightedCellsOnMinimap(); + + if (switchTeamConfirmMessageBox.getEnabled() == true) { + renderer.renderMessageBox(&switchTeamConfirmMessageBox); + } + + if (disconnectPlayerConfirmMessageBox.getEnabled() == true) { + renderer.renderMessageBox(&disconnectPlayerConfirmMessageBox); + } + + //exit message box + if (errorMessageBox.getEnabled()) { + renderer.renderMessageBox(&errorMessageBox); + } + if (mainMessageBox.getEnabled()) { + renderer.renderMessageBox(&mainMessageBox); + } + + //script message box + if (mainMessageBox.getEnabled() == false && + errorMessageBox.getEnabled() == false && + scriptManager.getMessageBoxEnabled()) { + renderer.renderMessageBox(scriptManager.getMessageBox()); + } + + //script display text + if (!scriptManager.getDisplayText().empty() + && !scriptManager.getMessageBoxEnabled()) { + Vec4f fontColor = getGui()->getDisplay()->getColor(); + + if (Renderer::renderText3DEnabled == true) { + renderer.renderText3D(scriptManager.getDisplayText(), + coreData.getMenuFontNormal3D(), + Vec3f(fontColor.x, fontColor.y, + fontColor.z), 200, 660, false); + } else { + renderer.renderText(scriptManager.getDisplayText(), + coreData.getMenuFontNormal(), + Vec3f(fontColor.x, fontColor.y, + fontColor.z), 200, 660, false); + } + } + + renderVideoPlayer(); + + renderer.renderPopupMenu(&popupMenu); + renderer.renderPopupMenu(&popupMenuSwitchTeams); + renderer.renderPopupMenu(&popupMenuDisconnectPlayer); + + if (program != NULL) + program->renderProgramMsgBox(); + + renderer.renderChatManager(&chatManager); + + //debug info + bool perfLogging = false; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled == true + || SystemFlags::getSystemSettingType(SystemFlags:: + debugWorldSynch).enabled == + true) { + perfLogging = true; + } + + string str = ""; + std::map < int, string > factionDebugInfo; + + if (renderer.getShowDebugUI() == true || + (perfLogging == true + && difftime((long int) time(NULL), lastRenderLog2d) >= 1)) { + str = getDebugStats(factionDebugInfo); + } + + if (this->getRenderInGamePerformance() == true) { + renderer.renderPerformanceStats(); + } else { + static time_t lastGamePerfCheck = time(NULL); + if (difftime((long int) time(NULL), lastGamePerfCheck) > 3) { + lastGamePerfCheck = time(NULL); + + getGamePerformanceCounts(true); + } + } + + if (renderer.getShowDebugUI() == true) { + const Metrics & metrics = Metrics::getInstance(); + int mh = metrics.getMinimapH(); + + if (this->getRenderInGamePerformance() == true) { + mh = mh + ((int) gamePerformanceCounts.size() * 14); + } + + const Vec4f fontColor = getGui()->getDisplay()->getColor(); + + if (Renderer::renderText3DEnabled == true) { + renderer.renderTextShadow3D(str, + coreData.getMenuFontNormal3D(), + fontColor, 10, + metrics.getVirtualH() - mh - 60, + false); + } else { + renderer.renderTextShadow(str, coreData.getMenuFontNormal(), + fontColor, 10, + metrics.getVirtualH() - mh - 60, false); + } + + vector < string > lineTokens; + Tokenize(str, lineTokens, "\n"); + int + fontHeightNormal = + (Renderer::renderText3DEnabled == + true ? coreData.getMenuFontNormal3D()-> + getMetrics()->getHeight("W") : coreData.getMenuFontNormal()-> + getMetrics()->getHeight("W")); + int fontHeightBig = + (Renderer::renderText3DEnabled == + true ? coreData.getMenuFontBig3D()-> + getMetrics()->getHeight("W") : coreData.getMenuFontBig()-> + getMetrics()->getHeight("W")); + int playerPosY = (int) lineTokens.size() * fontHeightNormal; + + //printf("lineTokens.size() = %d\n",lineTokens.size()); + + for (int i = 0; i < world.getFactionCount(); ++i) { + string factionInfo = factionDebugInfo[i]; + Vec3f + playerColor = + world.getFaction(i)->getTexture()-> + getPixmapConst()->getPixel3f(0, 0); + + if (Renderer::renderText3DEnabled == true) { + renderer.renderText3D(factionInfo, + coreData.getMenuFontBig3D(), + Vec4f(playerColor.x, playerColor.y, + playerColor.z, 1.0), 10, + //metrics.getVirtualH() - mh - 90 - 280 - (i * 16), + metrics.getVirtualH() - mh - 60 - + playerPosY - fontHeightBig - + (fontHeightBig * i), false); + } else { + renderer.renderText(factionInfo, + coreData.getMenuFontBig(), + Vec4f(playerColor.x, playerColor.y, + playerColor.z, 1.0), 10, + //metrics.getVirtualH() - mh - 90 - 280 - (i * 16), + metrics.getVirtualH() - mh - 60 - + playerPosY - fontHeightBig - + (fontHeightBig * i), false); + } + } + + if ((renderer.getShowDebugUILevel() & debugui_unit_titles) == + debugui_unit_titles) { + if (renderer.getAllowRenderUnitTitles() == false) { + renderer.setAllowRenderUnitTitles(true); + } + + if (Renderer::renderText3DEnabled == true) { + renderer.renderUnitTitles3D(coreData.getMenuFontNormal3D(), + Vec3f(1.0f)); + } else { + renderer.renderUnitTitles(coreData.getMenuFontNormal(), + Vec3f(1.0f)); + } + } + } + + //network status + if (renderNetworkStatus == true) { + if (NetworkManager::getInstance().getGameNetworkInterface() != NULL) { + const Metrics & metrics = Metrics::getInstance(); + int mx = metrics.getMinimapX(); + //int my= metrics.getMinimapY(); + int mw = metrics.getMinimapW(); + //int mh= metrics.getMinimapH(); + const Vec4f fontColor = getGui()->getDisplay()->getColor(); + + if (Renderer::renderText3DEnabled == true) { + renderer. + renderTextShadow3D(NetworkManager:: + getInstance().getGameNetworkInterface + ()->getNetworkStatus(), + coreData.getMenuFontNormal3D(), fontColor, + mx + mw + 5, + metrics.getVirtualH() - 30 - 20, false); + } else { + renderer. + renderTextShadow(NetworkManager:: + getInstance().getGameNetworkInterface + ()->getNetworkStatus(), + coreData.getMenuFontNormal(), fontColor, + mx + mw + 5, metrics.getVirtualH() - 30 - 20, + false); + } + } + } + + // clock + if (photoModeEnabled == false && timeDisplay == true) { + renderer.renderClock(); + } + + //resource info + if (photoModeEnabled == false) { + if (this->masterserverMode == false) { + renderer.renderResourceStatus(); + } + renderer.renderConsole(&console, + showFullConsole ? consoleFull : + consoleNormal); + } + + //2d mouse + renderer.renderMouse2d(mouseX, mouseY, mouse2d, + gui.isSelectingPos() ? 1.f : 0.f); + + if (perfLogging == true + && difftime((long int) time(NULL), lastRenderLog2d) >= 1) { + lastRenderLog2d = time(NULL); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] Statistics: %s\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, str.c_str()); + } + } + + + // ==================== misc ==================== + + void Game::checkWinner() { + // lookup int is team #, value is players alive on team + std::map < int, int > teamsAlive = getTeamsAlive(); + + if (gameOver == false || teamsAlive.size() > 1) { + if (gameSettings.getDefaultVictoryConditions()) { + checkWinnerStandard(); + } else { + checkWinnerScripted(); + } + } + } + + void Game::setEndGameTeamWinnersAndLosers() { + //bool lose= false; + bool + checkTeamIndex = !(this->masterserverMode == false + && world. + getThisFaction()->getPersonalityType() != + fpt_Observer); + + // lookup int is team #, value is players alive on team + std::map < int, int > teamsAlive; + for (int i = 0; i < world.getFactionCount(); ++i) { + if (checkTeamIndex == false || i != world.getThisFactionIndex()) { + if (factionLostGame(world.getFaction(i)) == false) { + teamsAlive[world.getFaction(i)->getTeam()] = + teamsAlive[world.getFaction(i)->getTeam()] + 1; + } + } + } + + // did some team win + if (teamsAlive.size() <= 1) { + for (int i = 0; i < world.getFactionCount(); ++i) { + if (checkTeamIndex == false || i != world.getThisFactionIndex()) { + if (teamsAlive.find(world.getFaction(i)->getTeam()) != + teamsAlive.end()) { + world.getStats()->setVictorious(i); + } else if (i == world.getThisFactionIndex()) { + //lose= true; + } + } + } + bool firstGameOverTrigger = false; + if (gameOver == false) { + firstGameOverTrigger = true; + gameOver = true; + } + if (this->gameSettings.isNetworkGame() == false || + this->gameSettings.getEnableObserverModeAtEndGame() == true) { + // Let the happy winner view everything left in the world + + // This caused too much LAG for network games + if (this->gameSettings.isNetworkGame() == false) { + Renderer::getInstance().setPhotoMode(true); + gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT); + } + // END + } + + if (firstGameOverTrigger == true) { + scriptManager.onGameOver(true); + } + + if (world.getFactionCount() == 1 + && world.getFaction(0)->getPersonalityType() == fpt_Observer) { + //printf("!!!!!!!!!!!!!!!!!!!!"); + + //gameCamera.setMoveY(100.0); + gameCamera.zoom(-300); + //gameCamera.update(); + } + // else { + // if(lose == true) { + // showLoseMessageBox(); + // } + // else { + // showWinMessageBox(); + // } + // } + } + } + + std::map < int, int > Game::getTeamsAlive() { + std::map < int, int > teamsAlive; + for (int factionIndex = 0; factionIndex < world.getFactionCount(); + ++factionIndex) { + if (factionIndex != world.getThisFactionIndex()) { + if (factionLostGame(world.getFaction(factionIndex)) == false) { + teamsAlive[world.getFaction(factionIndex)->getTeam()] = + teamsAlive[world.getFaction(factionIndex)->getTeam()] + 1; + } + } + } + // did some team win + return teamsAlive; + } + + void Game::checkWinnerStandardHeadlessOrObserver() { + // lookup int is team #, value is players alive on team + std::map < int, int > teamsAlive = getTeamsAlive(); + + // did some team win + if (teamsAlive.size() <= 1) { + if (this->masterserverMode == true) { + printf("Game finished...\n"); + } + for (int factionIndex = 0; factionIndex < world.getFactionCount(); + ++factionIndex) { + + Faction *faction = world.getFaction(factionIndex); + if (factionIndex != world.getThisFactionIndex() && + teamsAlive.find(faction->getTeam()) != teamsAlive.end()) { + + world.getStats()->setVictorious(factionIndex); + if (this->masterserverMode == true) { + + printf("Player: %s is on the winning team #: %d\n", + this->gameSettings.getNetworkPlayerName(factionIndex). + c_str(), faction->getTeam()); + } + } + } + bool wasGameOverAlready = gameOver; + gameOver = true; + + // Only need to process this once + if (wasGameOverAlready == false) { + if (this->gameSettings.isNetworkGame() == false || + this->gameSettings.getEnableObserverModeAtEndGame() == true) { + + // Let the happy winner view everything left in the world + // This caused too much LAG for network games + if (this->gameSettings.isNetworkGame() == false) { + + Renderer::getInstance().setPhotoMode(true); + gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT); + } + // END + } + scriptManager.onGameOver(true); + if (world.getFactionCount() == 1 && + world.getFaction(0)->getPersonalityType() == fpt_Observer) { + gameCamera.zoom(-300); + } else { + showWinMessageBox(); + } + } + } + } + + void Game::checkWinnerStandardPlayer() { + //lose + bool lose = false; + if (factionLostGame(world.getThisFaction()) == true) { + + bool playerLostGame = true; + // Team Shared units enabled? + if (isFlagType1BitEnabled(ft1_allow_shared_team_units) == true) { + + // Check if all team members have lost? + for (int factionIndex = 0; + factionIndex < world.getFactionCount(); ++factionIndex) { + + if (world.getFaction(factionIndex)->getPersonalityType() != + fpt_Observer) { + if (world. + getFaction(factionIndex)->isAlly(world. + getThisFaction()) == + true + && factionLostGame(world.getFaction(factionIndex)) == + false) { + + playerLostGame = false; + break; + } + } + } + } + + if (playerLostGame == true) { + lose = true; + for (int factionIndex = 0; + factionIndex < world.getFactionCount(); ++factionIndex) { + + if (world.getFaction(factionIndex)->getPersonalityType() != + fpt_Observer) { + if (world. + getFaction(factionIndex)->isAlly(world. + getThisFaction()) == + false + && factionLostGame(world.getFaction(factionIndex)) == + false) { + + world.getStats()->setVictorious(factionIndex); + } + } + } + bool wasGameOverAlready = gameOver; + gameOver = true; + + // Only need to process losing once + if (wasGameOverAlready == false) { + if (this->gameSettings.isNetworkGame() == false || + this->gameSettings.getEnableObserverModeAtEndGame() == true) { + // Let the poor user watch everything unfold + // This caused too much LAG for network games + if (this->gameSettings.isNetworkGame() == false) { + Renderer::getInstance().setPhotoMode(true); + gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT); + } + // END + // but don't let him cheat via teamchat + chatManager.setDisableTeamMode(true); + } + scriptManager.onGameOver(!lose); + showLoseMessageBox(); + } + } + } + + //win + if (lose == false) { + bool win = true; + for (int factionIndex = 0; factionIndex < world.getFactionCount(); + ++factionIndex) { + + if (factionIndex != world.getThisFactionIndex()) { + if (world.getFaction(factionIndex)->getPersonalityType() != + fpt_Observer) { + + if (factionLostGame(world.getFaction(factionIndex)) == + false + && world.getFaction(factionIndex)-> + isAlly(world.getThisFaction()) == false) { + + win = false; + } + } + } + } + + if (win) { + for (int factionIndex = 0; + factionIndex < world.getFactionCount(); ++factionIndex) { + if (world.getFaction(factionIndex)->getPersonalityType() != + fpt_Observer) { + if (world. + getFaction(factionIndex)->isAlly(world.getThisFaction())) { + + world.getStats()->setVictorious(factionIndex); + } + } + } + + bool wasGameOverAlready = gameOver; + gameOver = true; + + // Only need to process winning once + if (wasGameOverAlready == false) { + if (this->gameSettings.isNetworkGame() == false || + this->gameSettings.getEnableObserverModeAtEndGame() == true) { + // Let the happy winner view everything left in the world + + // This caused too much LAG for network games + if (this->gameSettings.isNetworkGame() == false) { + Renderer::getInstance().setPhotoMode(true); + gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT); + } + // END + } + scriptManager.onGameOver(win); + showWinMessageBox(); + } + } + } + } + + void Game::checkWinnerStandard() { + if (world.getFactionCount() <= 0) { + return; + } + if (this->masterserverMode == true || + world.getThisFaction()->getPersonalityType() == fpt_Observer) { + checkWinnerStandardHeadlessOrObserver(); + } else { + checkWinnerStandardPlayer(); + } + } + + void Game::checkWinnerScripted() { + if (scriptManager.getIsGameOver()) { + bool wasGameOverAlready = gameOver; + gameOver = true; + + + for (int index = 0; index < world.getFactionCount(); ++index) { + if (scriptManager.getPlayerModifiers(index)->getWinner()) { + + world.getStats()->setVictorious(index); + } + } + + // Only need to process winning once + if (wasGameOverAlready == false) { + if (this->gameSettings.isNetworkGame() == false || + this->gameSettings.getEnableObserverModeAtEndGame() == true) { + + // Let the happy winner view everything left in the world + // This caused too much LAG for network games + if (this->gameSettings.isNetworkGame() == false) { + Renderer::getInstance().setPhotoMode(true); + gameCamera.setMaxHeight(PHOTO_MODE_MAXHEIGHT); + } + // END + } + + if (this->masterserverMode == true || + world.getThisFaction()->getPersonalityType() == fpt_Observer) { + showWinMessageBox(); + } else { + scriptManager. + onGameOver(scriptManager.getPlayerModifiers + (world.getThisFactionIndex())->getWinner()); + + if (scriptManager.getPlayerModifiers + (world.getThisFactionIndex())->getWinner()) { + showWinMessageBox(); + } else { + showLoseMessageBox(); + } + } + } + } + } + + bool Game::isFlagType1BitEnabled(FlagTypes1 type) const { + return ((gameSettings.getFlagTypes1() & (uint32) type) == + (uint32) type); + } + + bool Game::factionLostGame(int factionIndex) { + return factionLostGame(world.getFaction(factionIndex)); + } + + bool Game::factionLostGame(const Faction * faction) { + if (faction != NULL) { + for (int factionIndex = 0; factionIndex < faction->getUnitCount(); + ++factionIndex) { + const UnitType *ut = faction->getUnit(factionIndex)->getType(); + if (ut->getCountInVictoryConditions() == ucvcNotSet) { + if (faction->getUnit(factionIndex)-> + getType()->hasSkillClass(scBeBuilt)) { + return false; + } + } else if (ut->getCountInVictoryConditions() == ucvcTrue) { + return false; + } + } + } + return true; + } + + //bool Game::hasBuilding(const Faction *faction) { + // if(faction != NULL) { + // for(int i=0; igetUnitCount(); ++i) { + // if(faction->getUnit(i)->getType()->hasSkillClass(scBeBuilt)) { + // return true; + // } + // } + // } + // return false; + //} + + void Game::incSpeed() { + if (disableSpeedChange == true) { + return; + } + + Lang & lang = Lang::getInstance(); + + if (this->speed < Config::getInstance().getInt("FastSpeedLoops")) { + if (this->speed == 0) { + this->speed = 1; + } else { + this->speed++; + } + console.addLine(lang.getString("GameSpeedSet") + " " + + ((this->speed == + 0) ? lang.getString("Slow") : (this->speed == + 1) ? + lang.getString("Normal") : "x" + + intToStr(this->speed))); + } + } + + void Game::decSpeed() { + if (disableSpeedChange == true) { + return; + } + + Lang & lang = Lang::getInstance(); + if (this->speed > 0) { + this->speed--; + console.addLine(lang.getString("GameSpeedSet") + " " + + ((this->speed == + 0) ? lang.getString("Slow") : (this->speed == + 1) ? + lang.getString("Normal") : "x" + + intToStr(this->speed))); + } + } + + void + Game::setPaused(bool value, bool forceAllowPauseStateChange, + bool clearCaches, bool joinNetworkGame) { + bool + speedChangesAllowed = + !NetworkManager::getInstance().isNetworkGame(); + //printf("Toggle pause value = %d, speedChangesAllowed = %d, forceAllowPauseStateChange = %d\n",value,speedChangesAllowed,forceAllowPauseStateChange); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled) + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "game.cpp line: %d setPaused value: %d clearCaches: %d forceAllowPauseStateChange: %d speedChangesAllowed: %d pausedForJoinGame: %d joinNetworkGame: %d\n", + __LINE__, value, clearCaches, + forceAllowPauseStateChange, + speedChangesAllowed, pausedForJoinGame, + joinNetworkGame); + //printf("Line: %d setPaused value: %d clearCaches: %d forceAllowPauseStateChange: %d speedChangesAllowed: %d pausedForJoinGame: %d joinNetworkGame: %d\n",__LINE__,value,clearCaches,forceAllowPauseStateChange,speedChangesAllowed,pausedForJoinGame,joinNetworkGame); + + if (forceAllowPauseStateChange == true || speedChangesAllowed == true) { + //printf("setPaused paused = %d, value = %d\n",paused,value); + + NetworkManager & networkManager = NetworkManager::getInstance(); + + // Cannot change pause state while client is joining in progress game + if (pausedForJoinGame == true && joinNetworkGame == false && + networkManager.getNetworkRole() == nrServer) { + + ServerInterface *server = + NetworkManager::getInstance().getServerInterface(); + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + this->gameSettings.getUniqueNetworkPlayerLanguages(); + + bool haveClientConnectedButNoReady = false; + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + + MutexSafeWrapper + safeMutex(server->getSlotMutex + (faction->getStartLocationIndex()), CODE_AT_LINE); + ConnectionSlot *slot = + server->getSlot(faction->getStartLocationIndex(), + false); + if (slot != NULL && slot->isConnected() == true + && slot->isReady() == false) { + for (unsigned int i = 0; i < languageList.size(); ++i) { + + char szMsg[8096] = ""; + if (lang.hasString("JoinPlayerToCurrentGameLaunch", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString + ("JoinPlayerToCurrentGameLaunch", + languageList[i]).c_str(), + slot->getName().c_str()); + } else { + snprintf(szMsg, 8096, + "Player: %s is about to join the game, please wait...", + slot->getName().c_str()); + } + + safeMutex.ReleaseLock(); + + bool localEcho = lang.isLanguageLocal(languageList[i]); + server->sendTextMessage(szMsg, -1, localEcho, + languageList[i]); + sleep(1); + + haveClientConnectedButNoReady = true; + } + } + } + + if (haveClientConnectedButNoReady == true) { + return; + } + } + + Lang & lang = Lang::getInstance(); + if (value == false) { + console.addLine(lang.getString("GameResumed")); + + bool wasPausedForJoinGame = pausedForJoinGame; + paused = false; + pausedForJoinGame = false; + pausedBeforeJoinGame = false; + pauseStateChanged = true; + + if (clearCaches == true) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugWorldSynch).enabled) + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "game.cpp line: %d Clear Caches for resume in progress game\n", + __LINE__); + //printf("Line: %d Clear Caches for resume in progress game\n",__LINE__); + + world.clearCaches(); + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + faction->clearCaches(); + } + world.refreshAllUnitExplorations(); + } + setupPopupMenus(false); + + if (networkManager.getNetworkRole() == nrClient && + wasPausedForJoinGame == true) { + initialResumeSpeedLoops = true; + } + + commander.setPauseNetworkCommands(false); + } else { + console.addLine(lang.getString("GamePaused")); + + if (joinNetworkGame == true) { + pausedBeforeJoinGame = paused; + } + paused = true; + pausedForJoinGame = joinNetworkGame; + pauseStateChanged = true; + + if (clearCaches == true) { + //printf("Line: %d Clear Caches for resume in progress game\n",__LINE__); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugWorldSynch).enabled) + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "game.cpp line: %d Clear Caches for resume in progress game\n", + __LINE__); + + world.clearCaches(); + for (int i = 0; i < world.getFactionCount(); ++i) { + Faction *faction = world.getFaction(i); + faction->clearCaches(); + } + world.refreshAllUnitExplorations(); + } + pauseRequestSent = false; + + commander.setPauseNetworkCommands(joinNetworkGame); + } + //printf("setPaused new paused = %d\n",paused); + } + } + + bool Game::getPaused() { + bool + speedChangesAllowed = + !NetworkManager::getInstance().isNetworkGame(); + if (speedChangesAllowed) { + if (popupMenu.getVisible() == true + || popupMenuSwitchTeams.getVisible() == true) { + return true; + } + // if(mainMessageBox.getEnabled() == true || errorMessageBox.getEnabled() == true){ + // return true; + // } + if (currentUIState != NULL) { + return true; + } + } + return paused; + } + + int Game::getUpdateLoops() { + if (commander.hasReplayCommandListForFrame() == true) { + return 1; + } + + if (getPaused()) { + return 0; + } else if (this->speed == 0) { + return updateFps % 2 == 0 ? 1 : 0; + } else + return this->speed; + } + + void Game::showLoseMessageBox() { + Lang & lang = Lang::getInstance(); + + NetworkManager & networkManager = NetworkManager::getInstance(); + if (networkManager.isNetworkGame() == true + && networkManager.getNetworkRole() == nrServer) { + showMessageBox(lang.getString("YouLose") + " " + + lang.getString("ExitBattleServerQuestion"), + lang.getString("BattleOver"), false); + } else { + showMessageBox(lang.getString("YouLose") + " " + + lang.getString("ExitBattleQuestion"), + lang.getString("BattleOver"), false); + } + } + + void Game::showWinMessageBox() { + Lang & lang = Lang::getInstance(); + + if (this->masterserverMode == true + || world.getThisFaction()->getPersonalityType() == fpt_Observer) { + showMessageBox(lang.getString("GameOver") + " " + + lang.getString("ExitBattleQuestion"), + lang.getString("BattleOver"), false); + } else { + showMessageBox(lang.getString("YouWin") + " " + + lang.getString("ExitBattleQuestion"), + lang.getString("BattleOver"), false); + } + } + + void + Game::showMessageBox(const string & text, const string & header, + bool toggle) { + if (toggle == false) { + mainMessageBox.setEnabled(false); + } + + if (mainMessageBox.getEnabled() == false) { + mainMessageBox.setText(text); + mainMessageBox.setHeader(header); + mainMessageBox.setEnabled(true); + } else { + mainMessageBox.setEnabled(false); + } + } + + void + Game::showErrorMessageBox(const string & text, const string & header, + bool toggle) { + if (toggle == false) { + errorMessageBox.setEnabled(false); + } + + if (errorMessageBox.getEnabled() == false) { + errorMessageBox.setText(text); + errorMessageBox.setHeader(header); + errorMessageBox.setEnabled(true); + } else { + errorMessageBox.setEnabled(false); + } + } + + void Game::startPerformanceTimer() { + captureAvgTestStatus = true; + updateFpsAvgTest = -1; + renderFpsAvgTest = -1; + } + + void Game::endPerformanceTimer() { + captureAvgTestStatus = false; + } + + Vec2i Game::getPerformanceTimerResults() { + Vec2i results(this->updateFpsAvgTest, this->renderFpsAvgTest); + return results; + } + + void Game::consoleAddLine(string line) { + console.addLine(line); + } + void Game::toggleTeamColorMarker() { + renderExtraTeamColor++; + renderExtraTeamColor = renderExtraTeamColor % 4; + } + + void + Game::addNetworkCommandToReplayList(NetworkCommand * networkCommand, + int worldFrameCount) { + Config & config = Config::getInstance(); + if (config.getBool("SaveCommandsForReplay", "false") == true) { + replayCommandList.push_back(make_pair + (worldFrameCount, *networkCommand)); + } + } + + void Game::renderVideoPlayer() { + if (videoPlayer != NULL) { + if (videoPlayer->isPlaying() == true) { + videoPlayer->playFrame(false); + } else { + delete videoPlayer; + videoPlayer = NULL; + } + } + } + + void Game::playStaticVideo(const string & playVideo) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false + && ::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == true) { + + //togglePauseGame(true,true); + tryPauseToggle(true); + setupRenderForVideo(); + + + // Context *c= GraphicsInterface::getInstance().getCurrentContext(); + // SDL_Surface *screen = static_cast(c)->getPlatformContextGlPtr()->getScreen(); + // + // string vlcPluginsPath = Config::getInstance().getString("VideoPlayerPluginsPath",""); + // //printf("screen->w = %d screen->h = %d screen->format->BitsPerPixel = %d\n",screen->w,screen->h,screen->format->BitsPerPixel); + // Shared::Graphics::VideoPlayer player(playVideo.c_str(), + // screen, + // 0,0, + // screen->w, + // screen->h, + // screen->format->BitsPerPixel, + // vlcPluginsPath, + // SystemFlags::VERBOSE_MODE_ENABLED); + // player.PlayVideo(); + //} + //tryPauseToggle(false); + + playStreamingVideo(playVideo); + playingStaticVideo = true; + } + } + void Game::playStreamingVideo(const string & playVideo) { + if (videoPlayer == NULL) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false + && ::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == + true) { + Context *c = GraphicsInterface::getInstance().getCurrentContext(); + PlatformContextGl *glCtx = + static_cast (c)->getPlatformContextGlPtr(); + SDL_Window *window = glCtx->getScreenWindow(); + SDL_Surface *screen = glCtx->getScreenSurface(); + + string + vlcPluginsPath = + Config::getInstance().getString("VideoPlayerPluginsPath", ""); + + videoPlayer = + new::Shared::Graphics::VideoPlayer(&Renderer::getInstance(), + playVideo, "", window, 0, + 0, screen->w, screen->h, + screen->format->BitsPerPixel, + false, vlcPluginsPath, + SystemFlags::VERBOSE_MODE_ENABLED); + } + } else { + if (videoPlayer->isPlaying() == false) { + delete videoPlayer; + videoPlayer = NULL; + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false + && ::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == + true) { + Context *c = + GraphicsInterface::getInstance().getCurrentContext(); + PlatformContextGl *glCtx = + static_cast (c)->getPlatformContextGlPtr(); + SDL_Window *window = glCtx->getScreenWindow(); + SDL_Surface *screen = glCtx->getScreenSurface(); + + string + vlcPluginsPath = + Config::getInstance().getString("VideoPlayerPluginsPath", ""); + + videoPlayer = + new::Shared::Graphics::VideoPlayer(&Renderer::getInstance(), + playVideo, "", window, + 0, 0, screen->w, + screen->h, + screen-> + format->BitsPerPixel, false, + vlcPluginsPath, + SystemFlags::VERBOSE_MODE_ENABLED); + } + } + } + + if (videoPlayer != NULL) { + videoPlayer->initPlayer(); + } + } + void Game::stopStreamingVideo(const string & playVideo) { + if (videoPlayer != NULL) { + videoPlayer->StopVideo(); + } + } + + void Game::stopAllVideo() { + if (videoPlayer != NULL) { + videoPlayer->StopVideo(); + } + } + + bool + Game::clientLagHandler(int slotIndex, + bool networkPauseGameForLaggedClients) { + if (networkPauseGameForLaggedClients == true) { + printf + ("**WARNING** Detected lag from client: %d networkPauseGameForLaggedClients: %d\n", + slotIndex, networkPauseGameForLaggedClients); + } else { + printf + ("==> Requested Resume Game after Pause for lagging client(s)...\n"); + } + + this->networkPauseGameForLaggedClientsRequested = + networkPauseGameForLaggedClients; + this->networkResumeGameForLaggedClientsRequested = + !networkPauseGameForLaggedClients; + return true; + } + + void Game::saveGame() { + string file = this->saveGame(GameConstants::saveGameFilePattern); + char szBuf[8096] = ""; + Lang & lang = Lang::getInstance(); + snprintf(szBuf, 8096, lang.getString("GameSaved", "", true).c_str(), + file.c_str()); + console.addLine(szBuf); + + Config & config = Config::getInstance(); + config.setString("LastSavedGame", file); + config.save(); + } + + string Game::saveGame(string name, const string & path) { + Config & config = Config::getInstance(); + // auto name file if using saved file pattern string + if (name == GameConstants::saveGameFilePattern) { + //time_t curTime = time(NULL); + //struct tm *loctime = localtime (&curTime); + struct tm loctime = threadsafe_localtime(systemtime_now()); + char szBuf2[100] = ""; + strftime(szBuf2, 100, "%Y%m%d_%H%M%S", &loctime); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, name.c_str(), szBuf2); + name = szBuf; + } else if (name == GameConstants::saveGameFileAutoTestDefault) { + //time_t curTime = time(NULL); + //struct tm *loctime = localtime (&curTime); + struct tm loctime = threadsafe_localtime(systemtime_now()); + char szBuf2[100] = ""; + strftime(szBuf2, 100, "%Y%m%d_%H%M%S", &loctime); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, name.c_str(), szBuf2); + name = szBuf; + } + + // Save the file now + string saveGameFile = path + name; + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != + "") { + saveGameFile = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + saveGameFile; + } else { + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + saveGameFile = userData + saveGameFile; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Saving game to [%s]\n", saveGameFile.c_str()); + + // This condition will re-play all the commands from a replay file + // INSTEAD of saving from a saved game. + if (config.getBool("SaveCommandsForReplay", "false") == true) { + std::map < string, string > mapTagReplacements; + XmlTree xmlTreeSaveGame(XML_RAPIDXML_ENGINE); + + xmlTreeSaveGame.init("zetaglest-saved-game"); + XmlNode *rootNodeReplay = xmlTreeSaveGame.getRootNode(); + + //std::map mapTagReplacements; + //time_t now = time(NULL); + //struct tm *loctime = localtime (&now); + struct tm loctime = threadsafe_localtime(systemtime_now()); + char szBuf[4096] = ""; + strftime(szBuf, 4095, "%Y-%m-%d %H:%M:%S", &loctime); + + rootNodeReplay->addAttribute("version", glestVersionString, + mapTagReplacements); + rootNodeReplay->addAttribute("timestamp", szBuf, mapTagReplacements); + + XmlNode *gameNodeReplay = rootNodeReplay->addChild("Game"); + gameSettings.saveGame(gameNodeReplay); + + gameNodeReplay->addAttribute("LastWorldFrameCount", + intToStr(world.getFrameCount()), + mapTagReplacements); + + for (unsigned int i = 0; i < replayCommandList.size(); ++i) { + std::pair < int, NetworkCommand > & cmd = replayCommandList[i]; + XmlNode *networkCommandNode = cmd.second.saveGame(gameNodeReplay); + networkCommandNode->addAttribute("worldFrameCount", + intToStr(cmd.first), + mapTagReplacements); + } + + string replayFile = saveGameFile + ".replay"; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Saving game replay commands to [%s]\n", + replayFile.c_str()); + xmlTreeSaveGame.save(replayFile); + } + + XmlTree xmlTree; + xmlTree.init("zetaglest-saved-game"); + XmlNode *rootNode = xmlTree.getRootNode(); + + std::map < string, string > mapTagReplacements; + //time_t now = time(NULL); + //struct tm *loctime = localtime (&now); + struct tm loctime = threadsafe_localtime(systemtime_now()); + char szBuf[4096] = ""; + strftime(szBuf, 4095, "%Y-%m-%d %H:%M:%S", &loctime); + + rootNode->addAttribute("version", glestVersionString, + mapTagReplacements); + rootNode->addAttribute("timestamp", szBuf, mapTagReplacements); + + XmlNode *gameNode = rootNode->addChild("Game"); + //World world; + world.saveGame(gameNode); + //AiInterfaces aiInterfaces; + for (unsigned int i = 0; i < aiInterfaces.size(); ++i) { + AiInterface *aiIntf = aiInterfaces[i]; + if (aiIntf != NULL) { + aiIntf->saveGame(gameNode); + } + } + //Gui gui; + gui.saveGame(gameNode); + //GameCamera gameCamera; + gameCamera.saveGame(gameNode); + //Commander commander; + //Console console; + //ChatManager chatManager; + //ScriptManager scriptManager; + scriptManager.saveGame(gameNode); + + //misc + //Checksum checksum; + gameNode->addAttribute("checksum", intToStr(checksum.getSum()), + mapTagReplacements); + //string loadingText; + // int mouse2d; + gameNode->addAttribute("mouse2d", intToStr(mouse2d), + mapTagReplacements); + // int mouseX; + gameNode->addAttribute("mouseX", intToStr(mouseX), + mapTagReplacements); + // int mouseY; //coords win32Api + gameNode->addAttribute("mouseY", intToStr(mouseY), + mapTagReplacements); + // Vec2i mouseCellPos; + gameNode->addAttribute("mouseCellPos", mouseCellPos.getString(), + mapTagReplacements); + // int updateFps, lastUpdateFps, avgUpdateFps; + // int totalRenderFps, renderFps, lastRenderFps, avgRenderFps,currentAvgRenderFpsTotal; + //Uint64 tickCount; + gameNode->addAttribute("tickCount", intToStr(tickCount), + mapTagReplacements); + + //bool paused; + gameNode->addAttribute("paused", intToStr(paused), + mapTagReplacements); + //bool gameOver; + gameNode->addAttribute("gameOver", intToStr(gameOver), + mapTagReplacements); + //bool renderNetworkStatus; + //bool showFullConsole; + //bool mouseMoved; + //float scrollSpeed; + gameNode->addAttribute("scrollSpeed", floatToStr(scrollSpeed, 6), + mapTagReplacements); + //bool camLeftButtonDown; + //bool camRightButtonDown; + //bool camUpButtonDown; + //bool camDownButtonDown; + + //Speed speed; + gameNode->addAttribute("speed", intToStr(speed), mapTagReplacements); + + //GraphicMessageBox mainMessageBox; + //GraphicMessageBox errorMessageBox; + + //misc ptr + //ParticleSystem *weatherParticleSystem; + if (weatherParticleSystem != NULL) { + weatherParticleSystem->saveGame(gameNode); + } + //GameSettings gameSettings; + gameSettings.saveGame(gameNode); + //Vec2i lastMousePos; + gameNode->addAttribute("lastMousePos", lastMousePos.getString(), + mapTagReplacements); + //time_t lastRenderLog2d; + gameNode->addAttribute("lastRenderLog2d", intToStr(lastRenderLog2d), + mapTagReplacements); + //DisplayMessageFunction originalDisplayMsgCallback; + //bool isFirstRender; + gameNode->addAttribute("isFirstRender", intToStr(isFirstRender), + mapTagReplacements); + + //bool quitTriggeredIndicator; + //int original_updateFps; + gameNode->addAttribute("original_updateFps", + intToStr(original_updateFps), + mapTagReplacements); + //int original_cameraFps; + gameNode->addAttribute("original_cameraFps", + intToStr(original_cameraFps), + mapTagReplacements); + + //bool captureAvgTestStatus; + gameNode->addAttribute("captureAvgTestStatus", + intToStr(captureAvgTestStatus), + mapTagReplacements); + //int updateFpsAvgTest; + gameNode->addAttribute("updateFpsAvgTest", intToStr(updateFpsAvgTest), + mapTagReplacements); + //int renderFpsAvgTest; + gameNode->addAttribute("renderFpsAvgTest", intToStr(renderFpsAvgTest), + mapTagReplacements); + + //int renderExtraTeamColor; + gameNode->addAttribute("renderExtraTeamColor", + intToStr(renderExtraTeamColor), + mapTagReplacements); + + //static const int renderTeamColorCircleBit=1; + //static const int renderTeamColorPlaneBit=2; + + //bool photoModeEnabled; + gameNode->addAttribute("photoModeEnabled", intToStr(photoModeEnabled), + mapTagReplacements); + //bool visibleHUD; + gameNode->addAttribute("visibleHUD", intToStr(visibleHUD), + mapTagReplacements); + + //bool timeDisplay + gameNode->addAttribute("timeDisplay", intToStr(timeDisplay), + mapTagReplacements); + + //bool withRainEffect; + gameNode->addAttribute("withRainEffect", intToStr(withRainEffect), + mapTagReplacements); + //Program *program; + + //bool gameStarted; + gameNode->addAttribute("gameStarted", intToStr(gameStarted), + mapTagReplacements); + + //time_t lastMaxUnitCalcTime; + gameNode->addAttribute("lastMaxUnitCalcTime", + intToStr(lastMaxUnitCalcTime), + mapTagReplacements); + + //PopupMenu popupMenu; + //PopupMenu popupMenuSwitchTeams; + + //std::map switchTeamIndexMap; + //GraphicMessageBox switchTeamConfirmMessageBox; + + //int exitGamePopupMenuIndex; + //int joinTeamPopupMenuIndex; + //int pauseGamePopupMenuIndex; + //int keyboardSetupPopupMenuIndex; + //GLuint statelist3dMenu; + //ProgramState *currentUIState; + + //bool masterserverMode; + + //StrSound *currentAmbientSound; + + //time_t lastNetworkPlayerConnectionCheck; + gameNode->addAttribute("lastNetworkPlayerConnectionCheck", + intToStr(lastNetworkPlayerConnectionCheck), + mapTagReplacements); + + //time_t lastMasterServerGameStatsDump; + gameNode->addAttribute("lastMasterServerGameStatsDump", + intToStr(lastMasterServerGameStatsDump), + mapTagReplacements); + + XmlNode *unitHighlightListNode = + gameNode->addChild("unitHighlightList"); + //for(unsigned int i = 0; i < unitHighlightList.size(); ++i) { + for (std::map < int, HighlightSpecialUnitInfo >::iterator iterMap = + unitHighlightList.begin(); iterMap != unitHighlightList.end(); + ++iterMap) { + HighlightSpecialUnitInfo & info = iterMap->second; + XmlNode *infoNode = unitHighlightListNode->addChild("info"); + infoNode->addAttribute("unitid", intToStr(iterMap->first), + mapTagReplacements); + infoNode->addAttribute("radius", floatToStr(info.radius, 6), + mapTagReplacements); + infoNode->addAttribute("thickness", floatToStr(info.thickness, 6), + mapTagReplacements); + infoNode->addAttribute("color", info.color.getString(), + mapTagReplacements); + } + + gameNode->addAttribute("disableSpeedChange", + intToStr(disableSpeedChange), + mapTagReplacements); + + xmlTree.save(saveGameFile); + + if (masterserverMode == false) { + // take Screenshot + string jpgFileName = saveGameFile + ".jpg"; + // menu is already disabled, last rendered screen is still with enabled one. Lets render again: + render3d(); + render2d(); + Renderer::getInstance().saveScreen(jpgFileName, + config.getInt + ("SaveGameScreenshotWidth", + "800"), + config.getInt + ("SaveGameScreenshotHeight", + "600")); + } + + return saveGameFile; + } + + void + Game::loadGame(string name, Program * programPtr, + bool isMasterserverMode, + const GameSettings * joinGameSettings) { + Config & config = Config::getInstance(); + // This condition will re-play all the commands from a replay file + // INSTEAD of saving from a saved game. + if (joinGameSettings == NULL + && config.getBool("SaveCommandsForReplay", "false") == true) { + XmlTree xmlTreeReplay(XML_RAPIDXML_ENGINE); + std::map < string, string > mapExtraTagReplacementValues; + xmlTreeReplay.load(name + ".replay", + Properties::getTagReplacementValues + (&mapExtraTagReplacementValues), true); + + const XmlNode *rootNode = xmlTreeReplay.getRootNode(); + + if (rootNode->hasChild("zetaglest-saved-game") == true) { + rootNode = rootNode->getChild("zetaglest-saved-game"); + } + + //const XmlNode *versionNode= rootNode->getChild("zetaglest-saved-game"); + const XmlNode *versionNode = rootNode; + + Lang & lang = Lang::getInstance(); + string gameVer = versionNode->getAttribute("version")->getValue(); + if (gameVer != glestVersionString + && checkVersionComptability(gameVer, + glestVersionString) == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("SavedGameBadVersion").c_str(), + gameVer.c_str(), glestVersionString.c_str()); + throw megaglest_runtime_error(szBuf, true); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("Found saved game version that matches your application version: [%s] --> [%s]\n", + gameVer.c_str(), glestVersionString.c_str()); + + XmlNode *gameNode = rootNode->getChild("Game"); + + GameSettings newGameSettingsReplay; + newGameSettingsReplay.loadGame(gameNode); + //printf("Loading scenario [%s]\n",newGameSettingsReplay.getScenarioDir().c_str()); + if (newGameSettingsReplay.getScenarioDir() != "" + && fileExists(newGameSettingsReplay.getScenarioDir()) == false) { + newGameSettingsReplay.setScenarioDir(Scenario::getScenarioPath + (Config:: + getInstance + ().getPathListForType + (ptScenarios), + newGameSettingsReplay.getScenario + ())); + + //printf("Loading scenario #2 [%s]\n",newGameSettingsReplay.getScenarioDir().c_str()); + } + + //GameSettings newGameSettings; + //newGameSettings.loadGame(gameNode); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Game settings loaded\n"); + + NetworkManager & networkManager = NetworkManager::getInstance(); + networkManager.end(); + networkManager.init(nrServer, true); + + Game *newGame = + new Game(programPtr, &newGameSettingsReplay, isMasterserverMode); + newGame->lastworldFrameCountForReplay = + gameNode->getAttribute("LastWorldFrameCount")->getIntValue(); + + vector < XmlNode * >networkCommandNodeList = + gameNode->getChildList("NetworkCommand"); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("networkCommandNodeList.size() = " MG_SIZE_T_SPECIFIER + "\n", networkCommandNodeList.size()); + for (unsigned int i = 0; i < networkCommandNodeList.size(); ++i) { + XmlNode *node = networkCommandNodeList[i]; + int + worldFrameCount = + node->getAttribute("worldFrameCount")->getIntValue(); + NetworkCommand command; + command.loadGame(node); + newGame->commander.addToReplayCommandList(command, + worldFrameCount); + } + + programPtr->setState(newGame); + return; + } + + XmlTree xmlTree(XML_RAPIDXML_ENGINE); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Before load of XML\n"); + std::map < string, string > mapExtraTagReplacementValues; + xmlTree.load(name, + Properties::getTagReplacementValues + (&mapExtraTagReplacementValues), true); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("After load of XML\n"); + + const XmlNode *rootNode = xmlTree.getRootNode(); + if (rootNode->hasChild("zetaglest-saved-game") == true) { + rootNode = rootNode->getChild("zetaglest-saved-game"); + } + + //const XmlNode *versionNode= rootNode->getChild("zetaglest-saved-game"); + const XmlNode *versionNode = rootNode; + + Lang & lang = Lang::getInstance(); + string gameVer = versionNode->getAttribute("version")->getValue(); + // this is the version check for loading normal save games from menu_state_load_game + if (gameVer != glestVersionString + && + (compareMajorMinorVersion + (gameVer, lastCompatibleSaveGameVersionString) < 0 + || compareMajorMinorVersion(glestVersionString, gameVer) < 0)) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("SavedGameBadVersion").c_str(), + gameVer.c_str(), glestVersionString.c_str()); + throw megaglest_runtime_error(szBuf, true); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("Found saved game version that matches your application version: [%s] --> [%s]\n", + gameVer.c_str(), glestVersionString.c_str()); + + XmlNode *gameNode = rootNode->getChild("Game"); + GameSettings newGameSettings; + if (joinGameSettings != NULL) { + newGameSettings = *joinGameSettings; + + XmlNode *worldNode = gameNode->getChild("World"); + XmlNode *guiNode = gameNode->getChild("Gui"); + XmlNode *selectionNode = guiNode->getChild("Selection"); + XmlNode *statsNode = worldNode->getChild("Stats"); + XmlNode *minimapNode = worldNode->getChild("Minimap"); + + if (gameVer != glestVersionString + && checkVersionComptability(gameVer, + glestVersionString) == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("SavedGameBadVersion").c_str(), + gameVer.c_str(), glestVersionString.c_str()); + throw megaglest_runtime_error(szBuf, true); + } + // This is explored fog of war for the host player, clear it + minimapNode->clearChild("fowPixmap1"); + + NetworkManager & networkManager = NetworkManager::getInstance(); + //NetworkRole role = networkManager.getNetworkRole(); + ClientInterface *clientInterface = + dynamic_cast < + ClientInterface *>(networkManager.getClientInterface()); + + for (int i = 0; i < newGameSettings.getFactionCount(); ++i) { + //replace by network + if (newGameSettings.getFactionControl(i) == ctHuman) { + newGameSettings.setFactionControl(i, ctNetwork); + } + + //set the faction index + if (newGameSettings.getStartLocationIndex(i) == + clientInterface->getPlayerIndex()) { + newGameSettings.setThisFactionIndex(i); + newGameSettings.setFactionControl(i, ctNetwork); + + worldNode-> + getAttribute("thisFactionIndex")->setValue(intToStr(i)); + //worldNode->getAttribute("thisTeamIndex")->setValue(intToStr(newGameSettings.getTeam(i))); + + XmlNode *factionNode = worldNode->getChild("Faction", i); + factionNode-> + getAttribute("thisFaction")->setValue(intToStr(i)); + factionNode-> + getAttribute("control")->setValue(intToStr(ctNetwork)); + + selectionNode-> + getAttribute("factionIndex")->setValue(intToStr(i)); + //selectionNode->getAttribute("teamIndex")->setValue(intToStr(newGameSettings.getTeam(i))); + + statsNode-> + getAttribute("thisFactionIndex")->setValue(intToStr(i)); + } else { + XmlNode *factionNode = worldNode->getChild("Faction", i); + factionNode-> + getAttribute("thisFaction")->setValue(intToStr(0)); + } + } + } else { + newGameSettings.loadGame(gameNode); + //printf("Loading scenario [%s]\n",newGameSettings.getScenarioDir().c_str()); + if (newGameSettings.getScenarioDir() != "" + && fileExists(newGameSettings.getScenarioDir()) == false) { + newGameSettings.setScenarioDir(Scenario::getScenarioPath + (Config:: + getInstance().getPathListForType + (ptScenarios), + newGameSettings.getScenario())); + + //printf("Loading scenario #2 [%s]\n",newGameSettings.getScenarioDir().c_str()); + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Game settings loaded\n"); + + if (joinGameSettings == NULL) { + NetworkManager & networkManager = NetworkManager::getInstance(); + networkManager.end(); + networkManager.init(nrServer, true); + } + + Game *newGame = + new Game(programPtr, &newGameSettings, isMasterserverMode); + + newGame->loadGameNode = gameNode; + newGame->inJoinGameLoading = (joinGameSettings != NULL); + + // newGame->mouse2d = gameNode->getAttribute("mouse2d")->getIntValue(); + // int mouseX; + // newGame->mouseX = gameNode->getAttribute("mouseX")->getIntValue(); + // int mouseY; //coords win32Api + // newGame->mouseY = gameNode->getAttribute("mouseY")->getIntValue(); + // Vec2i mouseCellPos; + // newGame->mouseCellPos = Vec2i::strToVec2(gameNode->getAttribute("mouseCellPos")->getValue()); + // int updateFps, lastUpdateFps, avgUpdateFps; + // int totalRenderFps, renderFps, lastRenderFps, avgRenderFps,currentAvgRenderFpsTotal; + //Uint64 tickCount; + newGame->tickCount = + gameNode->getAttribute("tickCount")->getIntValue(); + + //bool paused; + if (newGame->inJoinGameLoading == true) { + newGame->paused = + gameNode->getAttribute("paused")->getIntValue() != 0; + } else { + //newGame->paused = gameNode->getAttribute("paused")->getIntValue() != 0; + newGame->paused = true; + } + if (newGame->paused) + newGame->console.addLine(lang.getString("GamePaused")); + //bool gameOver; + newGame->gameOver = + gameNode->getAttribute("gameOver")->getIntValue() != 0; + //bool renderNetworkStatus; + //bool showFullConsole; + //bool mouseMoved; + //float scrollSpeed; + // newGame->scrollSpeed = gameNode->getAttribute("scrollSpeed")->getFloatValue(); + //bool camLeftButtonDown; + //bool camRightButtonDown; + //bool camUpButtonDown; + //bool camDownButtonDown; + + //Speed speed; + //gameNode->addAttribute("speed",intToStr(speed), mapTagReplacements); + + //GraphicMessageBox mainMessageBox; + //GraphicMessageBox errorMessageBox; + + //misc ptr + //ParticleSystem *weatherParticleSystem; + // if(weatherParticleSystem != NULL) { + // weatherParticleSystem->saveGame(gameNode); + // } + //GameSettings gameSettings; + // gameSettings.saveGame(gameNode); + //Vec2i lastMousePos; + // gameNode->addAttribute("lastMousePos",lastMousePos.getString(), mapTagReplacements); + //time_t lastRenderLog2d; + // gameNode->addAttribute("lastRenderLog2d",intToStr(lastRenderLog2d), mapTagReplacements); + //DisplayMessageFunction originalDisplayMsgCallback; + //bool isFirstRender; + // gameNode->addAttribute("isFirstRender",intToStr(isFirstRender), mapTagReplacements); + + //bool quitTriggeredIndicator; + //int original_updateFps; + // gameNode->addAttribute("original_updateFps",intToStr(original_updateFps), mapTagReplacements); + //int original_cameraFps; + // gameNode->addAttribute("original_cameraFps",intToStr(original_cameraFps), mapTagReplacements); + + //bool captureAvgTestStatus; + // gameNode->addAttribute("captureAvgTestStatus",intToStr(captureAvgTestStatus), mapTagReplacements); + //int updateFpsAvgTest; + // gameNode->addAttribute("updateFpsAvgTest",intToStr(updateFpsAvgTest), mapTagReplacements); + //int renderFpsAvgTest; + // gameNode->addAttribute("renderFpsAvgTest",intToStr(renderFpsAvgTest), mapTagReplacements); + + //int renderExtraTeamColor; + newGame->renderExtraTeamColor = + gameNode->getAttribute("renderExtraTeamColor")->getIntValue(); + + //static const int renderTeamColorCircleBit=1; + //static const int renderTeamColorPlaneBit=2; + + //bool photoModeEnabled; + //gameNode->addAttribute("photoModeEnabled",intToStr(photoModeEnabled), mapTagReplacements); + newGame->photoModeEnabled = + gameNode->getAttribute("photoModeEnabled")->getIntValue() != 0; + //bool visibleHUD; + //gameNode->addAttribute("visibleHUD",intToStr(visibleHUD), mapTagReplacements); + newGame->visibleHUD = + gameNode->getAttribute("visibleHUD")->getIntValue() != 0; + newGame->timeDisplay = + gameNode->getAttribute("timeDisplay")->getIntValue() != 0; + //bool withRainEffect; + //gameNode->addAttribute("withRainEffect",intToStr(withRainEffect), mapTagReplacements); + newGame->withRainEffect = + gameNode->getAttribute("withRainEffect")->getIntValue() != 0; + //Program *program; + + if (joinGameSettings == NULL) { + if (gameNode->hasChild("unitHighlightList") == true) { + XmlNode *unitHighlightListNode = + gameNode->getChild("unitHighlightList"); + vector < XmlNode * >infoNodeList = + unitHighlightListNode->getChildList("info"); + for (unsigned int i = 0; i < infoNodeList.size(); ++i) { + XmlNode *infoNode = infoNodeList[i]; + + int unitId = infoNode->getAttribute("radius")->getIntValue(); + HighlightSpecialUnitInfo info; + info.radius = infoNode->getAttribute("radius")->getFloatValue(); + info.thickness = + infoNode->getAttribute("thickness")->getFloatValue(); + info.color = + Vec4f::strToVec4(infoNode-> + getAttribute("color")->getValue()); + + newGame->unitHighlightList[unitId] = info; + } + } + } + + newGame->timeDisplay = + gameNode->getAttribute("timeDisplay")->getIntValue() != 0; + + if (gameNode->hasAttribute("disableSpeedChange") == true) { + newGame->disableSpeedChange = + gameNode->getAttribute("disableSpeedChange")->getIntValue() != 0; + } + + //bool gameStarted; + //gameNode->addAttribute("gameStarted",intToStr(gameStarted), mapTagReplacements); + // newGame->gameStarted = gameNode->getAttribute("gameStarted")->getIntValue(); + + //time_t lastMaxUnitCalcTime; + //gameNode->addAttribute("lastMaxUnitCalcTime",intToStr(lastMaxUnitCalcTime), mapTagReplacements); + + //PopupMenu popupMenu; + //PopupMenu popupMenuSwitchTeams; + + //std::map switchTeamIndexMap; + //GraphicMessageBox switchTeamConfirmMessageBox; + + //int exitGamePopupMenuIndex; + //int joinTeamPopupMenuIndex; + //int pauseGamePopupMenuIndex; + //int keyboardSetupPopupMenuIndex; + //GLuint statelist3dMenu; + //ProgramState *currentUIState; + + //bool masterserverMode; + + //StrSound *currentAmbientSound; + + //time_t lastNetworkPlayerConnectionCheck; + //gameNode->addAttribute("lastNetworkPlayerConnectionCheck",intToStr(lastNetworkPlayerConnectionCheck), mapTagReplacements); + + //time_t lastMasterServerGameStatsDump; + //gameNode->addAttribute("lastMasterServerGameStatsDump",intToStr(lastMasterServerGameStatsDump), mapTagReplacements); + + if (joinGameSettings == NULL) { + newGame->gameCamera.loadGame(gameNode); + } + + const XmlNode *worldNode = gameNode->getChild("World"); + newGame->world.loadGame(worldNode); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Starting Game ...\n"); + programPtr->setState(newGame); + } + + } + } //end namespace diff --git a/source/glest_game/game/game.h b/source/glest_game/game/game.h index 0f37268b2..ad1e03a27 100644 --- a/source/glest_game/game/game.h +++ b/source/glest_game/game/game.h @@ -50,543 +50,506 @@ using std::vector; using namespace Shared::Platform; using namespace Shared::PlatformCommon; -namespace Shared -{ - namespace Graphics - { - class VideoPlayer; - } +namespace Shared { + namespace Graphics { + class VideoPlayer; + } }; -namespace Glest -{ - namespace Game - { - - class GraphicMessageBox; - class ServerInterface; - - enum LoadGameItem - { - lgt_FactionPreview = 0x01, - lgt_TileSet = 0x02, - lgt_TechTree = 0x04, - lgt_Map = 0x08, - lgt_Scenario = 0x10, - - lgt_All = - (lgt_FactionPreview | lgt_TileSet | lgt_TechTree | lgt_Map | - lgt_Scenario) - }; - -// ===================================================== -// class Game -// -// Main game class -// ===================================================== - class Game: - public - ProgramState, - public - FileCRCPreCacheThreadCallbackInterface, - public CustomInputCallbackInterface, public ClientLagCallbackInterface - { - public: - static const float highlightTime; - - private: - typedef vector < Ai * > Ais; - typedef vector < AiInterface * > AiInterfaces; - - private: - //main data - World world; - AiInterfaces aiInterfaces; - Gui gui; - GameCamera gameCamera; - Commander commander; - Console console; - ChatManager chatManager; - ScriptManager scriptManager; - - //misc - Checksum checksum; - string loadingText; - int mouse2d; - int mouseX; - int mouseY; //coords win32Api - Vec2i mouseCellPos; - - int updateFps, lastUpdateFps, avgUpdateFps; - int framesToCatchUpAsClient; - int framesToSlowDownAsClient; - int receivedTooEarlyInFrames[GameConstants::networkSmoothInterval]; - int - framesNeededToWaitForServerMessage[GameConstants:: - networkSmoothInterval]; - int - totalRenderFps, - renderFps, lastRenderFps, avgRenderFps, currentAvgRenderFpsTotal; - uint64 tickCount; - bool paused; - bool pauseRequestSent; - bool resumeRequestSent; - bool pauseStateChanged; - bool pausedForJoinGame; - bool pausedBeforeJoinGame; - - bool gameOver; - bool renderNetworkStatus; - bool renderInGamePerformance; - bool showFullConsole; - bool setMarker; - bool cameraDragAllowed; - bool mouseMoved; - float scrollSpeed; - bool camLeftButtonDown; - bool camRightButtonDown; - bool camUpButtonDown; - bool camDownButtonDown; - - int speed; - GraphicMessageBox mainMessageBox; - GraphicMessageBox errorMessageBox; - - //misc ptr - ParticleSystem *weatherParticleSystem; - GameSettings gameSettings; - Vec2i lastMousePos; - time_t lastRenderLog2d; - DisplayMessageFunction originalDisplayMsgCallback; - bool isFirstRender; - - bool quitTriggeredIndicator; - bool quitPendingIndicator; - - int original_updateFps; - int original_cameraFps; - - bool captureAvgTestStatus; - int updateFpsAvgTest; - int renderFpsAvgTest; - - int renderExtraTeamColor; - static const int renderTeamColorCircleBit = 1; - static const int renderTeamColorPlaneBit = 2; - - bool photoModeEnabled; - int healthbarMode; - bool visibleHUD; - bool timeDisplay; - bool withRainEffect; - Program *program; - - bool gameStarted; - - time_t lastMaxUnitCalcTime; - - PopupMenu popupMenu; - PopupMenu popupMenuSwitchTeams; - PopupMenu popupMenuDisconnectPlayer; - - std::map < int, int > switchTeamIndexMap; - GraphicMessageBox switchTeamConfirmMessageBox; - - std::map < int, int > disconnectPlayerIndexMap; - int playerIndexDisconnect; - GraphicMessageBox disconnectPlayerConfirmMessageBox; - - int exitGamePopupMenuIndex; - int joinTeamPopupMenuIndex; - int pauseGamePopupMenuIndex; - int saveGamePopupMenuIndex; - int loadGamePopupMenuIndex; - //int markCellPopupMenuIndex; - //int unmarkCellPopupMenuIndex; - int keyboardSetupPopupMenuIndex; - int disconnectPlayerPopupMenuIndex; - //GLuint statelist3dMenu; - ProgramState *currentUIState; - - bool isMarkCellEnabled; - Vec2i cellMarkedPos; - MarkedCell cellMarkedData; - bool isMarkCellTextEnabled; - - Texture2D *markCellTexture; - bool isUnMarkCellEnabled; - Texture2D *unmarkCellTexture; - std::map < Vec2i, MarkedCell > mapMarkedCellList; - Texture2D *highlightCellTexture; - std::vector < MarkedCell > highlightedCells; - bool masterserverMode; - - StrSound *currentAmbientSound; - - time_t lastNetworkPlayerConnectionCheck; - - time_t lastMasterServerGameStatsDump; - - XmlNode *loadGameNode; - int lastworldFrameCountForReplay; - std::vector < std::pair < int, NetworkCommand > > replayCommandList; - - std::vector < string > streamingVideos; - ::Shared::Graphics::VideoPlayer * videoPlayer; - bool playingStaticVideo; - - Unit *currentCameraFollowUnit; - - std::map < int, HighlightSpecialUnitInfo > unitHighlightList; - - MasterSlaveThreadController masterController; - - bool inJoinGameLoading; - bool initialResumeSpeedLoops; - - bool quitGameCalled; - bool disableSpeedChange; - - std::map < int, FowAlphaCellsLookupItem > teamFowAlphaCellsLookupItem; - std::map < string, int64 > gamePerformanceCounts; - - bool networkPauseGameForLaggedClientsRequested; - bool networkResumeGameForLaggedClientsRequested; - - public: - Game (); - Game (Program * program, const GameSettings * gameSettings, - bool masterserverMode); - ~Game (); - - void reInitGUI (); - bool isFlagType1BitEnabled (FlagTypes1 type) const; - - bool isMarkCellMode ()const - { - return isMarkCellEnabled; - } - const Texture2D *getMarkCellTexture () const - { - return markCellTexture; - } - bool isUnMarkCellMode () const - { - return isUnMarkCellEnabled; - } - const Texture2D *getUnMarkCellTexture () const - { - return unmarkCellTexture; - } - - std::map < Vec2i, MarkedCell > getMapMarkedCellList () const - { - return mapMarkedCellList; - } - - const Texture2D *getHighlightCellTexture () const - { - return highlightCellTexture; - } - const std::vector < MarkedCell > *getHighlightedCells () const - { - return &highlightedCells; - } - void addOrReplaceInHighlightedCells (MarkedCell mc); - - bool isMasterserverMode ()const - { - return masterserverMode; - } - //get - GameSettings *getGameSettings () - { - return &gameSettings; - } - void setGameSettings (GameSettings * settings) - { - gameSettings = *settings; - } - const GameSettings *getReadOnlyGameSettings () const - { - return &gameSettings; - } - void setQuitPendingIndicator () - { - quitPendingIndicator = true; - } - - const GameCamera *getGameCamera () const - { - return &gameCamera; - } - GameCamera *getGameCameraPtr () - { - return &gameCamera; - } - const Commander *getCommander () const - { - return &commander; - } - Gui *getGuiPtr () - { - return &gui; - } - const Gui *getGui () const - { - return &gui; - } - Commander *getCommander () - { - return &commander; - } - Console *getConsole () - { - return &console; - } - ScriptManager *getScriptManager () - { - return &scriptManager; - } - World *getWorld () - { - return &world; - } - const World *getWorld () const - { - return &world; - } - - Program *getProgram () - { - return program; - } - - Vec2i getMouseCellPos ()const - { - return mouseCellPos; - } - bool isValidMouseCellPos () const; - - void removeUnitFromSelection (const Unit * unit); - bool addUnitToSelection (Unit * unit); - void addUnitToGroupSelection (Unit * unit, int groupIndex); - void removeUnitFromGroupSelection (int unitId, int groupIndex); - void recallGroupSelection (int groupIndex); - - Uint64 getTickCount () - { - return tickCount; - } - bool getPaused (); - void - setPaused (bool value, bool forceAllowPauseStateChange, - bool clearCaches, bool joinNetworkGame); - void tryPauseToggle (bool pause); - void setupRenderForVideo (); - void saveGame (); - const int getTotalRenderFps () const - { - return totalRenderFps; - } - - void toggleTeamColorMarker (); - //init - void resetMembers (); - virtual void load (int loadTypes); - virtual void load (); - virtual void init (); - virtual void init (bool initForPreviewOnly); - virtual void update (); - virtual void updateCamera (); - virtual void render (); - virtual void tick (); - - //event managing - virtual bool textInput (std::string text); - virtual bool sdlKeyDown (SDL_KeyboardEvent key); - virtual void keyDown (SDL_KeyboardEvent key); - virtual void keyUp (SDL_KeyboardEvent key); - virtual void keyPress (SDL_KeyboardEvent c); - virtual void mouseDownLeft (int x, int y); - virtual void mouseDownRight (int x, int y); - virtual void mouseUpCenter (int x, int y); - virtual void mouseUpLeft (int x, int y); - virtual void mouseDoubleClickLeft (int x, int y); - virtual void eventMouseWheel (int x, int y, int zDelta); - virtual void mouseMove (int x, int y, const MouseState * mouseState); - - virtual bool isInSpecialKeyCaptureEvent () - { - return chatManager.getEditEnabled (); - } - - virtual bool quitTriggered (); - virtual Stats quitAndToggleState (); - Stats quitGame (); - static void exitGameState (Program * program, Stats & endStats); - - void startPerformanceTimer (); - void endPerformanceTimer (); - Vec2i getPerformanceTimerResults (); - - //static Texture2D * findFactionLogoTexture(const GameSettings *settings, Logger *logger=NULL,string factionLogoFilter=GameConstants::LOADING_SCREEN_FILE_FILTER, bool useTechDefaultIfFilterNotFound=true); - static string - findFactionLogoFile (const GameSettings * settings, Logger * logger = - NULL, const string & factionLogoFilter = - GameConstants::LOADING_SCREEN_FILE_FILTER); - static string - extractScenarioLogoFile (const GameSettings * settings, - string & result, bool & loadingImageUsed, - Logger * logger = - NULL, string factionLogoFilter = - GameConstants::LOADING_SCREEN_FILE_FILTER); - static string extractFactionLogoFile (bool & loadingImageUsed, - const string & factionName, - string scenarioDir, - const string & techName, - Logger * logger = - NULL, string factionLogoFilter = - GameConstants:: - LOADING_SCREEN_FILE_FILTER); - static string extractTechLogoFile (string scenarioDir, - const string & techName, - bool & loadingImageUsed, - Logger * logger = - NULL, - const string & factionLogoFilter = - GameConstants:: - LOADING_SCREEN_FILE_FILTER); - - void loadHudTexture (const GameSettings * settings); - - bool getGameOver () - { - return gameOver; - } - bool hasGameStarted () - { - return gameStarted; - } - virtual vector < Texture2D * >processTech (string techName); - virtual void consoleAddLine (string line); - - void endGame (); - - void playStaticVideo (const string & playVideo); - void playStreamingVideo (const string & playVideo); - void stopStreamingVideo (const string & playVideo); - void stopAllVideo (); - - string saveGame (string name, const string & path = "saved/"); - static void - loadGame (string name, Program * programPtr, bool isMasterserverMode, - const GameSettings * joinGameSettings = NULL); - - void - addNetworkCommandToReplayList (NetworkCommand * networkCommand, - int worldFrameCount); - - bool factionLostGame (int factionIndex); - - void addCellMarker (Vec2i cellPos, MarkedCell cellData); - void removeCellMarker (Vec2i surfaceCellPos, const Faction * faction); - void showMarker (Vec2i cellPos, MarkedCell cellData); - - void - highlightUnit (int unitId, float radius, float thickness, - Vec4f color); - void unhighlightUnit (int unitId); - - bool showTranslatedTechTree ()const; - - void DumpCRCWorldLogIfRequired (string fileSuffix = ""); - - bool getDisableSpeedChange ()const - { - return disableSpeedChange; - } - void setDisableSpeedChange (bool value) - { - disableSpeedChange = value; - } - - string getGamePerformanceCounts (bool displayWarnings) const; - virtual void addPerformanceCount (string key, int64 value); - bool getRenderInGamePerformance ()const - { - return renderInGamePerformance; - } - - private: - //render - void render3d (); - void render2d (); - - //misc - void checkWinner (); - void checkWinnerStandard (); - void checkWinnerScripted (); - void setEndGameTeamWinnersAndLosers (); - - //bool hasBuilding(const Faction *faction); - bool factionLostGame (const Faction * faction); - void incSpeed (); - void decSpeed (); - int getUpdateLoops (); - - void showLoseMessageBox (); - void showWinMessageBox (); - void - showMessageBox (const string & text, const string & header, - bool toggle); - void - showErrorMessageBox (const string & text, const string & header, - bool toggle); - - void renderWorker (); - static int ErrorDisplayMessage (const char *msg, bool exitApp); - - void - ReplaceDisconnectedNetworkPlayersWithAI (bool isNetworkGame, - NetworkRole role); - void calcCameraMoveX (); - void calcCameraMoveZ (); - - int getFirstUnusedTeamNumber (); - void updateWorldStats (); - - void setupPopupMenus (bool checkClientAdminOverrideOnly); - - string getDebugStats (std::map < int, string > &factionDebugInfo); - - void renderVideoPlayer (); - - void updateNetworkMarkedCells (); - void updateNetworkUnMarkedCells (); - void updateNetworkHighligtedCells (); - - virtual void processInputText (string text, bool cancelled); - - void startMarkCell (); - void startCameraFollowUnit (); - - bool - switchSetupForSlots (ServerInterface * &serverInterface, - int startIndex, int endIndex, - bool onlyNetworkUnassigned); - void processNetworkSynchChecksIfRequired (); - Stats getEndGameStats (); - void checkWinnerStandardHeadlessOrObserver (); - void checkWinnerStandardPlayer (); - std::map < int, int > getTeamsAlive (); - void initCamera (Map * map); - - virtual bool - clientLagHandler (int slotIndex, - bool networkPauseGameForLaggedClients); - }; - -}} //end namespace +namespace Glest { + namespace Game { + + class GraphicMessageBox; + class ServerInterface; + + enum LoadGameItem { + lgt_FactionPreview = 0x01, + lgt_TileSet = 0x02, + lgt_TechTree = 0x04, + lgt_Map = 0x08, + lgt_Scenario = 0x10, + + lgt_All = + (lgt_FactionPreview | lgt_TileSet | lgt_TechTree | lgt_Map | + lgt_Scenario) + }; + + // ===================================================== + // class Game + // + // Main game class + // ===================================================== + class Game : + public + ProgramState, + public + FileCRCPreCacheThreadCallbackInterface, + public CustomInputCallbackInterface, public ClientLagCallbackInterface { + public: + static const float highlightTime; + + private: + typedef vector < Ai * > Ais; + typedef vector < AiInterface * > AiInterfaces; + + private: + //main data + World world; + AiInterfaces aiInterfaces; + Gui gui; + GameCamera gameCamera; + Commander commander; + Console console; + ChatManager chatManager; + ScriptManager scriptManager; + + //misc + Checksum checksum; + string loadingText; + int mouse2d; + int mouseX; + int mouseY; //coords win32Api + Vec2i mouseCellPos; + + int updateFps, lastUpdateFps, avgUpdateFps; + int framesToCatchUpAsClient; + int framesToSlowDownAsClient; + int receivedTooEarlyInFrames[GameConstants::networkSmoothInterval]; + int + framesNeededToWaitForServerMessage[GameConstants:: + networkSmoothInterval]; + int + totalRenderFps, + renderFps, lastRenderFps, avgRenderFps, currentAvgRenderFpsTotal; + uint64 tickCount; + bool paused; + bool pauseRequestSent; + bool resumeRequestSent; + bool pauseStateChanged; + bool pausedForJoinGame; + bool pausedBeforeJoinGame; + + bool gameOver; + bool renderNetworkStatus; + bool renderInGamePerformance; + bool showFullConsole; + bool setMarker; + bool cameraDragAllowed; + bool mouseMoved; + float scrollSpeed; + bool camLeftButtonDown; + bool camRightButtonDown; + bool camUpButtonDown; + bool camDownButtonDown; + + int speed; + GraphicMessageBox mainMessageBox; + GraphicMessageBox errorMessageBox; + + //misc ptr + ParticleSystem *weatherParticleSystem; + GameSettings gameSettings; + Vec2i lastMousePos; + time_t lastRenderLog2d; + DisplayMessageFunction originalDisplayMsgCallback; + bool isFirstRender; + + bool quitTriggeredIndicator; + bool quitPendingIndicator; + + int original_updateFps; + int original_cameraFps; + + bool captureAvgTestStatus; + int updateFpsAvgTest; + int renderFpsAvgTest; + + int renderExtraTeamColor; + static const int renderTeamColorCircleBit = 1; + static const int renderTeamColorPlaneBit = 2; + + bool photoModeEnabled; + int healthbarMode; + bool visibleHUD; + bool timeDisplay; + bool withRainEffect; + Program *program; + + bool gameStarted; + + time_t lastMaxUnitCalcTime; + + PopupMenu popupMenu; + PopupMenu popupMenuSwitchTeams; + PopupMenu popupMenuDisconnectPlayer; + + std::map < int, int > switchTeamIndexMap; + GraphicMessageBox switchTeamConfirmMessageBox; + + std::map < int, int > disconnectPlayerIndexMap; + int playerIndexDisconnect; + GraphicMessageBox disconnectPlayerConfirmMessageBox; + + int exitGamePopupMenuIndex; + int joinTeamPopupMenuIndex; + int pauseGamePopupMenuIndex; + int saveGamePopupMenuIndex; + int loadGamePopupMenuIndex; + //int markCellPopupMenuIndex; + //int unmarkCellPopupMenuIndex; + int keyboardSetupPopupMenuIndex; + int disconnectPlayerPopupMenuIndex; + //GLuint statelist3dMenu; + ProgramState *currentUIState; + + bool isMarkCellEnabled; + Vec2i cellMarkedPos; + MarkedCell cellMarkedData; + bool isMarkCellTextEnabled; + + Texture2D *markCellTexture; + bool isUnMarkCellEnabled; + Texture2D *unmarkCellTexture; + std::map < Vec2i, MarkedCell > mapMarkedCellList; + Texture2D *highlightCellTexture; + std::vector < MarkedCell > highlightedCells; + bool masterserverMode; + + StrSound *currentAmbientSound; + + time_t lastNetworkPlayerConnectionCheck; + + time_t lastMasterServerGameStatsDump; + + XmlNode *loadGameNode; + int lastworldFrameCountForReplay; + std::vector < std::pair < int, NetworkCommand > > replayCommandList; + + std::vector < string > streamingVideos; + ::Shared::Graphics::VideoPlayer * videoPlayer; + bool playingStaticVideo; + + Unit *currentCameraFollowUnit; + + std::map < int, HighlightSpecialUnitInfo > unitHighlightList; + + MasterSlaveThreadController masterController; + + bool inJoinGameLoading; + bool initialResumeSpeedLoops; + + bool quitGameCalled; + bool disableSpeedChange; + + std::map < int, FowAlphaCellsLookupItem > teamFowAlphaCellsLookupItem; + std::map < string, int64 > gamePerformanceCounts; + + bool networkPauseGameForLaggedClientsRequested; + bool networkResumeGameForLaggedClientsRequested; + + public: + Game(); + Game(Program * program, const GameSettings * gameSettings, + bool masterserverMode); + ~Game(); + + void reInitGUI(); + bool isFlagType1BitEnabled(FlagTypes1 type) const; + + bool isMarkCellMode()const { + return isMarkCellEnabled; + } + const Texture2D *getMarkCellTexture() const { + return markCellTexture; + } + bool isUnMarkCellMode() const { + return isUnMarkCellEnabled; + } + const Texture2D *getUnMarkCellTexture() const { + return unmarkCellTexture; + } + + std::map < Vec2i, MarkedCell > getMapMarkedCellList() const { + return mapMarkedCellList; + } + + const Texture2D *getHighlightCellTexture() const { + return highlightCellTexture; + } + const std::vector < MarkedCell > *getHighlightedCells() const { + return &highlightedCells; + } + void addOrReplaceInHighlightedCells(MarkedCell mc); + + bool isMasterserverMode()const { + return masterserverMode; + } + //get + GameSettings *getGameSettings() { + return &gameSettings; + } + void setGameSettings(GameSettings * settings) { + gameSettings = *settings; + } + const GameSettings *getReadOnlyGameSettings() const { + return &gameSettings; + } + void setQuitPendingIndicator() { + quitPendingIndicator = true; + } + + const GameCamera *getGameCamera() const { + return &gameCamera; + } + GameCamera *getGameCameraPtr() { + return &gameCamera; + } + const Commander *getCommander() const { + return &commander; + } + Gui *getGuiPtr() { + return &gui; + } + const Gui *getGui() const { + return &gui; + } + Commander *getCommander() { + return &commander; + } + Console *getConsole() { + return &console; + } + ScriptManager *getScriptManager() { + return &scriptManager; + } + World *getWorld() { + return &world; + } + const World *getWorld() const { + return &world; + } + + Program *getProgram() { + return program; + } + + Vec2i getMouseCellPos()const { + return mouseCellPos; + } + bool isValidMouseCellPos() const; + + void removeUnitFromSelection(const Unit * unit); + bool addUnitToSelection(Unit * unit); + void addUnitToGroupSelection(Unit * unit, int groupIndex); + void removeUnitFromGroupSelection(int unitId, int groupIndex); + void recallGroupSelection(int groupIndex); + + Uint64 getTickCount() { + return tickCount; + } + bool getPaused(); + void + setPaused(bool value, bool forceAllowPauseStateChange, + bool clearCaches, bool joinNetworkGame); + void tryPauseToggle(bool pause); + void setupRenderForVideo(); + void saveGame(); + const int getTotalRenderFps() const { + return totalRenderFps; + } + + void toggleTeamColorMarker(); + //init + void resetMembers(); + virtual void load(int loadTypes); + virtual void load(); + virtual void init(); + virtual void init(bool initForPreviewOnly); + virtual void update(); + virtual void updateCamera(); + virtual void render(); + virtual void tick(); + + //event managing + virtual bool textInput(std::string text); + virtual bool sdlKeyDown(SDL_KeyboardEvent key); + virtual void keyDown(SDL_KeyboardEvent key); + virtual void keyUp(SDL_KeyboardEvent key); + virtual void keyPress(SDL_KeyboardEvent c); + virtual void mouseDownLeft(int x, int y); + virtual void mouseDownRight(int x, int y); + virtual void mouseUpCenter(int x, int y); + virtual void mouseUpLeft(int x, int y); + virtual void mouseDoubleClickLeft(int x, int y); + virtual void eventMouseWheel(int x, int y, int zDelta); + virtual void mouseMove(int x, int y, const MouseState * mouseState); + + virtual bool isInSpecialKeyCaptureEvent() { + return chatManager.getEditEnabled(); + } + + virtual bool quitTriggered(); + virtual Stats quitAndToggleState(); + Stats quitGame(); + static void exitGameState(Program * program, Stats & endStats); + + void startPerformanceTimer(); + void endPerformanceTimer(); + Vec2i getPerformanceTimerResults(); + + //static Texture2D * findFactionLogoTexture(const GameSettings *settings, Logger *logger=NULL,string factionLogoFilter=GameConstants::LOADING_SCREEN_FILE_FILTER, bool useTechDefaultIfFilterNotFound=true); + static string + findFactionLogoFile(const GameSettings * settings, Logger * logger = + NULL, const string & factionLogoFilter = + GameConstants::LOADING_SCREEN_FILE_FILTER); + static string + extractScenarioLogoFile(const GameSettings * settings, + string & result, bool & loadingImageUsed, + Logger * logger = + NULL, string factionLogoFilter = + GameConstants::LOADING_SCREEN_FILE_FILTER); + static string extractFactionLogoFile(bool & loadingImageUsed, + const string & factionName, + string scenarioDir, + const string & techName, + Logger * logger = + NULL, string factionLogoFilter = + GameConstants:: + LOADING_SCREEN_FILE_FILTER); + static string extractTechLogoFile(string scenarioDir, + const string & techName, + bool & loadingImageUsed, + Logger * logger = + NULL, + const string & factionLogoFilter = + GameConstants:: + LOADING_SCREEN_FILE_FILTER); + + void loadHudTexture(const GameSettings * settings); + + bool getGameOver() { + return gameOver; + } + bool hasGameStarted() { + return gameStarted; + } + virtual vector < Texture2D * >processTech(string techName); + virtual void consoleAddLine(string line); + + void endGame(); + + void playStaticVideo(const string & playVideo); + void playStreamingVideo(const string & playVideo); + void stopStreamingVideo(const string & playVideo); + void stopAllVideo(); + + string saveGame(string name, const string & path = "saved/"); + static void + loadGame(string name, Program * programPtr, bool isMasterserverMode, + const GameSettings * joinGameSettings = NULL); + + void + addNetworkCommandToReplayList(NetworkCommand * networkCommand, + int worldFrameCount); + + bool factionLostGame(int factionIndex); + + void addCellMarker(Vec2i cellPos, MarkedCell cellData); + void removeCellMarker(Vec2i surfaceCellPos, const Faction * faction); + void showMarker(Vec2i cellPos, MarkedCell cellData); + + void + highlightUnit(int unitId, float radius, float thickness, + Vec4f color); + void unhighlightUnit(int unitId); + + bool showTranslatedTechTree()const; + + void DumpCRCWorldLogIfRequired(string fileSuffix = ""); + + bool getDisableSpeedChange()const { + return disableSpeedChange; + } + void setDisableSpeedChange(bool value) { + disableSpeedChange = value; + } + + string getGamePerformanceCounts(bool displayWarnings) const; + virtual void addPerformanceCount(string key, int64 value); + bool getRenderInGamePerformance()const { + return renderInGamePerformance; + } + + private: + //render + void render3d(); + void render2d(); + + //misc + void checkWinner(); + void checkWinnerStandard(); + void checkWinnerScripted(); + void setEndGameTeamWinnersAndLosers(); + + //bool hasBuilding(const Faction *faction); + bool factionLostGame(const Faction * faction); + void incSpeed(); + void decSpeed(); + int getUpdateLoops(); + + void showLoseMessageBox(); + void showWinMessageBox(); + void + showMessageBox(const string & text, const string & header, + bool toggle); + void + showErrorMessageBox(const string & text, const string & header, + bool toggle); + + void renderWorker(); + static int ErrorDisplayMessage(const char *msg, bool exitApp); + + void + ReplaceDisconnectedNetworkPlayersWithAI(bool isNetworkGame, + NetworkRole role); + void calcCameraMoveX(); + void calcCameraMoveZ(); + + int getFirstUnusedTeamNumber(); + void updateWorldStats(); + + void setupPopupMenus(bool checkClientAdminOverrideOnly); + + string getDebugStats(std::map < int, string > &factionDebugInfo); + + void renderVideoPlayer(); + + void updateNetworkMarkedCells(); + void updateNetworkUnMarkedCells(); + void updateNetworkHighligtedCells(); + + virtual void processInputText(string text, bool cancelled); + + void startMarkCell(); + void startCameraFollowUnit(); + + bool + switchSetupForSlots(ServerInterface * &serverInterface, + int startIndex, int endIndex, + bool onlyNetworkUnassigned); + void processNetworkSynchChecksIfRequired(); + Stats getEndGameStats(); + void checkWinnerStandardHeadlessOrObserver(); + void checkWinnerStandardPlayer(); + std::map < int, int > getTeamsAlive(); + void initCamera(Map * map); + + virtual bool + clientLagHandler(int slotIndex, + bool networkPauseGameForLaggedClients); + }; + + } +} //end namespace #endif diff --git a/source/glest_game/game/game_camera.cpp b/source/glest_game/game/game_camera.cpp index d84c58f18..da23e1e02 100644 --- a/source/glest_game/game/game_camera.cpp +++ b/source/glest_game/game/game_camera.cpp @@ -23,821 +23,733 @@ using namespace - Shared::Graphics; +Shared::Graphics; using - Shared::Xml::XmlNode; +Shared::Xml::XmlNode; using namespace - Shared::Util; +Shared::Util; namespace - Glest -{ - namespace - Game - { - -// ===================================================== -// class GameCamera -// ===================================================== - -//static std::map > > cacheVisibleQuad; - -// ================== PUBLIC ===================== - - const float - GameCamera::startingVAng = -60.f; - const float - GameCamera::startingHAng = 0.f; - const float - GameCamera::vTransitionMult = 0.125f; - const float - GameCamera::hTransitionMult = 0.125f; - const float - GameCamera::defaultHeight = 20.f; - const float - GameCamera::centerOffsetZ = 8.0f; - const float - GameCamera::shakeDist = 50.f; - -// ================= Constructor ================= - - GameCamera::GameCamera (): - pos (0.f, defaultHeight, 0.f), - destPos (0.f, defaultHeight, 0.f), - destAng (startingVAng, startingHAng) - { - //Config &config = Config::getInstance(); - calculatedDefault = defaultHeight; - state = sGame; - - cacheVisibleQuad. - clear (); - //MaxVisibleQuadItemCache = config.getInt("MaxVisibleQuadItemCache",intToStr(-1).c_str()); - MaxVisibleQuadItemCache = -1; - //if(Config::getInstance().getBool("DisableCaching","false") == true) { - // MaxVisibleQuadItemCache = 0; - //} - - //config - speed = - Config::getInstance ().getFloat ("CameraMoveSpeed", - "15") / GameConstants::cameraFps; - clampBounds = !Config::getInstance ().getBool ("PhotoMode"); - clampDisable = false; - - vAng = startingVAng; - hAng = startingHAng; - - rotate = 0; - - move = Vec3f (0.f); - - shakeDecrement = 0.f; - currentShakeIntensity = 0; - shakeOffset = Vec2f (0.f); - - //maxRenderDistance = Config::getInstance().getFloat("RenderDistanceMax","64"); - maxHeight = Config::getInstance ().getFloat ("CameraMaxDistance", "20"); - minHeight = Config::getInstance ().getFloat ("CameraMinDistance", "7"); - //maxCameraDist = maxHeight; - //minCameraDist = minHeight; - minVAng = -Config::getInstance ().getFloat ("CameraMaxYaw", "77.5"); - maxVAng = -Config::getInstance ().getFloat ("CameraMinYaw", "20"); - fov = Config::getInstance ().getFloat ("CameraFov", "45"); - - lastHAng = 0; - lastVAng = 0; - limitX = 0; - limitY = 0; - } - - GameCamera::~ - GameCamera () - { - cacheVisibleQuad.clear (); - } - - std::string - GameCamera::getCameraMovementKey () const - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "%s_%f_%f_%f_%s,%f", pos.getString ().c_str (), - hAng, vAng, rotate, move.getString ().c_str (), fov); - return - szBuf; - } - - void - GameCamera::setMaxHeight (float value) - { - if (value < 0) - { - maxHeight = - Config::getInstance ().getFloat ("CameraMaxDistance", "20"); - } - else - { - maxHeight = value; - } - } - - void - GameCamera::setCalculatedDefault (float calculatedDefault) - { - this->calculatedDefault = calculatedDefault; - if (maxHeight > 0 && maxHeight < calculatedDefault) - { - setMaxHeight (calculatedDefault); - } - resetPosition (); - } - - void - GameCamera::init (int limitX, int limitY) - { - this->limitX = limitX; - this->limitY = limitY; - } - -// ==================== Misc ===================== - - void - GameCamera::setPos (Vec2f pos) - { - this->pos = Vec3f (pos.x, this->pos.y, pos.y); - clampPosXZ (0.0f, (float) limitX, 0.0f, (float) limitY); - destPos.x = pos.x; - destPos.z = pos.y; - } - - void - GameCamera::setPos (Vec3f pos) - { - this->pos = pos; - //clampPosXZ(0.0f, (float)limitX, 0.0f, (float)limitY); - destPos.x = pos.x; - destPos.y = pos.y; - destPos.z = pos.z; - } - - void - GameCamera::shake (int shakeDuration, int shakeStartIntensity, - bool cameraDistanceAffected, Vec3f unitVector) - { - float - currentDurationLeft = 0; - float - incomingShakeIntensity = ((float) shakeStartIntensity) / 1000; - - // calculate the shake duration which is left - if (this->currentShakeIntensity > 0.f && this->shakeDecrement != 0.f) - { - currentDurationLeft = - this->currentShakeIntensity / this->shakeDecrement; - } - - // reduce new shake effect camera distance related - if (cameraDistanceAffected) - { - incomingShakeIntensity = - incomingShakeIntensity * (1.f - - unitVector.dist (getPos ()) / - GameCamera::shakeDist); - } - - // add camera shake effect to current one ( if exsists ). - if (this->currentShakeIntensity > 0) - { - this->currentShakeIntensity = - this->currentShakeIntensity + incomingShakeIntensity; - } - else - { - this->currentShakeIntensity = incomingShakeIntensity; - } - - // use bigger shakeDuration to calculate new shakeDecrement - if (currentDurationLeft < shakeDuration) - { - this->shakeDecrement = - currentShakeIntensity / ((float) shakeDuration); - } - else if (currentDurationLeft != 0.0f) - { - this->shakeDecrement = - currentShakeIntensity / ((float) currentDurationLeft); - } - } - - void - GameCamera::shakeCamera () - { - //RandomGen random; - if (currentShakeIntensity > 0.f) - { -// pos.x += (((float) (rand() % 50)) / 50.f - 0.5f) * currentShakeIntensity; -// pos.z += (((float) (rand() % 50)) / 50.f - 0.5f) * currentShakeIntensity; - - shakeOffset.x = - (((float) (rand () % 50)) / 50.f - 0.5f) * currentShakeIntensity; - shakeOffset.y = - (((float) (rand () % 50)) / 50.f - 0.5f) * currentShakeIntensity; - currentShakeIntensity -= shakeDecrement; - } - } - - void - GameCamera::update () - { - //move XZ - if (move.z) - { - moveForwardH (speed * move.z, 0.9f); - } - if (move.x) - { - moveSideH (speed * move.x, 0.9f); - } - - //free state - if (state == sFree) - { - if (std::fabs (rotate) == 1) - { - rotateHV (speed * 5 * rotate, 0); - } - if (move.y > 0) - { - moveUp (speed * move.y); - if (clampDisable == false && clampBounds && pos.y < maxHeight) - { - rotateHV (0.f, -speed * 1.7f * move.y); - } - } - if (move.y < 0) - { - moveUp (speed * move.y); - if (clampDisable == false && clampBounds && pos.y > minHeight) - { - rotateHV (0.f, -speed * 1.7f * move.y); - } - } - } - - //game state - if (abs (destAng.x - vAng) > 0.01f) - { - vAng += (destAng.x - vAng) * hTransitionMult; - } - if (abs (destAng.y - hAng) > 0.01f) - { - if (abs (destAng.y - hAng) > 180) - { - if (destAng.y > hAng) - { - hAng += (destAng.y - hAng - 360) * vTransitionMult; - } - else - { - hAng += (destAng.y - hAng + 360) * vTransitionMult; - } - } - else - { - hAng += (destAng.y - hAng) * vTransitionMult; - } - } - if (abs (destPos.x - pos.x) > 0.01f) - { - pos.x += (destPos.x - pos.x) / 32.0f; - } - if (abs (destPos.y - pos.y) > 0.01f) - { - pos.y += (destPos.y - pos.y) / 32.0f; - } - if (abs (destPos.z - pos.z) > 0.01f) - { - pos.z += (destPos.z - pos.z) / 32.0f; - } - clampAng (); - shakeCamera (); - - if (clampDisable == false && clampBounds) - { - clampPosXYZ (0.0f, (float) limitX, minHeight, maxHeight, 0.0f, - (float) limitY); - } - } - - Quad2i - GameCamera::computeVisibleQuad () - { - //printf("\n@@@ hAng [%f] vAng [%f] fov [%f]\n",hAng,vAng,fov); - - if (MaxVisibleQuadItemCache != 0) - { - std::map < float, - std::map < float, - std::map < - Vec3f, - Quad2i > > >::const_iterator - iterFind = cacheVisibleQuad.find (fov); - if (iterFind != cacheVisibleQuad.end ()) - { - std::map < float, - std::map < - Vec3f, - Quad2i > >::const_iterator - iterFind2 = iterFind->second.find (hAng); - if (iterFind2 != iterFind->second.end ()) - { - std::map < Vec3f, Quad2i >::const_iterator iterFind3 = - iterFind2->second.find (pos); - if (iterFind3 != iterFind2->second.end ()) - { - return iterFind3->second; - } - } - } - } - - float - nearDist = 15.f; - float - dist = pos.y > nearDist ? pos.y * 1.2f : nearDist; - float - farDist = 90.f * (pos.y > nearDist ? pos.y / 15.f : 1.f); - const float - viewDegree = 180.f; - - Vec2f - v (std::sin (degToRad (viewDegree - hAng)), - std::cos (degToRad (viewDegree - hAng))); - Vec2f - v1 (std::sin (degToRad (viewDegree - hAng - fov)), - std::cos (degToRad (viewDegree - hAng - fov))); - Vec2f - v2 (std::sin (degToRad (viewDegree - hAng + fov)), - std::cos (degToRad (viewDegree - hAng + fov))); - - v.normalize (); - v1.normalize (); - v2.normalize (); - - Vec2f - p = Vec2f (pos.x, pos.z) - v * dist; - Vec2i - p1 (static_cast < int >(p.x + v1.x * nearDist), - static_cast < int >(p.y + v1.y * nearDist)); - Vec2i - p2 (static_cast < int >(p.x + v1.x * farDist), - static_cast < int >(p.y + v1.y * farDist)); - Vec2i - p3 (static_cast < int >(p.x + v2.x * nearDist), - static_cast < int >(p.y + v2.y * nearDist)); - Vec2i - p4 (static_cast < int >(p.x + v2.x * farDist), - static_cast < int >(p.y + v2.y * farDist)); - - const bool - debug = false; - - Quad2i - result; - if (hAng >= 135 && hAng <= 225) - { - if (debug) - printf ("Line %d hAng [%f] fov [%f]\n", __LINE__, hAng, fov); - - result = Quad2i (p1, p2, p3, p4); - if (MaxVisibleQuadItemCache != 0 && - (MaxVisibleQuadItemCache < 0 - || (int) cacheVisibleQuad[fov][hAng].size () <= - MaxVisibleQuadItemCache)) - { - cacheVisibleQuad[fov][hAng][pos] = result; - } - } - else if (hAng >= 45 && hAng <= 135) - { - if (debug) - printf ("Line %d hAng [%f] fov [%f]\n", __LINE__, hAng, fov); - - result = Quad2i (p3, p1, p4, p2); - if (MaxVisibleQuadItemCache != 0 && - (MaxVisibleQuadItemCache < 0 - || (int) cacheVisibleQuad[fov][hAng].size () <= - MaxVisibleQuadItemCache)) - { - cacheVisibleQuad[fov][hAng][pos] = result; - } - } - else if (hAng >= 225 && hAng <= 315) - { - if (debug) - printf ("Line %d hAng [%f] fov [%f]\n", __LINE__, hAng, fov); - - result = Quad2i (p2, p4, p1, p3); - if (MaxVisibleQuadItemCache != 0 && - (MaxVisibleQuadItemCache < 0 - || (int) cacheVisibleQuad[fov][hAng].size () <= - MaxVisibleQuadItemCache)) - { - cacheVisibleQuad[fov][hAng][pos] = result; - } - } - else - { - if (debug) - printf ("Line %d hAng [%f] fov [%f]\n", __LINE__, hAng, fov); - - result = Quad2i (p4, p3, p2, p1); - if (MaxVisibleQuadItemCache != 0 && - (MaxVisibleQuadItemCache < 0 - || (int) cacheVisibleQuad[fov][hAng].size () <= - MaxVisibleQuadItemCache)) - { - cacheVisibleQuad[fov][hAng][pos] = Quad2i (p4, p3, p2, p1); - } - } - - return result; - } - - void - GameCamera::setState (State s) - { - if (s == sGame) - { - state = sGame; - setClampDisabled (false); - resetPosition (); - } - else if (s == sUnit) - { - state = sUnit; - setClampDisabled (true); - } - else if (s == sFree) - { - state = sFree; - setClampDisabled (false); - resetPosition (); - } - else - { - abort (); //"unknown camera state" - } - } - - void - GameCamera::resetPosition () - { - destAng.x = startingVAng; - destAng.y = startingHAng; - destPos.y = calculatedDefault; - } - - void - GameCamera::centerXZ (float x, float z) - { - destPos.x = pos.x = x; - destPos.z = pos.z = z + centerOffsetZ; - } - -//void GameCamera::transitionXYZ(float x, float y, float z) { -// destPos.x += x; -// destPos.y += y; -// destPos.z += z; -// clampPosXYZ(0.0f, (float)limitX, minHeight, maxHeight, 0.0f, (float)limitY); -//} - - void - GameCamera::transitionVH (float v, float h) - { - destAng.x -= v; - //destPos.y -= v * destPos.y / 100.f; - destAng.y -= h; - clampAng (); - } - - void - GameCamera::rotateToVH (float v, float h) - { - destAng.x = v; - destAng.y = h; - clampAng (); - } - - void - GameCamera::zoom (float dist) - { - float - flatDist = dist * std::cos (degToRad (vAng)); - Vec3f - offset (flatDist * std::sin (degToRad (hAng)), - dist * std::sin (degToRad (vAng)), - flatDist * -std::cos (degToRad (hAng))); - - destPos += offset; - } - - void - GameCamera::load (const XmlNode * node) - { - //destPos = node->getChildVec3fValue("pos"); - //destAng = node->getChildVec2fValue("angle"); - } - - void - GameCamera::save (XmlNode * node) const - { - //node->addChild("pos", pos); - //node->addChild("angle", Vec2f(vAng, hAng)); - } - -// ==================== PRIVATE ==================== - - void - GameCamera::clampPosXZ (float x1, float x2, float z1, float z2) - { - if (clampDisable == true) - { - return; - } - - if (pos.x < x1) - pos.x = x1; - if (destPos.x < x1) - destPos.x = x1; - if (pos.z < z1) - pos.z = z1; - if (destPos.z < z1) - destPos.z = z1; - if (pos.x > x2) - pos.x = x2; - if (destPos.x > x2) - destPos.x = x2; - if (pos.z > z2) - pos.z = z2; - if (destPos.z > z2) - destPos.z = z2; - } - - void - GameCamera::clampPosXYZ (float x1, float x2, float y1, float y2, float z1, - float z2) - { - if (clampDisable == true) - { - return; - } - - if (pos.x < x1) - pos.x = x1; - if (destPos.x < x1) - destPos.x = x1; - if (pos.y < y1) - pos.y = y1; - if (destPos.y < y1) - destPos.y = y1; - if (pos.z < z1) - pos.z = z1; - if (destPos.z < z1) - destPos.z = z1; - if (pos.x > x2) - pos.x = x2; - if (destPos.x > x2) - destPos.x = x2; - if (pos.y > y2) - pos.y = y2; - if (destPos.y > y2) - destPos.y = y2; - if (pos.z > z2) - pos.z = z2; - if (destPos.z > z2) - destPos.z = z2; - } - - void - GameCamera::rotateHV (float h, float v) - { - destAng.x = vAng += v; - destAng.y = hAng += h; - clampAng (); - } - - void - GameCamera::clampAng () - { - if (clampDisable == true && state != sUnit) - { - return; - } - - if (vAng > maxVAng) - vAng = maxVAng; - if (destAng.x > maxVAng) - destAng.x = maxVAng; - if (vAng < minVAng) - vAng = minVAng; - if (destAng.x < minVAng) - destAng.x = minVAng; - if (hAng > 360.f) - hAng -= 360.f; - if (destAng.y > 360.f) - destAng.y -= 360.f; - if (hAng < 0.f) - hAng += 360.f; - if (destAng.y < 0.f) - destAng.y = 360.f; - } - -//move camera forwad but never change heightFactor - void - GameCamera::moveForwardH (float d, float response) - { - Vec3f - offset (std::sin (degToRad (hAng)) * d, 0.f, - -std::cos (degToRad (hAng)) * d); - destPos += offset; - pos.x += offset.x * response; - pos.z += offset.z * response; - } - -//move camera to a side but never change heightFactor - void - GameCamera::moveSideH (float d, float response) - { - Vec3f - offset (std::sin (degToRad (hAng + 90)) * d, 0.f, - -std::cos (degToRad (hAng + 90)) * d); - destPos += offset; - pos.x += (destPos.x - pos.x) * response; - pos.z += (destPos.z - pos.z) * response; - } - - void - GameCamera::moveUp (float d) - { -// pos.y+= d; - destPos.y += d; - } - - void - GameCamera::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode * - gamecameraNode = rootNode->addChild ("GameCamera"); - -// Vec3f pos; - gamecameraNode->addAttribute ("pos", pos.getString (), - mapTagReplacements); -// Vec3f destPos; - gamecameraNode->addAttribute ("destPos", destPos.getString (), - mapTagReplacements); -// -// float hAng; //YZ plane positive -Z axis - gamecameraNode->addAttribute ("hAng", floatToStr (hAng, 6), - mapTagReplacements); -// float vAng; //XZ plane positive +Z axis - gamecameraNode->addAttribute ("vAng", floatToStr (vAng, 6), - mapTagReplacements); -// float lastHAng; - gamecameraNode->addAttribute ("lastHAng", floatToStr (lastHAng, 6), - mapTagReplacements); - -// float lastVAng; - gamecameraNode->addAttribute ("lastVAng", floatToStr (lastVAng, 6), - mapTagReplacements); -// Vec2f destAng; - gamecameraNode->addAttribute ("destAng", destAng.getString (), - mapTagReplacements); -// float rotate; - gamecameraNode->addAttribute ("rotate", floatToStr (rotate, 6), - mapTagReplacements); -// Vec3f move; - gamecameraNode->addAttribute ("move", move.getString (), - mapTagReplacements); -// State state; - gamecameraNode->addAttribute ("state", intToStr (state), - mapTagReplacements); -// int limitX; - gamecameraNode->addAttribute ("limitX", intToStr (limitX), - mapTagReplacements); -// int limitY; - gamecameraNode->addAttribute ("limitY", intToStr (limitY), - mapTagReplacements); -// //config -// float speed; - gamecameraNode->addAttribute ("speed", floatToStr (speed, 6), - mapTagReplacements); -// bool clampBounds; - gamecameraNode->addAttribute ("clampBounds", intToStr (clampBounds), - mapTagReplacements); -// //float maxRenderDistance; -// float maxHeight; - gamecameraNode->addAttribute ("maxHeight", floatToStr (maxHeight, 6), - mapTagReplacements); -// float minHeight; - gamecameraNode->addAttribute ("minHeight", floatToStr (minHeight, 6), - mapTagReplacements); -// //float maxCameraDist; -// //float minCameraDist; -// float minVAng; - gamecameraNode->addAttribute ("minVAng", floatToStr (minVAng, 6), - mapTagReplacements); -// float maxVAng; - gamecameraNode->addAttribute ("maxVAng", floatToStr (maxVAng, 6), - mapTagReplacements); -// float fov; - gamecameraNode->addAttribute ("fov", floatToStr (fov, 6), - mapTagReplacements); -// float calculatedDefault; - gamecameraNode->addAttribute ("calculatedDefault", - floatToStr (calculatedDefault, 6), - mapTagReplacements); -// std::map > > cacheVisibleQuad; -// int MaxVisibleQuadItemCache; - gamecameraNode->addAttribute ("MaxVisibleQuadItemCache", - intToStr (MaxVisibleQuadItemCache), - mapTagReplacements); - } - - void - GameCamera::loadGame (const XmlNode * rootNode) - { - const XmlNode * - gamecameraNode = rootNode->getChild ("GameCamera"); - - //firstTime = timeflowNode->getAttribute("firstTime")->getFloatValue(); - - // Vec3f pos; - pos = - Vec3f::strToVec3 (gamecameraNode->getAttribute ("pos")->getValue ()); - // Vec3f destPos; - destPos = - Vec3f::strToVec3 (gamecameraNode->getAttribute ("destPos")-> - getValue ()); - // - // float hAng; //YZ plane positive -Z axis - hAng = gamecameraNode->getAttribute ("hAng")->getFloatValue (); - // float vAng; //XZ plane positive +Z axis - vAng = gamecameraNode->getAttribute ("vAng")->getFloatValue (); - // float lastHAng; - lastHAng = gamecameraNode->getAttribute ("lastHAng")->getFloatValue (); - - // float lastVAng; - lastVAng = gamecameraNode->getAttribute ("lastVAng")->getFloatValue (); - // Vec2f destAng; - destAng = - Vec2f::strToVec2 (gamecameraNode->getAttribute ("destAng")-> - getValue ()); - // float rotate; - rotate = gamecameraNode->getAttribute ("rotate")->getFloatValue (); - // Vec3f move; - move = - Vec3f::strToVec3 (gamecameraNode->getAttribute ("move")->getValue ()); - // State state; - state = - static_cast < State > - (gamecameraNode->getAttribute ("state")->getIntValue ()); - // int limitX; - limitX = gamecameraNode->getAttribute ("limitX")->getIntValue (); - // int limitY; - limitY = gamecameraNode->getAttribute ("limitY")->getIntValue (); - // //config - // float speed; - speed = gamecameraNode->getAttribute ("speed")->getFloatValue (); - // bool clampBounds; - clampBounds = - gamecameraNode->getAttribute ("clampBounds")->getIntValue () != 0; - // //float maxRenderDistance; - // float maxHeight; - maxHeight = - gamecameraNode->getAttribute ("maxHeight")->getFloatValue (); - // float minHeight; - minHeight = - gamecameraNode->getAttribute ("minHeight")->getFloatValue (); - // //float maxCameraDist; - // //float minCameraDist; - // float minVAng; - minVAng = gamecameraNode->getAttribute ("minVAng")->getFloatValue (); - // float maxVAng; - maxVAng = gamecameraNode->getAttribute ("maxVAng")->getFloatValue (); - // float fov; - fov = gamecameraNode->getAttribute ("fov")->getFloatValue (); - // float calculatedDefault; - calculatedDefault = - gamecameraNode->getAttribute ("calculatedDefault")->getFloatValue (); - // std::map > > cacheVisibleQuad; - // int MaxVisibleQuadItemCache; - MaxVisibleQuadItemCache = - gamecameraNode->getAttribute ("MaxVisibleQuadItemCache")-> - getIntValue (); - - } - -}} //end namespace + Glest { + namespace + Game { + + // ===================================================== + // class GameCamera + // ===================================================== + + //static std::map > > cacheVisibleQuad; + + // ================== PUBLIC ===================== + + const float + GameCamera::startingVAng = -60.f; + const float + GameCamera::startingHAng = 0.f; + const float + GameCamera::vTransitionMult = 0.125f; + const float + GameCamera::hTransitionMult = 0.125f; + const float + GameCamera::defaultHeight = 20.f; + const float + GameCamera::centerOffsetZ = 8.0f; + const float + GameCamera::shakeDist = 50.f; + + // ================= Constructor ================= + + GameCamera::GameCamera() : + pos(0.f, defaultHeight, 0.f), + destPos(0.f, defaultHeight, 0.f), + destAng(startingVAng, startingHAng) { + //Config &config = Config::getInstance(); + calculatedDefault = defaultHeight; + state = sGame; + + cacheVisibleQuad. + clear(); + //MaxVisibleQuadItemCache = config.getInt("MaxVisibleQuadItemCache",intToStr(-1).c_str()); + MaxVisibleQuadItemCache = -1; + //if(Config::getInstance().getBool("DisableCaching","false") == true) { + // MaxVisibleQuadItemCache = 0; + //} + + //config + speed = + Config::getInstance().getFloat("CameraMoveSpeed", + "15") / GameConstants::cameraFps; + clampBounds = !Config::getInstance().getBool("PhotoMode"); + clampDisable = false; + + vAng = startingVAng; + hAng = startingHAng; + + rotate = 0; + + move = Vec3f(0.f); + + shakeDecrement = 0.f; + currentShakeIntensity = 0; + shakeOffset = Vec2f(0.f); + + //maxRenderDistance = Config::getInstance().getFloat("RenderDistanceMax","64"); + maxHeight = Config::getInstance().getFloat("CameraMaxDistance", "20"); + minHeight = Config::getInstance().getFloat("CameraMinDistance", "7"); + //maxCameraDist = maxHeight; + //minCameraDist = minHeight; + minVAng = -Config::getInstance().getFloat("CameraMaxYaw", "77.5"); + maxVAng = -Config::getInstance().getFloat("CameraMinYaw", "20"); + fov = Config::getInstance().getFloat("CameraFov", "45"); + + lastHAng = 0; + lastVAng = 0; + limitX = 0; + limitY = 0; + } + + GameCamera::~ + GameCamera() { + cacheVisibleQuad.clear(); + } + + std::string + GameCamera::getCameraMovementKey() const { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "%s_%f_%f_%f_%s,%f", pos.getString().c_str(), + hAng, vAng, rotate, move.getString().c_str(), fov); + return + szBuf; + } + + void + GameCamera::setMaxHeight(float value) { + if (value < 0) { + maxHeight = + Config::getInstance().getFloat("CameraMaxDistance", "20"); + } else { + maxHeight = value; + } + } + + void + GameCamera::setCalculatedDefault(float calculatedDefault) { + this->calculatedDefault = calculatedDefault; + if (maxHeight > 0 && maxHeight < calculatedDefault) { + setMaxHeight(calculatedDefault); + } + resetPosition(); + } + + void + GameCamera::init(int limitX, int limitY) { + this->limitX = limitX; + this->limitY = limitY; + } + + // ==================== Misc ===================== + + void + GameCamera::setPos(Vec2f pos) { + this->pos = Vec3f(pos.x, this->pos.y, pos.y); + clampPosXZ(0.0f, (float) limitX, 0.0f, (float) limitY); + destPos.x = pos.x; + destPos.z = pos.y; + } + + void + GameCamera::setPos(Vec3f pos) { + this->pos = pos; + //clampPosXZ(0.0f, (float)limitX, 0.0f, (float)limitY); + destPos.x = pos.x; + destPos.y = pos.y; + destPos.z = pos.z; + } + + void + GameCamera::shake(int shakeDuration, int shakeStartIntensity, + bool cameraDistanceAffected, Vec3f unitVector) { + float + currentDurationLeft = 0; + float + incomingShakeIntensity = ((float) shakeStartIntensity) / 1000; + + // calculate the shake duration which is left + if (this->currentShakeIntensity > 0.f && this->shakeDecrement != 0.f) { + currentDurationLeft = + this->currentShakeIntensity / this->shakeDecrement; + } + + // reduce new shake effect camera distance related + if (cameraDistanceAffected) { + incomingShakeIntensity = + incomingShakeIntensity * (1.f - + unitVector.dist(getPos()) / + GameCamera::shakeDist); + } + + // add camera shake effect to current one ( if exsists ). + if (this->currentShakeIntensity > 0) { + this->currentShakeIntensity = + this->currentShakeIntensity + incomingShakeIntensity; + } else { + this->currentShakeIntensity = incomingShakeIntensity; + } + + // use bigger shakeDuration to calculate new shakeDecrement + if (currentDurationLeft < shakeDuration) { + this->shakeDecrement = + currentShakeIntensity / ((float) shakeDuration); + } else if (currentDurationLeft != 0.0f) { + this->shakeDecrement = + currentShakeIntensity / ((float) currentDurationLeft); + } + } + + void + GameCamera::shakeCamera() { + //RandomGen random; + if (currentShakeIntensity > 0.f) { + // pos.x += (((float) (rand() % 50)) / 50.f - 0.5f) * currentShakeIntensity; + // pos.z += (((float) (rand() % 50)) / 50.f - 0.5f) * currentShakeIntensity; + + shakeOffset.x = + (((float) (rand() % 50)) / 50.f - 0.5f) * currentShakeIntensity; + shakeOffset.y = + (((float) (rand() % 50)) / 50.f - 0.5f) * currentShakeIntensity; + currentShakeIntensity -= shakeDecrement; + } + } + + void + GameCamera::update() { + //move XZ + if (move.z) { + moveForwardH(speed * move.z, 0.9f); + } + if (move.x) { + moveSideH(speed * move.x, 0.9f); + } + + //free state + if (state == sFree) { + if (std::fabs(rotate) == 1) { + rotateHV(speed * 5 * rotate, 0); + } + if (move.y > 0) { + moveUp(speed * move.y); + if (clampDisable == false && clampBounds && pos.y < maxHeight) { + rotateHV(0.f, -speed * 1.7f * move.y); + } + } + if (move.y < 0) { + moveUp(speed * move.y); + if (clampDisable == false && clampBounds && pos.y > minHeight) { + rotateHV(0.f, -speed * 1.7f * move.y); + } + } + } + + //game state + if (abs(destAng.x - vAng) > 0.01f) { + vAng += (destAng.x - vAng) * hTransitionMult; + } + if (abs(destAng.y - hAng) > 0.01f) { + if (abs(destAng.y - hAng) > 180) { + if (destAng.y > hAng) { + hAng += (destAng.y - hAng - 360) * vTransitionMult; + } else { + hAng += (destAng.y - hAng + 360) * vTransitionMult; + } + } else { + hAng += (destAng.y - hAng) * vTransitionMult; + } + } + if (abs(destPos.x - pos.x) > 0.01f) { + pos.x += (destPos.x - pos.x) / 32.0f; + } + if (abs(destPos.y - pos.y) > 0.01f) { + pos.y += (destPos.y - pos.y) / 32.0f; + } + if (abs(destPos.z - pos.z) > 0.01f) { + pos.z += (destPos.z - pos.z) / 32.0f; + } + clampAng(); + shakeCamera(); + + if (clampDisable == false && clampBounds) { + clampPosXYZ(0.0f, (float) limitX, minHeight, maxHeight, 0.0f, + (float) limitY); + } + } + + Quad2i + GameCamera::computeVisibleQuad() { + //printf("\n@@@ hAng [%f] vAng [%f] fov [%f]\n",hAng,vAng,fov); + + if (MaxVisibleQuadItemCache != 0) { + std::map < float, + std::map < float, + std::map < + Vec3f, + Quad2i > > >::const_iterator + iterFind = cacheVisibleQuad.find(fov); + if (iterFind != cacheVisibleQuad.end()) { + std::map < float, + std::map < + Vec3f, + Quad2i > >::const_iterator + iterFind2 = iterFind->second.find(hAng); + if (iterFind2 != iterFind->second.end()) { + std::map < Vec3f, Quad2i >::const_iterator iterFind3 = + iterFind2->second.find(pos); + if (iterFind3 != iterFind2->second.end()) { + return iterFind3->second; + } + } + } + } + + float + nearDist = 15.f; + float + dist = pos.y > nearDist ? pos.y * 1.2f : nearDist; + float + farDist = 90.f * (pos.y > nearDist ? pos.y / 15.f : 1.f); + const float + viewDegree = 180.f; + + Vec2f + v(std::sin(degToRad(viewDegree - hAng)), + std::cos(degToRad(viewDegree - hAng))); + Vec2f + v1(std::sin(degToRad(viewDegree - hAng - fov)), + std::cos(degToRad(viewDegree - hAng - fov))); + Vec2f + v2(std::sin(degToRad(viewDegree - hAng + fov)), + std::cos(degToRad(viewDegree - hAng + fov))); + + v.normalize(); + v1.normalize(); + v2.normalize(); + + Vec2f + p = Vec2f(pos.x, pos.z) - v * dist; + Vec2i + p1(static_cast (p.x + v1.x * nearDist), + static_cast (p.y + v1.y * nearDist)); + Vec2i + p2(static_cast (p.x + v1.x * farDist), + static_cast (p.y + v1.y * farDist)); + Vec2i + p3(static_cast (p.x + v2.x * nearDist), + static_cast (p.y + v2.y * nearDist)); + Vec2i + p4(static_cast (p.x + v2.x * farDist), + static_cast (p.y + v2.y * farDist)); + + const bool + debug = false; + + Quad2i + result; + if (hAng >= 135 && hAng <= 225) { + if (debug) + printf("Line %d hAng [%f] fov [%f]\n", __LINE__, hAng, fov); + + result = Quad2i(p1, p2, p3, p4); + if (MaxVisibleQuadItemCache != 0 && + (MaxVisibleQuadItemCache < 0 + || (int) cacheVisibleQuad[fov][hAng].size() <= + MaxVisibleQuadItemCache)) { + cacheVisibleQuad[fov][hAng][pos] = result; + } + } else if (hAng >= 45 && hAng <= 135) { + if (debug) + printf("Line %d hAng [%f] fov [%f]\n", __LINE__, hAng, fov); + + result = Quad2i(p3, p1, p4, p2); + if (MaxVisibleQuadItemCache != 0 && + (MaxVisibleQuadItemCache < 0 + || (int) cacheVisibleQuad[fov][hAng].size() <= + MaxVisibleQuadItemCache)) { + cacheVisibleQuad[fov][hAng][pos] = result; + } + } else if (hAng >= 225 && hAng <= 315) { + if (debug) + printf("Line %d hAng [%f] fov [%f]\n", __LINE__, hAng, fov); + + result = Quad2i(p2, p4, p1, p3); + if (MaxVisibleQuadItemCache != 0 && + (MaxVisibleQuadItemCache < 0 + || (int) cacheVisibleQuad[fov][hAng].size() <= + MaxVisibleQuadItemCache)) { + cacheVisibleQuad[fov][hAng][pos] = result; + } + } else { + if (debug) + printf("Line %d hAng [%f] fov [%f]\n", __LINE__, hAng, fov); + + result = Quad2i(p4, p3, p2, p1); + if (MaxVisibleQuadItemCache != 0 && + (MaxVisibleQuadItemCache < 0 + || (int) cacheVisibleQuad[fov][hAng].size() <= + MaxVisibleQuadItemCache)) { + cacheVisibleQuad[fov][hAng][pos] = Quad2i(p4, p3, p2, p1); + } + } + + return result; + } + + void + GameCamera::setState(State s) { + if (s == sGame) { + state = sGame; + setClampDisabled(false); + resetPosition(); + } else if (s == sUnit) { + state = sUnit; + setClampDisabled(true); + } else if (s == sFree) { + state = sFree; + setClampDisabled(false); + resetPosition(); + } else { + abort(); //"unknown camera state" + } + } + + void + GameCamera::resetPosition() { + destAng.x = startingVAng; + destAng.y = startingHAng; + destPos.y = calculatedDefault; + } + + void + GameCamera::centerXZ(float x, float z) { + destPos.x = pos.x = x; + destPos.z = pos.z = z + centerOffsetZ; + } + + //void GameCamera::transitionXYZ(float x, float y, float z) { + // destPos.x += x; + // destPos.y += y; + // destPos.z += z; + // clampPosXYZ(0.0f, (float)limitX, minHeight, maxHeight, 0.0f, (float)limitY); + //} + + void + GameCamera::transitionVH(float v, float h) { + destAng.x -= v; + //destPos.y -= v * destPos.y / 100.f; + destAng.y -= h; + clampAng(); + } + + void + GameCamera::rotateToVH(float v, float h) { + destAng.x = v; + destAng.y = h; + clampAng(); + } + + void + GameCamera::zoom(float dist) { + float + flatDist = dist * std::cos(degToRad(vAng)); + Vec3f + offset(flatDist * std::sin(degToRad(hAng)), + dist * std::sin(degToRad(vAng)), + flatDist * -std::cos(degToRad(hAng))); + + destPos += offset; + } + + void + GameCamera::load(const XmlNode * node) { + //destPos = node->getChildVec3fValue("pos"); + //destAng = node->getChildVec2fValue("angle"); + } + + void + GameCamera::save(XmlNode * node) const { + //node->addChild("pos", pos); + //node->addChild("angle", Vec2f(vAng, hAng)); + } + + // ==================== PRIVATE ==================== + + void + GameCamera::clampPosXZ(float x1, float x2, float z1, float z2) { + if (clampDisable == true) { + return; + } + + if (pos.x < x1) + pos.x = x1; + if (destPos.x < x1) + destPos.x = x1; + if (pos.z < z1) + pos.z = z1; + if (destPos.z < z1) + destPos.z = z1; + if (pos.x > x2) + pos.x = x2; + if (destPos.x > x2) + destPos.x = x2; + if (pos.z > z2) + pos.z = z2; + if (destPos.z > z2) + destPos.z = z2; + } + + void + GameCamera::clampPosXYZ(float x1, float x2, float y1, float y2, float z1, + float z2) { + if (clampDisable == true) { + return; + } + + if (pos.x < x1) + pos.x = x1; + if (destPos.x < x1) + destPos.x = x1; + if (pos.y < y1) + pos.y = y1; + if (destPos.y < y1) + destPos.y = y1; + if (pos.z < z1) + pos.z = z1; + if (destPos.z < z1) + destPos.z = z1; + if (pos.x > x2) + pos.x = x2; + if (destPos.x > x2) + destPos.x = x2; + if (pos.y > y2) + pos.y = y2; + if (destPos.y > y2) + destPos.y = y2; + if (pos.z > z2) + pos.z = z2; + if (destPos.z > z2) + destPos.z = z2; + } + + void + GameCamera::rotateHV(float h, float v) { + destAng.x = vAng += v; + destAng.y = hAng += h; + clampAng(); + } + + void + GameCamera::clampAng() { + if (clampDisable == true && state != sUnit) { + return; + } + + if (vAng > maxVAng) + vAng = maxVAng; + if (destAng.x > maxVAng) + destAng.x = maxVAng; + if (vAng < minVAng) + vAng = minVAng; + if (destAng.x < minVAng) + destAng.x = minVAng; + if (hAng > 360.f) + hAng -= 360.f; + if (destAng.y > 360.f) + destAng.y -= 360.f; + if (hAng < 0.f) + hAng += 360.f; + if (destAng.y < 0.f) + destAng.y = 360.f; + } + + //move camera forwad but never change heightFactor + void + GameCamera::moveForwardH(float d, float response) { + Vec3f + offset(std::sin(degToRad(hAng)) * d, 0.f, + -std::cos(degToRad(hAng)) * d); + destPos += offset; + pos.x += offset.x * response; + pos.z += offset.z * response; + } + + //move camera to a side but never change heightFactor + void + GameCamera::moveSideH(float d, float response) { + Vec3f + offset(std::sin(degToRad(hAng + 90)) * d, 0.f, + -std::cos(degToRad(hAng + 90)) * d); + destPos += offset; + pos.x += (destPos.x - pos.x) * response; + pos.z += (destPos.z - pos.z) * response; + } + + void + GameCamera::moveUp(float d) { + // pos.y+= d; + destPos.y += d; + } + + void + GameCamera::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode * + gamecameraNode = rootNode->addChild("GameCamera"); + + // Vec3f pos; + gamecameraNode->addAttribute("pos", pos.getString(), + mapTagReplacements); + // Vec3f destPos; + gamecameraNode->addAttribute("destPos", destPos.getString(), + mapTagReplacements); + // + // float hAng; //YZ plane positive -Z axis + gamecameraNode->addAttribute("hAng", floatToStr(hAng, 6), + mapTagReplacements); + // float vAng; //XZ plane positive +Z axis + gamecameraNode->addAttribute("vAng", floatToStr(vAng, 6), + mapTagReplacements); + // float lastHAng; + gamecameraNode->addAttribute("lastHAng", floatToStr(lastHAng, 6), + mapTagReplacements); + + // float lastVAng; + gamecameraNode->addAttribute("lastVAng", floatToStr(lastVAng, 6), + mapTagReplacements); + // Vec2f destAng; + gamecameraNode->addAttribute("destAng", destAng.getString(), + mapTagReplacements); + // float rotate; + gamecameraNode->addAttribute("rotate", floatToStr(rotate, 6), + mapTagReplacements); + // Vec3f move; + gamecameraNode->addAttribute("move", move.getString(), + mapTagReplacements); + // State state; + gamecameraNode->addAttribute("state", intToStr(state), + mapTagReplacements); + // int limitX; + gamecameraNode->addAttribute("limitX", intToStr(limitX), + mapTagReplacements); + // int limitY; + gamecameraNode->addAttribute("limitY", intToStr(limitY), + mapTagReplacements); + // //config + // float speed; + gamecameraNode->addAttribute("speed", floatToStr(speed, 6), + mapTagReplacements); + // bool clampBounds; + gamecameraNode->addAttribute("clampBounds", intToStr(clampBounds), + mapTagReplacements); + // //float maxRenderDistance; + // float maxHeight; + gamecameraNode->addAttribute("maxHeight", floatToStr(maxHeight, 6), + mapTagReplacements); + // float minHeight; + gamecameraNode->addAttribute("minHeight", floatToStr(minHeight, 6), + mapTagReplacements); + // //float maxCameraDist; + // //float minCameraDist; + // float minVAng; + gamecameraNode->addAttribute("minVAng", floatToStr(minVAng, 6), + mapTagReplacements); + // float maxVAng; + gamecameraNode->addAttribute("maxVAng", floatToStr(maxVAng, 6), + mapTagReplacements); + // float fov; + gamecameraNode->addAttribute("fov", floatToStr(fov, 6), + mapTagReplacements); + // float calculatedDefault; + gamecameraNode->addAttribute("calculatedDefault", + floatToStr(calculatedDefault, 6), + mapTagReplacements); + // std::map > > cacheVisibleQuad; + // int MaxVisibleQuadItemCache; + gamecameraNode->addAttribute("MaxVisibleQuadItemCache", + intToStr(MaxVisibleQuadItemCache), + mapTagReplacements); + } + + void + GameCamera::loadGame(const XmlNode * rootNode) { + const XmlNode * + gamecameraNode = rootNode->getChild("GameCamera"); + + //firstTime = timeflowNode->getAttribute("firstTime")->getFloatValue(); + + // Vec3f pos; + pos = + Vec3f::strToVec3(gamecameraNode->getAttribute("pos")->getValue()); + // Vec3f destPos; + destPos = + Vec3f::strToVec3(gamecameraNode->getAttribute("destPos")-> + getValue()); + // + // float hAng; //YZ plane positive -Z axis + hAng = gamecameraNode->getAttribute("hAng")->getFloatValue(); + // float vAng; //XZ plane positive +Z axis + vAng = gamecameraNode->getAttribute("vAng")->getFloatValue(); + // float lastHAng; + lastHAng = gamecameraNode->getAttribute("lastHAng")->getFloatValue(); + + // float lastVAng; + lastVAng = gamecameraNode->getAttribute("lastVAng")->getFloatValue(); + // Vec2f destAng; + destAng = + Vec2f::strToVec2(gamecameraNode->getAttribute("destAng")-> + getValue()); + // float rotate; + rotate = gamecameraNode->getAttribute("rotate")->getFloatValue(); + // Vec3f move; + move = + Vec3f::strToVec3(gamecameraNode->getAttribute("move")->getValue()); + // State state; + state = + static_cast + (gamecameraNode->getAttribute("state")->getIntValue()); + // int limitX; + limitX = gamecameraNode->getAttribute("limitX")->getIntValue(); + // int limitY; + limitY = gamecameraNode->getAttribute("limitY")->getIntValue(); + // //config + // float speed; + speed = gamecameraNode->getAttribute("speed")->getFloatValue(); + // bool clampBounds; + clampBounds = + gamecameraNode->getAttribute("clampBounds")->getIntValue() != 0; + // //float maxRenderDistance; + // float maxHeight; + maxHeight = + gamecameraNode->getAttribute("maxHeight")->getFloatValue(); + // float minHeight; + minHeight = + gamecameraNode->getAttribute("minHeight")->getFloatValue(); + // //float maxCameraDist; + // //float minCameraDist; + // float minVAng; + minVAng = gamecameraNode->getAttribute("minVAng")->getFloatValue(); + // float maxVAng; + maxVAng = gamecameraNode->getAttribute("maxVAng")->getFloatValue(); + // float fov; + fov = gamecameraNode->getAttribute("fov")->getFloatValue(); + // float calculatedDefault; + calculatedDefault = + gamecameraNode->getAttribute("calculatedDefault")->getFloatValue(); + // std::map > > cacheVisibleQuad; + // int MaxVisibleQuadItemCache; + MaxVisibleQuadItemCache = + gamecameraNode->getAttribute("MaxVisibleQuadItemCache")-> + getIntValue(); + + } + + } +} //end namespace diff --git a/source/glest_game/game/game_camera.h b/source/glest_game/game/game_camera.h index bccd96e9c..9607bfcdd 100644 --- a/source/glest_game/game/game_camera.h +++ b/source/glest_game/game/game_camera.h @@ -23,242 +23,216 @@ # include # include "leak_dumper.h" -namespace Shared -{ - namespace Xml - { - class XmlNode; -}} +namespace Shared { + namespace Xml { + class XmlNode; + } +} -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - using::Shared::Graphics::Quad2i; - using::Shared::Graphics::Vec3f; - using::Shared::Graphics::Vec2f; - using::Shared::Xml::XmlNode; + using::Shared::Graphics::Quad2i; + using::Shared::Graphics::Vec3f; + using::Shared::Graphics::Vec2f; + using::Shared::Xml::XmlNode; - class Config; + class Config; -// ===================================================== -// class GameCamera -// -/// A basic camera that holds information about the game view -// ===================================================== + // ===================================================== + // class GameCamera + // + /// A basic camera that holds information about the game view + // ===================================================== - class GameCamera - { - public: - static const float startingVAng; - static const float startingHAng; - static const float vTransitionMult; - static const float hTransitionMult; - static const float defaultHeight; - static const float centerOffsetZ; - static const float shakeDist; + class GameCamera { + public: + static const float startingVAng; + static const float startingHAng; + static const float vTransitionMult; + static const float hTransitionMult; + static const float defaultHeight; + static const float centerOffsetZ; + static const float shakeDist; - public: - enum State - { - sGame, - sFree, - sUnit - }; + public: + enum State { + sGame, + sFree, + sUnit + }; - private: - Vec3f pos; - Vec3f destPos; - Vec2f shakeOffset; + private: + Vec3f pos; + Vec3f destPos; + Vec2f shakeOffset; - float hAng; //YZ plane positive -Z axis - float vAng; //XZ plane positive +Z axis - float lastHAng; - float lastVAng; - Vec2f destAng; + float hAng; //YZ plane positive -Z axis + float vAng; //XZ plane positive +Z axis + float lastHAng; + float lastVAng; + Vec2f destAng; - float rotate; + float rotate; - Vec3f move; + Vec3f move; - float shakeDecrement; - float currentShakeIntensity; - State state; + float shakeDecrement; + float currentShakeIntensity; + State state; - int limitX; - int limitY; + int limitX; + int limitY; - //config - float speed; - bool clampBounds; - bool clampDisable; - //float maxRenderDistance; - float maxHeight; - float minHeight; - //float maxCameraDist; - //float minCameraDist; - float minVAng; - float maxVAng; - float fov; + //config + float speed; + bool clampBounds; + bool clampDisable; + //float maxRenderDistance; + float maxHeight; + float minHeight; + //float maxCameraDist; + //float minCameraDist; + float minVAng; + float maxVAng; + float fov; - float calculatedDefault; + float calculatedDefault; - std::map < float, std::map < float, std::map < Vec3f, - Quad2i > > >cacheVisibleQuad; - int MaxVisibleQuadItemCache; + std::map < float, std::map < float, std::map < Vec3f, + Quad2i > > >cacheVisibleQuad; + int MaxVisibleQuadItemCache; - public: - GameCamera (); - ~GameCamera (); + public: + GameCamera(); + ~GameCamera(); - void init (int limitX, int limitY); + void init(int limitX, int limitY); - //get - float getHAng () const - { - return hAng; - }; - float getVAng () const - { - return vAng; - } - State getState () const - { - return state; - } - void setState (State s); - void resetCamera () - { - setState (sGame); - } + //get + float getHAng() const { + return hAng; + }; + float getVAng() const { + return vAng; + } + State getState() const { + return state; + } + void setState(State s); + void resetCamera() { + setState(sGame); + } - const Vec3f & getPos () const - { - return pos; - } - float getFov () const - { - return fov; - } - //set - void setRotate (float rotate) - { - this->rotate = rotate; - } - void setPos (Vec2f pos); - void setPos (Vec3f pos); + const Vec3f & getPos() const { + return pos; + } + float getFov() const { + return fov; + } + //set + void setRotate(float rotate) { + this->rotate = rotate; + } + void setPos(Vec2f pos); + void setPos(Vec3f pos); - const Vec2f & getShakeOffset () const - { - return shakeOffset; - } - void shake (int shakeDuration, int shakeStartIntensity, - bool cameraDistanceAffected, Vec3f unitVector); + const Vec2f & getShakeOffset() const { + return shakeOffset; + } + void shake(int shakeDuration, int shakeStartIntensity, + bool cameraDistanceAffected, Vec3f unitVector); - void setMoveX (float f) - { - this->move.x = f; - } - void setMoveY (float f) - { - this->move.y = f; - } - void setMoveZ (float f) - { - this->move.z = f; - } + void setMoveX(float f) { + this->move.x = f; + } + void setMoveY(float f) { + this->move.y = f; + } + void setMoveZ(float f) { + this->move.z = f; + } - inline bool isMoving () const - { - return (this->move.x != 0.0 || this->move.y != 0.0 - || this->move.z != 0.0); - } - inline void stopMove () - { - this->move.x = 0.0; - this->move.y = 0.0; - this->move.z = 0.0; - } + inline bool isMoving() const { + return (this->move.x != 0.0 || this->move.y != 0.0 + || this->move.z != 0.0); + } + inline void stopMove() { + this->move.x = 0.0; + this->move.y = 0.0; + this->move.z = 0.0; + } - void stop () - { - destPos = pos; - destAng.x = vAng; - destAng.y = hAng; - } + void stop() { + destPos = pos; + destAng.x = vAng; + destAng.y = hAng; + } - std::string getCameraMovementKey ()const; + std::string getCameraMovementKey()const; - //other - void update (); - Quad2i computeVisibleQuad (); + //other + void update(); + Quad2i computeVisibleQuad(); - void centerXZ (float x, float z); - //void transitionXYZ(float x, float y, float z); - void transitionVH (float v, float h); - void rotateToVH (float v, float h); + void centerXZ(float x, float z); + //void transitionXYZ(float x, float y, float z); + void transitionVH(float v, float h); + void rotateToVH(float v, float h); - void zoom (float dist); - void moveForwardH (float dist, float response); // response: 1.0 for immediate, 0 for full inertia - void moveSideH (float dist, float response); + void zoom(float dist); + void moveForwardH(float dist, float response); // response: 1.0 for immediate, 0 for full inertia + void moveSideH(float dist, float response); - void load (const XmlNode * node); - void save (XmlNode * node) const; + void load(const XmlNode * node); + void save(XmlNode * node) const; - void setMaxHeight (float value); - float getCalculatedDefault () const - { - return calculatedDefault; - } - void setCalculatedDefault (float calculatedDefault); + void setMaxHeight(float value); + float getCalculatedDefault() const { + return calculatedDefault; + } + void setCalculatedDefault(float calculatedDefault); - float getMaxHeight () const - { - return maxHeight; - } - void setFov (float value) - { - fov = value; - } - void setMinVAng (float value) - { - minVAng = value; - } - void setMaxVAng (float value) - { - maxVAng = value; - } + float getMaxHeight() const { + return maxHeight; + } + void setFov(float value) { + fov = value; + } + void setMinVAng(float value) { + minVAng = value; + } + void setMaxVAng(float value) { + maxVAng = value; + } - void setHAng (float value) - { - hAng = value; - }; - void setVAng (float value) - { - vAng = value; - } + void setHAng(float value) { + hAng = value; + }; + void setVAng(float value) { + vAng = value; + } - void saveGame (XmlNode * rootNode); - void loadGame (const XmlNode * rootNode); + void saveGame(XmlNode * rootNode); + void loadGame(const XmlNode * rootNode); - private: - //void setClampBounds(bool value) { clampBounds = value; } - void resetPosition (); - void setClampDisabled (bool value) - { - clampDisable = value; - }; - void clampPosXYZ (float x1, float x2, float y1, float y2, float z1, - float z2); - void clampPosXZ (float x1, float x2, float z1, float z2); - void clampAng (); - void moveUp (float dist); - void rotateHV (float h, float v); - void shakeCamera (); - }; + private: + //void setClampBounds(bool value) { clampBounds = value; } + void resetPosition(); + void setClampDisabled(bool value) { + clampDisable = value; + }; + void clampPosXYZ(float x1, float x2, float y1, float y2, float z1, + float z2); + void clampPosXZ(float x1, float x2, float z1, float z2); + void clampAng(); + void moveUp(float dist); + void rotateHV(float h, float v); + void shakeCamera(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/game/game_constants.h b/source/glest_game/game/game_constants.h index 37c4ac51a..d2d8dbcb2 100644 --- a/source/glest_game/game/game_constants.h +++ b/source/glest_game/game/game_constants.h @@ -33,353 +33,328 @@ # include using namespace - Shared::Graphics; +Shared::Graphics; using namespace - std; +std; using namespace - Shared::Util; +Shared::Util; namespace - Glest -{ - namespace - Game - { + Glest { + namespace + Game { - template < - typename - T > - class - EnumParser - { - private: - typedef - map < - string, - T > - enumMapType; - typedef typename - enumMapType::const_iterator - enumMapTypeIter; - EnumParser (); + template < + typename + T > + class + EnumParser { + private: + typedef + map < + string, + T > + enumMapType; + typedef typename + enumMapType::const_iterator + enumMapTypeIter; + EnumParser(); - enumMapType - enumMap; + enumMapType + enumMap; - public: + public: - static T - getEnum (const string & value) - { - static - EnumParser < - T > - parser; - enumMapTypeIter - iValue = parser.enumMap.find (value); - if (iValue == parser.enumMap.end ()) - { - throw - std::runtime_error ("unknown enum lookup [" + value + "]"); - } - return - iValue-> - second; - } - static string - getString (const T & value) - { - static - EnumParser < - T > - parser; - for (enumMapTypeIter iValue = parser.enumMap.begin (); - iValue != parser.enumMap.end (); ++iValue) - { - if (iValue->second == value) - { - return iValue->first; - } - } - throw - std::runtime_error ("unknown enum lookup [" + intToStr (value) + "]"); - } - static int - getCount () - { - static - EnumParser < - T > - parser; - return parser.enumMap.size (); - } - }; + static T + getEnum(const string & value) { + static + EnumParser < + T > + parser; + enumMapTypeIter + iValue = parser.enumMap.find(value); + if (iValue == parser.enumMap.end()) { + throw + std::runtime_error("unknown enum lookup [" + value + "]"); + } + return + iValue-> + second; + } + static string + getString(const T & value) { + static + EnumParser < + T > + parser; + for (enumMapTypeIter iValue = parser.enumMap.begin(); + iValue != parser.enumMap.end(); ++iValue) { + if (iValue->second == value) { + return iValue->first; + } + } + throw + std::runtime_error("unknown enum lookup [" + intToStr(value) + "]"); + } + static int + getCount() { + static + EnumParser < + T > + parser; + return parser.enumMap.size(); + } + }; -// ===================================================== -// class GameConstants -// ===================================================== + // ===================================================== + // class GameConstants + // ===================================================== - const Vec4f - BLACK (0.0f, 0.0f, 0.0f, 1.0f); - const Vec4f - RED (1.0f, 0.0f, 0.0f, 1.0f); - const Vec4f - GREEN (0.0f, 1.0f, 0.0f, 1.0f); - const Vec4f - BLUE (0.0f, 0.0f, 1.0f, 1.0f); - const Vec4f - GLASS (1.0f, 1.0f, 1.0f, 0.3f); - const Vec4f - CYAN (0.0f, 1.0f, 1.0f, 1.0f); - const Vec4f - YELLOW (1.0f, 1.0f, 0.0f, 1.0f); - const Vec4f - MAGENTA (1.0f, 0.0f, 1.0f, 1.0f); - const Vec4f - WHITE (1.0f, 1.0f, 1.0f, 1.0f); - const Vec4f - ORANGE (1.0f, 0.7f, 0.0f, 1.0f); + const Vec4f + BLACK(0.0f, 0.0f, 0.0f, 1.0f); + const Vec4f + RED(1.0f, 0.0f, 0.0f, 1.0f); + const Vec4f + GREEN(0.0f, 1.0f, 0.0f, 1.0f); + const Vec4f + BLUE(0.0f, 0.0f, 1.0f, 1.0f); + const Vec4f + GLASS(1.0f, 1.0f, 1.0f, 0.3f); + const Vec4f + CYAN(0.0f, 1.0f, 1.0f, 1.0f); + const Vec4f + YELLOW(1.0f, 1.0f, 0.0f, 1.0f); + const Vec4f + MAGENTA(1.0f, 0.0f, 1.0f, 1.0f); + const Vec4f + WHITE(1.0f, 1.0f, 1.0f, 1.0f); + const Vec4f + ORANGE(1.0f, 0.7f, 0.0f, 1.0f); - enum PathFinderType - { - pfBasic - }; + enum PathFinderType { + pfBasic + }; - enum TravelState - { - tsArrived, - tsMoving, - tsBlocked, - tsImpossible - }; + enum TravelState { + tsArrived, + tsMoving, + tsBlocked, + tsImpossible + }; - enum ControlType - { - ctClosed, - ctCpuEasy, - ctCpu, - ctCpuUltra, - ctCpuZeta, - ctNetwork, - ctNetworkUnassigned, - ctHuman, + enum ControlType { + ctClosed, + ctCpuEasy, + ctCpu, + ctCpuUltra, + ctCpuZeta, + ctNetwork, + ctNetworkUnassigned, + ctHuman, - ctNetworkCpuEasy, - ctNetworkCpu, - ctNetworkCpuUltra, - ctNetworkCpuZeta - }; + ctNetworkCpuEasy, + ctNetworkCpu, + ctNetworkCpuUltra, + ctNetworkCpuZeta + }; - enum NetworkRole - { - nrServer, - nrClient, - nrIdle - }; + enum NetworkRole { + nrServer, + nrClient, + nrIdle + }; - enum FactionPersonalityType - { - fpt_Normal, - fpt_Observer, + enum FactionPersonalityType { + fpt_Normal, + fpt_Observer, - fpt_EndCount - }; + fpt_EndCount + }; - enum MasterServerGameStatusType - { - game_status_waiting_for_players = 0, - game_status_waiting_for_start = 1, - game_status_in_progress = 2, - game_status_finished = 3 - }; + enum MasterServerGameStatusType { + game_status_waiting_for_players = 0, + game_status_waiting_for_start = 1, + game_status_in_progress = 2, + game_status_finished = 3 + }; - class - GameConstants - { - public: - static const int - specialFactions = fpt_EndCount - 1; - static const int - maxPlayers = 10; - static const int - serverPort = 61357; - static const int - serverAdminPort = 61355; - static int - updateFps; - static int - cameraFps; + class + GameConstants { + public: + static const int + specialFactions = fpt_EndCount - 1; + static const int + maxPlayers = 10; + static const int + serverPort = 61357; + static const int + serverAdminPort = 61355; + static int + updateFps; + static int + cameraFps; - static int - networkFramePeriod; - static const int - networkPingInterval = 5; - static const int - networkSmoothInterval = 30; - static const int - maxClientConnectHandshakeSecs = 10; + static int + networkFramePeriod; + static const int + networkPingInterval = 5; + static const int + networkSmoothInterval = 30; + static const int + maxClientConnectHandshakeSecs = 10; - static const int - cellScale = 2; - static const int - clusterSize = 16; + static const int + cellScale = 2; + static const int + clusterSize = 16; - static const char * - folder_path_maps; - static const char * - folder_path_scenarios; - static const char * - folder_path_techs; - static const char * - folder_path_tilesets; - static const char * - folder_path_tutorials; + static const char * + folder_path_maps; + static const char * + folder_path_scenarios; + static const char * + folder_path_techs; + static const char * + folder_path_tilesets; + static const char * + folder_path_tutorials; - static const char * - NETWORK_SLOT_UNCONNECTED_SLOTNAME; - static const char * - NETWORK_SLOT_CLOSED_SLOTNAME; + static const char * + NETWORK_SLOT_UNCONNECTED_SLOTNAME; + static const char * + NETWORK_SLOT_CLOSED_SLOTNAME; - static const char * - folder_path_screenshots; + static const char * + folder_path_screenshots; - static const char * - OBSERVER_SLOTNAME; - static const char * - RANDOMFACTION_SLOTNAME; + static const char * + OBSERVER_SLOTNAME; + static const char * + RANDOMFACTION_SLOTNAME; - static const char * - steamCacheInstanceKey; - static const char * - preCacheThreadCacheLookupKey; - static const char * - playerTextureCacheLookupKey; - static const char * - ircClientCacheLookupKey; - static const char * - factionPreviewTextureCacheLookupKey; - static const char * - characterMenuScreenPositionListCacheLookupKey; - static const char * - pathCacheLookupKey; - static const char * - path_data_CacheLookupKey; - static const char * - path_ini_CacheLookupKey; - static const char * - path_logs_CacheLookupKey; + static const char * + steamCacheInstanceKey; + static const char * + preCacheThreadCacheLookupKey; + static const char * + playerTextureCacheLookupKey; + static const char * + ircClientCacheLookupKey; + static const char * + factionPreviewTextureCacheLookupKey; + static const char * + characterMenuScreenPositionListCacheLookupKey; + static const char * + pathCacheLookupKey; + static const char * + path_data_CacheLookupKey; + static const char * + path_ini_CacheLookupKey; + static const char * + path_logs_CacheLookupKey; - static const char * - application_name; + static const char * + application_name; - static const char * - saveNetworkGameFileServerCompressed; - static const char * - saveNetworkGameFileServer; - static const char * - saveNetworkGameFileClientCompressed; - static const char * - saveNetworkGameFileClient; - static const char * - saveGameFileDefault; - static const char * - saveGameFileAutoTestDefault; - static const char * - saveGameFilePattern; + static const char * + saveNetworkGameFileServerCompressed; + static const char * + saveNetworkGameFileServer; + static const char * + saveNetworkGameFileClientCompressed; + static const char * + saveNetworkGameFileClient; + static const char * + saveGameFileDefault; + static const char * + saveGameFileAutoTestDefault; + static const char * + saveGameFilePattern; - // VC++ Chokes on init of non integral static types - static const float - normalMultiplier; - static const float - easyMultiplier; - static const float - ultraMultiplier; - static const float - megaMultiplier; - // + // VC++ Chokes on init of non integral static types + static const float + normalMultiplier; + static const float + easyMultiplier; + static const float + ultraMultiplier; + static const float + megaMultiplier; + // - static const char * - LOADING_SCREEN_FILE; - static const char * - LOADING_SCREEN_FILE_FILTER; - static const char * - PREVIEW_SCREEN_FILE; - static const char * - PREVIEW_SCREEN_FILE_FILTER; - static const char * - HUD_SCREEN_FILE; - static const char * - HUD_SCREEN_FILE_FILTER; - }; + static const char * + LOADING_SCREEN_FILE; + static const char * + LOADING_SCREEN_FILE_FILTER; + static const char * + PREVIEW_SCREEN_FILE; + static const char * + PREVIEW_SCREEN_FILE_FILTER; + static const char * + HUD_SCREEN_FILE; + static const char * + HUD_SCREEN_FILE_FILTER; + }; - enum PathType - { - ptMaps, - ptScenarios, - ptTechs, - ptTilesets, - ptTutorials - }; + enum PathType { + ptMaps, + ptScenarios, + ptTechs, + ptTilesets, + ptTutorials + }; - struct CardinalDir - { - public: - enum Enum - { - NORTH, - EAST, - SOUTH, - WEST, - COUNT }; + struct CardinalDir { + public: + enum Enum { + NORTH, + EAST, + SOUTH, + WEST, + COUNT + }; - CardinalDir (): - value (NORTH) - { - } - explicit - CardinalDir (Enum v): - value (v) - { - } - explicit - CardinalDir (int v) - { - assertDirValid (v); - value = static_cast < Enum > (v); - } - operator - Enum () const - { - return - value; - } - int - asInt () const - { - return (int) - value; - } + CardinalDir() : + value(NORTH) { + } + explicit + CardinalDir(Enum v) : + value(v) { + } + explicit + CardinalDir(int v) { + assertDirValid(v); + value = static_cast (v); + } + operator + Enum () const { + return + value; + } + int + asInt() const { + return (int) + value; + } - static void - assertDirValid (int v) - { - assert (v >= 0 && v < 4); - } - void - operator++ () - { - value = static_cast < Enum > ((value + 1) % 4); - } - void - operator-- () - { // mod with negative numbers is a 'grey area', hence the +3 rather than -1 - value = static_cast < Enum > ((value + 3) % 4); - } + static void + assertDirValid(int v) { + assert(v >= 0 && v < 4); + } + void + operator++ () { + value = static_cast ((value + 1) % 4); + } + void + operator-- () { // mod with negative numbers is a 'grey area', hence the +3 rather than -1 + value = static_cast ((value + 3) % 4); + } - private: - Enum value; - }; + private: + Enum value; + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/game/game_settings.h b/source/glest_game/game/game_settings.h index 891d7cf49..be1d61510 100644 --- a/source/glest_game/game/game_settings.h +++ b/source/glest_game/game/game_settings.h @@ -23,1741 +23,1569 @@ # include "leak_dumper.h" using namespace - Shared::Util; +Shared::Util; using namespace - Shared::PlatformCommon; +Shared::PlatformCommon; using namespace - Shared::Platform; +Shared::Platform; using - Shared::Xml::XmlNode; +Shared::Xml::XmlNode; namespace - Glest -{ - namespace - Game - { - - enum ModType - { - mt_None, - mt_Map, - mt_Tileset, - mt_Techtree, - mt_Scenario - }; - -// =============================== -// class ModInfo -// =============================== - - class - ModInfo - { - public: - string - name; - string - url; - string - imageUrl; - string - description; - string - count; // used for faction count for example - string - crc; - string - localCRC; - ModType - type; - public: - ModInfo (); - }; - -// ===================================================== -// class GameSettings -// ===================================================== - - enum FlagTypes1 - { - ft1_none = 0x00, - ft1_show_map_resources = 0x01, - ft1_allow_team_switching = 0x02, - ft1_allow_in_game_joining = 0x04, - ft1_network_synch_checks_verbose = 0x08, - ft1_network_synch_checks = 0x10, - ft1_allow_shared_team_units = 0x20, - ft1_allow_shared_team_resources = 0x40 - //ft1_xxx = 0x80 - }; - - inline static bool - isFlagType1BitEnabled (uint32 flagValue, FlagTypes1 type) - { - return ((flagValue & (uint32) type) == (uint32) type); - } - - enum NetworkPlayerStatusType - { - npst_None = 0, - npst_PickSettings = 1, - npst_BeRightBack = 2, - npst_Ready = 3, - npst_Disconnected = 4 - }; - - class - GameSettings - { - private: - string - gameName; - string - description; - string - map; - string - tileset; - string - tech; - string - scenario; - string - scenarioDir; - string - factionTypeNames[GameConstants::maxPlayers]; //faction names - string - networkPlayerNames[GameConstants::maxPlayers]; - string - networkPlayerPlatform[GameConstants::maxPlayers]; - int - networkPlayerStatuses[GameConstants::maxPlayers]; - string - networkPlayerLanguages[GameConstants::maxPlayers]; - int - networkPlayerGameStatus[GameConstants::maxPlayers]; - - ControlType - factionControls[GameConstants::maxPlayers]; - int - resourceMultiplierIndex[GameConstants::maxPlayers]; - string - networkPlayerUUID[GameConstants::maxPlayers]; - - - int - thisFactionIndex; - int - factionCount; - int - teams[GameConstants::maxPlayers]; - int - startLocationIndex[GameConstants::maxPlayers]; - int - mapFilter; - - int - fallbackCpuMultiplier; - bool - defaultUnits; - bool - defaultResources; - bool - defaultVictoryConditions; - - bool - fogOfWar; - bool - allowObservers; - bool - enableObserverModeAtEndGame; - bool - enableServerControlledAI; - int - networkFramePeriod; - bool - networkPauseGameForLaggedClients; - PathFinderType - pathFinderType; - - uint32 - flagTypes1; - - uint32 - mapCRC; - uint32 - tilesetCRC; - uint32 - techCRC; - vector < - pair < - string, - uint32 > > - factionCRCList; - - int - aiAcceptSwitchTeamPercentChance; - int - masterserver_admin; - - int - masterserver_admin_factionIndex; - - bool - networkAllowNativeLanguageTechtree; - - string - gameUUID; - - public: - - static string - playerDisconnectedText; - - GameSettings () - { - defaultUnits = false; - defaultResources = false; - defaultVictoryConditions = false; - mapFilter = 0; - factionCount = 0; - thisFactionIndex = 0; - fogOfWar = true; - allowObservers = false; - enableObserverModeAtEndGame = false; - enableServerControlledAI = false; - networkFramePeriod = GameConstants::networkFramePeriod; - networkPauseGameForLaggedClients = false; - pathFinderType = pfBasic; - - static const string - DEFAULT_LANG = "english"; - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - factionTypeNames[i] = ""; - networkPlayerNames[i] = ""; - networkPlayerPlatform[i] = ""; - networkPlayerStatuses[i] = npst_None; - networkPlayerLanguages[i] = DEFAULT_LANG; - factionControls[i] = ctClosed; - resourceMultiplierIndex[i] = 1.0f; - teams[i] = 0; - startLocationIndex[i] = i; - networkPlayerGameStatus[i] = 0; - - networkPlayerUUID[i] = ""; - } - - flagTypes1 = ft1_none; - - mapCRC = 0; - tilesetCRC = 0; - techCRC = 0; - factionCRCList. - clear (); - aiAcceptSwitchTeamPercentChance = 30; - masterserver_admin = -1; - masterserver_admin_factionIndex = -1; - fallbackCpuMultiplier = 1.0f; - networkAllowNativeLanguageTechtree = true; - } - - // default copy constructor will do fine, and will maintain itself ;) - - //get - const - string & - getGameName () const - { - return - gameName; - } - const - string & - getDescription () const - { - return - description; - } - const - string & - getMap () const - { - return - map; - } - const - string & - getTileset () const - { - return - tileset; - } - const - string & - getTech () const - { - return - tech; - } - const - string & - getScenario () const - { - return - scenario; - } - const - string & - getScenarioDir () const - { - return - scenarioDir; - } - const - string & - getFactionTypeName (int factionIndex) const - { - if (factionIndex == -1) - { - static string - HEADLESS_FACTION = "headless-server"; - return - HEADLESS_FACTION; - } - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - return factionTypeNames[factionIndex]; - } - string - getNetworkPlayerName (int factionIndex) const - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - string - result = networkPlayerNames[factionIndex]; - if (networkPlayerStatuses[factionIndex] == npst_Disconnected) - { - result = playerDisconnectedText + result; - } - return result; - } - string - getNetworkPlayerPlatform (int factionIndex) const - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - string - result = networkPlayerPlatform[factionIndex]; - return result; - } - - const int - getNetworkPlayerStatuses (int factionIndex) const - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - return - networkPlayerStatuses[factionIndex]; - } - const string - getNetworkPlayerLanguages (int factionIndex) const - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - return - networkPlayerLanguages[factionIndex]; - } - - const int - getNetworkPlayerGameStatus (int factionIndex) const - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - return - networkPlayerGameStatus[factionIndex]; - } - - const - vector < - string > - getUniqueNetworkPlayerLanguages () const - { - vector < - string > - languageList; - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - if (networkPlayerLanguages[i] != "") - { - if (std:: - find (languageList.begin (), languageList.end (), - networkPlayerLanguages[i]) == languageList.end ()) - { - languageList.push_back (networkPlayerLanguages[i]); - } - } - } - if (languageList.empty () == true) - { - languageList.push_back (""); - } - return languageList; - } - - const string - getNetworkPlayerNameByPlayerIndex (int playerIndex) const - { - string - result = ""; - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - if (startLocationIndex[i] == playerIndex) - { - result = networkPlayerNames[i]; - break; - } - } - return - result; - } - const string - getNetworkPlayerPlatformByPlayerIndex (int playerIndex) const - { - string - result = ""; - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - if (startLocationIndex[i] == playerIndex) - { - result = networkPlayerPlatform[i]; - break; - } - } - return - result; - } - - ControlType - getFactionControl (int factionIndex) const - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - return - factionControls[factionIndex]; - } - int - getResourceMultiplierIndex (int factionIndex) const - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - return - resourceMultiplierIndex[factionIndex]; - } - - const - string & - getNetworkPlayerUUID (int factionIndex) const - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - return - networkPlayerUUID[factionIndex]; - } - - bool - isNetworkGame () const - { - bool - result = false; - for (int idx = 0; idx < GameConstants::maxPlayers; ++idx) - { - if (factionControls[idx] == ctNetwork - || factionControls[idx] == ctNetworkUnassigned - || networkPlayerStatuses[idx] == npst_Disconnected) - { - result = true; - break; - } - } - return - result; - } - int - getThisFactionIndex () const - { - return - thisFactionIndex; - } - int - getFactionCount () const - { - return - factionCount; - } - int - getTeam (int factionIndex) const - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - return - teams[factionIndex]; - } - - int - getStartLocationIndex (int factionIndex) const - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - return - startLocationIndex[factionIndex]; - } - int - getFactionIndexForStartLocation (int startIndex) const - { - if (startIndex < 0 || startIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid startIndex = %d\n", - __FUNCTION__, startIndex); - throw - megaglest_runtime_error (szBuf); - } - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - if (startLocationIndex[i] == startIndex) - { - return i; - } - } - return -1; - } - - int - getMapFilter () const - { - return - mapFilter; - } - - bool - getDefaultUnits () const - { - return - defaultUnits; - } - bool - getDefaultResources () const - { - return - defaultResources; - } - bool - getDefaultVictoryConditions () const - { - return - defaultVictoryConditions; - } - - bool - getFogOfWar () const - { - return - fogOfWar; - } - bool - getAllowObservers () const - { - return - allowObservers; - } - bool - getEnableObserverModeAtEndGame () const - { - return - enableObserverModeAtEndGame; - } - bool - getEnableServerControlledAI () const - { - return - enableServerControlledAI; - } - int - getNetworkFramePeriod () const - { - return - networkFramePeriod; - } - bool - getNetworkPauseGameForLaggedClients () const - { - return - networkPauseGameForLaggedClients; - } - PathFinderType - getPathFinderType () const - { - return - pathFinderType; - } - uint32 - getFlagTypes1 () const - { - return - flagTypes1; - } - - uint32 - getMapCRC () const - { - return - mapCRC; - } - uint32 - getTilesetCRC () const - { - return - tilesetCRC; - } - uint32 - getTechCRC () const - { - return - techCRC; - } - vector < - pair < - string, - uint32 > > - getFactionCRCList () const - { - return - factionCRCList; - } - - const - string & - getGameUUID () const - { - return - gameUUID; - } - - //set - void - setGameName (const string & gameName) - { - this->gameName = gameName; - } - void - setDescription (const string & description) - { - this->description = description; - } - void - setMap (const string & map) - { - this->map = map; - } - void - setTileset (const string & tileset) - { - this->tileset = tileset; - } - void - setTech (const string & tech) - { - this->tech = tech; - } - void - setScenario (const string & scenario) - { - this->scenario = scenario; - } - void - setScenarioDir (const string & scenarioDir) - { - this->scenarioDir = scenarioDir; - } - - void - setFactionTypeName (int factionIndex, const string & factionTypeName) - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - this->factionTypeNames[factionIndex] = factionTypeName; - } - void - setNetworkPlayerName (int factionIndex, const string & playername) - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - this->networkPlayerNames[factionIndex] = playername; - } - void - setNetworkPlayerPlatform (int factionIndex, const string & platform) - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - this->networkPlayerPlatform[factionIndex] = platform; - } - - void - setNetworkPlayerStatuses (int factionIndex, int status) - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - this->networkPlayerStatuses[factionIndex] = status; - } - - void - setNetworkPlayerGameStatus (int factionIndex, int status) - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - this->networkPlayerGameStatus[factionIndex] = status; - } - void - setNetworkPlayerLanguages (int factionIndex, const string & language) - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - this->networkPlayerLanguages[factionIndex] = language; - } - - void - setFactionControl (int factionIndex, ControlType controller) - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - this->factionControls[factionIndex] = controller; - } - void - setResourceMultiplierIndex (int factionIndex, int multiplierIndex) - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - //if(multiplierIndex >= 45) { - // printf("gamesettings Line: %d multiplier index: %d factionIndex: %d\n",__LINE__,multiplierIndex,factionIndex); - //} - - this->resourceMultiplierIndex[factionIndex] = multiplierIndex; - } - - void - setNetworkPlayerUUID (int factionIndex, const string & uuid) - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - this->networkPlayerUUID[factionIndex] = uuid; - } - - void - setThisFactionIndex (int thisFactionIndex) - { - this->thisFactionIndex = thisFactionIndex; - } - void - setFactionCount (int factionCount) - { - this->factionCount = factionCount; - } - void - setTeam (int factionIndex, int team) - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - this->teams[factionIndex] = team; - } - void - setStartLocationIndex (int factionIndex, int startLocationIndex) - { - if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", - __FUNCTION__, factionIndex); - throw - megaglest_runtime_error (szBuf); - } - - this->startLocationIndex[factionIndex] = startLocationIndex; - } - void - setMapFilter (int mapFilter) - { - this->mapFilter = mapFilter; - } - - void - setDefaultUnits (bool defaultUnits) - { - this->defaultUnits = defaultUnits; - } - void - setDefaultResources (bool defaultResources) - { - this->defaultResources = defaultResources; - } - void - setDefaultVictoryConditions (bool defaultVictoryConditions) - { - this->defaultVictoryConditions = defaultVictoryConditions; - } - - void - setFogOfWar (bool fogOfWar) - { - this->fogOfWar = fogOfWar; - } - void - setAllowObservers (bool value) - { - this->allowObservers = value; - } - void - setEnableObserverModeAtEndGame (bool value) - { - this->enableObserverModeAtEndGame = value; - } - void - setEnableServerControlledAI (bool value) - { - this->enableServerControlledAI = value; - } - void - setNetworkFramePeriod (int value) - { - this->networkFramePeriod = value; - } - void - setNetworkPauseGameForLaggedClients (bool value) - { - this->networkPauseGameForLaggedClients = value; - } - void - setPathFinderType (PathFinderType value) - { - this->pathFinderType = value; - } - - void - setFlagTypes1 (uint32 value) - { - this->flagTypes1 = value; - } - - void - setMapCRC (uint32 value) - { - mapCRC = value; - } - void - setTilesetCRC (uint32 value) - { - tilesetCRC = value; - } - void - setTechCRC (uint32 value) - { - techCRC = value; - } - - void - setFactionCRCList (const vector < pair < string, uint32 > >&value) - { - factionCRCList = value; - } - - int - getAiAcceptSwitchTeamPercentChance () const - { - return - aiAcceptSwitchTeamPercentChance; - } - void - setAiAcceptSwitchTeamPercentChance (int value) - { - aiAcceptSwitchTeamPercentChance = value; - } - - int - getFallbackCpuMultiplier () const - { - return - fallbackCpuMultiplier; - } - void - setFallbackCpuMultiplier (int value) - { - fallbackCpuMultiplier = value; - } - - int - getMasterserver_admin () const - { - return - masterserver_admin; - } - void - setMasterserver_admin (int value) - { - masterserver_admin = value; - } - - int - getMasterserver_admin_faction_index () const - { - return - masterserver_admin_factionIndex; - } - void - setMasterserver_admin_faction_index (int value) - { - masterserver_admin_factionIndex = value; - } - - bool - getNetworkAllowNativeLanguageTechtree () const - { - return - networkAllowNativeLanguageTechtree; - } - void - setNetworkAllowNativeLanguageTechtree (bool value) - { - networkAllowNativeLanguageTechtree = value; - } - - void - setGameUUID (const string & gameUUID) - { - this->gameUUID = gameUUID; - } - - string - toString () const - { - string - result = ""; - - result += - "Game ID = " + - gameUUID + - "\n"; - result += - "gameName = " + - gameName + - "\n"; - result += - "description = " + - description + - "\n"; - result += - "mapFilterIndex = " + - intToStr (mapFilter) + - "\n"; - result += - "map = " + - map + - "\n"; - result += - "tileset = " + - tileset + - "\n"; - result += - "tech = " + - tech + - "\n"; - result += - "scenario = " + - scenario + - "\n"; - result += - "scenarioDir = " + - scenarioDir + - "\n"; - - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - result += "player index = " + intToStr (idx) + "\n"; - result += - "factionTypeName = " + - factionTypeNames[idx] + - "\n"; - result += - "networkPlayerName = " + - networkPlayerNames[idx] + - "\n"; - result += - "networkPlayerPlatform = " + - networkPlayerPlatform[idx] + - "\n"; - result += - "networkPlayerLanguage = " + - networkPlayerLanguages[idx] + - "\n"; - - result += - "factionControl = " + - intToStr (factionControls[idx]) + - "\n"; - result += - "resourceMultiplierIndex = " + - intToStr (resourceMultiplierIndex[idx]) + - "\n"; - result += - "team = " + - intToStr (teams[idx]) + - "\n"; - result += - "startLocationIndex = " + - intToStr (startLocationIndex[idx]) + - "\n"; - result += - "networkPlayerUUID = " + - networkPlayerUUID[idx] + - "\n"; - } - - result += - "thisFactionIndex = " + - intToStr (thisFactionIndex) + - "\n"; - result += "factionCount = " + intToStr (factionCount) + "\n"; - result += "defaultUnits = " + intToStr (defaultUnits) + "\n"; - result += "defaultResources = " + intToStr (defaultResources) + "\n"; - result += - "defaultVictoryConditions = " + - intToStr (defaultVictoryConditions) + "\n"; - result += "fogOfWar = " + intToStr (fogOfWar) + "\n"; - result += "allowObservers = " + intToStr (allowObservers) + "\n"; - result += - "enableObserverModeAtEndGame = " + - intToStr (enableObserverModeAtEndGame) + "\n"; - result += - "enableServerControlledAI = " + - intToStr (enableServerControlledAI) + "\n"; - result += - "networkFramePeriod = " + intToStr (networkFramePeriod) + "\n"; - result += - "networkPauseGameForLaggedClients = " + - intToStr (networkPauseGameForLaggedClients) + "\n"; - result += "pathFinderType = " + intToStr (pathFinderType) + "\n"; - result += "flagTypes1 = " + uIntToStr (flagTypes1) + "\n"; - result += "mapCRC = " + uIntToStr (mapCRC) + "\n"; - result += "tilesetCRC = " + uIntToStr (tilesetCRC) + "\n"; - result += "techCRC = " + uIntToStr (techCRC) + "\n"; - - for (unsigned int i = 0; i < factionCRCList.size (); ++i) - { - result += - "factionCRCList name [" + factionCRCList[i].first + "] CRC = " + - uIntToStr (factionCRCList[i].second) + "\n"; - } - - result += - "aiAcceptSwitchTeamPercentChance = " + - intToStr (aiAcceptSwitchTeamPercentChance) + "\n"; - result += - "masterserver_admin = " + intToStr (masterserver_admin) + "\n"; - result += - "masterserver_admin_factionIndex = " + - intToStr (masterserver_admin_factionIndex) + "\n"; - - result += - "networkAllowNativeLanguageTechtree = " + - intToStr (networkAllowNativeLanguageTechtree) + "\n"; - return result; - } - - void - saveGame (XmlNode * rootNode) const - { - std::map < - string, - string > - mapTagReplacements; - XmlNode * - gameSettingsNode = rootNode->addChild ("GameSettings"); - - gameSettingsNode-> - addAttribute ("gameUUID", gameUUID, mapTagReplacements); - -// string gameName; - gameSettingsNode-> - addAttribute ("gameName", gameName, mapTagReplacements); -// string description; - gameSettingsNode-> - addAttribute ("description", description, mapTagReplacements); -// string map; - gameSettingsNode-> - addAttribute ("map", map, mapTagReplacements); -// string tileset; - gameSettingsNode-> - addAttribute ("tileset", tileset, mapTagReplacements); -// string tech; - gameSettingsNode-> - addAttribute ("tech", tech, mapTagReplacements); -// string scenario; - gameSettingsNode-> - addAttribute ("scenario", scenario, mapTagReplacements); -// string scenarioDir; - gameSettingsNode-> - addAttribute ("scenarioDir", scenarioDir, mapTagReplacements); -// string factionTypeNames[GameConstants::maxPlayers]; //faction names - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - XmlNode * - factionTypeNamesNode = - gameSettingsNode->addChild ("factionTypeNames"); - factionTypeNamesNode-> - addAttribute ("name", factionTypeNames[idx], mapTagReplacements); - } - -// string networkPlayerNames[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - XmlNode * - networkPlayerNamesNode = - gameSettingsNode->addChild ("networkPlayerNames"); - networkPlayerNamesNode->addAttribute ("name", - networkPlayerNames[idx], - mapTagReplacements); - } - - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - XmlNode * - networkPlayerNamesNode = - gameSettingsNode->addChild ("networkPlayerPlatform"); - networkPlayerNamesNode->addAttribute ("name", - networkPlayerPlatform[idx], - mapTagReplacements); - } - -// int networkPlayerStatuses[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - XmlNode * - networkPlayerStatusesNode = - gameSettingsNode->addChild ("networkPlayerStatuses"); - networkPlayerStatusesNode->addAttribute ("status", - intToStr - (networkPlayerStatuses - [idx]), - mapTagReplacements); - } - - // int networkPlayerStatuses[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - XmlNode * - networkPlayerStatusesNode = - gameSettingsNode->addChild ("networkPlayerGameStatus"); - networkPlayerStatusesNode->addAttribute ("game_status", - intToStr - (networkPlayerGameStatus - [idx]), - mapTagReplacements); - } - -// string networkPlayerLanguages[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - XmlNode * - networkPlayerLanguagesNode = - gameSettingsNode->addChild ("networkPlayerLanguages"); - networkPlayerLanguagesNode->addAttribute ("name", - networkPlayerLanguages - [idx], - mapTagReplacements); - } - -// ControlType factionControls[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - XmlNode * - factionControlsNode = - gameSettingsNode->addChild ("factionControls"); - factionControlsNode->addAttribute ("control", - intToStr (factionControls - [idx]), - mapTagReplacements); - } - -// int resourceMultiplierIndex[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - XmlNode * - resourceMultiplierIndexNode = - gameSettingsNode->addChild ("resourceMultiplierIndex"); - resourceMultiplierIndexNode->addAttribute ("multiplier", - intToStr - (resourceMultiplierIndex - [idx]), - mapTagReplacements); - } - -// int thisFactionIndex; - gameSettingsNode->addAttribute ("thisFactionIndex", - intToStr (thisFactionIndex), - mapTagReplacements); -// int factionCount; - gameSettingsNode->addAttribute ("factionCount", - intToStr (factionCount), - mapTagReplacements); -// int teams[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - XmlNode * - teamsNode = gameSettingsNode->addChild ("teams"); - teamsNode->addAttribute ("team", intToStr (teams[idx]), - mapTagReplacements); - } - -// int startLocationIndex[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - XmlNode * - startLocationIndexNode = - gameSettingsNode->addChild ("startLocationIndex"); - startLocationIndexNode->addAttribute ("location", - intToStr (startLocationIndex - [idx]), - mapTagReplacements); - } - - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - XmlNode * - networkPlayerUUIDNode = - gameSettingsNode->addChild ("networkPlayerUUID"); - networkPlayerUUIDNode->addAttribute ("value", - networkPlayerUUID[idx], - mapTagReplacements); - } - -// int mapFilterIndex; - gameSettingsNode->addAttribute ("mapFilterIndex", - intToStr (mapFilter), - mapTagReplacements); -// -// -// bool defaultUnits; - gameSettingsNode->addAttribute ("defaultUnits", - intToStr (defaultUnits), - mapTagReplacements); -// bool defaultResources; - gameSettingsNode->addAttribute ("defaultResources", - intToStr (defaultResources), - mapTagReplacements); -// bool defaultVictoryConditions; - gameSettingsNode->addAttribute ("defaultVictoryConditions", - intToStr (defaultVictoryConditions), - mapTagReplacements); -// bool fogOfWar; - gameSettingsNode->addAttribute ("fogOfWar", intToStr (fogOfWar), - mapTagReplacements); -// bool allowObservers; - gameSettingsNode->addAttribute ("allowObservers", - intToStr (allowObservers), - mapTagReplacements); -// bool enableObserverModeAtEndGame; - gameSettingsNode->addAttribute ("enableObserverModeAtEndGame", - intToStr - (enableObserverModeAtEndGame), - mapTagReplacements); -// bool enableServerControlledAI; - gameSettingsNode->addAttribute ("enableServerControlledAI", - intToStr (enableServerControlledAI), - mapTagReplacements); -// int networkFramePeriod; - gameSettingsNode->addAttribute ("networkFramePeriod", - intToStr (networkFramePeriod), - mapTagReplacements); -// bool networkPauseGameForLaggedClients; - gameSettingsNode->addAttribute ("networkPauseGameForLaggedClients", - intToStr - (networkPauseGameForLaggedClients), - mapTagReplacements); -// PathFinderType pathFinderType; - gameSettingsNode->addAttribute ("pathFinderType", - intToStr (pathFinderType), - mapTagReplacements); -// uint32 flagTypes1; - gameSettingsNode->addAttribute ("flagTypes1", uIntToStr (flagTypes1), - mapTagReplacements); -// int32 mapCRC; - gameSettingsNode->addAttribute ("mapCRC", uIntToStr (mapCRC), - mapTagReplacements); -// int32 tilesetCRC; - gameSettingsNode->addAttribute ("tilesetCRC", uIntToStr (tilesetCRC), - mapTagReplacements); -// int32 techCRC; - gameSettingsNode->addAttribute ("techCRC", uIntToStr (techCRC), - mapTagReplacements); -// vector > factionCRCList; - for (unsigned int i = 0; i < factionCRCList.size (); ++i) - { - const - pair < - string, - uint32 > & - item = factionCRCList[i]; - - XmlNode * - factionCRCListNode = - gameSettingsNode->addChild ("factionCRCList"); - factionCRCListNode->addAttribute ("key", item.first, - mapTagReplacements); - factionCRCListNode->addAttribute ("value", - uIntToStr (item.second), - mapTagReplacements); - } -// int aiAcceptSwitchTeamPercentChance; - gameSettingsNode->addAttribute ("aiAcceptSwitchTeamPercentChance", - intToStr - (aiAcceptSwitchTeamPercentChance), - mapTagReplacements); -// int masterserver_admin; - gameSettingsNode->addAttribute ("masterserver_admin", - intToStr (masterserver_admin), - mapTagReplacements); - - gameSettingsNode->addAttribute ("masterserver_admin_factionIndex", - intToStr - (masterserver_admin_factionIndex), - mapTagReplacements); - - gameSettingsNode->addAttribute ("networkAllowNativeLanguageTechtree", - intToStr - (networkAllowNativeLanguageTechtree), - mapTagReplacements); - } - - void - loadGame (const XmlNode * rootNode) - { - const XmlNode * - gameSettingsNode = rootNode->getChild ("GameSettings"); - - if (gameSettingsNode->hasAttribute ("gameUUID") == true) - { - gameUUID = - gameSettingsNode->getAttribute ("gameUUID")->getValue (); - } - -// string gameName; - if (gameSettingsNode->hasAttribute ("gameName") == true) - { - gameName = - gameSettingsNode->getAttribute ("gameName")->getValue (); - } - else - { - gameName = "oldSavegame"; - } -// string description; - description = - gameSettingsNode->getAttribute ("description")->getValue (); -// string map; - map = gameSettingsNode->getAttribute ("map")->getValue (); -// string tileset; - tileset = gameSettingsNode->getAttribute ("tileset")->getValue (); -// string tech; - tech = gameSettingsNode->getAttribute ("tech")->getValue (); -// string scenario; - scenario = gameSettingsNode->getAttribute ("scenario")->getValue (); -// string scenarioDir; - scenarioDir = - gameSettingsNode->getAttribute ("scenarioDir")->getValue (); - if (fileExists (scenarioDir) == false) - { - scenarioDir = Config::findValidLocalFileFromPath (scenarioDir); - } - -// string factionTypeNames[GameConstants::maxPlayers]; //faction names - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - const XmlNode * - factionTypeNamesNode = - gameSettingsNode->getChild ("factionTypeNames", idx); - factionTypeNames[idx] = - factionTypeNamesNode->getAttribute ("name")->getValue (); - } - -// string networkPlayerNames[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - const XmlNode * - networkPlayerNamesNode = - gameSettingsNode->getChild ("networkPlayerNames", idx); - networkPlayerNames[idx] = - networkPlayerNamesNode->getAttribute ("name")->getValue (); - } - -// int networkPlayerStatuses[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - const XmlNode * - networkPlayerStatusesNode = - gameSettingsNode->getChild ("networkPlayerStatuses", idx); - networkPlayerStatuses[idx] = - networkPlayerStatusesNode->getAttribute ("status")-> - getIntValue (); - } - - // int networkPlayerStatuses[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - if (gameSettingsNode-> - hasChildAtIndex ("networkPlayerGameStatus", idx) == true) - { - const XmlNode * - networkPlayerGameStatusNode = - gameSettingsNode->getChild ("networkPlayerGameStatus", idx); - networkPlayerGameStatus[idx] = - networkPlayerGameStatusNode->getAttribute ("game_status")-> - getIntValue (); - } - } - -// string networkPlayerLanguages[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - const XmlNode * - networkPlayerLanguagesNode = - gameSettingsNode->getChild ("networkPlayerLanguages", idx); - networkPlayerLanguages[idx] = - networkPlayerLanguagesNode->getAttribute ("name")->getValue (); - } - -// ControlType factionControls[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - const XmlNode * - factionControlsNode = - gameSettingsNode->getChild ("factionControls", idx); - factionControls[idx] = - static_cast < ControlType > - (factionControlsNode->getAttribute ("control")->getIntValue ()); - } - -// int resourceMultiplierIndex[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - const XmlNode * - resourceMultiplierIndexNode = - gameSettingsNode->getChild ("resourceMultiplierIndex", idx); - resourceMultiplierIndex[idx] = - resourceMultiplierIndexNode->getAttribute ("multiplier")-> - getIntValue (); - } - - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - if (gameSettingsNode-> - hasChildAtIndex ("networkPlayerUUID", idx) == true) - { - const XmlNode * - networkPlayerUUIDNode = - gameSettingsNode->getChild ("networkPlayerUUID", idx); - networkPlayerUUID[idx] = - networkPlayerUUIDNode->getAttribute ("value")->getValue (); - } - } - -// int thisFactionIndex; - thisFactionIndex = - gameSettingsNode->getAttribute ("thisFactionIndex")->getIntValue (); -// int factionCount; - factionCount = - gameSettingsNode->getAttribute ("factionCount")->getIntValue (); -// int teams[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - const XmlNode * - teamsNode = gameSettingsNode->getChild ("teams", idx); - teams[idx] = teamsNode->getAttribute ("team")->getIntValue (); - } - -// int startLocationIndex[GameConstants::maxPlayers]; - for (int idx = 0; idx < GameConstants::maxPlayers; idx++) - { - const XmlNode * - startLocationIndexNode = - gameSettingsNode->getChild ("startLocationIndex", idx); - startLocationIndex[idx] = - startLocationIndexNode->getAttribute ("location")-> - getIntValue (); - } - -// int mapFilterIndex; - mapFilter = - gameSettingsNode->getAttribute ("mapFilterIndex")->getIntValue (); -// -// -// bool defaultUnits; - defaultUnits = - gameSettingsNode->getAttribute ("defaultUnits")->getIntValue () != - 0; -// bool defaultResources; - defaultResources = - gameSettingsNode->getAttribute ("defaultResources")-> - getIntValue () != 0; -// bool defaultVictoryConditions; - defaultVictoryConditions = - gameSettingsNode->getAttribute ("defaultVictoryConditions")-> - getIntValue () != 0; -// bool fogOfWar; - fogOfWar = - gameSettingsNode->getAttribute ("fogOfWar")->getIntValue () != 0; -// bool allowObservers; - allowObservers = - gameSettingsNode->getAttribute ("allowObservers")->getIntValue () != - 0; -// bool enableObserverModeAtEndGame; - enableObserverModeAtEndGame = - gameSettingsNode->getAttribute ("enableObserverModeAtEndGame")-> - getIntValue () != 0; -// bool enableServerControlledAI; - enableServerControlledAI = - gameSettingsNode->getAttribute ("enableServerControlledAI")-> - getIntValue () != 0; -// int networkFramePeriod; - networkFramePeriod = - gameSettingsNode->getAttribute ("networkFramePeriod")-> - getIntValue (); -// bool networkPauseGameForLaggedClients; - networkPauseGameForLaggedClients = - gameSettingsNode-> - getAttribute ("networkPauseGameForLaggedClients")->getIntValue () != - 0; -// PathFinderType pathFinderType; - pathFinderType = - static_cast < PathFinderType > - (gameSettingsNode->getAttribute ("pathFinderType")->getIntValue ()); -// uint32 flagTypes1; - flagTypes1 = - gameSettingsNode->getAttribute ("flagTypes1")->getUIntValue (); -// int32 mapCRC; - mapCRC = gameSettingsNode->getAttribute ("mapCRC")->getUIntValue (); -// int32 tilesetCRC; - tilesetCRC = - gameSettingsNode->getAttribute ("tilesetCRC")->getUIntValue (); -// int32 techCRC; - techCRC = gameSettingsNode->getAttribute ("techCRC")->getUIntValue (); -// vector > factionCRCList; -// for(unsigned int i = 0; i < factionCRCList.size(); ++i) { -// const pair &item = factionCRCList[i]; -// -// XmlNode *factionCRCListNode = gameSettingsNode->addChild("factionCRCList"); -// factionCRCListNode->addAttribute("key",item.first, mapTagReplacements); -// factionCRCListNode->addAttribute("value",intToStr(item.second), mapTagReplacements); -// } -// int aiAcceptSwitchTeamPercentChance; - aiAcceptSwitchTeamPercentChance = - gameSettingsNode->getAttribute ("aiAcceptSwitchTeamPercentChance")-> - getIntValue (); -// int masterserver_admin; - masterserver_admin = - gameSettingsNode->getAttribute ("masterserver_admin")-> - getIntValue (); - - if (gameSettingsNode-> - hasAttribute ("masterserver_admin_factionIndex") == true) - { - masterserver_admin_factionIndex = - gameSettingsNode-> - getAttribute ("masterserver_admin_factionIndex")-> - getIntValue (); - } - - if (gameSettingsNode-> - hasAttribute ("networkAllowNativeLanguageTechtree") == true) - { - networkAllowNativeLanguageTechtree = - gameSettingsNode-> - getAttribute ("networkAllowNativeLanguageTechtree")-> - getIntValue () != 0; - } - } - - }; - - } + Glest { + namespace + Game { + + enum ModType { + mt_None, + mt_Map, + mt_Tileset, + mt_Techtree, + mt_Scenario + }; + + // =============================== + // class ModInfo + // =============================== + + class + ModInfo { + public: + string + name; + string + url; + string + imageUrl; + string + description; + string + count; // used for faction count for example + string + crc; + string + localCRC; + ModType + type; + public: + ModInfo(); + }; + + // ===================================================== + // class GameSettings + // ===================================================== + + enum FlagTypes1 { + ft1_none = 0x00, + ft1_show_map_resources = 0x01, + ft1_allow_team_switching = 0x02, + ft1_allow_in_game_joining = 0x04, + ft1_network_synch_checks_verbose = 0x08, + ft1_network_synch_checks = 0x10, + ft1_allow_shared_team_units = 0x20, + ft1_allow_shared_team_resources = 0x40 + //ft1_xxx = 0x80 + }; + + inline static bool + isFlagType1BitEnabled(uint32 flagValue, FlagTypes1 type) { + return ((flagValue & (uint32) type) == (uint32) type); + } + + enum NetworkPlayerStatusType { + npst_None = 0, + npst_PickSettings = 1, + npst_BeRightBack = 2, + npst_Ready = 3, + npst_Disconnected = 4 + }; + + class + GameSettings { + private: + string + gameName; + string + description; + string + map; + string + tileset; + string + tech; + string + scenario; + string + scenarioDir; + string + factionTypeNames[GameConstants::maxPlayers]; //faction names + string + networkPlayerNames[GameConstants::maxPlayers]; + string + networkPlayerPlatform[GameConstants::maxPlayers]; + int + networkPlayerStatuses[GameConstants::maxPlayers]; + string + networkPlayerLanguages[GameConstants::maxPlayers]; + int + networkPlayerGameStatus[GameConstants::maxPlayers]; + + ControlType + factionControls[GameConstants::maxPlayers]; + int + resourceMultiplierIndex[GameConstants::maxPlayers]; + string + networkPlayerUUID[GameConstants::maxPlayers]; + + + int + thisFactionIndex; + int + factionCount; + int + teams[GameConstants::maxPlayers]; + int + startLocationIndex[GameConstants::maxPlayers]; + int + mapFilter; + + int + fallbackCpuMultiplier; + bool + defaultUnits; + bool + defaultResources; + bool + defaultVictoryConditions; + + bool + fogOfWar; + bool + allowObservers; + bool + enableObserverModeAtEndGame; + bool + enableServerControlledAI; + int + networkFramePeriod; + bool + networkPauseGameForLaggedClients; + PathFinderType + pathFinderType; + + uint32 + flagTypes1; + + uint32 + mapCRC; + uint32 + tilesetCRC; + uint32 + techCRC; + vector < + pair < + string, + uint32 > > + factionCRCList; + + int + aiAcceptSwitchTeamPercentChance; + int + masterserver_admin; + + int + masterserver_admin_factionIndex; + + bool + networkAllowNativeLanguageTechtree; + + string + gameUUID; + + public: + + static string + playerDisconnectedText; + + GameSettings() { + defaultUnits = false; + defaultResources = false; + defaultVictoryConditions = false; + mapFilter = 0; + factionCount = 0; + thisFactionIndex = 0; + fogOfWar = true; + allowObservers = false; + enableObserverModeAtEndGame = false; + enableServerControlledAI = false; + networkFramePeriod = GameConstants::networkFramePeriod; + networkPauseGameForLaggedClients = false; + pathFinderType = pfBasic; + + static const string + DEFAULT_LANG = "english"; + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + factionTypeNames[i] = ""; + networkPlayerNames[i] = ""; + networkPlayerPlatform[i] = ""; + networkPlayerStatuses[i] = npst_None; + networkPlayerLanguages[i] = DEFAULT_LANG; + factionControls[i] = ctClosed; + resourceMultiplierIndex[i] = 1.0f; + teams[i] = 0; + startLocationIndex[i] = i; + networkPlayerGameStatus[i] = 0; + + networkPlayerUUID[i] = ""; + } + + flagTypes1 = ft1_none; + + mapCRC = 0; + tilesetCRC = 0; + techCRC = 0; + factionCRCList. + clear(); + aiAcceptSwitchTeamPercentChance = 30; + masterserver_admin = -1; + masterserver_admin_factionIndex = -1; + fallbackCpuMultiplier = 1.0f; + networkAllowNativeLanguageTechtree = true; + } + + // default copy constructor will do fine, and will maintain itself ;) + + //get + const + string & + getGameName() const { + return + gameName; + } + const + string & + getDescription() const { + return + description; + } + const + string & + getMap() const { + return + map; + } + const + string & + getTileset() const { + return + tileset; + } + const + string & + getTech() const { + return + tech; + } + const + string & + getScenario() const { + return + scenario; + } + const + string & + getScenarioDir() const { + return + scenarioDir; + } + const + string & + getFactionTypeName(int factionIndex) const { + if (factionIndex == -1) { + static string + HEADLESS_FACTION = "headless-server"; + return + HEADLESS_FACTION; + } + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + return factionTypeNames[factionIndex]; + } + string + getNetworkPlayerName(int factionIndex) const { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + string + result = networkPlayerNames[factionIndex]; + if (networkPlayerStatuses[factionIndex] == npst_Disconnected) { + result = playerDisconnectedText + result; + } + return result; + } + string + getNetworkPlayerPlatform(int factionIndex) const { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + string + result = networkPlayerPlatform[factionIndex]; + return result; + } + + const int + getNetworkPlayerStatuses(int factionIndex) const { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + return + networkPlayerStatuses[factionIndex]; + } + const string + getNetworkPlayerLanguages(int factionIndex) const { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + return + networkPlayerLanguages[factionIndex]; + } + + const int + getNetworkPlayerGameStatus(int factionIndex) const { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + return + networkPlayerGameStatus[factionIndex]; + } + + const + vector < + string > + getUniqueNetworkPlayerLanguages() const { + vector < + string > + languageList; + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + if (networkPlayerLanguages[i] != "") { + if (std:: + find(languageList.begin(), languageList.end(), + networkPlayerLanguages[i]) == languageList.end()) { + languageList.push_back(networkPlayerLanguages[i]); + } + } + } + if (languageList.empty() == true) { + languageList.push_back(""); + } + return languageList; + } + + const string + getNetworkPlayerNameByPlayerIndex(int playerIndex) const { + string + result = ""; + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + if (startLocationIndex[i] == playerIndex) { + result = networkPlayerNames[i]; + break; + } + } + return + result; + } + const string + getNetworkPlayerPlatformByPlayerIndex(int playerIndex) const { + string + result = ""; + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + if (startLocationIndex[i] == playerIndex) { + result = networkPlayerPlatform[i]; + break; + } + } + return + result; + } + + ControlType + getFactionControl(int factionIndex) const { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + return + factionControls[factionIndex]; + } + int + getResourceMultiplierIndex(int factionIndex) const { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + return + resourceMultiplierIndex[factionIndex]; + } + + const + string & + getNetworkPlayerUUID(int factionIndex) const { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + return + networkPlayerUUID[factionIndex]; + } + + bool + isNetworkGame() const { + bool + result = false; + for (int idx = 0; idx < GameConstants::maxPlayers; ++idx) { + if (factionControls[idx] == ctNetwork + || factionControls[idx] == ctNetworkUnassigned + || networkPlayerStatuses[idx] == npst_Disconnected) { + result = true; + break; + } + } + return + result; + } + int + getThisFactionIndex() const { + return + thisFactionIndex; + } + int + getFactionCount() const { + return + factionCount; + } + int + getTeam(int factionIndex) const { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + return + teams[factionIndex]; + } + + int + getStartLocationIndex(int factionIndex) const { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + return + startLocationIndex[factionIndex]; + } + int + getFactionIndexForStartLocation(int startIndex) const { + if (startIndex < 0 || startIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid startIndex = %d\n", + __FUNCTION__, startIndex); + throw + megaglest_runtime_error(szBuf); + } + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + if (startLocationIndex[i] == startIndex) { + return i; + } + } + return -1; + } + + int + getMapFilter() const { + return + mapFilter; + } + + bool + getDefaultUnits() const { + return + defaultUnits; + } + bool + getDefaultResources() const { + return + defaultResources; + } + bool + getDefaultVictoryConditions() const { + return + defaultVictoryConditions; + } + + bool + getFogOfWar() const { + return + fogOfWar; + } + bool + getAllowObservers() const { + return + allowObservers; + } + bool + getEnableObserverModeAtEndGame() const { + return + enableObserverModeAtEndGame; + } + bool + getEnableServerControlledAI() const { + return + enableServerControlledAI; + } + int + getNetworkFramePeriod() const { + return + networkFramePeriod; + } + bool + getNetworkPauseGameForLaggedClients() const { + return + networkPauseGameForLaggedClients; + } + PathFinderType + getPathFinderType() const { + return + pathFinderType; + } + uint32 + getFlagTypes1() const { + return + flagTypes1; + } + + uint32 + getMapCRC() const { + return + mapCRC; + } + uint32 + getTilesetCRC() const { + return + tilesetCRC; + } + uint32 + getTechCRC() const { + return + techCRC; + } + vector < + pair < + string, + uint32 > > + getFactionCRCList() const { + return + factionCRCList; + } + + const + string & + getGameUUID() const { + return + gameUUID; + } + + //set + void + setGameName(const string & gameName) { + this->gameName = gameName; + } + void + setDescription(const string & description) { + this->description = description; + } + void + setMap(const string & map) { + this->map = map; + } + void + setTileset(const string & tileset) { + this->tileset = tileset; + } + void + setTech(const string & tech) { + this->tech = tech; + } + void + setScenario(const string & scenario) { + this->scenario = scenario; + } + void + setScenarioDir(const string & scenarioDir) { + this->scenarioDir = scenarioDir; + } + + void + setFactionTypeName(int factionIndex, const string & factionTypeName) { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + this->factionTypeNames[factionIndex] = factionTypeName; + } + void + setNetworkPlayerName(int factionIndex, const string & playername) { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + this->networkPlayerNames[factionIndex] = playername; + } + void + setNetworkPlayerPlatform(int factionIndex, const string & platform) { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + this->networkPlayerPlatform[factionIndex] = platform; + } + + void + setNetworkPlayerStatuses(int factionIndex, int status) { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + this->networkPlayerStatuses[factionIndex] = status; + } + + void + setNetworkPlayerGameStatus(int factionIndex, int status) { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + this->networkPlayerGameStatus[factionIndex] = status; + } + void + setNetworkPlayerLanguages(int factionIndex, const string & language) { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + this->networkPlayerLanguages[factionIndex] = language; + } + + void + setFactionControl(int factionIndex, ControlType controller) { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + this->factionControls[factionIndex] = controller; + } + void + setResourceMultiplierIndex(int factionIndex, int multiplierIndex) { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + //if(multiplierIndex >= 45) { + // printf("gamesettings Line: %d multiplier index: %d factionIndex: %d\n",__LINE__,multiplierIndex,factionIndex); + //} + + this->resourceMultiplierIndex[factionIndex] = multiplierIndex; + } + + void + setNetworkPlayerUUID(int factionIndex, const string & uuid) { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + this->networkPlayerUUID[factionIndex] = uuid; + } + + void + setThisFactionIndex(int thisFactionIndex) { + this->thisFactionIndex = thisFactionIndex; + } + void + setFactionCount(int factionCount) { + this->factionCount = factionCount; + } + void + setTeam(int factionIndex, int team) { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + this->teams[factionIndex] = team; + } + void + setStartLocationIndex(int factionIndex, int startLocationIndex) { + if (factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s] Invalid factionIndex = %d\n", + __FUNCTION__, factionIndex); + throw + megaglest_runtime_error(szBuf); + } + + this->startLocationIndex[factionIndex] = startLocationIndex; + } + void + setMapFilter(int mapFilter) { + this->mapFilter = mapFilter; + } + + void + setDefaultUnits(bool defaultUnits) { + this->defaultUnits = defaultUnits; + } + void + setDefaultResources(bool defaultResources) { + this->defaultResources = defaultResources; + } + void + setDefaultVictoryConditions(bool defaultVictoryConditions) { + this->defaultVictoryConditions = defaultVictoryConditions; + } + + void + setFogOfWar(bool fogOfWar) { + this->fogOfWar = fogOfWar; + } + void + setAllowObservers(bool value) { + this->allowObservers = value; + } + void + setEnableObserverModeAtEndGame(bool value) { + this->enableObserverModeAtEndGame = value; + } + void + setEnableServerControlledAI(bool value) { + this->enableServerControlledAI = value; + } + void + setNetworkFramePeriod(int value) { + this->networkFramePeriod = value; + } + void + setNetworkPauseGameForLaggedClients(bool value) { + this->networkPauseGameForLaggedClients = value; + } + void + setPathFinderType(PathFinderType value) { + this->pathFinderType = value; + } + + void + setFlagTypes1(uint32 value) { + this->flagTypes1 = value; + } + + void + setMapCRC(uint32 value) { + mapCRC = value; + } + void + setTilesetCRC(uint32 value) { + tilesetCRC = value; + } + void + setTechCRC(uint32 value) { + techCRC = value; + } + + void + setFactionCRCList(const vector < pair < string, uint32 > >&value) { + factionCRCList = value; + } + + int + getAiAcceptSwitchTeamPercentChance() const { + return + aiAcceptSwitchTeamPercentChance; + } + void + setAiAcceptSwitchTeamPercentChance(int value) { + aiAcceptSwitchTeamPercentChance = value; + } + + int + getFallbackCpuMultiplier() const { + return + fallbackCpuMultiplier; + } + void + setFallbackCpuMultiplier(int value) { + fallbackCpuMultiplier = value; + } + + int + getMasterserver_admin() const { + return + masterserver_admin; + } + void + setMasterserver_admin(int value) { + masterserver_admin = value; + } + + int + getMasterserver_admin_faction_index() const { + return + masterserver_admin_factionIndex; + } + void + setMasterserver_admin_faction_index(int value) { + masterserver_admin_factionIndex = value; + } + + bool + getNetworkAllowNativeLanguageTechtree() const { + return + networkAllowNativeLanguageTechtree; + } + void + setNetworkAllowNativeLanguageTechtree(bool value) { + networkAllowNativeLanguageTechtree = value; + } + + void + setGameUUID(const string & gameUUID) { + this->gameUUID = gameUUID; + } + + string + toString() const { + string + result = ""; + + result += + "Game ID = " + + gameUUID + + "\n"; + result += + "gameName = " + + gameName + + "\n"; + result += + "description = " + + description + + "\n"; + result += + "mapFilterIndex = " + + intToStr(mapFilter) + + "\n"; + result += + "map = " + + map + + "\n"; + result += + "tileset = " + + tileset + + "\n"; + result += + "tech = " + + tech + + "\n"; + result += + "scenario = " + + scenario + + "\n"; + result += + "scenarioDir = " + + scenarioDir + + "\n"; + + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + result += "player index = " + intToStr(idx) + "\n"; + result += + "factionTypeName = " + + factionTypeNames[idx] + + "\n"; + result += + "networkPlayerName = " + + networkPlayerNames[idx] + + "\n"; + result += + "networkPlayerPlatform = " + + networkPlayerPlatform[idx] + + "\n"; + result += + "networkPlayerLanguage = " + + networkPlayerLanguages[idx] + + "\n"; + + result += + "factionControl = " + + intToStr(factionControls[idx]) + + "\n"; + result += + "resourceMultiplierIndex = " + + intToStr(resourceMultiplierIndex[idx]) + + "\n"; + result += + "team = " + + intToStr(teams[idx]) + + "\n"; + result += + "startLocationIndex = " + + intToStr(startLocationIndex[idx]) + + "\n"; + result += + "networkPlayerUUID = " + + networkPlayerUUID[idx] + + "\n"; + } + + result += + "thisFactionIndex = " + + intToStr(thisFactionIndex) + + "\n"; + result += "factionCount = " + intToStr(factionCount) + "\n"; + result += "defaultUnits = " + intToStr(defaultUnits) + "\n"; + result += "defaultResources = " + intToStr(defaultResources) + "\n"; + result += + "defaultVictoryConditions = " + + intToStr(defaultVictoryConditions) + "\n"; + result += "fogOfWar = " + intToStr(fogOfWar) + "\n"; + result += "allowObservers = " + intToStr(allowObservers) + "\n"; + result += + "enableObserverModeAtEndGame = " + + intToStr(enableObserverModeAtEndGame) + "\n"; + result += + "enableServerControlledAI = " + + intToStr(enableServerControlledAI) + "\n"; + result += + "networkFramePeriod = " + intToStr(networkFramePeriod) + "\n"; + result += + "networkPauseGameForLaggedClients = " + + intToStr(networkPauseGameForLaggedClients) + "\n"; + result += "pathFinderType = " + intToStr(pathFinderType) + "\n"; + result += "flagTypes1 = " + uIntToStr(flagTypes1) + "\n"; + result += "mapCRC = " + uIntToStr(mapCRC) + "\n"; + result += "tilesetCRC = " + uIntToStr(tilesetCRC) + "\n"; + result += "techCRC = " + uIntToStr(techCRC) + "\n"; + + for (unsigned int i = 0; i < factionCRCList.size(); ++i) { + result += + "factionCRCList name [" + factionCRCList[i].first + "] CRC = " + + uIntToStr(factionCRCList[i].second) + "\n"; + } + + result += + "aiAcceptSwitchTeamPercentChance = " + + intToStr(aiAcceptSwitchTeamPercentChance) + "\n"; + result += + "masterserver_admin = " + intToStr(masterserver_admin) + "\n"; + result += + "masterserver_admin_factionIndex = " + + intToStr(masterserver_admin_factionIndex) + "\n"; + + result += + "networkAllowNativeLanguageTechtree = " + + intToStr(networkAllowNativeLanguageTechtree) + "\n"; + return result; + } + + void + saveGame(XmlNode * rootNode) const { + std::map < + string, + string > + mapTagReplacements; + XmlNode * + gameSettingsNode = rootNode->addChild("GameSettings"); + + gameSettingsNode-> + addAttribute("gameUUID", gameUUID, mapTagReplacements); + + // string gameName; + gameSettingsNode-> + addAttribute("gameName", gameName, mapTagReplacements); + // string description; + gameSettingsNode-> + addAttribute("description", description, mapTagReplacements); + // string map; + gameSettingsNode-> + addAttribute("map", map, mapTagReplacements); + // string tileset; + gameSettingsNode-> + addAttribute("tileset", tileset, mapTagReplacements); + // string tech; + gameSettingsNode-> + addAttribute("tech", tech, mapTagReplacements); + // string scenario; + gameSettingsNode-> + addAttribute("scenario", scenario, mapTagReplacements); + // string scenarioDir; + gameSettingsNode-> + addAttribute("scenarioDir", scenarioDir, mapTagReplacements); + // string factionTypeNames[GameConstants::maxPlayers]; //faction names + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + XmlNode * + factionTypeNamesNode = + gameSettingsNode->addChild("factionTypeNames"); + factionTypeNamesNode-> + addAttribute("name", factionTypeNames[idx], mapTagReplacements); + } + + // string networkPlayerNames[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + XmlNode * + networkPlayerNamesNode = + gameSettingsNode->addChild("networkPlayerNames"); + networkPlayerNamesNode->addAttribute("name", + networkPlayerNames[idx], + mapTagReplacements); + } + + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + XmlNode * + networkPlayerNamesNode = + gameSettingsNode->addChild("networkPlayerPlatform"); + networkPlayerNamesNode->addAttribute("name", + networkPlayerPlatform[idx], + mapTagReplacements); + } + + // int networkPlayerStatuses[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + XmlNode * + networkPlayerStatusesNode = + gameSettingsNode->addChild("networkPlayerStatuses"); + networkPlayerStatusesNode->addAttribute("status", + intToStr + (networkPlayerStatuses + [idx]), + mapTagReplacements); + } + + // int networkPlayerStatuses[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + XmlNode * + networkPlayerStatusesNode = + gameSettingsNode->addChild("networkPlayerGameStatus"); + networkPlayerStatusesNode->addAttribute("game_status", + intToStr + (networkPlayerGameStatus + [idx]), + mapTagReplacements); + } + + // string networkPlayerLanguages[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + XmlNode * + networkPlayerLanguagesNode = + gameSettingsNode->addChild("networkPlayerLanguages"); + networkPlayerLanguagesNode->addAttribute("name", + networkPlayerLanguages + [idx], + mapTagReplacements); + } + + // ControlType factionControls[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + XmlNode * + factionControlsNode = + gameSettingsNode->addChild("factionControls"); + factionControlsNode->addAttribute("control", + intToStr(factionControls + [idx]), + mapTagReplacements); + } + + // int resourceMultiplierIndex[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + XmlNode * + resourceMultiplierIndexNode = + gameSettingsNode->addChild("resourceMultiplierIndex"); + resourceMultiplierIndexNode->addAttribute("multiplier", + intToStr + (resourceMultiplierIndex + [idx]), + mapTagReplacements); + } + + // int thisFactionIndex; + gameSettingsNode->addAttribute("thisFactionIndex", + intToStr(thisFactionIndex), + mapTagReplacements); + // int factionCount; + gameSettingsNode->addAttribute("factionCount", + intToStr(factionCount), + mapTagReplacements); + // int teams[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + XmlNode * + teamsNode = gameSettingsNode->addChild("teams"); + teamsNode->addAttribute("team", intToStr(teams[idx]), + mapTagReplacements); + } + + // int startLocationIndex[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + XmlNode * + startLocationIndexNode = + gameSettingsNode->addChild("startLocationIndex"); + startLocationIndexNode->addAttribute("location", + intToStr(startLocationIndex + [idx]), + mapTagReplacements); + } + + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + XmlNode * + networkPlayerUUIDNode = + gameSettingsNode->addChild("networkPlayerUUID"); + networkPlayerUUIDNode->addAttribute("value", + networkPlayerUUID[idx], + mapTagReplacements); + } + + // int mapFilterIndex; + gameSettingsNode->addAttribute("mapFilterIndex", + intToStr(mapFilter), + mapTagReplacements); + // + // + // bool defaultUnits; + gameSettingsNode->addAttribute("defaultUnits", + intToStr(defaultUnits), + mapTagReplacements); + // bool defaultResources; + gameSettingsNode->addAttribute("defaultResources", + intToStr(defaultResources), + mapTagReplacements); + // bool defaultVictoryConditions; + gameSettingsNode->addAttribute("defaultVictoryConditions", + intToStr(defaultVictoryConditions), + mapTagReplacements); + // bool fogOfWar; + gameSettingsNode->addAttribute("fogOfWar", intToStr(fogOfWar), + mapTagReplacements); + // bool allowObservers; + gameSettingsNode->addAttribute("allowObservers", + intToStr(allowObservers), + mapTagReplacements); + // bool enableObserverModeAtEndGame; + gameSettingsNode->addAttribute("enableObserverModeAtEndGame", + intToStr + (enableObserverModeAtEndGame), + mapTagReplacements); + // bool enableServerControlledAI; + gameSettingsNode->addAttribute("enableServerControlledAI", + intToStr(enableServerControlledAI), + mapTagReplacements); + // int networkFramePeriod; + gameSettingsNode->addAttribute("networkFramePeriod", + intToStr(networkFramePeriod), + mapTagReplacements); + // bool networkPauseGameForLaggedClients; + gameSettingsNode->addAttribute("networkPauseGameForLaggedClients", + intToStr + (networkPauseGameForLaggedClients), + mapTagReplacements); + // PathFinderType pathFinderType; + gameSettingsNode->addAttribute("pathFinderType", + intToStr(pathFinderType), + mapTagReplacements); + // uint32 flagTypes1; + gameSettingsNode->addAttribute("flagTypes1", uIntToStr(flagTypes1), + mapTagReplacements); + // int32 mapCRC; + gameSettingsNode->addAttribute("mapCRC", uIntToStr(mapCRC), + mapTagReplacements); + // int32 tilesetCRC; + gameSettingsNode->addAttribute("tilesetCRC", uIntToStr(tilesetCRC), + mapTagReplacements); + // int32 techCRC; + gameSettingsNode->addAttribute("techCRC", uIntToStr(techCRC), + mapTagReplacements); + // vector > factionCRCList; + for (unsigned int i = 0; i < factionCRCList.size(); ++i) { + const + pair < + string, + uint32 > & + item = factionCRCList[i]; + + XmlNode * + factionCRCListNode = + gameSettingsNode->addChild("factionCRCList"); + factionCRCListNode->addAttribute("key", item.first, + mapTagReplacements); + factionCRCListNode->addAttribute("value", + uIntToStr(item.second), + mapTagReplacements); + } + // int aiAcceptSwitchTeamPercentChance; + gameSettingsNode->addAttribute("aiAcceptSwitchTeamPercentChance", + intToStr + (aiAcceptSwitchTeamPercentChance), + mapTagReplacements); + // int masterserver_admin; + gameSettingsNode->addAttribute("masterserver_admin", + intToStr(masterserver_admin), + mapTagReplacements); + + gameSettingsNode->addAttribute("masterserver_admin_factionIndex", + intToStr + (masterserver_admin_factionIndex), + mapTagReplacements); + + gameSettingsNode->addAttribute("networkAllowNativeLanguageTechtree", + intToStr + (networkAllowNativeLanguageTechtree), + mapTagReplacements); + } + + void + loadGame(const XmlNode * rootNode) { + const XmlNode * + gameSettingsNode = rootNode->getChild("GameSettings"); + + if (gameSettingsNode->hasAttribute("gameUUID") == true) { + gameUUID = + gameSettingsNode->getAttribute("gameUUID")->getValue(); + } + + // string gameName; + if (gameSettingsNode->hasAttribute("gameName") == true) { + gameName = + gameSettingsNode->getAttribute("gameName")->getValue(); + } else { + gameName = "oldSavegame"; + } + // string description; + description = + gameSettingsNode->getAttribute("description")->getValue(); + // string map; + map = gameSettingsNode->getAttribute("map")->getValue(); + // string tileset; + tileset = gameSettingsNode->getAttribute("tileset")->getValue(); + // string tech; + tech = gameSettingsNode->getAttribute("tech")->getValue(); + // string scenario; + scenario = gameSettingsNode->getAttribute("scenario")->getValue(); + // string scenarioDir; + scenarioDir = + gameSettingsNode->getAttribute("scenarioDir")->getValue(); + if (fileExists(scenarioDir) == false) { + scenarioDir = Config::findValidLocalFileFromPath(scenarioDir); + } + + // string factionTypeNames[GameConstants::maxPlayers]; //faction names + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + const XmlNode * + factionTypeNamesNode = + gameSettingsNode->getChild("factionTypeNames", idx); + factionTypeNames[idx] = + factionTypeNamesNode->getAttribute("name")->getValue(); + } + + // string networkPlayerNames[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + const XmlNode * + networkPlayerNamesNode = + gameSettingsNode->getChild("networkPlayerNames", idx); + networkPlayerNames[idx] = + networkPlayerNamesNode->getAttribute("name")->getValue(); + } + + // int networkPlayerStatuses[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + const XmlNode * + networkPlayerStatusesNode = + gameSettingsNode->getChild("networkPlayerStatuses", idx); + networkPlayerStatuses[idx] = + networkPlayerStatusesNode->getAttribute("status")-> + getIntValue(); + } + + // int networkPlayerStatuses[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + if (gameSettingsNode-> + hasChildAtIndex("networkPlayerGameStatus", idx) == true) { + const XmlNode * + networkPlayerGameStatusNode = + gameSettingsNode->getChild("networkPlayerGameStatus", idx); + networkPlayerGameStatus[idx] = + networkPlayerGameStatusNode->getAttribute("game_status")-> + getIntValue(); + } + } + + // string networkPlayerLanguages[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + const XmlNode * + networkPlayerLanguagesNode = + gameSettingsNode->getChild("networkPlayerLanguages", idx); + networkPlayerLanguages[idx] = + networkPlayerLanguagesNode->getAttribute("name")->getValue(); + } + + // ControlType factionControls[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + const XmlNode * + factionControlsNode = + gameSettingsNode->getChild("factionControls", idx); + factionControls[idx] = + static_cast + (factionControlsNode->getAttribute("control")->getIntValue()); + } + + // int resourceMultiplierIndex[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + const XmlNode * + resourceMultiplierIndexNode = + gameSettingsNode->getChild("resourceMultiplierIndex", idx); + resourceMultiplierIndex[idx] = + resourceMultiplierIndexNode->getAttribute("multiplier")-> + getIntValue(); + } + + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + if (gameSettingsNode-> + hasChildAtIndex("networkPlayerUUID", idx) == true) { + const XmlNode * + networkPlayerUUIDNode = + gameSettingsNode->getChild("networkPlayerUUID", idx); + networkPlayerUUID[idx] = + networkPlayerUUIDNode->getAttribute("value")->getValue(); + } + } + + // int thisFactionIndex; + thisFactionIndex = + gameSettingsNode->getAttribute("thisFactionIndex")->getIntValue(); + // int factionCount; + factionCount = + gameSettingsNode->getAttribute("factionCount")->getIntValue(); + // int teams[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + const XmlNode * + teamsNode = gameSettingsNode->getChild("teams", idx); + teams[idx] = teamsNode->getAttribute("team")->getIntValue(); + } + + // int startLocationIndex[GameConstants::maxPlayers]; + for (int idx = 0; idx < GameConstants::maxPlayers; idx++) { + const XmlNode * + startLocationIndexNode = + gameSettingsNode->getChild("startLocationIndex", idx); + startLocationIndex[idx] = + startLocationIndexNode->getAttribute("location")-> + getIntValue(); + } + + // int mapFilterIndex; + mapFilter = + gameSettingsNode->getAttribute("mapFilterIndex")->getIntValue(); + // + // + // bool defaultUnits; + defaultUnits = + gameSettingsNode->getAttribute("defaultUnits")->getIntValue() != + 0; + // bool defaultResources; + defaultResources = + gameSettingsNode->getAttribute("defaultResources")-> + getIntValue() != 0; + // bool defaultVictoryConditions; + defaultVictoryConditions = + gameSettingsNode->getAttribute("defaultVictoryConditions")-> + getIntValue() != 0; + // bool fogOfWar; + fogOfWar = + gameSettingsNode->getAttribute("fogOfWar")->getIntValue() != 0; + // bool allowObservers; + allowObservers = + gameSettingsNode->getAttribute("allowObservers")->getIntValue() != + 0; + // bool enableObserverModeAtEndGame; + enableObserverModeAtEndGame = + gameSettingsNode->getAttribute("enableObserverModeAtEndGame")-> + getIntValue() != 0; + // bool enableServerControlledAI; + enableServerControlledAI = + gameSettingsNode->getAttribute("enableServerControlledAI")-> + getIntValue() != 0; + // int networkFramePeriod; + networkFramePeriod = + gameSettingsNode->getAttribute("networkFramePeriod")-> + getIntValue(); + // bool networkPauseGameForLaggedClients; + networkPauseGameForLaggedClients = + gameSettingsNode-> + getAttribute("networkPauseGameForLaggedClients")->getIntValue() != + 0; + // PathFinderType pathFinderType; + pathFinderType = + static_cast + (gameSettingsNode->getAttribute("pathFinderType")->getIntValue()); + // uint32 flagTypes1; + flagTypes1 = + gameSettingsNode->getAttribute("flagTypes1")->getUIntValue(); + // int32 mapCRC; + mapCRC = gameSettingsNode->getAttribute("mapCRC")->getUIntValue(); + // int32 tilesetCRC; + tilesetCRC = + gameSettingsNode->getAttribute("tilesetCRC")->getUIntValue(); + // int32 techCRC; + techCRC = gameSettingsNode->getAttribute("techCRC")->getUIntValue(); + // vector > factionCRCList; + // for(unsigned int i = 0; i < factionCRCList.size(); ++i) { + // const pair &item = factionCRCList[i]; + // + // XmlNode *factionCRCListNode = gameSettingsNode->addChild("factionCRCList"); + // factionCRCListNode->addAttribute("key",item.first, mapTagReplacements); + // factionCRCListNode->addAttribute("value",intToStr(item.second), mapTagReplacements); + // } + // int aiAcceptSwitchTeamPercentChance; + aiAcceptSwitchTeamPercentChance = + gameSettingsNode->getAttribute("aiAcceptSwitchTeamPercentChance")-> + getIntValue(); + // int masterserver_admin; + masterserver_admin = + gameSettingsNode->getAttribute("masterserver_admin")-> + getIntValue(); + + if (gameSettingsNode-> + hasAttribute("masterserver_admin_factionIndex") == true) { + masterserver_admin_factionIndex = + gameSettingsNode-> + getAttribute("masterserver_admin_factionIndex")-> + getIntValue(); + } + + if (gameSettingsNode-> + hasAttribute("networkAllowNativeLanguageTechtree") == true) { + networkAllowNativeLanguageTechtree = + gameSettingsNode-> + getAttribute("networkAllowNativeLanguageTechtree")-> + getIntValue() != 0; + } + } + + }; + + } } //end namespace #endif diff --git a/source/glest_game/game/script_manager.cpp b/source/glest_game/game/script_manager.cpp index ffda30484..2f337643a 100644 --- a/source/glest_game/game/script_manager.cpp +++ b/source/glest_game/game/script_manager.cpp @@ -20,7232 +20,6325 @@ #include "leak_dumper.h" using namespace - Shared::Platform; +Shared::Platform; using namespace - Shared::Lua; +Shared::Lua; using namespace - Shared::Util; +Shared::Util; namespace - Glest -{ - namespace - Game - { - - ScriptManagerMessage::ScriptManagerMessage (): - text (""), - header ("") - { - this->factionIndex = -1; - this-> - teamIndex = -1; - this-> - messageNotTranslated = true; - } - - ScriptManagerMessage::ScriptManagerMessage (const string & textIn, - const string & headerIn, - int factionIndex, - int teamIndex, - bool messageNotTranslated): - text (textIn), - header (headerIn) - { - this->factionIndex = factionIndex; - this-> - teamIndex = teamIndex; - this-> - messageNotTranslated = messageNotTranslated; - } - - void - ScriptManagerMessage::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode * - scriptManagerMessageNode = - rootNode->addChild ("ScriptManagerMessage"); - - //string text; - scriptManagerMessageNode->addAttribute ("text", text, - mapTagReplacements); - //string header; - scriptManagerMessageNode->addAttribute ("header", header, - mapTagReplacements); - scriptManagerMessageNode->addAttribute ("factionIndex", - intToStr (factionIndex), - mapTagReplacements); - scriptManagerMessageNode->addAttribute ("teamIndex", - intToStr (teamIndex), - mapTagReplacements); - scriptManagerMessageNode->addAttribute ("messageNotTranslated", - intToStr (messageNotTranslated), - mapTagReplacements); - } - - void - ScriptManagerMessage::loadGame (const XmlNode * rootNode) - { - const XmlNode * - scriptManagerMessageNode = rootNode; - - text = scriptManagerMessageNode->getAttribute ("text")->getValue (); - header = scriptManagerMessageNode->getAttribute ("header")->getValue (); - factionIndex = - scriptManagerMessageNode->getAttribute ("factionIndex")-> - getIntValue (); - teamIndex = - scriptManagerMessageNode->getAttribute ("teamIndex")->getIntValue (); - - messageNotTranslated = true; - if (scriptManagerMessageNode->hasAttribute ("messageNotTranslated") == - true) - { - messageNotTranslated = - (scriptManagerMessageNode->getAttribute ("messageNotTranslated")-> - getIntValue () != 0); - } - } - -// ===================================================== -// class PlayerModifiers -// ===================================================== - - PlayerModifiers::PlayerModifiers () - { - winner = false; - aiEnabled = true; - consumeEnabled = true; - } - - void - PlayerModifiers::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode * - playerModifiersNode = rootNode->addChild ("PlayerModifiers"); - - //bool winner; - playerModifiersNode->addAttribute ("winner", intToStr (winner), - mapTagReplacements); - //bool aiEnabled; - playerModifiersNode->addAttribute ("aiEnabled", intToStr (aiEnabled), - mapTagReplacements); - //bool consumeEnabled; - playerModifiersNode->addAttribute ("consumeEnabled", - intToStr (consumeEnabled), - mapTagReplacements); - } - - void - PlayerModifiers::loadGame (const XmlNode * rootNode) - { - const XmlNode * - playerModifiersNode = rootNode; - - winner = - playerModifiersNode->getAttribute ("winner")->getIntValue () != 0; - aiEnabled = - playerModifiersNode->getAttribute ("aiEnabled")->getIntValue () != 0; - consumeEnabled = - playerModifiersNode->getAttribute ("consumeEnabled")-> - getIntValue () != 0; - } - - CellTriggerEvent::CellTriggerEvent () - { - type = ctet_Unit; - sourceId = 0; - destId = 0; - //Vec2i destPos; - - triggerCount = 0; - } - - void - CellTriggerEvent::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode * - cellTriggerEventNode = rootNode->addChild ("CellTriggerEvent"); - -// CellTriggerEventType type; - cellTriggerEventNode->addAttribute ("type", intToStr (type), - mapTagReplacements); -// int sourceId; - cellTriggerEventNode->addAttribute ("sourceId", intToStr (sourceId), - mapTagReplacements); -// int destId; - cellTriggerEventNode->addAttribute ("destId", intToStr (destId), - mapTagReplacements); -// Vec2i destPos; - cellTriggerEventNode->addAttribute ("destPos", destPos.getString (), - mapTagReplacements); -// int triggerCount; - cellTriggerEventNode->addAttribute ("triggerCount", - intToStr (triggerCount), - mapTagReplacements); - -// Vec2i destPosEnd; - cellTriggerEventNode->addAttribute ("destPosEnd", - destPosEnd.getString (), - mapTagReplacements); - } - - void - CellTriggerEvent::loadGame (const XmlNode * rootNode) - { - const XmlNode * - cellTriggerEventNode = rootNode->getChild ("CellTriggerEvent"); - - type = - static_cast < CellTriggerEventType > - (cellTriggerEventNode->getAttribute ("type")->getIntValue ()); - sourceId = - cellTriggerEventNode->getAttribute ("sourceId")->getIntValue (); - destId = cellTriggerEventNode->getAttribute ("destId")->getIntValue (); - destPos = - Vec2i::strToVec2 (cellTriggerEventNode->getAttribute ("destPos")-> - getValue ()); - triggerCount = - cellTriggerEventNode->getAttribute ("triggerCount")->getIntValue (); - - if (cellTriggerEventNode->hasAttribute ("destPosEnd") == true) - { - destPosEnd = - Vec2i::strToVec2 (cellTriggerEventNode-> - getAttribute ("destPosEnd")->getValue ()); - } - } - - TimerTriggerEvent::TimerTriggerEvent () - { - running = false; - startFrame = 0; - endFrame = 0; - triggerSecondsElapsed = 0; - } - - void - TimerTriggerEvent::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode * - timerTriggerEventNode = rootNode->addChild ("TimerTriggerEvent"); - -// bool running; - timerTriggerEventNode->addAttribute ("running", intToStr (running), - mapTagReplacements); -// //time_t startTime; -// //time_t endTime; -// int startFrame; - timerTriggerEventNode->addAttribute ("startFrame", - intToStr (startFrame), - mapTagReplacements); -// int endFrame; - timerTriggerEventNode->addAttribute ("endFrame", intToStr (endFrame), - mapTagReplacements); - - if (triggerSecondsElapsed > 0) - { - timerTriggerEventNode->addAttribute ("triggerSecondsElapsed", - intToStr - (triggerSecondsElapsed), - mapTagReplacements); - } - } - - void - TimerTriggerEvent::loadGame (const XmlNode * rootNode) - { - const XmlNode * - timerTriggerEventNode = rootNode->getChild ("TimerTriggerEvent"); - - running = - timerTriggerEventNode->getAttribute ("running")->getIntValue () != 0; - startFrame = - timerTriggerEventNode->getAttribute ("startFrame")->getIntValue (); - endFrame = - timerTriggerEventNode->getAttribute ("endFrame")->getIntValue (); - if (timerTriggerEventNode->hasAttribute ("triggerSecondsElapsed") == - true) - { - triggerSecondsElapsed = - timerTriggerEventNode->getAttribute ("triggerSecondsElapsed")-> - getIntValue (); - } - } - -// ===================================================== -// class ScriptManager -// ===================================================== - ScriptManager * - ScriptManager::thisScriptManager = NULL; - const int - ScriptManager::messageWrapCount = 35; - const int - ScriptManager::displayTextWrapCount = 64; - - ScriptManager::ScriptManager () - { - world = NULL; - gameCamera = NULL; - lastCreatedUnitId = -1; - lastDeadUnitId = 0; - lastDeadUnitCauseOfDeath = 0; - lastDeadUnitKillerId = 0; - lastAttackedUnitId = 0; - lastAttackingUnitId = 0; - gameOver = false; - gameWon = false; - currentTimerTriggeredEventId = 0; - currentCellTriggeredEventId = 0; - currentCellTriggeredEventUnitId = 0; - currentEventId = 0; - inCellTriggerEvent = false; - rootNode = NULL; - currentCellTriggeredEventAreaEntryUnitId = 0; - currentCellTriggeredEventAreaExitUnitId = 0; - lastDayNightTriggerStatus = 0; - registeredDayNightEvent = false; - errorCount = 0; - - lastUnitTriggerEventUnitId = -1; - lastUnitTriggerEventType = utet_None; - } - - ScriptManager::~ScriptManager () - { - - } - - void - ScriptManager::init (World * world, GameCamera * gameCamera, - const XmlNode * rootNode) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - //printf("In [%s::%s Line: %d] rootNode [%p][%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,rootNode,(rootNode != NULL ? rootNode->getName().c_str() : "none")); - this->rootNode = rootNode; - const Scenario * - scenario = world->getScenario (); - - this->world = world; - this->gameCamera = gameCamera; - - //set static instance - thisScriptManager = this; - - //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - currentEventId = 1; - CellTriggerEventList.clear (); - TimerTriggerEventList.clear (); - - //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //register functions - luaScript.registerFunction (networkShowMessageForFaction, - "networkShowMessageForFaction"); - luaScript.registerFunction (networkShowMessageForTeam, - "networkShowMessageForTeam"); - - luaScript.registerFunction (networkSetCameraPositionForFaction, - "networkSetCameraPositionForFaction"); - luaScript.registerFunction (networkSetCameraPositionForTeam, - "networkSetCameraPositionForTeam"); - - luaScript.registerFunction (showMessage, "showMessage"); - luaScript.registerFunction (setDisplayText, "setDisplayText"); - luaScript.registerFunction (addConsoleText, "addConsoleText"); - luaScript.registerFunction (addConsoleLangText, "addConsoleLangText"); - luaScript.registerFunction (DisplayFormattedText, - "DisplayFormattedText"); - luaScript.registerFunction (DisplayFormattedText, - "displayFormattedText"); - luaScript.registerFunction (DisplayFormattedLangText, - "DisplayFormattedLangText"); - luaScript.registerFunction (DisplayFormattedLangText, - "displayFormattedLangText"); - luaScript.registerFunction (clearDisplayText, "clearDisplayText"); - luaScript.registerFunction (setCameraPosition, "setCameraPosition"); - luaScript.registerFunction (shakeCamera, "shakeCamera"); - luaScript.registerFunction (shakeCameraOnUnit, "shakeCameraOnUnit"); - luaScript.registerFunction (createUnit, "createUnit"); - luaScript.registerFunction (createUnitNoSpacing, "createUnitNoSpacing"); - luaScript.registerFunction (setLockedUnitForFaction, - "setLockedUnitForFaction"); - luaScript.registerFunction (destroyUnit, "destroyUnit"); - luaScript.registerFunction (giveKills, "giveKills"); - luaScript.registerFunction (morphToUnit, "morphToUnit"); - luaScript.registerFunction (moveToUnit, "moveToUnit"); - - luaScript.registerFunction (playStaticSound, "playStaticSound"); - luaScript.registerFunction (playStreamingSound, "playStreamingSound"); - luaScript.registerFunction (stopStreamingSound, "stopStreamingSound"); - luaScript.registerFunction (stopAllSound, "stopAllSound"); - luaScript.registerFunction (togglePauseGame, "togglePauseGame"); - - luaScript.registerFunction (playStaticVideo, "playStaticVideo"); - //luaScript.registerFunction(playStreamingVideo, "playStreamingVideo"); - //luaScript.registerFunction(stopStreamingVideo, "stopStreamingVideo"); - luaScript.registerFunction (stopAllVideo, "stopAllVideo"); - - luaScript.registerFunction (giveResource, "giveResource"); - luaScript.registerFunction (givePositionCommand, "givePositionCommand"); - luaScript.registerFunction (giveProductionCommand, - "giveProductionCommand"); - luaScript.registerFunction (giveAttackCommand, "giveAttackCommand"); - luaScript.registerFunction (giveUpgradeCommand, "giveUpgradeCommand"); - luaScript.registerFunction (giveAttackStoppedCommand, - "giveAttackStoppedCommand"); - luaScript.registerFunction (disableAi, "disableAi"); - luaScript.registerFunction (enableAi, "enableAi"); - luaScript.registerFunction (getAiEnabled, "getAiEnabled"); - luaScript.registerFunction (disableConsume, "disableConsume"); - luaScript.registerFunction (enableConsume, "enableConsume"); - luaScript.registerFunction (getConsumeEnabled, "getConsumeEnabled"); - luaScript.registerFunction (setPlayerAsWinner, "setPlayerAsWinner"); - luaScript.registerFunction (endGame, "endGame"); - - luaScript.registerFunction (startPerformanceTimer, - "startPerformanceTimer"); - luaScript.registerFunction (endPerformanceTimer, "endPerformanceTimer"); - luaScript.registerFunction (getPerformanceTimerResults, - "getPerformanceTimerResults"); - - luaScript.registerFunction (registerCellTriggerEventForUnitToUnit, - "registerCellTriggerEventForUnitToUnit"); - luaScript.registerFunction (registerCellTriggerEventForUnitToLocation, - "registerCellTriggerEventForUnitToLocation"); - luaScript.registerFunction (registerCellTriggerEventForFactionToUnit, - "registerCellTriggerEventForFactionToUnit"); - luaScript. - registerFunction (registerCellTriggerEventForFactionToLocation, - "registerCellTriggerEventForFactionToLocation"); - - luaScript. - registerFunction (registerCellAreaTriggerEventForUnitToLocation, - "registerCellAreaTriggerEventForUnitToLocation"); - luaScript. - registerFunction (registerCellAreaTriggerEventForFactionToLocation, - "registerCellAreaTriggerEventForFactionToLocation"); - luaScript.registerFunction (registerCellAreaTriggerEvent, - "registerCellAreaTriggerEvent"); - - luaScript.registerFunction (getCellTriggerEventCount, - "getCellTriggerEventCount"); - luaScript.registerFunction (unregisterCellTriggerEvent, - "unregisterCellTriggerEvent"); - luaScript.registerFunction (startTimerEvent, "startTimerEvent"); - luaScript.registerFunction (startEfficientTimerEvent, - "startEfficientTimerEvent"); - luaScript.registerFunction (resetTimerEvent, "resetTimerEvent"); - luaScript.registerFunction (stopTimerEvent, "stopTimerEvent"); - luaScript.registerFunction (getTimerEventSecondsElapsed, - "timerEventSecondsElapsed"); - luaScript.registerFunction (getCellTriggeredEventId, - "triggeredCellEventId"); - luaScript.registerFunction (getTimerTriggeredEventId, - "triggeredTimerEventId"); - - luaScript.registerFunction (getCellTriggeredEventAreaEntryUnitId, - "triggeredEventAreaEntryUnitId"); - luaScript.registerFunction (getCellTriggeredEventAreaExitUnitId, - "triggeredEventAreaExitUnitId"); - - luaScript.registerFunction (getCellTriggeredEventUnitId, - "triggeredCellEventUnitId"); - - luaScript.registerFunction (setRandomGenInit, "setRandomGenInit"); - luaScript.registerFunction (getRandomGen, "getRandomGen"); - luaScript.registerFunction (getWorldFrameCount, "getWorldFrameCount"); - - luaScript.registerFunction (getStartLocation, "startLocation"); - luaScript.registerFunction (getIsUnitAlive, "isUnitAlive"); - luaScript.registerFunction (getUnitPosition, "unitPosition"); - luaScript.registerFunction (setUnitPosition, "setUnitPosition"); - - luaScript.registerFunction (addCellMarker, "addCellMarker"); - luaScript.registerFunction (removeCellMarker, "removeCellMarker"); - luaScript.registerFunction (showMarker, "showMarker"); - - luaScript.registerFunction (getUnitFaction, "unitFaction"); - luaScript.registerFunction (getUnitName, "unitName"); - luaScript.registerFunction (getResourceAmount, "resourceAmount"); - - luaScript.registerFunction (getLastCreatedUnitName, - "lastCreatedUnitName"); - luaScript.registerFunction (getLastCreatedUnitId, "lastCreatedUnit"); - - luaScript.registerFunction (getLastDeadUnitName, "lastDeadUnitName"); - luaScript.registerFunction (getLastDeadUnitId, "lastDeadUnit"); - luaScript.registerFunction (getLastDeadUnitCauseOfDeath, - "lastDeadUnitCauseOfDeath"); - luaScript.registerFunction (getLastDeadUnitKillerName, - "lastDeadUnitKillerName"); - luaScript.registerFunction (getLastDeadUnitKillerId, - "lastDeadUnitKiller"); - - luaScript.registerFunction (getLastAttackedUnitName, - "lastAttackedUnitName"); - luaScript.registerFunction (getLastAttackedUnitId, "lastAttackedUnit"); - - luaScript.registerFunction (getLastAttackingUnitName, - "lastAttackingUnitName"); - luaScript.registerFunction (getLastAttackingUnitId, - "lastAttackingUnit"); - - luaScript.registerFunction (getUnitCount, "unitCount"); - luaScript.registerFunction (getUnitCountOfType, "unitCountOfType"); - - luaScript.registerFunction (getIsGameOver, "isGameOver"); - luaScript.registerFunction (getGameWon, "gameWon"); - - luaScript.registerFunction (getSystemMacroValue, "getSystemMacroValue"); - luaScript.registerFunction (scenarioDir, "scenarioDir"); - luaScript.registerFunction (getPlayerName, "getPlayerName"); - luaScript.registerFunction (getPlayerName, "playerName"); - - luaScript.registerFunction (loadScenario, "loadScenario"); - - luaScript.registerFunction (getUnitsForFaction, "getUnitsForFaction"); - luaScript.registerFunction (getUnitCurrentField, "getUnitCurrentField"); - - luaScript.registerFunction (isFreeCellsOrHasUnit, - "isFreeCellsOrHasUnit"); - luaScript.registerFunction (isFreeCells, "isFreeCells"); - - luaScript.registerFunction (getHumanFactionId, "humanFaction"); - - luaScript.registerFunction (highlightUnit, "highlightUnit"); - luaScript.registerFunction (unhighlightUnit, "unhighlightUnit"); - - luaScript.registerFunction (giveStopCommand, "giveStopCommand"); - luaScript.registerFunction (selectUnit, "selectUnit"); - luaScript.registerFunction (unselectUnit, "unselectUnit"); - luaScript.registerFunction (addUnitToGroupSelection, - "addUnitToGroupSelection"); - luaScript.registerFunction (recallGroupSelection, - "recallGroupSelection"); - luaScript.registerFunction (removeUnitFromGroupSelection, - "removeUnitFromGroupSelection"); - luaScript.registerFunction (setAttackWarningsEnabled, - "setAttackWarningsEnabled"); - luaScript.registerFunction (getAttackWarningsEnabled, - "getAttackWarningsEnabled"); - - luaScript.registerFunction (getIsDayTime, "getIsDayTime"); - luaScript.registerFunction (getIsNightTime, "getIsNightTime"); - luaScript.registerFunction (getTimeOfDay, "getTimeOfDay"); - luaScript.registerFunction (registerDayNightEvent, - "registerDayNightEvent"); - luaScript.registerFunction (unregisterDayNightEvent, - "unregisterDayNightEvent"); - - luaScript.registerFunction (registerUnitTriggerEvent, - "registerUnitTriggerEvent"); - luaScript.registerFunction (unregisterUnitTriggerEvent, - "unregisterUnitTriggerEvent"); - luaScript.registerFunction (getLastUnitTriggerEventUnitId, - "lastUnitTriggerEventUnit"); - luaScript.registerFunction (getLastUnitTriggerEventType, - "lastUnitTriggerEventType"); - luaScript.registerFunction (getUnitProperty, "getUnitProperty"); - luaScript.registerFunction (getUnitPropertyName, "getUnitPropertyName"); - luaScript.registerFunction (disableSpeedChange, "disableSpeedChange"); - luaScript.registerFunction (enableSpeedChange, "enableSpeedChange"); - luaScript.registerFunction (getSpeedChangeEnabled, - "getSpeedChangeEnabled"); - - luaScript.registerFunction (storeSaveGameData, "storeSaveGameData"); - luaScript.registerFunction (loadSaveGameData, "loadSaveGameData"); - - luaScript.registerFunction (getFactionPlayerType, - "getFactionPlayerType"); - - //load code - for (int i = 0; i < scenario->getScriptCount (); ++i) - { - const Script * - script = scenario->getScript (i); - luaScript.loadCode ("function " + script->getName () + "()" + - script->getCode () + "end\n", - script->getName ()); - } - - - //!!! -// string data_path= getGameReadWritePath(GameConstants::path_data_CacheLookupKey); -// if(data_path != ""){ -// endPathWithSlash(data_path); -// } -// string sandboxScriptFilename = data_path + "data/core/scripts/sandbox.lua"; -// string sandboxLuaCode = getFileTextContents(sandboxScriptFilename); -// -// //luaScript.loadCode(sandboxLuaCode + "\n", "megaglest_lua_sandbox"); -// luaScript.setSandboxWrapperFunctionName("runsandboxed"); -// luaScript.setSandboxCode(sandboxLuaCode); -// luaScript.runCode(sandboxLuaCode); - -// // Setup the lua security sandbox here -// luaScript.beginCall("megaglest_lua_sandbox"); -// luaScript.endCall(); - - //setup message box - messageBox.init (Lang::getInstance ().getString ("Ok")); - messageBox.setEnabled (false); - //messageBox.setAutoWordWrap(false); - - //last created unit - lastCreatedUnitId = -1; - lastDeadUnitName = ""; - lastDeadUnitId = -1; - lastDeadUnitCauseOfDeath = ucodNone; - lastDeadUnitKillerName = ""; - lastDeadUnitKillerId = -1; - - lastAttackedUnitName = ""; - lastAttackedUnitId = -1; - lastAttackingUnitName = ""; - lastAttackingUnitId = -1; - - gameOver = false; - gameWon = false; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - try - { - // Setup global functions and vars here - luaScript.beginCall ("global"); - luaScript.endCall (); - - //call startup function - if (this->rootNode == NULL) - { - luaScript.beginCall ("startup"); - luaScript.endCall (); - } - else - { - loadGame (this->rootNode); - this->rootNode = NULL; - - if (LuaScript::getDebugModeEnabled () == true) - printf ("Calling onLoad luaSavedGameData.size() = %d\n", - (int) luaSavedGameData.size ()); - - luaScript.beginCall ("onLoad"); - luaScript.endCall (); - } - } - catch (const megaglest_runtime_error & ex) - { - //string sErrBuf = ""; - //if(ex.wantStackTrace() == true) { - char - szErrBuf[8096] = ""; - //snprintf(szErrBuf,8096,"In [%s::%s %d]",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - string - sErrBuf = - string (szErrBuf) + - string ("The game may no longer be stable!\n\n\t [") + - string (ex.what ()) + string ("]\n"); - //} - SystemFlags::OutputDebug (SystemFlags::debugError, sErrBuf.c_str ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - sErrBuf.c_str ()); - - thisScriptManager-> - addMessageToQueue (ScriptManagerMessage - (sErrBuf.c_str (), "error", -1, -1, true)); - thisScriptManager->onMessageBoxOk (false); - } - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } - -// ========================== events =============================================== - - void - ScriptManager::onMessageBoxOk (bool popFront) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - Lang & lang = Lang::getInstance (); - - for (int index = 0; messageQueue.empty () == false; ++index) - { - //printf("i = %d messageQueue.size() = %d popFront = %d\n",i,messageQueue.size(),popFront); - if (popFront == true) - { - messageQueue.pop_front (); - } - if (messageQueue.empty () == false) - { -// printf("onMessageBoxOk [%s] factionIndex = %d [%d] teamIndex = %d [%d][%d]\n", -// wrapString(lang.getScenarioString(messageQueue.front().getText()), messageWrapCount).c_str(), -// messageQueue.front().getFactionIndex(), this->world->getThisFactionIndex(), -// messageQueue.front().getTeamIndex(),this->world->getThisTeamIndex(),this->world->getThisFaction()->getTeam()); - - if ((messageQueue.front ().getFactionIndex () < 0 - && messageQueue.front ().getTeamIndex () < 0) - || messageQueue.front ().getFactionIndex () == - this->world->getThisFactionIndex () - || messageQueue.front ().getTeamIndex () == - this->world->getThisTeamIndex ()) - { - - messageBox.setEnabled (true); - - string - msgText = messageQueue.front ().getText (); - string - msgHeader = messageQueue.front ().getHeader (); - if (messageQueue.front ().getMessageNotTranslated () == - false) - { - - msgText = - lang.getScenarioString (messageQueue.front (). - getText ()); - msgHeader = - lang.getScenarioString (messageQueue.front (). - getHeader ()); - } - messageBox.setText (msgText); - messageBox.setHeader (msgHeader); - break; - } - popFront = true; - } - } - } - - void - ScriptManager::onResourceHarvested () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (this->rootNode == NULL) - { - luaScript.beginCall ("resourceHarvested"); - luaScript.endCall (); - } - } - - void - ScriptManager::onUnitCreated (const Unit * unit) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (this->rootNode == NULL) - { - lastCreatedUnitName = unit->getType ()->getName (false); - lastCreatedUnitId = unit->getId (); - luaScript.beginCall ("unitCreated"); - luaScript.endCall (); - luaScript.beginCall ("unitCreatedOfType_" + - unit->getType ()->getName ()); - luaScript.endCall (); - } - } - - void - ScriptManager::onUnitDied (const Unit * unit) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (this->rootNode == NULL) - { - if (unit->getLastAttackerUnitId () >= 0) - { - Unit * - killer = world->findUnitById (unit->getLastAttackerUnitId ()); - - if (killer != NULL) - { - lastAttackingUnitName = killer->getType ()->getName (false); - lastAttackingUnitId = killer->getId (); - - lastDeadUnitKillerName = - killer->getType ()->getName (false); - lastDeadUnitKillerId = killer->getId (); - } - else - { - lastDeadUnitKillerName = ""; - lastDeadUnitKillerId = -1; - } - } - - lastAttackedUnitName = unit->getType ()->getName (false); - lastAttackedUnitId = unit->getId (); - - lastDeadUnitName = unit->getType ()->getName (false); - lastDeadUnitId = unit->getId (); - lastDeadUnitCauseOfDeath = unit->getCauseOfDeath (); - - luaScript.beginCall ("unitDied"); - luaScript.endCall (); - } - } - - void - ScriptManager::onUnitAttacked (const Unit * unit) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (this->rootNode == NULL) - { - lastAttackedUnitName = unit->getType ()->getName (false); - lastAttackedUnitId = unit->getId (); - luaScript.beginCall ("unitAttacked"); - luaScript.endCall (); - } - } - - void - ScriptManager::onUnitAttacking (const Unit * unit) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (this->rootNode == NULL) - { - lastAttackingUnitName = unit->getType ()->getName (false); - lastAttackingUnitId = unit->getId (); - luaScript.beginCall ("unitAttacking"); - luaScript.endCall (); - } - } - - void - ScriptManager::onGameOver (bool won) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - gameWon = won; - luaScript.beginCall ("gameOver"); - luaScript.endCall (); - } - - void - ScriptManager::onTimerTriggerEvent () - { - if (TimerTriggerEventList.empty () == true) - { - return; - } - if (this->rootNode != NULL) - { - return; - } - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] TimerTriggerEventList.size() = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - TimerTriggerEventList.size ()); - - for (std::map < int, TimerTriggerEvent >::iterator iterMap = - TimerTriggerEventList.begin (); - iterMap != TimerTriggerEventList.end (); ++iterMap) - { - - TimerTriggerEvent & event = iterMap->second; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] event.running = %d, event.startTime = %lld, event.endTime = %lld, diff = %f\n", - __FILE__, __FUNCTION__, __LINE__, - event.running, - (long long int) event.startFrame, - (long long int) event.endFrame, - (event.endFrame - event.startFrame)); - - if (event.running == true) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - // If using an efficient timer, check if its time to trigger - // on the elapsed check - if (event.triggerSecondsElapsed > 0) - { - int - elapsed = - (world->getFrameCount () - - event.startFrame) / GameConstants::updateFps; - if (elapsed < event.triggerSecondsElapsed) - { - continue; - } - } - currentTimerTriggeredEventId = iterMap->first; - luaScript.beginCall ("timerTriggerEvent"); - luaScript.endCall (); - - if (event.triggerSecondsElapsed > 0) - { - int - timerId = iterMap->first; - stopTimerEvent (timerId); - } - } - } - } - - void - ScriptManager::onCellTriggerEvent (Unit * movingUnit) - { - if (CellTriggerEventList.empty () == true) - { - return; - } - if (this->rootNode != NULL) - { - return; - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] movingUnit = %p, CellTriggerEventList.size() = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - movingUnit, CellTriggerEventList.size ()); - - // remove any delayed removals - unregisterCellTriggerEvent (-1); - - inCellTriggerEvent = true; - if (movingUnit != NULL) - { - //ScenarioInfo scenarioInfoStart = world->getScenario()->getInfo(); - - for (std::map < int, CellTriggerEvent >::iterator iterMap = - CellTriggerEventList.begin (); - iterMap != CellTriggerEventList.end (); ++iterMap) - { - CellTriggerEvent & event = iterMap->second; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] movingUnit = %d, event.type = %d, movingUnit->getPos() = %s, event.sourceId = %d, event.destId = %d, event.destPos = %s\n", - __FILE__, __FUNCTION__, __LINE__, - movingUnit->getId (), event.type, - movingUnit->getPos ().getString (). - c_str (), event.sourceId, - event.destId, - event.destPos.getString (). - c_str ()); - - bool - triggerEvent = false; - currentCellTriggeredEventAreaEntryUnitId = 0; - currentCellTriggeredEventAreaExitUnitId = 0; - currentCellTriggeredEventUnitId = 0; - - switch (event.type) - { - case ctet_Unit: - { - Unit * - destUnit = world->findUnitById (event.destId); - if (destUnit != NULL) - { - if (movingUnit->getId () == event.sourceId) - { - bool - srcInDst = - world->getMap ()->isInUnitTypeCells (destUnit-> - getType (), - destUnit-> - getPos (), - movingUnit-> - getPos ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] movingUnit = %d, event.type = %d, movingUnit->getPos() = %s, event.sourceId = %d, event.destId = %d, event.destPos = %s, destUnit->getPos() = %s, srcInDst = %d\n", - __FILE__, - __FUNCTION__, - __LINE__, - movingUnit->getId (), - event.type, - movingUnit->getPos (). - getString ().c_str (), - event.sourceId, - event.destId, - event.destPos. - getString ().c_str (), - destUnit->getPos (). - getString ().c_str (), - srcInDst); - - if (srcInDst == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags:: - debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__). - c_str (), - __FUNCTION__, - __LINE__); - } - else - { - srcInDst = - world->getMap ()-> - isNextToUnitTypeCells (destUnit->getType (), - destUnit->getPos (), - movingUnit-> - getPos ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags:: - debugLUA, - "In [%s::%s Line: %d] movingUnit = %d, event.type = %d, movingUnit->getPos() = %s, event.sourceId = %d, event.destId = %d, event.destPos = %s, destUnit->getPos() = %s, srcInDst = %d\n", - __FILE__, - __FUNCTION__, - __LINE__, - movingUnit-> - getId (), - event.type, - movingUnit-> - getPos (). - getString (). - c_str (), - event.sourceId, - event.destId, - event.destPos. - getString (). - c_str (), - destUnit-> - getPos (). - getString (). - c_str (), - srcInDst); - } - triggerEvent = srcInDst; - if (triggerEvent == true) - { - currentCellTriggeredEventUnitId = - movingUnit->getId (); - } - } - } - } - break; - case ctet_UnitPos: - { - if (movingUnit->getId () == event.sourceId) - { - bool - srcInDst = - world->getMap ()->isInUnitTypeCells (movingUnit-> - getType (), - event.destPos, - movingUnit-> - getPos ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] movingUnit = %d, event.type = %d, movingUnit->getPos() = %s, event.sourceId = %d, event.destId = %d, event.destPos = %s, srcInDst = %d\n", - __FILE__, __FUNCTION__, - __LINE__, - movingUnit->getId (), - event.type, - movingUnit->getPos (). - getString ().c_str (), - event.sourceId, - event.destId, - event.destPos. - getString ().c_str (), - srcInDst); - - if (srcInDst == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, - __LINE__); - } - triggerEvent = srcInDst; - - if (triggerEvent == true) - { - currentCellTriggeredEventUnitId = - movingUnit->getId (); - } - } - } - break; - - case ctet_UnitAreaPos: - { - if (movingUnit->getId () == event.sourceId) - { - bool - srcInDst = false; - - // Cache area lookup so for each unitsize and pos its done only once - bool - foundInCache = false; - std::map < int, - std::map < - Vec2i, - bool > >::iterator - iterFind1 = - event.eventLookupCache.find (movingUnit-> - getType ()-> - getSize ()); - if (iterFind1 != event.eventLookupCache.end ()) - { - std::map < Vec2i, bool >::iterator iterFind2 = - iterFind1->second.find (movingUnit->getPos ()); - if (iterFind2 != iterFind1->second.end ()) - { - foundInCache = true; - srcInDst = iterFind2->second; - } - } - - if (foundInCache == false) - { - for (int x = event.destPos.x; - srcInDst == false && x <= event.destPosEnd.x; - ++x) - { - for (int y = event.destPos.y; - srcInDst == false - && y <= event.destPosEnd.y; ++y) - { - srcInDst = - world->getMap ()-> - isInUnitTypeCells (movingUnit-> - getType (), Vec2i (x, - y), - movingUnit-> - getPos ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags:: - debugLUA, - "In [%s::%s Line: %d] movingUnit = %d, event.type = %d, movingUnit->getPos() = %s, event.sourceId = %d, event.destId = %d, event.destPos = %s, srcInDst = %d\n", - __FILE__, - __FUNCTION__, - __LINE__, - movingUnit-> - getId (), - event.type, - movingUnit-> - getPos (). - getString (). - c_str (), - event. - sourceId, - event.destId, - Vec2i (x, - y). - getString (). - c_str (), - srcInDst); - } - } - - event.eventLookupCache[movingUnit->getType ()-> - getSize ()][movingUnit-> - getPos ()] = - srcInDst; - } - - if (srcInDst == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, - __LINE__); - } - triggerEvent = srcInDst; - if (triggerEvent == true) - { - currentCellTriggeredEventUnitId = - movingUnit->getId (); - } - } - } - break; - - case ctet_Faction: - { - Unit * - destUnit = world->findUnitById (event.destId); - if (destUnit != NULL && - movingUnit->getFactionIndex () == event.sourceId) - { - bool - srcInDst = - world->getMap ()->isInUnitTypeCells (destUnit-> - getType (), - destUnit-> - getPos (), - movingUnit-> - getPos ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] movingUnit = %d, event.type = %d, movingUnit->getPos() = %s, event.sourceId = %d, event.destId = %d, event.destPos = %s, srcInDst = %d\n", - __FILE__, __FUNCTION__, - __LINE__, - movingUnit->getId (), - event.type, - movingUnit->getPos (). - getString ().c_str (), - event.sourceId, - event.destId, - event.destPos. - getString ().c_str (), - srcInDst); - - if (srcInDst == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, - __LINE__); - } - else - { - srcInDst = - world->getMap ()-> - isNextToUnitTypeCells (destUnit->getType (), - destUnit->getPos (), - movingUnit->getPos ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] movingUnit = %d, event.type = %d, movingUnit->getPos() = %s, event.sourceId = %d, event.destId = %d, event.destPos = %s, destUnit->getPos() = %s, srcInDst = %d\n", - __FILE__, - __FUNCTION__, - __LINE__, - movingUnit->getId (), - event.type, - movingUnit->getPos (). - getString ().c_str (), - event.sourceId, - event.destId, - event.destPos. - getString ().c_str (), - destUnit->getPos (). - getString ().c_str (), - srcInDst); - } - triggerEvent = srcInDst; - if (triggerEvent == true) - { - currentCellTriggeredEventUnitId = - movingUnit->getId (); - } - } - } - break; - - case ctet_FactionPos: - { - if (movingUnit->getFactionIndex () == event.sourceId) - { - //printf("ctet_FactionPos event.destPos = [%s], movingUnit->getPos() [%s]\n",event.destPos.getString().c_str(),movingUnit->getPos().getString().c_str()); - - bool - srcInDst = - world->getMap ()->isInUnitTypeCells (movingUnit-> - getType (), - event.destPos, - movingUnit-> - getPos ()); - if (srcInDst == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, - __LINE__); - } - triggerEvent = srcInDst; - if (triggerEvent == true) - { - currentCellTriggeredEventUnitId = - movingUnit->getId (); - } - } - } - break; - - case ctet_FactionAreaPos: - { - if (movingUnit->getFactionIndex () == event.sourceId) - { - //if(event.sourceId == 1) printf("ctet_FactionPos event.destPos = [%s], movingUnit->getPos() [%s] Unit id = %d\n",event.destPos.getString().c_str(),movingUnit->getPos().getString().c_str(),movingUnit->getId()); - - bool - srcInDst = false; - - // Cache area lookup so for each unitsize and pos its done only once - bool - foundInCache = false; - std::map < int, - std::map < - Vec2i, - bool > >::iterator - iterFind1 = - event.eventLookupCache.find (movingUnit-> - getType ()-> - getSize ()); - if (iterFind1 != event.eventLookupCache.end ()) - { - std::map < Vec2i, bool >::iterator iterFind2 = - iterFind1->second.find (movingUnit->getPos ()); - if (iterFind2 != iterFind1->second.end ()) - { - foundInCache = true; - srcInDst = iterFind2->second; - } - } - - if (foundInCache == false) - { - for (int x = event.destPos.x; - srcInDst == false && x <= event.destPosEnd.x; - ++x) - { - for (int y = event.destPos.y; - srcInDst == false - && y <= event.destPosEnd.y; ++y) - { - - srcInDst = - world->getMap ()-> - isInUnitTypeCells (movingUnit-> - getType (), Vec2i (x, - y), - movingUnit-> - getPos ()); - if (srcInDst == true) - { - if (SystemFlags:: - getSystemSettingType - (SystemFlags::debugLUA).enabled) - SystemFlags:: - OutputDebug (SystemFlags:: - debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, - __LINE__); - } - } - } - - event.eventLookupCache[movingUnit->getType ()-> - getSize ()][movingUnit-> - getPos ()] = - srcInDst; - } - - triggerEvent = srcInDst; - if (triggerEvent == true) - { - //printf("!!!UNIT IN AREA!!! Faction area pos, moving unit faction= %d, trigger faction = %d, unit id = %d\n",movingUnit->getFactionIndex(),event.sourceId,movingUnit->getId()); - currentCellTriggeredEventUnitId = - movingUnit->getId (); - } - } - } - break; - - case ctet_AreaPos: - { - // Is the unit already in the cell range? If no check if they are entering it - if (event.eventStateInfo.find (movingUnit->getId ()) == - event.eventStateInfo.end ()) - { - //printf("ctet_FactionPos event.destPos = [%s], movingUnit->getPos() [%s]\n",event.destPos.getString().c_str(),movingUnit->getPos().getString().c_str()); - - bool - srcInDst = false; - for (int x = event.destPos.x; - srcInDst == false && x <= event.destPosEnd.x; - ++x) - { - for (int y = event.destPos.y; - srcInDst == false && y <= event.destPosEnd.y; - ++y) - { - - srcInDst = - world->getMap ()-> - isInUnitTypeCells (movingUnit->getType (), - Vec2i (x, y), - movingUnit->getPos ()); - if (srcInDst == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags:: - debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__). - c_str (), - __FUNCTION__, - __LINE__); - - currentCellTriggeredEventAreaEntryUnitId = - movingUnit->getId (); - event.eventStateInfo[movingUnit-> - getId ()] = - Vec2i (x, y).getString (); - } - } - } - triggerEvent = srcInDst; - if (triggerEvent == true) - { - currentCellTriggeredEventUnitId = - movingUnit->getId (); - } - } - // If unit is already in cell range check if they are leaving? - else - { - bool - srcInDst = false; - for (int x = event.destPos.x; - srcInDst == false && x <= event.destPosEnd.x; - ++x) - { - for (int y = event.destPos.y; - srcInDst == false && y <= event.destPosEnd.y; - ++y) - { - - srcInDst = - world->getMap ()-> - isInUnitTypeCells (movingUnit->getType (), - Vec2i (x, y), - movingUnit->getPos ()); - if (srcInDst == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags:: - debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__). - c_str (), - __FUNCTION__, - __LINE__); - - //event.eventStateInfo[movingUnit->getId()] = Vec2i(x,y); - } - } - } - triggerEvent = (srcInDst == false); - if (triggerEvent == true) - { - currentCellTriggeredEventUnitId = - movingUnit->getId (); - } - - if (triggerEvent == true) - { - currentCellTriggeredEventAreaExitUnitId = - movingUnit->getId (); - - event.eventStateInfo.erase (movingUnit->getId ()); - } - } - } - break; - - } - - if (triggerEvent == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__); - - currentCellTriggeredEventId = iterMap->first; - event.triggerCount++; - - luaScript.beginCall ("cellTriggerEvent"); - luaScript.endCall (); - } - -// ScenarioInfo scenarioInfoEnd = world->getScenario()->getInfo(); -// if(scenarioInfoStart.file != scenarioInfoEnd.file) { -// break; -// } - } - } - - inCellTriggerEvent = false; - } - -// ========================== lua wrappers =============================================== - - string - ScriptManager::wrapString (const string & str, int wrapCount) - { - string - returnString; - - int - letterCount = 0; - for (int i = 0; i < (int) str.size (); ++i) - { - if (letterCount > wrapCount && str[i] == ' ') - { - returnString += '\n'; - letterCount = 0; - } - else - { - returnString += str[i]; - } - ++letterCount; - } - - return returnString; - } - - void - ScriptManager::networkShowMessageForFaction (const string & text, - const string & header, - int factionIndex) - { - messageQueue. - push_back (ScriptManagerMessage (text, header, factionIndex)); - thisScriptManager->onMessageBoxOk (false); - } - void - ScriptManager::networkShowMessageForTeam (const string & text, - const string & header, - int teamIndex) - { - // Team indexes are 0 based internally (but 1 based in the lua script) so convert - teamIndex--; - messageQueue. - push_back (ScriptManagerMessage (text, header, -1, teamIndex)); - thisScriptManager->onMessageBoxOk (false); - } - - void - ScriptManager::networkSetCameraPositionForFaction (int factionIndex, - const Vec2i & pos) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (factionIndex == this->world->getThisFactionIndex ()) - { - gameCamera->centerXZ (pos.x, pos.y); - } - } - - void - ScriptManager::networkSetCameraPositionForTeam (int teamIndex, - const Vec2i & pos) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (teamIndex == this->world->getThisTeamIndex ()) - { - gameCamera->centerXZ (pos.x, pos.y); - } - } - - void - ScriptManager::showMessage (const string & text, const string & header) - { - messageQueue.push_back (ScriptManagerMessage (text, header)); - thisScriptManager->onMessageBoxOk (false); - } - - void - ScriptManager::clearDisplayText () - { - displayText = ""; - } - - void - ScriptManager::setDisplayText (const string & text) - { - displayText = - wrapString (Lang::getInstance ().getScenarioString (text), - displayTextWrapCount); - } - - void - ScriptManager::addConsoleText (const string & text) - { - world->addConsoleText (text); - } - void - ScriptManager::addConsoleLangText (const char *fmt, ...) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - va_list - argList; - va_start (argList, fmt); - - const int - max_debug_buffer_size = 8096; - char - szBuf[max_debug_buffer_size] = ""; - vsnprintf (szBuf, max_debug_buffer_size - 1, fmt, argList); - - world->addConsoleTextWoLang (szBuf); - va_end (argList); - - } - - void - ScriptManager::DisplayFormattedText (const char *fmt, ...) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - va_list - argList; - va_start (argList, fmt); - - const int - max_debug_buffer_size = 8096; - char - szBuf[max_debug_buffer_size] = ""; - vsnprintf (szBuf, max_debug_buffer_size - 1, fmt, argList); - - displayText = szBuf; - - va_end (argList); - } - void - ScriptManager::DisplayFormattedLangText (const char *fmt, ...) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - va_list - argList; - va_start (argList, fmt); - - const int - max_debug_buffer_size = 8096; - char - szBuf[max_debug_buffer_size] = ""; - vsnprintf (szBuf, max_debug_buffer_size - 1, fmt, argList); - - displayText = szBuf; - - va_end (argList); - } - void - ScriptManager::setCameraPosition (const Vec2i & pos) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - gameCamera->centerXZ (pos.x, pos.y); - } - - void - ScriptManager::shakeCamera (int shakeIntensity, int shakeDuration, - bool cameraDistanceAffected, int unitId) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (cameraDistanceAffected) - { - Unit * - unit = world->findUnitById (unitId); - if (unit) - { - gameCamera->shake (shakeDuration, shakeIntensity, - cameraDistanceAffected, - unit->getCurrMidHeightVector ()); - } - } - else - { - gameCamera->shake (shakeDuration, shakeIntensity, - cameraDistanceAffected, Vec3f (0.f, 0.f, 0.f)); - } - } - - void - ScriptManager::createUnit (const string & unitName, int factionIndex, - Vec2i pos) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] unit [%s] factionIndex = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - unitName.c_str (), factionIndex); - world->createUnit (unitName, factionIndex, pos); - } - - void - ScriptManager::createUnitNoSpacing (const string & unitName, - int factionIndex, Vec2i pos) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] unit [%s] factionIndex = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - unitName.c_str (), factionIndex); - world->createUnit (unitName, factionIndex, pos, false); - } - - void - ScriptManager::setLockedUnitForFaction (const string & unitName, - int factionIndex, bool lock) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] unit [%s] factionIndex = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - unitName.c_str (), factionIndex); - if (world->getFactionCount () > factionIndex) - { - const UnitType * - ut = - world->getFaction (factionIndex)->getType ()-> - getUnitType (unitName); - world->getFaction (factionIndex)->setLockedUnitForFaction (ut, - lock); - } - else - { - throw - megaglest_runtime_error - ("Invalid faction index in setLockedUnitForFaction: " + - intToStr (factionIndex), true); - } - } - - void - ScriptManager::destroyUnit (int unitId) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] unit [%d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, unitId); - Unit * - unit = world->findUnitById (unitId); - if (unit != NULL) - { - // Make sure they die - bool - unit_dead = unit->decHp (unit->getHp () * unit->getHp ()); - if (unit_dead == false) - { - throw - megaglest_runtime_error ("unit_dead == false", true); - } - unit->kill (); - // If called from an existing die event we get a stack overflow - //onUnitDied(unit); - } - } - void - ScriptManager::giveKills (int unitId, int amount) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] unit [%d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, unitId); - Unit * - unit = world->findUnitById (unitId); - if (unit != NULL) - { - for (int index = 1; index <= amount; ++index) - { - unit->incKills (-1); - } - } - } - - void - ScriptManager::playStaticSound (const string & playSound) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] playSound [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - playSound.c_str ()); - world->playStaticSound (playSound); - } - void - ScriptManager::playStreamingSound (const string & playSound) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] playSound [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - playSound.c_str ()); - world->playStreamingSound (playSound); - } - - void - ScriptManager::stopStreamingSound (const string & playSound) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] playSound [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - playSound.c_str ()); - world->stopStreamingSound (playSound); - } - - void - ScriptManager::stopAllSound () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - world->stopAllSound (); - } - - void - ScriptManager::playStaticVideo (const string & playVideo) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] playVideo [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - playVideo.c_str ()); - world->playStaticVideo (playVideo); - } - void - ScriptManager::playStreamingVideo (const string & playVideo) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] playVideo [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - playVideo.c_str ()); - world->playStreamingVideo (playVideo); - } - - void - ScriptManager::stopStreamingVideo (const string & playVideo) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] playVideo [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - playVideo.c_str ()); - world->stopStreamingVideo (playVideo); - } - - void - ScriptManager::stopAllVideo () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - world->stopAllVideo (); - } - - void - ScriptManager::togglePauseGame (int pauseStatus) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] pauseStatus = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - pauseStatus); - world->togglePauseGame ((pauseStatus != 0), true); - } - - void - ScriptManager::morphToUnit (int unitId, const string & morphName, - int ignoreRequirements) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] unit [%d] morphName [%s] forceUpgradesIfRequired = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, unitId, - morphName.c_str (), ignoreRequirements); - - world->morphToUnit (unitId, morphName, (ignoreRequirements == 1)); - } - - void - ScriptManager::moveToUnit (int unitId, int destUnitId) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] unit [%d] destUnitId [%d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, unitId, - destUnitId); - - world->moveToUnit (unitId, destUnitId); - } - - void - ScriptManager::giveResource (const string & resourceName, - int factionIndex, int amount) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - world->giveResource (resourceName, factionIndex, amount); - } - - void - ScriptManager::givePositionCommand (int unitId, - const string & commandName, - const Vec2i & pos) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - world->givePositionCommand (unitId, commandName, pos); - } - - void - ScriptManager::giveAttackCommand (int unitId, int unitToAttackId) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - world->giveAttackCommand (unitId, unitToAttackId); - } - - void - ScriptManager::giveProductionCommand (int unitId, - const string & producedName) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - world->giveProductionCommand (unitId, producedName); - } - - void - ScriptManager::giveUpgradeCommand (int unitId, - const string & producedName) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - world->giveUpgradeCommand (unitId, producedName); - } - - void - ScriptManager::giveAttackStoppedCommand (int unitId, - const string & itemName, - int ignoreRequirements) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - world->giveAttackStoppedCommand (unitId, itemName, - (ignoreRequirements == 1)); - } - - void - ScriptManager::disableAi (int factionIndex) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (factionIndex >= 0 && factionIndex < GameConstants::maxPlayers) - { - playerModifiers[factionIndex].disableAi (); - disableConsume (factionIndex); // by this we stay somehow compatible with old behaviour - } - } - - void - ScriptManager::enableAi (int factionIndex) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (factionIndex >= 0 && factionIndex < GameConstants::maxPlayers) - { - playerModifiers[factionIndex].enableAi (); - } - } - - bool - ScriptManager::getAiEnabled (int factionIndex) - { - - if (factionIndex >= 0 && factionIndex < GameConstants::maxPlayers) - { - return playerModifiers[factionIndex].getAiEnabled (); - } - return false; - } - - void - ScriptManager::disableConsume (int factionIndex) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (factionIndex >= 0 && factionIndex < GameConstants::maxPlayers) - { - playerModifiers[factionIndex].disableConsume (); - } - } - - void - ScriptManager::enableConsume (int factionIndex) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (factionIndex >= 0 && factionIndex < GameConstants::maxPlayers) - { - playerModifiers[factionIndex].enableConsume (); - } - } - - bool - ScriptManager::getConsumeEnabled (int factionIndex) - { - - if (factionIndex >= 0 && factionIndex < GameConstants::maxPlayers) - { - return playerModifiers[factionIndex].getConsumeEnabled (); - } - return false; - } - - int - ScriptManager::registerCellTriggerEventForUnitToUnit (int sourceUnitId, - int destUnitId) - { - CellTriggerEvent - trigger; - trigger.type = ctet_Unit; - trigger.sourceId = sourceUnitId; - trigger.destId = destUnitId; - - int - eventId = currentEventId++; - CellTriggerEventList[eventId] = trigger; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] Unit: %d will trigger cell event when reaching unit: %d, eventId = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - sourceUnitId, destUnitId, eventId); - - return eventId; - } - - int - ScriptManager:: - registerCellTriggerEventForUnitToLocation (int sourceUnitId, - const Vec2i & pos) - { - CellTriggerEvent - trigger; - trigger.type = ctet_UnitPos; - trigger.sourceId = sourceUnitId; - trigger.destPos = pos; - - int - eventId = currentEventId++; - CellTriggerEventList[eventId] = trigger; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] Unit: %d will trigger cell event when reaching pos: %s, eventId = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - sourceUnitId, pos.getString ().c_str (), - eventId); - - return eventId; - } - - int - ScriptManager:: - registerCellAreaTriggerEventForUnitToLocation (int sourceUnitId, - const Vec4i & pos) - { - CellTriggerEvent - trigger; - trigger.type = ctet_UnitAreaPos; - trigger.sourceId = sourceUnitId; - trigger.destPos.x = pos.x; - trigger.destPos.y = pos.y; - trigger.destPosEnd.x = pos.z; - trigger.destPosEnd.y = pos.w; - - int - eventId = currentEventId++; - CellTriggerEventList[eventId] = trigger; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] Unit: %d will trigger cell event when reaching pos: %s, eventId = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - sourceUnitId, pos.getString ().c_str (), - eventId); - - return eventId; - } - - int - ScriptManager:: - registerCellTriggerEventForFactionToUnit (int sourceFactionId, - int destUnitId) - { - CellTriggerEvent - trigger; - trigger.type = ctet_Faction; - trigger.sourceId = sourceFactionId; - trigger.destId = destUnitId; - - int - eventId = currentEventId++; - CellTriggerEventList[eventId] = trigger; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] Faction: %d will trigger cell event when reaching unit: %d, eventId = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - sourceFactionId, destUnitId, eventId); - - return eventId; - } - - int - ScriptManager:: - registerCellTriggerEventForFactionToLocation (int sourceFactionId, - const Vec2i & pos) - { - CellTriggerEvent - trigger; - trigger.type = ctet_FactionPos; - trigger.sourceId = sourceFactionId; - trigger.destPos = pos; - - int - eventId = currentEventId++; - CellTriggerEventList[eventId] = trigger; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]Faction: %d will trigger cell event when reaching pos: %s, eventId = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - sourceFactionId, pos.getString ().c_str (), - eventId); - - return eventId; - } - - int - ScriptManager:: - registerCellAreaTriggerEventForFactionToLocation (int sourceFactionId, - const Vec4i & pos) - { - CellTriggerEvent - trigger; - trigger.type = ctet_FactionAreaPos; - trigger.sourceId = sourceFactionId; - trigger.destPos.x = pos.x; - trigger.destPos.y = pos.y; - trigger.destPosEnd.x = pos.z; - trigger.destPosEnd.y = pos.w; - - int - eventId = currentEventId++; - CellTriggerEventList[eventId] = trigger; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]Faction: %d will trigger cell event when reaching pos: %s, eventId = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - sourceFactionId, pos.getString ().c_str (), - eventId); - - return eventId; - } - - int - ScriptManager::registerCellAreaTriggerEvent (const Vec4i & pos) - { - CellTriggerEvent - trigger; - trigger.type = ctet_AreaPos; - trigger.sourceId = -1; - trigger.destPos.x = pos.x; - trigger.destPos.y = pos.y; - trigger.destPosEnd.x = pos.z; - trigger.destPosEnd.y = pos.w; - - int - eventId = currentEventId++; - CellTriggerEventList[eventId] = trigger; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] trigger cell event when reaching pos: %s, eventId = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - pos.getString ().c_str (), eventId); - - return eventId; - } - - int - ScriptManager::getCellTriggerEventCount (int eventId) - { - int - result = 0; - if (CellTriggerEventList.find (eventId) != CellTriggerEventList.end ()) - { - result = CellTriggerEventList[eventId].triggerCount; - } - - return result; - } - - void - ScriptManager::unregisterCellTriggerEvent (int eventId) - { - if (CellTriggerEventList.find (eventId) != CellTriggerEventList.end ()) - { - if (inCellTriggerEvent == false) - { - CellTriggerEventList.erase (eventId); - } - else - { - unRegisterCellTriggerEventList.push_back (eventId); - } - } - - if (inCellTriggerEvent == false) - { - if (unRegisterCellTriggerEventList.empty () == false) - { - for (int i = 0; - i < (int) unRegisterCellTriggerEventList.size (); ++i) - { - int - delayedEventId = unRegisterCellTriggerEventList[i]; - CellTriggerEventList.erase (delayedEventId); - } - unRegisterCellTriggerEventList.clear (); - } - } - } - - int - ScriptManager::startTimerEvent () - { - TimerTriggerEvent - trigger; - trigger.running = true; - //trigger.startTime = time(NULL); - trigger.startFrame = world->getFrameCount (); - //trigger.endTime = 0; - trigger.endFrame = 0; - - int - eventId = currentEventId++; - TimerTriggerEventList[eventId] = trigger; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] TimerTriggerEventList.size() = %d, eventId = %d, trigger.startTime = %lld, trigger.endTime = %lld\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - TimerTriggerEventList.size (), eventId, - (long long int) trigger.startFrame, - (long long int) trigger.endFrame); - - return eventId; - } - - int - ScriptManager::startEfficientTimerEvent (int triggerSecondsElapsed) - { - TimerTriggerEvent - trigger; - trigger.running = true; - //trigger.startTime = time(NULL); - trigger.startFrame = world->getFrameCount (); - //trigger.endTime = 0; - trigger.endFrame = 0; - trigger.triggerSecondsElapsed = triggerSecondsElapsed; - - int - eventId = currentEventId++; - TimerTriggerEventList[eventId] = trigger; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] TimerTriggerEventList.size() = %d, eventId = %d, trigger.startTime = %lld, trigger.endTime = %lld\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - TimerTriggerEventList.size (), eventId, - (long long int) trigger.startFrame, - (long long int) trigger.endFrame); - - return eventId; - } - - int - ScriptManager::resetTimerEvent (int eventId) - { - int - result = 0; - if (TimerTriggerEventList.find (eventId) != - TimerTriggerEventList.end ()) - { - TimerTriggerEvent & trigger = TimerTriggerEventList[eventId]; - result = getTimerEventSecondsElapsed (eventId); - - //trigger.startTime = time(NULL); - trigger.startFrame = world->getFrameCount (); - //trigger.endTime = 0; - trigger.endFrame = 0; - trigger.running = true; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] TimerTriggerEventList.size() = %d, eventId = %d, trigger.startTime = %lld, trigger.endTime = %lld, result = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - TimerTriggerEventList.size (), eventId, - (long long int) trigger.startFrame, - (long long int) trigger.endFrame, - result); - } - return result; - } - - int - ScriptManager::stopTimerEvent (int eventId) - { - int - result = 0; - if (TimerTriggerEventList.find (eventId) != - TimerTriggerEventList.end ()) - { - TimerTriggerEvent & trigger = TimerTriggerEventList[eventId]; - //trigger.endTime = time(NULL); - trigger.endFrame = world->getFrameCount (); - trigger.running = false; - result = getTimerEventSecondsElapsed (eventId); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] TimerTriggerEventList.size() = %d, eventId = %d, trigger.startTime = %lld, trigger.endTime = %lld, result = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - TimerTriggerEventList.size (), eventId, - (long long int) trigger.startFrame, - (long long int) trigger.endFrame, - result); - } - - return result; - } - - int - ScriptManager::getTimerEventSecondsElapsed (int eventId) - { - int - result = 0; - if (TimerTriggerEventList.find (eventId) != - TimerTriggerEventList.end ()) - { - TimerTriggerEvent & trigger = TimerTriggerEventList[eventId]; - if (trigger.running) - { - //result = (int)difftime(time(NULL),trigger.startTime); - result = - (world->getFrameCount () - - trigger.startFrame) / GameConstants::updateFps; - } - else - { - //result = (int)difftime(trigger.endTime,trigger.startTime); - result = - (trigger.endFrame - - trigger.startFrame) / GameConstants::updateFps; - } - - //printf("Timer event id = %d seconmds elapsed = %d\n",eventId,result); - } - - return result; - } - - void - ScriptManager::setPlayerAsWinner (int factionIndex) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - - if (factionIndex >= 0 && factionIndex < GameConstants::maxPlayers) - { - playerModifiers[factionIndex].setAsWinner (); - } - } - - void - ScriptManager::endGame () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - gameOver = true; - } - - void - ScriptManager::startPerformanceTimer () - { - - if (world->getGame () == NULL) - { - throw - megaglest_runtime_error ("#1 world->getGame() == NULL", true); - } - world->getGame ()->startPerformanceTimer (); - - } - - void - ScriptManager::endPerformanceTimer () - { - - if (world->getGame () == NULL) - { - throw - megaglest_runtime_error ("#2 world->getGame() == NULL", true); - } - world->getGame ()->endPerformanceTimer (); - - } - - Vec2i - ScriptManager::getPerformanceTimerResults () - { - - if (world->getGame () == NULL) - { - throw - megaglest_runtime_error ("#3 world->getGame() == NULL", true); - } - return world->getGame ()->getPerformanceTimerResults (); - } - - Vec2i - ScriptManager::getStartLocation (int factionIndex) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return world->getStartLocation (factionIndex); - } - - - Vec2i - ScriptManager::getUnitPosition (int unitId) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - Vec2i - result = world->getUnitPosition (unitId); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s] unitId = %d, pos [%s]\n", - __FUNCTION__, unitId, - result.getString ().c_str ()); - - return result; - } - - void - ScriptManager::setUnitPosition (int unitId, Vec2i pos) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return world->setUnitPosition (unitId, pos); - } - - void - ScriptManager::addCellMarker (Vec2i pos, int factionIndex, - const string & note, - const string & textureFile) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - world->addCellMarker (pos, factionIndex, note, textureFile); - } - - void - ScriptManager::removeCellMarker (Vec2i pos, int factionIndex) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return world->removeCellMarker (pos, factionIndex); - } - - void - ScriptManager::showMarker (Vec2i pos, int factionIndex, - const string & note, - const string & textureFile, int flashCount) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - world->showMarker (pos, factionIndex, note, textureFile, flashCount); - } - - int - ScriptManager::getIsUnitAlive (int unitId) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return world->getIsUnitAlive (unitId); - } - - int - ScriptManager::getUnitFaction (int unitId) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return world->getUnitFactionIndex (unitId); - } - const string - ScriptManager::getUnitName (int unitId) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - string - result = ""; - Unit * - unit = world->findUnitById (unitId); - if (unit) - { - result = world->findUnitById (unitId)->getType ()->getName (false); - } - return result; - } - - const string - ScriptManager::getUnitDisplayName (int unitId) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return world->getUnitName (unitId); - } - - int - ScriptManager::getResourceAmount (const string & resourceName, - int factionIndex) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return world->getResourceAmount (resourceName, factionIndex); - } - - const - string & - ScriptManager::getLastCreatedUnitName () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return lastCreatedUnitName; - } - - int - ScriptManager::getCellTriggeredEventId () - { - - return currentCellTriggeredEventId; - } - - int - ScriptManager::getTimerTriggeredEventId () - { - - return currentTimerTriggeredEventId; - } - - int - ScriptManager::getCellTriggeredEventAreaEntryUnitId () - { - - return currentCellTriggeredEventAreaEntryUnitId; - } - - int - ScriptManager::getCellTriggeredEventAreaExitUnitId () - { - - return currentCellTriggeredEventAreaExitUnitId; - } - - int - ScriptManager::getCellTriggeredEventUnitId () - { - - return currentCellTriggeredEventUnitId; - } - - void - ScriptManager::setRandomGenInit (int seed) - { - - random.init (seed); - } - - int - ScriptManager::getRandomGen (int minVal, int maxVal) - { - - return random.randRange (minVal, maxVal); - } - - int - ScriptManager::getWorldFrameCount () - { - - return world->getFrameCount (); - } - - bool - ScriptManager::getGameWon () const - { - - return - gameWon; - } - - bool - ScriptManager::getIsGameOver () const - { - - return - gameOver; - } - - int - ScriptManager::getLastCreatedUnitId () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return lastCreatedUnitId; - } - - const - string & - ScriptManager::getLastDeadUnitName () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return lastDeadUnitName; - } - - int - ScriptManager::getLastDeadUnitId () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return lastDeadUnitId; - } - - int - ScriptManager::getLastDeadUnitCauseOfDeath () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return lastDeadUnitCauseOfDeath; - } - - const - string & - ScriptManager::getLastDeadUnitKillerName () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return lastDeadUnitKillerName; - } - - int - ScriptManager::getLastDeadUnitKillerId () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return lastDeadUnitKillerId; - } - - const - string & - ScriptManager::getLastAttackedUnitName () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return lastAttackedUnitName; - } - - int - ScriptManager::getLastAttackedUnitId () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return lastAttackedUnitId; - } - - const - string & - ScriptManager::getLastAttackingUnitName () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return lastAttackingUnitName; - } - - int - ScriptManager::getLastAttackingUnitId () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return lastAttackingUnitId; - } - - int - ScriptManager::getUnitCount (int factionIndex) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return world->getUnitCount (factionIndex); - } - - int - ScriptManager::getUnitCountOfType (int factionIndex, - const string & typeName) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return world->getUnitCountOfType (factionIndex, typeName); - } - - const string - ScriptManager::getSystemMacroValue (const string & key) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return world->getSystemMacroValue (key); - } - - const string - ScriptManager::getPlayerName (int factionIndex) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return world->getPlayerName (factionIndex); - } - - void - ScriptManager::loadScenario (const string & name, bool keepFactions) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - - world->setQueuedScenario (name, keepFactions); - } - - vector < int > - ScriptManager::getUnitsForFaction (int factionIndex, - const string & commandTypeName, - int field) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - - return world->getUnitsForFaction (factionIndex, commandTypeName, field); - } - - int - ScriptManager::getUnitCurrentField (int unitId) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - - return world->getUnitCurrentField (unitId); - } - - int - ScriptManager::isFreeCellsOrHasUnit (int field, int unitId, Vec2i pos) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - - Unit * - unit = world->findUnitById (unitId); - if (unit == NULL) - { - throw - megaglest_runtime_error ("unit == NULL", true); - } - int - result = - world->getMap ()->isFreeCellsOrHasUnit (pos, - unit->getType ()->getSize (), - static_cast < Field > (field), - unit); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s] unitId = %d, [%s] pos [%s] field = %d result = %d\n", - __FUNCTION__, unitId, - unit->getType ()->getName (false).c_str (), - pos.getString ().c_str (), field, result); - - return result; - } - - int - ScriptManager::isFreeCells (int unitSize, int field, Vec2i pos) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - int - result = - world->getMap ()->isFreeCellsOrHasUnit (pos, unitSize, - static_cast < Field > (field), - NULL); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s] unitSize = %d, pos [%s] field = %d result = %d\n", - __FUNCTION__, unitSize, - pos.getString ().c_str (), field, result); - - return result; - } - - int - ScriptManager::getHumanFactionId () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return this->world->getThisFactionIndex (); - } - - void - ScriptManager::highlightUnit (int unitId, float radius, float thickness, - Vec4f color) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - - world->highlightUnit (unitId, radius, thickness, color); - } - - void - ScriptManager::unhighlightUnit (int unitId) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - - world->unhighlightUnit (unitId); - } - - void - ScriptManager::giveStopCommand (int unitId) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - world->giveStopCommand (unitId); - } - - bool - ScriptManager::selectUnit (int unitId) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return world->selectUnit (unitId); - } - - void - ScriptManager::unselectUnit (int unitId) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - world->unselectUnit (unitId); - } - - void - ScriptManager::addUnitToGroupSelection (int unitId, int groupIndex) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - world->addUnitToGroupSelection (unitId, groupIndex); - } - void - ScriptManager::recallGroupSelection (int groupIndex) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - world->recallGroupSelection (groupIndex); - } - void - ScriptManager::removeUnitFromGroupSelection (int unitId, int groupIndex) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - world->removeUnitFromGroupSelection (unitId, groupIndex); - } - - void - ScriptManager::setAttackWarningsEnabled (bool enabled) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - world->setAttackWarningsEnabled (enabled); - } - - bool - ScriptManager::getAttackWarningsEnabled () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - return world->getAttackWarningsEnabled (); - } - - void - ScriptManager::registerUnitTriggerEvent (int unitId) - { - UnitTriggerEventList[unitId] = utet_None; - } - - void - ScriptManager::unregisterUnitTriggerEvent (int unitId) - { - UnitTriggerEventList.erase (unitId); - } - - int - ScriptManager::getLastUnitTriggerEventUnitId () - { - return lastUnitTriggerEventUnitId; - } - UnitTriggerEventType - ScriptManager::getLastUnitTriggerEventType () - { - return lastUnitTriggerEventType; - } - - int - ScriptManager::getUnitProperty (int unitId, UnitTriggerEventType type) - { - int - result = -1; - - //printf("File: %s line: %d type: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,type); - - Unit * - unit = world->findUnitById (unitId); - if (unit != NULL) - { - switch (type) - { - case utet_None: - result = -2; - break; - case utet_HPChanged: - result = unit->getHp (); - break; - case utet_EPChanged: - result = unit->getEp (); - break; - case utet_LevelChanged: - result = -3; - if (unit->getLevel () != NULL) - { - result = unit->getLevel ()->getKills (); - } - break; - case utet_FieldChanged: - result = unit->getCurrField (); - break; - case utet_SkillChanged: - result = -4; - if (unit->getCurrSkill () != NULL) - { - result = unit->getCurrSkill ()->getClass (); - } - break; - default: - result = -1000; - break; - } - } - //printf("File: %s line: %d result: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,result); - return result; - } - const string - ScriptManager::getUnitPropertyName (int unitId, UnitTriggerEventType type) - { - string - result = ""; - Unit * - unit = world->findUnitById (unitId); - if (unit != NULL) - { - switch (type) - { - case utet_None: - result = ""; - break; - case utet_HPChanged: - result = ""; - break; - case utet_EPChanged: - result = ""; - break; - case utet_LevelChanged: - result = ""; - if (unit->getLevel () != NULL) - { - result = unit->getLevel ()->getName (false); - } - break; - case utet_FieldChanged: - result = ""; - break; - case utet_SkillChanged: - result = ""; - if (unit->getCurrSkill () != NULL) - { - result = unit->getCurrSkill ()->getName (); - } - break; - default: - result = "???"; - break; - } - } - return result; - } - - void - ScriptManager::onUnitTriggerEvent (const Unit * unit, - UnitTriggerEventType event) - { - //static bool inEvent = false; - //if(inEvent == true) { - // printf("\n\n!!!!!!!!!!!!!!! File: %s line: %d unit [%d - %s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,unit->getId(),unit->getType()->getName().c_str()); - // return; - //} - //inEvent = true; - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - if (UnitTriggerEventList.empty () == false) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - std::map < int, - UnitTriggerEventType >::iterator - iterFind = UnitTriggerEventList.find (unit->getId ()); - if (iterFind != UnitTriggerEventList.end ()) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - - lastUnitTriggerEventUnitId = unit->getId (); - lastUnitTriggerEventType = event; - - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - - luaScript.beginCall ("unitTriggerEvent"); - luaScript.endCall (); - - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - } - //inEvent = false; - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - - void - ScriptManager::registerDayNightEvent () - { - registeredDayNightEvent = true; - } - - void - ScriptManager::unregisterDayNightEvent () - { - registeredDayNightEvent = false; - } - - void - ScriptManager::onDayNightTriggerEvent () - { - if (registeredDayNightEvent == true) - { - bool - isDay = (this->getIsDayTime () == 1); - if ((lastDayNightTriggerStatus != 1 && isDay == true) || - (lastDayNightTriggerStatus != 2 && isDay == false)) - { - if (isDay == true) - { - lastDayNightTriggerStatus = 1; - } - else - { - lastDayNightTriggerStatus = 2; - } - - printf ("Triggering daynight event isDay: %d [%f]\n", isDay, - getTimeOfDay ()); - - luaScript.beginCall ("dayNightTriggerEvent"); - luaScript.endCall (); - } - } - } - - int - ScriptManager::getIsDayTime () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - - const TimeFlow * - tf = world->getTimeFlow (); - if (tf == NULL) - { - throw - megaglest_runtime_error ("#1 tf == NULL", true); - } - return tf->isDay (); - } - int - ScriptManager::getIsNightTime () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - - const TimeFlow * - tf = world->getTimeFlow (); - if (tf == NULL) - { - throw - megaglest_runtime_error ("#2 tf == NULL", true); - } - return tf->isNight (); - } - float - ScriptManager::getTimeOfDay () - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - - const TimeFlow * - tf = world->getTimeFlow (); - if (tf == NULL) - { - throw - megaglest_runtime_error ("#3 tf == NULL", true); - } - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - return tf->getTime (); - } - - void - ScriptManager::disableSpeedChange () - { - if (world->getGame () == NULL) - { - throw - megaglest_runtime_error ("#4 world->getGame() == NULL"); - } - world->getGame ()->setDisableSpeedChange (true); - } - void - ScriptManager::enableSpeedChange () - { - if (world->getGame () == NULL) - { - throw - megaglest_runtime_error ("#5 world->getGame() == NULL"); - } - world->getGame ()->setDisableSpeedChange (false); - } - - bool - ScriptManager::getSpeedChangeEnabled () - { - if (world->getGame () == NULL) - { - throw - megaglest_runtime_error ("#6 world->getGame() == NULL"); - } - return world->getGame ()->getDisableSpeedChange (); - } - - void - ScriptManager::addMessageToQueue (ScriptManagerMessage msg) - { - messageQueue.push_back (msg); - } - - void - ScriptManager::storeSaveGameData (string name, string value) - { - - if (LuaScript::getDebugModeEnabled () == true) - printf ("storeSaveGameData name [%s] value [%s]\n", name.c_str (), - value.c_str ()); - - luaSavedGameData[name] = value; - } - - string - ScriptManager::loadSaveGameData (string name) - { - string - value = luaSavedGameData[name]; - - if (LuaScript::getDebugModeEnabled () == true) - printf ("loadSaveGameData result name [%s] value [%s]\n", - name.c_str (), value.c_str ()); - - return value; - } - - ControlType - ScriptManager::getFactionPlayerType (int factionIndex) - { - Faction * - faction = world->getFaction (factionIndex); - if (faction != NULL) - { - return faction->getControlType (); - } - return ctClosed; - } -// ========================== lua callbacks =============================================== - - int - ScriptManager::showMessage (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - thisScriptManager->showMessage (luaArguments.getString (-2), - luaArguments.getString (-1)); - return luaArguments.getReturnCount (); - } - - int - ScriptManager::networkShowMessageForFaction (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - try - { - thisScriptManager->networkShowMessageForFaction (luaArguments. - getString (-3), - luaArguments. - getString (-2), - luaArguments. - getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::networkShowMessageForTeam (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - try - { - thisScriptManager->networkShowMessageForTeam (luaArguments. - getString (-3), - luaArguments. - getString (-2), - luaArguments. - getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::networkSetCameraPositionForFaction (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - try - { - thisScriptManager->networkSetCameraPositionForFaction (luaArguments. - getInt (-2), - luaArguments. - getVec2i (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::networkSetCameraPositionForTeam (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - try - { - thisScriptManager->networkSetCameraPositionForTeam (luaArguments. - getInt (-2), - luaArguments. - getVec2i (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - - int - ScriptManager::setDisplayText (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - try - { - thisScriptManager->setDisplayText (luaArguments.getString (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::addConsoleText (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - try - { - thisScriptManager->addConsoleText (luaArguments.getString (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::clearDisplayText (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - try - { - thisScriptManager->clearDisplayText (); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::setCameraPosition (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - try - { - thisScriptManager-> - setCameraPosition (Vec2i (luaArguments.getVec2i (-1))); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::shakeCamera (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - try - { - thisScriptManager->shakeCamera (luaArguments.getInt (-2), - luaArguments.getInt (-1), false, 0); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::shakeCameraOnUnit (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - try - { - thisScriptManager->shakeCamera (luaArguments.getInt (-3), - luaArguments.getInt (-2), true, - luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::createUnit (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] unit [%s] factionIndex = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - luaArguments.getString (-3).c_str (), - luaArguments.getInt (-2)); - - try - { - thisScriptManager->createUnit (luaArguments.getString (-3), - luaArguments.getInt (-2), - luaArguments.getVec2i (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - void - ScriptManager::error (LuaHandle * luaHandle, - const megaglest_runtime_error * mgErr, - const char *file, const char *function, int line) - { - char - szErrBuf[8096] = ""; - char - szErrBuf2[8096] = ""; - - int - luaLine = -1; - const char * - luaSource = ""; - - if (luaHandle != NULL) - { - lua_Debug - ar; - lua_getstack (luaHandle, 1, &ar); - lua_getinfo (luaHandle, "nSl", &ar); - - luaLine = ar.currentline; - luaSource = ar.source; - - } - snprintf (szErrBuf, 8096, "in %s::%s %d ", - extractFileFromDirectoryPath (file).c_str (), function, line); - snprintf (szErrBuf2, 8096, "Lua: tag=<%s> line=%d ", luaSource, - luaLine - 1); - string - sErrBuf = string ("Error! The game may no longer be stable!\n\n") - + string (szErrBuf) + "\n" + string (szErrBuf2) + "\n\n" - + string (mgErr->what ()); - - SystemFlags::OutputDebug (SystemFlags::debugError, sErrBuf.c_str ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, sErrBuf.c_str ()); - - thisScriptManager-> - addMessageToQueue (ScriptManagerMessage - (sErrBuf.c_str (), - "error " + - intToStr (thisScriptManager->errorCount), -1, -1, - true)); - thisScriptManager->errorCount++; - thisScriptManager->onMessageBoxOk (false); - } - - int - ScriptManager::createUnitNoSpacing (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] unit [%s] factionIndex = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - luaArguments.getString (-3).c_str (), - luaArguments.getInt (-2)); - - try - { - thisScriptManager->createUnitNoSpacing (luaArguments.getString (-3), - luaArguments.getInt (-2), - luaArguments.getVec2i (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::destroyUnit (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] unit [%d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - luaArguments.getInt (-1)); - - try - { - thisScriptManager->destroyUnit (luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::setLockedUnitForFaction (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] unit [%s] factionIndex = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - luaArguments.getString (-3).c_str (), - luaArguments.getInt (-2)); - - try - { - thisScriptManager->setLockedUnitForFaction (luaArguments. - getString (-3), - luaArguments.getInt (-2), - (luaArguments. - getInt (-1) == - 0 ? false : true)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::giveKills (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] unit [%d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - luaArguments.getInt (-1)); - - try - { - thisScriptManager->giveKills (luaArguments.getInt (-2), - luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::morphToUnit (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] unit [%d] morphName [%s] forceUpgrade = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - luaArguments.getInt (-3), - luaArguments.getString (-2).c_str (), - luaArguments.getInt (-1)); - - try - { - thisScriptManager->morphToUnit (luaArguments.getInt (-3), - luaArguments.getString (-2), - luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::moveToUnit (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] unit [%d] dest unit [%d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - luaArguments.getInt (-2), - luaArguments.getInt (-1)); - - try - { - thisScriptManager->moveToUnit (luaArguments.getInt (-2), - luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::playStaticSound (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] sound [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - luaArguments.getString (-1).c_str ()); - - try - { - thisScriptManager->playStaticSound (luaArguments.getString (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::playStreamingSound (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] sound [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - luaArguments.getString (-1).c_str ()); - - try - { - thisScriptManager->playStreamingSound (luaArguments.getString (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::stopStreamingSound (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] sound [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - luaArguments.getString (-1).c_str ()); - - try - { - thisScriptManager->stopStreamingSound (luaArguments.getString (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::stopAllSound (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - try - { - thisScriptManager->stopAllSound (); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::playStaticVideo (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] sound [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - luaArguments.getString (-1).c_str ()); - - try - { - thisScriptManager->playStaticVideo (luaArguments.getString (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::playStreamingVideo (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] sound [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - luaArguments.getString (-1).c_str ()); - - try - { - thisScriptManager->playStreamingVideo (luaArguments.getString (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::stopStreamingVideo (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] sound [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - luaArguments.getString (-1).c_str ()); - - try - { - thisScriptManager->stopStreamingVideo (luaArguments.getString (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::stopAllVideo (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - try - { - thisScriptManager->stopAllVideo (); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::togglePauseGame (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] value = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - luaArguments.getInt (-1)); - - try - { - thisScriptManager->togglePauseGame (luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - int - ScriptManager::giveResource (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->giveResource (luaArguments.getString (-3), - luaArguments.getInt (-2), - luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::givePositionCommand (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->givePositionCommand (luaArguments.getInt (-3), - luaArguments.getString (-2), - luaArguments.getVec2i (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::giveAttackCommand (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->giveAttackCommand (luaArguments.getInt (-2), - luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::giveProductionCommand (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->giveProductionCommand (luaArguments.getInt (-2), - luaArguments. - getString (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::giveUpgradeCommand (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->giveUpgradeCommand (luaArguments.getInt (-2), - luaArguments.getString (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::giveAttackStoppedCommand (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->giveAttackStoppedCommand (luaArguments.getInt (-3), - luaArguments. - getString (-2), - luaArguments. - getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::disableAi (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->disableAi (luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::enableAi (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->enableAi (luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getAiEnabled (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - bool - result = thisScriptManager->getAiEnabled (luaArguments.getInt (-1)); - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::disableConsume (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->disableConsume (luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::enableConsume (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->enableConsume (luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getConsumeEnabled (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - bool - result = - thisScriptManager->getConsumeEnabled (luaArguments.getInt (-1)); - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::registerCellTriggerEventForUnitToUnit (LuaHandle * - luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - int - result = - thisScriptManager-> - registerCellTriggerEventForUnitToUnit (luaArguments.getInt (-2), - luaArguments.getInt (-1)); - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::registerCellTriggerEventForUnitToLocation (LuaHandle * - luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - int - result = - thisScriptManager-> - registerCellTriggerEventForUnitToLocation (luaArguments.getInt (-2), - luaArguments. - getVec2i (-1)); - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::registerCellAreaTriggerEventForUnitToLocation (LuaHandle * - luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - int - result = - thisScriptManager-> - registerCellAreaTriggerEventForUnitToLocation (luaArguments. - getInt (-2), - luaArguments. - getVec4i (-1)); - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::registerCellTriggerEventForFactionToUnit (LuaHandle * - luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - int - result = - thisScriptManager-> - registerCellTriggerEventForFactionToUnit (luaArguments.getInt (-2), - luaArguments.getInt (-1)); - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::registerCellTriggerEventForFactionToLocation (LuaHandle * - luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - int - result = - thisScriptManager-> - registerCellTriggerEventForFactionToLocation (luaArguments. - getInt (-2), - luaArguments. - getVec2i (-1)); - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager:: - registerCellAreaTriggerEventForFactionToLocation (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - int - result = - thisScriptManager-> - registerCellAreaTriggerEventForFactionToLocation (luaArguments. - getInt (-2), - luaArguments. - getVec4i (-1)); - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::registerCellAreaTriggerEvent (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - int - result = - thisScriptManager->registerCellAreaTriggerEvent (luaArguments. - getVec4i (-1)); - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getCellTriggerEventCount (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - int - result = - thisScriptManager->getCellTriggerEventCount (luaArguments. - getInt (-1)); - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::unregisterCellTriggerEvent (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->unregisterCellTriggerEvent (luaArguments. - getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::startTimerEvent (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - int - result = thisScriptManager->startTimerEvent (); - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::startEfficientTimerEvent (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - int - result = - thisScriptManager->startEfficientTimerEvent (luaArguments. - getInt (-1)); - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::stopTimerEvent (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - int - result = - thisScriptManager->stopTimerEvent (luaArguments.getInt (-1)); - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::resetTimerEvent (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - int - result = - thisScriptManager->resetTimerEvent (luaArguments.getInt (-1)); - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getTimerEventSecondsElapsed (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - int - result = - thisScriptManager->getTimerEventSecondsElapsed (luaArguments. - getInt (-1)); - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::setPlayerAsWinner (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->setPlayerAsWinner (luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::endGame (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->endGame (); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::startPerformanceTimer (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->startPerformanceTimer (); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::endPerformanceTimer (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->endPerformanceTimer (); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getPerformanceTimerResults (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - Vec2i - results = thisScriptManager->getPerformanceTimerResults (); - luaArguments.returnVec2i (results); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getStartLocation (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - Vec2i - pos = - thisScriptManager->getStartLocation (luaArguments.getInt (-1)); - luaArguments.returnVec2i (pos); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getUnitPosition (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - Vec2i - pos = thisScriptManager->getUnitPosition (luaArguments.getInt (-1)); - luaArguments.returnVec2i (pos); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::setUnitPosition (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->setUnitPosition (luaArguments.getInt (-2), - luaArguments.getVec2i (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::addCellMarker (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - try - { - //printf("LUA addCellMarker --> START\n"); - - int - factionIndex = luaArguments.getInt (-4); - - //printf("LUA addCellMarker --> START 1\n"); - - Vec2i - pos = luaArguments.getVec2i (-1); - - //printf("LUA addCellMarker --> START 2\n"); - - string - note = luaArguments.getString (-3); - - //printf("LUA addCellMarker --> START 3\n"); - - string - texture = luaArguments.getString (-2); - - //printf("LUA addCellMarker --> faction [%d] pos [%s] note [%s] texture [%s]\n",factionIndex,pos.getString().c_str(),note.c_str(),texture.c_str()); - - thisScriptManager->addCellMarker (pos, factionIndex, note, texture); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::removeCellMarker (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - try - { - int - factionIndex = luaArguments.getInt (-2); - Vec2i - pos = luaArguments.getVec2i (-1); - - thisScriptManager->removeCellMarker (pos, factionIndex); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::showMarker (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - try - { - int - flashCount = luaArguments.getInt (-5); - //printf("LUA addCellMarker --> START\n"); - - int - factionIndex = luaArguments.getInt (-4); - - //printf("LUA addCellMarker --> START 1\n"); - - Vec2i - pos = luaArguments.getVec2i (-1); - - //printf("LUA addCellMarker --> START 2\n"); - - string - note = luaArguments.getString (-3); - - //printf("LUA addCellMarker --> START 3\n"); - - string - texture = luaArguments.getString (-2); - - //printf("LUA addCellMarker --> faction [%d] pos [%s] note [%s] texture [%s]\n",factionIndex,pos.getString().c_str(),note.c_str(),texture.c_str()); - - thisScriptManager->showMarker (pos, factionIndex, note, texture, - flashCount); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getUnitFaction (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - int - factionIndex = - thisScriptManager->getUnitFaction (luaArguments.getInt (-1)); - luaArguments.returnInt (factionIndex); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getUnitName (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - const string - unitname = - thisScriptManager->getUnitName (luaArguments.getInt (-1)); - luaArguments.returnString (unitname); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getUnitDisplayName (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - const string - unitname = - thisScriptManager->getUnitDisplayName (luaArguments.getInt (-1)); - luaArguments.returnString (unitname); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - - int - ScriptManager::getResourceAmount (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getResourceAmount (luaArguments. - getString (-2), - luaArguments.getInt (-1))); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getLastCreatedUnitName (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnString (thisScriptManager-> - getLastCreatedUnitName ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getLastCreatedUnitId (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager->getLastCreatedUnitId ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getCellTriggeredEventId (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getCellTriggeredEventId ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getTimerTriggeredEventId (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getTimerTriggeredEventId ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getCellTriggeredEventAreaEntryUnitId (LuaHandle * - luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getCellTriggeredEventAreaEntryUnitId ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getCellTriggeredEventAreaExitUnitId (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getCellTriggeredEventAreaExitUnitId ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getCellTriggeredEventUnitId (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getCellTriggeredEventUnitId ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::setRandomGenInit (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->setRandomGenInit (luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getRandomGen (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getRandomGen (luaArguments.getInt (-2), - luaArguments.getInt (-1))); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getWorldFrameCount (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager->getWorldFrameCount ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getLastDeadUnitName (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnString (thisScriptManager->getLastDeadUnitName ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getLastDeadUnitId (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager->getLastDeadUnitId ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getLastDeadUnitCauseOfDeath (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getLastDeadUnitCauseOfDeath ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getLastDeadUnitKillerName (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnString (thisScriptManager-> - getLastDeadUnitKillerName ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getLastDeadUnitKillerId (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getLastDeadUnitKillerId ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getLastAttackedUnitName (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnString (thisScriptManager-> - getLastAttackedUnitName ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getLastAttackedUnitId (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager->getLastAttackedUnitId ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getLastAttackingUnitName (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnString (thisScriptManager-> - getLastAttackingUnitName ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getLastAttackingUnitId (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager->getLastAttackingUnitId ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getSystemMacroValue (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnString (thisScriptManager-> - getSystemMacroValue (luaArguments. - getString (-1))); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::scenarioDir (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnString (thisScriptManager-> - getSystemMacroValue ("$SCENARIO_PATH")); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getPlayerName (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnString (thisScriptManager-> - getPlayerName (luaArguments.getInt (-1))); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getUnitCount (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getUnitCount (luaArguments.getInt (-1))); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getUnitCountOfType (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getUnitCountOfType (luaArguments.getInt (-2), - luaArguments. - getString (-1))); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::DisplayFormattedText (LuaHandle * luaHandle) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - try - { - //const char *ret; - //lua_lock(luaHandle); - //luaC_checkGC(luaHandle); - - int - args = lua_gettop (luaHandle); - if (lua_checkstack (luaHandle, args + 1)) - { - LuaArguments - luaArguments (luaHandle); - string - fmt = luaArguments.getString (-args); - //va_list argList; - //va_start(argList, fmt.c_str() ); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "DisplayFormattedText args = %d!\n", - args); - - const int - max_args_allowed = 8; - if (args == 1) - { - thisScriptManager->DisplayFormattedText (fmt.c_str ()); - } - else if (args == 2) - { - thisScriptManager->DisplayFormattedText (fmt.c_str (), - luaArguments. - getGenericData (-args - + - 1)); - } - else if (args == 3) - { - thisScriptManager->DisplayFormattedText (fmt.c_str (), - luaArguments. - getGenericData (-args - + 1), - luaArguments. - getGenericData (-args - + - 2)); - } - else if (args == 4) - { - thisScriptManager->DisplayFormattedText (fmt.c_str (), - luaArguments. - getGenericData (-args - + 1), - luaArguments. - getGenericData (-args - + 2), - luaArguments. - getGenericData (-args - + - 3)); - } - else if (args == 5) - { - thisScriptManager->DisplayFormattedText (fmt.c_str (), - luaArguments. - getGenericData (-args - + 1), - luaArguments. - getGenericData (-args - + 2), - luaArguments. - getGenericData (-args - + 3), - luaArguments. - getGenericData (-args - + - 4)); - } - else if (args == 6) - { - thisScriptManager->DisplayFormattedText (fmt.c_str (), - luaArguments. - getGenericData (-args - + 1), - luaArguments. - getGenericData (-args - + 2), - luaArguments. - getGenericData (-args - + 3), - luaArguments. - getGenericData (-args - + 4), - luaArguments. - getGenericData (-args - + - 5)); - } - else if (args == 7) - { - thisScriptManager->DisplayFormattedText (fmt.c_str (), - luaArguments. - getGenericData (-args - + 1), - luaArguments. - getGenericData (-args - + 2), - luaArguments. - getGenericData (-args - + 3), - luaArguments. - getGenericData (-args - + 4), - luaArguments. - getGenericData (-args - + 5), - luaArguments. - getGenericData (-args - + - 6)); - } - else if (args == max_args_allowed) - { - thisScriptManager->DisplayFormattedText (fmt.c_str (), - luaArguments. - getGenericData (-args - + 1), - luaArguments. - getGenericData (-args - + 2), - luaArguments. - getGenericData (-args - + 3), - luaArguments. - getGenericData (-args - + 4), - luaArguments. - getGenericData (-args - + 5), - luaArguments. - getGenericData (-args - + 6), - luaArguments. - getGenericData (-args - + - 7)); - } - else - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Invalid parameter count in method [%s] args = %d [argument count must be between 1 and %d]", - __FUNCTION__, args, max_args_allowed); - throw - megaglest_runtime_error (szBuf); - } - - //va_end(argList); - } - //lua_unlock(luaHandle); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return 1; - -/* - int args=lua_gettop(luaHandle); - if(lua_checkstack(luaHandle, args+1)) - { - va_list argList; - int i; - //lua_getfield(luaHandle, LUA_GLOBALSINDEX, "print"); - for(i = 1;i <= args; i++) { - lua_pushvalue(luaHandle, i); - } - lua_call(luaHandle, args, 0); - } - else - { - return luaL_error(luaHandle, "cannot grow stack"); - } -*/ - -/* - luax_getfunction(L, mod, fn); - for (int i = 0; i < n; i++) { - lua_pushvalue(L, idxs[i]); // The arguments. + Glest { + namespace + Game { + + ScriptManagerMessage::ScriptManagerMessage() : + text(""), + header("") { + this->factionIndex = -1; + this-> + teamIndex = -1; + this-> + messageNotTranslated = true; } - lua_call(L, n, 1); // Call the function, n args, one return value. - lua_replace(L, idxs[0]); // Replace the initial argument with the new object. - return 0; -*/ - } - - int - ScriptManager::addConsoleLangText (LuaHandle * luaHandle) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - try - { - //const char *ret; - //lua_lock(luaHandle); - //luaC_checkGC(luaHandle); - - int - args = lua_gettop (luaHandle); - if (lua_checkstack (luaHandle, args + 1)) - { - LuaArguments - luaArguments (luaHandle); - string - fmt = luaArguments.getString (-args); - //va_list argList; - //va_start(argList, fmt.c_str() ); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "DisplayFormattedText args = %d!\n", - args); - - const int - max_args_allowed = 8; - if (args == 1) - { - thisScriptManager->addConsoleLangText (Lang::getInstance (). - getScenarioString - (fmt).c_str ()); - } - else if (args == 2) - { - thisScriptManager->addConsoleLangText (Lang::getInstance (). - getScenarioString - (fmt).c_str (), - luaArguments. - getGenericData (-args + - 1)); - } - else if (args == 3) - { - thisScriptManager->addConsoleLangText (Lang::getInstance (). - getScenarioString - (fmt).c_str (), - luaArguments. - getGenericData (-args + - 1), - luaArguments. - getGenericData (-args + - 2)); - } - else if (args == 4) - { - thisScriptManager->addConsoleLangText (Lang::getInstance (). - getScenarioString - (fmt).c_str (), - luaArguments. - getGenericData (-args + - 1), - luaArguments. - getGenericData (-args + - 2), - luaArguments. - getGenericData (-args + - 3)); - } - else if (args == 5) - { - thisScriptManager->addConsoleLangText (Lang::getInstance (). - getScenarioString - (fmt).c_str (), - luaArguments. - getGenericData (-args + - 1), - luaArguments. - getGenericData (-args + - 2), - luaArguments. - getGenericData (-args + - 3), - luaArguments. - getGenericData (-args + - 4)); - } - else if (args == 6) - { - thisScriptManager->addConsoleLangText (Lang::getInstance (). - getScenarioString - (fmt).c_str (), - luaArguments. - getGenericData (-args + - 1), - luaArguments. - getGenericData (-args + - 2), - luaArguments. - getGenericData (-args + - 3), - luaArguments. - getGenericData (-args + - 4), - luaArguments. - getGenericData (-args + - 5)); - } - else if (args == 7) - { - thisScriptManager->addConsoleLangText (Lang::getInstance (). - getScenarioString - (fmt).c_str (), - luaArguments. - getGenericData (-args + - 1), - luaArguments. - getGenericData (-args + - 2), - luaArguments. - getGenericData (-args + - 3), - luaArguments. - getGenericData (-args + - 4), - luaArguments. - getGenericData (-args + - 5), - luaArguments. - getGenericData (-args + - 6)); - } - else if (args == max_args_allowed) - { - thisScriptManager->addConsoleLangText (Lang::getInstance (). - getScenarioString - (fmt).c_str (), - luaArguments. - getGenericData (-args + - 1), - luaArguments. - getGenericData (-args + - 2), - luaArguments. - getGenericData (-args + - 3), - luaArguments. - getGenericData (-args + - 4), - luaArguments. - getGenericData (-args + - 5), - luaArguments. - getGenericData (-args + - 6), - luaArguments. - getGenericData (-args + - 7)); - } - else - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Invalid parameter count in method [%s] args = %d [argument count must be between 1 and %d]", - __FUNCTION__, args, max_args_allowed); - throw - megaglest_runtime_error (szBuf); - } - - //va_end(argList); - } - //lua_unlock(luaHandle); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return 1; - } - - int - ScriptManager::DisplayFormattedLangText (LuaHandle * luaHandle) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - try - { - //const char *ret; - //lua_lock(luaHandle); - //luaC_checkGC(luaHandle); - - int - args = lua_gettop (luaHandle); - if (lua_checkstack (luaHandle, args + 1)) - { - LuaArguments - luaArguments (luaHandle); - string - fmt = luaArguments.getString (-args); - //va_list argList; - //va_start(argList, fmt.c_str() ); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "DisplayFormattedText args = %d!\n", - args); - - const int - max_args_allowed = 8; - if (args == 1) - { - thisScriptManager-> - DisplayFormattedLangText (Lang::getInstance (). - getScenarioString (fmt).c_str ()); - } - else if (args == 2) - { - thisScriptManager-> - DisplayFormattedLangText (Lang::getInstance (). - getScenarioString (fmt).c_str (), - luaArguments. - getGenericData (-args + 1)); - } - else if (args == 3) - { - thisScriptManager-> - DisplayFormattedLangText (Lang::getInstance (). - getScenarioString (fmt).c_str (), - luaArguments. - getGenericData (-args + 1), - luaArguments. - getGenericData (-args + 2)); - } - else if (args == 4) - { - thisScriptManager-> - DisplayFormattedLangText (Lang::getInstance (). - getScenarioString (fmt).c_str (), - luaArguments. - getGenericData (-args + 1), - luaArguments. - getGenericData (-args + 2), - luaArguments. - getGenericData (-args + 3)); - } - else if (args == 5) - { - thisScriptManager-> - DisplayFormattedLangText (Lang::getInstance (). - getScenarioString (fmt).c_str (), - luaArguments. - getGenericData (-args + 1), - luaArguments. - getGenericData (-args + 2), - luaArguments. - getGenericData (-args + 3), - luaArguments. - getGenericData (-args + 4)); - } - else if (args == 6) - { - thisScriptManager-> - DisplayFormattedLangText (Lang::getInstance (). - getScenarioString (fmt).c_str (), - luaArguments. - getGenericData (-args + 1), - luaArguments. - getGenericData (-args + 2), - luaArguments. - getGenericData (-args + 3), - luaArguments. - getGenericData (-args + 4), - luaArguments. - getGenericData (-args + 5)); - } - else if (args == 7) - { - thisScriptManager-> - DisplayFormattedLangText (Lang::getInstance (). - getScenarioString (fmt).c_str (), - luaArguments. - getGenericData (-args + 1), - luaArguments. - getGenericData (-args + 2), - luaArguments. - getGenericData (-args + 3), - luaArguments. - getGenericData (-args + 4), - luaArguments. - getGenericData (-args + 5), - luaArguments. - getGenericData (-args + 6)); - } - else if (args == max_args_allowed) - { - thisScriptManager-> - DisplayFormattedLangText (Lang::getInstance (). - getScenarioString (fmt).c_str (), - luaArguments. - getGenericData (-args + 1), - luaArguments. - getGenericData (-args + 2), - luaArguments. - getGenericData (-args + 3), - luaArguments. - getGenericData (-args + 4), - luaArguments. - getGenericData (-args + 5), - luaArguments. - getGenericData (-args + 6), - luaArguments. - getGenericData (-args + 7)); - } - else - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Invalid parameter count in method [%s] args = %d [argument count must be between 1 and %d]", - __FUNCTION__, args, max_args_allowed); - throw - megaglest_runtime_error (szBuf); - } - - //va_end(argList); - } - //lua_unlock(luaHandle); - - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return 1; - } - - int - ScriptManager::getGameWon (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager->getGameWon ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getIsGameOver (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager->getIsGameOver ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::loadScenario (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->loadScenario (luaArguments.getString (-2), - luaArguments.getInt (-1) != 0); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getUnitsForFaction (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - vector < int > - units = - thisScriptManager->getUnitsForFaction (luaArguments.getInt (-3), - luaArguments.getString (-2), - luaArguments.getInt (-1)); - luaArguments.returnVectorInt (units); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - - } - - int - ScriptManager::getUnitCurrentField (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getUnitCurrentField (luaArguments. - getInt (-1))); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getIsUnitAlive (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getIsUnitAlive (luaArguments.getInt (-1))); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::isFreeCellsOrHasUnit (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - try - { - int - result = - thisScriptManager->isFreeCellsOrHasUnit (luaArguments.getInt (-3), - luaArguments.getInt (-2), - luaArguments. - getVec2i (-1)); - - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::isFreeCells (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - - try - { - int - result = thisScriptManager->isFreeCells (luaArguments.getInt (-3), - luaArguments.getInt (-2), - luaArguments. - getVec2i (-1)); - - luaArguments.returnInt (result); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getHumanFactionId (LuaHandle * luaHandle) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager->getHumanFactionId ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::highlightUnit (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->highlightUnit (luaArguments.getInt (-4), - luaArguments.getFloat (-3), - luaArguments.getFloat (-2), - luaArguments.getVec4f (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::unhighlightUnit (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->unhighlightUnit (luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::giveStopCommand (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->giveStopCommand (luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::selectUnit (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - selectUnit (luaArguments.getInt (-1))); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::unselectUnit (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->unselectUnit (luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::addUnitToGroupSelection (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->addUnitToGroupSelection (luaArguments.getInt (-2), - luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::recallGroupSelection (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->recallGroupSelection (luaArguments.getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::removeUnitFromGroupSelection (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->removeUnitFromGroupSelection (luaArguments. - getInt (-2), - luaArguments. - getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::setAttackWarningsEnabled (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager-> - setAttackWarningsEnabled ((luaArguments.getInt (-1) == - 0 ? false : true)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - int - ScriptManager::getAttackWarningsEnabled (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getAttackWarningsEnabled ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getIsDayTime (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager->getIsDayTime ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - int - ScriptManager::getIsNightTime (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager->getIsNightTime ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - int - ScriptManager::getTimeOfDay (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnFloat (thisScriptManager->getTimeOfDay ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::registerDayNightEvent (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->registerDayNightEvent (); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - int - ScriptManager::unregisterDayNightEvent (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->unregisterDayNightEvent (); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::registerUnitTriggerEvent (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->registerUnitTriggerEvent (luaArguments. - getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - int - ScriptManager::unregisterUnitTriggerEvent (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->unregisterUnitTriggerEvent (luaArguments. - getInt (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - int - ScriptManager::getLastUnitTriggerEventUnitId (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getLastUnitTriggerEventUnitId ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - int - ScriptManager::getLastUnitTriggerEventType (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (static_cast < - int >(thisScriptManager-> - getLastUnitTriggerEventType ())); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getUnitProperty (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - int - value = - thisScriptManager->getUnitProperty (luaArguments.getInt (-2), - static_cast < - UnitTriggerEventType > - (luaArguments.getInt (-1))); - luaArguments.returnInt (value); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - int - ScriptManager::getUnitPropertyName (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - const string - unitname = - thisScriptManager->getUnitPropertyName (luaArguments.getInt (-2), - static_cast < - UnitTriggerEventType > - (luaArguments.getInt (-1))); - luaArguments.returnString (unitname); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::disableSpeedChange (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->disableSpeedChange (); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - int - ScriptManager::enableSpeedChange (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->enableSpeedChange (); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - int - ScriptManager::getSpeedChangeEnabled (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager->getSpeedChangeEnabled ()); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::storeSaveGameData (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - thisScriptManager->storeSaveGameData (luaArguments.getString (-2), - luaArguments.getString (-1)); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::loadSaveGameData (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnString (thisScriptManager-> - loadSaveGameData (luaArguments. - getString (-1))); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - } - - int - ScriptManager::getFactionPlayerType (LuaHandle * luaHandle) - { - LuaArguments - luaArguments (luaHandle); - try - { - luaArguments.returnInt (thisScriptManager-> - getFactionPlayerType (luaArguments. - getInt (-1))); - } - catch (const megaglest_runtime_error & ex) - { - error (luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); - } - - return luaArguments.getReturnCount (); - - } - - void - ScriptManager::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode * - scriptManagerNode = rootNode->addChild ("ScriptManager"); - - //lua -// string code; - scriptManagerNode->addAttribute ("code", code, mapTagReplacements); -// LuaScript luaScript; - - luaScript.beginCall ("onSave"); - luaScript.endCall (); - - if (LuaScript::getDebugModeEnabled () == true) - printf ("After onSave luaSavedGameData.size() = %d\n", - (int) luaSavedGameData.size ()); - for (std::map < string, string >::iterator iterMap = - luaSavedGameData.begin (); iterMap != luaSavedGameData.end (); - ++iterMap) - { - - XmlNode * - savedGameDataItemNode = - scriptManagerNode->addChild ("SavedGameDataItem"); - - savedGameDataItemNode->addAttribute ("key", iterMap->first, - mapTagReplacements); - savedGameDataItemNode->addAttribute ("value", iterMap->second, - mapTagReplacements); - } - -// //world -// World *world; -// GameCamera *gameCamera; -// -// //misc -// MessageQueue messageQueue; - for (std::list < ScriptManagerMessage >::iterator it = - messageQueue.begin (); it != messageQueue.end (); ++it) - { - (*it).saveGame (scriptManagerNode); - } - - //printf("==== ScriptManager Savegame messageBox [%d][%s][%s] displayText [%s]\n",messageBox.getEnabled(),messageBox.getText().c_str(),messageBox.getHeader().c_str(),displayText.c_str()); - -// GraphicMessageBox messageBox; - scriptManagerNode->addAttribute ("messageBox_enabled", - intToStr (messageBox.getEnabled ()), - mapTagReplacements); - scriptManagerNode->addAttribute ("messageBox_text", - messageBox.getText (), - mapTagReplacements); - scriptManagerNode->addAttribute ("messageBox_header", - messageBox.getHeader (), - mapTagReplacements); - -// string displayText; - scriptManagerNode->addAttribute ("displayText", displayText, - mapTagReplacements); -// -// //last created unit -// string lastCreatedUnitName; - scriptManagerNode->addAttribute ("lastCreatedUnitName", - lastCreatedUnitName, - mapTagReplacements); -// int lastCreatedUnitId; - scriptManagerNode->addAttribute ("lastCreatedUnitId", - intToStr (lastCreatedUnitId), - mapTagReplacements); -// -// //last dead unit -// string lastDeadUnitName; - scriptManagerNode->addAttribute ("lastDeadUnitName", lastDeadUnitName, - mapTagReplacements); -// int lastDeadUnitId; - scriptManagerNode->addAttribute ("lastDeadUnitId", - intToStr (lastDeadUnitId), - mapTagReplacements); -// int lastDeadUnitCauseOfDeath; - scriptManagerNode->addAttribute ("lastDeadUnitCauseOfDeath", - intToStr (lastDeadUnitCauseOfDeath), - mapTagReplacements); -// -// //last dead unit's killer -// string lastDeadUnitKillerName; - scriptManagerNode->addAttribute ("lastDeadUnitKillerName", - lastDeadUnitKillerName, - mapTagReplacements); -// int lastDeadUnitKillerId; - scriptManagerNode->addAttribute ("lastDeadUnitKillerId", - intToStr (lastDeadUnitKillerId), - mapTagReplacements); -// -// //last attacked unit -// string lastAttackedUnitName; - scriptManagerNode->addAttribute ("lastAttackedUnitName", - lastAttackedUnitName, - mapTagReplacements); -// int lastAttackedUnitId; - scriptManagerNode->addAttribute ("lastAttackedUnitId", - intToStr (lastAttackedUnitId), - mapTagReplacements); -// -// //last attacking unit -// string lastAttackingUnitName; - scriptManagerNode->addAttribute ("lastAttackingUnitName", - lastAttackingUnitName, - mapTagReplacements); -// int lastAttackingUnitId; - scriptManagerNode->addAttribute ("lastAttackingUnitId", - intToStr (lastAttackingUnitId), - mapTagReplacements); -// -// // end game state -// bool gameOver; - scriptManagerNode->addAttribute ("gameOver", intToStr (gameOver), - mapTagReplacements); -// bool gameWon; - scriptManagerNode->addAttribute ("gameWon", intToStr (gameWon), - mapTagReplacements); -// PlayerModifiers playerModifiers[GameConstants::maxPlayers]; - for (unsigned int i = 0; i < (unsigned int) GameConstants::maxPlayers; - ++i) - { - PlayerModifiers & player = playerModifiers[i]; - player.saveGame (scriptManagerNode); - } -// int currentTimerTriggeredEventId; - scriptManagerNode->addAttribute ("currentTimerTriggeredEventId", - intToStr - (currentTimerTriggeredEventId), - mapTagReplacements); -// int currentCellTriggeredEventId; - scriptManagerNode->addAttribute ("currentCellTriggeredEventId", - intToStr (currentCellTriggeredEventId), - mapTagReplacements); -// int currentEventId; - scriptManagerNode->addAttribute ("currentEventId", - intToStr (currentEventId), - mapTagReplacements); -// std::map CellTriggerEventList; - for (std::map < int, CellTriggerEvent >::iterator iterMap = - CellTriggerEventList.begin (); - iterMap != CellTriggerEventList.end (); ++iterMap) - { - XmlNode * - cellTriggerEventListNode = - scriptManagerNode->addChild ("CellTriggerEventList"); - - cellTriggerEventListNode->addAttribute ("key", - intToStr (iterMap->first), - mapTagReplacements); - iterMap->second.saveGame (cellTriggerEventListNode); - } -// std::map TimerTriggerEventList; - for (std::map < int, TimerTriggerEvent >::iterator iterMap = - TimerTriggerEventList.begin (); - iterMap != TimerTriggerEventList.end (); ++iterMap) - { - XmlNode * - timerTriggerEventListNode = - scriptManagerNode->addChild ("TimerTriggerEventList"); - - timerTriggerEventListNode->addAttribute ("key", - intToStr (iterMap->first), - mapTagReplacements); - iterMap->second.saveGame (timerTriggerEventListNode); - } - -// bool inCellTriggerEvent; - scriptManagerNode->addAttribute ("inCellTriggerEvent", - intToStr (inCellTriggerEvent), - mapTagReplacements); -// std::vector unRegisterCellTriggerEventList; - for (unsigned int i = 0; i < unRegisterCellTriggerEventList.size (); - ++i) - { - XmlNode * - unRegisterCellTriggerEventListNode = - scriptManagerNode->addChild ("unRegisterCellTriggerEventList"); - unRegisterCellTriggerEventListNode->addAttribute ("eventId", - intToStr - (unRegisterCellTriggerEventList - [i]), - mapTagReplacements); - } - - scriptManagerNode->addAttribute ("registeredDayNightEvent", - intToStr (registeredDayNightEvent), - mapTagReplacements); - scriptManagerNode->addAttribute ("lastDayNightTriggerStatus", - intToStr (lastDayNightTriggerStatus), - mapTagReplacements); - - for (std::map < int, UnitTriggerEventType >::iterator iterMap = - UnitTriggerEventList.begin (); - iterMap != UnitTriggerEventList.end (); ++iterMap) - { - XmlNode * - unitTriggerEventListNode = - scriptManagerNode->addChild ("UnitTriggerEventList"); - - unitTriggerEventListNode->addAttribute ("unitId", - intToStr (iterMap->first), - mapTagReplacements); - unitTriggerEventListNode->addAttribute ("eventType", - intToStr (iterMap->second), - mapTagReplacements); - } - scriptManagerNode->addAttribute ("lastUnitTriggerEventUnitId", - intToStr (lastUnitTriggerEventUnitId), - mapTagReplacements); - scriptManagerNode->addAttribute ("lastUnitTriggerEventType", - intToStr (lastUnitTriggerEventType), - mapTagReplacements); - - luaScript.saveGame (scriptManagerNode); - } - - void - ScriptManager::loadGame (const XmlNode * rootNode) - { - const XmlNode * - scriptManagerNode = rootNode->getChild ("ScriptManager"); - -// string code; - code = scriptManagerNode->getAttribute ("code")->getValue (); -// LuaScript luaScript; - - vector < XmlNode * >savedGameDataItemNodeList = - scriptManagerNode->getChildList ("SavedGameDataItem"); - - if (LuaScript::getDebugModeEnabled () == true) - printf ("In loadGame savedGameDataItemNodeList.size() = %d\n", - (int) savedGameDataItemNodeList.size ()); - - for (unsigned int i = 0; i < savedGameDataItemNodeList.size (); ++i) - { - XmlNode * - node = savedGameDataItemNodeList[i]; - string - key = node->getAttribute ("key")->getValue (); - string - value = node->getAttribute ("value")->getValue (); - - luaSavedGameData[key] = value; - } - -// //world -// World *world; -// GameCamera *gameCamera; -// -// //misc -// MessageQueue messageQueue; - messageQueue.clear (); - vector < XmlNode * >messageQueueNodeList = - scriptManagerNode->getChildList ("ScriptManagerMessage"); - for (unsigned int i = 0; i < messageQueueNodeList.size (); ++i) - { - XmlNode * - node = messageQueueNodeList[i]; - ScriptManagerMessage - msg; - msg.loadGame (node); - messageQueue.push_back (msg); - } - -// GraphicMessageBox messageBox; - messageBox.setEnabled (scriptManagerNode-> - getAttribute ("messageBox_enabled")-> - getIntValue () != 0); - messageBox.setText (scriptManagerNode-> - getAttribute ("messageBox_text")->getValue ()); - messageBox.setHeader (scriptManagerNode-> - getAttribute ("messageBox_header")->getValue ()); - -// string displayText; - displayText = - scriptManagerNode->getAttribute ("displayText")->getValue (); -// -// //last created unit -// string lastCreatedUnitName; - lastCreatedUnitName = - scriptManagerNode->getAttribute ("lastCreatedUnitName")->getValue (); -// int lastCreatedUnitId; - lastCreatedUnitId = - scriptManagerNode->getAttribute ("lastCreatedUnitId")->getIntValue (); -// -// //last dead unit -// string lastDeadUnitName; - lastDeadUnitName = - scriptManagerNode->getAttribute ("lastDeadUnitName")->getValue (); -// int lastDeadUnitId; - lastDeadUnitId = - scriptManagerNode->getAttribute ("lastDeadUnitId")->getIntValue (); -// int lastDeadUnitCauseOfDeath; - lastDeadUnitCauseOfDeath = - scriptManagerNode->getAttribute ("lastDeadUnitCauseOfDeath")-> - getIntValue (); -// -// //last dead unit's killer -// string lastDeadUnitKillerName; - lastDeadUnitKillerName = - scriptManagerNode->getAttribute ("lastDeadUnitKillerName")-> - getValue (); -// int lastDeadUnitKillerId; - lastDeadUnitKillerId = - scriptManagerNode->getAttribute ("lastDeadUnitKillerId")-> - getIntValue (); -// -// //last attacked unit -// string lastAttackedUnitName; - lastAttackedUnitName = - scriptManagerNode->getAttribute ("lastAttackedUnitName")->getValue (); -// int lastAttackedUnitId; - lastAttackedUnitId = - scriptManagerNode->getAttribute ("lastAttackedUnitId")-> - getIntValue (); -// -// //last attacking unit -// string lastAttackingUnitName; - lastAttackingUnitName = - scriptManagerNode->getAttribute ("lastAttackingUnitName")-> - getValue (); -// int lastAttackingUnitId; - lastAttackingUnitId = - scriptManagerNode->getAttribute ("lastAttackingUnitId")-> - getIntValue (); -// -// // end game state -// bool gameOver; - gameOver = - scriptManagerNode->getAttribute ("gameOver")->getIntValue () != 0; -// bool gameWon; - gameWon = - scriptManagerNode->getAttribute ("gameWon")->getIntValue () != 0; -// PlayerModifiers playerModifiers[GameConstants::maxPlayers]; - vector < XmlNode * >playerModifiersNodeList = - scriptManagerNode->getChildList ("PlayerModifiers"); - for (unsigned int i = 0; i < playerModifiersNodeList.size (); ++i) - { - XmlNode * - node = playerModifiersNodeList[i]; - playerModifiers[i].loadGame (node); - } -// int currentTimerTriggeredEventId; - currentTimerTriggeredEventId = - scriptManagerNode->getAttribute ("currentTimerTriggeredEventId")-> - getIntValue (); -// int currentCellTriggeredEventId; - currentCellTriggeredEventId = - scriptManagerNode->getAttribute ("currentCellTriggeredEventId")-> - getIntValue (); -// int currentEventId; - currentEventId = - scriptManagerNode->getAttribute ("currentEventId")->getIntValue (); -// std::map CellTriggerEventList; - vector < XmlNode * >cellTriggerEventListNodeList = - scriptManagerNode->getChildList ("CellTriggerEventList"); - for (unsigned int i = 0; i < cellTriggerEventListNodeList.size (); ++i) - { - XmlNode * - node = cellTriggerEventListNodeList[i]; - CellTriggerEvent - event; - event.loadGame (node); - CellTriggerEventList[node->getAttribute ("key")->getIntValue ()] = - event; - } - -// std::map TimerTriggerEventList; - vector < XmlNode * >timerTriggerEventListNodeList = - scriptManagerNode->getChildList ("TimerTriggerEventList"); - for (unsigned int i = 0; i < timerTriggerEventListNodeList.size (); ++i) - { - XmlNode * - node = timerTriggerEventListNodeList[i]; - - TimerTriggerEvent - event; - event.loadGame (node); - TimerTriggerEventList[node->getAttribute ("key")->getIntValue ()] = - event; - } - -// bool inCellTriggerEvent; - inCellTriggerEvent = - scriptManagerNode->getAttribute ("inCellTriggerEvent")-> - getIntValue () != 0; -// std::vector unRegisterCellTriggerEventList; - vector < XmlNode * >unRegisterCellTriggerEventListNodeList = - scriptManagerNode->getChildList ("unRegisterCellTriggerEventList"); - for (unsigned int i = 0; - i < unRegisterCellTriggerEventListNodeList.size (); ++i) - { - XmlNode * - node = unRegisterCellTriggerEventListNodeList[i]; - unRegisterCellTriggerEventList.push_back (node-> - getAttribute ("eventId")-> - getIntValue ()); - } - - if (scriptManagerNode->hasAttribute ("registeredDayNightEvent") == true) - { - registeredDayNightEvent = - scriptManagerNode->getAttribute ("registeredDayNightEvent")-> - getIntValue () != 0; - } - if (scriptManagerNode->hasAttribute ("lastDayNightTriggerStatus") == - true) - { - lastDayNightTriggerStatus = - scriptManagerNode->getAttribute ("lastDayNightTriggerStatus")-> - getIntValue (); - } - - vector < XmlNode * >unitTriggerEventListNodeList = - scriptManagerNode->getChildList ("UnitTriggerEventList"); - for (unsigned int i = 0; i < unitTriggerEventListNodeList.size (); ++i) - { - XmlNode * - node = unitTriggerEventListNodeList[i]; - - UnitTriggerEventType - eventType = utet_None; - int - unitId = node->getAttribute ("unitId")->getIntValue (); - if (node->hasAttribute ("eventType") == true) - { - eventType = - static_cast < UnitTriggerEventType > - (node->getAttribute ("eventType")->getIntValue ()); - } - else if (node->hasAttribute ("evenType") == true) - { - eventType = - static_cast < UnitTriggerEventType > - (node->getAttribute ("evenType")->getIntValue ()); - } - UnitTriggerEventList[unitId] = eventType; - } - if (scriptManagerNode->hasAttribute ("lastUnitTriggerEventUnitId") == - true) - { - lastUnitTriggerEventUnitId = - scriptManagerNode->getAttribute ("lastUnitTriggerEventUnitId")-> - getIntValue (); - } - if (scriptManagerNode->hasAttribute ("lastUnitTriggerEventType") == - true) - { - lastUnitTriggerEventType = - static_cast < UnitTriggerEventType > - (scriptManagerNode->getAttribute ("lastUnitTriggerEventType")-> - getIntValue ()); - } - - luaScript.loadGame (scriptManagerNode); - } - - - } + + ScriptManagerMessage::ScriptManagerMessage(const string & textIn, + const string & headerIn, + int factionIndex, + int teamIndex, + bool messageNotTranslated) : + text(textIn), + header(headerIn) { + this->factionIndex = factionIndex; + this-> + teamIndex = teamIndex; + this-> + messageNotTranslated = messageNotTranslated; + } + + void + ScriptManagerMessage::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode * + scriptManagerMessageNode = + rootNode->addChild("ScriptManagerMessage"); + + //string text; + scriptManagerMessageNode->addAttribute("text", text, + mapTagReplacements); + //string header; + scriptManagerMessageNode->addAttribute("header", header, + mapTagReplacements); + scriptManagerMessageNode->addAttribute("factionIndex", + intToStr(factionIndex), + mapTagReplacements); + scriptManagerMessageNode->addAttribute("teamIndex", + intToStr(teamIndex), + mapTagReplacements); + scriptManagerMessageNode->addAttribute("messageNotTranslated", + intToStr(messageNotTranslated), + mapTagReplacements); + } + + void + ScriptManagerMessage::loadGame(const XmlNode * rootNode) { + const XmlNode * + scriptManagerMessageNode = rootNode; + + text = scriptManagerMessageNode->getAttribute("text")->getValue(); + header = scriptManagerMessageNode->getAttribute("header")->getValue(); + factionIndex = + scriptManagerMessageNode->getAttribute("factionIndex")-> + getIntValue(); + teamIndex = + scriptManagerMessageNode->getAttribute("teamIndex")->getIntValue(); + + messageNotTranslated = true; + if (scriptManagerMessageNode->hasAttribute("messageNotTranslated") == + true) { + messageNotTranslated = + (scriptManagerMessageNode->getAttribute("messageNotTranslated")-> + getIntValue() != 0); + } + } + + // ===================================================== + // class PlayerModifiers + // ===================================================== + + PlayerModifiers::PlayerModifiers() { + winner = false; + aiEnabled = true; + consumeEnabled = true; + } + + void + PlayerModifiers::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode * + playerModifiersNode = rootNode->addChild("PlayerModifiers"); + + //bool winner; + playerModifiersNode->addAttribute("winner", intToStr(winner), + mapTagReplacements); + //bool aiEnabled; + playerModifiersNode->addAttribute("aiEnabled", intToStr(aiEnabled), + mapTagReplacements); + //bool consumeEnabled; + playerModifiersNode->addAttribute("consumeEnabled", + intToStr(consumeEnabled), + mapTagReplacements); + } + + void + PlayerModifiers::loadGame(const XmlNode * rootNode) { + const XmlNode * + playerModifiersNode = rootNode; + + winner = + playerModifiersNode->getAttribute("winner")->getIntValue() != 0; + aiEnabled = + playerModifiersNode->getAttribute("aiEnabled")->getIntValue() != 0; + consumeEnabled = + playerModifiersNode->getAttribute("consumeEnabled")-> + getIntValue() != 0; + } + + CellTriggerEvent::CellTriggerEvent() { + type = ctet_Unit; + sourceId = 0; + destId = 0; + //Vec2i destPos; + + triggerCount = 0; + } + + void + CellTriggerEvent::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode * + cellTriggerEventNode = rootNode->addChild("CellTriggerEvent"); + + // CellTriggerEventType type; + cellTriggerEventNode->addAttribute("type", intToStr(type), + mapTagReplacements); + // int sourceId; + cellTriggerEventNode->addAttribute("sourceId", intToStr(sourceId), + mapTagReplacements); + // int destId; + cellTriggerEventNode->addAttribute("destId", intToStr(destId), + mapTagReplacements); + // Vec2i destPos; + cellTriggerEventNode->addAttribute("destPos", destPos.getString(), + mapTagReplacements); + // int triggerCount; + cellTriggerEventNode->addAttribute("triggerCount", + intToStr(triggerCount), + mapTagReplacements); + + // Vec2i destPosEnd; + cellTriggerEventNode->addAttribute("destPosEnd", + destPosEnd.getString(), + mapTagReplacements); + } + + void + CellTriggerEvent::loadGame(const XmlNode * rootNode) { + const XmlNode * + cellTriggerEventNode = rootNode->getChild("CellTriggerEvent"); + + type = + static_cast + (cellTriggerEventNode->getAttribute("type")->getIntValue()); + sourceId = + cellTriggerEventNode->getAttribute("sourceId")->getIntValue(); + destId = cellTriggerEventNode->getAttribute("destId")->getIntValue(); + destPos = + Vec2i::strToVec2(cellTriggerEventNode->getAttribute("destPos")-> + getValue()); + triggerCount = + cellTriggerEventNode->getAttribute("triggerCount")->getIntValue(); + + if (cellTriggerEventNode->hasAttribute("destPosEnd") == true) { + destPosEnd = + Vec2i::strToVec2(cellTriggerEventNode-> + getAttribute("destPosEnd")->getValue()); + } + } + + TimerTriggerEvent::TimerTriggerEvent() { + running = false; + startFrame = 0; + endFrame = 0; + triggerSecondsElapsed = 0; + } + + void + TimerTriggerEvent::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode * + timerTriggerEventNode = rootNode->addChild("TimerTriggerEvent"); + + // bool running; + timerTriggerEventNode->addAttribute("running", intToStr(running), + mapTagReplacements); + // //time_t startTime; + // //time_t endTime; + // int startFrame; + timerTriggerEventNode->addAttribute("startFrame", + intToStr(startFrame), + mapTagReplacements); + // int endFrame; + timerTriggerEventNode->addAttribute("endFrame", intToStr(endFrame), + mapTagReplacements); + + if (triggerSecondsElapsed > 0) { + timerTriggerEventNode->addAttribute("triggerSecondsElapsed", + intToStr + (triggerSecondsElapsed), + mapTagReplacements); + } + } + + void + TimerTriggerEvent::loadGame(const XmlNode * rootNode) { + const XmlNode * + timerTriggerEventNode = rootNode->getChild("TimerTriggerEvent"); + + running = + timerTriggerEventNode->getAttribute("running")->getIntValue() != 0; + startFrame = + timerTriggerEventNode->getAttribute("startFrame")->getIntValue(); + endFrame = + timerTriggerEventNode->getAttribute("endFrame")->getIntValue(); + if (timerTriggerEventNode->hasAttribute("triggerSecondsElapsed") == + true) { + triggerSecondsElapsed = + timerTriggerEventNode->getAttribute("triggerSecondsElapsed")-> + getIntValue(); + } + } + + // ===================================================== + // class ScriptManager + // ===================================================== + ScriptManager * + ScriptManager::thisScriptManager = NULL; + const int + ScriptManager::messageWrapCount = 35; + const int + ScriptManager::displayTextWrapCount = 64; + + ScriptManager::ScriptManager() { + world = NULL; + gameCamera = NULL; + lastCreatedUnitId = -1; + lastDeadUnitId = 0; + lastDeadUnitCauseOfDeath = 0; + lastDeadUnitKillerId = 0; + lastAttackedUnitId = 0; + lastAttackingUnitId = 0; + gameOver = false; + gameWon = false; + currentTimerTriggeredEventId = 0; + currentCellTriggeredEventId = 0; + currentCellTriggeredEventUnitId = 0; + currentEventId = 0; + inCellTriggerEvent = false; + rootNode = NULL; + currentCellTriggeredEventAreaEntryUnitId = 0; + currentCellTriggeredEventAreaExitUnitId = 0; + lastDayNightTriggerStatus = 0; + registeredDayNightEvent = false; + errorCount = 0; + + lastUnitTriggerEventUnitId = -1; + lastUnitTriggerEventType = utet_None; + } + + ScriptManager::~ScriptManager() { + + } + + void + ScriptManager::init(World * world, GameCamera * gameCamera, + const XmlNode * rootNode) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + //printf("In [%s::%s Line: %d] rootNode [%p][%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,rootNode,(rootNode != NULL ? rootNode->getName().c_str() : "none")); + this->rootNode = rootNode; + const Scenario * + scenario = world->getScenario(); + + this->world = world; + this->gameCamera = gameCamera; + + //set static instance + thisScriptManager = this; + + //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + currentEventId = 1; + CellTriggerEventList.clear(); + TimerTriggerEventList.clear(); + + //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //register functions + luaScript.registerFunction(networkShowMessageForFaction, + "networkShowMessageForFaction"); + luaScript.registerFunction(networkShowMessageForTeam, + "networkShowMessageForTeam"); + + luaScript.registerFunction(networkSetCameraPositionForFaction, + "networkSetCameraPositionForFaction"); + luaScript.registerFunction(networkSetCameraPositionForTeam, + "networkSetCameraPositionForTeam"); + + luaScript.registerFunction(showMessage, "showMessage"); + luaScript.registerFunction(setDisplayText, "setDisplayText"); + luaScript.registerFunction(addConsoleText, "addConsoleText"); + luaScript.registerFunction(addConsoleLangText, "addConsoleLangText"); + luaScript.registerFunction(DisplayFormattedText, + "DisplayFormattedText"); + luaScript.registerFunction(DisplayFormattedText, + "displayFormattedText"); + luaScript.registerFunction(DisplayFormattedLangText, + "DisplayFormattedLangText"); + luaScript.registerFunction(DisplayFormattedLangText, + "displayFormattedLangText"); + luaScript.registerFunction(clearDisplayText, "clearDisplayText"); + luaScript.registerFunction(setCameraPosition, "setCameraPosition"); + luaScript.registerFunction(shakeCamera, "shakeCamera"); + luaScript.registerFunction(shakeCameraOnUnit, "shakeCameraOnUnit"); + luaScript.registerFunction(createUnit, "createUnit"); + luaScript.registerFunction(createUnitNoSpacing, "createUnitNoSpacing"); + luaScript.registerFunction(setLockedUnitForFaction, + "setLockedUnitForFaction"); + luaScript.registerFunction(destroyUnit, "destroyUnit"); + luaScript.registerFunction(giveKills, "giveKills"); + luaScript.registerFunction(morphToUnit, "morphToUnit"); + luaScript.registerFunction(moveToUnit, "moveToUnit"); + + luaScript.registerFunction(playStaticSound, "playStaticSound"); + luaScript.registerFunction(playStreamingSound, "playStreamingSound"); + luaScript.registerFunction(stopStreamingSound, "stopStreamingSound"); + luaScript.registerFunction(stopAllSound, "stopAllSound"); + luaScript.registerFunction(togglePauseGame, "togglePauseGame"); + + luaScript.registerFunction(playStaticVideo, "playStaticVideo"); + //luaScript.registerFunction(playStreamingVideo, "playStreamingVideo"); + //luaScript.registerFunction(stopStreamingVideo, "stopStreamingVideo"); + luaScript.registerFunction(stopAllVideo, "stopAllVideo"); + + luaScript.registerFunction(giveResource, "giveResource"); + luaScript.registerFunction(givePositionCommand, "givePositionCommand"); + luaScript.registerFunction(giveProductionCommand, + "giveProductionCommand"); + luaScript.registerFunction(giveAttackCommand, "giveAttackCommand"); + luaScript.registerFunction(giveUpgradeCommand, "giveUpgradeCommand"); + luaScript.registerFunction(giveAttackStoppedCommand, + "giveAttackStoppedCommand"); + luaScript.registerFunction(disableAi, "disableAi"); + luaScript.registerFunction(enableAi, "enableAi"); + luaScript.registerFunction(getAiEnabled, "getAiEnabled"); + luaScript.registerFunction(disableConsume, "disableConsume"); + luaScript.registerFunction(enableConsume, "enableConsume"); + luaScript.registerFunction(getConsumeEnabled, "getConsumeEnabled"); + luaScript.registerFunction(setPlayerAsWinner, "setPlayerAsWinner"); + luaScript.registerFunction(endGame, "endGame"); + + luaScript.registerFunction(startPerformanceTimer, + "startPerformanceTimer"); + luaScript.registerFunction(endPerformanceTimer, "endPerformanceTimer"); + luaScript.registerFunction(getPerformanceTimerResults, + "getPerformanceTimerResults"); + + luaScript.registerFunction(registerCellTriggerEventForUnitToUnit, + "registerCellTriggerEventForUnitToUnit"); + luaScript.registerFunction(registerCellTriggerEventForUnitToLocation, + "registerCellTriggerEventForUnitToLocation"); + luaScript.registerFunction(registerCellTriggerEventForFactionToUnit, + "registerCellTriggerEventForFactionToUnit"); + luaScript. + registerFunction(registerCellTriggerEventForFactionToLocation, + "registerCellTriggerEventForFactionToLocation"); + + luaScript. + registerFunction(registerCellAreaTriggerEventForUnitToLocation, + "registerCellAreaTriggerEventForUnitToLocation"); + luaScript. + registerFunction(registerCellAreaTriggerEventForFactionToLocation, + "registerCellAreaTriggerEventForFactionToLocation"); + luaScript.registerFunction(registerCellAreaTriggerEvent, + "registerCellAreaTriggerEvent"); + + luaScript.registerFunction(getCellTriggerEventCount, + "getCellTriggerEventCount"); + luaScript.registerFunction(unregisterCellTriggerEvent, + "unregisterCellTriggerEvent"); + luaScript.registerFunction(startTimerEvent, "startTimerEvent"); + luaScript.registerFunction(startEfficientTimerEvent, + "startEfficientTimerEvent"); + luaScript.registerFunction(resetTimerEvent, "resetTimerEvent"); + luaScript.registerFunction(stopTimerEvent, "stopTimerEvent"); + luaScript.registerFunction(getTimerEventSecondsElapsed, + "timerEventSecondsElapsed"); + luaScript.registerFunction(getCellTriggeredEventId, + "triggeredCellEventId"); + luaScript.registerFunction(getTimerTriggeredEventId, + "triggeredTimerEventId"); + + luaScript.registerFunction(getCellTriggeredEventAreaEntryUnitId, + "triggeredEventAreaEntryUnitId"); + luaScript.registerFunction(getCellTriggeredEventAreaExitUnitId, + "triggeredEventAreaExitUnitId"); + + luaScript.registerFunction(getCellTriggeredEventUnitId, + "triggeredCellEventUnitId"); + + luaScript.registerFunction(setRandomGenInit, "setRandomGenInit"); + luaScript.registerFunction(getRandomGen, "getRandomGen"); + luaScript.registerFunction(getWorldFrameCount, "getWorldFrameCount"); + + luaScript.registerFunction(getStartLocation, "startLocation"); + luaScript.registerFunction(getIsUnitAlive, "isUnitAlive"); + luaScript.registerFunction(getUnitPosition, "unitPosition"); + luaScript.registerFunction(setUnitPosition, "setUnitPosition"); + + luaScript.registerFunction(addCellMarker, "addCellMarker"); + luaScript.registerFunction(removeCellMarker, "removeCellMarker"); + luaScript.registerFunction(showMarker, "showMarker"); + + luaScript.registerFunction(getUnitFaction, "unitFaction"); + luaScript.registerFunction(getUnitName, "unitName"); + luaScript.registerFunction(getResourceAmount, "resourceAmount"); + + luaScript.registerFunction(getLastCreatedUnitName, + "lastCreatedUnitName"); + luaScript.registerFunction(getLastCreatedUnitId, "lastCreatedUnit"); + + luaScript.registerFunction(getLastDeadUnitName, "lastDeadUnitName"); + luaScript.registerFunction(getLastDeadUnitId, "lastDeadUnit"); + luaScript.registerFunction(getLastDeadUnitCauseOfDeath, + "lastDeadUnitCauseOfDeath"); + luaScript.registerFunction(getLastDeadUnitKillerName, + "lastDeadUnitKillerName"); + luaScript.registerFunction(getLastDeadUnitKillerId, + "lastDeadUnitKiller"); + + luaScript.registerFunction(getLastAttackedUnitName, + "lastAttackedUnitName"); + luaScript.registerFunction(getLastAttackedUnitId, "lastAttackedUnit"); + + luaScript.registerFunction(getLastAttackingUnitName, + "lastAttackingUnitName"); + luaScript.registerFunction(getLastAttackingUnitId, + "lastAttackingUnit"); + + luaScript.registerFunction(getUnitCount, "unitCount"); + luaScript.registerFunction(getUnitCountOfType, "unitCountOfType"); + + luaScript.registerFunction(getIsGameOver, "isGameOver"); + luaScript.registerFunction(getGameWon, "gameWon"); + + luaScript.registerFunction(getSystemMacroValue, "getSystemMacroValue"); + luaScript.registerFunction(scenarioDir, "scenarioDir"); + luaScript.registerFunction(getPlayerName, "getPlayerName"); + luaScript.registerFunction(getPlayerName, "playerName"); + + luaScript.registerFunction(loadScenario, "loadScenario"); + + luaScript.registerFunction(getUnitsForFaction, "getUnitsForFaction"); + luaScript.registerFunction(getUnitCurrentField, "getUnitCurrentField"); + + luaScript.registerFunction(isFreeCellsOrHasUnit, + "isFreeCellsOrHasUnit"); + luaScript.registerFunction(isFreeCells, "isFreeCells"); + + luaScript.registerFunction(getHumanFactionId, "humanFaction"); + + luaScript.registerFunction(highlightUnit, "highlightUnit"); + luaScript.registerFunction(unhighlightUnit, "unhighlightUnit"); + + luaScript.registerFunction(giveStopCommand, "giveStopCommand"); + luaScript.registerFunction(selectUnit, "selectUnit"); + luaScript.registerFunction(unselectUnit, "unselectUnit"); + luaScript.registerFunction(addUnitToGroupSelection, + "addUnitToGroupSelection"); + luaScript.registerFunction(recallGroupSelection, + "recallGroupSelection"); + luaScript.registerFunction(removeUnitFromGroupSelection, + "removeUnitFromGroupSelection"); + luaScript.registerFunction(setAttackWarningsEnabled, + "setAttackWarningsEnabled"); + luaScript.registerFunction(getAttackWarningsEnabled, + "getAttackWarningsEnabled"); + + luaScript.registerFunction(getIsDayTime, "getIsDayTime"); + luaScript.registerFunction(getIsNightTime, "getIsNightTime"); + luaScript.registerFunction(getTimeOfDay, "getTimeOfDay"); + luaScript.registerFunction(registerDayNightEvent, + "registerDayNightEvent"); + luaScript.registerFunction(unregisterDayNightEvent, + "unregisterDayNightEvent"); + + luaScript.registerFunction(registerUnitTriggerEvent, + "registerUnitTriggerEvent"); + luaScript.registerFunction(unregisterUnitTriggerEvent, + "unregisterUnitTriggerEvent"); + luaScript.registerFunction(getLastUnitTriggerEventUnitId, + "lastUnitTriggerEventUnit"); + luaScript.registerFunction(getLastUnitTriggerEventType, + "lastUnitTriggerEventType"); + luaScript.registerFunction(getUnitProperty, "getUnitProperty"); + luaScript.registerFunction(getUnitPropertyName, "getUnitPropertyName"); + luaScript.registerFunction(disableSpeedChange, "disableSpeedChange"); + luaScript.registerFunction(enableSpeedChange, "enableSpeedChange"); + luaScript.registerFunction(getSpeedChangeEnabled, + "getSpeedChangeEnabled"); + + luaScript.registerFunction(storeSaveGameData, "storeSaveGameData"); + luaScript.registerFunction(loadSaveGameData, "loadSaveGameData"); + + luaScript.registerFunction(getFactionPlayerType, + "getFactionPlayerType"); + + //load code + for (int i = 0; i < scenario->getScriptCount(); ++i) { + const Script * + script = scenario->getScript(i); + luaScript.loadCode("function " + script->getName() + "()" + + script->getCode() + "end\n", + script->getName()); + } + + + //!!! + // string data_path= getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + // if(data_path != ""){ + // endPathWithSlash(data_path); + // } + // string sandboxScriptFilename = data_path + "data/core/scripts/sandbox.lua"; + // string sandboxLuaCode = getFileTextContents(sandboxScriptFilename); + // + // //luaScript.loadCode(sandboxLuaCode + "\n", "megaglest_lua_sandbox"); + // luaScript.setSandboxWrapperFunctionName("runsandboxed"); + // luaScript.setSandboxCode(sandboxLuaCode); + // luaScript.runCode(sandboxLuaCode); + + // // Setup the lua security sandbox here + // luaScript.beginCall("megaglest_lua_sandbox"); + // luaScript.endCall(); + + //setup message box + messageBox.init(Lang::getInstance().getString("Ok")); + messageBox.setEnabled(false); + //messageBox.setAutoWordWrap(false); + + //last created unit + lastCreatedUnitId = -1; + lastDeadUnitName = ""; + lastDeadUnitId = -1; + lastDeadUnitCauseOfDeath = ucodNone; + lastDeadUnitKillerName = ""; + lastDeadUnitKillerId = -1; + + lastAttackedUnitName = ""; + lastAttackedUnitId = -1; + lastAttackingUnitName = ""; + lastAttackingUnitId = -1; + + gameOver = false; + gameWon = false; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + try { + // Setup global functions and vars here + luaScript.beginCall("global"); + luaScript.endCall(); + + //call startup function + if (this->rootNode == NULL) { + luaScript.beginCall("startup"); + luaScript.endCall(); + } else { + loadGame(this->rootNode); + this->rootNode = NULL; + + if (LuaScript::getDebugModeEnabled() == true) + printf("Calling onLoad luaSavedGameData.size() = %d\n", + (int) luaSavedGameData.size()); + + luaScript.beginCall("onLoad"); + luaScript.endCall(); + } + } catch (const megaglest_runtime_error & ex) { + //string sErrBuf = ""; + //if(ex.wantStackTrace() == true) { + char + szErrBuf[8096] = ""; + //snprintf(szErrBuf,8096,"In [%s::%s %d]",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + string + sErrBuf = + string(szErrBuf) + + string("The game may no longer be stable!\n\n\t [") + + string(ex.what()) + string("]\n"); + //} + SystemFlags::OutputDebug(SystemFlags::debugError, sErrBuf.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + sErrBuf.c_str()); + + thisScriptManager-> + addMessageToQueue(ScriptManagerMessage + (sErrBuf.c_str(), "error", -1, -1, true)); + thisScriptManager->onMessageBoxOk(false); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } + + // ========================== events =============================================== + + void + ScriptManager::onMessageBoxOk(bool popFront) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + Lang & lang = Lang::getInstance(); + + for (int index = 0; messageQueue.empty() == false; ++index) { + //printf("i = %d messageQueue.size() = %d popFront = %d\n",i,messageQueue.size(),popFront); + if (popFront == true) { + messageQueue.pop_front(); + } + if (messageQueue.empty() == false) { + // printf("onMessageBoxOk [%s] factionIndex = %d [%d] teamIndex = %d [%d][%d]\n", + // wrapString(lang.getScenarioString(messageQueue.front().getText()), messageWrapCount).c_str(), + // messageQueue.front().getFactionIndex(), this->world->getThisFactionIndex(), + // messageQueue.front().getTeamIndex(),this->world->getThisTeamIndex(),this->world->getThisFaction()->getTeam()); + + if ((messageQueue.front().getFactionIndex() < 0 + && messageQueue.front().getTeamIndex() < 0) + || messageQueue.front().getFactionIndex() == + this->world->getThisFactionIndex() + || messageQueue.front().getTeamIndex() == + this->world->getThisTeamIndex()) { + + messageBox.setEnabled(true); + + string + msgText = messageQueue.front().getText(); + string + msgHeader = messageQueue.front().getHeader(); + if (messageQueue.front().getMessageNotTranslated() == + false) { + + msgText = + lang.getScenarioString(messageQueue.front(). + getText()); + msgHeader = + lang.getScenarioString(messageQueue.front(). + getHeader()); + } + messageBox.setText(msgText); + messageBox.setHeader(msgHeader); + break; + } + popFront = true; + } + } + } + + void + ScriptManager::onResourceHarvested() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (this->rootNode == NULL) { + luaScript.beginCall("resourceHarvested"); + luaScript.endCall(); + } + } + + void + ScriptManager::onUnitCreated(const Unit * unit) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (this->rootNode == NULL) { + lastCreatedUnitName = unit->getType()->getName(false); + lastCreatedUnitId = unit->getId(); + luaScript.beginCall("unitCreated"); + luaScript.endCall(); + luaScript.beginCall("unitCreatedOfType_" + + unit->getType()->getName()); + luaScript.endCall(); + } + } + + void + ScriptManager::onUnitDied(const Unit * unit) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (this->rootNode == NULL) { + if (unit->getLastAttackerUnitId() >= 0) { + Unit * + killer = world->findUnitById(unit->getLastAttackerUnitId()); + + if (killer != NULL) { + lastAttackingUnitName = killer->getType()->getName(false); + lastAttackingUnitId = killer->getId(); + + lastDeadUnitKillerName = + killer->getType()->getName(false); + lastDeadUnitKillerId = killer->getId(); + } else { + lastDeadUnitKillerName = ""; + lastDeadUnitKillerId = -1; + } + } + + lastAttackedUnitName = unit->getType()->getName(false); + lastAttackedUnitId = unit->getId(); + + lastDeadUnitName = unit->getType()->getName(false); + lastDeadUnitId = unit->getId(); + lastDeadUnitCauseOfDeath = unit->getCauseOfDeath(); + + luaScript.beginCall("unitDied"); + luaScript.endCall(); + } + } + + void + ScriptManager::onUnitAttacked(const Unit * unit) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (this->rootNode == NULL) { + lastAttackedUnitName = unit->getType()->getName(false); + lastAttackedUnitId = unit->getId(); + luaScript.beginCall("unitAttacked"); + luaScript.endCall(); + } + } + + void + ScriptManager::onUnitAttacking(const Unit * unit) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (this->rootNode == NULL) { + lastAttackingUnitName = unit->getType()->getName(false); + lastAttackingUnitId = unit->getId(); + luaScript.beginCall("unitAttacking"); + luaScript.endCall(); + } + } + + void + ScriptManager::onGameOver(bool won) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + gameWon = won; + luaScript.beginCall("gameOver"); + luaScript.endCall(); + } + + void + ScriptManager::onTimerTriggerEvent() { + if (TimerTriggerEventList.empty() == true) { + return; + } + if (this->rootNode != NULL) { + return; + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] TimerTriggerEventList.size() = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + TimerTriggerEventList.size()); + + for (std::map < int, TimerTriggerEvent >::iterator iterMap = + TimerTriggerEventList.begin(); + iterMap != TimerTriggerEventList.end(); ++iterMap) { + + TimerTriggerEvent & event = iterMap->second; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] event.running = %d, event.startTime = %lld, event.endTime = %lld, diff = %f\n", + __FILE__, __FUNCTION__, __LINE__, + event.running, + (long long int) event.startFrame, + (long long int) event.endFrame, + (event.endFrame - event.startFrame)); + + if (event.running == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + // If using an efficient timer, check if its time to trigger + // on the elapsed check + if (event.triggerSecondsElapsed > 0) { + int + elapsed = + (world->getFrameCount() - + event.startFrame) / GameConstants::updateFps; + if (elapsed < event.triggerSecondsElapsed) { + continue; + } + } + currentTimerTriggeredEventId = iterMap->first; + luaScript.beginCall("timerTriggerEvent"); + luaScript.endCall(); + + if (event.triggerSecondsElapsed > 0) { + int + timerId = iterMap->first; + stopTimerEvent(timerId); + } + } + } + } + + void + ScriptManager::onCellTriggerEvent(Unit * movingUnit) { + if (CellTriggerEventList.empty() == true) { + return; + } + if (this->rootNode != NULL) { + return; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] movingUnit = %p, CellTriggerEventList.size() = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + movingUnit, CellTriggerEventList.size()); + + // remove any delayed removals + unregisterCellTriggerEvent(-1); + + inCellTriggerEvent = true; + if (movingUnit != NULL) { + //ScenarioInfo scenarioInfoStart = world->getScenario()->getInfo(); + + for (std::map < int, CellTriggerEvent >::iterator iterMap = + CellTriggerEventList.begin(); + iterMap != CellTriggerEventList.end(); ++iterMap) { + CellTriggerEvent & event = iterMap->second; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] movingUnit = %d, event.type = %d, movingUnit->getPos() = %s, event.sourceId = %d, event.destId = %d, event.destPos = %s\n", + __FILE__, __FUNCTION__, __LINE__, + movingUnit->getId(), event.type, + movingUnit->getPos().getString(). + c_str(), event.sourceId, + event.destId, + event.destPos.getString(). + c_str()); + + bool + triggerEvent = false; + currentCellTriggeredEventAreaEntryUnitId = 0; + currentCellTriggeredEventAreaExitUnitId = 0; + currentCellTriggeredEventUnitId = 0; + + switch (event.type) { + case ctet_Unit: + { + Unit * + destUnit = world->findUnitById(event.destId); + if (destUnit != NULL) { + if (movingUnit->getId() == event.sourceId) { + bool + srcInDst = + world->getMap()->isInUnitTypeCells(destUnit-> + getType(), + destUnit-> + getPos(), + movingUnit-> + getPos()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] movingUnit = %d, event.type = %d, movingUnit->getPos() = %s, event.sourceId = %d, event.destId = %d, event.destPos = %s, destUnit->getPos() = %s, srcInDst = %d\n", + __FILE__, + __FUNCTION__, + __LINE__, + movingUnit->getId(), + event.type, + movingUnit->getPos(). + getString().c_str(), + event.sourceId, + event.destId, + event.destPos. + getString().c_str(), + destUnit->getPos(). + getString().c_str(), + srcInDst); + + if (srcInDst == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags:: + debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__). + c_str(), + __FUNCTION__, + __LINE__); + } else { + srcInDst = + world->getMap()-> + isNextToUnitTypeCells(destUnit->getType(), + destUnit->getPos(), + movingUnit-> + getPos()); + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags:: + debugLUA, + "In [%s::%s Line: %d] movingUnit = %d, event.type = %d, movingUnit->getPos() = %s, event.sourceId = %d, event.destId = %d, event.destPos = %s, destUnit->getPos() = %s, srcInDst = %d\n", + __FILE__, + __FUNCTION__, + __LINE__, + movingUnit-> + getId(), + event.type, + movingUnit-> + getPos(). + getString(). + c_str(), + event.sourceId, + event.destId, + event.destPos. + getString(). + c_str(), + destUnit-> + getPos(). + getString(). + c_str(), + srcInDst); + } + triggerEvent = srcInDst; + if (triggerEvent == true) { + currentCellTriggeredEventUnitId = + movingUnit->getId(); + } + } + } + } + break; + case ctet_UnitPos: + { + if (movingUnit->getId() == event.sourceId) { + bool + srcInDst = + world->getMap()->isInUnitTypeCells(movingUnit-> + getType(), + event.destPos, + movingUnit-> + getPos()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] movingUnit = %d, event.type = %d, movingUnit->getPos() = %s, event.sourceId = %d, event.destId = %d, event.destPos = %s, srcInDst = %d\n", + __FILE__, __FUNCTION__, + __LINE__, + movingUnit->getId(), + event.type, + movingUnit->getPos(). + getString().c_str(), + event.sourceId, + event.destId, + event.destPos. + getString().c_str(), + srcInDst); + + if (srcInDst == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, + __LINE__); + } + triggerEvent = srcInDst; + + if (triggerEvent == true) { + currentCellTriggeredEventUnitId = + movingUnit->getId(); + } + } + } + break; + + case ctet_UnitAreaPos: + { + if (movingUnit->getId() == event.sourceId) { + bool + srcInDst = false; + + // Cache area lookup so for each unitsize and pos its done only once + bool + foundInCache = false; + std::map < int, + std::map < + Vec2i, + bool > >::iterator + iterFind1 = + event.eventLookupCache.find(movingUnit-> + getType()-> + getSize()); + if (iterFind1 != event.eventLookupCache.end()) { + std::map < Vec2i, bool >::iterator iterFind2 = + iterFind1->second.find(movingUnit->getPos()); + if (iterFind2 != iterFind1->second.end()) { + foundInCache = true; + srcInDst = iterFind2->second; + } + } + + if (foundInCache == false) { + for (int x = event.destPos.x; + srcInDst == false && x <= event.destPosEnd.x; + ++x) { + for (int y = event.destPos.y; + srcInDst == false + && y <= event.destPosEnd.y; ++y) { + srcInDst = + world->getMap()-> + isInUnitTypeCells(movingUnit-> + getType(), Vec2i(x, + y), + movingUnit-> + getPos()); + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags:: + debugLUA, + "In [%s::%s Line: %d] movingUnit = %d, event.type = %d, movingUnit->getPos() = %s, event.sourceId = %d, event.destId = %d, event.destPos = %s, srcInDst = %d\n", + __FILE__, + __FUNCTION__, + __LINE__, + movingUnit-> + getId(), + event.type, + movingUnit-> + getPos(). + getString(). + c_str(), + event. + sourceId, + event.destId, + Vec2i(x, + y). + getString(). + c_str(), + srcInDst); + } + } + + event.eventLookupCache[movingUnit->getType()-> + getSize()][movingUnit-> + getPos()] = + srcInDst; + } + + if (srcInDst == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, + __LINE__); + } + triggerEvent = srcInDst; + if (triggerEvent == true) { + currentCellTriggeredEventUnitId = + movingUnit->getId(); + } + } + } + break; + + case ctet_Faction: + { + Unit * + destUnit = world->findUnitById(event.destId); + if (destUnit != NULL && + movingUnit->getFactionIndex() == event.sourceId) { + bool + srcInDst = + world->getMap()->isInUnitTypeCells(destUnit-> + getType(), + destUnit-> + getPos(), + movingUnit-> + getPos()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] movingUnit = %d, event.type = %d, movingUnit->getPos() = %s, event.sourceId = %d, event.destId = %d, event.destPos = %s, srcInDst = %d\n", + __FILE__, __FUNCTION__, + __LINE__, + movingUnit->getId(), + event.type, + movingUnit->getPos(). + getString().c_str(), + event.sourceId, + event.destId, + event.destPos. + getString().c_str(), + srcInDst); + + if (srcInDst == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, + __LINE__); + } else { + srcInDst = + world->getMap()-> + isNextToUnitTypeCells(destUnit->getType(), + destUnit->getPos(), + movingUnit->getPos()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] movingUnit = %d, event.type = %d, movingUnit->getPos() = %s, event.sourceId = %d, event.destId = %d, event.destPos = %s, destUnit->getPos() = %s, srcInDst = %d\n", + __FILE__, + __FUNCTION__, + __LINE__, + movingUnit->getId(), + event.type, + movingUnit->getPos(). + getString().c_str(), + event.sourceId, + event.destId, + event.destPos. + getString().c_str(), + destUnit->getPos(). + getString().c_str(), + srcInDst); + } + triggerEvent = srcInDst; + if (triggerEvent == true) { + currentCellTriggeredEventUnitId = + movingUnit->getId(); + } + } + } + break; + + case ctet_FactionPos: + { + if (movingUnit->getFactionIndex() == event.sourceId) { + //printf("ctet_FactionPos event.destPos = [%s], movingUnit->getPos() [%s]\n",event.destPos.getString().c_str(),movingUnit->getPos().getString().c_str()); + + bool + srcInDst = + world->getMap()->isInUnitTypeCells(movingUnit-> + getType(), + event.destPos, + movingUnit-> + getPos()); + if (srcInDst == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, + __LINE__); + } + triggerEvent = srcInDst; + if (triggerEvent == true) { + currentCellTriggeredEventUnitId = + movingUnit->getId(); + } + } + } + break; + + case ctet_FactionAreaPos: + { + if (movingUnit->getFactionIndex() == event.sourceId) { + //if(event.sourceId == 1) printf("ctet_FactionPos event.destPos = [%s], movingUnit->getPos() [%s] Unit id = %d\n",event.destPos.getString().c_str(),movingUnit->getPos().getString().c_str(),movingUnit->getId()); + + bool + srcInDst = false; + + // Cache area lookup so for each unitsize and pos its done only once + bool + foundInCache = false; + std::map < int, + std::map < + Vec2i, + bool > >::iterator + iterFind1 = + event.eventLookupCache.find(movingUnit-> + getType()-> + getSize()); + if (iterFind1 != event.eventLookupCache.end()) { + std::map < Vec2i, bool >::iterator iterFind2 = + iterFind1->second.find(movingUnit->getPos()); + if (iterFind2 != iterFind1->second.end()) { + foundInCache = true; + srcInDst = iterFind2->second; + } + } + + if (foundInCache == false) { + for (int x = event.destPos.x; + srcInDst == false && x <= event.destPosEnd.x; + ++x) { + for (int y = event.destPos.y; + srcInDst == false + && y <= event.destPosEnd.y; ++y) { + + srcInDst = + world->getMap()-> + isInUnitTypeCells(movingUnit-> + getType(), Vec2i(x, + y), + movingUnit-> + getPos()); + if (srcInDst == true) { + if (SystemFlags:: + getSystemSettingType + (SystemFlags::debugLUA).enabled) + SystemFlags:: + OutputDebug(SystemFlags:: + debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, + __LINE__); + } + } + } + + event.eventLookupCache[movingUnit->getType()-> + getSize()][movingUnit-> + getPos()] = + srcInDst; + } + + triggerEvent = srcInDst; + if (triggerEvent == true) { + //printf("!!!UNIT IN AREA!!! Faction area pos, moving unit faction= %d, trigger faction = %d, unit id = %d\n",movingUnit->getFactionIndex(),event.sourceId,movingUnit->getId()); + currentCellTriggeredEventUnitId = + movingUnit->getId(); + } + } + } + break; + + case ctet_AreaPos: + { + // Is the unit already in the cell range? If no check if they are entering it + if (event.eventStateInfo.find(movingUnit->getId()) == + event.eventStateInfo.end()) { + //printf("ctet_FactionPos event.destPos = [%s], movingUnit->getPos() [%s]\n",event.destPos.getString().c_str(),movingUnit->getPos().getString().c_str()); + + bool + srcInDst = false; + for (int x = event.destPos.x; + srcInDst == false && x <= event.destPosEnd.x; + ++x) { + for (int y = event.destPos.y; + srcInDst == false && y <= event.destPosEnd.y; + ++y) { + + srcInDst = + world->getMap()-> + isInUnitTypeCells(movingUnit->getType(), + Vec2i(x, y), + movingUnit->getPos()); + if (srcInDst == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags:: + debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__). + c_str(), + __FUNCTION__, + __LINE__); + + currentCellTriggeredEventAreaEntryUnitId = + movingUnit->getId(); + event.eventStateInfo[movingUnit-> + getId()] = + Vec2i(x, y).getString(); + } + } + } + triggerEvent = srcInDst; + if (triggerEvent == true) { + currentCellTriggeredEventUnitId = + movingUnit->getId(); + } + } + // If unit is already in cell range check if they are leaving? + else { + bool + srcInDst = false; + for (int x = event.destPos.x; + srcInDst == false && x <= event.destPosEnd.x; + ++x) { + for (int y = event.destPos.y; + srcInDst == false && y <= event.destPosEnd.y; + ++y) { + + srcInDst = + world->getMap()-> + isInUnitTypeCells(movingUnit->getType(), + Vec2i(x, y), + movingUnit->getPos()); + if (srcInDst == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags:: + debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags:: + debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__). + c_str(), + __FUNCTION__, + __LINE__); + + //event.eventStateInfo[movingUnit->getId()] = Vec2i(x,y); + } + } + } + triggerEvent = (srcInDst == false); + if (triggerEvent == true) { + currentCellTriggeredEventUnitId = + movingUnit->getId(); + } + + if (triggerEvent == true) { + currentCellTriggeredEventAreaExitUnitId = + movingUnit->getId(); + + event.eventStateInfo.erase(movingUnit->getId()); + } + } + } + break; + + } + + if (triggerEvent == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__); + + currentCellTriggeredEventId = iterMap->first; + event.triggerCount++; + + luaScript.beginCall("cellTriggerEvent"); + luaScript.endCall(); + } + + // ScenarioInfo scenarioInfoEnd = world->getScenario()->getInfo(); + // if(scenarioInfoStart.file != scenarioInfoEnd.file) { + // break; + // } + } + } + + inCellTriggerEvent = false; + } + + // ========================== lua wrappers =============================================== + + string + ScriptManager::wrapString(const string & str, int wrapCount) { + string + returnString; + + int + letterCount = 0; + for (int i = 0; i < (int) str.size(); ++i) { + if (letterCount > wrapCount && str[i] == ' ') { + returnString += '\n'; + letterCount = 0; + } else { + returnString += str[i]; + } + ++letterCount; + } + + return returnString; + } + + void + ScriptManager::networkShowMessageForFaction(const string & text, + const string & header, + int factionIndex) { + messageQueue. + push_back(ScriptManagerMessage(text, header, factionIndex)); + thisScriptManager->onMessageBoxOk(false); + } + void + ScriptManager::networkShowMessageForTeam(const string & text, + const string & header, + int teamIndex) { + // Team indexes are 0 based internally (but 1 based in the lua script) so convert + teamIndex--; + messageQueue. + push_back(ScriptManagerMessage(text, header, -1, teamIndex)); + thisScriptManager->onMessageBoxOk(false); + } + + void + ScriptManager::networkSetCameraPositionForFaction(int factionIndex, + const Vec2i & pos) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (factionIndex == this->world->getThisFactionIndex()) { + gameCamera->centerXZ(pos.x, pos.y); + } + } + + void + ScriptManager::networkSetCameraPositionForTeam(int teamIndex, + const Vec2i & pos) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (teamIndex == this->world->getThisTeamIndex()) { + gameCamera->centerXZ(pos.x, pos.y); + } + } + + void + ScriptManager::showMessage(const string & text, const string & header) { + messageQueue.push_back(ScriptManagerMessage(text, header)); + thisScriptManager->onMessageBoxOk(false); + } + + void + ScriptManager::clearDisplayText() { + displayText = ""; + } + + void + ScriptManager::setDisplayText(const string & text) { + displayText = + wrapString(Lang::getInstance().getScenarioString(text), + displayTextWrapCount); + } + + void + ScriptManager::addConsoleText(const string & text) { + world->addConsoleText(text); + } + void + ScriptManager::addConsoleLangText(const char *fmt, ...) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + va_list + argList; + va_start(argList, fmt); + + const int + max_debug_buffer_size = 8096; + char + szBuf[max_debug_buffer_size] = ""; + vsnprintf(szBuf, max_debug_buffer_size - 1, fmt, argList); + + world->addConsoleTextWoLang(szBuf); + va_end(argList); + + } + + void + ScriptManager::DisplayFormattedText(const char *fmt, ...) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + va_list + argList; + va_start(argList, fmt); + + const int + max_debug_buffer_size = 8096; + char + szBuf[max_debug_buffer_size] = ""; + vsnprintf(szBuf, max_debug_buffer_size - 1, fmt, argList); + + displayText = szBuf; + + va_end(argList); + } + void + ScriptManager::DisplayFormattedLangText(const char *fmt, ...) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + va_list + argList; + va_start(argList, fmt); + + const int + max_debug_buffer_size = 8096; + char + szBuf[max_debug_buffer_size] = ""; + vsnprintf(szBuf, max_debug_buffer_size - 1, fmt, argList); + + displayText = szBuf; + + va_end(argList); + } + void + ScriptManager::setCameraPosition(const Vec2i & pos) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + gameCamera->centerXZ(pos.x, pos.y); + } + + void + ScriptManager::shakeCamera(int shakeIntensity, int shakeDuration, + bool cameraDistanceAffected, int unitId) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (cameraDistanceAffected) { + Unit * + unit = world->findUnitById(unitId); + if (unit) { + gameCamera->shake(shakeDuration, shakeIntensity, + cameraDistanceAffected, + unit->getCurrMidHeightVector()); + } + } else { + gameCamera->shake(shakeDuration, shakeIntensity, + cameraDistanceAffected, Vec3f(0.f, 0.f, 0.f)); + } + } + + void + ScriptManager::createUnit(const string & unitName, int factionIndex, + Vec2i pos) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] unit [%s] factionIndex = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + unitName.c_str(), factionIndex); + world->createUnit(unitName, factionIndex, pos); + } + + void + ScriptManager::createUnitNoSpacing(const string & unitName, + int factionIndex, Vec2i pos) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] unit [%s] factionIndex = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + unitName.c_str(), factionIndex); + world->createUnit(unitName, factionIndex, pos, false); + } + + void + ScriptManager::setLockedUnitForFaction(const string & unitName, + int factionIndex, bool lock) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] unit [%s] factionIndex = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + unitName.c_str(), factionIndex); + if (world->getFactionCount() > factionIndex) { + const UnitType * + ut = + world->getFaction(factionIndex)->getType()-> + getUnitType(unitName); + world->getFaction(factionIndex)->setLockedUnitForFaction(ut, + lock); + } else { + throw + megaglest_runtime_error + ("Invalid faction index in setLockedUnitForFaction: " + + intToStr(factionIndex), true); + } + } + + void + ScriptManager::destroyUnit(int unitId) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] unit [%d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, unitId); + Unit * + unit = world->findUnitById(unitId); + if (unit != NULL) { + // Make sure they die + bool + unit_dead = unit->decHp(unit->getHp() * unit->getHp()); + if (unit_dead == false) { + throw + megaglest_runtime_error("unit_dead == false", true); + } + unit->kill(); + // If called from an existing die event we get a stack overflow + //onUnitDied(unit); + } + } + void + ScriptManager::giveKills(int unitId, int amount) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] unit [%d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, unitId); + Unit * + unit = world->findUnitById(unitId); + if (unit != NULL) { + for (int index = 1; index <= amount; ++index) { + unit->incKills(-1); + } + } + } + + void + ScriptManager::playStaticSound(const string & playSound) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] playSound [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + playSound.c_str()); + world->playStaticSound(playSound); + } + void + ScriptManager::playStreamingSound(const string & playSound) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] playSound [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + playSound.c_str()); + world->playStreamingSound(playSound); + } + + void + ScriptManager::stopStreamingSound(const string & playSound) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] playSound [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + playSound.c_str()); + world->stopStreamingSound(playSound); + } + + void + ScriptManager::stopAllSound() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + world->stopAllSound(); + } + + void + ScriptManager::playStaticVideo(const string & playVideo) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] playVideo [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + playVideo.c_str()); + world->playStaticVideo(playVideo); + } + void + ScriptManager::playStreamingVideo(const string & playVideo) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] playVideo [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + playVideo.c_str()); + world->playStreamingVideo(playVideo); + } + + void + ScriptManager::stopStreamingVideo(const string & playVideo) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] playVideo [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + playVideo.c_str()); + world->stopStreamingVideo(playVideo); + } + + void + ScriptManager::stopAllVideo() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + world->stopAllVideo(); + } + + void + ScriptManager::togglePauseGame(int pauseStatus) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] pauseStatus = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + pauseStatus); + world->togglePauseGame((pauseStatus != 0), true); + } + + void + ScriptManager::morphToUnit(int unitId, const string & morphName, + int ignoreRequirements) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] unit [%d] morphName [%s] forceUpgradesIfRequired = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, unitId, + morphName.c_str(), ignoreRequirements); + + world->morphToUnit(unitId, morphName, (ignoreRequirements == 1)); + } + + void + ScriptManager::moveToUnit(int unitId, int destUnitId) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] unit [%d] destUnitId [%d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, unitId, + destUnitId); + + world->moveToUnit(unitId, destUnitId); + } + + void + ScriptManager::giveResource(const string & resourceName, + int factionIndex, int amount) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + world->giveResource(resourceName, factionIndex, amount); + } + + void + ScriptManager::givePositionCommand(int unitId, + const string & commandName, + const Vec2i & pos) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + world->givePositionCommand(unitId, commandName, pos); + } + + void + ScriptManager::giveAttackCommand(int unitId, int unitToAttackId) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + world->giveAttackCommand(unitId, unitToAttackId); + } + + void + ScriptManager::giveProductionCommand(int unitId, + const string & producedName) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + world->giveProductionCommand(unitId, producedName); + } + + void + ScriptManager::giveUpgradeCommand(int unitId, + const string & producedName) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + world->giveUpgradeCommand(unitId, producedName); + } + + void + ScriptManager::giveAttackStoppedCommand(int unitId, + const string & itemName, + int ignoreRequirements) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + world->giveAttackStoppedCommand(unitId, itemName, + (ignoreRequirements == 1)); + } + + void + ScriptManager::disableAi(int factionIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (factionIndex >= 0 && factionIndex < GameConstants::maxPlayers) { + playerModifiers[factionIndex].disableAi(); + disableConsume(factionIndex); // by this we stay somehow compatible with old behaviour + } + } + + void + ScriptManager::enableAi(int factionIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (factionIndex >= 0 && factionIndex < GameConstants::maxPlayers) { + playerModifiers[factionIndex].enableAi(); + } + } + + bool + ScriptManager::getAiEnabled(int factionIndex) { + + if (factionIndex >= 0 && factionIndex < GameConstants::maxPlayers) { + return playerModifiers[factionIndex].getAiEnabled(); + } + return false; + } + + void + ScriptManager::disableConsume(int factionIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (factionIndex >= 0 && factionIndex < GameConstants::maxPlayers) { + playerModifiers[factionIndex].disableConsume(); + } + } + + void + ScriptManager::enableConsume(int factionIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (factionIndex >= 0 && factionIndex < GameConstants::maxPlayers) { + playerModifiers[factionIndex].enableConsume(); + } + } + + bool + ScriptManager::getConsumeEnabled(int factionIndex) { + + if (factionIndex >= 0 && factionIndex < GameConstants::maxPlayers) { + return playerModifiers[factionIndex].getConsumeEnabled(); + } + return false; + } + + int + ScriptManager::registerCellTriggerEventForUnitToUnit(int sourceUnitId, + int destUnitId) { + CellTriggerEvent + trigger; + trigger.type = ctet_Unit; + trigger.sourceId = sourceUnitId; + trigger.destId = destUnitId; + + int + eventId = currentEventId++; + CellTriggerEventList[eventId] = trigger; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] Unit: %d will trigger cell event when reaching unit: %d, eventId = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + sourceUnitId, destUnitId, eventId); + + return eventId; + } + + int + ScriptManager:: + registerCellTriggerEventForUnitToLocation(int sourceUnitId, + const Vec2i & pos) { + CellTriggerEvent + trigger; + trigger.type = ctet_UnitPos; + trigger.sourceId = sourceUnitId; + trigger.destPos = pos; + + int + eventId = currentEventId++; + CellTriggerEventList[eventId] = trigger; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] Unit: %d will trigger cell event when reaching pos: %s, eventId = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + sourceUnitId, pos.getString().c_str(), + eventId); + + return eventId; + } + + int + ScriptManager:: + registerCellAreaTriggerEventForUnitToLocation(int sourceUnitId, + const Vec4i & pos) { + CellTriggerEvent + trigger; + trigger.type = ctet_UnitAreaPos; + trigger.sourceId = sourceUnitId; + trigger.destPos.x = pos.x; + trigger.destPos.y = pos.y; + trigger.destPosEnd.x = pos.z; + trigger.destPosEnd.y = pos.w; + + int + eventId = currentEventId++; + CellTriggerEventList[eventId] = trigger; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] Unit: %d will trigger cell event when reaching pos: %s, eventId = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + sourceUnitId, pos.getString().c_str(), + eventId); + + return eventId; + } + + int + ScriptManager:: + registerCellTriggerEventForFactionToUnit(int sourceFactionId, + int destUnitId) { + CellTriggerEvent + trigger; + trigger.type = ctet_Faction; + trigger.sourceId = sourceFactionId; + trigger.destId = destUnitId; + + int + eventId = currentEventId++; + CellTriggerEventList[eventId] = trigger; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] Faction: %d will trigger cell event when reaching unit: %d, eventId = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + sourceFactionId, destUnitId, eventId); + + return eventId; + } + + int + ScriptManager:: + registerCellTriggerEventForFactionToLocation(int sourceFactionId, + const Vec2i & pos) { + CellTriggerEvent + trigger; + trigger.type = ctet_FactionPos; + trigger.sourceId = sourceFactionId; + trigger.destPos = pos; + + int + eventId = currentEventId++; + CellTriggerEventList[eventId] = trigger; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]Faction: %d will trigger cell event when reaching pos: %s, eventId = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + sourceFactionId, pos.getString().c_str(), + eventId); + + return eventId; + } + + int + ScriptManager:: + registerCellAreaTriggerEventForFactionToLocation(int sourceFactionId, + const Vec4i & pos) { + CellTriggerEvent + trigger; + trigger.type = ctet_FactionAreaPos; + trigger.sourceId = sourceFactionId; + trigger.destPos.x = pos.x; + trigger.destPos.y = pos.y; + trigger.destPosEnd.x = pos.z; + trigger.destPosEnd.y = pos.w; + + int + eventId = currentEventId++; + CellTriggerEventList[eventId] = trigger; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]Faction: %d will trigger cell event when reaching pos: %s, eventId = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + sourceFactionId, pos.getString().c_str(), + eventId); + + return eventId; + } + + int + ScriptManager::registerCellAreaTriggerEvent(const Vec4i & pos) { + CellTriggerEvent + trigger; + trigger.type = ctet_AreaPos; + trigger.sourceId = -1; + trigger.destPos.x = pos.x; + trigger.destPos.y = pos.y; + trigger.destPosEnd.x = pos.z; + trigger.destPosEnd.y = pos.w; + + int + eventId = currentEventId++; + CellTriggerEventList[eventId] = trigger; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] trigger cell event when reaching pos: %s, eventId = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + pos.getString().c_str(), eventId); + + return eventId; + } + + int + ScriptManager::getCellTriggerEventCount(int eventId) { + int + result = 0; + if (CellTriggerEventList.find(eventId) != CellTriggerEventList.end()) { + result = CellTriggerEventList[eventId].triggerCount; + } + + return result; + } + + void + ScriptManager::unregisterCellTriggerEvent(int eventId) { + if (CellTriggerEventList.find(eventId) != CellTriggerEventList.end()) { + if (inCellTriggerEvent == false) { + CellTriggerEventList.erase(eventId); + } else { + unRegisterCellTriggerEventList.push_back(eventId); + } + } + + if (inCellTriggerEvent == false) { + if (unRegisterCellTriggerEventList.empty() == false) { + for (int i = 0; + i < (int) unRegisterCellTriggerEventList.size(); ++i) { + int + delayedEventId = unRegisterCellTriggerEventList[i]; + CellTriggerEventList.erase(delayedEventId); + } + unRegisterCellTriggerEventList.clear(); + } + } + } + + int + ScriptManager::startTimerEvent() { + TimerTriggerEvent + trigger; + trigger.running = true; + //trigger.startTime = time(NULL); + trigger.startFrame = world->getFrameCount(); + //trigger.endTime = 0; + trigger.endFrame = 0; + + int + eventId = currentEventId++; + TimerTriggerEventList[eventId] = trigger; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] TimerTriggerEventList.size() = %d, eventId = %d, trigger.startTime = %lld, trigger.endTime = %lld\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + TimerTriggerEventList.size(), eventId, + (long long int) trigger.startFrame, + (long long int) trigger.endFrame); + + return eventId; + } + + int + ScriptManager::startEfficientTimerEvent(int triggerSecondsElapsed) { + TimerTriggerEvent + trigger; + trigger.running = true; + //trigger.startTime = time(NULL); + trigger.startFrame = world->getFrameCount(); + //trigger.endTime = 0; + trigger.endFrame = 0; + trigger.triggerSecondsElapsed = triggerSecondsElapsed; + + int + eventId = currentEventId++; + TimerTriggerEventList[eventId] = trigger; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] TimerTriggerEventList.size() = %d, eventId = %d, trigger.startTime = %lld, trigger.endTime = %lld\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + TimerTriggerEventList.size(), eventId, + (long long int) trigger.startFrame, + (long long int) trigger.endFrame); + + return eventId; + } + + int + ScriptManager::resetTimerEvent(int eventId) { + int + result = 0; + if (TimerTriggerEventList.find(eventId) != + TimerTriggerEventList.end()) { + TimerTriggerEvent & trigger = TimerTriggerEventList[eventId]; + result = getTimerEventSecondsElapsed(eventId); + + //trigger.startTime = time(NULL); + trigger.startFrame = world->getFrameCount(); + //trigger.endTime = 0; + trigger.endFrame = 0; + trigger.running = true; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] TimerTriggerEventList.size() = %d, eventId = %d, trigger.startTime = %lld, trigger.endTime = %lld, result = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + TimerTriggerEventList.size(), eventId, + (long long int) trigger.startFrame, + (long long int) trigger.endFrame, + result); + } + return result; + } + + int + ScriptManager::stopTimerEvent(int eventId) { + int + result = 0; + if (TimerTriggerEventList.find(eventId) != + TimerTriggerEventList.end()) { + TimerTriggerEvent & trigger = TimerTriggerEventList[eventId]; + //trigger.endTime = time(NULL); + trigger.endFrame = world->getFrameCount(); + trigger.running = false; + result = getTimerEventSecondsElapsed(eventId); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] TimerTriggerEventList.size() = %d, eventId = %d, trigger.startTime = %lld, trigger.endTime = %lld, result = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + TimerTriggerEventList.size(), eventId, + (long long int) trigger.startFrame, + (long long int) trigger.endFrame, + result); + } + + return result; + } + + int + ScriptManager::getTimerEventSecondsElapsed(int eventId) { + int + result = 0; + if (TimerTriggerEventList.find(eventId) != + TimerTriggerEventList.end()) { + TimerTriggerEvent & trigger = TimerTriggerEventList[eventId]; + if (trigger.running) { + //result = (int)difftime(time(NULL),trigger.startTime); + result = + (world->getFrameCount() - + trigger.startFrame) / GameConstants::updateFps; + } else { + //result = (int)difftime(trigger.endTime,trigger.startTime); + result = + (trigger.endFrame - + trigger.startFrame) / GameConstants::updateFps; + } + + //printf("Timer event id = %d seconmds elapsed = %d\n",eventId,result); + } + + return result; + } + + void + ScriptManager::setPlayerAsWinner(int factionIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + + if (factionIndex >= 0 && factionIndex < GameConstants::maxPlayers) { + playerModifiers[factionIndex].setAsWinner(); + } + } + + void + ScriptManager::endGame() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + gameOver = true; + } + + void + ScriptManager::startPerformanceTimer() { + + if (world->getGame() == NULL) { + throw + megaglest_runtime_error("#1 world->getGame() == NULL", true); + } + world->getGame()->startPerformanceTimer(); + + } + + void + ScriptManager::endPerformanceTimer() { + + if (world->getGame() == NULL) { + throw + megaglest_runtime_error("#2 world->getGame() == NULL", true); + } + world->getGame()->endPerformanceTimer(); + + } + + Vec2i + ScriptManager::getPerformanceTimerResults() { + + if (world->getGame() == NULL) { + throw + megaglest_runtime_error("#3 world->getGame() == NULL", true); + } + return world->getGame()->getPerformanceTimerResults(); + } + + Vec2i + ScriptManager::getStartLocation(int factionIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return world->getStartLocation(factionIndex); + } + + + Vec2i + ScriptManager::getUnitPosition(int unitId) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + Vec2i + result = world->getUnitPosition(unitId); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s] unitId = %d, pos [%s]\n", + __FUNCTION__, unitId, + result.getString().c_str()); + + return result; + } + + void + ScriptManager::setUnitPosition(int unitId, Vec2i pos) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return world->setUnitPosition(unitId, pos); + } + + void + ScriptManager::addCellMarker(Vec2i pos, int factionIndex, + const string & note, + const string & textureFile) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + world->addCellMarker(pos, factionIndex, note, textureFile); + } + + void + ScriptManager::removeCellMarker(Vec2i pos, int factionIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return world->removeCellMarker(pos, factionIndex); + } + + void + ScriptManager::showMarker(Vec2i pos, int factionIndex, + const string & note, + const string & textureFile, int flashCount) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + world->showMarker(pos, factionIndex, note, textureFile, flashCount); + } + + int + ScriptManager::getIsUnitAlive(int unitId) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return world->getIsUnitAlive(unitId); + } + + int + ScriptManager::getUnitFaction(int unitId) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return world->getUnitFactionIndex(unitId); + } + const string + ScriptManager::getUnitName(int unitId) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + string + result = ""; + Unit * + unit = world->findUnitById(unitId); + if (unit) { + result = world->findUnitById(unitId)->getType()->getName(false); + } + return result; + } + + const string + ScriptManager::getUnitDisplayName(int unitId) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return world->getUnitName(unitId); + } + + int + ScriptManager::getResourceAmount(const string & resourceName, + int factionIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return world->getResourceAmount(resourceName, factionIndex); + } + + const + string & + ScriptManager::getLastCreatedUnitName() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return lastCreatedUnitName; + } + + int + ScriptManager::getCellTriggeredEventId() { + + return currentCellTriggeredEventId; + } + + int + ScriptManager::getTimerTriggeredEventId() { + + return currentTimerTriggeredEventId; + } + + int + ScriptManager::getCellTriggeredEventAreaEntryUnitId() { + + return currentCellTriggeredEventAreaEntryUnitId; + } + + int + ScriptManager::getCellTriggeredEventAreaExitUnitId() { + + return currentCellTriggeredEventAreaExitUnitId; + } + + int + ScriptManager::getCellTriggeredEventUnitId() { + + return currentCellTriggeredEventUnitId; + } + + void + ScriptManager::setRandomGenInit(int seed) { + + random.init(seed); + } + + int + ScriptManager::getRandomGen(int minVal, int maxVal) { + + return random.randRange(minVal, maxVal); + } + + int + ScriptManager::getWorldFrameCount() { + + return world->getFrameCount(); + } + + bool + ScriptManager::getGameWon() const { + + return + gameWon; + } + + bool + ScriptManager::getIsGameOver() const { + + return + gameOver; + } + + int + ScriptManager::getLastCreatedUnitId() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return lastCreatedUnitId; + } + + const + string & + ScriptManager::getLastDeadUnitName() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return lastDeadUnitName; + } + + int + ScriptManager::getLastDeadUnitId() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return lastDeadUnitId; + } + + int + ScriptManager::getLastDeadUnitCauseOfDeath() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return lastDeadUnitCauseOfDeath; + } + + const + string & + ScriptManager::getLastDeadUnitKillerName() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return lastDeadUnitKillerName; + } + + int + ScriptManager::getLastDeadUnitKillerId() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return lastDeadUnitKillerId; + } + + const + string & + ScriptManager::getLastAttackedUnitName() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return lastAttackedUnitName; + } + + int + ScriptManager::getLastAttackedUnitId() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return lastAttackedUnitId; + } + + const + string & + ScriptManager::getLastAttackingUnitName() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return lastAttackingUnitName; + } + + int + ScriptManager::getLastAttackingUnitId() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return lastAttackingUnitId; + } + + int + ScriptManager::getUnitCount(int factionIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return world->getUnitCount(factionIndex); + } + + int + ScriptManager::getUnitCountOfType(int factionIndex, + const string & typeName) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return world->getUnitCountOfType(factionIndex, typeName); + } + + const string + ScriptManager::getSystemMacroValue(const string & key) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return world->getSystemMacroValue(key); + } + + const string + ScriptManager::getPlayerName(int factionIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return world->getPlayerName(factionIndex); + } + + void + ScriptManager::loadScenario(const string & name, bool keepFactions) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + + world->setQueuedScenario(name, keepFactions); + } + + vector < int > + ScriptManager::getUnitsForFaction(int factionIndex, + const string & commandTypeName, + int field) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + + return world->getUnitsForFaction(factionIndex, commandTypeName, field); + } + + int + ScriptManager::getUnitCurrentField(int unitId) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + + return world->getUnitCurrentField(unitId); + } + + int + ScriptManager::isFreeCellsOrHasUnit(int field, int unitId, Vec2i pos) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + + Unit * + unit = world->findUnitById(unitId); + if (unit == NULL) { + throw + megaglest_runtime_error("unit == NULL", true); + } + int + result = + world->getMap()->isFreeCellsOrHasUnit(pos, + unit->getType()->getSize(), + static_cast (field), + unit); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s] unitId = %d, [%s] pos [%s] field = %d result = %d\n", + __FUNCTION__, unitId, + unit->getType()->getName(false).c_str(), + pos.getString().c_str(), field, result); + + return result; + } + + int + ScriptManager::isFreeCells(int unitSize, int field, Vec2i pos) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + int + result = + world->getMap()->isFreeCellsOrHasUnit(pos, unitSize, + static_cast (field), + NULL); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s] unitSize = %d, pos [%s] field = %d result = %d\n", + __FUNCTION__, unitSize, + pos.getString().c_str(), field, result); + + return result; + } + + int + ScriptManager::getHumanFactionId() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return this->world->getThisFactionIndex(); + } + + void + ScriptManager::highlightUnit(int unitId, float radius, float thickness, + Vec4f color) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + + world->highlightUnit(unitId, radius, thickness, color); + } + + void + ScriptManager::unhighlightUnit(int unitId) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + + world->unhighlightUnit(unitId); + } + + void + ScriptManager::giveStopCommand(int unitId) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + world->giveStopCommand(unitId); + } + + bool + ScriptManager::selectUnit(int unitId) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return world->selectUnit(unitId); + } + + void + ScriptManager::unselectUnit(int unitId) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + world->unselectUnit(unitId); + } + + void + ScriptManager::addUnitToGroupSelection(int unitId, int groupIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + world->addUnitToGroupSelection(unitId, groupIndex); + } + void + ScriptManager::recallGroupSelection(int groupIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + world->recallGroupSelection(groupIndex); + } + void + ScriptManager::removeUnitFromGroupSelection(int unitId, int groupIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + world->removeUnitFromGroupSelection(unitId, groupIndex); + } + + void + ScriptManager::setAttackWarningsEnabled(bool enabled) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + world->setAttackWarningsEnabled(enabled); + } + + bool + ScriptManager::getAttackWarningsEnabled() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + return world->getAttackWarningsEnabled(); + } + + void + ScriptManager::registerUnitTriggerEvent(int unitId) { + UnitTriggerEventList[unitId] = utet_None; + } + + void + ScriptManager::unregisterUnitTriggerEvent(int unitId) { + UnitTriggerEventList.erase(unitId); + } + + int + ScriptManager::getLastUnitTriggerEventUnitId() { + return lastUnitTriggerEventUnitId; + } + UnitTriggerEventType + ScriptManager::getLastUnitTriggerEventType() { + return lastUnitTriggerEventType; + } + + int + ScriptManager::getUnitProperty(int unitId, UnitTriggerEventType type) { + int + result = -1; + + //printf("File: %s line: %d type: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,type); + + Unit * + unit = world->findUnitById(unitId); + if (unit != NULL) { + switch (type) { + case utet_None: + result = -2; + break; + case utet_HPChanged: + result = unit->getHp(); + break; + case utet_EPChanged: + result = unit->getEp(); + break; + case utet_LevelChanged: + result = -3; + if (unit->getLevel() != NULL) { + result = unit->getLevel()->getKills(); + } + break; + case utet_FieldChanged: + result = unit->getCurrField(); + break; + case utet_SkillChanged: + result = -4; + if (unit->getCurrSkill() != NULL) { + result = unit->getCurrSkill()->getClass(); + } + break; + default: + result = -1000; + break; + } + } + //printf("File: %s line: %d result: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,result); + return result; + } + const string + ScriptManager::getUnitPropertyName(int unitId, UnitTriggerEventType type) { + string + result = ""; + Unit * + unit = world->findUnitById(unitId); + if (unit != NULL) { + switch (type) { + case utet_None: + result = ""; + break; + case utet_HPChanged: + result = ""; + break; + case utet_EPChanged: + result = ""; + break; + case utet_LevelChanged: + result = ""; + if (unit->getLevel() != NULL) { + result = unit->getLevel()->getName(false); + } + break; + case utet_FieldChanged: + result = ""; + break; + case utet_SkillChanged: + result = ""; + if (unit->getCurrSkill() != NULL) { + result = unit->getCurrSkill()->getName(); + } + break; + default: + result = "???"; + break; + } + } + return result; + } + + void + ScriptManager::onUnitTriggerEvent(const Unit * unit, + UnitTriggerEventType event) { + //static bool inEvent = false; + //if(inEvent == true) { + // printf("\n\n!!!!!!!!!!!!!!! File: %s line: %d unit [%d - %s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,unit->getId(),unit->getType()->getName().c_str()); + // return; + //} + //inEvent = true; + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + if (UnitTriggerEventList.empty() == false) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + std::map < int, + UnitTriggerEventType >::iterator + iterFind = UnitTriggerEventList.find(unit->getId()); + if (iterFind != UnitTriggerEventList.end()) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + + lastUnitTriggerEventUnitId = unit->getId(); + lastUnitTriggerEventType = event; + + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + + luaScript.beginCall("unitTriggerEvent"); + luaScript.endCall(); + + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + } + //inEvent = false; + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + + void + ScriptManager::registerDayNightEvent() { + registeredDayNightEvent = true; + } + + void + ScriptManager::unregisterDayNightEvent() { + registeredDayNightEvent = false; + } + + void + ScriptManager::onDayNightTriggerEvent() { + if (registeredDayNightEvent == true) { + bool + isDay = (this->getIsDayTime() == 1); + if ((lastDayNightTriggerStatus != 1 && isDay == true) || + (lastDayNightTriggerStatus != 2 && isDay == false)) { + if (isDay == true) { + lastDayNightTriggerStatus = 1; + } else { + lastDayNightTriggerStatus = 2; + } + + printf("Triggering daynight event isDay: %d [%f]\n", isDay, + getTimeOfDay()); + + luaScript.beginCall("dayNightTriggerEvent"); + luaScript.endCall(); + } + } + } + + int + ScriptManager::getIsDayTime() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + + const TimeFlow * + tf = world->getTimeFlow(); + if (tf == NULL) { + throw + megaglest_runtime_error("#1 tf == NULL", true); + } + return tf->isDay(); + } + int + ScriptManager::getIsNightTime() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + + const TimeFlow * + tf = world->getTimeFlow(); + if (tf == NULL) { + throw + megaglest_runtime_error("#2 tf == NULL", true); + } + return tf->isNight(); + } + float + ScriptManager::getTimeOfDay() { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + + const TimeFlow * + tf = world->getTimeFlow(); + if (tf == NULL) { + throw + megaglest_runtime_error("#3 tf == NULL", true); + } + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + return tf->getTime(); + } + + void + ScriptManager::disableSpeedChange() { + if (world->getGame() == NULL) { + throw + megaglest_runtime_error("#4 world->getGame() == NULL"); + } + world->getGame()->setDisableSpeedChange(true); + } + void + ScriptManager::enableSpeedChange() { + if (world->getGame() == NULL) { + throw + megaglest_runtime_error("#5 world->getGame() == NULL"); + } + world->getGame()->setDisableSpeedChange(false); + } + + bool + ScriptManager::getSpeedChangeEnabled() { + if (world->getGame() == NULL) { + throw + megaglest_runtime_error("#6 world->getGame() == NULL"); + } + return world->getGame()->getDisableSpeedChange(); + } + + void + ScriptManager::addMessageToQueue(ScriptManagerMessage msg) { + messageQueue.push_back(msg); + } + + void + ScriptManager::storeSaveGameData(string name, string value) { + + if (LuaScript::getDebugModeEnabled() == true) + printf("storeSaveGameData name [%s] value [%s]\n", name.c_str(), + value.c_str()); + + luaSavedGameData[name] = value; + } + + string + ScriptManager::loadSaveGameData(string name) { + string + value = luaSavedGameData[name]; + + if (LuaScript::getDebugModeEnabled() == true) + printf("loadSaveGameData result name [%s] value [%s]\n", + name.c_str(), value.c_str()); + + return value; + } + + ControlType + ScriptManager::getFactionPlayerType(int factionIndex) { + Faction * + faction = world->getFaction(factionIndex); + if (faction != NULL) { + return faction->getControlType(); + } + return ctClosed; + } + // ========================== lua callbacks =============================================== + + int + ScriptManager::showMessage(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + thisScriptManager->showMessage(luaArguments.getString(-2), + luaArguments.getString(-1)); + return luaArguments.getReturnCount(); + } + + int + ScriptManager::networkShowMessageForFaction(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + try { + thisScriptManager->networkShowMessageForFaction(luaArguments. + getString(-3), + luaArguments. + getString(-2), + luaArguments. + getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::networkShowMessageForTeam(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + try { + thisScriptManager->networkShowMessageForTeam(luaArguments. + getString(-3), + luaArguments. + getString(-2), + luaArguments. + getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::networkSetCameraPositionForFaction(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + try { + thisScriptManager->networkSetCameraPositionForFaction(luaArguments. + getInt(-2), + luaArguments. + getVec2i(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::networkSetCameraPositionForTeam(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + try { + thisScriptManager->networkSetCameraPositionForTeam(luaArguments. + getInt(-2), + luaArguments. + getVec2i(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + + int + ScriptManager::setDisplayText(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + try { + thisScriptManager->setDisplayText(luaArguments.getString(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::addConsoleText(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + try { + thisScriptManager->addConsoleText(luaArguments.getString(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::clearDisplayText(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + try { + thisScriptManager->clearDisplayText(); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::setCameraPosition(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + try { + thisScriptManager-> + setCameraPosition(Vec2i(luaArguments.getVec2i(-1))); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::shakeCamera(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + try { + thisScriptManager->shakeCamera(luaArguments.getInt(-2), + luaArguments.getInt(-1), false, 0); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::shakeCameraOnUnit(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + try { + thisScriptManager->shakeCamera(luaArguments.getInt(-3), + luaArguments.getInt(-2), true, + luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::createUnit(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] unit [%s] factionIndex = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + luaArguments.getString(-3).c_str(), + luaArguments.getInt(-2)); + + try { + thisScriptManager->createUnit(luaArguments.getString(-3), + luaArguments.getInt(-2), + luaArguments.getVec2i(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + void + ScriptManager::error(LuaHandle * luaHandle, + const megaglest_runtime_error * mgErr, + const char *file, const char *function, int line) { + char + szErrBuf[8096] = ""; + char + szErrBuf2[8096] = ""; + + int + luaLine = -1; + const char * + luaSource = ""; + + if (luaHandle != NULL) { + lua_Debug + ar; + lua_getstack(luaHandle, 1, &ar); + lua_getinfo(luaHandle, "nSl", &ar); + + luaLine = ar.currentline; + luaSource = ar.source; + + } + snprintf(szErrBuf, 8096, "in %s::%s %d ", + extractFileFromDirectoryPath(file).c_str(), function, line); + snprintf(szErrBuf2, 8096, "Lua: tag=<%s> line=%d ", luaSource, + luaLine - 1); + string + sErrBuf = string("Error! The game may no longer be stable!\n\n") + + string(szErrBuf) + "\n" + string(szErrBuf2) + "\n\n" + + string(mgErr->what()); + + SystemFlags::OutputDebug(SystemFlags::debugError, sErrBuf.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, sErrBuf.c_str()); + + thisScriptManager-> + addMessageToQueue(ScriptManagerMessage + (sErrBuf.c_str(), + "error " + + intToStr(thisScriptManager->errorCount), -1, -1, + true)); + thisScriptManager->errorCount++; + thisScriptManager->onMessageBoxOk(false); + } + + int + ScriptManager::createUnitNoSpacing(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] unit [%s] factionIndex = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + luaArguments.getString(-3).c_str(), + luaArguments.getInt(-2)); + + try { + thisScriptManager->createUnitNoSpacing(luaArguments.getString(-3), + luaArguments.getInt(-2), + luaArguments.getVec2i(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::destroyUnit(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] unit [%d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + luaArguments.getInt(-1)); + + try { + thisScriptManager->destroyUnit(luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::setLockedUnitForFaction(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] unit [%s] factionIndex = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + luaArguments.getString(-3).c_str(), + luaArguments.getInt(-2)); + + try { + thisScriptManager->setLockedUnitForFaction(luaArguments. + getString(-3), + luaArguments.getInt(-2), + (luaArguments. + getInt(-1) == + 0 ? false : true)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::giveKills(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] unit [%d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + luaArguments.getInt(-1)); + + try { + thisScriptManager->giveKills(luaArguments.getInt(-2), + luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::morphToUnit(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] unit [%d] morphName [%s] forceUpgrade = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + luaArguments.getInt(-3), + luaArguments.getString(-2).c_str(), + luaArguments.getInt(-1)); + + try { + thisScriptManager->morphToUnit(luaArguments.getInt(-3), + luaArguments.getString(-2), + luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::moveToUnit(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] unit [%d] dest unit [%d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + luaArguments.getInt(-2), + luaArguments.getInt(-1)); + + try { + thisScriptManager->moveToUnit(luaArguments.getInt(-2), + luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::playStaticSound(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] sound [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + luaArguments.getString(-1).c_str()); + + try { + thisScriptManager->playStaticSound(luaArguments.getString(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::playStreamingSound(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] sound [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + luaArguments.getString(-1).c_str()); + + try { + thisScriptManager->playStreamingSound(luaArguments.getString(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::stopStreamingSound(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] sound [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + luaArguments.getString(-1).c_str()); + + try { + thisScriptManager->stopStreamingSound(luaArguments.getString(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::stopAllSound(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + try { + thisScriptManager->stopAllSound(); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::playStaticVideo(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] sound [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + luaArguments.getString(-1).c_str()); + + try { + thisScriptManager->playStaticVideo(luaArguments.getString(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::playStreamingVideo(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] sound [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + luaArguments.getString(-1).c_str()); + + try { + thisScriptManager->playStreamingVideo(luaArguments.getString(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::stopStreamingVideo(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] sound [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + luaArguments.getString(-1).c_str()); + + try { + thisScriptManager->stopStreamingVideo(luaArguments.getString(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::stopAllVideo(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + try { + thisScriptManager->stopAllVideo(); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::togglePauseGame(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] value = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + luaArguments.getInt(-1)); + + try { + thisScriptManager->togglePauseGame(luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + int + ScriptManager::giveResource(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->giveResource(luaArguments.getString(-3), + luaArguments.getInt(-2), + luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::givePositionCommand(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->givePositionCommand(luaArguments.getInt(-3), + luaArguments.getString(-2), + luaArguments.getVec2i(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::giveAttackCommand(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->giveAttackCommand(luaArguments.getInt(-2), + luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::giveProductionCommand(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->giveProductionCommand(luaArguments.getInt(-2), + luaArguments. + getString(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::giveUpgradeCommand(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->giveUpgradeCommand(luaArguments.getInt(-2), + luaArguments.getString(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::giveAttackStoppedCommand(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->giveAttackStoppedCommand(luaArguments.getInt(-3), + luaArguments. + getString(-2), + luaArguments. + getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::disableAi(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->disableAi(luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::enableAi(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->enableAi(luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getAiEnabled(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + bool + result = thisScriptManager->getAiEnabled(luaArguments.getInt(-1)); + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::disableConsume(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->disableConsume(luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::enableConsume(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->enableConsume(luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getConsumeEnabled(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + bool + result = + thisScriptManager->getConsumeEnabled(luaArguments.getInt(-1)); + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::registerCellTriggerEventForUnitToUnit(LuaHandle * + luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + int + result = + thisScriptManager-> + registerCellTriggerEventForUnitToUnit(luaArguments.getInt(-2), + luaArguments.getInt(-1)); + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::registerCellTriggerEventForUnitToLocation(LuaHandle * + luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + int + result = + thisScriptManager-> + registerCellTriggerEventForUnitToLocation(luaArguments.getInt(-2), + luaArguments. + getVec2i(-1)); + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::registerCellAreaTriggerEventForUnitToLocation(LuaHandle * + luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + int + result = + thisScriptManager-> + registerCellAreaTriggerEventForUnitToLocation(luaArguments. + getInt(-2), + luaArguments. + getVec4i(-1)); + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::registerCellTriggerEventForFactionToUnit(LuaHandle * + luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + int + result = + thisScriptManager-> + registerCellTriggerEventForFactionToUnit(luaArguments.getInt(-2), + luaArguments.getInt(-1)); + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::registerCellTriggerEventForFactionToLocation(LuaHandle * + luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + int + result = + thisScriptManager-> + registerCellTriggerEventForFactionToLocation(luaArguments. + getInt(-2), + luaArguments. + getVec2i(-1)); + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager:: + registerCellAreaTriggerEventForFactionToLocation(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + int + result = + thisScriptManager-> + registerCellAreaTriggerEventForFactionToLocation(luaArguments. + getInt(-2), + luaArguments. + getVec4i(-1)); + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::registerCellAreaTriggerEvent(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + int + result = + thisScriptManager->registerCellAreaTriggerEvent(luaArguments. + getVec4i(-1)); + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getCellTriggerEventCount(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + int + result = + thisScriptManager->getCellTriggerEventCount(luaArguments. + getInt(-1)); + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::unregisterCellTriggerEvent(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->unregisterCellTriggerEvent(luaArguments. + getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::startTimerEvent(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + int + result = thisScriptManager->startTimerEvent(); + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::startEfficientTimerEvent(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + int + result = + thisScriptManager->startEfficientTimerEvent(luaArguments. + getInt(-1)); + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::stopTimerEvent(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + int + result = + thisScriptManager->stopTimerEvent(luaArguments.getInt(-1)); + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::resetTimerEvent(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + int + result = + thisScriptManager->resetTimerEvent(luaArguments.getInt(-1)); + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getTimerEventSecondsElapsed(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + int + result = + thisScriptManager->getTimerEventSecondsElapsed(luaArguments. + getInt(-1)); + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::setPlayerAsWinner(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->setPlayerAsWinner(luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::endGame(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->endGame(); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::startPerformanceTimer(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->startPerformanceTimer(); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::endPerformanceTimer(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->endPerformanceTimer(); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getPerformanceTimerResults(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + Vec2i + results = thisScriptManager->getPerformanceTimerResults(); + luaArguments.returnVec2i(results); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getStartLocation(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + Vec2i + pos = + thisScriptManager->getStartLocation(luaArguments.getInt(-1)); + luaArguments.returnVec2i(pos); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getUnitPosition(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + Vec2i + pos = thisScriptManager->getUnitPosition(luaArguments.getInt(-1)); + luaArguments.returnVec2i(pos); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::setUnitPosition(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->setUnitPosition(luaArguments.getInt(-2), + luaArguments.getVec2i(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::addCellMarker(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + try { + //printf("LUA addCellMarker --> START\n"); + + int + factionIndex = luaArguments.getInt(-4); + + //printf("LUA addCellMarker --> START 1\n"); + + Vec2i + pos = luaArguments.getVec2i(-1); + + //printf("LUA addCellMarker --> START 2\n"); + + string + note = luaArguments.getString(-3); + + //printf("LUA addCellMarker --> START 3\n"); + + string + texture = luaArguments.getString(-2); + + //printf("LUA addCellMarker --> faction [%d] pos [%s] note [%s] texture [%s]\n",factionIndex,pos.getString().c_str(),note.c_str(),texture.c_str()); + + thisScriptManager->addCellMarker(pos, factionIndex, note, texture); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::removeCellMarker(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + try { + int + factionIndex = luaArguments.getInt(-2); + Vec2i + pos = luaArguments.getVec2i(-1); + + thisScriptManager->removeCellMarker(pos, factionIndex); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::showMarker(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + try { + int + flashCount = luaArguments.getInt(-5); + //printf("LUA addCellMarker --> START\n"); + + int + factionIndex = luaArguments.getInt(-4); + + //printf("LUA addCellMarker --> START 1\n"); + + Vec2i + pos = luaArguments.getVec2i(-1); + + //printf("LUA addCellMarker --> START 2\n"); + + string + note = luaArguments.getString(-3); + + //printf("LUA addCellMarker --> START 3\n"); + + string + texture = luaArguments.getString(-2); + + //printf("LUA addCellMarker --> faction [%d] pos [%s] note [%s] texture [%s]\n",factionIndex,pos.getString().c_str(),note.c_str(),texture.c_str()); + + thisScriptManager->showMarker(pos, factionIndex, note, texture, + flashCount); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getUnitFaction(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + int + factionIndex = + thisScriptManager->getUnitFaction(luaArguments.getInt(-1)); + luaArguments.returnInt(factionIndex); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getUnitName(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + const string + unitname = + thisScriptManager->getUnitName(luaArguments.getInt(-1)); + luaArguments.returnString(unitname); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getUnitDisplayName(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + const string + unitname = + thisScriptManager->getUnitDisplayName(luaArguments.getInt(-1)); + luaArguments.returnString(unitname); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + + int + ScriptManager::getResourceAmount(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getResourceAmount(luaArguments. + getString(-2), + luaArguments.getInt(-1))); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getLastCreatedUnitName(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnString(thisScriptManager-> + getLastCreatedUnitName()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getLastCreatedUnitId(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager->getLastCreatedUnitId()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getCellTriggeredEventId(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getCellTriggeredEventId()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getTimerTriggeredEventId(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getTimerTriggeredEventId()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getCellTriggeredEventAreaEntryUnitId(LuaHandle * + luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getCellTriggeredEventAreaEntryUnitId()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getCellTriggeredEventAreaExitUnitId(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getCellTriggeredEventAreaExitUnitId()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getCellTriggeredEventUnitId(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getCellTriggeredEventUnitId()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::setRandomGenInit(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->setRandomGenInit(luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getRandomGen(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getRandomGen(luaArguments.getInt(-2), + luaArguments.getInt(-1))); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getWorldFrameCount(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager->getWorldFrameCount()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getLastDeadUnitName(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnString(thisScriptManager->getLastDeadUnitName()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getLastDeadUnitId(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager->getLastDeadUnitId()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getLastDeadUnitCauseOfDeath(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getLastDeadUnitCauseOfDeath()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getLastDeadUnitKillerName(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnString(thisScriptManager-> + getLastDeadUnitKillerName()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getLastDeadUnitKillerId(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getLastDeadUnitKillerId()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getLastAttackedUnitName(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnString(thisScriptManager-> + getLastAttackedUnitName()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getLastAttackedUnitId(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager->getLastAttackedUnitId()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getLastAttackingUnitName(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnString(thisScriptManager-> + getLastAttackingUnitName()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getLastAttackingUnitId(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager->getLastAttackingUnitId()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getSystemMacroValue(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnString(thisScriptManager-> + getSystemMacroValue(luaArguments. + getString(-1))); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::scenarioDir(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnString(thisScriptManager-> + getSystemMacroValue("$SCENARIO_PATH")); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getPlayerName(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnString(thisScriptManager-> + getPlayerName(luaArguments.getInt(-1))); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getUnitCount(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getUnitCount(luaArguments.getInt(-1))); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getUnitCountOfType(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getUnitCountOfType(luaArguments.getInt(-2), + luaArguments. + getString(-1))); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::DisplayFormattedText(LuaHandle * luaHandle) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + try { + //const char *ret; + //lua_lock(luaHandle); + //luaC_checkGC(luaHandle); + + int + args = lua_gettop(luaHandle); + if (lua_checkstack(luaHandle, args + 1)) { + LuaArguments + luaArguments(luaHandle); + string + fmt = luaArguments.getString(-args); + //va_list argList; + //va_start(argList, fmt.c_str() ); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "DisplayFormattedText args = %d!\n", + args); + + const int + max_args_allowed = 8; + if (args == 1) { + thisScriptManager->DisplayFormattedText(fmt.c_str()); + } else if (args == 2) { + thisScriptManager->DisplayFormattedText(fmt.c_str(), + luaArguments. + getGenericData(-args + + + 1)); + } else if (args == 3) { + thisScriptManager->DisplayFormattedText(fmt.c_str(), + luaArguments. + getGenericData(-args + + 1), + luaArguments. + getGenericData(-args + + + 2)); + } else if (args == 4) { + thisScriptManager->DisplayFormattedText(fmt.c_str(), + luaArguments. + getGenericData(-args + + 1), + luaArguments. + getGenericData(-args + + 2), + luaArguments. + getGenericData(-args + + + 3)); + } else if (args == 5) { + thisScriptManager->DisplayFormattedText(fmt.c_str(), + luaArguments. + getGenericData(-args + + 1), + luaArguments. + getGenericData(-args + + 2), + luaArguments. + getGenericData(-args + + 3), + luaArguments. + getGenericData(-args + + + 4)); + } else if (args == 6) { + thisScriptManager->DisplayFormattedText(fmt.c_str(), + luaArguments. + getGenericData(-args + + 1), + luaArguments. + getGenericData(-args + + 2), + luaArguments. + getGenericData(-args + + 3), + luaArguments. + getGenericData(-args + + 4), + luaArguments. + getGenericData(-args + + + 5)); + } else if (args == 7) { + thisScriptManager->DisplayFormattedText(fmt.c_str(), + luaArguments. + getGenericData(-args + + 1), + luaArguments. + getGenericData(-args + + 2), + luaArguments. + getGenericData(-args + + 3), + luaArguments. + getGenericData(-args + + 4), + luaArguments. + getGenericData(-args + + 5), + luaArguments. + getGenericData(-args + + + 6)); + } else if (args == max_args_allowed) { + thisScriptManager->DisplayFormattedText(fmt.c_str(), + luaArguments. + getGenericData(-args + + 1), + luaArguments. + getGenericData(-args + + 2), + luaArguments. + getGenericData(-args + + 3), + luaArguments. + getGenericData(-args + + 4), + luaArguments. + getGenericData(-args + + 5), + luaArguments. + getGenericData(-args + + 6), + luaArguments. + getGenericData(-args + + + 7)); + } else { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Invalid parameter count in method [%s] args = %d [argument count must be between 1 and %d]", + __FUNCTION__, args, max_args_allowed); + throw + megaglest_runtime_error(szBuf); + } + + //va_end(argList); + } + //lua_unlock(luaHandle); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return 1; + + /* + int args=lua_gettop(luaHandle); + if(lua_checkstack(luaHandle, args+1)) + { + va_list argList; + int i; + //lua_getfield(luaHandle, LUA_GLOBALSINDEX, "print"); + for(i = 1;i <= args; i++) { + lua_pushvalue(luaHandle, i); + } + lua_call(luaHandle, args, 0); + } + else + { + return luaL_error(luaHandle, "cannot grow stack"); + } + */ + + /* + luax_getfunction(L, mod, fn); + for (int i = 0; i < n; i++) { + lua_pushvalue(L, idxs[i]); // The arguments. + } + lua_call(L, n, 1); // Call the function, n args, one return value. + lua_replace(L, idxs[0]); // Replace the initial argument with the new object. + return 0; + */ + } + + int + ScriptManager::addConsoleLangText(LuaHandle * luaHandle) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + try { + //const char *ret; + //lua_lock(luaHandle); + //luaC_checkGC(luaHandle); + + int + args = lua_gettop(luaHandle); + if (lua_checkstack(luaHandle, args + 1)) { + LuaArguments + luaArguments(luaHandle); + string + fmt = luaArguments.getString(-args); + //va_list argList; + //va_start(argList, fmt.c_str() ); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "DisplayFormattedText args = %d!\n", + args); + + const int + max_args_allowed = 8; + if (args == 1) { + thisScriptManager->addConsoleLangText(Lang::getInstance(). + getScenarioString + (fmt).c_str()); + } else if (args == 2) { + thisScriptManager->addConsoleLangText(Lang::getInstance(). + getScenarioString + (fmt).c_str(), + luaArguments. + getGenericData(-args + + 1)); + } else if (args == 3) { + thisScriptManager->addConsoleLangText(Lang::getInstance(). + getScenarioString + (fmt).c_str(), + luaArguments. + getGenericData(-args + + 1), + luaArguments. + getGenericData(-args + + 2)); + } else if (args == 4) { + thisScriptManager->addConsoleLangText(Lang::getInstance(). + getScenarioString + (fmt).c_str(), + luaArguments. + getGenericData(-args + + 1), + luaArguments. + getGenericData(-args + + 2), + luaArguments. + getGenericData(-args + + 3)); + } else if (args == 5) { + thisScriptManager->addConsoleLangText(Lang::getInstance(). + getScenarioString + (fmt).c_str(), + luaArguments. + getGenericData(-args + + 1), + luaArguments. + getGenericData(-args + + 2), + luaArguments. + getGenericData(-args + + 3), + luaArguments. + getGenericData(-args + + 4)); + } else if (args == 6) { + thisScriptManager->addConsoleLangText(Lang::getInstance(). + getScenarioString + (fmt).c_str(), + luaArguments. + getGenericData(-args + + 1), + luaArguments. + getGenericData(-args + + 2), + luaArguments. + getGenericData(-args + + 3), + luaArguments. + getGenericData(-args + + 4), + luaArguments. + getGenericData(-args + + 5)); + } else if (args == 7) { + thisScriptManager->addConsoleLangText(Lang::getInstance(). + getScenarioString + (fmt).c_str(), + luaArguments. + getGenericData(-args + + 1), + luaArguments. + getGenericData(-args + + 2), + luaArguments. + getGenericData(-args + + 3), + luaArguments. + getGenericData(-args + + 4), + luaArguments. + getGenericData(-args + + 5), + luaArguments. + getGenericData(-args + + 6)); + } else if (args == max_args_allowed) { + thisScriptManager->addConsoleLangText(Lang::getInstance(). + getScenarioString + (fmt).c_str(), + luaArguments. + getGenericData(-args + + 1), + luaArguments. + getGenericData(-args + + 2), + luaArguments. + getGenericData(-args + + 3), + luaArguments. + getGenericData(-args + + 4), + luaArguments. + getGenericData(-args + + 5), + luaArguments. + getGenericData(-args + + 6), + luaArguments. + getGenericData(-args + + 7)); + } else { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Invalid parameter count in method [%s] args = %d [argument count must be between 1 and %d]", + __FUNCTION__, args, max_args_allowed); + throw + megaglest_runtime_error(szBuf); + } + + //va_end(argList); + } + //lua_unlock(luaHandle); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return 1; + } + + int + ScriptManager::DisplayFormattedLangText(LuaHandle * luaHandle) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + try { + //const char *ret; + //lua_lock(luaHandle); + //luaC_checkGC(luaHandle); + + int + args = lua_gettop(luaHandle); + if (lua_checkstack(luaHandle, args + 1)) { + LuaArguments + luaArguments(luaHandle); + string + fmt = luaArguments.getString(-args); + //va_list argList; + //va_start(argList, fmt.c_str() ); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "DisplayFormattedText args = %d!\n", + args); + + const int + max_args_allowed = 8; + if (args == 1) { + thisScriptManager-> + DisplayFormattedLangText(Lang::getInstance(). + getScenarioString(fmt).c_str()); + } else if (args == 2) { + thisScriptManager-> + DisplayFormattedLangText(Lang::getInstance(). + getScenarioString(fmt).c_str(), + luaArguments. + getGenericData(-args + 1)); + } else if (args == 3) { + thisScriptManager-> + DisplayFormattedLangText(Lang::getInstance(). + getScenarioString(fmt).c_str(), + luaArguments. + getGenericData(-args + 1), + luaArguments. + getGenericData(-args + 2)); + } else if (args == 4) { + thisScriptManager-> + DisplayFormattedLangText(Lang::getInstance(). + getScenarioString(fmt).c_str(), + luaArguments. + getGenericData(-args + 1), + luaArguments. + getGenericData(-args + 2), + luaArguments. + getGenericData(-args + 3)); + } else if (args == 5) { + thisScriptManager-> + DisplayFormattedLangText(Lang::getInstance(). + getScenarioString(fmt).c_str(), + luaArguments. + getGenericData(-args + 1), + luaArguments. + getGenericData(-args + 2), + luaArguments. + getGenericData(-args + 3), + luaArguments. + getGenericData(-args + 4)); + } else if (args == 6) { + thisScriptManager-> + DisplayFormattedLangText(Lang::getInstance(). + getScenarioString(fmt).c_str(), + luaArguments. + getGenericData(-args + 1), + luaArguments. + getGenericData(-args + 2), + luaArguments. + getGenericData(-args + 3), + luaArguments. + getGenericData(-args + 4), + luaArguments. + getGenericData(-args + 5)); + } else if (args == 7) { + thisScriptManager-> + DisplayFormattedLangText(Lang::getInstance(). + getScenarioString(fmt).c_str(), + luaArguments. + getGenericData(-args + 1), + luaArguments. + getGenericData(-args + 2), + luaArguments. + getGenericData(-args + 3), + luaArguments. + getGenericData(-args + 4), + luaArguments. + getGenericData(-args + 5), + luaArguments. + getGenericData(-args + 6)); + } else if (args == max_args_allowed) { + thisScriptManager-> + DisplayFormattedLangText(Lang::getInstance(). + getScenarioString(fmt).c_str(), + luaArguments. + getGenericData(-args + 1), + luaArguments. + getGenericData(-args + 2), + luaArguments. + getGenericData(-args + 3), + luaArguments. + getGenericData(-args + 4), + luaArguments. + getGenericData(-args + 5), + luaArguments. + getGenericData(-args + 6), + luaArguments. + getGenericData(-args + 7)); + } else { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Invalid parameter count in method [%s] args = %d [argument count must be between 1 and %d]", + __FUNCTION__, args, max_args_allowed); + throw + megaglest_runtime_error(szBuf); + } + + //va_end(argList); + } + //lua_unlock(luaHandle); + + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return 1; + } + + int + ScriptManager::getGameWon(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager->getGameWon()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getIsGameOver(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager->getIsGameOver()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::loadScenario(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->loadScenario(luaArguments.getString(-2), + luaArguments.getInt(-1) != 0); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getUnitsForFaction(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + vector < int > + units = + thisScriptManager->getUnitsForFaction(luaArguments.getInt(-3), + luaArguments.getString(-2), + luaArguments.getInt(-1)); + luaArguments.returnVectorInt(units); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + + } + + int + ScriptManager::getUnitCurrentField(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getUnitCurrentField(luaArguments. + getInt(-1))); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getIsUnitAlive(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getIsUnitAlive(luaArguments.getInt(-1))); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::isFreeCellsOrHasUnit(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + try { + int + result = + thisScriptManager->isFreeCellsOrHasUnit(luaArguments.getInt(-3), + luaArguments.getInt(-2), + luaArguments. + getVec2i(-1)); + + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::isFreeCells(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + + try { + int + result = thisScriptManager->isFreeCells(luaArguments.getInt(-3), + luaArguments.getInt(-2), + luaArguments. + getVec2i(-1)); + + luaArguments.returnInt(result); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getHumanFactionId(LuaHandle * luaHandle) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager->getHumanFactionId()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::highlightUnit(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->highlightUnit(luaArguments.getInt(-4), + luaArguments.getFloat(-3), + luaArguments.getFloat(-2), + luaArguments.getVec4f(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::unhighlightUnit(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->unhighlightUnit(luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::giveStopCommand(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->giveStopCommand(luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::selectUnit(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + selectUnit(luaArguments.getInt(-1))); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::unselectUnit(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->unselectUnit(luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::addUnitToGroupSelection(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->addUnitToGroupSelection(luaArguments.getInt(-2), + luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::recallGroupSelection(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->recallGroupSelection(luaArguments.getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::removeUnitFromGroupSelection(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->removeUnitFromGroupSelection(luaArguments. + getInt(-2), + luaArguments. + getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::setAttackWarningsEnabled(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager-> + setAttackWarningsEnabled((luaArguments.getInt(-1) == + 0 ? false : true)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + int + ScriptManager::getAttackWarningsEnabled(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getAttackWarningsEnabled()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getIsDayTime(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager->getIsDayTime()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + int + ScriptManager::getIsNightTime(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager->getIsNightTime()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + int + ScriptManager::getTimeOfDay(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnFloat(thisScriptManager->getTimeOfDay()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::registerDayNightEvent(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->registerDayNightEvent(); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + int + ScriptManager::unregisterDayNightEvent(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->unregisterDayNightEvent(); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::registerUnitTriggerEvent(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->registerUnitTriggerEvent(luaArguments. + getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + int + ScriptManager::unregisterUnitTriggerEvent(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->unregisterUnitTriggerEvent(luaArguments. + getInt(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + int + ScriptManager::getLastUnitTriggerEventUnitId(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getLastUnitTriggerEventUnitId()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + int + ScriptManager::getLastUnitTriggerEventType(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(static_cast < + int>(thisScriptManager-> + getLastUnitTriggerEventType())); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getUnitProperty(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + int + value = + thisScriptManager->getUnitProperty(luaArguments.getInt(-2), + static_cast < + UnitTriggerEventType> + (luaArguments.getInt(-1))); + luaArguments.returnInt(value); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + int + ScriptManager::getUnitPropertyName(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + const string + unitname = + thisScriptManager->getUnitPropertyName(luaArguments.getInt(-2), + static_cast < + UnitTriggerEventType> + (luaArguments.getInt(-1))); + luaArguments.returnString(unitname); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::disableSpeedChange(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->disableSpeedChange(); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + int + ScriptManager::enableSpeedChange(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->enableSpeedChange(); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + int + ScriptManager::getSpeedChangeEnabled(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager->getSpeedChangeEnabled()); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::storeSaveGameData(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + thisScriptManager->storeSaveGameData(luaArguments.getString(-2), + luaArguments.getString(-1)); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::loadSaveGameData(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnString(thisScriptManager-> + loadSaveGameData(luaArguments. + getString(-1))); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + } + + int + ScriptManager::getFactionPlayerType(LuaHandle * luaHandle) { + LuaArguments + luaArguments(luaHandle); + try { + luaArguments.returnInt(thisScriptManager-> + getFactionPlayerType(luaArguments. + getInt(-1))); + } catch (const megaglest_runtime_error & ex) { + error(luaHandle, &ex, __FILE__, __FUNCTION__, __LINE__); + } + + return luaArguments.getReturnCount(); + + } + + void + ScriptManager::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode * + scriptManagerNode = rootNode->addChild("ScriptManager"); + + //lua + // string code; + scriptManagerNode->addAttribute("code", code, mapTagReplacements); + // LuaScript luaScript; + + luaScript.beginCall("onSave"); + luaScript.endCall(); + + if (LuaScript::getDebugModeEnabled() == true) + printf("After onSave luaSavedGameData.size() = %d\n", + (int) luaSavedGameData.size()); + for (std::map < string, string >::iterator iterMap = + luaSavedGameData.begin(); iterMap != luaSavedGameData.end(); + ++iterMap) { + + XmlNode * + savedGameDataItemNode = + scriptManagerNode->addChild("SavedGameDataItem"); + + savedGameDataItemNode->addAttribute("key", iterMap->first, + mapTagReplacements); + savedGameDataItemNode->addAttribute("value", iterMap->second, + mapTagReplacements); + } + + // //world + // World *world; + // GameCamera *gameCamera; + // + // //misc + // MessageQueue messageQueue; + for (std::list < ScriptManagerMessage >::iterator it = + messageQueue.begin(); it != messageQueue.end(); ++it) { + (*it).saveGame(scriptManagerNode); + } + + //printf("==== ScriptManager Savegame messageBox [%d][%s][%s] displayText [%s]\n",messageBox.getEnabled(),messageBox.getText().c_str(),messageBox.getHeader().c_str(),displayText.c_str()); + + // GraphicMessageBox messageBox; + scriptManagerNode->addAttribute("messageBox_enabled", + intToStr(messageBox.getEnabled()), + mapTagReplacements); + scriptManagerNode->addAttribute("messageBox_text", + messageBox.getText(), + mapTagReplacements); + scriptManagerNode->addAttribute("messageBox_header", + messageBox.getHeader(), + mapTagReplacements); + + // string displayText; + scriptManagerNode->addAttribute("displayText", displayText, + mapTagReplacements); + // + // //last created unit + // string lastCreatedUnitName; + scriptManagerNode->addAttribute("lastCreatedUnitName", + lastCreatedUnitName, + mapTagReplacements); + // int lastCreatedUnitId; + scriptManagerNode->addAttribute("lastCreatedUnitId", + intToStr(lastCreatedUnitId), + mapTagReplacements); + // + // //last dead unit + // string lastDeadUnitName; + scriptManagerNode->addAttribute("lastDeadUnitName", lastDeadUnitName, + mapTagReplacements); + // int lastDeadUnitId; + scriptManagerNode->addAttribute("lastDeadUnitId", + intToStr(lastDeadUnitId), + mapTagReplacements); + // int lastDeadUnitCauseOfDeath; + scriptManagerNode->addAttribute("lastDeadUnitCauseOfDeath", + intToStr(lastDeadUnitCauseOfDeath), + mapTagReplacements); + // + // //last dead unit's killer + // string lastDeadUnitKillerName; + scriptManagerNode->addAttribute("lastDeadUnitKillerName", + lastDeadUnitKillerName, + mapTagReplacements); + // int lastDeadUnitKillerId; + scriptManagerNode->addAttribute("lastDeadUnitKillerId", + intToStr(lastDeadUnitKillerId), + mapTagReplacements); + // + // //last attacked unit + // string lastAttackedUnitName; + scriptManagerNode->addAttribute("lastAttackedUnitName", + lastAttackedUnitName, + mapTagReplacements); + // int lastAttackedUnitId; + scriptManagerNode->addAttribute("lastAttackedUnitId", + intToStr(lastAttackedUnitId), + mapTagReplacements); + // + // //last attacking unit + // string lastAttackingUnitName; + scriptManagerNode->addAttribute("lastAttackingUnitName", + lastAttackingUnitName, + mapTagReplacements); + // int lastAttackingUnitId; + scriptManagerNode->addAttribute("lastAttackingUnitId", + intToStr(lastAttackingUnitId), + mapTagReplacements); + // + // // end game state + // bool gameOver; + scriptManagerNode->addAttribute("gameOver", intToStr(gameOver), + mapTagReplacements); + // bool gameWon; + scriptManagerNode->addAttribute("gameWon", intToStr(gameWon), + mapTagReplacements); + // PlayerModifiers playerModifiers[GameConstants::maxPlayers]; + for (unsigned int i = 0; i < (unsigned int) GameConstants::maxPlayers; + ++i) { + PlayerModifiers & player = playerModifiers[i]; + player.saveGame(scriptManagerNode); + } + // int currentTimerTriggeredEventId; + scriptManagerNode->addAttribute("currentTimerTriggeredEventId", + intToStr + (currentTimerTriggeredEventId), + mapTagReplacements); + // int currentCellTriggeredEventId; + scriptManagerNode->addAttribute("currentCellTriggeredEventId", + intToStr(currentCellTriggeredEventId), + mapTagReplacements); + // int currentEventId; + scriptManagerNode->addAttribute("currentEventId", + intToStr(currentEventId), + mapTagReplacements); + // std::map CellTriggerEventList; + for (std::map < int, CellTriggerEvent >::iterator iterMap = + CellTriggerEventList.begin(); + iterMap != CellTriggerEventList.end(); ++iterMap) { + XmlNode * + cellTriggerEventListNode = + scriptManagerNode->addChild("CellTriggerEventList"); + + cellTriggerEventListNode->addAttribute("key", + intToStr(iterMap->first), + mapTagReplacements); + iterMap->second.saveGame(cellTriggerEventListNode); + } + // std::map TimerTriggerEventList; + for (std::map < int, TimerTriggerEvent >::iterator iterMap = + TimerTriggerEventList.begin(); + iterMap != TimerTriggerEventList.end(); ++iterMap) { + XmlNode * + timerTriggerEventListNode = + scriptManagerNode->addChild("TimerTriggerEventList"); + + timerTriggerEventListNode->addAttribute("key", + intToStr(iterMap->first), + mapTagReplacements); + iterMap->second.saveGame(timerTriggerEventListNode); + } + + // bool inCellTriggerEvent; + scriptManagerNode->addAttribute("inCellTriggerEvent", + intToStr(inCellTriggerEvent), + mapTagReplacements); + // std::vector unRegisterCellTriggerEventList; + for (unsigned int i = 0; i < unRegisterCellTriggerEventList.size(); + ++i) { + XmlNode * + unRegisterCellTriggerEventListNode = + scriptManagerNode->addChild("unRegisterCellTriggerEventList"); + unRegisterCellTriggerEventListNode->addAttribute("eventId", + intToStr + (unRegisterCellTriggerEventList + [i]), + mapTagReplacements); + } + + scriptManagerNode->addAttribute("registeredDayNightEvent", + intToStr(registeredDayNightEvent), + mapTagReplacements); + scriptManagerNode->addAttribute("lastDayNightTriggerStatus", + intToStr(lastDayNightTriggerStatus), + mapTagReplacements); + + for (std::map < int, UnitTriggerEventType >::iterator iterMap = + UnitTriggerEventList.begin(); + iterMap != UnitTriggerEventList.end(); ++iterMap) { + XmlNode * + unitTriggerEventListNode = + scriptManagerNode->addChild("UnitTriggerEventList"); + + unitTriggerEventListNode->addAttribute("unitId", + intToStr(iterMap->first), + mapTagReplacements); + unitTriggerEventListNode->addAttribute("eventType", + intToStr(iterMap->second), + mapTagReplacements); + } + scriptManagerNode->addAttribute("lastUnitTriggerEventUnitId", + intToStr(lastUnitTriggerEventUnitId), + mapTagReplacements); + scriptManagerNode->addAttribute("lastUnitTriggerEventType", + intToStr(lastUnitTriggerEventType), + mapTagReplacements); + + luaScript.saveGame(scriptManagerNode); + } + + void + ScriptManager::loadGame(const XmlNode * rootNode) { + const XmlNode * + scriptManagerNode = rootNode->getChild("ScriptManager"); + + // string code; + code = scriptManagerNode->getAttribute("code")->getValue(); + // LuaScript luaScript; + + vector < XmlNode * >savedGameDataItemNodeList = + scriptManagerNode->getChildList("SavedGameDataItem"); + + if (LuaScript::getDebugModeEnabled() == true) + printf("In loadGame savedGameDataItemNodeList.size() = %d\n", + (int) savedGameDataItemNodeList.size()); + + for (unsigned int i = 0; i < savedGameDataItemNodeList.size(); ++i) { + XmlNode * + node = savedGameDataItemNodeList[i]; + string + key = node->getAttribute("key")->getValue(); + string + value = node->getAttribute("value")->getValue(); + + luaSavedGameData[key] = value; + } + + // //world + // World *world; + // GameCamera *gameCamera; + // + // //misc + // MessageQueue messageQueue; + messageQueue.clear(); + vector < XmlNode * >messageQueueNodeList = + scriptManagerNode->getChildList("ScriptManagerMessage"); + for (unsigned int i = 0; i < messageQueueNodeList.size(); ++i) { + XmlNode * + node = messageQueueNodeList[i]; + ScriptManagerMessage + msg; + msg.loadGame(node); + messageQueue.push_back(msg); + } + + // GraphicMessageBox messageBox; + messageBox.setEnabled(scriptManagerNode-> + getAttribute("messageBox_enabled")-> + getIntValue() != 0); + messageBox.setText(scriptManagerNode-> + getAttribute("messageBox_text")->getValue()); + messageBox.setHeader(scriptManagerNode-> + getAttribute("messageBox_header")->getValue()); + + // string displayText; + displayText = + scriptManagerNode->getAttribute("displayText")->getValue(); + // + // //last created unit + // string lastCreatedUnitName; + lastCreatedUnitName = + scriptManagerNode->getAttribute("lastCreatedUnitName")->getValue(); + // int lastCreatedUnitId; + lastCreatedUnitId = + scriptManagerNode->getAttribute("lastCreatedUnitId")->getIntValue(); + // + // //last dead unit + // string lastDeadUnitName; + lastDeadUnitName = + scriptManagerNode->getAttribute("lastDeadUnitName")->getValue(); + // int lastDeadUnitId; + lastDeadUnitId = + scriptManagerNode->getAttribute("lastDeadUnitId")->getIntValue(); + // int lastDeadUnitCauseOfDeath; + lastDeadUnitCauseOfDeath = + scriptManagerNode->getAttribute("lastDeadUnitCauseOfDeath")-> + getIntValue(); + // + // //last dead unit's killer + // string lastDeadUnitKillerName; + lastDeadUnitKillerName = + scriptManagerNode->getAttribute("lastDeadUnitKillerName")-> + getValue(); + // int lastDeadUnitKillerId; + lastDeadUnitKillerId = + scriptManagerNode->getAttribute("lastDeadUnitKillerId")-> + getIntValue(); + // + // //last attacked unit + // string lastAttackedUnitName; + lastAttackedUnitName = + scriptManagerNode->getAttribute("lastAttackedUnitName")->getValue(); + // int lastAttackedUnitId; + lastAttackedUnitId = + scriptManagerNode->getAttribute("lastAttackedUnitId")-> + getIntValue(); + // + // //last attacking unit + // string lastAttackingUnitName; + lastAttackingUnitName = + scriptManagerNode->getAttribute("lastAttackingUnitName")-> + getValue(); + // int lastAttackingUnitId; + lastAttackingUnitId = + scriptManagerNode->getAttribute("lastAttackingUnitId")-> + getIntValue(); + // + // // end game state + // bool gameOver; + gameOver = + scriptManagerNode->getAttribute("gameOver")->getIntValue() != 0; + // bool gameWon; + gameWon = + scriptManagerNode->getAttribute("gameWon")->getIntValue() != 0; + // PlayerModifiers playerModifiers[GameConstants::maxPlayers]; + vector < XmlNode * >playerModifiersNodeList = + scriptManagerNode->getChildList("PlayerModifiers"); + for (unsigned int i = 0; i < playerModifiersNodeList.size(); ++i) { + XmlNode * + node = playerModifiersNodeList[i]; + playerModifiers[i].loadGame(node); + } + // int currentTimerTriggeredEventId; + currentTimerTriggeredEventId = + scriptManagerNode->getAttribute("currentTimerTriggeredEventId")-> + getIntValue(); + // int currentCellTriggeredEventId; + currentCellTriggeredEventId = + scriptManagerNode->getAttribute("currentCellTriggeredEventId")-> + getIntValue(); + // int currentEventId; + currentEventId = + scriptManagerNode->getAttribute("currentEventId")->getIntValue(); + // std::map CellTriggerEventList; + vector < XmlNode * >cellTriggerEventListNodeList = + scriptManagerNode->getChildList("CellTriggerEventList"); + for (unsigned int i = 0; i < cellTriggerEventListNodeList.size(); ++i) { + XmlNode * + node = cellTriggerEventListNodeList[i]; + CellTriggerEvent + event; + event.loadGame(node); + CellTriggerEventList[node->getAttribute("key")->getIntValue()] = + event; + } + + // std::map TimerTriggerEventList; + vector < XmlNode * >timerTriggerEventListNodeList = + scriptManagerNode->getChildList("TimerTriggerEventList"); + for (unsigned int i = 0; i < timerTriggerEventListNodeList.size(); ++i) { + XmlNode * + node = timerTriggerEventListNodeList[i]; + + TimerTriggerEvent + event; + event.loadGame(node); + TimerTriggerEventList[node->getAttribute("key")->getIntValue()] = + event; + } + + // bool inCellTriggerEvent; + inCellTriggerEvent = + scriptManagerNode->getAttribute("inCellTriggerEvent")-> + getIntValue() != 0; + // std::vector unRegisterCellTriggerEventList; + vector < XmlNode * >unRegisterCellTriggerEventListNodeList = + scriptManagerNode->getChildList("unRegisterCellTriggerEventList"); + for (unsigned int i = 0; + i < unRegisterCellTriggerEventListNodeList.size(); ++i) { + XmlNode * + node = unRegisterCellTriggerEventListNodeList[i]; + unRegisterCellTriggerEventList.push_back(node-> + getAttribute("eventId")-> + getIntValue()); + } + + if (scriptManagerNode->hasAttribute("registeredDayNightEvent") == true) { + registeredDayNightEvent = + scriptManagerNode->getAttribute("registeredDayNightEvent")-> + getIntValue() != 0; + } + if (scriptManagerNode->hasAttribute("lastDayNightTriggerStatus") == + true) { + lastDayNightTriggerStatus = + scriptManagerNode->getAttribute("lastDayNightTriggerStatus")-> + getIntValue(); + } + + vector < XmlNode * >unitTriggerEventListNodeList = + scriptManagerNode->getChildList("UnitTriggerEventList"); + for (unsigned int i = 0; i < unitTriggerEventListNodeList.size(); ++i) { + XmlNode * + node = unitTriggerEventListNodeList[i]; + + UnitTriggerEventType + eventType = utet_None; + int + unitId = node->getAttribute("unitId")->getIntValue(); + if (node->hasAttribute("eventType") == true) { + eventType = + static_cast + (node->getAttribute("eventType")->getIntValue()); + } else if (node->hasAttribute("evenType") == true) { + eventType = + static_cast + (node->getAttribute("evenType")->getIntValue()); + } + UnitTriggerEventList[unitId] = eventType; + } + if (scriptManagerNode->hasAttribute("lastUnitTriggerEventUnitId") == + true) { + lastUnitTriggerEventUnitId = + scriptManagerNode->getAttribute("lastUnitTriggerEventUnitId")-> + getIntValue(); + } + if (scriptManagerNode->hasAttribute("lastUnitTriggerEventType") == + true) { + lastUnitTriggerEventType = + static_cast + (scriptManagerNode->getAttribute("lastUnitTriggerEventType")-> + getIntValue()); + } + + luaScript.loadGame(scriptManagerNode); + } + + + } } //end namespace diff --git a/source/glest_game/game/script_manager.h b/source/glest_game/game/script_manager.h index 5783d53fb..4929a78c7 100644 --- a/source/glest_game/game/script_manager.h +++ b/source/glest_game/game/script_manager.h @@ -29,1081 +29,1056 @@ # include "platform_util.h" using - std::string; +std::string; using - std::list; +std::list; using - Shared::Graphics::Vec2i; +Shared::Graphics::Vec2i; using - Shared::Lua::LuaScript; +Shared::Lua::LuaScript; using - Shared::Lua::LuaHandle; +Shared::Lua::LuaHandle; using - Shared::Xml::XmlNode; +Shared::Xml::XmlNode; using - Shared::Util::RandomGen; +Shared::Util::RandomGen; namespace - Glest -{ - namespace - Game - { - - class - World; - class - Unit; - class - GameCamera; - -// ===================================================== -// class ScriptManagerMessage -// ===================================================== - - class - ScriptManagerMessage - { - private: - string - text; - string - header; - int - factionIndex; - int - teamIndex; - bool - messageNotTranslated; - - public: - ScriptManagerMessage (); - ScriptManagerMessage (const string & text, const string & header, - int factionIndex = -1, int teamIndex = - -1, bool messageNotTranslated = false); - const - string & - getText () const - { - return - text; - } - const - string & - getHeader () const - { - return - header; - } - int - getFactionIndex () const - { - return - factionIndex; - } - int - getTeamIndex () const - { - return - teamIndex; - } - bool - getMessageNotTranslated () const - { - return - messageNotTranslated; - } - - void - saveGame (XmlNode * rootNode); - void - loadGame (const XmlNode * rootNode); - }; - - class - PlayerModifiers - { - public: - PlayerModifiers (); - - void - disableAi () - { - aiEnabled = false; - } - void - enableAi () - { - aiEnabled = true; - } - - void - setAsWinner () - { - winner = true; - } - - void - disableConsume () - { - consumeEnabled = false; - } - void - enableConsume () - { - consumeEnabled = true; - } - - bool - getWinner () const - { - return - winner; - } - - bool - getAiEnabled () const - { - return - aiEnabled; - } - bool - getConsumeEnabled () const - { - return - consumeEnabled; - } - - void - saveGame (XmlNode * rootNode); - void - loadGame (const XmlNode * rootNode); - - private: - - bool winner; - bool - aiEnabled; - bool - consumeEnabled; - }; - -// ===================================================== -// class ScriptManager -// ===================================================== - - enum UnitTriggerEventType - { - utet_None = 0, - utet_HPChanged = 1, - utet_EPChanged, - utet_LevelChanged, - utet_FieldChanged, - utet_SkillChanged - }; - - enum CellTriggerEventType - { - ctet_Unit, - ctet_UnitPos, - ctet_Faction, - ctet_FactionPos, - ctet_UnitAreaPos, - ctet_FactionAreaPos, - ctet_AreaPos - }; - - class - CellTriggerEvent - { - public: - CellTriggerEvent (); - CellTriggerEventType - type; - int - sourceId; - int - destId; - Vec2i - destPos; - Vec2i - destPosEnd; - - int - triggerCount; - - std::map < int, - string > - eventStateInfo; - - std::map < int, - std::map < - Vec2i, - bool > > - eventLookupCache; - - void - saveGame (XmlNode * rootNode); - void - loadGame (const XmlNode * rootNode); - }; - - class - TimerTriggerEvent - { - public: - TimerTriggerEvent (); - bool - running; - //time_t startTime; - //time_t endTime; - int - startFrame; - int - endFrame; - - int - triggerSecondsElapsed; - - void - saveGame (XmlNode * rootNode); - void - loadGame (const XmlNode * rootNode); - }; - - class - ScriptManager - { - private: - typedef - list < - ScriptManagerMessage > - MessageQueue; - - private: - - //lua - string - code; - LuaScript - luaScript; - - //world - World * - world; - GameCamera * - gameCamera; - - //misc - MessageQueue - messageQueue; - GraphicMessageBox - messageBox; - string - displayText; - int - errorCount; - - //last created unit - string - lastCreatedUnitName; - int - lastCreatedUnitId; - - //last dead unit - string - lastDeadUnitName; - int - lastDeadUnitId; - int - lastDeadUnitCauseOfDeath; - - //last dead unit's killer - string - lastDeadUnitKillerName; - int - lastDeadUnitKillerId; - - //last attacked unit - string - lastAttackedUnitName; - int - lastAttackedUnitId; - - //last attacking unit - string - lastAttackingUnitName; - int - lastAttackingUnitId; - - // end game state - bool - gameOver; - bool - gameWon; - PlayerModifiers - playerModifiers[GameConstants::maxPlayers]; - - int - currentTimerTriggeredEventId; - int - currentCellTriggeredEventId; - int - currentCellTriggeredEventUnitId; - - int - currentCellTriggeredEventAreaEntryUnitId; - int - currentCellTriggeredEventAreaExitUnitId; - - int - currentEventId; - std::map < int, - CellTriggerEvent > - CellTriggerEventList; - std::map < int, - TimerTriggerEvent > - TimerTriggerEventList; - bool - inCellTriggerEvent; - std::vector < int > - unRegisterCellTriggerEventList; - - bool - registeredDayNightEvent; - int - lastDayNightTriggerStatus; - - std::map < int, - UnitTriggerEventType > - UnitTriggerEventList; - int - lastUnitTriggerEventUnitId; - UnitTriggerEventType - lastUnitTriggerEventType; - - RandomGen - random; - const XmlNode * - rootNode; - - std::map < - string, - string > - luaSavedGameData; - - private: - static ScriptManager * - thisScriptManager; - - private: - static const int - messageWrapCount; - static const int - displayTextWrapCount; - - public: - - ScriptManager (); - ~ - ScriptManager (); - void - init (World * world, GameCamera * gameCamera, const XmlNode * rootNode); - - //message box functions - void - addMessageToQueue (ScriptManagerMessage msg); - bool - getMessageBoxEnabled () const - { - return ! - messageQueue. - empty (); - } - GraphicMessageBox * - getMessageBox () - { - return &messageBox; - } - string - getDisplayText () const - { - return - displayText; - } - const PlayerModifiers * - getPlayerModifiers (int factionIndex) const - { - return & - playerModifiers[factionIndex]; - } - - //events - void - onMessageBoxOk (bool popFront = true); - void - onResourceHarvested (); - void - onUnitCreated (const Unit * unit); - void - onUnitDied (const Unit * unit); - void - onUnitAttacked (const Unit * unit); - void - onUnitAttacking (const Unit * unit); - void - onGameOver (bool won); - - void - onCellTriggerEvent (Unit * movingUnit); - void - onTimerTriggerEvent (); - void - onDayNightTriggerEvent (); - void - onUnitTriggerEvent (const Unit * unit, UnitTriggerEventType event); - - bool - getGameWon () const; - bool - getIsGameOver () const; - - void - saveGame (XmlNode * rootNode); - void - loadGame (const XmlNode * rootNode); - - private: - string wrapString (const string & str, int wrapCount); - - //wrappers, commands - void - networkShowMessageForFaction (const string & text, - const string & header, int factionIndex); - void - networkShowMessageForTeam (const string & text, const string & header, - int teamIndex); - - void - networkSetCameraPositionForFaction (int factionIndex, - const Vec2i & pos); - void - networkSetCameraPositionForTeam (int teamIndex, const Vec2i & pos); - - void - showMessage (const string & text, const string & header); - void - clearDisplayText (); - void - setDisplayText (const string & text); - void - addConsoleText (const string & text); - void - addConsoleLangText (const char *fmt, ...); - void - DisplayFormattedText (const char *fmt, ...); - void - DisplayFormattedLangText (const char *fmt, ...); - void - setCameraPosition (const Vec2i & pos); - void - shakeCamera (int shakeIntensity, int shakeDuration, - bool cameraDistanceAffected, int unitId); - void - createUnit (const string & unitName, int factionIndex, Vec2i pos); - void - createUnitNoSpacing (const string & unitName, int factionIndex, - Vec2i pos); - - void - setLockedUnitForFaction (const string & unitName, int factionIndex, - bool lock); - void - destroyUnit (int unitId); - void - giveKills (int unitId, int amount); - void - morphToUnit (int unitId, const string & morphName, - int ignoreRequirements); - void - moveToUnit (int unitId, int destUnitId); - void - giveAttackStoppedCommand (int unitId, const string & valueName, - int ignoreRequirements); - void - playStaticSound (const string & playSound); - void - playStreamingSound (const string & playSound); - void - stopStreamingSound (const string & playSound); - void - stopAllSound (); - void - togglePauseGame (int pauseStatus); - - void - playStaticVideo (const string & playVideo); - void - playStreamingVideo (const string & playVideo); - void - stopStreamingVideo (const string & playVideo); - void - stopAllVideo (); - - void - giveResource (const string & resourceName, int factionIndex, - int amount); - void - givePositionCommand (int unitId, const string & producedName, - const Vec2i & pos); - void - giveProductionCommand (int unitId, const string & producedName); - void - giveAttackCommand (int unitId, int unitToAttackId); - void - giveUpgradeCommand (int unitId, const string & upgradeName); - void - giveStopCommand (int unitId); - - void - disableAi (int factionIndex); - void - enableAi (int factionIndex); - void - disableConsume (int factionIndex); - void - enableConsume (int factionIndex); - - int - registerCellTriggerEventForUnitToUnit (int sourceUnitId, - int destUnitId); - int - registerCellTriggerEventForUnitToLocation (int sourceUnitId, - const Vec2i & pos); - int - registerCellTriggerEventForFactionToUnit (int sourceFactionId, - int destUnitId); - int - registerCellTriggerEventForFactionToLocation (int sourceFactionId, - const Vec2i & pos); - - int - registerCellAreaTriggerEventForUnitToLocation (int sourceUnitId, - const Vec4i & pos); - int - registerCellAreaTriggerEventForFactionToLocation (int sourceFactionId, - const Vec4i & pos); - - int - registerCellAreaTriggerEvent (const Vec4i & pos); - - int - getCellTriggerEventCount (int eventId); - void - unregisterCellTriggerEvent (int eventId); - int - startTimerEvent (); - int - startEfficientTimerEvent (int triggerSecondsElapsed); - int - resetTimerEvent (int eventId); - int - stopTimerEvent (int eventId); - int - getTimerEventSecondsElapsed (int eventId); - - int - getCellTriggeredEventId (); - int - getTimerTriggeredEventId (); - - int - getCellTriggeredEventAreaEntryUnitId (); - int - getCellTriggeredEventAreaExitUnitId (); - - int - getCellTriggeredEventUnitId (); - - void - setRandomGenInit (int seed); - int - getRandomGen (int minVal, int maxVal); - int - getWorldFrameCount (); - - bool - getAiEnabled (int factionIndex); - bool - getConsumeEnabled (int factionIndex); - - void - setPlayerAsWinner (int factionIndex); - void - endGame (); - - void - startPerformanceTimer (); - void - endPerformanceTimer (); - Vec2i - getPerformanceTimerResults (); - - //wrappers, queries - int - getIsUnitAlive (int unitId); - Vec2i - getStartLocation (int factionIndex); - Vec2i - getUnitPosition (int unitId); - int - getUnitFaction (int unitId); - const string - getUnitName (int unitId); - const string - getUnitDisplayName (int unitId); - int - getResourceAmount (const string & resourceName, int factionIndex); - const - string & - getLastCreatedUnitName (); - int - getLastCreatedUnitId (); - - void - setUnitPosition (int unitId, Vec2i pos); - - void - addCellMarker (Vec2i pos, int factionIndex, const string & note, - const string & textureFile); - void - removeCellMarker (Vec2i pos, int factionIndex); - - void - showMarker (Vec2i pos, int factionIndex, const string & note, - const string & textureFile, int flashCount); - - const - string & - getLastDeadUnitName (); - int - getLastDeadUnitId (); - int - getLastDeadUnitCauseOfDeath (); - const - string & - getLastDeadUnitKillerName (); - int - getLastDeadUnitKillerId (); - - const - string & - getLastAttackedUnitName (); - int - getLastAttackedUnitId (); - - const - string & - getLastAttackingUnitName (); - int - getLastAttackingUnitId (); - - int - getUnitCount (int factionIndex); - int - getUnitCountOfType (int factionIndex, const string & typeName); - - const string - getSystemMacroValue (const string & key); - const string - getPlayerName (int factionIndex); - - vector < int > - getUnitsForFaction (int factionIndex, const string & commandTypeName, - int field); - int - getUnitCurrentField (int unitId); - - void - loadScenario (const string & name, bool keepFactions); - - int - isFreeCellsOrHasUnit (int field, int unitId, Vec2i pos); - int - isFreeCells (int unitSize, int field, Vec2i pos); - - int - getHumanFactionId (); - void - highlightUnit (int unitId, float radius, float thickness, Vec4f color); - void - unhighlightUnit (int unitId); - - bool - selectUnit (int unitId); - void - unselectUnit (int unitId); - void - addUnitToGroupSelection (int unitId, int groupIndex); - void - recallGroupSelection (int groupIndex); - void - removeUnitFromGroupSelection (int unitId, int group); - void - setAttackWarningsEnabled (bool enabled); - bool - getAttackWarningsEnabled (); - - int - getIsDayTime (); - int - getIsNightTime (); - float - getTimeOfDay (); - void - registerDayNightEvent (); - void - unregisterDayNightEvent (); - - void - registerUnitTriggerEvent (int unitId); - void - unregisterUnitTriggerEvent (int unitId); - int - getLastUnitTriggerEventUnitId (); - UnitTriggerEventType - getLastUnitTriggerEventType (); - int - getUnitProperty (int unitId, UnitTriggerEventType type); - const string - getUnitPropertyName (int unitId, UnitTriggerEventType type); - - void - disableSpeedChange (); - void - enableSpeedChange (); - bool - getSpeedChangeEnabled (); - void - storeSaveGameData (string name, string value); - string - loadSaveGameData (string name); - - ControlType - getFactionPlayerType (int factionIndex); - // ----------------------------------------------------------------------- - - static void - error (LuaHandle * luaHandle, const megaglest_runtime_error * mgErr, - const char *file, const char *function, int line); - - //callbacks, commands - static int - networkShowMessageForFaction (LuaHandle * luaHandle); - static int - networkShowMessageForTeam (LuaHandle * luaHandle); - - static int - networkSetCameraPositionForFaction (LuaHandle * luaHandle); - static int - networkSetCameraPositionForTeam (LuaHandle * luaHandle); - - static int - showMessage (LuaHandle * luaHandle); - static int - setDisplayText (LuaHandle * luaHandle); - static int - addConsoleText (LuaHandle * luaHandle); - static int - addConsoleLangText (LuaHandle * luaHandle); - static int - DisplayFormattedText (LuaHandle * luaHandle); - static int - DisplayFormattedLangText (LuaHandle * luaHandle); - static int - clearDisplayText (LuaHandle * luaHandle); - static int - setCameraPosition (LuaHandle * luaHandle); - static int - shakeCamera (LuaHandle * luaHandle); - static int - shakeCameraOnUnit (LuaHandle * luaHandle); - static int - createUnit (LuaHandle * luaHandle); - static int - createUnitNoSpacing (LuaHandle * luaHandle); - - static int - setLockedUnitForFaction (LuaHandle * luaHandle); - static int - destroyUnit (LuaHandle * luaHandle); - static int - giveKills (LuaHandle * luaHandle); - static int - morphToUnit (LuaHandle * luaHandle); - static int - moveToUnit (LuaHandle * luaHandle); - static int - giveAttackStoppedCommand (LuaHandle * luaHandle); - static int - playStaticSound (LuaHandle * luaHandle); - static int - playStreamingSound (LuaHandle * luaHandle); - static int - stopStreamingSound (LuaHandle * luaHandle); - static int - stopAllSound (LuaHandle * luaHandle); - static int - togglePauseGame (LuaHandle * luaHandle); - - static int - playStaticVideo (LuaHandle * luaHandle); - static int - playStreamingVideo (LuaHandle * luaHandle); - static int - stopStreamingVideo (LuaHandle * luaHandle); - static int - stopAllVideo (LuaHandle * luaHandle); - - static int - giveResource (LuaHandle * luaHandle); - static int - givePositionCommand (LuaHandle * luaHandle); - static int - giveProductionCommand (LuaHandle * luaHandle); - static int - giveAttackCommand (LuaHandle * luaHandle); - static int - giveUpgradeCommand (LuaHandle * luaHandle); - - static int - disableAi (LuaHandle * luaHandle); - static int - enableAi (LuaHandle * luaHandle); - - static int - disableConsume (LuaHandle * luaHandle); - static int - enableConsume (LuaHandle * luaHandle); - - static int - getAiEnabled (LuaHandle * luaHandle); - static int - getConsumeEnabled (LuaHandle * luaHandle); - - static int - registerCellTriggerEventForUnitToUnit (LuaHandle * luaHandle); - static int - registerCellTriggerEventForUnitToLocation (LuaHandle * luaHandle); - static int - registerCellTriggerEventForFactionToUnit (LuaHandle * luaHandle); - static int - registerCellTriggerEventForFactionToLocation (LuaHandle * luaHandle); - - static int - registerCellAreaTriggerEventForUnitToLocation (LuaHandle * luaHandle); - static int - registerCellAreaTriggerEventForFactionToLocation (LuaHandle * - luaHandle); - - static int - registerCellAreaTriggerEvent (LuaHandle * luaHandle); - - static int - getCellTriggerEventCount (LuaHandle * luaHandle); - static int - unregisterCellTriggerEvent (LuaHandle * luaHandle); - static int - startTimerEvent (LuaHandle * luaHandle); - static int - startEfficientTimerEvent (LuaHandle * luaHandle); - static int - resetTimerEvent (LuaHandle * luaHandle); - static int - stopTimerEvent (LuaHandle * luaHandle); - static int - getTimerEventSecondsElapsed (LuaHandle * luaHandle); - - static int - getCellTriggeredEventId (LuaHandle * luaHandle); - static int - getTimerTriggeredEventId (LuaHandle * luaHandle); - - static int - getCellTriggeredEventAreaEntryUnitId (LuaHandle * luaHandle); - static int - getCellTriggeredEventAreaExitUnitId (LuaHandle * luaHandle); - - static int - getCellTriggeredEventUnitId (LuaHandle * luaHandle); - - static int - setRandomGenInit (LuaHandle * luaHandle); - static int - getRandomGen (LuaHandle * luaHandle); - static int - getWorldFrameCount (LuaHandle * luaHandle); - - static int - setPlayerAsWinner (LuaHandle * luaHandle); - static int - endGame (LuaHandle * luaHandle); - - static int - startPerformanceTimer (LuaHandle * luaHandle); - static int - endPerformanceTimer (LuaHandle * luaHandle); - static int - getPerformanceTimerResults (LuaHandle * luaHandle); - - //callbacks, queries - static int - getIsUnitAlive (LuaHandle * luaHandle); - static int - getStartLocation (LuaHandle * luaHandle); - static int - getUnitPosition (LuaHandle * luaHandle); - static int - getUnitFaction (LuaHandle * luaHandle); - static int - getUnitName (LuaHandle * luaHandle); - static int - getUnitDisplayName (LuaHandle * luaHandle); - static int - getResourceAmount (LuaHandle * luaHandle); - static int - getLastCreatedUnitName (LuaHandle * luaHandle); - static int - getLastCreatedUnitId (LuaHandle * luaHandle); - - static int - setUnitPosition (LuaHandle * luaHandle); - - static int - addCellMarker (LuaHandle * luaHandle); - static int - removeCellMarker (LuaHandle * luaHandle); - - static int - showMarker (LuaHandle * luaHandle); - - static int - getLastDeadUnitName (LuaHandle * luaHandle); - static int - getLastDeadUnitId (LuaHandle * luaHandle); - static int - getLastDeadUnitCauseOfDeath (LuaHandle * luaHandle); - static int - getLastDeadUnitKillerName (LuaHandle * luaHandle); - static int - getLastDeadUnitKillerId (LuaHandle * luaHandle); - - static int - getLastAttackedUnitName (LuaHandle * luaHandle); - static int - getLastAttackedUnitId (LuaHandle * luaHandle); - - static int - getLastAttackingUnitName (LuaHandle * luaHandle); - static int - getLastAttackingUnitId (LuaHandle * luaHandle); - - static int - getUnitCount (LuaHandle * luaHandle); - static int - getUnitCountOfType (LuaHandle * luaHandle); - - static int - getGameWon (LuaHandle * luaHandle); - static int - getIsGameOver (LuaHandle * luaHandle); - - static int - getSystemMacroValue (LuaHandle * luaHandle); - static int - getPlayerName (LuaHandle * luaHandle); - static int - scenarioDir (LuaHandle * luaHandle); - - static int - loadScenario (LuaHandle * luaHandle); - - static int - getUnitsForFaction (LuaHandle * luaHandle); - static int - getUnitCurrentField (LuaHandle * luaHandle); - - static int - isFreeCellsOrHasUnit (LuaHandle * luaHandle); - static int - isFreeCells (LuaHandle * luaHandle); - - static int - getHumanFactionId (LuaHandle * luaHandle); - - static int - highlightUnit (LuaHandle * luaHandle); - static int - unhighlightUnit (LuaHandle * luaHandle); - - static int - giveStopCommand (LuaHandle * luaHandle); - static int - selectUnit (LuaHandle * luaHandle); - static int - unselectUnit (LuaHandle * luaHandle); - static int - addUnitToGroupSelection (LuaHandle * luaHandle); - static int - recallGroupSelection (LuaHandle * luaHandle); - static int - removeUnitFromGroupSelection (LuaHandle * luaHandle); - static int - setAttackWarningsEnabled (LuaHandle * luaHandle); - static int - getAttackWarningsEnabled (LuaHandle * luaHandle); - - static int - getIsDayTime (LuaHandle * luaHandle); - static int - getIsNightTime (LuaHandle * luaHandle); - static int - getTimeOfDay (LuaHandle * luaHandle); - static int - registerDayNightEvent (LuaHandle * luaHandle); - static int - unregisterDayNightEvent (LuaHandle * luaHandle); - - static int - registerUnitTriggerEvent (LuaHandle * luaHandle); - static int - unregisterUnitTriggerEvent (LuaHandle * luaHandle); - static int - getLastUnitTriggerEventUnitId (LuaHandle * luaHandle); - static int - getLastUnitTriggerEventType (LuaHandle * luaHandle); - static int - getUnitProperty (LuaHandle * luaHandle); - static int - getUnitPropertyName (LuaHandle * luaHandle); - - static int - disableSpeedChange (LuaHandle * luaHandle); - static int - enableSpeedChange (LuaHandle * luaHandle); - static int - getSpeedChangeEnabled (LuaHandle * luaHandle); - - static int - storeSaveGameData (LuaHandle * luaHandle); - static int - loadSaveGameData (LuaHandle * luaHandle); - - static int - getFactionPlayerType (LuaHandle * luaHandle); - }; - -}} //end namespace + Glest { + namespace + Game { + + class + World; + class + Unit; + class + GameCamera; + + // ===================================================== + // class ScriptManagerMessage + // ===================================================== + + class + ScriptManagerMessage { + private: + string + text; + string + header; + int + factionIndex; + int + teamIndex; + bool + messageNotTranslated; + + public: + ScriptManagerMessage(); + ScriptManagerMessage(const string & text, const string & header, + int factionIndex = -1, int teamIndex = + -1, bool messageNotTranslated = false); + const + string & + getText() const { + return + text; + } + const + string & + getHeader() const { + return + header; + } + int + getFactionIndex() const { + return + factionIndex; + } + int + getTeamIndex() const { + return + teamIndex; + } + bool + getMessageNotTranslated() const { + return + messageNotTranslated; + } + + void + saveGame(XmlNode * rootNode); + void + loadGame(const XmlNode * rootNode); + }; + + class + PlayerModifiers { + public: + PlayerModifiers(); + + void + disableAi() { + aiEnabled = false; + } + void + enableAi() { + aiEnabled = true; + } + + void + setAsWinner() { + winner = true; + } + + void + disableConsume() { + consumeEnabled = false; + } + void + enableConsume() { + consumeEnabled = true; + } + + bool + getWinner() const { + return + winner; + } + + bool + getAiEnabled() const { + return + aiEnabled; + } + bool + getConsumeEnabled() const { + return + consumeEnabled; + } + + void + saveGame(XmlNode * rootNode); + void + loadGame(const XmlNode * rootNode); + + private: + + bool winner; + bool + aiEnabled; + bool + consumeEnabled; + }; + + // ===================================================== + // class ScriptManager + // ===================================================== + + enum UnitTriggerEventType { + utet_None = 0, + utet_HPChanged = 1, + utet_EPChanged, + utet_LevelChanged, + utet_FieldChanged, + utet_SkillChanged + }; + + enum CellTriggerEventType { + ctet_Unit, + ctet_UnitPos, + ctet_Faction, + ctet_FactionPos, + ctet_UnitAreaPos, + ctet_FactionAreaPos, + ctet_AreaPos + }; + + class + CellTriggerEvent { + public: + CellTriggerEvent(); + CellTriggerEventType + type; + int + sourceId; + int + destId; + Vec2i + destPos; + Vec2i + destPosEnd; + + int + triggerCount; + + std::map < int, + string > + eventStateInfo; + + std::map < int, + std::map < + Vec2i, + bool > > + eventLookupCache; + + void + saveGame(XmlNode * rootNode); + void + loadGame(const XmlNode * rootNode); + }; + + class + TimerTriggerEvent { + public: + TimerTriggerEvent(); + bool + running; + //time_t startTime; + //time_t endTime; + int + startFrame; + int + endFrame; + + int + triggerSecondsElapsed; + + void + saveGame(XmlNode * rootNode); + void + loadGame(const XmlNode * rootNode); + }; + + class + ScriptManager { + private: + typedef + list < + ScriptManagerMessage > + MessageQueue; + + private: + + //lua + string + code; + LuaScript + luaScript; + + //world + World * + world; + GameCamera * + gameCamera; + + //misc + MessageQueue + messageQueue; + GraphicMessageBox + messageBox; + string + displayText; + int + errorCount; + + //last created unit + string + lastCreatedUnitName; + int + lastCreatedUnitId; + + //last dead unit + string + lastDeadUnitName; + int + lastDeadUnitId; + int + lastDeadUnitCauseOfDeath; + + //last dead unit's killer + string + lastDeadUnitKillerName; + int + lastDeadUnitKillerId; + + //last attacked unit + string + lastAttackedUnitName; + int + lastAttackedUnitId; + + //last attacking unit + string + lastAttackingUnitName; + int + lastAttackingUnitId; + + // end game state + bool + gameOver; + bool + gameWon; + PlayerModifiers + playerModifiers[GameConstants::maxPlayers]; + + int + currentTimerTriggeredEventId; + int + currentCellTriggeredEventId; + int + currentCellTriggeredEventUnitId; + + int + currentCellTriggeredEventAreaEntryUnitId; + int + currentCellTriggeredEventAreaExitUnitId; + + int + currentEventId; + std::map < int, + CellTriggerEvent > + CellTriggerEventList; + std::map < int, + TimerTriggerEvent > + TimerTriggerEventList; + bool + inCellTriggerEvent; + std::vector < int > + unRegisterCellTriggerEventList; + + bool + registeredDayNightEvent; + int + lastDayNightTriggerStatus; + + std::map < int, + UnitTriggerEventType > + UnitTriggerEventList; + int + lastUnitTriggerEventUnitId; + UnitTriggerEventType + lastUnitTriggerEventType; + + RandomGen + random; + const XmlNode * + rootNode; + + std::map < + string, + string > + luaSavedGameData; + + private: + static ScriptManager * + thisScriptManager; + + private: + static const int + messageWrapCount; + static const int + displayTextWrapCount; + + public: + + ScriptManager(); + ~ + ScriptManager(); + void + init(World * world, GameCamera * gameCamera, const XmlNode * rootNode); + + //message box functions + void + addMessageToQueue(ScriptManagerMessage msg); + bool + getMessageBoxEnabled() const { + return ! + messageQueue. + empty(); + } + GraphicMessageBox * + getMessageBox() { + return &messageBox; + } + string + getDisplayText() const { + return + displayText; + } + const PlayerModifiers * + getPlayerModifiers(int factionIndex) const { + return & + playerModifiers[factionIndex]; + } + + //events + void + onMessageBoxOk(bool popFront = true); + void + onResourceHarvested(); + void + onUnitCreated(const Unit * unit); + void + onUnitDied(const Unit * unit); + void + onUnitAttacked(const Unit * unit); + void + onUnitAttacking(const Unit * unit); + void + onGameOver(bool won); + + void + onCellTriggerEvent(Unit * movingUnit); + void + onTimerTriggerEvent(); + void + onDayNightTriggerEvent(); + void + onUnitTriggerEvent(const Unit * unit, UnitTriggerEventType event); + + bool + getGameWon() const; + bool + getIsGameOver() const; + + void + saveGame(XmlNode * rootNode); + void + loadGame(const XmlNode * rootNode); + + private: + string wrapString(const string & str, int wrapCount); + + //wrappers, commands + void + networkShowMessageForFaction(const string & text, + const string & header, int factionIndex); + void + networkShowMessageForTeam(const string & text, const string & header, + int teamIndex); + + void + networkSetCameraPositionForFaction(int factionIndex, + const Vec2i & pos); + void + networkSetCameraPositionForTeam(int teamIndex, const Vec2i & pos); + + void + showMessage(const string & text, const string & header); + void + clearDisplayText(); + void + setDisplayText(const string & text); + void + addConsoleText(const string & text); + void + addConsoleLangText(const char *fmt, ...); + void + DisplayFormattedText(const char *fmt, ...); + void + DisplayFormattedLangText(const char *fmt, ...); + void + setCameraPosition(const Vec2i & pos); + void + shakeCamera(int shakeIntensity, int shakeDuration, + bool cameraDistanceAffected, int unitId); + void + createUnit(const string & unitName, int factionIndex, Vec2i pos); + void + createUnitNoSpacing(const string & unitName, int factionIndex, + Vec2i pos); + + void + setLockedUnitForFaction(const string & unitName, int factionIndex, + bool lock); + void + destroyUnit(int unitId); + void + giveKills(int unitId, int amount); + void + morphToUnit(int unitId, const string & morphName, + int ignoreRequirements); + void + moveToUnit(int unitId, int destUnitId); + void + giveAttackStoppedCommand(int unitId, const string & valueName, + int ignoreRequirements); + void + playStaticSound(const string & playSound); + void + playStreamingSound(const string & playSound); + void + stopStreamingSound(const string & playSound); + void + stopAllSound(); + void + togglePauseGame(int pauseStatus); + + void + playStaticVideo(const string & playVideo); + void + playStreamingVideo(const string & playVideo); + void + stopStreamingVideo(const string & playVideo); + void + stopAllVideo(); + + void + giveResource(const string & resourceName, int factionIndex, + int amount); + void + givePositionCommand(int unitId, const string & producedName, + const Vec2i & pos); + void + giveProductionCommand(int unitId, const string & producedName); + void + giveAttackCommand(int unitId, int unitToAttackId); + void + giveUpgradeCommand(int unitId, const string & upgradeName); + void + giveStopCommand(int unitId); + + void + disableAi(int factionIndex); + void + enableAi(int factionIndex); + void + disableConsume(int factionIndex); + void + enableConsume(int factionIndex); + + int + registerCellTriggerEventForUnitToUnit(int sourceUnitId, + int destUnitId); + int + registerCellTriggerEventForUnitToLocation(int sourceUnitId, + const Vec2i & pos); + int + registerCellTriggerEventForFactionToUnit(int sourceFactionId, + int destUnitId); + int + registerCellTriggerEventForFactionToLocation(int sourceFactionId, + const Vec2i & pos); + + int + registerCellAreaTriggerEventForUnitToLocation(int sourceUnitId, + const Vec4i & pos); + int + registerCellAreaTriggerEventForFactionToLocation(int sourceFactionId, + const Vec4i & pos); + + int + registerCellAreaTriggerEvent(const Vec4i & pos); + + int + getCellTriggerEventCount(int eventId); + void + unregisterCellTriggerEvent(int eventId); + int + startTimerEvent(); + int + startEfficientTimerEvent(int triggerSecondsElapsed); + int + resetTimerEvent(int eventId); + int + stopTimerEvent(int eventId); + int + getTimerEventSecondsElapsed(int eventId); + + int + getCellTriggeredEventId(); + int + getTimerTriggeredEventId(); + + int + getCellTriggeredEventAreaEntryUnitId(); + int + getCellTriggeredEventAreaExitUnitId(); + + int + getCellTriggeredEventUnitId(); + + void + setRandomGenInit(int seed); + int + getRandomGen(int minVal, int maxVal); + int + getWorldFrameCount(); + + bool + getAiEnabled(int factionIndex); + bool + getConsumeEnabled(int factionIndex); + + void + setPlayerAsWinner(int factionIndex); + void + endGame(); + + void + startPerformanceTimer(); + void + endPerformanceTimer(); + Vec2i + getPerformanceTimerResults(); + + //wrappers, queries + int + getIsUnitAlive(int unitId); + Vec2i + getStartLocation(int factionIndex); + Vec2i + getUnitPosition(int unitId); + int + getUnitFaction(int unitId); + const string + getUnitName(int unitId); + const string + getUnitDisplayName(int unitId); + int + getResourceAmount(const string & resourceName, int factionIndex); + const + string & + getLastCreatedUnitName(); + int + getLastCreatedUnitId(); + + void + setUnitPosition(int unitId, Vec2i pos); + + void + addCellMarker(Vec2i pos, int factionIndex, const string & note, + const string & textureFile); + void + removeCellMarker(Vec2i pos, int factionIndex); + + void + showMarker(Vec2i pos, int factionIndex, const string & note, + const string & textureFile, int flashCount); + + const + string & + getLastDeadUnitName(); + int + getLastDeadUnitId(); + int + getLastDeadUnitCauseOfDeath(); + const + string & + getLastDeadUnitKillerName(); + int + getLastDeadUnitKillerId(); + + const + string & + getLastAttackedUnitName(); + int + getLastAttackedUnitId(); + + const + string & + getLastAttackingUnitName(); + int + getLastAttackingUnitId(); + + int + getUnitCount(int factionIndex); + int + getUnitCountOfType(int factionIndex, const string & typeName); + + const string + getSystemMacroValue(const string & key); + const string + getPlayerName(int factionIndex); + + vector < int > + getUnitsForFaction(int factionIndex, const string & commandTypeName, + int field); + int + getUnitCurrentField(int unitId); + + void + loadScenario(const string & name, bool keepFactions); + + int + isFreeCellsOrHasUnit(int field, int unitId, Vec2i pos); + int + isFreeCells(int unitSize, int field, Vec2i pos); + + int + getHumanFactionId(); + void + highlightUnit(int unitId, float radius, float thickness, Vec4f color); + void + unhighlightUnit(int unitId); + + bool + selectUnit(int unitId); + void + unselectUnit(int unitId); + void + addUnitToGroupSelection(int unitId, int groupIndex); + void + recallGroupSelection(int groupIndex); + void + removeUnitFromGroupSelection(int unitId, int group); + void + setAttackWarningsEnabled(bool enabled); + bool + getAttackWarningsEnabled(); + + int + getIsDayTime(); + int + getIsNightTime(); + float + getTimeOfDay(); + void + registerDayNightEvent(); + void + unregisterDayNightEvent(); + + void + registerUnitTriggerEvent(int unitId); + void + unregisterUnitTriggerEvent(int unitId); + int + getLastUnitTriggerEventUnitId(); + UnitTriggerEventType + getLastUnitTriggerEventType(); + int + getUnitProperty(int unitId, UnitTriggerEventType type); + const string + getUnitPropertyName(int unitId, UnitTriggerEventType type); + + void + disableSpeedChange(); + void + enableSpeedChange(); + bool + getSpeedChangeEnabled(); + void + storeSaveGameData(string name, string value); + string + loadSaveGameData(string name); + + ControlType + getFactionPlayerType(int factionIndex); + // ----------------------------------------------------------------------- + + static void + error(LuaHandle * luaHandle, const megaglest_runtime_error * mgErr, + const char *file, const char *function, int line); + + //callbacks, commands + static int + networkShowMessageForFaction(LuaHandle * luaHandle); + static int + networkShowMessageForTeam(LuaHandle * luaHandle); + + static int + networkSetCameraPositionForFaction(LuaHandle * luaHandle); + static int + networkSetCameraPositionForTeam(LuaHandle * luaHandle); + + static int + showMessage(LuaHandle * luaHandle); + static int + setDisplayText(LuaHandle * luaHandle); + static int + addConsoleText(LuaHandle * luaHandle); + static int + addConsoleLangText(LuaHandle * luaHandle); + static int + DisplayFormattedText(LuaHandle * luaHandle); + static int + DisplayFormattedLangText(LuaHandle * luaHandle); + static int + clearDisplayText(LuaHandle * luaHandle); + static int + setCameraPosition(LuaHandle * luaHandle); + static int + shakeCamera(LuaHandle * luaHandle); + static int + shakeCameraOnUnit(LuaHandle * luaHandle); + static int + createUnit(LuaHandle * luaHandle); + static int + createUnitNoSpacing(LuaHandle * luaHandle); + + static int + setLockedUnitForFaction(LuaHandle * luaHandle); + static int + destroyUnit(LuaHandle * luaHandle); + static int + giveKills(LuaHandle * luaHandle); + static int + morphToUnit(LuaHandle * luaHandle); + static int + moveToUnit(LuaHandle * luaHandle); + static int + giveAttackStoppedCommand(LuaHandle * luaHandle); + static int + playStaticSound(LuaHandle * luaHandle); + static int + playStreamingSound(LuaHandle * luaHandle); + static int + stopStreamingSound(LuaHandle * luaHandle); + static int + stopAllSound(LuaHandle * luaHandle); + static int + togglePauseGame(LuaHandle * luaHandle); + + static int + playStaticVideo(LuaHandle * luaHandle); + static int + playStreamingVideo(LuaHandle * luaHandle); + static int + stopStreamingVideo(LuaHandle * luaHandle); + static int + stopAllVideo(LuaHandle * luaHandle); + + static int + giveResource(LuaHandle * luaHandle); + static int + givePositionCommand(LuaHandle * luaHandle); + static int + giveProductionCommand(LuaHandle * luaHandle); + static int + giveAttackCommand(LuaHandle * luaHandle); + static int + giveUpgradeCommand(LuaHandle * luaHandle); + + static int + disableAi(LuaHandle * luaHandle); + static int + enableAi(LuaHandle * luaHandle); + + static int + disableConsume(LuaHandle * luaHandle); + static int + enableConsume(LuaHandle * luaHandle); + + static int + getAiEnabled(LuaHandle * luaHandle); + static int + getConsumeEnabled(LuaHandle * luaHandle); + + static int + registerCellTriggerEventForUnitToUnit(LuaHandle * luaHandle); + static int + registerCellTriggerEventForUnitToLocation(LuaHandle * luaHandle); + static int + registerCellTriggerEventForFactionToUnit(LuaHandle * luaHandle); + static int + registerCellTriggerEventForFactionToLocation(LuaHandle * luaHandle); + + static int + registerCellAreaTriggerEventForUnitToLocation(LuaHandle * luaHandle); + static int + registerCellAreaTriggerEventForFactionToLocation(LuaHandle * + luaHandle); + + static int + registerCellAreaTriggerEvent(LuaHandle * luaHandle); + + static int + getCellTriggerEventCount(LuaHandle * luaHandle); + static int + unregisterCellTriggerEvent(LuaHandle * luaHandle); + static int + startTimerEvent(LuaHandle * luaHandle); + static int + startEfficientTimerEvent(LuaHandle * luaHandle); + static int + resetTimerEvent(LuaHandle * luaHandle); + static int + stopTimerEvent(LuaHandle * luaHandle); + static int + getTimerEventSecondsElapsed(LuaHandle * luaHandle); + + static int + getCellTriggeredEventId(LuaHandle * luaHandle); + static int + getTimerTriggeredEventId(LuaHandle * luaHandle); + + static int + getCellTriggeredEventAreaEntryUnitId(LuaHandle * luaHandle); + static int + getCellTriggeredEventAreaExitUnitId(LuaHandle * luaHandle); + + static int + getCellTriggeredEventUnitId(LuaHandle * luaHandle); + + static int + setRandomGenInit(LuaHandle * luaHandle); + static int + getRandomGen(LuaHandle * luaHandle); + static int + getWorldFrameCount(LuaHandle * luaHandle); + + static int + setPlayerAsWinner(LuaHandle * luaHandle); + static int + endGame(LuaHandle * luaHandle); + + static int + startPerformanceTimer(LuaHandle * luaHandle); + static int + endPerformanceTimer(LuaHandle * luaHandle); + static int + getPerformanceTimerResults(LuaHandle * luaHandle); + + //callbacks, queries + static int + getIsUnitAlive(LuaHandle * luaHandle); + static int + getStartLocation(LuaHandle * luaHandle); + static int + getUnitPosition(LuaHandle * luaHandle); + static int + getUnitFaction(LuaHandle * luaHandle); + static int + getUnitName(LuaHandle * luaHandle); + static int + getUnitDisplayName(LuaHandle * luaHandle); + static int + getResourceAmount(LuaHandle * luaHandle); + static int + getLastCreatedUnitName(LuaHandle * luaHandle); + static int + getLastCreatedUnitId(LuaHandle * luaHandle); + + static int + setUnitPosition(LuaHandle * luaHandle); + + static int + addCellMarker(LuaHandle * luaHandle); + static int + removeCellMarker(LuaHandle * luaHandle); + + static int + showMarker(LuaHandle * luaHandle); + + static int + getLastDeadUnitName(LuaHandle * luaHandle); + static int + getLastDeadUnitId(LuaHandle * luaHandle); + static int + getLastDeadUnitCauseOfDeath(LuaHandle * luaHandle); + static int + getLastDeadUnitKillerName(LuaHandle * luaHandle); + static int + getLastDeadUnitKillerId(LuaHandle * luaHandle); + + static int + getLastAttackedUnitName(LuaHandle * luaHandle); + static int + getLastAttackedUnitId(LuaHandle * luaHandle); + + static int + getLastAttackingUnitName(LuaHandle * luaHandle); + static int + getLastAttackingUnitId(LuaHandle * luaHandle); + + static int + getUnitCount(LuaHandle * luaHandle); + static int + getUnitCountOfType(LuaHandle * luaHandle); + + static int + getGameWon(LuaHandle * luaHandle); + static int + getIsGameOver(LuaHandle * luaHandle); + + static int + getSystemMacroValue(LuaHandle * luaHandle); + static int + getPlayerName(LuaHandle * luaHandle); + static int + scenarioDir(LuaHandle * luaHandle); + + static int + loadScenario(LuaHandle * luaHandle); + + static int + getUnitsForFaction(LuaHandle * luaHandle); + static int + getUnitCurrentField(LuaHandle * luaHandle); + + static int + isFreeCellsOrHasUnit(LuaHandle * luaHandle); + static int + isFreeCells(LuaHandle * luaHandle); + + static int + getHumanFactionId(LuaHandle * luaHandle); + + static int + highlightUnit(LuaHandle * luaHandle); + static int + unhighlightUnit(LuaHandle * luaHandle); + + static int + giveStopCommand(LuaHandle * luaHandle); + static int + selectUnit(LuaHandle * luaHandle); + static int + unselectUnit(LuaHandle * luaHandle); + static int + addUnitToGroupSelection(LuaHandle * luaHandle); + static int + recallGroupSelection(LuaHandle * luaHandle); + static int + removeUnitFromGroupSelection(LuaHandle * luaHandle); + static int + setAttackWarningsEnabled(LuaHandle * luaHandle); + static int + getAttackWarningsEnabled(LuaHandle * luaHandle); + + static int + getIsDayTime(LuaHandle * luaHandle); + static int + getIsNightTime(LuaHandle * luaHandle); + static int + getTimeOfDay(LuaHandle * luaHandle); + static int + registerDayNightEvent(LuaHandle * luaHandle); + static int + unregisterDayNightEvent(LuaHandle * luaHandle); + + static int + registerUnitTriggerEvent(LuaHandle * luaHandle); + static int + unregisterUnitTriggerEvent(LuaHandle * luaHandle); + static int + getLastUnitTriggerEventUnitId(LuaHandle * luaHandle); + static int + getLastUnitTriggerEventType(LuaHandle * luaHandle); + static int + getUnitProperty(LuaHandle * luaHandle); + static int + getUnitPropertyName(LuaHandle * luaHandle); + + static int + disableSpeedChange(LuaHandle * luaHandle); + static int + enableSpeedChange(LuaHandle * luaHandle); + static int + getSpeedChangeEnabled(LuaHandle * luaHandle); + + static int + storeSaveGameData(LuaHandle * luaHandle); + static int + loadSaveGameData(LuaHandle * luaHandle); + + static int + getFactionPlayerType(LuaHandle * luaHandle); + }; + + } +} //end namespace #endif diff --git a/source/glest_game/game/stats.cpp b/source/glest_game/game/stats.cpp index be28499b4..8094f5043 100644 --- a/source/glest_game/game/stats.cpp +++ b/source/glest_game/game/stats.cpp @@ -13,361 +13,335 @@ #include "lang.h" #include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - PlayerStats::PlayerStats () - { - control = ctClosed; - resourceMultiplier = 1.0f; - //factionTypeName = ""; - personalityType = fpt_Normal; - teamIndex = 0; - victory = false; - kills = 0; - enemykills = 0; - deaths = 0; - unitsProduced = 0; - resourcesHarvested = 0; - //playerName = ""; - playerLeftBeforeEnd = false; - timePlayerLeft = -1; - playerColor = Vec3f (0, 0, 0); - } + PlayerStats::PlayerStats() { + control = ctClosed; + resourceMultiplier = 1.0f; + //factionTypeName = ""; + personalityType = fpt_Normal; + teamIndex = 0; + victory = false; + kills = 0; + enemykills = 0; + deaths = 0; + unitsProduced = 0; + resourcesHarvested = 0; + //playerName = ""; + playerLeftBeforeEnd = false; + timePlayerLeft = -1; + playerColor = Vec3f(0, 0, 0); + } - string PlayerStats::getStats () const - { - string result = ""; + string PlayerStats::getStats() const { + string result = ""; - Lang & lang = Lang::getInstance (); - string controlString = ""; + Lang & lang = Lang::getInstance(); + string controlString = ""; - if (personalityType == fpt_Observer) - { - controlString = GameConstants::OBSERVER_SLOTNAME; - } - else - { - switch (control) - { - case ctCpuEasy: - controlString = lang.getString ("CpuEasy"); - break; - case ctCpu:controlString = lang.getString ("Cpu"); - break; - case ctCpuUltra:controlString = lang.getString ("CpuUltra"); - break; - case ctCpuZeta:controlString = lang.getString ("CpuZeta"); - break; - case ctNetwork:controlString = lang.getString ("Network"); - break; - case ctHuman:controlString = lang.getString ("Human"); - break; + if (personalityType == fpt_Observer) { + controlString = GameConstants::OBSERVER_SLOTNAME; + } else { + switch (control) { + case ctCpuEasy: + controlString = lang.getString("CpuEasy"); + break; + case ctCpu:controlString = lang.getString("Cpu"); + break; + case ctCpuUltra:controlString = lang.getString("CpuUltra"); + break; + case ctCpuZeta:controlString = lang.getString("CpuZeta"); + break; + case ctNetwork:controlString = lang.getString("Network"); + break; + case ctHuman:controlString = lang.getString("Human"); + break; - case ctNetworkCpuEasy:controlString = - lang.getString ("NetworkCpuEasy"); - break; - case ctNetworkCpu:controlString = lang.getString ("NetworkCpu"); - break; - case ctNetworkCpuUltra:controlString = - lang.getString ("NetworkCpuUltra"); - break; - case ctNetworkCpuZeta:controlString = - lang.getString ("NetworkCpuZeta"); - break; + case ctNetworkCpuEasy:controlString = + lang.getString("NetworkCpuEasy"); + break; + case ctNetworkCpu:controlString = lang.getString("NetworkCpu"); + break; + case ctNetworkCpuUltra:controlString = + lang.getString("NetworkCpuUltra"); + break; + case ctNetworkCpuZeta:controlString = + lang.getString("NetworkCpuZeta"); + break; - default:printf ("Error control = %d\n", control); - assert (false); - break; - }; - } + default:printf("Error control = %d\n", control); + assert(false); + break; + }; + } - if ((control != ctHuman && control != ctNetwork) || - (control == ctNetwork && playerLeftBeforeEnd == true)) - { - controlString += " x " + floatToStr (resourceMultiplier, 1); - } + if ((control != ctHuman && control != ctNetwork) || + (control == ctNetwork && playerLeftBeforeEnd == true)) { + controlString += " x " + floatToStr(resourceMultiplier, 1); + } - result += playerName + " (" + controlString + ") "; - if (control == ctNetwork && playerLeftBeforeEnd == true) - { - result += "player left before end "; - } - result += "faction: " + factionTypeName + " "; - result += "Team: " + intToStr (teamIndex) + " "; - result += "victory: " + boolToStr (victory) + " "; - result += "# kills: " + intToStr (kills) + " "; - result += "# enemy kills: " + intToStr (enemykills) + " "; - result += "# deaths: " + intToStr (deaths) + "\n"; - result += "# units produced: " + intToStr (unitsProduced) + " "; - result += "# resources harvested: " + intToStr (resourcesHarvested); + result += playerName + " (" + controlString + ") "; + if (control == ctNetwork && playerLeftBeforeEnd == true) { + result += "player left before end "; + } + result += "faction: " + factionTypeName + " "; + result += "Team: " + intToStr(teamIndex) + " "; + result += "victory: " + boolToStr(victory) + " "; + result += "# kills: " + intToStr(kills) + " "; + result += "# enemy kills: " + intToStr(enemykills) + " "; + result += "# deaths: " + intToStr(deaths) + "\n"; + result += "# units produced: " + intToStr(unitsProduced) + " "; + result += "# resources harvested: " + intToStr(resourcesHarvested); - return result; - } + return result; + } -// ===================================================== -// class Stats -// ===================================================== + // ===================================================== + // class Stats + // ===================================================== - void Stats::init (int factionCount, int thisFactionIndex, - const string & description, const string & techName) - { - this->thisFactionIndex = thisFactionIndex; - this->factionCount = factionCount; - this->description = description; - this->techName = techName; - } + void Stats::init(int factionCount, int thisFactionIndex, + const string & description, const string & techName) { + this->thisFactionIndex = thisFactionIndex; + this->factionCount = factionCount; + this->description = description; + this->techName = techName; + } - void Stats::setVictorious (int playerIndex) - { - playerStats[playerIndex].victory = true; - } + void Stats::setVictorious(int playerIndex) { + playerStats[playerIndex].victory = true; + } - void Stats::kill (int killerFactionIndex, int killedFactionIndex, - bool isEnemy, bool isDeathCounted, bool isKillCounted) - { - if (isKillCounted == true) - { - playerStats[killerFactionIndex].kills++; - } - if (isDeathCounted == true) - { - playerStats[killedFactionIndex].deaths++; - } - if (isEnemy == true && isKillCounted == true) - { - playerStats[killerFactionIndex].enemykills++; - } - } + void Stats::kill(int killerFactionIndex, int killedFactionIndex, + bool isEnemy, bool isDeathCounted, bool isKillCounted) { + if (isKillCounted == true) { + playerStats[killerFactionIndex].kills++; + } + if (isDeathCounted == true) { + playerStats[killedFactionIndex].deaths++; + } + if (isEnemy == true && isKillCounted == true) { + playerStats[killerFactionIndex].enemykills++; + } + } - void Stats::die (int diedFactionIndex, bool isDeathCounted) - { - if (isDeathCounted == true) - { - playerStats[diedFactionIndex].deaths++; - } - } + void Stats::die(int diedFactionIndex, bool isDeathCounted) { + if (isDeathCounted == true) { + playerStats[diedFactionIndex].deaths++; + } + } - void Stats::produce (int producerFactionIndex, bool isProductionCounted) - { - if (isProductionCounted == true) - { - playerStats[producerFactionIndex].unitsProduced++; - } - } + void Stats::produce(int producerFactionIndex, bool isProductionCounted) { + if (isProductionCounted == true) { + playerStats[producerFactionIndex].unitsProduced++; + } + } - void Stats::harvest (int harvesterFactionIndex, int amount) - { - playerStats[harvesterFactionIndex].resourcesHarvested += amount; - } + void Stats::harvest(int harvesterFactionIndex, int amount) { + playerStats[harvesterFactionIndex].resourcesHarvested += amount; + } - string Stats::getStats () const - { - string result = ""; + string Stats::getStats() const { + string result = ""; - result += "Description: " + description + "\n"; - result += "Faction count: " + intToStr (factionCount) + "\n"; + result += "Description: " + description + "\n"; + result += "Faction count: " + intToStr(factionCount) + "\n"; - result += - "Game duration (mins): " + - intToStr (getFramesToCalculatePlaytime () / GameConstants::updateFps / - 60) + "\n"; - result += - "Max Concurrent Units: " + intToStr (maxConcurrentUnitCount) + "\n"; - result += - "Total EndGame Concurrent Unit Count: " + - intToStr (totalEndGameConcurrentUnitCount) + "\n"; + result += + "Game duration (mins): " + + intToStr(getFramesToCalculatePlaytime() / GameConstants::updateFps / + 60) + "\n"; + result += + "Max Concurrent Units: " + intToStr(maxConcurrentUnitCount) + "\n"; + result += + "Total EndGame Concurrent Unit Count: " + + intToStr(totalEndGameConcurrentUnitCount) + "\n"; - for (unsigned int i = 0; i < (unsigned int) factionCount; ++i) - { - const PlayerStats & player = playerStats[i]; + for (unsigned int i = 0; i < (unsigned int) factionCount; ++i) { + const PlayerStats & player = playerStats[i]; - result += - "player #" + uIntToStr (i) + " " + player.getStats () + "\n"; - } + result += + "player #" + uIntToStr(i) + " " + player.getStats() + "\n"; + } - return result; - } + return result; + } - void Stats::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode *statsNode = rootNode->addChild ("Stats"); + void Stats::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode *statsNode = rootNode->addChild("Stats"); -// PlayerStats playerStats[GameConstants::maxPlayers]; - for (unsigned int i = 0; i < (unsigned int) GameConstants::maxPlayers; - ++i) - { - PlayerStats & stat = playerStats[i]; + // PlayerStats playerStats[GameConstants::maxPlayers]; + for (unsigned int i = 0; i < (unsigned int) GameConstants::maxPlayers; + ++i) { + PlayerStats & stat = playerStats[i]; - XmlNode *statsNodePlayer = statsNode->addChild ("Player"); + XmlNode *statsNodePlayer = statsNode->addChild("Player"); -// ControlType control; - statsNodePlayer->addAttribute ("control", intToStr (stat.control), - mapTagReplacements); -// float resourceMultiplier; - statsNodePlayer->addAttribute ("resourceMultiplier", - floatToStr (stat.resourceMultiplier, - 6), mapTagReplacements); -// string factionTypeName; - statsNodePlayer->addAttribute ("factionTypeName", - stat.factionTypeName, - mapTagReplacements); -// FactionPersonalityType personalityType; - statsNodePlayer->addAttribute ("personalityType", - intToStr (stat.personalityType), - mapTagReplacements); -// int teamIndex; - statsNodePlayer->addAttribute ("teamIndex", - intToStr (stat.teamIndex), - mapTagReplacements); -// bool victory; - statsNodePlayer->addAttribute ("victory", intToStr (stat.victory), - mapTagReplacements); -// int kills; - statsNodePlayer->addAttribute ("kills", intToStr (stat.kills), - mapTagReplacements); -// int enemykills; - statsNodePlayer->addAttribute ("enemykills", - intToStr (stat.enemykills), - mapTagReplacements); -// int deaths; - statsNodePlayer->addAttribute ("deaths", intToStr (stat.deaths), - mapTagReplacements); -// int unitsProduced; - statsNodePlayer->addAttribute ("unitsProduced", - intToStr (stat.unitsProduced), - mapTagReplacements); -// int resourcesHarvested; - statsNodePlayer->addAttribute ("resourcesHarvested", - intToStr (stat.resourcesHarvested), - mapTagReplacements); -// string playerName; - statsNodePlayer->addAttribute ("playerName", stat.playerName, - mapTagReplacements); -// Vec3f playerColor; - statsNodePlayer->addAttribute ("playerColor", - stat.playerColor.getString (), - mapTagReplacements); - } -// string description; - statsNode->addAttribute ("description", description, - mapTagReplacements); -// int factionCount; - statsNode->addAttribute ("factionCount", intToStr (factionCount), - mapTagReplacements); -// int thisFactionIndex; - statsNode->addAttribute ("thisFactionIndex", - intToStr (thisFactionIndex), - mapTagReplacements); -// -// float worldTimeElapsed; - statsNode->addAttribute ("worldTimeElapsed", - floatToStr (worldTimeElapsed, 6), - mapTagReplacements); -// int framesPlayed; - statsNode->addAttribute ("framesPlayed", intToStr (framesPlayed), - mapTagReplacements); -// int framesToCalculatePlaytime; - statsNode->addAttribute ("framesToCalculatePlaytime", - intToStr (framesToCalculatePlaytime), - mapTagReplacements); -// int maxConcurrentUnitCount; - statsNode->addAttribute ("maxConcurrentUnitCount", - intToStr (maxConcurrentUnitCount), - mapTagReplacements); -// int totalEndGameConcurrentUnitCount; - statsNode->addAttribute ("totalEndGameConcurrentUnitCount", - intToStr (totalEndGameConcurrentUnitCount), - mapTagReplacements); -// bool isMasterserverMode; - } + // ControlType control; + statsNodePlayer->addAttribute("control", intToStr(stat.control), + mapTagReplacements); + // float resourceMultiplier; + statsNodePlayer->addAttribute("resourceMultiplier", + floatToStr(stat.resourceMultiplier, + 6), mapTagReplacements); + // string factionTypeName; + statsNodePlayer->addAttribute("factionTypeName", + stat.factionTypeName, + mapTagReplacements); + // FactionPersonalityType personalityType; + statsNodePlayer->addAttribute("personalityType", + intToStr(stat.personalityType), + mapTagReplacements); + // int teamIndex; + statsNodePlayer->addAttribute("teamIndex", + intToStr(stat.teamIndex), + mapTagReplacements); + // bool victory; + statsNodePlayer->addAttribute("victory", intToStr(stat.victory), + mapTagReplacements); + // int kills; + statsNodePlayer->addAttribute("kills", intToStr(stat.kills), + mapTagReplacements); + // int enemykills; + statsNodePlayer->addAttribute("enemykills", + intToStr(stat.enemykills), + mapTagReplacements); + // int deaths; + statsNodePlayer->addAttribute("deaths", intToStr(stat.deaths), + mapTagReplacements); + // int unitsProduced; + statsNodePlayer->addAttribute("unitsProduced", + intToStr(stat.unitsProduced), + mapTagReplacements); + // int resourcesHarvested; + statsNodePlayer->addAttribute("resourcesHarvested", + intToStr(stat.resourcesHarvested), + mapTagReplacements); + // string playerName; + statsNodePlayer->addAttribute("playerName", stat.playerName, + mapTagReplacements); + // Vec3f playerColor; + statsNodePlayer->addAttribute("playerColor", + stat.playerColor.getString(), + mapTagReplacements); + } + // string description; + statsNode->addAttribute("description", description, + mapTagReplacements); + // int factionCount; + statsNode->addAttribute("factionCount", intToStr(factionCount), + mapTagReplacements); + // int thisFactionIndex; + statsNode->addAttribute("thisFactionIndex", + intToStr(thisFactionIndex), + mapTagReplacements); + // + // float worldTimeElapsed; + statsNode->addAttribute("worldTimeElapsed", + floatToStr(worldTimeElapsed, 6), + mapTagReplacements); + // int framesPlayed; + statsNode->addAttribute("framesPlayed", intToStr(framesPlayed), + mapTagReplacements); + // int framesToCalculatePlaytime; + statsNode->addAttribute("framesToCalculatePlaytime", + intToStr(framesToCalculatePlaytime), + mapTagReplacements); + // int maxConcurrentUnitCount; + statsNode->addAttribute("maxConcurrentUnitCount", + intToStr(maxConcurrentUnitCount), + mapTagReplacements); + // int totalEndGameConcurrentUnitCount; + statsNode->addAttribute("totalEndGameConcurrentUnitCount", + intToStr(totalEndGameConcurrentUnitCount), + mapTagReplacements); + // bool isMasterserverMode; + } - void Stats::loadGame (const XmlNode * rootNode) - { - const XmlNode *statsNode = rootNode->getChild ("Stats"); + void Stats::loadGame(const XmlNode * rootNode) { + const XmlNode *statsNode = rootNode->getChild("Stats"); - // PlayerStats playerStats[GameConstants::maxPlayers]; + // PlayerStats playerStats[GameConstants::maxPlayers]; - vector < XmlNode * >statsNodePlayerList = - statsNode->getChildList ("Player"); - for (unsigned int i = 0; i < statsNodePlayerList.size (); ++i) - { - XmlNode *statsNodePlayer = statsNodePlayerList[i]; - PlayerStats & stat = playerStats[i]; + vector < XmlNode * >statsNodePlayerList = + statsNode->getChildList("Player"); + for (unsigned int i = 0; i < statsNodePlayerList.size(); ++i) { + XmlNode *statsNodePlayer = statsNodePlayerList[i]; + PlayerStats & stat = playerStats[i]; - // ControlType control; - stat.control = - static_cast < ControlType > - (statsNodePlayer->getAttribute ("control")->getIntValue ()); - // float resourceMultiplier; - stat.resourceMultiplier = - statsNodePlayer->getAttribute ("resourceMultiplier")-> - getFloatValue (); - // string factionTypeName; - stat.factionTypeName = - statsNodePlayer->getAttribute ("factionTypeName")->getValue (); - // FactionPersonalityType personalityType; - stat.personalityType = - static_cast < FactionPersonalityType > - (statsNodePlayer->getAttribute ("personalityType")-> - getIntValue ()); - // int teamIndex; - stat.teamIndex = - statsNodePlayer->getAttribute ("teamIndex")->getIntValue (); - // bool victory; - stat.victory = - statsNodePlayer->getAttribute ("victory")->getIntValue () != 0; - // int kills; - stat.kills = - statsNodePlayer->getAttribute ("kills")->getIntValue (); - // int enemykills; - stat.enemykills = - statsNodePlayer->getAttribute ("enemykills")->getIntValue (); - // int deaths; - stat.deaths = - statsNodePlayer->getAttribute ("deaths")->getIntValue (); - // int unitsProduced; - stat.unitsProduced = - statsNodePlayer->getAttribute ("unitsProduced")->getIntValue (); - // int resourcesHarvested; - stat.resourcesHarvested = - statsNodePlayer->getAttribute ("resourcesHarvested")-> - getIntValue (); - // string playerName; - stat.playerName = - statsNodePlayer->getAttribute ("playerName")->getValue (); - // Vec3f playerColor; - stat.playerColor = - Vec3f::strToVec3 (statsNodePlayer->getAttribute ("playerColor")-> - getValue ()); - } - // string description; - //statsNode->addAttribute("description",description, mapTagReplacements); - description = statsNode->getAttribute ("description")->getValue (); - // int factionCount; - factionCount = statsNode->getAttribute ("factionCount")->getIntValue (); - // int thisFactionIndex; - thisFactionIndex = - statsNode->getAttribute ("thisFactionIndex")->getIntValue (); - // - // float worldTimeElapsed; - worldTimeElapsed = - statsNode->getAttribute ("worldTimeElapsed")->getFloatValue (); - // int framesPlayed; - framesPlayed = statsNode->getAttribute ("framesPlayed")->getIntValue (); - // int framesToCalculatePlaytime; - framesToCalculatePlaytime = - statsNode->getAttribute ("framesToCalculatePlaytime")->getIntValue (); - // int maxConcurrentUnitCount; - maxConcurrentUnitCount = - statsNode->getAttribute ("maxConcurrentUnitCount")->getIntValue (); - // int totalEndGameConcurrentUnitCount; - totalEndGameConcurrentUnitCount = - statsNode->getAttribute ("totalEndGameConcurrentUnitCount")-> - getIntValue (); - // bool isMasterserverMode; - } -}} //end namespace + // ControlType control; + stat.control = + static_cast + (statsNodePlayer->getAttribute("control")->getIntValue()); + // float resourceMultiplier; + stat.resourceMultiplier = + statsNodePlayer->getAttribute("resourceMultiplier")-> + getFloatValue(); + // string factionTypeName; + stat.factionTypeName = + statsNodePlayer->getAttribute("factionTypeName")->getValue(); + // FactionPersonalityType personalityType; + stat.personalityType = + static_cast + (statsNodePlayer->getAttribute("personalityType")-> + getIntValue()); + // int teamIndex; + stat.teamIndex = + statsNodePlayer->getAttribute("teamIndex")->getIntValue(); + // bool victory; + stat.victory = + statsNodePlayer->getAttribute("victory")->getIntValue() != 0; + // int kills; + stat.kills = + statsNodePlayer->getAttribute("kills")->getIntValue(); + // int enemykills; + stat.enemykills = + statsNodePlayer->getAttribute("enemykills")->getIntValue(); + // int deaths; + stat.deaths = + statsNodePlayer->getAttribute("deaths")->getIntValue(); + // int unitsProduced; + stat.unitsProduced = + statsNodePlayer->getAttribute("unitsProduced")->getIntValue(); + // int resourcesHarvested; + stat.resourcesHarvested = + statsNodePlayer->getAttribute("resourcesHarvested")-> + getIntValue(); + // string playerName; + stat.playerName = + statsNodePlayer->getAttribute("playerName")->getValue(); + // Vec3f playerColor; + stat.playerColor = + Vec3f::strToVec3(statsNodePlayer->getAttribute("playerColor")-> + getValue()); + } + // string description; + //statsNode->addAttribute("description",description, mapTagReplacements); + description = statsNode->getAttribute("description")->getValue(); + // int factionCount; + factionCount = statsNode->getAttribute("factionCount")->getIntValue(); + // int thisFactionIndex; + thisFactionIndex = + statsNode->getAttribute("thisFactionIndex")->getIntValue(); + // + // float worldTimeElapsed; + worldTimeElapsed = + statsNode->getAttribute("worldTimeElapsed")->getFloatValue(); + // int framesPlayed; + framesPlayed = statsNode->getAttribute("framesPlayed")->getIntValue(); + // int framesToCalculatePlaytime; + framesToCalculatePlaytime = + statsNode->getAttribute("framesToCalculatePlaytime")->getIntValue(); + // int maxConcurrentUnitCount; + maxConcurrentUnitCount = + statsNode->getAttribute("maxConcurrentUnitCount")->getIntValue(); + // int totalEndGameConcurrentUnitCount; + totalEndGameConcurrentUnitCount = + statsNode->getAttribute("totalEndGameConcurrentUnitCount")-> + getIntValue(); + // bool isMasterserverMode; + } + } +} //end namespace diff --git a/source/glest_game/game/stats.h b/source/glest_game/game/stats.h index 5da4a51c2..0f2b81153 100644 --- a/source/glest_game/game/stats.h +++ b/source/glest_game/game/stats.h @@ -25,395 +25,349 @@ # include "leak_dumper.h" using - std::string; +std::string; using namespace - Shared::Graphics; +Shared::Graphics; namespace - Glest -{ - namespace - Game - { + Glest { + namespace + Game { - class - PlayerStats - { - public: - PlayerStats (); + class + PlayerStats { + public: + PlayerStats(); - ControlType - control; - float - resourceMultiplier; - string - factionTypeName; - FactionPersonalityType - personalityType; - int - teamIndex; - bool - victory; - int - kills; - int - enemykills; - int - deaths; - int - unitsProduced; - int - resourcesHarvested; - string - playerName; - bool - playerLeftBeforeEnd; - int - timePlayerLeft; - Vec3f - playerColor; + ControlType + control; + float + resourceMultiplier; + string + factionTypeName; + FactionPersonalityType + personalityType; + int + teamIndex; + bool + victory; + int + kills; + int + enemykills; + int + deaths; + int + unitsProduced; + int + resourcesHarvested; + string + playerName; + bool + playerLeftBeforeEnd; + int + timePlayerLeft; + Vec3f + playerColor; - string - getStats () const; - }; + string + getStats() const; + }; -// ===================================================== -// class Stats -// -/// Player statistics that are shown after the game ends -// ===================================================== + // ===================================================== + // class Stats + // + /// Player statistics that are shown after the game ends + // ===================================================== - class - Stats - { - private: - PlayerStats - playerStats[GameConstants::maxPlayers]; + class + Stats { + private: + PlayerStats + playerStats[GameConstants::maxPlayers]; - string - description; - int - factionCount; - int - thisFactionIndex; + string + description; + int + factionCount; + int + thisFactionIndex; - float - worldTimeElapsed; - int - framesPlayed; - int - framesToCalculatePlaytime; - int - maxConcurrentUnitCount; - int - totalEndGameConcurrentUnitCount; - bool - isMasterserverMode; - string - techName; + float + worldTimeElapsed; + int + framesPlayed; + int + framesToCalculatePlaytime; + int + maxConcurrentUnitCount; + int + totalEndGameConcurrentUnitCount; + bool + isMasterserverMode; + string + techName; - public: + public: - Stats () - { - //description = ""; - factionCount = 0; - thisFactionIndex = 0; + Stats() { + //description = ""; + factionCount = 0; + thisFactionIndex = 0; - worldTimeElapsed = 0.0; - framesPlayed = 0; - framesToCalculatePlaytime = 0; - maxConcurrentUnitCount = 0; - totalEndGameConcurrentUnitCount = 0; - isMasterserverMode = false; - //techName = ""; - } + worldTimeElapsed = 0.0; + framesPlayed = 0; + framesToCalculatePlaytime = 0; + maxConcurrentUnitCount = 0; + totalEndGameConcurrentUnitCount = 0; + isMasterserverMode = false; + //techName = ""; + } - void - init (int factionCount, int thisFactionIndex, - const string & description, const string & techName); + void + init(int factionCount, int thisFactionIndex, + const string & description, const string & techName); - string - getDescription () const - { - return - description; - } - int - getThisFactionIndex () const - { - return - thisFactionIndex; - } - int - getFactionCount () const - { - return - factionCount; - } + string + getDescription() const { + return + description; + } + int + getThisFactionIndex() const { + return + thisFactionIndex; + } + int + getFactionCount() const { + return + factionCount; + } - float - getWorldTimeElapsed () const - { - return - worldTimeElapsed; - } - int - getFramesPlayed () const - { - return - framesPlayed; - } - int - getFramesToCalculatePlaytime () const - { - return - framesToCalculatePlaytime; - } - int - getMaxConcurrentUnitCount () const - { - return - maxConcurrentUnitCount; - } - int - getTotalEndGameConcurrentUnitCount () const - { - return - totalEndGameConcurrentUnitCount; - } + float + getWorldTimeElapsed() const { + return + worldTimeElapsed; + } + int + getFramesPlayed() const { + return + framesPlayed; + } + int + getFramesToCalculatePlaytime() const { + return + framesToCalculatePlaytime; + } + int + getMaxConcurrentUnitCount() const { + return + maxConcurrentUnitCount; + } + int + getTotalEndGameConcurrentUnitCount() const { + return + totalEndGameConcurrentUnitCount; + } - const - string & - getFactionTypeName (int factionIndex) const - { - return - playerStats[factionIndex]. - factionTypeName; - } - FactionPersonalityType - getPersonalityType (int factionIndex) const - { - return - playerStats[factionIndex]. - personalityType; - } - ControlType - getControl (int factionIndex) const - { - return - playerStats[factionIndex]. - control; - } - float - getResourceMultiplier (int factionIndex) const - { - return - playerStats[factionIndex]. - resourceMultiplier; - } - bool - getVictory (int factionIndex) const - { - return - playerStats[factionIndex]. - victory; - } - int - getTeam (int factionIndex) const - { - return - playerStats[factionIndex]. - teamIndex; - } - int - getKills (int factionIndex) const - { - return - playerStats[factionIndex]. - kills; - } - int - getEnemyKills (int factionIndex) const - { - return - playerStats[factionIndex]. - enemykills; - } - int - getDeaths (int factionIndex) const - { - return - playerStats[factionIndex]. - deaths; - } - int - getUnitsProduced (int factionIndex) const - { - return - playerStats[factionIndex]. - unitsProduced; - } - int - getResourcesHarvested (int factionIndex) const - { - return - playerStats[factionIndex]. - resourcesHarvested; - } - string - getPlayerName (int factionIndex) const - { - return - playerStats[factionIndex]. - playerName; - } - bool - getPlayerLeftBeforeEnd (int factionIndex) const - { - return - playerStats[factionIndex]. - playerLeftBeforeEnd; - } - void - setPlayerLeftBeforeEnd (int factionIndex, bool value) - { - playerStats[factionIndex].playerLeftBeforeEnd = value; - } - Vec3f - getPlayerColor (int factionIndex) const - { - return - playerStats[factionIndex]. - playerColor; - } + const + string & + getFactionTypeName(int factionIndex) const { + return + playerStats[factionIndex]. + factionTypeName; + } + FactionPersonalityType + getPersonalityType(int factionIndex) const { + return + playerStats[factionIndex]. + personalityType; + } + ControlType + getControl(int factionIndex) const { + return + playerStats[factionIndex]. + control; + } + float + getResourceMultiplier(int factionIndex) const { + return + playerStats[factionIndex]. + resourceMultiplier; + } + bool + getVictory(int factionIndex) const { + return + playerStats[factionIndex]. + victory; + } + int + getTeam(int factionIndex) const { + return + playerStats[factionIndex]. + teamIndex; + } + int + getKills(int factionIndex) const { + return + playerStats[factionIndex]. + kills; + } + int + getEnemyKills(int factionIndex) const { + return + playerStats[factionIndex]. + enemykills; + } + int + getDeaths(int factionIndex) const { + return + playerStats[factionIndex]. + deaths; + } + int + getUnitsProduced(int factionIndex) const { + return + playerStats[factionIndex]. + unitsProduced; + } + int + getResourcesHarvested(int factionIndex) const { + return + playerStats[factionIndex]. + resourcesHarvested; + } + string + getPlayerName(int factionIndex) const { + return + playerStats[factionIndex]. + playerName; + } + bool + getPlayerLeftBeforeEnd(int factionIndex) const { + return + playerStats[factionIndex]. + playerLeftBeforeEnd; + } + void + setPlayerLeftBeforeEnd(int factionIndex, bool value) { + playerStats[factionIndex].playerLeftBeforeEnd = value; + } + Vec3f + getPlayerColor(int factionIndex) const { + return + playerStats[factionIndex]. + playerColor; + } - int - getTimePlayerLeft (int factionIndex) const - { - return - playerStats[factionIndex]. - timePlayerLeft; - } - void - setTimePlayerLeft (int factionIndex, int value) - { - playerStats[factionIndex].timePlayerLeft = value; - } + int + getTimePlayerLeft(int factionIndex) const { + return + playerStats[factionIndex]. + timePlayerLeft; + } + void + setTimePlayerLeft(int factionIndex, int value) { + playerStats[factionIndex].timePlayerLeft = value; + } - bool - getIsMasterserverMode () const - { - return - isMasterserverMode; - } - void - setIsMasterserverMode (bool value) - { - isMasterserverMode = value; - } + bool + getIsMasterserverMode() const { + return + isMasterserverMode; + } + void + setIsMasterserverMode(bool value) { + isMasterserverMode = value; + } - void - setDescription (const string & description) - { - this->description = description; - } - void - setWorldTimeElapsed (float value) - { - this->worldTimeElapsed = value; - } - void - setFramesPlayed (int value) - { - this->framesPlayed = value; - } - void - setMaxConcurrentUnitCount (int value) - { - this->maxConcurrentUnitCount = value; - } - void - setTotalEndGameConcurrentUnitCount (int value) - { - this->totalEndGameConcurrentUnitCount = value; - } + void + setDescription(const string & description) { + this->description = description; + } + void + setWorldTimeElapsed(float value) { + this->worldTimeElapsed = value; + } + void + setFramesPlayed(int value) { + this->framesPlayed = value; + } + void + setMaxConcurrentUnitCount(int value) { + this->maxConcurrentUnitCount = value; + } + void + setTotalEndGameConcurrentUnitCount(int value) { + this->totalEndGameConcurrentUnitCount = value; + } - void - setFactionTypeName (int playerIndex, const string & factionTypeName) - { - playerStats[playerIndex].factionTypeName = factionTypeName; - } - void - setPersonalityType (int playerIndex, FactionPersonalityType value) - { - playerStats[playerIndex].personalityType = value; - } - void - setControl (int playerIndex, ControlType control) - { - playerStats[playerIndex].control = control; - } - void - setResourceMultiplier (int playerIndex, float resourceMultiplier) - { - playerStats[playerIndex].resourceMultiplier = resourceMultiplier; - } - void - setTeam (int playerIndex, int teamIndex) - { - playerStats[playerIndex].teamIndex = teamIndex; - } - void - setVictorious (int playerIndex); - void - kill (int killerFactionIndex, int killedFactionIndex, bool isEnemy, - bool isDeathCounted, bool isKillCounted); - void - die (int diedFactionIndex, bool isDeathCounted); - void - produce (int producerFactionIndex, bool isProductionCounted); - void - harvest (int harvesterFactionIndex, int amount); - void - setPlayerName (int playerIndex, const string & value) - { - playerStats[playerIndex].playerName = value; - } - void - setPlayerColor (int playerIndex, Vec3f value) - { - playerStats[playerIndex].playerColor = value; - } + void + setFactionTypeName(int playerIndex, const string & factionTypeName) { + playerStats[playerIndex].factionTypeName = factionTypeName; + } + void + setPersonalityType(int playerIndex, FactionPersonalityType value) { + playerStats[playerIndex].personalityType = value; + } + void + setControl(int playerIndex, ControlType control) { + playerStats[playerIndex].control = control; + } + void + setResourceMultiplier(int playerIndex, float resourceMultiplier) { + playerStats[playerIndex].resourceMultiplier = resourceMultiplier; + } + void + setTeam(int playerIndex, int teamIndex) { + playerStats[playerIndex].teamIndex = teamIndex; + } + void + setVictorious(int playerIndex); + void + kill(int killerFactionIndex, int killedFactionIndex, bool isEnemy, + bool isDeathCounted, bool isKillCounted); + void + die(int diedFactionIndex, bool isDeathCounted); + void + produce(int producerFactionIndex, bool isProductionCounted); + void + harvest(int harvesterFactionIndex, int amount); + void + setPlayerName(int playerIndex, const string & value) { + playerStats[playerIndex].playerName = value; + } + void + setPlayerColor(int playerIndex, Vec3f value) { + playerStats[playerIndex].playerColor = value; + } - void - addFramesToCalculatePlaytime () - { - this->framesToCalculatePlaytime++; - } + void + addFramesToCalculatePlaytime() { + this->framesToCalculatePlaytime++; + } - void - setTechName (const string & name) - { - techName = name; - } - string - getTechName () const - { - return - techName; - } + void + setTechName(const string & name) { + techName = name; + } + string + getTechName() const { + return + techName; + } - string - getStats () const; + string + getStats() const; - void - saveGame (XmlNode * rootNode); - void - loadGame (const XmlNode * rootNode); - }; + void + saveGame(XmlNode * rootNode); + void + loadGame(const XmlNode * rootNode); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/global/config.cpp b/source/glest_game/global/config.cpp index c3a72d51a..10686ba4b 100644 --- a/source/glest_game/global/config.cpp +++ b/source/glest_game/global/config.cpp @@ -37,1236 +37,1045 @@ using namespace Shared::Platform; using namespace Shared::Util; using namespace std; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - int GameConstants::networkFramePeriod = 20; - int GameConstants::updateFps = 40; - int GameConstants::cameraFps = 100; + int GameConstants::networkFramePeriod = 20; + int GameConstants::updateFps = 40; + int GameConstants::cameraFps = 100; - const float GameConstants::normalMultiplier = 1.0f; - const float GameConstants::easyMultiplier = 0.5f; - const float GameConstants::ultraMultiplier = 1.5f; - const float GameConstants::megaMultiplier = 2.5f; + const float GameConstants::normalMultiplier = 1.0f; + const float GameConstants::easyMultiplier = 0.5f; + const float GameConstants::ultraMultiplier = 1.5f; + const float GameConstants::megaMultiplier = 2.5f; - const char *GameConstants::folder_path_maps = "maps"; - const char *GameConstants::folder_path_scenarios = "scenarios"; - const char *GameConstants::folder_path_techs = "techs"; - const char *GameConstants::folder_path_tilesets = "tilesets"; - const char *GameConstants::folder_path_tutorials = "tutorials"; + const char *GameConstants::folder_path_maps = "maps"; + const char *GameConstants::folder_path_scenarios = "scenarios"; + const char *GameConstants::folder_path_techs = "techs"; + const char *GameConstants::folder_path_tilesets = "tilesets"; + const char *GameConstants::folder_path_tutorials = "tutorials"; - const char *GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME = "???"; - const char *GameConstants::NETWORK_SLOT_CLOSED_SLOTNAME = "Closed"; + const char *GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME = "???"; + const char *GameConstants::NETWORK_SLOT_CLOSED_SLOTNAME = "Closed"; - const char *GameConstants::folder_path_screenshots = "screens/"; + const char *GameConstants::folder_path_screenshots = "screens/"; - const char *GameConstants::OBSERVER_SLOTNAME = "*Observer*"; - const char *GameConstants::RANDOMFACTION_SLOTNAME = "*Random*"; + const char *GameConstants::OBSERVER_SLOTNAME = "*Observer*"; + const char *GameConstants::RANDOMFACTION_SLOTNAME = "*Random*"; - const char *GameConstants::steamCacheInstanceKey = "steamInstanceCache"; - const char *GameConstants::preCacheThreadCacheLookupKey = - "preCacheThreadCache"; - const char *GameConstants::ircClientCacheLookupKey = "ircClientCache"; - const char *GameConstants::playerTextureCacheLookupKey = - "playerTextureCache"; - const char *GameConstants::factionPreviewTextureCacheLookupKey = - "factionPreviewTextureCache"; - const char *GameConstants::characterMenuScreenPositionListCacheLookupKey = - "characterMenuScreenPositionListCache"; - const char *GameConstants::application_name = "ZetaGlest"; + const char *GameConstants::steamCacheInstanceKey = "steamInstanceCache"; + const char *GameConstants::preCacheThreadCacheLookupKey = + "preCacheThreadCache"; + const char *GameConstants::ircClientCacheLookupKey = "ircClientCache"; + const char *GameConstants::playerTextureCacheLookupKey = + "playerTextureCache"; + const char *GameConstants::factionPreviewTextureCacheLookupKey = + "factionPreviewTextureCache"; + const char *GameConstants::characterMenuScreenPositionListCacheLookupKey = + "characterMenuScreenPositionListCache"; + const char *GameConstants::application_name = "ZetaGlest"; - const char *GameConstants::LOADING_SCREEN_FILE = "loading_screen"; - const char *GameConstants::LOADING_SCREEN_FILE_FILTER = - "loading_screen*.*"; - const char *GameConstants::PREVIEW_SCREEN_FILE = "preview_screen"; - const char *GameConstants::PREVIEW_SCREEN_FILE_FILTER = - "preview_screen*.*"; - const char *GameConstants::HUD_SCREEN_FILE = "hud"; - const char *GameConstants::HUD_SCREEN_FILE_FILTER = "hud*.*"; + const char *GameConstants::LOADING_SCREEN_FILE = "loading_screen"; + const char *GameConstants::LOADING_SCREEN_FILE_FILTER = + "loading_screen*.*"; + const char *GameConstants::PREVIEW_SCREEN_FILE = "preview_screen"; + const char *GameConstants::PREVIEW_SCREEN_FILE_FILTER = + "preview_screen*.*"; + const char *GameConstants::HUD_SCREEN_FILE = "hud"; + const char *GameConstants::HUD_SCREEN_FILE_FILTER = "hud*.*"; - const char *GameConstants::pathCacheLookupKey = "pathCache_"; - const char *GameConstants::path_data_CacheLookupKey = "data"; - const char *GameConstants::path_ini_CacheLookupKey = "ini"; - const char *GameConstants::path_logs_CacheLookupKey = "logs"; + const char *GameConstants::pathCacheLookupKey = "pathCache_"; + const char *GameConstants::path_data_CacheLookupKey = "data"; + const char *GameConstants::path_ini_CacheLookupKey = "ini"; + const char *GameConstants::path_logs_CacheLookupKey = "logs"; - const char *GameConstants::saveNetworkGameFileServer = - "zetaglest-saved-server.xml"; - const char *GameConstants::saveNetworkGameFileServerCompressed = - "zetaglest-saved-server.zip"; + const char *GameConstants::saveNetworkGameFileServer = + "zetaglest-saved-server.xml"; + const char *GameConstants::saveNetworkGameFileServerCompressed = + "zetaglest-saved-server.zip"; - const char *GameConstants::saveNetworkGameFileClient = - "zetaglest-saved-client.xml"; - const char *GameConstants::saveNetworkGameFileClientCompressed = - "zetaglest-saved-client.zip"; + const char *GameConstants::saveNetworkGameFileClient = + "zetaglest-saved-client.xml"; + const char *GameConstants::saveNetworkGameFileClientCompressed = + "zetaglest-saved-client.zip"; - const char *GameConstants::saveGameFileDefault = "zetaglest-saved.xml"; - const char *GameConstants::saveGameFileAutoTestDefault = - "zetaglest-auto-saved_%s.xml"; - const char *GameConstants::saveGameFilePattern = "zetaglest-saved_%s.xml"; + const char *GameConstants::saveGameFileDefault = "zetaglest-saved.xml"; + const char *GameConstants::saveGameFileAutoTestDefault = + "zetaglest-auto-saved_%s.xml"; + const char *GameConstants::saveGameFilePattern = "zetaglest-saved_%s.xml"; - const char *Config::glest_ini_filename = "glest.ini"; - const char *Config::glestuser_ini_filename = "glestuser.ini"; + const char *Config::glest_ini_filename = "glest.ini"; + const char *Config::glestuser_ini_filename = "glestuser.ini"; - const char *Config::glestkeys_ini_filename = "glestkeys.ini"; - const char *Config::glestuserkeys_ini_filename = "glestuserkeys.ini"; + const char *Config::glestkeys_ini_filename = "glestkeys.ini"; + const char *Config::glestuserkeys_ini_filename = "glestuserkeys.ini"; - const char *Config::ACTIVE_MOD_PROPERTY_NAME = "current_mod_name"; + const char *Config::ACTIVE_MOD_PROPERTY_NAME = "current_mod_name"; - const char *Config::colorPicking = "color"; - const char *Config::selectBufPicking = "selectbuf"; - const char *Config::frustumPicking = "frustum"; + const char *Config::colorPicking = "color"; + const char *Config::selectBufPicking = "selectbuf"; + const char *Config::frustumPicking = "frustum"; - map < string, string > Config::customRuntimeProperties; + map < string, string > Config::customRuntimeProperties; -// ===================================================== -// class Config -// ===================================================== + // ===================================================== + // class Config + // ===================================================== - const string defaultNotFoundValue = "~~NOT FOUND~~"; + const string defaultNotFoundValue = "~~NOT FOUND~~"; - map < ConfigType, Config > Config::configList; + map < ConfigType, Config > Config::configList; - Config::Config () - { - fileLoaded.first = false; - fileLoaded.second = false; - cfgType.first = cfgMainGame; - cfgType.second = cfgUserGame; - fileName.first = ""; - fileName.second = ""; - fileNameParameter.first = ""; - fileNameParameter.second = ""; - custom_path_parameter = ""; - } + Config::Config() { + fileLoaded.first = false; + fileLoaded.second = false; + cfgType.first = cfgMainGame; + cfgType.second = cfgUserGame; + fileName.first = ""; + fileName.second = ""; + fileNameParameter.first = ""; + fileNameParameter.second = ""; + custom_path_parameter = ""; + } - bool Config::tryCustomPath (std::pair < ConfigType, ConfigType > &type, - std::pair < string, string > &file, - string custom_path) - { - bool wasFound = false; - if ((type.first == cfgMainGame && type.second == cfgUserGame && - file.first == glest_ini_filename - && file.second == glestuser_ini_filename) - || (type.first == cfgMainKeys && type.second == cfgUserKeys - && file.first == glestkeys_ini_filename - && file.second == glestuserkeys_ini_filename)) - { + bool Config::tryCustomPath(std::pair < ConfigType, ConfigType > &type, + std::pair < string, string > &file, + string custom_path) { + bool wasFound = false; + if ((type.first == cfgMainGame && type.second == cfgUserGame && + file.first == glest_ini_filename + && file.second == glestuser_ini_filename) + || (type.first == cfgMainKeys && type.second == cfgUserKeys + && file.first == glestkeys_ini_filename + && file.second == glestuserkeys_ini_filename)) { - string linuxPath = custom_path; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("-=-=-=-=-=-=-= looking for file in possible location [%s]\n", - linuxPath.c_str ()); + string linuxPath = custom_path; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("-=-=-=-=-=-=-= looking for file in possible location [%s]\n", + linuxPath.c_str()); #if defined(__linux__) - string nixFile = linuxPath + "linux_" + file.first; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("-=-=-=-=-=-=-= looking for linux specific file in possible location [%s]\n", - nixFile.c_str ()); + string nixFile = linuxPath + "linux_" + file.first; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("-=-=-=-=-=-=-= looking for linux specific file in possible location [%s]\n", + nixFile.c_str()); - if (wasFound == false && fileExists (nixFile) == true) - { - file.first = nixFile; - file.second = linuxPath + file.second; - wasFound = true; - } + if (wasFound == false && fileExists(nixFile) == true) { + file.first = nixFile; + file.second = linuxPath + file.second; + wasFound = true; + } #elif defined(__WIN32__) - string winFile = linuxPath + "windows_" + file.first; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("-=-=-=-=-=-=-= looking for windows specific file in possible location [%s]\n", - winFile.c_str ()); + string winFile = linuxPath + "windows_" + file.first; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("-=-=-=-=-=-=-= looking for windows specific file in possible location [%s]\n", + winFile.c_str()); - if (wasFound == false && fileExists (winFile) == true) - { - file.first = winFile; - file.second = linuxPath + file.second; - wasFound = true; - } + if (wasFound == false && fileExists(winFile) == true) { + file.first = winFile; + file.second = linuxPath + file.second; + wasFound = true; + } #endif - if (wasFound == false && fileExists (linuxPath + file.first) == true) - { - file.first = linuxPath + file.first; - file.second = linuxPath + file.second; - wasFound = true; - } - } - return wasFound; - } + if (wasFound == false && fileExists(linuxPath + file.first) == true) { + file.first = linuxPath + file.first; + file.second = linuxPath + file.second; + wasFound = true; + } + } + return wasFound; + } - Config::Config (std::pair < ConfigType, ConfigType > type, - std::pair < string, string > file, std::pair < bool, - bool > fileMustExist, string custom_path) - { - fileLoaded.first = false; - fileLoaded.second = false; - cfgType = type; - fileName = file; - fileNameParameter = file; - custom_path_parameter = custom_path; + Config::Config(std::pair < ConfigType, ConfigType > type, + std::pair < string, string > file, std::pair < bool, + bool > fileMustExist, string custom_path) { + fileLoaded.first = false; + fileLoaded.second = false; + cfgType = type; + fileName = file; + fileNameParameter = file; + custom_path_parameter = custom_path; - if (getGameReadWritePath (GameConstants::path_ini_CacheLookupKey) != "") - { - fileName.first = - getGameReadWritePath (GameConstants::path_ini_CacheLookupKey) + - fileName.first; - fileName.second = - getGameReadWritePath (GameConstants::path_ini_CacheLookupKey) + - fileName.second; - } + if (getGameReadWritePath(GameConstants::path_ini_CacheLookupKey) != "") { + fileName.first = + getGameReadWritePath(GameConstants::path_ini_CacheLookupKey) + + fileName.first; + fileName.second = + getGameReadWritePath(GameConstants::path_ini_CacheLookupKey) + + fileName.second; + } - bool foundPath = false; - string currentpath = custom_path; + bool foundPath = false; + string currentpath = custom_path; - if (custom_path != "") - { - foundPath = tryCustomPath (cfgType, fileName, custom_path); - } + if (custom_path != "") { + foundPath = tryCustomPath(cfgType, fileName, custom_path); + } - if (foundPath == false) - { - currentpath = - extractDirectoryPathFromFile (Properties::getApplicationPath ()); - foundPath = tryCustomPath (cfgType, fileName, currentpath); - } + if (foundPath == false) { + currentpath = + extractDirectoryPathFromFile(Properties::getApplicationPath()); + foundPath = tryCustomPath(cfgType, fileName, currentpath); + } #if defined(CUSTOM_DATA_INSTALL_PATH) - if (foundPath == false) - { - foundPath = - tryCustomPath (cfgType, fileName, - formatPath (TOSTRING (CUSTOM_DATA_INSTALL_PATH))); - } + if (foundPath == false) { + foundPath = + tryCustomPath(cfgType, fileName, + formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH))); + } #endif #if defined(MG_CMAKE_INSTALL_PREFIX) - if (foundPath == false) - { - foundPath = - tryCustomPath (cfgType, fileName, - formatPath (TOSTRING (MG_CMAKE_INSTALL_PREFIX))); - } + if (foundPath == false) { + foundPath = + tryCustomPath(cfgType, fileName, + formatPath(TOSTRING(MG_CMAKE_INSTALL_PREFIX))); + } #endif -// Look in standard linux shared paths for ini files + // Look in standard linux shared paths for ini files #if defined(__linux__) - if (foundPath == false) - { - foundPath = - tryCustomPath (cfgType, fileName, "/usr/share/zetaglest/"); - } - if (foundPath == false) - { - foundPath = - tryCustomPath (cfgType, fileName, "/usr/share/games/zetaglest/"); - } - if (foundPath == false) - { - foundPath = - tryCustomPath (cfgType, fileName, "/usr/local/share/zetaglest/"); - } - if (foundPath == false) - { - foundPath = - tryCustomPath (cfgType, fileName, - "/usr/local/share/games/zetaglest/"); - } + if (foundPath == false) { + foundPath = + tryCustomPath(cfgType, fileName, "/usr/share/zetaglest/"); + } + if (foundPath == false) { + foundPath = + tryCustomPath(cfgType, fileName, "/usr/share/games/zetaglest/"); + } + if (foundPath == false) { + foundPath = + tryCustomPath(cfgType, fileName, "/usr/local/share/zetaglest/"); + } + if (foundPath == false) { + foundPath = + tryCustomPath(cfgType, fileName, + "/usr/local/share/games/zetaglest/"); + } #endif - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("foundPath = [%d]\n", foundPath); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("foundPath = [%d]\n", foundPath); - if (fileMustExist.first == true && fileExists (fileName.first) == false) - { - //string currentpath = extractDirectoryPathFromFile(Properties::getApplicationPath()); - fileName.first = currentpath + fileName.first; - } + if (fileMustExist.first == true && fileExists(fileName.first) == false) { + //string currentpath = extractDirectoryPathFromFile(Properties::getApplicationPath()); + fileName.first = currentpath + fileName.first; + } #if defined(WIN32) - //string test = "C:\\Code\\zetaglest\\mk\\windows\\.\\..\\..\\data\\glest_game\\glest.ini"; - //updatePathClimbingParts(test); + //string test = "C:\\Code\\zetaglest\\mk\\windows\\.\\..\\..\\data\\glest_game\\glest.ini"; + //updatePathClimbingParts(test); - updatePathClimbingParts (fileName.first); + updatePathClimbingParts(fileName.first); #endif - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("-=-=-=-=-=-=-= About to load fileName.first = [%s]\n", - fileName.first.c_str ()); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("-=-=-=-=-=-=-= About to load fileName.first = [%s]\n", + fileName.first.c_str()); - if (fileMustExist.first == true || - (fileMustExist.first == false - && fileExists (fileName.first) == true)) - { - properties.first.load (fileName.first); - fileLoaded.first = true; - } + if (fileMustExist.first == true || + (fileMustExist.first == false + && fileExists(fileName.first) == true)) { + properties.first.load(fileName.first); + fileLoaded.first = true; + } - if (cfgType.first == cfgMainGame) - { - if (properties.first. - getString ("UserData_Root", - defaultNotFoundValue.c_str ()) != defaultNotFoundValue) - { - string userData = properties.first.getString ("UserData_Root"); - if (userData != "") - { - endPathWithSlash (userData); - } - fileName.second = userData + fileNameParameter.second; - } - else if (properties.first. - getString ("UserOverrideFile", - defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - string userData = properties.first.getString ("UserOverrideFile"); - if (userData != "") - { - endPathWithSlash (userData); - } - fileName.second = userData + fileNameParameter.second; - } + if (cfgType.first == cfgMainGame) { + if (properties.first. + getString("UserData_Root", + defaultNotFoundValue.c_str()) != defaultNotFoundValue) { + string userData = properties.first.getString("UserData_Root"); + if (userData != "") { + endPathWithSlash(userData); + } + fileName.second = userData + fileNameParameter.second; + } else if (properties.first. + getString("UserOverrideFile", + defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + string userData = properties.first.getString("UserOverrideFile"); + if (userData != "") { + endPathWithSlash(userData); + } + fileName.second = userData + fileNameParameter.second; + } #if defined(WIN32) - updatePathClimbingParts (fileName.second); + updatePathClimbingParts(fileName.second); #endif - } - else if (cfgType.first == cfgMainKeys) - { - Config & mainCfg = Config::getInstance (); - if (mainCfg. - getString ("UserData_Root", - defaultNotFoundValue.c_str ()) != defaultNotFoundValue) - { - string userData = mainCfg.getString ("UserData_Root"); - if (userData != "") - { - endPathWithSlash (userData); - } - fileName.second = userData + fileNameParameter.second; - } - else if (mainCfg. - getString ("UserOverrideFile", - defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - string userData = mainCfg.getString ("UserOverrideFile"); - if (userData != "") - { - endPathWithSlash (userData); - } - fileName.second = userData + fileNameParameter.second; - } + } else if (cfgType.first == cfgMainKeys) { + Config & mainCfg = Config::getInstance(); + if (mainCfg. + getString("UserData_Root", + defaultNotFoundValue.c_str()) != defaultNotFoundValue) { + string userData = mainCfg.getString("UserData_Root"); + if (userData != "") { + endPathWithSlash(userData); + } + fileName.second = userData + fileNameParameter.second; + } else if (mainCfg. + getString("UserOverrideFile", + defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + string userData = mainCfg.getString("UserOverrideFile"); + if (userData != "") { + endPathWithSlash(userData); + } + fileName.second = userData + fileNameParameter.second; + } #if defined(WIN32) - updatePathClimbingParts (fileName.second); + updatePathClimbingParts(fileName.second); #endif - } + } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("-=-=-=-=-=-=-= About to load fileName.second = [%s]\n", - fileName.second.c_str ()); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("-=-=-=-=-=-=-= About to load fileName.second = [%s]\n", + fileName.second.c_str()); - if (fileMustExist.second == true || - (fileMustExist.second == false - && fileExists (fileName.second) == true)) - { - properties.second.load (fileName.second); - fileLoaded.second = true; - } + if (fileMustExist.second == true || + (fileMustExist.second == false + && fileExists(fileName.second) == true)) { + properties.second.load(fileName.second); + fileLoaded.second = true; + } - try - { - if (fileName.second != "" && fileExists (fileName.second) == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] attempting to auto-create cfgFile.second = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - fileName.second.c_str ()); + try { + if (fileName.second != "" && fileExists(fileName.second) == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] attempting to auto-create cfgFile.second = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + fileName.second.c_str()); #if defined(WIN32) && !defined(__MINGW32__) - wstring wstr = utf8_decode (fileName.second); - FILE *fp = _wfopen (wstr.c_str (), L"w"); - std::ofstream userFile (fp); + wstring wstr = utf8_decode(fileName.second); + FILE *fp = _wfopen(wstr.c_str(), L"w"); + std::ofstream userFile(fp); #else - std::ofstream userFile; - userFile.open (fileName.second.c_str (), - ios_base::out | ios_base::trunc); + std::ofstream userFile; + userFile.open(fileName.second.c_str(), + ios_base::out | ios_base::trunc); #endif - userFile.close (); + userFile.close(); #if defined(WIN32) && !defined(__MINGW32__) - if (fp) - { - fclose (fp); - } + if (fp) { + fclose(fp); + } #endif - fileLoaded.second = true; - properties.second.load (fileName.second); - } - } - catch (const exception & ex) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - ex.what ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] ERROR trying to auto-create cfgFile.second = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - fileName.second.c_str ()); - } - } - - Config & Config::getInstance (std::pair < ConfigType, ConfigType > type, - std::pair < string, string > file, - std::pair < bool, bool > fileMustExist, - string custom_path) - { - if (configList.find (type.first) == configList.end ()) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - Config config (type, file, fileMustExist, custom_path); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - configList.insert (map < ConfigType, - Config >::value_type (type.first, config)); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - return configList.find (type.first)->second; - } - - void Config::CopyAll (Config * src, Config * dest) - { - - dest->properties = src->properties; - dest->cfgType = src->cfgType; - dest->fileName = src->fileName; - dest->fileNameParameter = src->fileNameParameter; - dest->fileLoaded = src->fileLoaded; - } - - void Config::reload () - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - std::pair < ConfigType, ConfigType > type = - std::make_pair (cfgType.first, cfgType.second); - Config newconfig (type, - std::make_pair (fileNameParameter.first, - fileNameParameter.second), - std::make_pair (true, false), custom_path_parameter); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - Config & oldconfig = configList.find (type.first)->second; - CopyAll (&newconfig, &oldconfig); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - void Config::save (const string & path) - { - if (fileLoaded.second == true) - { - if (path != "") - { - fileName.second = path; - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] save file [%s]\n", __FILE__, - __FUNCTION__, __LINE__, fileName.second.c_str ()); - properties.second.save (fileName.second); - return; - } - - if (path != "") - { - fileName.first = path; - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] save file [%s]\n", __FILE__, - __FUNCTION__, __LINE__, fileName.first.c_str ()); - properties.first.save (fileName.first); - } - - int Config::getInt (const char *key, const char *defaultValueIfNotFound) const - { - if (tempProperties.getString (key, defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return tempProperties.getInt (key, defaultValueIfNotFound); - } - if (fileLoaded.second == true && - properties.second.getString (key, - defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return properties.second.getInt (key, defaultValueIfNotFound); - } - return properties.first.getInt (key, defaultValueIfNotFound); - } - - bool Config::getBool (const char *key, const char *defaultValueIfNotFound) const - { - if (tempProperties.getString (key, defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return tempProperties.getBool (key, defaultValueIfNotFound); - } - - if (fileLoaded.second == true && - properties.second.getString (key, - defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return properties.second.getBool (key, defaultValueIfNotFound); - } - - return properties.first.getBool (key, defaultValueIfNotFound); - } - - float Config::getFloat (const char *key, - const char *defaultValueIfNotFound) const - { - if (tempProperties.getString (key, defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return tempProperties.getFloat (key, defaultValueIfNotFound); - } - - if (fileLoaded.second == true && - properties.second.getString (key, - defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return properties.second.getFloat (key, defaultValueIfNotFound); - } - - return properties.first.getFloat (key, defaultValueIfNotFound); - } - - const string Config::getString (const char *key, - const char *defaultValueIfNotFound) const - { - if (tempProperties.getString (key, defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return tempProperties.getString (key, defaultValueIfNotFound); - } - - if (fileLoaded.second == true && - properties.second.getString (key, - defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return properties.second.getString (key, defaultValueIfNotFound); - } - - return properties.first.getString (key, defaultValueIfNotFound); - } - - int Config::getInt (const string & key, - const char *defaultValueIfNotFound) const - { - if (tempProperties.getString (key, defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return tempProperties.getInt (key, defaultValueIfNotFound); - } - - if (fileLoaded.second == true && - properties.second.getString (key, - defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return properties.second.getInt (key, defaultValueIfNotFound); - } - - return properties.first.getInt (key, defaultValueIfNotFound); - } - - bool Config::getBool (const string & key, - const char *defaultValueIfNotFound) const - { - if (tempProperties.getString (key, defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return tempProperties.getBool (key, defaultValueIfNotFound); - } - - if (fileLoaded.second == true && - properties.second.getString (key, - defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return properties.second.getBool (key, defaultValueIfNotFound); - } - - return properties.first.getBool (key, defaultValueIfNotFound); - } - - float Config::getFloat (const string & key, - const char *defaultValueIfNotFound) const - { - if (tempProperties.getString (key, defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return tempProperties.getFloat (key, defaultValueIfNotFound); - } - - if (fileLoaded.second == true && - properties.second.getString (key, - defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return properties.second.getFloat (key, defaultValueIfNotFound); - } - - return properties.first.getFloat (key, defaultValueIfNotFound); - } - - const string Config::getString (const string & key, - const char *defaultValueIfNotFound) const - { - if (tempProperties.getString (key, defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return tempProperties.getString (key, defaultValueIfNotFound); - } - - if (fileLoaded.second == true && - properties.second.getString (key, - defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - return properties.second.getString (key, defaultValueIfNotFound); - } - - return properties.first.getString (key, defaultValueIfNotFound); - } - - SDL_Keycode Config::translateStringToSDLKey (const string & value) const - { - SDL_Keycode result = SDLK_UNKNOWN; - - if (IsNumeric (value.c_str ()) == true) - { - result = (SDL_Keycode) strToInt (value); - } - else if (value.substr (0, 2) == "vk") - { - if (value == "vkLeft") - { - result = SDLK_LEFT; - } - else if (value == "vkRight") - { - result = SDLK_RIGHT; - } - else if (value == "vkUp") - { - result = SDLK_UP; - } - else if (value == "vkDown") - { - result = SDLK_DOWN; - } - else if (value == "vkAdd") - { - result = SDLK_PLUS; - } - else if (value == "vkSubtract") - { - result = SDLK_MINUS; - } - else if (value == "vkEscape") - { - result = SDLK_ESCAPE; - } - else if (value == "vkF1") - { - result = SDLK_F1; - } - else if (value == "vkF2") - { - result = SDLK_F2; - } - else if (value == "vkF3") - { - result = SDLK_F3; - } - else if (value == "vkF4") - { - result = SDLK_F4; - } - else if (value == "vkF5") - { - result = SDLK_F5; - } - else if (value == "vkF6") - { - result = SDLK_F6; - } - else if (value == "vkF7") - { - result = SDLK_F7; - } - else if (value == "vkF8") - { - result = SDLK_F8; - } - else if (value == "vkF9") - { - result = SDLK_F9; - } - else if (value == "vkF10") - { - result = SDLK_F10; - } - else if (value == "vkF11") - { - result = SDLK_F11; - } - else if (value == "vkF12") - { - result = SDLK_F12; - } - else if (value == "vkPrint") - { - result = SDLK_PRINTSCREEN; - } - else if (value == "vkPause") - { - result = SDLK_PAUSE; - } - else - { - string sError = "Unsupported key translation [" + value + "]"; - throw megaglest_runtime_error (sError.c_str ()); - } - } - else if (value.length () >= 1) - { - if (value.length () == 3 && value[0] == '\'' && value[2] == '\'') - { - result = (SDL_Keycode) value[1]; - } - else - { - bool foundKey = false; - if (value.length () > 1) - { - SDL_Keycode lookup = SDL_GetKeyFromName (value.c_str ()); - if (lookup != SDLK_UNKNOWN) - { - result = lookup; - foundKey = true; - } - } - - if (foundKey == false) - { - result = (SDL_Keycode) value[0]; - } - } - } - else - { - string sError = "Unsupported key translation" + value; - throw megaglest_runtime_error (sError.c_str ()); - } - - // Because SDL is based on lower Ascii - //result = tolower(result); - return result; - } - - SDL_Keycode Config::getSDLKey (const char *key) const - { - if (fileLoaded.second == true && - properties.second.getString (key, - defaultNotFoundValue.c_str ()) != - defaultNotFoundValue) - { - - string value = properties.second.getString (key); - return translateStringToSDLKey (value); - } - string value = properties.first.getString (key); - return translateStringToSDLKey (value); - } - -//char Config::getCharKey(const char *key) const { -// if(fileLoaded.second == true && -// properties.second.getString(key, defaultNotFoundValue.c_str()) != defaultNotFoundValue) { -// -// string value = properties.second.getString(key); -// return translateStringToCharKey(value); -// } -// string value = properties.first.getString(key); -// return translateStringToCharKey(value); -//} - - void Config::setInt (const string & key, int value, bool tempBuffer) - { - if (tempBuffer == true) - { - tempProperties.setInt (key, value); - return; - } - if (fileLoaded.second == true) - { - properties.second.setInt (key, value); - return; - } - properties.first.setInt (key, value); - } - - void Config::setBool (const string & key, bool value, bool tempBuffer) - { - if (tempBuffer == true) - { - tempProperties.setBool (key, value); - return; - } - - if (fileLoaded.second == true) - { - properties.second.setBool (key, value); - return; - } - - properties.first.setBool (key, value); - } - - void Config::setFloat (const string & key, float value, bool tempBuffer) - { - if (tempBuffer == true) - { - tempProperties.setFloat (key, value); - return; - } - - if (fileLoaded.second == true) - { - properties.second.setFloat (key, value); - return; - } - - properties.first.setFloat (key, value); - } - - void Config::setString (const string & key, const string & value, - bool tempBuffer) - { - if (tempBuffer == true) - { - tempProperties.setString (key, value); - return; - } - - if (fileLoaded.second == true) - { - properties.second.setString (key, value); - return; - } - - properties.first.setString (key, value); - } - - vector < pair < string, - string > - >Config:: - getPropertiesFromContainer (const Properties & propertiesObj) const - { - vector < pair < string, string > >result; - - int count = propertiesObj.getPropertyCount (); - for (int i = 0; i < count; ++i) - { - pair < string, string > property; - property.first = propertiesObj.getKey (i); - property.second = propertiesObj.getString (i); - result.push_back (property); - } - - return result; - } - - vector < pair < string, string > >Config::getMergedProperties ()const - { - vector < pair < string, string > >result = getMasterProperties (); - vector < pair < string, string > >resultUser = getUserProperties (); - for (unsigned int i = 0; i < resultUser.size (); ++i) - { - const pair < string, string > &propertyUser = resultUser[i]; - bool overrideProperty = false; - for (unsigned int j = 0; j < result.size (); ++j) - { - pair < string, string > &property = result[j]; - // Take the user property and override the original value - if (property.first == propertyUser.first) - { - overrideProperty = true; - property.second = propertyUser.second; - break; - } - } - if (overrideProperty == false) - { - result.push_back (propertyUser); - } - } - - return result; - } - - vector < pair < string, string > >Config::getMasterProperties ()const - { - return getPropertiesFromContainer (properties.first); - } - - vector < pair < string, string > >Config::getUserProperties () const - { - return getPropertiesFromContainer (properties.second); - } - - void Config::setUserProperties (const vector < pair < string, - string > >&valueList) - { - Properties & propertiesObj = properties.second; - - for (unsigned int idx = 0; idx < valueList.size (); ++idx) - { - const pair < string, string > &nameValuePair = valueList[idx]; - propertiesObj.setString (nameValuePair.first, nameValuePair.second); - } - } - - string Config::getFileName (bool userFilename) const - { - string result = fileName.second; - if (userFilename == false) - { - result = fileName.first; - } - - return result; - } - - string Config::toString () - { - return properties.first.toString (); - } - - vector < string > Config::getPathListForType (PathType type, - string scenarioDir) - { - vector < string > pathList; - string data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - - string userData = getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - //if(data_path == "") { - // userData = userData; - //} - //else { - // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("extractLastDirectoryFromPath(userData) [%s] from userData [%s]\n",extractLastDirectoryFromPath(userData).c_str(),userData.c_str()); - // userData = data_path + extractLastDirectoryFromPath(userData); - //} - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] userData path [%s]\n",__FILE__,__FUNCTION__,__LINE__,userData.c_str()); - - if (isdir (userData.c_str ()) == false) - { - createDirectoryPaths (userData); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] creating path [%s]\n", __FILE__, - __FUNCTION__, __LINE__, userData.c_str ()); - } - - string userDataMaps = userData + GameConstants::folder_path_maps; - if (isdir (userDataMaps.c_str ()) == false) - { - createDirectoryPaths (userDataMaps); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] creating path [%s]\n", __FILE__, - __FUNCTION__, __LINE__, userDataMaps.c_str ()); - } - string userDataScenarios = - userData + GameConstants::folder_path_scenarios; - if (isdir (userDataScenarios.c_str ()) == false) - { - createDirectoryPaths (userDataScenarios); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] creating path [%s]\n", __FILE__, - __FUNCTION__, __LINE__, userDataScenarios.c_str ()); - } - string userDataTechs = userData + GameConstants::folder_path_techs; - if (isdir (userDataTechs.c_str ()) == false) - { - createDirectoryPaths (userDataTechs); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] creating path [%s]\n", __FILE__, - __FUNCTION__, __LINE__, userDataTechs.c_str ()); - } - string userDataTilesets = - userData + GameConstants::folder_path_tilesets; - if (isdir (userDataTilesets.c_str ()) == false) - { - createDirectoryPaths (userDataTilesets); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] creating path [%s]\n", __FILE__, - __FUNCTION__, __LINE__, userDataTilesets.c_str ()); - } - string userDataTutorials = - userData + GameConstants::folder_path_tutorials; - if (isdir (userDataTutorials.c_str ()) == false) - { - createDirectoryPaths (userDataTutorials); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] creating path [%s]\n", __FILE__, - __FUNCTION__, __LINE__, userDataTutorials.c_str ()); - } - } - if (scenarioDir != "") - { - if (EndsWith (scenarioDir, ".xml") == true) - { - scenarioDir = extractDirectoryPathFromFile (scenarioDir); - } - - //string scenarioLocation = data_path + scenarioDir; - string scenarioLocation = scenarioDir; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Scenario path [%s]\n", scenarioLocation.c_str ()); - pathList.push_back (scenarioLocation); - } - - switch (type) - { - case ptMaps: - pathList.push_back (data_path + GameConstants::folder_path_maps); - if (userData != "") - { - pathList.push_back (userData + - string (GameConstants::folder_path_maps)); - } - break; - case ptScenarios: - pathList.push_back (data_path + GameConstants::folder_path_scenarios); - if (userData != "") - { - pathList.push_back (userData + - string (GameConstants::folder_path_scenarios)); - } - break; - case ptTechs: - pathList.push_back (data_path + GameConstants::folder_path_techs); - if (userData != "") - { - pathList.push_back (userData + - string (GameConstants::folder_path_techs)); - } - break; - case ptTilesets: - pathList.push_back (data_path + GameConstants::folder_path_tilesets); - if (userData != "") - { - pathList.push_back (userData + - string (GameConstants::folder_path_tilesets)); - } - break; - case ptTutorials: - pathList.push_back (data_path + GameConstants::folder_path_tutorials); - if (userData != "") - { - pathList.push_back (userData + - string (GameConstants::folder_path_tutorials)); - } - break; - } - - return pathList; - } - - bool Config::replaceFileWithLocalFile (const vector < string > &dirList, - string fileNamePart, - string & resultToReplace) - { - bool found = false; - for (unsigned int i = 0; i < dirList.size (); ++i) - { - string path = dirList[i]; - endPathWithSlash (path); - string newFileName = path + fileNamePart; - if (fileExists (newFileName) == true) - { - resultToReplace = newFileName; - found = true; - break; - } - } - return found; - } - - - - string Config::findValidLocalFileFromPath (string fileName) - { - string result = fileName; - - if (fileName.find ("maps/") != fileName.npos) - { - size_t pos = fileName.find ("maps/"); - string fileNamePart = fileName.substr (pos + 5); - Config & config = Config::getInstance (); - vector < string > dirList = config.getPathListForType (ptMaps); - replaceFileWithLocalFile (dirList, fileNamePart, result); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Found file [%s] @ " MG_SIZE_T_SPECIFIER - " [%s]\nNew File [%s]\n", fileName.c_str (), pos, - fileNamePart.c_str (), result.c_str ()); - } - else if (fileName.find ("tilesets/") != fileName.npos) - { - size_t pos = fileName.find ("tilesets/"); - string fileNamePart = fileName.substr (pos + 9); - Config & config = Config::getInstance (); - vector < string > dirList = config.getPathListForType (ptTilesets); - replaceFileWithLocalFile (dirList, fileNamePart, result); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Found file [%s] @ " MG_SIZE_T_SPECIFIER - " [%s]\nNew File [%s]\n", fileName.c_str (), pos, - fileNamePart.c_str (), result.c_str ()); - } - else if (fileName.find ("techs/") != fileName.npos) - { - size_t pos = fileName.find ("techs/"); - string fileNamePart = fileName.substr (pos + 6); - Config & config = Config::getInstance (); - vector < string > dirList = config.getPathListForType (ptTechs); - replaceFileWithLocalFile (dirList, fileNamePart, result); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Found file [%s] @ " MG_SIZE_T_SPECIFIER - " [%s]\nNew File [%s]\n", fileName.c_str (), pos, - fileNamePart.c_str (), result.c_str ()); - } - else if (fileName.find ("scenarios/") != fileName.npos) - { - size_t pos = fileName.find ("scenarios/"); - string fileNamePart = fileName.substr (pos + 10); - Config & config = Config::getInstance (); - vector < string > dirList = config.getPathListForType (ptScenarios); - replaceFileWithLocalFile (dirList, fileNamePart, result); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Found file [%s] @ " MG_SIZE_T_SPECIFIER - " [%s]\nNew File [%s]\n", fileName.c_str (), pos, - fileNamePart.c_str (), result.c_str ()); - } - else if (fileName.find ("tutorials/") != fileName.npos) - { - size_t pos = fileName.find ("tutorials/"); - string fileNamePart = fileName.substr (pos + 10); - Config & config = Config::getInstance (); - vector < string > dirList = config.getPathListForType (ptTutorials); - replaceFileWithLocalFile (dirList, fileNamePart, result); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Found file [%s] @ " MG_SIZE_T_SPECIFIER - " [%s]\nNew File [%s]\n", fileName.c_str (), pos, - fileNamePart.c_str (), result.c_str ()); - } - - return result; - } - - -// static - string Config::getMapPath (const string & mapName, string scenarioDir, - bool errorOnNotFound) - { - - Config & config = Config::getInstance (); - vector < string > pathList = - config.getPathListForType (ptMaps, scenarioDir); - - for (int idx = 0; idx < (int) pathList.size (); idx++) - { - string map_path = pathList[idx]; - endPathWithSlash (map_path); - - const string mega = map_path + mapName + ".mgm"; - const string glest = map_path + mapName + ".gbm"; - if (fileExists (mega)) - { - return mega; - } - else if (fileExists (glest)) - { - return glest; - } - } - - if (errorOnNotFound == true) - { - //abort(); - throw megaglest_runtime_error ("Map not found [" + mapName + - "]\nScenario [" + scenarioDir + "]"); - } - - return ""; - } - - } + fileLoaded.second = true; + properties.second.load(fileName.second); + } + } catch (const exception & ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] ERROR trying to auto-create cfgFile.second = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + fileName.second.c_str()); + } + } + + Config & Config::getInstance(std::pair < ConfigType, ConfigType > type, + std::pair < string, string > file, + std::pair < bool, bool > fileMustExist, + string custom_path) { + if (configList.find(type.first) == configList.end()) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + Config config(type, file, fileMustExist, custom_path); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + configList.insert(map < ConfigType, + Config >::value_type(type.first, config)); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + return configList.find(type.first)->second; + } + + void Config::CopyAll(Config * src, Config * dest) { + + dest->properties = src->properties; + dest->cfgType = src->cfgType; + dest->fileName = src->fileName; + dest->fileNameParameter = src->fileNameParameter; + dest->fileLoaded = src->fileLoaded; + } + + void Config::reload() { + if (SystemFlags::VERBOSE_MODE_ENABLED) + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + std::pair < ConfigType, ConfigType > type = + std::make_pair(cfgType.first, cfgType.second); + Config newconfig(type, + std::make_pair(fileNameParameter.first, + fileNameParameter.second), + std::make_pair(true, false), custom_path_parameter); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + Config & oldconfig = configList.find(type.first)->second; + CopyAll(&newconfig, &oldconfig); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + void Config::save(const string & path) { + if (fileLoaded.second == true) { + if (path != "") { + fileName.second = path; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] save file [%s]\n", __FILE__, + __FUNCTION__, __LINE__, fileName.second.c_str()); + properties.second.save(fileName.second); + return; + } + + if (path != "") { + fileName.first = path; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] save file [%s]\n", __FILE__, + __FUNCTION__, __LINE__, fileName.first.c_str()); + properties.first.save(fileName.first); + } + + int Config::getInt(const char *key, const char *defaultValueIfNotFound) const { + if (tempProperties.getString(key, defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return tempProperties.getInt(key, defaultValueIfNotFound); + } + if (fileLoaded.second == true && + properties.second.getString(key, + defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return properties.second.getInt(key, defaultValueIfNotFound); + } + return properties.first.getInt(key, defaultValueIfNotFound); + } + + bool Config::getBool(const char *key, const char *defaultValueIfNotFound) const { + if (tempProperties.getString(key, defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return tempProperties.getBool(key, defaultValueIfNotFound); + } + + if (fileLoaded.second == true && + properties.second.getString(key, + defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return properties.second.getBool(key, defaultValueIfNotFound); + } + + return properties.first.getBool(key, defaultValueIfNotFound); + } + + float Config::getFloat(const char *key, + const char *defaultValueIfNotFound) const { + if (tempProperties.getString(key, defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return tempProperties.getFloat(key, defaultValueIfNotFound); + } + + if (fileLoaded.second == true && + properties.second.getString(key, + defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return properties.second.getFloat(key, defaultValueIfNotFound); + } + + return properties.first.getFloat(key, defaultValueIfNotFound); + } + + const string Config::getString(const char *key, + const char *defaultValueIfNotFound) const { + if (tempProperties.getString(key, defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return tempProperties.getString(key, defaultValueIfNotFound); + } + + if (fileLoaded.second == true && + properties.second.getString(key, + defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return properties.second.getString(key, defaultValueIfNotFound); + } + + return properties.first.getString(key, defaultValueIfNotFound); + } + + int Config::getInt(const string & key, + const char *defaultValueIfNotFound) const { + if (tempProperties.getString(key, defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return tempProperties.getInt(key, defaultValueIfNotFound); + } + + if (fileLoaded.second == true && + properties.second.getString(key, + defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return properties.second.getInt(key, defaultValueIfNotFound); + } + + return properties.first.getInt(key, defaultValueIfNotFound); + } + + bool Config::getBool(const string & key, + const char *defaultValueIfNotFound) const { + if (tempProperties.getString(key, defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return tempProperties.getBool(key, defaultValueIfNotFound); + } + + if (fileLoaded.second == true && + properties.second.getString(key, + defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return properties.second.getBool(key, defaultValueIfNotFound); + } + + return properties.first.getBool(key, defaultValueIfNotFound); + } + + float Config::getFloat(const string & key, + const char *defaultValueIfNotFound) const { + if (tempProperties.getString(key, defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return tempProperties.getFloat(key, defaultValueIfNotFound); + } + + if (fileLoaded.second == true && + properties.second.getString(key, + defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return properties.second.getFloat(key, defaultValueIfNotFound); + } + + return properties.first.getFloat(key, defaultValueIfNotFound); + } + + const string Config::getString(const string & key, + const char *defaultValueIfNotFound) const { + if (tempProperties.getString(key, defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return tempProperties.getString(key, defaultValueIfNotFound); + } + + if (fileLoaded.second == true && + properties.second.getString(key, + defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + return properties.second.getString(key, defaultValueIfNotFound); + } + + return properties.first.getString(key, defaultValueIfNotFound); + } + + SDL_Keycode Config::translateStringToSDLKey(const string & value) const { + SDL_Keycode result = SDLK_UNKNOWN; + + if (IsNumeric(value.c_str()) == true) { + result = (SDL_Keycode) strToInt(value); + } else if (value.substr(0, 2) == "vk") { + if (value == "vkLeft") { + result = SDLK_LEFT; + } else if (value == "vkRight") { + result = SDLK_RIGHT; + } else if (value == "vkUp") { + result = SDLK_UP; + } else if (value == "vkDown") { + result = SDLK_DOWN; + } else if (value == "vkAdd") { + result = SDLK_PLUS; + } else if (value == "vkSubtract") { + result = SDLK_MINUS; + } else if (value == "vkEscape") { + result = SDLK_ESCAPE; + } else if (value == "vkF1") { + result = SDLK_F1; + } else if (value == "vkF2") { + result = SDLK_F2; + } else if (value == "vkF3") { + result = SDLK_F3; + } else if (value == "vkF4") { + result = SDLK_F4; + } else if (value == "vkF5") { + result = SDLK_F5; + } else if (value == "vkF6") { + result = SDLK_F6; + } else if (value == "vkF7") { + result = SDLK_F7; + } else if (value == "vkF8") { + result = SDLK_F8; + } else if (value == "vkF9") { + result = SDLK_F9; + } else if (value == "vkF10") { + result = SDLK_F10; + } else if (value == "vkF11") { + result = SDLK_F11; + } else if (value == "vkF12") { + result = SDLK_F12; + } else if (value == "vkPrint") { + result = SDLK_PRINTSCREEN; + } else if (value == "vkPause") { + result = SDLK_PAUSE; + } else { + string sError = "Unsupported key translation [" + value + "]"; + throw megaglest_runtime_error(sError.c_str()); + } + } else if (value.length() >= 1) { + if (value.length() == 3 && value[0] == '\'' && value[2] == '\'') { + result = (SDL_Keycode) value[1]; + } else { + bool foundKey = false; + if (value.length() > 1) { + SDL_Keycode lookup = SDL_GetKeyFromName(value.c_str()); + if (lookup != SDLK_UNKNOWN) { + result = lookup; + foundKey = true; + } + } + + if (foundKey == false) { + result = (SDL_Keycode) value[0]; + } + } + } else { + string sError = "Unsupported key translation" + value; + throw megaglest_runtime_error(sError.c_str()); + } + + // Because SDL is based on lower Ascii + //result = tolower(result); + return result; + } + + SDL_Keycode Config::getSDLKey(const char *key) const { + if (fileLoaded.second == true && + properties.second.getString(key, + defaultNotFoundValue.c_str()) != + defaultNotFoundValue) { + + string value = properties.second.getString(key); + return translateStringToSDLKey(value); + } + string value = properties.first.getString(key); + return translateStringToSDLKey(value); + } + + //char Config::getCharKey(const char *key) const { + // if(fileLoaded.second == true && + // properties.second.getString(key, defaultNotFoundValue.c_str()) != defaultNotFoundValue) { + // + // string value = properties.second.getString(key); + // return translateStringToCharKey(value); + // } + // string value = properties.first.getString(key); + // return translateStringToCharKey(value); + //} + + void Config::setInt(const string & key, int value, bool tempBuffer) { + if (tempBuffer == true) { + tempProperties.setInt(key, value); + return; + } + if (fileLoaded.second == true) { + properties.second.setInt(key, value); + return; + } + properties.first.setInt(key, value); + } + + void Config::setBool(const string & key, bool value, bool tempBuffer) { + if (tempBuffer == true) { + tempProperties.setBool(key, value); + return; + } + + if (fileLoaded.second == true) { + properties.second.setBool(key, value); + return; + } + + properties.first.setBool(key, value); + } + + void Config::setFloat(const string & key, float value, bool tempBuffer) { + if (tempBuffer == true) { + tempProperties.setFloat(key, value); + return; + } + + if (fileLoaded.second == true) { + properties.second.setFloat(key, value); + return; + } + + properties.first.setFloat(key, value); + } + + void Config::setString(const string & key, const string & value, + bool tempBuffer) { + if (tempBuffer == true) { + tempProperties.setString(key, value); + return; + } + + if (fileLoaded.second == true) { + properties.second.setString(key, value); + return; + } + + properties.first.setString(key, value); + } + + vector < pair < string, + string > + >Config:: + getPropertiesFromContainer(const Properties & propertiesObj) const { + vector < pair < string, string > >result; + + int count = propertiesObj.getPropertyCount(); + for (int i = 0; i < count; ++i) { + pair < string, string > property; + property.first = propertiesObj.getKey(i); + property.second = propertiesObj.getString(i); + result.push_back(property); + } + + return result; + } + + vector < pair < string, string > >Config::getMergedProperties()const { + vector < pair < string, string > >result = getMasterProperties(); + vector < pair < string, string > >resultUser = getUserProperties(); + for (unsigned int i = 0; i < resultUser.size(); ++i) { + const pair < string, string > &propertyUser = resultUser[i]; + bool overrideProperty = false; + for (unsigned int j = 0; j < result.size(); ++j) { + pair < string, string > &property = result[j]; + // Take the user property and override the original value + if (property.first == propertyUser.first) { + overrideProperty = true; + property.second = propertyUser.second; + break; + } + } + if (overrideProperty == false) { + result.push_back(propertyUser); + } + } + + return result; + } + + vector < pair < string, string > >Config::getMasterProperties()const { + return getPropertiesFromContainer(properties.first); + } + + vector < pair < string, string > >Config::getUserProperties() const { + return getPropertiesFromContainer(properties.second); + } + + void Config::setUserProperties(const vector < pair < string, + string > >&valueList) { + Properties & propertiesObj = properties.second; + + for (unsigned int idx = 0; idx < valueList.size(); ++idx) { + const pair < string, string > &nameValuePair = valueList[idx]; + propertiesObj.setString(nameValuePair.first, nameValuePair.second); + } + } + + string Config::getFileName(bool userFilename) const { + string result = fileName.second; + if (userFilename == false) { + result = fileName.first; + } + + return result; + } + + string Config::toString() { + return properties.first.toString(); + } + + vector < string > Config::getPathListForType(PathType type, + string scenarioDir) { + vector < string > pathList; + string data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + + string userData = getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + //if(data_path == "") { + // userData = userData; + //} + //else { + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("extractLastDirectoryFromPath(userData) [%s] from userData [%s]\n",extractLastDirectoryFromPath(userData).c_str(),userData.c_str()); + // userData = data_path + extractLastDirectoryFromPath(userData); + //} + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] userData path [%s]\n",__FILE__,__FUNCTION__,__LINE__,userData.c_str()); + + if (isdir(userData.c_str()) == false) { + createDirectoryPaths(userData); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] creating path [%s]\n", __FILE__, + __FUNCTION__, __LINE__, userData.c_str()); + } + + string userDataMaps = userData + GameConstants::folder_path_maps; + if (isdir(userDataMaps.c_str()) == false) { + createDirectoryPaths(userDataMaps); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] creating path [%s]\n", __FILE__, + __FUNCTION__, __LINE__, userDataMaps.c_str()); + } + string userDataScenarios = + userData + GameConstants::folder_path_scenarios; + if (isdir(userDataScenarios.c_str()) == false) { + createDirectoryPaths(userDataScenarios); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] creating path [%s]\n", __FILE__, + __FUNCTION__, __LINE__, userDataScenarios.c_str()); + } + string userDataTechs = userData + GameConstants::folder_path_techs; + if (isdir(userDataTechs.c_str()) == false) { + createDirectoryPaths(userDataTechs); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] creating path [%s]\n", __FILE__, + __FUNCTION__, __LINE__, userDataTechs.c_str()); + } + string userDataTilesets = + userData + GameConstants::folder_path_tilesets; + if (isdir(userDataTilesets.c_str()) == false) { + createDirectoryPaths(userDataTilesets); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] creating path [%s]\n", __FILE__, + __FUNCTION__, __LINE__, userDataTilesets.c_str()); + } + string userDataTutorials = + userData + GameConstants::folder_path_tutorials; + if (isdir(userDataTutorials.c_str()) == false) { + createDirectoryPaths(userDataTutorials); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] creating path [%s]\n", __FILE__, + __FUNCTION__, __LINE__, userDataTutorials.c_str()); + } + } + if (scenarioDir != "") { + if (EndsWith(scenarioDir, ".xml") == true) { + scenarioDir = extractDirectoryPathFromFile(scenarioDir); + } + + //string scenarioLocation = data_path + scenarioDir; + string scenarioLocation = scenarioDir; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Scenario path [%s]\n", scenarioLocation.c_str()); + pathList.push_back(scenarioLocation); + } + + switch (type) { + case ptMaps: + pathList.push_back(data_path + GameConstants::folder_path_maps); + if (userData != "") { + pathList.push_back(userData + + string(GameConstants::folder_path_maps)); + } + break; + case ptScenarios: + pathList.push_back(data_path + GameConstants::folder_path_scenarios); + if (userData != "") { + pathList.push_back(userData + + string(GameConstants::folder_path_scenarios)); + } + break; + case ptTechs: + pathList.push_back(data_path + GameConstants::folder_path_techs); + if (userData != "") { + pathList.push_back(userData + + string(GameConstants::folder_path_techs)); + } + break; + case ptTilesets: + pathList.push_back(data_path + GameConstants::folder_path_tilesets); + if (userData != "") { + pathList.push_back(userData + + string(GameConstants::folder_path_tilesets)); + } + break; + case ptTutorials: + pathList.push_back(data_path + GameConstants::folder_path_tutorials); + if (userData != "") { + pathList.push_back(userData + + string(GameConstants::folder_path_tutorials)); + } + break; + } + + return pathList; + } + + bool Config::replaceFileWithLocalFile(const vector < string > &dirList, + string fileNamePart, + string & resultToReplace) { + bool found = false; + for (unsigned int i = 0; i < dirList.size(); ++i) { + string path = dirList[i]; + endPathWithSlash(path); + string newFileName = path + fileNamePart; + if (fileExists(newFileName) == true) { + resultToReplace = newFileName; + found = true; + break; + } + } + return found; + } + + + + string Config::findValidLocalFileFromPath(string fileName) { + string result = fileName; + + if (fileName.find("maps/") != fileName.npos) { + size_t pos = fileName.find("maps/"); + string fileNamePart = fileName.substr(pos + 5); + Config & config = Config::getInstance(); + vector < string > dirList = config.getPathListForType(ptMaps); + replaceFileWithLocalFile(dirList, fileNamePart, result); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Found file [%s] @ " MG_SIZE_T_SPECIFIER + " [%s]\nNew File [%s]\n", fileName.c_str(), pos, + fileNamePart.c_str(), result.c_str()); + } else if (fileName.find("tilesets/") != fileName.npos) { + size_t pos = fileName.find("tilesets/"); + string fileNamePart = fileName.substr(pos + 9); + Config & config = Config::getInstance(); + vector < string > dirList = config.getPathListForType(ptTilesets); + replaceFileWithLocalFile(dirList, fileNamePart, result); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Found file [%s] @ " MG_SIZE_T_SPECIFIER + " [%s]\nNew File [%s]\n", fileName.c_str(), pos, + fileNamePart.c_str(), result.c_str()); + } else if (fileName.find("techs/") != fileName.npos) { + size_t pos = fileName.find("techs/"); + string fileNamePart = fileName.substr(pos + 6); + Config & config = Config::getInstance(); + vector < string > dirList = config.getPathListForType(ptTechs); + replaceFileWithLocalFile(dirList, fileNamePart, result); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Found file [%s] @ " MG_SIZE_T_SPECIFIER + " [%s]\nNew File [%s]\n", fileName.c_str(), pos, + fileNamePart.c_str(), result.c_str()); + } else if (fileName.find("scenarios/") != fileName.npos) { + size_t pos = fileName.find("scenarios/"); + string fileNamePart = fileName.substr(pos + 10); + Config & config = Config::getInstance(); + vector < string > dirList = config.getPathListForType(ptScenarios); + replaceFileWithLocalFile(dirList, fileNamePart, result); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Found file [%s] @ " MG_SIZE_T_SPECIFIER + " [%s]\nNew File [%s]\n", fileName.c_str(), pos, + fileNamePart.c_str(), result.c_str()); + } else if (fileName.find("tutorials/") != fileName.npos) { + size_t pos = fileName.find("tutorials/"); + string fileNamePart = fileName.substr(pos + 10); + Config & config = Config::getInstance(); + vector < string > dirList = config.getPathListForType(ptTutorials); + replaceFileWithLocalFile(dirList, fileNamePart, result); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Found file [%s] @ " MG_SIZE_T_SPECIFIER + " [%s]\nNew File [%s]\n", fileName.c_str(), pos, + fileNamePart.c_str(), result.c_str()); + } + + return result; + } + + + // static + string Config::getMapPath(const string & mapName, string scenarioDir, + bool errorOnNotFound) { + + Config & config = Config::getInstance(); + vector < string > pathList = + config.getPathListForType(ptMaps, scenarioDir); + + for (int idx = 0; idx < (int) pathList.size(); idx++) { + string map_path = pathList[idx]; + endPathWithSlash(map_path); + + const string mega = map_path + mapName + ".mgm"; + const string glest = map_path + mapName + ".gbm"; + if (fileExists(mega)) { + return mega; + } else if (fileExists(glest)) { + return glest; + } + } + + if (errorOnNotFound == true) { + //abort(); + throw megaglest_runtime_error("Map not found [" + mapName + + "]\nScenario [" + scenarioDir + "]"); + } + + return ""; + } + + } } // end namespace diff --git a/source/glest_game/global/config.h b/source/glest_game/global/config.h index 752d0ec44..df48c41ae 100644 --- a/source/glest_game/global/config.h +++ b/source/glest_game/global/config.h @@ -34,148 +34,143 @@ # include # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - using Shared::Util::Properties; + using Shared::Util::Properties; -// ===================================================== -// class Config -// -// Game configuration -// ===================================================== + // ===================================================== + // class Config + // + // Game configuration + // ===================================================== - enum ConfigType - { - cfgMainGame, - cfgUserGame, - cfgTempGame, - cfgMainKeys, - cfgUserKeys, - cfgTempKeys - }; + enum ConfigType { + cfgMainGame, + cfgUserGame, + cfgTempGame, + cfgMainKeys, + cfgUserKeys, + cfgTempKeys + }; - class Config - { - private: + class Config { + private: - std::pair < Properties, Properties > properties; - Properties tempProperties; - std::pair < ConfigType, ConfigType > cfgType; - std::pair < string, string > fileNameParameter; - std::pair < string, string > fileName; - std::pair < bool, bool > fileLoaded; - string custom_path_parameter; + std::pair < Properties, Properties > properties; + Properties tempProperties; + std::pair < ConfigType, ConfigType > cfgType; + std::pair < string, string > fileNameParameter; + std::pair < string, string > fileName; + std::pair < bool, bool > fileLoaded; + string custom_path_parameter; - static map < ConfigType, Config > configList; + static map < ConfigType, Config > configList; - static const char *glest_ini_filename; - static const char *glestuser_ini_filename; + static const char *glest_ini_filename; + static const char *glestuser_ini_filename; - static map < string, string > customRuntimeProperties; + static map < string, string > customRuntimeProperties; - public: + public: - static const char *glestkeys_ini_filename; - static const char *glestuserkeys_ini_filename; + static const char *glestkeys_ini_filename; + static const char *glestuserkeys_ini_filename; - static const char *ACTIVE_MOD_PROPERTY_NAME; + static const char *ACTIVE_MOD_PROPERTY_NAME; - static const char *colorPicking; - static const char *selectBufPicking; - static const char *frustumPicking; + static const char *colorPicking; + static const char *selectBufPicking; + static const char *frustumPicking; - protected: + protected: - Config (); - Config (std::pair < ConfigType, ConfigType > type, std::pair < string, - string > file, std::pair < bool, bool > fileMustExist, - string custom_path = ""); - bool tryCustomPath (std::pair < ConfigType, ConfigType > &type, - std::pair < string, string > &file, - string custom_path); - static void CopyAll (Config * src, Config * dest); - vector < pair < string, - string > - >getPropertiesFromContainer (const Properties & propertiesObj) const; - static bool replaceFileWithLocalFile (const vector < string > &dirList, - string fileNamePart, - string & resultToReplace); + Config(); + Config(std::pair < ConfigType, ConfigType > type, std::pair < string, + string > file, std::pair < bool, bool > fileMustExist, + string custom_path = ""); + bool tryCustomPath(std::pair < ConfigType, ConfigType > &type, + std::pair < string, string > &file, + string custom_path); + static void CopyAll(Config * src, Config * dest); + vector < pair < string, + string > + >getPropertiesFromContainer(const Properties & propertiesObj) const; + static bool replaceFileWithLocalFile(const vector < string > &dirList, + string fileNamePart, + string & resultToReplace); - public: + public: - static Config & getInstance (std::pair < ConfigType, ConfigType > type = - std::make_pair (cfgMainGame, cfgUserGame), - std::pair < string, string > file = - std::make_pair (glest_ini_filename, - glestuser_ini_filename), - std::pair < bool, bool > fileMustExist = - std::make_pair (true, false), - string custom_path = ""); - void save (const string & path = ""); - void reload (); + static Config & getInstance(std::pair < ConfigType, ConfigType > type = + std::make_pair(cfgMainGame, cfgUserGame), + std::pair < string, string > file = + std::make_pair(glest_ini_filename, + glestuser_ini_filename), + std::pair < bool, bool > fileMustExist = + std::make_pair(true, false), + string custom_path = ""); + void save(const string & path = ""); + void reload(); - int getInt (const string & key, const char *defaultValueIfNotFound = - NULL) const; - bool getBool (const string & key, const char *defaultValueIfNotFound = - NULL) const; - float getFloat (const string & key, const char *defaultValueIfNotFound = - NULL) const; - const string getString (const string & key, - const char *defaultValueIfNotFound = - NULL) const; + int getInt(const string & key, const char *defaultValueIfNotFound = + NULL) const; + bool getBool(const string & key, const char *defaultValueIfNotFound = + NULL) const; + float getFloat(const string & key, const char *defaultValueIfNotFound = + NULL) const; + const string getString(const string & key, + const char *defaultValueIfNotFound = + NULL) const; - int getInt (const char *key, const char *defaultValueIfNotFound = - NULL) const; - bool getBool (const char *key, const char *defaultValueIfNotFound = - NULL) const; - float getFloat (const char *key, const char *defaultValueIfNotFound = - NULL) const; - const string getString (const char *key, - const char *defaultValueIfNotFound = - NULL) const; - //char getCharKey(const char *key) const; - SDL_Keycode getSDLKey (const char *key) const; + int getInt(const char *key, const char *defaultValueIfNotFound = + NULL) const; + bool getBool(const char *key, const char *defaultValueIfNotFound = + NULL) const; + float getFloat(const char *key, const char *defaultValueIfNotFound = + NULL) const; + const string getString(const char *key, + const char *defaultValueIfNotFound = + NULL) const; + //char getCharKey(const char *key) const; + SDL_Keycode getSDLKey(const char *key) const; - void setInt (const string & key, int value, bool tempBuffer = false); - void setBool (const string & key, bool value, bool tempBuffer = false); - void setFloat (const string & key, float value, bool tempBuffer = - false); - void setString (const string & key, const string & value, - bool tempBuffer = false); + void setInt(const string & key, int value, bool tempBuffer = false); + void setBool(const string & key, bool value, bool tempBuffer = false); + void setFloat(const string & key, float value, bool tempBuffer = + false); + void setString(const string & key, const string & value, + bool tempBuffer = false); - vector < string > getPathListForType (PathType type, - string scenarioDir = ""); + vector < string > getPathListForType(PathType type, + string scenarioDir = ""); - vector < pair < string, string > >getMergedProperties () const; - vector < pair < string, string > >getMasterProperties () const; - vector < pair < string, string > >getUserProperties () const; - void setUserProperties (const vector < pair < string, - string > >&valueList); + vector < pair < string, string > >getMergedProperties() const; + vector < pair < string, string > >getMasterProperties() const; + vector < pair < string, string > >getUserProperties() const; + void setUserProperties(const vector < pair < string, + string > >&valueList); - string getFileName (bool userFilename) const; + string getFileName(bool userFilename) const; - SDL_Keycode translateStringToSDLKey (const string & value) const; + SDL_Keycode translateStringToSDLKey(const string & value) const; - string toString (); + string toString(); - static string getCustomRuntimeProperty (string key) - { - return customRuntimeProperties[key]; - } - static void setCustomRuntimeProperty (string key, string value) - { - customRuntimeProperties[key] = value; - } + static string getCustomRuntimeProperty(string key) { + return customRuntimeProperties[key]; + } + static void setCustomRuntimeProperty(string key, string value) { + customRuntimeProperties[key] = value; + } - static string findValidLocalFileFromPath (string fileName); + static string findValidLocalFileFromPath(string fileName); - static string getMapPath (const string & mapName, string scenarioDir = - "", bool errorOnNotFound = true); - }; + static string getMapPath(const string & mapName, string scenarioDir = + "", bool errorOnNotFound = true); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/global/core_data.cpp b/source/glest_game/global/core_data.cpp index 70d2a4555..cc304cef2 100644 --- a/source/glest_game/global/core_data.cpp +++ b/source/glest_game/global/core_data.cpp @@ -38,1959 +38,1772 @@ using namespace Shared::Sound; using namespace Shared::Graphics; using namespace Shared::Util; -namespace Glest -{ - namespace Game - { - -// ===================================================== -// class CoreData -// ===================================================== - - static string tempDataLocation = getUserHome (); -// ===================== PUBLIC ======================== - - static const string CORE_PATH = "data/core/"; - static const string CORE_MISC_TEXTURES_PATH = - CORE_PATH + "misc_textures/"; - - static const string CORE_MENU_PATH = CORE_PATH + "menu/"; - static const string CORE_MENU_TEXTURES_PATH = - CORE_MENU_PATH + "textures/"; - static const string CORE_MENU_SOUND_PATH = CORE_MENU_PATH + "sound/"; - static const string CORE_MENU_MUSIC_PATH = CORE_MENU_PATH + "music/"; - static const string CORE_MENU_VIDEOS_PATH = CORE_MENU_PATH + "videos/"; - - static const string CORE_WATER_SOUNDS_PATH = CORE_PATH + "/water_sounds/"; - - // Sound effects - // These variables are specified in the ini file - const string PlaySoundClip::sfxAttention = "PlaySoundAttention"; - const string PlaySoundClip::sfxHighlight = "PlaySoundHighlight"; - const string PlaySoundClip::sfxNewServer = "PlaySoundNewServer"; - const string PlaySoundClip::sfxMarker = "PlaySoundMarker"; - const string PlaySoundClip::sfxMenuClickA = "PlaySoundMenuClickA"; - const string PlaySoundClip::sfxMenuClickB = "PlaySoundMenuClickB"; - const string PlaySoundClip::sfxMenuClickC = "PlaySoundMenuClickC"; - - CoreData & CoreData::getInstance () - { - static CoreData coreData; - return coreData; - } - - CoreData::CoreData () - { - logoTexture = NULL; - logoTextureList.clear (); - backgroundTexture = NULL; - fireTexture = NULL; - teamColorTexture = NULL; - snowTexture = NULL; - waterSplashTexture = NULL; - customTexture = NULL; - buttonSmallTexture = NULL; - buttonBigTexture = NULL; - horizontalLineTexture = NULL; - verticalLineTexture = NULL; - checkBoxTexture = NULL; - checkedCheckBoxTexture = NULL; - gameWinnerTexture = NULL; - notOnServerTexture = NULL; - onServerDifferentTexture = NULL; - onServerTexture = NULL; - onServerInstalledTexture = NULL; - statusReadyTexture = NULL; - statusNotReadyTexture = NULL; - statusBRBTexture = NULL; - - healthbarTexture = NULL; - healthbarBackgroundTexture = NULL; - - miscTextureList.clear (); - - displayFont = NULL; - menuFontNormal = NULL; - displayFontSmall = NULL; - menuFontBig = NULL; - menuFontVeryBig = NULL; - consoleFont = NULL; - - displayFont3D = NULL; - menuFontNormal3D = NULL; - displayFontSmall3D = NULL; - menuFontBig3D = NULL; - menuFontVeryBig3D = NULL; - consoleFont3D = NULL; - - introVideoFilename = ""; - mainMenuVideoFilename = ""; - - battleEndWinVideoFilename = ""; - battleEndWinVideoFilenameFallback = ""; - battleEndWinMusicFilename = ""; - battleEndLoseVideoFilename = ""; - battleEndLoseVideoFilenameFallback = ""; - battleEndLoseMusicFilename = ""; - } - - CoreData::~CoreData () - { - cleanup (); - } - - void CoreData::cleanup () - { - deleteValues (waterSounds.getSoundsPtr ()->begin (), - waterSounds.getSoundsPtr ()->end ()); - waterSounds.getSoundsPtr ()->clear (); - } - - Texture2D *CoreData::getTextureBySystemId (TextureSystemType type) - { - Texture2D *result = NULL; - switch (type) - { - case tsyst_logoTexture: - result = getLogoTexture (); - break; - //std::vector logoTextureList; - case tsyst_backgroundTexture: - result = getBackgroundTexture (); - break; - case tsyst_fireTexture: - result = getFireTexture (); - break; - case tsyst_teamColorTexture: - result = getTeamColorTexture (); - break; - case tsyst_snowTexture: - result = getSnowTexture (); - break; - case tsyst_waterSplashTexture: - result = getWaterSplashTexture (); - break; - case tsyst_customTexture: - result = getCustomTexture (); - break; - case tsyst_buttonSmallTexture: - result = buttonSmallTexture; - break; - case tsyst_buttonBigTexture: - result = buttonBigTexture; - break; - case tsyst_horizontalLineTexture: - result = horizontalLineTexture; - break; - case tsyst_verticalLineTexture: - result = verticalLineTexture; - break; - case tsyst_checkBoxTexture: - result = checkBoxTexture; - break; - case tsyst_checkedCheckBoxTexture: - result = checkedCheckBoxTexture; - break; - case tsyst_gameWinnerTexture: - result = gameWinnerTexture; - break; - case tsyst_notOnServerTexture: - result = notOnServerTexture; - break; - case tsyst_onServerDifferentTexture: - result = onServerDifferentTexture; - break; - case tsyst_onServerTexture: - result = onServerTexture; - break; - case tsyst_onServerInstalledTexture: - result = onServerInstalledTexture; - break; - case tsyst_statusReadyTexture: - result = statusReadyTexture; - break; - case tsyst_statusNotReadyTexture: - result = statusNotReadyTexture; - break; - case tsyst_statusBRBTexture: - result = statusBRBTexture; - break; - case tsyst_healthbarTexture: - result = healthbarTexture; - break; - case tsyst_healthbarBackgroundTexture: - result = healthbarBackgroundTexture; - break; - - //std::vector miscTextureList; - } - return result; - } - - void CoreData::cleanupTexture (Texture2D ** texture) - { - Renderer & renderer = Renderer::getInstance (); - renderer.endTexture (rsGlobal, *texture); - *texture = NULL; - } - - void CoreData::loadTextureIfRequired (Texture2D ** tex, string data_path, - string uniqueFilePath, - int texSystemId, bool setMipMap, - bool setAlpha, - bool loadUniqueFilePath, - bool compressionDisabled) - { - if (*tex == NULL) - { - bool attemptToLoadTexture = (texSystemId == tsyst_NONE); - if (attemptToLoadTexture == false && - itemLoadAttempted.find (texSystemId) == itemLoadAttempted.end ()) - { - - attemptToLoadTexture = true; - itemLoadAttempted[texSystemId] = true; - } - - if (attemptToLoadTexture == true) - { - Renderer & renderer = Renderer::getInstance (); - *tex = renderer.newTexture2D (rsGlobal); - if (*tex) - { - - (*tex)->setForceCompressionDisabled (compressionDisabled); - (*tex)->setMipmap (setMipMap); - if (setAlpha == true) - { - - (*tex)->setFormat (Texture::fAlpha); - (*tex)->getPixmap ()->init (1); - } - - try - { - string fileToLoad = uniqueFilePath; - if (loadUniqueFilePath == false) - { - - fileToLoad = - getGameCustomCoreDataPath (data_path, uniqueFilePath); - } - (*tex)->getPixmap ()->load (fileToLoad); - (*tex)->setTextureSystemId (texSystemId); - - renderer.initTexture (rsGlobal, *tex); - } - catch (const megaglest_runtime_error & ex) - { - message (ex.what (), - GlobalStaticFlags::getIsNonGraphicalModeEnabled (), - tempDataLocation); - cleanupTexture (tex); - } - } - } - } - } - - string CoreData::getDataPath () - { - string data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - if (data_path != "") - { - endPathWithSlash (data_path); - } - return data_path; - } - - Texture2D *CoreData::getBackgroundTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&backgroundTexture, getDataPath (), - CORE_MENU_TEXTURES_PATH + "back.tga", - tsyst_backgroundTexture, false, false, false); - - return backgroundTexture; - } - Texture2D *CoreData::getFireTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&fireTexture, data_path, - CORE_MISC_TEXTURES_PATH + "fire_particle.tga", - tsyst_fireTexture, true, true, false); - - return fireTexture; - } - Texture2D *CoreData::getTeamColorTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&teamColorTexture, data_path, - CORE_MISC_TEXTURES_PATH + - "team_color_texture.tga", tsyst_teamColorTexture, - true, true, false); - - return teamColorTexture; - } - Texture2D *CoreData::getSnowTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&snowTexture, data_path, - CORE_MISC_TEXTURES_PATH + "snow_particle.tga", - tsyst_snowTexture, false, true, false); - - return snowTexture; - } - Texture2D *CoreData::getLogoTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&logoTexture, data_path, - CORE_MENU_TEXTURES_PATH + "logo.tga", - tsyst_logoTexture, false, false, false); - - return logoTexture; - } - Texture2D *CoreData::getWaterSplashTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&waterSplashTexture, data_path, - CORE_MISC_TEXTURES_PATH + "water_splash.tga", - tsyst_waterSplashTexture, true, true, false); - - return waterSplashTexture; - } - Texture2D *CoreData::getCustomTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&customTexture, data_path, - CORE_MENU_TEXTURES_PATH + "custom_texture.tga", - tsyst_customTexture, true, false, false); - - return customTexture; - } - Texture2D *CoreData::getButtonSmallTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&buttonSmallTexture, data_path, - CORE_MENU_TEXTURES_PATH + "button_small.tga", - tsyst_buttonSmallTexture, true, false, false, - true); - - return buttonSmallTexture; - } - Texture2D *CoreData::getButtonBigTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&buttonBigTexture, data_path, - CORE_MENU_TEXTURES_PATH + "button_big.tga", - tsyst_buttonBigTexture, true, false, false, - true); - - return buttonBigTexture; - } - Texture2D *CoreData::getHorizontalLineTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&horizontalLineTexture, data_path, - CORE_MENU_TEXTURES_PATH + "line_horizontal.tga", - tsyst_horizontalLineTexture, true, false, false, - true); - - return horizontalLineTexture; - } - Texture2D *CoreData::getVerticalLineTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&verticalLineTexture, data_path, - CORE_MENU_TEXTURES_PATH + "line_vertical.tga", - tsyst_verticalLineTexture, true, false, false, - true); - - return verticalLineTexture; - } - Texture2D *CoreData::getCheckBoxTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&checkBoxTexture, data_path, - CORE_MENU_TEXTURES_PATH + "checkbox.tga", - tsyst_checkBoxTexture, true, false, false, true); - - return checkBoxTexture; - } - Texture2D *CoreData::getCheckedCheckBoxTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&checkedCheckBoxTexture, data_path, - CORE_MENU_TEXTURES_PATH + "checkbox_checked.tga", - tsyst_checkedCheckBoxTexture, true, false, false, - true); - - return checkedCheckBoxTexture; - } - Texture2D *CoreData::getNotOnServerTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (¬OnServerTexture, data_path, - CORE_MENU_TEXTURES_PATH + "not_on_server.tga", - tsyst_notOnServerTexture, true, false, false); - - return notOnServerTexture; - } - Texture2D *CoreData::getOnServerDifferentTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&onServerDifferentTexture, data_path, - CORE_MENU_TEXTURES_PATH + - "on_server_different.tga", - tsyst_onServerDifferentTexture, true, false, - false); - - return onServerDifferentTexture; - } - Texture2D *CoreData::getOnServerTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&onServerTexture, data_path, - CORE_MENU_TEXTURES_PATH + "on_server.tga", - tsyst_onServerTexture, true, false, false); - - return onServerTexture; - } - Texture2D *CoreData::getOnServerInstalledTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&onServerInstalledTexture, data_path, - CORE_MENU_TEXTURES_PATH + - "on_server_installed.tga", - tsyst_onServerInstalledTexture, true, false, - false); - - return onServerInstalledTexture; - } - Texture2D *CoreData::getStatusReadyTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&statusReadyTexture, data_path, - CORE_MENU_TEXTURES_PATH + "status_ready.png", - tsyst_statusReadyTexture, true, false, false); - - return statusReadyTexture; - } - Texture2D *CoreData::getStatusNotReadyTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&statusNotReadyTexture, data_path, - CORE_MENU_TEXTURES_PATH + "status_notready.png", - tsyst_statusNotReadyTexture, true, false, false); - - return statusNotReadyTexture; - } - Texture2D *CoreData::getStatusBRBTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&statusBRBTexture, data_path, - CORE_MENU_TEXTURES_PATH + "status_brb.png", - tsyst_statusBRBTexture, true, false, false); - - return statusBRBTexture; - } - Texture2D *CoreData::getGameWinnerTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&gameWinnerTexture, data_path, - CORE_MISC_TEXTURES_PATH + "game_winner.png", - tsyst_gameWinnerTexture, true, false, false, - true); - - return gameWinnerTexture; - } - - Texture2D *CoreData::getHealthbarTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&healthbarTexture, data_path, - CORE_MISC_TEXTURES_PATH + "healthbar.png", - tsyst_healthbarTexture, true, false, false, - true); - - return healthbarTexture; - } - - Texture2D *CoreData::getHealthbarBackgroundTexture () - { - string data_path = getDataPath (); - loadTextureIfRequired (&healthbarBackgroundTexture, data_path, - CORE_MISC_TEXTURES_PATH + - "healthbarBackground.png", - tsyst_healthbarBackgroundTexture, true, false, - false, true); - - return healthbarBackgroundTexture; - } - - void CoreData::loadLogoTextureExtraIfRequired () - { - int loadAttemptLookupKey = tsyst_COUNT + 1; - if (itemLoadAttempted.find (loadAttemptLookupKey) == - itemLoadAttempted.end ()) - { - - itemLoadAttempted[loadAttemptLookupKey] = true; - - string data_path = getDataPath (); - logoTextureList.clear (); - string logosPath = getGameCustomCoreDataPath (data_path, "") - + CORE_MENU_TEXTURES_PATH + "logo*.*"; - vector < string > logoFilenames; - findAll (logosPath, logoFilenames, false, false); - for (int index = 0; index < (int) logoFilenames.size (); ++index) - { - - string logo = logoFilenames[index]; - if (strcmp ("logo.tga", logo.c_str ()) != 0) - { - - Texture2D *logoTextureExtra = NULL; - loadTextureIfRequired (&logoTextureExtra, data_path, - getGameCustomCoreDataPath (data_path, "") + - CORE_MENU_TEXTURES_PATH + logo, tsyst_NONE, - true, false, true); - logoTextureList.push_back (logoTextureExtra); - } - } - if (logoTextureList.empty () == true) - { - - logosPath = data_path + CORE_MENU_TEXTURES_PATH + "logo*.*"; - vector < string > logoFilenames; - findAll (logosPath, logoFilenames, false, false); - for (int index = 0; index < (int) logoFilenames.size (); ++index) - { - - string logo = logoFilenames[index]; - if (strcmp ("logo.tga", logo.c_str ()) != 0) - { - - Texture2D *logoTextureExtra = NULL; - loadTextureIfRequired (&logoTextureExtra, data_path, - data_path + CORE_MENU_TEXTURES_PATH + - logo, tsyst_NONE, true, false, true); - logoTextureList.push_back (logoTextureExtra); - } - } - } - } - } - size_t CoreData::getLogoTextureExtraCount () - { - loadLogoTextureExtraIfRequired (); - return logoTextureList.size (); - } - Texture2D *CoreData::getLogoTextureExtra (int idx) - { - loadLogoTextureExtraIfRequired (); - return logoTextureList[idx]; - } - - void CoreData::loadMiscTextureListIfRequired () - { - int loadAttemptLookupKey = tsyst_COUNT + 2; - if (itemLoadAttempted.find (loadAttemptLookupKey) == - itemLoadAttempted.end ()) - { - - itemLoadAttempted[loadAttemptLookupKey] = true; - - string data_path = getDataPath (); - - miscTextureList.clear (); - string introPath = getGameCustomCoreDataPath (data_path, "") - + CORE_MENU_TEXTURES_PATH + "intro*.*"; - vector < string > introFilenames; - findAll (introPath, introFilenames, false, false); - for (int i = 0; i < (int) introFilenames.size (); ++i) - { - string logo = introFilenames[i]; - - Texture2D *logoTextureExtra = NULL; - loadTextureIfRequired (&logoTextureExtra, data_path, - getGameCustomCoreDataPath (data_path, - "") + - CORE_MENU_TEXTURES_PATH + logo, tsyst_NONE, - true, false, true); - miscTextureList.push_back (logoTextureExtra); - } - if (miscTextureList.empty () == true) - { - introPath = data_path + CORE_MENU_TEXTURES_PATH + "intro*.*"; - vector < string > introFilenames; - findAll (introPath, introFilenames, false, false); - for (int i = 0; i < (int) introFilenames.size (); ++i) - { - string logo = introFilenames[i]; - - Texture2D *logoTextureExtra = NULL; - loadTextureIfRequired (&logoTextureExtra, data_path, - data_path + CORE_MENU_TEXTURES_PATH + logo, - tsyst_NONE, true, false, true); - miscTextureList.push_back (logoTextureExtra); - } - } - - } - } - - std::vector < Texture2D * >&CoreData::getMiscTextureList () - { - loadMiscTextureListIfRequired (); - return miscTextureList; - } - - void CoreData::loadTextures (string data_path) - { - // Required to be loaded at program startup as they may be accessed in - // threads or some other dangerous way so lazy loading is not an option - getCustomTexture (); - } - - StaticSound *CoreData::getClickSoundA () - { - static PlaySoundClip snd; - return snd.getSound (snd.sfxMenuClickA); - } - - StaticSound *CoreData::getClickSoundB () - { - static PlaySoundClip snd; - return snd.getSound (snd.sfxMenuClickB); - - } - StaticSound *CoreData::getClickSoundC () - { - static PlaySoundClip snd; - return snd.getSound (snd.sfxMenuClickC); - } - - void CoreData::loadWaterSoundsIfRequired () - { - int loadAttemptLookupKey = tsyst_COUNT + 9; - if (itemLoadAttempted.find (loadAttemptLookupKey) == - itemLoadAttempted.end ()) - { - - itemLoadAttempted[loadAttemptLookupKey] = true; - - string data_path = getDataPath (); - cleanup (); - waterSounds.resize (6); - - for (int index = 0; index < 6; ++index) - { - waterSounds[index] = new StaticSound (); - if (waterSounds[index] != NULL) - { - try - { - waterSounds[index]->load (getGameCustomCoreDataPath (data_path, - CORE_WATER_SOUNDS_PATH - + "water" + - intToStr - (index) + - ".wav")); - } - catch (const megaglest_runtime_error & ex) - { - message (ex.what (), - GlobalStaticFlags::getIsNonGraphicalModeEnabled (), - tempDataLocation); - } - } - } - } - } - - StaticSound *CoreData::getWaterSound () - { - loadWaterSoundsIfRequired (); - return waterSounds.getRandSound (); - } - - void CoreData::loadSounds (string data_path) - { - // sounds -// try { -// clickSoundA.load( -// getGameCustomCoreDataPath(data_path, -// CORE_MENU_SOUND_PATH + "click_a.wav")); -// clickSoundB.load( -// getGameCustomCoreDataPath(data_path, -// CORE_MENU_SOUND_PATH + "click_b.wav")); -// clickSoundC.load( -// getGameCustomCoreDataPath(data_path, -// CORE_MENU_SOUND_PATH + "click_c.wav")); -// attentionSound.load( -// getGameCustomCoreDataPath(data_path, -// CORE_MENU_SOUND_PATH + "attention.wav")); -// highlightSound.load( -// getGameCustomCoreDataPath(data_path, -// CORE_MENU_SOUND_PATH + "highlight.wav")); -// markerSound.load( -// getGameCustomCoreDataPath(data_path, -// CORE_MENU_SOUND_PATH + "sonar.wav")); -// } -// catch (const megaglest_runtime_error& ex) { -// message(ex.what(), GlobalStaticFlags::getIsNonGraphicalModeEnabled(), -// tempDataLocation); -// } - -// cleanup(); -// waterSounds.resize(6); -// -// for (int i = 0; i < 6; ++i) { -// waterSounds[i] = new StaticSound(); -// if (waterSounds[i]) { -// try { -// waterSounds[i]->load( -// getGameCustomCoreDataPath(data_path, -// CORE_WATER_SOUNDS_PATH + "water" + intToStr(i) -// + ".wav")); -// } catch (const megaglest_runtime_error& ex) { -// message(ex.what(), -// GlobalStaticFlags::getIsNonGraphicalModeEnabled(), -// tempDataLocation); -// } -// } -// } - } - - - void CoreData::loadMusicIfRequired () - { - int loadAttemptLookupKey = tsyst_COUNT + 10; - if (itemLoadAttempted.find (loadAttemptLookupKey) == - itemLoadAttempted.end ()) - { - - itemLoadAttempted[loadAttemptLookupKey] = true; - - string data_path = getDataPath (); - - XmlTree xmlTree; - xmlTree. - load (getGameCustomCoreDataPath - (data_path, CORE_MENU_PATH + "menu.xml"), - Properties::getTagReplacementValues ()); - const XmlNode *menuNode = xmlTree.getRootNode (); - string menuMusicPath = "/menu/music/"; - string menuIntroMusicFile = "intro_music.ogg"; - string menuMusicFile = "menu_music.ogg"; - if (menuNode->hasChild ("intro") == true) - { - const XmlNode *introNode = menuNode->getChild ("intro"); - // intro info - const XmlNode *menuPathNode = - introNode->getChild ("menu-music-path"); - menuMusicPath = - menuPathNode->getAttribute ("value")->getRestrictedValue (); - const XmlNode *menuIntroMusicNode = - introNode->getChild ("menu-intro-music"); - menuIntroMusicFile = - menuIntroMusicNode->getAttribute ("value")->getRestrictedValue (); - const XmlNode *menuMusicNode = introNode->getChild ("menu-music"); - menuMusicFile = - menuMusicNode->getAttribute ("value")->getRestrictedValue (); - } - try - { - introMusic.open (getGameCustomCoreDataPath (data_path, - CORE_PATH + - menuMusicPath + - menuIntroMusicFile)); - introMusic.setNext (&menuMusic); - menuMusic.open (getGameCustomCoreDataPath (data_path, - CORE_PATH + - menuMusicPath + - menuMusicFile)); - menuMusic.setNext (&menuMusic); - } - catch (const megaglest_runtime_error & ex) - { - message (ex.what (), - GlobalStaticFlags::getIsNonGraphicalModeEnabled (), - tempDataLocation); - } - } - } - - StrSound *CoreData::getIntroMusic () - { - loadMusicIfRequired (); - return &introMusic; - } - - StrSound *CoreData::getMenuMusic () - { - loadMusicIfRequired (); - return &menuMusic; - } - - void CoreData::loadMusic (string data_path) - { - } - - void CoreData::loadIntroMedia (string data_path) - { - Config & config = Config::getInstance (); - - introVideoFilename = config.getString ("IntroVideoURL", ""); - introVideoFilenameFallback = - config.getString ("IntroVideoURLFallback", ""); - if (introVideoFilename == "") - { - string introVideoPath = getGameCustomCoreDataPath (data_path, "") - + CORE_MENU_VIDEOS_PATH + "intro.*"; - vector < string > introVideos; - findAll (introVideoPath, introVideos, false, false); - for (int i = 0; i < (int) introVideos.size (); ++i) - { - string video = getGameCustomCoreDataPath (data_path, "") - + CORE_MENU_VIDEOS_PATH + introVideos[i]; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Checking if intro video [%s] exists\n", video.c_str ()); - - if (fileExists (video)) - { - introVideoFilename = video; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("FOUND intro video [%s] will use this file\n", - video.c_str ()); - - break; - } - } - if (introVideoFilename == "") - { - introVideoPath = data_path + CORE_MENU_VIDEOS_PATH + "intro.*"; - introVideos.clear (); - findAll (introVideoPath, introVideos, false, false); - for (int i = 0; i < (int) introVideos.size (); ++i) - { - string video = data_path + CORE_MENU_VIDEOS_PATH + introVideos[i]; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Checking if intro video [%s] exists\n", - video.c_str ()); - - if (fileExists (video)) - { - introVideoFilename = video; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("FOUND intro video [%s] will use this file\n", - video.c_str ()); - - break; - } - } - } - } - } - - void CoreData::loadMainMenuMedia (string data_path) - { - Config & config = Config::getInstance (); - - mainMenuVideoFilename = config.getString ("MainMenuVideoURL", ""); - mainMenuVideoFilenameFallback = - config.getString ("MainMenuVideoURLFallback", ""); - if (mainMenuVideoFilename == "") - { - string mainVideoPath = getGameCustomCoreDataPath (data_path, "") - + CORE_MENU_VIDEOS_PATH + "main.*"; - vector < string > mainVideos; - findAll (mainVideoPath, mainVideos, false, false); - for (int i = 0; i < (int) mainVideos.size (); ++i) - { - string video = getGameCustomCoreDataPath (data_path, "") - + CORE_MENU_VIDEOS_PATH + mainVideos[i]; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Checking if mainmenu video [%s] exists\n", - video.c_str ()); - - if (fileExists (video)) - { - mainMenuVideoFilename = video; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("FOUND mainmenu video [%s] will use this file\n", - video.c_str ()); - - break; - } - } - if (mainMenuVideoFilename == "") - { - mainVideoPath = data_path + CORE_MENU_VIDEOS_PATH + "main.*"; - mainVideos.clear (); - findAll (mainVideoPath, mainVideos, false, false); - for (int i = 0; i < (int) mainVideos.size (); ++i) - { - string video = data_path + CORE_MENU_VIDEOS_PATH + mainVideos[i]; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Checking if mainmenu video [%s] exists\n", - video.c_str ()); - - if (fileExists (video)) - { - mainMenuVideoFilename = video; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("FOUND mainmenu video [%s] will use this file\n", - video.c_str ()); - - break; - } - } - } - } - } - - void CoreData::loadBattleEndMedia (string data_path) - { - Config & config = Config::getInstance (); - - battleEndWinVideoFilename = - config.getString ("BattleEndWinVideoURL", ""); - battleEndWinVideoFilenameFallback = - config.getString ("BattleEndWinVideoURLFallback", ""); - if (battleEndWinVideoFilename == "") - { - string battleEndWinVideoPath = - getGameCustomCoreDataPath (data_path, - "") + CORE_MENU_VIDEOS_PATH + - "battle_end_win.*"; - vector < string > battleEndWinVideos; - findAll (battleEndWinVideoPath, battleEndWinVideos, false, false); - for (int i = 0; i < (int) battleEndWinVideos.size (); ++i) - { - string video = getGameCustomCoreDataPath (data_path, "") - + CORE_MENU_VIDEOS_PATH + battleEndWinVideos[i]; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Checking if battle end win video [%s] exists\n", - video.c_str ()); - - if (fileExists (video)) - { - battleEndWinVideoFilename = video; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("FOUND battle end win video [%s] will use this file\n", - video.c_str ()); - - break; - } - } - if (battleEndWinVideoFilename == "") - { - battleEndWinVideoPath = data_path + CORE_MENU_VIDEOS_PATH - + "battle_end_win.*"; - battleEndWinVideos.clear (); - findAll (battleEndWinVideoPath, battleEndWinVideos, false, false); - for (int i = 0; i < (int) battleEndWinVideos.size (); ++i) - { - string video = data_path + CORE_MENU_VIDEOS_PATH - + battleEndWinVideos[i]; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Checking if battle end win video [%s] exists\n", - video.c_str ()); - - if (fileExists (video)) - { - battleEndWinVideoFilename = video; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("FOUND battle end video win [%s] will use this file\n", - video.c_str ()); - - break; - } - } - } - } - battleEndWinMusicFilename = - config.getString ("BattleEndWinMusicFilename", ""); - if (battleEndWinMusicFilename == "") - { - string battleEndWinPath = getGameCustomCoreDataPath (data_path, "") - + CORE_MENU_MUSIC_PATH + "battle_end_win.*"; - vector < string > battleEndWinMusic; - findAll (battleEndWinPath, battleEndWinMusic, false, false); - for (int i = 0; i < (int) battleEndWinMusic.size (); ++i) - { - string music = getGameCustomCoreDataPath (data_path, "") - + CORE_MENU_MUSIC_PATH + battleEndWinMusic[i]; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Checking if battle end win music [%s] exists\n", - music.c_str ()); - - if (fileExists (music)) - { - battleEndWinMusicFilename = music; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("FOUND battle end win music [%s] will use this file\n", - music.c_str ()); - - break; - } - } - if (battleEndWinMusicFilename == "") - { - battleEndWinPath = data_path + CORE_MENU_MUSIC_PATH - + "battle_end_win.*"; - battleEndWinMusic.clear (); - findAll (battleEndWinPath, battleEndWinMusic, false, false); - for (int i = 0; i < (int) battleEndWinMusic.size (); ++i) - { - string music = data_path + CORE_MENU_MUSIC_PATH - + battleEndWinMusic[i]; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Checking if battle end win music [%s] exists\n", - music.c_str ()); - - if (fileExists (music)) - { - battleEndWinMusicFilename = music; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("FOUND battle end music win [%s] will use this file\n", - music.c_str ()); - - break; - } - } - } - } - battleEndLoseVideoFilename = - config.getString ("BattleEndLoseVideoURL", ""); - battleEndLoseVideoFilenameFallback = - config.getString ("BattleEndLoseVideoURLFallback", ""); - if (battleEndLoseVideoFilename == "") - { - string battleEndLoseVideoPath = - getGameCustomCoreDataPath (data_path, - "") + CORE_MENU_VIDEOS_PATH + - "battle_end_lose.*"; - vector < string > battleEndLoseVideos; - findAll (battleEndLoseVideoPath, battleEndLoseVideos, false, false); - for (int i = 0; i < (int) battleEndLoseVideos.size (); ++i) - { - string video = getGameCustomCoreDataPath (data_path, "") - + CORE_MENU_VIDEOS_PATH + battleEndLoseVideos[i]; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Checking if battle end lose video [%s] exists\n", - video.c_str ()); - - if (fileExists (video)) - { - battleEndLoseVideoFilename = video; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("FOUND battle end lose video [%s] will use this file\n", - video.c_str ()); - - break; - } - } - if (battleEndLoseVideoFilename == "") - { - battleEndLoseVideoPath = data_path + CORE_MENU_VIDEOS_PATH - + "battle_end_lose.*"; - battleEndLoseVideos.clear (); - findAll (battleEndLoseVideoPath, battleEndLoseVideos, false, false); - for (int i = 0; i < (int) battleEndLoseVideos.size (); ++i) - { - string video = data_path + CORE_MENU_VIDEOS_PATH - + battleEndLoseVideos[i]; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Checking if battle end lose video [%s] exists\n", - video.c_str ()); - - if (fileExists (video)) - { - battleEndLoseVideoFilename = video; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("FOUND battle end video lose [%s] will use this file\n", - video.c_str ()); - - break; - } - } - } - } - battleEndLoseMusicFilename = - config.getString ("BattleEndLoseMusicFilename", ""); - if (battleEndLoseMusicFilename == "") - { - string battleEndLosePath = getGameCustomCoreDataPath (data_path, "") - + CORE_MENU_MUSIC_PATH + "battle_end_lose.*"; - vector < string > battleEndLoseMusic; - findAll (battleEndLosePath, battleEndLoseMusic, false, false); - for (int i = 0; i < (int) battleEndLoseMusic.size (); ++i) - { - string music = getGameCustomCoreDataPath (data_path, "") - + CORE_MENU_MUSIC_PATH + battleEndLoseMusic[i]; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Checking if battle end lose music [%s] exists\n", - music.c_str ()); - - if (fileExists (music)) - { - battleEndLoseMusicFilename = music; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("FOUND battle end lose music [%s] will use this file\n", - music.c_str ()); - - break; - } - } - if (battleEndLoseMusicFilename == "") - { - battleEndLosePath = data_path + CORE_MENU_MUSIC_PATH - + "battle_end_lose.*"; - battleEndLoseMusic.clear (); - findAll (battleEndLosePath, battleEndLoseMusic, false, false); - for (int i = 0; i < (int) battleEndLoseMusic.size (); ++i) - { - string music = data_path + CORE_MENU_MUSIC_PATH - + battleEndLoseMusic[i]; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Checking if battle end lose music [%s] exists\n", - music.c_str ()); - - if (fileExists (music)) - { - battleEndLoseMusicFilename = music; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("FOUND battle end music lose [%s] will use this file\n", - music.c_str ()); - - break; - } - } - } - } - } - - void CoreData::load () - { - string data_path = CoreData::getDataPath (); - - Logger::getInstance ().add (Lang::getInstance (). - getString ("LogScreenCoreDataLoading", "", - true)); - - // textures - loadTextures (data_path); - - // fonts - loadFonts (); - - // sounds - loadSounds (data_path); - - // music - loadMusic (data_path); - - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false && - Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer () == true) - { - - loadIntroMedia (data_path); - - loadMainMenuMedia (data_path); - - loadBattleEndMedia (data_path); - } - } - - bool CoreData::hasIntroVideoFilename () const - { - bool result = (introVideoFilename != ""); - return result; - } - - bool CoreData::hasMainMenuVideoFilename () const - { - bool result = (mainMenuVideoFilename != ""); - return result; - } - -//bool CoreData::hasBattleEndVideoFilename(bool won) const { -// bool result = false; -// if(won == true) { -// result =(battleEndWinVideoFilename != ""); -// } -// else { -// result =(battleEndLoseVideoFilename != ""); -// } -// return result; -//} - - void CoreData::registerFontChangedCallback (std::string entityName, - FontChangedCallbackInterface * - cb) - { - if (entityName == "") - { - printf ("Register Font Callback detected a blank entityName!\n"); - throw - megaglest_runtime_error - ("Register Font Callback detected a blank entityName!"); - } - if (entityName != "") - { - registeredFontChangedCallbacks[entityName].push_back (cb); - } - } - void CoreData::unRegisterFontChangedCallback (std::string entityName) - { - if (entityName == "") - { - printf ("UnRegister Font Callback detected a blank entityName!\n"); - throw - megaglest_runtime_error - ("UnRegister Font Callback detected a blank entityName!"); - } - if (entityName != "") - { - registeredFontChangedCallbacks.erase (entityName); - } - } - void CoreData::triggerFontChangedCallbacks (std::string fontUniqueId, - Font * font) - { - for (std::map < std::string, - std::vector < - FontChangedCallbackInterface * > >::const_iterator iterMap = - registeredFontChangedCallbacks.begin (); - iterMap != registeredFontChangedCallbacks.end (); ++iterMap) - { - for (unsigned int index = 0; index < iterMap->second.size (); ++index) - { - //printf("Font Callback detected calling: Control [%s] for Font: [%s] value [%p]\n",iterMap->first.c_str(),fontUniqueId.c_str(),font); - FontChangedCallbackInterface *cb = iterMap->second[index]; - cb->FontChangedCallback (fontUniqueId, font); - } - } - } - void CoreData::loadFonts () - { - Lang & lang = Lang::getInstance (); - - //display font - Config & config = Config::getInstance (); - - string displayFontNamePrefix = config.getString ("FontDisplayPrefix"); - string displayFontNamePostfix = config.getString ("FontDisplayPostfix"); - int displayFontSize = - computeFontSize (config.getInt ("FontDisplayBaseSize")); - - if (lang.hasString ("FontDisplayPrefix") == true) - { - displayFontNamePrefix = lang.getString ("FontDisplayPrefix"); - } - if (lang.hasString ("FontDisplayPostfix") == true) - { - displayFontNamePostfix = lang.getString ("FontDisplayPostfix"); - } - if (lang.hasString ("FontDisplayBaseSize") == true) - { - displayFontSize = - computeFontSize (strToInt (lang.getString ("FontDisplayBaseSize"))); - } - string displayFontName = - displayFontNamePrefix + intToStr (displayFontSize) + - displayFontNamePostfix; - - displayFont = - loadFont < Font2D > (displayFont, displayFontName, displayFontSize, - "FontDisplay", "FontDisplayFamily", - "displayFont"); - displayFont3D = - loadFont < Font3D > (displayFont3D, displayFontName, displayFontSize, - "FontDisplay", "FontDisplayFamily", - "displayFont3D"); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] displayFontName = [%s] displayFontSize = %d\n", - __FILE__, __FUNCTION__, __LINE__, - displayFontName.c_str (), displayFontSize); - - //menu fonts - string displayFontNameSmallPrefix = - config.getString ("FontDisplayPrefix"); - string displayFontNameSmallPostfix = - config.getString ("FontDisplayPostfix"); - int displayFontNameSmallSize = - computeFontSize (config.getInt ("FontDisplaySmallBaseSize")); - - if (lang.hasString ("FontDisplayPrefix") == true) - { - displayFontNameSmallPrefix = lang.getString ("FontDisplayPrefix"); - } - if (lang.hasString ("FontDisplayPostfix") == true) - { - displayFontNameSmallPostfix = lang.getString ("FontDisplayPostfix"); - } - if (lang.hasString ("FontDisplaySmallBaseSize") == true) - { - displayFontNameSmallSize = - computeFontSize (strToInt - (lang.getString ("FontDisplaySmallBaseSize"))); - } - string displayFontNameSmall = - displayFontNameSmallPrefix + intToStr (displayFontNameSmallSize) + - displayFontNameSmallPostfix; - - displayFontSmall = - loadFont < Font2D > (displayFontSmall, displayFontNameSmall, - displayFontNameSmallSize, "FontSmallDisplay", - "FontSmallDisplayFamily", "displayFontSmall"); - displayFontSmall3D = - loadFont < Font3D > (displayFontSmall3D, displayFontNameSmall, - displayFontNameSmallSize, "FontSmallDisplay", - "FontSmallDisplayFamily", "displayFontSmall3D"); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] displayFontSmallName = [%s] displayFontSmallNameSize = %d\n", - __FILE__, __FUNCTION__, __LINE__, - displayFontNameSmall.c_str (), - displayFontNameSmallSize); - - string menuFontNameNormalPrefix = - config.getString ("FontMenuNormalPrefix"); - string menuFontNameNormalPostfix = - config.getString ("FontMenuNormalPostfix"); - int menuFontNameNormalSize = - computeFontSize (config.getInt ("FontMenuNormalBaseSize")); - if (lang.hasString ("FontMenuNormalPrefix") == true) - { - menuFontNameNormalPrefix = lang.getString ("FontMenuNormalPrefix"); - } - if (lang.hasString ("FontMenuNormalPostfix") == true) - { - menuFontNameNormalPostfix = lang.getString ("FontMenuNormalPostfix"); - } - if (lang.hasString ("FontMenuNormalBaseSize") == true) - { - menuFontNameNormalSize = - computeFontSize (strToInt - (lang.getString ("FontMenuNormalBaseSize"))); - } - string menuFontNameNormal = - menuFontNameNormalPrefix + intToStr (menuFontNameNormalSize) + - menuFontNameNormalPostfix; - - menuFontNormal = - loadFont < Font2D > (menuFontNormal, menuFontNameNormal, - menuFontNameNormalSize, "FontMenuNormal", - "FontMenuNormalFamily", "menuFontNormal"); - menuFontNormal3D = - loadFont < Font3D > (menuFontNormal3D, menuFontNameNormal, - menuFontNameNormalSize, "FontMenuNormal", - "FontMenuNormalFamily", "menuFontNormal3D"); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] menuFontNormalName = [%s] menuFontNormalNameSize = %d\n", - __FILE__, __FUNCTION__, __LINE__, - menuFontNameNormal.c_str (), - menuFontNameNormalSize); - - string menuFontNameBigPrefix = config.getString ("FontMenuBigPrefix"); - string menuFontNameBigPostfix = config.getString ("FontMenuBigPostfix"); - int menuFontNameBigSize = - computeFontSize (config.getInt ("FontMenuBigBaseSize")); - - if (lang.hasString ("FontMenuBigPrefix") == true) - { - menuFontNameBigPrefix = lang.getString ("FontMenuBigPrefix"); - } - if (lang.hasString ("FontMenuBigPostfix") == true) - { - menuFontNameBigPostfix = lang.getString ("FontMenuBigPostfix"); - } - if (lang.hasString ("FontMenuBigBaseSize") == true) - { - menuFontNameBigSize = - computeFontSize (strToInt (lang.getString ("FontMenuBigBaseSize"))); - } - string menuFontNameBig = - menuFontNameBigPrefix + intToStr (menuFontNameBigSize) + - menuFontNameBigPostfix; - - menuFontBig = - loadFont < Font2D > (menuFontBig, menuFontNameBig, - menuFontNameBigSize, "FontMenuBig", - "FontMenuBigFamily", "menuFontBig"); - menuFontBig3D = - loadFont < Font3D > (menuFontBig3D, menuFontNameBig, - menuFontNameBigSize, "FontMenuBig", - "FontMenuBigFamily", "menuFontBig3D"); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] menuFontNameBig = [%s] menuFontNameBigSize = %d\n", - __FILE__, __FUNCTION__, __LINE__, - menuFontNameBig.c_str (), - menuFontNameBigSize); - - string menuFontNameVeryBigPrefix = - config.getString ("FontMenuBigPrefix"); - string menuFontNameVeryBigPostfix = - config.getString ("FontMenuBigPostfix"); - int menuFontNameVeryBigSize = - computeFontSize (config.getInt ("FontMenuVeryBigBaseSize")); - - if (lang.hasString ("FontMenuBigPrefix") == true) - { - menuFontNameVeryBigPrefix = lang.getString ("FontMenuBigPrefix"); - } - if (lang.hasString ("FontMenuBigPostfix") == true) - { - menuFontNameVeryBigPostfix = lang.getString ("FontMenuBigPostfix"); - } - if (lang.hasString ("FontMenuVeryBigBaseSize") == true) - { - menuFontNameVeryBigSize = - computeFontSize (strToInt - (lang.getString ("FontMenuVeryBigBaseSize"))); - } - string menuFontNameVeryBig = - menuFontNameVeryBigPrefix + intToStr (menuFontNameVeryBigSize) + - menuFontNameVeryBigPostfix; - - menuFontVeryBig = - loadFont < Font2D > (menuFontVeryBig, menuFontNameVeryBig, - menuFontNameVeryBigSize, "FontMenuVeryBig", - "FontMenuVeryBigFamily", "menuFontVeryBig"); - menuFontVeryBig3D = - loadFont < Font3D > (menuFontVeryBig3D, menuFontNameVeryBig, - menuFontNameVeryBigSize, "FontMenuVeryBig", - "FontMenuVeryBigFamily", "menuFontVeryBig3D"); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] menuFontNameVeryBig = [%s] menuFontNameVeryBigSize = %d\n", - __FILE__, __FUNCTION__, __LINE__, - menuFontNameVeryBig.c_str (), - menuFontNameVeryBigSize); - - //console font - string consoleFontNamePrefix = config.getString ("FontConsolePrefix"); - string consoleFontNamePostfix = config.getString ("FontConsolePostfix"); - int consoleFontNameSize = - computeFontSize (config.getInt ("FontConsoleBaseSize")); - - if (lang.hasString ("FontConsolePrefix") == true) - { - consoleFontNamePrefix = lang.getString ("FontConsolePrefix"); - } - if (lang.hasString ("FontConsolePostfix") == true) - { - consoleFontNamePostfix = lang.getString ("FontConsolePostfix"); - } - if (lang.hasString ("FontConsoleBaseSize") == true) - { - consoleFontNameSize = - computeFontSize (strToInt (lang.getString ("FontConsoleBaseSize"))); - } - string consoleFontName = - consoleFontNamePrefix + intToStr (consoleFontNameSize) + - consoleFontNamePostfix; - - consoleFont = - loadFont < Font2D > (consoleFont, consoleFontName, - consoleFontNameSize, "FontConsole", - "FontConsoleFamily", "consoleFont"); - consoleFont3D = - loadFont < Font3D > (consoleFont3D, consoleFontName, - consoleFontNameSize, "FontConsole", - "FontConsoleFamily", "consoleFont3D"); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] consoleFontName = [%s] consoleFontNameSize = %d\n", - __FILE__, __FUNCTION__, __LINE__, - consoleFontName.c_str (), - consoleFontNameSize); - } - - - template < typename T > T * CoreData::loadFont (Font * menuFont, - string menuFontName, - int menuFontNameSize, - string fontType, - string fontTypeFamily, - string fontUniqueKey) - { - Renderer & renderer = Renderer::getInstance (); - if (menuFont) - { - string fontUniqueId = menuFont->getFontUniqueId (); - renderer.endFont (menuFont, rsGlobal); - menuFont = NULL; - triggerFontChangedCallbacks (fontUniqueId, menuFont); - } - if (Renderer::renderText3DEnabled == false) - { - menuFont = renderer.newFont (rsGlobal); - } - else - { - menuFont = renderer.newFont3D (rsGlobal); - } - if (menuFont) - { - Config & config = Config::getInstance (); - menuFont->setType (menuFontName, config.getString (fontType, ""), - config.getString (fontTypeFamily, "")); - menuFont->setSize (menuFontNameSize); - menuFont->setWidth (Font::wBold); - menuFont->setFontUniqueId (fontUniqueKey); - triggerFontChangedCallbacks (menuFont->getFontUniqueId (), menuFont); - } - return (T *) menuFont; - } - - int CoreData::computeFontSize (int size) - { - int rs = size; - Config & config = Config::getInstance (); - if (Font::forceLegacyFonts == true) - { - int screenH = config.getInt ("ScreenHeight"); - rs = size * screenH / 1024; - } - //FontSizeAdjustment - rs += config.getInt ("FontSizeAdjustment"); - if (Font::forceLegacyFonts == false) - { - rs += Font::baseSize; //basesize only for new font system - } - if (Font::forceLegacyFonts == true) - { - if (rs < 10) - { - rs = 10; - } - } - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] fontsize original %d calculated:%d \n", - __FILE__, __FUNCTION__, __LINE__, size, rs); - return rs; - } - - void CoreData::saveGameSettingsToFile (std::string fileName, - GameSettings * gameSettings, - int advancedIndex) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", __FILE__, - __FUNCTION__, __LINE__); - - Config & config = Config::getInstance (); - string userData = config.getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - fileName = userData + fileName; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] fileName = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - fileName.c_str ()); +namespace Glest { + namespace Game { + + // ===================================================== + // class CoreData + // ===================================================== + + static string tempDataLocation = getUserHome(); + // ===================== PUBLIC ======================== + + static const string CORE_PATH = "data/core/"; + static const string CORE_MISC_TEXTURES_PATH = + CORE_PATH + "misc_textures/"; + + static const string CORE_MENU_PATH = CORE_PATH + "menu/"; + static const string CORE_MENU_TEXTURES_PATH = + CORE_MENU_PATH + "textures/"; + static const string CORE_MENU_SOUND_PATH = CORE_MENU_PATH + "sound/"; + static const string CORE_MENU_MUSIC_PATH = CORE_MENU_PATH + "music/"; + static const string CORE_MENU_VIDEOS_PATH = CORE_MENU_PATH + "videos/"; + + static const string CORE_WATER_SOUNDS_PATH = CORE_PATH + "/water_sounds/"; + + // Sound effects + // These variables are specified in the ini file + const string PlaySoundClip::sfxAttention = "PlaySoundAttention"; + const string PlaySoundClip::sfxHighlight = "PlaySoundHighlight"; + const string PlaySoundClip::sfxNewServer = "PlaySoundNewServer"; + const string PlaySoundClip::sfxMarker = "PlaySoundMarker"; + const string PlaySoundClip::sfxMenuClickA = "PlaySoundMenuClickA"; + const string PlaySoundClip::sfxMenuClickB = "PlaySoundMenuClickB"; + const string PlaySoundClip::sfxMenuClickC = "PlaySoundMenuClickC"; + + CoreData & CoreData::getInstance() { + static CoreData coreData; + return coreData; + } + + CoreData::CoreData() { + logoTexture = NULL; + logoTextureList.clear(); + backgroundTexture = NULL; + fireTexture = NULL; + teamColorTexture = NULL; + snowTexture = NULL; + waterSplashTexture = NULL; + customTexture = NULL; + buttonSmallTexture = NULL; + buttonBigTexture = NULL; + horizontalLineTexture = NULL; + verticalLineTexture = NULL; + checkBoxTexture = NULL; + checkedCheckBoxTexture = NULL; + gameWinnerTexture = NULL; + notOnServerTexture = NULL; + onServerDifferentTexture = NULL; + onServerTexture = NULL; + onServerInstalledTexture = NULL; + statusReadyTexture = NULL; + statusNotReadyTexture = NULL; + statusBRBTexture = NULL; + + healthbarTexture = NULL; + healthbarBackgroundTexture = NULL; + + miscTextureList.clear(); + + displayFont = NULL; + menuFontNormal = NULL; + displayFontSmall = NULL; + menuFontBig = NULL; + menuFontVeryBig = NULL; + consoleFont = NULL; + + displayFont3D = NULL; + menuFontNormal3D = NULL; + displayFontSmall3D = NULL; + menuFontBig3D = NULL; + menuFontVeryBig3D = NULL; + consoleFont3D = NULL; + + introVideoFilename = ""; + mainMenuVideoFilename = ""; + + battleEndWinVideoFilename = ""; + battleEndWinVideoFilenameFallback = ""; + battleEndWinMusicFilename = ""; + battleEndLoseVideoFilename = ""; + battleEndLoseVideoFilenameFallback = ""; + battleEndLoseMusicFilename = ""; + } + + CoreData::~CoreData() { + cleanup(); + } + + void CoreData::cleanup() { + deleteValues(waterSounds.getSoundsPtr()->begin(), + waterSounds.getSoundsPtr()->end()); + waterSounds.getSoundsPtr()->clear(); + } + + Texture2D *CoreData::getTextureBySystemId(TextureSystemType type) { + Texture2D *result = NULL; + switch (type) { + case tsyst_logoTexture: + result = getLogoTexture(); + break; + //std::vector logoTextureList; + case tsyst_backgroundTexture: + result = getBackgroundTexture(); + break; + case tsyst_fireTexture: + result = getFireTexture(); + break; + case tsyst_teamColorTexture: + result = getTeamColorTexture(); + break; + case tsyst_snowTexture: + result = getSnowTexture(); + break; + case tsyst_waterSplashTexture: + result = getWaterSplashTexture(); + break; + case tsyst_customTexture: + result = getCustomTexture(); + break; + case tsyst_buttonSmallTexture: + result = buttonSmallTexture; + break; + case tsyst_buttonBigTexture: + result = buttonBigTexture; + break; + case tsyst_horizontalLineTexture: + result = horizontalLineTexture; + break; + case tsyst_verticalLineTexture: + result = verticalLineTexture; + break; + case tsyst_checkBoxTexture: + result = checkBoxTexture; + break; + case tsyst_checkedCheckBoxTexture: + result = checkedCheckBoxTexture; + break; + case tsyst_gameWinnerTexture: + result = gameWinnerTexture; + break; + case tsyst_notOnServerTexture: + result = notOnServerTexture; + break; + case tsyst_onServerDifferentTexture: + result = onServerDifferentTexture; + break; + case tsyst_onServerTexture: + result = onServerTexture; + break; + case tsyst_onServerInstalledTexture: + result = onServerInstalledTexture; + break; + case tsyst_statusReadyTexture: + result = statusReadyTexture; + break; + case tsyst_statusNotReadyTexture: + result = statusNotReadyTexture; + break; + case tsyst_statusBRBTexture: + result = statusBRBTexture; + break; + case tsyst_healthbarTexture: + result = healthbarTexture; + break; + case tsyst_healthbarBackgroundTexture: + result = healthbarBackgroundTexture; + break; + + //std::vector miscTextureList; + } + return result; + } + + void CoreData::cleanupTexture(Texture2D ** texture) { + Renderer & renderer = Renderer::getInstance(); + renderer.endTexture(rsGlobal, *texture); + *texture = NULL; + } + + void CoreData::loadTextureIfRequired(Texture2D ** tex, string data_path, + string uniqueFilePath, + int texSystemId, bool setMipMap, + bool setAlpha, + bool loadUniqueFilePath, + bool compressionDisabled) { + if (*tex == NULL) { + bool attemptToLoadTexture = (texSystemId == tsyst_NONE); + if (attemptToLoadTexture == false && + itemLoadAttempted.find(texSystemId) == itemLoadAttempted.end()) { + + attemptToLoadTexture = true; + itemLoadAttempted[texSystemId] = true; + } + + if (attemptToLoadTexture == true) { + Renderer & renderer = Renderer::getInstance(); + *tex = renderer.newTexture2D(rsGlobal); + if (*tex) { + + (*tex)->setForceCompressionDisabled(compressionDisabled); + (*tex)->setMipmap(setMipMap); + if (setAlpha == true) { + + (*tex)->setFormat(Texture::fAlpha); + (*tex)->getPixmap()->init(1); + } + + try { + string fileToLoad = uniqueFilePath; + if (loadUniqueFilePath == false) { + + fileToLoad = + getGameCustomCoreDataPath(data_path, uniqueFilePath); + } + (*tex)->getPixmap()->load(fileToLoad); + (*tex)->setTextureSystemId(texSystemId); + + renderer.initTexture(rsGlobal, *tex); + } catch (const megaglest_runtime_error & ex) { + message(ex.what(), + GlobalStaticFlags::getIsNonGraphicalModeEnabled(), + tempDataLocation); + cleanupTexture(tex); + } + } + } + } + } + + string CoreData::getDataPath() { + string data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + if (data_path != "") { + endPathWithSlash(data_path); + } + return data_path; + } + + Texture2D *CoreData::getBackgroundTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&backgroundTexture, getDataPath(), + CORE_MENU_TEXTURES_PATH + "back.tga", + tsyst_backgroundTexture, false, false, false); + + return backgroundTexture; + } + Texture2D *CoreData::getFireTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&fireTexture, data_path, + CORE_MISC_TEXTURES_PATH + "fire_particle.tga", + tsyst_fireTexture, true, true, false); + + return fireTexture; + } + Texture2D *CoreData::getTeamColorTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&teamColorTexture, data_path, + CORE_MISC_TEXTURES_PATH + + "team_color_texture.tga", tsyst_teamColorTexture, + true, true, false); + + return teamColorTexture; + } + Texture2D *CoreData::getSnowTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&snowTexture, data_path, + CORE_MISC_TEXTURES_PATH + "snow_particle.tga", + tsyst_snowTexture, false, true, false); + + return snowTexture; + } + Texture2D *CoreData::getLogoTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&logoTexture, data_path, + CORE_MENU_TEXTURES_PATH + "logo.tga", + tsyst_logoTexture, false, false, false); + + return logoTexture; + } + Texture2D *CoreData::getWaterSplashTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&waterSplashTexture, data_path, + CORE_MISC_TEXTURES_PATH + "water_splash.tga", + tsyst_waterSplashTexture, true, true, false); + + return waterSplashTexture; + } + Texture2D *CoreData::getCustomTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&customTexture, data_path, + CORE_MENU_TEXTURES_PATH + "custom_texture.tga", + tsyst_customTexture, true, false, false); + + return customTexture; + } + Texture2D *CoreData::getButtonSmallTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&buttonSmallTexture, data_path, + CORE_MENU_TEXTURES_PATH + "button_small.tga", + tsyst_buttonSmallTexture, true, false, false, + true); + + return buttonSmallTexture; + } + Texture2D *CoreData::getButtonBigTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&buttonBigTexture, data_path, + CORE_MENU_TEXTURES_PATH + "button_big.tga", + tsyst_buttonBigTexture, true, false, false, + true); + + return buttonBigTexture; + } + Texture2D *CoreData::getHorizontalLineTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&horizontalLineTexture, data_path, + CORE_MENU_TEXTURES_PATH + "line_horizontal.tga", + tsyst_horizontalLineTexture, true, false, false, + true); + + return horizontalLineTexture; + } + Texture2D *CoreData::getVerticalLineTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&verticalLineTexture, data_path, + CORE_MENU_TEXTURES_PATH + "line_vertical.tga", + tsyst_verticalLineTexture, true, false, false, + true); + + return verticalLineTexture; + } + Texture2D *CoreData::getCheckBoxTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&checkBoxTexture, data_path, + CORE_MENU_TEXTURES_PATH + "checkbox.tga", + tsyst_checkBoxTexture, true, false, false, true); + + return checkBoxTexture; + } + Texture2D *CoreData::getCheckedCheckBoxTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&checkedCheckBoxTexture, data_path, + CORE_MENU_TEXTURES_PATH + "checkbox_checked.tga", + tsyst_checkedCheckBoxTexture, true, false, false, + true); + + return checkedCheckBoxTexture; + } + Texture2D *CoreData::getNotOnServerTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(¬OnServerTexture, data_path, + CORE_MENU_TEXTURES_PATH + "not_on_server.tga", + tsyst_notOnServerTexture, true, false, false); + + return notOnServerTexture; + } + Texture2D *CoreData::getOnServerDifferentTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&onServerDifferentTexture, data_path, + CORE_MENU_TEXTURES_PATH + + "on_server_different.tga", + tsyst_onServerDifferentTexture, true, false, + false); + + return onServerDifferentTexture; + } + Texture2D *CoreData::getOnServerTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&onServerTexture, data_path, + CORE_MENU_TEXTURES_PATH + "on_server.tga", + tsyst_onServerTexture, true, false, false); + + return onServerTexture; + } + Texture2D *CoreData::getOnServerInstalledTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&onServerInstalledTexture, data_path, + CORE_MENU_TEXTURES_PATH + + "on_server_installed.tga", + tsyst_onServerInstalledTexture, true, false, + false); + + return onServerInstalledTexture; + } + Texture2D *CoreData::getStatusReadyTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&statusReadyTexture, data_path, + CORE_MENU_TEXTURES_PATH + "status_ready.png", + tsyst_statusReadyTexture, true, false, false); + + return statusReadyTexture; + } + Texture2D *CoreData::getStatusNotReadyTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&statusNotReadyTexture, data_path, + CORE_MENU_TEXTURES_PATH + "status_notready.png", + tsyst_statusNotReadyTexture, true, false, false); + + return statusNotReadyTexture; + } + Texture2D *CoreData::getStatusBRBTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&statusBRBTexture, data_path, + CORE_MENU_TEXTURES_PATH + "status_brb.png", + tsyst_statusBRBTexture, true, false, false); + + return statusBRBTexture; + } + Texture2D *CoreData::getGameWinnerTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&gameWinnerTexture, data_path, + CORE_MISC_TEXTURES_PATH + "game_winner.png", + tsyst_gameWinnerTexture, true, false, false, + true); + + return gameWinnerTexture; + } + + Texture2D *CoreData::getHealthbarTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&healthbarTexture, data_path, + CORE_MISC_TEXTURES_PATH + "healthbar.png", + tsyst_healthbarTexture, true, false, false, + true); + + return healthbarTexture; + } + + Texture2D *CoreData::getHealthbarBackgroundTexture() { + string data_path = getDataPath(); + loadTextureIfRequired(&healthbarBackgroundTexture, data_path, + CORE_MISC_TEXTURES_PATH + + "healthbarBackground.png", + tsyst_healthbarBackgroundTexture, true, false, + false, true); + + return healthbarBackgroundTexture; + } + + void CoreData::loadLogoTextureExtraIfRequired() { + int loadAttemptLookupKey = tsyst_COUNT + 1; + if (itemLoadAttempted.find(loadAttemptLookupKey) == + itemLoadAttempted.end()) { + + itemLoadAttempted[loadAttemptLookupKey] = true; + + string data_path = getDataPath(); + logoTextureList.clear(); + string logosPath = getGameCustomCoreDataPath(data_path, "") + + CORE_MENU_TEXTURES_PATH + "logo*.*"; + vector < string > logoFilenames; + findAll(logosPath, logoFilenames, false, false); + for (int index = 0; index < (int) logoFilenames.size(); ++index) { + + string logo = logoFilenames[index]; + if (strcmp("logo.tga", logo.c_str()) != 0) { + + Texture2D *logoTextureExtra = NULL; + loadTextureIfRequired(&logoTextureExtra, data_path, + getGameCustomCoreDataPath(data_path, "") + + CORE_MENU_TEXTURES_PATH + logo, tsyst_NONE, + true, false, true); + logoTextureList.push_back(logoTextureExtra); + } + } + if (logoTextureList.empty() == true) { + + logosPath = data_path + CORE_MENU_TEXTURES_PATH + "logo*.*"; + vector < string > logoFilenames; + findAll(logosPath, logoFilenames, false, false); + for (int index = 0; index < (int) logoFilenames.size(); ++index) { + + string logo = logoFilenames[index]; + if (strcmp("logo.tga", logo.c_str()) != 0) { + + Texture2D *logoTextureExtra = NULL; + loadTextureIfRequired(&logoTextureExtra, data_path, + data_path + CORE_MENU_TEXTURES_PATH + + logo, tsyst_NONE, true, false, true); + logoTextureList.push_back(logoTextureExtra); + } + } + } + } + } + size_t CoreData::getLogoTextureExtraCount() { + loadLogoTextureExtraIfRequired(); + return logoTextureList.size(); + } + Texture2D *CoreData::getLogoTextureExtra(int idx) { + loadLogoTextureExtraIfRequired(); + return logoTextureList[idx]; + } + + void CoreData::loadMiscTextureListIfRequired() { + int loadAttemptLookupKey = tsyst_COUNT + 2; + if (itemLoadAttempted.find(loadAttemptLookupKey) == + itemLoadAttempted.end()) { + + itemLoadAttempted[loadAttemptLookupKey] = true; + + string data_path = getDataPath(); + + miscTextureList.clear(); + string introPath = getGameCustomCoreDataPath(data_path, "") + + CORE_MENU_TEXTURES_PATH + "intro*.*"; + vector < string > introFilenames; + findAll(introPath, introFilenames, false, false); + for (int i = 0; i < (int) introFilenames.size(); ++i) { + string logo = introFilenames[i]; + + Texture2D *logoTextureExtra = NULL; + loadTextureIfRequired(&logoTextureExtra, data_path, + getGameCustomCoreDataPath(data_path, + "") + + CORE_MENU_TEXTURES_PATH + logo, tsyst_NONE, + true, false, true); + miscTextureList.push_back(logoTextureExtra); + } + if (miscTextureList.empty() == true) { + introPath = data_path + CORE_MENU_TEXTURES_PATH + "intro*.*"; + vector < string > introFilenames; + findAll(introPath, introFilenames, false, false); + for (int i = 0; i < (int) introFilenames.size(); ++i) { + string logo = introFilenames[i]; + + Texture2D *logoTextureExtra = NULL; + loadTextureIfRequired(&logoTextureExtra, data_path, + data_path + CORE_MENU_TEXTURES_PATH + logo, + tsyst_NONE, true, false, true); + miscTextureList.push_back(logoTextureExtra); + } + } + + } + } + + std::vector < Texture2D * >&CoreData::getMiscTextureList() { + loadMiscTextureListIfRequired(); + return miscTextureList; + } + + void CoreData::loadTextures(string data_path) { + // Required to be loaded at program startup as they may be accessed in + // threads or some other dangerous way so lazy loading is not an option + getCustomTexture(); + } + + StaticSound *CoreData::getClickSoundA() { + static PlaySoundClip snd; + return snd.getSound(snd.sfxMenuClickA); + } + + StaticSound *CoreData::getClickSoundB() { + static PlaySoundClip snd; + return snd.getSound(snd.sfxMenuClickB); + + } + StaticSound *CoreData::getClickSoundC() { + static PlaySoundClip snd; + return snd.getSound(snd.sfxMenuClickC); + } + + void CoreData::loadWaterSoundsIfRequired() { + int loadAttemptLookupKey = tsyst_COUNT + 9; + if (itemLoadAttempted.find(loadAttemptLookupKey) == + itemLoadAttempted.end()) { + + itemLoadAttempted[loadAttemptLookupKey] = true; + + string data_path = getDataPath(); + cleanup(); + waterSounds.resize(6); + + for (int index = 0; index < 6; ++index) { + waterSounds[index] = new StaticSound(); + if (waterSounds[index] != NULL) { + try { + waterSounds[index]->load(getGameCustomCoreDataPath(data_path, + CORE_WATER_SOUNDS_PATH + + "water" + + intToStr + (index) + + ".wav")); + } catch (const megaglest_runtime_error & ex) { + message(ex.what(), + GlobalStaticFlags::getIsNonGraphicalModeEnabled(), + tempDataLocation); + } + } + } + } + } + + StaticSound *CoreData::getWaterSound() { + loadWaterSoundsIfRequired(); + return waterSounds.getRandSound(); + } + + void CoreData::loadSounds(string data_path) { + // sounds + // try { + // clickSoundA.load( + // getGameCustomCoreDataPath(data_path, + // CORE_MENU_SOUND_PATH + "click_a.wav")); + // clickSoundB.load( + // getGameCustomCoreDataPath(data_path, + // CORE_MENU_SOUND_PATH + "click_b.wav")); + // clickSoundC.load( + // getGameCustomCoreDataPath(data_path, + // CORE_MENU_SOUND_PATH + "click_c.wav")); + // attentionSound.load( + // getGameCustomCoreDataPath(data_path, + // CORE_MENU_SOUND_PATH + "attention.wav")); + // highlightSound.load( + // getGameCustomCoreDataPath(data_path, + // CORE_MENU_SOUND_PATH + "highlight.wav")); + // markerSound.load( + // getGameCustomCoreDataPath(data_path, + // CORE_MENU_SOUND_PATH + "sonar.wav")); + // } + // catch (const megaglest_runtime_error& ex) { + // message(ex.what(), GlobalStaticFlags::getIsNonGraphicalModeEnabled(), + // tempDataLocation); + // } + + // cleanup(); + // waterSounds.resize(6); + // + // for (int i = 0; i < 6; ++i) { + // waterSounds[i] = new StaticSound(); + // if (waterSounds[i]) { + // try { + // waterSounds[i]->load( + // getGameCustomCoreDataPath(data_path, + // CORE_WATER_SOUNDS_PATH + "water" + intToStr(i) + // + ".wav")); + // } catch (const megaglest_runtime_error& ex) { + // message(ex.what(), + // GlobalStaticFlags::getIsNonGraphicalModeEnabled(), + // tempDataLocation); + // } + // } + // } + } + + + void CoreData::loadMusicIfRequired() { + int loadAttemptLookupKey = tsyst_COUNT + 10; + if (itemLoadAttempted.find(loadAttemptLookupKey) == + itemLoadAttempted.end()) { + + itemLoadAttempted[loadAttemptLookupKey] = true; + + string data_path = getDataPath(); + + XmlTree xmlTree; + xmlTree. + load(getGameCustomCoreDataPath + (data_path, CORE_MENU_PATH + "menu.xml"), + Properties::getTagReplacementValues()); + const XmlNode *menuNode = xmlTree.getRootNode(); + string menuMusicPath = "/menu/music/"; + string menuIntroMusicFile = "intro_music.ogg"; + string menuMusicFile = "menu_music.ogg"; + if (menuNode->hasChild("intro") == true) { + const XmlNode *introNode = menuNode->getChild("intro"); + // intro info + const XmlNode *menuPathNode = + introNode->getChild("menu-music-path"); + menuMusicPath = + menuPathNode->getAttribute("value")->getRestrictedValue(); + const XmlNode *menuIntroMusicNode = + introNode->getChild("menu-intro-music"); + menuIntroMusicFile = + menuIntroMusicNode->getAttribute("value")->getRestrictedValue(); + const XmlNode *menuMusicNode = introNode->getChild("menu-music"); + menuMusicFile = + menuMusicNode->getAttribute("value")->getRestrictedValue(); + } + try { + introMusic.open(getGameCustomCoreDataPath(data_path, + CORE_PATH + + menuMusicPath + + menuIntroMusicFile)); + introMusic.setNext(&menuMusic); + menuMusic.open(getGameCustomCoreDataPath(data_path, + CORE_PATH + + menuMusicPath + + menuMusicFile)); + menuMusic.setNext(&menuMusic); + } catch (const megaglest_runtime_error & ex) { + message(ex.what(), + GlobalStaticFlags::getIsNonGraphicalModeEnabled(), + tempDataLocation); + } + } + } + + StrSound *CoreData::getIntroMusic() { + loadMusicIfRequired(); + return &introMusic; + } + + StrSound *CoreData::getMenuMusic() { + loadMusicIfRequired(); + return &menuMusic; + } + + void CoreData::loadMusic(string data_path) { + } + + void CoreData::loadIntroMedia(string data_path) { + Config & config = Config::getInstance(); + + introVideoFilename = config.getString("IntroVideoURL", ""); + introVideoFilenameFallback = + config.getString("IntroVideoURLFallback", ""); + if (introVideoFilename == "") { + string introVideoPath = getGameCustomCoreDataPath(data_path, "") + + CORE_MENU_VIDEOS_PATH + "intro.*"; + vector < string > introVideos; + findAll(introVideoPath, introVideos, false, false); + for (int i = 0; i < (int) introVideos.size(); ++i) { + string video = getGameCustomCoreDataPath(data_path, "") + + CORE_MENU_VIDEOS_PATH + introVideos[i]; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Checking if intro video [%s] exists\n", video.c_str()); + + if (fileExists(video)) { + introVideoFilename = video; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("FOUND intro video [%s] will use this file\n", + video.c_str()); + + break; + } + } + if (introVideoFilename == "") { + introVideoPath = data_path + CORE_MENU_VIDEOS_PATH + "intro.*"; + introVideos.clear(); + findAll(introVideoPath, introVideos, false, false); + for (int i = 0; i < (int) introVideos.size(); ++i) { + string video = data_path + CORE_MENU_VIDEOS_PATH + introVideos[i]; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Checking if intro video [%s] exists\n", + video.c_str()); + + if (fileExists(video)) { + introVideoFilename = video; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("FOUND intro video [%s] will use this file\n", + video.c_str()); + + break; + } + } + } + } + } + + void CoreData::loadMainMenuMedia(string data_path) { + Config & config = Config::getInstance(); + + mainMenuVideoFilename = config.getString("MainMenuVideoURL", ""); + mainMenuVideoFilenameFallback = + config.getString("MainMenuVideoURLFallback", ""); + if (mainMenuVideoFilename == "") { + string mainVideoPath = getGameCustomCoreDataPath(data_path, "") + + CORE_MENU_VIDEOS_PATH + "main.*"; + vector < string > mainVideos; + findAll(mainVideoPath, mainVideos, false, false); + for (int i = 0; i < (int) mainVideos.size(); ++i) { + string video = getGameCustomCoreDataPath(data_path, "") + + CORE_MENU_VIDEOS_PATH + mainVideos[i]; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Checking if mainmenu video [%s] exists\n", + video.c_str()); + + if (fileExists(video)) { + mainMenuVideoFilename = video; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("FOUND mainmenu video [%s] will use this file\n", + video.c_str()); + + break; + } + } + if (mainMenuVideoFilename == "") { + mainVideoPath = data_path + CORE_MENU_VIDEOS_PATH + "main.*"; + mainVideos.clear(); + findAll(mainVideoPath, mainVideos, false, false); + for (int i = 0; i < (int) mainVideos.size(); ++i) { + string video = data_path + CORE_MENU_VIDEOS_PATH + mainVideos[i]; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Checking if mainmenu video [%s] exists\n", + video.c_str()); + + if (fileExists(video)) { + mainMenuVideoFilename = video; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("FOUND mainmenu video [%s] will use this file\n", + video.c_str()); + + break; + } + } + } + } + } + + void CoreData::loadBattleEndMedia(string data_path) { + Config & config = Config::getInstance(); + + battleEndWinVideoFilename = + config.getString("BattleEndWinVideoURL", ""); + battleEndWinVideoFilenameFallback = + config.getString("BattleEndWinVideoURLFallback", ""); + if (battleEndWinVideoFilename == "") { + string battleEndWinVideoPath = + getGameCustomCoreDataPath(data_path, + "") + CORE_MENU_VIDEOS_PATH + + "battle_end_win.*"; + vector < string > battleEndWinVideos; + findAll(battleEndWinVideoPath, battleEndWinVideos, false, false); + for (int i = 0; i < (int) battleEndWinVideos.size(); ++i) { + string video = getGameCustomCoreDataPath(data_path, "") + + CORE_MENU_VIDEOS_PATH + battleEndWinVideos[i]; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Checking if battle end win video [%s] exists\n", + video.c_str()); + + if (fileExists(video)) { + battleEndWinVideoFilename = video; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("FOUND battle end win video [%s] will use this file\n", + video.c_str()); + + break; + } + } + if (battleEndWinVideoFilename == "") { + battleEndWinVideoPath = data_path + CORE_MENU_VIDEOS_PATH + + "battle_end_win.*"; + battleEndWinVideos.clear(); + findAll(battleEndWinVideoPath, battleEndWinVideos, false, false); + for (int i = 0; i < (int) battleEndWinVideos.size(); ++i) { + string video = data_path + CORE_MENU_VIDEOS_PATH + + battleEndWinVideos[i]; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Checking if battle end win video [%s] exists\n", + video.c_str()); + + if (fileExists(video)) { + battleEndWinVideoFilename = video; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("FOUND battle end video win [%s] will use this file\n", + video.c_str()); + + break; + } + } + } + } + battleEndWinMusicFilename = + config.getString("BattleEndWinMusicFilename", ""); + if (battleEndWinMusicFilename == "") { + string battleEndWinPath = getGameCustomCoreDataPath(data_path, "") + + CORE_MENU_MUSIC_PATH + "battle_end_win.*"; + vector < string > battleEndWinMusic; + findAll(battleEndWinPath, battleEndWinMusic, false, false); + for (int i = 0; i < (int) battleEndWinMusic.size(); ++i) { + string music = getGameCustomCoreDataPath(data_path, "") + + CORE_MENU_MUSIC_PATH + battleEndWinMusic[i]; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Checking if battle end win music [%s] exists\n", + music.c_str()); + + if (fileExists(music)) { + battleEndWinMusicFilename = music; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("FOUND battle end win music [%s] will use this file\n", + music.c_str()); + + break; + } + } + if (battleEndWinMusicFilename == "") { + battleEndWinPath = data_path + CORE_MENU_MUSIC_PATH + + "battle_end_win.*"; + battleEndWinMusic.clear(); + findAll(battleEndWinPath, battleEndWinMusic, false, false); + for (int i = 0; i < (int) battleEndWinMusic.size(); ++i) { + string music = data_path + CORE_MENU_MUSIC_PATH + + battleEndWinMusic[i]; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Checking if battle end win music [%s] exists\n", + music.c_str()); + + if (fileExists(music)) { + battleEndWinMusicFilename = music; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("FOUND battle end music win [%s] will use this file\n", + music.c_str()); + + break; + } + } + } + } + battleEndLoseVideoFilename = + config.getString("BattleEndLoseVideoURL", ""); + battleEndLoseVideoFilenameFallback = + config.getString("BattleEndLoseVideoURLFallback", ""); + if (battleEndLoseVideoFilename == "") { + string battleEndLoseVideoPath = + getGameCustomCoreDataPath(data_path, + "") + CORE_MENU_VIDEOS_PATH + + "battle_end_lose.*"; + vector < string > battleEndLoseVideos; + findAll(battleEndLoseVideoPath, battleEndLoseVideos, false, false); + for (int i = 0; i < (int) battleEndLoseVideos.size(); ++i) { + string video = getGameCustomCoreDataPath(data_path, "") + + CORE_MENU_VIDEOS_PATH + battleEndLoseVideos[i]; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Checking if battle end lose video [%s] exists\n", + video.c_str()); + + if (fileExists(video)) { + battleEndLoseVideoFilename = video; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("FOUND battle end lose video [%s] will use this file\n", + video.c_str()); + + break; + } + } + if (battleEndLoseVideoFilename == "") { + battleEndLoseVideoPath = data_path + CORE_MENU_VIDEOS_PATH + + "battle_end_lose.*"; + battleEndLoseVideos.clear(); + findAll(battleEndLoseVideoPath, battleEndLoseVideos, false, false); + for (int i = 0; i < (int) battleEndLoseVideos.size(); ++i) { + string video = data_path + CORE_MENU_VIDEOS_PATH + + battleEndLoseVideos[i]; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Checking if battle end lose video [%s] exists\n", + video.c_str()); + + if (fileExists(video)) { + battleEndLoseVideoFilename = video; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("FOUND battle end video lose [%s] will use this file\n", + video.c_str()); + + break; + } + } + } + } + battleEndLoseMusicFilename = + config.getString("BattleEndLoseMusicFilename", ""); + if (battleEndLoseMusicFilename == "") { + string battleEndLosePath = getGameCustomCoreDataPath(data_path, "") + + CORE_MENU_MUSIC_PATH + "battle_end_lose.*"; + vector < string > battleEndLoseMusic; + findAll(battleEndLosePath, battleEndLoseMusic, false, false); + for (int i = 0; i < (int) battleEndLoseMusic.size(); ++i) { + string music = getGameCustomCoreDataPath(data_path, "") + + CORE_MENU_MUSIC_PATH + battleEndLoseMusic[i]; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Checking if battle end lose music [%s] exists\n", + music.c_str()); + + if (fileExists(music)) { + battleEndLoseMusicFilename = music; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("FOUND battle end lose music [%s] will use this file\n", + music.c_str()); + + break; + } + } + if (battleEndLoseMusicFilename == "") { + battleEndLosePath = data_path + CORE_MENU_MUSIC_PATH + + "battle_end_lose.*"; + battleEndLoseMusic.clear(); + findAll(battleEndLosePath, battleEndLoseMusic, false, false); + for (int i = 0; i < (int) battleEndLoseMusic.size(); ++i) { + string music = data_path + CORE_MENU_MUSIC_PATH + + battleEndLoseMusic[i]; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Checking if battle end lose music [%s] exists\n", + music.c_str()); + + if (fileExists(music)) { + battleEndLoseMusicFilename = music; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("FOUND battle end music lose [%s] will use this file\n", + music.c_str()); + + break; + } + } + } + } + } + + void CoreData::load() { + string data_path = CoreData::getDataPath(); + + Logger::getInstance().add(Lang::getInstance(). + getString("LogScreenCoreDataLoading", "", + true)); + + // textures + loadTextures(data_path); + + // fonts + loadFonts(); + + // sounds + loadSounds(data_path); + + // music + loadMusic(data_path); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false && + Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == true) { + + loadIntroMedia(data_path); + + loadMainMenuMedia(data_path); + + loadBattleEndMedia(data_path); + } + } + + bool CoreData::hasIntroVideoFilename() const { + bool result = (introVideoFilename != ""); + return result; + } + + bool CoreData::hasMainMenuVideoFilename() const { + bool result = (mainMenuVideoFilename != ""); + return result; + } + + //bool CoreData::hasBattleEndVideoFilename(bool won) const { + // bool result = false; + // if(won == true) { + // result =(battleEndWinVideoFilename != ""); + // } + // else { + // result =(battleEndLoseVideoFilename != ""); + // } + // return result; + //} + + void CoreData::registerFontChangedCallback(std::string entityName, + FontChangedCallbackInterface * + cb) { + if (entityName == "") { + printf("Register Font Callback detected a blank entityName!\n"); + throw + megaglest_runtime_error + ("Register Font Callback detected a blank entityName!"); + } + if (entityName != "") { + registeredFontChangedCallbacks[entityName].push_back(cb); + } + } + void CoreData::unRegisterFontChangedCallback(std::string entityName) { + if (entityName == "") { + printf("UnRegister Font Callback detected a blank entityName!\n"); + throw + megaglest_runtime_error + ("UnRegister Font Callback detected a blank entityName!"); + } + if (entityName != "") { + registeredFontChangedCallbacks.erase(entityName); + } + } + void CoreData::triggerFontChangedCallbacks(std::string fontUniqueId, + Font * font) { + for (std::map < std::string, + std::vector < + FontChangedCallbackInterface * > >::const_iterator iterMap = + registeredFontChangedCallbacks.begin(); + iterMap != registeredFontChangedCallbacks.end(); ++iterMap) { + for (unsigned int index = 0; index < iterMap->second.size(); ++index) { + //printf("Font Callback detected calling: Control [%s] for Font: [%s] value [%p]\n",iterMap->first.c_str(),fontUniqueId.c_str(),font); + FontChangedCallbackInterface *cb = iterMap->second[index]; + cb->FontChangedCallback(fontUniqueId, font); + } + } + } + void CoreData::loadFonts() { + Lang & lang = Lang::getInstance(); + + //display font + Config & config = Config::getInstance(); + + string displayFontNamePrefix = config.getString("FontDisplayPrefix"); + string displayFontNamePostfix = config.getString("FontDisplayPostfix"); + int displayFontSize = + computeFontSize(config.getInt("FontDisplayBaseSize")); + + if (lang.hasString("FontDisplayPrefix") == true) { + displayFontNamePrefix = lang.getString("FontDisplayPrefix"); + } + if (lang.hasString("FontDisplayPostfix") == true) { + displayFontNamePostfix = lang.getString("FontDisplayPostfix"); + } + if (lang.hasString("FontDisplayBaseSize") == true) { + displayFontSize = + computeFontSize(strToInt(lang.getString("FontDisplayBaseSize"))); + } + string displayFontName = + displayFontNamePrefix + intToStr(displayFontSize) + + displayFontNamePostfix; + + displayFont = + loadFont < Font2D >(displayFont, displayFontName, displayFontSize, + "FontDisplay", "FontDisplayFamily", + "displayFont"); + displayFont3D = + loadFont < Font3D >(displayFont3D, displayFontName, displayFontSize, + "FontDisplay", "FontDisplayFamily", + "displayFont3D"); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] displayFontName = [%s] displayFontSize = %d\n", + __FILE__, __FUNCTION__, __LINE__, + displayFontName.c_str(), displayFontSize); + + //menu fonts + string displayFontNameSmallPrefix = + config.getString("FontDisplayPrefix"); + string displayFontNameSmallPostfix = + config.getString("FontDisplayPostfix"); + int displayFontNameSmallSize = + computeFontSize(config.getInt("FontDisplaySmallBaseSize")); + + if (lang.hasString("FontDisplayPrefix") == true) { + displayFontNameSmallPrefix = lang.getString("FontDisplayPrefix"); + } + if (lang.hasString("FontDisplayPostfix") == true) { + displayFontNameSmallPostfix = lang.getString("FontDisplayPostfix"); + } + if (lang.hasString("FontDisplaySmallBaseSize") == true) { + displayFontNameSmallSize = + computeFontSize(strToInt + (lang.getString("FontDisplaySmallBaseSize"))); + } + string displayFontNameSmall = + displayFontNameSmallPrefix + intToStr(displayFontNameSmallSize) + + displayFontNameSmallPostfix; + + displayFontSmall = + loadFont < Font2D >(displayFontSmall, displayFontNameSmall, + displayFontNameSmallSize, "FontSmallDisplay", + "FontSmallDisplayFamily", "displayFontSmall"); + displayFontSmall3D = + loadFont < Font3D >(displayFontSmall3D, displayFontNameSmall, + displayFontNameSmallSize, "FontSmallDisplay", + "FontSmallDisplayFamily", "displayFontSmall3D"); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] displayFontSmallName = [%s] displayFontSmallNameSize = %d\n", + __FILE__, __FUNCTION__, __LINE__, + displayFontNameSmall.c_str(), + displayFontNameSmallSize); + + string menuFontNameNormalPrefix = + config.getString("FontMenuNormalPrefix"); + string menuFontNameNormalPostfix = + config.getString("FontMenuNormalPostfix"); + int menuFontNameNormalSize = + computeFontSize(config.getInt("FontMenuNormalBaseSize")); + if (lang.hasString("FontMenuNormalPrefix") == true) { + menuFontNameNormalPrefix = lang.getString("FontMenuNormalPrefix"); + } + if (lang.hasString("FontMenuNormalPostfix") == true) { + menuFontNameNormalPostfix = lang.getString("FontMenuNormalPostfix"); + } + if (lang.hasString("FontMenuNormalBaseSize") == true) { + menuFontNameNormalSize = + computeFontSize(strToInt + (lang.getString("FontMenuNormalBaseSize"))); + } + string menuFontNameNormal = + menuFontNameNormalPrefix + intToStr(menuFontNameNormalSize) + + menuFontNameNormalPostfix; + + menuFontNormal = + loadFont < Font2D >(menuFontNormal, menuFontNameNormal, + menuFontNameNormalSize, "FontMenuNormal", + "FontMenuNormalFamily", "menuFontNormal"); + menuFontNormal3D = + loadFont < Font3D >(menuFontNormal3D, menuFontNameNormal, + menuFontNameNormalSize, "FontMenuNormal", + "FontMenuNormalFamily", "menuFontNormal3D"); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] menuFontNormalName = [%s] menuFontNormalNameSize = %d\n", + __FILE__, __FUNCTION__, __LINE__, + menuFontNameNormal.c_str(), + menuFontNameNormalSize); + + string menuFontNameBigPrefix = config.getString("FontMenuBigPrefix"); + string menuFontNameBigPostfix = config.getString("FontMenuBigPostfix"); + int menuFontNameBigSize = + computeFontSize(config.getInt("FontMenuBigBaseSize")); + + if (lang.hasString("FontMenuBigPrefix") == true) { + menuFontNameBigPrefix = lang.getString("FontMenuBigPrefix"); + } + if (lang.hasString("FontMenuBigPostfix") == true) { + menuFontNameBigPostfix = lang.getString("FontMenuBigPostfix"); + } + if (lang.hasString("FontMenuBigBaseSize") == true) { + menuFontNameBigSize = + computeFontSize(strToInt(lang.getString("FontMenuBigBaseSize"))); + } + string menuFontNameBig = + menuFontNameBigPrefix + intToStr(menuFontNameBigSize) + + menuFontNameBigPostfix; + + menuFontBig = + loadFont < Font2D >(menuFontBig, menuFontNameBig, + menuFontNameBigSize, "FontMenuBig", + "FontMenuBigFamily", "menuFontBig"); + menuFontBig3D = + loadFont < Font3D >(menuFontBig3D, menuFontNameBig, + menuFontNameBigSize, "FontMenuBig", + "FontMenuBigFamily", "menuFontBig3D"); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] menuFontNameBig = [%s] menuFontNameBigSize = %d\n", + __FILE__, __FUNCTION__, __LINE__, + menuFontNameBig.c_str(), + menuFontNameBigSize); + + string menuFontNameVeryBigPrefix = + config.getString("FontMenuBigPrefix"); + string menuFontNameVeryBigPostfix = + config.getString("FontMenuBigPostfix"); + int menuFontNameVeryBigSize = + computeFontSize(config.getInt("FontMenuVeryBigBaseSize")); + + if (lang.hasString("FontMenuBigPrefix") == true) { + menuFontNameVeryBigPrefix = lang.getString("FontMenuBigPrefix"); + } + if (lang.hasString("FontMenuBigPostfix") == true) { + menuFontNameVeryBigPostfix = lang.getString("FontMenuBigPostfix"); + } + if (lang.hasString("FontMenuVeryBigBaseSize") == true) { + menuFontNameVeryBigSize = + computeFontSize(strToInt + (lang.getString("FontMenuVeryBigBaseSize"))); + } + string menuFontNameVeryBig = + menuFontNameVeryBigPrefix + intToStr(menuFontNameVeryBigSize) + + menuFontNameVeryBigPostfix; + + menuFontVeryBig = + loadFont < Font2D >(menuFontVeryBig, menuFontNameVeryBig, + menuFontNameVeryBigSize, "FontMenuVeryBig", + "FontMenuVeryBigFamily", "menuFontVeryBig"); + menuFontVeryBig3D = + loadFont < Font3D >(menuFontVeryBig3D, menuFontNameVeryBig, + menuFontNameVeryBigSize, "FontMenuVeryBig", + "FontMenuVeryBigFamily", "menuFontVeryBig3D"); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] menuFontNameVeryBig = [%s] menuFontNameVeryBigSize = %d\n", + __FILE__, __FUNCTION__, __LINE__, + menuFontNameVeryBig.c_str(), + menuFontNameVeryBigSize); + + //console font + string consoleFontNamePrefix = config.getString("FontConsolePrefix"); + string consoleFontNamePostfix = config.getString("FontConsolePostfix"); + int consoleFontNameSize = + computeFontSize(config.getInt("FontConsoleBaseSize")); + + if (lang.hasString("FontConsolePrefix") == true) { + consoleFontNamePrefix = lang.getString("FontConsolePrefix"); + } + if (lang.hasString("FontConsolePostfix") == true) { + consoleFontNamePostfix = lang.getString("FontConsolePostfix"); + } + if (lang.hasString("FontConsoleBaseSize") == true) { + consoleFontNameSize = + computeFontSize(strToInt(lang.getString("FontConsoleBaseSize"))); + } + string consoleFontName = + consoleFontNamePrefix + intToStr(consoleFontNameSize) + + consoleFontNamePostfix; + + consoleFont = + loadFont < Font2D >(consoleFont, consoleFontName, + consoleFontNameSize, "FontConsole", + "FontConsoleFamily", "consoleFont"); + consoleFont3D = + loadFont < Font3D >(consoleFont3D, consoleFontName, + consoleFontNameSize, "FontConsole", + "FontConsoleFamily", "consoleFont3D"); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] consoleFontName = [%s] consoleFontNameSize = %d\n", + __FILE__, __FUNCTION__, __LINE__, + consoleFontName.c_str(), + consoleFontNameSize); + } + + + template < typename T > T * CoreData::loadFont(Font * menuFont, + string menuFontName, + int menuFontNameSize, + string fontType, + string fontTypeFamily, + string fontUniqueKey) { + Renderer & renderer = Renderer::getInstance(); + if (menuFont) { + string fontUniqueId = menuFont->getFontUniqueId(); + renderer.endFont(menuFont, rsGlobal); + menuFont = NULL; + triggerFontChangedCallbacks(fontUniqueId, menuFont); + } + if (Renderer::renderText3DEnabled == false) { + menuFont = renderer.newFont(rsGlobal); + } else { + menuFont = renderer.newFont3D(rsGlobal); + } + if (menuFont) { + Config & config = Config::getInstance(); + menuFont->setType(menuFontName, config.getString(fontType, ""), + config.getString(fontTypeFamily, "")); + menuFont->setSize(menuFontNameSize); + menuFont->setWidth(Font::wBold); + menuFont->setFontUniqueId(fontUniqueKey); + triggerFontChangedCallbacks(menuFont->getFontUniqueId(), menuFont); + } + return (T *) menuFont; + } + + int CoreData::computeFontSize(int size) { + int rs = size; + Config & config = Config::getInstance(); + if (Font::forceLegacyFonts == true) { + int screenH = config.getInt("ScreenHeight"); + rs = size * screenH / 1024; + } + //FontSizeAdjustment + rs += config.getInt("FontSizeAdjustment"); + if (Font::forceLegacyFonts == false) { + rs += Font::baseSize; //basesize only for new font system + } + if (Font::forceLegacyFonts == true) { + if (rs < 10) { + rs = 10; + } + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] fontsize original %d calculated:%d \n", + __FILE__, __FUNCTION__, __LINE__, size, rs); + return rs; + } + + void CoreData::saveGameSettingsToFile(std::string fileName, + GameSettings * gameSettings, + int advancedIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", __FILE__, + __FUNCTION__, __LINE__); + + Config & config = Config::getInstance(); + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + fileName = userData + fileName; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] fileName = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + fileName.c_str()); #if defined(WIN32) && !defined(__MINGW32__) - FILE *fp = _wfopen (utf8_decode (fileName).c_str (), L"w"); - std::ofstream saveGameFile (fp); + FILE *fp = _wfopen(utf8_decode(fileName).c_str(), L"w"); + std::ofstream saveGameFile(fp); #else - std::ofstream saveGameFile; - saveGameFile.open (fileName.c_str (), ios_base::out | ios_base::trunc); + std::ofstream saveGameFile; + saveGameFile.open(fileName.c_str(), ios_base::out | ios_base::trunc); #endif - saveGameFile << "Description=" << gameSettings-> - getDescription () << std::endl; - saveGameFile << "MapFilterIndex=" << Shared::PlatformByteOrder:: - toCommonEndian (gameSettings->getMapFilter ()) << std::endl; - saveGameFile << "Map=" << gameSettings->getMap () << std::endl; - saveGameFile << "Tileset=" << gameSettings->getTileset () << std::endl; - saveGameFile << "TechTree=" << gameSettings->getTech () << std::endl; - saveGameFile << "DefaultUnits=" << Shared::PlatformByteOrder:: - toCommonEndian (gameSettings->getDefaultUnits ()) << std::endl; - saveGameFile << "DefaultResources=" << Shared::PlatformByteOrder:: - toCommonEndian (gameSettings->getDefaultResources ()) << std::endl; - saveGameFile << "DefaultVictoryConditions=" << Shared:: - PlatformByteOrder::toCommonEndian (gameSettings-> - getDefaultVictoryConditions ()) << - std::endl; - saveGameFile << "FogOfWar=" << Shared::PlatformByteOrder:: - toCommonEndian (gameSettings->getFogOfWar ()) << std::endl; - saveGameFile << "AdvancedIndex=" << Shared::PlatformByteOrder:: - toCommonEndian (advancedIndex) << std::endl; - saveGameFile << "AllowObservers=" << Shared::PlatformByteOrder:: - toCommonEndian (gameSettings->getAllowObservers ()) << std::endl; - saveGameFile << "FlagTypes1=" << Shared::PlatformByteOrder:: - toCommonEndian (gameSettings->getFlagTypes1 ()) << std::endl; - saveGameFile << "EnableObserverModeAtEndGame=" << Shared:: - PlatformByteOrder::toCommonEndian (gameSettings-> - getEnableObserverModeAtEndGame ()) - << std::endl; - saveGameFile << "AiAcceptSwitchTeamPercentChance=" << Shared:: - PlatformByteOrder::toCommonEndian (gameSettings-> - getAiAcceptSwitchTeamPercentChance - ()) << std::endl; - saveGameFile << "FallbackCpuMultiplier=" << Shared::PlatformByteOrder:: - toCommonEndian (gameSettings-> - getFallbackCpuMultiplier ()) << std::endl; - saveGameFile << "PathFinderType=" << Shared::PlatformByteOrder:: - toCommonEndian (gameSettings->getPathFinderType ()) << std::endl; - saveGameFile << "EnableServerControlledAI=" << Shared:: - PlatformByteOrder::toCommonEndian (gameSettings-> - getEnableServerControlledAI ()) << - std::endl; - saveGameFile << "NetworkFramePeriod=" << Shared::PlatformByteOrder:: - toCommonEndian (gameSettings->getNetworkFramePeriod ()) << std::endl; - saveGameFile << "NetworkPauseGameForLaggedClients=" << Shared:: - PlatformByteOrder::toCommonEndian (gameSettings-> - getNetworkPauseGameForLaggedClients - ()) << std::endl; + saveGameFile << "Description=" << gameSettings-> + getDescription() << std::endl; + saveGameFile << "MapFilterIndex=" << Shared::PlatformByteOrder:: + toCommonEndian(gameSettings->getMapFilter()) << std::endl; + saveGameFile << "Map=" << gameSettings->getMap() << std::endl; + saveGameFile << "Tileset=" << gameSettings->getTileset() << std::endl; + saveGameFile << "TechTree=" << gameSettings->getTech() << std::endl; + saveGameFile << "DefaultUnits=" << Shared::PlatformByteOrder:: + toCommonEndian(gameSettings->getDefaultUnits()) << std::endl; + saveGameFile << "DefaultResources=" << Shared::PlatformByteOrder:: + toCommonEndian(gameSettings->getDefaultResources()) << std::endl; + saveGameFile << "DefaultVictoryConditions=" << Shared:: + PlatformByteOrder::toCommonEndian(gameSettings-> + getDefaultVictoryConditions()) << + std::endl; + saveGameFile << "FogOfWar=" << Shared::PlatformByteOrder:: + toCommonEndian(gameSettings->getFogOfWar()) << std::endl; + saveGameFile << "AdvancedIndex=" << Shared::PlatformByteOrder:: + toCommonEndian(advancedIndex) << std::endl; + saveGameFile << "AllowObservers=" << Shared::PlatformByteOrder:: + toCommonEndian(gameSettings->getAllowObservers()) << std::endl; + saveGameFile << "FlagTypes1=" << Shared::PlatformByteOrder:: + toCommonEndian(gameSettings->getFlagTypes1()) << std::endl; + saveGameFile << "EnableObserverModeAtEndGame=" << Shared:: + PlatformByteOrder::toCommonEndian(gameSettings-> + getEnableObserverModeAtEndGame()) + << std::endl; + saveGameFile << "AiAcceptSwitchTeamPercentChance=" << Shared:: + PlatformByteOrder::toCommonEndian(gameSettings-> + getAiAcceptSwitchTeamPercentChance + ()) << std::endl; + saveGameFile << "FallbackCpuMultiplier=" << Shared::PlatformByteOrder:: + toCommonEndian(gameSettings-> + getFallbackCpuMultiplier()) << std::endl; + saveGameFile << "PathFinderType=" << Shared::PlatformByteOrder:: + toCommonEndian(gameSettings->getPathFinderType()) << std::endl; + saveGameFile << "EnableServerControlledAI=" << Shared:: + PlatformByteOrder::toCommonEndian(gameSettings-> + getEnableServerControlledAI()) << + std::endl; + saveGameFile << "NetworkFramePeriod=" << Shared::PlatformByteOrder:: + toCommonEndian(gameSettings->getNetworkFramePeriod()) << std::endl; + saveGameFile << "NetworkPauseGameForLaggedClients=" << Shared:: + PlatformByteOrder::toCommonEndian(gameSettings-> + getNetworkPauseGameForLaggedClients + ()) << std::endl; - saveGameFile << "FactionThisFactionIndex=" << Shared:: - PlatformByteOrder::toCommonEndian (gameSettings-> - getThisFactionIndex ()) << std:: - endl; - saveGameFile << "FactionCount=" << Shared::PlatformByteOrder:: - toCommonEndian (gameSettings->getFactionCount ()) << std::endl; + saveGameFile << "FactionThisFactionIndex=" << Shared:: + PlatformByteOrder::toCommonEndian(gameSettings-> + getThisFactionIndex()) << std:: + endl; + saveGameFile << "FactionCount=" << Shared::PlatformByteOrder:: + toCommonEndian(gameSettings->getFactionCount()) << std::endl; - saveGameFile << "NetworkAllowNativeLanguageTechtree=" << Shared:: - PlatformByteOrder::toCommonEndian (gameSettings-> - getNetworkAllowNativeLanguageTechtree - ()) << std::endl; + saveGameFile << "NetworkAllowNativeLanguageTechtree=" << Shared:: + PlatformByteOrder::toCommonEndian(gameSettings-> + getNetworkAllowNativeLanguageTechtree + ()) << std::endl; - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - int slotIndex = gameSettings->getStartLocationIndex (i); + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + int slotIndex = gameSettings->getStartLocationIndex(i); - saveGameFile << "FactionControlForIndex" << Shared:: - PlatformByteOrder::toCommonEndian (slotIndex) << "=" << Shared:: - PlatformByteOrder::toCommonEndian (gameSettings-> - getFactionControl (i)) << std:: - endl; - saveGameFile << "ResourceMultiplierIndex" << Shared:: - PlatformByteOrder::toCommonEndian (slotIndex) << "=" << Shared:: - PlatformByteOrder::toCommonEndian (gameSettings-> - getResourceMultiplierIndex (i)) - << std::endl; - saveGameFile << "FactionTeamForIndex" << Shared::PlatformByteOrder:: - toCommonEndian (slotIndex) << "=" << Shared::PlatformByteOrder:: - toCommonEndian (gameSettings->getTeam (i)) << std::endl; - saveGameFile << "FactionStartLocationForIndex" << Shared:: - PlatformByteOrder::toCommonEndian (slotIndex) << "=" << Shared:: - PlatformByteOrder::toCommonEndian (gameSettings-> - getStartLocationIndex (i)) << - std::endl; - saveGameFile << "FactionTypeNameForIndex" << Shared:: - PlatformByteOrder:: - toCommonEndian (slotIndex) << "=" << gameSettings-> - getFactionTypeName (i) << std::endl; - saveGameFile << "FactionPlayerNameForIndex" << Shared:: - PlatformByteOrder:: - toCommonEndian (slotIndex) << "=" << gameSettings-> - getNetworkPlayerName (i) << std::endl; + saveGameFile << "FactionControlForIndex" << Shared:: + PlatformByteOrder::toCommonEndian(slotIndex) << "=" << Shared:: + PlatformByteOrder::toCommonEndian(gameSettings-> + getFactionControl(i)) << std:: + endl; + saveGameFile << "ResourceMultiplierIndex" << Shared:: + PlatformByteOrder::toCommonEndian(slotIndex) << "=" << Shared:: + PlatformByteOrder::toCommonEndian(gameSettings-> + getResourceMultiplierIndex(i)) + << std::endl; + saveGameFile << "FactionTeamForIndex" << Shared::PlatformByteOrder:: + toCommonEndian(slotIndex) << "=" << Shared::PlatformByteOrder:: + toCommonEndian(gameSettings->getTeam(i)) << std::endl; + saveGameFile << "FactionStartLocationForIndex" << Shared:: + PlatformByteOrder::toCommonEndian(slotIndex) << "=" << Shared:: + PlatformByteOrder::toCommonEndian(gameSettings-> + getStartLocationIndex(i)) << + std::endl; + saveGameFile << "FactionTypeNameForIndex" << Shared:: + PlatformByteOrder:: + toCommonEndian(slotIndex) << "=" << gameSettings-> + getFactionTypeName(i) << std::endl; + saveGameFile << "FactionPlayerNameForIndex" << Shared:: + PlatformByteOrder:: + toCommonEndian(slotIndex) << "=" << gameSettings-> + getNetworkPlayerName(i) << std::endl; - saveGameFile << "FactionPlayerUUIDForIndex" << Shared:: - PlatformByteOrder:: - toCommonEndian (slotIndex) << "=" << gameSettings-> - getNetworkPlayerUUID (i) << std::endl; - } + saveGameFile << "FactionPlayerUUIDForIndex" << Shared:: + PlatformByteOrder:: + toCommonEndian(slotIndex) << "=" << gameSettings-> + getNetworkPlayerUUID(i) << std::endl; + } #if defined(WIN32) && !defined(__MINGW32__) - if (fp) - fclose (fp); + if (fp) + fclose(fp); #endif - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", __FILE__, - __FUNCTION__, __LINE__); - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", __FILE__, + __FUNCTION__, __LINE__); + } - bool CoreData::loadGameSettingsFromFile (std::string fileName, - GameSettings * gameSettings) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", __FILE__, - __FUNCTION__, __LINE__); + bool CoreData::loadGameSettingsFromFile(std::string fileName, + GameSettings * gameSettings) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", __FILE__, + __FUNCTION__, __LINE__); - bool fileWasFound = false; - Config & config = Config::getInstance (); - string userData = config.getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - if (fileExists (userData + fileName) == true) - { - fileName = userData + fileName; - fileWasFound = true; - } + bool fileWasFound = false; + Config & config = Config::getInstance(); + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + if (fileExists(userData + fileName) == true) { + fileName = userData + fileName; + fileWasFound = true; + } - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] fileName = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - fileName.c_str ()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] fileName = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + fileName.c_str()); - if (fileExists (fileName) == false) - { - return false; - } + if (fileExists(fileName) == false) { + return false; + } - fileWasFound = true; - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] fileName = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - fileName.c_str ()); + fileWasFound = true; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] fileName = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + fileName.c_str()); - Properties properties; - properties.load (fileName); + Properties properties; + properties.load(fileName); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] fileName = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - fileName.c_str ()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] fileName = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + fileName.c_str()); - gameSettings->setMapFilter (properties.getInt ("MapFilterIndex", "0")); - gameSettings->setDescription (properties.getString ("Description")); - gameSettings->setMap (properties.getString ("Map")); - gameSettings->setTileset (properties.getString ("Tileset")); - gameSettings->setTech (properties.getString ("TechTree")); - gameSettings->setDefaultUnits (properties.getBool ("DefaultUnits")); - gameSettings->setDefaultResources (properties. - getBool ("DefaultResources")); - gameSettings->setDefaultVictoryConditions (properties. - getBool - ("DefaultVictoryConditions")); - gameSettings->setFogOfWar (properties.getBool ("FogOfWar")); - //listBoxAdvanced.setSelectedItemIndex(properties.getInt("AdvancedIndex","0")); + gameSettings->setMapFilter(properties.getInt("MapFilterIndex", "0")); + gameSettings->setDescription(properties.getString("Description")); + gameSettings->setMap(properties.getString("Map")); + gameSettings->setTileset(properties.getString("Tileset")); + gameSettings->setTech(properties.getString("TechTree")); + gameSettings->setDefaultUnits(properties.getBool("DefaultUnits")); + gameSettings->setDefaultResources(properties. + getBool("DefaultResources")); + gameSettings->setDefaultVictoryConditions(properties. + getBool + ("DefaultVictoryConditions")); + gameSettings->setFogOfWar(properties.getBool("FogOfWar")); + //listBoxAdvanced.setSelectedItemIndex(properties.getInt("AdvancedIndex","0")); - gameSettings->setAllowObservers (properties. - getBool ("AllowObservers", "false")); - gameSettings->setFlagTypes1 (properties.getInt ("FlagTypes1", "0")); + gameSettings->setAllowObservers(properties. + getBool("AllowObservers", "false")); + gameSettings->setFlagTypes1(properties.getInt("FlagTypes1", "0")); - uint32 valueFlags1 = gameSettings->getFlagTypes1 (); - if (Config::getInstance (). - getBool ("EnableNetworkGameSynchChecks", "false") == true) - { - //printf("*WARNING* - EnableNetworkGameSynchChecks is enabled\n"); + uint32 valueFlags1 = gameSettings->getFlagTypes1(); + if (Config::getInstance(). + getBool("EnableNetworkGameSynchChecks", "false") == true) { + //printf("*WARNING* - EnableNetworkGameSynchChecks is enabled\n"); - valueFlags1 |= ft1_network_synch_checks_verbose; - gameSettings->setFlagTypes1 (valueFlags1); + valueFlags1 |= ft1_network_synch_checks_verbose; + gameSettings->setFlagTypes1(valueFlags1); - } - else - { - valueFlags1 &= ~ft1_network_synch_checks_verbose; - gameSettings->setFlagTypes1 (valueFlags1); + } else { + valueFlags1 &= ~ft1_network_synch_checks_verbose; + gameSettings->setFlagTypes1(valueFlags1); - } - if (Config::getInstance (). - getBool ("EnableNetworkGameSynchMonitor", "false") == true) - { - //printf("*WARNING* - EnableNetworkGameSynchChecks is enabled\n"); + } + if (Config::getInstance(). + getBool("EnableNetworkGameSynchMonitor", "false") == true) { + //printf("*WARNING* - EnableNetworkGameSynchChecks is enabled\n"); - valueFlags1 |= ft1_network_synch_checks; - gameSettings->setFlagTypes1 (valueFlags1); + valueFlags1 |= ft1_network_synch_checks; + gameSettings->setFlagTypes1(valueFlags1); - } - else - { - valueFlags1 &= ~ft1_network_synch_checks; - gameSettings->setFlagTypes1 (valueFlags1); + } else { + valueFlags1 &= ~ft1_network_synch_checks; + gameSettings->setFlagTypes1(valueFlags1); - } + } - gameSettings->setEnableObserverModeAtEndGame (properties. - getBool - ("EnableObserverModeAtEndGame")); - gameSettings->setAiAcceptSwitchTeamPercentChance (properties. - getInt - ("AiAcceptSwitchTeamPercentChance", - "30")); - gameSettings->setFallbackCpuMultiplier (properties. - getInt ("FallbackCpuMultiplier", - "5")); + gameSettings->setEnableObserverModeAtEndGame(properties. + getBool + ("EnableObserverModeAtEndGame")); + gameSettings->setAiAcceptSwitchTeamPercentChance(properties. + getInt + ("AiAcceptSwitchTeamPercentChance", + "30")); + gameSettings->setFallbackCpuMultiplier(properties. + getInt("FallbackCpuMultiplier", + "5")); - gameSettings->setPathFinderType (static_cast < PathFinderType > - (properties. - getInt ("PathFinderType", - intToStr (pfBasic). - c_str ()))); - gameSettings->setEnableServerControlledAI (properties. - getBool - ("EnableServerControlledAI", - "true")); - gameSettings->setNetworkFramePeriod (properties. - getInt ("NetworkFramePeriod", - intToStr (GameConstants:: - networkFramePeriod). - c_str ())); - gameSettings->setNetworkPauseGameForLaggedClients (properties. - getBool - ("NetworkPauseGameForLaggedClients", - "false")); + gameSettings->setPathFinderType(static_cast + (properties. + getInt("PathFinderType", + intToStr(pfBasic). + c_str()))); + gameSettings->setEnableServerControlledAI(properties. + getBool + ("EnableServerControlledAI", + "true")); + gameSettings->setNetworkFramePeriod(properties. + getInt("NetworkFramePeriod", + intToStr(GameConstants:: + networkFramePeriod). + c_str())); + gameSettings->setNetworkPauseGameForLaggedClients(properties. + getBool + ("NetworkPauseGameForLaggedClients", + "false")); - gameSettings->setThisFactionIndex (properties. - getInt ("FactionThisFactionIndex")); - gameSettings->setFactionCount (properties.getInt ("FactionCount")); + gameSettings->setThisFactionIndex(properties. + getInt("FactionThisFactionIndex")); + gameSettings->setFactionCount(properties.getInt("FactionCount")); - if (properties.hasString ("NetworkAllowNativeLanguageTechtree") == true) - { - gameSettings->setNetworkAllowNativeLanguageTechtree (properties. - getBool - ("NetworkAllowNativeLanguageTechtree")); - } - else - { - gameSettings->setNetworkAllowNativeLanguageTechtree (false); - } + if (properties.hasString("NetworkAllowNativeLanguageTechtree") == true) { + gameSettings->setNetworkAllowNativeLanguageTechtree(properties. + getBool + ("NetworkAllowNativeLanguageTechtree")); + } else { + gameSettings->setNetworkAllowNativeLanguageTechtree(false); + } - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - gameSettings->setFactionControl (i, - (ControlType) properties. - getInt (string - ("FactionControlForIndex") + - intToStr (i), - intToStr (ctClosed). - c_str ())); + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + gameSettings->setFactionControl(i, + (ControlType) properties. + getInt(string + ("FactionControlForIndex") + + intToStr(i), + intToStr(ctClosed). + c_str())); - if (gameSettings->getFactionControl (i) == ctNetworkUnassigned) - { - gameSettings->setFactionControl (i, ctNetwork); - } + if (gameSettings->getFactionControl(i) == ctNetworkUnassigned) { + gameSettings->setFactionControl(i, ctNetwork); + } - gameSettings->setResourceMultiplierIndex (i, - properties. - getInt (string - ("ResourceMultiplierIndex") - + intToStr (i), - "5")); - gameSettings->setTeam (i, - properties. - getInt (string ("FactionTeamForIndex") + - intToStr (i), "0")); - gameSettings->setStartLocationIndex (i, - properties. - getInt (string - ("FactionStartLocationForIndex") - + intToStr (i), - intToStr (i).c_str ())); - gameSettings->setFactionTypeName (i, - properties. - getString (string - ("FactionTypeNameForIndex") - + intToStr (i), "?")); + gameSettings->setResourceMultiplierIndex(i, + properties. + getInt(string + ("ResourceMultiplierIndex") + + intToStr(i), + "5")); + gameSettings->setTeam(i, + properties. + getInt(string("FactionTeamForIndex") + + intToStr(i), "0")); + gameSettings->setStartLocationIndex(i, + properties. + getInt(string + ("FactionStartLocationForIndex") + + intToStr(i), + intToStr(i).c_str())); + gameSettings->setFactionTypeName(i, + properties. + getString(string + ("FactionTypeNameForIndex") + + intToStr(i), "?")); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] i = %d, factionTypeName [%s]\n", - __FILE__, __FUNCTION__, __LINE__, i, - gameSettings->getFactionTypeName (i). - c_str ()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] i = %d, factionTypeName [%s]\n", + __FILE__, __FUNCTION__, __LINE__, i, + gameSettings->getFactionTypeName(i). + c_str()); - if (gameSettings->getFactionControl (i) == ctHuman) - { - gameSettings->setNetworkPlayerName (i, - properties. - getString (string - ("FactionPlayerNameForIndex") - + intToStr (i), "")); - } - else - { - gameSettings->setNetworkPlayerName (i, ""); - } + if (gameSettings->getFactionControl(i) == ctHuman) { + gameSettings->setNetworkPlayerName(i, + properties. + getString(string + ("FactionPlayerNameForIndex") + + intToStr(i), "")); + } else { + gameSettings->setNetworkPlayerName(i, ""); + } - gameSettings->setNetworkPlayerUUID (i, - properties. - getString (string - ("FactionPlayerUUIDForIndex") - + intToStr (i), "")); - } + gameSettings->setNetworkPlayerUUID(i, + properties. + getString(string + ("FactionPlayerUUIDForIndex") + + intToStr(i), "")); + } - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", __FILE__, - __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", __FILE__, + __FUNCTION__, __LINE__); - return fileWasFound; - } + return fileWasFound; + } - PlaySoundClip::PlaySoundClip (void) {}; + PlaySoundClip::PlaySoundClip(void) { + }; - PlaySoundClip::~PlaySoundClip (void) {}; + PlaySoundClip::~PlaySoundClip(void) { + }; - StaticSound *PlaySoundClip::getSound (const std::string& iniPlaySoundVal) - { - CoreData coreData; - int loadAttemptLookupKey = coreData.tsyst_COUNT + 6; - if (coreData.itemLoadAttempted.find (loadAttemptLookupKey) == - coreData.itemLoadAttempted.end ()) - { + StaticSound *PlaySoundClip::getSound(const std::string& iniPlaySoundVal) { + CoreData coreData; + int loadAttemptLookupKey = coreData.tsyst_COUNT + 6; + if (coreData.itemLoadAttempted.find(loadAttemptLookupKey) == + coreData.itemLoadAttempted.end()) { - coreData.itemLoadAttempted[loadAttemptLookupKey] = true; + coreData.itemLoadAttempted[loadAttemptLookupKey] = true; - try - { - static Config & config = Config::getInstance (); - iniPlaySound.load (config.getString (iniPlaySoundVal, "")); - } - catch (const megaglest_runtime_error & ex) - { - message (ex.what (), - GlobalStaticFlags::getIsNonGraphicalModeEnabled (), - tempDataLocation); - } - } + try { + static Config & config = Config::getInstance(); + iniPlaySound.load(config.getString(iniPlaySoundVal, "")); + } catch (const megaglest_runtime_error & ex) { + message(ex.what(), + GlobalStaticFlags::getIsNonGraphicalModeEnabled(), + tempDataLocation); + } + } - return &iniPlaySound; - } + return &iniPlaySound; + } -// ================== PRIVATE ======================== + // ================== PRIVATE ======================== - } + } } //end namespace diff --git a/source/glest_game/global/core_data.h b/source/glest_game/global/core_data.h index 6865f0d4b..57fea5d8b 100644 --- a/source/glest_game/global/core_data.h +++ b/source/glest_game/global/core_data.h @@ -33,347 +33,324 @@ # include "sound_container.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - using::Shared::Graphics::Texture2D; - using::Shared::Graphics::Texture3D; - using::Shared::Graphics::Font; - using::Shared::Graphics::Font2D; - using::Shared::Graphics::Font3D; - using::Shared::Graphics::FontChangedCallbackInterface; - using::Shared::Sound::StrSound; - using::Shared::Sound::StaticSound; + using::Shared::Graphics::Texture2D; + using::Shared::Graphics::Texture3D; + using::Shared::Graphics::Font; + using::Shared::Graphics::Font2D; + using::Shared::Graphics::Font3D; + using::Shared::Graphics::FontChangedCallbackInterface; + using::Shared::Sound::StrSound; + using::Shared::Sound::StaticSound; -// ===================================================== -// class CoreData -// -/// Data shared among all the ProgramStates -// ===================================================== + // ===================================================== + // class CoreData + // + /// Data shared among all the ProgramStates + // ===================================================== - class GameSettings; + class GameSettings; - class CoreData - { - friend class PlaySoundClip; - private: - std::map < int, bool > itemLoadAttempted; + class CoreData { + friend class PlaySoundClip; + private: + std::map < int, bool > itemLoadAttempted; - StrSound introMusic; - StrSound menuMusic; - SoundContainer waterSounds; + StrSound introMusic; + StrSound menuMusic; + SoundContainer waterSounds; - Texture2D *logoTexture; - std::vector < Texture2D * >logoTextureList; - Texture2D *backgroundTexture; - Texture2D *fireTexture; - Texture2D *teamColorTexture; - Texture2D *snowTexture; - Texture2D *waterSplashTexture; - Texture2D *customTexture; - Texture2D *buttonSmallTexture; - Texture2D *buttonBigTexture; - Texture2D *horizontalLineTexture; - Texture2D *verticalLineTexture; - Texture2D *checkBoxTexture; - Texture2D *checkedCheckBoxTexture; - Texture2D *gameWinnerTexture; - Texture2D *notOnServerTexture; - Texture2D *onServerDifferentTexture; - Texture2D *onServerTexture; - Texture2D *onServerInstalledTexture; - Texture2D *statusReadyTexture; - Texture2D *statusNotReadyTexture; - Texture2D *statusBRBTexture; + Texture2D *logoTexture; + std::vector < Texture2D * >logoTextureList; + Texture2D *backgroundTexture; + Texture2D *fireTexture; + Texture2D *teamColorTexture; + Texture2D *snowTexture; + Texture2D *waterSplashTexture; + Texture2D *customTexture; + Texture2D *buttonSmallTexture; + Texture2D *buttonBigTexture; + Texture2D *horizontalLineTexture; + Texture2D *verticalLineTexture; + Texture2D *checkBoxTexture; + Texture2D *checkedCheckBoxTexture; + Texture2D *gameWinnerTexture; + Texture2D *notOnServerTexture; + Texture2D *onServerDifferentTexture; + Texture2D *onServerTexture; + Texture2D *onServerInstalledTexture; + Texture2D *statusReadyTexture; + Texture2D *statusNotReadyTexture; + Texture2D *statusBRBTexture; - Texture2D *healthbarTexture; - Texture2D *healthbarBackgroundTexture; + Texture2D *healthbarTexture; + Texture2D *healthbarBackgroundTexture; - std::vector < Texture2D * >miscTextureList; + std::vector < Texture2D * >miscTextureList; - Font2D *displayFont; - Font2D *menuFontNormal; - Font2D *displayFontSmall; - Font2D *menuFontBig; - Font2D *menuFontVeryBig; - Font2D *consoleFont; + Font2D *displayFont; + Font2D *menuFontNormal; + Font2D *displayFontSmall; + Font2D *menuFontBig; + Font2D *menuFontVeryBig; + Font2D *consoleFont; - Font3D *displayFont3D; - Font3D *menuFontNormal3D; - Font3D *displayFontSmall3D; - Font3D *menuFontBig3D; - Font3D *menuFontVeryBig3D; - Font3D *consoleFont3D; + Font3D *displayFont3D; + Font3D *menuFontNormal3D; + Font3D *displayFontSmall3D; + Font3D *menuFontBig3D; + Font3D *menuFontVeryBig3D; + Font3D *consoleFont3D; - string introVideoFilename; - string introVideoFilenameFallback; + string introVideoFilename; + string introVideoFilenameFallback; - string mainMenuVideoFilename; - string mainMenuVideoFilenameFallback; + string mainMenuVideoFilename; + string mainMenuVideoFilenameFallback; - string battleEndWinVideoFilename; - string battleEndWinVideoFilenameFallback; - string battleEndWinMusicFilename; + string battleEndWinVideoFilename; + string battleEndWinVideoFilenameFallback; + string battleEndWinMusicFilename; - string battleEndLoseVideoFilename; - string battleEndLoseVideoFilenameFallback; - string battleEndLoseMusicFilename; + string battleEndLoseVideoFilename; + string battleEndLoseVideoFilenameFallback; + string battleEndLoseMusicFilename; - std::map < std::string, - std::vector < - FontChangedCallbackInterface * > >registeredFontChangedCallbacks; - public: + std::map < std::string, + std::vector < + FontChangedCallbackInterface * > >registeredFontChangedCallbacks; + public: - enum TextureSystemType - { - tsyst_NONE, - tsyst_logoTexture, - tsyst_backgroundTexture, - tsyst_fireTexture, - tsyst_teamColorTexture, - tsyst_snowTexture, - tsyst_waterSplashTexture, - tsyst_customTexture, - tsyst_buttonSmallTexture, - tsyst_buttonBigTexture, - tsyst_horizontalLineTexture, - tsyst_verticalLineTexture, - tsyst_checkBoxTexture, - tsyst_checkedCheckBoxTexture, - tsyst_gameWinnerTexture, - tsyst_notOnServerTexture, - tsyst_onServerDifferentTexture, - tsyst_onServerTexture, - tsyst_onServerInstalledTexture, - tsyst_statusReadyTexture, - tsyst_statusNotReadyTexture, - tsyst_statusBRBTexture, - tsyst_healthbarTexture, - tsyst_healthbarBackgroundTexture, + enum TextureSystemType { + tsyst_NONE, + tsyst_logoTexture, + tsyst_backgroundTexture, + tsyst_fireTexture, + tsyst_teamColorTexture, + tsyst_snowTexture, + tsyst_waterSplashTexture, + tsyst_customTexture, + tsyst_buttonSmallTexture, + tsyst_buttonBigTexture, + tsyst_horizontalLineTexture, + tsyst_verticalLineTexture, + tsyst_checkBoxTexture, + tsyst_checkedCheckBoxTexture, + tsyst_gameWinnerTexture, + tsyst_notOnServerTexture, + tsyst_onServerDifferentTexture, + tsyst_onServerTexture, + tsyst_onServerInstalledTexture, + tsyst_statusReadyTexture, + tsyst_statusNotReadyTexture, + tsyst_statusBRBTexture, + tsyst_healthbarTexture, + tsyst_healthbarBackgroundTexture, - tsyst_COUNT - }; + tsyst_COUNT + }; - public: + public: - ~CoreData (); - static CoreData & getInstance (); + ~CoreData(); + static CoreData & getInstance(); - void load (); - void cleanup (); - void loadFonts (); + void load(); + void cleanup(); + void loadFonts(); - // Textures - Texture2D *getTextureBySystemId (TextureSystemType type); + // Textures + Texture2D *getTextureBySystemId(TextureSystemType type); - Texture2D *getBackgroundTexture (); - Texture2D *getFireTexture (); - Texture2D *getTeamColorTexture (); - Texture2D *getSnowTexture (); - Texture2D *getLogoTexture (); - Texture2D *getWaterSplashTexture (); - Texture2D *getCustomTexture (); - Texture2D *getButtonSmallTexture (); - Texture2D *getButtonBigTexture (); - Texture2D *getHorizontalLineTexture (); - Texture2D *getVerticalLineTexture (); - Texture2D *getCheckBoxTexture (); - Texture2D *getCheckedCheckBoxTexture (); - Texture2D *getNotOnServerTexture (); - Texture2D *getOnServerDifferentTexture (); - Texture2D *getOnServerTexture (); - Texture2D *getOnServerInstalledTexture (); - Texture2D *getStatusReadyTexture (); - Texture2D *getStatusNotReadyTexture (); - Texture2D *getStatusBRBTexture (); - Texture2D *getGameWinnerTexture (); + Texture2D *getBackgroundTexture(); + Texture2D *getFireTexture(); + Texture2D *getTeamColorTexture(); + Texture2D *getSnowTexture(); + Texture2D *getLogoTexture(); + Texture2D *getWaterSplashTexture(); + Texture2D *getCustomTexture(); + Texture2D *getButtonSmallTexture(); + Texture2D *getButtonBigTexture(); + Texture2D *getHorizontalLineTexture(); + Texture2D *getVerticalLineTexture(); + Texture2D *getCheckBoxTexture(); + Texture2D *getCheckedCheckBoxTexture(); + Texture2D *getNotOnServerTexture(); + Texture2D *getOnServerDifferentTexture(); + Texture2D *getOnServerTexture(); + Texture2D *getOnServerInstalledTexture(); + Texture2D *getStatusReadyTexture(); + Texture2D *getStatusNotReadyTexture(); + Texture2D *getStatusBRBTexture(); + Texture2D *getGameWinnerTexture(); - Texture2D *getHealthbarTexture (); - Texture2D *getHealthbarBackgroundTexture (); + Texture2D *getHealthbarTexture(); + Texture2D *getHealthbarBackgroundTexture(); - size_t getLogoTextureExtraCount (); - Texture2D *getLogoTextureExtra (int idx); + size_t getLogoTextureExtraCount(); + Texture2D *getLogoTextureExtra(int idx); - std::vector < Texture2D * >&getMiscTextureList (); + std::vector < Texture2D * >&getMiscTextureList(); - // Sounds and Music - StrSound *getIntroMusic (); - StrSound *getMenuMusic (); + // Sounds and Music + StrSound *getIntroMusic(); + StrSound *getMenuMusic(); - // When issue #63 was done - // - // and the PlaySoundFile class was created, - // these functions were kept because they were being called from many - // different places in the code base. Rather than trying to change - // all those locations, I made these three into "wrapper" functions. - // -andy5995 2018-02-22 - StaticSound *getClickSoundA (); - StaticSound *getClickSoundB (); - StaticSound *getClickSoundC (); + // When issue #63 was done + // + // and the PlaySoundFile class was created, + // these functions were kept because they were being called from many + // different places in the code base. Rather than trying to change + // all those locations, I made these three into "wrapper" functions. + // -andy5995 2018-02-22 + StaticSound *getClickSoundA(); + StaticSound *getClickSoundB(); + StaticSound *getClickSoundC(); - StaticSound *getWaterSound (); + StaticSound *getWaterSound(); - // Fonts - Font2D *getDisplayFont () const - { - return displayFont; - } - Font2D *getDisplayFontSmall () const - { - return displayFontSmall; - } - Font2D *getMenuFontNormal () const - { - return menuFontNormal; - } - Font2D *getMenuFontBig () const - { - return menuFontBig; - } - Font2D *getMenuFontVeryBig () const - { - return menuFontVeryBig; - } - Font2D *getConsoleFont () const - { - return consoleFont; - } + // Fonts + Font2D *getDisplayFont() const { + return displayFont; + } + Font2D *getDisplayFontSmall() const { + return displayFontSmall; + } + Font2D *getMenuFontNormal() const { + return menuFontNormal; + } + Font2D *getMenuFontBig() const { + return menuFontBig; + } + Font2D *getMenuFontVeryBig() const { + return menuFontVeryBig; + } + Font2D *getConsoleFont() const { + return consoleFont; + } - Font3D *getDisplayFont3D () const - { - return displayFont3D; - } - Font3D *getDisplayFontSmall3D () const - { - return displayFontSmall3D; - } - Font3D *getMenuFontNormal3D () const - { - return menuFontNormal3D; - } - Font3D *getMenuFontBig3D () const - { - return menuFontBig3D; - } - Font3D *getMenuFontVeryBig3D () const - { - return menuFontVeryBig3D; - } - Font3D *getConsoleFont3D () const - { - return consoleFont3D; - } + Font3D *getDisplayFont3D() const { + return displayFont3D; + } + Font3D *getDisplayFontSmall3D() const { + return displayFontSmall3D; + } + Font3D *getMenuFontNormal3D() const { + return menuFontNormal3D; + } + Font3D *getMenuFontBig3D() const { + return menuFontBig3D; + } + Font3D *getMenuFontVeryBig3D() const { + return menuFontVeryBig3D; + } + Font3D *getConsoleFont3D() const { + return consoleFont3D; + } - // Helper functions - string getMainMenuVideoFilename () const - { - return mainMenuVideoFilename; - } - bool hasMainMenuVideoFilename () const; - string getMainMenuVideoFilenameFallback () const - { - return mainMenuVideoFilenameFallback; - } - bool hasMainMenuVideoFilenameFallback () const; + // Helper functions + string getMainMenuVideoFilename() const { + return mainMenuVideoFilename; + } + bool hasMainMenuVideoFilename() const; + string getMainMenuVideoFilenameFallback() const { + return mainMenuVideoFilenameFallback; + } + bool hasMainMenuVideoFilenameFallback() const; - string getIntroVideoFilename () const - { - return introVideoFilename; - } - bool hasIntroVideoFilename () const; - string getIntroVideoFilenameFallback () const - { - return introVideoFilenameFallback; - } - bool hasIntroVideoFilenameFallback () const; + string getIntroVideoFilename() const { + return introVideoFilename; + } + bool hasIntroVideoFilename() const; + string getIntroVideoFilenameFallback() const { + return introVideoFilenameFallback; + } + bool hasIntroVideoFilenameFallback() const; - string getBattleEndVideoFilename (bool won) const - { - return won == - true ? battleEndWinVideoFilename : battleEndLoseVideoFilename; - } - //bool hasBattleEndVideoFilename(bool won) const; - string getBattleEndVideoFilenameFallback (bool won) const - { - return won == - true ? battleEndWinVideoFilenameFallback : - battleEndLoseVideoFilenameFallback; - } - bool hasBattleEndVideoFilenameFallback (bool won) const; + string getBattleEndVideoFilename(bool won) const { + return won == + true ? battleEndWinVideoFilename : battleEndLoseVideoFilename; + } + //bool hasBattleEndVideoFilename(bool won) const; + string getBattleEndVideoFilenameFallback(bool won) const { + return won == + true ? battleEndWinVideoFilenameFallback : + battleEndLoseVideoFilenameFallback; + } + bool hasBattleEndVideoFilenameFallback(bool won) const; - string getBattleEndMusicFilename (bool won) const - { - return won == - true ? battleEndWinMusicFilename : battleEndLoseMusicFilename; - } + string getBattleEndMusicFilename(bool won) const { + return won == + true ? battleEndWinMusicFilename : battleEndLoseMusicFilename; + } - void saveGameSettingsToFile (std::string fileName, - GameSettings * gameSettings, - int advancedIndex = 0); - bool loadGameSettingsFromFile (std::string fileName, - GameSettings * gameSettings); + void saveGameSettingsToFile(std::string fileName, + GameSettings * gameSettings, + int advancedIndex = 0); + bool loadGameSettingsFromFile(std::string fileName, + GameSettings * gameSettings); - void registerFontChangedCallback (std::string entityName, - FontChangedCallbackInterface * cb); - void unRegisterFontChangedCallback (std::string entityName); - private: + void registerFontChangedCallback(std::string entityName, + FontChangedCallbackInterface * cb); + void unRegisterFontChangedCallback(std::string entityName); + private: - CoreData (); + CoreData(); - int computeFontSize (int size); - void cleanupTexture (Texture2D ** texture); - void loadTextures (string data_path); - void loadSounds (string data_path); - void loadMusic (string data_path); - void loadIntroMedia (string data_path); - void loadMainMenuMedia (string data_path); - void loadBattleEndMedia (string data_path); + int computeFontSize(int size); + void cleanupTexture(Texture2D ** texture); + void loadTextures(string data_path); + void loadSounds(string data_path); + void loadMusic(string data_path); + void loadIntroMedia(string data_path); + void loadMainMenuMedia(string data_path); + void loadBattleEndMedia(string data_path); - string getDataPath (); - void loadTextureIfRequired (Texture2D ** tex, string data_path, - string uniqueFilePath, int texSystemId, - bool setMipMap, bool setAlpha, - bool loadUniqueFilePath, - bool compressionDisabled = false); + string getDataPath(); + void loadTextureIfRequired(Texture2D ** tex, string data_path, + string uniqueFilePath, int texSystemId, + bool setMipMap, bool setAlpha, + bool loadUniqueFilePath, + bool compressionDisabled = false); - void loadLogoTextureExtraIfRequired (); - void loadMiscTextureListIfRequired (); + void loadLogoTextureExtraIfRequired(); + void loadMiscTextureListIfRequired(); - void loadWaterSoundsIfRequired (); - void loadMusicIfRequired (); + void loadWaterSoundsIfRequired(); + void loadMusicIfRequired(); - void triggerFontChangedCallbacks (std::string fontUniqueId, - Font * font); - template < typename T > T * loadFont (Font * menuFontNormal, - string menuFontNameNormal, - int menuFontNameNormalSize, - string fontType, - string fontTypeFamily, - string fontUniqueKey); + void triggerFontChangedCallbacks(std::string fontUniqueId, + Font * font); + template < typename T > T * loadFont(Font * menuFontNormal, + string menuFontNameNormal, + int menuFontNameNormalSize, + string fontType, + string fontTypeFamily, + string fontUniqueKey); - }; + }; - class PlaySoundClip - { - private: - StaticSound iniPlaySound; - public: - StaticSound *getSound (const std::string& iniPlaySoundVal); - static const string sfxAttention; - static const string sfxHighlight; - static const string sfxNewServer; - static const string sfxMarker; - static const string sfxMenuClickA; - static const string sfxMenuClickB; - static const string sfxMenuClickC; - PlaySoundClip(); - ~PlaySoundClip(); + class PlaySoundClip { + private: + StaticSound iniPlaySound; + public: + StaticSound * getSound(const std::string& iniPlaySoundVal); + static const string sfxAttention; + static const string sfxHighlight; + static const string sfxNewServer; + static const string sfxMarker; + static const string sfxMenuClickA; + static const string sfxMenuClickB; + static const string sfxMenuClickC; + PlaySoundClip(); + ~PlaySoundClip(); - }; -}} //end namespace + }; + } +} //end namespace #endif diff --git a/source/glest_game/global/lang.cpp b/source/glest_game/global/lang.cpp index c90dc4dec..ea2ef291a 100644 --- a/source/glest_game/global/lang.cpp +++ b/source/glest_game/global/lang.cpp @@ -32,1048 +32,879 @@ using namespace std; using namespace Shared::Util; using namespace Shared::Platform; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - const char *DEFAULT_LANGUAGE = "english"; + const char *DEFAULT_LANGUAGE = "english"; -// ===================================================== -// class Lang -// ===================================================== + // ===================================================== + // class Lang + // ===================================================== - Lang::Lang () - { - language = ""; - is_utf8_language = false; - allowNativeLanguageTechtree = true; - techNameLoaded = ""; - } + Lang::Lang() { + language = ""; + is_utf8_language = false; + allowNativeLanguageTechtree = true; + techNameLoaded = ""; + } - Lang & Lang::getInstance () - { - static Lang lang; - return lang; - } + Lang & Lang::getInstance() { + static Lang lang; + return lang; + } - string Lang::getDefaultLanguage () const - { - return DEFAULT_LANGUAGE; - } + string Lang::getDefaultLanguage() const { + return DEFAULT_LANGUAGE; + } - void Lang::loadGameStrings (string uselanguage, bool loadFonts, - bool fallbackToDefault) - { - if (uselanguage.length () == 2 - || (uselanguage.length () == 5 && uselanguage[2] == '-')) - { - uselanguage = getLanguageFile (uselanguage); - } - bool languageChanged = (uselanguage != this->language); - this->language = uselanguage; - loadGameStringProperties (uselanguage, - gameStringsAllLanguages[this->language], true, - fallbackToDefault); + void Lang::loadGameStrings(string uselanguage, bool loadFonts, + bool fallbackToDefault) { + if (uselanguage.length() == 2 + || (uselanguage.length() == 5 && uselanguage[2] == '-')) { + uselanguage = getLanguageFile(uselanguage); + } + bool languageChanged = (uselanguage != this->language); + this->language = uselanguage; + loadGameStringProperties(uselanguage, + gameStringsAllLanguages[this->language], true, + fallbackToDefault); - if (languageChanged == true) - { - Font::resetToDefaults (); - Lang & lang = Lang::getInstance (); - if (lang.hasString ("FONT_BASE_SIZE")) - { - Font::baseSize = strToInt (lang.getString ("FONT_BASE_SIZE")); - } + if (languageChanged == true) { + Font::resetToDefaults(); + Lang & lang = Lang::getInstance(); + if (lang.hasString("FONT_BASE_SIZE")) { + Font::baseSize = strToInt(lang.getString("FONT_BASE_SIZE")); + } - if (lang.hasString ("FONT_SCALE_SIZE")) - { - Font::scaleFontValue = - strToFloat (lang.getString ("FONT_SCALE_SIZE")); - } - if (lang.hasString ("FONT_SCALE_CENTERH_FACTOR")) - { - Font::scaleFontValueCenterHFactor = - strToFloat (lang.getString ("FONT_SCALE_CENTERH_FACTOR")); - } + if (lang.hasString("FONT_SCALE_SIZE")) { + Font::scaleFontValue = + strToFloat(lang.getString("FONT_SCALE_SIZE")); + } + if (lang.hasString("FONT_SCALE_CENTERH_FACTOR")) { + Font::scaleFontValueCenterHFactor = + strToFloat(lang.getString("FONT_SCALE_CENTERH_FACTOR")); + } - if (lang.hasString ("FONT_CHARCOUNT")) - { - // 256 for English - // 30000 for Chinese - Font::charCount = strToInt (lang.getString ("FONT_CHARCOUNT")); - } - if (lang.hasString ("FONT_TYPENAME")) - { - Font::fontTypeName = lang.getString ("FONT_TYPENAME"); - } - if (lang.hasString ("FONT_CHARSET")) - { - // Example values: - // DEFAULT_CHARSET (English) = 1 - // GB2312_CHARSET (Chinese) = 134 - Shared::Platform::PlatformContextGl::charSet = - strToInt (lang.getString ("FONT_CHARSET")); - } - if (lang.hasString ("FONT_MULTIBYTE")) - { - Font::fontIsMultibyte = - strToBool (lang.getString ("FONT_MULTIBYTE")); - } + if (lang.hasString("FONT_CHARCOUNT")) { + // 256 for English + // 30000 for Chinese + Font::charCount = strToInt(lang.getString("FONT_CHARCOUNT")); + } + if (lang.hasString("FONT_TYPENAME")) { + Font::fontTypeName = lang.getString("FONT_TYPENAME"); + } + if (lang.hasString("FONT_CHARSET")) { + // Example values: + // DEFAULT_CHARSET (English) = 1 + // GB2312_CHARSET (Chinese) = 134 + Shared::Platform::PlatformContextGl::charSet = + strToInt(lang.getString("FONT_CHARSET")); + } + if (lang.hasString("FONT_MULTIBYTE")) { + Font::fontIsMultibyte = + strToBool(lang.getString("FONT_MULTIBYTE")); + } - if (lang.hasString ("FONT_RIGHTTOLEFT")) - { - Font::fontIsRightToLeft = - strToBool (lang.getString ("FONT_RIGHTTOLEFT")); - } + if (lang.hasString("FONT_RIGHTTOLEFT")) { + Font::fontIsRightToLeft = + strToBool(lang.getString("FONT_RIGHTTOLEFT")); + } - if (lang.hasString ("FONT_RIGHTTOLEFT_MIXED_SUPPORT")) - { - Font::fontSupportMixedRightToLeft = - strToBool (lang.getString ("FONT_RIGHTTOLEFT_MIXED_SUPPORT")); - } + if (lang.hasString("FONT_RIGHTTOLEFT_MIXED_SUPPORT")) { + Font::fontSupportMixedRightToLeft = + strToBool(lang.getString("FONT_RIGHTTOLEFT_MIXED_SUPPORT")); + } - if (lang.hasString ("MEGAGLEST_FONT")) - { - //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-japanese-gothic.ttf",0); // Japanese + if (lang.hasString("MEGAGLEST_FONT")) { + //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-japanese-gothic.ttf",0); // Japanese #if defined(WIN32) - string newEnvValue = - "MEGAGLEST_FONT=" + lang.getString ("MEGAGLEST_FONT"); - _putenv (newEnvValue.c_str ()); + string newEnvValue = + "MEGAGLEST_FONT=" + lang.getString("MEGAGLEST_FONT"); + _putenv(newEnvValue.c_str()); #else - setenv ("MEGAGLEST_FONT", - lang.getString ("MEGAGLEST_FONT").c_str (), 0); + setenv("MEGAGLEST_FONT", + lang.getString("MEGAGLEST_FONT").c_str(), 0); #endif - } + } - if (lang.hasString ("MEGAGLEST_FONT_FAMILY")) - { + if (lang.hasString("MEGAGLEST_FONT_FAMILY")) { #if defined(WIN32) - string newEnvValue = - "MEGAGLEST_FONT_FAMILY=" + - lang.getString ("MEGAGLEST_FONT_FAMILY"); - _putenv (newEnvValue.c_str ()); + string newEnvValue = + "MEGAGLEST_FONT_FAMILY=" + + lang.getString("MEGAGLEST_FONT_FAMILY"); + _putenv(newEnvValue.c_str()); #else - setenv ("MEGAGLEST_FONT_FAMILY", - lang.getString ("MEGAGLEST_FONT_FAMILY").c_str (), 0); + setenv("MEGAGLEST_FONT_FAMILY", + lang.getString("MEGAGLEST_FONT_FAMILY").c_str(), 0); #endif - } + } #if defined(WIN32) - // Win32 overrides for fonts (just in case they must be different) + // Win32 overrides for fonts (just in case they must be different) - if (lang.hasString ("FONT_BASE_SIZE_WINDOWS")) - { - // 256 for English - // 30000 for Chinese - Font::baseSize = - strToInt (lang.getString ("FONT_BASE_SIZE_WINDOWS")); - } + if (lang.hasString("FONT_BASE_SIZE_WINDOWS")) { + // 256 for English + // 30000 for Chinese + Font::baseSize = + strToInt(lang.getString("FONT_BASE_SIZE_WINDOWS")); + } - if (lang.hasString ("FONT_SCALE_SIZE_WINDOWS")) - { - Font::scaleFontValue = - strToFloat (lang.getString ("FONT_SCALE_SIZE_WINDOWS")); - } - if (lang.hasString ("FONT_SCALE_CENTERH_FACTOR_WINDOWS")) - { - Font::scaleFontValueCenterHFactor = - strToFloat (lang.getString ("FONT_SCALE_CENTERH_FACTOR_WINDOWS")); - } + if (lang.hasString("FONT_SCALE_SIZE_WINDOWS")) { + Font::scaleFontValue = + strToFloat(lang.getString("FONT_SCALE_SIZE_WINDOWS")); + } + if (lang.hasString("FONT_SCALE_CENTERH_FACTOR_WINDOWS")) { + Font::scaleFontValueCenterHFactor = + strToFloat(lang.getString("FONT_SCALE_CENTERH_FACTOR_WINDOWS")); + } - if (lang.hasString ("FONT_HEIGHT_TEXT_WINDOWS")) - { - Font::langHeightText = - lang.getString ("FONT_HEIGHT_TEXT_WINDOWS", - Font::langHeightText.c_str ()); - } + if (lang.hasString("FONT_HEIGHT_TEXT_WINDOWS")) { + Font::langHeightText = + lang.getString("FONT_HEIGHT_TEXT_WINDOWS", + Font::langHeightText.c_str()); + } - if (lang.hasString ("FONT_CHARCOUNT_WINDOWS")) - { - // 256 for English - // 30000 for Chinese - Font::charCount = - strToInt (lang.getString ("FONT_CHARCOUNT_WINDOWS")); - } - if (lang.hasString ("FONT_TYPENAME_WINDOWS")) - { - Font::fontTypeName = lang.getString ("FONT_TYPENAME_WINDOWS"); - } - if (lang.hasString ("FONT_CHARSET_WINDOWS")) - { - // Example values: - // DEFAULT_CHARSET (English) = 1 - // GB2312_CHARSET (Chinese) = 134 - Shared::Platform::PlatformContextGl::charSet = - strToInt (lang.getString ("FONT_CHARSET_WINDOWS")); - } - if (lang.hasString ("FONT_MULTIBYTE_WINDOWS")) - { - Font::fontIsMultibyte = - strToBool (lang.getString ("FONT_MULTIBYTE_WINDOWS")); - } - if (lang.hasString ("FONT_RIGHTTOLEFT_WINDOWS")) - { - Font::fontIsRightToLeft = - strToBool (lang.getString ("FONT_RIGHTTOLEFT_WINDOWS")); - } + if (lang.hasString("FONT_CHARCOUNT_WINDOWS")) { + // 256 for English + // 30000 for Chinese + Font::charCount = + strToInt(lang.getString("FONT_CHARCOUNT_WINDOWS")); + } + if (lang.hasString("FONT_TYPENAME_WINDOWS")) { + Font::fontTypeName = lang.getString("FONT_TYPENAME_WINDOWS"); + } + if (lang.hasString("FONT_CHARSET_WINDOWS")) { + // Example values: + // DEFAULT_CHARSET (English) = 1 + // GB2312_CHARSET (Chinese) = 134 + Shared::Platform::PlatformContextGl::charSet = + strToInt(lang.getString("FONT_CHARSET_WINDOWS")); + } + if (lang.hasString("FONT_MULTIBYTE_WINDOWS")) { + Font::fontIsMultibyte = + strToBool(lang.getString("FONT_MULTIBYTE_WINDOWS")); + } + if (lang.hasString("FONT_RIGHTTOLEFT_WINDOWS")) { + Font::fontIsRightToLeft = + strToBool(lang.getString("FONT_RIGHTTOLEFT_WINDOWS")); + } - if (lang.hasString ("MEGAGLEST_FONT_WINDOWS")) - { - //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-japanese-gothic.ttf",0); // Japanese - string newEnvValue = - "MEGAGLEST_FONT=" + lang.getString ("MEGAGLEST_FONT_WINDOWS"); - _putenv (newEnvValue.c_str ()); - } + if (lang.hasString("MEGAGLEST_FONT_WINDOWS")) { + //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-japanese-gothic.ttf",0); // Japanese + string newEnvValue = + "MEGAGLEST_FONT=" + lang.getString("MEGAGLEST_FONT_WINDOWS"); + _putenv(newEnvValue.c_str()); + } - // end win32 + // end win32 #endif - if (lang.hasString ("ALLOWED_SPECIAL_KEYS", "", false)) - { - string allowedKeys = lang.getString ("ALLOWED_SPECIAL_KEYS"); - Window::addAllowedKeys (allowedKeys); - } - else - { - Window::clearAllowedKeys (); - } - - if (loadFonts == true) - { - CoreData & coreData = CoreData::getInstance (); - coreData.loadFonts (); - } - } - } - - void Lang::loadGameStringProperties (string uselanguage, - Properties & properties, - bool fileMustExist, - bool fallbackToDefault) - { - properties.clear (); - string data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - //string languageFile = data_path + "data/lang/" + uselanguage + ".lng"; - string languageFile = - getGameCustomCoreDataPath (data_path, - "data/lang/" + uselanguage + ".lng"); - if (fileMustExist == false && fileExists (languageFile) == false) - { - return; - } - else if (fileExists (languageFile) == false - && fallbackToDefault == true) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] path = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - languageFile.c_str ()); - //throw megaglest_runtime_error("File NOT FOUND, can't open file: [" + languageFile + "]"); - printf - ("Language file NOT FOUND, can't open file: [%s] switching to default language: %s\n", - languageFile.c_str (), DEFAULT_LANGUAGE); - - languageFile = - getGameCustomCoreDataPath (data_path, - "data/lang/" + - string (DEFAULT_LANGUAGE) + ".lng"); - } - is_utf8_language = valid_utf8_file (languageFile.c_str ()); - properties.load (languageFile); - } - -//bool Lang::isUTF8Language() const { -// return is_utf8_language; -//} - - void Lang::loadScenarioStrings (string scenarioDir, string scenarioName, - bool isTutorial) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] scenarioDir = [%s] scenarioName = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - scenarioDir.c_str (), - scenarioName.c_str ()); - - //printf("Loading scenario scenarioDir [%s] scenarioName [%s]\n",scenarioDir.c_str(),scenarioName.c_str()); - - // First try to find scenario lng file in userdata - Config & config = Config::getInstance (); - vector < string > scenarioPaths; - if (isTutorial == false) - { - scenarioPaths = config.getPathListForType (ptScenarios); - } - else - { - scenarioPaths = config.getPathListForType (ptTutorials); - } - if (scenarioPaths.size () > 1) - { - string & scenarioPath = scenarioPaths[1]; - endPathWithSlash (scenarioPath); - - string currentPath = scenarioPath; - endPathWithSlash (currentPath); - string scenarioFolder = currentPath + scenarioName + "/"; - string path = scenarioFolder + scenarioName + "_" + language + ".lng"; - - //try to load the current language first - if (fileExists (path)) - { - scenarioDir = scenarioPath; - } - } - - string currentPath = scenarioDir; - endPathWithSlash (currentPath); - string scenarioFolder = currentPath + scenarioName + "/"; - string path = scenarioFolder + scenarioName + "_" + language + ".lng"; - if (EndsWith (scenarioDir, ".xml") == true) - { - scenarioFolder = extractDirectoryPathFromFile (scenarioDir); - path = scenarioFolder + scenarioName + "_" + language + ".lng"; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] path = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - path.c_str ()); - } - - scenarioStrings.clear (); - - //try to load the current language first - if (fileExists (path)) - { - //printf("#2 Loading scenario path [%s]\n",path.c_str()); - - scenarioStrings.load (path); - } - else - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] path not found [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - path.c_str ()); - - //try english otherwise - path = scenarioFolder + scenarioName + "_english.lng"; - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] path = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - path.c_str ()); - - if (fileExists (path)) - { - //printf("#3 Loading scenario path [%s]\n",path.c_str()); - - scenarioStrings.load (path); - } - } - } - - bool Lang::loadTechTreeStrings (string techTree, bool forceLoad) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] techTree = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - techTree.c_str ()); - - //printf("Line: %d techTree = %s forceLoad = %d\n",__LINE__,techTree.c_str(),forceLoad); - - if (forceLoad == false && techTree == techNameLoaded) - { - return true; - } - - bool foundTranslation = false; - - string currentPath = ""; - Config & config = Config::getInstance (); - vector < string > techPaths = config.getPathListForType (ptTechs); - for (int idx = 0; idx < (int) techPaths.size (); idx++) - { - string & techPath = techPaths[idx]; - endPathWithSlash (techPath); - - if (folderExists (techPath + techTree) == true) - { - currentPath = techPath; - endPathWithSlash (currentPath); - break; - } - } - - string techTreeFolder = currentPath + techTree + "/"; - string path = - techTreeFolder + "lang/" + techTree + "_" + language + ".lng"; - string pathDefault = - techTreeFolder + "lang/" + techTree + "_default.lng"; - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] path = [%s] pathDefault = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - path.c_str (), pathDefault.c_str ()); - - //techTreeStrings.clear(); - //techTreeStringsDefault.clear(); - - //printf("Line: %d techTree = %s this->language = %s forceLoad = %d path = %s\n",__LINE__,techTree.c_str(),this->language.c_str(),forceLoad,path.c_str()); - - //try to load the current language first - if (fileExists (path)) - { - foundTranslation = true; - if (forceLoad == true || - path != - techTreeStringsAllLanguages[techTree][this->language].getpath ()) - { - - //printf("Line: %d techTree = %s forceLoad = %d path = %s\n",__LINE__,techTree.c_str(),forceLoad,path.c_str()); - - techTreeStringsAllLanguages[techTree][this->language].load (path); - techNameLoaded = techTree; - } - else if (path == - techTreeStringsAllLanguages[techTree][this->language]. - getpath () && techTree != techNameLoaded) - { - techNameLoaded = techTree; - } - } - else - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] path not found [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - path.c_str ()); - - //try english otherwise - string default_language = "english"; - path = - techTreeFolder + "lang/" + techTree + "_" + default_language + - ".lng"; - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] path = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - path.c_str ()); - - //printf("Line: %d techTree = %s forceLoad = %d path = %s\n",__LINE__,techTree.c_str(),forceLoad,path.c_str()); - - if (fileExists (path)) - { - foundTranslation = true; - if (forceLoad == true || - path != - techTreeStringsAllLanguages[techTree][default_language]. - getpath ()) - { - //printf("Line: %d techTree = %s forceLoad = %d path = %s\n",__LINE__,techTree.c_str(),forceLoad,path.c_str()); - - techTreeStringsAllLanguages[techTree][default_language]. - load (path); - techNameLoaded = techTree; - } - else if (path == - techTreeStringsAllLanguages[techTree][default_language]. - getpath () && techTree != techNameLoaded) - { - techNameLoaded = techTree; - } - } - } - - if (fileExists (pathDefault)) - { - foundTranslation = true; - string default_language = "default"; - - //printf("Line: %d techTree = %s forceLoad = %d default_language = %s\n",__LINE__,techTree.c_str(),forceLoad,default_language.c_str()); - - if (forceLoad == true || - pathDefault != - techTreeStringsAllLanguages[techTree][default_language]. - getpath ()) - { - //printf("Line: %d techTree = %s forceLoad = %d pathDefault = %s\n",__LINE__,techTree.c_str(),forceLoad,pathDefault.c_str()); - - techTreeStringsAllLanguages[techTree][default_language]. - load (pathDefault); - techNameLoaded = techTree; - } - else if (pathDefault == - techTreeStringsAllLanguages[techTree][default_language]. - getpath () && techTree != techNameLoaded) - { - techNameLoaded = techTree; - } - } - - return foundTranslation; - } - - void Lang::loadTilesetStrings (string tileset) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] tileset = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - tileset.c_str ()); - - string currentPath = ""; - Config & config = Config::getInstance (); - vector < string > tilesetPaths = config.getPathListForType (ptTilesets); - for (int idx = 0; idx < (int) tilesetPaths.size (); idx++) - { - string & tilesetPath = tilesetPaths[idx]; - endPathWithSlash (tilesetPath); - - //printf("tilesetPath [%s]\n",tilesetPath.c_str()); - - if (folderExists (tilesetPath + tileset) == true) - { - currentPath = tilesetPath; - endPathWithSlash (currentPath); - break; - } - } - - string tilesetFolder = currentPath + tileset + "/"; - string path = - tilesetFolder + "lang/" + tileset + "_" + language + ".lng"; - string pathDefault = tilesetFolder + "lang/" + tileset + "_default.lng"; - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] path = [%s] pathDefault = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - path.c_str (), pathDefault.c_str ()); - - tilesetStrings.clear (); - tilesetStringsDefault.clear (); - - //try to load the current language first - if (fileExists (path)) - { - tilesetStrings.load (path); - } - else - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] path not found [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - path.c_str ()); - - //try english otherwise - path = tilesetFolder + "lang/" + tileset + "_english.lng"; - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] path = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - path.c_str ()); - - if (fileExists (path)) - { - tilesetStrings.load (path); - } - } - - if (fileExists (pathDefault)) - { - tilesetStringsDefault.load (pathDefault); - } - } - - bool Lang::hasString (const string & s, string uselanguage, - bool fallbackToDefault) - { - bool result = false; - try - { - if (uselanguage != "") - { - //printf("#a fallbackToDefault = %d [%s] uselanguage [%s] DEFAULT_LANGUAGE [%s] this->language [%s]\n",fallbackToDefault,s.c_str(),uselanguage.c_str(),DEFAULT_LANGUAGE,this->language.c_str()); - if (gameStringsAllLanguages.find (uselanguage) == - gameStringsAllLanguages.end ()) - { - loadGameStringProperties (uselanguage, - gameStringsAllLanguages[uselanguage], - false); - } - //string result2 = otherLanguageStrings[uselanguage].getString(s); - gameStringsAllLanguages[uselanguage].getString (s); - //printf("#b result2 [%s]\n",result2.c_str()); - - result = true; - } - else - { - //string result2 = strings.getString(s); - gameStringsAllLanguages[this->language].getString (s); - result = true; - } - } - catch (exception & ex) - { - if (gameStringsAllLanguages[this->language].getpath () != "") - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s] for uselanguage [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - ex.what (), uselanguage.c_str ()); - } - - //printf("#1 fallbackToDefault = %d [%s] uselanguage [%s] DEFAULT_LANGUAGE [%s] this->language [%s]\n",fallbackToDefault,s.c_str(),uselanguage.c_str(),DEFAULT_LANGUAGE,this->language.c_str()); - if (fallbackToDefault == true && uselanguage != DEFAULT_LANGUAGE - && this->language != DEFAULT_LANGUAGE) - { - result = hasString (s, DEFAULT_LANGUAGE, false); - } - else - { - - } - } - return result; - } - - bool Lang::isLanguageLocal (string compareLanguage) const - { - return (compareLanguage == language); - } - - string Lang::parseResult (const string & key, const string & value) - { - if (value != "$USE_DEFAULT_LANGUAGE_VALUE") - { - return value; - } - string result = Lang::getString (key, DEFAULT_LANGUAGE); - return result; - } - string Lang::getString (const string & s, string uselanguage, - bool fallbackToDefault) - { - try - { - string result = ""; - - if (uselanguage != "") - { - if (gameStringsAllLanguages.find (uselanguage) == - gameStringsAllLanguages.end ()) - { - loadGameStringProperties (uselanguage, - gameStringsAllLanguages[uselanguage], - false); - } - result = gameStringsAllLanguages[uselanguage].getString (s); - replaceAll (result, "\\n", "\n"); - } - else - { - result = gameStringsAllLanguages[this->language].getString (s); - replaceAll (result, "\\n", "\n"); - } - - return parseResult (s, result);; - } - catch (exception & ex) - { - if (gameStringsAllLanguages[this->language].getpath () != "") - { - if (fallbackToDefault == false || SystemFlags::VERBOSE_MODE_ENABLED) - { - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s] uselanguage [%s] text [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - ex.what (), uselanguage.c_str (), - s.c_str ()); - } - } - } - - //printf("#2 fallbackToDefault = %d [%s] uselanguage [%s] DEFAULT_LANGUAGE [%s] this->language [%s]\n",fallbackToDefault,s.c_str(),uselanguage.c_str(),DEFAULT_LANGUAGE,this->language.c_str()); - - //if(fallbackToDefault == true && uselanguage != DEFAULT_LANGUAGE && this->language != DEFAULT_LANGUAGE) { - if (uselanguage != DEFAULT_LANGUAGE - && this->language != DEFAULT_LANGUAGE) - { - return getString (s, DEFAULT_LANGUAGE, false); - } - - //return "???" + s + "???"; - } - return "???" + s + "???"; - } - - string Lang::getScenarioString (const string & s) - { - try - { - string result = scenarioStrings.getString (s); - replaceAll (result, "\\n", "\n"); - return result; - } - catch (exception & ex) - { - if (scenarioStrings.getpath () != "") - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - ex.what ()); - } - return "???" + s + "???"; - } - } - - bool Lang::hasScenarioString (const string & s) - { - bool result = false; - try - { - scenarioStrings.getString (s); - result = true; - } - catch (exception & ex) - { - if (scenarioStrings.getpath () != "") - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - ex.what ()); - } - } - return result; - } - - string Lang::getTechTreeString (const string & s, - const char *defaultValue) - { - try - { - string result = ""; - string default_language = "default"; - - //printf("Line: %d techNameLoaded = %s s = %s this->language = %s\n",__LINE__,techNameLoaded.c_str(),s.c_str(),this->language.c_str()); - - if (allowNativeLanguageTechtree == true && - (techTreeStringsAllLanguages[techNameLoaded][this->language]. - hasString (s) == true || defaultValue == NULL)) - { - if (techTreeStringsAllLanguages[techNameLoaded][this->language]. - hasString (s) == false - && - techTreeStringsAllLanguages[techNameLoaded][default_language]. - hasString (s) == true) - { - - //printf("Line: %d techNameLoaded = %s s = %s this->language = %s\n",__LINE__,techNameLoaded.c_str(),s.c_str(),this->language.c_str()); - - result = - techTreeStringsAllLanguages[techNameLoaded][default_language]. - getString (s); - } - else - { - - //printf("Line: %d techNameLoaded = %s s = %s this->language = %s\n",__LINE__,techNameLoaded.c_str(),s.c_str(),this->language.c_str()); - - result = - techTreeStringsAllLanguages[techNameLoaded][this->language]. - getString (s); - } - } - else if (allowNativeLanguageTechtree == true && - techTreeStringsAllLanguages[techNameLoaded] - [default_language].hasString (s) == true) - { - - //printf("Line: %d techNameLoaded = %s s = %s this->language = %s\n",__LINE__,techNameLoaded.c_str(),s.c_str(),this->language.c_str()); - - result = - techTreeStringsAllLanguages[techNameLoaded][default_language]. - getString (s); - } - else if (defaultValue != NULL) - { - result = defaultValue; - } - replaceAll (result, "\\n", "\n"); - return result; - } - catch (exception & ex) - { - if (techTreeStringsAllLanguages[techNameLoaded][this->language]. - getpath () != "") - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - ex.what ()); - } - //return "???" + s + "???"; - } - return "???" + s + "???"; - } - - string Lang::getTilesetString (const string & s, const char *defaultValue) - { - try - { - string result = ""; - - if (tilesetStrings.hasString (s) == true || defaultValue == NULL) - { - if (tilesetStrings.hasString (s) == false - && tilesetStringsDefault.hasString (s) == true) - { - result = tilesetStringsDefault.getString (s); - } - else - { - result = tilesetStrings.getString (s); - } - } - else if (tilesetStringsDefault.hasString (s) == true) - { - result = tilesetStringsDefault.getString (s); - } - else if (defaultValue != NULL) - { - result = defaultValue; - } - replaceAll (result, "\\n", "\n"); - return result; - } - catch (exception & ex) - { - if (tilesetStrings.getpath () != "") - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - ex.what ()); - } - //return "???" + s + "???"; - } - return "???" + s + "???"; - } - - bool Lang::fileMatchesISO630Code (string uselanguage, - string testLanguageFile) - { - bool result = false; - Properties stringsTest; - stringsTest.load (testLanguageFile); - - try - { - string iso639 = stringsTest.getString ("ISO639-1"); - if (iso639 == uselanguage) - { - result = true; - } - } - //catch(const exception &ex) { - catch ( ...) - { - } - - return result; - } - - string Lang::getLanguageFile (string uselanguage) - { - bool foundMatch = false; - string result = uselanguage; - - string data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - - vector < string > langResults; - string userDataPath = getGameCustomCoreDataPath (data_path, ""); - findAll (userDataPath + "data/lang/*.lng", langResults, true, false); - for (unsigned int i = 0; i < langResults.size () && foundMatch == false; - ++i) - { - string testLanguageFile = - userDataPath + "data/lang/" + langResults[i] + ".lng"; - foundMatch = fileMatchesISO630Code (uselanguage, testLanguageFile); - if (foundMatch == true) - { - result = langResults[i]; - } - } - if (foundMatch == false) - { - langResults.clear (); - findAll (data_path + "data/lang/*.lng", langResults, true); - for (unsigned int i = 0; - i < langResults.size () && foundMatch == false; ++i) - { - string testLanguageFile = - data_path + "data/lang/" + langResults[i] + ".lng"; - foundMatch = fileMatchesISO630Code (uselanguage, testLanguageFile); - if (foundMatch == true) - { - result = langResults[i]; - } - } - } - return result; - } - - string Lang::getNativeLanguageName (string uselanguage, - string testLanguageFile) - { - string result = uselanguage; - - static map < string, string > cachedNativeLanguageNames; - if (cachedNativeLanguageNames.find (testLanguageFile) != - cachedNativeLanguageNames.end ()) - { - result = cachedNativeLanguageNames[testLanguageFile]; - } - else - { - Properties stringsTest; - stringsTest.load (testLanguageFile); - - try - { - result = stringsTest.getString ("NativeLanguageName"); - cachedNativeLanguageNames[testLanguageFile] = result; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Caching native language name for [%s] = [%s]\n", - testLanguageFile.c_str (), result.c_str ()); - } - catch (const exception & ex) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("ERROR Caching native language name for [%s] msg: [%s]\n", - testLanguageFile.c_str (), ex.what ()); - } - catch ( ...) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("ERROR Caching native language name for [%s] msg: [UNKNOWN]\n", - testLanguageFile.c_str ()); - } - } - - return result; - } - - pair < string, - string > Lang::getNavtiveNameFromLanguageName (string langName) - { - pair < string, string > result; - - //printf("looking for language [%s]\n",langName.c_str()); - - map < string, string > nativeList = - Lang::getDiscoveredLanguageList (true); - map < string, string >::iterator iterMap = nativeList.find (langName); - if (iterMap != nativeList.end ()) - { - result = make_pair (iterMap->second, iterMap->first); - } - return result; - } - - map < string, - string > Lang::getDiscoveredLanguageList (bool searchKeyIsLangName) - { - map < string, string > result; - - string data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - string userDataPath = getGameCustomCoreDataPath (data_path, ""); - - vector < string > langResults; - findAll (userDataPath + "data/lang/*.lng", langResults, true, false); - for (unsigned int i = 0; i < langResults.size (); ++i) - { - string testLanguage = langResults[i]; - string testLanguageFile = - userDataPath + "data/lang/" + testLanguage + ".lng"; - string nativeName = - getNativeLanguageName (testLanguage, testLanguageFile); - if (searchKeyIsLangName == false) - { - result[nativeName] = testLanguage; - } - else - { - result[testLanguage] = nativeName; - } - } - - vector < string > langResults2; - findAll (data_path + "data/lang/*.lng", langResults2, true); - if (langResults2.empty () && langResults.empty ()) - { - throw megaglest_runtime_error ("There are no lang files"); - } - for (unsigned int i = 0; i < langResults2.size (); ++i) - { - string testLanguage = langResults2[i]; - if (std:: - find (langResults.begin (), langResults.end (), - testLanguage) == langResults.end ()) - { - langResults.push_back (testLanguage); - - string testLanguageFile = - data_path + "data/lang/" + testLanguage + ".lng"; - string nativeName = - getNativeLanguageName (testLanguage, testLanguageFile); - if (searchKeyIsLangName == false) - { - result[nativeName] = testLanguage; - } - else - { - result[testLanguage] = nativeName; - } - } - } - - return result; - } - - } + if (lang.hasString("ALLOWED_SPECIAL_KEYS", "", false)) { + string allowedKeys = lang.getString("ALLOWED_SPECIAL_KEYS"); + Window::addAllowedKeys(allowedKeys); + } else { + Window::clearAllowedKeys(); + } + + if (loadFonts == true) { + CoreData & coreData = CoreData::getInstance(); + coreData.loadFonts(); + } + } + } + + void Lang::loadGameStringProperties(string uselanguage, + Properties & properties, + bool fileMustExist, + bool fallbackToDefault) { + properties.clear(); + string data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + //string languageFile = data_path + "data/lang/" + uselanguage + ".lng"; + string languageFile = + getGameCustomCoreDataPath(data_path, + "data/lang/" + uselanguage + ".lng"); + if (fileMustExist == false && fileExists(languageFile) == false) { + return; + } else if (fileExists(languageFile) == false + && fallbackToDefault == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] path = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + languageFile.c_str()); + //throw megaglest_runtime_error("File NOT FOUND, can't open file: [" + languageFile + "]"); + printf + ("Language file NOT FOUND, can't open file: [%s] switching to default language: %s\n", + languageFile.c_str(), DEFAULT_LANGUAGE); + + languageFile = + getGameCustomCoreDataPath(data_path, + "data/lang/" + + string(DEFAULT_LANGUAGE) + ".lng"); + } + is_utf8_language = valid_utf8_file(languageFile.c_str()); + properties.load(languageFile); + } + + //bool Lang::isUTF8Language() const { + // return is_utf8_language; + //} + + void Lang::loadScenarioStrings(string scenarioDir, string scenarioName, + bool isTutorial) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] scenarioDir = [%s] scenarioName = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + scenarioDir.c_str(), + scenarioName.c_str()); + + //printf("Loading scenario scenarioDir [%s] scenarioName [%s]\n",scenarioDir.c_str(),scenarioName.c_str()); + + // First try to find scenario lng file in userdata + Config & config = Config::getInstance(); + vector < string > scenarioPaths; + if (isTutorial == false) { + scenarioPaths = config.getPathListForType(ptScenarios); + } else { + scenarioPaths = config.getPathListForType(ptTutorials); + } + if (scenarioPaths.size() > 1) { + string & scenarioPath = scenarioPaths[1]; + endPathWithSlash(scenarioPath); + + string currentPath = scenarioPath; + endPathWithSlash(currentPath); + string scenarioFolder = currentPath + scenarioName + "/"; + string path = scenarioFolder + scenarioName + "_" + language + ".lng"; + + //try to load the current language first + if (fileExists(path)) { + scenarioDir = scenarioPath; + } + } + + string currentPath = scenarioDir; + endPathWithSlash(currentPath); + string scenarioFolder = currentPath + scenarioName + "/"; + string path = scenarioFolder + scenarioName + "_" + language + ".lng"; + if (EndsWith(scenarioDir, ".xml") == true) { + scenarioFolder = extractDirectoryPathFromFile(scenarioDir); + path = scenarioFolder + scenarioName + "_" + language + ".lng"; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] path = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + path.c_str()); + } + + scenarioStrings.clear(); + + //try to load the current language first + if (fileExists(path)) { + //printf("#2 Loading scenario path [%s]\n",path.c_str()); + + scenarioStrings.load(path); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] path not found [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + path.c_str()); + + //try english otherwise + path = scenarioFolder + scenarioName + "_english.lng"; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] path = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + path.c_str()); + + if (fileExists(path)) { + //printf("#3 Loading scenario path [%s]\n",path.c_str()); + + scenarioStrings.load(path); + } + } + } + + bool Lang::loadTechTreeStrings(string techTree, bool forceLoad) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] techTree = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + techTree.c_str()); + + //printf("Line: %d techTree = %s forceLoad = %d\n",__LINE__,techTree.c_str(),forceLoad); + + if (forceLoad == false && techTree == techNameLoaded) { + return true; + } + + bool foundTranslation = false; + + string currentPath = ""; + Config & config = Config::getInstance(); + vector < string > techPaths = config.getPathListForType(ptTechs); + for (int idx = 0; idx < (int) techPaths.size(); idx++) { + string & techPath = techPaths[idx]; + endPathWithSlash(techPath); + + if (folderExists(techPath + techTree) == true) { + currentPath = techPath; + endPathWithSlash(currentPath); + break; + } + } + + string techTreeFolder = currentPath + techTree + "/"; + string path = + techTreeFolder + "lang/" + techTree + "_" + language + ".lng"; + string pathDefault = + techTreeFolder + "lang/" + techTree + "_default.lng"; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] path = [%s] pathDefault = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + path.c_str(), pathDefault.c_str()); + + //techTreeStrings.clear(); + //techTreeStringsDefault.clear(); + + //printf("Line: %d techTree = %s this->language = %s forceLoad = %d path = %s\n",__LINE__,techTree.c_str(),this->language.c_str(),forceLoad,path.c_str()); + + //try to load the current language first + if (fileExists(path)) { + foundTranslation = true; + if (forceLoad == true || + path != + techTreeStringsAllLanguages[techTree][this->language].getpath()) { + + //printf("Line: %d techTree = %s forceLoad = %d path = %s\n",__LINE__,techTree.c_str(),forceLoad,path.c_str()); + + techTreeStringsAllLanguages[techTree][this->language].load(path); + techNameLoaded = techTree; + } else if (path == + techTreeStringsAllLanguages[techTree][this->language]. + getpath() && techTree != techNameLoaded) { + techNameLoaded = techTree; + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] path not found [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + path.c_str()); + + //try english otherwise + string default_language = "english"; + path = + techTreeFolder + "lang/" + techTree + "_" + default_language + + ".lng"; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] path = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + path.c_str()); + + //printf("Line: %d techTree = %s forceLoad = %d path = %s\n",__LINE__,techTree.c_str(),forceLoad,path.c_str()); + + if (fileExists(path)) { + foundTranslation = true; + if (forceLoad == true || + path != + techTreeStringsAllLanguages[techTree][default_language]. + getpath()) { + //printf("Line: %d techTree = %s forceLoad = %d path = %s\n",__LINE__,techTree.c_str(),forceLoad,path.c_str()); + + techTreeStringsAllLanguages[techTree][default_language]. + load(path); + techNameLoaded = techTree; + } else if (path == + techTreeStringsAllLanguages[techTree][default_language]. + getpath() && techTree != techNameLoaded) { + techNameLoaded = techTree; + } + } + } + + if (fileExists(pathDefault)) { + foundTranslation = true; + string default_language = "default"; + + //printf("Line: %d techTree = %s forceLoad = %d default_language = %s\n",__LINE__,techTree.c_str(),forceLoad,default_language.c_str()); + + if (forceLoad == true || + pathDefault != + techTreeStringsAllLanguages[techTree][default_language]. + getpath()) { + //printf("Line: %d techTree = %s forceLoad = %d pathDefault = %s\n",__LINE__,techTree.c_str(),forceLoad,pathDefault.c_str()); + + techTreeStringsAllLanguages[techTree][default_language]. + load(pathDefault); + techNameLoaded = techTree; + } else if (pathDefault == + techTreeStringsAllLanguages[techTree][default_language]. + getpath() && techTree != techNameLoaded) { + techNameLoaded = techTree; + } + } + + return foundTranslation; + } + + void Lang::loadTilesetStrings(string tileset) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] tileset = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + tileset.c_str()); + + string currentPath = ""; + Config & config = Config::getInstance(); + vector < string > tilesetPaths = config.getPathListForType(ptTilesets); + for (int idx = 0; idx < (int) tilesetPaths.size(); idx++) { + string & tilesetPath = tilesetPaths[idx]; + endPathWithSlash(tilesetPath); + + //printf("tilesetPath [%s]\n",tilesetPath.c_str()); + + if (folderExists(tilesetPath + tileset) == true) { + currentPath = tilesetPath; + endPathWithSlash(currentPath); + break; + } + } + + string tilesetFolder = currentPath + tileset + "/"; + string path = + tilesetFolder + "lang/" + tileset + "_" + language + ".lng"; + string pathDefault = tilesetFolder + "lang/" + tileset + "_default.lng"; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] path = [%s] pathDefault = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + path.c_str(), pathDefault.c_str()); + + tilesetStrings.clear(); + tilesetStringsDefault.clear(); + + //try to load the current language first + if (fileExists(path)) { + tilesetStrings.load(path); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] path not found [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + path.c_str()); + + //try english otherwise + path = tilesetFolder + "lang/" + tileset + "_english.lng"; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] path = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + path.c_str()); + + if (fileExists(path)) { + tilesetStrings.load(path); + } + } + + if (fileExists(pathDefault)) { + tilesetStringsDefault.load(pathDefault); + } + } + + bool Lang::hasString(const string & s, string uselanguage, + bool fallbackToDefault) { + bool result = false; + try { + if (uselanguage != "") { + //printf("#a fallbackToDefault = %d [%s] uselanguage [%s] DEFAULT_LANGUAGE [%s] this->language [%s]\n",fallbackToDefault,s.c_str(),uselanguage.c_str(),DEFAULT_LANGUAGE,this->language.c_str()); + if (gameStringsAllLanguages.find(uselanguage) == + gameStringsAllLanguages.end()) { + loadGameStringProperties(uselanguage, + gameStringsAllLanguages[uselanguage], + false); + } + //string result2 = otherLanguageStrings[uselanguage].getString(s); + gameStringsAllLanguages[uselanguage].getString(s); + //printf("#b result2 [%s]\n",result2.c_str()); + + result = true; + } else { + //string result2 = strings.getString(s); + gameStringsAllLanguages[this->language].getString(s); + result = true; + } + } catch (exception & ex) { + if (gameStringsAllLanguages[this->language].getpath() != "") { + if (SystemFlags::VERBOSE_MODE_ENABLED) + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s] for uselanguage [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + ex.what(), uselanguage.c_str()); + } + + //printf("#1 fallbackToDefault = %d [%s] uselanguage [%s] DEFAULT_LANGUAGE [%s] this->language [%s]\n",fallbackToDefault,s.c_str(),uselanguage.c_str(),DEFAULT_LANGUAGE,this->language.c_str()); + if (fallbackToDefault == true && uselanguage != DEFAULT_LANGUAGE + && this->language != DEFAULT_LANGUAGE) { + result = hasString(s, DEFAULT_LANGUAGE, false); + } else { + + } + } + return result; + } + + bool Lang::isLanguageLocal(string compareLanguage) const { + return (compareLanguage == language); + } + + string Lang::parseResult(const string & key, const string & value) { + if (value != "$USE_DEFAULT_LANGUAGE_VALUE") { + return value; + } + string result = Lang::getString(key, DEFAULT_LANGUAGE); + return result; + } + string Lang::getString(const string & s, string uselanguage, + bool fallbackToDefault) { + try { + string result = ""; + + if (uselanguage != "") { + if (gameStringsAllLanguages.find(uselanguage) == + gameStringsAllLanguages.end()) { + loadGameStringProperties(uselanguage, + gameStringsAllLanguages[uselanguage], + false); + } + result = gameStringsAllLanguages[uselanguage].getString(s); + replaceAll(result, "\\n", "\n"); + } else { + result = gameStringsAllLanguages[this->language].getString(s); + replaceAll(result, "\\n", "\n"); + } + + return parseResult(s, result);; + } catch (exception & ex) { + if (gameStringsAllLanguages[this->language].getpath() != "") { + if (fallbackToDefault == false || SystemFlags::VERBOSE_MODE_ENABLED) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s] uselanguage [%s] text [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + ex.what(), uselanguage.c_str(), + s.c_str()); + } + } + } + + //printf("#2 fallbackToDefault = %d [%s] uselanguage [%s] DEFAULT_LANGUAGE [%s] this->language [%s]\n",fallbackToDefault,s.c_str(),uselanguage.c_str(),DEFAULT_LANGUAGE,this->language.c_str()); + + //if(fallbackToDefault == true && uselanguage != DEFAULT_LANGUAGE && this->language != DEFAULT_LANGUAGE) { + if (uselanguage != DEFAULT_LANGUAGE + && this->language != DEFAULT_LANGUAGE) { + return getString(s, DEFAULT_LANGUAGE, false); + } + + //return "???" + s + "???"; + } + return "???" + s + "???"; + } + + string Lang::getScenarioString(const string & s) { + try { + string result = scenarioStrings.getString(s); + replaceAll(result, "\\n", "\n"); + return result; + } catch (exception & ex) { + if (scenarioStrings.getpath() != "") { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + ex.what()); + } + return "???" + s + "???"; + } + } + + bool Lang::hasScenarioString(const string & s) { + bool result = false; + try { + scenarioStrings.getString(s); + result = true; + } catch (exception & ex) { + if (scenarioStrings.getpath() != "") { + if (SystemFlags::VERBOSE_MODE_ENABLED) + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + ex.what()); + } + } + return result; + } + + string Lang::getTechTreeString(const string & s, + const char *defaultValue) { + try { + string result = ""; + string default_language = "default"; + + //printf("Line: %d techNameLoaded = %s s = %s this->language = %s\n",__LINE__,techNameLoaded.c_str(),s.c_str(),this->language.c_str()); + + if (allowNativeLanguageTechtree == true && + (techTreeStringsAllLanguages[techNameLoaded][this->language]. + hasString(s) == true || defaultValue == NULL)) { + if (techTreeStringsAllLanguages[techNameLoaded][this->language]. + hasString(s) == false + && + techTreeStringsAllLanguages[techNameLoaded][default_language]. + hasString(s) == true) { + + //printf("Line: %d techNameLoaded = %s s = %s this->language = %s\n",__LINE__,techNameLoaded.c_str(),s.c_str(),this->language.c_str()); + + result = + techTreeStringsAllLanguages[techNameLoaded][default_language]. + getString(s); + } else { + + //printf("Line: %d techNameLoaded = %s s = %s this->language = %s\n",__LINE__,techNameLoaded.c_str(),s.c_str(),this->language.c_str()); + + result = + techTreeStringsAllLanguages[techNameLoaded][this->language]. + getString(s); + } + } else if (allowNativeLanguageTechtree == true && + techTreeStringsAllLanguages[techNameLoaded] + [default_language].hasString(s) == true) { + + //printf("Line: %d techNameLoaded = %s s = %s this->language = %s\n",__LINE__,techNameLoaded.c_str(),s.c_str(),this->language.c_str()); + + result = + techTreeStringsAllLanguages[techNameLoaded][default_language]. + getString(s); + } else if (defaultValue != NULL) { + result = defaultValue; + } + replaceAll(result, "\\n", "\n"); + return result; + } catch (exception & ex) { + if (techTreeStringsAllLanguages[techNameLoaded][this->language]. + getpath() != "") { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + ex.what()); + } + //return "???" + s + "???"; + } + return "???" + s + "???"; + } + + string Lang::getTilesetString(const string & s, const char *defaultValue) { + try { + string result = ""; + + if (tilesetStrings.hasString(s) == true || defaultValue == NULL) { + if (tilesetStrings.hasString(s) == false + && tilesetStringsDefault.hasString(s) == true) { + result = tilesetStringsDefault.getString(s); + } else { + result = tilesetStrings.getString(s); + } + } else if (tilesetStringsDefault.hasString(s) == true) { + result = tilesetStringsDefault.getString(s); + } else if (defaultValue != NULL) { + result = defaultValue; + } + replaceAll(result, "\\n", "\n"); + return result; + } catch (exception & ex) { + if (tilesetStrings.getpath() != "") { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + ex.what()); + } + //return "???" + s + "???"; + } + return "???" + s + "???"; + } + + bool Lang::fileMatchesISO630Code(string uselanguage, + string testLanguageFile) { + bool result = false; + Properties stringsTest; + stringsTest.load(testLanguageFile); + + try { + string iso639 = stringsTest.getString("ISO639-1"); + if (iso639 == uselanguage) { + result = true; + } + } + //catch(const exception &ex) { + catch (...) { + } + + return result; + } + + string Lang::getLanguageFile(string uselanguage) { + bool foundMatch = false; + string result = uselanguage; + + string data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + + vector < string > langResults; + string userDataPath = getGameCustomCoreDataPath(data_path, ""); + findAll(userDataPath + "data/lang/*.lng", langResults, true, false); + for (unsigned int i = 0; i < langResults.size() && foundMatch == false; + ++i) { + string testLanguageFile = + userDataPath + "data/lang/" + langResults[i] + ".lng"; + foundMatch = fileMatchesISO630Code(uselanguage, testLanguageFile); + if (foundMatch == true) { + result = langResults[i]; + } + } + if (foundMatch == false) { + langResults.clear(); + findAll(data_path + "data/lang/*.lng", langResults, true); + for (unsigned int i = 0; + i < langResults.size() && foundMatch == false; ++i) { + string testLanguageFile = + data_path + "data/lang/" + langResults[i] + ".lng"; + foundMatch = fileMatchesISO630Code(uselanguage, testLanguageFile); + if (foundMatch == true) { + result = langResults[i]; + } + } + } + return result; + } + + string Lang::getNativeLanguageName(string uselanguage, + string testLanguageFile) { + string result = uselanguage; + + static map < string, string > cachedNativeLanguageNames; + if (cachedNativeLanguageNames.find(testLanguageFile) != + cachedNativeLanguageNames.end()) { + result = cachedNativeLanguageNames[testLanguageFile]; + } else { + Properties stringsTest; + stringsTest.load(testLanguageFile); + + try { + result = stringsTest.getString("NativeLanguageName"); + cachedNativeLanguageNames[testLanguageFile] = result; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Caching native language name for [%s] = [%s]\n", + testLanguageFile.c_str(), result.c_str()); + } catch (const exception & ex) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("ERROR Caching native language name for [%s] msg: [%s]\n", + testLanguageFile.c_str(), ex.what()); + } catch (...) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("ERROR Caching native language name for [%s] msg: [UNKNOWN]\n", + testLanguageFile.c_str()); + } + } + + return result; + } + + pair < string, + string > Lang::getNavtiveNameFromLanguageName(string langName) { + pair < string, string > result; + + //printf("looking for language [%s]\n",langName.c_str()); + + map < string, string > nativeList = + Lang::getDiscoveredLanguageList(true); + map < string, string >::iterator iterMap = nativeList.find(langName); + if (iterMap != nativeList.end()) { + result = make_pair(iterMap->second, iterMap->first); + } + return result; + } + + map < string, + string > Lang::getDiscoveredLanguageList(bool searchKeyIsLangName) { + map < string, string > result; + + string data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + string userDataPath = getGameCustomCoreDataPath(data_path, ""); + + vector < string > langResults; + findAll(userDataPath + "data/lang/*.lng", langResults, true, false); + for (unsigned int i = 0; i < langResults.size(); ++i) { + string testLanguage = langResults[i]; + string testLanguageFile = + userDataPath + "data/lang/" + testLanguage + ".lng"; + string nativeName = + getNativeLanguageName(testLanguage, testLanguageFile); + if (searchKeyIsLangName == false) { + result[nativeName] = testLanguage; + } else { + result[testLanguage] = nativeName; + } + } + + vector < string > langResults2; + findAll(data_path + "data/lang/*.lng", langResults2, true); + if (langResults2.empty() && langResults.empty()) { + throw megaglest_runtime_error("There are no lang files"); + } + for (unsigned int i = 0; i < langResults2.size(); ++i) { + string testLanguage = langResults2[i]; + if (std:: + find(langResults.begin(), langResults.end(), + testLanguage) == langResults.end()) { + langResults.push_back(testLanguage); + + string testLanguageFile = + data_path + "data/lang/" + testLanguage + ".lng"; + string nativeName = + getNativeLanguageName(testLanguage, testLanguageFile); + if (searchKeyIsLangName == false) { + result[nativeName] = testLanguage; + } else { + result[testLanguage] = nativeName; + } + } + } + + return result; + } + + } } //end namespace diff --git a/source/glest_game/global/lang.h b/source/glest_game/global/lang.h index d5f684fcc..fde16b132 100644 --- a/source/glest_game/global/lang.h +++ b/source/glest_game/global/lang.h @@ -20,101 +20,95 @@ # include "properties.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - using Shared::Util::Properties; + using Shared::Util::Properties; -// ===================================================== -// class Lang -// -// String table -// ===================================================== + // ===================================================== + // class Lang + // + // String table + // ===================================================== - class Lang - { - private: + class Lang { + private: - bool is_utf8_language; - string language; - std::map < string, Properties > gameStringsAllLanguages; + bool is_utf8_language; + string language; + std::map < string, Properties > gameStringsAllLanguages; - Properties scenarioStrings; + Properties scenarioStrings; - Properties tilesetStrings; - Properties tilesetStringsDefault; + Properties tilesetStrings; + Properties tilesetStringsDefault; - std::map < string, std::map < string, - Properties > >techTreeStringsAllLanguages; - string techNameLoaded; - bool allowNativeLanguageTechtree; + std::map < string, std::map < string, + Properties > >techTreeStringsAllLanguages; + string techNameLoaded; + bool allowNativeLanguageTechtree; - private: - Lang (); - void loadGameStringProperties (string language, Properties & properties, - bool fileMustExist, - bool fallbackToDefault = false); - bool fileMatchesISO630Code (string uselanguage, - string testLanguageFile); - string getNativeLanguageName (string uselanguage, - string testLanguageFile); + private: + Lang(); + void loadGameStringProperties(string language, Properties & properties, + bool fileMustExist, + bool fallbackToDefault = false); + bool fileMatchesISO630Code(string uselanguage, + string testLanguageFile); + string getNativeLanguageName(string uselanguage, + string testLanguageFile); - string parseResult (const string & key, const string & value); + string parseResult(const string & key, const string & value); - public: - static Lang & getInstance (); + public: + static Lang & getInstance(); - string getTechNameLoaded () const - { - return techNameLoaded; - } - bool getAllowNativeLanguageTechtree () const - { - return allowNativeLanguageTechtree; - } - void setAllowNativeLanguageTechtree (bool value) - { - allowNativeLanguageTechtree = value; - } + string getTechNameLoaded() const { + return techNameLoaded; + } + bool getAllowNativeLanguageTechtree() const { + return allowNativeLanguageTechtree; + } + void setAllowNativeLanguageTechtree(bool value) { + allowNativeLanguageTechtree = value; + } - void loadGameStrings (string uselanguage, bool loadFonts = - true, bool fallbackToDefault = false); - void loadScenarioStrings (string scenarioDir, string scenarioName, - bool isTutorial); - bool loadTechTreeStrings (string techTree, bool forceLoad = false); - void loadTilesetStrings (string tileset); + void loadGameStrings(string uselanguage, bool loadFonts = + true, bool fallbackToDefault = false); + void loadScenarioStrings(string scenarioDir, string scenarioName, + bool isTutorial); + bool loadTechTreeStrings(string techTree, bool forceLoad = false); + void loadTilesetStrings(string tileset); - string getString (const string & s, string uselanguage = - "", bool fallbackToDefault = false); - bool hasString (const string & s, string uselanguage = - "", bool fallbackToDefault = false); + string getString(const string & s, string uselanguage = + "", bool fallbackToDefault = false); + bool hasString(const string & s, string uselanguage = + "", bool fallbackToDefault = false); - string getScenarioString (const string & s); - bool hasScenarioString (const string & s); + string getScenarioString(const string & s); + bool hasScenarioString(const string & s); - string getTechTreeString (const string & s, const char *defaultValue = - NULL); - string getTilesetString (const string & s, const char *defaultValue = - NULL); + string getTechTreeString(const string & s, const char *defaultValue = + NULL); + string getTilesetString(const string & s, const char *defaultValue = + NULL); - string getLanguage () const - { - return language; - } - bool isLanguageLocal (string compareLanguage) const; - //bool isUTF8Language() const; - string getDefaultLanguage () const; + string getLanguage() const { + return language; + } + bool isLanguageLocal(string compareLanguage) const; + //bool isUTF8Language() const; + string getDefaultLanguage() const; - map < string, - string > getDiscoveredLanguageList (bool searchKeyIsLangName = false); - pair < string, - string > getNavtiveNameFromLanguageName (string langName); + map < string, + string > getDiscoveredLanguageList(bool searchKeyIsLangName = false); + pair < string, + string > getNavtiveNameFromLanguageName(string langName); - string getLanguageFile (string uselanguage); - }; + string getLanguageFile(string uselanguage); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/global/metrics.cpp b/source/glest_game/global/metrics.cpp index 34bf853a8..315a2fe11 100644 --- a/source/glest_game/global/metrics.cpp +++ b/source/glest_game/global/metrics.cpp @@ -16,117 +16,96 @@ using namespace std; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class Metrics -// ===================================================== + // ===================================================== + // class Metrics + // ===================================================== - Metrics::Metrics () - { - reloadData (); - } + Metrics::Metrics() { + reloadData(); + } - void Metrics::reload (int resWidth, int resHeight) - { - Metrics *metrics = getInstancePtr (); - metrics->reloadData (resWidth, resHeight); - } + void Metrics::reload(int resWidth, int resHeight) { + Metrics *metrics = getInstancePtr(); + metrics->reloadData(resWidth, resHeight); + } - void Metrics::reloadData (int resWidth, int resHeight) - { - Config & config = Config::getInstance (); + void Metrics::reloadData(int resWidth, int resHeight) { + Config & config = Config::getInstance(); - virtualW = 1000; - virtualH = 750; + virtualW = 1000; + virtualH = 750; - if (resWidth > 0) - { - screenW = resWidth; - } - else - { - screenW = config.getInt ("ScreenWidth"); - } - if (resHeight > 0) - { - screenH = resHeight; - } - else - { - screenH = config.getInt ("ScreenHeight"); - } + if (resWidth > 0) { + screenW = resWidth; + } else { + screenW = config.getInt("ScreenWidth"); + } + if (resHeight > 0) { + screenH = resHeight; + } else { + screenH = config.getInt("ScreenHeight"); + } - minimapX = 10; - minimapY = 750 - 128 - 30 + 16; - minimapW = 128; - minimapH = 128; + minimapX = 10; + minimapY = 750 - 128 - 30 + 16; + minimapW = 128; + minimapH = 128; - displayX = 800; - displayY = 250; - displayW = 128; - displayH = 480; - } + displayX = 800; + displayY = 250; + displayW = 128; + displayH = 480; + } - Metrics *Metrics::getInstancePtr () - { - static Metrics metrics; - return &metrics; - } + Metrics *Metrics::getInstancePtr() { + static Metrics metrics; + return &metrics; + } - const Metrics & Metrics::getInstance () - { - Metrics *metrics = getInstancePtr (); - return *metrics; - } + const Metrics & Metrics::getInstance() { + Metrics *metrics = getInstancePtr(); + return *metrics; + } - float Metrics::getAspectRatio () const - { - if (screenH == 0) - { - throw megaglest_runtime_error ("div by 0 screenH == 0"); - } - return static_cast < float >(screenW) / screenH; - } + float Metrics::getAspectRatio() const { + if (screenH == 0) { + throw megaglest_runtime_error("div by 0 screenH == 0"); + } + return static_cast (screenW) / screenH; + } - int Metrics::toVirtualX (int w) const - { - if (screenW == 0) - { - throw megaglest_runtime_error ("div by 0 screenW == 0"); - } - return w * virtualW / screenW; - } + int Metrics::toVirtualX(int w) const { + if (screenW == 0) { + throw megaglest_runtime_error("div by 0 screenW == 0"); + } + return w * virtualW / screenW; + } - int Metrics::toVirtualY (int h) const - { - if (screenH == 0) - { - throw megaglest_runtime_error ("div by 0 screenH == 0"); - } + int Metrics::toVirtualY(int h) const { + if (screenH == 0) { + throw megaglest_runtime_error("div by 0 screenH == 0"); + } - //printf("h [%d] virtualH [%d] screenH [%d] result = %d\n",h,virtualH,screenH,(h*virtualH/screenH)); + //printf("h [%d] virtualH [%d] screenH [%d] result = %d\n",h,virtualH,screenH,(h*virtualH/screenH)); - return h * virtualH / screenH; - } + return h * virtualH / screenH; + } - bool Metrics::isInDisplay (int x, int y) const - { - return - x > displayX && - y > displayY && x < displayX + displayW && y < displayY + displayH; - } + bool Metrics::isInDisplay(int x, int y) const { + return + x > displayX && + y > displayY && x < displayX + displayW && y < displayY + displayH; + } - bool Metrics::isInMinimap (int x, int y) const - { - return - x > minimapX && - y > minimapY && x < minimapX + minimapW && y < minimapY + minimapH; - } + bool Metrics::isInMinimap(int x, int y) const { + return + x > minimapX && + y > minimapY && x < minimapX + minimapW && y < minimapY + minimapH; + } - } + } } // end namespace diff --git a/source/glest_game/global/metrics.h b/source/glest_game/global/metrics.h index 8a938bc1b..ec20d52f0 100644 --- a/source/glest_game/global/metrics.h +++ b/source/glest_game/global/metrics.h @@ -20,98 +20,84 @@ # include "config.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class Metrics -// ===================================================== + // ===================================================== + // class Metrics + // ===================================================== - class Metrics - { - private: - int virtualW; - int virtualH; - int screenW; - int screenH; - int minimapX; - int minimapY; - int minimapW; - int minimapH; - int displayX; - int displayY; - int displayH; - int displayW; + class Metrics { + private: + int virtualW; + int virtualH; + int screenW; + int screenH; + int minimapX; + int minimapY; + int minimapW; + int minimapH; + int displayX; + int displayY; + int displayH; + int displayW; - private: - Metrics (); - static Metrics *getInstancePtr (); - void reloadData (int resWidth = -1, int resHeight = -1); + private: + Metrics(); + static Metrics *getInstancePtr(); + void reloadData(int resWidth = -1, int resHeight = -1); - public: - static const Metrics & getInstance (); + public: + static const Metrics & getInstance(); - int getVirtualW () const - { - return virtualW; - } - int getVirtualH () const - { - return virtualH; - } - int getScreenW () const - { - return screenW; - } - int getScreenH () const - { - return screenH; - } - int getMinimapX () const - { - return minimapX; - } - int getMinimapY () const - { - return minimapY; - } - int getMinimapW () const - { - return minimapW; - } - int getMinimapH () const - { - return minimapH; - } - int getDisplayX () const - { - return displayX; - } - int getDisplayY () const - { - return displayY; - } - int getDisplayH () const - { - return displayH; - } - int getDisplayW () const - { - return displayW; - } - float getAspectRatio () const; + int getVirtualW() const { + return virtualW; + } + int getVirtualH() const { + return virtualH; + } + int getScreenW() const { + return screenW; + } + int getScreenH() const { + return screenH; + } + int getMinimapX() const { + return minimapX; + } + int getMinimapY() const { + return minimapY; + } + int getMinimapW() const { + return minimapW; + } + int getMinimapH() const { + return minimapH; + } + int getDisplayX() const { + return displayX; + } + int getDisplayY() const { + return displayY; + } + int getDisplayH() const { + return displayH; + } + int getDisplayW() const { + return displayW; + } + float getAspectRatio() const; - int toVirtualX (int w) const; - int toVirtualY (int h) const; + int toVirtualX(int w) const; + int toVirtualY(int h) const; - bool isInDisplay (int x, int y) const; - bool isInMinimap (int x, int y) const; + bool isInDisplay(int x, int y) const; + bool isInMinimap(int x, int y) const; - static void reload (int resWidth = -1, int resHeight = -1); - }; + static void reload(int resWidth = -1, int resHeight = -1); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/graphics/particle_type.cpp b/source/glest_game/graphics/particle_type.cpp index 12caa3560..f2abd326f 100644 --- a/source/glest_game/graphics/particle_type.cpp +++ b/source/glest_game/graphics/particle_type.cpp @@ -28,600 +28,594 @@ using namespace Shared::Graphics; using namespace Shared::Util; using namespace Shared::PlatformCommon; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class ParticleSystemType -// ===================================================== -const bool checkMemory = false; -static map memoryObjectList; + // ===================================================== + // class ParticleSystemType + // ===================================================== + const bool checkMemory = false; + static map memoryObjectList; -ParticleSystemType::ParticleSystemType() { - if(checkMemory) { - printf("++ Create ParticleSystemType [%p]\n",this); - memoryObjectList[this]++; - } - - teamcolorNoEnergy=false; - teamcolorEnergy=false; - alternations=0; - particleSystemStartDelay=0; - texture=NULL; - model=NULL; - minmaxEnabled=false; - minHp=0; - maxHp=0; - minmaxIsPercent=false; - - modelCycle=0; - size=0; - sizeNoEnergy=0; - speed=0; - speedUpRelative=0; - speedUpConstant=0; - gravity=0; - emissionRate=0; - energyMax=0; - energyVar=0; - -} - -ParticleSystemType::ParticleSystemType(const ParticleSystemType &src) { - if(checkMemory) { - printf("++ Create ParticleSystemType #2 [%p]\n",this); - memoryObjectList[this]++; - } - - copyAll(src); -} - -ParticleSystemType & ParticleSystemType::operator=(const ParticleSystemType &src) { - if(checkMemory) { - printf("++ Create ParticleSystemType #3 [%p]\n",this); - memoryObjectList[this]++; - } - - copyAll(src); - return *this; -} - -ParticleSystemType::~ParticleSystemType() { - if(checkMemory) { - printf("-- Delete ParticleSystemType [%p] type = [%s]\n",this,type.c_str()); - memoryObjectList[this]--; - assert(memoryObjectList[this] == 0); - } - for(Children::iterator it = children.begin(); it != children.end(); ++it) { - delete *it; - } - children.clear(); -} - -void ParticleSystemType::copyAll(const ParticleSystemType &src) { - this->type = src.type; - this->texture = src.texture; - this->model = src.model; - this->modelCycle = src.modelCycle; - this->primitive = src.primitive; - this->offset = src.offset; - this->color = src.color; - this->colorNoEnergy = src.colorNoEnergy; - this->size = src.size; - this->sizeNoEnergy = src.sizeNoEnergy; - this->speed = src.speed; - this->speedUpRelative = src.speedUpRelative; - this->speedUpConstant = src.speedUpConstant; - this->gravity = src.gravity; - this->emissionRate = src.emissionRate; - this->energyMax = src.energyMax; - this->energyVar = src.energyVar; - this->mode = src.mode; - this->teamcolorNoEnergy = src.teamcolorNoEnergy; - this->teamcolorEnergy = src.teamcolorEnergy; - this->alternations = src.alternations; - this->particleSystemStartDelay= src.particleSystemStartDelay; - for(Children::iterator it = children.begin(); it != children.end(); ++it) { - UnitParticleSystemType *child = *it; - - // Deep copy the child particles - UnitParticleSystemType *newCopy = new UnitParticleSystemType(); - *newCopy = *child; - children.push_back(newCopy); - } - - this->minmaxEnabled = src.minmaxEnabled; - this->minHp = src.minHp; - this->maxHp = src.maxHp; - this->minmaxIsPercent = src.minmaxIsPercent; -} - -void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &dir, - RendererInterface *renderer, std::map > > &loadedFileList, - string parentLoader, string techtreePath) { - - //texture - const XmlNode *textureNode= particleSystemNode->getChild("texture"); - bool textureEnabled= textureNode->getAttribute("value")->getBoolValue(); - - if(textureEnabled){ - texture= renderer->newTexture2D(rsGame); - if(texture) { - if(textureNode->getAttribute("luminance")->getBoolValue()){ - texture->setFormat(Texture::fAlpha); - texture->getPixmap()->init(1); + ParticleSystemType::ParticleSystemType() { + if (checkMemory) { + printf("++ Create ParticleSystemType [%p]\n", this); + memoryObjectList[this]++; } - else{ - texture->getPixmap()->init(4); + + teamcolorNoEnergy = false; + teamcolorEnergy = false; + alternations = 0; + particleSystemStartDelay = 0; + texture = NULL; + model = NULL; + minmaxEnabled = false; + minHp = 0; + maxHp = 0; + minmaxIsPercent = false; + + modelCycle = 0; + size = 0; + sizeNoEnergy = 0; + speed = 0; + speedUpRelative = 0; + speedUpConstant = 0; + gravity = 0; + emissionRate = 0; + energyMax = 0; + energyVar = 0; + + } + + ParticleSystemType::ParticleSystemType(const ParticleSystemType &src) { + if (checkMemory) { + printf("++ Create ParticleSystemType #2 [%p]\n", this); + memoryObjectList[this]++; + } + + copyAll(src); + } + + ParticleSystemType & ParticleSystemType::operator=(const ParticleSystemType &src) { + if (checkMemory) { + printf("++ Create ParticleSystemType #3 [%p]\n", this); + memoryObjectList[this]++; + } + + copyAll(src); + return *this; + } + + ParticleSystemType::~ParticleSystemType() { + if (checkMemory) { + printf("-- Delete ParticleSystemType [%p] type = [%s]\n", this, type.c_str()); + memoryObjectList[this]--; + assert(memoryObjectList[this] == 0); + } + for (Children::iterator it = children.begin(); it != children.end(); ++it) { + delete *it; + } + children.clear(); + } + + void ParticleSystemType::copyAll(const ParticleSystemType &src) { + this->type = src.type; + this->texture = src.texture; + this->model = src.model; + this->modelCycle = src.modelCycle; + this->primitive = src.primitive; + this->offset = src.offset; + this->color = src.color; + this->colorNoEnergy = src.colorNoEnergy; + this->size = src.size; + this->sizeNoEnergy = src.sizeNoEnergy; + this->speed = src.speed; + this->speedUpRelative = src.speedUpRelative; + this->speedUpConstant = src.speedUpConstant; + this->gravity = src.gravity; + this->emissionRate = src.emissionRate; + this->energyMax = src.energyMax; + this->energyVar = src.energyVar; + this->mode = src.mode; + this->teamcolorNoEnergy = src.teamcolorNoEnergy; + this->teamcolorEnergy = src.teamcolorEnergy; + this->alternations = src.alternations; + this->particleSystemStartDelay = src.particleSystemStartDelay; + for (Children::iterator it = children.begin(); it != children.end(); ++it) { + UnitParticleSystemType *child = *it; + + // Deep copy the child particles + UnitParticleSystemType *newCopy = new UnitParticleSystemType(); + *newCopy = *child; + children.push_back(newCopy); + } + + this->minmaxEnabled = src.minmaxEnabled; + this->minHp = src.minHp; + this->maxHp = src.maxHp; + this->minmaxIsPercent = src.minmaxIsPercent; + } + + void ParticleSystemType::load(const XmlNode *particleSystemNode, const string &dir, + RendererInterface *renderer, std::map > > &loadedFileList, + string parentLoader, string techtreePath) { + + //texture + const XmlNode *textureNode = particleSystemNode->getChild("texture"); + bool textureEnabled = textureNode->getAttribute("value")->getBoolValue(); + + if (textureEnabled) { + texture = renderer->newTexture2D(rsGame); + if (texture) { + if (textureNode->getAttribute("luminance")->getBoolValue()) { + texture->setFormat(Texture::fAlpha); + texture->getPixmap()->init(1); + } else { + texture->getPixmap()->init(4); + } + } + string currentPath = dir; + endPathWithSlash(currentPath); + if (texture) { + texture->load(textureNode->getAttribute("path")->getRestrictedValue(currentPath)); + } + loadedFileList[textureNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(parentLoader, textureNode->getAttribute("path")->getRestrictedValue())); + } else { + texture = NULL; + } + + //model + if (particleSystemNode->hasChild("model")) { + const XmlNode *modelNode = particleSystemNode->getChild("model"); + bool modelEnabled = modelNode->getAttribute("value")->getBoolValue(); + if (modelEnabled) { + string currentPath = dir; + endPathWithSlash(currentPath); + + string path = modelNode->getAttribute("path")->getRestrictedValue(currentPath); + model = renderer->newModel(rsGame, path, false, &loadedFileList, &parentLoader); + loadedFileList[path].push_back(make_pair(parentLoader, modelNode->getAttribute("path")->getRestrictedValue())); + + if (modelNode->hasChild("cycles")) { + modelCycle = modelNode->getChild("cycles")->getAttribute("value")->getFloatValue(); + if (modelCycle < 0.0) + throw megaglest_runtime_error("negative model cycle value is bad"); + } + } + } else { + model = NULL; + } + + //primitive + const XmlNode *primitiveNode = particleSystemNode->getChild("primitive"); + primitive = primitiveNode->getAttribute("value")->getRestrictedValue(); + + //offset + const XmlNode *offsetNode = particleSystemNode->getChild("offset"); + offset.x = offsetNode->getAttribute("x")->getFloatValue(); + offset.y = offsetNode->getAttribute("y")->getFloatValue(); + offset.z = offsetNode->getAttribute("z")->getFloatValue(); + + //color + const XmlNode *colorNode = particleSystemNode->getChild("color"); + color.x = colorNode->getAttribute("red")->getFloatValue(0.f, 1.0f); + color.y = colorNode->getAttribute("green")->getFloatValue(0.f, 1.0f); + color.z = colorNode->getAttribute("blue")->getFloatValue(0.f, 1.0f); + color.w = colorNode->getAttribute("alpha")->getFloatValue(0.f, 1.0f); + + //color + const XmlNode *colorNoEnergyNode = particleSystemNode->getChild("color-no-energy"); + colorNoEnergy.x = colorNoEnergyNode->getAttribute("red")->getFloatValue(0.f, 1.0f); + colorNoEnergy.y = colorNoEnergyNode->getAttribute("green")->getFloatValue(0.f, 1.0f); + colorNoEnergy.z = colorNoEnergyNode->getAttribute("blue")->getFloatValue(0.f, 1.0f); + colorNoEnergy.w = colorNoEnergyNode->getAttribute("alpha")->getFloatValue(0.f, 1.0f); + + //size + const XmlNode *sizeNode = particleSystemNode->getChild("size"); + size = sizeNode->getAttribute("value")->getFloatValue(); + + //sizeNoEnergy + const XmlNode *sizeNoEnergyNode = particleSystemNode->getChild("size-no-energy"); + sizeNoEnergy = sizeNoEnergyNode->getAttribute("value")->getFloatValue(); + + //speed + const XmlNode *speedNode = particleSystemNode->getChild("speed"); + speed = speedNode->getAttribute("value")->getFloatValue() / GameConstants::updateFps; + + //speedUp + if (particleSystemNode->hasChild("speedUp")) { + const XmlNode *speedUpNode = particleSystemNode->getChild("speedUp"); + if (speedUpNode->hasAttribute("relative")) { + speedUpRelative = speedUpNode->getAttribute("relative")->getFloatValue(); + } + if (speedUpNode->hasAttribute("constant")) { + speedUpConstant = speedUpNode->getAttribute("constant")->getFloatValue(); + } + } + + //gravity + const XmlNode *gravityNode = particleSystemNode->getChild("gravity"); + gravity = gravityNode->getAttribute("value")->getFloatValue() / GameConstants::updateFps; + + //emission rate + const XmlNode *emissionRateNode = particleSystemNode->getChild("emission-rate"); + emissionRate = emissionRateNode->getAttribute("value")->getFloatValue(); + + //energy max + const XmlNode *energyMaxNode = particleSystemNode->getChild("energy-max"); + energyMax = energyMaxNode->getAttribute("value")->getIntValue(); + + //speed + const XmlNode *energyVarNode = particleSystemNode->getChild("energy-var"); + energyVar = energyVarNode->getAttribute("value")->getIntValue(); + + //teamcolorNoEnergy + if (particleSystemNode->hasChild("teamcolorNoEnergy")) { + const XmlNode *teamcolorNoEnergyNode = particleSystemNode->getChild("teamcolorNoEnergy"); + teamcolorNoEnergy = teamcolorNoEnergyNode->getAttribute("value")->getBoolValue(); + } + //teamcolorEnergy + if (particleSystemNode->hasChild("teamcolorEnergy")) { + const XmlNode *teamcolorEnergyNode = particleSystemNode->getChild("teamcolorEnergy"); + teamcolorEnergy = teamcolorEnergyNode->getAttribute("value")->getBoolValue(); + } + //alternations + if (particleSystemNode->hasChild("alternations")) { + const XmlNode *alternatingNode = particleSystemNode->getChild("alternations"); + alternations = alternatingNode->getAttribute("value")->getIntValue(); + } + //particleSystemStartDelay + if (particleSystemNode->hasChild("particleSystemStartDelay")) { + const XmlNode *node = particleSystemNode->getChild("particleSystemStartDelay"); + particleSystemStartDelay = node->getAttribute("value")->getIntValue(); + } + //mode + if (particleSystemNode->hasChild("mode")) { + const XmlNode *modeNode = particleSystemNode->getChild("mode"); + mode = modeNode->getAttribute("value")->getRestrictedValue(); + } else { + mode = "normal"; + } + + // child particles + if (particleSystemNode->hasChild("child-particles")) { + const XmlNode *childrenNode = particleSystemNode->getChild("child-particles"); + if (childrenNode->getAttribute("value")->getBoolValue()) { + for (unsigned int i = 0; i < childrenNode->getChildCount(); ++i) { + const XmlNode *particleFileNode = childrenNode->getChild("particle-file", i); + string path = particleFileNode->getAttribute("path")->getRestrictedValue(); + UnitParticleSystemType *unitParticleSystemType = new UnitParticleSystemType(); + string childPath = dir; + endPathWithSlash(childPath); + childPath += path; + string childDir = extractDirectoryPathFromFile(childPath); + unitParticleSystemType->load(particleFileNode, childDir, childPath, renderer, loadedFileList, parentLoader, techtreePath); + loadedFileList[childPath].push_back(make_pair(parentLoader, path)); + children.push_back(unitParticleSystemType); + } + } } } - string currentPath = dir; - endPathWithSlash(currentPath); - if(texture) { - texture->load(textureNode->getAttribute("path")->getRestrictedValue(currentPath)); + + void ParticleSystemType::setValues(AttackParticleSystem *ats) { + // add instances of all children; some settings will cascade to all children + for (Children::iterator i = children.begin(); i != children.end(); ++i) { + UnitParticleSystem *child = new UnitParticleSystem(); + child->setParticleOwner(ats->getParticleOwner()); + child->setParticleType((*i)); + (*i)->setValues(child); + ats->addChild(child); + child->setState(ParticleSystem::sPlay); + } + ats->setTexture(texture); + ats->setPrimitive(AttackParticleSystem::strToPrimitive(primitive)); + ats->setOffset(offset); + ats->setColor(color); + ats->setColorNoEnergy(colorNoEnergy); + ats->setSpeed(speed); + ats->setSpeedUpRelative(speedUpRelative); + ats->setSpeedUpConstant(speedUpConstant); + ats->setGravity(gravity); + ats->setParticleSize(size); + ats->setSizeNoEnergy(sizeNoEnergy); + ats->setEmissionRate(emissionRate); + ats->setMaxParticleEnergy(energyMax); + ats->setVarParticleEnergy(energyVar); + ats->setModel(model); + ats->setModelCycle(modelCycle); + ats->setTeamcolorNoEnergy(teamcolorNoEnergy); + ats->setTeamcolorEnergy(teamcolorEnergy); + ats->setAlternations(alternations); + ats->setParticleSystemStartDelay(particleSystemStartDelay); + ats->setBlendMode(ParticleSystem::strToBlendMode(mode)); } - loadedFileList[textureNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(parentLoader,textureNode->getAttribute("path")->getRestrictedValue())); - } - else { - texture= NULL; - } - //model - if(particleSystemNode->hasChild("model")){ - const XmlNode *modelNode= particleSystemNode->getChild("model"); - bool modelEnabled= modelNode->getAttribute("value")->getBoolValue(); - if(modelEnabled) { - string currentPath = dir; - endPathWithSlash(currentPath); + void ParticleSystemType::loadGame(const XmlNode *rootNode) { + const XmlNode *particleSystemTypeNode = rootNode->getChild("ParticleSystemType"); - string path= modelNode->getAttribute("path")->getRestrictedValue(currentPath); - model= renderer->newModel(rsGame,path, false, &loadedFileList, &parentLoader); - loadedFileList[path].push_back(make_pair(parentLoader,modelNode->getAttribute("path")->getRestrictedValue())); + type = particleSystemTypeNode->getAttribute("type")->getIntValue(); - if(modelNode->hasChild("cycles")) { - modelCycle = modelNode->getChild("cycles")->getAttribute("value")->getFloatValue(); - if(modelCycle < 0.0) - throw megaglest_runtime_error("negative model cycle value is bad"); + modelCycle = particleSystemTypeNode->getAttribute("modelCycle")->getFloatValue(); + primitive = particleSystemTypeNode->getAttribute("primitive")->getValue(); + offset = Vec3f::strToVec3(particleSystemTypeNode->getAttribute("offset")->getValue()); + color = Vec4f::strToVec4(particleSystemTypeNode->getAttribute("color")->getValue()); + colorNoEnergy = Vec4f::strToVec4(particleSystemTypeNode->getAttribute("colorNoEnergy")->getValue()); + size = particleSystemTypeNode->getAttribute("size")->getFloatValue(); + sizeNoEnergy = particleSystemTypeNode->getAttribute("sizeNoEnergy")->getFloatValue(); + speed = particleSystemTypeNode->getAttribute("speed")->getFloatValue(); + if (particleSystemTypeNode->hasAttribute("speedUpRelative")) { + speedUpRelative = particleSystemTypeNode->getAttribute("speedUpRelative")->getFloatValue(); + } + if (particleSystemTypeNode->hasAttribute("speedUpConstant")) { + speedUpConstant = particleSystemTypeNode->getAttribute("speedUpConstant")->getFloatValue(); + } + gravity = particleSystemTypeNode->getAttribute("gravity")->getFloatValue(); + emissionRate = particleSystemTypeNode->getAttribute("emissionRate")->getFloatValue(); + energyMax = particleSystemTypeNode->getAttribute("energyMax")->getIntValue(); + energyVar = particleSystemTypeNode->getAttribute("energyVar")->getIntValue(); + mode = particleSystemTypeNode->getAttribute("mode")->getValue(); + teamcolorNoEnergy = (particleSystemTypeNode->getAttribute("teamcolorNoEnergy")->getIntValue() != 0); + teamcolorEnergy = (particleSystemTypeNode->getAttribute("teamcolorEnergy")->getIntValue() != 0); + alternations = particleSystemTypeNode->getAttribute("alternations")->getIntValue(); + particleSystemStartDelay = particleSystemTypeNode->getAttribute("particleSystemStartDelay")->getIntValue(); + + if (particleSystemTypeNode->hasChild("UnitParticleSystemType")) { + vector particleSystemTypeNodeList = particleSystemTypeNode->getChildList("UnitParticleSystemType"); + for (unsigned int i = 0; i < particleSystemTypeNodeList.size(); ++i) { + XmlNode *node = particleSystemTypeNodeList[i]; + + UnitParticleSystemType *child = new UnitParticleSystemType(); + child->loadGame(node); + children.push_back(child); + } + } + minmaxEnabled = (particleSystemTypeNode->getAttribute("minmaxEnabled")->getIntValue() != 0); + minHp = particleSystemTypeNode->getAttribute("minHp")->getIntValue(); + maxHp = particleSystemTypeNode->getAttribute("maxHp")->getIntValue(); + minmaxIsPercent = (particleSystemTypeNode->getAttribute("minmaxIsPercent")->getIntValue() != 0); + } + + void ParticleSystemType::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *particleSystemTypeNode = rootNode->addChild("ParticleSystemType"); + + // string type; + particleSystemTypeNode->addAttribute("type", type, mapTagReplacements); + // Texture2D *texture; + // Model *model; + // float modelCycle; + particleSystemTypeNode->addAttribute("modelCycle", floatToStr(modelCycle, 6), mapTagReplacements); + // string primitive; + particleSystemTypeNode->addAttribute("primitive", primitive, mapTagReplacements); + // Vec3f offset; + particleSystemTypeNode->addAttribute("offset", offset.getString(), mapTagReplacements); + // Vec4f color; + particleSystemTypeNode->addAttribute("color", color.getString(), mapTagReplacements); + // Vec4f colorNoEnergy; + particleSystemTypeNode->addAttribute("colorNoEnergy", colorNoEnergy.getString(), mapTagReplacements); + // float size; + particleSystemTypeNode->addAttribute("size", floatToStr(size, 6), mapTagReplacements); + // float sizeNoEnergy; + particleSystemTypeNode->addAttribute("sizeNoEnergy", floatToStr(sizeNoEnergy, 6), mapTagReplacements); + // float speed; + particleSystemTypeNode->addAttribute("speed", floatToStr(speed, 6), mapTagReplacements); + // float speedUpRelative; + particleSystemTypeNode->addAttribute("speedUpRelative", floatToStr(speedUpRelative, 6), mapTagReplacements); + // float speedUpConstant; + particleSystemTypeNode->addAttribute("speedUpConstant", floatToStr(speedUpConstant, 6), mapTagReplacements); + // float gravity; + particleSystemTypeNode->addAttribute("gravity", floatToStr(gravity, 6), mapTagReplacements); + // float emissionRate; + particleSystemTypeNode->addAttribute("emissionRate", floatToStr(emissionRate, 6), mapTagReplacements); + // int energyMax; + particleSystemTypeNode->addAttribute("energyMax", intToStr(energyMax), mapTagReplacements); + // int energyVar; + particleSystemTypeNode->addAttribute("energyVar", intToStr(energyVar), mapTagReplacements); + // string mode; + particleSystemTypeNode->addAttribute("mode", mode, mapTagReplacements); + // bool teamcolorNoEnergy; + particleSystemTypeNode->addAttribute("teamcolorNoEnergy", intToStr(teamcolorNoEnergy), mapTagReplacements); + // bool teamcolorEnergy; + particleSystemTypeNode->addAttribute("teamcolorEnergy", intToStr(teamcolorEnergy), mapTagReplacements); + // int alternations; + particleSystemTypeNode->addAttribute("alternations", intToStr(alternations), mapTagReplacements); + // int particleSystemStartDelay; + particleSystemTypeNode->addAttribute("particleSystemStartDelay", intToStr(particleSystemStartDelay), mapTagReplacements); + // typedef std::list Children; + // Children children; + for (Children::iterator it = children.begin(); it != children.end(); ++it) { + (*it)->saveGame(particleSystemTypeNode); + } + // bool minmaxEnabled; + particleSystemTypeNode->addAttribute("minmaxEnabled", intToStr(minmaxEnabled), mapTagReplacements); + // int minHp; + particleSystemTypeNode->addAttribute("minHp", intToStr(minHp), mapTagReplacements); + // int maxHp; + particleSystemTypeNode->addAttribute("maxHp", intToStr(maxHp), mapTagReplacements); + // bool minmaxIsPercent; + particleSystemTypeNode->addAttribute("minmaxIsPercent", intToStr(minmaxIsPercent), mapTagReplacements); + } + + // =========================================================== + // class ParticleSystemTypeProjectile + // =========================================================== + + ParticleSystemTypeProjectile::ParticleSystemTypeProjectile() : ParticleSystemType() { + trajectorySpeed = 0.0f; + trajectoryScale = 0.0f; + trajectoryFrequency = 0.0f; + } + + void ParticleSystemTypeProjectile::load(const XmlNode* particleFileNode, const string &dir, const string &path, + RendererInterface *renderer, std::map > > &loadedFileList, + string parentLoader, string techtreePath) { + + try { + XmlTree xmlTree; + + std::map mapExtraTagReplacementValues; + mapExtraTagReplacementValues["$COMMONDATAPATH"] = techtreePath + "/commondata/"; + xmlTree.load(path, Properties::getTagReplacementValues(&mapExtraTagReplacementValues)); + loadedFileList[path].push_back(make_pair(parentLoader, parentLoader)); + + const XmlNode *particleSystemNode = xmlTree.getRootNode(); + + if (particleFileNode) { + // immediate children in the particleFileNode will override the particleSystemNode + particleFileNode->setSuper(particleSystemNode); + particleSystemNode = particleFileNode; + } + + ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList, parentLoader, techtreePath); + + //trajectory values + const XmlNode *tajectoryNode = particleSystemNode->getChild("trajectory"); + trajectory = tajectoryNode->getAttribute("type")->getRestrictedValue(); + + //trajectory speed + const XmlNode *tajectorySpeedNode = tajectoryNode->getChild("speed"); + trajectorySpeed = tajectorySpeedNode->getAttribute("value")->getFloatValue() / (float) GameConstants::updateFps; + //printf("[%s] trajectorySpeed = %f\n",path.c_str(),trajectorySpeed); + + if (trajectory == "parabolic" || trajectory == "spiral") { + //trajectory scale + const XmlNode *tajectoryScaleNode = tajectoryNode->getChild("scale"); + trajectoryScale = tajectoryScaleNode->getAttribute("value")->getFloatValue(); + } else { + trajectoryScale = 1.0f; + } + + if (trajectory == "spiral") { + //trajectory frequency + const XmlNode *tajectoryFrequencyNode = tajectoryNode->getChild("frequency"); + trajectoryFrequency = tajectoryFrequencyNode->getAttribute("value")->getFloatValue(); + } else { + trajectoryFrequency = 1.0f; + } + } catch (const exception &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, e.what()); + throw megaglest_runtime_error("Error loading ParticleSystem: " + path + "\n" + e.what()); } } - } - else { - model= NULL; - } - //primitive - const XmlNode *primitiveNode= particleSystemNode->getChild("primitive"); - primitive= primitiveNode->getAttribute("value")->getRestrictedValue(); + ProjectileParticleSystem *ParticleSystemTypeProjectile::create(ParticleOwner *owner) { + ProjectileParticleSystem *ps = new ProjectileParticleSystem(); + ps->setParticleOwner(owner); + ParticleSystemType::setValues(ps); - //offset - const XmlNode *offsetNode= particleSystemNode->getChild("offset"); - offset.x= offsetNode->getAttribute("x")->getFloatValue(); - offset.y= offsetNode->getAttribute("y")->getFloatValue(); - offset.z= offsetNode->getAttribute("z")->getFloatValue(); + ps->setTrajectory(ProjectileParticleSystem::strToTrajectory(trajectory)); - //color - const XmlNode *colorNode= particleSystemNode->getChild("color"); - color.x= colorNode->getAttribute("red")->getFloatValue(0.f, 1.0f); - color.y= colorNode->getAttribute("green")->getFloatValue(0.f, 1.0f); - color.z= colorNode->getAttribute("blue")->getFloatValue(0.f, 1.0f); - color.w= colorNode->getAttribute("alpha")->getFloatValue(0.f, 1.0f); + //printf("Setting trajectorySpeed = %f\n",trajectorySpeed); + ps->setTrajectorySpeed(trajectorySpeed); + ps->setTrajectoryScale(trajectoryScale); + ps->setTrajectoryFrequency(trajectoryFrequency); - //color - const XmlNode *colorNoEnergyNode= particleSystemNode->getChild("color-no-energy"); - colorNoEnergy.x= colorNoEnergyNode->getAttribute("red")->getFloatValue(0.f, 1.0f); - colorNoEnergy.y= colorNoEnergyNode->getAttribute("green")->getFloatValue(0.f, 1.0f); - colorNoEnergy.z= colorNoEnergyNode->getAttribute("blue")->getFloatValue(0.f, 1.0f); - colorNoEnergy.w= colorNoEnergyNode->getAttribute("alpha")->getFloatValue(0.f, 1.0f); + ps->initParticleSystem(); - //size - const XmlNode *sizeNode= particleSystemNode->getChild("size"); - size= sizeNode->getAttribute("value")->getFloatValue(); + return ps; + } - //sizeNoEnergy - const XmlNode *sizeNoEnergyNode= particleSystemNode->getChild("size-no-energy"); - sizeNoEnergy= sizeNoEnergyNode->getAttribute("value")->getFloatValue(); + void ParticleSystemTypeProjectile::saveGame(XmlNode *rootNode) { + ParticleSystemType::saveGame(rootNode); - //speed - const XmlNode *speedNode= particleSystemNode->getChild("speed"); - speed= speedNode->getAttribute("value")->getFloatValue()/GameConstants::updateFps; + std::map mapTagReplacements; + XmlNode *particleSystemTypeProjectileNode = rootNode->addChild("ParticleSystemTypeProjectile"); - //speedUp - if(particleSystemNode->hasChild("speedUp")){ - const XmlNode *speedUpNode= particleSystemNode->getChild("speedUp"); - if(speedUpNode->hasAttribute("relative")){ - speedUpRelative= speedUpNode->getAttribute("relative")->getFloatValue(); - } - if(speedUpNode->hasAttribute("constant")){ - speedUpConstant= speedUpNode->getAttribute("constant")->getFloatValue(); - } - } + // string trajectory; + particleSystemTypeProjectileNode->addAttribute("trajectory", trajectory, mapTagReplacements); + // float trajectorySpeed; + particleSystemTypeProjectileNode->addAttribute("trajectorySpeed", floatToStr(trajectorySpeed, 6), mapTagReplacements); + // float trajectoryScale; + particleSystemTypeProjectileNode->addAttribute("trajectoryScale", floatToStr(trajectoryScale, 6), mapTagReplacements); + // float trajectoryFrequency; + particleSystemTypeProjectileNode->addAttribute("trajectoryFrequency", floatToStr(trajectoryFrequency, 6), mapTagReplacements); + } - //gravity - const XmlNode *gravityNode= particleSystemNode->getChild("gravity"); - gravity= gravityNode->getAttribute("value")->getFloatValue()/GameConstants::updateFps; + // =========================================================== + // class ParticleSystemTypeSplash + // =========================================================== - //emission rate - const XmlNode *emissionRateNode= particleSystemNode->getChild("emission-rate"); - emissionRate= emissionRateNode->getAttribute("value")->getFloatValue(); + ParticleSystemTypeSplash::ParticleSystemTypeSplash() { + emissionRateFade = 0.0f; + verticalSpreadA = 0.0f; + verticalSpreadB = 0.0f; + horizontalSpreadA = 0.0f; + horizontalSpreadB = 0.0f; + } - //energy max - const XmlNode *energyMaxNode= particleSystemNode->getChild("energy-max"); - energyMax= energyMaxNode->getAttribute("value")->getIntValue(); + void ParticleSystemTypeSplash::load(const XmlNode* particleFileNode, const string &dir, const string &path, + RendererInterface *renderer, std::map > > &loadedFileList, + string parentLoader, string techtreePath) { - //speed - const XmlNode *energyVarNode= particleSystemNode->getChild("energy-var"); - energyVar= energyVarNode->getAttribute("value")->getIntValue(); + try { + XmlTree xmlTree; - //teamcolorNoEnergy - if(particleSystemNode->hasChild("teamcolorNoEnergy")){ - const XmlNode *teamcolorNoEnergyNode= particleSystemNode->getChild("teamcolorNoEnergy"); - teamcolorNoEnergy= teamcolorNoEnergyNode->getAttribute("value")->getBoolValue(); - } - //teamcolorEnergy - if(particleSystemNode->hasChild("teamcolorEnergy")){ - const XmlNode *teamcolorEnergyNode= particleSystemNode->getChild("teamcolorEnergy"); - teamcolorEnergy= teamcolorEnergyNode->getAttribute("value")->getBoolValue(); - } - //alternations - if(particleSystemNode->hasChild("alternations")){ - const XmlNode *alternatingNode= particleSystemNode->getChild("alternations"); - alternations= alternatingNode->getAttribute("value")->getIntValue(); - } - //particleSystemStartDelay - if(particleSystemNode->hasChild("particleSystemStartDelay")){ - const XmlNode *node= particleSystemNode->getChild("particleSystemStartDelay"); - particleSystemStartDelay= node->getAttribute("value")->getIntValue(); - } - //mode - if(particleSystemNode->hasChild("mode")) { - const XmlNode *modeNode= particleSystemNode->getChild("mode"); - mode= modeNode->getAttribute("value")->getRestrictedValue(); - } - else { - mode="normal"; - } + std::map mapExtraTagReplacementValues; + mapExtraTagReplacementValues["$COMMONDATAPATH"] = techtreePath + "/commondata/"; + xmlTree.load(path, Properties::getTagReplacementValues(&mapExtraTagReplacementValues)); + loadedFileList[path].push_back(make_pair(parentLoader, parentLoader)); - // child particles - if(particleSystemNode->hasChild("child-particles")) { - const XmlNode *childrenNode= particleSystemNode->getChild("child-particles"); - if(childrenNode->getAttribute("value")->getBoolValue()) { - for(unsigned int i = 0; i < childrenNode->getChildCount(); ++i) { - const XmlNode *particleFileNode= childrenNode->getChild("particle-file",i); - string path= particleFileNode->getAttribute("path")->getRestrictedValue(); - UnitParticleSystemType *unitParticleSystemType= new UnitParticleSystemType(); - string childPath= dir; - endPathWithSlash(childPath); - childPath += path; - string childDir = extractDirectoryPathFromFile(childPath); - unitParticleSystemType->load(particleFileNode,childDir,childPath,renderer,loadedFileList,parentLoader,techtreePath); - loadedFileList[childPath].push_back(make_pair(parentLoader,path)); - children.push_back(unitParticleSystemType); + const XmlNode *particleSystemNode = xmlTree.getRootNode(); + + if (particleFileNode) { + // immediate children in the particleFileNode will override the particleSystemNode + particleFileNode->setSuper(particleSystemNode); + particleSystemNode = particleFileNode; + } + + ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList, parentLoader, techtreePath); + + //emission rate fade + const XmlNode *emissionRateFadeNode = particleSystemNode->getChild("emission-rate-fade"); + emissionRateFade = emissionRateFadeNode->getAttribute("value")->getFloatValue(); + + //spread values + const XmlNode *verticalSpreadNode = particleSystemNode->getChild("vertical-spread"); + verticalSpreadA = verticalSpreadNode->getAttribute("a")->getFloatValue(0.0f, 1.0f); + verticalSpreadB = verticalSpreadNode->getAttribute("b")->getFloatValue(-1.0f, 1.0f); + + const XmlNode *horizontalSpreadNode = particleSystemNode->getChild("horizontal-spread"); + horizontalSpreadA = horizontalSpreadNode->getAttribute("a")->getFloatValue(0.0f, 1.0f); + horizontalSpreadB = horizontalSpreadNode->getAttribute("b")->getFloatValue(-1.0f, 1.0f); + } catch (const exception &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, e.what()); + throw megaglest_runtime_error("Error loading ParticleSystem: " + path + "\n" + e.what()); } } - } -} -void ParticleSystemType::setValues(AttackParticleSystem *ats){ - // add instances of all children; some settings will cascade to all children - for(Children::iterator i=children.begin(); i!=children.end(); ++i){ - UnitParticleSystem *child = new UnitParticleSystem(); - child->setParticleOwner(ats->getParticleOwner()); - child->setParticleType((*i)); - (*i)->setValues(child); - ats->addChild(child); - child->setState(ParticleSystem::sPlay); - } - ats->setTexture(texture); - ats->setPrimitive(AttackParticleSystem::strToPrimitive(primitive)); - ats->setOffset(offset); - ats->setColor(color); - ats->setColorNoEnergy(colorNoEnergy); - ats->setSpeed(speed); - ats->setSpeedUpRelative(speedUpRelative); - ats->setSpeedUpConstant(speedUpConstant); - ats->setGravity(gravity); - ats->setParticleSize(size); - ats->setSizeNoEnergy(sizeNoEnergy); - ats->setEmissionRate(emissionRate); - ats->setMaxParticleEnergy(energyMax); - ats->setVarParticleEnergy(energyVar); - ats->setModel(model); - ats->setModelCycle(modelCycle); - ats->setTeamcolorNoEnergy(teamcolorNoEnergy); - ats->setTeamcolorEnergy(teamcolorEnergy); - ats->setAlternations(alternations); - ats->setParticleSystemStartDelay(particleSystemStartDelay); - ats->setBlendMode(ParticleSystem::strToBlendMode(mode)); -} + SplashParticleSystem *ParticleSystemTypeSplash::create(ParticleOwner *owner) { + SplashParticleSystem *ps = new SplashParticleSystem(); + ps->setParticleOwner(owner); + ParticleSystemType::setValues(ps); -void ParticleSystemType::loadGame(const XmlNode *rootNode) { - const XmlNode *particleSystemTypeNode = rootNode->getChild("ParticleSystemType"); + ps->setEmissionRateFade(emissionRateFade); + ps->setVerticalSpreadA(verticalSpreadA); + ps->setVerticalSpreadB(verticalSpreadB); + ps->setHorizontalSpreadA(horizontalSpreadA); + ps->setHorizontalSpreadB(horizontalSpreadB); - type = particleSystemTypeNode->getAttribute("type")->getIntValue(); + ps->initParticleSystem(); - modelCycle = particleSystemTypeNode->getAttribute("modelCycle")->getFloatValue(); - primitive = particleSystemTypeNode->getAttribute("primitive")->getValue(); - offset = Vec3f::strToVec3(particleSystemTypeNode->getAttribute("offset")->getValue()); - color = Vec4f::strToVec4(particleSystemTypeNode->getAttribute("color")->getValue()); - colorNoEnergy = Vec4f::strToVec4(particleSystemTypeNode->getAttribute("colorNoEnergy")->getValue()); - size = particleSystemTypeNode->getAttribute("size")->getFloatValue(); - sizeNoEnergy = particleSystemTypeNode->getAttribute("sizeNoEnergy")->getFloatValue(); - speed = particleSystemTypeNode->getAttribute("speed")->getFloatValue(); - if(particleSystemTypeNode->hasAttribute("speedUpRelative")){ - speedUpRelative = particleSystemTypeNode->getAttribute("speedUpRelative")->getFloatValue(); - } - if(particleSystemTypeNode->hasAttribute("speedUpConstant")){ - speedUpConstant = particleSystemTypeNode->getAttribute("speedUpConstant")->getFloatValue(); - } - gravity = particleSystemTypeNode->getAttribute("gravity")->getFloatValue(); - emissionRate = particleSystemTypeNode->getAttribute("emissionRate")->getFloatValue(); - energyMax = particleSystemTypeNode->getAttribute("energyMax")->getIntValue(); - energyVar = particleSystemTypeNode->getAttribute("energyVar")->getIntValue(); - mode = particleSystemTypeNode->getAttribute("mode")->getValue(); - teamcolorNoEnergy = (particleSystemTypeNode->getAttribute("teamcolorNoEnergy")->getIntValue() != 0); - teamcolorEnergy = (particleSystemTypeNode->getAttribute("teamcolorEnergy")->getIntValue() != 0); - alternations = particleSystemTypeNode->getAttribute("alternations")->getIntValue(); - particleSystemStartDelay = particleSystemTypeNode->getAttribute("particleSystemStartDelay")->getIntValue(); - - if(particleSystemTypeNode->hasChild("UnitParticleSystemType")) { - vector particleSystemTypeNodeList = particleSystemTypeNode->getChildList("UnitParticleSystemType"); - for(unsigned int i = 0; i < particleSystemTypeNodeList.size(); ++i) { - XmlNode *node = particleSystemTypeNodeList[i]; - - UnitParticleSystemType *child = new UnitParticleSystemType(); - child->loadGame(node); - children.push_back(child); - } - } - minmaxEnabled = (particleSystemTypeNode->getAttribute("minmaxEnabled")->getIntValue() != 0); - minHp = particleSystemTypeNode->getAttribute("minHp")->getIntValue(); - maxHp = particleSystemTypeNode->getAttribute("maxHp")->getIntValue(); - minmaxIsPercent = (particleSystemTypeNode->getAttribute("minmaxIsPercent")->getIntValue() != 0); -} - -void ParticleSystemType::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *particleSystemTypeNode = rootNode->addChild("ParticleSystemType"); - -// string type; - particleSystemTypeNode->addAttribute("type",type, mapTagReplacements); -// Texture2D *texture; -// Model *model; -// float modelCycle; - particleSystemTypeNode->addAttribute("modelCycle",floatToStr(modelCycle,6), mapTagReplacements); -// string primitive; - particleSystemTypeNode->addAttribute("primitive",primitive, mapTagReplacements); -// Vec3f offset; - particleSystemTypeNode->addAttribute("offset",offset.getString(), mapTagReplacements); -// Vec4f color; - particleSystemTypeNode->addAttribute("color",color.getString(), mapTagReplacements); -// Vec4f colorNoEnergy; - particleSystemTypeNode->addAttribute("colorNoEnergy",colorNoEnergy.getString(), mapTagReplacements); -// float size; - particleSystemTypeNode->addAttribute("size",floatToStr(size,6), mapTagReplacements); -// float sizeNoEnergy; - particleSystemTypeNode->addAttribute("sizeNoEnergy",floatToStr(sizeNoEnergy,6), mapTagReplacements); -// float speed; - particleSystemTypeNode->addAttribute("speed",floatToStr(speed,6), mapTagReplacements); -// float speedUpRelative; - particleSystemTypeNode->addAttribute("speedUpRelative",floatToStr(speedUpRelative,6), mapTagReplacements); -// float speedUpConstant; - particleSystemTypeNode->addAttribute("speedUpConstant",floatToStr(speedUpConstant,6), mapTagReplacements); -// float gravity; - particleSystemTypeNode->addAttribute("gravity",floatToStr(gravity,6), mapTagReplacements); -// float emissionRate; - particleSystemTypeNode->addAttribute("emissionRate",floatToStr(emissionRate,6), mapTagReplacements); -// int energyMax; - particleSystemTypeNode->addAttribute("energyMax",intToStr(energyMax), mapTagReplacements); -// int energyVar; - particleSystemTypeNode->addAttribute("energyVar",intToStr(energyVar), mapTagReplacements); -// string mode; - particleSystemTypeNode->addAttribute("mode",mode, mapTagReplacements); -// bool teamcolorNoEnergy; - particleSystemTypeNode->addAttribute("teamcolorNoEnergy",intToStr(teamcolorNoEnergy), mapTagReplacements); -// bool teamcolorEnergy; - particleSystemTypeNode->addAttribute("teamcolorEnergy",intToStr(teamcolorEnergy), mapTagReplacements); -// int alternations; - particleSystemTypeNode->addAttribute("alternations",intToStr(alternations), mapTagReplacements); -// int particleSystemStartDelay; - particleSystemTypeNode->addAttribute("particleSystemStartDelay",intToStr(particleSystemStartDelay), mapTagReplacements); -// typedef std::list Children; -// Children children; - for(Children::iterator it = children.begin(); it != children.end(); ++it) { - (*it)->saveGame(particleSystemTypeNode); - } -// bool minmaxEnabled; - particleSystemTypeNode->addAttribute("minmaxEnabled",intToStr(minmaxEnabled), mapTagReplacements); -// int minHp; - particleSystemTypeNode->addAttribute("minHp",intToStr(minHp), mapTagReplacements); -// int maxHp; - particleSystemTypeNode->addAttribute("maxHp",intToStr(maxHp), mapTagReplacements); -// bool minmaxIsPercent; - particleSystemTypeNode->addAttribute("minmaxIsPercent",intToStr(minmaxIsPercent), mapTagReplacements); -} - -// =========================================================== -// class ParticleSystemTypeProjectile -// =========================================================== - -ParticleSystemTypeProjectile::ParticleSystemTypeProjectile() : ParticleSystemType() { - trajectorySpeed = 0.0f; - trajectoryScale = 0.0f; - trajectoryFrequency = 0.0f; -} - -void ParticleSystemTypeProjectile::load(const XmlNode* particleFileNode, const string &dir, const string &path, - RendererInterface *renderer, std::map > > &loadedFileList, - string parentLoader, string techtreePath) { - - try{ - XmlTree xmlTree; - - std::map mapExtraTagReplacementValues; - mapExtraTagReplacementValues["$COMMONDATAPATH"] = techtreePath + "/commondata/"; - xmlTree.load(path, Properties::getTagReplacementValues(&mapExtraTagReplacementValues)); - loadedFileList[path].push_back(make_pair(parentLoader,parentLoader)); - - const XmlNode *particleSystemNode= xmlTree.getRootNode(); - - if(particleFileNode){ - // immediate children in the particleFileNode will override the particleSystemNode - particleFileNode->setSuper(particleSystemNode); - particleSystemNode= particleFileNode; + return ps; } - ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList,parentLoader, techtreePath); + void ParticleSystemTypeSplash::saveGame(XmlNode *rootNode) { + ParticleSystemType::saveGame(rootNode); - //trajectory values - const XmlNode *tajectoryNode= particleSystemNode->getChild("trajectory"); - trajectory= tajectoryNode->getAttribute("type")->getRestrictedValue(); + std::map mapTagReplacements; + XmlNode *particleSystemTypeSplashNode = rootNode->addChild("ParticleSystemTypeSplash"); - //trajectory speed - const XmlNode *tajectorySpeedNode= tajectoryNode->getChild("speed"); - trajectorySpeed= tajectorySpeedNode->getAttribute("value")->getFloatValue() / (float)GameConstants::updateFps; - //printf("[%s] trajectorySpeed = %f\n",path.c_str(),trajectorySpeed); - - if(trajectory=="parabolic" || trajectory=="spiral"){ - //trajectory scale - const XmlNode *tajectoryScaleNode= tajectoryNode->getChild("scale"); - trajectoryScale= tajectoryScaleNode->getAttribute("value")->getFloatValue(); - } - else{ - trajectoryScale= 1.0f; + // float emissionRateFade; + particleSystemTypeSplashNode->addAttribute("emissionRateFade", floatToStr(emissionRateFade, 6), mapTagReplacements); + // float verticalSpreadA; + particleSystemTypeSplashNode->addAttribute("verticalSpreadA", floatToStr(verticalSpreadA, 6), mapTagReplacements); + // float verticalSpreadB; + particleSystemTypeSplashNode->addAttribute("verticalSpreadB", floatToStr(verticalSpreadB, 6), mapTagReplacements); + // float horizontalSpreadA; + particleSystemTypeSplashNode->addAttribute("horizontalSpreadA", floatToStr(horizontalSpreadA, 6), mapTagReplacements); + // float horizontalSpreadB; + particleSystemTypeSplashNode->addAttribute("horizontalSpreadB", floatToStr(horizontalSpreadB, 6), mapTagReplacements); } - if(trajectory=="spiral"){ - //trajectory frequency - const XmlNode *tajectoryFrequencyNode= tajectoryNode->getChild("frequency"); - trajectoryFrequency= tajectoryFrequencyNode->getAttribute("value")->getFloatValue(); - } - else{ - trajectoryFrequency= 1.0f; - } } - catch(const exception &e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what()); - throw megaglest_runtime_error("Error loading ParticleSystem: "+ path + "\n" +e.what()); - } -} - -ProjectileParticleSystem *ParticleSystemTypeProjectile::create(ParticleOwner *owner) { - ProjectileParticleSystem *ps= new ProjectileParticleSystem(); - ps->setParticleOwner(owner); - ParticleSystemType::setValues(ps); - - ps->setTrajectory(ProjectileParticleSystem::strToTrajectory(trajectory)); - - //printf("Setting trajectorySpeed = %f\n",trajectorySpeed); - ps->setTrajectorySpeed(trajectorySpeed); - ps->setTrajectoryScale(trajectoryScale); - ps->setTrajectoryFrequency(trajectoryFrequency); - - ps->initParticleSystem(); - - return ps; -} - -void ParticleSystemTypeProjectile::saveGame(XmlNode *rootNode) { - ParticleSystemType::saveGame(rootNode); - - std::map mapTagReplacements; - XmlNode *particleSystemTypeProjectileNode = rootNode->addChild("ParticleSystemTypeProjectile"); - -// string trajectory; - particleSystemTypeProjectileNode->addAttribute("trajectory",trajectory, mapTagReplacements); -// float trajectorySpeed; - particleSystemTypeProjectileNode->addAttribute("trajectorySpeed",floatToStr(trajectorySpeed,6), mapTagReplacements); -// float trajectoryScale; - particleSystemTypeProjectileNode->addAttribute("trajectoryScale",floatToStr(trajectoryScale,6), mapTagReplacements); -// float trajectoryFrequency; - particleSystemTypeProjectileNode->addAttribute("trajectoryFrequency",floatToStr(trajectoryFrequency,6), mapTagReplacements); -} - -// =========================================================== -// class ParticleSystemTypeSplash -// =========================================================== - -ParticleSystemTypeSplash::ParticleSystemTypeSplash() { - emissionRateFade = 0.0f; - verticalSpreadA = 0.0f; - verticalSpreadB = 0.0f; - horizontalSpreadA = 0.0f; - horizontalSpreadB = 0.0f; -} - -void ParticleSystemTypeSplash::load(const XmlNode* particleFileNode, const string &dir, const string &path, - RendererInterface *renderer, std::map > > &loadedFileList, - string parentLoader, string techtreePath) { - - try{ - XmlTree xmlTree; - - std::map mapExtraTagReplacementValues; - mapExtraTagReplacementValues["$COMMONDATAPATH"] = techtreePath + "/commondata/"; - xmlTree.load(path, Properties::getTagReplacementValues(&mapExtraTagReplacementValues)); - loadedFileList[path].push_back(make_pair(parentLoader,parentLoader)); - - const XmlNode *particleSystemNode= xmlTree.getRootNode(); - - if(particleFileNode){ - // immediate children in the particleFileNode will override the particleSystemNode - particleFileNode->setSuper(particleSystemNode); - particleSystemNode= particleFileNode; - } - - ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList, parentLoader, techtreePath); - - //emission rate fade - const XmlNode *emissionRateFadeNode= particleSystemNode->getChild("emission-rate-fade"); - emissionRateFade= emissionRateFadeNode->getAttribute("value")->getFloatValue(); - - //spread values - const XmlNode *verticalSpreadNode= particleSystemNode->getChild("vertical-spread"); - verticalSpreadA= verticalSpreadNode->getAttribute("a")->getFloatValue(0.0f, 1.0f); - verticalSpreadB= verticalSpreadNode->getAttribute("b")->getFloatValue(-1.0f, 1.0f); - - const XmlNode *horizontalSpreadNode= particleSystemNode->getChild("horizontal-spread"); - horizontalSpreadA= horizontalSpreadNode->getAttribute("a")->getFloatValue(0.0f, 1.0f); - horizontalSpreadB= horizontalSpreadNode->getAttribute("b")->getFloatValue(-1.0f, 1.0f); - } - catch(const exception &e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what()); - throw megaglest_runtime_error("Error loading ParticleSystem: "+ path + "\n" +e.what()); - } -} - -SplashParticleSystem *ParticleSystemTypeSplash::create(ParticleOwner *owner) { - SplashParticleSystem *ps= new SplashParticleSystem(); - ps->setParticleOwner(owner); - ParticleSystemType::setValues(ps); - - ps->setEmissionRateFade(emissionRateFade); - ps->setVerticalSpreadA(verticalSpreadA); - ps->setVerticalSpreadB(verticalSpreadB); - ps->setHorizontalSpreadA(horizontalSpreadA); - ps->setHorizontalSpreadB(horizontalSpreadB); - - ps->initParticleSystem(); - - return ps; -} - -void ParticleSystemTypeSplash::saveGame(XmlNode *rootNode) { - ParticleSystemType::saveGame(rootNode); - - std::map mapTagReplacements; - XmlNode *particleSystemTypeSplashNode = rootNode->addChild("ParticleSystemTypeSplash"); - -// float emissionRateFade; - particleSystemTypeSplashNode->addAttribute("emissionRateFade",floatToStr(emissionRateFade,6), mapTagReplacements); -// float verticalSpreadA; - particleSystemTypeSplashNode->addAttribute("verticalSpreadA",floatToStr(verticalSpreadA,6), mapTagReplacements); -// float verticalSpreadB; - particleSystemTypeSplashNode->addAttribute("verticalSpreadB",floatToStr(verticalSpreadB,6), mapTagReplacements); -// float horizontalSpreadA; - particleSystemTypeSplashNode->addAttribute("horizontalSpreadA",floatToStr(horizontalSpreadA,6), mapTagReplacements); -// float horizontalSpreadB; - particleSystemTypeSplashNode->addAttribute("horizontalSpreadB",floatToStr(horizontalSpreadB,6), mapTagReplacements); -} - -}}//end mamespace +}//end mamespace diff --git a/source/glest_game/graphics/particle_type.h b/source/glest_game/graphics/particle_type.h index 0291cbbf7..d8b99df78 100644 --- a/source/glest_game/graphics/particle_type.h +++ b/source/glest_game/graphics/particle_type.h @@ -13,8 +13,8 @@ #define _GLEST_GAME_PARTICLETYPE_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -30,139 +30,163 @@ using std::string; using namespace Shared::Graphics; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -using Shared::Graphics::ParticleSystem; -using Shared::Graphics::UnitParticleSystem; -using Shared::Graphics::AttackParticleSystem; -using Shared::Graphics::ProjectileParticleSystem; -using Shared::Graphics::SplashParticleSystem; -using Shared::Graphics::Texture2D; -using Shared::Graphics::Vec3f; -using Shared::Graphics::Vec4f; -using Shared::Graphics::Model; -using Shared::Util::MultiFactory; -using Shared::Xml::XmlNode; + using Shared::Graphics::ParticleSystem; + using Shared::Graphics::UnitParticleSystem; + using Shared::Graphics::AttackParticleSystem; + using Shared::Graphics::ProjectileParticleSystem; + using Shared::Graphics::SplashParticleSystem; + using Shared::Graphics::Texture2D; + using Shared::Graphics::Vec3f; + using Shared::Graphics::Vec4f; + using Shared::Graphics::Model; + using Shared::Util::MultiFactory; + using Shared::Xml::XmlNode; -class UnitParticleSystemType; + class UnitParticleSystemType; -// =========================================================== -// class ParticleSystemType -// -/// A type of particle system -// =========================================================== + // =========================================================== + // class ParticleSystemType + // + /// A type of particle system + // =========================================================== -class ParticleSystemType : public ParticleSystemTypeInterface { -protected: - string type; - Texture2D *texture; - Model *model; - float modelCycle; - string primitive; - Vec3f offset; - Vec4f color; - Vec4f colorNoEnergy; - float size; - float sizeNoEnergy; - float speed; - float speedUpRelative; - float speedUpConstant; - float gravity; - float emissionRate; - int energyMax; - int energyVar; - string mode; - bool teamcolorNoEnergy; - bool teamcolorEnergy; - int alternations; - int particleSystemStartDelay; - typedef std::list Children; - Children children; + class ParticleSystemType : public ParticleSystemTypeInterface { + protected: + string type; + Texture2D *texture; + Model *model; + float modelCycle; + string primitive; + Vec3f offset; + Vec4f color; + Vec4f colorNoEnergy; + float size; + float sizeNoEnergy; + float speed; + float speedUpRelative; + float speedUpConstant; + float gravity; + float emissionRate; + int energyMax; + int energyVar; + string mode; + bool teamcolorNoEnergy; + bool teamcolorEnergy; + int alternations; + int particleSystemStartDelay; + typedef std::list Children; + Children children; - bool minmaxEnabled; - int minHp; - int maxHp; - bool minmaxIsPercent; + bool minmaxEnabled; + int minHp; + int maxHp; + bool minmaxIsPercent; - void copyAll(const ParticleSystemType &src); -public: + void copyAll(const ParticleSystemType &src); + public: - ParticleSystemType(); - virtual ~ParticleSystemType(); + ParticleSystemType(); + virtual ~ParticleSystemType(); - ParticleSystemType & operator=(const ParticleSystemType &src); - ParticleSystemType(const ParticleSystemType &src); + ParticleSystemType & operator=(const ParticleSystemType &src); + ParticleSystemType(const ParticleSystemType &src); - void load(const XmlNode *particleSystemNode, const string &dir, - RendererInterface *renderer, std::map > > &loadedFileList, - string parentLoader, string techtreePath); - void setValues(AttackParticleSystem *ats); - bool hasTexture() const { return(texture != NULL); } - bool hasModel() const { return(model != NULL); } + void load(const XmlNode *particleSystemNode, const string &dir, + RendererInterface *renderer, std::map > > &loadedFileList, + string parentLoader, string techtreePath); + void setValues(AttackParticleSystem *ats); + bool hasTexture() const { + return(texture != NULL); + } + bool hasModel() const { + return(model != NULL); + } - bool getMinmaxEnabled() const { return minmaxEnabled;} - int getMinHp() const { return minHp;} - int getMaxHp() const { return maxHp;} - bool getMinmaxIsPercent() const { return minmaxIsPercent; } + bool getMinmaxEnabled() const { + return minmaxEnabled; + } + int getMinHp() const { + return minHp; + } + int getMaxHp() const { + return maxHp; + } + bool getMinmaxIsPercent() const { + return minmaxIsPercent; + } - void setMinmaxEnabled(bool value) { minmaxEnabled=value;} - void setMinHp(int value) { minHp=value;} - void setMaxHp(int value) { maxHp=value;} - void setMinmaxIsPercent(bool value) { minmaxIsPercent=value; } + void setMinmaxEnabled(bool value) { + minmaxEnabled = value; + } + void setMinHp(int value) { + minHp = value; + } + void setMaxHp(int value) { + maxHp = value; + } + void setMinmaxIsPercent(bool value) { + minmaxIsPercent = value; + } - string getType() const { return type; }; + string getType() const { + return type; + }; - virtual void saveGame(XmlNode *rootNode); - virtual void loadGame(const XmlNode *rootNode); + virtual void saveGame(XmlNode *rootNode); + virtual void loadGame(const XmlNode *rootNode); -protected: + protected: -}; + }; -// =========================================================== -// class ParticleSystemTypeProjectile -// =========================================================== + // =========================================================== + // class ParticleSystemTypeProjectile + // =========================================================== -class ParticleSystemTypeProjectile: public ParticleSystemType{ -private: - string trajectory; - float trajectorySpeed; - float trajectoryScale; - float trajectoryFrequency; + class ParticleSystemTypeProjectile : public ParticleSystemType { + private: + string trajectory; + float trajectorySpeed; + float trajectoryScale; + float trajectoryFrequency; -public: - ParticleSystemTypeProjectile(); - void load(const XmlNode *particleFileNode, const string &dir, const string &path, - RendererInterface *renderer, std::map > > &loadedFileList, - string parentLoader, string techtreePath); - ProjectileParticleSystem *create(ParticleOwner *owner); + public: + ParticleSystemTypeProjectile(); + void load(const XmlNode *particleFileNode, const string &dir, const string &path, + RendererInterface *renderer, std::map > > &loadedFileList, + string parentLoader, string techtreePath); + ProjectileParticleSystem *create(ParticleOwner *owner); - virtual void saveGame(XmlNode *rootNode); -}; + virtual void saveGame(XmlNode *rootNode); + }; -// =========================================================== -// class ParticleSystemTypeSplash -// =========================================================== + // =========================================================== + // class ParticleSystemTypeSplash + // =========================================================== -class ParticleSystemTypeSplash: public ParticleSystemType { -public: + class ParticleSystemTypeSplash : public ParticleSystemType { + public: - ParticleSystemTypeSplash(); - void load(const XmlNode *particleFileNode, const string &dir, const string &path, - RendererInterface *renderer, std::map > > &loadedFileList, - string parentLoader, string techtreePath); - SplashParticleSystem *create(ParticleOwner *owner); + ParticleSystemTypeSplash(); + void load(const XmlNode *particleFileNode, const string &dir, const string &path, + RendererInterface *renderer, std::map > > &loadedFileList, + string parentLoader, string techtreePath); + SplashParticleSystem *create(ParticleOwner *owner); - virtual void saveGame(XmlNode *rootNode); + virtual void saveGame(XmlNode *rootNode); -private: - float emissionRateFade; - float verticalSpreadA; - float verticalSpreadB; - float horizontalSpreadA; - float horizontalSpreadB; -}; + private: + float emissionRateFade; + float verticalSpreadA; + float verticalSpreadB; + float horizontalSpreadA; + float horizontalSpreadB; + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index d1539b82e..21553fef6 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -36,5315 +36,4818 @@ using namespace Shared::Graphics::Gl; using namespace Shared::Util; using namespace Shared::Graphics; -namespace Glest { namespace Game{ +namespace Glest { + namespace Game { -uint32 Renderer::SurfaceData::nextUniqueId = 1; -bool Renderer::renderText3DEnabled = true; + uint32 Renderer::SurfaceData::nextUniqueId = 1; + bool Renderer::renderText3DEnabled = true; -//const float SKIP_INTERPOLATION_DISTANCE = 20.0f; -const string DEFAULT_CHAR_FOR_WIDTH_CALC = "V"; + //const float SKIP_INTERPOLATION_DISTANCE = 20.0f; + const string DEFAULT_CHAR_FOR_WIDTH_CALC = "V"; -enum PROJECTION_TO_INFINITY { - pti_D_IS_ZERO, - pti_N_OVER_D_IS_OUTSIDE -}; - -// ===================================================== -// class MeshCallbackTeamColor -// ===================================================== - -bool MeshCallbackTeamColor::noTeamColors = false; - -void MeshCallbackTeamColor::execute(const Mesh *mesh) { - //team color - if( mesh->getCustomTexture() && teamTexture != NULL && - MeshCallbackTeamColor::noTeamColors == false) { - //texture 0 - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - - //set color to interpolation - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE1); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); - - //set alpha to 1 - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); - - //texture 1 - glActiveTexture(GL_TEXTURE1); - glMultiTexCoord2f(GL_TEXTURE1, 0.f, 0.f); - glEnable(GL_TEXTURE_2D); - - glBindTexture(GL_TEXTURE_2D, static_cast(teamTexture)->getHandle()); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); - - //set alpha to 1 - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); - - glActiveTexture(GL_TEXTURE0); - } - else { - glActiveTexture(GL_TEXTURE1); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - } -} - -// =========================================================== -// class Renderer -// =========================================================== - -// ===================== PUBLIC ======================== - -const int Renderer::maxProgressBar= 100; -const Vec4f Renderer::progressBarBack1= Vec4f(0.7f, 0.7f, 0.7f, 0.7f); -const Vec4f Renderer::progressBarBack2= Vec4f(0.7f, 0.7f, 0.7f, 1.f); -const Vec4f Renderer::progressBarFront1= Vec4f(0.f, 0.5f, 0.f, 1.f); -const Vec4f Renderer::progressBarFront2= Vec4f(0.f, 0.1f, 0.f, 1.f); - -const float Renderer::sunDist= 10e6; -const float Renderer::moonDist= 10e6; -const float Renderer::lightAmbFactor= 0.4f; - -const int Renderer::maxMouse2dAnim= 100; - -const GLenum Renderer::baseTexUnit= GL_TEXTURE0; -const GLenum Renderer::fowTexUnit= GL_TEXTURE1; -const GLenum Renderer::shadowTexUnit= GL_TEXTURE2; - -const float Renderer::selectionCircleRadius= 0.7f; -const float Renderer::magicCircleRadius= 1.f; - -//perspective values -const float Renderer::perspFov= 60.f; -const float Renderer::perspNearPlane= 1.f; -//const float Renderer::perspFarPlane= 50.f; -float Renderer::perspFarPlane= 1000000.f; - -const float Renderer::ambFactor= 0.7f; -const Vec4f Renderer::fowColor= Vec4f(0.0f, 0.0f, 0.0f, 1.0f); -const Vec4f Renderer::defSpecularColor= Vec4f(0.8f, 0.8f, 0.8f, 1.f); -const Vec4f Renderer::defDiffuseColor= Vec4f(1.f, 1.f, 1.f, 1.f); -const Vec4f Renderer::defAmbientColor= Vec4f(1.f * ambFactor, 1.f * ambFactor, 1.f * ambFactor, 1.f); -const Vec4f Renderer::defColor= Vec4f(1.f, 1.f, 1.f, 1.f); - -//const float Renderer::maxLightDist= 100.f; -const float Renderer::maxLightDist= 100.f; - -bool Renderer::rendererEnded = true; - -const int MIN_FPS_NORMAL_RENDERING = 15; -const int MIN_FPS_NORMAL_RENDERING_TOP_THRESHOLD = 25; - -const int OBJECT_SELECT_OFFSET=100000000; - -bool VisibleQuadContainerCache::enableFrustumCalcs = true; - -// ==================== constructor and destructor ==================== - -Renderer::Renderer() : BaseRenderer(), saveScreenShotThreadAccessor(new Mutex(CODE_AT_LINE)) { - //this->masterserverMode = masterserverMode; - //printf("this->masterserverMode = %d\n",this->masterserverMode); - //assert(0==1); - - Renderer::rendererEnded = false; - shadowIntensity = 0; - shadowFrameSkip = 0; - triangleCount = 0; - smoothedRenderFps = 0; - shadowTextureSize = 0; - shadows = sDisabled; - shadowMapFrame = 0; - textures3D = false; - photoMode = false; - focusArrows = false; - pointCount = 0; - maxLights = 0; - waterAnim = 0; - - this->allowRenderUnitTitles = false; - this->menu = NULL; - this->game = NULL; - this->gameCamera = NULL; - showDebugUI = false; - showDebugUILevel = debugui_fps; - modelRenderer = NULL; - textRenderer = NULL; - textRenderer3D = NULL; - particleRenderer = NULL; - saveScreenShotThread = NULL; - mapSurfaceData.clear(); - visibleFrameUnitList.clear(); - visibleFrameUnitListCameraKey = ""; - - quadCache = VisibleQuadContainerCache(); - quadCache.clearFrustumData(); - - lastRenderFps=MIN_FPS_NORMAL_RENDERING; - shadowsOffDueToMinRender=false; - shadowMapHandle=0; - shadowMapHandleValid=false; - - //list3d=0; - //list3dValid=false; - //list2d=0; - //list2dValid=false; - //list3dMenu=0; - //list3dMenuValid=false; - //customlist3dMenu=NULL; - //this->mm3d = NULL; - this->custom_mm3d = NULL; - - this->program = NULL; - - //resources - for(int i=0; i < rsCount; ++i) { - modelManager[i] = NULL; - textureManager[i] = NULL; - particleManager[i] = NULL; - fontManager[i] = NULL; - } - - Config &config= Config::getInstance(); - - Renderer::perspFarPlane = config.getFloat("PerspectiveFarPlane",floatToStr(Renderer::perspFarPlane).c_str()); - this->no2DMouseRendering = config.getBool("No2DMouseRendering","false"); - this->maxConsoleLines= config.getInt("ConsoleMaxLines"); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Renderer::perspFarPlane [%f] this->no2DMouseRendering [%d] this->maxConsoleLines [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,Renderer::perspFarPlane,this->no2DMouseRendering,this->maxConsoleLines); - - GraphicsInterface &gi= GraphicsInterface::getInstance(); - FactoryRepository &fr= FactoryRepository::getInstance(); - gi.setFactory(fr.getGraphicsFactory(config.getString("FactoryGraphics"))); - GraphicsFactory *graphicsFactory= GraphicsInterface::getInstance().getFactory(); - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - modelRenderer= graphicsFactory->newModelRenderer(); - textRenderer= graphicsFactory->newTextRenderer2D(); - textRenderer3D = graphicsFactory->newTextRenderer3D(); - particleRenderer= graphicsFactory->newParticleRenderer(); - } - - //resources - for(int i=0; i< rsCount; ++i) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - modelManager[i]= graphicsFactory->newModelManager(); - textureManager[i]= graphicsFactory->newTextureManager(); - modelManager[i]->setTextureManager(textureManager[i]); - fontManager[i]= graphicsFactory->newFontManager(); - } - particleManager[i]= graphicsFactory->newParticleManager(); - } - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); - saveScreenShotThread = new SimpleTaskThread(this,0,25); - saveScreenShotThread->setUniqueID(mutexOwnerId); - saveScreenShotThread->start(); - } -} - -void Renderer::cleanupScreenshotThread() { - if(saveScreenShotThread) { - saveScreenShotThread->signalQuit(); -// for(time_t elapsed = time(NULL); -// getSaveScreenQueueSize() > 0 && difftime((long int)time(NULL),elapsed) <= 7;) { -// sleep(0); -// } -// if(saveScreenShotThread->canShutdown(true) == true && -// saveScreenShotThread->shutdownAndWait() == true) { -// //printf("IN MenuStateCustomGame cleanup - C\n"); -// delete saveScreenShotThread; -// } -// saveScreenShotThread = NULL; - if(saveScreenShotThread->shutdownAndWait() == true) { - delete saveScreenShotThread; - } - saveScreenShotThread = NULL; - - - if(getSaveScreenQueueSize() > 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] FORCING MEMORY CLEANUP and NOT SAVING screenshots, saveScreenQueue.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,saveScreenQueue.size()); - - static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(saveScreenShotThreadAccessor,mutexOwnerId); - for(std::list >::iterator iter = saveScreenQueue.begin(); - iter != saveScreenQueue.end(); ++iter) { - delete iter->second; - } - saveScreenQueue.clear(); - } - } -} - -Renderer::~Renderer() { - try{ - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - delete modelRenderer; - modelRenderer = NULL; - delete textRenderer; - textRenderer = NULL; - delete textRenderer3D; - textRenderer3D = NULL; - delete particleRenderer; - particleRenderer = NULL; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //resources - for(int i=0; imenu = NULL; - this->game = NULL; - this->gameCamera = NULL; - - delete saveScreenShotThreadAccessor; - saveScreenShotThreadAccessor = NULL; - } - catch(const exception &e) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what()); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf); - - throw megaglest_runtime_error(szBuf); - } -} - -void Renderer::simpleTask(BaseThread *callingThread,void *userdata) { - // This code reads pixmaps from a queue and saves them to disk - Pixmap2D *savePixMapBuffer=NULL; - string path=""; - static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(saveScreenShotThreadAccessor,mutexOwnerId); - if(saveScreenQueue.empty() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] saveScreenQueue.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,saveScreenQueue.size()); - - savePixMapBuffer = saveScreenQueue.front().second; - path = saveScreenQueue.front().first; - - saveScreenQueue.pop_front(); - } - safeMutex.ReleaseLock(); - - if(savePixMapBuffer != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] about to save [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str()); - - savePixMapBuffer->save(path); - delete savePixMapBuffer; - } -} - -bool Renderer::isEnded() { - return Renderer::rendererEnded; -} - -Renderer &Renderer::getInstance() { - static Renderer renderer; - return renderer; -} - -void Renderer::reinitAll() { - //resources - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - for(int i=0; iinit(); - textureManager[i]->init(true); - //particleManager[i]->init(); - //fontManager[i]->init(); - } -} -// ==================== init ==================== - -void Renderer::init() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - Config &config= Config::getInstance(); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - loadConfig(); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(config.getBool("CheckGlCaps")){ - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - checkGlCaps(); - } - - if(glActiveTexture == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error: glActiveTexture == NULL\nglActiveTexture is only supported if the GL version is 1.3 or greater,\nor if the ARB_multitexture extension is supported!"); - throw megaglest_runtime_error(szBuf); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(config.getBool("FirstTime")){ - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - config.setBool("FirstTime", false); - autoConfig(); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - config.save(); - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - modelManager[rsGlobal]->init(); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - textureManager[rsGlobal]->init(); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - fontManager[rsGlobal]->init(); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - init2dList(); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - glHint(GL_FOG_HINT, GL_FASTEST); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST); - glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); - //glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST); - - //glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST); - glHint(GL_TEXTURE_COMPRESSION_HINT, GL_FASTEST); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - -} - -void Renderer::initGame(const Game *game, GameCamera *gameCamera) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - this->gameCamera = gameCamera; - VisibleQuadContainerCache::enableFrustumCalcs = Config::getInstance().getBool("EnableFrustrumCalcs","true"); - quadCache = VisibleQuadContainerCache(); - quadCache.clearFrustumData(); - - SurfaceData::nextUniqueId = 1; - mapSurfaceData.clear(); - this->game= game; - worldToScreenPosCache.clear(); - - //vars - shadowMapFrame= 0; - waterAnim= 0; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - //check gl caps - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - checkGlOptionalCaps(); - - //shadows - if(shadows == sProjected || shadows == sShadowMapping) { - static_cast(modelRenderer)->setSecondaryTexCoordUnit(2); - Config &config= Config::getInstance(); - - glGenTextures(1, &shadowMapHandle); - shadowMapHandleValid=true; - - shadowIntensity= config.getFloat("ShadowIntensity","1.0"); - if(game!=NULL){ - shadowIntensity=shadowIntensity*game->getWorld()->getTileset()->getShadowIntense(); - if(shadowIntensity > 1.0f){ - shadowIntensity=1.0f; - } - } - - glBindTexture(GL_TEXTURE_2D, shadowMapHandle); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - if(shadows == sShadowMapping) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //shadow mapping - glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); - //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 1.0f-shadowAlpha); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, - shadowTextureSize, shadowTextureSize, - 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //projected - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, - shadowTextureSize, shadowTextureSize, - 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); - } - - shadowMapFrame= -1; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - IF_DEBUG_EDITION( getDebugRenderer().init(); ) - - //texture init - modelManager[rsGame]->init(); - textureManager[rsGame]->init(); - fontManager[rsGame]->init(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - init3dList(); -} - -void Renderer::manageDeferredParticleSystems() { - -// if(deferredParticleSystems.empty() == false) { -// printf("deferredParticleSystems.size() = %d\n",(int)deferredParticleSystems.size()); -// } - - for(unsigned int i = 0; i < deferredParticleSystems.size(); ++i) { - std::pair &deferredParticleSystem = deferredParticleSystems[i]; - ParticleSystem *ps = deferredParticleSystem.first; - ResourceScope rs = deferredParticleSystem.second; - if(ps->getTextureFileLoadDeferred() != "" && ps->getTexture() == NULL) { - CoreData::TextureSystemType textureSystemId = - static_cast( - ps->getTextureFileLoadDeferredSystemId()); - - //printf("Load DEFERRED particle i = %d textureSystemId = %d\n",i,textureSystemId); - - if(textureSystemId != CoreData::tsyst_NONE) { - Texture2D *texture= CoreData::getInstance().getTextureBySystemId(textureSystemId); - //printf("Loading texture from system [%d] [%p]\n",textureSystemId,texture); - ps->setTexture(texture); - - //printf("#2 Load DEFERRED particle i = %d textureSystemId = %d, texture = %p\n",i,textureSystemId,texture); - } - else { - Texture2D *texture= newTexture2D(rs); - if(texture) { - texture->setFormat(ps->getTextureFileLoadDeferredFormat()); - texture->getPixmap()->init(ps->getTextureFileLoadDeferredComponents()); - } - if(texture) { - string textureFile = ps->getTextureFileLoadDeferred(); - if(fileExists(textureFile) == false) { - textureFile = Config::findValidLocalFileFromPath(textureFile); - } - texture->load(textureFile); - ps->setTexture(texture); - } - //printf("#3 Load DEFERRED particle i = %d textureSystemId = %d, texture = %p\n",i,textureSystemId,texture); - } - } - if(dynamic_cast(ps) != NULL) { - GameParticleSystem *gps = dynamic_cast(ps); - if(gps != NULL && gps->getModelFileLoadDeferred() != "" && gps->getModel() == NULL) { - std::map > > loadedFileList; - Model *model= newModel(rsGame, gps->getModelFileLoadDeferred(), false, &loadedFileList, NULL); - if(model) - gps->setModel(model); - } - } - manageParticleSystem(ps, rs); - //printf("Managing ps [%p]\n",ps); - } - deferredParticleSystems.clear(); - //printf("After deferredParticleSystems.size() = %d\n",deferredParticleSystems.size()); -} - -void Renderer::initMenu(const MainMenu *mm) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - this->menu = mm; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - modelManager[rsMenu]->init(); - textureManager[rsMenu]->init(); - fontManager[rsMenu]->init(); - //modelRenderer->setCustomTexture(CoreData::getInstance().getCustomTexture()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //init3dListMenu(mm); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void Renderer::reset3d() { - assertGl(); - glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); - //glCallList(list3d); - render3dSetup(); - - pointCount= 0; - triangleCount= 0; - assertGl(); -} - -void Renderer::reset2d() { - assertGl(); - glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR); - //glCallList(list2d); - render2dMenuSetup(); - assertGl(); -} - -void Renderer::reset3dMenu() { - assertGl(); - glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR); - - //printf("In [%s::%s Line: %d] this->custom_mm3d [%p] this->mm3d [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->custom_mm3d,this->mm3d); - - if(this->custom_mm3d != NULL) { - render3dMenuSetup(this->custom_mm3d); - //glCallList(*this->customlist3dMenu); - } - else { - render3dMenuSetup(this->menu); - //render3dMenuSetup(this->mm3d); - //glCallList(list3dMenu); - } - - assertGl(); -} - -// ==================== end ==================== - -void Renderer::end() { - quadCache = VisibleQuadContainerCache(); - quadCache.clearFrustumData(); - - if(Renderer::rendererEnded == true) { - return; - } - std::map &crcFactionPreviewTextureCache = CacheManager::getCachedItem< std::map >(GameConstants::factionPreviewTextureCacheLookupKey); - crcFactionPreviewTextureCache.clear(); - - // Wait for the queue to become empty or timeout the thread at 7 seconds - cleanupScreenshotThread(); - - mapSurfaceData.clear(); - - //delete resources - if(modelManager[rsGlobal]) { - modelManager[rsGlobal]->end(); - } - if(textureManager[rsGlobal]) { - textureManager[rsGlobal]->end(); - } - if(fontManager[rsGlobal]) { - fontManager[rsGlobal]->end(); - } - if(particleManager[rsGlobal]) { - particleManager[rsGlobal]->end(); - } - - //delete 2d list - //if(list2dValid == true) { - // glDeleteLists(list2d, 1); - // list2dValid=false; - //} - - Renderer::rendererEnded = true; -} - -void Renderer::endScenario() { - this->game= NULL; - this->gameCamera = NULL; - quadCache = VisibleQuadContainerCache(); - quadCache.clearFrustumData(); - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - //delete resources - //modelManager[rsGame]->end(); - //textureManager[rsGame]->end(); - //fontManager[rsGame]->end(); - //particleManager[rsGame]->end(); - - if(shadowMapHandleValid == true && - (shadows == sProjected || shadows == sShadowMapping)) { - glDeleteTextures(1, &shadowMapHandle); - shadowMapHandleValid=false; - } - - //if(list3dValid == true) { - // glDeleteLists(list3d, 1); - // list3dValid=false; - //} - - worldToScreenPosCache.clear(); - ReleaseSurfaceVBOs(); - mapSurfaceData.clear(); -} - -void Renderer::endGame(bool isFinalEnd) { - this->game= NULL; - this->gameCamera = NULL; - Config &config= Config::getInstance(); - - try { - quadCache = VisibleQuadContainerCache(); - quadCache.clearFrustumData(); - } - catch(const exception &e) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what()); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf); - - abort(); - } - - if(isFinalEnd) { - //delete resources - if(modelManager[rsGame] != NULL) { - modelManager[rsGame]->end(); - } - if(textureManager[rsGame] != NULL) { - textureManager[rsGame]->end(); - } - if(fontManager[rsGame] != NULL) { - fontManager[rsGame]->end(); - } - if(particleManager[rsGame] != NULL) { - particleManager[rsGame]->end(); - } - } - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(shadowMapHandleValid == true && - (shadows == sProjected || shadows == sShadowMapping)) { - glDeleteTextures(1, &shadowMapHandle); - shadowMapHandleValid=false; - } - shadowIntensity= config.getFloat("ShadowIntensity","1.0"); - - //if(list3dValid == true) { - // glDeleteLists(list3d, 1); - // list3dValid=false; - //} - - worldToScreenPosCache.clear(); - ReleaseSurfaceVBOs(); - mapSurfaceData.clear(); -} - -void Renderer::endMenu() { - this->menu = NULL; - - //delete resources - if(modelManager[rsMenu]) { - modelManager[rsMenu]->end(); - } - if(textureManager[rsMenu]) { - textureManager[rsMenu]->end(); - } - if(fontManager[rsMenu]) { - fontManager[rsMenu]->end(); - } - if(particleManager[rsMenu]) { - particleManager[rsMenu]->end(); - } - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - //if(this->customlist3dMenu != NULL) { - // glDeleteLists(*this->customlist3dMenu,1); - //} - //else { - // glDeleteLists(list3dMenu, 1); - //} -} - -//void Renderer::reloadResources() { -// if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { -// return; -// } -// -// for(int i=0; iend(); -// textureManager[i]->end(); -// fontManager[i]->end(); -// } -// -// for(int i=0; iinit(); -// textureManager[i]->init(); -// fontManager[i]->init(); -// } -//} - -// ==================== engine interface ==================== - -void Renderer::initTexture(ResourceScope rs, Texture *texture) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - textureManager[rs]->initTexture(texture); -} - -void Renderer::endTexture(ResourceScope rs, Texture *texture, bool mustExistInList) { - string textureFilename = texture->getPath(); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] free texture from manager [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,textureFilename.c_str()); - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - textureManager[rs]->endTexture(texture,mustExistInList); - - if(rs == rsGlobal) { - std::map &crcFactionPreviewTextureCache = CacheManager::getCachedItem< std::map >(GameConstants::factionPreviewTextureCacheLookupKey); - if(crcFactionPreviewTextureCache.find(textureFilename) != crcFactionPreviewTextureCache.end()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] textureFilename [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,textureFilename.c_str()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] free texture from cache [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,textureFilename.c_str()); - - crcFactionPreviewTextureCache.erase(textureFilename); - } - } -} -void Renderer::endLastTexture(ResourceScope rs, bool mustExistInList) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - textureManager[rs]->endLastTexture(mustExistInList); -} - -Model *Renderer::newModel(ResourceScope rs,const string &path,bool deletePixMapAfterLoad,std::map > > *loadedFileList, string *sourceLoader){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return NULL; - } - - return modelManager[rs]->newModel(path,deletePixMapAfterLoad,loadedFileList,sourceLoader); -} - -void Renderer::endModel(ResourceScope rs, Model *model,bool mustExistInList) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - modelManager[rs]->endModel(model,mustExistInList); -} -void Renderer::endLastModel(ResourceScope rs, bool mustExistInList) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - modelManager[rs]->endLastModel(mustExistInList); -} - -Texture2D *Renderer::newTexture2D(ResourceScope rs){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return NULL; - } - - return textureManager[rs]->newTexture2D(); -} - -Texture3D *Renderer::newTexture3D(ResourceScope rs){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return NULL; - } - - return textureManager[rs]->newTexture3D(); -} - -Font2D *Renderer::newFont(ResourceScope rs){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return NULL; - } - - return fontManager[rs]->newFont2D(); -} - -Font3D *Renderer::newFont3D(ResourceScope rs){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return NULL; - } - - return fontManager[rs]->newFont3D(); -} - -void Renderer::endFont(::Shared::Graphics::Font *font, ResourceScope rs, bool mustExistInList) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - fontManager[rs]->endFont(font,mustExistInList); -} - -//void Renderer::resetFontManager(ResourceScope rs) { -// if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { -// return; -// } -// fontManager[rs]->end(); -// fontManager[rsGlobal]->init(); -//} - -void Renderer::addToDeferredParticleSystemList(std::pair deferredParticleSystem) { - deferredParticleSystems.push_back(deferredParticleSystem); -} - -void Renderer::manageParticleSystem(ParticleSystem *particleSystem, ResourceScope rs){ - particleManager[rs]->manage(particleSystem); -} - -bool Renderer::validateParticleSystemStillExists(ParticleSystem * particleSystem,ResourceScope rs) const { - return particleManager[rs]->validateParticleSystemStillExists(particleSystem); -} - -void Renderer::removeParticleSystemsForParticleOwner(ParticleOwner * particleOwner,ResourceScope rs) { - particleManager[rs]->removeParticleSystemsForParticleOwner(particleOwner); -} - -void Renderer::cleanupParticleSystems(vector &particleSystems, ResourceScope rs) { - particleManager[rs]->cleanupParticleSystems(particleSystems); -} - -void Renderer::cleanupUnitParticleSystems(vector &particleSystems, ResourceScope rs) { - particleManager[rs]->cleanupUnitParticleSystems(particleSystems); -} - -void Renderer::updateParticleManager(ResourceScope rs, int renderFps) { - particleManager[rs]->update(renderFps); -} - -void Renderer::renderParticleManager(ResourceScope rs){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - glDepthFunc(GL_LESS); - particleRenderer->renderManager(particleManager[rs], modelRenderer); - glPopAttrib(); -} - -void Renderer::swapBuffers() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - //glFlush(); // should not be required - http://www.opengl.org/wiki/Common_Mistakes - //glFlush(); - - GraphicsInterface::getInstance().getCurrentContext()->swapBuffers(); -} - -// ==================== lighting ==================== - -//places all the opengl lights -void Renderer::setupLighting() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - int lightCount= 0; - const World *world= game->getWorld(); - const GameCamera *gameCamera= game->getGameCamera(); - const TimeFlow *timeFlow= world->getTimeFlow(); - float time= timeFlow->getTime(); - - assertGl(); - - //sun/moon light - Vec3f lightColor= timeFlow->computeLightColor(); - Vec3f fogColor= world->getTileset()->getFogColor(); - Vec4f lightPos= timeFlow->isDay()? computeSunPos(time): computeMoonPos(time); - nearestLightPos= lightPos; - - glLightfv(GL_LIGHT0, GL_POSITION, lightPos.ptr()); - glLightfv(GL_LIGHT0, GL_AMBIENT, Vec4f(lightColor*lightAmbFactor, 1.f).ptr()); - glLightfv(GL_LIGHT0, GL_DIFFUSE, Vec4f(lightColor, 1.f).ptr()); - glLightfv(GL_LIGHT0, GL_SPECULAR, Vec4f(0.0f, 0.0f, 0.f, 1.f).ptr()); - - glFogfv(GL_FOG_COLOR, Vec4f(fogColor*lightColor, 1.f).ptr()); - - lightCount++; - - //disable all secondary lights - for(int i= 1; i < maxLights; ++i) { - glDisable(GL_LIGHT0 + i); - } - - //unit lights (not projectiles) - - if(timeFlow->isTotalNight()) { - VisibleQuadContainerCache &qCache = getQuadCache(); - if(qCache.visibleQuadUnitList.empty() == false) { - //bool modelRenderStarted = false; - for(int visibleUnitIndex = 0; - visibleUnitIndex < (int)qCache.visibleQuadUnitList.size() && lightCount < maxLights; - ++visibleUnitIndex) { - Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; - - if(world->toRenderUnit(unit) && - unit->getCurrMidHeightVector().dist(gameCamera->getPos()) < maxLightDist && - unit->getType()->getLight() && unit->isOperative()) { - //printf("$$$ Show light for faction: %s # %d / %d for Unit [%d - %s]\n",world->getFaction(i)->getType()->getName().c_str(),lightCount,maxLights,unit->getId(),unit->getFullName().c_str()); - - Vec4f pos= Vec4f(unit->getCurrMidHeightVector()); - pos.y+=4.f; - - GLenum lightEnum= GL_LIGHT0 + lightCount; - - glEnable(lightEnum); - glLightfv(lightEnum, GL_POSITION, pos.ptr()); - glLightfv(lightEnum, GL_AMBIENT, Vec4f(unit->getType()->getLightColor()).ptr()); - glLightfv(lightEnum, GL_DIFFUSE, Vec4f(unit->getType()->getLightColor()).ptr()); - glLightfv(lightEnum, GL_SPECULAR, Vec4f(unit->getType()->getLightColor()*0.3f).ptr()); - glLightf(lightEnum, GL_QUADRATIC_ATTENUATION, 0.05f); - - ++lightCount; - - const GameCamera *gameCamera= game->getGameCamera(); - - if(Vec3f(pos).dist(gameCamera->getPos())getPos())){ - nearestLightPos= pos; - } - } - } - } - } - - assertGl(); -} - -//void Renderer::setupLightingForRotatedModel() { -// if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { -// return; -// } -// -// const World *world= game->getWorld(); -// //const GameCamera *gameCamera= game->getGameCamera(); -// const TimeFlow *timeFlow= world->getTimeFlow(); -// float time= timeFlow->getTime(); -// -// assertGl(); -// -// //sun/moon light -// Vec3f lightColor= timeFlow->computeLightColor(); -// Vec3f fogColor= world->getTileset()->getFogColor(); -// Vec4f lightPos= timeFlow->isDay()? computeSunPos(time): computeMoonPos(time); -// //nearestLightPos= lightPos; -// -// glLightfv(GL_LIGHT0, GL_POSITION, lightPos.ptr()); -// glLightfv(GL_LIGHT0, GL_AMBIENT, Vec4f(lightColor*lightAmbFactor, 1.f).ptr()); -// glLightfv(GL_LIGHT0, GL_DIFFUSE, Vec4f(lightColor, 1.f).ptr()); -// glLightfv(GL_LIGHT0, GL_SPECULAR, Vec4f(0.0f, 0.0f, 0.f, 1.f).ptr()); -// -// glFogfv(GL_FOG_COLOR, Vec4f(fogColor*lightColor, 1.f).ptr()); -// -// assertGl(); -//} - -void Renderer::loadGameCameraMatrix() { - const GameCamera *gameCamera= game->getGameCamera(); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - if(gameCamera != NULL) { - glRotatef(gameCamera->getVAng(), -1, 0, 0); - glRotatef(gameCamera->getHAng(), 0, 1, 0); - glTranslatef(-(gameCamera->getPos().x + gameCamera->getShakeOffset().x), - -gameCamera->getPos().y, - -(gameCamera->getPos().z + gameCamera->getShakeOffset().y)); - } -} - -void Renderer::loadCameraMatrix(const Camera *camera) { - const Vec3f &position= camera->getConstPosition(); - Quaternion orientation= camera->getOrientation().conjugate(); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glMultMatrixf(orientation.toMatrix4().ptr()); - glTranslatef(-position.x, -position.y, -position.z); -} - -static Vec2i _unprojectMap(const Vec2i& pt,const GLdouble* model,const GLdouble* projection,const GLint* viewport,const char* label=NULL) { - Vec3d a,b; - /* note viewport[3] is height of window in pixels */ - GLint realy = viewport[3] - (GLint) pt.y; - gluUnProject(pt.x,realy,0,model,projection,viewport,&a.x,&a.y,&a.z); - gluUnProject(pt.x,realy,1,model,projection,viewport,&b.x,&b.y,&b.z); - - // junk values if you were looking parallel to the XZ plane; this shouldn't happen as the camera can't do this? - const Vec3f - start(a.x,a.y,a.z), - stop(b.x,b.y,b.z), - plane(0,0,0), - norm(0,1,0), - u = stop-start, - w = start-plane; - const float d = norm.x*u.x + norm.y*u.y + norm.z*u.z; - if(std::fabs(d) < 0.00001) - throw pti_D_IS_ZERO; - - const float nd = -(norm.x*w.x + norm.y*w.y + norm.z*w.z) / d; - if(nd < 0.0 || nd >= 1.0) - throw pti_N_OVER_D_IS_OUTSIDE; - - const Vec3f i = start + u*nd; - //const Vec2i pos(i.x,i.z); - - Vec2i pos; - if(strcmp(label,"tl") == 0) { - pos = Vec2i(std::floor(i.x),std::floor(i.z)); - } - else if(strcmp(label,"tr") == 0) { - pos = Vec2i(std::ceil(i.x),std::floor(i.z)); - } - else if(strcmp(label,"bl") == 0) { - pos = Vec2i(std::floor(i.x),std::ceil(i.z)); - } - else if(strcmp(label,"br") == 0) { - pos = Vec2i(std::ceil(i.x),std::ceil(i.z)); - } - - if(false) { // print debug info - if(label) printf("%s ",label); - printf("%d,%d -> %f,%f,%f -> %f,%f,%f -> %f,%f,%f -> %d,%d\n", - pt.x,pt.y, - start.x,start.y,start.z, - stop.x,stop.y,stop.z, - i.x,i.y,i.z, - pos.x,pos.y); - } - return pos; - -} - -bool Renderer::ExtractFrustum(VisibleQuadContainerCache &quadCacheItem) { - bool frustumChanged = false; - vector proj(16,0); - vector modl(16,0); - - /* Get the current PROJECTION matrix from OpenGL */ - glGetFloatv( GL_PROJECTION_MATRIX, &proj[0] ); - - /* Get the current MODELVIEW matrix from OpenGL */ - glGetFloatv( GL_MODELVIEW_MATRIX, &modl[0] ); - -// for(unsigned int i = 0; i < proj.size(); ++i) { -// //printf("\ni = %d proj [%f][%f] modl [%f][%f]\n",i,proj[i],quadCacheItem.proj[i],modl[i],quadCacheItem.modl[i]); -// if(proj[i] != quadCacheItem.proj[i]) { -// frustumChanged = true; -// break; -// } -// if(modl[i] != quadCacheItem.modl[i]) { -// frustumChanged = true; -// break; -// } -// } - - // Check the frustum cache - const bool useFrustumCache = Config::getInstance().getBool("EnableFrustrumCache","false"); - pair,vector > lookupKey; - if(useFrustumCache == true) { - lookupKey = make_pair(proj,modl); - map,vector >, vector > >::iterator iterFind = quadCacheItem.frustumDataCache.find(lookupKey); - if(iterFind != quadCacheItem.frustumDataCache.end()) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum found in cache\n"); - - quadCacheItem.frustumData = iterFind->second; - frustumChanged = (quadCacheItem.proj != proj || quadCacheItem.modl != modl); - if(frustumChanged == true) { - quadCacheItem.proj = proj; - quadCacheItem.modl = modl; - } - - return frustumChanged; - } - } - - if(quadCacheItem.proj != proj || quadCacheItem.modl != modl) { - //if(frustumChanged == true) { - frustumChanged = true; - vector > &frustum = quadCacheItem.frustumData; - //assert(frustum.size() == 6); - //assert(frustum[0].size() == 4); - - quadCacheItem.proj = proj; - quadCacheItem.modl = modl; - - float clip[16]; - float t=0; - - /* Combine the two matrices (multiply projection by modelview) */ - clip[ 0] = modl[ 0] * proj[ 0] + modl[ 1] * proj[ 4] + modl[ 2] * proj[ 8] + modl[ 3] * proj[12]; - clip[ 1] = modl[ 0] * proj[ 1] + modl[ 1] * proj[ 5] + modl[ 2] * proj[ 9] + modl[ 3] * proj[13]; - clip[ 2] = modl[ 0] * proj[ 2] + modl[ 1] * proj[ 6] + modl[ 2] * proj[10] + modl[ 3] * proj[14]; - clip[ 3] = modl[ 0] * proj[ 3] + modl[ 1] * proj[ 7] + modl[ 2] * proj[11] + modl[ 3] * proj[15]; - - clip[ 4] = modl[ 4] * proj[ 0] + modl[ 5] * proj[ 4] + modl[ 6] * proj[ 8] + modl[ 7] * proj[12]; - clip[ 5] = modl[ 4] * proj[ 1] + modl[ 5] * proj[ 5] + modl[ 6] * proj[ 9] + modl[ 7] * proj[13]; - clip[ 6] = modl[ 4] * proj[ 2] + modl[ 5] * proj[ 6] + modl[ 6] * proj[10] + modl[ 7] * proj[14]; - clip[ 7] = modl[ 4] * proj[ 3] + modl[ 5] * proj[ 7] + modl[ 6] * proj[11] + modl[ 7] * proj[15]; - - clip[ 8] = modl[ 8] * proj[ 0] + modl[ 9] * proj[ 4] + modl[10] * proj[ 8] + modl[11] * proj[12]; - clip[ 9] = modl[ 8] * proj[ 1] + modl[ 9] * proj[ 5] + modl[10] * proj[ 9] + modl[11] * proj[13]; - clip[10] = modl[ 8] * proj[ 2] + modl[ 9] * proj[ 6] + modl[10] * proj[10] + modl[11] * proj[14]; - clip[11] = modl[ 8] * proj[ 3] + modl[ 9] * proj[ 7] + modl[10] * proj[11] + modl[11] * proj[15]; - - clip[12] = modl[12] * proj[ 0] + modl[13] * proj[ 4] + modl[14] * proj[ 8] + modl[15] * proj[12]; - clip[13] = modl[12] * proj[ 1] + modl[13] * proj[ 5] + modl[14] * proj[ 9] + modl[15] * proj[13]; - clip[14] = modl[12] * proj[ 2] + modl[13] * proj[ 6] + modl[14] * proj[10] + modl[15] * proj[14]; - clip[15] = modl[12] * proj[ 3] + modl[13] * proj[ 7] + modl[14] * proj[11] + modl[15] * proj[15]; - - /* Extract the numbers for the RIGHT plane */ - frustum[0][0] = clip[ 3] - clip[ 0]; - frustum[0][1] = clip[ 7] - clip[ 4]; - frustum[0][2] = clip[11] - clip[ 8]; - frustum[0][3] = clip[15] - clip[12]; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n",0,frustum[0][0],frustum[0][1],frustum[0][2],frustum[0][3]); - - /* Normalize the result */ - t = std::sqrt( frustum[0][0] * frustum[0][0] + frustum[0][1] * frustum[0][1] + frustum[0][2] * frustum[0][2] ); - if(t != 0.0) { - frustum[0][0] /= t; - frustum[0][1] /= t; - frustum[0][2] /= t; - frustum[0][3] /= t; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n",0,frustum[0][0],frustum[0][1],frustum[0][2],frustum[0][3],t); - } - - /* Extract the numbers for the LEFT plane */ - frustum[1][0] = clip[ 3] + clip[ 0]; - frustum[1][1] = clip[ 7] + clip[ 4]; - frustum[1][2] = clip[11] + clip[ 8]; - frustum[1][3] = clip[15] + clip[12]; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n",1,frustum[1][0],frustum[1][1],frustum[1][2],frustum[1][3]); - - /* Normalize the result */ - t = std::sqrt( frustum[1][0] * frustum[1][0] + frustum[1][1] * frustum[1][1] + frustum[1][2] * frustum[1][2] ); - if(t != 0.0) { - frustum[1][0] /= t; - frustum[1][1] /= t; - frustum[1][2] /= t; - frustum[1][3] /= t; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n",1,frustum[1][0],frustum[1][1],frustum[1][2],frustum[1][3],t); - } - - /* Extract the BOTTOM plane */ - frustum[2][0] = clip[ 3] + clip[ 1]; - frustum[2][1] = clip[ 7] + clip[ 5]; - frustum[2][2] = clip[11] + clip[ 9]; - frustum[2][3] = clip[15] + clip[13]; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n",2,frustum[2][0],frustum[2][1],frustum[2][2],frustum[2][3]); - - /* Normalize the result */ - - t = std::sqrt( frustum[2][0] * frustum[2][0] + frustum[2][1] * frustum[2][1] + frustum[2][2] * frustum[2][2] ); - if(t != 0.0) { - frustum[2][0] /= t; - frustum[2][1] /= t; - frustum[2][2] /= t; - frustum[2][3] /= t; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n",2,frustum[2][0],frustum[2][1],frustum[2][2],frustum[2][3],t); - } - - /* Extract the TOP plane */ - frustum[3][0] = clip[ 3] - clip[ 1]; - frustum[3][1] = clip[ 7] - clip[ 5]; - frustum[3][2] = clip[11] - clip[ 9]; - frustum[3][3] = clip[15] - clip[13]; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n",3,frustum[3][0],frustum[3][1],frustum[3][2],frustum[3][3]); - - /* Normalize the result */ - - t = std::sqrt( frustum[3][0] * frustum[3][0] + frustum[3][1] * frustum[3][1] + frustum[3][2] * frustum[3][2] ); - if(t != 0.0) { - frustum[3][0] /= t; - frustum[3][1] /= t; - frustum[3][2] /= t; - frustum[3][3] /= t; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n",3,frustum[3][0],frustum[3][1],frustum[3][2],frustum[3][3],t); - } - - /* Extract the FAR plane */ - frustum[4][0] = clip[ 3] - clip[ 2]; - frustum[4][1] = clip[ 7] - clip[ 6]; - frustum[4][2] = clip[11] - clip[10]; - frustum[4][3] = clip[15] - clip[14]; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n",4,frustum[4][0],frustum[4][1],frustum[4][2],frustum[4][3]); - - /* Normalize the result */ - - t = std::sqrt( frustum[4][0] * frustum[4][0] + frustum[4][1] * frustum[4][1] + frustum[4][2] * frustum[4][2] ); - - if(t != 0.0) { - frustum[4][0] /= t; - frustum[4][1] /= t; - frustum[4][2] /= t; - frustum[4][3] /= t; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n",4,frustum[4][0],frustum[4][1],frustum[4][2],frustum[4][3],t); - } - - /* Extract the NEAR plane */ - frustum[5][0] = clip[ 3] + clip[ 2]; - frustum[5][1] = clip[ 7] + clip[ 6]; - frustum[5][2] = clip[11] + clip[10]; - frustum[5][3] = clip[15] + clip[14]; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n",5,frustum[5][0],frustum[5][1],frustum[5][2],frustum[5][3]); - - /* Normalize the result */ - - t = std::sqrt( frustum[5][0] * frustum[5][0] + frustum[5][1] * frustum[5][1] + frustum[5][2] * frustum[5][2] ); - - if(t != 0.0) { - frustum[5][0] /= t; - frustum[5][1] /= t; - frustum[5][2] /= t; - frustum[5][3] /= t; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n",5,frustum[5][0],frustum[5][1],frustum[5][2],frustum[5][3],t); - } - - if(useFrustumCache == true) { - quadCacheItem.frustumDataCache[lookupKey] = frustum; - } - } - return frustumChanged; -} - -//bool Renderer::PointInFrustum(vector > &frustum, float x, float y, float z ) { -// unsigned int p=0; -// -// for( p = 0; p < frustum.size(); p++ ) { -// if( frustum[p][0] * x + frustum[p][1] * y + frustum[p][2] * z + frustum[p][3] <= 0 ) { -// return false; -// } -// } -// return true; -//} -// -//bool Renderer::SphereInFrustum(vector > &frustum, float x, float y, float z, float radius) { -// // Go through all the sides of the frustum -// for(int i = 0; i < (int)frustum.size(); i++ ) { -// // If the center of the sphere is farther away from the plane than the radius -// if(frustum[i][0] * x + frustum[i][1] * y + frustum[i][2] * z + frustum[i][3] <= -radius ) { -// // The distance was greater than the radius so the sphere is outside of the frustum -// return false; -// } -// } -// -// // The sphere was inside of the frustum! -// return true; -//} - -bool Renderer::CubeInFrustum(vector > &frustum, float x, float y, float z, float size ) { - unsigned int p=0; - - for( p = 0; p < frustum.size(); p++ ) { - if( frustum[p][0] * (x - size) + frustum[p][1] * (y - size) + frustum[p][2] * (z - size) + frustum[p][3] > 0 ) - continue; - if( frustum[p][0] * (x + size) + frustum[p][1] * (y - size) + frustum[p][2] * (z - size) + frustum[p][3] > 0 ) - continue; - if( frustum[p][0] * (x - size) + frustum[p][1] * (y + size) + frustum[p][2] * (z - size) + frustum[p][3] > 0 ) - continue; - if( frustum[p][0] * (x + size) + frustum[p][1] * (y + size) + frustum[p][2] * (z - size) + frustum[p][3] > 0 ) - continue; - if( frustum[p][0] * (x - size) + frustum[p][1] * (y - size) + frustum[p][2] * (z + size) + frustum[p][3] > 0 ) - continue; - if( frustum[p][0] * (x + size) + frustum[p][1] * (y - size) + frustum[p][2] * (z + size) + frustum[p][3] > 0 ) - continue; - if( frustum[p][0] * (x - size) + frustum[p][1] * (y + size) + frustum[p][2] * (z + size) + frustum[p][3] > 0 ) - continue; - if( frustum[p][0] * (x + size) + frustum[p][1] * (y + size) + frustum[p][2] * (z + size) + frustum[p][3] > 0 ) - continue; - return false; - } - return true; -} - -void Renderer::computeVisibleQuad() { - visibleQuad = this->gameCamera->computeVisibleQuad(); - - bool frustumChanged = false; - if(VisibleQuadContainerCache::enableFrustumCalcs == true) { - frustumChanged = ExtractFrustum(quadCache); - } - - if(frustumChanged && SystemFlags::VERBOSE_MODE_ENABLED) { - printf("\nCamera: %d,%d %d,%d %d,%d %d,%d\n", - visibleQuad.p[0].x,visibleQuad.p[0].y, - visibleQuad.p[1].x,visibleQuad.p[1].y, - visibleQuad.p[2].x,visibleQuad.p[2].y, - visibleQuad.p[3].x,visibleQuad.p[3].y); - - for(unsigned int i = 0; i < quadCache.frustumData.size(); ++i) { - printf("\nFrustum #%u [" MG_SIZE_T_SPECIFIER "]: ",i,quadCache.frustumData.size()); - vector &frustumDataInner = quadCache.frustumData[i]; - for(unsigned int j = 0; j < frustumDataInner.size(); ++j) { - printf("[%f]",quadCache.frustumData[i][j]); - } - } - - printf("\nEND\n"); - } - - const bool newVisibleQuadCalc = false; - if(newVisibleQuadCalc) { - const bool debug = false; - try { - if(debug) { - visibleQuad = gameCamera->computeVisibleQuad(); - printf("Camera: %d,%d %d,%d %d,%d %d,%d\n", - visibleQuad.p[0].x,visibleQuad.p[0].y, - visibleQuad.p[1].x,visibleQuad.p[1].y, - visibleQuad.p[2].x,visibleQuad.p[2].y, - visibleQuad.p[3].x,visibleQuad.p[3].y); - } - - - // compute the four corners using OpenGL - GLdouble model[16], projection[16]; - GLint viewport[4]; - glGetDoublev(GL_MODELVIEW_MATRIX,model); - glGetDoublev(GL_PROJECTION_MATRIX,projection); - glGetIntegerv(GL_VIEWPORT,viewport); - Vec2i - tl = _unprojectMap(Vec2i(0,0),model,projection,viewport,"tl"), - tr = _unprojectMap(Vec2i(viewport[2],0),model,projection,viewport,"tr"), - br = _unprojectMap(Vec2i(viewport[2],viewport[3]),model,projection,viewport,"br"), - bl = _unprojectMap(Vec2i(0,viewport[3]),model,projection,viewport,"bl"); - - - // orientate it for map iterator - //bool swapRequiredX = false; - bool swapRequiredY = false; - int const cellBuffer = 4; - if((tl.x > tr.x) || (bl.x > br.x)) { - if(debug) printf("Swap X???\n"); - - //std::swap(tl,bl); - //std::swap(tr,br); - if(tl.x > tr.x) { - if(debug) printf("Swap X1???\n"); - - tr.x += cellBuffer; - tl.x -= cellBuffer; - - std::swap(tl.x,tr.x); - //swapRequiredX = true; - } - else { - tl.x += cellBuffer; - tr.x -= cellBuffer; - } - if(bl.x > br.x) { - if(debug) printf("Swap X2???\n"); - - bl.x += cellBuffer; - br.x -= cellBuffer; - - std::swap(bl.x,br.x); - //swapRequiredX = true; - } - else { - br.x += cellBuffer; - bl.x -= cellBuffer; - } - } - - if((tl.y > bl.y) || (tr.y > br.y)) { - visibleQuad = this->gameCamera->computeVisibleQuad(); - - if(debug) printf("Swap Y???\n"); - - if(tl.y > bl.y) { - if(debug) printf("Swap Y1???\n"); - - tl.y += cellBuffer; - bl.y -= cellBuffer; - - std::swap(tl.y,bl.y); - swapRequiredY = true; - } - else { - bl.y += cellBuffer; - tl.y -= cellBuffer; - } - if(tr.y > br.y) { - if(debug) printf("Swap Y2???\n"); - - tr.y += cellBuffer; - br.y -= cellBuffer; - - std::swap(tr.y,br.y); - swapRequiredY = true; - } - else { - br.y += cellBuffer; - tr.y -= cellBuffer; - } - - - //std::swap(tl,tr); - //std::swap(bl,br); - } - if(swapRequiredY == false) { - tl.y -= cellBuffer; - tr.y -= cellBuffer; - bl.y += cellBuffer; - br.y += cellBuffer; - } - - // set it as the frustum - visibleQuad = Quad2i(tl,bl,tr,br); // strange order - if(debug) { - printf("Will: %d,%d %d,%d %d,%d %d,%d\n", - visibleQuad.p[0].x,visibleQuad.p[0].y, - visibleQuad.p[1].x,visibleQuad.p[1].y, - visibleQuad.p[2].x,visibleQuad.p[2].y, - visibleQuad.p[3].x,visibleQuad.p[3].y); - } - } - catch(PROJECTION_TO_INFINITY &e) { - if(debug) printf("hmm staring at the horizon %d\n",(int)e); - // use historic code solution - visibleQuad = this->gameCamera->computeVisibleQuad(); - } - } -} - -// ======================================= -// basic rendering -// ======================================= - -void Renderer::renderMouse2d(int x, int y, int anim, float fade) { - if(no2DMouseRendering == true) { - return; - } - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } -// float blue=0.0f; -// float green=0.4f; - if(game != NULL && game->getGui() != NULL) { - const Gui *gui=game->getGui(); - const Display *display=gui->getDisplay(); - int downPos= display->getDownSelectedPos(); - if(downPos != Display::invalidPos){ - // in state of doing something - const Texture2D *texture= display->getDownImage(downPos); - renderTextureQuad(x+18,y-50,32,32,texture,0.8f); - } -// else { -// // Display current commandtype -// const Unit *unit=NULL; -// if(gui->getSelection()->isEmpty()){ -// blue=0.0f; -// green=0.1f; -// } -// else{ -// unit=gui->getSelection()->getFrontUnit(); -// if(unit->getCurrCommand()!=NULL && unit->getCurrCommand()->getCommandType()->getImage()!=NULL){ -// const Texture2D *texture = unit->getCurrCommand()->getCommandType()->getImage(); -// renderTextureQuad(x+18,y-50,32,32,texture,0.2f); -// } -// } -// } - - if(game->isMarkCellMode() == true) { - const Texture2D *texture= game->getMarkCellTexture(); - renderTextureQuad(x,y,texture->getTextureWidth(),texture->getTextureHeight(),texture,0.8f); - } - if(game->isUnMarkCellMode() == true) { - const Texture2D *texture= game->getUnMarkCellTexture(); - renderTextureQuad(x,y,texture->getTextureWidth(),texture->getTextureHeight(),texture,0.8f); - } - } - - float fadeFactor = fade + 1.f; - - anim= anim * 2 - maxMouse2dAnim; - - float color2= (abs(anim*(int)fadeFactor)/static_cast(maxMouse2dAnim))/2.f+0.4f; - float color1= (abs(anim*(int)fadeFactor)/static_cast(maxMouse2dAnim))/2.f+0.8f; - - glPushAttrib(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_LINE_BIT); - glEnable(GL_BLEND); - - //inside - glColor4f(0.4f*fadeFactor, 0.2f*fadeFactor, 0.2f*fadeFactor, 0.5f*fadeFactor); - glBegin(GL_TRIANGLES); - glVertex2i(x, y); - glVertex2i(x+20, y-10); - glVertex2i(x+10, y-20); - glEnd(); - - //border - glLineWidth(2); - glBegin(GL_LINE_LOOP); - glColor4f(1.f, 0.2f, 0, color1); - glVertex2i(x, y); - glColor4f(1.f, 0.4f, 0, color2); - glVertex2i(x+20, y-10); - glColor4f(1.f, 0.4f, 0, color2); - glVertex2i(x+10, y-20); - glEnd(); - glPopAttrib(); - - -/* - if(no2DMouseRendering == true) { - return; - } - float color1 = 0.0, color2 = 0.0; - - float fadeFactor = fade + 1.f; - - anim= anim * 2 - maxMouse2dAnim; - - color2= (abs(anim*(int)fadeFactor)/static_cast(maxMouse2dAnim))/2.f+0.4f; - color1= (abs(anim*(int)fadeFactor)/static_cast(maxMouse2dAnim))/2.f+0.8f; - - glPushAttrib(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_LINE_BIT); - glEnable(GL_BLEND); - - //inside - Vec2i vertices[3]; - vertices[0] = Vec2i(x, y); - vertices[1] = Vec2i(x+20, y-10); - vertices[2] = Vec2i(x+10, y-20); - - glColor4f(0.4f*fadeFactor, 0.2f*fadeFactor, 0.2f*fadeFactor, 0.5f*fadeFactor); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_INT, 0, &vertices[0]); - glDrawArrays(GL_TRIANGLES, 0, 3); - glDisableClientState(GL_VERTEX_ARRAY); - - //border - vertices[0] = Vec2i(x, y); - vertices[1] = Vec2i(x+20, y-10); - vertices[2] = Vec2i(x+10, y-20); - - Vec4f colors[4]; - colors[0] = Vec4f(1.f, 0.2f, 0, color1); - colors[1] = Vec4f(1.f, 0.4f, 0, color2); - colors[2] = Vec4f(1.f, 0.4f, 0, color2); - - glLineWidth(2); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_INT, 0, &vertices[0]); - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, 0, &colors[0]); - glDrawArrays(GL_LINE_LOOP, 0, 3); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - - glPopAttrib(); -*/ -} - -void Renderer::renderMouse3d() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - Config &config= Config::getInstance(); - if(config.getBool("RecordMode","false") == true) { - return; - } - - if(game == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s] Line: %d game == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - else if(game->getGui() == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s] Line: %d game->getGui() == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - else if(game->getGui()->getMouse3d() == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s] Line: %d game->getGui()->getMouse3d() == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - - const Gui *gui= game->getGui(); - const Mouse3d *mouse3d= gui->getMouse3d(); - const Map *map= game->getWorld()->getMap(); - if(map == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s] Line: %d map == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - - assertGl(); - - if((mouse3d->isEnabled() || gui->isPlacingBuilding()) && gui->isValidPosObjWorld()) { - const Vec2i &pos= gui->getPosObjWorld(); - - glMatrixMode(GL_MODELVIEW); - - glPushAttrib(GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_BLEND); - glDisable(GL_STENCIL_TEST); - glDepthFunc(GL_LESS); - glEnable(GL_COLOR_MATERIAL); - glDepthMask(GL_FALSE); - - if(gui->isPlacingBuilding()) { - - modelRenderer->begin(true, true, false, false); - - const UnitType *building= gui->getBuilding(); - const Gui *gui= game->getGui(); - renderGhostModel(building, pos, gui->getSelectedFacing()); - - modelRenderer->end(); - - glDisable(GL_COLOR_MATERIAL); - glPopAttrib(); - } - else { - glPushMatrix(); - Vec3f pos3f= Vec3f(pos.x, map->getCell(pos)->getHeight(), pos.y); - Vec4f color; - GLUquadricObj *cilQuadric; - //standard mouse - glDisable(GL_TEXTURE_2D); - glDisable(GL_CULL_FACE); - color= Vec4f(1.f, 0.f, 0.f, 1.f-mouse3d->getFade()); - glColor4fv(color.ptr()); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color.ptr()); - - glTranslatef(pos3f.x, pos3f.y+2.f, pos3f.z); - glRotatef(90.f, 1.f, 0.f, 0.f); - glRotatef(static_cast(mouse3d->getRot()), 0.f, 0.f, 1.f); - - cilQuadric= gluNewQuadric(); - gluQuadricDrawStyle(cilQuadric, GLU_FILL); - gluCylinder(cilQuadric, 0.5f, 0.f, 2.f, 4, 1); - gluCylinder(cilQuadric, 0.5f, 0.f, 0.f, 4, 1); - glTranslatef(0.f, 0.f, 1.f); - gluCylinder(cilQuadric, 0.7f, 0.f, 1.f, 4, 1); - gluCylinder(cilQuadric, 0.7f, 0.f, 0.f, 4, 1); - gluDeleteQuadric(cilQuadric); - - glPopAttrib(); - glPopMatrix(); - } - } - -} - -void Renderer::renderBackground(const Texture2D *texture) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - const Metrics &metrics= Metrics::getInstance(); - - assertGl(); - - glPushAttrib(GL_ENABLE_BIT); - - glDisable(GL_LIGHTING); - glEnable(GL_TEXTURE_2D); - - renderQuad(0, 0, metrics.getVirtualW(), metrics.getVirtualH(), texture); - - glPopAttrib(); - - assertGl(); -} - -void Renderer::renderTextureQuad(int x, int y, int w, int h, const Texture2D *texture, float alpha,const Vec3f *color) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - assertGl(); - - glPushAttrib(GL_ENABLE_BIT); - - glDisable(GL_LIGHTING); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - - if(color != NULL) { - Vec4f newColor(*color); - newColor.w = alpha; - glColor4fv(newColor.ptr()); - } - else { - glColor4f(1.f, 1.f, 1.f, alpha); - } - renderQuad(x, y, w, h, texture); - - glPopAttrib(); - - assertGl(); -} - -void Renderer::renderConsoleLine3D(int lineIndex, int xPosition, int yPosition, int lineHeight, - Font3D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - Vec4f fontColor; - Lang &lang= Lang::getInstance(); - //const Metrics &metrics= Metrics::getInstance(); - FontMetrics *fontMetrics= font->getMetrics(); - - if(game != NULL) { - fontColor = game->getGui()->getDisplay()->getColor(); - } - else { - // white shadowed is default ( in the menu for example ) - //fontColor=Vec4f(1.f, 1.f, 1.f, 0.0f); - fontColor=Vec4f(lineInfo->color.x,lineInfo->color.y,lineInfo->color.z, 0.0f); - } - - Vec4f defaultFontColor = fontColor; - - if(lineInfo->PlayerIndex >= 0) { - std::map &crcPlayerTextureCache = CacheManager::getCachedItem< std::map >(GameConstants::playerTextureCacheLookupKey); - Vec3f playerColor = crcPlayerTextureCache[lineInfo->PlayerIndex]->getPixmap()->getPixel3f(0, 0); - fontColor.x = playerColor.x; - fontColor.y = playerColor.y; - fontColor.z = playerColor.z; - - GameNetworkInterface *gameNetInterface = NetworkManager::getInstance().getGameNetworkInterface(); - if(gameNetInterface != NULL && gameNetInterface->getGameSettings() != NULL) { - const GameSettings *gameSettings = gameNetInterface->getGameSettings(); - string playerName = gameSettings->getNetworkPlayerNameByPlayerIndex(lineInfo->PlayerIndex); - if(playerName != lineInfo->originalPlayerName && lineInfo->originalPlayerName != "") { - playerName = lineInfo->originalPlayerName; - } - if(playerName == GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) { - playerName = lang.getString("SystemUser"); - } - //printf("playerName [%s], line [%s]\n",playerName.c_str(),line.c_str()); - - //string headerLine = "*" + playerName + ":"; - //string headerLine = playerName + ": "; - string headerLine = playerName; - if(lineInfo->teamMode == true) { - headerLine += " (" + lang.getString("Team") + ")"; - } - headerLine += ": "; - - if(fontMetrics == NULL) { - throw megaglest_runtime_error("fontMetrics == NULL"); - } - - renderTextShadow3D( - headerLine, - font, - fontColor, - xPosition, lineIndex * lineHeight + yPosition); - - fontColor = defaultFontColor; - //xPosition += (8 * (playerName.length() + 2)); - // Proper font spacing after username portion of chat text rendering - - //xPosition += (metrics.toVirtualX(fontMetrics->getTextWidth(headerLine))); - xPosition += fontMetrics->getTextWidth(headerLine); - } - } - else if(lineInfo->originalPlayerName != "") { - string playerName = lineInfo->originalPlayerName; - //string headerLine = playerName + ": "; - string headerLine = playerName; - if(lineInfo->teamMode == true) { - headerLine += " (" + lang.getString("Team") + ")"; - } - headerLine += ": "; - - if(fontMetrics == NULL) { - throw megaglest_runtime_error("fontMetrics == NULL"); - } - - renderTextShadow3D( - headerLine, - font, - fontColor, - xPosition, lineIndex * lineHeight + yPosition); - - fontColor = defaultFontColor; - //xPosition += (8 * (playerName.length() + 2)); - // Proper font spacing after username portion of chat text rendering - //xPosition += (metrics.toVirtualX(fontMetrics->getTextWidth(headerLine))); - xPosition += fontMetrics->getTextWidth(headerLine); - } - else { - fontColor = defaultFontColor; - } - - if(stringToHightlight!="" && lineInfo->text.find(stringToHightlight)!=string::npos){ - fontColor=Vec4f(1.f, 0.5f, 0.5f, 0.0f); - } - renderTextShadow3D( - lineInfo->text, - font, - fontColor, - xPosition, (lineIndex * lineHeight) + yPosition); -} - -void Renderer::renderConsoleLine(int lineIndex, int xPosition, int yPosition, int lineHeight, - Font2D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - Vec4f fontColor; - Lang &lang= Lang::getInstance(); - - const Metrics &metrics= Metrics::getInstance(); - FontMetrics *fontMetrics= font->getMetrics(); - - if(game != NULL) { - fontColor = game->getGui()->getDisplay()->getColor(); - } - else { - // white shadowed is default ( in the menu for example ) - //fontColor=Vec4f(1.f, 1.f, 1.f, 0.0f); - fontColor=Vec4f(lineInfo->color.x,lineInfo->color.y,lineInfo->color.z, 0.0f); - } - - Vec4f defaultFontColor = fontColor; - - if(lineInfo->PlayerIndex >= 0) { - std::map &crcPlayerTextureCache = CacheManager::getCachedItem< std::map >(GameConstants::playerTextureCacheLookupKey); - Vec3f playerColor = crcPlayerTextureCache[lineInfo->PlayerIndex]->getPixmap()->getPixel3f(0, 0); - fontColor.x = playerColor.x; - fontColor.y = playerColor.y; - fontColor.z = playerColor.z; - - GameNetworkInterface *gameNetInterface = NetworkManager::getInstance().getGameNetworkInterface(); - if(gameNetInterface != NULL && gameNetInterface->getGameSettings() != NULL) { - const GameSettings *gameSettings = gameNetInterface->getGameSettings(); - string playerName = gameSettings->getNetworkPlayerNameByPlayerIndex(lineInfo->PlayerIndex); - if(playerName != lineInfo->originalPlayerName && lineInfo->originalPlayerName != "") { - playerName = lineInfo->originalPlayerName; - } - //printf("playerName [%s], line [%s]\n",playerName.c_str(),line.c_str()); - - //string headerLine = "*" + playerName + ":"; - //string headerLine = playerName + ": "; - string headerLine = playerName; - if(lineInfo->teamMode == true) { - headerLine += " (" + lang.getString("Team") + ")"; - } - headerLine += ": "; - - if(fontMetrics == NULL) { - throw megaglest_runtime_error("fontMetrics == NULL"); - } - - renderTextShadow( - headerLine, - font, - fontColor, - xPosition, lineIndex * lineHeight + yPosition); - - fontColor = defaultFontColor; - //xPosition += (8 * (playerName.length() + 2)); - // Proper font spacing after username portion of chat text rendering - xPosition += (metrics.toVirtualX(fontMetrics->getTextWidth(headerLine))); - } - } - else if(lineInfo->originalPlayerName != "") { - string playerName = lineInfo->originalPlayerName; - //string headerLine = playerName + ": "; - string headerLine = playerName; - if(lineInfo->teamMode == true) { - headerLine += " (" + lang.getString("Team") + ")"; - } - headerLine += ": "; - - if(fontMetrics == NULL) { - throw megaglest_runtime_error("fontMetrics == NULL"); - } - - renderTextShadow( - headerLine, - font, - fontColor, - xPosition, lineIndex * lineHeight + yPosition); - - fontColor = defaultFontColor; - //xPosition += (8 * (playerName.length() + 2)); - // Proper font spacing after username portion of chat text rendering - xPosition += (metrics.toVirtualX(fontMetrics->getTextWidth(headerLine))); - } - else { - fontColor = defaultFontColor; - } - - if(stringToHightlight!="" && lineInfo->text.find(stringToHightlight)!=string::npos){ - fontColor=Vec4f(1.f, 0.5f, 0.5f, 0.0f); - } - renderTextShadow( - lineInfo->text, - font, - fontColor, - xPosition, (lineIndex * lineHeight) + yPosition); -} - -void Renderer::renderConsole(const Console *console, ConsoleMode mode , int overrideMaxConsoleLines){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(console == NULL) { - throw megaglest_runtime_error("console == NULL"); - } - - glPushAttrib(GL_ENABLE_BIT); - glEnable(GL_BLEND); - - if(mode==consoleFull) { - int x= console->getXPos()-5; - int y= console->getYPos()-5; - int h= console->getLineHeight()*console->getStoredLineCount(); - - if(h > 0) { - int w= 1000; - //background - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); - glEnable(GL_BLEND); - - glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ; - - glBegin(GL_TRIANGLE_STRIP); - glVertex2i(x, y); - glVertex2i(x, y+h); - glVertex2i(x+w, y); - glVertex2i(x+w, y+h); - glEnd(); - glPopAttrib(); - } - for(int i = 0; i < console->getStoredLineCount(); ++i) { - const ConsoleLineInfo &lineInfo = console->getStoredLineItem(i); - if(renderText3DEnabled == true) { - renderConsoleLine3D(i, console->getXPos(), console->getYPos(), - console->getLineHeight(), console->getFont3D(), - console->getStringToHighlight(), &lineInfo); - } - else { - renderConsoleLine(i, console->getXPos(), console->getYPos(), - console->getLineHeight(), console->getFont(), - console->getStringToHighlight(), &lineInfo); - } - } - } - else if(mode==consoleStoredOnly) { - int allowedMaxLines = (overrideMaxConsoleLines >= 0 ? overrideMaxConsoleLines : maxConsoleLines); - for(int i = 0; i < console->getStoredLineCount() && i < allowedMaxLines; ++i) { - const ConsoleLineInfo &lineInfo = console->getStoredLineItem(i); - if(renderText3DEnabled == true) { - renderConsoleLine3D(i, console->getXPos(), console->getYPos(), - console->getLineHeight(), console->getFont3D(), console->getStringToHighlight(), &lineInfo); - } - else { - renderConsoleLine(i, console->getXPos(), console->getYPos(), - console->getLineHeight(), console->getFont(), console->getStringToHighlight(), &lineInfo); - } - } - } - else if(mode==consoleStoredAndNormal) { - int allowedMaxLines = (overrideMaxConsoleLines >= 0 ? overrideMaxConsoleLines : maxConsoleLines); - float starttimestamp=-1; - int consoleIndex=0; - for(int i = 0; i < console->getLineCount() && i < allowedMaxLines; ++i) { - const ConsoleLineInfo &lineInfo = console->getLineItem(i); - if(starttimestamp>lineInfo.timeStamp || starttimestamp==-1) starttimestamp=lineInfo.timeStamp; - if(renderText3DEnabled == true) { - renderConsoleLine3D(i, console->getXPos(), console->getYPos(), - console->getLineHeight(), console->getFont3D(), console->getStringToHighlight(), &lineInfo); - } - else { - renderConsoleLine(i, console->getXPos(), console->getYPos(), - console->getLineHeight(), console->getFont(), console->getStringToHighlight(), &lineInfo); - } - consoleIndex++; - } - for(int i = 0; i < console->getStoredLineCount() && consoleIndex < allowedMaxLines; ++i) { - const ConsoleLineInfo &lineInfo = console->getStoredLineItem(i); - if( lineInfo.timeStampgetXPos(), console->getYPos(), - console->getLineHeight(), console->getFont3D(), console->getStringToHighlight(), &lineInfo); - } - else { - renderConsoleLine(consoleIndex, console->getXPos(), console->getYPos(), - console->getLineHeight(), console->getFont(), console->getStringToHighlight(), &lineInfo); - } - consoleIndex++; - } - } - } - else if(mode==consoleNormal) { - for(int i = 0; i < console->getLineCount(); ++i) { - const ConsoleLineInfo &lineInfo = console->getLineItem(i); - if(renderText3DEnabled == true) { - renderConsoleLine3D(i, console->getXPos(), console->getYPos(), - console->getLineHeight(), console->getFont3D(), console->getStringToHighlight(), &lineInfo); - } - else { - renderConsoleLine(i, console->getXPos(), console->getYPos(), - console->getLineHeight(), console->getFont(), console->getStringToHighlight(), &lineInfo); - } - } - } - glPopAttrib(); -} - -void Renderer::renderChatManager(const ChatManager *chatManager) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - Vec4f fontColor; - Lang &lang= Lang::getInstance(); - - if(chatManager->getEditEnabled()) { - Vec4f color=Vec4f(0.0f,0.0f,0.0f,0.6f); - string text=""; - - if(chatManager->isInCustomInputMode() == true) { - text += lang.getString("CellHint"); - } - else if(chatManager->getInMenu()) { - text += lang.getString("Chat"); - } - else if(chatManager->getTeamMode()) { - text += lang.getString("Team"); - } - else { - text += lang.getString("All"); - } - text += ": " + chatManager->getText() + "_"; - - if(game != NULL) { - fontColor = game->getGui()->getDisplay()->getColor(); - } - else { - // white shadowed is default ( in the menu for example ) - fontColor=Vec4f(1.f, 1.f, 1.f, 0.0f); - } - - // render Background - int x=chatManager->getXPos(); - int y=chatManager->getYPos()-6; - int h=22; - int w=830; - - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); - glEnable(GL_BLEND); - - glColor4f(color.x, color.y, color.z, color.w) ; - - glBegin(GL_TRIANGLE_STRIP); - glVertex2i(x, y); - glVertex2i(x, y+h); - glVertex2i(x+w, y); - glVertex2i(x+w, y+h); - glEnd(); - glPopAttrib(); - - if(renderText3DEnabled == true) { - renderTextShadow3D( - text, - chatManager->getFont3D(), - fontColor, - chatManager->getXPos(), chatManager->getYPos()); - } - else { - renderTextShadow( - text, - chatManager->getFont(), - fontColor, - chatManager->getXPos(), chatManager->getYPos()); - } - } - else - { - if (chatManager->getInMenu()) { - string text = "\t\t\t\t\t>> "+lang.getString("PressEnterToChat")+" <<"; - fontColor = Vec4f(0.5f, 0.5f, 0.5f, 0.5f); - - if(renderText3DEnabled == true) { - renderTextShadow3D(text, chatManager->getFont3D(), fontColor, - chatManager->getXPos(), chatManager->getYPos()); - } - else { - renderTextShadow(text, chatManager->getFont(), fontColor, - chatManager->getXPos(), chatManager->getYPos()); - } - } - } -} - - -void Renderer::renderPerformanceStats() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - const Metrics &metrics = Metrics::getInstance(); - const Vec4f fontColor = game->getGui()->getDisplay()->getColor(); - - char szBuf[200]=""; - snprintf(szBuf,200,"Frame: %d",game->getWorld()->getFrameCount() / 20); - string str = string(szBuf) + string("\n"); - - static time_t lastGamePerfCheck = time(NULL); - static string gamePerfStats = ""; - if(difftime((long int)time(NULL),lastGamePerfCheck) > 3) { - lastGamePerfCheck = time(NULL); - gamePerfStats = game->getGamePerformanceCounts(true); - } - - if(gamePerfStats != "") { - str += gamePerfStats + "\n"; - } - - if(renderText3DEnabled == true) { - renderTextShadow3D( - str, CoreData::getInstance().getDisplayFontSmall3D(), - fontColor, - 10, metrics.getVirtualH()-180, false); - } - else { - renderTextShadow( - str, CoreData::getInstance().getDisplayFontSmall(), - fontColor, - 10, metrics.getVirtualH()-180, false); - } -} - -void Renderer::renderClock() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - Config &config= Config::getInstance(); - if(config.getBool("InGameClock","true") == false && - config.getBool("InGameLocalClock","true") == false && - config.getBool("InGameFrameCounter","false") == false) { - return; - } - - string str = ""; - const Metrics &metrics = Metrics::getInstance(); - const World *world = game->getWorld(); - const Vec4f fontColor = game->getGui()->getDisplay()->getColor(); - - if(config.getBool("InGameClock","true") == true) { - Lang &lang= Lang::getInstance(); - char szBuf[501]=""; - - //int hours = world->getTimeFlow()->getTime(); - //int minutes = (world->getTimeFlow()->getTime() - hours) * 100 * 0.6; // scale 100 to 60 - //snprintf(szBuf,200,"%s %.2d:%.2d",lang.getString("GameTime","",true).c_str(),hours,minutes); - // string header2 = lang.getString("GameDurationTime","",true) + ": " + getTimeString(stats.getFramesToCalculatePlaytime()); - snprintf(szBuf,500,"%s %s",lang.getString("GameDurationTime","",true).c_str(),getTimeDuationString(world->getFrameCount(),GameConstants::updateFps).c_str()); - if(str != "") { - str += " "; - } - str += szBuf; - } - - if(config.getBool("InGameLocalClock","true") == true) { - //time_t nowTime = time(NULL); - //struct tm *loctime = localtime(&nowTime); - struct tm loctime = threadsafe_localtime(systemtime_now()); - char szBuf2[100]=""; - strftime(szBuf2,100,"%H:%M",&loctime); - - Lang &lang= Lang::getInstance(); - char szBuf[200]=""; - snprintf(szBuf,200,"%s %s",lang.getString("LocalTime","",true).c_str(),szBuf2); - if(str != "") { - str += " "; - } - str += szBuf; - } - - if(config.getBool("InGameFrameCounter","false") == true) { - char szBuf[200]=""; - snprintf(szBuf,200,"Frame: %d",game->getWorld()->getFrameCount() / 20); - if(str != "") { - str += " "; - } - str += szBuf; - } - - //string str = szBuf; - - if(renderText3DEnabled == true) { - renderTextShadow3D( - str, CoreData::getInstance().getDisplayFontSmall3D(), - fontColor, - 10, metrics.getVirtualH()-160, false); - } - else { - renderTextShadow( - str, CoreData::getInstance().getDisplayFontSmall(), - fontColor, - 10, metrics.getVirtualH()-160, false); - } -} - -void Renderer::renderResourceStatus() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - const World *world = game->getWorld(); - Config &config= Config::getInstance(); - - if(world->getThisFactionIndex() < 0 || - world->getThisFactionIndex() >= world->getFactionCount()) { - return; - } - - const Faction *thisFaction = world->getFaction(world->getThisFactionIndex()); - - assertGl(); - glPushAttrib(GL_ENABLE_BIT); - - int rowsRendered = 0; - int resourceCountRendered = 0; - bool twoRessourceLines=false; - - bool sharedTeamUnits = game != NULL && game->getGui() != NULL - && game->isFlagType1BitEnabled(ft1_allow_shared_team_units) - == true; - bool sharedTeamResources = game != NULL && game->getGui() != NULL - && game->isFlagType1BitEnabled( - ft1_allow_shared_team_resources) == true; - - bool renderSharedTeamResources=false; - bool renderSharedTeamUnits=false; - bool renderLocalFactionResources=false; - - if(config.getBool("TwoLineTeamResourceRendering","false") == true) { - if( sharedTeamResources == true || sharedTeamUnits == true){ - twoRessourceLines=true; - } - if(sharedTeamResources == true){ - renderSharedTeamResources=true; - renderSharedTeamUnits=true; - } - else if(sharedTeamUnits == true){ - renderSharedTeamUnits=true; - renderLocalFactionResources=true; - } - else{ - renderLocalFactionResources=true; - } - } - else { - if(sharedTeamResources == true) - renderSharedTeamResources=true; - else if(sharedTeamUnits == true) - renderSharedTeamUnits=true; - else - renderLocalFactionResources=true; - } - - if(renderSharedTeamResources == true) { - resourceCountRendered = 0; - for(int techTreeResourceTypeIndex = 0; - techTreeResourceTypeIndex < world->getTechTree()->getResourceTypeCount(); - ++techTreeResourceTypeIndex) { - - const ResourceType *rt = world->getTechTree()->getResourceType(techTreeResourceTypeIndex); - - if ( rt->getDisplayInHud() == false ) { - continue; - } - - bool showResource = world->showResourceTypeForTeam(rt, thisFaction->getTeam()); - if(showResource == true) { - rowsRendered = renderResource(thisFaction, - false, twoRessourceLines, rt, 0, - resourceCountRendered); - } - } - if(resourceCountRendered > 0) { - rowsRendered++; - } - } - - if(renderLocalFactionResources == true){ - resourceCountRendered = 0; - - const Faction *factionForResourceView = thisFaction; - bool localFactionResourcesOnly = true; - - for(int techTreeResourceTypeIndex = 0; - techTreeResourceTypeIndex < world->getTechTree()->getResourceTypeCount(); - ++techTreeResourceTypeIndex) { - const ResourceType *rt = world->getTechTree()->getResourceType(techTreeResourceTypeIndex); - if ( rt->getDisplayInHud() == false ) { - continue; - } - - //if any unit produces the resource - bool showResource; - if (twoRessourceLines) - showResource = world->showResourceTypeForTeam(rt, - factionForResourceView->getTeam()); - else - showResource = world->showResourceTypeForFaction(rt, - factionForResourceView); - if(showResource == true) { - renderResource(factionForResourceView, localFactionResourcesOnly, - twoRessourceLines, rt, rowsRendered, resourceCountRendered); - } - } - if(resourceCountRendered > 0) { - rowsRendered++; - } - } - - if(renderSharedTeamUnits == true){ - resourceCountRendered = 0; - - const Faction *factionForResourceView = thisFaction; - bool localFactionResourcesOnly = true; - - const Gui *gui = game->getGui(); - if(gui != NULL) { - const Selection *selection = gui->getSelection(); - if(selection != NULL && selection->getCount() > 0 && selection->getFrontUnit() != NULL) { - const Unit *selectedUnit = selection->getFrontUnit(); - if(selectedUnit != NULL && selectedUnit->getFaction()->isAlly(thisFaction) == true) { - factionForResourceView = selectedUnit->getFaction(); - } - } - } - - for(int techTreeResourceTypeIndex = 0; - techTreeResourceTypeIndex < world->getTechTree()->getResourceTypeCount(); - ++techTreeResourceTypeIndex) { - const ResourceType *rt = world->getTechTree()->getResourceType(techTreeResourceTypeIndex); - if ( rt->getDisplayInHud() == false ) { - continue; - } - - //if any unit produces the resource - bool showResource; - if (twoRessourceLines) - showResource = world->showResourceTypeForTeam(rt, - factionForResourceView->getTeam()); - else - showResource = world->showResourceTypeForFaction(rt, - factionForResourceView); - - if(showResource == true) { - renderResource(factionForResourceView, localFactionResourcesOnly, - twoRessourceLines, rt, rowsRendered, resourceCountRendered); - } - } - //if(resourceCountRendered > 0) { - // rowsRendered++; - //} - } - - glPopAttrib(); - - assertGl(); -} - -int Renderer::renderResource(const Faction *factionForResourceView,bool localFactionResourcesOnly, - bool twoResourceLines, const ResourceType *rt, int startRow, int &resourceCountRendered) { - - const Metrics &metrics = Metrics::getInstance(); - const int MAX_RESOURCES_PER_ROW = 6; - - int resourceRowHeigth=30; - int resourceYStart=metrics.getVirtualH()-30; - if(twoResourceLines){ - // we need to save some space - resourceYStart=metrics.getVirtualH()-22; - resourceRowHeigth=16; - } - - //draw resource status - if(localFactionResourcesOnly == true) { - Vec4f resourceFontColor = Vec4f(factionForResourceView->getTexture()->getPixmapConst()->getPixel3f(0,0)); - int resourceCol = 0; - int resourceRow = startRow; - - int x=resourceCol * 100 + 190; - int y=resourceYStart - (resourceRowHeigth * resourceRow); - int h=16; - int w=8; - glColor3f(resourceFontColor.x,resourceFontColor.y,resourceFontColor.z); - glBegin(GL_TRIANGLE_STRIP); - glVertex2i(x, y+h); - glVertex2i(x, y); - glVertex2i(x+w, y+h/2); - glEnd(); - } - - const Resource *r = factionForResourceView->getResource(rt,localFactionResourcesOnly); - string str = intToStr(r->getAmount()); - - glEnable(GL_TEXTURE_2D); - - const Vec4f fontColor = game->getGui()->getDisplay()->getColor(); - Vec4f resourceFontColor = fontColor; - - bool isNegativeConsumableDisplayCycle = false; - if(rt->getClass() == rcConsumable) { - // Show in yellow/orange/red font if negative - if(r->getBalance() * 5 + r->getAmount() < 0) { - if(time(NULL) % 2 == 0) { - - isNegativeConsumableDisplayCycle = true; - if(r->getBalance() * 1 + r->getAmount() < 0) { - glColor3f(RED.x,RED.y,RED.z); - resourceFontColor = RED; - } - else if(r->getBalance() * 3 + r->getAmount() < 0) { - glColor3f(ORANGE.x,ORANGE.y,ORANGE.z); - resourceFontColor = ORANGE; - } - else if(r->getBalance() * 5 + r->getAmount() < 0) { - glColor3f(YELLOW.x,YELLOW.y,YELLOW.z); - resourceFontColor = YELLOW; - } - } - } - } - - if(isNegativeConsumableDisplayCycle == false) { - glColor3f(1.f, 1.f, 1.f); - } - - int resourceRow = startRow + (resourceCountRendered > 0 ? resourceCountRendered / MAX_RESOURCES_PER_ROW : 0); - int resourceCol = resourceCountRendered % MAX_RESOURCES_PER_ROW; - - renderQuad(resourceCol * 100 + 200, resourceYStart - (resourceRowHeigth * resourceRow), 16, 16, rt->getImage()); - - if(rt->getClass() != rcStatic) { - str+= "/" + intToStr(factionForResourceView->getStoreAmount(rt,localFactionResourcesOnly)); - } - if(rt->getClass() == rcConsumable) { - str+= "("; - if(r->getBalance() > 0) { - str+= "+"; - } - str+= intToStr(r->getBalance()) + ")"; - } - - glDisable(GL_TEXTURE_2D); - - if(renderText3DEnabled == true) { - renderTextShadow3D( - str, CoreData::getInstance().getDisplayFontSmall3D(), - resourceFontColor, - resourceCol * 100 + 220, resourceYStart - (resourceRowHeigth * resourceRow), false); - } - else { - renderTextShadow( - str, CoreData::getInstance().getDisplayFontSmall(), - resourceFontColor, - resourceCol * 100 + 220, resourceYStart - (resourceRowHeigth * resourceRow), false); - } - ++resourceCountRendered; - - return resourceRow; -} - -void Renderer::renderSelectionQuad() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - Config &config= Config::getInstance(); - if(config.getBool("RecordMode","false") == true) { - return; - } - - const Gui *gui= game->getGui(); - const SelectionQuad *sq= gui->getSelectionQuad(); - - Vec2i down= sq->getPosDown(); - Vec2i up= sq->getPosUp(); - - if(gui->isSelecting()) { - glPushAttrib(GL_CURRENT_BIT | GL_LINE_BIT); - - Vec2i vertices[4]; - vertices[0] = Vec2i(down.x, down.y); - vertices[1] = Vec2i(up.x, down.y); - vertices[2] = Vec2i(up.x, up.y); - vertices[3] = Vec2i(down.x, up.y); - - glColor3f(0,1,0); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_INT, 0, &vertices[0]); - glDrawArrays(GL_LINE_LOOP, 0, 4); - glDisableClientState(GL_VERTEX_ARRAY); - -/* - glColor3f(0,1,0); - glBegin(GL_LINE_LOOP); - glVertex2i(down.x, down.y); - glVertex2i(up.x, down.y); - glVertex2i(up.x, up.y); - glVertex2i(down.x, up.y); - glEnd(); -*/ - glPopAttrib(); - } -} - -Vec2i computeCenteredPos(const string &text, Font2D *font, int x, int y) { - if(font == NULL) { - //abort(); - throw megaglest_runtime_error("font == NULL (1) text = " + text); - } - const Metrics &metrics= Metrics::getInstance(); - FontMetrics *fontMetrics= font->getMetrics(); - - if(fontMetrics == NULL) { - throw megaglest_runtime_error("fontMetrics == NULL (1) text = " + text); - } - - int virtualX = (fontMetrics->getTextWidth(text) > 0 ? static_cast(fontMetrics->getTextWidth(text)/2.f) : 5); - int virtualY = (fontMetrics->getHeight(text) > 0 ? static_cast(fontMetrics->getHeight(text)/2.f) : 5); - - Vec2i textPos( - x-metrics.toVirtualX(virtualX), - y-metrics.toVirtualY(virtualY)); - - //printf("text [%s] x = %d y = %d virtualX = %d virtualY = %d fontMetrics->getHeight() = %f\n",text.c_str(),x,y,virtualX,virtualY,fontMetrics->getHeight()); - - return textPos; -} - -Vec2i computeCenteredPos(const string &text, Font3D *font, int x, int y) { - if(font == NULL) { - throw megaglest_runtime_error("font == NULL (2) text = " + text); - } - const Metrics &metrics= Metrics::getInstance(); - FontMetrics *fontMetrics= font->getMetrics(); - - if(fontMetrics == NULL) { - throw megaglest_runtime_error("fontMetrics == NULL (2) text = " + text); - } - - int virtualX = (fontMetrics->getTextWidth(text) > 0 ? static_cast(fontMetrics->getTextWidth(text) / 2.f) : 5); - int virtualY = (fontMetrics->getHeight(text) > 0 ? static_cast(fontMetrics->getHeight(text) / 2.f) : 5); - - Vec2i textPos( - x-metrics.toVirtualX(virtualX), - y-metrics.toVirtualY(virtualY)); - - return textPos; -} - -void Renderer::renderTextSurroundingBox(int x, int y, int w, int h, - int maxEditWidth, int maxEditRenderWidth) { - //glColor4fv(color.ptr()); - //glBegin(GL_QUADS); // Start drawing a quad primitive - - //printf("A w = %d maxEditWidth = %d maxEditRenderWidth = %d\n",w,maxEditWidth,maxEditRenderWidth); - if(maxEditWidth >= 0 || maxEditRenderWidth >= 0) { - //printf("B w = %d maxEditWidth = %d maxEditRenderWidth = %d\n",w,maxEditWidth,maxEditRenderWidth); - if(maxEditRenderWidth >= 0) { - w = maxEditRenderWidth; - } - else { - w = maxEditWidth; - } - } - //printf("HI!!!\n"); - glPointSize(20.0f); - - int margin = 4; - //glBegin(GL_POINTS); // Start drawing a point primitive - glBegin(GL_LINE_LOOP); // Start drawing a line primitive - - glVertex3f(x, y+h, 0.0f); // The bottom left corner - glVertex3f(x, y-margin, 0.0f); // The top left corner - glVertex3f(x+w, y-margin, 0.0f); // The top right corner - glVertex3f(x+w, y+h, 0.0f); // The bottom right corner - glEnd(); -} - -void Renderer::renderTextBoundingBox3D(const string &text, Font3D *font, - float alpha, int x, int y, int w, int h, bool centeredW, bool centeredH, - bool editModeEnabled,int maxEditWidth, int maxEditRenderWidth) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); - glEnable(GL_BLEND); - glColor4fv(Vec4f(1.f, 1.f, 1.f, alpha).ptr()); - - Vec2f pos= Vec2f(x, y); - //Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); - if(centeredW == true || centeredH == true) { - getCentered3DPos(text, font, pos, w, h, centeredW, centeredH); - } - - if(editModeEnabled) { - if(maxEditWidth >= 0 || maxEditRenderWidth >= 0) { - int useWidth = maxEditWidth; - string temp = ""; - for(int i = 0; i < useWidth; ++i) { - temp += DEFAULT_CHAR_FOR_WIDTH_CALC; - } - float lineWidth = (font->getTextHandler()->Advance(temp.c_str()) * ::Shared::Graphics::Font::scaleFontValue); - useWidth = (int)lineWidth; - - maxEditWidth = useWidth; - } - - renderTextSurroundingBox(pos.x, pos.y, w, h,maxEditWidth,maxEditRenderWidth); - } - glColor4fv(Vec4f(1.f, 1.f, 1.f, alpha).ptr()); - TextRendererSafeWrapper safeTextRender(textRenderer3D,font); - textRenderer3D->render(text, pos.x, pos.y); - safeTextRender.end(); - - glDisable(GL_BLEND); - glPopAttrib(); -} - -void Renderer::renderText3D(const string &text, Font3D *font, float alpha, int x, int y, bool centered) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); - glEnable(GL_BLEND); - glColor4fv(Vec4f(1.f, 1.f, 1.f, alpha).ptr()); - - Vec2i pos= Vec2i(x, y); - //Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); - - TextRendererSafeWrapper safeTextRender(textRenderer3D,font); - textRenderer3D->render(text, pos.x, pos.y, centered); - //textRenderer3D->end(); - safeTextRender.end(); - - glDisable(GL_BLEND); - glPopAttrib(); -} - -void Renderer::renderText(const string &text, Font2D *font, float alpha, int x, int y, bool centered) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); - glEnable(GL_BLEND); - glColor4fv(Vec4f(1.f, 1.f, 1.f, alpha).ptr()); - - Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); - - TextRendererSafeWrapper safeTextRender(textRenderer,font); - textRenderer->render(text, pos.x, pos.y); - safeTextRender.end(); - - glPopAttrib(); -} - -Vec2f Renderer::getCentered3DPos(const string &text, Font3D *font, Vec2f &pos, int w, int h,bool centeredW, bool centeredH) { - if(centeredW == true) { - if(font == NULL) { - //abort(); - throw megaglest_runtime_error("font == NULL (5) text = " + text); - } - else if(font->getTextHandler() == NULL) { - char szBuf[8096] = ""; - snprintf(szBuf, 8096, "font->getTextHandler() == NULL(5) text = [%s] FontPtr = [%p]\n", text.c_str(),font); - throw megaglest_runtime_error(szBuf); - } - - float lineWidth = (font->getTextHandler()->Advance(text.c_str()) * ::Shared::Graphics::Font::scaleFontValue); - if(lineWidth < w) { - pos.x += ((w / 2.f) - (lineWidth / 2.f)); - } - } - - if(centeredH) { - if(font == NULL) { - throw megaglest_runtime_error("font == NULL (6) text = " + text); - } - else if(font->getTextHandler() == NULL) { - throw megaglest_runtime_error("font->getTextHandler() == NULL (6) text = " + text); - } - - //const Metrics &metrics= Metrics::getInstance(); - //float lineHeight = (font->getTextHandler()->LineHeight(text.c_str()) * Font::scaleFontValue); - float lineHeight = (font->getTextHandler()->LineHeight(text.c_str()) * ::Shared::Graphics::Font::scaleFontValue); - //lineHeight=metrics.toVirtualY(lineHeight); - //lineHeight= lineHeight / (2.f + 0.2f * FontMetrics::DEFAULT_Y_OFFSET_FACTOR); - //pos.y += (h / 2.f) - (lineHeight / 2.f); - //pos.y += (h / 2.f) - (lineHeight); - //pos.y += (lineHeight / 2.f); // y starts at the middle of the render position, so only move up 1/2 the font height - - if(lineHeight < h) { - //printf("line %d, lineHeight [%f] h [%d] text [%s]\n",__LINE__,lineHeight,h,text.c_str()); - - //if(Font::forceFTGLFonts == true) { - // First go to top of bounding box - pos.y += (h - lineHeight); - pos.y -= ((h - lineHeight) / ::Shared::Graphics::Font::scaleFontValueCenterHFactor); -// } -// else { -// pos.y += (float)(((float)h) / 2.0); -// float heightGap = (float)(((float)h - lineHeight) / 2.0); -// pos.y -= heightGap; -// -// //printf("h = %d lineHeight = %f heightGap = %f\n",h,lineHeight,heightGap); -// -// // Now calculate till we get text to middle -// //pos.y -= (realHeight / 2); -// //pos.y += (lineHeight / 2); -// } - } - else if(lineHeight > h) { - //printf("line %d, lineHeight [%f] h [%d] text [%s]\n",__LINE__,lineHeight,h,text.c_str()); - - pos.y += (std::ceil(lineHeight - h)); - } - } - return pos; -} - -void Renderer::renderTextBoundingBox3D(const string &text, Font3D *font, - const Vec3f &color, int x, int y, int w, int h, bool centeredW, - bool centeredH, bool editModeEnabled,int maxEditWidth, int maxEditRenderWidth) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - glPushAttrib(GL_CURRENT_BIT); - glColor3fv(color.ptr()); - - Vec2f pos= Vec2f(x, y); - //Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); - - if(centeredW == true || centeredH == true) { - getCentered3DPos(text, font, pos, w, h,centeredW,centeredH); - } - - if(editModeEnabled) { - if(maxEditWidth >= 0 || maxEditRenderWidth >= 0) { - int useWidth = maxEditWidth; - string temp = ""; - for(int i = 0; i < useWidth; ++i) { - temp += DEFAULT_CHAR_FOR_WIDTH_CALC; - } - float lineWidth = (font->getTextHandler()->Advance(temp.c_str()) * ::Shared::Graphics::Font::scaleFontValue); - useWidth = (int)lineWidth; - - maxEditWidth = useWidth; - } - - renderTextSurroundingBox(pos.x, pos.y, w, h,maxEditWidth,maxEditRenderWidth); - } - glColor3fv(color.ptr()); - TextRendererSafeWrapper safeTextRender(textRenderer3D,font); - textRenderer3D->render(text, pos.x, pos.y); - safeTextRender.end(); - - glPopAttrib(); -} - -void Renderer::renderText3D(const string &text, Font3D *font, const Vec3f &color, int x, int y, bool centered) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - glPushAttrib(GL_CURRENT_BIT); - glColor3fv(color.ptr()); - - Vec2i pos= Vec2i(x, y); - //Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); - - TextRendererSafeWrapper safeTextRender(textRenderer3D,font); - textRenderer3D->render(text, pos.x, pos.y, centered); - safeTextRender.end(); - - glPopAttrib(); -} - -void Renderer::renderText(const string &text, Font2D *font, const Vec3f &color, int x, int y, bool centered){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - glPushAttrib(GL_CURRENT_BIT); - glColor3fv(color.ptr()); - - Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); - - TextRendererSafeWrapper safeTextRender(textRenderer,font); - textRenderer->render(text, pos.x, pos.y); - safeTextRender.end(); - - glPopAttrib(); -} - -void Renderer::renderTextBoundingBox3D(const string &text, Font3D *font, - const Vec4f &color, int x, int y, int w, int h, bool centeredW, - bool centeredH, bool editModeEnabled,int maxEditWidth, int maxEditRenderWidth) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); - glEnable(GL_BLEND); - glColor4fv(color.ptr()); - - Vec2f pos= Vec2f(x, y); - //Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); - - if(centeredW == true || centeredH == true) { - getCentered3DPos(text, font, pos, w, h,centeredW,centeredH); - } - - if(editModeEnabled) { - if(maxEditWidth >= 0 || maxEditRenderWidth >= 0) { - int useWidth = maxEditWidth; - string temp = ""; - for(int i = 0; i < useWidth; ++i) { - temp += DEFAULT_CHAR_FOR_WIDTH_CALC; - } - float lineWidth = (font->getTextHandler()->Advance(temp.c_str()) * ::Shared::Graphics::Font::scaleFontValue); - useWidth = (int)lineWidth; - - maxEditWidth = useWidth; - } - - renderTextSurroundingBox(pos.x, pos.y, w, h,maxEditWidth,maxEditRenderWidth); - } - glColor4fv(color.ptr()); - TextRendererSafeWrapper safeTextRender(textRenderer3D,font); - textRenderer3D->render(text, pos.x, pos.y); - safeTextRender.end(); - - glDisable(GL_BLEND); - glPopAttrib(); -} - -void Renderer::renderText3D(const string &text, Font3D *font, const Vec4f &color, int x, int y, bool centered) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); - glEnable(GL_BLEND); - glColor4fv(color.ptr()); - - Vec2i pos= Vec2i(x, y); - //Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); - - TextRendererSafeWrapper safeTextRender(textRenderer3D,font); - textRenderer3D->render(text, pos.x, pos.y, centered); - safeTextRender.end(); - - glDisable(GL_BLEND); - glPopAttrib(); -} - -void Renderer::renderText(const string &text, Font2D *font, const Vec4f &color, int x, int y, bool centered){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); - glEnable(GL_BLEND); - glColor4fv(color.ptr()); - - Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); - - TextRendererSafeWrapper safeTextRender(textRenderer,font); - textRenderer->render(text, pos.x, pos.y); - safeTextRender.end(); - - glPopAttrib(); -} - -void Renderer::renderTextShadow3D(const string &text, Font3D *font,const Vec4f &color, int x, int y, bool centered) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(font == NULL) { - throw megaglest_runtime_error("font == NULL (3) text = " + text); - } - - glPushAttrib(GL_CURRENT_BIT); - - Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); - - TextRendererSafeWrapper safeTextRender(textRenderer3D,font); - if(color.w < 0.5) { - glColor3f(0.0f, 0.0f, 0.0f); - - textRenderer3D->render(text, pos.x-1.0f, pos.y-1.0f); - } - glColor3f(color.x,color.y,color.z); - - textRenderer3D->render(text, pos.x, pos.y); - //textRenderer3D->end(); - safeTextRender.end(); - - glPopAttrib(); -} - -void Renderer::renderTextShadow(const string &text, Font2D *font,const Vec4f &color, int x, int y, bool centered){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(font == NULL) { - throw megaglest_runtime_error("font == NULL (4) text = " + text); - } - - glPushAttrib(GL_CURRENT_BIT); - - Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); - - TextRendererSafeWrapper safeTextRender(textRenderer,font); - if(color.w < 0.5) { - glColor3f(0.0f, 0.0f, 0.0f); - - textRenderer->render(text, pos.x-1.0f, pos.y-1.0f); - } - glColor3f(color.x,color.y,color.z); - - textRenderer->render(text, pos.x, pos.y); - //textRenderer->end(); - safeTextRender.end(); - - glPopAttrib(); -} - -// ============= COMPONENTS ============================= - -void Renderer::renderLabel(GraphicLabel *label) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(label->getEditable() && label->getMaxEditRenderWidth()>0) - { - int x= label->getX(); - int y= label->getY(); - int h= label->getH(); - int w= label->getMaxEditRenderWidth(); - if(h>0){ - //background - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); - glEnable(GL_BLEND); - - glColor4f(0.2f, 0.2f, 0.2f, 0.6f*label->getFade()) ; - - glBegin(GL_TRIANGLE_STRIP); - glVertex2i(x, y); - glVertex2i(x, y+h); - glVertex2i(x+w, y); - glVertex2i(x+w, y+h); - glEnd(); - glPopAttrib(); - } - } - - if(label->getRenderBackground()) - { - int x= label->getX(); - int y= label->getY(); - int h= label->getH(); - int w= label->getW(); - if(label->getMaxEditRenderWidth()>0){ - w= label->getMaxEditRenderWidth(); - } - Vec4f color=label->getBackgroundColor(); - if(h>0){ - //background - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); - glEnable(GL_BLEND); - - glColor4f(color.x, color.y, color.z, color.w*label->getFade()) ; - - glBegin(GL_TRIANGLE_STRIP); - glVertex2i(x, y); - glVertex2i(x, y+h); - glVertex2i(x+w, y); - glVertex2i(x+w, y+h); - glEnd(); - glPopAttrib(); - } - } - - if(label->getTexture()!=NULL ) - { - int x= label->getX(); - int y= label->getY(); - int h= label->getH(); - int w= label->getW(); - if(h>0){ - //background - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, static_cast( label->getTexture())->getHandle()); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f*label->getFade()) ; - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(0.f, 0.f); - glVertex2f(x, y); - - glTexCoord2f(0.f, 1.f); - glVertex2f(x, y+h); - - glTexCoord2f(1.f, 0.f); - glVertex2f(x+w, y); - - glTexCoord2f(1.f, 1.f); - glVertex2f(x+w, y+h); - glEnd(); - glDisable(GL_TEXTURE_2D); - glPopAttrib(); - } - } - Vec3f labelColor=label->getTextColor(); - Vec4f colorWithAlpha = Vec4f(labelColor.x,labelColor.y,labelColor.z,GraphicComponent::getFade()); - renderLabel(label,&colorWithAlpha); -} - -void Renderer::renderLabel(GraphicLabel *label,const Vec3f *color) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(color != NULL) { - Vec4f colorWithAlpha = Vec4f(*color); - colorWithAlpha.w = GraphicComponent::getFade(); - renderLabel(label,&colorWithAlpha); - } - else { - Vec4f *colorWithAlpha = NULL; - renderLabel(label,colorWithAlpha); - } -} - -void Renderer::renderLabel(GraphicLabel *label,const Vec4f *color) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(label->getVisible() == false) { - return; - } - try { - glPushAttrib(GL_ENABLE_BIT); - glEnable(GL_BLEND); - - vector lines; - string renderTextString = (label->getTextNativeTranslation() != "" ? label->getTextNativeTranslation() : label->getText()); - if(label->getWordWrap() == true) { - Tokenize(renderTextString,lines,"\n"); - } - else { - lines.push_back(renderTextString); - } - - for(unsigned int i = 0; i < lines.size(); ++i) { - Vec2i textPos; - int x= label->getX(); - int y= label->getY() - (i * label->getH()); - int h= label->getH(); - int w= label->getW(); - //if(label->getInstanceName() == "modDescrLabel") printf("~~~ lines.size() [%u] i = %d lines[i] [%s] y = %d\n",lines.size(),i,lines[i].c_str(),y); - - if(label->getCentered()) { - textPos= Vec2i(x+w/2, y+h/2); - } - else { - textPos= Vec2i(x, y+h/4); - } - - string renderTextStr = lines[i]; - if(label->getIsPassword() == true) { - if(renderTextStr != "") { - renderTextStr = "*****"; - } - } - - if(color != NULL) { - if(renderText3DEnabled == true) { - //renderText3D(lines[i], label->getFont3D(), (*color), textPos.x, textPos.y, label->getCentered()); - //printf("Text Render3D [%s] font3d [%p]\n",lines[i].c_str(),label->getFont3D()); - //printf("Label render C\n"); - - renderTextBoundingBox3D(renderTextStr, label->getFont3D(), (*color), - x, y, w, h, label->getCenteredW(),label->getCenteredH(), - label->getEditModeEnabled(),label->getMaxEditWidth(), - label->getMaxEditRenderWidth()); - } - else { - //printf("Label render D\n"); - renderText(renderTextStr, label->getFont(), (*color), textPos.x, textPos.y, label->getCentered()); - } - } - else { - if(renderText3DEnabled == true) { - //renderText3D(lines[i], label->getFont3D(), GraphicComponent::getFade(), textPos.x, textPos.y, label->getCentered()); - //printf("Text Render3D [%s] font3d [%p]\n",lines[i].c_str(),label->getFont3D()); - //printf("Label render E\n"); - renderTextBoundingBox3D(renderTextStr, label->getFont3D(), - GraphicComponent::getFade(), x, y, w, h, - label->getCenteredW(),label->getCenteredH(), - label->getEditModeEnabled(),label->getMaxEditWidth(), - label->getMaxEditRenderWidth()); - } - else { - //printf("Label render F\n"); - renderText(renderTextStr, label->getFont(), GraphicComponent::getFade(), textPos.x, textPos.y, label->getCentered()); - } - } - } - glPopAttrib(); - } - catch(const exception &e) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s] For Control [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what(),label->getInstanceName().c_str()); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf); - - throw megaglest_runtime_error(szBuf); - } - -} - -void Renderer::renderButton(GraphicButton *button, const Vec4f *fontColorOverride, bool *lightedOverride) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(button->getVisible() == false) { - return; - } - - try { - - //char szBuf[8096]=""; - //snprintf(szBuf,8096,"In [%s::%s Line: %d]\n For Control container [%s] name [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,button->getContainerName().c_str(), button->getInstanceName().c_str()); - //printf(szBuf); - - int x= button->getX(); - int y= button->getY(); - int h= button->getH(); - int w= button->getW(); - - const Vec3f disabledTextColor= Vec3f(0.25f,0.25f,0.25f); - - glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT); - - //background - CoreData &coreData= CoreData::getInstance(); - Texture2D *backTexture = NULL; - - if(button->getUseCustomTexture() == true) { - backTexture = dynamic_cast(button->getCustomTexture()); - } - else { - backTexture = w > 3 * h / 2 ? coreData.getButtonBigTexture(): coreData.getButtonSmallTexture(); - } - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - - if(backTexture != NULL) { - glBindTexture(GL_TEXTURE_2D, static_cast(backTexture)->getHandle()); - } - else { - glBindTexture(GL_TEXTURE_2D, 0); - } - - //button - Vec4f fontColor(GraphicComponent::getCustomTextColor()); - - if(fontColorOverride != NULL) { - fontColor= *fontColorOverride; - } - else { - // white shadowed is default ( in the menu for example ) - fontColor.w = GraphicComponent::getFade(); - } - - //Vec4f color= Vec4f(1.f, 1.f, 1.f, GraphicComponent::getFade()); - Vec4f color= fontColor; - glColor4fv(color.ptr()); - - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(0.f, 0.f); - glVertex2f(x, y); - - glTexCoord2f(0.f, 1.f); - glVertex2f(x, y+h); - - glTexCoord2f(1.f, 0.f); - glVertex2f(x+w, y); - - glTexCoord2f(1.f, 1.f); - glVertex2f(x+w, y+h); - - glEnd(); - - glDisable(GL_TEXTURE_2D); - - //lighting - float anim= GraphicComponent::getAnim(); - if(anim>0.5f) anim= 1.f-anim; - - bool renderLighted = (button->getLighted() && button->getEditable()); - if(lightedOverride != NULL) { - renderLighted = *lightedOverride; - } - if(renderLighted) { - const int lightSize= 0; - const Vec4f color1= Vec4f(color.x, color.y, color.z, 0.1f+anim*0.5f); - const Vec4f color2= Vec4f(color.x, color.y, color.z, 0.3f+anim); - - glBegin(GL_TRIANGLE_FAN); - - glColor4fv(color2.ptr()); - glVertex2f(x+w/2, y+h/2); - - glColor4fv(color1.ptr()); - glVertex2f(x-lightSize, y-lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x+w+lightSize, y-lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x+w+lightSize, y+h+lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x+w+lightSize, y+h+lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x-lightSize, y+h+lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x-lightSize, y-lightSize); - - glEnd(); - } - - //Vec2i textPos= Vec2i(x + w / 2, y + h / 2); - - if(button->getEditable()) { - if(renderText3DEnabled == true) { - //renderText3D(button->getText(), button->getFont3D(), color,x + (w / 2), y + (h / 2), true); - renderTextBoundingBox3D(button->getText(), button->getFont3D(), - color, x, y, w, h, true, true,false,-1,-1); - } - else { - renderText(button->getText(), button->getFont(), color,x + (w / 2), y + (h / 2), true); - } - } - else { - if(renderText3DEnabled == true) { - //renderText3D(button->getText(), button->getFont3D(),disabledTextColor, - // x + (w / 2), y + (h / 2), true); - renderTextBoundingBox3D(button->getText(), button->getFont3D(),disabledTextColor, - x, y, w, h, true, true,false,-1,-1); - } - else { - renderText(button->getText(), button->getFont(),disabledTextColor, - x + (w / 2), y + (h / 2), true); - } - } - - glPopAttrib(); - } - catch(const exception &e) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s] For Control container [%s] name [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what(),button->getContainerName().c_str(), button->getInstanceName().c_str()); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf); - - throw megaglest_runtime_error(szBuf); - } -} - -void Renderer::renderCheckBox(const GraphicCheckBox *box) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(box->getVisible() == false) { - return; - } - - int x= box->getX(); - int y= box->getY(); - int h= box->getH(); - int w= box->getW(); - - //const Vec3f disabledTextColor= Vec3f(0.25f,0.25f,0.25f); - - glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT); - - //background - CoreData &coreData= CoreData::getInstance(); - Texture2D *backTexture= box->getValue()? coreData.getCheckedCheckBoxTexture(): coreData.getCheckBoxTexture(); - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - - glBindTexture(GL_TEXTURE_2D, static_cast(backTexture)->getHandle()); - - //box - Vec4f fontColor; - //if(game!=NULL){ - // fontColor=game->getGui()->getDisplay()->getColor(); - // fontColor.w = GraphicComponent::getFade(); - //} - //else { - // white shadowed is default ( in the menu for example ) - fontColor=Vec4f(1.f, 1.f, 1.f, GraphicComponent::getFade()); - //} - - //Vec4f color= Vec4f(1.f, 1.f, 1.f, GraphicComponent::getFade()); - Vec4f color= fontColor; - glColor4fv(color.ptr()); - - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(0.f, 0.f); - glVertex2f(x, y); - - glTexCoord2f(0.f, 1.f); - glVertex2f(x, y+h); - - glTexCoord2f(1.f, 0.f); - glVertex2f(x+w, y); - - glTexCoord2f(1.f, 1.f); - glVertex2f(x+w, y+h); - - glEnd(); - - glDisable(GL_TEXTURE_2D); - - //lighting - float anim= GraphicComponent::getAnim(); - if(anim > 0.5f) { - anim = 1.f - anim; - } - - if(box->getLighted() && box->getEditable()) { - const int lightSize= 0; - const Vec4f color1= Vec4f(color.x, color.y, color.z, 0.1f+anim*0.5f); - const Vec4f color2= Vec4f(color.x, color.y, color.z, 0.3f+anim); - - glBegin(GL_TRIANGLE_FAN); - - glColor4fv(color2.ptr()); - glVertex2f(x+w/2, y+h/2); - - glColor4fv(color1.ptr()); - glVertex2f(x-lightSize, y-lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x+w+lightSize, y-lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x+w+lightSize, y+h+lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x+w+lightSize, y+h+lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x-lightSize, y+h+lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x-lightSize, y-lightSize); - - glEnd(); - } - - glPopAttrib(); -} - - -void Renderer::renderLine(const GraphicLine *line) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(line->getVisible() == false) { - return; - } - - int x= line->getX(); - int y= line->getY(); - int h= line->getH(); - int w= line->getW(); - - //const Vec3f disabledTextColor= Vec3f(0.25f,0.25f,0.25f); - - glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT); - - //background - CoreData &coreData= CoreData::getInstance(); - Texture2D *backTexture= line->getHorizontal()? coreData.getHorizontalLineTexture(): coreData.getVerticalLineTexture(); - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - - glBindTexture(GL_TEXTURE_2D, static_cast(backTexture)->getHandle()); - - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(0.f, 0.f); - glVertex2f(x, y); - - glTexCoord2f(0.f, 1.f); - glVertex2f(x, y+h); - - glTexCoord2f(1.f, 0.f); - glVertex2f(x+w, y); - - glTexCoord2f(1.f, 1.f); - glVertex2f(x+w, y+h); - - glEnd(); - - glDisable(GL_TEXTURE_2D); - glPopAttrib(); -} - -void Renderer::renderScrollBar(const GraphicScrollBar *sb) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(sb->getVisible() == false) { - return; - } - - int x= sb->getX(); - int y= sb->getY(); - int h= sb->getH(); - int w= sb->getW(); - - //const Vec3f disabledTextColor= Vec3f(0.25f,0.25f,0.25f); - - glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT); - ///////////////////// - //background - //////////////////// - CoreData &coreData= CoreData::getInstance(); - Texture2D *backTexture= coreData.getHorizontalLineTexture(); - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - - glBindTexture(GL_TEXTURE_2D, static_cast(backTexture)->getHandle()); - - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(0.f, 0.f); - glVertex2f(x, y); - - glTexCoord2f(0.f, 1.f); - glVertex2f(x, y+h); - - glTexCoord2f(1.f, 0.f); - glVertex2f(x+w, y); - - glTexCoord2f(1.f, 1.f); - glVertex2f(x+w, y+h); - - glEnd(); - - //////////////////// - // selectBlock - //////////////////// - - x= sb->getX(); - y= sb->getY(); - h= sb->getH(); - w= sb->getW(); - - if( sb->getHorizontal()) { - x=x+sb->getVisibleCompPosStart(); - w=sb->getVisibleCompPosEnd()-sb->getVisibleCompPosStart(); - } - else { - y=y+sb->getVisibleCompPosStart(); - h=sb->getVisibleCompPosEnd()-sb->getVisibleCompPosStart(); - } - - Texture2D *selectTexture= coreData.getButtonBigTexture(); - assert(selectTexture != NULL); - - glBindTexture(GL_TEXTURE_2D, static_cast(selectTexture)->getHandle()); - - //button - Vec4f fontColor; - //if(game!=NULL){ - // fontColor=game->getGui()->getDisplay()->getColor(); - // fontColor.w = GraphicComponent::getFade(); - //} - //else { - // white shadowed is default ( in the menu for example ) - fontColor=Vec4f(1.f, 1.f, 1.f, GraphicComponent::getFade()); - //} - - //Vec4f color= Vec4f(1.f, 1.f, 1.f, GraphicComponent::getFade()); - Vec4f color= fontColor; - glColor4fv(color.ptr()); - - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(0.f, 0.f); - glVertex2f(x, y); - - glTexCoord2f(0.f, 1.f); - glVertex2f(x, y+h); - - glTexCoord2f(1.f, 0.f); - glVertex2f(x+w, y); - - glTexCoord2f(1.f, 1.f); - glVertex2f(x+w, y+h); - - glEnd(); - - glDisable(GL_TEXTURE_2D); - - //lighting - float anim= GraphicComponent::getAnim(); - if(anim>0.5f) anim= 1.f-anim; - - if(sb->getLighted() && sb->getEditable()){ - const int lightSize= 0; - const Vec4f color1= Vec4f(color.x, color.y, color.z, 0.1f+anim*0.5f); - const Vec4f color2= Vec4f(color.x, color.y, color.z, 0.3f+anim); - - glBegin(GL_TRIANGLE_FAN); - - glColor4fv(color2.ptr()); - glVertex2f(x+w/2, y+h/2); - - glColor4fv(color1.ptr()); - glVertex2f(x-lightSize, y-lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x+w+lightSize, y-lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x+w+lightSize, y+h+lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x+w+lightSize, y+h+lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x-lightSize, y+h+lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x-lightSize, y-lightSize); - - glEnd(); - } - - glPopAttrib(); -} - -void Renderer::renderListBox(GraphicListBox *listBox) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(listBox->getVisible() == false) { - return; - } - //if(listBox->getLeftControlled()==true) - { - int x= listBox->getX(); - int y= listBox->getY(); - int h= listBox->getH(); - int w= listBox->getW(); - if(h>0){ - //background - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); - glEnable(GL_BLEND); - - glColor4f(0.0f, 0.0f, 0.0f, 0.6f*listBox->getFade()) ; - - glBegin(GL_TRIANGLE_STRIP); - glVertex2i(x, y); - glVertex2i(x, y+h); - glVertex2i(x+w, y); - glVertex2i(x+w, y+h); - glEnd(); - glPopAttrib(); - } - } - renderButton(listBox->getButton1()); - renderButton(listBox->getButton2()); - - glPushAttrib(GL_ENABLE_BIT); - glEnable(GL_BLEND); - - GraphicLabel label("ListBox_render_label","label",false); - //label.setInstanceName("ListBox_render_label"); - if(listBox->getLeftControlled()==true){ - label.init(listBox->getX()+listBox->getButton1()->getW()+listBox->getButton2()->getW()+2, listBox->getY(), listBox->getW(), listBox->getH(), false,listBox->getTextColor()); - } - else { - label.init(listBox->getX(), listBox->getY(), listBox->getW(), listBox->getH(), true,listBox->getTextColor()); - } - label.setText(listBox->getText()); - label.setTextNativeTranslation(listBox->getTextNativeTranslation()); - label.setFont(listBox->getFont()); - label.setFont3D(listBox->getFont3D()); - renderLabel(&label); - - - //lighting - - bool renderLighted= (listBox->getLighted()); - - - if(renderLighted) { - float anim= GraphicComponent::getAnim(); - if(anim>0.5f) anim= 1.f-anim; - - Vec3f color=listBox->getTextColor(); - int x= listBox->getX()+listBox->getButton1()->getW(); - int y= listBox->getY(); - int h= listBox->getH(); - int w= listBox->getW()-listBox->getButton1()->getW()-listBox->getButton2()->getW(); - - const int lightSize= 0; - const Vec4f color1= Vec4f(color.x, color.y, color.z, 0.1f+anim*0.5f); - const Vec4f color2= Vec4f(color.x, color.y, color.z, 0.3f+anim); - - glBegin(GL_TRIANGLE_FAN); - - glColor4fv(color2.ptr()); - glVertex2f(x+w/2, y+h/2); - - glColor4fv(color1.ptr()); - glVertex2f(x-lightSize, y-lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x+w+lightSize, y-lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x+w+lightSize, y+h+lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x+w+lightSize, y+h+lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x-lightSize, y+h+lightSize); - - glColor4fv(color1.ptr()); - glVertex2f(x-lightSize, y-lightSize); - - glEnd(); - } - - glPopAttrib(); -} - -void Renderer::renderMessageBox(GraphicMessageBox *messageBox) { - const int headerHeight=25; - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - try { - if(messageBox->getVisible() == false) { - return; - } - - if((renderText3DEnabled == false && messageBox->getFont() == NULL) || - (renderText3DEnabled == true && messageBox->getFont3D() == NULL)) { - messageBox->setFont(CoreData::getInstance().getMenuFontNormal()); - messageBox->setFont3D(CoreData::getInstance().getMenuFontNormal3D()); - } - - string wrappedText = messageBox->getText(); - if(messageBox->getAutoWordWrap() == true) { - if(renderText3DEnabled == false) { - wrappedText = messageBox->getFont()->getMetrics()->wordWrapText(wrappedText,messageBox->getW() * 0.90); - } - else { - wrappedText = messageBox->getFont3D()->getMetrics()->wordWrapText(wrappedText,messageBox->getW() * 0.90); - } - } - - //background - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); - glEnable(GL_BLEND); - - glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ; - glBegin(GL_TRIANGLE_STRIP); - glVertex2i(messageBox->getX(), messageBox->getY()+messageBox->getH()-headerHeight); - glVertex2i(messageBox->getX(), messageBox->getY()); - glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + messageBox->getH()-headerHeight); - glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY()); - glEnd(); - - glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ; - glBegin(GL_TRIANGLE_STRIP); - glVertex2i(messageBox->getX(), messageBox->getY()+messageBox->getH()); - glVertex2i(messageBox->getX(), messageBox->getY()+messageBox->getH()-headerHeight); - glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + messageBox->getH()); - glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY()+messageBox->getH()-headerHeight); - glEnd(); - - glBegin(GL_LINE_LOOP); - glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ; - glVertex2i(messageBox->getX(), messageBox->getY()); - - glColor4f(0.0f, 0.0f, 0.0f, 0.25f) ; - glVertex2i(messageBox->getX()+ messageBox->getW(), messageBox->getY()); - - glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ; - glVertex2i(messageBox->getX()+ messageBox->getW(), messageBox->getY() + messageBox->getH()); - - glColor4f(0.25f, 0.25f, 0.25f, 0.25f) ; - glVertex2i(messageBox->getX(), messageBox->getY() + messageBox->getH()); - glEnd(); - - glBegin(GL_LINE_STRIP); - glColor4f(1.0f, 1.0f, 1.0f, 0.25f) ; - glVertex2i(messageBox->getX(), messageBox->getY() + messageBox->getH()-headerHeight); - - glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ; - glVertex2i(messageBox->getX()+ messageBox->getW(), messageBox->getY() + messageBox->getH()-headerHeight); - glEnd(); - - glPopAttrib(); - - - //buttons - for(int i=0; igetButtonCount();i++){ - - if((renderText3DEnabled == false && messageBox->getButton(i)->getFont() == NULL) || - (renderText3DEnabled == true && messageBox->getButton(i)->getFont3D() == NULL)) { - messageBox->getButton(i)->setFont(CoreData::getInstance().getMenuFontNormal()); - messageBox->getButton(i)->setFont3D(CoreData::getInstance().getMenuFontNormal3D()); - } - - renderButton(messageBox->getButton(i)); - } - - Vec4f fontColor; - //if(game!=NULL){ - // fontColor=game->getGui()->getDisplay()->getColor(); - //} - //else { - // white shadowed is default ( in the menu for example ) - fontColor=Vec4f(1.f, 1.f, 1.f, 1.0f); - //} - - if(renderText3DEnabled == true) { - //text - renderTextShadow3D( - wrappedText, messageBox->getFont3D(), fontColor, - messageBox->getX()+15, messageBox->getY()+messageBox->getH()-headerHeight*2, - false ); - - renderTextShadow3D( - messageBox->getHeader(), messageBox->getFont3D(),fontColor, - messageBox->getX()+15, messageBox->getY()+messageBox->getH()-headerHeight+8, - false ); - - } - else { - //text - renderTextShadow( - wrappedText, messageBox->getFont(), fontColor, - messageBox->getX()+15, messageBox->getY()+messageBox->getH()-headerHeight*2, - false ); - - renderTextShadow( - messageBox->getHeader(), messageBox->getFont(),fontColor, - messageBox->getX()+15, messageBox->getY()+messageBox->getH()-headerHeight+8, - false ); - } - } - catch(const exception &e) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what()); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,szBuf); - - throw megaglest_runtime_error(szBuf); - } -} - -// ==================== complex rendering ==================== - -//VisibleQuadContainerVBOCache * Renderer::GetSurfaceVBOs(SurfaceData *cellData) { -// std::map::iterator iterFind = mapSurfaceVBOCache.find(cellData->uniqueId); -// if(iterFind == mapSurfaceVBOCache.end()) { -// Vec2f *texCoords = &cellData->texCoords[0]; -// Vec2f *texCoordsSurface = &cellData->texCoordsSurface[0]; -// Vec3f *vertices = &cellData->vertices[0]; -// Vec3f *normals = &cellData->normals[0]; -// -// VisibleQuadContainerVBOCache vboCache; -// -// // Generate And Bind The Vertex Buffer -// glGenBuffersARB( 1, (GLuint*)&vboCache.m_nVBOVertices ); // Get A Valid Name -// glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache.m_nVBOVertices ); // Bind The Buffer -// // Load The Data -// glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec3f) * cellData->bufferCount, vertices, GL_STATIC_DRAW_ARB ); -// glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); -// -// assertGl(); -// // Generate And Bind The Texture Coordinate Buffer -// glGenBuffersARB( 1, (GLuint*)&vboCache.m_nVBOFowTexCoords ); // Get A Valid Name -// glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache.m_nVBOFowTexCoords ); // Bind The Buffer -// // Load The Data -// glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec2f) * cellData->bufferCount, texCoords, GL_STATIC_DRAW_ARB ); -// glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); -// -// assertGl(); -// // Generate And Bind The Texture Coordinate Buffer -// glGenBuffersARB( 1, (GLuint*)&vboCache.m_nVBOSurfaceTexCoords ); // Get A Valid Name -// glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache.m_nVBOSurfaceTexCoords ); // Bind The Buffer -// // Load The Data -// glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec2f) * cellData->bufferCount, texCoordsSurface, GL_STATIC_DRAW_ARB ); -// glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); -// -// assertGl(); -// // Generate And Bind The Normal Buffer -// glGenBuffersARB( 1, (GLuint*)&vboCache.m_nVBONormals ); // Get A Valid Name -// glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache.m_nVBONormals ); // Bind The Buffer -// // Load The Data -// glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec3f) * cellData->bufferCount, normals, GL_STATIC_DRAW_ARB ); -// glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); -// -// vboCache.hasBuiltVBOs = true; -// -// mapSurfaceVBOCache[cellData->uniqueId] = vboCache; -// -// // don't need the data in computer RAM anymore its in the GPU now -// cellData->texCoords.clear(); -// cellData->texCoordsSurface.clear(); -// cellData->vertices.clear(); -// cellData->normals.clear(); -// } -// -// return &mapSurfaceVBOCache[cellData->uniqueId]; -//} - -void Renderer::ReleaseSurfaceVBOs() { - for(std::map::iterator iterFind = mapSurfaceVBOCache.begin(); - iterFind != mapSurfaceVBOCache.end(); ++iterFind) { - - VisibleQuadContainerVBOCache &item = iterFind->second; - if(item.hasBuiltVBOs == true) { - glDeleteBuffersARB( 1, (GLuint*)&item.m_nVBOVertices ); // Get A Valid Name - glDeleteBuffersARB( 1, (GLuint*)&item.m_nVBOFowTexCoords ); // Get A Valid Name - glDeleteBuffersARB( 1, (GLuint*)&item.m_nVBOSurfaceTexCoords ); // Get A Valid Name - glDeleteBuffersARB( 1, (GLuint*)&item.m_nVBONormals ); // Get A Valid Name - //glDeleteBuffersARB( 1, &item.m_nVBOIndexes ); // Get A Valid Name - } - } - - mapSurfaceVBOCache.clear(); -} - -Renderer::MapRenderer::Layer::~Layer() { - if(vbo_vertices) glDeleteBuffersARB(1,&vbo_vertices); - if(vbo_normals) glDeleteBuffersARB(1,&vbo_normals); - if(vbo_fowTexCoords) glDeleteBuffersARB(1,&vbo_fowTexCoords); - if(vbo_surfTexCoords) glDeleteBuffersARB(1,&vbo_surfTexCoords); - if(vbo_indices) glDeleteBuffersARB(1,&vbo_indices); - -} - -template void _loadVBO(GLuint &vbo,std::vector buf,int target=GL_ARRAY_BUFFER_ARB) { - assert(buf.size()); - if(true /* vbo enabled? */) { - glGenBuffersARB(1,&vbo); - assert(vbo); - glBindBufferARB(target,vbo); - glBufferDataARB(target,sizeof(T)*buf.size(),&buf[0],GL_STATIC_DRAW_ARB); - glBindBufferARB(target,0); - assertGl(); - buf.clear(); - } -} - -void Renderer::MapRenderer::Layer::load_vbos(bool vboEnabled) { - indexCount = (int)indices.size(); - if(vboEnabled) { - _loadVBO(vbo_vertices,vertices); - _loadVBO(vbo_normals,normals); - _loadVBO(vbo_fowTexCoords,fowTexCoords); - _loadVBO(vbo_surfTexCoords,surfTexCoords); - - _loadVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB); - } - else { - vbo_vertices = 0; - vbo_normals = 0; - vbo_fowTexCoords = 0; - vbo_surfTexCoords = 0; - vbo_indices = 0; - } -} - -void Renderer::MapRenderer::loadVisibleLayers(float coordStep,VisibleQuadContainerCache &qCache) { - int totalCellCount = 0; - // we create a layer for each visible texture in the map - for(int visibleIndex = 0; - visibleIndex < (int)qCache.visibleScaledCellList.size(); ++visibleIndex) { - Vec2i &pos = qCache.visibleScaledCellList[visibleIndex]; - - totalCellCount++; - - SurfaceCell *tc00= map->getSurfaceCell(pos.x, pos.y); - SurfaceCell *tc10= map->getSurfaceCell(pos.x+1, pos.y); - SurfaceCell *tc01= map->getSurfaceCell(pos.x, pos.y+1); - SurfaceCell *tc11= map->getSurfaceCell(pos.x+1, pos.y+1); - - const Vec2f &surfCoord= tc00->getSurfTexCoord(); - - SurfaceCell *tc[4] = { - tc00, - tc10, - tc01, - tc11 + enum PROJECTION_TO_INFINITY { + pti_D_IS_ZERO, + pti_N_OVER_D_IS_OUTSIDE }; - int textureHandle = static_cast(tc[0]->getSurfaceTexture())->getHandle(); - string texturePath = static_cast(tc[0]->getSurfaceTexture())->getPath(); - //int32 textureCRC = CalculatePixelsCRC(static_cast(tc[0]->getSurfaceTexture())); - Layer* layer = NULL; - for(Layers::iterator it= layers.begin(); it!= layers.end(); ++it) { - if((*it)->textureHandle == textureHandle) { - //if((*it)->texturePath == texturePath) { - //if((*it)->textureCRC == textureCRC) { - layer = *it; - break; - } - } - if(!layer) { - layer = new Layer(textureHandle); - layer->texturePath = texturePath; - //layer->textureCRC = textureCRC; - layers.push_back(layer); - //printf("Ading new unique texture [%s]\n",texturePath.c_str()); - } - // we'll be super-lazy and re-emit all four corners just because its easier - int index[4]; - int loopIndexes[4] = { 2,0,3,1 }; - for(int i=0; i < 4; i++) { - index[i] = (int)layer->vertices.size(); - SurfaceCell *corner = tc[loopIndexes[i]]; + // ===================================================== + // class MeshCallbackTeamColor + // ===================================================== - layer->vertices.push_back(corner->getVertex()); - layer->normals.push_back(corner->getNormal()); - layer->fowTexCoords.push_back(corner->getFowTexCoord()); - } + bool MeshCallbackTeamColor::noTeamColors = false; - layer->surfTexCoords.push_back(Vec2f(surfCoord.x, surfCoord.y + coordStep)); - layer->surfTexCoords.push_back(Vec2f(surfCoord.x, surfCoord.y)); - layer->surfTexCoords.push_back(Vec2f(surfCoord.x+coordStep, surfCoord.y+coordStep)); - layer->surfTexCoords.push_back(Vec2f(surfCoord.x+coordStep, surfCoord.y)); + void MeshCallbackTeamColor::execute(const Mesh *mesh) { + //team color + if (mesh->getCustomTexture() && teamTexture != NULL && + MeshCallbackTeamColor::noTeamColors == false) { + //texture 0 + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - // and make two triangles (no strip, we may be disjoint) - layer->indices.push_back(index[0]); - layer->indices.push_back(index[1]); - layer->indices.push_back(index[2]); - layer->indices.push_back(index[1]); - layer->indices.push_back(index[3]); - layer->indices.push_back(index[2]); + //set color to interpolation + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); - } - // turn them into vbos (actually this method will just calc the index count) - for(Layers::iterator layer= layers.begin(); layer!= layers.end(); ++layer){ - (*layer)->load_vbos(false); - } + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - //printf("Total # of layers for this map = %d totalCellCount = %d overall render reduction ratio = %d times\n",layers.size(),totalCellCount,(totalCellCount / layers.size())); -} + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE1); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); -void Renderer::MapRenderer::load(float coordStep) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); - int totalCellCount = 0; - // we create a layer for each texture in the map - for(int y=0; ygetSurfaceH()-1; y++) { - for(int x=0; xgetSurfaceW()-1; x++) { - totalCellCount++; + //set alpha to 1 + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); - SurfaceCell *tc[4] = { - map->getSurfaceCell(x,y), - map->getSurfaceCell(x+1,y), - map->getSurfaceCell(x,y+1), - map->getSurfaceCell(x+1,y+1) - }; - int textureHandle = static_cast(tc[0]->getSurfaceTexture())->getHandle(); - string texturePath = static_cast(tc[0]->getSurfaceTexture())->getPath(); - //int32 textureCRC = CalculatePixelsCRC(static_cast(tc[0]->getSurfaceTexture())); - Layer* layer = NULL; - for(Layers::iterator it= layers.begin(); it!= layers.end(); ++it) { - if((*it)->textureHandle == textureHandle) { - //if((*it)->texturePath == texturePath) { - //if((*it)->textureCRC == textureCRC) { - layer = *it; - break; - } - } - if(!layer) { - layer = new Layer(textureHandle); - layer->texturePath = texturePath; - //layer->textureCRC = textureCRC; - layers.push_back(layer); - - //printf("Ading new unique texture [%s]\n",texturePath.c_str()); - } - // we'll be super-lazy and re-emit all four corners just because its easier - int index[4]; - int loopIndexes[4] = { 2,0,3,1 }; - for(int i=0; i < 4; i++) { - index[i] = (int)layer->vertices.size(); - SurfaceCell *corner = tc[loopIndexes[i]]; - layer->vertices.push_back(corner->getVertex()); - layer->normals.push_back(corner->getNormal()); - } - - // the texture coords are all on the current texture obviously - layer->fowTexCoords.push_back(tc[loopIndexes[0]]->getFowTexCoord()); - layer->fowTexCoords.push_back(tc[loopIndexes[1]]->getFowTexCoord()); - layer->fowTexCoords.push_back(tc[loopIndexes[2]]->getFowTexCoord()); - layer->fowTexCoords.push_back(tc[loopIndexes[3]]->getFowTexCoord()); - - layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord()+Vec2f(0,coordStep)); - layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord()+Vec2f(0,0)); - layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord()+Vec2f(coordStep,coordStep)); - layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord()+Vec2f(coordStep,0)); - - layer->cellToIndicesMap[Vec2i(x,y)] = (int)layer->indices.size(); - - // and make two triangles (no strip, we may be disjoint) - layer->indices.push_back(index[0]); - layer->indices.push_back(index[1]); - layer->indices.push_back(index[2]); - layer->indices.push_back(index[1]); - layer->indices.push_back(index[3]); - layer->indices.push_back(index[2]); - } - } - // turn them into vbos - for(Layers::iterator layer= layers.begin(); layer!= layers.end(); ++layer){ - (*layer)->load_vbos(true); - } - - //printf("Total # of layers for this map = %d totalCellCount = %d overall render reduction ratio = %d times\n",layers.size(),totalCellCount,(totalCellCount / layers.size())); -} - -template void* _bindVBO(GLuint vbo,std::vector &buf,int target=GL_ARRAY_BUFFER_ARB) { - void* result = NULL; - if(vbo) { - glBindBuffer(target,vbo); - } - else { - result = &buf[0]; - } - return result; -} - -void Renderer::MapRenderer::Layer::renderVisibleLayer() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - //glBindTexture(GL_TEXTURE_2D, static_cast(fowTex)->getHandle()); - glClientActiveTexture(Renderer::fowTexUnit); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0,&fowTexCoords[0]); - - glBindTexture(GL_TEXTURE_2D, textureHandle); - glClientActiveTexture(Renderer::baseTexUnit); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, &surfTexCoords[0]); - - glVertexPointer(3, GL_FLOAT, 0, &vertices[0]); - glNormalPointer(GL_FLOAT, 0, &normals[0]); - - //glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size()); - //unsigned short faceIndices[4] = {0, 1, 2, 3}; - //glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, &faceIndices[0]); - glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,&indices[0]); - - glClientActiveTexture(Renderer::fowTexUnit); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTexture(Renderer::baseTexUnit); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -} - -void Renderer::MapRenderer::Layer::render(VisibleQuadContainerCache &qCache) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - -// const bool renderOnlyVisibleQuad = true; -// -// if(renderOnlyVisibleQuad == true) { - vector > rowsToRender; - - if(rowsToRenderCache.find(qCache.lastVisibleQuad) != rowsToRenderCache.end()) { - rowsToRender = rowsToRenderCache[qCache.lastVisibleQuad]; - } - else { - int startIndex = -1; - int lastValidIndex = -1; - - for(int visibleIndex = 0; - visibleIndex < (int)qCache.visibleScaledCellList.size(); ++visibleIndex) { - Vec2i &pos = qCache.visibleScaledCellList[visibleIndex]; - - if(cellToIndicesMap.find(pos) != cellToIndicesMap.end()) { - //printf("Layer Render, visibleindex = %d pos [%s] cellToIndicesMap[pos] = %d lastValidIndex = %d\n",visibleIndex,pos.getString().c_str(),cellToIndicesMap[pos],lastValidIndex); - - if(startIndex < 0 || cellToIndicesMap[pos] == lastValidIndex + 6) { - lastValidIndex = cellToIndicesMap[pos]; - if(startIndex < 0) { - startIndex = lastValidIndex; - } - } - else if(startIndex >= 0) { - rowsToRender.push_back(make_pair(startIndex,lastValidIndex)); - - lastValidIndex = cellToIndicesMap[pos]; - startIndex = lastValidIndex; - } - } - } - if(startIndex >= 0) { - rowsToRender.push_back(make_pair(startIndex,lastValidIndex)); - } - - rowsToRenderCache[qCache.lastVisibleQuad] = rowsToRender; - } - - if(rowsToRender.empty() == false) { - //printf("Layer has %d rows in visible quad, visible quad has %d cells\n",rowsToRender.size(),qCache.visibleScaledCellList.size()); - - glVertexPointer(3,GL_FLOAT,0,_bindVBO(vbo_vertices,vertices)); - glNormalPointer(GL_FLOAT,0,_bindVBO(vbo_normals,normals)); - - glClientActiveTexture(Renderer::fowTexUnit); - glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_fowTexCoords,fowTexCoords)); - - glClientActiveTexture(Renderer::baseTexUnit); - glBindTexture(GL_TEXTURE_2D,textureHandle); - glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_surfTexCoords,surfTexCoords)); - - for(unsigned int i = 0; i < rowsToRender.size(); ++i) { - //glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,_bindVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB)); - glDrawRangeElements(GL_TRIANGLES,rowsToRender[i].first,rowsToRender[i].second,indexCount,GL_UNSIGNED_INT,_bindVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB)); - } - } -// } -// else { -// glVertexPointer(3,GL_FLOAT,0,_bindVBO(vbo_vertices,vertices)); -// glNormalPointer(GL_FLOAT,0,_bindVBO(vbo_normals,normals)); -// -// glClientActiveTexture(Renderer::fowTexUnit); -// glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_fowTexCoords,fowTexCoords)); -// -// glClientActiveTexture(Renderer::baseTexUnit); -// glBindTexture(GL_TEXTURE_2D,textureHandle); -// glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_surfTexCoords,surfTexCoords)); -// -// glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,_bindVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB)); -// } -} - -void Renderer::MapRenderer::renderVisibleLayers(const Map* map,float coordStep,VisibleQuadContainerCache &qCache) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(map != this->map) { - //printf("New Map loading\n"); - destroy(); // clear any previous map data - this->map = map; - loadVisibleLayers(coordStep,qCache); - } - else if(lastVisibleQuad != qCache.lastVisibleQuad) { - //printf("New Visible Quad loading\n"); - destroy(); // clear any previous map data - this->map = map; - loadVisibleLayers(coordStep,qCache); - } - - lastVisibleQuad = qCache.lastVisibleQuad; - //printf("About to render %d layers\n",layers.size()); - - glClientActiveTexture(fowTexUnit); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTexture(baseTexUnit); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - for(Layers::iterator layer= layers.begin(); layer!= layers.end(); ++layer) - (*layer)->renderVisibleLayer(); - glDisableClientState(GL_VERTEX_ARRAY); - glBindBuffer(GL_ARRAY_BUFFER_ARB,0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0); - glDisableClientState(GL_NORMAL_ARRAY); - glClientActiveTexture(fowTexUnit); - glBindTexture(GL_TEXTURE_2D,0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTexture(baseTexUnit); - glBindTexture(GL_TEXTURE_2D,0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - assertGl(); -} - -void Renderer::MapRenderer::render(const Map* map,float coordStep,VisibleQuadContainerCache &qCache) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(map != this->map) { - destroy(); // clear any previous map data - this->map = map; - load(coordStep); - } - - //printf("About to render %d layers\n",layers.size()); - - glClientActiveTexture(fowTexUnit); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTexture(baseTexUnit); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - for(Layers::iterator layer= layers.begin(); layer!= layers.end(); ++layer) - (*layer)->render(qCache); - glDisableClientState(GL_VERTEX_ARRAY); - glBindBuffer(GL_ARRAY_BUFFER_ARB,0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB,0); - glDisableClientState(GL_NORMAL_ARRAY); - glClientActiveTexture(fowTexUnit); - glBindTexture(GL_TEXTURE_2D,0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTexture(baseTexUnit); - glBindTexture(GL_TEXTURE_2D,0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - assertGl(); -} - -void Renderer::MapRenderer::destroy() { - while(layers.empty() == false) { - delete layers.back(); - layers.pop_back(); - } - map = NULL; -} - -void Renderer::renderSurface(const int renderFps) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - IF_DEBUG_EDITION( - if (getDebugRenderer().willRenderSurface()) { - getDebugRenderer().renderSurface(visibleQuad / Map::cellScale); - } else { - ) - assertGl(); - - const World *world= game->getWorld(); - const Map *map= world->getMap(); - float coordStep= world->getTileset()->getSurfaceAtlas()->getCoordStep(); - - const Texture2D *fowTex= world->getMinimap()->getFowTexture(); - if(fowTex == NULL) { - return; - } - - glPushAttrib(GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_FOG_BIT | GL_TEXTURE_BIT); - - glEnable(GL_BLEND); - glEnable(GL_COLOR_MATERIAL); - glDisable(GL_ALPHA_TEST); - glEnable(GL_CULL_FACE); - - //fog of war tex unit - glActiveTexture(fowTexUnit); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, static_cast(fowTex)->getHandle()); - - glTexSubImage2D( - GL_TEXTURE_2D, 0, 0, 0, - fowTex->getPixmapConst()->getW(), fowTex->getPixmapConst()->getH(), - GL_ALPHA, GL_UNSIGNED_BYTE, fowTex->getPixmapConst()->getPixels()); - - if(shadowsOffDueToMinRender == false) { - //shadow texture - if(shadows == sProjected || shadows == sShadowMapping) { - glActiveTexture(shadowTexUnit); - glEnable(GL_TEXTURE_2D); - - glBindTexture(GL_TEXTURE_2D, shadowMapHandle); - - static_cast(modelRenderer)->setDuplicateTexCoords(true); - enableProjectiveTexturing(); - } - } - - const Rect2i mapBounds(0, 0, map->getSurfaceW()-1, map->getSurfaceH()-1); - - glActiveTexture(baseTexUnit); - - VisibleQuadContainerCache &qCache = getQuadCache(); - - bool useVBORendering = getVBOSupported(); - if(useVBORendering == true) { - VisibleQuadContainerCache &qCache = getQuadCache(); - //mapRenderer.render(map,coordStep,qCache); - mapRenderer.renderVisibleLayers(map,coordStep,qCache); - } - else if(qCache.visibleScaledCellList.empty() == false) { - - int lastTex=-1; - //int currTex=-1; - - //Quad2i snapshotOfvisibleQuad = visibleQuad; - - //bool useVertexArrayRendering = getVBOSupported(); - //bool useVertexArrayRendering = false; - //if(useVertexArrayRendering == false) { - //printf("\LEGACY qCache.visibleScaledCellList.size() = %d \n",qCache.visibleScaledCellList.size()); - - Vec2f texCoords[4]; - Vec2f texCoordsSurface[4]; - Vec3f vertices[4]; - Vec3f normals[4]; - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - std::map uniqueVisibleTextures; - for(int visibleIndex = 0; - visibleIndex < (int)qCache.visibleScaledCellList.size(); ++visibleIndex) { - Vec2i &pos = qCache.visibleScaledCellList[visibleIndex]; - SurfaceCell *tc00= map->getSurfaceCell(pos.x, pos.y); - int cellTex= static_cast(tc00->getSurfaceTexture())->getHandle(); - - uniqueVisibleTextures[cellTex]++; - } - - //printf("Current renders = %d possible = %d\n",qCache.visibleScaledCellList.size(),uniqueVisibleTextures.size()); - - for(int visibleIndex = 0; - visibleIndex < (int)qCache.visibleScaledCellList.size(); ++visibleIndex) { - Vec2i &pos = qCache.visibleScaledCellList[visibleIndex]; - - SurfaceCell *tc00= map->getSurfaceCell(pos.x, pos.y); - SurfaceCell *tc10= map->getSurfaceCell(pos.x+1, pos.y); - SurfaceCell *tc01= map->getSurfaceCell(pos.x, pos.y+1); - SurfaceCell *tc11= map->getSurfaceCell(pos.x+1, pos.y+1); - - if(tc00 == NULL) { - throw megaglest_runtime_error("tc00 == NULL"); - } - if(tc10 == NULL) { - throw megaglest_runtime_error("tc10 == NULL"); - } - if(tc01 == NULL) { - throw megaglest_runtime_error("tc01 == NULL"); - } - if(tc11 == NULL) { - throw megaglest_runtime_error("tc11 == NULL"); - } - - triangleCount+= 2; - pointCount+= 4; - - //set texture - if(tc00->getSurfaceTexture() == NULL) { - throw megaglest_runtime_error("tc00->getSurfaceTexture() == NULL"); - } - int currTex= static_cast(tc00->getSurfaceTexture())->getHandle(); - if(currTex != lastTex) { - lastTex = currTex; - //glBindTexture(GL_TEXTURE_2D, lastTex); - } - - const Vec2f &surfCoord= tc00->getSurfTexCoord(); - - texCoords[0] = tc01->getFowTexCoord(); - texCoordsSurface[0] = Vec2f(surfCoord.x, surfCoord.y + coordStep); - vertices[0] = tc01->getVertex(); - normals[0] = tc01->getNormal();; - - texCoords[1] = tc00->getFowTexCoord(); - texCoordsSurface[1] = Vec2f(surfCoord.x, surfCoord.y); - vertices[1] = tc00->getVertex(); - normals[1] = tc00->getNormal(); - - texCoords[2] = tc11->getFowTexCoord(); - texCoordsSurface[2] = Vec2f(surfCoord.x+coordStep, surfCoord.y+coordStep); - vertices[2] = tc11->getVertex(); - normals[2] = tc11->getNormal(); - - texCoords[3] = tc10->getFowTexCoord(); - texCoordsSurface[3] = Vec2f(surfCoord.x+coordStep, surfCoord.y); - vertices[3] = tc10->getVertex(); - normals[3] = tc10->getNormal(); - - //glBindTexture(GL_TEXTURE_2D, static_cast(fowTex)->getHandle()); - glClientActiveTexture(fowTexUnit); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0,&texCoords[0]); - - glBindTexture(GL_TEXTURE_2D, lastTex); - glClientActiveTexture(baseTexUnit); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, &texCoordsSurface[0]); - - glVertexPointer(3, GL_FLOAT, 0, &vertices[0]); - glNormalPointer(GL_FLOAT, 0, &normals[0]); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - //unsigned short faceIndices[4] = {0, 1, 2, 3}; - //glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, &faceIndices[0]); - - glClientActiveTexture(fowTexUnit); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glClientActiveTexture(baseTexUnit); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - -/* - glBegin(GL_TRIANGLE_STRIP); - - //draw quad using immediate mode - glMultiTexCoord2fv(fowTexUnit, tc01->getFowTexCoord().ptr()); - glMultiTexCoord2f(baseTexUnit, surfCoord.x, surfCoord.y + coordStep); - glNormal3fv(tc01->getNormal().ptr()); - glVertex3fv(tc01->getVertex().ptr()); - - glMultiTexCoord2fv(fowTexUnit, tc00->getFowTexCoord().ptr()); - glMultiTexCoord2f(baseTexUnit, surfCoord.x, surfCoord.y); - glNormal3fv(tc00->getNormal().ptr()); - glVertex3fv(tc00->getVertex().ptr()); - - glMultiTexCoord2fv(fowTexUnit, tc11->getFowTexCoord().ptr()); - glMultiTexCoord2f(baseTexUnit, surfCoord.x+coordStep, surfCoord.y+coordStep); - glNormal3fv(tc11->getNormal().ptr()); - glVertex3fv(tc11->getVertex().ptr()); - - glMultiTexCoord2fv(fowTexUnit, tc10->getFowTexCoord().ptr()); - glMultiTexCoord2f(baseTexUnit, surfCoord.x + coordStep, surfCoord.y); - glNormal3fv(tc10->getNormal().ptr()); - glVertex3fv(tc10->getVertex().ptr()); - - glEnd(); -*/ - } - - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - -// } -// else { -// const bool useVBOs = false; -// const bool useSurfaceCache = false; -// -// std::vector surfaceData; -// bool recalcSurface = false; -// -// if(useSurfaceCache == true) { -// std::map > >::iterator iterFind = mapSurfaceData.find(snapshotOfvisibleQuad.getString()); -// if(iterFind == mapSurfaceData.end()) { -// recalcSurface = true; -// //printf("#1 Calculating surface for Rendering using VA's [%s]\n",snapshotOfvisibleQuad.getString().c_str()); -// } -///* -// else if(iterFind->second.first.getMillis() >= 250) { -// recalcSurface = true; -// mapSurfaceData.erase(snapshotOfvisibleQuad.getString()); -// //printf("#2 RE-Calculating surface for Rendering using VA's [%s]\n",snapshotOfvisibleQuad.getString().c_str()); -// } -//*/ -// } -// else { -// recalcSurface = true; -// } -// -// if(recalcSurface == true) { -// //printf("Calculating surface for Rendering using VA's [%s]\n",snapshotOfvisibleQuad.getString().c_str()); -// -// std::vector *surface = &surfaceData; -// if(useSurfaceCache == true) { -// std::pair > &surfaceCacheEntity = mapSurfaceData[snapshotOfvisibleQuad.getString()]; -// surface = &surfaceCacheEntity.second; -// //surface.reserve(qCache.visibleScaledCellList.size()); -// } -// surface->reserve(qCache.visibleScaledCellList.size()); -// -// int lastSurfaceDataIndex = -1; -// for(int visibleIndex = 0; -// visibleIndex < (int)qCache.visibleScaledCellList.size(); ++visibleIndex) { -// Vec2i &pos = qCache.visibleScaledCellList[visibleIndex]; -// -// SurfaceCell *tc00= map->getSurfaceCell(pos.x, pos.y); -// SurfaceCell *tc10= map->getSurfaceCell(pos.x+1, pos.y); -// SurfaceCell *tc01= map->getSurfaceCell(pos.x, pos.y+1); -// SurfaceCell *tc11= map->getSurfaceCell(pos.x+1, pos.y+1); -// -// if(tc00 == NULL) { -// throw megaglest_runtime_error("tc00 == NULL"); -// } -// if(tc10 == NULL) { -// throw megaglest_runtime_error("tc10 == NULL"); -// } -// if(tc01 == NULL) { -// throw megaglest_runtime_error("tc01 == NULL"); -// } -// if(tc11 == NULL) { -// throw megaglest_runtime_error("tc11 == NULL"); -// } -// -// triangleCount+= 2; -// pointCount+= 4; -// -// //set texture -// if(tc00->getSurfaceTexture() == NULL) { -// throw megaglest_runtime_error("tc00->getSurfaceTexture() == NULL"); -// } -// -// int surfaceDataIndex = -1; -// currTex= static_cast(tc00->getSurfaceTexture())->getHandle(); -// if(currTex != lastTex) { -// lastTex = currTex; -// } -// else { -// surfaceDataIndex = lastSurfaceDataIndex; -// } -// -// if(surfaceDataIndex < 0) { -// SurfaceData newData; -// newData.uniqueId = SurfaceData::nextUniqueId; -// SurfaceData::nextUniqueId++; -// newData.bufferCount=0; -// newData.textureHandle = currTex; -// surface->push_back(newData); -// -// surfaceDataIndex = (int)surface->size() - 1; -// } -// -// lastSurfaceDataIndex = surfaceDataIndex; -// -// SurfaceData *cellData = &(*surface)[surfaceDataIndex]; -// -// const Vec2f &surfCoord= tc00->getSurfTexCoord(); -// -// cellData->texCoords.push_back(tc01->getFowTexCoord()); -// cellData->texCoordsSurface.push_back(Vec2f(surfCoord.x, surfCoord.y + coordStep)); -// cellData->vertices.push_back(tc01->getVertex()); -// cellData->normals.push_back(tc01->getNormal()); -// cellData->bufferCount++; -// -// cellData->texCoords.push_back(tc00->getFowTexCoord()); -// cellData->texCoordsSurface.push_back(Vec2f(surfCoord.x, surfCoord.y)); -// cellData->vertices.push_back(tc00->getVertex()); -// cellData->normals.push_back(tc00->getNormal()); -// cellData->bufferCount++; -// -// cellData->texCoords.push_back(tc11->getFowTexCoord()); -// cellData->texCoordsSurface.push_back(Vec2f(surfCoord.x+coordStep, surfCoord.y+coordStep)); -// cellData->vertices.push_back(tc11->getVertex()); -// cellData->normals.push_back(tc11->getNormal()); -// cellData->bufferCount++; -// -// cellData->texCoords.push_back(tc10->getFowTexCoord()); -// cellData->texCoordsSurface.push_back(Vec2f(surfCoord.x+coordStep, surfCoord.y)); -// cellData->vertices.push_back(tc10->getVertex()); -// cellData->normals.push_back(tc10->getNormal()); -// cellData->bufferCount++; -// } -// } -// -// std::vector *surface = &surfaceData; -// if(useSurfaceCache == true) { -// std::pair > &surfaceCacheEntity = mapSurfaceData[snapshotOfvisibleQuad.getString()]; -// surface = &surfaceCacheEntity.second; -// } -// -// glEnableClientState(GL_VERTEX_ARRAY); -// glEnableClientState(GL_NORMAL_ARRAY); -// -// for(int i = 0; i < (int)surface->size(); ++i) { -// SurfaceData &data = (*surface)[i]; -// -// if(useVBOs == true) { -// VisibleQuadContainerVBOCache *vboCache = GetSurfaceVBOs(&data); -// -// //glBindTexture(GL_TEXTURE_2D, static_cast(fowTex)->getHandle()); -// glClientActiveTexture(fowTexUnit); -// glEnableClientState(GL_TEXTURE_COORD_ARRAY); -// -// glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache->m_nVBOFowTexCoords); -// glTexCoordPointer(2, GL_FLOAT, 0,(char *) NULL); -// -// glBindTexture(GL_TEXTURE_2D, data.textureHandle); -// glClientActiveTexture(baseTexUnit); -// glEnableClientState(GL_TEXTURE_COORD_ARRAY); -// -// glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache->m_nVBOSurfaceTexCoords); -// glTexCoordPointer(2, GL_FLOAT, 0, (char *) NULL); -// -// glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache->m_nVBOVertices); -// glVertexPointer(3, GL_FLOAT, 0, (char *) NULL); -// -// glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache->m_nVBONormals); -// glNormalPointer(GL_FLOAT, 0, (char *) NULL); -// -// glDrawArrays(GL_TRIANGLE_STRIP, 0, data.bufferCount); -// -// glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); -// -// glClientActiveTexture(fowTexUnit); -// glDisableClientState(GL_TEXTURE_COORD_ARRAY); -// glClientActiveTexture(baseTexUnit); -// glDisableClientState(GL_TEXTURE_COORD_ARRAY); -// -// } -// else { -// Vec2f *texCoords = &data.texCoords[0]; -// Vec2f *texCoordsSurface = &data.texCoordsSurface[0]; -// Vec3f *vertices = &data.vertices[0]; -// Vec3f *normals = &data.normals[0]; -// -// //glBindTexture(GL_TEXTURE_2D, static_cast(fowTex)->getHandle()); -// glClientActiveTexture(fowTexUnit); -// glEnableClientState(GL_TEXTURE_COORD_ARRAY); -// glTexCoordPointer(2, GL_FLOAT, 0,texCoords); -// -// glBindTexture(GL_TEXTURE_2D, data.textureHandle); -// glClientActiveTexture(baseTexUnit); -// glEnableClientState(GL_TEXTURE_COORD_ARRAY); -// glTexCoordPointer(2, GL_FLOAT, 0, texCoordsSurface); -// -// glVertexPointer(3, GL_FLOAT, 0, vertices); -// glNormalPointer(GL_FLOAT, 0, normals); -// -// glDrawArrays(GL_TRIANGLE_STRIP, 0, data.bufferCount); -// -// glClientActiveTexture(fowTexUnit); -// glDisableClientState(GL_TEXTURE_COORD_ARRAY); -// glClientActiveTexture(baseTexUnit); -// glDisableClientState(GL_TEXTURE_COORD_ARRAY); -// } -// } -// -// glDisableClientState(GL_NORMAL_ARRAY); -// glDisableClientState(GL_VERTEX_ARRAY); -// -// //printf("Surface Render before [%d] after [%d]\n",qCache.visibleScaledCellList.size(),surface.size()); -// } - } - - //Restore - static_cast(modelRenderer)->setDuplicateTexCoords(false); - - glDisable(GL_TEXTURE_2D); - - glPopAttrib(); - - //assert - GLenum glresult = glGetError(); //remove when first mtex problem solved - if(glresult) { - assertGl(); - } - assertGl(); - - IF_DEBUG_EDITION( - } // end else, if not renderering debug textures instead of regular terrain - getDebugRenderer().renderEffects(visibleQuad / Map::cellScale); - ) -} - -void Renderer::renderObjects(const int renderFps) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - const World *world= game->getWorld(); - //const Map *map= world->getMap(); - - Config &config= Config::getInstance(); - int tilesetObjectsToAnimate=config.getInt("AnimatedTilesetObjects","-1"); - - assertGl(); - - const Texture2D *fowTex = world->getMinimap()->getFowTexture(); - const Pixmap2D *fowTexPixmap = fowTex->getPixmapConst(); - Vec3f baseFogColor = world->getTileset()->getFogColor() * world->getTimeFlow()->computeLightColor(); - - bool modelRenderStarted = false; - - VisibleQuadContainerCache &qCache = getQuadCache(); - - // for(int visibleIndex = 0; - // visibleIndex < qCache.visibleObjectList.size(); ++visibleIndex) { - // render from last to first object so animated objects which are on bottom of screen are - // rendered first which looks better for limited number of animated tileset objects - for(int visibleIndex = (int)qCache.visibleObjectList.size()-1; - visibleIndex >= 0 ; --visibleIndex) { - Object *o = qCache.visibleObjectList[visibleIndex]; - - Model *objModel= o->getModelPtr(); - //objModel->updateInterpolationData(o->getAnimProgress(), true); - const Vec3f v= o->getConstPos(); - - if(modelRenderStarted == false) { - modelRenderStarted = true; - - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_FOG_BIT | GL_LIGHTING_BIT | GL_TEXTURE_BIT); - - if(shadowsOffDueToMinRender == false && - shadows == sShadowMapping) { - glActiveTexture(shadowTexUnit); + //texture 1 + glActiveTexture(GL_TEXTURE1); + glMultiTexCoord2f(GL_TEXTURE1, 0.f, 0.f); glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, static_cast(teamTexture)->getHandle()); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); + + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); + + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); + + //set alpha to 1 + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); + + glActiveTexture(GL_TEXTURE0); + } else { + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + } + + // =========================================================== + // class Renderer + // =========================================================== + + // ===================== PUBLIC ======================== + + const int Renderer::maxProgressBar = 100; + const Vec4f Renderer::progressBarBack1 = Vec4f(0.7f, 0.7f, 0.7f, 0.7f); + const Vec4f Renderer::progressBarBack2 = Vec4f(0.7f, 0.7f, 0.7f, 1.f); + const Vec4f Renderer::progressBarFront1 = Vec4f(0.f, 0.5f, 0.f, 1.f); + const Vec4f Renderer::progressBarFront2 = Vec4f(0.f, 0.1f, 0.f, 1.f); + + const float Renderer::sunDist = 10e6; + const float Renderer::moonDist = 10e6; + const float Renderer::lightAmbFactor = 0.4f; + + const int Renderer::maxMouse2dAnim = 100; + + const GLenum Renderer::baseTexUnit = GL_TEXTURE0; + const GLenum Renderer::fowTexUnit = GL_TEXTURE1; + const GLenum Renderer::shadowTexUnit = GL_TEXTURE2; + + const float Renderer::selectionCircleRadius = 0.7f; + const float Renderer::magicCircleRadius = 1.f; + + //perspective values + const float Renderer::perspFov = 60.f; + const float Renderer::perspNearPlane = 1.f; + //const float Renderer::perspFarPlane= 50.f; + float Renderer::perspFarPlane = 1000000.f; + + const float Renderer::ambFactor = 0.7f; + const Vec4f Renderer::fowColor = Vec4f(0.0f, 0.0f, 0.0f, 1.0f); + const Vec4f Renderer::defSpecularColor = Vec4f(0.8f, 0.8f, 0.8f, 1.f); + const Vec4f Renderer::defDiffuseColor = Vec4f(1.f, 1.f, 1.f, 1.f); + const Vec4f Renderer::defAmbientColor = Vec4f(1.f * ambFactor, 1.f * ambFactor, 1.f * ambFactor, 1.f); + const Vec4f Renderer::defColor = Vec4f(1.f, 1.f, 1.f, 1.f); + + //const float Renderer::maxLightDist= 100.f; + const float Renderer::maxLightDist = 100.f; + + bool Renderer::rendererEnded = true; + + const int MIN_FPS_NORMAL_RENDERING = 15; + const int MIN_FPS_NORMAL_RENDERING_TOP_THRESHOLD = 25; + + const int OBJECT_SELECT_OFFSET = 100000000; + + bool VisibleQuadContainerCache::enableFrustumCalcs = true; + + // ==================== constructor and destructor ==================== + + Renderer::Renderer() : BaseRenderer(), saveScreenShotThreadAccessor(new Mutex(CODE_AT_LINE)) { + //this->masterserverMode = masterserverMode; + //printf("this->masterserverMode = %d\n",this->masterserverMode); + //assert(0==1); + + Renderer::rendererEnded = false; + shadowIntensity = 0; + shadowFrameSkip = 0; + triangleCount = 0; + smoothedRenderFps = 0; + shadowTextureSize = 0; + shadows = sDisabled; + shadowMapFrame = 0; + textures3D = false; + photoMode = false; + focusArrows = false; + pointCount = 0; + maxLights = 0; + waterAnim = 0; + + this->allowRenderUnitTitles = false; + this->menu = NULL; + this->game = NULL; + this->gameCamera = NULL; + showDebugUI = false; + showDebugUILevel = debugui_fps; + modelRenderer = NULL; + textRenderer = NULL; + textRenderer3D = NULL; + particleRenderer = NULL; + saveScreenShotThread = NULL; + mapSurfaceData.clear(); + visibleFrameUnitList.clear(); + visibleFrameUnitListCameraKey = ""; + + quadCache = VisibleQuadContainerCache(); + quadCache.clearFrustumData(); + + lastRenderFps = MIN_FPS_NORMAL_RENDERING; + shadowsOffDueToMinRender = false; + shadowMapHandle = 0; + shadowMapHandleValid = false; + + //list3d=0; + //list3dValid=false; + //list2d=0; + //list2dValid=false; + //list3dMenu=0; + //list3dMenuValid=false; + //customlist3dMenu=NULL; + //this->mm3d = NULL; + this->custom_mm3d = NULL; + + this->program = NULL; + + //resources + for (int i = 0; i < rsCount; ++i) { + modelManager[i] = NULL; + textureManager[i] = NULL; + particleManager[i] = NULL; + fontManager[i] = NULL; + } + + Config &config = Config::getInstance(); + + Renderer::perspFarPlane = config.getFloat("PerspectiveFarPlane", floatToStr(Renderer::perspFarPlane).c_str()); + this->no2DMouseRendering = config.getBool("No2DMouseRendering", "false"); + this->maxConsoleLines = config.getInt("ConsoleMaxLines"); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Renderer::perspFarPlane [%f] this->no2DMouseRendering [%d] this->maxConsoleLines [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, Renderer::perspFarPlane, this->no2DMouseRendering, this->maxConsoleLines); + + GraphicsInterface &gi = GraphicsInterface::getInstance(); + FactoryRepository &fr = FactoryRepository::getInstance(); + gi.setFactory(fr.getGraphicsFactory(config.getString("FactoryGraphics"))); + GraphicsFactory *graphicsFactory = GraphicsInterface::getInstance().getFactory(); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + modelRenderer = graphicsFactory->newModelRenderer(); + textRenderer = graphicsFactory->newTextRenderer2D(); + textRenderer3D = graphicsFactory->newTextRenderer3D(); + particleRenderer = graphicsFactory->newParticleRenderer(); + } + + //resources + for (int i = 0; i < rsCount; ++i) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + modelManager[i] = graphicsFactory->newModelManager(); + textureManager[i] = graphicsFactory->newTextureManager(); + modelManager[i]->setTextureManager(textureManager[i]); + fontManager[i] = graphicsFactory->newFontManager(); + } + particleManager[i] = graphicsFactory->newParticleManager(); + } + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); + saveScreenShotThread = new SimpleTaskThread(this, 0, 25); + saveScreenShotThread->setUniqueID(mutexOwnerId); + saveScreenShotThread->start(); + } + } + + void Renderer::cleanupScreenshotThread() { + if (saveScreenShotThread) { + saveScreenShotThread->signalQuit(); + // for(time_t elapsed = time(NULL); + // getSaveScreenQueueSize() > 0 && difftime((long int)time(NULL),elapsed) <= 7;) { + // sleep(0); + // } + // if(saveScreenShotThread->canShutdown(true) == true && + // saveScreenShotThread->shutdownAndWait() == true) { + // //printf("IN MenuStateCustomGame cleanup - C\n"); + // delete saveScreenShotThread; + // } + // saveScreenShotThread = NULL; + if (saveScreenShotThread->shutdownAndWait() == true) { + delete saveScreenShotThread; + } + saveScreenShotThread = NULL; + + + if (getSaveScreenQueueSize() > 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d] FORCING MEMORY CLEANUP and NOT SAVING screenshots, saveScreenQueue.size() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, saveScreenQueue.size()); + + static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(saveScreenShotThreadAccessor, mutexOwnerId); + for (std::list >::iterator iter = saveScreenQueue.begin(); + iter != saveScreenQueue.end(); ++iter) { + delete iter->second; + } + saveScreenQueue.clear(); + } + } + } + + Renderer::~Renderer() { + try { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + delete modelRenderer; + modelRenderer = NULL; + delete textRenderer; + textRenderer = NULL; + delete textRenderer3D; + textRenderer3D = NULL; + delete particleRenderer; + particleRenderer = NULL; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + //resources + for (int i = 0; i < rsCount; ++i) { + delete modelManager[i]; + modelManager[i] = NULL; + delete textureManager[i]; + textureManager[i] = NULL; + delete particleManager[i]; + particleManager[i] = NULL; + delete fontManager[i]; + fontManager[i] = NULL; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + // Wait for the queue to become empty or timeout the thread at 7 seconds + cleanupScreenshotThread(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + mapSurfaceData.clear(); + quadCache = VisibleQuadContainerCache(); + quadCache.clearFrustumData(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + this->menu = NULL; + this->game = NULL; + this->gameCamera = NULL; + + delete saveScreenShotThreadAccessor; + saveScreenShotThreadAccessor = NULL; + } catch (const exception &e) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d]\nError [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + throw megaglest_runtime_error(szBuf); + } + } + + void Renderer::simpleTask(BaseThread *callingThread, void *userdata) { + // This code reads pixmaps from a queue and saves them to disk + Pixmap2D *savePixMapBuffer = NULL; + string path = ""; + static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(saveScreenShotThreadAccessor, mutexOwnerId); + if (saveScreenQueue.empty() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d] saveScreenQueue.size() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, saveScreenQueue.size()); + + savePixMapBuffer = saveScreenQueue.front().second; + path = saveScreenQueue.front().first; + + saveScreenQueue.pop_front(); + } + safeMutex.ReleaseLock(); + + if (savePixMapBuffer != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d] about to save [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, path.c_str()); + + savePixMapBuffer->save(path); + delete savePixMapBuffer; + } + } + + bool Renderer::isEnded() { + return Renderer::rendererEnded; + } + + Renderer &Renderer::getInstance() { + static Renderer renderer; + return renderer; + } + + void Renderer::reinitAll() { + //resources + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + for (int i = 0; i < rsCount; ++i) { + //modelManager[i]->init(); + textureManager[i]->init(true); + //particleManager[i]->init(); + //fontManager[i]->init(); + } + } + // ==================== init ==================== + + void Renderer::init() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + Config &config = Config::getInstance(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + loadConfig(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (config.getBool("CheckGlCaps")) { + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + checkGlCaps(); + } + + if (glActiveTexture == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error: glActiveTexture == NULL\nglActiveTexture is only supported if the GL version is 1.3 or greater,\nor if the ARB_multitexture extension is supported!"); + throw megaglest_runtime_error(szBuf); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (config.getBool("FirstTime")) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + config.setBool("FirstTime", false); + autoConfig(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + config.save(); + } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + modelManager[rsGlobal]->init(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + textureManager[rsGlobal]->init(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + fontManager[rsGlobal]->init(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + init2dList(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + glHint(GL_FOG_HINT, GL_FASTEST); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + //glHint(GL_GENERATE_MIPMAP_HINT, GL_FASTEST); + glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); + //glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST); + + //glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST); + glHint(GL_TEXTURE_COMPRESSION_HINT, GL_FASTEST); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + } + + void Renderer::initGame(const Game *game, GameCamera *gameCamera) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + this->gameCamera = gameCamera; + VisibleQuadContainerCache::enableFrustumCalcs = Config::getInstance().getBool("EnableFrustrumCalcs", "true"); + quadCache = VisibleQuadContainerCache(); + quadCache.clearFrustumData(); + + SurfaceData::nextUniqueId = 1; + mapSurfaceData.clear(); + this->game = game; + worldToScreenPosCache.clear(); + + //vars + shadowMapFrame = 0; + waterAnim = 0; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + //check gl caps + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + checkGlOptionalCaps(); + + //shadows + if (shadows == sProjected || shadows == sShadowMapping) { + static_cast(modelRenderer)->setSecondaryTexCoordUnit(2); + Config &config = Config::getInstance(); + + glGenTextures(1, &shadowMapHandle); + shadowMapHandleValid = true; + + shadowIntensity = config.getFloat("ShadowIntensity", "1.0"); + if (game != NULL) { + shadowIntensity = shadowIntensity * game->getWorld()->getTileset()->getShadowIntense(); + if (shadowIntensity > 1.0f) { + shadowIntensity = 1.0f; + } + } + glBindTexture(GL_TEXTURE_2D, shadowMapHandle); - static_cast(modelRenderer)->setDuplicateTexCoords(true); - enableProjectiveTexturing(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + if (shadows == sShadowMapping) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + //shadow mapping + glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 1.0f-shadowAlpha); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, + shadowTextureSize, shadowTextureSize, + 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + //projected + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, + shadowTextureSize, shadowTextureSize, + 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); + } + + shadowMapFrame = -1; } - glActiveTexture(baseTexUnit); - glEnable(GL_COLOR_MATERIAL); - glAlphaFunc(GL_GREATER, 0.5f); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - modelRenderer->begin(true, true, false, false); - } - //ambient and diffuse color is taken from cell color + IF_DEBUG_EDITION(getDebugRenderer().init(); ) - float fowFactor= fowTexPixmap->getPixelf(o->getMapPos().x / Map::cellScale, o->getMapPos().y / Map::cellScale); - Vec4f color= Vec4f(Vec3f(fowFactor), 1.f); - glColor4fv(color.ptr()); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (color * ambFactor).ptr()); - glFogfv(GL_FOG_COLOR, (baseFogColor * fowFactor).ptr()); + //texture init + modelManager[rsGame]->init(); + textureManager[rsGame]->init(); + fontManager[rsGame]->init(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glTranslatef(v.x, v.y, v.z); - glRotatef(o->getRotation(), 0.f, 1.f, 0.f); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - //We use OpenGL Lights so no manual action is needed here. In fact this call did bad things on lighting big rocks for example - // if(o->getRotation() != 0.0) { - // setupLightingForRotatedModel(); - // } - - //objModel->updateInterpolationData(0.f, true); - //if(this->gameCamera->getPos().dist(o->getPos()) <= SKIP_INTERPOLATION_DISTANCE) { - - - if (tilesetObjectsToAnimate == -1) { - objModel->updateInterpolationData(o->getAnimProgress(), true); - } else if (tilesetObjectsToAnimate > 0 && o->isAnimated()) { - tilesetObjectsToAnimate--; - objModel->updateInterpolationData(o->getAnimProgress(), true); - } else { - objModel->updateInterpolationData(0, true); + init3dList(); } -// objModel->updateInterpolationData(o->getAnimProgress(), true); + void Renderer::manageDeferredParticleSystems() { + + // if(deferredParticleSystems.empty() == false) { + // printf("deferredParticleSystems.size() = %d\n",(int)deferredParticleSystems.size()); + // } + + for (unsigned int i = 0; i < deferredParticleSystems.size(); ++i) { + std::pair &deferredParticleSystem = deferredParticleSystems[i]; + ParticleSystem *ps = deferredParticleSystem.first; + ResourceScope rs = deferredParticleSystem.second; + if (ps->getTextureFileLoadDeferred() != "" && ps->getTexture() == NULL) { + CoreData::TextureSystemType textureSystemId = + static_cast( + ps->getTextureFileLoadDeferredSystemId()); + + //printf("Load DEFERRED particle i = %d textureSystemId = %d\n",i,textureSystemId); + + if (textureSystemId != CoreData::tsyst_NONE) { + Texture2D *texture = CoreData::getInstance().getTextureBySystemId(textureSystemId); + //printf("Loading texture from system [%d] [%p]\n",textureSystemId,texture); + ps->setTexture(texture); + + //printf("#2 Load DEFERRED particle i = %d textureSystemId = %d, texture = %p\n",i,textureSystemId,texture); + } else { + Texture2D *texture = newTexture2D(rs); + if (texture) { + texture->setFormat(ps->getTextureFileLoadDeferredFormat()); + texture->getPixmap()->init(ps->getTextureFileLoadDeferredComponents()); + } + if (texture) { + string textureFile = ps->getTextureFileLoadDeferred(); + if (fileExists(textureFile) == false) { + textureFile = Config::findValidLocalFileFromPath(textureFile); + } + texture->load(textureFile); + ps->setTexture(texture); + } + //printf("#3 Load DEFERRED particle i = %d textureSystemId = %d, texture = %p\n",i,textureSystemId,texture); + } + } + if (dynamic_cast(ps) != NULL) { + GameParticleSystem *gps = dynamic_cast(ps); + if (gps != NULL && gps->getModelFileLoadDeferred() != "" && gps->getModel() == NULL) { + std::map > > loadedFileList; + Model *model = newModel(rsGame, gps->getModelFileLoadDeferred(), false, &loadedFileList, NULL); + if (model) + gps->setModel(model); + } + } + manageParticleSystem(ps, rs); + //printf("Managing ps [%p]\n",ps); + } + deferredParticleSystems.clear(); + //printf("After deferredParticleSystems.size() = %d\n",deferredParticleSystems.size()); + } + + void Renderer::initMenu(const MainMenu *mm) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + this->menu = mm; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + modelManager[rsMenu]->init(); + textureManager[rsMenu]->init(); + fontManager[rsMenu]->init(); + //modelRenderer->setCustomTexture(CoreData::getInstance().getCustomTexture()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + //init3dListMenu(mm); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void Renderer::reset3d() { + assertGl(); + glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); + //glCallList(list3d); + render3dSetup(); + + pointCount = 0; + triangleCount = 0; + assertGl(); + } + + void Renderer::reset2d() { + assertGl(); + glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR); + //glCallList(list2d); + render2dMenuSetup(); + assertGl(); + } + + void Renderer::reset3dMenu() { + assertGl(); + glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR); + + //printf("In [%s::%s Line: %d] this->custom_mm3d [%p] this->mm3d [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->custom_mm3d,this->mm3d); + + if (this->custom_mm3d != NULL) { + render3dMenuSetup(this->custom_mm3d); + //glCallList(*this->customlist3dMenu); + } else { + render3dMenuSetup(this->menu); + //render3dMenuSetup(this->mm3d); + //glCallList(list3dMenu); + } + + assertGl(); + } + + // ==================== end ==================== + + void Renderer::end() { + quadCache = VisibleQuadContainerCache(); + quadCache.clearFrustumData(); + + if (Renderer::rendererEnded == true) { + return; + } + std::map &crcFactionPreviewTextureCache = CacheManager::getCachedItem< std::map >(GameConstants::factionPreviewTextureCacheLookupKey); + crcFactionPreviewTextureCache.clear(); + + // Wait for the queue to become empty or timeout the thread at 7 seconds + cleanupScreenshotThread(); + + mapSurfaceData.clear(); + + //delete resources + if (modelManager[rsGlobal]) { + modelManager[rsGlobal]->end(); + } + if (textureManager[rsGlobal]) { + textureManager[rsGlobal]->end(); + } + if (fontManager[rsGlobal]) { + fontManager[rsGlobal]->end(); + } + if (particleManager[rsGlobal]) { + particleManager[rsGlobal]->end(); + } + + //delete 2d list + //if(list2dValid == true) { + // glDeleteLists(list2d, 1); + // list2dValid=false; + //} + + Renderer::rendererEnded = true; + } + + void Renderer::endScenario() { + this->game = NULL; + this->gameCamera = NULL; + quadCache = VisibleQuadContainerCache(); + quadCache.clearFrustumData(); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + //delete resources + //modelManager[rsGame]->end(); + //textureManager[rsGame]->end(); + //fontManager[rsGame]->end(); + //particleManager[rsGame]->end(); + + if (shadowMapHandleValid == true && + (shadows == sProjected || shadows == sShadowMapping)) { + glDeleteTextures(1, &shadowMapHandle); + shadowMapHandleValid = false; + } + + //if(list3dValid == true) { + // glDeleteLists(list3d, 1); + // list3dValid=false; + //} + + worldToScreenPosCache.clear(); + ReleaseSurfaceVBOs(); + mapSurfaceData.clear(); + } + + void Renderer::endGame(bool isFinalEnd) { + this->game = NULL; + this->gameCamera = NULL; + Config &config = Config::getInstance(); + + try { + quadCache = VisibleQuadContainerCache(); + quadCache.clearFrustumData(); + } catch (const exception &e) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d]\nError [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + abort(); + } + + if (isFinalEnd) { + //delete resources + if (modelManager[rsGame] != NULL) { + modelManager[rsGame]->end(); + } + if (textureManager[rsGame] != NULL) { + textureManager[rsGame]->end(); + } + if (fontManager[rsGame] != NULL) { + fontManager[rsGame]->end(); + } + if (particleManager[rsGame] != NULL) { + particleManager[rsGame]->end(); + } + } + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (shadowMapHandleValid == true && + (shadows == sProjected || shadows == sShadowMapping)) { + glDeleteTextures(1, &shadowMapHandle); + shadowMapHandleValid = false; + } + shadowIntensity = config.getFloat("ShadowIntensity", "1.0"); + + //if(list3dValid == true) { + // glDeleteLists(list3d, 1); + // list3dValid=false; + //} + + worldToScreenPosCache.clear(); + ReleaseSurfaceVBOs(); + mapSurfaceData.clear(); + } + + void Renderer::endMenu() { + this->menu = NULL; + + //delete resources + if (modelManager[rsMenu]) { + modelManager[rsMenu]->end(); + } + if (textureManager[rsMenu]) { + textureManager[rsMenu]->end(); + } + if (fontManager[rsMenu]) { + fontManager[rsMenu]->end(); + } + if (particleManager[rsMenu]) { + particleManager[rsMenu]->end(); + } + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + //if(this->customlist3dMenu != NULL) { + // glDeleteLists(*this->customlist3dMenu,1); + //} + //else { + // glDeleteLists(list3dMenu, 1); + //} + } + + //void Renderer::reloadResources() { + // if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + // return; + // } + // + // for(int i=0; iend(); + // textureManager[i]->end(); + // fontManager[i]->end(); + // } + // + // for(int i=0; iinit(); + // textureManager[i]->init(); + // fontManager[i]->init(); + // } //} - modelRenderer->render(objModel); - triangleCount+= objModel->getTriangleCount(); - pointCount+= objModel->getVertexCount(); + // ==================== engine interface ==================== - glPopMatrix(); - } + void Renderer::initTexture(ResourceScope rs, Texture *texture) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } - if(modelRenderStarted == true) { - modelRenderer->end(); - glPopAttrib(); - } - - //restore - static_cast(modelRenderer)->setDuplicateTexCoords(true); - - assertGl(); -} - -void Renderer::renderWater() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - const World *world= game->getWorld(); - const Map *map= world->getMap(); - - const Texture2D *fowTex= world->getMinimap()->getFowTexture(); - if(fowTex == NULL) { - return; - } - - float waterAnim= world->getWaterEffects()->getAmin(); - - //assert - assertGl(); - - glPushAttrib(GL_TEXTURE_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT); - - //water texture nit - glDisable(GL_TEXTURE_2D); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - if(textures3D) { - Texture3D *waterTex= world->getTileset()->getWaterTex(); - if(waterTex == NULL) { - throw megaglest_runtime_error("waterTex == NULL"); + textureManager[rs]->initTexture(texture); } - glEnable(GL_TEXTURE_3D); - glBindTexture(GL_TEXTURE_3D, static_cast(waterTex)->getHandle()); - } - else{ - glEnable(GL_COLOR_MATERIAL); - glColor4f(0.5f, 0.5f, 1.0f, 0.5f); - glBindTexture(GL_TEXTURE_3D, 0); - } - assertGl(); + void Renderer::endTexture(ResourceScope rs, Texture *texture, bool mustExistInList) { + string textureFilename = texture->getPath(); - //fog of War texture Unit - //const Texture2D *fowTex= world->getMinimap()->getFowTexture(); - glActiveTexture(fowTexUnit); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, static_cast(fowTex)->getHandle()); - glActiveTexture(baseTexUnit); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] free texture from manager [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, textureFilename.c_str()); - assertGl(); - - int thisTeamIndex= world->getThisTeamIndex(); - bool cellExplored = world->showWorldForPlayer(world->getThisFactionIndex()); - bool closed= false; - - Rect2i boundingRect= visibleQuad.computeBoundingRect(); - Rect2i scaledRect= boundingRect/Map::cellScale; - scaledRect.clamp(0, 0, map->getSurfaceW()-1, map->getSurfaceH()-1); - - float waterLevel= world->getMap()->getWaterLevel(); - for(int j=scaledRect.p[0].y; jgetSurfaceCell(i, j); - SurfaceCell *tc1= map->getSurfaceCell(i, j+1); - if(tc0 == NULL) { - throw megaglest_runtime_error("tc0 == NULL"); - } - if(tc1 == NULL) { - throw megaglest_runtime_error("tc1 == NULL"); + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; } - if(cellExplored == false) { - cellExplored = (tc0->isExplored(thisTeamIndex) || tc1->isExplored(thisTeamIndex)); - } + textureManager[rs]->endTexture(texture, mustExistInList); - if(cellExplored == true && tc0->getNearSubmerged()) { - glNormal3f(0.f, 1.f, 0.f); - closed= false; + if (rs == rsGlobal) { + std::map &crcFactionPreviewTextureCache = CacheManager::getCachedItem< std::map >(GameConstants::factionPreviewTextureCacheLookupKey); + if (crcFactionPreviewTextureCache.find(textureFilename) != crcFactionPreviewTextureCache.end()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] textureFilename [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, textureFilename.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] free texture from cache [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, textureFilename.c_str()); - triangleCount+= 2; - pointCount+= 2; + crcFactionPreviewTextureCache.erase(textureFilename); + } + } + } + void Renderer::endLastTexture(ResourceScope rs, bool mustExistInList) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } - //vertex 1 - glMaterialfv( - GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, - computeWaterColor(waterLevel, tc1->getHeight()).ptr()); - glMultiTexCoord2fv(GL_TEXTURE1, tc1->getFowTexCoord().ptr()); - glTexCoord3f(i, 1.f, waterAnim); - glVertex3f( - static_cast(i)*Map::mapScale, - waterLevel, - static_cast(j+1)*Map::mapScale); + textureManager[rs]->endLastTexture(mustExistInList); + } - //vertex 2 - glMaterialfv( - GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, - computeWaterColor(waterLevel, tc0->getHeight()).ptr()); - glMultiTexCoord2fv(GL_TEXTURE1, tc0->getFowTexCoord().ptr()); - glTexCoord3f(i, 0.f, waterAnim); - glVertex3f( - static_cast(i)*Map::mapScale, - waterLevel, - static_cast(j)*Map::mapScale); + Model *Renderer::newModel(ResourceScope rs, const string &path, bool deletePixMapAfterLoad, std::map > > *loadedFileList, string *sourceLoader) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return NULL; + } - } - else{ - if(closed == false) { - pointCount+= 2; + return modelManager[rs]->newModel(path, deletePixMapAfterLoad, loadedFileList, sourceLoader); + } - //vertex 1 - glMaterialfv( - GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, - computeWaterColor(waterLevel, tc1->getHeight()).ptr()); - glMultiTexCoord2fv(GL_TEXTURE1, tc1->getFowTexCoord().ptr()); - glTexCoord3f(i, 1.f, waterAnim); - glVertex3f( - static_cast(i)*Map::mapScale, - waterLevel, - static_cast(j+1)*Map::mapScale); + void Renderer::endModel(ResourceScope rs, Model *model, bool mustExistInList) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } - //vertex 2 - glMaterialfv( - GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, - computeWaterColor(waterLevel, tc0->getHeight()).ptr()); - glMultiTexCoord2fv(GL_TEXTURE1, tc0->getFowTexCoord().ptr()); - glTexCoord3f(i, 0.f, waterAnim); - glVertex3f( - static_cast(i)*Map::mapScale, - waterLevel, - static_cast(j)*Map::mapScale); + modelManager[rs]->endModel(model, mustExistInList); + } + void Renderer::endLastModel(ResourceScope rs, bool mustExistInList) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + modelManager[rs]->endLastModel(mustExistInList); + } + + Texture2D *Renderer::newTexture2D(ResourceScope rs) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return NULL; + } + + return textureManager[rs]->newTexture2D(); + } + + Texture3D *Renderer::newTexture3D(ResourceScope rs) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return NULL; + } + + return textureManager[rs]->newTexture3D(); + } + + Font2D *Renderer::newFont(ResourceScope rs) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return NULL; + } + + return fontManager[rs]->newFont2D(); + } + + Font3D *Renderer::newFont3D(ResourceScope rs) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return NULL; + } + + return fontManager[rs]->newFont3D(); + } + + void Renderer::endFont(::Shared::Graphics::Font *font, ResourceScope rs, bool mustExistInList) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + fontManager[rs]->endFont(font, mustExistInList); + } + + //void Renderer::resetFontManager(ResourceScope rs) { + // if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + // return; + // } + // fontManager[rs]->end(); + // fontManager[rsGlobal]->init(); + //} + + void Renderer::addToDeferredParticleSystemList(std::pair deferredParticleSystem) { + deferredParticleSystems.push_back(deferredParticleSystem); + } + + void Renderer::manageParticleSystem(ParticleSystem *particleSystem, ResourceScope rs) { + particleManager[rs]->manage(particleSystem); + } + + bool Renderer::validateParticleSystemStillExists(ParticleSystem * particleSystem, ResourceScope rs) const { + return particleManager[rs]->validateParticleSystemStillExists(particleSystem); + } + + void Renderer::removeParticleSystemsForParticleOwner(ParticleOwner * particleOwner, ResourceScope rs) { + particleManager[rs]->removeParticleSystemsForParticleOwner(particleOwner); + } + + void Renderer::cleanupParticleSystems(vector &particleSystems, ResourceScope rs) { + particleManager[rs]->cleanupParticleSystems(particleSystems); + } + + void Renderer::cleanupUnitParticleSystems(vector &particleSystems, ResourceScope rs) { + particleManager[rs]->cleanupUnitParticleSystems(particleSystems); + } + + void Renderer::updateParticleManager(ResourceScope rs, int renderFps) { + particleManager[rs]->update(renderFps); + } + + void Renderer::renderParticleManager(ResourceScope rs) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + glDepthFunc(GL_LESS); + particleRenderer->renderManager(particleManager[rs], modelRenderer); + glPopAttrib(); + } + + void Renderer::swapBuffers() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + //glFlush(); // should not be required - http://www.opengl.org/wiki/Common_Mistakes + //glFlush(); + + GraphicsInterface::getInstance().getCurrentContext()->swapBuffers(); + } + + // ==================== lighting ==================== + + //places all the opengl lights + void Renderer::setupLighting() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + int lightCount = 0; + const World *world = game->getWorld(); + const GameCamera *gameCamera = game->getGameCamera(); + const TimeFlow *timeFlow = world->getTimeFlow(); + float time = timeFlow->getTime(); + + assertGl(); + + //sun/moon light + Vec3f lightColor = timeFlow->computeLightColor(); + Vec3f fogColor = world->getTileset()->getFogColor(); + Vec4f lightPos = timeFlow->isDay() ? computeSunPos(time) : computeMoonPos(time); + nearestLightPos = lightPos; + + glLightfv(GL_LIGHT0, GL_POSITION, lightPos.ptr()); + glLightfv(GL_LIGHT0, GL_AMBIENT, Vec4f(lightColor*lightAmbFactor, 1.f).ptr()); + glLightfv(GL_LIGHT0, GL_DIFFUSE, Vec4f(lightColor, 1.f).ptr()); + glLightfv(GL_LIGHT0, GL_SPECULAR, Vec4f(0.0f, 0.0f, 0.f, 1.f).ptr()); + + glFogfv(GL_FOG_COLOR, Vec4f(fogColor*lightColor, 1.f).ptr()); + + lightCount++; + + //disable all secondary lights + for (int i = 1; i < maxLights; ++i) { + glDisable(GL_LIGHT0 + i); + } + + //unit lights (not projectiles) + + if (timeFlow->isTotalNight()) { + VisibleQuadContainerCache &qCache = getQuadCache(); + if (qCache.visibleQuadUnitList.empty() == false) { + //bool modelRenderStarted = false; + for (int visibleUnitIndex = 0; + visibleUnitIndex < (int) qCache.visibleQuadUnitList.size() && lightCount < maxLights; + ++visibleUnitIndex) { + Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; + + if (world->toRenderUnit(unit) && + unit->getCurrMidHeightVector().dist(gameCamera->getPos()) < maxLightDist && + unit->getType()->getLight() && unit->isOperative()) { + //printf("$$$ Show light for faction: %s # %d / %d for Unit [%d - %s]\n",world->getFaction(i)->getType()->getName().c_str(),lightCount,maxLights,unit->getId(),unit->getFullName().c_str()); + + Vec4f pos = Vec4f(unit->getCurrMidHeightVector()); + pos.y += 4.f; + + GLenum lightEnum = GL_LIGHT0 + lightCount; + + glEnable(lightEnum); + glLightfv(lightEnum, GL_POSITION, pos.ptr()); + glLightfv(lightEnum, GL_AMBIENT, Vec4f(unit->getType()->getLightColor()).ptr()); + glLightfv(lightEnum, GL_DIFFUSE, Vec4f(unit->getType()->getLightColor()).ptr()); + glLightfv(lightEnum, GL_SPECULAR, Vec4f(unit->getType()->getLightColor()*0.3f).ptr()); + glLightf(lightEnum, GL_QUADRATIC_ATTENUATION, 0.05f); + + ++lightCount; + + const GameCamera *gameCamera = game->getGameCamera(); + + if (Vec3f(pos).dist(gameCamera->getPos()) < Vec3f(nearestLightPos).dist(gameCamera->getPos())) { + nearestLightPos = pos; + } + } + } + } + } + + assertGl(); + } + + //void Renderer::setupLightingForRotatedModel() { + // if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + // return; + // } + // + // const World *world= game->getWorld(); + // //const GameCamera *gameCamera= game->getGameCamera(); + // const TimeFlow *timeFlow= world->getTimeFlow(); + // float time= timeFlow->getTime(); + // + // assertGl(); + // + // //sun/moon light + // Vec3f lightColor= timeFlow->computeLightColor(); + // Vec3f fogColor= world->getTileset()->getFogColor(); + // Vec4f lightPos= timeFlow->isDay()? computeSunPos(time): computeMoonPos(time); + // //nearestLightPos= lightPos; + // + // glLightfv(GL_LIGHT0, GL_POSITION, lightPos.ptr()); + // glLightfv(GL_LIGHT0, GL_AMBIENT, Vec4f(lightColor*lightAmbFactor, 1.f).ptr()); + // glLightfv(GL_LIGHT0, GL_DIFFUSE, Vec4f(lightColor, 1.f).ptr()); + // glLightfv(GL_LIGHT0, GL_SPECULAR, Vec4f(0.0f, 0.0f, 0.f, 1.f).ptr()); + // + // glFogfv(GL_FOG_COLOR, Vec4f(fogColor*lightColor, 1.f).ptr()); + // + // assertGl(); + //} + + void Renderer::loadGameCameraMatrix() { + const GameCamera *gameCamera = game->getGameCamera(); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + if (gameCamera != NULL) { + glRotatef(gameCamera->getVAng(), -1, 0, 0); + glRotatef(gameCamera->getHAng(), 0, 1, 0); + glTranslatef(-(gameCamera->getPos().x + gameCamera->getShakeOffset().x), + -gameCamera->getPos().y, + -(gameCamera->getPos().z + gameCamera->getShakeOffset().y)); + } + } + + void Renderer::loadCameraMatrix(const Camera *camera) { + const Vec3f &position = camera->getConstPosition(); + Quaternion orientation = camera->getOrientation().conjugate(); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glMultMatrixf(orientation.toMatrix4().ptr()); + glTranslatef(-position.x, -position.y, -position.z); + } + + static Vec2i _unprojectMap(const Vec2i& pt, const GLdouble* model, const GLdouble* projection, const GLint* viewport, const char* label = NULL) { + Vec3d a, b; + /* note viewport[3] is height of window in pixels */ + GLint realy = viewport[3] - (GLint) pt.y; + gluUnProject(pt.x, realy, 0, model, projection, viewport, &a.x, &a.y, &a.z); + gluUnProject(pt.x, realy, 1, model, projection, viewport, &b.x, &b.y, &b.z); + + // junk values if you were looking parallel to the XZ plane; this shouldn't happen as the camera can't do this? + const Vec3f + start(a.x, a.y, a.z), + stop(b.x, b.y, b.z), + plane(0, 0, 0), + norm(0, 1, 0), + u = stop - start, + w = start - plane; + const float d = norm.x*u.x + norm.y*u.y + norm.z*u.z; + if (std::fabs(d) < 0.00001) + throw pti_D_IS_ZERO; + + const float nd = -(norm.x*w.x + norm.y*w.y + norm.z*w.z) / d; + if (nd < 0.0 || nd >= 1.0) + throw pti_N_OVER_D_IS_OUTSIDE; + + const Vec3f i = start + u * nd; + //const Vec2i pos(i.x,i.z); + + Vec2i pos; + if (strcmp(label, "tl") == 0) { + pos = Vec2i(std::floor(i.x), std::floor(i.z)); + } else if (strcmp(label, "tr") == 0) { + pos = Vec2i(std::ceil(i.x), std::floor(i.z)); + } else if (strcmp(label, "bl") == 0) { + pos = Vec2i(std::floor(i.x), std::ceil(i.z)); + } else if (strcmp(label, "br") == 0) { + pos = Vec2i(std::ceil(i.x), std::ceil(i.z)); + } + + if (false) { // print debug info + if (label) printf("%s ", label); + printf("%d,%d -> %f,%f,%f -> %f,%f,%f -> %f,%f,%f -> %d,%d\n", + pt.x, pt.y, + start.x, start.y, start.z, + stop.x, stop.y, stop.z, + i.x, i.y, i.z, + pos.x, pos.y); + } + return pos; + + } + + bool Renderer::ExtractFrustum(VisibleQuadContainerCache &quadCacheItem) { + bool frustumChanged = false; + vector proj(16, 0); + vector modl(16, 0); + + /* Get the current PROJECTION matrix from OpenGL */ + glGetFloatv(GL_PROJECTION_MATRIX, &proj[0]); + + /* Get the current MODELVIEW matrix from OpenGL */ + glGetFloatv(GL_MODELVIEW_MATRIX, &modl[0]); + + // for(unsigned int i = 0; i < proj.size(); ++i) { + // //printf("\ni = %d proj [%f][%f] modl [%f][%f]\n",i,proj[i],quadCacheItem.proj[i],modl[i],quadCacheItem.modl[i]); + // if(proj[i] != quadCacheItem.proj[i]) { + // frustumChanged = true; + // break; + // } + // if(modl[i] != quadCacheItem.modl[i]) { + // frustumChanged = true; + // break; + // } + // } + + // Check the frustum cache + const bool useFrustumCache = Config::getInstance().getBool("EnableFrustrumCache", "false"); + pair, vector > lookupKey; + if (useFrustumCache == true) { + lookupKey = make_pair(proj, modl); + map, vector >, vector > >::iterator iterFind = quadCacheItem.frustumDataCache.find(lookupKey); + if (iterFind != quadCacheItem.frustumDataCache.end()) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum found in cache\n"); + + quadCacheItem.frustumData = iterFind->second; + frustumChanged = (quadCacheItem.proj != proj || quadCacheItem.modl != modl); + if (frustumChanged == true) { + quadCacheItem.proj = proj; + quadCacheItem.modl = modl; + } + + return frustumChanged; + } + } + + if (quadCacheItem.proj != proj || quadCacheItem.modl != modl) { + //if(frustumChanged == true) { + frustumChanged = true; + vector > &frustum = quadCacheItem.frustumData; + //assert(frustum.size() == 6); + //assert(frustum[0].size() == 4); + + quadCacheItem.proj = proj; + quadCacheItem.modl = modl; + + float clip[16]; + float t = 0; + + /* Combine the two matrices (multiply projection by modelview) */ + clip[0] = modl[0] * proj[0] + modl[1] * proj[4] + modl[2] * proj[8] + modl[3] * proj[12]; + clip[1] = modl[0] * proj[1] + modl[1] * proj[5] + modl[2] * proj[9] + modl[3] * proj[13]; + clip[2] = modl[0] * proj[2] + modl[1] * proj[6] + modl[2] * proj[10] + modl[3] * proj[14]; + clip[3] = modl[0] * proj[3] + modl[1] * proj[7] + modl[2] * proj[11] + modl[3] * proj[15]; + + clip[4] = modl[4] * proj[0] + modl[5] * proj[4] + modl[6] * proj[8] + modl[7] * proj[12]; + clip[5] = modl[4] * proj[1] + modl[5] * proj[5] + modl[6] * proj[9] + modl[7] * proj[13]; + clip[6] = modl[4] * proj[2] + modl[5] * proj[6] + modl[6] * proj[10] + modl[7] * proj[14]; + clip[7] = modl[4] * proj[3] + modl[5] * proj[7] + modl[6] * proj[11] + modl[7] * proj[15]; + + clip[8] = modl[8] * proj[0] + modl[9] * proj[4] + modl[10] * proj[8] + modl[11] * proj[12]; + clip[9] = modl[8] * proj[1] + modl[9] * proj[5] + modl[10] * proj[9] + modl[11] * proj[13]; + clip[10] = modl[8] * proj[2] + modl[9] * proj[6] + modl[10] * proj[10] + modl[11] * proj[14]; + clip[11] = modl[8] * proj[3] + modl[9] * proj[7] + modl[10] * proj[11] + modl[11] * proj[15]; + + clip[12] = modl[12] * proj[0] + modl[13] * proj[4] + modl[14] * proj[8] + modl[15] * proj[12]; + clip[13] = modl[12] * proj[1] + modl[13] * proj[5] + modl[14] * proj[9] + modl[15] * proj[13]; + clip[14] = modl[12] * proj[2] + modl[13] * proj[6] + modl[14] * proj[10] + modl[15] * proj[14]; + clip[15] = modl[12] * proj[3] + modl[13] * proj[7] + modl[14] * proj[11] + modl[15] * proj[15]; + + /* Extract the numbers for the RIGHT plane */ + frustum[0][0] = clip[3] - clip[0]; + frustum[0][1] = clip[7] - clip[4]; + frustum[0][2] = clip[11] - clip[8]; + frustum[0][3] = clip[15] - clip[12]; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n", 0, frustum[0][0], frustum[0][1], frustum[0][2], frustum[0][3]); + + /* Normalize the result */ + t = std::sqrt(frustum[0][0] * frustum[0][0] + frustum[0][1] * frustum[0][1] + frustum[0][2] * frustum[0][2]); + if (t != 0.0) { + frustum[0][0] /= t; + frustum[0][1] /= t; + frustum[0][2] /= t; + frustum[0][3] /= t; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n", 0, frustum[0][0], frustum[0][1], frustum[0][2], frustum[0][3], t); + } + + /* Extract the numbers for the LEFT plane */ + frustum[1][0] = clip[3] + clip[0]; + frustum[1][1] = clip[7] + clip[4]; + frustum[1][2] = clip[11] + clip[8]; + frustum[1][3] = clip[15] + clip[12]; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n", 1, frustum[1][0], frustum[1][1], frustum[1][2], frustum[1][3]); + + /* Normalize the result */ + t = std::sqrt(frustum[1][0] * frustum[1][0] + frustum[1][1] * frustum[1][1] + frustum[1][2] * frustum[1][2]); + if (t != 0.0) { + frustum[1][0] /= t; + frustum[1][1] /= t; + frustum[1][2] /= t; + frustum[1][3] /= t; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n", 1, frustum[1][0], frustum[1][1], frustum[1][2], frustum[1][3], t); + } + + /* Extract the BOTTOM plane */ + frustum[2][0] = clip[3] + clip[1]; + frustum[2][1] = clip[7] + clip[5]; + frustum[2][2] = clip[11] + clip[9]; + frustum[2][3] = clip[15] + clip[13]; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n", 2, frustum[2][0], frustum[2][1], frustum[2][2], frustum[2][3]); + + /* Normalize the result */ + + t = std::sqrt(frustum[2][0] * frustum[2][0] + frustum[2][1] * frustum[2][1] + frustum[2][2] * frustum[2][2]); + if (t != 0.0) { + frustum[2][0] /= t; + frustum[2][1] /= t; + frustum[2][2] /= t; + frustum[2][3] /= t; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n", 2, frustum[2][0], frustum[2][1], frustum[2][2], frustum[2][3], t); + } + + /* Extract the TOP plane */ + frustum[3][0] = clip[3] - clip[1]; + frustum[3][1] = clip[7] - clip[5]; + frustum[3][2] = clip[11] - clip[9]; + frustum[3][3] = clip[15] - clip[13]; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n", 3, frustum[3][0], frustum[3][1], frustum[3][2], frustum[3][3]); + + /* Normalize the result */ + + t = std::sqrt(frustum[3][0] * frustum[3][0] + frustum[3][1] * frustum[3][1] + frustum[3][2] * frustum[3][2]); + if (t != 0.0) { + frustum[3][0] /= t; + frustum[3][1] /= t; + frustum[3][2] /= t; + frustum[3][3] /= t; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n", 3, frustum[3][0], frustum[3][1], frustum[3][2], frustum[3][3], t); + } + + /* Extract the FAR plane */ + frustum[4][0] = clip[3] - clip[2]; + frustum[4][1] = clip[7] - clip[6]; + frustum[4][2] = clip[11] - clip[10]; + frustum[4][3] = clip[15] - clip[14]; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n", 4, frustum[4][0], frustum[4][1], frustum[4][2], frustum[4][3]); + + /* Normalize the result */ + + t = std::sqrt(frustum[4][0] * frustum[4][0] + frustum[4][1] * frustum[4][1] + frustum[4][2] * frustum[4][2]); + + if (t != 0.0) { + frustum[4][0] /= t; + frustum[4][1] /= t; + frustum[4][2] /= t; + frustum[4][3] /= t; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n", 4, frustum[4][0], frustum[4][1], frustum[4][2], frustum[4][3], t); + } + + /* Extract the NEAR plane */ + frustum[5][0] = clip[3] + clip[2]; + frustum[5][1] = clip[7] + clip[6]; + frustum[5][2] = clip[11] + clip[10]; + frustum[5][3] = clip[15] + clip[14]; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%da: [%f][%f][%f][%f]\n", 5, frustum[5][0], frustum[5][1], frustum[5][2], frustum[5][3]); + + /* Normalize the result */ + + t = std::sqrt(frustum[5][0] * frustum[5][0] + frustum[5][1] * frustum[5][1] + frustum[5][2] * frustum[5][2]); + + if (t != 0.0) { + frustum[5][0] /= t; + frustum[5][1] /= t; + frustum[5][2] /= t; + frustum[5][3] /= t; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nCalc Frustum #%db: [%f][%f][%f][%f] t = %f\n", 5, frustum[5][0], frustum[5][1], frustum[5][2], frustum[5][3], t); + } + + if (useFrustumCache == true) { + quadCacheItem.frustumDataCache[lookupKey] = frustum; + } + } + return frustumChanged; + } + + //bool Renderer::PointInFrustum(vector > &frustum, float x, float y, float z ) { + // unsigned int p=0; + // + // for( p = 0; p < frustum.size(); p++ ) { + // if( frustum[p][0] * x + frustum[p][1] * y + frustum[p][2] * z + frustum[p][3] <= 0 ) { + // return false; + // } + // } + // return true; + //} + // + //bool Renderer::SphereInFrustum(vector > &frustum, float x, float y, float z, float radius) { + // // Go through all the sides of the frustum + // for(int i = 0; i < (int)frustum.size(); i++ ) { + // // If the center of the sphere is farther away from the plane than the radius + // if(frustum[i][0] * x + frustum[i][1] * y + frustum[i][2] * z + frustum[i][3] <= -radius ) { + // // The distance was greater than the radius so the sphere is outside of the frustum + // return false; + // } + // } + // + // // The sphere was inside of the frustum! + // return true; + //} + + bool Renderer::CubeInFrustum(vector > &frustum, float x, float y, float z, float size) { + unsigned int p = 0; + + for (p = 0; p < frustum.size(); p++) { + if (frustum[p][0] * (x - size) + frustum[p][1] * (y - size) + frustum[p][2] * (z - size) + frustum[p][3] > 0) + continue; + if (frustum[p][0] * (x + size) + frustum[p][1] * (y - size) + frustum[p][2] * (z - size) + frustum[p][3] > 0) + continue; + if (frustum[p][0] * (x - size) + frustum[p][1] * (y + size) + frustum[p][2] * (z - size) + frustum[p][3] > 0) + continue; + if (frustum[p][0] * (x + size) + frustum[p][1] * (y + size) + frustum[p][2] * (z - size) + frustum[p][3] > 0) + continue; + if (frustum[p][0] * (x - size) + frustum[p][1] * (y - size) + frustum[p][2] * (z + size) + frustum[p][3] > 0) + continue; + if (frustum[p][0] * (x + size) + frustum[p][1] * (y - size) + frustum[p][2] * (z + size) + frustum[p][3] > 0) + continue; + if (frustum[p][0] * (x - size) + frustum[p][1] * (y + size) + frustum[p][2] * (z + size) + frustum[p][3] > 0) + continue; + if (frustum[p][0] * (x + size) + frustum[p][1] * (y + size) + frustum[p][2] * (z + size) + frustum[p][3] > 0) + continue; + return false; + } + return true; + } + + void Renderer::computeVisibleQuad() { + visibleQuad = this->gameCamera->computeVisibleQuad(); + + bool frustumChanged = false; + if (VisibleQuadContainerCache::enableFrustumCalcs == true) { + frustumChanged = ExtractFrustum(quadCache); + } + + if (frustumChanged && SystemFlags::VERBOSE_MODE_ENABLED) { + printf("\nCamera: %d,%d %d,%d %d,%d %d,%d\n", + visibleQuad.p[0].x, visibleQuad.p[0].y, + visibleQuad.p[1].x, visibleQuad.p[1].y, + visibleQuad.p[2].x, visibleQuad.p[2].y, + visibleQuad.p[3].x, visibleQuad.p[3].y); + + for (unsigned int i = 0; i < quadCache.frustumData.size(); ++i) { + printf("\nFrustum #%u [" MG_SIZE_T_SPECIFIER "]: ", i, quadCache.frustumData.size()); + vector &frustumDataInner = quadCache.frustumData[i]; + for (unsigned int j = 0; j < frustumDataInner.size(); ++j) { + printf("[%f]", quadCache.frustumData[i][j]); + } + } + + printf("\nEND\n"); + } + + const bool newVisibleQuadCalc = false; + if (newVisibleQuadCalc) { + const bool debug = false; + try { + if (debug) { + visibleQuad = gameCamera->computeVisibleQuad(); + printf("Camera: %d,%d %d,%d %d,%d %d,%d\n", + visibleQuad.p[0].x, visibleQuad.p[0].y, + visibleQuad.p[1].x, visibleQuad.p[1].y, + visibleQuad.p[2].x, visibleQuad.p[2].y, + visibleQuad.p[3].x, visibleQuad.p[3].y); + } + + + // compute the four corners using OpenGL + GLdouble model[16], projection[16]; + GLint viewport[4]; + glGetDoublev(GL_MODELVIEW_MATRIX, model); + glGetDoublev(GL_PROJECTION_MATRIX, projection); + glGetIntegerv(GL_VIEWPORT, viewport); + Vec2i + tl = _unprojectMap(Vec2i(0, 0), model, projection, viewport, "tl"), + tr = _unprojectMap(Vec2i(viewport[2], 0), model, projection, viewport, "tr"), + br = _unprojectMap(Vec2i(viewport[2], viewport[3]), model, projection, viewport, "br"), + bl = _unprojectMap(Vec2i(0, viewport[3]), model, projection, viewport, "bl"); + + + // orientate it for map iterator + //bool swapRequiredX = false; + bool swapRequiredY = false; + int const cellBuffer = 4; + if ((tl.x > tr.x) || (bl.x > br.x)) { + if (debug) printf("Swap X???\n"); + + //std::swap(tl,bl); + //std::swap(tr,br); + if (tl.x > tr.x) { + if (debug) printf("Swap X1???\n"); + + tr.x += cellBuffer; + tl.x -= cellBuffer; + + std::swap(tl.x, tr.x); + //swapRequiredX = true; + } else { + tl.x += cellBuffer; + tr.x -= cellBuffer; + } + if (bl.x > br.x) { + if (debug) printf("Swap X2???\n"); + + bl.x += cellBuffer; + br.x -= cellBuffer; + + std::swap(bl.x, br.x); + //swapRequiredX = true; + } else { + br.x += cellBuffer; + bl.x -= cellBuffer; + } + } + + if ((tl.y > bl.y) || (tr.y > br.y)) { + visibleQuad = this->gameCamera->computeVisibleQuad(); + + if (debug) printf("Swap Y???\n"); + + if (tl.y > bl.y) { + if (debug) printf("Swap Y1???\n"); + + tl.y += cellBuffer; + bl.y -= cellBuffer; + + std::swap(tl.y, bl.y); + swapRequiredY = true; + } else { + bl.y += cellBuffer; + tl.y -= cellBuffer; + } + if (tr.y > br.y) { + if (debug) printf("Swap Y2???\n"); + + tr.y += cellBuffer; + br.y -= cellBuffer; + + std::swap(tr.y, br.y); + swapRequiredY = true; + } else { + br.y += cellBuffer; + tr.y -= cellBuffer; + } + + + //std::swap(tl,tr); + //std::swap(bl,br); + } + if (swapRequiredY == false) { + tl.y -= cellBuffer; + tr.y -= cellBuffer; + bl.y += cellBuffer; + br.y += cellBuffer; + } + + // set it as the frustum + visibleQuad = Quad2i(tl, bl, tr, br); // strange order + if (debug) { + printf("Will: %d,%d %d,%d %d,%d %d,%d\n", + visibleQuad.p[0].x, visibleQuad.p[0].y, + visibleQuad.p[1].x, visibleQuad.p[1].y, + visibleQuad.p[2].x, visibleQuad.p[2].y, + visibleQuad.p[3].x, visibleQuad.p[3].y); + } + } catch (PROJECTION_TO_INFINITY &e) { + if (debug) printf("hmm staring at the horizon %d\n", (int) e); + // use historic code solution + visibleQuad = this->gameCamera->computeVisibleQuad(); + } + } + } + + // ======================================= + // basic rendering + // ======================================= + + void Renderer::renderMouse2d(int x, int y, int anim, float fade) { + if (no2DMouseRendering == true) { + return; + } + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + // float blue=0.0f; + // float green=0.4f; + if (game != NULL && game->getGui() != NULL) { + const Gui *gui = game->getGui(); + const Display *display = gui->getDisplay(); + int downPos = display->getDownSelectedPos(); + if (downPos != Display::invalidPos) { + // in state of doing something + const Texture2D *texture = display->getDownImage(downPos); + renderTextureQuad(x + 18, y - 50, 32, 32, texture, 0.8f); + } + // else { + // // Display current commandtype + // const Unit *unit=NULL; + // if(gui->getSelection()->isEmpty()){ + // blue=0.0f; + // green=0.1f; + // } + // else{ + // unit=gui->getSelection()->getFrontUnit(); + // if(unit->getCurrCommand()!=NULL && unit->getCurrCommand()->getCommandType()->getImage()!=NULL){ + // const Texture2D *texture = unit->getCurrCommand()->getCommandType()->getImage(); + // renderTextureQuad(x+18,y-50,32,32,texture,0.2f); + // } + // } + // } + + if (game->isMarkCellMode() == true) { + const Texture2D *texture = game->getMarkCellTexture(); + renderTextureQuad(x, y, texture->getTextureWidth(), texture->getTextureHeight(), texture, 0.8f); + } + if (game->isUnMarkCellMode() == true) { + const Texture2D *texture = game->getUnMarkCellTexture(); + renderTextureQuad(x, y, texture->getTextureWidth(), texture->getTextureHeight(), texture, 0.8f); + } + } + + float fadeFactor = fade + 1.f; + + anim = anim * 2 - maxMouse2dAnim; + + float color2 = (abs(anim*(int) fadeFactor) / static_cast(maxMouse2dAnim)) / 2.f + 0.4f; + float color1 = (abs(anim*(int) fadeFactor) / static_cast(maxMouse2dAnim)) / 2.f + 0.8f; + + glPushAttrib(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_LINE_BIT); + glEnable(GL_BLEND); + + //inside + glColor4f(0.4f*fadeFactor, 0.2f*fadeFactor, 0.2f*fadeFactor, 0.5f*fadeFactor); + glBegin(GL_TRIANGLES); + glVertex2i(x, y); + glVertex2i(x + 20, y - 10); + glVertex2i(x + 10, y - 20); + glEnd(); + + //border + glLineWidth(2); + glBegin(GL_LINE_LOOP); + glColor4f(1.f, 0.2f, 0, color1); + glVertex2i(x, y); + glColor4f(1.f, 0.4f, 0, color2); + glVertex2i(x + 20, y - 10); + glColor4f(1.f, 0.4f, 0, color2); + glVertex2i(x + 10, y - 20); + glEnd(); + glPopAttrib(); + + + /* + if(no2DMouseRendering == true) { + return; + } + float color1 = 0.0, color2 = 0.0; + + float fadeFactor = fade + 1.f; + + anim= anim * 2 - maxMouse2dAnim; + + color2= (abs(anim*(int)fadeFactor)/static_cast(maxMouse2dAnim))/2.f+0.4f; + color1= (abs(anim*(int)fadeFactor)/static_cast(maxMouse2dAnim))/2.f+0.8f; + + glPushAttrib(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_LINE_BIT); + glEnable(GL_BLEND); + + //inside + Vec2i vertices[3]; + vertices[0] = Vec2i(x, y); + vertices[1] = Vec2i(x+20, y-10); + vertices[2] = Vec2i(x+10, y-20); + + glColor4f(0.4f*fadeFactor, 0.2f*fadeFactor, 0.2f*fadeFactor, 0.5f*fadeFactor); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_INT, 0, &vertices[0]); + glDrawArrays(GL_TRIANGLES, 0, 3); + glDisableClientState(GL_VERTEX_ARRAY); + + //border + vertices[0] = Vec2i(x, y); + vertices[1] = Vec2i(x+20, y-10); + vertices[2] = Vec2i(x+10, y-20); + + Vec4f colors[4]; + colors[0] = Vec4f(1.f, 0.2f, 0, color1); + colors[1] = Vec4f(1.f, 0.4f, 0, color2); + colors[2] = Vec4f(1.f, 0.4f, 0, color2); + + glLineWidth(2); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_INT, 0, &vertices[0]); + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(4, GL_FLOAT, 0, &colors[0]); + glDrawArrays(GL_LINE_LOOP, 0, 3); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + glPopAttrib(); + */ + } + + void Renderer::renderMouse3d() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + Config &config = Config::getInstance(); + if (config.getBool("RecordMode", "false") == true) { + return; + } + + if (game == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s] Line: %d game == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } else if (game->getGui() == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s] Line: %d game->getGui() == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } else if (game->getGui()->getMouse3d() == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s] Line: %d game->getGui()->getMouse3d() == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } + + const Gui *gui = game->getGui(); + const Mouse3d *mouse3d = gui->getMouse3d(); + const Map *map = game->getWorld()->getMap(); + if (map == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s] Line: %d map == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } + + assertGl(); + + if ((mouse3d->isEnabled() || gui->isPlacingBuilding()) && gui->isValidPosObjWorld()) { + const Vec2i &pos = gui->getPosObjWorld(); + + glMatrixMode(GL_MODELVIEW); + + glPushAttrib(GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_BLEND); + glDisable(GL_STENCIL_TEST); + glDepthFunc(GL_LESS); + glEnable(GL_COLOR_MATERIAL); + glDepthMask(GL_FALSE); + + if (gui->isPlacingBuilding()) { + + modelRenderer->begin(true, true, false, false); + + const UnitType *building = gui->getBuilding(); + const Gui *gui = game->getGui(); + renderGhostModel(building, pos, gui->getSelectedFacing()); + + modelRenderer->end(); + + glDisable(GL_COLOR_MATERIAL); + glPopAttrib(); + } else { + glPushMatrix(); + Vec3f pos3f = Vec3f(pos.x, map->getCell(pos)->getHeight(), pos.y); + Vec4f color; + GLUquadricObj *cilQuadric; + //standard mouse + glDisable(GL_TEXTURE_2D); + glDisable(GL_CULL_FACE); + color = Vec4f(1.f, 0.f, 0.f, 1.f - mouse3d->getFade()); + glColor4fv(color.ptr()); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color.ptr()); + + glTranslatef(pos3f.x, pos3f.y + 2.f, pos3f.z); + glRotatef(90.f, 1.f, 0.f, 0.f); + glRotatef(static_cast(mouse3d->getRot()), 0.f, 0.f, 1.f); + + cilQuadric = gluNewQuadric(); + gluQuadricDrawStyle(cilQuadric, GLU_FILL); + gluCylinder(cilQuadric, 0.5f, 0.f, 2.f, 4, 1); + gluCylinder(cilQuadric, 0.5f, 0.f, 0.f, 4, 1); + glTranslatef(0.f, 0.f, 1.f); + gluCylinder(cilQuadric, 0.7f, 0.f, 1.f, 4, 1); + gluCylinder(cilQuadric, 0.7f, 0.f, 0.f, 4, 1); + gluDeleteQuadric(cilQuadric); + + glPopAttrib(); + glPopMatrix(); + } + } + + } + + void Renderer::renderBackground(const Texture2D *texture) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + const Metrics &metrics = Metrics::getInstance(); + + assertGl(); + + glPushAttrib(GL_ENABLE_BIT); + + glDisable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + + renderQuad(0, 0, metrics.getVirtualW(), metrics.getVirtualH(), texture); + + glPopAttrib(); + + assertGl(); + } + + void Renderer::renderTextureQuad(int x, int y, int w, int h, const Texture2D *texture, float alpha, const Vec3f *color) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + assertGl(); + + glPushAttrib(GL_ENABLE_BIT); + + glDisable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + + if (color != NULL) { + Vec4f newColor(*color); + newColor.w = alpha; + glColor4fv(newColor.ptr()); + } else { + glColor4f(1.f, 1.f, 1.f, alpha); + } + renderQuad(x, y, w, h, texture); + + glPopAttrib(); + + assertGl(); + } + + void Renderer::renderConsoleLine3D(int lineIndex, int xPosition, int yPosition, int lineHeight, + Font3D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + Vec4f fontColor; + Lang &lang = Lang::getInstance(); + //const Metrics &metrics= Metrics::getInstance(); + FontMetrics *fontMetrics = font->getMetrics(); + + if (game != NULL) { + fontColor = game->getGui()->getDisplay()->getColor(); + } else { + // white shadowed is default ( in the menu for example ) + //fontColor=Vec4f(1.f, 1.f, 1.f, 0.0f); + fontColor = Vec4f(lineInfo->color.x, lineInfo->color.y, lineInfo->color.z, 0.0f); + } + + Vec4f defaultFontColor = fontColor; + + if (lineInfo->PlayerIndex >= 0) { + std::map &crcPlayerTextureCache = CacheManager::getCachedItem< std::map >(GameConstants::playerTextureCacheLookupKey); + Vec3f playerColor = crcPlayerTextureCache[lineInfo->PlayerIndex]->getPixmap()->getPixel3f(0, 0); + fontColor.x = playerColor.x; + fontColor.y = playerColor.y; + fontColor.z = playerColor.z; + + GameNetworkInterface *gameNetInterface = NetworkManager::getInstance().getGameNetworkInterface(); + if (gameNetInterface != NULL && gameNetInterface->getGameSettings() != NULL) { + const GameSettings *gameSettings = gameNetInterface->getGameSettings(); + string playerName = gameSettings->getNetworkPlayerNameByPlayerIndex(lineInfo->PlayerIndex); + if (playerName != lineInfo->originalPlayerName && lineInfo->originalPlayerName != "") { + playerName = lineInfo->originalPlayerName; + } + if (playerName == GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) { + playerName = lang.getString("SystemUser"); + } + //printf("playerName [%s], line [%s]\n",playerName.c_str(),line.c_str()); + + //string headerLine = "*" + playerName + ":"; + //string headerLine = playerName + ": "; + string headerLine = playerName; + if (lineInfo->teamMode == true) { + headerLine += " (" + lang.getString("Team") + ")"; + } + headerLine += ": "; + + if (fontMetrics == NULL) { + throw megaglest_runtime_error("fontMetrics == NULL"); + } + + renderTextShadow3D( + headerLine, + font, + fontColor, + xPosition, lineIndex * lineHeight + yPosition); + + fontColor = defaultFontColor; + //xPosition += (8 * (playerName.length() + 2)); + // Proper font spacing after username portion of chat text rendering + + //xPosition += (metrics.toVirtualX(fontMetrics->getTextWidth(headerLine))); + xPosition += fontMetrics->getTextWidth(headerLine); + } + } else if (lineInfo->originalPlayerName != "") { + string playerName = lineInfo->originalPlayerName; + //string headerLine = playerName + ": "; + string headerLine = playerName; + if (lineInfo->teamMode == true) { + headerLine += " (" + lang.getString("Team") + ")"; + } + headerLine += ": "; + + if (fontMetrics == NULL) { + throw megaglest_runtime_error("fontMetrics == NULL"); + } + + renderTextShadow3D( + headerLine, + font, + fontColor, + xPosition, lineIndex * lineHeight + yPosition); + + fontColor = defaultFontColor; + //xPosition += (8 * (playerName.length() + 2)); + // Proper font spacing after username portion of chat text rendering + //xPosition += (metrics.toVirtualX(fontMetrics->getTextWidth(headerLine))); + xPosition += fontMetrics->getTextWidth(headerLine); + } else { + fontColor = defaultFontColor; + } + + if (stringToHightlight != "" && lineInfo->text.find(stringToHightlight) != string::npos) { + fontColor = Vec4f(1.f, 0.5f, 0.5f, 0.0f); + } + renderTextShadow3D( + lineInfo->text, + font, + fontColor, + xPosition, (lineIndex * lineHeight) + yPosition); + } + + void Renderer::renderConsoleLine(int lineIndex, int xPosition, int yPosition, int lineHeight, + Font2D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + Vec4f fontColor; + Lang &lang = Lang::getInstance(); + + const Metrics &metrics = Metrics::getInstance(); + FontMetrics *fontMetrics = font->getMetrics(); + + if (game != NULL) { + fontColor = game->getGui()->getDisplay()->getColor(); + } else { + // white shadowed is default ( in the menu for example ) + //fontColor=Vec4f(1.f, 1.f, 1.f, 0.0f); + fontColor = Vec4f(lineInfo->color.x, lineInfo->color.y, lineInfo->color.z, 0.0f); + } + + Vec4f defaultFontColor = fontColor; + + if (lineInfo->PlayerIndex >= 0) { + std::map &crcPlayerTextureCache = CacheManager::getCachedItem< std::map >(GameConstants::playerTextureCacheLookupKey); + Vec3f playerColor = crcPlayerTextureCache[lineInfo->PlayerIndex]->getPixmap()->getPixel3f(0, 0); + fontColor.x = playerColor.x; + fontColor.y = playerColor.y; + fontColor.z = playerColor.z; + + GameNetworkInterface *gameNetInterface = NetworkManager::getInstance().getGameNetworkInterface(); + if (gameNetInterface != NULL && gameNetInterface->getGameSettings() != NULL) { + const GameSettings *gameSettings = gameNetInterface->getGameSettings(); + string playerName = gameSettings->getNetworkPlayerNameByPlayerIndex(lineInfo->PlayerIndex); + if (playerName != lineInfo->originalPlayerName && lineInfo->originalPlayerName != "") { + playerName = lineInfo->originalPlayerName; + } + //printf("playerName [%s], line [%s]\n",playerName.c_str(),line.c_str()); + + //string headerLine = "*" + playerName + ":"; + //string headerLine = playerName + ": "; + string headerLine = playerName; + if (lineInfo->teamMode == true) { + headerLine += " (" + lang.getString("Team") + ")"; + } + headerLine += ": "; + + if (fontMetrics == NULL) { + throw megaglest_runtime_error("fontMetrics == NULL"); + } + + renderTextShadow( + headerLine, + font, + fontColor, + xPosition, lineIndex * lineHeight + yPosition); + + fontColor = defaultFontColor; + //xPosition += (8 * (playerName.length() + 2)); + // Proper font spacing after username portion of chat text rendering + xPosition += (metrics.toVirtualX(fontMetrics->getTextWidth(headerLine))); + } + } else if (lineInfo->originalPlayerName != "") { + string playerName = lineInfo->originalPlayerName; + //string headerLine = playerName + ": "; + string headerLine = playerName; + if (lineInfo->teamMode == true) { + headerLine += " (" + lang.getString("Team") + ")"; + } + headerLine += ": "; + + if (fontMetrics == NULL) { + throw megaglest_runtime_error("fontMetrics == NULL"); + } + + renderTextShadow( + headerLine, + font, + fontColor, + xPosition, lineIndex * lineHeight + yPosition); + + fontColor = defaultFontColor; + //xPosition += (8 * (playerName.length() + 2)); + // Proper font spacing after username portion of chat text rendering + xPosition += (metrics.toVirtualX(fontMetrics->getTextWidth(headerLine))); + } else { + fontColor = defaultFontColor; + } + + if (stringToHightlight != "" && lineInfo->text.find(stringToHightlight) != string::npos) { + fontColor = Vec4f(1.f, 0.5f, 0.5f, 0.0f); + } + renderTextShadow( + lineInfo->text, + font, + fontColor, + xPosition, (lineIndex * lineHeight) + yPosition); + } + + void Renderer::renderConsole(const Console *console, ConsoleMode mode, int overrideMaxConsoleLines) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (console == NULL) { + throw megaglest_runtime_error("console == NULL"); + } + + glPushAttrib(GL_ENABLE_BIT); + glEnable(GL_BLEND); + + if (mode == consoleFull) { + int x = console->getXPos() - 5; + int y = console->getYPos() - 5; + int h = console->getLineHeight()*console->getStoredLineCount(); + + if (h > 0) { + int w = 1000; + //background + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + + glColor4f(0.0f, 0.0f, 0.0f, 0.8f); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2i(x, y); + glVertex2i(x, y + h); + glVertex2i(x + w, y); + glVertex2i(x + w, y + h); + glEnd(); + glPopAttrib(); + } + for (int i = 0; i < console->getStoredLineCount(); ++i) { + const ConsoleLineInfo &lineInfo = console->getStoredLineItem(i); + if (renderText3DEnabled == true) { + renderConsoleLine3D(i, console->getXPos(), console->getYPos(), + console->getLineHeight(), console->getFont3D(), + console->getStringToHighlight(), &lineInfo); + } else { + renderConsoleLine(i, console->getXPos(), console->getYPos(), + console->getLineHeight(), console->getFont(), + console->getStringToHighlight(), &lineInfo); + } + } + } else if (mode == consoleStoredOnly) { + int allowedMaxLines = (overrideMaxConsoleLines >= 0 ? overrideMaxConsoleLines : maxConsoleLines); + for (int i = 0; i < console->getStoredLineCount() && i < allowedMaxLines; ++i) { + const ConsoleLineInfo &lineInfo = console->getStoredLineItem(i); + if (renderText3DEnabled == true) { + renderConsoleLine3D(i, console->getXPos(), console->getYPos(), + console->getLineHeight(), console->getFont3D(), console->getStringToHighlight(), &lineInfo); + } else { + renderConsoleLine(i, console->getXPos(), console->getYPos(), + console->getLineHeight(), console->getFont(), console->getStringToHighlight(), &lineInfo); + } + } + } else if (mode == consoleStoredAndNormal) { + int allowedMaxLines = (overrideMaxConsoleLines >= 0 ? overrideMaxConsoleLines : maxConsoleLines); + float starttimestamp = -1; + int consoleIndex = 0; + for (int i = 0; i < console->getLineCount() && i < allowedMaxLines; ++i) { + const ConsoleLineInfo &lineInfo = console->getLineItem(i); + if (starttimestamp > lineInfo.timeStamp || starttimestamp == -1) starttimestamp = lineInfo.timeStamp; + if (renderText3DEnabled == true) { + renderConsoleLine3D(i, console->getXPos(), console->getYPos(), + console->getLineHeight(), console->getFont3D(), console->getStringToHighlight(), &lineInfo); + } else { + renderConsoleLine(i, console->getXPos(), console->getYPos(), + console->getLineHeight(), console->getFont(), console->getStringToHighlight(), &lineInfo); + } + consoleIndex++; + } + for (int i = 0; i < console->getStoredLineCount() && consoleIndex < allowedMaxLines; ++i) { + const ConsoleLineInfo &lineInfo = console->getStoredLineItem(i); + if (lineInfo.timeStamp < starttimestamp || starttimestamp == -1) { + if (renderText3DEnabled == true) { + renderConsoleLine3D(consoleIndex, console->getXPos(), console->getYPos(), + console->getLineHeight(), console->getFont3D(), console->getStringToHighlight(), &lineInfo); + } else { + renderConsoleLine(consoleIndex, console->getXPos(), console->getYPos(), + console->getLineHeight(), console->getFont(), console->getStringToHighlight(), &lineInfo); + } + consoleIndex++; + } + } + } else if (mode == consoleNormal) { + for (int i = 0; i < console->getLineCount(); ++i) { + const ConsoleLineInfo &lineInfo = console->getLineItem(i); + if (renderText3DEnabled == true) { + renderConsoleLine3D(i, console->getXPos(), console->getYPos(), + console->getLineHeight(), console->getFont3D(), console->getStringToHighlight(), &lineInfo); + } else { + renderConsoleLine(i, console->getXPos(), console->getYPos(), + console->getLineHeight(), console->getFont(), console->getStringToHighlight(), &lineInfo); + } + } + } + glPopAttrib(); + } + + void Renderer::renderChatManager(const ChatManager *chatManager) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + Vec4f fontColor; + Lang &lang = Lang::getInstance(); + + if (chatManager->getEditEnabled()) { + Vec4f color = Vec4f(0.0f, 0.0f, 0.0f, 0.6f); + string text = ""; + + if (chatManager->isInCustomInputMode() == true) { + text += lang.getString("CellHint"); + } else if (chatManager->getInMenu()) { + text += lang.getString("Chat"); + } else if (chatManager->getTeamMode()) { + text += lang.getString("Team"); + } else { + text += lang.getString("All"); + } + text += ": " + chatManager->getText() + "_"; + + if (game != NULL) { + fontColor = game->getGui()->getDisplay()->getColor(); + } else { + // white shadowed is default ( in the menu for example ) + fontColor = Vec4f(1.f, 1.f, 1.f, 0.0f); + } + + // render Background + int x = chatManager->getXPos(); + int y = chatManager->getYPos() - 6; + int h = 22; + int w = 830; + + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + + glColor4f(color.x, color.y, color.z, color.w); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2i(x, y); + glVertex2i(x, y + h); + glVertex2i(x + w, y); + glVertex2i(x + w, y + h); + glEnd(); + glPopAttrib(); + + if (renderText3DEnabled == true) { + renderTextShadow3D( + text, + chatManager->getFont3D(), + fontColor, + chatManager->getXPos(), chatManager->getYPos()); + } else { + renderTextShadow( + text, + chatManager->getFont(), + fontColor, + chatManager->getXPos(), chatManager->getYPos()); + } + } else { + if (chatManager->getInMenu()) { + string text = "\t\t\t\t\t>> " + lang.getString("PressEnterToChat") + " <<"; + fontColor = Vec4f(0.5f, 0.5f, 0.5f, 0.5f); + + if (renderText3DEnabled == true) { + renderTextShadow3D(text, chatManager->getFont3D(), fontColor, + chatManager->getXPos(), chatManager->getYPos()); + } else { + renderTextShadow(text, chatManager->getFont(), fontColor, + chatManager->getXPos(), chatManager->getYPos()); + } + } + } + } + + + void Renderer::renderPerformanceStats() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + const Metrics &metrics = Metrics::getInstance(); + const Vec4f fontColor = game->getGui()->getDisplay()->getColor(); + + char szBuf[200] = ""; + snprintf(szBuf, 200, "Frame: %d", game->getWorld()->getFrameCount() / 20); + string str = string(szBuf) + string("\n"); + + static time_t lastGamePerfCheck = time(NULL); + static string gamePerfStats = ""; + if (difftime((long int) time(NULL), lastGamePerfCheck) > 3) { + lastGamePerfCheck = time(NULL); + gamePerfStats = game->getGamePerformanceCounts(true); + } + + if (gamePerfStats != "") { + str += gamePerfStats + "\n"; + } + + if (renderText3DEnabled == true) { + renderTextShadow3D( + str, CoreData::getInstance().getDisplayFontSmall3D(), + fontColor, + 10, metrics.getVirtualH() - 180, false); + } else { + renderTextShadow( + str, CoreData::getInstance().getDisplayFontSmall(), + fontColor, + 10, metrics.getVirtualH() - 180, false); + } + } + + void Renderer::renderClock() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + Config &config = Config::getInstance(); + if (config.getBool("InGameClock", "true") == false && + config.getBool("InGameLocalClock", "true") == false && + config.getBool("InGameFrameCounter", "false") == false) { + return; + } + + string str = ""; + const Metrics &metrics = Metrics::getInstance(); + const World *world = game->getWorld(); + const Vec4f fontColor = game->getGui()->getDisplay()->getColor(); + + if (config.getBool("InGameClock", "true") == true) { + Lang &lang = Lang::getInstance(); + char szBuf[501] = ""; + + //int hours = world->getTimeFlow()->getTime(); + //int minutes = (world->getTimeFlow()->getTime() - hours) * 100 * 0.6; // scale 100 to 60 + //snprintf(szBuf,200,"%s %.2d:%.2d",lang.getString("GameTime","",true).c_str(),hours,minutes); + // string header2 = lang.getString("GameDurationTime","",true) + ": " + getTimeString(stats.getFramesToCalculatePlaytime()); + snprintf(szBuf, 500, "%s %s", lang.getString("GameDurationTime", "", true).c_str(), getTimeDuationString(world->getFrameCount(), GameConstants::updateFps).c_str()); + if (str != "") { + str += " "; + } + str += szBuf; + } + + if (config.getBool("InGameLocalClock", "true") == true) { + //time_t nowTime = time(NULL); + //struct tm *loctime = localtime(&nowTime); + struct tm loctime = threadsafe_localtime(systemtime_now()); + char szBuf2[100] = ""; + strftime(szBuf2, 100, "%H:%M", &loctime); + + Lang &lang = Lang::getInstance(); + char szBuf[200] = ""; + snprintf(szBuf, 200, "%s %s", lang.getString("LocalTime", "", true).c_str(), szBuf2); + if (str != "") { + str += " "; + } + str += szBuf; + } + + if (config.getBool("InGameFrameCounter", "false") == true) { + char szBuf[200] = ""; + snprintf(szBuf, 200, "Frame: %d", game->getWorld()->getFrameCount() / 20); + if (str != "") { + str += " "; + } + str += szBuf; + } + + //string str = szBuf; + + if (renderText3DEnabled == true) { + renderTextShadow3D( + str, CoreData::getInstance().getDisplayFontSmall3D(), + fontColor, + 10, metrics.getVirtualH() - 160, false); + } else { + renderTextShadow( + str, CoreData::getInstance().getDisplayFontSmall(), + fontColor, + 10, metrics.getVirtualH() - 160, false); + } + } + + void Renderer::renderResourceStatus() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + const World *world = game->getWorld(); + Config &config = Config::getInstance(); + + if (world->getThisFactionIndex() < 0 || + world->getThisFactionIndex() >= world->getFactionCount()) { + return; + } + + const Faction *thisFaction = world->getFaction(world->getThisFactionIndex()); + + assertGl(); + glPushAttrib(GL_ENABLE_BIT); + + int rowsRendered = 0; + int resourceCountRendered = 0; + bool twoRessourceLines = false; + + bool sharedTeamUnits = game != NULL && game->getGui() != NULL + && game->isFlagType1BitEnabled(ft1_allow_shared_team_units) + == true; + bool sharedTeamResources = game != NULL && game->getGui() != NULL + && game->isFlagType1BitEnabled( + ft1_allow_shared_team_resources) == true; + + bool renderSharedTeamResources = false; + bool renderSharedTeamUnits = false; + bool renderLocalFactionResources = false; + + if (config.getBool("TwoLineTeamResourceRendering", "false") == true) { + if (sharedTeamResources == true || sharedTeamUnits == true) { + twoRessourceLines = true; + } + if (sharedTeamResources == true) { + renderSharedTeamResources = true; + renderSharedTeamUnits = true; + } else if (sharedTeamUnits == true) { + renderSharedTeamUnits = true; + renderLocalFactionResources = true; + } else { + renderLocalFactionResources = true; + } + } else { + if (sharedTeamResources == true) + renderSharedTeamResources = true; + else if (sharedTeamUnits == true) + renderSharedTeamUnits = true; + else + renderLocalFactionResources = true; + } + + if (renderSharedTeamResources == true) { + resourceCountRendered = 0; + for (int techTreeResourceTypeIndex = 0; + techTreeResourceTypeIndex < world->getTechTree()->getResourceTypeCount(); + ++techTreeResourceTypeIndex) { + + const ResourceType *rt = world->getTechTree()->getResourceType(techTreeResourceTypeIndex); + + if (rt->getDisplayInHud() == false) { + continue; + } + + bool showResource = world->showResourceTypeForTeam(rt, thisFaction->getTeam()); + if (showResource == true) { + rowsRendered = renderResource(thisFaction, + false, twoRessourceLines, rt, 0, + resourceCountRendered); + } + } + if (resourceCountRendered > 0) { + rowsRendered++; + } + } + + if (renderLocalFactionResources == true) { + resourceCountRendered = 0; + + const Faction *factionForResourceView = thisFaction; + bool localFactionResourcesOnly = true; + + for (int techTreeResourceTypeIndex = 0; + techTreeResourceTypeIndex < world->getTechTree()->getResourceTypeCount(); + ++techTreeResourceTypeIndex) { + const ResourceType *rt = world->getTechTree()->getResourceType(techTreeResourceTypeIndex); + if (rt->getDisplayInHud() == false) { + continue; + } + + //if any unit produces the resource + bool showResource; + if (twoRessourceLines) + showResource = world->showResourceTypeForTeam(rt, + factionForResourceView->getTeam()); + else + showResource = world->showResourceTypeForFaction(rt, + factionForResourceView); + if (showResource == true) { + renderResource(factionForResourceView, localFactionResourcesOnly, + twoRessourceLines, rt, rowsRendered, resourceCountRendered); + } + } + if (resourceCountRendered > 0) { + rowsRendered++; + } + } + + if (renderSharedTeamUnits == true) { + resourceCountRendered = 0; + + const Faction *factionForResourceView = thisFaction; + bool localFactionResourcesOnly = true; + + const Gui *gui = game->getGui(); + if (gui != NULL) { + const Selection *selection = gui->getSelection(); + if (selection != NULL && selection->getCount() > 0 && selection->getFrontUnit() != NULL) { + const Unit *selectedUnit = selection->getFrontUnit(); + if (selectedUnit != NULL && selectedUnit->getFaction()->isAlly(thisFaction) == true) { + factionForResourceView = selectedUnit->getFaction(); + } + } + } + + for (int techTreeResourceTypeIndex = 0; + techTreeResourceTypeIndex < world->getTechTree()->getResourceTypeCount(); + ++techTreeResourceTypeIndex) { + const ResourceType *rt = world->getTechTree()->getResourceType(techTreeResourceTypeIndex); + if (rt->getDisplayInHud() == false) { + continue; + } + + //if any unit produces the resource + bool showResource; + if (twoRessourceLines) + showResource = world->showResourceTypeForTeam(rt, + factionForResourceView->getTeam()); + else + showResource = world->showResourceTypeForFaction(rt, + factionForResourceView); + + if (showResource == true) { + renderResource(factionForResourceView, localFactionResourcesOnly, + twoRessourceLines, rt, rowsRendered, resourceCountRendered); + } + } + //if(resourceCountRendered > 0) { + // rowsRendered++; + //} + } + + glPopAttrib(); + + assertGl(); + } + + int Renderer::renderResource(const Faction *factionForResourceView, bool localFactionResourcesOnly, + bool twoResourceLines, const ResourceType *rt, int startRow, int &resourceCountRendered) { + + const Metrics &metrics = Metrics::getInstance(); + const int MAX_RESOURCES_PER_ROW = 6; + + int resourceRowHeigth = 30; + int resourceYStart = metrics.getVirtualH() - 30; + if (twoResourceLines) { + // we need to save some space + resourceYStart = metrics.getVirtualH() - 22; + resourceRowHeigth = 16; + } + + //draw resource status + if (localFactionResourcesOnly == true) { + Vec4f resourceFontColor = Vec4f(factionForResourceView->getTexture()->getPixmapConst()->getPixel3f(0, 0)); + int resourceCol = 0; + int resourceRow = startRow; + + int x = resourceCol * 100 + 190; + int y = resourceYStart - (resourceRowHeigth * resourceRow); + int h = 16; + int w = 8; + glColor3f(resourceFontColor.x, resourceFontColor.y, resourceFontColor.z); + glBegin(GL_TRIANGLE_STRIP); + glVertex2i(x, y + h); + glVertex2i(x, y); + glVertex2i(x + w, y + h / 2); + glEnd(); + } + + const Resource *r = factionForResourceView->getResource(rt, localFactionResourcesOnly); + string str = intToStr(r->getAmount()); + + glEnable(GL_TEXTURE_2D); + + const Vec4f fontColor = game->getGui()->getDisplay()->getColor(); + Vec4f resourceFontColor = fontColor; + + bool isNegativeConsumableDisplayCycle = false; + if (rt->getClass() == rcConsumable) { + // Show in yellow/orange/red font if negative + if (r->getBalance() * 5 + r->getAmount() < 0) { + if (time(NULL) % 2 == 0) { + + isNegativeConsumableDisplayCycle = true; + if (r->getBalance() * 1 + r->getAmount() < 0) { + glColor3f(RED.x, RED.y, RED.z); + resourceFontColor = RED; + } else if (r->getBalance() * 3 + r->getAmount() < 0) { + glColor3f(ORANGE.x, ORANGE.y, ORANGE.z); + resourceFontColor = ORANGE; + } else if (r->getBalance() * 5 + r->getAmount() < 0) { + glColor3f(YELLOW.x, YELLOW.y, YELLOW.z); + resourceFontColor = YELLOW; + } + } + } + } + + if (isNegativeConsumableDisplayCycle == false) { + glColor3f(1.f, 1.f, 1.f); + } + + int resourceRow = startRow + (resourceCountRendered > 0 ? resourceCountRendered / MAX_RESOURCES_PER_ROW : 0); + int resourceCol = resourceCountRendered % MAX_RESOURCES_PER_ROW; + + renderQuad(resourceCol * 100 + 200, resourceYStart - (resourceRowHeigth * resourceRow), 16, 16, rt->getImage()); + + if (rt->getClass() != rcStatic) { + str += "/" + intToStr(factionForResourceView->getStoreAmount(rt, localFactionResourcesOnly)); + } + if (rt->getClass() == rcConsumable) { + str += "("; + if (r->getBalance() > 0) { + str += "+"; + } + str += intToStr(r->getBalance()) + ")"; + } + + glDisable(GL_TEXTURE_2D); + + if (renderText3DEnabled == true) { + renderTextShadow3D( + str, CoreData::getInstance().getDisplayFontSmall3D(), + resourceFontColor, + resourceCol * 100 + 220, resourceYStart - (resourceRowHeigth * resourceRow), false); + } else { + renderTextShadow( + str, CoreData::getInstance().getDisplayFontSmall(), + resourceFontColor, + resourceCol * 100 + 220, resourceYStart - (resourceRowHeigth * resourceRow), false); + } + ++resourceCountRendered; + + return resourceRow; + } + + void Renderer::renderSelectionQuad() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + Config &config = Config::getInstance(); + if (config.getBool("RecordMode", "false") == true) { + return; + } + + const Gui *gui = game->getGui(); + const SelectionQuad *sq = gui->getSelectionQuad(); + + Vec2i down = sq->getPosDown(); + Vec2i up = sq->getPosUp(); + + if (gui->isSelecting()) { + glPushAttrib(GL_CURRENT_BIT | GL_LINE_BIT); + + Vec2i vertices[4]; + vertices[0] = Vec2i(down.x, down.y); + vertices[1] = Vec2i(up.x, down.y); + vertices[2] = Vec2i(up.x, up.y); + vertices[3] = Vec2i(down.x, up.y); + + glColor3f(0, 1, 0); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_INT, 0, &vertices[0]); + glDrawArrays(GL_LINE_LOOP, 0, 4); + glDisableClientState(GL_VERTEX_ARRAY); + + /* + glColor3f(0,1,0); + glBegin(GL_LINE_LOOP); + glVertex2i(down.x, down.y); + glVertex2i(up.x, down.y); + glVertex2i(up.x, up.y); + glVertex2i(down.x, up.y); + glEnd(); + */ + glPopAttrib(); + } + } + + Vec2i computeCenteredPos(const string &text, Font2D *font, int x, int y) { + if (font == NULL) { + //abort(); + throw megaglest_runtime_error("font == NULL (1) text = " + text); + } + const Metrics &metrics = Metrics::getInstance(); + FontMetrics *fontMetrics = font->getMetrics(); + + if (fontMetrics == NULL) { + throw megaglest_runtime_error("fontMetrics == NULL (1) text = " + text); + } + + int virtualX = (fontMetrics->getTextWidth(text) > 0 ? static_cast(fontMetrics->getTextWidth(text) / 2.f) : 5); + int virtualY = (fontMetrics->getHeight(text) > 0 ? static_cast(fontMetrics->getHeight(text) / 2.f) : 5); + + Vec2i textPos( + x - metrics.toVirtualX(virtualX), + y - metrics.toVirtualY(virtualY)); + + //printf("text [%s] x = %d y = %d virtualX = %d virtualY = %d fontMetrics->getHeight() = %f\n",text.c_str(),x,y,virtualX,virtualY,fontMetrics->getHeight()); + + return textPos; + } + + Vec2i computeCenteredPos(const string &text, Font3D *font, int x, int y) { + if (font == NULL) { + throw megaglest_runtime_error("font == NULL (2) text = " + text); + } + const Metrics &metrics = Metrics::getInstance(); + FontMetrics *fontMetrics = font->getMetrics(); + + if (fontMetrics == NULL) { + throw megaglest_runtime_error("fontMetrics == NULL (2) text = " + text); + } + + int virtualX = (fontMetrics->getTextWidth(text) > 0 ? static_cast(fontMetrics->getTextWidth(text) / 2.f) : 5); + int virtualY = (fontMetrics->getHeight(text) > 0 ? static_cast(fontMetrics->getHeight(text) / 2.f) : 5); + + Vec2i textPos( + x - metrics.toVirtualX(virtualX), + y - metrics.toVirtualY(virtualY)); + + return textPos; + } + + void Renderer::renderTextSurroundingBox(int x, int y, int w, int h, + int maxEditWidth, int maxEditRenderWidth) { + //glColor4fv(color.ptr()); + //glBegin(GL_QUADS); // Start drawing a quad primitive + + //printf("A w = %d maxEditWidth = %d maxEditRenderWidth = %d\n",w,maxEditWidth,maxEditRenderWidth); + if (maxEditWidth >= 0 || maxEditRenderWidth >= 0) { + //printf("B w = %d maxEditWidth = %d maxEditRenderWidth = %d\n",w,maxEditWidth,maxEditRenderWidth); + if (maxEditRenderWidth >= 0) { + w = maxEditRenderWidth; + } else { + w = maxEditWidth; + } + } + //printf("HI!!!\n"); + glPointSize(20.0f); + + int margin = 4; + //glBegin(GL_POINTS); // Start drawing a point primitive + glBegin(GL_LINE_LOOP); // Start drawing a line primitive + + glVertex3f(x, y + h, 0.0f); // The bottom left corner + glVertex3f(x, y - margin, 0.0f); // The top left corner + glVertex3f(x + w, y - margin, 0.0f); // The top right corner + glVertex3f(x + w, y + h, 0.0f); // The bottom right corner + glEnd(); + } + + void Renderer::renderTextBoundingBox3D(const string &text, Font3D *font, + float alpha, int x, int y, int w, int h, bool centeredW, bool centeredH, + bool editModeEnabled, int maxEditWidth, int maxEditRenderWidth) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + glColor4fv(Vec4f(1.f, 1.f, 1.f, alpha).ptr()); + + Vec2f pos = Vec2f(x, y); + //Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); + if (centeredW == true || centeredH == true) { + getCentered3DPos(text, font, pos, w, h, centeredW, centeredH); + } + + if (editModeEnabled) { + if (maxEditWidth >= 0 || maxEditRenderWidth >= 0) { + int useWidth = maxEditWidth; + string temp = ""; + for (int i = 0; i < useWidth; ++i) { + temp += DEFAULT_CHAR_FOR_WIDTH_CALC; + } + float lineWidth = (font->getTextHandler()->Advance(temp.c_str()) * ::Shared::Graphics::Font::scaleFontValue); + useWidth = (int) lineWidth; + + maxEditWidth = useWidth; + } + + renderTextSurroundingBox(pos.x, pos.y, w, h, maxEditWidth, maxEditRenderWidth); + } + glColor4fv(Vec4f(1.f, 1.f, 1.f, alpha).ptr()); + TextRendererSafeWrapper safeTextRender(textRenderer3D, font); + textRenderer3D->render(text, pos.x, pos.y); + safeTextRender.end(); + + glDisable(GL_BLEND); + glPopAttrib(); + } + + void Renderer::renderText3D(const string &text, Font3D *font, float alpha, int x, int y, bool centered) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + glColor4fv(Vec4f(1.f, 1.f, 1.f, alpha).ptr()); + + Vec2i pos = Vec2i(x, y); + //Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); + + TextRendererSafeWrapper safeTextRender(textRenderer3D, font); + textRenderer3D->render(text, pos.x, pos.y, centered); + //textRenderer3D->end(); + safeTextRender.end(); + + glDisable(GL_BLEND); + glPopAttrib(); + } + + void Renderer::renderText(const string &text, Font2D *font, float alpha, int x, int y, bool centered) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + glColor4fv(Vec4f(1.f, 1.f, 1.f, alpha).ptr()); + + Vec2i pos = centered ? computeCenteredPos(text, font, x, y) : Vec2i(x, y); + + TextRendererSafeWrapper safeTextRender(textRenderer, font); + textRenderer->render(text, pos.x, pos.y); + safeTextRender.end(); + + glPopAttrib(); + } + + Vec2f Renderer::getCentered3DPos(const string &text, Font3D *font, Vec2f &pos, int w, int h, bool centeredW, bool centeredH) { + if (centeredW == true) { + if (font == NULL) { + //abort(); + throw megaglest_runtime_error("font == NULL (5) text = " + text); + } else if (font->getTextHandler() == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "font->getTextHandler() == NULL(5) text = [%s] FontPtr = [%p]\n", text.c_str(), font); + throw megaglest_runtime_error(szBuf); + } + + float lineWidth = (font->getTextHandler()->Advance(text.c_str()) * ::Shared::Graphics::Font::scaleFontValue); + if (lineWidth < w) { + pos.x += ((w / 2.f) - (lineWidth / 2.f)); + } + } + + if (centeredH) { + if (font == NULL) { + throw megaglest_runtime_error("font == NULL (6) text = " + text); + } else if (font->getTextHandler() == NULL) { + throw megaglest_runtime_error("font->getTextHandler() == NULL (6) text = " + text); + } + + //const Metrics &metrics= Metrics::getInstance(); + //float lineHeight = (font->getTextHandler()->LineHeight(text.c_str()) * Font::scaleFontValue); + float lineHeight = (font->getTextHandler()->LineHeight(text.c_str()) * ::Shared::Graphics::Font::scaleFontValue); + //lineHeight=metrics.toVirtualY(lineHeight); + //lineHeight= lineHeight / (2.f + 0.2f * FontMetrics::DEFAULT_Y_OFFSET_FACTOR); + //pos.y += (h / 2.f) - (lineHeight / 2.f); + //pos.y += (h / 2.f) - (lineHeight); + //pos.y += (lineHeight / 2.f); // y starts at the middle of the render position, so only move up 1/2 the font height + + if (lineHeight < h) { + //printf("line %d, lineHeight [%f] h [%d] text [%s]\n",__LINE__,lineHeight,h,text.c_str()); + + //if(Font::forceFTGLFonts == true) { + // First go to top of bounding box + pos.y += (h - lineHeight); + pos.y -= ((h - lineHeight) / ::Shared::Graphics::Font::scaleFontValueCenterHFactor); + // } + // else { + // pos.y += (float)(((float)h) / 2.0); + // float heightGap = (float)(((float)h - lineHeight) / 2.0); + // pos.y -= heightGap; + // + // //printf("h = %d lineHeight = %f heightGap = %f\n",h,lineHeight,heightGap); + // + // // Now calculate till we get text to middle + // //pos.y -= (realHeight / 2); + // //pos.y += (lineHeight / 2); + // } + } else if (lineHeight > h) { + //printf("line %d, lineHeight [%f] h [%d] text [%s]\n",__LINE__,lineHeight,h,text.c_str()); + + pos.y += (std::ceil(lineHeight - h)); + } + } + return pos; + } + + void Renderer::renderTextBoundingBox3D(const string &text, Font3D *font, + const Vec3f &color, int x, int y, int w, int h, bool centeredW, + bool centeredH, bool editModeEnabled, int maxEditWidth, int maxEditRenderWidth) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + glPushAttrib(GL_CURRENT_BIT); + glColor3fv(color.ptr()); + + Vec2f pos = Vec2f(x, y); + //Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); + + if (centeredW == true || centeredH == true) { + getCentered3DPos(text, font, pos, w, h, centeredW, centeredH); + } + + if (editModeEnabled) { + if (maxEditWidth >= 0 || maxEditRenderWidth >= 0) { + int useWidth = maxEditWidth; + string temp = ""; + for (int i = 0; i < useWidth; ++i) { + temp += DEFAULT_CHAR_FOR_WIDTH_CALC; + } + float lineWidth = (font->getTextHandler()->Advance(temp.c_str()) * ::Shared::Graphics::Font::scaleFontValue); + useWidth = (int) lineWidth; + + maxEditWidth = useWidth; + } + + renderTextSurroundingBox(pos.x, pos.y, w, h, maxEditWidth, maxEditRenderWidth); + } + glColor3fv(color.ptr()); + TextRendererSafeWrapper safeTextRender(textRenderer3D, font); + textRenderer3D->render(text, pos.x, pos.y); + safeTextRender.end(); + + glPopAttrib(); + } + + void Renderer::renderText3D(const string &text, Font3D *font, const Vec3f &color, int x, int y, bool centered) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + glPushAttrib(GL_CURRENT_BIT); + glColor3fv(color.ptr()); + + Vec2i pos = Vec2i(x, y); + //Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); + + TextRendererSafeWrapper safeTextRender(textRenderer3D, font); + textRenderer3D->render(text, pos.x, pos.y, centered); + safeTextRender.end(); + + glPopAttrib(); + } + + void Renderer::renderText(const string &text, Font2D *font, const Vec3f &color, int x, int y, bool centered) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + glPushAttrib(GL_CURRENT_BIT); + glColor3fv(color.ptr()); + + Vec2i pos = centered ? computeCenteredPos(text, font, x, y) : Vec2i(x, y); + + TextRendererSafeWrapper safeTextRender(textRenderer, font); + textRenderer->render(text, pos.x, pos.y); + safeTextRender.end(); + + glPopAttrib(); + } + + void Renderer::renderTextBoundingBox3D(const string &text, Font3D *font, + const Vec4f &color, int x, int y, int w, int h, bool centeredW, + bool centeredH, bool editModeEnabled, int maxEditWidth, int maxEditRenderWidth) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + glColor4fv(color.ptr()); + + Vec2f pos = Vec2f(x, y); + //Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); + + if (centeredW == true || centeredH == true) { + getCentered3DPos(text, font, pos, w, h, centeredW, centeredH); + } + + if (editModeEnabled) { + if (maxEditWidth >= 0 || maxEditRenderWidth >= 0) { + int useWidth = maxEditWidth; + string temp = ""; + for (int i = 0; i < useWidth; ++i) { + temp += DEFAULT_CHAR_FOR_WIDTH_CALC; + } + float lineWidth = (font->getTextHandler()->Advance(temp.c_str()) * ::Shared::Graphics::Font::scaleFontValue); + useWidth = (int) lineWidth; + + maxEditWidth = useWidth; + } + + renderTextSurroundingBox(pos.x, pos.y, w, h, maxEditWidth, maxEditRenderWidth); + } + glColor4fv(color.ptr()); + TextRendererSafeWrapper safeTextRender(textRenderer3D, font); + textRenderer3D->render(text, pos.x, pos.y); + safeTextRender.end(); + + glDisable(GL_BLEND); + glPopAttrib(); + } + + void Renderer::renderText3D(const string &text, Font3D *font, const Vec4f &color, int x, int y, bool centered) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + glColor4fv(color.ptr()); + + Vec2i pos = Vec2i(x, y); + //Vec2i pos= centered? computeCenteredPos(text, font, x, y): Vec2i(x, y); + + TextRendererSafeWrapper safeTextRender(textRenderer3D, font); + textRenderer3D->render(text, pos.x, pos.y, centered); + safeTextRender.end(); + + glDisable(GL_BLEND); + glPopAttrib(); + } + + void Renderer::renderText(const string &text, Font2D *font, const Vec4f &color, int x, int y, bool centered) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + glColor4fv(color.ptr()); + + Vec2i pos = centered ? computeCenteredPos(text, font, x, y) : Vec2i(x, y); + + TextRendererSafeWrapper safeTextRender(textRenderer, font); + textRenderer->render(text, pos.x, pos.y); + safeTextRender.end(); + + glPopAttrib(); + } + + void Renderer::renderTextShadow3D(const string &text, Font3D *font, const Vec4f &color, int x, int y, bool centered) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (font == NULL) { + throw megaglest_runtime_error("font == NULL (3) text = " + text); + } + + glPushAttrib(GL_CURRENT_BIT); + + Vec2i pos = centered ? computeCenteredPos(text, font, x, y) : Vec2i(x, y); + + TextRendererSafeWrapper safeTextRender(textRenderer3D, font); + if (color.w < 0.5) { + glColor3f(0.0f, 0.0f, 0.0f); + + textRenderer3D->render(text, pos.x - 1.0f, pos.y - 1.0f); + } + glColor3f(color.x, color.y, color.z); + + textRenderer3D->render(text, pos.x, pos.y); + //textRenderer3D->end(); + safeTextRender.end(); + + glPopAttrib(); + } + + void Renderer::renderTextShadow(const string &text, Font2D *font, const Vec4f &color, int x, int y, bool centered) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (font == NULL) { + throw megaglest_runtime_error("font == NULL (4) text = " + text); + } + + glPushAttrib(GL_CURRENT_BIT); + + Vec2i pos = centered ? computeCenteredPos(text, font, x, y) : Vec2i(x, y); + + TextRendererSafeWrapper safeTextRender(textRenderer, font); + if (color.w < 0.5) { + glColor3f(0.0f, 0.0f, 0.0f); + + textRenderer->render(text, pos.x - 1.0f, pos.y - 1.0f); + } + glColor3f(color.x, color.y, color.z); + + textRenderer->render(text, pos.x, pos.y); + //textRenderer->end(); + safeTextRender.end(); + + glPopAttrib(); + } + + // ============= COMPONENTS ============================= + + void Renderer::renderLabel(GraphicLabel *label) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (label->getEditable() && label->getMaxEditRenderWidth() > 0) { + int x = label->getX(); + int y = label->getY(); + int h = label->getH(); + int w = label->getMaxEditRenderWidth(); + if (h > 0) { + //background + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + + glColor4f(0.2f, 0.2f, 0.2f, 0.6f*label->getFade()); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2i(x, y); + glVertex2i(x, y + h); + glVertex2i(x + w, y); + glVertex2i(x + w, y + h); + glEnd(); + glPopAttrib(); + } + } + + if (label->getRenderBackground()) { + int x = label->getX(); + int y = label->getY(); + int h = label->getH(); + int w = label->getW(); + if (label->getMaxEditRenderWidth() > 0) { + w = label->getMaxEditRenderWidth(); + } + Vec4f color = label->getBackgroundColor(); + if (h > 0) { + //background + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + + glColor4f(color.x, color.y, color.z, color.w*label->getFade()); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2i(x, y); + glVertex2i(x, y + h); + glVertex2i(x + w, y); + glVertex2i(x + w, y + h); + glEnd(); + glPopAttrib(); + } + } + + if (label->getTexture() != NULL) { + int x = label->getX(); + int y = label->getY(); + int h = label->getH(); + int w = label->getW(); + if (h > 0) { + //background + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, static_cast(label->getTexture())->getHandle()); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f*label->getFade()); + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0.f, 0.f); + glVertex2f(x, y); + + glTexCoord2f(0.f, 1.f); + glVertex2f(x, y + h); + + glTexCoord2f(1.f, 0.f); + glVertex2f(x + w, y); + + glTexCoord2f(1.f, 1.f); + glVertex2f(x + w, y + h); + glEnd(); + glDisable(GL_TEXTURE_2D); + glPopAttrib(); + } + } + Vec3f labelColor = label->getTextColor(); + Vec4f colorWithAlpha = Vec4f(labelColor.x, labelColor.y, labelColor.z, GraphicComponent::getFade()); + renderLabel(label, &colorWithAlpha); + } + + void Renderer::renderLabel(GraphicLabel *label, const Vec3f *color) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (color != NULL) { + Vec4f colorWithAlpha = Vec4f(*color); + colorWithAlpha.w = GraphicComponent::getFade(); + renderLabel(label, &colorWithAlpha); + } else { + Vec4f *colorWithAlpha = NULL; + renderLabel(label, colorWithAlpha); + } + } + + void Renderer::renderLabel(GraphicLabel *label, const Vec4f *color) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (label->getVisible() == false) { + return; + } + try { + glPushAttrib(GL_ENABLE_BIT); + glEnable(GL_BLEND); + + vector lines; + string renderTextString = (label->getTextNativeTranslation() != "" ? label->getTextNativeTranslation() : label->getText()); + if (label->getWordWrap() == true) { + Tokenize(renderTextString, lines, "\n"); + } else { + lines.push_back(renderTextString); + } + + for (unsigned int i = 0; i < lines.size(); ++i) { + Vec2i textPos; + int x = label->getX(); + int y = label->getY() - (i * label->getH()); + int h = label->getH(); + int w = label->getW(); + //if(label->getInstanceName() == "modDescrLabel") printf("~~~ lines.size() [%u] i = %d lines[i] [%s] y = %d\n",lines.size(),i,lines[i].c_str(),y); + + if (label->getCentered()) { + textPos = Vec2i(x + w / 2, y + h / 2); + } else { + textPos = Vec2i(x, y + h / 4); + } + + string renderTextStr = lines[i]; + if (label->getIsPassword() == true) { + if (renderTextStr != "") { + renderTextStr = "*****"; + } + } + + if (color != NULL) { + if (renderText3DEnabled == true) { + //renderText3D(lines[i], label->getFont3D(), (*color), textPos.x, textPos.y, label->getCentered()); + //printf("Text Render3D [%s] font3d [%p]\n",lines[i].c_str(),label->getFont3D()); + //printf("Label render C\n"); + + renderTextBoundingBox3D(renderTextStr, label->getFont3D(), (*color), + x, y, w, h, label->getCenteredW(), label->getCenteredH(), + label->getEditModeEnabled(), label->getMaxEditWidth(), + label->getMaxEditRenderWidth()); + } else { + //printf("Label render D\n"); + renderText(renderTextStr, label->getFont(), (*color), textPos.x, textPos.y, label->getCentered()); + } + } else { + if (renderText3DEnabled == true) { + //renderText3D(lines[i], label->getFont3D(), GraphicComponent::getFade(), textPos.x, textPos.y, label->getCentered()); + //printf("Text Render3D [%s] font3d [%p]\n",lines[i].c_str(),label->getFont3D()); + //printf("Label render E\n"); + renderTextBoundingBox3D(renderTextStr, label->getFont3D(), + GraphicComponent::getFade(), x, y, w, h, + label->getCenteredW(), label->getCenteredH(), + label->getEditModeEnabled(), label->getMaxEditWidth(), + label->getMaxEditRenderWidth()); + } else { + //printf("Label render F\n"); + renderText(renderTextStr, label->getFont(), GraphicComponent::getFade(), textPos.x, textPos.y, label->getCentered()); + } + } + } + glPopAttrib(); + } catch (const exception &e) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d]\nError [%s] For Control [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what(), label->getInstanceName().c_str()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + throw megaglest_runtime_error(szBuf); + } + + } + + void Renderer::renderButton(GraphicButton *button, const Vec4f *fontColorOverride, bool *lightedOverride) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (button->getVisible() == false) { + return; + } + + try { + + //char szBuf[8096]=""; + //snprintf(szBuf,8096,"In [%s::%s Line: %d]\n For Control container [%s] name [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,button->getContainerName().c_str(), button->getInstanceName().c_str()); + //printf(szBuf); + + int x = button->getX(); + int y = button->getY(); + int h = button->getH(); + int w = button->getW(); + + const Vec3f disabledTextColor = Vec3f(0.25f, 0.25f, 0.25f); + + glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT); + + //background + CoreData &coreData = CoreData::getInstance(); + Texture2D *backTexture = NULL; + + if (button->getUseCustomTexture() == true) { + backTexture = dynamic_cast(button->getCustomTexture()); + } else { + backTexture = w > 3 * h / 2 ? coreData.getButtonBigTexture() : coreData.getButtonSmallTexture(); + } + + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + + if (backTexture != NULL) { + glBindTexture(GL_TEXTURE_2D, static_cast(backTexture)->getHandle()); + } else { + glBindTexture(GL_TEXTURE_2D, 0); + } + + //button + Vec4f fontColor(GraphicComponent::getCustomTextColor()); + + if (fontColorOverride != NULL) { + fontColor = *fontColorOverride; + } else { + // white shadowed is default ( in the menu for example ) + fontColor.w = GraphicComponent::getFade(); + } + + //Vec4f color= Vec4f(1.f, 1.f, 1.f, GraphicComponent::getFade()); + Vec4f color = fontColor; + glColor4fv(color.ptr()); + + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0.f, 0.f); + glVertex2f(x, y); + + glTexCoord2f(0.f, 1.f); + glVertex2f(x, y + h); + + glTexCoord2f(1.f, 0.f); + glVertex2f(x + w, y); + + glTexCoord2f(1.f, 1.f); + glVertex2f(x + w, y + h); + + glEnd(); + + glDisable(GL_TEXTURE_2D); + + //lighting + float anim = GraphicComponent::getAnim(); + if (anim > 0.5f) anim = 1.f - anim; + + bool renderLighted = (button->getLighted() && button->getEditable()); + if (lightedOverride != NULL) { + renderLighted = *lightedOverride; + } + if (renderLighted) { + const int lightSize = 0; + const Vec4f color1 = Vec4f(color.x, color.y, color.z, 0.1f + anim * 0.5f); + const Vec4f color2 = Vec4f(color.x, color.y, color.z, 0.3f + anim); + + glBegin(GL_TRIANGLE_FAN); + + glColor4fv(color2.ptr()); + glVertex2f(x + w / 2, y + h / 2); + + glColor4fv(color1.ptr()); + glVertex2f(x - lightSize, y - lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x + w + lightSize, y - lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x + w + lightSize, y + h + lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x + w + lightSize, y + h + lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x - lightSize, y + h + lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x - lightSize, y - lightSize); glEnd(); + } + + //Vec2i textPos= Vec2i(x + w / 2, y + h / 2); + + if (button->getEditable()) { + if (renderText3DEnabled == true) { + //renderText3D(button->getText(), button->getFont3D(), color,x + (w / 2), y + (h / 2), true); + renderTextBoundingBox3D(button->getText(), button->getFont3D(), + color, x, y, w, h, true, true, false, -1, -1); + } else { + renderText(button->getText(), button->getFont(), color, x + (w / 2), y + (h / 2), true); + } + } else { + if (renderText3DEnabled == true) { + //renderText3D(button->getText(), button->getFont3D(),disabledTextColor, + // x + (w / 2), y + (h / 2), true); + renderTextBoundingBox3D(button->getText(), button->getFont3D(), disabledTextColor, + x, y, w, h, true, true, false, -1, -1); + } else { + renderText(button->getText(), button->getFont(), disabledTextColor, + x + (w / 2), y + (h / 2), true); + } + } + + glPopAttrib(); + } catch (const exception &e) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d]\nError [%s] For Control container [%s] name [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what(), button->getContainerName().c_str(), button->getInstanceName().c_str()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + throw megaglest_runtime_error(szBuf); + } + } + + void Renderer::renderCheckBox(const GraphicCheckBox *box) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (box->getVisible() == false) { + return; + } + + int x = box->getX(); + int y = box->getY(); + int h = box->getH(); + int w = box->getW(); + + //const Vec3f disabledTextColor= Vec3f(0.25f,0.25f,0.25f); + + glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT); + + //background + CoreData &coreData = CoreData::getInstance(); + Texture2D *backTexture = box->getValue() ? coreData.getCheckedCheckBoxTexture() : coreData.getCheckBoxTexture(); + + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + + glBindTexture(GL_TEXTURE_2D, static_cast(backTexture)->getHandle()); + + //box + Vec4f fontColor; + //if(game!=NULL){ + // fontColor=game->getGui()->getDisplay()->getColor(); + // fontColor.w = GraphicComponent::getFade(); + //} + //else { + // white shadowed is default ( in the menu for example ) + fontColor = Vec4f(1.f, 1.f, 1.f, GraphicComponent::getFade()); + //} + + //Vec4f color= Vec4f(1.f, 1.f, 1.f, GraphicComponent::getFade()); + Vec4f color = fontColor; + glColor4fv(color.ptr()); + + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0.f, 0.f); + glVertex2f(x, y); + + glTexCoord2f(0.f, 1.f); + glVertex2f(x, y + h); + + glTexCoord2f(1.f, 0.f); + glVertex2f(x + w, y); + + glTexCoord2f(1.f, 1.f); + glVertex2f(x + w, y + h); + + glEnd(); + + glDisable(GL_TEXTURE_2D); + + //lighting + float anim = GraphicComponent::getAnim(); + if (anim > 0.5f) { + anim = 1.f - anim; + } + + if (box->getLighted() && box->getEditable()) { + const int lightSize = 0; + const Vec4f color1 = Vec4f(color.x, color.y, color.z, 0.1f + anim * 0.5f); + const Vec4f color2 = Vec4f(color.x, color.y, color.z, 0.3f + anim); + + glBegin(GL_TRIANGLE_FAN); + + glColor4fv(color2.ptr()); + glVertex2f(x + w / 2, y + h / 2); + + glColor4fv(color1.ptr()); + glVertex2f(x - lightSize, y - lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x + w + lightSize, y - lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x + w + lightSize, y + h + lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x + w + lightSize, y + h + lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x - lightSize, y + h + lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x - lightSize, y - lightSize); + + glEnd(); + } + + glPopAttrib(); + } + + + void Renderer::renderLine(const GraphicLine *line) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (line->getVisible() == false) { + return; + } + + int x = line->getX(); + int y = line->getY(); + int h = line->getH(); + int w = line->getW(); + + //const Vec3f disabledTextColor= Vec3f(0.25f,0.25f,0.25f); + + glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT); + + //background + CoreData &coreData = CoreData::getInstance(); + Texture2D *backTexture = line->getHorizontal() ? coreData.getHorizontalLineTexture() : coreData.getVerticalLineTexture(); + + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + + glBindTexture(GL_TEXTURE_2D, static_cast(backTexture)->getHandle()); + + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0.f, 0.f); + glVertex2f(x, y); + + glTexCoord2f(0.f, 1.f); + glVertex2f(x, y + h); + + glTexCoord2f(1.f, 0.f); + glVertex2f(x + w, y); + + glTexCoord2f(1.f, 1.f); + glVertex2f(x + w, y + h); + + glEnd(); + + glDisable(GL_TEXTURE_2D); + glPopAttrib(); + } + + void Renderer::renderScrollBar(const GraphicScrollBar *sb) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (sb->getVisible() == false) { + return; + } + + int x = sb->getX(); + int y = sb->getY(); + int h = sb->getH(); + int w = sb->getW(); + + //const Vec3f disabledTextColor= Vec3f(0.25f,0.25f,0.25f); + + glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT); + ///////////////////// + //background + //////////////////// + CoreData &coreData = CoreData::getInstance(); + Texture2D *backTexture = coreData.getHorizontalLineTexture(); + + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + + glBindTexture(GL_TEXTURE_2D, static_cast(backTexture)->getHandle()); + + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0.f, 0.f); + glVertex2f(x, y); + + glTexCoord2f(0.f, 1.f); + glVertex2f(x, y + h); + + glTexCoord2f(1.f, 0.f); + glVertex2f(x + w, y); + + glTexCoord2f(1.f, 1.f); + glVertex2f(x + w, y + h); + + glEnd(); + + //////////////////// + // selectBlock + //////////////////// + + x = sb->getX(); + y = sb->getY(); + h = sb->getH(); + w = sb->getW(); + + if (sb->getHorizontal()) { + x = x + sb->getVisibleCompPosStart(); + w = sb->getVisibleCompPosEnd() - sb->getVisibleCompPosStart(); + } else { + y = y + sb->getVisibleCompPosStart(); + h = sb->getVisibleCompPosEnd() - sb->getVisibleCompPosStart(); + } + + Texture2D *selectTexture = coreData.getButtonBigTexture(); + assert(selectTexture != NULL); + + glBindTexture(GL_TEXTURE_2D, static_cast(selectTexture)->getHandle()); + + //button + Vec4f fontColor; + //if(game!=NULL){ + // fontColor=game->getGui()->getDisplay()->getColor(); + // fontColor.w = GraphicComponent::getFade(); + //} + //else { + // white shadowed is default ( in the menu for example ) + fontColor = Vec4f(1.f, 1.f, 1.f, GraphicComponent::getFade()); + //} + + //Vec4f color= Vec4f(1.f, 1.f, 1.f, GraphicComponent::getFade()); + Vec4f color = fontColor; + glColor4fv(color.ptr()); + + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0.f, 0.f); + glVertex2f(x, y); + + glTexCoord2f(0.f, 1.f); + glVertex2f(x, y + h); + + glTexCoord2f(1.f, 0.f); + glVertex2f(x + w, y); + + glTexCoord2f(1.f, 1.f); + glVertex2f(x + w, y + h); + + glEnd(); + + glDisable(GL_TEXTURE_2D); + + //lighting + float anim = GraphicComponent::getAnim(); + if (anim > 0.5f) anim = 1.f - anim; + + if (sb->getLighted() && sb->getEditable()) { + const int lightSize = 0; + const Vec4f color1 = Vec4f(color.x, color.y, color.z, 0.1f + anim * 0.5f); + const Vec4f color2 = Vec4f(color.x, color.y, color.z, 0.3f + anim); + + glBegin(GL_TRIANGLE_FAN); + + glColor4fv(color2.ptr()); + glVertex2f(x + w / 2, y + h / 2); + + glColor4fv(color1.ptr()); + glVertex2f(x - lightSize, y - lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x + w + lightSize, y - lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x + w + lightSize, y + h + lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x + w + lightSize, y + h + lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x - lightSize, y + h + lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x - lightSize, y - lightSize); + + glEnd(); + } + + glPopAttrib(); + } + + void Renderer::renderListBox(GraphicListBox *listBox) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (listBox->getVisible() == false) { + return; + } + //if(listBox->getLeftControlled()==true) + { + int x = listBox->getX(); + int y = listBox->getY(); + int h = listBox->getH(); + int w = listBox->getW(); + if (h > 0) { + //background + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + + glColor4f(0.0f, 0.0f, 0.0f, 0.6f*listBox->getFade()); + glBegin(GL_TRIANGLE_STRIP); - closed= true; + glVertex2i(x, y); + glVertex2i(x, y + h); + glVertex2i(x + w, y); + glVertex2i(x + w, y + h); + glEnd(); + glPopAttrib(); } - } - } - glEnd(); - } - - //restore - glPopAttrib(); - - assertGl(); -} - -void Renderer::renderTeamColorCircle(){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - VisibleQuadContainerCache &qCache = getQuadCache(); - if(qCache.visibleQuadUnitList.empty() == false) { - - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); - glDisable(GL_LIGHTING); - glDisable(GL_TEXTURE_2D); - glDepthFunc(GL_ALWAYS); - glDisable(GL_STENCIL_TEST); - glDisable(GL_CULL_FACE); - glEnable(GL_BLEND); - glLineWidth(2.f); - - for(int visibleUnitIndex = 0; - visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { - Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; - Vec3f currVec= unit->getCurrVectorFlat(); - Vec3f color=unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0); - glColor4f(color.x, color.y, color.z, 0.7f); - renderSelectionCircle(currVec, unit->getType()->getSize(), 0.8f, 0.05f); } - glPopAttrib(); - } -} + renderButton(listBox->getButton1()); + renderButton(listBox->getButton2()); -void Renderer::renderSpecialHighlightUnits(std::map unitHighlightList) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true || unitHighlightList.empty() == true) { - return; - } + glPushAttrib(GL_ENABLE_BIT); + glEnable(GL_BLEND); - VisibleQuadContainerCache &qCache = getQuadCache(); - if(qCache.visibleQuadUnitList.empty() == false) { + GraphicLabel label("ListBox_render_label", "label", false); + //label.setInstanceName("ListBox_render_label"); + if (listBox->getLeftControlled() == true) { + label.init(listBox->getX() + listBox->getButton1()->getW() + listBox->getButton2()->getW() + 2, listBox->getY(), listBox->getW(), listBox->getH(), false, listBox->getTextColor()); + } else { + label.init(listBox->getX(), listBox->getY(), listBox->getW(), listBox->getH(), true, listBox->getTextColor()); + } + label.setText(listBox->getText()); + label.setTextNativeTranslation(listBox->getTextNativeTranslation()); + label.setFont(listBox->getFont()); + label.setFont3D(listBox->getFont3D()); + renderLabel(&label); - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); - glDisable(GL_LIGHTING); - glDisable(GL_TEXTURE_2D); - glDepthFunc(GL_ALWAYS); - glDisable(GL_STENCIL_TEST); - glDisable(GL_CULL_FACE); - glEnable(GL_BLEND); - glLineWidth(2.f); - for(int visibleUnitIndex = 0; - visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { - Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; + //lighting - std::map::iterator iterFindSpecialUnit = unitHighlightList.find(unit->getId()); - if(iterFindSpecialUnit != unitHighlightList.end()) { - Vec3f color=unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0); - float radius = 1.0f; - float thickness = 0.1f; - float alpha = 0.65f; + bool renderLighted = (listBox->getLighted()); - HighlightSpecialUnitInfo &specialInfo = iterFindSpecialUnit->second; - if(specialInfo.color.x >= 0) { - color.x = specialInfo.color.x; - color.y = specialInfo.color.y; - color.z = specialInfo.color.z; - } - if(specialInfo.color.w >= 0) { - alpha = specialInfo.color.w; - } - if(specialInfo.radius > 0) { - radius = specialInfo.radius; - } - if(specialInfo.thickness > 0) { - thickness = specialInfo.thickness; - } - glColor4f(color.x, color.y, color.z, alpha); + if (renderLighted) { + float anim = GraphicComponent::getAnim(); + if (anim > 0.5f) anim = 1.f - anim; - Vec3f currVec= unit->getCurrVectorFlat(); - renderSelectionCircle(currVec, unit->getType()->getSize(), radius, thickness); - } + Vec3f color = listBox->getTextColor(); + int x = listBox->getX() + listBox->getButton1()->getW(); + int y = listBox->getY(); + int h = listBox->getH(); + int w = listBox->getW() - listBox->getButton1()->getW() - listBox->getButton2()->getW(); + + const int lightSize = 0; + const Vec4f color1 = Vec4f(color.x, color.y, color.z, 0.1f + anim * 0.5f); + const Vec4f color2 = Vec4f(color.x, color.y, color.z, 0.3f + anim); + + glBegin(GL_TRIANGLE_FAN); + + glColor4fv(color2.ptr()); + glVertex2f(x + w / 2, y + h / 2); + + glColor4fv(color1.ptr()); + glVertex2f(x - lightSize, y - lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x + w + lightSize, y - lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x + w + lightSize, y + h + lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x + w + lightSize, y + h + lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x - lightSize, y + h + lightSize); + + glColor4fv(color1.ptr()); + glVertex2f(x - lightSize, y - lightSize); + + glEnd(); + } + + glPopAttrib(); } - glPopAttrib(); - } -} -void Renderer::renderTeamColorPlane(){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } + void Renderer::renderMessageBox(GraphicMessageBox *messageBox) { + const int headerHeight = 25; + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } - VisibleQuadContainerCache &qCache = getQuadCache(); - if(qCache.visibleQuadUnitList.empty() == false){ - glPushAttrib(GL_ENABLE_BIT); - glDisable(GL_LIGHTING); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glEnable(GL_COLOR_MATERIAL); - const Texture2D *texture=CoreData::getInstance().getTeamColorTexture(); - for(int visibleUnitIndex = 0; - visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex){ - Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; - if( unit->isAlive()){ - Vec3f currVec= unit->getCurrVectorFlat(); - renderTeamColorEffect(currVec,visibleUnitIndex,unit->getType()->getSize(), - unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0),texture); + try { + if (messageBox->getVisible() == false) { + return; + } + + if ((renderText3DEnabled == false && messageBox->getFont() == NULL) || + (renderText3DEnabled == true && messageBox->getFont3D() == NULL)) { + messageBox->setFont(CoreData::getInstance().getMenuFontNormal()); + messageBox->setFont3D(CoreData::getInstance().getMenuFontNormal3D()); + } + + string wrappedText = messageBox->getText(); + if (messageBox->getAutoWordWrap() == true) { + if (renderText3DEnabled == false) { + wrappedText = messageBox->getFont()->getMetrics()->wordWrapText(wrappedText, messageBox->getW() * 0.90); + } else { + wrappedText = messageBox->getFont3D()->getMetrics()->wordWrapText(wrappedText, messageBox->getW() * 0.90); + } + } + + //background + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + + glColor4f(0.0f, 0.0f, 0.0f, 0.8f); + glBegin(GL_TRIANGLE_STRIP); + glVertex2i(messageBox->getX(), messageBox->getY() + messageBox->getH() - headerHeight); + glVertex2i(messageBox->getX(), messageBox->getY()); + glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + messageBox->getH() - headerHeight); + glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY()); + glEnd(); + + glColor4f(0.0f, 0.0f, 0.0f, 0.8f); + glBegin(GL_TRIANGLE_STRIP); + glVertex2i(messageBox->getX(), messageBox->getY() + messageBox->getH()); + glVertex2i(messageBox->getX(), messageBox->getY() + messageBox->getH() - headerHeight); + glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + messageBox->getH()); + glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + messageBox->getH() - headerHeight); + glEnd(); + + glBegin(GL_LINE_LOOP); + glColor4f(0.5f, 0.5f, 0.5f, 0.25f); + glVertex2i(messageBox->getX(), messageBox->getY()); + + glColor4f(0.0f, 0.0f, 0.0f, 0.25f); + glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY()); + + glColor4f(0.5f, 0.5f, 0.5f, 0.25f); + glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + messageBox->getH()); + + glColor4f(0.25f, 0.25f, 0.25f, 0.25f); + glVertex2i(messageBox->getX(), messageBox->getY() + messageBox->getH()); + glEnd(); + + glBegin(GL_LINE_STRIP); + glColor4f(1.0f, 1.0f, 1.0f, 0.25f); + glVertex2i(messageBox->getX(), messageBox->getY() + messageBox->getH() - headerHeight); + + glColor4f(0.5f, 0.5f, 0.5f, 0.25f); + glVertex2i(messageBox->getX() + messageBox->getW(), messageBox->getY() + messageBox->getH() - headerHeight); + glEnd(); + + glPopAttrib(); + + + //buttons + for (int i = 0; i < messageBox->getButtonCount(); i++) { + + if ((renderText3DEnabled == false && messageBox->getButton(i)->getFont() == NULL) || + (renderText3DEnabled == true && messageBox->getButton(i)->getFont3D() == NULL)) { + messageBox->getButton(i)->setFont(CoreData::getInstance().getMenuFontNormal()); + messageBox->getButton(i)->setFont3D(CoreData::getInstance().getMenuFontNormal3D()); + } + + renderButton(messageBox->getButton(i)); + } + + Vec4f fontColor; + //if(game!=NULL){ + // fontColor=game->getGui()->getDisplay()->getColor(); + //} + //else { + // white shadowed is default ( in the menu for example ) + fontColor = Vec4f(1.f, 1.f, 1.f, 1.0f); + //} + + if (renderText3DEnabled == true) { + //text + renderTextShadow3D( + wrappedText, messageBox->getFont3D(), fontColor, + messageBox->getX() + 15, messageBox->getY() + messageBox->getH() - headerHeight * 2, + false); + + renderTextShadow3D( + messageBox->getHeader(), messageBox->getFont3D(), fontColor, + messageBox->getX() + 15, messageBox->getY() + messageBox->getH() - headerHeight + 8, + false); + + } else { + //text + renderTextShadow( + wrappedText, messageBox->getFont(), fontColor, + messageBox->getX() + 15, messageBox->getY() + messageBox->getH() - headerHeight * 2, + false); + + renderTextShadow( + messageBox->getHeader(), messageBox->getFont(), fontColor, + messageBox->getX() + 15, messageBox->getY() + messageBox->getH() - headerHeight + 8, + false); + } + } catch (const exception &e) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d]\nError [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + + throw megaglest_runtime_error(szBuf); } } - glDisable(GL_COLOR_MATERIAL); - glPopAttrib(); - } -} -void Renderer::renderGhostModel(const UnitType *building, const Vec2i pos,CardinalDir facing, Vec4f *forceColor) { - //const UnitType *building= gui->getBuilding(); - //const Vec2i &pos= gui->getPosObjWorld(); + // ==================== complex rendering ==================== - //const Gui *gui= game->getGui(); - //const Mouse3d *mouse3d= gui->getMouse3d(); - const Map *map= game->getWorld()->getMap(); - if(map == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s] Line: %d map == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - - glPushMatrix(); - Vec3f pos3f= Vec3f(pos.x, map->getCell(pos)->getHeight(), pos.y); - - //selection building placement - float offset= building->getSize()/2.f-0.5f; - glTranslatef(pos3f.x+offset, pos3f.y, pos3f.z+offset); - - //choose color - Vec4f color; - if(forceColor != NULL) { - color = *forceColor; - } - else { - if(map->isFreeCells(pos, building->getSize(), fLand)) { - color= Vec4f(1.f, 1.f, 1.f, 0.5f); - } - else { -// Uint64 tc=game->getTickCount(); -// float red=0.49f+((tc%4*1.0f)/2); - color= Vec4f(1.0f, 0.f, 0.f, 0.5f); - } - } - - glColor4fv(color.ptr()); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color.ptr()); - Model *buildingModel= building->getFirstStOfClass(scStop)->getAnimation(); - - if(facing != CardinalDir::NORTH) { - float rotateAmount = facing * 90.f; - if(rotateAmount > 0) { - glRotatef(rotateAmount, 0.f, 1.f, 0.f); - } - } - - buildingModel->updateInterpolationData(0.f, false); - modelRenderer->render(buildingModel); - - glPopMatrix(); -} - -void Renderer::renderUnits(bool airUnits, const int renderFps) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - //Unit *unit=NULL; - //const World *world= game->getWorld(); - MeshCallbackTeamColor meshCallbackTeamColor; - - //assert - assertGl(); - - if(visibleFrameUnitList.empty() == false) { - visibleFrameUnitList.clear(); - //visibleFrameUnitListCameraKey = ""; - //if(visibleFrameUnitListCameraKey != game->getGameCamera()->getCameraMovementKey()) { - // worldToScreenPosCache.clear(); + //VisibleQuadContainerVBOCache * Renderer::GetSurfaceVBOs(SurfaceData *cellData) { + // std::map::iterator iterFind = mapSurfaceVBOCache.find(cellData->uniqueId); + // if(iterFind == mapSurfaceVBOCache.end()) { + // Vec2f *texCoords = &cellData->texCoords[0]; + // Vec2f *texCoordsSurface = &cellData->texCoordsSurface[0]; + // Vec3f *vertices = &cellData->vertices[0]; + // Vec3f *normals = &cellData->normals[0]; + // + // VisibleQuadContainerVBOCache vboCache; + // + // // Generate And Bind The Vertex Buffer + // glGenBuffersARB( 1, (GLuint*)&vboCache.m_nVBOVertices ); // Get A Valid Name + // glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache.m_nVBOVertices ); // Bind The Buffer + // // Load The Data + // glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec3f) * cellData->bufferCount, vertices, GL_STATIC_DRAW_ARB ); + // glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + // + // assertGl(); + // // Generate And Bind The Texture Coordinate Buffer + // glGenBuffersARB( 1, (GLuint*)&vboCache.m_nVBOFowTexCoords ); // Get A Valid Name + // glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache.m_nVBOFowTexCoords ); // Bind The Buffer + // // Load The Data + // glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec2f) * cellData->bufferCount, texCoords, GL_STATIC_DRAW_ARB ); + // glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + // + // assertGl(); + // // Generate And Bind The Texture Coordinate Buffer + // glGenBuffersARB( 1, (GLuint*)&vboCache.m_nVBOSurfaceTexCoords ); // Get A Valid Name + // glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache.m_nVBOSurfaceTexCoords ); // Bind The Buffer + // // Load The Data + // glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec2f) * cellData->bufferCount, texCoordsSurface, GL_STATIC_DRAW_ARB ); + // glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + // + // assertGl(); + // // Generate And Bind The Normal Buffer + // glGenBuffersARB( 1, (GLuint*)&vboCache.m_nVBONormals ); // Get A Valid Name + // glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache.m_nVBONormals ); // Bind The Buffer + // // Load The Data + // glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec3f) * cellData->bufferCount, normals, GL_STATIC_DRAW_ARB ); + // glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + // + // vboCache.hasBuiltVBOs = true; + // + // mapSurfaceVBOCache[cellData->uniqueId] = vboCache; + // + // // don't need the data in computer RAM anymore its in the GPU now + // cellData->texCoords.clear(); + // cellData->texCoordsSurface.clear(); + // cellData->vertices.clear(); + // cellData->normals.clear(); + // } + // + // return &mapSurfaceVBOCache[cellData->uniqueId]; //} - } - VisibleQuadContainerCache &qCache = getQuadCache(); - if(qCache.visibleQuadUnitList.empty() == false) { - bool modelRenderStarted = false; - for(int visibleUnitIndex = 0; - visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { - Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; + void Renderer::ReleaseSurfaceVBOs() { + for (std::map::iterator iterFind = mapSurfaceVBOCache.begin(); + iterFind != mapSurfaceVBOCache.end(); ++iterFind) { - if(( airUnits==false && unit->getType()->getField()==fAir) || ( airUnits==true && unit->getType()->getField()!=fAir)){ - continue; + VisibleQuadContainerVBOCache &item = iterFind->second; + if (item.hasBuiltVBOs == true) { + glDeleteBuffersARB(1, (GLuint*) &item.m_nVBOVertices); // Get A Valid Name + glDeleteBuffersARB(1, (GLuint*) &item.m_nVBOFowTexCoords); // Get A Valid Name + glDeleteBuffersARB(1, (GLuint*) &item.m_nVBOSurfaceTexCoords); // Get A Valid Name + glDeleteBuffersARB(1, (GLuint*) &item.m_nVBONormals); // Get A Valid Name + //glDeleteBuffersARB( 1, &item.m_nVBOIndexes ); // Get A Valid Name + } } - meshCallbackTeamColor.setTeamTexture(unit->getFaction()->getTexture()); - if(modelRenderStarted == false) { - modelRenderStarted = true; + mapSurfaceVBOCache.clear(); + } - glPushAttrib(GL_ENABLE_BIT | GL_FOG_BIT | GL_LIGHTING_BIT | GL_TEXTURE_BIT); - glEnable(GL_COLOR_MATERIAL); + Renderer::MapRenderer::Layer::~Layer() { + if (vbo_vertices) glDeleteBuffersARB(1, &vbo_vertices); + if (vbo_normals) glDeleteBuffersARB(1, &vbo_normals); + if (vbo_fowTexCoords) glDeleteBuffersARB(1, &vbo_fowTexCoords); + if (vbo_surfTexCoords) glDeleteBuffersARB(1, &vbo_surfTexCoords); + if (vbo_indices) glDeleteBuffersARB(1, &vbo_indices); - if(!shadowsOffDueToMinRender) { - if(shadows == sShadowMapping) { + } + + template void _loadVBO(GLuint &vbo, std::vector buf, int target = GL_ARRAY_BUFFER_ARB) { + assert(buf.size()); + if (true /* vbo enabled? */) { + glGenBuffersARB(1, &vbo); + assert(vbo); + glBindBufferARB(target, vbo); + glBufferDataARB(target, sizeof(T)*buf.size(), &buf[0], GL_STATIC_DRAW_ARB); + glBindBufferARB(target, 0); + assertGl(); + buf.clear(); + } + } + + void Renderer::MapRenderer::Layer::load_vbos(bool vboEnabled) { + indexCount = (int) indices.size(); + if (vboEnabled) { + _loadVBO(vbo_vertices, vertices); + _loadVBO(vbo_normals, normals); + _loadVBO(vbo_fowTexCoords, fowTexCoords); + _loadVBO(vbo_surfTexCoords, surfTexCoords); + + _loadVBO(vbo_indices, indices, GL_ELEMENT_ARRAY_BUFFER_ARB); + } else { + vbo_vertices = 0; + vbo_normals = 0; + vbo_fowTexCoords = 0; + vbo_surfTexCoords = 0; + vbo_indices = 0; + } + } + + void Renderer::MapRenderer::loadVisibleLayers(float coordStep, VisibleQuadContainerCache &qCache) { + int totalCellCount = 0; + // we create a layer for each visible texture in the map + for (int visibleIndex = 0; + visibleIndex < (int) qCache.visibleScaledCellList.size(); ++visibleIndex) { + Vec2i &pos = qCache.visibleScaledCellList[visibleIndex]; + + totalCellCount++; + + SurfaceCell *tc00 = map->getSurfaceCell(pos.x, pos.y); + SurfaceCell *tc10 = map->getSurfaceCell(pos.x + 1, pos.y); + SurfaceCell *tc01 = map->getSurfaceCell(pos.x, pos.y + 1); + SurfaceCell *tc11 = map->getSurfaceCell(pos.x + 1, pos.y + 1); + + const Vec2f &surfCoord = tc00->getSurfTexCoord(); + + SurfaceCell *tc[4] = { + tc00, + tc10, + tc01, + tc11 + }; + int textureHandle = static_cast(tc[0]->getSurfaceTexture())->getHandle(); + string texturePath = static_cast(tc[0]->getSurfaceTexture())->getPath(); + //int32 textureCRC = CalculatePixelsCRC(static_cast(tc[0]->getSurfaceTexture())); + Layer* layer = NULL; + for (Layers::iterator it = layers.begin(); it != layers.end(); ++it) { + if ((*it)->textureHandle == textureHandle) { + //if((*it)->texturePath == texturePath) { + //if((*it)->textureCRC == textureCRC) { + layer = *it; + break; + } + } + if (!layer) { + layer = new Layer(textureHandle); + layer->texturePath = texturePath; + //layer->textureCRC = textureCRC; + layers.push_back(layer); + + //printf("Ading new unique texture [%s]\n",texturePath.c_str()); + } + // we'll be super-lazy and re-emit all four corners just because its easier + int index[4]; + int loopIndexes[4] = { 2,0,3,1 }; + for (int i = 0; i < 4; i++) { + index[i] = (int) layer->vertices.size(); + SurfaceCell *corner = tc[loopIndexes[i]]; + + layer->vertices.push_back(corner->getVertex()); + layer->normals.push_back(corner->getNormal()); + layer->fowTexCoords.push_back(corner->getFowTexCoord()); + } + + layer->surfTexCoords.push_back(Vec2f(surfCoord.x, surfCoord.y + coordStep)); + layer->surfTexCoords.push_back(Vec2f(surfCoord.x, surfCoord.y)); + layer->surfTexCoords.push_back(Vec2f(surfCoord.x + coordStep, surfCoord.y + coordStep)); + layer->surfTexCoords.push_back(Vec2f(surfCoord.x + coordStep, surfCoord.y)); + + // and make two triangles (no strip, we may be disjoint) + layer->indices.push_back(index[0]); + layer->indices.push_back(index[1]); + layer->indices.push_back(index[2]); + layer->indices.push_back(index[1]); + layer->indices.push_back(index[3]); + layer->indices.push_back(index[2]); + + } + // turn them into vbos (actually this method will just calc the index count) + for (Layers::iterator layer = layers.begin(); layer != layers.end(); ++layer) { + (*layer)->load_vbos(false); + } + + //printf("Total # of layers for this map = %d totalCellCount = %d overall render reduction ratio = %d times\n",layers.size(),totalCellCount,(totalCellCount / layers.size())); + } + + void Renderer::MapRenderer::load(float coordStep) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + int totalCellCount = 0; + // we create a layer for each texture in the map + for (int y = 0; y < map->getSurfaceH() - 1; y++) { + for (int x = 0; x < map->getSurfaceW() - 1; x++) { + totalCellCount++; + + SurfaceCell *tc[4] = { + map->getSurfaceCell(x,y), + map->getSurfaceCell(x + 1,y), + map->getSurfaceCell(x,y + 1), + map->getSurfaceCell(x + 1,y + 1) + }; + int textureHandle = static_cast(tc[0]->getSurfaceTexture())->getHandle(); + string texturePath = static_cast(tc[0]->getSurfaceTexture())->getPath(); + //int32 textureCRC = CalculatePixelsCRC(static_cast(tc[0]->getSurfaceTexture())); + Layer* layer = NULL; + for (Layers::iterator it = layers.begin(); it != layers.end(); ++it) { + if ((*it)->textureHandle == textureHandle) { + //if((*it)->texturePath == texturePath) { + //if((*it)->textureCRC == textureCRC) { + layer = *it; + break; + } + } + if (!layer) { + layer = new Layer(textureHandle); + layer->texturePath = texturePath; + //layer->textureCRC = textureCRC; + layers.push_back(layer); + + //printf("Ading new unique texture [%s]\n",texturePath.c_str()); + } + // we'll be super-lazy and re-emit all four corners just because its easier + int index[4]; + int loopIndexes[4] = { 2,0,3,1 }; + for (int i = 0; i < 4; i++) { + index[i] = (int) layer->vertices.size(); + SurfaceCell *corner = tc[loopIndexes[i]]; + layer->vertices.push_back(corner->getVertex()); + layer->normals.push_back(corner->getNormal()); + } + + // the texture coords are all on the current texture obviously + layer->fowTexCoords.push_back(tc[loopIndexes[0]]->getFowTexCoord()); + layer->fowTexCoords.push_back(tc[loopIndexes[1]]->getFowTexCoord()); + layer->fowTexCoords.push_back(tc[loopIndexes[2]]->getFowTexCoord()); + layer->fowTexCoords.push_back(tc[loopIndexes[3]]->getFowTexCoord()); + + layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord() + Vec2f(0, coordStep)); + layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord() + Vec2f(0, 0)); + layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord() + Vec2f(coordStep, coordStep)); + layer->surfTexCoords.push_back(tc[0]->getSurfTexCoord() + Vec2f(coordStep, 0)); + + layer->cellToIndicesMap[Vec2i(x, y)] = (int) layer->indices.size(); + + // and make two triangles (no strip, we may be disjoint) + layer->indices.push_back(index[0]); + layer->indices.push_back(index[1]); + layer->indices.push_back(index[2]); + layer->indices.push_back(index[1]); + layer->indices.push_back(index[3]); + layer->indices.push_back(index[2]); + } + } + // turn them into vbos + for (Layers::iterator layer = layers.begin(); layer != layers.end(); ++layer) { + (*layer)->load_vbos(true); + } + + //printf("Total # of layers for this map = %d totalCellCount = %d overall render reduction ratio = %d times\n",layers.size(),totalCellCount,(totalCellCount / layers.size())); + } + + template void* _bindVBO(GLuint vbo, std::vector &buf, int target = GL_ARRAY_BUFFER_ARB) { + void* result = NULL; + if (vbo) { + glBindBuffer(target, vbo); + } else { + result = &buf[0]; + } + return result; + } + + void Renderer::MapRenderer::Layer::renderVisibleLayer() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + //glBindTexture(GL_TEXTURE_2D, static_cast(fowTex)->getHandle()); + glClientActiveTexture(Renderer::fowTexUnit); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, &fowTexCoords[0]); + + glBindTexture(GL_TEXTURE_2D, textureHandle); + glClientActiveTexture(Renderer::baseTexUnit); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, &surfTexCoords[0]); + + glVertexPointer(3, GL_FLOAT, 0, &vertices[0]); + glNormalPointer(GL_FLOAT, 0, &normals[0]); + + //glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size()); + //unsigned short faceIndices[4] = {0, 1, 2, 3}; + //glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, &faceIndices[0]); + glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, &indices[0]); + + glClientActiveTexture(Renderer::fowTexUnit); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(Renderer::baseTexUnit); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + + void Renderer::MapRenderer::Layer::render(VisibleQuadContainerCache &qCache) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + // const bool renderOnlyVisibleQuad = true; + // + // if(renderOnlyVisibleQuad == true) { + vector > rowsToRender; + + if (rowsToRenderCache.find(qCache.lastVisibleQuad) != rowsToRenderCache.end()) { + rowsToRender = rowsToRenderCache[qCache.lastVisibleQuad]; + } else { + int startIndex = -1; + int lastValidIndex = -1; + + for (int visibleIndex = 0; + visibleIndex < (int) qCache.visibleScaledCellList.size(); ++visibleIndex) { + Vec2i &pos = qCache.visibleScaledCellList[visibleIndex]; + + if (cellToIndicesMap.find(pos) != cellToIndicesMap.end()) { + //printf("Layer Render, visibleindex = %d pos [%s] cellToIndicesMap[pos] = %d lastValidIndex = %d\n",visibleIndex,pos.getString().c_str(),cellToIndicesMap[pos],lastValidIndex); + + if (startIndex < 0 || cellToIndicesMap[pos] == lastValidIndex + 6) { + lastValidIndex = cellToIndicesMap[pos]; + if (startIndex < 0) { + startIndex = lastValidIndex; + } + } else if (startIndex >= 0) { + rowsToRender.push_back(make_pair(startIndex, lastValidIndex)); + + lastValidIndex = cellToIndicesMap[pos]; + startIndex = lastValidIndex; + } + } + } + if (startIndex >= 0) { + rowsToRender.push_back(make_pair(startIndex, lastValidIndex)); + } + + rowsToRenderCache[qCache.lastVisibleQuad] = rowsToRender; + } + + if (rowsToRender.empty() == false) { + //printf("Layer has %d rows in visible quad, visible quad has %d cells\n",rowsToRender.size(),qCache.visibleScaledCellList.size()); + + glVertexPointer(3, GL_FLOAT, 0, _bindVBO(vbo_vertices, vertices)); + glNormalPointer(GL_FLOAT, 0, _bindVBO(vbo_normals, normals)); + + glClientActiveTexture(Renderer::fowTexUnit); + glTexCoordPointer(2, GL_FLOAT, 0, _bindVBO(vbo_fowTexCoords, fowTexCoords)); + + glClientActiveTexture(Renderer::baseTexUnit); + glBindTexture(GL_TEXTURE_2D, textureHandle); + glTexCoordPointer(2, GL_FLOAT, 0, _bindVBO(vbo_surfTexCoords, surfTexCoords)); + + for (unsigned int i = 0; i < rowsToRender.size(); ++i) { + //glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,_bindVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB)); + glDrawRangeElements(GL_TRIANGLES, rowsToRender[i].first, rowsToRender[i].second, indexCount, GL_UNSIGNED_INT, _bindVBO(vbo_indices, indices, GL_ELEMENT_ARRAY_BUFFER_ARB)); + } + } + // } + // else { + // glVertexPointer(3,GL_FLOAT,0,_bindVBO(vbo_vertices,vertices)); + // glNormalPointer(GL_FLOAT,0,_bindVBO(vbo_normals,normals)); + // + // glClientActiveTexture(Renderer::fowTexUnit); + // glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_fowTexCoords,fowTexCoords)); + // + // glClientActiveTexture(Renderer::baseTexUnit); + // glBindTexture(GL_TEXTURE_2D,textureHandle); + // glTexCoordPointer(2,GL_FLOAT,0,_bindVBO(vbo_surfTexCoords,surfTexCoords)); + // + // glDrawElements(GL_TRIANGLES,indexCount,GL_UNSIGNED_INT,_bindVBO(vbo_indices,indices,GL_ELEMENT_ARRAY_BUFFER_ARB)); + // } + } + + void Renderer::MapRenderer::renderVisibleLayers(const Map* map, float coordStep, VisibleQuadContainerCache &qCache) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (map != this->map) { + //printf("New Map loading\n"); + destroy(); // clear any previous map data + this->map = map; + loadVisibleLayers(coordStep, qCache); + } else if (lastVisibleQuad != qCache.lastVisibleQuad) { + //printf("New Visible Quad loading\n"); + destroy(); // clear any previous map data + this->map = map; + loadVisibleLayers(coordStep, qCache); + } + + lastVisibleQuad = qCache.lastVisibleQuad; + //printf("About to render %d layers\n",layers.size()); + + glClientActiveTexture(fowTexUnit); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(baseTexUnit); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + for (Layers::iterator layer = layers.begin(); layer != layers.end(); ++layer) + (*layer)->renderVisibleLayer(); + glDisableClientState(GL_VERTEX_ARRAY); + glBindBuffer(GL_ARRAY_BUFFER_ARB, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + glDisableClientState(GL_NORMAL_ARRAY); + glClientActiveTexture(fowTexUnit); + glBindTexture(GL_TEXTURE_2D, 0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(baseTexUnit); + glBindTexture(GL_TEXTURE_2D, 0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + assertGl(); + } + + void Renderer::MapRenderer::render(const Map* map, float coordStep, VisibleQuadContainerCache &qCache) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (map != this->map) { + destroy(); // clear any previous map data + this->map = map; + load(coordStep); + } + + //printf("About to render %d layers\n",layers.size()); + + glClientActiveTexture(fowTexUnit); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(baseTexUnit); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + for (Layers::iterator layer = layers.begin(); layer != layers.end(); ++layer) + (*layer)->render(qCache); + glDisableClientState(GL_VERTEX_ARRAY); + glBindBuffer(GL_ARRAY_BUFFER_ARB, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + glDisableClientState(GL_NORMAL_ARRAY); + glClientActiveTexture(fowTexUnit); + glBindTexture(GL_TEXTURE_2D, 0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(baseTexUnit); + glBindTexture(GL_TEXTURE_2D, 0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + assertGl(); + } + + void Renderer::MapRenderer::destroy() { + while (layers.empty() == false) { + delete layers.back(); + layers.pop_back(); + } + map = NULL; + } + + void Renderer::renderSurface(const int renderFps) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + IF_DEBUG_EDITION( + if (getDebugRenderer().willRenderSurface()) { + getDebugRenderer().renderSurface(visibleQuad / Map::cellScale); + } else { + ) + assertGl(); + + const World *world = game->getWorld(); + const Map *map = world->getMap(); + float coordStep = world->getTileset()->getSurfaceAtlas()->getCoordStep(); + + const Texture2D *fowTex = world->getMinimap()->getFowTexture(); + if (fowTex == NULL) { + return; + } + + glPushAttrib(GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_FOG_BIT | GL_TEXTURE_BIT); + + glEnable(GL_BLEND); + glEnable(GL_COLOR_MATERIAL); + glDisable(GL_ALPHA_TEST); + glEnable(GL_CULL_FACE); + + //fog of war tex unit + glActiveTexture(fowTexUnit); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, static_cast(fowTex)->getHandle()); + + glTexSubImage2D( + GL_TEXTURE_2D, 0, 0, 0, + fowTex->getPixmapConst()->getW(), fowTex->getPixmapConst()->getH(), + GL_ALPHA, GL_UNSIGNED_BYTE, fowTex->getPixmapConst()->getPixels()); + + if (shadowsOffDueToMinRender == false) { + //shadow texture + if (shadows == sProjected || shadows == sShadowMapping) { + glActiveTexture(shadowTexUnit); + glEnable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, shadowMapHandle); + + static_cast(modelRenderer)->setDuplicateTexCoords(true); + enableProjectiveTexturing(); + } + } + + const Rect2i mapBounds(0, 0, map->getSurfaceW() - 1, map->getSurfaceH() - 1); + + glActiveTexture(baseTexUnit); + + VisibleQuadContainerCache &qCache = getQuadCache(); + + bool useVBORendering = getVBOSupported(); + if (useVBORendering == true) { + VisibleQuadContainerCache &qCache = getQuadCache(); + //mapRenderer.render(map,coordStep,qCache); + mapRenderer.renderVisibleLayers(map, coordStep, qCache); + } else if (qCache.visibleScaledCellList.empty() == false) { + + int lastTex = -1; + //int currTex=-1; + + //Quad2i snapshotOfvisibleQuad = visibleQuad; + + //bool useVertexArrayRendering = getVBOSupported(); + //bool useVertexArrayRendering = false; + //if(useVertexArrayRendering == false) { + //printf("\LEGACY qCache.visibleScaledCellList.size() = %d \n",qCache.visibleScaledCellList.size()); + + Vec2f texCoords[4]; + Vec2f texCoordsSurface[4]; + Vec3f vertices[4]; + Vec3f normals[4]; + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + std::map uniqueVisibleTextures; + for (int visibleIndex = 0; + visibleIndex < (int) qCache.visibleScaledCellList.size(); ++visibleIndex) { + Vec2i &pos = qCache.visibleScaledCellList[visibleIndex]; + SurfaceCell *tc00 = map->getSurfaceCell(pos.x, pos.y); + int cellTex = static_cast(tc00->getSurfaceTexture())->getHandle(); + + uniqueVisibleTextures[cellTex]++; + } + + //printf("Current renders = %d possible = %d\n",qCache.visibleScaledCellList.size(),uniqueVisibleTextures.size()); + + for (int visibleIndex = 0; + visibleIndex < (int) qCache.visibleScaledCellList.size(); ++visibleIndex) { + Vec2i &pos = qCache.visibleScaledCellList[visibleIndex]; + + SurfaceCell *tc00 = map->getSurfaceCell(pos.x, pos.y); + SurfaceCell *tc10 = map->getSurfaceCell(pos.x + 1, pos.y); + SurfaceCell *tc01 = map->getSurfaceCell(pos.x, pos.y + 1); + SurfaceCell *tc11 = map->getSurfaceCell(pos.x + 1, pos.y + 1); + + if (tc00 == NULL) { + throw megaglest_runtime_error("tc00 == NULL"); + } + if (tc10 == NULL) { + throw megaglest_runtime_error("tc10 == NULL"); + } + if (tc01 == NULL) { + throw megaglest_runtime_error("tc01 == NULL"); + } + if (tc11 == NULL) { + throw megaglest_runtime_error("tc11 == NULL"); + } + + triangleCount += 2; + pointCount += 4; + + //set texture + if (tc00->getSurfaceTexture() == NULL) { + throw megaglest_runtime_error("tc00->getSurfaceTexture() == NULL"); + } + int currTex = static_cast(tc00->getSurfaceTexture())->getHandle(); + if (currTex != lastTex) { + lastTex = currTex; + //glBindTexture(GL_TEXTURE_2D, lastTex); + } + + const Vec2f &surfCoord = tc00->getSurfTexCoord(); + + texCoords[0] = tc01->getFowTexCoord(); + texCoordsSurface[0] = Vec2f(surfCoord.x, surfCoord.y + coordStep); + vertices[0] = tc01->getVertex(); + normals[0] = tc01->getNormal();; + + texCoords[1] = tc00->getFowTexCoord(); + texCoordsSurface[1] = Vec2f(surfCoord.x, surfCoord.y); + vertices[1] = tc00->getVertex(); + normals[1] = tc00->getNormal(); + + texCoords[2] = tc11->getFowTexCoord(); + texCoordsSurface[2] = Vec2f(surfCoord.x + coordStep, surfCoord.y + coordStep); + vertices[2] = tc11->getVertex(); + normals[2] = tc11->getNormal(); + + texCoords[3] = tc10->getFowTexCoord(); + texCoordsSurface[3] = Vec2f(surfCoord.x + coordStep, surfCoord.y); + vertices[3] = tc10->getVertex(); + normals[3] = tc10->getNormal(); + + //glBindTexture(GL_TEXTURE_2D, static_cast(fowTex)->getHandle()); + glClientActiveTexture(fowTexUnit); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, &texCoords[0]); + + glBindTexture(GL_TEXTURE_2D, lastTex); + glClientActiveTexture(baseTexUnit); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, &texCoordsSurface[0]); + + glVertexPointer(3, GL_FLOAT, 0, &vertices[0]); + glNormalPointer(GL_FLOAT, 0, &normals[0]); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + //unsigned short faceIndices[4] = {0, 1, 2, 3}; + //glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, &faceIndices[0]); + + glClientActiveTexture(fowTexUnit); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTexture(baseTexUnit); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + /* + glBegin(GL_TRIANGLE_STRIP); + + //draw quad using immediate mode + glMultiTexCoord2fv(fowTexUnit, tc01->getFowTexCoord().ptr()); + glMultiTexCoord2f(baseTexUnit, surfCoord.x, surfCoord.y + coordStep); + glNormal3fv(tc01->getNormal().ptr()); + glVertex3fv(tc01->getVertex().ptr()); + + glMultiTexCoord2fv(fowTexUnit, tc00->getFowTexCoord().ptr()); + glMultiTexCoord2f(baseTexUnit, surfCoord.x, surfCoord.y); + glNormal3fv(tc00->getNormal().ptr()); + glVertex3fv(tc00->getVertex().ptr()); + + glMultiTexCoord2fv(fowTexUnit, tc11->getFowTexCoord().ptr()); + glMultiTexCoord2f(baseTexUnit, surfCoord.x+coordStep, surfCoord.y+coordStep); + glNormal3fv(tc11->getNormal().ptr()); + glVertex3fv(tc11->getVertex().ptr()); + + glMultiTexCoord2fv(fowTexUnit, tc10->getFowTexCoord().ptr()); + glMultiTexCoord2f(baseTexUnit, surfCoord.x + coordStep, surfCoord.y); + glNormal3fv(tc10->getNormal().ptr()); + glVertex3fv(tc10->getVertex().ptr()); + + glEnd(); + */ + } + + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + // } + // else { + // const bool useVBOs = false; + // const bool useSurfaceCache = false; + // + // std::vector surfaceData; + // bool recalcSurface = false; + // + // if(useSurfaceCache == true) { + // std::map > >::iterator iterFind = mapSurfaceData.find(snapshotOfvisibleQuad.getString()); + // if(iterFind == mapSurfaceData.end()) { + // recalcSurface = true; + // //printf("#1 Calculating surface for Rendering using VA's [%s]\n",snapshotOfvisibleQuad.getString().c_str()); + // } + ///* + // else if(iterFind->second.first.getMillis() >= 250) { + // recalcSurface = true; + // mapSurfaceData.erase(snapshotOfvisibleQuad.getString()); + // //printf("#2 RE-Calculating surface for Rendering using VA's [%s]\n",snapshotOfvisibleQuad.getString().c_str()); + // } + //*/ + // } + // else { + // recalcSurface = true; + // } + // + // if(recalcSurface == true) { + // //printf("Calculating surface for Rendering using VA's [%s]\n",snapshotOfvisibleQuad.getString().c_str()); + // + // std::vector *surface = &surfaceData; + // if(useSurfaceCache == true) { + // std::pair > &surfaceCacheEntity = mapSurfaceData[snapshotOfvisibleQuad.getString()]; + // surface = &surfaceCacheEntity.second; + // //surface.reserve(qCache.visibleScaledCellList.size()); + // } + // surface->reserve(qCache.visibleScaledCellList.size()); + // + // int lastSurfaceDataIndex = -1; + // for(int visibleIndex = 0; + // visibleIndex < (int)qCache.visibleScaledCellList.size(); ++visibleIndex) { + // Vec2i &pos = qCache.visibleScaledCellList[visibleIndex]; + // + // SurfaceCell *tc00= map->getSurfaceCell(pos.x, pos.y); + // SurfaceCell *tc10= map->getSurfaceCell(pos.x+1, pos.y); + // SurfaceCell *tc01= map->getSurfaceCell(pos.x, pos.y+1); + // SurfaceCell *tc11= map->getSurfaceCell(pos.x+1, pos.y+1); + // + // if(tc00 == NULL) { + // throw megaglest_runtime_error("tc00 == NULL"); + // } + // if(tc10 == NULL) { + // throw megaglest_runtime_error("tc10 == NULL"); + // } + // if(tc01 == NULL) { + // throw megaglest_runtime_error("tc01 == NULL"); + // } + // if(tc11 == NULL) { + // throw megaglest_runtime_error("tc11 == NULL"); + // } + // + // triangleCount+= 2; + // pointCount+= 4; + // + // //set texture + // if(tc00->getSurfaceTexture() == NULL) { + // throw megaglest_runtime_error("tc00->getSurfaceTexture() == NULL"); + // } + // + // int surfaceDataIndex = -1; + // currTex= static_cast(tc00->getSurfaceTexture())->getHandle(); + // if(currTex != lastTex) { + // lastTex = currTex; + // } + // else { + // surfaceDataIndex = lastSurfaceDataIndex; + // } + // + // if(surfaceDataIndex < 0) { + // SurfaceData newData; + // newData.uniqueId = SurfaceData::nextUniqueId; + // SurfaceData::nextUniqueId++; + // newData.bufferCount=0; + // newData.textureHandle = currTex; + // surface->push_back(newData); + // + // surfaceDataIndex = (int)surface->size() - 1; + // } + // + // lastSurfaceDataIndex = surfaceDataIndex; + // + // SurfaceData *cellData = &(*surface)[surfaceDataIndex]; + // + // const Vec2f &surfCoord= tc00->getSurfTexCoord(); + // + // cellData->texCoords.push_back(tc01->getFowTexCoord()); + // cellData->texCoordsSurface.push_back(Vec2f(surfCoord.x, surfCoord.y + coordStep)); + // cellData->vertices.push_back(tc01->getVertex()); + // cellData->normals.push_back(tc01->getNormal()); + // cellData->bufferCount++; + // + // cellData->texCoords.push_back(tc00->getFowTexCoord()); + // cellData->texCoordsSurface.push_back(Vec2f(surfCoord.x, surfCoord.y)); + // cellData->vertices.push_back(tc00->getVertex()); + // cellData->normals.push_back(tc00->getNormal()); + // cellData->bufferCount++; + // + // cellData->texCoords.push_back(tc11->getFowTexCoord()); + // cellData->texCoordsSurface.push_back(Vec2f(surfCoord.x+coordStep, surfCoord.y+coordStep)); + // cellData->vertices.push_back(tc11->getVertex()); + // cellData->normals.push_back(tc11->getNormal()); + // cellData->bufferCount++; + // + // cellData->texCoords.push_back(tc10->getFowTexCoord()); + // cellData->texCoordsSurface.push_back(Vec2f(surfCoord.x+coordStep, surfCoord.y)); + // cellData->vertices.push_back(tc10->getVertex()); + // cellData->normals.push_back(tc10->getNormal()); + // cellData->bufferCount++; + // } + // } + // + // std::vector *surface = &surfaceData; + // if(useSurfaceCache == true) { + // std::pair > &surfaceCacheEntity = mapSurfaceData[snapshotOfvisibleQuad.getString()]; + // surface = &surfaceCacheEntity.second; + // } + // + // glEnableClientState(GL_VERTEX_ARRAY); + // glEnableClientState(GL_NORMAL_ARRAY); + // + // for(int i = 0; i < (int)surface->size(); ++i) { + // SurfaceData &data = (*surface)[i]; + // + // if(useVBOs == true) { + // VisibleQuadContainerVBOCache *vboCache = GetSurfaceVBOs(&data); + // + // //glBindTexture(GL_TEXTURE_2D, static_cast(fowTex)->getHandle()); + // glClientActiveTexture(fowTexUnit); + // glEnableClientState(GL_TEXTURE_COORD_ARRAY); + // + // glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache->m_nVBOFowTexCoords); + // glTexCoordPointer(2, GL_FLOAT, 0,(char *) NULL); + // + // glBindTexture(GL_TEXTURE_2D, data.textureHandle); + // glClientActiveTexture(baseTexUnit); + // glEnableClientState(GL_TEXTURE_COORD_ARRAY); + // + // glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache->m_nVBOSurfaceTexCoords); + // glTexCoordPointer(2, GL_FLOAT, 0, (char *) NULL); + // + // glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache->m_nVBOVertices); + // glVertexPointer(3, GL_FLOAT, 0, (char *) NULL); + // + // glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboCache->m_nVBONormals); + // glNormalPointer(GL_FLOAT, 0, (char *) NULL); + // + // glDrawArrays(GL_TRIANGLE_STRIP, 0, data.bufferCount); + // + // glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); + // + // glClientActiveTexture(fowTexUnit); + // glDisableClientState(GL_TEXTURE_COORD_ARRAY); + // glClientActiveTexture(baseTexUnit); + // glDisableClientState(GL_TEXTURE_COORD_ARRAY); + // + // } + // else { + // Vec2f *texCoords = &data.texCoords[0]; + // Vec2f *texCoordsSurface = &data.texCoordsSurface[0]; + // Vec3f *vertices = &data.vertices[0]; + // Vec3f *normals = &data.normals[0]; + // + // //glBindTexture(GL_TEXTURE_2D, static_cast(fowTex)->getHandle()); + // glClientActiveTexture(fowTexUnit); + // glEnableClientState(GL_TEXTURE_COORD_ARRAY); + // glTexCoordPointer(2, GL_FLOAT, 0,texCoords); + // + // glBindTexture(GL_TEXTURE_2D, data.textureHandle); + // glClientActiveTexture(baseTexUnit); + // glEnableClientState(GL_TEXTURE_COORD_ARRAY); + // glTexCoordPointer(2, GL_FLOAT, 0, texCoordsSurface); + // + // glVertexPointer(3, GL_FLOAT, 0, vertices); + // glNormalPointer(GL_FLOAT, 0, normals); + // + // glDrawArrays(GL_TRIANGLE_STRIP, 0, data.bufferCount); + // + // glClientActiveTexture(fowTexUnit); + // glDisableClientState(GL_TEXTURE_COORD_ARRAY); + // glClientActiveTexture(baseTexUnit); + // glDisableClientState(GL_TEXTURE_COORD_ARRAY); + // } + // } + // + // glDisableClientState(GL_NORMAL_ARRAY); + // glDisableClientState(GL_VERTEX_ARRAY); + // + // //printf("Surface Render before [%d] after [%d]\n",qCache.visibleScaledCellList.size(),surface.size()); + // } + } + + //Restore + static_cast(modelRenderer)->setDuplicateTexCoords(false); + + glDisable(GL_TEXTURE_2D); + + glPopAttrib(); + + //assert + GLenum glresult = glGetError(); //remove when first mtex problem solved + if (glresult) { + assertGl(); + } + assertGl(); + + IF_DEBUG_EDITION( + } // end else, if not renderering debug textures instead of regular terrain + getDebugRenderer().renderEffects(visibleQuad / Map::cellScale); + ) + } + + void Renderer::renderObjects(const int renderFps) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + const World *world = game->getWorld(); + //const Map *map= world->getMap(); + + Config &config = Config::getInstance(); + int tilesetObjectsToAnimate = config.getInt("AnimatedTilesetObjects", "-1"); + + assertGl(); + + const Texture2D *fowTex = world->getMinimap()->getFowTexture(); + const Pixmap2D *fowTexPixmap = fowTex->getPixmapConst(); + Vec3f baseFogColor = world->getTileset()->getFogColor() * world->getTimeFlow()->computeLightColor(); + + bool modelRenderStarted = false; + + VisibleQuadContainerCache &qCache = getQuadCache(); + + // for(int visibleIndex = 0; + // visibleIndex < qCache.visibleObjectList.size(); ++visibleIndex) { + // render from last to first object so animated objects which are on bottom of screen are + // rendered first which looks better for limited number of animated tileset objects + for (int visibleIndex = (int) qCache.visibleObjectList.size() - 1; + visibleIndex >= 0; --visibleIndex) { + Object *o = qCache.visibleObjectList[visibleIndex]; + + Model *objModel = o->getModelPtr(); + //objModel->updateInterpolationData(o->getAnimProgress(), true); + const Vec3f v = o->getConstPos(); + + if (modelRenderStarted == false) { + modelRenderStarted = true; + + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_FOG_BIT | GL_LIGHTING_BIT | GL_TEXTURE_BIT); + + if (shadowsOffDueToMinRender == false && + shadows == sShadowMapping) { glActiveTexture(shadowTexUnit); glEnable(GL_TEXTURE_2D); @@ -5353,4770 +4856,5139 @@ void Renderer::renderUnits(bool airUnits, const int renderFps) { static_cast(modelRenderer)->setDuplicateTexCoords(true); enableProjectiveTexturing(); } + + glActiveTexture(baseTexUnit); + glEnable(GL_COLOR_MATERIAL); + glAlphaFunc(GL_GREATER, 0.5f); + + modelRenderer->begin(true, true, false, false); } - glActiveTexture(baseTexUnit); + //ambient and diffuse color is taken from cell color - modelRenderer->begin(true, true, true, false, &meshCallbackTeamColor); - } - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - - //translate - Vec3f currVec= unit->getCurrVectorFlat(); - glTranslatef(currVec.x, currVec.y, currVec.z); - - //rotate - float zrot=unit->getRotationZ(); - float xrot=unit->getRotationX(); - if(zrot!=.0f){ - glRotatef(zrot, 0.f, 0.f, 1.f); - } - if(xrot!=.0f){ - glRotatef(xrot, 1.f, 0.f, 0.f); - } - glRotatef(unit->getRotation(), 0.f, 1.f, 0.f); - - //dead alpha - const SkillType *st= unit->getCurrSkill(); - if(st->getClass() == scDie && static_cast(st)->getFade()) { - float alpha= 1.0f - unit->getAnimProgressAsFloat(); - glDisable(GL_COLOR_MATERIAL); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Vec4f(1.0f, 1.0f, 1.0f, alpha).ptr()); - } - else { - glEnable(GL_COLOR_MATERIAL); - // we cut off a tiny bit here to avoid problems with fully transparent texture parts cutting units in background rendered later. - glAlphaFunc(GL_GREATER, 0.02f); - } - - //render - Model *model= unit->getCurrentModelPtr(); - //printf("Rendering model [%d - %s]\n[%s]\nCamera [%s]\nDistance: %f\n",unit->getId(),unit->getType()->getName().c_str(),unit->getCurrVector().getString().c_str(),this->gameCamera->getPos().getString().c_str(),this->gameCamera->getPos().dist(unit->getCurrVector())); - - //if(this->gameCamera->getPos().dist(unit->getCurrVector()) <= SKIP_INTERPOLATION_DISTANCE) { - model->updateInterpolationData(unit->getAnimProgressAsFloat(), unit->isAlive() && !unit->isAnimProgressBound()); - //} - - modelRenderer->render(model); - triangleCount+= model->getTriangleCount(); - pointCount+= model->getVertexCount(); - - glPopMatrix(); - unit->setVisible(true); - - if( showDebugUI == true && - (showDebugUILevel & debugui_unit_titles) == debugui_unit_titles) { - - unit->setScreenPos(computeScreenPosition(currVec)); - visibleFrameUnitList.push_back(unit); - visibleFrameUnitListCameraKey = game->getGameCamera()->getCameraMovementKey(); - } - } - - if(modelRenderStarted == true) { - modelRenderer->end(); - glPopAttrib(); - } - } - - //restore - static_cast(modelRenderer)->setDuplicateTexCoords(true); - - // reset alpha - glAlphaFunc(GL_GREATER, 0.0f); - //assert - assertGl(); - -} - -void Renderer::renderUnitsToBuild(const int renderFps) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - //assert - assertGl(); - - VisibleQuadContainerCache &qCache = getQuadCache(); - if(qCache.visibleQuadUnitBuildList.empty() == false) { - - glMatrixMode(GL_MODELVIEW); - glPushAttrib(GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_BLEND); - glDisable(GL_STENCIL_TEST); - glDepthFunc(GL_LESS); - glEnable(GL_COLOR_MATERIAL); - glDepthMask(GL_FALSE); - - modelRenderer->begin(true, true, false, false); - - for(int visibleUnitIndex = 0; - visibleUnitIndex < (int)qCache.visibleQuadUnitBuildList.size(); ++visibleUnitIndex) { - const UnitBuildInfo &buildUnit = qCache.visibleQuadUnitBuildList[visibleUnitIndex]; - //Vec4f modelColor= Vec4f(0.f, 1.f, 0.f, 0.5f); - const Vec3f teamColor = buildUnit.unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0); - Vec4f modelColor= Vec4f(teamColor.x,teamColor.y,teamColor.z,0.4f); - renderGhostModel(buildUnit.buildUnit, buildUnit.pos, buildUnit.facing, &modelColor); - - //printf("Rendering to build unit index = %d\n",visibleUnitIndex); - } - - modelRenderer->end(); - - glDisable(GL_COLOR_MATERIAL); - glPopAttrib(); - } - - //assert - assertGl(); - -} - -void Renderer::renderTeamColorEffect(Vec3f &v, int heigth, int size, Vec3f color, const Texture2D *texture) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - //GLUquadricObj *disc; - float halfSize=size; - //halfSize=halfSize; - float heigthoffset=0.5+heigth%25*0.004; - glPushMatrix(); - glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getHandle()); - glColor4f(color.x, color.y, color.z, 1.0f); - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2i(0, 1); - glVertex3f(v.x-halfSize,v.y+heigthoffset,v.z+halfSize); - glTexCoord2i(0, 0); - glVertex3f(v.x-halfSize,v.y+heigthoffset, v.z-halfSize); - glTexCoord2i(1, 1); - - glVertex3f(v.x+halfSize,v.y+heigthoffset, v.z+halfSize); - glTexCoord2i(1, 0); - glVertex3f(v.x+halfSize,v.y+heigthoffset, v.z-halfSize); - glEnd(); - glPopMatrix(); - -} - -void Renderer::renderMorphEffects(){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - VisibleQuadContainerCache &qCache = getQuadCache(); - if(qCache.visibleQuadUnitList.empty() == false) { - bool initialized=false; - int frameCycle=0; - for(int visibleUnitIndex = 0; - visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { - Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; - if(unit->getCurrSkill() != NULL && unit->getCurrSkill()->getClass() == scMorph) { - Command *command= unit->getCurrCommand(); - if(command != NULL && command->getCommandType()->commandTypeClass == ccMorph){ - const MorphCommandType *mct= static_cast(command->getCommandType()); - const UnitType* mType=mct->getMorphUnit(); - - if(mType->getSize()>unit->getType()->getSize() || - mType->getField()!=unit->getType()->getField()){ - if(!initialized){ - const World *world= game->getWorld(); - frameCycle=world->getFrameCount() % 40; - - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); - glDisable(GL_LIGHTING); - glDisable(GL_TEXTURE_2D); - glDepthFunc(GL_ALWAYS); - glDisable(GL_STENCIL_TEST); - glDisable(GL_CULL_FACE); - glEnable(GL_BLEND); - glLineWidth(2.f); - initialized=true; - } - - Vec3f currVec= unit->getCurrVectorFlat(); - currVec=Vec3f(currVec.x,currVec.y+0.3f,currVec.z); - if(mType->getField() == fAir && unit->getType()->getField()== fLand) { - currVec=Vec3f(currVec.x,currVec.y+game->getWorld()->getTileset()->getAirHeight(),currVec.z); - } - if(mType->getField() == fLand && unit->getType()->getField()== fAir) { - currVec=Vec3f(currVec.x,currVec.y-game->getWorld()->getTileset()->getAirHeight(),currVec.z); - } - - float color=frameCycle*0.4f/40; - glColor4f(color,color, 0.4f, 0.4f); - renderSelectionCircle(currVec, mType->getSize(), frameCycle*0.85f/40, 0.2f); - } - } - } - } - if(initialized) { - glPopAttrib(); - } - } -} - - - -void Renderer::renderSelectionEffects(int healthbarMode) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - Config &config= Config::getInstance(); - if(config.getBool("RecordMode","false") == true) { - return; - } - - const World *world= game->getWorld(); - const Map *map= world->getMap(); - const Selection *selection= game->getGui()->getSelection(); - const Object *selectedResourceObject= game->getGui()->getSelectedResourceObject(); - - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); - glDisable(GL_LIGHTING); - glDisable(GL_TEXTURE_2D); - glDepthFunc(GL_ALWAYS); - glDisable(GL_STENCIL_TEST); - glDisable(GL_CULL_FACE); - glEnable(GL_BLEND); - glLineWidth(2.f); - - //units - for(int i=0; igetCount(); ++i){ - - const Unit *unit= selection->getUnit(i); - if(unit != NULL) { - //translate - Vec3f currVec= unit->getCurrVectorFlat(); - currVec.y+= 0.3f; - - //selection circle - int finalHealthbarMode = hbvUndefined; - if(healthbarMode == hbvUndefined) { - finalHealthbarMode = unit->getFaction()->getType()->getHealthbarVisible(); - } - else { - finalHealthbarMode = healthbarMode; - } - bool healthbarsVisible =((finalHealthbarMode & hbvAlways) || - (finalHealthbarMode & hbvSelected) || - (finalHealthbarMode & hbvIfNeeded)); - float selectionCircleThickness = 0.2f; - float hpRatio = unit->getHpRatio(); - if(healthbarsVisible) { - selectionCircleThickness = 0.05f; - hpRatio = 1.0f; - } - - if(world->getThisFactionIndex() == unit->getFactionIndex()) { - if( showDebugUI == true && - ((showDebugUILevel & debugui_unit_titles) == debugui_unit_titles) && - unit->getCommandSize() > 0 && - dynamic_cast(unit->getCurrCommand()->getCommandType()) != NULL) { - glColor4f(hpRatio, hpRatio, hpRatio, 0.3f); - } - else { - glColor4f(0, hpRatio, 0, 0.3f); - } - } - else if ( world->getThisTeamIndex() == unit->getTeam()) { - glColor4f(hpRatio, hpRatio, 0, 0.3f); - } - else { - glColor4f(hpRatio, 0, 0, 0.3f); - } - renderSelectionCircle(currVec, unit->getType()->getSize(), selectionCircleRadius,selectionCircleThickness); - - if( showDebugUI == true && - (showDebugUILevel & debugui_unit_titles) == debugui_unit_titles) { - - const UnitPathInterface *path= unit->getPath(); - const UnitPathBasic *pathfinder = (path == NULL ? NULL : dynamic_cast(path)); - if(pathfinder != NULL) { - vector pathList = pathfinder->getQueue(); - - Vec2i lastPosValue; - for(int i = 0; i < (int)pathList.size(); ++i) { - Vec2i curPosValue = pathList[i]; - if(i == 0) { - lastPosValue = curPosValue; - } - Vec3f currVec2 = unit->getVectorFlat(lastPosValue,curPosValue); - currVec2.y+= 0.3f; - renderSelectionCircle(currVec2, 1, selectionCircleRadius); - } - } - } - - //magic circle - if(!healthbarsVisible && world->getThisFactionIndex() == unit->getFactionIndex() && unit->getType()->getMaxEp() > 0) { - glColor4f(unit->getEpRatio()/2.f, unit->getEpRatio(), unit->getEpRatio(), 0.5f); - renderSelectionCircle(currVec, unit->getType()->getSize(), magicCircleRadius); - } - - // Render Attack-boost circles - if(showDebugUI == true) { - //const std::pair > ¤tAttackBoostUnits = unit->getCurrentAttackBoostUnits(); - const UnitAttackBoostEffectOriginator &effect = unit->getAttackBoostOriginatorEffect(); - - if(effect.skillType->isAttackBoostEnabled() == true) { - glColor4f(MAGENTA.x,MAGENTA.y,MAGENTA.z,MAGENTA.w); - renderSelectionCircle(currVec, 1, effect.skillType->getAttackBoost()->radius, .25f/effect.skillType->getAttackBoost()->radius); - - for(unsigned int i = 0; i < effect.currentAttackBoostUnits.size(); ++i) { - // Remove attack boost upgrades from unit - int findUnitId = effect.currentAttackBoostUnits[i]; - Unit *affectedUnit = game->getWorld()->findUnitById(findUnitId); - if(affectedUnit != NULL) { - Vec3f currVecBoost = affectedUnit->getCurrVectorFlat(); - currVecBoost.y += 0.3f; - - renderSelectionCircle(currVecBoost, affectedUnit->getType()->getSize(), 1.f); - } - } - } - } - - //meeting point arrow - if(unit->getType()->getMeetingPoint()) { - Vec2i pos= unit->getMeetingPos(); - map->clampPos(pos); - - Vec3f arrowTarget= Vec3f(pos.x, map->getCell(pos)->getHeight(), pos.y); - renderArrow(unit->getCurrVectorFlat(), arrowTarget, Vec3f(0.f, 0.f, 1.f), 0.3f); - } - } - } - - if(selectedResourceObject != NULL && selectedResourceObject->getResource() != NULL && selection->getCount() < 1) { - Resource *r= selectedResourceObject->getResource(); - int defaultValue= r->getType()->getDefResPerPatch(); - float colorValue=static_cast(r->getAmount())/static_cast(defaultValue); - glColor4f(0.1f, 0.1f , colorValue, 0.4f); - renderSelectionCircle(selectedResourceObject->getPos(),2, selectionCircleRadius); - } - //target arrow - if(selection->getCount() == 1) { - const Unit *unit= selection->getUnit(0); - if(unit != NULL) { - //comand arrow - if(focusArrows && unit->anyCommand()) { - const CommandType *ct= unit->getCurrCommand()->getCommandType(); - if(ct->getClicks() != cOne){ - - //arrow color - Vec3f arrowColor; - switch(ct->getClass()) { - case ccMove: - arrowColor= Vec3f(0.f, 1.f, 0.f); - break; - case ccAttack: - case ccAttackStopped: - arrowColor= Vec3f(1.f, 0.f, 0.f); - break; - default: - arrowColor= Vec3f(1.f, 1.f, 0.f); - break; - } - - //arrow target - Vec3f arrowTarget; - Command *c= unit->getCurrCommand(); - if(c->getUnit() != NULL) { - arrowTarget= c->getUnit()->getCurrVectorFlat(); - } - else { - Vec2i pos= c->getPos(); - map->clampPos(pos); - - arrowTarget= Vec3f(pos.x, map->getCell(pos)->getHeight(), pos.y); - } - - renderArrow(unit->getCurrVectorFlat(), arrowTarget, arrowColor, 0.3f); - } - } - } - } - - //render selection hightlights - if(game->getGui()->getHighlightedUnit() != NULL) { - const Unit *unit=game->getGui()->getHighlightedUnit() ; - - if(unit->isHighlighted()) { - float highlight= unit->getHightlight(); - if(game->getWorld()->getThisFactionIndex() == unit->getFactionIndex()) { - glColor4f(0.f, 1.f, 0.f, highlight); - } - else{ - glColor4f(1.f, 0.f, 0.f, highlight); - } - - Vec3f v= unit->getCurrVectorFlat(); - v.y+= 0.3f; - renderSelectionCircle(v, unit->getType()->getSize(), 0.5f+0.4f*highlight ); - } - } -// old inefficient way to render highlights -// for(int i=0; i < world->getFactionCount(); ++i) { -// for(int j=0; j < world->getFaction(i)->getUnitCount(); ++j) { -// const Unit *unit= world->getFaction(i)->getUnit(j); -// -// if(unit->isHighlighted()) { -// float highlight= unit->getHightlight(); -// if(game->getWorld()->getThisFactionIndex() == unit->getFactionIndex()) { -// glColor4f(0.f, 1.f, 0.f, highlight); -// } -// else{ -// glColor4f(1.f, 0.f, 0.f, highlight); -// } -// -// Vec3f v= unit->getCurrVectorFlat(); -// v.y+= 0.3f; -// renderSelectionCircle(v, unit->getType()->getSize(), 0.5f+0.4f*highlight ); -// } -// } -// } - //render resource selection highlight - if(game->getGui()->getHighlightedResourceObject() != NULL) { - const Object* object=game->getGui()->getHighlightedResourceObject(); - if(object->isHighlighted()) { - float highlight= object->getHightlight(); - glColor4f(0.1f, 0.1f , 1.0f, highlight); - Vec3f v= object->getPos(); - v.y+= 0.3f; - renderSelectionCircle(v, 2, 0.4f+0.4f*highlight ); - } - } - - glPopAttrib(); -} - -void Renderer::renderHealthBars(int healthbarMode){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - Config &config= Config::getInstance(); - if(config.getBool("RecordMode","false") == true) { - return; - } - - if(config.getBool("PhotoMode")) { - return; - } - - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); - glDisable(GL_LIGHTING); - glDisable(GL_TEXTURE_2D); - glDepthFunc(GL_ALWAYS); - glDisable(GL_STENCIL_TEST); - glDisable(GL_CULL_FACE); - glEnable(GL_BLEND); - glLineWidth(2.f); - - VisibleQuadContainerCache &qCache = getQuadCache(); - if(qCache.visibleQuadUnitList.empty() == false) { - for(int visibleUnitIndex = 0; - visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { - Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; - if(isHealthBarVisible(unit,healthbarMode)) { - float healthbarheight; - float healthbarthickness; - const Texture2D *healthbarTexture; - const Texture2D *healthbarBackgroundTexture; - bool healthbarLineBorder; - - //get settings of the faction - healthbarheight=unit->getFaction()->getType()->getHealthbarHeight(); - healthbarthickness=unit->getFaction()->getType()->getHealthbarThickness(); - healthbarLineBorder=unit->getFaction()->getType()->isHealthbarLineBorder(); - CoreData &coreData= CoreData::getInstance(); - //First try faction texture then use core Texture - if(unit->getFaction()->getType()->isHealthbarBorderTextureEnabled()) { - healthbarTexture=unit->getFaction()->getType()->getHealthbarTexture(); - if(healthbarTexture==NULL) { - healthbarTexture=coreData.getHealthbarTexture(); - } - } else { - healthbarTexture=NULL; - } - if(unit->getFaction()->getType()->isHealthbarBackgroundTextureEnabled()) { - healthbarBackgroundTexture=unit->getFaction()->getType()->getHealthbarBackgroundTexture(); - if(healthbarBackgroundTexture==NULL) { - healthbarBackgroundTexture=coreData.getHealthbarBackgroundTexture(); - } - } else { - healthbarBackgroundTexture=NULL; - } - - //replace them by the ones from the unit if existent - if(unit->getType()->getHealthbarVisible()!=hbvOff && unit->getType()->getHealthbarVisible()!=hbvUndefined) { - if(unit->getType()->getHealthbarHeight()!=-100.0f) { - healthbarheight=unit->getType()->getHealthbarHeight(); - } - if(unit->getType()->getHealthbarThickness()!=-1.0f) { - healthbarthickness=unit->getType()->getHealthbarThickness(); - } - } - - Vec3f currVec= unit->getCurrVectorFlat(); - if(healthbarheight==-100.0f) { - currVec.y+=unit->getType()->getHeight(); - } else { - currVec.y+=healthbarheight; - } - renderHealthBar(currVec,unit,healthbarthickness,healthbarLineBorder,healthbarTexture,healthbarBackgroundTexture); - } - } - } - glPopAttrib(); -} - -bool Renderer::isHealthBarVisible(const Unit *unit,int healthbarMode){ - int healthbarVisible=hbvUndefined; - //check options (hotkey) - if(healthbarMode==hbvUndefined) { - healthbarVisible=unit->getFaction()->getType()->getHealthbarVisible(); - } else { - healthbarVisible=healthbarMode; - } - - //replace them by the ones from the unit if existent - if(unit->getType()->getHealthbarVisible()!=hbvOff && unit->getType()->getHealthbarVisible()!=hbvUndefined) { - if(healthbarMode==hbvUndefined) { //don't override the visible setting when hotkey is not hbvUndefined - healthbarVisible=unit->getType()->getHealthbarVisible(); - } - } - - bool settingsWantToRenderThem=!(healthbarVisible==hbvUndefined || (healthbarVisible&hbvOff)) - && ((healthbarVisible&hbvAlways) - || ((healthbarVisible&hbvIfNeeded) && unit->getHp()getType()->getMaxHp()+unit->getTotalUpgrade()->getMaxHp()) - || ((healthbarVisible&hbvIfNeeded) && unit->getType()->getMaxEp() > 0 && unit->getEp()getType()->getMaxEp()+unit->getTotalUpgrade()->getMaxEp()) - || ((healthbarVisible&hbvIfNeeded) && unit->getProductionPercent() > 0) - || ((healthbarVisible&hbvSelected) && game->getGui()->isSelected(unit))); - - if(unit->isAlive() && (settingsWantToRenderThem)) { - return true; - } - return false; -} - -void Renderer::renderWaterEffects(){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - const World *world= game->getWorld(); - const WaterEffects *we= world->getWaterEffects(); - const Map *map= world->getMap(); - CoreData &coreData= CoreData::getInstance(); - float height= map->getWaterLevel()+0.001f; - - assertGl(); - - glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_BLEND); - glDisable(GL_ALPHA_TEST); - glDepthMask(GL_FALSE); - glDepthFunc(GL_LEQUAL); - glEnable(GL_COLOR_MATERIAL); - - //glNormal3f(0.f, 1.f, 0.f); - - //splashes - glBindTexture(GL_TEXTURE_2D, static_cast(coreData.getWaterSplashTexture())->getHandle()); - - //!!! - Vec2f texCoords[4]; - Vec3f vertices[4]; - Vec3f normals[4]; - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - for(int i=0; igetWaterSplashCount(); ++i){ - const WaterSplash *ws= we->getWaterSplash(i); - - //render only if enabled - if(ws->getEnabled()){ - - //render only if visible - Vec2i intPos= Vec2i(static_cast(ws->getPos().x), static_cast(ws->getPos().y)); - const Vec2i &mapPos = Map::toSurfCoords(intPos); - - bool visible = map->getSurfaceCell(mapPos)->isVisible(world->getThisTeamIndex()); - if(visible == false && world->showWorldForPlayer(world->getThisFactionIndex()) == true) { - visible = true; - } - - if(visible == true) { - float scale= ws->getAnim()*ws->getSize(); - texCoords[0] = Vec2f(0.f, 1.f); - vertices[0] = Vec3f(ws->getPos().x-scale, height, ws->getPos().y+scale); - normals[0] = Vec3f(0.f, 1.f, 0.f); - - texCoords[1] = Vec2f(0.f, 0.f); - vertices[1] = Vec3f(ws->getPos().x-scale, height, ws->getPos().y-scale); - normals[1] = Vec3f(0.f, 1.f, 0.f); - - texCoords[2] = Vec2f(1.f, 1.f); - vertices[2] = Vec3f(ws->getPos().x+scale, height, ws->getPos().y+scale); - normals[2] = Vec3f(0.f, 1.f, 0.f); - - texCoords[3] = Vec2f(1.f, 0.f); - vertices[3] = Vec3f(ws->getPos().x+scale, height, ws->getPos().y-scale); - normals[3] = Vec3f(0.f, 1.f, 0.f); - - glColor4f(1.f, 1.f, 1.f, 1.f - ws->getAnim()); - glTexCoordPointer(2, GL_FLOAT, 0,&texCoords[0]); - glVertexPointer(3, GL_FLOAT, 0, &vertices[0]); - glNormalPointer(GL_FLOAT, 0, &normals[0]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - -/* - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(0.f, 1.f); - glVertex3f(ws->getPos().x-scale, height, ws->getPos().y+scale); - glTexCoord2f(0.f, 0.f); - glVertex3f(ws->getPos().x-scale, height, ws->getPos().y-scale); - glTexCoord2f(1.f, 1.f); - glVertex3f(ws->getPos().x+scale, height, ws->getPos().y+scale); - glTexCoord2f(1.f, 0.f); - glVertex3f(ws->getPos().x+scale, height, ws->getPos().y-scale); - glEnd(); -*/ - } - } - } - - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - - glPopAttrib(); - - assertGl(); -} - -void Renderer::renderHud(){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - Texture2D *hudTexture=game->getGui()->getHudTexture(); - if(hudTexture!=NULL){ - const Metrics &metrics= Metrics::getInstance(); - renderTextureQuad(0, 0, metrics.getVirtualW(), metrics.getVirtualH(),hudTexture,1.0f); - } -} - -void Renderer::renderMinimap(){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - const World *world= game->getWorld(); - const Minimap *minimap= world->getMinimap(); - - if(minimap == NULL || minimap->getTexture() == NULL) { - return; - } - - const GameCamera *gameCamera= game->getGameCamera(); - const Pixmap2D *pixmap= minimap->getTexture()->getPixmapConst(); - const Metrics &metrics= Metrics::getInstance(); - const WaterEffects *attackEffects= world->getAttackEffects(); - - int mx= metrics.getMinimapX(); - int my= metrics.getMinimapY(); - int mw= metrics.getMinimapW(); - int mh= metrics.getMinimapH(); - - Vec2f zoom= Vec2f( - static_cast(mw)/ pixmap->getW(), - static_cast(mh)/ pixmap->getH()); - - assertGl(); - - // render minimap border - Vec4f col= game->getGui()->getDisplay()->getColor(); - glColor4f(col.x*0.5f,col.y*0.5f,col.z*0.5f,1.0 ); - - int borderWidth=2; - glBegin(GL_QUADS); - glVertex2i(mx-borderWidth, my-borderWidth); - glVertex2i(mx-borderWidth, my); - glVertex2i(mx+mw+borderWidth, my); - glVertex2i(mx+mw+borderWidth, my-borderWidth); - glEnd(); - - glBegin(GL_QUADS); - glVertex2i(mx-borderWidth, my+mh+borderWidth); - glVertex2i(mx-borderWidth, my+mh); - glVertex2i(mx+mw+borderWidth, my+mh); - glVertex2i(mx+mw+borderWidth, my+mh+borderWidth); - glEnd(); - - glBegin(GL_QUADS); - glVertex2i(mx-borderWidth, my); - glVertex2i(mx-borderWidth, my+mh); - glVertex2i(mx, my+mh); - glVertex2i(mx, my); - glEnd(); - - glBegin(GL_QUADS); - glVertex2i(mx+mw, my); - glVertex2i(mx+mw, my+mh); - glVertex2i(mx+mw+borderWidth, my+mh); - glVertex2i(mx+mw+borderWidth, my); - glEnd(); - - assertGl(); - - glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_TEXTURE_BIT); - - //draw map - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - - glActiveTexture(fowTexUnit); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, static_cast(minimap->getFowTexture())->getHandle()); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE); - - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); - - glActiveTexture(baseTexUnit); - glBindTexture(GL_TEXTURE_2D, static_cast(minimap->getTexture())->getHandle()); - - glColor4f(0.5f, 0.5f, 0.5f, 0.2f); - - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(0.0f, 1.0f); - glMultiTexCoord2f(fowTexUnit, 0.0f, 1.0f); - glVertex2i(mx, my); - - glTexCoord2f(0.0f, 0.0f); - glMultiTexCoord2f(fowTexUnit, 0.0f, 0.0f); - glVertex2i(mx, my+mh); - - glTexCoord2f(1.0f, 1.0f); - glMultiTexCoord2f(fowTexUnit, 1.0f, 1.0f); - glVertex2i(mx+mw, my); - - glTexCoord2f(1.0f, 0.0f); - glMultiTexCoord2f(fowTexUnit, 1.0f, 0.0f); - glVertex2i(mx+mw, my+mh); - glEnd(); - - glDisable(GL_BLEND); - - glActiveTexture(fowTexUnit); - glDisable(GL_TEXTURE_2D); - glActiveTexture(baseTexUnit); - glDisable(GL_TEXTURE_2D); - - glEnable(GL_BLEND); - - const int itemCount = attackEffects->getWaterSplashCount() * 12; - if(itemCount > 0) { - vector vertices; - vertices.resize(itemCount); - vector colors; - colors.resize(itemCount); - - // draw attack alarm - int vertexIndex = 0; - for(int i = 0; i < attackEffects->getWaterSplashCount(); ++i) { - const WaterSplash *ws = attackEffects->getWaterSplash(i); - float scale= (1/ws->getAnim()*ws->getSize())*5; - //glColor4f(1.f, 1.f, 0.f, 1.f-ws->getAnim()); - float alpha=(1.f-ws->getAnim())*0.01f; - Vec2f pos= ws->getPos()/Map::cellScale; - float attackX=mx +pos.x*zoom.x; - float attackY=my +mh -pos.y*zoom.y; - if(ws->getEnabled()){ - // glBegin(GL_QUADS); - // glVertex2f(attackX-scale, attackY-scale); - // glVertex2f(attackX-scale, attackY+scale); - // glVertex2f(attackX+scale, attackY+scale); - // glVertex2f(attackX+scale, attackY-scale); - // glEnd(); - - colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); - vertices[vertexIndex] = Vec2f(attackX-scale, attackY-scale); - vertexIndex++; - colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); - vertices[vertexIndex] = Vec2f(attackX-scale, attackY+scale); - vertexIndex++; - colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, 0.8f); - vertices[vertexIndex] = Vec2f(attackX, attackY); - vertexIndex++; - - colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); - vertices[vertexIndex] = Vec2f(attackX+scale, attackY+scale); - vertexIndex++; - colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); - vertices[vertexIndex] = Vec2f(attackX-scale, attackY+scale); - vertexIndex++; - colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, 0.8f); - vertices[vertexIndex] = Vec2f(attackX, attackY); - vertexIndex++; - - colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); - vertices[vertexIndex] = Vec2f(attackX+scale, attackY+scale); - vertexIndex++; - colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); - vertices[vertexIndex] = Vec2f(attackX+scale, attackY-scale); - vertexIndex++; - colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, 0.8f); - vertices[vertexIndex] = Vec2f(attackX, attackY); - vertexIndex++; - - colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); - vertices[vertexIndex] = Vec2f(attackX+scale, attackY-scale); - vertexIndex++; - colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); - vertices[vertexIndex] = Vec2f(attackX-scale, attackY-scale); - vertexIndex++; - colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, 0.8f); - vertices[vertexIndex] = Vec2f(attackX, attackY); - vertexIndex++; - - /* - glBegin(GL_TRIANGLES); - glColor4f(1.f, 1.f, 0.f, alpha); - glVertex2f(attackX-scale, attackY-scale); - glVertex2f(attackX-scale, attackY+scale); - glColor4f(1.f, 1.f, 0.f, 0.8f); - glVertex2f(attackX, attackY); - glEnd(); - glBegin(GL_TRIANGLES); - glColor4f(1.f, 1.f, 0.f, alpha); - glVertex2f(attackX-scale, attackY+scale); - glVertex2f(attackX+scale, attackY+scale); - glColor4f(1.f, 1.f, 0.f, 0.8f); - glVertex2f(attackX, attackY); - glEnd(); - glBegin(GL_TRIANGLES); - glColor4f(1.f, 1.f, 0.f, alpha); - glVertex2f(attackX+scale, attackY+scale); - glVertex2f(attackX+scale, attackY-scale); - glColor4f(1.f, 1.f, 0.f, 0.8f); - glVertex2f(attackX, attackY); - glEnd(); - glBegin(GL_TRIANGLES); - glColor4f(1.f, 1.f, 0.f, alpha); - glVertex2f(attackX+scale, attackY-scale); - glVertex2f(attackX-scale, attackY-scale); - glColor4f(1.f, 1.f, 0.f, 0.8f); - glVertex2f(attackX, attackY); - glEnd(); - */ - - } - } - - if(vertexIndex > 0) { - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - glColorPointer(4,GL_FLOAT, 0, &colors[0]); - glVertexPointer(2, GL_FLOAT, 0, &vertices[0]); - glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexIndex); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - } - } - - glDisable(GL_BLEND); - - //draw units - VisibleQuadContainerCache &qCache = getQuadCache(); - std::vector visibleUnitList = qCache.visibleUnitList; - - const bool showAllUnitsInMinimap = Config::getInstance().getBool("DebugGameSynchUI","false"); - if(showAllUnitsInMinimap == true) { - visibleUnitList.clear(); - - const World *world= game->getWorld(); - for(unsigned int i = 0; i < (unsigned int)world->getFactionCount(); ++i) { - const Faction *faction = world->getFaction(i); - for(unsigned int j = 0; j < (unsigned int)faction->getUnitCount(); ++j) { - Unit *unit = faction->getUnit(j); - visibleUnitList.push_back(unit); - } - } - } - - if(visibleUnitList.empty() == false) { - uint32 unitIdx=0; - vector unit_vertices; - unit_vertices.resize(visibleUnitList.size()*4); - vector unit_colors; - unit_colors.resize(visibleUnitList.size()*4); - - for(int visibleIndex = 0; - visibleIndex < (int)visibleUnitList.size(); ++visibleIndex) { - Unit *unit = visibleUnitList[visibleIndex]; - if (unit->isAlive() == false) { - continue; - } - - Vec2i pos= unit->getPos() / Map::cellScale; - int size= unit->getType()->getSize(); - Vec3f color= unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0); - - unit_colors[unitIdx] = color; - unit_vertices[unitIdx] = Vec2f(mx + pos.x*zoom.x, my + mh - (pos.y*zoom.y)); - unitIdx++; - - unit_colors[unitIdx] = color; - unit_vertices[unitIdx] = Vec2f(mx + (pos.x+1)*zoom.x+size, my + mh - (pos.y*zoom.y)); - unitIdx++; - - unit_colors[unitIdx] = color; - unit_vertices[unitIdx] = Vec2f(mx + (pos.x+1)*zoom.x+size, my + mh - ((pos.y+size)*zoom.y)); - unitIdx++; - - unit_colors[unitIdx] = color; - unit_vertices[unitIdx] = Vec2f(mx + pos.x*zoom.x, my + mh - ((pos.y+size)*zoom.y)); - unitIdx++; - } - - if(unitIdx > 0) { - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - glColorPointer(3,GL_FLOAT, 0, &unit_colors[0]); - glVertexPointer(2, GL_FLOAT, 0, &unit_vertices[0]); - glDrawArrays(GL_QUADS, 0, unitIdx); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - } - - } - - renderMarkedCellsOnMinimap(); - - //draw camera - float wRatio= static_cast(metrics.getMinimapW()) / world->getMap()->getW(); - float hRatio= static_cast(metrics.getMinimapH()) / world->getMap()->getH(); - - int x= static_cast(gameCamera->getPos().x * wRatio); - int y= static_cast(gameCamera->getPos().z * hRatio); - - float ang= degToRad(gameCamera->getHAng()); - - glEnable(GL_BLEND); - - int x1; - int y1; - x1 = mx + x + static_cast(20*std::sin(ang-pi/5)); - y1 = my + mh - (y-static_cast(20*std::cos(ang-pi/5))); - - int x2; - int y2; - x2 = mx + x + static_cast(20*std::sin(ang+pi/5)); - y2 = my + mh - (y-static_cast(20*std::cos(ang+pi/5))); - - glColor4f(1.f, 1.f, 1.f, 1.f); - glBegin(GL_TRIANGLES); - - glVertex2i(mx+x, my+mh-y); - glColor4f(1.f, 1.f, 1.f, 0.0f); - glVertex2i(x1,y1); - glColor4f(1.f, 1.f, 1.f, 0.0f); - glVertex2i(x2,y2); - - glEnd(); - - glPopAttrib(); - - assertGl(); -} - -void Renderer::renderHighlightedCellsOnMinimap() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - // Draw marked cells - const std::vector *highlightedCells = game->getHighlightedCells(); - if(highlightedCells->empty() == false) { - //const Map *map= game->getWorld()->getMap(); - const World *world= game->getWorld(); - const Minimap *minimap= world->getMinimap(); - int pointersize=10; - if(minimap == NULL || minimap->getTexture() == NULL) { - return; - } - - //const GameCamera *gameCamera= game->getGameCamera(); - const Pixmap2D *pixmap= minimap->getTexture()->getPixmapConst(); - const Metrics &metrics= Metrics::getInstance(); - - - //int mx= metrics.getMinimapX(); - int my= metrics.getMinimapY(); - int mw= metrics.getMinimapW(); - int mh= metrics.getMinimapH(); - - Vec2f zoom= Vec2f( - static_cast(mw)/ pixmap->getW()/2, - static_cast(mh)/ pixmap->getH()/2); - - for(int i = 0;i < (int)highlightedCells->size(); i++) { - const MarkedCell *mc=&highlightedCells->at(i); - if(mc->getFaction() == NULL || (mc->getFaction()->getTeam() == game->getWorld()->getThisFaction()->getTeam())) { - const Texture2D *texture= game->getHighlightCellTexture(); - Vec3f color(MarkedCell::static_system_marker_color); - if(mc->getFaction() != NULL) { - color= mc->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0); - } - int lighting=(mc->getAliveCount()%15); - Vec3f myColor=Vec3f(color.x/2+.5f/lighting,color.y/2+.5f/lighting,color.z/2+.5f/lighting); - - Vec2i pos=mc->getTargetPos(); - if(texture != NULL) { - //float alpha = 0.49f+0.5f/(mc->getAliveCount()%15); - float alpha=1.0f; - renderTextureQuad((int)(pos.x*zoom.x)+pointersize, my + mh-(int)(pos.y*zoom.y), pointersize, pointersize, texture, alpha,&myColor); - } - } - } - } -} - -void Renderer::renderMarkedCellsOnMinimap() { - // Draw marked cells - std::map markedCells = game->getMapMarkedCellList(); - if(markedCells.empty() == false) { - //const Map *map= game->getWorld()->getMap(); - const World *world= game->getWorld(); - const Minimap *minimap= world->getMinimap(); - - if(minimap == NULL || minimap->getTexture() == NULL) { - return; - } - - //const GameCamera *gameCamera= game->getGameCamera(); - const Pixmap2D *pixmap= minimap->getTexture()->getPixmapConst(); - const Metrics &metrics= Metrics::getInstance(); - //const WaterEffects *attackEffects= world->getAttackEffects(); - - int mx= metrics.getMinimapX(); - int my= metrics.getMinimapY(); - int mw= metrics.getMinimapW(); - int mh= metrics.getMinimapH(); - - Vec2f zoom= Vec2f( - static_cast(mw)/ pixmap->getW(), - static_cast(mh)/ pixmap->getH()); - - uint32 unitIdx=0; - vector unit_vertices; - unit_vertices.resize(markedCells.size()*4); - vector unit_colors; - unit_colors.resize(markedCells.size()*4); - - for(std::map::iterator iterMap =markedCells.begin(); - iterMap != markedCells.end(); ++iterMap) { - MarkedCell &bm = iterMap->second; - if(bm.getPlayerIndex() < 0 || - (bm.getFaction() != NULL && - bm.getFaction()->getTeam() == game->getWorld()->getThisFaction()->getTeam())) { - Vec2i pos= bm.getTargetPos() / Map::cellScale; - float size= 0.5f; - - Vec3f color(MarkedCell::static_system_marker_color); - if(bm.getFaction() != NULL) { - color= bm.getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0); - } - float alpha = 0.65f; - - unit_colors[unitIdx] = Vec4f(color.x,color.y,color.z,alpha); - unit_vertices[unitIdx] = Vec2f(mx + pos.x*zoom.x, my + mh - (pos.y*zoom.y)); - unitIdx++; - - unit_colors[unitIdx] = Vec4f(color.x,color.y,color.z,alpha); - unit_vertices[unitIdx] = Vec2f(mx + (pos.x+1)*zoom.x+size, my + mh - (pos.y*zoom.y)); - unitIdx++; - - unit_colors[unitIdx] = Vec4f(color.x,color.y,color.z,alpha); - unit_vertices[unitIdx] = Vec2f(mx + (pos.x+1)*zoom.x+size, my + mh - ((pos.y+size)*zoom.y)); - unitIdx++; - - unit_colors[unitIdx] = Vec4f(color.x,color.y,color.z,alpha); - unit_vertices[unitIdx] = Vec2f(mx + pos.x*zoom.x, my + mh - ((pos.y+size)*zoom.y)); - unitIdx++; - } - } - - if(unitIdx > 0) { - glEnable(GL_BLEND); - - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - glColorPointer(4,GL_FLOAT, 0, &unit_colors[0]); - glVertexPointer(2, GL_FLOAT, 0, &unit_vertices[0]); - glDrawArrays(GL_QUADS, 0, unitIdx); - //glDrawArrays(GL_TRIANGLE_STRIP, 0, unitIdx); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - - glDisable(GL_BLEND); - } - } -} -void Renderer::renderVisibleMarkedCells(bool renderTextHint,int x, int y) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - // Draw marked cells - std::map markedCells = game->getMapMarkedCellList(); - if(markedCells.empty() == false) { - const Texture2D *texture= game->getMarkCellTexture(); - const int yOffset = -40; - - for(std::map::iterator iterMap =markedCells.begin(); - iterMap != markedCells.end(); ++iterMap) { - MarkedCell &bm = iterMap->second; - if(bm.getPlayerIndex() < 0 || - (bm.getFaction() != NULL && - bm.getFaction()->getTeam() == game->getWorld()->getThisFaction()->getTeam())) { - const Map *map= game->getWorld()->getMap(); - std::pair bmVisible = posInCellQuadCache( - map->toSurfCoords(bm.getTargetPos())); - if(bmVisible.first == true) { - if(renderTextHint == true) { - if(bm.getNote() != "") { - bool validPosObjWorld= x > bmVisible.second.x && - y > bmVisible.second.y + yOffset && - x < bmVisible.second.x + texture->getTextureWidth() && - y < bmVisible.second.y + yOffset + texture->getTextureHeight(); - - if(validPosObjWorld) { - //printf("Checking for hint text render mouse [%d,%d] marker pos [%d,%d] validPosObjWorld = %d, hint [%s]\n",x,y,bm.getTargetPos().x,bm.getTargetPos().y,validPosObjWorld,bm.getNote().c_str()); - - //Lang &lang= Lang::getInstance(); - Vec4f fontColor = Vec4f(1.0f, 1.0f, 1.0f, 0.25f); - - if(renderText3DEnabled == true) { - renderTextShadow3D(bm.getNote(), CoreData::getInstance().getConsoleFont3D(), fontColor, - bmVisible.second.x, bmVisible.second.y); - } - else { - renderTextShadow(bm.getNote(), CoreData::getInstance().getConsoleFont(), fontColor, - bmVisible.second.x, bmVisible.second.y); - } - } - } - } - else { - - -/* - //texture 0 - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - - //set color to interpolation - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE1); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); - - //set alpha to 1 - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); - - //texture 1 - glActiveTexture(GL_TEXTURE1); - glMultiTexCoord2f(GL_TEXTURE1, 0.f, 0.f); - glEnable(GL_TEXTURE_2D); - - glBindTexture(GL_TEXTURE_2D, static_cast(bm.getFaction()->getTexture())->getHandle()); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); - - //set alpha to 1 - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); - - glActiveTexture(GL_TEXTURE0); -*/ - - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - Vec3f color(MarkedCell::static_system_marker_color); - if(bm.getFaction() != NULL) { - color = bm.getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0); - } - - renderTextureQuad( - bmVisible.second.x,bmVisible.second.y + yOffset, - texture->getTextureWidth(),texture->getTextureHeight(),texture,0.8f,&color); - -/* - glActiveTexture(GL_TEXTURE1); - glDisable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); -*/ - } - } - } - } - } -} - -void Renderer::renderDisplay() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - CoreData &coreData= CoreData::getInstance(); - const Metrics &metrics= Metrics::getInstance(); - const Display *display= game->getGui()->getDisplay(); - - glPushAttrib(GL_ENABLE_BIT); - - if(renderText3DEnabled == true) { - //infoString - renderTextShadow3D( - display->getInfoText().c_str(), - coreData.getDisplayFont3D(), - display->getColor(), - metrics.getDisplayX(), - metrics.getDisplayY()+Display::infoStringY); - - //title - renderTextShadow3D( - display->getTitle().c_str(), - coreData.getDisplayFont3D(), - display->getColor(), - metrics.getDisplayX()+40, - metrics.getDisplayY() + metrics.getDisplayH() - 20); - - glColor3f(0.0f, 0.0f, 0.0f); - - //text - renderTextShadow3D( - display->getText().c_str(), - coreData.getDisplayFont3D(), - display->getColor(), - metrics.getDisplayX() -1, - metrics.getDisplayY() + metrics.getDisplayH() - 56); - - //progress Bar - if(display->getProgressBar() != -1) { - renderProgressBar3D( - display->getProgressBar(), - metrics.getDisplayX(), - metrics.getDisplayY() + metrics.getDisplayH()-50, - coreData.getDisplayFontSmall3D(), 175); - } - } - else { - //infoString - renderTextShadow( - display->getInfoText().c_str(), - coreData.getDisplayFont(), - display->getColor(), - metrics.getDisplayX(), - metrics.getDisplayY()+Display::infoStringY); - - //title - renderTextShadow( - display->getTitle().c_str(), - coreData.getDisplayFont(), - display->getColor(), - metrics.getDisplayX()+40, - metrics.getDisplayY() + metrics.getDisplayH() - 20); - - glColor3f(0.0f, 0.0f, 0.0f); - - //text - renderTextShadow( - display->getText().c_str(), - coreData.getDisplayFont(), - display->getColor(), - metrics.getDisplayX() -1, - metrics.getDisplayY() + metrics.getDisplayH() - 56); - - //progress Bar - if(display->getProgressBar()!=-1){ - renderProgressBar( - display->getProgressBar(), - metrics.getDisplayX(), - metrics.getDisplayY() + metrics.getDisplayH()-50, - coreData.getDisplayFontSmall()); - } - } - - //up images - glEnable(GL_TEXTURE_2D); - - glColor3f(1.f, 1.f, 1.f); - for(int i=0; igetUpImage(i)!=NULL){ - renderQuad( - metrics.getDisplayX()+display->computeUpX(i), - metrics.getDisplayY()+display->computeUpY(i), - display->getUpImageSize(), display->getUpImageSize(), display->getUpImage(i)); - } - } - - //down images - for(int i=0; igetDownImage(i)!=NULL){ - if(display->getDownLighted(i)){ - glColor3f(1.f, 1.f, 1.f); - } - else{ - glColor3f(0.3f, 0.3f, 0.3f); - } - - int x= metrics.getDisplayX()+display->computeDownX(i); - int y= metrics.getDisplayY()+display->computeDownY(i); - int size= Display::imageSize; - - if(display->getDownSelectedPos()==i){ - x-= 3; - y-= 3; - size+= 6; - } - - renderQuad(x, y, size, size, display->getDownImage(i)); - } - } - - //selection - int downPos= display->getDownSelectedPos(); - if(downPos!=Display::invalidPos){ - const Texture2D *texture= display->getDownImage(downPos); - if(texture!=NULL){ - int x= metrics.getDisplayX()+display->computeDownX(downPos)-3; - int y= metrics.getDisplayY()+display->computeDownY(downPos)-3; - int size= Display::imageSize+6; - renderQuad(x, y, size, size, display->getDownImage(downPos)); - } - } - - glPopAttrib(); -} - -void Renderer::renderMenuBackground(const MenuBackground *menuBackground) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - assertGl(); - - const Vec3f &cameraPosition= menuBackground->getCamera()->getConstPosition(); - - glPushAttrib(GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); - - //clear - Vec4f fogColor= Vec4f(0.4f, 0.4f, 0.4f, 1.f) * menuBackground->getFade(); - glClearColor(fogColor.x, fogColor.y, fogColor.z, 1.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glFogfv(GL_FOG_COLOR, fogColor.ptr()); - - //light - Vec4f lightPos= Vec4f(10.f, 10.f, 10.f, 1.f)* menuBackground->getFade(); - Vec4f diffLight= Vec4f(0.9f, 0.9f, 0.9f, 1.f)* menuBackground->getFade(); - Vec4f ambLight= Vec4f(0.3f, 0.3f, 0.3f, 1.f)* menuBackground->getFade(); - Vec4f specLight= Vec4f(0.1f, 0.1f, 0.1f, 1.f)* menuBackground->getFade(); - - glEnable(GL_LIGHT0); - glLightfv(GL_LIGHT0, GL_POSITION, lightPos.ptr()); - glLightfv(GL_LIGHT0, GL_DIFFUSE, diffLight.ptr()); - glLightfv(GL_LIGHT0, GL_AMBIENT, ambLight.ptr()); - glLightfv(GL_LIGHT0, GL_SPECULAR, specLight.ptr()); - - //main model - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.5f); - modelRenderer->begin(true, true, true, false); - menuBackground->getMainModelPtr()->updateInterpolationData(menuBackground->getAnim(), true); - modelRenderer->render(menuBackground->getMainModelPtr()); - modelRenderer->end(); - glDisable(GL_ALPHA_TEST); - - //characters - float dist= menuBackground->getAboutPosition().dist(cameraPosition); - float minDist= 3.f; - if(dist < minDist) { - - glAlphaFunc(GL_GREATER, 0.0f); - float alpha= clamp((minDist-dist) / minDist, 0.f, 1.f); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Vec4f(1.0f, 1.0f, 1.0f, alpha).ptr()); - - std::vector &characterMenuScreenPositionListCache = - CacheManager::getCachedItem< std::vector >(GameConstants::characterMenuScreenPositionListCacheLookupKey); - characterMenuScreenPositionListCache.clear(); - - modelRenderer->begin(true, true, false, false); - - for(int i=0; i < MenuBackground::characterCount; ++i) { - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - Vec3f worldPos(i*2.f-4.f, -1.4f, -7.5f); - glTranslatef(worldPos.x,worldPos.y,worldPos.z); - - // - // Get the screen coordinates for each character model - START - //std::vector projection(16); - //std::vector modelview(16); - //std::vector screen_coords(3); - - //glGetDoublev(GL_PROJECTION_MATRIX, projection.data()); - //glGetDoublev(GL_MODELVIEW_MATRIX, modelview.data()); - - const Metrics &metrics= Metrics::getInstance(); - GLint viewport[]= {0, 0, metrics.getVirtualW(), metrics.getVirtualH()}; - - //get matrices - GLdouble projection[16]; - glGetDoublev(GL_PROJECTION_MATRIX, projection); - - GLdouble modelview[16]; - glGetDoublev(GL_MODELVIEW_MATRIX, modelview); - - //get the screen coordinates - GLdouble screen_coords[3]; - - gluProject(worldPos.x, worldPos.y, worldPos.z, - modelview, projection, viewport, - &screen_coords[0], &screen_coords[1], &screen_coords[2]); - characterMenuScreenPositionListCache.push_back(Vec3f(screen_coords[0],screen_coords[1],screen_coords[2])); - // Get the screen coordinates for each character model - END - // - - menuBackground->getCharacterModelPtr(i)->updateInterpolationData(menuBackground->getAnim(), true); - modelRenderer->render(menuBackground->getCharacterModelPtr(i)); - - glPopMatrix(); - } - modelRenderer->end(); - } - - //water - if(menuBackground->getWater()) { - - //water surface - const int waterTesselation= 10; - const int waterSize= 250; - const int waterQuadSize= 2*waterSize/waterTesselation; - const float waterHeight= menuBackground->getWaterHeight(); - - glEnable(GL_BLEND); - - glNormal3f(0.f, 1.f, 0.f); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Vec4f(1.f, 1.f, 1.f, 1.f).ptr()); - GLuint waterHandle= static_cast(menuBackground->getWaterTexture())->getHandle(); - glBindTexture(GL_TEXTURE_2D, waterHandle); - for(int i=1; i < waterTesselation; ++i) { - glBegin(GL_TRIANGLE_STRIP); - for(int j=1; j < waterTesselation; ++j) { - glTexCoord2i(1, 2 % j); - glVertex3f(-waterSize+i*waterQuadSize, waterHeight, -waterSize+j*waterQuadSize); - glTexCoord2i(0, 2 % j); - glVertex3f(-waterSize+(i+1)*waterQuadSize, waterHeight, -waterSize+j*waterQuadSize); - } - glEnd(); - } - glDisable(GL_BLEND); - - //raindrops - if(menuBackground->getRain()) { - const float maxRaindropAlpha= 0.5f; - - glEnable(GL_BLEND); - glDisable(GL_LIGHTING); - glDisable(GL_ALPHA_TEST); - glDepthMask(GL_FALSE); - - //splashes - CoreData &coreData= CoreData::getInstance(); - glBindTexture(GL_TEXTURE_2D, static_cast(coreData.getWaterSplashTexture())->getHandle()); - for(int i=0; i< MenuBackground::raindropCount; ++i) { - - Vec2f pos= menuBackground->getRaindropPos(i); - float scale= menuBackground->getRaindropState(i); - float alpha= maxRaindropAlpha-scale*maxRaindropAlpha; - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - - glColor4f(1.f, 1.f, 1.f, alpha); - glTranslatef(pos.x, waterHeight+0.01f, pos.y); - - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(0.f, 1.f); - glVertex3f(-scale, 0, scale); - glTexCoord2f(0.f, 0.f); - glVertex3f(-scale, 0, -scale); - glTexCoord2f(1.f, 1.f); - glVertex3f(scale, 0, scale); - glTexCoord2f(1.f, 0.f); - glVertex3f(scale, 0, -scale); - glEnd(); - - glPopMatrix(); - } - } - } - - glPopAttrib(); - - assertGl(); -} - -void Renderer::renderMenuBackground(Camera *camera, float fade, Model *mainModel, vector characterModels,const Vec3f characterPosition, float anim) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - assertGl(); - - const Vec3f &cameraPosition= camera->getConstPosition(); - - glPushAttrib(GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); - - //clear - //Vec4f fogColor= Vec4f(0.4f, 0.4f, 0.4f, 1.f) * fade; - // Show black bacground - Vec4f fogColor= Vec4f(0.f, 0.f, 0.f, 1.f); - glClearColor(fogColor.x, fogColor.y, fogColor.z, 1.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glFogfv(GL_FOG_COLOR, fogColor.ptr()); - - //light - Vec4f lightPos= Vec4f(10.f, 10.f, 10.f, 1.f) * fade; - Vec4f diffLight= Vec4f(0.9f, 0.9f, 0.9f, 1.f) * fade; - Vec4f ambLight= Vec4f(0.3f, 0.3f, 0.3f, 1.f) * fade; - Vec4f specLight= Vec4f(0.1f, 0.1f, 0.1f, 1.f) * fade; - - glEnable(GL_LIGHT0); - glLightfv(GL_LIGHT0, GL_POSITION, lightPos.ptr()); - glLightfv(GL_LIGHT0, GL_DIFFUSE, diffLight.ptr()); - glLightfv(GL_LIGHT0, GL_AMBIENT, ambLight.ptr()); - glLightfv(GL_LIGHT0, GL_SPECULAR, specLight.ptr()); - - //main model - if(mainModel) { - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.5f); - modelRenderer->begin(true, true, true, false); - mainModel->updateInterpolationData(anim, true); - modelRenderer->render(mainModel); - modelRenderer->end(); - glDisable(GL_ALPHA_TEST); - } - - //characters - if(characterModels.empty() == false) { - float dist= characterPosition.dist(cameraPosition); - float minDist= 3.f; - if(dist < minDist) { - glAlphaFunc(GL_GREATER, 0.0f); - float alpha= clamp((minDist-dist) / minDist, 0.f, 1.f); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Vec4f(1.0f, 1.0f, 1.0f, alpha).ptr()); - modelRenderer->begin(true, true, false, false); - - for(unsigned int i = 0; i < characterModels.size(); ++i) { - if(characterModels[i]) { - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glTranslatef(i*2.f-4.f, -1.4f, -7.5f); - characterModels[i]->updateInterpolationData(anim, true); - modelRenderer->render(characterModels[i]); - glPopMatrix(); - } - } - modelRenderer->end(); - } - } - - - glPopAttrib(); - - assertGl(); -} - -// ==================== computing ==================== - -bool Renderer::ccomputePosition(const Vec2i &screenPos, Vec2i &worldPos, bool exactCoords) { - assertGl(); - const Map* map= game->getWorld()->getMap(); - const Metrics &metrics= Metrics::getInstance(); - float depth= 0.0f; - GLdouble modelviewMatrix[16]; - GLdouble projectionMatrix[16]; - GLint viewport[4]= {0, 0, metrics.getScreenW(), metrics.getScreenH()}; - GLdouble worldX; - GLdouble worldY; - GLdouble worldZ; - GLint screenX= (screenPos.x * metrics.getScreenW() / metrics.getVirtualW()); - GLint screenY= (screenPos.y * metrics.getScreenH() / metrics.getVirtualH()); - - //get the depth in the cursor pixel - glReadPixels(screenX, screenY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); - - //load matrices - loadProjectionMatrix(); - loadGameCameraMatrix(); - - //get matrices - glGetDoublev(GL_MODELVIEW_MATRIX, modelviewMatrix); - glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix); - - //get the world coordinates - gluUnProject( - screenX, screenY, depth, - modelviewMatrix, projectionMatrix, viewport, - &worldX, &worldY, &worldZ); - - //conver coords to int - if(exactCoords == true) { - worldPos= Vec2i(static_cast(worldX), static_cast(worldZ)); - } - else { - worldPos= Vec2i(static_cast(worldX+0.5f), static_cast(worldZ+0.5f)); - } - - //clamp coords to map size - return map->isInside(worldPos); -} - -// This method takes world co-ordinates and translates them to screen co-ords -Vec3f Renderer::computeScreenPosition(const Vec3f &worldPos) { - if(worldToScreenPosCache.find(worldPos) != worldToScreenPosCache.end()) { - return worldToScreenPosCache[worldPos]; - } - assertGl(); - - const Metrics &metrics= Metrics::getInstance(); - GLint viewport[]= {0, 0, metrics.getVirtualW(), metrics.getVirtualH()}; - GLdouble worldX = worldPos.x; - GLdouble worldY = worldPos.y; - GLdouble worldZ = worldPos.z; - - //load matrices - loadProjectionMatrix(); - loadGameCameraMatrix(); - - //get matrices - GLdouble modelviewMatrix[16]; - glGetDoublev(GL_MODELVIEW_MATRIX, modelviewMatrix); - GLdouble projectionMatrix[16]; - glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix); - - //get the screen coordinates - GLdouble screenX; - GLdouble screenY; - GLdouble screenZ; - gluProject(worldX, worldY, worldZ, - modelviewMatrix, projectionMatrix, viewport, - &screenX, &screenY, &screenZ); - - Vec3f screenPos(screenX,screenY,screenZ); - worldToScreenPosCache[worldPos]=screenPos; - - return screenPos; -} - -void Renderer::computeSelected( Selection::UnitContainer &units, const Object *&obj, - const bool withObjectSelection, - const Vec2i &posDown, const Vec2i &posUp) { - const string selectionType=toLower(Config::getInstance().getString("SelectionType",Config::colorPicking)); - - if(selectionType==Config::colorPicking) { - selectUsingColorPicking(units,obj, withObjectSelection,posDown, posUp); - } - /// Frustum approach --> Currently not accurate enough - else if(selectionType==Config::frustumPicking) { - selectUsingFrustumSelection(units,obj, withObjectSelection,posDown, posUp); - } - else { - selectUsingSelectionBuffer(units,obj, withObjectSelection,posDown, posUp); - } -} - -void Renderer::selectUsingFrustumSelection(Selection::UnitContainer &units, - const Object *&obj, const bool withObjectSelection, - const Vec2i &posDown, const Vec2i &posUp) { - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - const Metrics &metrics= Metrics::getInstance(); - GLint view[]= {0, 0, metrics.getVirtualW(), metrics.getVirtualH()}; - - //compute center and dimensions of selection rectangle - int x = (posDown.x+posUp.x) / 2; - int y = (posDown.y+posUp.y) / 2; - int w = abs(posDown.x-posUp.x); - int h = abs(posDown.y-posUp.y); - if(w < 2) { - w = 2; - } - if(h < 2) { - h = 2; - } - - gluPickMatrix(x, y, w, h, view); - gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, perspFarPlane); - loadGameCameraMatrix(); - - VisibleQuadContainerCache quadSelectionCacheItem; - ExtractFrustum(quadSelectionCacheItem); - - //pop matrices - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - - VisibleQuadContainerCache &qCache = getQuadCache(); - if(qCache.visibleQuadUnitList.empty() == false) { - for(int visibleUnitIndex = 0; - visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { - Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; - if(unit != NULL && unit->isAlive()) { - Vec3f unitPos = unit->getCurrMidHeightVector(); - bool insideQuad = CubeInFrustum(quadSelectionCacheItem.frustumData, - unitPos.x, unitPos.y, unitPos.z, unit->getType()->getRenderSize()); - if(insideQuad == true) { - units.push_back(unit); - } - } - } - } - - if(withObjectSelection == true) { - if(qCache.visibleObjectList.empty() == false) { - for(int visibleIndex = 0; - visibleIndex < (int)qCache.visibleObjectList.size(); ++visibleIndex) { - Object *object = qCache.visibleObjectList[visibleIndex]; - if(object != NULL) { - bool insideQuad = CubeInFrustum(quadSelectionCacheItem.frustumData, - object->getPos().x, object->getPos().y, object->getPos().z, 1); - if(insideQuad == true) { - obj = object; - //if(withObjectSelection == true) { - break; - //} - } - } - } - } - } -} - -void Renderer::selectUsingSelectionBuffer(Selection::UnitContainer &units, - const Object *&obj, const bool withObjectSelection, - const Vec2i &posDown, const Vec2i &posUp) { - //compute center and dimensions of selection rectangle - int x = (posDown.x+posUp.x) / 2; - int y = (posDown.y+posUp.y) / 2; - int w = abs(posDown.x-posUp.x); - int h = abs(posDown.y-posUp.y); - if(w < 2) { - w = 2; - } - if(h < 2) { - h = 2; - } - - //declarations - GLuint selectBuffer[Gui::maxSelBuff]; - - //setup matrices - glSelectBuffer(Gui::maxSelBuff, selectBuffer); - //glMatrixMode(GL_PROJECTION); - //glPushMatrix(); - - GLint renderModeResult = glRenderMode(GL_SELECT); - if(renderModeResult < 0) { - const char *errorString= reinterpret_cast(gluErrorString(renderModeResult)); - char szBuf[8096]=""; - snprintf(szBuf,8096,"OpenGL error #%d [0x%X] : [%s] at file: [%s], line: %d",renderModeResult,renderModeResult,errorString,extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - - printf("%s\n",szBuf); - } - - - glPushMatrix(); - glMatrixMode(GL_PROJECTION); - - glLoadIdentity(); - - const Metrics &metrics= Metrics::getInstance(); - GLint view[]= {0, 0, metrics.getVirtualW(), metrics.getVirtualH()}; - //GLint view[4]; - //glGetIntegerv(GL_VIEWPORT, view); - - gluPickMatrix(x, y, w, h, view); - gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, perspFarPlane); - //gluPerspective(perspFov, metrics.getAspectRatio(), 0.0001, 1000.0); - //gluPerspective(perspFov, (float)view[2]/(float)view[3], perspNearPlane, perspFarPlane); - loadGameCameraMatrix(); - - //render units to find which ones should be selected - renderUnitsFast(); - if(withObjectSelection == true) { - renderObjectsFast(false,true); - } - - //pop matrices - glPopMatrix(); - - // Added this to ensure all the selection calls are done now - // (see http://www.unknownroad.com/rtfm/graphics/glselection.html section: [0x4]) - //glFlush(); - - //select units by checking the selected buffer - int selCount= glRenderMode(GL_RENDER); - if(selCount > 0) { - VisibleQuadContainerCache &qCache = getQuadCache(); - for(int i = 1; i <= selCount; ++i) { - int index = selectBuffer[i*4-1]; - if(index >= OBJECT_SELECT_OFFSET) { - Object *object = qCache.visibleObjectList[index - OBJECT_SELECT_OFFSET]; - if(object != NULL) { - obj = object; - if(withObjectSelection == true) { - break; - } - } - } - else { - Unit *unit = qCache.visibleQuadUnitList[index]; - if(unit != NULL && unit->isAlive()) { - units.push_back(unit); - } - } - } - } - else if(selCount < 0) { - const char *errorString= reinterpret_cast(gluErrorString(selCount)); - char szBuf[8096]=""; - snprintf(szBuf,8096,"OpenGL error #%d [0x%X] : [%s] at file: [%s], line: %d",selCount,selCount,errorString,extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - - printf("%s\n",szBuf); - } -} - -void Renderer::selectUsingColorPicking(Selection::UnitContainer &units, - const Object *&obj, const bool withObjectSelection, - const Vec2i &posDown, const Vec2i &posUp) { - int x1 = posDown.x; - int y1 = posDown.y; - int x2 = posUp.x; - int y2 = posUp.y; - - int x = min(x1,x2); - int y = min(y1,y2); - int w = max(x1,x2) - min(x1,x2); - int h = max(y1,y2) - min(y1,y2); - if(w < 2) { - w = 2; - } - if(h < 2) { - h = 2; - } - - const Metrics &metrics= Metrics::getInstance(); - x= (x * metrics.getScreenW() / metrics.getVirtualW()); - y= (y * metrics.getScreenH() / metrics.getVirtualH()); - - w= (w * metrics.getScreenW() / metrics.getVirtualW()); - h= (h * metrics.getScreenH() / metrics.getVirtualH()); - - PixelBufferWrapper::begin(); - - - glPushMatrix(); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - //GLint view[]= {0, 0, metrics.getVirtualW(), metrics.getVirtualH()}; - //gluPickMatrix(x, y, w, h, view); - gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, perspFarPlane); - loadGameCameraMatrix(); - - //render units to find which ones should be selected - //printf("In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - vector rendererUnits = renderUnitsFast(false, true); - //printf("In [%s::%s] Line: %d rendererUnits = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,rendererUnits.size()); - - - // Added this to ensure all the selection calls are done now - // (see http://www.unknownroad.com/rtfm/graphics/glselection.html section: [0x4]) - //glFlush(); - - //GraphicsInterface::getInstance().getCurrentContext()->swapBuffers(); - - PixelBufferWrapper::end(); - - vector unitsVector; - bool unitFound=false; - - if(rendererUnits.empty() == false) { - copy(rendererUnits.begin(), rendererUnits.end(), std::inserter(unitsVector, unitsVector.begin())); - } - - if(unitsVector.empty() == false) { - vector pickedList = BaseColorPickEntity::getPickedList(x,y,w,h, unitsVector); - //printf("In [%s::%s] Line: %d pickedList = %d models rendered = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,pickedList.size(),rendererModels.size()); - - if(pickedList.empty() == false) { - units.reserve(pickedList.size()); - for(unsigned int i = 0; i < pickedList.size(); ++i) { - int index = pickedList[i]; - //printf("In [%s::%s] Line: %d searching for selected object i = %d index = %d units = %d objects = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,index,rendererUnits.size(),rendererObjects.size()); - - if(rendererUnits.empty() == false && index < (int)rendererUnits.size()) { - Unit *unit = rendererUnits[index]; - if(unit != NULL && unit->isAlive()) { - unitFound=true; - units.push_back(unit); - } - } - } - } - } - - if(withObjectSelection == true && unitFound==false) { - vector rendererObjects; - vector objectsVector; - rendererObjects = renderObjectsFast(false,true,true); - if(rendererObjects.empty() == false) { - copy(rendererObjects.begin(), rendererObjects.end(), std::inserter(objectsVector, objectsVector.begin())); - } - - if(objectsVector.empty() == false) { - vector pickedList = BaseColorPickEntity::getPickedList(x,y,w,h, objectsVector); - //printf("In [%s::%s] Line: %d pickedList = %d models rendered = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,pickedList.size(),rendererModels.size()); - - if(pickedList.empty() == false) { - for(unsigned int i = 0; i < pickedList.size(); ++i) { - int index = pickedList[i]; - //printf("In [%s::%s] Line: %d searching for selected object i = %d index = %d units = %d objects = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,index,rendererUnits.size(),rendererObjects.size()); - - if(rendererObjects.empty() == false && index < (int)rendererObjects.size()) { - Object *object = rendererObjects[index]; - //printf("In [%s::%s] Line: %d searching for selected object i = %d index = %d [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,index,object); - - if(object != NULL) { - obj = object; - break; - } - } - } - } - } - } - //pop matrices - glPopMatrix(); -} - -// ==================== shadows ==================== - -void Renderer::renderShadowsToTexture(const int renderFps){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(shadowsOffDueToMinRender == false && - (shadows == sProjected || shadows == sShadowMapping)) { - - shadowMapFrame= (shadowMapFrame + 1) % (shadowFrameSkip + 1); - - if(shadowMapFrame == 0){ - assertGl(); - - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT | GL_POLYGON_BIT); - - if(shadows == sShadowMapping) { - glClear(GL_DEPTH_BUFFER_BIT); - } - else { - float color= 1.0f-shadowIntensity; - glColor3f(color, color, color); - glClearColor(1.f, 1.f, 1.f, 1.f); - glDisable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT); - } - - //assertGl(); - - //clear color buffer - // - //set viewport, we leave one texel always in white to avoid problems - glViewport(1, 1, shadowTextureSize-2, shadowTextureSize-2); - - //assertGl(); - - if(nearestLightPos.w == 0.f) { - //directional light - - //light pos - assert(game != NULL); - assert(game->getWorld() != NULL); - const TimeFlow *tf= game->getWorld()->getTimeFlow(); - assert(tf != NULL); - float ang= tf->isDay()? computeSunAngle(tf->getTime()): computeMoonAngle(tf->getTime()); - ang= radToDeg(ang); - - //push and set projection - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - //assertGl(); - - if(game->getGameCamera()->getState()==GameCamera::sGame){ - //glOrtho(-35, 5, -15, 15, -1000, 1000); - //glOrtho(-30, 30, -20, 20, -1000, 1000); - glOrtho(-30, 5, -20, 20, -1000, 1000); - } - else{ - glOrtho(-30, 30, -20, 20, -1000, 1000); - } - - //assertGl(); - - //push and set modelview - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - glRotatef(15, 0, 1, 0); - - glRotatef(ang, 1, 0, 0); - glRotatef(90, 0, 1, 0); - const Vec3f &pos= game->getGameCamera()->getPos(); - - glTranslatef(static_cast(-pos.x), 0, static_cast(-pos.z)); - - //assertGl(); - } - else { - //non directional light - - //push projection - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - //assertGl(); - - gluPerspective(perspFov, 1.f, perspNearPlane, perspFarPlane); - //const Metrics &metrics= Metrics::getInstance(); - //gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, perspFarPlane); - - - assertGl(); - - //push modelview - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - glRotatef(-90, -1, 0, 0); - glTranslatef(-nearestLightPos.x, -nearestLightPos.y-2, -nearestLightPos.z); - - //assertGl(); - } - - if(shadows == sShadowMapping) { - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(1.0f, 16.0f); - - //assertGl(); - } - - //render 3d - renderUnitsFast(true); - renderObjectsFast(true,false); - - //assertGl(); - - //read color buffer - glBindTexture(GL_TEXTURE_2D, shadowMapHandle); - assertGl(); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowTextureSize, shadowTextureSize); - GLenum error = glGetError(); - // This error can happen when a Linux user switches from an X session - // back to a running game, and 'seems' to be safe to ignore it - if(error != GL_INVALID_OPERATION) { - assertGlWithErrorNumber(error); - } - - //get elemental matrices - static Matrix4f matrix1; - static bool matrix1Populate = true; - if(matrix1Populate == true) { - matrix1Populate = false; - matrix1[0]= 0.5f; matrix1[4]= 0.f; matrix1[8]= 0.f; matrix1[12]= 0.5f; - matrix1[1]= 0.f; matrix1[5]= 0.5f; matrix1[9]= 0.f; matrix1[13]= 0.5f; - matrix1[2]= 0.f; matrix1[6]= 0.f; matrix1[10]= 0.5f; matrix1[14]= 0.5f; - matrix1[3]= 0.f; matrix1[7]= 0.f; matrix1[11]= 0.f; matrix1[15]= 1.f; - } - Matrix4f matrix2; - glGetFloatv(GL_PROJECTION_MATRIX, matrix2.ptr()); - - //assertGl(); - - Matrix4f matrix3; - glGetFloatv(GL_MODELVIEW_MATRIX, matrix3.ptr()); - - //pop both matrices - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - - //assertGl(); - - //compute texture matrix - glLoadMatrixf(matrix1.ptr()); - glMultMatrixf(matrix2.ptr()); - glMultMatrixf(matrix3.ptr()); - glGetFloatv(GL_TRANSPOSE_PROJECTION_MATRIX_ARB, shadowMapMatrix.ptr()); - - //assertGl(); - - //if(shadows == sShadowMapping) { - // glDisable(GL_POLYGON_OFFSET_FILL); - // glPolygonOffset(0.0f, 0.0f); - //} - - //pop - glPopMatrix(); - - //assertGl(); - - glPopAttrib(); - - assertGl(); - } - } -} - - -// ==================== gl wrap ==================== - -string Renderer::getGlInfo(){ - string infoStr=""; - Lang &lang= Lang::getInstance(); - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - infoStr+= lang.getString("OpenGlInfo")+":\n"; - infoStr+= " "+lang.getString("OpenGlVersion")+": "; - infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n"; - infoStr+= " "+lang.getString("OpenGlRenderer")+": "; - infoStr+= string((getGlVersion() != NULL ? getGlVersion() : "?"))+"\n"; - infoStr+= " "+lang.getString("OpenGlVendor")+": "; - infoStr+= string((getGlVendor() != NULL ? getGlVendor() : "?"))+"\n"; - infoStr+= " "+lang.getString("OpenGlMaxLights")+": "; - infoStr+= intToStr(getGlMaxLights())+"\n"; - infoStr+= " "+lang.getString("OpenGlMaxTextureSize")+": "; - infoStr+= intToStr(getGlMaxTextureSize())+"\n"; - infoStr+= " "+lang.getString("OpenGlMaxTextureUnits")+": "; - infoStr+= intToStr(getGlMaxTextureUnits())+"\n"; - infoStr+= " "+lang.getString("OpenGlModelviewStack")+": "; - infoStr+= intToStr(getGlModelviewMatrixStackDepth())+"\n"; - infoStr+= " "+lang.getString("OpenGlProjectionStack")+": "; - infoStr+= intToStr(getGlProjectionMatrixStackDepth())+"\n"; - } - return infoStr; -} - -string Renderer::getGlMoreInfo(){ - string infoStr=""; - Lang &lang= Lang::getInstance(); - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - //gl extensions - infoStr+= lang.getString("OpenGlExtensions")+":\n "; - - string extensions= getGlExtensions(); - int charCount= 0; - for(int i = 0; i < (int)extensions.size(); ++i) { - infoStr+= extensions[i]; - if(charCount>120 && extensions[i]==' '){ - infoStr+= "\n "; - charCount= 0; - } - ++charCount; - } - - //platform extensions - infoStr+= "\n\n"; - infoStr+= lang.getString("OpenGlPlatformExtensions")+":\n "; - - charCount= 0; - string platformExtensions= getGlPlatformExtensions(); - for(int i = 0; i < (int)platformExtensions.size(); ++i) { - infoStr+= platformExtensions[i]; - if(charCount>120 && platformExtensions[i]==' '){ - infoStr+= "\n "; - charCount= 0; - } - ++charCount; - } - } - - return infoStr; -} - -void Renderer::autoConfig() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - Config &config= Config::getInstance(); - - bool nvidiaCard= toLower(getGlVendor()).find("nvidia")!=string::npos; - bool atiCard= toLower(getGlVendor()).find("ati")!=string::npos; - //bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow") && isGlExtensionSupported("GL_ARB_shadow_ambient"); - bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow"); - - //3D textures - config.setBool("Textures3D", isGlExtensionSupported("GL_EXT_texture3D")); - - //shadows - string shadows=""; - if(getGlMaxTextureUnits()>=3){ - if(nvidiaCard && shadowExtensions){ - shadows= shadowsToStr(sShadowMapping); - } - else{ - shadows= shadowsToStr(sProjected); - } - } - else{ - shadows=shadowsToStr(sDisabled); - } - config.setString("Shadows", shadows); - - //lights - config.setInt("MaxLights", atiCard? 1: 4); - - //filter - config.setString("Filter", "Bilinear"); - } -} - -void Renderer::clearBuffers() { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -} - -void Renderer::clearZBuffer() { - glClear(GL_DEPTH_BUFFER_BIT); -} - -void Renderer::loadConfig() { - Config &config= Config::getInstance(); - - //cache most used config params - maxLights= config.getInt("MaxLights"); - photoMode= config.getBool("PhotoMode"); - focusArrows= config.getBool("FocusArrows"); - textures3D= config.getBool("Textures3D"); - float gammaValue=config.getFloat("GammaValue","0.0"); - if(this->program == NULL) { - throw megaglest_runtime_error("this->program == NULL"); - } - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - //if(this->program != NULL) { - if(gammaValue != 0.0) { - this->program->getWindow()->setGamma(gammaValue); - } - //} - } - //load shadows - shadows= strToShadows(config.getString("Shadows")); - if(shadows==sProjected || shadows==sShadowMapping){ - shadowTextureSize= config.getInt("ShadowTextureSize"); - shadowFrameSkip= config.getInt("ShadowFrameSkip"); - shadowIntensity= config.getFloat("ShadowIntensity","1.0"); - } - - //load filter settings - Texture2D::Filter textureFilter= strToTextureFilter(config.getString("Filter")); - int maxAnisotropy= config.getInt("FilterMaxAnisotropy"); - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - for(int i=0; isetFilter(textureFilter); - textureManager[i]->setMaxAnisotropy(maxAnisotropy); - } - } -} - -//Texture2D *Renderer::saveScreenToTexture(int x, int y, int width, int height) { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// -// Config &config= Config::getInstance(); -// Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter")); -// int maxAnisotropy = config.getInt("FilterMaxAnisotropy"); -// -// Texture2D *texture = GraphicsInterface::getInstance().getFactory()->newTexture2D(); -// texture->setForceCompressionDisabled(true); -// texture->setMipmap(false); -// Pixmap2D *pixmapScreenShot = texture->getPixmap(); -// pixmapScreenShot->init(width, height, 3); -// texture->init(textureFilter,maxAnisotropy); -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// //glFinish(); -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// glReadPixels(x, y, pixmapScreenShot->getW(), pixmapScreenShot->getH(), -// GL_RGB, GL_UNSIGNED_BYTE, pixmapScreenShot->getPixels()); -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// -// return texture; -//} - -void Renderer::saveScreen(const string &path,int w, int h) { - const Metrics &sm= Metrics::getInstance(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - Pixmap2D *pixmapScreenShot = new Pixmap2D(sm.getScreenW(),sm.getScreenH(), 3); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //glFinish(); - - glPixelStorei(GL_PACK_ALIGNMENT, 1); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - glReadPixels(0, 0, pixmapScreenShot->getW(), pixmapScreenShot->getH(), - GL_RGB, GL_UNSIGNED_BYTE, pixmapScreenShot->getPixels()); - - if(w==0 || h==0){ - h=sm.getScreenH(); - w=sm.getScreenW(); - } - else{ - pixmapScreenShot->Scale(GL_RGB,w,h); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - // Signal the threads queue to add a screenshot save request - MutexSafeWrapper safeMutex(saveScreenShotThreadAccessor,string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__)); - saveScreenQueue.push_back(make_pair(path,pixmapScreenShot)); - safeMutex.ReleaseLock(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -unsigned int Renderer::getSaveScreenQueueSize() { - MutexSafeWrapper safeMutex(saveScreenShotThreadAccessor,string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__)); - int queueSize = (int)saveScreenQueue.size(); - safeMutex.ReleaseLock(); - - return queueSize; -} - -// ==================== PRIVATE ==================== - -float Renderer::computeSunAngle(float time) { - - float dayTime= TimeFlow::dusk-TimeFlow::dawn; - float fTime= (time-TimeFlow::dawn)/dayTime; - return clamp(fTime*pi, pi/8.f, 7.f*pi/8.f); -} - -float Renderer::computeMoonAngle(float time) { - float nightTime= 24-(TimeFlow::dusk-TimeFlow::dawn); - - if(time Renderer::renderUnitsFast(bool renderingShadows, bool colorPickingSelection) { - vector unitsList; - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return unitsList; - } - - assert(game != NULL); - //const World *world= game->getWorld(); - //assert(world != NULL); - - VisibleQuadContainerCache &qCache = getQuadCache(); - if(qCache.visibleQuadUnitList.empty() == false) { - if(colorPickingSelection == true) { - unitsList.reserve(qCache.visibleQuadUnitList.size()); - } - - bool modelRenderStarted = false; - bool renderOnlyBuildings=true; - for(int k=0; k<2 ;k++) { - if(k==0){ - //glDisable(GL_DEPTH_TEST); - renderOnlyBuildings=true; - } - else { - if(colorPickingSelection == true){ - // clear depth buffer to get units behind buildings rendered in front of them - glClear(GL_DEPTH_BUFFER_BIT); - } - //glEnable(GL_DEPTH_TEST); - renderOnlyBuildings=false; - } - for(int visibleUnitIndex = 0; - visibleUnitIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { - Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; - - if(renderingShadows==false && unit->isAlive()==false){ - // no need to render dead units for selection - continue; - } - - if(renderOnlyBuildings==true && unit->getType()->hasSkillClass(scMove)){ - continue; - } - - if(renderOnlyBuildings==false && !unit->getType()->hasSkillClass(scMove)){ - continue; - } - - if(modelRenderStarted == false) { - modelRenderStarted = true; - - if(colorPickingSelection == false) { - //glPushAttrib(GL_ENABLE_BIT| GL_TEXTURE_BIT); - glDisable(GL_LIGHTING); - if (renderingShadows == false) { - glPushAttrib(GL_ENABLE_BIT); - glDisable(GL_TEXTURE_2D); - } - else { - glPushAttrib(GL_ENABLE_BIT| GL_TEXTURE_BIT); - glEnable(GL_TEXTURE_2D); - glAlphaFunc(GL_GREATER, 0.4f); - - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - - //set color to the texture alpha - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - - //set alpha to the texture alpha - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); - } - } - - modelRenderer->begin(false, renderingShadows, false, colorPickingSelection); - - if(colorPickingSelection == false) { - glInitNames(); - } - } - - if(colorPickingSelection == false) { - glPushName(visibleUnitIndex); - } - - //assertGl(); - - glMatrixMode(GL_MODELVIEW); - //debuxar modelo - glPushMatrix(); - - //translate - Vec3f currVec= unit->getCurrVectorFlat(); - glTranslatef(currVec.x, currVec.y, currVec.z); - - //rotate - glRotatef(unit->getRotation(), 0.f, 1.f, 0.f); - - //render - Model *model= unit->getCurrentModelPtr(); - //if(this->gameCamera->getPos().dist(unit->getCurrVector()) <= SKIP_INTERPOLATION_DISTANCE) { - - // ***MV don't think this is needed below 2013/01/11 - model->updateInterpolationVertices(unit->getAnimProgressAsFloat(), unit->isAlive() && !unit->isAnimProgressBound()); - - //} - - if(colorPickingSelection == true) { - unit->setUniquePickingColor(); - unitsList.push_back(unit); - } - - modelRenderer->render(model,rmSelection); - - glPopMatrix(); - - if(colorPickingSelection == false) { - glPopName(); - } - } - } - - if(modelRenderStarted == true) { - modelRenderer->end(); - if(colorPickingSelection == false) { - glPopAttrib(); - } - } - } - //glDisable(GL_DEPTH_TEST); - return unitsList; -} - -//render objects for selection purposes -vector Renderer::renderObjectsFast(bool renderingShadows, bool resourceOnly, - bool colorPickingSelection) { - vector objectList; - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return objectList; - } - - VisibleQuadContainerCache &qCache = getQuadCache(); - if(qCache.visibleObjectList.empty() == false) { - if(colorPickingSelection == true) { - objectList.reserve(qCache.visibleObjectList.size()); - } - - bool modelRenderStarted = false; - for(int visibleIndex = 0; - visibleIndex < (int)qCache.visibleObjectList.size(); ++visibleIndex) { - Object *o = qCache.visibleObjectList[visibleIndex]; - - if(modelRenderStarted == false) { - modelRenderStarted = true; - - if(colorPickingSelection == false) { - glDisable(GL_LIGHTING); - - if (renderingShadows == false){ - glPushAttrib(GL_ENABLE_BIT); - glDisable(GL_TEXTURE_2D); - } - else { - glPushAttrib(GL_ENABLE_BIT| GL_TEXTURE_BIT); - glAlphaFunc(GL_GREATER, 0.5f); - - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); - - //set color to the texture alpha - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); - - //set alpha to the texture alpha - glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); - glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE); - glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); - } - } - - modelRenderer->begin(false, renderingShadows, false, colorPickingSelection); - - if(colorPickingSelection == false) { - glInitNames(); - } - } - - if(resourceOnly == false || o->getResource()!= NULL) { - Model *objModel= o->getModelPtr(); - //if(this->gameCamera->getPos().dist(o->getPos()) <= SKIP_INTERPOLATION_DISTANCE) { - - // ***MV don't think this is needed below 2013/01/11 - //objModel->updateInterpolationData(o->getAnimProgress(), true); - - //} - const Vec3f v= o->getConstPos(); - - if(colorPickingSelection == false) { - glPushName(OBJECT_SELECT_OFFSET+visibleIndex); - } + float fowFactor = fowTexPixmap->getPixelf(o->getMapPos().x / Map::cellScale, o->getMapPos().y / Map::cellScale); + Vec4f color = Vec4f(Vec3f(fowFactor), 1.f); + glColor4fv(color.ptr()); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (color * ambFactor).ptr()); + glFogfv(GL_FOG_COLOR, (baseFogColor * fowFactor).ptr()); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(v.x, v.y, v.z); glRotatef(o->getRotation(), 0.f, 1.f, 0.f); - if(colorPickingSelection == true) { - o->setUniquePickingColor(); - objectList.push_back(o); + //We use OpenGL Lights so no manual action is needed here. In fact this call did bad things on lighting big rocks for example + // if(o->getRotation() != 0.0) { + // setupLightingForRotatedModel(); + // } + + //objModel->updateInterpolationData(0.f, true); + //if(this->gameCamera->getPos().dist(o->getPos()) <= SKIP_INTERPOLATION_DISTANCE) { + + + if (tilesetObjectsToAnimate == -1) { + objModel->updateInterpolationData(o->getAnimProgress(), true); + } else if (tilesetObjectsToAnimate > 0 && o->isAnimated()) { + tilesetObjectsToAnimate--; + objModel->updateInterpolationData(o->getAnimProgress(), true); + } else { + objModel->updateInterpolationData(0, true); } - modelRenderer->render(objModel,resourceOnly?rmSelection:rmNormal); + // objModel->updateInterpolationData(o->getAnimProgress(), true); + //} + modelRenderer->render(objModel); + + triangleCount += objModel->getTriangleCount(); + pointCount += objModel->getVertexCount(); glPopMatrix(); - - if(colorPickingSelection == false) { - glPopName(); - } } + + if (modelRenderStarted == true) { + modelRenderer->end(); + glPopAttrib(); + } + + //restore + static_cast(modelRenderer)->setDuplicateTexCoords(true); + + assertGl(); } - if(modelRenderStarted == true) { - modelRenderer->end(); + void Renderer::renderWater() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } - if(colorPickingSelection == false) { + const World *world = game->getWorld(); + const Map *map = world->getMap(); + + const Texture2D *fowTex = world->getMinimap()->getFowTexture(); + if (fowTex == NULL) { + return; + } + + float waterAnim = world->getWaterEffects()->getAmin(); + + //assert + assertGl(); + + glPushAttrib(GL_TEXTURE_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT); + + //water texture nit + glDisable(GL_TEXTURE_2D); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + if (textures3D) { + Texture3D *waterTex = world->getTileset()->getWaterTex(); + if (waterTex == NULL) { + throw megaglest_runtime_error("waterTex == NULL"); + } + glEnable(GL_TEXTURE_3D); + glBindTexture(GL_TEXTURE_3D, static_cast(waterTex)->getHandle()); + } else { + glEnable(GL_COLOR_MATERIAL); + glColor4f(0.5f, 0.5f, 1.0f, 0.5f); + glBindTexture(GL_TEXTURE_3D, 0); + } + + assertGl(); + + //fog of War texture Unit + //const Texture2D *fowTex= world->getMinimap()->getFowTexture(); + glActiveTexture(fowTexUnit); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, static_cast(fowTex)->getHandle()); + glActiveTexture(baseTexUnit); + + assertGl(); + + int thisTeamIndex = world->getThisTeamIndex(); + bool cellExplored = world->showWorldForPlayer(world->getThisFactionIndex()); + bool closed = false; + + Rect2i boundingRect = visibleQuad.computeBoundingRect(); + Rect2i scaledRect = boundingRect / Map::cellScale; + scaledRect.clamp(0, 0, map->getSurfaceW() - 1, map->getSurfaceH() - 1); + + float waterLevel = world->getMap()->getWaterLevel(); + for (int j = scaledRect.p[0].y; j < scaledRect.p[1].y; ++j) { + glBegin(GL_TRIANGLE_STRIP); + + for (int i = scaledRect.p[0].x; i <= scaledRect.p[1].x; ++i) { + SurfaceCell *tc0 = map->getSurfaceCell(i, j); + SurfaceCell *tc1 = map->getSurfaceCell(i, j + 1); + if (tc0 == NULL) { + throw megaglest_runtime_error("tc0 == NULL"); + } + if (tc1 == NULL) { + throw megaglest_runtime_error("tc1 == NULL"); + } + + if (cellExplored == false) { + cellExplored = (tc0->isExplored(thisTeamIndex) || tc1->isExplored(thisTeamIndex)); + } + + if (cellExplored == true && tc0->getNearSubmerged()) { + glNormal3f(0.f, 1.f, 0.f); + closed = false; + + triangleCount += 2; + pointCount += 2; + + //vertex 1 + glMaterialfv( + GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, + computeWaterColor(waterLevel, tc1->getHeight()).ptr()); + glMultiTexCoord2fv(GL_TEXTURE1, tc1->getFowTexCoord().ptr()); + glTexCoord3f(i, 1.f, waterAnim); + glVertex3f( + static_cast(i)*Map::mapScale, + waterLevel, + static_cast(j + 1)*Map::mapScale); + + //vertex 2 + glMaterialfv( + GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, + computeWaterColor(waterLevel, tc0->getHeight()).ptr()); + glMultiTexCoord2fv(GL_TEXTURE1, tc0->getFowTexCoord().ptr()); + glTexCoord3f(i, 0.f, waterAnim); + glVertex3f( + static_cast(i)*Map::mapScale, + waterLevel, + static_cast(j)*Map::mapScale); + + } else { + if (closed == false) { + pointCount += 2; + + //vertex 1 + glMaterialfv( + GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, + computeWaterColor(waterLevel, tc1->getHeight()).ptr()); + glMultiTexCoord2fv(GL_TEXTURE1, tc1->getFowTexCoord().ptr()); + glTexCoord3f(i, 1.f, waterAnim); + glVertex3f( + static_cast(i)*Map::mapScale, + waterLevel, + static_cast(j + 1)*Map::mapScale); + + //vertex 2 + glMaterialfv( + GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, + computeWaterColor(waterLevel, tc0->getHeight()).ptr()); + glMultiTexCoord2fv(GL_TEXTURE1, tc0->getFowTexCoord().ptr()); + glTexCoord3f(i, 0.f, waterAnim); + glVertex3f( + static_cast(i)*Map::mapScale, + waterLevel, + static_cast(j)*Map::mapScale); + + glEnd(); + glBegin(GL_TRIANGLE_STRIP); + closed = true; + } + } + } + glEnd(); + } + + //restore + glPopAttrib(); + + assertGl(); + } + + void Renderer::renderTeamColorCircle() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + VisibleQuadContainerCache &qCache = getQuadCache(); + if (qCache.visibleQuadUnitList.empty() == false) { + + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glDepthFunc(GL_ALWAYS); + glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + glLineWidth(2.f); + + for (int visibleUnitIndex = 0; + visibleUnitIndex < (int) qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { + Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; + Vec3f currVec = unit->getCurrVectorFlat(); + Vec3f color = unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0); + glColor4f(color.x, color.y, color.z, 0.7f); + renderSelectionCircle(currVec, unit->getType()->getSize(), 0.8f, 0.05f); + } glPopAttrib(); } } - } - return objectList; -} - -// ==================== gl caps ==================== - -void Renderer::checkGlCaps() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(glActiveTexture == NULL) { - string message; - - message += "Your system supports OpenGL version ["; - message += getGlVersion() + string("]\n"); - message += "ZetaGlest needs a version that supports\n"; - message += "glActiveTexture (OpenGL 1.3) or the ARB_multitexture extension."; - - throw megaglest_runtime_error(message.c_str(),true); - } - - //opengl 2.1 - if(glewIsSupported("GL_VERSION_2_1") == false) { - string message; - - message += "Your system supports OpenGL version ["; - message += getGlVersion() + string("]\n"); - message += "ZetaGlest needs at least version 2.1 to work\n"; - message += "You may solve this problem by installing your latest video card drivers"; - - throw megaglest_runtime_error(message.c_str(),true); - } - - //opengl 1.4 or extension - //if(!isGlVersionSupported(1, 4, 0)){ - if(glewIsSupported("GL_VERSION_1_4") == false) { - checkExtension("GL_ARB_texture_env_crossbar", "ZetaGlest"); - } -} - -void Renderer::checkGlOptionalCaps() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //shadows - if(shadows == sProjected || shadows == sShadowMapping) { - if(getGlMaxTextureUnits() < 3) { - throw megaglest_runtime_error("Your system doesn't support 3 texture units, required for shadows"); - } - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //shadow mapping - if(shadows == sShadowMapping) { - checkExtension("GL_ARB_shadow", "Shadow Mapping"); - //checkExtension("GL_ARB_shadow_ambient", "Shadow Mapping"); - //checkExtension("GL_ARB_depth_texture", "Shadow Mapping"); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void Renderer::checkExtension(const string &extension, const string &msg) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(!isGlExtensionSupported(extension.c_str())) { - string str= "OpenGL extension not supported: " + extension + ", required for " + msg; - throw megaglest_runtime_error(str); - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -// ==================== init 3d lists ==================== - -void Renderer::init3dList() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - render3dSetup(); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //const Metrics &metrics= Metrics::getInstance(); - - //assertGl(); - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //list3d= glGenLists(1); - //assertGl(); - //list3dValid=true; - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //glNewList(list3d, GL_COMPILE_AND_EXECUTE); - //need to execute, because if not gluPerspective takes no effect and gluLoadMatrix is wrong - //render3dSetup(); - //glEndList(); - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //assert - //assertGl(); -} - -void Renderer::render3dSetup() { - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - const Metrics &metrics= Metrics::getInstance(); - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //misc - glViewport(0, 0, metrics.getScreenW(), metrics.getScreenH()); - glClearColor(fowColor.x, fowColor.y, fowColor.z, fowColor.w); - glFrontFace(GL_CW); - glEnable(GL_CULL_FACE); - loadProjectionMatrix(); - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //texture state - glActiveTexture(shadowTexUnit); - glDisable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - glActiveTexture(fowTexUnit); - glDisable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - glActiveTexture(baseTexUnit); - glEnable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //material state - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, defSpecularColor.ptr()); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, defAmbientColor.ptr()); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, defDiffuseColor.ptr()); - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glColor4fv(defColor.ptr()); - - //blend state - glDisable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //alpha test state - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.f); - - //depth test state - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); - glDepthFunc(GL_LESS); - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //lighting state - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - - //matrix mode - glMatrixMode(GL_MODELVIEW); - - //stencil test - glDisable(GL_STENCIL_TEST); - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //fog - const Tileset *tileset= NULL; - if(game != NULL && game->getWorld() != NULL) { - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - tileset = game->getWorld()->getTileset(); - } - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(tileset != NULL && tileset->getFog()) { - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - glEnable(GL_FOG); - if(tileset->getFogMode()==fmExp) { - glFogi(GL_FOG_MODE, GL_EXP); - } - else { - glFogi(GL_FOG_MODE, GL_EXP2); - } - - glFogf(GL_FOG_DENSITY, tileset->getFogDensity()); - glFogfv(GL_FOG_COLOR, tileset->getFogColor().ptr()); - } - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void Renderer::init2dList() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - -// //this list sets the state for the 2d rendering -// list2d= glGenLists(1); -// assertGl(); -// list2dValid=true; -// -// glNewList(list2d, GL_COMPILE); -// render2dMenuSetup(); -// glEndList(); -// -// assertGl(); -} - -void Renderer::render2dMenuSetup() { - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - const Metrics &metrics= Metrics::getInstance(); - //projection - glViewport(0, 0, metrics.getScreenW(), metrics.getScreenH()); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, metrics.getVirtualW(), 0, metrics.getVirtualH(), 0, 1); - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //modelview - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //disable everything - glDisable(GL_BLEND); - glDisable(GL_LIGHTING); - glDisable(GL_ALPHA_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_STENCIL_TEST); - glDisable(GL_FOG); - glDisable(GL_CULL_FACE); - glFrontFace(GL_CCW); - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(glActiveTexture != NULL) { - glActiveTexture(baseTexUnit); - } - else { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s] Line: %d\nglActiveTexture == NULL\nglActiveTexture is only supported if the GL version is 1.3 or greater,\nor if the ARB_multitexture extension is supported!",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glDisable(GL_TEXTURE_2D); - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //blend func - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - //color - glColor4f(1.f, 1.f, 1.f, 1.f); - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -//void Renderer::init3dListMenu(const MainMenu *mm) { -// if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { -// return; -// } -// -// //this->mm3d = mm; -// //printf("In [%s::%s Line: %d] this->custom_mm3d [%p] this->mm3d [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->custom_mm3d,this->mm3d); -// -///* -// assertGl(); -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// -// const Metrics &metrics= Metrics::getInstance(); -// //const MenuBackground *mb= mm->getConstMenuBackground(); -// const MenuBackground *mb = NULL; -// if(mm != NULL) { -// mb = mm->getConstMenuBackground(); -// } -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// -// if(this->customlist3dMenu != NULL) { -// *this->customlist3dMenu = glGenLists(1); -// assertGl(); -// } -// else { -// list3dMenu= glGenLists(1); -// assertGl(); -// list3dMenuValid=true; -// } -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// -// if(this->customlist3dMenu != NULL) { -// glNewList(*this->customlist3dMenu, GL_COMPILE); -// } -// else { -// glNewList(list3dMenu, GL_COMPILE); -// } -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// //misc -// glViewport(0, 0, metrics.getScreenW(), metrics.getScreenH()); -// glClearColor(0.4f, 0.4f, 0.4f, 1.f); -// glFrontFace(GL_CW); -// glEnable(GL_CULL_FACE); -// glMatrixMode(GL_PROJECTION); -// glLoadIdentity(); -// gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, 1000000); -// -// //texture state -// glEnable(GL_TEXTURE_2D); -// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); -// -// //material state -// glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, defSpecularColor.ptr()); -// glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, defAmbientColor.ptr()); -// glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, defDiffuseColor.ptr()); -// glColor4fv(defColor.ptr()); -// glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); -// -// //blend state -// glDisable(GL_BLEND); -// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -// -// //alpha test state -// glEnable(GL_ALPHA_TEST); -// glAlphaFunc(GL_GREATER, 0.f); -// -// //depth test state -// glEnable(GL_DEPTH_TEST); -// glDepthMask(GL_TRUE); -// glDepthFunc(GL_LESS); -// -// //lighting state -// glEnable(GL_LIGHTING); -// -// //matrix mode -// glMatrixMode(GL_MODELVIEW); -// -// //stencil test -// glDisable(GL_STENCIL_TEST); -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// -// //fog -// if(mb != NULL && mb->getFog()){ -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// -// glEnable(GL_FOG); -// glFogi(GL_FOG_MODE, GL_EXP2); -// glFogf(GL_FOG_DENSITY, mb->getFogDensity()); -// } -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// -// glEndList(); -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// -// //assert -// assertGl(); -//*/ -//} - -void Renderer::render3dMenuSetup(const MainMenu *mm) { - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - const Metrics &metrics= Metrics::getInstance(); - const MenuBackground *mb = NULL; - if(mm != NULL) { - mb = mm->getConstMenuBackground(); - } - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //misc - glViewport(0, 0, metrics.getScreenW(), metrics.getScreenH()); - glClearColor(0.4f, 0.4f, 0.4f, 1.f); - glFrontFace(GL_CW); - glEnable(GL_CULL_FACE); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, 1000000); - - //texture state - glEnable(GL_TEXTURE_2D); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - //material state - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, defSpecularColor.ptr()); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, defAmbientColor.ptr()); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, defDiffuseColor.ptr()); - glColor4fv(defColor.ptr()); - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - - //blend state - glDisable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - //alpha test state - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.f); - - //depth test state - glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); - glDepthFunc(GL_LESS); - - //lighting state - glEnable(GL_LIGHTING); - - //matrix mode - glMatrixMode(GL_MODELVIEW); - - //stencil test - glDisable(GL_STENCIL_TEST); - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //fog - if(mb != NULL && mb->getFog()) { - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - glEnable(GL_FOG); - glFogi(GL_FOG_MODE, GL_EXP2); - glFogf(GL_FOG_DENSITY, mb->getFogDensity()); - } - - //assert - assertGl(); - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} -// ==================== misc ==================== - -void Renderer::loadProjectionMatrix() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - GLdouble clipping; - const Metrics &metrics= Metrics::getInstance(); - - assertGl(); - - clipping= photoMode ? perspFarPlane*100 : perspFarPlane; - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, clipping); - - assertGl(); -} - -void Renderer::enableProjectiveTexturing() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - glTexGenfv(GL_S, GL_EYE_PLANE, &shadowMapMatrix[0]); - glTexGenfv(GL_T, GL_EYE_PLANE, &shadowMapMatrix[4]); - glTexGenfv(GL_R, GL_EYE_PLANE, &shadowMapMatrix[8]); - glTexGenfv(GL_Q, GL_EYE_PLANE, &shadowMapMatrix[12]); - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glEnable(GL_TEXTURE_GEN_R); - glEnable(GL_TEXTURE_GEN_Q); -} - -// ==================== private aux drawing ==================== -void Renderer::renderHealthBar(Vec3f v, Unit *unit, float height, bool lineBorder, const Texture2D *texture, const Texture2D *backgroundTexture) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - int numberOfBars=1; - int barCount=0; - float hp=unit->getHpRatio(); - float ep=-1.f; - if(unit->getType()->getTotalMaxEp(unit->getTotalUpgrade()) !=0 ) { - ep=unit->getEpRatio(); - numberOfBars++; - } - int productionPercent=unit->getProductionPercent(); - if(productionPercent!=-1) { - numberOfBars++; - } - int size=unit->getType()->getSize(); - - - Vec3f rightVector; - Vec3f upVector; - Vec3f rightVectorTexture; - Vec3f upVectorTexture; - v.y+=1; - float modelview[16]; - float width=(float)size/6+0.25f; - float red; - float green; - float brightness=0.8f; - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - - // get the current modelview state - glGetFloatv(GL_MODELVIEW_MATRIX , modelview); - rightVector= Vec3f(modelview[0], modelview[4], modelview[8]); - upVector= Vec3f(modelview[1], modelview[5], modelview[9]); - rightVectorTexture=rightVector*2; - upVectorTexture=upVector*4; - - //from green to yellow to red - - if(hp >= 0.75f) { - green=1; - red=1-((2*hp-1)-0.5f); - } else { - red=1; - green=0.5f+(2*hp-1); - } - - if(red>1.0f) red=1.0f; - if(green>1.0f) green=1.0f; - float yOffset=(float)numberOfBars/2.f; - - if(backgroundTexture!=NULL) { - //backgroundTexture - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, static_cast(backgroundTexture)->getHandle()); - glColor4f(1.f,1.f,1.f,1.f); - //glColor4f(red+0.1f,green+0.1f,0.1f,0.5f); - glBegin(GL_QUADS); - glTexCoord2i(0,1); - glVertex3fv((v - (rightVectorTexture*width - upVectorTexture*height*yOffset)).ptr()); - glTexCoord2i(0,0); - glVertex3fv((v - (rightVectorTexture*width + upVectorTexture*height*yOffset)).ptr()); - glTexCoord2i(1,0); - glVertex3fv((v + (rightVectorTexture*width - upVectorTexture*height*yOffset)).ptr()); - glTexCoord2i(1,1); - glVertex3fv((v + (rightVectorTexture*width + upVectorTexture*height*yOffset)).ptr()); - glEnd(); - glDisable(GL_TEXTURE_2D); - } - - //healthbar - glColor4f(red*brightness,green*brightness,0.0f,0.4f); - //hpbar - barCount++; - internalRenderHp(numberOfBars,barCount,hp,v,width,height,rightVector,upVector); - - - if(ep > -1.0f) { - //epbar - barCount++; - //glColor4f(brightness,0,brightness,0.5f); - glColor4f(.15f*brightness,0.3f*brightness,0.8f*brightness,0.7f); - internalRenderHp(numberOfBars,barCount,ep,v,width,height,rightVector,upVector); - } - if(productionPercent!=-1) { - barCount++; - glColor4f(brightness,0,brightness,0.6f); - //glColor4f(0.0f*brightness,0.4f*brightness,0.2f*brightness,0.8f); - internalRenderHp(numberOfBars,barCount,(float)productionPercent/100,v,width,height,rightVector,upVector); - } - - -// glBegin(GL_QUADS); -// if(ep < -2.0f) { -// //hpbar -// glVertex3fv((v - (rightVector*width - upVector*height)).ptr()); -// glVertex3fv((v - (rightVector*width + upVector*height)).ptr()); -// glVertex3fv((v + (rightVector*hp*width - upVector*height)).ptr()); -// glVertex3fv((v + (rightVector*hp*width + upVector*height)).ptr()); -// -// } else { -// //hpbar -// glVertex3fv((v - (rightVector*width - upVector*height)).ptr()); -// glVertex3fv((v - (rightVector*width + upVector*height*0.0f)).ptr()); -// glVertex3fv((v + (rightVector*hp*width - upVector*height*0.0f)).ptr()); -// glVertex3fv((v + (rightVector*hp*width + upVector*height)).ptr()); -// //epbar -// glColor4f(brightness,0,brightness,0.4f); -// glVertex3fv((v - (rightVector*width + upVector*height*0.0f)).ptr()); -// glVertex3fv((v - (rightVector*width + upVector*height)).ptr()); -// glVertex3fv((v + (rightVector*ep*width - upVector*height)).ptr()); -// glVertex3fv((v + (rightVector*ep*width - upVector*height*0.0f)).ptr()); -// } -// glEnd(); - - if(lineBorder) { - //border - glColor4f(red*brightness,green*brightness,0.1f*brightness,0.5f); - glBegin(GL_LINE_LOOP); - glVertex3fv((v - (rightVector*width - upVector*height*yOffset)).ptr()); - glVertex3fv((v - (rightVector*width + upVector*height*yOffset)).ptr()); - glVertex3fv((v + (rightVector*width - upVector*height*yOffset)).ptr()); - glVertex3fv((v + (rightVector*width + upVector*height*yOffset)).ptr()); - glEnd(); - } - - if(texture!=NULL) { - //BorderTexture - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getHandle()); - glColor4f(1.f,1.f,1.f,1.f); - //glColor4f(red+0.1f,green+0.1f,0.1f,0.5f); - glBegin(GL_QUADS); - glTexCoord2i(0,1); - glVertex3fv((v - (rightVectorTexture*width - upVectorTexture*height*yOffset)).ptr()); - glTexCoord2i(0,0); - glVertex3fv((v - (rightVectorTexture*width + upVectorTexture*height*yOffset)).ptr()); - glTexCoord2i(1,0); - glVertex3fv((v + (rightVectorTexture*width - upVectorTexture*height*yOffset)).ptr()); - glTexCoord2i(1,1); - glVertex3fv((v + (rightVectorTexture*width + upVectorTexture*height*yOffset)).ptr()); - glEnd(); - glDisable(GL_TEXTURE_2D); - } - - glPopMatrix(); -} - -void Renderer::internalRenderHp(int numberOfBars, int barNumber, float hp, - Vec3f posVector, float width, float singleHPheight, Vec3f rightVector, Vec3f upVector) { - - float yOffset=(float)numberOfBars*singleHPheight/2; - float offsetTop=yOffset-singleHPheight*(barNumber-1); - float offsetBottom=yOffset-singleHPheight*barNumber; - offsetBottom=offsetBottom*-1; - hp=hp*2-1; - - glBegin(GL_QUADS); - glVertex3fv((posVector - (rightVector*width - upVector*offsetTop)).ptr()); - glVertex3fv((posVector - (rightVector*width + upVector*offsetBottom)).ptr()); - glVertex3fv((posVector + (rightVector*hp*width - upVector*offsetBottom)).ptr()); - glVertex3fv((posVector + (rightVector*hp*width + upVector*offsetTop)).ptr()); - glEnd(); -} - -void Renderer::renderSelectionCircle(Vec3f v, int size, float radius, float thickness) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - GLUquadricObj *disc; - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - - glTranslatef(v.x, v.y, v.z); - glRotatef(90.f, 1.f, 0.f, 0.f); - disc= gluNewQuadric(); - gluQuadricDrawStyle(disc, GLU_FILL); - gluCylinder(disc, radius*(size-thickness), radius*size, thickness, 30, 1); - gluDeleteQuadric(disc); - - glPopMatrix(); - // glBegin (GL_QUAD_STRIP); - // for (float k = 0; k <= 180; k=k+1) { - // float j=degToRad(k); - // glVertex3f(v.x+std::cos(j)*.9*radius*size, v.y+thickness, v.z+std::sin(j)*.9*radius*size); - // glVertex3f(v.x+std::cos(j)*radius*size, v.y, v.z+std::sin(j)*radius*size); - // } - // glEnd(); -} - -void Renderer::renderArrow(const Vec3f &pos1, const Vec3f &pos2, - const Vec3f &color, float width) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - Config &config= Config::getInstance(); - if(config.getBool("RecordMode","false") == true) { - return; - } - - const int tesselation= 3; - const float arrowEndSize= 0.4f; - const float maxlen= 25; - const float blendDelay= 5.f; - - Vec3f dir= Vec3f(pos2-pos1); - float len= dir.length(); - - if(len>maxlen) { - return; - } - float alphaFactor= clamp((maxlen-len)/blendDelay, 0.f, 1.f); - - dir.normalize(); - Vec3f normal= dir.cross(Vec3f(0, 1, 0)); - - Vec3f pos2Left= pos2 + normal*(width-0.05f) - dir*arrowEndSize*width; - Vec3f pos2Right= pos2 - normal*(width-0.05f) - dir*arrowEndSize*width; - Vec3f pos1Left= pos1 + normal*(width+0.05f); - Vec3f pos1Right= pos1 - normal*(width+0.05f); - - //arrow body - glBegin(GL_TRIANGLE_STRIP); - for(int i=0; i<=tesselation; ++i) { - float t= static_cast(i)/tesselation; - Vec3f a= pos1Left.lerp(t, pos2Left); - Vec3f b= pos1Right.lerp(t, pos2Right); - Vec4f c= Vec4f(color, t*0.25f*alphaFactor); - - glColor4fv(c.ptr()); - - glVertex3fv(a.ptr()); - glVertex3fv(b.ptr()); - - } - - glEnd(); - //arrow end - glBegin(GL_TRIANGLES); - glVertex3fv((pos2Left + normal*(arrowEndSize-0.1f)).ptr()); - glVertex3fv((pos2Right - normal*(arrowEndSize-0.1f)).ptr()); - glVertex3fv((pos2 + dir*(arrowEndSize-0.1f)).ptr()); - glEnd(); -} - -void Renderer::renderProgressBar3D(int size, int x, int y, Font3D *font, int customWidth, - string prefixLabel,bool centeredText,int customHeight) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - // Makiong this smaller than 14 is a bad idea (since the font size is never smaller than that) - int progressbarHeight = (customHeight > 0 ? customHeight : 14); - int currentSize = size; - int maxSize = maxProgressBar; - string renderText = intToStr(static_cast(size)) + "%"; - if(customWidth > 0) { - if(size > 0) { - currentSize = (int)((double)customWidth * ((double)size / 100.0)); - } - maxSize = customWidth; - //if(maxSize <= 0) { - // maxSize = maxProgressBar; - //} - } - if(prefixLabel != "") { - renderText = prefixLabel + renderText; - } - - //bar - glBegin(GL_QUADS); - glColor4fv(progressBarFront2.ptr()); - glVertex2i(x, y); - glVertex2i(x, y + progressbarHeight); - glColor4fv(progressBarFront1.ptr()); - glVertex2i(x + currentSize, y + progressbarHeight); - glVertex2i(x + currentSize, y); - glEnd(); - - //transp bar - glEnable(GL_BLEND); - glBegin(GL_QUADS); - glColor4fv(progressBarBack2.ptr()); - glVertex2i(x + currentSize, y); - glVertex2i(x + currentSize, y + progressbarHeight); - glColor4fv(progressBarBack1.ptr()); - glVertex2i(x + maxSize, y + progressbarHeight); - glVertex2i(x + maxSize, y); - glEnd(); - glDisable(GL_BLEND); - - //text - //glColor3fv(defColor.ptr()); - //printf("Render progress bar3d renderText [%s] y = %d, centeredText = %d\n",renderText.c_str(),y, centeredText); - - renderTextBoundingBox3D(renderText, font, defColor, x, y, maxSize, - progressbarHeight, true, true, false,-1,-1); -} - -void Renderer::renderProgressBar(int size, int x, int y, Font2D *font, int customWidth, - string prefixLabel,bool centeredText) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - int currentSize = size; - int maxSize = maxProgressBar; - string renderText = intToStr(static_cast(size)) + "%"; - if(customWidth > 0) { - if(size > 0) { - currentSize = (int)((double)customWidth * ((double)size / 100.0)); - } - maxSize = customWidth; - //if(maxSize <= 0) { - // maxSize = maxProgressBar; - //} - } - if(prefixLabel != "") { - renderText = prefixLabel + renderText; - } - - //bar - glBegin(GL_QUADS); - glColor4fv(progressBarFront2.ptr()); - glVertex2i(x, y); - glVertex2i(x, y+10); - glColor4fv(progressBarFront1.ptr()); - glVertex2i(x + currentSize, y+10); - glVertex2i(x + currentSize, y); - glEnd(); - - //transp bar - glEnable(GL_BLEND); - glBegin(GL_QUADS); - glColor4fv(progressBarBack2.ptr()); - glVertex2i(x + currentSize, y); - glVertex2i(x + currentSize, y+10); - glColor4fv(progressBarBack1.ptr()); - glVertex2i(x + maxSize, y+10); - glVertex2i(x + maxSize, y); - glEnd(); - glDisable(GL_BLEND); - - //text - glColor3fv(defColor.ptr()); - - //textRenderer->begin(font); - TextRendererSafeWrapper safeTextRender(textRenderer,font); - if(centeredText == true) { - textRenderer->render(renderText.c_str(), x + maxSize / 2, y, centeredText); - } - else { - textRenderer->render(renderText.c_str(), x, y, centeredText); - } - //textRenderer->end(); - safeTextRender.end(); -} - - -//void Renderer::renderTile(const Vec2i &pos) { -// if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { -// return; -// } -// -// const Map *map= game->getWorld()->getMap(); -// Vec2i scaledPos= pos * Map::cellScale; -// -// glMatrixMode(GL_MODELVIEW); -// glPushMatrix(); -// glTranslatef(-0.5f, 0.f, -0.5f); -// -// glInitNames(); -// for(int i=0; i < Map::cellScale; ++i) { -// for(int j=0; j < Map::cellScale; ++j) { -// -// Vec2i renderPos= scaledPos + Vec2i(i, j); -// -// glPushName(renderPos.y); -// glPushName(renderPos.x); -// -// glDisable(GL_CULL_FACE); -// -// float h1 = map->getCell(renderPos.x, renderPos.y)->getHeight(); -// float h2 = map->getCell(renderPos.x, renderPos.y+1)->getHeight(); -// float h3 = map->getCell(renderPos.x+1, renderPos.y)->getHeight(); -// float h4 = map->getCell(renderPos.x+1, renderPos.y+1)->getHeight(); -// -// glBegin(GL_TRIANGLE_STRIP); -// glVertex3f( -// static_cast(renderPos.x), -// h1, -// static_cast(renderPos.y)); -// glVertex3f( -// static_cast(renderPos.x), -// h2, -// static_cast(renderPos.y+1)); -// glVertex3f( -// static_cast(renderPos.x+1), -// h3, -// static_cast(renderPos.y)); -// glVertex3f( -// static_cast(renderPos.x+1), -// h4, -// static_cast(renderPos.y+1)); -// glEnd(); -// -// glPopName(); -// glPopName(); -// } -// } -// -// glPopMatrix(); -//} - -void Renderer::renderQuad(int x, int y, int w, int h, const Texture2D *texture) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - if(texture == NULL) { - printf("\n**WARNING** detected a null texture to render in renderQuad!\n"); - return; - } - - if(w < 0) { - w = texture->getPixmapConst()->getW(); - } - if(h < 0) { - h = texture->getPixmapConst()->getH(); - } - - glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getHandle()); - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2i(0, 1); - glVertex2i(x, y+h); - glTexCoord2i(0, 0); - glVertex2i(x, y); - glTexCoord2i(1, 1); - glVertex2i(x+w, y+h); - glTexCoord2i(1, 0); - glVertex2i(x+w, y); - glEnd(); -} - -Renderer::Shadows Renderer::strToShadows(const string &s){ - if(s=="Projected"){ - return sProjected; - } - else if(s=="ShadowMapping"){ - return sShadowMapping; - } - return sDisabled; -} - -string Renderer::shadowsToStr(Shadows shadows){ - switch(shadows){ - case sDisabled: - return "Disabled2"; - case sProjected: - return "Projected"; - case sShadowMapping: - return "ShadowMapping"; - default: - assert(false); - return ""; - } -} - -Texture2D::Filter Renderer::strToTextureFilter(const string &s){ - if(s=="Bilinear"){ - return Texture2D::fBilinear; - } - else if(s=="Trilinear"){ - return Texture2D::fTrilinear; - } - - throw megaglest_runtime_error("Error converting from string to FilterType, found: "+s); -} - -void Renderer::setAllowRenderUnitTitles(bool value) { - allowRenderUnitTitles = value; -} - -// This method renders titles for units -void Renderer::renderUnitTitles3D(Font3D *font, Vec3f color) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - //std::map unitRenderedList; - - if(visibleFrameUnitList.empty() == false) { - //printf("Render Unit titles ON\n"); - - for(int idx = 0; idx < (int)visibleFrameUnitList.size(); idx++) { - const Unit *unit = visibleFrameUnitList[idx]; - if(unit != NULL) { - if(unit->getVisible() == true) { - if(unit->getCurrentUnitTitle() != "") { - //get the screen coordinates - Vec3f screenPos = unit->getScreenPos(); - renderText3D(unit->getCurrentUnitTitle(), font, color, std::fabs(screenPos.x) + 5, std::fabs(screenPos.y) + 5, false); - //unitRenderedList[unit->getId()] = true; - } - else { - string str = unit->getFullName(unit->showTranslatedTechTree()) + " - " + intToStr(unit->getId()) + " [" + unit->getPosNotThreadSafe().getString() + "]"; - Vec3f screenPos = unit->getScreenPos(); - renderText3D(str, font, color, std::fabs(screenPos.x) + 5, std::fabs(screenPos.y) + 5, false); + void Renderer::renderSpecialHighlightUnits(std::map unitHighlightList) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true || unitHighlightList.empty() == true) { + return; + } + + VisibleQuadContainerCache &qCache = getQuadCache(); + if (qCache.visibleQuadUnitList.empty() == false) { + + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glDepthFunc(GL_ALWAYS); + glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + glLineWidth(2.f); + + for (int visibleUnitIndex = 0; + visibleUnitIndex < (int) qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { + Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; + + std::map::iterator iterFindSpecialUnit = unitHighlightList.find(unit->getId()); + if (iterFindSpecialUnit != unitHighlightList.end()) { + Vec3f color = unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0); + float radius = 1.0f; + float thickness = 0.1f; + float alpha = 0.65f; + + HighlightSpecialUnitInfo &specialInfo = iterFindSpecialUnit->second; + if (specialInfo.color.x >= 0) { + color.x = specialInfo.color.x; + color.y = specialInfo.color.y; + color.z = specialInfo.color.z; + } + if (specialInfo.color.w >= 0) { + alpha = specialInfo.color.w; + } + if (specialInfo.radius > 0) { + radius = specialInfo.radius; + } + if (specialInfo.thickness > 0) { + thickness = specialInfo.thickness; + } + + glColor4f(color.x, color.y, color.z, alpha); + + Vec3f currVec = unit->getCurrVectorFlat(); + renderSelectionCircle(currVec, unit->getType()->getSize(), radius, thickness); } } + glPopAttrib(); } } - visibleFrameUnitList.clear(); - } - /* - if(renderUnitTitleList.empty() == false) { - for(int idx = 0; idx < renderUnitTitleList.size(); idx++) { - std::pair &unitInfo = renderUnitTitleList[idx]; - Unit *unit = unitInfo.first; - - const World *world= game->getWorld(); - Unit *validUnit = world->findUnitById(unit->getId()); - - if(validUnit != NULL && unitRenderedList.find(validUnit->getId()) == unitRenderedList.end()) { - string str = validUnit->getFullName() + " - " + intToStr(validUnit->getId()); - //get the screen coordinates - Vec3f &screenPos = unitInfo.second; - renderText(str, font, color, fabs(screenPos.x) + 5, fabs(screenPos.y) + 5, false); - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] screenPos.x = %f, screenPos.y = %f, screenPos.z = %f\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,screenPos.x,screenPos.y,screenPos.z); + void Renderer::renderTeamColorPlane() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; } - } - renderUnitTitleList.clear(); - } - */ -} -// This method renders titles for units -void Renderer::renderUnitTitles(Font2D *font, Vec3f color) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - //std::map unitRenderedList; - - if(visibleFrameUnitList.empty() == false) { - //printf("Render Unit titles ON\n"); - - for(int idx = 0; idx < (int)visibleFrameUnitList.size(); idx++) { - const Unit *unit = visibleFrameUnitList[idx]; - if(unit != NULL) { - if(unit->getCurrentUnitTitle() != "") { - //get the screen coordinates - Vec3f screenPos = unit->getScreenPos(); - renderText(unit->getCurrentUnitTitle(), font, color, std::fabs(screenPos.x) + 5, std::fabs(screenPos.y) + 5, false); - - //unitRenderedList[unit->getId()] = true; - } - else { - string str = unit->getFullName(unit->showTranslatedTechTree()) + " - " + intToStr(unit->getId()) + " [" + unit->getPosNotThreadSafe().getString() + "]"; - Vec3f screenPos = unit->getScreenPos(); - renderText(str, font, color, std::fabs(screenPos.x) + 5, std::fabs(screenPos.y) + 5, false); + VisibleQuadContainerCache &qCache = getQuadCache(); + if (qCache.visibleQuadUnitList.empty() == false) { + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glEnable(GL_COLOR_MATERIAL); + const Texture2D *texture = CoreData::getInstance().getTeamColorTexture(); + for (int visibleUnitIndex = 0; + visibleUnitIndex < (int) qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { + Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; + if (unit->isAlive()) { + Vec3f currVec = unit->getCurrVectorFlat(); + renderTeamColorEffect(currVec, visibleUnitIndex, unit->getType()->getSize(), + unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0), texture); + } } + glDisable(GL_COLOR_MATERIAL); + glPopAttrib(); } } - visibleFrameUnitList.clear(); - } - /* - if(renderUnitTitleList.empty() == false) { - for(int idx = 0; idx < renderUnitTitleList.size(); idx++) { - std::pair &unitInfo = renderUnitTitleList[idx]; - Unit *unit = unitInfo.first; + void Renderer::renderGhostModel(const UnitType *building, const Vec2i pos, CardinalDir facing, Vec4f *forceColor) { + //const UnitType *building= gui->getBuilding(); + //const Vec2i &pos= gui->getPosObjWorld(); - const World *world= game->getWorld(); - Unit *validUnit = world->findUnitById(unit->getId()); - - if(validUnit != NULL && unitRenderedList.find(validUnit->getId()) == unitRenderedList.end()) { - string str = validUnit->getFullName() + " - " + intToStr(validUnit->getId()); - //get the screen coordinates - Vec3f &screenPos = unitInfo.second; - renderText(str, font, color, fabs(screenPos.x) + 5, fabs(screenPos.y) + 5, false); - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] screenPos.x = %f, screenPos.y = %f, screenPos.z = %f\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,screenPos.x,screenPos.y,screenPos.z); + //const Gui *gui= game->getGui(); + //const Mouse3d *mouse3d= gui->getMouse3d(); + const Map *map = game->getWorld()->getMap(); + if (map == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s] Line: %d map == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); } - } - renderUnitTitleList.clear(); - } - */ -} -void Renderer::removeObjectFromQuadCache(const Object *o) { - VisibleQuadContainerCache &qCache = getQuadCache(); - for(int visibleIndex = 0; - visibleIndex < (int)qCache.visibleObjectList.size(); ++visibleIndex) { - Object *currentObj = qCache.visibleObjectList[visibleIndex]; - if(currentObj == o) { - qCache.visibleObjectList.erase(qCache.visibleObjectList.begin() + visibleIndex); - break; - } - } -} + glPushMatrix(); + Vec3f pos3f = Vec3f(pos.x, map->getCell(pos)->getHeight(), pos.y); -void Renderer::removeUnitFromQuadCache(const Unit *unit) { - VisibleQuadContainerCache &qCache = getQuadCache(); - for(int visibleIndex = 0; - visibleIndex < (int)qCache.visibleQuadUnitList.size(); ++visibleIndex) { - Unit *currentUnit = qCache.visibleQuadUnitList[visibleIndex]; - if(currentUnit == unit) { - qCache.visibleQuadUnitList.erase(qCache.visibleQuadUnitList.begin() + visibleIndex); - break; - } - } - for(int visibleIndex = 0; - visibleIndex < (int)qCache.visibleUnitList.size(); ++visibleIndex) { - Unit *currentUnit = qCache.visibleUnitList[visibleIndex]; - if(currentUnit == unit) { - qCache.visibleUnitList.erase(qCache.visibleUnitList.begin() + visibleIndex); - break; - } - } -} + //selection building placement + float offset = building->getSize() / 2.f - 0.5f; + glTranslatef(pos3f.x + offset, pos3f.y, pos3f.z + offset); -VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame, - bool forceNew) { - //forceNew = true; - if(game != NULL && game->getWorld() != NULL) { - const World *world= game->getWorld(); - - if(forceNew == true || - (updateOnDirtyFrame == true && - (world->getFrameCount() != quadCache.cacheFrame || - visibleQuad != quadCache.lastVisibleQuad))) { - - // Dump cached info - //if(forceNew == true || visibleQuad != quadCache.lastVisibleQuad) { - //quadCache.clearCacheData(); - //} - //else { - quadCache.clearVolatileCacheData(); - worldToScreenPosCache.clear(); - //} - - // Unit calculations - for(int i = 0; i < world->getFactionCount(); ++i) { - const Faction *faction = world->getFaction(i); - for(int j = 0; j < faction->getUnitCount(); ++j) { - Unit *unit= faction->getUnit(j); - - bool unitCheckedForRender = false; - if(VisibleQuadContainerCache::enableFrustumCalcs == true) { - //bool insideQuad = PointInFrustum(quadCache.frustumData, unit->getCurrVector().x, unit->getCurrVector().y, unit->getCurrVector().z ); - bool insideQuad = CubeInFrustum(quadCache.frustumData, unit->getCurrMidHeightVector().x, unit->getCurrMidHeightVector().y, unit->getCurrMidHeightVector().z, unit->getType()->getRenderSize()); - bool renderInMap = world->toRenderUnit(unit); - if(insideQuad == false || renderInMap == false) { - unit->setVisible(false); - if(renderInMap == true) { - quadCache.visibleUnitList.push_back(unit); - } - unitCheckedForRender = true; // no more need to check any further; - // Currently don't need this list - //quadCache.inVisibleUnitList.push_back(unit); - } - } - if(unitCheckedForRender == false) { - bool insideQuad = visibleQuad.isInside(unit->getPos()); - bool renderInMap = world->toRenderUnit(unit); - if(insideQuad == true && renderInMap == true) { - quadCache.visibleQuadUnitList.push_back(unit); - } - else { - unit->setVisible(false); - // Currently don't need this list - //quadCache.inVisibleUnitList.push_back(unit); - } - - if(renderInMap == true) { - quadCache.visibleUnitList.push_back(unit); - } - } - - bool unitBuildPending = unit->isBuildCommandPending(); - if(unitBuildPending == true) { - const UnitBuildInfo &pendingUnit = unit->getBuildCommandPendingInfo(); - const Vec2i &pos = pendingUnit.pos; - const Map *map= world->getMap(); - - bool unitBuildCheckedForRender = false; - - //printf("#1 Unit is about to build another unit\n"); - - if(VisibleQuadContainerCache::enableFrustumCalcs == true) { - Vec3f pos3f= Vec3f(pos.x, map->getCell(pos)->getHeight(), pos.y); - //bool insideQuad = PointInFrustum(quadCache.frustumData, unit->getCurrVector().x, unit->getCurrVector().y, unit->getCurrVector().z ); - bool insideQuad = CubeInFrustum(quadCache.frustumData, pos3f.x, pos3f.y, pos3f.z, pendingUnit.buildUnit->getRenderSize()); - bool renderInMap = world->toRenderUnit(pendingUnit); - if(insideQuad == false || renderInMap == false) { - if(renderInMap == true) { - quadCache.visibleQuadUnitBuildList.push_back(pendingUnit); - } - unitBuildCheckedForRender = true; // no more need to check any further; - // Currently don't need this list - //quadCache.inVisibleUnitList.push_back(unit); - } - - //printf("#2 Unit build added? insideQuad = %d, renderInMap = %d\n",insideQuad,renderInMap); - } - - if(unitBuildCheckedForRender == false) { - bool insideQuad = visibleQuad.isInside(pos); - bool renderInMap = world->toRenderUnit(pendingUnit); - if(insideQuad == true && renderInMap == true) { - quadCache.visibleQuadUnitBuildList.push_back(pendingUnit); - } - else { - //unit->setVisible(false); - // Currently don't need this list - //quadCache.inVisibleUnitList.push_back(unit); - } - - //printf("#3 Unit build added? insideQuad = %d, renderInMap = %d\n",insideQuad,renderInMap); - } - - //printf("#4 quadCache.visibleQuadUnitBuildList.size() = %d\n",quadCache.visibleQuadUnitBuildList.size()); - } + //choose color + Vec4f color; + if (forceColor != NULL) { + color = *forceColor; + } else { + if (map->isFreeCells(pos, building->getSize(), fLand)) { + color = Vec4f(1.f, 1.f, 1.f, 0.5f); + } else { + // Uint64 tc=game->getTickCount(); + // float red=0.49f+((tc%4*1.0f)/2); + color = Vec4f(1.0f, 0.f, 0.f, 0.5f); } } - if(forceNew == true || visibleQuad != quadCache.lastVisibleQuad) { - // Object calculations - const Map *map= world->getMap(); - // clear visibility of old objects - for(int visibleIndex = 0; - visibleIndex < (int)quadCache.visibleObjectList.size(); ++visibleIndex){ - quadCache.visibleObjectList[visibleIndex]->setVisible(false); + glColor4fv(color.ptr()); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color.ptr()); + Model *buildingModel = building->getFirstStOfClass(scStop)->getAnimation(); + + if (facing != CardinalDir::NORTH) { + float rotateAmount = facing * 90.f; + if (rotateAmount > 0) { + glRotatef(rotateAmount, 0.f, 1.f, 0.f); } - quadCache.clearNonVolatileCacheData(); + } - //int loops1=0; - PosQuadIterator pqi(map,visibleQuad, Map::cellScale); - while(pqi.next()) { - const Vec2i &pos= pqi.getPos(); - if(map->isInside(pos)) { - //loops1++; - const Vec2i &mapPos = Map::toSurfCoords(pos); + buildingModel->updateInterpolationData(0.f, false); + modelRenderer->render(buildingModel); - //quadCache.visibleCellList.push_back(mapPos); + glPopMatrix(); + } - SurfaceCell *sc = map->getSurfaceCell(mapPos); - Object *o = sc->getObject(); + void Renderer::renderUnits(bool airUnits, const int renderFps) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } - if(VisibleQuadContainerCache::enableFrustumCalcs == true) { - if(o != NULL) { - //bool insideQuad = PointInFrustum(quadCache.frustumData, o->getPos().x, o->getPos().y, o->getPos().z ); - bool insideQuad = CubeInFrustum(quadCache.frustumData, o->getPos().x, o->getPos().y, o->getPos().z, 1); - if(insideQuad == false) { - o->setVisible(false); - continue; - } + //Unit *unit=NULL; + //const World *world= game->getWorld(); + MeshCallbackTeamColor meshCallbackTeamColor; + + //assert + assertGl(); + + if (visibleFrameUnitList.empty() == false) { + visibleFrameUnitList.clear(); + //visibleFrameUnitListCameraKey = ""; + //if(visibleFrameUnitListCameraKey != game->getGameCamera()->getCameraMovementKey()) { + // worldToScreenPosCache.clear(); + //} + } + + VisibleQuadContainerCache &qCache = getQuadCache(); + if (qCache.visibleQuadUnitList.empty() == false) { + bool modelRenderStarted = false; + for (int visibleUnitIndex = 0; + visibleUnitIndex < (int) qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { + Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; + + if ((airUnits == false && unit->getType()->getField() == fAir) || (airUnits == true && unit->getType()->getField() != fAir)) { + continue; + } + meshCallbackTeamColor.setTeamTexture(unit->getFaction()->getTexture()); + + if (modelRenderStarted == false) { + modelRenderStarted = true; + + glPushAttrib(GL_ENABLE_BIT | GL_FOG_BIT | GL_LIGHTING_BIT | GL_TEXTURE_BIT); + glEnable(GL_COLOR_MATERIAL); + + if (!shadowsOffDueToMinRender) { + if (shadows == sShadowMapping) { + glActiveTexture(shadowTexUnit); + glEnable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, shadowMapHandle); + + static_cast(modelRenderer)->setDuplicateTexCoords(true); + enableProjectiveTexturing(); } } + glActiveTexture(baseTexUnit); - bool cellExplored = world->showWorldForPlayer(world->getThisFactionIndex()); - if(cellExplored == false) { - cellExplored = sc->isExplored(world->getThisTeamIndex()); - } + modelRenderer->begin(true, true, true, false, &meshCallbackTeamColor); + } - bool isExplored = (cellExplored == true && o != NULL); - //bool isVisible = (sc->isVisible(world->getThisTeamIndex()) && o != NULL); - bool isVisible = true; + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); - if(isExplored == true && isVisible == true) { - quadCache.visibleObjectList.push_back(o); - o->setVisible(true); - } + //translate + Vec3f currVec = unit->getCurrVectorFlat(); + glTranslatef(currVec.x, currVec.y, currVec.z); + + //rotate + float zrot = unit->getRotationZ(); + float xrot = unit->getRotationX(); + if (zrot != .0f) { + glRotatef(zrot, 0.f, 0.f, 1.f); + } + if (xrot != .0f) { + glRotatef(xrot, 1.f, 0.f, 0.f); + } + glRotatef(unit->getRotation(), 0.f, 1.f, 0.f); + + //dead alpha + const SkillType *st = unit->getCurrSkill(); + if (st->getClass() == scDie && static_cast(st)->getFade()) { + float alpha = 1.0f - unit->getAnimProgressAsFloat(); + glDisable(GL_COLOR_MATERIAL); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Vec4f(1.0f, 1.0f, 1.0f, alpha).ptr()); + } else { + glEnable(GL_COLOR_MATERIAL); + // we cut off a tiny bit here to avoid problems with fully transparent texture parts cutting units in background rendered later. + glAlphaFunc(GL_GREATER, 0.02f); + } + + //render + Model *model = unit->getCurrentModelPtr(); + //printf("Rendering model [%d - %s]\n[%s]\nCamera [%s]\nDistance: %f\n",unit->getId(),unit->getType()->getName().c_str(),unit->getCurrVector().getString().c_str(),this->gameCamera->getPos().getString().c_str(),this->gameCamera->getPos().dist(unit->getCurrVector())); + + //if(this->gameCamera->getPos().dist(unit->getCurrVector()) <= SKIP_INTERPOLATION_DISTANCE) { + model->updateInterpolationData(unit->getAnimProgressAsFloat(), unit->isAlive() && !unit->isAnimProgressBound()); + //} + + modelRenderer->render(model); + triangleCount += model->getTriangleCount(); + pointCount += model->getVertexCount(); + + glPopMatrix(); + unit->setVisible(true); + + if (showDebugUI == true && + (showDebugUILevel & debugui_unit_titles) == debugui_unit_titles) { + + unit->setScreenPos(computeScreenPosition(currVec)); + visibleFrameUnitList.push_back(unit); + visibleFrameUnitListCameraKey = game->getGameCamera()->getCameraMovementKey(); } } - //printf("Frame # = %d loops1 = %d\n",world->getFrameCount(),loops1); - - //int loops2=0; - - std::map markedCells = game->getMapMarkedCellList(); - - const Rect2i mapBounds(0, 0, map->getSurfaceW()-1, map->getSurfaceH()-1); - Quad2i scaledQuad = visibleQuad / Map::cellScale; - PosQuadIterator pqis(map,scaledQuad); - while(pqis.next()) { - const Vec2i &pos= pqis.getPos(); - if(mapBounds.isInside(pos)) { - //loops2++; - if(VisibleQuadContainerCache::enableFrustumCalcs == false) { - quadCache.visibleScaledCellList.push_back(pos); - - if(markedCells.empty() == false) { - if(markedCells.find(pos) != markedCells.end()) { - //printf("#1 ******** VISIBLE SCALED CELL FOUND in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",pos.getString().c_str(),markedCells.size()); - //if(markedCells.empty() == false) { - //SurfaceCell *sc = map->getSurfaceCell(pos); - //quadCache.visibleScaledCellToScreenPosList[pos]=computeScreenPosition(sc->getVertex()); - updateMarkedCellScreenPosQuadCache(pos); - } - else { - //printf("#1 VISIBLE SCALED CELL NOT FOUND in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",pos.getString().c_str(),markedCells.size()); - } - } - } - else { - //bool insideQuad = false; - - //if( !insideQuad) { - SurfaceCell *sc = map->getSurfaceCell(pos.x, pos.y); - bool insideQuad = CubeInFrustum(quadCache.frustumData, sc->getVertex().x, sc->getVertex().y, sc->getVertex().z, 0); - //} - if( !insideQuad) { - SurfaceCell *sc = map->getSurfaceCell(pos.x+1, pos.y); - insideQuad = CubeInFrustum(quadCache.frustumData, sc->getVertex().x, sc->getVertex().y, sc->getVertex().z, 0); - } - if( !insideQuad) { - SurfaceCell *sc = map->getSurfaceCell(pos.x, pos.y+1); - insideQuad = CubeInFrustum(quadCache.frustumData, sc->getVertex().x, sc->getVertex().y, sc->getVertex().z, 0); - } - if( !insideQuad) { - SurfaceCell *sc = map->getSurfaceCell(pos.x+1, pos.y+1); - insideQuad = CubeInFrustum(quadCache.frustumData, sc->getVertex().x, sc->getVertex().y, sc->getVertex().z, 0); - } - - if(insideQuad == true) { - quadCache.visibleScaledCellList.push_back(pos); - - if(markedCells.empty() == false) { - if(markedCells.find(pos) != markedCells.end()) { - //printf("#2 ******** VISIBLE SCALED CELL FOUND in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",pos.getString().c_str(),markedCells.size()); - //if(markedCells.empty() == false) { - //quadCache.visibleScaledCellToScreenPosList[pos]=computeScreenPosition(sc->getVertex()); - updateMarkedCellScreenPosQuadCache(pos); - } - else { - //printf("#2 VISIBLE SCALED CELL NOT FOUND in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",pos.getString().c_str(),markedCells.size()); - } - } - } - } - } + if (modelRenderStarted == true) { + modelRenderer->end(); + glPopAttrib(); } - //printf("Frame # = %d loops2 = %d\n",world->getFrameCount(),loops2); - } - quadCache.cacheFrame = world->getFrameCount(); - quadCache.lastVisibleQuad = visibleQuad; - } - } - - return quadCache; -} - -void Renderer::updateMarkedCellScreenPosQuadCache(Vec2i pos) { - const World *world= game->getWorld(); - const Map *map= world->getMap(); - - SurfaceCell *sc = map->getSurfaceCell(pos); - quadCache.visibleScaledCellToScreenPosList[pos]=computeScreenPosition(sc->getVertex()); -} - -void Renderer::forceQuadCacheUpdate() { - quadCache.cacheFrame = -1; - - Vec2i clearPos(-1,-1); - quadCache.lastVisibleQuad.p[0] = clearPos; - quadCache.lastVisibleQuad.p[1] = clearPos; - quadCache.lastVisibleQuad.p[2] = clearPos; - quadCache.lastVisibleQuad.p[3] = clearPos; -} - -std::pair Renderer::posInCellQuadCache(Vec2i pos) { - std::pair result = make_pair(false,Vec3f()); - if(std::find( - quadCache.visibleScaledCellList.begin(), - quadCache.visibleScaledCellList.end(), - pos) != quadCache.visibleScaledCellList.end()) { - result.first = true; - result.second = quadCache.visibleScaledCellToScreenPosList[pos]; - } - return result; -} - -//Vec3f Renderer::getMarkedCellScreenPosQuadCache(Vec2i pos) { -// Vec3f result(-1,-1,-1); -// if(std::find( -// quadCache.visibleScaledCellList.begin(), -// quadCache.visibleScaledCellList.end(), -// pos) != quadCache.visibleScaledCellList.end()) { -// result = quadCache.visibleScaledCellToScreenPosList[pos]; -// } -// return result; -//} - -void Renderer::beginRenderToTexture(Texture2D **renderToTexture) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - static bool supportFBOs = Texture2DGl().supports_FBO_RBO(); - - if(supportFBOs == true && renderToTexture != NULL) { - Config &config= Config::getInstance(); - Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter")); - int maxAnisotropy = config.getInt("FilterMaxAnisotropy"); - - const Metrics &metrics = Metrics::getInstance(); - - *renderToTexture = GraphicsInterface::getInstance().getFactory()->newTexture2D(); - Texture2DGl *texture = static_cast(*renderToTexture); - texture->setMipmap(false); - Pixmap2D *pixmapScreenShot = texture->getPixmap(); - pixmapScreenShot->init(metrics.getScreenW(), metrics.getScreenH(), 4); - texture->setForceCompressionDisabled(true); - texture->init(textureFilter,maxAnisotropy); - texture->setup_FBO_RBO(); - - assertGl(); - - if(texture->checkFrameBufferStatus() == false) { - //printf("******************** WARNING CANNOT Attach to FBO!\n"); - texture->end(); - delete texture; - *renderToTexture=NULL; - } - } -} - -void Renderer::endRenderToTexture(Texture2D **renderToTexture) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - static bool supportFBOs = Texture2DGl().supports_FBO_RBO(); - - if(supportFBOs == true && renderToTexture != NULL && *renderToTexture != NULL) { - Texture2DGl *texture = static_cast(*renderToTexture); - if(texture != NULL) { - texture->dettachFrameBufferFromTexture(); - } - - assertGl(); - } -} - -void Renderer::renderMapPreview( const MapPreview *map, bool renderAll, - int screenPosX, int screenPosY, - Texture2D **renderToTexture) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - static bool supportFBOs = Texture2DGl().supports_FBO_RBO(); - if(Config::getInstance().getBool("LegacyMapPreviewRendering","false") == true) { - supportFBOs = false; - } - - //static bool supportFBOs = false; - const Metrics &metrics= Metrics::getInstance(); - - float alt = 0; - float showWater = 0; - int renderMapHeight = 64; - int renderMapWidth = 64; - float cellSize = 2; - float playerCrossSize = 2; - float clientW = renderMapWidth * cellSize; - float clientH = renderMapHeight * cellSize;; - float minDimension = std::min(metrics.getVirtualW(), metrics.getVirtualH()); - - // stretch small maps to 128x128 - if(map->getW() < map->getH()) { - cellSize = cellSize * renderMapHeight / map->getH(); - } - else { - cellSize = cellSize * renderMapWidth / map->getW(); - } - - assertGl(); - - if(supportFBOs == true && renderToTexture != NULL) { - Config &config= Config::getInstance(); - Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter")); - int maxAnisotropy = config.getInt("FilterMaxAnisotropy"); - - *renderToTexture = GraphicsInterface::getInstance().getFactory()->newTexture2D(); - Texture2DGl *texture = static_cast(*renderToTexture); - texture->setMipmap(false); - Pixmap2D *pixmapScreenShot = texture->getPixmap(); - pixmapScreenShot->init(minDimension, minDimension, 4); - texture->setForceCompressionDisabled(true); - texture->init(textureFilter,maxAnisotropy); - texture->setup_FBO_RBO(); - - assertGl(); - - if(texture->checkFrameBufferStatus() == false) { - //printf("******************** WARNING CANNOT Attach to FBO!\n"); - texture->end(); - delete texture; - *renderToTexture=NULL; - } - } - - if(supportFBOs == true && renderToTexture != NULL && *renderToTexture != NULL) { - cellSize =1; - clientW = minDimension; - clientH = minDimension; - int mapMaxDimensionSize = std::max(map->getW(),map->getH()); - switch(mapMaxDimensionSize) { - case 8: - cellSize = 96; - break; - case 16: - cellSize = 48; - break; - case 32: - cellSize = 24; - break; - case 64: - cellSize = 12; - break; - case 128: - cellSize = 6; - break; - case 256: - cellSize = 3; - break; - case 512: - cellSize = 2; - break; - } - } - - glFrontFace(GL_CW); - glEnable(GL_CULL_FACE); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - assertGl(); - - GLint viewport[4]; // Where The original Viewport Values Will Be Stored - - if(supportFBOs == true && renderToTexture != NULL && *renderToTexture != NULL) { - glGetIntegerv(GL_VIEWPORT, viewport); - glOrtho(0, clientW, 0, clientH, 0, 1); - glViewport(0, 0, clientW, clientH); - } - else { - glOrtho(0, metrics.getVirtualW(), 0, metrics.getVirtualH(), 0, 1); - } - - glMatrixMode(GL_MODELVIEW); - - glPushMatrix(); - glLoadIdentity(); - - if(supportFBOs == false || renderToTexture == NULL || *renderToTexture == NULL) { - glTranslatef(static_cast(screenPosX),static_cast(screenPosY)-clientH,0.0f); - } - - assertGl(); - - glPushAttrib(GL_CURRENT_BIT); - glLineWidth(1); - glColor3f(0, 0, 0); - - for (int j = 0; j < map->getH(); j++) { - for (int i = 0; i < map->getW(); i++) { - //surface - alt = map->getHeight(i, j) / 20.f; - showWater = map->getWaterLevel()/ 20.f - alt; - showWater = (showWater > 0)? showWater:0; - Vec3f surfColor; - switch (map->getSurface(i, j)) { - case st_Grass: - surfColor = Vec3f(0.0, 0.8f * alt, 0.f + showWater); - break; - case st_Secondary_Grass: - surfColor = Vec3f(0.4f * alt, 0.6f * alt, 0.f + showWater); - break; - case st_Road: - surfColor = Vec3f(0.6f * alt, 0.3f * alt, 0.f + showWater); - break; - case st_Stone: - surfColor = Vec3f(0.7f * alt, 0.7f * alt, 0.7f * alt + showWater); - break; - case st_Ground: - surfColor = Vec3f(0.7f * alt, 0.5f * alt, 0.3f * alt + showWater); - break; } - glColor3fv(surfColor.ptr()); + //restore + static_cast(modelRenderer)->setDuplicateTexCoords(true); + // reset alpha + glAlphaFunc(GL_GREATER, 0.0f); + //assert + assertGl(); + + } + + void Renderer::renderUnitsToBuild(const int renderFps) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + //assert + assertGl(); + + VisibleQuadContainerCache &qCache = getQuadCache(); + if (qCache.visibleQuadUnitBuildList.empty() == false) { + + glMatrixMode(GL_MODELVIEW); + glPushAttrib(GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_BLEND); + glDisable(GL_STENCIL_TEST); + glDepthFunc(GL_LESS); + glEnable(GL_COLOR_MATERIAL); + glDepthMask(GL_FALSE); + + modelRenderer->begin(true, true, false, false); + + for (int visibleUnitIndex = 0; + visibleUnitIndex < (int) qCache.visibleQuadUnitBuildList.size(); ++visibleUnitIndex) { + const UnitBuildInfo &buildUnit = qCache.visibleQuadUnitBuildList[visibleUnitIndex]; + //Vec4f modelColor= Vec4f(0.f, 1.f, 0.f, 0.5f); + const Vec3f teamColor = buildUnit.unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0); + Vec4f modelColor = Vec4f(teamColor.x, teamColor.y, teamColor.z, 0.4f); + renderGhostModel(buildUnit.buildUnit, buildUnit.pos, buildUnit.facing, &modelColor); + + //printf("Rendering to build unit index = %d\n",visibleUnitIndex); + } + + modelRenderer->end(); + + glDisable(GL_COLOR_MATERIAL); + glPopAttrib(); + } + + //assert + assertGl(); + + } + + void Renderer::renderTeamColorEffect(Vec3f &v, int heigth, int size, Vec3f color, const Texture2D *texture) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + //GLUquadricObj *disc; + float halfSize = size; + //halfSize=halfSize; + float heigthoffset = 0.5 + heigth % 25 * 0.004; + glPushMatrix(); + glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getHandle()); + glColor4f(color.x, color.y, color.z, 1.0f); glBegin(GL_TRIANGLE_STRIP); - glVertex2f(i * cellSize, clientH - j * cellSize - cellSize); - glVertex2f(i * cellSize, clientH - j * cellSize); - glVertex2f(i * cellSize + cellSize, clientH - j * cellSize - cellSize); - glVertex2f(i * cellSize + cellSize, clientH - j * cellSize); + glTexCoord2i(0, 1); + glVertex3f(v.x - halfSize, v.y + heigthoffset, v.z + halfSize); + glTexCoord2i(0, 0); + glVertex3f(v.x - halfSize, v.y + heigthoffset, v.z - halfSize); + glTexCoord2i(1, 1); + + glVertex3f(v.x + halfSize, v.y + heigthoffset, v.z + halfSize); + glTexCoord2i(1, 0); + glVertex3f(v.x + halfSize, v.y + heigthoffset, v.z - halfSize); + glEnd(); + glPopMatrix(); + + } + + void Renderer::renderMorphEffects() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + VisibleQuadContainerCache &qCache = getQuadCache(); + if (qCache.visibleQuadUnitList.empty() == false) { + bool initialized = false; + int frameCycle = 0; + for (int visibleUnitIndex = 0; + visibleUnitIndex < (int) qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { + Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; + if (unit->getCurrSkill() != NULL && unit->getCurrSkill()->getClass() == scMorph) { + Command *command = unit->getCurrCommand(); + if (command != NULL && command->getCommandType()->commandTypeClass == ccMorph) { + const MorphCommandType *mct = static_cast(command->getCommandType()); + const UnitType* mType = mct->getMorphUnit(); + + if (mType->getSize() > unit->getType()->getSize() || + mType->getField() != unit->getType()->getField()) { + if (!initialized) { + const World *world = game->getWorld(); + frameCycle = world->getFrameCount() % 40; + + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glDepthFunc(GL_ALWAYS); + glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + glLineWidth(2.f); + initialized = true; + } + + Vec3f currVec = unit->getCurrVectorFlat(); + currVec = Vec3f(currVec.x, currVec.y + 0.3f, currVec.z); + if (mType->getField() == fAir && unit->getType()->getField() == fLand) { + currVec = Vec3f(currVec.x, currVec.y + game->getWorld()->getTileset()->getAirHeight(), currVec.z); + } + if (mType->getField() == fLand && unit->getType()->getField() == fAir) { + currVec = Vec3f(currVec.x, currVec.y - game->getWorld()->getTileset()->getAirHeight(), currVec.z); + } + + float color = frameCycle * 0.4f / 40; + glColor4f(color, color, 0.4f, 0.4f); + renderSelectionCircle(currVec, mType->getSize(), frameCycle*0.85f / 40, 0.2f); + } + } + } + } + if (initialized) { + glPopAttrib(); + } + } + } + + + + void Renderer::renderSelectionEffects(int healthbarMode) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + Config &config = Config::getInstance(); + if (config.getBool("RecordMode", "false") == true) { + return; + } + + const World *world = game->getWorld(); + const Map *map = world->getMap(); + const Selection *selection = game->getGui()->getSelection(); + const Object *selectedResourceObject = game->getGui()->getSelectedResourceObject(); + + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glDepthFunc(GL_ALWAYS); + glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + glLineWidth(2.f); + + //units + for (int i = 0; i < selection->getCount(); ++i) { + + const Unit *unit = selection->getUnit(i); + if (unit != NULL) { + //translate + Vec3f currVec = unit->getCurrVectorFlat(); + currVec.y += 0.3f; + + //selection circle + int finalHealthbarMode = hbvUndefined; + if (healthbarMode == hbvUndefined) { + finalHealthbarMode = unit->getFaction()->getType()->getHealthbarVisible(); + } else { + finalHealthbarMode = healthbarMode; + } + bool healthbarsVisible = ((finalHealthbarMode & hbvAlways) || + (finalHealthbarMode & hbvSelected) || + (finalHealthbarMode & hbvIfNeeded)); + float selectionCircleThickness = 0.2f; + float hpRatio = unit->getHpRatio(); + if (healthbarsVisible) { + selectionCircleThickness = 0.05f; + hpRatio = 1.0f; + } + + if (world->getThisFactionIndex() == unit->getFactionIndex()) { + if (showDebugUI == true && + ((showDebugUILevel & debugui_unit_titles) == debugui_unit_titles) && + unit->getCommandSize() > 0 && + dynamic_cast(unit->getCurrCommand()->getCommandType()) != NULL) { + glColor4f(hpRatio, hpRatio, hpRatio, 0.3f); + } else { + glColor4f(0, hpRatio, 0, 0.3f); + } + } else if (world->getThisTeamIndex() == unit->getTeam()) { + glColor4f(hpRatio, hpRatio, 0, 0.3f); + } else { + glColor4f(hpRatio, 0, 0, 0.3f); + } + renderSelectionCircle(currVec, unit->getType()->getSize(), selectionCircleRadius, selectionCircleThickness); + + if (showDebugUI == true && + (showDebugUILevel & debugui_unit_titles) == debugui_unit_titles) { + + const UnitPathInterface *path = unit->getPath(); + const UnitPathBasic *pathfinder = (path == NULL ? NULL : dynamic_cast(path)); + if (pathfinder != NULL) { + vector pathList = pathfinder->getQueue(); + + Vec2i lastPosValue; + for (int i = 0; i < (int) pathList.size(); ++i) { + Vec2i curPosValue = pathList[i]; + if (i == 0) { + lastPosValue = curPosValue; + } + Vec3f currVec2 = unit->getVectorFlat(lastPosValue, curPosValue); + currVec2.y += 0.3f; + renderSelectionCircle(currVec2, 1, selectionCircleRadius); + } + } + } + + //magic circle + if (!healthbarsVisible && world->getThisFactionIndex() == unit->getFactionIndex() && unit->getType()->getMaxEp() > 0) { + glColor4f(unit->getEpRatio() / 2.f, unit->getEpRatio(), unit->getEpRatio(), 0.5f); + renderSelectionCircle(currVec, unit->getType()->getSize(), magicCircleRadius); + } + + // Render Attack-boost circles + if (showDebugUI == true) { + //const std::pair > ¤tAttackBoostUnits = unit->getCurrentAttackBoostUnits(); + const UnitAttackBoostEffectOriginator &effect = unit->getAttackBoostOriginatorEffect(); + + if (effect.skillType->isAttackBoostEnabled() == true) { + glColor4f(MAGENTA.x, MAGENTA.y, MAGENTA.z, MAGENTA.w); + renderSelectionCircle(currVec, 1, effect.skillType->getAttackBoost()->radius, .25f / effect.skillType->getAttackBoost()->radius); + + for (unsigned int i = 0; i < effect.currentAttackBoostUnits.size(); ++i) { + // Remove attack boost upgrades from unit + int findUnitId = effect.currentAttackBoostUnits[i]; + Unit *affectedUnit = game->getWorld()->findUnitById(findUnitId); + if (affectedUnit != NULL) { + Vec3f currVecBoost = affectedUnit->getCurrVectorFlat(); + currVecBoost.y += 0.3f; + + renderSelectionCircle(currVecBoost, affectedUnit->getType()->getSize(), 1.f); + } + } + } + } + + //meeting point arrow + if (unit->getType()->getMeetingPoint()) { + Vec2i pos = unit->getMeetingPos(); + map->clampPos(pos); + + Vec3f arrowTarget = Vec3f(pos.x, map->getCell(pos)->getHeight(), pos.y); + renderArrow(unit->getCurrVectorFlat(), arrowTarget, Vec3f(0.f, 0.f, 1.f), 0.3f); + } + } + } + + if (selectedResourceObject != NULL && selectedResourceObject->getResource() != NULL && selection->getCount() < 1) { + Resource *r = selectedResourceObject->getResource(); + int defaultValue = r->getType()->getDefResPerPatch(); + float colorValue = static_cast(r->getAmount()) / static_cast(defaultValue); + glColor4f(0.1f, 0.1f, colorValue, 0.4f); + renderSelectionCircle(selectedResourceObject->getPos(), 2, selectionCircleRadius); + } + //target arrow + if (selection->getCount() == 1) { + const Unit *unit = selection->getUnit(0); + if (unit != NULL) { + //comand arrow + if (focusArrows && unit->anyCommand()) { + const CommandType *ct = unit->getCurrCommand()->getCommandType(); + if (ct->getClicks() != cOne) { + + //arrow color + Vec3f arrowColor; + switch (ct->getClass()) { + case ccMove: + arrowColor = Vec3f(0.f, 1.f, 0.f); + break; + case ccAttack: + case ccAttackStopped: + arrowColor = Vec3f(1.f, 0.f, 0.f); + break; + default: + arrowColor = Vec3f(1.f, 1.f, 0.f); + break; + } + + //arrow target + Vec3f arrowTarget; + Command *c = unit->getCurrCommand(); + if (c->getUnit() != NULL) { + arrowTarget = c->getUnit()->getCurrVectorFlat(); + } else { + Vec2i pos = c->getPos(); + map->clampPos(pos); + + arrowTarget = Vec3f(pos.x, map->getCell(pos)->getHeight(), pos.y); + } + + renderArrow(unit->getCurrVectorFlat(), arrowTarget, arrowColor, 0.3f); + } + } + } + } + + //render selection hightlights + if (game->getGui()->getHighlightedUnit() != NULL) { + const Unit *unit = game->getGui()->getHighlightedUnit(); + + if (unit->isHighlighted()) { + float highlight = unit->getHightlight(); + if (game->getWorld()->getThisFactionIndex() == unit->getFactionIndex()) { + glColor4f(0.f, 1.f, 0.f, highlight); + } else { + glColor4f(1.f, 0.f, 0.f, highlight); + } + + Vec3f v = unit->getCurrVectorFlat(); + v.y += 0.3f; + renderSelectionCircle(v, unit->getType()->getSize(), 0.5f + 0.4f*highlight); + } + } + // old inefficient way to render highlights + // for(int i=0; i < world->getFactionCount(); ++i) { + // for(int j=0; j < world->getFaction(i)->getUnitCount(); ++j) { + // const Unit *unit= world->getFaction(i)->getUnit(j); + // + // if(unit->isHighlighted()) { + // float highlight= unit->getHightlight(); + // if(game->getWorld()->getThisFactionIndex() == unit->getFactionIndex()) { + // glColor4f(0.f, 1.f, 0.f, highlight); + // } + // else{ + // glColor4f(1.f, 0.f, 0.f, highlight); + // } + // + // Vec3f v= unit->getCurrVectorFlat(); + // v.y+= 0.3f; + // renderSelectionCircle(v, unit->getType()->getSize(), 0.5f+0.4f*highlight ); + // } + // } + // } + //render resource selection highlight + if (game->getGui()->getHighlightedResourceObject() != NULL) { + const Object* object = game->getGui()->getHighlightedResourceObject(); + if (object->isHighlighted()) { + float highlight = object->getHightlight(); + glColor4f(0.1f, 0.1f, 1.0f, highlight); + Vec3f v = object->getPos(); + v.y += 0.3f; + renderSelectionCircle(v, 2, 0.4f + 0.4f*highlight); + } + } + + glPopAttrib(); + } + + void Renderer::renderHealthBars(int healthbarMode) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + Config &config = Config::getInstance(); + if (config.getBool("RecordMode", "false") == true) { + return; + } + + if (config.getBool("PhotoMode")) { + return; + } + + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glDepthFunc(GL_ALWAYS); + glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); + glLineWidth(2.f); + + VisibleQuadContainerCache &qCache = getQuadCache(); + if (qCache.visibleQuadUnitList.empty() == false) { + for (int visibleUnitIndex = 0; + visibleUnitIndex < (int) qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { + Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; + if (isHealthBarVisible(unit, healthbarMode)) { + float healthbarheight; + float healthbarthickness; + const Texture2D *healthbarTexture; + const Texture2D *healthbarBackgroundTexture; + bool healthbarLineBorder; + + //get settings of the faction + healthbarheight = unit->getFaction()->getType()->getHealthbarHeight(); + healthbarthickness = unit->getFaction()->getType()->getHealthbarThickness(); + healthbarLineBorder = unit->getFaction()->getType()->isHealthbarLineBorder(); + CoreData &coreData = CoreData::getInstance(); + //First try faction texture then use core Texture + if (unit->getFaction()->getType()->isHealthbarBorderTextureEnabled()) { + healthbarTexture = unit->getFaction()->getType()->getHealthbarTexture(); + if (healthbarTexture == NULL) { + healthbarTexture = coreData.getHealthbarTexture(); + } + } else { + healthbarTexture = NULL; + } + if (unit->getFaction()->getType()->isHealthbarBackgroundTextureEnabled()) { + healthbarBackgroundTexture = unit->getFaction()->getType()->getHealthbarBackgroundTexture(); + if (healthbarBackgroundTexture == NULL) { + healthbarBackgroundTexture = coreData.getHealthbarBackgroundTexture(); + } + } else { + healthbarBackgroundTexture = NULL; + } + + //replace them by the ones from the unit if existent + if (unit->getType()->getHealthbarVisible() != hbvOff && unit->getType()->getHealthbarVisible() != hbvUndefined) { + if (unit->getType()->getHealthbarHeight() != -100.0f) { + healthbarheight = unit->getType()->getHealthbarHeight(); + } + if (unit->getType()->getHealthbarThickness() != -1.0f) { + healthbarthickness = unit->getType()->getHealthbarThickness(); + } + } + + Vec3f currVec = unit->getCurrVectorFlat(); + if (healthbarheight == -100.0f) { + currVec.y += unit->getType()->getHeight(); + } else { + currVec.y += healthbarheight; + } + renderHealthBar(currVec, unit, healthbarthickness, healthbarLineBorder, healthbarTexture, healthbarBackgroundTexture); + } + } + } + glPopAttrib(); + } + + bool Renderer::isHealthBarVisible(const Unit *unit, int healthbarMode) { + int healthbarVisible = hbvUndefined; + //check options (hotkey) + if (healthbarMode == hbvUndefined) { + healthbarVisible = unit->getFaction()->getType()->getHealthbarVisible(); + } else { + healthbarVisible = healthbarMode; + } + + //replace them by the ones from the unit if existent + if (unit->getType()->getHealthbarVisible() != hbvOff && unit->getType()->getHealthbarVisible() != hbvUndefined) { + if (healthbarMode == hbvUndefined) { //don't override the visible setting when hotkey is not hbvUndefined + healthbarVisible = unit->getType()->getHealthbarVisible(); + } + } + + bool settingsWantToRenderThem = !(healthbarVisible == hbvUndefined || (healthbarVisible&hbvOff)) + && ((healthbarVisible&hbvAlways) + || ((healthbarVisible&hbvIfNeeded) && unit->getHp() < unit->getType()->getMaxHp() + unit->getTotalUpgrade()->getMaxHp()) + || ((healthbarVisible&hbvIfNeeded) && unit->getType()->getMaxEp() > 0 && unit->getEp() < unit->getType()->getMaxEp() + unit->getTotalUpgrade()->getMaxEp()) + || ((healthbarVisible&hbvIfNeeded) && unit->getProductionPercent() > 0) + || ((healthbarVisible&hbvSelected) && game->getGui()->isSelected(unit))); + + if (unit->isAlive() && (settingsWantToRenderThem)) { + return true; + } + return false; + } + + void Renderer::renderWaterEffects() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + const World *world = game->getWorld(); + const WaterEffects *we = world->getWaterEffects(); + const Map *map = world->getMap(); + CoreData &coreData = CoreData::getInstance(); + float height = map->getWaterLevel() + 0.001f; + + assertGl(); + + glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + glDepthMask(GL_FALSE); + glDepthFunc(GL_LEQUAL); + glEnable(GL_COLOR_MATERIAL); + + //glNormal3f(0.f, 1.f, 0.f); + + //splashes + glBindTexture(GL_TEXTURE_2D, static_cast(coreData.getWaterSplashTexture())->getHandle()); + + //!!! + Vec2f texCoords[4]; + Vec3f vertices[4]; + Vec3f normals[4]; + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + for (int i = 0; i < we->getWaterSplashCount(); ++i) { + const WaterSplash *ws = we->getWaterSplash(i); + + //render only if enabled + if (ws->getEnabled()) { + + //render only if visible + Vec2i intPos = Vec2i(static_cast(ws->getPos().x), static_cast(ws->getPos().y)); + const Vec2i &mapPos = Map::toSurfCoords(intPos); + + bool visible = map->getSurfaceCell(mapPos)->isVisible(world->getThisTeamIndex()); + if (visible == false && world->showWorldForPlayer(world->getThisFactionIndex()) == true) { + visible = true; + } + + if (visible == true) { + float scale = ws->getAnim()*ws->getSize(); + texCoords[0] = Vec2f(0.f, 1.f); + vertices[0] = Vec3f(ws->getPos().x - scale, height, ws->getPos().y + scale); + normals[0] = Vec3f(0.f, 1.f, 0.f); + + texCoords[1] = Vec2f(0.f, 0.f); + vertices[1] = Vec3f(ws->getPos().x - scale, height, ws->getPos().y - scale); + normals[1] = Vec3f(0.f, 1.f, 0.f); + + texCoords[2] = Vec2f(1.f, 1.f); + vertices[2] = Vec3f(ws->getPos().x + scale, height, ws->getPos().y + scale); + normals[2] = Vec3f(0.f, 1.f, 0.f); + + texCoords[3] = Vec2f(1.f, 0.f); + vertices[3] = Vec3f(ws->getPos().x + scale, height, ws->getPos().y - scale); + normals[3] = Vec3f(0.f, 1.f, 0.f); + + glColor4f(1.f, 1.f, 1.f, 1.f - ws->getAnim()); + glTexCoordPointer(2, GL_FLOAT, 0, &texCoords[0]); + glVertexPointer(3, GL_FLOAT, 0, &vertices[0]); + glNormalPointer(GL_FLOAT, 0, &normals[0]); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + + /* + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0.f, 1.f); + glVertex3f(ws->getPos().x-scale, height, ws->getPos().y+scale); + glTexCoord2f(0.f, 0.f); + glVertex3f(ws->getPos().x-scale, height, ws->getPos().y-scale); + glTexCoord2f(1.f, 1.f); + glVertex3f(ws->getPos().x+scale, height, ws->getPos().y+scale); + glTexCoord2f(1.f, 0.f); + glVertex3f(ws->getPos().x+scale, height, ws->getPos().y-scale); + glEnd(); + */ + } + } + } + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + glPopAttrib(); + + assertGl(); + } + + void Renderer::renderHud() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + Texture2D *hudTexture = game->getGui()->getHudTexture(); + if (hudTexture != NULL) { + const Metrics &metrics = Metrics::getInstance(); + renderTextureQuad(0, 0, metrics.getVirtualW(), metrics.getVirtualH(), hudTexture, 1.0f); + } + } + + void Renderer::renderMinimap() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + const World *world = game->getWorld(); + const Minimap *minimap = world->getMinimap(); + + if (minimap == NULL || minimap->getTexture() == NULL) { + return; + } + + const GameCamera *gameCamera = game->getGameCamera(); + const Pixmap2D *pixmap = minimap->getTexture()->getPixmapConst(); + const Metrics &metrics = Metrics::getInstance(); + const WaterEffects *attackEffects = world->getAttackEffects(); + + int mx = metrics.getMinimapX(); + int my = metrics.getMinimapY(); + int mw = metrics.getMinimapW(); + int mh = metrics.getMinimapH(); + + Vec2f zoom = Vec2f( + static_cast(mw) / pixmap->getW(), + static_cast(mh) / pixmap->getH()); + + assertGl(); + + // render minimap border + Vec4f col = game->getGui()->getDisplay()->getColor(); + glColor4f(col.x*0.5f, col.y*0.5f, col.z*0.5f, 1.0); + + int borderWidth = 2; + glBegin(GL_QUADS); + glVertex2i(mx - borderWidth, my - borderWidth); + glVertex2i(mx - borderWidth, my); + glVertex2i(mx + mw + borderWidth, my); + glVertex2i(mx + mw + borderWidth, my - borderWidth); glEnd(); - //objects - if(renderAll == true) { - switch (map->getObject(i, j)) { - case 0: - glColor3f(0.f, 0.f, 0.f); - break; - case 1: - glColor3f(1.f, 0.f, 0.f); - break; - case 2: - glColor3f(1.f, 1.f, 1.f); - break; - case 3: - glColor3f(0.5f, 0.5f, 1.f); - break; - case 4: - glColor3f(0.f, 0.f, 1.f); - break; - case 5: - glColor3f(0.5f, 0.5f, 0.5f); - break; - case 6: - glColor3f(1.f, 0.8f, 0.5f); - break; - case 7: - glColor3f(0.f, 1.f, 1.f); - break; - case 8: - glColor3f(0.7f, 0.1f, 0.3f); - break; - case 9: - glColor3f(0.5f, 1.f, 0.1f); - break; - case 10: - glColor3f(1.f, 0.2f, 0.8f); - break;// we don't render unvisible blocking objects + glBegin(GL_QUADS); + glVertex2i(mx - borderWidth, my + mh + borderWidth); + glVertex2i(mx - borderWidth, my + mh); + glVertex2i(mx + mw + borderWidth, my + mh); + glVertex2i(mx + mw + borderWidth, my + mh + borderWidth); + glEnd(); + + glBegin(GL_QUADS); + glVertex2i(mx - borderWidth, my); + glVertex2i(mx - borderWidth, my + mh); + glVertex2i(mx, my + mh); + glVertex2i(mx, my); + glEnd(); + + glBegin(GL_QUADS); + glVertex2i(mx + mw, my); + glVertex2i(mx + mw, my + mh); + glVertex2i(mx + mw + borderWidth, my + mh); + glVertex2i(mx + mw + borderWidth, my); + glEnd(); + + assertGl(); + + glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_TEXTURE_BIT); + + //draw map + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + + glActiveTexture(fowTexUnit); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, static_cast(minimap->getFowTexture())->getHandle()); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE); + + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); + + glActiveTexture(baseTexUnit); + glBindTexture(GL_TEXTURE_2D, static_cast(minimap->getTexture())->getHandle()); + + glColor4f(0.5f, 0.5f, 0.5f, 0.2f); + + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0.0f, 1.0f); + glMultiTexCoord2f(fowTexUnit, 0.0f, 1.0f); + glVertex2i(mx, my); + + glTexCoord2f(0.0f, 0.0f); + glMultiTexCoord2f(fowTexUnit, 0.0f, 0.0f); + glVertex2i(mx, my + mh); + + glTexCoord2f(1.0f, 1.0f); + glMultiTexCoord2f(fowTexUnit, 1.0f, 1.0f); + glVertex2i(mx + mw, my); + + glTexCoord2f(1.0f, 0.0f); + glMultiTexCoord2f(fowTexUnit, 1.0f, 0.0f); + glVertex2i(mx + mw, my + mh); + glEnd(); + + glDisable(GL_BLEND); + + glActiveTexture(fowTexUnit); + glDisable(GL_TEXTURE_2D); + glActiveTexture(baseTexUnit); + glDisable(GL_TEXTURE_2D); + + glEnable(GL_BLEND); + + const int itemCount = attackEffects->getWaterSplashCount() * 12; + if (itemCount > 0) { + vector vertices; + vertices.resize(itemCount); + vector colors; + colors.resize(itemCount); + + // draw attack alarm + int vertexIndex = 0; + for (int i = 0; i < attackEffects->getWaterSplashCount(); ++i) { + const WaterSplash *ws = attackEffects->getWaterSplash(i); + float scale = (1 / ws->getAnim()*ws->getSize()) * 5; + //glColor4f(1.f, 1.f, 0.f, 1.f-ws->getAnim()); + float alpha = (1.f - ws->getAnim())*0.01f; + Vec2f pos = ws->getPos() / Map::cellScale; + float attackX = mx + pos.x*zoom.x; + float attackY = my + mh - pos.y*zoom.y; + if (ws->getEnabled()) { + // glBegin(GL_QUADS); + // glVertex2f(attackX-scale, attackY-scale); + // glVertex2f(attackX-scale, attackY+scale); + // glVertex2f(attackX+scale, attackY+scale); + // glVertex2f(attackX+scale, attackY-scale); + // glEnd(); + + colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); + vertices[vertexIndex] = Vec2f(attackX - scale, attackY - scale); + vertexIndex++; + colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); + vertices[vertexIndex] = Vec2f(attackX - scale, attackY + scale); + vertexIndex++; + colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, 0.8f); + vertices[vertexIndex] = Vec2f(attackX, attackY); + vertexIndex++; + + colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); + vertices[vertexIndex] = Vec2f(attackX + scale, attackY + scale); + vertexIndex++; + colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); + vertices[vertexIndex] = Vec2f(attackX - scale, attackY + scale); + vertexIndex++; + colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, 0.8f); + vertices[vertexIndex] = Vec2f(attackX, attackY); + vertexIndex++; + + colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); + vertices[vertexIndex] = Vec2f(attackX + scale, attackY + scale); + vertexIndex++; + colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); + vertices[vertexIndex] = Vec2f(attackX + scale, attackY - scale); + vertexIndex++; + colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, 0.8f); + vertices[vertexIndex] = Vec2f(attackX, attackY); + vertexIndex++; + + colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); + vertices[vertexIndex] = Vec2f(attackX + scale, attackY - scale); + vertexIndex++; + colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, alpha); + vertices[vertexIndex] = Vec2f(attackX - scale, attackY - scale); + vertexIndex++; + colors[vertexIndex] = Vec4f(1.f, 1.f, 0.f, 0.8f); + vertices[vertexIndex] = Vec2f(attackX, attackY); + vertexIndex++; + + /* + glBegin(GL_TRIANGLES); + glColor4f(1.f, 1.f, 0.f, alpha); + glVertex2f(attackX-scale, attackY-scale); + glVertex2f(attackX-scale, attackY+scale); + glColor4f(1.f, 1.f, 0.f, 0.8f); + glVertex2f(attackX, attackY); + glEnd(); + glBegin(GL_TRIANGLES); + glColor4f(1.f, 1.f, 0.f, alpha); + glVertex2f(attackX-scale, attackY+scale); + glVertex2f(attackX+scale, attackY+scale); + glColor4f(1.f, 1.f, 0.f, 0.8f); + glVertex2f(attackX, attackY); + glEnd(); + glBegin(GL_TRIANGLES); + glColor4f(1.f, 1.f, 0.f, alpha); + glVertex2f(attackX+scale, attackY+scale); + glVertex2f(attackX+scale, attackY-scale); + glColor4f(1.f, 1.f, 0.f, 0.8f); + glVertex2f(attackX, attackY); + glEnd(); + glBegin(GL_TRIANGLES); + glColor4f(1.f, 1.f, 0.f, alpha); + glVertex2f(attackX+scale, attackY-scale); + glVertex2f(attackX-scale, attackY-scale); + glColor4f(1.f, 1.f, 0.f, 0.8f); + glVertex2f(attackX, attackY); + glEnd(); + */ + + } } - if ( renderAll && (map->getObject(i, j) != 0) && (map->getObject(i, j) != 10) ) { - glPointSize(cellSize / 2.f); - glBegin(GL_POINTS); - glVertex2f(i * cellSize + cellSize / 2.f, clientH - j * cellSize - cellSize / 2.f); - glEnd(); + if (vertexIndex > 0) { + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glColorPointer(4, GL_FLOAT, 0, &colors[0]); + glVertexPointer(2, GL_FLOAT, 0, &vertices[0]); + glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexIndex); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); } } - // bool found = false; + glDisable(GL_BLEND); - //height lines - // if (!found) { + //draw units + VisibleQuadContainerCache &qCache = getQuadCache(); + std::vector visibleUnitList = qCache.visibleUnitList; - //left - if (i > 0 && map->getHeight(i - 1, j) > map->getHeight(i, j)) { - glColor3fv((surfColor*0.5f).ptr()); - glBegin(GL_LINES); - glVertex2f(i * cellSize, clientH - (j + 1) * cellSize); - glVertex2f(i * cellSize, clientH - j * cellSize); - glEnd(); - } - //down - if (j > 0 && map->getHeight(i, j - 1) > map->getHeight(i, j)) { - glColor3fv((surfColor*0.5f).ptr()); - glBegin(GL_LINES); - glVertex2f(i * cellSize, clientH - j * cellSize); - glVertex2f((i + 1) * cellSize, clientH - j * cellSize); - glEnd(); + const bool showAllUnitsInMinimap = Config::getInstance().getBool("DebugGameSynchUI", "false"); + if (showAllUnitsInMinimap == true) { + visibleUnitList.clear(); + + const World *world = game->getWorld(); + for (unsigned int i = 0; i < (unsigned int) world->getFactionCount(); ++i) { + const Faction *faction = world->getFaction(i); + for (unsigned int j = 0; j < (unsigned int) faction->getUnitCount(); ++j) { + Unit *unit = faction->getUnit(j); + visibleUnitList.push_back(unit); + } } + } + if (visibleUnitList.empty() == false) { + uint32 unitIdx = 0; + vector unit_vertices; + unit_vertices.resize(visibleUnitList.size() * 4); + vector unit_colors; + unit_colors.resize(visibleUnitList.size() * 4); - //left - if (i > 0 && map->getHeight(i - 1, j) < map->getHeight(i, j)) { - glColor3fv((surfColor*2.f).ptr()); - glBegin(GL_LINES); - glVertex2f(i * cellSize, clientH - (j + 1) * cellSize); - glVertex2f(i * cellSize, clientH - j * cellSize); - glEnd(); - } - if (j > 0 && map->getHeight(i, j - 1) < map->getHeight(i, j)) { - glColor3fv((surfColor*2.f).ptr()); - glBegin(GL_LINES); - glVertex2f(i * cellSize, clientH - j * cellSize); - glVertex2f((i + 1) * cellSize, clientH - j * cellSize); - glEnd(); - } - // } - - //resources - if(renderAll == true) { - switch (map->getResource(i, j)) { - case 1: glColor3f(1.f, 1.f, 0.f); break; - case 2: glColor3f(0.5f, 0.5f, 0.5f); break; - case 3: glColor3f(1.f, 0.f, 0.f); break; - case 4: glColor3f(0.f, 0.f, 1.f); break; - case 5: glColor3f(0.5f, 0.5f, 1.f); break; + for (int visibleIndex = 0; + visibleIndex < (int) visibleUnitList.size(); ++visibleIndex) { + Unit *unit = visibleUnitList[visibleIndex]; + if (unit->isAlive() == false) { + continue; } - if (renderAll && map->getResource(i, j) != 0) { + Vec2i pos = unit->getPos() / Map::cellScale; + int size = unit->getType()->getSize(); + Vec3f color = unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0); + + unit_colors[unitIdx] = color; + unit_vertices[unitIdx] = Vec2f(mx + pos.x*zoom.x, my + mh - (pos.y*zoom.y)); + unitIdx++; + + unit_colors[unitIdx] = color; + unit_vertices[unitIdx] = Vec2f(mx + (pos.x + 1)*zoom.x + size, my + mh - (pos.y*zoom.y)); + unitIdx++; + + unit_colors[unitIdx] = color; + unit_vertices[unitIdx] = Vec2f(mx + (pos.x + 1)*zoom.x + size, my + mh - ((pos.y + size)*zoom.y)); + unitIdx++; + + unit_colors[unitIdx] = color; + unit_vertices[unitIdx] = Vec2f(mx + pos.x*zoom.x, my + mh - ((pos.y + size)*zoom.y)); + unitIdx++; + } + + if (unitIdx > 0) { + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glColorPointer(3, GL_FLOAT, 0, &unit_colors[0]); + glVertexPointer(2, GL_FLOAT, 0, &unit_vertices[0]); + glDrawArrays(GL_QUADS, 0, unitIdx); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + } + + } + + renderMarkedCellsOnMinimap(); + + //draw camera + float wRatio = static_cast(metrics.getMinimapW()) / world->getMap()->getW(); + float hRatio = static_cast(metrics.getMinimapH()) / world->getMap()->getH(); + + int x = static_cast(gameCamera->getPos().x * wRatio); + int y = static_cast(gameCamera->getPos().z * hRatio); + + float ang = degToRad(gameCamera->getHAng()); + + glEnable(GL_BLEND); + + int x1; + int y1; + x1 = mx + x + static_cast(20 * std::sin(ang - pi / 5)); + y1 = my + mh - (y - static_cast(20 * std::cos(ang - pi / 5))); + + int x2; + int y2; + x2 = mx + x + static_cast(20 * std::sin(ang + pi / 5)); + y2 = my + mh - (y - static_cast(20 * std::cos(ang + pi / 5))); + + glColor4f(1.f, 1.f, 1.f, 1.f); + glBegin(GL_TRIANGLES); + + glVertex2i(mx + x, my + mh - y); + glColor4f(1.f, 1.f, 1.f, 0.0f); + glVertex2i(x1, y1); + glColor4f(1.f, 1.f, 1.f, 0.0f); + glVertex2i(x2, y2); + + glEnd(); + + glPopAttrib(); + + assertGl(); + } + + void Renderer::renderHighlightedCellsOnMinimap() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + // Draw marked cells + const std::vector *highlightedCells = game->getHighlightedCells(); + if (highlightedCells->empty() == false) { + //const Map *map= game->getWorld()->getMap(); + const World *world = game->getWorld(); + const Minimap *minimap = world->getMinimap(); + int pointersize = 10; + if (minimap == NULL || minimap->getTexture() == NULL) { + return; + } + + //const GameCamera *gameCamera= game->getGameCamera(); + const Pixmap2D *pixmap = minimap->getTexture()->getPixmapConst(); + const Metrics &metrics = Metrics::getInstance(); + + + //int mx= metrics.getMinimapX(); + int my = metrics.getMinimapY(); + int mw = metrics.getMinimapW(); + int mh = metrics.getMinimapH(); + + Vec2f zoom = Vec2f( + static_cast(mw) / pixmap->getW() / 2, + static_cast(mh) / pixmap->getH() / 2); + + for (int i = 0; i < (int) highlightedCells->size(); i++) { + const MarkedCell *mc = &highlightedCells->at(i); + if (mc->getFaction() == NULL || (mc->getFaction()->getTeam() == game->getWorld()->getThisFaction()->getTeam())) { + const Texture2D *texture = game->getHighlightCellTexture(); + Vec3f color(MarkedCell::static_system_marker_color); + if (mc->getFaction() != NULL) { + color = mc->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0); + } + int lighting = (mc->getAliveCount() % 15); + Vec3f myColor = Vec3f(color.x / 2 + .5f / lighting, color.y / 2 + .5f / lighting, color.z / 2 + .5f / lighting); + + Vec2i pos = mc->getTargetPos(); + if (texture != NULL) { + //float alpha = 0.49f+0.5f/(mc->getAliveCount()%15); + float alpha = 1.0f; + renderTextureQuad((int) (pos.x*zoom.x) + pointersize, my + mh - (int) (pos.y*zoom.y), pointersize, pointersize, texture, alpha, &myColor); + } + } + } + } + } + + void Renderer::renderMarkedCellsOnMinimap() { + // Draw marked cells + std::map markedCells = game->getMapMarkedCellList(); + if (markedCells.empty() == false) { + //const Map *map= game->getWorld()->getMap(); + const World *world = game->getWorld(); + const Minimap *minimap = world->getMinimap(); + + if (minimap == NULL || minimap->getTexture() == NULL) { + return; + } + + //const GameCamera *gameCamera= game->getGameCamera(); + const Pixmap2D *pixmap = minimap->getTexture()->getPixmapConst(); + const Metrics &metrics = Metrics::getInstance(); + //const WaterEffects *attackEffects= world->getAttackEffects(); + + int mx = metrics.getMinimapX(); + int my = metrics.getMinimapY(); + int mw = metrics.getMinimapW(); + int mh = metrics.getMinimapH(); + + Vec2f zoom = Vec2f( + static_cast(mw) / pixmap->getW(), + static_cast(mh) / pixmap->getH()); + + uint32 unitIdx = 0; + vector unit_vertices; + unit_vertices.resize(markedCells.size() * 4); + vector unit_colors; + unit_colors.resize(markedCells.size() * 4); + + for (std::map::iterator iterMap = markedCells.begin(); + iterMap != markedCells.end(); ++iterMap) { + MarkedCell &bm = iterMap->second; + if (bm.getPlayerIndex() < 0 || + (bm.getFaction() != NULL && + bm.getFaction()->getTeam() == game->getWorld()->getThisFaction()->getTeam())) { + Vec2i pos = bm.getTargetPos() / Map::cellScale; + float size = 0.5f; + + Vec3f color(MarkedCell::static_system_marker_color); + if (bm.getFaction() != NULL) { + color = bm.getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0); + } + float alpha = 0.65f; + + unit_colors[unitIdx] = Vec4f(color.x, color.y, color.z, alpha); + unit_vertices[unitIdx] = Vec2f(mx + pos.x*zoom.x, my + mh - (pos.y*zoom.y)); + unitIdx++; + + unit_colors[unitIdx] = Vec4f(color.x, color.y, color.z, alpha); + unit_vertices[unitIdx] = Vec2f(mx + (pos.x + 1)*zoom.x + size, my + mh - (pos.y*zoom.y)); + unitIdx++; + + unit_colors[unitIdx] = Vec4f(color.x, color.y, color.z, alpha); + unit_vertices[unitIdx] = Vec2f(mx + (pos.x + 1)*zoom.x + size, my + mh - ((pos.y + size)*zoom.y)); + unitIdx++; + + unit_colors[unitIdx] = Vec4f(color.x, color.y, color.z, alpha); + unit_vertices[unitIdx] = Vec2f(mx + pos.x*zoom.x, my + mh - ((pos.y + size)*zoom.y)); + unitIdx++; + } + } + + if (unitIdx > 0) { + glEnable(GL_BLEND); + + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + glColorPointer(4, GL_FLOAT, 0, &unit_colors[0]); + glVertexPointer(2, GL_FLOAT, 0, &unit_vertices[0]); + glDrawArrays(GL_QUADS, 0, unitIdx); + //glDrawArrays(GL_TRIANGLE_STRIP, 0, unitIdx); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + glDisable(GL_BLEND); + } + } + } + void Renderer::renderVisibleMarkedCells(bool renderTextHint, int x, int y) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + // Draw marked cells + std::map markedCells = game->getMapMarkedCellList(); + if (markedCells.empty() == false) { + const Texture2D *texture = game->getMarkCellTexture(); + const int yOffset = -40; + + for (std::map::iterator iterMap = markedCells.begin(); + iterMap != markedCells.end(); ++iterMap) { + MarkedCell &bm = iterMap->second; + if (bm.getPlayerIndex() < 0 || + (bm.getFaction() != NULL && + bm.getFaction()->getTeam() == game->getWorld()->getThisFaction()->getTeam())) { + const Map *map = game->getWorld()->getMap(); + std::pair bmVisible = posInCellQuadCache( + map->toSurfCoords(bm.getTargetPos())); + if (bmVisible.first == true) { + if (renderTextHint == true) { + if (bm.getNote() != "") { + bool validPosObjWorld = x > bmVisible.second.x && + y > bmVisible.second.y + yOffset && + x < bmVisible.second.x + texture->getTextureWidth() && + y < bmVisible.second.y + yOffset + texture->getTextureHeight(); + + if (validPosObjWorld) { + //printf("Checking for hint text render mouse [%d,%d] marker pos [%d,%d] validPosObjWorld = %d, hint [%s]\n",x,y,bm.getTargetPos().x,bm.getTargetPos().y,validPosObjWorld,bm.getNote().c_str()); + + //Lang &lang= Lang::getInstance(); + Vec4f fontColor = Vec4f(1.0f, 1.0f, 1.0f, 0.25f); + + if (renderText3DEnabled == true) { + renderTextShadow3D(bm.getNote(), CoreData::getInstance().getConsoleFont3D(), fontColor, + bmVisible.second.x, bmVisible.second.y); + } else { + renderTextShadow(bm.getNote(), CoreData::getInstance().getConsoleFont(), fontColor, + bmVisible.second.x, bmVisible.second.y); + } + } + } + } else { + + + /* + //texture 0 + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + + //set color to interpolation + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); + + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); + + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE1); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); + + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); + + //set alpha to 1 + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); + + //texture 1 + glActiveTexture(GL_TEXTURE1); + glMultiTexCoord2f(GL_TEXTURE1, 0.f, 0.f); + glEnable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, static_cast(bm.getFaction()->getTexture())->getHandle()); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); + + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); + + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); + + //set alpha to 1 + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); + + glActiveTexture(GL_TEXTURE0); + */ + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + Vec3f color(MarkedCell::static_system_marker_color); + if (bm.getFaction() != NULL) { + color = bm.getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0); + } + + renderTextureQuad( + bmVisible.second.x, bmVisible.second.y + yOffset, + texture->getTextureWidth(), texture->getTextureHeight(), texture, 0.8f, &color); + + /* + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glActiveTexture(GL_TEXTURE0); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + */ + } + } + } + } + } + } + + void Renderer::renderDisplay() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + CoreData &coreData = CoreData::getInstance(); + const Metrics &metrics = Metrics::getInstance(); + const Display *display = game->getGui()->getDisplay(); + + glPushAttrib(GL_ENABLE_BIT); + + if (renderText3DEnabled == true) { + //infoString + renderTextShadow3D( + display->getInfoText().c_str(), + coreData.getDisplayFont3D(), + display->getColor(), + metrics.getDisplayX(), + metrics.getDisplayY() + Display::infoStringY); + + //title + renderTextShadow3D( + display->getTitle().c_str(), + coreData.getDisplayFont3D(), + display->getColor(), + metrics.getDisplayX() + 40, + metrics.getDisplayY() + metrics.getDisplayH() - 20); + + glColor3f(0.0f, 0.0f, 0.0f); + + //text + renderTextShadow3D( + display->getText().c_str(), + coreData.getDisplayFont3D(), + display->getColor(), + metrics.getDisplayX() - 1, + metrics.getDisplayY() + metrics.getDisplayH() - 56); + + //progress Bar + if (display->getProgressBar() != -1) { + renderProgressBar3D( + display->getProgressBar(), + metrics.getDisplayX(), + metrics.getDisplayY() + metrics.getDisplayH() - 50, + coreData.getDisplayFontSmall3D(), 175); + } + } else { + //infoString + renderTextShadow( + display->getInfoText().c_str(), + coreData.getDisplayFont(), + display->getColor(), + metrics.getDisplayX(), + metrics.getDisplayY() + Display::infoStringY); + + //title + renderTextShadow( + display->getTitle().c_str(), + coreData.getDisplayFont(), + display->getColor(), + metrics.getDisplayX() + 40, + metrics.getDisplayY() + metrics.getDisplayH() - 20); + + glColor3f(0.0f, 0.0f, 0.0f); + + //text + renderTextShadow( + display->getText().c_str(), + coreData.getDisplayFont(), + display->getColor(), + metrics.getDisplayX() - 1, + metrics.getDisplayY() + metrics.getDisplayH() - 56); + + //progress Bar + if (display->getProgressBar() != -1) { + renderProgressBar( + display->getProgressBar(), + metrics.getDisplayX(), + metrics.getDisplayY() + metrics.getDisplayH() - 50, + coreData.getDisplayFontSmall()); + } + } + + //up images + glEnable(GL_TEXTURE_2D); + + glColor3f(1.f, 1.f, 1.f); + for (int i = 0; i < Display::upCellCount; ++i) { + if (display->getUpImage(i) != NULL) { + renderQuad( + metrics.getDisplayX() + display->computeUpX(i), + metrics.getDisplayY() + display->computeUpY(i), + display->getUpImageSize(), display->getUpImageSize(), display->getUpImage(i)); + } + } + + //down images + for (int i = 0; i < Display::downCellCount; ++i) { + if (display->getDownImage(i) != NULL) { + if (display->getDownLighted(i)) { + glColor3f(1.f, 1.f, 1.f); + } else { + glColor3f(0.3f, 0.3f, 0.3f); + } + + int x = metrics.getDisplayX() + display->computeDownX(i); + int y = metrics.getDisplayY() + display->computeDownY(i); + int size = Display::imageSize; + + if (display->getDownSelectedPos() == i) { + x -= 3; + y -= 3; + size += 6; + } + + renderQuad(x, y, size, size, display->getDownImage(i)); + } + } + + //selection + int downPos = display->getDownSelectedPos(); + if (downPos != Display::invalidPos) { + const Texture2D *texture = display->getDownImage(downPos); + if (texture != NULL) { + int x = metrics.getDisplayX() + display->computeDownX(downPos) - 3; + int y = metrics.getDisplayY() + display->computeDownY(downPos) - 3; + int size = Display::imageSize + 6; + renderQuad(x, y, size, size, display->getDownImage(downPos)); + } + } + + glPopAttrib(); + } + + void Renderer::renderMenuBackground(const MenuBackground *menuBackground) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + assertGl(); + + const Vec3f &cameraPosition = menuBackground->getCamera()->getConstPosition(); + + glPushAttrib(GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); + + //clear + Vec4f fogColor = Vec4f(0.4f, 0.4f, 0.4f, 1.f) * menuBackground->getFade(); + glClearColor(fogColor.x, fogColor.y, fogColor.z, 1.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glFogfv(GL_FOG_COLOR, fogColor.ptr()); + + //light + Vec4f lightPos = Vec4f(10.f, 10.f, 10.f, 1.f)* menuBackground->getFade(); + Vec4f diffLight = Vec4f(0.9f, 0.9f, 0.9f, 1.f)* menuBackground->getFade(); + Vec4f ambLight = Vec4f(0.3f, 0.3f, 0.3f, 1.f)* menuBackground->getFade(); + Vec4f specLight = Vec4f(0.1f, 0.1f, 0.1f, 1.f)* menuBackground->getFade(); + + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, lightPos.ptr()); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffLight.ptr()); + glLightfv(GL_LIGHT0, GL_AMBIENT, ambLight.ptr()); + glLightfv(GL_LIGHT0, GL_SPECULAR, specLight.ptr()); + + //main model + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.5f); + modelRenderer->begin(true, true, true, false); + menuBackground->getMainModelPtr()->updateInterpolationData(menuBackground->getAnim(), true); + modelRenderer->render(menuBackground->getMainModelPtr()); + modelRenderer->end(); + glDisable(GL_ALPHA_TEST); + + //characters + float dist = menuBackground->getAboutPosition().dist(cameraPosition); + float minDist = 3.f; + if (dist < minDist) { + + glAlphaFunc(GL_GREATER, 0.0f); + float alpha = clamp((minDist - dist) / minDist, 0.f, 1.f); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Vec4f(1.0f, 1.0f, 1.0f, alpha).ptr()); + + std::vector &characterMenuScreenPositionListCache = + CacheManager::getCachedItem< std::vector >(GameConstants::characterMenuScreenPositionListCacheLookupKey); + characterMenuScreenPositionListCache.clear(); + + modelRenderer->begin(true, true, false, false); + + for (int i = 0; i < MenuBackground::characterCount; ++i) { + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + Vec3f worldPos(i*2.f - 4.f, -1.4f, -7.5f); + glTranslatef(worldPos.x, worldPos.y, worldPos.z); + + // + // Get the screen coordinates for each character model - START + //std::vector projection(16); + //std::vector modelview(16); + //std::vector screen_coords(3); + + //glGetDoublev(GL_PROJECTION_MATRIX, projection.data()); + //glGetDoublev(GL_MODELVIEW_MATRIX, modelview.data()); + + const Metrics &metrics = Metrics::getInstance(); + GLint viewport[] = { 0, 0, metrics.getVirtualW(), metrics.getVirtualH() }; + + //get matrices + GLdouble projection[16]; + glGetDoublev(GL_PROJECTION_MATRIX, projection); + + GLdouble modelview[16]; + glGetDoublev(GL_MODELVIEW_MATRIX, modelview); + + //get the screen coordinates + GLdouble screen_coords[3]; + + gluProject(worldPos.x, worldPos.y, worldPos.z, + modelview, projection, viewport, + &screen_coords[0], &screen_coords[1], &screen_coords[2]); + characterMenuScreenPositionListCache.push_back(Vec3f(screen_coords[0], screen_coords[1], screen_coords[2])); + // Get the screen coordinates for each character model - END + // + + menuBackground->getCharacterModelPtr(i)->updateInterpolationData(menuBackground->getAnim(), true); + modelRenderer->render(menuBackground->getCharacterModelPtr(i)); + + glPopMatrix(); + } + modelRenderer->end(); + } + + //water + if (menuBackground->getWater()) { + + //water surface + const int waterTesselation = 10; + const int waterSize = 250; + const int waterQuadSize = 2 * waterSize / waterTesselation; + const float waterHeight = menuBackground->getWaterHeight(); + + glEnable(GL_BLEND); + + glNormal3f(0.f, 1.f, 0.f); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Vec4f(1.f, 1.f, 1.f, 1.f).ptr()); + GLuint waterHandle = static_cast(menuBackground->getWaterTexture())->getHandle(); + glBindTexture(GL_TEXTURE_2D, waterHandle); + for (int i = 1; i < waterTesselation; ++i) { + glBegin(GL_TRIANGLE_STRIP); + for (int j = 1; j < waterTesselation; ++j) { + glTexCoord2i(1, 2 % j); + glVertex3f(-waterSize + i * waterQuadSize, waterHeight, -waterSize + j * waterQuadSize); + glTexCoord2i(0, 2 % j); + glVertex3f(-waterSize + (i + 1)*waterQuadSize, waterHeight, -waterSize + j * waterQuadSize); + } + glEnd(); + } + glDisable(GL_BLEND); + + //raindrops + if (menuBackground->getRain()) { + const float maxRaindropAlpha = 0.5f; + + glEnable(GL_BLEND); + glDisable(GL_LIGHTING); + glDisable(GL_ALPHA_TEST); + glDepthMask(GL_FALSE); + + //splashes + CoreData &coreData = CoreData::getInstance(); + glBindTexture(GL_TEXTURE_2D, static_cast(coreData.getWaterSplashTexture())->getHandle()); + for (int i = 0; i < MenuBackground::raindropCount; ++i) { + + Vec2f pos = menuBackground->getRaindropPos(i); + float scale = menuBackground->getRaindropState(i); + float alpha = maxRaindropAlpha - scale * maxRaindropAlpha; + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + glColor4f(1.f, 1.f, 1.f, alpha); + glTranslatef(pos.x, waterHeight + 0.01f, pos.y); + + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2f(0.f, 1.f); + glVertex3f(-scale, 0, scale); + glTexCoord2f(0.f, 0.f); + glVertex3f(-scale, 0, -scale); + glTexCoord2f(1.f, 1.f); + glVertex3f(scale, 0, scale); + glTexCoord2f(1.f, 0.f); + glVertex3f(scale, 0, -scale); + glEnd(); + + glPopMatrix(); + } + } + } + + glPopAttrib(); + + assertGl(); + } + + void Renderer::renderMenuBackground(Camera *camera, float fade, Model *mainModel, vector characterModels, const Vec3f characterPosition, float anim) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + assertGl(); + + const Vec3f &cameraPosition = camera->getConstPosition(); + + glPushAttrib(GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); + + //clear + //Vec4f fogColor= Vec4f(0.4f, 0.4f, 0.4f, 1.f) * fade; + // Show black bacground + Vec4f fogColor = Vec4f(0.f, 0.f, 0.f, 1.f); + glClearColor(fogColor.x, fogColor.y, fogColor.z, 1.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glFogfv(GL_FOG_COLOR, fogColor.ptr()); + + //light + Vec4f lightPos = Vec4f(10.f, 10.f, 10.f, 1.f) * fade; + Vec4f diffLight = Vec4f(0.9f, 0.9f, 0.9f, 1.f) * fade; + Vec4f ambLight = Vec4f(0.3f, 0.3f, 0.3f, 1.f) * fade; + Vec4f specLight = Vec4f(0.1f, 0.1f, 0.1f, 1.f) * fade; + + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, lightPos.ptr()); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffLight.ptr()); + glLightfv(GL_LIGHT0, GL_AMBIENT, ambLight.ptr()); + glLightfv(GL_LIGHT0, GL_SPECULAR, specLight.ptr()); + + //main model + if (mainModel) { + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.5f); + modelRenderer->begin(true, true, true, false); + mainModel->updateInterpolationData(anim, true); + modelRenderer->render(mainModel); + modelRenderer->end(); + glDisable(GL_ALPHA_TEST); + } + + //characters + if (characterModels.empty() == false) { + float dist = characterPosition.dist(cameraPosition); + float minDist = 3.f; + if (dist < minDist) { + glAlphaFunc(GL_GREATER, 0.0f); + float alpha = clamp((minDist - dist) / minDist, 0.f, 1.f); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Vec4f(1.0f, 1.0f, 1.0f, alpha).ptr()); + modelRenderer->begin(true, true, false, false); + + for (unsigned int i = 0; i < characterModels.size(); ++i) { + if (characterModels[i]) { + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glTranslatef(i*2.f - 4.f, -1.4f, -7.5f); + characterModels[i]->updateInterpolationData(anim, true); + modelRenderer->render(characterModels[i]); + glPopMatrix(); + } + } + modelRenderer->end(); + } + } + + + glPopAttrib(); + + assertGl(); + } + + // ==================== computing ==================== + + bool Renderer::ccomputePosition(const Vec2i &screenPos, Vec2i &worldPos, bool exactCoords) { + assertGl(); + const Map* map = game->getWorld()->getMap(); + const Metrics &metrics = Metrics::getInstance(); + float depth = 0.0f; + GLdouble modelviewMatrix[16]; + GLdouble projectionMatrix[16]; + GLint viewport[4] = { 0, 0, metrics.getScreenW(), metrics.getScreenH() }; + GLdouble worldX; + GLdouble worldY; + GLdouble worldZ; + GLint screenX = (screenPos.x * metrics.getScreenW() / metrics.getVirtualW()); + GLint screenY = (screenPos.y * metrics.getScreenH() / metrics.getVirtualH()); + + //get the depth in the cursor pixel + glReadPixels(screenX, screenY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); + + //load matrices + loadProjectionMatrix(); + loadGameCameraMatrix(); + + //get matrices + glGetDoublev(GL_MODELVIEW_MATRIX, modelviewMatrix); + glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix); + + //get the world coordinates + gluUnProject( + screenX, screenY, depth, + modelviewMatrix, projectionMatrix, viewport, + &worldX, &worldY, &worldZ); + + //conver coords to int + if (exactCoords == true) { + worldPos = Vec2i(static_cast(worldX), static_cast(worldZ)); + } else { + worldPos = Vec2i(static_cast(worldX + 0.5f), static_cast(worldZ + 0.5f)); + } + + //clamp coords to map size + return map->isInside(worldPos); + } + + // This method takes world co-ordinates and translates them to screen co-ords + Vec3f Renderer::computeScreenPosition(const Vec3f &worldPos) { + if (worldToScreenPosCache.find(worldPos) != worldToScreenPosCache.end()) { + return worldToScreenPosCache[worldPos]; + } + assertGl(); + + const Metrics &metrics = Metrics::getInstance(); + GLint viewport[] = { 0, 0, metrics.getVirtualW(), metrics.getVirtualH() }; + GLdouble worldX = worldPos.x; + GLdouble worldY = worldPos.y; + GLdouble worldZ = worldPos.z; + + //load matrices + loadProjectionMatrix(); + loadGameCameraMatrix(); + + //get matrices + GLdouble modelviewMatrix[16]; + glGetDoublev(GL_MODELVIEW_MATRIX, modelviewMatrix); + GLdouble projectionMatrix[16]; + glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix); + + //get the screen coordinates + GLdouble screenX; + GLdouble screenY; + GLdouble screenZ; + gluProject(worldX, worldY, worldZ, + modelviewMatrix, projectionMatrix, viewport, + &screenX, &screenY, &screenZ); + + Vec3f screenPos(screenX, screenY, screenZ); + worldToScreenPosCache[worldPos] = screenPos; + + return screenPos; + } + + void Renderer::computeSelected(Selection::UnitContainer &units, const Object *&obj, + const bool withObjectSelection, + const Vec2i &posDown, const Vec2i &posUp) { + const string selectionType = toLower(Config::getInstance().getString("SelectionType", Config::colorPicking)); + + if (selectionType == Config::colorPicking) { + selectUsingColorPicking(units, obj, withObjectSelection, posDown, posUp); + } + /// Frustum approach --> Currently not accurate enough + else if (selectionType == Config::frustumPicking) { + selectUsingFrustumSelection(units, obj, withObjectSelection, posDown, posUp); + } else { + selectUsingSelectionBuffer(units, obj, withObjectSelection, posDown, posUp); + } + } + + void Renderer::selectUsingFrustumSelection(Selection::UnitContainer &units, + const Object *&obj, const bool withObjectSelection, + const Vec2i &posDown, const Vec2i &posUp) { + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + const Metrics &metrics = Metrics::getInstance(); + GLint view[] = { 0, 0, metrics.getVirtualW(), metrics.getVirtualH() }; + + //compute center and dimensions of selection rectangle + int x = (posDown.x + posUp.x) / 2; + int y = (posDown.y + posUp.y) / 2; + int w = abs(posDown.x - posUp.x); + int h = abs(posDown.y - posUp.y); + if (w < 2) { + w = 2; + } + if (h < 2) { + h = 2; + } + + gluPickMatrix(x, y, w, h, view); + gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, perspFarPlane); + loadGameCameraMatrix(); + + VisibleQuadContainerCache quadSelectionCacheItem; + ExtractFrustum(quadSelectionCacheItem); + + //pop matrices + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + VisibleQuadContainerCache &qCache = getQuadCache(); + if (qCache.visibleQuadUnitList.empty() == false) { + for (int visibleUnitIndex = 0; + visibleUnitIndex < (int) qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { + Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; + if (unit != NULL && unit->isAlive()) { + Vec3f unitPos = unit->getCurrMidHeightVector(); + bool insideQuad = CubeInFrustum(quadSelectionCacheItem.frustumData, + unitPos.x, unitPos.y, unitPos.z, unit->getType()->getRenderSize()); + if (insideQuad == true) { + units.push_back(unit); + } + } + } + } + + if (withObjectSelection == true) { + if (qCache.visibleObjectList.empty() == false) { + for (int visibleIndex = 0; + visibleIndex < (int) qCache.visibleObjectList.size(); ++visibleIndex) { + Object *object = qCache.visibleObjectList[visibleIndex]; + if (object != NULL) { + bool insideQuad = CubeInFrustum(quadSelectionCacheItem.frustumData, + object->getPos().x, object->getPos().y, object->getPos().z, 1); + if (insideQuad == true) { + obj = object; + //if(withObjectSelection == true) { + break; + //} + } + } + } + } + } + } + + void Renderer::selectUsingSelectionBuffer(Selection::UnitContainer &units, + const Object *&obj, const bool withObjectSelection, + const Vec2i &posDown, const Vec2i &posUp) { + //compute center and dimensions of selection rectangle + int x = (posDown.x + posUp.x) / 2; + int y = (posDown.y + posUp.y) / 2; + int w = abs(posDown.x - posUp.x); + int h = abs(posDown.y - posUp.y); + if (w < 2) { + w = 2; + } + if (h < 2) { + h = 2; + } + + //declarations + GLuint selectBuffer[Gui::maxSelBuff]; + + //setup matrices + glSelectBuffer(Gui::maxSelBuff, selectBuffer); + //glMatrixMode(GL_PROJECTION); + //glPushMatrix(); + + GLint renderModeResult = glRenderMode(GL_SELECT); + if (renderModeResult < 0) { + const char *errorString = reinterpret_cast(gluErrorString(renderModeResult)); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "OpenGL error #%d [0x%X] : [%s] at file: [%s], line: %d", renderModeResult, renderModeResult, errorString, extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__); + + printf("%s\n", szBuf); + } + + + glPushMatrix(); + glMatrixMode(GL_PROJECTION); + + glLoadIdentity(); + + const Metrics &metrics = Metrics::getInstance(); + GLint view[] = { 0, 0, metrics.getVirtualW(), metrics.getVirtualH() }; + //GLint view[4]; + //glGetIntegerv(GL_VIEWPORT, view); + + gluPickMatrix(x, y, w, h, view); + gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, perspFarPlane); + //gluPerspective(perspFov, metrics.getAspectRatio(), 0.0001, 1000.0); + //gluPerspective(perspFov, (float)view[2]/(float)view[3], perspNearPlane, perspFarPlane); + loadGameCameraMatrix(); + + //render units to find which ones should be selected + renderUnitsFast(); + if (withObjectSelection == true) { + renderObjectsFast(false, true); + } + + //pop matrices + glPopMatrix(); + + // Added this to ensure all the selection calls are done now + // (see http://www.unknownroad.com/rtfm/graphics/glselection.html section: [0x4]) + //glFlush(); + + //select units by checking the selected buffer + int selCount = glRenderMode(GL_RENDER); + if (selCount > 0) { + VisibleQuadContainerCache &qCache = getQuadCache(); + for (int i = 1; i <= selCount; ++i) { + int index = selectBuffer[i * 4 - 1]; + if (index >= OBJECT_SELECT_OFFSET) { + Object *object = qCache.visibleObjectList[index - OBJECT_SELECT_OFFSET]; + if (object != NULL) { + obj = object; + if (withObjectSelection == true) { + break; + } + } + } else { + Unit *unit = qCache.visibleQuadUnitList[index]; + if (unit != NULL && unit->isAlive()) { + units.push_back(unit); + } + } + } + } else if (selCount < 0) { + const char *errorString = reinterpret_cast(gluErrorString(selCount)); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "OpenGL error #%d [0x%X] : [%s] at file: [%s], line: %d", selCount, selCount, errorString, extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__); + + printf("%s\n", szBuf); + } + } + + void Renderer::selectUsingColorPicking(Selection::UnitContainer &units, + const Object *&obj, const bool withObjectSelection, + const Vec2i &posDown, const Vec2i &posUp) { + int x1 = posDown.x; + int y1 = posDown.y; + int x2 = posUp.x; + int y2 = posUp.y; + + int x = min(x1, x2); + int y = min(y1, y2); + int w = max(x1, x2) - min(x1, x2); + int h = max(y1, y2) - min(y1, y2); + if (w < 2) { + w = 2; + } + if (h < 2) { + h = 2; + } + + const Metrics &metrics = Metrics::getInstance(); + x = (x * metrics.getScreenW() / metrics.getVirtualW()); + y = (y * metrics.getScreenH() / metrics.getVirtualH()); + + w = (w * metrics.getScreenW() / metrics.getVirtualW()); + h = (h * metrics.getScreenH() / metrics.getVirtualH()); + + PixelBufferWrapper::begin(); + + + glPushMatrix(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + //GLint view[]= {0, 0, metrics.getVirtualW(), metrics.getVirtualH()}; + //gluPickMatrix(x, y, w, h, view); + gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, perspFarPlane); + loadGameCameraMatrix(); + + //render units to find which ones should be selected + //printf("In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + vector rendererUnits = renderUnitsFast(false, true); + //printf("In [%s::%s] Line: %d rendererUnits = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,rendererUnits.size()); + + + // Added this to ensure all the selection calls are done now + // (see http://www.unknownroad.com/rtfm/graphics/glselection.html section: [0x4]) + //glFlush(); + + //GraphicsInterface::getInstance().getCurrentContext()->swapBuffers(); + + PixelBufferWrapper::end(); + + vector unitsVector; + bool unitFound = false; + + if (rendererUnits.empty() == false) { + copy(rendererUnits.begin(), rendererUnits.end(), std::inserter(unitsVector, unitsVector.begin())); + } + + if (unitsVector.empty() == false) { + vector pickedList = BaseColorPickEntity::getPickedList(x, y, w, h, unitsVector); + //printf("In [%s::%s] Line: %d pickedList = %d models rendered = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,pickedList.size(),rendererModels.size()); + + if (pickedList.empty() == false) { + units.reserve(pickedList.size()); + for (unsigned int i = 0; i < pickedList.size(); ++i) { + int index = pickedList[i]; + //printf("In [%s::%s] Line: %d searching for selected object i = %d index = %d units = %d objects = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,index,rendererUnits.size(),rendererObjects.size()); + + if (rendererUnits.empty() == false && index < (int) rendererUnits.size()) { + Unit *unit = rendererUnits[index]; + if (unit != NULL && unit->isAlive()) { + unitFound = true; + units.push_back(unit); + } + } + } + } + } + + if (withObjectSelection == true && unitFound == false) { + vector rendererObjects; + vector objectsVector; + rendererObjects = renderObjectsFast(false, true, true); + if (rendererObjects.empty() == false) { + copy(rendererObjects.begin(), rendererObjects.end(), std::inserter(objectsVector, objectsVector.begin())); + } + + if (objectsVector.empty() == false) { + vector pickedList = BaseColorPickEntity::getPickedList(x, y, w, h, objectsVector); + //printf("In [%s::%s] Line: %d pickedList = %d models rendered = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,pickedList.size(),rendererModels.size()); + + if (pickedList.empty() == false) { + for (unsigned int i = 0; i < pickedList.size(); ++i) { + int index = pickedList[i]; + //printf("In [%s::%s] Line: %d searching for selected object i = %d index = %d units = %d objects = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,index,rendererUnits.size(),rendererObjects.size()); + + if (rendererObjects.empty() == false && index < (int) rendererObjects.size()) { + Object *object = rendererObjects[index]; + //printf("In [%s::%s] Line: %d searching for selected object i = %d index = %d [%p]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,index,object); + + if (object != NULL) { + obj = object; + break; + } + } + } + } + } + } + //pop matrices + glPopMatrix(); + } + + // ==================== shadows ==================== + + void Renderer::renderShadowsToTexture(const int renderFps) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (shadowsOffDueToMinRender == false && + (shadows == sProjected || shadows == sShadowMapping)) { + + shadowMapFrame = (shadowMapFrame + 1) % (shadowFrameSkip + 1); + + if (shadowMapFrame == 0) { + assertGl(); + + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT | GL_POLYGON_BIT); + + if (shadows == sShadowMapping) { + glClear(GL_DEPTH_BUFFER_BIT); + } else { + float color = 1.0f - shadowIntensity; + glColor3f(color, color, color); + glClearColor(1.f, 1.f, 1.f, 1.f); + glDisable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT); + } + + //assertGl(); + + //clear color buffer + // + //set viewport, we leave one texel always in white to avoid problems + glViewport(1, 1, shadowTextureSize - 2, shadowTextureSize - 2); + + //assertGl(); + + if (nearestLightPos.w == 0.f) { + //directional light + + //light pos + assert(game != NULL); + assert(game->getWorld() != NULL); + const TimeFlow *tf = game->getWorld()->getTimeFlow(); + assert(tf != NULL); + float ang = tf->isDay() ? computeSunAngle(tf->getTime()) : computeMoonAngle(tf->getTime()); + ang = radToDeg(ang); + + //push and set projection + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + //assertGl(); + + if (game->getGameCamera()->getState() == GameCamera::sGame) { + //glOrtho(-35, 5, -15, 15, -1000, 1000); + //glOrtho(-30, 30, -20, 20, -1000, 1000); + glOrtho(-30, 5, -20, 20, -1000, 1000); + } else { + glOrtho(-30, 30, -20, 20, -1000, 1000); + } + + //assertGl(); + + //push and set modelview + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glRotatef(15, 0, 1, 0); + + glRotatef(ang, 1, 0, 0); + glRotatef(90, 0, 1, 0); + const Vec3f &pos = game->getGameCamera()->getPos(); + + glTranslatef(static_cast(-pos.x), 0, static_cast(-pos.z)); + + //assertGl(); + } else { + //non directional light + + //push projection + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + //assertGl(); + + gluPerspective(perspFov, 1.f, perspNearPlane, perspFarPlane); + //const Metrics &metrics= Metrics::getInstance(); + //gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, perspFarPlane); + + + assertGl(); + + //push modelview + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glRotatef(-90, -1, 0, 0); + glTranslatef(-nearestLightPos.x, -nearestLightPos.y - 2, -nearestLightPos.z); + + //assertGl(); + } + + if (shadows == sShadowMapping) { + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(1.0f, 16.0f); + + //assertGl(); + } + + //render 3d + renderUnitsFast(true); + renderObjectsFast(true, false); + + //assertGl(); + + //read color buffer + glBindTexture(GL_TEXTURE_2D, shadowMapHandle); + assertGl(); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowTextureSize, shadowTextureSize); + GLenum error = glGetError(); + // This error can happen when a Linux user switches from an X session + // back to a running game, and 'seems' to be safe to ignore it + if (error != GL_INVALID_OPERATION) { + assertGlWithErrorNumber(error); + } + + //get elemental matrices + static Matrix4f matrix1; + static bool matrix1Populate = true; + if (matrix1Populate == true) { + matrix1Populate = false; + matrix1[0] = 0.5f; matrix1[4] = 0.f; matrix1[8] = 0.f; matrix1[12] = 0.5f; + matrix1[1] = 0.f; matrix1[5] = 0.5f; matrix1[9] = 0.f; matrix1[13] = 0.5f; + matrix1[2] = 0.f; matrix1[6] = 0.f; matrix1[10] = 0.5f; matrix1[14] = 0.5f; + matrix1[3] = 0.f; matrix1[7] = 0.f; matrix1[11] = 0.f; matrix1[15] = 1.f; + } + Matrix4f matrix2; + glGetFloatv(GL_PROJECTION_MATRIX, matrix2.ptr()); + + //assertGl(); + + Matrix4f matrix3; + glGetFloatv(GL_MODELVIEW_MATRIX, matrix3.ptr()); + + //pop both matrices + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + + //assertGl(); + + //compute texture matrix + glLoadMatrixf(matrix1.ptr()); + glMultMatrixf(matrix2.ptr()); + glMultMatrixf(matrix3.ptr()); + glGetFloatv(GL_TRANSPOSE_PROJECTION_MATRIX_ARB, shadowMapMatrix.ptr()); + + //assertGl(); + + //if(shadows == sShadowMapping) { + // glDisable(GL_POLYGON_OFFSET_FILL); + // glPolygonOffset(0.0f, 0.0f); + //} + + //pop + glPopMatrix(); + + //assertGl(); + + glPopAttrib(); + + assertGl(); + } + } + } + + + // ==================== gl wrap ==================== + + string Renderer::getGlInfo() { + string infoStr = ""; + Lang &lang = Lang::getInstance(); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + infoStr += lang.getString("OpenGlInfo") + ":\n"; + infoStr += " " + lang.getString("OpenGlVersion") + ": "; + infoStr += string((getGlVersion() != NULL ? getGlVersion() : "?")) + "\n"; + infoStr += " " + lang.getString("OpenGlRenderer") + ": "; + infoStr += string((getGlVersion() != NULL ? getGlVersion() : "?")) + "\n"; + infoStr += " " + lang.getString("OpenGlVendor") + ": "; + infoStr += string((getGlVendor() != NULL ? getGlVendor() : "?")) + "\n"; + infoStr += " " + lang.getString("OpenGlMaxLights") + ": "; + infoStr += intToStr(getGlMaxLights()) + "\n"; + infoStr += " " + lang.getString("OpenGlMaxTextureSize") + ": "; + infoStr += intToStr(getGlMaxTextureSize()) + "\n"; + infoStr += " " + lang.getString("OpenGlMaxTextureUnits") + ": "; + infoStr += intToStr(getGlMaxTextureUnits()) + "\n"; + infoStr += " " + lang.getString("OpenGlModelviewStack") + ": "; + infoStr += intToStr(getGlModelviewMatrixStackDepth()) + "\n"; + infoStr += " " + lang.getString("OpenGlProjectionStack") + ": "; + infoStr += intToStr(getGlProjectionMatrixStackDepth()) + "\n"; + } + return infoStr; + } + + string Renderer::getGlMoreInfo() { + string infoStr = ""; + Lang &lang = Lang::getInstance(); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + //gl extensions + infoStr += lang.getString("OpenGlExtensions") + ":\n "; + + string extensions = getGlExtensions(); + int charCount = 0; + for (int i = 0; i < (int) extensions.size(); ++i) { + infoStr += extensions[i]; + if (charCount > 120 && extensions[i] == ' ') { + infoStr += "\n "; + charCount = 0; + } + ++charCount; + } + + //platform extensions + infoStr += "\n\n"; + infoStr += lang.getString("OpenGlPlatformExtensions") + ":\n "; + + charCount = 0; + string platformExtensions = getGlPlatformExtensions(); + for (int i = 0; i < (int) platformExtensions.size(); ++i) { + infoStr += platformExtensions[i]; + if (charCount > 120 && platformExtensions[i] == ' ') { + infoStr += "\n "; + charCount = 0; + } + ++charCount; + } + } + + return infoStr; + } + + void Renderer::autoConfig() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + Config &config = Config::getInstance(); + + bool nvidiaCard = toLower(getGlVendor()).find("nvidia") != string::npos; + bool atiCard = toLower(getGlVendor()).find("ati") != string::npos; + //bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow") && isGlExtensionSupported("GL_ARB_shadow_ambient"); + bool shadowExtensions = isGlExtensionSupported("GL_ARB_shadow"); + + //3D textures + config.setBool("Textures3D", isGlExtensionSupported("GL_EXT_texture3D")); + + //shadows + string shadows = ""; + if (getGlMaxTextureUnits() >= 3) { + if (nvidiaCard && shadowExtensions) { + shadows = shadowsToStr(sShadowMapping); + } else { + shadows = shadowsToStr(sProjected); + } + } else { + shadows = shadowsToStr(sDisabled); + } + config.setString("Shadows", shadows); + + //lights + config.setInt("MaxLights", atiCard ? 1 : 4); + + //filter + config.setString("Filter", "Bilinear"); + } + } + + void Renderer::clearBuffers() { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + + void Renderer::clearZBuffer() { + glClear(GL_DEPTH_BUFFER_BIT); + } + + void Renderer::loadConfig() { + Config &config = Config::getInstance(); + + //cache most used config params + maxLights = config.getInt("MaxLights"); + photoMode = config.getBool("PhotoMode"); + focusArrows = config.getBool("FocusArrows"); + textures3D = config.getBool("Textures3D"); + float gammaValue = config.getFloat("GammaValue", "0.0"); + if (this->program == NULL) { + throw megaglest_runtime_error("this->program == NULL"); + } + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + //if(this->program != NULL) { + if (gammaValue != 0.0) { + this->program->getWindow()->setGamma(gammaValue); + } + //} + } + //load shadows + shadows = strToShadows(config.getString("Shadows")); + if (shadows == sProjected || shadows == sShadowMapping) { + shadowTextureSize = config.getInt("ShadowTextureSize"); + shadowFrameSkip = config.getInt("ShadowFrameSkip"); + shadowIntensity = config.getFloat("ShadowIntensity", "1.0"); + } + + //load filter settings + Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter")); + int maxAnisotropy = config.getInt("FilterMaxAnisotropy"); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + for (int i = 0; i < rsCount; ++i) { + textureManager[i]->setFilter(textureFilter); + textureManager[i]->setMaxAnisotropy(maxAnisotropy); + } + } + } + + //Texture2D *Renderer::saveScreenToTexture(int x, int y, int width, int height) { + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // + // Config &config= Config::getInstance(); + // Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter")); + // int maxAnisotropy = config.getInt("FilterMaxAnisotropy"); + // + // Texture2D *texture = GraphicsInterface::getInstance().getFactory()->newTexture2D(); + // texture->setForceCompressionDisabled(true); + // texture->setMipmap(false); + // Pixmap2D *pixmapScreenShot = texture->getPixmap(); + // pixmapScreenShot->init(width, height, 3); + // texture->init(textureFilter,maxAnisotropy); + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // //glFinish(); + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // glReadPixels(x, y, pixmapScreenShot->getW(), pixmapScreenShot->getH(), + // GL_RGB, GL_UNSIGNED_BYTE, pixmapScreenShot->getPixels()); + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // + // return texture; + //} + + void Renderer::saveScreen(const string &path, int w, int h) { + const Metrics &sm = Metrics::getInstance(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + Pixmap2D *pixmapScreenShot = new Pixmap2D(sm.getScreenW(), sm.getScreenH(), 3); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + //glFinish(); + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + glReadPixels(0, 0, pixmapScreenShot->getW(), pixmapScreenShot->getH(), + GL_RGB, GL_UNSIGNED_BYTE, pixmapScreenShot->getPixels()); + + if (w == 0 || h == 0) { + h = sm.getScreenH(); + w = sm.getScreenW(); + } else { + pixmapScreenShot->Scale(GL_RGB, w, h); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + // Signal the threads queue to add a screenshot save request + MutexSafeWrapper safeMutex(saveScreenShotThreadAccessor, string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__)); + saveScreenQueue.push_back(make_pair(path, pixmapScreenShot)); + safeMutex.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + unsigned int Renderer::getSaveScreenQueueSize() { + MutexSafeWrapper safeMutex(saveScreenShotThreadAccessor, string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__)); + int queueSize = (int) saveScreenQueue.size(); + safeMutex.ReleaseLock(); + + return queueSize; + } + + // ==================== PRIVATE ==================== + + float Renderer::computeSunAngle(float time) { + + float dayTime = TimeFlow::dusk - TimeFlow::dawn; + float fTime = (time - TimeFlow::dawn) / dayTime; + return clamp(fTime*pi, pi / 8.f, 7.f*pi / 8.f); + } + + float Renderer::computeMoonAngle(float time) { + float nightTime = 24 - (TimeFlow::dusk - TimeFlow::dawn); + + if (time < TimeFlow::dawn) { + time += 24.f; + } + + float fTime = (time - TimeFlow::dusk) / nightTime; + return clamp((1.0f - fTime)*pi, pi / 8.f, 7.f*pi / 8.f); + } + + Vec4f Renderer::computeSunPos(float time) { + float ang = computeSunAngle(time); + return Vec4f(-std::cos(ang)*sunDist, std::sin(ang)*sunDist, 0.f, 0.f); + } + + Vec4f Renderer::computeMoonPos(float time) { + float ang = computeMoonAngle(time); + return Vec4f(-std::cos(ang)*moonDist, std::sin(ang)*moonDist, 0.f, 0.f); + } + + // ==================== fast render ==================== + + //render units for selection purposes + vector Renderer::renderUnitsFast(bool renderingShadows, bool colorPickingSelection) { + vector unitsList; + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return unitsList; + } + + assert(game != NULL); + //const World *world= game->getWorld(); + //assert(world != NULL); + + VisibleQuadContainerCache &qCache = getQuadCache(); + if (qCache.visibleQuadUnitList.empty() == false) { + if (colorPickingSelection == true) { + unitsList.reserve(qCache.visibleQuadUnitList.size()); + } + + bool modelRenderStarted = false; + bool renderOnlyBuildings = true; + for (int k = 0; k < 2; k++) { + if (k == 0) { + //glDisable(GL_DEPTH_TEST); + renderOnlyBuildings = true; + } else { + if (colorPickingSelection == true) { + // clear depth buffer to get units behind buildings rendered in front of them + glClear(GL_DEPTH_BUFFER_BIT); + } + //glEnable(GL_DEPTH_TEST); + renderOnlyBuildings = false; + } + for (int visibleUnitIndex = 0; + visibleUnitIndex < (int) qCache.visibleQuadUnitList.size(); ++visibleUnitIndex) { + Unit *unit = qCache.visibleQuadUnitList[visibleUnitIndex]; + + if (renderingShadows == false && unit->isAlive() == false) { + // no need to render dead units for selection + continue; + } + + if (renderOnlyBuildings == true && unit->getType()->hasSkillClass(scMove)) { + continue; + } + + if (renderOnlyBuildings == false && !unit->getType()->hasSkillClass(scMove)) { + continue; + } + + if (modelRenderStarted == false) { + modelRenderStarted = true; + + if (colorPickingSelection == false) { + //glPushAttrib(GL_ENABLE_BIT| GL_TEXTURE_BIT); + glDisable(GL_LIGHTING); + if (renderingShadows == false) { + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_TEXTURE_2D); + } else { + glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT); + glEnable(GL_TEXTURE_2D); + glAlphaFunc(GL_GREATER, 0.4f); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + + //set color to the texture alpha + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); + + //set alpha to the texture alpha + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); + } + } + + modelRenderer->begin(false, renderingShadows, false, colorPickingSelection); + + if (colorPickingSelection == false) { + glInitNames(); + } + } + + if (colorPickingSelection == false) { + glPushName(visibleUnitIndex); + } + + //assertGl(); + + glMatrixMode(GL_MODELVIEW); + //debuxar modelo + glPushMatrix(); + + //translate + Vec3f currVec = unit->getCurrVectorFlat(); + glTranslatef(currVec.x, currVec.y, currVec.z); + + //rotate + glRotatef(unit->getRotation(), 0.f, 1.f, 0.f); + + //render + Model *model = unit->getCurrentModelPtr(); + //if(this->gameCamera->getPos().dist(unit->getCurrVector()) <= SKIP_INTERPOLATION_DISTANCE) { + + // ***MV don't think this is needed below 2013/01/11 + model->updateInterpolationVertices(unit->getAnimProgressAsFloat(), unit->isAlive() && !unit->isAnimProgressBound()); + + //} + + if (colorPickingSelection == true) { + unit->setUniquePickingColor(); + unitsList.push_back(unit); + } + + modelRenderer->render(model, rmSelection); + + glPopMatrix(); + + if (colorPickingSelection == false) { + glPopName(); + } + } + } + + if (modelRenderStarted == true) { + modelRenderer->end(); + if (colorPickingSelection == false) { + glPopAttrib(); + } + } + } + //glDisable(GL_DEPTH_TEST); + return unitsList; + } + + //render objects for selection purposes + vector Renderer::renderObjectsFast(bool renderingShadows, bool resourceOnly, + bool colorPickingSelection) { + vector objectList; + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return objectList; + } + + VisibleQuadContainerCache &qCache = getQuadCache(); + if (qCache.visibleObjectList.empty() == false) { + if (colorPickingSelection == true) { + objectList.reserve(qCache.visibleObjectList.size()); + } + + bool modelRenderStarted = false; + for (int visibleIndex = 0; + visibleIndex < (int) qCache.visibleObjectList.size(); ++visibleIndex) { + Object *o = qCache.visibleObjectList[visibleIndex]; + + if (modelRenderStarted == false) { + modelRenderStarted = true; + + if (colorPickingSelection == false) { + glDisable(GL_LIGHTING); + + if (renderingShadows == false) { + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_TEXTURE_2D); + } else { + glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT); + glAlphaFunc(GL_GREATER, 0.5f); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + + //set color to the texture alpha + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); + + //set alpha to the texture alpha + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); + } + } + + modelRenderer->begin(false, renderingShadows, false, colorPickingSelection); + + if (colorPickingSelection == false) { + glInitNames(); + } + } + + if (resourceOnly == false || o->getResource() != NULL) { + Model *objModel = o->getModelPtr(); + //if(this->gameCamera->getPos().dist(o->getPos()) <= SKIP_INTERPOLATION_DISTANCE) { + + // ***MV don't think this is needed below 2013/01/11 + //objModel->updateInterpolationData(o->getAnimProgress(), true); + + //} + const Vec3f v = o->getConstPos(); + + if (colorPickingSelection == false) { + glPushName(OBJECT_SELECT_OFFSET + visibleIndex); + } + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glTranslatef(v.x, v.y, v.z); + glRotatef(o->getRotation(), 0.f, 1.f, 0.f); + + if (colorPickingSelection == true) { + o->setUniquePickingColor(); + objectList.push_back(o); + } + + modelRenderer->render(objModel, resourceOnly ? rmSelection : rmNormal); + + glPopMatrix(); + + if (colorPickingSelection == false) { + glPopName(); + } + } + } + + if (modelRenderStarted == true) { + modelRenderer->end(); + + if (colorPickingSelection == false) { + glPopAttrib(); + } + } + } + + return objectList; + } + + // ==================== gl caps ==================== + + void Renderer::checkGlCaps() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (glActiveTexture == NULL) { + string message; + + message += "Your system supports OpenGL version ["; + message += getGlVersion() + string("]\n"); + message += "ZetaGlest needs a version that supports\n"; + message += "glActiveTexture (OpenGL 1.3) or the ARB_multitexture extension."; + + throw megaglest_runtime_error(message.c_str(), true); + } + + //opengl 2.1 + if (glewIsSupported("GL_VERSION_2_1") == false) { + string message; + + message += "Your system supports OpenGL version ["; + message += getGlVersion() + string("]\n"); + message += "ZetaGlest needs at least version 2.1 to work\n"; + message += "You may solve this problem by installing your latest video card drivers"; + + throw megaglest_runtime_error(message.c_str(), true); + } + + //opengl 1.4 or extension + //if(!isGlVersionSupported(1, 4, 0)){ + if (glewIsSupported("GL_VERSION_1_4") == false) { + checkExtension("GL_ARB_texture_env_crossbar", "ZetaGlest"); + } + } + + void Renderer::checkGlOptionalCaps() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + //shadows + if (shadows == sProjected || shadows == sShadowMapping) { + if (getGlMaxTextureUnits() < 3) { + throw megaglest_runtime_error("Your system doesn't support 3 texture units, required for shadows"); + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + //shadow mapping + if (shadows == sShadowMapping) { + checkExtension("GL_ARB_shadow", "Shadow Mapping"); + //checkExtension("GL_ARB_shadow_ambient", "Shadow Mapping"); + //checkExtension("GL_ARB_depth_texture", "Shadow Mapping"); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void Renderer::checkExtension(const string &extension, const string &msg) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (!isGlExtensionSupported(extension.c_str())) { + string str = "OpenGL extension not supported: " + extension + ", required for " + msg; + throw megaglest_runtime_error(str); + } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + // ==================== init 3d lists ==================== + + void Renderer::init3dList() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + render3dSetup(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + //const Metrics &metrics= Metrics::getInstance(); + + //assertGl(); + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //list3d= glGenLists(1); + //assertGl(); + //list3dValid=true; + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //glNewList(list3d, GL_COMPILE_AND_EXECUTE); + //need to execute, because if not gluPerspective takes no effect and gluLoadMatrix is wrong + //render3dSetup(); + //glEndList(); + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //assert + //assertGl(); + } + + void Renderer::render3dSetup() { + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + const Metrics &metrics = Metrics::getInstance(); + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //misc + glViewport(0, 0, metrics.getScreenW(), metrics.getScreenH()); + glClearColor(fowColor.x, fowColor.y, fowColor.z, fowColor.w); + glFrontFace(GL_CW); + glEnable(GL_CULL_FACE); + loadProjectionMatrix(); + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //texture state + glActiveTexture(shadowTexUnit); + glDisable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glActiveTexture(fowTexUnit); + glDisable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glActiveTexture(baseTexUnit); + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //material state + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, defSpecularColor.ptr()); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, defAmbientColor.ptr()); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, defDiffuseColor.ptr()); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glColor4fv(defColor.ptr()); + + //blend state + glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //alpha test state + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.f); + + //depth test state + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + glDepthFunc(GL_LESS); + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //lighting state + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + //matrix mode + glMatrixMode(GL_MODELVIEW); + + //stencil test + glDisable(GL_STENCIL_TEST); + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //fog + const Tileset *tileset = NULL; + if (game != NULL && game->getWorld() != NULL) { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + tileset = game->getWorld()->getTileset(); + } + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + if (tileset != NULL && tileset->getFog()) { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + glEnable(GL_FOG); + if (tileset->getFogMode() == fmExp) { + glFogi(GL_FOG_MODE, GL_EXP); + } else { + glFogi(GL_FOG_MODE, GL_EXP2); + } + + glFogf(GL_FOG_DENSITY, tileset->getFogDensity()); + glFogfv(GL_FOG_COLOR, tileset->getFogColor().ptr()); + } + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + } + + void Renderer::init2dList() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + // //this list sets the state for the 2d rendering + // list2d= glGenLists(1); + // assertGl(); + // list2dValid=true; + // + // glNewList(list2d, GL_COMPILE); + // render2dMenuSetup(); + // glEndList(); + // + // assertGl(); + } + + void Renderer::render2dMenuSetup() { + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + const Metrics &metrics = Metrics::getInstance(); + //projection + glViewport(0, 0, metrics.getScreenW(), metrics.getScreenH()); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, metrics.getVirtualW(), 0, metrics.getVirtualH(), 0, 1); + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //modelview + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //disable everything + glDisable(GL_BLEND); + glDisable(GL_LIGHTING); + glDisable(GL_ALPHA_TEST); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glDisable(GL_FOG); + glDisable(GL_CULL_FACE); + glFrontFace(GL_CCW); + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + if (glActiveTexture != NULL) { + glActiveTexture(baseTexUnit); + } else { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s] Line: %d\nglActiveTexture == NULL\nglActiveTexture is only supported if the GL version is 1.3 or greater,\nor if the ARB_multitexture extension is supported!", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glDisable(GL_TEXTURE_2D); + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //blend func + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + //color + glColor4f(1.f, 1.f, 1.f, 1.f); + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + } + + //void Renderer::init3dListMenu(const MainMenu *mm) { + // if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + // return; + // } + // + // //this->mm3d = mm; + // //printf("In [%s::%s Line: %d] this->custom_mm3d [%p] this->mm3d [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->custom_mm3d,this->mm3d); + // + ///* + // assertGl(); + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // + // const Metrics &metrics= Metrics::getInstance(); + // //const MenuBackground *mb= mm->getConstMenuBackground(); + // const MenuBackground *mb = NULL; + // if(mm != NULL) { + // mb = mm->getConstMenuBackground(); + // } + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // + // if(this->customlist3dMenu != NULL) { + // *this->customlist3dMenu = glGenLists(1); + // assertGl(); + // } + // else { + // list3dMenu= glGenLists(1); + // assertGl(); + // list3dMenuValid=true; + // } + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // + // if(this->customlist3dMenu != NULL) { + // glNewList(*this->customlist3dMenu, GL_COMPILE); + // } + // else { + // glNewList(list3dMenu, GL_COMPILE); + // } + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // //misc + // glViewport(0, 0, metrics.getScreenW(), metrics.getScreenH()); + // glClearColor(0.4f, 0.4f, 0.4f, 1.f); + // glFrontFace(GL_CW); + // glEnable(GL_CULL_FACE); + // glMatrixMode(GL_PROJECTION); + // glLoadIdentity(); + // gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, 1000000); + // + // //texture state + // glEnable(GL_TEXTURE_2D); + // glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + // + // //material state + // glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, defSpecularColor.ptr()); + // glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, defAmbientColor.ptr()); + // glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, defDiffuseColor.ptr()); + // glColor4fv(defColor.ptr()); + // glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + // + // //blend state + // glDisable(GL_BLEND); + // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // + // //alpha test state + // glEnable(GL_ALPHA_TEST); + // glAlphaFunc(GL_GREATER, 0.f); + // + // //depth test state + // glEnable(GL_DEPTH_TEST); + // glDepthMask(GL_TRUE); + // glDepthFunc(GL_LESS); + // + // //lighting state + // glEnable(GL_LIGHTING); + // + // //matrix mode + // glMatrixMode(GL_MODELVIEW); + // + // //stencil test + // glDisable(GL_STENCIL_TEST); + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // + // //fog + // if(mb != NULL && mb->getFog()){ + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // + // glEnable(GL_FOG); + // glFogi(GL_FOG_MODE, GL_EXP2); + // glFogf(GL_FOG_DENSITY, mb->getFogDensity()); + // } + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // + // glEndList(); + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // + // //assert + // assertGl(); + //*/ + //} + + void Renderer::render3dMenuSetup(const MainMenu *mm) { + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + const Metrics &metrics = Metrics::getInstance(); + const MenuBackground *mb = NULL; + if (mm != NULL) { + mb = mm->getConstMenuBackground(); + } + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + //misc + glViewport(0, 0, metrics.getScreenW(), metrics.getScreenH()); + glClearColor(0.4f, 0.4f, 0.4f, 1.f); + glFrontFace(GL_CW); + glEnable(GL_CULL_FACE); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, 1000000); + + //texture state + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + //material state + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, defSpecularColor.ptr()); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, defAmbientColor.ptr()); + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, defDiffuseColor.ptr()); + glColor4fv(defColor.ptr()); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + + //blend state + glDisable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + //alpha test state + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.f); + + //depth test state + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + glDepthFunc(GL_LESS); + + //lighting state + glEnable(GL_LIGHTING); + + //matrix mode + glMatrixMode(GL_MODELVIEW); + + //stencil test + glDisable(GL_STENCIL_TEST); + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //fog + if (mb != NULL && mb->getFog()) { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + glEnable(GL_FOG); + glFogi(GL_FOG_MODE, GL_EXP2); + glFogf(GL_FOG_DENSITY, mb->getFogDensity()); + } + + //assert + assertGl(); + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + } + // ==================== misc ==================== + + void Renderer::loadProjectionMatrix() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + GLdouble clipping; + const Metrics &metrics = Metrics::getInstance(); + + assertGl(); + + clipping = photoMode ? perspFarPlane * 100 : perspFarPlane; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(perspFov, metrics.getAspectRatio(), perspNearPlane, clipping); + + assertGl(); + } + + void Renderer::enableProjectiveTexturing() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + glTexGenfv(GL_S, GL_EYE_PLANE, &shadowMapMatrix[0]); + glTexGenfv(GL_T, GL_EYE_PLANE, &shadowMapMatrix[4]); + glTexGenfv(GL_R, GL_EYE_PLANE, &shadowMapMatrix[8]); + glTexGenfv(GL_Q, GL_EYE_PLANE, &shadowMapMatrix[12]); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + glEnable(GL_TEXTURE_GEN_Q); + } + + // ==================== private aux drawing ==================== + void Renderer::renderHealthBar(Vec3f v, Unit *unit, float height, bool lineBorder, const Texture2D *texture, const Texture2D *backgroundTexture) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + int numberOfBars = 1; + int barCount = 0; + float hp = unit->getHpRatio(); + float ep = -1.f; + if (unit->getType()->getTotalMaxEp(unit->getTotalUpgrade()) != 0) { + ep = unit->getEpRatio(); + numberOfBars++; + } + int productionPercent = unit->getProductionPercent(); + if (productionPercent != -1) { + numberOfBars++; + } + int size = unit->getType()->getSize(); + + + Vec3f rightVector; + Vec3f upVector; + Vec3f rightVectorTexture; + Vec3f upVectorTexture; + v.y += 1; + float modelview[16]; + float width = (float) size / 6 + 0.25f; + float red; + float green; + float brightness = 0.8f; + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + // get the current modelview state + glGetFloatv(GL_MODELVIEW_MATRIX, modelview); + rightVector = Vec3f(modelview[0], modelview[4], modelview[8]); + upVector = Vec3f(modelview[1], modelview[5], modelview[9]); + rightVectorTexture = rightVector * 2; + upVectorTexture = upVector * 4; + + //from green to yellow to red + + if (hp >= 0.75f) { + green = 1; + red = 1 - ((2 * hp - 1) - 0.5f); + } else { + red = 1; + green = 0.5f + (2 * hp - 1); + } + + if (red > 1.0f) red = 1.0f; + if (green > 1.0f) green = 1.0f; + float yOffset = (float) numberOfBars / 2.f; + + if (backgroundTexture != NULL) { + //backgroundTexture + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, static_cast(backgroundTexture)->getHandle()); + glColor4f(1.f, 1.f, 1.f, 1.f); + //glColor4f(red+0.1f,green+0.1f,0.1f,0.5f); + glBegin(GL_QUADS); + glTexCoord2i(0, 1); + glVertex3fv((v - (rightVectorTexture*width - upVectorTexture * height*yOffset)).ptr()); + glTexCoord2i(0, 0); + glVertex3fv((v - (rightVectorTexture*width + upVectorTexture * height*yOffset)).ptr()); + glTexCoord2i(1, 0); + glVertex3fv((v + (rightVectorTexture*width - upVectorTexture * height*yOffset)).ptr()); + glTexCoord2i(1, 1); + glVertex3fv((v + (rightVectorTexture*width + upVectorTexture * height*yOffset)).ptr()); + glEnd(); + glDisable(GL_TEXTURE_2D); + } + + //healthbar + glColor4f(red*brightness, green*brightness, 0.0f, 0.4f); + //hpbar + barCount++; + internalRenderHp(numberOfBars, barCount, hp, v, width, height, rightVector, upVector); + + + if (ep > -1.0f) { + //epbar + barCount++; + //glColor4f(brightness,0,brightness,0.5f); + glColor4f(.15f*brightness, 0.3f*brightness, 0.8f*brightness, 0.7f); + internalRenderHp(numberOfBars, barCount, ep, v, width, height, rightVector, upVector); + } + if (productionPercent != -1) { + barCount++; + glColor4f(brightness, 0, brightness, 0.6f); + //glColor4f(0.0f*brightness,0.4f*brightness,0.2f*brightness,0.8f); + internalRenderHp(numberOfBars, barCount, (float) productionPercent / 100, v, width, height, rightVector, upVector); + } + + + // glBegin(GL_QUADS); + // if(ep < -2.0f) { + // //hpbar + // glVertex3fv((v - (rightVector*width - upVector*height)).ptr()); + // glVertex3fv((v - (rightVector*width + upVector*height)).ptr()); + // glVertex3fv((v + (rightVector*hp*width - upVector*height)).ptr()); + // glVertex3fv((v + (rightVector*hp*width + upVector*height)).ptr()); + // + // } else { + // //hpbar + // glVertex3fv((v - (rightVector*width - upVector*height)).ptr()); + // glVertex3fv((v - (rightVector*width + upVector*height*0.0f)).ptr()); + // glVertex3fv((v + (rightVector*hp*width - upVector*height*0.0f)).ptr()); + // glVertex3fv((v + (rightVector*hp*width + upVector*height)).ptr()); + // //epbar + // glColor4f(brightness,0,brightness,0.4f); + // glVertex3fv((v - (rightVector*width + upVector*height*0.0f)).ptr()); + // glVertex3fv((v - (rightVector*width + upVector*height)).ptr()); + // glVertex3fv((v + (rightVector*ep*width - upVector*height)).ptr()); + // glVertex3fv((v + (rightVector*ep*width - upVector*height*0.0f)).ptr()); + // } + // glEnd(); + + if (lineBorder) { + //border + glColor4f(red*brightness, green*brightness, 0.1f*brightness, 0.5f); + glBegin(GL_LINE_LOOP); + glVertex3fv((v - (rightVector*width - upVector * height*yOffset)).ptr()); + glVertex3fv((v - (rightVector*width + upVector * height*yOffset)).ptr()); + glVertex3fv((v + (rightVector*width - upVector * height*yOffset)).ptr()); + glVertex3fv((v + (rightVector*width + upVector * height*yOffset)).ptr()); + glEnd(); + } + + if (texture != NULL) { + //BorderTexture + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getHandle()); + glColor4f(1.f, 1.f, 1.f, 1.f); + //glColor4f(red+0.1f,green+0.1f,0.1f,0.5f); + glBegin(GL_QUADS); + glTexCoord2i(0, 1); + glVertex3fv((v - (rightVectorTexture*width - upVectorTexture * height*yOffset)).ptr()); + glTexCoord2i(0, 0); + glVertex3fv((v - (rightVectorTexture*width + upVectorTexture * height*yOffset)).ptr()); + glTexCoord2i(1, 0); + glVertex3fv((v + (rightVectorTexture*width - upVectorTexture * height*yOffset)).ptr()); + glTexCoord2i(1, 1); + glVertex3fv((v + (rightVectorTexture*width + upVectorTexture * height*yOffset)).ptr()); + glEnd(); + glDisable(GL_TEXTURE_2D); + } + + glPopMatrix(); + } + + void Renderer::internalRenderHp(int numberOfBars, int barNumber, float hp, + Vec3f posVector, float width, float singleHPheight, Vec3f rightVector, Vec3f upVector) { + + float yOffset = (float) numberOfBars*singleHPheight / 2; + float offsetTop = yOffset - singleHPheight * (barNumber - 1); + float offsetBottom = yOffset - singleHPheight * barNumber; + offsetBottom = offsetBottom * -1; + hp = hp * 2 - 1; + + glBegin(GL_QUADS); + glVertex3fv((posVector - (rightVector*width - upVector * offsetTop)).ptr()); + glVertex3fv((posVector - (rightVector*width + upVector * offsetBottom)).ptr()); + glVertex3fv((posVector + (rightVector*hp*width - upVector * offsetBottom)).ptr()); + glVertex3fv((posVector + (rightVector*hp*width + upVector * offsetTop)).ptr()); + glEnd(); + } + + void Renderer::renderSelectionCircle(Vec3f v, int size, float radius, float thickness) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + GLUquadricObj *disc; + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + glTranslatef(v.x, v.y, v.z); + glRotatef(90.f, 1.f, 0.f, 0.f); + disc = gluNewQuadric(); + gluQuadricDrawStyle(disc, GLU_FILL); + gluCylinder(disc, radius*(size - thickness), radius*size, thickness, 30, 1); + gluDeleteQuadric(disc); + + glPopMatrix(); + // glBegin (GL_QUAD_STRIP); + // for (float k = 0; k <= 180; k=k+1) { + // float j=degToRad(k); + // glVertex3f(v.x+std::cos(j)*.9*radius*size, v.y+thickness, v.z+std::sin(j)*.9*radius*size); + // glVertex3f(v.x+std::cos(j)*radius*size, v.y, v.z+std::sin(j)*radius*size); + // } + // glEnd(); + } + + void Renderer::renderArrow(const Vec3f &pos1, const Vec3f &pos2, + const Vec3f &color, float width) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + Config &config = Config::getInstance(); + if (config.getBool("RecordMode", "false") == true) { + return; + } + + const int tesselation = 3; + const float arrowEndSize = 0.4f; + const float maxlen = 25; + const float blendDelay = 5.f; + + Vec3f dir = Vec3f(pos2 - pos1); + float len = dir.length(); + + if (len > maxlen) { + return; + } + float alphaFactor = clamp((maxlen - len) / blendDelay, 0.f, 1.f); + + dir.normalize(); + Vec3f normal = dir.cross(Vec3f(0, 1, 0)); + + Vec3f pos2Left = pos2 + normal * (width - 0.05f) - dir * arrowEndSize*width; + Vec3f pos2Right = pos2 - normal * (width - 0.05f) - dir * arrowEndSize*width; + Vec3f pos1Left = pos1 + normal * (width + 0.05f); + Vec3f pos1Right = pos1 - normal * (width + 0.05f); + + //arrow body + glBegin(GL_TRIANGLE_STRIP); + for (int i = 0; i <= tesselation; ++i) { + float t = static_cast(i) / tesselation; + Vec3f a = pos1Left.lerp(t, pos2Left); + Vec3f b = pos1Right.lerp(t, pos2Right); + Vec4f c = Vec4f(color, t*0.25f*alphaFactor); + + glColor4fv(c.ptr()); + + glVertex3fv(a.ptr()); + glVertex3fv(b.ptr()); + + } + + glEnd(); + //arrow end + glBegin(GL_TRIANGLES); + glVertex3fv((pos2Left + normal * (arrowEndSize - 0.1f)).ptr()); + glVertex3fv((pos2Right - normal * (arrowEndSize - 0.1f)).ptr()); + glVertex3fv((pos2 + dir * (arrowEndSize - 0.1f)).ptr()); + glEnd(); + } + + void Renderer::renderProgressBar3D(int size, int x, int y, Font3D *font, int customWidth, + string prefixLabel, bool centeredText, int customHeight) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + // Makiong this smaller than 14 is a bad idea (since the font size is never smaller than that) + int progressbarHeight = (customHeight > 0 ? customHeight : 14); + int currentSize = size; + int maxSize = maxProgressBar; + string renderText = intToStr(static_cast(size)) + "%"; + if (customWidth > 0) { + if (size > 0) { + currentSize = (int) ((double) customWidth * ((double) size / 100.0)); + } + maxSize = customWidth; + //if(maxSize <= 0) { + // maxSize = maxProgressBar; + //} + } + if (prefixLabel != "") { + renderText = prefixLabel + renderText; + } + + //bar + glBegin(GL_QUADS); + glColor4fv(progressBarFront2.ptr()); + glVertex2i(x, y); + glVertex2i(x, y + progressbarHeight); + glColor4fv(progressBarFront1.ptr()); + glVertex2i(x + currentSize, y + progressbarHeight); + glVertex2i(x + currentSize, y); + glEnd(); + + //transp bar + glEnable(GL_BLEND); + glBegin(GL_QUADS); + glColor4fv(progressBarBack2.ptr()); + glVertex2i(x + currentSize, y); + glVertex2i(x + currentSize, y + progressbarHeight); + glColor4fv(progressBarBack1.ptr()); + glVertex2i(x + maxSize, y + progressbarHeight); + glVertex2i(x + maxSize, y); + glEnd(); + glDisable(GL_BLEND); + + //text + //glColor3fv(defColor.ptr()); + //printf("Render progress bar3d renderText [%s] y = %d, centeredText = %d\n",renderText.c_str(),y, centeredText); + + renderTextBoundingBox3D(renderText, font, defColor, x, y, maxSize, + progressbarHeight, true, true, false, -1, -1); + } + + void Renderer::renderProgressBar(int size, int x, int y, Font2D *font, int customWidth, + string prefixLabel, bool centeredText) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + int currentSize = size; + int maxSize = maxProgressBar; + string renderText = intToStr(static_cast(size)) + "%"; + if (customWidth > 0) { + if (size > 0) { + currentSize = (int) ((double) customWidth * ((double) size / 100.0)); + } + maxSize = customWidth; + //if(maxSize <= 0) { + // maxSize = maxProgressBar; + //} + } + if (prefixLabel != "") { + renderText = prefixLabel + renderText; + } + + //bar + glBegin(GL_QUADS); + glColor4fv(progressBarFront2.ptr()); + glVertex2i(x, y); + glVertex2i(x, y + 10); + glColor4fv(progressBarFront1.ptr()); + glVertex2i(x + currentSize, y + 10); + glVertex2i(x + currentSize, y); + glEnd(); + + //transp bar + glEnable(GL_BLEND); + glBegin(GL_QUADS); + glColor4fv(progressBarBack2.ptr()); + glVertex2i(x + currentSize, y); + glVertex2i(x + currentSize, y + 10); + glColor4fv(progressBarBack1.ptr()); + glVertex2i(x + maxSize, y + 10); + glVertex2i(x + maxSize, y); + glEnd(); + glDisable(GL_BLEND); + + //text + glColor3fv(defColor.ptr()); + + //textRenderer->begin(font); + TextRendererSafeWrapper safeTextRender(textRenderer, font); + if (centeredText == true) { + textRenderer->render(renderText.c_str(), x + maxSize / 2, y, centeredText); + } else { + textRenderer->render(renderText.c_str(), x, y, centeredText); + } + //textRenderer->end(); + safeTextRender.end(); + } + + + //void Renderer::renderTile(const Vec2i &pos) { + // if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + // return; + // } + // + // const Map *map= game->getWorld()->getMap(); + // Vec2i scaledPos= pos * Map::cellScale; + // + // glMatrixMode(GL_MODELVIEW); + // glPushMatrix(); + // glTranslatef(-0.5f, 0.f, -0.5f); + // + // glInitNames(); + // for(int i=0; i < Map::cellScale; ++i) { + // for(int j=0; j < Map::cellScale; ++j) { + // + // Vec2i renderPos= scaledPos + Vec2i(i, j); + // + // glPushName(renderPos.y); + // glPushName(renderPos.x); + // + // glDisable(GL_CULL_FACE); + // + // float h1 = map->getCell(renderPos.x, renderPos.y)->getHeight(); + // float h2 = map->getCell(renderPos.x, renderPos.y+1)->getHeight(); + // float h3 = map->getCell(renderPos.x+1, renderPos.y)->getHeight(); + // float h4 = map->getCell(renderPos.x+1, renderPos.y+1)->getHeight(); + // + // glBegin(GL_TRIANGLE_STRIP); + // glVertex3f( + // static_cast(renderPos.x), + // h1, + // static_cast(renderPos.y)); + // glVertex3f( + // static_cast(renderPos.x), + // h2, + // static_cast(renderPos.y+1)); + // glVertex3f( + // static_cast(renderPos.x+1), + // h3, + // static_cast(renderPos.y)); + // glVertex3f( + // static_cast(renderPos.x+1), + // h4, + // static_cast(renderPos.y+1)); + // glEnd(); + // + // glPopName(); + // glPopName(); + // } + // } + // + // glPopMatrix(); + //} + + void Renderer::renderQuad(int x, int y, int w, int h, const Texture2D *texture) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + if (texture == NULL) { + printf("\n**WARNING** detected a null texture to render in renderQuad!\n"); + return; + } + + if (w < 0) { + w = texture->getPixmapConst()->getW(); + } + if (h < 0) { + h = texture->getPixmapConst()->getH(); + } + + glBindTexture(GL_TEXTURE_2D, static_cast(texture)->getHandle()); + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2i(0, 1); + glVertex2i(x, y + h); + glTexCoord2i(0, 0); + glVertex2i(x, y); + glTexCoord2i(1, 1); + glVertex2i(x + w, y + h); + glTexCoord2i(1, 0); + glVertex2i(x + w, y); + glEnd(); + } + + Renderer::Shadows Renderer::strToShadows(const string &s) { + if (s == "Projected") { + return sProjected; + } else if (s == "ShadowMapping") { + return sShadowMapping; + } + return sDisabled; + } + + string Renderer::shadowsToStr(Shadows shadows) { + switch (shadows) { + case sDisabled: + return "Disabled2"; + case sProjected: + return "Projected"; + case sShadowMapping: + return "ShadowMapping"; + default: + assert(false); + return ""; + } + } + + Texture2D::Filter Renderer::strToTextureFilter(const string &s) { + if (s == "Bilinear") { + return Texture2D::fBilinear; + } else if (s == "Trilinear") { + return Texture2D::fTrilinear; + } + + throw megaglest_runtime_error("Error converting from string to FilterType, found: " + s); + } + + void Renderer::setAllowRenderUnitTitles(bool value) { + allowRenderUnitTitles = value; + } + + // This method renders titles for units + void Renderer::renderUnitTitles3D(Font3D *font, Vec3f color) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + //std::map unitRenderedList; + + if (visibleFrameUnitList.empty() == false) { + //printf("Render Unit titles ON\n"); + + for (int idx = 0; idx < (int) visibleFrameUnitList.size(); idx++) { + const Unit *unit = visibleFrameUnitList[idx]; + if (unit != NULL) { + if (unit->getVisible() == true) { + if (unit->getCurrentUnitTitle() != "") { + //get the screen coordinates + Vec3f screenPos = unit->getScreenPos(); + renderText3D(unit->getCurrentUnitTitle(), font, color, std::fabs(screenPos.x) + 5, std::fabs(screenPos.y) + 5, false); + //unitRenderedList[unit->getId()] = true; + } else { + string str = unit->getFullName(unit->showTranslatedTechTree()) + " - " + intToStr(unit->getId()) + " [" + unit->getPosNotThreadSafe().getString() + "]"; + Vec3f screenPos = unit->getScreenPos(); + renderText3D(str, font, color, std::fabs(screenPos.x) + 5, std::fabs(screenPos.y) + 5, false); + } + } + } + } + visibleFrameUnitList.clear(); + } + + /* + if(renderUnitTitleList.empty() == false) { + for(int idx = 0; idx < renderUnitTitleList.size(); idx++) { + std::pair &unitInfo = renderUnitTitleList[idx]; + Unit *unit = unitInfo.first; + + const World *world= game->getWorld(); + Unit *validUnit = world->findUnitById(unit->getId()); + + if(validUnit != NULL && unitRenderedList.find(validUnit->getId()) == unitRenderedList.end()) { + string str = validUnit->getFullName() + " - " + intToStr(validUnit->getId()); + //get the screen coordinates + Vec3f &screenPos = unitInfo.second; + renderText(str, font, color, fabs(screenPos.x) + 5, fabs(screenPos.y) + 5, false); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] screenPos.x = %f, screenPos.y = %f, screenPos.z = %f\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,screenPos.x,screenPos.y,screenPos.z); + } + } + renderUnitTitleList.clear(); + } + */ + } + + // This method renders titles for units + void Renderer::renderUnitTitles(Font2D *font, Vec3f color) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + //std::map unitRenderedList; + + if (visibleFrameUnitList.empty() == false) { + //printf("Render Unit titles ON\n"); + + for (int idx = 0; idx < (int) visibleFrameUnitList.size(); idx++) { + const Unit *unit = visibleFrameUnitList[idx]; + if (unit != NULL) { + if (unit->getCurrentUnitTitle() != "") { + //get the screen coordinates + Vec3f screenPos = unit->getScreenPos(); + renderText(unit->getCurrentUnitTitle(), font, color, std::fabs(screenPos.x) + 5, std::fabs(screenPos.y) + 5, false); + + //unitRenderedList[unit->getId()] = true; + } else { + string str = unit->getFullName(unit->showTranslatedTechTree()) + " - " + intToStr(unit->getId()) + " [" + unit->getPosNotThreadSafe().getString() + "]"; + Vec3f screenPos = unit->getScreenPos(); + renderText(str, font, color, std::fabs(screenPos.x) + 5, std::fabs(screenPos.y) + 5, false); + } + } + } + visibleFrameUnitList.clear(); + } + + /* + if(renderUnitTitleList.empty() == false) { + for(int idx = 0; idx < renderUnitTitleList.size(); idx++) { + std::pair &unitInfo = renderUnitTitleList[idx]; + Unit *unit = unitInfo.first; + + const World *world= game->getWorld(); + Unit *validUnit = world->findUnitById(unit->getId()); + + if(validUnit != NULL && unitRenderedList.find(validUnit->getId()) == unitRenderedList.end()) { + string str = validUnit->getFullName() + " - " + intToStr(validUnit->getId()); + //get the screen coordinates + Vec3f &screenPos = unitInfo.second; + renderText(str, font, color, fabs(screenPos.x) + 5, fabs(screenPos.y) + 5, false); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] screenPos.x = %f, screenPos.y = %f, screenPos.z = %f\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,screenPos.x,screenPos.y,screenPos.z); + } + } + renderUnitTitleList.clear(); + } + */ + } + + void Renderer::removeObjectFromQuadCache(const Object *o) { + VisibleQuadContainerCache &qCache = getQuadCache(); + for (int visibleIndex = 0; + visibleIndex < (int) qCache.visibleObjectList.size(); ++visibleIndex) { + Object *currentObj = qCache.visibleObjectList[visibleIndex]; + if (currentObj == o) { + qCache.visibleObjectList.erase(qCache.visibleObjectList.begin() + visibleIndex); + break; + } + } + } + + void Renderer::removeUnitFromQuadCache(const Unit *unit) { + VisibleQuadContainerCache &qCache = getQuadCache(); + for (int visibleIndex = 0; + visibleIndex < (int) qCache.visibleQuadUnitList.size(); ++visibleIndex) { + Unit *currentUnit = qCache.visibleQuadUnitList[visibleIndex]; + if (currentUnit == unit) { + qCache.visibleQuadUnitList.erase(qCache.visibleQuadUnitList.begin() + visibleIndex); + break; + } + } + for (int visibleIndex = 0; + visibleIndex < (int) qCache.visibleUnitList.size(); ++visibleIndex) { + Unit *currentUnit = qCache.visibleUnitList[visibleIndex]; + if (currentUnit == unit) { + qCache.visibleUnitList.erase(qCache.visibleUnitList.begin() + visibleIndex); + break; + } + } + } + + VisibleQuadContainerCache & Renderer::getQuadCache(bool updateOnDirtyFrame, + bool forceNew) { + //forceNew = true; + if (game != NULL && game->getWorld() != NULL) { + const World *world = game->getWorld(); + + if (forceNew == true || + (updateOnDirtyFrame == true && + (world->getFrameCount() != quadCache.cacheFrame || + visibleQuad != quadCache.lastVisibleQuad))) { + + // Dump cached info + //if(forceNew == true || visibleQuad != quadCache.lastVisibleQuad) { + //quadCache.clearCacheData(); + //} + //else { + quadCache.clearVolatileCacheData(); + worldToScreenPosCache.clear(); + //} + + // Unit calculations + for (int i = 0; i < world->getFactionCount(); ++i) { + const Faction *faction = world->getFaction(i); + for (int j = 0; j < faction->getUnitCount(); ++j) { + Unit *unit = faction->getUnit(j); + + bool unitCheckedForRender = false; + if (VisibleQuadContainerCache::enableFrustumCalcs == true) { + //bool insideQuad = PointInFrustum(quadCache.frustumData, unit->getCurrVector().x, unit->getCurrVector().y, unit->getCurrVector().z ); + bool insideQuad = CubeInFrustum(quadCache.frustumData, unit->getCurrMidHeightVector().x, unit->getCurrMidHeightVector().y, unit->getCurrMidHeightVector().z, unit->getType()->getRenderSize()); + bool renderInMap = world->toRenderUnit(unit); + if (insideQuad == false || renderInMap == false) { + unit->setVisible(false); + if (renderInMap == true) { + quadCache.visibleUnitList.push_back(unit); + } + unitCheckedForRender = true; // no more need to check any further; + // Currently don't need this list + //quadCache.inVisibleUnitList.push_back(unit); + } + } + if (unitCheckedForRender == false) { + bool insideQuad = visibleQuad.isInside(unit->getPos()); + bool renderInMap = world->toRenderUnit(unit); + if (insideQuad == true && renderInMap == true) { + quadCache.visibleQuadUnitList.push_back(unit); + } else { + unit->setVisible(false); + // Currently don't need this list + //quadCache.inVisibleUnitList.push_back(unit); + } + + if (renderInMap == true) { + quadCache.visibleUnitList.push_back(unit); + } + } + + bool unitBuildPending = unit->isBuildCommandPending(); + if (unitBuildPending == true) { + const UnitBuildInfo &pendingUnit = unit->getBuildCommandPendingInfo(); + const Vec2i &pos = pendingUnit.pos; + const Map *map = world->getMap(); + + bool unitBuildCheckedForRender = false; + + //printf("#1 Unit is about to build another unit\n"); + + if (VisibleQuadContainerCache::enableFrustumCalcs == true) { + Vec3f pos3f = Vec3f(pos.x, map->getCell(pos)->getHeight(), pos.y); + //bool insideQuad = PointInFrustum(quadCache.frustumData, unit->getCurrVector().x, unit->getCurrVector().y, unit->getCurrVector().z ); + bool insideQuad = CubeInFrustum(quadCache.frustumData, pos3f.x, pos3f.y, pos3f.z, pendingUnit.buildUnit->getRenderSize()); + bool renderInMap = world->toRenderUnit(pendingUnit); + if (insideQuad == false || renderInMap == false) { + if (renderInMap == true) { + quadCache.visibleQuadUnitBuildList.push_back(pendingUnit); + } + unitBuildCheckedForRender = true; // no more need to check any further; + // Currently don't need this list + //quadCache.inVisibleUnitList.push_back(unit); + } + + //printf("#2 Unit build added? insideQuad = %d, renderInMap = %d\n",insideQuad,renderInMap); + } + + if (unitBuildCheckedForRender == false) { + bool insideQuad = visibleQuad.isInside(pos); + bool renderInMap = world->toRenderUnit(pendingUnit); + if (insideQuad == true && renderInMap == true) { + quadCache.visibleQuadUnitBuildList.push_back(pendingUnit); + } else { + //unit->setVisible(false); + // Currently don't need this list + //quadCache.inVisibleUnitList.push_back(unit); + } + + //printf("#3 Unit build added? insideQuad = %d, renderInMap = %d\n",insideQuad,renderInMap); + } + + //printf("#4 quadCache.visibleQuadUnitBuildList.size() = %d\n",quadCache.visibleQuadUnitBuildList.size()); + } + } + } + + if (forceNew == true || visibleQuad != quadCache.lastVisibleQuad) { + // Object calculations + const Map *map = world->getMap(); + // clear visibility of old objects + for (int visibleIndex = 0; + visibleIndex < (int) quadCache.visibleObjectList.size(); ++visibleIndex) { + quadCache.visibleObjectList[visibleIndex]->setVisible(false); + } + quadCache.clearNonVolatileCacheData(); + + //int loops1=0; + PosQuadIterator pqi(map, visibleQuad, Map::cellScale); + while (pqi.next()) { + const Vec2i &pos = pqi.getPos(); + if (map->isInside(pos)) { + //loops1++; + const Vec2i &mapPos = Map::toSurfCoords(pos); + + //quadCache.visibleCellList.push_back(mapPos); + + SurfaceCell *sc = map->getSurfaceCell(mapPos); + Object *o = sc->getObject(); + + if (VisibleQuadContainerCache::enableFrustumCalcs == true) { + if (o != NULL) { + //bool insideQuad = PointInFrustum(quadCache.frustumData, o->getPos().x, o->getPos().y, o->getPos().z ); + bool insideQuad = CubeInFrustum(quadCache.frustumData, o->getPos().x, o->getPos().y, o->getPos().z, 1); + if (insideQuad == false) { + o->setVisible(false); + continue; + } + } + } + + bool cellExplored = world->showWorldForPlayer(world->getThisFactionIndex()); + if (cellExplored == false) { + cellExplored = sc->isExplored(world->getThisTeamIndex()); + } + + bool isExplored = (cellExplored == true && o != NULL); + //bool isVisible = (sc->isVisible(world->getThisTeamIndex()) && o != NULL); + bool isVisible = true; + + if (isExplored == true && isVisible == true) { + quadCache.visibleObjectList.push_back(o); + o->setVisible(true); + } + } + } + + //printf("Frame # = %d loops1 = %d\n",world->getFrameCount(),loops1); + + //int loops2=0; + + std::map markedCells = game->getMapMarkedCellList(); + + const Rect2i mapBounds(0, 0, map->getSurfaceW() - 1, map->getSurfaceH() - 1); + Quad2i scaledQuad = visibleQuad / Map::cellScale; + PosQuadIterator pqis(map, scaledQuad); + while (pqis.next()) { + const Vec2i &pos = pqis.getPos(); + if (mapBounds.isInside(pos)) { + //loops2++; + if (VisibleQuadContainerCache::enableFrustumCalcs == false) { + quadCache.visibleScaledCellList.push_back(pos); + + if (markedCells.empty() == false) { + if (markedCells.find(pos) != markedCells.end()) { + //printf("#1 ******** VISIBLE SCALED CELL FOUND in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",pos.getString().c_str(),markedCells.size()); + //if(markedCells.empty() == false) { + //SurfaceCell *sc = map->getSurfaceCell(pos); + //quadCache.visibleScaledCellToScreenPosList[pos]=computeScreenPosition(sc->getVertex()); + updateMarkedCellScreenPosQuadCache(pos); + } else { + //printf("#1 VISIBLE SCALED CELL NOT FOUND in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",pos.getString().c_str(),markedCells.size()); + } + } + } else { + //bool insideQuad = false; + + //if( !insideQuad) { + SurfaceCell *sc = map->getSurfaceCell(pos.x, pos.y); + bool insideQuad = CubeInFrustum(quadCache.frustumData, sc->getVertex().x, sc->getVertex().y, sc->getVertex().z, 0); + //} + if (!insideQuad) { + SurfaceCell *sc = map->getSurfaceCell(pos.x + 1, pos.y); + insideQuad = CubeInFrustum(quadCache.frustumData, sc->getVertex().x, sc->getVertex().y, sc->getVertex().z, 0); + } + if (!insideQuad) { + SurfaceCell *sc = map->getSurfaceCell(pos.x, pos.y + 1); + insideQuad = CubeInFrustum(quadCache.frustumData, sc->getVertex().x, sc->getVertex().y, sc->getVertex().z, 0); + } + if (!insideQuad) { + SurfaceCell *sc = map->getSurfaceCell(pos.x + 1, pos.y + 1); + insideQuad = CubeInFrustum(quadCache.frustumData, sc->getVertex().x, sc->getVertex().y, sc->getVertex().z, 0); + } + + if (insideQuad == true) { + quadCache.visibleScaledCellList.push_back(pos); + + if (markedCells.empty() == false) { + if (markedCells.find(pos) != markedCells.end()) { + //printf("#2 ******** VISIBLE SCALED CELL FOUND in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",pos.getString().c_str(),markedCells.size()); + //if(markedCells.empty() == false) { + //quadCache.visibleScaledCellToScreenPosList[pos]=computeScreenPosition(sc->getVertex()); + updateMarkedCellScreenPosQuadCache(pos); + } else { + //printf("#2 VISIBLE SCALED CELL NOT FOUND in marked list pos [%s] markedCells.size() = " MG_SIZE_T_SPECIFIER "\n",pos.getString().c_str(),markedCells.size()); + } + } + } + } + } + } + //printf("Frame # = %d loops2 = %d\n",world->getFrameCount(),loops2); + } + quadCache.cacheFrame = world->getFrameCount(); + quadCache.lastVisibleQuad = visibleQuad; + } + } + + return quadCache; + } + + void Renderer::updateMarkedCellScreenPosQuadCache(Vec2i pos) { + const World *world = game->getWorld(); + const Map *map = world->getMap(); + + SurfaceCell *sc = map->getSurfaceCell(pos); + quadCache.visibleScaledCellToScreenPosList[pos] = computeScreenPosition(sc->getVertex()); + } + + void Renderer::forceQuadCacheUpdate() { + quadCache.cacheFrame = -1; + + Vec2i clearPos(-1, -1); + quadCache.lastVisibleQuad.p[0] = clearPos; + quadCache.lastVisibleQuad.p[1] = clearPos; + quadCache.lastVisibleQuad.p[2] = clearPos; + quadCache.lastVisibleQuad.p[3] = clearPos; + } + + std::pair Renderer::posInCellQuadCache(Vec2i pos) { + std::pair result = make_pair(false, Vec3f()); + if (std::find( + quadCache.visibleScaledCellList.begin(), + quadCache.visibleScaledCellList.end(), + pos) != quadCache.visibleScaledCellList.end()) { + result.first = true; + result.second = quadCache.visibleScaledCellToScreenPosList[pos]; + } + return result; + } + + //Vec3f Renderer::getMarkedCellScreenPosQuadCache(Vec2i pos) { + // Vec3f result(-1,-1,-1); + // if(std::find( + // quadCache.visibleScaledCellList.begin(), + // quadCache.visibleScaledCellList.end(), + // pos) != quadCache.visibleScaledCellList.end()) { + // result = quadCache.visibleScaledCellToScreenPosList[pos]; + // } + // return result; + //} + + void Renderer::beginRenderToTexture(Texture2D **renderToTexture) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + static bool supportFBOs = Texture2DGl().supports_FBO_RBO(); + + if (supportFBOs == true && renderToTexture != NULL) { + Config &config = Config::getInstance(); + Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter")); + int maxAnisotropy = config.getInt("FilterMaxAnisotropy"); + + const Metrics &metrics = Metrics::getInstance(); + + *renderToTexture = GraphicsInterface::getInstance().getFactory()->newTexture2D(); + Texture2DGl *texture = static_cast(*renderToTexture); + texture->setMipmap(false); + Pixmap2D *pixmapScreenShot = texture->getPixmap(); + pixmapScreenShot->init(metrics.getScreenW(), metrics.getScreenH(), 4); + texture->setForceCompressionDisabled(true); + texture->init(textureFilter, maxAnisotropy); + texture->setup_FBO_RBO(); + + assertGl(); + + if (texture->checkFrameBufferStatus() == false) { + //printf("******************** WARNING CANNOT Attach to FBO!\n"); + texture->end(); + delete texture; + *renderToTexture = NULL; + } + } + } + + void Renderer::endRenderToTexture(Texture2D **renderToTexture) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + static bool supportFBOs = Texture2DGl().supports_FBO_RBO(); + + if (supportFBOs == true && renderToTexture != NULL && *renderToTexture != NULL) { + Texture2DGl *texture = static_cast(*renderToTexture); + if (texture != NULL) { + texture->dettachFrameBufferFromTexture(); + } + + assertGl(); + } + } + + void Renderer::renderMapPreview(const MapPreview *map, bool renderAll, + int screenPosX, int screenPosY, + Texture2D **renderToTexture) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + static bool supportFBOs = Texture2DGl().supports_FBO_RBO(); + if (Config::getInstance().getBool("LegacyMapPreviewRendering", "false") == true) { + supportFBOs = false; + } + + //static bool supportFBOs = false; + const Metrics &metrics = Metrics::getInstance(); + + float alt = 0; + float showWater = 0; + int renderMapHeight = 64; + int renderMapWidth = 64; + float cellSize = 2; + float playerCrossSize = 2; + float clientW = renderMapWidth * cellSize; + float clientH = renderMapHeight * cellSize;; + float minDimension = std::min(metrics.getVirtualW(), metrics.getVirtualH()); + + // stretch small maps to 128x128 + if (map->getW() < map->getH()) { + cellSize = cellSize * renderMapHeight / map->getH(); + } else { + cellSize = cellSize * renderMapWidth / map->getW(); + } + + assertGl(); + + if (supportFBOs == true && renderToTexture != NULL) { + Config &config = Config::getInstance(); + Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter")); + int maxAnisotropy = config.getInt("FilterMaxAnisotropy"); + + *renderToTexture = GraphicsInterface::getInstance().getFactory()->newTexture2D(); + Texture2DGl *texture = static_cast(*renderToTexture); + texture->setMipmap(false); + Pixmap2D *pixmapScreenShot = texture->getPixmap(); + pixmapScreenShot->init(minDimension, minDimension, 4); + texture->setForceCompressionDisabled(true); + texture->init(textureFilter, maxAnisotropy); + texture->setup_FBO_RBO(); + + assertGl(); + + if (texture->checkFrameBufferStatus() == false) { + //printf("******************** WARNING CANNOT Attach to FBO!\n"); + texture->end(); + delete texture; + *renderToTexture = NULL; + } + } + + if (supportFBOs == true && renderToTexture != NULL && *renderToTexture != NULL) { + cellSize = 1; + clientW = minDimension; + clientH = minDimension; + int mapMaxDimensionSize = std::max(map->getW(), map->getH()); + switch (mapMaxDimensionSize) { + case 8: + cellSize = 96; + break; + case 16: + cellSize = 48; + break; + case 32: + cellSize = 24; + break; + case 64: + cellSize = 12; + break; + case 128: + cellSize = 6; + break; + case 256: + cellSize = 3; + break; + case 512: + cellSize = 2; + break; + } + } + + glFrontFace(GL_CW); + glEnable(GL_CULL_FACE); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + assertGl(); + + GLint viewport[4]; // Where The original Viewport Values Will Be Stored + + if (supportFBOs == true && renderToTexture != NULL && *renderToTexture != NULL) { + glGetIntegerv(GL_VIEWPORT, viewport); + glOrtho(0, clientW, 0, clientH, 0, 1); + glViewport(0, 0, clientW, clientH); + } else { + glOrtho(0, metrics.getVirtualW(), 0, metrics.getVirtualH(), 0, 1); + } + + glMatrixMode(GL_MODELVIEW); + + glPushMatrix(); + glLoadIdentity(); + + if (supportFBOs == false || renderToTexture == NULL || *renderToTexture == NULL) { + glTranslatef(static_cast(screenPosX), static_cast(screenPosY) - clientH, 0.0f); + } + + assertGl(); + + glPushAttrib(GL_CURRENT_BIT); + glLineWidth(1); + glColor3f(0, 0, 0); + + for (int j = 0; j < map->getH(); j++) { + for (int i = 0; i < map->getW(); i++) { + //surface + alt = map->getHeight(i, j) / 20.f; + showWater = map->getWaterLevel() / 20.f - alt; + showWater = (showWater > 0) ? showWater : 0; + Vec3f surfColor; + switch (map->getSurface(i, j)) { + case st_Grass: + surfColor = Vec3f(0.0, 0.8f * alt, 0.f + showWater); + break; + case st_Secondary_Grass: + surfColor = Vec3f(0.4f * alt, 0.6f * alt, 0.f + showWater); + break; + case st_Road: + surfColor = Vec3f(0.6f * alt, 0.3f * alt, 0.f + showWater); + break; + case st_Stone: + surfColor = Vec3f(0.7f * alt, 0.7f * alt, 0.7f * alt + showWater); + break; + case st_Ground: + surfColor = Vec3f(0.7f * alt, 0.5f * alt, 0.3f * alt + showWater); + break; + } + + glColor3fv(surfColor.ptr()); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2f(i * cellSize, clientH - j * cellSize - cellSize); + glVertex2f(i * cellSize, clientH - j * cellSize); + glVertex2f(i * cellSize + cellSize, clientH - j * cellSize - cellSize); + glVertex2f(i * cellSize + cellSize, clientH - j * cellSize); + glEnd(); + + //objects + if (renderAll == true) { + switch (map->getObject(i, j)) { + case 0: + glColor3f(0.f, 0.f, 0.f); + break; + case 1: + glColor3f(1.f, 0.f, 0.f); + break; + case 2: + glColor3f(1.f, 1.f, 1.f); + break; + case 3: + glColor3f(0.5f, 0.5f, 1.f); + break; + case 4: + glColor3f(0.f, 0.f, 1.f); + break; + case 5: + glColor3f(0.5f, 0.5f, 0.5f); + break; + case 6: + glColor3f(1.f, 0.8f, 0.5f); + break; + case 7: + glColor3f(0.f, 1.f, 1.f); + break; + case 8: + glColor3f(0.7f, 0.1f, 0.3f); + break; + case 9: + glColor3f(0.5f, 1.f, 0.1f); + break; + case 10: + glColor3f(1.f, 0.2f, 0.8f); + break;// we don't render unvisible blocking objects + } + + if (renderAll && (map->getObject(i, j) != 0) && (map->getObject(i, j) != 10)) { + glPointSize(cellSize / 2.f); + glBegin(GL_POINTS); + glVertex2f(i * cellSize + cellSize / 2.f, clientH - j * cellSize - cellSize / 2.f); + glEnd(); + } + } + + // bool found = false; + + //height lines + // if (!found) { + + //left + if (i > 0 && map->getHeight(i - 1, j) > map->getHeight(i, j)) { + glColor3fv((surfColor*0.5f).ptr()); glBegin(GL_LINES); - glVertex2f(i * cellSize, clientH - j * cellSize - cellSize); - glVertex2f(i * cellSize + cellSize, clientH - j * cellSize); + glVertex2f(i * cellSize, clientH - (j + 1) * cellSize); glVertex2f(i * cellSize, clientH - j * cellSize); - glVertex2f(i * cellSize + cellSize, clientH - j * cellSize - cellSize); glEnd(); } + //down + if (j > 0 && map->getHeight(i, j - 1) > map->getHeight(i, j)) { + glColor3fv((surfColor*0.5f).ptr()); + glBegin(GL_LINES); + glVertex2f(i * cellSize, clientH - j * cellSize); + glVertex2f((i + 1) * cellSize, clientH - j * cellSize); + glEnd(); + } + + + //left + if (i > 0 && map->getHeight(i - 1, j) < map->getHeight(i, j)) { + glColor3fv((surfColor*2.f).ptr()); + glBegin(GL_LINES); + glVertex2f(i * cellSize, clientH - (j + 1) * cellSize); + glVertex2f(i * cellSize, clientH - j * cellSize); + glEnd(); + } + if (j > 0 && map->getHeight(i, j - 1) < map->getHeight(i, j)) { + glColor3fv((surfColor*2.f).ptr()); + glBegin(GL_LINES); + glVertex2f(i * cellSize, clientH - j * cellSize); + glVertex2f((i + 1) * cellSize, clientH - j * cellSize); + glEnd(); + } + // } + + //resources + if (renderAll == true) { + switch (map->getResource(i, j)) { + case 1: glColor3f(1.f, 1.f, 0.f); break; + case 2: glColor3f(0.5f, 0.5f, 0.5f); break; + case 3: glColor3f(1.f, 0.f, 0.f); break; + case 4: glColor3f(0.f, 0.f, 1.f); break; + case 5: glColor3f(0.5f, 0.5f, 1.f); break; + } + + if (renderAll && map->getResource(i, j) != 0) { + glBegin(GL_LINES); + glVertex2f(i * cellSize, clientH - j * cellSize - cellSize); + glVertex2f(i * cellSize + cellSize, clientH - j * cellSize); + glVertex2f(i * cellSize, clientH - j * cellSize); + glVertex2f(i * cellSize + cellSize, clientH - j * cellSize - cellSize); + glEnd(); + } + } } - } - } - - //start locations - glLineWidth(3); - - assertGl(); - - if(supportFBOs == true && renderToTexture != NULL && *renderToTexture != NULL) { - glLineWidth(14); - playerCrossSize = 24; - } - else { - // force playerCrossSize to be at least of size 4 - if(cellSize < 4) { - playerCrossSize = 4; - } - else { - playerCrossSize = cellSize; - } - } - - assertGl(); - - Vec2f *vertices = new Vec2f[map->getMaxFactions() * 4]; - Vec3f *colors = new Vec3f[map->getMaxFactions() * 4]; - - for (int i = 0; i < map->getMaxFactions(); i++) { - Vec3f color; - switch (i) { - case 0: - color = Vec3f(1.f, 0.f, 0.f); - break; - case 1: - color = Vec3f(0.f, 0.f, 1.f); - break; - case 2: - color = Vec3f(0.f, 1.f, 0.f); - break; - case 3: - color = Vec3f(1.f, 1.f, 0.f); - break; - case 4: - color = Vec3f(1.f, 1.f, 1.f); - break; - case 5: - color = Vec3f(0.f, 1.f, 0.8f); - break; - case 6: - color = Vec3f(1.f, 0.5f, 0.f); - break; - case 7: - color = Vec3f(1.f, 0.5f, 1.f); - break; - } - - colors[i*4] = color; - colors[(i*4)+1] = color; - colors[(i*4)+2] = color; - colors[(i*4)+3] = color; - - vertices[i*4] = Vec2f((map->getStartLocationX(i) - 1) * cellSize, clientH - (map->getStartLocationY(i) - 1) * cellSize); - vertices[(i*4)+1] = Vec2f((map->getStartLocationX(i) + 1) * cellSize + playerCrossSize, clientH - (map->getStartLocationY(i) + 1) * cellSize - playerCrossSize); - vertices[(i*4)+2] = Vec2f((map->getStartLocationX(i) - 1) * cellSize, clientH - (map->getStartLocationY(i) + 1) * cellSize - playerCrossSize); - vertices[(i*4)+3] = Vec2f((map->getStartLocationX(i) + 1) * cellSize + playerCrossSize, clientH - (map->getStartLocationY(i) - 1) * cellSize); - } - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(3, GL_FLOAT, 0, &colors[0]); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, &vertices[0]); - glDrawArrays(GL_LINES, 0, 4 * map->getMaxFactions()); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - - assertGl(); - - glLineWidth(1); - - glPopMatrix(); - glPopAttrib(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - - if(supportFBOs == true && renderToTexture != NULL && *renderToTexture != NULL) { - Texture2DGl *texture = static_cast(*renderToTexture); - if(texture != NULL) { - texture->dettachFrameBufferFromTexture(); - } - - glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); - - assertGl(); - } - - delete [] vertices; - delete [] colors; - - assertGl(); -} - -// setLastRenderFps and calculate shadowsOffDueToMinRender -void Renderer::setLastRenderFps(int value) { - lastRenderFps = value; - smoothedRenderFps=(MIN_FPS_NORMAL_RENDERING*smoothedRenderFps+lastRenderFps)/(MIN_FPS_NORMAL_RENDERING+1.0f); - - if(smoothedRenderFps>=MIN_FPS_NORMAL_RENDERING_TOP_THRESHOLD){ - shadowsOffDueToMinRender=false; - } - if(smoothedRenderFps<=MIN_FPS_NORMAL_RENDERING){ - shadowsOffDueToMinRender=true; - } -} - -std::size_t Renderer::getCurrentPixelByteCount(ResourceScope rs) const { - std::size_t result = 0; - for(int i = (rs == rsCount ? 0 : rs); i < rsCount; ++i) { - if(textureManager[i] != NULL) { - const ::Shared::Graphics::TextureContainer &textures = textureManager[i]->getTextures(); - for(int j = 0; j < (int)textures.size(); ++j) { - const Texture *texture = textures[j]; - result += texture->getPixelByteCount(); - } - if(rs != rsCount) { - break; - } - } - } - - return result; -} - -Texture2D * Renderer::preloadTexture(string logoFilename) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] logoFilename [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,logoFilename.c_str()); - - Texture2D *result = NULL; - if(logoFilename != "") { - // Cache faction preview textures - string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey); - std::map &crcFactionPreviewTextureCache = CacheManager::getCachedItem< std::map >(GameConstants::factionPreviewTextureCacheLookupKey); - - if(crcFactionPreviewTextureCache.find(logoFilename) != crcFactionPreviewTextureCache.end()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] logoFilename [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,logoFilename.c_str()); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] load texture from cache [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,logoFilename.c_str()); - - result = crcFactionPreviewTextureCache[logoFilename]; - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] logoFilename [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,logoFilename.c_str()); - Renderer &renderer= Renderer::getInstance(); - result = renderer.newTexture2D(rsGlobal); - if(result) { - result->setMipmap(true); - result->load(logoFilename); - //renderer.initTexture(rsGlobal,result); } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] add texture to manager and cache [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,logoFilename.c_str()); + //start locations + glLineWidth(3); - crcFactionPreviewTextureCache[logoFilename] = result; - } - } + assertGl(); - return result; -} - -Texture2D * Renderer::findTexture(string logoFilename) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] logoFilename [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,logoFilename.c_str()); - - Texture2D *result = preloadTexture(logoFilename); - if(result != NULL && result->getInited() == false) { - Renderer &renderer= Renderer::getInstance(); - renderer.initTexture(rsGlobal,result); - } - - return result; -} - -void Renderer::cycleShowDebugUILevel() { - //printf("#1 showDebugUILevel = %d, debugui_fps = %d, debugui_unit_titles = %d\n",showDebugUILevel,debugui_fps,debugui_unit_titles); - - //if(showDebugUI == false) { - // showDebugUI = true; - //} - if((showDebugUILevel & debugui_fps) != debugui_fps || - (showDebugUILevel & debugui_unit_titles) != debugui_unit_titles) { - showDebugUILevel |= debugui_fps; - showDebugUILevel |= debugui_unit_titles; - } - else { - showDebugUILevel = debugui_fps; - } - - //printf("#2 showDebugUILevel = %d, debugui_fps = %d, debugui_unit_titles = %d\n",showDebugUILevel,debugui_fps,debugui_unit_titles); -} - -void Renderer::renderFPSWhenEnabled(int lastFps) { - if(getShowDebugUI() == true) { - CoreData &coreData= CoreData::getInstance(); - if(Renderer::renderText3DEnabled) { - renderText3D( - "FPS: " + intToStr(lastFps), - coreData.getMenuFontNormal3D(), Vec3f(1.f), 10, 10, false); - } - else { - renderText( - "FPS: " + intToStr(lastFps), - coreData.getMenuFontNormal(), Vec3f(1.f), 10, 10, false); - } - } -} - -void Renderer::renderPopupMenu(PopupMenu *menu) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - if(menu->getVisible() == false || menu->getEnabled() == false) { - return; - } - - //background - glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); - glEnable(GL_BLEND); - - glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ; - glBegin(GL_TRIANGLE_STRIP); - glVertex2i(menu->getX(), menu->getY() + 9 * menu->getH() / 10); - glVertex2i(menu->getX(), menu->getY()); - glVertex2i(menu->getX() + menu->getW(), menu->getY() + 9 * menu->getH() / 10); - glVertex2i(menu->getX() + menu->getW(), menu->getY()); - glEnd(); - - glColor4f(0.0f, 0.0f, 0.0f, 0.8f) ; - glBegin(GL_TRIANGLE_STRIP); - glVertex2i(menu->getX(), menu->getY() + menu->getH()); - glVertex2i(menu->getX(), menu->getY() + 9 * menu->getH() / 10); - glVertex2i(menu->getX() + menu->getW(), menu->getY() + menu->getH()); - glVertex2i(menu->getX() + menu->getW(), menu->getY() + 9 * menu->getH() / 10); - glEnd(); - - glBegin(GL_LINE_LOOP); - glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ; - glVertex2i(menu->getX(), menu->getY()); - - glColor4f(0.0f, 0.0f, 0.0f, 0.25f) ; - glVertex2i(menu->getX() + menu->getW(), menu->getY()); - - glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ; - glVertex2i(menu->getX() + menu->getW(), menu->getY() + menu->getH()); - - glColor4f(0.25f, 0.25f, 0.25f, 0.25f) ; - glVertex2i(menu->getX(), menu->getY() + menu->getH()); - glEnd(); - - glBegin(GL_LINE_STRIP); - glColor4f(1.0f, 1.0f, 1.0f, 0.25f) ; - glVertex2i(menu->getX(), menu->getY() + 90*menu->getH()/100); - - glColor4f(0.5f, 0.5f, 0.5f, 0.25f) ; - glVertex2i(menu->getX()+ menu->getW(), menu->getY() + 90*menu->getH()/100); - glEnd(); - - glPopAttrib(); - - Vec4f fontColor; - //if(game!=NULL){ - // fontColor=game->getGui()->getDisplay()->getColor(); - //} - //else { - // white shadowed is default ( in the menu for example ) - fontColor=Vec4f(1.f, 1.f, 1.f, 1.0f); - //} - - if(renderText3DEnabled == true) { - //text - renderTextBoundingBox3D( - menu->getHeader(), menu->getFont3D(),fontColor, - menu->getX(), menu->getY()+93*menu->getH()/100,menu->getW(),0, - true,false, false,-1,-1); - - } - else { - //text - int renderX = (menu->getX() + (menu->getW() / 2)); - //int renderY = (menu->getY() + (menu->getH() / 2)); - FontMetrics *fontMetrics= menu->getFont()->getMetrics(); - int renderY = menu->getY() + menu->getH() - fontMetrics->getHeight(menu->getHeader()); - renderTextShadow( - menu->getHeader(), menu->getFont(),fontColor, - renderX, renderY, - true); - - //renderText(button->getText(), button->getFont(), color,x + (w / 2), y + (h / 2), true); - } - - //buttons -// int maxButtonWidth = -1; - std::vector &menuItems = menu->getMenuItems(); -// for(unsigned int i = 0; i < menuItems.size(); ++i) { -// GraphicButton *button = &menuItems[i]; -// int currentButtonWidth = -1; -// if(renderText3DEnabled == true) { -// FontMetrics *fontMetrics= menu->getFont3D()->getMetrics(); -// currentButtonWidth = fontMetrics->getTextWidth(button->getText()); -// } -// else { -// FontMetrics *fontMetrics= menu->getFont()->getMetrics(); -// currentButtonWidth = fontMetrics->getTextWidth(button->getText()); -// } -// -// if(maxButtonWidth < 0 || currentButtonWidth > maxButtonWidth) { -// maxButtonWidth = currentButtonWidth + 5; -// } -// } - - for(unsigned int i = 0; i < menuItems.size(); ++i) { - GraphicButton *button = &menuItems[i]; - - //button->setW(maxButtonWidth); - renderButton(button); - } - -} - -void Renderer::setupRenderForVideo() { - clearBuffers(); - //3d - reset3dMenu(); - clearZBuffer(); - //2d - reset2d(); - glClearColor(0.f, 0.f, 0.f, 1.f); -} - -void Renderer::renderVideoLoading(int progressPercent) { - //printf("Rendering progress progressPercent = %d\n",progressPercent); - setupRenderForVideo(); - - Lang &lang= Lang::getInstance(); - string textToRender = lang.getString("PleaseWait"); - const Metrics &metrics= Metrics::getInstance(); - - static Chrono cycle(true); - static float anim = 0.0f; - - if(CoreData::getInstance().getMenuFontBig3D() != NULL) { - - int w= metrics.getVirtualW(); - int renderX = (w / 2) - (CoreData::getInstance().getMenuFontBig3D()->getMetrics()->getTextWidth(textToRender) / 2); - int h= metrics.getVirtualH(); - int renderY = (h / 2) + (CoreData::getInstance().getMenuFontBig3D()->getMetrics()->getHeight(textToRender) / 2); - - renderText3D( - textToRender, - CoreData::getInstance().getMenuFontBig3D(), - Vec4f(1.f, 1.f, 0.f,anim), - renderX, renderY, false); - } - else { - renderText( - textToRender, - CoreData::getInstance().getMenuFontBig(), - Vec4f(1.f, 1.f, 0.f,anim), (metrics.getScreenW() / 2), - (metrics.getScreenH() / 2), true); - } - swapBuffers(); - - if(cycle.getCurMillis() % 50 == 0) { - static bool animCycleUp = true; - if(animCycleUp == true) { - anim += 0.1f; - if(anim > 1.f) { - anim= 1.f; - cycle.reset(); - animCycleUp = false; + if (supportFBOs == true && renderToTexture != NULL && *renderToTexture != NULL) { + glLineWidth(14); + playerCrossSize = 24; + } else { + // force playerCrossSize to be at least of size 4 + if (cellSize < 4) { + playerCrossSize = 4; + } else { + playerCrossSize = cellSize; + } } - } - else { - anim -= 0.1f; - if(anim < 0.f) { - anim= 0.f; - cycle.reset(); - animCycleUp = true; - } - } - } -} -}}//end namespace + assertGl(); + + Vec2f *vertices = new Vec2f[map->getMaxFactions() * 4]; + Vec3f *colors = new Vec3f[map->getMaxFactions() * 4]; + + for (int i = 0; i < map->getMaxFactions(); i++) { + Vec3f color; + switch (i) { + case 0: + color = Vec3f(1.f, 0.f, 0.f); + break; + case 1: + color = Vec3f(0.f, 0.f, 1.f); + break; + case 2: + color = Vec3f(0.f, 1.f, 0.f); + break; + case 3: + color = Vec3f(1.f, 1.f, 0.f); + break; + case 4: + color = Vec3f(1.f, 1.f, 1.f); + break; + case 5: + color = Vec3f(0.f, 1.f, 0.8f); + break; + case 6: + color = Vec3f(1.f, 0.5f, 0.f); + break; + case 7: + color = Vec3f(1.f, 0.5f, 1.f); + break; + } + + colors[i * 4] = color; + colors[(i * 4) + 1] = color; + colors[(i * 4) + 2] = color; + colors[(i * 4) + 3] = color; + + vertices[i * 4] = Vec2f((map->getStartLocationX(i) - 1) * cellSize, clientH - (map->getStartLocationY(i) - 1) * cellSize); + vertices[(i * 4) + 1] = Vec2f((map->getStartLocationX(i) + 1) * cellSize + playerCrossSize, clientH - (map->getStartLocationY(i) + 1) * cellSize - playerCrossSize); + vertices[(i * 4) + 2] = Vec2f((map->getStartLocationX(i) - 1) * cellSize, clientH - (map->getStartLocationY(i) + 1) * cellSize - playerCrossSize); + vertices[(i * 4) + 3] = Vec2f((map->getStartLocationX(i) + 1) * cellSize + playerCrossSize, clientH - (map->getStartLocationY(i) - 1) * cellSize); + } + + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(3, GL_FLOAT, 0, &colors[0]); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, &vertices[0]); + glDrawArrays(GL_LINES, 0, 4 * map->getMaxFactions()); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + + assertGl(); + + glLineWidth(1); + + glPopMatrix(); + glPopAttrib(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + if (supportFBOs == true && renderToTexture != NULL && *renderToTexture != NULL) { + Texture2DGl *texture = static_cast(*renderToTexture); + if (texture != NULL) { + texture->dettachFrameBufferFromTexture(); + } + + glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + + assertGl(); + } + + delete[] vertices; + delete[] colors; + + assertGl(); + } + + // setLastRenderFps and calculate shadowsOffDueToMinRender + void Renderer::setLastRenderFps(int value) { + lastRenderFps = value; + smoothedRenderFps = (MIN_FPS_NORMAL_RENDERING*smoothedRenderFps + lastRenderFps) / (MIN_FPS_NORMAL_RENDERING + 1.0f); + + if (smoothedRenderFps >= MIN_FPS_NORMAL_RENDERING_TOP_THRESHOLD) { + shadowsOffDueToMinRender = false; + } + if (smoothedRenderFps <= MIN_FPS_NORMAL_RENDERING) { + shadowsOffDueToMinRender = true; + } + } + + std::size_t Renderer::getCurrentPixelByteCount(ResourceScope rs) const { + std::size_t result = 0; + for (int i = (rs == rsCount ? 0 : rs); i < rsCount; ++i) { + if (textureManager[i] != NULL) { + const ::Shared::Graphics::TextureContainer &textures = textureManager[i]->getTextures(); + for (int j = 0; j < (int) textures.size(); ++j) { + const Texture *texture = textures[j]; + result += texture->getPixelByteCount(); + } + if (rs != rsCount) { + break; + } + } + } + + return result; + } + + Texture2D * Renderer::preloadTexture(string logoFilename) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] logoFilename [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, logoFilename.c_str()); + + Texture2D *result = NULL; + if (logoFilename != "") { + // Cache faction preview textures + string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + std::map &crcFactionPreviewTextureCache = CacheManager::getCachedItem< std::map >(GameConstants::factionPreviewTextureCacheLookupKey); + + if (crcFactionPreviewTextureCache.find(logoFilename) != crcFactionPreviewTextureCache.end()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] logoFilename [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, logoFilename.c_str()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] load texture from cache [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, logoFilename.c_str()); + + result = crcFactionPreviewTextureCache[logoFilename]; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] logoFilename [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, logoFilename.c_str()); + Renderer &renderer = Renderer::getInstance(); + result = renderer.newTexture2D(rsGlobal); + if (result) { + result->setMipmap(true); + result->load(logoFilename); + //renderer.initTexture(rsGlobal,result); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] add texture to manager and cache [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, logoFilename.c_str()); + + crcFactionPreviewTextureCache[logoFilename] = result; + } + } + + return result; + } + + Texture2D * Renderer::findTexture(string logoFilename) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] logoFilename [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, logoFilename.c_str()); + + Texture2D *result = preloadTexture(logoFilename); + if (result != NULL && result->getInited() == false) { + Renderer &renderer = Renderer::getInstance(); + renderer.initTexture(rsGlobal, result); + } + + return result; + } + + void Renderer::cycleShowDebugUILevel() { + //printf("#1 showDebugUILevel = %d, debugui_fps = %d, debugui_unit_titles = %d\n",showDebugUILevel,debugui_fps,debugui_unit_titles); + + //if(showDebugUI == false) { + // showDebugUI = true; + //} + if ((showDebugUILevel & debugui_fps) != debugui_fps || + (showDebugUILevel & debugui_unit_titles) != debugui_unit_titles) { + showDebugUILevel |= debugui_fps; + showDebugUILevel |= debugui_unit_titles; + } else { + showDebugUILevel = debugui_fps; + } + + //printf("#2 showDebugUILevel = %d, debugui_fps = %d, debugui_unit_titles = %d\n",showDebugUILevel,debugui_fps,debugui_unit_titles); + } + + void Renderer::renderFPSWhenEnabled(int lastFps) { + if (getShowDebugUI() == true) { + CoreData &coreData = CoreData::getInstance(); + if (Renderer::renderText3DEnabled) { + renderText3D( + "FPS: " + intToStr(lastFps), + coreData.getMenuFontNormal3D(), Vec3f(1.f), 10, 10, false); + } else { + renderText( + "FPS: " + intToStr(lastFps), + coreData.getMenuFontNormal(), Vec3f(1.f), 10, 10, false); + } + } + } + + void Renderer::renderPopupMenu(PopupMenu *menu) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (menu->getVisible() == false || menu->getEnabled() == false) { + return; + } + + //background + glPushAttrib(GL_ENABLE_BIT | GL_CURRENT_BIT); + glEnable(GL_BLEND); + + glColor4f(0.0f, 0.0f, 0.0f, 0.8f); + glBegin(GL_TRIANGLE_STRIP); + glVertex2i(menu->getX(), menu->getY() + 9 * menu->getH() / 10); + glVertex2i(menu->getX(), menu->getY()); + glVertex2i(menu->getX() + menu->getW(), menu->getY() + 9 * menu->getH() / 10); + glVertex2i(menu->getX() + menu->getW(), menu->getY()); + glEnd(); + + glColor4f(0.0f, 0.0f, 0.0f, 0.8f); + glBegin(GL_TRIANGLE_STRIP); + glVertex2i(menu->getX(), menu->getY() + menu->getH()); + glVertex2i(menu->getX(), menu->getY() + 9 * menu->getH() / 10); + glVertex2i(menu->getX() + menu->getW(), menu->getY() + menu->getH()); + glVertex2i(menu->getX() + menu->getW(), menu->getY() + 9 * menu->getH() / 10); + glEnd(); + + glBegin(GL_LINE_LOOP); + glColor4f(0.5f, 0.5f, 0.5f, 0.25f); + glVertex2i(menu->getX(), menu->getY()); + + glColor4f(0.0f, 0.0f, 0.0f, 0.25f); + glVertex2i(menu->getX() + menu->getW(), menu->getY()); + + glColor4f(0.5f, 0.5f, 0.5f, 0.25f); + glVertex2i(menu->getX() + menu->getW(), menu->getY() + menu->getH()); + + glColor4f(0.25f, 0.25f, 0.25f, 0.25f); + glVertex2i(menu->getX(), menu->getY() + menu->getH()); + glEnd(); + + glBegin(GL_LINE_STRIP); + glColor4f(1.0f, 1.0f, 1.0f, 0.25f); + glVertex2i(menu->getX(), menu->getY() + 90 * menu->getH() / 100); + + glColor4f(0.5f, 0.5f, 0.5f, 0.25f); + glVertex2i(menu->getX() + menu->getW(), menu->getY() + 90 * menu->getH() / 100); + glEnd(); + + glPopAttrib(); + + Vec4f fontColor; + //if(game!=NULL){ + // fontColor=game->getGui()->getDisplay()->getColor(); + //} + //else { + // white shadowed is default ( in the menu for example ) + fontColor = Vec4f(1.f, 1.f, 1.f, 1.0f); + //} + + if (renderText3DEnabled == true) { + //text + renderTextBoundingBox3D( + menu->getHeader(), menu->getFont3D(), fontColor, + menu->getX(), menu->getY() + 93 * menu->getH() / 100, menu->getW(), 0, + true, false, false, -1, -1); + + } else { + //text + int renderX = (menu->getX() + (menu->getW() / 2)); + //int renderY = (menu->getY() + (menu->getH() / 2)); + FontMetrics *fontMetrics = menu->getFont()->getMetrics(); + int renderY = menu->getY() + menu->getH() - fontMetrics->getHeight(menu->getHeader()); + renderTextShadow( + menu->getHeader(), menu->getFont(), fontColor, + renderX, renderY, + true); + + //renderText(button->getText(), button->getFont(), color,x + (w / 2), y + (h / 2), true); + } + + //buttons + // int maxButtonWidth = -1; + std::vector &menuItems = menu->getMenuItems(); + // for(unsigned int i = 0; i < menuItems.size(); ++i) { + // GraphicButton *button = &menuItems[i]; + // int currentButtonWidth = -1; + // if(renderText3DEnabled == true) { + // FontMetrics *fontMetrics= menu->getFont3D()->getMetrics(); + // currentButtonWidth = fontMetrics->getTextWidth(button->getText()); + // } + // else { + // FontMetrics *fontMetrics= menu->getFont()->getMetrics(); + // currentButtonWidth = fontMetrics->getTextWidth(button->getText()); + // } + // + // if(maxButtonWidth < 0 || currentButtonWidth > maxButtonWidth) { + // maxButtonWidth = currentButtonWidth + 5; + // } + // } + + for (unsigned int i = 0; i < menuItems.size(); ++i) { + GraphicButton *button = &menuItems[i]; + + //button->setW(maxButtonWidth); + renderButton(button); + } + + } + + void Renderer::setupRenderForVideo() { + clearBuffers(); + //3d + reset3dMenu(); + clearZBuffer(); + //2d + reset2d(); + glClearColor(0.f, 0.f, 0.f, 1.f); + } + + void Renderer::renderVideoLoading(int progressPercent) { + //printf("Rendering progress progressPercent = %d\n",progressPercent); + setupRenderForVideo(); + + Lang &lang = Lang::getInstance(); + string textToRender = lang.getString("PleaseWait"); + const Metrics &metrics = Metrics::getInstance(); + + static Chrono cycle(true); + static float anim = 0.0f; + + if (CoreData::getInstance().getMenuFontBig3D() != NULL) { + + int w = metrics.getVirtualW(); + int renderX = (w / 2) - (CoreData::getInstance().getMenuFontBig3D()->getMetrics()->getTextWidth(textToRender) / 2); + int h = metrics.getVirtualH(); + int renderY = (h / 2) + (CoreData::getInstance().getMenuFontBig3D()->getMetrics()->getHeight(textToRender) / 2); + + renderText3D( + textToRender, + CoreData::getInstance().getMenuFontBig3D(), + Vec4f(1.f, 1.f, 0.f, anim), + renderX, renderY, false); + } else { + renderText( + textToRender, + CoreData::getInstance().getMenuFontBig(), + Vec4f(1.f, 1.f, 0.f, anim), (metrics.getScreenW() / 2), + (metrics.getScreenH() / 2), true); + } + swapBuffers(); + + if (cycle.getCurMillis() % 50 == 0) { + static bool animCycleUp = true; + if (animCycleUp == true) { + anim += 0.1f; + if (anim > 1.f) { + anim = 1.f; + cycle.reset(); + animCycleUp = false; + } + } else { + anim -= 0.1f; + if (anim < 0.f) { + anim = 0.f; + cycle.reset(); + animCycleUp = true; + } + } + } + } + + } +}//end namespace diff --git a/source/glest_game/graphics/renderer.h b/source/glest_game/graphics/renderer.h index 3eea90fac..6a02cbccb 100644 --- a/source/glest_game/graphics/renderer.h +++ b/source/glest_game/graphics/renderer.h @@ -13,8 +13,8 @@ #define _GLEST_GAME_RENDERER_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include "vec.h" @@ -49,675 +49,723 @@ #include "leak_dumper.h" enum DebugUILevelType { - debugui_fps = 0x01, + debugui_fps = 0x01, debugui_unit_titles = 0x02 }; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -using namespace ::Shared::Graphics; -using namespace ::Shared::PlatformCommon; + using namespace ::Shared::Graphics; + using namespace ::Shared::PlatformCommon; -//non shared classes -class Config; -class Game; -class GameCamera; -class MainMenu; -class Console; -class MenuBackground; -class ChatManager; -class Object; -class ConsoleLineInfo; -class SurfaceCell; -class Program; -// ===================================================== -// class MeshCallbackTeamColor -// ===================================================== + //non shared classes + class Config; + class Game; + class GameCamera; + class MainMenu; + class Console; + class MenuBackground; + class ChatManager; + class Object; + class ConsoleLineInfo; + class SurfaceCell; + class Program; + // ===================================================== + // class MeshCallbackTeamColor + // ===================================================== -class MeshCallbackTeamColor: public MeshCallback { -private: - const Texture *teamTexture; + class MeshCallbackTeamColor : public MeshCallback { + private: + const Texture *teamTexture; -public: - MeshCallbackTeamColor() : MeshCallback() { - teamTexture = NULL; - } - void setTeamTexture(const Texture *teamTexture) {this->teamTexture= teamTexture;} - virtual void execute(const Mesh *mesh); + public: + MeshCallbackTeamColor() : MeshCallback() { + teamTexture = NULL; + } + void setTeamTexture(const Texture *teamTexture) { + this->teamTexture = teamTexture; + } + virtual void execute(const Mesh *mesh); - static bool noTeamColors; -}; + static bool noTeamColors; + }; -// =========================================================== -// class Renderer -// -/// OpenGL renderer, uses the shared library -// =========================================================== + // =========================================================== + // class Renderer + // + /// OpenGL renderer, uses the shared library + // =========================================================== -class VisibleQuadContainerCache { -protected: + class VisibleQuadContainerCache { + protected: - inline void CopyAll(const VisibleQuadContainerCache &obj) { - cacheFrame = obj.cacheFrame; - visibleObjectList = obj.visibleObjectList; - visibleUnitList = obj.visibleUnitList; - visibleQuadUnitList = obj.visibleQuadUnitList; - visibleQuadUnitBuildList = obj.visibleQuadUnitBuildList; - visibleScaledCellList = obj.visibleScaledCellList; - visibleScaledCellToScreenPosList = obj.visibleScaledCellToScreenPosList; - lastVisibleQuad = obj.lastVisibleQuad; - frustumData = obj.frustumData; - proj = obj.proj; - modl = obj.modl; - frustumDataCache = obj.frustumDataCache; - } - -public: - - inline VisibleQuadContainerCache() { - cacheFrame = 0; - clearFrustumData(); - clearCacheData(); - } - inline VisibleQuadContainerCache(const VisibleQuadContainerCache &obj) { - CopyAll(obj); - } - inline VisibleQuadContainerCache & operator=(const VisibleQuadContainerCache &obj) { - CopyAll(obj); - return *this; - } - - inline void clearCacheData() { - clearVolatileCacheData(); - clearNonVolatileCacheData(); - } - inline void clearVolatileCacheData() { - visibleUnitList.clear(); - visibleQuadUnitList.clear(); - visibleQuadUnitBuildList.clear(); - //inVisibleUnitList.clear(); - - visibleUnitList.reserve(500); - visibleQuadUnitList.reserve(500); - visibleQuadUnitBuildList.reserve(100); - } - inline void clearNonVolatileCacheData() { - visibleObjectList.clear(); - visibleScaledCellList.clear(); - visibleScaledCellToScreenPosList.clear(); - - visibleObjectList.reserve(500); - visibleScaledCellList.reserve(500); - } - inline void clearFrustumData() { - frustumData = vector >(6,vector(4,0)); - proj = vector(16,0); - modl = vector(16,0); - frustumDataCache.clear(); - } - int cacheFrame; - Quad2i lastVisibleQuad; - std::vector visibleObjectList; - std::vector visibleQuadUnitList; - std::vector visibleQuadUnitBuildList; - std::vector visibleUnitList; - std::vector visibleScaledCellList; - std::map visibleScaledCellToScreenPosList; - - static bool enableFrustumCalcs; - vector > frustumData; - vector proj; - vector modl; - map,vector >, vector > > frustumDataCache; - -}; - -class VisibleQuadContainerVBOCache { -public: - // Vertex Buffer Object Names - bool hasBuiltVBOs; - uint32 m_nVBOVertices; // Vertex VBO Name - uint32 m_nVBOFowTexCoords; // Texture Coordinate VBO Name for fog of war texture coords - uint32 m_nVBOSurfaceTexCoords; // Texture Coordinate VBO Name for surface texture coords - uint32 m_nVBONormals; // Normal VBO Name - //uint32 m_nVBOIndexes; // Indexes VBO Name -}; - -enum ConsoleMode { - consoleOff, - consoleNormal, - consoleFull, - consoleStoredOnly, - consoleStoredAndNormal, - - consoleCount -}; - -class Renderer : public RendererInterface, - public BaseRenderer, - // This is for screen saver thread - public SimpleTaskCallbackInterface, - public VideoLoadingCallbackInterface { -public: - //progress bar - static const int maxProgressBar; - static const Vec4f progressBarBack1; - static const Vec4f progressBarBack2; - static const Vec4f progressBarFront1; - static const Vec4f progressBarFront2; - - //sun and moon - static const float sunDist; - static const float moonDist; - static const float lightAmbFactor; - - //mouse - static const int maxMouse2dAnim; - - //texture units - static const GLenum baseTexUnit; - static const GLenum fowTexUnit; - static const GLenum shadowTexUnit; - - //selection - static const float selectionCircleRadius; - static const float magicCircleRadius; - - //perspective values - static const float perspFov; - static const float perspNearPlane; - static float perspFarPlane; - - //default values - static const float ambFactor; - static const Vec4f defSpecularColor; - static const Vec4f defDiffuseColor; - static const Vec4f defAmbientColor; - static const Vec4f defColor; - static const Vec4f fowColor; - - //light - static const float maxLightDist; - - static bool renderText3DEnabled; - -public: - enum Shadows { - sDisabled, - sProjected, - sShadowMapping, - - sCount - }; - -private: - - //config - int maxLights; - bool photoMode; - int shadowTextureSize; - int shadowFrameSkip; - float shadowIntensity; - bool focusArrows; - bool textures3D; - Shadows shadows; - int maxConsoleLines; - - //game - const Game *game; - GameCamera *gameCamera; - const MainMenu *menu; - Program *program; - - //misc - int triangleCount; - int pointCount; - Quad2i visibleQuad; - Quad2i visibleQuadFromCamera; - Vec4f nearestLightPos; - VisibleQuadContainerCache quadCache; - VisibleQuadContainerCache quadCacheSelection; - - //renderers - ModelRenderer *modelRenderer; - TextRenderer2D *textRenderer; - TextRenderer3D *textRenderer3D; - ParticleRenderer *particleRenderer; - - //texture managers - ModelManager *modelManager[rsCount]; - TextureManager *textureManager[rsCount]; - FontManager *fontManager[rsCount]; - ParticleManager *particleManager[rsCount]; - - //state lists - //GLuint list3d; - //bool list3dValid; - //GLuint list2d; - //bool list2dValid; - //GLuint list3dMenu; - //bool list3dMenuValid; - //GLuint *customlist3dMenu; - //const MainMenu *mm3d; - const MainMenu *custom_mm3d; - - //shadows - GLuint shadowMapHandle; - bool shadowMapHandleValid; - - Matrix4f shadowMapMatrix; - int shadowMapFrame; - - //water - float waterAnim; - - bool allowRenderUnitTitles; - //std::vector > renderUnitTitleList; - std::vector visibleFrameUnitList; - string visibleFrameUnitListCameraKey; - - bool no2DMouseRendering; - bool showDebugUI; - int showDebugUILevel; - - int lastRenderFps; - float smoothedRenderFps; - bool shadowsOffDueToMinRender; - - std::vector > deferredParticleSystems; - - SimpleTaskThread *saveScreenShotThread; - Mutex *saveScreenShotThreadAccessor; - std::list > saveScreenQueue; - - std::map worldToScreenPosCache; - - //bool masterserverMode; - - std::map mapSurfaceVBOCache; - - class SurfaceData { - public: - inline SurfaceData() { - uniqueId=0; - bufferCount=0; - textureHandle=0; - } - static uint32 nextUniqueId; - uint32 uniqueId; - int bufferCount; - int textureHandle; - vector texCoords; - vector texCoordsSurface; - vector vertices; - vector normals; - }; - - //VisibleQuadContainerVBOCache * GetSurfaceVBOs(SurfaceData *cellData); - void ReleaseSurfaceVBOs(); - std::map > > mapSurfaceData; - static bool rendererEnded; - - class MapRenderer { - public: - inline MapRenderer(): map(NULL) {} - inline ~MapRenderer() { destroy(); } - void render(const Map* map,float coordStep,VisibleQuadContainerCache &qCache); - void renderVisibleLayers(const Map* map,float coordStep,VisibleQuadContainerCache &qCache); - void destroy(); - private: - void load(float coordStep); - void loadVisibleLayers(float coordStep,VisibleQuadContainerCache &qCache); - - const Map* map; - struct Layer { - inline explicit Layer(int th): - vbo_vertices(0), vbo_normals(0), - vbo_fowTexCoords(0), vbo_surfTexCoords(0), - vbo_indices(0), indexCount(0), - textureHandle(th),textureCRC(0) {} - - inline explicit Layer(Layer &obj) { - *this = obj; + inline void CopyAll(const VisibleQuadContainerCache &obj) { + cacheFrame = obj.cacheFrame; + visibleObjectList = obj.visibleObjectList; + visibleUnitList = obj.visibleUnitList; + visibleQuadUnitList = obj.visibleQuadUnitList; + visibleQuadUnitBuildList = obj.visibleQuadUnitBuildList; + visibleScaledCellList = obj.visibleScaledCellList; + visibleScaledCellToScreenPosList = obj.visibleScaledCellToScreenPosList; + lastVisibleQuad = obj.lastVisibleQuad; + frustumData = obj.frustumData; + proj = obj.proj; + modl = obj.modl; + frustumDataCache = obj.frustumDataCache; } - inline Layer & operator=(Layer &obj) { - this->vertices = obj.vertices; - this->normals = obj.normals; - this->fowTexCoords = obj.fowTexCoords; - this->surfTexCoords = obj.surfTexCoords; - this->indices = obj.indices; - this->cellToIndicesMap = obj.cellToIndicesMap; - this->rowsToRenderCache = obj.rowsToRenderCache; - this->vbo_vertices = obj.vbo_vertices; - this->vbo_normals = obj.vbo_normals; - this->vbo_fowTexCoords = obj.vbo_fowTexCoords; - this->vbo_surfTexCoords = obj.vbo_surfTexCoords; - this->vbo_indices = obj.vbo_indices; - this->indexCount = obj.indexCount; - this->textureHandle = obj.textureHandle; - this->texturePath = obj.texturePath; - this->textureCRC = obj.textureCRC; + public: + inline VisibleQuadContainerCache() { + cacheFrame = 0; + clearFrustumData(); + clearCacheData(); + } + inline VisibleQuadContainerCache(const VisibleQuadContainerCache &obj) { + CopyAll(obj); + } + inline VisibleQuadContainerCache & operator=(const VisibleQuadContainerCache &obj) { + CopyAll(obj); return *this; } - ~Layer(); - void load_vbos(bool vboEnabled); - void render(VisibleQuadContainerCache &qCache); - void renderVisibleLayer(); + inline void clearCacheData() { + clearVolatileCacheData(); + clearNonVolatileCacheData(); + } + inline void clearVolatileCacheData() { + visibleUnitList.clear(); + visibleQuadUnitList.clear(); + visibleQuadUnitBuildList.clear(); + //inVisibleUnitList.clear(); - std::vector vertices, normals; - std::vector fowTexCoords, surfTexCoords; - std::vector indices; - std::map cellToIndicesMap; - std::map > > rowsToRenderCache; + visibleUnitList.reserve(500); + visibleQuadUnitList.reserve(500); + visibleQuadUnitBuildList.reserve(100); + } + inline void clearNonVolatileCacheData() { + visibleObjectList.clear(); + visibleScaledCellList.clear(); + visibleScaledCellToScreenPosList.clear(); + + visibleObjectList.reserve(500); + visibleScaledCellList.reserve(500); + } + inline void clearFrustumData() { + frustumData = vector >(6, vector(4, 0)); + proj = vector(16, 0); + modl = vector(16, 0); + frustumDataCache.clear(); + } + int cacheFrame; + Quad2i lastVisibleQuad; + std::vector visibleObjectList; + std::vector visibleQuadUnitList; + std::vector visibleQuadUnitBuildList; + std::vector visibleUnitList; + std::vector visibleScaledCellList; + std::map visibleScaledCellToScreenPosList; + + static bool enableFrustumCalcs; + vector > frustumData; + vector proj; + vector modl; + map, vector >, vector > > frustumDataCache; - GLuint vbo_vertices, vbo_normals, - vbo_fowTexCoords, vbo_surfTexCoords, - vbo_indices; - int indexCount; - int textureHandle; - string texturePath; - uint32 textureCRC; }; - typedef std::vector Layers; - Layers layers; - Quad2i lastVisibleQuad; - } mapRenderer; - bool ExtractFrustum(VisibleQuadContainerCache &quadCacheItem); - //bool PointInFrustum(vector > &frustum, float x, float y, float z ); - //bool SphereInFrustum(vector > &frustum, float x, float y, float z, float radius); - bool CubeInFrustum(vector > &frustum, float x, float y, float z, float size ); + class VisibleQuadContainerVBOCache { + public: + // Vertex Buffer Object Names + bool hasBuiltVBOs; + uint32 m_nVBOVertices; // Vertex VBO Name + uint32 m_nVBOFowTexCoords; // Texture Coordinate VBO Name for fog of war texture coords + uint32 m_nVBOSurfaceTexCoords; // Texture Coordinate VBO Name for surface texture coords + uint32 m_nVBONormals; // Normal VBO Name + //uint32 m_nVBOIndexes; // Indexes VBO Name + }; -private: - Renderer(); - ~Renderer(); + enum ConsoleMode { + consoleOff, + consoleNormal, + consoleFull, + consoleStoredOnly, + consoleStoredAndNormal, -public: - static Renderer &getInstance(); - static bool isEnded(); - //bool isMasterserverMode() const { return masterserverMode; } + consoleCount + }; - void addToDeferredParticleSystemList(std::pair deferredParticleSystem); - void manageDeferredParticleSystems(); + class Renderer : public RendererInterface, + public BaseRenderer, + // This is for screen saver thread + public SimpleTaskCallbackInterface, + public VideoLoadingCallbackInterface { + public: + //progress bar + static const int maxProgressBar; + static const Vec4f progressBarBack1; + static const Vec4f progressBarBack2; + static const Vec4f progressBarFront1; + static const Vec4f progressBarFront2; - void reinitAll(); + //sun and moon + static const float sunDist; + static const float moonDist; + static const float lightAmbFactor; - //init - void init(); - void initGame(const Game *game, GameCamera *gameCamera); - void initMenu(const MainMenu *mm); - void reset3d(); - void reset2d(); - void reset3dMenu(); + //mouse + static const int maxMouse2dAnim; - //end - void end(); - void endScenario(); - void endMenu(); - void endGame(bool isFinalEnd); + //texture units + static const GLenum baseTexUnit; + static const GLenum fowTexUnit; + static const GLenum shadowTexUnit; - //get - inline int getTriangleCount() const {return triangleCount;} - inline int getPointCount() const {return pointCount;} + //selection + static const float selectionCircleRadius; + static const float magicCircleRadius; - //misc - //void reloadResources(); + //perspective values + static const float perspFov; + static const float perspNearPlane; + static float perspFarPlane; - //engine interface - void initTexture(ResourceScope rs, Texture *texture); - void endTexture(ResourceScope rs, Texture *texture,bool mustExistInList=false); - void endLastTexture(ResourceScope rs, bool mustExistInList=false); + //default values + static const float ambFactor; + static const Vec4f defSpecularColor; + static const Vec4f defDiffuseColor; + static const Vec4f defAmbientColor; + static const Vec4f defColor; + static const Vec4f fowColor; - Model *newModel(ResourceScope rs,const string &path,bool deletePixMapAfterLoad=false,std::map > > *loadedFileList=NULL, string *sourceLoader=NULL); - void endModel(ResourceScope rs, Model *model, bool mustExistInList=false); - void endLastModel(ResourceScope rs, bool mustExistInList=false); + //light + static const float maxLightDist; - Texture2D *newTexture2D(ResourceScope rs); - Texture3D *newTexture3D(ResourceScope rs); - Font2D *newFont(ResourceScope rs); - Font3D *newFont3D(ResourceScope rs); - void endFont(::Shared::Graphics::Font *font, ResourceScope rs, bool mustExistInList=false); - //void resetFontManager(ResourceScope rs); + static bool renderText3DEnabled; - inline TextRenderer2D *getTextRenderer() const {return textRenderer;} - inline TextRenderer3D *getTextRenderer3D() const {return textRenderer3D;} + public: + enum Shadows { + sDisabled, + sProjected, + sShadowMapping, - void manageParticleSystem(ParticleSystem *particleSystem, ResourceScope rs); - void cleanupParticleSystems(vector &particleSystems,ResourceScope rs); - void cleanupUnitParticleSystems(vector &particleSystems,ResourceScope rs); - bool validateParticleSystemStillExists(ParticleSystem * particleSystem,ResourceScope rs) const; - void removeParticleSystemsForParticleOwner(ParticleOwner * particleOwner,ResourceScope rs); - void updateParticleManager(ResourceScope rs,int renderFps=-1); - void renderParticleManager(ResourceScope rs); - void swapBuffers(); + sCount + }; - //lights and camera - void setupLighting(); - //void setupLightingForRotatedModel(); - void loadGameCameraMatrix(); - void loadCameraMatrix(const Camera *camera); - void computeVisibleQuad(); + private: - //basic rendering - void renderMouse2d(int mouseX, int mouseY, int anim, float fade= 0.f); - void renderMouse3d(); + //config + int maxLights; + bool photoMode; + int shadowTextureSize; + int shadowFrameSkip; + float shadowIntensity; + bool focusArrows; + bool textures3D; + Shadows shadows; + int maxConsoleLines; - void renderGhostModel(const UnitType *building, const Vec2i pos,CardinalDir facing,Vec4f *forceColor=NULL); + //game + const Game *game; + GameCamera *gameCamera; + const MainMenu *menu; + Program *program; - void renderBackground(const Texture2D *texture); - void renderTextureQuad(int x, int y, int w, int h, const Texture2D *texture, float alpha=1.f,const Vec3f *color=NULL); - void renderConsole(const Console *console, ConsoleMode mode=consoleNormal, int overrideMaxConsoleLines=-1); - void renderConsoleLine3D(int lineIndex, int xPosition, int yPosition, int lineHeight, Font3D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo); - void renderConsoleLine(int lineIndex, int xPosition, int yPosition, int lineHeight, Font2D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo); + //misc + int triangleCount; + int pointCount; + Quad2i visibleQuad; + Quad2i visibleQuadFromCamera; + Vec4f nearestLightPos; + VisibleQuadContainerCache quadCache; + VisibleQuadContainerCache quadCacheSelection; - void renderChatManager(const ChatManager *chatManager); - void renderClock(); - void renderPerformanceStats(); - void renderResourceStatus(); - void renderSelectionQuad(); - void renderText(const string &text, Font2D *font, float alpha, int x, int y, bool centered= false); - void renderText(const string &text, Font2D *font, const Vec3f &color, int x, int y, bool centered= false); - void renderText(const string &text, Font2D *font, const Vec4f &color, int x, int y, bool centered=false); - void renderTextShadow(const string &text, Font2D *font,const Vec4f &color, int x, int y, bool centered= false); + //renderers + ModelRenderer *modelRenderer; + TextRenderer2D *textRenderer; + TextRenderer3D *textRenderer3D; + ParticleRenderer *particleRenderer; - void renderText3D(const string &text, Font3D *font, float alpha, int x, int y, bool centered); - void renderText3D(const string &text, Font3D *font, const Vec3f &color, int x, int y, bool centered); - void renderText3D(const string &text, Font3D *font, const Vec4f &color, int x, int y, bool centered); - void renderTextShadow3D(const string &text, Font3D *font,const Vec4f &color, int x, int y, bool centered=false); - void renderProgressBar3D(int size, int x, int y, Font3D *font, int customWidth=-1, string prefixLabel="", bool centeredText=true,int customHeight=-1); + //texture managers + ModelManager *modelManager[rsCount]; + TextureManager *textureManager[rsCount]; + FontManager *fontManager[rsCount]; + ParticleManager *particleManager[rsCount]; - Vec2f getCentered3DPos(const string &text, Font3D *font, Vec2f &pos, int w, int h, bool centeredW, bool centeredH); - void renderTextBoundingBox3D(const string &text, Font3D *font, const Vec4f &color, int x, int y, int w, int h, bool centeredW, bool centeredH, bool editModeEnabled, int maxEditWidth, int maxEditRenderWidth); - void renderTextBoundingBox3D(const string &text, Font3D *font, const Vec3f &color, int x, int y, int w, int h, bool centeredW, bool centeredH, bool editModeEnabled,int maxEditWidth, int maxEditRenderWidth); - void renderTextBoundingBox3D(const string &text, Font3D *font, float alpha, int x, int y, int w, int h, bool centeredW, bool centeredH, bool editModeEnabled,int maxEditWidth, int maxEditRenderWidth); + //state lists + //GLuint list3d; + //bool list3dValid; + //GLuint list2d; + //bool list2dValid; + //GLuint list3dMenu; + //bool list3dMenuValid; + //GLuint *customlist3dMenu; + //const MainMenu *mm3d; + const MainMenu *custom_mm3d; - void renderTextSurroundingBox(int x, int y, int w, int h,int maxEditWidth, int maxEditRenderWidth); + //shadows + GLuint shadowMapHandle; + bool shadowMapHandleValid; - void beginRenderToTexture(Texture2D **renderToTexture); - void endRenderToTexture(Texture2D **renderToTexture); + Matrix4f shadowMapMatrix; + int shadowMapFrame; - void renderFPSWhenEnabled(int lastFps); + //water + float waterAnim; - //components - void renderLabel(GraphicLabel *label); - void renderLabel(GraphicLabel *label,const Vec3f *color); - void renderLabel(GraphicLabel *label,const Vec4f *color); - void renderButton(GraphicButton *button,const Vec4f *fontColorOverride=NULL,bool *lightedOverride=NULL); - void renderCheckBox(const GraphicCheckBox *box); - void renderLine(const GraphicLine *line); - void renderScrollBar(const GraphicScrollBar *sb); - void renderListBox(GraphicListBox *listBox); - void renderMessageBox(GraphicMessageBox *listBox); - void renderPopupMenu(PopupMenu *menu); + bool allowRenderUnitTitles; + //std::vector > renderUnitTitleList; + std::vector visibleFrameUnitList; + string visibleFrameUnitListCameraKey; - //complex rendering - void renderSurface(const int renderFps); - void renderObjects(const int renderFps); + bool no2DMouseRendering; + bool showDebugUI; + int showDebugUILevel; - void renderWater(); - void renderUnits(bool airUnits, const int renderFps); - void renderUnitsToBuild(const int renderFps); + int lastRenderFps; + float smoothedRenderFps; + bool shadowsOffDueToMinRender; - void renderSelectionEffects(int healthbarMode); - void renderHealthBars(int healthbarMode); - void renderWaterEffects(); - void renderHud(); - void renderMinimap(); - void renderDisplay(); - void renderMenuBackground(const MenuBackground *menuBackground); - void renderMapPreview(const MapPreview *map, bool renderAll, int screenX, int screenY,Texture2D **renderToTexture=NULL); - void renderMenuBackground(Camera *camera, float fade, Model *mainModel, vector characterModels,const Vec3f characterPosition, float anim); + std::vector > deferredParticleSystems; - //computing - bool ccomputePosition(const Vec2i &screenPos, Vec2i &worldPos,bool exactCoords=false); - void computeSelected(Selection::UnitContainer &units, const Object *&obj, const bool withObjectSelection, const Vec2i &posDown, const Vec2i &posUp); - void selectUsingColorPicking(Selection::UnitContainer &units, const Object *&obj,const bool withObjectSelection,const Vec2i &posDown, const Vec2i &posUp); - void selectUsingSelectionBuffer(Selection::UnitContainer &units,const Object *&obj, const bool withObjectSelection,const Vec2i &posDown, const Vec2i &posUp); - void selectUsingFrustumSelection(Selection::UnitContainer &units,const Object *&obj, const bool withObjectSelection,const Vec2i &posDown, const Vec2i &posUp); + SimpleTaskThread *saveScreenShotThread; + Mutex *saveScreenShotThreadAccessor; + std::list > saveScreenQueue; + + std::map worldToScreenPosCache; + + //bool masterserverMode; + + std::map mapSurfaceVBOCache; + + class SurfaceData { + public: + inline SurfaceData() { + uniqueId = 0; + bufferCount = 0; + textureHandle = 0; + } + static uint32 nextUniqueId; + uint32 uniqueId; + int bufferCount; + int textureHandle; + vector texCoords; + vector texCoordsSurface; + vector vertices; + vector normals; + }; + + //VisibleQuadContainerVBOCache * GetSurfaceVBOs(SurfaceData *cellData); + void ReleaseSurfaceVBOs(); + std::map > > mapSurfaceData; + static bool rendererEnded; + + class MapRenderer { + public: + inline MapRenderer() : map(NULL) { + } + inline ~MapRenderer() { + destroy(); + } + void render(const Map* map, float coordStep, VisibleQuadContainerCache &qCache); + void renderVisibleLayers(const Map* map, float coordStep, VisibleQuadContainerCache &qCache); + void destroy(); + private: + void load(float coordStep); + void loadVisibleLayers(float coordStep, VisibleQuadContainerCache &qCache); + + const Map* map; + struct Layer { + inline explicit Layer(int th) : + vbo_vertices(0), vbo_normals(0), + vbo_fowTexCoords(0), vbo_surfTexCoords(0), + vbo_indices(0), indexCount(0), + textureHandle(th), textureCRC(0) { + } + + inline explicit Layer(Layer &obj) { + *this = obj; + } + + inline Layer & operator=(Layer &obj) { + this->vertices = obj.vertices; + this->normals = obj.normals; + this->fowTexCoords = obj.fowTexCoords; + this->surfTexCoords = obj.surfTexCoords; + this->indices = obj.indices; + this->cellToIndicesMap = obj.cellToIndicesMap; + this->rowsToRenderCache = obj.rowsToRenderCache; + this->vbo_vertices = obj.vbo_vertices; + this->vbo_normals = obj.vbo_normals; + this->vbo_fowTexCoords = obj.vbo_fowTexCoords; + this->vbo_surfTexCoords = obj.vbo_surfTexCoords; + this->vbo_indices = obj.vbo_indices; + this->indexCount = obj.indexCount; + this->textureHandle = obj.textureHandle; + this->texturePath = obj.texturePath; + this->textureCRC = obj.textureCRC; + + return *this; + } + + ~Layer(); + void load_vbos(bool vboEnabled); + void render(VisibleQuadContainerCache &qCache); + void renderVisibleLayer(); + + std::vector vertices, normals; + std::vector fowTexCoords, surfTexCoords; + std::vector indices; + std::map cellToIndicesMap; + std::map > > rowsToRenderCache; + + GLuint vbo_vertices, vbo_normals, + vbo_fowTexCoords, vbo_surfTexCoords, + vbo_indices; + int indexCount; + int textureHandle; + string texturePath; + uint32 textureCRC; + }; + typedef std::vector Layers; + Layers layers; + Quad2i lastVisibleQuad; + } mapRenderer; + + bool ExtractFrustum(VisibleQuadContainerCache &quadCacheItem); + //bool PointInFrustum(vector > &frustum, float x, float y, float z ); + //bool SphereInFrustum(vector > &frustum, float x, float y, float z, float radius); + bool CubeInFrustum(vector > &frustum, float x, float y, float z, float size); + + private: + Renderer(); + ~Renderer(); + + public: + static Renderer &getInstance(); + static bool isEnded(); + //bool isMasterserverMode() const { return masterserverMode; } + + void addToDeferredParticleSystemList(std::pair deferredParticleSystem); + void manageDeferredParticleSystems(); + + void reinitAll(); + + //init + void init(); + void initGame(const Game *game, GameCamera *gameCamera); + void initMenu(const MainMenu *mm); + void reset3d(); + void reset2d(); + void reset3dMenu(); + + //end + void end(); + void endScenario(); + void endMenu(); + void endGame(bool isFinalEnd); + + //get + inline int getTriangleCount() const { + return triangleCount; + } + inline int getPointCount() const { + return pointCount; + } + + //misc + //void reloadResources(); + + //engine interface + void initTexture(ResourceScope rs, Texture *texture); + void endTexture(ResourceScope rs, Texture *texture, bool mustExistInList = false); + void endLastTexture(ResourceScope rs, bool mustExistInList = false); + + Model *newModel(ResourceScope rs, const string &path, bool deletePixMapAfterLoad = false, std::map > > *loadedFileList = NULL, string *sourceLoader = NULL); + void endModel(ResourceScope rs, Model *model, bool mustExistInList = false); + void endLastModel(ResourceScope rs, bool mustExistInList = false); + + Texture2D *newTexture2D(ResourceScope rs); + Texture3D *newTexture3D(ResourceScope rs); + Font2D *newFont(ResourceScope rs); + Font3D *newFont3D(ResourceScope rs); + void endFont(::Shared::Graphics::Font *font, ResourceScope rs, bool mustExistInList = false); + //void resetFontManager(ResourceScope rs); + + inline TextRenderer2D *getTextRenderer() const { + return textRenderer; + } + inline TextRenderer3D *getTextRenderer3D() const { + return textRenderer3D; + } + + void manageParticleSystem(ParticleSystem *particleSystem, ResourceScope rs); + void cleanupParticleSystems(vector &particleSystems, ResourceScope rs); + void cleanupUnitParticleSystems(vector &particleSystems, ResourceScope rs); + bool validateParticleSystemStillExists(ParticleSystem * particleSystem, ResourceScope rs) const; + void removeParticleSystemsForParticleOwner(ParticleOwner * particleOwner, ResourceScope rs); + void updateParticleManager(ResourceScope rs, int renderFps = -1); + void renderParticleManager(ResourceScope rs); + void swapBuffers(); + + //lights and camera + void setupLighting(); + //void setupLightingForRotatedModel(); + void loadGameCameraMatrix(); + void loadCameraMatrix(const Camera *camera); + void computeVisibleQuad(); + + //basic rendering + void renderMouse2d(int mouseX, int mouseY, int anim, float fade = 0.f); + void renderMouse3d(); + + void renderGhostModel(const UnitType *building, const Vec2i pos, CardinalDir facing, Vec4f *forceColor = NULL); + + void renderBackground(const Texture2D *texture); + void renderTextureQuad(int x, int y, int w, int h, const Texture2D *texture, float alpha = 1.f, const Vec3f *color = NULL); + void renderConsole(const Console *console, ConsoleMode mode = consoleNormal, int overrideMaxConsoleLines = -1); + void renderConsoleLine3D(int lineIndex, int xPosition, int yPosition, int lineHeight, Font3D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo); + void renderConsoleLine(int lineIndex, int xPosition, int yPosition, int lineHeight, Font2D* font, string stringToHightlight, const ConsoleLineInfo *lineInfo); + + void renderChatManager(const ChatManager *chatManager); + void renderClock(); + void renderPerformanceStats(); + void renderResourceStatus(); + void renderSelectionQuad(); + void renderText(const string &text, Font2D *font, float alpha, int x, int y, bool centered = false); + void renderText(const string &text, Font2D *font, const Vec3f &color, int x, int y, bool centered = false); + void renderText(const string &text, Font2D *font, const Vec4f &color, int x, int y, bool centered = false); + void renderTextShadow(const string &text, Font2D *font, const Vec4f &color, int x, int y, bool centered = false); + + void renderText3D(const string &text, Font3D *font, float alpha, int x, int y, bool centered); + void renderText3D(const string &text, Font3D *font, const Vec3f &color, int x, int y, bool centered); + void renderText3D(const string &text, Font3D *font, const Vec4f &color, int x, int y, bool centered); + void renderTextShadow3D(const string &text, Font3D *font, const Vec4f &color, int x, int y, bool centered = false); + void renderProgressBar3D(int size, int x, int y, Font3D *font, int customWidth = -1, string prefixLabel = "", bool centeredText = true, int customHeight = -1); + + Vec2f getCentered3DPos(const string &text, Font3D *font, Vec2f &pos, int w, int h, bool centeredW, bool centeredH); + void renderTextBoundingBox3D(const string &text, Font3D *font, const Vec4f &color, int x, int y, int w, int h, bool centeredW, bool centeredH, bool editModeEnabled, int maxEditWidth, int maxEditRenderWidth); + void renderTextBoundingBox3D(const string &text, Font3D *font, const Vec3f &color, int x, int y, int w, int h, bool centeredW, bool centeredH, bool editModeEnabled, int maxEditWidth, int maxEditRenderWidth); + void renderTextBoundingBox3D(const string &text, Font3D *font, float alpha, int x, int y, int w, int h, bool centeredW, bool centeredH, bool editModeEnabled, int maxEditWidth, int maxEditRenderWidth); + + void renderTextSurroundingBox(int x, int y, int w, int h, int maxEditWidth, int maxEditRenderWidth); + + void beginRenderToTexture(Texture2D **renderToTexture); + void endRenderToTexture(Texture2D **renderToTexture); + + void renderFPSWhenEnabled(int lastFps); + + //components + void renderLabel(GraphicLabel *label); + void renderLabel(GraphicLabel *label, const Vec3f *color); + void renderLabel(GraphicLabel *label, const Vec4f *color); + void renderButton(GraphicButton *button, const Vec4f *fontColorOverride = NULL, bool *lightedOverride = NULL); + void renderCheckBox(const GraphicCheckBox *box); + void renderLine(const GraphicLine *line); + void renderScrollBar(const GraphicScrollBar *sb); + void renderListBox(GraphicListBox *listBox); + void renderMessageBox(GraphicMessageBox *listBox); + void renderPopupMenu(PopupMenu *menu); + + //complex rendering + void renderSurface(const int renderFps); + void renderObjects(const int renderFps); + + void renderWater(); + void renderUnits(bool airUnits, const int renderFps); + void renderUnitsToBuild(const int renderFps); + + void renderSelectionEffects(int healthbarMode); + void renderHealthBars(int healthbarMode); + void renderWaterEffects(); + void renderHud(); + void renderMinimap(); + void renderDisplay(); + void renderMenuBackground(const MenuBackground *menuBackground); + void renderMapPreview(const MapPreview *map, bool renderAll, int screenX, int screenY, Texture2D **renderToTexture = NULL); + void renderMenuBackground(Camera *camera, float fade, Model *mainModel, vector characterModels, const Vec3f characterPosition, float anim); + + //computing + bool ccomputePosition(const Vec2i &screenPos, Vec2i &worldPos, bool exactCoords = false); + void computeSelected(Selection::UnitContainer &units, const Object *&obj, const bool withObjectSelection, const Vec2i &posDown, const Vec2i &posUp); + void selectUsingColorPicking(Selection::UnitContainer &units, const Object *&obj, const bool withObjectSelection, const Vec2i &posDown, const Vec2i &posUp); + void selectUsingSelectionBuffer(Selection::UnitContainer &units, const Object *&obj, const bool withObjectSelection, const Vec2i &posDown, const Vec2i &posUp); + void selectUsingFrustumSelection(Selection::UnitContainer &units, const Object *&obj, const bool withObjectSelection, const Vec2i &posDown, const Vec2i &posUp); - //gl wrap - string getGlInfo(); - string getGlMoreInfo(); - void autoConfig(); + //gl wrap + string getGlInfo(); + string getGlMoreInfo(); + void autoConfig(); - //clear - void clearBuffers(); - void clearZBuffer(); + //clear + void clearBuffers(); + void clearZBuffer(); - //shadows - void renderShadowsToTexture(const int renderFps); + //shadows + void renderShadowsToTexture(const int renderFps); - //misc - void loadConfig(); - void saveScreen(const string &path,int w=0, int h=0); - inline Quad2i getVisibleQuad() const {return visibleQuad;} - inline Quad2i getVisibleQuadFromCamera() const {return visibleQuadFromCamera;} - void renderTeamColorPlane(); - void renderSpecialHighlightUnits(std::map unitHighlightList); - void renderTeamColorCircle(); - void renderMorphEffects(); + //misc + void loadConfig(); + void saveScreen(const string &path, int w = 0, int h = 0); + inline Quad2i getVisibleQuad() const { + return visibleQuad; + } + inline Quad2i getVisibleQuadFromCamera() const { + return visibleQuadFromCamera; + } + void renderTeamColorPlane(); + void renderSpecialHighlightUnits(std::map unitHighlightList); + void renderTeamColorCircle(); + void renderMorphEffects(); - //static - static Shadows strToShadows(const string &s); - static string shadowsToStr(Shadows shadows); + //static + static Shadows strToShadows(const string &s); + static string shadowsToStr(Shadows shadows); - inline const Game * getGame() { return game; } + inline const Game * getGame() { + return game; + } - void setAllowRenderUnitTitles(bool value); - inline bool getAllowRenderUnitTitles() { return allowRenderUnitTitles; } - void renderUnitTitles(Font2D *font, Vec3f color); - void renderUnitTitles3D(Font3D *font, Vec3f color); - Vec3f computeScreenPosition(const Vec3f &worldPos); + void setAllowRenderUnitTitles(bool value); + inline bool getAllowRenderUnitTitles() { + return allowRenderUnitTitles; + } + void renderUnitTitles(Font2D *font, Vec3f color); + void renderUnitTitles3D(Font3D *font, Vec3f color); + Vec3f computeScreenPosition(const Vec3f &worldPos); - void setPhotoMode(bool value) { photoMode = value; } + void setPhotoMode(bool value) { + photoMode = value; + } - inline bool getNo2DMouseRendering() const { return no2DMouseRendering; } - void setNo2DMouseRendering(bool value) { no2DMouseRendering = value; } + inline bool getNo2DMouseRendering() const { + return no2DMouseRendering; + } + void setNo2DMouseRendering(bool value) { + no2DMouseRendering = value; + } - inline bool getShowDebugUI() const { return showDebugUI; } - void setShowDebugUI(bool value) { showDebugUI = value; } + inline bool getShowDebugUI() const { + return showDebugUI; + } + void setShowDebugUI(bool value) { + showDebugUI = value; + } - inline int getShowDebugUILevel() const { return showDebugUILevel; } - void setShowDebugUILevel(int value) { showDebugUILevel=value; } - void cycleShowDebugUILevel(); + inline int getShowDebugUILevel() const { + return showDebugUILevel; + } + void setShowDebugUILevel(int value) { + showDebugUILevel = value; + } + void cycleShowDebugUILevel(); - void setLastRenderFps(int value); - inline int getLastRenderFps() const { return lastRenderFps;} + void setLastRenderFps(int value); + inline int getLastRenderFps() const { + return lastRenderFps; + } - VisibleQuadContainerCache & getQuadCache(bool updateOnDirtyFrame=true,bool forceNew=false); - std::pair posInCellQuadCache(Vec2i pos); - //Vec3f getMarkedCellScreenPosQuadCache(Vec2i pos); - void updateMarkedCellScreenPosQuadCache(Vec2i pos); - void forceQuadCacheUpdate(); - void renderVisibleMarkedCells(bool renderTextHint=false,int x=-1, int y=-1); - void renderMarkedCellsOnMinimap(); + VisibleQuadContainerCache & getQuadCache(bool updateOnDirtyFrame = true, bool forceNew = false); + std::pair posInCellQuadCache(Vec2i pos); + //Vec3f getMarkedCellScreenPosQuadCache(Vec2i pos); + void updateMarkedCellScreenPosQuadCache(Vec2i pos); + void forceQuadCacheUpdate(); + void renderVisibleMarkedCells(bool renderTextHint = false, int x = -1, int y = -1); + void renderMarkedCellsOnMinimap(); - void renderHighlightedCellsOnMinimap(); + void renderHighlightedCellsOnMinimap(); - void removeObjectFromQuadCache(const Object *o); - void removeUnitFromQuadCache(const Unit *unit); + void removeObjectFromQuadCache(const Object *o); + void removeUnitFromQuadCache(const Unit *unit); - std::size_t getCurrentPixelByteCount(ResourceScope rs=rsGame) const; - unsigned int getSaveScreenQueueSize(); + std::size_t getCurrentPixelByteCount(ResourceScope rs = rsGame) const; + unsigned int getSaveScreenQueueSize(); - //Texture2D *saveScreenToTexture(int x, int y, int width, int height); + //Texture2D *saveScreenToTexture(int x, int y, int width, int height); - void renderProgressBar(int size, int x, int y, Font2D *font,int customWidth=-1, string prefixLabel="", bool centeredText=true); + void renderProgressBar(int size, int x, int y, Font2D *font, int customWidth = -1, string prefixLabel = "", bool centeredText = true); - static Texture2D * findTexture(string logoFilename); - static Texture2D * preloadTexture(string logoFilename); - inline int getCachedSurfaceDataSize() const { return (int)mapSurfaceData.size(); } + static Texture2D * findTexture(string logoFilename); + static Texture2D * preloadTexture(string logoFilename); + inline int getCachedSurfaceDataSize() const { + return (int) mapSurfaceData.size(); + } - //void setCustom3dMenuList(GLuint *customlist3dMenu) { this->customlist3dMenu = customlist3dMenu; } - //inline GLuint * getCustom3dMenuList() const { return this->customlist3dMenu; } - void setCustom3dMenu(const MainMenu *mm) { this->custom_mm3d = mm; } - const MainMenu * getCustom3dMenu() { return this->custom_mm3d; } + //void setCustom3dMenuList(GLuint *customlist3dMenu) { this->customlist3dMenu = customlist3dMenu; } + //inline GLuint * getCustom3dMenuList() const { return this->customlist3dMenu; } + void setCustom3dMenu(const MainMenu *mm) { + this->custom_mm3d = mm; + } + const MainMenu * getCustom3dMenu() { + return this->custom_mm3d; + } - //void init3dListMenu(const MainMenu *mm); + //void init3dListMenu(const MainMenu *mm); - void setProgram(Program *program) { this->program = program; } + void setProgram(Program *program) { + this->program = program; + } - void setupRenderForVideo(); - virtual void renderVideoLoading(int progressPercent); + void setupRenderForVideo(); + virtual void renderVideoLoading(int progressPercent); + + private: + //private misc + float computeSunAngle(float time); + float computeMoonAngle(float time); + Vec4f computeSunPos(float time); + Vec4f computeMoonPos(float time); + inline Vec4f computeWaterColor(float waterLevel, float cellHeight) { + const float waterFactor = 1.5f; + return Vec4f(1.f, 1.f, 1.f, clamp((waterLevel - cellHeight) * waterFactor, 0.f, 1.f)); + } + void checkExtension(const string &extension, const string &msg); + + //selection render + vector renderObjectsFast(bool renderingShadows = false, bool resourceOnly = false, bool colorPickingSelection = false); + vector renderUnitsFast(bool renderingShadows = false, bool colorPickingSelection = false); + + //gl requirements + void checkGlCaps(); + void checkGlOptionalCaps(); + + //gl init + void init3dList(); + void init2dList(); + + //misc + void loadProjectionMatrix(); + void enableProjectiveTexturing(); + + //private aux drawing + void renderSelectionCircle(Vec3f v, int size, float radius, float thickness = 0.2f); + bool isHealthBarVisible(const Unit *unit, int healthbarMode); + void renderHealthBar(Vec3f v, Unit *unit, float height, bool lineBorder, const Texture2D *texture = NULL, const Texture2D *backgroundTexture = NULL); + void internalRenderHp(int numberOfBars, int barNumber, float hp, Vec3f posVector, float width, float singleHPheight, Vec3f rightVector, Vec3f upVector); + void renderTeamColorEffect(Vec3f &v, int heigth, int size, Vec3f color, const Texture2D *texture); + void renderArrow(const Vec3f &pos1, const Vec3f &pos2, const Vec3f &color, float width); + //void renderTile(const Vec2i &pos); + void renderQuad(int x, int y, int w, int h, const Texture2D *texture); + + void simpleTask(BaseThread *callingThread, void *userdata); + + //static + static Texture2D::Filter strToTextureFilter(const string &s); + void cleanupScreenshotThread(); + + void render2dMenuSetup(); + void render3dSetup(); + void render3dMenuSetup(const MainMenu *mm); + + int renderResource(const Faction *factionForResourceView, + bool localFactionResourcesOnly, bool twoResourceLines, const ResourceType *rt, + int startRow, int &resourceCountRendered); + + }; -private: - //private misc - float computeSunAngle(float time); - float computeMoonAngle(float time); - Vec4f computeSunPos(float time); - Vec4f computeMoonPos(float time); - inline Vec4f computeWaterColor(float waterLevel, float cellHeight) { - const float waterFactor= 1.5f; - return Vec4f(1.f, 1.f, 1.f, clamp((waterLevel-cellHeight) * waterFactor, 0.f, 1.f)); } - void checkExtension(const string &extension, const string &msg); - - //selection render - vector renderObjectsFast(bool renderingShadows = false, bool resourceOnly = false, bool colorPickingSelection = false); - vector renderUnitsFast(bool renderingShadows = false, bool colorPickingSelection = false); - - //gl requirements - void checkGlCaps(); - void checkGlOptionalCaps(); - - //gl init - void init3dList(); - void init2dList(); - - //misc - void loadProjectionMatrix(); - void enableProjectiveTexturing(); - - //private aux drawing - void renderSelectionCircle(Vec3f v, int size, float radius, float thickness=0.2f); - bool isHealthBarVisible(const Unit *unit,int healthbarMode); - void renderHealthBar(Vec3f v, Unit *unit, float height, bool lineBorder, const Texture2D *texture=NULL, const Texture2D *backgroundTexture=NULL); - void internalRenderHp(int numberOfBars, int barNumber, float hp, Vec3f posVector, float width, float singleHPheight, Vec3f rightVector, Vec3f upVector); - void renderTeamColorEffect(Vec3f &v, int heigth, int size, Vec3f color, const Texture2D *texture); - void renderArrow(const Vec3f &pos1, const Vec3f &pos2, const Vec3f &color, float width); - //void renderTile(const Vec2i &pos); - void renderQuad(int x, int y, int w, int h, const Texture2D *texture); - - void simpleTask(BaseThread *callingThread,void *userdata); - - //static - static Texture2D::Filter strToTextureFilter(const string &s); - void cleanupScreenshotThread(); - - void render2dMenuSetup(); - void render3dSetup(); - void render3dMenuSetup(const MainMenu *mm); - - int renderResource(const Faction *factionForResourceView, - bool localFactionResourcesOnly,bool twoResourceLines, const ResourceType *rt, - int startRow, int &resourceCountRendered); - -}; - -}} //end namespace +} //end namespace #endif diff --git a/source/glest_game/graphics/unit_particle_type.cpp b/source/glest_game/graphics/unit_particle_type.cpp index 0deeefd3f..08d39ff0b 100644 --- a/source/glest_game/graphics/unit_particle_type.cpp +++ b/source/glest_game/graphics/unit_particle_type.cpp @@ -25,360 +25,353 @@ using namespace Shared::Graphics; using namespace Shared::Util; using namespace Shared::PlatformCommon; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class UnitParticleSystemType -// ===================================================== -UnitParticleSystemType::UnitParticleSystemType() : ParticleSystemType() { - shape = UnitParticleSystem::sLinear; - angle = 0; - radius = 0; - minRadius = 0; - emissionRateFade = 0; - relative = false; - meshName = ""; - relativeDirection = false; - fixed = false; - staticParticleCount = 0; - isVisibleAtNight = true; - isVisibleAtDay = true; - isDaylightAffected = false; - radiusBasedStartenergy = false; - delay = 0; - lifetime = 0; - startTime = 0; - endTime = 1; -} - -void UnitParticleSystemType::load(const XmlNode *particleSystemNode, const string &dir, - RendererInterface *renderer, std::map > > &loadedFileList, - string parentLoader, string techtreePath) { - - ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList, - parentLoader,techtreePath); - - //shape - angle= 0.0f; - if(particleSystemNode->hasChild("shape")){ - const XmlNode *shapeNode= particleSystemNode->getChild("shape"); - shape= UnitParticleSystem::strToShape(shapeNode->getAttribute("value")->getRestrictedValue()); - if(shape == UnitParticleSystem::sConical){ - angle= shapeNode->getChild("angle")->getAttribute("value")->getFloatValue(); + // ===================================================== + // class UnitParticleSystemType + // ===================================================== + UnitParticleSystemType::UnitParticleSystemType() : ParticleSystemType() { + shape = UnitParticleSystem::sLinear; + angle = 0; + radius = 0; + minRadius = 0; + emissionRateFade = 0; + relative = false; + meshName = ""; + relativeDirection = false; + fixed = false; + staticParticleCount = 0; + isVisibleAtNight = true; + isVisibleAtDay = true; + isDaylightAffected = false; + radiusBasedStartenergy = false; + delay = 0; + lifetime = 0; + startTime = 0; + endTime = 1; } - } else { - shape = UnitParticleSystem::sLinear; - } - if(shape != UnitParticleSystem::sSpherical){ - //direction - const XmlNode *directionNode= particleSystemNode->getChild("direction"); - direction.x= directionNode->getAttribute("x")->getFloatValue(); - direction.y= directionNode->getAttribute("y")->getFloatValue(); - direction.z= directionNode->getAttribute("z")->getFloatValue(); - if((shape == UnitParticleSystem::sConical) && (0.0 == direction.length())) - throw megaglest_runtime_error("direction cannot be zero"); - // ought to warn about 0 directions generally - } - //emission rate fade - if(particleSystemNode->hasChild("emission-rate-fade")){ - const XmlNode *emissionRateFadeNode= particleSystemNode->getChild("emission-rate-fade"); - emissionRateFade= emissionRateFadeNode->getAttribute("value")->getFloatValue(); - } else { - emissionRateFade = 0; - } - - //radius - const XmlNode *radiusNode= particleSystemNode->getChild("radius"); - radius= radiusNode->getAttribute("value")->getFloatValue(); - - // min radius - if(particleSystemNode->hasChild("min-radius")){ - const XmlNode *minRadiusNode= particleSystemNode->getChild("min-radius"); - minRadius= minRadiusNode->getAttribute("value")->getFloatValue(); - if(minRadius > radius) - throw megaglest_runtime_error("min-radius cannot be bigger than radius"); - } else { - minRadius = 0; - } - if((minRadius == 0) && (shape == UnitParticleSystem::sConical)) { - minRadius = 0.001f; // fudge it so we aren't generating particles that are exactly centred - if(minRadius > radius) - radius = minRadius; - } + void UnitParticleSystemType::load(const XmlNode *particleSystemNode, const string &dir, + RendererInterface *renderer, std::map > > &loadedFileList, + string parentLoader, string techtreePath) { - //relative - const XmlNode *relativeNode= particleSystemNode->getChild("relative"); - relative= relativeNode->getAttribute("value")->getBoolValue(); - + ParticleSystemType::load(particleSystemNode, dir, renderer, loadedFileList, + parentLoader, techtreePath); - //meshName - if(particleSystemNode->hasChild("meshName")){ - const XmlNode *tmpNode= particleSystemNode->getChild("meshName"); - meshName= tmpNode->getAttribute("value")->getValue(); - } - else{ - meshName=""; - } - - //relativeDirection - if(particleSystemNode->hasChild("relativeDirection")){ - const XmlNode *relativeDirectionNode= particleSystemNode->getChild("relativeDirection"); - relativeDirection= relativeDirectionNode->getAttribute("value")->getBoolValue(); - } - else{ - relativeDirection=true; - } + //shape + angle = 0.0f; + if (particleSystemNode->hasChild("shape")) { + const XmlNode *shapeNode = particleSystemNode->getChild("shape"); + shape = UnitParticleSystem::strToShape(shapeNode->getAttribute("value")->getRestrictedValue()); + if (shape == UnitParticleSystem::sConical) { + angle = shapeNode->getChild("angle")->getAttribute("value")->getFloatValue(); + } + } else { + shape = UnitParticleSystem::sLinear; + } + if (shape != UnitParticleSystem::sSpherical) { + //direction + const XmlNode *directionNode = particleSystemNode->getChild("direction"); + direction.x = directionNode->getAttribute("x")->getFloatValue(); + direction.y = directionNode->getAttribute("y")->getFloatValue(); + direction.z = directionNode->getAttribute("z")->getFloatValue(); + if ((shape == UnitParticleSystem::sConical) && (0.0 == direction.length())) + throw megaglest_runtime_error("direction cannot be zero"); + // ought to warn about 0 directions generally + } - if(particleSystemNode->hasChild("static-particle-count")){ - //staticParticleCount - const XmlNode *staticParticleCountNode= particleSystemNode->getChild("static-particle-count"); - staticParticleCount= staticParticleCountNode->getAttribute("value")->getIntValue(); - } - else{ - staticParticleCount=0; - } - - //isVisibleAtNight - if(particleSystemNode->hasChild("isVisibleAtNight")){ - const XmlNode *isVisibleAtNightNode= particleSystemNode->getChild("isVisibleAtNight"); - isVisibleAtNight= isVisibleAtNightNode->getAttribute("value")->getBoolValue(); - } - else { - isVisibleAtNight=true; - } + //emission rate fade + if (particleSystemNode->hasChild("emission-rate-fade")) { + const XmlNode *emissionRateFadeNode = particleSystemNode->getChild("emission-rate-fade"); + emissionRateFade = emissionRateFadeNode->getAttribute("value")->getFloatValue(); + } else { + emissionRateFade = 0; + } - //isVisibleAtDay - if(particleSystemNode->hasChild("isVisibleAtDay")){ - const XmlNode *isVisibleAtDayNode= particleSystemNode->getChild("isVisibleAtDay"); - isVisibleAtDay= isVisibleAtDayNode->getAttribute("value")->getBoolValue(); - } - else { - isVisibleAtDay=true; - } + //radius + const XmlNode *radiusNode = particleSystemNode->getChild("radius"); + radius = radiusNode->getAttribute("value")->getFloatValue(); - //isDaylightAffected - if(particleSystemNode->hasChild("isDaylightAffected")){ - const XmlNode *node= particleSystemNode->getChild("isDaylightAffected"); - isDaylightAffected= node->getAttribute("value")->getBoolValue(); - } - else { - isDaylightAffected=false; - } + // min radius + if (particleSystemNode->hasChild("min-radius")) { + const XmlNode *minRadiusNode = particleSystemNode->getChild("min-radius"); + minRadius = minRadiusNode->getAttribute("value")->getFloatValue(); + if (minRadius > radius) + throw megaglest_runtime_error("min-radius cannot be bigger than radius"); + } else { + minRadius = 0; + } + if ((minRadius == 0) && (shape == UnitParticleSystem::sConical)) { + minRadius = 0.001f; // fudge it so we aren't generating particles that are exactly centred + if (minRadius > radius) + radius = minRadius; + } - //radiusBasedStartenergy - if(particleSystemNode->hasChild("radiusBasedStartenergy")){ - const XmlNode *isVisibleAtDayNode= particleSystemNode->getChild("radiusBasedStartenergy"); - radiusBasedStartenergy= isVisibleAtDayNode->getAttribute("value")->getBoolValue(); - } - else{ - radiusBasedStartenergy= true; - } + //relative + const XmlNode *relativeNode = particleSystemNode->getChild("relative"); + relative = relativeNode->getAttribute("value")->getBoolValue(); - //fixed - const XmlNode *fixedNode= particleSystemNode->getChild("fixed"); - fixed= fixedNode->getAttribute("value")->getBoolValue(); - // delay - if(particleSystemNode->hasChild("delay")) { - const XmlNode* delayNode = particleSystemNode->getChild("delay"); - const float delay_secs = delayNode->getAttribute("value")->getFloatValue(); - if(delay_secs < 0) - throw megaglest_runtime_error("particle effect delay cannot be negative"); - delay = (int)delay_secs * GameConstants::updateFps; - } else{ - delay= 0; - } + //meshName + if (particleSystemNode->hasChild("meshName")) { + const XmlNode *tmpNode = particleSystemNode->getChild("meshName"); + meshName = tmpNode->getAttribute("value")->getValue(); + } else { + meshName = ""; + } - // lifetime - if(particleSystemNode->hasChild("lifetime")) { - const XmlNode* lifetimeNode = particleSystemNode->getChild("lifetime"); - const float lifetime_secs = lifetimeNode->getAttribute("value")->getFloatValue(); - if(lifetime_secs < 0 && lifetime_secs != -1) - throw megaglest_runtime_error("particle effect lifetime cannot be negative (-1 means inherited from parent particle)"); - lifetime = (int)lifetime_secs * GameConstants::updateFps; - } else{ - lifetime= -1; //default - } -} + //relativeDirection + if (particleSystemNode->hasChild("relativeDirection")) { + const XmlNode *relativeDirectionNode = particleSystemNode->getChild("relativeDirection"); + relativeDirection = relativeDirectionNode->getAttribute("value")->getBoolValue(); + } else { + relativeDirection = true; + } -ObjectParticleSystemType::ObjectParticleSystemType() : UnitParticleSystemType() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s Line: %d] NEW [%p]\n",__FUNCTION__,__LINE__,this); -} -ObjectParticleSystemType::~ObjectParticleSystemType() { - if(SystemFlags::VERBOSE_MODE_ENABLED) { - printf("In [%s Line: %d] NEW [%p]\n",__FUNCTION__,__LINE__,this); - //printf("%s\n",PlatformExceptionHandler::getStackTrace().c_str()); - } -} + if (particleSystemNode->hasChild("static-particle-count")) { + //staticParticleCount + const XmlNode *staticParticleCountNode = particleSystemNode->getChild("static-particle-count"); + staticParticleCount = staticParticleCountNode->getAttribute("value")->getIntValue(); + } else { + staticParticleCount = 0; + } -const void UnitParticleSystemType::setValues(UnitParticleSystem *ups){ - // whilst we extend ParticleSystemType we don't use ParticleSystemType::setValues() - // add instances of all children; some settings will cascade to all children - for(Children::iterator i=children.begin(); i!=children.end(); ++i){ - UnitParticleSystem *child = new UnitParticleSystem(); - child->setParticleOwner(ups->getParticleOwner()); - child->setParticleType((*i)); - (*i)->setValues(child); - ups->addChild(child); - } - // set values - ups->setModel(model); - ups->setModelCycle(modelCycle); - ups->setTexture(texture); - ups->setPrimitive(UnitParticleSystem::strToPrimitive(primitive)); - ups->setOffset(offset); - ups->setShape(shape); - ups->setAngle(angle); - ups->setDirection(direction); - ups->setColor(color); - ups->setColorNoEnergy(colorNoEnergy); - ups->setSpeed(speed); - ups->setSpeedUpRelative(speedUpRelative); - ups->setSpeedUpConstant(speedUpConstant); - ups->setGravity(gravity); - ups->setParticleSize(size); - ups->setSizeNoEnergy(sizeNoEnergy); - ups->setEmissionRate(emissionRate); - ups->setMaxParticleEnergy(energyMax); - ups->setVarParticleEnergy(energyVar); - ups->setFixed(fixed); - ups->setRelative(relative); - ups->setMeshName(meshName); - ups->setRelativeDirection(relativeDirection); - ups->setDelay(delay); - ups->setLifetime(lifetime); - ups->setEmissionRateFade(emissionRateFade); - ups->setTeamcolorNoEnergy(teamcolorNoEnergy); - ups->setTeamcolorEnergy(teamcolorEnergy); - ups->setAlternations(alternations); - ups->setParticleSystemStartDelay(particleSystemStartDelay); + //isVisibleAtNight + if (particleSystemNode->hasChild("isVisibleAtNight")) { + const XmlNode *isVisibleAtNightNode = particleSystemNode->getChild("isVisibleAtNight"); + isVisibleAtNight = isVisibleAtNightNode->getAttribute("value")->getBoolValue(); + } else { + isVisibleAtNight = true; + } - ups->setIsVisibleAtNight(isVisibleAtNight); - ups->setIsVisibleAtDay(isVisibleAtDay); - ups->setIsDaylightAffected(isDaylightAffected); - ups->setStaticParticleCount(staticParticleCount); - ups->setRadius(radius); - ups->setMinRadius(minRadius); - ups->setBlendMode(ParticleSystem::strToBlendMode(mode)); - ups->setRadiusBasedStartenergy(radiusBasedStartenergy); - //prepare system for given staticParticleCount - if(staticParticleCount>0) - { - ups->setEmissionRate(0.0f); - ups->setSpeed(0); - direction.x= 0.0f; - direction.y= 0.0f; - direction.z= 0.0f; - ups->setDirection(direction); - } + //isVisibleAtDay + if (particleSystemNode->hasChild("isVisibleAtDay")) { + const XmlNode *isVisibleAtDayNode = particleSystemNode->getChild("isVisibleAtDay"); + isVisibleAtDay = isVisibleAtDayNode->getAttribute("value")->getBoolValue(); + } else { + isVisibleAtDay = true; + } - ups->setStartTime(startTime); - ups->setEndTime(endTime); -} + //isDaylightAffected + if (particleSystemNode->hasChild("isDaylightAffected")) { + const XmlNode *node = particleSystemNode->getChild("isDaylightAffected"); + isDaylightAffected = node->getAttribute("value")->getBoolValue(); + } else { + isDaylightAffected = false; + } -void UnitParticleSystemType::load(const XmlNode *particleFileNode, const string &dir, const string &path, - RendererInterface *renderer, std::map > > &loadedFileList, - string parentLoader, string techtreePath) { + //radiusBasedStartenergy + if (particleSystemNode->hasChild("radiusBasedStartenergy")) { + const XmlNode *isVisibleAtDayNode = particleSystemNode->getChild("radiusBasedStartenergy"); + radiusBasedStartenergy = isVisibleAtDayNode->getAttribute("value")->getBoolValue(); + } else { + radiusBasedStartenergy = true; + } - try{ - XmlTree xmlTree; + //fixed + const XmlNode *fixedNode = particleSystemNode->getChild("fixed"); + fixed = fixedNode->getAttribute("value")->getBoolValue(); - std::map mapExtraTagReplacementValues; - mapExtraTagReplacementValues["$COMMONDATAPATH"] = techtreePath + "/commondata/"; - xmlTree.load(path, Properties::getTagReplacementValues(&mapExtraTagReplacementValues)); - loadedFileList[path].push_back(make_pair(parentLoader,parentLoader)); - const XmlNode *particleSystemNode= xmlTree.getRootNode(); - - if(particleFileNode){ - // immediate children in the particleFileNode will override the particleSystemNode - particleFileNode->setSuper(particleSystemNode); - particleSystemNode= particleFileNode; + // delay + if (particleSystemNode->hasChild("delay")) { + const XmlNode* delayNode = particleSystemNode->getChild("delay"); + const float delay_secs = delayNode->getAttribute("value")->getFloatValue(); + if (delay_secs < 0) + throw megaglest_runtime_error("particle effect delay cannot be negative"); + delay = (int) delay_secs * GameConstants::updateFps; + } else { + delay = 0; + } + + // lifetime + if (particleSystemNode->hasChild("lifetime")) { + const XmlNode* lifetimeNode = particleSystemNode->getChild("lifetime"); + const float lifetime_secs = lifetimeNode->getAttribute("value")->getFloatValue(); + if (lifetime_secs < 0 && lifetime_secs != -1) + throw megaglest_runtime_error("particle effect lifetime cannot be negative (-1 means inherited from parent particle)"); + lifetime = (int) lifetime_secs * GameConstants::updateFps; + } else { + lifetime = -1; //default + } } - - UnitParticleSystemType::load(particleSystemNode, dir, renderer, - loadedFileList, parentLoader, techtreePath); + + ObjectParticleSystemType::ObjectParticleSystemType() : UnitParticleSystemType() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s Line: %d] NEW [%p]\n", __FUNCTION__, __LINE__, this); + } + ObjectParticleSystemType::~ObjectParticleSystemType() { + if (SystemFlags::VERBOSE_MODE_ENABLED) { + printf("In [%s Line: %d] NEW [%p]\n", __FUNCTION__, __LINE__, this); + //printf("%s\n",PlatformExceptionHandler::getStackTrace().c_str()); + } + } + + const void UnitParticleSystemType::setValues(UnitParticleSystem *ups) { + // whilst we extend ParticleSystemType we don't use ParticleSystemType::setValues() + // add instances of all children; some settings will cascade to all children + for (Children::iterator i = children.begin(); i != children.end(); ++i) { + UnitParticleSystem *child = new UnitParticleSystem(); + child->setParticleOwner(ups->getParticleOwner()); + child->setParticleType((*i)); + (*i)->setValues(child); + ups->addChild(child); + } + // set values + ups->setModel(model); + ups->setModelCycle(modelCycle); + ups->setTexture(texture); + ups->setPrimitive(UnitParticleSystem::strToPrimitive(primitive)); + ups->setOffset(offset); + ups->setShape(shape); + ups->setAngle(angle); + ups->setDirection(direction); + ups->setColor(color); + ups->setColorNoEnergy(colorNoEnergy); + ups->setSpeed(speed); + ups->setSpeedUpRelative(speedUpRelative); + ups->setSpeedUpConstant(speedUpConstant); + ups->setGravity(gravity); + ups->setParticleSize(size); + ups->setSizeNoEnergy(sizeNoEnergy); + ups->setEmissionRate(emissionRate); + ups->setMaxParticleEnergy(energyMax); + ups->setVarParticleEnergy(energyVar); + ups->setFixed(fixed); + ups->setRelative(relative); + ups->setMeshName(meshName); + ups->setRelativeDirection(relativeDirection); + ups->setDelay(delay); + ups->setLifetime(lifetime); + ups->setEmissionRateFade(emissionRateFade); + ups->setTeamcolorNoEnergy(teamcolorNoEnergy); + ups->setTeamcolorEnergy(teamcolorEnergy); + ups->setAlternations(alternations); + ups->setParticleSystemStartDelay(particleSystemStartDelay); + + ups->setIsVisibleAtNight(isVisibleAtNight); + ups->setIsVisibleAtDay(isVisibleAtDay); + ups->setIsDaylightAffected(isDaylightAffected); + ups->setStaticParticleCount(staticParticleCount); + ups->setRadius(radius); + ups->setMinRadius(minRadius); + ups->setBlendMode(ParticleSystem::strToBlendMode(mode)); + ups->setRadiusBasedStartenergy(radiusBasedStartenergy); + //prepare system for given staticParticleCount + if (staticParticleCount > 0) { + ups->setEmissionRate(0.0f); + ups->setSpeed(0); + direction.x = 0.0f; + direction.y = 0.0f; + direction.z = 0.0f; + ups->setDirection(direction); + } + + ups->setStartTime(startTime); + ups->setEndTime(endTime); + } + + void UnitParticleSystemType::load(const XmlNode *particleFileNode, const string &dir, const string &path, + RendererInterface *renderer, std::map > > &loadedFileList, + string parentLoader, string techtreePath) { + + try { + XmlTree xmlTree; + + std::map mapExtraTagReplacementValues; + mapExtraTagReplacementValues["$COMMONDATAPATH"] = techtreePath + "/commondata/"; + xmlTree.load(path, Properties::getTagReplacementValues(&mapExtraTagReplacementValues)); + loadedFileList[path].push_back(make_pair(parentLoader, parentLoader)); + const XmlNode *particleSystemNode = xmlTree.getRootNode(); + + if (particleFileNode) { + // immediate children in the particleFileNode will override the particleSystemNode + particleFileNode->setSuper(particleSystemNode); + particleSystemNode = particleFileNode; + } + + UnitParticleSystemType::load(particleSystemNode, dir, renderer, + loadedFileList, parentLoader, techtreePath); + } catch (const exception &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, e.what()); + throw megaglest_runtime_error("Error loading ParticleSystem: " + path + "\n" + e.what()); + } + } + + void UnitParticleSystemType::loadGame(const XmlNode *rootNode) { + ParticleSystemType::loadGame(rootNode); + + const XmlNode *unitParticleSystemTypeNode = rootNode->getChild("UnitParticleSystemType"); + + shape = static_cast(unitParticleSystemTypeNode->getAttribute("shape")->getIntValue()); + angle = unitParticleSystemTypeNode->getAttribute("angle")->getFloatValue(); + radius = unitParticleSystemTypeNode->getAttribute("radius")->getFloatValue(); + minRadius = unitParticleSystemTypeNode->getAttribute("minRadius")->getFloatValue(); + emissionRateFade = unitParticleSystemTypeNode->getAttribute("emissionRateFade")->getFloatValue(); + direction = Vec3f::strToVec3(unitParticleSystemTypeNode->getAttribute("direction")->getValue()); + relative = (unitParticleSystemTypeNode->getAttribute("relative")->getIntValue() != 0); + if (unitParticleSystemTypeNode->hasAttribute("meshName")) { + meshName = unitParticleSystemTypeNode->getAttribute("meshName")->getValue(); + } else { + meshName = ""; + } + relativeDirection = (unitParticleSystemTypeNode->getAttribute("relativeDirection")->getIntValue() != 0); + fixed = (unitParticleSystemTypeNode->getAttribute("fixed")->getIntValue() != 0); + staticParticleCount = unitParticleSystemTypeNode->getAttribute("staticParticleCount")->getIntValue(); + isVisibleAtNight = (unitParticleSystemTypeNode->getAttribute("isVisibleAtNight")->getIntValue() != 0); + isVisibleAtDay = (unitParticleSystemTypeNode->getAttribute("isVisibleAtDay")->getIntValue() != 0); + isDaylightAffected = (unitParticleSystemTypeNode->getAttribute("isDaylightAffected")->getIntValue() != 0); + radiusBasedStartenergy = (unitParticleSystemTypeNode->getAttribute("radiusBasedStartenergy")->getIntValue() != 0); + delay = unitParticleSystemTypeNode->getAttribute("delay")->getIntValue(); + lifetime = unitParticleSystemTypeNode->getAttribute("lifetime")->getIntValue(); + startTime = unitParticleSystemTypeNode->getAttribute("startTime")->getFloatValue(); + endTime = unitParticleSystemTypeNode->getAttribute("endTime")->getFloatValue(); + } + + void UnitParticleSystemType::saveGame(XmlNode *rootNode) { + ParticleSystemType::saveGame(rootNode); + + std::map mapTagReplacements; + XmlNode *unitParticleSystemTypeNode = rootNode->addChild("UnitParticleSystemType"); + + // UnitParticleSystem::Shape shape; + unitParticleSystemTypeNode->addAttribute("shape", intToStr(shape), mapTagReplacements); + // float angle; + unitParticleSystemTypeNode->addAttribute("angle", floatToStr(angle, 6), mapTagReplacements); + // float radius; + unitParticleSystemTypeNode->addAttribute("radius", floatToStr(radius, 6), mapTagReplacements); + // float minRadius; + unitParticleSystemTypeNode->addAttribute("minRadius", floatToStr(minRadius, 6), mapTagReplacements); + // float emissionRateFade; + unitParticleSystemTypeNode->addAttribute("emissionRateFade", floatToStr(emissionRateFade, 6), mapTagReplacements); + // Vec3f direction; + unitParticleSystemTypeNode->addAttribute("direction", direction.getString(), mapTagReplacements); + // bool relative; + unitParticleSystemTypeNode->addAttribute("relative", intToStr(relative), mapTagReplacements); + // string meshName; + unitParticleSystemTypeNode->addAttribute("meshName", meshName, mapTagReplacements); + // bool relativeDirection; + unitParticleSystemTypeNode->addAttribute("relativeDirection", intToStr(relativeDirection), mapTagReplacements); + // bool fixed; + unitParticleSystemTypeNode->addAttribute("fixed", intToStr(fixed), mapTagReplacements); + // int staticParticleCount; + unitParticleSystemTypeNode->addAttribute("staticParticleCount", intToStr(staticParticleCount), mapTagReplacements); + // bool isVisibleAtNight; + unitParticleSystemTypeNode->addAttribute("isVisibleAtNight", intToStr(isVisibleAtNight), mapTagReplacements); + // bool isVisibleAtDay; + unitParticleSystemTypeNode->addAttribute("isVisibleAtDay", intToStr(isVisibleAtDay), mapTagReplacements); + // bool isDaylightAffected; + unitParticleSystemTypeNode->addAttribute("isDaylightAffected", intToStr(isDaylightAffected), mapTagReplacements); + // bool radiusBasedStartenergy; + unitParticleSystemTypeNode->addAttribute("radiusBasedStartenergy", intToStr(radiusBasedStartenergy), mapTagReplacements); + // int delay; + unitParticleSystemTypeNode->addAttribute("delay", intToStr(delay), mapTagReplacements); + // int lifetime; + unitParticleSystemTypeNode->addAttribute("lifetime", intToStr(lifetime), mapTagReplacements); + // float startTime; + unitParticleSystemTypeNode->addAttribute("startTime", floatToStr(startTime, 6), mapTagReplacements); + // float endTime; + unitParticleSystemTypeNode->addAttribute("endTime", floatToStr(endTime, 6), mapTagReplacements); + } + } - catch(const exception &e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what()); - throw megaglest_runtime_error("Error loading ParticleSystem: "+ path + "\n" +e.what()); - } -} - -void UnitParticleSystemType::loadGame(const XmlNode *rootNode) { - ParticleSystemType::loadGame(rootNode); - - const XmlNode *unitParticleSystemTypeNode = rootNode->getChild("UnitParticleSystemType"); - - shape = static_cast(unitParticleSystemTypeNode->getAttribute("shape")->getIntValue()); - angle = unitParticleSystemTypeNode->getAttribute("angle")->getFloatValue(); - radius = unitParticleSystemTypeNode->getAttribute("radius")->getFloatValue(); - minRadius = unitParticleSystemTypeNode->getAttribute("minRadius")->getFloatValue(); - emissionRateFade = unitParticleSystemTypeNode->getAttribute("emissionRateFade")->getFloatValue(); - direction = Vec3f::strToVec3(unitParticleSystemTypeNode->getAttribute("direction")->getValue()); - relative = (unitParticleSystemTypeNode->getAttribute("relative")->getIntValue() != 0); - if(unitParticleSystemTypeNode->hasAttribute("meshName")){ - meshName = unitParticleSystemTypeNode->getAttribute("meshName")->getValue();} - else { - meshName = ""; - } - relativeDirection = (unitParticleSystemTypeNode->getAttribute("relativeDirection")->getIntValue() != 0); - fixed = (unitParticleSystemTypeNode->getAttribute("fixed")->getIntValue() != 0); - staticParticleCount = unitParticleSystemTypeNode->getAttribute("staticParticleCount")->getIntValue(); - isVisibleAtNight = (unitParticleSystemTypeNode->getAttribute("isVisibleAtNight")->getIntValue() != 0); - isVisibleAtDay = (unitParticleSystemTypeNode->getAttribute("isVisibleAtDay")->getIntValue() != 0); - isDaylightAffected = (unitParticleSystemTypeNode->getAttribute("isDaylightAffected")->getIntValue() != 0); - radiusBasedStartenergy = (unitParticleSystemTypeNode->getAttribute("radiusBasedStartenergy")->getIntValue() != 0); - delay = unitParticleSystemTypeNode->getAttribute("delay")->getIntValue(); - lifetime = unitParticleSystemTypeNode->getAttribute("lifetime")->getIntValue(); - startTime = unitParticleSystemTypeNode->getAttribute("startTime")->getFloatValue(); - endTime = unitParticleSystemTypeNode->getAttribute("endTime")->getFloatValue(); -} - -void UnitParticleSystemType::saveGame(XmlNode *rootNode) { - ParticleSystemType::saveGame(rootNode); - - std::map mapTagReplacements; - XmlNode *unitParticleSystemTypeNode = rootNode->addChild("UnitParticleSystemType"); - -// UnitParticleSystem::Shape shape; - unitParticleSystemTypeNode->addAttribute("shape",intToStr(shape), mapTagReplacements); -// float angle; - unitParticleSystemTypeNode->addAttribute("angle",floatToStr(angle,6), mapTagReplacements); -// float radius; - unitParticleSystemTypeNode->addAttribute("radius",floatToStr(radius,6), mapTagReplacements); -// float minRadius; - unitParticleSystemTypeNode->addAttribute("minRadius",floatToStr(minRadius,6), mapTagReplacements); -// float emissionRateFade; - unitParticleSystemTypeNode->addAttribute("emissionRateFade",floatToStr(emissionRateFade,6), mapTagReplacements); -// Vec3f direction; - unitParticleSystemTypeNode->addAttribute("direction",direction.getString(), mapTagReplacements); -// bool relative; - unitParticleSystemTypeNode->addAttribute("relative",intToStr(relative), mapTagReplacements); -// string meshName; - unitParticleSystemTypeNode->addAttribute("meshName",meshName, mapTagReplacements); -// bool relativeDirection; - unitParticleSystemTypeNode->addAttribute("relativeDirection",intToStr(relativeDirection), mapTagReplacements); -// bool fixed; - unitParticleSystemTypeNode->addAttribute("fixed",intToStr(fixed), mapTagReplacements); -// int staticParticleCount; - unitParticleSystemTypeNode->addAttribute("staticParticleCount",intToStr(staticParticleCount), mapTagReplacements); -// bool isVisibleAtNight; - unitParticleSystemTypeNode->addAttribute("isVisibleAtNight",intToStr(isVisibleAtNight), mapTagReplacements); -// bool isVisibleAtDay; - unitParticleSystemTypeNode->addAttribute("isVisibleAtDay",intToStr(isVisibleAtDay), mapTagReplacements); -// bool isDaylightAffected; - unitParticleSystemTypeNode->addAttribute("isDaylightAffected",intToStr(isDaylightAffected), mapTagReplacements); -// bool radiusBasedStartenergy; - unitParticleSystemTypeNode->addAttribute("radiusBasedStartenergy",intToStr(radiusBasedStartenergy), mapTagReplacements); -// int delay; - unitParticleSystemTypeNode->addAttribute("delay",intToStr(delay), mapTagReplacements); -// int lifetime; - unitParticleSystemTypeNode->addAttribute("lifetime",intToStr(lifetime), mapTagReplacements); -// float startTime; - unitParticleSystemTypeNode->addAttribute("startTime",floatToStr(startTime,6), mapTagReplacements); -// float endTime; - unitParticleSystemTypeNode->addAttribute("endTime",floatToStr(endTime,6), mapTagReplacements); -} - -}}//end mamespace +}//end mamespace diff --git a/source/glest_game/graphics/unit_particle_type.h b/source/glest_game/graphics/unit_particle_type.h index 159d96a87..2c5582e59 100644 --- a/source/glest_game/graphics/unit_particle_type.h +++ b/source/glest_game/graphics/unit_particle_type.h @@ -13,8 +13,8 @@ #define _GLEST_GAME_UNITPARTICLETYPE_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -32,74 +32,87 @@ using std::string; using namespace Shared::Graphics; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -using Shared::Graphics::ParticleManager; -using Shared::Graphics::ParticleSystem; -using Shared::Graphics::UnitParticleSystem; -using Shared::Graphics::Texture2D; -using Shared::Graphics::Vec3f; -using Shared::Graphics::Vec4f; -using Shared::Util::MultiFactory; -using Shared::Xml::XmlNode; + using Shared::Graphics::ParticleManager; + using Shared::Graphics::ParticleSystem; + using Shared::Graphics::UnitParticleSystem; + using Shared::Graphics::Texture2D; + using Shared::Graphics::Vec3f; + using Shared::Graphics::Vec4f; + using Shared::Util::MultiFactory; + using Shared::Xml::XmlNode; -// =========================================================== -// class ParticleSystemType -// -/// A type of particle system -// =========================================================== + // =========================================================== + // class ParticleSystemType + // + /// A type of particle system + // =========================================================== -class UnitParticleSystemType: public ParticleSystemType { -protected: - UnitParticleSystem::Shape shape; - float angle; - float radius; - float minRadius; - float emissionRateFade; - Vec3f direction; - bool relative; - string meshName; - bool relativeDirection; - bool fixed; - int staticParticleCount; - bool isVisibleAtNight; - bool isVisibleAtDay; - bool isDaylightAffected; - bool radiusBasedStartenergy; - int delay; - int lifetime; - float startTime; - float endTime; + class UnitParticleSystemType : public ParticleSystemType { + protected: + UnitParticleSystem::Shape shape; + float angle; + float radius; + float minRadius; + float emissionRateFade; + Vec3f direction; + bool relative; + string meshName; + bool relativeDirection; + bool fixed; + int staticParticleCount; + bool isVisibleAtNight; + bool isVisibleAtDay; + bool isDaylightAffected; + bool radiusBasedStartenergy; + int delay; + int lifetime; + float startTime; + float endTime; -public: - UnitParticleSystemType(); - virtual ~UnitParticleSystemType() {}; + public: + UnitParticleSystemType(); + virtual ~UnitParticleSystemType() { + }; - void load(const XmlNode *particleSystemNode, const string &dir, - RendererInterface *newTexture, std::map > > &loadedFileList, - string parentLoader, string techtreePath); - void load(const XmlNode *particleFileNode, const string &dir, const string &path, RendererInterface *newTexture, - std::map > > &loadedFileList,string parentLoader, - string techtreePath); + void load(const XmlNode *particleSystemNode, const string &dir, + RendererInterface *newTexture, std::map > > &loadedFileList, + string parentLoader, string techtreePath); + void load(const XmlNode *particleFileNode, const string &dir, const string &path, RendererInterface *newTexture, + std::map > > &loadedFileList, string parentLoader, + string techtreePath); - void setStartTime(float startTime) { this->startTime = startTime; } - float getStartTime() const { return this->startTime; } - void setEndTime(float endTime) { this->endTime = endTime; } - float getEndTime() const { return this->endTime; } + void setStartTime(float startTime) { + this->startTime = startTime; + } + float getStartTime() const { + return this->startTime; + } + void setEndTime(float endTime) { + this->endTime = endTime; + } + float getEndTime() const { + return this->endTime; + } - const void setValues (UnitParticleSystem *uts); - bool hasTexture() const { return(texture != NULL); } - virtual void saveGame(XmlNode *rootNode); - virtual void loadGame(const XmlNode *rootNode); -}; + const void setValues(UnitParticleSystem *uts); + bool hasTexture() const { + return(texture != NULL); + } + virtual void saveGame(XmlNode *rootNode); + virtual void loadGame(const XmlNode *rootNode); + }; -class ObjectParticleSystemType: public UnitParticleSystemType { -public: - ObjectParticleSystemType(); - virtual ~ObjectParticleSystemType(); -}; + class ObjectParticleSystemType : public UnitParticleSystemType { + public: + ObjectParticleSystemType(); + virtual ~ObjectParticleSystemType(); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/glest_game/gui/display.cpp b/source/glest_game/gui/display.cpp index e66fdf74c..0884534a0 100644 --- a/source/glest_game/gui/display.cpp +++ b/source/glest_game/gui/display.cpp @@ -19,166 +19,167 @@ using namespace Shared::Graphics; using namespace Shared::Util; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class Display -// ===================================================== + // ===================================================== + // class Display + // ===================================================== -Display::Display(){ - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + Display::Display() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - colors[0]= Vec4f(1.f, 1.f, 1.f, 0.0f); - colors[1]= Vec4f(1.f, 0.5f, 0.5f, 0.0f); - colors[2]= Vec4f(0.5f, 0.5f, 1.0f, 0.0f); - colors[3]= Vec4f(0.5f, 1.0f, 0.5f, 0.0f); - colors[4]= Vec4f(0.0f, 0.0f, 0.0f, 1.0f); - colors[5]= Vec4f(0.0f, 0.0f, 1.0f, 1.0f); - colors[6]= Vec4f(1.0f, 0.0f, 0.0f, 1.0f); - colors[7]= Vec4f(0.0f, 1.0f, 0.0f, 1.0f); - colors[8]= Vec4f(1.0f, 1.0f, 1.0f, 1.0f); + colors[0] = Vec4f(1.f, 1.f, 1.f, 0.0f); + colors[1] = Vec4f(1.f, 0.5f, 0.5f, 0.0f); + colors[2] = Vec4f(0.5f, 0.5f, 1.0f, 0.0f); + colors[3] = Vec4f(0.5f, 1.0f, 0.5f, 0.0f); + colors[4] = Vec4f(0.0f, 0.0f, 0.0f, 1.0f); + colors[5] = Vec4f(0.0f, 0.0f, 1.0f, 1.0f); + colors[6] = Vec4f(1.0f, 0.0f, 0.0f, 1.0f); + colors[7] = Vec4f(0.0f, 1.0f, 0.0f, 1.0f); + colors[8] = Vec4f(1.0f, 1.0f, 1.0f, 1.0f); - currentColor= 0; - clear(); + currentColor = 0; + clear(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void Display::calculateUpDimensions(int index) { - if(index>maxUpIndex){ - maxUpIndex=index; - if(maxUpIndex+1>upCellSideCount*upCellSideCount){ - upCellSideCount=upCellSideCount+1; - upImageSize = static_cast(imageSize) * static_cast(cellSideCount) / static_cast(upCellSideCount) + 0.9f; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); } + + void Display::calculateUpDimensions(int index) { + if (index > maxUpIndex) { + maxUpIndex = index; + if (maxUpIndex + 1 > upCellSideCount*upCellSideCount) { + upCellSideCount = upCellSideCount + 1; + upImageSize = static_cast(imageSize) * static_cast(cellSideCount) / static_cast(upCellSideCount) + 0.9f; + } + } + } + + Vec4f Display::getColor() const { + if (currentColor < 0 || currentColor >= colorCount) { + throw megaglest_runtime_error("currentColor >= colorCount"); + } + return colors[currentColor]; + } + + void Display::setUpImage(int i, const Texture2D *image) { + if (i >= upCellCount) throw megaglest_runtime_error("i>=upCellCount in Display::setUpImage"); + upImages[i] = image; + calculateUpDimensions(i); + } + + //misc + void Display::clear() { + downSelectedPos = invalidPos; + for (int i = 0; i < upCellCount; ++i) { + upImages[i] = NULL; + } + + for (int i = 0; i < downCellCount; ++i) { + downImages[i] = NULL; + downLighted[i] = true; + commandTypes[i] = NULL; + commandClasses[i] = ccNull; + } + + title.clear(); + text.clear(); + progressBar = -1; + + upCellSideCount = cellSideCount; + upImageSize = imageSize; + maxUpIndex = 0; + } + void Display::switchColor() { + currentColor = (currentColor + 1) % colorCount; + } + + int Display::computeDownIndex(int x, int y) const { + y = y - (downY - cellSideCount * imageSize); + + if (y > imageSize*cellSideCount || y < 0) { + return invalidPos; + } + + int cellX = x / imageSize; + int cellY = (y / imageSize) % cellSideCount; + int index = (cellSideCount - cellY - 1)*cellSideCount + cellX;; + + if (index < 0 || index >= downCellCount || downImages[index] == NULL) { + index = invalidPos; + } + + return index; + } + + int Display::computeDownX(int index) const { + return (index % cellSideCount) * imageSize; + } + + int Display::computeDownY(int index) const { + return Display::downY - (index / cellSideCount)*imageSize - imageSize; + } + + int Display::computeUpX(int index) const { + return (index % upCellSideCount) * upImageSize; + } + + int Display::computeUpY(int index) const { + return Metrics::getInstance().getDisplayH() - (index / upCellSideCount)*upImageSize - upImageSize; + } + + void Display::saveGame(XmlNode *rootNode) const { + std::map mapTagReplacements; + XmlNode *displayNode = rootNode->addChild("Display"); + + // string title; + displayNode->addAttribute("title", title, mapTagReplacements); + // string text; + displayNode->addAttribute("text", text, mapTagReplacements); + // string infoText; + displayNode->addAttribute("infoText", infoText, mapTagReplacements); + // const Texture2D *upImages[upCellCount]; + // const Texture2D *downImages[downCellCount]; + // bool downLighted[downCellCount]; + // const CommandType *commandTypes[downCellCount]; + // CommandClass commandClasses[downCellCount]; + // int progressBar; + displayNode->addAttribute("progressBar", intToStr(progressBar), mapTagReplacements); + // int downSelectedPos; + displayNode->addAttribute("downSelectedPos", intToStr(downSelectedPos), mapTagReplacements); + // Vec4f colors[colorCount]; + // int currentColor; + displayNode->addAttribute("currentColor", intToStr(currentColor), mapTagReplacements); + // int upCellSideCount; + // int upImageSize; + // int maxUpIndex; + } + + void Display::loadGame(const XmlNode *rootNode) { + const XmlNode *displayNode = rootNode->getChild("Display"); + + // string title; + title = displayNode->getAttribute("title")->getValue(); + // string text; + text = displayNode->getAttribute("text")->getValue(); + // string infoText; + infoText = displayNode->getAttribute("infoText")->getValue(); + // const Texture2D *upImages[upCellCount]; + // const Texture2D *downImages[downCellCount]; + // bool downLighted[downCellCount]; + // const CommandType *commandTypes[downCellCount]; + // CommandClass commandClasses[downCellCount]; + // int progressBar; + progressBar = displayNode->getAttribute("progressBar")->getIntValue(); + // int downSelectedPos; + //displayNode->addAttribute("downSelectedPos",intToStr(downSelectedPos), mapTagReplacements); + // Vec4f colors[colorCount]; + // int currentColor; + //currentColor = displayNode->getAttribute("progressBar")->getIntValue(); + // int upCellSideCount; + // int upImageSize; + // int maxUpIndex; + } + } -} - -Vec4f Display::getColor() const { - if(currentColor < 0 || currentColor >= colorCount) { - throw megaglest_runtime_error("currentColor >= colorCount"); - } - return colors[currentColor]; -} - -void Display::setUpImage(int i, const Texture2D *image) -{ - if(i>=upCellCount) throw megaglest_runtime_error("i>=upCellCount in Display::setUpImage"); - upImages[i]= image; - calculateUpDimensions(i); -} - -//misc -void Display::clear(){ - downSelectedPos= invalidPos; - for(int i=0; iimageSize*cellSideCount || y < 0){ - return invalidPos; - } - - int cellX= x/imageSize; - int cellY= (y/imageSize) % cellSideCount; - int index= (cellSideCount-cellY-1)*cellSideCount+cellX;; - - if(index<0 || index>=downCellCount || downImages[index]==NULL){ - index= invalidPos; - } - - return index; -} - -int Display::computeDownX(int index) const{ - return (index % cellSideCount) * imageSize; -} - -int Display::computeDownY(int index) const{ - return Display::downY - (index/cellSideCount)*imageSize - imageSize; -} - -int Display::computeUpX(int index) const{ - return (index % upCellSideCount) * upImageSize; -} - -int Display::computeUpY(int index) const{ - return Metrics::getInstance().getDisplayH() - (index/upCellSideCount)*upImageSize - upImageSize; -} - -void Display::saveGame(XmlNode *rootNode) const { - std::map mapTagReplacements; - XmlNode *displayNode = rootNode->addChild("Display"); - -// string title; - displayNode->addAttribute("title",title, mapTagReplacements); -// string text; - displayNode->addAttribute("text",text, mapTagReplacements); -// string infoText; - displayNode->addAttribute("infoText",infoText, mapTagReplacements); -// const Texture2D *upImages[upCellCount]; -// const Texture2D *downImages[downCellCount]; -// bool downLighted[downCellCount]; -// const CommandType *commandTypes[downCellCount]; -// CommandClass commandClasses[downCellCount]; -// int progressBar; - displayNode->addAttribute("progressBar",intToStr(progressBar), mapTagReplacements); -// int downSelectedPos; - displayNode->addAttribute("downSelectedPos",intToStr(downSelectedPos), mapTagReplacements); -// Vec4f colors[colorCount]; -// int currentColor; - displayNode->addAttribute("currentColor",intToStr(currentColor), mapTagReplacements); -// int upCellSideCount; -// int upImageSize; -// int maxUpIndex; -} - -void Display::loadGame(const XmlNode *rootNode) { - const XmlNode *displayNode = rootNode->getChild("Display"); - - // string title; - title = displayNode->getAttribute("title")->getValue(); - // string text; - text = displayNode->getAttribute("text")->getValue(); - // string infoText; - infoText = displayNode->getAttribute("infoText")->getValue(); - // const Texture2D *upImages[upCellCount]; - // const Texture2D *downImages[downCellCount]; - // bool downLighted[downCellCount]; - // const CommandType *commandTypes[downCellCount]; - // CommandClass commandClasses[downCellCount]; - // int progressBar; - progressBar = displayNode->getAttribute("progressBar")->getIntValue(); - // int downSelectedPos; - //displayNode->addAttribute("downSelectedPos",intToStr(downSelectedPos), mapTagReplacements); - // Vec4f colors[colorCount]; - // int currentColor; - //currentColor = displayNode->getAttribute("progressBar")->getIntValue(); - // int upCellSideCount; - // int upImageSize; - // int maxUpIndex; -} - -}}//end namespace +}//end namespace diff --git a/source/glest_game/gui/display.h b/source/glest_game/gui/display.h index 257eb5169..94393c5cc 100644 --- a/source/glest_game/gui/display.h +++ b/source/glest_game/gui/display.h @@ -13,8 +13,8 @@ #define _GLEST_GAME_DISPLAY_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -30,90 +30,134 @@ using Shared::Graphics::Texture2D; using Shared::Graphics::Vec4f; using Shared::Util::replaceBy; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class Display -// -/// Display for unit commands, and unit selection -// ===================================================== + // ===================================================== + // class Display + // + /// Display for unit commands, and unit selection + // ===================================================== -class Display{ -public: - static const int cellSideCount= 4; - static const int upCellCount= 36; - static const int downCellCount= cellSideCount*cellSideCount; - static const int colorCount= 9; - static const int imageSize= 32; - static const int invalidPos= -1; - static const int downY = imageSize*9; - static const int infoStringY= imageSize*4; + class Display { + public: + static const int cellSideCount = 4; + static const int upCellCount = 36; + static const int downCellCount = cellSideCount * cellSideCount; + static const int colorCount = 9; + static const int imageSize = 32; + static const int invalidPos = -1; + static const int downY = imageSize * 9; + static const int infoStringY = imageSize * 4; -private: - string title; - string text; - string infoText; - const Texture2D *upImages[upCellCount]; - const Texture2D *downImages[downCellCount]; - bool downLighted[downCellCount]; - const CommandType *commandTypes[downCellCount]; - CommandClass commandClasses[downCellCount]; - int progressBar; - int downSelectedPos; - Vec4f colors[colorCount]; - int currentColor; + private: + string title; + string text; + string infoText; + const Texture2D *upImages[upCellCount]; + const Texture2D *downImages[downCellCount]; + bool downLighted[downCellCount]; + const CommandType *commandTypes[downCellCount]; + CommandClass commandClasses[downCellCount]; + int progressBar; + int downSelectedPos; + Vec4f colors[colorCount]; + int currentColor; - int upCellSideCount; - int upImageSize; - int maxUpIndex; - + int upCellSideCount; + int upImageSize; + int maxUpIndex; -public: - Display(); - //get - string getTitle() const {return title;} - string getText() const {return text;} - string getInfoText() const {return infoText;} - const Texture2D *getUpImage(int index) const {return upImages[index];} - const Texture2D *getDownImage(int index) const {return downImages[index];} - bool getDownLighted(int index) const {return downLighted[index];} - const CommandType *getCommandType(int i) const {return commandTypes[i];} - CommandClass getCommandClass(int i) const {return commandClasses[i];} - Vec4f getColor() const; - int getProgressBar() const {return progressBar;} - int getDownSelectedPos() const {return downSelectedPos;} - int getUpCellSideCount() const {return upCellSideCount;} - int getUpImageSize() const {return upImageSize;} - - //set - void setTitle(const string title) {this->title= formatString(title);} - void setText(const string &text) {this->text= formatString(text);} - void setInfoText(const string infoText) {this->infoText= formatString(infoText);} - void setUpImage(int i, const Texture2D *image); - void setDownImage(int i, const Texture2D *image) {downImages[i]= image;} - void setCommandType(int i, const CommandType *ct) {commandTypes[i]= ct;} - void setCommandClass(int i, const CommandClass cc) {commandClasses[i]= cc;} - void setDownLighted(int i, bool lighted) {downLighted[i]= lighted;} - void setProgressBar(int i) {progressBar= i;} - void setDownSelectedPos(int i) {downSelectedPos= i;} - - //misc - void clear(); - void switchColor(); - int computeDownIndex(int x, int y) const; - int computeDownX(int index) const; - int computeDownY(int index) const; - int computeUpX(int index) const; - int computeUpY(int index) const; + public: + Display(); - void saveGame(XmlNode *rootNode) const; - void loadGame(const XmlNode *rootNode); + //get + string getTitle() const { + return title; + } + string getText() const { + return text; + } + string getInfoText() const { + return infoText; + } + const Texture2D *getUpImage(int index) const { + return upImages[index]; + } + const Texture2D *getDownImage(int index) const { + return downImages[index]; + } + bool getDownLighted(int index) const { + return downLighted[index]; + } + const CommandType *getCommandType(int i) const { + return commandTypes[i]; + } + CommandClass getCommandClass(int i) const { + return commandClasses[i]; + } + Vec4f getColor() const; + int getProgressBar() const { + return progressBar; + } + int getDownSelectedPos() const { + return downSelectedPos; + } + int getUpCellSideCount() const { + return upCellSideCount; + } + int getUpImageSize() const { + return upImageSize; + } -private: - void calculateUpDimensions(int index); -}; + //set + void setTitle(const string title) { + this->title = formatString(title); + } + void setText(const string &text) { + this->text = formatString(text); + } + void setInfoText(const string infoText) { + this->infoText = formatString(infoText); + } + void setUpImage(int i, const Texture2D *image); + void setDownImage(int i, const Texture2D *image) { + downImages[i] = image; + } + void setCommandType(int i, const CommandType *ct) { + commandTypes[i] = ct; + } + void setCommandClass(int i, const CommandClass cc) { + commandClasses[i] = cc; + } + void setDownLighted(int i, bool lighted) { + downLighted[i] = lighted; + } + void setProgressBar(int i) { + progressBar = i; + } + void setDownSelectedPos(int i) { + downSelectedPos = i; + } -}}//end namespace + //misc + void clear(); + void switchColor(); + int computeDownIndex(int x, int y) const; + int computeDownX(int index) const; + int computeDownY(int index) const; + int computeUpX(int index) const; + int computeUpY(int index) const; + + void saveGame(XmlNode *rootNode) const; + void loadGame(const XmlNode *rootNode); + + private: + void calculateUpDimensions(int index); + }; + + } +}//end namespace #endif diff --git a/source/glest_game/gui/gui.cpp b/source/glest_game/gui/gui.cpp index 60e390921..f91f292d2 100644 --- a/source/glest_game/gui/gui.cpp +++ b/source/glest_game/gui/gui.cpp @@ -35,1370 +35,1321 @@ using namespace Shared::Graphics; using namespace Shared::Util; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class Mouse3d -// ===================================================== + // ===================================================== + // class Mouse3d + // ===================================================== -const float Mouse3d::fadeSpeed= 1.f/50.f; + const float Mouse3d::fadeSpeed = 1.f / 50.f; -static const int queueCommandKey = vkShift; + static const int queueCommandKey = vkShift; -Mouse3d::Mouse3d(){ - enabled= false; - rot= 0; - fade= 0.f; -} - -void Mouse3d::enable(){ - enabled= true; - fade= 0.f; -} - -void Mouse3d::update(){ - if(enabled){ - rot= (rot + 3) % 360; - fade+= fadeSpeed; - if(fade>1.f) fade= 1.f; - } -} - -// =============================== -// class SelectionQuad -// =============================== - -SelectionQuad::SelectionQuad(){ - enabled= false; - posDown= Vec2i(0); - posUp= Vec2i(0); -} - -void SelectionQuad::setPosDown(const Vec2i &posDown){ - enabled= true; - this->posDown= posDown; - this->posUp= posDown; -} - -void SelectionQuad::setPosUp(const Vec2i &posUp){ - this->posUp= posUp; -} - -void SelectionQuad::disable(){ - enabled= false; -} - -// ===================================================== -// class Gui -// ===================================================== - -//constructor -Gui::Gui(){ - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] START\n",__FILE__,__FUNCTION__); - - lastGroupRecall = -1; - posObjWorld= Vec2i(54, 14); - validPosObjWorld= false; - activeCommandType= NULL; - activeCommandClass= ccStop; - selectingBuilding= false; - selectedBuildingFacing = CardinalDir(CardinalDir::NORTH); - selectingPos= false; - selectingMeetingPoint= false; - activePos= invalidPos; - lastPosDisplay= invalidPos; - lastQuadCalcFrame=0; - selectionCalculationFrameSkip=10; - minQuadSize=20; - selectedResourceObjectPos=Vec2i(-1,-1); - highlightedResourceObjectPos=Vec2i(-1,-1); - highlightedUnitId=-1; - hudTexture=NULL; - commander=NULL; - world=NULL; - game=NULL; - gameCamera=NULL; - console=NULL; - choosenBuildingType=NULL; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] END\n",__FILE__,__FUNCTION__); -} - -void Gui::init(Game *game) { - - this->commander = game->getCommander(); - this->gameCamera = game->getGameCameraPtr(); - this->console = game->getConsole(); - this->world = game->getWorld(); - this->game = game; - - selection.init(this, - world->getThisFactionIndex(), - world->getThisTeamIndex(), - game->isFlagType1BitEnabled(ft1_allow_shared_team_units)); -} - -void Gui::end(){ - selection.clear(); - if(hudTexture != NULL) { - Renderer::getInstance().endTexture(rsGlobal, hudTexture, false); - } - hudTexture = NULL; -} - -// ==================== get ==================== - -const UnitType *Gui::getBuilding() const{ - assert(selectingBuilding); - return choosenBuildingType; -} -const Object *Gui::getSelectedResourceObject() const{ - if(selectedResourceObjectPos.x==-1){ - return NULL; - } - else { - return world->getMap()->getSurfaceCell(selectedResourceObjectPos)->getObject(); - } -} -Object *Gui::getHighlightedResourceObject() const{ - if(highlightedResourceObjectPos.x==-1){ - return NULL; - } - else { - if(world == NULL) { - throw megaglest_runtime_error("world == NULL"); + Mouse3d::Mouse3d() { + enabled = false; + rot = 0; + fade = 0.f; } - if(world->getMap() == NULL) { - throw megaglest_runtime_error("world->getMap() == NULL"); + + void Mouse3d::enable() { + enabled = true; + fade = 0.f; } - if(world->getMap()->getSurfaceCell(highlightedResourceObjectPos) == NULL) { - throw megaglest_runtime_error("world->getMap()->getSurfaceCell(highlightedResourceObjectPos) == NULL"); - } - return world->getMap()->getSurfaceCell(highlightedResourceObjectPos)->getObject(); - } -} -Unit* Gui::getHighlightedUnit() const{ - if(highlightedUnitId==-1){ - return NULL; - } - else { - return world->findUnitById(highlightedUnitId); - } -} - -// ==================== is ==================== - -bool Gui::isPlacingBuilding() const{ - return isSelectingPos() && activeCommandType!=NULL && activeCommandType->getClass()==ccBuild; -} - -// ==================== set ==================== - -void Gui::invalidatePosObjWorld(){ - validPosObjWorld= false; -} - -// ==================== reset state ==================== - -void Gui::resetState(){ - selectingBuilding= false; - selectedBuildingFacing = CardinalDir(CardinalDir::NORTH); - selectingPos= false; - selectingMeetingPoint= false; - activePos= invalidPos; - activeCommandClass= ccStop; - activeCommandType= NULL; -} - -// ==================== events ==================== - -void Gui::update(){ - - if(selectionQuad.isEnabled() && selectionQuad.getPosUp().dist(selectionQuad.getPosDown())>minQuadSize){ - computeSelected(false,false); - } - mouse3d.update(); -} - -void Gui::tick(){ - computeDisplay(); -} - -//in display coords -bool Gui::mouseValid(int x, int y) { - return computePosDisplay(x, y) != invalidPos; -} - -void Gui::mouseDownLeftDisplay(int x, int y) { - if(selectingPos == false && - selectingMeetingPoint == false) { - - int posDisplay = computePosDisplay(x, y); - - if(posDisplay != invalidPos) { - if(selection.isCommandable()) { - - if(selectingBuilding) { - mouseDownDisplayUnitBuild(posDisplay); - } - else { - mouseDownDisplayUnitSkills(posDisplay); - } + void Mouse3d::update() { + if (enabled) { + rot = (rot + 3) % 360; + fade += fadeSpeed; + if (fade > 1.f) fade = 1.f; } - else { + } + + // =============================== + // class SelectionQuad + // =============================== + + SelectionQuad::SelectionQuad() { + enabled = false; + posDown = Vec2i(0); + posUp = Vec2i(0); + } + + void SelectionQuad::setPosDown(const Vec2i &posDown) { + enabled = true; + this->posDown = posDown; + this->posUp = posDown; + } + + void SelectionQuad::setPosUp(const Vec2i &posUp) { + this->posUp = posUp; + } + + void SelectionQuad::disable() { + enabled = false; + } + + // ===================================================== + // class Gui + // ===================================================== + + //constructor + Gui::Gui() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] START\n", __FILE__, __FUNCTION__); + + lastGroupRecall = -1; + posObjWorld = Vec2i(54, 14); + validPosObjWorld = false; + activeCommandType = NULL; + activeCommandClass = ccStop; + selectingBuilding = false; + selectedBuildingFacing = CardinalDir(CardinalDir::NORTH); + selectingPos = false; + selectingMeetingPoint = false; + activePos = invalidPos; + lastPosDisplay = invalidPos; + lastQuadCalcFrame = 0; + selectionCalculationFrameSkip = 10; + minQuadSize = 20; + selectedResourceObjectPos = Vec2i(-1, -1); + highlightedResourceObjectPos = Vec2i(-1, -1); + highlightedUnitId = -1; + hudTexture = NULL; + commander = NULL; + world = NULL; + game = NULL; + gameCamera = NULL; + console = NULL; + choosenBuildingType = NULL; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] END\n", __FILE__, __FUNCTION__); + } + + void Gui::init(Game *game) { + + this->commander = game->getCommander(); + this->gameCamera = game->getGameCameraPtr(); + this->console = game->getConsole(); + this->world = game->getWorld(); + this->game = game; + + selection.init(this, + world->getThisFactionIndex(), + world->getThisTeamIndex(), + game->isFlagType1BitEnabled(ft1_allow_shared_team_units)); + } + + void Gui::end() { + selection.clear(); + if (hudTexture != NULL) { + Renderer::getInstance().endTexture(rsGlobal, hudTexture, false); + } + hudTexture = NULL; + } + + // ==================== get ==================== + + const UnitType *Gui::getBuilding() const { + assert(selectingBuilding); + return choosenBuildingType; + } + const Object *Gui::getSelectedResourceObject() const { + if (selectedResourceObjectPos.x == -1) { + return NULL; + } else { + return world->getMap()->getSurfaceCell(selectedResourceObjectPos)->getObject(); + } + } + Object *Gui::getHighlightedResourceObject() const { + if (highlightedResourceObjectPos.x == -1) { + return NULL; + } else { + if (world == NULL) { + throw megaglest_runtime_error("world == NULL"); + } + if (world->getMap() == NULL) { + throw megaglest_runtime_error("world->getMap() == NULL"); + } + if (world->getMap()->getSurfaceCell(highlightedResourceObjectPos) == NULL) { + throw megaglest_runtime_error("world->getMap()->getSurfaceCell(highlightedResourceObjectPos) == NULL"); + } + return world->getMap()->getSurfaceCell(highlightedResourceObjectPos)->getObject(); + } + } + + Unit* Gui::getHighlightedUnit() const { + if (highlightedUnitId == -1) { + return NULL; + } else { + return world->findUnitById(highlightedUnitId); + } + } + + // ==================== is ==================== + + bool Gui::isPlacingBuilding() const { + return isSelectingPos() && activeCommandType != NULL && activeCommandType->getClass() == ccBuild; + } + + // ==================== set ==================== + + void Gui::invalidatePosObjWorld() { + validPosObjWorld = false; + } + + // ==================== reset state ==================== + + void Gui::resetState() { + selectingBuilding = false; + selectedBuildingFacing = CardinalDir(CardinalDir::NORTH); + selectingPos = false; + selectingMeetingPoint = false; + activePos = invalidPos; + activeCommandClass = ccStop; + activeCommandType = NULL; + } + + // ==================== events ==================== + + void Gui::update() { + + if (selectionQuad.isEnabled() && selectionQuad.getPosUp().dist(selectionQuad.getPosDown()) > minQuadSize) { + computeSelected(false, false); + } + mouse3d.update(); + } + + void Gui::tick() { + computeDisplay(); + } + + //in display coords + bool Gui::mouseValid(int x, int y) { + return computePosDisplay(x, y) != invalidPos; + } + + void Gui::mouseDownLeftDisplay(int x, int y) { + if (selectingPos == false && + selectingMeetingPoint == false) { + + int posDisplay = computePosDisplay(x, y); + + if (posDisplay != invalidPos) { + if (selection.isCommandable()) { + + if (selectingBuilding) { + mouseDownDisplayUnitBuild(posDisplay); + } else { + mouseDownDisplayUnitSkills(posDisplay); + } + } else { + resetState(); + } + } + computeDisplay(); + } + } + + void Gui::mouseMoveDisplay(int x, int y) { + computeInfoString(computePosDisplay(x, y)); + } + + void Gui::mouseMoveOutsideDisplay() { + computeInfoString(invalidPos); + } + + void Gui::mouseDownLeftGraphics(int x, int y, bool prepared) { + if (selectingPos) { + //give standard orders + Vec2i targetPos = game->getMouseCellPos(); + if (prepared || (game->isValidMouseCellPos() && + world->getMap()->isInsideSurface(world->getMap()->toSurfCoords(targetPos)) == true)) { + giveTwoClickOrders(x, y, prepared); + } resetState(); } - } - computeDisplay(); - } -} - -void Gui::mouseMoveDisplay(int x, int y) { - computeInfoString(computePosDisplay(x, y)); -} - -void Gui::mouseMoveOutsideDisplay() { - computeInfoString(invalidPos); -} - -void Gui::mouseDownLeftGraphics(int x, int y, bool prepared) { - if(selectingPos) { - //give standard orders - Vec2i targetPos=game->getMouseCellPos(); - if(prepared || (game->isValidMouseCellPos() && - world->getMap()->isInsideSurface(world->getMap()->toSurfCoords(targetPos)) == true)) { - giveTwoClickOrders(x, y, prepared); - } - resetState(); - } - //set meeting point - else if(selectingMeetingPoint) { - if(selection.isCommandable()) { - Vec2i targetPos=game->getMouseCellPos(); - if(prepared || (game->isValidMouseCellPos() && - world->getMap()->isInsideSurface(world->getMap()->toSurfCoords(targetPos)) == true)) { - commander->trySetMeetingPoint(selection.getFrontUnit(), targetPos); - } - } - resetState(); - } - else { - selectionQuad.setPosDown(Vec2i(x, y)); - computeSelected(false,false); - } - computeDisplay(); -} - -void Gui::mouseDownRightGraphics(int x, int y , bool prepared) { - if(selectingPos || selectingMeetingPoint) { - resetState(); - } - else if(selection.isCommandable()) { - if(prepared) { - //Vec2i targetPos=game->getMouseCellPos(); - givePreparedDefaultOrders(x, y); - } - else { - Vec2i targetPos=game->getMouseCellPos(); - if(game->isValidMouseCellPos() && - world->getMap()->isInsideSurface(world->getMap()->toSurfCoords(targetPos)) == true) { - giveDefaultOrders(x, y); - } - } - } - computeDisplay(); -} - -void Gui::mouseUpLeftGraphics(int x, int y) { - if(!selectingPos && !selectingMeetingPoint) { - if(selectionQuad.isEnabled()){ - selectionQuad.setPosUp(Vec2i(x, y)); - if(selectionQuad.getPosUp().dist(selectionQuad.getPosDown()) > minQuadSize) { - computeSelected(false,true); - } - if(selection.isCommandable() && random.randRange(0, 1)==0){ - SoundRenderer::getInstance().playFx( - selection.getFrontUnit()->getType()->getSelectionSound(), - selection.getFrontUnit()->getCurrMidHeightVector(), - gameCamera->getPos()); - } - selectionQuad.disable(); - } - } -} - -void Gui::mouseMoveGraphics(int x, int y) { - //compute selection - if(selectionQuad.isEnabled()){ - selectionQuad.setPosUp(Vec2i(x, y)); - computeSelected(false,false); - } - - //compute position for building - if(isPlacingBuilding()){ - posObjWorld=game->getMouseCellPos(); - validPosObjWorld= game->isValidMouseCellPos(); - } - - display.setInfoText(""); -} - -void Gui::mouseDoubleClickLeftGraphics(int x, int y){ - if(!selectingPos && !selectingMeetingPoint){ - selectionQuad.setPosDown(Vec2i(x, y)); - computeSelected(true,true); - computeDisplay(); - } -} - -void Gui::groupKey(int groupIndex) { - if(isKeyDown(vkControl)){ - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] groupIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,groupIndex); -// bool allAssigned=true; - bool clearGroup=!isKeyDown(vkShift); -// if(!clearGroup){ -// Unit* unit=selection.getFrontUnit(); -// if(unit!=null && unit->getType()->getMultiSelect()==false){ -// return; -// } -// } - bool allAssigned=selection.assignGroup(groupIndex,clearGroup); - if(!allAssigned){ - console->addStdMessage("GroupAssignFailed"); - } - } - else{ - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] groupIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,groupIndex); - - int recallGroupCenterCameraTimeout = Config::getInstance().getInt("RecallGroupCenterCameraTimeoutMilliseconds","1500"); - - if(lastGroupRecall == groupIndex && - lastGroupRecallTime.getMillis() > 0 && - lastGroupRecallTime.getMillis() <= recallGroupCenterCameraTimeout) { - - selection.recallGroup(groupIndex,!isKeyDown(vkShift)); - centerCameraOnSelection(); - } - else { - selection.recallGroup(groupIndex,!isKeyDown(vkShift)); - } - - lastGroupRecallTime.start(); - lastGroupRecall = groupIndex; - } -} - -void Gui::hotKey(SDL_KeyboardEvent key) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] key = [%c][%d]\n",__FILE__,__FUNCTION__,key,key); - - Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); - - //if(key == configKeys.getCharKey("HotKeyCenterCameraOnSelection")) { - if(isKeyPressed(configKeys.getSDLKey("HotKeyCenterCameraOnSelection"),key) == true) { - centerCameraOnSelection(); - } - //else if(key == configKeys.getCharKey("HotKeySelectIdleHarvesterUnit")) { - else if(isKeyPressed(configKeys.getSDLKey("HotKeySelectIdleHarvesterUnit"),key) == true) { - selectInterestingUnit(iutIdleHarvester); - } - //else if(key == configKeys.getCharKey("HotKeySelectBuiltBuilding")) { - else if(isKeyPressed(configKeys.getSDLKey("HotKeySelectBuiltBuilding"),key) == true) { - selectInterestingUnit(iutBuiltBuilding); - } - //else if(key == configKeys.getCharKey("HotKeyDumpWorldToLog")) { - else if(isKeyPressed(configKeys.getSDLKey("HotKeyDumpWorldToLog"),key) == true) { - std::string worldLog = world->DumpWorldToLog(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] worldLog dumped to [%s]\n",__FILE__,__FUNCTION__,__LINE__,worldLog.c_str()); - } - //else if(key == configKeys.getCharKey("HotKeyRotateUnitDuringPlacement")){ - else if(isKeyPressed(configKeys.getSDLKey("HotKeyRotateUnitDuringPlacement"),key) == true) { - // Here the user triggers a unit rotation while placing a unit - if(isPlacingBuilding()) { - if(getBuilding()->getRotationAllowed()){ - ++selectedBuildingFacing; - } - } - } - //else if(key == configKeys.getCharKey("HotKeySelectDamagedUnit")) { - else if(isKeyPressed(configKeys.getSDLKey("HotKeySelectDamagedUnit"),key) == true) { - selectInterestingUnit(iutDamaged); - } - //else if(key == configKeys.getCharKey("HotKeySelectStoreUnit")) { - else if(isKeyPressed(configKeys.getSDLKey("HotKeySelectStoreUnit"),key) == true) { - selectInterestingUnit(iutStore); - } - //else if(key == configKeys.getCharKey("HotKeySelectedUnitsAttack")) { - else if(isKeyPressed(configKeys.getSDLKey("HotKeySelectedUnitsAttack"),key) == true) { - clickCommonCommand(ccAttack); - } - //else if(key == configKeys.getCharKey("HotKeySelectedUnitsAttack")) { - else if(isKeyPressed(configKeys.getSDLKey("HotKeySelectedUnitsMove"),key) == true) { - clickCommonCommand(ccMove); - } - //else if(key == configKeys.getCharKey("HotKeySelectedUnitsStop")) { - else if(isKeyPressed(configKeys.getSDLKey("HotKeySelectedUnitsStop"),key) == true) { - clickCommonCommand(ccStop); - } -} - -void Gui::switchToNextDisplayColor(){ - display.switchColor(); -} - -void Gui::onSelectionChanged(){ - resetState(); - computeDisplay(); -} - -// ================= PRIVATE ================= - -void Gui::giveOneClickOrders(){ - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - std::pair result(crFailUndefined,""); - bool queueKeyDown = isKeyDown(queueCommandKey); - if(selection.isUniform()){ - result= commander->tryGiveCommand(&selection, activeCommandType, Vec2i(0), (Unit*)NULL, queueKeyDown); - } - else{ - result= commander->tryGiveCommand(&selection, activeCommandClass, Vec2i(0), (Unit*)NULL, queueKeyDown); - } - addOrdersResultToConsole(activeCommandClass, result); - activeCommandType= NULL; - activeCommandClass= ccStop; -} - -void Gui::giveDefaultOrders(int x, int y) { - //compute target - //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - const Unit *targetUnit= NULL; - Vec2i targetPos; - if(computeTarget(Vec2i(x, y), targetPos, targetUnit) == false) { - console->addStdMessage("InvalidPosition"); - return; - } - //printf("In [%s::%s Line: %d] targetUnit = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,targetUnit); - giveDefaultOrders(targetPos.x,targetPos.y,targetUnit,true); - //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void Gui::givePreparedDefaultOrders(int x, int y){ - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - giveDefaultOrders(x, y, NULL,false); -} - -void Gui::giveDefaultOrders(int x, int y,const Unit *targetUnit, bool paintMouse3d) { - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - bool queueKeyDown = isKeyDown(queueCommandKey); - Vec2i targetPos=Vec2i(x, y); - - //give order - //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - std::pair result= commander->tryGiveCommand(&selection, targetPos, targetUnit, queueKeyDown); - - //printf("In [%s::%s Line: %d] selected units = %d result.first = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,selection.getCount(),result.first); - - //graphical result - addOrdersResultToConsole(activeCommandClass, result); - if(result.first == crSuccess || result.first == crSomeFailed) { - if(paintMouse3d) - mouse3d.enable(); - - if(random.randRange(0, 1)==0){ - SoundRenderer::getInstance().playFx( - selection.getFrontUnit()->getType()->getCommandSound(), - selection.getFrontUnit()->getCurrMidHeightVector(), - gameCamera->getPos()); - } - } - - //reset - resetState(); -} - -void Gui::giveTwoClickOrders(int x, int y , bool prepared) { - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - std::pair result(crFailUndefined,""); - - //compute target - const Unit *targetUnit= NULL; - Vec2i targetPos; - if(prepared){ - targetPos=Vec2i(x, y); - } - else { - if(computeTarget(Vec2i(x, y), targetPos, targetUnit) == false) { - console->addStdMessage("InvalidPosition"); - return; - } - } - - bool queueKeyDown = isKeyDown(queueCommandKey); - //give orders to the units of this faction - if(selectingBuilding == false) { - if(selection.isUniform()) { - result= commander->tryGiveCommand(&selection, activeCommandType, - targetPos, targetUnit,queueKeyDown); - } - else { - result= commander->tryGiveCommand(&selection, activeCommandClass, - targetPos, targetUnit,queueKeyDown); - } - } - else { - //selecting building - result= commander->tryGiveCommand(&selection, - activeCommandType, posObjWorld, choosenBuildingType, - selectedBuildingFacing,queueKeyDown); - } - - //graphical result - addOrdersResultToConsole(activeCommandClass, result); - if(result.first == crSuccess || result.first == crSomeFailed) { - if(prepared == false) { - mouse3d.enable(); - } - - if(random.randRange(0, 1) == 0) { - SoundRenderer::getInstance().playFx( - selection.getFrontUnit()->getType()->getCommandSound(), - selection.getFrontUnit()->getCurrMidHeightVector(), - gameCamera->getPos()); - } - } -} - -void Gui::centerCameraOnSelection() { - if(selection.isEmpty() == false) { - Vec3f refPos= selection.getRefPos(); - gameCamera->centerXZ(refPos.x, refPos.z); - } -} - -void Gui::selectInterestingUnit(InterestingUnitType iut) { - const Faction *thisFaction = world->getThisFaction(); - const Unit* previousUnit = NULL; - bool previousFound = true; - - //start at the next harvester - if(selection.getCount() == 1) { - const Unit* refUnit= selection.getFrontUnit(); - - if(refUnit->isInteresting(iut)) { - previousUnit= refUnit; - previousFound= false; - } - } - - //clear selection - selection.clear(); - - //search - for(int index = 0; index < thisFaction->getUnitCount(); ++index){ - Unit* unit = thisFaction->getUnit(index); - - if(previousFound == true) { - if(unit->isInteresting(iut)) { - selection.select(unit,false); - break; - } - } - else{ - if(unit == previousUnit) { - previousFound = true; - } - } - } - - //search again if we have a previous - if(selection.isEmpty() && previousUnit != NULL && previousFound == true) { - for(int index = 0; index < thisFaction->getUnitCount(); ++index) { - Unit* unit = thisFaction->getUnit(index); - - if(unit->isInteresting(iut)) { - selection.select(unit,false); - break; - } - } - } -} - -void Gui::clickCommonCommand(CommandClass commandClass) { - for(int index = 0; index < Display::downCellCount; ++index) { - const CommandType *ct = display.getCommandType(index); - - if((ct != NULL && ct->getClass() == commandClass) || - display.getCommandClass(index) == commandClass) { - - mouseDownDisplayUnitSkills(index); - break; - } - } - computeDisplay(); -} - -void Gui::mouseDownDisplayUnitSkills(int posDisplay) { - if(selection.isEmpty() == false) { - if(posDisplay != cancelPos) { - if(posDisplay != meetingPointPos) { - const Unit *unit= selection.getFrontUnit(); - - //uniform selection - if(selection.isUniform()) { - const CommandType *ct = display.getCommandType(posDisplay); - - // try to switch to next attack type - if(activeCommandClass == ccAttack && activeCommandType!=NULL) { - - int maxI = unit->getType()->getCommandTypeCount(); - int cmdTypeId = activeCommandType->getId(); - int cmdTypeIdNext = cmdTypeId+1; - - while(cmdTypeIdNext != cmdTypeId) { - if(cmdTypeIdNext >= maxI) { - cmdTypeIdNext = 0; - } - const CommandType *ctype = display.getCommandType(cmdTypeIdNext); - if(ctype != NULL && ctype->getClass() == ccAttack) { - if(ctype != NULL && unit->getFaction()->reqsOk(ctype)) { - posDisplay=cmdTypeIdNext; - ct = display.getCommandType(posDisplay); - break; - } - } - cmdTypeIdNext++; - } - } - - if(ct != NULL && unit->getFaction()->reqsOk(ct)) { - activeCommandType= ct; - activeCommandClass= activeCommandType->getClass(); - } - else { - posDisplay= invalidPos; - activeCommandType= NULL; - activeCommandClass= ccStop; - return; + //set meeting point + else if (selectingMeetingPoint) { + if (selection.isCommandable()) { + Vec2i targetPos = game->getMouseCellPos(); + if (prepared || (game->isValidMouseCellPos() && + world->getMap()->isInsideSurface(world->getMap()->toSurfCoords(targetPos)) == true)) { + commander->trySetMeetingPoint(selection.getFrontUnit(), targetPos); } } + resetState(); + } else { + selectionQuad.setPosDown(Vec2i(x, y)); + computeSelected(false, false); + } + computeDisplay(); + } - //non uniform selection - else { - activeCommandType= NULL; - activeCommandClass= display.getCommandClass(posDisplay); - } - - //give orders depending on command type - if(!selection.isEmpty()){ - const CommandType *ct= selection.getUnit(0)->getType()->getFirstCtOfClass(activeCommandClass); - if(activeCommandType!=NULL && activeCommandType->getClass()==ccBuild){ - assert(selection.isUniform()); - selectingBuilding= true; - } - else if(ct->getClicks()==cOne){ - invalidatePosObjWorld(); - giveOneClickOrders(); - } - else{ - selectingPos= true; - activePos= posDisplay; + void Gui::mouseDownRightGraphics(int x, int y, bool prepared) { + if (selectingPos || selectingMeetingPoint) { + resetState(); + } else if (selection.isCommandable()) { + if (prepared) { + //Vec2i targetPos=game->getMouseCellPos(); + givePreparedDefaultOrders(x, y); + } else { + Vec2i targetPos = game->getMouseCellPos(); + if (game->isValidMouseCellPos() && + world->getMap()->isInsideSurface(world->getMap()->toSurfCoords(targetPos)) == true) { + giveDefaultOrders(x, y); } } } - else{ - activePos= posDisplay; - selectingMeetingPoint= true; + computeDisplay(); + } + + void Gui::mouseUpLeftGraphics(int x, int y) { + if (!selectingPos && !selectingMeetingPoint) { + if (selectionQuad.isEnabled()) { + selectionQuad.setPosUp(Vec2i(x, y)); + if (selectionQuad.getPosUp().dist(selectionQuad.getPosDown()) > minQuadSize) { + computeSelected(false, true); + } + if (selection.isCommandable() && random.randRange(0, 1) == 0) { + SoundRenderer::getInstance().playFx( + selection.getFrontUnit()->getType()->getSelectionSound(), + selection.getFrontUnit()->getCurrMidHeightVector(), + gameCamera->getPos()); + } + selectionQuad.disable(); + } } } - else{ - commander->tryCancelCommand(&selection); + + void Gui::mouseMoveGraphics(int x, int y) { + //compute selection + if (selectionQuad.isEnabled()) { + selectionQuad.setPosUp(Vec2i(x, y)); + computeSelected(false, false); + } + + //compute position for building + if (isPlacingBuilding()) { + posObjWorld = game->getMouseCellPos(); + validPosObjWorld = game->isValidMouseCellPos(); + } + + display.setInfoText(""); } - } -} -void Gui::mouseDownDisplayUnitBuild(int posDisplay) { - //int factionIndex = world->getThisFactionIndex(); + void Gui::mouseDoubleClickLeftGraphics(int x, int y) { + if (!selectingPos && !selectingMeetingPoint) { + selectionQuad.setPosDown(Vec2i(x, y)); + computeSelected(true, true); + computeDisplay(); + } + } - if(posDisplay == cancelPos) { - resetState(); - } - else { - if(activeCommandType != NULL && - activeCommandType->getClass() == ccBuild) { + void Gui::groupKey(int groupIndex) { + if (isKeyDown(vkControl)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] groupIndex = %d\n", __FILE__, __FUNCTION__, __LINE__, groupIndex); + // bool allAssigned=true; + bool clearGroup = !isKeyDown(vkShift); + // if(!clearGroup){ + // Unit* unit=selection.getFrontUnit(); + // if(unit!=null && unit->getType()->getMultiSelect()==false){ + // return; + // } + // } + bool allAssigned = selection.assignGroup(groupIndex, clearGroup); + if (!allAssigned) { + console->addStdMessage("GroupAssignFailed"); + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] groupIndex = %d\n", __FILE__, __FUNCTION__, __LINE__, groupIndex); - const BuildCommandType *bct = dynamic_cast(activeCommandType); - if(bct != NULL) { - const UnitType *ut = bct->getBuilding(posDisplay); + int recallGroupCenterCameraTimeout = Config::getInstance().getInt("RecallGroupCenterCameraTimeoutMilliseconds", "1500"); - const Unit *unit = selection.getFrontUnit(); - if(unit != NULL && unit->getFaction() != NULL) { + if (lastGroupRecall == groupIndex && + lastGroupRecallTime.getMillis() > 0 && + lastGroupRecallTime.getMillis() <= recallGroupCenterCameraTimeout) { - if(selection.canSelectUnitFactionCheck(unit) == true && - unit->getFaction()->reqsOk(ut)) { + selection.recallGroup(groupIndex, !isKeyDown(vkShift)); + centerCameraOnSelection(); + } else { + selection.recallGroup(groupIndex, !isKeyDown(vkShift)); + } - choosenBuildingType = ut; - selectingPos = true; - selectedBuildingFacing = CardinalDir(CardinalDir::NORTH); - activePos = posDisplay; + lastGroupRecallTime.start(); + lastGroupRecall = groupIndex; + } + } + + void Gui::hotKey(SDL_KeyboardEvent key) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] key = [%c][%d]\n", __FILE__, __FUNCTION__, key, key); + + Config &configKeys = Config::getInstance(std::pair(cfgMainKeys, cfgUserKeys)); + + //if(key == configKeys.getCharKey("HotKeyCenterCameraOnSelection")) { + if (isKeyPressed(configKeys.getSDLKey("HotKeyCenterCameraOnSelection"), key) == true) { + centerCameraOnSelection(); + } + //else if(key == configKeys.getCharKey("HotKeySelectIdleHarvesterUnit")) { + else if (isKeyPressed(configKeys.getSDLKey("HotKeySelectIdleHarvesterUnit"), key) == true) { + selectInterestingUnit(iutIdleHarvester); + } + //else if(key == configKeys.getCharKey("HotKeySelectBuiltBuilding")) { + else if (isKeyPressed(configKeys.getSDLKey("HotKeySelectBuiltBuilding"), key) == true) { + selectInterestingUnit(iutBuiltBuilding); + } + //else if(key == configKeys.getCharKey("HotKeyDumpWorldToLog")) { + else if (isKeyPressed(configKeys.getSDLKey("HotKeyDumpWorldToLog"), key) == true) { + std::string worldLog = world->DumpWorldToLog(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] worldLog dumped to [%s]\n", __FILE__, __FUNCTION__, __LINE__, worldLog.c_str()); + } + //else if(key == configKeys.getCharKey("HotKeyRotateUnitDuringPlacement")){ + else if (isKeyPressed(configKeys.getSDLKey("HotKeyRotateUnitDuringPlacement"), key) == true) { + // Here the user triggers a unit rotation while placing a unit + if (isPlacingBuilding()) { + if (getBuilding()->getRotationAllowed()) { + ++selectedBuildingFacing; } } } - } - } -} - - -string Gui::computeDefaultInfoString() { - string result=""; - - if(selection.isUniform()) { - if(selection.isObserver() || selection.isCommandable()) { - // default is the description extension - result = selection.getFrontUnit()->getDescExtension(game->showTranslatedTechTree()); - } - } - return result; -} - - -void Gui::computeInfoString(int posDisplay){ - - Lang &lang= Lang::getInstance(); - - lastPosDisplay = posDisplay; - - display.setInfoText(computeDefaultInfoString()); - - if(posDisplay!=invalidPos && selection.isCommandable()){ - if(!selectingBuilding){ - if(posDisplay==cancelPos){ - display.setInfoText(lang.getString("Cancel")); + //else if(key == configKeys.getCharKey("HotKeySelectDamagedUnit")) { + else if (isKeyPressed(configKeys.getSDLKey("HotKeySelectDamagedUnit"), key) == true) { + selectInterestingUnit(iutDamaged); } - else if(posDisplay==meetingPointPos){ - display.setInfoText(lang.getString("MeetingPoint")); + //else if(key == configKeys.getCharKey("HotKeySelectStoreUnit")) { + else if (isKeyPressed(configKeys.getSDLKey("HotKeySelectStoreUnit"), key) == true) { + selectInterestingUnit(iutStore); } - else{ - //uniform selection - if(selection.isUniform()){ - const Unit *unit= selection.getFrontUnit(); - const CommandType *ct= display.getCommandType(posDisplay); - - if(ct!=NULL){ - if(unit->getFaction()->reqsOk(ct)){ - display.setInfoText(ct->getDesc(unit->getTotalUpgrade(),game->showTranslatedTechTree())); - } - else{ - display.setInfoText(ct->getReqDesc(game->showTranslatedTechTree())); - if(ct->getClass()==ccUpgrade){ - string text=""; - const UpgradeCommandType *uct= static_cast(ct); - if(unit->getFaction()->getUpgradeManager()->isUpgrading(uct->getProducedUpgrade())){ - text=lang.getString("Upgrading")+"\n\n"; - } - else if(unit->getFaction()->getUpgradeManager()->isUpgraded(uct->getProducedUpgrade())){ - text=lang.getString("AlreadyUpgraded")+"\n\n"; - } - display.setInfoText(text+ct->getReqDesc(game->showTranslatedTechTree())); - } - //locked by scenario - else if(ct->getClass()==ccProduce){ - string text=""; - const ProduceCommandType *pct= static_cast(ct); - if(unit->getFaction()->isUnitLocked(pct->getProducedUnit())){ - display.setInfoText(lang.getString("LockedByScenario")+"\n\n"+ct->getReqDesc(game->showTranslatedTechTree())); - } - } - else if(ct->getClass()==ccMorph){ - const MorphCommandType *mct= static_cast(ct); - if(unit->getFaction()->isUnitLocked(mct->getMorphUnit())){ - display.setInfoText(lang.getString("LockedByScenario")+"\n\n"+ct->getReqDesc(game->showTranslatedTechTree())); - } - } - } - } - } - - //non uniform selection - else{ - const UnitType *ut= selection.getFrontUnit()->getType(); - CommandClass cc= display.getCommandClass(posDisplay); - if(cc!=ccNull){ - display.setInfoText(lang.getString("CommonCommand") + ": " + ut->getFirstCtOfClass(cc)->toString(true)); - } - } + //else if(key == configKeys.getCharKey("HotKeySelectedUnitsAttack")) { + else if (isKeyPressed(configKeys.getSDLKey("HotKeySelectedUnitsAttack"), key) == true) { + clickCommonCommand(ccAttack); } - } - else{ - if(posDisplay==cancelPos){ - display.setInfoText(lang.getString("Return")); + //else if(key == configKeys.getCharKey("HotKeySelectedUnitsAttack")) { + else if (isKeyPressed(configKeys.getSDLKey("HotKeySelectedUnitsMove"), key) == true) { + clickCommonCommand(ccMove); } - else{ - if(activeCommandType!=NULL && activeCommandType->getClass()==ccBuild){ - //locked by scenario - const BuildCommandType *bct= static_cast(activeCommandType); - const Unit *unit= selection.getFrontUnit(); - if(unit->getFaction()->isUnitLocked(bct->getBuilding(posDisplay))){ - display.setInfoText(lang.getString("LockedByScenario")+"\n\n"+bct->getBuilding(posDisplay)->getReqDesc(game->showTranslatedTechTree())); - } else { - bool translatedValue= game->showTranslatedTechTree(); - const UnitType *building=bct->getBuilding(posDisplay); - string str= lang.getString("BuildSpeed",(translatedValue == true ? "" : "english"))+": "+ intToStr(bct->getBuildSkillType()->getSpeed())+"\n"; - str+=""+Lang::getInstance().getString("TimeSteps",(translatedValue == true ? "" : "english"))+": "+intToStr(building->getProductionTime())+"\n"; - int64 speed=bct->getBuildSkillType()->getSpeed()+bct->getBuildSkillType()->getTotalSpeed(unit->getTotalUpgrade()); - int64 time=building->getProductionTime(); - int64 seconds=time*100/speed; - str+=""+Lang::getInstance().getString("Time",(translatedValue == true ? "" : "english"))+": "+intToStr(seconds); - str+="\n\n"; - str+=building->getReqDesc(translatedValue); - display.setInfoText(str); - } - } - } - } - } -} - -void Gui::computeDisplay(){ - - //printf("Start ===> computeDisplay()\n"); - Lang &lang= Lang::getInstance(); - //init - display.clear(); - - // ================ PART 1 ================ - const Object *selectedResourceObject =getSelectedResourceObject(); - if(selection.isEmpty() && selectedResourceObject != NULL && selectedResourceObject->getResource() != NULL) { - Resource *r = selectedResourceObject->getResource(); - display.setTitle(r->getType()->getName(game->showTranslatedTechTree())); - display.setText(lang.getString("Amount")+ ": "+intToStr(r->getAmount())+" / "+intToStr(r->getType()->getDefResPerPatch())); - //display.setProgressBar(r->); - display.setUpImage(0, r->getType()->getImage()); - } - else { - //title, text and progress bar - if(selection.getCount() == 1){ - display.setTitle(selection.getFrontUnit()->getFullName(game->showTranslatedTechTree())); - display.setText(selection.getFrontUnit()->getDesc(game->showTranslatedTechTree())); - display.setProgressBar(selection.getFrontUnit()->getProductionPercent()); - } - - //portraits - int unitIndex = 0; - for(unitIndex = 0; unitIndex < selection.getCount(); ++unitIndex){ - try { - const Unit *unit = selection.getUnit(unitIndex); - if(unit == NULL) { - throw megaglest_runtime_error("unit == NULL"); - } - if(unit->getType() == NULL) { - throw megaglest_runtime_error("unit->getType() == NULL"); - } - if(unit->getType()->getImage() == NULL) { - throw megaglest_runtime_error("unit->getType()->getImage()"); - } - - display.setUpImage(unitIndex, unit->getType()->getImage()); - } - catch(exception &ex) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error in unit selection for index: %d error [%s]",unitIndex,ex.what()); - throw megaglest_runtime_error(szBuf, true); + //else if(key == configKeys.getCharKey("HotKeySelectedUnitsStop")) { + else if (isKeyPressed(configKeys.getSDLKey("HotKeySelectedUnitsStop"), key) == true) { + clickCommonCommand(ccStop); } } - // ================ PART 2 ================ - - if(selectingPos || selectingMeetingPoint){ - //printf("selectingPos || selectingMeetingPoint\n"); - display.setDownSelectedPos(activePos); + void Gui::switchToNextDisplayColor() { + display.switchColor(); } - //printf("computeDisplay selection.isCommandable() = %d\n",selection.isCommandable()); + void Gui::onSelectionChanged() { + resetState(); + computeDisplay(); + } - if(selection.isCommandable()) { - //printf("selection.isComandable()\n"); + // ================= PRIVATE ================= - if(selectingBuilding == false){ + void Gui::giveOneClickOrders() { + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - //cancel button - const Unit *u= selection.getFrontUnit(); - const UnitType *ut= u->getType(); - if(selection.isCancelable()) { - //printf("selection.isCancelable() commandcount = %d\n",selection.getUnit(0)->getCommandSize()); - if(selection.getUnit(0)->getCommandSize() > 0){ - //printf("Current Command [%s]\n",selection.getUnit(0)->getCurrCommand()->toString().c_str()); - } + std::pair result(crFailUndefined, ""); + bool queueKeyDown = isKeyDown(queueCommandKey); + if (selection.isUniform()) { + result = commander->tryGiveCommand(&selection, activeCommandType, Vec2i(0), (Unit*) NULL, queueKeyDown); + } else { + result = commander->tryGiveCommand(&selection, activeCommandClass, Vec2i(0), (Unit*) NULL, queueKeyDown); + } + addOrdersResultToConsole(activeCommandClass, result); + activeCommandType = NULL; + activeCommandClass = ccStop; + } - display.setDownImage(cancelPos, ut->getCancelImage()); - display.setDownLighted(cancelPos, true); - } + void Gui::giveDefaultOrders(int x, int y) { + //compute target + //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //meeting point - if(selection.isMeetable()){ - //printf("selection.isMeetable()\n"); + const Unit *targetUnit = NULL; + Vec2i targetPos; + if (computeTarget(Vec2i(x, y), targetPos, targetUnit) == false) { + console->addStdMessage("InvalidPosition"); + return; + } + //printf("In [%s::%s Line: %d] targetUnit = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,targetUnit); + giveDefaultOrders(targetPos.x, targetPos.y, targetUnit, true); + //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + } - display.setDownImage(meetingPointPos, ut->getMeetingPointImage()); - display.setDownLighted(meetingPointPos, true); - } + void Gui::givePreparedDefaultOrders(int x, int y) { + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + giveDefaultOrders(x, y, NULL, false); + } + void Gui::giveDefaultOrders(int x, int y, const Unit *targetUnit, bool paintMouse3d) { + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + bool queueKeyDown = isKeyDown(queueCommandKey); + Vec2i targetPos = Vec2i(x, y); - //printf("computeDisplay selection.isUniform() = %d\n",selection.isUniform()); + //give order + //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + std::pair result = commander->tryGiveCommand(&selection, targetPos, targetUnit, queueKeyDown); - if(selection.isUniform()) { - //printf("selection.isUniform()\n"); + //printf("In [%s::%s Line: %d] selected units = %d result.first = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,selection.getCount(),result.first); - //uniform selection - if(u->isBuilt()){ - //printf("u->isBuilt()\n"); + //graphical result + addOrdersResultToConsole(activeCommandClass, result); + if (result.first == crSuccess || result.first == crSomeFailed) { + if (paintMouse3d) + mouse3d.enable(); - int morphPos= 8; - for(int i= 0; i < ut->getCommandTypeCount(); ++i){ - int displayPos= i; - const CommandType *ct= ut->getCommandType(i); - if(ct->getClass() == ccMorph) { - displayPos= morphPos++; - } - - //printf("computeDisplay i = %d displayPos = %d morphPos = %d ct->getClass() = %d [%s]\n",i,displayPos,morphPos,ct->getClass(),ct->getName().c_str()); - - display.setDownImage(displayPos, ct->getImage()); - display.setCommandType(displayPos, ct); - display.setCommandClass(displayPos, ct->getClass()); - display.setDownLighted(displayPos, u->getFaction()->reqsOk(ct)); - } - } - } - else{ - //printf("selection.isUniform() == FALSE\n"); - - //non uniform selection - int lastCommand= 0; - for(int i= 0; i < ccCount; ++i){ - CommandClass cc= static_cast (i); - - //printf("computeDisplay i = %d cc = %d isshared = %d lastCommand = %d\n",i,cc,isSharedCommandClass(cc),lastCommand); - - if(isSharedCommandClass(cc) && cc != ccBuild){ - display.setDownLighted(lastCommand, true); - display.setDownImage(lastCommand, ut->getFirstCtOfClass(cc)->getImage()); - display.setCommandClass(lastCommand, cc); - lastCommand++; - } - } + if (random.randRange(0, 1) == 0) { + SoundRenderer::getInstance().playFx( + selection.getFrontUnit()->getType()->getCommandSound(), + selection.getFrontUnit()->getCurrMidHeightVector(), + gameCamera->getPos()); } } - else{ + //reset + resetState(); + } + + void Gui::giveTwoClickOrders(int x, int y, bool prepared) { + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + std::pair result(crFailUndefined, ""); + + //compute target + const Unit *targetUnit = NULL; + Vec2i targetPos; + if (prepared) { + targetPos = Vec2i(x, y); + } else { + if (computeTarget(Vec2i(x, y), targetPos, targetUnit) == false) { + console->addStdMessage("InvalidPosition"); + return; + } + } + + bool queueKeyDown = isKeyDown(queueCommandKey); + //give orders to the units of this faction + if (selectingBuilding == false) { + if (selection.isUniform()) { + result = commander->tryGiveCommand(&selection, activeCommandType, + targetPos, targetUnit, queueKeyDown); + } else { + result = commander->tryGiveCommand(&selection, activeCommandClass, + targetPos, targetUnit, queueKeyDown); + } + } else { //selecting building - const Unit *unit= selection.getFrontUnit(); - if(activeCommandType != NULL && activeCommandType->getClass() == ccBuild){ - const BuildCommandType* bct= static_cast (activeCommandType); - for(int i= 0; i < bct->getBuildingCount(); ++i){ - display.setDownImage(i, bct->getBuilding(i)->getImage()); - display.setDownLighted(i, unit->getFaction()->reqsOk(bct->getBuilding(i))); - } - display.setDownImage(cancelPos, selection.getFrontUnit()->getType()->getCancelImage()); - display.setDownLighted(cancelPos, true); + result = commander->tryGiveCommand(&selection, + activeCommandType, posObjWorld, choosenBuildingType, + selectedBuildingFacing, queueKeyDown); + } + + //graphical result + addOrdersResultToConsole(activeCommandClass, result); + if (result.first == crSuccess || result.first == crSomeFailed) { + if (prepared == false) { + mouse3d.enable(); } - } - } - } - // refresh other things - if(!isSelecting() && !isSelectingPos()){ - if(!isSelectingPos() && lastPosDisplay == invalidPos){ - computeInfoString(lastPosDisplay); - } - } - -} - -int Gui::computePosDisplay(int x, int y){ - int posDisplay= display.computeDownIndex(x, y); - - //printf("computePosDisplay x = %d y = %d posDisplay = %d Display::downCellCount = %d cc = %d ct = %p\n",x,y,posDisplay,Display::downCellCount,display.getCommandClass(posDisplay),display.getCommandType(posDisplay)); - - if(posDisplay < 0 || posDisplay >= Display::downCellCount) { - posDisplay= invalidPos; - //printf("In [%s:%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); - } - else if(selection.isCommandable()) { - if(posDisplay != cancelPos) { - if(posDisplay != meetingPointPos) { - if(selectingBuilding == false) { - //standard selection - if(display.getCommandClass(posDisplay) == ccNull && display.getCommandType(posDisplay) == NULL) { - posDisplay= invalidPos; - //printf("In [%s:%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); - } - } - else { - //building selection - if(activeCommandType != NULL && activeCommandType->getClass() == ccBuild){ - const BuildCommandType *bct= static_cast(activeCommandType); - if(posDisplay >= bct->getBuildingCount()) { - posDisplay= invalidPos; - //printf("In [%s:%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); - } - } - } - } - else{ - //check meeting point - if(!selection.isMeetable()) { - posDisplay= invalidPos; - //printf("In [%s:%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); - } - } - } - else { - //check cancel button - if(selection.isCancelable() == false) { - posDisplay= invalidPos; - //printf("In [%s:%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); - } - } - } - else { - posDisplay= invalidPos; - //printf("In [%s:%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); - } - - //printf("computePosDisplay returning = %d\n",posDisplay); - - return posDisplay; -} - -void Gui::addOrdersResultToConsole(CommandClass cc, std::pair result) { - - switch(result.first) { - case crSuccess: - break; - case crFailReqs: - switch(cc){ - case ccBuild: - console->addStdMessage("BuildingNoReqs",result.second); - break; - case ccProduce: - console->addStdMessage("UnitNoReqs",result.second); - break; - case ccMorph: - console->addStdMessage("MorphNoReqs",result.second); - break; - case ccUpgrade: - console->addStdMessage("UpgradeNoReqs",result.second); - break; - default: - break; - } - break; - case crFailRes: - switch(cc){ - case ccBuild: - console->addStdMessage("BuildingNoRes",result.second); - break; - case ccProduce: - console->addStdMessage("UnitNoRes",result.second); - break; - case ccMorph: - console->addStdMessage("MorphNoRes",result.second); - break; - case ccUpgrade: - console->addStdMessage("UpgradeNoRes",result.second); - break; - default: - break; - } - break; - - case crFailUndefined: - console->addStdMessage("InvalidOrder",result.second); - break; - - case crSomeFailed: - console->addStdMessage("SomeOrdersFailed",result.second); - break; - } -} - -bool Gui::isSharedCommandClass(CommandClass commandClass){ - for(int i=0; igetType()->getFirstCtOfClass(commandClass); - if(ct==NULL || !unit->getFaction()->reqsOk(ct)) - return false; - } - return true; -} - -void Gui::computeSelected(bool doubleClick, bool force){ - Selection::UnitContainer units; - - if( force || ( lastQuadCalcFrame+selectionCalculationFrameSkip < game->getTotalRenderFps() ) ){ - lastQuadCalcFrame=game->getTotalRenderFps(); - const Object *selectedResourceObject=NULL; - selectedResourceObjectPos=Vec2i(-1,-1); - if(selectionQuad.isEnabled() && selectionQuad.getPosUp().dist(selectionQuad.getPosDown())getMapPos()); - } - } - else{ - Renderer::getInstance().computeSelected(units, selectedResourceObject, false, selectionQuad.getPosDown(), selectionQuad.getPosUp()); - } - selectingBuilding= false; - activeCommandType= NULL; - - //select all units of the same type if double click - if(doubleClick && units.empty() == false){ - const Unit *refUnit= getRelevantObjectFromSelection(&units); - int factionIndex= refUnit->getFactionIndex(); - for(int i=0; igetFaction(factionIndex)->getUnitCount(); ++i){ - Unit *unit= world->getFaction(factionIndex)->getUnit(i); - if(unit->getPos().dist(refUnit->getPosNotThreadSafe())getType()==refUnit->getType() && unit->isOperative()==refUnit->isOperative() ) - { - units.push_back(unit); + if (random.randRange(0, 1) == 0) { + SoundRenderer::getInstance().playFx( + selection.getFrontUnit()->getType()->getCommandSound(), + selection.getFrontUnit()->getCurrMidHeightVector(), + gameCamera->getPos()); } } } - bool shiftDown= isKeyDown(vkShift); - bool controlDown= isKeyDown(vkControl); + void Gui::centerCameraOnSelection() { + if (selection.isEmpty() == false) { + Vec3f refPos = selection.getRefPos(); + gameCamera->centerXZ(refPos.x, refPos.z); + } + } - if(!shiftDown && !controlDown){ - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] about to call selection.clear()\n",__FILE__,__FUNCTION__,__LINE__); + void Gui::selectInterestingUnit(InterestingUnitType iut) { + const Faction *thisFaction = world->getThisFaction(); + const Unit* previousUnit = NULL; + bool previousFound = true; + + //start at the next harvester + if (selection.getCount() == 1) { + const Unit* refUnit = selection.getFrontUnit(); + + if (refUnit->isInteresting(iut)) { + previousUnit = refUnit; + previousFound = false; + } + } + + //clear selection selection.clear(); - } - if(!controlDown){ - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] about to call selection.select(units)\n",__FILE__,__FUNCTION__,__LINE__); - selection.select(units,shiftDown); - if(!selection.isEmpty()){ - selectedResourceObject=NULL; + //search + for (int index = 0; index < thisFaction->getUnitCount(); ++index) { + Unit* unit = thisFaction->getUnit(index); + + if (previousFound == true) { + if (unit->isInteresting(iut)) { + selection.select(unit, false); + break; + } + } else { + if (unit == previousUnit) { + previousFound = true; + } + } + } + + //search again if we have a previous + if (selection.isEmpty() && previousUnit != NULL && previousFound == true) { + for (int index = 0; index < thisFaction->getUnitCount(); ++index) { + Unit* unit = thisFaction->getUnit(index); + + if (unit->isInteresting(iut)) { + selection.select(unit, false); + break; + } + } } } - else{ - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] selection.unSelect(units)\n",__FILE__,__FUNCTION__,__LINE__); - selection.unSelect(units); - } - } -} -bool Gui::computeTarget(const Vec2i &screenPos, Vec2i &targetPos, const Unit *&targetUnit){ - Selection::UnitContainer uc; - Renderer &renderer= Renderer::getInstance(); - const Object* obj= NULL; - renderer.computeSelected(uc, obj, true, screenPos, screenPos); - validPosObjWorld= false; + void Gui::clickCommonCommand(CommandClass commandClass) { + for (int index = 0; index < Display::downCellCount; ++index) { + const CommandType *ct = display.getCommandType(index); - if(uc.empty() == false){ - targetUnit= getRelevantObjectFromSelection(&uc); - targetPos= targetUnit->getPosNotThreadSafe(); - // we need to respect cellmaps. Searching for a cell which is really occupied - int size=targetUnit->getType()->getSize(); - bool foundUnit=false; - for ( int x= 0;xgetMap()->getCell(Vec2i(targetPos.x+x,targetPos.y+y))->getUnit(targetUnit->getType()->getField())==targetUnit){ - targetPos=Vec2i(targetPos.x+x,targetPos.y+y); - foundUnit=true; + if ((ct != NULL && ct->getClass() == commandClass) || + display.getCommandClass(index) == commandClass) { + + mouseDownDisplayUnitSkills(index); break; } } - if(foundUnit) break; + computeDisplay(); } - highlightedUnitId=targetUnit->getId(); - getHighlightedUnit()->resetHighlight(); - return true; - } - else if(obj != NULL){ - targetUnit= NULL; - highlightedResourceObjectPos=Map::toSurfCoords(obj->getMapPos()); - Object *selObj = getHighlightedResourceObject(); - if(selObj != NULL) { - selObj->resetHighlight(); - // get real click pos - targetPos=game->getMouseCellPos(); - //validPosObjWorld= true; - //posObjWorld = targetPos; + void Gui::mouseDownDisplayUnitSkills(int posDisplay) { + if (selection.isEmpty() == false) { + if (posDisplay != cancelPos) { + if (posDisplay != meetingPointPos) { + const Unit *unit = selection.getFrontUnit(); - int tx= targetPos.x; - int ty= targetPos.y; + //uniform selection + if (selection.isUniform()) { + const CommandType *ct = display.getCommandType(posDisplay); - int ox= obj->getMapPos().x; - int oy= obj->getMapPos().y; + // try to switch to next attack type + if (activeCommandClass == ccAttack && activeCommandType != NULL) { - Resource* clickedRecource= world->getMap()->getSurfaceCell(Map::toSurfCoords(obj->getMapPos()))->getResource(); + int maxI = unit->getType()->getCommandTypeCount(); + int cmdTypeId = activeCommandType->getId(); + int cmdTypeIdNext = cmdTypeId + 1; - // lets see if the click had the same Resource - if(clickedRecource == world->getMap()->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource()){ - // same ressource is meant, so use the user selected position - return true; - } - else{// calculate a valid resource position which is as near as possible to the selected position - Vec2i testIt= Vec2i(obj->getMapPos()); - /////////////// - // test both // - /////////////// - if(ty < oy){ - testIt.y--; - } - else if(ty > oy){ - testIt.y++; - } - if(tx < ox){ - testIt.x--; - } - else if(tx > ox){ - testIt.x++; - } + while (cmdTypeIdNext != cmdTypeId) { + if (cmdTypeIdNext >= maxI) { + cmdTypeIdNext = 0; + } + const CommandType *ctype = display.getCommandType(cmdTypeIdNext); + if (ctype != NULL && ctype->getClass() == ccAttack) { + if (ctype != NULL && unit->getFaction()->reqsOk(ctype)) { + posDisplay = cmdTypeIdNext; + ct = display.getCommandType(posDisplay); + break; + } + } + cmdTypeIdNext++; + } + } - if(clickedRecource == world->getMap()->getSurfaceCell(Map::toSurfCoords(testIt))->getResource()){ - // same ressource is meant, so use this position - targetPos= testIt; - //posObjWorld= targetPos; - return true; - } - else{ - testIt= Vec2i(obj->getMapPos()); - } + if (ct != NULL && unit->getFaction()->reqsOk(ct)) { + activeCommandType = ct; + activeCommandClass = activeCommandType->getClass(); + } else { + posDisplay = invalidPos; + activeCommandType = NULL; + activeCommandClass = ccStop; + return; + } + } - ///////////////// - // test y-only // - ///////////////// - if(ty < oy){ - testIt.y--; - } - else if(ty > oy){ - testIt.y++; - } - if(clickedRecource == world->getMap()->getSurfaceCell(Map::toSurfCoords(testIt))->getResource()){ - // same ressource is meant, so use this position - targetPos= testIt; - //posObjWorld= targetPos; - return true; - } - else{ - testIt= Vec2i(obj->getMapPos()); - } + //non uniform selection + else { + activeCommandType = NULL; + activeCommandClass = display.getCommandClass(posDisplay); + } - ///////////////// - // test x-only // - ///////////////// - if(tx < ox){ - testIt.x--; - } - else if(tx > ox){ - testIt.x++; - } - if(clickedRecource == world->getMap()->getSurfaceCell(Map::toSurfCoords(testIt))->getResource()){ - // same ressource is meant, so use this position - targetPos= testIt; - //posObjWorld= targetPos; - return true; + //give orders depending on command type + if (!selection.isEmpty()) { + const CommandType *ct = selection.getUnit(0)->getType()->getFirstCtOfClass(activeCommandClass); + if (activeCommandType != NULL && activeCommandType->getClass() == ccBuild) { + assert(selection.isUniform()); + selectingBuilding = true; + } else if (ct->getClicks() == cOne) { + invalidatePosObjWorld(); + giveOneClickOrders(); + } else { + selectingPos = true; + activePos = posDisplay; + } + } + } else { + activePos = posDisplay; + selectingMeetingPoint = true; + } + } else { + commander->tryCancelCommand(&selection); } } - // give up and use the object position; - targetPos= obj->getMapPos(); - posObjWorld= targetPos; + } + + void Gui::mouseDownDisplayUnitBuild(int posDisplay) { + //int factionIndex = world->getThisFactionIndex(); + + if (posDisplay == cancelPos) { + resetState(); + } else { + if (activeCommandType != NULL && + activeCommandType->getClass() == ccBuild) { + + const BuildCommandType *bct = dynamic_cast(activeCommandType); + if (bct != NULL) { + const UnitType *ut = bct->getBuilding(posDisplay); + + const Unit *unit = selection.getFrontUnit(); + if (unit != NULL && unit->getFaction() != NULL) { + + if (selection.canSelectUnitFactionCheck(unit) == true && + unit->getFaction()->reqsOk(ut)) { + + choosenBuildingType = ut; + selectingPos = true; + selectedBuildingFacing = CardinalDir(CardinalDir::NORTH); + activePos = posDisplay; + } + } + } + } + } + } + + + string Gui::computeDefaultInfoString() { + string result = ""; + + if (selection.isUniform()) { + if (selection.isObserver() || selection.isCommandable()) { + // default is the description extension + result = selection.getFrontUnit()->getDescExtension(game->showTranslatedTechTree()); + } + } + return result; + } + + + void Gui::computeInfoString(int posDisplay) { + + Lang &lang = Lang::getInstance(); + + lastPosDisplay = posDisplay; + + display.setInfoText(computeDefaultInfoString()); + + if (posDisplay != invalidPos && selection.isCommandable()) { + if (!selectingBuilding) { + if (posDisplay == cancelPos) { + display.setInfoText(lang.getString("Cancel")); + } else if (posDisplay == meetingPointPos) { + display.setInfoText(lang.getString("MeetingPoint")); + } else { + //uniform selection + if (selection.isUniform()) { + const Unit *unit = selection.getFrontUnit(); + const CommandType *ct = display.getCommandType(posDisplay); + + if (ct != NULL) { + if (unit->getFaction()->reqsOk(ct)) { + display.setInfoText(ct->getDesc(unit->getTotalUpgrade(), game->showTranslatedTechTree())); + } else { + display.setInfoText(ct->getReqDesc(game->showTranslatedTechTree())); + if (ct->getClass() == ccUpgrade) { + string text = ""; + const UpgradeCommandType *uct = static_cast(ct); + if (unit->getFaction()->getUpgradeManager()->isUpgrading(uct->getProducedUpgrade())) { + text = lang.getString("Upgrading") + "\n\n"; + } else if (unit->getFaction()->getUpgradeManager()->isUpgraded(uct->getProducedUpgrade())) { + text = lang.getString("AlreadyUpgraded") + "\n\n"; + } + display.setInfoText(text + ct->getReqDesc(game->showTranslatedTechTree())); + } + //locked by scenario + else if (ct->getClass() == ccProduce) { + string text = ""; + const ProduceCommandType *pct = static_cast(ct); + if (unit->getFaction()->isUnitLocked(pct->getProducedUnit())) { + display.setInfoText(lang.getString("LockedByScenario") + "\n\n" + ct->getReqDesc(game->showTranslatedTechTree())); + } + } else if (ct->getClass() == ccMorph) { + const MorphCommandType *mct = static_cast(ct); + if (unit->getFaction()->isUnitLocked(mct->getMorphUnit())) { + display.setInfoText(lang.getString("LockedByScenario") + "\n\n" + ct->getReqDesc(game->showTranslatedTechTree())); + } + } + } + } + } + + //non uniform selection + else { + const UnitType *ut = selection.getFrontUnit()->getType(); + CommandClass cc = display.getCommandClass(posDisplay); + if (cc != ccNull) { + display.setInfoText(lang.getString("CommonCommand") + ": " + ut->getFirstCtOfClass(cc)->toString(true)); + } + } + } + } else { + if (posDisplay == cancelPos) { + display.setInfoText(lang.getString("Return")); + } else { + if (activeCommandType != NULL && activeCommandType->getClass() == ccBuild) { + //locked by scenario + const BuildCommandType *bct = static_cast(activeCommandType); + const Unit *unit = selection.getFrontUnit(); + if (unit->getFaction()->isUnitLocked(bct->getBuilding(posDisplay))) { + display.setInfoText(lang.getString("LockedByScenario") + "\n\n" + bct->getBuilding(posDisplay)->getReqDesc(game->showTranslatedTechTree())); + } else { + bool translatedValue = game->showTranslatedTechTree(); + const UnitType *building = bct->getBuilding(posDisplay); + string str = lang.getString("BuildSpeed", (translatedValue == true ? "" : "english")) + ": " + intToStr(bct->getBuildSkillType()->getSpeed()) + "\n"; + str += "" + Lang::getInstance().getString("TimeSteps", (translatedValue == true ? "" : "english")) + ": " + intToStr(building->getProductionTime()) + "\n"; + int64 speed = bct->getBuildSkillType()->getSpeed() + bct->getBuildSkillType()->getTotalSpeed(unit->getTotalUpgrade()); + int64 time = building->getProductionTime(); + int64 seconds = time * 100 / speed; + str += "" + Lang::getInstance().getString("Time", (translatedValue == true ? "" : "english")) + ": " + intToStr(seconds); + str += "\n\n"; + str += building->getReqDesc(translatedValue); + display.setInfoText(str); + } + } + } + } + } + } + + void Gui::computeDisplay() { + + //printf("Start ===> computeDisplay()\n"); + Lang &lang = Lang::getInstance(); + //init + display.clear(); + + // ================ PART 1 ================ + const Object *selectedResourceObject = getSelectedResourceObject(); + if (selection.isEmpty() && selectedResourceObject != NULL && selectedResourceObject->getResource() != NULL) { + Resource *r = selectedResourceObject->getResource(); + display.setTitle(r->getType()->getName(game->showTranslatedTechTree())); + display.setText(lang.getString("Amount") + ": " + intToStr(r->getAmount()) + " / " + intToStr(r->getType()->getDefResPerPatch())); + //display.setProgressBar(r->); + display.setUpImage(0, r->getType()->getImage()); + } else { + //title, text and progress bar + if (selection.getCount() == 1) { + display.setTitle(selection.getFrontUnit()->getFullName(game->showTranslatedTechTree())); + display.setText(selection.getFrontUnit()->getDesc(game->showTranslatedTechTree())); + display.setProgressBar(selection.getFrontUnit()->getProductionPercent()); + } + + //portraits + int unitIndex = 0; + for (unitIndex = 0; unitIndex < selection.getCount(); ++unitIndex) { + try { + const Unit *unit = selection.getUnit(unitIndex); + if (unit == NULL) { + throw megaglest_runtime_error("unit == NULL"); + } + if (unit->getType() == NULL) { + throw megaglest_runtime_error("unit->getType() == NULL"); + } + if (unit->getType()->getImage() == NULL) { + throw megaglest_runtime_error("unit->getType()->getImage()"); + } + + display.setUpImage(unitIndex, unit->getType()->getImage()); + } catch (exception &ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error in unit selection for index: %d error [%s]", unitIndex, ex.what()); + throw megaglest_runtime_error(szBuf, true); + } + } + + // ================ PART 2 ================ + + if (selectingPos || selectingMeetingPoint) { + //printf("selectingPos || selectingMeetingPoint\n"); + display.setDownSelectedPos(activePos); + } + + //printf("computeDisplay selection.isCommandable() = %d\n",selection.isCommandable()); + + if (selection.isCommandable()) { + //printf("selection.isComandable()\n"); + + if (selectingBuilding == false) { + + //cancel button + const Unit *u = selection.getFrontUnit(); + const UnitType *ut = u->getType(); + if (selection.isCancelable()) { + //printf("selection.isCancelable() commandcount = %d\n",selection.getUnit(0)->getCommandSize()); + if (selection.getUnit(0)->getCommandSize() > 0) { + //printf("Current Command [%s]\n",selection.getUnit(0)->getCurrCommand()->toString().c_str()); + } + + display.setDownImage(cancelPos, ut->getCancelImage()); + display.setDownLighted(cancelPos, true); + } + + //meeting point + if (selection.isMeetable()) { + //printf("selection.isMeetable()\n"); + + display.setDownImage(meetingPointPos, ut->getMeetingPointImage()); + display.setDownLighted(meetingPointPos, true); + } + + + //printf("computeDisplay selection.isUniform() = %d\n",selection.isUniform()); + + if (selection.isUniform()) { + //printf("selection.isUniform()\n"); + + //uniform selection + if (u->isBuilt()) { + //printf("u->isBuilt()\n"); + + int morphPos = 8; + for (int i = 0; i < ut->getCommandTypeCount(); ++i) { + int displayPos = i; + const CommandType *ct = ut->getCommandType(i); + if (ct->getClass() == ccMorph) { + displayPos = morphPos++; + } + + //printf("computeDisplay i = %d displayPos = %d morphPos = %d ct->getClass() = %d [%s]\n",i,displayPos,morphPos,ct->getClass(),ct->getName().c_str()); + + display.setDownImage(displayPos, ct->getImage()); + display.setCommandType(displayPos, ct); + display.setCommandClass(displayPos, ct->getClass()); + display.setDownLighted(displayPos, u->getFaction()->reqsOk(ct)); + } + } + } else { + //printf("selection.isUniform() == FALSE\n"); + + //non uniform selection + int lastCommand = 0; + for (int i = 0; i < ccCount; ++i) { + CommandClass cc = static_cast (i); + + //printf("computeDisplay i = %d cc = %d isshared = %d lastCommand = %d\n",i,cc,isSharedCommandClass(cc),lastCommand); + + if (isSharedCommandClass(cc) && cc != ccBuild) { + display.setDownLighted(lastCommand, true); + display.setDownImage(lastCommand, ut->getFirstCtOfClass(cc)->getImage()); + display.setCommandClass(lastCommand, cc); + lastCommand++; + } + } + } + } else { + + //selecting building + const Unit *unit = selection.getFrontUnit(); + if (activeCommandType != NULL && activeCommandType->getClass() == ccBuild) { + const BuildCommandType* bct = static_cast (activeCommandType); + for (int i = 0; i < bct->getBuildingCount(); ++i) { + display.setDownImage(i, bct->getBuilding(i)->getImage()); + display.setDownLighted(i, unit->getFaction()->reqsOk(bct->getBuilding(i))); + } + display.setDownImage(cancelPos, selection.getFrontUnit()->getType()->getCancelImage()); + display.setDownLighted(cancelPos, true); + } + } + } + } + + // refresh other things + if (!isSelecting() && !isSelectingPos()) { + if (!isSelectingPos() && lastPosDisplay == invalidPos) { + computeInfoString(lastPosDisplay); + } + } + + } + + int Gui::computePosDisplay(int x, int y) { + int posDisplay = display.computeDownIndex(x, y); + + //printf("computePosDisplay x = %d y = %d posDisplay = %d Display::downCellCount = %d cc = %d ct = %p\n",x,y,posDisplay,Display::downCellCount,display.getCommandClass(posDisplay),display.getCommandType(posDisplay)); + + if (posDisplay < 0 || posDisplay >= Display::downCellCount) { + posDisplay = invalidPos; + //printf("In [%s:%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + } else if (selection.isCommandable()) { + if (posDisplay != cancelPos) { + if (posDisplay != meetingPointPos) { + if (selectingBuilding == false) { + //standard selection + if (display.getCommandClass(posDisplay) == ccNull && display.getCommandType(posDisplay) == NULL) { + posDisplay = invalidPos; + //printf("In [%s:%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + } + } else { + //building selection + if (activeCommandType != NULL && activeCommandType->getClass() == ccBuild) { + const BuildCommandType *bct = static_cast(activeCommandType); + if (posDisplay >= bct->getBuildingCount()) { + posDisplay = invalidPos; + //printf("In [%s:%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + } + } + } + } else { + //check meeting point + if (!selection.isMeetable()) { + posDisplay = invalidPos; + //printf("In [%s:%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + } + } + } else { + //check cancel button + if (selection.isCancelable() == false) { + posDisplay = invalidPos; + //printf("In [%s:%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + } + } + } else { + posDisplay = invalidPos; + //printf("In [%s:%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + } + + //printf("computePosDisplay returning = %d\n",posDisplay); + + return posDisplay; + } + + void Gui::addOrdersResultToConsole(CommandClass cc, std::pair result) { + + switch (result.first) { + case crSuccess: + break; + case crFailReqs: + switch (cc) { + case ccBuild: + console->addStdMessage("BuildingNoReqs", result.second); + break; + case ccProduce: + console->addStdMessage("UnitNoReqs", result.second); + break; + case ccMorph: + console->addStdMessage("MorphNoReqs", result.second); + break; + case ccUpgrade: + console->addStdMessage("UpgradeNoReqs", result.second); + break; + default: + break; + } + break; + case crFailRes: + switch (cc) { + case ccBuild: + console->addStdMessage("BuildingNoRes", result.second); + break; + case ccProduce: + console->addStdMessage("UnitNoRes", result.second); + break; + case ccMorph: + console->addStdMessage("MorphNoRes", result.second); + break; + case ccUpgrade: + console->addStdMessage("UpgradeNoRes", result.second); + break; + default: + break; + } + break; + + case crFailUndefined: + console->addStdMessage("InvalidOrder", result.second); + break; + + case crSomeFailed: + console->addStdMessage("SomeOrdersFailed", result.second); + break; + } + } + + bool Gui::isSharedCommandClass(CommandClass commandClass) { + for (int i = 0; i < selection.getCount(); ++i) { + const Unit *unit = selection.getUnit(i); + const CommandType *ct = unit->getType()->getFirstCtOfClass(commandClass); + if (ct == NULL || !unit->getFaction()->reqsOk(ct)) + return false; + } return true; } - else { - return false; - } - } - else{ - targetUnit= NULL; - targetPos=game->getMouseCellPos(); - if(game->isValidMouseCellPos()){ - validPosObjWorld= true; - posObjWorld= targetPos; - if(world->getMap()->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource() != NULL) { - highlightedResourceObjectPos=Map::toSurfCoords(targetPos); + void Gui::computeSelected(bool doubleClick, bool force) { + Selection::UnitContainer units; + + if (force || (lastQuadCalcFrame + selectionCalculationFrameSkip < game->getTotalRenderFps())) { + lastQuadCalcFrame = game->getTotalRenderFps(); + const Object *selectedResourceObject = NULL; + selectedResourceObjectPos = Vec2i(-1, -1); + if (selectionQuad.isEnabled() && selectionQuad.getPosUp().dist(selectionQuad.getPosDown()) < minQuadSize) { + //Renderer::getInstance().computeSelected(units, selectedResourceObject, true, selectionQuad.getPosDown(), selectionQuad.getPosDown()); + Renderer::getInstance().computeSelected(units, selectedResourceObject, true, selectionQuad.getPosDown(), selectionQuad.getPosDown()); + if (selectedResourceObject != NULL) { + selectedResourceObjectPos = Map::toSurfCoords(selectedResourceObject->getMapPos()); + } + } else { + Renderer::getInstance().computeSelected(units, selectedResourceObject, false, selectionQuad.getPosDown(), selectionQuad.getPosUp()); + } + selectingBuilding = false; + activeCommandType = NULL; + + //select all units of the same type if double click + if (doubleClick && units.empty() == false) { + const Unit *refUnit = getRelevantObjectFromSelection(&units); + int factionIndex = refUnit->getFactionIndex(); + for (int i = 0; i < world->getFaction(factionIndex)->getUnitCount(); ++i) { + Unit *unit = world->getFaction(factionIndex)->getUnit(i); + if (unit->getPos().dist(refUnit->getPosNotThreadSafe()) < doubleClickSelectionRadius && + unit->getType() == refUnit->getType() && unit->isOperative() == refUnit->isOperative()) { + units.push_back(unit); + } + } + } + + bool shiftDown = isKeyDown(vkShift); + bool controlDown = isKeyDown(vkControl); + + if (!shiftDown && !controlDown) { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] about to call selection.clear()\n",__FILE__,__FUNCTION__,__LINE__); + selection.clear(); + } + + if (!controlDown) { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] about to call selection.select(units)\n",__FILE__,__FUNCTION__,__LINE__); + selection.select(units, shiftDown); + if (!selection.isEmpty()) { + selectedResourceObject = NULL; + } + } else { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] selection.unSelect(units)\n",__FILE__,__FUNCTION__,__LINE__); + selection.unSelect(units); + } + } + } + + bool Gui::computeTarget(const Vec2i &screenPos, Vec2i &targetPos, const Unit *&targetUnit) { + Selection::UnitContainer uc; + Renderer &renderer = Renderer::getInstance(); + const Object* obj = NULL; + renderer.computeSelected(uc, obj, true, screenPos, screenPos); + validPosObjWorld = false; + + if (uc.empty() == false) { + targetUnit = getRelevantObjectFromSelection(&uc); + targetPos = targetUnit->getPosNotThreadSafe(); + // we need to respect cellmaps. Searching for a cell which is really occupied + int size = targetUnit->getType()->getSize(); + bool foundUnit = false; + for (int x = 0; x < size; ++x) { + for (int y = 0; y < size; ++y) { + if (world->getMap()->getCell(Vec2i(targetPos.x + x, targetPos.y + y))->getUnit(targetUnit->getType()->getField()) == targetUnit) { + targetPos = Vec2i(targetPos.x + x, targetPos.y + y); + foundUnit = true; + break; + } + } + if (foundUnit) break; + } + highlightedUnitId = targetUnit->getId(); + getHighlightedUnit()->resetHighlight(); + return true; + } else if (obj != NULL) { + targetUnit = NULL; + highlightedResourceObjectPos = Map::toSurfCoords(obj->getMapPos()); Object *selObj = getHighlightedResourceObject(); - if(selObj != NULL) { + if (selObj != NULL) { selObj->resetHighlight(); + // get real click pos + targetPos = game->getMouseCellPos(); + //validPosObjWorld= true; + //posObjWorld = targetPos; + + int tx = targetPos.x; + int ty = targetPos.y; + + int ox = obj->getMapPos().x; + int oy = obj->getMapPos().y; + + Resource* clickedRecource = world->getMap()->getSurfaceCell(Map::toSurfCoords(obj->getMapPos()))->getResource(); + + // lets see if the click had the same Resource + if (clickedRecource == world->getMap()->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource()) { + // same ressource is meant, so use the user selected position + return true; + } else {// calculate a valid resource position which is as near as possible to the selected position + Vec2i testIt = Vec2i(obj->getMapPos()); + /////////////// + // test both // + /////////////// + if (ty < oy) { + testIt.y--; + } else if (ty > oy) { + testIt.y++; + } + if (tx < ox) { + testIt.x--; + } else if (tx > ox) { + testIt.x++; + } + + if (clickedRecource == world->getMap()->getSurfaceCell(Map::toSurfCoords(testIt))->getResource()) { + // same ressource is meant, so use this position + targetPos = testIt; + //posObjWorld= targetPos; + return true; + } else { + testIt = Vec2i(obj->getMapPos()); + } + + ///////////////// + // test y-only // + ///////////////// + if (ty < oy) { + testIt.y--; + } else if (ty > oy) { + testIt.y++; + } + if (clickedRecource == world->getMap()->getSurfaceCell(Map::toSurfCoords(testIt))->getResource()) { + // same ressource is meant, so use this position + targetPos = testIt; + //posObjWorld= targetPos; + return true; + } else { + testIt = Vec2i(obj->getMapPos()); + } + + ///////////////// + // test x-only // + ///////////////// + if (tx < ox) { + testIt.x--; + } else if (tx > ox) { + testIt.x++; + } + if (clickedRecource == world->getMap()->getSurfaceCell(Map::toSurfCoords(testIt))->getResource()) { + // same ressource is meant, so use this position + targetPos = testIt; + //posObjWorld= targetPos; + return true; + } + } + // give up and use the object position; + targetPos = obj->getMapPos(); + posObjWorld = targetPos; + return true; + } else { + return false; + } + } else { + targetUnit = NULL; + targetPos = game->getMouseCellPos(); + if (game->isValidMouseCellPos()) { + validPosObjWorld = true; + posObjWorld = targetPos; + + if (world->getMap()->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource() != NULL) { + highlightedResourceObjectPos = Map::toSurfCoords(targetPos); + + Object *selObj = getHighlightedResourceObject(); + if (selObj != NULL) { + selObj->resetHighlight(); + } + } + + return true; + } else { + return false; } } - - return true; } - else{ - return false; + + Unit* Gui::getRelevantObjectFromSelection(Selection::UnitContainer *uc) { + Unit *resultUnit = NULL; + for (int i = 0; i < (int) uc->size(); ++i) { + resultUnit = uc->at(i); + if (resultUnit->getType()->hasSkillClass(scMove)) {// moving units are more relevant than non moving ones + break; + } + } + return resultUnit; } - } -} -Unit* Gui::getRelevantObjectFromSelection(Selection::UnitContainer *uc){ - Unit *resultUnit=NULL; - for(int i= 0; i < (int)uc->size(); ++i) { - resultUnit= uc->at(i); - if(resultUnit->getType()->hasSkillClass(scMove)){// moving units are more relevant than non moving ones - break; + void Gui::saveGame(XmlNode *rootNode) const { + std::map mapTagReplacements; + XmlNode *guiNode = rootNode->addChild("Gui"); + + guiNode->addAttribute("random", intToStr(random.getLastNumber()), mapTagReplacements); + guiNode->addAttribute("posObjWorld", posObjWorld.getString(), mapTagReplacements); + guiNode->addAttribute("validPosObjWorld", intToStr(validPosObjWorld), mapTagReplacements); + if (choosenBuildingType != NULL) { + const Faction* thisFaction = world->getThisFaction(); + guiNode->addAttribute("choosenBuildingType", choosenBuildingType->getName(false), mapTagReplacements); + guiNode->addAttribute("choosenBuildingTypeFactionIndex", intToStr(thisFaction->getIndex()), mapTagReplacements); + } + if (activeCommandType != NULL) { + guiNode->addAttribute("activeCommandType", activeCommandType->getName(false), mapTagReplacements); + } + + guiNode->addAttribute("activeCommandClass", intToStr(activeCommandClass), mapTagReplacements); + guiNode->addAttribute("activePos", intToStr(activePos), mapTagReplacements); + guiNode->addAttribute("lastPosDisplay", intToStr(lastPosDisplay), mapTagReplacements); + display.saveGame(guiNode); + selection.saveGame(guiNode); + guiNode->addAttribute("lastQuadCalcFrame", intToStr(lastQuadCalcFrame), mapTagReplacements); + guiNode->addAttribute("selectionCalculationFrameSkip", intToStr(selectionCalculationFrameSkip), mapTagReplacements); + guiNode->addAttribute("minQuadSize", intToStr(minQuadSize), mapTagReplacements); + guiNode->addAttribute("lastGroupRecall", intToStr(lastGroupRecall), mapTagReplacements); + guiNode->addAttribute("selectingBuilding", intToStr(selectingBuilding), mapTagReplacements); + guiNode->addAttribute("selectingPos", intToStr(selectingPos), mapTagReplacements); + guiNode->addAttribute("selectingMeetingPoint", intToStr(selectingMeetingPoint), mapTagReplacements); + guiNode->addAttribute("selectedBuildingFacing", intToStr(selectedBuildingFacing), mapTagReplacements); } + + void Gui::loadGame(const XmlNode *rootNode, World *world) { + const XmlNode *guiNode = rootNode->getChild("Gui"); + + random.setLastNumber(guiNode->getAttribute("random")->getIntValue()); + posObjWorld = Vec2i::strToVec2(guiNode->getAttribute("posObjWorld")->getValue()); + validPosObjWorld = guiNode->getAttribute("validPosObjWorld")->getIntValue() != 0; + if (guiNode->hasAttribute("choosenBuildingType") == true) { + string unitType = guiNode->getAttribute("choosenBuildingType")->getValue(); + int factionIndex = guiNode->getAttribute("choosenBuildingTypeFactionIndex")->getIntValue(); + choosenBuildingType = world->getFaction(factionIndex)->getType()->getUnitType(unitType); + } + activePos = guiNode->getAttribute("activePos")->getIntValue(); + lastPosDisplay = guiNode->getAttribute("lastPosDisplay")->getIntValue(); + display.loadGame(guiNode); + selection.loadGame(guiNode, world); + // don't load this! lastQuadCalcFrame = guiNode->getAttribute("lastQuadCalcFrame")->getIntValue(); + lastQuadCalcFrame = game->getTotalRenderFps(); + selectionCalculationFrameSkip = guiNode->getAttribute("selectionCalculationFrameSkip")->getIntValue(); + minQuadSize = guiNode->getAttribute("minQuadSize")->getIntValue(); + lastGroupRecall = guiNode->getAttribute("lastGroupRecall")->getIntValue(); + } + } - return resultUnit; -} - -void Gui::saveGame(XmlNode *rootNode) const { - std::map mapTagReplacements; - XmlNode *guiNode = rootNode->addChild("Gui"); - - guiNode->addAttribute("random",intToStr(random.getLastNumber()), mapTagReplacements); - guiNode->addAttribute("posObjWorld",posObjWorld.getString(), mapTagReplacements); - guiNode->addAttribute("validPosObjWorld",intToStr(validPosObjWorld), mapTagReplacements); - if(choosenBuildingType != NULL) { - const Faction* thisFaction= world->getThisFaction(); - guiNode->addAttribute("choosenBuildingType",choosenBuildingType->getName(false), mapTagReplacements); - guiNode->addAttribute("choosenBuildingTypeFactionIndex",intToStr(thisFaction->getIndex()), mapTagReplacements); - } - if(activeCommandType != NULL) { - guiNode->addAttribute("activeCommandType",activeCommandType->getName(false), mapTagReplacements); - } - - guiNode->addAttribute("activeCommandClass",intToStr(activeCommandClass), mapTagReplacements); - guiNode->addAttribute("activePos",intToStr(activePos), mapTagReplacements); - guiNode->addAttribute("lastPosDisplay",intToStr(lastPosDisplay), mapTagReplacements); - display.saveGame(guiNode); - selection.saveGame(guiNode); - guiNode->addAttribute("lastQuadCalcFrame",intToStr(lastQuadCalcFrame), mapTagReplacements); - guiNode->addAttribute("selectionCalculationFrameSkip",intToStr(selectionCalculationFrameSkip), mapTagReplacements); - guiNode->addAttribute("minQuadSize",intToStr(minQuadSize), mapTagReplacements); - guiNode->addAttribute("lastGroupRecall",intToStr(lastGroupRecall), mapTagReplacements); - guiNode->addAttribute("selectingBuilding",intToStr(selectingBuilding), mapTagReplacements); - guiNode->addAttribute("selectingPos",intToStr(selectingPos), mapTagReplacements); - guiNode->addAttribute("selectingMeetingPoint",intToStr(selectingMeetingPoint), mapTagReplacements); - guiNode->addAttribute("selectedBuildingFacing",intToStr(selectedBuildingFacing), mapTagReplacements); -} - -void Gui::loadGame(const XmlNode *rootNode, World *world) { - const XmlNode *guiNode = rootNode->getChild("Gui"); - - random.setLastNumber(guiNode->getAttribute("random")->getIntValue()); - posObjWorld = Vec2i::strToVec2(guiNode->getAttribute("posObjWorld")->getValue()); - validPosObjWorld = guiNode->getAttribute("validPosObjWorld")->getIntValue() != 0; - if(guiNode->hasAttribute("choosenBuildingType") == true) { - string unitType = guiNode->getAttribute("choosenBuildingType")->getValue(); - int factionIndex = guiNode->getAttribute("choosenBuildingTypeFactionIndex")->getIntValue(); - choosenBuildingType = world->getFaction(factionIndex)->getType()->getUnitType(unitType); - } - activePos = guiNode->getAttribute("activePos")->getIntValue(); - lastPosDisplay = guiNode->getAttribute("lastPosDisplay")->getIntValue(); - display.loadGame(guiNode); - selection.loadGame(guiNode,world); - // don't load this! lastQuadCalcFrame = guiNode->getAttribute("lastQuadCalcFrame")->getIntValue(); - lastQuadCalcFrame = game->getTotalRenderFps(); - selectionCalculationFrameSkip = guiNode->getAttribute("selectionCalculationFrameSkip")->getIntValue(); - minQuadSize = guiNode->getAttribute("minQuadSize")->getIntValue(); - lastGroupRecall = guiNode->getAttribute("lastGroupRecall")->getIntValue(); -} - -}}//end namespace +}//end namespace diff --git a/source/glest_game/gui/gui.h b/source/glest_game/gui/gui.h index c9c8905c9..0b888cfd5 100644 --- a/source/glest_game/gui/gui.h +++ b/source/glest_game/gui/gui.h @@ -26,213 +26,255 @@ using Shared::Util::RandomGen; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -class Unit; -class World; -class CommandType; -class GameCamera; -class Game; + class Unit; + class World; + class CommandType; + class GameCamera; + class Game; -enum DisplayState{ - dsEmpty, - dsUnitSkills, - dsUnitBuild, - dsEnemy -}; + enum DisplayState { + dsEmpty, + dsUnitSkills, + dsUnitBuild, + dsEnemy + }; -// ===================================================== -// class Mouse3d -// ===================================================== + // ===================================================== + // class Mouse3d + // ===================================================== -class Mouse3d{ -public: - static const float fadeSpeed; + class Mouse3d { + public: + static const float fadeSpeed; -private: - bool enabled; - int rot; - float fade; + private: + bool enabled; + int rot; + float fade; -public: - Mouse3d(); + public: + Mouse3d(); - void enable(); - void update(); + void enable(); + void update(); - bool isEnabled() const {return enabled;} - float getFade() const {return fade;} - int getRot() const {return rot;} -}; + bool isEnabled() const { + return enabled; + } + float getFade() const { + return fade; + } + int getRot() const { + return rot; + } + }; -// ===================================================== -// class SelectionQuad -// ===================================================== + // ===================================================== + // class SelectionQuad + // ===================================================== -class SelectionQuad{ -private: - Vec2i posDown; - Vec2i posUp; - bool enabled; + class SelectionQuad { + private: + Vec2i posDown; + Vec2i posUp; + bool enabled; -public: - SelectionQuad(); + public: + SelectionQuad(); - bool isEnabled() const {return enabled;} - Vec2i getPosDown() const {return posDown;} - Vec2i getPosUp() const {return posUp;} + bool isEnabled() const { + return enabled; + } + Vec2i getPosDown() const { + return posDown; + } + Vec2i getPosUp() const { + return posUp; + } - void setPosDown(const Vec2i &posDown); - void setPosUp(const Vec2i &posUp); - void disable(); -}; + void setPosDown(const Vec2i &posDown); + void setPosUp(const Vec2i &posUp); + void disable(); + }; -// ===================================================== -// class Gui -// -/// In game GUI -// ===================================================== + // ===================================================== + // class Gui + // + /// In game GUI + // ===================================================== -class Gui { -public: - static const int maxSelBuff= 128*5; - static const int upgradeDisplayIndex= 8; + class Gui { + public: + static const int maxSelBuff = 128 * 5; + static const int upgradeDisplayIndex = 8; - static const int meetingPointPos= 14; - static const int cancelPos= 15; - static const int imageCount= 16; + static const int meetingPointPos = 14; + static const int cancelPos = 15; + static const int imageCount = 16; - static const int invalidPos= -1; - static const int doubleClickSelectionRadius= 20; + static const int invalidPos = -1; + static const int doubleClickSelectionRadius = 20; -private: - //External objects - RandomGen random; - const Commander *commander; - const World *world; - const Game *game; - GameCamera *gameCamera; - Console *console; + private: + //External objects + RandomGen random; + const Commander *commander; + const World *world; + const Game *game; + GameCamera *gameCamera; + Console *console; - //Positions - Vec2i posObjWorld; //world coords - bool validPosObjWorld; + //Positions + Vec2i posObjWorld; //world coords + bool validPosObjWorld; - //display - const UnitType *choosenBuildingType; - const CommandType *activeCommandType; - CommandClass activeCommandClass; - int activePos; - int lastPosDisplay; + //display + const UnitType *choosenBuildingType; + const CommandType *activeCommandType; + CommandClass activeCommandClass; + int activePos; + int lastPosDisplay; - //composite - Display display; - Mouse3d mouse3d; - Selection selection; - SelectionQuad selectionQuad; - int lastQuadCalcFrame; - int selectionCalculationFrameSkip; - int minQuadSize; + //composite + Display display; + Mouse3d mouse3d; + Selection selection; + SelectionQuad selectionQuad; + int lastQuadCalcFrame; + int selectionCalculationFrameSkip; + int minQuadSize; - Chrono lastGroupRecallTime; - int lastGroupRecall; + Chrono lastGroupRecallTime; + int lastGroupRecall; - //states - bool selectingBuilding; - bool selectingPos; - bool selectingMeetingPoint; + //states + bool selectingBuilding; + bool selectingPos; + bool selectingMeetingPoint; - CardinalDir selectedBuildingFacing; - Vec2i selectedResourceObjectPos; - Vec2i highlightedResourceObjectPos; - int highlightedUnitId; + CardinalDir selectedBuildingFacing; + Vec2i selectedResourceObjectPos; + Vec2i highlightedResourceObjectPos; + int highlightedUnitId; - Texture2D* hudTexture; + Texture2D* hudTexture; -public: - Gui(); - void init(Game *game); - void end(); + public: + Gui(); + void init(Game *game); + void end(); - //get - Vec2i getPosObjWorld() const {return posObjWorld;} - const UnitType *getBuilding() const; + //get + Vec2i getPosObjWorld() const { + return posObjWorld; + } + const UnitType *getBuilding() const; - Texture2D *getHudTexture() const {return hudTexture;} - void setHudTexture(Texture2D* value) { hudTexture = value;} + Texture2D *getHudTexture() const { + return hudTexture; + } + void setHudTexture(Texture2D* value) { + hudTexture = value; + } - const Mouse3d *getMouse3d() const {return &mouse3d;} - const Display *getDisplay() const {return &display;} - const Selection *getSelection() const {return &selection;} - Selection *getSelectionPtr() {return &selection;} - const Object *getSelectedResourceObject() const; - Object *getHighlightedResourceObject() const; - Unit *getHighlightedUnit() const; + const Mouse3d *getMouse3d() const { + return &mouse3d; + } + const Display *getDisplay() const { + return &display; + } + const Selection *getSelection() const { + return &selection; + } + Selection *getSelectionPtr() { + return &selection; + } + const Object *getSelectedResourceObject() const; + Object *getHighlightedResourceObject() const; + Unit *getHighlightedUnit() const; - const SelectionQuad *getSelectionQuad() const {return &selectionQuad;} - CardinalDir getSelectedFacing() const {return selectedBuildingFacing;} - bool isSelected(const Unit *unit) const {return selection.hasUnit(unit);} + const SelectionQuad *getSelectionQuad() const { + return &selectionQuad; + } + CardinalDir getSelectedFacing() const { + return selectedBuildingFacing; + } + bool isSelected(const Unit *unit) const { + return selection.hasUnit(unit); + } - bool isValidPosObjWorld() const {return validPosObjWorld;} - bool isSelecting() const {return selectionQuad.isEnabled();} - bool isSelectingPos() const {return selectingPos;} - bool isSelectingBuilding() const {return selectingBuilding;} - bool isPlacingBuilding() const; + bool isValidPosObjWorld() const { + return validPosObjWorld; + } + bool isSelecting() const { + return selectionQuad.isEnabled(); + } + bool isSelectingPos() const { + return selectingPos; + } + bool isSelectingBuilding() const { + return selectingBuilding; + } + bool isPlacingBuilding() const; - //set - void invalidatePosObjWorld(); + //set + void invalidatePosObjWorld(); - //events - void update(); - void tick(); - bool mouseValid(int x, int y); - void mouseDownLeftDisplay(int x, int y); - void mouseMoveDisplay(int x, int y); - void mouseMoveOutsideDisplay(); - void mouseDownLeftGraphics(int x, int y, bool prepared); - void mouseDownRightGraphics(int x, int y, bool prepared); - void mouseUpLeftGraphics(int x, int y); - void mouseMoveGraphics(int x, int y); - void mouseDoubleClickLeftGraphics(int x, int y); - void groupKey(int groupIndex); - void hotKey(SDL_KeyboardEvent key); + //events + void update(); + void tick(); + bool mouseValid(int x, int y); + void mouseDownLeftDisplay(int x, int y); + void mouseMoveDisplay(int x, int y); + void mouseMoveOutsideDisplay(); + void mouseDownLeftGraphics(int x, int y, bool prepared); + void mouseDownRightGraphics(int x, int y, bool prepared); + void mouseUpLeftGraphics(int x, int y); + void mouseMoveGraphics(int x, int y); + void mouseDoubleClickLeftGraphics(int x, int y); + void groupKey(int groupIndex); + void hotKey(SDL_KeyboardEvent key); - //misc - void switchToNextDisplayColor(); - void onSelectionChanged(); + //misc + void switchToNextDisplayColor(); + void onSelectionChanged(); - void saveGame(XmlNode *rootNode) const; - void loadGame(const XmlNode *rootNode, World *world); + void saveGame(XmlNode *rootNode) const; + void loadGame(const XmlNode *rootNode, World *world); -private: + private: - //orders - void giveDefaultOrders(int x, int y); - void giveDefaultOrders(int x, int y, const Unit *targetUnit, bool paintMouse3d); - void givePreparedDefaultOrders(int x, int y); - void giveOneClickOrders(); - void giveTwoClickOrders(int x, int y, bool prepared); + //orders + void giveDefaultOrders(int x, int y); + void giveDefaultOrders(int x, int y, const Unit *targetUnit, bool paintMouse3d); + void givePreparedDefaultOrders(int x, int y); + void giveOneClickOrders(); + void giveTwoClickOrders(int x, int y, bool prepared); - //hotkeys - void centerCameraOnSelection(); - void selectInterestingUnit(InterestingUnitType iut); - void clickCommonCommand(CommandClass commandClass); + //hotkeys + void centerCameraOnSelection(); + void selectInterestingUnit(InterestingUnitType iut); + void clickCommonCommand(CommandClass commandClass); - //misc - int computePosDisplay(int x, int y); - void computeDisplay(); - void resetState(); - void mouseDownDisplayUnitSkills(int posDisplay); - void mouseDownDisplayUnitBuild(int posDisplay); - void computeInfoString(int posDisplay); - string computeDefaultInfoString(); - void addOrdersResultToConsole(CommandClass cc, std::pair result); - bool isSharedCommandClass(CommandClass commandClass); - void computeSelected(bool doubleCkick,bool force); - bool computeTarget(const Vec2i &screenPos, Vec2i &targetPos, const Unit *&targetUnit); - Unit* getRelevantObjectFromSelection(Selection::UnitContainer *uc); -}; + //misc + int computePosDisplay(int x, int y); + void computeDisplay(); + void resetState(); + void mouseDownDisplayUnitSkills(int posDisplay); + void mouseDownDisplayUnitBuild(int posDisplay); + void computeInfoString(int posDisplay); + string computeDefaultInfoString(); + void addOrdersResultToConsole(CommandClass cc, std::pair result); + bool isSharedCommandClass(CommandClass commandClass); + void computeSelected(bool doubleCkick, bool force); + bool computeTarget(const Vec2i &screenPos, Vec2i &targetPos, const Unit *&targetUnit); + Unit* getRelevantObjectFromSelection(Selection::UnitContainer *uc); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/gui/selection.cpp b/source/glest_game/gui/selection.cpp index 878099501..f0a2797fe 100644 --- a/source/glest_game/gui/selection.cpp +++ b/source/glest_game/gui/selection.cpp @@ -21,423 +21,424 @@ using namespace std; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class Selection -// ===================================================== + // ===================================================== + // class Selection + // ===================================================== -void Selection::init(Gui *gui, int factionIndex, int teamIndex, bool allowSharedTeamUnits) { - this->factionIndex = factionIndex; - this->teamIndex = teamIndex; - this->allowSharedTeamUnits = allowSharedTeamUnits; - this->gui = gui; - clear(); -} - -Selection::~Selection(){ - clear(); -} - -bool Selection::canSelectUnitFactionCheck(const Unit *unit) const { - //check if enemy - if(unit->getFactionIndex() != factionIndex) { - if(this->allowSharedTeamUnits == false || - unit->getFaction()->getTeam() != teamIndex) { - return false; + void Selection::init(Gui *gui, int factionIndex, int teamIndex, bool allowSharedTeamUnits) { + this->factionIndex = factionIndex; + this->teamIndex = teamIndex; + this->allowSharedTeamUnits = allowSharedTeamUnits; + this->gui = gui; + clear(); } - } - return true; -} + Selection::~Selection() { + clear(); + } -bool Selection::select(Unit *unit, bool addToSelection) { - bool result = false; - if((int)selectedUnits.size() >= Config::getInstance().getInt("MaxUnitSelectCount",intToStr(maxUnits).c_str())) { - return result; - } + bool Selection::canSelectUnitFactionCheck(const Unit *unit) const { + //check if enemy + if (unit->getFactionIndex() != factionIndex) { + if (this->allowSharedTeamUnits == false || + unit->getFaction()->getTeam() != teamIndex) { + return false; + } + } - // Fix Bug reported on sourceforge.net: Glest::Game::Selection::select crash with NULL pointer - ID: 3608835 - if(unit != NULL) { - //check if already selected - for(int index = 0; index < (int)selectedUnits.size(); ++index) { - if(selectedUnits[index] == unit) { + return true; + } + + bool Selection::select(Unit *unit, bool addToSelection) { + bool result = false; + if ((int) selectedUnits.size() >= Config::getInstance().getInt("MaxUnitSelectCount", intToStr(maxUnits).c_str())) { + return result; + } + + // Fix Bug reported on sourceforge.net: Glest::Game::Selection::select crash with NULL pointer - ID: 3608835 + if (unit != NULL) { + //check if already selected + for (int index = 0; index < (int) selectedUnits.size(); ++index) { + if (selectedUnits[index] == unit) { + return true; + } + } + + //check if dead + if (unit->isDead() == true) { + return false; + } + + //check if commandable + if (unit->getType()->isCommandable() == false && isEmpty() == false) { + return false; + } + + //check if multisel + if (unit->getType()->getMultiSelect() == false && isEmpty() == false) { + return false; + } + + //check if multitypesel + if (selectedUnits.size() > 0) { + bool isUnifromSelectOK = (selectedUnits.front()->getType() == unit->getType() && unit->isOperative() == selectedUnits.front()->isOperative()); + if (selectedUnits.front()->getType()->getUniformSelect() == true && !isUnifromSelectOK) { + if (addToSelection) + return false; + else + clear(); + } + + if (unit->getType()->getUniformSelect() == true + && !isUnifromSelectOK) { + return false; + } + } + + //check if enemy + if (canSelectUnitFactionCheck(unit) == false && isEmpty() == false) { + return false; + } + + //check existing enemy + //if(selectedUnits.size() == 1 && selectedUnits.front()->getFactionIndex() != factionIndex) { + if (selectedUnits.size() == 1 && canSelectUnitFactionCheck(selectedUnits.front()) == false) { + clear(); + } + + //check existing multisel + if (selectedUnits.size() == 1 && + selectedUnits.front()->getType()->getMultiSelect() == false) { + clear(); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] unit selected [%s]\n", __FILE__, __FUNCTION__, __LINE__, unit->toString().c_str()); + + unit->addObserver(this); + + int unitTypeId = unit->getType()->getId(); + bool inserted = false; + for (int index = 0; index < (int) selectedUnits.size(); ++index) { + + int currentTypeId = selectedUnits[index]->getType()->getId(); + if (unitTypeId <= currentTypeId) { + + //place unit here + selectedUnits.insert(selectedUnits.begin() + index, unit); + inserted = true; + break; + } + } + if (inserted == false) { + selectedUnits.push_back(unit); + } + result = true; + gui->onSelectionChanged(); + } + + return result; + } + + void Selection::select(const UnitContainer &units, bool addToSelection) { + + //add units to gui + for (UnitIterator it = units.begin(); it != units.end(); ++it) { + select(*it, addToSelection); + } + } + + void Selection::unSelect(const UnitContainer &units) { + + //add units to gui + for (UnitIterator it = units.begin(); it != units.end(); ++it) { + for (int i = 0; i < (int) selectedUnits.size(); ++i) { + if (selectedUnits[i] == *it) { + unSelect(i); + } + } + } + } + + void Selection::unSelect(int i) { + selectedUnits.erase(selectedUnits.begin() + i); + gui->onSelectionChanged(); + } + + void Selection::clear() { + selectedUnits.clear(); + } + + bool Selection::isUniform() const { + if (selectedUnits.empty() == true) { return true; } - } - //check if dead - if(unit->isDead() == true) { - return false; - } + const UnitType *ut = selectedUnits.front()->getType(); - //check if commandable - if(unit->getType()->isCommandable() == false && isEmpty() == false) { - return false; - } - - //check if multisel - if(unit->getType()->getMultiSelect() == false && isEmpty() == false) { - return false; - } - - //check if multitypesel - if(selectedUnits.size() > 0) { - bool isUnifromSelectOK = ( selectedUnits.front()->getType() == unit->getType() && unit->isOperative() == selectedUnits.front()->isOperative()); - if(selectedUnits.front()->getType()->getUniformSelect() == true && !isUnifromSelectOK ) { - if(addToSelection) + for (int i = 0; i < (int) selectedUnits.size(); ++i) { + if (selectedUnits[i]->getType() != ut) { return false; - else - clear(); + } + } + return true; + } + + bool Selection::isEnemy() const { + return selectedUnits.size() == 1 && + //selectedUnits.front()->getFactionIndex() != factionIndex; + canSelectUnitFactionCheck(selectedUnits.front()) == false; + } + + bool Selection::isObserver() const { + return selectedUnits.size() == 1 && + (teamIndex == (GameConstants::maxPlayers - 1 + fpt_Observer)); + } + + bool Selection::isCommandable() const { + //printf("\n\n\n\n********* selection.isCommandable() ---> isEmpty() [%d] isEnemy() [%d] selectedUnits.size() [%d]\n\n",isEmpty(),isEnemy(),(int)selectedUnits.size()); + + return + isEmpty() == false && + isEnemy() == false && + (selectedUnits.size() == 1 && selectedUnits.front()->isAlive() == false) == false && + selectedUnits.front()->getType()->isCommandable(); + } + + bool Selection::isCancelable() const { + return + selectedUnits.size() > 1 || + (selectedUnits.size() == 1 && selectedUnits[0]->anyCommand(true)); + } + + bool Selection::isMeetable() const { + return + isUniform() && + isCommandable() && + selectedUnits.front()->getType()->getMeetingPoint(); + } + + Vec3f Selection::getRefPos() const { + return getFrontUnit()->getCurrMidHeightVector(); + } + + bool Selection::hasUnit(const Unit* unit) const { + return find(selectedUnits.begin(), selectedUnits.end(), unit) != selectedUnits.end(); + } + + bool Selection::assignGroup(int groupIndex, bool clearGroup, const UnitContainer *pUnits) { + if (groupIndex < 0 || groupIndex >= maxGroups) { + throw megaglest_runtime_error("Invalid value for groupIndex = " + intToStr(groupIndex)); } - if (unit->getType()->getUniformSelect() == true - && !isUnifromSelectOK ) { + //clear group + if (true == clearGroup) { + groups[groupIndex].clear(); + } + + //assign new group + const UnitContainer *addUnits = &selectedUnits; + if (pUnits != NULL) { + addUnits = pUnits; + } + + for (unsigned int i = 0; i < addUnits->size(); ++i) { + if (false == addUnitToGroup(groupIndex, (*addUnits)[i])) { + // don't try to add more, group is maybe full + return false; + } + } + return true; + } + + /** + * returns false if unit cannot be added + */ + bool Selection::addUnitToGroup(int groupIndex, Unit *unit) { + if (groupIndex < 0 || groupIndex >= maxGroups) { + throw megaglest_runtime_error("Invalid value for groupIndex = " + intToStr(groupIndex)); + } + bool alreadyExists = false; + bool groupIsFull = (int) groups[groupIndex].size() >= Config::getInstance().getInt("MaxUnitSelectCount", intToStr(maxUnits).c_str()); + + for (int i = 0; i < (int) groups[groupIndex].size(); ++i) { + if (groups[groupIndex][i] == unit) { + alreadyExists = true; + break; + } + } + + if (alreadyExists) { + return true; + } + + // check for non Multiselect units + if ((int) groups[groupIndex].size() > 0) { + if (!unit->getType()->getMultiSelect()) { + //dont add single selection units to already filled group + return false; + } + Unit* unitInGroup = groups[groupIndex][0]; + if (!unitInGroup->getType()->getMultiSelect()) { + //dont add a unit to a group which has a single selection unit + return false; + } + } + + // check for uniformselect units + if ((int) groups[groupIndex].size() > 0) { + Unit* unitInGroup = groups[groupIndex][0]; + if (unit->getType()->getUniformSelect() || unitInGroup->getType()->getUniformSelect()) { + if (unit->isOperative() != unitInGroup->isOperative()) { + //dont add units that are not in same operative state + return false; + } + if (unitInGroup->getType() != unit->getType()) { + //dont add another unit to a group of uniform selection units + return false; + } + } + } + + if (unit != NULL && !groupIsFull) { + groups[groupIndex].push_back(unit); + return true; + } else { return false; } } - //check if enemy - if(canSelectUnitFactionCheck(unit) == false && isEmpty() == false) { - return false; - } - - //check existing enemy - //if(selectedUnits.size() == 1 && selectedUnits.front()->getFactionIndex() != factionIndex) { - if(selectedUnits.size() == 1 && canSelectUnitFactionCheck(selectedUnits.front()) == false) { - clear(); - } - - //check existing multisel - if(selectedUnits.size() == 1 && - selectedUnits.front()->getType()->getMultiSelect() == false) { - clear(); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unit selected [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str()); - - unit->addObserver(this); - - int unitTypeId = unit->getType()->getId(); - bool inserted = false; - for(int index = 0; index < (int)selectedUnits.size(); ++index) { - - int currentTypeId = selectedUnits[index]->getType()->getId(); - if(unitTypeId <= currentTypeId) { - - //place unit here - selectedUnits.insert(selectedUnits.begin() + index,unit); - inserted = true; - break; + void Selection::removeUnitFromGroup(int groupIndex, int unitId) { + if (groupIndex < 0 || groupIndex >= maxGroups) { + throw megaglest_runtime_error("Invalid value for groupIndex = " + intToStr(groupIndex)); } - } - if(inserted == false) { - selectedUnits.push_back(unit); - } - result = true; - gui->onSelectionChanged(); - } - return result; -} - -void Selection::select(const UnitContainer &units, bool addToSelection){ - - //add units to gui - for(UnitIterator it = units.begin(); it != units.end(); ++it) { - select(*it,addToSelection); - } -} - -void Selection::unSelect(const UnitContainer &units) { - - //add units to gui - for(UnitIterator it = units.begin(); it != units.end(); ++it) { - for(int i = 0; i < (int)selectedUnits.size(); ++i) { - if(selectedUnits[i] == *it) { - unSelect(i); - } - } - } -} - -void Selection::unSelect(int i) { - selectedUnits.erase(selectedUnits.begin() + i); - gui->onSelectionChanged(); -} - -void Selection::clear(){ - selectedUnits.clear(); -} - -bool Selection::isUniform() const{ - if(selectedUnits.empty() == true) { - return true; - } - - const UnitType *ut= selectedUnits.front()->getType(); - - for(int i = 0; i < (int)selectedUnits.size(); ++i) { - if(selectedUnits[i]->getType() != ut) { - return false; - } - } - return true; -} - -bool Selection::isEnemy() const { - return selectedUnits.size() == 1 && - //selectedUnits.front()->getFactionIndex() != factionIndex; - canSelectUnitFactionCheck(selectedUnits.front()) == false; -} - -bool Selection::isObserver() const { - return selectedUnits.size() == 1 && - (teamIndex == (GameConstants::maxPlayers -1 + fpt_Observer)); -} - -bool Selection::isCommandable() const { - //printf("\n\n\n\n********* selection.isCommandable() ---> isEmpty() [%d] isEnemy() [%d] selectedUnits.size() [%d]\n\n",isEmpty(),isEnemy(),(int)selectedUnits.size()); - - return - isEmpty() == false && - isEnemy() == false && - (selectedUnits.size() == 1 && selectedUnits.front()->isAlive() == false) == false && - selectedUnits.front()->getType()->isCommandable(); -} - -bool Selection::isCancelable() const { - return - selectedUnits.size() > 1 || - (selectedUnits.size() == 1 && selectedUnits[0]->anyCommand(true)); -} - -bool Selection::isMeetable() const{ - return - isUniform() && - isCommandable() && - selectedUnits.front()->getType()->getMeetingPoint(); -} - -Vec3f Selection::getRefPos() const{ - return getFrontUnit()->getCurrMidHeightVector(); -} - -bool Selection::hasUnit(const Unit* unit) const { - return find(selectedUnits.begin(), selectedUnits.end(), unit) != selectedUnits.end(); -} - -bool Selection::assignGroup(int groupIndex, bool clearGroup,const UnitContainer *pUnits) { - if(groupIndex < 0 || groupIndex >= maxGroups) { - throw megaglest_runtime_error("Invalid value for groupIndex = " + intToStr(groupIndex)); - } - - //clear group - if(true==clearGroup){ - groups[groupIndex].clear(); - } - - //assign new group - const UnitContainer *addUnits = &selectedUnits; - if(pUnits != NULL) { - addUnits = pUnits; - } - - for(unsigned int i = 0; i < addUnits->size(); ++i) { - if(false == addUnitToGroup(groupIndex,(*addUnits)[i])){ - // don't try to add more, group is maybe full - return false; - } - } - return true; -} - -/** - * returns false if unit cannot be added - */ -bool Selection::addUnitToGroup(int groupIndex,Unit *unit) { - if(groupIndex < 0 || groupIndex >= maxGroups) { - throw megaglest_runtime_error("Invalid value for groupIndex = " + intToStr(groupIndex)); - } - bool alreadyExists=false; - bool groupIsFull=(int)groups[groupIndex].size() >= Config::getInstance().getInt("MaxUnitSelectCount",intToStr(maxUnits).c_str()); - - for(int i = 0; i < (int)groups[groupIndex].size(); ++i) { - if(groups[groupIndex][i] == unit) { - alreadyExists=true; - break; - } - } - - if(alreadyExists){ - return true; - } - - // check for non Multiselect units - if((int)groups[groupIndex].size()>0 ){ - if( !unit->getType()->getMultiSelect()){ - //dont add single selection units to already filled group - return false; - } - Unit* unitInGroup=groups[groupIndex][0]; - if( !unitInGroup->getType()->getMultiSelect()){ - //dont add a unit to a group which has a single selection unit - return false; - } - } - - // check for uniformselect units - if((int)groups[groupIndex].size()>0 ) { - Unit* unitInGroup=groups[groupIndex][0]; - if( unit->getType()->getUniformSelect() || unitInGroup->getType()->getUniformSelect() ) { - if( unit->isOperative() != unitInGroup->isOperative()) { - //dont add units that are not in same operative state - return false; - } - if( unitInGroup->getType() != unit->getType()){ - //dont add another unit to a group of uniform selection units - return false; - } - } - } - - if(unit != NULL && !groupIsFull) { - groups[groupIndex].push_back(unit); - return true; - } - else{ - return false; - } -} - -void Selection::removeUnitFromGroup(int groupIndex,int unitId) { - if(groupIndex < 0 || groupIndex >= maxGroups) { - throw megaglest_runtime_error("Invalid value for groupIndex = " + intToStr(groupIndex)); - } - - for(unsigned int i = 0; i < groups[groupIndex].size(); ++i) { - Unit *unit = groups[groupIndex][i]; - if(unit != NULL && unit->getId() == unitId) { - groups[groupIndex].erase(groups[groupIndex].begin() + i); - break; - } - } -} - -//vector Selection::getUnitsForGroup(int groupIndex) { -// if(groupIndex < 0 || groupIndex >= maxGroups) { -// throw megaglest_runtime_error("Invalid value for groupIndex = " + intToStr(groupIndex)); -// } -// return groups[groupIndex]; -//} - -void Selection::recallGroup(int groupIndex,bool clearSelection){ - if(groupIndex < 0 || groupIndex >= maxGroups) { - throw megaglest_runtime_error("Invalid value for groupIndex = " + intToStr(groupIndex)); - } - - if(clearSelection==true){ - clear(); - } - for(int i = 0; i < (int)groups[groupIndex].size(); ++i) { - select(groups[groupIndex][i],!clearSelection); - } -} - -void Selection::unitEvent(UnitObserver::Event event, const Unit *unit) { - - if(event == UnitObserver::eKill) { - - //remove from selection - for(int index = 0; index < (int)selectedUnits.size(); ++index) { - if(selectedUnits[index] == unit){ - selectedUnits.erase(selectedUnits.begin() + index); - break; - } - } - - //remove from groups - for(int index = 0; index < maxGroups; ++index) { - for(int index2 = 0; index2 < (int)groups[index].size(); ++index2) { - if(groups[index][index2] == unit) { - groups[index].erase(groups[index].begin() + index2); + for (unsigned int i = 0; i < groups[groupIndex].size(); ++i) { + Unit *unit = groups[groupIndex][i]; + if (unit != NULL && unit->getId() == unitId) { + groups[groupIndex].erase(groups[groupIndex].begin() + i); break; } } } - //notify gui only if no more units to execute the command - //of course the selection changed, but this doesn't matter in this case. - if( selectedUnits.empty() == true) { - gui->onSelectionChanged(); + //vector Selection::getUnitsForGroup(int groupIndex) { + // if(groupIndex < 0 || groupIndex >= maxGroups) { + // throw megaglest_runtime_error("Invalid value for groupIndex = " + intToStr(groupIndex)); + // } + // return groups[groupIndex]; + //} + + void Selection::recallGroup(int groupIndex, bool clearSelection) { + if (groupIndex < 0 || groupIndex >= maxGroups) { + throw megaglest_runtime_error("Invalid value for groupIndex = " + intToStr(groupIndex)); + } + + if (clearSelection == true) { + clear(); + } + for (int i = 0; i < (int) groups[groupIndex].size(); ++i) { + select(groups[groupIndex][i], !clearSelection); + } } - } -} -void Selection::saveGame(XmlNode *rootNode) const { + void Selection::unitEvent(UnitObserver::Event event, const Unit *unit) { - std::map mapTagReplacements; - XmlNode *selectionNode = rootNode->addChild("Selection"); + if (event == UnitObserver::eKill) { - selectionNode->addAttribute("factionIndex",intToStr(factionIndex), mapTagReplacements); - selectionNode->addAttribute("teamIndex",intToStr(teamIndex), mapTagReplacements); - selectionNode->addAttribute("allowSharedTeamUnits",intToStr(allowSharedTeamUnits), mapTagReplacements); + //remove from selection + for (int index = 0; index < (int) selectedUnits.size(); ++index) { + if (selectedUnits[index] == unit) { + selectedUnits.erase(selectedUnits.begin() + index); + break; + } + } - for(unsigned int i = 0; i < selectedUnits.size(); i++) { - Unit *unit = selectedUnits[i]; + //remove from groups + for (int index = 0; index < maxGroups; ++index) { + for (int index2 = 0; index2 < (int) groups[index].size(); ++index2) { + if (groups[index][index2] == unit) { + groups[index].erase(groups[index].begin() + index2); + break; + } + } + } - XmlNode *selectedUnitsNode = selectionNode->addChild("selectedUnits"); - selectedUnitsNode->addAttribute("unitId",intToStr(unit->getId()), mapTagReplacements); - } - - for(unsigned int x = 0; x < (unsigned int)maxGroups; ++x) { - XmlNode *groupsNode = selectionNode->addChild("groups"); - for(unsigned int i = 0; i < (unsigned int)groups[x].size(); ++i) { - Unit *unit = groups[x][i]; - - XmlNode *selectedUnitsNode = groupsNode->addChild("selectedUnits"); - selectedUnitsNode->addAttribute("unitId",intToStr(unit->getId()), mapTagReplacements); + //notify gui only if no more units to execute the command + //of course the selection changed, but this doesn't matter in this case. + if (selectedUnits.empty() == true) { + gui->onSelectionChanged(); + } + } } - } -} -void Selection::loadGame(const XmlNode *rootNode, World *world) { + void Selection::saveGame(XmlNode *rootNode) const { - const XmlNode *selectionNode = rootNode->getChild("Selection"); + std::map mapTagReplacements; + XmlNode *selectionNode = rootNode->addChild("Selection"); - factionIndex = selectionNode->getAttribute("factionIndex")->getIntValue(); - teamIndex = selectionNode->getAttribute("teamIndex")->getIntValue(); - if(selectionNode->hasAttribute("allowSharedTeamUnits") == true) { - allowSharedTeamUnits = (selectionNode->getAttribute("allowSharedTeamUnits")->getIntValue() != 0); - } + selectionNode->addAttribute("factionIndex", intToStr(factionIndex), mapTagReplacements); + selectionNode->addAttribute("teamIndex", intToStr(teamIndex), mapTagReplacements); + selectionNode->addAttribute("allowSharedTeamUnits", intToStr(allowSharedTeamUnits), mapTagReplacements); - vector selectedUnitsNodeList = selectionNode->getChildList("selectedUnits"); - for(unsigned int i = 0; i < selectedUnitsNodeList.size(); ++i) { - XmlNode *selectedUnitsNode = selectedUnitsNodeList[i]; + for (unsigned int i = 0; i < selectedUnits.size(); i++) { + Unit *unit = selectedUnits[i]; - int unitId = selectedUnitsNode->getAttribute("unitId")->getIntValue(); - Unit *unit = world->findUnitById(unitId); - //assert(unit != NULL); - //printf("#1 Unit [%s], group: %d\n",unit->getType()->getName().c_str(),i); - selectedUnits.push_back(unit); - } + XmlNode *selectedUnitsNode = selectionNode->addChild("selectedUnits"); + selectedUnitsNode->addAttribute("unitId", intToStr(unit->getId()), mapTagReplacements); + } - vector groupsNodeList = selectionNode->getChildList("groups"); - for(unsigned int i = 0; i < groupsNodeList.size(); ++i) { - XmlNode *groupsNode = groupsNodeList[i]; + for (unsigned int x = 0; x < (unsigned int) maxGroups; ++x) { + XmlNode *groupsNode = selectionNode->addChild("groups"); + for (unsigned int i = 0; i < (unsigned int) groups[x].size(); ++i) { + Unit *unit = groups[x][i]; - vector selectedGroupsUnitsNodeList = groupsNode->getChildList("selectedUnits"); - for(unsigned int j = 0; j < selectedGroupsUnitsNodeList.size(); ++j) { - XmlNode *selectedGroupsUnitsNode = selectedGroupsUnitsNodeList[j]; - - int unitId = selectedGroupsUnitsNode->getAttribute("unitId")->getIntValue(); - Unit *unit = world->findUnitById(unitId); - //assert(unit != NULL); - //printf("Unit #2 [%s], group: %d\n",unit->getType()->getName().c_str(),i); - groups[i].push_back(unit); + XmlNode *selectedUnitsNode = groupsNode->addChild("selectedUnits"); + selectedUnitsNode->addAttribute("unitId", intToStr(unit->getId()), mapTagReplacements); + } + } } + + void Selection::loadGame(const XmlNode *rootNode, World *world) { + + const XmlNode *selectionNode = rootNode->getChild("Selection"); + + factionIndex = selectionNode->getAttribute("factionIndex")->getIntValue(); + teamIndex = selectionNode->getAttribute("teamIndex")->getIntValue(); + if (selectionNode->hasAttribute("allowSharedTeamUnits") == true) { + allowSharedTeamUnits = (selectionNode->getAttribute("allowSharedTeamUnits")->getIntValue() != 0); + } + + vector selectedUnitsNodeList = selectionNode->getChildList("selectedUnits"); + for (unsigned int i = 0; i < selectedUnitsNodeList.size(); ++i) { + XmlNode *selectedUnitsNode = selectedUnitsNodeList[i]; + + int unitId = selectedUnitsNode->getAttribute("unitId")->getIntValue(); + Unit *unit = world->findUnitById(unitId); + //assert(unit != NULL); + //printf("#1 Unit [%s], group: %d\n",unit->getType()->getName().c_str(),i); + selectedUnits.push_back(unit); + } + + vector groupsNodeList = selectionNode->getChildList("groups"); + for (unsigned int i = 0; i < groupsNodeList.size(); ++i) { + XmlNode *groupsNode = groupsNodeList[i]; + + vector selectedGroupsUnitsNodeList = groupsNode->getChildList("selectedUnits"); + for (unsigned int j = 0; j < selectedGroupsUnitsNodeList.size(); ++j) { + XmlNode *selectedGroupsUnitsNode = selectedGroupsUnitsNodeList[j]; + + int unitId = selectedGroupsUnitsNode->getAttribute("unitId")->getIntValue(); + Unit *unit = world->findUnitById(unitId); + //assert(unit != NULL); + //printf("Unit #2 [%s], group: %d\n",unit->getType()->getName().c_str(),i); + groups[i].push_back(unit); + } + } + } + + } -} - - -}}//end namespace +}//end namespace diff --git a/source/glest_game/gui/selection.h b/source/glest_game/gui/selection.h index b305df8f9..9e83b40fd 100644 --- a/source/glest_game/gui/selection.h +++ b/source/glest_game/gui/selection.h @@ -13,8 +13,8 @@ #define _GLEST_GAME_SELECTION_ #ifdef WIN32 - #include - #include +#include +#include #endif #include "unit.h" @@ -23,87 +23,99 @@ using std::vector; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -class Gui; -class World; + class Gui; + class World; -class HighlightSpecialUnitInfo { -public: - float radius; - float thickness; - Vec4f color; -}; + class HighlightSpecialUnitInfo { + public: + float radius; + float thickness; + Vec4f color; + }; -// ===================================================== -// class Selection -// -/// List of selected units and groups -// ===================================================== + // ===================================================== + // class Selection + // + /// List of selected units and groups + // ===================================================== -class Selection: public UnitObserver { -public: - typedef vector UnitContainer; - typedef UnitContainer::const_iterator UnitIterator; + class Selection : public UnitObserver { + public: + typedef vector UnitContainer; + typedef UnitContainer::const_iterator UnitIterator; -public: - static const int maxGroups = 10; - static const int maxUnits = 36; + public: + static const int maxGroups = 10; + static const int maxUnits = 36; -private: - int factionIndex; - int teamIndex; - bool allowSharedTeamUnits; - UnitContainer selectedUnits; - UnitContainer groups[maxGroups]; - Gui *gui; + private: + int factionIndex; + int teamIndex; + bool allowSharedTeamUnits; + UnitContainer selectedUnits; + UnitContainer groups[maxGroups]; + Gui *gui; + + public: + Selection() : UnitObserver() { + factionIndex = 0; + teamIndex = 0; + allowSharedTeamUnits = false; + gui = NULL; + } + void init(Gui *gui, int factionIndex, int teamIndex, bool allowSharedTeamUnits); + virtual ~Selection(); + + bool select(Unit *unit, bool addToSelection); + void select(const UnitContainer &units, bool addToSelection); + void unSelect(const UnitContainer &units); + void unSelect(int unitIndex); + void clear(); + + bool isEmpty() const { + return selectedUnits.empty(); + } + bool isUniform() const; + bool isEnemy() const; + bool isObserver() const; + + bool isCommandable() const; + bool isCancelable() const; + bool isMeetable() const; + int getCount() const { + return (int) selectedUnits.size(); + } + const Unit *getUnit(int i) const { + return selectedUnits[i]; + } + Unit *getUnitPtr(int i) { + return selectedUnits[i]; + } + const Unit *getFrontUnit() const { + return selectedUnits.front(); + } + Vec3f getRefPos() const; + bool hasUnit(const Unit* unit) const; + + bool assignGroup(int groupIndex, bool clearGroup = true, const UnitContainer *pUnits = NULL); + bool addUnitToGroup(int groupIndex, Unit *unit); + void removeUnitFromGroup(int groupIndex, int UnitId); + void recallGroup(int groupIndex, bool clearSelection = true); + + //vector getUnitsForGroup(int groupIndex); + + virtual void unitEvent(UnitObserver::Event event, const Unit *unit); + bool canSelectUnitFactionCheck(const Unit *unit) const; + + virtual void saveGame(XmlNode *rootNode) const; + void loadGame(const XmlNode *rootNode, World *world); + + }; -public: - Selection() : UnitObserver() { - factionIndex = 0; - teamIndex = 0; - allowSharedTeamUnits = false; - gui = NULL; } - void init(Gui *gui, int factionIndex, int teamIndex, bool allowSharedTeamUnits); - virtual ~Selection(); - - bool select(Unit *unit, bool addToSelection); - void select(const UnitContainer &units, bool addToSelection); - void unSelect(const UnitContainer &units); - void unSelect(int unitIndex); - void clear(); - - bool isEmpty() const {return selectedUnits.empty();} - bool isUniform() const; - bool isEnemy() const; - bool isObserver() const; - - bool isCommandable() const; - bool isCancelable() const; - bool isMeetable() const; - int getCount() const {return (int)selectedUnits.size();} - const Unit *getUnit(int i) const {return selectedUnits[i];} - Unit *getUnitPtr(int i) {return selectedUnits[i];} - const Unit *getFrontUnit() const {return selectedUnits.front();} - Vec3f getRefPos() const; - bool hasUnit(const Unit* unit) const; - - bool assignGroup(int groupIndex, bool clearGroup=true, const UnitContainer *pUnits=NULL); - bool addUnitToGroup(int groupIndex,Unit *unit); - void removeUnitFromGroup(int groupIndex,int UnitId); - void recallGroup(int groupIndex, bool clearSelection=true); - - //vector getUnitsForGroup(int groupIndex); - - virtual void unitEvent(UnitObserver::Event event, const Unit *unit); - bool canSelectUnitFactionCheck(const Unit *unit) const; - - virtual void saveGame(XmlNode *rootNode) const; - void loadGame(const XmlNode *rootNode, World *world); - -}; - -}}//end namespace +}//end namespace #endif diff --git a/source/glest_game/main/battle_end.cpp b/source/glest_game/main/battle_end.cpp index 94c8355cc..315edaf1d 100644 --- a/source/glest_game/main/battle_end.cpp +++ b/source/glest_game/main/battle_end.cpp @@ -29,1125 +29,959 @@ #include "leak_dumper.h" using namespace - Shared::Util; - -namespace Glest -{ - namespace Game - { - -// ===================================================== -// class BattleEnd -// ===================================================== - - BattleEnd::BattleEnd (Program * program, const Stats * stats, - ProgramState * originState): - ProgramState (program), - menuBackgroundVideo (NULL), - gameSettings (NULL) - { - - containerName = "BattleEnd"; - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d] stats = %p\n", __FILE__, - __FUNCTION__, __LINE__, stats); - - this->originState = originState; - if (stats != NULL) - { - this->stats = *stats; - } - if (originState != NULL) - { - Game * - game = dynamic_cast < Game * >(originState); - if (game != NULL) - { - gameSettings = new GameSettings (); - *gameSettings = *(game->getGameSettings ()); - } - } - mouseX = 0; - mouseY = 0; - mouse2d = 0; - renderToTexture = NULL; - renderToTextureCount = 0; - - const - Metrics & - metrics = Metrics::getInstance (); - Lang & lang = Lang::getInstance (); - int - buttonWidth = 125; - int - xLocation = (metrics.getVirtualW () / 2) - (buttonWidth / 2); - buttonExit.init (xLocation, 80, buttonWidth); - buttonExit.setText (lang.getString ("Exit")); - -//mesage box - mainMessageBox.init (lang.getString ("Yes"), lang.getString ("No")); - mainMessageBox.setEnabled (false); - - SystemFlags::OutputDebug (SystemFlags::debugSystem, "In [%s::%s %d]\n", - __FILE__, __FUNCTION__, __LINE__); - - initBackgroundVideo (); - initBackgroundMusic (); - - GraphicComponent::applyAllCustomProperties (containerName); - } - - void - BattleEnd::reloadUI () - { - Lang & lang = Lang::getInstance (); - - buttonExit.setText (lang.getString ("Exit")); - mainMessageBox.init (lang.getString ("Yes"), lang.getString ("No")); - - GraphicComponent::reloadFontsForRegisterGraphicComponents - (containerName); - } - - BattleEnd::~BattleEnd () - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, "In [%s::%s %d]\n", - __FILE__, __FUNCTION__, __LINE__); - - if (menuBackgroundVideo != NULL) - { - menuBackgroundVideo->closePlayer (); - delete menuBackgroundVideo; - menuBackgroundVideo = NULL; - } - - delete gameSettings; - gameSettings = NULL; - - delete originState; - originState = NULL; - - if (CoreData::getInstance ().hasMainMenuVideoFilename () == false) - { - SoundRenderer::getInstance (). - playMusic (CoreData::getInstance ().getMenuMusic ()); - } - - SystemFlags::OutputDebug (SystemFlags::debugSystem, "In [%s::%s %d]\n", - __FILE__, __FUNCTION__, __LINE__); - - delete renderToTexture; - renderToTexture = NULL; - - SystemFlags::OutputDebug (SystemFlags::debugSystem, "In [%s::%s %d]\n", - __FILE__, __FUNCTION__, __LINE__); - } - - std::pair < string, string > BattleEnd::getBattleEndVideo (bool won) - { - std::pair < string, string > result; - - string factionVideoUrl = ""; - string factionVideoUrlFallback = ""; - - if (gameSettings != NULL) - { - string currentTechName_factionPreview = gameSettings->getTech (); - string - currentFactionName_factionPreview = - gameSettings->getFactionTypeName (stats.getThisFactionIndex ()); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#1 tech [%s] faction [%s] won = %d\n", - currentTechName_factionPreview.c_str (), - currentFactionName_factionPreview.c_str (), won); - - string - factionDefinitionXML = - Game::findFactionLogoFile (gameSettings, NULL, - currentFactionName_factionPreview + - ".xml"); - if (factionDefinitionXML != "" - && currentFactionName_factionPreview != - GameConstants::RANDOMFACTION_SLOTNAME - && currentFactionName_factionPreview != - GameConstants::OBSERVER_SLOTNAME - && fileExists (factionDefinitionXML) == true) - { - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#2 tech [%s] faction [%s]\n", - currentTechName_factionPreview.c_str (), - currentFactionName_factionPreview.c_str ()); - - XmlTree xmlTree; - std::map < string, string > mapExtraTagReplacementValues; - xmlTree.load (factionDefinitionXML, - Properties::getTagReplacementValues - (&mapExtraTagReplacementValues)); - const XmlNode * - factionNode = xmlTree.getRootNode (); - if (won == true) - { - if (factionNode->hasAttribute ("battle-end-win-video") == true) - { - factionVideoUrl = - factionNode-> - getAttribute ("battle-end-win-video")->getValue (); - } - } - else - { - if (factionNode->hasAttribute ("battle-end-lose-video") == true) - { - factionVideoUrl = - factionNode-> - getAttribute ("battle-end-lose-video")->getValue (); - } - } - - if (factionVideoUrl != "" && fileExists (factionVideoUrl) == false) - { - string techTreePath = ""; - string factionPath = ""; - std::vector < std::string > factionPartsList; - Tokenize (factionDefinitionXML, factionPartsList, "factions/"); - if (factionPartsList.size () > 1) - { - techTreePath = factionPartsList[0]; - - string - factionPath = - techTreePath + "factions/" + - currentFactionName_factionPreview; - endPathWithSlash (factionPath); - factionVideoUrl = factionPath + factionVideoUrl; - } - } - - if (won == true) - { - factionVideoUrlFallback = - Game::findFactionLogoFile (gameSettings, NULL, - "battle_end_win_video.*"); - } - else - { - factionVideoUrlFallback = - Game::findFactionLogoFile (gameSettings, NULL, - "battle_end_lose_video.*"); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#3 factionVideoUrl [%s] factionVideoUrlFallback [%s]\n", - factionVideoUrl.c_str (), - factionVideoUrlFallback.c_str ()); -//printf("#3 factionVideoUrl [%s] factionVideoUrlFallback [%s]\n",factionVideoUrl.c_str(),factionVideoUrlFallback.c_str()); - - if (factionVideoUrl == "") - { - factionVideoUrl = factionVideoUrlFallback; - factionVideoUrlFallback = ""; - } - } -//printf("currentFactionName_factionPreview [%s] random [%s] observer [%s] factionVideoUrl [%s]\n",currentFactionName_factionPreview.c_str(),GameConstants::RANDOMFACTION_SLOTNAME,GameConstants::OBSERVER_SLOTNAME,factionVideoUrl.c_str()); - } - - if (factionVideoUrl != "") - { - result.first = factionVideoUrl; - result.second = factionVideoUrlFallback; - } - else - { - result.first = - CoreData::getInstance ().getBattleEndVideoFilename (won); - result.second = - CoreData::getInstance ().getBattleEndVideoFilenameFallback (won); - } - - return result; - } - - string BattleEnd::getBattleEndMusic (bool won) - { - string result = ""; - string resultFallback = ""; - - if (gameSettings != NULL) - { - string currentTechName_factionPreview = gameSettings->getTech (); - string - currentFactionName_factionPreview = - gameSettings->getFactionTypeName (stats.getThisFactionIndex ()); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#1 tech [%s] faction [%s] won = %d\n", - currentTechName_factionPreview.c_str (), - currentFactionName_factionPreview.c_str (), won); - - string - factionDefinitionXML = - Game::findFactionLogoFile (gameSettings, NULL, - currentFactionName_factionPreview + - ".xml"); - if (factionDefinitionXML != "" - && currentFactionName_factionPreview != - GameConstants::RANDOMFACTION_SLOTNAME - && currentFactionName_factionPreview != - GameConstants::OBSERVER_SLOTNAME - && fileExists (factionDefinitionXML) == true) - { - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#2 tech [%s] faction [%s]\n", - currentTechName_factionPreview.c_str (), - currentFactionName_factionPreview.c_str ()); - - XmlTree xmlTree; - std::map < string, string > mapExtraTagReplacementValues; - xmlTree.load (factionDefinitionXML, - Properties::getTagReplacementValues - (&mapExtraTagReplacementValues)); - const XmlNode * - factionNode = xmlTree.getRootNode (); - if (won == true) - { - if (factionNode->hasAttribute ("battle-end-win-music") == true) - { - result = - factionNode-> - getAttribute ("battle-end-win-music")->getValue (); - } - } - else - { - if (factionNode->hasAttribute ("battle-end-lose-music") == true) - { - result = - factionNode-> - getAttribute ("battle-end-lose-music")->getValue (); - } - } - - if (result != "" && fileExists (result) == false) - { - string techTreePath = ""; - string factionPath = ""; - std::vector < std::string > factionPartsList; - Tokenize (factionDefinitionXML, factionPartsList, "factions/"); - if (factionPartsList.size () > 1) - { - techTreePath = factionPartsList[0]; - - string - factionPath = - techTreePath + "factions/" + - currentFactionName_factionPreview; - endPathWithSlash (factionPath); - result = factionPath + result; - } - } - - if (won == true) - { - resultFallback = - Game::findFactionLogoFile (gameSettings, NULL, - "battle_end_win_music.*"); - } - else - { - resultFallback = - Game::findFactionLogoFile (gameSettings, NULL, - "battle_end_lose_music.*"); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#3 result [%s] resultFallback [%s]\n", result.c_str (), - resultFallback.c_str ()); -//printf("#3 result [%s] resultFallback [%s]\n",result.c_str(),resultFallback.c_str()); - - if (result == "") - { - result = resultFallback; - } - } -//printf("currentFactionName_factionPreview [%s] random [%s] observer [%s] factionVideoUrl [%s]\n",currentFactionName_factionPreview.c_str(),GameConstants::RANDOMFACTION_SLOTNAME,GameConstants::OBSERVER_SLOTNAME,factionVideoUrl.c_str()); - } - - if (result == "") - { - result = CoreData::getInstance ().getBattleEndMusicFilename (won); - } - - return result; - } - - void - BattleEnd::initBackgroundMusic () - { - string music = ""; - - if (stats.getThisFactionIndex () >= 0 - && stats.getTeam (stats.getThisFactionIndex ()) != - GameConstants::maxPlayers - 1 + fpt_Observer) - { - if (stats.getVictory (stats.getThisFactionIndex ())) - { -//header += lang.getString("Victory"); - music = getBattleEndMusic (true); - } - else - { -//header += lang.getString("Defeat"); - music = getBattleEndMusic (false); - } - - if (music != "" && fileExists (music) == true) - { - printf ("music [%s] \n", music.c_str ()); - - battleEndMusic.open (music); - battleEndMusic.setNext (&battleEndMusic); - - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - soundRenderer.playMusic (&battleEndMusic); - } - } - } - - void - BattleEnd::initBackgroundVideo () - { - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false - &&::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer () == true) - { - - if (menuBackgroundVideo != NULL) - { - menuBackgroundVideo->closePlayer (); - delete menuBackgroundVideo; - menuBackgroundVideo = NULL; - } - - string videoFile = ""; - string videoFileFallback = ""; - - if (stats.getThisFactionIndex () >= 0 - && stats.getTeam (stats.getThisFactionIndex ()) != - GameConstants::maxPlayers - 1 + fpt_Observer) - { - if (stats.getVictory (stats.getThisFactionIndex ())) - { -//header += lang.getString("Victory"); - -//videoFile = CoreData::getInstance().getBattleEndVideoFilename(true); -//videoFileFallback = CoreData::getInstance().getBattleEndVideoFilenameFallback(true); - std::pair < string, string > wonVideos = getBattleEndVideo (true); - videoFile = wonVideos.first; - videoFileFallback = wonVideos.second; - } - else - { -//header += lang.getString("Defeat"); -//videoFile = CoreData::getInstance().getBattleEndVideoFilename(false); -//videoFileFallback = CoreData::getInstance().getBattleEndVideoFilenameFallback(false); - std::pair < string, string > lostVideos = - getBattleEndVideo (false); - videoFile = lostVideos.first; - videoFileFallback = lostVideos.second; - } - } - else - { -//header += "Observer"; - } - - if (fileExists (videoFile) || fileExists (videoFileFallback)) - { - printf ("videoFile [%s] videoFileFallback [%s]\n", - videoFile.c_str (), videoFileFallback.c_str ()); - - Context * - c = GraphicsInterface::getInstance ().getCurrentContext (); - PlatformContextGl * - glCtx = - static_cast < ContextGl * >(c)->getPlatformContextGlPtr (); - SDL_Window * - window = glCtx->getScreenWindow (); - SDL_Surface * - screen = glCtx->getScreenSurface (); - - string - vlcPluginsPath = - Config::getInstance ().getString ("VideoPlayerPluginsPath", ""); -//printf("screen->w = %d screen->h = %d screen->format->BitsPerPixel = %d\n",screen->w,screen->h,screen->format->BitsPerPixel); - menuBackgroundVideo = new VideoPlayer (&Renderer::getInstance (), - videoFile, - videoFileFallback, - window, - 0, 0, - screen->w, - screen->h, - screen->format->BitsPerPixel, - true, - vlcPluginsPath, - SystemFlags::VERBOSE_MODE_ENABLED); - menuBackgroundVideo->initPlayer (); - } - } - } - - void - BattleEnd::update () - { - if (Config::getInstance ().getBool ("AutoTest")) - { - AutoTest::getInstance ().updateBattleEnd (program); - return; - } - mouse2d = (mouse2d + 1) % Renderer::maxMouse2dAnim; - - if (this->stats.getIsMasterserverMode () == true) - { - if (program->getWantShutdownApplicationAfterGame () == true) - { - program->setShutdownApplicationEnabled (true); - return; - } - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); -//program->setState(new MainMenu(program)); - program->initServer (program->getWindow (), false, true, true); - return; - } - } - - void - BattleEnd::render () - { - if (this->stats.getIsMasterserverMode () == true) - { - return; - } - Renderer & renderer = Renderer::getInstance (); -//CoreData &coreData= CoreData::getInstance(); - - canRender (); - incrementFps (); - -//printf("In [%s::%s Line: %d] renderToTexture [%p]\n",__FILE__,__FUNCTION__,__LINE__,renderToTexture); - if (menuBackgroundVideo == NULL && renderToTexture != NULL) - { -//printf("Rendering from texture!\n"); - - renderer.clearBuffers (); - renderer.reset3dMenu (); - renderer.clearZBuffer (); - - renderer.reset2d (); - - renderer.renderBackground (renderToTexture); - - renderer.renderButton (&buttonExit); - -//exit message box - if (mainMessageBox.getEnabled () && mainMessageBox.getVisible ()) - { - renderer.renderMessageBox (&mainMessageBox); - } - - renderer.renderMouse2d (mouseX, mouseY, mouse2dAnim); - } - else - { -//printf("Rendering to texture!\n"); - - if (menuBackgroundVideo == NULL && renderToTextureCount >= 300) - { - renderer.beginRenderToTexture (&renderToTexture); - } - - TextRenderer2D * - textRenderer2D = renderer.getTextRenderer (); - TextRenderer3D * - textRenderer3D = renderer.getTextRenderer3D (); - TextRenderer * - textRenderer = NULL; - - if (Renderer::renderText3DEnabled == true) - { - textRenderer = textRenderer3D; - } - else - { - textRenderer = textRenderer2D; - } - - Lang & lang = Lang::getInstance (); - - renderer.clearBuffers (); - renderer.reset3dMenu (); - renderer.clearZBuffer (); - renderer.reset2d (); - - if (menuBackgroundVideo != NULL) - { -//printf("Rendering video not null!\n"); - - if (menuBackgroundVideo->isPlaying () == true) - { - menuBackgroundVideo->playFrame (false); - -//printf("Rendering video playing!\n"); - } - else - { - if (menuBackgroundVideo != NULL) - { -//initBackgroundVideo(); - menuBackgroundVideo->RestartVideo (); - } - } - } - else - { - renderer. - renderBackground (CoreData:: - getInstance ().getBackgroundTexture ()); - } - -//int winnerIndex = -1; - int - bestScore = -1; -//int mostKillsIndex = -1; - int - bestKills = -1; -//int mostEnemyKillsIndex = -1; - int - bestEnemyKills = -1; -//int leastDeathsIndex = -1; - int - leastDeaths = -1; -//int mostUnitsProducedIndex = -1; - int - bestUnitsProduced = -1; -//int mostResourcesHarvestedIndex = -1; - int - bestResourcesHarvested = -1; - - for (int i = 0; i < stats.getFactionCount (); ++i) - { - if (stats.getTeam (i) == - GameConstants::maxPlayers - 1 + fpt_Observer) - { - continue; - } - -//int team= stats.getTeam(i) + 1; - int - kills = stats.getKills (i); - if (kills > bestKills) - { - bestKills = kills; -//mostKillsIndex = i; - } - - int - enemykills = stats.getEnemyKills (i); - if (enemykills > bestEnemyKills) - { - bestEnemyKills = enemykills; -//mostEnemyKillsIndex = i; - } - - int - deaths = stats.getDeaths (i); - if (deaths < leastDeaths || leastDeaths < 0) - { - leastDeaths = deaths; -//leastDeathsIndex = i; - } - - int - unitsProduced = stats.getUnitsProduced (i); - if (unitsProduced > bestUnitsProduced) - { - bestUnitsProduced = unitsProduced; -//mostUnitsProducedIndex = i; - } - - int - resourcesHarvested = stats.getResourcesHarvested (i); - if (resourcesHarvested > bestResourcesHarvested) - { - bestResourcesHarvested = resourcesHarvested; -//mostResourcesHarvestedIndex = i; - } - - int - score = - enemykills * 100 + unitsProduced * 50 + resourcesHarvested / 10; - - if (score > bestScore) - { - bestScore = score; -//winnerIndex = i; - } - } - - bool - disableStatsColorCoding = - Config::getInstance ().getBool ("DisableBattleEndColorCoding", - "false"); - - if (Renderer::renderText3DEnabled == true) - { - textRenderer3D-> - begin (CoreData::getInstance ().getMenuFontNormal3D ()); - } - else - { - textRenderer2D-> - begin (CoreData::getInstance ().getMenuFontNormal ()); - } - - int - lm = 20; - int - bm = 100; - - int - realPlayerCount = 0; - for (int i = 0; i < stats.getFactionCount (); ++i) - { - if (stats.getTeam (i) == - GameConstants::maxPlayers - 1 + fpt_Observer) - { - continue; - } - - realPlayerCount++; - int - textX = lm + 60 + (realPlayerCount * 100); - int - team = stats.getTeam (i) + 1; - int - kills = stats.getKills (i); - int - enemykills = stats.getEnemyKills (i); - int - deaths = stats.getDeaths (i); - int - unitsProduced = stats.getUnitsProduced (i); - int - resourcesHarvested = stats.getResourcesHarvested (i); - - int - score = - enemykills * 100 + unitsProduced * 50 + resourcesHarvested / 10; - string controlString; - - if (stats.getPersonalityType (i) == fpt_Observer) - { - controlString = GameConstants::OBSERVER_SLOTNAME; - } - else - { - switch (stats.getControl (i)) - { - case ctCpuEasy: - controlString = lang.getString ("CpuEasy"); - break; - case ctCpu: - controlString = lang.getString ("Cpu"); - break; - case ctCpuUltra: - controlString = lang.getString ("CpuUltra"); - break; - case ctCpuZeta: - controlString = lang.getString ("CpuZeta"); - break; - case ctNetwork: - controlString = lang.getString ("Network"); - break; - case ctHuman: - controlString = lang.getString ("Human"); - break; - - case ctNetworkCpuEasy: - controlString = lang.getString ("NetworkCpuEasy"); - break; - case ctNetworkCpu: - controlString = lang.getString ("NetworkCpu"); - break; - case ctNetworkCpuUltra: - controlString = lang.getString ("NetworkCpuUltra"); - break; - case ctNetworkCpuZeta: - controlString = lang.getString ("NetworkCpuZeta"); - break; - - default: - printf ("Error control = %d for i = %d\n", stats.getControl (i), - i); - assert (false); - break; - }; - } - - if (stats.getControl (i) != ctHuman - && stats.getControl (i) != ctNetwork) - { - controlString += - "\nx " + floatToStr (stats.getResourceMultiplier (i), 1); - } - else if (stats.getPlayerLeftBeforeEnd (i) == true) - { - controlString += - "\n" + lang.getString ("CpuUltra") + "\nx " + - floatToStr (stats.getResourceMultiplier (i), 1); - } - - if (score == bestScore && stats.getVictory (i)) - { - if (CoreData::getInstance ().getGameWinnerTexture () != NULL) - { - renderer.renderTextureQuad (textX, bm + 420, -1, -1, - CoreData:: - getInstance ().getGameWinnerTexture - (), 0.7f); - } - } - - Vec3f color = stats.getPlayerColor (i); - if (stats.getPlayerName (i) != "") - { - string textToRender = stats.getPlayerName (i).substr (0, 11); - if (stats.getPlayerLeftBeforeEnd (i) == true) - { - textToRender += - "\n(" + getTimeDuationString (stats.getTimePlayerLeft (i), - GameConstants::updateFps) + ")"; - } - - textRenderer->render (textToRender.c_str (), textX, bm + 400, - false, &color); - } - else - { - textRenderer->render ((lang.getString ("Player") + " " + - intToStr (i + 1)).c_str (), textX, - bm + 400, false, &color); - } - - Vec3f highliteColor = Vec3f (WHITE.x, WHITE.y, WHITE.z); - if (disableStatsColorCoding == false) - { - highliteColor.x = 0.85f; - highliteColor.y = 0.8f; - highliteColor.z = 0.07f; - } - - if (stats.getPersonalityType (i) == fpt_Observer) - { - textRenderer->render (lang.getString ("GameOver").c_str (), textX, - bm + 360); - } - else - { - if (stats.getVictory (i)) - { - textRenderer->render (stats. - getVictory (i) ? - lang.getString ("Victory"). - c_str () : lang.getString ("Defeat"). - c_str (), textX, bm + 360, false, - &highliteColor); - } - else - { - textRenderer->render (stats. - getVictory (i) ? - lang.getString ("Victory"). - c_str () : lang.getString ("Defeat"). - c_str (), textX, bm + 360); - } - } - - textRenderer->render (controlString, textX, bm + 320); - textRenderer->render (stats.getFactionTypeName (i), textX, - bm + 280); - textRenderer->render (intToStr (team).c_str (), textX, bm + 240); - - if (kills == bestKills) - { - textRenderer->render (intToStr (kills).c_str (), textX, bm + 200, - false, &highliteColor); - } - else - { - textRenderer->render (intToStr (kills).c_str (), textX, bm + 200); - } - if (enemykills == bestEnemyKills) - { - textRenderer->render (intToStr (enemykills).c_str (), textX, - bm + 180, false, &highliteColor); - } - else - { - textRenderer->render (intToStr (enemykills).c_str (), textX, - bm + 180); - } - if (deaths == leastDeaths) - { - textRenderer->render (intToStr (deaths).c_str (), textX, bm + 160, - false, &highliteColor); - } - else - { - textRenderer->render (intToStr (deaths).c_str (), textX, - bm + 160); - } - if (unitsProduced == bestUnitsProduced) - { - textRenderer->render (intToStr (unitsProduced).c_str (), textX, - bm + 120, false, &highliteColor); - } - else - { - textRenderer->render (intToStr (unitsProduced).c_str (), textX, - bm + 120); - } - if (resourcesHarvested == bestResourcesHarvested) - { - textRenderer->render (intToStr (resourcesHarvested).c_str (), - textX, bm + 80, false, &highliteColor); - } - else - { - textRenderer->render (intToStr (resourcesHarvested).c_str (), - textX, bm + 80); - } - if (score == bestScore) - { - textRenderer->render (intToStr (score).c_str (), textX, bm + 20, - false, &highliteColor); - } - else - { - textRenderer->render (intToStr (score).c_str (), textX, bm + 20); - } - } - - textRenderer->render ("\n" + (lang.getString ("LeftAt")), lm, - bm + 400); - textRenderer->render (lang.getString ("Result"), lm, bm + 360); - textRenderer->render (lang.getString ("Control"), lm, bm + 320); - textRenderer->render (lang.getString ("Faction"), lm, bm + 280); - textRenderer->render (lang.getString ("Team"), lm, bm + 240); - textRenderer->render (lang.getString ("Kills"), lm, bm + 200); - textRenderer->render (lang.getString ("EnemyKills"), lm, bm + 180); - textRenderer->render (lang.getString ("Deaths"), lm, bm + 160); - textRenderer->render (lang.getString ("UnitsProduced"), lm, bm + 120); - textRenderer->render (lang.getString ("ResourcesHarvested"), lm, - bm + 80); - textRenderer->render (lang.getString ("Score"), lm, bm + 20); - - textRenderer->end (); - - if (Renderer::renderText3DEnabled == true) - { - textRenderer3D-> - begin (CoreData::getInstance ().getMenuFontVeryBig3D ()); - } - else - { - textRenderer2D-> - begin (CoreData::getInstance ().getMenuFontVeryBig ()); - } - - string header = stats.getDescription () + " - "; - - if (stats.getThisFactionIndex () >= 0 - && stats.getTeam (stats.getThisFactionIndex ()) != - GameConstants::maxPlayers - 1 + fpt_Observer) - { - if (stats.getVictory (stats.getThisFactionIndex ())) - { - header += lang.getString ("Victory"); - } - else - { - header += lang.getString ("Defeat"); - } - } - else - { - header += "Observer"; - } - textRenderer->render (header, lm + 250, bm + 550); - -//GameConstants::updateFps -//string header2 = lang.getString("GameDurationTime","",true) + " " + floatToStr(stats.getWorldTimeElapsed() / 24.0,2); - - string - header2 = - lang.getString ("GameDurationTime", "", - true) + ": " + - getTimeDuationString (stats.getFramesToCalculatePlaytime (), - GameConstants::updateFps); - textRenderer->render (header2, lm + 250, bm + 530); - - header2 = - lang.getString ("GameMaxConcurrentUnitCount") + ": " + - intToStr (stats.getMaxConcurrentUnitCount ()); - textRenderer->render (header2, lm + 250, bm + 510); - - header2 = - lang.getString ("GameTotalEndGameConcurrentUnitCount") + ": " + - intToStr (stats.getTotalEndGameConcurrentUnitCount ()); - textRenderer->render (header2, lm + 250, bm + 490); - - textRenderer->end (); - - renderer.renderButton (&buttonExit); - -//exit message box - if (mainMessageBox.getEnabled () && renderToTextureCount < 300) - { - renderer.renderMessageBox (&mainMessageBox); - } - - if (menuBackgroundVideo == NULL && renderToTexture == NULL) - { - renderer.renderMouse2d (mouseX, mouseY, mouse2d, 0.f); - } - - if (menuBackgroundVideo == NULL && renderToTextureCount >= 300) - { - renderer.endRenderToTexture (&renderToTexture); - } - - if (menuBackgroundVideo == NULL) - { - if (renderToTexture == NULL && renderToTextureCount < 300) - { - renderToTextureCount++; - } - } - } - - renderer.renderFPSWhenEnabled (lastFps); - - renderer.swapBuffers (); - } - - void - BattleEnd::keyDown (SDL_KeyboardEvent key) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, "In [%s::%s %d]\n", - __FILE__, __FUNCTION__, __LINE__); - if (isKeyPressed (SDLK_ESCAPE, key) == true) - { -//program->setState(new MainMenu(program)); - - if (mainMessageBox.getEnabled ()) - { - mainMessageBox.setEnabled (false); - } - else - { - Lang & lang = Lang::getInstance (); - showMessageBox (lang.getString ("ExitToRootMenu"), "", true); - } - } - else if (isKeyPressed (SDLK_RETURN, key) - && mainMessageBox.getEnabled ()) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - program->setState (new MainMenu (program)); - } - } - - void - BattleEnd::mouseDownLeft (int x, int y) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, "In [%s::%s %d]\n", - __FILE__, __FUNCTION__, __LINE__); -//program->setState(new MainMenu(program)); - - if (buttonExit.mouseClick (x, y)) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, __FUNCTION__, - __LINE__); - program->setState (new MainMenu (program)); - } - else if (mainMessageBox.getEnabled ()) - { - int - button = 0; - if (mainMessageBox.mouseClick (x, y, button)) - { - if (button == 0) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - program->setState (new MainMenu (program)); - } - else - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); -//close message box - mainMessageBox.setEnabled (false); - } - } - } - - } - - void - BattleEnd::mouseMove (int x, int y, const MouseState * ms) - { - mouseX = x; - mouseY = y; - - buttonExit.mouseMove (x, y); - if (mainMessageBox.getEnabled ()) - { - mainMessageBox.mouseMove (x, y); - } - - } - - void - BattleEnd::showMessageBox (const string & text, const string & header, - bool toggle) - { - if (toggle == false) - { - mainMessageBox.setEnabled (false); - } - - if (mainMessageBox.getEnabled () == false) - { - mainMessageBox.setText (text); - mainMessageBox.setHeader (header); - mainMessageBox.setEnabled (true); - } - else - { - mainMessageBox.setEnabled (false); - } - } - - } +Shared::Util; + +namespace Glest { + namespace Game { + + // ===================================================== + // class BattleEnd + // ===================================================== + + BattleEnd::BattleEnd(Program * program, const Stats * stats, + ProgramState * originState) : + ProgramState(program), + menuBackgroundVideo(NULL), + gameSettings(NULL) { + + containerName = "BattleEnd"; + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d] stats = %p\n", __FILE__, + __FUNCTION__, __LINE__, stats); + + this->originState = originState; + if (stats != NULL) { + this->stats = *stats; + } + if (originState != NULL) { + Game * + game = dynamic_cast (originState); + if (game != NULL) { + gameSettings = new GameSettings(); + *gameSettings = *(game->getGameSettings()); + } + } + mouseX = 0; + mouseY = 0; + mouse2d = 0; + renderToTexture = NULL; + renderToTextureCount = 0; + + const + Metrics & + metrics = Metrics::getInstance(); + Lang & lang = Lang::getInstance(); + int + buttonWidth = 125; + int + xLocation = (metrics.getVirtualW() / 2) - (buttonWidth / 2); + buttonExit.init(xLocation, 80, buttonWidth); + buttonExit.setText(lang.getString("Exit")); + + //mesage box + mainMessageBox.init(lang.getString("Yes"), lang.getString("No")); + mainMessageBox.setEnabled(false); + + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", + __FILE__, __FUNCTION__, __LINE__); + + initBackgroundVideo(); + initBackgroundMusic(); + + GraphicComponent::applyAllCustomProperties(containerName); + } + + void + BattleEnd::reloadUI() { + Lang & lang = Lang::getInstance(); + + buttonExit.setText(lang.getString("Exit")); + mainMessageBox.init(lang.getString("Yes"), lang.getString("No")); + + GraphicComponent::reloadFontsForRegisterGraphicComponents + (containerName); + } + + BattleEnd::~BattleEnd() { + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", + __FILE__, __FUNCTION__, __LINE__); + + if (menuBackgroundVideo != NULL) { + menuBackgroundVideo->closePlayer(); + delete menuBackgroundVideo; + menuBackgroundVideo = NULL; + } + + delete gameSettings; + gameSettings = NULL; + + delete originState; + originState = NULL; + + if (CoreData::getInstance().hasMainMenuVideoFilename() == false) { + SoundRenderer::getInstance(). + playMusic(CoreData::getInstance().getMenuMusic()); + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", + __FILE__, __FUNCTION__, __LINE__); + + delete renderToTexture; + renderToTexture = NULL; + + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", + __FILE__, __FUNCTION__, __LINE__); + } + + std::pair < string, string > BattleEnd::getBattleEndVideo(bool won) { + std::pair < string, string > result; + + string factionVideoUrl = ""; + string factionVideoUrlFallback = ""; + + if (gameSettings != NULL) { + string currentTechName_factionPreview = gameSettings->getTech(); + string + currentFactionName_factionPreview = + gameSettings->getFactionTypeName(stats.getThisFactionIndex()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#1 tech [%s] faction [%s] won = %d\n", + currentTechName_factionPreview.c_str(), + currentFactionName_factionPreview.c_str(), won); + + string + factionDefinitionXML = + Game::findFactionLogoFile(gameSettings, NULL, + currentFactionName_factionPreview + + ".xml"); + if (factionDefinitionXML != "" + && currentFactionName_factionPreview != + GameConstants::RANDOMFACTION_SLOTNAME + && currentFactionName_factionPreview != + GameConstants::OBSERVER_SLOTNAME + && fileExists(factionDefinitionXML) == true) { + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#2 tech [%s] faction [%s]\n", + currentTechName_factionPreview.c_str(), + currentFactionName_factionPreview.c_str()); + + XmlTree xmlTree; + std::map < string, string > mapExtraTagReplacementValues; + xmlTree.load(factionDefinitionXML, + Properties::getTagReplacementValues + (&mapExtraTagReplacementValues)); + const XmlNode * + factionNode = xmlTree.getRootNode(); + if (won == true) { + if (factionNode->hasAttribute("battle-end-win-video") == true) { + factionVideoUrl = + factionNode-> + getAttribute("battle-end-win-video")->getValue(); + } + } else { + if (factionNode->hasAttribute("battle-end-lose-video") == true) { + factionVideoUrl = + factionNode-> + getAttribute("battle-end-lose-video")->getValue(); + } + } + + if (factionVideoUrl != "" && fileExists(factionVideoUrl) == false) { + string techTreePath = ""; + string factionPath = ""; + std::vector < std::string > factionPartsList; + Tokenize(factionDefinitionXML, factionPartsList, "factions/"); + if (factionPartsList.size() > 1) { + techTreePath = factionPartsList[0]; + + string + factionPath = + techTreePath + "factions/" + + currentFactionName_factionPreview; + endPathWithSlash(factionPath); + factionVideoUrl = factionPath + factionVideoUrl; + } + } + + if (won == true) { + factionVideoUrlFallback = + Game::findFactionLogoFile(gameSettings, NULL, + "battle_end_win_video.*"); + } else { + factionVideoUrlFallback = + Game::findFactionLogoFile(gameSettings, NULL, + "battle_end_lose_video.*"); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#3 factionVideoUrl [%s] factionVideoUrlFallback [%s]\n", + factionVideoUrl.c_str(), + factionVideoUrlFallback.c_str()); + //printf("#3 factionVideoUrl [%s] factionVideoUrlFallback [%s]\n",factionVideoUrl.c_str(),factionVideoUrlFallback.c_str()); + + if (factionVideoUrl == "") { + factionVideoUrl = factionVideoUrlFallback; + factionVideoUrlFallback = ""; + } + } + //printf("currentFactionName_factionPreview [%s] random [%s] observer [%s] factionVideoUrl [%s]\n",currentFactionName_factionPreview.c_str(),GameConstants::RANDOMFACTION_SLOTNAME,GameConstants::OBSERVER_SLOTNAME,factionVideoUrl.c_str()); + } + + if (factionVideoUrl != "") { + result.first = factionVideoUrl; + result.second = factionVideoUrlFallback; + } else { + result.first = + CoreData::getInstance().getBattleEndVideoFilename(won); + result.second = + CoreData::getInstance().getBattleEndVideoFilenameFallback(won); + } + + return result; + } + + string BattleEnd::getBattleEndMusic(bool won) { + string result = ""; + string resultFallback = ""; + + if (gameSettings != NULL) { + string currentTechName_factionPreview = gameSettings->getTech(); + string + currentFactionName_factionPreview = + gameSettings->getFactionTypeName(stats.getThisFactionIndex()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#1 tech [%s] faction [%s] won = %d\n", + currentTechName_factionPreview.c_str(), + currentFactionName_factionPreview.c_str(), won); + + string + factionDefinitionXML = + Game::findFactionLogoFile(gameSettings, NULL, + currentFactionName_factionPreview + + ".xml"); + if (factionDefinitionXML != "" + && currentFactionName_factionPreview != + GameConstants::RANDOMFACTION_SLOTNAME + && currentFactionName_factionPreview != + GameConstants::OBSERVER_SLOTNAME + && fileExists(factionDefinitionXML) == true) { + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#2 tech [%s] faction [%s]\n", + currentTechName_factionPreview.c_str(), + currentFactionName_factionPreview.c_str()); + + XmlTree xmlTree; + std::map < string, string > mapExtraTagReplacementValues; + xmlTree.load(factionDefinitionXML, + Properties::getTagReplacementValues + (&mapExtraTagReplacementValues)); + const XmlNode * + factionNode = xmlTree.getRootNode(); + if (won == true) { + if (factionNode->hasAttribute("battle-end-win-music") == true) { + result = + factionNode-> + getAttribute("battle-end-win-music")->getValue(); + } + } else { + if (factionNode->hasAttribute("battle-end-lose-music") == true) { + result = + factionNode-> + getAttribute("battle-end-lose-music")->getValue(); + } + } + + if (result != "" && fileExists(result) == false) { + string techTreePath = ""; + string factionPath = ""; + std::vector < std::string > factionPartsList; + Tokenize(factionDefinitionXML, factionPartsList, "factions/"); + if (factionPartsList.size() > 1) { + techTreePath = factionPartsList[0]; + + string + factionPath = + techTreePath + "factions/" + + currentFactionName_factionPreview; + endPathWithSlash(factionPath); + result = factionPath + result; + } + } + + if (won == true) { + resultFallback = + Game::findFactionLogoFile(gameSettings, NULL, + "battle_end_win_music.*"); + } else { + resultFallback = + Game::findFactionLogoFile(gameSettings, NULL, + "battle_end_lose_music.*"); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#3 result [%s] resultFallback [%s]\n", result.c_str(), + resultFallback.c_str()); + //printf("#3 result [%s] resultFallback [%s]\n",result.c_str(),resultFallback.c_str()); + + if (result == "") { + result = resultFallback; + } + } + //printf("currentFactionName_factionPreview [%s] random [%s] observer [%s] factionVideoUrl [%s]\n",currentFactionName_factionPreview.c_str(),GameConstants::RANDOMFACTION_SLOTNAME,GameConstants::OBSERVER_SLOTNAME,factionVideoUrl.c_str()); + } + + if (result == "") { + result = CoreData::getInstance().getBattleEndMusicFilename(won); + } + + return result; + } + + void + BattleEnd::initBackgroundMusic() { + string music = ""; + + if (stats.getThisFactionIndex() >= 0 + && stats.getTeam(stats.getThisFactionIndex()) != + GameConstants::maxPlayers - 1 + fpt_Observer) { + if (stats.getVictory(stats.getThisFactionIndex())) { + //header += lang.getString("Victory"); + music = getBattleEndMusic(true); + } else { + //header += lang.getString("Defeat"); + music = getBattleEndMusic(false); + } + + if (music != "" && fileExists(music) == true) { + printf("music [%s] \n", music.c_str()); + + battleEndMusic.open(music); + battleEndMusic.setNext(&battleEndMusic); + + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + soundRenderer.playMusic(&battleEndMusic); + } + } + } + + void + BattleEnd::initBackgroundVideo() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false + && ::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == true) { + + if (menuBackgroundVideo != NULL) { + menuBackgroundVideo->closePlayer(); + delete menuBackgroundVideo; + menuBackgroundVideo = NULL; + } + + string videoFile = ""; + string videoFileFallback = ""; + + if (stats.getThisFactionIndex() >= 0 + && stats.getTeam(stats.getThisFactionIndex()) != + GameConstants::maxPlayers - 1 + fpt_Observer) { + if (stats.getVictory(stats.getThisFactionIndex())) { + //header += lang.getString("Victory"); + + //videoFile = CoreData::getInstance().getBattleEndVideoFilename(true); + //videoFileFallback = CoreData::getInstance().getBattleEndVideoFilenameFallback(true); + std::pair < string, string > wonVideos = getBattleEndVideo(true); + videoFile = wonVideos.first; + videoFileFallback = wonVideos.second; + } else { + //header += lang.getString("Defeat"); + //videoFile = CoreData::getInstance().getBattleEndVideoFilename(false); + //videoFileFallback = CoreData::getInstance().getBattleEndVideoFilenameFallback(false); + std::pair < string, string > lostVideos = + getBattleEndVideo(false); + videoFile = lostVideos.first; + videoFileFallback = lostVideos.second; + } + } else { + //header += "Observer"; + } + + if (fileExists(videoFile) || fileExists(videoFileFallback)) { + printf("videoFile [%s] videoFileFallback [%s]\n", + videoFile.c_str(), videoFileFallback.c_str()); + + Context * + c = GraphicsInterface::getInstance().getCurrentContext(); + PlatformContextGl * + glCtx = + static_cast (c)->getPlatformContextGlPtr(); + SDL_Window * + window = glCtx->getScreenWindow(); + SDL_Surface * + screen = glCtx->getScreenSurface(); + + string + vlcPluginsPath = + Config::getInstance().getString("VideoPlayerPluginsPath", ""); + //printf("screen->w = %d screen->h = %d screen->format->BitsPerPixel = %d\n",screen->w,screen->h,screen->format->BitsPerPixel); + menuBackgroundVideo = new VideoPlayer(&Renderer::getInstance(), + videoFile, + videoFileFallback, + window, + 0, 0, + screen->w, + screen->h, + screen->format->BitsPerPixel, + true, + vlcPluginsPath, + SystemFlags::VERBOSE_MODE_ENABLED); + menuBackgroundVideo->initPlayer(); + } + } + } + + void + BattleEnd::update() { + if (Config::getInstance().getBool("AutoTest")) { + AutoTest::getInstance().updateBattleEnd(program); + return; + } + mouse2d = (mouse2d + 1) % Renderer::maxMouse2dAnim; + + if (this->stats.getIsMasterserverMode() == true) { + if (program->getWantShutdownApplicationAfterGame() == true) { + program->setShutdownApplicationEnabled(true); + return; + } + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + //program->setState(new MainMenu(program)); + program->initServer(program->getWindow(), false, true, true); + return; + } + } + + void + BattleEnd::render() { + if (this->stats.getIsMasterserverMode() == true) { + return; + } + Renderer & renderer = Renderer::getInstance(); + //CoreData &coreData= CoreData::getInstance(); + + canRender(); + incrementFps(); + + //printf("In [%s::%s Line: %d] renderToTexture [%p]\n",__FILE__,__FUNCTION__,__LINE__,renderToTexture); + if (menuBackgroundVideo == NULL && renderToTexture != NULL) { + //printf("Rendering from texture!\n"); + + renderer.clearBuffers(); + renderer.reset3dMenu(); + renderer.clearZBuffer(); + + renderer.reset2d(); + + renderer.renderBackground(renderToTexture); + + renderer.renderButton(&buttonExit); + + //exit message box + if (mainMessageBox.getEnabled() && mainMessageBox.getVisible()) { + renderer.renderMessageBox(&mainMessageBox); + } + + renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim); + } else { + //printf("Rendering to texture!\n"); + + if (menuBackgroundVideo == NULL && renderToTextureCount >= 300) { + renderer.beginRenderToTexture(&renderToTexture); + } + + TextRenderer2D * + textRenderer2D = renderer.getTextRenderer(); + TextRenderer3D * + textRenderer3D = renderer.getTextRenderer3D(); + TextRenderer * + textRenderer = NULL; + + if (Renderer::renderText3DEnabled == true) { + textRenderer = textRenderer3D; + } else { + textRenderer = textRenderer2D; + } + + Lang & lang = Lang::getInstance(); + + renderer.clearBuffers(); + renderer.reset3dMenu(); + renderer.clearZBuffer(); + renderer.reset2d(); + + if (menuBackgroundVideo != NULL) { + //printf("Rendering video not null!\n"); + + if (menuBackgroundVideo->isPlaying() == true) { + menuBackgroundVideo->playFrame(false); + + //printf("Rendering video playing!\n"); + } else { + if (menuBackgroundVideo != NULL) { + //initBackgroundVideo(); + menuBackgroundVideo->RestartVideo(); + } + } + } else { + renderer. + renderBackground(CoreData:: + getInstance().getBackgroundTexture()); + } + + //int winnerIndex = -1; + int + bestScore = -1; + //int mostKillsIndex = -1; + int + bestKills = -1; + //int mostEnemyKillsIndex = -1; + int + bestEnemyKills = -1; + //int leastDeathsIndex = -1; + int + leastDeaths = -1; + //int mostUnitsProducedIndex = -1; + int + bestUnitsProduced = -1; + //int mostResourcesHarvestedIndex = -1; + int + bestResourcesHarvested = -1; + + for (int i = 0; i < stats.getFactionCount(); ++i) { + if (stats.getTeam(i) == + GameConstants::maxPlayers - 1 + fpt_Observer) { + continue; + } + + //int team= stats.getTeam(i) + 1; + int + kills = stats.getKills(i); + if (kills > bestKills) { + bestKills = kills; + //mostKillsIndex = i; + } + + int + enemykills = stats.getEnemyKills(i); + if (enemykills > bestEnemyKills) { + bestEnemyKills = enemykills; + //mostEnemyKillsIndex = i; + } + + int + deaths = stats.getDeaths(i); + if (deaths < leastDeaths || leastDeaths < 0) { + leastDeaths = deaths; + //leastDeathsIndex = i; + } + + int + unitsProduced = stats.getUnitsProduced(i); + if (unitsProduced > bestUnitsProduced) { + bestUnitsProduced = unitsProduced; + //mostUnitsProducedIndex = i; + } + + int + resourcesHarvested = stats.getResourcesHarvested(i); + if (resourcesHarvested > bestResourcesHarvested) { + bestResourcesHarvested = resourcesHarvested; + //mostResourcesHarvestedIndex = i; + } + + int + score = + enemykills * 100 + unitsProduced * 50 + resourcesHarvested / 10; + + if (score > bestScore) { + bestScore = score; + //winnerIndex = i; + } + } + + bool + disableStatsColorCoding = + Config::getInstance().getBool("DisableBattleEndColorCoding", + "false"); + + if (Renderer::renderText3DEnabled == true) { + textRenderer3D-> + begin(CoreData::getInstance().getMenuFontNormal3D()); + } else { + textRenderer2D-> + begin(CoreData::getInstance().getMenuFontNormal()); + } + + int + lm = 20; + int + bm = 100; + + int + realPlayerCount = 0; + for (int i = 0; i < stats.getFactionCount(); ++i) { + if (stats.getTeam(i) == + GameConstants::maxPlayers - 1 + fpt_Observer) { + continue; + } + + realPlayerCount++; + int + textX = lm + 60 + (realPlayerCount * 100); + int + team = stats.getTeam(i) + 1; + int + kills = stats.getKills(i); + int + enemykills = stats.getEnemyKills(i); + int + deaths = stats.getDeaths(i); + int + unitsProduced = stats.getUnitsProduced(i); + int + resourcesHarvested = stats.getResourcesHarvested(i); + + int + score = + enemykills * 100 + unitsProduced * 50 + resourcesHarvested / 10; + string controlString; + + if (stats.getPersonalityType(i) == fpt_Observer) { + controlString = GameConstants::OBSERVER_SLOTNAME; + } else { + switch (stats.getControl(i)) { + case ctCpuEasy: + controlString = lang.getString("CpuEasy"); + break; + case ctCpu: + controlString = lang.getString("Cpu"); + break; + case ctCpuUltra: + controlString = lang.getString("CpuUltra"); + break; + case ctCpuZeta: + controlString = lang.getString("CpuZeta"); + break; + case ctNetwork: + controlString = lang.getString("Network"); + break; + case ctHuman: + controlString = lang.getString("Human"); + break; + + case ctNetworkCpuEasy: + controlString = lang.getString("NetworkCpuEasy"); + break; + case ctNetworkCpu: + controlString = lang.getString("NetworkCpu"); + break; + case ctNetworkCpuUltra: + controlString = lang.getString("NetworkCpuUltra"); + break; + case ctNetworkCpuZeta: + controlString = lang.getString("NetworkCpuZeta"); + break; + + default: + printf("Error control = %d for i = %d\n", stats.getControl(i), + i); + assert(false); + break; + }; + } + + if (stats.getControl(i) != ctHuman + && stats.getControl(i) != ctNetwork) { + controlString += + "\nx " + floatToStr(stats.getResourceMultiplier(i), 1); + } else if (stats.getPlayerLeftBeforeEnd(i) == true) { + controlString += + "\n" + lang.getString("CpuUltra") + "\nx " + + floatToStr(stats.getResourceMultiplier(i), 1); + } + + if (score == bestScore && stats.getVictory(i)) { + if (CoreData::getInstance().getGameWinnerTexture() != NULL) { + renderer.renderTextureQuad(textX, bm + 420, -1, -1, + CoreData:: + getInstance().getGameWinnerTexture + (), 0.7f); + } + } + + Vec3f color = stats.getPlayerColor(i); + if (stats.getPlayerName(i) != "") { + string textToRender = stats.getPlayerName(i).substr(0, 11); + if (stats.getPlayerLeftBeforeEnd(i) == true) { + textToRender += + "\n(" + getTimeDuationString(stats.getTimePlayerLeft(i), + GameConstants::updateFps) + ")"; + } + + textRenderer->render(textToRender.c_str(), textX, bm + 400, + false, &color); + } else { + textRenderer->render((lang.getString("Player") + " " + + intToStr(i + 1)).c_str(), textX, + bm + 400, false, &color); + } + + Vec3f highliteColor = Vec3f(WHITE.x, WHITE.y, WHITE.z); + if (disableStatsColorCoding == false) { + highliteColor.x = 0.85f; + highliteColor.y = 0.8f; + highliteColor.z = 0.07f; + } + + if (stats.getPersonalityType(i) == fpt_Observer) { + textRenderer->render(lang.getString("GameOver").c_str(), textX, + bm + 360); + } else { + if (stats.getVictory(i)) { + textRenderer->render(stats. + getVictory(i) ? + lang.getString("Victory"). + c_str() : lang.getString("Defeat"). + c_str(), textX, bm + 360, false, + &highliteColor); + } else { + textRenderer->render(stats. + getVictory(i) ? + lang.getString("Victory"). + c_str() : lang.getString("Defeat"). + c_str(), textX, bm + 360); + } + } + + textRenderer->render(controlString, textX, bm + 320); + textRenderer->render(stats.getFactionTypeName(i), textX, + bm + 280); + textRenderer->render(intToStr(team).c_str(), textX, bm + 240); + + if (kills == bestKills) { + textRenderer->render(intToStr(kills).c_str(), textX, bm + 200, + false, &highliteColor); + } else { + textRenderer->render(intToStr(kills).c_str(), textX, bm + 200); + } + if (enemykills == bestEnemyKills) { + textRenderer->render(intToStr(enemykills).c_str(), textX, + bm + 180, false, &highliteColor); + } else { + textRenderer->render(intToStr(enemykills).c_str(), textX, + bm + 180); + } + if (deaths == leastDeaths) { + textRenderer->render(intToStr(deaths).c_str(), textX, bm + 160, + false, &highliteColor); + } else { + textRenderer->render(intToStr(deaths).c_str(), textX, + bm + 160); + } + if (unitsProduced == bestUnitsProduced) { + textRenderer->render(intToStr(unitsProduced).c_str(), textX, + bm + 120, false, &highliteColor); + } else { + textRenderer->render(intToStr(unitsProduced).c_str(), textX, + bm + 120); + } + if (resourcesHarvested == bestResourcesHarvested) { + textRenderer->render(intToStr(resourcesHarvested).c_str(), + textX, bm + 80, false, &highliteColor); + } else { + textRenderer->render(intToStr(resourcesHarvested).c_str(), + textX, bm + 80); + } + if (score == bestScore) { + textRenderer->render(intToStr(score).c_str(), textX, bm + 20, + false, &highliteColor); + } else { + textRenderer->render(intToStr(score).c_str(), textX, bm + 20); + } + } + + textRenderer->render("\n" + (lang.getString("LeftAt")), lm, + bm + 400); + textRenderer->render(lang.getString("Result"), lm, bm + 360); + textRenderer->render(lang.getString("Control"), lm, bm + 320); + textRenderer->render(lang.getString("Faction"), lm, bm + 280); + textRenderer->render(lang.getString("Team"), lm, bm + 240); + textRenderer->render(lang.getString("Kills"), lm, bm + 200); + textRenderer->render(lang.getString("EnemyKills"), lm, bm + 180); + textRenderer->render(lang.getString("Deaths"), lm, bm + 160); + textRenderer->render(lang.getString("UnitsProduced"), lm, bm + 120); + textRenderer->render(lang.getString("ResourcesHarvested"), lm, + bm + 80); + textRenderer->render(lang.getString("Score"), lm, bm + 20); + + textRenderer->end(); + + if (Renderer::renderText3DEnabled == true) { + textRenderer3D-> + begin(CoreData::getInstance().getMenuFontVeryBig3D()); + } else { + textRenderer2D-> + begin(CoreData::getInstance().getMenuFontVeryBig()); + } + + string header = stats.getDescription() + " - "; + + if (stats.getThisFactionIndex() >= 0 + && stats.getTeam(stats.getThisFactionIndex()) != + GameConstants::maxPlayers - 1 + fpt_Observer) { + if (stats.getVictory(stats.getThisFactionIndex())) { + header += lang.getString("Victory"); + } else { + header += lang.getString("Defeat"); + } + } else { + header += "Observer"; + } + textRenderer->render(header, lm + 250, bm + 550); + + //GameConstants::updateFps + //string header2 = lang.getString("GameDurationTime","",true) + " " + floatToStr(stats.getWorldTimeElapsed() / 24.0,2); + + string + header2 = + lang.getString("GameDurationTime", "", + true) + ": " + + getTimeDuationString(stats.getFramesToCalculatePlaytime(), + GameConstants::updateFps); + textRenderer->render(header2, lm + 250, bm + 530); + + header2 = + lang.getString("GameMaxConcurrentUnitCount") + ": " + + intToStr(stats.getMaxConcurrentUnitCount()); + textRenderer->render(header2, lm + 250, bm + 510); + + header2 = + lang.getString("GameTotalEndGameConcurrentUnitCount") + ": " + + intToStr(stats.getTotalEndGameConcurrentUnitCount()); + textRenderer->render(header2, lm + 250, bm + 490); + + textRenderer->end(); + + renderer.renderButton(&buttonExit); + + //exit message box + if (mainMessageBox.getEnabled() && renderToTextureCount < 300) { + renderer.renderMessageBox(&mainMessageBox); + } + + if (menuBackgroundVideo == NULL && renderToTexture == NULL) { + renderer.renderMouse2d(mouseX, mouseY, mouse2d, 0.f); + } + + if (menuBackgroundVideo == NULL && renderToTextureCount >= 300) { + renderer.endRenderToTexture(&renderToTexture); + } + + if (menuBackgroundVideo == NULL) { + if (renderToTexture == NULL && renderToTextureCount < 300) { + renderToTextureCount++; + } + } + } + + renderer.renderFPSWhenEnabled(lastFps); + + renderer.swapBuffers(); + } + + void + BattleEnd::keyDown(SDL_KeyboardEvent key) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", + __FILE__, __FUNCTION__, __LINE__); + if (isKeyPressed(SDLK_ESCAPE, key) == true) { + //program->setState(new MainMenu(program)); + + if (mainMessageBox.getEnabled()) { + mainMessageBox.setEnabled(false); + } else { + Lang & lang = Lang::getInstance(); + showMessageBox(lang.getString("ExitToRootMenu"), "", true); + } + } else if (isKeyPressed(SDLK_RETURN, key) + && mainMessageBox.getEnabled()) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + program->setState(new MainMenu(program)); + } + } + + void + BattleEnd::mouseDownLeft(int x, int y) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", + __FILE__, __FUNCTION__, __LINE__); + //program->setState(new MainMenu(program)); + + if (buttonExit.mouseClick(x, y)) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, __FUNCTION__, + __LINE__); + program->setState(new MainMenu(program)); + } else if (mainMessageBox.getEnabled()) { + int + button = 0; + if (mainMessageBox.mouseClick(x, y, button)) { + if (button == 0) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + program->setState(new MainMenu(program)); + } else { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + //close message box + mainMessageBox.setEnabled(false); + } + } + } + + } + + void + BattleEnd::mouseMove(int x, int y, const MouseState * ms) { + mouseX = x; + mouseY = y; + + buttonExit.mouseMove(x, y); + if (mainMessageBox.getEnabled()) { + mainMessageBox.mouseMove(x, y); + } + + } + + void + BattleEnd::showMessageBox(const string & text, const string & header, + bool toggle) { + if (toggle == false) { + mainMessageBox.setEnabled(false); + } + + if (mainMessageBox.getEnabled() == false) { + mainMessageBox.setText(text); + mainMessageBox.setHeader(header); + mainMessageBox.setEnabled(true); + } else { + mainMessageBox.setEnabled(false); + } + } + + } } //end namespace diff --git a/source/glest_game/main/battle_end.h b/source/glest_game/main/battle_end.h index 4a5bec66b..11d3000cb 100644 --- a/source/glest_game/main/battle_end.h +++ b/source/glest_game/main/battle_end.h @@ -21,67 +21,63 @@ # include "stats.h" # include "leak_dumper.h" -namespace Shared -{ - namespace Graphics - { - class VideoPlayer; - } +namespace Shared { + namespace Graphics { + class VideoPlayer; + } } -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - class GameSettings; -// ===================================================== -// class BattleEnd -// -/// ProgramState representing the end of the game -// ===================================================== + class GameSettings; + // ===================================================== + // class BattleEnd + // + /// ProgramState representing the end of the game + // ===================================================== - class BattleEnd:public ProgramState - { - private: - Stats stats; + class BattleEnd :public ProgramState { + private: + Stats stats; - GraphicButton buttonExit; - int mouse2d; - GraphicMessageBox mainMessageBox; - Texture2D *renderToTexture; - uint64 renderToTextureCount; - ProgramState *originState; - const char *containerName; + GraphicButton buttonExit; + int mouse2d; + GraphicMessageBox mainMessageBox; + Texture2D *renderToTexture; + uint64 renderToTextureCount; + ProgramState *originState; + const char *containerName; - ::Shared::Graphics::VideoPlayer * menuBackgroundVideo; - GameSettings *gameSettings; - StrSound battleEndMusic; + ::Shared::Graphics::VideoPlayer * menuBackgroundVideo; + GameSettings *gameSettings; + StrSound battleEndMusic; - void showMessageBox (const string & text, const string & header, - bool toggle); + void showMessageBox(const string & text, const string & header, + bool toggle); - public: - BattleEnd (Program * program, const Stats * stats, - ProgramState * originState); - ~BattleEnd (); + public: + BattleEnd(Program * program, const Stats * stats, + ProgramState * originState); + ~BattleEnd(); - virtual void update (); - virtual void render (); - virtual void keyDown (SDL_KeyboardEvent key); - virtual void mouseDownLeft (int x, int y); - virtual void mouseMove (int x, int y, const MouseState * ms); -//virtual void tick(); - virtual void reloadUI (); + virtual void update(); + virtual void render(); + virtual void keyDown(SDL_KeyboardEvent key); + virtual void mouseDownLeft(int x, int y); + virtual void mouseMove(int x, int y, const MouseState * ms); + //virtual void tick(); + virtual void reloadUI(); - private: + private: - void initBackgroundVideo (); - std::pair < string, string > getBattleEndVideo (bool won); - string getBattleEndMusic (bool won); - void initBackgroundMusic (); - }; + void initBackgroundVideo(); + std::pair < string, string > getBattleEndVideo(bool won); + string getBattleEndMusic(bool won); + void initBackgroundMusic(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/main/intro.cpp b/source/glest_game/main/intro.cpp index 21263045e..fb0dfdd5c 100644 --- a/source/glest_game/main/intro.cpp +++ b/source/glest_game/main/intro.cpp @@ -30,1110 +30,979 @@ #include "leak_dumper.h" using namespace - Shared::Util; +Shared::Util; using - namespace - Shared::Graphics; +namespace + Shared::Graphics; using - namespace - Shared::Xml; - -namespace Glest -{ - namespace Game - { - -//struct Timer { -//public: -// Timer () -// : current_time (0.0), last_time (0.0) { } -// -//public: -// void update () { -// last_time = current_time; -// current_time = static_cast(SDL_GetTicks ()) / 1000.0; -// } -// -// double deltaTime () const { -// return (current_time - last_time); -// } -// -//public: -// double current_time; -// double last_time; -// -//} animTimer; - -// ===================================================== -// class Text -// ===================================================== - - IntroText::IntroText (const string & text, const Vec2i & pos, int time, - Font2D * font, Font3D * font3D) - { - this->text = text; - this->pos = pos; - this->time = time; - this->texture = NULL; - this->font = font; - this->font3D = font3D; - } - - IntroText::IntroText (const Texture2D * texture, const Vec2i & pos, - const Vec2i & size, int time) - { - this->pos = pos; - this->size = size; - this->time = time; - this->texture = texture; - this->font = NULL; - this->font3D = NULL; - } - -// ===================================================== -// class Intro -// ===================================================== - - int - Intro::introTime = 50000; - int - Intro::appearTime = 2500; - int - Intro::showTime = 3500; - int - Intro::disapearTime = 2500; - - Intro::Intro (Program * program): - ProgramState (program) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false && - (::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer () == false - || CoreData::getInstance ().hasIntroVideoFilename () == false)) - { - soundRenderer.playMusic (CoreData::getInstance ().getIntroMusic ()); - } - - const - Metrics & - metrics = Metrics::getInstance (); - int - w = metrics.getVirtualW (); - int - h = metrics.getVirtualH (); - timer = 0; - mouseX = 0; - mouseY = 0; - mouse2d = 0; - exitAfterIntroVideo = false; - - Renderer & renderer = Renderer::getInstance (); -//renderer.init3dListMenu(NULL); - renderer.initMenu (NULL); - fade = 0.f; - anim = 0.f; - targetCamera = NULL; - t = 0.f; - - startPosition.x = 5;; - startPosition.y = 10; - startPosition.z = 40; - camera.setPosition (startPosition); - - Vec3f startRotation; - startRotation.x = 0; - startRotation.y = 0; - startRotation.z = 0; - - camera.setOrientation (Quaternion - (EulerAngles - (degToRad (startRotation.x), - degToRad (startRotation.y), - degToRad (startRotation.z)))); - - Intro::introTime = 3000; - Intro::appearTime = 500; - Intro::showTime = 500; - Intro::disapearTime = 500; - int - showIntroPics = 0; - int - showIntroPicsTime = 0; - bool showIntroPicsRandom = false; - bool showIntroModels = false; - bool showIntroModelsRandom = false; - modelMinAnimSpeed = 0; - modelMaxAnimSpeed = 0; - - XmlTree xmlTree; - string - data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - xmlTree.load (getGameCustomCoreDataPath - (data_path, "data/core/menu/menu.xml"), - Properties::getTagReplacementValues ()); - const XmlNode * - menuNode = xmlTree.getRootNode (); - - if (menuNode->hasChild ("intro") == true) - { - const XmlNode * - introNode = menuNode->getChild ("intro"); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, - __FUNCTION__, __LINE__); - -//camera - const XmlNode * - cameraNode = introNode->getChild ("camera"); - -//position - const XmlNode * - positionNode = cameraNode->getChild ("start-position"); - startPosition.x = positionNode->getAttribute ("x")->getFloatValue (); - startPosition.y = positionNode->getAttribute ("y")->getFloatValue (); - startPosition.z = positionNode->getAttribute ("z")->getFloatValue (); - camera.setPosition (startPosition); - -//rotation - const XmlNode * - rotationNode = cameraNode->getChild ("start-rotation"); - Vec3f startRotation; - startRotation.x = rotationNode->getAttribute ("x")->getFloatValue (); - startRotation.y = rotationNode->getAttribute ("y")->getFloatValue (); - startRotation.z = rotationNode->getAttribute ("z")->getFloatValue (); - camera.setOrientation (Quaternion - (EulerAngles - (degToRad (startRotation.x), - degToRad (startRotation.y), - degToRad (startRotation.z)))); - -// intro info - const XmlNode * - introTimeNode = introNode->getChild ("intro-time"); - Intro::introTime = - introTimeNode->getAttribute ("value")->getIntValue (); - const XmlNode * - appearTimeNode = introNode->getChild ("appear-time"); - Intro::appearTime = - appearTimeNode->getAttribute ("value")->getIntValue (); - const XmlNode * - showTimeNode = introNode->getChild ("show-time"); - Intro::showTime = - showTimeNode->getAttribute ("value")->getIntValue (); - const XmlNode * - disappearTimeNode = introNode->getChild ("disappear-time"); - Intro::disapearTime = - disappearTimeNode->getAttribute ("value")->getIntValue (); - const XmlNode * - showIntroPicturesNode = introNode->getChild ("show-intro-pictures"); - showIntroPics = - showIntroPicturesNode->getAttribute ("value")->getIntValue (); - showIntroPicsTime = - showIntroPicturesNode->getAttribute ("time")->getIntValue (); - showIntroPicsRandom = - showIntroPicturesNode->getAttribute ("random")->getBoolValue (); - - const XmlNode * - showIntroModelsNode = introNode->getChild ("show-intro-models"); - showIntroModels = - showIntroModelsNode->getAttribute ("value")->getBoolValue (); - showIntroModelsRandom = - showIntroModelsNode->getAttribute ("random")->getBoolValue (); - modelMinAnimSpeed = - showIntroModelsNode-> - getAttribute ("min-anim-speed")->getFloatValue (); - modelMaxAnimSpeed = - showIntroModelsNode-> - getAttribute ("max-anim-speed")->getFloatValue (); - } - -//load main model - modelIndex = 0; - models.clear (); - if (showIntroModels == true) - { - -//getGameCustomCoreDataPath(data_path, "data/core/menu/menu.xml") - string - introPath = - getGameCustomCoreDataPath (data_path, - "") + - "data/core/menu/main_model/intro*.g3d"; - vector < string > introModels; - findAll (introPath, introModels, false, false); - for (int i = 0; i < (int) introModels.size (); ++i) - { - string logo = introModels[i]; - Model * - model = renderer.newModel (rsMenu, - getGameCustomCoreDataPath (data_path, - "") + - "data/core/menu/main_model/" + logo); - if (model) - { - models.push_back (model); -//printf("#1 Intro model [%s]\n",model->getFileName().c_str()); - } - } - - if (models.empty () == true) - { - introPath = data_path + "data/core/menu/main_model/intro*.g3d"; -//vector introModels; - findAll (introPath, introModels, false, false); - for (int i = 0; i < (int) introModels.size (); ++i) - { - string logo = introModels[i]; - Model * - model = renderer.newModel (rsMenu, - data_path + - "data/core/menu/main_model/" + logo); - if (model) - { - models.push_back (model); -//printf("#2 Intro model [%s]\n",model->getFileName().c_str()); - } - } - } - - if (showIntroModelsRandom == true) - { - std::vector < Model * >modelList; - -//unsigned int seed = time(NULL); - Chrono seed (true); - srand ((unsigned int) seed.getCurTicks ()); - int - failedLookups = 0; - std::map < int, - bool > - usedIndex; - for (; modelList.size () < models.size ();) - { - int - index = rand () % models.size (); - if (usedIndex.find (index) != usedIndex.end ()) - { - failedLookups++; - srand ((unsigned int) seed.getCurTicks () / failedLookups); - continue; - } -//printf("picIndex = %d list count = %d\n",picIndex,coreData.getMiscTextureList().size()); - modelList.push_back (models[index]); - usedIndex[index] = true; - srand ((unsigned int) seed.getCurTicks () / - (unsigned int) modelList.size ()); - } - models = modelList; - } - } - - int - displayItemNumber = 1; - int - appear = Intro::appearTime; - int - disappear = - Intro::showTime + Intro::appearTime + (Intro::disapearTime * 2); - - const unsigned int - maxIntroLines = 100; - Lang & lang = Lang::getInstance (); - for (unsigned int i = 1; i < maxIntroLines; ++i) - { - string introTagName = "IntroText" + intToStr (i); - string introTagTextureName = "IntroTexture" + intToStr (i); - - if (lang.hasString (introTagName, "", true) == true || - lang.hasString (introTagTextureName, "", true) == true) - { - string lineText = ""; - - if (lang.hasString (introTagName, "", true) == true) - { - lineText = lang.getString (introTagName, "", true); - } - - string showStartTime = "IntroStartMilliseconds" + intToStr (i); - - int - displayTime = appear; - if (lang.hasString (showStartTime, "", true) == true) - { - displayTime = strToInt (lang.getString (showStartTime, "", true)); - } - else - { - if (i == 1) - { - displayTime = appear; - } - else if (i == 2) - { - displayTime = disappear; - } - else if (i >= 3) - { - displayTime = disappear * (++displayItemNumber); - } - } - -// Is this a texture? - if (lang.hasString (introTagName, "", true) == false && - lang.hasString (introTagTextureName, "", true) == true) - { - - string - introTagTextureWidthName = "IntroTextureWidth" + intToStr (i); - string - introTagTextureHeightName = "IntroTextureHeight" + intToStr (i); - - lineText = lang.getString (introTagTextureName, "", true); - Texture2D * - logoTexture = renderer.newTexture2D (rsGlobal); - if (logoTexture) - { - logoTexture->setMipmap (false); - logoTexture->getPixmap ()->load (lineText); - - renderer.initTexture (rsGlobal, logoTexture); - } - - - int - textureWidth = 256; - if (logoTexture != NULL) - { - textureWidth = logoTexture->getTextureWidth (); - } - if (lang.hasString (introTagTextureWidthName, "", true) == true) - { - textureWidth = - strToInt (lang.getString - (introTagTextureWidthName, "", true)); - } - - int - textureHeight = 128; - if (logoTexture != NULL) - { - textureHeight = logoTexture->getTextureHeight (); - } - if (lang.hasString (introTagTextureHeightName, "", true) == true) - { - textureHeight = - strToInt (lang.getString - (introTagTextureHeightName, "", true)); - } - - texts.push_back (new - IntroText (logoTexture, - Vec2i (w / 2 - (textureWidth / 2), - h / 2 - (textureHeight / 2)), - Vec2i (textureWidth, textureHeight), - displayTime)); - } -// This is a line of text - else - { - string introTagTextXName = "IntroTextX" + intToStr (i); - string introTagTextYName = "IntroTextY" + intToStr (i); - string - introTagTextFontTypeName = "IntroTextFontType" + intToStr (i); - - int - textX = -1; - if (lang.hasString (introTagTextXName, "", true) == true) - { - string value = lang.getString (introTagTextXName, "", true); - if (value.length () > 0 && (value[0] == '+' || value[0] == '-')) - { - textX = w / 2 + strToInt (value); - } - else - { - textX = strToInt (value); - } - } - - int - textY = -1; - if (lang.hasString (introTagTextYName, "", true) == true) - { - string value = lang.getString (introTagTextYName, "", true); - if (value.length () > 0 && (value[0] == '+' || value[0] == '-')) - { - textY = h / 2 + strToInt (value); - } - else - { - textY = strToInt (value); - } - } - - Font2D * - font = coreData.getMenuFontVeryBig (); - Font3D * - font3d = coreData.getMenuFontVeryBig3D (); - - if (lang.hasString (introTagTextFontTypeName, "", true) == true) - { - string - value = lang.getString (introTagTextFontTypeName, "", true); - if (value == "displaynormal") - { - font = coreData.getDisplayFont (); - font3d = coreData.getDisplayFont3D (); - } - else if (value == "displaysmall") - { - font = coreData.getDisplayFontSmall (); - font3d = coreData.getDisplayFontSmall3D (); - } - else if (value == "menunormal") - { - font = coreData.getMenuFontNormal (); - font3d = coreData.getMenuFontNormal3D (); - } - else if (value == "menubig") - { - font = coreData.getMenuFontBig (); - font3d = coreData.getMenuFontBig3D (); - } - else if (value == "menuverybig") - { - font = coreData.getMenuFontVeryBig (); - font3d = coreData.getMenuFontVeryBig3D (); - } - else if (value == "consolenormal") - { - font = coreData.getConsoleFont (); - font3d = coreData.getConsoleFont3D (); - } - - } - texts.push_back (new - IntroText (lineText, Vec2i (textX, textY), - displayTime, font, font3d)); - } - } - else - { - break; - } - } - modelShowTime = disappear * (displayItemNumber); - if (lang.hasString ("IntroModelStartMilliseconds", "", true) == true) - { - modelShowTime = - strToInt (lang.getString ("IntroModelStartMilliseconds", "", true)); - } - else - { - modelShowTime = disappear * (displayItemNumber); - } - -/* -string lineText = "Based on award-winning classic Glest"; -texts.push_back(new Text(lineText, Vec2i(-1, -1), appear, coreData.getMenuFontVeryBig(),coreData.getMenuFontVeryBig3D())); -lineText = "the MegaGlest Team presents"; -texts.push_back(new Text(lineText, Vec2i(-1, -1), disappear, coreData.getMenuFontVeryBig(),coreData.getMenuFontVeryBig3D())); -lineText = "a libre software real-time strategy game"; -texts.push_back(new Text(lineText, Vec2i(-1, -1), disappear *(++displayItemNumber), coreData.getMenuFontVeryBig(),coreData.getMenuFontVeryBig3D())); - -texts.push_back(new Text(coreData.getLogoTexture(), Vec2i(w/2-128, h/2-64), Vec2i(256, 128), disappear *(++displayItemNumber))); -texts.push_back(new Text(glestVersionString, Vec2i(w/2+45, h/2-45), disappear *(displayItemNumber++), coreData.getMenuFontNormal(),coreData.getMenuFontNormal3D())); -lineText = "www.megaglest.org"; -//texts.push_back(new Text(lineText, Vec2i(-1, -1), disappear *(displayItemNumber++), coreData.getMenuFontVeryBig(),coreData.getMenuFontVeryBig3D())); -texts.push_back(new Text(lineText, Vec2i(-1, h/2-45-18), disappear *(displayItemNumber-1), coreData.getMenuFontVeryBig(),coreData.getMenuFontVeryBig3D())); -*/ - - - - if (showIntroPics > 0 && coreData.getMiscTextureList ().size () > 0) - { - const int - showMiscTime = showIntroPicsTime; - - std::vector < Texture2D * >intoTexList; - if (showIntroPicsRandom == true) - { -//unsigned int seed = time(NULL); - Chrono seed (true); - srand ((unsigned int) seed.getCurTicks ()); - int - failedLookups = 0; - std::map < int, - bool > - usedIndex; - for (; (int) intoTexList.size () < showIntroPics;) - { - int - picIndex = rand () % coreData.getMiscTextureList ().size (); - if (usedIndex.find (picIndex) != usedIndex.end ()) - { - failedLookups++; - srand ((unsigned int) seed.getCurTicks () / failedLookups); - - if (failedLookups > 10000) - { - for (unsigned int i = 0; - i < coreData.getMiscTextureList ().size (); ++i) - { - if (usedIndex.find (i) == usedIndex.end ()) - { - picIndex = i; - break; - } - } - } - else - { - continue; - } - } -//printf("picIndex = %d list count = %d\n",picIndex,coreData.getMiscTextureList().size()); - intoTexList.push_back (coreData.getMiscTextureList ()[picIndex]); - usedIndex[picIndex] = true; - srand ((unsigned int) seed.getCurTicks () / - (unsigned int) intoTexList.size ()); - } - } - else - { - for (unsigned int i = 0; - i < (unsigned int) coreData.getMiscTextureList ().size () && - i < (unsigned int) showIntroPics; ++i) - { - Texture2D * - tex = coreData.getMiscTextureList ()[i]; - intoTexList.push_back (tex); - } - } - - for (unsigned int i = 0; i < intoTexList.size (); ++i) - { - Texture2D * - tex = intoTexList[i]; -//printf("tex # %d [%s]\n",i,tex->getPath().c_str()); - - Vec2i texPlacement; - if (i == 0 || i % 9 == 0) - { - texPlacement = Vec2i (1, h - tex->getTextureHeight ()); - } - else if (i == 1 || i % 9 == 1) - { - texPlacement = Vec2i (1, 1); - } - else if (i == 2 || i % 9 == 2) - { - texPlacement = Vec2i (w - tex->getTextureWidth (), 1); - } - else if (i == 3 || i % 9 == 3) - { - texPlacement = - Vec2i (w - tex->getTextureWidth (), - h - tex->getTextureHeight ()); - } - else if (i == 4 || i % 9 == 4) - { - texPlacement = - Vec2i (w / 2 - tex->getTextureWidth () / 2, - h - tex->getTextureHeight ()); - } - else if (i == 5 || i % 9 == 5) - { - texPlacement = Vec2i (w / 2 - tex->getTextureWidth () / 2, 1); - } - else if (i == 6 || i % 9 == 6) - { - texPlacement = - Vec2i (1, (h / 2) - (tex->getTextureHeight () / 2)); - } - else if (i == 7 || i % 9 == 7) - { - texPlacement = - Vec2i (w - tex->getTextureWidth (), - (h / 2) - (tex->getTextureHeight () / 2)); - } - - int - textureStartTime = disappear * displayItemNumber; - if (lang.hasString ("IntroTextureStartMilliseconds", "", true) == - true) - { - textureStartTime = - strToInt (lang.getString ("IntroTextureStartMilliseconds", "", - true)); - } - - texts.push_back (new - IntroText (tex, texPlacement, - Vec2i (tex->getTextureWidth (), - tex->getTextureHeight ()), - textureStartTime + - (showMiscTime * (i + 1)))); - } - } - - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - renderer.swapBuffers (); - } - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false - &&::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer () == true - && CoreData::getInstance ().hasIntroVideoFilename () == true) - { - string - introVideoFile = CoreData::getInstance ().getIntroVideoFilename (); - string - introVideoFileFallback = - CoreData::getInstance ().getIntroVideoFilenameFallback (); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Intro Video [%s] [%s]\n", introVideoFile.c_str (), - introVideoFileFallback.c_str ()); - - Context * - c = GraphicsInterface::getInstance ().getCurrentContext (); - PlatformContextGl * - glCtx = static_cast < ContextGl * >(c)->getPlatformContextGlPtr (); - SDL_Window * - window = glCtx->getScreenWindow (); - SDL_Surface * - screen = glCtx->getScreenSurface (); - - string - vlcPluginsPath = - Config::getInstance ().getString ("VideoPlayerPluginsPath", ""); -//printf("screen->w = %d screen->h = %d screen->format->BitsPerPixel = %d\n",screen->w,screen->h,screen->format->BitsPerPixel); - ::Shared::Graphics::VideoPlayer player (&Renderer::getInstance (), - introVideoFile, - introVideoFileFallback, - window, - 0, 0, - screen->w, - screen->h, - screen->format->BitsPerPixel, - false, - vlcPluginsPath, - SystemFlags::VERBOSE_MODE_ENABLED); - player.PlayVideo (); - exitAfterIntroVideo = true; - return; - } - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - Intro::~Intro () - { - deleteValues (texts.begin (), texts.end ()); - -//deleteValues(introTextureList.begin(),introTextureList.end()); -// if(test) { -// glmDelete(test); -// } - -//Shared::Graphics::md5::cleanupMD5OpenGL(); - } - - void - Intro::update () - { - if (exitAfterIntroVideo == true) - { - mouseUpLeft (0, 0); -//cleanup(); - return; - } - timer++; - if (timer > introTime * GameConstants::updateFps / 1000) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - cleanup (); - return; - } - - if (Config::getInstance ().getBool ("AutoTest")) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - AutoTest::getInstance ().updateIntro (program); - return; - } - - mouse2d = (mouse2d + 1) % Renderer::maxMouse2dAnim; - - if (targetCamera != NULL) - { - t += - ((0.01f + - (1.f - t) / 10.f) / 20.f) * (60.f / GameConstants::updateFps); - -//interpolate position - camera.setPosition (lastCamera. - getPosition ().lerp (t, - targetCamera-> - getPosition ())); - -//interpolate orientation - Quaternion - q = - lastCamera.getOrientation ().lerp (t, - targetCamera->getOrientation ()); - camera.setOrientation (q); - - if (t >= 1.f) - { - targetCamera = NULL; - t = 0.f; - } - } - -//fade - if (fade <= 1.f) - { - fade += 0.6f / GameConstants::updateFps; - if (fade > 1.f) - { - fade = 1.f; - } - } - -//animation -//const float minSpeed = 0.015f; -//const float minSpeed = 0.010f; -//const float maxSpeed = 0.6f; - const float - minSpeed = modelMinAnimSpeed; - const float - maxSpeed = modelMaxAnimSpeed; - anim += - (maxSpeed / GameConstants::updateFps) / 5 + - random.randRange (minSpeed, - max (minSpeed + 0.0001f, - (maxSpeed / GameConstants::updateFps) / 5.f)); - if (anim > 1.f) - { - anim = 0.f; - } - -//animTimer.update(); - } - - void - Intro::renderModelBackground () - { -// Black background - glClearColor (0, 0, 0, 1); - - if (models.empty () == false) - { - int - difTime = 1000 * timer / GameConstants::updateFps - modelShowTime; - int - totalModelShowTime = Intro::introTime - modelShowTime; - int - individualModelShowTime = totalModelShowTime / (int) models.size (); - -//printf("difTime = %d individualModelShowTime = %d modelIndex = %d\n",difTime,individualModelShowTime,modelIndex); - -//int difTime= 1; - if (difTime > 0) - { - if (difTime > ((modelIndex + 1) * individualModelShowTime)) - { -//int oldmodelIndex = modelIndex; - if (modelIndex + 1 < (int) models.size ()) - { - modelIndex++; - -//position -//nextCamera.setPosition(camera.getPosition()); -// nextCamera.setPosition(Vec3f(84,-9,11)); -// -// //rotation -// //Vec3f startRotation(0,12,0); -// Vec3f startRotation(0,-80,0); -// nextCamera.setOrientation(Quaternion(EulerAngles( -// degToRad(startRotation.x), -// degToRad(startRotation.y), -// degToRad(startRotation.z)))); -// -// this->targetCamera = &nextCamera; -// this->lastCamera= camera; -// this->t= 0.f; - - } -//printf("oldmodelIndex = %d, modelIndex = %d\n",oldmodelIndex,modelIndex); - } - Renderer & renderer = Renderer::getInstance (); - vector < Model * >characterModels; - characterModels.push_back (NULL); - characterModels.push_back (NULL); - characterModels.push_back (models[modelIndex]); - const - Vec3f - characterPosition = startPosition; - renderer.renderMenuBackground (&camera, fade, NULL, characterModels, - characterPosition, anim); - } - } - } - - void - Intro::render () - { - Renderer & renderer = Renderer::getInstance (); - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == true) - { - return; - } - - canRender (); - incrementFps (); - - renderer.clearBuffers (); - renderer.reset3dMenu (); - - renderer.clearZBuffer (); - renderer.loadCameraMatrix (&camera); - - renderModelBackground (); - renderer.renderParticleManager (rsMenu); - - renderer.reset2d (); - - for (int i = 0; i < (int) texts.size (); ++i) - { - IntroText * - text = texts[i]; - - int - difTime = - 1000 * timer / GameConstants::updateFps - text->getTime (); - - if (difTime > 0 && difTime < appearTime + showTime + disapearTime) - { - float - alpha = 1.f; - if (difTime > 0 && difTime < appearTime) - { -//apearing - alpha = static_cast < float >(difTime) / - appearTime; - } - else if (difTime > 0 - && difTime < appearTime + showTime + disapearTime) - { -//disappearing - alpha = - 1.f - static_cast < float >(difTime - appearTime - showTime) / - disapearTime; - } - - if (text->getText ().empty () == false) - { - int - renderX = text->getPos ().x; - int - renderY = text->getPos ().y; - - if (Renderer::renderText3DEnabled) - { - if (renderX < 0) - { - const - Metrics & - metrics = Metrics::getInstance (); - int - w = metrics.getVirtualW (); - renderX = - (w / 2) - - (text->getFont3D ()-> - getMetrics ()->getTextWidth (text->getText ()) / 2); - } - if (renderY < 0) - { - const - Metrics & - metrics = Metrics::getInstance (); - int - h = metrics.getVirtualH (); - renderY = - (h / 2) + - (text->getFont3D ()-> - getMetrics ()->getHeight (text->getText ()) / 2); - } - - renderer.renderText3D (text->getText (), text->getFont3D (), - alpha, renderX, renderY, false); - } - else - { - if (renderX < 0) - { - const - Metrics & - metrics = Metrics::getInstance (); - int - w = metrics.getVirtualW (); - renderX = (w / 2); - } - if (renderY < 0) - { - const - Metrics & - metrics = Metrics::getInstance (); - int - h = metrics.getVirtualH (); - renderY = (h / 2); - } - - renderer.renderText (text->getText (), text->getFont (), alpha, - renderX, renderY, true); - } - } - - if (text->getTexture () != NULL) - { - renderer.renderTextureQuad (text->getPos ().x, text->getPos ().y, - text->getSize ().x, - text->getSize ().y, - text->getTexture (), alpha); - } - } - } - - if (program != NULL) - program->renderProgramMsgBox (); - - if (this->forceMouseRender == true) - renderer.renderMouse2d (mouseX, mouseY, mouse2d, 0.f); - - bool - showIntroTiming = - Config::getInstance ().getBool ("ShowIntroTiming", "false"); - if (showIntroTiming == true && Intro::introTime > 0) - { - CoreData & coreData = CoreData::getInstance (); - int - difTime = 1000 * timer / GameConstants::updateFps; - string - timingText = - intToStr (difTime) + " / " + intToStr (Intro::introTime); - - if (Renderer::renderText3DEnabled) - { -//const Metrics &metrics= Metrics::getInstance(); -//int w= metrics.getVirtualW(); -//int h= metrics.getVirtualH(); - - renderer.renderText3D (timingText, coreData.getMenuFontVeryBig3D (), - 1, 10, 20, false); - } - else - { -//const Metrics &metrics= Metrics::getInstance(); -//int w= metrics.getVirtualW(); -//int h= metrics.getVirtualH(); - - renderer.renderText (timingText, coreData.getMenuFontVeryBig (), 1, - 10, 20, false); - } - } - - renderer.renderFPSWhenEnabled (lastFps); - renderer.swapBuffers (); - } - - void - Intro::keyDown (SDL_KeyboardEvent key) - { - SDL_keysym keystate = key.keysym; -//printf("keystate.mod = %d key = unicode[%d] regular[%d] lalt [%d] ralt [%d] alt [%d]\n",keystate.mod,key.keysym.unicode,key.keysym.sym,(keystate.mod & KMOD_LALT),(keystate.mod & KMOD_RALT),(keystate.mod & KMOD_ALT)); - - if (keystate.mod & (KMOD_LALT | KMOD_RALT)) - { -//printf("ALT KEY #1\n"); - - if (isKeyPressed (SDLK_RETURN, key) == true || - isKeyPressed (SDLK_RALT, key) == true || - isKeyPressed (SDLK_LALT, key) == true) - { - return; - } - } - -//printf("Exiting intro\n"); - mouseUpLeft (0, 0); - } - - void - Intro::mouseUpLeft (int x, int y) - { - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - soundRenderer.stopMusic (CoreData::getInstance ().getIntroMusic ()); - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - if (CoreData::getInstance ().hasMainMenuVideoFilename () == false) - { - soundRenderer.playMusic (CoreData::getInstance ().getMenuMusic ()); - } - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - cleanup (); - } - - void - Intro::cleanup () - { - Renderer::getInstance ().endMenu (); - - program->setState (new MainMenu (program)); - } - - void - Intro::mouseMove (int x, int y, const MouseState * ms) - { - mouseX = x; - mouseY = y; - } - -}} //end namespace +namespace + Shared::Xml; + +namespace Glest { + namespace Game { + + //struct Timer { + //public: + // Timer () + // : current_time (0.0), last_time (0.0) { } + // + //public: + // void update () { + // last_time = current_time; + // current_time = static_cast(SDL_GetTicks ()) / 1000.0; + // } + // + // double deltaTime () const { + // return (current_time - last_time); + // } + // + //public: + // double current_time; + // double last_time; + // + //} animTimer; + + // ===================================================== + // class Text + // ===================================================== + + IntroText::IntroText(const string & text, const Vec2i & pos, int time, + Font2D * font, Font3D * font3D) { + this->text = text; + this->pos = pos; + this->time = time; + this->texture = NULL; + this->font = font; + this->font3D = font3D; + } + + IntroText::IntroText(const Texture2D * texture, const Vec2i & pos, + const Vec2i & size, int time) { + this->pos = pos; + this->size = size; + this->time = time; + this->texture = texture; + this->font = NULL; + this->font3D = NULL; + } + + // ===================================================== + // class Intro + // ===================================================== + + int + Intro::introTime = 50000; + int + Intro::appearTime = 2500; + int + Intro::showTime = 3500; + int + Intro::disapearTime = 2500; + + Intro::Intro(Program * program) : + ProgramState(program) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false && + (::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == false + || CoreData::getInstance().hasIntroVideoFilename() == false)) { + soundRenderer.playMusic(CoreData::getInstance().getIntroMusic()); + } + + const + Metrics & + metrics = Metrics::getInstance(); + int + w = metrics.getVirtualW(); + int + h = metrics.getVirtualH(); + timer = 0; + mouseX = 0; + mouseY = 0; + mouse2d = 0; + exitAfterIntroVideo = false; + + Renderer & renderer = Renderer::getInstance(); + //renderer.init3dListMenu(NULL); + renderer.initMenu(NULL); + fade = 0.f; + anim = 0.f; + targetCamera = NULL; + t = 0.f; + + startPosition.x = 5;; + startPosition.y = 10; + startPosition.z = 40; + camera.setPosition(startPosition); + + Vec3f startRotation; + startRotation.x = 0; + startRotation.y = 0; + startRotation.z = 0; + + camera.setOrientation(Quaternion + (EulerAngles + (degToRad(startRotation.x), + degToRad(startRotation.y), + degToRad(startRotation.z)))); + + Intro::introTime = 3000; + Intro::appearTime = 500; + Intro::showTime = 500; + Intro::disapearTime = 500; + int + showIntroPics = 0; + int + showIntroPicsTime = 0; + bool showIntroPicsRandom = false; + bool showIntroModels = false; + bool showIntroModelsRandom = false; + modelMinAnimSpeed = 0; + modelMaxAnimSpeed = 0; + + XmlTree xmlTree; + string + data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + xmlTree.load(getGameCustomCoreDataPath + (data_path, "data/core/menu/menu.xml"), + Properties::getTagReplacementValues()); + const XmlNode * + menuNode = xmlTree.getRootNode(); + + if (menuNode->hasChild("intro") == true) { + const XmlNode * + introNode = menuNode->getChild("intro"); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + //camera + const XmlNode * + cameraNode = introNode->getChild("camera"); + + //position + const XmlNode * + positionNode = cameraNode->getChild("start-position"); + startPosition.x = positionNode->getAttribute("x")->getFloatValue(); + startPosition.y = positionNode->getAttribute("y")->getFloatValue(); + startPosition.z = positionNode->getAttribute("z")->getFloatValue(); + camera.setPosition(startPosition); + + //rotation + const XmlNode * + rotationNode = cameraNode->getChild("start-rotation"); + Vec3f startRotation; + startRotation.x = rotationNode->getAttribute("x")->getFloatValue(); + startRotation.y = rotationNode->getAttribute("y")->getFloatValue(); + startRotation.z = rotationNode->getAttribute("z")->getFloatValue(); + camera.setOrientation(Quaternion + (EulerAngles + (degToRad(startRotation.x), + degToRad(startRotation.y), + degToRad(startRotation.z)))); + + // intro info + const XmlNode * + introTimeNode = introNode->getChild("intro-time"); + Intro::introTime = + introTimeNode->getAttribute("value")->getIntValue(); + const XmlNode * + appearTimeNode = introNode->getChild("appear-time"); + Intro::appearTime = + appearTimeNode->getAttribute("value")->getIntValue(); + const XmlNode * + showTimeNode = introNode->getChild("show-time"); + Intro::showTime = + showTimeNode->getAttribute("value")->getIntValue(); + const XmlNode * + disappearTimeNode = introNode->getChild("disappear-time"); + Intro::disapearTime = + disappearTimeNode->getAttribute("value")->getIntValue(); + const XmlNode * + showIntroPicturesNode = introNode->getChild("show-intro-pictures"); + showIntroPics = + showIntroPicturesNode->getAttribute("value")->getIntValue(); + showIntroPicsTime = + showIntroPicturesNode->getAttribute("time")->getIntValue(); + showIntroPicsRandom = + showIntroPicturesNode->getAttribute("random")->getBoolValue(); + + const XmlNode * + showIntroModelsNode = introNode->getChild("show-intro-models"); + showIntroModels = + showIntroModelsNode->getAttribute("value")->getBoolValue(); + showIntroModelsRandom = + showIntroModelsNode->getAttribute("random")->getBoolValue(); + modelMinAnimSpeed = + showIntroModelsNode-> + getAttribute("min-anim-speed")->getFloatValue(); + modelMaxAnimSpeed = + showIntroModelsNode-> + getAttribute("max-anim-speed")->getFloatValue(); + } + + //load main model + modelIndex = 0; + models.clear(); + if (showIntroModels == true) { + + //getGameCustomCoreDataPath(data_path, "data/core/menu/menu.xml") + string + introPath = + getGameCustomCoreDataPath(data_path, + "") + + "data/core/menu/main_model/intro*.g3d"; + vector < string > introModels; + findAll(introPath, introModels, false, false); + for (int i = 0; i < (int) introModels.size(); ++i) { + string logo = introModels[i]; + Model * + model = renderer.newModel(rsMenu, + getGameCustomCoreDataPath(data_path, + "") + + "data/core/menu/main_model/" + logo); + if (model) { + models.push_back(model); + //printf("#1 Intro model [%s]\n",model->getFileName().c_str()); + } + } + + if (models.empty() == true) { + introPath = data_path + "data/core/menu/main_model/intro*.g3d"; + //vector introModels; + findAll(introPath, introModels, false, false); + for (int i = 0; i < (int) introModels.size(); ++i) { + string logo = introModels[i]; + Model * + model = renderer.newModel(rsMenu, + data_path + + "data/core/menu/main_model/" + logo); + if (model) { + models.push_back(model); + //printf("#2 Intro model [%s]\n",model->getFileName().c_str()); + } + } + } + + if (showIntroModelsRandom == true) { + std::vector < Model * >modelList; + + //unsigned int seed = time(NULL); + Chrono seed(true); + srand((unsigned int) seed.getCurTicks()); + int + failedLookups = 0; + std::map < int, + bool > + usedIndex; + for (; modelList.size() < models.size();) { + int + index = rand() % models.size(); + if (usedIndex.find(index) != usedIndex.end()) { + failedLookups++; + srand((unsigned int) seed.getCurTicks() / failedLookups); + continue; + } + //printf("picIndex = %d list count = %d\n",picIndex,coreData.getMiscTextureList().size()); + modelList.push_back(models[index]); + usedIndex[index] = true; + srand((unsigned int) seed.getCurTicks() / + (unsigned int) modelList.size()); + } + models = modelList; + } + } + + int + displayItemNumber = 1; + int + appear = Intro::appearTime; + int + disappear = + Intro::showTime + Intro::appearTime + (Intro::disapearTime * 2); + + const unsigned int + maxIntroLines = 100; + Lang & lang = Lang::getInstance(); + for (unsigned int i = 1; i < maxIntroLines; ++i) { + string introTagName = "IntroText" + intToStr(i); + string introTagTextureName = "IntroTexture" + intToStr(i); + + if (lang.hasString(introTagName, "", true) == true || + lang.hasString(introTagTextureName, "", true) == true) { + string lineText = ""; + + if (lang.hasString(introTagName, "", true) == true) { + lineText = lang.getString(introTagName, "", true); + } + + string showStartTime = "IntroStartMilliseconds" + intToStr(i); + + int + displayTime = appear; + if (lang.hasString(showStartTime, "", true) == true) { + displayTime = strToInt(lang.getString(showStartTime, "", true)); + } else { + if (i == 1) { + displayTime = appear; + } else if (i == 2) { + displayTime = disappear; + } else if (i >= 3) { + displayTime = disappear * (++displayItemNumber); + } + } + + // Is this a texture? + if (lang.hasString(introTagName, "", true) == false && + lang.hasString(introTagTextureName, "", true) == true) { + + string + introTagTextureWidthName = "IntroTextureWidth" + intToStr(i); + string + introTagTextureHeightName = "IntroTextureHeight" + intToStr(i); + + lineText = lang.getString(introTagTextureName, "", true); + Texture2D * + logoTexture = renderer.newTexture2D(rsGlobal); + if (logoTexture) { + logoTexture->setMipmap(false); + logoTexture->getPixmap()->load(lineText); + + renderer.initTexture(rsGlobal, logoTexture); + } + + + int + textureWidth = 256; + if (logoTexture != NULL) { + textureWidth = logoTexture->getTextureWidth(); + } + if (lang.hasString(introTagTextureWidthName, "", true) == true) { + textureWidth = + strToInt(lang.getString + (introTagTextureWidthName, "", true)); + } + + int + textureHeight = 128; + if (logoTexture != NULL) { + textureHeight = logoTexture->getTextureHeight(); + } + if (lang.hasString(introTagTextureHeightName, "", true) == true) { + textureHeight = + strToInt(lang.getString + (introTagTextureHeightName, "", true)); + } + + texts.push_back(new + IntroText(logoTexture, + Vec2i(w / 2 - (textureWidth / 2), + h / 2 - (textureHeight / 2)), + Vec2i(textureWidth, textureHeight), + displayTime)); + } + // This is a line of text + else { + string introTagTextXName = "IntroTextX" + intToStr(i); + string introTagTextYName = "IntroTextY" + intToStr(i); + string + introTagTextFontTypeName = "IntroTextFontType" + intToStr(i); + + int + textX = -1; + if (lang.hasString(introTagTextXName, "", true) == true) { + string value = lang.getString(introTagTextXName, "", true); + if (value.length() > 0 && (value[0] == '+' || value[0] == '-')) { + textX = w / 2 + strToInt(value); + } else { + textX = strToInt(value); + } + } + + int + textY = -1; + if (lang.hasString(introTagTextYName, "", true) == true) { + string value = lang.getString(introTagTextYName, "", true); + if (value.length() > 0 && (value[0] == '+' || value[0] == '-')) { + textY = h / 2 + strToInt(value); + } else { + textY = strToInt(value); + } + } + + Font2D * + font = coreData.getMenuFontVeryBig(); + Font3D * + font3d = coreData.getMenuFontVeryBig3D(); + + if (lang.hasString(introTagTextFontTypeName, "", true) == true) { + string + value = lang.getString(introTagTextFontTypeName, "", true); + if (value == "displaynormal") { + font = coreData.getDisplayFont(); + font3d = coreData.getDisplayFont3D(); + } else if (value == "displaysmall") { + font = coreData.getDisplayFontSmall(); + font3d = coreData.getDisplayFontSmall3D(); + } else if (value == "menunormal") { + font = coreData.getMenuFontNormal(); + font3d = coreData.getMenuFontNormal3D(); + } else if (value == "menubig") { + font = coreData.getMenuFontBig(); + font3d = coreData.getMenuFontBig3D(); + } else if (value == "menuverybig") { + font = coreData.getMenuFontVeryBig(); + font3d = coreData.getMenuFontVeryBig3D(); + } else if (value == "consolenormal") { + font = coreData.getConsoleFont(); + font3d = coreData.getConsoleFont3D(); + } + + } + texts.push_back(new + IntroText(lineText, Vec2i(textX, textY), + displayTime, font, font3d)); + } + } else { + break; + } + } + modelShowTime = disappear * (displayItemNumber); + if (lang.hasString("IntroModelStartMilliseconds", "", true) == true) { + modelShowTime = + strToInt(lang.getString("IntroModelStartMilliseconds", "", true)); + } else { + modelShowTime = disappear * (displayItemNumber); + } + + /* + string lineText = "Based on award-winning classic Glest"; + texts.push_back(new Text(lineText, Vec2i(-1, -1), appear, coreData.getMenuFontVeryBig(),coreData.getMenuFontVeryBig3D())); + lineText = "the MegaGlest Team presents"; + texts.push_back(new Text(lineText, Vec2i(-1, -1), disappear, coreData.getMenuFontVeryBig(),coreData.getMenuFontVeryBig3D())); + lineText = "a libre software real-time strategy game"; + texts.push_back(new Text(lineText, Vec2i(-1, -1), disappear *(++displayItemNumber), coreData.getMenuFontVeryBig(),coreData.getMenuFontVeryBig3D())); + + texts.push_back(new Text(coreData.getLogoTexture(), Vec2i(w/2-128, h/2-64), Vec2i(256, 128), disappear *(++displayItemNumber))); + texts.push_back(new Text(glestVersionString, Vec2i(w/2+45, h/2-45), disappear *(displayItemNumber++), coreData.getMenuFontNormal(),coreData.getMenuFontNormal3D())); + lineText = "www.megaglest.org"; + //texts.push_back(new Text(lineText, Vec2i(-1, -1), disappear *(displayItemNumber++), coreData.getMenuFontVeryBig(),coreData.getMenuFontVeryBig3D())); + texts.push_back(new Text(lineText, Vec2i(-1, h/2-45-18), disappear *(displayItemNumber-1), coreData.getMenuFontVeryBig(),coreData.getMenuFontVeryBig3D())); + */ + + + + if (showIntroPics > 0 && coreData.getMiscTextureList().size() > 0) { + const int + showMiscTime = showIntroPicsTime; + + std::vector < Texture2D * >intoTexList; + if (showIntroPicsRandom == true) { + //unsigned int seed = time(NULL); + Chrono seed(true); + srand((unsigned int) seed.getCurTicks()); + int + failedLookups = 0; + std::map < int, + bool > + usedIndex; + for (; (int) intoTexList.size() < showIntroPics;) { + int + picIndex = rand() % coreData.getMiscTextureList().size(); + if (usedIndex.find(picIndex) != usedIndex.end()) { + failedLookups++; + srand((unsigned int) seed.getCurTicks() / failedLookups); + + if (failedLookups > 10000) { + for (unsigned int i = 0; + i < coreData.getMiscTextureList().size(); ++i) { + if (usedIndex.find(i) == usedIndex.end()) { + picIndex = i; + break; + } + } + } else { + continue; + } + } + //printf("picIndex = %d list count = %d\n",picIndex,coreData.getMiscTextureList().size()); + intoTexList.push_back(coreData.getMiscTextureList()[picIndex]); + usedIndex[picIndex] = true; + srand((unsigned int) seed.getCurTicks() / + (unsigned int) intoTexList.size()); + } + } else { + for (unsigned int i = 0; + i < (unsigned int) coreData.getMiscTextureList().size() && + i < (unsigned int) showIntroPics; ++i) { + Texture2D * + tex = coreData.getMiscTextureList()[i]; + intoTexList.push_back(tex); + } + } + + for (unsigned int i = 0; i < intoTexList.size(); ++i) { + Texture2D * + tex = intoTexList[i]; + //printf("tex # %d [%s]\n",i,tex->getPath().c_str()); + + Vec2i texPlacement; + if (i == 0 || i % 9 == 0) { + texPlacement = Vec2i(1, h - tex->getTextureHeight()); + } else if (i == 1 || i % 9 == 1) { + texPlacement = Vec2i(1, 1); + } else if (i == 2 || i % 9 == 2) { + texPlacement = Vec2i(w - tex->getTextureWidth(), 1); + } else if (i == 3 || i % 9 == 3) { + texPlacement = + Vec2i(w - tex->getTextureWidth(), + h - tex->getTextureHeight()); + } else if (i == 4 || i % 9 == 4) { + texPlacement = + Vec2i(w / 2 - tex->getTextureWidth() / 2, + h - tex->getTextureHeight()); + } else if (i == 5 || i % 9 == 5) { + texPlacement = Vec2i(w / 2 - tex->getTextureWidth() / 2, 1); + } else if (i == 6 || i % 9 == 6) { + texPlacement = + Vec2i(1, (h / 2) - (tex->getTextureHeight() / 2)); + } else if (i == 7 || i % 9 == 7) { + texPlacement = + Vec2i(w - tex->getTextureWidth(), + (h / 2) - (tex->getTextureHeight() / 2)); + } + + int + textureStartTime = disappear * displayItemNumber; + if (lang.hasString("IntroTextureStartMilliseconds", "", true) == + true) { + textureStartTime = + strToInt(lang.getString("IntroTextureStartMilliseconds", "", + true)); + } + + texts.push_back(new + IntroText(tex, texPlacement, + Vec2i(tex->getTextureWidth(), + tex->getTextureHeight()), + textureStartTime + + (showMiscTime * (i + 1)))); + } + } + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + renderer.swapBuffers(); + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false + && ::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == true + && CoreData::getInstance().hasIntroVideoFilename() == true) { + string + introVideoFile = CoreData::getInstance().getIntroVideoFilename(); + string + introVideoFileFallback = + CoreData::getInstance().getIntroVideoFilenameFallback(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Intro Video [%s] [%s]\n", introVideoFile.c_str(), + introVideoFileFallback.c_str()); + + Context * + c = GraphicsInterface::getInstance().getCurrentContext(); + PlatformContextGl * + glCtx = static_cast (c)->getPlatformContextGlPtr(); + SDL_Window * + window = glCtx->getScreenWindow(); + SDL_Surface * + screen = glCtx->getScreenSurface(); + + string + vlcPluginsPath = + Config::getInstance().getString("VideoPlayerPluginsPath", ""); + //printf("screen->w = %d screen->h = %d screen->format->BitsPerPixel = %d\n",screen->w,screen->h,screen->format->BitsPerPixel); + ::Shared::Graphics::VideoPlayer player(&Renderer::getInstance(), + introVideoFile, + introVideoFileFallback, + window, + 0, 0, + screen->w, + screen->h, + screen->format->BitsPerPixel, + false, + vlcPluginsPath, + SystemFlags::VERBOSE_MODE_ENABLED); + player.PlayVideo(); + exitAfterIntroVideo = true; + return; + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + Intro::~Intro() { + deleteValues(texts.begin(), texts.end()); + + //deleteValues(introTextureList.begin(),introTextureList.end()); + // if(test) { + // glmDelete(test); + // } + + //Shared::Graphics::md5::cleanupMD5OpenGL(); + } + + void + Intro::update() { + if (exitAfterIntroVideo == true) { + mouseUpLeft(0, 0); + //cleanup(); + return; + } + timer++; + if (timer > introTime * GameConstants::updateFps / 1000) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + cleanup(); + return; + } + + if (Config::getInstance().getBool("AutoTest")) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + AutoTest::getInstance().updateIntro(program); + return; + } + + mouse2d = (mouse2d + 1) % Renderer::maxMouse2dAnim; + + if (targetCamera != NULL) { + t += + ((0.01f + + (1.f - t) / 10.f) / 20.f) * (60.f / GameConstants::updateFps); + + //interpolate position + camera.setPosition(lastCamera. + getPosition().lerp(t, + targetCamera-> + getPosition())); + + //interpolate orientation + Quaternion + q = + lastCamera.getOrientation().lerp(t, + targetCamera->getOrientation()); + camera.setOrientation(q); + + if (t >= 1.f) { + targetCamera = NULL; + t = 0.f; + } + } + + //fade + if (fade <= 1.f) { + fade += 0.6f / GameConstants::updateFps; + if (fade > 1.f) { + fade = 1.f; + } + } + + //animation + //const float minSpeed = 0.015f; + //const float minSpeed = 0.010f; + //const float maxSpeed = 0.6f; + const float + minSpeed = modelMinAnimSpeed; + const float + maxSpeed = modelMaxAnimSpeed; + anim += + (maxSpeed / GameConstants::updateFps) / 5 + + random.randRange(minSpeed, + max(minSpeed + 0.0001f, + (maxSpeed / GameConstants::updateFps) / 5.f)); + if (anim > 1.f) { + anim = 0.f; + } + + //animTimer.update(); + } + + void + Intro::renderModelBackground() { + // Black background + glClearColor(0, 0, 0, 1); + + if (models.empty() == false) { + int + difTime = 1000 * timer / GameConstants::updateFps - modelShowTime; + int + totalModelShowTime = Intro::introTime - modelShowTime; + int + individualModelShowTime = totalModelShowTime / (int) models.size(); + + //printf("difTime = %d individualModelShowTime = %d modelIndex = %d\n",difTime,individualModelShowTime,modelIndex); + + //int difTime= 1; + if (difTime > 0) { + if (difTime > ((modelIndex + 1) * individualModelShowTime)) { + //int oldmodelIndex = modelIndex; + if (modelIndex + 1 < (int) models.size()) { + modelIndex++; + + //position + //nextCamera.setPosition(camera.getPosition()); + // nextCamera.setPosition(Vec3f(84,-9,11)); + // + // //rotation + // //Vec3f startRotation(0,12,0); + // Vec3f startRotation(0,-80,0); + // nextCamera.setOrientation(Quaternion(EulerAngles( + // degToRad(startRotation.x), + // degToRad(startRotation.y), + // degToRad(startRotation.z)))); + // + // this->targetCamera = &nextCamera; + // this->lastCamera= camera; + // this->t= 0.f; + + } + //printf("oldmodelIndex = %d, modelIndex = %d\n",oldmodelIndex,modelIndex); + } + Renderer & renderer = Renderer::getInstance(); + vector < Model * >characterModels; + characterModels.push_back(NULL); + characterModels.push_back(NULL); + characterModels.push_back(models[modelIndex]); + const + Vec3f + characterPosition = startPosition; + renderer.renderMenuBackground(&camera, fade, NULL, characterModels, + characterPosition, anim); + } + } + } + + void + Intro::render() { + Renderer & renderer = Renderer::getInstance(); + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + canRender(); + incrementFps(); + + renderer.clearBuffers(); + renderer.reset3dMenu(); + + renderer.clearZBuffer(); + renderer.loadCameraMatrix(&camera); + + renderModelBackground(); + renderer.renderParticleManager(rsMenu); + + renderer.reset2d(); + + for (int i = 0; i < (int) texts.size(); ++i) { + IntroText * + text = texts[i]; + + int + difTime = + 1000 * timer / GameConstants::updateFps - text->getTime(); + + if (difTime > 0 && difTime < appearTime + showTime + disapearTime) { + float + alpha = 1.f; + if (difTime > 0 && difTime < appearTime) { + //apearing + alpha = static_cast (difTime) / + appearTime; + } else if (difTime > 0 + && difTime < appearTime + showTime + disapearTime) { + //disappearing + alpha = + 1.f - static_cast (difTime - appearTime - showTime) / + disapearTime; + } + + if (text->getText().empty() == false) { + int + renderX = text->getPos().x; + int + renderY = text->getPos().y; + + if (Renderer::renderText3DEnabled) { + if (renderX < 0) { + const + Metrics & + metrics = Metrics::getInstance(); + int + w = metrics.getVirtualW(); + renderX = + (w / 2) - + (text->getFont3D()-> + getMetrics()->getTextWidth(text->getText()) / 2); + } + if (renderY < 0) { + const + Metrics & + metrics = Metrics::getInstance(); + int + h = metrics.getVirtualH(); + renderY = + (h / 2) + + (text->getFont3D()-> + getMetrics()->getHeight(text->getText()) / 2); + } + + renderer.renderText3D(text->getText(), text->getFont3D(), + alpha, renderX, renderY, false); + } else { + if (renderX < 0) { + const + Metrics & + metrics = Metrics::getInstance(); + int + w = metrics.getVirtualW(); + renderX = (w / 2); + } + if (renderY < 0) { + const + Metrics & + metrics = Metrics::getInstance(); + int + h = metrics.getVirtualH(); + renderY = (h / 2); + } + + renderer.renderText(text->getText(), text->getFont(), alpha, + renderX, renderY, true); + } + } + + if (text->getTexture() != NULL) { + renderer.renderTextureQuad(text->getPos().x, text->getPos().y, + text->getSize().x, + text->getSize().y, + text->getTexture(), alpha); + } + } + } + + if (program != NULL) + program->renderProgramMsgBox(); + + if (this->forceMouseRender == true) + renderer.renderMouse2d(mouseX, mouseY, mouse2d, 0.f); + + bool + showIntroTiming = + Config::getInstance().getBool("ShowIntroTiming", "false"); + if (showIntroTiming == true && Intro::introTime > 0) { + CoreData & coreData = CoreData::getInstance(); + int + difTime = 1000 * timer / GameConstants::updateFps; + string + timingText = + intToStr(difTime) + " / " + intToStr(Intro::introTime); + + if (Renderer::renderText3DEnabled) { + //const Metrics &metrics= Metrics::getInstance(); + //int w= metrics.getVirtualW(); + //int h= metrics.getVirtualH(); + + renderer.renderText3D(timingText, coreData.getMenuFontVeryBig3D(), + 1, 10, 20, false); + } else { + //const Metrics &metrics= Metrics::getInstance(); + //int w= metrics.getVirtualW(); + //int h= metrics.getVirtualH(); + + renderer.renderText(timingText, coreData.getMenuFontVeryBig(), 1, + 10, 20, false); + } + } + + renderer.renderFPSWhenEnabled(lastFps); + renderer.swapBuffers(); + } + + void + Intro::keyDown(SDL_KeyboardEvent key) { + SDL_keysym keystate = key.keysym; + //printf("keystate.mod = %d key = unicode[%d] regular[%d] lalt [%d] ralt [%d] alt [%d]\n",keystate.mod,key.keysym.unicode,key.keysym.sym,(keystate.mod & KMOD_LALT),(keystate.mod & KMOD_RALT),(keystate.mod & KMOD_ALT)); + + if (keystate.mod & (KMOD_LALT | KMOD_RALT)) { + //printf("ALT KEY #1\n"); + + if (isKeyPressed(SDLK_RETURN, key) == true || + isKeyPressed(SDLK_RALT, key) == true || + isKeyPressed(SDLK_LALT, key) == true) { + return; + } + } + + //printf("Exiting intro\n"); + mouseUpLeft(0, 0); + } + + void + Intro::mouseUpLeft(int x, int y) { + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + soundRenderer.stopMusic(CoreData::getInstance().getIntroMusic()); + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + if (CoreData::getInstance().hasMainMenuVideoFilename() == false) { + soundRenderer.playMusic(CoreData::getInstance().getMenuMusic()); + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + cleanup(); + } + + void + Intro::cleanup() { + Renderer::getInstance().endMenu(); + + program->setState(new MainMenu(program)); + } + + void + Intro::mouseMove(int x, int y, const MouseState * ms) { + mouseX = x; + mouseY = y; + } + + } +} //end namespace diff --git a/source/glest_game/main/intro.h b/source/glest_game/main/intro.h index 600e527a9..1a19927dc 100644 --- a/source/glest_game/main/intro.h +++ b/source/glest_game/main/intro.h @@ -42,156 +42,146 @@ using Shared::Util::RandomGen; //class Md5Object; //}}} -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class Text -// ===================================================== + // ===================================================== + // class Text + // ===================================================== - class IntroText - { - private: - string text; - Vec2i pos; - Vec2i size; - int - time; - Font2D * - font; - Font3D * - font3D; - const Texture2D * - texture; + class IntroText { + private: + string text; + Vec2i pos; + Vec2i size; + int + time; + Font2D * + font; + Font3D * + font3D; + const Texture2D * + texture; - public: - IntroText (const string & text, const Vec2i & pos, int time, - Font2D * font, Font3D * font3D); - IntroText (const Texture2D * texture, const Vec2i & pos, - const Vec2i & size, int time); + public: + IntroText(const string & text, const Vec2i & pos, int time, + Font2D * font, Font3D * font3D); + IntroText(const Texture2D * texture, const Vec2i & pos, + const Vec2i & size, int time); - const - string & - getText () const - { - return - text; - } - Font2D * - getFont () - { - return font; - } - Font3D * - getFont3D () - { - return font3D; - } - const - Vec2i & - getPos () const - { - return - pos; - } - const - Vec2i & - getSize () const - { - return - size; - } - int - getTime () const - { - return - time; - } - const Texture2D * - getTexture () const - { - return - texture; - } - }; + const + string & + getText() const { + return + text; + } + Font2D * + getFont() { + return font; + } + Font3D * + getFont3D() { + return font3D; + } + const + Vec2i & + getPos() const { + return + pos; + } + const + Vec2i & + getSize() const { + return + size; + } + int + getTime() const { + return + time; + } + const Texture2D * + getTexture() const { + return + texture; + } + }; -// ===================================================== -// class Intro -// -/// ProgramState representing the intro -// ===================================================== + // ===================================================== + // class Intro + // + /// ProgramState representing the intro + // ===================================================== - class Intro: - public ProgramState - { - private: - static int - introTime; - static int - appearTime; - static int - showTime; - static int - disapearTime; + class Intro : + public ProgramState { + private: + static int + introTime; + static int + appearTime; + static int + showTime; + static int + disapearTime; - private: - vector < IntroText * >texts; - int - timer; - int - mouse2d; + private: + vector < IntroText * >texts; + int + timer; + int + mouse2d; -//Model *mainModel; - int - modelIndex; - float - modelMinAnimSpeed; - float - modelMaxAnimSpeed; - vector < Model * >models; - Camera nextCamera; - Camera camera; - Camera lastCamera; - const Camera * - targetCamera; - float - t; - RandomGen random; - float - anim; - float - fade; - Vec3f startPosition; - int - modelShowTime; + //Model *mainModel; + int + modelIndex; + float + modelMinAnimSpeed; + float + modelMaxAnimSpeed; + vector < Model * >models; + Camera nextCamera; + Camera camera; + Camera lastCamera; + const Camera * + targetCamera; + float + t; + RandomGen random; + float + anim; + float + fade; + Vec3f startPosition; + int + modelShowTime; -//GLMmodel* test; -//Shared::Graphics::md5::Md5Object *md5Test; + //GLMmodel* test; + //Shared::Graphics::md5::Md5Object *md5Test; - bool exitAfterIntroVideo; - void - cleanup (); - void - renderModelBackground (); + bool exitAfterIntroVideo; + void + cleanup(); + void + renderModelBackground(); - public: - explicit Intro (Program * program); - virtual ~ Intro (); + public: + explicit Intro(Program * program); + virtual ~Intro(); - virtual void - update (); - virtual void - render (); - virtual void - keyDown (SDL_KeyboardEvent key); - virtual void - mouseUpLeft (int x, int y); - void - mouseMove (int x, int y, const MouseState * ms); - }; + virtual void + update(); + virtual void + render(); + virtual void + keyDown(SDL_KeyboardEvent key); + virtual void + mouseUpLeft(int x, int y); + void + mouseMove(int x, int y, const MouseState * ms); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index 6f752ffba..c553c09e4 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -100,7 +100,7 @@ using namespace std; using namespace - Shared::Platform; +Shared::Platform; using namespace Shared::Util; using namespace Shared::Graphics; using namespace Shared::Graphics::Gl; @@ -116,9371 +116,8291 @@ using namespace Shared; * Namespace used for game related code. */ namespace - Glest -{ - namespace - Game - { + Glest { + namespace + Game { - static - string - tempDataLocation = getUserHome (); - static - string - mg_app_name = ""; - static - string - mailStringSupport = ""; - static - bool - sdl_quitCalled = false; + static + string + tempDataLocation = getUserHome(); + static + string + mg_app_name = ""; + static + string + mailStringSupport = ""; + static + bool + sdl_quitCalled = false; - static - bool - disableheadless_console = false; - static - bool - disableBacktrace = false; - static - bool - gameInitialized = false; + static + bool + disableheadless_console = false; + static + bool + disableBacktrace = false; + static + bool + gameInitialized = false; - static Program * - mainProgram = NULL; - static FileCRCPreCacheThread * - preCacheThread = NULL; + static Program * + mainProgram = NULL; + static FileCRCPreCacheThread * + preCacheThread = NULL; #ifdef WIN32 - static - string - runtimeErrorMsg = ""; -// keeps in scope for duration of the application -//SocketManager *winSockManager = NULL; + static + string + runtimeErrorMsg = ""; + // keeps in scope for duration of the application + //SocketManager *winSockManager = NULL; #endif #ifdef HAVE_GOOGLE_BREAKPAD - auto_ptr < - google_breakpad::ExceptionHandler > - errorHandlerPtr; + auto_ptr < + google_breakpad::ExceptionHandler > + errorHandlerPtr; #endif - class - NavtiveLanguageNameListCacheGenerator: - public - SimpleTaskCallbackInterface - { - virtual void - simpleTask (BaseThread * callingThread, void *userdata) - { - Lang & lang = Lang::getInstance (); - lang. - getDiscoveredLanguageList (true); - } - }; + class + NavtiveLanguageNameListCacheGenerator : + public + SimpleTaskCallbackInterface { + virtual void + simpleTask(BaseThread * callingThread, void *userdata) { + Lang & lang = Lang::getInstance(); + lang. + getDiscoveredLanguageList(true); + } + }; -// ===================================================== -// class ExceptionHandler -// ===================================================== - class - ExceptionHandler: - public - PlatformExceptionHandler - { - public: + // ===================================================== + // class ExceptionHandler + // ===================================================== + class + ExceptionHandler : + public + PlatformExceptionHandler { + public: #if defined(__WIN32__) && !defined(__GNUC__) - virtual void - handle (LPEXCEPTION_POINTERS pointers); + virtual void + handle(LPEXCEPTION_POINTERS pointers); #endif - virtual void - handle (); + virtual void + handle(); - static void - logError (const char *msg, bool confirmToConsole); - static void - handleRuntimeError (const megaglest_runtime_error & ex); - static void - handleRuntimeError (const char *msg, bool getStackTraceString); - static int - DisplayMessage (const char *msg, bool exitApp); - }; + static void + logError(const char *msg, bool confirmToConsole); + static void + handleRuntimeError(const megaglest_runtime_error & ex); + static void + handleRuntimeError(const char *msg, bool getStackTraceString); + static int + DisplayMessage(const char *msg, bool exitApp); + }; - void - cleanupCRCThread () - { - if (preCacheThread != NULL) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + void + cleanupCRCThread() { + if (preCacheThread != NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - const double - MAX_THREAD_WAIT = 60; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("START - shutting down crc threads\n"); - time_t - elapsed = time (NULL); - preCacheThread-> - signalQuit (); - for (; preCacheThread->canShutdown (false) == false && - difftime ((long int) time (NULL), elapsed) <= MAX_THREAD_WAIT;) - { - } - if (difftime ((long int) time (NULL), elapsed) <= MAX_THREAD_WAIT) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("B - shutting down crc threads\n"); + const double + MAX_THREAD_WAIT = 60; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("START - shutting down crc threads\n"); + time_t + elapsed = time(NULL); + preCacheThread-> + signalQuit(); + for (; preCacheThread->canShutdown(false) == false && + difftime((long int) time(NULL), elapsed) <= MAX_THREAD_WAIT;) { + } + if (difftime((long int) time(NULL), elapsed) <= MAX_THREAD_WAIT) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("B - shutting down crc threads\n"); - for (; preCacheThread->shutdownAndWait () == false && - difftime ((long int) time (NULL), elapsed) <= MAX_THREAD_WAIT;) - { - } - if (preCacheThread->getRunningStatus () == false) - { - delete - preCacheThread; - preCacheThread = NULL; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("C - shutting down crc threads\n"); - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, - __LINE__); - } - else - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("D - shutting down crc threads\n"); + for (; preCacheThread->shutdownAndWait() == false && + difftime((long int) time(NULL), elapsed) <= MAX_THREAD_WAIT;) { + } + if (preCacheThread->getRunningStatus() == false) { + delete + preCacheThread; + preCacheThread = NULL; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("C - shutting down crc threads\n"); + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, + __LINE__); + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("D - shutting down crc threads\n"); - if (preCacheThread->canShutdown (false) == true) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - delete - preCacheThread; - preCacheThread = NULL; + if (preCacheThread->canShutdown(false) == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + delete + preCacheThread; + preCacheThread = NULL; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("E - shutting down crc threads\n"); - } - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("F - shutting down crc threads\n"); - preCacheThread = NULL; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("E - shutting down crc threads\n"); + } + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("F - shutting down crc threads\n"); + preCacheThread = NULL; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } - static void - cleanupProcessObjects () - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + static void + cleanupProcessObjects() { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - showCursor (true); - restoreVideoMode (::Shared::Platform::Window::getSDLWindow (), true); - } + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + showCursor(true); + restoreVideoMode(::Shared::Platform::Window::getSDLWindow(), true); + } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#1 IRCCLient Cache SHUTDOWN\n"); - IRCThread *& - ircClient = - CacheManager::getCachedItem < - IRCThread * >(GameConstants::ircClientCacheLookupKey); - if (ircClient != NULL) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#2 IRCCLient Cache SHUTDOWN\n"); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#1 IRCCLient Cache SHUTDOWN\n"); + IRCThread *& + ircClient = + CacheManager::getCachedItem < + IRCThread * >(GameConstants::ircClientCacheLookupKey); + if (ircClient != NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#2 IRCCLient Cache SHUTDOWN\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - ircClient->disconnect (); - ircClient->signalQuit (); - ircClient = NULL; - sleep (0); - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#4 IRCCLient Cache SHUTDOWN\n"); + ircClient->disconnect(); + ircClient->signalQuit(); + ircClient = NULL; + sleep(0); + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#4 IRCCLient Cache SHUTDOWN\n"); - cleanupCRCThread (); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + cleanupCRCThread(); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (Renderer::isEnded () == false) - { - Renderer::getInstance ().end (); - CoreData & coreData = CoreData::getInstance (); - coreData.cleanup (); - } + if (Renderer::isEnded() == false) { + Renderer::getInstance().end(); + CoreData & coreData = CoreData::getInstance(); + coreData.cleanup(); + } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - SystemFlags::Close (); - SystemFlags::SHUTDOWN_PROGRAM_MODE = true; + SystemFlags::Close(); + SystemFlags::SHUTDOWN_PROGRAM_MODE = true; -//printf("Closing IRC CLient %d\n",__LINE__); + //printf("Closing IRC CLient %d\n",__LINE__); - Thread::shutdownThreads (); + Thread::shutdownThreads(); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("start running threads = " MG_SIZE_T_SPECIFIER "\n", - Thread::getThreadList ().size ()); - time_t - elapsed = time (NULL); - int - lastLazyThreadDump = 0; - for (; Thread::getThreadList ().size () > 0 && - difftime ((long int) time (NULL), elapsed) <= 10;) - { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("start running threads = " MG_SIZE_T_SPECIFIER "\n", + Thread::getThreadList().size()); + time_t + elapsed = time(NULL); + int + lastLazyThreadDump = 0; + for (; Thread::getThreadList().size() > 0 && + difftime((long int) time(NULL), elapsed) <= 10;) { - if (difftime ((long int) time (NULL), elapsed) > 1) - { - if (lastLazyThreadDump != - (int) difftime ((long int) time (NULL), elapsed)) - { - lastLazyThreadDump = difftime ((long int) time (NULL), elapsed); + if (difftime((long int) time(NULL), elapsed) > 1) { + if (lastLazyThreadDump != + (int) difftime((long int) time(NULL), elapsed)) { + lastLazyThreadDump = difftime((long int) time(NULL), elapsed); - printf ("Waiting for the following threads to exit [" - MG_SIZE_T_SPECIFIER "]:\n", - Thread::getThreadList ().size ()); + printf("Waiting for the following threads to exit [" + MG_SIZE_T_SPECIFIER "]:\n", + Thread::getThreadList().size()); - for (int i = 0; i < (int) Thread::getThreadList ().size (); ++i) - { - BaseThread * - baseThread = - dynamic_cast < BaseThread * >(Thread::getThreadList ()[i]); - printf - ("Thread index: %d ptr [%p] isBaseThread: %d, Name: [%s]\n", - i, baseThread, (baseThread != NULL ? 1 : 0), - (baseThread != - NULL ? baseThread->getUniqueID ().c_str () : "")); - } - } - } - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("end running threads = " MG_SIZE_T_SPECIFIER "\n", - Thread::getThreadList ().size ()); + for (int i = 0; i < (int) Thread::getThreadList().size(); ++i) { + BaseThread * + baseThread = + dynamic_cast (Thread::getThreadList()[i]); + printf + ("Thread index: %d ptr [%p] isBaseThread: %d, Name: [%s]\n", + i, baseThread, (baseThread != NULL ? 1 : 0), + (baseThread != + NULL ? baseThread->getUniqueID().c_str() : "")); + } + } + } + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("end running threads = " MG_SIZE_T_SPECIFIER "\n", + Thread::getThreadList().size()); - Thread::shutdownThreads (); + Thread::shutdownThreads(); - std::map < int, - Texture2D * >& - crcPlayerTextureCache = CacheManager::getCachedItem < std::map < int, - Texture2D * > >(GameConstants::playerTextureCacheLookupKey); - crcPlayerTextureCache.clear (); + std::map < int, + Texture2D * >& + crcPlayerTextureCache = CacheManager::getCachedItem < std::map < int, + Texture2D * > >(GameConstants::playerTextureCacheLookupKey); + crcPlayerTextureCache.clear(); - std::map < string, Texture2D * >&crcFactionPreviewTextureCache = - CacheManager::getCachedItem < std::map < string, - Texture2D * > >(GameConstants::factionPreviewTextureCacheLookupKey); - crcFactionPreviewTextureCache.clear (); + std::map < string, Texture2D * >&crcFactionPreviewTextureCache = + CacheManager::getCachedItem < std::map < string, + Texture2D * > >(GameConstants::factionPreviewTextureCacheLookupKey); + crcFactionPreviewTextureCache.clear(); - std::map < string, vector < FileReader < Pixmap2D > const *>*>& - list2d = FileReader < Pixmap2D >::getFileReadersMap (); - deleteMapValues (list2d.begin (), list2d.end ()); - std::map < string, vector < FileReader < Pixmap3D > const *>*>& - list3d = FileReader < Pixmap3D >::getFileReadersMap (); - deleteMapValues (list3d.begin (), list3d.end ()); + std::map < string, vector < FileReader < Pixmap2D > const *>*>& + list2d = FileReader < Pixmap2D >::getFileReadersMap(); + deleteMapValues(list2d.begin(), list2d.end()); + std::map < string, vector < FileReader < Pixmap3D > const *>*>& + list3d = FileReader < Pixmap3D >::getFileReadersMap(); + deleteMapValues(list3d.begin(), list3d.end()); #if defined(WANT_XERCES) - XmlIo::getInstance ().cleanup (); + XmlIo::getInstance().cleanup(); #endif - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - SystemFlags::globalCleanupHTTP (); - CacheManager::cleanupMutexes (); - } + SystemFlags::globalCleanupHTTP(); + CacheManager::cleanupMutexes(); + } #if defined(WIN32) && !defined(_DEBUG) && !defined(__GNUC__) - void - fatal (const char *s, ...) // failure exit - { - static int - errors = 0; - errors++; + void + fatal(const char *s, ...) // failure exit + { + static int + errors = 0; + errors++; - if (errors <= 5) - { // print up to two extra recursive errors - defvformatstring (msg, s, s); - string - errText = string (msg) + " [" + runtimeErrorMsg + "]"; -//puts(msg); - string - sErr = string (mg_app_name) + " fatal error"; - SystemFlags::OutputDebug (SystemFlags::debugError, "%s\n", - errText.c_str ()); - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", - errText.c_str ()); + if (errors <= 5) { // print up to two extra recursive errors + defvformatstring(msg, s, s); + string + errText = string(msg) + " [" + runtimeErrorMsg + "]"; + //puts(msg); + string + sErr = string(mg_app_name) + " fatal error"; + SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", + errText.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", + errText.c_str()); - if (errors <= 1) - { // avoid recursion - if (SDL_WasInit (SDL_INIT_VIDEO)) - { - SDL_SetRelativeMouseMode (SDL_FALSE); - } + if (errors <= 1) { // avoid recursion + if (SDL_WasInit(SDL_INIT_VIDEO)) { + SDL_SetRelativeMouseMode(SDL_FALSE); + } # ifdef WIN32 - LPWSTR - wstr = Ansi2WideString (errText.c_str ()); - LPWSTR - wstr1 = Ansi2WideString (sErr.c_str ()); + LPWSTR + wstr = Ansi2WideString(errText.c_str()); + LPWSTR + wstr1 = Ansi2WideString(sErr.c_str()); - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - MessageBox (NULL, wstr, wstr1, MB_OK | MB_SYSTEMMODAL); - } + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + MessageBox(NULL, wstr, wstr1, MB_OK | MB_SYSTEMMODAL); + } - if (wstr) - delete[]wstr; - if (wstr1) - delete[]wstr1; + if (wstr) + delete[]wstr; + if (wstr1) + delete[]wstr1; # endif - } - } + } + } -// Now try to shutdown threads if possible - delete - mainProgram; - mainProgram = NULL; -// END + // Now try to shutdown threads if possible + delete + mainProgram; + mainProgram = NULL; + // END - if (sdl_quitCalled == false) - { - sdl_quitCalled = true; - SDL_Quit (); - } - exit (EXIT_FAILURE); - } + if (sdl_quitCalled == false) { + sdl_quitCalled = true; + SDL_Quit(); + } + exit(EXIT_FAILURE); + } - std::string get_module_path (HMODULE module = 0) - { - char - path_name[MAX_PATH] = { }; - DWORD - size = GetModuleFileNameA (module, path_name, MAX_PATH); - return std::string (path_name, size); - } - void - write_module_name (string & out, HANDLE process, DWORD64 program_counter) - { - DWORD64 - module_base = SymGetModuleBase64 (process, program_counter); - if (module_base) - { - std::string module_name = - get_module_path (reinterpret_cast < HMODULE > (module_base)); - if (!module_name.empty ()) - out += module_name + "|"; - else - out += "Unknown module|"; - } - else - { - out += "Unknown module|"; - } - } + std::string get_module_path(HMODULE module = 0) { + char + path_name[MAX_PATH] = {}; + DWORD + size = GetModuleFileNameA(module, path_name, MAX_PATH); + return std::string(path_name, size); + } + void + write_module_name(string & out, HANDLE process, DWORD64 program_counter) { + DWORD64 + module_base = SymGetModuleBase64(process, program_counter); + if (module_base) { + std::string module_name = + get_module_path(reinterpret_cast (module_base)); + if (!module_name.empty()) + out += module_name + "|"; + else + out += "Unknown module|"; + } else { + out += "Unknown module|"; + } + } - void - write_function_name (string & out, HANDLE process, - DWORD64 program_counter) - { - SYMBOL_INFO_PACKAGE - sym = { - sizeof (sym) - }; - sym.si.MaxNameLen = MAX_SYM_NAME; - if (SymFromAddr (process, program_counter, 0, &sym.si)) - { - out += string (sym.si.Name) + "()"; - } - else - { - out += "Unknown function"; - } - } + void + write_function_name(string & out, HANDLE process, + DWORD64 program_counter) { + SYMBOL_INFO_PACKAGE + sym = { + sizeof(sym) + }; + sym.si.MaxNameLen = MAX_SYM_NAME; + if (SymFromAddr(process, program_counter, 0, &sym.si)) { + out += string(sym.si.Name) + "()"; + } else { + out += "Unknown function"; + } + } - void - write_file_and_line (string & out, HANDLE process, - DWORD64 program_counter) - { - IMAGEHLP_LINE64 - ih_line = { - sizeof (IMAGEHLP_LINE64) - }; - DWORD - dummy = 0; - if (SymGetLineFromAddr64 (process, program_counter, &dummy, &ih_line)) - { - out += - string ("|") + string (ih_line.FileName) + ":" + - intToStr (ih_line.LineNumber); - } - } - void - generate_stack_trace (string & out, CONTEXT ctx, int skip) - { - STACKFRAME64 - sf = { - }; + void + write_file_and_line(string & out, HANDLE process, + DWORD64 program_counter) { + IMAGEHLP_LINE64 + ih_line = { + sizeof(IMAGEHLP_LINE64) + }; + DWORD + dummy = 0; + if (SymGetLineFromAddr64(process, program_counter, &dummy, &ih_line)) { + out += + string("|") + string(ih_line.FileName) + ":" + + intToStr(ih_line.LineNumber); + } + } + void + generate_stack_trace(string & out, CONTEXT ctx, int skip) { + STACKFRAME64 + sf = { + }; # if !defined(_WIN64) - sf.AddrPC.Offset = ctx.Eip; + sf.AddrPC.Offset = ctx.Eip; # else - sf.AddrPC.Offset = ctx.Rip; + sf.AddrPC.Offset = ctx.Rip; # endif - sf.AddrPC.Mode = AddrModeFlat; + sf.AddrPC.Mode = AddrModeFlat; # if !defined(_WIN64) - sf.AddrStack.Offset = ctx.Esp; + sf.AddrStack.Offset = ctx.Esp; # else - sf.AddrStack.Offset = ctx.Rsp; + sf.AddrStack.Offset = ctx.Rsp; # endif - sf.AddrStack.Mode = AddrModeFlat; + sf.AddrStack.Mode = AddrModeFlat; # if !defined(_WIN64) - sf.AddrFrame.Offset = ctx.Ebp; + sf.AddrFrame.Offset = ctx.Ebp; # else - sf.AddrFrame.Offset = ctx.Rbp; + sf.AddrFrame.Offset = ctx.Rbp; # endif - sf.AddrFrame.Mode = AddrModeFlat; + sf.AddrFrame.Mode = AddrModeFlat; - HANDLE - process = GetCurrentProcess (); - HANDLE - thread = GetCurrentThread (); + HANDLE + process = GetCurrentProcess(); + HANDLE + thread = GetCurrentThread(); - bool - tryThreadContext = true; - CONTEXT - threadContext; - memset (&threadContext, 0, sizeof (CONTEXT)); - threadContext.ContextFlags = CONTEXT_FULL; + bool + tryThreadContext = true; + CONTEXT + threadContext; + memset(&threadContext, 0, sizeof(CONTEXT)); + threadContext.ContextFlags = CONTEXT_FULL; - for (;;) - { - SetLastError (0); + for (;;) { + SetLastError(0); # if !defined(_WIN64) - BOOL - stack_walk_ok = StackWalk64 (IMAGE_FILE_MACHINE_I386, + BOOL + stack_walk_ok = StackWalk64(IMAGE_FILE_MACHINE_I386, # else - BOOL - stack_walk_ok = StackWalk64 (IMAGE_FILE_MACHINE_AMD64, + BOOL + stack_walk_ok = StackWalk64(IMAGE_FILE_MACHINE_AMD64, # endif - process, thread, &sf, - (tryThreadContext == - false ? &threadContext : &ctx), - 0, &SymFunctionTableAccess64, - &SymGetModuleBase64, 0); - if (!stack_walk_ok || !sf.AddrFrame.Offset) - { - if (tryThreadContext == true) - { - tryThreadContext = false; - if (GetThreadContext (thread, &threadContext) != 0) - { + process, thread, &sf, + (tryThreadContext == + false ? &threadContext : &ctx), + 0, &SymFunctionTableAccess64, + &SymGetModuleBase64, 0); + if (!stack_walk_ok || !sf.AddrFrame.Offset) { + if (tryThreadContext == true) { + tryThreadContext = false; + if (GetThreadContext(thread, &threadContext) != 0) { # if !defined(_WIN64) - sf.AddrPC.Offset = threadContext.Eip; + sf.AddrPC.Offset = threadContext.Eip; # else - sf.AddrPC.Offset = threadContext.Rip; + sf.AddrPC.Offset = threadContext.Rip; # endif - sf.AddrPC.Mode = AddrModeFlat; + sf.AddrPC.Mode = AddrModeFlat; # if !defined(_WIN64) - sf.AddrStack.Offset = threadContext.Esp; + sf.AddrStack.Offset = threadContext.Esp; # else - sf.AddrStack.Offset = threadContext.Rsp; + sf.AddrStack.Offset = threadContext.Rsp; # endif - sf.AddrStack.Mode = AddrModeFlat; + sf.AddrStack.Mode = AddrModeFlat; # if !defined(_WIN64) - sf.AddrFrame.Offset = threadContext.Ebp; + sf.AddrFrame.Offset = threadContext.Ebp; # else - sf.AddrFrame.Offset = threadContext.Rbp; + sf.AddrFrame.Offset = threadContext.Rbp; # endif - sf.AddrFrame.Mode = AddrModeFlat; - } - else - { - return; - } - } - else - { - return; - } - } + sf.AddrFrame.Mode = AddrModeFlat; + } else { + return; + } + } else { + return; + } + } - if (skip) - { - --skip; - } - else - { -// write the address - out += intToStr (sf.AddrPC.Offset) + "|"; + if (skip) { + --skip; + } else { + // write the address + out += intToStr(sf.AddrPC.Offset) + "|"; - write_module_name (out, process, sf.AddrPC.Offset); - write_function_name (out, process, sf.AddrPC.Offset); - write_file_and_line (out, process, sf.AddrPC.Offset); + write_module_name(out, process, sf.AddrPC.Offset); + write_function_name(out, process, sf.AddrPC.Offset); + write_file_and_line(out, process, sf.AddrPC.Offset); - out += "\n"; - } - } - } + out += "\n"; + } + } + } - struct UntypedException - { - explicit - UntypedException (const EXCEPTION_RECORD & er): - exception_object (reinterpret_cast < - void *>(er.ExceptionInformation[1])), - type_array (reinterpret_cast < - _ThrowInfo * - >(er.ExceptionInformation[2])->pCatchableTypeArray) - { - } - void * - exception_object; - _CatchableTypeArray * - type_array; - }; + struct UntypedException { + explicit + UntypedException(const EXCEPTION_RECORD & er) : + exception_object(reinterpret_cast < + void *>(er.ExceptionInformation[1])), + type_array(reinterpret_cast < + _ThrowInfo * + >(er.ExceptionInformation[2])->pCatchableTypeArray) { + } + void * + exception_object; + _CatchableTypeArray * + type_array; + }; - void * - exception_cast_worker (const UntypedException & e, const type_info & ti) - { - for (int i = 0; i < e.type_array->nCatchableTypes; ++i) - { - _CatchableType & type_i = *e.type_array->arrayOfCatchableTypes[i]; - const - std::type_info & - ti_i = *reinterpret_cast < std::type_info * >(type_i.pType); - if (ti_i == ti) - { - char * - base_address = reinterpret_cast < char *>(e.exception_object); - base_address += type_i.thisDisplacement.mdisp; - return base_address; - } - } - return 0; - } + void * + exception_cast_worker(const UntypedException & e, const type_info & ti) { + for (int i = 0; i < e.type_array->nCatchableTypes; ++i) { + _CatchableType & type_i = *e.type_array->arrayOfCatchableTypes[i]; + const + std::type_info & + ti_i = *reinterpret_cast (type_i.pType); + if (ti_i == ti) { + char * + base_address = reinterpret_cast (e.exception_object); + base_address += type_i.thisDisplacement.mdisp; + return base_address; + } + } + return 0; + } - template < typename T > T * exception_cast (const UntypedException & e) - { - const - std::type_info & - ti = typeid (T); - return reinterpret_cast < T * >(exception_cast_worker (e, ti)); - } - void - stackdumper (unsigned int type, EXCEPTION_POINTERS * ep, bool fatalExit) - { + template < typename T > T * exception_cast(const UntypedException & e) { + const + std::type_info & + ti = typeid (T); + return reinterpret_cast (exception_cast_worker(e, ti)); + } + void + stackdumper(unsigned int type, EXCEPTION_POINTERS * ep, bool fatalExit) { # ifdef HAVE_GOOGLE_BREAKPAD - if (errorHandlerPtr.get () != NULL) - { - errorHandlerPtr->WriteMinidump (); - } + if (errorHandlerPtr.get() != NULL) { + errorHandlerPtr->WriteMinidump(); + } # endif - if (!ep) - { - fatal ("unknown type"); - return; - } - EXCEPTION_RECORD * - er = ep->ExceptionRecord; - CONTEXT * - context = ep->ContextRecord; - string - out = ""; - int - skip = 0; + if (!ep) { + fatal("unknown type"); + return; + } + EXCEPTION_RECORD * + er = ep->ExceptionRecord; + CONTEXT * + context = ep->ContextRecord; + string + out = ""; + int + skip = 0; - switch (er->ExceptionCode) - { - case 0xE06D7363: - { // C++ exception - UntypedException - ue (*er); - if (std::exception * e = exception_cast < std::exception > (ue)) - { - const - std::type_info & - ti = typeid (*e); - out += string (ti.name ()) + ":" + string (e->what ()); - } - else - { - out += "Unknown C++ exception thrown."; - } - skip = 2; // skip RaiseException and _CxxThrowException - } - break; - case EXCEPTION_ACCESS_VIOLATION: - { - out += string ("Access violation. Illegal ") - + (er->ExceptionInformation[0] ? "write" : "read") - + string (" by ") - + intToStr ((int) er->ExceptionAddress) - + string (" at ") + intToStr (er->ExceptionInformation[1]); - } break; - default: - { - out += "SEH exception thrown. Exception code: " - + er->ExceptionCode - + string (" at ") + intToStr ((int) er->ExceptionAddress); - } - } + switch (er->ExceptionCode) { + case 0xE06D7363: + { // C++ exception + UntypedException + ue(*er); + if (std::exception * e = exception_cast (ue)) { + const + std::type_info & + ti = typeid (*e); + out += string(ti.name()) + ":" + string(e->what()); + } else { + out += "Unknown C++ exception thrown."; + } + skip = 2; // skip RaiseException and _CxxThrowException + } + break; + case EXCEPTION_ACCESS_VIOLATION: + { + out += string("Access violation. Illegal ") + + (er->ExceptionInformation[0] ? "write" : "read") + + string(" by ") + + intToStr((int) er->ExceptionAddress) + + string(" at ") + intToStr(er->ExceptionInformation[1]); + } break; + default: + { + out += "SEH exception thrown. Exception code: " + + er->ExceptionCode + + string(" at ") + intToStr((int) er->ExceptionAddress); + } + } - generate_stack_trace (out, *context, skip); + generate_stack_trace(out, *context, skip); - if (fatalExit == true) - { - fatal (out.c_str ()); - } - else - { - ExceptionHandler::logError (out.c_str (), true); - } - } + if (fatalExit == true) { + fatal(out.c_str()); + } else { + ExceptionHandler::logError(out.c_str(), true); + } + } #endif -// ===================================================== -// class ExceptionHandler -// ===================================================== + // ===================================================== + // class ExceptionHandler + // ===================================================== #if defined(WIN32) && !defined(__GNUC__) - void - ExceptionHandler::handle (LPEXCEPTION_POINTERS pointers) - { - string - msg = - "#1 An error occurred and " + string (mg_app_name) + - " will close.\nPlease report this bug to: " + string (mailString); - msg += - ", attaching the generated " + getCrashDumpFileName () + " file."; + void + ExceptionHandler::handle(LPEXCEPTION_POINTERS pointers) { + string + msg = + "#1 An error occurred and " + string(mg_app_name) + + " will close.\nPlease report this bug to: " + string(mailString); + msg += + ", attaching the generated " + getCrashDumpFileName() + " file."; - SystemFlags::OutputDebug (SystemFlags::debugError, "%s\n", - msg.c_str ()); - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", - msg.c_str ()); + SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", + msg.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", + msg.c_str()); - stackdumper (0, pointers, false); + stackdumper(0, pointers, false); - if (mainProgram && gameInitialized == true) - { - mainProgram->showMessage (msg.c_str ()); - } + if (mainProgram && gameInitialized == true) { + mainProgram->showMessage(msg.c_str()); + } - message (msg.c_str (), - GlobalStaticFlags::getIsNonGraphicalModeEnabled (), - tempDataLocation); - } + message(msg.c_str(), + GlobalStaticFlags::getIsNonGraphicalModeEnabled(), + tempDataLocation); + } #endif - void - ExceptionHandler::handle () - { - string - msg = - "#1 An error occurred and " + string (mg_app_name) + - " will close.\nPlease report this bug to: " + string (mailString); + void + ExceptionHandler::handle() { + string + msg = + "#1 An error occurred and " + string(mg_app_name) + + " will close.\nPlease report this bug to: " + string(mailString); #ifdef WIN32 - msg += - ", attaching the generated " + getCrashDumpFileName () + " file."; + msg += + ", attaching the generated " + getCrashDumpFileName() + " file."; #endif - SystemFlags::OutputDebug (SystemFlags::debugError, "%s\n", - msg.c_str ()); - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", - msg.c_str ()); + SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", + msg.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", + msg.c_str()); - if (mainProgram && gameInitialized == true) - { - mainProgram->showMessage (msg.c_str ()); - } + if (mainProgram && gameInitialized == true) { + mainProgram->showMessage(msg.c_str()); + } - message (msg.c_str (), - GlobalStaticFlags::getIsNonGraphicalModeEnabled (), - tempDataLocation); - } + message(msg.c_str(), + GlobalStaticFlags::getIsNonGraphicalModeEnabled(), + tempDataLocation); + } - void - ExceptionHandler::logError (const char *msg, bool confirmToConsole) - { - string - errorLogFile = "error.log"; - if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) != - "") - { - errorLogFile = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - errorLogFile; - } - else - { - string - userData = Config::getInstance ().getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - errorLogFile = userData + errorLogFile; - } + void + ExceptionHandler::logError(const char *msg, bool confirmToConsole) { + string + errorLogFile = "error.log"; + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != + "") { + errorLogFile = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + errorLogFile; + } else { + string + userData = Config::getInstance().getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + errorLogFile = userData + errorLogFile; + } #if defined(WIN32) && !defined(__MINGW32__) - FILE * - fp = _wfopen (utf8_decode (errorLogFile).c_str (), L"w"); - std::ofstream logFile (fp); + FILE * + fp = _wfopen(utf8_decode(errorLogFile).c_str(), L"w"); + std::ofstream logFile(fp); #else - std::ofstream logFile; - logFile.open (errorLogFile.c_str (), ios_base::out | ios_base::trunc); + std::ofstream logFile; + logFile.open(errorLogFile.c_str(), ios_base::out | ios_base::trunc); #endif - if (logFile.is_open () == true) - { -//time_t curtime = time (NULL); -//struct tm *loctime = localtime (&curtime); - struct tm - loctime = threadsafe_localtime (systemtime_now ()); - char - szBuf2[100] = ""; - strftime (szBuf2, 100, "%Y-%m-%d %H:%M:%S", &loctime); + if (logFile.is_open() == true) { + //time_t curtime = time (NULL); + //struct tm *loctime = localtime (&curtime); + struct tm + loctime = threadsafe_localtime(systemtime_now()); + char + szBuf2[100] = ""; + strftime(szBuf2, 100, "%Y-%m-%d %H:%M:%S", &loctime); - logFile << "[" << szBuf2 << "] Runtime Error information:" << - std::endl; - logFile << "======================================================" << - std::endl; - logFile << (msg != NULL ? msg : "null") << std::endl; - logFile.close (); + logFile << "[" << szBuf2 << "] Runtime Error information:" << + std::endl; + logFile << "======================================================" << + std::endl; + logFile << (msg != NULL ? msg : "null") << std::endl; + logFile.close(); #if defined(WIN32) && !defined(__MINGW32__) - if (fp) - { - fclose (fp); - } + if (fp) { + fclose(fp); + } #endif - if (confirmToConsole == true) - { - printf ("Error saved to logfile [%s]\n", errorLogFile.c_str ()); - fflush (stdout); - } - } - else - { - if (confirmToConsole == true) - { - printf ("COULD NOT SAVE TO ERROR logfile [%s]\n", - errorLogFile.c_str ()); - fflush (stdout); - } - } - } + if (confirmToConsole == true) { + printf("Error saved to logfile [%s]\n", errorLogFile.c_str()); + fflush(stdout); + } + } else { + if (confirmToConsole == true) { + printf("COULD NOT SAVE TO ERROR logfile [%s]\n", + errorLogFile.c_str()); + fflush(stdout); + } + } + } - void - ExceptionHandler::handleRuntimeError (const megaglest_runtime_error & ex) - { - const char * - msg = ex.what (); - handleRuntimeError (msg, false); - } + void + ExceptionHandler::handleRuntimeError(const megaglest_runtime_error & ex) { + const char * + msg = ex.what(); + handleRuntimeError(msg, false); + } - void - ExceptionHandler::handleRuntimeError (const char *msg, - bool getStackTraceString) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + void + ExceptionHandler::handleRuntimeError(const char *msg, + bool getStackTraceString) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - static - bool - inErrorNow = false; - if (inErrorNow == true) - { - printf ("\n=====================================\n"); - printf ("\n** Already in error handler aborting, msg [%s]\n", msg); - fflush (stdout); - abort (); -//return; - } - inErrorNow = true; + static + bool + inErrorNow = false; + if (inErrorNow == true) { + printf("\n=====================================\n"); + printf("\n** Already in error handler aborting, msg [%s]\n", msg); + fflush(stdout); + abort(); + //return; + } + inErrorNow = true; - logError (msg, true); + logError(msg, true); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line: %d] program = %p gameInitialized = %d msg [%s]\n", - __FILE__, __FUNCTION__, __LINE__, mainProgram, gameInitialized, - msg); - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] [%s] gameInitialized = %d, program = %p\n", - __FILE__, __FUNCTION__, __LINE__, msg, - gameInitialized, mainProgram); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] [%s] gameInitialized = %d, program = %p\n", - __FILE__, __FUNCTION__, __LINE__, msg, - gameInitialized, mainProgram); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line: %d] program = %p gameInitialized = %d msg [%s]\n", + __FILE__, __FUNCTION__, __LINE__, mainProgram, gameInitialized, + msg); + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] [%s] gameInitialized = %d, program = %p\n", + __FILE__, __FUNCTION__, __LINE__, msg, + gameInitialized, mainProgram); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] [%s] gameInitialized = %d, program = %p\n", + __FILE__, __FUNCTION__, __LINE__, msg, + gameInitialized, mainProgram); - string - errMsg = (msg != NULL ? msg : "null"); + string + errMsg = (msg != NULL ? msg : "null"); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - bool - gotStackTrace = false; - if (getStackTraceString == true && disableBacktrace == false - && sdl_quitCalled == false) - { - string - stackTrace = getStackTrace (); - errMsg += stackTrace; - gotStackTrace = true; - } + bool + gotStackTrace = false; + if (getStackTraceString == true && disableBacktrace == false + && sdl_quitCalled == false) { + string + stackTrace = getStackTrace(); + errMsg += stackTrace; + gotStackTrace = true; + } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - logError (errMsg.c_str (), false); + logError(errMsg.c_str(), false); - if (gotStackTrace == true) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] [%s]\n", __FILE__, - __FUNCTION__, __LINE__, errMsg.c_str ()); - } - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] [%s]\n", __FILE__, - __FUNCTION__, __LINE__, errMsg.c_str ()); + if (gotStackTrace == true) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] [%s]\n", __FILE__, + __FUNCTION__, __LINE__, errMsg.c_str()); + } + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] [%s]\n", __FILE__, + __FUNCTION__, __LINE__, errMsg.c_str()); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); -//abort(); + //abort(); - if (mainProgram && gameInitialized == true) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (mainProgram && gameInitialized == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (mainProgram->getState () != NULL) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, - __LINE__); - mainProgram->showMessage (errMsg.c_str ()); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, - __LINE__); + if (mainProgram->getState() != NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, + __LINE__); + mainProgram->showMessage(errMsg.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, + __LINE__); - if (glActiveTexture != NULL) - { - for (; - GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false - && mainProgram->isMessageShowing ();) - { - ::Shared::Platform::Window::handleEvent (); - try - { - mainProgram->loop (); - } - catch (const exception & e) - { - printf ("\n=====================================\n"); - printf - ("\n** Already in error handler exiting error rendering, msg [%s]\n", - e.what ()); - fflush (stdout); - break; - } - } - } - } - else - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, - __LINE__); - mainProgram->showMessage (errMsg.c_str ()); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, - __LINE__); + if (glActiveTexture != NULL) { + for (; + GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false + && mainProgram->isMessageShowing();) { + ::Shared::Platform::Window::handleEvent(); + try { + mainProgram->loop(); + } catch (const exception & e) { + printf("\n=====================================\n"); + printf + ("\n** Already in error handler exiting error rendering, msg [%s]\n", + e.what()); + fflush(stdout); + break; + } + } + } + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, + __LINE__); + mainProgram->showMessage(errMsg.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, + __LINE__); - if (glActiveTexture != NULL) - { - for (; - GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false - && mainProgram->isMessageShowing ();) - { - ::Shared::Platform::Window::handleEvent (); - try - { - mainProgram->loop (); - } - catch (const exception & e) - { - printf ("\n=====================================\n"); - printf - ("\n** Already in error handler exiting error rendering, msg [%s]\n", - e.what ()); - fflush (stdout); - break; - } - } - } - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - } - else - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (glActiveTexture != NULL) { + for (; + GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false + && mainProgram->isMessageShowing();) { + ::Shared::Platform::Window::handleEvent(); + try { + mainProgram->loop(); + } catch (const exception & e) { + printf("\n=====================================\n"); + printf + ("\n** Already in error handler exiting error rendering, msg [%s]\n", + e.what()); + fflush(stdout); + break; + } + } + } + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - string - err = "#2 An error occurred and "; - if (sdl_quitCalled == false) - { - err += mg_app_name; - } - err += - " will close.\nError msg = [" + errMsg + - "]\n\nPlease report this bug to "; - if (sdl_quitCalled == false) - { - err += mailStringSupport; - } + string + err = "#2 An error occurred and "; + if (sdl_quitCalled == false) { + err += mg_app_name; + } + err += + " will close.\nError msg = [" + errMsg + + "]\n\nPlease report this bug to "; + if (sdl_quitCalled == false) { + err += mailStringSupport; + } #ifdef WIN32 - err += - string (", attaching the generated ") + getCrashDumpFileName () + - string (" file."); + err += + string(", attaching the generated ") + getCrashDumpFileName() + + string(" file."); #endif - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - message (err, GlobalStaticFlags::getIsNonGraphicalModeEnabled (), - tempDataLocation); - } + message(err, GlobalStaticFlags::getIsNonGraphicalModeEnabled(), + tempDataLocation); + } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); -// Now try to shutdown threads if possible - delete - mainProgram; - mainProgram = NULL; -// END + // Now try to shutdown threads if possible + delete + mainProgram; + mainProgram = NULL; + // END - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); #ifdef WIN32 - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - showCursor (true); - restoreVideoMode (::Shared::Platform::Window::getSDLWindow (), true); - } + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + showCursor(true); + restoreVideoMode(::Shared::Platform::Window::getSDLWindow(), true); + } - runtimeErrorMsg = errMsg; - inErrorNow = false; - throw - runtimeErrorMsg; + runtimeErrorMsg = errMsg; + inErrorNow = false; + throw + runtimeErrorMsg; #endif - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - - cleanupProcessObjects (); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - - if (sdl_quitCalled == false) - { - sdl_quitCalled = true; - SDL_Quit (); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - - inErrorNow = false; - - abort (); - } - - int - ExceptionHandler::DisplayMessage (const char *msg, bool exitApp) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__, - __FUNCTION__, __LINE__, msg, exitApp); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] msg [%s] exitApp = %d\n", - __FILE__, __FUNCTION__, __LINE__, msg, - exitApp); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__, - __FUNCTION__, __LINE__, msg, exitApp); - - if (mainProgram && gameInitialized == true) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__, - __FUNCTION__, __LINE__, msg, exitApp); - mainProgram->showMessage (msg); - } - else - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__, - __FUNCTION__, __LINE__, msg, exitApp); - message (msg, GlobalStaticFlags::getIsNonGraphicalModeEnabled (), - tempDataLocation); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__, - __FUNCTION__, __LINE__, msg, exitApp); - - if (exitApp == true) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", msg); - -// Now try to shutdown threads if possible - delete - mainProgram; - mainProgram = NULL; -// END - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__, - __FUNCTION__, __LINE__, msg, exitApp); - cleanupProcessObjects (); - - if (sdl_quitCalled == false) - { - sdl_quitCalled = true; - SDL_Quit (); - } - exit (-1); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__, - __FUNCTION__, __LINE__, msg, exitApp); - return 0; - } - -// ===================================================== -// class MainWindow -// ===================================================== - - MainWindow::MainWindow (Program * program):WindowGl (), popupMenu ("MainWindow", - "popupMenu") - { - this->program = program; -//this->popupMenu.registerGraphicComponentOnlyFontCallbacks("MainWindow", "popupMenu"); - this->popupMenu.setEnabled (false); - this->popupMenu.setVisible (false); - this->triggerLanguageToggle = false; - this->triggerLanguage = ""; - this->cancelLanguageSelection = -1; - } - - MainWindow::~MainWindow () - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - delete - program; - program = NULL; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - } - - int - MainWindow::getDesiredScreenWidth () - { - Config & config = Config::getInstance (); - return config.getInt ("ScreenWidth"); - } - int - MainWindow::getDesiredScreenHeight () - { - Config & config = Config::getInstance (); - return config.getInt ("ScreenHeight"); - } - - void - MainWindow::eventToggleFullScreen (bool isFullscreen) - { - WindowGl::eventToggleFullScreen (isFullscreen); - - if (isFullscreen) - { - Metrics::reload (this->program->getWindow ()->getScreenWidth (), - this->program->getWindow ()->getScreenHeight ()); - } - else - { - Config & config = Config::getInstance (); - Metrics::reload (config.getInt ("ScreenWidth"), - config.getInt ("ScreenHeight")); -//window->setText(config.getString("WindowTitle","ZetaGlest")); -//this->mainMenu->init(); - } - - } - - void - MainWindow::eventMouseDown (int x, int y, MouseButton mouseButton) - { - const - Metrics & - metrics = Metrics::getInstance (); - int - vx = metrics.toVirtualX (x); - int - vy = metrics.toVirtualY (getH () - y); - - if (program == NULL) - { - throw - megaglest_runtime_error - ("In [MainWindow::eventMouseDown] ERROR, program == NULL!"); - } - - if (popupMenu.getVisible () == true && popupMenu.mouseClick (vx, vy)) - { - std::pair < int, - string > - result = popupMenu.mouseClickedMenuItem (vx, vy); - - popupMenu.setEnabled (false); - popupMenu.setVisible (false); - -// Exit game - if (result.first != cancelLanguageSelection) - { - Lang & lang = Lang::getInstance (); - map < string, string > languageList = - lang.getDiscoveredLanguageList (true); - for (map < string, string >::iterator iterMap = - languageList.begin (); iterMap != languageList.end (); - ++iterMap) - { - string - matchLanguage = iterMap->first + "-" + iterMap->second; - if (matchLanguage == result.second) - { - this->triggerLanguageToggle = true; - this->triggerLanguage = iterMap->first; - break; - } - } - - } - - return; - } - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - switch (mouseButton) - { - case mbLeft: - program->mouseDownLeft (vx, vy); - break; - case mbRight: -//program->mouseDownRight(vx, vy); - break; - case mbCenter: -//program->mouseDownCenter(vx, vy); - break; - default: - break; - } - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - ProgramState * - programState = program->getState (); - if (programState != NULL) - { - switch (mouseButton) - { - case mbLeft: - programState->mouseDownLeft (vx, vy); - break; - case mbRight: - programState->mouseDownRight (vx, vy); - break; - case mbCenter: - programState->mouseDownCenter (vx, vy); - break; - default: - break; - } - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - void - MainWindow::eventMouseUp (int x, int y, MouseButton mouseButton) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - const - Metrics & - metrics = Metrics::getInstance (); - int - vx = metrics.toVirtualX (x); - int - vy = metrics.toVirtualY (getH () - y); - - if (program == NULL) - { - throw - megaglest_runtime_error - ("In [MainWindow::eventMouseUp] ERROR, program == NULL!"); - } - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - ProgramState * - programState = program->getState (); - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - if (programState != NULL) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - switch (mouseButton) - { - case mbLeft: - programState->mouseUpLeft (vx, vy); - break; - case mbRight: - programState->mouseUpRight (vx, vy); - break; - case mbCenter: - programState->mouseUpCenter (vx, vy); - break; - default: - break; - } - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - void - MainWindow::eventMouseDoubleClick (int x, int y, MouseButton mouseButton) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - const - Metrics & - metrics = Metrics::getInstance (); - int - vx = metrics.toVirtualX (x); - int - vy = metrics.toVirtualY (getH () - y); - - if (program == NULL) - { - throw - megaglest_runtime_error - ("In [MainWindow::eventMouseDoubleClick] ERROR, program == NULL!"); - } - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - ProgramState * - programState = program->getState (); - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - if (programState != NULL) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - switch (mouseButton) - { - case mbLeft: - programState->mouseDoubleClickLeft (vx, vy); - break; - case mbRight: - programState->mouseDoubleClickRight (vx, vy); - break; - case mbCenter: - programState->mouseDoubleClickCenter (vx, vy); - break; - default: - break; - } - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - void - MainWindow::eventMouseMove (int x, int y, const MouseState * ms) - { - - const - Metrics & - metrics = Metrics::getInstance (); - int - vx = metrics.toVirtualX (x); - int - vy = metrics.toVirtualY (getH () - y); - - if (program == NULL) - { - throw - megaglest_runtime_error - ("In [MainWindow::eventMouseMove] ERROR, program == NULL!"); - } - - program->eventMouseMove (vx, vy, ms); - - ProgramState * - programState = program->getState (); - if (programState != NULL) - { - programState->mouseMove (vx, vy, ms); - } - } - - void - MainWindow::eventMouseWheel (int x, int y, int zDelta) - { - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - const - Metrics & - metrics = Metrics::getInstance (); - int - vx = metrics.toVirtualX (x); - int - vy = metrics.toVirtualY (getH () - y); - - if (program == NULL) - { - throw - megaglest_runtime_error - ("In [MainWindow::eventMouseMove] ERROR, program == NULL!"); - } - - ProgramState * - programState = program->getState (); - - if (programState != NULL) - { - programState->eventMouseWheel (vx, vy, zDelta); - } - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - void - MainWindow::render () - { - if (popupMenu.getVisible () == true) - { - Renderer & renderer = Renderer::getInstance (); - renderer.renderPopupMenu (&popupMenu); - } - } - - void - MainWindow::showLanguages () - { - Lang & lang = Lang::getInstance (); - std::vector < string > menuItems; - map < string, string > languageList = - lang.getDiscoveredLanguageList (true); - for (map < string, string >::iterator iterMap = languageList.begin (); - iterMap != languageList.end (); ++iterMap) - { - menuItems.push_back (iterMap->first + "-" + iterMap->second); - } - - menuItems.push_back (lang.getString ("Exit")); - cancelLanguageSelection = (int) menuItems.size () - 1; - - popupMenu.setW (100); - popupMenu.setH (100); - popupMenu.init (lang.getString ("GameMenuTitle"), menuItems); - popupMenu.setEnabled (true); - popupMenu.setVisible (true); - } - - void - MainWindow::toggleLanguage (string language) - { - popupMenu.setEnabled (false); - popupMenu.setVisible (false); - this->triggerLanguageToggle = false; - this->triggerLanguage = ""; - - Lang & lang = Lang::getInstance (); - string - currentLanguage = lang.getLanguage (); - - string - newLanguageSelected = language; - if (language == "") - { - newLanguageSelected = currentLanguage; - - vector < string > langResults; - string - data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - - string - userDataPath = getGameCustomCoreDataPath (data_path, ""); - findAll (userDataPath + "data/lang/*.lng", langResults, true, false); - - vector < string > langResults2; - findAll (data_path + "data/lang/*.lng", langResults2, true); - if (langResults2.empty () && langResults.empty ()) - { - throw - megaglest_runtime_error ("There are no lang files"); - } - for (unsigned int i = 0; i < langResults2.size (); ++i) - { - string - testLanguage = langResults2[i]; - if (std::find (langResults.begin (), langResults.end (), - testLanguage) == langResults.end ()) - { - langResults.push_back (testLanguage); - } - } - - for (unsigned int i = 0; i < langResults.size (); ++i) - { - string - testLanguage = langResults[i]; - if (testLanguage == currentLanguage) - { - if (i + 1 < langResults.size ()) - { - newLanguageSelected = langResults[i + 1]; - } - else - { - newLanguageSelected = langResults[0]; - } - break; - } - } - } - if (newLanguageSelected != currentLanguage) - { - lang.loadGameStrings (newLanguageSelected); - program->reloadUI (); - program->consoleAddLine (lang.getString ("Language") + " " + - newLanguageSelected); - } - } - - bool - MainWindow::eventTextInput (std::string text) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] [%s]\n", __FILE__, - __FUNCTION__, __LINE__, text.c_str ()); - - if (program == NULL) - { - throw - megaglest_runtime_error - ("In [MainWindow::eventKeyDown] ERROR, program == NULL!"); - } - - bool - result = program->textInput (text); - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] result = %d\n", - __FILE__, __FUNCTION__, __LINE__, result); - - return result; - } - - bool - MainWindow::eventSdlKeyDown (SDL_KeyboardEvent key) - { - if (program == NULL) - { - throw - megaglest_runtime_error - ("In [MainWindow::eventKeyDown] ERROR, program == NULL!"); - } - return program->sdlKeyDown (key); - } - - void - MainWindow::eventKeyDown (SDL_KeyboardEvent key) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] [%d]\n", __FILE__, - __FUNCTION__, __LINE__, key.keysym.sym); - -//printf("In mainwindow checking keypress for key [%d]\n",key.keysym.sym); - - SDL_keysym - keystate = key.keysym; - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = [%c][%d]\n", - __FILE__, __FUNCTION__, __LINE__, key, key); - - if (program == NULL) - { - throw - megaglest_runtime_error - ("In [MainWindow::eventKeyDown] ERROR, program == NULL!"); - } - - if (popupMenu.getVisible () == true - && isKeyPressed (SDLK_ESCAPE, key) == true) - { - this->popupMenu.setEnabled (false); - this->popupMenu.setVisible (false); - return; - } - - program->keyDown (key); - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - if (keystate.mod & (KMOD_LALT | KMOD_RALT)) - { -//if(key == vkReturn) { - if (isKeyPressed (SDLK_RETURN, key) == true) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] ALT-ENTER pressed\n", - __FILE__, __FUNCTION__, __LINE__); - -// This stupidity only required in win32. -// We reload the textures so that the canvas paints textures properly + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + cleanupProcessObjects(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (sdl_quitCalled == false) { + sdl_quitCalled = true; + SDL_Quit(); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + inErrorNow = false; + + abort(); + } + + int + ExceptionHandler::DisplayMessage(const char *msg, bool exitApp) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__, + __FUNCTION__, __LINE__, msg, exitApp); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] msg [%s] exitApp = %d\n", + __FILE__, __FUNCTION__, __LINE__, msg, + exitApp); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__, + __FUNCTION__, __LINE__, msg, exitApp); + + if (mainProgram && gameInitialized == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__, + __FUNCTION__, __LINE__, msg, exitApp); + mainProgram->showMessage(msg); + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__, + __FUNCTION__, __LINE__, msg, exitApp); + message(msg, GlobalStaticFlags::getIsNonGraphicalModeEnabled(), + tempDataLocation); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__, + __FUNCTION__, __LINE__, msg, exitApp); + + if (exitApp == true) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", msg); + + // Now try to shutdown threads if possible + delete + mainProgram; + mainProgram = NULL; + // END + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__, + __FUNCTION__, __LINE__, msg, exitApp); + cleanupProcessObjects(); + + if (sdl_quitCalled == false) { + sdl_quitCalled = true; + SDL_Quit(); + } + exit(-1); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] msg [%s] exitApp = %d\n", __FILE__, + __FUNCTION__, __LINE__, msg, exitApp); + return 0; + } + + // ===================================================== + // class MainWindow + // ===================================================== + + MainWindow::MainWindow(Program * program) :WindowGl(), popupMenu("MainWindow", + "popupMenu") { + this->program = program; + //this->popupMenu.registerGraphicComponentOnlyFontCallbacks("MainWindow", "popupMenu"); + this->popupMenu.setEnabled(false); + this->popupMenu.setVisible(false); + this->triggerLanguageToggle = false; + this->triggerLanguage = ""; + this->cancelLanguageSelection = -1; + } + + MainWindow::~MainWindow() { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + delete + program; + program = NULL; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + int + MainWindow::getDesiredScreenWidth() { + Config & config = Config::getInstance(); + return config.getInt("ScreenWidth"); + } + int + MainWindow::getDesiredScreenHeight() { + Config & config = Config::getInstance(); + return config.getInt("ScreenHeight"); + } + + void + MainWindow::eventToggleFullScreen(bool isFullscreen) { + WindowGl::eventToggleFullScreen(isFullscreen); + + if (isFullscreen) { + Metrics::reload(this->program->getWindow()->getScreenWidth(), + this->program->getWindow()->getScreenHeight()); + } else { + Config & config = Config::getInstance(); + Metrics::reload(config.getInt("ScreenWidth"), + config.getInt("ScreenHeight")); + //window->setText(config.getString("WindowTitle","ZetaGlest")); + //this->mainMenu->init(); + } + + } + + void + MainWindow::eventMouseDown(int x, int y, MouseButton mouseButton) { + const + Metrics & + metrics = Metrics::getInstance(); + int + vx = metrics.toVirtualX(x); + int + vy = metrics.toVirtualY(getH() - y); + + if (program == NULL) { + throw + megaglest_runtime_error + ("In [MainWindow::eventMouseDown] ERROR, program == NULL!"); + } + + if (popupMenu.getVisible() == true && popupMenu.mouseClick(vx, vy)) { + std::pair < int, + string > + result = popupMenu.mouseClickedMenuItem(vx, vy); + + popupMenu.setEnabled(false); + popupMenu.setVisible(false); + + // Exit game + if (result.first != cancelLanguageSelection) { + Lang & lang = Lang::getInstance(); + map < string, string > languageList = + lang.getDiscoveredLanguageList(true); + for (map < string, string >::iterator iterMap = + languageList.begin(); iterMap != languageList.end(); + ++iterMap) { + string + matchLanguage = iterMap->first + "-" + iterMap->second; + if (matchLanguage == result.second) { + this->triggerLanguageToggle = true; + this->triggerLanguage = iterMap->first; + break; + } + } + + } + + return; + } + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + switch (mouseButton) { + case mbLeft: + program->mouseDownLeft(vx, vy); + break; + case mbRight: + //program->mouseDownRight(vx, vy); + break; + case mbCenter: + //program->mouseDownCenter(vx, vy); + break; + default: + break; + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + ProgramState * + programState = program->getState(); + if (programState != NULL) { + switch (mouseButton) { + case mbLeft: + programState->mouseDownLeft(vx, vy); + break; + case mbRight: + programState->mouseDownRight(vx, vy); + break; + case mbCenter: + programState->mouseDownCenter(vx, vy); + break; + default: + break; + } + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + void + MainWindow::eventMouseUp(int x, int y, MouseButton mouseButton) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + const + Metrics & + metrics = Metrics::getInstance(); + int + vx = metrics.toVirtualX(x); + int + vy = metrics.toVirtualY(getH() - y); + + if (program == NULL) { + throw + megaglest_runtime_error + ("In [MainWindow::eventMouseUp] ERROR, program == NULL!"); + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + ProgramState * + programState = program->getState(); + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + if (programState != NULL) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + switch (mouseButton) { + case mbLeft: + programState->mouseUpLeft(vx, vy); + break; + case mbRight: + programState->mouseUpRight(vx, vy); + break; + case mbCenter: + programState->mouseUpCenter(vx, vy); + break; + default: + break; + } + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + void + MainWindow::eventMouseDoubleClick(int x, int y, MouseButton mouseButton) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + const + Metrics & + metrics = Metrics::getInstance(); + int + vx = metrics.toVirtualX(x); + int + vy = metrics.toVirtualY(getH() - y); + + if (program == NULL) { + throw + megaglest_runtime_error + ("In [MainWindow::eventMouseDoubleClick] ERROR, program == NULL!"); + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + ProgramState * + programState = program->getState(); + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + if (programState != NULL) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + switch (mouseButton) { + case mbLeft: + programState->mouseDoubleClickLeft(vx, vy); + break; + case mbRight: + programState->mouseDoubleClickRight(vx, vy); + break; + case mbCenter: + programState->mouseDoubleClickCenter(vx, vy); + break; + default: + break; + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + void + MainWindow::eventMouseMove(int x, int y, const MouseState * ms) { + + const + Metrics & + metrics = Metrics::getInstance(); + int + vx = metrics.toVirtualX(x); + int + vy = metrics.toVirtualY(getH() - y); + + if (program == NULL) { + throw + megaglest_runtime_error + ("In [MainWindow::eventMouseMove] ERROR, program == NULL!"); + } + + program->eventMouseMove(vx, vy, ms); + + ProgramState * + programState = program->getState(); + if (programState != NULL) { + programState->mouseMove(vx, vy, ms); + } + } + + void + MainWindow::eventMouseWheel(int x, int y, int zDelta) { + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + const + Metrics & + metrics = Metrics::getInstance(); + int + vx = metrics.toVirtualX(x); + int + vy = metrics.toVirtualY(getH() - y); + + if (program == NULL) { + throw + megaglest_runtime_error + ("In [MainWindow::eventMouseMove] ERROR, program == NULL!"); + } + + ProgramState * + programState = program->getState(); + + if (programState != NULL) { + programState->eventMouseWheel(vx, vy, zDelta); + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + void + MainWindow::render() { + if (popupMenu.getVisible() == true) { + Renderer & renderer = Renderer::getInstance(); + renderer.renderPopupMenu(&popupMenu); + } + } + + void + MainWindow::showLanguages() { + Lang & lang = Lang::getInstance(); + std::vector < string > menuItems; + map < string, string > languageList = + lang.getDiscoveredLanguageList(true); + for (map < string, string >::iterator iterMap = languageList.begin(); + iterMap != languageList.end(); ++iterMap) { + menuItems.push_back(iterMap->first + "-" + iterMap->second); + } + + menuItems.push_back(lang.getString("Exit")); + cancelLanguageSelection = (int) menuItems.size() - 1; + + popupMenu.setW(100); + popupMenu.setH(100); + popupMenu.init(lang.getString("GameMenuTitle"), menuItems); + popupMenu.setEnabled(true); + popupMenu.setVisible(true); + } + + void + MainWindow::toggleLanguage(string language) { + popupMenu.setEnabled(false); + popupMenu.setVisible(false); + this->triggerLanguageToggle = false; + this->triggerLanguage = ""; + + Lang & lang = Lang::getInstance(); + string + currentLanguage = lang.getLanguage(); + + string + newLanguageSelected = language; + if (language == "") { + newLanguageSelected = currentLanguage; + + vector < string > langResults; + string + data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + + string + userDataPath = getGameCustomCoreDataPath(data_path, ""); + findAll(userDataPath + "data/lang/*.lng", langResults, true, false); + + vector < string > langResults2; + findAll(data_path + "data/lang/*.lng", langResults2, true); + if (langResults2.empty() && langResults.empty()) { + throw + megaglest_runtime_error("There are no lang files"); + } + for (unsigned int i = 0; i < langResults2.size(); ++i) { + string + testLanguage = langResults2[i]; + if (std::find(langResults.begin(), langResults.end(), + testLanguage) == langResults.end()) { + langResults.push_back(testLanguage); + } + } + + for (unsigned int i = 0; i < langResults.size(); ++i) { + string + testLanguage = langResults[i]; + if (testLanguage == currentLanguage) { + if (i + 1 < langResults.size()) { + newLanguageSelected = langResults[i + 1]; + } else { + newLanguageSelected = langResults[0]; + } + break; + } + } + } + if (newLanguageSelected != currentLanguage) { + lang.loadGameStrings(newLanguageSelected); + program->reloadUI(); + program->consoleAddLine(lang.getString("Language") + " " + + newLanguageSelected); + } + } + + bool + MainWindow::eventTextInput(std::string text) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] [%s]\n", __FILE__, + __FUNCTION__, __LINE__, text.c_str()); + + if (program == NULL) { + throw + megaglest_runtime_error + ("In [MainWindow::eventKeyDown] ERROR, program == NULL!"); + } + + bool + result = program->textInput(text); + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] result = %d\n", + __FILE__, __FUNCTION__, __LINE__, result); + + return result; + } + + bool + MainWindow::eventSdlKeyDown(SDL_KeyboardEvent key) { + if (program == NULL) { + throw + megaglest_runtime_error + ("In [MainWindow::eventKeyDown] ERROR, program == NULL!"); + } + return program->sdlKeyDown(key); + } + + void + MainWindow::eventKeyDown(SDL_KeyboardEvent key) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] [%d]\n", __FILE__, + __FUNCTION__, __LINE__, key.keysym.sym); + + //printf("In mainwindow checking keypress for key [%d]\n",key.keysym.sym); + + SDL_keysym + keystate = key.keysym; + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = [%c][%d]\n", + __FILE__, __FUNCTION__, __LINE__, key, key); + + if (program == NULL) { + throw + megaglest_runtime_error + ("In [MainWindow::eventKeyDown] ERROR, program == NULL!"); + } + + if (popupMenu.getVisible() == true + && isKeyPressed(SDLK_ESCAPE, key) == true) { + this->popupMenu.setEnabled(false); + this->popupMenu.setVisible(false); + return; + } + + program->keyDown(key); + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + if (keystate.mod & (KMOD_LALT | KMOD_RALT)) { + //if(key == vkReturn) { + if (isKeyPressed(SDLK_RETURN, key) == true) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] ALT-ENTER pressed\n", + __FILE__, __FUNCTION__, __LINE__); + + // This stupidity only required in win32. + // We reload the textures so that the canvas paints textures properly #ifdef WIN32 - if (Window::getAllowAltEnterFullscreenToggle () == true) - { - Renderer & renderer = Renderer::getInstance (); - renderer.reinitAll (); - } + if (Window::getAllowAltEnterFullscreenToggle() == true) { + Renderer & renderer = Renderer::getInstance(); + renderer.reinitAll(); + } #endif - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - } + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + } -//printf("In mainwindow checking keypress for key [%d] mod [%d] modvalue: %d\n",key.keysym.sym,keystate.mod,(keystate.mod & (KMOD_LCTRL | KMOD_RCTRL))); + //printf("In mainwindow checking keypress for key [%d] mod [%d] modvalue: %d\n",key.keysym.sym,keystate.mod,(keystate.mod & (KMOD_LCTRL | KMOD_RCTRL))); - if (program != NULL && program->isInSpecialKeyCaptureEvent () == false) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + if (program != NULL && program->isInSpecialKeyCaptureEvent() == false) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - vector < int > - modifiersToCheck; - modifiersToCheck.push_back (KMOD_LCTRL); - modifiersToCheck.push_back (KMOD_RCTRL); - modifiersToCheck.push_back (KMOD_LALT); - modifiersToCheck.push_back (KMOD_RALT); - modifiersToCheck.push_back (KMOD_LSHIFT); - modifiersToCheck.push_back (KMOD_RSHIFT); + vector < int > + modifiersToCheck; + modifiersToCheck.push_back(KMOD_LCTRL); + modifiersToCheck.push_back(KMOD_RCTRL); + modifiersToCheck.push_back(KMOD_LALT); + modifiersToCheck.push_back(KMOD_RALT); + modifiersToCheck.push_back(KMOD_LSHIFT); + modifiersToCheck.push_back(KMOD_RSHIFT); - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - if (isKeyPressed (configKeys.getSDLKey ("HotKeyShowDebug"), key) == - true) - { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + if (isKeyPressed(configKeys.getSDLKey("HotKeyShowDebug"), key) == + true) { - Renderer & renderer = Renderer::getInstance (); - if (keystate.mod & (KMOD_LALT | KMOD_RALT)) - { - renderer.cycleShowDebugUILevel (); - printf ("**Cycled Debug UI level to: %d\n", - renderer.getShowDebugUILevel ()); - } - else - { - bool - showDebugUI = renderer.getShowDebugUI (); - renderer.setShowDebugUI (!showDebugUI); - } - } - else if ((keystate.mod & (KMOD_LCTRL | KMOD_RCTRL)) && - isKeyPressed (configKeys.getSDLKey ("SwitchLanguage"), - key) == true) - { - if ((keystate.mod & (KMOD_LSHIFT | KMOD_RSHIFT))) - { - this->triggerLanguageToggle = true; - this->triggerLanguage = ""; - } - else - { - showLanguages (); - } - } - else - if (isKeyPressed - (configKeys.getSDLKey ("ReloadINI"), key, - modifiersToCheck) == true) - { - Config & config = Config::getInstance (); - config.reload (); - } - else - if (isKeyPressed - (configKeys.getSDLKey ("Screenshot"), key, - modifiersToCheck) == true) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Screenshot key pressed\n"); + Renderer & renderer = Renderer::getInstance(); + if (keystate.mod & (KMOD_LALT | KMOD_RALT)) { + renderer.cycleShowDebugUILevel(); + printf("**Cycled Debug UI level to: %d\n", + renderer.getShowDebugUILevel()); + } else { + bool + showDebugUI = renderer.getShowDebugUI(); + renderer.setShowDebugUI(!showDebugUI); + } + } else if ((keystate.mod & (KMOD_LCTRL | KMOD_RCTRL)) && + isKeyPressed(configKeys.getSDLKey("SwitchLanguage"), + key) == true) { + if ((keystate.mod & (KMOD_LSHIFT | KMOD_RSHIFT))) { + this->triggerLanguageToggle = true; + this->triggerLanguage = ""; + } else { + showLanguages(); + } + } else + if (isKeyPressed + (configKeys.getSDLKey("ReloadINI"), key, + modifiersToCheck) == true) { + Config & config = Config::getInstance(); + config.reload(); + } else + if (isKeyPressed + (configKeys.getSDLKey("Screenshot"), key, + modifiersToCheck) == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Screenshot key pressed\n"); - string - userData = Config::getInstance ().getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } + string + userData = Config::getInstance().getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } - string - path = userData + GameConstants::folder_path_screenshots; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Screenshot checking path [%s]\n", path.c_str ()); + string + path = userData + GameConstants::folder_path_screenshots; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Screenshot checking path [%s]\n", path.c_str()); - if (isdir (path.c_str ()) == false) - { - createDirectoryPaths (path); - } + if (isdir(path.c_str()) == false) { + createDirectoryPaths(path); + } - if (isdir (path.c_str ()) == true) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Screenshot path [%s]\n", path.c_str ()); + if (isdir(path.c_str()) == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Screenshot path [%s]\n", path.c_str()); - Config & config = Config::getInstance (); - string - fileFormat = config.getString ("ScreenShotFileType", "jpg"); + Config & config = Config::getInstance(); + string + fileFormat = config.getString("ScreenShotFileType", "jpg"); - unsigned int - queueSize = Renderer::getInstance ().getSaveScreenQueueSize (); + unsigned int + queueSize = Renderer::getInstance().getSaveScreenQueueSize(); - for (int i = 0; i < 5000; ++i) - { - path = userData + GameConstants::folder_path_screenshots; - path += - string ("screen") + intToStr (i + queueSize) + string (".") + - fileFormat; + for (int i = 0; i < 5000; ++i) { + path = userData + GameConstants::folder_path_screenshots; + path += + string("screen") + intToStr(i + queueSize) + string(".") + + fileFormat; #ifdef WIN32 - FILE * - f = _wfopen (utf8_decode (path).c_str (), L"rb"); + FILE * + f = _wfopen(utf8_decode(path).c_str(), L"rb"); #else - FILE * - f = fopen (path.c_str (), "rb"); + FILE * + f = fopen(path.c_str(), "rb"); #endif - if (f == NULL) - { - Lang & lang = Lang::getInstance (); - char - szBuf[8096] = ""; - if (lang.getString ("ScreenshotSavedTo").length () > 0 - && lang.getString ("ScreenshotSavedTo")[0] != '?') - { - snprintf (szBuf, 8096, - lang.getString ("ScreenshotSavedTo").c_str (), - path.c_str ()); - } - else - { - snprintf (szBuf, 8096, "Screenshot will be saved to: %s", - path.c_str ()); - } + if (f == NULL) { + Lang & lang = Lang::getInstance(); + char + szBuf[8096] = ""; + if (lang.getString("ScreenshotSavedTo").length() > 0 + && lang.getString("ScreenshotSavedTo")[0] != '?') { + snprintf(szBuf, 8096, + lang.getString("ScreenshotSavedTo").c_str(), + path.c_str()); + } else { + snprintf(szBuf, 8096, "Screenshot will be saved to: %s", + path.c_str()); + } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] %s\n", __FILE__, __FUNCTION__, - __LINE__, szBuf); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] %s\n", __FILE__, __FUNCTION__, + __LINE__, szBuf); - bool - showScreenshotSavedMsg = - Config::getInstance (). - getBool ("DisableScreenshotConsoleText", "false"); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Screenshot console showScreenshotSavedMsg = %d\n", - showScreenshotSavedMsg); + bool + showScreenshotSavedMsg = + Config::getInstance(). + getBool("DisableScreenshotConsoleText", "false"); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Screenshot console showScreenshotSavedMsg = %d\n", + showScreenshotSavedMsg); - if (showScreenshotSavedMsg == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Screenshot console [%s]\n", szBuf); - program->consoleAddLine (szBuf); - } + if (showScreenshotSavedMsg == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Screenshot console [%s]\n", szBuf); + program->consoleAddLine(szBuf); + } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Screenshot save to [%s]\n", path.c_str ()); - Renderer::getInstance ().saveScreen (path); - break; - } - else - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("CANNOT save Screenshot [%s]\n", path.c_str ()); - fclose (f); - } - } - } - } - } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Screenshot save to [%s]\n", path.c_str()); + Renderer::getInstance().saveScreen(path); + break; + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("CANNOT save Screenshot [%s]\n", path.c_str()); + fclose(f); + } + } + } + } + } - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } - void - MainWindow::eventKeyUp (SDL_KeyboardEvent key) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] [%d]\n", __FILE__, - __FUNCTION__, __LINE__, key); - if (program == NULL) - { - throw - megaglest_runtime_error - ("In [MainWindow::eventKeyUp] ERROR, program == NULL!"); - } + void + MainWindow::eventKeyUp(SDL_KeyboardEvent key) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] [%d]\n", __FILE__, + __FUNCTION__, __LINE__, key); + if (program == NULL) { + throw + megaglest_runtime_error + ("In [MainWindow::eventKeyUp] ERROR, program == NULL!"); + } - program->keyUp (key); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] [%d]\n", __FILE__, - __FUNCTION__, __LINE__, key); - } + program->keyUp(key); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] [%d]\n", __FILE__, + __FUNCTION__, __LINE__, key); + } - void - MainWindow::eventKeyPress (SDL_KeyboardEvent c) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] [%d]\n", __FILE__, - __FUNCTION__, __LINE__, c); - if (program == NULL) - { - throw - megaglest_runtime_error - ("In [MainWindow::eventKeyPress] ERROR, program == NULL!"); - } + void + MainWindow::eventKeyPress(SDL_KeyboardEvent c) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] [%d]\n", __FILE__, + __FUNCTION__, __LINE__, c); + if (program == NULL) { + throw + megaglest_runtime_error + ("In [MainWindow::eventKeyPress] ERROR, program == NULL!"); + } - program->keyPress (c); + program->keyPress(c); - if (program != NULL && program->isInSpecialKeyCaptureEvent () == false) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + if (program != NULL && program->isInSpecialKeyCaptureEvent() == false) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - if (isKeyPressed - (configKeys.getSDLKey ("HotKeyToggleOSMouseEnabled"), c) == true) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + if (isKeyPressed + (configKeys.getSDLKey("HotKeyToggleOSMouseEnabled"), c) == true) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - bool - showCursorState = false; - int - state = SDL_ShowCursor (SDL_QUERY); - if (state == SDL_DISABLE) - { - showCursorState = true; - } + bool + showCursorState = false; + int + state = SDL_ShowCursor(SDL_QUERY); + if (state == SDL_DISABLE) { + showCursorState = true; + } - showCursor (showCursorState); - Renderer & renderer = Renderer::getInstance (); - renderer.setNo2DMouseRendering (showCursorState); + showCursor(showCursorState); + Renderer & renderer = Renderer::getInstance(); + renderer.setNo2DMouseRendering(showCursorState); - Window::lastShowMouseState = SDL_ShowCursor (SDL_QUERY); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] Window::lastShowMouseState = %d\n", - __FILE__, __FUNCTION__, __LINE__, - Window::lastShowMouseState); - } - } - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] [%d]\n", __FILE__, - __FUNCTION__, __LINE__, c); - } + Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] Window::lastShowMouseState = %d\n", + __FILE__, __FUNCTION__, __LINE__, + Window::lastShowMouseState); + } + } + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] [%d]\n", __FILE__, + __FUNCTION__, __LINE__, c); + } - void - MainWindow::eventWindowEvent (SDL_WindowEvent event) - { - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] [%d]\n", __FILE__, - __FUNCTION__, __LINE__, event.event); - if (program == NULL) - { - throw - megaglest_runtime_error - ("In [MainWindow::eventKeyPress] ERROR, program == NULL!"); - } + void + MainWindow::eventWindowEvent(SDL_WindowEvent event) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] [%d]\n", __FILE__, + __FUNCTION__, __LINE__, event.event); + if (program == NULL) { + throw + megaglest_runtime_error + ("In [MainWindow::eventKeyPress] ERROR, program == NULL!"); + } -// if(program->getState() != NULL && dynamic_cast(program->getState()) != NULL) { -// printf("In eventWindowEvent skip\n"); -// return; -// } -//Renderer &renderer= Renderer::getInstance(); - switch (event.event) - { - case SDL_WINDOWEVENT_ENTER: - { -//printf("In SDL_WINDOWEVENT_ENTER\n"); -// bool showCursorState = Window::lastShowMouseState; -// showCursor(showCursorState); -// renderer.setNo2DMouseRendering(showCursorState); -// -// Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] Window::lastShowMouseState = %d\n", - __FILE__, __FUNCTION__, __LINE__, - Window::lastShowMouseState); - } - break; - case SDL_WINDOWEVENT_LEAVE: - { -//printf("In SDL_WINDOWEVENT_LEAVE\n"); -// bool showCursorState = false; -// int state = SDL_ShowCursor(SDL_QUERY); -// if(state == SDL_DISABLE) { -// showCursorState = true; -// } -// showCursor(showCursorState); -// renderer.setNo2DMouseRendering(showCursorState); -// -// Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] Window::lastShowMouseState = %d\n", - __FILE__, __FUNCTION__, __LINE__, - Window::lastShowMouseState); - } - break; - case SDL_WINDOWEVENT_FOCUS_GAINED: - { -//printf("SDL_WINDOWEVENT_FOCUS_GAINED\n"); -// bool showCursorState = Window::lastShowMouseState; -// showCursor(showCursorState); -// renderer.setNo2DMouseRendering(showCursorState); -// -// Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] Window::lastShowMouseState = %d\n", - __FILE__, __FUNCTION__, __LINE__, - Window::lastShowMouseState); - } - break; - case SDL_WINDOWEVENT_FOCUS_LOST: - { -//printf("SDL_WINDOWEVENT_FOCUS_LOST\n"); -// bool showCursorState = false; -// int state = SDL_ShowCursor(SDL_QUERY); -// if(state == SDL_DISABLE) { -// showCursorState = true; -// } -// showCursor(showCursorState); -// renderer.setNo2DMouseRendering(showCursorState); -// -// Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] Window::lastShowMouseState = %d\n", - __FILE__, __FUNCTION__, __LINE__, - Window::lastShowMouseState); - } - break; + // if(program->getState() != NULL && dynamic_cast(program->getState()) != NULL) { + // printf("In eventWindowEvent skip\n"); + // return; + // } + //Renderer &renderer= Renderer::getInstance(); + switch (event.event) { + case SDL_WINDOWEVENT_ENTER: + { + //printf("In SDL_WINDOWEVENT_ENTER\n"); + // bool showCursorState = Window::lastShowMouseState; + // showCursor(showCursorState); + // renderer.setNo2DMouseRendering(showCursorState); + // + // Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] Window::lastShowMouseState = %d\n", + __FILE__, __FUNCTION__, __LINE__, + Window::lastShowMouseState); + } + break; + case SDL_WINDOWEVENT_LEAVE: + { + //printf("In SDL_WINDOWEVENT_LEAVE\n"); + // bool showCursorState = false; + // int state = SDL_ShowCursor(SDL_QUERY); + // if(state == SDL_DISABLE) { + // showCursorState = true; + // } + // showCursor(showCursorState); + // renderer.setNo2DMouseRendering(showCursorState); + // + // Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] Window::lastShowMouseState = %d\n", + __FILE__, __FUNCTION__, __LINE__, + Window::lastShowMouseState); + } + break; + case SDL_WINDOWEVENT_FOCUS_GAINED: + { + //printf("SDL_WINDOWEVENT_FOCUS_GAINED\n"); + // bool showCursorState = Window::lastShowMouseState; + // showCursor(showCursorState); + // renderer.setNo2DMouseRendering(showCursorState); + // + // Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] Window::lastShowMouseState = %d\n", + __FILE__, __FUNCTION__, __LINE__, + Window::lastShowMouseState); + } + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + { + //printf("SDL_WINDOWEVENT_FOCUS_LOST\n"); + // bool showCursorState = false; + // int state = SDL_ShowCursor(SDL_QUERY); + // if(state == SDL_DISABLE) { + // showCursorState = true; + // } + // showCursor(showCursorState); + // renderer.setNo2DMouseRendering(showCursorState); + // + // Window::lastShowMouseState = SDL_ShowCursor(SDL_QUERY); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] Window::lastShowMouseState = %d\n", + __FILE__, __FUNCTION__, __LINE__, + Window::lastShowMouseState); + } + break; - } + } - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] [%d]\n", __FILE__, - __FUNCTION__, __LINE__, event.event); - } + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] [%d]\n", __FILE__, + __FUNCTION__, __LINE__, event.event); + } - void - MainWindow::eventActivate (bool active) - { - if (!active) - { -//minimize(); - } - } + void + MainWindow::eventActivate(bool active) { + if (!active) { + //minimize(); + } + } - void - MainWindow::eventResize (SizeState sizeState) - { - if (program == NULL) - { - throw - megaglest_runtime_error - ("In [MainWindow::eventResize] ERROR, program == NULL!"); - } + void + MainWindow::eventResize(SizeState sizeState) { + if (program == NULL) { + throw + megaglest_runtime_error + ("In [MainWindow::eventResize] ERROR, program == NULL!"); + } - program->resize (sizeState); - } + program->resize(sizeState); + } - void - MainWindow::eventClose () - { - delete - program; - program = NULL; - } + void + MainWindow::eventClose() { + delete + program; + program = NULL; + } - void - MainWindow::setProgram (Program * program) - { - this->program = program; - } + void + MainWindow::setProgram(Program * program) { + this->program = program; + } -// ===================================================== -// Main -// ===================================================== - SystemFlags - debugger; + // ===================================================== + // Main + // ===================================================== + SystemFlags + debugger; - void - print_SDL_version (const char *preamble, SDL_version * v) - { - printf ("%s %u.%u.%u\n", preamble, v->major, v->minor, v->patch); - } + void + print_SDL_version(const char *preamble, SDL_version * v) { + printf("%s %u.%u.%u\n", preamble, v->major, v->minor, v->patch); + } - int - setupGameItemPaths (int argc, char **argv, Config * config) - { -// Setup path cache for files and folders used in the game - std::map < string, string > &pathCache = - CacheManager::getCachedItem < std::map < string, - string > >(GameConstants::pathCacheLookupKey); + int + setupGameItemPaths(int argc, char **argv, Config * config) { + // Setup path cache for files and folders used in the game + std::map < string, string > &pathCache = + CacheManager::getCachedItem < std::map < string, + string > >(GameConstants::pathCacheLookupKey); - Properties - devProperties; - string - devPropertyFile = Properties::getApplicationPath () + "glest-dev.ini"; - if (fileExists (devPropertyFile) == true) - { - devProperties.load (devPropertyFile); + Properties + devProperties; + string + devPropertyFile = Properties::getApplicationPath() + "glest-dev.ini"; + if (fileExists(devPropertyFile) == true) { + devProperties.load(devPropertyFile); - if (devProperties.hasString ("ServerListPath") == true) - { - string - devItem = devProperties.getString ("ServerListPath"); - if (devItem != "") - { - endPathWithSlash (devItem); - } - if (config != NULL) - { - config->setString ("ServerListPath", devItem, true); - } - } + if (devProperties.hasString("ServerListPath") == true) { + string + devItem = devProperties.getString("ServerListPath"); + if (devItem != "") { + endPathWithSlash(devItem); + } + if (config != NULL) { + config->setString("ServerListPath", devItem, true); + } + } - if (devProperties.hasString ("GlestKeysIniPath") == true) - { - string - devItem = devProperties.getString ("GlestKeysIniPath"); - if (devItem != "") - { - endPathWithSlash (devItem); - } - if (config != NULL) - { - config->setString ("GlestKeysIniPath", devItem, true); - } - } - } + if (devProperties.hasString("GlestKeysIniPath") == true) { + string + devItem = devProperties.getString("GlestKeysIniPath"); + if (devItem != "") { + endPathWithSlash(devItem); + } + if (config != NULL) { + config->setString("GlestKeysIniPath", devItem, true); + } + } + } -//GAME_ARG_DATA_PATH - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_DATA_PATH]) == - true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_DATA_PATH]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_DATA_PATH]), - &foundParamIndIndex); - } - string - customPath = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (customPath, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - customPathValue = paramPartTokens[1]; - Properties::applyTagsToValue (customPathValue); - if (customPathValue != "") - { - endPathWithSlash (customPathValue); - } - pathCache[GameConstants::path_data_CacheLookupKey] = - customPathValue; - Properties::setApplicationDataPath (pathCache - [GameConstants:: - path_data_CacheLookupKey]); + //GAME_ARG_DATA_PATH + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_DATA_PATH]) == + true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_DATA_PATH]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_DATA_PATH]), + &foundParamIndIndex); + } + string + customPath = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(customPath, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + customPathValue = paramPartTokens[1]; + Properties::applyTagsToValue(customPathValue); + if (customPathValue != "") { + endPathWithSlash(customPathValue); + } + pathCache[GameConstants::path_data_CacheLookupKey] = + customPathValue; + Properties::setApplicationDataPath(pathCache + [GameConstants:: + path_data_CacheLookupKey]); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Using custom data path [%s]\n", - customPathValue.c_str ()); - } - else - { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Using custom data path [%s]\n", + customPathValue.c_str()); + } else { - printf - ("\nInvalid path specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - printParameterHelp (argv[0], false); - return 1; - } - } - else if (config != NULL) - { + printf + ("\nInvalid path specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(argv[0], false); + return 1; + } + } else if (config != NULL) { - bool - foundPath = false; - string - customPathValue = ""; + bool + foundPath = false; + string + customPathValue = ""; - if (fileExists (devPropertyFile) == true - && devProperties.hasString ("DataPath") == true) - { - foundPath = true; - customPathValue = devProperties.getString ("DataPath", ""); - } - else if (config->getString ("DataPath", "") != "") - { - foundPath = true; - customPathValue = config->getString ("DataPath", ""); - } + if (fileExists(devPropertyFile) == true + && devProperties.hasString("DataPath") == true) { + foundPath = true; + customPathValue = devProperties.getString("DataPath", ""); + } else if (config->getString("DataPath", "") != "") { + foundPath = true; + customPathValue = config->getString("DataPath", ""); + } - if (foundPath == true) - { - pathCache[GameConstants::path_data_CacheLookupKey] = - customPathValue; + if (foundPath == true) { + pathCache[GameConstants::path_data_CacheLookupKey] = + customPathValue; - if (customPathValue != "") - { - endPathWithSlash (customPathValue); - } + if (customPathValue != "") { + endPathWithSlash(customPathValue); + } - Properties::setApplicationDataPath (pathCache - [GameConstants:: - path_data_CacheLookupKey]); + Properties::setApplicationDataPath(pathCache + [GameConstants:: + path_data_CacheLookupKey]); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Using ini specified data path [%s]\n", - config->getString ("DataPath", "").c_str ()); - } - } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Using ini specified data path [%s]\n", + config->getString("DataPath", "").c_str()); + } + } -//GAME_ARG_INI_PATH - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_INI_PATH]) == - true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_INI_PATH]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_INI_PATH]), - &foundParamIndIndex); - } - string - customPath = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (customPath, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - customPathValue = paramPartTokens[1]; - Properties::applyTagsToValue (customPathValue); - pathCache[GameConstants::path_ini_CacheLookupKey] = customPathValue; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Using custom ini path [%s]\n", customPathValue.c_str ()); - } - else - { + //GAME_ARG_INI_PATH + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_INI_PATH]) == + true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_INI_PATH]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_INI_PATH]), + &foundParamIndIndex); + } + string + customPath = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(customPath, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + customPathValue = paramPartTokens[1]; + Properties::applyTagsToValue(customPathValue); + pathCache[GameConstants::path_ini_CacheLookupKey] = customPathValue; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Using custom ini path [%s]\n", customPathValue.c_str()); + } else { - printf - ("\nInvalid path specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - printParameterHelp (argv[0], false); - return 1; - } - } + printf + ("\nInvalid path specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(argv[0], false); + return 1; + } + } -//GAME_ARG_LOG_PATH - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_LOG_PATH]) == - true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_LOG_PATH]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_LOG_PATH]), - &foundParamIndIndex); - } - string - customPath = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (customPath, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - customPathValue = paramPartTokens[1]; - Properties::applyTagsToValue (customPathValue); - pathCache[GameConstants::path_logs_CacheLookupKey] = - customPathValue; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Using custom logs path [%s]\n", - customPathValue.c_str ()); - } - else - { + //GAME_ARG_LOG_PATH + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_LOG_PATH]) == + true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_LOG_PATH]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_LOG_PATH]), + &foundParamIndIndex); + } + string + customPath = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(customPath, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + customPathValue = paramPartTokens[1]; + Properties::applyTagsToValue(customPathValue); + pathCache[GameConstants::path_logs_CacheLookupKey] = + customPathValue; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Using custom logs path [%s]\n", + customPathValue.c_str()); + } else { - printf - ("\nInvalid path specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - printParameterHelp (argv[0], false); - return 1; - } - } - else if (config != NULL) - { + printf + ("\nInvalid path specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(argv[0], false); + return 1; + } + } else if (config != NULL) { - bool - foundPath = false; - string - customPathValue = ""; + bool + foundPath = false; + string + customPathValue = ""; - if (fileExists (devPropertyFile) == true - && devProperties.hasString ("LogPath") == true) - { - foundPath = true; - customPathValue = devProperties.getString ("LogPath", ""); - } - else if (config->getString ("LogPath", "") != "") - { - foundPath = true; - customPathValue = config->getString ("LogPath", ""); - } + if (fileExists(devPropertyFile) == true + && devProperties.hasString("LogPath") == true) { + foundPath = true; + customPathValue = devProperties.getString("LogPath", ""); + } else if (config->getString("LogPath", "") != "") { + foundPath = true; + customPathValue = config->getString("LogPath", ""); + } - if (foundPath == true) - { - pathCache[GameConstants::path_logs_CacheLookupKey] = - customPathValue; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Using ini specified logs path [%s]\n", - config->getString ("LogPath", "").c_str ()); - } - } + if (foundPath == true) { + pathCache[GameConstants::path_logs_CacheLookupKey] = + customPathValue; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Using ini specified logs path [%s]\n", + config->getString("LogPath", "").c_str()); + } + } - Text::DEFAULT_FONT_PATH = - pathCache[GameConstants::path_data_CacheLookupKey]; - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_FONT_PATH]) == - true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_FONT_PATH]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_FONT_PATH]), - &foundParamIndIndex); - } - string - customPath = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (customPath, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - customPathValue = paramPartTokens[1]; - Properties::applyTagsToValue (customPathValue); + Text::DEFAULT_FONT_PATH = + pathCache[GameConstants::path_data_CacheLookupKey]; + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_FONT_PATH]) == + true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_FONT_PATH]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_FONT_PATH]), + &foundParamIndIndex); + } + string + customPath = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(customPath, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + customPathValue = paramPartTokens[1]; + Properties::applyTagsToValue(customPathValue); - Text::DEFAULT_FONT_PATH_ABSOLUTE = customPathValue; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Using custom fonts path [%s]\n", - customPathValue.c_str ()); - } - else - { + Text::DEFAULT_FONT_PATH_ABSOLUTE = customPathValue; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Using custom fonts path [%s]\n", + customPathValue.c_str()); + } else { - printf - ("\nInvalid path specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - printParameterHelp (argv[0], false); - return 1; - } - } + printf + ("\nInvalid path specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(argv[0], false); + return 1; + } + } - return 0; - } + return 0; + } - void - setupLogging (Config & config, bool haveSpecialOutputCommandLineOption) - { + void + setupLogging(Config & config, bool haveSpecialOutputCommandLineOption) { - SystemFlags::getSystemSettingType (SystemFlags::debugSystem).enabled = - config.getBool ("DebugMode", "false"); - SystemFlags::getSystemSettingType (SystemFlags::debugNetwork).enabled = - config.getBool ("DebugNetwork", "false"); - SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - enabled = config.getBool ("DebugPerformance", "false"); - SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch). - enabled = config.getBool ("DebugWorldSynch", "false"); - SystemFlags::getSystemSettingType (SystemFlags::debugUnitCommands). - enabled = config.getBool ("DebugUnitCommands", "false"); - SystemFlags::getSystemSettingType (SystemFlags::debugPathFinder). - enabled = config.getBool ("DebugPathFinder", "false"); - SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled = - config.getBool ("DebugLUA", "false"); - LuaScript::setDebugModeEnabled (SystemFlags:: - getSystemSettingType (SystemFlags:: - debugLUA). - enabled); - SystemFlags::getSystemSettingType (SystemFlags::debugSound).enabled = - config.getBool ("DebugSound", "false"); - SystemFlags::getSystemSettingType (SystemFlags::debugError).enabled = - config.getBool ("DebugError", "true"); + SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled = + config.getBool("DebugMode", "false"); + SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled = + config.getBool("DebugNetwork", "false"); + SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + enabled = config.getBool("DebugPerformance", "false"); + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch). + enabled = config.getBool("DebugWorldSynch", "false"); + SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands). + enabled = config.getBool("DebugUnitCommands", "false"); + SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder). + enabled = config.getBool("DebugPathFinder", "false"); + SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled = + config.getBool("DebugLUA", "false"); + LuaScript::setDebugModeEnabled(SystemFlags:: + getSystemSettingType(SystemFlags:: + debugLUA). + enabled); + SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled = + config.getBool("DebugSound", "false"); + SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled = + config.getBool("DebugError", "true"); - string - userData = config.getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } + string + userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } #ifdef HAVE_GOOGLE_BREAKPAD - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#1 In setting up errorHandlerPtr->set_dump_path [%p]...\n", - errorHandlerPtr.get ()); - if (errorHandlerPtr.get () != NULL) - { - string - dumpFilePath; - if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) != - "") - { - dumpFilePath = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey); - } - else - { - dumpFilePath = userData; - } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#1 In setting up errorHandlerPtr->set_dump_path [%p]...\n", + errorHandlerPtr.get()); + if (errorHandlerPtr.get() != NULL) { + string + dumpFilePath; + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != + "") { + dumpFilePath = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey); + } else { + dumpFilePath = userData; + } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#2 In setting up errorHandlerPtr->set_dump_path...\n"); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#2 In setting up errorHandlerPtr->set_dump_path...\n"); # if defined(WIN32) - wstring - dumpfilepath = utf8_decode (dumpFilePath); - if (SystemFlags::VERBOSE_MODE_ENABLED) - wprintf - (L"Hooking up google_breakpad::ExceptionHandler to save dmp files to [%s]...\n", - dumpfilepath.c_str ()); - errorHandlerPtr->set_dump_path (dumpfilepath); + wstring + dumpfilepath = utf8_decode(dumpFilePath); + if (SystemFlags::VERBOSE_MODE_ENABLED) + wprintf + (L"Hooking up google_breakpad::ExceptionHandler to save dmp files to [%s]...\n", + dumpfilepath.c_str()); + errorHandlerPtr->set_dump_path(dumpfilepath); # else - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("Hooking up google_breakpad::ExceptionHandler to save dmp files to [%s]...\n", - dumpFilePath.c_str ()); -//errorHandlerPtr->set_dump_path(dumpfilepath); - google_breakpad::MinidumpDescriptor descriptor (dumpFilePath); - errorHandlerPtr->set_minidump_descriptor (descriptor); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("Hooking up google_breakpad::ExceptionHandler to save dmp files to [%s]...\n", + dumpFilePath.c_str()); + //errorHandlerPtr->set_dump_path(dumpfilepath); + google_breakpad::MinidumpDescriptor descriptor(dumpFilePath); + errorHandlerPtr->set_minidump_descriptor(descriptor); # endif - } + } #endif - string - debugLogFile = config.getString ("DebugLogFile", ""); - if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) != - "") - { - debugLogFile = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - debugLogFile; - } - else - { - debugLogFile = userData + debugLogFile; - } - - string - debugWorldSynchLogFile = - config.getString ("DebugLogFileWorldSynch", ""); - if (debugWorldSynchLogFile == "") - { - debugWorldSynchLogFile = debugLogFile; - } - else if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) - != "") - { - debugWorldSynchLogFile = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - debugWorldSynchLogFile; - } - else - { - debugWorldSynchLogFile = userData + debugWorldSynchLogFile; - } - - string - debugPerformanceLogFile = - config.getString ("DebugLogFilePerformance", ""); - if (debugPerformanceLogFile == "") - { - debugPerformanceLogFile = debugLogFile; - } - else if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) - != "") - { - debugPerformanceLogFile = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - debugPerformanceLogFile; - } - else - { - debugPerformanceLogFile = userData + debugPerformanceLogFile; - } - - string - debugNetworkLogFile = config.getString ("DebugLogFileNetwork", ""); - if (debugNetworkLogFile == "") - { - debugNetworkLogFile = debugLogFile; - } - else if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) - != "") - { - debugNetworkLogFile = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - debugNetworkLogFile; - } - else - { - debugNetworkLogFile = userData + debugNetworkLogFile; - } - - string - debugUnitCommandsLogFile = - config.getString ("DebugLogFileUnitCommands", ""); - if (debugUnitCommandsLogFile == "") - { - debugUnitCommandsLogFile = debugLogFile; - } - else if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) - != "") - { - debugUnitCommandsLogFile = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - debugUnitCommandsLogFile; - } - else - { - debugUnitCommandsLogFile = userData + debugUnitCommandsLogFile; - } - - string - debugPathFinderLogFile = - config.getString ("DebugLogFilePathFinder", ""); - if (debugPathFinderLogFile == "") - { - debugPathFinderLogFile = debugLogFile; - } - else if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) - != "") - { - debugPathFinderLogFile = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - debugPathFinderLogFile; - } - else - { - debugPathFinderLogFile = userData + debugPathFinderLogFile; - } - - string - debugLUALogFile = config.getString ("DebugLogFileLUA", ""); - if (debugLUALogFile == "") - { - debugLUALogFile = debugLogFile; - } - else if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) - != "") - { - debugLUALogFile = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - debugLUALogFile; - } - else - { - debugLUALogFile = userData + debugLUALogFile; - } - - string - debugSoundLogFile = config.getString ("DebugLogFileSound", ""); - if (debugSoundLogFile == "") - { - debugSoundLogFile = debugLogFile; - } - else if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) - != "") - { - debugSoundLogFile = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - debugSoundLogFile; - } - else - { - debugSoundLogFile = userData + debugSoundLogFile; - } - - string - debugErrorLogFile = config.getString ("DebugLogFileError", ""); - - SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - debugLogFileName = debugLogFile; - SystemFlags::getSystemSettingType (SystemFlags::debugNetwork). - debugLogFileName = debugNetworkLogFile; - SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). - debugLogFileName = debugPerformanceLogFile; - SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch). - debugLogFileName = debugWorldSynchLogFile; - SystemFlags::getSystemSettingType (SystemFlags::debugUnitCommands). - debugLogFileName = debugUnitCommandsLogFile; - SystemFlags::getSystemSettingType (SystemFlags::debugPathFinder). - debugLogFileName = debugPathFinderLogFile; - SystemFlags::getSystemSettingType (SystemFlags::debugLUA). - debugLogFileName = debugLUALogFile; - SystemFlags::getSystemSettingType (SystemFlags::debugSound). - debugLogFileName = debugSoundLogFile; - SystemFlags::getSystemSettingType (SystemFlags::debugError). - debugLogFileName = debugErrorLogFile; - - if (haveSpecialOutputCommandLineOption == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("--- Startup log settings are ---\ndebugSystem [%d][%s]\ndebugNetwork [%d][%s]\ndebugPerformance [%d][%s]\ndebugWorldSynch [%d][%s]\ndebugUnitCommands[%d][%s]\ndebugPathFinder[%d][%s]\ndebugLUA [%d][%s]\ndebugSound [%d][%s]\ndebugError [%d][%s]\n", - SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled, debugLogFile.c_str (), - SystemFlags::getSystemSettingType (SystemFlags::debugNetwork). - enabled, debugNetworkLogFile.c_str (), - SystemFlags::getSystemSettingType (SystemFlags:: - debugPerformance).enabled, - debugPerformanceLogFile.c_str (), - SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch). - enabled, debugWorldSynchLogFile.c_str (), - SystemFlags::getSystemSettingType (SystemFlags:: - debugUnitCommands).enabled, - debugUnitCommandsLogFile.c_str (), - SystemFlags::getSystemSettingType (SystemFlags::debugPathFinder). - enabled, debugPathFinderLogFile.c_str (), - SystemFlags::getSystemSettingType (SystemFlags::debugLUA). - enabled, debugLUALogFile.c_str (), - SystemFlags::getSystemSettingType (SystemFlags::debugSound). - enabled, debugSoundLogFile.c_str (), - SystemFlags::getSystemSettingType (SystemFlags::debugError). - enabled, debugErrorLogFile.c_str ()); - } - } - - void - runTilesetValidationForPath (string tilesetPath, string tilesetName, - World & world, bool purgeUnusedFiles, - bool purgeDuplicateFiles, - bool showDuplicateFiles, bool gitPurgeFiles, - double &purgedMegaBytes) - { - Checksum - checksum; - -//bool techtree_errors = false; - - std::map < string, vector < pair < string, string > > >loadedFileList; - vector < string > pathList; - pathList.push_back (tilesetPath); - world.loadTileset (pathList, tilesetName, &checksum, loadedFileList); - -// Fixup paths with .. - { - std::map < string, vector < pair < string, - string > > >newLoadedFileList; - for (std::map < string, vector < pair < string, - string > > >::iterator iterMap = loadedFileList.begin (); - iterMap != loadedFileList.end (); ++iterMap) - { - string - loadedFile = iterMap->first; - - replaceAll (loadedFile, "//", "/"); - replaceAll (loadedFile, "\\\\", "\\"); - updatePathClimbingParts (loadedFile); - - if (newLoadedFileList.find (loadedFile) != newLoadedFileList.end ()) - { - for (unsigned int xx1 = 0; xx1 < iterMap->second.size (); ++xx1) - { - pair < string, string > &newVal = iterMap->second[xx1]; - replaceAll (newVal.first, "//", "/"); - replaceAll (newVal.first, "\\\\", "\\"); - updatePathClimbingParts (newVal.first); - replaceAll (newVal.second, "//", "/"); - replaceAll (newVal.second, "\\\\", "\\"); - updatePathClimbingParts (newVal.second); - - newLoadedFileList[loadedFile].push_back (newVal); - } - } - else - { - for (unsigned int xx1 = 0; xx1 < iterMap->second.size (); ++xx1) - { - pair < string, string > &newVal = iterMap->second[xx1]; - replaceAll (newVal.first, "//", "/"); - replaceAll (newVal.first, "\\\\", "\\"); - updatePathClimbingParts (newVal.first); - replaceAll (newVal.second, "//", "/"); - replaceAll (newVal.second, "\\\\", "\\"); - updatePathClimbingParts (newVal.second); - } - - newLoadedFileList[loadedFile] = iterMap->second; - } - } - loadedFileList = newLoadedFileList; - } - -// Validate the faction setup to ensure we don't have any bad associations -// std::vector resultErrors = world.validateFactionTypes(); - -// Now check for unused files in the techtree - std::map < string, vector < pair < string, string > > >foundFileList; - for (unsigned int i = 0; i < pathList.size (); ++i) - { - string - path = pathList[i]; - endPathWithSlash (path); - path = path + tilesetName + "/"; - - replaceAll (path, "//", "/"); - replaceAll (path, "\\\\", "\\"); - - vector < string > foundFiles = - getFolderTreeContentsListRecursively (path + "*.", ""); - for (unsigned int j = 0; j < foundFiles.size (); ++j) - { - string - file = foundFiles[j]; - replaceAll (file, "//", "/"); - replaceAll (file, "\\\\", "\\"); - - replaceAll (file, "//", "/"); - replaceAll (file, "\\\\", "\\"); - - foundFileList[file].push_back (make_pair (path, path)); - } - } - - printf ("Found tileset filecount = " MG_SIZE_T_SPECIFIER ", used = " - MG_SIZE_T_SPECIFIER "\n", foundFileList.size (), - loadedFileList.size ()); - - int - purgeCount = 0; - bool - foundUnusedFile = false; - for (std::map < string, vector < pair < string, - string > > >::iterator iterMap = foundFileList.begin (); - iterMap != foundFileList.end (); ++iterMap) - { - string - foundFile = iterMap->first; - replaceAll (foundFile, "//", "/"); - replaceAll (foundFile, "\\\\", "\\"); - - if (loadedFileList.find (foundFile) == loadedFileList.end () && - foundFile.find ("lang/") == foundFile.npos) - { - if (foundUnusedFile == false) - { - printf - ("\nLine ref: %d, Warning, unused files were detected - START:\n=====================\n", - __LINE__); - } - foundUnusedFile = true; - - printf ("[%s]\n", foundFile.c_str ()); - - string - fileName = extractFileFromDirectoryPath (foundFile); - if (loadedFileList.find (fileName) != loadedFileList.end ()) - { - printf ("possible match on [%s] ?\n", - loadedFileList.find (fileName)->first.c_str ()); - } - else if (purgeUnusedFiles == true) - { - off_t - fileSize = getFileSize (foundFile); -// convert to MB - purgedMegaBytes += ((double) fileSize / 1048576.0); - purgeCount++; - - if (gitPurgeFiles == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "git rm \"%s\"", foundFile.c_str ()); - bool - gitOk = executeShellCommand (szBuf, 0); - if (gitOk == false) - { - throw - megaglest_runtime_error ("Call to command failed [" + - string (szBuf) + "]"); - } - } - else - { - removeFile (foundFile); - } - } - } - } - if (foundUnusedFile == true) - { - if (purgedMegaBytes > 0) - { - printf ("Purged %.2f MB (%d) in files\n", purgedMegaBytes, - purgeCount); - } - printf - ("\nLine ref: %d, Warning, unused files were detected - END:\n", - __LINE__); - } - - if (showDuplicateFiles == true) - { - std::map < uint32, vector < string > >mapDuplicateFiles; -// Now check for duplicate data content - for (std::map < string, vector < pair < string, - string > > >::iterator iterMap = loadedFileList.begin (); - iterMap != loadedFileList.end (); ++iterMap) - { - string - fileName = iterMap->first; - Checksum - checksum; - checksum.addFile (fileName); - uint32 - crcValue = checksum.getSum (); - mapDuplicateFiles[crcValue].push_back (fileName); - } - - double - duplicateMegaBytesPurged = 0; - int - duplicateCountPurged = 0; - - double - duplicateMegaBytes = 0; - int - duplicateCount = 0; - - bool - foundDuplicates = false; - for (std::map < uint32, vector < string > >::iterator iterMap = - mapDuplicateFiles.begin (); iterMap != mapDuplicateFiles.end (); - ++iterMap) - { - vector < string > &fileList = iterMap->second; - if (fileList.size () > 1) - { - if (foundDuplicates == false) - { - foundDuplicates = true; - printf - ("\nWarning, duplicate files were detected - START:\n=====================\n"); - } - - map < string, int > - parentList; - for (unsigned int idx = 0; idx < fileList.size (); ++idx) - { - string - duplicateFile = fileList[idx]; - if (idx > 0) - { - off_t - fileSize = getFileSize (duplicateFile); -// convert to MB - duplicateMegaBytes += ((double) fileSize / 1048576.0); - duplicateCount++; - } - else - { - printf ("\n"); - } - - printf ("[%s]\n", duplicateFile.c_str ()); - std::map < string, vector < pair < string, - string > > >::iterator iterFind = - loadedFileList.find (duplicateFile); - if (iterFind != loadedFileList.end ()) - { - for (unsigned int jdx = 0; jdx < iterFind->second.size (); - jdx++) - { - parentList[iterFind->second[jdx].first]++; - } - } - } - - for (map < string, int >::iterator iterMap1 = parentList.begin (); - iterMap1 != parentList.end (); ++iterMap1) - { - - if (iterMap1 == parentList.begin ()) - { - printf ("\tParents:\n"); - } - printf ("\t[%s]\n", iterMap1->first.c_str ()); - } - - if (purgeDuplicateFiles == true) - { - - string - newCommonFileName = ""; - for (unsigned int idx = 0; idx < fileList.size (); ++idx) - { - string - duplicateFile = fileList[idx]; - string - fileExt = extractExtension (duplicateFile); - if (fileExt == "wav" || fileExt == "ogg") - { - off_t - fileSize = getFileSize (duplicateFile); - if (idx == 0) - { - newCommonFileName = - "$COMMONDATAPATH/sounds/" + - extractFileFromDirectoryPath (duplicateFile); - - string - expandedNewCommonFileName = newCommonFileName; - - std::map < string, string > mapExtraTagReplacementValues; - - mapExtraTagReplacementValues = - Properties::getTagReplacementValues - (&mapExtraTagReplacementValues); - Properties::applyTagsToValue (expandedNewCommonFileName, - &mapExtraTagReplacementValues); - replaceAll (expandedNewCommonFileName, "//", "/"); - createDirectoryPaths (extractDirectoryPathFromFile - (expandedNewCommonFileName)); - - if (gitPurgeFiles == true) - { - copyFileTo (duplicateFile, expandedNewCommonFileName); - - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "git rm \"%s\"", - duplicateFile.c_str ()); - bool - gitOk = executeShellCommand (szBuf, 0); - if (gitOk == false) - { - throw - megaglest_runtime_error ("Call to command failed [" - + string (szBuf) + "]"); - } - printf - ("*** Duplicate file:\n[%s]\nwas git rm and copied to:\n[%s]\n", - duplicateFile.c_str (), - expandedNewCommonFileName.c_str ()); - } - else - { -//int result = 0; - int - result = rename (duplicateFile.c_str (), - expandedNewCommonFileName.c_str ()); - if (result != 0) - { - char - szBuf[8096] = ""; - char * - errmsg = strerror (errno); - snprintf (szBuf, 8096, - "!!! Error [%s] Could not rename [%s] to [%s]!", - errmsg, duplicateFile.c_str (), - expandedNewCommonFileName.c_str ()); - throw - megaglest_runtime_error (szBuf); - } - else - { - printf - ("*** Duplicate file:\n[%s]\nwas renamed to:\n[%s]\n", - duplicateFile.c_str (), - expandedNewCommonFileName.c_str ()); - } - } - } - else - { - if (gitPurgeFiles == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "git rm \"%s\"", - duplicateFile.c_str ()); - bool - gitOk = executeShellCommand (szBuf, 0); - if (gitOk == false) - { - throw - megaglest_runtime_error ("Call to command failed [" - + string (szBuf) + "]"); - } - printf ("*** Duplicate file:\n[%s]\nwas git rm\n", - duplicateFile.c_str ()); - } - else - { - removeFile (duplicateFile); - } - printf ("*** Duplicate file:\n[%s]\nwas removed\n", - duplicateFile.c_str ()); - -// convert to MB - duplicateMegaBytesPurged += - ((double) fileSize / 1048576.0); - duplicateCountPurged++; - } - } - } - - std::map < string, int > - mapUniqueParentList; - - for (unsigned int idx = 0; idx < fileList.size (); ++idx) - { - string - duplicateFile = fileList[idx]; - string - fileExt = extractExtension (duplicateFile); - if (fileExt == "wav" || fileExt == "ogg") - { - std::map < string, vector < pair < string, - string > > >::iterator iterFind2 = - loadedFileList.find (duplicateFile); - if (iterFind2 != loadedFileList.end ()) - { - for (unsigned int jdx1 = 0; - jdx1 < iterFind2->second.size (); jdx1++) - { - string - parentFile = iterFind2->second[jdx1].first; - string - searchText = iterFind2->second[jdx1].second; - - if (mapUniqueParentList.find (parentFile) == - mapUniqueParentList.end ()) - { - printf - ("*** Searching parent file:\n[%s]\nfor duplicate file reference:\n[%s]\nto replace with newname:\n[%s]\n", - parentFile.c_str (), searchText.c_str (), - newCommonFileName.c_str ()); - bool - foundText = - searchAndReplaceTextInFile (parentFile, searchText, - newCommonFileName, - false); - printf ("foundText = %d\n", foundText); - if (foundText == false) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Line ref = %d, Error finding text [%s] in file [%s]", - __LINE__, searchText.c_str (), - parentFile.c_str ()); - throw - megaglest_runtime_error (szBuf); - } - mapUniqueParentList[parentFile]++; - } - } - } - } - } - } - else - { - string - newCommonFileName = ""; - for (unsigned int idx = 0; idx < fileList.size (); ++idx) - { - string - duplicateFile = fileList[idx]; - string - fileExt = extractExtension (duplicateFile); - if (fileExt == "wav" || fileExt == "ogg") - { -//off_t fileSize = getFileSize(duplicateFile); - if (idx == 0) - { - newCommonFileName = - "$COMMONDATAPATH/sounds/" + - extractFileFromDirectoryPath (duplicateFile); - break; - } - } - } - - for (unsigned int idx = 0; idx < fileList.size (); ++idx) - { - string - duplicateFile = fileList[idx]; - string - fileExt = extractExtension (duplicateFile); - if (fileExt == "wav" || fileExt == "ogg") - { - std::map < string, vector < pair < string, - string > > >::iterator iterFind4 = - loadedFileList.find (duplicateFile); - if (iterFind4 != loadedFileList.end ()) - { - for (unsigned int jdx = 0; - jdx < iterFind4->second.size (); jdx++) - { - string - parentFile = iterFind4->second[jdx].first; - string - searchText = iterFind4->second[jdx].second; - - bool - foundText = - searchAndReplaceTextInFile (parentFile, searchText, - newCommonFileName, true); - if (foundText == false) - { - - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Line ref = %d, Error finding text\n[%s]\nin file\n[%s]\nnew Common File [%s]\n", - __LINE__, searchText.c_str (), - parentFile.c_str (), - newCommonFileName.c_str ()); - printf - ("\n\n=================================================\n%s", - szBuf); - - throw - megaglest_runtime_error (szBuf); - } - } - } - } - } - } - } - } - if (foundDuplicates == true) - { - printf ("Duplicates %.2f MB (%d) in files\n", duplicateMegaBytes, - duplicateCount); - printf ("Duplicates purged %.2f MB (%d) in files\n", - duplicateMegaBytesPurged, duplicateCountPurged); - - printf ("\nWarning, duplicate files were detected - END:\n"); - } - } - -//if(techtree_errors == false) { - printf - ("\nValidation found NO ERRORS for tilesetPath [%s] tilesetName [%s]:\n", - tilesetPath.c_str (), tilesetName.c_str ()); -//} - - printf - ("----------------------------------------------------------------"); - } - - void - runTechValidationForPath (string techPath, string techName, - const std::vector < string > - &filteredFactionList, World & world, - bool purgeUnusedFiles, bool purgeDuplicateFiles, - bool showDuplicateFiles, bool gitPurgeFiles, - double &purgedMegaBytes) - { - - string - techTreeFolder = techPath + techName; - string - techTreeFactionFolder = techTreeFolder + "/factions/"; - vector < string > factionsList; - findDirs (techTreeFactionFolder, factionsList, false, false); - - if (factionsList.empty () == false) - { - Checksum - checksum; - set < string > factions; - for (int j = 0; j < (int) factionsList.size (); ++j) - { - if (filteredFactionList.empty () == true || - std::find (filteredFactionList.begin (), - filteredFactionList.end (), - factionsList[j]) != filteredFactionList.end ()) - { - factions.insert (factionsList[j]); - } - } - - printf - ("\n----------------------------------------------------------------"); - printf - ("\nChecking techPath [%s] techName [%s] total faction count = %d\n", - techPath.c_str (), techName.c_str (), (int) factionsList.size ()); - for (int j = 0; j < (int) factionsList.size (); ++j) - { - if (filteredFactionList.empty () == true || - std::find (filteredFactionList.begin (), - filteredFactionList.end (), - factionsList[j]) != filteredFactionList.end ()) - { - printf ("Using faction [%s]\n", factionsList[j].c_str ()); - } - } - - if (factions.empty () == false) - { - bool - techtree_errors = false; - - std::map < string, vector < pair < string, - string > > >loadedFileList; - vector < string > pathList; - pathList.push_back (techPath); - Config & config = Config::getInstance (); - vector < string > otherTechPaths = - config.getPathListForType (ptTechs, ""); - pathList.insert (pathList.end (), otherTechPaths.begin (), - otherTechPaths.end ()); - - try - { - world.loadTech (pathList, techName, factions, &checksum, - loadedFileList, true); - -// Fixup paths with .. - { - std::map < string, vector < pair < string, - string > > >newLoadedFileList; - for (std::map < string, vector < pair < string, - string > > >::iterator iterMap = loadedFileList.begin (); - iterMap != loadedFileList.end (); ++iterMap) - { - string - loadedFile = iterMap->first; - - replaceAll (loadedFile, "//", "/"); - replaceAll (loadedFile, "\\\\", "\\"); - updatePathClimbingParts (loadedFile); - - if (newLoadedFileList.find (loadedFile) != - newLoadedFileList.end ()) - { - for (unsigned int xx1 = 0; xx1 < iterMap->second.size (); - ++xx1) - { - pair < string, string > &newVal = iterMap->second[xx1]; - replaceAll (newVal.first, "//", "/"); - replaceAll (newVal.first, "\\\\", "\\"); - updatePathClimbingParts (newVal.first); - replaceAll (newVal.second, "//", "/"); - replaceAll (newVal.second, "\\\\", "\\"); - updatePathClimbingParts (newVal.second); - - newLoadedFileList[loadedFile].push_back (newVal); - } - } - else - { - for (unsigned int xx1 = 0; xx1 < iterMap->second.size (); - ++xx1) - { - pair < string, string > &newVal = iterMap->second[xx1]; - replaceAll (newVal.first, "//", "/"); - replaceAll (newVal.first, "\\\\", "\\"); - updatePathClimbingParts (newVal.first); - replaceAll (newVal.second, "//", "/"); - replaceAll (newVal.second, "\\\\", "\\"); - updatePathClimbingParts (newVal.second); - } - - newLoadedFileList[loadedFile] = iterMap->second; - } - } - loadedFileList = newLoadedFileList; - } - -// Validate the faction setup to ensure we don't have any bad associations - std::vector < std::string > resultErrors = - world.validateFactionTypes (); - if (resultErrors.empty () == false) - { - techtree_errors = true; -// Display the validation errors - string - errorText = - "\nErrors were detected:\n=====================\n"; - for (int i = 0; i < (int) resultErrors.size (); ++i) - { - if (i > 0) - { - errorText += "\n"; - } - errorText = errorText + resultErrors[i]; - } - errorText += "\n=====================\n"; - printf ("%s", errorText.c_str ()); - } - -// Validate the faction resource setup to ensure we don't have any bad associations - printf ("\nChecking resources, count = %d\n", - world.getTechTree ()->getResourceTypeCount ()); - - for (int i = 0; i < world.getTechTree ()->getResourceTypeCount (); - ++i) - { - printf ("Found techtree resource [%s]\n", - world.getTechTree ()->getResourceType (i)->getName (). - c_str ()); - } - - resultErrors = world.validateResourceTypes (); - if (resultErrors.empty () == false) - { - techtree_errors = true; -// Display the validation errors - string - errorText = - "\nErrors were detected:\n=====================\n"; - for (int i = 0; i < (int) resultErrors.size (); ++i) - { - if (i > 0) - { - errorText += "\n"; - } - errorText = errorText + resultErrors[i]; - } - errorText += "\n=====================\n"; - printf ("%s", errorText.c_str ()); - } - -// Now check for unused files in the techtree - std::map < string, vector < pair < string, - string > > >foundFileList; - for (unsigned int i = 0; i < pathList.size (); ++i) - { - string - path = pathList[i]; - endPathWithSlash (path); - path = path + techName + "/"; - - replaceAll (path, "//", "/"); - replaceAll (path, "\\\\", "\\"); - - vector < string > foundFiles = - getFolderTreeContentsListRecursively (path + "*.", ""); - for (unsigned int j = 0; j < foundFiles.size (); ++j) - { - string - file = foundFiles[j]; - replaceAll (file, "//", "/"); - replaceAll (file, "\\\\", "\\"); - -// ignore loading screen, preview screen and hud - if (file.find (GameConstants::LOADING_SCREEN_FILE) != - string::npos - || file.find (GameConstants::PREVIEW_SCREEN_FILE) != - string::npos - || file.find (GameConstants::HUD_SCREEN_FILE) != - string::npos) - { - continue; - } - -// ignore commondata since we are not loading all factions - if (filteredFactionList.size () > 0) - { - if (file.find ("/commondata/") != string::npos) - { - continue; - } - } - - if (file.find ("/factions/") != string::npos) - { - bool - includeFaction = false; - for (set < string >::iterator it = factions.begin (); - it != factions.end (); ++it) - { - string - currentFaction = *it; - if (file.find ("/factions/" + currentFaction) != - string::npos) - { - includeFaction = true; - break; - } - } - if (includeFaction == false) - { - continue; - } - } - - replaceAll (file, "//", "/"); - replaceAll (file, "\\\\", "\\"); - - foundFileList[file].push_back (make_pair (path, path)); - } - } - - printf ("Found techtree filecount = " MG_SIZE_T_SPECIFIER - ", used = " MG_SIZE_T_SPECIFIER "\n", - foundFileList.size (), loadedFileList.size ()); - - int - purgeCount = 0; - bool - foundUnusedFile = false; - for (std::map < string, vector < pair < string, - string > > >::iterator iterMap = foundFileList.begin (); - iterMap != foundFileList.end (); ++iterMap) - { - string - foundFile = iterMap->first; - replaceAll (foundFile, "//", "/"); - replaceAll (foundFile, "\\\\", "\\"); - - if (loadedFileList.find (foundFile) == loadedFileList.end () && - foundFile.find ("lang/") == foundFile.npos) - { - if (foundUnusedFile == false) - { - printf - ("\nLine ref: %d, Warning, unused files were detected - START:\n=====================\n", - __LINE__); - } - foundUnusedFile = true; - - printf ("[%s]\n", foundFile.c_str ()); - - string - fileName = extractFileFromDirectoryPath (foundFile); - if (loadedFileList.find (fileName) != loadedFileList.end ()) - { - printf ("possible match on [%s] ?\n", - loadedFileList.find (fileName)->first.c_str ()); - } - else if (purgeUnusedFiles == true) - { - off_t - fileSize = getFileSize (foundFile); -// convert to MB - purgedMegaBytes += ((double) fileSize / 1048576.0); - purgeCount++; - - if (gitPurgeFiles == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "git rm \"%s\"", - foundFile.c_str ()); - bool - gitOk = executeShellCommand (szBuf, 0); - if (gitOk == false) - { - throw - megaglest_runtime_error ("Call to command failed [" + - string (szBuf) + "]"); - } - } - else - { - removeFile (foundFile); - } - } - } - } - if (foundUnusedFile == true) - { - if (purgedMegaBytes > 0) - { - printf ("Purged %.2f MB (%d) in files\n", purgedMegaBytes, - purgeCount); - } - printf - ("\nLine ref: %d, Warning, unused files were detected - END:\n", - __LINE__); - } - - if (showDuplicateFiles == true) - { - std::map < uint32, vector < string > >mapDuplicateFiles; -// Now check for duplicate data content - for (std::map < string, vector < pair < string, - string > > >::iterator iterMap = loadedFileList.begin (); - iterMap != loadedFileList.end (); ++iterMap) - { - string - fileName = iterMap->first; - Checksum - checksum; - checksum.addFile (fileName); - uint32 - crcValue = checksum.getSum (); - if (crcValue == 0) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Error calculating CRC for file [%s]", - fileName.c_str ()); - throw - megaglest_runtime_error (szBuf); - } - mapDuplicateFiles[crcValue].push_back (fileName); - } - - double - duplicateMegaBytesPurged = 0; - int - duplicateCountPurged = 0; - - double - duplicateMegaBytes = 0; - int - duplicateCount = 0; - - bool - foundDuplicates = false; - for (std::map < uint32, vector < string > >::iterator iterMap = - mapDuplicateFiles.begin (); - iterMap != mapDuplicateFiles.end (); ++iterMap) - { - vector < string > &fileList = iterMap->second; - if (fileList.size () > 1) - { - if (foundDuplicates == false) - { - foundDuplicates = true; - printf - ("\nWarning, duplicate files were detected - START:\n=====================\n"); - } - - printf ("----- START duplicate files for CRC [%u] count [" - MG_SIZE_T_SPECIFIER "] first file is [%s]\n", - iterMap->first, fileList.size (), - fileList[0].c_str ()); - - map < string, int > - parentList; - for (unsigned int idx = 0; idx < fileList.size (); ++idx) - { - string - duplicateFile = fileList[idx]; - if (idx > 0) - { - off_t - fileSize = getFileSize (duplicateFile); -// convert to MB - duplicateMegaBytes += ((double) fileSize / 1048576.0); - duplicateCount++; - } - else - { - printf ("\n"); - } - - printf ("[%s]\n", duplicateFile.c_str ()); - std::map < string, vector < pair < string, - string > > >::iterator iterFind = - loadedFileList.find (duplicateFile); - if (iterFind != loadedFileList.end ()) - { - for (unsigned int jdx = 0; - jdx < iterFind->second.size (); jdx++) - { - parentList[iterFind->second[jdx].first]++; - } - } - - string - newCommonFileName = - "$COMMONDATAPATH/sounds/" + - extractFileFromDirectoryPath (duplicateFile); - string - expandedNewCommonFileName = newCommonFileName; - std::map < string, string > mapExtraTagReplacementValues; - string - techCommonData = techPath + techName + "/commondata/"; - replaceAll (techCommonData, "//", "/"); - mapExtraTagReplacementValues["$COMMONDATAPATH"] = - techCommonData; - mapExtraTagReplacementValues = - Properties::getTagReplacementValues - (&mapExtraTagReplacementValues); - Properties::applyTagsToValue (expandedNewCommonFileName, - &mapExtraTagReplacementValues); - replaceAll (expandedNewCommonFileName, "//", "/"); - } - - printf ("----- Finding parents for duplicate files [" - MG_SIZE_T_SPECIFIER "] first file is [%s]\n", - fileList.size (), fileList[0].c_str ()); - - for (map < string, int >::iterator iterMap1 = - parentList.begin (); iterMap1 != parentList.end (); - ++iterMap1) - { - - if (iterMap1 == parentList.begin ()) - { - printf ("\tParents:\n"); - } - printf ("\t[%s]\n", iterMap1->first.c_str ()); - } - - if (purgeDuplicateFiles == true) - { - - printf ("----- move / remove duplicate files [" - MG_SIZE_T_SPECIFIER "] first file is [%s]\n", - fileList.size (), fileList[0].c_str ()); -// First move first duplicate to commondata and delete all other copies - string - newCommonFileName = ""; - for (unsigned int idx = 0; idx < fileList.size (); ++idx) - { - string - duplicateFile = fileList[idx]; - string - fileExt = extractExtension (duplicateFile); - if (fileExt == "wav" || fileExt == "ogg") - { - off_t - fileSize = getFileSize (duplicateFile); - - printf ("#1 [%u / " MG_SIZE_T_SPECIFIER - "] removing duplicate [%s]\n", idx, - fileList.size (), duplicateFile.c_str ()); - - if (idx == 0) - { - newCommonFileName = - "$COMMONDATAPATH/sounds/" + - extractFileFromDirectoryPath (duplicateFile); - - string - expandedNewCommonFileName = newCommonFileName; - - std::map < string, - string > mapExtraTagReplacementValues; - - string - techCommonData = - techPath + techName + "/commondata/"; - replaceAll (techCommonData, "//", "/"); - - mapExtraTagReplacementValues["$COMMONDATAPATH"] = - techCommonData; - mapExtraTagReplacementValues = - Properties::getTagReplacementValues - (&mapExtraTagReplacementValues); - Properties::applyTagsToValue - (expandedNewCommonFileName, - &mapExtraTagReplacementValues); - replaceAll (expandedNewCommonFileName, "//", "/"); - createDirectoryPaths (extractDirectoryPathFromFile - (expandedNewCommonFileName)); - - if (gitPurgeFiles == true) - { - copyFileTo (duplicateFile, - expandedNewCommonFileName); - - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "git rm \"%s\"", - duplicateFile.c_str ()); - bool - gitOk = executeShellCommand (szBuf, 0); - if (gitOk == false) - { - throw - megaglest_runtime_error - ("Call to command failed [" + string (szBuf) + - "]"); - } - printf - ("*** Duplicate file:\n[%s]\nwas git rm and copied to:\n[%s]\n", - duplicateFile.c_str (), - expandedNewCommonFileName.c_str ()); - } - else - { - printf - ("moving duplicate [%s] to common data [%s] expanded to [%s]\n", - duplicateFile.c_str (), - newCommonFileName.c_str (), - expandedNewCommonFileName.c_str ()); - - int - result = rename (duplicateFile.c_str (), - expandedNewCommonFileName.c_str - ()); - if (result != 0) - { - char - szBuf[8096] = ""; - char * - errmsg = strerror (errno); - snprintf (szBuf, 8096, - "!!! Error [%s] Could not rename [%s] to [%s]!", - errmsg, duplicateFile.c_str (), - expandedNewCommonFileName.c_str ()); - throw - megaglest_runtime_error (szBuf); - } - else - { - printf - ("*** Duplicate file:\n[%s]\nwas renamed to:\n[%s]\n", - duplicateFile.c_str (), - expandedNewCommonFileName.c_str ()); - } - } - } - else - { - if (gitPurgeFiles == true) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "git rm \"%s\"", - duplicateFile.c_str ()); - bool - gitOk = executeShellCommand (szBuf, 0); - if (gitOk == false) - { - throw - megaglest_runtime_error - ("Call to command failed [" + string (szBuf) + - "]"); - } - printf ("*** Duplicate file:\n[%s]\nwas git rm\n", - duplicateFile.c_str ()); - } - else - { - printf ("removing duplicate [%s]\n", - duplicateFile.c_str ()); - removeFile (duplicateFile); - } - printf ("*** Duplicate file:\n[%s]\nwas removed\n", - duplicateFile.c_str ()); - -// convert to MB - duplicateMegaBytesPurged += - ((double) fileSize / 1048576.0); - duplicateCountPurged++; - } - } - } - - printf ("----- update XML files for duplicate files [" - MG_SIZE_T_SPECIFIER "] first file is [%s]\n", - fileList.size (), fileList[0].c_str ()); - std::map < string, int > - mapUniqueParentList; - -// Update the XML files to point to the new single copy in commondata - for (unsigned int idx = 0; idx < fileList.size (); ++idx) - { - string - duplicateFile = fileList[idx]; - string - fileExt = extractExtension (duplicateFile); - if (fileExt == "wav" || fileExt == "ogg") - { - std::map < string, vector < pair < string, - string > > >::iterator iterFind2 = - loadedFileList.find (duplicateFile); - if (iterFind2 != loadedFileList.end ()) - { - for (unsigned int jdx1 = 0; - jdx1 < iterFind2->second.size (); jdx1++) - { - string - parentFile = iterFind2->second[jdx1].first; - string - searchText = iterFind2->second[jdx1].second; - - if (mapUniqueParentList.find (parentFile) == - mapUniqueParentList.end ()) - { - printf - ("*** Searching parent file:\n[%s]\nfor duplicate file reference:\n[%s]\nto replace with newname:\n[%s]\n", - parentFile.c_str (), searchText.c_str (), - newCommonFileName.c_str ()); - bool - foundText = - searchAndReplaceTextInFile (parentFile, - searchText, - newCommonFileName, - false); - printf ("foundText = %d\n", foundText); - if (foundText == false) - { - - string - techCommonData = - techPath + techName + "/commondata/"; - replaceAll (techCommonData, "//", "/"); - - if (StartsWith (searchText, techCommonData) == - true) - { - printf - ("WARNING #1 [%d] techCommonData check\n[%s]\n[%s]\n[%s]\n[%s]\n", - foundText, parentFile.c_str (), - techCommonData.c_str (), - searchText.c_str (), - newCommonFileName.c_str ()); - - replaceAll (searchText, techCommonData, - "$COMMONDATAPATH/"); - foundText = - searchAndReplaceTextInFile (parentFile, - searchText, - newCommonFileName, - false); - - printf - ("WARNING #2 [%d] techCommonData check\n[%s]\n[%s]\n[%s]\n[%s]\n", - foundText, parentFile.c_str (), - techCommonData.c_str (), - searchText.c_str (), - newCommonFileName.c_str ()); - } - if (foundText == false) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Line ref = %d, Error finding text\n[%s]\nin file\n[%s]\nnew Common File [%s]\n", - __LINE__, searchText.c_str (), - parentFile.c_str (), - newCommonFileName.c_str ()); - printf - ("\n\n=================================================\n%s", - szBuf); - - throw - megaglest_runtime_error (szBuf); - } - } - mapUniqueParentList[parentFile]++; - } - } - } - } - } - } - else - { - - string - newCommonFileName = ""; - for (unsigned int idx = 0; idx < fileList.size (); ++idx) - { - string - duplicateFile = fileList[idx]; - string - fileExt = extractExtension (duplicateFile); - if (fileExt == "wav" || fileExt == "ogg") - { -//off_t fileSize = getFileSize(duplicateFile); - if (idx == 0) - { - newCommonFileName = - "$COMMONDATAPATH/sounds/" + - extractFileFromDirectoryPath (duplicateFile); - break; - } - } - } - - for (unsigned int idx = 0; idx < fileList.size (); ++idx) - { - string - duplicateFile = fileList[idx]; - string - fileExt = extractExtension (duplicateFile); - if (fileExt == "wav" || fileExt == "ogg") - { - std::map < string, vector < pair < string, - string > > >::iterator iterFind4 = - loadedFileList.find (duplicateFile); - if (iterFind4 != loadedFileList.end ()) - { - for (unsigned int jdx = 0; - jdx < iterFind4->second.size (); jdx++) - { - string - parentFile = iterFind4->second[jdx].first; - string - searchText = iterFind4->second[jdx].second; - - bool - foundText = - searchAndReplaceTextInFile (parentFile, - searchText, - newCommonFileName, - true); - - if (foundText == false) - { - string - techCommonData = - techPath + techName + "/commondata/"; - replaceAll (techCommonData, "//", "/"); - - if (StartsWith (searchText, techCommonData) == - true) - { - replaceAll (searchText, techCommonData, - "$COMMONDATAPATH/"); - foundText = - searchAndReplaceTextInFile (parentFile, - searchText, - newCommonFileName, - true); - - } - if (foundText == false) - { - -// Check if the sound file already references commandata - foundText = - searchAndReplaceTextInFile (parentFile, - newCommonFileName, - newCommonFileName, - true); - if (foundText == false) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Line ref = %d, Error finding text\n[%s]\nin file\n[%s]\nnew Common File [%s]\n", - __LINE__, searchText.c_str (), - parentFile.c_str (), - newCommonFileName.c_str ()); - printf - ("\n\n=================================================\n%s", - szBuf); - - throw - megaglest_runtime_error (szBuf); - } - } - } - } - } - } - } - } - - - printf ("----- END duplicate files [" MG_SIZE_T_SPECIFIER - "] first file is [%s]\n", fileList.size (), - fileList[0].c_str ()); - } - } - if (foundDuplicates == true) - { - printf ("Duplicates %.2f MB (%d) in files\n", - duplicateMegaBytes, duplicateCount); - printf ("Duplicates purged %.2f MB (%d) in files\n", - duplicateMegaBytesPurged, duplicateCountPurged); - - printf ("\nWarning, duplicate files were detected - END:\n"); - } - } - } - catch (const megaglest_runtime_error & ex) - { - techtree_errors = true; - printf - ("\n\n****ERROR**** detected while validating the techName: %s\nMESSAGE: %s\n", - techName.c_str (), ex.what ()); - } - - if (techtree_errors == false) - { - printf - ("\nValidation found NO ERRORS for techPath [%s] techName [%s] factions checked (count = %d):\n", - techPath.c_str (), techName.c_str (), (int) factions.size ()); - for (set < string >::iterator it = factions.begin (); - it != factions.end (); ++it) - { - printf ("Faction [%s]\n", (*it).c_str ()); - } - } - } - printf - ("----------------------------------------------------------------"); - } - else if (folderExists (techTreeFolder) == true) - { - printf - ("\nWarning, No factions were found for the techtree located in: [%s]\n", - techTreeFolder.c_str ()); - } - } - - - void - runTechTranslationExtractionForPath (string techPath, string techName, - const std::vector < string > - &filteredFactionList, World & world) - { - vector < string > factionsList; - findDirs (techPath + techName + "/factions/", factionsList, false, - false); - - if (factionsList.empty () == false) - { - Checksum - checksum; - set < string > factions; - for (int j = 0; j < (int) factionsList.size (); ++j) - { - if (filteredFactionList.empty () == true || - std::find (filteredFactionList.begin (), - filteredFactionList.end (), - factionsList[j]) != filteredFactionList.end ()) - { - factions.insert (factionsList[j]); - } - } - - printf - ("\n----------------------------------------------------------------"); - printf - ("\nChecking techPath [%s] techName [%s] total faction count = %d\n", - techPath.c_str (), techName.c_str (), (int) factionsList.size ()); - for (int j = 0; j < (int) factionsList.size (); ++j) - { - if (filteredFactionList.empty () == true || - std::find (filteredFactionList.begin (), - filteredFactionList.end (), - factionsList[j]) != filteredFactionList.end ()) - { - printf ("Using faction [%s]\n", factionsList[j].c_str ()); - } - } - - if (factions.empty () == false) - { - std::map < string, vector < pair < string, - string > > >loadedFileList; - vector < string > pathList; - pathList.push_back (techPath); - Config & config = Config::getInstance (); - vector < string > otherTechPaths = - config.getPathListForType (ptTechs, ""); - pathList.insert (pathList.end (), otherTechPaths.begin (), - otherTechPaths.end ()); - - try - { - world.loadTech (pathList, techName, factions, &checksum, - loadedFileList, true); - - const TechTree * - techtree = world.getTechTree (); - string - translationFile = techtree->getPath (); - endPathWithSlash (translationFile); - translationFile += "lang/" + techName + "_default.lng"; - if (fileExists (translationFile) == false) - { - string - txFilePath = extractDirectoryPathFromFile (translationFile); - createDirectoryPaths (txFilePath); + string + debugLogFile = config.getString("DebugLogFile", ""); + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != + "") { + debugLogFile = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + debugLogFile; + } else { + debugLogFile = userData + debugLogFile; + } + + string + debugWorldSynchLogFile = + config.getString("DebugLogFileWorldSynch", ""); + if (debugWorldSynchLogFile == "") { + debugWorldSynchLogFile = debugLogFile; + } else if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + != "") { + debugWorldSynchLogFile = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + debugWorldSynchLogFile; + } else { + debugWorldSynchLogFile = userData + debugWorldSynchLogFile; + } + + string + debugPerformanceLogFile = + config.getString("DebugLogFilePerformance", ""); + if (debugPerformanceLogFile == "") { + debugPerformanceLogFile = debugLogFile; + } else if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + != "") { + debugPerformanceLogFile = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + debugPerformanceLogFile; + } else { + debugPerformanceLogFile = userData + debugPerformanceLogFile; + } + + string + debugNetworkLogFile = config.getString("DebugLogFileNetwork", ""); + if (debugNetworkLogFile == "") { + debugNetworkLogFile = debugLogFile; + } else if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + != "") { + debugNetworkLogFile = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + debugNetworkLogFile; + } else { + debugNetworkLogFile = userData + debugNetworkLogFile; + } + + string + debugUnitCommandsLogFile = + config.getString("DebugLogFileUnitCommands", ""); + if (debugUnitCommandsLogFile == "") { + debugUnitCommandsLogFile = debugLogFile; + } else if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + != "") { + debugUnitCommandsLogFile = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + debugUnitCommandsLogFile; + } else { + debugUnitCommandsLogFile = userData + debugUnitCommandsLogFile; + } + + string + debugPathFinderLogFile = + config.getString("DebugLogFilePathFinder", ""); + if (debugPathFinderLogFile == "") { + debugPathFinderLogFile = debugLogFile; + } else if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + != "") { + debugPathFinderLogFile = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + debugPathFinderLogFile; + } else { + debugPathFinderLogFile = userData + debugPathFinderLogFile; + } + + string + debugLUALogFile = config.getString("DebugLogFileLUA", ""); + if (debugLUALogFile == "") { + debugLUALogFile = debugLogFile; + } else if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + != "") { + debugLUALogFile = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + debugLUALogFile; + } else { + debugLUALogFile = userData + debugLUALogFile; + } + + string + debugSoundLogFile = config.getString("DebugLogFileSound", ""); + if (debugSoundLogFile == "") { + debugSoundLogFile = debugLogFile; + } else if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + != "") { + debugSoundLogFile = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + debugSoundLogFile; + } else { + debugSoundLogFile = userData + debugSoundLogFile; + } + + string + debugErrorLogFile = config.getString("DebugLogFileError", ""); + + SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + debugLogFileName = debugLogFile; + SystemFlags::getSystemSettingType(SystemFlags::debugNetwork). + debugLogFileName = debugNetworkLogFile; + SystemFlags::getSystemSettingType(SystemFlags::debugPerformance). + debugLogFileName = debugPerformanceLogFile; + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch). + debugLogFileName = debugWorldSynchLogFile; + SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands). + debugLogFileName = debugUnitCommandsLogFile; + SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder). + debugLogFileName = debugPathFinderLogFile; + SystemFlags::getSystemSettingType(SystemFlags::debugLUA). + debugLogFileName = debugLUALogFile; + SystemFlags::getSystemSettingType(SystemFlags::debugSound). + debugLogFileName = debugSoundLogFile; + SystemFlags::getSystemSettingType(SystemFlags::debugError). + debugLogFileName = debugErrorLogFile; + + if (haveSpecialOutputCommandLineOption == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("--- Startup log settings are ---\ndebugSystem [%d][%s]\ndebugNetwork [%d][%s]\ndebugPerformance [%d][%s]\ndebugWorldSynch [%d][%s]\ndebugUnitCommands[%d][%s]\ndebugPathFinder[%d][%s]\ndebugLUA [%d][%s]\ndebugSound [%d][%s]\ndebugError [%d][%s]\n", + SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled, debugLogFile.c_str(), + SystemFlags::getSystemSettingType(SystemFlags::debugNetwork). + enabled, debugNetworkLogFile.c_str(), + SystemFlags::getSystemSettingType(SystemFlags:: + debugPerformance).enabled, + debugPerformanceLogFile.c_str(), + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch). + enabled, debugWorldSynchLogFile.c_str(), + SystemFlags::getSystemSettingType(SystemFlags:: + debugUnitCommands).enabled, + debugUnitCommandsLogFile.c_str(), + SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder). + enabled, debugPathFinderLogFile.c_str(), + SystemFlags::getSystemSettingType(SystemFlags::debugLUA). + enabled, debugLUALogFile.c_str(), + SystemFlags::getSystemSettingType(SystemFlags::debugSound). + enabled, debugSoundLogFile.c_str(), + SystemFlags::getSystemSettingType(SystemFlags::debugError). + enabled, debugErrorLogFile.c_str()); + } + } + + void + runTilesetValidationForPath(string tilesetPath, string tilesetName, + World & world, bool purgeUnusedFiles, + bool purgeDuplicateFiles, + bool showDuplicateFiles, bool gitPurgeFiles, + double &purgedMegaBytes) { + Checksum + checksum; + + //bool techtree_errors = false; + + std::map < string, vector < pair < string, string > > >loadedFileList; + vector < string > pathList; + pathList.push_back(tilesetPath); + world.loadTileset(pathList, tilesetName, &checksum, loadedFileList); + + // Fixup paths with .. + { + std::map < string, vector < pair < string, + string > > >newLoadedFileList; + for (std::map < string, vector < pair < string, + string > > >::iterator iterMap = loadedFileList.begin(); + iterMap != loadedFileList.end(); ++iterMap) { + string + loadedFile = iterMap->first; + + replaceAll(loadedFile, "//", "/"); + replaceAll(loadedFile, "\\\\", "\\"); + updatePathClimbingParts(loadedFile); + + if (newLoadedFileList.find(loadedFile) != newLoadedFileList.end()) { + for (unsigned int xx1 = 0; xx1 < iterMap->second.size(); ++xx1) { + pair < string, string > &newVal = iterMap->second[xx1]; + replaceAll(newVal.first, "//", "/"); + replaceAll(newVal.first, "\\\\", "\\"); + updatePathClimbingParts(newVal.first); + replaceAll(newVal.second, "//", "/"); + replaceAll(newVal.second, "\\\\", "\\"); + updatePathClimbingParts(newVal.second); + + newLoadedFileList[loadedFile].push_back(newVal); + } + } else { + for (unsigned int xx1 = 0; xx1 < iterMap->second.size(); ++xx1) { + pair < string, string > &newVal = iterMap->second[xx1]; + replaceAll(newVal.first, "//", "/"); + replaceAll(newVal.first, "\\\\", "\\"); + updatePathClimbingParts(newVal.first); + replaceAll(newVal.second, "//", "/"); + replaceAll(newVal.second, "\\\\", "\\"); + updatePathClimbingParts(newVal.second); + } + + newLoadedFileList[loadedFile] = iterMap->second; + } + } + loadedFileList = newLoadedFileList; + } + + // Validate the faction setup to ensure we don't have any bad associations + // std::vector resultErrors = world.validateFactionTypes(); + + // Now check for unused files in the techtree + std::map < string, vector < pair < string, string > > >foundFileList; + for (unsigned int i = 0; i < pathList.size(); ++i) { + string + path = pathList[i]; + endPathWithSlash(path); + path = path + tilesetName + "/"; + + replaceAll(path, "//", "/"); + replaceAll(path, "\\\\", "\\"); + + vector < string > foundFiles = + getFolderTreeContentsListRecursively(path + "*.", ""); + for (unsigned int j = 0; j < foundFiles.size(); ++j) { + string + file = foundFiles[j]; + replaceAll(file, "//", "/"); + replaceAll(file, "\\\\", "\\"); + + replaceAll(file, "//", "/"); + replaceAll(file, "\\\\", "\\"); + + foundFileList[file].push_back(make_pair(path, path)); + } + } + + printf("Found tileset filecount = " MG_SIZE_T_SPECIFIER ", used = " + MG_SIZE_T_SPECIFIER "\n", foundFileList.size(), + loadedFileList.size()); + + int + purgeCount = 0; + bool + foundUnusedFile = false; + for (std::map < string, vector < pair < string, + string > > >::iterator iterMap = foundFileList.begin(); + iterMap != foundFileList.end(); ++iterMap) { + string + foundFile = iterMap->first; + replaceAll(foundFile, "//", "/"); + replaceAll(foundFile, "\\\\", "\\"); + + if (loadedFileList.find(foundFile) == loadedFileList.end() && + foundFile.find("lang/") == foundFile.npos) { + if (foundUnusedFile == false) { + printf + ("\nLine ref: %d, Warning, unused files were detected - START:\n=====================\n", + __LINE__); + } + foundUnusedFile = true; + + printf("[%s]\n", foundFile.c_str()); + + string + fileName = extractFileFromDirectoryPath(foundFile); + if (loadedFileList.find(fileName) != loadedFileList.end()) { + printf("possible match on [%s] ?\n", + loadedFileList.find(fileName)->first.c_str()); + } else if (purgeUnusedFiles == true) { + off_t + fileSize = getFileSize(foundFile); + // convert to MB + purgedMegaBytes += ((double) fileSize / 1048576.0); + purgeCount++; + + if (gitPurgeFiles == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "git rm \"%s\"", foundFile.c_str()); + bool + gitOk = executeShellCommand(szBuf, 0); + if (gitOk == false) { + throw + megaglest_runtime_error("Call to command failed [" + + string(szBuf) + "]"); + } + } else { + removeFile(foundFile); + } + } + } + } + if (foundUnusedFile == true) { + if (purgedMegaBytes > 0) { + printf("Purged %.2f MB (%d) in files\n", purgedMegaBytes, + purgeCount); + } + printf + ("\nLine ref: %d, Warning, unused files were detected - END:\n", + __LINE__); + } + + if (showDuplicateFiles == true) { + std::map < uint32, vector < string > >mapDuplicateFiles; + // Now check for duplicate data content + for (std::map < string, vector < pair < string, + string > > >::iterator iterMap = loadedFileList.begin(); + iterMap != loadedFileList.end(); ++iterMap) { + string + fileName = iterMap->first; + Checksum + checksum; + checksum.addFile(fileName); + uint32 + crcValue = checksum.getSum(); + mapDuplicateFiles[crcValue].push_back(fileName); + } + + double + duplicateMegaBytesPurged = 0; + int + duplicateCountPurged = 0; + + double + duplicateMegaBytes = 0; + int + duplicateCount = 0; + + bool + foundDuplicates = false; + for (std::map < uint32, vector < string > >::iterator iterMap = + mapDuplicateFiles.begin(); iterMap != mapDuplicateFiles.end(); + ++iterMap) { + vector < string > &fileList = iterMap->second; + if (fileList.size() > 1) { + if (foundDuplicates == false) { + foundDuplicates = true; + printf + ("\nWarning, duplicate files were detected - START:\n=====================\n"); + } + + map < string, int > + parentList; + for (unsigned int idx = 0; idx < fileList.size(); ++idx) { + string + duplicateFile = fileList[idx]; + if (idx > 0) { + off_t + fileSize = getFileSize(duplicateFile); + // convert to MB + duplicateMegaBytes += ((double) fileSize / 1048576.0); + duplicateCount++; + } else { + printf("\n"); + } + + printf("[%s]\n", duplicateFile.c_str()); + std::map < string, vector < pair < string, + string > > >::iterator iterFind = + loadedFileList.find(duplicateFile); + if (iterFind != loadedFileList.end()) { + for (unsigned int jdx = 0; jdx < iterFind->second.size(); + jdx++) { + parentList[iterFind->second[jdx].first]++; + } + } + } + + for (map < string, int >::iterator iterMap1 = parentList.begin(); + iterMap1 != parentList.end(); ++iterMap1) { + + if (iterMap1 == parentList.begin()) { + printf("\tParents:\n"); + } + printf("\t[%s]\n", iterMap1->first.c_str()); + } + + if (purgeDuplicateFiles == true) { + + string + newCommonFileName = ""; + for (unsigned int idx = 0; idx < fileList.size(); ++idx) { + string + duplicateFile = fileList[idx]; + string + fileExt = extractExtension(duplicateFile); + if (fileExt == "wav" || fileExt == "ogg") { + off_t + fileSize = getFileSize(duplicateFile); + if (idx == 0) { + newCommonFileName = + "$COMMONDATAPATH/sounds/" + + extractFileFromDirectoryPath(duplicateFile); + + string + expandedNewCommonFileName = newCommonFileName; + + std::map < string, string > mapExtraTagReplacementValues; + + mapExtraTagReplacementValues = + Properties::getTagReplacementValues + (&mapExtraTagReplacementValues); + Properties::applyTagsToValue(expandedNewCommonFileName, + &mapExtraTagReplacementValues); + replaceAll(expandedNewCommonFileName, "//", "/"); + createDirectoryPaths(extractDirectoryPathFromFile + (expandedNewCommonFileName)); + + if (gitPurgeFiles == true) { + copyFileTo(duplicateFile, expandedNewCommonFileName); + + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "git rm \"%s\"", + duplicateFile.c_str()); + bool + gitOk = executeShellCommand(szBuf, 0); + if (gitOk == false) { + throw + megaglest_runtime_error("Call to command failed [" + + string(szBuf) + "]"); + } + printf + ("*** Duplicate file:\n[%s]\nwas git rm and copied to:\n[%s]\n", + duplicateFile.c_str(), + expandedNewCommonFileName.c_str()); + } else { + //int result = 0; + int + result = rename(duplicateFile.c_str(), + expandedNewCommonFileName.c_str()); + if (result != 0) { + char + szBuf[8096] = ""; + char * + errmsg = strerror(errno); + snprintf(szBuf, 8096, + "!!! Error [%s] Could not rename [%s] to [%s]!", + errmsg, duplicateFile.c_str(), + expandedNewCommonFileName.c_str()); + throw + megaglest_runtime_error(szBuf); + } else { + printf + ("*** Duplicate file:\n[%s]\nwas renamed to:\n[%s]\n", + duplicateFile.c_str(), + expandedNewCommonFileName.c_str()); + } + } + } else { + if (gitPurgeFiles == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "git rm \"%s\"", + duplicateFile.c_str()); + bool + gitOk = executeShellCommand(szBuf, 0); + if (gitOk == false) { + throw + megaglest_runtime_error("Call to command failed [" + + string(szBuf) + "]"); + } + printf("*** Duplicate file:\n[%s]\nwas git rm\n", + duplicateFile.c_str()); + } else { + removeFile(duplicateFile); + } + printf("*** Duplicate file:\n[%s]\nwas removed\n", + duplicateFile.c_str()); + + // convert to MB + duplicateMegaBytesPurged += + ((double) fileSize / 1048576.0); + duplicateCountPurged++; + } + } + } + + std::map < string, int > + mapUniqueParentList; + + for (unsigned int idx = 0; idx < fileList.size(); ++idx) { + string + duplicateFile = fileList[idx]; + string + fileExt = extractExtension(duplicateFile); + if (fileExt == "wav" || fileExt == "ogg") { + std::map < string, vector < pair < string, + string > > >::iterator iterFind2 = + loadedFileList.find(duplicateFile); + if (iterFind2 != loadedFileList.end()) { + for (unsigned int jdx1 = 0; + jdx1 < iterFind2->second.size(); jdx1++) { + string + parentFile = iterFind2->second[jdx1].first; + string + searchText = iterFind2->second[jdx1].second; + + if (mapUniqueParentList.find(parentFile) == + mapUniqueParentList.end()) { + printf + ("*** Searching parent file:\n[%s]\nfor duplicate file reference:\n[%s]\nto replace with newname:\n[%s]\n", + parentFile.c_str(), searchText.c_str(), + newCommonFileName.c_str()); + bool + foundText = + searchAndReplaceTextInFile(parentFile, searchText, + newCommonFileName, + false); + printf("foundText = %d\n", foundText); + if (foundText == false) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Line ref = %d, Error finding text [%s] in file [%s]", + __LINE__, searchText.c_str(), + parentFile.c_str()); + throw + megaglest_runtime_error(szBuf); + } + mapUniqueParentList[parentFile]++; + } + } + } + } + } + } else { + string + newCommonFileName = ""; + for (unsigned int idx = 0; idx < fileList.size(); ++idx) { + string + duplicateFile = fileList[idx]; + string + fileExt = extractExtension(duplicateFile); + if (fileExt == "wav" || fileExt == "ogg") { + //off_t fileSize = getFileSize(duplicateFile); + if (idx == 0) { + newCommonFileName = + "$COMMONDATAPATH/sounds/" + + extractFileFromDirectoryPath(duplicateFile); + break; + } + } + } + + for (unsigned int idx = 0; idx < fileList.size(); ++idx) { + string + duplicateFile = fileList[idx]; + string + fileExt = extractExtension(duplicateFile); + if (fileExt == "wav" || fileExt == "ogg") { + std::map < string, vector < pair < string, + string > > >::iterator iterFind4 = + loadedFileList.find(duplicateFile); + if (iterFind4 != loadedFileList.end()) { + for (unsigned int jdx = 0; + jdx < iterFind4->second.size(); jdx++) { + string + parentFile = iterFind4->second[jdx].first; + string + searchText = iterFind4->second[jdx].second; + + bool + foundText = + searchAndReplaceTextInFile(parentFile, searchText, + newCommonFileName, true); + if (foundText == false) { + + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Line ref = %d, Error finding text\n[%s]\nin file\n[%s]\nnew Common File [%s]\n", + __LINE__, searchText.c_str(), + parentFile.c_str(), + newCommonFileName.c_str()); + printf + ("\n\n=================================================\n%s", + szBuf); + + throw + megaglest_runtime_error(szBuf); + } + } + } + } + } + } + } + } + if (foundDuplicates == true) { + printf("Duplicates %.2f MB (%d) in files\n", duplicateMegaBytes, + duplicateCount); + printf("Duplicates purged %.2f MB (%d) in files\n", + duplicateMegaBytesPurged, duplicateCountPurged); + + printf("\nWarning, duplicate files were detected - END:\n"); + } + } + + //if(techtree_errors == false) { + printf + ("\nValidation found NO ERRORS for tilesetPath [%s] tilesetName [%s]:\n", + tilesetPath.c_str(), tilesetName.c_str()); + //} + + printf + ("----------------------------------------------------------------"); + } + + void + runTechValidationForPath(string techPath, string techName, + const std::vector < string > + &filteredFactionList, World & world, + bool purgeUnusedFiles, bool purgeDuplicateFiles, + bool showDuplicateFiles, bool gitPurgeFiles, + double &purgedMegaBytes) { + + string + techTreeFolder = techPath + techName; + string + techTreeFactionFolder = techTreeFolder + "/factions/"; + vector < string > factionsList; + findDirs(techTreeFactionFolder, factionsList, false, false); + + if (factionsList.empty() == false) { + Checksum + checksum; + set < string > factions; + for (int j = 0; j < (int) factionsList.size(); ++j) { + if (filteredFactionList.empty() == true || + std::find(filteredFactionList.begin(), + filteredFactionList.end(), + factionsList[j]) != filteredFactionList.end()) { + factions.insert(factionsList[j]); + } + } + + printf + ("\n----------------------------------------------------------------"); + printf + ("\nChecking techPath [%s] techName [%s] total faction count = %d\n", + techPath.c_str(), techName.c_str(), (int) factionsList.size()); + for (int j = 0; j < (int) factionsList.size(); ++j) { + if (filteredFactionList.empty() == true || + std::find(filteredFactionList.begin(), + filteredFactionList.end(), + factionsList[j]) != filteredFactionList.end()) { + printf("Using faction [%s]\n", factionsList[j].c_str()); + } + } + + if (factions.empty() == false) { + bool + techtree_errors = false; + + std::map < string, vector < pair < string, + string > > >loadedFileList; + vector < string > pathList; + pathList.push_back(techPath); + Config & config = Config::getInstance(); + vector < string > otherTechPaths = + config.getPathListForType(ptTechs, ""); + pathList.insert(pathList.end(), otherTechPaths.begin(), + otherTechPaths.end()); + + try { + world.loadTech(pathList, techName, factions, &checksum, + loadedFileList, true); + + // Fixup paths with .. + { + std::map < string, vector < pair < string, + string > > >newLoadedFileList; + for (std::map < string, vector < pair < string, + string > > >::iterator iterMap = loadedFileList.begin(); + iterMap != loadedFileList.end(); ++iterMap) { + string + loadedFile = iterMap->first; + + replaceAll(loadedFile, "//", "/"); + replaceAll(loadedFile, "\\\\", "\\"); + updatePathClimbingParts(loadedFile); + + if (newLoadedFileList.find(loadedFile) != + newLoadedFileList.end()) { + for (unsigned int xx1 = 0; xx1 < iterMap->second.size(); + ++xx1) { + pair < string, string > &newVal = iterMap->second[xx1]; + replaceAll(newVal.first, "//", "/"); + replaceAll(newVal.first, "\\\\", "\\"); + updatePathClimbingParts(newVal.first); + replaceAll(newVal.second, "//", "/"); + replaceAll(newVal.second, "\\\\", "\\"); + updatePathClimbingParts(newVal.second); + + newLoadedFileList[loadedFile].push_back(newVal); + } + } else { + for (unsigned int xx1 = 0; xx1 < iterMap->second.size(); + ++xx1) { + pair < string, string > &newVal = iterMap->second[xx1]; + replaceAll(newVal.first, "//", "/"); + replaceAll(newVal.first, "\\\\", "\\"); + updatePathClimbingParts(newVal.first); + replaceAll(newVal.second, "//", "/"); + replaceAll(newVal.second, "\\\\", "\\"); + updatePathClimbingParts(newVal.second); + } + + newLoadedFileList[loadedFile] = iterMap->second; + } + } + loadedFileList = newLoadedFileList; + } + + // Validate the faction setup to ensure we don't have any bad associations + std::vector < std::string > resultErrors = + world.validateFactionTypes(); + if (resultErrors.empty() == false) { + techtree_errors = true; + // Display the validation errors + string + errorText = + "\nErrors were detected:\n=====================\n"; + for (int i = 0; i < (int) resultErrors.size(); ++i) { + if (i > 0) { + errorText += "\n"; + } + errorText = errorText + resultErrors[i]; + } + errorText += "\n=====================\n"; + printf("%s", errorText.c_str()); + } + + // Validate the faction resource setup to ensure we don't have any bad associations + printf("\nChecking resources, count = %d\n", + world.getTechTree()->getResourceTypeCount()); + + for (int i = 0; i < world.getTechTree()->getResourceTypeCount(); + ++i) { + printf("Found techtree resource [%s]\n", + world.getTechTree()->getResourceType(i)->getName(). + c_str()); + } + + resultErrors = world.validateResourceTypes(); + if (resultErrors.empty() == false) { + techtree_errors = true; + // Display the validation errors + string + errorText = + "\nErrors were detected:\n=====================\n"; + for (int i = 0; i < (int) resultErrors.size(); ++i) { + if (i > 0) { + errorText += "\n"; + } + errorText = errorText + resultErrors[i]; + } + errorText += "\n=====================\n"; + printf("%s", errorText.c_str()); + } + + // Now check for unused files in the techtree + std::map < string, vector < pair < string, + string > > >foundFileList; + for (unsigned int i = 0; i < pathList.size(); ++i) { + string + path = pathList[i]; + endPathWithSlash(path); + path = path + techName + "/"; + + replaceAll(path, "//", "/"); + replaceAll(path, "\\\\", "\\"); + + vector < string > foundFiles = + getFolderTreeContentsListRecursively(path + "*.", ""); + for (unsigned int j = 0; j < foundFiles.size(); ++j) { + string + file = foundFiles[j]; + replaceAll(file, "//", "/"); + replaceAll(file, "\\\\", "\\"); + + // ignore loading screen, preview screen and hud + if (file.find(GameConstants::LOADING_SCREEN_FILE) != + string::npos + || file.find(GameConstants::PREVIEW_SCREEN_FILE) != + string::npos + || file.find(GameConstants::HUD_SCREEN_FILE) != + string::npos) { + continue; + } + + // ignore commondata since we are not loading all factions + if (filteredFactionList.size() > 0) { + if (file.find("/commondata/") != string::npos) { + continue; + } + } + + if (file.find("/factions/") != string::npos) { + bool + includeFaction = false; + for (set < string >::iterator it = factions.begin(); + it != factions.end(); ++it) { + string + currentFaction = *it; + if (file.find("/factions/" + currentFaction) != + string::npos) { + includeFaction = true; + break; + } + } + if (includeFaction == false) { + continue; + } + } + + replaceAll(file, "//", "/"); + replaceAll(file, "\\\\", "\\"); + + foundFileList[file].push_back(make_pair(path, path)); + } + } + + printf("Found techtree filecount = " MG_SIZE_T_SPECIFIER + ", used = " MG_SIZE_T_SPECIFIER "\n", + foundFileList.size(), loadedFileList.size()); + + int + purgeCount = 0; + bool + foundUnusedFile = false; + for (std::map < string, vector < pair < string, + string > > >::iterator iterMap = foundFileList.begin(); + iterMap != foundFileList.end(); ++iterMap) { + string + foundFile = iterMap->first; + replaceAll(foundFile, "//", "/"); + replaceAll(foundFile, "\\\\", "\\"); + + if (loadedFileList.find(foundFile) == loadedFileList.end() && + foundFile.find("lang/") == foundFile.npos) { + if (foundUnusedFile == false) { + printf + ("\nLine ref: %d, Warning, unused files were detected - START:\n=====================\n", + __LINE__); + } + foundUnusedFile = true; + + printf("[%s]\n", foundFile.c_str()); + + string + fileName = extractFileFromDirectoryPath(foundFile); + if (loadedFileList.find(fileName) != loadedFileList.end()) { + printf("possible match on [%s] ?\n", + loadedFileList.find(fileName)->first.c_str()); + } else if (purgeUnusedFiles == true) { + off_t + fileSize = getFileSize(foundFile); + // convert to MB + purgedMegaBytes += ((double) fileSize / 1048576.0); + purgeCount++; + + if (gitPurgeFiles == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "git rm \"%s\"", + foundFile.c_str()); + bool + gitOk = executeShellCommand(szBuf, 0); + if (gitOk == false) { + throw + megaglest_runtime_error("Call to command failed [" + + string(szBuf) + "]"); + } + } else { + removeFile(foundFile); + } + } + } + } + if (foundUnusedFile == true) { + if (purgedMegaBytes > 0) { + printf("Purged %.2f MB (%d) in files\n", purgedMegaBytes, + purgeCount); + } + printf + ("\nLine ref: %d, Warning, unused files were detected - END:\n", + __LINE__); + } + + if (showDuplicateFiles == true) { + std::map < uint32, vector < string > >mapDuplicateFiles; + // Now check for duplicate data content + for (std::map < string, vector < pair < string, + string > > >::iterator iterMap = loadedFileList.begin(); + iterMap != loadedFileList.end(); ++iterMap) { + string + fileName = iterMap->first; + Checksum + checksum; + checksum.addFile(fileName); + uint32 + crcValue = checksum.getSum(); + if (crcValue == 0) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Error calculating CRC for file [%s]", + fileName.c_str()); + throw + megaglest_runtime_error(szBuf); + } + mapDuplicateFiles[crcValue].push_back(fileName); + } + + double + duplicateMegaBytesPurged = 0; + int + duplicateCountPurged = 0; + + double + duplicateMegaBytes = 0; + int + duplicateCount = 0; + + bool + foundDuplicates = false; + for (std::map < uint32, vector < string > >::iterator iterMap = + mapDuplicateFiles.begin(); + iterMap != mapDuplicateFiles.end(); ++iterMap) { + vector < string > &fileList = iterMap->second; + if (fileList.size() > 1) { + if (foundDuplicates == false) { + foundDuplicates = true; + printf + ("\nWarning, duplicate files were detected - START:\n=====================\n"); + } + + printf("----- START duplicate files for CRC [%u] count [" + MG_SIZE_T_SPECIFIER "] first file is [%s]\n", + iterMap->first, fileList.size(), + fileList[0].c_str()); + + map < string, int > + parentList; + for (unsigned int idx = 0; idx < fileList.size(); ++idx) { + string + duplicateFile = fileList[idx]; + if (idx > 0) { + off_t + fileSize = getFileSize(duplicateFile); + // convert to MB + duplicateMegaBytes += ((double) fileSize / 1048576.0); + duplicateCount++; + } else { + printf("\n"); + } + + printf("[%s]\n", duplicateFile.c_str()); + std::map < string, vector < pair < string, + string > > >::iterator iterFind = + loadedFileList.find(duplicateFile); + if (iterFind != loadedFileList.end()) { + for (unsigned int jdx = 0; + jdx < iterFind->second.size(); jdx++) { + parentList[iterFind->second[jdx].first]++; + } + } + + string + newCommonFileName = + "$COMMONDATAPATH/sounds/" + + extractFileFromDirectoryPath(duplicateFile); + string + expandedNewCommonFileName = newCommonFileName; + std::map < string, string > mapExtraTagReplacementValues; + string + techCommonData = techPath + techName + "/commondata/"; + replaceAll(techCommonData, "//", "/"); + mapExtraTagReplacementValues["$COMMONDATAPATH"] = + techCommonData; + mapExtraTagReplacementValues = + Properties::getTagReplacementValues + (&mapExtraTagReplacementValues); + Properties::applyTagsToValue(expandedNewCommonFileName, + &mapExtraTagReplacementValues); + replaceAll(expandedNewCommonFileName, "//", "/"); + } + + printf("----- Finding parents for duplicate files [" + MG_SIZE_T_SPECIFIER "] first file is [%s]\n", + fileList.size(), fileList[0].c_str()); + + for (map < string, int >::iterator iterMap1 = + parentList.begin(); iterMap1 != parentList.end(); + ++iterMap1) { + + if (iterMap1 == parentList.begin()) { + printf("\tParents:\n"); + } + printf("\t[%s]\n", iterMap1->first.c_str()); + } + + if (purgeDuplicateFiles == true) { + + printf("----- move / remove duplicate files [" + MG_SIZE_T_SPECIFIER "] first file is [%s]\n", + fileList.size(), fileList[0].c_str()); + // First move first duplicate to commondata and delete all other copies + string + newCommonFileName = ""; + for (unsigned int idx = 0; idx < fileList.size(); ++idx) { + string + duplicateFile = fileList[idx]; + string + fileExt = extractExtension(duplicateFile); + if (fileExt == "wav" || fileExt == "ogg") { + off_t + fileSize = getFileSize(duplicateFile); + + printf("#1 [%u / " MG_SIZE_T_SPECIFIER + "] removing duplicate [%s]\n", idx, + fileList.size(), duplicateFile.c_str()); + + if (idx == 0) { + newCommonFileName = + "$COMMONDATAPATH/sounds/" + + extractFileFromDirectoryPath(duplicateFile); + + string + expandedNewCommonFileName = newCommonFileName; + + std::map < string, + string > mapExtraTagReplacementValues; + + string + techCommonData = + techPath + techName + "/commondata/"; + replaceAll(techCommonData, "//", "/"); + + mapExtraTagReplacementValues["$COMMONDATAPATH"] = + techCommonData; + mapExtraTagReplacementValues = + Properties::getTagReplacementValues + (&mapExtraTagReplacementValues); + Properties::applyTagsToValue + (expandedNewCommonFileName, + &mapExtraTagReplacementValues); + replaceAll(expandedNewCommonFileName, "//", "/"); + createDirectoryPaths(extractDirectoryPathFromFile + (expandedNewCommonFileName)); + + if (gitPurgeFiles == true) { + copyFileTo(duplicateFile, + expandedNewCommonFileName); + + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "git rm \"%s\"", + duplicateFile.c_str()); + bool + gitOk = executeShellCommand(szBuf, 0); + if (gitOk == false) { + throw + megaglest_runtime_error + ("Call to command failed [" + string(szBuf) + + "]"); + } + printf + ("*** Duplicate file:\n[%s]\nwas git rm and copied to:\n[%s]\n", + duplicateFile.c_str(), + expandedNewCommonFileName.c_str()); + } else { + printf + ("moving duplicate [%s] to common data [%s] expanded to [%s]\n", + duplicateFile.c_str(), + newCommonFileName.c_str(), + expandedNewCommonFileName.c_str()); + + int + result = rename(duplicateFile.c_str(), + expandedNewCommonFileName.c_str + ()); + if (result != 0) { + char + szBuf[8096] = ""; + char * + errmsg = strerror(errno); + snprintf(szBuf, 8096, + "!!! Error [%s] Could not rename [%s] to [%s]!", + errmsg, duplicateFile.c_str(), + expandedNewCommonFileName.c_str()); + throw + megaglest_runtime_error(szBuf); + } else { + printf + ("*** Duplicate file:\n[%s]\nwas renamed to:\n[%s]\n", + duplicateFile.c_str(), + expandedNewCommonFileName.c_str()); + } + } + } else { + if (gitPurgeFiles == true) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "git rm \"%s\"", + duplicateFile.c_str()); + bool + gitOk = executeShellCommand(szBuf, 0); + if (gitOk == false) { + throw + megaglest_runtime_error + ("Call to command failed [" + string(szBuf) + + "]"); + } + printf("*** Duplicate file:\n[%s]\nwas git rm\n", + duplicateFile.c_str()); + } else { + printf("removing duplicate [%s]\n", + duplicateFile.c_str()); + removeFile(duplicateFile); + } + printf("*** Duplicate file:\n[%s]\nwas removed\n", + duplicateFile.c_str()); + + // convert to MB + duplicateMegaBytesPurged += + ((double) fileSize / 1048576.0); + duplicateCountPurged++; + } + } + } + + printf("----- update XML files for duplicate files [" + MG_SIZE_T_SPECIFIER "] first file is [%s]\n", + fileList.size(), fileList[0].c_str()); + std::map < string, int > + mapUniqueParentList; + + // Update the XML files to point to the new single copy in commondata + for (unsigned int idx = 0; idx < fileList.size(); ++idx) { + string + duplicateFile = fileList[idx]; + string + fileExt = extractExtension(duplicateFile); + if (fileExt == "wav" || fileExt == "ogg") { + std::map < string, vector < pair < string, + string > > >::iterator iterFind2 = + loadedFileList.find(duplicateFile); + if (iterFind2 != loadedFileList.end()) { + for (unsigned int jdx1 = 0; + jdx1 < iterFind2->second.size(); jdx1++) { + string + parentFile = iterFind2->second[jdx1].first; + string + searchText = iterFind2->second[jdx1].second; + + if (mapUniqueParentList.find(parentFile) == + mapUniqueParentList.end()) { + printf + ("*** Searching parent file:\n[%s]\nfor duplicate file reference:\n[%s]\nto replace with newname:\n[%s]\n", + parentFile.c_str(), searchText.c_str(), + newCommonFileName.c_str()); + bool + foundText = + searchAndReplaceTextInFile(parentFile, + searchText, + newCommonFileName, + false); + printf("foundText = %d\n", foundText); + if (foundText == false) { + + string + techCommonData = + techPath + techName + "/commondata/"; + replaceAll(techCommonData, "//", "/"); + + if (StartsWith(searchText, techCommonData) == + true) { + printf + ("WARNING #1 [%d] techCommonData check\n[%s]\n[%s]\n[%s]\n[%s]\n", + foundText, parentFile.c_str(), + techCommonData.c_str(), + searchText.c_str(), + newCommonFileName.c_str()); + + replaceAll(searchText, techCommonData, + "$COMMONDATAPATH/"); + foundText = + searchAndReplaceTextInFile(parentFile, + searchText, + newCommonFileName, + false); + + printf + ("WARNING #2 [%d] techCommonData check\n[%s]\n[%s]\n[%s]\n[%s]\n", + foundText, parentFile.c_str(), + techCommonData.c_str(), + searchText.c_str(), + newCommonFileName.c_str()); + } + if (foundText == false) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Line ref = %d, Error finding text\n[%s]\nin file\n[%s]\nnew Common File [%s]\n", + __LINE__, searchText.c_str(), + parentFile.c_str(), + newCommonFileName.c_str()); + printf + ("\n\n=================================================\n%s", + szBuf); + + throw + megaglest_runtime_error(szBuf); + } + } + mapUniqueParentList[parentFile]++; + } + } + } + } + } + } else { + + string + newCommonFileName = ""; + for (unsigned int idx = 0; idx < fileList.size(); ++idx) { + string + duplicateFile = fileList[idx]; + string + fileExt = extractExtension(duplicateFile); + if (fileExt == "wav" || fileExt == "ogg") { + //off_t fileSize = getFileSize(duplicateFile); + if (idx == 0) { + newCommonFileName = + "$COMMONDATAPATH/sounds/" + + extractFileFromDirectoryPath(duplicateFile); + break; + } + } + } + + for (unsigned int idx = 0; idx < fileList.size(); ++idx) { + string + duplicateFile = fileList[idx]; + string + fileExt = extractExtension(duplicateFile); + if (fileExt == "wav" || fileExt == "ogg") { + std::map < string, vector < pair < string, + string > > >::iterator iterFind4 = + loadedFileList.find(duplicateFile); + if (iterFind4 != loadedFileList.end()) { + for (unsigned int jdx = 0; + jdx < iterFind4->second.size(); jdx++) { + string + parentFile = iterFind4->second[jdx].first; + string + searchText = iterFind4->second[jdx].second; + + bool + foundText = + searchAndReplaceTextInFile(parentFile, + searchText, + newCommonFileName, + true); + + if (foundText == false) { + string + techCommonData = + techPath + techName + "/commondata/"; + replaceAll(techCommonData, "//", "/"); + + if (StartsWith(searchText, techCommonData) == + true) { + replaceAll(searchText, techCommonData, + "$COMMONDATAPATH/"); + foundText = + searchAndReplaceTextInFile(parentFile, + searchText, + newCommonFileName, + true); + + } + if (foundText == false) { + + // Check if the sound file already references commandata + foundText = + searchAndReplaceTextInFile(parentFile, + newCommonFileName, + newCommonFileName, + true); + if (foundText == false) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Line ref = %d, Error finding text\n[%s]\nin file\n[%s]\nnew Common File [%s]\n", + __LINE__, searchText.c_str(), + parentFile.c_str(), + newCommonFileName.c_str()); + printf + ("\n\n=================================================\n%s", + szBuf); + + throw + megaglest_runtime_error(szBuf); + } + } + } + } + } + } + } + } + + + printf("----- END duplicate files [" MG_SIZE_T_SPECIFIER + "] first file is [%s]\n", fileList.size(), + fileList[0].c_str()); + } + } + if (foundDuplicates == true) { + printf("Duplicates %.2f MB (%d) in files\n", + duplicateMegaBytes, duplicateCount); + printf("Duplicates purged %.2f MB (%d) in files\n", + duplicateMegaBytesPurged, duplicateCountPurged); + + printf("\nWarning, duplicate files were detected - END:\n"); + } + } + } catch (const megaglest_runtime_error & ex) { + techtree_errors = true; + printf + ("\n\n****ERROR**** detected while validating the techName: %s\nMESSAGE: %s\n", + techName.c_str(), ex.what()); + } + + if (techtree_errors == false) { + printf + ("\nValidation found NO ERRORS for techPath [%s] techName [%s] factions checked (count = %d):\n", + techPath.c_str(), techName.c_str(), (int) factions.size()); + for (set < string >::iterator it = factions.begin(); + it != factions.end(); ++it) { + printf("Faction [%s]\n", (*it).c_str()); + } + } + } + printf + ("----------------------------------------------------------------"); + } else if (folderExists(techTreeFolder) == true) { + printf + ("\nWarning, No factions were found for the techtree located in: [%s]\n", + techTreeFolder.c_str()); + } + } + + + void + runTechTranslationExtractionForPath(string techPath, string techName, + const std::vector < string > + &filteredFactionList, World & world) { + vector < string > factionsList; + findDirs(techPath + techName + "/factions/", factionsList, false, + false); + + if (factionsList.empty() == false) { + Checksum + checksum; + set < string > factions; + for (int j = 0; j < (int) factionsList.size(); ++j) { + if (filteredFactionList.empty() == true || + std::find(filteredFactionList.begin(), + filteredFactionList.end(), + factionsList[j]) != filteredFactionList.end()) { + factions.insert(factionsList[j]); + } + } + + printf + ("\n----------------------------------------------------------------"); + printf + ("\nChecking techPath [%s] techName [%s] total faction count = %d\n", + techPath.c_str(), techName.c_str(), (int) factionsList.size()); + for (int j = 0; j < (int) factionsList.size(); ++j) { + if (filteredFactionList.empty() == true || + std::find(filteredFactionList.begin(), + filteredFactionList.end(), + factionsList[j]) != filteredFactionList.end()) { + printf("Using faction [%s]\n", factionsList[j].c_str()); + } + } + + if (factions.empty() == false) { + std::map < string, vector < pair < string, + string > > >loadedFileList; + vector < string > pathList; + pathList.push_back(techPath); + Config & config = Config::getInstance(); + vector < string > otherTechPaths = + config.getPathListForType(ptTechs, ""); + pathList.insert(pathList.end(), otherTechPaths.begin(), + otherTechPaths.end()); + + try { + world.loadTech(pathList, techName, factions, &checksum, + loadedFileList, true); + + const TechTree * + techtree = world.getTechTree(); + string + translationFile = techtree->getPath(); + endPathWithSlash(translationFile); + translationFile += "lang/" + techName + "_default.lng"; + if (fileExists(translationFile) == false) { + string + txFilePath = extractDirectoryPathFromFile(translationFile); + createDirectoryPaths(txFilePath); #if defined(WIN32) && !defined(__MINGW32__) - FILE * - fp = _wfopen (utf8_decode (translationFile).c_str (), L"w"); - std::ofstream txFile (fp); + FILE * + fp = _wfopen(utf8_decode(translationFile).c_str(), L"w"); + std::ofstream txFile(fp); #else - std::ofstream txFile; - txFile.open (translationFile.c_str (), - ios_base::out | ios_base::trunc); + std::ofstream txFile; + txFile.open(translationFile.c_str(), + ios_base::out | ios_base::trunc); #endif - if (txFile.is_open () == true) - { - string - _transl_TechTreeName = techName; - replaceAll (_transl_TechTreeName, "_", " "); - txFile << "; TechTree" << std::endl; - txFile << "TechTreeName=" << _transl_TechTreeName << - std::endl; + if (txFile.is_open() == true) { + string + _transl_TechTreeName = techName; + replaceAll(_transl_TechTreeName, "_", " "); + txFile << "; TechTree" << std::endl; + txFile << "TechTreeName=" << _transl_TechTreeName << + std::endl; - txFile << "; -------------------------------------" << - std::endl; - txFile << "; Types of Armor" << std::endl; - for (int index = 0; index < techtree->getArmorTypeCount (); - ++index) - { - const ArmorType * - at = techtree->getArmorTypeByIndex (index); - string - _transl_ArmorTypeName = at->getName (false); - replaceAll (_transl_ArmorTypeName, "_", " "); - txFile << "ArmorTypeName_" << at->getName (false) << "=" << - _transl_ArmorTypeName << std::endl; - } + txFile << "; -------------------------------------" << + std::endl; + txFile << "; Types of Armor" << std::endl; + for (int index = 0; index < techtree->getArmorTypeCount(); + ++index) { + const ArmorType * + at = techtree->getArmorTypeByIndex(index); + string + _transl_ArmorTypeName = at->getName(false); + replaceAll(_transl_ArmorTypeName, "_", " "); + txFile << "ArmorTypeName_" << at->getName(false) << "=" << + _transl_ArmorTypeName << std::endl; + } - txFile << "; --------------------" << std::endl; - txFile << "; Types of Attack" << std::endl; - for (int index = 0; index < techtree->getAttackTypeCount (); - ++index) - { - const AttackType * - at = techtree->getAttackTypeByIndex (index); - string - _transl_AttackTypeName = at->getName (false); - replaceAll (_transl_AttackTypeName, "_", " "); - txFile << "AttackTypeName_" << at->getName (false) << "=" << - _transl_AttackTypeName << std::endl; - } + txFile << "; --------------------" << std::endl; + txFile << "; Types of Attack" << std::endl; + for (int index = 0; index < techtree->getAttackTypeCount(); + ++index) { + const AttackType * + at = techtree->getAttackTypeByIndex(index); + string + _transl_AttackTypeName = at->getName(false); + replaceAll(_transl_AttackTypeName, "_", " "); + txFile << "AttackTypeName_" << at->getName(false) << "=" << + _transl_AttackTypeName << std::endl; + } - txFile << "; --------------------" << std::endl; - txFile << "; Types of Resources" << std::endl; - for (int index = 0; index < techtree->getResourceTypeCount (); - ++index) - { - const ResourceType * - rt = techtree->getResourceType (index); - string - _transl_ResourceTypeName = rt->getName (false); - replaceAll (_transl_ResourceTypeName, "_", " "); - txFile << "ResourceTypeName_" << rt->getName (false) << "=" - << _transl_ResourceTypeName << std::endl; - } + txFile << "; --------------------" << std::endl; + txFile << "; Types of Resources" << std::endl; + for (int index = 0; index < techtree->getResourceTypeCount(); + ++index) { + const ResourceType * + rt = techtree->getResourceType(index); + string + _transl_ResourceTypeName = rt->getName(false); + replaceAll(_transl_ResourceTypeName, "_", " "); + txFile << "ResourceTypeName_" << rt->getName(false) << "=" + << _transl_ResourceTypeName << std::endl; + } -//txFile << "FactionName_" << GameConstants::OBSERVER_SLOTNAME << "=" << GameConstants::OBSERVER_SLOTNAME << std::endl; -//txFile << "FactionName_" << GameConstants::RANDOMFACTION_SLOTNAME << "=" << GameConstants::RANDOMFACTION_SLOTNAME << std::endl; - for (int index = 0; index < techtree->getTypeCount (); - ++index) - { - const FactionType * - ft = techtree->getType (index); - string - _transl_FactionName = ft->getName (false); - replaceAll (_transl_FactionName, "_", " "); - txFile << - "; -----------------------------------------------------------------------------" - << std::endl; - txFile << "; Faction" << std::endl; - txFile << "FactionName_" << ft->getName (false) << "=" << - _transl_FactionName << std::endl; + //txFile << "FactionName_" << GameConstants::OBSERVER_SLOTNAME << "=" << GameConstants::OBSERVER_SLOTNAME << std::endl; + //txFile << "FactionName_" << GameConstants::RANDOMFACTION_SLOTNAME << "=" << GameConstants::RANDOMFACTION_SLOTNAME << std::endl; + for (int index = 0; index < techtree->getTypeCount(); + ++index) { + const FactionType * + ft = techtree->getType(index); + string + _transl_FactionName = ft->getName(false); + replaceAll(_transl_FactionName, "_", " "); + txFile << + "; -----------------------------------------------------------------------------" + << std::endl; + txFile << "; Faction" << std::endl; + txFile << "FactionName_" << ft->getName(false) << "=" << + _transl_FactionName << std::endl; - txFile << "; -------------------------------------" << - std::endl; - txFile << "; Types of Upgrades for this Faction" << - std::endl; - for (int upgradeIndex = 0; - upgradeIndex < ft->getUpgradeTypeCount (); - ++upgradeIndex) - { - const UpgradeType * - upt = ft->getUpgradeType (upgradeIndex); - string - _transl_UpgradeTypeName = upt->getName (false); - replaceAll (_transl_UpgradeTypeName, "_", " "); - txFile << "UpgradeTypeName_" << upt->getName (false) << - "=" << _transl_UpgradeTypeName << std::endl; - } + txFile << "; -------------------------------------" << + std::endl; + txFile << "; Types of Upgrades for this Faction" << + std::endl; + for (int upgradeIndex = 0; + upgradeIndex < ft->getUpgradeTypeCount(); + ++upgradeIndex) { + const UpgradeType * + upt = ft->getUpgradeType(upgradeIndex); + string + _transl_UpgradeTypeName = upt->getName(false); + replaceAll(_transl_UpgradeTypeName, "_", " "); + txFile << "UpgradeTypeName_" << upt->getName(false) << + "=" << _transl_UpgradeTypeName << std::endl; + } - for (int unitIndex = 0; unitIndex < ft->getUnitTypeCount (); - ++unitIndex) - { - const UnitType * - ut = ft->getUnitType (unitIndex); - string - _transl_UnitTypeName = ut->getName (false); - replaceAll (_transl_UnitTypeName, "_", " "); - txFile << "; -------------------------------------" << - std::endl; - txFile << "; Unit" << std::endl; - txFile << "UnitTypeName_" << ut->getName (false) << "=" << - _transl_UnitTypeName << std::endl; + for (int unitIndex = 0; unitIndex < ft->getUnitTypeCount(); + ++unitIndex) { + const UnitType * + ut = ft->getUnitType(unitIndex); + string + _transl_UnitTypeName = ut->getName(false); + replaceAll(_transl_UnitTypeName, "_", " "); + txFile << "; -------------------------------------" << + std::endl; + txFile << "; Unit" << std::endl; + txFile << "UnitTypeName_" << ut->getName(false) << "=" << + _transl_UnitTypeName << std::endl; - txFile << "; --------------------" << std::endl; - txFile << "; Levels for this Unit" << std::endl; - for (int levelIndex = 0; - levelIndex < ut->getLevelCount (); ++levelIndex) - { - const Level * - level = ut->getLevel (levelIndex); - string - _transl_LevelName = level->getName (false); - replaceAll (_transl_LevelName, "_", " "); - txFile << "LevelName_" << level->getName (false) << "=" - << _transl_LevelName << std::endl; - } + txFile << "; --------------------" << std::endl; + txFile << "; Levels for this Unit" << std::endl; + for (int levelIndex = 0; + levelIndex < ut->getLevelCount(); ++levelIndex) { + const Level * + level = ut->getLevel(levelIndex); + string + _transl_LevelName = level->getName(false); + replaceAll(_transl_LevelName, "_", " "); + txFile << "LevelName_" << level->getName(false) << "=" + << _transl_LevelName << std::endl; + } - txFile << "; --------------------" << std::endl; - txFile << "; Types of Commands for this Unit" << - std::endl; - for (int commandIndex = 0; - commandIndex < ut->getCommandTypeCount (); - ++commandIndex) - { - const CommandType * - ct = ut->getCommandType (commandIndex); - string - _transl_CommandName = ct->getName (false); - replaceAll (_transl_CommandName, "_", " "); - txFile << "CommandName_" << ct->getName (false) << "=" - << _transl_CommandName << std::endl; - } - } - } - txFile << "; -------------------------------------" << - std::endl; - } - txFile.close (); + txFile << "; --------------------" << std::endl; + txFile << "; Types of Commands for this Unit" << + std::endl; + for (int commandIndex = 0; + commandIndex < ut->getCommandTypeCount(); + ++commandIndex) { + const CommandType * + ct = ut->getCommandType(commandIndex); + string + _transl_CommandName = ct->getName(false); + replaceAll(_transl_CommandName, "_", " "); + txFile << "CommandName_" << ct->getName(false) << "=" + << _transl_CommandName << std::endl; + } + } + } + txFile << "; -------------------------------------" << + std::endl; + } + txFile.close(); #if defined(WIN32) && !defined(__MINGW32__) - if (fp) - { - fclose (fp); - } + if (fp) { + fclose(fp); + } #endif - } - else - { - printf - ("\n** Cannot product techtree translation file [%s] for techPath [%s] techName [%s] because the file already exists!\n", - translationFile.c_str (), techPath.c_str (), - techName.c_str ()); - } - } - catch (const megaglest_runtime_error & ex) - { - printf - ("\n\n****ERROR**** detected while loading the techName: %s\nMESSAGE: %s\n", - techName.c_str (), ex.what ()); - } - - } - printf - ("----------------------------------------------------------------"); - } - } - - void - runTechTranslationExtraction (int argc, char **argv) - { - printf ("====== Started Translation Extraction ======\n"); - - Config & config = Config::getInstance (); - -// Did the user pass a specific list of factions to validate? - std::vector < string > filteredFactionList; - - vector < string > results; - findDirs (config.getPathListForType (ptTechs), results); - vector < string > techTreeFiles = results; -// Did the user pass a specific list of techtrees to validate? - std::vector < string > filteredTechTreeList; - if (hasCommandArgument - (argc, argv, - string (GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) + string ("=")) == - true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) + - string ("="), &foundParamIndIndex); - string - filterList = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (filterList, paramPartTokens, "="); - if (paramPartTokens.size () >= 2) - { - string - techtreeList = paramPartTokens[1]; - Tokenize (techtreeList, filteredTechTreeList, ","); - - if (filteredTechTreeList.empty () == false) - { - printf - ("Filtering techtrees and only looking for the following:\n"); - for (int idx = 0; idx < (int) filteredTechTreeList.size (); ++idx) - { - filteredTechTreeList[idx] = trim (filteredTechTreeList[idx]); - printf ("%s\n", filteredTechTreeList[idx].c_str ()); - } - } - } - } - - { - printf - ("\n---------------- Loading factions inside world ----------------"); - World - world; - - vector < string > techPaths = config.getPathListForType (ptTechs); - for (int idx = 0; idx < (int) techPaths.size (); idx++) - { - string & techPath = techPaths[idx]; - endPathWithSlash (techPath); - - for (int idx2 = 0; idx2 < (int) techTreeFiles.size (); idx2++) - { - string & techName = techTreeFiles[idx2]; - - if (filteredTechTreeList.empty () == true || - std::find (filteredTechTreeList.begin (), - filteredTechTreeList.end (), - techName) != filteredTechTreeList.end ()) - { - - runTechTranslationExtractionForPath (techPath, techName, - filteredFactionList, - world); - } - } - } - - printf ("\n====== Finished Translation ======\n"); - } - - } - - - void - runTechValidationReport (int argc, char **argv) - { - printf ("====== Started Validation ======\n"); - - bool - purgeDuplicateFiles = false; - bool - showDuplicateFiles = true; - bool - purgeUnusedFiles = false; - bool - gitPurgeFiles = false; - - double - purgedMegaBytes = 0; - Config & config = Config::getInstance (); - -// Did the user pass a specific scenario to validate? - if (hasCommandArgument - (argc, argv, - string (GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) + string ("=")) == - true) - { - - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) + - string ("="), &foundParamIndIndex); - - string - filterList = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (filterList, paramPartTokens, "="); - - if (paramPartTokens.size () >= 2) - { - string - validateScenarioName = paramPartTokens[1]; - - printf ("Filtering scenario: %s\n", validateScenarioName.c_str ()); - - if (paramPartTokens.size () >= 3) - { - if (paramPartTokens[2] == "purgeunused") - { - purgeUnusedFiles = true; - printf ("*NOTE All unused scenario files will be deleted!\n"); - } - } - - { - printf - ("\n---------------- Loading scenario inside world ----------------\n"); - - bool - scenarioFound = false; - World - world; - std::vector < string > filteredFactionList; - - vector < string > scenarioPaths = - config.getPathListForType (ptScenarios); - for (int idx = 0; idx < (int) scenarioPaths.size (); idx++) - { - string & scenarioPath = scenarioPaths[idx]; - endPathWithSlash (scenarioPath); - - vector < string > scenarioList; - findDirs (scenarioPath, scenarioList, false, false); - for (int idx2 = 0; idx2 < (int) scenarioList.size (); idx2++) - { - string & scenarioName = scenarioList[idx2]; - - if (scenarioName == validateScenarioName) - { - scenarioFound = true; - - string - file = - scenarioPath + scenarioName + "/" + scenarioName + ".xml"; - - XmlTree - xmlTree; - xmlTree.load (file, Properties::getTagReplacementValues ()); - const XmlNode * - scenarioNode = xmlTree.getRootNode (); - string - techName = - scenarioNode->getChild ("tech-tree")-> - getAttribute ("value")->getValue (); - -// Self Contained techtree? - string - scenarioTechtree = - scenarioPath + scenarioName + "/" + techName + "/" + - techName + ".xml"; - - printf - ("\nFound Scenario [%s] looking for techtree [%s]...\n", - scenarioName.c_str (), scenarioTechtree.c_str ()); - - if (fileExists (scenarioTechtree) == true) - { - string - techPath = scenarioPath + scenarioName + "/"; - - printf - ("\nFound Scenario [%s] with custom techtree [%s] validating...\n", - scenarioName.c_str (), techName.c_str ()); - runTechValidationForPath (techPath, techName, - filteredFactionList, world, - purgeUnusedFiles, - showDuplicateFiles, false, - false, purgedMegaBytes); - } - else - { - vector < string > techPaths = - config.getPathListForType (ptTechs); - for (int idx = 0; idx < (int) techPaths.size (); idx++) - { - string & techPath = techPaths[idx]; - endPathWithSlash (techPath); - scenarioTechtree = - techPath + "/" + techName + "/" + techName + ".xml"; - if (fileExists (scenarioTechtree) == true) - { - printf - ("\nFound Scenario [%s] with techtree [%s] validating...\n", - scenarioName.c_str (), techName.c_str ()); - runTechValidationForPath (techPath, techName, - filteredFactionList, world, - purgeUnusedFiles, - showDuplicateFiles, false, - false, purgedMegaBytes); - - break; - } - } - } - } - } - } - - if (scenarioFound == false) - { - printf ("\nWARNING, the scenario [%s] was NOT FOUND!\n", - validateScenarioName.c_str ()); - } - printf ("\n====== Finished Validation ======\n"); - } - return; - } - else - { - printf - ("\nInvalid missing scenario specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - return; - } - } - -// Did the user pass a specific list of factions to validate? - std::vector < string > filteredFactionList; - if (hasCommandArgument - (argc, argv, - string (GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) + string ("=")) == - true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) + - string ("="), &foundParamIndIndex); - - string - filterList = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (filterList, paramPartTokens, "="); - - if (paramPartTokens.size () >= 2) - { - string - factionList = paramPartTokens[1]; - Tokenize (factionList, filteredFactionList, ","); - - if (filteredFactionList.empty () == false) - { - printf - ("Filtering factions and only looking for the following:\n"); - for (int idx = 0; idx < (int) filteredFactionList.size (); ++idx) - { - filteredFactionList[idx] = trim (filteredFactionList[idx]); - printf ("%s\n", filteredFactionList[idx].c_str ()); - } - } - - if (paramPartTokens.size () >= 3) - { - if (paramPartTokens[2] == "purgeunused") - { - purgeUnusedFiles = true; - printf ("*NOTE All unused faction files will be deleted!\n"); - } - } - } - } - vector < string > results; - findDirs (config.getPathListForType (ptTechs), results); - vector < string > techTreeFiles = results; -// Did the user pass a specific list of techtrees to validate? - std::vector < string > filteredTechTreeList; - if (hasCommandArgument - (argc, argv, - string (GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) + string ("=")) == - true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) + - string ("="), &foundParamIndIndex); - string - filterList = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (filterList, paramPartTokens, "="); - if (paramPartTokens.size () >= 2) - { - string - techtreeList = paramPartTokens[1]; - Tokenize (techtreeList, filteredTechTreeList, ","); - - if (filteredTechTreeList.empty () == false) - { - printf - ("Filtering techtrees and only looking for the following:\n"); - for (int idx = 0; idx < (int) filteredTechTreeList.size (); ++idx) - { - filteredTechTreeList[idx] = trim (filteredTechTreeList[idx]); - printf ("%s\n", filteredTechTreeList[idx].c_str ()); - } - } - - if (paramPartTokens.size () >= 3) - { - if (paramPartTokens[2] == "purgeunused") - { - purgeUnusedFiles = true; - printf ("*NOTE All unused techtree files will be deleted!\n"); - } - else if (paramPartTokens[2] == "purgeduplicates") - { - purgeDuplicateFiles = true; - printf ("*NOTE All duplicate techtree files will be merged!\n"); - } - else if (paramPartTokens[2] == "gitdelete") - { - gitPurgeFiles = true; - printf - ("*NOTE All unused / duplicate techtree files will be removed from git!\n"); - } - else if (paramPartTokens[2] == "hideduplicates") - { - showDuplicateFiles = false; - printf - ("*NOTE All duplicate techtree files will NOT be shown!\n"); - } - } - if (paramPartTokens.size () >= 4) - { - if (paramPartTokens[3] == "purgeunused") - { - purgeUnusedFiles = true; - printf ("*NOTE All unused techtree files will be deleted!\n"); - } - else if (paramPartTokens[3] == "purgeduplicates") - { - purgeDuplicateFiles = true; - printf ("*NOTE All duplicate techtree files will be merged!\n"); - } - else if (paramPartTokens[3] == "gitdelete") - { - gitPurgeFiles = true; - printf - ("*NOTE All unused / duplicate techtree files will be removed from git!\n"); - } - else if (paramPartTokens[3] == "hideduplicates") - { - showDuplicateFiles = false; - printf - ("*NOTE All duplicate techtree files will NOT be shown!\n"); - } - } - if (paramPartTokens.size () >= 5) - { - if (paramPartTokens[4] == "purgeunused") - { - purgeUnusedFiles = true; - printf ("*NOTE All unused techtree files will be deleted!\n"); - } - else if (paramPartTokens[4] == "purgeduplicates") - { - purgeDuplicateFiles = true; - printf ("*NOTE All duplicate techtree files will be merged!\n"); - } - else if (paramPartTokens[4] == "gitdelete") - { - gitPurgeFiles = true; - printf - ("*NOTE All unused / duplicate techtree files will be removed from git!\n"); - } - else if (paramPartTokens[4] == "hideduplicates") - { - showDuplicateFiles = false; - printf - ("*NOTE All duplicate techtree files will NOT be shown!\n"); - } - } - } - } - - { - printf - ("\n---------------- Loading factions inside world ----------------"); - World - world; - - vector < string > techPaths = config.getPathListForType (ptTechs); - for (int idx = 0; idx < (int) techPaths.size (); idx++) - { - string & techPath = techPaths[idx]; - endPathWithSlash (techPath); - - for (int idx2 = 0; idx2 < (int) techTreeFiles.size (); idx2++) - { - string & techName = techTreeFiles[idx2]; - - if (filteredTechTreeList.empty () == true || - std::find (filteredTechTreeList.begin (), - filteredTechTreeList.end (), - techName) != filteredTechTreeList.end ()) - { - - runTechValidationForPath (techPath, techName, - filteredFactionList, world, - purgeUnusedFiles, purgeDuplicateFiles, - showDuplicateFiles, gitPurgeFiles, - purgedMegaBytes); - } - } - } - - printf ("\n====== Finished Validation ======\n"); - } - - } - - void - runTilesetValidationReport (int argc, char **argv) - { - printf ("====== Started Validation ======\n"); - - Config & config = Config::getInstance (); - -// Did the user pass a specific tileset to validate? - if (hasCommandArgument - (argc, argv, - string (GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) + string ("=")) == - true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) + - string ("="), &foundParamIndIndex); - - string - filterList = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (filterList, paramPartTokens, "="); - - if (paramPartTokens.size () >= 2) - { - string - validateTilesetName = paramPartTokens[1]; - - printf ("Filtering tileset: %s\n", validateTilesetName.c_str ()); - - bool - purgeUnusedFiles = false; - if (paramPartTokens.size () >= 3) - { - if (paramPartTokens[2] == "purgeunused") - { - purgeUnusedFiles = true; - printf ("*NOTE All unused tileset files will be deleted!\n"); - } - } - - { - printf - ("\n---------------- Loading tileset inside world ----------------\n"); - - World - world; - double - purgedMegaBytes = 0; - bool - showDuplicateFiles = true; - - bool - tilesetFound = false; - - vector < string > tilesetPaths = - config.getPathListForType (ptTilesets); - for (int idx = 0; idx < (int) tilesetPaths.size (); idx++) - { - string & tilesetPath = tilesetPaths[idx]; - endPathWithSlash (tilesetPath); - - vector < string > tilesetList; - findDirs (tilesetPath, tilesetList, false, false); - for (int idx2 = 0; idx2 < (int) tilesetList.size (); idx2++) - { - string & tilesetName = tilesetList[idx2]; - if (tilesetName == validateTilesetName) - { - tilesetFound = true; - runTilesetValidationForPath (tilesetPath, tilesetName, - world, purgeUnusedFiles, - showDuplicateFiles, false, - false, purgedMegaBytes); - } - } - } - - if (tilesetFound == false) - { - printf ("*ERROR The specified tileset [%s] was NOT FOUND!\n", - validateTilesetName.c_str ()); - } - printf ("\n====== Finished Validation ======\n"); - } - return; - } - else - { - printf - ("\nInvalid missing tileset specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - return; - } - } - else - { - printf ("\nInvalid missing tileset specified on commandline\n\n"); - return; - } - } - - void - ShowINISettings (int argc, char **argv, Config & config, - Config & configKeys) - { - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true) - { - vector < string > filteredPropertyList; - if (hasCommandArgument - (argc, argv, - string (GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) + string ("=")) == - true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) + - string ("="), &foundParamIndIndex); - string - filterList = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (filterList, paramPartTokens, "="); - if (paramPartTokens.size () >= 2) - { - string - tokenList = paramPartTokens[1]; - Tokenize (tokenList, filteredPropertyList, ","); - - if (filteredPropertyList.empty () == false) - { - printf - ("Filtering properties and only looking for the following:\n"); - for (int idx = 0; idx < (int) filteredPropertyList.size (); - ++idx) - { - filteredPropertyList[idx] = trim (filteredPropertyList[idx]); - printf ("%s\n", filteredPropertyList[idx].c_str ()); - } - } - } - } - - printf ("\nMain settings report\n"); - printf ("====================\n"); - vector < pair < string, string > >mergedMainSettings = - config.getMergedProperties (); - vector < pair < string, string > >mergedKeySettings = - configKeys.getMergedProperties (); - -// Figure out the max # of tabs we need to format display nicely - int - tabCount = 1; - for (int i = 0; i < (int) mergedMainSettings.size (); ++i) - { - const - pair < - string, - string > & - nameValue = mergedMainSettings[i]; - - bool - displayProperty = false; - if (filteredPropertyList.empty () == false) - { - if (find - (filteredPropertyList.begin (), filteredPropertyList.end (), - nameValue.first) != filteredPropertyList.end ()) - { - displayProperty = true; - } - } - else - { - displayProperty = true; - } - - if (displayProperty == true) - { - int - requredTabs = ((int) nameValue.first.length () / 8) + 1; - if (nameValue.first.length () % 8) - { - requredTabs++; - } - if (requredTabs > tabCount) - { - tabCount = requredTabs; - } - } - } - for (int i = 0; i < (int) mergedKeySettings.size (); ++i) - { - const - pair < - string, - string > & - nameValue = mergedKeySettings[i]; - - bool - displayProperty = false; - if (filteredPropertyList.empty () == false) - { - if (find - (filteredPropertyList.begin (), filteredPropertyList.end (), - nameValue.first) != filteredPropertyList.end ()) - { - displayProperty = true; - } - } - else - { - displayProperty = true; - } - - if (displayProperty == true) - { - int - requredTabs = ((int) nameValue.first.length () / 8) + 1; - if (nameValue.first.length () % 8) - { - requredTabs++; - } - if (requredTabs > tabCount) - { - tabCount = requredTabs; - } - } - } - -// Output the properties - for (int i = 0; i < (int) mergedMainSettings.size (); ++i) - { - const - pair < - string, - string > & - nameValue = mergedMainSettings[i]; - - bool - displayProperty = false; - if (filteredPropertyList.empty () == false) - { - if (find - (filteredPropertyList.begin (), filteredPropertyList.end (), - nameValue.first) != filteredPropertyList.end ()) - { - displayProperty = true; - } - } - else - { - displayProperty = true; - } - - if (displayProperty == true) - { - printf ("Property Name [%s]", nameValue.first.c_str ()); - - int - tabs = ((int) nameValue.first.length () / 8) + 1; - for (int j = 0; j < (tabCount - tabs); ++j) - { - printf ("\t"); - } - - string - displayValue = nameValue.second; - if (nameValue.first == "TranslationGetURLPassword") - { - displayValue = "*****"; - } - - printf ("Value [%s]\n", displayValue.c_str ()); - } - } - - printf ("\n\nMain key binding settings report\n"); - printf ("====================================\n"); - - for (int i = 0; i < (int) mergedKeySettings.size (); ++i) - { - const - pair < - string, - string > & - nameValue = mergedKeySettings[i]; - - bool - displayProperty = false; - if (filteredPropertyList.empty () == false) - { - if (find - (filteredPropertyList.begin (), filteredPropertyList.end (), - nameValue.first) != filteredPropertyList.end ()) - { - displayProperty = true; - } - } - else - { - displayProperty = true; - } - - if (displayProperty == true) - { - printf ("Property Name [%s]", nameValue.first.c_str ()); - - int - tabs = ((int) nameValue.first.length () / 8) + 1; - for (int j = 0; j < (tabCount - tabs); ++j) - { - printf ("\t"); - } - - printf ("Value [%s]\n", nameValue.second.c_str ()); - } - } - } - } - - Steam & initSteamInstance () - { - Steam *& - steamInstance = - CacheManager::getCachedItem < - Steam * >(GameConstants::steamCacheInstanceKey); - if (steamInstance == NULL) - { - steamInstance = new Steam (); - } - return *steamInstance; - } - - void - setupSteamSettings (bool steamEnabled, bool steamResetStats, - bool debugEnabled) - { - Config & config = Config::getInstance (); - config.setBool ("SteamEnabled", steamEnabled, true); - if (steamEnabled) - { - printf ("*NOTE: Steam Integration Enabled.\n"); - - if (debugEnabled) - { - printf ("*NOTE: Steam Debugging Enabled.\n"); - } - Steam::setDebugEnabled (debugEnabled); - - Steam & steam = initSteamInstance (); - -// For Debugging purposes: - if (steamResetStats) - { - printf - ("*WARNING: Steam Stats / Achievements are being RESET by request!\n"); - steam.resetStats (true); - } - - string - steamPlayerName = steam.userName (); - string - steamLang = steam.lang (); - printf - ("Steam Integration Enabled!\nSteam User Name is [%s] Language is [%s]\n", - steamPlayerName.c_str (), steamLang.c_str ()); - - bool - needToSaveConfig = false; - string - currentPLayerName = config.getString ("NetPlayerName", ""); - if (currentPLayerName == "newbie" || currentPLayerName == "") - { - config.setString ("NetPlayerName", steamPlayerName); - needToSaveConfig = true; - } - if (needToSaveConfig == true) - { - config.save (); - } - } - } - - void - CheckForDuplicateData () - { - Config & config = Config::getInstance (); - - string - duplicateWarnings = ""; - - try - { - - - { - - string - scenarioDir = ""; - vector < string > pathList = - config.getPathListForType (ptMaps, scenarioDir); - vector < string > invalidMapList; - vector < string > maps = - MapPreview::findAllValidMaps (pathList, scenarioDir, false, true, - &invalidMapList); - std::sort (maps.begin (), maps.end ()); - - if (maps.empty () == true) - { - throw - megaglest_runtime_error ("No maps were found!", true); - } - else if (invalidMapList.empty () == false) - { - string - errorMsg = - "Warning invalid maps were detected (will be ignored):\n"; - for (int i = 0; i < (int) invalidMapList.size (); ++i) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "map [%s]\n", - invalidMapList[i].c_str ()); - - errorMsg += szBuf; - } - duplicateWarnings += errorMsg; - } - - vector < string > duplicateMapsToRename; - for (int i = 0; i < (int) maps.size (); ++i) - { - string - map1 = maps[i]; - for (int j = 0; j < (int) maps.size (); ++j) - { - if (i != j) - { - string - map2 = maps[j]; - - if (map1 == map2) - { - if (std::find (duplicateMapsToRename.begin (), - duplicateMapsToRename.end (), - map1) == duplicateMapsToRename.end ()) - { - duplicateMapsToRename.push_back (map1); - } - } - } - } - } - if (duplicateMapsToRename.empty () == false) - { - string - errorMsg = - "Warning duplicate maps were detected and renamed:\n"; - for (int i = 0; i < (int) duplicateMapsToRename.size (); ++i) - { - string - currentPath = pathList[1]; - endPathWithSlash (currentPath); - - string - oldFile = currentPath + duplicateMapsToRename[i]; - string - newFile = currentPath + duplicateMapsToRename[i]; - string - ext = extractExtension (newFile); - newFile = - newFile.substr (0, newFile.length () - ext.length () - 1); - newFile = newFile + "_custom." + ext; - - char - szBuf[8096] = ""; - int - result = rename (oldFile.c_str (), newFile.c_str ()); - if (result != 0) - { - char * - errmsg = strerror (errno); - snprintf (szBuf, 8096, - "Error [%s]\nCould not rename [%s] to [%s]!", - errmsg, oldFile.c_str (), newFile.c_str ()); - throw - megaglest_runtime_error (szBuf, true); - } - else - { - snprintf (szBuf, 8096, - "map [%s] in [%s]\nwas renamed to [%s]", - duplicateMapsToRename[i].c_str (), oldFile.c_str (), - newFile.c_str ()); - } - errorMsg += szBuf; - } - duplicateWarnings += errorMsg; - } - } - - { -//tilesets - std::vector < std::string > tileSets; - vector < string > tilesetPaths = - config.getPathListForType (ptTilesets); - findDirs (tilesetPaths, tileSets, false, true); - - if (tileSets.empty ()) - { - throw - megaglest_runtime_error ("No tilesets were found!", true); - } - - vector < string > duplicateTilesetsToRename; - for (int i = 0; i < (int) tileSets.size (); ++i) - { - string - tileSet1 = tileSets[i]; - for (int j = 0; j < (int) tileSets.size (); ++j) - { - if (i != j) - { - string - tileSet2 = tileSets[j]; - if (tileSet1 == tileSet2) - { - if (std::find (duplicateTilesetsToRename.begin (), - duplicateTilesetsToRename.end (), - tileSet1) == - duplicateTilesetsToRename.end ()) - { - duplicateTilesetsToRename.push_back (tileSet1); - } - } - } - } - } - if (duplicateTilesetsToRename.empty () == false) - { - string - errorMsg = - "Warning duplicate tilesets were detected and renamed:\n"; - - for (int i = 0; i < (int) duplicateTilesetsToRename.size (); ++i) - { - string - currentPath = tilesetPaths[1]; - endPathWithSlash (currentPath); - - string - oldFile = currentPath + duplicateTilesetsToRename[i]; - string - newFile = currentPath + duplicateTilesetsToRename[i]; - newFile = newFile + "_custom"; - - char - szBuf[8096] = ""; - int - result = rename (oldFile.c_str (), newFile.c_str ()); - if (result != 0) - { - char * - errmsg = strerror (errno); - snprintf (szBuf, 8096, - "Error [%s]\nCould not rename [%s] to [%s]!", - errmsg, oldFile.c_str (), newFile.c_str ()); - throw - megaglest_runtime_error (szBuf, true); - } - else - { - snprintf (szBuf, 8096, - "tileset [%s] in [%s]\nwas renamed to [%s]", - duplicateTilesetsToRename[i].c_str (), - oldFile.c_str (), newFile.c_str ()); - - string - tilesetName = extractFileFromDirectoryPath (oldFile); - oldFile = newFile + "/" + tilesetName + ".xml"; - newFile = newFile + "/" + tilesetName + "_custom.xml"; - - result = rename (oldFile.c_str (), newFile.c_str ()); - - if (result != 0) - { - char * - errmsg = strerror (errno); - snprintf (szBuf, 8096, - "Error [%s]\nCould not rename [%s] to [%s]!", - errmsg, oldFile.c_str (), newFile.c_str ()); - throw - megaglest_runtime_error (szBuf, true); - } - - } - errorMsg += szBuf; - } - duplicateWarnings += errorMsg; - } - } - - { - vector < string > techPaths = config.getPathListForType (ptTechs); - vector < string > techTrees; - findDirs (techPaths, techTrees, false, true); - if (techTrees.empty ()) - { - throw - megaglest_runtime_error ("No tech-trees were found (dup)!", - true); - } - - vector < string > duplicateTechtreesToRename; - for (int i = 0; i < (int) techTrees.size (); ++i) - { - string - techtree1 = techTrees[i]; - for (int j = 0; j < (int) techTrees.size (); ++j) - { - if (i != j) - { - string - techtree2 = techTrees[j]; - if (techtree1 == techtree2) - { - if (std::find (duplicateTechtreesToRename.begin (), - duplicateTechtreesToRename.end (), - techtree1) == - duplicateTechtreesToRename.end ()) - { - duplicateTechtreesToRename.push_back (techtree1); - } - } - } - } - } - if (duplicateTechtreesToRename.empty () == false) - { - string - errorMsg = - "Warning duplicate techtrees were detected and renamed:\n"; - - for (int i = 0; i < (int) duplicateTechtreesToRename.size (); ++i) - { - string - currentPath = techPaths[1]; - endPathWithSlash (currentPath); - - string - oldFile = currentPath + duplicateTechtreesToRename[i]; - string - newFile = currentPath + duplicateTechtreesToRename[i]; - newFile = newFile + "_custom"; - - char - szBuf[8096] = ""; - int - result = rename (oldFile.c_str (), newFile.c_str ()); - if (result != 0) - { - char * - errmsg = strerror (errno); - snprintf (szBuf, 8096, - "Error [%s]\nCould not rename [%s] to [%s]!", - errmsg, oldFile.c_str (), newFile.c_str ()); - throw - megaglest_runtime_error (szBuf, true); - } - else - { - snprintf (szBuf, 8096, - "techtree [%s] in [%s]\nwas renamed to [%s]", - duplicateTechtreesToRename[i].c_str (), - oldFile.c_str (), newFile.c_str ()); - - string - tilesetName = extractFileFromDirectoryPath (oldFile); - oldFile = newFile + "/" + tilesetName + ".xml"; - newFile = newFile + "/" + tilesetName + "_custom.xml"; - - int - rename_result = rename (oldFile.c_str (), newFile.c_str ()); - if (rename_result != 0) - { - printf ("Error renaming [%s] to [%s]\n", oldFile.c_str (), - newFile.c_str ()); - } - } - errorMsg += szBuf; - } - duplicateWarnings += errorMsg; - } - } - - } - catch (const megaglest_runtime_error & ex) - { - if (mainProgram) - { - mainProgram->getState ()->setForceMouseRender (true); - } - ExceptionHandler::DisplayMessage (ex.what (), false); - } - - if (duplicateWarnings != "") - { - if (mainProgram) - { - mainProgram->getState ()->setForceMouseRender (true); - } - ExceptionHandler::DisplayMessage (duplicateWarnings.c_str (), false); - } - } - - int - handleCreateDataArchivesCommand (int argc, char **argv) - { - int - return_value = 1; - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) - + string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS - [GAME_ARG_CREATE_DATA_ARCHIVES]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - compress_item = paramPartTokens[1]; - bool - includeMainData = false; - if (paramPartTokens.size () >= 3 - && paramPartTokens[2] == "include_main") - { - includeMainData = true; - } - - Config & config = Config::getInstance (); - string - fileArchiveExtension = - config.getString ("FileArchiveExtension", ""); - string - fileArchiveCompressCommand = - config.getString ("FileArchiveCompressCommand", ""); - string - fileArchiveCompressCommandParameters = - config.getString ("FileArchiveCompressCommandParameters", ""); - int32 - fileArchiveCompressCommandSuccessResult = - config.getInt ("FileArchiveCompressCommandSuccessResult", "0"); - - string - userData = config.getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - - int - typesSelected = 0; - if (compress_item == "techtrees" || compress_item == "all") - { - typesSelected++; - - vector < string > pathList = - config.getPathListForType (ptTechs, ""); - vector < string > results; - findDirs (pathList, results); - - printf - ("Techtrees found:\n===========================================\n"); - for (unsigned int i = 0; i < results.size (); ++i) - { - string - name = results[i]; - - for (unsigned int j = 0; j < pathList.size (); ++j) - { - string - techPath = pathList[j]; - if (techPath != "") - { - endPathWithSlash (techPath); - } - - vector < string > results2; - findDirs (techPath + name + "/factions", results2, false, - true); - if (results2.empty () == false) - { - string - techtreePath = techPath + name; - if (includeMainData == false) - { - if (techtreePath.find (userData) == techPath.npos) - { - printf ("Skipping techtree: [%s]\n", - techtreePath.c_str ()); - continue; - } - } - - string - downloadArchive = techtreePath + fileArchiveExtension; - - if (fileExists (downloadArchive) == true) - { - bool - removed = removeFile (downloadArchive); - if (removed == false) - { - printf ("Error could not remove old file: [%s]\n", - downloadArchive.c_str ()); - } - } - string - compressCmd = - getFullFileArchiveCompressCommand - (fileArchiveCompressCommand, - fileArchiveCompressCommandParameters, - downloadArchive, techtreePath); - - printf ("Running compression command: %s\n", - compressCmd.c_str ()); - - if (executeShellCommand - (compressCmd, - fileArchiveCompressCommandSuccessResult) == false) - { - printf ("Error could not create new file: [%s]\n", - downloadArchive.c_str ()); - } - - if (fileExists (downloadArchive) == true) - { - off_t - fileSize = getFileSize (downloadArchive); -// convert to MB - double - megaBytes = ((double) fileSize / 1048576.0); - printf ("%s [download archive %.2fMB]\n", name.c_str (), - megaBytes); - } - } - } - } - printf ("===========================================\nTotal: " - MG_SIZE_T_SPECIFIER "\n", results.size ()); - } - if (compress_item == "tilesets" || compress_item == "all") - { - typesSelected++; - - vector < string > pathList = - config.getPathListForType (ptTilesets, ""); - vector < string > results; - findDirs (pathList, results); - - printf - ("Tilesets found:\n===========================================\n"); - for (unsigned int i = 0; i < results.size (); ++i) - { - string - name = results[i]; - - for (unsigned int j = 0; j < pathList.size (); ++j) - { - string - tilesetPath = pathList[j]; - if (tilesetPath != "") - { - endPathWithSlash (tilesetPath); - } - - if (fileExists (tilesetPath + name + "/" + name + ".xml") == - true) - { - string - tilesetDataPath = tilesetPath + name; - if (includeMainData == false) - { - if (tilesetPath.find (userData) == tilesetPath.npos) - { - printf ("Skipping tileset data: [%s]\n", - tilesetDataPath.c_str ()); - continue; - } - } - - string - downloadArchive = tilesetDataPath + fileArchiveExtension; - - if (fileExists (downloadArchive) == true) - { - bool - removed = removeFile (downloadArchive); - if (removed == false) - { - printf ("Error could not remove old file: [%s]\n", - downloadArchive.c_str ()); - } - } - string - compressCmd = - getFullFileArchiveCompressCommand - (fileArchiveCompressCommand, - fileArchiveCompressCommandParameters, - downloadArchive, tilesetDataPath); - - printf ("Running compression command: %s\n", - compressCmd.c_str ()); - - if (executeShellCommand - (compressCmd, - fileArchiveCompressCommandSuccessResult) == false) - { - printf ("Error could not create new file: [%s]\n", - downloadArchive.c_str ()); - } - - if (fileExists (downloadArchive) == true) - { - off_t - fileSize = getFileSize (downloadArchive); -// convert to MB - double - megaBytes = ((double) fileSize / 1048576.0); - printf ("%s [download archive %.2fMB]\n", name.c_str (), - megaBytes); - } - - break; - } - } - } - printf ("===========================================\nTotal: " - MG_SIZE_T_SPECIFIER "\n", results.size ()); - - } - if (typesSelected == 0) - { - printf ("Compress item [%s] is not valid!\n", - compress_item.c_str ()); - return_value = 1; - } - else - return_value = 0; - } - else - { - printf - ("\nInvalid missing map specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - - return_value = 1; - } - } - - return return_value; - } - - int - handleShowCRCValuesCommand (int argc, char **argv) - { - int - return_value = 1; - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]) == - true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - itemName = paramPartTokens[1]; - - string - file = Config::getMapPath (itemName, "", false); - if (file != "") - { - Checksum - checksum; - checksum.addFile (file); - uint32 - crcValue = checksum.getSum (); - - printf ("CRC value for map [%s] file [%s] is [%u]\n", - itemName.c_str (), file.c_str (), crcValue); - - return_value = 0; - } - else - { - printf ("Map [%s] was NOT FOUND\n", itemName.c_str ()); - return_value = 1; - } - } - else - { - printf - ("\nInvalid missing map specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - - return_value = 1; - } - } - - else - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - itemName = paramPartTokens[1]; - - Config & config = Config::getInstance (); - uint32 - crcValue = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTilesets, ""), - string ("/") + itemName + string ("/*"), ".xml", NULL, true); - if (crcValue != 0) - { - printf ("CRC value for tileset [%s] is [%u]\n", itemName.c_str (), - crcValue); - - return_value = 0; - } - else - { - printf ("Tileset [%s] was NOT FOUND\n", itemName.c_str ()); - return_value = 1; - } - } - else - { - printf - ("\nInvalid missing tileset specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - - return_value = 1; - } - } - - else - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - itemName = paramPartTokens[1]; - - Config & config = Config::getInstance (); - uint32 - crcValue = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), "/" + itemName + "/*", - ".xml", NULL, true); - if (crcValue != 0) - { - printf ("CRC value for techtree [%s] is [%u]\n", - itemName.c_str (), crcValue); - - return_value = 0; - } - else - { - printf ("Techtree [%s] was NOT FOUND\n", itemName.c_str ()); - - return_value = 1; - } - } - else - { - printf - ("\nInvalid missing techtree specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - - return_value = 1; - } - } - - else - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - itemName = paramPartTokens[1]; - - Config & config = Config::getInstance (); - uint32 - crcValue = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptScenarios, ""), - "/" + itemName + "/*", ".xml", NULL, true); - if (crcValue != 0) - { - printf ("CRC value for scenario [%s] is [%u]\n", - itemName.c_str (), crcValue); - - return_value = 0; - } - else - { - printf ("Scenario [%s] was NOT FOUND\n", itemName.c_str ()); - return_value = 1; - } - } - else - { - printf - ("\nInvalid missing scenario specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - - return_value = 0; - } - } - - else - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]) - == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]), - &foundParamIndIndex); - } - - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 3 && paramPartTokens[1].length () > 0) - { - string - itemName = paramPartTokens[1]; - string - itemNameFilter = paramPartTokens[2]; - uint32 - crcValue = - getFolderTreeContentsCheckSumRecursively (itemName, - itemNameFilter, NULL, - true); - - printf ("CRC value for path [%s] filter [%s] is [%u]\n", - itemName.c_str (), itemNameFilter.c_str (), crcValue); - - return_value = 0; - } - else - { - if (paramPartTokens.size () < 2) - { - printf - ("\nInvalid missing path and filter specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - } - if (paramPartTokens.size () < 3) - { - printf - ("\nInvalid missing filter specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 3 ? paramPartTokens[2].c_str () : NULL)); - } - - return_value = 1; - } - } - - return return_value; - } - - int - handleListDataCommand (int argc, char **argv) - { - int - return_value = 1; - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_LIST_MAPS]) == - true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_LIST_MAPS]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_LIST_MAPS]), - &foundParamIndIndex); - } - - Config & config = Config::getInstance (); - vector < string > pathList = config.getPathListForType (ptMaps, ""); - vector < string > maps = - MapPreview::findAllValidMaps (pathList, "", false, true); - std::sort (maps.begin (), maps.end ()); - - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - itemNameFilter = paramPartTokens[1]; - printf ("Using filter for maps list [%s]\n", - itemNameFilter.c_str ()); - - vector < string > filteredMaps; - for (unsigned int i = 0; i < maps.size (); ++i) - { - string - mapName = maps[i]; - if (itemNameFilter.find ("*") != itemNameFilter.npos) - { - if (StartsWith - (mapName, - itemNameFilter.substr (0, - itemNameFilter.find ("*"))) == true) - { - filteredMaps.push_back (mapName); - } - } - else if (mapName == itemNameFilter) - { - filteredMaps.push_back (mapName); - } - } - maps = filteredMaps; - } - - printf ("Maps found:\n===========================================\n"); - for (unsigned int i = 0; i < maps.size (); ++i) - { - string - mapName = maps[i]; - printf ("%s\n", mapName.c_str ()); - } - printf ("===========================================\nTotal: " - MG_SIZE_T_SPECIFIER "\n", maps.size ()); - - return_value = 0; - } - - else - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_LIST_TECHTRESS]), - &foundParamIndIndex); - } - - Config & config = Config::getInstance (); - vector < string > pathList = config.getPathListForType (ptTechs, ""); - vector < string > results; - findDirs (pathList, results); - - bool - showfactions = false; - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - cmd = paramPartTokens[1]; - if (cmd == "showfactions") - { - showfactions = true; - } - else - { - throw - megaglest_runtime_error ("unknown command for techtreelist [" + - cmd + "]"); - } - printf ("Using special command for techtree list [%s]\n", - cmd.c_str ()); - } - - printf - ("Techtrees found:\n===========================================\n"); - for (unsigned int i = 0; i < results.size (); ++i) - { - string - name = results[i]; - - for (unsigned int j = 0; j < pathList.size (); ++j) - { - string - techPath = pathList[j]; - if (techPath != "") - { - endPathWithSlash (techPath); - } - vector < string > results2; - findDirs (techPath + name + "/factions", results2, false, true); - if (results2.empty () == false) - { - string - downloadArchive = techPath + name + ".7z"; - - if (fileExists (downloadArchive) == true) - { - off_t - fileSize = getFileSize (downloadArchive); -// convert to MB - double - megaBytes = ((double) fileSize / 1048576.0); - printf ("%s [download archive %.2fMB]\n", name.c_str (), - megaBytes); - } - else - { - printf ("%s\n", name.c_str ()); - } - - if (showfactions == true) - { - printf ("--> Factions:\n"); - for (unsigned int k = 0; k < results2.size (); ++k) - { - string - name2 = results2[k]; - printf ("--> %s\n", name2.c_str ()); - } - printf ("--> Total Factions: " MG_SIZE_T_SPECIFIER "\n", - results2.size ()); - break; - } - } - } - } - printf - ("===========================================\nTotal Techtrees: " - MG_SIZE_T_SPECIFIER "\n", results.size ()); - - return_value = 0; - } - - else - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_LIST_SCENARIOS]), - &foundParamIndIndex); - } - - Config & config = Config::getInstance (); - vector < string > pathList = - config.getPathListForType (ptScenarios, ""); - vector < string > results; - findDirs (pathList, results); - - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - itemNameFilter = paramPartTokens[1]; - printf ("Using filter for scenarios list [%s]\n", - itemNameFilter.c_str ()); - - vector < string > filtered; - for (unsigned int i = 0; i < results.size (); ++i) - { - string - name = results[i]; - if (itemNameFilter.find ("*") != itemNameFilter.npos) - { - if (StartsWith - (name, - itemNameFilter.substr (0, - itemNameFilter.find ("*"))) == true) - { - filtered.push_back (name); - } - } - else if (name == itemNameFilter) - { - filtered.push_back (name); - } - } - results = filtered; - } - - printf - ("Scenarios found:\n===========================================\n"); - for (unsigned int i = 0; i < results.size (); ++i) - { - string - name = results[i]; - printf ("%s\n", name.c_str ()); - } - printf ("===========================================\nTotal: " - MG_SIZE_T_SPECIFIER "\n", results.size ()); - - return_value = 0; - } - - else - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_LIST_TILESETS]) - == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_LIST_TILESETS]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_LIST_TILESETS]), - &foundParamIndIndex); - } - - Config & config = Config::getInstance (); - vector < string > pathList = - config.getPathListForType (ptTilesets, ""); - vector < string > results; - findDirs (pathList, results); - - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - itemNameFilter = paramPartTokens[1]; - printf ("Using filter for tilesets list [%s]\n", - itemNameFilter.c_str ()); - - vector < string > filtered; - for (unsigned int i = 0; i < results.size (); ++i) - { - string - name = results[i]; - if (itemNameFilter.find ("*") != itemNameFilter.npos) - { - if (StartsWith - (name, - itemNameFilter.substr (0, - itemNameFilter.find ("*"))) == true) - { - filtered.push_back (name); - } - } - else if (name == itemNameFilter) - { - filtered.push_back (name); - } - } - results = filtered; - } - - printf - ("Tilesets found:\n===========================================\n"); - for (unsigned int i = 0; i < results.size (); ++i) - { - string - name = results[i]; - - for (unsigned int j = 0; j < pathList.size (); ++j) - { - string - tilesetPath = pathList[j]; - if (tilesetPath != "") - { - endPathWithSlash (tilesetPath); - } - if (fileExists (tilesetPath + name + "/" + name + ".xml") == true) - { - string - downloadArchive = tilesetPath + name + ".7z"; - if (fileExists (downloadArchive) == true) - { - off_t - fileSize = getFileSize (downloadArchive); -// convert to MB - double - megaBytes = ((double) fileSize / 1048576.0); - printf ("%s [download archive %.2fMB]\n", name.c_str (), - megaBytes); - } - else - { - printf ("%s\n", name.c_str ()); - } - - break; - } - } - } - printf ("===========================================\nTotal: " - MG_SIZE_T_SPECIFIER "\n", results.size ()); - - return_value = 0; - } - - else - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_LIST_TUTORIALS]), - &foundParamIndIndex); - } - - Config & config = Config::getInstance (); - vector < string > pathList = - config.getPathListForType (ptTutorials, ""); - vector < string > results; - findDirs (pathList, results); - - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - itemNameFilter = paramPartTokens[1]; - printf ("Using filter for tutorials list [%s]\n", - itemNameFilter.c_str ()); - - vector < string > filtered; - for (unsigned int i = 0; i < results.size (); ++i) - { - string - name = results[i]; - if (itemNameFilter.find ("*") != itemNameFilter.npos) - { - if (StartsWith - (name, - itemNameFilter.substr (0, - itemNameFilter.find ("*"))) == true) - { - filtered.push_back (name); - } - } - else if (name == itemNameFilter) - { - filtered.push_back (name); - } - } - results = filtered; - } - - printf - ("Tutorials found:\n===========================================\n"); - for (unsigned int i = 0; i < results.size (); ++i) - { - string - name = results[i]; - - for (unsigned int j = 0; j < pathList.size (); ++j) - { - string - tutorialsPath = pathList[j]; - if (tutorialsPath != "") - { - endPathWithSlash (tutorialsPath); - } - if (fileExists (tutorialsPath + name + "/" + name + ".xml") == - true) - { - string - downloadArchive = tutorialsPath + name + ".7z"; - if (fileExists (downloadArchive) == true) - { - off_t - fileSize = getFileSize (downloadArchive); -// convert to MB - double - megaBytes = ((double) fileSize / 1048576.0); - printf ("%s [download archive %.2fMB]\n", name.c_str (), - megaBytes); - } - else - { - printf ("%s\n", name.c_str ()); - } - - break; - } - } - } - printf ("===========================================\nTotal: " - MG_SIZE_T_SPECIFIER "\n", results.size ()); - - return_value = 0; - } - - return return_value; - } - - int - glestMain (int argc, char **argv) - { + } else { + printf + ("\n** Cannot product techtree translation file [%s] for techPath [%s] techName [%s] because the file already exists!\n", + translationFile.c_str(), techPath.c_str(), + techName.c_str()); + } + } catch (const megaglest_runtime_error & ex) { + printf + ("\n\n****ERROR**** detected while loading the techName: %s\nMESSAGE: %s\n", + techName.c_str(), ex.what()); + } + + } + printf + ("----------------------------------------------------------------"); + } + } + + void + runTechTranslationExtraction(int argc, char **argv) { + printf("====== Started Translation Extraction ======\n"); + + Config & config = Config::getInstance(); + + // Did the user pass a specific list of factions to validate? + std::vector < string > filteredFactionList; + + vector < string > results; + findDirs(config.getPathListForType(ptTechs), results); + vector < string > techTreeFiles = results; + // Did the user pass a specific list of techtrees to validate? + std::vector < string > filteredTechTreeList; + if (hasCommandArgument + (argc, argv, + string(GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) + string("=")) == + true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) + + string("="), &foundParamIndIndex); + string + filterList = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(filterList, paramPartTokens, "="); + if (paramPartTokens.size() >= 2) { + string + techtreeList = paramPartTokens[1]; + Tokenize(techtreeList, filteredTechTreeList, ","); + + if (filteredTechTreeList.empty() == false) { + printf + ("Filtering techtrees and only looking for the following:\n"); + for (int idx = 0; idx < (int) filteredTechTreeList.size(); ++idx) { + filteredTechTreeList[idx] = trim(filteredTechTreeList[idx]); + printf("%s\n", filteredTechTreeList[idx].c_str()); + } + } + } + } + + { + printf + ("\n---------------- Loading factions inside world ----------------"); + World + world; + + vector < string > techPaths = config.getPathListForType(ptTechs); + for (int idx = 0; idx < (int) techPaths.size(); idx++) { + string & techPath = techPaths[idx]; + endPathWithSlash(techPath); + + for (int idx2 = 0; idx2 < (int) techTreeFiles.size(); idx2++) { + string & techName = techTreeFiles[idx2]; + + if (filteredTechTreeList.empty() == true || + std::find(filteredTechTreeList.begin(), + filteredTechTreeList.end(), + techName) != filteredTechTreeList.end()) { + + runTechTranslationExtractionForPath(techPath, techName, + filteredFactionList, + world); + } + } + } + + printf("\n====== Finished Translation ======\n"); + } + + } + + + void + runTechValidationReport(int argc, char **argv) { + printf("====== Started Validation ======\n"); + + bool + purgeDuplicateFiles = false; + bool + showDuplicateFiles = true; + bool + purgeUnusedFiles = false; + bool + gitPurgeFiles = false; + + double + purgedMegaBytes = 0; + Config & config = Config::getInstance(); + + // Did the user pass a specific scenario to validate? + if (hasCommandArgument + (argc, argv, + string(GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) + string("=")) == + true) { + + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) + + string("="), &foundParamIndIndex); + + string + filterList = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(filterList, paramPartTokens, "="); + + if (paramPartTokens.size() >= 2) { + string + validateScenarioName = paramPartTokens[1]; + + printf("Filtering scenario: %s\n", validateScenarioName.c_str()); + + if (paramPartTokens.size() >= 3) { + if (paramPartTokens[2] == "purgeunused") { + purgeUnusedFiles = true; + printf("*NOTE All unused scenario files will be deleted!\n"); + } + } + + { + printf + ("\n---------------- Loading scenario inside world ----------------\n"); + + bool + scenarioFound = false; + World + world; + std::vector < string > filteredFactionList; + + vector < string > scenarioPaths = + config.getPathListForType(ptScenarios); + for (int idx = 0; idx < (int) scenarioPaths.size(); idx++) { + string & scenarioPath = scenarioPaths[idx]; + endPathWithSlash(scenarioPath); + + vector < string > scenarioList; + findDirs(scenarioPath, scenarioList, false, false); + for (int idx2 = 0; idx2 < (int) scenarioList.size(); idx2++) { + string & scenarioName = scenarioList[idx2]; + + if (scenarioName == validateScenarioName) { + scenarioFound = true; + + string + file = + scenarioPath + scenarioName + "/" + scenarioName + ".xml"; + + XmlTree + xmlTree; + xmlTree.load(file, Properties::getTagReplacementValues()); + const XmlNode * + scenarioNode = xmlTree.getRootNode(); + string + techName = + scenarioNode->getChild("tech-tree")-> + getAttribute("value")->getValue(); + + // Self Contained techtree? + string + scenarioTechtree = + scenarioPath + scenarioName + "/" + techName + "/" + + techName + ".xml"; + + printf + ("\nFound Scenario [%s] looking for techtree [%s]...\n", + scenarioName.c_str(), scenarioTechtree.c_str()); + + if (fileExists(scenarioTechtree) == true) { + string + techPath = scenarioPath + scenarioName + "/"; + + printf + ("\nFound Scenario [%s] with custom techtree [%s] validating...\n", + scenarioName.c_str(), techName.c_str()); + runTechValidationForPath(techPath, techName, + filteredFactionList, world, + purgeUnusedFiles, + showDuplicateFiles, false, + false, purgedMegaBytes); + } else { + vector < string > techPaths = + config.getPathListForType(ptTechs); + for (int idx = 0; idx < (int) techPaths.size(); idx++) { + string & techPath = techPaths[idx]; + endPathWithSlash(techPath); + scenarioTechtree = + techPath + "/" + techName + "/" + techName + ".xml"; + if (fileExists(scenarioTechtree) == true) { + printf + ("\nFound Scenario [%s] with techtree [%s] validating...\n", + scenarioName.c_str(), techName.c_str()); + runTechValidationForPath(techPath, techName, + filteredFactionList, world, + purgeUnusedFiles, + showDuplicateFiles, false, + false, purgedMegaBytes); + + break; + } + } + } + } + } + } + + if (scenarioFound == false) { + printf("\nWARNING, the scenario [%s] was NOT FOUND!\n", + validateScenarioName.c_str()); + } + printf("\n====== Finished Validation ======\n"); + } + return; + } else { + printf + ("\nInvalid missing scenario specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + return; + } + } + + // Did the user pass a specific list of factions to validate? + std::vector < string > filteredFactionList; + if (hasCommandArgument + (argc, argv, + string(GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) + string("=")) == + true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) + + string("="), &foundParamIndIndex); + + string + filterList = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(filterList, paramPartTokens, "="); + + if (paramPartTokens.size() >= 2) { + string + factionList = paramPartTokens[1]; + Tokenize(factionList, filteredFactionList, ","); + + if (filteredFactionList.empty() == false) { + printf + ("Filtering factions and only looking for the following:\n"); + for (int idx = 0; idx < (int) filteredFactionList.size(); ++idx) { + filteredFactionList[idx] = trim(filteredFactionList[idx]); + printf("%s\n", filteredFactionList[idx].c_str()); + } + } + + if (paramPartTokens.size() >= 3) { + if (paramPartTokens[2] == "purgeunused") { + purgeUnusedFiles = true; + printf("*NOTE All unused faction files will be deleted!\n"); + } + } + } + } + vector < string > results; + findDirs(config.getPathListForType(ptTechs), results); + vector < string > techTreeFiles = results; + // Did the user pass a specific list of techtrees to validate? + std::vector < string > filteredTechTreeList; + if (hasCommandArgument + (argc, argv, + string(GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) + string("=")) == + true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) + + string("="), &foundParamIndIndex); + string + filterList = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(filterList, paramPartTokens, "="); + if (paramPartTokens.size() >= 2) { + string + techtreeList = paramPartTokens[1]; + Tokenize(techtreeList, filteredTechTreeList, ","); + + if (filteredTechTreeList.empty() == false) { + printf + ("Filtering techtrees and only looking for the following:\n"); + for (int idx = 0; idx < (int) filteredTechTreeList.size(); ++idx) { + filteredTechTreeList[idx] = trim(filteredTechTreeList[idx]); + printf("%s\n", filteredTechTreeList[idx].c_str()); + } + } + + if (paramPartTokens.size() >= 3) { + if (paramPartTokens[2] == "purgeunused") { + purgeUnusedFiles = true; + printf("*NOTE All unused techtree files will be deleted!\n"); + } else if (paramPartTokens[2] == "purgeduplicates") { + purgeDuplicateFiles = true; + printf("*NOTE All duplicate techtree files will be merged!\n"); + } else if (paramPartTokens[2] == "gitdelete") { + gitPurgeFiles = true; + printf + ("*NOTE All unused / duplicate techtree files will be removed from git!\n"); + } else if (paramPartTokens[2] == "hideduplicates") { + showDuplicateFiles = false; + printf + ("*NOTE All duplicate techtree files will NOT be shown!\n"); + } + } + if (paramPartTokens.size() >= 4) { + if (paramPartTokens[3] == "purgeunused") { + purgeUnusedFiles = true; + printf("*NOTE All unused techtree files will be deleted!\n"); + } else if (paramPartTokens[3] == "purgeduplicates") { + purgeDuplicateFiles = true; + printf("*NOTE All duplicate techtree files will be merged!\n"); + } else if (paramPartTokens[3] == "gitdelete") { + gitPurgeFiles = true; + printf + ("*NOTE All unused / duplicate techtree files will be removed from git!\n"); + } else if (paramPartTokens[3] == "hideduplicates") { + showDuplicateFiles = false; + printf + ("*NOTE All duplicate techtree files will NOT be shown!\n"); + } + } + if (paramPartTokens.size() >= 5) { + if (paramPartTokens[4] == "purgeunused") { + purgeUnusedFiles = true; + printf("*NOTE All unused techtree files will be deleted!\n"); + } else if (paramPartTokens[4] == "purgeduplicates") { + purgeDuplicateFiles = true; + printf("*NOTE All duplicate techtree files will be merged!\n"); + } else if (paramPartTokens[4] == "gitdelete") { + gitPurgeFiles = true; + printf + ("*NOTE All unused / duplicate techtree files will be removed from git!\n"); + } else if (paramPartTokens[4] == "hideduplicates") { + showDuplicateFiles = false; + printf + ("*NOTE All duplicate techtree files will NOT be shown!\n"); + } + } + } + } + + { + printf + ("\n---------------- Loading factions inside world ----------------"); + World + world; + + vector < string > techPaths = config.getPathListForType(ptTechs); + for (int idx = 0; idx < (int) techPaths.size(); idx++) { + string & techPath = techPaths[idx]; + endPathWithSlash(techPath); + + for (int idx2 = 0; idx2 < (int) techTreeFiles.size(); idx2++) { + string & techName = techTreeFiles[idx2]; + + if (filteredTechTreeList.empty() == true || + std::find(filteredTechTreeList.begin(), + filteredTechTreeList.end(), + techName) != filteredTechTreeList.end()) { + + runTechValidationForPath(techPath, techName, + filteredFactionList, world, + purgeUnusedFiles, purgeDuplicateFiles, + showDuplicateFiles, gitPurgeFiles, + purgedMegaBytes); + } + } + } + + printf("\n====== Finished Validation ======\n"); + } + + } + + void + runTilesetValidationReport(int argc, char **argv) { + printf("====== Started Validation ======\n"); + + Config & config = Config::getInstance(); + + // Did the user pass a specific tileset to validate? + if (hasCommandArgument + (argc, argv, + string(GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) + string("=")) == + true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) + + string("="), &foundParamIndIndex); + + string + filterList = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(filterList, paramPartTokens, "="); + + if (paramPartTokens.size() >= 2) { + string + validateTilesetName = paramPartTokens[1]; + + printf("Filtering tileset: %s\n", validateTilesetName.c_str()); + + bool + purgeUnusedFiles = false; + if (paramPartTokens.size() >= 3) { + if (paramPartTokens[2] == "purgeunused") { + purgeUnusedFiles = true; + printf("*NOTE All unused tileset files will be deleted!\n"); + } + } + + { + printf + ("\n---------------- Loading tileset inside world ----------------\n"); + + World + world; + double + purgedMegaBytes = 0; + bool + showDuplicateFiles = true; + + bool + tilesetFound = false; + + vector < string > tilesetPaths = + config.getPathListForType(ptTilesets); + for (int idx = 0; idx < (int) tilesetPaths.size(); idx++) { + string & tilesetPath = tilesetPaths[idx]; + endPathWithSlash(tilesetPath); + + vector < string > tilesetList; + findDirs(tilesetPath, tilesetList, false, false); + for (int idx2 = 0; idx2 < (int) tilesetList.size(); idx2++) { + string & tilesetName = tilesetList[idx2]; + if (tilesetName == validateTilesetName) { + tilesetFound = true; + runTilesetValidationForPath(tilesetPath, tilesetName, + world, purgeUnusedFiles, + showDuplicateFiles, false, + false, purgedMegaBytes); + } + } + } + + if (tilesetFound == false) { + printf("*ERROR The specified tileset [%s] was NOT FOUND!\n", + validateTilesetName.c_str()); + } + printf("\n====== Finished Validation ======\n"); + } + return; + } else { + printf + ("\nInvalid missing tileset specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + return; + } + } else { + printf("\nInvalid missing tileset specified on commandline\n\n"); + return; + } + } + + void + ShowINISettings(int argc, char **argv, Config & config, + Config & configKeys) { + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true) { + vector < string > filteredPropertyList; + if (hasCommandArgument + (argc, argv, + string(GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) + string("=")) == + true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) + + string("="), &foundParamIndIndex); + string + filterList = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(filterList, paramPartTokens, "="); + if (paramPartTokens.size() >= 2) { + string + tokenList = paramPartTokens[1]; + Tokenize(tokenList, filteredPropertyList, ","); + + if (filteredPropertyList.empty() == false) { + printf + ("Filtering properties and only looking for the following:\n"); + for (int idx = 0; idx < (int) filteredPropertyList.size(); + ++idx) { + filteredPropertyList[idx] = trim(filteredPropertyList[idx]); + printf("%s\n", filteredPropertyList[idx].c_str()); + } + } + } + } + + printf("\nMain settings report\n"); + printf("====================\n"); + vector < pair < string, string > >mergedMainSettings = + config.getMergedProperties(); + vector < pair < string, string > >mergedKeySettings = + configKeys.getMergedProperties(); + + // Figure out the max # of tabs we need to format display nicely + int + tabCount = 1; + for (int i = 0; i < (int) mergedMainSettings.size(); ++i) { + const + pair < + string, + string > & + nameValue = mergedMainSettings[i]; + + bool + displayProperty = false; + if (filteredPropertyList.empty() == false) { + if (find + (filteredPropertyList.begin(), filteredPropertyList.end(), + nameValue.first) != filteredPropertyList.end()) { + displayProperty = true; + } + } else { + displayProperty = true; + } + + if (displayProperty == true) { + int + requredTabs = ((int) nameValue.first.length() / 8) + 1; + if (nameValue.first.length() % 8) { + requredTabs++; + } + if (requredTabs > tabCount) { + tabCount = requredTabs; + } + } + } + for (int i = 0; i < (int) mergedKeySettings.size(); ++i) { + const + pair < + string, + string > & + nameValue = mergedKeySettings[i]; + + bool + displayProperty = false; + if (filteredPropertyList.empty() == false) { + if (find + (filteredPropertyList.begin(), filteredPropertyList.end(), + nameValue.first) != filteredPropertyList.end()) { + displayProperty = true; + } + } else { + displayProperty = true; + } + + if (displayProperty == true) { + int + requredTabs = ((int) nameValue.first.length() / 8) + 1; + if (nameValue.first.length() % 8) { + requredTabs++; + } + if (requredTabs > tabCount) { + tabCount = requredTabs; + } + } + } + + // Output the properties + for (int i = 0; i < (int) mergedMainSettings.size(); ++i) { + const + pair < + string, + string > & + nameValue = mergedMainSettings[i]; + + bool + displayProperty = false; + if (filteredPropertyList.empty() == false) { + if (find + (filteredPropertyList.begin(), filteredPropertyList.end(), + nameValue.first) != filteredPropertyList.end()) { + displayProperty = true; + } + } else { + displayProperty = true; + } + + if (displayProperty == true) { + printf("Property Name [%s]", nameValue.first.c_str()); + + int + tabs = ((int) nameValue.first.length() / 8) + 1; + for (int j = 0; j < (tabCount - tabs); ++j) { + printf("\t"); + } + + string + displayValue = nameValue.second; + if (nameValue.first == "TranslationGetURLPassword") { + displayValue = "*****"; + } + + printf("Value [%s]\n", displayValue.c_str()); + } + } + + printf("\n\nMain key binding settings report\n"); + printf("====================================\n"); + + for (int i = 0; i < (int) mergedKeySettings.size(); ++i) { + const + pair < + string, + string > & + nameValue = mergedKeySettings[i]; + + bool + displayProperty = false; + if (filteredPropertyList.empty() == false) { + if (find + (filteredPropertyList.begin(), filteredPropertyList.end(), + nameValue.first) != filteredPropertyList.end()) { + displayProperty = true; + } + } else { + displayProperty = true; + } + + if (displayProperty == true) { + printf("Property Name [%s]", nameValue.first.c_str()); + + int + tabs = ((int) nameValue.first.length() / 8) + 1; + for (int j = 0; j < (tabCount - tabs); ++j) { + printf("\t"); + } + + printf("Value [%s]\n", nameValue.second.c_str()); + } + } + } + } + + Steam & initSteamInstance() { + Steam *& + steamInstance = + CacheManager::getCachedItem < + Steam * >(GameConstants::steamCacheInstanceKey); + if (steamInstance == NULL) { + steamInstance = new Steam(); + } + return *steamInstance; + } + + void + setupSteamSettings(bool steamEnabled, bool steamResetStats, + bool debugEnabled) { + Config & config = Config::getInstance(); + config.setBool("SteamEnabled", steamEnabled, true); + if (steamEnabled) { + printf("*NOTE: Steam Integration Enabled.\n"); + + if (debugEnabled) { + printf("*NOTE: Steam Debugging Enabled.\n"); + } + Steam::setDebugEnabled(debugEnabled); + + Steam & steam = initSteamInstance(); + + // For Debugging purposes: + if (steamResetStats) { + printf + ("*WARNING: Steam Stats / Achievements are being RESET by request!\n"); + steam.resetStats(true); + } + + string + steamPlayerName = steam.userName(); + string + steamLang = steam.lang(); + printf + ("Steam Integration Enabled!\nSteam User Name is [%s] Language is [%s]\n", + steamPlayerName.c_str(), steamLang.c_str()); + + bool + needToSaveConfig = false; + string + currentPLayerName = config.getString("NetPlayerName", ""); + if (currentPLayerName == "newbie" || currentPLayerName == "") { + config.setString("NetPlayerName", steamPlayerName); + needToSaveConfig = true; + } + if (needToSaveConfig == true) { + config.save(); + } + } + } + + void + CheckForDuplicateData() { + Config & config = Config::getInstance(); + + string + duplicateWarnings = ""; + + try { + + + { + + string + scenarioDir = ""; + vector < string > pathList = + config.getPathListForType(ptMaps, scenarioDir); + vector < string > invalidMapList; + vector < string > maps = + MapPreview::findAllValidMaps(pathList, scenarioDir, false, true, + &invalidMapList); + std::sort(maps.begin(), maps.end()); + + if (maps.empty() == true) { + throw + megaglest_runtime_error("No maps were found!", true); + } else if (invalidMapList.empty() == false) { + string + errorMsg = + "Warning invalid maps were detected (will be ignored):\n"; + for (int i = 0; i < (int) invalidMapList.size(); ++i) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "map [%s]\n", + invalidMapList[i].c_str()); + + errorMsg += szBuf; + } + duplicateWarnings += errorMsg; + } + + vector < string > duplicateMapsToRename; + for (int i = 0; i < (int) maps.size(); ++i) { + string + map1 = maps[i]; + for (int j = 0; j < (int) maps.size(); ++j) { + if (i != j) { + string + map2 = maps[j]; + + if (map1 == map2) { + if (std::find(duplicateMapsToRename.begin(), + duplicateMapsToRename.end(), + map1) == duplicateMapsToRename.end()) { + duplicateMapsToRename.push_back(map1); + } + } + } + } + } + if (duplicateMapsToRename.empty() == false) { + string + errorMsg = + "Warning duplicate maps were detected and renamed:\n"; + for (int i = 0; i < (int) duplicateMapsToRename.size(); ++i) { + string + currentPath = pathList[1]; + endPathWithSlash(currentPath); + + string + oldFile = currentPath + duplicateMapsToRename[i]; + string + newFile = currentPath + duplicateMapsToRename[i]; + string + ext = extractExtension(newFile); + newFile = + newFile.substr(0, newFile.length() - ext.length() - 1); + newFile = newFile + "_custom." + ext; + + char + szBuf[8096] = ""; + int + result = rename(oldFile.c_str(), newFile.c_str()); + if (result != 0) { + char * + errmsg = strerror(errno); + snprintf(szBuf, 8096, + "Error [%s]\nCould not rename [%s] to [%s]!", + errmsg, oldFile.c_str(), newFile.c_str()); + throw + megaglest_runtime_error(szBuf, true); + } else { + snprintf(szBuf, 8096, + "map [%s] in [%s]\nwas renamed to [%s]", + duplicateMapsToRename[i].c_str(), oldFile.c_str(), + newFile.c_str()); + } + errorMsg += szBuf; + } + duplicateWarnings += errorMsg; + } + } + + { + //tilesets + std::vector < std::string > tileSets; + vector < string > tilesetPaths = + config.getPathListForType(ptTilesets); + findDirs(tilesetPaths, tileSets, false, true); + + if (tileSets.empty()) { + throw + megaglest_runtime_error("No tilesets were found!", true); + } + + vector < string > duplicateTilesetsToRename; + for (int i = 0; i < (int) tileSets.size(); ++i) { + string + tileSet1 = tileSets[i]; + for (int j = 0; j < (int) tileSets.size(); ++j) { + if (i != j) { + string + tileSet2 = tileSets[j]; + if (tileSet1 == tileSet2) { + if (std::find(duplicateTilesetsToRename.begin(), + duplicateTilesetsToRename.end(), + tileSet1) == + duplicateTilesetsToRename.end()) { + duplicateTilesetsToRename.push_back(tileSet1); + } + } + } + } + } + if (duplicateTilesetsToRename.empty() == false) { + string + errorMsg = + "Warning duplicate tilesets were detected and renamed:\n"; + + for (int i = 0; i < (int) duplicateTilesetsToRename.size(); ++i) { + string + currentPath = tilesetPaths[1]; + endPathWithSlash(currentPath); + + string + oldFile = currentPath + duplicateTilesetsToRename[i]; + string + newFile = currentPath + duplicateTilesetsToRename[i]; + newFile = newFile + "_custom"; + + char + szBuf[8096] = ""; + int + result = rename(oldFile.c_str(), newFile.c_str()); + if (result != 0) { + char * + errmsg = strerror(errno); + snprintf(szBuf, 8096, + "Error [%s]\nCould not rename [%s] to [%s]!", + errmsg, oldFile.c_str(), newFile.c_str()); + throw + megaglest_runtime_error(szBuf, true); + } else { + snprintf(szBuf, 8096, + "tileset [%s] in [%s]\nwas renamed to [%s]", + duplicateTilesetsToRename[i].c_str(), + oldFile.c_str(), newFile.c_str()); + + string + tilesetName = extractFileFromDirectoryPath(oldFile); + oldFile = newFile + "/" + tilesetName + ".xml"; + newFile = newFile + "/" + tilesetName + "_custom.xml"; + + result = rename(oldFile.c_str(), newFile.c_str()); + + if (result != 0) { + char * + errmsg = strerror(errno); + snprintf(szBuf, 8096, + "Error [%s]\nCould not rename [%s] to [%s]!", + errmsg, oldFile.c_str(), newFile.c_str()); + throw + megaglest_runtime_error(szBuf, true); + } + + } + errorMsg += szBuf; + } + duplicateWarnings += errorMsg; + } + } + + { + vector < string > techPaths = config.getPathListForType(ptTechs); + vector < string > techTrees; + findDirs(techPaths, techTrees, false, true); + if (techTrees.empty()) { + throw + megaglest_runtime_error("No tech-trees were found (dup)!", + true); + } + + vector < string > duplicateTechtreesToRename; + for (int i = 0; i < (int) techTrees.size(); ++i) { + string + techtree1 = techTrees[i]; + for (int j = 0; j < (int) techTrees.size(); ++j) { + if (i != j) { + string + techtree2 = techTrees[j]; + if (techtree1 == techtree2) { + if (std::find(duplicateTechtreesToRename.begin(), + duplicateTechtreesToRename.end(), + techtree1) == + duplicateTechtreesToRename.end()) { + duplicateTechtreesToRename.push_back(techtree1); + } + } + } + } + } + if (duplicateTechtreesToRename.empty() == false) { + string + errorMsg = + "Warning duplicate techtrees were detected and renamed:\n"; + + for (int i = 0; i < (int) duplicateTechtreesToRename.size(); ++i) { + string + currentPath = techPaths[1]; + endPathWithSlash(currentPath); + + string + oldFile = currentPath + duplicateTechtreesToRename[i]; + string + newFile = currentPath + duplicateTechtreesToRename[i]; + newFile = newFile + "_custom"; + + char + szBuf[8096] = ""; + int + result = rename(oldFile.c_str(), newFile.c_str()); + if (result != 0) { + char * + errmsg = strerror(errno); + snprintf(szBuf, 8096, + "Error [%s]\nCould not rename [%s] to [%s]!", + errmsg, oldFile.c_str(), newFile.c_str()); + throw + megaglest_runtime_error(szBuf, true); + } else { + snprintf(szBuf, 8096, + "techtree [%s] in [%s]\nwas renamed to [%s]", + duplicateTechtreesToRename[i].c_str(), + oldFile.c_str(), newFile.c_str()); + + string + tilesetName = extractFileFromDirectoryPath(oldFile); + oldFile = newFile + "/" + tilesetName + ".xml"; + newFile = newFile + "/" + tilesetName + "_custom.xml"; + + int + rename_result = rename(oldFile.c_str(), newFile.c_str()); + if (rename_result != 0) { + printf("Error renaming [%s] to [%s]\n", oldFile.c_str(), + newFile.c_str()); + } + } + errorMsg += szBuf; + } + duplicateWarnings += errorMsg; + } + } + + } catch (const megaglest_runtime_error & ex) { + if (mainProgram) { + mainProgram->getState()->setForceMouseRender(true); + } + ExceptionHandler::DisplayMessage(ex.what(), false); + } + + if (duplicateWarnings != "") { + if (mainProgram) { + mainProgram->getState()->setForceMouseRender(true); + } + ExceptionHandler::DisplayMessage(duplicateWarnings.c_str(), false); + } + } + + int + handleCreateDataArchivesCommand(int argc, char **argv) { + int + return_value = 1; + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS + [GAME_ARG_CREATE_DATA_ARCHIVES]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + compress_item = paramPartTokens[1]; + bool + includeMainData = false; + if (paramPartTokens.size() >= 3 + && paramPartTokens[2] == "include_main") { + includeMainData = true; + } + + Config & config = Config::getInstance(); + string + fileArchiveExtension = + config.getString("FileArchiveExtension", ""); + string + fileArchiveCompressCommand = + config.getString("FileArchiveCompressCommand", ""); + string + fileArchiveCompressCommandParameters = + config.getString("FileArchiveCompressCommandParameters", ""); + int32 + fileArchiveCompressCommandSuccessResult = + config.getInt("FileArchiveCompressCommandSuccessResult", "0"); + + string + userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + + int + typesSelected = 0; + if (compress_item == "techtrees" || compress_item == "all") { + typesSelected++; + + vector < string > pathList = + config.getPathListForType(ptTechs, ""); + vector < string > results; + findDirs(pathList, results); + + printf + ("Techtrees found:\n===========================================\n"); + for (unsigned int i = 0; i < results.size(); ++i) { + string + name = results[i]; + + for (unsigned int j = 0; j < pathList.size(); ++j) { + string + techPath = pathList[j]; + if (techPath != "") { + endPathWithSlash(techPath); + } + + vector < string > results2; + findDirs(techPath + name + "/factions", results2, false, + true); + if (results2.empty() == false) { + string + techtreePath = techPath + name; + if (includeMainData == false) { + if (techtreePath.find(userData) == techPath.npos) { + printf("Skipping techtree: [%s]\n", + techtreePath.c_str()); + continue; + } + } + + string + downloadArchive = techtreePath + fileArchiveExtension; + + if (fileExists(downloadArchive) == true) { + bool + removed = removeFile(downloadArchive); + if (removed == false) { + printf("Error could not remove old file: [%s]\n", + downloadArchive.c_str()); + } + } + string + compressCmd = + getFullFileArchiveCompressCommand + (fileArchiveCompressCommand, + fileArchiveCompressCommandParameters, + downloadArchive, techtreePath); + + printf("Running compression command: %s\n", + compressCmd.c_str()); + + if (executeShellCommand + (compressCmd, + fileArchiveCompressCommandSuccessResult) == false) { + printf("Error could not create new file: [%s]\n", + downloadArchive.c_str()); + } + + if (fileExists(downloadArchive) == true) { + off_t + fileSize = getFileSize(downloadArchive); + // convert to MB + double + megaBytes = ((double) fileSize / 1048576.0); + printf("%s [download archive %.2fMB]\n", name.c_str(), + megaBytes); + } + } + } + } + printf("===========================================\nTotal: " + MG_SIZE_T_SPECIFIER "\n", results.size()); + } + if (compress_item == "tilesets" || compress_item == "all") { + typesSelected++; + + vector < string > pathList = + config.getPathListForType(ptTilesets, ""); + vector < string > results; + findDirs(pathList, results); + + printf + ("Tilesets found:\n===========================================\n"); + for (unsigned int i = 0; i < results.size(); ++i) { + string + name = results[i]; + + for (unsigned int j = 0; j < pathList.size(); ++j) { + string + tilesetPath = pathList[j]; + if (tilesetPath != "") { + endPathWithSlash(tilesetPath); + } + + if (fileExists(tilesetPath + name + "/" + name + ".xml") == + true) { + string + tilesetDataPath = tilesetPath + name; + if (includeMainData == false) { + if (tilesetPath.find(userData) == tilesetPath.npos) { + printf("Skipping tileset data: [%s]\n", + tilesetDataPath.c_str()); + continue; + } + } + + string + downloadArchive = tilesetDataPath + fileArchiveExtension; + + if (fileExists(downloadArchive) == true) { + bool + removed = removeFile(downloadArchive); + if (removed == false) { + printf("Error could not remove old file: [%s]\n", + downloadArchive.c_str()); + } + } + string + compressCmd = + getFullFileArchiveCompressCommand + (fileArchiveCompressCommand, + fileArchiveCompressCommandParameters, + downloadArchive, tilesetDataPath); + + printf("Running compression command: %s\n", + compressCmd.c_str()); + + if (executeShellCommand + (compressCmd, + fileArchiveCompressCommandSuccessResult) == false) { + printf("Error could not create new file: [%s]\n", + downloadArchive.c_str()); + } + + if (fileExists(downloadArchive) == true) { + off_t + fileSize = getFileSize(downloadArchive); + // convert to MB + double + megaBytes = ((double) fileSize / 1048576.0); + printf("%s [download archive %.2fMB]\n", name.c_str(), + megaBytes); + } + + break; + } + } + } + printf("===========================================\nTotal: " + MG_SIZE_T_SPECIFIER "\n", results.size()); + + } + if (typesSelected == 0) { + printf("Compress item [%s] is not valid!\n", + compress_item.c_str()); + return_value = 1; + } else + return_value = 0; + } else { + printf + ("\nInvalid missing map specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + + return_value = 1; + } + } + + return return_value; + } + + int + handleShowCRCValuesCommand(int argc, char **argv) { + int + return_value = 1; + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]) == + true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + itemName = paramPartTokens[1]; + + string + file = Config::getMapPath(itemName, "", false); + if (file != "") { + Checksum + checksum; + checksum.addFile(file); + uint32 + crcValue = checksum.getSum(); + + printf("CRC value for map [%s] file [%s] is [%u]\n", + itemName.c_str(), file.c_str(), crcValue); + + return_value = 0; + } else { + printf("Map [%s] was NOT FOUND\n", itemName.c_str()); + return_value = 1; + } + } else { + printf + ("\nInvalid missing map specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + + return_value = 1; + } + } + + else + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + itemName = paramPartTokens[1]; + + Config & config = Config::getInstance(); + uint32 + crcValue = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTilesets, ""), + string("/") + itemName + string("/*"), ".xml", NULL, true); + if (crcValue != 0) { + printf("CRC value for tileset [%s] is [%u]\n", itemName.c_str(), + crcValue); + + return_value = 0; + } else { + printf("Tileset [%s] was NOT FOUND\n", itemName.c_str()); + return_value = 1; + } + } else { + printf + ("\nInvalid missing tileset specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + + return_value = 1; + } + } + + else + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + itemName = paramPartTokens[1]; + + Config & config = Config::getInstance(); + uint32 + crcValue = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), "/" + itemName + "/*", + ".xml", NULL, true); + if (crcValue != 0) { + printf("CRC value for techtree [%s] is [%u]\n", + itemName.c_str(), crcValue); + + return_value = 0; + } else { + printf("Techtree [%s] was NOT FOUND\n", itemName.c_str()); + + return_value = 1; + } + } else { + printf + ("\nInvalid missing techtree specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + + return_value = 1; + } + } + + else + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + itemName = paramPartTokens[1]; + + Config & config = Config::getInstance(); + uint32 + crcValue = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptScenarios, ""), + "/" + itemName + "/*", ".xml", NULL, true); + if (crcValue != 0) { + printf("CRC value for scenario [%s] is [%u]\n", + itemName.c_str(), crcValue); + + return_value = 0; + } else { + printf("Scenario [%s] was NOT FOUND\n", itemName.c_str()); + return_value = 1; + } + } else { + printf + ("\nInvalid missing scenario specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + + return_value = 0; + } + } + + else + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]) + == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]), + &foundParamIndIndex); + } + + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 3 && paramPartTokens[1].length() > 0) { + string + itemName = paramPartTokens[1]; + string + itemNameFilter = paramPartTokens[2]; + uint32 + crcValue = + getFolderTreeContentsCheckSumRecursively(itemName, + itemNameFilter, NULL, + true); + + printf("CRC value for path [%s] filter [%s] is [%u]\n", + itemName.c_str(), itemNameFilter.c_str(), crcValue); + + return_value = 0; + } else { + if (paramPartTokens.size() < 2) { + printf + ("\nInvalid missing path and filter specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + } + if (paramPartTokens.size() < 3) { + printf + ("\nInvalid missing filter specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 3 ? paramPartTokens[2].c_str() : NULL)); + } + + return_value = 1; + } + } + + return return_value; + } + + int + handleListDataCommand(int argc, char **argv) { + int + return_value = 1; + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_LIST_MAPS]) == + true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_LIST_MAPS]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_LIST_MAPS]), + &foundParamIndIndex); + } + + Config & config = Config::getInstance(); + vector < string > pathList = config.getPathListForType(ptMaps, ""); + vector < string > maps = + MapPreview::findAllValidMaps(pathList, "", false, true); + std::sort(maps.begin(), maps.end()); + + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + itemNameFilter = paramPartTokens[1]; + printf("Using filter for maps list [%s]\n", + itemNameFilter.c_str()); + + vector < string > filteredMaps; + for (unsigned int i = 0; i < maps.size(); ++i) { + string + mapName = maps[i]; + if (itemNameFilter.find("*") != itemNameFilter.npos) { + if (StartsWith + (mapName, + itemNameFilter.substr(0, + itemNameFilter.find("*"))) == true) { + filteredMaps.push_back(mapName); + } + } else if (mapName == itemNameFilter) { + filteredMaps.push_back(mapName); + } + } + maps = filteredMaps; + } + + printf("Maps found:\n===========================================\n"); + for (unsigned int i = 0; i < maps.size(); ++i) { + string + mapName = maps[i]; + printf("%s\n", mapName.c_str()); + } + printf("===========================================\nTotal: " + MG_SIZE_T_SPECIFIER "\n", maps.size()); + + return_value = 0; + } + + else + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_LIST_TECHTRESS]), + &foundParamIndIndex); + } + + Config & config = Config::getInstance(); + vector < string > pathList = config.getPathListForType(ptTechs, ""); + vector < string > results; + findDirs(pathList, results); + + bool + showfactions = false; + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + cmd = paramPartTokens[1]; + if (cmd == "showfactions") { + showfactions = true; + } else { + throw + megaglest_runtime_error("unknown command for techtreelist [" + + cmd + "]"); + } + printf("Using special command for techtree list [%s]\n", + cmd.c_str()); + } + + printf + ("Techtrees found:\n===========================================\n"); + for (unsigned int i = 0; i < results.size(); ++i) { + string + name = results[i]; + + for (unsigned int j = 0; j < pathList.size(); ++j) { + string + techPath = pathList[j]; + if (techPath != "") { + endPathWithSlash(techPath); + } + vector < string > results2; + findDirs(techPath + name + "/factions", results2, false, true); + if (results2.empty() == false) { + string + downloadArchive = techPath + name + ".7z"; + + if (fileExists(downloadArchive) == true) { + off_t + fileSize = getFileSize(downloadArchive); + // convert to MB + double + megaBytes = ((double) fileSize / 1048576.0); + printf("%s [download archive %.2fMB]\n", name.c_str(), + megaBytes); + } else { + printf("%s\n", name.c_str()); + } + + if (showfactions == true) { + printf("--> Factions:\n"); + for (unsigned int k = 0; k < results2.size(); ++k) { + string + name2 = results2[k]; + printf("--> %s\n", name2.c_str()); + } + printf("--> Total Factions: " MG_SIZE_T_SPECIFIER "\n", + results2.size()); + break; + } + } + } + } + printf + ("===========================================\nTotal Techtrees: " + MG_SIZE_T_SPECIFIER "\n", results.size()); + + return_value = 0; + } + + else + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_LIST_SCENARIOS]), + &foundParamIndIndex); + } + + Config & config = Config::getInstance(); + vector < string > pathList = + config.getPathListForType(ptScenarios, ""); + vector < string > results; + findDirs(pathList, results); + + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + itemNameFilter = paramPartTokens[1]; + printf("Using filter for scenarios list [%s]\n", + itemNameFilter.c_str()); + + vector < string > filtered; + for (unsigned int i = 0; i < results.size(); ++i) { + string + name = results[i]; + if (itemNameFilter.find("*") != itemNameFilter.npos) { + if (StartsWith + (name, + itemNameFilter.substr(0, + itemNameFilter.find("*"))) == true) { + filtered.push_back(name); + } + } else if (name == itemNameFilter) { + filtered.push_back(name); + } + } + results = filtered; + } + + printf + ("Scenarios found:\n===========================================\n"); + for (unsigned int i = 0; i < results.size(); ++i) { + string + name = results[i]; + printf("%s\n", name.c_str()); + } + printf("===========================================\nTotal: " + MG_SIZE_T_SPECIFIER "\n", results.size()); + + return_value = 0; + } + + else + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_LIST_TILESETS]) + == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_LIST_TILESETS]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_LIST_TILESETS]), + &foundParamIndIndex); + } + + Config & config = Config::getInstance(); + vector < string > pathList = + config.getPathListForType(ptTilesets, ""); + vector < string > results; + findDirs(pathList, results); + + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + itemNameFilter = paramPartTokens[1]; + printf("Using filter for tilesets list [%s]\n", + itemNameFilter.c_str()); + + vector < string > filtered; + for (unsigned int i = 0; i < results.size(); ++i) { + string + name = results[i]; + if (itemNameFilter.find("*") != itemNameFilter.npos) { + if (StartsWith + (name, + itemNameFilter.substr(0, + itemNameFilter.find("*"))) == true) { + filtered.push_back(name); + } + } else if (name == itemNameFilter) { + filtered.push_back(name); + } + } + results = filtered; + } + + printf + ("Tilesets found:\n===========================================\n"); + for (unsigned int i = 0; i < results.size(); ++i) { + string + name = results[i]; + + for (unsigned int j = 0; j < pathList.size(); ++j) { + string + tilesetPath = pathList[j]; + if (tilesetPath != "") { + endPathWithSlash(tilesetPath); + } + if (fileExists(tilesetPath + name + "/" + name + ".xml") == true) { + string + downloadArchive = tilesetPath + name + ".7z"; + if (fileExists(downloadArchive) == true) { + off_t + fileSize = getFileSize(downloadArchive); + // convert to MB + double + megaBytes = ((double) fileSize / 1048576.0); + printf("%s [download archive %.2fMB]\n", name.c_str(), + megaBytes); + } else { + printf("%s\n", name.c_str()); + } + + break; + } + } + } + printf("===========================================\nTotal: " + MG_SIZE_T_SPECIFIER "\n", results.size()); + + return_value = 0; + } + + else + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_LIST_TUTORIALS]), + &foundParamIndIndex); + } + + Config & config = Config::getInstance(); + vector < string > pathList = + config.getPathListForType(ptTutorials, ""); + vector < string > results; + findDirs(pathList, results); + + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + itemNameFilter = paramPartTokens[1]; + printf("Using filter for tutorials list [%s]\n", + itemNameFilter.c_str()); + + vector < string > filtered; + for (unsigned int i = 0; i < results.size(); ++i) { + string + name = results[i]; + if (itemNameFilter.find("*") != itemNameFilter.npos) { + if (StartsWith + (name, + itemNameFilter.substr(0, + itemNameFilter.find("*"))) == true) { + filtered.push_back(name); + } + } else if (name == itemNameFilter) { + filtered.push_back(name); + } + } + results = filtered; + } + + printf + ("Tutorials found:\n===========================================\n"); + for (unsigned int i = 0; i < results.size(); ++i) { + string + name = results[i]; + + for (unsigned int j = 0; j < pathList.size(); ++j) { + string + tutorialsPath = pathList[j]; + if (tutorialsPath != "") { + endPathWithSlash(tutorialsPath); + } + if (fileExists(tutorialsPath + name + "/" + name + ".xml") == + true) { + string + downloadArchive = tutorialsPath + name + ".7z"; + if (fileExists(downloadArchive) == true) { + off_t + fileSize = getFileSize(downloadArchive); + // convert to MB + double + megaBytes = ((double) fileSize / 1048576.0); + printf("%s [download archive %.2fMB]\n", name.c_str(), + megaBytes); + } else { + printf("%s\n", name.c_str()); + } + + break; + } + } + } + printf("===========================================\nTotal: " + MG_SIZE_T_SPECIFIER "\n", results.size()); + + return_value = 0; + } + + return return_value; + } + + int + glestMain(int argc, char **argv) { #ifdef SL_LEAK_DUMP -//AllocInfo::set_application_binary(executable_path(argv[0],true)); - string & app = AllocInfo::get_application_binary (); - app = executable_path (argv[0], true); -//want_full_leak_stacktrace = true; -//want_full_leak_stacktrace_line_numbers = true; + //AllocInfo::set_application_binary(executable_path(argv[0],true)); + string & app = AllocInfo::get_application_binary(); + app = executable_path(argv[0], true); + //want_full_leak_stacktrace = true; + //want_full_leak_stacktrace_line_numbers = true; #endif - Thread::setMainThreadId (); -// printf("START ALLOC char 200\n"); -//char *ptr = new char[200]; -// printf("END ALLOC char 200\n"); -// return -1; - SystemFlags::VERBOSE_MODE_ENABLED = false; - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_VERBOSE_MODE]) == - true) - { - SystemFlags::VERBOSE_MODE_ENABLED = true; - Thread::setEnableVerboseMode (true); -//LuaScript::setDebugModeEnabled(true); - } -// DEbug testing threads -//Thread::setEnableVerboseMode(true); + Thread::setMainThreadId(); + // printf("START ALLOC char 200\n"); + //char *ptr = new char[200]; + // printf("END ALLOC char 200\n"); + // return -1; + SystemFlags::VERBOSE_MODE_ENABLED = false; + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_VERBOSE_MODE]) == + true) { + SystemFlags::VERBOSE_MODE_ENABLED = true; + Thread::setEnableVerboseMode(true); + //LuaScript::setDebugModeEnabled(true); + } + // DEbug testing threads + //Thread::setEnableVerboseMode(true); - PlatformExceptionHandler::application_binary = - executable_path (argv[0], true); - mg_app_name = GameConstants::application_name; - mailStringSupport = mailString; - SystemFlags::ENABLE_THREADED_LOGGING = false; - disableBacktrace = false; - bool - foundInvalidArgs = false; - preCacheThread = NULL; + PlatformExceptionHandler::application_binary = + executable_path(argv[0], true); + mg_app_name = GameConstants::application_name; + mailStringSupport = mailString; + SystemFlags::ENABLE_THREADED_LOGGING = false; + disableBacktrace = false; + bool + foundInvalidArgs = false; + preCacheThread = NULL; - Properties::setApplicationPath (executable_path (argv[0])); - Properties::setApplicationDataPath (executable_path (argv[0])); - Properties::setGameVersion (glestVersionString); + Properties::setApplicationPath(executable_path(argv[0])); + Properties::setApplicationDataPath(executable_path(argv[0])); + Properties::setGameVersion(glestVersionString); - ServerSocket::setMaxPlayerCount (GameConstants::maxPlayers); + ServerSocket::setMaxPlayerCount(GameConstants::maxPlayers); - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_DISABLE_BACKTRACE]) == true) - { - disableBacktrace = true; - } - PlatformExceptionHandler::disableBacktrace = disableBacktrace; + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_DISABLE_BACKTRACE]) == true) { + disableBacktrace = true; + } + PlatformExceptionHandler::disableBacktrace = disableBacktrace; #if defined(CUSTOM_DATA_INSTALL_PATH) - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\n\nCUSTOM_DATA_INSTALL_PATH = [%s]\n\n", - formatPath (TOSTRING (CUSTOM_DATA_INSTALL_PATH)).c_str ()); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\n\nCUSTOM_DATA_INSTALL_PATH = [%s]\n\n", + formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)).c_str()); #endif - const int - knownArgCount = sizeof (GAME_ARGS) / sizeof (GAME_ARGS[0]); - for (int idx = 1; idx < argc; ++idx) - { - if (hasCommandArgument - (knownArgCount, (char **) &GAME_ARGS[0], argv[idx], NULL, 0, - true) == false) - { - foundInvalidArgs = true; - printf ("\nInvalid argument: %s", argv[idx]); - } - } + const int + knownArgCount = sizeof(GAME_ARGS) / sizeof(GAME_ARGS[0]); + for (int idx = 1; idx < argc; ++idx) { + if (hasCommandArgument + (knownArgCount, (char **) &GAME_ARGS[0], argv[idx], NULL, 0, + true) == false) { + foundInvalidArgs = true; + printf("\nInvalid argument: %s", argv[idx]); + } + } - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_HELP]) == true || - foundInvalidArgs == true) - { + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_HELP]) == true || + foundInvalidArgs == true) { - printParameterHelp (argv[0], foundInvalidArgs); - return 2; - } + printParameterHelp(argv[0], foundInvalidArgs); + return 2; + } - if (hasCommandArgument - (argc, argv, - string (GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) - { -//isMasterServerModeEnabled = true; -//Window::setMasterserverMode(isMasterServerModeEnabled); - GlobalStaticFlags::setIsNonGraphicalModeEnabled (true); + if (hasCommandArgument + (argc, argv, + string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) { + //isMasterServerModeEnabled = true; + //Window::setMasterserverMode(isMasterServerModeEnabled); + GlobalStaticFlags::setIsNonGraphicalModeEnabled(true); - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_MASTERSERVER_MODE]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_MASTERSERVER_MODE]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - headless_command_list = paramPartTokens[1]; + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + headless_command_list = paramPartTokens[1]; - vector < string > paramHeadlessCommandList; - Tokenize (headless_command_list, paramHeadlessCommandList, ","); + vector < string > paramHeadlessCommandList; + Tokenize(headless_command_list, paramHeadlessCommandList, ","); - for (unsigned int i = 0; i < paramHeadlessCommandList.size (); ++i) - { - string - headless_command = paramHeadlessCommandList[i]; - if (headless_command == "exit") - { - printf ("Forcing quit after game has completed [%s]\n", - headless_command.c_str ()); - Program::setWantShutdownApplicationAfterGame (true); - } - else if (headless_command == "vps") - { - printf ("Disabled reading from console [%s]\n", - headless_command.c_str ()); - disableheadless_console = true; - } - else if (headless_command == "lan") - { - printf ("Forcing local LAN mode [%s]\n", - headless_command.c_str ()); - GlobalStaticFlags::setFlag (gsft_lan_mode); - } - } - } - } + for (unsigned int i = 0; i < paramHeadlessCommandList.size(); ++i) { + string + headless_command = paramHeadlessCommandList[i]; + if (headless_command == "exit") { + printf("Forcing quit after game has completed [%s]\n", + headless_command.c_str()); + Program::setWantShutdownApplicationAfterGame(true); + } else if (headless_command == "vps") { + printf("Disabled reading from console [%s]\n", + headless_command.c_str()); + disableheadless_console = true; + } else if (headless_command == "lan") { + printf("Forcing local LAN mode [%s]\n", + headless_command.c_str()); + GlobalStaticFlags::setFlag(gsft_lan_mode); + } + } + } + } - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_SERVER_TITLE]) == - true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_SERVER_TITLE]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_SERVER_TITLE]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - Config & config = Config::getInstance (); - string - serverTitle = paramPartTokens[1]; - printf ("Forcing serverTitle[%s]\n", serverTitle.c_str ()); + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_SERVER_TITLE]) == + true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_SERVER_TITLE]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_SERVER_TITLE]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + Config & config = Config::getInstance(); + string + serverTitle = paramPartTokens[1]; + printf("Forcing serverTitle[%s]\n", serverTitle.c_str()); - config.setString ("ServerTitle", serverTitle, true); - } - else - { - printf - ("\nInvalid missing server title specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); + config.setString("ServerTitle", serverTitle, true); + } else { + printf + ("\nInvalid missing server title specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); - return 1; - } - } + return 1; + } + } -//#ifdef WIN32 -//SocketManager winSockManager; -//#endif + //#ifdef WIN32 + //SocketManager winSockManager; + //#endif - bool - haveSpecialOutputCommandLineOption = false; + bool + haveSpecialOutputCommandLineOption = false; - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_OPENGL_INFO]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_SDL_INFO]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LUA_INFO]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_CURL_INFO]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_XERCES_INFO]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VERSION]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_MAPS]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == - true) - { - haveSpecialOutputCommandLineOption = true; - } + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_OPENGL_INFO]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_SDL_INFO]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LUA_INFO]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_CURL_INFO]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_XERCES_INFO]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VERSION]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_MAPS]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == + true) { + haveSpecialOutputCommandLineOption = true; + } - if (haveSpecialOutputCommandLineOption == false || - hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VERSION]) == true) - { - printf ("%s %s", extractFileFromDirectoryPath (argv[0]).c_str (), - getNetworkPlatformFreeVersionString ().c_str ()); -// printf("\nCompiled using: %s on: %s platform: %s endianness: %s",getCompilerNameString().c_str(),getCompileDateTime().c_str(),getPlatformNameString().c_str(),(::Shared::PlatformByteOrder::isBigEndian() == true ? "big" : "little")); - printf ("\nCompiled using: %s platform: %s endianness: %s", - getCompilerNameString ().c_str (), - getPlatformNameString ().c_str (), - (::Shared::PlatformByteOrder::isBigEndian () == - true ? "big" : "little")); + if (haveSpecialOutputCommandLineOption == false || + hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VERSION]) == true) { + printf("%s %s", extractFileFromDirectoryPath(argv[0]).c_str(), + getNetworkPlatformFreeVersionString().c_str()); + // printf("\nCompiled using: %s on: %s platform: %s endianness: %s",getCompilerNameString().c_str(),getCompileDateTime().c_str(),getPlatformNameString().c_str(),(::Shared::PlatformByteOrder::isBigEndian() == true ? "big" : "little")); + printf("\nCompiled using: %s platform: %s endianness: %s", + getCompilerNameString().c_str(), + getPlatformNameString().c_str(), + (::Shared::PlatformByteOrder::isBigEndian() == + true ? "big" : "little")); -// printf("\n\nData type sizes int8 = " MG_SIZE_T_SPECIFIER " int16 = " MG_SIZE_T_SPECIFIER " int32 = " MG_SIZE_T_SPECIFIER " int64 = " MG_SIZE_T_SPECIFIER "\n\n",sizeof(int8),sizeof(int16),sizeof(int32),sizeof(int64)); -// -// Config::getInstance().setBool("DebugNetworkPackets",true,true); -// NetworkMessageIntro data(424336, "mg_version_x","player_x", 3, nmgstOk,444444, 555555, "english"); -// unsigned char *buf = data.packMessage(); -// printf("\nSend packet size = %u\n%s\n",data.getPackedSize(),data.toString().c_str()); -// data.dump_packet("Send data", buf, data.getPackedSize()); -// //delete [] buf; -// -// NetworkMessageIntro data2; -// data2.unpackMessage(buf); -// printf("\nReceive packet size = %u\n%s\n",data2.getPackedSize(),data2.toString().c_str()); -// data2.dump_packet("nReceive data", buf, data2.getPackedSize()); -// delete [] buf; + // printf("\n\nData type sizes int8 = " MG_SIZE_T_SPECIFIER " int16 = " MG_SIZE_T_SPECIFIER " int32 = " MG_SIZE_T_SPECIFIER " int64 = " MG_SIZE_T_SPECIFIER "\n\n",sizeof(int8),sizeof(int16),sizeof(int32),sizeof(int64)); + // + // Config::getInstance().setBool("DebugNetworkPackets",true,true); + // NetworkMessageIntro data(424336, "mg_version_x","player_x", 3, nmgstOk,444444, 555555, "english"); + // unsigned char *buf = data.packMessage(); + // printf("\nSend packet size = %u\n%s\n",data.getPackedSize(),data.toString().c_str()); + // data.dump_packet("Send data", buf, data.getPackedSize()); + // //delete [] buf; + // + // NetworkMessageIntro data2; + // data2.unpackMessage(buf); + // printf("\nReceive packet size = %u\n%s\n",data2.getPackedSize(),data2.toString().c_str()); + // data2.dump_packet("nReceive data", buf, data2.getPackedSize()); + // delete [] buf; -// SwitchSetupRequest data("factionname", 3,-1,2,"softcoder",10, 11,"eng"); -// -// unsigned char *buf = data.packMessage(); -// printf("\nSend packet size = %u\n%s\nTeam = %d faction [%s] currentFactionIndex = %d toFactionIndex = %d [%s] [%s] %d %d\n",data.getPackedSize(),buf,data.getToTeam(),data.getSelectedFactionName().c_str(),data.getCurrentFactionIndex(),data.getToFactionIndex(),data.getNetworkPlayerLanguage().c_str(),data.getNetworkPlayerName().c_str(),data.getNetworkPlayerStatus(),data.getSwitchFlags()); -// //delete [] buf; -// -// data.unpackMessage(buf); -// printf("\nGot packet size = %u\n%s\nTeam = %d faction [%s] currentFactionIndex = %d toFactionIndex = %d [%s] [%s] %d %d\n",data.getPackedSize(),buf,data.getToTeam(),data.getSelectedFactionName().c_str(),data.getCurrentFactionIndex(),data.getToFactionIndex(),data.getNetworkPlayerLanguage().c_str(),data.getNetworkPlayerName().c_str(),data.getNetworkPlayerStatus(),data.getSwitchFlags()); -// delete [] buf; + // SwitchSetupRequest data("factionname", 3,-1,2,"softcoder",10, 11,"eng"); + // + // unsigned char *buf = data.packMessage(); + // printf("\nSend packet size = %u\n%s\nTeam = %d faction [%s] currentFactionIndex = %d toFactionIndex = %d [%s] [%s] %d %d\n",data.getPackedSize(),buf,data.getToTeam(),data.getSelectedFactionName().c_str(),data.getCurrentFactionIndex(),data.getToFactionIndex(),data.getNetworkPlayerLanguage().c_str(),data.getNetworkPlayerName().c_str(),data.getNetworkPlayerStatus(),data.getSwitchFlags()); + // //delete [] buf; + // + // data.unpackMessage(buf); + // printf("\nGot packet size = %u\n%s\nTeam = %d faction [%s] currentFactionIndex = %d toFactionIndex = %d [%s] [%s] %d %d\n",data.getPackedSize(),buf,data.getToTeam(),data.getSelectedFactionName().c_str(),data.getCurrentFactionIndex(),data.getToFactionIndex(),data.getNetworkPlayerLanguage().c_str(),data.getNetworkPlayerName().c_str(),data.getNetworkPlayerStatus(),data.getSwitchFlags()); + // delete [] buf; -// int8 a = 1; -// uint8 b = 2; -// int16 c = 3; -// uint16 d = 4; -// int32 e = 5; -// uint32 f = 6; -// -// printf("\nPack test #1: [%d][%u][%d][%u][%d][%u]\n,",a,b,c,d,e,f); -// -// unsigned char *buf = new unsigned char[100]; -// unsigned int packedsize = pack(buf, "cChHlL", -// a, -// b, -// c, -// d, -// e, -// f); -// -// printf("Pack test #2: [%u][%s]\n,",packedsize,buf); -// -// int8 a1 = 0; -// uint8 b1 = 0; -// int16 c1 = 0; -// uint16 d1 = 0; -// int32 e1 = 0; -// uint32 f1 = 0; -// -// unpack(buf, "cChHlL", -// &a1, -// &b1, -// &c1, -// &d1, -// &e1, -// &f1); -// -// printf("UnPack test #3: [%d][%u][%d][%u][%d][%u]\n,",a1,b1,c1,d1,e1,f1); + // int8 a = 1; + // uint8 b = 2; + // int16 c = 3; + // uint16 d = 4; + // int32 e = 5; + // uint32 f = 6; + // + // printf("\nPack test #1: [%d][%u][%d][%u][%d][%u]\n,",a,b,c,d,e,f); + // + // unsigned char *buf = new unsigned char[100]; + // unsigned int packedsize = pack(buf, "cChHlL", + // a, + // b, + // c, + // d, + // e, + // f); + // + // printf("Pack test #2: [%u][%s]\n,",packedsize,buf); + // + // int8 a1 = 0; + // uint8 b1 = 0; + // int16 c1 = 0; + // uint16 d1 = 0; + // int32 e1 = 0; + // uint32 f1 = 0; + // + // unpack(buf, "cChHlL", + // &a1, + // &b1, + // &c1, + // &d1, + // &e1, + // &f1); + // + // printf("UnPack test #3: [%d][%u][%d][%u][%d][%u]\n,",a1,b1,c1,d1,e1,f1); - if (SystemFlags::VERBOSE_MODE_ENABLED == true) - { - int8 - testVar = 111; - printf ("\nEndian value = %d", testVar); - testVar =::Shared::PlatformByteOrder::toCommonEndian (testVar); - printf ("\nEndian to common value = %d", testVar); - testVar =::Shared::PlatformByteOrder::fromCommonEndian (testVar); - printf ("\nEndian from common value = %d", testVar); + if (SystemFlags::VERBOSE_MODE_ENABLED == true) { + int8 + testVar = 111; + printf("\nEndian value = %d", testVar); + testVar = ::Shared::PlatformByteOrder::toCommonEndian(testVar); + printf("\nEndian to common value = %d", testVar); + testVar = ::Shared::PlatformByteOrder::fromCommonEndian(testVar); + printf("\nEndian from common value = %d", testVar); - printf ("\nint8 sizeof = " MG_SIZE_T_SPECIFIER "", sizeof (int8)); - printf ("\nSwitchSetupRequest sizeof = " MG_SIZE_T_SPECIFIER "", - SwitchSetupRequest ().getDataSize ()); - } + printf("\nint8 sizeof = " MG_SIZE_T_SPECIFIER "", sizeof(int8)); + printf("\nSwitchSetupRequest sizeof = " MG_SIZE_T_SPECIFIER "", + SwitchSetupRequest().getDataSize()); + } - printf ("\nversion: [%s]", glestVersionString.c_str()); + printf("\nversion: [%s]", glestVersionString.c_str()); #ifdef USE_STREFLOP # if defined(STREFLOP_SSE) - const char * - instruction_set = "[SSE]"; + const char * + instruction_set = "[SSE]"; # elif defined(STREFLOP_X87) - const char * - instruction_set = "[X87]"; + const char * + instruction_set = "[X87]"; # elif defined(STREFLOP_SOFT) - const char * - instruction_set = "[SOFTFLOAT]"; + const char * + instruction_set = "[SOFTFLOAT]"; # else - const char * - instruction_set = "[none]"; + const char * + instruction_set = "[none]"; # endif # if defined(STREFLOP_NO_DENORMALS) - const char * - denormals = "[no-denormals]"; + const char * + denormals = "[no-denormals]"; # else - const char * - denormals = "[denormals]"; + const char * + denormals = "[denormals]"; # endif - printf (" - using STREFLOP %s - %s\n", instruction_set, denormals); + printf(" - using STREFLOP %s - %s\n", instruction_set, denormals); #else - printf ("\n"); + printf("\n"); #endif - } + } - setGameVersion (glestVersionString); + setGameVersion(glestVersionString); #ifdef WIN32 - CheckPacketThrottling (); + CheckPacketThrottling(); #endif - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_OPENGL_INFO]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_SDL_INFO]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LUA_INFO]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_CURL_INFO]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_XERCES_INFO]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VERSION]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_MAPS]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == - true) - { - VideoPlayer::setDisabled (true); - } + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_OPENGL_INFO]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_SDL_INFO]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LUA_INFO]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_CURL_INFO]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_XERCES_INFO]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VERSION]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_MAPS]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == + true) { + VideoPlayer::setDisabled(true); + } -//throw megaglest_runtime_error("Test!"); + //throw megaglest_runtime_error("Test!"); - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_SDL_INFO]) == - true) - { - SDL_version - ver; + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_SDL_INFO]) == + true) { + SDL_version + ver; -// Prints the compile time version - SDL_VERSION (&ver); - print_SDL_version ("SDL compile-time version", &ver); + // Prints the compile time version + SDL_VERSION(&ver); + print_SDL_version("SDL compile-time version", &ver); -// Prints the run-time version - SDL_GetVersion (&ver); - print_SDL_version ("SDL runtime version", &ver); -//const SDL_VideoInfo *vidInfo = SDL_GetVideoInfo(); -//printf("Video card Memory: %u\n",vidInfo->video_mem); - } + // Prints the run-time version + SDL_GetVersion(&ver); + print_SDL_version("SDL runtime version", &ver); + //const SDL_VideoInfo *vidInfo = SDL_GetVideoInfo(); + //printf("Video card Memory: %u\n",vidInfo->video_mem); + } - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_LUA_INFO]) == - true) - { - printf ("LUA version: %s\n", LUA_RELEASE); - } + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_LUA_INFO]) == + true) { + printf("LUA version: %s\n", LUA_RELEASE); + } - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_CURL_INFO]) == - true) - { - curl_version_info_data * - curlVersion = curl_version_info (CURLVERSION_NOW); - printf ("CURL version: %s [%s] SSL enabled: %d\n", - curlVersion->version, - (curlVersion->ssl_version != - NULL ? curlVersion->ssl_version : ""), - ((curlVersion->features & CURL_VERSION_SSL) == - CURL_VERSION_SSL ? true : false)); - if (curlVersion->protocols != NULL - && curlVersion->protocols[0] != NULL) - { - printf ("protocols: "); - for (unsigned int i = 0; - curlVersion->protocols != NULL - && curlVersion->protocols[i] != NULL; ++i) - { - printf ("%s ", curlVersion->protocols[i]); - if (i > 0 && i % 10 == 0) - { - printf ("\n "); - } - } - printf ("\n"); - } - } + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_CURL_INFO]) == + true) { + curl_version_info_data * + curlVersion = curl_version_info(CURLVERSION_NOW); + printf("CURL version: %s [%s] SSL enabled: %d\n", + curlVersion->version, + (curlVersion->ssl_version != + NULL ? curlVersion->ssl_version : ""), + ((curlVersion->features & CURL_VERSION_SSL) == + CURL_VERSION_SSL ? true : false)); + if (curlVersion->protocols != NULL + && curlVersion->protocols[0] != NULL) { + printf("protocols: "); + for (unsigned int i = 0; + curlVersion->protocols != NULL + && curlVersion->protocols[i] != NULL; ++i) { + printf("%s ", curlVersion->protocols[i]); + if (i > 0 && i % 10 == 0) { + printf("\n "); + } + } + printf("\n"); + } + } #if defined(WANT_XERCES) - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_XERCES_INFO]) == - true) - { - printf ("XERCES version: %s\n", XERCES_FULLVERSIONDOT); - } + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_XERCES_INFO]) == + true) { + printf("XERCES version: %s\n", XERCES_FULLVERSIONDOT); + } #endif - if ((hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_VERSION]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_SDL_INFO]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LUA_INFO]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_CURL_INFO]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_XERCES_INFO]) == true) - && hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_OPENGL_INFO]) == false - && hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == - false - && hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == - false - && hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == - false - && hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == - false - && hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == - false - && hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_MAPS]) == false - && hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == false - && hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == false - && hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_TILESETS]) == false - && hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == false - && hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == - false) - { - return 0; - } - - if (hasCommandArgument (argc, argv, string (GAME_ARGS[GAME_ARG_MOD])) == - true) - { - - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_MOD]) + string ("="), - &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, string (GAME_ARGS[GAME_ARG_MOD]), - &foundParamIndIndex); - } - string - scenarioName = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (scenarioName, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 && paramPartTokens[1].length () > 0) - { - string - autoloadModName = paramPartTokens[1]; - if (Properties::applyTagsToValue (autoloadModName) == true) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Property key [%s] now has value [%s]\n", - Config::ACTIVE_MOD_PROPERTY_NAME, - autoloadModName.c_str ()); - } - - Config::setCustomRuntimeProperty (Config::ACTIVE_MOD_PROPERTY_NAME, - autoloadModName); - - printf ("Setting mod active [%s]\n", autoloadModName.c_str ()); - } - else - { - printf - ("\nInvalid mod pathname specified on commandline [%s] mod [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - printParameterHelp (argv[0], foundInvalidArgs); - return 1; - } - } - - SystemFlags::init (haveSpecialOutputCommandLineOption); -//SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled = true; -//SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled = true; - - MainWindow * - mainWindow = NULL; - Program * - program = NULL; - ExceptionHandler - exceptionHandler; - exceptionHandler.install (getCrashDumpFileName ()); - - int - shutdownFadeSoundMilliseconds = 1000; - Chrono - chronoshutdownFadeSound; - SimpleTaskThread * - soundThreadManager = NULL; - - try - { -// Setup paths to game items (like data, logs, ini etc) - int - setupResult = setupGameItemPaths (argc, argv, NULL); - if (setupResult != 0) - { - return setupResult; - } - -// Attempt to read ini files - Config & config = Config::getInstance (); - setupGameItemPaths (argc, argv, &config); - - setupSteamSettings (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_STEAM]), - hasCommandArgument (argc, argv, - GAME_ARGS - [GAME_ARG_STEAM_RESET_STATS]), - hasCommandArgument (argc, argv, - GAME_ARGS - [GAME_ARG_STEAM_DEBUG])); - - if (config.getString ("PlayerId", "") == "") - { - char - uuid_str[38]; - get_uuid_string (uuid_str, sizeof (uuid_str)); - - config.setString ("PlayerId", uuid_str); - config.save (); - } - -//printf("Players UUID: [%s]\n",config.getString("PlayerId","").c_str()); - - if (config.getBool ("DisableLuaSandbox", "false") == true) - { - LuaScript::setDisableSandbox (true); - } - - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_DEBUG_NETWORK_PACKETS]) == true) - { - printf ("*NOTE: debugging network packets.\n"); - config.setBool ("DebugNetworkPackets", true, true); - } - - if (hasCommandArgument - (argc, argv, - GAME_ARGS[GAME_ARG_DEBUG_NETWORK_PACKET_SIZES]) == true) - { - printf ("*NOTE: debugging network packet SIZES.\n"); - config.setBool ("DebugNetworkPacketSizes", true, true); - } - - if (hasCommandArgument - (argc, argv, - GAME_ARGS[GAME_ARG_DEBUG_NETWORK_PACKET_STATS]) == true) - { - printf ("*NOTE: debugging network packet STATISTICS.\n"); - config.setBool ("DebugNetworkPacketStats", true, true); - } - - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_ENABLE_NEW_PROTOCOL]) == true) - { - printf ("*NOTE: enabling new network protocol.\n"); - NetworkMessage::useOldProtocol = false; - } - - Socket::setBroadCastPort (config.getInt ("BroadcastPort", - intToStr - (Socket::getBroadCastPort - ()).c_str ())); - - Socket::disableNagle = config.getBool ("DisableNagle", "false"); - if (Socket::disableNagle) - { - printf - ("*WARNING users wants to disable the socket nagle algorithm.\n"); - } - Socket::DEFAULT_SOCKET_SENDBUF_SIZE = - config.getInt ("DefaultSocketSendBufferSize", - intToStr (Socket::DEFAULT_SOCKET_SENDBUF_SIZE). - c_str ()); - if (Socket::DEFAULT_SOCKET_SENDBUF_SIZE >= 0) - { - printf - ("*WARNING users wants to set default socket send buffer size to: %d\n", - Socket::DEFAULT_SOCKET_SENDBUF_SIZE); - } - Socket::DEFAULT_SOCKET_RECVBUF_SIZE = - config.getInt ("DefaultSocketReceiveBufferSize", - intToStr (Socket::DEFAULT_SOCKET_RECVBUF_SIZE). - c_str ()); - if (Socket::DEFAULT_SOCKET_RECVBUF_SIZE >= 0) - { - printf - ("*WARNING users wants to set default socket receive buffer size to: %d\n", - Socket::DEFAULT_SOCKET_RECVBUF_SIZE); - } - - shutdownFadeSoundMilliseconds = - config.getInt ("ShutdownFadeSoundMilliseconds", - intToStr (shutdownFadeSoundMilliseconds).c_str ()); - - string - userData = config.getString ("UserData_Root", ""); - if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) != - "") - { - userData = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey); - } - if (userData != "") - { - endPathWithSlash (userData); - } - - string - data_path_check = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - string - userDataPath_check = - getGameCustomCoreDataPath (data_path_check, ""); - if (data_path_check == userDataPath_check) - { - printf - ("****WARNING**** your game data path and user data path are the same.\nThis will likely create problems: %s\n", - data_path_check.c_str ()); - throw - megaglest_runtime_error - ("Regular and User data paths cannot have the same value [" + - userDataPath_check + "]"); - } - - if (userData != "") - { - if (isdir (userData.c_str ()) == false) - { - createDirectoryPaths (userData); - } - } - string - crcCachePath = userData + "cache/"; - if (isdir (crcCachePath.c_str ()) == false) - { - createDirectoryPaths (crcCachePath); - } - setCRCCacheFilePath (crcCachePath); - - string - savedGamePath = userData + "saved/"; - if (isdir (savedGamePath.c_str ()) == false) - { - createDirectoryPaths (savedGamePath); - } - - string - tempDataPath = userData + "temp/"; - tempDataLocation = tempDataPath; - if (isdir (tempDataPath.c_str ()) == true) - { - removeFolder (tempDataPath); - } - createDirectoryPaths (tempDataPath); - - string - binaryNameOld = - Properties::getApplicationPath () + - extractFileFromDirectoryPath - (PlatformExceptionHandler::application_binary) + "__REMOVE"; - if (fileExists (binaryNameOld)) - { - removeFile (binaryNameOld); - } - - string - netInterfaces = config.getString ("NetworkInterfaces", ""); - if (netInterfaces != "") - { -//printf("Using network interfaces: %s\n",netInterfaces.c_str()); - std::vector < std::string > intfList; - Tokenize (netInterfaces, intfList, ","); - Socket::setIntfTypes (intfList); - } - - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_USE_PORTS]) == - true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_USE_PORTS]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_USE_PORTS]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - string - portsToUse = paramPartTokens[1]; - - vector < string > paramPartPortsTokens; - Tokenize (portsToUse, paramPartPortsTokens, ","); - if (paramPartPortsTokens.size () >= 2 - && paramPartPortsTokens[1].length () > 0) - { - int - internalPort = strToInt (paramPartPortsTokens[0]); - int - externalPort = strToInt (paramPartPortsTokens[1]); - - printf ("Forcing internal port# %d, external port# %d\n", - internalPort, externalPort); - - config.setInt ("PortServer", internalPort, true); - config.setInt ("PortExternal", externalPort, true); - config.setInt ("FTPServerPort", internalPort + 1, true); - - if (paramPartPortsTokens.size () >= 3 - && paramPartPortsTokens[2].length () > 0) - { - int - statusPort = strToInt (paramPartPortsTokens[2]); - - printf ("Forcing status port# %d\n", statusPort); - - config.setInt ("ServerAdminPort", statusPort, true); - } - } - else - { - printf - ("\nInvalid ports specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - return 1; - } - } - else - { - printf - ("\nInvalid missing ports specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - return 1; - } - } - - if (hasCommandArgument - (argc, argv, - string (GAME_ARGS[GAME_ARG_MASTERSERVER_STATUS])) == true) - { - Ip - ip ("localhost"); - int - port = Config::getInstance ().getInt ("ServerAdminPort", - intToStr - (GameConstants:: - serverAdminPort).c_str ()); - ClientSocket - clientSocket; - clientSocket.setBlock (false); - clientSocket.connect (ip, port); - if (clientSocket.isConnected () == true) - { - clientSocket.setBlock (true); - - char - szBuf[8096] = ""; - clientSocket.receive (&szBuf[0], 8095, false); - std::cout << szBuf << std::endl; - } - else - { - std::cout << - "Could not connect (possibly no clients connected) to host: " << - ip.getString () << " port: " << port << std::endl; - } - - return 0; - } - - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_DISABLE_SOUND]) - == true - || hasCommandArgument (argc, argv, - string (GAME_ARGS - [GAME_ARG_MASTERSERVER_MODE])) == - true) - { - config.setString ("FactorySound", "None", true); - if (hasCommandArgument - (argc, argv, - string (GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) - { -//Logger::getInstance().setMasterserverMode(true); -//Model::setMasterserverMode(true); -//Shared::Sound::Sound::setMasterserverMode(true); - } - } - - if (hasCommandArgument - (argc, argv, - GAME_ARGS[GAME_ARG_DISABLE_OPENGL_CAPS_CHECK]) == true - || config.getBool ("CheckGlCaps") == false) - { - printf ("**WARNING** disabling opengl capability checking...\n"); - config.setBool ("CheckGlCaps", false, true); - } - - bool - enableATIHacks = config.getBool ("EnableATIHacks", "false"); - if (enableATIHacks == true) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("**WARNING** Enabling ATI video card hacks\n"); - TextureGl::setEnableATIHacks (enableATIHacks); - } - - Renderer::renderText3DEnabled = - config.getBool ("Enable3DFontRendering", - intToStr (Renderer::renderText3DEnabled).c_str ()); - - if (config.getBool ("EnableLegacyFonts", "false") == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_ENABLE_LEGACYFONTS]) == - true) - { - ::Shared::Graphics::Font::forceLegacyFonts = true; - Renderer::renderText3DEnabled = false; - printf ("**WARNING** Forcing Legacy Fonts Enabled\n"); - } - else - { - Renderer::renderText3DEnabled = - config.getBool ("Enable3DFontRendering", - intToStr (Renderer::renderText3DEnabled). - c_str ()); - } - - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_USE_RESOLUTION]) == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_USE_RESOLUTION]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_USE_RESOLUTION]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - string - settings = paramPartTokens[1]; - printf ("Forcing resolution [%s]\n", settings.c_str ()); - - paramPartTokens.clear (); - Tokenize (settings, paramPartTokens, "x"); - if (paramPartTokens.size () >= 2) - { - int - newScreenWidth = strToInt (paramPartTokens[0]); - config.setInt ("ScreenWidth", newScreenWidth, true); - - int - newScreenHeight = strToInt (paramPartTokens[1]); - config.setInt ("ScreenHeight", newScreenHeight, true); - } - else - { - printf - ("\nInvalid missing resolution settings specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - return 1; - } - } - else - { - printf - ("\nInvalid missing resolution setting specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - return 1; - } - } - - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_USE_COLORBITS]) - == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_USE_COLORBITS]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_USE_COLORBITS]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - string - settings = paramPartTokens[1]; - printf ("Forcing colorbits [%s]\n", settings.c_str ()); - - int - newColorBits = strToInt (settings); - config.setInt ("ColorBits", newColorBits, true); - } - else - { - printf - ("\nInvalid missing colorbits settings specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - return 1; - } - } - - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_USE_DEPTHBITS]) - == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_USE_DEPTHBITS]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_USE_DEPTHBITS]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - string - settings = paramPartTokens[1]; - printf ("Forcing depthbits [%s]\n", settings.c_str ()); - - int - newDepthBits = strToInt (settings); - config.setInt ("DepthBits", newDepthBits, true); - } - else - { - printf - ("\nInvalid missing depthbits setting specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - return 1; - } - } - - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_USE_FULLSCREEN]) == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_USE_FULLSCREEN]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_USE_FULLSCREEN]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - string - settings = paramPartTokens[1]; - printf ("Forcing fullscreen [%s]\n", settings.c_str ()); - - bool - newFullScreenMode = strToBool (settings); - config.setBool ("Windowed", !newFullScreenMode, true); - } - else - { - printf - ("\nInvalid missing fullscreen setting specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - return 1; - } - } - - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_SET_GAMMA]) == - true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_SET_GAMMA]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_SET_GAMMA]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - string - settings = paramPartTokens[1]; - printf ("Forcing gamma [%s]\n", settings.c_str ()); - - float - newGammaValue = strToFloat (settings); - config.setFloat ("GammaValue", newGammaValue, true); - } - else - { - printf - ("\nInvalid missing gamma setting specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - return 1; - } - } - - - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_DISABLE_VIDEOS]) == true) - { - VideoPlayer::setDisabled (true); - } - else if (config.getBool ("EnableVideos", "true") == false) - { - VideoPlayer::setDisabled (true); - } - -// Set some statics based on ini entries - SystemFlags::ENABLE_THREADED_LOGGING = - config.getBool ("ThreadedLogging", "true"); - FontGl::setDefault_fontType (config.getString ("DefaultFont", - FontGl:: - getDefault_fontType (). - c_str ())); - UPNP_Tools::isUPNP = !config.getBool ("DisableUPNP", "false"); - Texture::useTextureCompression = - config.getBool ("EnableTextureCompression", "false"); - -// 256 for English -// 30000 for Chinese - ::Shared::Graphics::Font::charCount = - config.getInt ("FONT_CHARCOUNT", - intToStr (::Shared::Graphics::Font::charCount). - c_str ()); - ::Shared::Graphics::Font::fontTypeName = - config. - getString ("FONT_TYPENAME",::Shared::Graphics::Font::fontTypeName. - c_str ()); - ::Shared::Graphics::Font::fontIsMultibyte = - config.getBool ("FONT_MULTIBYTE", - intToStr (::Shared::Graphics::Font:: - fontIsMultibyte).c_str ()); - ::Shared::Graphics::Font::fontIsRightToLeft = - config.getBool ("FONT_RIGHTTOLEFT", - intToStr (::Shared::Graphics::Font:: - fontIsRightToLeft).c_str ()); - ::Shared::Graphics::Font::baseSize = - config.getInt ("FONT_BASE_SIZE", - intToStr (::Shared::Graphics::Font::baseSize). - c_str ()); - ::Shared::Graphics::Font::scaleFontValue = - config.getFloat ("FONT_SCALE_SIZE", - floatToStr (::Shared::Graphics::Font:: - scaleFontValue).c_str ()); - ::Shared::Graphics::Font::scaleFontValueCenterHFactor = - config.getFloat ("FONT_SCALE_CENTERH_FACTOR", - floatToStr (::Shared::Graphics::Font:: - scaleFontValueCenterHFactor).c_str ()); - ::Shared::Graphics::Font::langHeightText = - config. - getString ("FONT_HEIGHT_TEXT",::Shared::Graphics::Font:: - langHeightText.c_str ()); - ::Shared::Graphics::Font::fontSupportMixedRightToLeft = - config.getBool ("FONT_RIGHTTOLEFT_MIXED_SUPPORT", - intToStr (::Shared::Graphics::Font:: - fontSupportMixedRightToLeft).c_str ()); - -// Example values: -// DEFAULT_CHARSET (English) = 1 -// GB2312_CHARSET (Chinese) = 134 - ::Shared::Platform::PlatformContextGl::charSet = - config.getInt ("FONT_CHARSET", - intToStr (::Shared::Platform::PlatformContextGl:: - charSet).c_str ()); - if (config.getBool ("No2DMouseRendering", "false") == false) - { - showCursor (false); -//showWindowCursorState = false; - } - if (config.getInt ("DEFAULT_HTTP_TIMEOUT", - intToStr (SystemFlags:: - DEFAULT_HTTP_TIMEOUT).c_str ()) >= 0) - { - SystemFlags::DEFAULT_HTTP_TIMEOUT = - config.getInt ("DEFAULT_HTTP_TIMEOUT", - intToStr (SystemFlags::DEFAULT_HTTP_TIMEOUT). - c_str ()); - } - - bool - allowAltEnterFullscreenToggle = - config.getBool ("AllowAltEnterFullscreenToggle", - boolToStr (::Shared::Platform::Window:: - getAllowAltEnterFullscreenToggle ()). - c_str ()); - ::Shared::Platform::Window:: - setAllowAltEnterFullscreenToggle (allowAltEnterFullscreenToggle); - - if (config.getBool ("noTeamColors", "false") == true) - { - MeshCallbackTeamColor::noTeamColors = true; - } - - - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_LUA_DEBUG]) == - true) - { - printf ("Forcing LUA debugging enabled!\n"); - config.setBool ("DebugLUA", true, true); - } - -// Setup debug logging etc - setupLogging (config, haveSpecialOutputCommandLineOption); - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::PlatformContextGl::charSet = %d, Font::fontIsMultibyte = %d, fontIsRightToLeft = %d\n", - __FILE__, __FUNCTION__, - __LINE__,::Shared::Graphics::Font:: - charCount,::Shared::Graphics::Font:: - fontTypeName. - c_str (),::Shared::Platform:: - PlatformContextGl::charSet,::Shared:: - Graphics::Font::fontIsMultibyte,::Shared:: - Graphics::Font::fontIsRightToLeft); - - NetworkInterface::setDisplayMessageFunction (ExceptionHandler:: - DisplayMessage); - MenuStateMasterserver::setDisplayMessageFunction (ExceptionHandler:: - DisplayMessage); + if ((hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_VERSION]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_SDL_INFO]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LUA_INFO]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_CURL_INFO]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_XERCES_INFO]) == true) + && hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_OPENGL_INFO]) == false + && hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == + false + && hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == + false + && hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == + false + && hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == + false + && hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == + false + && hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_MAPS]) == false + && hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == false + && hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == false + && hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_TILESETS]) == false + && hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == false + && hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == + false) { + return 0; + } + + if (hasCommandArgument(argc, argv, string(GAME_ARGS[GAME_ARG_MOD])) == + true) { + + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_MOD]) + string("="), + &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, string(GAME_ARGS[GAME_ARG_MOD]), + &foundParamIndIndex); + } + string + scenarioName = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(scenarioName, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 && paramPartTokens[1].length() > 0) { + string + autoloadModName = paramPartTokens[1]; + if (Properties::applyTagsToValue(autoloadModName) == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Property key [%s] now has value [%s]\n", + Config::ACTIVE_MOD_PROPERTY_NAME, + autoloadModName.c_str()); + } + + Config::setCustomRuntimeProperty(Config::ACTIVE_MOD_PROPERTY_NAME, + autoloadModName); + + printf("Setting mod active [%s]\n", autoloadModName.c_str()); + } else { + printf + ("\nInvalid mod pathname specified on commandline [%s] mod [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(argv[0], foundInvalidArgs); + return 1; + } + } + + SystemFlags::init(haveSpecialOutputCommandLineOption); + //SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled = true; + //SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled = true; + + MainWindow * + mainWindow = NULL; + Program * + program = NULL; + ExceptionHandler + exceptionHandler; + exceptionHandler.install(getCrashDumpFileName()); + + int + shutdownFadeSoundMilliseconds = 1000; + Chrono + chronoshutdownFadeSound; + SimpleTaskThread * + soundThreadManager = NULL; + + try { + // Setup paths to game items (like data, logs, ini etc) + int + setupResult = setupGameItemPaths(argc, argv, NULL); + if (setupResult != 0) { + return setupResult; + } + + // Attempt to read ini files + Config & config = Config::getInstance(); + setupGameItemPaths(argc, argv, &config); + + setupSteamSettings(hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_STEAM]), + hasCommandArgument(argc, argv, + GAME_ARGS + [GAME_ARG_STEAM_RESET_STATS]), + hasCommandArgument(argc, argv, + GAME_ARGS + [GAME_ARG_STEAM_DEBUG])); + + if (config.getString("PlayerId", "") == "") { + char + uuid_str[38]; + get_uuid_string(uuid_str, sizeof(uuid_str)); + + config.setString("PlayerId", uuid_str); + config.save(); + } + + //printf("Players UUID: [%s]\n",config.getString("PlayerId","").c_str()); + + if (config.getBool("DisableLuaSandbox", "false") == true) { + LuaScript::setDisableSandbox(true); + } + + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_DEBUG_NETWORK_PACKETS]) == true) { + printf("*NOTE: debugging network packets.\n"); + config.setBool("DebugNetworkPackets", true, true); + } + + if (hasCommandArgument + (argc, argv, + GAME_ARGS[GAME_ARG_DEBUG_NETWORK_PACKET_SIZES]) == true) { + printf("*NOTE: debugging network packet SIZES.\n"); + config.setBool("DebugNetworkPacketSizes", true, true); + } + + if (hasCommandArgument + (argc, argv, + GAME_ARGS[GAME_ARG_DEBUG_NETWORK_PACKET_STATS]) == true) { + printf("*NOTE: debugging network packet STATISTICS.\n"); + config.setBool("DebugNetworkPacketStats", true, true); + } + + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_ENABLE_NEW_PROTOCOL]) == true) { + printf("*NOTE: enabling new network protocol.\n"); + NetworkMessage::useOldProtocol = false; + } + + Socket::setBroadCastPort(config.getInt("BroadcastPort", + intToStr + (Socket::getBroadCastPort + ()).c_str())); + + Socket::disableNagle = config.getBool("DisableNagle", "false"); + if (Socket::disableNagle) { + printf + ("*WARNING users wants to disable the socket nagle algorithm.\n"); + } + Socket::DEFAULT_SOCKET_SENDBUF_SIZE = + config.getInt("DefaultSocketSendBufferSize", + intToStr(Socket::DEFAULT_SOCKET_SENDBUF_SIZE). + c_str()); + if (Socket::DEFAULT_SOCKET_SENDBUF_SIZE >= 0) { + printf + ("*WARNING users wants to set default socket send buffer size to: %d\n", + Socket::DEFAULT_SOCKET_SENDBUF_SIZE); + } + Socket::DEFAULT_SOCKET_RECVBUF_SIZE = + config.getInt("DefaultSocketReceiveBufferSize", + intToStr(Socket::DEFAULT_SOCKET_RECVBUF_SIZE). + c_str()); + if (Socket::DEFAULT_SOCKET_RECVBUF_SIZE >= 0) { + printf + ("*WARNING users wants to set default socket receive buffer size to: %d\n", + Socket::DEFAULT_SOCKET_RECVBUF_SIZE); + } + + shutdownFadeSoundMilliseconds = + config.getInt("ShutdownFadeSoundMilliseconds", + intToStr(shutdownFadeSoundMilliseconds).c_str()); + + string + userData = config.getString("UserData_Root", ""); + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != + "") { + userData = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey); + } + if (userData != "") { + endPathWithSlash(userData); + } + + string + data_path_check = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + string + userDataPath_check = + getGameCustomCoreDataPath(data_path_check, ""); + if (data_path_check == userDataPath_check) { + printf + ("****WARNING**** your game data path and user data path are the same.\nThis will likely create problems: %s\n", + data_path_check.c_str()); + throw + megaglest_runtime_error + ("Regular and User data paths cannot have the same value [" + + userDataPath_check + "]"); + } + + if (userData != "") { + if (isdir(userData.c_str()) == false) { + createDirectoryPaths(userData); + } + } + string + crcCachePath = userData + "cache/"; + if (isdir(crcCachePath.c_str()) == false) { + createDirectoryPaths(crcCachePath); + } + setCRCCacheFilePath(crcCachePath); + + string + savedGamePath = userData + "saved/"; + if (isdir(savedGamePath.c_str()) == false) { + createDirectoryPaths(savedGamePath); + } + + string + tempDataPath = userData + "temp/"; + tempDataLocation = tempDataPath; + if (isdir(tempDataPath.c_str()) == true) { + removeFolder(tempDataPath); + } + createDirectoryPaths(tempDataPath); + + string + binaryNameOld = + Properties::getApplicationPath() + + extractFileFromDirectoryPath + (PlatformExceptionHandler::application_binary) + "__REMOVE"; + if (fileExists(binaryNameOld)) { + removeFile(binaryNameOld); + } + + string + netInterfaces = config.getString("NetworkInterfaces", ""); + if (netInterfaces != "") { + //printf("Using network interfaces: %s\n",netInterfaces.c_str()); + std::vector < std::string > intfList; + Tokenize(netInterfaces, intfList, ","); + Socket::setIntfTypes(intfList); + } + + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_USE_PORTS]) == + true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_USE_PORTS]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_USE_PORTS]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + string + portsToUse = paramPartTokens[1]; + + vector < string > paramPartPortsTokens; + Tokenize(portsToUse, paramPartPortsTokens, ","); + if (paramPartPortsTokens.size() >= 2 + && paramPartPortsTokens[1].length() > 0) { + int + internalPort = strToInt(paramPartPortsTokens[0]); + int + externalPort = strToInt(paramPartPortsTokens[1]); + + printf("Forcing internal port# %d, external port# %d\n", + internalPort, externalPort); + + config.setInt("PortServer", internalPort, true); + config.setInt("PortExternal", externalPort, true); + config.setInt("FTPServerPort", internalPort + 1, true); + + if (paramPartPortsTokens.size() >= 3 + && paramPartPortsTokens[2].length() > 0) { + int + statusPort = strToInt(paramPartPortsTokens[2]); + + printf("Forcing status port# %d\n", statusPort); + + config.setInt("ServerAdminPort", statusPort, true); + } + } else { + printf + ("\nInvalid ports specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + return 1; + } + } else { + printf + ("\nInvalid missing ports specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + return 1; + } + } + + if (hasCommandArgument + (argc, argv, + string(GAME_ARGS[GAME_ARG_MASTERSERVER_STATUS])) == true) { + Ip + ip("localhost"); + int + port = Config::getInstance().getInt("ServerAdminPort", + intToStr + (GameConstants:: + serverAdminPort).c_str()); + ClientSocket + clientSocket; + clientSocket.setBlock(false); + clientSocket.connect(ip, port); + if (clientSocket.isConnected() == true) { + clientSocket.setBlock(true); + + char + szBuf[8096] = ""; + clientSocket.receive(&szBuf[0], 8095, false); + std::cout << szBuf << std::endl; + } else { + std::cout << + "Could not connect (possibly no clients connected) to host: " << + ip.getString() << " port: " << port << std::endl; + } + + return 0; + } + + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_DISABLE_SOUND]) + == true + || hasCommandArgument(argc, argv, + string(GAME_ARGS + [GAME_ARG_MASTERSERVER_MODE])) == + true) { + config.setString("FactorySound", "None", true); + if (hasCommandArgument + (argc, argv, + string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) { + //Logger::getInstance().setMasterserverMode(true); + //Model::setMasterserverMode(true); + //Shared::Sound::Sound::setMasterserverMode(true); + } + } + + if (hasCommandArgument + (argc, argv, + GAME_ARGS[GAME_ARG_DISABLE_OPENGL_CAPS_CHECK]) == true + || config.getBool("CheckGlCaps") == false) { + printf("**WARNING** disabling opengl capability checking...\n"); + config.setBool("CheckGlCaps", false, true); + } + + bool + enableATIHacks = config.getBool("EnableATIHacks", "false"); + if (enableATIHacks == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("**WARNING** Enabling ATI video card hacks\n"); + TextureGl::setEnableATIHacks(enableATIHacks); + } + + Renderer::renderText3DEnabled = + config.getBool("Enable3DFontRendering", + intToStr(Renderer::renderText3DEnabled).c_str()); + + if (config.getBool("EnableLegacyFonts", "false") == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_ENABLE_LEGACYFONTS]) == + true) { + ::Shared::Graphics::Font::forceLegacyFonts = true; + Renderer::renderText3DEnabled = false; + printf("**WARNING** Forcing Legacy Fonts Enabled\n"); + } else { + Renderer::renderText3DEnabled = + config.getBool("Enable3DFontRendering", + intToStr(Renderer::renderText3DEnabled). + c_str()); + } + + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_USE_RESOLUTION]) == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_USE_RESOLUTION]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_USE_RESOLUTION]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + string + settings = paramPartTokens[1]; + printf("Forcing resolution [%s]\n", settings.c_str()); + + paramPartTokens.clear(); + Tokenize(settings, paramPartTokens, "x"); + if (paramPartTokens.size() >= 2) { + int + newScreenWidth = strToInt(paramPartTokens[0]); + config.setInt("ScreenWidth", newScreenWidth, true); + + int + newScreenHeight = strToInt(paramPartTokens[1]); + config.setInt("ScreenHeight", newScreenHeight, true); + } else { + printf + ("\nInvalid missing resolution settings specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + return 1; + } + } else { + printf + ("\nInvalid missing resolution setting specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + return 1; + } + } + + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_USE_COLORBITS]) + == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_USE_COLORBITS]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_USE_COLORBITS]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + string + settings = paramPartTokens[1]; + printf("Forcing colorbits [%s]\n", settings.c_str()); + + int + newColorBits = strToInt(settings); + config.setInt("ColorBits", newColorBits, true); + } else { + printf + ("\nInvalid missing colorbits settings specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + return 1; + } + } + + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_USE_DEPTHBITS]) + == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_USE_DEPTHBITS]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_USE_DEPTHBITS]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + string + settings = paramPartTokens[1]; + printf("Forcing depthbits [%s]\n", settings.c_str()); + + int + newDepthBits = strToInt(settings); + config.setInt("DepthBits", newDepthBits, true); + } else { + printf + ("\nInvalid missing depthbits setting specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + return 1; + } + } + + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_USE_FULLSCREEN]) == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_USE_FULLSCREEN]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_USE_FULLSCREEN]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + string + settings = paramPartTokens[1]; + printf("Forcing fullscreen [%s]\n", settings.c_str()); + + bool + newFullScreenMode = strToBool(settings); + config.setBool("Windowed", !newFullScreenMode, true); + } else { + printf + ("\nInvalid missing fullscreen setting specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + return 1; + } + } + + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_SET_GAMMA]) == + true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_SET_GAMMA]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_SET_GAMMA]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + string + settings = paramPartTokens[1]; + printf("Forcing gamma [%s]\n", settings.c_str()); + + float + newGammaValue = strToFloat(settings); + config.setFloat("GammaValue", newGammaValue, true); + } else { + printf + ("\nInvalid missing gamma setting specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + return 1; + } + } + + + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_DISABLE_VIDEOS]) == true) { + VideoPlayer::setDisabled(true); + } else if (config.getBool("EnableVideos", "true") == false) { + VideoPlayer::setDisabled(true); + } + + // Set some statics based on ini entries + SystemFlags::ENABLE_THREADED_LOGGING = + config.getBool("ThreadedLogging", "true"); + FontGl::setDefault_fontType(config.getString("DefaultFont", + FontGl:: + getDefault_fontType(). + c_str())); + UPNP_Tools::isUPNP = !config.getBool("DisableUPNP", "false"); + Texture::useTextureCompression = + config.getBool("EnableTextureCompression", "false"); + + // 256 for English + // 30000 for Chinese + ::Shared::Graphics::Font::charCount = + config.getInt("FONT_CHARCOUNT", + intToStr(::Shared::Graphics::Font::charCount). + c_str()); + ::Shared::Graphics::Font::fontTypeName = + config. + getString("FONT_TYPENAME", ::Shared::Graphics::Font::fontTypeName. + c_str()); + ::Shared::Graphics::Font::fontIsMultibyte = + config.getBool("FONT_MULTIBYTE", + intToStr(::Shared::Graphics::Font:: + fontIsMultibyte).c_str()); + ::Shared::Graphics::Font::fontIsRightToLeft = + config.getBool("FONT_RIGHTTOLEFT", + intToStr(::Shared::Graphics::Font:: + fontIsRightToLeft).c_str()); + ::Shared::Graphics::Font::baseSize = + config.getInt("FONT_BASE_SIZE", + intToStr(::Shared::Graphics::Font::baseSize). + c_str()); + ::Shared::Graphics::Font::scaleFontValue = + config.getFloat("FONT_SCALE_SIZE", + floatToStr(::Shared::Graphics::Font:: + scaleFontValue).c_str()); + ::Shared::Graphics::Font::scaleFontValueCenterHFactor = + config.getFloat("FONT_SCALE_CENTERH_FACTOR", + floatToStr(::Shared::Graphics::Font:: + scaleFontValueCenterHFactor).c_str()); + ::Shared::Graphics::Font::langHeightText = + config. + getString("FONT_HEIGHT_TEXT", ::Shared::Graphics::Font:: + langHeightText.c_str()); + ::Shared::Graphics::Font::fontSupportMixedRightToLeft = + config.getBool("FONT_RIGHTTOLEFT_MIXED_SUPPORT", + intToStr(::Shared::Graphics::Font:: + fontSupportMixedRightToLeft).c_str()); + + // Example values: + // DEFAULT_CHARSET (English) = 1 + // GB2312_CHARSET (Chinese) = 134 + ::Shared::Platform::PlatformContextGl::charSet = + config.getInt("FONT_CHARSET", + intToStr(::Shared::Platform::PlatformContextGl:: + charSet).c_str()); + if (config.getBool("No2DMouseRendering", "false") == false) { + showCursor(false); + //showWindowCursorState = false; + } + if (config.getInt("DEFAULT_HTTP_TIMEOUT", + intToStr(SystemFlags:: + DEFAULT_HTTP_TIMEOUT).c_str()) >= 0) { + SystemFlags::DEFAULT_HTTP_TIMEOUT = + config.getInt("DEFAULT_HTTP_TIMEOUT", + intToStr(SystemFlags::DEFAULT_HTTP_TIMEOUT). + c_str()); + } + + bool + allowAltEnterFullscreenToggle = + config.getBool("AllowAltEnterFullscreenToggle", + boolToStr(::Shared::Platform::Window:: + getAllowAltEnterFullscreenToggle()). + c_str()); + ::Shared::Platform::Window:: + setAllowAltEnterFullscreenToggle(allowAltEnterFullscreenToggle); + + if (config.getBool("noTeamColors", "false") == true) { + MeshCallbackTeamColor::noTeamColors = true; + } + + + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_LUA_DEBUG]) == + true) { + printf("Forcing LUA debugging enabled!\n"); + config.setBool("DebugLUA", true, true); + } + + // Setup debug logging etc + setupLogging(config, haveSpecialOutputCommandLineOption); + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::PlatformContextGl::charSet = %d, Font::fontIsMultibyte = %d, fontIsRightToLeft = %d\n", + __FILE__, __FUNCTION__, + __LINE__, ::Shared::Graphics::Font:: + charCount, ::Shared::Graphics::Font:: + fontTypeName. + c_str(), ::Shared::Platform:: + PlatformContextGl::charSet, ::Shared:: + Graphics::Font::fontIsMultibyte, ::Shared:: + Graphics::Font::fontIsRightToLeft); + + NetworkInterface::setDisplayMessageFunction(ExceptionHandler:: + DisplayMessage); + MenuStateMasterserver::setDisplayMessageFunction(ExceptionHandler:: + DisplayMessage); #ifdef USE_STREFLOP - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "%s, STREFLOP enabled.\n", - getNetworkVersionString ().c_str ()); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "%s, STREFLOP enabled.\n", + getNetworkVersionString().c_str()); #else - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "%s, STREFLOP NOT enabled.\n", - getNetworkVersionString ().c_str ()); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "%s, STREFLOP NOT enabled.\n", + getNetworkVersionString().c_str()); #endif - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - SystemFlags::OutputDebug (SystemFlags::debugUnitCommands, "START\n"); - SystemFlags::OutputDebug (SystemFlags::debugPathFinder, "START\n"); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "START\n"); + SystemFlags::OutputDebug(SystemFlags::debugPathFinder, "START\n"); -// Setup hotkeys from key ini files - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys), - std::pair < string, - string > (Config::glestkeys_ini_filename, - Config::glestuserkeys_ini_filename), - std::pair < bool, bool > (true, false), - config.getString ("GlestKeysIniPath", "")); + // Setup hotkeys from key ini files + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys), + std::pair < string, + string >(Config::glestkeys_ini_filename, + Config::glestuserkeys_ini_filename), + std::pair < bool, bool >(true, false), + config.getString("GlestKeysIniPath", "")); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true) - { - ShowINISettings (argc, argv, config, configKeys); - return 0; - } + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true) { + ShowINISettings(argc, argv, config, configKeys); + return 0; + } -// Explicitly disable VBO's - if (config.getBool ("DisableVBO", "false") == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_DISABLE_VBO]) == true) - { - setVBOSupported (false); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("**INFO** Disabling VBOs\n"); - } + // Explicitly disable VBO's + if (config.getBool("DisableVBO", "false") == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_DISABLE_VBO]) == true) { + setVBOSupported(false); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("**INFO** Disabling VBOs\n"); + } - if (config.getBool ("DisableVertexInterpolation", "false") - || hasCommandArgument (argc, argv, - GAME_ARGS - [GAME_ARG_DISABLE_VERTEX_INTERPOLATION])) - { - InterpolationData::setEnableInterpolation (false); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("**INFO** Disabling Interpolation\n"); - } + if (config.getBool("DisableVertexInterpolation", "false") + || hasCommandArgument(argc, argv, + GAME_ARGS + [GAME_ARG_DISABLE_VERTEX_INTERPOLATION])) { + InterpolationData::setEnableInterpolation(false); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("**INFO** Disabling Interpolation\n"); + } - if (config.getBool ("EnableVSynch", "false") == true) - { - ::Shared::Platform::Window::setTryVSynch (true); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("**ENABLED OPENGL VSYNCH**\n"); - } + if (config.getBool("EnableVSynch", "false") == true) { + ::Shared::Platform::Window::setTryVSynch(true); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("**ENABLED OPENGL VSYNCH**\n"); + } -//float pingTime = Socket::getAveragePingMS("soft-haus.com"); -//printf("Ping time = %f\n",pingTime); + //float pingTime = Socket::getAveragePingMS("soft-haus.com"); + //printf("Ping time = %f\n",pingTime); -// Load the language strings - Lang & lang = Lang::getInstance (); - string - language = config.getString ("Lang"); - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_USE_LANGUAGE]) - == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_USE_LANGUAGE]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_USE_LANGUAGE]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - language = paramPartTokens[1]; - printf ("Forcing language [%s]\n", language.c_str ()); - } - else - { - printf - ("\nInvalid missing language specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - return 1; - } - } - else - { + // Load the language strings + Lang & lang = Lang::getInstance(); + string + language = config.getString("Lang"); + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_USE_LANGUAGE]) + == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_USE_LANGUAGE]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_USE_LANGUAGE]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + language = paramPartTokens[1]; + printf("Forcing language [%s]\n", language.c_str()); + } else { + printf + ("\nInvalid missing language specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + return 1; + } + } else { #ifdef _WIN32 - int - localeBufferSize = - GetLocaleInfo (LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, - NULL, 0); - wchar_t * - sysLocale = new wchar_t[localeBufferSize]; - GetLocaleInfo (LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, - sysLocale, localeBufferSize); + int + localeBufferSize = + GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, + NULL, 0); + wchar_t * + sysLocale = new wchar_t[localeBufferSize]; + GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, + sysLocale, localeBufferSize); -//String langValue(sysLocale); -//const char *lang_locale = langValue.c_str(); - char - langValue[1024] = ""; - wcstombs (langValue, sysLocale, 1023); - const char * - lang_locale = &langValue[0]; + //String langValue(sysLocale); + //const char *lang_locale = langValue.c_str(); + char + langValue[1024] = ""; + wcstombs(langValue, sysLocale, 1023); + const char * + lang_locale = &langValue[0]; - delete[]sysLocale; + delete[]sysLocale; #else - const char * - lang_locale = setlocale (LC_ALL, ""); + const char * + lang_locale = setlocale(LC_ALL, ""); #endif - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Locale is: [%s]\n", lang_locale); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Locale is: [%s]\n", lang_locale); - if (lang_locale != NULL && strlen (lang_locale) >= 2) - { - if (config.getBool ("AutoLocaleLanguageDetect", "true") == true) - { - language = lang_locale; - language = language.substr (0, 2); - printf ("Auto setting language [%s]\n", language.c_str ()); + if (lang_locale != NULL && strlen(lang_locale) >= 2) { + if (config.getBool("AutoLocaleLanguageDetect", "true") == true) { + language = lang_locale; + language = language.substr(0, 2); + printf("Auto setting language [%s]\n", language.c_str()); - config.setString ("AutoLocaleLanguageDetect", "false"); - config.save (); - } - } - } + config.setString("AutoLocaleLanguageDetect", "false"); + config.save(); + } + } + } - if (hasCommandArgument - (argc, argv, string (GAME_ARGS[GAME_ARG_AUTO_TEST])) == true - || Config::getInstance ().getBool ("AutoTest", "false") == true) - { - printf ("Running in auto test mode\n"); - } - if (hasCommandArgument - (argc, argv, string (GAME_ARGS[GAME_ARG_AUTO_TEST])) == true) - { - Config::getInstance ().setBool ("AutoTest", true, true); + if (hasCommandArgument + (argc, argv, string(GAME_ARGS[GAME_ARG_AUTO_TEST])) == true + || Config::getInstance().getBool("AutoTest", "false") == true) { + printf("Running in auto test mode\n"); + } + if (hasCommandArgument + (argc, argv, string(GAME_ARGS[GAME_ARG_AUTO_TEST])) == true) { + Config::getInstance().setBool("AutoTest", true, true); - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_AUTO_TEST]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_AUTO_TEST]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - vector < string > paramPartTokens2; - Tokenize (paramPartTokens[1], paramPartTokens2, ","); - if (paramPartTokens2.empty () == false - && paramPartTokens2[0].length () > 0) - { - string - newMaxSeconds = paramPartTokens2[0]; - time_t - newTimeMaxSeconds = strToInt (newMaxSeconds); - AutoTest::setMaxGameTime (newTimeMaxSeconds); - printf - ("Forcing maximum game time to [%ld] seconds (%.2f minutes)\n", - (long int) newTimeMaxSeconds, - ((double) newTimeMaxSeconds / 60.0)); - } - if (paramPartTokens2.size () >= 3 - && paramPartTokens2[2].length () > 0) - { - string - autoTestCmd = paramPartTokens2[2]; - if (autoTestCmd == "exit") - { - printf - ("Detected auto test command [%s], will exit after game.\n", - autoTestCmd.c_str ()); + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_AUTO_TEST]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_AUTO_TEST]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + vector < string > paramPartTokens2; + Tokenize(paramPartTokens[1], paramPartTokens2, ","); + if (paramPartTokens2.empty() == false + && paramPartTokens2[0].length() > 0) { + string + newMaxSeconds = paramPartTokens2[0]; + time_t + newTimeMaxSeconds = strToInt(newMaxSeconds); + AutoTest::setMaxGameTime(newTimeMaxSeconds); + printf + ("Forcing maximum game time to [%ld] seconds (%.2f minutes)\n", + (long int) newTimeMaxSeconds, + ((double) newTimeMaxSeconds / 60.0)); + } + if (paramPartTokens2.size() >= 3 + && paramPartTokens2[2].length() > 0) { + string + autoTestCmd = paramPartTokens2[2]; + if (autoTestCmd == "exit") { + printf + ("Detected auto test command [%s], will exit after game.\n", + autoTestCmd.c_str()); - AutoTest::setWantExitGameWhenDone (true); - } - else - { - printf - ("WARNING: Detected and UNKNOWN auto test command [%s].\n", - autoTestCmd.c_str ()); - } - } + AutoTest::setWantExitGameWhenDone(true); + } else { + printf + ("WARNING: Detected and UNKNOWN auto test command [%s].\n", + autoTestCmd.c_str()); + } + } - if (paramPartTokens2.size () >= 2 - && paramPartTokens2[1].length () > 0) - { - string - newGameSettingsFileToLoad = paramPartTokens2[1]; + if (paramPartTokens2.size() >= 2 + && paramPartTokens2[1].length() > 0) { + string + newGameSettingsFileToLoad = paramPartTokens2[1]; - printf ("About to auto test using game settings file [%s]\n", - newGameSettingsFileToLoad.c_str ()); - AutoTest::setLoadGameSettingsFile (newGameSettingsFileToLoad); - } - } - } + printf("About to auto test using game settings file [%s]\n", + newGameSettingsFileToLoad.c_str()); + AutoTest::setLoadGameSettingsFile(newGameSettingsFileToLoad); + } + } + } - Renderer & renderer = Renderer::getInstance (); - lang.loadGameStrings (language, false, true); + Renderer & renderer = Renderer::getInstance(); + lang.loadGameStrings(language, false, true); - if (lang.hasString ("FONT_HEIGHT_TEXT")) - { - ::Shared::Graphics::Font::langHeightText = - config. - getString ("FONT_HEIGHT_TEXT",::Shared::Graphics::Font:: - langHeightText.c_str ()); - } + if (lang.hasString("FONT_HEIGHT_TEXT")) { + ::Shared::Graphics::Font::langHeightText = + config. + getString("FONT_HEIGHT_TEXT", ::Shared::Graphics::Font:: + langHeightText.c_str()); + } - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_FONT_BASESIZE]) - == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_FONT_BASESIZE]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_FONT_BASESIZE]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - string - newfontBaseSize = paramPartTokens[1]; - printf ("Forcing font base size[%s]\n", newfontBaseSize.c_str ()); + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_FONT_BASESIZE]) + == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_FONT_BASESIZE]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_FONT_BASESIZE]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + string + newfontBaseSize = paramPartTokens[1]; + printf("Forcing font base size[%s]\n", newfontBaseSize.c_str()); - ::Shared::Graphics::Font::baseSize = strToInt (newfontBaseSize); - } - else - { - printf - ("\nInvalid missing font base size specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); + ::Shared::Graphics::Font::baseSize = strToInt(newfontBaseSize); + } else { + printf + ("\nInvalid missing font base size specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); - return 1; - } - } + return 1; + } + } - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::PlatformContextGl::charSet = %d, Font::fontIsMultibyte = %d, Font::fontIsRightToLeft = %d\n", - __FILE__, __FUNCTION__, - __LINE__,::Shared::Graphics::Font:: - charCount,::Shared::Graphics::Font:: - fontTypeName. - c_str (),::Shared::Platform:: - PlatformContextGl::charSet,::Shared:: - Graphics::Font::fontIsMultibyte,::Shared:: - Graphics::Font::fontIsRightToLeft); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("Using Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::PlatformContextGl::charSet = %d, Font::fontIsMultibyte = %d, Font::fontIsRightToLeft = %d\n",:: - Shared::Graphics::Font::charCount,::Shared::Graphics::Font:: - fontTypeName. - c_str (),::Shared::Platform::PlatformContextGl::charSet,:: - Shared::Graphics::Font::fontIsMultibyte,::Shared::Graphics:: - Font::fontIsRightToLeft); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::PlatformContextGl::charSet = %d, Font::fontIsMultibyte = %d, Font::fontIsRightToLeft = %d\n", + __FILE__, __FUNCTION__, + __LINE__, ::Shared::Graphics::Font:: + charCount, ::Shared::Graphics::Font:: + fontTypeName. + c_str(), ::Shared::Platform:: + PlatformContextGl::charSet, ::Shared:: + Graphics::Font::fontIsMultibyte, ::Shared:: + Graphics::Font::fontIsRightToLeft); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("Using Font::charCount = %d, Font::fontTypeName [%s] Shared::Platform::PlatformContextGl::charSet = %d, Font::fontIsMultibyte = %d, Font::fontIsRightToLeft = %d\n", :: + Shared::Graphics::Font::charCount, ::Shared::Graphics::Font:: + fontTypeName. + c_str(), ::Shared::Platform::PlatformContextGl::charSet, :: + Shared::Graphics::Font::fontIsMultibyte, ::Shared::Graphics:: + Font::fontIsRightToLeft); - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_USE_FONT]) == - true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_USE_FONT]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_USE_FONT]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - string - newfont = paramPartTokens[1]; + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_USE_FONT]) == + true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_USE_FONT]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_USE_FONT]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + string + newfont = paramPartTokens[1]; - Properties::applyTagsToValue (newfont); - printf ("Forcing font [%s]\n", newfont.c_str ()); + Properties::applyTagsToValue(newfont); + printf("Forcing font [%s]\n", newfont.c_str()); #if defined(WIN32) - string - newEnvValue = "MEGAGLEST_FONT=" + newfont; - _putenv (newEnvValue.c_str ()); + string + newEnvValue = "MEGAGLEST_FONT=" + newfont; + _putenv(newEnvValue.c_str()); #else - setenv ("MEGAGLEST_FONT", newfont.c_str (), 1); + setenv("MEGAGLEST_FONT", newfont.c_str(), 1); #endif - } - else - { - printf - ("\nInvalid missing font specified on commandline [%s] value [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - return 1; - } - } - - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == true) - { - return handleCreateDataArchivesCommand (argc, argv); - } - - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]) - == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]) == true) - { - return handleShowCRCValuesCommand (argc, argv); - } - - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_LIST_MAPS]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == - true) - { - return handleListDataCommand (argc, argv); - - } - - program = new Program (); - mainProgram = program; - renderer.setProgram (program); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugPathFinder). - enabled == true) - { - renderer.setAllowRenderUnitTitles (SystemFlags::getSystemSettingType - (SystemFlags::debugPathFinder). - enabled); - SystemFlags::OutputDebug (SystemFlags::debugPathFinder, - "In [%s::%s Line: %d] renderer.setAllowRenderUnitTitles = %d\n", - __FILE__, __FUNCTION__, __LINE__, - SystemFlags:: - getSystemSettingType (SystemFlags:: - debugPathFinder). - enabled); - } - renderer.setAllowRenderUnitTitles (true); - - string - screenShotsPath = userData + GameConstants::folder_path_screenshots; - if (isdir (screenShotsPath.c_str ()) == false) - { - createDirectoryPaths (screenShotsPath); - } - -// Cache Player textures - START - string - data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - std::map < int, - Texture2D * >& - crcPlayerTextureCache = - CacheManager::getCachedItem < std::map < int, - Texture2D * > >(GameConstants::playerTextureCacheLookupKey); - for (int index = 0; index < GameConstants::maxPlayers; ++index) - { - string - playerTexture = - getGameCustomCoreDataPath (data_path, - "data/core/faction_textures/faction" + - intToStr (index) + ".tga"); - if (fileExists (playerTexture) == true) - { - Texture2D * - texture = Renderer::getInstance ().newTexture2D (rsGlobal); - if (texture) - { - texture->load (playerTexture); - } - crcPlayerTextureCache[index] = texture; - } - else - { - crcPlayerTextureCache[index] = NULL; - } - } -// Cache Player textures - END - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - mainWindow = new MainWindow (program); - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - GameSettings - startupGameSettings; - -//parse command line - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_SERVER]) == - true) - { - program->initServer (mainWindow, false, true); - gameInitialized = true; - } - else - if (hasCommandArgument - (argc, argv, - string (GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) - { - program->initServer (mainWindow, false, true, true); - gameInitialized = true; - } - else - if (hasCommandArgument - (argc, argv, - string (GAME_ARGS[GAME_ARG_AUTOSTART_LASTGAME])) == true) - { - program->initServer (mainWindow, true, false); - gameInitialized = true; - } - else - if (hasCommandArgument - (argc, argv, - string (GAME_ARGS[GAME_ARG_AUTOSTART_LAST_SAVED_GAME])) == - true) - { - string - fileName = ""; - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS - [GAME_ARG_AUTOSTART_LAST_SAVED_GAME]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex >= 0) - { - string - loadfileName = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (loadfileName, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - fileName = paramPartTokens[1]; - - if (fileExists (fileName) == false) - { -// Save the file now - string - saveGameFile = "saved/" + fileName; - if (getGameReadWritePath - (GameConstants::path_logs_CacheLookupKey) != "") - { - saveGameFile = - getGameReadWritePath - (GameConstants::path_logs_CacheLookupKey) + saveGameFile; - } - else - { - saveGameFile = userData + saveGameFile; - } - if (fileExists (saveGameFile) == true) - { - fileName = saveGameFile; - } - } - - if (fileExists (fileName) == false) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "File specified for loading a saved game cannot be found: [%s]", - fileName.c_str ()); - printf - ("\n\n======================================================================================\n%s\n======================================================================================\n\n\n", - szBuf); - - throw - megaglest_runtime_error (szBuf); - } - } - } - program->initSavedGame (mainWindow, false, fileName); - gameInitialized = true; - } - else - if (hasCommandArgument - (argc, argv, string (GAME_ARGS[GAME_ARG_PREVIEW_MAP])) == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_PREVIEW_MAP]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_PREVIEW_MAP]), - &foundParamIndIndex); - } - string - mapName = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (mapName, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - vector < string > paramPartTokens2; - string - tileset = "forest"; - Tokenize (paramPartTokens[1], paramPartTokens2, ","); - if (paramPartTokens2.size () >= 2 - && paramPartTokens2[1].length () > 0) - { - tileset = paramPartTokens2[1]; - } - string - autoloadMapName = paramPartTokens2[0]; - - GameSettings * - gameSettings = &startupGameSettings; - gameSettings->setMap (autoloadMapName); - gameSettings->setTileset (tileset); - gameSettings->setTech ("megapack"); - gameSettings->setDefaultUnits (false); - gameSettings->setDefaultResources (false); - gameSettings->setDefaultVictoryConditions (true); - gameSettings->setFogOfWar (false); - gameSettings->setAllowObservers (true); - gameSettings->setPathFinderType (pfBasic); - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - ControlType - ct = ctClosed; - - gameSettings->setNetworkPlayerStatuses (i, npst_None); - gameSettings->setFactionControl (i, ct); - gameSettings->setStartLocationIndex (i, i); - gameSettings->setResourceMultiplierIndex (i, 10); - gameSettings->setNetworkPlayerName (i, - GameConstants:: - NETWORK_SLOT_CLOSED_SLOTNAME); - } - - ControlType - ct = ctHuman; - - gameSettings->setNetworkPlayerStatuses (0, npst_None); - gameSettings->setFactionControl (0, ct); - gameSettings->setFactionTypeName (0, - formatString - (GameConstants:: - OBSERVER_SLOTNAME)); - gameSettings->setTeam (0, - GameConstants::maxPlayers + fpt_Observer - - 1); - gameSettings->setStartLocationIndex (0, 0); - gameSettings->setNetworkPlayerName (0, - GameConstants:: - OBSERVER_SLOTNAME); - - gameSettings->setFactionCount (1); - - Config & config = Config::getInstance (); - gameSettings->setEnableServerControlledAI (config.getBool - ("ServerControlledAI", - "true")); - gameSettings->setNetworkFramePeriod (config.getInt - ("NetworkSendFrameCount", - "20")); - - program->initServer (mainWindow, gameSettings); - gameInitialized = true; - } - else - { - printf - ("\nInvalid map name specified on commandline [%s] map [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - printParameterHelp (argv[0], foundInvalidArgs); - delete - mainWindow; - mainWindow = NULL; - return 1; - } - } - - else - if (hasCommandArgument - (argc, argv, string (GAME_ARGS[GAME_ARG_CONNECT])) == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_CONNECT]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_CONNECT]), - &foundParamIndIndex); - } - string - serverToConnectTo = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (serverToConnectTo, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - string - autoConnectServer = paramPartTokens[1]; - - int - port = config.getInt ("PortServer", - intToStr (GameConstants:: - serverPort).c_str ()); - vector < string > paramPartTokens2; - Tokenize (autoConnectServer, paramPartTokens2, ":"); - autoConnectServer = paramPartTokens2[0]; - if (paramPartTokens2.size () >= 2 - && paramPartTokens2[1].length () > 0) - { - port = strToInt (paramPartTokens2[1]); - } - - printf ("Connecting to host [%s] using port: %d\n", - autoConnectServer.c_str (), port); - if (autoConnectServer == "auto-connect") - { - program->initClientAutoFindHost (mainWindow); - } - else - { - program->initClient (mainWindow, autoConnectServer, port); - } - gameInitialized = true; - } - else - { - - printf - ("\nInvalid host specified on commandline [%s] host [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - printParameterHelp (argv[0], foundInvalidArgs); - delete - mainWindow; - mainWindow = NULL; - return 1; - } - } - - else - if (hasCommandArgument - (argc, argv, string (GAME_ARGS[GAME_ARG_CLIENT])) == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_CLIENT]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_CLIENT]), - &foundParamIndIndex); - } - string - serverToConnectTo = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (serverToConnectTo, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - string - autoConnectServer = paramPartTokens[1]; - - if (autoConnectServer == "auto-connect") - { - program->initClientAutoFindHost (mainWindow); - } - else - { - program->initClient (mainWindow, autoConnectServer); - } - gameInitialized = true; - } - else - { - - printf - ("\nInvalid host specified on commandline [%s] host [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - printParameterHelp (argv[0], foundInvalidArgs); - delete - mainWindow; - mainWindow = NULL; - return 1; - } - } - else - if (hasCommandArgument - (argc, argv, string (GAME_ARGS[GAME_ARG_LOADSCENARIO])) == true) - { - - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_LOADSCENARIO]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_LOADSCENARIO]), - &foundParamIndIndex); - } - string - scenarioName = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (scenarioName, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - string - autoloadScenarioName = paramPartTokens[1]; - - program->initScenario (mainWindow, autoloadScenarioName); - gameInitialized = true; - } - else - { - printf - ("\nInvalid scenario name specified on commandline [%s] scenario [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - printParameterHelp (argv[0], foundInvalidArgs); - delete - mainWindow; - mainWindow = NULL; - return 1; - } - } - else - { - program->initNormal (mainWindow); - } - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] OpenGL Info:\n%s\n", - __FILE__, __FUNCTION__, __LINE__, - renderer.getGlInfo ().c_str ()); - - if (hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_OPENGL_INFO]) - == true) - { - printf ("%s", renderer.getGlInfo ().c_str ()); - printf ("%s", renderer.getGlMoreInfo ().c_str ()); - - delete - mainWindow; - mainWindow = NULL; - return 0; - } - - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_CONVERT_MODELS]) == true) - { - int - foundParamIndIndex = -1; - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_CONVERT_MODELS]) + - string ("="), &foundParamIndIndex); - if (foundParamIndIndex < 0) - { - hasCommandArgument (argc, argv, - string (GAME_ARGS[GAME_ARG_CONVERT_MODELS]), - &foundParamIndIndex); - } - string - paramValue = argv[foundParamIndIndex]; - vector < string > paramPartTokens; - Tokenize (paramValue, paramPartTokens, "="); - if (paramPartTokens.size () >= 2 - && paramPartTokens[1].length () > 0) - { - string - modelFile = paramPartTokens[1]; - printf ("About to convert model(s) [%s]\n", modelFile.c_str ()); - - string - textureFormat = ""; - if (paramPartTokens.size () >= 3 - && paramPartTokens[1].length () > 0) - { - textureFormat = paramPartTokens[2]; - printf ("About to convert using texture format [%s]\n", - textureFormat.c_str ()); - } - - bool - keepsmallest = false; - if (paramPartTokens.size () >= 4 - && paramPartTokens[1].length () > 0) - { - keepsmallest = (paramPartTokens[3] == "keepsmallest"); - printf ("About to convert using keepsmallest = %d\n", - keepsmallest); - } - - showCursor (true); - - const - Metrics & - metrics = Metrics::getInstance (); - renderer.clearBuffers (); - renderer.clearZBuffer (); - renderer.reset2d (); - - if (CoreData::getInstance ().getMenuFontBig3D () != NULL) - { - renderer.renderText3D ("Please wait, converting models...", - CoreData::getInstance (). - getMenuFontBig3D (), Vec3f (1.f, 1.f, - 0.f), - (metrics.getScreenW () / 2) - 400, - (metrics.getScreenH () / 2), true); - } - else - { - renderer.renderText ("Please wait, converting models...", - CoreData::getInstance ().getMenuFontBig (), - Vec3f (1.f, 1.f, 0.f), - (metrics.getScreenW () / 2) - 400, - (metrics.getScreenH () / 2), true); - } - renderer.swapBuffers (); - - std::vector < string > models; - if (isdir (modelFile.c_str ()) == true) - { - models = - getFolderTreeContentsListRecursively (modelFile, ".g3d"); - } - else - { - models.push_back (modelFile); - } - - sleep (0); - ::Shared::Platform::Window::handleEvent (); - SDL_PumpEvents (); - - int - result = 0; - char - szTextBuf[8096] = ""; - for (unsigned int i = 0; i < models.size (); ++i) - { - string & file = models[i]; - - renderer.clearBuffers (); - renderer.clearZBuffer (); - renderer.reset2d (); - snprintf (szTextBuf, 8096, - "Please wait, converting models [%u of " - MG_SIZE_T_SPECIFIER "] ...", i, models.size ()); - - if (CoreData::getInstance ().getMenuFontBig3D () != NULL) - { - renderer.renderText3D (szTextBuf, - CoreData::getInstance (). - getMenuFontBig3D (), Vec3f (1.f, 1.f, - 0.f), - (metrics.getScreenW () / 2) - 400, - (metrics.getScreenH () / 2), true); - } - else - { - renderer.renderText (szTextBuf, - CoreData::getInstance (). - getMenuFontBig (), Vec3f (1.f, 1.f, 0.f), - (metrics.getScreenW () / 2) - 400, - (metrics.getScreenH () / 2), true); - } - renderer.swapBuffers (); - - sleep (0); - ::Shared::Platform::Window::handleEvent (); - SDL_PumpEvents (); - - try - { - printf ("About to load model [%s] [%u of " MG_SIZE_T_SPECIFIER - "]\n", file.c_str (), i, models.size ()); - Model * - model = renderer.newModel (rsGlobal, file); - printf ("About to save converted model [%s]\n", - file.c_str ()); - model->save (file, textureFormat, keepsmallest); - Renderer::getInstance ().endModel (rsGlobal, model); - } - catch (const exception & ex) - { - result = 1; - printf ("ERROR loading model [%s] message [%s]\n", - file.c_str (), ex.what ()); - } - - } - - delete - mainWindow; - mainWindow = NULL; - return result; - } - else - { - printf - ("\nInvalid model specified on commandline [%s] texture [%s]\n\n", - argv[foundParamIndIndex], - (paramPartTokens.size () >= - 2 ? paramPartTokens[1].c_str () : NULL)); - printParameterHelp (argv[0], foundInvalidArgs); - delete - mainWindow; - mainWindow = NULL; - return 1; - } - } - - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == - true - || hasCommandArgument (argc, argv, - GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == - true) - { - runTechValidationReport (argc, argv); - - delete - mainWindow; - mainWindow = NULL; - return 0; - } - - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == true) - { - runTechTranslationExtraction (argc, argv); - delete - mainWindow; - mainWindow = NULL; - return 0; - } - - if (hasCommandArgument - (argc, argv, GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true) - { - runTilesetValidationReport (argc, argv); - - delete - mainWindow; - mainWindow = NULL; - return 0; - } - - gameInitialized = true; - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - CheckForDuplicateData (); - - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - -//throw "BLAH!"; - -// START Test out SIGSEGV error handling -//int *foo = (int*)-1; // make a bad pointer -//printf("%d\n", *foo); // causes segfault -// END - - bool - startCRCPrecacheThread = - config.getBool ("PreCacheCRCThread", "true"); -//printf("### In [%s::%s Line: %d] precache thread enabled = %d SystemFlags::VERBOSE_MODE_ENABLED = %d\n",__FILE__,__FUNCTION__,__LINE__,startCRCPrecacheThread,SystemFlags::VERBOSE_MODE_ENABLED); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] precache thread enabled = %d\n", - __FILE__, __FUNCTION__, __LINE__, startCRCPrecacheThread); - if (startCRCPrecacheThread == true - && GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - static - string - mutexOwnerId = - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - string ("_") + intToStr (__LINE__); - vector < string > techDataPaths = - config.getPathListForType (ptTechs); - - FileCRCPreCacheThread::setPreCacheThreadCacheLookupKey - (GameConstants::preCacheThreadCacheLookupKey); - FileCRCPreCacheThread *& - preCacheCRCThreadPtr = - CacheManager::getCachedItem < - FileCRCPreCacheThread * - >(GameConstants::preCacheThreadCacheLookupKey); - if (preCacheCRCThreadPtr == NULL) - { - preCacheCRCThreadPtr = new FileCRCPreCacheThread (); - } - preCacheThread = preCacheCRCThreadPtr; - preCacheThread->setUniqueID (mutexOwnerId); - preCacheThread->setTechDataPaths (techDataPaths); -//preCacheThread->setFileCRCPreCacheThreadCallbackInterface(&preCacheThreadGame); - preCacheThread->start (); - } - - auto_ptr < NavtiveLanguageNameListCacheGenerator > lngCacheGen; - auto_ptr < SimpleTaskThread > languageCacheGen; - - bool - startNativeLanguageNamesPrecacheThread = - config.getBool ("PreCacheNativeLanguageNamesThread", "true"); - if (startNativeLanguageNamesPrecacheThread == true - && GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - lngCacheGen.reset (new NavtiveLanguageNameListCacheGenerator ()); - languageCacheGen.reset (new - SimpleTaskThread (lngCacheGen.get (), 1)); - - languageCacheGen->start (); - } - -// test -//Shared::Platform::MessageBox(NULL,"Mark's test.","Test",0); -//throw megaglest_runtime_error("test!"); -//ExceptionHandler::DisplayMessage("test!", false); - -// Check for commands being input from stdin - string - command = ""; + } else { + printf + ("\nInvalid missing font specified on commandline [%s] value [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + return 1; + } + } + + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]) == true) { + return handleCreateDataArchivesCommand(argc, argv); + } + + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]) + == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]) == true) { + return handleShowCRCValuesCommand(argc, argv); + } + + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_LIST_MAPS]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == + true) { + return handleListDataCommand(argc, argv); + + } + + program = new Program(); + mainProgram = program; + renderer.setProgram(program); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder). + enabled == true) { + renderer.setAllowRenderUnitTitles(SystemFlags::getSystemSettingType + (SystemFlags::debugPathFinder). + enabled); + SystemFlags::OutputDebug(SystemFlags::debugPathFinder, + "In [%s::%s Line: %d] renderer.setAllowRenderUnitTitles = %d\n", + __FILE__, __FUNCTION__, __LINE__, + SystemFlags:: + getSystemSettingType(SystemFlags:: + debugPathFinder). + enabled); + } + renderer.setAllowRenderUnitTitles(true); + + string + screenShotsPath = userData + GameConstants::folder_path_screenshots; + if (isdir(screenShotsPath.c_str()) == false) { + createDirectoryPaths(screenShotsPath); + } + + // Cache Player textures - START + string + data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + std::map < int, + Texture2D * >& + crcPlayerTextureCache = + CacheManager::getCachedItem < std::map < int, + Texture2D * > >(GameConstants::playerTextureCacheLookupKey); + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + string + playerTexture = + getGameCustomCoreDataPath(data_path, + "data/core/faction_textures/faction" + + intToStr(index) + ".tga"); + if (fileExists(playerTexture) == true) { + Texture2D * + texture = Renderer::getInstance().newTexture2D(rsGlobal); + if (texture) { + texture->load(playerTexture); + } + crcPlayerTextureCache[index] = texture; + } else { + crcPlayerTextureCache[index] = NULL; + } + } + // Cache Player textures - END + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + mainWindow = new MainWindow(program); + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + GameSettings + startupGameSettings; + + //parse command line + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_SERVER]) == + true) { + program->initServer(mainWindow, false, true); + gameInitialized = true; + } else + if (hasCommandArgument + (argc, argv, + string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true) { + program->initServer(mainWindow, false, true, true); + gameInitialized = true; + } else + if (hasCommandArgument + (argc, argv, + string(GAME_ARGS[GAME_ARG_AUTOSTART_LASTGAME])) == true) { + program->initServer(mainWindow, true, false); + gameInitialized = true; + } else + if (hasCommandArgument + (argc, argv, + string(GAME_ARGS[GAME_ARG_AUTOSTART_LAST_SAVED_GAME])) == + true) { + string + fileName = ""; + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS + [GAME_ARG_AUTOSTART_LAST_SAVED_GAME]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex >= 0) { + string + loadfileName = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(loadfileName, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + fileName = paramPartTokens[1]; + + if (fileExists(fileName) == false) { + // Save the file now + string + saveGameFile = "saved/" + fileName; + if (getGameReadWritePath + (GameConstants::path_logs_CacheLookupKey) != "") { + saveGameFile = + getGameReadWritePath + (GameConstants::path_logs_CacheLookupKey) + saveGameFile; + } else { + saveGameFile = userData + saveGameFile; + } + if (fileExists(saveGameFile) == true) { + fileName = saveGameFile; + } + } + + if (fileExists(fileName) == false) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "File specified for loading a saved game cannot be found: [%s]", + fileName.c_str()); + printf + ("\n\n======================================================================================\n%s\n======================================================================================\n\n\n", + szBuf); + + throw + megaglest_runtime_error(szBuf); + } + } + } + program->initSavedGame(mainWindow, false, fileName); + gameInitialized = true; + } else + if (hasCommandArgument + (argc, argv, string(GAME_ARGS[GAME_ARG_PREVIEW_MAP])) == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_PREVIEW_MAP]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_PREVIEW_MAP]), + &foundParamIndIndex); + } + string + mapName = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(mapName, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + vector < string > paramPartTokens2; + string + tileset = "forest"; + Tokenize(paramPartTokens[1], paramPartTokens2, ","); + if (paramPartTokens2.size() >= 2 + && paramPartTokens2[1].length() > 0) { + tileset = paramPartTokens2[1]; + } + string + autoloadMapName = paramPartTokens2[0]; + + GameSettings * + gameSettings = &startupGameSettings; + gameSettings->setMap(autoloadMapName); + gameSettings->setTileset(tileset); + gameSettings->setTech("megapack"); + gameSettings->setDefaultUnits(false); + gameSettings->setDefaultResources(false); + gameSettings->setDefaultVictoryConditions(true); + gameSettings->setFogOfWar(false); + gameSettings->setAllowObservers(true); + gameSettings->setPathFinderType(pfBasic); + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + ControlType + ct = ctClosed; + + gameSettings->setNetworkPlayerStatuses(i, npst_None); + gameSettings->setFactionControl(i, ct); + gameSettings->setStartLocationIndex(i, i); + gameSettings->setResourceMultiplierIndex(i, 10); + gameSettings->setNetworkPlayerName(i, + GameConstants:: + NETWORK_SLOT_CLOSED_SLOTNAME); + } + + ControlType + ct = ctHuman; + + gameSettings->setNetworkPlayerStatuses(0, npst_None); + gameSettings->setFactionControl(0, ct); + gameSettings->setFactionTypeName(0, + formatString + (GameConstants:: + OBSERVER_SLOTNAME)); + gameSettings->setTeam(0, + GameConstants::maxPlayers + fpt_Observer - + 1); + gameSettings->setStartLocationIndex(0, 0); + gameSettings->setNetworkPlayerName(0, + GameConstants:: + OBSERVER_SLOTNAME); + + gameSettings->setFactionCount(1); + + Config & config = Config::getInstance(); + gameSettings->setEnableServerControlledAI(config.getBool + ("ServerControlledAI", + "true")); + gameSettings->setNetworkFramePeriod(config.getInt + ("NetworkSendFrameCount", + "20")); + + program->initServer(mainWindow, gameSettings); + gameInitialized = true; + } else { + printf + ("\nInvalid map name specified on commandline [%s] map [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(argv[0], foundInvalidArgs); + delete + mainWindow; + mainWindow = NULL; + return 1; + } + } + + else + if (hasCommandArgument + (argc, argv, string(GAME_ARGS[GAME_ARG_CONNECT])) == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_CONNECT]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_CONNECT]), + &foundParamIndIndex); + } + string + serverToConnectTo = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(serverToConnectTo, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + string + autoConnectServer = paramPartTokens[1]; + + int + port = config.getInt("PortServer", + intToStr(GameConstants:: + serverPort).c_str()); + vector < string > paramPartTokens2; + Tokenize(autoConnectServer, paramPartTokens2, ":"); + autoConnectServer = paramPartTokens2[0]; + if (paramPartTokens2.size() >= 2 + && paramPartTokens2[1].length() > 0) { + port = strToInt(paramPartTokens2[1]); + } + + printf("Connecting to host [%s] using port: %d\n", + autoConnectServer.c_str(), port); + if (autoConnectServer == "auto-connect") { + program->initClientAutoFindHost(mainWindow); + } else { + program->initClient(mainWindow, autoConnectServer, port); + } + gameInitialized = true; + } else { + + printf + ("\nInvalid host specified on commandline [%s] host [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(argv[0], foundInvalidArgs); + delete + mainWindow; + mainWindow = NULL; + return 1; + } + } + + else + if (hasCommandArgument + (argc, argv, string(GAME_ARGS[GAME_ARG_CLIENT])) == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_CLIENT]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_CLIENT]), + &foundParamIndIndex); + } + string + serverToConnectTo = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(serverToConnectTo, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + string + autoConnectServer = paramPartTokens[1]; + + if (autoConnectServer == "auto-connect") { + program->initClientAutoFindHost(mainWindow); + } else { + program->initClient(mainWindow, autoConnectServer); + } + gameInitialized = true; + } else { + + printf + ("\nInvalid host specified on commandline [%s] host [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(argv[0], foundInvalidArgs); + delete + mainWindow; + mainWindow = NULL; + return 1; + } + } else + if (hasCommandArgument + (argc, argv, string(GAME_ARGS[GAME_ARG_LOADSCENARIO])) == true) { + + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_LOADSCENARIO]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_LOADSCENARIO]), + &foundParamIndIndex); + } + string + scenarioName = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(scenarioName, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + string + autoloadScenarioName = paramPartTokens[1]; + + program->initScenario(mainWindow, autoloadScenarioName); + gameInitialized = true; + } else { + printf + ("\nInvalid scenario name specified on commandline [%s] scenario [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(argv[0], foundInvalidArgs); + delete + mainWindow; + mainWindow = NULL; + return 1; + } + } else { + program->initNormal(mainWindow); + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] OpenGL Info:\n%s\n", + __FILE__, __FUNCTION__, __LINE__, + renderer.getGlInfo().c_str()); + + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_OPENGL_INFO]) + == true) { + printf("%s", renderer.getGlInfo().c_str()); + printf("%s", renderer.getGlMoreInfo().c_str()); + + delete + mainWindow; + mainWindow = NULL; + return 0; + } + + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_CONVERT_MODELS]) == true) { + int + foundParamIndIndex = -1; + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_CONVERT_MODELS]) + + string("="), &foundParamIndIndex); + if (foundParamIndIndex < 0) { + hasCommandArgument(argc, argv, + string(GAME_ARGS[GAME_ARG_CONVERT_MODELS]), + &foundParamIndIndex); + } + string + paramValue = argv[foundParamIndIndex]; + vector < string > paramPartTokens; + Tokenize(paramValue, paramPartTokens, "="); + if (paramPartTokens.size() >= 2 + && paramPartTokens[1].length() > 0) { + string + modelFile = paramPartTokens[1]; + printf("About to convert model(s) [%s]\n", modelFile.c_str()); + + string + textureFormat = ""; + if (paramPartTokens.size() >= 3 + && paramPartTokens[1].length() > 0) { + textureFormat = paramPartTokens[2]; + printf("About to convert using texture format [%s]\n", + textureFormat.c_str()); + } + + bool + keepsmallest = false; + if (paramPartTokens.size() >= 4 + && paramPartTokens[1].length() > 0) { + keepsmallest = (paramPartTokens[3] == "keepsmallest"); + printf("About to convert using keepsmallest = %d\n", + keepsmallest); + } + + showCursor(true); + + const + Metrics & + metrics = Metrics::getInstance(); + renderer.clearBuffers(); + renderer.clearZBuffer(); + renderer.reset2d(); + + if (CoreData::getInstance().getMenuFontBig3D() != NULL) { + renderer.renderText3D("Please wait, converting models...", + CoreData::getInstance(). + getMenuFontBig3D(), Vec3f(1.f, 1.f, + 0.f), + (metrics.getScreenW() / 2) - 400, + (metrics.getScreenH() / 2), true); + } else { + renderer.renderText("Please wait, converting models...", + CoreData::getInstance().getMenuFontBig(), + Vec3f(1.f, 1.f, 0.f), + (metrics.getScreenW() / 2) - 400, + (metrics.getScreenH() / 2), true); + } + renderer.swapBuffers(); + + std::vector < string > models; + if (isdir(modelFile.c_str()) == true) { + models = + getFolderTreeContentsListRecursively(modelFile, ".g3d"); + } else { + models.push_back(modelFile); + } + + sleep(0); + ::Shared::Platform::Window::handleEvent(); + SDL_PumpEvents(); + + int + result = 0; + char + szTextBuf[8096] = ""; + for (unsigned int i = 0; i < models.size(); ++i) { + string & file = models[i]; + + renderer.clearBuffers(); + renderer.clearZBuffer(); + renderer.reset2d(); + snprintf(szTextBuf, 8096, + "Please wait, converting models [%u of " + MG_SIZE_T_SPECIFIER "] ...", i, models.size()); + + if (CoreData::getInstance().getMenuFontBig3D() != NULL) { + renderer.renderText3D(szTextBuf, + CoreData::getInstance(). + getMenuFontBig3D(), Vec3f(1.f, 1.f, + 0.f), + (metrics.getScreenW() / 2) - 400, + (metrics.getScreenH() / 2), true); + } else { + renderer.renderText(szTextBuf, + CoreData::getInstance(). + getMenuFontBig(), Vec3f(1.f, 1.f, 0.f), + (metrics.getScreenW() / 2) - 400, + (metrics.getScreenH() / 2), true); + } + renderer.swapBuffers(); + + sleep(0); + ::Shared::Platform::Window::handleEvent(); + SDL_PumpEvents(); + + try { + printf("About to load model [%s] [%u of " MG_SIZE_T_SPECIFIER + "]\n", file.c_str(), i, models.size()); + Model * + model = renderer.newModel(rsGlobal, file); + printf("About to save converted model [%s]\n", + file.c_str()); + model->save(file, textureFormat, keepsmallest); + Renderer::getInstance().endModel(rsGlobal, model); + } catch (const exception & ex) { + result = 1; + printf("ERROR loading model [%s] message [%s]\n", + file.c_str(), ex.what()); + } + + } + + delete + mainWindow; + mainWindow = NULL; + return result; + } else { + printf + ("\nInvalid model specified on commandline [%s] texture [%s]\n\n", + argv[foundParamIndIndex], + (paramPartTokens.size() >= + 2 ? paramPartTokens[1].c_str() : NULL)); + printParameterHelp(argv[0], foundInvalidArgs); + delete + mainWindow; + mainWindow = NULL; + return 1; + } + } + + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == + true + || hasCommandArgument(argc, argv, + GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == + true) { + runTechValidationReport(argc, argv); + + delete + mainWindow; + mainWindow = NULL; + return 0; + } + + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]) == true) { + runTechTranslationExtraction(argc, argv); + delete + mainWindow; + mainWindow = NULL; + return 0; + } + + if (hasCommandArgument + (argc, argv, GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true) { + runTilesetValidationReport(argc, argv); + + delete + mainWindow; + mainWindow = NULL; + return 0; + } + + gameInitialized = true; + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + CheckForDuplicateData(); + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + //throw "BLAH!"; + + // START Test out SIGSEGV error handling + //int *foo = (int*)-1; // make a bad pointer + //printf("%d\n", *foo); // causes segfault + // END + + bool + startCRCPrecacheThread = + config.getBool("PreCacheCRCThread", "true"); + //printf("### In [%s::%s Line: %d] precache thread enabled = %d SystemFlags::VERBOSE_MODE_ENABLED = %d\n",__FILE__,__FUNCTION__,__LINE__,startCRCPrecacheThread,SystemFlags::VERBOSE_MODE_ENABLED); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] precache thread enabled = %d\n", + __FILE__, __FUNCTION__, __LINE__, startCRCPrecacheThread); + if (startCRCPrecacheThread == true + && GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + static + string + mutexOwnerId = + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + string("_") + intToStr(__LINE__); + vector < string > techDataPaths = + config.getPathListForType(ptTechs); + + FileCRCPreCacheThread::setPreCacheThreadCacheLookupKey + (GameConstants::preCacheThreadCacheLookupKey); + FileCRCPreCacheThread *& + preCacheCRCThreadPtr = + CacheManager::getCachedItem < + FileCRCPreCacheThread * + >(GameConstants::preCacheThreadCacheLookupKey); + if (preCacheCRCThreadPtr == NULL) { + preCacheCRCThreadPtr = new FileCRCPreCacheThread(); + } + preCacheThread = preCacheCRCThreadPtr; + preCacheThread->setUniqueID(mutexOwnerId); + preCacheThread->setTechDataPaths(techDataPaths); + //preCacheThread->setFileCRCPreCacheThreadCallbackInterface(&preCacheThreadGame); + preCacheThread->start(); + } + + auto_ptr < NavtiveLanguageNameListCacheGenerator > lngCacheGen; + auto_ptr < SimpleTaskThread > languageCacheGen; + + bool + startNativeLanguageNamesPrecacheThread = + config.getBool("PreCacheNativeLanguageNamesThread", "true"); + if (startNativeLanguageNamesPrecacheThread == true + && GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + lngCacheGen.reset(new NavtiveLanguageNameListCacheGenerator()); + languageCacheGen.reset(new + SimpleTaskThread(lngCacheGen.get(), 1)); + + languageCacheGen->start(); + } + + // test + //Shared::Platform::MessageBox(NULL,"Mark's test.","Test",0); + //throw megaglest_runtime_error("test!"); + //ExceptionHandler::DisplayMessage("test!", false); + + // Check for commands being input from stdin + string + command = ""; #ifndef WIN32 - pollfd - cinfd[1]; + pollfd + cinfd[1]; #else - HANDLE - h = 0; + HANDLE + h = 0; #endif - if (disableheadless_console == false) - { + if (disableheadless_console == false) { #ifndef WIN32 -// Theoretically this should always be 0, but one fileno call isn't going to hurt, and if -// we try to run somewhere that stdin isn't fd 0 then it will still just work - cinfd[0].fd = fileno (stdin); - cinfd[0].events = POLLIN; + // Theoretically this should always be 0, but one fileno call isn't going to hurt, and if + // we try to run somewhere that stdin isn't fd 0 then it will still just work + cinfd[0].fd = fileno(stdin); + cinfd[0].events = POLLIN; #else - h = GetStdHandle (STD_INPUT_HANDLE); -//DWORD dwMode; -//GetConsoleMode(h, &dwMode); -//SetConsoleMode(h, dwMode & ~ENABLE_MOUSE_INPUT); - FlushConsoleInputBuffer (h); + h = GetStdHandle(STD_INPUT_HANDLE); + //DWORD dwMode; + //GetConsoleMode(h, &dwMode); + //SetConsoleMode(h, dwMode & ~ENABLE_MOUSE_INPUT); + FlushConsoleInputBuffer(h); #endif - } + } - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == true) - { - printf ("Headless server is now running...\n"); - printf ("To shutdown type: quit\n"); - printf ("All commands require you to press ENTER\n"); - } + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + printf("Headless server is now running...\n"); + printf("To shutdown type: quit\n"); + printf("All commands require you to press ENTER\n"); + } -//throw megaglest_runtime_error("Test!"); -//printf("About to throw an exception...\n"); -//throw 123; + //throw megaglest_runtime_error("Test!"); + //printf("About to throw an exception...\n"); + //throw 123; -//main loop - while (program->isShutdownApplicationEnabled () == false - &&::Shared::Platform::Window::handleEvent ()) - { - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == true) - { + //main loop + while (program->isShutdownApplicationEnabled() == false + && ::Shared::Platform::Window::handleEvent()) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - if (disableheadless_console == false) - { + if (disableheadless_console == false) { #ifndef WIN32 - int - pollresult = poll (cinfd, 1, 0); - int - pollerror = errno; - if (pollresult) + int + pollresult = poll(cinfd, 1, 0); + int + pollerror = errno; + if (pollresult) #else -// This is problematic because input on Windows is not line-buffered so this will return -// even if getline may block. I haven't found a good way to fix it, so for the moment -// I just strongly suggest only running the server from the Python frontend, which does -// line buffer input. This does work okay as long as the user doesn't enter characters -// without pressing enter, and then try to end the server another way (say a remote -// console command), in which case we'll still be waiting for the stdin EOL and hang. + // This is problematic because input on Windows is not line-buffered so this will return + // even if getline may block. I haven't found a good way to fix it, so for the moment + // I just strongly suggest only running the server from the Python frontend, which does + // line buffer input. This does work okay as long as the user doesn't enter characters + // without pressing enter, and then try to end the server another way (say a remote + // console command), in which case we'll still be waiting for the stdin EOL and hang. - DWORD - saveMode; - GetConsoleMode (h, &saveMode); - DWORD - dwMode = saveMode; - dwMode &= ~ENABLE_MOUSE_INPUT; - dwMode &= ~ENABLE_WINDOW_INPUT; - SetConsoleMode (h, dwMode); + DWORD + saveMode; + GetConsoleMode(h, &saveMode); + DWORD + dwMode = saveMode; + dwMode &= ~ENABLE_MOUSE_INPUT; + dwMode &= ~ENABLE_WINDOW_INPUT; + SetConsoleMode(h, dwMode); - bool - gotData = (WaitForSingleObject (h, 0) == WAIT_OBJECT_0); - SetConsoleMode (h, saveMode); - if (gotData == true) + bool + gotData = (WaitForSingleObject(h, 0) == WAIT_OBJECT_0); + SetConsoleMode(h, saveMode); + if (gotData == true) #endif - { + { #ifdef WIN32 - bool - skip = true; - DWORD - nNumberOfCharsToRead = 1024; - DWORD - nRead = 0; - INPUT_RECORD - irInRec[1025]; + bool + skip = true; + DWORD + nNumberOfCharsToRead = 1024; + DWORD + nRead = 0; + INPUT_RECORD + irInRec[1025]; - PeekConsoleInput (h, &irInRec[0], nNumberOfCharsToRead, - &nRead); - for (int i = 0; i < nRead; ++i) - { - INPUT_RECORD & inr = irInRec[i]; + PeekConsoleInput(h, &irInRec[0], nNumberOfCharsToRead, + &nRead); + for (int i = 0; i < nRead; ++i) { + INPUT_RECORD & inr = irInRec[i]; -//printf("inr.EventType = %d\n",inr.EventType); - if (inr.EventType == KEY_EVENT) - { - if (inr.Event.KeyEvent.bKeyDown) - { - char - cHoldKey = inr.Event.KeyEvent.uChar.AsciiChar; - if (cHoldKey == '\r') - { - skip = false; - break; - } - } - } - } + //printf("inr.EventType = %d\n",inr.EventType); + if (inr.EventType == KEY_EVENT) { + if (inr.Event.KeyEvent.bKeyDown) { + char + cHoldKey = inr.Event.KeyEvent.uChar.AsciiChar; + if (cHoldKey == '\r') { + skip = false; + break; + } + } + } + } #else - bool - skip = false; + bool + skip = false; #endif - if (skip == false) - { - getline (cin, command); - cin.clear (); + if (skip == false) { + getline(cin, command); + cin.clear(); - printf ("server command [%s]\n", command.c_str ()); - if (command == "quit") - { - break; - } + printf("server command [%s]\n", command.c_str()); + if (command == "quit") { + break; + } #ifndef WIN32 - if (cinfd[0].revents & POLLNVAL) - { - printf ("invalid file descriptor\n"); - } - if (cinfd[0].revents & POLLERR) - { - printf ("error in file descriptor\n"); - } - if (cinfd[0].revents & POLLHUP) - { - printf ("hang up in file descriptor\n"); - } + if (cinfd[0].revents & POLLNVAL) { + printf("invalid file descriptor\n"); + } + if (cinfd[0].revents & POLLERR) { + printf("error in file descriptor\n"); + } + if (cinfd[0].revents & POLLHUP) { + printf("hang up in file descriptor\n"); + } - if (pollresult < 0) - { - printf ("pollresult = %d errno = %d [%s]\n", pollresult, - pollerror, strerror (pollerror)); + if (pollresult < 0) { + printf("pollresult = %d errno = %d [%s]\n", pollresult, + pollerror, strerror(pollerror)); - cinfd[0].fd = fileno (stdin); - cinfd[0].events = POLLIN; - } + cinfd[0].fd = fileno(stdin); + cinfd[0].events = POLLIN; + } #endif - } - } - } -//printf("looping\n"); - } + } + } + } + //printf("looping\n"); + } - program->loop (); + program->loop(); -// Because OpenGL really doesn't do multi-threading well -// if(difftime(time(NULL),lastTextureLoadEvent) >= 3) { -// lastTextureLoadEvent = time(NULL); -// vector textureList = preCacheThread->getPendingTextureList(1); -// for(unsigned int i = 0; i < textureList.size(); ++i) { -// Texture2D * factionLogo = textureList[i]; -// if(factionLogo != NULL) { -// printf("\n\n\n\n|||||||||||||||||||||||||| Load texture [%s]\n",factionLogo->getPath().c_str()); -// //Renderer::findTexture(factionLogo); -// renderer.initTexture(rsGlobal,factionLogo); -// } -// } -// } - } + // Because OpenGL really doesn't do multi-threading well + // if(difftime(time(NULL),lastTextureLoadEvent) >= 3) { + // lastTextureLoadEvent = time(NULL); + // vector textureList = preCacheThread->getPendingTextureList(1); + // for(unsigned int i = 0; i < textureList.size(); ++i) { + // Texture2D * factionLogo = textureList[i]; + // if(factionLogo != NULL) { + // printf("\n\n\n\n|||||||||||||||||||||||||| Load texture [%s]\n",factionLogo->getPath().c_str()); + // //Renderer::findTexture(factionLogo); + // renderer.initTexture(rsGlobal,factionLogo); + // } + // } + // } + } - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == true) - { - printf ("\nHeadless server is about to quit...\n"); - } + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + printf("\nHeadless server is about to quit...\n"); + } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line: %d] starting normal application shutdown\n", - __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line: %d] starting normal application shutdown\n", + __FILE__, __FUNCTION__, __LINE__); - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - soundThreadManager = program->getSoundThreadManager (true); - if (soundThreadManager) - { - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - soundRenderer.stopAllSounds (shutdownFadeSoundMilliseconds); - chronoshutdownFadeSound.start (); - } - } + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + soundThreadManager = program->getSoundThreadManager(true); + if (soundThreadManager) { + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds); + chronoshutdownFadeSound.start(); + } + } - cleanupCRCThread (); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + cleanupCRCThread(); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - showCursor (true); -//showWindowCursorState = true; - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - } - catch (const megaglest_runtime_error & e) - { + showCursor(true); + //showWindowCursorState = true; + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } catch (const megaglest_runtime_error & e) { - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - soundThreadManager = - (program != NULL ? program->getSoundThreadManager (true) : NULL); - if (soundThreadManager) - { - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - soundRenderer.stopAllSounds (shutdownFadeSoundMilliseconds); - chronoshutdownFadeSound.start (); - } - if (program != NULL && - program->getTryingRendererInit () == true && - program->getRendererInitOk () == false) - { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + soundThreadManager = + (program != NULL ? program->getSoundThreadManager(true) : NULL); + if (soundThreadManager) { + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds); + chronoshutdownFadeSound.start(); + } + if (program != NULL && + program->getTryingRendererInit() == true && + program->getRendererInitOk() == false) { - message (e.what (), - GlobalStaticFlags::getIsNonGraphicalModeEnabled (), - tempDataLocation); - } - } + message(e.what(), + GlobalStaticFlags::getIsNonGraphicalModeEnabled(), + tempDataLocation); + } + } - if (program == NULL || program->getTryingRendererInit () == false || - (program->getTryingRendererInit () == true && - program->getRendererInitOk () == true)) - { + if (program == NULL || program->getTryingRendererInit() == false || + (program->getTryingRendererInit() == true && + program->getRendererInitOk() == true)) { - ExceptionHandler::handleRuntimeError (e); - } - } - catch (const exception & e) - { - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - soundThreadManager = - (program != NULL ? program->getSoundThreadManager (true) : NULL); - if (soundThreadManager) - { - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - soundRenderer.stopAllSounds (shutdownFadeSoundMilliseconds); - chronoshutdownFadeSound.start (); - } - } + ExceptionHandler::handleRuntimeError(e); + } + } catch (const exception & e) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + soundThreadManager = + (program != NULL ? program->getSoundThreadManager(true) : NULL); + if (soundThreadManager) { + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds); + chronoshutdownFadeSound.start(); + } + } - ExceptionHandler::handleRuntimeError (e.what (), true); - } - catch (const char *e) - { - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - soundThreadManager = - (program != NULL ? program->getSoundThreadManager (true) : NULL); - if (soundThreadManager) - { - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - soundRenderer.stopAllSounds (shutdownFadeSoundMilliseconds); - chronoshutdownFadeSound.start (); - } - } + ExceptionHandler::handleRuntimeError(e.what(), true); + } catch (const char *e) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + soundThreadManager = + (program != NULL ? program->getSoundThreadManager(true) : NULL); + if (soundThreadManager) { + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds); + chronoshutdownFadeSound.start(); + } + } - ExceptionHandler::handleRuntimeError (e, true); - } - catch (const string & ex) - { - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - soundThreadManager = - (program != NULL ? program->getSoundThreadManager (true) : NULL); - if (soundThreadManager) - { - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - soundRenderer.stopAllSounds (shutdownFadeSoundMilliseconds); - chronoshutdownFadeSound.start (); - } - } + ExceptionHandler::handleRuntimeError(e, true); + } catch (const string & ex) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + soundThreadManager = + (program != NULL ? program->getSoundThreadManager(true) : NULL); + if (soundThreadManager) { + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds); + chronoshutdownFadeSound.start(); + } + } - ExceptionHandler::handleRuntimeError (ex.c_str (), true); - } + ExceptionHandler::handleRuntimeError(ex.c_str(), true); + } #if !defined(HAVE_GOOGLE_BREAKPAD) - catch ( ...) - { - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - soundThreadManager = - (program != NULL ? program->getSoundThreadManager (true) : NULL); - if (soundThreadManager) - { - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - soundRenderer.stopAllSounds (shutdownFadeSoundMilliseconds); - chronoshutdownFadeSound.start (); - } - } + catch (...) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + soundThreadManager = + (program != NULL ? program->getSoundThreadManager(true) : NULL); + if (soundThreadManager) { + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + soundRenderer.stopAllSounds(shutdownFadeSoundMilliseconds); + chronoshutdownFadeSound.start(); + } + } - ExceptionHandler::handleRuntimeError ("Unknown error [main]!", true); - } + ExceptionHandler::handleRuntimeError("Unknown error [main]!", true); + } #endif - cleanupCRCThread (); + cleanupCRCThread(); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - delete - mainWindow; - mainWindow = NULL; + delete + mainWindow; + mainWindow = NULL; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - GraphicComponent::clearRegisteredComponents (); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + GraphicComponent::clearRegisteredComponents(); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - if (soundThreadManager) - { - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - if (Config::getInstance ().getString ("FactorySound", "") != "None" && - soundRenderer.isVolumeTurnedOff () == false) - { + if (soundThreadManager) { + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + if (Config::getInstance().getString("FactorySound", "") != "None" && + soundRenderer.isVolumeTurnedOff() == false) { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, - __LINE__); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, + __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - for (; - chronoshutdownFadeSound.getMillis () <= - shutdownFadeSoundMilliseconds;) - { - sleep (10); - } - } + for (; + chronoshutdownFadeSound.getMillis() <= + shutdownFadeSoundMilliseconds;) { + sleep(10); + } + } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - BaseThread::shutdownAndWait (soundThreadManager); + BaseThread::shutdownAndWait(soundThreadManager); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - delete - soundThreadManager; - soundThreadManager = NULL; - } + delete + soundThreadManager; + soundThreadManager = NULL; + } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - return 0; - } + return 0; + } #if defined(__GNUC__) && !defined(__FreeBSD__) && !defined(BSD) - void - handleSIGSEGV (int sig) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] Error detected: signal %d:\n", __FILE__, - __FUNCTION__, __LINE__, sig); - printf ("%s", szBuf); -//abort(); + void + handleSIGSEGV(int sig) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] Error detected: signal %d:\n", __FILE__, + __FUNCTION__, __LINE__, sig); + printf("%s", szBuf); + //abort(); - ExceptionHandler::handleRuntimeError (szBuf, true); - } + ExceptionHandler::handleRuntimeError(szBuf, true); + } #endif #if defined(HAVE_GOOGLE_BREAKPAD) # if defined(WIN32) -// Callback when minidump written. - static - bool - MinidumpCallback (const wchar_t * dump_path, - const wchar_t * minidump_id, - void *context, - EXCEPTION_POINTERS * exinfo, - MDRawAssertionInfo * assertion, bool succeeded) - { - printf ("\n======= In MinidumpCallback...\n"); - wprintf - (L"\n***ERROR details captured:\nCrash minidump folder: %s\nfile: %s.dmp\nSucceeded: %d\n", - (dump_path != NULL ? dump_path : L"(null)"), - (minidump_id != NULL ? minidump_id : L"(null)"), succeeded); + // Callback when minidump written. + static + bool + MinidumpCallback(const wchar_t * dump_path, + const wchar_t * minidump_id, + void *context, + EXCEPTION_POINTERS * exinfo, + MDRawAssertionInfo * assertion, bool succeeded) { + printf("\n======= In MinidumpCallback...\n"); + wprintf + (L"\n***ERROR details captured:\nCrash minidump folder: %s\nfile: %s.dmp\nSucceeded: %d\n", + (dump_path != NULL ? dump_path : L"(null)"), + (minidump_id != NULL ? minidump_id : L"(null)"), succeeded); - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - wchar_t - szBuf[8096]; - int - bufBytes = _snwprintf (szBuf, 8096, - L"An unhandled error was detected.\n\nA crash dump file has been created in the folder:\n%s\nCrash dump filename is: %s.dmp", - dump_path, minidump_id); - szBuf[bufBytes] = '\0'; - MessageBox (NULL, szBuf, L"Unhandled error", MB_OK | MB_SYSTEMMODAL); - } + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + wchar_t + szBuf[8096]; + int + bufBytes = _snwprintf(szBuf, 8096, + L"An unhandled error was detected.\n\nA crash dump file has been created in the folder:\n%s\nCrash dump filename is: %s.dmp", + dump_path, minidump_id); + szBuf[bufBytes] = '\0'; + MessageBox(NULL, szBuf, L"Unhandled error", MB_OK | MB_SYSTEMMODAL); + } - return succeeded; - } + return succeeded; + } # else -// Callback when minidump written. - static - bool - MinidumpCallback (const google_breakpad::MinidumpDescriptor & descriptor, - void *context, bool succeeded) - { - printf ("\n======= In MinidumpCallback...\n"); - printf - ("\n***ERROR details captured:\nCrash minidump folder: %s\nfile: %s\nSucceeded: %d\n", - descriptor.directory ().c_str (), descriptor.path (), succeeded); + // Callback when minidump written. + static + bool + MinidumpCallback(const google_breakpad::MinidumpDescriptor & descriptor, + void *context, bool succeeded) { + printf("\n======= In MinidumpCallback...\n"); + printf + ("\n***ERROR details captured:\nCrash minidump folder: %s\nfile: %s\nSucceeded: %d\n", + descriptor.directory().c_str(), descriptor.path(), succeeded); - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - char - szBuf[8096]; - snprintf (szBuf, 8096, - "An unhandled error was detected.\n\nA crash dump file has been created in the folder:\n%s\nCrash dump filename is: %s", - descriptor.directory ().c_str (), descriptor.path ()); - message (szBuf, GlobalStaticFlags::getIsNonGraphicalModeEnabled (), - tempDataLocation); - } + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + char + szBuf[8096]; + snprintf(szBuf, 8096, + "An unhandled error was detected.\n\nA crash dump file has been created in the folder:\n%s\nCrash dump filename is: %s", + descriptor.directory().c_str(), descriptor.path()); + message(szBuf, GlobalStaticFlags::getIsNonGraphicalModeEnabled(), + tempDataLocation); + } - return succeeded; - } + return succeeded; + } # endif #endif #ifdef WIN32 - void - EnableCrashingOnCrashes () - { - typedef - BOOL (WINAPI * tGetPolicy) (LPDWORD lpFlags); - typedef - BOOL (WINAPI * tSetPolicy) (DWORD dwFlags); - const - DWORD - EXCEPTION_SWALLOWING = 0x1; + void + EnableCrashingOnCrashes() { + typedef + BOOL(WINAPI * tGetPolicy) (LPDWORD lpFlags); + typedef + BOOL(WINAPI * tSetPolicy) (DWORD dwFlags); + const + DWORD + EXCEPTION_SWALLOWING = 0x1; - HMODULE - kernel32 = LoadLibraryA ("kernel32.dll"); - if (kernel32 != 0) - { - tGetPolicy - pGetPolicy = - (tGetPolicy) GetProcAddress (kernel32, - "GetProcessUserModeExceptionPolicy"); - tSetPolicy - pSetPolicy = - (tSetPolicy) GetProcAddress (kernel32, - "SetProcessUserModeExceptionPolicy"); - if (pGetPolicy && pSetPolicy) - { - DWORD - dwFlags; - if (pGetPolicy (&dwFlags)) - { -// Turn off the filter - pSetPolicy (dwFlags & ~EXCEPTION_SWALLOWING); - } - } - } - } + HMODULE + kernel32 = LoadLibraryA("kernel32.dll"); + if (kernel32 != 0) { + tGetPolicy + pGetPolicy = + (tGetPolicy) GetProcAddress(kernel32, + "GetProcessUserModeExceptionPolicy"); + tSetPolicy + pSetPolicy = + (tSetPolicy) GetProcAddress(kernel32, + "SetProcessUserModeExceptionPolicy"); + if (pGetPolicy && pSetPolicy) { + DWORD + dwFlags; + if (pGetPolicy(&dwFlags)) { + // Turn off the filter + pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING); + } + } + } + } #endif - int - glestMainSEHWrapper (int argc, char **argv) - { - int - result = 0; + int + glestMainSEHWrapper(int argc, char **argv) { + int + result = 0; #ifdef WIN32_STACK_TRACE -//printf("Hooking up WIN32_STACK_TRACE...\n"); - __try - { + //printf("Hooking up WIN32_STACK_TRACE...\n"); + __try { #endif -//application_binary= executable_path(argv[0],true); -//printf("\n\nargv0 [%s] application_binary [%s]\n\n",argv[0],application_binary.c_str()); + //application_binary= executable_path(argv[0],true); + //printf("\n\nargv0 [%s] application_binary [%s]\n\n",argv[0],application_binary.c_str()); #if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD) - if (hasCommandArgument - (argc, argv, - string (GAME_ARGS[GAME_ARG_DISABLE_SIGSEGV_HANDLER])) == false) - { - signal (SIGSEGV, handleSIGSEGV); - } + if (hasCommandArgument + (argc, argv, + string(GAME_ARGS[GAME_ARG_DISABLE_SIGSEGV_HANDLER])) == false) { + signal(SIGSEGV, handleSIGSEGV); + } -// http://developerweb.net/viewtopic.php?id=3013 -//signal(SIGPIPE, SIG_IGN); + // http://developerweb.net/viewtopic.php?id=3013 + //signal(SIGPIPE, SIG_IGN); #endif - initSpecialStrings (); + initSpecialStrings(); - IRCThread::setGlobalCacheContainerName - (GameConstants::ircClientCacheLookupKey); - result = glestMain (argc, argv); + IRCThread::setGlobalCacheContainerName + (GameConstants::ircClientCacheLookupKey); + result = glestMain(argc, argv); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - cleanupProcessObjects (); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + cleanupProcessObjects(); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); #ifdef WIN32 -//delete winSockManager; -//winSockManager = NULL; + //delete winSockManager; + //winSockManager = NULL; #endif - if (sdl_quitCalled == false) - { - sdl_quitCalled = true; - SDL_Quit (); - } + if (sdl_quitCalled == false) { + sdl_quitCalled = true; + SDL_Quit(); + } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); #ifdef WIN32_STACK_TRACE - } - __except (stackdumper (0, GetExceptionInformation (), true), - EXCEPTION_CONTINUE_SEARCH) - { - return 0; - } + } __except (stackdumper(0, GetExceptionInformation(), true), + EXCEPTION_CONTINUE_SEARCH) { + return 0; + } #endif - return result; - } + return result; + } - int - glestMainWrapper (int argc, char **argv) - { -//setlocale(LC_ALL, "zh_TW.UTF-8"); -//setlocale(LC_ALL, ""); + int + glestMainWrapper(int argc, char **argv) { + //setlocale(LC_ALL, "zh_TW.UTF-8"); + //setlocale(LC_ALL, ""); #ifdef WIN32 - EnableCrashingOnCrashes (); + EnableCrashingOnCrashes(); #endif #if defined(HAVE_GOOGLE_BREAKPAD) -/* -handler = new ExceptionHandler(const wstring& dump_path, -FilterCallback filter, -MinidumpCallback callback, -void* callback_context, -int handler_types, -MINIDUMP_TYPE dump_type, -const wchar_t* pipe_name, -const CustomClientInfo* custom_info); -*/ + /* + handler = new ExceptionHandler(const wstring& dump_path, + FilterCallback filter, + MinidumpCallback callback, + void* callback_context, + int handler_types, + MINIDUMP_TYPE dump_type, + const wchar_t* pipe_name, + const CustomClientInfo* custom_info); + */ -// See this link about swallowed exceptions in Win 7: http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/ -//DWORD dwFlags; -//if (GetProcessUserModeExceptionPolicy(&dwFlags)) { -// SetProcessUserModeExceptionPolicy(dwFlags & ~PROCESS_CALLBACK_FILTER_ENABLED); // turn off bit 1 -//} + // See this link about swallowed exceptions in Win 7: http://blog.paulbetts.org/index.php/2010/07/20/the-case-of-the-disappearing-onload-exception-user-mode-callback-exceptions-in-x64/ + //DWORD dwFlags; + //if (GetProcessUserModeExceptionPolicy(&dwFlags)) { + // SetProcessUserModeExceptionPolicy(dwFlags & ~PROCESS_CALLBACK_FILTER_ENABLED); // turn off bit 1 + //} -//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Hooking up google_breakpad::ExceptionHandler...\n"); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Hooking up google_breakpad::ExceptionHandler...\n"); # if defined(WIN32) - wstring - dumpfilepath = utf8_decode ("."); -//google_breakpad::ExceptionHandler handler(dumpfilepath, NULL, MinidumpCallback, NULL, true); - errorHandlerPtr.reset (new - google_breakpad::ExceptionHandler (dumpfilepath, - NULL, - MinidumpCallback, - NULL, - google_breakpad::ExceptionHandler:: - HANDLER_ALL)); + wstring + dumpfilepath = utf8_decode("."); + //google_breakpad::ExceptionHandler handler(dumpfilepath, NULL, MinidumpCallback, NULL, true); + errorHandlerPtr.reset(new + google_breakpad::ExceptionHandler(dumpfilepath, + NULL, + MinidumpCallback, + NULL, + google_breakpad::ExceptionHandler:: + HANDLER_ALL)); # else - google_breakpad::MinidumpDescriptor descriptor ("."); - errorHandlerPtr.reset (new - google_breakpad::ExceptionHandler (descriptor, - NULL, - MinidumpCallback, - NULL, true, - -1)); + google_breakpad::MinidumpDescriptor descriptor("."); + errorHandlerPtr.reset(new + google_breakpad::ExceptionHandler(descriptor, + NULL, + MinidumpCallback, + NULL, true, + -1)); # endif -// ExceptionHandler(const wstring& dump_path, -// FilterCallback filter, -// MinidumpCallback callback, -// void* callback_context, -// int handler_types); + // ExceptionHandler(const wstring& dump_path, + // FilterCallback filter, + // MinidumpCallback callback, + // void* callback_context, + // int handler_types); #endif @@ -9493,36 +8413,33 @@ const CustomClientInfo* custom_info); #ifdef WIN32 //winSockManager = new SocketManager(); - SocketManager - winSockManager; + SocketManager + winSockManager; #endif - bool - isSteamMode = - hasCommandArgument (argc, argv, GAME_ARGS[GAME_ARG_STEAM]); - if (isSteamMode == true) - { - if (!STEAMSHIM_init ()) - { - printf ("\nSteam API init failed, terminating.\n"); - return 42; - } - } + bool + isSteamMode = + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_STEAM]); + if (isSteamMode == true) { + if (!STEAMSHIM_init()) { + printf("\nSteam API init failed, terminating.\n"); + return 42; + } + } - int - result = glestMainSEHWrapper (argc, argv); + int + result = glestMainSEHWrapper(argc, argv); - if (isSteamMode == true) - { - printf ("\nSteam API deinit.\n"); - STEAMSHIM_deinit (); - } + if (isSteamMode == true) { + printf("\nSteam API deinit.\n"); + STEAMSHIM_deinit(); + } - return result; - } + return result; + } - } + } } //end namespace -MAIN_FUNCTION (Glest::Game::glestMainWrapper) +MAIN_FUNCTION(Glest::Game::glestMainWrapper) diff --git a/source/glest_game/main/main.h b/source/glest_game/main/main.h index d72227e13..d7f4857ec 100644 --- a/source/glest_game/main/main.h +++ b/source/glest_game/main/main.h @@ -20,95 +20,91 @@ using Shared::Platform::MouseButton; using Shared::Platform::MouseState; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class MainWindow -// -/// Main program window -// ===================================================== + // ===================================================== + // class MainWindow + // + /// Main program window + // ===================================================== - class MainWindow: - public WindowGl - { - private: - Program * program; - PopupMenu popupMenu; - int - cancelLanguageSelection; - bool triggerLanguageToggle; - string triggerLanguage; + class MainWindow : + public WindowGl { + private: + Program * program; + PopupMenu popupMenu; + int + cancelLanguageSelection; + bool triggerLanguageToggle; + string triggerLanguage; - void - showLanguages (); + void + showLanguages(); - public: - explicit MainWindow (Program * program); - ~MainWindow (); + public: + explicit MainWindow(Program * program); + ~MainWindow(); - void - setProgram (Program * program); + void + setProgram(Program * program); - virtual void - eventMouseDown (int x, int y, MouseButton mouseButton); - virtual void - eventMouseUp (int x, int y, MouseButton mouseButton); - virtual void - eventMouseDoubleClick (int x, int y, MouseButton mouseButton); - virtual void - eventMouseMove (int x, int y, const MouseState * mouseState); - virtual - bool - eventTextInput (std::string text); - virtual - bool - eventSdlKeyDown (SDL_KeyboardEvent key); - virtual void - eventKeyDown (SDL_KeyboardEvent key); - virtual void - eventMouseWheel (int x, int y, int zDelta); - virtual void - eventKeyUp (SDL_KeyboardEvent key); - virtual void - eventKeyPress (SDL_KeyboardEvent c); - virtual void - eventActivate (bool active); - virtual void - eventResize (SizeState sizeState); - virtual void - eventClose (); - virtual void - eventWindowEvent (SDL_WindowEvent event); + virtual void + eventMouseDown(int x, int y, MouseButton mouseButton); + virtual void + eventMouseUp(int x, int y, MouseButton mouseButton); + virtual void + eventMouseDoubleClick(int x, int y, MouseButton mouseButton); + virtual void + eventMouseMove(int x, int y, const MouseState * mouseState); + virtual + bool + eventTextInput(std::string text); + virtual + bool + eventSdlKeyDown(SDL_KeyboardEvent key); + virtual void + eventKeyDown(SDL_KeyboardEvent key); + virtual void + eventMouseWheel(int x, int y, int zDelta); + virtual void + eventKeyUp(SDL_KeyboardEvent key); + virtual void + eventKeyPress(SDL_KeyboardEvent c); + virtual void + eventActivate(bool active); + virtual void + eventResize(SizeState sizeState); + virtual void + eventClose(); + virtual void + eventWindowEvent(SDL_WindowEvent event); - virtual void - render (); - void - toggleLanguage (string language); - bool getTriggerLanguageToggle ()const - { - return - triggerLanguageToggle; - } - string - getTriggerLanguage () const - { - return - triggerLanguage; - } + virtual void + render(); + void + toggleLanguage(string language); + bool getTriggerLanguageToggle()const { + return + triggerLanguageToggle; + } + string + getTriggerLanguage() const { + return + triggerLanguage; + } - virtual int - getDesiredScreenWidth (); - virtual int - getDesiredScreenHeight (); + virtual int + getDesiredScreenWidth(); + virtual int + getDesiredScreenHeight(); - protected: - virtual void - eventToggleFullScreen (bool isFullscreen); - }; + protected: + virtual void + eventToggleFullScreen(bool isFullscreen); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/main/program.cpp b/source/glest_game/main/program.cpp index 0cc689526..ae316037b 100644 --- a/source/glest_game/main/program.cpp +++ b/source/glest_game/main/program.cpp @@ -42,1667 +42,1524 @@ #include "leak_dumper.h" using namespace - Shared::Util; +Shared::Util; using - namespace - Shared::Graphics; +namespace + Shared::Graphics; using - namespace - Shared::Graphics::Gl; +namespace + Shared::Graphics::Gl; // ===================================================== // class Program // ===================================================== -namespace Glest -{ - namespace Game - { - - const int - Program::maxTimes = 10; - Program * - Program::singleton = NULL; - const int - SOUND_THREAD_UPDATE_MILLISECONDS = 25; - - bool Program::wantShutdownApplicationAfterGame = false; - const char * - ProgramState::MAIN_PROGRAM_RENDER_KEY = "ZETAGLEST.RENDER"; - -// ===================================================== -// class Program::CrashProgramState -// ===================================================== - - ProgramState::ProgramState (Program * program) - { - this->program = program; - this->forceMouseRender = false; - this->mouseX = 0; - this->mouseY = 0; - this->mouse2dAnim = 0; - this->fps = 0; - this->lastFps = 0; - this->startX = 0; - this->startY = 0; - } - - void - ProgramState::restoreToStartXY () - { - SDL_WarpMouseInWindow (this->program->getWindow ()->getSDLWindow (), - startX, startY); - } - - void - ProgramState::incrementFps () - { - fps++; - } - - void - ProgramState::tick () - { - lastFps = fps; - fps = 0; - } - - bool ProgramState::canRender (bool sleepIfCannotRender) - { - int - maxFPSCap = Config::getInstance ().getInt ("RenderFPSCap", "500"); - int - sleepMillis = - Config::getInstance ().getInt ("RenderFPSCapSleepMillis", "1"); -//Renderer &renderer= Renderer::getInstance(); - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == true) - { - maxFPSCap = - Config::getInstance ().getInt ("RenderFPSCapHeadless", "250"); - sleepMillis = - Config::getInstance ().getInt ("RenderFPSCapHeadlessSleepMillis", - "1"); - } - - if (lastFps > maxFPSCap) - { - if (sleepIfCannotRender == true) - { - sleep (sleepMillis); -//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] sleeping because lastFps = %d, maxFPSCap = %d sleepMillis = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,lastFps,maxFPSCap,sleepMillis); - } - return false; - } - return true; - } - - void - ProgramState::render () - { - Renderer & renderer = Renderer::getInstance (); - - canRender (); - incrementFps (); - - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - renderer.clearBuffers (); - renderer.reset2d (); - renderer.renderMessageBox (program->getMsgBox ()); - renderer.renderMouse2d (mouseX, mouseY, mouse2dAnim); - renderer.swapBuffers (); - } - } - - void - ProgramState::update () - { - mouse2dAnim = (mouse2dAnim + 1) % Renderer::maxMouse2dAnim; - } - - void - ProgramState::mouseMove (int x, int y, const MouseState * mouseState) - { - mouseX = x; - mouseY = y; - program->getMsgBox ()->mouseMove (x, y); - } - - Program::ShowMessageProgramState::ShowMessageProgramState (Program * - program, - const char - *msg): - ProgramState (program) - { - userWantsExit = false; - msgBox.registerGraphicComponent ("ShowMessageProgramState", "msgBox"); - msgBox.init ("Ok"); - - if (msg) - { - fprintf (stderr, "%s\n", msg); - msgBox.setText (msg); - } - else - { - msgBox.setText ("ZetaGlest has crashed."); - } - - mouse2dAnim = mouseY = mouseX = 0; - this->msg = (msg ? msg : ""); - } - - void - Program::ShowMessageProgramState::render () - { - Renderer & renderer = Renderer::getInstance (); - renderer.clearBuffers (); - renderer.reset2d (); - renderer.renderMessageBox (&msgBox); - renderer.renderMouse2d (mouseX, mouseY, mouse2dAnim); - renderer.swapBuffers (); - } - - void - Program::ShowMessageProgramState::mouseDownLeft (int x, int y) - { - int - button = 0; - if (msgBox.mouseClick (x, y, button)) - { - program->exit (); - userWantsExit = true; - } - } - - void - Program::ShowMessageProgramState::keyPress (SDL_KeyboardEvent c) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d] c = [%d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - c.keysym.sym); - -// if user pressed return we exit -//if(c == 13) { - if (isKeyPressed (SDLK_RETURN, c) == true) - { - program->exit (); - userWantsExit = true; - } - } - - void - Program::ShowMessageProgramState::mouseMove (int x, int y, - const MouseState & - mouseState) - { - mouseX = x; - mouseY = y; - msgBox.mouseMove (x, y); - } - - void - Program::ShowMessageProgramState::update () - { - mouse2dAnim = (mouse2dAnim + 1) % Renderer::maxMouse2dAnim; - } - -// ===================== PUBLIC ======================== - - bool Program::rendererInitOk = false; - bool Program::tryingRendererInit = false; - - Program::Program ():msgBox ("Program", "msgBox") - { -//this->masterserverMode = false; - this->window = NULL; - this->shutdownApplicationEnabled = false; - this->skipRenderFrameCount = 0; - this->messageBoxIsSystemError = false; - this->programStateOldSystemError = NULL; - this->programState = NULL; - this->singleton = this; - this->soundThreadManager = NULL; - -//mesage box - Lang & lang = Lang::getInstance (); -//msgBox.registerGraphicComponent("Program", "msgBox"); - msgBox.init (lang.getString ("Ok")); - msgBox.setEnabled (false); - } - -//bool Program::isMasterserverMode() const { -// return this->masterserverMode; -//} - - void - Program::initNormal (WindowGl * window) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - Config & config = Config::getInstance (); - init (window); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - setState (new Intro (this)); - showCursor (config.getBool ("No2DMouseRendering", "false")); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - void - Program::initSavedGame (WindowGl * window, bool masterserverMode, - string saveGameFile) - { - init (window); - MainMenu * - mainMenu = new MainMenu (this); - setState (mainMenu); - - if (saveGameFile == "") - { - Config & config = Config::getInstance (); - saveGameFile = config.getString ("LastSavedGame", ""); - if (saveGameFile == "") - { - saveGameFile = GameConstants::saveGameFileDefault; - if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) - != "") - { - saveGameFile = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - saveGameFile; - } - else - { - string - userData = - Config::getInstance ().getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - saveGameFile = userData + saveGameFile; - } - } - } - -//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Loading game from [%s]\n",saveGameFile.c_str()); - printf ("Loading saved game from [%s]\n", saveGameFile.c_str ()); - - Game::loadGame (saveGameFile, this, masterserverMode); - } - - void - Program::initServer (WindowGl * window, bool autostart, - bool openNetworkSlots, bool masterserverMode) - { -//this->masterserverMode = masterserverMode; - init (window); - MainMenu * - mainMenu = new MainMenu (this); - setState (mainMenu); - mainMenu->setState (new - MenuStateCustomGame (this, mainMenu, - openNetworkSlots, pNewGame, - autostart, NULL, - masterserverMode)); - } - - void - Program::initServer (WindowGl * window, GameSettings * settings) - { - init (window); - MainMenu * - mainMenu = new MainMenu (this); - setState (mainMenu); - mainMenu->setState (new - MenuStateCustomGame (this, mainMenu, false, - pNewGame, true, settings)); - } - - void - Program::initClient (WindowGl * window, const Ip & serverIp, - int portNumber) - { - init (window); - MainMenu * - mainMenu = new MainMenu (this); - setState (mainMenu); - mainMenu->setState (new - MenuStateJoinGame (this, mainMenu, true, serverIp, - portNumber)); - } - - void - Program::initClientAutoFindHost (WindowGl * window) - { - init (window); - MainMenu * - mainMenu = new MainMenu (this); - setState (mainMenu); - bool autoFindHost = true; - mainMenu->setState (new - MenuStateJoinGame (this, mainMenu, &autoFindHost)); - - } - - void - Program::initScenario (WindowGl * window, string autoloadScenarioName) - { - init (window); - MainMenu * - mainMenu = new MainMenu (this); - setState (mainMenu); - mainMenu->setState (new MenuStateScenario (this, mainMenu, false, - Config:: - getInstance - ().getPathListForType - (ptScenarios), - autoloadScenarioName)); - } - - Program::~Program () - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - delete programState; - programState = NULL; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - - Renderer::getInstance ().end (); - CoreData & coreData = CoreData::getInstance (); - coreData.cleanup (); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - -//restore video mode - restoreDisplaySettings (); - singleton = NULL; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - - if (soundThreadManager != NULL) - { - BaseThread::shutdownAndWait (soundThreadManager); - delete soundThreadManager; - soundThreadManager = NULL; - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - } - - void - Program::restoreStateFromSystemError () - { - messageBoxIsSystemError = false; - if (this->programStateOldSystemError == NULL) - { - setState (new Intro (this)); - } - else - { - setState (this->programStateOldSystemError); - } - } - - bool Program::textInput (std::string text) - { - if (msgBox.getEnabled ()) - { - return false; - } -//delegate event - return programState->textInput (text); - } - - bool Program::sdlKeyDown (SDL_KeyboardEvent key) - { -//delegate event - return programState->sdlKeyDown (key); - } - - void - Program::keyDown (SDL_KeyboardEvent key) - { - if (msgBox.getEnabled ()) - { -//SDL_keysym keystate = Window::getKeystate(); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//if(key == vkEscape || key == SDLK_ESCAPE || -// ((key == vkReturn || key == SDLK_RETURN || key == SDLK_KP_ENTER) && !(keystate.mod & (KMOD_LALT | KMOD_RALT)))) { - if (isKeyPressed (SDLK_ESCAPE, key) == true - || ((isKeyPressed (SDLK_RETURN, key) == true) - && !(key.keysym.mod & (KMOD_LALT | KMOD_RALT)))) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//printf("---> keystate [%d]\n",keystate); - msgBox.setEnabled (false); - if (messageBoxIsSystemError == true) - { - restoreStateFromSystemError (); - } - } - } -//delegate event - programState->keyDown (key); - } - - void - Program::keyUp (SDL_KeyboardEvent key) - { - programState->keyUp (key); - } - - void - Program::keyPress (SDL_KeyboardEvent c) - { - programState->keyPress (c); - } - - void - Program::mouseDownLeft (int x, int y) - { - if (msgBox.getEnabled ()) - { - int - button = 0; - if (msgBox.mouseClick (x, y, button)) - { -//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -//close message box - msgBox.setEnabled (false); - if (messageBoxIsSystemError == true) - { - restoreStateFromSystemError (); - } - } - } - } - - void - Program::eventMouseMove (int x, int y, const MouseState * ms) - { - if (msgBox.getEnabled ()) - { - msgBox.mouseMove (x, y); - } - } - - void - Program::simpleTask (BaseThread * callingThread, void *userdata) - { - loopWorker (); - } - - void - Program::loop () - { - loopWorker (); - } - - void - Program::loopWorker () - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] ================================= MAIN LOOP START ================================= \n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//Renderer &renderer= Renderer::getInstance(); - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false - && window) - { - MainWindow * - mainWindow = dynamic_cast < MainWindow * >(window); - if (mainWindow) - { -//mainWindow->render(); - if (mainWindow->getTriggerLanguageToggle ()) - { - mainWindow->toggleLanguage (mainWindow->getTriggerLanguage ()); - } - } - } - - Chrono chronoPerformanceCounts; - - bool - showPerfStats = - Config::getInstance ().getBool ("ShowPerfStats", "false"); - Chrono chronoPerf; - char - perfBuf[8096] = ""; - std::vector < string > perfList; - if (showPerfStats) - chronoPerf.start (); - - Chrono chronoLoop; +namespace Glest { + namespace Game { + + const int + Program::maxTimes = 10; + Program * + Program::singleton = NULL; + const int + SOUND_THREAD_UPDATE_MILLISECONDS = 25; + + bool Program::wantShutdownApplicationAfterGame = false; + const char * + ProgramState::MAIN_PROGRAM_RENDER_KEY = "ZETAGLEST.RENDER"; + + // ===================================================== + // class Program::CrashProgramState + // ===================================================== + + ProgramState::ProgramState(Program * program) { + this->program = program; + this->forceMouseRender = false; + this->mouseX = 0; + this->mouseY = 0; + this->mouse2dAnim = 0; + this->fps = 0; + this->lastFps = 0; + this->startX = 0; + this->startY = 0; + } + + void + ProgramState::restoreToStartXY() { + SDL_WarpMouseInWindow(this->program->getWindow()->getSDLWindow(), + startX, startY); + } + + void + ProgramState::incrementFps() { + fps++; + } + + void + ProgramState::tick() { + lastFps = fps; + fps = 0; + } + + bool ProgramState::canRender(bool sleepIfCannotRender) { + int + maxFPSCap = Config::getInstance().getInt("RenderFPSCap", "500"); + int + sleepMillis = + Config::getInstance().getInt("RenderFPSCapSleepMillis", "1"); + //Renderer &renderer= Renderer::getInstance(); + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + maxFPSCap = + Config::getInstance().getInt("RenderFPSCapHeadless", "250"); + sleepMillis = + Config::getInstance().getInt("RenderFPSCapHeadlessSleepMillis", + "1"); + } + + if (lastFps > maxFPSCap) { + if (sleepIfCannotRender == true) { + sleep(sleepMillis); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] sleeping because lastFps = %d, maxFPSCap = %d sleepMillis = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,lastFps,maxFPSCap,sleepMillis); + } + return false; + } + return true; + } + + void + ProgramState::render() { + Renderer & renderer = Renderer::getInstance(); + + canRender(); + incrementFps(); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + renderer.clearBuffers(); + renderer.reset2d(); + renderer.renderMessageBox(program->getMsgBox()); + renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim); + renderer.swapBuffers(); + } + } + + void + ProgramState::update() { + mouse2dAnim = (mouse2dAnim + 1) % Renderer::maxMouse2dAnim; + } + + void + ProgramState::mouseMove(int x, int y, const MouseState * mouseState) { + mouseX = x; + mouseY = y; + program->getMsgBox()->mouseMove(x, y); + } + + Program::ShowMessageProgramState::ShowMessageProgramState(Program * + program, + const char + *msg) : + ProgramState(program) { + userWantsExit = false; + msgBox.registerGraphicComponent("ShowMessageProgramState", "msgBox"); + msgBox.init("Ok"); + + if (msg) { + fprintf(stderr, "%s\n", msg); + msgBox.setText(msg); + } else { + msgBox.setText("ZetaGlest has crashed."); + } + + mouse2dAnim = mouseY = mouseX = 0; + this->msg = (msg ? msg : ""); + } + + void + Program::ShowMessageProgramState::render() { + Renderer & renderer = Renderer::getInstance(); + renderer.clearBuffers(); + renderer.reset2d(); + renderer.renderMessageBox(&msgBox); + renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim); + renderer.swapBuffers(); + } + + void + Program::ShowMessageProgramState::mouseDownLeft(int x, int y) { + int + button = 0; + if (msgBox.mouseClick(x, y, button)) { + program->exit(); + userWantsExit = true; + } + } + + void + Program::ShowMessageProgramState::keyPress(SDL_KeyboardEvent c) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d] c = [%d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + c.keysym.sym); + + // if user pressed return we exit + //if(c == 13) { + if (isKeyPressed(SDLK_RETURN, c) == true) { + program->exit(); + userWantsExit = true; + } + } + + void + Program::ShowMessageProgramState::mouseMove(int x, int y, + const MouseState & + mouseState) { + mouseX = x; + mouseY = y; + msgBox.mouseMove(x, y); + } + + void + Program::ShowMessageProgramState::update() { + mouse2dAnim = (mouse2dAnim + 1) % Renderer::maxMouse2dAnim; + } + + // ===================== PUBLIC ======================== + + bool Program::rendererInitOk = false; + bool Program::tryingRendererInit = false; + + Program::Program() :msgBox("Program", "msgBox") { + //this->masterserverMode = false; + this->window = NULL; + this->shutdownApplicationEnabled = false; + this->skipRenderFrameCount = 0; + this->messageBoxIsSystemError = false; + this->programStateOldSystemError = NULL; + this->programState = NULL; + this->singleton = this; + this->soundThreadManager = NULL; + + //mesage box + Lang & lang = Lang::getInstance(); + //msgBox.registerGraphicComponent("Program", "msgBox"); + msgBox.init(lang.getString("Ok")); + msgBox.setEnabled(false); + } + + //bool Program::isMasterserverMode() const { + // return this->masterserverMode; + //} + + void + Program::initNormal(WindowGl * window) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + Config & config = Config::getInstance(); + init(window); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + setState(new Intro(this)); + showCursor(config.getBool("No2DMouseRendering", "false")); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + void + Program::initSavedGame(WindowGl * window, bool masterserverMode, + string saveGameFile) { + init(window); + MainMenu * + mainMenu = new MainMenu(this); + setState(mainMenu); + + if (saveGameFile == "") { + Config & config = Config::getInstance(); + saveGameFile = config.getString("LastSavedGame", ""); + if (saveGameFile == "") { + saveGameFile = GameConstants::saveGameFileDefault; + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + != "") { + saveGameFile = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + saveGameFile; + } else { + string + userData = + Config::getInstance().getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + saveGameFile = userData + saveGameFile; + } + } + } + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Loading game from [%s]\n",saveGameFile.c_str()); + printf("Loading saved game from [%s]\n", saveGameFile.c_str()); + + Game::loadGame(saveGameFile, this, masterserverMode); + } + + void + Program::initServer(WindowGl * window, bool autostart, + bool openNetworkSlots, bool masterserverMode) { + //this->masterserverMode = masterserverMode; + init(window); + MainMenu * + mainMenu = new MainMenu(this); + setState(mainMenu); + mainMenu->setState(new + MenuStateCustomGame(this, mainMenu, + openNetworkSlots, pNewGame, + autostart, NULL, + masterserverMode)); + } + + void + Program::initServer(WindowGl * window, GameSettings * settings) { + init(window); + MainMenu * + mainMenu = new MainMenu(this); + setState(mainMenu); + mainMenu->setState(new + MenuStateCustomGame(this, mainMenu, false, + pNewGame, true, settings)); + } + + void + Program::initClient(WindowGl * window, const Ip & serverIp, + int portNumber) { + init(window); + MainMenu * + mainMenu = new MainMenu(this); + setState(mainMenu); + mainMenu->setState(new + MenuStateJoinGame(this, mainMenu, true, serverIp, + portNumber)); + } + + void + Program::initClientAutoFindHost(WindowGl * window) { + init(window); + MainMenu * + mainMenu = new MainMenu(this); + setState(mainMenu); + bool autoFindHost = true; + mainMenu->setState(new + MenuStateJoinGame(this, mainMenu, &autoFindHost)); + + } + + void + Program::initScenario(WindowGl * window, string autoloadScenarioName) { + init(window); + MainMenu * + mainMenu = new MainMenu(this); + setState(mainMenu); + mainMenu->setState(new MenuStateScenario(this, mainMenu, false, + Config:: + getInstance + ().getPathListForType + (ptScenarios), + autoloadScenarioName)); + } + + Program::~Program() { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + delete programState; + programState = NULL; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + + Renderer::getInstance().end(); + CoreData & coreData = CoreData::getInstance(); + coreData.cleanup(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + + //restore video mode + restoreDisplaySettings(); + singleton = NULL; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + + if (soundThreadManager != NULL) { + BaseThread::shutdownAndWait(soundThreadManager); + delete soundThreadManager; + soundThreadManager = NULL; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + } + + void + Program::restoreStateFromSystemError() { + messageBoxIsSystemError = false; + if (this->programStateOldSystemError == NULL) { + setState(new Intro(this)); + } else { + setState(this->programStateOldSystemError); + } + } + + bool Program::textInput(std::string text) { + if (msgBox.getEnabled()) { + return false; + } + //delegate event + return programState->textInput(text); + } + + bool Program::sdlKeyDown(SDL_KeyboardEvent key) { + //delegate event + return programState->sdlKeyDown(key); + } + + void + Program::keyDown(SDL_KeyboardEvent key) { + if (msgBox.getEnabled()) { + //SDL_keysym keystate = Window::getKeystate(); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //if(key == vkEscape || key == SDLK_ESCAPE || + // ((key == vkReturn || key == SDLK_RETURN || key == SDLK_KP_ENTER) && !(keystate.mod & (KMOD_LALT | KMOD_RALT)))) { + if (isKeyPressed(SDLK_ESCAPE, key) == true + || ((isKeyPressed(SDLK_RETURN, key) == true) + && !(key.keysym.mod & (KMOD_LALT | KMOD_RALT)))) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //printf("---> keystate [%d]\n",keystate); + msgBox.setEnabled(false); + if (messageBoxIsSystemError == true) { + restoreStateFromSystemError(); + } + } + } + //delegate event + programState->keyDown(key); + } + + void + Program::keyUp(SDL_KeyboardEvent key) { + programState->keyUp(key); + } + + void + Program::keyPress(SDL_KeyboardEvent c) { + programState->keyPress(c); + } + + void + Program::mouseDownLeft(int x, int y) { + if (msgBox.getEnabled()) { + int + button = 0; + if (msgBox.mouseClick(x, y, button)) { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + //close message box + msgBox.setEnabled(false); + if (messageBoxIsSystemError == true) { + restoreStateFromSystemError(); + } + } + } + } + + void + Program::eventMouseMove(int x, int y, const MouseState * ms) { + if (msgBox.getEnabled()) { + msgBox.mouseMove(x, y); + } + } + + void + Program::simpleTask(BaseThread * callingThread, void *userdata) { + loopWorker(); + } + + void + Program::loop() { + loopWorker(); + } + + void + Program::loopWorker() { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] ================================= MAIN LOOP START ================================= \n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //Renderer &renderer= Renderer::getInstance(); + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false + && window) { + MainWindow * + mainWindow = dynamic_cast (window); + if (mainWindow) { + //mainWindow->render(); + if (mainWindow->getTriggerLanguageToggle()) { + mainWindow->toggleLanguage(mainWindow->getTriggerLanguage()); + } + } + } + + Chrono chronoPerformanceCounts; + + bool + showPerfStats = + Config::getInstance().getBool("ShowPerfStats", "false"); + Chrono chronoPerf; + char + perfBuf[8096] = ""; + std::vector < string > perfList; + if (showPerfStats) + chronoPerf.start(); + + Chrono chronoLoop; #ifdef DEBUG - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled) - chronoLoop.start (); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled) + chronoLoop.start(); #endif - Chrono chrono; + Chrono chrono; #ifdef DEBUG - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled) - chrono.start (); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled) + chrono.start(); #endif -//render - assert (programState != NULL); + //render + assert(programState != NULL); - if (this->programState->quitTriggered () == true) - { + if (this->programState->quitTriggered() == true) { #ifdef DEBUG - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); #endif - Stats endStats = this->programState->quitAndToggleState (); + Stats endStats = this->programState->quitAndToggleState(); #ifdef DEBUG - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); #endif - Game::exitGameState (this, endStats); + Game::exitGameState(this, endStats); #ifdef DEBUG - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); #endif - return; - } - ProgramState * - prevState = this->programState; + return; + } + ProgramState * + prevState = this->programState; - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } - assert (programState != NULL); + assert(programState != NULL); - chronoPerformanceCounts.start (); + chronoPerformanceCounts.start(); - programState->render (); + programState->render(); - programState->addPerformanceCount (ProgramState:: - MAIN_PROGRAM_RENDER_KEY, - chronoPerformanceCounts. - getMillis ()); + programState->addPerformanceCount(ProgramState:: + MAIN_PROGRAM_RENDER_KEY, + chronoPerformanceCounts. + getMillis()); - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } #ifdef DEBUG - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d programState->render took msecs: %lld ==============> MAIN LOOP RENDERING\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d programState->render took msecs: %lld ==============> MAIN LOOP RENDERING\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); -//update camera - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled) - chrono.start (); + //update camera + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled) + chrono.start(); #endif - chronoPerformanceCounts.start (); + chronoPerformanceCounts.start(); - while (updateCameraTimer.isTime ()) - { - programState->updateCamera (); - } + while (updateCameraTimer.isTime()) { + programState->updateCamera(); + } - programState->addPerformanceCount ("programState->updateCamera()", - chronoPerformanceCounts.getMillis - ()); + programState->addPerformanceCount("programState->updateCamera()", + chronoPerformanceCounts.getMillis + ()); - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } #ifdef DEBUG - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d programState->render took msecs: %lld ==============> MAIN LOOP CAMERA UPDATING\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d programState->render took msecs: %lld ==============> MAIN LOOP CAMERA UPDATING\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); -//update world - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled) - chrono.start (); + //update world + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled) + chrono.start(); #endif - int - updateCount = 0; - while (prevState == this->programState && updateTimer.isTime ()) - { - Chrono chronoUpdateLoop; + int + updateCount = 0; + while (prevState == this->programState && updateTimer.isTime()) { + Chrono chronoUpdateLoop; #ifdef DEBUG - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled) - chronoUpdateLoop.start (); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled) + chronoUpdateLoop.start(); #endif - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER - " updateCount: %d\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis (), - updateCount); - perfList.push_back (perfBuf); - } + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER + " updateCount: %d\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis(), + updateCount); + perfList.push_back(perfBuf); + } - GraphicComponent::update (); - programState->update (); + GraphicComponent::update(); + programState->update(); #ifdef DEBUG - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chronoUpdateLoop.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] programState->update took msecs: %lld, updateCount = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chronoUpdateLoop.getMillis (), - updateCount); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chronoUpdateLoop.getMillis () > 0) - chronoUpdateLoop.start (); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chronoUpdateLoop.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] programState->update took msecs: %lld, updateCount = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chronoUpdateLoop.getMillis(), + updateCount); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chronoUpdateLoop.getMillis() > 0) + chronoUpdateLoop.start(); #endif - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER - " updateCount: %d\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis (), - updateCount); - perfList.push_back (perfBuf); - } + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER + " updateCount: %d\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis(), + updateCount); + perfList.push_back(perfBuf); + } - if (prevState == this->programState) - { - chronoPerformanceCounts.start (); + if (prevState == this->programState) { + chronoPerformanceCounts.start(); - if (soundThreadManager == NULL - || soundThreadManager->isThreadExecutionLagging ()) - { - if (soundThreadManager != NULL) - { + if (soundThreadManager == NULL + || soundThreadManager->isThreadExecutionLagging()) { + if (soundThreadManager != NULL) { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d] ERROR / WARNING soundThreadManager->isThreadExecutionLagging is TRUE\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s %d] ERROR / WARNING soundThreadManager->isThreadExecutionLagging is TRUE\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - SoundRenderer::getInstance ().update (); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d] ERROR / WARNING soundThreadManager->isThreadExecutionLagging is TRUE\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s %d] ERROR / WARNING soundThreadManager->isThreadExecutionLagging is TRUE\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + SoundRenderer::getInstance().update(); #ifdef DEBUG - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chronoUpdateLoop.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] SoundRenderer::getInstance().update() took msecs: %lld, updateCount = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, - chronoUpdateLoop.getMillis (), - updateCount); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chronoUpdateLoop.getMillis () > 0) - chronoUpdateLoop.start (); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chronoUpdateLoop.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] SoundRenderer::getInstance().update() took msecs: %lld, updateCount = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, + chronoUpdateLoop.getMillis(), + updateCount); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chronoUpdateLoop.getMillis() > 0) + chronoUpdateLoop.start(); #endif - } + } - programState->addPerformanceCount - ("SoundRenderer::getInstance().update()", - chronoPerformanceCounts.getMillis ()); + programState->addPerformanceCount + ("SoundRenderer::getInstance().update()", + chronoPerformanceCounts.getMillis()); - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER - " updateCount: %d\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis (), - updateCount); - perfList.push_back (perfBuf); - } + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER + " updateCount: %d\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis(), + updateCount); + perfList.push_back(perfBuf); + } - chronoPerformanceCounts.start (); + chronoPerformanceCounts.start(); - NetworkManager::getInstance ().update (); + NetworkManager::getInstance().update(); - programState->addPerformanceCount - ("NetworkManager::getInstance().update()", - chronoPerformanceCounts.getMillis ()); + programState->addPerformanceCount + ("NetworkManager::getInstance().update()", + chronoPerformanceCounts.getMillis()); #ifdef DEBUG - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chronoUpdateLoop.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] NetworkManager::getInstance().update() took msecs: %lld, updateCount = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chronoUpdateLoop.getMillis (), - updateCount); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chronoUpdateLoop.getMillis () > 0) - chronoUpdateLoop.start (); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chronoUpdateLoop.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] NetworkManager::getInstance().update() took msecs: %lld, updateCount = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chronoUpdateLoop.getMillis(), + updateCount); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chronoUpdateLoop.getMillis() > 0) + chronoUpdateLoop.start(); #endif - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER - " updateCount: %d\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis (), - updateCount); - perfList.push_back (perfBuf); - } + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER + " updateCount: %d\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis(), + updateCount); + perfList.push_back(perfBuf); + } - } - updateCount++; - } + } + updateCount++; + } #ifdef DEBUG - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d AFTER programState->update took msecs: %lld ==============> MAIN LOOP BODY LOGIC, updateCount = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - chrono.getMillis (), updateCount); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d AFTER programState->update took msecs: %lld ==============> MAIN LOOP BODY LOGIC, updateCount = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + chrono.getMillis(), updateCount); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); #endif - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } - if (prevState == this->programState) - { -//fps timer - chronoPerformanceCounts.start (); + if (prevState == this->programState) { + //fps timer + chronoPerformanceCounts.start(); - chrono.start (); - while (fpsTimer.isTime ()) - { - programState->tick (); - } + chrono.start(); + while (fpsTimer.isTime()) { + programState->tick(); + } - programState->addPerformanceCount ("programState->tick()", - chronoPerformanceCounts.getMillis - ()); + programState->addPerformanceCount("programState->tick()", + chronoPerformanceCounts.getMillis + ()); - if (showPerfStats) - { - sprintf (perfBuf, - "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, chronoPerf.getMillis ()); - perfList.push_back (perfBuf); - } + if (showPerfStats) { + sprintf(perfBuf, + "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } #ifdef DEBUG - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d programState->render took msecs: %lld ==============> MAIN LOOP TICKING\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d programState->render took msecs: %lld ==============> MAIN LOOP TICKING\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); -//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d programState->render took msecs: %lld ==============> MAIN LOOP TICKING\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d programState->render took msecs: %lld ==============> MAIN LOOP TICKING\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); #endif - } + } - if (showPerfStats && chronoPerf.getMillis () >= 100) - { - for (unsigned int x = 0; x < perfList.size (); ++x) - { - printf ("%s", perfList[x].c_str ()); - } - } + if (showPerfStats && chronoPerf.getMillis() >= 100) { + for (unsigned int x = 0; x < perfList.size(); ++x) { + printf("%s", perfList[x].c_str()); + } + } #ifdef DEBUG - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] ------------------------------- MAIN LOOP END, stats: loop took msecs: %lld -------------------------------\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - chronoLoop.getMillis ()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] ------------------------------- MAIN LOOP END, stats: loop took msecs: %lld -------------------------------\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + chronoLoop.getMillis()); #endif - } - - void - Program::resize (SizeState sizeState) - { - - switch (sizeState) - { - case ssMinimized: -//restoreVideoMode(); - break; - case ssMaximized: - case ssRestored: -//setDisplaySettings(); -//renderer.reloadResources(); - break; - } - } - -// ==================== misc ==================== - - void - Program::renderProgramMsgBox () - { - Renderer & renderer = Renderer::getInstance (); - if (msgBox.getEnabled ()) - { - renderer.renderMessageBox (&msgBox); - } - - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false - && window) - { - MainWindow * - mainWindow = dynamic_cast < MainWindow * >(window); - if (mainWindow) - { - mainWindow->render (); - } - } - - } - - void - Program::setState (ProgramState * programStateNew, bool cleanupOldState) - { - try - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - this->programStateOldSystemError = this->programState; - bool msgBoxEnabled = msgBox.getEnabled (); - - if (dynamic_cast < Game * >(programStateNew) != NULL) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - int - X = 0; - int - Y = 0; - SDL_GetMouseState (&X, &Y); - programStateNew->setStartXY (X, Y); - Logger::getInstance ().setProgress (0); - Logger::getInstance ().setState (""); - - - SDL_PumpEvents (); - - showCursor (true); - SDL_PumpEvents (); - sleep (0); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - if (cleanupOldState == true) - { - if (this->programState != programStateNew) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - this->programStateOldSystemError = NULL; - delete this->programState; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - this->programState = NULL; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//mesage box - Lang & lang = Lang::getInstance (); - msgBox.init (lang.getString ("Ok")); - msgBox.setEnabled (msgBoxEnabled); - - fpsTimer.init (1, maxTimes); - updateTimer.init (GameConstants::updateFps, maxTimes); - updateCameraTimer.init (GameConstants::cameraFps, maxTimes); - - this->programState = programStateNew; - assert (programStateNew != NULL); - if (programStateNew == NULL) - { - throw megaglest_runtime_error ("programStateNew == NULL"); - } - programStateNew->load (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - programStateNew->init (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - updateTimer.reset (); - updateCameraTimer.reset (); - fpsTimer.reset (); - - Config & config = Config::getInstance (); - if (dynamic_cast < Intro * >(programStateNew) != NULL - && msgBoxEnabled == true) - { - showCursor (true); - } - else - { - showCursor (config.getBool ("No2DMouseRendering", "false")); - } - - this->programStateOldSystemError = NULL; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - catch (megaglest_runtime_error & e) - { -//printf("3333333 ex.wantStackTrace() = %d\n",e.wantStackTrace()); - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d]\nError [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, e.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); -//abort(); -//printf("44444444a ex.wantStackTrace() = %d\n",e.wantStackTrace()); - - messageBoxIsSystemError = true; - string errorMsg = e.what (); - - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - if (dynamic_cast < Game * >(programStateNew) != NULL) - { - try - { - Game * - game = dynamic_cast < Game * >(programStateNew); - Renderer & renderer = Renderer::getInstance (); - game->setQuitPendingIndicator (); // by this the world is no more updated - renderer.initGame (game, game->getGameCameraPtr ()); - } - catch (megaglest_runtime_error & ex2) - { - errorMsg += "\n" + string (ex2.what ()); - } - } - } - -//printf("44444444b ex.wantStackTrace() = %d\n",e.wantStackTrace()); - this->showMessage (errorMsg.c_str ()); -//setState(new Intro(this)); - } - catch (const exception & e) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d]\nError [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, e.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, szBuf); -//abort(); - - messageBoxIsSystemError = true; - - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - if (dynamic_cast < Game * >(programStateNew) != NULL) - { - Game * - game = dynamic_cast < Game * >(programStateNew); - Renderer & renderer = Renderer::getInstance (); - renderer.initGame (game, game->getGameCameraPtr ()); - } - } - - this->showMessage (e.what ()); -//setState(new Intro(this)); - } - } - - void - Program::exit () - { - window->destroy (); - } - -// ==================== PRIVATE ==================== - - void - Program::initResolution () - { - const - Metrics & - metrics = Metrics::getInstance (); - if (window->getScreenWidth () != metrics.getScreenW () || - window->getScreenHeight () != metrics.getScreenH ()) - { - - int - oldW = metrics.getScreenW (); - int - oldH = metrics.getScreenH (); - - Config & config = Config::getInstance (); - config.setInt ("ScreenWidth", window->getScreenWidth (), true); - config.setInt ("ScreenHeight", window->getScreenHeight (), true); - - metrics.reload (window->getScreenWidth (), - window->getScreenHeight ()); - printf - ("MainWindow forced change of resolution to desktop values (%d x %d) instead of (%d x %d)\n", - metrics.getScreenW (), metrics.getScreenH (), oldW, oldH); - } - } - - void - Program::init (WindowGl * window, bool initSound, bool toggleFullScreen) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - this->window = window; - Config & config = Config::getInstance (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//set video mode - if (toggleFullScreen == false) - { - setDisplaySettings (); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//window -//window->setText("ZetaGlest"); - window->setStyle (config.getBool ("Windowed") ? wsWindowedFixed : - wsFullscreen); - window->setPos (0, 0); - window->setSize (config.getInt ("ScreenWidth"), - config.getInt ("ScreenHeight")); - window->create (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//timers - fpsTimer.init (1, maxTimes); - updateTimer.init (GameConstants::updateFps, maxTimes); - updateCameraTimer.init (GameConstants::cameraFps, maxTimes); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//log start - Logger & logger = Logger::getInstance (); - string logFile = "glest.log"; - if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) != - "") - { - logFile = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - logFile; - } - else - { - string userData = config.getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - - logFile = userData + logFile; - } - logger.setFile (logFile); - logger.clear (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//lang -//Lang &lang= Lang::getInstance(); - Lang::getInstance (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//render - Renderer & renderer = Renderer::getInstance (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - window->initGl (config.getInt ("ColorBits"), - config.getInt ("DepthBits"), - config.getInt ("StencilBits"), - config.getBool ("HardwareAcceleration", "false"), - config.getBool ("FullScreenAntiAliasing", "false"), - config.getFloat ("GammaValue", "0.0")); - window->setText (config.getString ("WindowTitle", "ZetaGlest")); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - window->makeCurrentGl (); - initResolution (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//coreData, needs renderer, but must load before renderer init - CoreData & coreData = CoreData::getInstance (); - coreData.load (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//init renderer (load global textures) - tryingRendererInit = true; - renderer.init (); - tryingRendererInit = false; - rendererInitOk = true; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//sound - if (initSound == true && toggleFullScreen == false) - { - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - bool initOk = soundRenderer.init (window); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] initOk = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, initOk); - -// Test sound system failed -//initOk = false; -// END - - if (initOk == false) - { - string sError = "Sound System could not be initialized!"; - this->showMessage (sError.c_str ()); - } - -// Run sound streaming in a background thread if enabled - if (SoundRenderer::getInstance ().runningThreaded () == true) - { - if (BaseThread::shutdownAndWait (soundThreadManager) == true) - { - delete soundThreadManager; - } - static - string - mutexOwnerId = - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - string ("_") + intToStr (__LINE__); - soundThreadManager = - new SimpleTaskThread (&SoundRenderer::getInstance (), 0, - SOUND_THREAD_UPDATE_MILLISECONDS); - soundThreadManager->setUniqueID (mutexOwnerId); - soundThreadManager->start (); - } - } - - NetworkInterface::setAllowGameDataSynchCheck (Config:: - getInstance ().getBool - ("AllowGameDataSynchCheck", - "false")); - NetworkInterface::setAllowDownloadDataSynch (Config:: - getInstance ().getBool - ("AllowDownloadDataSynch", - "false")); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - void - Program::reloadUI () - { - if (programState) - { - programState->reloadUI (); - } - } - - void - Program::setDisplaySettings () - { - - Config & config = Config::getInstance (); - - if (!config.getBool ("Windowed")) - { - -//int freq= config.getInt("RefreshFrequency"); - int - colorBits = config.getInt ("ColorBits"); - int - screenWidth = config.getInt ("ScreenWidth"); - int - screenHeight = config.getInt ("ScreenHeight"); - - if (config.getBool ("AutoMaxFullScreen", "false") == true) - { - getFullscreenVideoInfo (colorBits, screenWidth, screenHeight, - !config.getBool ("Windowed")); - config.setInt ("ColorBits", colorBits); - config.setInt ("ScreenWidth", screenWidth); - config.setInt ("ScreenHeight", screenHeight); - } - } - changeVideoModeFullScreen (!config.getBool ("Windowed")); - } - - void - Program::restoreDisplaySettings () - { - Config & config = Config::getInstance (); - - if (!config.getBool ("Windowed")) - { - restoreVideoMode (this->getWindow ()->getSDLWindow ()); - } - } - - bool Program::isMessageShowing () - { - return msgBox.getEnabled (); - } - - void - Program::showMessage (const char *msg) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d] msg [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - msg); - - msgBox.setText (msg); - msgBox.setEnabled (true); - - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == true) - { - printf ("Message:\n%s\n", msg); - - if (messageBoxIsSystemError == true) - { - messageBoxIsSystemError = false; -//setState(new Intro(this)); - initServer (window, false, true, true); - } - } - } - - void - Program::stopSoundSystem () - { - if (soundThreadManager != NULL) - { - BaseThread::shutdownAndWait (soundThreadManager); - delete soundThreadManager; - soundThreadManager = NULL; - } - } - - void - Program::startSoundSystem () - { - stopSoundSystem (); - if (SoundRenderer::getInstance ().runningThreaded () == true) - { - static - string - mutexOwnerId = - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - string ("_") + intToStr (__LINE__); - soundThreadManager = - new SimpleTaskThread (&SoundRenderer::getInstance (), 0, - SOUND_THREAD_UPDATE_MILLISECONDS); - soundThreadManager->setUniqueID (mutexOwnerId); - soundThreadManager->start (); - } - } - -//void Program::resetSoundSystem() { -// startSoundSystem(); -//} - -//void Program::reInitGl() { -// if(window != NULL) { -// Config &config= Config::getInstance(); -// window->initGl(config.getInt("ColorBits"), -// config.getInt("DepthBits"), -// config.getInt("StencilBits"), -// config.getBool("HardwareAcceleration","false"), -// config.getBool("FullScreenAntiAliasing","false"), -// config.getFloat("GammaValue","0.0")); -// window->setText(config.getString("WindowTitle","ZetaGlest")); -// initResolution(); -// } -//} - - void - Program::consoleAddLine (string line) - { - if (programState != NULL) - { - programState->consoleAddLine (line); - } - } - - SimpleTaskThread * - Program::getSoundThreadManager (bool takeOwnership) - { - SimpleTaskThread * - result = soundThreadManager; - if (takeOwnership) - { - soundThreadManager = NULL; - } - return result; - } - - } + } + + void + Program::resize(SizeState sizeState) { + + switch (sizeState) { + case ssMinimized: + //restoreVideoMode(); + break; + case ssMaximized: + case ssRestored: + //setDisplaySettings(); + //renderer.reloadResources(); + break; + } + } + + // ==================== misc ==================== + + void + Program::renderProgramMsgBox() { + Renderer & renderer = Renderer::getInstance(); + if (msgBox.getEnabled()) { + renderer.renderMessageBox(&msgBox); + } + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false + && window) { + MainWindow * + mainWindow = dynamic_cast (window); + if (mainWindow) { + mainWindow->render(); + } + } + + } + + void + Program::setState(ProgramState * programStateNew, bool cleanupOldState) { + try { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + this->programStateOldSystemError = this->programState; + bool msgBoxEnabled = msgBox.getEnabled(); + + if (dynamic_cast (programStateNew) != NULL) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + int + X = 0; + int + Y = 0; + SDL_GetMouseState(&X, &Y); + programStateNew->setStartXY(X, Y); + Logger::getInstance().setProgress(0); + Logger::getInstance().setState(""); + + + SDL_PumpEvents(); + + showCursor(true); + SDL_PumpEvents(); + sleep(0); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + if (cleanupOldState == true) { + if (this->programState != programStateNew) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + this->programStateOldSystemError = NULL; + delete this->programState; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + this->programState = NULL; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //mesage box + Lang & lang = Lang::getInstance(); + msgBox.init(lang.getString("Ok")); + msgBox.setEnabled(msgBoxEnabled); + + fpsTimer.init(1, maxTimes); + updateTimer.init(GameConstants::updateFps, maxTimes); + updateCameraTimer.init(GameConstants::cameraFps, maxTimes); + + this->programState = programStateNew; + assert(programStateNew != NULL); + if (programStateNew == NULL) { + throw megaglest_runtime_error("programStateNew == NULL"); + } + programStateNew->load(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + programStateNew->init(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + updateTimer.reset(); + updateCameraTimer.reset(); + fpsTimer.reset(); + + Config & config = Config::getInstance(); + if (dynamic_cast (programStateNew) != NULL + && msgBoxEnabled == true) { + showCursor(true); + } else { + showCursor(config.getBool("No2DMouseRendering", "false")); + } + + this->programStateOldSystemError = NULL; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } catch (megaglest_runtime_error & e) { + //printf("3333333 ex.wantStackTrace() = %d\n",e.wantStackTrace()); + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d]\nError [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, e.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + //abort(); + //printf("44444444a ex.wantStackTrace() = %d\n",e.wantStackTrace()); + + messageBoxIsSystemError = true; + string errorMsg = e.what(); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + if (dynamic_cast (programStateNew) != NULL) { + try { + Game * + game = dynamic_cast (programStateNew); + Renderer & renderer = Renderer::getInstance(); + game->setQuitPendingIndicator(); // by this the world is no more updated + renderer.initGame(game, game->getGameCameraPtr()); + } catch (megaglest_runtime_error & ex2) { + errorMsg += "\n" + string(ex2.what()); + } + } + } + + //printf("44444444b ex.wantStackTrace() = %d\n",e.wantStackTrace()); + this->showMessage(errorMsg.c_str()); + //setState(new Intro(this)); + } catch (const exception & e) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d]\nError [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, e.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, szBuf); + //abort(); + + messageBoxIsSystemError = true; + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + if (dynamic_cast (programStateNew) != NULL) { + Game * + game = dynamic_cast (programStateNew); + Renderer & renderer = Renderer::getInstance(); + renderer.initGame(game, game->getGameCameraPtr()); + } + } + + this->showMessage(e.what()); + //setState(new Intro(this)); + } + } + + void + Program::exit() { + window->destroy(); + } + + // ==================== PRIVATE ==================== + + void + Program::initResolution() { + const + Metrics & + metrics = Metrics::getInstance(); + if (window->getScreenWidth() != metrics.getScreenW() || + window->getScreenHeight() != metrics.getScreenH()) { + + int + oldW = metrics.getScreenW(); + int + oldH = metrics.getScreenH(); + + Config & config = Config::getInstance(); + config.setInt("ScreenWidth", window->getScreenWidth(), true); + config.setInt("ScreenHeight", window->getScreenHeight(), true); + + metrics.reload(window->getScreenWidth(), + window->getScreenHeight()); + printf + ("MainWindow forced change of resolution to desktop values (%d x %d) instead of (%d x %d)\n", + metrics.getScreenW(), metrics.getScreenH(), oldW, oldH); + } + } + + void + Program::init(WindowGl * window, bool initSound, bool toggleFullScreen) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + this->window = window; + Config & config = Config::getInstance(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //set video mode + if (toggleFullScreen == false) { + setDisplaySettings(); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //window + //window->setText("ZetaGlest"); + window->setStyle(config.getBool("Windowed") ? wsWindowedFixed : + wsFullscreen); + window->setPos(0, 0); + window->setSize(config.getInt("ScreenWidth"), + config.getInt("ScreenHeight")); + window->create(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //timers + fpsTimer.init(1, maxTimes); + updateTimer.init(GameConstants::updateFps, maxTimes); + updateCameraTimer.init(GameConstants::cameraFps, maxTimes); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //log start + Logger & logger = Logger::getInstance(); + string logFile = "glest.log"; + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != + "") { + logFile = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + logFile; + } else { + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + + logFile = userData + logFile; + } + logger.setFile(logFile); + logger.clear(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //lang + //Lang &lang= Lang::getInstance(); + Lang::getInstance(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //render + Renderer & renderer = Renderer::getInstance(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + window->initGl(config.getInt("ColorBits"), + config.getInt("DepthBits"), + config.getInt("StencilBits"), + config.getBool("HardwareAcceleration", "false"), + config.getBool("FullScreenAntiAliasing", "false"), + config.getFloat("GammaValue", "0.0")); + window->setText(config.getString("WindowTitle", "ZetaGlest")); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + window->makeCurrentGl(); + initResolution(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //coreData, needs renderer, but must load before renderer init + CoreData & coreData = CoreData::getInstance(); + coreData.load(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //init renderer (load global textures) + tryingRendererInit = true; + renderer.init(); + tryingRendererInit = false; + rendererInitOk = true; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //sound + if (initSound == true && toggleFullScreen == false) { + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + bool initOk = soundRenderer.init(window); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] initOk = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, initOk); + + // Test sound system failed + //initOk = false; + // END + + if (initOk == false) { + string sError = "Sound System could not be initialized!"; + this->showMessage(sError.c_str()); + } + + // Run sound streaming in a background thread if enabled + if (SoundRenderer::getInstance().runningThreaded() == true) { + if (BaseThread::shutdownAndWait(soundThreadManager) == true) { + delete soundThreadManager; + } + static + string + mutexOwnerId = + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + string("_") + intToStr(__LINE__); + soundThreadManager = + new SimpleTaskThread(&SoundRenderer::getInstance(), 0, + SOUND_THREAD_UPDATE_MILLISECONDS); + soundThreadManager->setUniqueID(mutexOwnerId); + soundThreadManager->start(); + } + } + + NetworkInterface::setAllowGameDataSynchCheck(Config:: + getInstance().getBool + ("AllowGameDataSynchCheck", + "false")); + NetworkInterface::setAllowDownloadDataSynch(Config:: + getInstance().getBool + ("AllowDownloadDataSynch", + "false")); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + void + Program::reloadUI() { + if (programState) { + programState->reloadUI(); + } + } + + void + Program::setDisplaySettings() { + + Config & config = Config::getInstance(); + + if (!config.getBool("Windowed")) { + + //int freq= config.getInt("RefreshFrequency"); + int + colorBits = config.getInt("ColorBits"); + int + screenWidth = config.getInt("ScreenWidth"); + int + screenHeight = config.getInt("ScreenHeight"); + + if (config.getBool("AutoMaxFullScreen", "false") == true) { + getFullscreenVideoInfo(colorBits, screenWidth, screenHeight, + !config.getBool("Windowed")); + config.setInt("ColorBits", colorBits); + config.setInt("ScreenWidth", screenWidth); + config.setInt("ScreenHeight", screenHeight); + } + } + changeVideoModeFullScreen(!config.getBool("Windowed")); + } + + void + Program::restoreDisplaySettings() { + Config & config = Config::getInstance(); + + if (!config.getBool("Windowed")) { + restoreVideoMode(this->getWindow()->getSDLWindow()); + } + } + + bool Program::isMessageShowing() { + return msgBox.getEnabled(); + } + + void + Program::showMessage(const char *msg) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d] msg [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + msg); + + msgBox.setText(msg); + msgBox.setEnabled(true); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + printf("Message:\n%s\n", msg); + + if (messageBoxIsSystemError == true) { + messageBoxIsSystemError = false; + //setState(new Intro(this)); + initServer(window, false, true, true); + } + } + } + + void + Program::stopSoundSystem() { + if (soundThreadManager != NULL) { + BaseThread::shutdownAndWait(soundThreadManager); + delete soundThreadManager; + soundThreadManager = NULL; + } + } + + void + Program::startSoundSystem() { + stopSoundSystem(); + if (SoundRenderer::getInstance().runningThreaded() == true) { + static + string + mutexOwnerId = + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + string("_") + intToStr(__LINE__); + soundThreadManager = + new SimpleTaskThread(&SoundRenderer::getInstance(), 0, + SOUND_THREAD_UPDATE_MILLISECONDS); + soundThreadManager->setUniqueID(mutexOwnerId); + soundThreadManager->start(); + } + } + + //void Program::resetSoundSystem() { + // startSoundSystem(); + //} + + //void Program::reInitGl() { + // if(window != NULL) { + // Config &config= Config::getInstance(); + // window->initGl(config.getInt("ColorBits"), + // config.getInt("DepthBits"), + // config.getInt("StencilBits"), + // config.getBool("HardwareAcceleration","false"), + // config.getBool("FullScreenAntiAliasing","false"), + // config.getFloat("GammaValue","0.0")); + // window->setText(config.getString("WindowTitle","ZetaGlest")); + // initResolution(); + // } + //} + + void + Program::consoleAddLine(string line) { + if (programState != NULL) { + programState->consoleAddLine(line); + } + } + + SimpleTaskThread * + Program::getSoundThreadManager(bool takeOwnership) { + SimpleTaskThread * + result = soundThreadManager; + if (takeOwnership) { + soundThreadManager = NULL; + } + return result; + } + + } } //end namespace diff --git a/source/glest_game/main/program.h b/source/glest_game/main/program.h index 52c4ab96e..409a72974 100644 --- a/source/glest_game/main/program.h +++ b/source/glest_game/main/program.h @@ -50,461 +50,412 @@ using Shared::Platform::MouseState; using Shared::PlatformCommon::PerformanceTimer; using Shared::Platform::Ip; using - namespace - Shared::PlatformCommon; +namespace + Shared::PlatformCommon; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - class Program; - class MainWindow; - class GameSettings; + class Program; + class MainWindow; + class GameSettings; -// ===================================================== -// class ProgramState -// -/// Base class for all program states: -/// Intro, MainMenu, Game, BattleEnd (State Design pattern) -// ===================================================== + // ===================================================== + // class ProgramState + // + /// Base class for all program states: + /// Intro, MainMenu, Game, BattleEnd (State Design pattern) + // ===================================================== - class ProgramState - { - protected: - Program * program; + class ProgramState { + protected: + Program * program; - int - mouseX; - int - mouseY; - int - mouse2dAnim; + int + mouseX; + int + mouseY; + int + mouse2dAnim; - int - startX; - int - startY; - bool forceMouseRender; + int + startX; + int + startY; + bool forceMouseRender; - int - fps; - int - lastFps; + int + fps; + int + lastFps; - public: + public: - static const char * - MAIN_PROGRAM_RENDER_KEY; + static const char * + MAIN_PROGRAM_RENDER_KEY; - explicit ProgramState (Program * program); - virtual ~ ProgramState () - { - }; + explicit ProgramState(Program * program); + virtual ~ProgramState() { + }; - int - getFps () const - { - return - fps; - } - int - getLastFps () const - { - return - lastFps; - } + int + getFps() const { + return + fps; + } + int + getLastFps() const { + return + lastFps; + } -//virtual void render()=0; - virtual - bool - canRender (bool sleepIfCannotRender = true); - virtual void - render (); - virtual void - update (); - virtual void - updateCamera () - { - }; - virtual void - tick (); - virtual void - init () - { - }; - virtual void - load () - { - }; - virtual void - end () - { - }; - virtual void - mouseDownLeft (int x, int y) - { - }; - virtual void - mouseUpLeft (int x, int y) - { - }; - virtual void - mouseUpRight (int x, int y) - { - } - virtual void - mouseUpCenter (int x, int y) - { - } - virtual void - mouseDownRight (int x, int y) - { - }; - virtual void - mouseDownCenter (int x, int y) - { - } - virtual void - mouseDoubleClickLeft (int x, int y) - { - }; - virtual void - mouseDoubleClickRight (int x, int y) - { - } - virtual void - mouseDoubleClickCenter (int x, int y) - { - } - virtual void - eventMouseWheel (int x, int y, int zDelta) - { - } - virtual void - mouseMove (int x, int y, const MouseState * mouseState); - virtual - bool - textInput (std::string text) - { - return false; - }; - virtual void - keyDown (SDL_KeyboardEvent key) - { - }; - virtual - bool - sdlKeyDown (SDL_KeyboardEvent key) - { - return false; - }; - virtual void - keyUp (SDL_KeyboardEvent key) - { - }; - virtual void - keyPress (SDL_KeyboardEvent c) - { - }; - virtual void - setStartXY (int X, int Y) - { - startX = X; - startY = Y; - } - virtual void - restoreToStartXY (); - virtual - bool - isInSpecialKeyCaptureEvent () - { - return false; - } - virtual - bool - quitTriggered () - { - return false; - } - virtual - Stats - quitAndToggleState () - { - return Stats (); - }; - virtual Program * - getProgram () - { - return program; - } - virtual const Program * - getProgramConstPtr () - { - return program; - } - virtual void - setForceMouseRender (bool value) - { - forceMouseRender = value; - } - virtual void - consoleAddLine (string line) - { - }; + //virtual void render()=0; + virtual + bool + canRender(bool sleepIfCannotRender = true); + virtual void + render(); + virtual void + update(); + virtual void + updateCamera() { + }; + virtual void + tick(); + virtual void + init() { + }; + virtual void + load() { + }; + virtual void + end() { + }; + virtual void + mouseDownLeft(int x, int y) { + }; + virtual void + mouseUpLeft(int x, int y) { + }; + virtual void + mouseUpRight(int x, int y) { + } + virtual void + mouseUpCenter(int x, int y) { + } + virtual void + mouseDownRight(int x, int y) { + }; + virtual void + mouseDownCenter(int x, int y) { + } + virtual void + mouseDoubleClickLeft(int x, int y) { + }; + virtual void + mouseDoubleClickRight(int x, int y) { + } + virtual void + mouseDoubleClickCenter(int x, int y) { + } + virtual void + eventMouseWheel(int x, int y, int zDelta) { + } + virtual void + mouseMove(int x, int y, const MouseState * mouseState); + virtual + bool + textInput(std::string text) { + return false; + }; + virtual void + keyDown(SDL_KeyboardEvent key) { + }; + virtual + bool + sdlKeyDown(SDL_KeyboardEvent key) { + return false; + }; + virtual void + keyUp(SDL_KeyboardEvent key) { + }; + virtual void + keyPress(SDL_KeyboardEvent c) { + }; + virtual void + setStartXY(int X, int Y) { + startX = X; + startY = Y; + } + virtual void + restoreToStartXY(); + virtual + bool + isInSpecialKeyCaptureEvent() { + return false; + } + virtual + bool + quitTriggered() { + return false; + } + virtual + Stats + quitAndToggleState() { + return Stats(); + }; + virtual Program * + getProgram() { + return program; + } + virtual const Program * + getProgramConstPtr() { + return program; + } + virtual void + setForceMouseRender(bool value) { + forceMouseRender = value; + } + virtual void + consoleAddLine(string line) { + }; - virtual void - reloadUI () - { - }; - virtual void - addPerformanceCount (string key, int64 value) - { - }; + virtual void + reloadUI() { + }; + virtual void + addPerformanceCount(string key, int64 value) { + }; - protected: - virtual void - incrementFps (); - }; + protected: + virtual void + incrementFps(); + }; -// =============================== -// class Program -// =============================== + // =============================== + // class Program + // =============================== - class Program - { - private: - static const int - maxTimes; - SimpleTaskThread * - soundThreadManager; + class Program { + private: + static const int + maxTimes; + SimpleTaskThread * + soundThreadManager; - class ShowMessageProgramState: - public ProgramState - { - GraphicMessageBox msgBox; - int - mouseX; - int - mouseY; - int - mouse2dAnim; - string msg; - bool userWantsExit; + class ShowMessageProgramState : + public ProgramState { + GraphicMessageBox msgBox; + int + mouseX; + int + mouseY; + int + mouse2dAnim; + string msg; + bool userWantsExit; - public: - ShowMessageProgramState (Program * program, const char *msg); + public: + ShowMessageProgramState(Program * program, const char *msg); - virtual void - render (); - virtual void - mouseDownLeft (int x, int y); - virtual void - mouseMove (int x, int y, const MouseState & mouseState); - virtual void - keyPress (SDL_KeyboardEvent c); - virtual void - update (); - virtual - bool - wantExit () - { - return userWantsExit; - } - }; + virtual void + render(); + virtual void + mouseDownLeft(int x, int y); + virtual void + mouseMove(int x, int y, const MouseState & mouseState); + virtual void + keyPress(SDL_KeyboardEvent c); + virtual void + update(); + virtual + bool + wantExit() { + return userWantsExit; + } + }; - private: - ProgramState * programState; + private: + ProgramState * programState; - PerformanceTimer fpsTimer; - PerformanceTimer updateTimer; - PerformanceTimer updateCameraTimer; + PerformanceTimer fpsTimer; + PerformanceTimer updateTimer; + PerformanceTimer updateCameraTimer; - WindowGl * - window; - static Program * - singleton; + WindowGl * + window; + static Program * + singleton; - GraphicMessageBox msgBox; - int - skipRenderFrameCount; + GraphicMessageBox msgBox; + int + skipRenderFrameCount; - bool messageBoxIsSystemError; - ProgramState * - programStateOldSystemError; + bool messageBoxIsSystemError; + ProgramState * + programStateOldSystemError; -//bool masterserverMode; - bool shutdownApplicationEnabled; - static - bool - wantShutdownApplicationAfterGame; + //bool masterserverMode; + bool shutdownApplicationEnabled; + static + bool + wantShutdownApplicationAfterGame; - static - bool - tryingRendererInit; - static - bool - rendererInitOk; + static + bool + tryingRendererInit; + static + bool + rendererInitOk; - public: - Program (); - virtual ~ Program (); + public: + Program(); + virtual ~Program(); - static - bool - getTryingRendererInit () - { - return tryingRendererInit; - } - static - bool - getRendererInitOk () - { - return rendererInitOk; - } + static + bool + getTryingRendererInit() { + return tryingRendererInit; + } + static + bool + getRendererInitOk() { + return rendererInitOk; + } - static Program * - getInstance () - { - return singleton; - } + static Program * + getInstance() { + return singleton; + } - static void - setWantShutdownApplicationAfterGame (bool value) - { - wantShutdownApplicationAfterGame = value; - } - static - bool - getWantShutdownApplicationAfterGame () - { - return wantShutdownApplicationAfterGame; - } + static void + setWantShutdownApplicationAfterGame(bool value) { + wantShutdownApplicationAfterGame = value; + } + static + bool + getWantShutdownApplicationAfterGame() { + return wantShutdownApplicationAfterGame; + } -//bool isMasterserverMode() const; - bool isShutdownApplicationEnabled ()const - { - return - shutdownApplicationEnabled; - } - void - setShutdownApplicationEnabled (bool value) - { - shutdownApplicationEnabled = value; - } + //bool isMasterserverMode() const; + bool isShutdownApplicationEnabled()const { + return + shutdownApplicationEnabled; + } + void + setShutdownApplicationEnabled(bool value) { + shutdownApplicationEnabled = value; + } - GraphicMessageBox * - getMsgBox () - { - return &msgBox; - } - void - initNormal (WindowGl * window); - void - initServer (WindowGl * window, bool autostart = - false, bool openNetworkSlots = - false, bool masterserverMode = false); - void - initServer (WindowGl * window, GameSettings * settings); - void - initSavedGame (WindowGl * window, bool masterserverMode = - false, string saveGameFile = ""); - void - initClient (WindowGl * window, const Ip & serverIp, int portNumber = - -1); - void - initClientAutoFindHost (WindowGl * window); - void - initScenario (WindowGl * window, string autoloadScenarioName); + GraphicMessageBox * + getMsgBox() { + return &msgBox; + } + void + initNormal(WindowGl * window); + void + initServer(WindowGl * window, bool autostart = + false, bool openNetworkSlots = + false, bool masterserverMode = false); + void + initServer(WindowGl * window, GameSettings * settings); + void + initSavedGame(WindowGl * window, bool masterserverMode = + false, string saveGameFile = ""); + void + initClient(WindowGl * window, const Ip & serverIp, int portNumber = + -1); + void + initClientAutoFindHost(WindowGl * window); + void + initScenario(WindowGl * window, string autoloadScenarioName); -//main - bool textInput (std::string text); - void - keyDown (SDL_KeyboardEvent key); - bool sdlKeyDown (SDL_KeyboardEvent key); - void - keyUp (SDL_KeyboardEvent key); - void - keyPress (SDL_KeyboardEvent c); + //main + bool textInput(std::string text); + void + keyDown(SDL_KeyboardEvent key); + bool sdlKeyDown(SDL_KeyboardEvent key); + void + keyUp(SDL_KeyboardEvent key); + void + keyPress(SDL_KeyboardEvent c); - void - loop (); - void - loopWorker (); - void - resize (SizeState sizeState); - void - showMessage (const char *msg); - bool isMessageShowing (); + void + loop(); + void + loopWorker(); + void + resize(SizeState sizeState); + void + showMessage(const char *msg); + bool isMessageShowing(); -//misc - void - setState (ProgramState * programStateNew, bool cleanupOldState = true); - ProgramState * - getState () - { - return programState; - } - WindowGl * - getWindow () - { - return window; - } - const WindowGl * - getWindowConstPtr () const - { - return - window; - } - void - init (WindowGl * window, bool initSound = true, bool toggleFullScreen = - false); - void - exit (); + //misc + void + setState(ProgramState * programStateNew, bool cleanupOldState = true); + ProgramState * + getState() { + return programState; + } + WindowGl * + getWindow() { + return window; + } + const WindowGl * + getWindowConstPtr() const { + return + window; + } + void + init(WindowGl * window, bool initSound = true, bool toggleFullScreen = + false); + void + exit(); - virtual void - simpleTask (BaseThread * callingThread, void *userdata); + virtual void + simpleTask(BaseThread * callingThread, void *userdata); - void - mouseDownLeft (int x, int y); - void - eventMouseMove (int x, int y, const MouseState * ms); + void + mouseDownLeft(int x, int y); + void + eventMouseMove(int x, int y, const MouseState * ms); - void - renderProgramMsgBox (); - bool isInSpecialKeyCaptureEvent () - { - return programState->isInSpecialKeyCaptureEvent (); - } + void + renderProgramMsgBox(); + bool isInSpecialKeyCaptureEvent() { + return programState->isInSpecialKeyCaptureEvent(); + } -//void reInitGl(); -//void resetSoundSystem(); - void - stopSoundSystem (); - void - startSoundSystem (); + //void reInitGl(); + //void resetSoundSystem(); + void + stopSoundSystem(); + void + startSoundSystem(); - virtual void - consoleAddLine (string line); + virtual void + consoleAddLine(string line); - virtual SimpleTaskThread * - getSoundThreadManager (bool takeOwnership); - virtual void - reloadUI (); + virtual SimpleTaskThread * + getSoundThreadManager(bool takeOwnership); + virtual void + reloadUI(); - private: + private: - void - setDisplaySettings (); - void - restoreDisplaySettings (); - void - restoreStateFromSystemError (); - void - initResolution (); - }; + void + setDisplaySettings(); + void + restoreDisplaySettings(); + void + restoreStateFromSystemError(); + void + initResolution(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/menu/main_menu.cpp b/source/glest_game/menu/main_menu.cpp index 4da5ad29c..955dfe46f 100644 --- a/source/glest_game/menu/main_menu.cpp +++ b/source/glest_game/menu/main_menu.cpp @@ -32,740 +32,651 @@ #include "leak_dumper.h" using namespace - Shared::Sound; +Shared::Sound; using namespace - Shared::Platform; +Shared::Platform; using namespace - Shared::Util; +Shared::Util; using namespace - Shared::Graphics; +Shared::Graphics; using namespace - Shared::Xml; +Shared::Xml; namespace - Glest -{ - namespace - Game - { - -// ===================================================== -// class MainMenu -// ===================================================== - -// ===================== PUBLIC ======================== - MenuState * - MainMenu::oldstate = NULL; - - MainMenu::MainMenu (Program * program): - ProgramState (program), - menuBackgroundVideo (NULL) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, __FUNCTION__, - __LINE__); - - //printf("In MainMenu::MainMenu()\n"); - - mouseX = 100; - mouseY = 100; - - state = NULL; - this-> - program = program; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, __FUNCTION__, - __LINE__); - - Config & - config = Config::getInstance (); - if (config.getString ("CustomMenuTextColor", "") != "") - { - string - customMenuTextColor = config.getString ("CustomMenuTextColor"); - Vec3f - customTextColor = Vec3f::strToVec3 (customMenuTextColor); - GraphicComponent::setCustomTextColor (customTextColor); - } - - setState (new MenuStateRoot (program, this)); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, __FUNCTION__, - __LINE__); - } - - void - MainMenu::reloadUI () - { - if (state) - { - state->reloadUI (); - } - } - - MainMenu::~MainMenu () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, __FUNCTION__, - __LINE__); - - //printf("In MainMenu::~MainMenu()\n"); - - if (menuBackgroundVideo != NULL) - { - menuBackgroundVideo->closePlayer (); - delete - menuBackgroundVideo; - menuBackgroundVideo = NULL; - } - delete - state; - state = NULL; - delete - oldstate; - oldstate = NULL; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, __FUNCTION__, - __LINE__); - - Renderer::getInstance ().endMenu (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, __FUNCTION__, - __LINE__); - - //SoundRenderer &soundRenderer= SoundRenderer::getInstance(); - //soundRenderer.stopAllSounds(); - GraphicComponent::setCustomTextColor (Vec3f (1.0f, 1.0f, 1.0f)); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, __FUNCTION__, - __LINE__); - } - - void - MainMenu::init () - { - Renderer::getInstance ().initMenu (this); - - initBackgroundVideo (); - } - - void - MainMenu::initBackgroundVideo () - { - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false - &&::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer () == true - && CoreData::getInstance ().hasMainMenuVideoFilename () == true) - { - string - introVideoFile = - CoreData::getInstance ().getMainMenuVideoFilename (); - string - introVideoFileFallback = - CoreData::getInstance ().getMainMenuVideoFilenameFallback (); - - Context * - c = GraphicsInterface::getInstance ().getCurrentContext (); - PlatformContextGl * - glCtx = static_cast < ContextGl * >(c)->getPlatformContextGlPtr (); - SDL_Window * - window = glCtx->getScreenWindow (); - SDL_Surface * - screen = glCtx->getScreenSurface (); - - string - vlcPluginsPath = - Config::getInstance ().getString ("VideoPlayerPluginsPath", ""); - //printf("screen->w = %d screen->h = %d screen->format->BitsPerPixel = %d\n",screen->w,screen->h,screen->format->BitsPerPixel); - menuBackgroundVideo = new VideoPlayer (&Renderer::getInstance (), - introVideoFile, - introVideoFileFallback, - window, - 0, 0, - screen->w, - screen->h, - screen->format->BitsPerPixel, - true, - vlcPluginsPath, - SystemFlags:: - VERBOSE_MODE_ENABLED); - menuBackgroundVideo->initPlayer (); - } - } - -//asynchronus render update - void - MainMenu::render () - { - Renderer & renderer = Renderer::getInstance (); - - canRender (); - incrementFps (); - - if (state->isMasterserverMode () == false) - { - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - - if (state->isVideoPlaying () == true) - { - if (menuBackgroundVideo != NULL) - { - if (menuBackgroundVideo->isPlaying () == true) - { - menuBackgroundVideo->closePlayer (); - delete - menuBackgroundVideo; - menuBackgroundVideo = NULL; - } - } - } - else if (menuBackgroundVideo == NULL) - { - initBackgroundVideo (); - } - renderer.clearBuffers (); - - //3d - renderer.reset3dMenu (); - renderer.clearZBuffer (); - - //printf("In [%s::%s Line: %d] menuBackgroundVideo [%p]\n",__FILE__,__FUNCTION__,__LINE__,menuBackgroundVideo); - - if (menuBackgroundVideo == NULL) - { - renderer.loadCameraMatrix (menuBackground.getCamera ()); - renderer.renderMenuBackground (&menuBackground); - renderer.renderParticleManager (rsMenu); - } - - //2d - renderer.reset2d (); - - if (menuBackgroundVideo != NULL) - { - if (menuBackgroundVideo->isPlaying () == true) - { - menuBackgroundVideo->playFrame (false); - } - else - { - menuBackgroundVideo->RestartVideo (); - } - } - } - state->render (); - - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false) - { - renderer.renderMouse2d (mouseX, mouseY, mouse2dAnim); - renderer.renderFPSWhenEnabled (lastFps); - renderer.swapBuffers (); - } - } - } - -//syncronus update - void - MainMenu::update () - { - if (menuBackgroundVideo == NULL) - { - Renderer::getInstance ().updateParticleManager (rsMenu); - } - mouse2dAnim = (mouse2dAnim + 1) % Renderer::maxMouse2dAnim; - if (menuBackgroundVideo == NULL) - { - menuBackground.update (); - } - state->update (); - } - -//event magangement: mouse click - void - MainMenu::mouseMove (int x, int y, const MouseState * ms) - { - mouseX = x; - mouseY = y; - state->mouseMove (x, y, ms); - } - -//returns if exiting - void - MainMenu::mouseDownLeft (int x, int y) - { - if (GraphicComponent::getFade () < 0.2f) - return; - state->mouseClick (x, y, mbLeft); - } - - void - MainMenu::mouseDownRight (int x, int y) - { - if (GraphicComponent::getFade () < 0.2f) - return; - state->mouseClick (x, y, mbRight); - } - - void - MainMenu::mouseUpLeft (int x, int y) - { - if (GraphicComponent::getFade () < 0.2f) - return; - state->mouseUp (x, y, mbLeft); - } - - bool - MainMenu::textInput (std::string text) - { - return state->textInput (text); - } - void - MainMenu::keyDown (SDL_KeyboardEvent key) - { - state->keyDown (key); - } - - void - MainMenu::keyUp (SDL_KeyboardEvent key) - { - state->keyUp (key); - } - - void - MainMenu::keyPress (SDL_KeyboardEvent c) - { - state->keyPress (c); - } - - void - MainMenu::setState (MenuState * newstate) - { - //printf("In [%s::%s Line: %d] oldstate [%p] newstate [%p] this->state [%p]\n",__FILE__,__FUNCTION__,__LINE__,oldstate,newstate,this->state); - - //printf("In MainMenu::setState() #1\n"); - - if (oldstate != NULL && oldstate != newstate) - { - MenuState * - oldstatePtr = oldstate; - delete - oldstate; - - //printf("In MainMenu::setState() #2\n"); - - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if (oldstatePtr != this->state) - { - oldstate = this->state; - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - //printf("In MainMenu::setState() #3\n"); - } - else - { - oldstate = NULL; - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - //printf("In MainMenu::setState() #4\n"); - } - } - else - { - oldstate = this->state; - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - //printf("In MainMenu::setState() #5\n"); - } - - if (this->state != NULL) - { - - } - - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - this->state = newstate; - - GraphicComponent::resetFade (); - if (newstate) - { - menuBackground.setTargetCamera (newstate->getCamera ()); - } - } - - bool - MainMenu::isInSpecialKeyCaptureEvent () - { - return state->isInSpecialKeyCaptureEvent (); - } - - void - MainMenu::consoleAddLine (string line) - { - if (state != NULL) - { - state->consoleAddLine (line); - } - } - -// ===================================================== -// class MenuState -// ===================================================== - - MenuState::MenuState (Program * program, MainMenu * mainMenu, - const string & stateName) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, __FUNCTION__, - __LINE__); - this->containerName = "MenuState"; - this->program = program; - this->mainMenu = mainMenu; - console.registerGraphicComponent (containerName, "menuStateConsole"); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, __FUNCTION__, - __LINE__); - //switch on menu music again, it might be muted - Config & config = Config::getInstance (); - float - configVolume = (config.getInt ("SoundVolumeMusic") / 100.f); - CoreData::getInstance ().getMenuMusic ()->setVolume (configVolume); - - string - data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - - //camera - XmlTree - xmlTree; - xmlTree. - load (getGameCustomCoreDataPath - (data_path, "data/core/menu/menu.xml"), - Properties::getTagReplacementValues ()); - const XmlNode * - menuNode = xmlTree.getRootNode (); - const XmlNode * - cameraNode = menuNode->getChild ("camera"); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, __FUNCTION__, - __LINE__); - - //position - const XmlNode * - positionNode = cameraNode->getChild (stateName + "-position"); - Vec3f - startPosition; - startPosition.x = positionNode->getAttribute ("x")->getFloatValue (); - startPosition.y = positionNode->getAttribute ("y")->getFloatValue (); - startPosition.z = positionNode->getAttribute ("z")->getFloatValue (); - camera.setPosition (startPosition); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, __FUNCTION__, - __LINE__); - - //rotation - const XmlNode * - rotationNode = cameraNode->getChild (stateName + "-rotation"); - Vec3f - startRotation; - startRotation.x = rotationNode->getAttribute ("x")->getFloatValue (); - startRotation.y = rotationNode->getAttribute ("y")->getFloatValue (); - startRotation.z = rotationNode->getAttribute ("z")->getFloatValue (); - camera. - setOrientation (Quaternion - (EulerAngles - (degToRad (startRotation.x), - degToRad (startRotation.y), - degToRad (startRotation.z)))); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, __FUNCTION__, - __LINE__); - } - - MenuState::~MenuState () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, __FUNCTION__, - __LINE__); - GraphicComponent::clearRegisteredComponents (this->containerName); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s %d]\n", __FILE__, __FUNCTION__, - __LINE__); - } - - void - MenuState::consoleAddLine (string line) - { - bool - onlyWantChatMsgs = console.getOnlyChatMessagesInStoredLines (); - if (onlyWantChatMsgs == true) - { - console.setOnlyChatMessagesInStoredLines (false); - } - console.addLine (line); - if (onlyWantChatMsgs == true) - { - console.setOnlyChatMessagesInStoredLines (true); - } - } - - void - MenuState::reloadUI () - { - //console.resetFonts(); - } - - void - MenuState::setActiveInputLabel (GraphicLabel * newLabel, - GraphicLabel ** activeInputLabelPtr) - { - GraphicLabel * - activeInputLabelEdit = *activeInputLabelPtr; - if (newLabel != NULL) - { - if (newLabel == activeInputLabelEdit) - { - return; - } - string - text = newLabel->getText (); - size_t - found = text.find_last_of ("_"); - if (found == string::npos || found != text.length () - 1) - { - text += "_"; - } - newLabel->setText (text); - //textCharLength = extractKeyPressedUnicodeLength(text); - newLabel-> - setTextCharLengthList (extractKeyPressedUnicodeLength (text)); - } - if (activeInputLabelEdit != NULL - && activeInputLabelEdit->getText ().empty () == false) - { - string - text = activeInputLabelEdit->getText (); - size_t - found = text.find_last_of ("_"); - if (found != string::npos && found == text.length () - 1) - { - //printf("Removing trailing edit char, found = %d [%d][%s]\n",found,text.length(),text.c_str()); - text = text.substr (0, found); - } - activeInputLabelEdit->setText (text); - //textCharLength = extractKeyPressedUnicodeLength(text); - activeInputLabelEdit-> - setTextCharLengthList (extractKeyPressedUnicodeLength (text)); - activeInputLabelEdit->setEditModeEnabled (false); - } - if (newLabel != NULL) - { - *activeInputLabelPtr = newLabel; - newLabel->setEditModeEnabled (true); - } - else - { - *activeInputLabelPtr = NULL; - } - } - - - bool - MenuState::keyPressEditLabel (SDL_KeyboardEvent c, - GraphicLabel ** activeInputLabelPtr) - { - if (isKeyPressed (SDLK_ESCAPE, c, false) == true || - isKeyPressed (SDLK_RETURN, c, false) == true) - { - GraphicLabel * - activeInputLabel = *activeInputLabelPtr; - setActiveInputLabel (NULL, activeInputLabelPtr); - //textCharLength.clear(); - activeInputLabel->clearTextCharLengthList (); - return true; - } - return false; - } - - bool - MenuState::textInputEditLabel (string input, - GraphicLabel ** activeInputLabelPtr) - { - bool - eventHandled = false; - GraphicLabel * - activeInputLabel = *activeInputLabelPtr; - if (activeInputLabel != NULL) - { - int - maxTextSize = activeInputLabel->getMaxEditWidth (); - - //if((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || - // (c=='-') || (c=='(') || (c==')')) { - //if(isAllowedInputTextKey(key)) - { - if ((int) activeInputLabel->getTextCharLengthList ().size () < - maxTextSize) - { - string - text = activeInputLabel->getText (); - - if (text.size () > 0) - { - size_t - found = text.find_last_of ("_"); - if (found == string::npos || found != text.length () - 1) - { - text += input; - activeInputLabel->addTextCharLengthToList (input.length ()); - } - else - { - text = text.substr (0, found) + input + "_"; - //int lastCharLen = activeInputLabel->getTextCharLengthList()[activeInputLabel->getTextCharLengthList().size()-1]; - activeInputLabel->deleteTextCharLengthFromList (); - activeInputLabel->addTextCharLengthToList (input.length ()); - activeInputLabel->addTextCharLengthToList (1); - } - } - else - { - text = input; - activeInputLabel->addTextCharLengthToList (input.length ()); - } - //delete [] utfStr; - - activeInputLabel->setText (text); - - eventHandled = true; - } - } - } - return eventHandled; - } - - bool - MenuState::keyDownEditLabel (SDL_KeyboardEvent c, - GraphicLabel ** activeInputLabelPtr) - { - bool - eventHandled = false; - GraphicLabel * - activeInputLabel = *activeInputLabelPtr; - if (activeInputLabel != NULL) - { - string - text = activeInputLabel->getText (); - if (isKeyPressed (SDLK_BACKSPACE, c) == true && text.length () > 0) - { - //printf("BSPACE text [%s]\n",text.c_str()); - - bool - hasUnderscore = false; - bool - delChar = false; - size_t - found = text.find_last_of ("_"); - if (found == string::npos || found != text.length () - 1) - { - //printf("A text.length() = %d textCharLength.size() = %d\n",text.length(),textCharLength.size()); - if (activeInputLabel-> - getTextCharLengthList ()[activeInputLabel-> - getTextCharLengthList ().size () - - 1] >= 1) - { - delChar = true; - } - } - else - { - //printf("B text.length() = %d textCharLength.size() = %d\n",text.length(),textCharLength.size()); - hasUnderscore = true; - if (activeInputLabel->getTextCharLengthList ().size () >= 2 - && activeInputLabel-> - getTextCharLengthList ()[activeInputLabel-> - getTextCharLengthList ().size () - - 2] >= 1) - { - delChar = true; - } - } - if (delChar == true) - { - if (hasUnderscore) - { - //if(textCharLength.size() > 1) { - if (activeInputLabel->getTextCharLengthList ().size () > 1) - { - //printf("Underscore erase start\n"); - for (unsigned int i = 0; - i < - (unsigned int) activeInputLabel-> - getTextCharLengthList ()[activeInputLabel-> - getTextCharLengthList (). - size () - 2]; ++i) - { - text.erase (text.end () - 2); - } - //printf("AFTER DEL textCharLength.size() = %d textCharLength[textCharLength.size()-1] = %d text.length() = %d\n",textCharLength.size(),textCharLength[textCharLength.size()-1],text.length()); - activeInputLabel->deleteTextCharLengthFromList (); - activeInputLabel->deleteTextCharLengthFromList (); - activeInputLabel->addTextCharLengthToList (1); - } - } - else - { - for (unsigned int i = 0; - i < - (unsigned int) activeInputLabel-> - getTextCharLengthList ()[activeInputLabel-> - getTextCharLengthList ().size () - - 1]; ++i) - { - text.erase (text.end () - 1); - } - activeInputLabel->deleteTextCharLengthFromList (); - } - } - activeInputLabel->setText (text); - eventHandled = true; - } - } - return eventHandled; - } - - } + Glest { + namespace + Game { + + // ===================================================== + // class MainMenu + // ===================================================== + + // ===================== PUBLIC ======================== + MenuState * + MainMenu::oldstate = NULL; + + MainMenu::MainMenu(Program * program) : + ProgramState(program), + menuBackgroundVideo(NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, __FUNCTION__, + __LINE__); + + //printf("In MainMenu::MainMenu()\n"); + + mouseX = 100; + mouseY = 100; + + state = NULL; + this-> + program = program; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, __FUNCTION__, + __LINE__); + + Config & + config = Config::getInstance(); + if (config.getString("CustomMenuTextColor", "") != "") { + string + customMenuTextColor = config.getString("CustomMenuTextColor"); + Vec3f + customTextColor = Vec3f::strToVec3(customMenuTextColor); + GraphicComponent::setCustomTextColor(customTextColor); + } + + setState(new MenuStateRoot(program, this)); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, __FUNCTION__, + __LINE__); + } + + void + MainMenu::reloadUI() { + if (state) { + state->reloadUI(); + } + } + + MainMenu::~MainMenu() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, __FUNCTION__, + __LINE__); + + //printf("In MainMenu::~MainMenu()\n"); + + if (menuBackgroundVideo != NULL) { + menuBackgroundVideo->closePlayer(); + delete + menuBackgroundVideo; + menuBackgroundVideo = NULL; + } + delete + state; + state = NULL; + delete + oldstate; + oldstate = NULL; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, __FUNCTION__, + __LINE__); + + Renderer::getInstance().endMenu(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, __FUNCTION__, + __LINE__); + + //SoundRenderer &soundRenderer= SoundRenderer::getInstance(); + //soundRenderer.stopAllSounds(); + GraphicComponent::setCustomTextColor(Vec3f(1.0f, 1.0f, 1.0f)); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, __FUNCTION__, + __LINE__); + } + + void + MainMenu::init() { + Renderer::getInstance().initMenu(this); + + initBackgroundVideo(); + } + + void + MainMenu::initBackgroundVideo() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false + && ::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == true + && CoreData::getInstance().hasMainMenuVideoFilename() == true) { + string + introVideoFile = + CoreData::getInstance().getMainMenuVideoFilename(); + string + introVideoFileFallback = + CoreData::getInstance().getMainMenuVideoFilenameFallback(); + + Context * + c = GraphicsInterface::getInstance().getCurrentContext(); + PlatformContextGl * + glCtx = static_cast (c)->getPlatformContextGlPtr(); + SDL_Window * + window = glCtx->getScreenWindow(); + SDL_Surface * + screen = glCtx->getScreenSurface(); + + string + vlcPluginsPath = + Config::getInstance().getString("VideoPlayerPluginsPath", ""); + //printf("screen->w = %d screen->h = %d screen->format->BitsPerPixel = %d\n",screen->w,screen->h,screen->format->BitsPerPixel); + menuBackgroundVideo = new VideoPlayer(&Renderer::getInstance(), + introVideoFile, + introVideoFileFallback, + window, + 0, 0, + screen->w, + screen->h, + screen->format->BitsPerPixel, + true, + vlcPluginsPath, + SystemFlags:: + VERBOSE_MODE_ENABLED); + menuBackgroundVideo->initPlayer(); + } + } + + //asynchronus render update + void + MainMenu::render() { + Renderer & renderer = Renderer::getInstance(); + + canRender(); + incrementFps(); + + if (state->isMasterserverMode() == false) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + + if (state->isVideoPlaying() == true) { + if (menuBackgroundVideo != NULL) { + if (menuBackgroundVideo->isPlaying() == true) { + menuBackgroundVideo->closePlayer(); + delete + menuBackgroundVideo; + menuBackgroundVideo = NULL; + } + } + } else if (menuBackgroundVideo == NULL) { + initBackgroundVideo(); + } + renderer.clearBuffers(); + + //3d + renderer.reset3dMenu(); + renderer.clearZBuffer(); + + //printf("In [%s::%s Line: %d] menuBackgroundVideo [%p]\n",__FILE__,__FUNCTION__,__LINE__,menuBackgroundVideo); + + if (menuBackgroundVideo == NULL) { + renderer.loadCameraMatrix(menuBackground.getCamera()); + renderer.renderMenuBackground(&menuBackground); + renderer.renderParticleManager(rsMenu); + } + + //2d + renderer.reset2d(); + + if (menuBackgroundVideo != NULL) { + if (menuBackgroundVideo->isPlaying() == true) { + menuBackgroundVideo->playFrame(false); + } else { + menuBackgroundVideo->RestartVideo(); + } + } + } + state->render(); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim); + renderer.renderFPSWhenEnabled(lastFps); + renderer.swapBuffers(); + } + } + } + + //syncronus update + void + MainMenu::update() { + if (menuBackgroundVideo == NULL) { + Renderer::getInstance().updateParticleManager(rsMenu); + } + mouse2dAnim = (mouse2dAnim + 1) % Renderer::maxMouse2dAnim; + if (menuBackgroundVideo == NULL) { + menuBackground.update(); + } + state->update(); + } + + //event magangement: mouse click + void + MainMenu::mouseMove(int x, int y, const MouseState * ms) { + mouseX = x; + mouseY = y; + state->mouseMove(x, y, ms); + } + + //returns if exiting + void + MainMenu::mouseDownLeft(int x, int y) { + if (GraphicComponent::getFade() < 0.2f) + return; + state->mouseClick(x, y, mbLeft); + } + + void + MainMenu::mouseDownRight(int x, int y) { + if (GraphicComponent::getFade() < 0.2f) + return; + state->mouseClick(x, y, mbRight); + } + + void + MainMenu::mouseUpLeft(int x, int y) { + if (GraphicComponent::getFade() < 0.2f) + return; + state->mouseUp(x, y, mbLeft); + } + + bool + MainMenu::textInput(std::string text) { + return state->textInput(text); + } + void + MainMenu::keyDown(SDL_KeyboardEvent key) { + state->keyDown(key); + } + + void + MainMenu::keyUp(SDL_KeyboardEvent key) { + state->keyUp(key); + } + + void + MainMenu::keyPress(SDL_KeyboardEvent c) { + state->keyPress(c); + } + + void + MainMenu::setState(MenuState * newstate) { + //printf("In [%s::%s Line: %d] oldstate [%p] newstate [%p] this->state [%p]\n",__FILE__,__FUNCTION__,__LINE__,oldstate,newstate,this->state); + + //printf("In MainMenu::setState() #1\n"); + + if (oldstate != NULL && oldstate != newstate) { + MenuState * + oldstatePtr = oldstate; + delete + oldstate; + + //printf("In MainMenu::setState() #2\n"); + + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if (oldstatePtr != this->state) { + oldstate = this->state; + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //printf("In MainMenu::setState() #3\n"); + } else { + oldstate = NULL; + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //printf("In MainMenu::setState() #4\n"); + } + } else { + oldstate = this->state; + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //printf("In MainMenu::setState() #5\n"); + } + + if (this->state != NULL) { + + } + + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + this->state = newstate; + + GraphicComponent::resetFade(); + if (newstate) { + menuBackground.setTargetCamera(newstate->getCamera()); + } + } + + bool + MainMenu::isInSpecialKeyCaptureEvent() { + return state->isInSpecialKeyCaptureEvent(); + } + + void + MainMenu::consoleAddLine(string line) { + if (state != NULL) { + state->consoleAddLine(line); + } + } + + // ===================================================== + // class MenuState + // ===================================================== + + MenuState::MenuState(Program * program, MainMenu * mainMenu, + const string & stateName) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, __FUNCTION__, + __LINE__); + this->containerName = "MenuState"; + this->program = program; + this->mainMenu = mainMenu; + console.registerGraphicComponent(containerName, "menuStateConsole"); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, __FUNCTION__, + __LINE__); + //switch on menu music again, it might be muted + Config & config = Config::getInstance(); + float + configVolume = (config.getInt("SoundVolumeMusic") / 100.f); + CoreData::getInstance().getMenuMusic()->setVolume(configVolume); + + string + data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + + //camera + XmlTree + xmlTree; + xmlTree. + load(getGameCustomCoreDataPath + (data_path, "data/core/menu/menu.xml"), + Properties::getTagReplacementValues()); + const XmlNode * + menuNode = xmlTree.getRootNode(); + const XmlNode * + cameraNode = menuNode->getChild("camera"); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, __FUNCTION__, + __LINE__); + + //position + const XmlNode * + positionNode = cameraNode->getChild(stateName + "-position"); + Vec3f + startPosition; + startPosition.x = positionNode->getAttribute("x")->getFloatValue(); + startPosition.y = positionNode->getAttribute("y")->getFloatValue(); + startPosition.z = positionNode->getAttribute("z")->getFloatValue(); + camera.setPosition(startPosition); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, __FUNCTION__, + __LINE__); + + //rotation + const XmlNode * + rotationNode = cameraNode->getChild(stateName + "-rotation"); + Vec3f + startRotation; + startRotation.x = rotationNode->getAttribute("x")->getFloatValue(); + startRotation.y = rotationNode->getAttribute("y")->getFloatValue(); + startRotation.z = rotationNode->getAttribute("z")->getFloatValue(); + camera. + setOrientation(Quaternion + (EulerAngles + (degToRad(startRotation.x), + degToRad(startRotation.y), + degToRad(startRotation.z)))); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, __FUNCTION__, + __LINE__); + } + + MenuState::~MenuState() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, __FUNCTION__, + __LINE__); + GraphicComponent::clearRegisteredComponents(this->containerName); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s %d]\n", __FILE__, __FUNCTION__, + __LINE__); + } + + void + MenuState::consoleAddLine(string line) { + bool + onlyWantChatMsgs = console.getOnlyChatMessagesInStoredLines(); + if (onlyWantChatMsgs == true) { + console.setOnlyChatMessagesInStoredLines(false); + } + console.addLine(line); + if (onlyWantChatMsgs == true) { + console.setOnlyChatMessagesInStoredLines(true); + } + } + + void + MenuState::reloadUI() { + //console.resetFonts(); + } + + void + MenuState::setActiveInputLabel(GraphicLabel * newLabel, + GraphicLabel ** activeInputLabelPtr) { + GraphicLabel * + activeInputLabelEdit = *activeInputLabelPtr; + if (newLabel != NULL) { + if (newLabel == activeInputLabelEdit) { + return; + } + string + text = newLabel->getText(); + size_t + found = text.find_last_of("_"); + if (found == string::npos || found != text.length() - 1) { + text += "_"; + } + newLabel->setText(text); + //textCharLength = extractKeyPressedUnicodeLength(text); + newLabel-> + setTextCharLengthList(extractKeyPressedUnicodeLength(text)); + } + if (activeInputLabelEdit != NULL + && activeInputLabelEdit->getText().empty() == false) { + string + text = activeInputLabelEdit->getText(); + size_t + found = text.find_last_of("_"); + if (found != string::npos && found == text.length() - 1) { + //printf("Removing trailing edit char, found = %d [%d][%s]\n",found,text.length(),text.c_str()); + text = text.substr(0, found); + } + activeInputLabelEdit->setText(text); + //textCharLength = extractKeyPressedUnicodeLength(text); + activeInputLabelEdit-> + setTextCharLengthList(extractKeyPressedUnicodeLength(text)); + activeInputLabelEdit->setEditModeEnabled(false); + } + if (newLabel != NULL) { + *activeInputLabelPtr = newLabel; + newLabel->setEditModeEnabled(true); + } else { + *activeInputLabelPtr = NULL; + } + } + + + bool + MenuState::keyPressEditLabel(SDL_KeyboardEvent c, + GraphicLabel ** activeInputLabelPtr) { + if (isKeyPressed(SDLK_ESCAPE, c, false) == true || + isKeyPressed(SDLK_RETURN, c, false) == true) { + GraphicLabel * + activeInputLabel = *activeInputLabelPtr; + setActiveInputLabel(NULL, activeInputLabelPtr); + //textCharLength.clear(); + activeInputLabel->clearTextCharLengthList(); + return true; + } + return false; + } + + bool + MenuState::textInputEditLabel(string input, + GraphicLabel ** activeInputLabelPtr) { + bool + eventHandled = false; + GraphicLabel * + activeInputLabel = *activeInputLabelPtr; + if (activeInputLabel != NULL) { + int + maxTextSize = activeInputLabel->getMaxEditWidth(); + + //if((c>='0' && c<='9') || (c>='a' && c<='z') || (c>='A' && c<='Z') || + // (c=='-') || (c=='(') || (c==')')) { + //if(isAllowedInputTextKey(key)) + { + if ((int) activeInputLabel->getTextCharLengthList().size() < + maxTextSize) { + string + text = activeInputLabel->getText(); + + if (text.size() > 0) { + size_t + found = text.find_last_of("_"); + if (found == string::npos || found != text.length() - 1) { + text += input; + activeInputLabel->addTextCharLengthToList(input.length()); + } else { + text = text.substr(0, found) + input + "_"; + //int lastCharLen = activeInputLabel->getTextCharLengthList()[activeInputLabel->getTextCharLengthList().size()-1]; + activeInputLabel->deleteTextCharLengthFromList(); + activeInputLabel->addTextCharLengthToList(input.length()); + activeInputLabel->addTextCharLengthToList(1); + } + } else { + text = input; + activeInputLabel->addTextCharLengthToList(input.length()); + } + //delete [] utfStr; + + activeInputLabel->setText(text); + + eventHandled = true; + } + } + } + return eventHandled; + } + + bool + MenuState::keyDownEditLabel(SDL_KeyboardEvent c, + GraphicLabel ** activeInputLabelPtr) { + bool + eventHandled = false; + GraphicLabel * + activeInputLabel = *activeInputLabelPtr; + if (activeInputLabel != NULL) { + string + text = activeInputLabel->getText(); + if (isKeyPressed(SDLK_BACKSPACE, c) == true && text.length() > 0) { + //printf("BSPACE text [%s]\n",text.c_str()); + + bool + hasUnderscore = false; + bool + delChar = false; + size_t + found = text.find_last_of("_"); + if (found == string::npos || found != text.length() - 1) { + //printf("A text.length() = %d textCharLength.size() = %d\n",text.length(),textCharLength.size()); + if (activeInputLabel-> + getTextCharLengthList()[activeInputLabel-> + getTextCharLengthList().size() - + 1] >= 1) { + delChar = true; + } + } else { + //printf("B text.length() = %d textCharLength.size() = %d\n",text.length(),textCharLength.size()); + hasUnderscore = true; + if (activeInputLabel->getTextCharLengthList().size() >= 2 + && activeInputLabel-> + getTextCharLengthList()[activeInputLabel-> + getTextCharLengthList().size() - + 2] >= 1) { + delChar = true; + } + } + if (delChar == true) { + if (hasUnderscore) { + //if(textCharLength.size() > 1) { + if (activeInputLabel->getTextCharLengthList().size() > 1) { + //printf("Underscore erase start\n"); + for (unsigned int i = 0; + i < + (unsigned int) activeInputLabel-> + getTextCharLengthList()[activeInputLabel-> + getTextCharLengthList(). + size() - 2]; ++i) { + text.erase(text.end() - 2); + } + //printf("AFTER DEL textCharLength.size() = %d textCharLength[textCharLength.size()-1] = %d text.length() = %d\n",textCharLength.size(),textCharLength[textCharLength.size()-1],text.length()); + activeInputLabel->deleteTextCharLengthFromList(); + activeInputLabel->deleteTextCharLengthFromList(); + activeInputLabel->addTextCharLengthToList(1); + } + } else { + for (unsigned int i = 0; + i < + (unsigned int) activeInputLabel-> + getTextCharLengthList()[activeInputLabel-> + getTextCharLengthList().size() - + 1]; ++i) { + text.erase(text.end() - 1); + } + activeInputLabel->deleteTextCharLengthFromList(); + } + } + activeInputLabel->setText(text); + eventHandled = true; + } + } + return eventHandled; + } + + } } //end namespace diff --git a/source/glest_game/menu/main_menu.h b/source/glest_game/menu/main_menu.h index 1d949b282..72369d7fe 100644 --- a/source/glest_game/menu/main_menu.h +++ b/source/glest_game/menu/main_menu.h @@ -27,173 +27,152 @@ # include "game_settings.h" # include "leak_dumper.h" -namespace Shared -{ - namespace Graphics - { - class VideoPlayer; - } +namespace Shared { + namespace Graphics { + class VideoPlayer; + } } -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - class MenuState; + class MenuState; -// ===================================================== -// class MainMenu -// -/// Main menu ProgramState -// ===================================================== + // ===================================================== + // class MainMenu + // + /// Main menu ProgramState + // ===================================================== - class MainMenu:public ProgramState - { + class MainMenu :public ProgramState { - private: - static MenuState *oldstate; - //up - Program *program; + private: + static MenuState *oldstate; + //up + Program *program; - //shared - GameSettings gameSettings; - MenuBackground menuBackground; - ::Shared::Graphics::VideoPlayer * menuBackgroundVideo; + //shared + GameSettings gameSettings; + MenuBackground menuBackground; + ::Shared::Graphics::VideoPlayer * menuBackgroundVideo; - MenuState *state; + MenuState *state; - //shared - int mouseX, mouseY; - int mouse2dAnim; + //shared + int mouseX, mouseY; + int mouse2dAnim; - void initBackgroundVideo (); + void initBackgroundVideo(); - public: - explicit MainMenu (Program * program); - virtual ~ MainMenu (); + public: + explicit MainMenu(Program * program); + virtual ~MainMenu(); - MenuBackground *getMenuBackground () - { - return &menuBackground; - } - const MenuBackground *getConstMenuBackground () const - { - return &menuBackground; - } + MenuBackground *getMenuBackground() { + return &menuBackground; + } + const MenuBackground *getConstMenuBackground() const { + return &menuBackground; + } - virtual void render (); - virtual void update (); - virtual void init (); - virtual void mouseMove (int x, int y, const MouseState * mouseState); - virtual void mouseDownLeft (int x, int y); - virtual void mouseDownRight (int x, int y); - virtual void mouseUpLeft (int x, int y); - virtual bool textInput (std::string text); - virtual void keyDown (SDL_KeyboardEvent key); - virtual void keyUp (SDL_KeyboardEvent key); - virtual void keyPress (SDL_KeyboardEvent key); + virtual void render(); + virtual void update(); + virtual void init(); + virtual void mouseMove(int x, int y, const MouseState * mouseState); + virtual void mouseDownLeft(int x, int y); + virtual void mouseDownRight(int x, int y); + virtual void mouseUpLeft(int x, int y); + virtual bool textInput(std::string text); + virtual void keyDown(SDL_KeyboardEvent key); + virtual void keyUp(SDL_KeyboardEvent key); + virtual void keyPress(SDL_KeyboardEvent key); - void setState (MenuState * state); - virtual bool isInSpecialKeyCaptureEvent (); + void setState(MenuState * state); + virtual bool isInSpecialKeyCaptureEvent(); - int getMouseX () const - { - return mouseX; - } - int getMouseY () const - { - return mouseY; - } - int getMouse2dAnim () const - { - return mouse2dAnim; - } - virtual void consoleAddLine (string line); - virtual void reloadUI (); - }; + int getMouseX() const { + return mouseX; + } + int getMouseY() const { + return mouseY; + } + int getMouse2dAnim() const { + return mouse2dAnim; + } + virtual void consoleAddLine(string line); + virtual void reloadUI(); + }; -// =============================== -// class MenuState -// =============================== + // =============================== + // class MenuState + // =============================== - class MenuState - { - protected: - Program * program; + class MenuState { + protected: + Program * program; - MainMenu *mainMenu; - Camera camera; + MainMenu *mainMenu; + Camera camera; - const char *containerName; - Console console; + const char *containerName; + Console console; - //vector textCharLength; + //vector textCharLength; - protected: + protected: - void setActiveInputLabel (GraphicLabel * newLabel, - GraphicLabel ** activeInputLabelPtr); - bool textInputEditLabel (string input, - GraphicLabel ** activeInputLabelPtr); - bool keyPressEditLabel (SDL_KeyboardEvent c, - GraphicLabel ** activeInputLabelPtr); - bool keyDownEditLabel (SDL_KeyboardEvent c, - GraphicLabel ** activeInputLabelPtr); + void setActiveInputLabel(GraphicLabel * newLabel, + GraphicLabel ** activeInputLabelPtr); + bool textInputEditLabel(string input, + GraphicLabel ** activeInputLabelPtr); + bool keyPressEditLabel(SDL_KeyboardEvent c, + GraphicLabel ** activeInputLabelPtr); + bool keyDownEditLabel(SDL_KeyboardEvent c, + GraphicLabel ** activeInputLabelPtr); - public: - MenuState (Program * program, MainMenu * mainMenu, - const string & stateName); - virtual ~ MenuState (); - virtual void mouseClick (int x, int y, MouseButton mouseButton) = 0; - virtual void mouseUp (int x, int y, const MouseButton mouseButton) - { - }; - virtual void mouseMove (int x, int y, const MouseState * mouseState) = - 0; - virtual void render () = 0; - virtual void update () - { - }; + public: + MenuState(Program * program, MainMenu * mainMenu, + const string & stateName); + virtual ~MenuState(); + virtual void mouseClick(int x, int y, MouseButton mouseButton) = 0; + virtual void mouseUp(int x, int y, const MouseButton mouseButton) { + }; + virtual void mouseMove(int x, int y, const MouseState * mouseState) = + 0; + virtual void render() = 0; + virtual void update() { + }; - virtual bool textInput (std::string text) - { - return false; - } - virtual void keyDown (SDL_KeyboardEvent key) - { - }; - virtual void keyPress (SDL_KeyboardEvent c) - { - }; - virtual void keyUp (SDL_KeyboardEvent key) - { - }; + virtual bool textInput(std::string text) { + return false; + } + virtual void keyDown(SDL_KeyboardEvent key) { + }; + virtual void keyPress(SDL_KeyboardEvent c) { + }; + virtual void keyUp(SDL_KeyboardEvent key) { + }; - virtual bool isMasterserverMode () const - { - return false; - } - const Camera *getCamera () const - { - return &camera; - } + virtual bool isMasterserverMode() const { + return false; + } + const Camera *getCamera() const { + return &camera; + } - virtual bool isInSpecialKeyCaptureEvent () - { - return false; - } - virtual void consoleAddLine (string line); - virtual void reloadUI (); + virtual bool isInSpecialKeyCaptureEvent() { + return false; + } + virtual void consoleAddLine(string line); + virtual void reloadUI(); - virtual bool isVideoPlaying () - { - return false; - }; - }; + virtual bool isVideoPlaying() { + return false; + }; + }; - } + } } //end namespace #endif diff --git a/source/glest_game/menu/menu_background.cpp b/source/glest_game/menu/menu_background.cpp index 2f53d9630..f4dea70e9 100644 --- a/source/glest_game/menu/menu_background.cpp +++ b/source/glest_game/menu/menu_background.cpp @@ -23,305 +23,272 @@ #include "leak_dumper.h" using namespace - Shared::Util; +Shared::Util; using namespace - Shared::Xml; +Shared::Xml; using namespace - Shared::Graphics; +Shared::Graphics; namespace - Glest -{ - namespace - Game - { + Glest { + namespace + Game { -// ===================================================== -// class MenuBackground -// ===================================================== + // ===================================================== + // class MenuBackground + // ===================================================== - MenuBackground::MenuBackground (): - rps (NULL) - { - Renderer & renderer = Renderer::getInstance (); + MenuBackground::MenuBackground() : + rps(NULL) { + Renderer & renderer = Renderer::getInstance(); - //load data - string - data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); + //load data + string + data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); - XmlTree - xmlTree; - xmlTree. - load (getGameCustomCoreDataPath (data_path, "data/core/menu/menu.xml"), - Properties::getTagReplacementValues ()); - const XmlNode * - menuNode = xmlTree.getRootNode (); + XmlTree + xmlTree; + xmlTree. + load(getGameCustomCoreDataPath(data_path, "data/core/menu/menu.xml"), + Properties::getTagReplacementValues()); + const XmlNode * + menuNode = xmlTree.getRootNode(); - //water - const XmlNode * - waterNode = menuNode->getChild ("water"); - water = waterNode->getAttribute ("value")->getBoolValue (); - if (water) - { - waterHeight = waterNode->getAttribute ("height")->getFloatValue (); + //water + const XmlNode * + waterNode = menuNode->getChild("water"); + water = waterNode->getAttribute("value")->getBoolValue(); + if (water) { + waterHeight = waterNode->getAttribute("height")->getFloatValue(); - //water texture - waterTexture = renderer.newTexture2D (rsMenu); - if (waterTexture) - { - waterTexture->getPixmap ()->init (4); - waterTexture-> - getPixmap ()-> - load (getGameCustomCoreDataPath - (data_path, "data/core/menu/textures/water.tga")); - } - } + //water texture + waterTexture = renderer.newTexture2D(rsMenu); + if (waterTexture) { + waterTexture->getPixmap()->init(4); + waterTexture-> + getPixmap()-> + load(getGameCustomCoreDataPath + (data_path, "data/core/menu/textures/water.tga")); + } + } - //fog - const XmlNode * - fogNode = menuNode->getChild ("fog"); - fog = fogNode->getAttribute ("value")->getBoolValue (); - if (fog) - { - fogDensity = fogNode->getAttribute ("density")->getFloatValue (); - } + //fog + const XmlNode * + fogNode = menuNode->getChild("fog"); + fog = fogNode->getAttribute("value")->getBoolValue(); + if (fog) { + fogDensity = fogNode->getAttribute("density")->getFloatValue(); + } - //rain - bool - withRainEffect = - Config::getInstance ().getBool ("RainEffectMenu", "true"); - if (withRainEffect == true) - { - rain = - menuNode->getChild ("rain")->getAttribute ("value")-> - getBoolValue (); - if (rain) - { - createRainParticleSystem (); - } - } - else - { - rain = false; - } + //rain + bool + withRainEffect = + Config::getInstance().getBool("RainEffectMenu", "true"); + if (withRainEffect == true) { + rain = + menuNode->getChild("rain")->getAttribute("value")-> + getBoolValue(); + if (rain) { + createRainParticleSystem(); + } + } else { + rain = false; + } - //camera - const XmlNode * - cameraNode = menuNode->getChild ("camera"); + //camera + const XmlNode * + cameraNode = menuNode->getChild("camera"); - //position - const XmlNode * - positionNode = cameraNode->getChild ("start-position"); - Vec3f - startPosition; - startPosition.x = positionNode->getAttribute ("x")->getFloatValue (); - startPosition.y = positionNode->getAttribute ("y")->getFloatValue (); - startPosition.z = positionNode->getAttribute ("z")->getFloatValue (); - camera.setPosition (startPosition); + //position + const XmlNode * + positionNode = cameraNode->getChild("start-position"); + Vec3f + startPosition; + startPosition.x = positionNode->getAttribute("x")->getFloatValue(); + startPosition.y = positionNode->getAttribute("y")->getFloatValue(); + startPosition.z = positionNode->getAttribute("z")->getFloatValue(); + camera.setPosition(startPosition); - //rotation - const XmlNode * - rotationNode = cameraNode->getChild ("start-rotation"); - Vec3f - startRotation; - startRotation.x = rotationNode->getAttribute ("x")->getFloatValue (); - startRotation.y = rotationNode->getAttribute ("y")->getFloatValue (); - startRotation.z = rotationNode->getAttribute ("z")->getFloatValue (); - camera. - setOrientation (Quaternion - (EulerAngles - (degToRad (startRotation.x), - degToRad (startRotation.y), - degToRad (startRotation.z)))); + //rotation + const XmlNode * + rotationNode = cameraNode->getChild("start-rotation"); + Vec3f + startRotation; + startRotation.x = rotationNode->getAttribute("x")->getFloatValue(); + startRotation.y = rotationNode->getAttribute("y")->getFloatValue(); + startRotation.z = rotationNode->getAttribute("z")->getFloatValue(); + camera. + setOrientation(Quaternion + (EulerAngles + (degToRad(startRotation.x), + degToRad(startRotation.y), + degToRad(startRotation.z)))); - //load main model - string - mainModelFile = "data/core/menu/main_model/menu_main.g3d"; - if (menuNode->hasChild ("menu-background-model") == true) - { - //mainModel->load(data_path + "data/core/menu/main_model/menu_main.g3d"); - const XmlNode * - mainMenuModelNode = menuNode->getChild ("menu-background-model"); - mainModelFile = - mainMenuModelNode->getAttribute ("value")->getRestrictedValue (); - } - mainModel = - renderer.newModel (rsMenu, - getGameCustomCoreDataPath (data_path, - mainModelFile)); + //load main model + string + mainModelFile = "data/core/menu/main_model/menu_main.g3d"; + if (menuNode->hasChild("menu-background-model") == true) { + //mainModel->load(data_path + "data/core/menu/main_model/menu_main.g3d"); + const XmlNode * + mainMenuModelNode = menuNode->getChild("menu-background-model"); + mainModelFile = + mainMenuModelNode->getAttribute("value")->getRestrictedValue(); + } + mainModel = + renderer.newModel(rsMenu, + getGameCustomCoreDataPath(data_path, + mainModelFile)); - //models - for (int i = 0; i < 5; ++i) - { - characterModels[i] = - renderer.newModel (rsMenu, - getGameCustomCoreDataPath (data_path, - "data/core/menu/about_models/character" - + intToStr (i) + - ".g3d")); - } + //models + for (int i = 0; i < 5; ++i) { + characterModels[i] = + renderer.newModel(rsMenu, + getGameCustomCoreDataPath(data_path, + "data/core/menu/about_models/character" + + intToStr(i) + + ".g3d")); + } - //about position - positionNode = cameraNode->getChild ("about-position"); - aboutPosition.x = positionNode->getAttribute ("x")->getFloatValue (); - aboutPosition.y = positionNode->getAttribute ("y")->getFloatValue (); - aboutPosition.z = positionNode->getAttribute ("z")->getFloatValue (); - //rotationNode= cameraNode->getChild("about-rotation"); + //about position + positionNode = cameraNode->getChild("about-position"); + aboutPosition.x = positionNode->getAttribute("x")->getFloatValue(); + aboutPosition.y = positionNode->getAttribute("y")->getFloatValue(); + aboutPosition.z = positionNode->getAttribute("z")->getFloatValue(); + //rotationNode= cameraNode->getChild("about-rotation"); - targetCamera = NULL; - t = 0.f; - fade = 0.f; - anim = 0.f; - } + targetCamera = NULL; + t = 0.f; + fade = 0.f; + anim = 0.f; + } - MenuBackground::~MenuBackground () - { - //printf("In ~MenuBackground() rps = %p\n",rps); + MenuBackground::~MenuBackground() { + //printf("In ~MenuBackground() rps = %p\n",rps); - cleanup (); - } + cleanup(); + } - void - MenuBackground::cleanup () - { - //printf("In MenuBackground::cleanup() rps = %p\n",rps); + void + MenuBackground::cleanup() { + //printf("In MenuBackground::cleanup() rps = %p\n",rps); - if (rps != NULL) - { - Renderer & renderer = Renderer::getInstance (); - if (renderer.validateParticleSystemStillExists (rps, rsMenu) == true) - { - rps->fade (); - vector < ParticleSystem * >particleSystems; - particleSystems.push_back (rps); - renderer.cleanupParticleSystems (particleSystems, rsMenu); - } + if (rps != NULL) { + Renderer & renderer = Renderer::getInstance(); + if (renderer.validateParticleSystemStillExists(rps, rsMenu) == true) { + rps->fade(); + vector < ParticleSystem * >particleSystems; + particleSystems.push_back(rps); + renderer.cleanupParticleSystems(particleSystems, rsMenu); + } - rps = NULL; - } - } + rps = NULL; + } + } - void - MenuBackground::createRainParticleSystem () - { - //printf("In MenuBackground::createRainParticleSystem() rps = %p\n",rps); + void + MenuBackground::createRainParticleSystem() { + //printf("In MenuBackground::createRainParticleSystem() rps = %p\n",rps); - if (rps == NULL) - { - rps = new RainParticleSystem (); - rps->setSpeed (12.f / GameConstants::updateFps); - rps->setEmissionRate (25); - rps->setWind (-90.f, 4.f / GameConstants::updateFps); - rps->setPos (Vec3f (0.f, 25.f, 0.f)); - rps->setColor (Vec4f (1.f, 1.f, 1.f, 0.2f)); - rps->setRadius (30.f); + if (rps == NULL) { + rps = new RainParticleSystem(); + rps->setSpeed(12.f / GameConstants::updateFps); + rps->setEmissionRate(25); + rps->setWind(-90.f, 4.f / GameConstants::updateFps); + rps->setPos(Vec3f(0.f, 25.f, 0.f)); + rps->setColor(Vec4f(1.f, 1.f, 1.f, 0.2f)); + rps->setRadius(30.f); - Renderer & renderer = Renderer::getInstance (); - renderer.manageParticleSystem (rps, rsMenu); + Renderer & renderer = Renderer::getInstance(); + renderer.manageParticleSystem(rps, rsMenu); - for (int i = 0; i < raindropCount; ++i) - { - raindropStates[i] = random.randRange (0.f, 1.f); - raindropPos[i] = computeRaindropPos (); - } - } - } + for (int i = 0; i < raindropCount; ++i) { + raindropStates[i] = random.randRange(0.f, 1.f); + raindropPos[i] = computeRaindropPos(); + } + } + } - void - MenuBackground::setTargetCamera (const Camera * targetCamera) - { - this->targetCamera = targetCamera; - this->lastCamera = camera; - t = 0.f; - } + void + MenuBackground::setTargetCamera(const Camera * targetCamera) { + this->targetCamera = targetCamera; + this->lastCamera = camera; + t = 0.f; + } - void - MenuBackground::update () - { - //rain drops - bool - withRainEffect = - Config::getInstance ().getBool ("RainEffectMenu", "true"); - if (withRainEffect == true) - { - if (rain == false) - { - rain = true; - createRainParticleSystem (); - } + void + MenuBackground::update() { + //rain drops + bool + withRainEffect = + Config::getInstance().getBool("RainEffectMenu", "true"); + if (withRainEffect == true) { + if (rain == false) { + rain = true; + createRainParticleSystem(); + } - for (int i = 0; i < raindropCount; ++i) - { - raindropStates[i] += 1.f / GameConstants::updateFps; - if (raindropStates[i] >= 1.f) - { - raindropStates[i] = 0.f; - raindropPos[i] = computeRaindropPos (); - } - } - } - else if (rain == true) - { - rain = false; + for (int i = 0; i < raindropCount; ++i) { + raindropStates[i] += 1.f / GameConstants::updateFps; + if (raindropStates[i] >= 1.f) { + raindropStates[i] = 0.f; + raindropPos[i] = computeRaindropPos(); + } + } + } else if (rain == true) { + rain = false; - cleanup (); - } + cleanup(); + } - if (targetCamera != NULL) - { - t += - ((0.01f + - (1.f - t) / 10.f) / 20.f) * (60.f / GameConstants::updateFps); + if (targetCamera != NULL) { + t += + ((0.01f + + (1.f - t) / 10.f) / 20.f) * (60.f / GameConstants::updateFps); - //interpolate position - camera.setPosition (lastCamera.getPosition (). - lerp (t, targetCamera->getPosition ())); + //interpolate position + camera.setPosition(lastCamera.getPosition(). + lerp(t, targetCamera->getPosition())); - //interpolate orientation - Quaternion - q = - lastCamera.getOrientation ().lerp (t, - targetCamera->getOrientation ()); - camera.setOrientation (q); + //interpolate orientation + Quaternion + q = + lastCamera.getOrientation().lerp(t, + targetCamera->getOrientation()); + camera.setOrientation(q); - if (t >= 1.f) - { - targetCamera = NULL; - t = 0.f; - } - } + if (t >= 1.f) { + targetCamera = NULL; + t = 0.f; + } + } - //fade - if (fade <= 1.f) - { - fade += 0.6f / GameConstants::updateFps; - if (fade > 1.f) - { - fade = 1.f; - } - } + //fade + if (fade <= 1.f) { + fade += 0.6f / GameConstants::updateFps; + if (fade > 1.f) { + fade = 1.f; + } + } - //animation - anim += - (0.6f / GameConstants::updateFps) / 5 + random.randRange (0.f, - (0.6f / - GameConstants:: - updateFps) - / 5.f); - if (anim > 1.f) - { - anim = 0.f; - } - } + //animation + anim += + (0.6f / GameConstants::updateFps) / 5 + random.randRange(0.f, + (0.6f / + GameConstants:: + updateFps) + / 5.f); + if (anim > 1.f) { + anim = 0.f; + } + } - Vec2f - MenuBackground::computeRaindropPos () - { - float - f = static_cast < float >(meshSize); - return Vec2f (random.randRange (-f, f), random.randRange (-f, f)); - } + Vec2f + MenuBackground::computeRaindropPos() { + float + f = static_cast (meshSize); + return Vec2f(random.randRange(-f, f), random.randRange(-f, f)); + } - } + } } //end namespace diff --git a/source/glest_game/menu/menu_background.h b/source/glest_game/menu/menu_background.h index 3ed5a8ca0..e47c40ca7 100644 --- a/source/glest_game/menu/menu_background.h +++ b/source/glest_game/menu/menu_background.h @@ -26,215 +26,197 @@ # include "leak_dumper.h" using - Shared::Graphics::RainParticleSystem; +Shared::Graphics::RainParticleSystem; using - Shared::Graphics::FireParticleSystem; +Shared::Graphics::FireParticleSystem; using - Shared::Graphics::Camera; +Shared::Graphics::Camera; using - Shared::Graphics::Vec3f; +Shared::Graphics::Vec3f; using - Shared::Graphics::Vec2f; +Shared::Graphics::Vec2f; using - Shared::Graphics::Texture2D; +Shared::Graphics::Texture2D; using - Shared::Graphics::Model; +Shared::Graphics::Model; using - Shared::Util::RandomGen; +Shared::Util::RandomGen; namespace - Glest -{ - namespace - Game - { + Glest { + namespace + Game { -// =========================================================== -// class MenuBackground -// -/// Holds the data to display the 3D environment -/// in the MenuState -// =========================================================== + // =========================================================== + // class MenuBackground + // + /// Holds the data to display the 3D environment + /// in the MenuState + // =========================================================== - class - MenuBackground - { - public: - static const int - meshSize = 32; - static const int - raindropCount = 1000; - static const int - characterCount = 5; + class + MenuBackground { + public: + static const int + meshSize = 32; + static const int + raindropCount = 1000; + static const int + characterCount = 5; - private: - Model * - mainModel; + private: + Model * + mainModel; - //water - bool - water; - float - waterHeight; - Texture2D * - waterTexture; + //water + bool + water; + float + waterHeight; + Texture2D * + waterTexture; - //fog - bool - fog; - float - fogDensity; + //fog + bool + fog; + float + fogDensity; - //rain - bool - rain; - Vec2f - raindropPos[raindropCount]; - float - raindropStates[raindropCount]; + //rain + bool + rain; + Vec2f + raindropPos[raindropCount]; + float + raindropStates[raindropCount]; - //camera - Camera - camera; - Camera - lastCamera; - const Camera * - targetCamera; - float - t; + //camera + Camera + camera; + Camera + lastCamera; + const Camera * + targetCamera; + float + t; - //misc - RandomGen - random; - Model * - characterModels[characterCount]; - float - anim; - float - fade; - Vec3f - aboutPosition; + //misc + RandomGen + random; + Model * + characterModels[characterCount]; + float + anim; + float + fade; + Vec3f + aboutPosition; - RainParticleSystem * - rps; + RainParticleSystem * + rps; - public: - MenuBackground (); - ~ - MenuBackground (); + public: + MenuBackground(); + ~ + MenuBackground(); - bool - getWater () const - { - return - water; - } - float - getWaterHeight () const - { - return - waterHeight; - } - bool - getFog () const - { - return - fog; - } - float - getFogDensity () const - { - return - fogDensity; - } - bool - getRain () const - { - return - rain; - } - Texture2D * - getWaterTexture () const - { - return - waterTexture; - } - const Camera * - getCamera () const - { - return & - camera; - } - const Model * - getCharacterModel (int i) const - { - return - characterModels[i]; - } - Model * - getCharacterModelPtr (int i) const - { - return - characterModels[i]; - } - const Model * - getMainModel () const - { - return - mainModel; - } - Model * - getMainModelPtr () const - { - return - mainModel; - } - float - getFade () const - { - return - fade; - } - Vec2f - getRaindropPos (int i) const - { - return - raindropPos[i]; - } - float - getRaindropState (int i) const - { - return - raindropStates[i]; - } - float - getAnim () const - { - return - anim; - } - const - Vec3f & - getAboutPosition () const - { - return - aboutPosition; - } + bool + getWater() const { + return + water; + } + float + getWaterHeight() const { + return + waterHeight; + } + bool + getFog() const { + return + fog; + } + float + getFogDensity() const { + return + fogDensity; + } + bool + getRain() const { + return + rain; + } + Texture2D * + getWaterTexture() const { + return + waterTexture; + } + const Camera * + getCamera() const { + return & + camera; + } + const Model * + getCharacterModel(int i) const { + return + characterModels[i]; + } + Model * + getCharacterModelPtr(int i) const { + return + characterModels[i]; + } + const Model * + getMainModel() const { + return + mainModel; + } + Model * + getMainModelPtr() const { + return + mainModel; + } + float + getFade() const { + return + fade; + } + Vec2f + getRaindropPos(int i) const { + return + raindropPos[i]; + } + float + getRaindropState(int i) const { + return + raindropStates[i]; + } + float + getAnim() const { + return + anim; + } + const + Vec3f & + getAboutPosition() const { + return + aboutPosition; + } - void - setTargetCamera (const Camera * targetCamera); - void - update (); + void + setTargetCamera(const Camera * targetCamera); + void + update(); - private: - Vec2f - computeRaindropPos (); - void - createRainParticleSystem (); - void - cleanup (); - }; + private: + Vec2f + computeRaindropPos(); + void + createRainParticleSystem(); + void + cleanup(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/menu/menu_state_about.cpp b/source/glest_game/menu/menu_state_about.cpp index c5f76c7f0..3e1f3dd56 100644 --- a/source/glest_game/menu/menu_state_about.cpp +++ b/source/glest_game/menu/menu_state_about.cpp @@ -25,398 +25,348 @@ using namespace std; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class MenuStateAbout -// ===================================================== + // ===================================================== + // class MenuStateAbout + // ===================================================== - MenuStateAbout::MenuStateAbout (Program * program, - MainMenu * mainMenu):MenuState (program, - mainMenu, - "about") - { + MenuStateAbout::MenuStateAbout(Program * program, + MainMenu * mainMenu) :MenuState(program, + mainMenu, + "about") { - containerName = "About"; - Lang & lang = Lang::getInstance (); + containerName = "About"; + Lang & lang = Lang::getInstance(); - adjustModelText = true; + adjustModelText = true; - customModTextureX = 0; - customModTextureY = 0; - customModTextureW = 0; - customModTextureH = 0; - customModTextureAlpha = 0.f; + customModTextureX = 0; + customModTextureY = 0; + customModTextureW = 0; + customModTextureH = 0; + customModTextureAlpha = 0.f; - string additionalCredits = loadAdditionalCredits (); + string additionalCredits = loadAdditionalCredits(); - //init - buttonReturn.registerGraphicComponent (containerName, "buttonReturn"); - buttonReturn.init (438, 100, 125); - buttonReturn.setText (lang.getString ("Return")); + //init + buttonReturn.registerGraphicComponent(containerName, "buttonReturn"); + buttonReturn.init(438, 100, 125); + buttonReturn.setText(lang.getString("Return")); - labelAdditionalCredits.registerGraphicComponent (containerName, - "labelAdditionalCredits"); - labelAdditionalCredits.init (500, 700); - labelAdditionalCredits.setText (additionalCredits); + labelAdditionalCredits.registerGraphicComponent(containerName, + "labelAdditionalCredits"); + labelAdditionalCredits.init(500, 700); + labelAdditionalCredits.setText(additionalCredits); - if (additionalCredits == "") - { - for (int i = 0; i < aboutStringCount1; ++i) - { - labelAbout1[i].registerGraphicComponent (containerName, - "labelAbout1" + - intToStr (i)); - labelAbout1[i].init (100, 700 - i * 20); - labelAbout1[i].setText (getAboutString1 (i)); - } + if (additionalCredits == "") { + for (int i = 0; i < aboutStringCount1; ++i) { + labelAbout1[i].registerGraphicComponent(containerName, + "labelAbout1" + + intToStr(i)); + labelAbout1[i].init(100, 700 - i * 20); + labelAbout1[i].setText(getAboutString1(i)); + } - for (int i = 0; i < aboutStringCount2; ++i) - { - labelAbout2[i].registerGraphicComponent (containerName, - "labelAbout2" + - intToStr (i)); - labelAbout2[i].init (450, 620 - i * 20); - labelAbout2[i].setText (getAboutString2 (i)); - } - } - else - { - for (int i = 0; i < aboutStringCount1; ++i) - { - labelAbout1[i].registerGraphicComponent (containerName, - "labelAbout1" + - intToStr (i)); - labelAbout1[i].init (100, 700 - i * 20); - labelAbout1[i].setText (getAboutString1 (i)); - } + for (int i = 0; i < aboutStringCount2; ++i) { + labelAbout2[i].registerGraphicComponent(containerName, + "labelAbout2" + + intToStr(i)); + labelAbout2[i].init(450, 620 - i * 20); + labelAbout2[i].setText(getAboutString2(i)); + } + } else { + for (int i = 0; i < aboutStringCount1; ++i) { + labelAbout1[i].registerGraphicComponent(containerName, + "labelAbout1" + + intToStr(i)); + labelAbout1[i].init(100, 700 - i * 20); + labelAbout1[i].setText(getAboutString1(i)); + } - for (int i = 0; i < aboutStringCount2; ++i) - { - labelAbout2[i].registerGraphicComponent (containerName, - "labelAbout2" + - intToStr (i)); - labelAbout2[i].init (100, 620 - i * 20); - labelAbout2[i].setText (getAboutString2 (i)); - } - } + for (int i = 0; i < aboutStringCount2; ++i) { + labelAbout2[i].registerGraphicComponent(containerName, + "labelAbout2" + + intToStr(i)); + labelAbout2[i].init(100, 620 - i * 20); + labelAbout2[i].setText(getAboutString2(i)); + } + } - for (int i = 0; i < teammateCount; ++i) - { - int xPos = (182 + i * 138); - labelTeammateName[i].registerGraphicComponent (containerName, - "labelTeammateName" + - intToStr (i)); - labelTeammateName[i].init (xPos, 500); - labelTeammateRole[i].registerGraphicComponent (containerName, - "labelTeammateRole" + - intToStr (i)); - labelTeammateRole[i].init (xPos, 520); + for (int i = 0; i < teammateCount; ++i) { + int xPos = (182 + i * 138); + labelTeammateName[i].registerGraphicComponent(containerName, + "labelTeammateName" + + intToStr(i)); + labelTeammateName[i].init(xPos, 500); + labelTeammateRole[i].registerGraphicComponent(containerName, + "labelTeammateRole" + + intToStr(i)); + labelTeammateRole[i].init(xPos, 520); - labelTeammateName[i].setText (getTeammateName (i)); - labelTeammateRole[i].setText (getTeammateRole (i)); - } + labelTeammateName[i].setText(getTeammateName(i)); + labelTeammateRole[i].setText(getTeammateRole(i)); + } - for (int i = teammateTopLineCount; i < teammateCount; ++i) - { - labelTeammateName[i].init (202 + (i - 5) * 138, 160); - labelTeammateRole[i].init (202 + (i - 5) * 138, 180); - } - labelTeammateName[8].init (labelTeammateName[4].getX (), 160); - labelTeammateRole[8].init (labelTeammateRole[4].getX (), 180); + for (int i = teammateTopLineCount; i < teammateCount; ++i) { + labelTeammateName[i].init(202 + (i - 5) * 138, 160); + labelTeammateRole[i].init(202 + (i - 5) * 138, 180); + } + labelTeammateName[8].init(labelTeammateName[4].getX(), 160); + labelTeammateRole[8].init(labelTeammateRole[4].getX(), 180); - customModTexture = NULL; - labelCustomModCredits.registerGraphicComponent (containerName, - "labelCustomModCredits"); - labelCustomModCredits.init (-1, -1); - labelCustomModCredits.setText (""); - labelCustomModCredits.setVisible (false); + customModTexture = NULL; + labelCustomModCredits.registerGraphicComponent(containerName, + "labelCustomModCredits"); + labelCustomModCredits.init(-1, -1); + labelCustomModCredits.setText(""); + labelCustomModCredits.setVisible(false); - enableCustomModCredits = - Config::getInstance ().getBool ("EnabledCustomModCredits", "false"); - if (enableCustomModCredits == true) - { - string customModCreditsText = - Config::getInstance ().getString ("CustomModCreditsText", ""); - if (customModCreditsText != "") - { - replaceAll (customModCreditsText, "\\n", "\n"); - int x = - Config::getInstance ().getInt ("CustomModCreditsTextX", "1"); - int y = - Config::getInstance ().getInt ("CustomModCreditsTextY", "1"); - int w = - Config::getInstance ().getInt ("CustomModCreditsTextW", - intToStr (GraphicLabel::defW). - c_str ()); - int h = - Config::getInstance ().getInt ("CustomModCreditsTextH", - intToStr (GraphicLabel::defH). - c_str ()); + enableCustomModCredits = + Config::getInstance().getBool("EnabledCustomModCredits", "false"); + if (enableCustomModCredits == true) { + string customModCreditsText = + Config::getInstance().getString("CustomModCreditsText", ""); + if (customModCreditsText != "") { + replaceAll(customModCreditsText, "\\n", "\n"); + int x = + Config::getInstance().getInt("CustomModCreditsTextX", "1"); + int y = + Config::getInstance().getInt("CustomModCreditsTextY", "1"); + int w = + Config::getInstance().getInt("CustomModCreditsTextW", + intToStr(GraphicLabel::defW). + c_str()); + int h = + Config::getInstance().getInt("CustomModCreditsTextH", + intToStr(GraphicLabel::defH). + c_str()); - labelCustomModCredits.init (x, y, w, h); - labelCustomModCredits.setText (customModCreditsText); - labelCustomModCredits.setVisible (true); - } + labelCustomModCredits.init(x, y, w, h); + labelCustomModCredits.setText(customModCreditsText); + labelCustomModCredits.setVisible(true); + } - int buttonReturnX = - Config::getInstance ().getInt ("CustomModCreditsReturnX", - intToStr (buttonReturn.getX ()). - c_str ()); - int buttonReturnY = - Config::getInstance ().getInt ("CustomModCreditsReturnY", - intToStr (buttonReturn.getY ()). - c_str ()); - int buttonReturnW = - Config::getInstance ().getInt ("CustomModCreditsReturnW", - intToStr (buttonReturn.getW ()). - c_str ()); + int buttonReturnX = + Config::getInstance().getInt("CustomModCreditsReturnX", + intToStr(buttonReturn.getX()). + c_str()); + int buttonReturnY = + Config::getInstance().getInt("CustomModCreditsReturnY", + intToStr(buttonReturn.getY()). + c_str()); + int buttonReturnW = + Config::getInstance().getInt("CustomModCreditsReturnW", + intToStr(buttonReturn.getW()). + c_str()); - buttonReturn.init (buttonReturnX, buttonReturnY, buttonReturnW); - } + buttonReturn.init(buttonReturnX, buttonReturnY, buttonReturnW); + } - GraphicComponent::applyAllCustomProperties (containerName); - } + GraphicComponent::applyAllCustomProperties(containerName); + } - MenuStateAbout::~MenuStateAbout () - { - if (customModTexture != NULL) - { - Renderer::getInstance ().endTexture (rsGlobal, customModTexture, - false); - customModTexture = NULL; - } - } + MenuStateAbout::~MenuStateAbout() { + if (customModTexture != NULL) { + Renderer::getInstance().endTexture(rsGlobal, customModTexture, + false); + customModTexture = NULL; + } + } - void MenuStateAbout::reloadUI () - { - Lang & lang = Lang::getInstance (); + void MenuStateAbout::reloadUI() { + Lang & lang = Lang::getInstance(); - adjustModelText = true; - string additionalCredits = loadAdditionalCredits (); + adjustModelText = true; + string additionalCredits = loadAdditionalCredits(); - buttonReturn.setText (lang.getString ("Return")); - labelAdditionalCredits.setText (additionalCredits); + buttonReturn.setText(lang.getString("Return")); + labelAdditionalCredits.setText(additionalCredits); - //if(additionalCredits == "") { - for (int i = 0; i < aboutStringCount1; ++i) - { - labelAbout1[i].setText (getAboutString1 (i)); - } + //if(additionalCredits == "") { + for (int i = 0; i < aboutStringCount1; ++i) { + labelAbout1[i].setText(getAboutString1(i)); + } - for (int i = 0; i < aboutStringCount2; ++i) - { - labelAbout2[i].setText (getAboutString2 (i)); - } - //} - //else { - // for(int i= 0; i < aboutStringCount1; ++i){ - // labelAbout1[i].setText(getAboutString1(i)); - // } + for (int i = 0; i < aboutStringCount2; ++i) { + labelAbout2[i].setText(getAboutString2(i)); + } + //} + //else { + // for(int i= 0; i < aboutStringCount1; ++i){ + // labelAbout1[i].setText(getAboutString1(i)); + // } - // for(int i= 0; i < aboutStringCount2; ++i){ - // labelAbout2[i].setText(getAboutString2(i)); - // } - //} + // for(int i= 0; i < aboutStringCount2; ++i){ + // labelAbout2[i].setText(getAboutString2(i)); + // } + //} - for (int i = 0; i < teammateCount; ++i) - { - labelTeammateName[i].setText (getTeammateName (i)); - labelTeammateRole[i].setText (getTeammateRole (i)); - } + for (int i = 0; i < teammateCount; ++i) { + labelTeammateName[i].setText(getTeammateName(i)); + labelTeammateRole[i].setText(getTeammateRole(i)); + } - GraphicComponent:: - reloadFontsForRegisterGraphicComponents (containerName); - } + GraphicComponent:: + reloadFontsForRegisterGraphicComponents(containerName); + } - string MenuStateAbout::loadAdditionalCredits () - { - string data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - if (data_path != "") - { - endPathWithSlash (data_path); - } - string result = ""; - const string dir = - getGameCustomCoreDataPath (data_path, "data/core/menu/credits.txt"); - //printf("dir [%s]\n",dir.c_str()); + string MenuStateAbout::loadAdditionalCredits() { + string data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + if (data_path != "") { + endPathWithSlash(data_path); + } + string result = ""; + const string dir = + getGameCustomCoreDataPath(data_path, "data/core/menu/credits.txt"); + //printf("dir [%s]\n",dir.c_str()); - if (fileExists (dir) == true) - { + if (fileExists(dir) == true) { #if defined(WIN32) && !defined(__MINGW32__) - FILE *fp = _wfopen (utf8_decode (dir).c_str (), L"r"); - ifstream file (fp); + FILE *fp = _wfopen(utf8_decode(dir).c_str(), L"r"); + ifstream file(fp); #else - ifstream file (dir.c_str ()); + ifstream file(dir.c_str()); #endif - std::string buffer; - while (!file.eof ()) - { - getline (file, buffer); - result += buffer + "\n"; - } - std::cout << buffer << std::endl; - file.close (); + std::string buffer; + while (!file.eof()) { + getline(file, buffer); + result += buffer + "\n"; + } + std::cout << buffer << std::endl; + file.close(); #if defined(WIN32) && !defined(__MINGW32__) - if (fp) - fclose (fp); + if (fp) + fclose(fp); #endif - } - return result; - } + } + return result; + } - void MenuStateAbout::mouseClick (int x, int y, MouseButton mouseButton) - { + void MenuStateAbout::mouseClick(int x, int y, MouseButton mouseButton) { - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); - if (buttonReturn.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateRoot (program, mainMenu)); - } + if (buttonReturn.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateRoot(program, mainMenu)); + } - } + } - void MenuStateAbout::mouseMove (int x, int y, const MouseState * ms) - { - buttonReturn.mouseMove (x, y); - } + void MenuStateAbout::mouseMove(int x, int y, const MouseState * ms) { + buttonReturn.mouseMove(x, y); + } - void MenuStateAbout::render () - { - Renderer & renderer = Renderer::getInstance (); + void MenuStateAbout::render() { + Renderer & renderer = Renderer::getInstance(); - if (enableCustomModCredits == true) - { - if (customModTexture == NULL) - { - string customModCreditsTextureFile = - Config::getInstance ().getString ("CustomModCreditsTextureFile", - ""); - if (customModCreditsTextureFile != "") - { - string data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - if (data_path != "") - { - endPathWithSlash (data_path); - } - customModTexture = - Renderer::findTexture (data_path + customModCreditsTextureFile); - } - } + if (enableCustomModCredits == true) { + if (customModTexture == NULL) { + string customModCreditsTextureFile = + Config::getInstance().getString("CustomModCreditsTextureFile", + ""); + if (customModCreditsTextureFile != "") { + string data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + if (data_path != "") { + endPathWithSlash(data_path); + } + customModTexture = + Renderer::findTexture(data_path + customModCreditsTextureFile); + } + } - renderer.renderBackground (customModTexture); - renderer.renderLabel (&labelCustomModCredits); - } - else - { - renderer.renderLabel (&labelAdditionalCredits); + renderer.renderBackground(customModTexture); + renderer.renderLabel(&labelCustomModCredits); + } else { + renderer.renderLabel(&labelAdditionalCredits); - for (int i = 0; i < aboutStringCount1; ++i) - { - renderer.renderLabel (&labelAbout1[i]); - } - for (int i = 0; i < aboutStringCount2; ++i) - { - renderer.renderLabel (&labelAbout2[i]); - } + for (int i = 0; i < aboutStringCount1; ++i) { + renderer.renderLabel(&labelAbout1[i]); + } + for (int i = 0; i < aboutStringCount2; ++i) { + renderer.renderLabel(&labelAbout2[i]); + } - if (adjustModelText == true) - { - std::vector < Vec3f > &characterMenuScreenPositionListCache = - CacheManager::getCachedItem < std::vector < Vec3f > - >(GameConstants::characterMenuScreenPositionListCacheLookupKey); + if (adjustModelText == true) { + std::vector < Vec3f > &characterMenuScreenPositionListCache = + CacheManager::getCachedItem < std::vector < Vec3f > + >(GameConstants::characterMenuScreenPositionListCacheLookupKey); - for (int i = 0; i < teammateCount; ++i) - { - int characterPos = (i % teammateTopLineCount); - if (characterPos < - (int) characterMenuScreenPositionListCache.size ()) - { - adjustModelText = false; + for (int i = 0; i < teammateCount; ++i) { + int characterPos = (i % teammateTopLineCount); + if (characterPos < + (int) characterMenuScreenPositionListCache.size()) { + adjustModelText = false; - int xPos = characterMenuScreenPositionListCache[characterPos].x; - if (i == 7 - && characterPos + 1 < - (int) characterMenuScreenPositionListCache.size ()) - { - xPos += - ((characterMenuScreenPositionListCache[characterPos + 1].x - - characterMenuScreenPositionListCache[characterPos].x) / - 2); - } - else if (i == 8 - && characterPos + 1 < - (int) characterMenuScreenPositionListCache.size ()) - { - xPos = - characterMenuScreenPositionListCache[characterPos + 1].x; - } + int xPos = characterMenuScreenPositionListCache[characterPos].x; + if (i == 7 + && characterPos + 1 < + (int) characterMenuScreenPositionListCache.size()) { + xPos += + ((characterMenuScreenPositionListCache[characterPos + 1].x - + characterMenuScreenPositionListCache[characterPos].x) / + 2); + } else if (i == 8 + && characterPos + 1 < + (int) characterMenuScreenPositionListCache.size()) { + xPos = + characterMenuScreenPositionListCache[characterPos + 1].x; + } - FontMetrics *fontMetrics = NULL; - if (Renderer::renderText3DEnabled == false) - { - fontMetrics = labelTeammateName[i].getFont ()->getMetrics (); - } - else - { - fontMetrics = - labelTeammateName[i].getFont3D ()->getMetrics (); - } - int newxPos = - xPos - - (fontMetrics->getTextWidth (labelTeammateName[i].getText ()) / - 2); - if (newxPos != labelTeammateName[i].getX ()) - { - labelTeammateName[i].init (newxPos, - labelTeammateName[i].getY ()); - } + FontMetrics *fontMetrics = NULL; + if (Renderer::renderText3DEnabled == false) { + fontMetrics = labelTeammateName[i].getFont()->getMetrics(); + } else { + fontMetrics = + labelTeammateName[i].getFont3D()->getMetrics(); + } + int newxPos = + xPos - + (fontMetrics->getTextWidth(labelTeammateName[i].getText()) / + 2); + if (newxPos != labelTeammateName[i].getX()) { + labelTeammateName[i].init(newxPos, + labelTeammateName[i].getY()); + } - newxPos = - xPos - - (fontMetrics->getTextWidth (labelTeammateRole[i].getText ()) / - 2); - if (newxPos != labelTeammateRole[i].getX ()) - { - labelTeammateRole[i].init (newxPos, - labelTeammateRole[i].getY ()); - } - } - } - } + newxPos = + xPos - + (fontMetrics->getTextWidth(labelTeammateRole[i].getText()) / + 2); + if (newxPos != labelTeammateRole[i].getX()) { + labelTeammateRole[i].init(newxPos, + labelTeammateRole[i].getY()); + } + } + } + } - for (int i = 0; i < teammateCount; ++i) - { - renderer.renderLabel (&labelTeammateName[i]); - renderer.renderLabel (&labelTeammateRole[i]); - } - } + for (int i = 0; i < teammateCount; ++i) { + renderer.renderLabel(&labelTeammateName[i]); + renderer.renderLabel(&labelTeammateRole[i]); + } + } - renderer.renderButton (&buttonReturn); + renderer.renderButton(&buttonReturn); - if (program != NULL) - program->renderProgramMsgBox (); + if (program != NULL) + program->renderProgramMsgBox(); - } + } - void MenuStateAbout::keyDown (SDL_KeyboardEvent key) - { - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - if (isKeyPressed (configKeys.getSDLKey ("SaveGUILayout"), key) == true) - { - GraphicComponent::saveAllCustomProperties (containerName); - } - } + void MenuStateAbout::keyDown(SDL_KeyboardEvent key) { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), key) == true) { + GraphicComponent::saveAllCustomProperties(containerName); + } + } - } + } } //end namespace diff --git a/source/glest_game/menu/menu_state_about.h b/source/glest_game/menu/menu_state_about.h index 8aff74123..884e79737 100644 --- a/source/glest_game/menu/menu_state_about.h +++ b/source/glest_game/menu/menu_state_about.h @@ -20,56 +20,54 @@ # include "main_menu.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// =============================== -// class MenuStateAbout -// =============================== + // =============================== + // class MenuStateAbout + // =============================== - class MenuStateAbout:public MenuState - { - public: - static const int aboutStringCount1 = 4; - static const int aboutStringCount2 = 3; - static const int teammateCount = 9; - static const int teammateTopLineCount = 5; + class MenuStateAbout :public MenuState { + public: + static const int aboutStringCount1 = 4; + static const int aboutStringCount2 = 3; + static const int teammateCount = 9; + static const int teammateTopLineCount = 5; - private: - GraphicButton buttonReturn; - GraphicLabel labelAdditionalCredits; - GraphicLabel labelAbout1[aboutStringCount1]; - GraphicLabel labelAbout2[aboutStringCount2]; - GraphicLabel labelTeammateName[teammateCount]; - GraphicLabel labelTeammateRole[teammateCount]; + private: + GraphicButton buttonReturn; + GraphicLabel labelAdditionalCredits; + GraphicLabel labelAbout1[aboutStringCount1]; + GraphicLabel labelAbout2[aboutStringCount2]; + GraphicLabel labelTeammateName[teammateCount]; + GraphicLabel labelTeammateRole[teammateCount]; - bool adjustModelText; - string loadAdditionalCredits (); + bool adjustModelText; + string loadAdditionalCredits(); - bool enableCustomModCredits; - Texture2D *customModTexture; - int customModTextureX; - int customModTextureY; - int customModTextureW; - int customModTextureH; - float customModTextureAlpha; + bool enableCustomModCredits; + Texture2D *customModTexture; + int customModTextureX; + int customModTextureY; + int customModTextureW; + int customModTextureH; + float customModTextureAlpha; - GraphicLabel labelCustomModCredits; + GraphicLabel labelCustomModCredits; - public: - MenuStateAbout (Program * program, MainMenu * mainMenu); - virtual ~ MenuStateAbout (); + public: + MenuStateAbout(Program * program, MainMenu * mainMenu); + virtual ~MenuStateAbout(); - void mouseClick (int x, int y, MouseButton mouseButton); - void mouseMove (int x, int y, const MouseState * mouseState); - void render (); - virtual void keyDown (SDL_KeyboardEvent key); + void mouseClick(int x, int y, MouseButton mouseButton); + void mouseMove(int x, int y, const MouseState * mouseState); + void render(); + virtual void keyDown(SDL_KeyboardEvent key); - virtual void reloadUI (); - }; + virtual void reloadUI(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index 6d35720d5..36d33ae8b 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -45,9119 +45,8131 @@ #include "leak_dumper.h" using namespace - Shared::Util; +Shared::Util; using namespace - Shared::CompressionUtil; - -namespace Glest -{ - namespace Game - { - - static const int - MAX_PING_LAG_COUNT = 6; - static const double - REPROMPT_DOWNLOAD_SECONDS = 7; -//static const string ITEM_MISSING = "***missing***"; -// above replaced with Lang::getInstance().getString("DataMissing","",true) - const int - HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS = 2; - static const char * - HEADLESS_SAVED_GAME_FILENAME = "lastHeadlessGameSettings.mgg"; - - const int - mapPreviewTexture_X = 5; - const int - mapPreviewTexture_Y = 185; - const int - mapPreviewTexture_W = 150; - const int - mapPreviewTexture_H = 150; - - struct FormatString - { - void - operator () (string & s) - { - s = formatString (s); - } - }; - -// ===================================================== -// class MenuStateConnectedGame -// ===================================================== - - MenuStateConnectedGame::MenuStateConnectedGame (Program * program, MainMenu * mainMenu, JoinMenu joinMenuInfo, bool openNetworkSlots): - MenuState (program, mainMenu, "connected-game"), - modHttpServerThread (NULL) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - - containerName = "ClientConnectedGame"; - switchSetupRequestFlagType |= ssrft_NetworkPlayerName; - updateDataSynchDetailText = false; - launchingNewGame = false; - isfirstSwitchingMapMessage = true; - - this->zoomedMap = false; - this->render_mapPreviewTexture_X = mapPreviewTexture_X; - this->render_mapPreviewTexture_Y = mapPreviewTexture_Y; - this->render_mapPreviewTexture_W = mapPreviewTexture_W; - this->render_mapPreviewTexture_H = mapPreviewTexture_H; - - needToBroadcastServerSettings = false; - broadcastServerSettingsDelayTimer = 0; - lastGameSettingsReceivedCount = 0; - noReceiveTimer = time (NULL) - 100; // old but inititialized ( must be an "old" time ) - - soundConnectionCount = 0; - - this->factionVideo = NULL; - factionVideoSwitchedOffVolume = false; - currentTechName_factionPreview = ""; - currentFactionName_factionPreview = ""; - - ftpClientThread = NULL; - ftpMissingDataType = ftpmsg_MissingNone; - getMissingMapFromFTPServer = ""; - getMissingMapFromFTPServerLastPrompted = 0; - getMissingMapFromFTPServerInProgress = false; - getMissingTilesetFromFTPServer = ""; - getMissingTilesetFromFTPServerLastPrompted = 0; - getMissingTilesetFromFTPServerInProgress = false; - getMissingTechtreeFromFTPServer = ""; - getMissingTechtreeFromFTPServerLastPrompted = 0; - getMissingTechtreeFromFTPServerInProgress = false; - - getInProgressSavedGameFromFTPServer = ""; - getInProgressSavedGameFromFTPServerInProgress = false; - readyToJoinInProgressGame = false; - - lastCheckedCRCTilesetName = ""; - lastCheckedCRCTechtreeName = ""; - lastCheckedCRCMapName = ""; - lastCheckedCRCTilesetValue = 0; - lastCheckedCRCTechtreeValue = 0; - lastCheckedCRCMapValue = 0; - - mapPreviewTexture = NULL; - currentFactionLogo = ""; - factionTexture = NULL; - lastMissingMap = ""; - lastMissingTechtree = ""; - lastMissingTileSet = ""; - - activeInputLabel = NULL; - lastNetworkSendPing = 0; - pingCount = 0; - needToSetChangedGameSettings = false; - lastSetChangedGameSettings = time (NULL); - showFullConsole = false; - - - currentFactionName = ""; - currentMap = ""; - settingsReceivedFromServer = false; - initialSettingsReceivedFromServer = false; - - validOriginalGameSettings = false; - validDisplayedGamesettings = false; - - returnMenuInfo = joinMenuInfo; - Lang & lang = Lang::getInstance (); - - mainMessageBox.registerGraphicComponent (containerName, - "mainMessageBox"); - mainMessageBox.init (lang.getString ("Ok")); - mainMessageBox.setEnabled (false); - - ftpMessageBox.registerGraphicComponent (containerName, "ftpMessageBox"); - ftpMessageBox.init (lang.getString ("ModCenter"), - lang.getString ("GameHost")); - ftpMessageBox.addButton (lang.getString ("NoDownload")); - ftpMessageBox.setEnabled (false); - - NetworkManager & networkManager = NetworkManager::getInstance (); - Config & config = Config::getInstance (); - defaultPlayerName = - config.getString ("NetPlayerName", Socket::getHostName ().c_str ()); - enableFactionTexturePreview = config.getBool ("FactionPreview", "true"); - enableMapPreview = config.getBool ("MapPreview", "true"); - - enableScenarioTexturePreview = - Config::getInstance ().getBool ("EnableScenarioTexturePreview", - "true"); - scenarioLogoTexture = NULL; - previewLoadDelayTimer = time (NULL); - needToLoadTextures = true; - this->dirList = Config::getInstance ().getPathListForType (ptScenarios); - - vector < - string > - techtreesList = Config::getInstance ().getPathListForType (ptTechs); - techTree.reset (new TechTree (techtreesList)); - - vector < - string > - teamItems, controlItems, results, rMultiplier, playerStatuses; - - // Some of these values must also be changed to match those in - // menu_state_custom_game.cpp - int - labelOffset = 23; - int - setupPos = 605; - // mapHeadPos is the placement of the text "map", not the map itself - int mapHeadPos = 310; - int - mapPos = mapHeadPos - labelOffset; - int - aHeadPos = mapHeadPos - 90; - int - aPos = aHeadPos - labelOffset; - int - networkHeadPos = 700; - -//state - labelStatus.registerGraphicComponent (containerName, "labelStatus"); - labelStatus.init (30, networkHeadPos); - labelStatus.setText (""); - - labelInfo.registerGraphicComponent (containerName, "labelInfo"); - labelInfo.init (30, networkHeadPos + 30); - labelInfo.setText (""); - labelInfo.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelInfo.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - - labelWaitingForPlayers.registerGraphicComponent (containerName, - "labelInfo"); - labelWaitingForPlayers.init (30, 100); - labelWaitingForPlayers.setText (""); - labelWaitingForPlayers.setFont (CoreData::getInstance (). - getMenuFontBig ()); - labelWaitingForPlayers.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - labelWaitingForPlayers.setTextColor (Vec3f (1.0f, 1.0f, 0.f)); - - timerLabelFlash = time (NULL); - labelDataSynchInfo.registerGraphicComponent (containerName, - "labelDataSynchInfo"); - labelDataSynchInfo.init (30, networkHeadPos - 60); - labelDataSynchInfo.setText (""); - labelDataSynchInfo.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelDataSynchInfo.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - - int - xoffset = 90; - labelAllowTeamUnitSharing.registerGraphicComponent (containerName, - "labelAllowTeamUnitSharing"); - labelAllowTeamUnitSharing.init (xoffset + 410, 670, 80); - labelAllowTeamUnitSharing.setText (lang. - getString ("AllowTeamUnitSharing")); - labelAllowTeamUnitSharing.setVisible (true); - - checkBoxAllowTeamUnitSharing.registerGraphicComponent (containerName, - "checkBoxAllowTeamUnitSharing"); - checkBoxAllowTeamUnitSharing.init (xoffset + 612, 670); - checkBoxAllowTeamUnitSharing.setValue (false); - checkBoxAllowTeamUnitSharing.setVisible (true); - checkBoxAllowTeamUnitSharing.setEditable (false); - - labelAllowTeamResourceSharing.registerGraphicComponent (containerName, - "labelAllowTeamResourceSharing"); - labelAllowTeamResourceSharing.init (xoffset + 410, 640, 80); - labelAllowTeamResourceSharing.setText (lang. - getString - ("AllowTeamResourceSharing")); - labelAllowTeamResourceSharing.setVisible (true); - - checkBoxAllowTeamResourceSharing.registerGraphicComponent - (containerName, "checkBoxAllowTeamResourceSharing"); - checkBoxAllowTeamResourceSharing.init (xoffset + 612, 640); - checkBoxAllowTeamResourceSharing.setValue (false); - checkBoxAllowTeamResourceSharing.setVisible (true); - checkBoxAllowTeamResourceSharing.setEditable (false); - -// fog - o - war - xoffset = 65; - labelFogOfWar.registerGraphicComponent (containerName, "labelFogOfWar"); - labelFogOfWar.init (xoffset + 100, aHeadPos, 165); - labelFogOfWar.setText (lang.getString ("FogOfWar")); - - listBoxFogOfWar.registerGraphicComponent (containerName, - "listBoxFogOfWar"); - listBoxFogOfWar.init (xoffset + 100, aPos, 165); - listBoxFogOfWar.pushBackItem (lang.getString ("Enabled")); - listBoxFogOfWar.pushBackItem (lang.getString ("Explored")); - listBoxFogOfWar.pushBackItem (lang.getString ("Disabled")); - listBoxFogOfWar.setSelectedItemIndex (0); - listBoxFogOfWar.setEditable (false); - - labelAllowObservers.registerGraphicComponent (containerName, - "labelAllowObservers"); - labelAllowObservers.init (xoffset + 325, aHeadPos, 80); - labelAllowObservers.setText (lang.getString ("AllowObservers")); - - checkBoxAllowObservers.registerGraphicComponent (containerName, - "checkBoxAllowObservers"); - checkBoxAllowObservers.init (xoffset + 325, aPos); - checkBoxAllowObservers.setValue (checkBoxAllowObservers.getValue ()); - - checkBoxAllowObservers.setEditable (false); - - for (int i = 0; i < 45; ++i) - { - rMultiplier.push_back (floatToStr (0.5f + 0.1f * i, 1)); - } - - labelFallbackCpuMultiplier.registerGraphicComponent (containerName, - "labelFallbackCpuMultiplier"); - labelFallbackCpuMultiplier.init (xoffset + 500, aHeadPos, 80); - labelFallbackCpuMultiplier.setText (lang.getString - ("FallbackCpuMultiplier")); - - listBoxFallbackCpuMultiplier.registerGraphicComponent (containerName, - "listBoxFallbackCpuMultiplier"); - listBoxFallbackCpuMultiplier.init (xoffset + 500, aPos, 80); - listBoxFallbackCpuMultiplier.setItems (rMultiplier); - listBoxFallbackCpuMultiplier.setSelectedItem ("1.0"); - - -// Allow Switch Team Mode - labelEnableSwitchTeamMode.registerGraphicComponent (containerName, - "labelEnableSwitchTeamMode"); - labelEnableSwitchTeamMode.init (xoffset + 325, aHeadPos + 45, 80); - labelEnableSwitchTeamMode. - setText (lang.getString ("EnableSwitchTeamMode")); - - checkBoxEnableSwitchTeamMode.registerGraphicComponent (containerName, - "checkBoxEnableSwitchTeamMode"); - checkBoxEnableSwitchTeamMode.init (xoffset + 325, aPos + 45); - checkBoxEnableSwitchTeamMode.setValue (false); - checkBoxEnableSwitchTeamMode.setEditable (false); - - labelAISwitchTeamAcceptPercent.registerGraphicComponent (containerName, - "labelAISwitchTeamAcceptPercent"); - labelAISwitchTeamAcceptPercent.init (xoffset + 500, aHeadPos + 45, 80); - labelAISwitchTeamAcceptPercent.setText (lang.getString - ("AISwitchTeamAcceptPercent")); - - listBoxAISwitchTeamAcceptPercent.registerGraphicComponent - (containerName, "listBoxAISwitchTeamAcceptPercent"); - listBoxAISwitchTeamAcceptPercent.init (xoffset + 500, aPos + 45, 80); - for (int i = 0; i <= 100; i = i + 10) - { - listBoxAISwitchTeamAcceptPercent.pushBackItem (intToStr (i)); - } - listBoxAISwitchTeamAcceptPercent.setSelectedItem (intToStr (30)); - listBoxAISwitchTeamAcceptPercent.setEditable (false); - -//create - buttonCancelDownloads.registerGraphicComponent (containerName, - "buttonCancelDownloads"); - buttonCancelDownloads.init (xoffset + 620, 180, 150); - buttonCancelDownloads.setText (lang.getString ("CancelDownloads")); - -// Network Frame Period - xoffset = 65; -//map listBox - - xoffset = 65; -// MapFilter - labelMapFilter.registerGraphicComponent (containerName, - "labelMapFilter"); - labelMapFilter.init (xoffset + 325, mapHeadPos); - labelMapFilter.setText (lang.getString ("MapFilter")); - - listBoxMapFilter.registerGraphicComponent (containerName, - "listBoxMapFilter"); - listBoxMapFilter.init (xoffset + 325, mapPos, 80); - listBoxMapFilter.pushBackItem ("-"); - for (int i = 1; i < GameConstants::maxPlayers + 1; ++i) - { - listBoxMapFilter.pushBackItem (intToStr (i)); - } - listBoxMapFilter.setSelectedItemIndex (0); - listBoxMapFilter.setEditable (false); - - -// put them all in a set, to weed out duplicates (gbm & mgm with same name) -// will also ensure they are alphabetically listed (rather than how the OS provides them) - listBoxMap.registerGraphicComponent (containerName, "listBoxMap"); - listBoxMap.init (xoffset + 100, mapPos, 220); - listBoxMap.setEditable (false); - - labelMapInfo.registerGraphicComponent (containerName, "labelMapInfo"); - labelMapInfo.init (xoffset + 100, mapPos - labelOffset - 10, 200, 40); - labelMapInfo.setText ("?"); - - labelMap.registerGraphicComponent (containerName, "labelMap"); - labelMap.init (xoffset + 100, mapHeadPos); - labelMap.setText (lang.getString ("Map")); - -//tileset listBox - listBoxTileset.registerGraphicComponent (containerName, - "listBoxTileset"); - listBoxTileset.init (xoffset + 500, mapPos, 160); - listBoxTileset.setEditable (false); - - labelTileset.registerGraphicComponent (containerName, "labelTileset"); - labelTileset.init (xoffset + 500, mapHeadPos); - labelTileset.setText (lang.getString ("Tileset")); - - -//tech Tree listBox - listBoxTechTree.setEditable (false); - - listBoxTechTree.registerGraphicComponent (containerName, - "listBoxTechTree"); - listBoxTechTree.init (xoffset + 700, mapPos, 180); - - labelTechTree.registerGraphicComponent (containerName, "labelTechTree"); - labelTechTree.init (xoffset + 700, mapHeadPos); - labelTechTree.setText (lang.getString ("TechTree")); - - labelAllowNativeLanguageTechtree.registerGraphicComponent - (containerName, "labelAllowNativeLanguageTechtree"); - labelAllowNativeLanguageTechtree.init (xoffset + 700, aHeadPos + 45); - labelAllowNativeLanguageTechtree.setText (lang.getString - ("AllowNativeLanguageTechtree")); - - checkBoxAllowNativeLanguageTechtree.registerGraphicComponent - (containerName, "checkBoxAllowNativeLanguageTechtree"); - checkBoxAllowNativeLanguageTechtree.init (xoffset + 700, aPos + 45); - checkBoxAllowNativeLanguageTechtree.setValue (false); - checkBoxAllowNativeLanguageTechtree.setEditable (false); - checkBoxAllowNativeLanguageTechtree.setEnabled (false); - -// Network Scenario - int - scenarioX = xoffset + 700; - int - scenarioY = aPos; - labelScenario.registerGraphicComponent (containerName, "labelScenario"); - labelScenario.init (scenarioX, aHeadPos); - labelScenario.setText (lang.getString ("Scenario")); - listBoxScenario.registerGraphicComponent (containerName, - "listBoxScenario"); - listBoxScenario.init (scenarioX + 30, scenarioY, 190); - listBoxScenario.setEditable (false); - listBoxScenario.setEnabled (false); - checkBoxScenario.registerGraphicComponent (containerName, - "checkBoxScenario"); - checkBoxScenario.init (scenarioX, scenarioY); - checkBoxScenario.setValue (false); - checkBoxScenario.setEditable (false); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - xoffset = 5; - int - rowHeight = 27; - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - labelPlayers[i].registerGraphicComponent (containerName, - "labelPlayers" + - intToStr (i)); - labelPlayers[i].init (xoffset - 1, setupPos - 30 - i * rowHeight + 2); - labelPlayers[i]. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - labelPlayers[i]. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - labelPlayers[i].setEditable (false); - - labelPlayerStatus[i].registerGraphicComponent (containerName, - "labelPlayerStatus" + - intToStr (i)); - labelPlayerStatus[i].init (xoffset + 14, - setupPos - 30 - i * rowHeight + 2); - labelPlayerNames[i].registerGraphicComponent (containerName, - "labelPlayerNames" + - intToStr (i)); - labelPlayerNames[i].init (xoffset + 30, - setupPos - 30 - i * rowHeight); - - listBoxControls[i].registerGraphicComponent (containerName, - "listBoxControls" + - intToStr (i)); - listBoxControls[i].init (xoffset + 160, setupPos - 30 - i * rowHeight, - 174); - listBoxControls[i].setEditable (false); - - listBoxRMultiplier[i].registerGraphicComponent (containerName, - "listBoxRMultiplier" + - intToStr (i)); - listBoxRMultiplier[i].init (xoffset + 336, - setupPos - 30 - i * rowHeight, 70); - listBoxRMultiplier[i].setEditable (false); - - listBoxFactions[i].registerGraphicComponent (containerName, - "listBoxFactions" + - intToStr (i)); - listBoxFactions[i].init (xoffset + 411, setupPos - 30 - i * rowHeight, - 247); - listBoxFactions[i].setLeftControlled (true); - listBoxFactions[i].setEditable (false); - - listBoxTeams[i].registerGraphicComponent (containerName, - "listBoxTeams" + - intToStr (i)); - listBoxTeams[i].init (xoffset + 660, setupPos - 30 - i * rowHeight, - 60); - listBoxTeams[i].setEditable (false); - listBoxTeams[i].setLighted (true); - - labelNetStatus[i].registerGraphicComponent (containerName, - "labelNetStatus" + - intToStr (i)); - labelNetStatus[i].init (xoffset + 723, setupPos - 30 - i * rowHeight, - 60); - labelNetStatus[i]. - setFont (CoreData::getInstance ().getDisplayFontSmall ()); - labelNetStatus[i]. - setFont3D (CoreData::getInstance ().getDisplayFontSmall3D ()); - - grabSlotButton[i].registerGraphicComponent (containerName, - "grabSlotButton" + - intToStr (i)); - grabSlotButton[i].init (xoffset + 726, setupPos - 30 - i * rowHeight, - 35, rowHeight - 5); - grabSlotButton[i].setText (">"); - } - - labelControl.registerGraphicComponent (containerName, "labelControl"); - labelControl.init (xoffset + 160, setupPos, 50, GraphicListBox::defH, - true); - labelControl.setText (lang.getString ("Control")); - - labelRMultiplier.registerGraphicComponent (containerName, - "labelRMultiplier"); - labelRMultiplier.init (xoffset + 310, setupPos, 50, - GraphicListBox::defH, true); - - labelFaction.registerGraphicComponent (containerName, "labelFaction"); - labelFaction.init (xoffset + 411, setupPos, 50, GraphicListBox::defH, - true); - labelFaction.setText (lang.getString ("Faction")); - - labelTeam.registerGraphicComponent (containerName, "labelTeam"); - labelTeam.init (xoffset + 660, setupPos, 50, GraphicListBox::defH, - true); - labelTeam.setText (lang.getString ("Team")); - - labelControl.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelControl.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - labelFaction.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelFaction.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - labelTeam.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelTeam.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - -//texts - buttonDisconnect.setText (lang.getString ("Return")); - - controlItems.push_back (lang.getString ("Closed")); - controlItems.push_back (lang.getString ("CpuEasy")); - controlItems.push_back (lang.getString ("Cpu")); - controlItems.push_back (lang.getString ("CpuUltra")); - controlItems.push_back (lang.getString ("CpuZeta")); - controlItems.push_back (lang.getString ("Network")); - controlItems.push_back (lang.getString ("NetworkUnassigned")); - controlItems.push_back (lang.getString ("Human")); - - - if (config.getBool ("EnableNetworkCpu", "false") == true) - { - controlItems.push_back (lang.getString ("NetworkCpuEasy")); - controlItems.push_back (lang.getString ("NetworkCpu")); - controlItems.push_back (lang.getString ("NetworkCpuUltra")); - controlItems.push_back (lang.getString ("NetworkCpuZeta")); - } - - for (int i = 1; i <= GameConstants::maxPlayers; ++i) - { - teamItems.push_back (intToStr (i)); - } - for (int i = GameConstants::maxPlayers + 1; - i <= GameConstants::maxPlayers + GameConstants::specialFactions; - ++i) - { - teamItems.push_back (intToStr (i)); - } - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - labelPlayerStatus[i].setText (""); - labelPlayerStatus[i].setTexture (NULL); - labelPlayerStatus[i].setH (16); - labelPlayerStatus[i].setW (12); - - labelPlayers[i].setText (intToStr (i + 1)); - labelPlayerNames[i].setText (""); - labelPlayerNames[i].setMaxEditWidth (16); - labelPlayerNames[i].setMaxEditRenderWidth (127); - - listBoxTeams[i].setItems (teamItems); - listBoxTeams[i].setSelectedItemIndex (i); - listBoxControls[i].setItems (controlItems); - listBoxRMultiplier[i].setItems (rMultiplier); - listBoxRMultiplier[i].setSelectedItem ("1.0"); - - labelNetStatus[i].setText ("V"); - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//init controllers - listBoxControls[0].setSelectedItemIndex (ctHuman); - - -//map listBox -// put them all in a set, to weed out duplicates (gbm & mgm with same name) -// will also ensure they are alphabetically listed (rather than how the OS provides them) - setupMapList (""); - listBoxMap.setItems (formattedPlayerSortedMaps[0]); - - int - buttonx = 165; - int - buttony = 150; - - listBoxPlayerStatus.registerGraphicComponent (containerName, - "listBoxPlayerStatus"); - listBoxPlayerStatus.init (buttonx, buttony, 165); - listBoxPlayerStatus.setTextColor (Vec3f (1.0f, 0.f, 0.f)); - listBoxPlayerStatus.setLighted (true); - playerStatuses.push_back (lang.getString ("PlayerStatusSetup")); - playerStatuses.push_back (lang.getString ("PlayerStatusBeRightBack")); - playerStatuses.push_back (lang.getString ("PlayerStatusReady")); - listBoxPlayerStatus.setItems (playerStatuses); - buttonx += 180; - - buttonDisconnect.registerGraphicComponent (containerName, - "buttonDisconnect"); - buttonDisconnect.init (buttonx, buttony, 125); - buttonx += 132; - - buttonRestoreLastSettings.registerGraphicComponent (containerName, - "buttonRestoreLastSettings"); - buttonRestoreLastSettings.init (buttonx, buttony, 240); - buttonRestoreLastSettings.setText (lang.getString - ("ReloadLastGameSettings")); - buttonx += 247; - - buttonPlayNow.registerGraphicComponent (containerName, "buttonPlayNow"); - buttonPlayNow.init (buttonx, buttony, 125); - buttonPlayNow.setText (lang.getString ("PlayNow")); - buttonPlayNow.setVisible (false); - - -// write hint to console: - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - - console.addLine (lang.getString ("ToSwitchOffMusicPress") + " - \"" + - configKeys.getString ("ToggleMusic") + "\""); - chatManager.init (&console, -1, true); - - GraphicComponent::applyAllCustomProperties (containerName); - -//tileset listBox - setupTilesetList (""); - - int - initialTechSelection = setupTechList ("", true); - listBoxTechTree.setSelectedItemIndex (initialTechSelection); - - -//scenario listbox - vector < string > resultsScenarios; - findDirs (dirList, resultsScenarios); -// Filter out only scenarios with no network slots - for (int i = 0; i < (int) resultsScenarios.size (); ++i) - { - string scenario = resultsScenarios[i]; - string file = Scenario::getScenarioPath (dirList, scenario); - - try - { - if (file != "") - { - bool isTutorial = Scenario::isGameTutorial (file); - Scenario::loadScenarioInfo (file, &scenarioInfo, isTutorial); - - bool isNetworkScenario = false; - for (unsigned int j = 0; - isNetworkScenario == false - && j < (unsigned int) GameConstants::maxPlayers; ++j) - { - if (scenarioInfo.factionControls[j] == ctNetwork) - { - isNetworkScenario = true; - } - } - if (isNetworkScenario == true) - { - scenarioFiles.push_back (scenario); - } - } - } - catch (const std::exception & ex) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s %d]\nError loading scenario [%s]:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, scenario.c_str (), ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - showMessageBox (szBuf, "Error", false); -//throw megaglest_runtime_error(szBuf); - } - } - resultsScenarios.clear (); - for (int i = 0; i < (int) scenarioFiles.size (); ++i) - { - resultsScenarios.push_back (formatString (scenarioFiles[i])); - } - listBoxScenario.setItems (resultsScenarios); - checkBoxScenario.setEnabled (false); - - if (config.getBool ("EnableFTPXfer", "true") == true) - { - ClientInterface * - clientInterface = networkManager.getClientInterface (); - string serverUrl = clientInterface->getServerIpAddress (); - int - portNumber = clientInterface->getServerFTPPort (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] Using FTP port #: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, portNumber); - - vector < string > mapPathList = config.getPathListForType (ptMaps); - std::pair < string, string > mapsPath; - if (mapPathList.empty () == false) - { - mapsPath.first = mapPathList[0]; - } - if (mapPathList.size () > 1) - { - mapsPath.second = mapPathList[1]; - } - std::pair < string, string > tilesetsPath; - vector < string > tilesetsList = - Config::getInstance ().getPathListForType (ptTilesets); - if (tilesetsList.empty () == false) - { - tilesetsPath.first = tilesetsList[0]; - if (tilesetsList.size () > 1) - { - tilesetsPath.second = tilesetsList[1]; - } - } - - std::pair < string, string > techtreesPath; - if (techtreesList.empty () == false) - { - techtreesPath.first = techtreesList[0]; - if (techtreesList.size () > 1) - { - techtreesPath.second = techtreesList[1]; - } - } - - std::pair < string, string > scenariosPath; - vector < string > scenariosList = - Config::getInstance ().getPathListForType (ptScenarios); - if (scenariosList.empty () == false) - { - scenariosPath.first = scenariosList[0]; - if (scenariosList.size () > 1) - { - scenariosPath.second = scenariosList[1]; - } - } - - string - fileArchiveExtension = - config.getString ("FileArchiveExtension", ""); - string - fileArchiveExtractCommand = - config.getString ("FileArchiveExtractCommand", ""); - string - fileArchiveExtractCommandParameters = - config.getString ("FileArchiveExtractCommandParameters", ""); - int32 - fileArchiveExtractCommandSuccessResult = - config.getInt ("FileArchiveExtractCommandSuccessResult", "0"); - -// Get path to temp files - string tempFilePath = "temp/"; - if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) != - "") - { - tempFilePath = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - tempFilePath; - } - else - { - string userData = config.getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - tempFilePath = userData + tempFilePath; - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Temp files path [%s]\n", tempFilePath.c_str ()); - - ftpClientThread = new FTPClientThread (portNumber, serverUrl, - mapsPath, tilesetsPath, - techtreesPath, scenariosPath, - this, fileArchiveExtension, - fileArchiveExtractCommand, - fileArchiveExtractCommandParameters, - fileArchiveExtractCommandSuccessResult, - tempFilePath); - ftpClientThread->start (); - } -// Start http meta data thread - static - string - mutexOwnerId = - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - string ("_") + intToStr (__LINE__); - modHttpServerThread = new SimpleTaskThread (this, 0, 200); - modHttpServerThread->setUniqueID (mutexOwnerId); - modHttpServerThread->start (); - - ClientInterface * - clientInterface = networkManager.getClientInterface (); - if (clientInterface != NULL - && clientInterface->getJoinGameInProgress () == true) - { - listBoxPlayerStatus.setVisible (false); - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("JoinPlayerToCurrentGameWelcome", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString ("JoinPlayerToCurrentGameWelcome", - languageList[i]).c_str (), - getHumanPlayerName ().c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Player: %s has connected to the game and would like to join.", - getHumanPlayerName ().c_str ()); - } - bool localEcho = lang.isLanguageLocal (languageList[i]); - clientInterface->sendTextMessage (szMsg, -1, localEcho, - languageList[i]); - } - sleep (1); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - // I moved this block from loadMapInfo(), and modified it. It was - // setting the slots visible based on the number of hardMaxPlayers - // every time a new map was loaded. Trying it here instead, so the - // labels are made visible only once. Below, we'll be disabling slots - // that exceed hardMaxPlayers - for (int i = 0; i < GameConstants::maxPlayers; i++) - { - labelPlayers[i].setVisible (true); - labelPlayerNames[i].setVisible (true); - listBoxControls[i].setVisible (true); - listBoxFactions[i].setVisible (true); - listBoxTeams[i].setVisible (true); - labelNetStatus[i].setVisible (true); - } - } - - void - MenuStateConnectedGame::reloadUI () - { - Config & config = Config::getInstance (); - Lang & lang = Lang::getInstance (); - - console.resetFonts (); - mainMessageBox.init (lang.getString ("Ok")); - ftpMessageBox.init (lang.getString ("ModCenter"), - lang.getString ("GameHost")); - ftpMessageBox.addButton (lang.getString ("NoDownload")); - - labelInfo.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelInfo.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - - labelWaitingForPlayers. - setFont (CoreData::getInstance ().getMenuFontBig ()); - labelWaitingForPlayers. - setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - - labelDataSynchInfo.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelDataSynchInfo. - setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - - buttonCancelDownloads.setText (lang.getString ("CancelDownloads")); - - labelFogOfWar.setText (lang.getString ("FogOfWar")); - - vector < string > fowItems; - fowItems.push_back (lang.getString ("Enabled")); - fowItems.push_back (lang.getString ("Explored")); - fowItems.push_back (lang.getString ("Disabled")); - listBoxFogOfWar.setItems (fowItems); - - labelAllowObservers.setText (lang.getString ("AllowObservers")); - labelFallbackCpuMultiplier.setText (lang.getString - ("FallbackCpuMultiplier")); - - labelEnableSwitchTeamMode. - setText (lang.getString ("EnableSwitchTeamMode")); - - labelAllowTeamUnitSharing. - setText (lang.getString ("AllowTeamUnitSharing")); - labelAllowTeamResourceSharing. - setText (lang.getString ("AllowTeamResourceSharing")); - - labelAISwitchTeamAcceptPercent.setText (lang.getString - ("AISwitchTeamAcceptPercent")); - - vector < string > aiswitchteamModeItems; - for (int i = 0; i <= 100; i = i + 10) - { - aiswitchteamModeItems.push_back (intToStr (i)); - } - listBoxAISwitchTeamAcceptPercent.setItems (aiswitchteamModeItems); - - vector < string > rMultiplier; - for (int i = 0; i < 45; ++i) - { - rMultiplier.push_back (floatToStr (0.5f + 0.1f * i, 1)); - } - listBoxFallbackCpuMultiplier.setItems (rMultiplier); - - labelMap.setText (lang.getString ("Map")); - - labelMapFilter.setText (lang.getString ("MapFilter")); - - labelTileset.setText (lang.getString ("Tileset")); - - labelTechTree.setText (lang.getString ("TechTree")); - - vector < string > playerstatusItems; - playerstatusItems.push_back (lang.getString ("PlayerStatusSetup")); - playerstatusItems. - push_back (lang.getString ("PlayerStatusBeRightBack")); - playerstatusItems.push_back (lang.getString ("PlayerStatusReady")); - listBoxPlayerStatus.setItems (playerstatusItems); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - labelControl.setText (lang.getString ("Control")); - - labelFaction.setText (lang.getString ("Faction")); - - labelTeam.setText (lang.getString ("Team")); - - labelControl.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelControl.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - labelFaction.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelFaction.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - labelTeam.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelTeam.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - -//texts - buttonDisconnect.setText (lang.getString ("Return")); - - vector < string > controlItems; - controlItems.push_back (lang.getString ("Closed")); - controlItems.push_back (lang.getString ("CpuEasy")); - controlItems.push_back (lang.getString ("Cpu")); - controlItems.push_back (lang.getString ("CpuUltra")); - controlItems.push_back (lang.getString ("CpuZeta")); - controlItems.push_back (lang.getString ("Network")); - controlItems.push_back (lang.getString ("NetworkUnassigned")); - controlItems.push_back (lang.getString ("Human")); - - if (config.getBool ("EnableNetworkCpu", "false") == true) - { - controlItems.push_back (lang.getString ("NetworkCpuEasy")); - controlItems.push_back (lang.getString ("NetworkCpu")); - controlItems.push_back (lang.getString ("NetworkCpuUltra")); - controlItems.push_back (lang.getString ("NetworkCpuZeta")); - } - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - labelPlayers[i].setText (intToStr (i + 1)); - listBoxControls[i].setItems (controlItems); - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - labelScenario.setText (lang.getString ("Scenario")); - - labelAllowNativeLanguageTechtree.setText (lang.getString - ("AllowNativeLanguageTechtree")); - - buttonPlayNow.setText (lang.getString ("PlayNow")); - buttonRestoreLastSettings.setText (lang.getString - ("ReloadLastGameSettings")); - - chatManager.init (&console, -1, true); - - GraphicComponent::reloadFontsForRegisterGraphicComponents - (containerName); - } - - void - MenuStateConnectedGame::disconnectFromServer () - { - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (false); - if (clientInterface != NULL) - { - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - - soundRenderer.playFx (coreData.getClickSoundA ()); - if (clientInterface->getSocket () != NULL) - { - if (clientInterface->isConnected () == true) - { - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - string sQuitText = lang.getString ("QuitGame", languageList[i]); - clientInterface->sendTextMessage (sQuitText, -1, false, - languageList[i]); - } - sleep (1); - - } - clientInterface->close (); - } - clientInterface->reset (); - } - currentFactionName = ""; - currentMap = ""; - } - - MenuStateConnectedGame::~MenuStateConnectedGame () - { - if (launchingNewGame == false) - { - disconnectFromServer (); - NetworkManager & networkManager = NetworkManager::getInstance (); - networkManager.end (); - } - - if (modHttpServerThread != NULL) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - modHttpServerThread->setSimpleTaskInterfaceValid (false); - modHttpServerThread->signalQuit (); - modHttpServerThread->setThreadOwnerValid (false); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - if (modHttpServerThread->canShutdown (true) == true - && modHttpServerThread->shutdownAndWait () == true) - { - delete modHttpServerThread; - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - modHttpServerThread = NULL; - } - - if (ftpClientThread != NULL) - { - ftpClientThread->setCallBackObject (NULL); - ftpClientThread->signalQuit (); - sleep (0); - if (ftpClientThread->canShutdown (true) == true && - ftpClientThread->shutdownAndWait () == true) - { - delete ftpClientThread; - } - else - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s %d] Error cannot shutdown ftpClientThread\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("%s", szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - } - - ftpClientThread = NULL; - } - - cleanupMapPreviewTexture (); - - if (factionVideo != NULL) - { - factionVideo->closePlayer (); - delete factionVideo; - factionVideo = NULL; - } - } - - string MenuStateConnectedGame::refreshTilesetModInfo (string tilesetInfo) - { - std::vector < std::string > tilesetInfoList; - Tokenize (tilesetInfo, tilesetInfoList, "|"); - if (tilesetInfoList.size () >= 5) - { - Config & config = Config::getInstance (); - ModInfo modinfo; - modinfo.name = tilesetInfoList[0]; - modinfo.crc = tilesetInfoList[1]; - modinfo.description = tilesetInfoList[2]; - modinfo.url = tilesetInfoList[3]; - modinfo.imageUrl = tilesetInfoList[4]; - modinfo.type = mt_Tileset; - - string - itemPath = - config.getPathListForType (ptTilesets, - "")[1] + "/" + modinfo.name + - string ("/*"); - if (itemPath.empty () == false) - { - bool - forceRefresh = - (mapCRCUpdateList.find (itemPath) == mapCRCUpdateList.end ()); - uint32 - crc = - getFolderTreeContentsCheckSumRecursively (itemPath, ".xml", NULL, - forceRefresh); - if (crc == 0) - { - itemPath = - config.getPathListForType (ptTilesets, - "")[0] + "/" + modinfo.name + - string ("/*"); - if (itemPath.empty () == false) - { - forceRefresh = - (mapCRCUpdateList.find (itemPath) == mapCRCUpdateList.end ()); - crc = - getFolderTreeContentsCheckSumRecursively (itemPath, ".xml", - NULL, forceRefresh); - } - } - modinfo.localCRC = uIntToStr (crc); -//printf("itemPath='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); - -//printf("#1 refreshTilesetModInfo name [%s] modInfo.crc [%s] modInfo.localCRC [%s]\n",modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str()); - } - else - { - modinfo.localCRC = ""; - -//printf("#2 refreshTilesetModInfo name [%s] modInfo.crc [%s] modInfo.localCRC [%s]\n",modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str()); - } - - tilesetCacheList[modinfo.name] = modinfo; - return modinfo.name; - } - return ""; - } - - string MenuStateConnectedGame::refreshTechModInfo (string techInfo) - { - std::vector < std::string > techInfoList; - Tokenize (techInfo, techInfoList, "|"); - if (techInfoList.size () >= 6) - { - Config & config = Config::getInstance (); - ModInfo modinfo; - modinfo.name = techInfoList[0]; - modinfo.count = techInfoList[1]; - modinfo.crc = techInfoList[2]; - modinfo.description = techInfoList[3]; - modinfo.url = techInfoList[4]; - modinfo.imageUrl = techInfoList[5]; - modinfo.type = mt_Techtree; - - string - itemPath = - config.getPathListForType (ptTechs, - "")[1] + "/" + modinfo.name + - string ("/*"); - if (itemPath.empty () == false) - { - bool - forceRefresh = - (mapCRCUpdateList.find (itemPath) == mapCRCUpdateList.end ()); - uint32 - crc = - getFolderTreeContentsCheckSumRecursively (itemPath, ".xml", NULL, - forceRefresh); - if (crc == 0) - { - itemPath = - config.getPathListForType (ptTechs, - "")[0] + "/" + modinfo.name + - string ("/*"); - if (itemPath.empty () == false) - { - forceRefresh = - (mapCRCUpdateList.find (itemPath) == mapCRCUpdateList.end ()); - crc = - getFolderTreeContentsCheckSumRecursively (itemPath, ".xml", - NULL, forceRefresh); - } - } - modinfo.localCRC = uIntToStr (crc); -//printf("itemPath='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); - } - else - { - modinfo.localCRC = ""; - } - techCacheList[modinfo.name] = modinfo; - return modinfo.name; - } - return ""; - } - - string MenuStateConnectedGame::getMapCRC (string mapName) - { - Config & config = Config::getInstance (); - vector < string > mappaths = config.getPathListForType (ptMaps, ""); - string result = ""; - if (mappaths.empty () == false) - { - Checksum checksum; - string itemPath = mappaths[1] + "/" + mapName; - if (fileExists (itemPath)) - { - checksum.addFile (itemPath); - uint32 crc = checksum.getSum (); - result = uIntToStr (crc); -//printf("itemPath='%s' modinfo.name='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); - } - else - { - itemPath = mappaths[0] + "/" + mapName; - if (fileExists (itemPath)) - { - checksum.addFile (itemPath); - uint32 crc = checksum.getSum (); - result = uIntToStr (crc); -//printf("itemPath='%s' modinfo.name='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); - } - else - { - result = ""; - } - } - } - else - { - result = ""; - } - return result; - } - - string MenuStateConnectedGame::refreshMapModInfo (string mapInfo) - { - std::vector < std::string > mapInfoList; - Tokenize (mapInfo, mapInfoList, "|"); - if (mapInfoList.size () >= 6) - { -//Config &config = Config::getInstance(); - ModInfo modinfo; - modinfo.name = mapInfoList[0]; - modinfo.count = mapInfoList[1]; - modinfo.crc = mapInfoList[2]; - modinfo.description = mapInfoList[3]; - modinfo.url = mapInfoList[4]; - modinfo.imageUrl = mapInfoList[5]; - modinfo.type = mt_Map; - modinfo.localCRC = getMapCRC (modinfo.name); - mapCacheList[modinfo.name] = modinfo; - return modinfo.name; - } - return ""; - } - - void - MenuStateConnectedGame::simpleTask (BaseThread * callingThread, - void *userdata) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - static - string - mutexOwnerId = string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexThreadOwner (callingThread->getMutexThreadOwnerValid (), - mutexOwnerId); - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - callingThread->getMutexThreadOwnerValid ()->setOwnerId (mutexOwnerId); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - Lang & lang = Lang::getInstance (); - Config & config = Config::getInstance (); - - std::string techsMetaData = ""; - std::string tilesetsMetaData = ""; - std::string mapsMetaData = ""; - std::string scenariosMetaData = ""; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - if (config.getString ("Masterserver", "") != "") - { - string baseURL = config.getString ("Masterserver"); - if (baseURL != "") - { - endPathWithSlash (baseURL, false); - } - string - phpVersionParam = - config.getString ("phpVersionParam", "?version=0.1"); - string - gameVersion = - "&glestVersion=" + SystemFlags::escapeURL (glestVersionString); - string - playerUUID = - "&uuid=" + - SystemFlags::escapeURL (config.getString ("PlayerId", "")); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line %d] About to call first http url, base [%s]..\n", - __FILE__, __FUNCTION__, __LINE__, baseURL.c_str ()); - - CURL * - handle = SystemFlags::initHTTP (); - CURLcode curlResult = CURLE_OK; - techsMetaData = - SystemFlags::getHTTP (baseURL + "showTechsForGlest.php" + - phpVersionParam + gameVersion + playerUUID, - handle, -1, &curlResult); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("techsMetaData [%s] curlResult = %d\n", - techsMetaData.c_str (), curlResult); - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - if (curlResult != CURLE_OK) - { - string curlError = curl_easy_strerror (curlResult); - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModErrorGettingServerData").c_str (), - curlError.c_str ()); - console.addLine (string ("#1 ") + szBuf, true); - } - - if (curlResult == CURLE_OK || - (curlResult != CURLE_COULDNT_RESOLVE_HOST && - curlResult != CURLE_COULDNT_CONNECT)) - { - - tilesetsMetaData = - SystemFlags::getHTTP (baseURL + "showTilesetsForGlest.php" + - phpVersionParam + gameVersion, handle, -1, - &curlResult); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("tilesetsMetaData [%s]\n", tilesetsMetaData.c_str ()); - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - if (curlResult != CURLE_OK) - { - string curlError = curl_easy_strerror (curlResult); - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModErrorGettingServerData").c_str (), - curlError.c_str ()); - console.addLine (string ("#2 ") + szBuf, true); - } - - mapsMetaData = - SystemFlags::getHTTP (baseURL + "showMapsForGlest.php" + - phpVersionParam + gameVersion, handle, -1, - &curlResult); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("mapsMetaData [%s]\n", mapsMetaData.c_str ()); - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - if (curlResult != CURLE_OK) - { - string curlError = curl_easy_strerror (curlResult); - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModErrorGettingServerData").c_str (), - curlError.c_str ()); - console.addLine (string ("#3 ") + szBuf, true); - } - - scenariosMetaData = - SystemFlags::getHTTP (baseURL + "showScenariosForGlest.php" + - phpVersionParam + gameVersion, handle, -1, - &curlResult); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("scenariosMetaData [%s]\n", scenariosMetaData.c_str ()); - - if (curlResult != CURLE_OK) - { - string curlError = curl_easy_strerror (curlResult); - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModErrorGettingServerData").c_str (), - curlError.c_str ()); - console.addLine (string ("#4 ") + szBuf, true); - } - } - SystemFlags::cleanupHTTP (&handle); - } - else - { - console.addLine (lang.getString ("MasterServerMissing"), true); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - MutexSafeWrapper - safeMutex (callingThread->getMutexThreadObjectAccessor (), - string (__FILE__) + "_" + intToStr (__LINE__)); - tilesetListRemote.clear (); - Tokenize (tilesetsMetaData, tilesetListRemote, "\n"); - safeMutex.ReleaseLock (true); - - for (unsigned int i = 0; i < tilesetListRemote.size (); i++) - { - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - safeMutex.Lock (); - string result = refreshTilesetModInfo (tilesetListRemote[i]); - safeMutex.ReleaseLock (true); - } - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - safeMutex.Lock (); - techListRemote.clear (); - Tokenize (techsMetaData, techListRemote, "\n"); - safeMutex.ReleaseLock (true); - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - for (unsigned int i = 0; i < techListRemote.size (); i++) - { - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - safeMutex.Lock (); - string result = refreshTechModInfo (techListRemote[i]); - safeMutex.ReleaseLock (true); - } - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - safeMutex.Lock (); - mapListRemote.clear (); - Tokenize (mapsMetaData, mapListRemote, "\n"); - safeMutex.ReleaseLock (true); - - for (unsigned int i = 0; i < mapListRemote.size (); i++) - { - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - safeMutex.Lock (); - string result = refreshMapModInfo (mapListRemote[i]); - safeMutex.ReleaseLock (true); - } - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - if (modHttpServerThread != NULL) - { - modHttpServerThread->signalQuit (); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - } - - void - MenuStateConnectedGame::mouseClick (int x, int y, MouseButton mouseButton) - { - - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - Lang & lang = Lang::getInstance (); - - string advanceToItemStartingWith = ""; - if (mainMessageBox.getEnabled () == false) - { - if (::Shared::Platform::Window::isKeyStateModPressed (KMOD_SHIFT) == - true) - { - wchar_t - lastKey =::Shared::Platform::Window::extractLastKeyPressed (); -//printf("lastKey = %d [%c]\n",lastKey,lastKey); - advanceToItemStartingWith = lastKey; - } - } - - if (mapPreviewTexture != NULL) - { -// printf("X: %d Y: %d [%d, %d, %d, %d]\n", -// x, y, -// this->render_mapPreviewTexture_X, this->render_mapPreviewTexture_X + this->render_mapPreviewTexture_W, -// this->render_mapPreviewTexture_Y, this->render_mapPreviewTexture_Y + this->render_mapPreviewTexture_H); - - if (x >= this->render_mapPreviewTexture_X - && x <= - this->render_mapPreviewTexture_X + - this->render_mapPreviewTexture_W - && y >= this->render_mapPreviewTexture_Y - && y <= - this->render_mapPreviewTexture_Y + - this->render_mapPreviewTexture_H) - { - - if (this->render_mapPreviewTexture_X == mapPreviewTexture_X && - this->render_mapPreviewTexture_Y == mapPreviewTexture_Y && - this->render_mapPreviewTexture_W == mapPreviewTexture_W && - this->render_mapPreviewTexture_H == mapPreviewTexture_H) - { - - const - Metrics & - metrics = Metrics::getInstance (); - - this->render_mapPreviewTexture_X = 0; - this->render_mapPreviewTexture_Y = 0; - this->render_mapPreviewTexture_W = metrics.getVirtualW (); - this->render_mapPreviewTexture_H = metrics.getVirtualH (); - this->zoomedMap = true; - - cleanupMapPreviewTexture (); - } - else - { - this->render_mapPreviewTexture_X = mapPreviewTexture_X; - this->render_mapPreviewTexture_Y = mapPreviewTexture_Y; - this->render_mapPreviewTexture_W = mapPreviewTexture_W; - this->render_mapPreviewTexture_H = mapPreviewTexture_H; - this->zoomedMap = false; - - cleanupMapPreviewTexture (); - } - return; - } - if (this->zoomedMap == true) - { - return; - } - } - - if (mainMessageBox.getEnabled ()) - { - int - button = 0; - if (mainMessageBox.mouseClick (x, y, button)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - if (button == 0) - { - mainMessageBox.setEnabled (false); - } - } - } - else if (ftpMessageBox.getEnabled ()) - { - int - button = 0; - if (ftpMessageBox.mouseClick (x, y, button)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - ftpMessageBox.setEnabled (false); - - if (button == 0 - || (button == 1 && ftpMessageBox.getButtonCount () == 3)) - { - if (ftpMissingDataType == ftpmsg_MissingMap) - { - getMissingMapFromFTPServerInProgress = true; - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingMapNowDownloading", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString ("DataMissingMapNowDownloading", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), - getMissingMapFromFTPServer.c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Player: %s is attempting to download the map: %s", - getHumanPlayerName ().c_str (), - getMissingMapFromFTPServer.c_str ()); - } - bool localEcho = lang.isLanguageLocal (languageList[i]); - clientInterface->sendTextMessage (szMsg, -1, localEcho, - languageList[i]); - } - - if (ftpClientThread != NULL) - { - if (button == 0 && ftpMessageBox.getButtonCount () == 3) - { - string mapName = getMissingMapFromFTPServer; - - MutexSafeWrapper - safeMutexThread ((modHttpServerThread != - NULL ? - modHttpServerThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - string mapURL = mapCacheList[mapName].url; - safeMutexThread.ReleaseLock (); - - if (ftpClientThread != NULL) - ftpClientThread->addMapToRequests (mapName, mapURL); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? - ftpClientThread->getProgressMutex - () : NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - fileFTPProgressList[getMissingMapFromFTPServer] = - pair < int, - string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - } - else - { - ftpClientThread->addMapToRequests - (getMissingMapFromFTPServer); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? - ftpClientThread->getProgressMutex - () : NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - fileFTPProgressList[getMissingMapFromFTPServer] = - pair < int, - string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - } - } - } - else if (ftpMissingDataType == ftpmsg_MissingTileset) - { - getMissingTilesetFromFTPServerInProgress = true; - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingTilesetNowDownloading", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString - ("DataMissingTilesetNowDownloading", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), - getMissingTilesetFromFTPServer.c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Player: %s is attempting to download the tileset: %s", - getHumanPlayerName ().c_str (), - getMissingTilesetFromFTPServer.c_str ()); - } - bool localEcho = lang.isLanguageLocal (languageList[i]); - clientInterface->sendTextMessage (szMsg, -1, localEcho, - languageList[i]); - } - - if (ftpClientThread != NULL) - { - if (button == 0 && ftpMessageBox.getButtonCount () == 3) - { - string tilesetName = getMissingTilesetFromFTPServer; - - MutexSafeWrapper - safeMutexThread ((modHttpServerThread != - NULL ? - modHttpServerThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - string tilesetURL = tilesetCacheList[tilesetName].url; - safeMutexThread.ReleaseLock (); - - if (ftpClientThread != NULL) - ftpClientThread->addTilesetToRequests (tilesetName, - tilesetURL); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? - ftpClientThread->getProgressMutex - () : NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - fileFTPProgressList[getMissingTilesetFromFTPServer] = - pair < int, - string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - } - else - { - ftpClientThread->addTilesetToRequests - (getMissingTilesetFromFTPServer); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? - ftpClientThread->getProgressMutex - () : NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - fileFTPProgressList[getMissingTilesetFromFTPServer] = - pair < int, - string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - } - } - } - else if (ftpMissingDataType == ftpmsg_MissingTechtree) - { - getMissingTechtreeFromFTPServerInProgress = true; - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingTechtreeNowDownloading", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString - ("DataMissingTechtreeNowDownloading", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), - getMissingTechtreeFromFTPServer.c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Player: %s is attempting to download the techtree: %s", - getHumanPlayerName ().c_str (), - getMissingTechtreeFromFTPServer.c_str ()); - } - bool localEcho = lang.isLanguageLocal (languageList[i]); - clientInterface->sendTextMessage (szMsg, -1, localEcho, - languageList[i]); - } - - if (ftpClientThread != NULL) - { - if (button == 0 && ftpMessageBox.getButtonCount () == 3) - { - string techName = getMissingTechtreeFromFTPServer; - - MutexSafeWrapper - safeMutexThread ((modHttpServerThread != - NULL ? - modHttpServerThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - string techURL = techCacheList[techName].url; - safeMutexThread.ReleaseLock (); - - if (ftpClientThread != NULL) - ftpClientThread->addTechtreeToRequests (techName, - techURL); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? - ftpClientThread->getProgressMutex - () : NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - fileFTPProgressList[getMissingTechtreeFromFTPServer] = - pair < int, - string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - } - else - { - ftpClientThread->addTechtreeToRequests - (getMissingTechtreeFromFTPServer); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? - ftpClientThread->getProgressMutex - () : NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - fileFTPProgressList[getMissingTechtreeFromFTPServer] = - pair < int, - string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - } - } - } - } - } - } - else if (buttonCancelDownloads.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - - if (ftpClientThread != NULL && fileFTPProgressList.empty () == false) - { - - ftpClientThread->setCallBackObject (NULL); - ftpClientThread->signalQuit (); - sleep (0); - if (ftpClientThread->canShutdown (true) == true && - ftpClientThread->shutdownAndWait () == true) - { - delete ftpClientThread; - } - else - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s %d] Error cannot shutdown ftpClientThread\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("%s", szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", - szBuf); - } - ftpClientThread = NULL; - - fileFTPProgressList.clear (); - getMissingMapFromFTPServerInProgress = false; - getMissingTilesetFromFTPServerInProgress = false; - getMissingTechtreeFromFTPServerInProgress = false; - getMissingMapFromFTPServer = ""; - getMissingTilesetFromFTPServer = ""; - getMissingTechtreeFromFTPServer = ""; - getMissingMapFromFTPServerLastPrompted = 0; - getMissingTilesetFromFTPServerLastPrompted = 0; - getMissingTechtreeFromFTPServerLastPrompted = 0; - - ClientInterface * - clientInterface = networkManager.getClientInterface (); - if (clientInterface == NULL) - { - throw megaglest_runtime_error ("clientInterface == NULL"); - } - if (getInProgressSavedGameFromFTPServerInProgress == true) - { - if (clientInterface != NULL) - { - clientInterface->close (); - return; - } - } - - getInProgressSavedGameFromFTPServer = ""; - getInProgressSavedGameFromFTPServerInProgress = false; - - string serverUrl = clientInterface->getServerIpAddress (); - int - portNumber = clientInterface->getServerFTPPort (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] Using FTP port #: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, portNumber); - - Config & config = Config::getInstance (); - vector < string > mapPathList = config.getPathListForType (ptMaps); - std::pair < string, string > mapsPath; - if (mapPathList.empty () == false) - { - mapsPath.first = mapPathList[0]; - } - if (mapPathList.size () > 1) - { - mapsPath.second = mapPathList[1]; - } - std::pair < string, string > tilesetsPath; - vector < string > tilesetsList = - Config::getInstance ().getPathListForType (ptTilesets); - if (tilesetsList.empty () == false) - { - tilesetsPath.first = tilesetsList[0]; - if (tilesetsList.size () > 1) - { - tilesetsPath.second = tilesetsList[1]; - } - } - - std::pair < string, string > techtreesPath; - vector < string > techtreesList = - Config::getInstance ().getPathListForType (ptTechs); - if (techtreesList.empty () == false) - { - techtreesPath.first = techtreesList[0]; - if (techtreesList.size () > 1) - { - techtreesPath.second = techtreesList[1]; - } - } - - std::pair < string, string > scenariosPath; - vector < string > scenariosList = - Config::getInstance ().getPathListForType (ptScenarios); - if (scenariosList.empty () == false) - { - scenariosPath.first = scenariosList[0]; - if (scenariosList.size () > 1) - { - scenariosPath.second = scenariosList[1]; - } - } - - string - fileArchiveExtension = - config.getString ("FileArchiveExtension", ""); - string - fileArchiveExtractCommand = - config.getString ("FileArchiveExtractCommand", ""); - string - fileArchiveExtractCommandParameters = - config.getString ("FileArchiveExtractCommandParameters", ""); - int32 - fileArchiveExtractCommandSuccessResult = - config.getInt ("FileArchiveExtractCommandSuccessResult", "0"); - -// Get path to temp files - string tempFilePath = "temp/"; - if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) - != "") - { - tempFilePath = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - tempFilePath; - } - else - { - string userData = config.getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - tempFilePath = userData + tempFilePath; - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Temp files path [%s]\n", tempFilePath.c_str ()); - - ftpClientThread = new FTPClientThread (portNumber, serverUrl, - mapsPath, tilesetsPath, - techtreesPath, scenariosPath, - this, fileArchiveExtension, - fileArchiveExtractCommand, - fileArchiveExtractCommandParameters, - fileArchiveExtractCommandSuccessResult, - tempFilePath); - ftpClientThread->start (); - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("CancelDownloadsMsg", languageList[i]) == - true) - { - snprintf (szMsg, 8096, - lang.getString ("CancelDownloadsMsg", - languageList[i]).c_str (), - getHumanPlayerName ().c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Player: %s cancelled all file downloads.", - getHumanPlayerName ().c_str ()); - } - clientInterface->sendTextMessage (szMsg, -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - } - } - } - else if (buttonDisconnect.mouseClick (x, y)) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - disconnectFromServer (); - networkManager.end (); - returnToJoinMenu (); - return; - } - - if (initialSettingsReceivedFromServer == false) - { - return; - } - - if (activeInputLabel != NULL - && activeInputLabel->mouseClick (x, y) == false) - { - setActiveInputLabel (NULL); - } - -// Only allow changes after we get game settings from the server - if (clientInterface != NULL && clientInterface->isConnected () == true) - { - int - myCurrentIndex = -1; - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { // find my current index by looking at editable listBoxes - if ( //listBoxFactions[i].getEditable() && - clientInterface-> - getGameSettings ()->getStartLocationIndex (clientInterface-> - getGameSettings - ()->getThisFactionIndex - ()) == i) - { - myCurrentIndex = i; - } - } - -//printf("myCurrentIndex = %d thisFactionIndex = %d\n",myCurrentIndex,clientInterface->getGameSettings()->getThisFactionIndex()); - - if (myCurrentIndex != -1) - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - if (listBoxFactions[i].getEditable () && - clientInterface-> - getGameSettings ()->getStartLocationIndex (clientInterface-> - getGameSettings - ()->getThisFactionIndex - ()) == i) - { - if (listBoxFactions[i].mouseClick - (x, y, advanceToItemStartingWith)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - ClientInterface * - clientInterface = - NetworkManager::getInstance ().getClientInterface (); - if (clientInterface->isConnected ()) - { - clientInterface->setGameSettingsReceived (false); - clientInterface-> - sendSwitchSetupRequest (listBoxFactions[i].getSelectedItem - (), i, -1, - listBoxTeams - [i].getSelectedItemIndex (), - getHumanPlayerName (), - getNetworkPlayerStatus (), - switchSetupRequestFlagType, - lang.getLanguage ()); - switchSetupRequestFlagType = ssrft_None; - noReceiveTimer = time (NULL); - } - break; - } - } - if (listBoxTeams[i].getEditable () && - clientInterface-> - getGameSettings ()->getStartLocationIndex (clientInterface-> - getGameSettings - ()->getThisFactionIndex - ()) == i) - { - if (listBoxTeams[i].mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - if (clientInterface->isConnected ()) - { - clientInterface->setGameSettingsReceived (false); - clientInterface-> - sendSwitchSetupRequest (listBoxFactions[i].getSelectedItem - (), i, -1, - listBoxTeams - [i].getSelectedItemIndex (), - getHumanPlayerName (), - getNetworkPlayerStatus (), - switchSetupRequestFlagType, - lang.getLanguage ()); - switchSetupRequestFlagType = ssrft_None; - } - break; - } - } - - bool canGrabSlot = false; - ClientInterface * - clientInterface = networkManager.getClientInterface (); - if (clientInterface != NULL - && clientInterface->getJoinGameInProgress () == true) - { - canGrabSlot = - ((listBoxControls[i].getSelectedItemIndex () == ctNetwork - && labelNetStatus[i].getText () == - GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) - || (listBoxControls[i].getSelectedItemIndex () != ctHuman - && listBoxControls[i].getSelectedItemIndex () != ctClosed - && listBoxControls[i].getSelectedItemIndex () != - ctNetwork)); - } - else - { - canGrabSlot = - (listBoxControls[i].getSelectedItemIndex () == ctNetwork - && labelNetStatus[i].getText () == - GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME); - } - - if (canGrabSlot == true) - { - if (clientInterface != NULL && i < mapInfo.players - && grabSlotButton[i].mouseClick (x, y)) - { -//printf("Send slot switch request for slot = %d, myCurrentIndex = %d\n",i,myCurrentIndex); - - soundRenderer.playFx (coreData.getClickSoundB ()); - clientInterface->setGameSettingsReceived (false); - settingsReceivedFromServer = false; - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] sending a switchSlot request from %d to %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, - clientInterface->getGameSettings - ()->getThisFactionIndex (), i); - -//printf("Switch slot from %d to %d\n",myCurrentIndex,i); - - string - desiredFactionName = - listBoxFactions[myCurrentIndex].getSelectedItem (); - int - desiredTeamIndex = - listBoxTeams[myCurrentIndex].getSelectedItemIndex (); - if (checkBoxScenario.getValue () == true) - { - desiredFactionName = listBoxFactions[i].getSelectedItem (); - desiredTeamIndex = listBoxTeams[i].getSelectedItemIndex (); - } - -//printf("Sending switch slot request to server...\n"); - - clientInterface->sendSwitchSetupRequest (desiredFactionName, - myCurrentIndex, - i, - desiredTeamIndex, - getHumanPlayerName - (), - getNetworkPlayerStatus - (), - switchSetupRequestFlagType, - lang.getLanguage ()); - labelPlayerNames[myCurrentIndex].setText (""); - labelPlayerNames[i].setText (""); - switchSetupRequestFlagType = ssrft_None; - break; - } - } - - if (labelPlayerNames[i].mouseClick (x, y) - && (activeInputLabel != &labelPlayerNames[i])) - { - if (clientInterface != NULL - && i == clientInterface->getPlayerIndex ()) - { - setActiveInputLabel (&labelPlayerNames[i]); - } - } - } - - if (listBoxPlayerStatus.mouseClick (x, y)) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - soundRenderer.playFx (coreData.getClickSoundC ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (getNetworkPlayerStatus () == npst_PickSettings) - { - listBoxPlayerStatus.setTextColor (Vec3f (1.0f, 0.0f, 0.0f)); - listBoxPlayerStatus.setLighted (true); - } - else if (getNetworkPlayerStatus () == npst_BeRightBack) - { - listBoxPlayerStatus.setTextColor (Vec3f (1.0f, 1.0f, 0.0f)); - listBoxPlayerStatus.setLighted (true); - } - else if (getNetworkPlayerStatus () == npst_Ready) - { - listBoxPlayerStatus.setTextColor (Vec3f (0.0f, 1.0f, 0.0f)); - listBoxPlayerStatus.setLighted (false); - } - - ClientInterface * - clientInterface = - NetworkManager::getInstance ().getClientInterface (); - if (clientInterface != NULL && clientInterface->isConnected ()) - { - clientInterface->setGameSettingsReceived (false); - clientInterface->sendSwitchSetupRequest (listBoxFactions - [clientInterface-> - getPlayerIndex ()]. - getSelectedItem (), - clientInterface-> - getPlayerIndex (), -1, - listBoxTeams - [clientInterface->getPlayerIndex - ()].getSelectedItemIndex - (), - getHumanPlayerName (), - getNetworkPlayerStatus - (), - switchSetupRequestFlagType, - lang.getLanguage ()); - switchSetupRequestFlagType = ssrft_None; - } - } - - if (isHeadlessAdmin () == true) - { -//printf("#1 admin key [%d] client key [%d]\n",settings->getMasterserver_admin(),clientInterface->getSessionKey()); - mouseClickAdmin (x, y, mouseButton, advanceToItemStartingWith); - } - else if (clientInterface != NULL - && clientInterface->getJoinGameInProgress () == true) - { - if (buttonPlayNow.mouseClick (x, y) && buttonPlayNow.getEnabled ()) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - uint32 tilesetCRC = lastCheckedCRCTilesetValue; - uint32 techCRC = lastCheckedCRCTechtreeValue; - uint32 mapCRC = lastCheckedCRCMapValue; - const GameSettings * - gameSettings = clientInterface->getGameSettings (); - - bool - dataSynchMismatch = - ((mapCRC != 0 && mapCRC != gameSettings->getMapCRC ()) - || (tilesetCRC != 0 - && tilesetCRC != gameSettings->getTilesetCRC ()) - || (techCRC != 0 && techCRC != gameSettings->getTechCRC ())); - if (dataSynchMismatch == false) - { - PlayNow (true); - return; - } - else - { - showMessageBox - ("You cannot start the game because\none or more clients do not have the same game data!", - "Data Mismatch Error", false); - } - } - } - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - bool MenuStateConnectedGame::isHeadlessAdmin () - { - bool result = false; - - ClientInterface * - clientInterface = - NetworkManager::getInstance ().getClientInterface (); - if (clientInterface != NULL && clientInterface->isConnected ()) - { - const GameSettings * - settings = clientInterface->getGameSettings (); - if (settings != NULL) - { -//printf("#1 admin key [%d] client key [%d]\n",settings->getMasterserver_admin(),clientInterface->getSessionKey()); - - if (settings->getMasterserver_admin () == - clientInterface->getSessionKey ()) - { - result = true; - } - } - } - - return result; - } - - void - MenuStateConnectedGame::broadCastGameSettingsToHeadlessServer (bool - forceNow) - { - if (isHeadlessAdmin () == false) - { - return; - } - - if (forceNow == true || - ((needToBroadcastServerSettings == true) - && - (difftime - ((long int) time (NULL), - broadcastServerSettingsDelayTimer) >= - HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS))) - { -//printf("In [%s:%s] Line: %d forceNow = %d broadcastServerSettingsDelayTimer = " MG_SIZE_T_SPECIFIER ", now =" MG_SIZE_T_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,forceNow,broadcastServerSettingsDelayTimer,time(NULL)); - - needToBroadcastServerSettings = false; - broadcastServerSettingsDelayTimer = time (NULL); - - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - - for (int i = 0; i < mapInfo.players; ++i) - { - if (listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned) - { - listBoxControls[i].setSelectedItemIndex (ctNetwork); - } - } - for (int i = mapInfo.players; i < GameConstants::maxPlayers; ++i) - { - if (listBoxControls[i].getSelectedItemIndex () == ctNetwork) - { - listBoxControls[i].setSelectedItemIndex (ctNetworkUnassigned); - } - } - - if (validDisplayedGamesettings) - { - loadGameSettings (&displayedGamesettings); - - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("broadcast settings:\n%s\n", - displayedGamesettings.toString ().c_str ()); - -//printf("Client sending map [%s] admin key [%d]\n",gameSettings.getMap().c_str(),gameSettings.getMasterserver_admin()); -//printf("sending Settings map filter=%d\n",displayedGamesettings.getMapFilter()); - clientInterface->broadcastGameSetup (&displayedGamesettings); - noReceiveTimer = time (NULL); - } - } - } - - void - MenuStateConnectedGame::updateResourceMultiplier (const int index) - { - ControlType - ct = - static_cast < ControlType > - (listBoxControls[index].getSelectedItemIndex ()); - if (ct == ctCpuEasy || ct == ctNetworkCpuEasy) - { - listBoxRMultiplier[index].setSelectedItem (floatToStr - (GameConstants:: - easyMultiplier, 1)); - listBoxRMultiplier[index].setEnabled (true); - } - else if (ct == ctCpu || ct == ctNetworkCpu) - { - listBoxRMultiplier[index].setSelectedItem (floatToStr - (GameConstants:: - normalMultiplier, 1)); - listBoxRMultiplier[index].setEnabled (true); - } - else if (ct == ctCpuUltra || ct == ctNetworkCpuUltra) - { - listBoxRMultiplier[index].setSelectedItem (floatToStr - (GameConstants:: - ultraMultiplier, 1)); - listBoxRMultiplier[index].setEnabled (true); - } - else if (ct == ctCpuZeta || ct == ctNetworkCpuZeta) - { - listBoxRMultiplier[index].setSelectedItem (floatToStr - (GameConstants:: - megaMultiplier, 1)); - listBoxRMultiplier[index].setEnabled (true); - } - else - { - listBoxRMultiplier[index].setSelectedItem (floatToStr - (GameConstants:: - normalMultiplier, 1)); - listBoxRMultiplier[index].setEnabled (false); - } - - listBoxRMultiplier[index]. - setEditable (listBoxRMultiplier[index].getEnabled ()); - listBoxRMultiplier[index]. - setVisible (listBoxRMultiplier[index].getEnabled ()); - } - - void - MenuStateConnectedGame::mouseClickAdmin (int x, int y, - MouseButton mouseButton, - string advanceToItemStartingWith) - { - - try - { - int - oldListBoxMapfilterIndex = listBoxMapFilter.getSelectedItemIndex (); - if (buttonPlayNow.mouseClick (x, y) && buttonPlayNow.getEnabled ()) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - PlayNow (true); - return; - } - else if (buttonRestoreLastSettings.mouseClick (x, y) - && buttonRestoreLastSettings.getEnabled ()) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - soundRenderer.playFx (coreData.getClickSoundB ()); - - RestoreLastGameSettings (); - } - else if (checkBoxAllowNativeLanguageTechtree.mouseClick (x, y)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } - else if (listBoxMap.mouseClick (x, y, advanceToItemStartingWith)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", - getCurrentMapFile ().c_str ()); - - if (loadMapInfo - (Config::getMapPath (getCurrentMapFile (), "", false), &mapInfo, - true) == true) - { - labelMapInfo.setText (mapInfo.desc); - } - else - { - labelMapInfo.setText ("???"); - } - - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } - else if (listBoxFogOfWar.mouseClick (x, y)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } - else if (checkBoxAllowObservers.mouseClick (x, y)) - { +Shared::CompressionUtil; + +namespace Glest { + namespace Game { + + static const int + MAX_PING_LAG_COUNT = 6; + static const double + REPROMPT_DOWNLOAD_SECONDS = 7; + //static const string ITEM_MISSING = "***missing***"; + // above replaced with Lang::getInstance().getString("DataMissing","",true) + const int + HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS = 2; + static const char * + HEADLESS_SAVED_GAME_FILENAME = "lastHeadlessGameSettings.mgg"; + + const int + mapPreviewTexture_X = 5; + const int + mapPreviewTexture_Y = 185; + const int + mapPreviewTexture_W = 150; + const int + mapPreviewTexture_H = 150; + + struct FormatString { + void + operator () (string & s) { + s = formatString(s); + } + }; + + // ===================================================== + // class MenuStateConnectedGame + // ===================================================== + + MenuStateConnectedGame::MenuStateConnectedGame(Program * program, MainMenu * mainMenu, JoinMenu joinMenuInfo, bool openNetworkSlots) : + MenuState(program, mainMenu, "connected-game"), + modHttpServerThread(NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + containerName = "ClientConnectedGame"; + switchSetupRequestFlagType |= ssrft_NetworkPlayerName; + updateDataSynchDetailText = false; + launchingNewGame = false; + isfirstSwitchingMapMessage = true; + + this->zoomedMap = false; + this->render_mapPreviewTexture_X = mapPreviewTexture_X; + this->render_mapPreviewTexture_Y = mapPreviewTexture_Y; + this->render_mapPreviewTexture_W = mapPreviewTexture_W; + this->render_mapPreviewTexture_H = mapPreviewTexture_H; + + needToBroadcastServerSettings = false; + broadcastServerSettingsDelayTimer = 0; + lastGameSettingsReceivedCount = 0; + noReceiveTimer = time(NULL) - 100; // old but inititialized ( must be an "old" time ) + + soundConnectionCount = 0; + + this->factionVideo = NULL; + factionVideoSwitchedOffVolume = false; + currentTechName_factionPreview = ""; + currentFactionName_factionPreview = ""; + + ftpClientThread = NULL; + ftpMissingDataType = ftpmsg_MissingNone; + getMissingMapFromFTPServer = ""; + getMissingMapFromFTPServerLastPrompted = 0; + getMissingMapFromFTPServerInProgress = false; + getMissingTilesetFromFTPServer = ""; + getMissingTilesetFromFTPServerLastPrompted = 0; + getMissingTilesetFromFTPServerInProgress = false; + getMissingTechtreeFromFTPServer = ""; + getMissingTechtreeFromFTPServerLastPrompted = 0; + getMissingTechtreeFromFTPServerInProgress = false; + + getInProgressSavedGameFromFTPServer = ""; + getInProgressSavedGameFromFTPServerInProgress = false; + readyToJoinInProgressGame = false; + + lastCheckedCRCTilesetName = ""; + lastCheckedCRCTechtreeName = ""; + lastCheckedCRCMapName = ""; + lastCheckedCRCTilesetValue = 0; + lastCheckedCRCTechtreeValue = 0; + lastCheckedCRCMapValue = 0; + + mapPreviewTexture = NULL; + currentFactionLogo = ""; + factionTexture = NULL; + lastMissingMap = ""; + lastMissingTechtree = ""; + lastMissingTileSet = ""; + + activeInputLabel = NULL; + lastNetworkSendPing = 0; + pingCount = 0; + needToSetChangedGameSettings = false; + lastSetChangedGameSettings = time(NULL); + showFullConsole = false; + + + currentFactionName = ""; + currentMap = ""; + settingsReceivedFromServer = false; + initialSettingsReceivedFromServer = false; + + validOriginalGameSettings = false; + validDisplayedGamesettings = false; + + returnMenuInfo = joinMenuInfo; + Lang & lang = Lang::getInstance(); + + mainMessageBox.registerGraphicComponent(containerName, + "mainMessageBox"); + mainMessageBox.init(lang.getString("Ok")); + mainMessageBox.setEnabled(false); + + ftpMessageBox.registerGraphicComponent(containerName, "ftpMessageBox"); + ftpMessageBox.init(lang.getString("ModCenter"), + lang.getString("GameHost")); + ftpMessageBox.addButton(lang.getString("NoDownload")); + ftpMessageBox.setEnabled(false); + + NetworkManager & networkManager = NetworkManager::getInstance(); + Config & config = Config::getInstance(); + defaultPlayerName = + config.getString("NetPlayerName", Socket::getHostName().c_str()); + enableFactionTexturePreview = config.getBool("FactionPreview", "true"); + enableMapPreview = config.getBool("MapPreview", "true"); + + enableScenarioTexturePreview = + Config::getInstance().getBool("EnableScenarioTexturePreview", + "true"); + scenarioLogoTexture = NULL; + previewLoadDelayTimer = time(NULL); + needToLoadTextures = true; + this->dirList = Config::getInstance().getPathListForType(ptScenarios); + + vector < + string > + techtreesList = Config::getInstance().getPathListForType(ptTechs); + techTree.reset(new TechTree(techtreesList)); + + vector < + string > + teamItems, controlItems, results, rMultiplier, playerStatuses; + + // Some of these values must also be changed to match those in + // menu_state_custom_game.cpp + int + labelOffset = 23; + int + setupPos = 605; + // mapHeadPos is the placement of the text "map", not the map itself + int mapHeadPos = 310; + int + mapPos = mapHeadPos - labelOffset; + int + aHeadPos = mapHeadPos - 90; + int + aPos = aHeadPos - labelOffset; + int + networkHeadPos = 700; + + //state + labelStatus.registerGraphicComponent(containerName, "labelStatus"); + labelStatus.init(30, networkHeadPos); + labelStatus.setText(""); + + labelInfo.registerGraphicComponent(containerName, "labelInfo"); + labelInfo.init(30, networkHeadPos + 30); + labelInfo.setText(""); + labelInfo.setFont(CoreData::getInstance().getMenuFontBig()); + labelInfo.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + + labelWaitingForPlayers.registerGraphicComponent(containerName, + "labelInfo"); + labelWaitingForPlayers.init(30, 100); + labelWaitingForPlayers.setText(""); + labelWaitingForPlayers.setFont(CoreData::getInstance(). + getMenuFontBig()); + labelWaitingForPlayers.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + labelWaitingForPlayers.setTextColor(Vec3f(1.0f, 1.0f, 0.f)); + + timerLabelFlash = time(NULL); + labelDataSynchInfo.registerGraphicComponent(containerName, + "labelDataSynchInfo"); + labelDataSynchInfo.init(30, networkHeadPos - 60); + labelDataSynchInfo.setText(""); + labelDataSynchInfo.setFont(CoreData::getInstance().getMenuFontBig()); + labelDataSynchInfo.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + + int + xoffset = 90; + labelAllowTeamUnitSharing.registerGraphicComponent(containerName, + "labelAllowTeamUnitSharing"); + labelAllowTeamUnitSharing.init(xoffset + 410, 670, 80); + labelAllowTeamUnitSharing.setText(lang. + getString("AllowTeamUnitSharing")); + labelAllowTeamUnitSharing.setVisible(true); + + checkBoxAllowTeamUnitSharing.registerGraphicComponent(containerName, + "checkBoxAllowTeamUnitSharing"); + checkBoxAllowTeamUnitSharing.init(xoffset + 612, 670); + checkBoxAllowTeamUnitSharing.setValue(false); + checkBoxAllowTeamUnitSharing.setVisible(true); + checkBoxAllowTeamUnitSharing.setEditable(false); + + labelAllowTeamResourceSharing.registerGraphicComponent(containerName, + "labelAllowTeamResourceSharing"); + labelAllowTeamResourceSharing.init(xoffset + 410, 640, 80); + labelAllowTeamResourceSharing.setText(lang. + getString + ("AllowTeamResourceSharing")); + labelAllowTeamResourceSharing.setVisible(true); + + checkBoxAllowTeamResourceSharing.registerGraphicComponent + (containerName, "checkBoxAllowTeamResourceSharing"); + checkBoxAllowTeamResourceSharing.init(xoffset + 612, 640); + checkBoxAllowTeamResourceSharing.setValue(false); + checkBoxAllowTeamResourceSharing.setVisible(true); + checkBoxAllowTeamResourceSharing.setEditable(false); + + // fog - o - war + xoffset = 65; + labelFogOfWar.registerGraphicComponent(containerName, "labelFogOfWar"); + labelFogOfWar.init(xoffset + 100, aHeadPos, 165); + labelFogOfWar.setText(lang.getString("FogOfWar")); + + listBoxFogOfWar.registerGraphicComponent(containerName, + "listBoxFogOfWar"); + listBoxFogOfWar.init(xoffset + 100, aPos, 165); + listBoxFogOfWar.pushBackItem(lang.getString("Enabled")); + listBoxFogOfWar.pushBackItem(lang.getString("Explored")); + listBoxFogOfWar.pushBackItem(lang.getString("Disabled")); + listBoxFogOfWar.setSelectedItemIndex(0); + listBoxFogOfWar.setEditable(false); + + labelAllowObservers.registerGraphicComponent(containerName, + "labelAllowObservers"); + labelAllowObservers.init(xoffset + 325, aHeadPos, 80); + labelAllowObservers.setText(lang.getString("AllowObservers")); + + checkBoxAllowObservers.registerGraphicComponent(containerName, + "checkBoxAllowObservers"); + checkBoxAllowObservers.init(xoffset + 325, aPos); + checkBoxAllowObservers.setValue(checkBoxAllowObservers.getValue()); + + checkBoxAllowObservers.setEditable(false); + + for (int i = 0; i < 45; ++i) { + rMultiplier.push_back(floatToStr(0.5f + 0.1f * i, 1)); + } + + labelFallbackCpuMultiplier.registerGraphicComponent(containerName, + "labelFallbackCpuMultiplier"); + labelFallbackCpuMultiplier.init(xoffset + 500, aHeadPos, 80); + labelFallbackCpuMultiplier.setText(lang.getString + ("FallbackCpuMultiplier")); + + listBoxFallbackCpuMultiplier.registerGraphicComponent(containerName, + "listBoxFallbackCpuMultiplier"); + listBoxFallbackCpuMultiplier.init(xoffset + 500, aPos, 80); + listBoxFallbackCpuMultiplier.setItems(rMultiplier); + listBoxFallbackCpuMultiplier.setSelectedItem("1.0"); + + + // Allow Switch Team Mode + labelEnableSwitchTeamMode.registerGraphicComponent(containerName, + "labelEnableSwitchTeamMode"); + labelEnableSwitchTeamMode.init(xoffset + 325, aHeadPos + 45, 80); + labelEnableSwitchTeamMode. + setText(lang.getString("EnableSwitchTeamMode")); + + checkBoxEnableSwitchTeamMode.registerGraphicComponent(containerName, + "checkBoxEnableSwitchTeamMode"); + checkBoxEnableSwitchTeamMode.init(xoffset + 325, aPos + 45); + checkBoxEnableSwitchTeamMode.setValue(false); + checkBoxEnableSwitchTeamMode.setEditable(false); + + labelAISwitchTeamAcceptPercent.registerGraphicComponent(containerName, + "labelAISwitchTeamAcceptPercent"); + labelAISwitchTeamAcceptPercent.init(xoffset + 500, aHeadPos + 45, 80); + labelAISwitchTeamAcceptPercent.setText(lang.getString + ("AISwitchTeamAcceptPercent")); + + listBoxAISwitchTeamAcceptPercent.registerGraphicComponent + (containerName, "listBoxAISwitchTeamAcceptPercent"); + listBoxAISwitchTeamAcceptPercent.init(xoffset + 500, aPos + 45, 80); + for (int i = 0; i <= 100; i = i + 10) { + listBoxAISwitchTeamAcceptPercent.pushBackItem(intToStr(i)); + } + listBoxAISwitchTeamAcceptPercent.setSelectedItem(intToStr(30)); + listBoxAISwitchTeamAcceptPercent.setEditable(false); + + //create + buttonCancelDownloads.registerGraphicComponent(containerName, + "buttonCancelDownloads"); + buttonCancelDownloads.init(xoffset + 620, 180, 150); + buttonCancelDownloads.setText(lang.getString("CancelDownloads")); + + // Network Frame Period + xoffset = 65; + //map listBox + + xoffset = 65; + // MapFilter + labelMapFilter.registerGraphicComponent(containerName, + "labelMapFilter"); + labelMapFilter.init(xoffset + 325, mapHeadPos); + labelMapFilter.setText(lang.getString("MapFilter")); + + listBoxMapFilter.registerGraphicComponent(containerName, + "listBoxMapFilter"); + listBoxMapFilter.init(xoffset + 325, mapPos, 80); + listBoxMapFilter.pushBackItem("-"); + for (int i = 1; i < GameConstants::maxPlayers + 1; ++i) { + listBoxMapFilter.pushBackItem(intToStr(i)); + } + listBoxMapFilter.setSelectedItemIndex(0); + listBoxMapFilter.setEditable(false); + + + // put them all in a set, to weed out duplicates (gbm & mgm with same name) + // will also ensure they are alphabetically listed (rather than how the OS provides them) + listBoxMap.registerGraphicComponent(containerName, "listBoxMap"); + listBoxMap.init(xoffset + 100, mapPos, 220); + listBoxMap.setEditable(false); + + labelMapInfo.registerGraphicComponent(containerName, "labelMapInfo"); + labelMapInfo.init(xoffset + 100, mapPos - labelOffset - 10, 200, 40); + labelMapInfo.setText("?"); + + labelMap.registerGraphicComponent(containerName, "labelMap"); + labelMap.init(xoffset + 100, mapHeadPos); + labelMap.setText(lang.getString("Map")); + + //tileset listBox + listBoxTileset.registerGraphicComponent(containerName, + "listBoxTileset"); + listBoxTileset.init(xoffset + 500, mapPos, 160); + listBoxTileset.setEditable(false); + + labelTileset.registerGraphicComponent(containerName, "labelTileset"); + labelTileset.init(xoffset + 500, mapHeadPos); + labelTileset.setText(lang.getString("Tileset")); + + + //tech Tree listBox + listBoxTechTree.setEditable(false); + + listBoxTechTree.registerGraphicComponent(containerName, + "listBoxTechTree"); + listBoxTechTree.init(xoffset + 700, mapPos, 180); + + labelTechTree.registerGraphicComponent(containerName, "labelTechTree"); + labelTechTree.init(xoffset + 700, mapHeadPos); + labelTechTree.setText(lang.getString("TechTree")); + + labelAllowNativeLanguageTechtree.registerGraphicComponent + (containerName, "labelAllowNativeLanguageTechtree"); + labelAllowNativeLanguageTechtree.init(xoffset + 700, aHeadPos + 45); + labelAllowNativeLanguageTechtree.setText(lang.getString + ("AllowNativeLanguageTechtree")); + + checkBoxAllowNativeLanguageTechtree.registerGraphicComponent + (containerName, "checkBoxAllowNativeLanguageTechtree"); + checkBoxAllowNativeLanguageTechtree.init(xoffset + 700, aPos + 45); + checkBoxAllowNativeLanguageTechtree.setValue(false); + checkBoxAllowNativeLanguageTechtree.setEditable(false); + checkBoxAllowNativeLanguageTechtree.setEnabled(false); + + // Network Scenario + int + scenarioX = xoffset + 700; + int + scenarioY = aPos; + labelScenario.registerGraphicComponent(containerName, "labelScenario"); + labelScenario.init(scenarioX, aHeadPos); + labelScenario.setText(lang.getString("Scenario")); + listBoxScenario.registerGraphicComponent(containerName, + "listBoxScenario"); + listBoxScenario.init(scenarioX + 30, scenarioY, 190); + listBoxScenario.setEditable(false); + listBoxScenario.setEnabled(false); + checkBoxScenario.registerGraphicComponent(containerName, + "checkBoxScenario"); + checkBoxScenario.init(scenarioX, scenarioY); + checkBoxScenario.setValue(false); + checkBoxScenario.setEditable(false); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + xoffset = 5; + int + rowHeight = 27; + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + labelPlayers[i].registerGraphicComponent(containerName, + "labelPlayers" + + intToStr(i)); + labelPlayers[i].init(xoffset - 1, setupPos - 30 - i * rowHeight + 2); + labelPlayers[i]. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + labelPlayers[i]. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + labelPlayers[i].setEditable(false); + + labelPlayerStatus[i].registerGraphicComponent(containerName, + "labelPlayerStatus" + + intToStr(i)); + labelPlayerStatus[i].init(xoffset + 14, + setupPos - 30 - i * rowHeight + 2); + labelPlayerNames[i].registerGraphicComponent(containerName, + "labelPlayerNames" + + intToStr(i)); + labelPlayerNames[i].init(xoffset + 30, + setupPos - 30 - i * rowHeight); + + listBoxControls[i].registerGraphicComponent(containerName, + "listBoxControls" + + intToStr(i)); + listBoxControls[i].init(xoffset + 160, setupPos - 30 - i * rowHeight, + 174); + listBoxControls[i].setEditable(false); + + listBoxRMultiplier[i].registerGraphicComponent(containerName, + "listBoxRMultiplier" + + intToStr(i)); + listBoxRMultiplier[i].init(xoffset + 336, + setupPos - 30 - i * rowHeight, 70); + listBoxRMultiplier[i].setEditable(false); + + listBoxFactions[i].registerGraphicComponent(containerName, + "listBoxFactions" + + intToStr(i)); + listBoxFactions[i].init(xoffset + 411, setupPos - 30 - i * rowHeight, + 247); + listBoxFactions[i].setLeftControlled(true); + listBoxFactions[i].setEditable(false); + + listBoxTeams[i].registerGraphicComponent(containerName, + "listBoxTeams" + + intToStr(i)); + listBoxTeams[i].init(xoffset + 660, setupPos - 30 - i * rowHeight, + 60); + listBoxTeams[i].setEditable(false); + listBoxTeams[i].setLighted(true); + + labelNetStatus[i].registerGraphicComponent(containerName, + "labelNetStatus" + + intToStr(i)); + labelNetStatus[i].init(xoffset + 723, setupPos - 30 - i * rowHeight, + 60); + labelNetStatus[i]. + setFont(CoreData::getInstance().getDisplayFontSmall()); + labelNetStatus[i]. + setFont3D(CoreData::getInstance().getDisplayFontSmall3D()); + + grabSlotButton[i].registerGraphicComponent(containerName, + "grabSlotButton" + + intToStr(i)); + grabSlotButton[i].init(xoffset + 726, setupPos - 30 - i * rowHeight, + 35, rowHeight - 5); + grabSlotButton[i].setText(">"); + } + + labelControl.registerGraphicComponent(containerName, "labelControl"); + labelControl.init(xoffset + 160, setupPos, 50, GraphicListBox::defH, + true); + labelControl.setText(lang.getString("Control")); + + labelRMultiplier.registerGraphicComponent(containerName, + "labelRMultiplier"); + labelRMultiplier.init(xoffset + 310, setupPos, 50, + GraphicListBox::defH, true); + + labelFaction.registerGraphicComponent(containerName, "labelFaction"); + labelFaction.init(xoffset + 411, setupPos, 50, GraphicListBox::defH, + true); + labelFaction.setText(lang.getString("Faction")); + + labelTeam.registerGraphicComponent(containerName, "labelTeam"); + labelTeam.init(xoffset + 660, setupPos, 50, GraphicListBox::defH, + true); + labelTeam.setText(lang.getString("Team")); + + labelControl.setFont(CoreData::getInstance().getMenuFontBig()); + labelControl.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelFaction.setFont(CoreData::getInstance().getMenuFontBig()); + labelFaction.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelTeam.setFont(CoreData::getInstance().getMenuFontBig()); + labelTeam.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + + //texts + buttonDisconnect.setText(lang.getString("Return")); + + controlItems.push_back(lang.getString("Closed")); + controlItems.push_back(lang.getString("CpuEasy")); + controlItems.push_back(lang.getString("Cpu")); + controlItems.push_back(lang.getString("CpuUltra")); + controlItems.push_back(lang.getString("CpuZeta")); + controlItems.push_back(lang.getString("Network")); + controlItems.push_back(lang.getString("NetworkUnassigned")); + controlItems.push_back(lang.getString("Human")); + + + if (config.getBool("EnableNetworkCpu", "false") == true) { + controlItems.push_back(lang.getString("NetworkCpuEasy")); + controlItems.push_back(lang.getString("NetworkCpu")); + controlItems.push_back(lang.getString("NetworkCpuUltra")); + controlItems.push_back(lang.getString("NetworkCpuZeta")); + } + + for (int i = 1; i <= GameConstants::maxPlayers; ++i) { + teamItems.push_back(intToStr(i)); + } + for (int i = GameConstants::maxPlayers + 1; + i <= GameConstants::maxPlayers + GameConstants::specialFactions; + ++i) { + teamItems.push_back(intToStr(i)); + } + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + labelPlayerStatus[i].setText(""); + labelPlayerStatus[i].setTexture(NULL); + labelPlayerStatus[i].setH(16); + labelPlayerStatus[i].setW(12); + + labelPlayers[i].setText(intToStr(i + 1)); + labelPlayerNames[i].setText(""); + labelPlayerNames[i].setMaxEditWidth(16); + labelPlayerNames[i].setMaxEditRenderWidth(127); + + listBoxTeams[i].setItems(teamItems); + listBoxTeams[i].setSelectedItemIndex(i); + listBoxControls[i].setItems(controlItems); + listBoxRMultiplier[i].setItems(rMultiplier); + listBoxRMultiplier[i].setSelectedItem("1.0"); + + labelNetStatus[i].setText("V"); + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //init controllers + listBoxControls[0].setSelectedItemIndex(ctHuman); + + + //map listBox + // put them all in a set, to weed out duplicates (gbm & mgm with same name) + // will also ensure they are alphabetically listed (rather than how the OS provides them) + setupMapList(""); + listBoxMap.setItems(formattedPlayerSortedMaps[0]); + + int + buttonx = 165; + int + buttony = 150; + + listBoxPlayerStatus.registerGraphicComponent(containerName, + "listBoxPlayerStatus"); + listBoxPlayerStatus.init(buttonx, buttony, 165); + listBoxPlayerStatus.setTextColor(Vec3f(1.0f, 0.f, 0.f)); + listBoxPlayerStatus.setLighted(true); + playerStatuses.push_back(lang.getString("PlayerStatusSetup")); + playerStatuses.push_back(lang.getString("PlayerStatusBeRightBack")); + playerStatuses.push_back(lang.getString("PlayerStatusReady")); + listBoxPlayerStatus.setItems(playerStatuses); + buttonx += 180; + + buttonDisconnect.registerGraphicComponent(containerName, + "buttonDisconnect"); + buttonDisconnect.init(buttonx, buttony, 125); + buttonx += 132; + + buttonRestoreLastSettings.registerGraphicComponent(containerName, + "buttonRestoreLastSettings"); + buttonRestoreLastSettings.init(buttonx, buttony, 240); + buttonRestoreLastSettings.setText(lang.getString + ("ReloadLastGameSettings")); + buttonx += 247; + + buttonPlayNow.registerGraphicComponent(containerName, "buttonPlayNow"); + buttonPlayNow.init(buttonx, buttony, 125); + buttonPlayNow.setText(lang.getString("PlayNow")); + buttonPlayNow.setVisible(false); + + + // write hint to console: + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + + console.addLine(lang.getString("ToSwitchOffMusicPress") + " - \"" + + configKeys.getString("ToggleMusic") + "\""); + chatManager.init(&console, -1, true); + + GraphicComponent::applyAllCustomProperties(containerName); + + //tileset listBox + setupTilesetList(""); + + int + initialTechSelection = setupTechList("", true); + listBoxTechTree.setSelectedItemIndex(initialTechSelection); + + + //scenario listbox + vector < string > resultsScenarios; + findDirs(dirList, resultsScenarios); + // Filter out only scenarios with no network slots + for (int i = 0; i < (int) resultsScenarios.size(); ++i) { + string scenario = resultsScenarios[i]; + string file = Scenario::getScenarioPath(dirList, scenario); + + try { + if (file != "") { + bool isTutorial = Scenario::isGameTutorial(file); + Scenario::loadScenarioInfo(file, &scenarioInfo, isTutorial); + + bool isNetworkScenario = false; + for (unsigned int j = 0; + isNetworkScenario == false + && j < (unsigned int) GameConstants::maxPlayers; ++j) { + if (scenarioInfo.factionControls[j] == ctNetwork) { + isNetworkScenario = true; + } + } + if (isNetworkScenario == true) { + scenarioFiles.push_back(scenario); + } + } + } catch (const std::exception & ex) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s %d]\nError loading scenario [%s]:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, scenario.c_str(), ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + showMessageBox(szBuf, "Error", false); + //throw megaglest_runtime_error(szBuf); + } + } + resultsScenarios.clear(); + for (int i = 0; i < (int) scenarioFiles.size(); ++i) { + resultsScenarios.push_back(formatString(scenarioFiles[i])); + } + listBoxScenario.setItems(resultsScenarios); + checkBoxScenario.setEnabled(false); + + if (config.getBool("EnableFTPXfer", "true") == true) { + ClientInterface * + clientInterface = networkManager.getClientInterface(); + string serverUrl = clientInterface->getServerIpAddress(); + int + portNumber = clientInterface->getServerFTPPort(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] Using FTP port #: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, portNumber); + + vector < string > mapPathList = config.getPathListForType(ptMaps); + std::pair < string, string > mapsPath; + if (mapPathList.empty() == false) { + mapsPath.first = mapPathList[0]; + } + if (mapPathList.size() > 1) { + mapsPath.second = mapPathList[1]; + } + std::pair < string, string > tilesetsPath; + vector < string > tilesetsList = + Config::getInstance().getPathListForType(ptTilesets); + if (tilesetsList.empty() == false) { + tilesetsPath.first = tilesetsList[0]; + if (tilesetsList.size() > 1) { + tilesetsPath.second = tilesetsList[1]; + } + } + + std::pair < string, string > techtreesPath; + if (techtreesList.empty() == false) { + techtreesPath.first = techtreesList[0]; + if (techtreesList.size() > 1) { + techtreesPath.second = techtreesList[1]; + } + } + + std::pair < string, string > scenariosPath; + vector < string > scenariosList = + Config::getInstance().getPathListForType(ptScenarios); + if (scenariosList.empty() == false) { + scenariosPath.first = scenariosList[0]; + if (scenariosList.size() > 1) { + scenariosPath.second = scenariosList[1]; + } + } + + string + fileArchiveExtension = + config.getString("FileArchiveExtension", ""); + string + fileArchiveExtractCommand = + config.getString("FileArchiveExtractCommand", ""); + string + fileArchiveExtractCommandParameters = + config.getString("FileArchiveExtractCommandParameters", ""); + int32 + fileArchiveExtractCommandSuccessResult = + config.getInt("FileArchiveExtractCommandSuccessResult", "0"); + + // Get path to temp files + string tempFilePath = "temp/"; + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != + "") { + tempFilePath = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + tempFilePath; + } else { + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + tempFilePath = userData + tempFilePath; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Temp files path [%s]\n", tempFilePath.c_str()); + + ftpClientThread = new FTPClientThread(portNumber, serverUrl, + mapsPath, tilesetsPath, + techtreesPath, scenariosPath, + this, fileArchiveExtension, + fileArchiveExtractCommand, + fileArchiveExtractCommandParameters, + fileArchiveExtractCommandSuccessResult, + tempFilePath); + ftpClientThread->start(); + } + // Start http meta data thread + static + string + mutexOwnerId = + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + string("_") + intToStr(__LINE__); + modHttpServerThread = new SimpleTaskThread(this, 0, 200); + modHttpServerThread->setUniqueID(mutexOwnerId); + modHttpServerThread->start(); + + ClientInterface * + clientInterface = networkManager.getClientInterface(); + if (clientInterface != NULL + && clientInterface->getJoinGameInProgress() == true) { + listBoxPlayerStatus.setVisible(false); + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("JoinPlayerToCurrentGameWelcome", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString("JoinPlayerToCurrentGameWelcome", + languageList[i]).c_str(), + getHumanPlayerName().c_str()); + } else { + snprintf(szMsg, 8096, + "Player: %s has connected to the game and would like to join.", + getHumanPlayerName().c_str()); + } + bool localEcho = lang.isLanguageLocal(languageList[i]); + clientInterface->sendTextMessage(szMsg, -1, localEcho, + languageList[i]); + } + sleep(1); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + // I moved this block from loadMapInfo(), and modified it. It was + // setting the slots visible based on the number of hardMaxPlayers + // every time a new map was loaded. Trying it here instead, so the + // labels are made visible only once. Below, we'll be disabling slots + // that exceed hardMaxPlayers + for (int i = 0; i < GameConstants::maxPlayers; i++) { + labelPlayers[i].setVisible(true); + labelPlayerNames[i].setVisible(true); + listBoxControls[i].setVisible(true); + listBoxFactions[i].setVisible(true); + listBoxTeams[i].setVisible(true); + labelNetStatus[i].setVisible(true); + } + } + + void + MenuStateConnectedGame::reloadUI() { + Config & config = Config::getInstance(); + Lang & lang = Lang::getInstance(); + + console.resetFonts(); + mainMessageBox.init(lang.getString("Ok")); + ftpMessageBox.init(lang.getString("ModCenter"), + lang.getString("GameHost")); + ftpMessageBox.addButton(lang.getString("NoDownload")); + + labelInfo.setFont(CoreData::getInstance().getMenuFontBig()); + labelInfo.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + + labelWaitingForPlayers. + setFont(CoreData::getInstance().getMenuFontBig()); + labelWaitingForPlayers. + setFont3D(CoreData::getInstance().getMenuFontBig3D()); + + labelDataSynchInfo.setFont(CoreData::getInstance().getMenuFontBig()); + labelDataSynchInfo. + setFont3D(CoreData::getInstance().getMenuFontBig3D()); + + buttonCancelDownloads.setText(lang.getString("CancelDownloads")); + + labelFogOfWar.setText(lang.getString("FogOfWar")); + + vector < string > fowItems; + fowItems.push_back(lang.getString("Enabled")); + fowItems.push_back(lang.getString("Explored")); + fowItems.push_back(lang.getString("Disabled")); + listBoxFogOfWar.setItems(fowItems); + + labelAllowObservers.setText(lang.getString("AllowObservers")); + labelFallbackCpuMultiplier.setText(lang.getString + ("FallbackCpuMultiplier")); + + labelEnableSwitchTeamMode. + setText(lang.getString("EnableSwitchTeamMode")); + + labelAllowTeamUnitSharing. + setText(lang.getString("AllowTeamUnitSharing")); + labelAllowTeamResourceSharing. + setText(lang.getString("AllowTeamResourceSharing")); + + labelAISwitchTeamAcceptPercent.setText(lang.getString + ("AISwitchTeamAcceptPercent")); + + vector < string > aiswitchteamModeItems; + for (int i = 0; i <= 100; i = i + 10) { + aiswitchteamModeItems.push_back(intToStr(i)); + } + listBoxAISwitchTeamAcceptPercent.setItems(aiswitchteamModeItems); + + vector < string > rMultiplier; + for (int i = 0; i < 45; ++i) { + rMultiplier.push_back(floatToStr(0.5f + 0.1f * i, 1)); + } + listBoxFallbackCpuMultiplier.setItems(rMultiplier); + + labelMap.setText(lang.getString("Map")); + + labelMapFilter.setText(lang.getString("MapFilter")); + + labelTileset.setText(lang.getString("Tileset")); + + labelTechTree.setText(lang.getString("TechTree")); + + vector < string > playerstatusItems; + playerstatusItems.push_back(lang.getString("PlayerStatusSetup")); + playerstatusItems. + push_back(lang.getString("PlayerStatusBeRightBack")); + playerstatusItems.push_back(lang.getString("PlayerStatusReady")); + listBoxPlayerStatus.setItems(playerstatusItems); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + labelControl.setText(lang.getString("Control")); + + labelFaction.setText(lang.getString("Faction")); + + labelTeam.setText(lang.getString("Team")); + + labelControl.setFont(CoreData::getInstance().getMenuFontBig()); + labelControl.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelFaction.setFont(CoreData::getInstance().getMenuFontBig()); + labelFaction.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelTeam.setFont(CoreData::getInstance().getMenuFontBig()); + labelTeam.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + + //texts + buttonDisconnect.setText(lang.getString("Return")); + + vector < string > controlItems; + controlItems.push_back(lang.getString("Closed")); + controlItems.push_back(lang.getString("CpuEasy")); + controlItems.push_back(lang.getString("Cpu")); + controlItems.push_back(lang.getString("CpuUltra")); + controlItems.push_back(lang.getString("CpuZeta")); + controlItems.push_back(lang.getString("Network")); + controlItems.push_back(lang.getString("NetworkUnassigned")); + controlItems.push_back(lang.getString("Human")); + + if (config.getBool("EnableNetworkCpu", "false") == true) { + controlItems.push_back(lang.getString("NetworkCpuEasy")); + controlItems.push_back(lang.getString("NetworkCpu")); + controlItems.push_back(lang.getString("NetworkCpuUltra")); + controlItems.push_back(lang.getString("NetworkCpuZeta")); + } + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + labelPlayers[i].setText(intToStr(i + 1)); + listBoxControls[i].setItems(controlItems); + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + labelScenario.setText(lang.getString("Scenario")); + + labelAllowNativeLanguageTechtree.setText(lang.getString + ("AllowNativeLanguageTechtree")); + + buttonPlayNow.setText(lang.getString("PlayNow")); + buttonRestoreLastSettings.setText(lang.getString + ("ReloadLastGameSettings")); + + chatManager.init(&console, -1, true); + + GraphicComponent::reloadFontsForRegisterGraphicComponents + (containerName); + } + + void + MenuStateConnectedGame::disconnectFromServer() { + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(false); + if (clientInterface != NULL) { + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + + soundRenderer.playFx(coreData.getClickSoundA()); + if (clientInterface->getSocket() != NULL) { + if (clientInterface->isConnected() == true) { + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + string sQuitText = lang.getString("QuitGame", languageList[i]); + clientInterface->sendTextMessage(sQuitText, -1, false, + languageList[i]); + } + sleep(1); + + } + clientInterface->close(); + } + clientInterface->reset(); + } + currentFactionName = ""; + currentMap = ""; + } + + MenuStateConnectedGame::~MenuStateConnectedGame() { + if (launchingNewGame == false) { + disconnectFromServer(); + NetworkManager & networkManager = NetworkManager::getInstance(); + networkManager.end(); + } + + if (modHttpServerThread != NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + modHttpServerThread->setSimpleTaskInterfaceValid(false); + modHttpServerThread->signalQuit(); + modHttpServerThread->setThreadOwnerValid(false); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + if (modHttpServerThread->canShutdown(true) == true + && modHttpServerThread->shutdownAndWait() == true) { + delete modHttpServerThread; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + modHttpServerThread = NULL; + } + + if (ftpClientThread != NULL) { + ftpClientThread->setCallBackObject(NULL); + ftpClientThread->signalQuit(); + sleep(0); + if (ftpClientThread->canShutdown(true) == true && + ftpClientThread->shutdownAndWait() == true) { + delete ftpClientThread; + } else { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s %d] Error cannot shutdown ftpClientThread\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("%s", szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + } + + ftpClientThread = NULL; + } + + cleanupMapPreviewTexture(); + + if (factionVideo != NULL) { + factionVideo->closePlayer(); + delete factionVideo; + factionVideo = NULL; + } + } + + string MenuStateConnectedGame::refreshTilesetModInfo(string tilesetInfo) { + std::vector < std::string > tilesetInfoList; + Tokenize(tilesetInfo, tilesetInfoList, "|"); + if (tilesetInfoList.size() >= 5) { + Config & config = Config::getInstance(); + ModInfo modinfo; + modinfo.name = tilesetInfoList[0]; + modinfo.crc = tilesetInfoList[1]; + modinfo.description = tilesetInfoList[2]; + modinfo.url = tilesetInfoList[3]; + modinfo.imageUrl = tilesetInfoList[4]; + modinfo.type = mt_Tileset; + + string + itemPath = + config.getPathListForType(ptTilesets, + "")[1] + "/" + modinfo.name + + string("/*"); + if (itemPath.empty() == false) { + bool + forceRefresh = + (mapCRCUpdateList.find(itemPath) == mapCRCUpdateList.end()); + uint32 + crc = + getFolderTreeContentsCheckSumRecursively(itemPath, ".xml", NULL, + forceRefresh); + if (crc == 0) { + itemPath = + config.getPathListForType(ptTilesets, + "")[0] + "/" + modinfo.name + + string("/*"); + if (itemPath.empty() == false) { + forceRefresh = + (mapCRCUpdateList.find(itemPath) == mapCRCUpdateList.end()); + crc = + getFolderTreeContentsCheckSumRecursively(itemPath, ".xml", + NULL, forceRefresh); + } + } + modinfo.localCRC = uIntToStr(crc); + //printf("itemPath='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); + + //printf("#1 refreshTilesetModInfo name [%s] modInfo.crc [%s] modInfo.localCRC [%s]\n",modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str()); + } else { + modinfo.localCRC = ""; + + //printf("#2 refreshTilesetModInfo name [%s] modInfo.crc [%s] modInfo.localCRC [%s]\n",modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str()); + } + + tilesetCacheList[modinfo.name] = modinfo; + return modinfo.name; + } + return ""; + } + + string MenuStateConnectedGame::refreshTechModInfo(string techInfo) { + std::vector < std::string > techInfoList; + Tokenize(techInfo, techInfoList, "|"); + if (techInfoList.size() >= 6) { + Config & config = Config::getInstance(); + ModInfo modinfo; + modinfo.name = techInfoList[0]; + modinfo.count = techInfoList[1]; + modinfo.crc = techInfoList[2]; + modinfo.description = techInfoList[3]; + modinfo.url = techInfoList[4]; + modinfo.imageUrl = techInfoList[5]; + modinfo.type = mt_Techtree; + + string + itemPath = + config.getPathListForType(ptTechs, + "")[1] + "/" + modinfo.name + + string("/*"); + if (itemPath.empty() == false) { + bool + forceRefresh = + (mapCRCUpdateList.find(itemPath) == mapCRCUpdateList.end()); + uint32 + crc = + getFolderTreeContentsCheckSumRecursively(itemPath, ".xml", NULL, + forceRefresh); + if (crc == 0) { + itemPath = + config.getPathListForType(ptTechs, + "")[0] + "/" + modinfo.name + + string("/*"); + if (itemPath.empty() == false) { + forceRefresh = + (mapCRCUpdateList.find(itemPath) == mapCRCUpdateList.end()); + crc = + getFolderTreeContentsCheckSumRecursively(itemPath, ".xml", + NULL, forceRefresh); + } + } + modinfo.localCRC = uIntToStr(crc); + //printf("itemPath='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); + } else { + modinfo.localCRC = ""; + } + techCacheList[modinfo.name] = modinfo; + return modinfo.name; + } + return ""; + } + + string MenuStateConnectedGame::getMapCRC(string mapName) { + Config & config = Config::getInstance(); + vector < string > mappaths = config.getPathListForType(ptMaps, ""); + string result = ""; + if (mappaths.empty() == false) { + Checksum checksum; + string itemPath = mappaths[1] + "/" + mapName; + if (fileExists(itemPath)) { + checksum.addFile(itemPath); + uint32 crc = checksum.getSum(); + result = uIntToStr(crc); + //printf("itemPath='%s' modinfo.name='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); + } else { + itemPath = mappaths[0] + "/" + mapName; + if (fileExists(itemPath)) { + checksum.addFile(itemPath); + uint32 crc = checksum.getSum(); + result = uIntToStr(crc); + //printf("itemPath='%s' modinfo.name='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); + } else { + result = ""; + } + } + } else { + result = ""; + } + return result; + } + + string MenuStateConnectedGame::refreshMapModInfo(string mapInfo) { + std::vector < std::string > mapInfoList; + Tokenize(mapInfo, mapInfoList, "|"); + if (mapInfoList.size() >= 6) { + //Config &config = Config::getInstance(); + ModInfo modinfo; + modinfo.name = mapInfoList[0]; + modinfo.count = mapInfoList[1]; + modinfo.crc = mapInfoList[2]; + modinfo.description = mapInfoList[3]; + modinfo.url = mapInfoList[4]; + modinfo.imageUrl = mapInfoList[5]; + modinfo.type = mt_Map; + modinfo.localCRC = getMapCRC(modinfo.name); + mapCacheList[modinfo.name] = modinfo; + return modinfo.name; + } + return ""; + } + + void + MenuStateConnectedGame::simpleTask(BaseThread * callingThread, + void *userdata) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + static + string + mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexThreadOwner(callingThread->getMutexThreadOwnerValid(), + mutexOwnerId); + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + callingThread->getMutexThreadOwnerValid()->setOwnerId(mutexOwnerId); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + Lang & lang = Lang::getInstance(); + Config & config = Config::getInstance(); + + std::string techsMetaData = ""; + std::string tilesetsMetaData = ""; + std::string mapsMetaData = ""; + std::string scenariosMetaData = ""; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (config.getString("Masterserver", "") != "") { + string baseURL = config.getString("Masterserver"); + if (baseURL != "") { + endPathWithSlash(baseURL, false); + } + string + phpVersionParam = + config.getString("phpVersionParam", "?version=0.1"); + string + gameVersion = + "&glestVersion=" + SystemFlags::escapeURL(glestVersionString); + string + playerUUID = + "&uuid=" + + SystemFlags::escapeURL(config.getString("PlayerId", "")); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line %d] About to call first http url, base [%s]..\n", + __FILE__, __FUNCTION__, __LINE__, baseURL.c_str()); + + CURL * + handle = SystemFlags::initHTTP(); + CURLcode curlResult = CURLE_OK; + techsMetaData = + SystemFlags::getHTTP(baseURL + "showTechsForGlest.php" + + phpVersionParam + gameVersion + playerUUID, + handle, -1, &curlResult); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("techsMetaData [%s] curlResult = %d\n", + techsMetaData.c_str(), curlResult); + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + if (curlResult != CURLE_OK) { + string curlError = curl_easy_strerror(curlResult); + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModErrorGettingServerData").c_str(), + curlError.c_str()); + console.addLine(string("#1 ") + szBuf, true); + } + + if (curlResult == CURLE_OK || + (curlResult != CURLE_COULDNT_RESOLVE_HOST && + curlResult != CURLE_COULDNT_CONNECT)) { + + tilesetsMetaData = + SystemFlags::getHTTP(baseURL + "showTilesetsForGlest.php" + + phpVersionParam + gameVersion, handle, -1, + &curlResult); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("tilesetsMetaData [%s]\n", tilesetsMetaData.c_str()); + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + if (curlResult != CURLE_OK) { + string curlError = curl_easy_strerror(curlResult); + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModErrorGettingServerData").c_str(), + curlError.c_str()); + console.addLine(string("#2 ") + szBuf, true); + } + + mapsMetaData = + SystemFlags::getHTTP(baseURL + "showMapsForGlest.php" + + phpVersionParam + gameVersion, handle, -1, + &curlResult); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("mapsMetaData [%s]\n", mapsMetaData.c_str()); + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + if (curlResult != CURLE_OK) { + string curlError = curl_easy_strerror(curlResult); + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModErrorGettingServerData").c_str(), + curlError.c_str()); + console.addLine(string("#3 ") + szBuf, true); + } + + scenariosMetaData = + SystemFlags::getHTTP(baseURL + "showScenariosForGlest.php" + + phpVersionParam + gameVersion, handle, -1, + &curlResult); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("scenariosMetaData [%s]\n", scenariosMetaData.c_str()); + + if (curlResult != CURLE_OK) { + string curlError = curl_easy_strerror(curlResult); + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModErrorGettingServerData").c_str(), + curlError.c_str()); + console.addLine(string("#4 ") + szBuf, true); + } + } + SystemFlags::cleanupHTTP(&handle); + } else { + console.addLine(lang.getString("MasterServerMissing"), true); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + MutexSafeWrapper + safeMutex(callingThread->getMutexThreadObjectAccessor(), + string(__FILE__) + "_" + intToStr(__LINE__)); + tilesetListRemote.clear(); + Tokenize(tilesetsMetaData, tilesetListRemote, "\n"); + safeMutex.ReleaseLock(true); + + for (unsigned int i = 0; i < tilesetListRemote.size(); i++) { + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + safeMutex.Lock(); + string result = refreshTilesetModInfo(tilesetListRemote[i]); + safeMutex.ReleaseLock(true); + } + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + safeMutex.Lock(); + techListRemote.clear(); + Tokenize(techsMetaData, techListRemote, "\n"); + safeMutex.ReleaseLock(true); + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + for (unsigned int i = 0; i < techListRemote.size(); i++) { + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + safeMutex.Lock(); + string result = refreshTechModInfo(techListRemote[i]); + safeMutex.ReleaseLock(true); + } + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + safeMutex.Lock(); + mapListRemote.clear(); + Tokenize(mapsMetaData, mapListRemote, "\n"); + safeMutex.ReleaseLock(true); + + for (unsigned int i = 0; i < mapListRemote.size(); i++) { + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + safeMutex.Lock(); + string result = refreshMapModInfo(mapListRemote[i]); + safeMutex.ReleaseLock(true); + } + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + if (modHttpServerThread != NULL) { + modHttpServerThread->signalQuit(); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void + MenuStateConnectedGame::mouseClick(int x, int y, MouseButton mouseButton) { + + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + Lang & lang = Lang::getInstance(); + + string advanceToItemStartingWith = ""; + if (mainMessageBox.getEnabled() == false) { + if (::Shared::Platform::Window::isKeyStateModPressed(KMOD_SHIFT) == + true) { + wchar_t + lastKey = ::Shared::Platform::Window::extractLastKeyPressed(); + //printf("lastKey = %d [%c]\n",lastKey,lastKey); + advanceToItemStartingWith = lastKey; + } + } + + if (mapPreviewTexture != NULL) { + // printf("X: %d Y: %d [%d, %d, %d, %d]\n", + // x, y, + // this->render_mapPreviewTexture_X, this->render_mapPreviewTexture_X + this->render_mapPreviewTexture_W, + // this->render_mapPreviewTexture_Y, this->render_mapPreviewTexture_Y + this->render_mapPreviewTexture_H); + + if (x >= this->render_mapPreviewTexture_X + && x <= + this->render_mapPreviewTexture_X + + this->render_mapPreviewTexture_W + && y >= this->render_mapPreviewTexture_Y + && y <= + this->render_mapPreviewTexture_Y + + this->render_mapPreviewTexture_H) { + + if (this->render_mapPreviewTexture_X == mapPreviewTexture_X && + this->render_mapPreviewTexture_Y == mapPreviewTexture_Y && + this->render_mapPreviewTexture_W == mapPreviewTexture_W && + this->render_mapPreviewTexture_H == mapPreviewTexture_H) { + + const + Metrics & + metrics = Metrics::getInstance(); + + this->render_mapPreviewTexture_X = 0; + this->render_mapPreviewTexture_Y = 0; + this->render_mapPreviewTexture_W = metrics.getVirtualW(); + this->render_mapPreviewTexture_H = metrics.getVirtualH(); + this->zoomedMap = true; + + cleanupMapPreviewTexture(); + } else { + this->render_mapPreviewTexture_X = mapPreviewTexture_X; + this->render_mapPreviewTexture_Y = mapPreviewTexture_Y; + this->render_mapPreviewTexture_W = mapPreviewTexture_W; + this->render_mapPreviewTexture_H = mapPreviewTexture_H; + this->zoomedMap = false; + + cleanupMapPreviewTexture(); + } + return; + } + if (this->zoomedMap == true) { + return; + } + } + + if (mainMessageBox.getEnabled()) { + int + button = 0; + if (mainMessageBox.mouseClick(x, y, button)) { + soundRenderer.playFx(coreData.getClickSoundA()); + if (button == 0) { + mainMessageBox.setEnabled(false); + } + } + } else if (ftpMessageBox.getEnabled()) { + int + button = 0; + if (ftpMessageBox.mouseClick(x, y, button)) { + soundRenderer.playFx(coreData.getClickSoundA()); + ftpMessageBox.setEnabled(false); + + if (button == 0 + || (button == 1 && ftpMessageBox.getButtonCount() == 3)) { + if (ftpMissingDataType == ftpmsg_MissingMap) { + getMissingMapFromFTPServerInProgress = true; + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingMapNowDownloading", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString("DataMissingMapNowDownloading", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), + getMissingMapFromFTPServer.c_str()); + } else { + snprintf(szMsg, 8096, + "Player: %s is attempting to download the map: %s", + getHumanPlayerName().c_str(), + getMissingMapFromFTPServer.c_str()); + } + bool localEcho = lang.isLanguageLocal(languageList[i]); + clientInterface->sendTextMessage(szMsg, -1, localEcho, + languageList[i]); + } + + if (ftpClientThread != NULL) { + if (button == 0 && ftpMessageBox.getButtonCount() == 3) { + string mapName = getMissingMapFromFTPServer; + + MutexSafeWrapper + safeMutexThread((modHttpServerThread != + NULL ? + modHttpServerThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + string mapURL = mapCacheList[mapName].url; + safeMutexThread.ReleaseLock(); + + if (ftpClientThread != NULL) + ftpClientThread->addMapToRequests(mapName, mapURL); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? + ftpClientThread->getProgressMutex + () : NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + fileFTPProgressList[getMissingMapFromFTPServer] = + pair < int, + string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + } else { + ftpClientThread->addMapToRequests + (getMissingMapFromFTPServer); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? + ftpClientThread->getProgressMutex + () : NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + fileFTPProgressList[getMissingMapFromFTPServer] = + pair < int, + string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + } + } + } else if (ftpMissingDataType == ftpmsg_MissingTileset) { + getMissingTilesetFromFTPServerInProgress = true; + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingTilesetNowDownloading", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString + ("DataMissingTilesetNowDownloading", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), + getMissingTilesetFromFTPServer.c_str()); + } else { + snprintf(szMsg, 8096, + "Player: %s is attempting to download the tileset: %s", + getHumanPlayerName().c_str(), + getMissingTilesetFromFTPServer.c_str()); + } + bool localEcho = lang.isLanguageLocal(languageList[i]); + clientInterface->sendTextMessage(szMsg, -1, localEcho, + languageList[i]); + } + + if (ftpClientThread != NULL) { + if (button == 0 && ftpMessageBox.getButtonCount() == 3) { + string tilesetName = getMissingTilesetFromFTPServer; + + MutexSafeWrapper + safeMutexThread((modHttpServerThread != + NULL ? + modHttpServerThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + string tilesetURL = tilesetCacheList[tilesetName].url; + safeMutexThread.ReleaseLock(); + + if (ftpClientThread != NULL) + ftpClientThread->addTilesetToRequests(tilesetName, + tilesetURL); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? + ftpClientThread->getProgressMutex + () : NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + fileFTPProgressList[getMissingTilesetFromFTPServer] = + pair < int, + string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + } else { + ftpClientThread->addTilesetToRequests + (getMissingTilesetFromFTPServer); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? + ftpClientThread->getProgressMutex + () : NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + fileFTPProgressList[getMissingTilesetFromFTPServer] = + pair < int, + string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + } + } + } else if (ftpMissingDataType == ftpmsg_MissingTechtree) { + getMissingTechtreeFromFTPServerInProgress = true; + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingTechtreeNowDownloading", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString + ("DataMissingTechtreeNowDownloading", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), + getMissingTechtreeFromFTPServer.c_str()); + } else { + snprintf(szMsg, 8096, + "Player: %s is attempting to download the techtree: %s", + getHumanPlayerName().c_str(), + getMissingTechtreeFromFTPServer.c_str()); + } + bool localEcho = lang.isLanguageLocal(languageList[i]); + clientInterface->sendTextMessage(szMsg, -1, localEcho, + languageList[i]); + } + + if (ftpClientThread != NULL) { + if (button == 0 && ftpMessageBox.getButtonCount() == 3) { + string techName = getMissingTechtreeFromFTPServer; + + MutexSafeWrapper + safeMutexThread((modHttpServerThread != + NULL ? + modHttpServerThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + string techURL = techCacheList[techName].url; + safeMutexThread.ReleaseLock(); + + if (ftpClientThread != NULL) + ftpClientThread->addTechtreeToRequests(techName, + techURL); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? + ftpClientThread->getProgressMutex + () : NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + fileFTPProgressList[getMissingTechtreeFromFTPServer] = + pair < int, + string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + } else { + ftpClientThread->addTechtreeToRequests + (getMissingTechtreeFromFTPServer); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? + ftpClientThread->getProgressMutex + () : NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + fileFTPProgressList[getMissingTechtreeFromFTPServer] = + pair < int, + string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + } + } + } + } + } + } else if (buttonCancelDownloads.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + + if (ftpClientThread != NULL && fileFTPProgressList.empty() == false) { + + ftpClientThread->setCallBackObject(NULL); + ftpClientThread->signalQuit(); + sleep(0); + if (ftpClientThread->canShutdown(true) == true && + ftpClientThread->shutdownAndWait() == true) { + delete ftpClientThread; + } else { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s %d] Error cannot shutdown ftpClientThread\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("%s", szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", + szBuf); + } + ftpClientThread = NULL; + + fileFTPProgressList.clear(); + getMissingMapFromFTPServerInProgress = false; + getMissingTilesetFromFTPServerInProgress = false; + getMissingTechtreeFromFTPServerInProgress = false; + getMissingMapFromFTPServer = ""; + getMissingTilesetFromFTPServer = ""; + getMissingTechtreeFromFTPServer = ""; + getMissingMapFromFTPServerLastPrompted = 0; + getMissingTilesetFromFTPServerLastPrompted = 0; + getMissingTechtreeFromFTPServerLastPrompted = 0; + + ClientInterface * + clientInterface = networkManager.getClientInterface(); + if (clientInterface == NULL) { + throw megaglest_runtime_error("clientInterface == NULL"); + } + if (getInProgressSavedGameFromFTPServerInProgress == true) { + if (clientInterface != NULL) { + clientInterface->close(); + return; + } + } + + getInProgressSavedGameFromFTPServer = ""; + getInProgressSavedGameFromFTPServerInProgress = false; + + string serverUrl = clientInterface->getServerIpAddress(); + int + portNumber = clientInterface->getServerFTPPort(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] Using FTP port #: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, portNumber); + + Config & config = Config::getInstance(); + vector < string > mapPathList = config.getPathListForType(ptMaps); + std::pair < string, string > mapsPath; + if (mapPathList.empty() == false) { + mapsPath.first = mapPathList[0]; + } + if (mapPathList.size() > 1) { + mapsPath.second = mapPathList[1]; + } + std::pair < string, string > tilesetsPath; + vector < string > tilesetsList = + Config::getInstance().getPathListForType(ptTilesets); + if (tilesetsList.empty() == false) { + tilesetsPath.first = tilesetsList[0]; + if (tilesetsList.size() > 1) { + tilesetsPath.second = tilesetsList[1]; + } + } + + std::pair < string, string > techtreesPath; + vector < string > techtreesList = + Config::getInstance().getPathListForType(ptTechs); + if (techtreesList.empty() == false) { + techtreesPath.first = techtreesList[0]; + if (techtreesList.size() > 1) { + techtreesPath.second = techtreesList[1]; + } + } + + std::pair < string, string > scenariosPath; + vector < string > scenariosList = + Config::getInstance().getPathListForType(ptScenarios); + if (scenariosList.empty() == false) { + scenariosPath.first = scenariosList[0]; + if (scenariosList.size() > 1) { + scenariosPath.second = scenariosList[1]; + } + } + + string + fileArchiveExtension = + config.getString("FileArchiveExtension", ""); + string + fileArchiveExtractCommand = + config.getString("FileArchiveExtractCommand", ""); + string + fileArchiveExtractCommandParameters = + config.getString("FileArchiveExtractCommandParameters", ""); + int32 + fileArchiveExtractCommandSuccessResult = + config.getInt("FileArchiveExtractCommandSuccessResult", "0"); + + // Get path to temp files + string tempFilePath = "temp/"; + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + != "") { + tempFilePath = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + tempFilePath; + } else { + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + tempFilePath = userData + tempFilePath; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Temp files path [%s]\n", tempFilePath.c_str()); + + ftpClientThread = new FTPClientThread(portNumber, serverUrl, + mapsPath, tilesetsPath, + techtreesPath, scenariosPath, + this, fileArchiveExtension, + fileArchiveExtractCommand, + fileArchiveExtractCommandParameters, + fileArchiveExtractCommandSuccessResult, + tempFilePath); + ftpClientThread->start(); + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("CancelDownloadsMsg", languageList[i]) == + true) { + snprintf(szMsg, 8096, + lang.getString("CancelDownloadsMsg", + languageList[i]).c_str(), + getHumanPlayerName().c_str()); + } else { + snprintf(szMsg, 8096, + "Player: %s cancelled all file downloads.", + getHumanPlayerName().c_str()); + } + clientInterface->sendTextMessage(szMsg, -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + } + } + } else if (buttonDisconnect.mouseClick(x, y)) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + disconnectFromServer(); + networkManager.end(); + returnToJoinMenu(); + return; + } + + if (initialSettingsReceivedFromServer == false) { + return; + } + + if (activeInputLabel != NULL + && activeInputLabel->mouseClick(x, y) == false) { + setActiveInputLabel(NULL); + } + + // Only allow changes after we get game settings from the server + if (clientInterface != NULL && clientInterface->isConnected() == true) { + int + myCurrentIndex = -1; + for (int i = 0; i < GameConstants::maxPlayers; ++i) { // find my current index by looking at editable listBoxes + if ( //listBoxFactions[i].getEditable() && + clientInterface-> + getGameSettings()->getStartLocationIndex(clientInterface-> + getGameSettings + ()->getThisFactionIndex + ()) == i) { + myCurrentIndex = i; + } + } + + //printf("myCurrentIndex = %d thisFactionIndex = %d\n",myCurrentIndex,clientInterface->getGameSettings()->getThisFactionIndex()); + + if (myCurrentIndex != -1) + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + if (listBoxFactions[i].getEditable() && + clientInterface-> + getGameSettings()->getStartLocationIndex(clientInterface-> + getGameSettings + ()->getThisFactionIndex + ()) == i) { + if (listBoxFactions[i].mouseClick + (x, y, advanceToItemStartingWith)) { + soundRenderer.playFx(coreData.getClickSoundA()); + ClientInterface * + clientInterface = + NetworkManager::getInstance().getClientInterface(); + if (clientInterface->isConnected()) { + clientInterface->setGameSettingsReceived(false); + clientInterface-> + sendSwitchSetupRequest(listBoxFactions[i].getSelectedItem + (), i, -1, + listBoxTeams + [i].getSelectedItemIndex(), + getHumanPlayerName(), + getNetworkPlayerStatus(), + switchSetupRequestFlagType, + lang.getLanguage()); + switchSetupRequestFlagType = ssrft_None; + noReceiveTimer = time(NULL); + } + break; + } + } + if (listBoxTeams[i].getEditable() && + clientInterface-> + getGameSettings()->getStartLocationIndex(clientInterface-> + getGameSettings + ()->getThisFactionIndex + ()) == i) { + if (listBoxTeams[i].mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + if (clientInterface->isConnected()) { + clientInterface->setGameSettingsReceived(false); + clientInterface-> + sendSwitchSetupRequest(listBoxFactions[i].getSelectedItem + (), i, -1, + listBoxTeams + [i].getSelectedItemIndex(), + getHumanPlayerName(), + getNetworkPlayerStatus(), + switchSetupRequestFlagType, + lang.getLanguage()); + switchSetupRequestFlagType = ssrft_None; + } + break; + } + } + + bool canGrabSlot = false; + ClientInterface * + clientInterface = networkManager.getClientInterface(); + if (clientInterface != NULL + && clientInterface->getJoinGameInProgress() == true) { + canGrabSlot = + ((listBoxControls[i].getSelectedItemIndex() == ctNetwork + && labelNetStatus[i].getText() == + GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) + || (listBoxControls[i].getSelectedItemIndex() != ctHuman + && listBoxControls[i].getSelectedItemIndex() != ctClosed + && listBoxControls[i].getSelectedItemIndex() != + ctNetwork)); + } else { + canGrabSlot = + (listBoxControls[i].getSelectedItemIndex() == ctNetwork + && labelNetStatus[i].getText() == + GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME); + } + + if (canGrabSlot == true) { + if (clientInterface != NULL && i < mapInfo.players + && grabSlotButton[i].mouseClick(x, y)) { + //printf("Send slot switch request for slot = %d, myCurrentIndex = %d\n",i,myCurrentIndex); + + soundRenderer.playFx(coreData.getClickSoundB()); + clientInterface->setGameSettingsReceived(false); + settingsReceivedFromServer = false; + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] sending a switchSlot request from %d to %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, + clientInterface->getGameSettings + ()->getThisFactionIndex(), i); + + //printf("Switch slot from %d to %d\n",myCurrentIndex,i); + + string + desiredFactionName = + listBoxFactions[myCurrentIndex].getSelectedItem(); + int + desiredTeamIndex = + listBoxTeams[myCurrentIndex].getSelectedItemIndex(); + if (checkBoxScenario.getValue() == true) { + desiredFactionName = listBoxFactions[i].getSelectedItem(); + desiredTeamIndex = listBoxTeams[i].getSelectedItemIndex(); + } + + //printf("Sending switch slot request to server...\n"); + + clientInterface->sendSwitchSetupRequest(desiredFactionName, + myCurrentIndex, + i, + desiredTeamIndex, + getHumanPlayerName + (), + getNetworkPlayerStatus + (), + switchSetupRequestFlagType, + lang.getLanguage()); + labelPlayerNames[myCurrentIndex].setText(""); + labelPlayerNames[i].setText(""); + switchSetupRequestFlagType = ssrft_None; + break; + } + } + + if (labelPlayerNames[i].mouseClick(x, y) + && (activeInputLabel != &labelPlayerNames[i])) { + if (clientInterface != NULL + && i == clientInterface->getPlayerIndex()) { + setActiveInputLabel(&labelPlayerNames[i]); + } + } + } + + if (listBoxPlayerStatus.mouseClick(x, y)) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + soundRenderer.playFx(coreData.getClickSoundC()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (getNetworkPlayerStatus() == npst_PickSettings) { + listBoxPlayerStatus.setTextColor(Vec3f(1.0f, 0.0f, 0.0f)); + listBoxPlayerStatus.setLighted(true); + } else if (getNetworkPlayerStatus() == npst_BeRightBack) { + listBoxPlayerStatus.setTextColor(Vec3f(1.0f, 1.0f, 0.0f)); + listBoxPlayerStatus.setLighted(true); + } else if (getNetworkPlayerStatus() == npst_Ready) { + listBoxPlayerStatus.setTextColor(Vec3f(0.0f, 1.0f, 0.0f)); + listBoxPlayerStatus.setLighted(false); + } + + ClientInterface * + clientInterface = + NetworkManager::getInstance().getClientInterface(); + if (clientInterface != NULL && clientInterface->isConnected()) { + clientInterface->setGameSettingsReceived(false); + clientInterface->sendSwitchSetupRequest(listBoxFactions + [clientInterface-> + getPlayerIndex()]. + getSelectedItem(), + clientInterface-> + getPlayerIndex(), -1, + listBoxTeams + [clientInterface->getPlayerIndex + ()].getSelectedItemIndex + (), + getHumanPlayerName(), + getNetworkPlayerStatus + (), + switchSetupRequestFlagType, + lang.getLanguage()); + switchSetupRequestFlagType = ssrft_None; + } + } + + if (isHeadlessAdmin() == true) { + //printf("#1 admin key [%d] client key [%d]\n",settings->getMasterserver_admin(),clientInterface->getSessionKey()); + mouseClickAdmin(x, y, mouseButton, advanceToItemStartingWith); + } else if (clientInterface != NULL + && clientInterface->getJoinGameInProgress() == true) { + if (buttonPlayNow.mouseClick(x, y) && buttonPlayNow.getEnabled()) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + uint32 tilesetCRC = lastCheckedCRCTilesetValue; + uint32 techCRC = lastCheckedCRCTechtreeValue; + uint32 mapCRC = lastCheckedCRCMapValue; + const GameSettings * + gameSettings = clientInterface->getGameSettings(); + + bool + dataSynchMismatch = + ((mapCRC != 0 && mapCRC != gameSettings->getMapCRC()) + || (tilesetCRC != 0 + && tilesetCRC != gameSettings->getTilesetCRC()) + || (techCRC != 0 && techCRC != gameSettings->getTechCRC())); + if (dataSynchMismatch == false) { + PlayNow(true); + return; + } else { + showMessageBox + ("You cannot start the game because\none or more clients do not have the same game data!", + "Data Mismatch Error", false); + } + } + } + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + bool MenuStateConnectedGame::isHeadlessAdmin() { + bool result = false; + + ClientInterface * + clientInterface = + NetworkManager::getInstance().getClientInterface(); + if (clientInterface != NULL && clientInterface->isConnected()) { + const GameSettings * + settings = clientInterface->getGameSettings(); + if (settings != NULL) { + //printf("#1 admin key [%d] client key [%d]\n",settings->getMasterserver_admin(),clientInterface->getSessionKey()); + + if (settings->getMasterserver_admin() == + clientInterface->getSessionKey()) { + result = true; + } + } + } + + return result; + } + + void + MenuStateConnectedGame::broadCastGameSettingsToHeadlessServer(bool + forceNow) { + if (isHeadlessAdmin() == false) { + return; + } + + if (forceNow == true || + ((needToBroadcastServerSettings == true) + && + (difftime + ((long int) time(NULL), + broadcastServerSettingsDelayTimer) >= + HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS))) { + //printf("In [%s:%s] Line: %d forceNow = %d broadcastServerSettingsDelayTimer = " MG_SIZE_T_SPECIFIER ", now =" MG_SIZE_T_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,forceNow,broadcastServerSettingsDelayTimer,time(NULL)); + + needToBroadcastServerSettings = false; + broadcastServerSettingsDelayTimer = time(NULL); + + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + + for (int i = 0; i < mapInfo.players; ++i) { + if (listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned) { + listBoxControls[i].setSelectedItemIndex(ctNetwork); + } + } + for (int i = mapInfo.players; i < GameConstants::maxPlayers; ++i) { + if (listBoxControls[i].getSelectedItemIndex() == ctNetwork) { + listBoxControls[i].setSelectedItemIndex(ctNetworkUnassigned); + } + } + + if (validDisplayedGamesettings) { + loadGameSettings(&displayedGamesettings); + + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("broadcast settings:\n%s\n", + displayedGamesettings.toString().c_str()); + + //printf("Client sending map [%s] admin key [%d]\n",gameSettings.getMap().c_str(),gameSettings.getMasterserver_admin()); + //printf("sending Settings map filter=%d\n",displayedGamesettings.getMapFilter()); + clientInterface->broadcastGameSetup(&displayedGamesettings); + noReceiveTimer = time(NULL); + } + } + } + + void + MenuStateConnectedGame::updateResourceMultiplier(const int index) { + ControlType + ct = + static_cast + (listBoxControls[index].getSelectedItemIndex()); + if (ct == ctCpuEasy || ct == ctNetworkCpuEasy) { + listBoxRMultiplier[index].setSelectedItem(floatToStr + (GameConstants:: + easyMultiplier, 1)); + listBoxRMultiplier[index].setEnabled(true); + } else if (ct == ctCpu || ct == ctNetworkCpu) { + listBoxRMultiplier[index].setSelectedItem(floatToStr + (GameConstants:: + normalMultiplier, 1)); + listBoxRMultiplier[index].setEnabled(true); + } else if (ct == ctCpuUltra || ct == ctNetworkCpuUltra) { + listBoxRMultiplier[index].setSelectedItem(floatToStr + (GameConstants:: + ultraMultiplier, 1)); + listBoxRMultiplier[index].setEnabled(true); + } else if (ct == ctCpuZeta || ct == ctNetworkCpuZeta) { + listBoxRMultiplier[index].setSelectedItem(floatToStr + (GameConstants:: + megaMultiplier, 1)); + listBoxRMultiplier[index].setEnabled(true); + } else { + listBoxRMultiplier[index].setSelectedItem(floatToStr + (GameConstants:: + normalMultiplier, 1)); + listBoxRMultiplier[index].setEnabled(false); + } + + listBoxRMultiplier[index]. + setEditable(listBoxRMultiplier[index].getEnabled()); + listBoxRMultiplier[index]. + setVisible(listBoxRMultiplier[index].getEnabled()); + } + + void + MenuStateConnectedGame::mouseClickAdmin(int x, int y, + MouseButton mouseButton, + string advanceToItemStartingWith) { + + try { + int + oldListBoxMapfilterIndex = listBoxMapFilter.getSelectedItemIndex(); + if (buttonPlayNow.mouseClick(x, y) && buttonPlayNow.getEnabled()) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + PlayNow(true); + return; + } else if (buttonRestoreLastSettings.mouseClick(x, y) + && buttonRestoreLastSettings.getEnabled()) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + soundRenderer.playFx(coreData.getClickSoundB()); + + RestoreLastGameSettings(); + } else if (checkBoxAllowNativeLanguageTechtree.mouseClick(x, y)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } else if (listBoxMap.mouseClick(x, y, advanceToItemStartingWith)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", + getCurrentMapFile().c_str()); + + if (loadMapInfo + (Config::getMapPath(getCurrentMapFile(), "", false), &mapInfo, + true) == true) { + labelMapInfo.setText(mapInfo.desc); + } else { + labelMapInfo.setText("???"); + } + + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } else if (listBoxFogOfWar.mouseClick(x, y)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } else if (checkBoxAllowObservers.mouseClick(x, y)) { #ifdef DEBUG - PRINT_DEBUG ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); + PRINT_DEBUG("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); #endif - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } - else if (checkBoxEnableSwitchTeamMode.mouseClick (x, y)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } - else if (listBoxAISwitchTeamAcceptPercent.getEnabled () - && listBoxAISwitchTeamAcceptPercent.mouseClick (x, y)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } - else if (listBoxFallbackCpuMultiplier.getEnabled () - && listBoxFallbackCpuMultiplier.mouseClick (x, y)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } - else if (listBoxTileset.mouseClick (x, y, advanceToItemStartingWith)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } else if (checkBoxEnableSwitchTeamMode.mouseClick(x, y)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } else if (listBoxAISwitchTeamAcceptPercent.getEnabled() + && listBoxAISwitchTeamAcceptPercent.mouseClick(x, y)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } else if (listBoxFallbackCpuMultiplier.getEnabled() + && listBoxFallbackCpuMultiplier.mouseClick(x, y)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } else if (listBoxTileset.mouseClick(x, y, advanceToItemStartingWith)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } - else if (listBoxMapFilter.mouseClick (x, y)) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", - getCurrentMapFile ().c_str ()); - switchToNextMapGroup (listBoxMapFilter.getSelectedItemIndex () - - oldListBoxMapfilterIndex); - if (loadMapInfo - (Config::getMapPath (getCurrentMapFile (), "", false), &mapInfo, - true) == true) - { - labelMapInfo.setText (mapInfo.desc); - } - else - { - labelMapInfo.setText ("???"); - } - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } - else if (listBoxTechTree.mouseClick (x, y, advanceToItemStartingWith)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - reloadFactions (false, ""); - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } + else if (listBoxMapFilter.mouseClick(x, y)) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", + getCurrentMapFile().c_str()); + switchToNextMapGroup(listBoxMapFilter.getSelectedItemIndex() - + oldListBoxMapfilterIndex); + if (loadMapInfo + (Config::getMapPath(getCurrentMapFile(), "", false), &mapInfo, + true) == true) { + labelMapInfo.setText(mapInfo.desc); + } else { + labelMapInfo.setText("???"); + } + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } else if (listBoxTechTree.mouseClick(x, y, advanceToItemStartingWith)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + reloadFactions(false, ""); + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } - else if (checkBoxAllowTeamUnitSharing.mouseClick (x, y)) - { - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } - else if (checkBoxAllowTeamResourceSharing.mouseClick (x, y)) - { - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } - else - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); + else if (checkBoxAllowTeamUnitSharing.mouseClick(x, y)) { + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } else if (checkBoxAllowTeamResourceSharing.mouseClick(x, y)) { + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); - for (int i = 0; i < mapInfo.players; ++i) - { -// set multiplier - if (listBoxRMultiplier[i].mouseClick (x, y)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); -//broadCastGameSettingsToMasterserver(); - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } + for (int i = 0; i < mapInfo.players; ++i) { + // set multiplier + if (listBoxRMultiplier[i].mouseClick(x, y)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + //broadCastGameSettingsToMasterserver(); + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } -//ensure that only 1 human player is present - if (clientInterface != NULL - && clientInterface->getGameSettings () != NULL - && clientInterface-> - getGameSettings ()->getStartLocationIndex (clientInterface-> - getGameSettings - ()->getThisFactionIndex - ()) != i - && listBoxControls[i].mouseClick (x, y)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); + //ensure that only 1 human player is present + if (clientInterface != NULL + && clientInterface->getGameSettings() != NULL + && clientInterface-> + getGameSettings()->getStartLocationIndex(clientInterface-> + getGameSettings + ()->getThisFactionIndex + ()) != i + && listBoxControls[i].mouseClick(x, y)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); -//!! this must be done two times!"" - if (listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned) - { - listBoxControls[i].mouseClick (x, y); - } - if ((isHeadlessAdmin () == true) - && (listBoxControls[i].getSelectedItemIndex () == ctHuman)) - { - listBoxControls[i].mouseClick (x, y); - } -//!! this must be done two times!"" - if (listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned) - { - listBoxControls[i].mouseClick (x, y); - } + //!! this must be done two times!"" + if (listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned) { + listBoxControls[i].mouseClick(x, y); + } + if ((isHeadlessAdmin() == true) + && (listBoxControls[i].getSelectedItemIndex() == ctHuman)) { + listBoxControls[i].mouseClick(x, y); + } + //!! this must be done two times!"" + if (listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned) { + listBoxControls[i].mouseClick(x, y); + } - updateResourceMultiplier (i); + updateResourceMultiplier(i); - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } - else if (clientInterface != NULL - && clientInterface-> - getGameSettings ()->getStartLocationIndex - (clientInterface->getGameSettings ()->getThisFactionIndex - ()) != i - && listBoxFactions[i].mouseClick (x, y, - advanceToItemStartingWith)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); -// Disallow CPU players to be observers - if (factionFiles[listBoxFactions[i].getSelectedItemIndex ()] == - formatString (GameConstants::OBSERVER_SLOTNAME) - && (listBoxControls[i].getSelectedItemIndex () == ctCpuEasy - || listBoxControls[i].getSelectedItemIndex () == ctCpu - || listBoxControls[i].getSelectedItemIndex () == - ctCpuUltra - || listBoxControls[i].getSelectedItemIndex () == - ctCpuZeta)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - listBoxFactions[i].setSelectedItemIndex (0); - } + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } else if (clientInterface != NULL + && clientInterface-> + getGameSettings()->getStartLocationIndex + (clientInterface->getGameSettings()->getThisFactionIndex + ()) != i + && listBoxFactions[i].mouseClick(x, y, + advanceToItemStartingWith)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + // Disallow CPU players to be observers + if (factionFiles[listBoxFactions[i].getSelectedItemIndex()] == + formatString(GameConstants::OBSERVER_SLOTNAME) + && (listBoxControls[i].getSelectedItemIndex() == ctCpuEasy + || listBoxControls[i].getSelectedItemIndex() == ctCpu + || listBoxControls[i].getSelectedItemIndex() == + ctCpuUltra + || listBoxControls[i].getSelectedItemIndex() == + ctCpuZeta)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + listBoxFactions[i].setSelectedItemIndex(0); + } - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } - else if (clientInterface != NULL - && clientInterface-> - getGameSettings ()->getStartLocationIndex - (clientInterface->getGameSettings ()->getThisFactionIndex - ()) != i && listBoxTeams[i].mouseClick (x, y)) - { + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } else if (clientInterface != NULL + && clientInterface-> + getGameSettings()->getStartLocationIndex + (clientInterface->getGameSettings()->getThisFactionIndex + ()) != i && listBoxTeams[i].mouseClick(x, y)) { #ifdef DEBUG - PRINT_DEBUG ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); + PRINT_DEBUG("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); #endif - if (factionFiles[listBoxFactions[i].getSelectedItemIndex ()] != - formatString (GameConstants::OBSERVER_SLOTNAME)) - { - if (listBoxTeams[i].getSelectedItemIndex () + 1 != - (GameConstants::maxPlayers + fpt_Observer)) - { -//lastSelectedTeamIndex[i] = listBoxTeams[i].getSelectedItemIndex(); - } - } - - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - } - } - } - } - catch (const std::exception & ex) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - showMessageBox (szBuf, "Error", false); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - void - MenuStateConnectedGame::PlayNow (bool saveGame) - { - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - - GameSettings gameSettings = *clientInterface->getGameSettings (); - loadGameSettings (&gameSettings); - - if (saveGame == true) - { - CoreData:: - getInstance ().saveGameSettingsToFile (HEADLESS_SAVED_GAME_FILENAME, - &gameSettings, true); - } - - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - soundRenderer.playFx (coreData.getClickSoundC ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//printf("Client sending map [%s] admin key [%d]\n",gameSettings.getMap().c_str(),gameSettings.getMasterserver_admin()); - - if (clientInterface->getJoinGameInProgress () == true) - { - if (readyToJoinInProgressGame == false && launchingNewGame == false) - { - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("JoinPlayerToCurrentGameLaunch", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString ("JoinPlayerToCurrentGameLaunch", - languageList[i]).c_str (), - getHumanPlayerName ().c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Player: %s is about to join the game, please wait...", - getHumanPlayerName ().c_str ()); - } - bool localEcho = lang.isLanguageLocal (languageList[i]); - clientInterface->sendTextMessage (szMsg, -1, localEcho, - languageList[i]); - } - - sleep (1); - launchingNewGame = true; - clientInterface->broadcastGameStart (&gameSettings); - } - return; - } - else - { - launchingNewGame = true; - broadCastGameSettingsToHeadlessServer (needToBroadcastServerSettings); - clientInterface->broadcastGameStart (&gameSettings); - } - } - - void - MenuStateConnectedGame::switchToNextMapGroup (const int direction) - { - int - i = listBoxMapFilter.getSelectedItemIndex (); -// if there are no maps for the current selection we switch to next selection - while (formattedPlayerSortedMaps[i].empty ()) - { - i = i + direction; - if (i > GameConstants::maxPlayers) - { - i = 0; - } - if (i < 0) - { - i = GameConstants::maxPlayers; - } - } - switchToMapGroup (i); - } - - void - MenuStateConnectedGame::switchToMapGroup (int filterIndex) - { - int - i = filterIndex; - listBoxMapFilter.setSelectedItemIndex (i); - listBoxMap.setItems (formattedPlayerSortedMaps[i]); -// printf("switching map group to filter=%d mapgroup has %d maps. map=%s \n",i, -// (int)formattedPlayerSortedMaps[i].size(),formattedPlayerSortedMaps[i][0].c_str()); - } - - string MenuStateConnectedGame::getCurrentMapFile () - { - int - i = listBoxMapFilter.getSelectedItemIndex (); - int - mapIndex = listBoxMap.getSelectedItemIndex (); - if (playerSortedMaps[i].empty () == false) - { - return playerSortedMaps[i].at (mapIndex); - } - return ""; - } - - void - MenuStateConnectedGame::reloadFactions (bool keepExistingSelectedItem, - string scenario) - { - vector < string > results; - Config & config = Config::getInstance (); - Lang & lang = Lang::getInstance (); - - string scenarioDir = Scenario::getScenarioDir (dirList, scenario); - vector < string > techPaths = - config.getPathListForType (ptTechs, scenarioDir); - for (int idx = 0; idx < (int) techPaths.size (); idx++) - { - string & techPath = techPaths[idx]; - endPathWithSlash (techPath); - - if (listBoxTechTree.getSelectedItemIndex () >= 0 - && listBoxTechTree.getSelectedItemIndex () < - (int) techTreeFiles.size ()) - { - findDirs (techPath + - techTreeFiles[listBoxTechTree.getSelectedItemIndex ()] + - "/factions/", results, false, false); - } - if (results.empty () == false) - { - break; - } - } - - if (results.empty () == true) - { -//throw megaglest_runtime_error("(2)There are no factions for the tech tree [" + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "]"); -//showGeneralError=true; -//generalErrorToShow = "[#2] There are no factions for the tech tree [" + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "]"; - } - - vector < string > translatedFactionNames; - factionFiles = results; - for (int i = 0; i < (int) results.size (); ++i) - { - results[i] = formatString (results[i]); - string - translatedString = - techTree->getTranslatedFactionName (techTreeFiles - [listBoxTechTree. - getSelectedItemIndex ()], - factionFiles[i]); - if (toLower (translatedString) == toLower (results[i])) - { - translatedFactionNames.push_back (results[i]); - } - else - { - translatedFactionNames.push_back (results[i] + " (" + - translatedString + ")"); - } -//printf("FACTIONS i = %d results [%s]\n",i,results[i].c_str()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "Tech [%s] has faction [%s]\n", - techTreeFiles - [listBoxTechTree.getSelectedItemIndex - ()].c_str (), results[i].c_str ()); - } - - results.push_back (formatString - (GameConstants::RANDOMFACTION_SLOTNAME)); - factionFiles.push_back (formatString - (GameConstants::RANDOMFACTION_SLOTNAME)); - translatedFactionNames.push_back ("*" + - lang.getString ("Random", "", - true) + "*"); - -// Add special Observer Faction - if (checkBoxAllowObservers.getValue () == 1) - { - results.push_back (formatString (GameConstants::OBSERVER_SLOTNAME)); - factionFiles.push_back (formatString - (GameConstants::OBSERVER_SLOTNAME)); - translatedFactionNames.push_back ("*" + - lang.getString ("Observer", "", - true) + "*"); - } - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - int - originalIndex = listBoxFactions[i].getSelectedItemIndex (); - string - originalValue = - (listBoxFactions[i].getItemCount () > - 0 ? listBoxFactions[i].getSelectedItem () : ""); - - listBoxFactions[i].setItems (results, translatedFactionNames); - if (keepExistingSelectedItem == false || - (checkBoxAllowObservers.getValue () == true && - originalValue == - formatString (GameConstants::OBSERVER_SLOTNAME))) - { - listBoxFactions[i].setSelectedItemIndex (i % results.size ()); - - if (originalValue == formatString (GameConstants::OBSERVER_SLOTNAME) - && listBoxFactions[i].getSelectedItem () != - formatString (GameConstants::OBSERVER_SLOTNAME)) - { - if (listBoxTeams[i].getSelectedItem () == - intToStr (GameConstants::maxPlayers + fpt_Observer)) - { - listBoxTeams[i].setSelectedItem (intToStr (1)); - } - } - } - else if (originalIndex < (int) results.size ()) - { - listBoxFactions[i].setSelectedItemIndex (originalIndex); - } - } - } - - void - MenuStateConnectedGame::loadGameSettings (GameSettings * gameSettings) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - int - factionCount = 0; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -// Test flags values -//gameSettings->setFlagTypes1(ft1_show_map_resources); -// - - if (checkBoxScenario.getValue () == true) - { - gameSettings->setScenario (scenarioInfo.name); - gameSettings->setScenarioDir (Scenario::getScenarioPath - (dirList, scenarioInfo.name)); - - gameSettings->setDefaultResources (scenarioInfo.defaultResources); - gameSettings->setDefaultUnits (scenarioInfo.defaultUnits); - gameSettings-> - setDefaultVictoryConditions (scenarioInfo.defaultVictoryConditions); - } - else - { - gameSettings->setScenario (""); - gameSettings->setScenarioDir (""); - } - - gameSettings->setNetworkAllowNativeLanguageTechtree - (checkBoxAllowNativeLanguageTechtree.getValue ()); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line %d] listBoxMap.getSelectedItemIndex() = %d, mapFiles.size() = " - MG_SIZE_T_SPECIFIER ", getCurrentMapFile() [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), __FUNCTION__, - __LINE__, listBoxMap.getSelectedItemIndex (), mapFiles.size (), - getCurrentMapFile ().c_str ()); - - if (listBoxMap.getSelectedItemIndex () >= 0 - && listBoxMap.getSelectedItemIndex () < (int) mapFiles.size ()) - { - gameSettings->setDescription (formatString (getCurrentMapFile ())); - gameSettings->setMap (getCurrentMapFile ()); - gameSettings->setMapFilter (listBoxMapFilter.getSelectedItemIndex ()); - } - else - { - Lang & lang = Lang::getInstance (); - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingMap=Player", languageList[i]) == - true) - { - snprintf (szMsg, 8096, - lang.getString ("DataMissingMap=Player", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), - listBoxMap.getSelectedItem ().c_str ()); - } - else - { - snprintf (szMsg, 8096, "Player: %s is missing the map: %s", - getHumanPlayerName ().c_str (), - listBoxMap.getSelectedItem ().c_str ()); - } - bool localEcho = lang.isLanguageLocal (languageList[i]); - clientInterface->sendTextMessage (szMsg, -1, localEcho, - languageList[i]); - } - } - - if (listBoxTileset.getSelectedItemIndex () >= 0 - && listBoxTileset.getSelectedItemIndex () < - (int) tilesetFiles.size ()) - { - gameSettings->setTileset (tilesetFiles - [listBoxTileset.getSelectedItemIndex ()]); - } - else - { -//printf("A loadGameSettings listBoxTileset.getSelectedItemIndex() = %d tilesetFiles.size() = %d\n",listBoxTileset.getSelectedItemIndex(),tilesetFiles.size()); - - Lang & lang = Lang::getInstance (); - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingTileset=Player", languageList[i]) == - true) - { - snprintf (szMsg, 8096, - lang.getString ("DataMissingTileset=Player", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), - listBoxTileset.getSelectedItem ().c_str ()); - } - else - { - snprintf (szMsg, 8096, "Player: %s is missing the tileset: %s", - getHumanPlayerName ().c_str (), - listBoxTileset.getSelectedItem ().c_str ()); - } - bool localEcho = lang.isLanguageLocal (languageList[i]); - clientInterface->sendTextMessage (szMsg, -1, localEcho, - languageList[i]); - } - } - if (listBoxTechTree.getSelectedItemIndex () >= 0 - && listBoxTechTree.getSelectedItemIndex () < - (int) techTreeFiles.size ()) - { - gameSettings->setTech (techTreeFiles - [listBoxTechTree.getSelectedItemIndex ()]); - } - else - { - Lang & lang = Lang::getInstance (); - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingTechtree=Player", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString ("DataMissingTechtree=Player", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), - listBoxTechTree.getSelectedItem ().c_str ()); - } - else - { - snprintf (szMsg, 8096, "Player: %s is missing the techtree: %s", - getHumanPlayerName ().c_str (), - listBoxTechTree.getSelectedItem ().c_str ()); - } - bool localEcho = lang.isLanguageLocal (languageList[i]); - clientInterface->sendTextMessage (szMsg, -1, localEcho, - languageList[i]); - } - } - - if (checkBoxScenario.getValue () == false) - { - gameSettings->setDefaultUnits (true); - gameSettings->setDefaultResources (true); - gameSettings->setDefaultVictoryConditions (true); - } - - gameSettings->setFogOfWar (listBoxFogOfWar.getSelectedItemIndex () == 0 - || listBoxFogOfWar.getSelectedItemIndex () == - 1); - - gameSettings->setAllowObservers (checkBoxAllowObservers.getValue () == - true); - - uint32 valueFlags1 = gameSettings->getFlagTypes1 (); - if (listBoxFogOfWar.getSelectedItemIndex () == 1 || - listBoxFogOfWar.getSelectedItemIndex () == 2) - { - valueFlags1 |= ft1_show_map_resources; - gameSettings->setFlagTypes1 (valueFlags1); - } - else - { - valueFlags1 &= ~ft1_show_map_resources; - gameSettings->setFlagTypes1 (valueFlags1); - } - -//gameSettings->setEnableObserverModeAtEndGame(listBoxEnableObserverMode.getSelectedItemIndex() == 0); - gameSettings->setEnableObserverModeAtEndGame (true); -//gameSettings->setPathFinderType(static_cast(listBoxPathFinderType.getSelectedItemIndex())); - - valueFlags1 = gameSettings->getFlagTypes1 (); - if (checkBoxEnableSwitchTeamMode.getValue () == true) - { - valueFlags1 |= ft1_allow_team_switching; - gameSettings->setFlagTypes1 (valueFlags1); - } - else - { - valueFlags1 &= ~ft1_allow_team_switching; - gameSettings->setFlagTypes1 (valueFlags1); - } - gameSettings->setAiAcceptSwitchTeamPercentChance (strToInt - (listBoxAISwitchTeamAcceptPercent.getSelectedItem - ())); - gameSettings-> - setFallbackCpuMultiplier - (listBoxFallbackCpuMultiplier.getSelectedItemIndex ()); - - valueFlags1 = gameSettings->getFlagTypes1 (); - if (checkBoxAllowTeamUnitSharing.getValue () == true) - { - valueFlags1 |= ft1_allow_shared_team_units; - gameSettings->setFlagTypes1 (valueFlags1); - } - else - { - valueFlags1 &= ~ft1_allow_shared_team_units; - gameSettings->setFlagTypes1 (valueFlags1); - } - - valueFlags1 = gameSettings->getFlagTypes1 (); - if (checkBoxAllowTeamResourceSharing.getValue () == true) - { - valueFlags1 |= ft1_allow_shared_team_resources; - gameSettings->setFlagTypes1 (valueFlags1); - } - else - { - valueFlags1 &= ~ft1_allow_shared_team_resources; - gameSettings->setFlagTypes1 (valueFlags1); - } - -// First save Used slots -//for(int i=0; i - (listBoxControls[i].getSelectedItemIndex ()); - - if (ct != ctClosed) - { - int - slotIndex = factionCount; - ControlType - oldControlType = gameSettings->getFactionControl (slotIndex); - gameSettings->setFactionControl (slotIndex, ct); - if (ct == ctHuman) - { -//if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, slotIndex = %d, getHumanPlayerName(i) [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,slotIndex,getHumanPlayerName(i).c_str()); - - gameSettings->setThisFactionIndex (slotIndex); - gameSettings->setNetworkPlayerName (slotIndex, - getHumanPlayerName ()); - gameSettings->setNetworkPlayerUUID (slotIndex, - Config:: - getInstance ().getString - ("PlayerId", "")); - gameSettings->setNetworkPlayerPlatform (slotIndex, - getPlatformNameString ()); - gameSettings->setNetworkPlayerStatuses (slotIndex, - getNetworkPlayerStatus - ()); - Lang & lang = Lang::getInstance (); - gameSettings->setNetworkPlayerLanguages (slotIndex, - lang.getLanguage ()); - - gameSettings->setResourceMultiplierIndex (slotIndex, 5); - } - else - { - gameSettings->setResourceMultiplierIndex (slotIndex, - listBoxRMultiplier - [i].getSelectedItemIndex - ()); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] i = %d, factionFiles[listBoxFactions[i].getSelectedItemIndex()] [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, i, - factionFiles[listBoxFactions - [i].getSelectedItemIndex - ()].c_str ()); - - gameSettings->setFactionTypeName (slotIndex, - factionFiles[listBoxFactions - [i].getSelectedItemIndex - ()]); - if (factionFiles[listBoxFactions[i].getSelectedItemIndex ()] == - formatString (GameConstants::OBSERVER_SLOTNAME)) - { - listBoxTeams[i].setSelectedItem (intToStr - (GameConstants::maxPlayers + - fpt_Observer)); - } - - gameSettings->setTeam (slotIndex, - listBoxTeams[i].getSelectedItemIndex ()); - gameSettings->setStartLocationIndex (slotIndex, i); -//printf("!!! setStartLocationIndex #1 slotIndex = %d, i = %d\n",slotIndex, i); - - if (listBoxControls[i].getSelectedItemIndex () == ctNetwork - || listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned) - { - if (oldControlType != ctNetwork - && oldControlType != ctNetworkUnassigned) - { - gameSettings->setNetworkPlayerName (slotIndex, ""); - } - } - else if (listBoxControls[i].getSelectedItemIndex () != ctHuman) - { - AIPlayerCount++; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] i = %d, playername is AI (blank)\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, i); - - Lang & lang = Lang::getInstance (); - gameSettings->setNetworkPlayerName (slotIndex, - lang.getString ("AI") + - intToStr (AIPlayerCount)); - labelPlayerNames[i].setText (""); - } - - factionCount++; - } - else - { - labelPlayerNames[i].setText (""); - } - } - -// Next save closed slots - int - closedCount = 0; - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - ControlType - ct = - static_cast < ControlType > - (listBoxControls[i].getSelectedItemIndex ()); - if (ct == ctClosed) - { - int - slotIndex = factionCount + closedCount; - - gameSettings->setFactionControl (slotIndex, ct); - gameSettings->setTeam (slotIndex, - listBoxTeams[i].getSelectedItemIndex ()); - gameSettings->setStartLocationIndex (slotIndex, i); -//printf("!!! setStartLocationIndex #2 slotIndex = %d, i = %d\n",slotIndex, i); - - gameSettings->setResourceMultiplierIndex (slotIndex, 5); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] i = %d, factionFiles[listBoxFactions[i].getSelectedItemIndex()] [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, i, - factionFiles[listBoxFactions - [i].getSelectedItemIndex - ()].c_str ()); - - gameSettings->setFactionTypeName (slotIndex, - factionFiles[listBoxFactions - [i].getSelectedItemIndex - ()]); - gameSettings->setNetworkPlayerStatuses (slotIndex, npst_None); - gameSettings->setNetworkPlayerName (slotIndex, - GameConstants::NETWORK_SLOT_CLOSED_SLOTNAME); - - closedCount++; - } - } - - gameSettings->setFactionCount (factionCount); - - Config & config = Config::getInstance (); - gameSettings->setEnableServerControlledAI (config.getBool - ("ServerControlledAI", - "true")); - gameSettings-> - setNetworkFramePeriod (config.getInt ("NetworkSendFrameCount", "20")); - - if (hasNetworkGameSettings () == true) - { - if (gameSettings->getTileset () != "") - { - if (lastCheckedCRCTilesetName != gameSettings->getTileset ()) - { -//console.addLine("Checking tileset CRC [" + gameSettings->getTileset() + "]"); - lastCheckedCRCTilesetValue = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTilesets, ""), - string ("/") + gameSettings->getTileset () + string ("/*"), - ".xml", NULL); - if (lastCheckedCRCTilesetValue == 0 - || lastCheckedCRCTilesetValue != - gameSettings->getTilesetCRC ()) - { - lastCheckedCRCTilesetValue = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTilesets, ""), - string ("/") + gameSettings->getTileset () + string ("/*"), - ".xml", NULL, true); - } - lastCheckedCRCTilesetName = gameSettings->getTileset (); - } - gameSettings->setTilesetCRC (lastCheckedCRCTilesetValue); - } - - if (config.getBool ("DisableServerLobbyTechtreeCRCCheck", "false") == - false) - { - if (gameSettings->getTech () != "") - { - if (lastCheckedCRCTechtreeName != gameSettings->getTech ()) - { -//console.addLine("Checking techtree CRC [" + gameSettings->getTech() + "]"); - lastCheckedCRCTechtreeValue = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), - "/" + gameSettings->getTech () + "/*", ".xml", NULL); - if (lastCheckedCRCTechtreeValue == 0 - || lastCheckedCRCTechtreeValue != - gameSettings->getTechCRC ()) - { - lastCheckedCRCTechtreeValue = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), - "/" + gameSettings->getTech () + "/*", ".xml", NULL, true); - } - - reloadFactions (true, gameSettings->getScenario ()); - factionCRCList.clear (); - for (unsigned int factionIdx = 0; - factionIdx < factionFiles.size (); ++factionIdx) - { - string factionName = factionFiles[factionIdx]; - if (factionName != GameConstants::RANDOMFACTION_SLOTNAME && - factionName != GameConstants::OBSERVER_SLOTNAME) - { -//factionCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + gameSettings->getTech() + "/factions/" + factionName + "/*", ".xml", NULL, true); - uint32 - factionCRC = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), - "/" + gameSettings->getTech () + "/factions/" + - factionName + "/*", ".xml", NULL); - if (factionCRC == 0) - { - factionCRC = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), - "/" + gameSettings->getTech () + "/factions/" + - factionName + "/*", ".xml", NULL, true); - } - factionCRCList.push_back (make_pair - (factionName, factionCRC)); - } - } -//console.addLine("Found factions: " + intToStr(factionCRCList.size())); - lastCheckedCRCTechtreeName = gameSettings->getTech (); - } - - gameSettings->setFactionCRCList (factionCRCList); - gameSettings->setTechCRC (lastCheckedCRCTechtreeValue); - } - } - - if (gameSettings->getMap () != "") - { - if (lastCheckedCRCMapName != gameSettings->getMap ()) - { - Checksum checksum; - string - file = Config::getMapPath (gameSettings->getMap (), "", false); -//console.addLine("Checking map CRC [" + file + "]"); - checksum.addFile (file); - lastCheckedCRCMapValue = checksum.getSum (); - lastCheckedCRCMapName = gameSettings->getMap (); - } - gameSettings->setMapCRC (lastCheckedCRCMapValue); - } - } - -//replace server player by network - for (int i = 0; i < gameSettings->getFactionCount (); ++i) - { -//replace by network - if (gameSettings->getFactionControl (i) == ctHuman) - { - gameSettings->setFactionControl (i, ctNetwork); - } - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - void - MenuStateConnectedGame::returnToJoinMenu () - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (modHttpServerThread != NULL) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - modHttpServerThread->setSimpleTaskInterfaceValid (false); - modHttpServerThread->signalQuit (); -//modHttpServerThread->setThreadOwnerValid(false); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - if (modHttpServerThread->canShutdown (true) == true - && modHttpServerThread->shutdownAndWait () == true) - { - delete modHttpServerThread; - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - modHttpServerThread = NULL; - } - - if (ftpClientThread != NULL) - { - - ftpClientThread->setCallBackObject (NULL); - ftpClientThread->signalQuit (); - sleep (0); - if (ftpClientThread->canShutdown (true) == true && - ftpClientThread->shutdownAndWait () == true) - { - delete ftpClientThread; - } - else - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s %d] Error cannot shutdown ftpClientThread\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("%s", szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - } - ftpClientThread = NULL; - } - - if (returnMenuInfo == jmSimple) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - launchingNewGame = true; - disconnectFromServer (); - mainMenu->setState (new MenuStateJoinGame (program, mainMenu)); - } - else - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - launchingNewGame = true; - disconnectFromServer (); - mainMenu->setState (new MenuStateMasterserver (program, mainMenu)); - } - } - - void - MenuStateConnectedGame::mouseMove (int x, int y, const MouseState * ms) - { - if (mainMessageBox.getEnabled ()) - { - mainMessageBox.mouseMove (x, y); - } - - if (ftpMessageBox.getEnabled ()) - { - ftpMessageBox.mouseMove (x, y); - } - - buttonCancelDownloads.mouseMove (x, y); - buttonDisconnect.mouseMove (x, y); - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - listBoxControls[i].mouseMove (x, y); - listBoxFactions[i].mouseMove (x, y); - listBoxTeams[i].mouseMove (x, y); - grabSlotButton[i].mouseMove (x, y); - } - - listBoxMap.mouseMove (x, y); - listBoxFogOfWar.mouseMove (x, y); - checkBoxAllowObservers.mouseMove (x, y); - listBoxTileset.mouseMove (x, y); - listBoxMapFilter.mouseMove (x, y); - listBoxTechTree.mouseMove (x, y); - listBoxPlayerStatus.mouseMove (x, y); - - checkBoxScenario.mouseMove (x, y); - listBoxScenario.mouseMove (x, y); - - labelAllowTeamUnitSharing.mouseMove (x, y); - checkBoxAllowTeamUnitSharing.mouseMove (x, y); - labelAllowTeamResourceSharing.mouseMove (x, y); - checkBoxAllowTeamResourceSharing.mouseMove (x, y); - - checkBoxAllowNativeLanguageTechtree.mouseMove (x, y); - - buttonPlayNow.mouseMove (x, y); - buttonRestoreLastSettings.mouseMove (x, y); - } - - bool MenuStateConnectedGame::isVideoPlaying () - { - bool result = false; - if (factionVideo != NULL) - { - result = factionVideo->isPlaying (); - } - return result; - } - - void - MenuStateConnectedGame::render () - { - try - { - Renderer & renderer = Renderer::getInstance (); - - if (mainMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&mainMessageBox); - } - - renderer.renderButton (&buttonDisconnect); - - if (initialSettingsReceivedFromServer == false) - { - return; - } - - if (factionTexture != NULL) - { - if (factionVideo == NULL || factionVideo->isPlaying () == false) - { - renderer.renderTextureQuad (800, 600, 200, 150, factionTexture, - 1); - } - } - if (factionVideo != NULL) - { - if (factionVideo->isPlaying () == true) - { - factionVideo->playFrame (false); - } - else - { - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false - &&::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer () == - true) - { - if (factionVideo != NULL) - { - factionVideo->closePlayer (); - delete factionVideo; - factionVideo = NULL; - - if (validDisplayedGamesettings) - { - initFactionPreview (&displayedGamesettings); - } - } - } - } - } - - if (mapPreviewTexture != NULL) - { -//renderer.renderTextureQuad(5,185,150,150,mapPreviewTexture,1.0f); - renderer.renderTextureQuad (this->render_mapPreviewTexture_X, - this->render_mapPreviewTexture_Y, - this->render_mapPreviewTexture_W, - this->render_mapPreviewTexture_H, - mapPreviewTexture, 1.0f); - if (this->zoomedMap == true) - { - return; - } -//printf("=================> Rendering map preview texture\n"); - } - - if (scenarioLogoTexture != NULL) - { - renderer.renderTextureQuad (300, 350, 400, 300, scenarioLogoTexture, - 1.0f); -//renderer.renderBackground(scenarioLogoTexture); - } - - renderer.renderButton (&buttonDisconnect); - -// Get a reference to the player texture cache - std::map < int, - Texture2D * >& - crcPlayerTextureCache = - CacheManager::getCachedItem < std::map < int, - Texture2D * > >(GameConstants::playerTextureCacheLookupKey); - -// START - this code ensure player title and player names don't overlap - int - offsetPosition = 0; - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - const - Metrics & - metrics = Metrics::getInstance (); - FontMetrics * - fontMetrics = NULL; - if (Renderer::renderText3DEnabled == false) - { - fontMetrics = - CoreData::getInstance ().getMenuFontNormal ()->getMetrics (); - } - else - { - fontMetrics = - CoreData::getInstance ().getMenuFontNormal3D ()->getMetrics (); - } - - if (fontMetrics == NULL) - { - throw megaglest_runtime_error ("fontMetrics == NULL"); - } - int - curWidth = - (metrics.toVirtualX - (fontMetrics->getTextWidth (labelPlayers[i].getText ()))); - - if (labelPlayers[i].getX () + curWidth >= - labelPlayerNames[i].getX ()) - { - int - newOffsetPosition = labelPlayers[i].getX () + curWidth + 2; - if (offsetPosition < newOffsetPosition) - { - offsetPosition = newOffsetPosition; - } - } - } -// END - - renderer.renderListBox (&listBoxPlayerStatus); - - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - if (listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned) - { - bool renderIt = true; -//printf("Player #%d [%s] control = %d\n",i,labelPlayerNames[i].getText().c_str(),listBoxControls[i].getSelectedItemIndex()); - if (labelNetStatus[i].getText () == - GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) - { - renderIt = false; - } - labelPlayers[i].setVisible (renderIt); - labelPlayerNames[i].setVisible (renderIt); - listBoxControls[i].setVisible (renderIt); - listBoxRMultiplier[i].setVisible (renderIt); - listBoxFactions[i].setVisible (renderIt); - listBoxTeams[i].setVisible (renderIt); - labelNetStatus[i].setVisible (renderIt); - } - - if (listBoxControls[i].getSelectedItemIndex () != ctClosed) - { - renderer.renderLabel (&labelPlayerStatus[i]); - } - - if (crcPlayerTextureCache[i] != NULL) - { -// Render the player # label the player's color - - Vec3f - playerColor = - crcPlayerTextureCache[i]->getPixmap ()->getPixel3f (0, 0); - if (clientInterface != NULL - && clientInterface->getGameSettings () != NULL - && clientInterface-> - getGameSettings ()->getMasterserver_admin () > 0 - && clientInterface-> - getGameSettings ()->getMasterserver_admin_faction_index () == - i) - { - - if (difftime ((long int) time (NULL), timerLabelFlash) < 1) - { - renderer.renderLabel (&labelPlayers[i], &playerColor); - } - else - { - Vec4f - flashColor = - Vec4f (playerColor.x, playerColor.y, playerColor.z, 0.45f); - renderer.renderLabel (&labelPlayers[i], &flashColor); - } - - } - else - { - renderer.renderLabel (&labelPlayers[i], &playerColor); - } - -// Blend the color with white so make it more readable -//Vec4f newColor(1.f, 1.f, 1.f, 0.57f); -//renderer.renderLabel(&labelPlayers[i],&newColor); - -//int quadWidth = labelPlayerNames[i].getX() - labelPlayers[i].getX() - 5; -//renderer.renderTextureQuad(labelPlayers[i].getX(), labelPlayers[i].getY(), quadWidth, labelPlayers[i].getH(), crcPlayerTextureCache[i],1.0f,&playerColor); - } - else - { - renderer.renderLabel (&labelPlayers[i]); - } - - if (offsetPosition > 0) - { - labelPlayerNames[i].setX (offsetPosition); - } - - renderer.renderListBox (&listBoxControls[i]); - if (listBoxControls[i].getSelectedItemIndex () != ctClosed) - { - renderer.renderListBox (&listBoxRMultiplier[i]); - renderer.renderListBox (&listBoxFactions[i]); - int - teamnumber = listBoxTeams[i].getSelectedItemIndex (); - Vec3f teamcolor = Vec3f (1.0f, 1.0f, 1.0f); - if (teamnumber >= 0 && teamnumber < 8) - { - teamcolor = - crcPlayerTextureCache[teamnumber]-> - getPixmap ()->getPixel3f (0, 0); - } - listBoxTeams[i].setTextColor (teamcolor); - renderer.renderListBox (&listBoxTeams[i]); - - bool canGrabSlot = false; - ClientInterface * - clientInterface = networkManager.getClientInterface (); - if (clientInterface != NULL - && clientInterface->getJoinGameInProgress () == true) - { - canGrabSlot = - ((listBoxControls[i].getSelectedItemIndex () == ctNetwork - && labelNetStatus[i].getText () == - GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) - || (listBoxControls[i].getSelectedItemIndex () != ctHuman - && listBoxControls[i].getSelectedItemIndex () != ctClosed - && listBoxControls[i].getSelectedItemIndex () != - ctNetwork)); - } - else - { - canGrabSlot = - (listBoxControls[i].getSelectedItemIndex () == ctNetwork - && labelNetStatus[i].getText () == - GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME); - } - - if (canGrabSlot == true) - { - if (i < mapInfo.players) - { - renderer.renderButton (&grabSlotButton[i]); - } - } - else if (listBoxControls[i].getSelectedItemIndex () == ctNetwork - || listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned - || listBoxControls[i].getSelectedItemIndex () == ctHuman) - { - renderer.renderLabel (&labelNetStatus[i]); - } - - if (listBoxControls[i].getSelectedItemIndex () == ctNetwork || - listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned - || listBoxControls[i].getSelectedItemIndex () == ctHuman) - { - if (labelNetStatus[i].getText () != - GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) - { - renderer.renderLabel (&labelPlayerNames[i]); - } - } - } - } - renderer.renderLabel (&labelStatus); - renderer.renderLabel (&labelInfo); - - if (difftime ((long int) time (NULL), timerLabelFlash) < 1) - { - renderer.renderLabel (&labelDataSynchInfo, &RED); - renderer.renderLabel (&labelWaitingForPlayers, &YELLOW); - } - else - { - renderer.renderLabel (&labelDataSynchInfo, &WHITE); - renderer.renderLabel (&labelWaitingForPlayers, &WHITE); - } - - renderer.renderLabel (&labelMap); - renderer.renderLabel (&labelMapFilter); - renderer.renderLabel (&labelFogOfWar); - renderer.renderLabel (&labelAllowObservers); - renderer.renderLabel (&labelFallbackCpuMultiplier); - renderer.renderLabel (&labelTileset); - renderer.renderLabel (&labelTechTree); - renderer.renderLabel (&labelControl); - renderer.renderLabel (&labelFaction); - renderer.renderLabel (&labelTeam); - renderer.renderLabel (&labelMapInfo); - - renderer.renderListBox (&listBoxMap); - renderer.renderListBox (&listBoxMapFilter); - renderer.renderListBox (&listBoxFogOfWar); - renderer.renderCheckBox (&checkBoxAllowObservers); - renderer.renderListBox (&listBoxTileset); - renderer.renderListBox (&listBoxTechTree); - - renderer.renderLabel (&labelEnableSwitchTeamMode); - renderer.renderLabel (&labelAISwitchTeamAcceptPercent); - - renderer.renderCheckBox (&checkBoxEnableSwitchTeamMode); - renderer.renderListBox (&listBoxAISwitchTeamAcceptPercent); - renderer.renderListBox (&listBoxFallbackCpuMultiplier); - - renderer.renderLabel (&labelAllowTeamUnitSharing); - renderer.renderCheckBox (&checkBoxAllowTeamUnitSharing); - - renderer.renderLabel (&labelAllowTeamResourceSharing); - renderer.renderCheckBox (&checkBoxAllowTeamResourceSharing); - - renderer.renderButton (&buttonPlayNow); - renderer.renderButton (&buttonRestoreLastSettings); - - renderer.renderCheckBox (&checkBoxScenario); - renderer.renderLabel (&labelScenario); - if (checkBoxScenario.getValue () == true) - { - renderer.renderListBox (&listBoxScenario); - } - - renderer.renderLabel (&labelAllowNativeLanguageTechtree); - renderer.renderCheckBox (&checkBoxAllowNativeLanguageTechtree); - - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread->getProgressMutex () : - NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - -// !!! START TEMP MV -//renderer.renderButton(&buttonCancelDownloads); -//fileFTPProgressList.clear(); -//fileFTPProgressList["test1a dsa asd asda sdasd asd ad ad"] = make_pair(1,"testa"); -//fileFTPProgressList["test2 asdasdasdadas dasdasdasda"] = make_pair(1,"testb"); -//fileFTPProgressList["test3 asdasdad asd ada dasdadasdada"] = make_pair(1,"testc"); -// !!! END TEMP MV - - if (fileFTPProgressList.empty () == false) - { - Lang & lang = Lang::getInstance (); - renderer.renderButton (&buttonCancelDownloads); - int - xLocation = buttonCancelDownloads.getX (); - int - yLocation = buttonCancelDownloads.getY () - 20; - for (std::map < string, pair < int, string > >::iterator iterMap = - fileFTPProgressList.begin (); - iterMap != fileFTPProgressList.end (); ++iterMap) - { - string - progressLabelPrefix = - lang.getString ("ModDownloading") + " " + iterMap->first + " "; -//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nRendering file progress with the following prefix [%s]\n",progressLabelPrefix.c_str()); - - if (Renderer::renderText3DEnabled) - { - renderer.renderProgressBar3D (iterMap->second.first, xLocation, -//10, - yLocation, - CoreData::getInstance - ().getDisplayFontSmall3D (), -//350,progressLabelPrefix); - 300, progressLabelPrefix); - } - else - { - renderer.renderProgressBar (iterMap->second.first, -//10, - xLocation, - yLocation, - CoreData:: - getInstance ().getDisplayFontSmall - (), -//350,progressLabelPrefix); - 300, progressLabelPrefix); - } - - yLocation -= 20; - } - } - safeMutexFTPProgress.ReleaseLock (); - - if (mainMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&mainMessageBox); - } - if (ftpMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&ftpMessageBox); - } - - if (program != NULL) - program->renderProgramMsgBox (); - - if (enableMapPreview && (mapPreview.hasFileLoaded () == true)) - { - - int - mouseX = mainMenu->getMouseX (); - int - mouseY = mainMenu->getMouseY (); - int - mouse2dAnim = mainMenu->getMouse2dAnim (); - - if (mapPreviewTexture == NULL) - { - renderer.renderMouse2d (mouseX, mouseY, mouse2dAnim); - - bool renderAll = (listBoxFogOfWar.getSelectedItemIndex () == 2); -//renderer.renderMapPreview(&mapPreview, renderAll, 10, 350, &mapPreviewTexture); - renderer.renderMapPreview (&mapPreview, renderAll, - this->render_mapPreviewTexture_X, - this->render_mapPreviewTexture_Y, - &mapPreviewTexture); - } - } - renderer.renderChatManager (&chatManager); - renderer.renderConsole (&console, - showFullConsole ? consoleFull : - consoleStoredAndNormal); - - if (difftime ((long int) time (NULL), timerLabelFlash) > 2) - { - timerLabelFlash = time (NULL); - } - } - catch (const std::exception & ex) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw megaglest_runtime_error (szBuf); - } - } - - void - MenuStateConnectedGame::update () - { - Chrono chrono; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled) - chrono.start (); - - Lang & lang = Lang::getInstance (); - ClientInterface * - clientInterface = - NetworkManager::getInstance ().getClientInterface (); - - string newLabelConnectionInfo = lang.getString ("WaitingHost"); - if (clientInterface != NULL - && clientInterface->getJoinGameInProgress () == true) - { - newLabelConnectionInfo = lang.getString ("MGGameStatus2"); - } -// Test progress bar -//MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); -//fileFTPProgressList["test"] = pair(difftime(time(NULL),lastNetworkSendPing) * 20,"test file 123"); -//safeMutexFTPProgress.ReleaseLock(); -// - - if (clientInterface != NULL && clientInterface->isConnected ()) - { -//printf("#2 admin key [%d] client key [%d]\n",settings->getMasterserver_admin(),clientInterface->getSessionKey()); - broadCastGameSettingsToHeadlessServer (false); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - bool - notCurrentlySwitching = - ((difftime - ((long int) time (NULL), - broadcastServerSettingsDelayTimer)) >= - HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS); - bool - receiveAllowedNow = - difftime ((long int) time (NULL), noReceiveTimer) > 2; - bool - newMessage = - lastGameSettingsReceivedCount < - clientInterface->getGameSettingsReceivedCount (); - if (validDisplayedGamesettings == false - || (notCurrentlySwitching && newMessage && receiveAllowedNow)) - { - -//printf("I take the whole settings top broadcastDelay=%d noReceiveTimer=%d\n", (int)difftime((long int) time(NULL), broadcastServerSettingsDelayTimer),(int)difftime((long int) time(NULL), noReceiveTimer)); - - displayedGamesettings = *(clientInterface->getGameSettings ()); - originalGamesettings = displayedGamesettings; - validDisplayedGamesettings = true; - } - - checkBoxAllowNativeLanguageTechtree.setEditable (isHeadlessAdmin ()); - checkBoxAllowNativeLanguageTechtree.setEnabled (isHeadlessAdmin ()); - - listBoxMap.setEditable (isHeadlessAdmin ()); - listBoxMapFilter.setEditable (isHeadlessAdmin ()); - buttonPlayNow.setVisible (isHeadlessAdmin () || - clientInterface->getJoinGameInProgress () == - true); - buttonRestoreLastSettings.setVisible (isHeadlessAdmin ()); - listBoxTechTree.setEditable (isHeadlessAdmin ()); - listBoxTileset.setEditable (isHeadlessAdmin ()); - checkBoxEnableSwitchTeamMode.setEditable (isHeadlessAdmin ()); - listBoxAISwitchTeamAcceptPercent.setEditable (isHeadlessAdmin ()); - listBoxFallbackCpuMultiplier.setEditable (isHeadlessAdmin ()); - listBoxFogOfWar.setEditable (isHeadlessAdmin ()); - checkBoxAllowObservers.setEditable (isHeadlessAdmin ()); - - checkBoxAllowTeamUnitSharing.setEditable (isHeadlessAdmin ()); - checkBoxAllowTeamResourceSharing.setEditable (isHeadlessAdmin ()); - - if (isHeadlessAdmin () == true) - { - bool hasOtherPlayer = false; - bool hasOpenSlot = false; - for (int i = 0; - i < GameConstants::maxPlayers; ++i) - { - if (displayedGamesettings.getFactionControl (i) == ctNetwork - && clientInterface->getPlayerIndex () != (int) i) - { - hasOpenSlot = true; - } - if (displayedGamesettings.getFactionControl (i) == ctNetwork && - displayedGamesettings.getNetworkPlayerNameByPlayerIndex (i) != - GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME - && displayedGamesettings.getNetworkPlayerNameByPlayerIndex (i) - != GameConstants::NETWORK_SLOT_CLOSED_SLOTNAME) - { - listBoxControls[i].setEditable (false); - if (clientInterface->getPlayerIndex () != (int) i) - { - hasOtherPlayer = true; - } - } - else if (clientInterface->getPlayerIndex () == (int) i || - i >= mapInfo.hardMaxPlayers) - { - // Most of the code that handles how to show the set up - // when observers are allowed is in the update() function - // in menu_state_custom_game.cpp. Explicitly stating to change - // players to observers, changing teams to the special "observer" - // team is done in that function. So basically, the update() function - // in this file receives the info from update() in - // menu_state_custom_game.cpp - // - // Mostly what needs to be done here is disable observer slots - // so the info can't be changed by the headless admin. We don't want - // him or her to accidently enable a non-observer into an observer slot - // that's > mapInfo.hardMaxPlayers, or to change the team. - // - listBoxControls[i].setEditable (false); - } - else - { - if (i < mapInfo.hardMaxPlayers) - { - listBoxControls[i].setEditable (true); - } - } - if (i < mapInfo.hardMaxPlayers) - { - listBoxRMultiplier[i].setEditable (isHeadlessAdmin ()); - listBoxFactions[i].setEditable (isHeadlessAdmin ()); - listBoxTeams[i].setEditable (isHeadlessAdmin ()); - } - } - if (hasOtherPlayer) - { - labelWaitingForPlayers.setText (""); - labelWaitingForPlayers.setVisible (false); - } - else if (hasOpenSlot) - { - labelWaitingForPlayers. - setText (lang.getString ("WaitingForPlayers")); - labelWaitingForPlayers.setVisible (true); - } - else - { - labelWaitingForPlayers. - setText (lang.getString ("OpenANetworkSLot")); - labelWaitingForPlayers.setVisible (true); - } - } - else - { - labelWaitingForPlayers.setText (""); - labelWaitingForPlayers.setVisible (false); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (difftime ((long int) time (NULL), lastNetworkSendPing) >= - GameConstants::networkPingInterval) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] about to sendPingMessage...\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - lastNetworkSendPing = time (NULL); - clientInterface->sendPingMessage (GameConstants:: - networkPingInterval, - (int64) time (NULL)); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] pingCount = %d, clientInterface->getLastPingLag() = %f, GameConstants::networkPingInterval = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, pingCount, - clientInterface->getLastPingLag (), - GameConstants::networkPingInterval); - -// Starting checking timeout after sending at least 3 pings to server - if (clientInterface->isConnected () && - pingCount >= MAX_PING_LAG_COUNT - && clientInterface->getLastPingLag () >= - (GameConstants::networkPingInterval * MAX_PING_LAG_COUNT)) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - clientInterface->updateLobby (); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (clientInterface->isConnected () - && clientInterface->getJoinGameInProgress () == false - && pingCount >= MAX_PING_LAG_COUNT - && clientInterface->getLastPingLag () >= - (GameConstants::networkPingInterval * MAX_PING_LAG_COUNT)) - { - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? - ftpClientThread->getProgressMutex () : - NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - if (fileFTPProgressList.empty () == true) - { - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - displayedGamesettings.getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - clientInterface->sendTextMessage (lang.getString - ("ConnectionTimedOut", - languageList[i]) + - " : " + - doubleToStr - (clientInterface->getLastPingLag - (), 2), -1, false, - languageList[i]); - sleep (1); - clientInterface->close (); - } - } - } - } - - pingCount++; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - buttonDisconnect.setText (lang.getString ("Disconnect")); - - if (clientInterface->getAllowDownloadDataSynch () == false) - { - string label = lang.getString ("ConnectedToServer"); - - if (clientInterface->getServerName ().empty () == false) - { - label = label + " " + clientInterface->getServerName (); - } - - label = label + ", " + clientInterface->getVersionString (); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (clientInterface->getAllowGameDataSynchCheck () == false && - displayedGamesettings.getTileset () != "" && - displayedGamesettings.getTech () != "" && - displayedGamesettings.getMap () != "") - { - Config & config = Config::getInstance (); - - MutexSafeWrapper - safeMutexFTPProgress (ftpClientThread != - NULL ? - ftpClientThread->getProgressMutex () : - NULL, - string (__FILE__) + "_" + - intToStr (__LINE__)); - - uint32 tilesetCRC = lastCheckedCRCTilesetValue; - if (lastCheckedCRCTilesetName != - displayedGamesettings.getTileset () - && displayedGamesettings.getTileset () != "") - { -//console.addLine("Checking tileset CRC [" + displayedGamesettings.getTileset() + "]"); - tilesetCRC = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTilesets, ""), - string ("/") + displayedGamesettings.getTileset () + - string ("/*"), ".xml", NULL); - if (tilesetCRC == 0 - || tilesetCRC != displayedGamesettings.getTilesetCRC ()) - { - tilesetCRC = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTilesets, ""), - string ("/") + displayedGamesettings.getTileset () + - string ("/*"), ".xml", NULL, true); - } - -// Test data synch -//tilesetCRC++; - lastCheckedCRCTilesetValue = tilesetCRC; - lastCheckedCRCTilesetName = displayedGamesettings.getTileset (); - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - uint32 techCRC = lastCheckedCRCTechtreeValue; - if (lastCheckedCRCTechtreeName != displayedGamesettings.getTech () - && displayedGamesettings.getTech () != "") - { -//console.addLine("Checking techtree CRC [" + displayedGamesettings.getTech() + "]"); - techCRC = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), - string ("/") + displayedGamesettings.getTech () + - string ("/*"), ".xml", NULL); -//clientInterface->sendTextMessage("#1 TechCRC = " + intToStr(techCRC) + " remoteCRC = " + intToStr(displayedGamesettings.getTechCRC()),-1, true, ""); - - if (techCRC == 0 - || techCRC != displayedGamesettings.getTechCRC ()) - { - techCRC = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), - string ("/") + displayedGamesettings.getTech () + - string ("/*"), ".xml", NULL, true); -//clientInterface->sendTextMessage("#2 TechCRC = " + intToStr(techCRC) + " remoteCRC = " + intToStr(displayedGamesettings.getTechCRC()),-1, true, ""); - } - - - if (techCRC != 0 - && techCRC != displayedGamesettings.getTechCRC () - && listBoxTechTree.getSelectedItemIndex () >= 0 - && listBoxTechTree.getSelectedItem () != - Lang::getInstance ().getString ("DataMissing", "", true)) - { - -//time_t now = time(NULL); - time_t - lastUpdateDate = - getFolderTreeContentsCheckSumRecursivelyLastGenerated - (config.getPathListForType (ptTechs, ""), - string ("/") + displayedGamesettings.getTech () + - string ("/*"), ".xml"); - - const - time_t - REFRESH_CRC_DAY_SECONDS = 60 * 60 * 1; - if (lastUpdateDate <= 0 || - difftime ((long int) time (NULL), - lastUpdateDate) >= REFRESH_CRC_DAY_SECONDS) - { - techCRC = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), - string ("/") + displayedGamesettings.getTech () + - string ("/*"), ".xml", NULL, true); -//clientInterface->sendTextMessage("#3 TechCRC = " + intToStr(techCRC) + " remoteCRC = " + intToStr(displayedGamesettings.getTechCRC()),-1, true, ""); - } - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - -// Test data synch -//techCRC++; - lastCheckedCRCTechtreeValue = techCRC; - lastCheckedCRCTechtreeName = displayedGamesettings.getTech (); - - loadFactions (&displayedGamesettings, false); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - factionCRCList.clear (); - for (unsigned int factionIdx = 0; - factionIdx < factionFiles.size (); ++factionIdx) - { - string factionName = factionFiles[factionIdx]; - if (factionName != GameConstants::RANDOMFACTION_SLOTNAME && - factionName != GameConstants::OBSERVER_SLOTNAME && - factionName != - Lang::getInstance ().getString ("DataMissing", "", true)) - { - - uint32 factionCRC = 0; -//time_t now = time(NULL); - time_t - lastUpdateDate = - getFolderTreeContentsCheckSumRecursivelyLastGenerated - (config.getPathListForType (ptTechs, ""), - "/" + displayedGamesettings.getTech () + "/factions/" + - factionName + "/*", ".xml"); - - const - time_t - REFRESH_CRC_DAY_SECONDS = 60 * 60 * 24; - if (lastUpdateDate <= 0 || - difftime ((long int) time (NULL), - lastUpdateDate) >= REFRESH_CRC_DAY_SECONDS - || (techCRC != 0 - && techCRC != displayedGamesettings.getTechCRC ())) - { - factionCRC = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), - "/" + displayedGamesettings.getTech () + "/factions/" + - factionName + "/*", ".xml", NULL, true); - } - else - { - factionCRC = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), - "/" + displayedGamesettings.getTech () + "/factions/" + - factionName + "/*", ".xml", NULL); - } - if (factionCRC == 0) - { - factionCRC = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), - "/" + displayedGamesettings.getTech () + "/factions/" + - factionName + "/*", ".xml", NULL, true); - } - - if (factionCRC != 0) - { - vector < pair < string, uint32 > >serverFactionCRCList = - displayedGamesettings.getFactionCRCList (); - for (unsigned int factionIdx1 = 0; - factionIdx1 < serverFactionCRCList.size (); - ++factionIdx1) - { - pair < string, uint32 > &serverFaction = - serverFactionCRCList[factionIdx1]; - if (serverFaction.first == factionName) - { - if (serverFaction.second != factionCRC) - { - factionCRC = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), - "/" + displayedGamesettings.getTech () + - "/factions/" + factionName + "/*", ".xml", NULL, - true); - } - break; - } - } - } - factionCRCList.push_back (make_pair - (factionName, factionCRC)); - } - } -//console.addLine("Found factions: " + intToStr(factionCRCList.size())); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - uint32 mapCRC = lastCheckedCRCMapValue; - if (lastCheckedCRCMapName != displayedGamesettings.getMap () && - displayedGamesettings.getMap () != "") - { - Checksum checksum; - string - file = - Config::getMapPath (displayedGamesettings.getMap (), "", - false); -//console.addLine("Checking map CRC [" + file + "]"); - checksum.addFile (file); - mapCRC = checksum.getSum (); -// Test data synch -//mapCRC++; - - lastCheckedCRCMapValue = mapCRC; - lastCheckedCRCMapName = displayedGamesettings.getMap (); - } - safeMutexFTPProgress.ReleaseLock (); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - bool - dataSynchMismatch = - ((mapCRC != 0 && mapCRC != displayedGamesettings.getMapCRC ()) - || (tilesetCRC != 0 - && tilesetCRC != displayedGamesettings.getTilesetCRC ()) - || (techCRC != 0 - && techCRC != displayedGamesettings.getTechCRC ())); - -//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nmapCRC [%d] displayedGamesettings.getMapCRC() [%d]\ntilesetCRC [%d] displayedGamesettings.getTilesetCRC() [%d]\ntechCRC [%d] displayedGamesettings.getTechCRC() [%d]\n",mapCRC,displayedGamesettings.getMapCRC(),tilesetCRC,displayedGamesettings.getTilesetCRC(),techCRC,displayedGamesettings.getTechCRC()); - - if (dataSynchMismatch == true && - (difftime - ((long int) time (NULL), - broadcastServerSettingsDelayTimer) >= - HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS)) - { -//printf("Data not synched: lmap %u rmap: %u ltile: %d rtile: %u ltech: %u rtech: %u\n",mapCRC,displayedGamesettings.getMapCRC(),tilesetCRC,displayedGamesettings.getTilesetCRC(),techCRC,displayedGamesettings.getTechCRC()); - - string labelSynch = lang.getString ("DataNotSynchedTitle"); - - if (mapCRC != 0 && mapCRC != displayedGamesettings.getMapCRC () - && listBoxMap.getSelectedItemIndex () >= 0 - && listBoxMap.getSelectedItem () != - Lang::getInstance ().getString ("DataMissing", "", true)) - { - labelSynch = labelSynch + " " + lang.getString ("Map"); - - if (updateDataSynchDetailText == true && - lastMapDataSynchError != - lang.getString ("DataNotSynchedMap") + " " + - listBoxMap.getSelectedItem ()) - { - lastMapDataSynchError = - lang.getString ("DataNotSynchedMap") + " " + - listBoxMap.getSelectedItem (); - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - string - msg = - lang.getString ("DataNotSynchedMap", - languageList[i]) + " " + - listBoxMap.getSelectedItem (); - bool localEcho = lang.isLanguageLocal (languageList[i]); - clientInterface->sendTextMessage (msg, -1, localEcho, - languageList[i]); - } - } - } - - if (tilesetCRC != 0 - && tilesetCRC != displayedGamesettings.getTilesetCRC () - && listBoxTileset.getSelectedItemIndex () >= 0 - && listBoxTileset.getSelectedItem () != - Lang::getInstance ().getString ("DataMissing", "", true)) - { - labelSynch = labelSynch + " " + lang.getString ("Tileset"); - if (updateDataSynchDetailText == true && - lastTileDataSynchError != - lang.getString ("DataNotSynchedTileset") + " " + - listBoxTileset.getSelectedItem ()) - { - lastTileDataSynchError = - lang.getString ("DataNotSynchedTileset") + " " + - listBoxTileset.getSelectedItem (); - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - string - msg = - lang.getString ("DataNotSynchedTileset", - languageList[i]) + " " + - listBoxTileset.getSelectedItem (); - bool localEcho = lang.isLanguageLocal (languageList[i]); - clientInterface->sendTextMessage (msg, -1, localEcho, - languageList[i]); - } - } - } - - if (techCRC != 0 - && techCRC != displayedGamesettings.getTechCRC () - && listBoxTechTree.getSelectedItemIndex () >= 0 - && listBoxTechTree.getSelectedItem () != - Lang::getInstance ().getString ("DataMissing", "", true)) - { - labelSynch = labelSynch + " " + lang.getString ("TechTree"); - if (updateDataSynchDetailText == true && - lastTechtreeDataSynchError != - lang.getString ("DataNotSynchedTechtree") + " " + - listBoxTechTree.getSelectedItem ()) - { - lastTechtreeDataSynchError = - lang.getString ("DataNotSynchedTechtree") + " " + - listBoxTechTree.getSelectedItem (); - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - string - msg = - lang.getString ("DataNotSynchedTechtree", - languageList[i]) + " " + - listBoxTechTree.getSelectedItem (); - bool localEcho = lang.isLanguageLocal (languageList[i]); - clientInterface->sendTextMessage (msg, -1, localEcho, - languageList[i]); - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - const int - MAX_CHAT_TEXT_LINE_LENGTH = 110; -//const vector languageList = clientInterface->getGameSettings()->getUniqueNetworkPlayerLanguages(); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - bool localEcho = lang.isLanguageLocal (languageList[i]); - - string mismatchedFactionText = ""; - vector < string > mismatchedFactionTextList; - vector < pair < string, uint32 > >serverFactionCRCList = - displayedGamesettings.getFactionCRCList (); - - for (unsigned int factionIdx = 0; - factionIdx < serverFactionCRCList.size (); - ++factionIdx) - { - pair < string, uint32 > &serverFaction = - serverFactionCRCList[factionIdx]; - - bool foundFaction = false; - for (unsigned int clientFactionIdx = 0; - clientFactionIdx < factionCRCList.size (); - ++clientFactionIdx) - { - pair < string, uint32 > &clientFaction = - factionCRCList[clientFactionIdx]; - - if (serverFaction.first == clientFaction.first) - { - foundFaction = true; - if (serverFaction.second != clientFaction.second) - { - if (mismatchedFactionText.length () >= 10) - { - mismatchedFactionTextList.push_back - (mismatchedFactionText); - mismatchedFactionText = ""; - } - if (mismatchedFactionText == "") - { - mismatchedFactionText = - "The following factions are mismatched: "; - if (lang.hasString ("MismatchedFactions", - languageList[i]) == true) - { - mismatchedFactionText = - lang.getString ("MismatchedFactions", - languageList[i]); - } - - mismatchedFactionText += - " [" + intToStr (factionCRCList.size ()) + - "][" + - intToStr (serverFactionCRCList.size ()) + - "] - "; - } - else - { - mismatchedFactionText += ", "; - } - mismatchedFactionText += serverFaction.first; - } - break; - } - } - - if (foundFaction == false) - { - if ((int) mismatchedFactionText.length () > - MAX_CHAT_TEXT_LINE_LENGTH) - { - mismatchedFactionTextList.push_back - (mismatchedFactionText); - mismatchedFactionText = ""; - } - - if (mismatchedFactionText == "") - { - mismatchedFactionText = - "The following factions are mismatched: "; - if (lang.hasString ("MismatchedFactions", - languageList[i]) == true) - { - mismatchedFactionText = - lang.getString ("MismatchedFactions", - languageList[i]); - } - - mismatchedFactionText += - " [" + intToStr (factionCRCList.size ()) + "][" + - intToStr (serverFactionCRCList.size ()) + "] - "; - } - else - { - mismatchedFactionText += ", "; - } - - if (lang.hasString ("MismatchedFactionsMissing", - languageList[i]) == true) - { - mismatchedFactionText += - serverFaction.first + " " + - lang.getString ("MismatchedFactionsMissing", - languageList[i]); - } - else - { - mismatchedFactionText += - serverFaction.first + " (missing)"; - } - } - } - - for (unsigned int clientFactionIdx = 0; - clientFactionIdx < factionCRCList.size (); - ++clientFactionIdx) - { - pair < string, uint32 > &clientFaction = - factionCRCList[clientFactionIdx]; - - bool foundFaction = false; - for (unsigned int factionIdx = 0; - factionIdx < serverFactionCRCList.size (); - ++factionIdx) - { - pair < string, uint32 > &serverFaction = - serverFactionCRCList[factionIdx]; - - if (serverFaction.first == clientFaction.first) - { - foundFaction = true; - break; - } - } - - if (foundFaction == false) - { - if ((int) mismatchedFactionText.length () > - MAX_CHAT_TEXT_LINE_LENGTH) - { - mismatchedFactionTextList.push_back - (mismatchedFactionText); - mismatchedFactionText = ""; - } - - if (mismatchedFactionText == "") - { - mismatchedFactionText = - "The following factions are mismatched: "; - if (lang.hasString ("MismatchedFactions", - languageList[i]) == true) - { - mismatchedFactionText = - lang.getString ("MismatchedFactions", - languageList[i]); - } - - mismatchedFactionText += - " [" + intToStr (factionCRCList.size ()) + "][" + - intToStr (serverFactionCRCList.size ()) + "] - "; - } - else - { - mismatchedFactionText += ", "; - } - - if (lang.hasString ("MismatchedFactionsExtra", - languageList[i]) == true) - { - mismatchedFactionText += - clientFaction.first + " " + - lang.getString ("MismatchedFactionsExtra", - languageList[i]); - } - else - { - mismatchedFactionText += - clientFaction.first + " (extra)"; - } - } - } - - if (mismatchedFactionText != "") - { - if (mismatchedFactionTextList.empty () == false) - { - if (mismatchedFactionText != "") - { - mismatchedFactionText += "."; - mismatchedFactionTextList.push_back - (mismatchedFactionText); - } - for (unsigned int splitIdx = 0; - splitIdx < mismatchedFactionTextList.size (); - ++splitIdx) - { - clientInterface->sendTextMessage - (mismatchedFactionTextList[splitIdx], -1, - localEcho, languageList[i]); - } - } - else - { - mismatchedFactionText += "."; - clientInterface->sendTextMessage - (mismatchedFactionText, -1, localEcho, - languageList[i]); - } - } - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - } - } - - updateDataSynchDetailText = false; - labelDataSynchInfo.setText (labelSynch); - } - else - { - labelDataSynchInfo.setText (""); - } - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (clientInterface->getAllowGameDataSynchCheck () == true && - clientInterface->getNetworkGameDataSynchCheckOk () == false) - { - label = label + " -synch mismatch for:"; - - if (clientInterface->getNetworkGameDataSynchCheckOkMap () == - false) - { - label = label + " map"; - - if (updateDataSynchDetailText == true && - clientInterface->getReceivedDataSynchCheck () && - lastMapDataSynchError != - "map CRC mismatch, " + listBoxMap.getSelectedItem ()) - { - lastMapDataSynchError = - "map CRC mismatch, " + listBoxMap.getSelectedItem (); - clientInterface->sendTextMessage (lastMapDataSynchError, -1, - true, ""); - } - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (clientInterface->getNetworkGameDataSynchCheckOkTile () == - false) - { - label = label + " tile"; - if (updateDataSynchDetailText == true && - clientInterface->getReceivedDataSynchCheck () && - lastTileDataSynchError != - "tile CRC mismatch, " + listBoxTileset.getSelectedItem ()) - { - lastTileDataSynchError = - "tile CRC mismatch, " + listBoxTileset.getSelectedItem (); - clientInterface->sendTextMessage (lastTileDataSynchError, -1, - true, ""); - } - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (clientInterface->getNetworkGameDataSynchCheckOkTech () == - false) - { - label = label + " techtree"; - - if (updateDataSynchDetailText == true && - clientInterface->getReceivedDataSynchCheck ()) - { - - string - report = - clientInterface->getNetworkGameDataSynchCheckTechMismatchReport - (); - if (lastTechtreeDataSynchError != - "techtree CRC mismatch" + report) - { - lastTechtreeDataSynchError = - "techtree CRC mismatch" + report; - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] report: %s\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - report.c_str ()); - - clientInterface->sendTextMessage ("techtree CRC mismatch", - -1, true, ""); - vector < string > reportLineTokens; - Tokenize (report, reportLineTokens, "\n"); - for (int reportLine = 0; - reportLine < (int) reportLineTokens.size (); - ++reportLine) - { - clientInterface->sendTextMessage (reportLineTokens - [reportLine], -1, true, - ""); - } - } - } - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (clientInterface->getReceivedDataSynchCheck () == true) - { - updateDataSynchDetailText = false; - } - } - else if (clientInterface->getAllowGameDataSynchCheck () == true) - { - label += " - data synch is ok"; - } - - labelStatus.setText (label); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - } - else - { - string label = lang.getString ("ConnectedToServer"); - - if (!clientInterface->getServerName ().empty ()) - { - label = label + " " + clientInterface->getServerName (); - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (clientInterface->getAllowGameDataSynchCheck () == true && - clientInterface->getNetworkGameDataSynchCheckOk () == false) - { - label = label + " -waiting to synch:"; - if (clientInterface->getNetworkGameDataSynchCheckOkMap () == - false) - { - label = label + " map"; - } - if (clientInterface->getNetworkGameDataSynchCheckOkTile () == - false) - { - label = label + " tile"; - } - if (clientInterface->getNetworkGameDataSynchCheckOkTech () == - false) - { - label = label + " techtree"; - } - } - else if (clientInterface->getAllowGameDataSynchCheck () == true) - { - label += " - data synch is ok"; - } - - labelStatus.setText (label); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - } - else - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (clientInterface != NULL - && clientInterface->isConnected () == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - clientInterface->close (); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - returnToJoinMenu (); - return; - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - -//process network messages - if (clientInterface != NULL && clientInterface->isConnected ()) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - try - { - if (clientInterface->getGameSettingsReceived () - && validDisplayedGamesettings - && lastGameSettingsReceivedCount != - clientInterface->getGameSettingsReceivedCount ()) - { - lastGameSettingsReceivedCount = - clientInterface->getGameSettingsReceivedCount (); - bool - errorOnMissingData = - (clientInterface->getAllowGameDataSynchCheck () == false); - - const GameSettings * - receivedGameSettings = clientInterface->getGameSettings (); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - -//printf("Menu got new settings thisfactionindex = %d startlocation: %d control = %d\n",displayedGamesettings.getThisFactionIndex(),clientInterface->getGameSettings()->getStartLocationIndex(clientInterface->getGameSettings()->getThisFactionIndex()),displayedGamesettings.getFactionControl(clientInterface->getGameSettings()->getThisFactionIndex())); - if (difftime ((long int) time (NULL), noReceiveTimer) < 3 - || difftime ((long int) time (NULL), - broadcastServerSettingsDelayTimer) < - HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS) - { -// copy my current settings in UI to displayedSettings; - loadGameSettings (&displayedGamesettings); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - -// check if there are any changed fields from others clients - if (isHeadlessAdmin ()) - { -//printf("I am headless admin and will restore only some parts\n"); -// only copy those parts which are editable by normal clients - for (int i = 0; i < receivedGameSettings->getFactionCount (); - i++) - { - if (displayedGamesettings.getFactionControl (i) == - ctNetwork) - { - if (originalGamesettings.getTeam (i) == - displayedGamesettings.getTeam (i)) - { - displayedGamesettings.setTeam (i, - receivedGameSettings->getTeam - (i)); - originalGamesettings.setTeam (i, - receivedGameSettings->getTeam - (i)); - } - if (originalGamesettings.getFactionTypeName (i) == - displayedGamesettings.getFactionTypeName (i)) - { - displayedGamesettings.setFactionTypeName (i, - receivedGameSettings->getFactionTypeName - (i)); - originalGamesettings.setFactionTypeName (i, - receivedGameSettings->getFactionTypeName - (i)); - } - displayedGamesettings.setNetworkPlayerGameStatus (i, - receivedGameSettings->getNetworkPlayerGameStatus - (i)); - originalGamesettings.setNetworkPlayerGameStatus (i, - receivedGameSettings->getNetworkPlayerGameStatus - (i)); - displayedGamesettings.setNetworkPlayerName (i, - receivedGameSettings->getNetworkPlayerName - (i)); - originalGamesettings.setNetworkPlayerName (i, - receivedGameSettings->getNetworkPlayerName - (i)); - } - } - } - else - { -//printf("I am client and restore everything but not my line\n"); -// copy all received fields just not those which are editable for normal client -//store my changes - int - i = clientInterface->getPlayerIndex (); - int - team = displayedGamesettings.getTeam (i); - string faction = displayedGamesettings.getFactionTypeName (i); - int - status = - displayedGamesettings.getNetworkPlayerGameStatus (i); - string - networkPlayerName = - displayedGamesettings.getNetworkPlayerName (i); - displayedGamesettings = *receivedGameSettings; - originalGamesettings = *receivedGameSettings; - - displayedGamesettings.setTeam (i, team); - originalGamesettings.setTeam (i, team); - displayedGamesettings.setFactionTypeName (i, faction); - originalGamesettings.setFactionTypeName (i, faction); - displayedGamesettings.setNetworkPlayerGameStatus (i, status); - originalGamesettings.setNetworkPlayerGameStatus (i, status); - displayedGamesettings.setNetworkPlayerName (i, - networkPlayerName); - originalGamesettings.setNetworkPlayerName (i, - networkPlayerName); - - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - setupUIFromGameSettings (&displayedGamesettings, - errorOnMissingData); - } - else - { -// do nothing - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - setupUIFromGameSettings (&displayedGamesettings, - errorOnMissingData); - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - broadCastGameSettingsToHeadlessServer - (needToBroadcastServerSettings); - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - -// check if we are joining an in progress game - if (clientInterface->getJoinGameInProgress () == true && - clientInterface->getJoinGameInProgressLaunch () == true && - clientInterface->getReadyForInGameJoin () == true && - ftpClientThread != NULL) - { - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? - ftpClientThread->getProgressMutex () : - NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - if (readyToJoinInProgressGame == false) - { - if (getInProgressSavedGameFromFTPServer == "") - { - - getInProgressSavedGameFromFTPServerInProgress = true; - ftpClientThread->addTempFileToRequests - (GameConstants::saveNetworkGameFileClientCompressed, - GameConstants::saveNetworkGameFileServerCompressed); - - getInProgressSavedGameFromFTPServer = - GameConstants::saveNetworkGameFileServerCompressed; - fileFTPProgressList[getInProgressSavedGameFromFTPServer] = - pair < int, - string > (0, ""); - } - safeMutexFTPProgress.ReleaseLock (); - } - else - { - safeMutexFTPProgress.ReleaseLock (); - - string - saveGameFile = - "temp/" + string (GameConstants::saveNetworkGameFileClient); - if (getGameReadWritePath - (GameConstants::path_logs_CacheLookupKey) != "") - { - saveGameFile = - getGameReadWritePath - (GameConstants::path_logs_CacheLookupKey) + saveGameFile; - } - else - { - string - userData = - Config::getInstance ().getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - saveGameFile = userData + saveGameFile; - } - -//printf("Loading saved game file [%s]\n",saveGameFile.c_str()); - - GameSettings - gameSettings = *clientInterface->getGameSettings (); - loadGameSettings (&gameSettings); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - Game::loadGame (saveGameFile, program, false, &gameSettings); - return; - } - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - -//update lobby - clientInterface = - NetworkManager::getInstance ().getClientInterface (); - if (clientInterface != NULL && clientInterface->isConnected ()) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - clientInterface->updateLobby (); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - clientInterface = - NetworkManager::getInstance ().getClientInterface (); - if (clientInterface != NULL && clientInterface->isConnected ()) - { - if (initialSettingsReceivedFromServer == true && - clientInterface->getIntroDone () == true && - (switchSetupRequestFlagType & ssrft_NetworkPlayerName) == - ssrft_NetworkPlayerName) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] getHumanPlayerName() = [%s], clientInterface->getGameSettings()->getThisFactionIndex() = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, - getHumanPlayerName ().c_str (), - clientInterface->getGameSettings - ()->getThisFactionIndex ()); - clientInterface->sendSwitchSetupRequest ("", - clientInterface->getPlayerIndex - (), -1, -1, - getHumanPlayerName (), - getNetworkPlayerStatus - (), - switchSetupRequestFlagType, - lang.getLanguage ()); - - switchSetupRequestFlagType = ssrft_None; - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - -//intro - if (clientInterface->getIntroDone ()) - { - if (newLabelConnectionInfo != labelInfo.getText ()) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, - __LINE__); - labelInfo.setText (newLabelConnectionInfo); - } - } - -//launch - if (clientInterface->getLaunchGame ()) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - assert (clientInterface != NULL); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (modHttpServerThread != NULL) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - modHttpServerThread->setSimpleTaskInterfaceValid (false); - modHttpServerThread->signalQuit (); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - if (modHttpServerThread->canShutdown (true) == true - && modHttpServerThread->shutdownAndWait () == true) - { - delete modHttpServerThread; - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - modHttpServerThread = NULL; - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (ftpClientThread != NULL) - { - ftpClientThread->setCallBackObject (NULL); - ftpClientThread->signalQuit (); - sleep (0); - if (ftpClientThread->canShutdown (true) == true && - ftpClientThread->shutdownAndWait () == true) - { - delete ftpClientThread; - } - else - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s %d] Error cannot shutdown ftpClientThread\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("%s", szBuf); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", - szBuf); - } - ftpClientThread = NULL; - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - launchingNewGame = true; - - GameSettings - gameSettings = *clientInterface->getGameSettings (); -// complete game settings with local stuff - if (gameSettings.getScenario () != "") - { - string scenario = gameSettings.getScenario (); - listBoxScenario.setSelectedItem (formatString (scenario)); - string file = Scenario::getScenarioPath (dirList, scenario); - - bool isTutorial = Scenario::isGameTutorial (file); - Scenario::loadScenarioInfo (file, &scenarioInfo, isTutorial); - - gameSettings.setScenarioDir (Scenario::getScenarioPath - (dirList, scenarioInfo.name)); - - gameSettings. - setDefaultResources (scenarioInfo.defaultResources); - gameSettings.setDefaultUnits (scenarioInfo.defaultUnits); - gameSettings.setDefaultVictoryConditions - (scenarioInfo.defaultVictoryConditions); - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - program->setState (new Game (program, &gameSettings, false)); - return; - } - } - -//call the chat manager - chatManager.updateNetwork (); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - -//console732 - console.update (); - -// check for need to switch music on again - if (clientInterface != NULL) - { - int - currentConnectionCount = 0; - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - if (displayedGamesettings.getFactionControl (i) == ctNetwork && - displayedGamesettings.getNetworkPlayerName (i) != "" && - displayedGamesettings.getNetworkPlayerName (i) != - GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) - { - currentConnectionCount++; - } - } - if (currentConnectionCount > soundConnectionCount) - { - soundConnectionCount = currentConnectionCount; - static PlaySoundClip snd; - SoundRenderer::getInstance (). - playFx (snd.getSound (snd.sfxAttention)); -//switch on music again!! - Config & config = Config::getInstance (); - float - configVolume = (config.getInt ("SoundVolumeMusic") / 100.f); - CoreData::getInstance (). - getMenuMusic ()->setVolume (configVolume); - } - soundConnectionCount = currentConnectionCount; - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - } - catch (const runtime_error & ex) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, ex.what ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] %s\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, szBuf); - showMessageBox (szBuf, "Error", false); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - } - } - - bool - MenuStateConnectedGame::loadFactions (const GameSettings * gameSettings, - bool errorOnNoFactions) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - Lang & lang = Lang::getInstance (); - bool foundFactions = false; - vector < string > results; - - string - scenarioDir = - Scenario::getScenarioDir (dirList, gameSettings->getScenario ()); - if (gameSettings->getTech () != "") - { - Config & config = Config::getInstance (); - - vector < string > techPaths = - config.getPathListForType (ptTechs, scenarioDir); - for (int idx = 0; idx < (int) techPaths.size (); idx++) - { - string & techPath = techPaths[idx]; - endPathWithSlash (techPath); -//findAll(techPath + gameSettings->getTech() + "/factions/*.", results, false, false); - findDirs (techPath + gameSettings->getTech () + "/factions/", - results, false, false); - if (results.empty () == false) - { - break; - } - } - - if (results.empty () == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - if (clientInterface->getAllowGameDataSynchCheck () == false) - { - if (errorOnNoFactions == true) - { - throw - megaglest_runtime_error - ("(2)There are no factions for the tech tree [" + - gameSettings->getTech () + "]"); - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] (2)There are no factions for the tech tree [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, - gameSettings->getTech ().c_str ()); - } - results. - push_back (Lang:: - getInstance ().getString ("DataMissing", "", true)); - factionFiles = results; - vector < string > translatedFactionNames; - for (int i = 0; i < (int) factionFiles.size (); ++i) - { - results[i] = formatString (results[i]); - string - translatedString = - techTree->getTranslatedFactionName (gameSettings->getTech (), - factionFiles[i]); - if (toLower (translatedString) == toLower (results[i])) - { - translatedFactionNames.push_back (results[i]); - } - else - { - translatedFactionNames.push_back (results[i] + " (" + - translatedString + ")"); - } - } - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - listBoxFactions[i].setItems (results, translatedFactionNames); - } - - if (lastMissingTechtree != gameSettings->getTech () && - gameSettings->getTech () != "") - { - lastMissingTechtree = gameSettings->getTech (); - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingTechtree", languageList[i]) == - true) - { - snprintf (szMsg, 8096, - lang.getString ("DataMissingTechtree", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), - gameSettings->getTech ().c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Player: %s is missing the techtree: %s", - getHumanPlayerName ().c_str (), - gameSettings->getTech ().c_str ()); - } - clientInterface->sendTextMessage (szMsg, -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - } - } - - foundFactions = false; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - else - { - lastMissingTechtree = ""; - getMissingTechtreeFromFTPServer = ""; - - factionFiles = results; - vector < string > translatedFactionNames; - for (int i = 0; i < (int) factionFiles.size (); ++i) - { - results[i] = formatString (results[i]); - string - translatedString = - techTree->getTranslatedFactionName (gameSettings->getTech (), - factionFiles[i]); - if (toLower (translatedString) == toLower (results[i])) - { - translatedFactionNames.push_back (results[i]); - } - else - { - translatedFactionNames.push_back (results[i] + " (" + - translatedString + ")"); - } - } - - results.push_back (formatString - (GameConstants::RANDOMFACTION_SLOTNAME)); - factionFiles.push_back (formatString - (GameConstants::RANDOMFACTION_SLOTNAME)); - translatedFactionNames.push_back ("*" + - lang.getString ("Random", "", - true) + "*"); - -// Add special Observer Faction - if (checkBoxAllowObservers.getValue () == 1) - { - results.push_back (formatString - (GameConstants::OBSERVER_SLOTNAME)); - factionFiles.push_back (formatString - (GameConstants::OBSERVER_SLOTNAME)); - translatedFactionNames.push_back ("*" + - lang.getString ("Observer", "", - true) + "*"); - } - - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - listBoxFactions[i].setItems (results, translatedFactionNames); - } - - foundFactions = (results.empty () == false); - } - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - return foundFactions; - } - -// ============ PRIVATE =========================== - - bool MenuStateConnectedGame::hasNetworkGameSettings () - { - bool hasNetworkSlot = false; - - try - { - for (int i = 0; i < mapInfo.players; ++i) - { - ControlType - ct = - static_cast < ControlType > - (listBoxControls[i].getSelectedItemIndex ()); - if (ct != ctClosed) - { - if (ct == ctNetwork || ct == ctNetworkUnassigned) - { - hasNetworkSlot = true; - break; - } - } - } - if (hasNetworkSlot == false) - { - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - ControlType - ct = - static_cast < ControlType > - (listBoxControls[i].getSelectedItemIndex ()); - if (ct != ctClosed) - { - if (ct == ctNetworkUnassigned) - { - hasNetworkSlot = true; - break; - } - } - } - } - } - catch (const std::exception & ex) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - ex.what ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] %s\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, szBuf); - showMessageBox (szBuf, "Error", false); - } - - return hasNetworkSlot; - } - - void - MenuStateConnectedGame::keyDown (SDL_KeyboardEvent key) - { - if (activeInputLabel != NULL) - { - bool handled = keyDownEditLabel (key, &activeInputLabel); - if (handled == true) - { - switchSetupRequestFlagType |= ssrft_NetworkPlayerName; - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - else - { -//send key to the chat manager - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - if (clientInterface != NULL && - clientInterface->isConnected () == true && - clientInterface->getIntroDone () == true) - { - chatManager.keyDown (key); - } - if (chatManager.getEditEnabled () == false && - (::Shared::Platform::Window::isKeyStateModPressed (KMOD_SHIFT) == - false)) - { - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - - if (isKeyPressed (configKeys.getSDLKey ("ShowFullConsole"), key) == - true) - { - showFullConsole = true; - } - else if (isKeyPressed (configKeys.getSDLKey ("ToggleMusic"), key) == - true) - { - Config & config = Config::getInstance (); - Lang & lang = Lang::getInstance (); - - float - configVolume = (config.getInt ("SoundVolumeMusic") / 100.f); - float - currentVolume = - CoreData::getInstance ().getMenuMusic ()->getVolume (); - if (currentVolume > 0) - { - CoreData::getInstance ().getMenuMusic ()->setVolume (0.f); - console.addLine (lang.getString ("GameMusic") + " " + - lang.getString ("Off")); - } - else - { - CoreData::getInstance (). - getMenuMusic ()->setVolume (configVolume); -//If the config says zero, use the default music volume -//gameMusic->setVolume(configVolume ? configVolume : 0.9); - console.addLine (lang.getString ("GameMusic")); - } - } -//else if(key == configKeys.getCharKey("SaveGUILayout")) { - else if (isKeyPressed (configKeys.getSDLKey ("SaveGUILayout"), key) - == true) - { - bool - saved = - GraphicComponent::saveAllCustomProperties (containerName); - Lang & lang = Lang::getInstance (); - console.addLine (lang.getString ("GUILayoutSaved") + " [" + - (saved ? lang. - getString ("Yes") : lang.getString ("No")) + - "]"); - } - } - } - } - - bool MenuStateConnectedGame::textInput (std::string text) - { - if (activeInputLabel != NULL) - { - bool handled = textInputEditLabel (text, &activeInputLabel); - if (handled == true) - { - switchSetupRequestFlagType |= ssrft_NetworkPlayerName; - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - return handled; - } - else - { - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - if (clientInterface != NULL && clientInterface->isConnected () == true - && clientInterface->getIntroDone () == true) - { - return chatManager.textInput (text); - } - } - return false; - } - - void - MenuStateConnectedGame::keyPress (SDL_KeyboardEvent c) - { - if (activeInputLabel != NULL) - { - keyPressEditLabel (c, &activeInputLabel); - } - else - { - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - if (clientInterface != NULL && clientInterface->isConnected () == true - && clientInterface->getIntroDone () == true) - { - chatManager.keyPress (c); - } - } - } - - void - MenuStateConnectedGame::keyUp (SDL_KeyboardEvent key) - { - if (activeInputLabel == NULL) - { - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - if (clientInterface != NULL && - clientInterface->isConnected () == true && - clientInterface->getIntroDone () == true) - { - chatManager.keyUp (key); - } - - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - - if (chatManager.getEditEnabled ()) - { -//send key to the chat manager - chatManager.keyUp (key); - } - else if (isKeyPressed (configKeys.getSDLKey ("ShowFullConsole"), key) - == true) - { - showFullConsole = false; - } - } - } - - void - MenuStateConnectedGame::setActiveInputLabel (GraphicLabel * newLable) - { - MenuState::setActiveInputLabel (newLable, &activeInputLabel); - } - - string MenuStateConnectedGame::getHumanPlayerName () - { - string result = defaultPlayerName; - - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - for (int j = 0; j < GameConstants::maxPlayers; ++j) - { - if (clientInterface != NULL && - j == clientInterface->getPlayerIndex () && - labelPlayerNames[j].getText () != "") - { - result = labelPlayerNames[j].getText (); - - if (activeInputLabel != NULL) - { - size_t found = result.find_last_of ("_"); - if (found != string::npos) - { - result = result.substr (0, found); - } - } - - break; - } - } - - return result; - } - - void - MenuStateConnectedGame::loadFactionTexture (string filepath) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (enableFactionTexturePreview == true) - { - if (filepath == "") - { - factionTexture = NULL; - } - else - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] filepath = [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, filepath.c_str ()); - factionTexture = Renderer::findTexture (filepath); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - } - } - - bool - MenuStateConnectedGame::loadMapInfo (string file, MapInfo * mapInfo, - bool loadMapPreview) - { - bool mapLoaded = false; - try - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] map [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, file.c_str ()); - - if (file != "") - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - lastMissingMap = file; - - Lang & lang = Lang::getInstance (); - if (MapPreview::loadMapInfo - (file, mapInfo, lang.getString ("MaxPlayers"), - lang.getString ("Size"), true) == true) - { - mapInfo->players = GameConstants::maxPlayers; - -// Not painting properly so this is on hold - if (loadMapPreview == true) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - if (mapPreview.getMapFileLoaded () != file) - { - mapPreview.loadFromFile (file.c_str ()); - cleanupMapPreviewTexture (); - } - } - - mapLoaded = true; - } - } - else - { - cleanupMapPreviewTexture (); - mapInfo->desc = - Lang::getInstance ().getString ("DataMissing", "", true); - - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - const GameSettings * - gameSettings = clientInterface->getGameSettings (); - - if (lastMissingMap != gameSettings->getMap ()) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - lastMissingMap = gameSettings->getMap (); - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingMap", languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString ("DataMissingMap", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), - gameSettings->getMap ().c_str ()); - } - else - { - snprintf (szMsg, 8096, "Player: %s is missing the map: %s", - getHumanPlayerName ().c_str (), - gameSettings->getMap ().c_str ()); - } - clientInterface->sendTextMessage (szMsg, -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - } - } - } - } - catch (exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - e.what ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] error [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, e.what ()); - - showMessageBox ("Error loading map file: " + file + '\n' + e.what (), - "Error", false); - } - - return mapLoaded; - } - - void - MenuStateConnectedGame::showMessageBox (const string & text, - const string & header, - bool toggle) - { - if (!toggle) - { - mainMessageBox.setEnabled (false); - } - - if (!mainMessageBox.getEnabled ()) - { - mainMessageBox.setText (text); - mainMessageBox.setHeader (header); - mainMessageBox.setEnabled (true); - } - else - { - mainMessageBox.setEnabled (false); - } - } - - void - MenuStateConnectedGame::showFTPMessageBox (const string & text, - const string & header, - bool toggle) - { - if (!toggle) - { - ftpMessageBox.setEnabled (false); - } - - if (!ftpMessageBox.getEnabled ()) - { - ftpMessageBox.setText (text); - ftpMessageBox.setHeader (header); - ftpMessageBox.setEnabled (true); - } - else - { - ftpMessageBox.setEnabled (false); - } - } - - int32 MenuStateConnectedGame::getNetworkPlayerStatus () - { - int32 result = npst_None; - switch (listBoxPlayerStatus.getSelectedItemIndex ()) - { - case 2: - result = npst_Ready; - break; - case 1: - result = npst_BeRightBack; - break; - case 0: - result = npst_PickSettings; - break; - } - - return result; - } - - void - MenuStateConnectedGame::cleanupMapPreviewTexture () - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (mapPreviewTexture != NULL) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - mapPreviewTexture->end (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - delete mapPreviewTexture; - mapPreviewTexture = NULL; - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - bool MenuStateConnectedGame::isInSpecialKeyCaptureEvent () - { - bool - result = (chatManager.getEditEnabled () || activeInputLabel != NULL); - return result; - } - - void - MenuStateConnectedGame::FTPClient_CallbackEvent (string itemName, - FTP_Client_CallbackType - type, - pair < - FTP_Client_ResultType, - string > result, - void *userdata) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (type == ftp_cct_DownloadProgress) - { - FTPClientCallbackInterface::FtpProgressStats * stats = - (FTPClientCallbackInterface::FtpProgressStats *) userdata; - if (stats != NULL) - { - int - fileProgress = 0; - if (stats->download_total > 0) - { - fileProgress = - ((stats->download_now / stats->download_total) * 100.0); - } -//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP Callback for [%s] current file [%s] fileProgress = %d [now = %f, total = %f]\n",itemName.c_str(),stats->currentFilename.c_str(), fileProgress,stats->download_now,stats->download_total); - - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread->getProgressMutex () - : NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - pair < int, - string > - lastProgress; - std::map < string, pair < int, - string > >::iterator - iterFind = fileFTPProgressList.find (itemName); - if (iterFind == fileFTPProgressList.end ()) - { - iterFind = - fileFTPProgressList.find (GameConstants:: - saveNetworkGameFileServerCompressed); - if (iterFind == fileFTPProgressList.end ()) - { - iterFind = - fileFTPProgressList.find (GameConstants:: - saveNetworkGameFileClientCompressed); - } - } - if (iterFind != fileFTPProgressList.end ()) - { - lastProgress = iterFind->second; - fileFTPProgressList[iterFind->first] = pair < int, - string > (fileProgress, stats->currentFilename); - } - safeMutexFTPProgress.ReleaseLock (); - - if (itemName != "" - && (lastProgress.first / 25) < (fileProgress / 25)) - { - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("FileDownloadProgress", languageList[i]) == - true) - { - snprintf (szMsg, 8096, - lang.getString ("FileDownloadProgress", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), itemName.c_str (), - fileProgress); - } - else - { - snprintf (szMsg, 8096, - "Player: %s download progress for [%s] is %d %%", - getHumanPlayerName ().c_str (), itemName.c_str (), - fileProgress); - } - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] szMsg [%s] lastProgress.first = %d, fileProgress = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, szMsg, lastProgress.first, - fileProgress); - clientInterface->sendTextMessage (szMsg, -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - } - sleep (1); - } - } - } - else if (type == ftp_cct_ExtractProgress) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Got FTP extract Callback for [%s] result = %d [%s]\n", - itemName.c_str (), result.first, result.second.c_str ()); - - if (userdata == NULL) - { - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingExtractDownload", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString ("DataMissingExtractDownload", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), itemName.c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Please wait, player: %s is extracting: %s", - getHumanPlayerName ().c_str (), itemName.c_str ()); - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] szMsg [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, szMsg); - clientInterface->sendTextMessage (szMsg, -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - } - sleep (1); - } - else - { - char * - szBuf = (char *) userdata; -//printf("%s\n",szBuf); -//console.addLine(szBuf); - console.addLine (szBuf, false, ""); - } - } - else if (type == ftp_cct_Map) - { - getMissingMapFromFTPServerInProgress = false; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Got FTP Callback for [%s] result = %d [%s]\n", - itemName.c_str (), result.first, result.second.c_str ()); - - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread->getProgressMutex () : - NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - fileFTPProgressList.erase (itemName); - safeMutexFTPProgress.ReleaseLock (); - - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - const GameSettings * - gameSettings = clientInterface->getGameSettings (); - - if (result.first == ftp_crt_SUCCESS) - { -// Clear the CRC file Cache - string file = Config::getMapPath (itemName, "", false); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("Got map itemName [%s] file [%s] lastCheckedCRCMapName [%s] gameSettings->getMap() [%s]\n", - itemName.c_str (), file.c_str (), - lastCheckedCRCMapName.c_str (), - gameSettings->getMap ().c_str ()); - - if (gameSettings != NULL && itemName == gameSettings->getMap () && - lastCheckedCRCMapName == gameSettings->getMap () && - gameSettings->getMap () != "") - { - Checksum::clearFileCache (); - Checksum checksum; - - checksum.addFile (file); - lastCheckedCRCMapValue = checksum.getSum (); - } - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingMapSuccessDownload", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString ("DataMissingMapSuccessDownload", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), itemName.c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Player: %s SUCCESSFULLY downloaded the map: %s", - getHumanPlayerName ().c_str (), itemName.c_str ()); - } - clientInterface->sendTextMessage (szMsg, -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - } - sleep (1); - } - else - { - printf - ("FAILED map itemName [%s] lastCheckedCRCMapName [%s] gameSettings->getMap() [%s]\n", - itemName.c_str (), lastCheckedCRCMapName.c_str (), - gameSettings->getMap ().c_str ()); - - curl_version_info_data * - curlVersion = curl_version_info (CURLVERSION_NOW); - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingMapFailDownload", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString ("DataMissingMapFailDownload", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), itemName.c_str (), - curlVersion->version); - } - else - { - snprintf (szMsg, 8096, - "Player: %s FAILED to download the map: [%s] using CURL version [%s]", - getHumanPlayerName ().c_str (), itemName.c_str (), - curlVersion->version); - } - clientInterface->sendTextMessage (szMsg, -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - - if (result.first == ftp_crt_HOST_NOT_ACCEPTING) - { - if (lang.hasString ("HostNotAcceptingDataConnections", - languageList[i]) == true) - { - clientInterface->sendTextMessage (lang.getString - ("HostNotAcceptingDataConnections", - languageList[i]), -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - } - else - { - clientInterface->sendTextMessage - ("*Warning* the host is not accepting data connections.", - -1, lang.isLanguageLocal (languageList[i]), - languageList[i]); - } - } - } - sleep (1); - - console.addLine (result.second, true); - } - } - else if (type == ftp_cct_Tileset) - { - getMissingTilesetFromFTPServerInProgress = false; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Got FTP Callback for [%s] result = %d [%s]\n", - itemName.c_str (), result.first, result.second.c_str ()); - - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread->getProgressMutex () : - NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - fileFTPProgressList.erase (itemName); - safeMutexFTPProgress.ReleaseLock (true); - - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - const GameSettings * - gameSettings = clientInterface->getGameSettings (); - - if (result.first == ftp_crt_SUCCESS) - { - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingTilesetSuccessDownload", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString ("DataMissingTilesetSuccessDownload", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), itemName.c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Player: %s SUCCESSFULLY downloaded the tileset: %s", - getHumanPlayerName ().c_str (), itemName.c_str ()); - } - clientInterface->sendTextMessage (szMsg, -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - } - sleep (1); - -// START -// Clear the CRC Cache if it is populated -// -// Clear the CRC file Cache - safeMutexFTPProgress.Lock (); - Checksum::clearFileCache (); - - vector < string > paths = - Config::getInstance ().getPathListForType (ptTilesets); - string pathSearchString = string ("/") + itemName + string ("/*"); - const - string - filterFileExt = ".xml"; - clearFolderTreeContentsCheckSum (paths, pathSearchString, - filterFileExt); - clearFolderTreeContentsCheckSumList (paths, pathSearchString, - filterFileExt); - -// Refresh CRC - -//printf("Got map itemName [%s] file [%s] lastCheckedCRCMapName [%s] gameSettings->getMap() [%s]\n", -// itemName.c_str(),file.c_str(),lastCheckedCRCMapName.c_str(),gameSettings->getMap().c_str()); - - if (gameSettings != NULL && itemName == gameSettings->getTileset () - && lastCheckedCRCTilesetName == gameSettings->getTileset () - && gameSettings->getTileset () != "") - { - Config & config = Config::getInstance (); - lastCheckedCRCTilesetValue = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTilesets, ""), - string ("/") + itemName + string ("/*"), ".xml", NULL, true); - } - - safeMutexFTPProgress.ReleaseLock (); -// END - -// Reload tilesets for the UI - string - scenarioDir = - Scenario::getScenarioDir (dirList, gameSettings->getScenario ()); - findDirs (Config::getInstance ().getPathListForType (ptTilesets, - scenarioDir), - tilesetFiles); - - std::vector < string > tilesetsFormatted = tilesetFiles; - std::for_each (tilesetsFormatted.begin (), tilesetsFormatted.end (), - FormatString ()); - listBoxTileset.setItems (tilesetsFormatted); - } - else - { - curl_version_info_data * - curlVersion = curl_version_info (CURLVERSION_NOW); - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingTilesetFailDownload", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString ("DataMissingTilesetFailDownload", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), - (itemName + "(.7z)").c_str (), curlVersion->version); - } - else - { - snprintf (szMsg, 8096, - "Player: %s FAILED to download the tileset: [%s] using CURL version [%s]", - getHumanPlayerName ().c_str (), - (itemName + "(.7z)").c_str (), curlVersion->version); - } - clientInterface->sendTextMessage (szMsg, -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - - if (result.first == ftp_crt_HOST_NOT_ACCEPTING) - { - if (lang.hasString ("HostNotAcceptingDataConnections", - languageList[i]) == true) - { - clientInterface->sendTextMessage (lang.getString - ("HostNotAcceptingDataConnections", - languageList[i]), -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - } - else - { - clientInterface->sendTextMessage - ("*Warning* the host is not accepting data connections.", - -1, lang.isLanguageLocal (languageList[i]), - languageList[i]); - } - } - } - sleep (1); - - console.addLine (result.second, true); - } - } - else if (type == ftp_cct_Techtree) - { - getMissingTechtreeFromFTPServerInProgress = false; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Got FTP Callback for [%s] result = %d [%s]\n", - itemName.c_str (), result.first, result.second.c_str ()); - - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread->getProgressMutex () : - NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - fileFTPProgressList.erase (itemName); - safeMutexFTPProgress.ReleaseLock (true); - - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - const GameSettings * - gameSettings = clientInterface->getGameSettings (); - - if (result.first == ftp_crt_SUCCESS) - { - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingTechtreeSuccessDownload", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString ("DataMissingTechtreeSuccessDownload", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), itemName.c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Player: %s SUCCESSFULLY downloaded the techtree: %s", - getHumanPlayerName ().c_str (), itemName.c_str ()); - } - clientInterface->sendTextMessage (szMsg, -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - } - sleep (1); - -// START -// Clear the CRC Cache if it is populated -// -// Clear the CRC file Cache - safeMutexFTPProgress.Lock (); - Checksum::clearFileCache (); - - vector < string > paths = - Config::getInstance ().getPathListForType (ptTechs); - string pathSearchString = string ("/") + itemName + string ("/*"); - const - string - filterFileExt = ".xml"; - clearFolderTreeContentsCheckSum (paths, pathSearchString, - filterFileExt); - clearFolderTreeContentsCheckSumList (paths, pathSearchString, - filterFileExt); - -// Refresh CRC - if (gameSettings != NULL && itemName == gameSettings->getTech () && - lastCheckedCRCTechtreeName == gameSettings->getTech () && - gameSettings->getTech () != "") - { - Config & config = Config::getInstance (); - lastCheckedCRCTechtreeValue = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), - string ("/") + itemName + string ("/*"), ".xml", NULL, true); - } - safeMutexFTPProgress.ReleaseLock (); -// END - -// Reload techs for the UI - string - scenarioDir = - Scenario::getScenarioDir (dirList, gameSettings->getScenario ()); - findDirs (Config:: - getInstance ().getPathListForType (ptTechs, scenarioDir), - techTreeFiles); - - vector < string > translatedTechs; - std::vector < string > techsFormatted = techTreeFiles; - for (int i = 0; i < (int) techsFormatted.size (); i++) - { - techsFormatted.at (i) = formatString (techsFormatted.at (i)); - - string - txTech = - techTree->getTranslatedName (techTreeFiles.at (i), true); - translatedTechs.push_back (formatString (txTech)); - } - listBoxTechTree.setItems (techsFormatted, translatedTechs); - } - else - { - curl_version_info_data * - curlVersion = curl_version_info (CURLVERSION_NOW); - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < (unsigned int) languageList.size (); - ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingTechtreeFailDownload", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString ("DataMissingTechtreeFailDownload", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), - (itemName + "(.7z)").c_str (), curlVersion->version); - } - else - { - snprintf (szMsg, 8096, - "Player: %s FAILED to download the techtree: [%s] using CURL version [%s]", - getHumanPlayerName ().c_str (), - (itemName + "(.7z)").c_str (), curlVersion->version); - } - clientInterface->sendTextMessage (szMsg, -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - - if (result.first == ftp_crt_HOST_NOT_ACCEPTING) - { - if (lang.hasString ("HostNotAcceptingDataConnections", - languageList[i]) == true) - { - clientInterface->sendTextMessage (lang.getString - ("HostNotAcceptingDataConnections", - languageList[i]), -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - } - else - { - clientInterface->sendTextMessage - ("*Warning* the host is not accepting data connections.", - -1, lang.isLanguageLocal (languageList[i]), - languageList[i]); - } - } - } - sleep (1); - - console.addLine (result.second, true); - } - } - else if (type == ftp_cct_TempFile) - { - getInProgressSavedGameFromFTPServerInProgress = false; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Got FTP Callback for [%s] result = %d [%s]\n", - itemName.c_str (), result.first, result.second.c_str ()); - - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread->getProgressMutex () : - NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); -//fileFTPProgressList.erase(itemName); - std::map < string, pair < int, - string > >::iterator - iterFind = fileFTPProgressList.find (itemName); - if (iterFind == fileFTPProgressList.end ()) - { - iterFind = - fileFTPProgressList.find (GameConstants:: - saveNetworkGameFileServerCompressed); - if (iterFind == fileFTPProgressList.end ()) - { - iterFind = - fileFTPProgressList.find (GameConstants:: - saveNetworkGameFileClientCompressed); - } - } - if (iterFind != fileFTPProgressList.end ()) - { - fileFTPProgressList.erase (iterFind->first); - } - safeMutexFTPProgress.ReleaseLock (); - -//printf("Status update downloading saved game file: [%s]\n",itemName.c_str()); - - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); -//const GameSettings *gameSettings = clientInterface->getGameSettings(); - - if (result.first == ftp_crt_SUCCESS) - { - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("JoinPlayerToCurrentGameSuccessDownload", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString - ("JoinPlayerToCurrentGameSuccessDownload", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), itemName.c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Player: %s SUCCESSFULLY downloaded the saved game: %s", - getHumanPlayerName ().c_str (), itemName.c_str ()); - } - clientInterface->sendTextMessage (szMsg, -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - } - sleep (1); - - if (itemName == GameConstants::saveNetworkGameFileClientCompressed) - { - string saveGameFilePath = "temp/"; - string - saveGameFile = - saveGameFilePath + - string (GameConstants::saveNetworkGameFileClientCompressed); - if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) - != "") - { - saveGameFilePath = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) - + saveGameFilePath; - saveGameFile = - saveGameFilePath + - string (GameConstants::saveNetworkGameFileClientCompressed); - } - else - { - string - userData = - Config::getInstance ().getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - saveGameFilePath = userData + saveGameFilePath; - saveGameFile = - saveGameFilePath + - string (GameConstants::saveNetworkGameFileClientCompressed); - } - - string - extractedFileName = - saveGameFilePath + - string (GameConstants::saveNetworkGameFileClient); - bool - extract_result = - extractFileFromZIPFile (saveGameFile, extractedFileName); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Saved game [%s] compressed to [%s] returned: %d\n", - saveGameFile.c_str (), extractedFileName.c_str (), - extract_result); - } - readyToJoinInProgressGame = true; - -//printf("Success downloading saved game file: [%s]\n",itemName.c_str()); - } - else - { - curl_version_info_data * - curlVersion = curl_version_info (CURLVERSION_NOW); - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - char - szMsg[8096] = ""; - if (lang.hasString ("JoinPlayerToCurrentGameFailDownload", - languageList[i]) == true) - { - snprintf (szMsg, 8096, - lang.getString ("JoinPlayerToCurrentGameFailDownload", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), itemName.c_str (), - curlVersion->version); - } - else - { - snprintf (szMsg, 8096, - "Player: %s FAILED to download the saved game: [%s] using CURL version [%s]", - getHumanPlayerName ().c_str (), itemName.c_str (), - curlVersion->version); - } - clientInterface->sendTextMessage (szMsg, -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - - if (result.first == ftp_crt_HOST_NOT_ACCEPTING) - { - if (lang.hasString ("HostNotAcceptingDataConnections", - languageList[i]) == true) - { - clientInterface->sendTextMessage (lang.getString - ("HostNotAcceptingDataConnections", - languageList[i]), -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - } - else - { - clientInterface->sendTextMessage - ("*Warning* the host is not accepting data connections.", - -1, lang.isLanguageLocal (languageList[i]), - languageList[i]); - } - } - } - sleep (1); - - console.addLine (result.second, true); - } - } - } - - void - MenuStateConnectedGame::setupUIFromGameSettings (GameSettings * - gameSettings, - bool errorOnMissingData) - { - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - - updateDataSynchDetailText = true; - vector < string > tilesets, techtree; - - if (gameSettings == NULL) - { - throw megaglest_runtime_error ("gameSettings == NULL"); - } - - - checkBoxScenario.setValue ((gameSettings->getScenario () != "")); - if (checkBoxScenario.getValue () == true) - { - int - originalFOWValue = listBoxFogOfWar.getSelectedItemIndex (); - - string scenario = gameSettings->getScenario (); - listBoxScenario.setSelectedItem (formatString (scenario)); - string file = Scenario::getScenarioPath (dirList, scenario); - - bool isTutorial = Scenario::isGameTutorial (file); - Scenario::loadScenarioInfo (file, &scenarioInfo, isTutorial); - - gameSettings->setScenarioDir (Scenario::getScenarioPath - (dirList, scenarioInfo.name)); - - gameSettings->setDefaultResources (scenarioInfo.defaultResources); - gameSettings->setDefaultUnits (scenarioInfo.defaultUnits); - gameSettings-> - setDefaultVictoryConditions (scenarioInfo.defaultVictoryConditions); - - if (scenarioInfo.fogOfWar == false - && scenarioInfo.fogOfWar_exploredFlag == false) - { - listBoxFogOfWar.setSelectedItemIndex (2); - } - else if (scenarioInfo.fogOfWar_exploredFlag == true) - { - listBoxFogOfWar.setSelectedItemIndex (1); - } - else - { - listBoxFogOfWar.setSelectedItemIndex (0); - } - - checkBoxAllowTeamUnitSharing. - setValue (scenarioInfo.allowTeamUnitSharing); - checkBoxAllowTeamResourceSharing. - setValue (scenarioInfo.allowTeamResourceSharing); - - if (originalFOWValue != listBoxFogOfWar.getSelectedItemIndex ()) - { - cleanupMapPreviewTexture (); - } - } - - if (listBoxMapFilter.getSelectedItemIndex () != - gameSettings->getMapFilter ()) - { - switchToMapGroup (gameSettings->getMapFilter ()); -// printf("Switching to Map filter group %d \n",gameSettings->getMapFilter()); - } - - string - scenarioDir = - Scenario::getScenarioDir (dirList, gameSettings->getScenario ()); - setupMapList (gameSettings->getScenario ()); - setupTechList (gameSettings->getScenario ()); - setupTilesetList (gameSettings->getScenario ()); - - -//printf("A gameSettings->getTileset() [%s]\n",gameSettings->getTileset().c_str()); - - if (getMissingTilesetFromFTPServerInProgress == false - && gameSettings->getTileset () != "") - { -// tileset - tilesets = tilesetFiles; - std::for_each (tilesets.begin (), tilesets.end (), FormatString ()); - - if (std::find (tilesetFiles.begin (), tilesetFiles.end (), - gameSettings->getTileset ()) != tilesetFiles.end ()) - { - lastMissingTileSet = ""; - getMissingTilesetFromFTPServer = ""; - listBoxTileset.setSelectedItem (formatString - (gameSettings->getTileset ())); - } - else - { -// try to get the tileset via ftp - if (ftpClientThread != NULL && - (getMissingTilesetFromFTPServer != gameSettings->getTileset () - || difftime (time (NULL), - getMissingTilesetFromFTPServerLastPrompted) > - REPROMPT_DOWNLOAD_SECONDS)) - { - if (ftpMessageBox.getEnabled () == false) - { - getMissingTilesetFromFTPServerLastPrompted = time (NULL); - getMissingTilesetFromFTPServer = gameSettings->getTileset (); - Lang & lang = Lang::getInstance (); - - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "%s %s ?", - lang. - getString ("DownloadMissingTilesetQuestion").c_str (), - gameSettings->getTileset ().c_str ()); - -// Is the item in the mod center? - MutexSafeWrapper - safeMutexThread ((modHttpServerThread != - NULL ? - modHttpServerThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - if (tilesetCacheList.find (getMissingTilesetFromFTPServer) == - tilesetCacheList.end ()) - { - ftpMessageBox.init (lang.getString ("Yes"), - lang.getString ("NoDownload")); - } - else - { - ftpMessageBox.init (lang.getString ("ModCenter"), - lang.getString ("GameHost")); - ftpMessageBox.addButton (lang.getString ("NoDownload")); - } - safeMutexThread.ReleaseLock (); - - ftpMissingDataType = ftpmsg_MissingTileset; - showFTPMessageBox (szBuf, lang.getString ("Question"), false); - } - } - - tilesets. - push_back (Lang:: - getInstance ().getString ("DataMissing", "", true)); - - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - const GameSettings * - gameSettings = clientInterface->getGameSettings (); - - if (lastMissingTileSet != gameSettings->getTileset ()) - { - lastMissingTileSet = gameSettings->getTileset (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingTileset", languageList[i]) == - true) - { - snprintf (szMsg, 8096, - lang.getString ("DataMissingTileset", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), - gameSettings->getTileset ().c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Player: %s is missing the tileset: %s", - getHumanPlayerName ().c_str (), - gameSettings->getTileset ().c_str ()); - } - clientInterface->sendTextMessage (szMsg, -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - } - } - - listBoxTileset.setItems (tilesets); - listBoxTileset. - setSelectedItem (Lang:: - getInstance ().getString ("DataMissing", "", - true)); - } - - } - - if (getMissingTechtreeFromFTPServerInProgress == false && - gameSettings->getTech () != "") - { -// techtree - techtree = techTreeFiles; - std::for_each (techtree.begin (), techtree.end (), FormatString ()); - - if (std::find (techTreeFiles.begin (), techTreeFiles.end (), - gameSettings->getTech ()) != techTreeFiles.end ()) - { - - lastMissingTechtree = ""; - getMissingTechtreeFromFTPServer = ""; - reloadFactions (true, gameSettings->getScenario ()); - listBoxTechTree.setSelectedItem (formatString - (gameSettings->getTech ())); - } - else - { -// try to get the tileset via ftp - if (ftpClientThread != NULL - && (getMissingTechtreeFromFTPServer != gameSettings->getTech () - || difftime (time (NULL), - getMissingTechtreeFromFTPServerLastPrompted) > - REPROMPT_DOWNLOAD_SECONDS)) - { - if (ftpMessageBox.getEnabled () == false) - { - getMissingTechtreeFromFTPServerLastPrompted = time (NULL); - getMissingTechtreeFromFTPServer = gameSettings->getTech (); - Lang & lang = Lang::getInstance (); - - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "%s %s ?", - lang. - getString ("DownloadMissingTechtreeQuestion").c_str - (), gameSettings->getTech ().c_str ()); - -// Is the item in the mod center? - MutexSafeWrapper - safeMutexThread ((modHttpServerThread != - NULL ? - modHttpServerThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - if (techCacheList.find (getMissingTechtreeFromFTPServer) == - techCacheList.end ()) - { - ftpMessageBox.init (lang.getString ("Yes"), - lang.getString ("NoDownload")); - } - else - { - ftpMessageBox.init (lang.getString ("ModCenter"), - lang.getString ("GameHost")); - ftpMessageBox.addButton (lang.getString ("NoDownload")); - } - safeMutexThread.ReleaseLock (); - - ftpMissingDataType = ftpmsg_MissingTechtree; - showFTPMessageBox (szBuf, lang.getString ("Question"), false); - } - } - - techtree. - push_back (Lang:: - getInstance ().getString ("DataMissing", "", true)); - - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - const GameSettings * - gameSettings = clientInterface->getGameSettings (); - - if (lastMissingTechtree != gameSettings->getTech ()) - { - lastMissingTechtree = gameSettings->getTech (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - Lang & lang = Lang::getInstance (); - const - vector < - string > - languageList = - clientInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int i = 0; i < languageList.size (); ++i) - { - - char - szMsg[8096] = ""; - if (lang.hasString ("DataMissingTechtree", languageList[i]) == - true) - { - snprintf (szMsg, 8096, - lang.getString ("DataMissingTechtree", - languageList[i]).c_str (), - getHumanPlayerName ().c_str (), - gameSettings->getTech ().c_str ()); - } - else - { - snprintf (szMsg, 8096, - "Player: %s is missing the techtree: %s", - getHumanPlayerName ().c_str (), - gameSettings->getTech ().c_str ()); - } - clientInterface->sendTextMessage (szMsg, -1, - lang.isLanguageLocal - (languageList[i]), - languageList[i]); - } - } - - vector < string > translatedTechs; - for (unsigned int i = 0; i < techTreeFiles.size (); i++) - { - string - txTech = techTree->getTranslatedName (techTreeFiles.at (i)); - translatedTechs.push_back (txTech); - } - listBoxTechTree.setItems (techtree, translatedTechs); - listBoxTechTree. - setSelectedItem (Lang:: - getInstance ().getString ("DataMissing", "", - true)); - } - } - -// factions - bool hasFactions = true; - if (currentFactionName != gameSettings->getTech () - && gameSettings->getTech () != "") - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] hasFactions = %d, currentFactionName [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, hasFactions, - currentFactionName.c_str ()); - currentFactionName = gameSettings->getTech (); - hasFactions = loadFactions (gameSettings, false); - } - else - { -// do this to process special faction types like observers - loadFactions (gameSettings, false); - } - - - if (getMissingMapFromFTPServerInProgress == false && - gameSettings->getMap () != "" - && gameSettings->getMapFilter () == - listBoxMapFilter.getSelectedItemIndex ()) - { -// map - bool missingMap = false; - string mapFile = gameSettings->getMap (); - mapFile = formatString (mapFile); - - if (currentMap != gameSettings->getMap ()) - { // load the setup again - currentMap = gameSettings->getMap (); - } - bool - mapLoaded = - loadMapInfo (Config::getMapPath (currentMap, scenarioDir, false), - &mapInfo, true); - if (mapLoaded == false) - { -// try to get the map via ftp - if (ftpClientThread != NULL - && (getMissingMapFromFTPServer != currentMap - || difftime (time (NULL), - getMissingMapFromFTPServerLastPrompted) > - REPROMPT_DOWNLOAD_SECONDS)) - { - if (ftpMessageBox.getEnabled () == false) - { - getMissingMapFromFTPServerLastPrompted = time (NULL); - getMissingMapFromFTPServer = currentMap; - Lang & lang = Lang::getInstance (); - - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "%s %s ?", - lang. - getString ("DownloadMissingMapQuestion").c_str (), - currentMap.c_str ()); - -// Is the item in the mod center? - MutexSafeWrapper - safeMutexThread ((modHttpServerThread != - NULL ? - modHttpServerThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + - intToStr (__LINE__)); - if (mapCacheList.find (getMissingMapFromFTPServer) == - mapCacheList.end ()) - { - ftpMessageBox.init (lang.getString ("Yes"), - lang.getString ("NoDownload")); - } - else - { - ftpMessageBox.init (lang.getString ("ModCenter"), - lang.getString ("GameHost")); - ftpMessageBox.addButton (lang.getString ("NoDownload")); - } - safeMutexThread.ReleaseLock (); - - ftpMissingDataType = ftpmsg_MissingMap; - showFTPMessageBox (szBuf, lang.getString ("Question"), false); - } - } - - formattedPlayerSortedMaps[gameSettings-> - getMapFilter ()].push_back (Lang:: - getInstance - ().getString - ("DataMissing", - "", true)); - mapFile = Lang::getInstance ().getString ("DataMissing", "", true); - missingMap = true; - } - - if (isHeadlessAdmin () && !missingMap - && mapFile != listBoxMap.getSelectedItem ()) - { -//console.addLine("Headless server does not have map, switching to next one"); - if (isfirstSwitchingMapMessage) - { - isfirstSwitchingMapMessage = false; - } - else - { - console.addLine (Lang::getInstance ().getString - ("HeadlessServerDoesNotHaveMap", "", true)); - } - } - listBoxMap.setItems (formattedPlayerSortedMaps - [gameSettings->getMapFilter ()]); - -//printf("Setting map from game settings map:%s , settingsfilter=%d , boxfilter=%d \n",gameSettings->getMap().c_str(),gameSettings->getMapFilter(),listBoxMapFilter.getSelectedItemIndex()); - listBoxMap.setSelectedItem (mapFile); - labelMapInfo.setText (mapInfo.desc); - } - -// FogOfWar - if (checkBoxScenario.getValue () == false) - { - int - originalFOWValue = listBoxFogOfWar.getSelectedItemIndex (); - listBoxFogOfWar.setSelectedItemIndex (0); // default is 0! - if (gameSettings->getFogOfWar () == false) - { - listBoxFogOfWar.setSelectedItemIndex (2); - } - if ((gameSettings->getFlagTypes1 () & ft1_show_map_resources) == - ft1_show_map_resources) - { - if (gameSettings->getFogOfWar () == true) - { - listBoxFogOfWar.setSelectedItemIndex (1); - } - } - if (originalFOWValue != listBoxFogOfWar.getSelectedItemIndex ()) - { - cleanupMapPreviewTexture (); - } - } - -// Allow Observers - if (gameSettings->getAllowObservers ()) - { - checkBoxAllowObservers.setValue (true); - } - else - { - checkBoxAllowObservers.setValue (false); - } - - if ((gameSettings->getFlagTypes1 () & ft1_allow_team_switching) == - ft1_allow_team_switching) - { - checkBoxEnableSwitchTeamMode.setValue (true); - } - else - { - checkBoxEnableSwitchTeamMode.setValue (false); - } - listBoxAISwitchTeamAcceptPercent.setSelectedItem (intToStr - (gameSettings->getAiAcceptSwitchTeamPercentChance - ())); - listBoxFallbackCpuMultiplier. - setSelectedItemIndex (gameSettings->getFallbackCpuMultiplier ()); - - if ((gameSettings->getFlagTypes1 () & ft1_allow_shared_team_units) == - ft1_allow_shared_team_units) - { - checkBoxAllowTeamUnitSharing.setValue (true); - } - else - { - checkBoxAllowTeamUnitSharing.setValue (false); - } - - if ((gameSettings->getFlagTypes1 () & ft1_allow_shared_team_resources) - == ft1_allow_shared_team_resources) - { - checkBoxAllowTeamResourceSharing.setValue (true); - } - else - { - checkBoxAllowTeamResourceSharing.setValue (false); - } - - checkBoxAllowNativeLanguageTechtree. - setValue (gameSettings->getNetworkAllowNativeLanguageTechtree ()); - -// Control - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - listBoxControls[i].setSelectedItemIndex (ctClosed); - - if (isHeadlessAdmin () == false) - { - if (clientInterface->getJoinGameInProgress () == false) - { - listBoxFactions[i].setEditable (false); - listBoxTeams[i].setEditable (false); - } - } - - labelPlayerStatus[i].setTexture (NULL);; - } - - if (hasFactions == true && gameSettings != NULL) - { - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - -//for(int i=0; i < gameSettings->getFactionCount(); ++i){ - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - int - slot = gameSettings->getStartLocationIndex (i); - - if (slot == clientInterface->getPlayerIndex ()) - { - labelPlayerNames[slot].setEditable (true); - } - else - { - labelPlayerNames[slot].setEditable (false); - } - - if (i >= mapInfo.players) - { - if (gameSettings->getFactionControl (i) != ctNetworkUnassigned) - { - continue; - } - else if (clientInterface->getPlayerIndex () != slot) - { - continue; - } - } - - if (gameSettings->getFactionControl (i) == ctNetwork || - gameSettings->getFactionControl (i) == ctNetworkUnassigned || - gameSettings->getFactionControl (i) == ctHuman) - { - switch (gameSettings->getNetworkPlayerStatuses (i)) - { - case npst_BeRightBack: - labelPlayerStatus[slot]. - setTexture (CoreData::getInstance ().getStatusBRBTexture ()); - break; - case npst_Ready: - labelPlayerStatus[slot]. - setTexture (CoreData:: - getInstance ().getStatusReadyTexture ()); - break; - case npst_PickSettings: - labelPlayerStatus[slot]. - setTexture (CoreData:: - getInstance ().getStatusNotReadyTexture ()); - break; - case npst_Disconnected: - labelPlayerStatus[slot].setTexture (NULL); - break; - - default: - labelPlayerStatus[slot].setTexture (NULL); - break; - } - } - - listBoxControls[slot]. - setSelectedItemIndex (gameSettings->getFactionControl (i), - errorOnMissingData); - listBoxRMultiplier[slot]. - setSelectedItemIndex (gameSettings->getResourceMultiplierIndex - (i), errorOnMissingData); - listBoxTeams[slot].setSelectedItemIndex (gameSettings->getTeam (i), - errorOnMissingData); - listBoxFactions[slot].setSelectedItem (formatString - (gameSettings-> - getFactionTypeName (i)), - false); - - if (gameSettings->getFactionControl (i) == ctNetwork || - gameSettings->getFactionControl (i) == ctNetworkUnassigned) - { - labelNetStatus[slot]. - setText (gameSettings->getNetworkPlayerName (i)); - if (gameSettings->getThisFactionIndex () != i - && gameSettings->getNetworkPlayerName (i) != "" - && gameSettings->getNetworkPlayerName (i) != - GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) - { - labelPlayerNames[slot]. - setText (gameSettings->getNetworkPlayerName (i)); - } - } - - ControlType ct = gameSettings->getFactionControl (i); - if (ct == ctHuman || ct == ctNetwork || ct == ctClosed) - { - listBoxRMultiplier[slot].setEnabled (false); - listBoxRMultiplier[slot].setVisible (false); - } - else - { - listBoxRMultiplier[slot].setEnabled (true); - listBoxRMultiplier[slot].setVisible (true); - } - - if ((gameSettings->getFactionControl (i) == ctNetwork || - gameSettings->getFactionControl (i) == ctNetworkUnassigned) && - gameSettings->getThisFactionIndex () == i) - { - -// set my current slot to ctHuman - if (gameSettings->getFactionControl (i) != ctNetworkUnassigned) - { - listBoxControls[slot].setSelectedItemIndex (ctHuman); - } - if (checkBoxScenario.getValue () == false) - { - if (clientInterface->getJoinGameInProgress () == false) - { - if (i <= mapInfo.hardMaxPlayers) - { - listBoxFactions[slot].setEditable (true); - listBoxTeams[slot].setEditable (true); - } - else - { - // looks more must be done to allow people to take an observer - // slot after the game has started. Extra network slots close - // when the game starts. - listBoxFactions[slot].setEditable (checkBoxAllowObservers.getValue ()); - listBoxTeams[slot].setEditable (checkBoxAllowObservers.getValue ()); - } - } - } - - if (labelPlayerNames[slot].getText () == "" && - gameSettings->getNetworkPlayerName (i) != "" && - gameSettings->getNetworkPlayerName (i) != - GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) - { - labelPlayerNames[slot]. - setText (gameSettings->getNetworkPlayerName (i)); - } - } - } - settingsReceivedFromServer = true; - initialSettingsReceivedFromServer = true; - - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - - if (enableFactionTexturePreview == true) - { - if (clientInterface != NULL && clientInterface->isConnected () && - gameSettings != NULL) - { - - if (currentTechName_factionPreview != gameSettings->getTech () || - currentFactionName_factionPreview != - gameSettings-> - getFactionTypeName (gameSettings->getThisFactionIndex ())) - { - - currentTechName_factionPreview = gameSettings->getTech (); - currentFactionName_factionPreview = - gameSettings-> - getFactionTypeName (gameSettings->getThisFactionIndex ()); - - initFactionPreview (gameSettings); - } - } - } - - } - - void - MenuStateConnectedGame::initFactionPreview (const GameSettings * - gameSettings) - { - string factionVideoUrl = ""; - string factionVideoUrlFallback = ""; - - string - factionDefinitionXML = - Game::findFactionLogoFile (gameSettings, NULL, - currentFactionName_factionPreview + - ".xml"); - if (factionDefinitionXML != "" - && currentFactionName_factionPreview != - GameConstants::RANDOMFACTION_SLOTNAME - && currentFactionName_factionPreview != - GameConstants::OBSERVER_SLOTNAME - && fileExists (factionDefinitionXML) == true) - { - XmlTree xmlTree; - std::map < string, string > mapExtraTagReplacementValues; - xmlTree.load (factionDefinitionXML, - Properties::getTagReplacementValues - (&mapExtraTagReplacementValues)); - const XmlNode * - factionNode = xmlTree.getRootNode (); - if (factionNode->hasAttribute ("faction-preview-video") == true) - { - factionVideoUrl = - factionNode->getAttribute ("faction-preview-video")->getValue (); - } - - factionVideoUrlFallback = - Game::findFactionLogoFile (gameSettings, NULL, "preview_video.*"); - if (factionVideoUrl == "") - { - factionVideoUrl = factionVideoUrlFallback; - factionVideoUrlFallback = ""; - } - } - - if (factionVideoUrl != "") - { - if (CoreData::getInstance ().getMenuMusic ()->getVolume () != 0) - { - CoreData::getInstance ().getMenuMusic ()->setVolume (0); - factionVideoSwitchedOffVolume = true; - } - - if (currentFactionLogo != factionVideoUrl) - { - currentFactionLogo = factionVideoUrl; - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false - &&::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer () == - true) - { - - if (factionVideo != NULL) - { - factionVideo->closePlayer (); - delete factionVideo; - factionVideo = NULL; - } - string introVideoFile = factionVideoUrl; - string introVideoFileFallback = factionVideoUrlFallback; - - Context * - c = GraphicsInterface::getInstance ().getCurrentContext (); - PlatformContextGl * - glCtx = - static_cast < ContextGl * >(c)->getPlatformContextGlPtr (); - SDL_Window * - window = glCtx->getScreenWindow (); - SDL_Surface * - screen = glCtx->getScreenSurface (); - - string - vlcPluginsPath = - Config::getInstance ().getString ("VideoPlayerPluginsPath", ""); -//printf("screen->w = %d screen->h = %d screen->format->BitsPerPixel = %d\n",screen->w,screen->h,screen->format->BitsPerPixel); - factionVideo = new VideoPlayer (&Renderer::getInstance (), - introVideoFile, - introVideoFileFallback, - window, - 0, 0, - screen->w, - screen->h, - screen->format->BitsPerPixel, - true, - vlcPluginsPath, - SystemFlags::VERBOSE_MODE_ENABLED); - factionVideo->initPlayer (); - } - } - } - else - { -//switch on music again!! - Config & config = Config::getInstance (); - float - configVolume = (config.getInt ("SoundVolumeMusic") / 100.f); - if (factionVideoSwitchedOffVolume) - { - if (CoreData::getInstance ().getMenuMusic ()->getVolume () != - configVolume) - { - CoreData::getInstance (). - getMenuMusic ()->setVolume (configVolume); - } - factionVideoSwitchedOffVolume = false; - } - - if (factionVideo != NULL) - { - factionVideo->closePlayer (); - delete factionVideo; - factionVideo = NULL; - } - } - - if (factionVideo == NULL) - { - string - factionLogo = - Game::findFactionLogoFile (gameSettings, NULL, - GameConstants::PREVIEW_SCREEN_FILE_FILTER); - if (factionLogo == "") - { - factionLogo = Game::findFactionLogoFile (gameSettings, NULL); - } - if (currentFactionLogo != factionLogo) - { - currentFactionLogo = factionLogo; - loadFactionTexture (currentFactionLogo); - } - } - } - - void - MenuStateConnectedGame::RestoreLastGameSettings () - { -// Ensure we have set the gamesettings at least once - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface * - clientInterface = networkManager.getClientInterface (); - GameSettings gameSettings = *clientInterface->getGameSettings (); - CoreData:: - getInstance ().loadGameSettingsFromFile (HEADLESS_SAVED_GAME_FILENAME, - &gameSettings); - if (gameSettings.getMap () == "") - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - loadGameSettings (&gameSettings); - } - - setupUIFromGameSettings (&gameSettings, false); - - needToBroadcastServerSettings = true; - broadcastServerSettingsDelayTimer = time (NULL); - noReceiveTimer = time (NULL); - - } - - int - MenuStateConnectedGame::setupMapList (string scenario) - { - int - initialMapSelection = 0; - - try - { - Config & config = Config::getInstance (); - vector < string > invalidMapList; - string scenarioDir = Scenario::getScenarioDir (dirList, scenario); - vector < string > pathList = - config.getPathListForType (ptMaps, scenarioDir); - vector < string > allMaps = - MapPreview::findAllValidMaps (pathList, scenarioDir, false, true, - &invalidMapList); -// sort map list non case sensitive - std::sort (allMaps.begin (), allMaps.end (), compareNonCaseSensitive); - if (scenario != "") - { - vector < string > allMaps2 = - MapPreview:: - findAllValidMaps (config.getPathListForType (ptMaps, ""), "", - false, true, &invalidMapList); - copy (allMaps2.begin (), allMaps2.end (), - std::inserter (allMaps, allMaps.begin ())); - std::sort (allMaps.begin (), allMaps.end (), - compareNonCaseSensitive); - } - - if (allMaps.empty ()) - { - throw megaglest_runtime_error ("No maps were found!"); - } - vector < string > results; - copy (allMaps.begin (), allMaps.end (), std::back_inserter (results)); - mapFiles = results; - - for (unsigned int i = 0; i < GameConstants::maxPlayers + 1; ++i) - { - playerSortedMaps[i].clear (); - formattedPlayerSortedMaps[i].clear (); - } - - copy (mapFiles.begin (), mapFiles.end (), - std::back_inserter (playerSortedMaps[0])); - copy (playerSortedMaps[0].begin (), playerSortedMaps[0].end (), - std::back_inserter (formattedPlayerSortedMaps[0])); - std::for_each (formattedPlayerSortedMaps[0].begin (), - formattedPlayerSortedMaps[0].end (), FormatString ()); - - formattedMapFiles.clear (); - for (int i = 0; i < (int) mapFiles.size (); i++) - { // fetch info and put map in right list - loadMapInfo (Config::getMapPath - (mapFiles.at (i), scenarioDir, false), &mapInfo, - false); - - if (GameConstants::maxPlayers + 1 <= mapInfo.players) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Sorted map list [%d] does not match\ncurrent map playercount [%d]\nfor file [%s]\nmap [%s]", - GameConstants::maxPlayers + 1, mapInfo.players, - Config::getMapPath (mapFiles.at (i), "", - false).c_str (), - mapInfo.desc.c_str ()); - throw megaglest_runtime_error (szBuf); - } - playerSortedMaps[mapInfo.hardMaxPlayers].push_back (mapFiles.at (i)); - formattedPlayerSortedMaps[mapInfo.hardMaxPlayers].push_back (formatString - (mapFiles.at - (i))); - if (config.getString ("InitialMap", "Conflict") == - formattedPlayerSortedMaps[mapInfo.hardMaxPlayers].back ()) - { - initialMapSelection = i; - } - formattedMapFiles.push_back (formatString (mapFiles.at (i))); - } - - if (scenario != "") - { - string file = Scenario::getScenarioPath (dirList, scenario); - loadScenarioInfo (file, &scenarioInfo); - - loadMapInfo (Config::getMapPath - (scenarioInfo.mapName, scenarioDir, true), &mapInfo, - false); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line %d] listBoxMap.getSelectedItemIndex() = %d, mapFiles.size() = " - MG_SIZE_T_SPECIFIER - ", mapInfo.players = %d, formattedPlayerSortedMaps[mapInfo.players].size() = " - MG_SIZE_T_SPECIFIER ", scenarioInfo.mapName [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), __FUNCTION__, - __LINE__, listBoxMap.getSelectedItemIndex (), mapFiles.size (), - mapInfo.players, - formattedPlayerSortedMaps[mapInfo.players].size (), - scenarioInfo.mapName.c_str ()); - listBoxMap.setItems (formattedPlayerSortedMaps[mapInfo.players]); - } - } - catch (const std::exception & ex) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - throw megaglest_runtime_error (szBuf); -//abort(); - } - - return initialMapSelection; - } - - int - MenuStateConnectedGame::setupTechList (string scenario, bool forceLoad) - { - int - initialTechSelection = 0; - try - { - Config & config = Config::getInstance (); - - string scenarioDir = Scenario::getScenarioDir (dirList, scenario); - vector < string > results; - vector < string > techPaths = - config.getPathListForType (ptTechs, scenarioDir); - findDirs (techPaths, results); - - if (results.empty ()) - { - throw megaglest_runtime_error ("No tech-trees were found!"); - } - - techTreeFiles = results; - - vector < string > translatedTechs; - - for (unsigned int i = 0; i < results.size (); i++) - { -//printf("TECHS i = %d results [%s] scenario [%s]\n",i,results[i].c_str(),scenario.c_str()); - - results.at (i) = formatString (results.at (i)); - if (config.getString ("InitialTechTree", "Megapack") == - results.at (i)) - { - initialTechSelection = i; - } - string - txTech = - techTree->getTranslatedName (techTreeFiles.at (i), forceLoad); - translatedTechs.push_back (formatString (txTech)); - } - - - listBoxTechTree.setItems (results, translatedTechs); - } - catch (const std::exception & ex) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - throw megaglest_runtime_error (szBuf); - } - - return initialTechSelection; - } - - void - MenuStateConnectedGame::setupTilesetList (string scenario) - { - try - { - Config & config = Config::getInstance (); - - string scenarioDir = Scenario::getScenarioDir (dirList, scenario); - - vector < string > results; - findDirs (config.getPathListForType (ptTilesets, scenarioDir), - results); - if (results.empty ()) - { -//throw megaglest_runtime_error("No tile-sets were found!"); - showMessageBox ("No tile-sets were found!", "Error", false); - } - else - { - tilesetFiles = results; - std::for_each (results.begin (), results.end (), FormatString ()); - - listBoxTileset.setItems (results); - } - } - catch (const std::exception & ex) - { - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - throw megaglest_runtime_error (szBuf); - } - } - - void - MenuStateConnectedGame::loadScenarioInfo (string file, - ScenarioInfo * scenarioInfo) - { - bool isTutorial = Scenario::isGameTutorial (file); - Scenario::loadScenarioInfo (file, scenarioInfo, isTutorial); - - previewLoadDelayTimer = time (NULL); - needToLoadTextures = true; - } - -}} //end namespace + if (factionFiles[listBoxFactions[i].getSelectedItemIndex()] != + formatString(GameConstants::OBSERVER_SLOTNAME)) { + if (listBoxTeams[i].getSelectedItemIndex() + 1 != + (GameConstants::maxPlayers + fpt_Observer)) { + //lastSelectedTeamIndex[i] = listBoxTeams[i].getSelectedItemIndex(); + } + } + + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + } + } + } + } catch (const std::exception & ex) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + showMessageBox(szBuf, "Error", false); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + void + MenuStateConnectedGame::PlayNow(bool saveGame) { + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + + GameSettings gameSettings = *clientInterface->getGameSettings(); + loadGameSettings(&gameSettings); + + if (saveGame == true) { + CoreData:: + getInstance().saveGameSettingsToFile(HEADLESS_SAVED_GAME_FILENAME, + &gameSettings, true); + } + + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + soundRenderer.playFx(coreData.getClickSoundC()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //printf("Client sending map [%s] admin key [%d]\n",gameSettings.getMap().c_str(),gameSettings.getMasterserver_admin()); + + if (clientInterface->getJoinGameInProgress() == true) { + if (readyToJoinInProgressGame == false && launchingNewGame == false) { + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("JoinPlayerToCurrentGameLaunch", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString("JoinPlayerToCurrentGameLaunch", + languageList[i]).c_str(), + getHumanPlayerName().c_str()); + } else { + snprintf(szMsg, 8096, + "Player: %s is about to join the game, please wait...", + getHumanPlayerName().c_str()); + } + bool localEcho = lang.isLanguageLocal(languageList[i]); + clientInterface->sendTextMessage(szMsg, -1, localEcho, + languageList[i]); + } + + sleep(1); + launchingNewGame = true; + clientInterface->broadcastGameStart(&gameSettings); + } + return; + } else { + launchingNewGame = true; + broadCastGameSettingsToHeadlessServer(needToBroadcastServerSettings); + clientInterface->broadcastGameStart(&gameSettings); + } + } + + void + MenuStateConnectedGame::switchToNextMapGroup(const int direction) { + int + i = listBoxMapFilter.getSelectedItemIndex(); + // if there are no maps for the current selection we switch to next selection + while (formattedPlayerSortedMaps[i].empty()) { + i = i + direction; + if (i > GameConstants::maxPlayers) { + i = 0; + } + if (i < 0) { + i = GameConstants::maxPlayers; + } + } + switchToMapGroup(i); + } + + void + MenuStateConnectedGame::switchToMapGroup(int filterIndex) { + int + i = filterIndex; + listBoxMapFilter.setSelectedItemIndex(i); + listBoxMap.setItems(formattedPlayerSortedMaps[i]); + // printf("switching map group to filter=%d mapgroup has %d maps. map=%s \n",i, + // (int)formattedPlayerSortedMaps[i].size(),formattedPlayerSortedMaps[i][0].c_str()); + } + + string MenuStateConnectedGame::getCurrentMapFile() { + int + i = listBoxMapFilter.getSelectedItemIndex(); + int + mapIndex = listBoxMap.getSelectedItemIndex(); + if (playerSortedMaps[i].empty() == false) { + return playerSortedMaps[i].at(mapIndex); + } + return ""; + } + + void + MenuStateConnectedGame::reloadFactions(bool keepExistingSelectedItem, + string scenario) { + vector < string > results; + Config & config = Config::getInstance(); + Lang & lang = Lang::getInstance(); + + string scenarioDir = Scenario::getScenarioDir(dirList, scenario); + vector < string > techPaths = + config.getPathListForType(ptTechs, scenarioDir); + for (int idx = 0; idx < (int) techPaths.size(); idx++) { + string & techPath = techPaths[idx]; + endPathWithSlash(techPath); + + if (listBoxTechTree.getSelectedItemIndex() >= 0 + && listBoxTechTree.getSelectedItemIndex() < + (int) techTreeFiles.size()) { + findDirs(techPath + + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + + "/factions/", results, false, false); + } + if (results.empty() == false) { + break; + } + } + + if (results.empty() == true) { + //throw megaglest_runtime_error("(2)There are no factions for the tech tree [" + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "]"); + //showGeneralError=true; + //generalErrorToShow = "[#2] There are no factions for the tech tree [" + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "]"; + } + + vector < string > translatedFactionNames; + factionFiles = results; + for (int i = 0; i < (int) results.size(); ++i) { + results[i] = formatString(results[i]); + string + translatedString = + techTree->getTranslatedFactionName(techTreeFiles + [listBoxTechTree. + getSelectedItemIndex()], + factionFiles[i]); + if (toLower(translatedString) == toLower(results[i])) { + translatedFactionNames.push_back(results[i]); + } else { + translatedFactionNames.push_back(results[i] + " (" + + translatedString + ")"); + } + //printf("FACTIONS i = %d results [%s]\n",i,results[i].c_str()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "Tech [%s] has faction [%s]\n", + techTreeFiles + [listBoxTechTree.getSelectedItemIndex + ()].c_str(), results[i].c_str()); + } + + results.push_back(formatString + (GameConstants::RANDOMFACTION_SLOTNAME)); + factionFiles.push_back(formatString + (GameConstants::RANDOMFACTION_SLOTNAME)); + translatedFactionNames.push_back("*" + + lang.getString("Random", "", + true) + "*"); + + // Add special Observer Faction + if (checkBoxAllowObservers.getValue() == 1) { + results.push_back(formatString(GameConstants::OBSERVER_SLOTNAME)); + factionFiles.push_back(formatString + (GameConstants::OBSERVER_SLOTNAME)); + translatedFactionNames.push_back("*" + + lang.getString("Observer", "", + true) + "*"); + } + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + int + originalIndex = listBoxFactions[i].getSelectedItemIndex(); + string + originalValue = + (listBoxFactions[i].getItemCount() > + 0 ? listBoxFactions[i].getSelectedItem() : ""); + + listBoxFactions[i].setItems(results, translatedFactionNames); + if (keepExistingSelectedItem == false || + (checkBoxAllowObservers.getValue() == true && + originalValue == + formatString(GameConstants::OBSERVER_SLOTNAME))) { + listBoxFactions[i].setSelectedItemIndex(i % results.size()); + + if (originalValue == formatString(GameConstants::OBSERVER_SLOTNAME) + && listBoxFactions[i].getSelectedItem() != + formatString(GameConstants::OBSERVER_SLOTNAME)) { + if (listBoxTeams[i].getSelectedItem() == + intToStr(GameConstants::maxPlayers + fpt_Observer)) { + listBoxTeams[i].setSelectedItem(intToStr(1)); + } + } + } else if (originalIndex < (int) results.size()) { + listBoxFactions[i].setSelectedItemIndex(originalIndex); + } + } + } + + void + MenuStateConnectedGame::loadGameSettings(GameSettings * gameSettings) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + int + factionCount = 0; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + // Test flags values + //gameSettings->setFlagTypes1(ft1_show_map_resources); + // + + if (checkBoxScenario.getValue() == true) { + gameSettings->setScenario(scenarioInfo.name); + gameSettings->setScenarioDir(Scenario::getScenarioPath + (dirList, scenarioInfo.name)); + + gameSettings->setDefaultResources(scenarioInfo.defaultResources); + gameSettings->setDefaultUnits(scenarioInfo.defaultUnits); + gameSettings-> + setDefaultVictoryConditions(scenarioInfo.defaultVictoryConditions); + } else { + gameSettings->setScenario(""); + gameSettings->setScenarioDir(""); + } + + gameSettings->setNetworkAllowNativeLanguageTechtree + (checkBoxAllowNativeLanguageTechtree.getValue()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line %d] listBoxMap.getSelectedItemIndex() = %d, mapFiles.size() = " + MG_SIZE_T_SPECIFIER ", getCurrentMapFile() [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, + __LINE__, listBoxMap.getSelectedItemIndex(), mapFiles.size(), + getCurrentMapFile().c_str()); + + if (listBoxMap.getSelectedItemIndex() >= 0 + && listBoxMap.getSelectedItemIndex() < (int) mapFiles.size()) { + gameSettings->setDescription(formatString(getCurrentMapFile())); + gameSettings->setMap(getCurrentMapFile()); + gameSettings->setMapFilter(listBoxMapFilter.getSelectedItemIndex()); + } else { + Lang & lang = Lang::getInstance(); + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingMap=Player", languageList[i]) == + true) { + snprintf(szMsg, 8096, + lang.getString("DataMissingMap=Player", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), + listBoxMap.getSelectedItem().c_str()); + } else { + snprintf(szMsg, 8096, "Player: %s is missing the map: %s", + getHumanPlayerName().c_str(), + listBoxMap.getSelectedItem().c_str()); + } + bool localEcho = lang.isLanguageLocal(languageList[i]); + clientInterface->sendTextMessage(szMsg, -1, localEcho, + languageList[i]); + } + } + + if (listBoxTileset.getSelectedItemIndex() >= 0 + && listBoxTileset.getSelectedItemIndex() < + (int) tilesetFiles.size()) { + gameSettings->setTileset(tilesetFiles + [listBoxTileset.getSelectedItemIndex()]); + } else { + //printf("A loadGameSettings listBoxTileset.getSelectedItemIndex() = %d tilesetFiles.size() = %d\n",listBoxTileset.getSelectedItemIndex(),tilesetFiles.size()); + + Lang & lang = Lang::getInstance(); + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingTileset=Player", languageList[i]) == + true) { + snprintf(szMsg, 8096, + lang.getString("DataMissingTileset=Player", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), + listBoxTileset.getSelectedItem().c_str()); + } else { + snprintf(szMsg, 8096, "Player: %s is missing the tileset: %s", + getHumanPlayerName().c_str(), + listBoxTileset.getSelectedItem().c_str()); + } + bool localEcho = lang.isLanguageLocal(languageList[i]); + clientInterface->sendTextMessage(szMsg, -1, localEcho, + languageList[i]); + } + } + if (listBoxTechTree.getSelectedItemIndex() >= 0 + && listBoxTechTree.getSelectedItemIndex() < + (int) techTreeFiles.size()) { + gameSettings->setTech(techTreeFiles + [listBoxTechTree.getSelectedItemIndex()]); + } else { + Lang & lang = Lang::getInstance(); + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingTechtree=Player", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString("DataMissingTechtree=Player", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), + listBoxTechTree.getSelectedItem().c_str()); + } else { + snprintf(szMsg, 8096, "Player: %s is missing the techtree: %s", + getHumanPlayerName().c_str(), + listBoxTechTree.getSelectedItem().c_str()); + } + bool localEcho = lang.isLanguageLocal(languageList[i]); + clientInterface->sendTextMessage(szMsg, -1, localEcho, + languageList[i]); + } + } + + if (checkBoxScenario.getValue() == false) { + gameSettings->setDefaultUnits(true); + gameSettings->setDefaultResources(true); + gameSettings->setDefaultVictoryConditions(true); + } + + gameSettings->setFogOfWar(listBoxFogOfWar.getSelectedItemIndex() == 0 + || listBoxFogOfWar.getSelectedItemIndex() == + 1); + + gameSettings->setAllowObservers(checkBoxAllowObservers.getValue() == + true); + + uint32 valueFlags1 = gameSettings->getFlagTypes1(); + if (listBoxFogOfWar.getSelectedItemIndex() == 1 || + listBoxFogOfWar.getSelectedItemIndex() == 2) { + valueFlags1 |= ft1_show_map_resources; + gameSettings->setFlagTypes1(valueFlags1); + } else { + valueFlags1 &= ~ft1_show_map_resources; + gameSettings->setFlagTypes1(valueFlags1); + } + + //gameSettings->setEnableObserverModeAtEndGame(listBoxEnableObserverMode.getSelectedItemIndex() == 0); + gameSettings->setEnableObserverModeAtEndGame(true); + //gameSettings->setPathFinderType(static_cast(listBoxPathFinderType.getSelectedItemIndex())); + + valueFlags1 = gameSettings->getFlagTypes1(); + if (checkBoxEnableSwitchTeamMode.getValue() == true) { + valueFlags1 |= ft1_allow_team_switching; + gameSettings->setFlagTypes1(valueFlags1); + } else { + valueFlags1 &= ~ft1_allow_team_switching; + gameSettings->setFlagTypes1(valueFlags1); + } + gameSettings->setAiAcceptSwitchTeamPercentChance(strToInt + (listBoxAISwitchTeamAcceptPercent.getSelectedItem + ())); + gameSettings-> + setFallbackCpuMultiplier + (listBoxFallbackCpuMultiplier.getSelectedItemIndex()); + + valueFlags1 = gameSettings->getFlagTypes1(); + if (checkBoxAllowTeamUnitSharing.getValue() == true) { + valueFlags1 |= ft1_allow_shared_team_units; + gameSettings->setFlagTypes1(valueFlags1); + } else { + valueFlags1 &= ~ft1_allow_shared_team_units; + gameSettings->setFlagTypes1(valueFlags1); + } + + valueFlags1 = gameSettings->getFlagTypes1(); + if (checkBoxAllowTeamResourceSharing.getValue() == true) { + valueFlags1 |= ft1_allow_shared_team_resources; + gameSettings->setFlagTypes1(valueFlags1); + } else { + valueFlags1 &= ~ft1_allow_shared_team_resources; + gameSettings->setFlagTypes1(valueFlags1); + } + + // First save Used slots + //for(int i=0; i + (listBoxControls[i].getSelectedItemIndex()); + + if (ct != ctClosed) { + int + slotIndex = factionCount; + ControlType + oldControlType = gameSettings->getFactionControl(slotIndex); + gameSettings->setFactionControl(slotIndex, ct); + if (ct == ctHuman) { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, slotIndex = %d, getHumanPlayerName(i) [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,slotIndex,getHumanPlayerName(i).c_str()); + + gameSettings->setThisFactionIndex(slotIndex); + gameSettings->setNetworkPlayerName(slotIndex, + getHumanPlayerName()); + gameSettings->setNetworkPlayerUUID(slotIndex, + Config:: + getInstance().getString + ("PlayerId", "")); + gameSettings->setNetworkPlayerPlatform(slotIndex, + getPlatformNameString()); + gameSettings->setNetworkPlayerStatuses(slotIndex, + getNetworkPlayerStatus + ()); + Lang & lang = Lang::getInstance(); + gameSettings->setNetworkPlayerLanguages(slotIndex, + lang.getLanguage()); + + gameSettings->setResourceMultiplierIndex(slotIndex, 5); + } else { + gameSettings->setResourceMultiplierIndex(slotIndex, + listBoxRMultiplier + [i].getSelectedItemIndex + ()); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] i = %d, factionFiles[listBoxFactions[i].getSelectedItemIndex()] [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, i, + factionFiles[listBoxFactions + [i].getSelectedItemIndex + ()].c_str()); + + gameSettings->setFactionTypeName(slotIndex, + factionFiles[listBoxFactions + [i].getSelectedItemIndex + ()]); + if (factionFiles[listBoxFactions[i].getSelectedItemIndex()] == + formatString(GameConstants::OBSERVER_SLOTNAME)) { + listBoxTeams[i].setSelectedItem(intToStr + (GameConstants::maxPlayers + + fpt_Observer)); + } + + gameSettings->setTeam(slotIndex, + listBoxTeams[i].getSelectedItemIndex()); + gameSettings->setStartLocationIndex(slotIndex, i); + //printf("!!! setStartLocationIndex #1 slotIndex = %d, i = %d\n",slotIndex, i); + + if (listBoxControls[i].getSelectedItemIndex() == ctNetwork + || listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned) { + if (oldControlType != ctNetwork + && oldControlType != ctNetworkUnassigned) { + gameSettings->setNetworkPlayerName(slotIndex, ""); + } + } else if (listBoxControls[i].getSelectedItemIndex() != ctHuman) { + AIPlayerCount++; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] i = %d, playername is AI (blank)\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, i); + + Lang & lang = Lang::getInstance(); + gameSettings->setNetworkPlayerName(slotIndex, + lang.getString("AI") + + intToStr(AIPlayerCount)); + labelPlayerNames[i].setText(""); + } + + factionCount++; + } else { + labelPlayerNames[i].setText(""); + } + } + + // Next save closed slots + int + closedCount = 0; + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + ControlType + ct = + static_cast + (listBoxControls[i].getSelectedItemIndex()); + if (ct == ctClosed) { + int + slotIndex = factionCount + closedCount; + + gameSettings->setFactionControl(slotIndex, ct); + gameSettings->setTeam(slotIndex, + listBoxTeams[i].getSelectedItemIndex()); + gameSettings->setStartLocationIndex(slotIndex, i); + //printf("!!! setStartLocationIndex #2 slotIndex = %d, i = %d\n",slotIndex, i); + + gameSettings->setResourceMultiplierIndex(slotIndex, 5); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] i = %d, factionFiles[listBoxFactions[i].getSelectedItemIndex()] [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, i, + factionFiles[listBoxFactions + [i].getSelectedItemIndex + ()].c_str()); + + gameSettings->setFactionTypeName(slotIndex, + factionFiles[listBoxFactions + [i].getSelectedItemIndex + ()]); + gameSettings->setNetworkPlayerStatuses(slotIndex, npst_None); + gameSettings->setNetworkPlayerName(slotIndex, + GameConstants::NETWORK_SLOT_CLOSED_SLOTNAME); + + closedCount++; + } + } + + gameSettings->setFactionCount(factionCount); + + Config & config = Config::getInstance(); + gameSettings->setEnableServerControlledAI(config.getBool + ("ServerControlledAI", + "true")); + gameSettings-> + setNetworkFramePeriod(config.getInt("NetworkSendFrameCount", "20")); + + if (hasNetworkGameSettings() == true) { + if (gameSettings->getTileset() != "") { + if (lastCheckedCRCTilesetName != gameSettings->getTileset()) { + //console.addLine("Checking tileset CRC [" + gameSettings->getTileset() + "]"); + lastCheckedCRCTilesetValue = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTilesets, ""), + string("/") + gameSettings->getTileset() + string("/*"), + ".xml", NULL); + if (lastCheckedCRCTilesetValue == 0 + || lastCheckedCRCTilesetValue != + gameSettings->getTilesetCRC()) { + lastCheckedCRCTilesetValue = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTilesets, ""), + string("/") + gameSettings->getTileset() + string("/*"), + ".xml", NULL, true); + } + lastCheckedCRCTilesetName = gameSettings->getTileset(); + } + gameSettings->setTilesetCRC(lastCheckedCRCTilesetValue); + } + + if (config.getBool("DisableServerLobbyTechtreeCRCCheck", "false") == + false) { + if (gameSettings->getTech() != "") { + if (lastCheckedCRCTechtreeName != gameSettings->getTech()) { + //console.addLine("Checking techtree CRC [" + gameSettings->getTech() + "]"); + lastCheckedCRCTechtreeValue = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), + "/" + gameSettings->getTech() + "/*", ".xml", NULL); + if (lastCheckedCRCTechtreeValue == 0 + || lastCheckedCRCTechtreeValue != + gameSettings->getTechCRC()) { + lastCheckedCRCTechtreeValue = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), + "/" + gameSettings->getTech() + "/*", ".xml", NULL, true); + } + + reloadFactions(true, gameSettings->getScenario()); + factionCRCList.clear(); + for (unsigned int factionIdx = 0; + factionIdx < factionFiles.size(); ++factionIdx) { + string factionName = factionFiles[factionIdx]; + if (factionName != GameConstants::RANDOMFACTION_SLOTNAME && + factionName != GameConstants::OBSERVER_SLOTNAME) { + //factionCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + gameSettings->getTech() + "/factions/" + factionName + "/*", ".xml", NULL, true); + uint32 + factionCRC = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), + "/" + gameSettings->getTech() + "/factions/" + + factionName + "/*", ".xml", NULL); + if (factionCRC == 0) { + factionCRC = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), + "/" + gameSettings->getTech() + "/factions/" + + factionName + "/*", ".xml", NULL, true); + } + factionCRCList.push_back(make_pair + (factionName, factionCRC)); + } + } + //console.addLine("Found factions: " + intToStr(factionCRCList.size())); + lastCheckedCRCTechtreeName = gameSettings->getTech(); + } + + gameSettings->setFactionCRCList(factionCRCList); + gameSettings->setTechCRC(lastCheckedCRCTechtreeValue); + } + } + + if (gameSettings->getMap() != "") { + if (lastCheckedCRCMapName != gameSettings->getMap()) { + Checksum checksum; + string + file = Config::getMapPath(gameSettings->getMap(), "", false); + //console.addLine("Checking map CRC [" + file + "]"); + checksum.addFile(file); + lastCheckedCRCMapValue = checksum.getSum(); + lastCheckedCRCMapName = gameSettings->getMap(); + } + gameSettings->setMapCRC(lastCheckedCRCMapValue); + } + } + + //replace server player by network + for (int i = 0; i < gameSettings->getFactionCount(); ++i) { + //replace by network + if (gameSettings->getFactionControl(i) == ctHuman) { + gameSettings->setFactionControl(i, ctNetwork); + } + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + void + MenuStateConnectedGame::returnToJoinMenu() { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (modHttpServerThread != NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + modHttpServerThread->setSimpleTaskInterfaceValid(false); + modHttpServerThread->signalQuit(); + //modHttpServerThread->setThreadOwnerValid(false); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + if (modHttpServerThread->canShutdown(true) == true + && modHttpServerThread->shutdownAndWait() == true) { + delete modHttpServerThread; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + modHttpServerThread = NULL; + } + + if (ftpClientThread != NULL) { + + ftpClientThread->setCallBackObject(NULL); + ftpClientThread->signalQuit(); + sleep(0); + if (ftpClientThread->canShutdown(true) == true && + ftpClientThread->shutdownAndWait() == true) { + delete ftpClientThread; + } else { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s %d] Error cannot shutdown ftpClientThread\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("%s", szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + } + ftpClientThread = NULL; + } + + if (returnMenuInfo == jmSimple) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + launchingNewGame = true; + disconnectFromServer(); + mainMenu->setState(new MenuStateJoinGame(program, mainMenu)); + } else { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + launchingNewGame = true; + disconnectFromServer(); + mainMenu->setState(new MenuStateMasterserver(program, mainMenu)); + } + } + + void + MenuStateConnectedGame::mouseMove(int x, int y, const MouseState * ms) { + if (mainMessageBox.getEnabled()) { + mainMessageBox.mouseMove(x, y); + } + + if (ftpMessageBox.getEnabled()) { + ftpMessageBox.mouseMove(x, y); + } + + buttonCancelDownloads.mouseMove(x, y); + buttonDisconnect.mouseMove(x, y); + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + listBoxControls[i].mouseMove(x, y); + listBoxFactions[i].mouseMove(x, y); + listBoxTeams[i].mouseMove(x, y); + grabSlotButton[i].mouseMove(x, y); + } + + listBoxMap.mouseMove(x, y); + listBoxFogOfWar.mouseMove(x, y); + checkBoxAllowObservers.mouseMove(x, y); + listBoxTileset.mouseMove(x, y); + listBoxMapFilter.mouseMove(x, y); + listBoxTechTree.mouseMove(x, y); + listBoxPlayerStatus.mouseMove(x, y); + + checkBoxScenario.mouseMove(x, y); + listBoxScenario.mouseMove(x, y); + + labelAllowTeamUnitSharing.mouseMove(x, y); + checkBoxAllowTeamUnitSharing.mouseMove(x, y); + labelAllowTeamResourceSharing.mouseMove(x, y); + checkBoxAllowTeamResourceSharing.mouseMove(x, y); + + checkBoxAllowNativeLanguageTechtree.mouseMove(x, y); + + buttonPlayNow.mouseMove(x, y); + buttonRestoreLastSettings.mouseMove(x, y); + } + + bool MenuStateConnectedGame::isVideoPlaying() { + bool result = false; + if (factionVideo != NULL) { + result = factionVideo->isPlaying(); + } + return result; + } + + void + MenuStateConnectedGame::render() { + try { + Renderer & renderer = Renderer::getInstance(); + + if (mainMessageBox.getEnabled()) { + renderer.renderMessageBox(&mainMessageBox); + } + + renderer.renderButton(&buttonDisconnect); + + if (initialSettingsReceivedFromServer == false) { + return; + } + + if (factionTexture != NULL) { + if (factionVideo == NULL || factionVideo->isPlaying() == false) { + renderer.renderTextureQuad(800, 600, 200, 150, factionTexture, + 1); + } + } + if (factionVideo != NULL) { + if (factionVideo->isPlaying() == true) { + factionVideo->playFrame(false); + } else { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false + && ::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == + true) { + if (factionVideo != NULL) { + factionVideo->closePlayer(); + delete factionVideo; + factionVideo = NULL; + + if (validDisplayedGamesettings) { + initFactionPreview(&displayedGamesettings); + } + } + } + } + } + + if (mapPreviewTexture != NULL) { + //renderer.renderTextureQuad(5,185,150,150,mapPreviewTexture,1.0f); + renderer.renderTextureQuad(this->render_mapPreviewTexture_X, + this->render_mapPreviewTexture_Y, + this->render_mapPreviewTexture_W, + this->render_mapPreviewTexture_H, + mapPreviewTexture, 1.0f); + if (this->zoomedMap == true) { + return; + } + //printf("=================> Rendering map preview texture\n"); + } + + if (scenarioLogoTexture != NULL) { + renderer.renderTextureQuad(300, 350, 400, 300, scenarioLogoTexture, + 1.0f); + //renderer.renderBackground(scenarioLogoTexture); + } + + renderer.renderButton(&buttonDisconnect); + + // Get a reference to the player texture cache + std::map < int, + Texture2D * >& + crcPlayerTextureCache = + CacheManager::getCachedItem < std::map < int, + Texture2D * > >(GameConstants::playerTextureCacheLookupKey); + + // START - this code ensure player title and player names don't overlap + int + offsetPosition = 0; + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + const + Metrics & + metrics = Metrics::getInstance(); + FontMetrics * + fontMetrics = NULL; + if (Renderer::renderText3DEnabled == false) { + fontMetrics = + CoreData::getInstance().getMenuFontNormal()->getMetrics(); + } else { + fontMetrics = + CoreData::getInstance().getMenuFontNormal3D()->getMetrics(); + } + + if (fontMetrics == NULL) { + throw megaglest_runtime_error("fontMetrics == NULL"); + } + int + curWidth = + (metrics.toVirtualX + (fontMetrics->getTextWidth(labelPlayers[i].getText()))); + + if (labelPlayers[i].getX() + curWidth >= + labelPlayerNames[i].getX()) { + int + newOffsetPosition = labelPlayers[i].getX() + curWidth + 2; + if (offsetPosition < newOffsetPosition) { + offsetPosition = newOffsetPosition; + } + } + } + // END + + renderer.renderListBox(&listBoxPlayerStatus); + + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + if (listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned) { + bool renderIt = true; + //printf("Player #%d [%s] control = %d\n",i,labelPlayerNames[i].getText().c_str(),listBoxControls[i].getSelectedItemIndex()); + if (labelNetStatus[i].getText() == + GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) { + renderIt = false; + } + labelPlayers[i].setVisible(renderIt); + labelPlayerNames[i].setVisible(renderIt); + listBoxControls[i].setVisible(renderIt); + listBoxRMultiplier[i].setVisible(renderIt); + listBoxFactions[i].setVisible(renderIt); + listBoxTeams[i].setVisible(renderIt); + labelNetStatus[i].setVisible(renderIt); + } + + if (listBoxControls[i].getSelectedItemIndex() != ctClosed) { + renderer.renderLabel(&labelPlayerStatus[i]); + } + + if (crcPlayerTextureCache[i] != NULL) { + // Render the player # label the player's color + + Vec3f + playerColor = + crcPlayerTextureCache[i]->getPixmap()->getPixel3f(0, 0); + if (clientInterface != NULL + && clientInterface->getGameSettings() != NULL + && clientInterface-> + getGameSettings()->getMasterserver_admin() > 0 + && clientInterface-> + getGameSettings()->getMasterserver_admin_faction_index() == + i) { + + if (difftime((long int) time(NULL), timerLabelFlash) < 1) { + renderer.renderLabel(&labelPlayers[i], &playerColor); + } else { + Vec4f + flashColor = + Vec4f(playerColor.x, playerColor.y, playerColor.z, 0.45f); + renderer.renderLabel(&labelPlayers[i], &flashColor); + } + + } else { + renderer.renderLabel(&labelPlayers[i], &playerColor); + } + + // Blend the color with white so make it more readable + //Vec4f newColor(1.f, 1.f, 1.f, 0.57f); + //renderer.renderLabel(&labelPlayers[i],&newColor); + + //int quadWidth = labelPlayerNames[i].getX() - labelPlayers[i].getX() - 5; + //renderer.renderTextureQuad(labelPlayers[i].getX(), labelPlayers[i].getY(), quadWidth, labelPlayers[i].getH(), crcPlayerTextureCache[i],1.0f,&playerColor); + } else { + renderer.renderLabel(&labelPlayers[i]); + } + + if (offsetPosition > 0) { + labelPlayerNames[i].setX(offsetPosition); + } + + renderer.renderListBox(&listBoxControls[i]); + if (listBoxControls[i].getSelectedItemIndex() != ctClosed) { + renderer.renderListBox(&listBoxRMultiplier[i]); + renderer.renderListBox(&listBoxFactions[i]); + int + teamnumber = listBoxTeams[i].getSelectedItemIndex(); + Vec3f teamcolor = Vec3f(1.0f, 1.0f, 1.0f); + if (teamnumber >= 0 && teamnumber < 8) { + teamcolor = + crcPlayerTextureCache[teamnumber]-> + getPixmap()->getPixel3f(0, 0); + } + listBoxTeams[i].setTextColor(teamcolor); + renderer.renderListBox(&listBoxTeams[i]); + + bool canGrabSlot = false; + ClientInterface * + clientInterface = networkManager.getClientInterface(); + if (clientInterface != NULL + && clientInterface->getJoinGameInProgress() == true) { + canGrabSlot = + ((listBoxControls[i].getSelectedItemIndex() == ctNetwork + && labelNetStatus[i].getText() == + GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) + || (listBoxControls[i].getSelectedItemIndex() != ctHuman + && listBoxControls[i].getSelectedItemIndex() != ctClosed + && listBoxControls[i].getSelectedItemIndex() != + ctNetwork)); + } else { + canGrabSlot = + (listBoxControls[i].getSelectedItemIndex() == ctNetwork + && labelNetStatus[i].getText() == + GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME); + } + + if (canGrabSlot == true) { + if (i < mapInfo.players) { + renderer.renderButton(&grabSlotButton[i]); + } + } else if (listBoxControls[i].getSelectedItemIndex() == ctNetwork + || listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned + || listBoxControls[i].getSelectedItemIndex() == ctHuman) { + renderer.renderLabel(&labelNetStatus[i]); + } + + if (listBoxControls[i].getSelectedItemIndex() == ctNetwork || + listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned + || listBoxControls[i].getSelectedItemIndex() == ctHuman) { + if (labelNetStatus[i].getText() != + GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) { + renderer.renderLabel(&labelPlayerNames[i]); + } + } + } + } + renderer.renderLabel(&labelStatus); + renderer.renderLabel(&labelInfo); + + if (difftime((long int) time(NULL), timerLabelFlash) < 1) { + renderer.renderLabel(&labelDataSynchInfo, &RED); + renderer.renderLabel(&labelWaitingForPlayers, &YELLOW); + } else { + renderer.renderLabel(&labelDataSynchInfo, &WHITE); + renderer.renderLabel(&labelWaitingForPlayers, &WHITE); + } + + renderer.renderLabel(&labelMap); + renderer.renderLabel(&labelMapFilter); + renderer.renderLabel(&labelFogOfWar); + renderer.renderLabel(&labelAllowObservers); + renderer.renderLabel(&labelFallbackCpuMultiplier); + renderer.renderLabel(&labelTileset); + renderer.renderLabel(&labelTechTree); + renderer.renderLabel(&labelControl); + renderer.renderLabel(&labelFaction); + renderer.renderLabel(&labelTeam); + renderer.renderLabel(&labelMapInfo); + + renderer.renderListBox(&listBoxMap); + renderer.renderListBox(&listBoxMapFilter); + renderer.renderListBox(&listBoxFogOfWar); + renderer.renderCheckBox(&checkBoxAllowObservers); + renderer.renderListBox(&listBoxTileset); + renderer.renderListBox(&listBoxTechTree); + + renderer.renderLabel(&labelEnableSwitchTeamMode); + renderer.renderLabel(&labelAISwitchTeamAcceptPercent); + + renderer.renderCheckBox(&checkBoxEnableSwitchTeamMode); + renderer.renderListBox(&listBoxAISwitchTeamAcceptPercent); + renderer.renderListBox(&listBoxFallbackCpuMultiplier); + + renderer.renderLabel(&labelAllowTeamUnitSharing); + renderer.renderCheckBox(&checkBoxAllowTeamUnitSharing); + + renderer.renderLabel(&labelAllowTeamResourceSharing); + renderer.renderCheckBox(&checkBoxAllowTeamResourceSharing); + + renderer.renderButton(&buttonPlayNow); + renderer.renderButton(&buttonRestoreLastSettings); + + renderer.renderCheckBox(&checkBoxScenario); + renderer.renderLabel(&labelScenario); + if (checkBoxScenario.getValue() == true) { + renderer.renderListBox(&listBoxScenario); + } + + renderer.renderLabel(&labelAllowNativeLanguageTechtree); + renderer.renderCheckBox(&checkBoxAllowNativeLanguageTechtree); + + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread->getProgressMutex() : + NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + + // !!! START TEMP MV + //renderer.renderButton(&buttonCancelDownloads); + //fileFTPProgressList.clear(); + //fileFTPProgressList["test1a dsa asd asda sdasd asd ad ad"] = make_pair(1,"testa"); + //fileFTPProgressList["test2 asdasdasdadas dasdasdasda"] = make_pair(1,"testb"); + //fileFTPProgressList["test3 asdasdad asd ada dasdadasdada"] = make_pair(1,"testc"); + // !!! END TEMP MV + + if (fileFTPProgressList.empty() == false) { + Lang & lang = Lang::getInstance(); + renderer.renderButton(&buttonCancelDownloads); + int + xLocation = buttonCancelDownloads.getX(); + int + yLocation = buttonCancelDownloads.getY() - 20; + for (std::map < string, pair < int, string > >::iterator iterMap = + fileFTPProgressList.begin(); + iterMap != fileFTPProgressList.end(); ++iterMap) { + string + progressLabelPrefix = + lang.getString("ModDownloading") + " " + iterMap->first + " "; + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nRendering file progress with the following prefix [%s]\n",progressLabelPrefix.c_str()); + + if (Renderer::renderText3DEnabled) { + renderer.renderProgressBar3D(iterMap->second.first, xLocation, + //10, + yLocation, + CoreData::getInstance + ().getDisplayFontSmall3D(), + //350,progressLabelPrefix); + 300, progressLabelPrefix); + } else { + renderer.renderProgressBar(iterMap->second.first, + //10, + xLocation, + yLocation, + CoreData:: + getInstance().getDisplayFontSmall + (), + //350,progressLabelPrefix); + 300, progressLabelPrefix); + } + + yLocation -= 20; + } + } + safeMutexFTPProgress.ReleaseLock(); + + if (mainMessageBox.getEnabled()) { + renderer.renderMessageBox(&mainMessageBox); + } + if (ftpMessageBox.getEnabled()) { + renderer.renderMessageBox(&ftpMessageBox); + } + + if (program != NULL) + program->renderProgramMsgBox(); + + if (enableMapPreview && (mapPreview.hasFileLoaded() == true)) { + + int + mouseX = mainMenu->getMouseX(); + int + mouseY = mainMenu->getMouseY(); + int + mouse2dAnim = mainMenu->getMouse2dAnim(); + + if (mapPreviewTexture == NULL) { + renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim); + + bool renderAll = (listBoxFogOfWar.getSelectedItemIndex() == 2); + //renderer.renderMapPreview(&mapPreview, renderAll, 10, 350, &mapPreviewTexture); + renderer.renderMapPreview(&mapPreview, renderAll, + this->render_mapPreviewTexture_X, + this->render_mapPreviewTexture_Y, + &mapPreviewTexture); + } + } + renderer.renderChatManager(&chatManager); + renderer.renderConsole(&console, + showFullConsole ? consoleFull : + consoleStoredAndNormal); + + if (difftime((long int) time(NULL), timerLabelFlash) > 2) { + timerLabelFlash = time(NULL); + } + } catch (const std::exception & ex) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + } + + void + MenuStateConnectedGame::update() { + Chrono chrono; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled) + chrono.start(); + + Lang & lang = Lang::getInstance(); + ClientInterface * + clientInterface = + NetworkManager::getInstance().getClientInterface(); + + string newLabelConnectionInfo = lang.getString("WaitingHost"); + if (clientInterface != NULL + && clientInterface->getJoinGameInProgress() == true) { + newLabelConnectionInfo = lang.getString("MGGameStatus2"); + } + // Test progress bar + //MutexSafeWrapper safeMutexFTPProgress((ftpClientThread != NULL ? ftpClientThread->getProgressMutex() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + //fileFTPProgressList["test"] = pair(difftime(time(NULL),lastNetworkSendPing) * 20,"test file 123"); + //safeMutexFTPProgress.ReleaseLock(); + // + + if (clientInterface != NULL && clientInterface->isConnected()) { + //printf("#2 admin key [%d] client key [%d]\n",settings->getMasterserver_admin(),clientInterface->getSessionKey()); + broadCastGameSettingsToHeadlessServer(false); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + bool + notCurrentlySwitching = + ((difftime + ((long int) time(NULL), + broadcastServerSettingsDelayTimer)) >= + HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS); + bool + receiveAllowedNow = + difftime((long int) time(NULL), noReceiveTimer) > 2; + bool + newMessage = + lastGameSettingsReceivedCount < + clientInterface->getGameSettingsReceivedCount(); + if (validDisplayedGamesettings == false + || (notCurrentlySwitching && newMessage && receiveAllowedNow)) { + + //printf("I take the whole settings top broadcastDelay=%d noReceiveTimer=%d\n", (int)difftime((long int) time(NULL), broadcastServerSettingsDelayTimer),(int)difftime((long int) time(NULL), noReceiveTimer)); + + displayedGamesettings = *(clientInterface->getGameSettings()); + originalGamesettings = displayedGamesettings; + validDisplayedGamesettings = true; + } + + checkBoxAllowNativeLanguageTechtree.setEditable(isHeadlessAdmin()); + checkBoxAllowNativeLanguageTechtree.setEnabled(isHeadlessAdmin()); + + listBoxMap.setEditable(isHeadlessAdmin()); + listBoxMapFilter.setEditable(isHeadlessAdmin()); + buttonPlayNow.setVisible(isHeadlessAdmin() || + clientInterface->getJoinGameInProgress() == + true); + buttonRestoreLastSettings.setVisible(isHeadlessAdmin()); + listBoxTechTree.setEditable(isHeadlessAdmin()); + listBoxTileset.setEditable(isHeadlessAdmin()); + checkBoxEnableSwitchTeamMode.setEditable(isHeadlessAdmin()); + listBoxAISwitchTeamAcceptPercent.setEditable(isHeadlessAdmin()); + listBoxFallbackCpuMultiplier.setEditable(isHeadlessAdmin()); + listBoxFogOfWar.setEditable(isHeadlessAdmin()); + checkBoxAllowObservers.setEditable(isHeadlessAdmin()); + + checkBoxAllowTeamUnitSharing.setEditable(isHeadlessAdmin()); + checkBoxAllowTeamResourceSharing.setEditable(isHeadlessAdmin()); + + if (isHeadlessAdmin() == true) { + bool hasOtherPlayer = false; + bool hasOpenSlot = false; + for (int i = 0; + i < GameConstants::maxPlayers; ++i) { + if (displayedGamesettings.getFactionControl(i) == ctNetwork + && clientInterface->getPlayerIndex() != (int) i) { + hasOpenSlot = true; + } + if (displayedGamesettings.getFactionControl(i) == ctNetwork && + displayedGamesettings.getNetworkPlayerNameByPlayerIndex(i) != + GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME + && displayedGamesettings.getNetworkPlayerNameByPlayerIndex(i) + != GameConstants::NETWORK_SLOT_CLOSED_SLOTNAME) { + listBoxControls[i].setEditable(false); + if (clientInterface->getPlayerIndex() != (int) i) { + hasOtherPlayer = true; + } + } else if (clientInterface->getPlayerIndex() == (int) i || + i >= mapInfo.hardMaxPlayers) { + // Most of the code that handles how to show the set up + // when observers are allowed is in the update() function + // in menu_state_custom_game.cpp. Explicitly stating to change + // players to observers, changing teams to the special "observer" + // team is done in that function. So basically, the update() function + // in this file receives the info from update() in + // menu_state_custom_game.cpp + // + // Mostly what needs to be done here is disable observer slots + // so the info can't be changed by the headless admin. We don't want + // him or her to accidently enable a non-observer into an observer slot + // that's > mapInfo.hardMaxPlayers, or to change the team. + // + listBoxControls[i].setEditable(false); + } else { + if (i < mapInfo.hardMaxPlayers) { + listBoxControls[i].setEditable(true); + } + } + if (i < mapInfo.hardMaxPlayers) { + listBoxRMultiplier[i].setEditable(isHeadlessAdmin()); + listBoxFactions[i].setEditable(isHeadlessAdmin()); + listBoxTeams[i].setEditable(isHeadlessAdmin()); + } + } + if (hasOtherPlayer) { + labelWaitingForPlayers.setText(""); + labelWaitingForPlayers.setVisible(false); + } else if (hasOpenSlot) { + labelWaitingForPlayers. + setText(lang.getString("WaitingForPlayers")); + labelWaitingForPlayers.setVisible(true); + } else { + labelWaitingForPlayers. + setText(lang.getString("OpenANetworkSLot")); + labelWaitingForPlayers.setVisible(true); + } + } else { + labelWaitingForPlayers.setText(""); + labelWaitingForPlayers.setVisible(false); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (difftime((long int) time(NULL), lastNetworkSendPing) >= + GameConstants::networkPingInterval) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] about to sendPingMessage...\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + lastNetworkSendPing = time(NULL); + clientInterface->sendPingMessage(GameConstants:: + networkPingInterval, + (int64) time(NULL)); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] pingCount = %d, clientInterface->getLastPingLag() = %f, GameConstants::networkPingInterval = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, pingCount, + clientInterface->getLastPingLag(), + GameConstants::networkPingInterval); + + // Starting checking timeout after sending at least 3 pings to server + if (clientInterface->isConnected() && + pingCount >= MAX_PING_LAG_COUNT + && clientInterface->getLastPingLag() >= + (GameConstants::networkPingInterval * MAX_PING_LAG_COUNT)) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + clientInterface->updateLobby(); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (clientInterface->isConnected() + && clientInterface->getJoinGameInProgress() == false + && pingCount >= MAX_PING_LAG_COUNT + && clientInterface->getLastPingLag() >= + (GameConstants::networkPingInterval * MAX_PING_LAG_COUNT)) { + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? + ftpClientThread->getProgressMutex() : + NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + if (fileFTPProgressList.empty() == true) { + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + displayedGamesettings.getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + clientInterface->sendTextMessage(lang.getString + ("ConnectionTimedOut", + languageList[i]) + + " : " + + doubleToStr + (clientInterface->getLastPingLag + (), 2), -1, false, + languageList[i]); + sleep(1); + clientInterface->close(); + } + } + } + } + + pingCount++; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + buttonDisconnect.setText(lang.getString("Disconnect")); + + if (clientInterface->getAllowDownloadDataSynch() == false) { + string label = lang.getString("ConnectedToServer"); + + if (clientInterface->getServerName().empty() == false) { + label = label + " " + clientInterface->getServerName(); + } + + label = label + ", " + clientInterface->getVersionString(); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (clientInterface->getAllowGameDataSynchCheck() == false && + displayedGamesettings.getTileset() != "" && + displayedGamesettings.getTech() != "" && + displayedGamesettings.getMap() != "") { + Config & config = Config::getInstance(); + + MutexSafeWrapper + safeMutexFTPProgress(ftpClientThread != + NULL ? + ftpClientThread->getProgressMutex() : + NULL, + string(__FILE__) + "_" + + intToStr(__LINE__)); + + uint32 tilesetCRC = lastCheckedCRCTilesetValue; + if (lastCheckedCRCTilesetName != + displayedGamesettings.getTileset() + && displayedGamesettings.getTileset() != "") { + //console.addLine("Checking tileset CRC [" + displayedGamesettings.getTileset() + "]"); + tilesetCRC = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTilesets, ""), + string("/") + displayedGamesettings.getTileset() + + string("/*"), ".xml", NULL); + if (tilesetCRC == 0 + || tilesetCRC != displayedGamesettings.getTilesetCRC()) { + tilesetCRC = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTilesets, ""), + string("/") + displayedGamesettings.getTileset() + + string("/*"), ".xml", NULL, true); + } + + // Test data synch + //tilesetCRC++; + lastCheckedCRCTilesetValue = tilesetCRC; + lastCheckedCRCTilesetName = displayedGamesettings.getTileset(); + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + uint32 techCRC = lastCheckedCRCTechtreeValue; + if (lastCheckedCRCTechtreeName != displayedGamesettings.getTech() + && displayedGamesettings.getTech() != "") { + //console.addLine("Checking techtree CRC [" + displayedGamesettings.getTech() + "]"); + techCRC = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), + string("/") + displayedGamesettings.getTech() + + string("/*"), ".xml", NULL); + //clientInterface->sendTextMessage("#1 TechCRC = " + intToStr(techCRC) + " remoteCRC = " + intToStr(displayedGamesettings.getTechCRC()),-1, true, ""); + + if (techCRC == 0 + || techCRC != displayedGamesettings.getTechCRC()) { + techCRC = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), + string("/") + displayedGamesettings.getTech() + + string("/*"), ".xml", NULL, true); + //clientInterface->sendTextMessage("#2 TechCRC = " + intToStr(techCRC) + " remoteCRC = " + intToStr(displayedGamesettings.getTechCRC()),-1, true, ""); + } + + + if (techCRC != 0 + && techCRC != displayedGamesettings.getTechCRC() + && listBoxTechTree.getSelectedItemIndex() >= 0 + && listBoxTechTree.getSelectedItem() != + Lang::getInstance().getString("DataMissing", "", true)) { + + //time_t now = time(NULL); + time_t + lastUpdateDate = + getFolderTreeContentsCheckSumRecursivelyLastGenerated + (config.getPathListForType(ptTechs, ""), + string("/") + displayedGamesettings.getTech() + + string("/*"), ".xml"); + + const + time_t + REFRESH_CRC_DAY_SECONDS = 60 * 60 * 1; + if (lastUpdateDate <= 0 || + difftime((long int) time(NULL), + lastUpdateDate) >= REFRESH_CRC_DAY_SECONDS) { + techCRC = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), + string("/") + displayedGamesettings.getTech() + + string("/*"), ".xml", NULL, true); + //clientInterface->sendTextMessage("#3 TechCRC = " + intToStr(techCRC) + " remoteCRC = " + intToStr(displayedGamesettings.getTechCRC()),-1, true, ""); + } + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + // Test data synch + //techCRC++; + lastCheckedCRCTechtreeValue = techCRC; + lastCheckedCRCTechtreeName = displayedGamesettings.getTech(); + + loadFactions(&displayedGamesettings, false); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + factionCRCList.clear(); + for (unsigned int factionIdx = 0; + factionIdx < factionFiles.size(); ++factionIdx) { + string factionName = factionFiles[factionIdx]; + if (factionName != GameConstants::RANDOMFACTION_SLOTNAME && + factionName != GameConstants::OBSERVER_SLOTNAME && + factionName != + Lang::getInstance().getString("DataMissing", "", true)) { + + uint32 factionCRC = 0; + //time_t now = time(NULL); + time_t + lastUpdateDate = + getFolderTreeContentsCheckSumRecursivelyLastGenerated + (config.getPathListForType(ptTechs, ""), + "/" + displayedGamesettings.getTech() + "/factions/" + + factionName + "/*", ".xml"); + + const + time_t + REFRESH_CRC_DAY_SECONDS = 60 * 60 * 24; + if (lastUpdateDate <= 0 || + difftime((long int) time(NULL), + lastUpdateDate) >= REFRESH_CRC_DAY_SECONDS + || (techCRC != 0 + && techCRC != displayedGamesettings.getTechCRC())) { + factionCRC = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), + "/" + displayedGamesettings.getTech() + "/factions/" + + factionName + "/*", ".xml", NULL, true); + } else { + factionCRC = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), + "/" + displayedGamesettings.getTech() + "/factions/" + + factionName + "/*", ".xml", NULL); + } + if (factionCRC == 0) { + factionCRC = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), + "/" + displayedGamesettings.getTech() + "/factions/" + + factionName + "/*", ".xml", NULL, true); + } + + if (factionCRC != 0) { + vector < pair < string, uint32 > >serverFactionCRCList = + displayedGamesettings.getFactionCRCList(); + for (unsigned int factionIdx1 = 0; + factionIdx1 < serverFactionCRCList.size(); + ++factionIdx1) { + pair < string, uint32 > &serverFaction = + serverFactionCRCList[factionIdx1]; + if (serverFaction.first == factionName) { + if (serverFaction.second != factionCRC) { + factionCRC = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), + "/" + displayedGamesettings.getTech() + + "/factions/" + factionName + "/*", ".xml", NULL, + true); + } + break; + } + } + } + factionCRCList.push_back(make_pair + (factionName, factionCRC)); + } + } + //console.addLine("Found factions: " + intToStr(factionCRCList.size())); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + uint32 mapCRC = lastCheckedCRCMapValue; + if (lastCheckedCRCMapName != displayedGamesettings.getMap() && + displayedGamesettings.getMap() != "") { + Checksum checksum; + string + file = + Config::getMapPath(displayedGamesettings.getMap(), "", + false); + //console.addLine("Checking map CRC [" + file + "]"); + checksum.addFile(file); + mapCRC = checksum.getSum(); + // Test data synch + //mapCRC++; + + lastCheckedCRCMapValue = mapCRC; + lastCheckedCRCMapName = displayedGamesettings.getMap(); + } + safeMutexFTPProgress.ReleaseLock(); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + bool + dataSynchMismatch = + ((mapCRC != 0 && mapCRC != displayedGamesettings.getMapCRC()) + || (tilesetCRC != 0 + && tilesetCRC != displayedGamesettings.getTilesetCRC()) + || (techCRC != 0 + && techCRC != displayedGamesettings.getTechCRC())); + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nmapCRC [%d] displayedGamesettings.getMapCRC() [%d]\ntilesetCRC [%d] displayedGamesettings.getTilesetCRC() [%d]\ntechCRC [%d] displayedGamesettings.getTechCRC() [%d]\n",mapCRC,displayedGamesettings.getMapCRC(),tilesetCRC,displayedGamesettings.getTilesetCRC(),techCRC,displayedGamesettings.getTechCRC()); + + if (dataSynchMismatch == true && + (difftime + ((long int) time(NULL), + broadcastServerSettingsDelayTimer) >= + HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS)) { + //printf("Data not synched: lmap %u rmap: %u ltile: %d rtile: %u ltech: %u rtech: %u\n",mapCRC,displayedGamesettings.getMapCRC(),tilesetCRC,displayedGamesettings.getTilesetCRC(),techCRC,displayedGamesettings.getTechCRC()); + + string labelSynch = lang.getString("DataNotSynchedTitle"); + + if (mapCRC != 0 && mapCRC != displayedGamesettings.getMapCRC() + && listBoxMap.getSelectedItemIndex() >= 0 + && listBoxMap.getSelectedItem() != + Lang::getInstance().getString("DataMissing", "", true)) { + labelSynch = labelSynch + " " + lang.getString("Map"); + + if (updateDataSynchDetailText == true && + lastMapDataSynchError != + lang.getString("DataNotSynchedMap") + " " + + listBoxMap.getSelectedItem()) { + lastMapDataSynchError = + lang.getString("DataNotSynchedMap") + " " + + listBoxMap.getSelectedItem(); + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + string + msg = + lang.getString("DataNotSynchedMap", + languageList[i]) + " " + + listBoxMap.getSelectedItem(); + bool localEcho = lang.isLanguageLocal(languageList[i]); + clientInterface->sendTextMessage(msg, -1, localEcho, + languageList[i]); + } + } + } + + if (tilesetCRC != 0 + && tilesetCRC != displayedGamesettings.getTilesetCRC() + && listBoxTileset.getSelectedItemIndex() >= 0 + && listBoxTileset.getSelectedItem() != + Lang::getInstance().getString("DataMissing", "", true)) { + labelSynch = labelSynch + " " + lang.getString("Tileset"); + if (updateDataSynchDetailText == true && + lastTileDataSynchError != + lang.getString("DataNotSynchedTileset") + " " + + listBoxTileset.getSelectedItem()) { + lastTileDataSynchError = + lang.getString("DataNotSynchedTileset") + " " + + listBoxTileset.getSelectedItem(); + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + string + msg = + lang.getString("DataNotSynchedTileset", + languageList[i]) + " " + + listBoxTileset.getSelectedItem(); + bool localEcho = lang.isLanguageLocal(languageList[i]); + clientInterface->sendTextMessage(msg, -1, localEcho, + languageList[i]); + } + } + } + + if (techCRC != 0 + && techCRC != displayedGamesettings.getTechCRC() + && listBoxTechTree.getSelectedItemIndex() >= 0 + && listBoxTechTree.getSelectedItem() != + Lang::getInstance().getString("DataMissing", "", true)) { + labelSynch = labelSynch + " " + lang.getString("TechTree"); + if (updateDataSynchDetailText == true && + lastTechtreeDataSynchError != + lang.getString("DataNotSynchedTechtree") + " " + + listBoxTechTree.getSelectedItem()) { + lastTechtreeDataSynchError = + lang.getString("DataNotSynchedTechtree") + " " + + listBoxTechTree.getSelectedItem(); + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + string + msg = + lang.getString("DataNotSynchedTechtree", + languageList[i]) + " " + + listBoxTechTree.getSelectedItem(); + bool localEcho = lang.isLanguageLocal(languageList[i]); + clientInterface->sendTextMessage(msg, -1, localEcho, + languageList[i]); + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + const int + MAX_CHAT_TEXT_LINE_LENGTH = 110; + //const vector languageList = clientInterface->getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + bool localEcho = lang.isLanguageLocal(languageList[i]); + + string mismatchedFactionText = ""; + vector < string > mismatchedFactionTextList; + vector < pair < string, uint32 > >serverFactionCRCList = + displayedGamesettings.getFactionCRCList(); + + for (unsigned int factionIdx = 0; + factionIdx < serverFactionCRCList.size(); + ++factionIdx) { + pair < string, uint32 > &serverFaction = + serverFactionCRCList[factionIdx]; + + bool foundFaction = false; + for (unsigned int clientFactionIdx = 0; + clientFactionIdx < factionCRCList.size(); + ++clientFactionIdx) { + pair < string, uint32 > &clientFaction = + factionCRCList[clientFactionIdx]; + + if (serverFaction.first == clientFaction.first) { + foundFaction = true; + if (serverFaction.second != clientFaction.second) { + if (mismatchedFactionText.length() >= 10) { + mismatchedFactionTextList.push_back + (mismatchedFactionText); + mismatchedFactionText = ""; + } + if (mismatchedFactionText == "") { + mismatchedFactionText = + "The following factions are mismatched: "; + if (lang.hasString("MismatchedFactions", + languageList[i]) == true) { + mismatchedFactionText = + lang.getString("MismatchedFactions", + languageList[i]); + } + + mismatchedFactionText += + " [" + intToStr(factionCRCList.size()) + + "][" + + intToStr(serverFactionCRCList.size()) + + "] - "; + } else { + mismatchedFactionText += ", "; + } + mismatchedFactionText += serverFaction.first; + } + break; + } + } + + if (foundFaction == false) { + if ((int) mismatchedFactionText.length() > + MAX_CHAT_TEXT_LINE_LENGTH) { + mismatchedFactionTextList.push_back + (mismatchedFactionText); + mismatchedFactionText = ""; + } + + if (mismatchedFactionText == "") { + mismatchedFactionText = + "The following factions are mismatched: "; + if (lang.hasString("MismatchedFactions", + languageList[i]) == true) { + mismatchedFactionText = + lang.getString("MismatchedFactions", + languageList[i]); + } + + mismatchedFactionText += + " [" + intToStr(factionCRCList.size()) + "][" + + intToStr(serverFactionCRCList.size()) + "] - "; + } else { + mismatchedFactionText += ", "; + } + + if (lang.hasString("MismatchedFactionsMissing", + languageList[i]) == true) { + mismatchedFactionText += + serverFaction.first + " " + + lang.getString("MismatchedFactionsMissing", + languageList[i]); + } else { + mismatchedFactionText += + serverFaction.first + " (missing)"; + } + } + } + + for (unsigned int clientFactionIdx = 0; + clientFactionIdx < factionCRCList.size(); + ++clientFactionIdx) { + pair < string, uint32 > &clientFaction = + factionCRCList[clientFactionIdx]; + + bool foundFaction = false; + for (unsigned int factionIdx = 0; + factionIdx < serverFactionCRCList.size(); + ++factionIdx) { + pair < string, uint32 > &serverFaction = + serverFactionCRCList[factionIdx]; + + if (serverFaction.first == clientFaction.first) { + foundFaction = true; + break; + } + } + + if (foundFaction == false) { + if ((int) mismatchedFactionText.length() > + MAX_CHAT_TEXT_LINE_LENGTH) { + mismatchedFactionTextList.push_back + (mismatchedFactionText); + mismatchedFactionText = ""; + } + + if (mismatchedFactionText == "") { + mismatchedFactionText = + "The following factions are mismatched: "; + if (lang.hasString("MismatchedFactions", + languageList[i]) == true) { + mismatchedFactionText = + lang.getString("MismatchedFactions", + languageList[i]); + } + + mismatchedFactionText += + " [" + intToStr(factionCRCList.size()) + "][" + + intToStr(serverFactionCRCList.size()) + "] - "; + } else { + mismatchedFactionText += ", "; + } + + if (lang.hasString("MismatchedFactionsExtra", + languageList[i]) == true) { + mismatchedFactionText += + clientFaction.first + " " + + lang.getString("MismatchedFactionsExtra", + languageList[i]); + } else { + mismatchedFactionText += + clientFaction.first + " (extra)"; + } + } + } + + if (mismatchedFactionText != "") { + if (mismatchedFactionTextList.empty() == false) { + if (mismatchedFactionText != "") { + mismatchedFactionText += "."; + mismatchedFactionTextList.push_back + (mismatchedFactionText); + } + for (unsigned int splitIdx = 0; + splitIdx < mismatchedFactionTextList.size(); + ++splitIdx) { + clientInterface->sendTextMessage + (mismatchedFactionTextList[splitIdx], -1, + localEcho, languageList[i]); + } + } else { + mismatchedFactionText += "."; + clientInterface->sendTextMessage + (mismatchedFactionText, -1, localEcho, + languageList[i]); + } + } + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + } + } + + updateDataSynchDetailText = false; + labelDataSynchInfo.setText(labelSynch); + } else { + labelDataSynchInfo.setText(""); + } + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (clientInterface->getAllowGameDataSynchCheck() == true && + clientInterface->getNetworkGameDataSynchCheckOk() == false) { + label = label + " -synch mismatch for:"; + + if (clientInterface->getNetworkGameDataSynchCheckOkMap() == + false) { + label = label + " map"; + + if (updateDataSynchDetailText == true && + clientInterface->getReceivedDataSynchCheck() && + lastMapDataSynchError != + "map CRC mismatch, " + listBoxMap.getSelectedItem()) { + lastMapDataSynchError = + "map CRC mismatch, " + listBoxMap.getSelectedItem(); + clientInterface->sendTextMessage(lastMapDataSynchError, -1, + true, ""); + } + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (clientInterface->getNetworkGameDataSynchCheckOkTile() == + false) { + label = label + " tile"; + if (updateDataSynchDetailText == true && + clientInterface->getReceivedDataSynchCheck() && + lastTileDataSynchError != + "tile CRC mismatch, " + listBoxTileset.getSelectedItem()) { + lastTileDataSynchError = + "tile CRC mismatch, " + listBoxTileset.getSelectedItem(); + clientInterface->sendTextMessage(lastTileDataSynchError, -1, + true, ""); + } + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (clientInterface->getNetworkGameDataSynchCheckOkTech() == + false) { + label = label + " techtree"; + + if (updateDataSynchDetailText == true && + clientInterface->getReceivedDataSynchCheck()) { + + string + report = + clientInterface->getNetworkGameDataSynchCheckTechMismatchReport + (); + if (lastTechtreeDataSynchError != + "techtree CRC mismatch" + report) { + lastTechtreeDataSynchError = + "techtree CRC mismatch" + report; + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] report: %s\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + report.c_str()); + + clientInterface->sendTextMessage("techtree CRC mismatch", + -1, true, ""); + vector < string > reportLineTokens; + Tokenize(report, reportLineTokens, "\n"); + for (int reportLine = 0; + reportLine < (int) reportLineTokens.size(); + ++reportLine) { + clientInterface->sendTextMessage(reportLineTokens + [reportLine], -1, true, + ""); + } + } + } + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (clientInterface->getReceivedDataSynchCheck() == true) { + updateDataSynchDetailText = false; + } + } else if (clientInterface->getAllowGameDataSynchCheck() == true) { + label += " - data synch is ok"; + } + + labelStatus.setText(label); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + } else { + string label = lang.getString("ConnectedToServer"); + + if (!clientInterface->getServerName().empty()) { + label = label + " " + clientInterface->getServerName(); + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (clientInterface->getAllowGameDataSynchCheck() == true && + clientInterface->getNetworkGameDataSynchCheckOk() == false) { + label = label + " -waiting to synch:"; + if (clientInterface->getNetworkGameDataSynchCheckOkMap() == + false) { + label = label + " map"; + } + if (clientInterface->getNetworkGameDataSynchCheckOkTile() == + false) { + label = label + " tile"; + } + if (clientInterface->getNetworkGameDataSynchCheckOkTech() == + false) { + label = label + " techtree"; + } + } else if (clientInterface->getAllowGameDataSynchCheck() == true) { + label += " - data synch is ok"; + } + + labelStatus.setText(label); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + } else { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (clientInterface != NULL + && clientInterface->isConnected() == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + clientInterface->close(); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + returnToJoinMenu(); + return; + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //process network messages + if (clientInterface != NULL && clientInterface->isConnected()) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + try { + if (clientInterface->getGameSettingsReceived() + && validDisplayedGamesettings + && lastGameSettingsReceivedCount != + clientInterface->getGameSettingsReceivedCount()) { + lastGameSettingsReceivedCount = + clientInterface->getGameSettingsReceivedCount(); + bool + errorOnMissingData = + (clientInterface->getAllowGameDataSynchCheck() == false); + + const GameSettings * + receivedGameSettings = clientInterface->getGameSettings(); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //printf("Menu got new settings thisfactionindex = %d startlocation: %d control = %d\n",displayedGamesettings.getThisFactionIndex(),clientInterface->getGameSettings()->getStartLocationIndex(clientInterface->getGameSettings()->getThisFactionIndex()),displayedGamesettings.getFactionControl(clientInterface->getGameSettings()->getThisFactionIndex())); + if (difftime((long int) time(NULL), noReceiveTimer) < 3 + || difftime((long int) time(NULL), + broadcastServerSettingsDelayTimer) < + HEADLESSSERVER_BROADCAST_SETTINGS_SECONDS) { + // copy my current settings in UI to displayedSettings; + loadGameSettings(&displayedGamesettings); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + // check if there are any changed fields from others clients + if (isHeadlessAdmin()) { + //printf("I am headless admin and will restore only some parts\n"); + // only copy those parts which are editable by normal clients + for (int i = 0; i < receivedGameSettings->getFactionCount(); + i++) { + if (displayedGamesettings.getFactionControl(i) == + ctNetwork) { + if (originalGamesettings.getTeam(i) == + displayedGamesettings.getTeam(i)) { + displayedGamesettings.setTeam(i, + receivedGameSettings->getTeam + (i)); + originalGamesettings.setTeam(i, + receivedGameSettings->getTeam + (i)); + } + if (originalGamesettings.getFactionTypeName(i) == + displayedGamesettings.getFactionTypeName(i)) { + displayedGamesettings.setFactionTypeName(i, + receivedGameSettings->getFactionTypeName + (i)); + originalGamesettings.setFactionTypeName(i, + receivedGameSettings->getFactionTypeName + (i)); + } + displayedGamesettings.setNetworkPlayerGameStatus(i, + receivedGameSettings->getNetworkPlayerGameStatus + (i)); + originalGamesettings.setNetworkPlayerGameStatus(i, + receivedGameSettings->getNetworkPlayerGameStatus + (i)); + displayedGamesettings.setNetworkPlayerName(i, + receivedGameSettings->getNetworkPlayerName + (i)); + originalGamesettings.setNetworkPlayerName(i, + receivedGameSettings->getNetworkPlayerName + (i)); + } + } + } else { + //printf("I am client and restore everything but not my line\n"); + // copy all received fields just not those which are editable for normal client + //store my changes + int + i = clientInterface->getPlayerIndex(); + int + team = displayedGamesettings.getTeam(i); + string faction = displayedGamesettings.getFactionTypeName(i); + int + status = + displayedGamesettings.getNetworkPlayerGameStatus(i); + string + networkPlayerName = + displayedGamesettings.getNetworkPlayerName(i); + displayedGamesettings = *receivedGameSettings; + originalGamesettings = *receivedGameSettings; + + displayedGamesettings.setTeam(i, team); + originalGamesettings.setTeam(i, team); + displayedGamesettings.setFactionTypeName(i, faction); + originalGamesettings.setFactionTypeName(i, faction); + displayedGamesettings.setNetworkPlayerGameStatus(i, status); + originalGamesettings.setNetworkPlayerGameStatus(i, status); + displayedGamesettings.setNetworkPlayerName(i, + networkPlayerName); + originalGamesettings.setNetworkPlayerName(i, + networkPlayerName); + + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + setupUIFromGameSettings(&displayedGamesettings, + errorOnMissingData); + } else { + // do nothing + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + setupUIFromGameSettings(&displayedGamesettings, + errorOnMissingData); + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + broadCastGameSettingsToHeadlessServer + (needToBroadcastServerSettings); + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + // check if we are joining an in progress game + if (clientInterface->getJoinGameInProgress() == true && + clientInterface->getJoinGameInProgressLaunch() == true && + clientInterface->getReadyForInGameJoin() == true && + ftpClientThread != NULL) { + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? + ftpClientThread->getProgressMutex() : + NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + if (readyToJoinInProgressGame == false) { + if (getInProgressSavedGameFromFTPServer == "") { + + getInProgressSavedGameFromFTPServerInProgress = true; + ftpClientThread->addTempFileToRequests + (GameConstants::saveNetworkGameFileClientCompressed, + GameConstants::saveNetworkGameFileServerCompressed); + + getInProgressSavedGameFromFTPServer = + GameConstants::saveNetworkGameFileServerCompressed; + fileFTPProgressList[getInProgressSavedGameFromFTPServer] = + pair < int, + string >(0, ""); + } + safeMutexFTPProgress.ReleaseLock(); + } else { + safeMutexFTPProgress.ReleaseLock(); + + string + saveGameFile = + "temp/" + string(GameConstants::saveNetworkGameFileClient); + if (getGameReadWritePath + (GameConstants::path_logs_CacheLookupKey) != "") { + saveGameFile = + getGameReadWritePath + (GameConstants::path_logs_CacheLookupKey) + saveGameFile; + } else { + string + userData = + Config::getInstance().getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + saveGameFile = userData + saveGameFile; + } + + //printf("Loading saved game file [%s]\n",saveGameFile.c_str()); + + GameSettings + gameSettings = *clientInterface->getGameSettings(); + loadGameSettings(&gameSettings); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + Game::loadGame(saveGameFile, program, false, &gameSettings); + return; + } + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //update lobby + clientInterface = + NetworkManager::getInstance().getClientInterface(); + if (clientInterface != NULL && clientInterface->isConnected()) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + clientInterface->updateLobby(); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + clientInterface = + NetworkManager::getInstance().getClientInterface(); + if (clientInterface != NULL && clientInterface->isConnected()) { + if (initialSettingsReceivedFromServer == true && + clientInterface->getIntroDone() == true && + (switchSetupRequestFlagType & ssrft_NetworkPlayerName) == + ssrft_NetworkPlayerName) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] getHumanPlayerName() = [%s], clientInterface->getGameSettings()->getThisFactionIndex() = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, + getHumanPlayerName().c_str(), + clientInterface->getGameSettings + ()->getThisFactionIndex()); + clientInterface->sendSwitchSetupRequest("", + clientInterface->getPlayerIndex + (), -1, -1, + getHumanPlayerName(), + getNetworkPlayerStatus + (), + switchSetupRequestFlagType, + lang.getLanguage()); + + switchSetupRequestFlagType = ssrft_None; + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //intro + if (clientInterface->getIntroDone()) { + if (newLabelConnectionInfo != labelInfo.getText()) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, + __LINE__); + labelInfo.setText(newLabelConnectionInfo); + } + } + + //launch + if (clientInterface->getLaunchGame()) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + assert(clientInterface != NULL); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (modHttpServerThread != NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + modHttpServerThread->setSimpleTaskInterfaceValid(false); + modHttpServerThread->signalQuit(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + if (modHttpServerThread->canShutdown(true) == true + && modHttpServerThread->shutdownAndWait() == true) { + delete modHttpServerThread; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + modHttpServerThread = NULL; + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (ftpClientThread != NULL) { + ftpClientThread->setCallBackObject(NULL); + ftpClientThread->signalQuit(); + sleep(0); + if (ftpClientThread->canShutdown(true) == true && + ftpClientThread->shutdownAndWait() == true) { + delete ftpClientThread; + } else { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s %d] Error cannot shutdown ftpClientThread\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("%s", szBuf); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", + szBuf); + } + ftpClientThread = NULL; + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + launchingNewGame = true; + + GameSettings + gameSettings = *clientInterface->getGameSettings(); + // complete game settings with local stuff + if (gameSettings.getScenario() != "") { + string scenario = gameSettings.getScenario(); + listBoxScenario.setSelectedItem(formatString(scenario)); + string file = Scenario::getScenarioPath(dirList, scenario); + + bool isTutorial = Scenario::isGameTutorial(file); + Scenario::loadScenarioInfo(file, &scenarioInfo, isTutorial); + + gameSettings.setScenarioDir(Scenario::getScenarioPath + (dirList, scenarioInfo.name)); + + gameSettings. + setDefaultResources(scenarioInfo.defaultResources); + gameSettings.setDefaultUnits(scenarioInfo.defaultUnits); + gameSettings.setDefaultVictoryConditions + (scenarioInfo.defaultVictoryConditions); + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + program->setState(new Game(program, &gameSettings, false)); + return; + } + } + + //call the chat manager + chatManager.updateNetwork(); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //console732 + console.update(); + + // check for need to switch music on again + if (clientInterface != NULL) { + int + currentConnectionCount = 0; + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + if (displayedGamesettings.getFactionControl(i) == ctNetwork && + displayedGamesettings.getNetworkPlayerName(i) != "" && + displayedGamesettings.getNetworkPlayerName(i) != + GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) { + currentConnectionCount++; + } + } + if (currentConnectionCount > soundConnectionCount) { + soundConnectionCount = currentConnectionCount; + static PlaySoundClip snd; + SoundRenderer::getInstance(). + playFx(snd.getSound(snd.sfxAttention)); + //switch on music again!! + Config & config = Config::getInstance(); + float + configVolume = (config.getInt("SoundVolumeMusic") / 100.f); + CoreData::getInstance(). + getMenuMusic()->setVolume(configVolume); + } + soundConnectionCount = currentConnectionCount; + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + } catch (const runtime_error & ex) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, ex.what()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] %s\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, szBuf); + showMessageBox(szBuf, "Error", false); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + } + } + + bool + MenuStateConnectedGame::loadFactions(const GameSettings * gameSettings, + bool errorOnNoFactions) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + Lang & lang = Lang::getInstance(); + bool foundFactions = false; + vector < string > results; + + string + scenarioDir = + Scenario::getScenarioDir(dirList, gameSettings->getScenario()); + if (gameSettings->getTech() != "") { + Config & config = Config::getInstance(); + + vector < string > techPaths = + config.getPathListForType(ptTechs, scenarioDir); + for (int idx = 0; idx < (int) techPaths.size(); idx++) { + string & techPath = techPaths[idx]; + endPathWithSlash(techPath); + //findAll(techPath + gameSettings->getTech() + "/factions/*.", results, false, false); + findDirs(techPath + gameSettings->getTech() + "/factions/", + results, false, false); + if (results.empty() == false) { + break; + } + } + + if (results.empty() == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + if (clientInterface->getAllowGameDataSynchCheck() == false) { + if (errorOnNoFactions == true) { + throw + megaglest_runtime_error + ("(2)There are no factions for the tech tree [" + + gameSettings->getTech() + "]"); + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] (2)There are no factions for the tech tree [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, + gameSettings->getTech().c_str()); + } + results. + push_back(Lang:: + getInstance().getString("DataMissing", "", true)); + factionFiles = results; + vector < string > translatedFactionNames; + for (int i = 0; i < (int) factionFiles.size(); ++i) { + results[i] = formatString(results[i]); + string + translatedString = + techTree->getTranslatedFactionName(gameSettings->getTech(), + factionFiles[i]); + if (toLower(translatedString) == toLower(results[i])) { + translatedFactionNames.push_back(results[i]); + } else { + translatedFactionNames.push_back(results[i] + " (" + + translatedString + ")"); + } + } + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + listBoxFactions[i].setItems(results, translatedFactionNames); + } + + if (lastMissingTechtree != gameSettings->getTech() && + gameSettings->getTech() != "") { + lastMissingTechtree = gameSettings->getTech(); + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingTechtree", languageList[i]) == + true) { + snprintf(szMsg, 8096, + lang.getString("DataMissingTechtree", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), + gameSettings->getTech().c_str()); + } else { + snprintf(szMsg, 8096, + "Player: %s is missing the techtree: %s", + getHumanPlayerName().c_str(), + gameSettings->getTech().c_str()); + } + clientInterface->sendTextMessage(szMsg, -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + } + } + + foundFactions = false; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } else { + lastMissingTechtree = ""; + getMissingTechtreeFromFTPServer = ""; + + factionFiles = results; + vector < string > translatedFactionNames; + for (int i = 0; i < (int) factionFiles.size(); ++i) { + results[i] = formatString(results[i]); + string + translatedString = + techTree->getTranslatedFactionName(gameSettings->getTech(), + factionFiles[i]); + if (toLower(translatedString) == toLower(results[i])) { + translatedFactionNames.push_back(results[i]); + } else { + translatedFactionNames.push_back(results[i] + " (" + + translatedString + ")"); + } + } + + results.push_back(formatString + (GameConstants::RANDOMFACTION_SLOTNAME)); + factionFiles.push_back(formatString + (GameConstants::RANDOMFACTION_SLOTNAME)); + translatedFactionNames.push_back("*" + + lang.getString("Random", "", + true) + "*"); + + // Add special Observer Faction + if (checkBoxAllowObservers.getValue() == 1) { + results.push_back(formatString + (GameConstants::OBSERVER_SLOTNAME)); + factionFiles.push_back(formatString + (GameConstants::OBSERVER_SLOTNAME)); + translatedFactionNames.push_back("*" + + lang.getString("Observer", "", + true) + "*"); + } + + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + listBoxFactions[i].setItems(results, translatedFactionNames); + } + + foundFactions = (results.empty() == false); + } + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + return foundFactions; + } + + // ============ PRIVATE =========================== + + bool MenuStateConnectedGame::hasNetworkGameSettings() { + bool hasNetworkSlot = false; + + try { + for (int i = 0; i < mapInfo.players; ++i) { + ControlType + ct = + static_cast + (listBoxControls[i].getSelectedItemIndex()); + if (ct != ctClosed) { + if (ct == ctNetwork || ct == ctNetworkUnassigned) { + hasNetworkSlot = true; + break; + } + } + } + if (hasNetworkSlot == false) { + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + ControlType + ct = + static_cast + (listBoxControls[i].getSelectedItemIndex()); + if (ct != ctClosed) { + if (ct == ctNetworkUnassigned) { + hasNetworkSlot = true; + break; + } + } + } + } + } catch (const std::exception & ex) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + ex.what()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] %s\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, szBuf); + showMessageBox(szBuf, "Error", false); + } + + return hasNetworkSlot; + } + + void + MenuStateConnectedGame::keyDown(SDL_KeyboardEvent key) { + if (activeInputLabel != NULL) { + bool handled = keyDownEditLabel(key, &activeInputLabel); + if (handled == true) { + switchSetupRequestFlagType |= ssrft_NetworkPlayerName; + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } else { + //send key to the chat manager + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + if (clientInterface != NULL && + clientInterface->isConnected() == true && + clientInterface->getIntroDone() == true) { + chatManager.keyDown(key); + } + if (chatManager.getEditEnabled() == false && + (::Shared::Platform::Window::isKeyStateModPressed(KMOD_SHIFT) == + false)) { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + + if (isKeyPressed(configKeys.getSDLKey("ShowFullConsole"), key) == + true) { + showFullConsole = true; + } else if (isKeyPressed(configKeys.getSDLKey("ToggleMusic"), key) == + true) { + Config & config = Config::getInstance(); + Lang & lang = Lang::getInstance(); + + float + configVolume = (config.getInt("SoundVolumeMusic") / 100.f); + float + currentVolume = + CoreData::getInstance().getMenuMusic()->getVolume(); + if (currentVolume > 0) { + CoreData::getInstance().getMenuMusic()->setVolume(0.f); + console.addLine(lang.getString("GameMusic") + " " + + lang.getString("Off")); + } else { + CoreData::getInstance(). + getMenuMusic()->setVolume(configVolume); + //If the config says zero, use the default music volume + //gameMusic->setVolume(configVolume ? configVolume : 0.9); + console.addLine(lang.getString("GameMusic")); + } + } + //else if(key == configKeys.getCharKey("SaveGUILayout")) { + else if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), key) + == true) { + bool + saved = + GraphicComponent::saveAllCustomProperties(containerName); + Lang & lang = Lang::getInstance(); + console.addLine(lang.getString("GUILayoutSaved") + " [" + + (saved ? lang. + getString("Yes") : lang.getString("No")) + + "]"); + } + } + } + } + + bool MenuStateConnectedGame::textInput(std::string text) { + if (activeInputLabel != NULL) { + bool handled = textInputEditLabel(text, &activeInputLabel); + if (handled == true) { + switchSetupRequestFlagType |= ssrft_NetworkPlayerName; + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + return handled; + } else { + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + if (clientInterface != NULL && clientInterface->isConnected() == true + && clientInterface->getIntroDone() == true) { + return chatManager.textInput(text); + } + } + return false; + } + + void + MenuStateConnectedGame::keyPress(SDL_KeyboardEvent c) { + if (activeInputLabel != NULL) { + keyPressEditLabel(c, &activeInputLabel); + } else { + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + if (clientInterface != NULL && clientInterface->isConnected() == true + && clientInterface->getIntroDone() == true) { + chatManager.keyPress(c); + } + } + } + + void + MenuStateConnectedGame::keyUp(SDL_KeyboardEvent key) { + if (activeInputLabel == NULL) { + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + if (clientInterface != NULL && + clientInterface->isConnected() == true && + clientInterface->getIntroDone() == true) { + chatManager.keyUp(key); + } + + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + + if (chatManager.getEditEnabled()) { + //send key to the chat manager + chatManager.keyUp(key); + } else if (isKeyPressed(configKeys.getSDLKey("ShowFullConsole"), key) + == true) { + showFullConsole = false; + } + } + } + + void + MenuStateConnectedGame::setActiveInputLabel(GraphicLabel * newLable) { + MenuState::setActiveInputLabel(newLable, &activeInputLabel); + } + + string MenuStateConnectedGame::getHumanPlayerName() { + string result = defaultPlayerName; + + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + for (int j = 0; j < GameConstants::maxPlayers; ++j) { + if (clientInterface != NULL && + j == clientInterface->getPlayerIndex() && + labelPlayerNames[j].getText() != "") { + result = labelPlayerNames[j].getText(); + + if (activeInputLabel != NULL) { + size_t found = result.find_last_of("_"); + if (found != string::npos) { + result = result.substr(0, found); + } + } + + break; + } + } + + return result; + } + + void + MenuStateConnectedGame::loadFactionTexture(string filepath) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (enableFactionTexturePreview == true) { + if (filepath == "") { + factionTexture = NULL; + } else { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] filepath = [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, filepath.c_str()); + factionTexture = Renderer::findTexture(filepath); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + } + } + + bool + MenuStateConnectedGame::loadMapInfo(string file, MapInfo * mapInfo, + bool loadMapPreview) { + bool mapLoaded = false; + try { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] map [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, file.c_str()); + + if (file != "") { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + lastMissingMap = file; + + Lang & lang = Lang::getInstance(); + if (MapPreview::loadMapInfo + (file, mapInfo, lang.getString("MaxPlayers"), + lang.getString("Size"), true) == true) { + mapInfo->players = GameConstants::maxPlayers; + + // Not painting properly so this is on hold + if (loadMapPreview == true) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + if (mapPreview.getMapFileLoaded() != file) { + mapPreview.loadFromFile(file.c_str()); + cleanupMapPreviewTexture(); + } + } + + mapLoaded = true; + } + } else { + cleanupMapPreviewTexture(); + mapInfo->desc = + Lang::getInstance().getString("DataMissing", "", true); + + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + const GameSettings * + gameSettings = clientInterface->getGameSettings(); + + if (lastMissingMap != gameSettings->getMap()) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + lastMissingMap = gameSettings->getMap(); + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingMap", languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString("DataMissingMap", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), + gameSettings->getMap().c_str()); + } else { + snprintf(szMsg, 8096, "Player: %s is missing the map: %s", + getHumanPlayerName().c_str(), + gameSettings->getMap().c_str()); + } + clientInterface->sendTextMessage(szMsg, -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + } + } + } + } catch (exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + e.what()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] error [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, e.what()); + + showMessageBox("Error loading map file: " + file + '\n' + e.what(), + "Error", false); + } + + return mapLoaded; + } + + void + MenuStateConnectedGame::showMessageBox(const string & text, + const string & header, + bool toggle) { + if (!toggle) { + mainMessageBox.setEnabled(false); + } + + if (!mainMessageBox.getEnabled()) { + mainMessageBox.setText(text); + mainMessageBox.setHeader(header); + mainMessageBox.setEnabled(true); + } else { + mainMessageBox.setEnabled(false); + } + } + + void + MenuStateConnectedGame::showFTPMessageBox(const string & text, + const string & header, + bool toggle) { + if (!toggle) { + ftpMessageBox.setEnabled(false); + } + + if (!ftpMessageBox.getEnabled()) { + ftpMessageBox.setText(text); + ftpMessageBox.setHeader(header); + ftpMessageBox.setEnabled(true); + } else { + ftpMessageBox.setEnabled(false); + } + } + + int32 MenuStateConnectedGame::getNetworkPlayerStatus() { + int32 result = npst_None; + switch (listBoxPlayerStatus.getSelectedItemIndex()) { + case 2: + result = npst_Ready; + break; + case 1: + result = npst_BeRightBack; + break; + case 0: + result = npst_PickSettings; + break; + } + + return result; + } + + void + MenuStateConnectedGame::cleanupMapPreviewTexture() { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (mapPreviewTexture != NULL) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + mapPreviewTexture->end(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + delete mapPreviewTexture; + mapPreviewTexture = NULL; + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + bool MenuStateConnectedGame::isInSpecialKeyCaptureEvent() { + bool + result = (chatManager.getEditEnabled() || activeInputLabel != NULL); + return result; + } + + void + MenuStateConnectedGame::FTPClient_CallbackEvent(string itemName, + FTP_Client_CallbackType + type, + pair < + FTP_Client_ResultType, + string > result, + void *userdata) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (type == ftp_cct_DownloadProgress) { + FTPClientCallbackInterface::FtpProgressStats * stats = + (FTPClientCallbackInterface::FtpProgressStats *) userdata; + if (stats != NULL) { + int + fileProgress = 0; + if (stats->download_total > 0) { + fileProgress = + ((stats->download_now / stats->download_total) * 100.0); + } + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP Callback for [%s] current file [%s] fileProgress = %d [now = %f, total = %f]\n",itemName.c_str(),stats->currentFilename.c_str(), fileProgress,stats->download_now,stats->download_total); + + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread->getProgressMutex() + : NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + pair < int, + string > + lastProgress; + std::map < string, pair < int, + string > >::iterator + iterFind = fileFTPProgressList.find(itemName); + if (iterFind == fileFTPProgressList.end()) { + iterFind = + fileFTPProgressList.find(GameConstants:: + saveNetworkGameFileServerCompressed); + if (iterFind == fileFTPProgressList.end()) { + iterFind = + fileFTPProgressList.find(GameConstants:: + saveNetworkGameFileClientCompressed); + } + } + if (iterFind != fileFTPProgressList.end()) { + lastProgress = iterFind->second; + fileFTPProgressList[iterFind->first] = pair < int, + string >(fileProgress, stats->currentFilename); + } + safeMutexFTPProgress.ReleaseLock(); + + if (itemName != "" + && (lastProgress.first / 25) < (fileProgress / 25)) { + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("FileDownloadProgress", languageList[i]) == + true) { + snprintf(szMsg, 8096, + lang.getString("FileDownloadProgress", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), itemName.c_str(), + fileProgress); + } else { + snprintf(szMsg, 8096, + "Player: %s download progress for [%s] is %d %%", + getHumanPlayerName().c_str(), itemName.c_str(), + fileProgress); + } + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] szMsg [%s] lastProgress.first = %d, fileProgress = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, szMsg, lastProgress.first, + fileProgress); + clientInterface->sendTextMessage(szMsg, -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + } + sleep(1); + } + } + } else if (type == ftp_cct_ExtractProgress) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Got FTP extract Callback for [%s] result = %d [%s]\n", + itemName.c_str(), result.first, result.second.c_str()); + + if (userdata == NULL) { + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingExtractDownload", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString("DataMissingExtractDownload", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), itemName.c_str()); + } else { + snprintf(szMsg, 8096, + "Please wait, player: %s is extracting: %s", + getHumanPlayerName().c_str(), itemName.c_str()); + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] szMsg [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, szMsg); + clientInterface->sendTextMessage(szMsg, -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + } + sleep(1); + } else { + char * + szBuf = (char *) userdata; + //printf("%s\n",szBuf); + //console.addLine(szBuf); + console.addLine(szBuf, false, ""); + } + } else if (type == ftp_cct_Map) { + getMissingMapFromFTPServerInProgress = false; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Got FTP Callback for [%s] result = %d [%s]\n", + itemName.c_str(), result.first, result.second.c_str()); + + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread->getProgressMutex() : + NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + fileFTPProgressList.erase(itemName); + safeMutexFTPProgress.ReleaseLock(); + + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + const GameSettings * + gameSettings = clientInterface->getGameSettings(); + + if (result.first == ftp_crt_SUCCESS) { + // Clear the CRC file Cache + string file = Config::getMapPath(itemName, "", false); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("Got map itemName [%s] file [%s] lastCheckedCRCMapName [%s] gameSettings->getMap() [%s]\n", + itemName.c_str(), file.c_str(), + lastCheckedCRCMapName.c_str(), + gameSettings->getMap().c_str()); + + if (gameSettings != NULL && itemName == gameSettings->getMap() && + lastCheckedCRCMapName == gameSettings->getMap() && + gameSettings->getMap() != "") { + Checksum::clearFileCache(); + Checksum checksum; + + checksum.addFile(file); + lastCheckedCRCMapValue = checksum.getSum(); + } + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingMapSuccessDownload", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString("DataMissingMapSuccessDownload", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), itemName.c_str()); + } else { + snprintf(szMsg, 8096, + "Player: %s SUCCESSFULLY downloaded the map: %s", + getHumanPlayerName().c_str(), itemName.c_str()); + } + clientInterface->sendTextMessage(szMsg, -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + } + sleep(1); + } else { + printf + ("FAILED map itemName [%s] lastCheckedCRCMapName [%s] gameSettings->getMap() [%s]\n", + itemName.c_str(), lastCheckedCRCMapName.c_str(), + gameSettings->getMap().c_str()); + + curl_version_info_data * + curlVersion = curl_version_info(CURLVERSION_NOW); + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingMapFailDownload", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString("DataMissingMapFailDownload", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), itemName.c_str(), + curlVersion->version); + } else { + snprintf(szMsg, 8096, + "Player: %s FAILED to download the map: [%s] using CURL version [%s]", + getHumanPlayerName().c_str(), itemName.c_str(), + curlVersion->version); + } + clientInterface->sendTextMessage(szMsg, -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + + if (result.first == ftp_crt_HOST_NOT_ACCEPTING) { + if (lang.hasString("HostNotAcceptingDataConnections", + languageList[i]) == true) { + clientInterface->sendTextMessage(lang.getString + ("HostNotAcceptingDataConnections", + languageList[i]), -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + } else { + clientInterface->sendTextMessage + ("*Warning* the host is not accepting data connections.", + -1, lang.isLanguageLocal(languageList[i]), + languageList[i]); + } + } + } + sleep(1); + + console.addLine(result.second, true); + } + } else if (type == ftp_cct_Tileset) { + getMissingTilesetFromFTPServerInProgress = false; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Got FTP Callback for [%s] result = %d [%s]\n", + itemName.c_str(), result.first, result.second.c_str()); + + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread->getProgressMutex() : + NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + fileFTPProgressList.erase(itemName); + safeMutexFTPProgress.ReleaseLock(true); + + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + const GameSettings * + gameSettings = clientInterface->getGameSettings(); + + if (result.first == ftp_crt_SUCCESS) { + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingTilesetSuccessDownload", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString("DataMissingTilesetSuccessDownload", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), itemName.c_str()); + } else { + snprintf(szMsg, 8096, + "Player: %s SUCCESSFULLY downloaded the tileset: %s", + getHumanPlayerName().c_str(), itemName.c_str()); + } + clientInterface->sendTextMessage(szMsg, -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + } + sleep(1); + + // START + // Clear the CRC Cache if it is populated + // + // Clear the CRC file Cache + safeMutexFTPProgress.Lock(); + Checksum::clearFileCache(); + + vector < string > paths = + Config::getInstance().getPathListForType(ptTilesets); + string pathSearchString = string("/") + itemName + string("/*"); + const + string + filterFileExt = ".xml"; + clearFolderTreeContentsCheckSum(paths, pathSearchString, + filterFileExt); + clearFolderTreeContentsCheckSumList(paths, pathSearchString, + filterFileExt); + + // Refresh CRC + + //printf("Got map itemName [%s] file [%s] lastCheckedCRCMapName [%s] gameSettings->getMap() [%s]\n", + // itemName.c_str(),file.c_str(),lastCheckedCRCMapName.c_str(),gameSettings->getMap().c_str()); + + if (gameSettings != NULL && itemName == gameSettings->getTileset() + && lastCheckedCRCTilesetName == gameSettings->getTileset() + && gameSettings->getTileset() != "") { + Config & config = Config::getInstance(); + lastCheckedCRCTilesetValue = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTilesets, ""), + string("/") + itemName + string("/*"), ".xml", NULL, true); + } + + safeMutexFTPProgress.ReleaseLock(); + // END + + // Reload tilesets for the UI + string + scenarioDir = + Scenario::getScenarioDir(dirList, gameSettings->getScenario()); + findDirs(Config::getInstance().getPathListForType(ptTilesets, + scenarioDir), + tilesetFiles); + + std::vector < string > tilesetsFormatted = tilesetFiles; + std::for_each(tilesetsFormatted.begin(), tilesetsFormatted.end(), + FormatString()); + listBoxTileset.setItems(tilesetsFormatted); + } else { + curl_version_info_data * + curlVersion = curl_version_info(CURLVERSION_NOW); + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingTilesetFailDownload", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString("DataMissingTilesetFailDownload", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), + (itemName + "(.7z)").c_str(), curlVersion->version); + } else { + snprintf(szMsg, 8096, + "Player: %s FAILED to download the tileset: [%s] using CURL version [%s]", + getHumanPlayerName().c_str(), + (itemName + "(.7z)").c_str(), curlVersion->version); + } + clientInterface->sendTextMessage(szMsg, -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + + if (result.first == ftp_crt_HOST_NOT_ACCEPTING) { + if (lang.hasString("HostNotAcceptingDataConnections", + languageList[i]) == true) { + clientInterface->sendTextMessage(lang.getString + ("HostNotAcceptingDataConnections", + languageList[i]), -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + } else { + clientInterface->sendTextMessage + ("*Warning* the host is not accepting data connections.", + -1, lang.isLanguageLocal(languageList[i]), + languageList[i]); + } + } + } + sleep(1); + + console.addLine(result.second, true); + } + } else if (type == ftp_cct_Techtree) { + getMissingTechtreeFromFTPServerInProgress = false; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Got FTP Callback for [%s] result = %d [%s]\n", + itemName.c_str(), result.first, result.second.c_str()); + + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread->getProgressMutex() : + NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + fileFTPProgressList.erase(itemName); + safeMutexFTPProgress.ReleaseLock(true); + + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + const GameSettings * + gameSettings = clientInterface->getGameSettings(); + + if (result.first == ftp_crt_SUCCESS) { + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingTechtreeSuccessDownload", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString("DataMissingTechtreeSuccessDownload", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), itemName.c_str()); + } else { + snprintf(szMsg, 8096, + "Player: %s SUCCESSFULLY downloaded the techtree: %s", + getHumanPlayerName().c_str(), itemName.c_str()); + } + clientInterface->sendTextMessage(szMsg, -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + } + sleep(1); + + // START + // Clear the CRC Cache if it is populated + // + // Clear the CRC file Cache + safeMutexFTPProgress.Lock(); + Checksum::clearFileCache(); + + vector < string > paths = + Config::getInstance().getPathListForType(ptTechs); + string pathSearchString = string("/") + itemName + string("/*"); + const + string + filterFileExt = ".xml"; + clearFolderTreeContentsCheckSum(paths, pathSearchString, + filterFileExt); + clearFolderTreeContentsCheckSumList(paths, pathSearchString, + filterFileExt); + + // Refresh CRC + if (gameSettings != NULL && itemName == gameSettings->getTech() && + lastCheckedCRCTechtreeName == gameSettings->getTech() && + gameSettings->getTech() != "") { + Config & config = Config::getInstance(); + lastCheckedCRCTechtreeValue = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), + string("/") + itemName + string("/*"), ".xml", NULL, true); + } + safeMutexFTPProgress.ReleaseLock(); + // END + + // Reload techs for the UI + string + scenarioDir = + Scenario::getScenarioDir(dirList, gameSettings->getScenario()); + findDirs(Config:: + getInstance().getPathListForType(ptTechs, scenarioDir), + techTreeFiles); + + vector < string > translatedTechs; + std::vector < string > techsFormatted = techTreeFiles; + for (int i = 0; i < (int) techsFormatted.size(); i++) { + techsFormatted.at(i) = formatString(techsFormatted.at(i)); + + string + txTech = + techTree->getTranslatedName(techTreeFiles.at(i), true); + translatedTechs.push_back(formatString(txTech)); + } + listBoxTechTree.setItems(techsFormatted, translatedTechs); + } else { + curl_version_info_data * + curlVersion = curl_version_info(CURLVERSION_NOW); + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < (unsigned int) languageList.size(); + ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingTechtreeFailDownload", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString("DataMissingTechtreeFailDownload", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), + (itemName + "(.7z)").c_str(), curlVersion->version); + } else { + snprintf(szMsg, 8096, + "Player: %s FAILED to download the techtree: [%s] using CURL version [%s]", + getHumanPlayerName().c_str(), + (itemName + "(.7z)").c_str(), curlVersion->version); + } + clientInterface->sendTextMessage(szMsg, -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + + if (result.first == ftp_crt_HOST_NOT_ACCEPTING) { + if (lang.hasString("HostNotAcceptingDataConnections", + languageList[i]) == true) { + clientInterface->sendTextMessage(lang.getString + ("HostNotAcceptingDataConnections", + languageList[i]), -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + } else { + clientInterface->sendTextMessage + ("*Warning* the host is not accepting data connections.", + -1, lang.isLanguageLocal(languageList[i]), + languageList[i]); + } + } + } + sleep(1); + + console.addLine(result.second, true); + } + } else if (type == ftp_cct_TempFile) { + getInProgressSavedGameFromFTPServerInProgress = false; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Got FTP Callback for [%s] result = %d [%s]\n", + itemName.c_str(), result.first, result.second.c_str()); + + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread->getProgressMutex() : + NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + //fileFTPProgressList.erase(itemName); + std::map < string, pair < int, + string > >::iterator + iterFind = fileFTPProgressList.find(itemName); + if (iterFind == fileFTPProgressList.end()) { + iterFind = + fileFTPProgressList.find(GameConstants:: + saveNetworkGameFileServerCompressed); + if (iterFind == fileFTPProgressList.end()) { + iterFind = + fileFTPProgressList.find(GameConstants:: + saveNetworkGameFileClientCompressed); + } + } + if (iterFind != fileFTPProgressList.end()) { + fileFTPProgressList.erase(iterFind->first); + } + safeMutexFTPProgress.ReleaseLock(); + + //printf("Status update downloading saved game file: [%s]\n",itemName.c_str()); + + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + //const GameSettings *gameSettings = clientInterface->getGameSettings(); + + if (result.first == ftp_crt_SUCCESS) { + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("JoinPlayerToCurrentGameSuccessDownload", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString + ("JoinPlayerToCurrentGameSuccessDownload", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), itemName.c_str()); + } else { + snprintf(szMsg, 8096, + "Player: %s SUCCESSFULLY downloaded the saved game: %s", + getHumanPlayerName().c_str(), itemName.c_str()); + } + clientInterface->sendTextMessage(szMsg, -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + } + sleep(1); + + if (itemName == GameConstants::saveNetworkGameFileClientCompressed) { + string saveGameFilePath = "temp/"; + string + saveGameFile = + saveGameFilePath + + string(GameConstants::saveNetworkGameFileClientCompressed); + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + != "") { + saveGameFilePath = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + saveGameFilePath; + saveGameFile = + saveGameFilePath + + string(GameConstants::saveNetworkGameFileClientCompressed); + } else { + string + userData = + Config::getInstance().getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + saveGameFilePath = userData + saveGameFilePath; + saveGameFile = + saveGameFilePath + + string(GameConstants::saveNetworkGameFileClientCompressed); + } + + string + extractedFileName = + saveGameFilePath + + string(GameConstants::saveNetworkGameFileClient); + bool + extract_result = + extractFileFromZIPFile(saveGameFile, extractedFileName); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Saved game [%s] compressed to [%s] returned: %d\n", + saveGameFile.c_str(), extractedFileName.c_str(), + extract_result); + } + readyToJoinInProgressGame = true; + + //printf("Success downloading saved game file: [%s]\n",itemName.c_str()); + } else { + curl_version_info_data * + curlVersion = curl_version_info(CURLVERSION_NOW); + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + char + szMsg[8096] = ""; + if (lang.hasString("JoinPlayerToCurrentGameFailDownload", + languageList[i]) == true) { + snprintf(szMsg, 8096, + lang.getString("JoinPlayerToCurrentGameFailDownload", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), itemName.c_str(), + curlVersion->version); + } else { + snprintf(szMsg, 8096, + "Player: %s FAILED to download the saved game: [%s] using CURL version [%s]", + getHumanPlayerName().c_str(), itemName.c_str(), + curlVersion->version); + } + clientInterface->sendTextMessage(szMsg, -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + + if (result.first == ftp_crt_HOST_NOT_ACCEPTING) { + if (lang.hasString("HostNotAcceptingDataConnections", + languageList[i]) == true) { + clientInterface->sendTextMessage(lang.getString + ("HostNotAcceptingDataConnections", + languageList[i]), -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + } else { + clientInterface->sendTextMessage + ("*Warning* the host is not accepting data connections.", + -1, lang.isLanguageLocal(languageList[i]), + languageList[i]); + } + } + } + sleep(1); + + console.addLine(result.second, true); + } + } + } + + void + MenuStateConnectedGame::setupUIFromGameSettings(GameSettings * + gameSettings, + bool errorOnMissingData) { + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + + updateDataSynchDetailText = true; + vector < string > tilesets, techtree; + + if (gameSettings == NULL) { + throw megaglest_runtime_error("gameSettings == NULL"); + } + + + checkBoxScenario.setValue((gameSettings->getScenario() != "")); + if (checkBoxScenario.getValue() == true) { + int + originalFOWValue = listBoxFogOfWar.getSelectedItemIndex(); + + string scenario = gameSettings->getScenario(); + listBoxScenario.setSelectedItem(formatString(scenario)); + string file = Scenario::getScenarioPath(dirList, scenario); + + bool isTutorial = Scenario::isGameTutorial(file); + Scenario::loadScenarioInfo(file, &scenarioInfo, isTutorial); + + gameSettings->setScenarioDir(Scenario::getScenarioPath + (dirList, scenarioInfo.name)); + + gameSettings->setDefaultResources(scenarioInfo.defaultResources); + gameSettings->setDefaultUnits(scenarioInfo.defaultUnits); + gameSettings-> + setDefaultVictoryConditions(scenarioInfo.defaultVictoryConditions); + + if (scenarioInfo.fogOfWar == false + && scenarioInfo.fogOfWar_exploredFlag == false) { + listBoxFogOfWar.setSelectedItemIndex(2); + } else if (scenarioInfo.fogOfWar_exploredFlag == true) { + listBoxFogOfWar.setSelectedItemIndex(1); + } else { + listBoxFogOfWar.setSelectedItemIndex(0); + } + + checkBoxAllowTeamUnitSharing. + setValue(scenarioInfo.allowTeamUnitSharing); + checkBoxAllowTeamResourceSharing. + setValue(scenarioInfo.allowTeamResourceSharing); + + if (originalFOWValue != listBoxFogOfWar.getSelectedItemIndex()) { + cleanupMapPreviewTexture(); + } + } + + if (listBoxMapFilter.getSelectedItemIndex() != + gameSettings->getMapFilter()) { + switchToMapGroup(gameSettings->getMapFilter()); + // printf("Switching to Map filter group %d \n",gameSettings->getMapFilter()); + } + + string + scenarioDir = + Scenario::getScenarioDir(dirList, gameSettings->getScenario()); + setupMapList(gameSettings->getScenario()); + setupTechList(gameSettings->getScenario()); + setupTilesetList(gameSettings->getScenario()); + + + //printf("A gameSettings->getTileset() [%s]\n",gameSettings->getTileset().c_str()); + + if (getMissingTilesetFromFTPServerInProgress == false + && gameSettings->getTileset() != "") { + // tileset + tilesets = tilesetFiles; + std::for_each(tilesets.begin(), tilesets.end(), FormatString()); + + if (std::find(tilesetFiles.begin(), tilesetFiles.end(), + gameSettings->getTileset()) != tilesetFiles.end()) { + lastMissingTileSet = ""; + getMissingTilesetFromFTPServer = ""; + listBoxTileset.setSelectedItem(formatString + (gameSettings->getTileset())); + } else { + // try to get the tileset via ftp + if (ftpClientThread != NULL && + (getMissingTilesetFromFTPServer != gameSettings->getTileset() + || difftime(time(NULL), + getMissingTilesetFromFTPServerLastPrompted) > + REPROMPT_DOWNLOAD_SECONDS)) { + if (ftpMessageBox.getEnabled() == false) { + getMissingTilesetFromFTPServerLastPrompted = time(NULL); + getMissingTilesetFromFTPServer = gameSettings->getTileset(); + Lang & lang = Lang::getInstance(); + + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "%s %s ?", + lang. + getString("DownloadMissingTilesetQuestion").c_str(), + gameSettings->getTileset().c_str()); + + // Is the item in the mod center? + MutexSafeWrapper + safeMutexThread((modHttpServerThread != + NULL ? + modHttpServerThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + if (tilesetCacheList.find(getMissingTilesetFromFTPServer) == + tilesetCacheList.end()) { + ftpMessageBox.init(lang.getString("Yes"), + lang.getString("NoDownload")); + } else { + ftpMessageBox.init(lang.getString("ModCenter"), + lang.getString("GameHost")); + ftpMessageBox.addButton(lang.getString("NoDownload")); + } + safeMutexThread.ReleaseLock(); + + ftpMissingDataType = ftpmsg_MissingTileset; + showFTPMessageBox(szBuf, lang.getString("Question"), false); + } + } + + tilesets. + push_back(Lang:: + getInstance().getString("DataMissing", "", true)); + + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + const GameSettings * + gameSettings = clientInterface->getGameSettings(); + + if (lastMissingTileSet != gameSettings->getTileset()) { + lastMissingTileSet = gameSettings->getTileset(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingTileset", languageList[i]) == + true) { + snprintf(szMsg, 8096, + lang.getString("DataMissingTileset", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), + gameSettings->getTileset().c_str()); + } else { + snprintf(szMsg, 8096, + "Player: %s is missing the tileset: %s", + getHumanPlayerName().c_str(), + gameSettings->getTileset().c_str()); + } + clientInterface->sendTextMessage(szMsg, -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + } + } + + listBoxTileset.setItems(tilesets); + listBoxTileset. + setSelectedItem(Lang:: + getInstance().getString("DataMissing", "", + true)); + } + + } + + if (getMissingTechtreeFromFTPServerInProgress == false && + gameSettings->getTech() != "") { + // techtree + techtree = techTreeFiles; + std::for_each(techtree.begin(), techtree.end(), FormatString()); + + if (std::find(techTreeFiles.begin(), techTreeFiles.end(), + gameSettings->getTech()) != techTreeFiles.end()) { + + lastMissingTechtree = ""; + getMissingTechtreeFromFTPServer = ""; + reloadFactions(true, gameSettings->getScenario()); + listBoxTechTree.setSelectedItem(formatString + (gameSettings->getTech())); + } else { + // try to get the tileset via ftp + if (ftpClientThread != NULL + && (getMissingTechtreeFromFTPServer != gameSettings->getTech() + || difftime(time(NULL), + getMissingTechtreeFromFTPServerLastPrompted) > + REPROMPT_DOWNLOAD_SECONDS)) { + if (ftpMessageBox.getEnabled() == false) { + getMissingTechtreeFromFTPServerLastPrompted = time(NULL); + getMissingTechtreeFromFTPServer = gameSettings->getTech(); + Lang & lang = Lang::getInstance(); + + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "%s %s ?", + lang. + getString("DownloadMissingTechtreeQuestion").c_str + (), gameSettings->getTech().c_str()); + + // Is the item in the mod center? + MutexSafeWrapper + safeMutexThread((modHttpServerThread != + NULL ? + modHttpServerThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + if (techCacheList.find(getMissingTechtreeFromFTPServer) == + techCacheList.end()) { + ftpMessageBox.init(lang.getString("Yes"), + lang.getString("NoDownload")); + } else { + ftpMessageBox.init(lang.getString("ModCenter"), + lang.getString("GameHost")); + ftpMessageBox.addButton(lang.getString("NoDownload")); + } + safeMutexThread.ReleaseLock(); + + ftpMissingDataType = ftpmsg_MissingTechtree; + showFTPMessageBox(szBuf, lang.getString("Question"), false); + } + } + + techtree. + push_back(Lang:: + getInstance().getString("DataMissing", "", true)); + + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + const GameSettings * + gameSettings = clientInterface->getGameSettings(); + + if (lastMissingTechtree != gameSettings->getTech()) { + lastMissingTechtree = gameSettings->getTech(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + Lang & lang = Lang::getInstance(); + const + vector < + string > + languageList = + clientInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + + char + szMsg[8096] = ""; + if (lang.hasString("DataMissingTechtree", languageList[i]) == + true) { + snprintf(szMsg, 8096, + lang.getString("DataMissingTechtree", + languageList[i]).c_str(), + getHumanPlayerName().c_str(), + gameSettings->getTech().c_str()); + } else { + snprintf(szMsg, 8096, + "Player: %s is missing the techtree: %s", + getHumanPlayerName().c_str(), + gameSettings->getTech().c_str()); + } + clientInterface->sendTextMessage(szMsg, -1, + lang.isLanguageLocal + (languageList[i]), + languageList[i]); + } + } + + vector < string > translatedTechs; + for (unsigned int i = 0; i < techTreeFiles.size(); i++) { + string + txTech = techTree->getTranslatedName(techTreeFiles.at(i)); + translatedTechs.push_back(txTech); + } + listBoxTechTree.setItems(techtree, translatedTechs); + listBoxTechTree. + setSelectedItem(Lang:: + getInstance().getString("DataMissing", "", + true)); + } + } + + // factions + bool hasFactions = true; + if (currentFactionName != gameSettings->getTech() + && gameSettings->getTech() != "") { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] hasFactions = %d, currentFactionName [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, hasFactions, + currentFactionName.c_str()); + currentFactionName = gameSettings->getTech(); + hasFactions = loadFactions(gameSettings, false); + } else { + // do this to process special faction types like observers + loadFactions(gameSettings, false); + } + + + if (getMissingMapFromFTPServerInProgress == false && + gameSettings->getMap() != "" + && gameSettings->getMapFilter() == + listBoxMapFilter.getSelectedItemIndex()) { + // map + bool missingMap = false; + string mapFile = gameSettings->getMap(); + mapFile = formatString(mapFile); + + if (currentMap != gameSettings->getMap()) { // load the setup again + currentMap = gameSettings->getMap(); + } + bool + mapLoaded = + loadMapInfo(Config::getMapPath(currentMap, scenarioDir, false), + &mapInfo, true); + if (mapLoaded == false) { + // try to get the map via ftp + if (ftpClientThread != NULL + && (getMissingMapFromFTPServer != currentMap + || difftime(time(NULL), + getMissingMapFromFTPServerLastPrompted) > + REPROMPT_DOWNLOAD_SECONDS)) { + if (ftpMessageBox.getEnabled() == false) { + getMissingMapFromFTPServerLastPrompted = time(NULL); + getMissingMapFromFTPServer = currentMap; + Lang & lang = Lang::getInstance(); + + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "%s %s ?", + lang. + getString("DownloadMissingMapQuestion").c_str(), + currentMap.c_str()); + + // Is the item in the mod center? + MutexSafeWrapper + safeMutexThread((modHttpServerThread != + NULL ? + modHttpServerThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + + intToStr(__LINE__)); + if (mapCacheList.find(getMissingMapFromFTPServer) == + mapCacheList.end()) { + ftpMessageBox.init(lang.getString("Yes"), + lang.getString("NoDownload")); + } else { + ftpMessageBox.init(lang.getString("ModCenter"), + lang.getString("GameHost")); + ftpMessageBox.addButton(lang.getString("NoDownload")); + } + safeMutexThread.ReleaseLock(); + + ftpMissingDataType = ftpmsg_MissingMap; + showFTPMessageBox(szBuf, lang.getString("Question"), false); + } + } + + formattedPlayerSortedMaps[gameSettings-> + getMapFilter()].push_back(Lang:: + getInstance + ().getString + ("DataMissing", + "", true)); + mapFile = Lang::getInstance().getString("DataMissing", "", true); + missingMap = true; + } + + if (isHeadlessAdmin() && !missingMap + && mapFile != listBoxMap.getSelectedItem()) { + //console.addLine("Headless server does not have map, switching to next one"); + if (isfirstSwitchingMapMessage) { + isfirstSwitchingMapMessage = false; + } else { + console.addLine(Lang::getInstance().getString + ("HeadlessServerDoesNotHaveMap", "", true)); + } + } + listBoxMap.setItems(formattedPlayerSortedMaps + [gameSettings->getMapFilter()]); + + //printf("Setting map from game settings map:%s , settingsfilter=%d , boxfilter=%d \n",gameSettings->getMap().c_str(),gameSettings->getMapFilter(),listBoxMapFilter.getSelectedItemIndex()); + listBoxMap.setSelectedItem(mapFile); + labelMapInfo.setText(mapInfo.desc); + } + + // FogOfWar + if (checkBoxScenario.getValue() == false) { + int + originalFOWValue = listBoxFogOfWar.getSelectedItemIndex(); + listBoxFogOfWar.setSelectedItemIndex(0); // default is 0! + if (gameSettings->getFogOfWar() == false) { + listBoxFogOfWar.setSelectedItemIndex(2); + } + if ((gameSettings->getFlagTypes1() & ft1_show_map_resources) == + ft1_show_map_resources) { + if (gameSettings->getFogOfWar() == true) { + listBoxFogOfWar.setSelectedItemIndex(1); + } + } + if (originalFOWValue != listBoxFogOfWar.getSelectedItemIndex()) { + cleanupMapPreviewTexture(); + } + } + + // Allow Observers + if (gameSettings->getAllowObservers()) { + checkBoxAllowObservers.setValue(true); + } else { + checkBoxAllowObservers.setValue(false); + } + + if ((gameSettings->getFlagTypes1() & ft1_allow_team_switching) == + ft1_allow_team_switching) { + checkBoxEnableSwitchTeamMode.setValue(true); + } else { + checkBoxEnableSwitchTeamMode.setValue(false); + } + listBoxAISwitchTeamAcceptPercent.setSelectedItem(intToStr + (gameSettings->getAiAcceptSwitchTeamPercentChance + ())); + listBoxFallbackCpuMultiplier. + setSelectedItemIndex(gameSettings->getFallbackCpuMultiplier()); + + if ((gameSettings->getFlagTypes1() & ft1_allow_shared_team_units) == + ft1_allow_shared_team_units) { + checkBoxAllowTeamUnitSharing.setValue(true); + } else { + checkBoxAllowTeamUnitSharing.setValue(false); + } + + if ((gameSettings->getFlagTypes1() & ft1_allow_shared_team_resources) + == ft1_allow_shared_team_resources) { + checkBoxAllowTeamResourceSharing.setValue(true); + } else { + checkBoxAllowTeamResourceSharing.setValue(false); + } + + checkBoxAllowNativeLanguageTechtree. + setValue(gameSettings->getNetworkAllowNativeLanguageTechtree()); + + // Control + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + listBoxControls[i].setSelectedItemIndex(ctClosed); + + if (isHeadlessAdmin() == false) { + if (clientInterface->getJoinGameInProgress() == false) { + listBoxFactions[i].setEditable(false); + listBoxTeams[i].setEditable(false); + } + } + + labelPlayerStatus[i].setTexture(NULL);; + } + + if (hasFactions == true && gameSettings != NULL) { + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + + //for(int i=0; i < gameSettings->getFactionCount(); ++i){ + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + int + slot = gameSettings->getStartLocationIndex(i); + + if (slot == clientInterface->getPlayerIndex()) { + labelPlayerNames[slot].setEditable(true); + } else { + labelPlayerNames[slot].setEditable(false); + } + + if (i >= mapInfo.players) { + if (gameSettings->getFactionControl(i) != ctNetworkUnassigned) { + continue; + } else if (clientInterface->getPlayerIndex() != slot) { + continue; + } + } + + if (gameSettings->getFactionControl(i) == ctNetwork || + gameSettings->getFactionControl(i) == ctNetworkUnassigned || + gameSettings->getFactionControl(i) == ctHuman) { + switch (gameSettings->getNetworkPlayerStatuses(i)) { + case npst_BeRightBack: + labelPlayerStatus[slot]. + setTexture(CoreData::getInstance().getStatusBRBTexture()); + break; + case npst_Ready: + labelPlayerStatus[slot]. + setTexture(CoreData:: + getInstance().getStatusReadyTexture()); + break; + case npst_PickSettings: + labelPlayerStatus[slot]. + setTexture(CoreData:: + getInstance().getStatusNotReadyTexture()); + break; + case npst_Disconnected: + labelPlayerStatus[slot].setTexture(NULL); + break; + + default: + labelPlayerStatus[slot].setTexture(NULL); + break; + } + } + + listBoxControls[slot]. + setSelectedItemIndex(gameSettings->getFactionControl(i), + errorOnMissingData); + listBoxRMultiplier[slot]. + setSelectedItemIndex(gameSettings->getResourceMultiplierIndex + (i), errorOnMissingData); + listBoxTeams[slot].setSelectedItemIndex(gameSettings->getTeam(i), + errorOnMissingData); + listBoxFactions[slot].setSelectedItem(formatString + (gameSettings-> + getFactionTypeName(i)), + false); + + if (gameSettings->getFactionControl(i) == ctNetwork || + gameSettings->getFactionControl(i) == ctNetworkUnassigned) { + labelNetStatus[slot]. + setText(gameSettings->getNetworkPlayerName(i)); + if (gameSettings->getThisFactionIndex() != i + && gameSettings->getNetworkPlayerName(i) != "" + && gameSettings->getNetworkPlayerName(i) != + GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) { + labelPlayerNames[slot]. + setText(gameSettings->getNetworkPlayerName(i)); + } + } + + ControlType ct = gameSettings->getFactionControl(i); + if (ct == ctHuman || ct == ctNetwork || ct == ctClosed) { + listBoxRMultiplier[slot].setEnabled(false); + listBoxRMultiplier[slot].setVisible(false); + } else { + listBoxRMultiplier[slot].setEnabled(true); + listBoxRMultiplier[slot].setVisible(true); + } + + if ((gameSettings->getFactionControl(i) == ctNetwork || + gameSettings->getFactionControl(i) == ctNetworkUnassigned) && + gameSettings->getThisFactionIndex() == i) { + + // set my current slot to ctHuman + if (gameSettings->getFactionControl(i) != ctNetworkUnassigned) { + listBoxControls[slot].setSelectedItemIndex(ctHuman); + } + if (checkBoxScenario.getValue() == false) { + if (clientInterface->getJoinGameInProgress() == false) { + if (i <= mapInfo.hardMaxPlayers) { + listBoxFactions[slot].setEditable(true); + listBoxTeams[slot].setEditable(true); + } else { + // looks more must be done to allow people to take an observer + // slot after the game has started. Extra network slots close + // when the game starts. + listBoxFactions[slot].setEditable(checkBoxAllowObservers.getValue()); + listBoxTeams[slot].setEditable(checkBoxAllowObservers.getValue()); + } + } + } + + if (labelPlayerNames[slot].getText() == "" && + gameSettings->getNetworkPlayerName(i) != "" && + gameSettings->getNetworkPlayerName(i) != + GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) { + labelPlayerNames[slot]. + setText(gameSettings->getNetworkPlayerName(i)); + } + } + } + settingsReceivedFromServer = true; + initialSettingsReceivedFromServer = true; + + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + + if (enableFactionTexturePreview == true) { + if (clientInterface != NULL && clientInterface->isConnected() && + gameSettings != NULL) { + + if (currentTechName_factionPreview != gameSettings->getTech() || + currentFactionName_factionPreview != + gameSettings-> + getFactionTypeName(gameSettings->getThisFactionIndex())) { + + currentTechName_factionPreview = gameSettings->getTech(); + currentFactionName_factionPreview = + gameSettings-> + getFactionTypeName(gameSettings->getThisFactionIndex()); + + initFactionPreview(gameSettings); + } + } + } + + } + + void + MenuStateConnectedGame::initFactionPreview(const GameSettings * + gameSettings) { + string factionVideoUrl = ""; + string factionVideoUrlFallback = ""; + + string + factionDefinitionXML = + Game::findFactionLogoFile(gameSettings, NULL, + currentFactionName_factionPreview + + ".xml"); + if (factionDefinitionXML != "" + && currentFactionName_factionPreview != + GameConstants::RANDOMFACTION_SLOTNAME + && currentFactionName_factionPreview != + GameConstants::OBSERVER_SLOTNAME + && fileExists(factionDefinitionXML) == true) { + XmlTree xmlTree; + std::map < string, string > mapExtraTagReplacementValues; + xmlTree.load(factionDefinitionXML, + Properties::getTagReplacementValues + (&mapExtraTagReplacementValues)); + const XmlNode * + factionNode = xmlTree.getRootNode(); + if (factionNode->hasAttribute("faction-preview-video") == true) { + factionVideoUrl = + factionNode->getAttribute("faction-preview-video")->getValue(); + } + + factionVideoUrlFallback = + Game::findFactionLogoFile(gameSettings, NULL, "preview_video.*"); + if (factionVideoUrl == "") { + factionVideoUrl = factionVideoUrlFallback; + factionVideoUrlFallback = ""; + } + } + + if (factionVideoUrl != "") { + if (CoreData::getInstance().getMenuMusic()->getVolume() != 0) { + CoreData::getInstance().getMenuMusic()->setVolume(0); + factionVideoSwitchedOffVolume = true; + } + + if (currentFactionLogo != factionVideoUrl) { + currentFactionLogo = factionVideoUrl; + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false + && ::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == + true) { + + if (factionVideo != NULL) { + factionVideo->closePlayer(); + delete factionVideo; + factionVideo = NULL; + } + string introVideoFile = factionVideoUrl; + string introVideoFileFallback = factionVideoUrlFallback; + + Context * + c = GraphicsInterface::getInstance().getCurrentContext(); + PlatformContextGl * + glCtx = + static_cast (c)->getPlatformContextGlPtr(); + SDL_Window * + window = glCtx->getScreenWindow(); + SDL_Surface * + screen = glCtx->getScreenSurface(); + + string + vlcPluginsPath = + Config::getInstance().getString("VideoPlayerPluginsPath", ""); + //printf("screen->w = %d screen->h = %d screen->format->BitsPerPixel = %d\n",screen->w,screen->h,screen->format->BitsPerPixel); + factionVideo = new VideoPlayer(&Renderer::getInstance(), + introVideoFile, + introVideoFileFallback, + window, + 0, 0, + screen->w, + screen->h, + screen->format->BitsPerPixel, + true, + vlcPluginsPath, + SystemFlags::VERBOSE_MODE_ENABLED); + factionVideo->initPlayer(); + } + } + } else { + //switch on music again!! + Config & config = Config::getInstance(); + float + configVolume = (config.getInt("SoundVolumeMusic") / 100.f); + if (factionVideoSwitchedOffVolume) { + if (CoreData::getInstance().getMenuMusic()->getVolume() != + configVolume) { + CoreData::getInstance(). + getMenuMusic()->setVolume(configVolume); + } + factionVideoSwitchedOffVolume = false; + } + + if (factionVideo != NULL) { + factionVideo->closePlayer(); + delete factionVideo; + factionVideo = NULL; + } + } + + if (factionVideo == NULL) { + string + factionLogo = + Game::findFactionLogoFile(gameSettings, NULL, + GameConstants::PREVIEW_SCREEN_FILE_FILTER); + if (factionLogo == "") { + factionLogo = Game::findFactionLogoFile(gameSettings, NULL); + } + if (currentFactionLogo != factionLogo) { + currentFactionLogo = factionLogo; + loadFactionTexture(currentFactionLogo); + } + } + } + + void + MenuStateConnectedGame::RestoreLastGameSettings() { + // Ensure we have set the gamesettings at least once + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface * + clientInterface = networkManager.getClientInterface(); + GameSettings gameSettings = *clientInterface->getGameSettings(); + CoreData:: + getInstance().loadGameSettingsFromFile(HEADLESS_SAVED_GAME_FILENAME, + &gameSettings); + if (gameSettings.getMap() == "") { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + loadGameSettings(&gameSettings); + } + + setupUIFromGameSettings(&gameSettings, false); + + needToBroadcastServerSettings = true; + broadcastServerSettingsDelayTimer = time(NULL); + noReceiveTimer = time(NULL); + + } + + int + MenuStateConnectedGame::setupMapList(string scenario) { + int + initialMapSelection = 0; + + try { + Config & config = Config::getInstance(); + vector < string > invalidMapList; + string scenarioDir = Scenario::getScenarioDir(dirList, scenario); + vector < string > pathList = + config.getPathListForType(ptMaps, scenarioDir); + vector < string > allMaps = + MapPreview::findAllValidMaps(pathList, scenarioDir, false, true, + &invalidMapList); + // sort map list non case sensitive + std::sort(allMaps.begin(), allMaps.end(), compareNonCaseSensitive); + if (scenario != "") { + vector < string > allMaps2 = + MapPreview:: + findAllValidMaps(config.getPathListForType(ptMaps, ""), "", + false, true, &invalidMapList); + copy(allMaps2.begin(), allMaps2.end(), + std::inserter(allMaps, allMaps.begin())); + std::sort(allMaps.begin(), allMaps.end(), + compareNonCaseSensitive); + } + + if (allMaps.empty()) { + throw megaglest_runtime_error("No maps were found!"); + } + vector < string > results; + copy(allMaps.begin(), allMaps.end(), std::back_inserter(results)); + mapFiles = results; + + for (unsigned int i = 0; i < GameConstants::maxPlayers + 1; ++i) { + playerSortedMaps[i].clear(); + formattedPlayerSortedMaps[i].clear(); + } + + copy(mapFiles.begin(), mapFiles.end(), + std::back_inserter(playerSortedMaps[0])); + copy(playerSortedMaps[0].begin(), playerSortedMaps[0].end(), + std::back_inserter(formattedPlayerSortedMaps[0])); + std::for_each(formattedPlayerSortedMaps[0].begin(), + formattedPlayerSortedMaps[0].end(), FormatString()); + + formattedMapFiles.clear(); + for (int i = 0; i < (int) mapFiles.size(); i++) { // fetch info and put map in right list + loadMapInfo(Config::getMapPath + (mapFiles.at(i), scenarioDir, false), &mapInfo, + false); + + if (GameConstants::maxPlayers + 1 <= mapInfo.players) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Sorted map list [%d] does not match\ncurrent map playercount [%d]\nfor file [%s]\nmap [%s]", + GameConstants::maxPlayers + 1, mapInfo.players, + Config::getMapPath(mapFiles.at(i), "", + false).c_str(), + mapInfo.desc.c_str()); + throw megaglest_runtime_error(szBuf); + } + playerSortedMaps[mapInfo.hardMaxPlayers].push_back(mapFiles.at(i)); + formattedPlayerSortedMaps[mapInfo.hardMaxPlayers].push_back(formatString + (mapFiles.at + (i))); + if (config.getString("InitialMap", "Conflict") == + formattedPlayerSortedMaps[mapInfo.hardMaxPlayers].back()) { + initialMapSelection = i; + } + formattedMapFiles.push_back(formatString(mapFiles.at(i))); + } + + if (scenario != "") { + string file = Scenario::getScenarioPath(dirList, scenario); + loadScenarioInfo(file, &scenarioInfo); + + loadMapInfo(Config::getMapPath + (scenarioInfo.mapName, scenarioDir, true), &mapInfo, + false); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line %d] listBoxMap.getSelectedItemIndex() = %d, mapFiles.size() = " + MG_SIZE_T_SPECIFIER + ", mapInfo.players = %d, formattedPlayerSortedMaps[mapInfo.players].size() = " + MG_SIZE_T_SPECIFIER ", scenarioInfo.mapName [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, + __LINE__, listBoxMap.getSelectedItemIndex(), mapFiles.size(), + mapInfo.players, + formattedPlayerSortedMaps[mapInfo.players].size(), + scenarioInfo.mapName.c_str()); + listBoxMap.setItems(formattedPlayerSortedMaps[mapInfo.players]); + } + } catch (const std::exception & ex) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + throw megaglest_runtime_error(szBuf); + //abort(); + } + + return initialMapSelection; + } + + int + MenuStateConnectedGame::setupTechList(string scenario, bool forceLoad) { + int + initialTechSelection = 0; + try { + Config & config = Config::getInstance(); + + string scenarioDir = Scenario::getScenarioDir(dirList, scenario); + vector < string > results; + vector < string > techPaths = + config.getPathListForType(ptTechs, scenarioDir); + findDirs(techPaths, results); + + if (results.empty()) { + throw megaglest_runtime_error("No tech-trees were found!"); + } + + techTreeFiles = results; + + vector < string > translatedTechs; + + for (unsigned int i = 0; i < results.size(); i++) { + //printf("TECHS i = %d results [%s] scenario [%s]\n",i,results[i].c_str(),scenario.c_str()); + + results.at(i) = formatString(results.at(i)); + if (config.getString("InitialTechTree", "Megapack") == + results.at(i)) { + initialTechSelection = i; + } + string + txTech = + techTree->getTranslatedName(techTreeFiles.at(i), forceLoad); + translatedTechs.push_back(formatString(txTech)); + } + + + listBoxTechTree.setItems(results, translatedTechs); + } catch (const std::exception & ex) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + throw megaglest_runtime_error(szBuf); + } + + return initialTechSelection; + } + + void + MenuStateConnectedGame::setupTilesetList(string scenario) { + try { + Config & config = Config::getInstance(); + + string scenarioDir = Scenario::getScenarioDir(dirList, scenario); + + vector < string > results; + findDirs(config.getPathListForType(ptTilesets, scenarioDir), + results); + if (results.empty()) { + //throw megaglest_runtime_error("No tile-sets were found!"); + showMessageBox("No tile-sets were found!", "Error", false); + } else { + tilesetFiles = results; + std::for_each(results.begin(), results.end(), FormatString()); + + listBoxTileset.setItems(results); + } + } catch (const std::exception & ex) { + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + throw megaglest_runtime_error(szBuf); + } + } + + void + MenuStateConnectedGame::loadScenarioInfo(string file, + ScenarioInfo * scenarioInfo) { + bool isTutorial = Scenario::isGameTutorial(file); + Scenario::loadScenarioInfo(file, scenarioInfo, isTutorial); + + previewLoadDelayTimer = time(NULL); + needToLoadTextures = true; + } + + } +} //end namespace diff --git a/source/glest_game/menu/menu_state_connected_game.h b/source/glest_game/menu/menu_state_connected_game.h index 6de8b4d26..1db58ce10 100644 --- a/source/glest_game/menu/menu_state_connected_game.h +++ b/source/glest_game/menu/menu_state_connected_game.h @@ -36,326 +36,321 @@ # include "common_scoped_ptr.h" # include "leak_dumper.h" -namespace Shared -{ - namespace Graphics - { - class VideoPlayer; -}} - -namespace Glest -{ - namespace Game - { - - class TechTree; - - enum JoinMenu - { - jmSimple, - jmMasterserver, - - jmCount - }; - - enum FTPMessageType - { - ftpmsg_MissingNone, - ftpmsg_MissingMap, - ftpmsg_MissingTileset, - ftpmsg_MissingTechtree - }; - -// =============================== -// class MenuStateConnectedGame -// =============================== - - class MenuStateConnectedGame:public MenuState, - public FTPClientCallbackInterface, public SimpleTaskCallbackInterface - { - private: - GraphicButton buttonDisconnect; - GraphicLabel labelControl; - GraphicLabel labelRMultiplier; - GraphicLabel labelFaction; - GraphicLabel labelTeam; - GraphicLabel labelMap; - GraphicLabel labelFogOfWar; - GraphicLabel labelTechTree; - GraphicLabel labelTileset; - GraphicLabel labelMapInfo; - GraphicLabel labelStatus; - GraphicLabel labelInfo; - GraphicLabel labelWaitingForPlayers; - GraphicButton buttonRestoreLastSettings; - -//GraphicLabel labelPathFinderType; -//GraphicListBox listBoxPathFinderType; - - GraphicLabel labelMapPlayerCount; - GraphicListBox listBoxMapPlayerCount; - - GraphicLabel labelAdvanced; - GraphicListBox listBoxAdvanced; - - GraphicListBox listBoxMap; - GraphicListBox listBoxFogOfWar; - GraphicListBox listBoxTechTree; - GraphicListBox listBoxTileset; - GraphicLabel labelPlayers[GameConstants::maxPlayers]; - GraphicLabel labelPlayerNames[GameConstants::maxPlayers]; - GraphicListBox listBoxControls[GameConstants::maxPlayers]; - GraphicListBox listBoxRMultiplier[GameConstants::maxPlayers]; - GraphicListBox listBoxFactions[GameConstants::maxPlayers]; - GraphicListBox listBoxTeams[GameConstants::maxPlayers]; - GraphicLabel labelNetStatus[GameConstants::maxPlayers]; - GraphicButton grabSlotButton[GameConstants::maxPlayers]; - - GraphicListBox listBoxPlayerStatus; - GraphicLabel labelPlayerStatus[GameConstants::maxPlayers]; - - GraphicLabel labelMapFilter; - GraphicListBox listBoxMapFilter; - - GraphicLabel labelAllowObservers; - GraphicCheckBox checkBoxAllowObservers; - - GraphicLabel labelAllowNativeLanguageTechtree; - GraphicCheckBox checkBoxAllowNativeLanguageTechtree; - - GraphicLabel *activeInputLabel; - - time_t timerLabelFlash; - GraphicLabel labelDataSynchInfo; - - MapInfo mapInfo; - Texture2D *mapPreviewTexture; - bool zoomedMap; - int render_mapPreviewTexture_X; - int render_mapPreviewTexture_Y; - int render_mapPreviewTexture_W; - int render_mapPreviewTexture_H; - - bool needToSetChangedGameSettings; - time_t lastSetChangedGameSettings; - bool updateDataSynchDetailText; - - int soundConnectionCount; - -//Console console; - ChatManager chatManager; - bool showFullConsole; - - string currentFactionName; - string currentMap; - JoinMenu returnMenuInfo; - bool settingsReceivedFromServer; - time_t lastNetworkSendPing; - int pingCount; - bool initialSettingsReceivedFromServer; - - string lastMapDataSynchError; - string lastTileDataSynchError; - string lastTechtreeDataSynchError; - - int8 switchSetupRequestFlagType; - string defaultPlayerName; - - bool enableFactionTexturePreview; - bool enableMapPreview; - - string currentTechName_factionPreview; - string currentFactionName_factionPreview; - string currentFactionLogo; - Texture2D *factionTexture; - ::Shared::Graphics::VideoPlayer * factionVideo; - bool factionVideoSwitchedOffVolume; - - MapPreview mapPreview; - - GraphicMessageBox mainMessageBox; - - std::string lastMissingMap; - std::string lastMissingTechtree; - std::string lastMissingTileSet; - - vector < string > mapFiles; - vector < string > techTreeFiles; - vector < string > tilesetFiles; - vector < string > factionFiles; +namespace Shared { + namespace Graphics { + class VideoPlayer; + } +} + +namespace Glest { + namespace Game { + + class TechTree; + + enum JoinMenu { + jmSimple, + jmMasterserver, + + jmCount + }; + + enum FTPMessageType { + ftpmsg_MissingNone, + ftpmsg_MissingMap, + ftpmsg_MissingTileset, + ftpmsg_MissingTechtree + }; + + // =============================== + // class MenuStateConnectedGame + // =============================== + + class MenuStateConnectedGame :public MenuState, + public FTPClientCallbackInterface, public SimpleTaskCallbackInterface { + private: + GraphicButton buttonDisconnect; + GraphicLabel labelControl; + GraphicLabel labelRMultiplier; + GraphicLabel labelFaction; + GraphicLabel labelTeam; + GraphicLabel labelMap; + GraphicLabel labelFogOfWar; + GraphicLabel labelTechTree; + GraphicLabel labelTileset; + GraphicLabel labelMapInfo; + GraphicLabel labelStatus; + GraphicLabel labelInfo; + GraphicLabel labelWaitingForPlayers; + GraphicButton buttonRestoreLastSettings; + + //GraphicLabel labelPathFinderType; + //GraphicListBox listBoxPathFinderType; + + GraphicLabel labelMapPlayerCount; + GraphicListBox listBoxMapPlayerCount; + + GraphicLabel labelAdvanced; + GraphicListBox listBoxAdvanced; + + GraphicListBox listBoxMap; + GraphicListBox listBoxFogOfWar; + GraphicListBox listBoxTechTree; + GraphicListBox listBoxTileset; + GraphicLabel labelPlayers[GameConstants::maxPlayers]; + GraphicLabel labelPlayerNames[GameConstants::maxPlayers]; + GraphicListBox listBoxControls[GameConstants::maxPlayers]; + GraphicListBox listBoxRMultiplier[GameConstants::maxPlayers]; + GraphicListBox listBoxFactions[GameConstants::maxPlayers]; + GraphicListBox listBoxTeams[GameConstants::maxPlayers]; + GraphicLabel labelNetStatus[GameConstants::maxPlayers]; + GraphicButton grabSlotButton[GameConstants::maxPlayers]; + + GraphicListBox listBoxPlayerStatus; + GraphicLabel labelPlayerStatus[GameConstants::maxPlayers]; + + GraphicLabel labelMapFilter; + GraphicListBox listBoxMapFilter; + + GraphicLabel labelAllowObservers; + GraphicCheckBox checkBoxAllowObservers; + + GraphicLabel labelAllowNativeLanguageTechtree; + GraphicCheckBox checkBoxAllowNativeLanguageTechtree; + + GraphicLabel *activeInputLabel; + + time_t timerLabelFlash; + GraphicLabel labelDataSynchInfo; + + MapInfo mapInfo; + Texture2D *mapPreviewTexture; + bool zoomedMap; + int render_mapPreviewTexture_X; + int render_mapPreviewTexture_Y; + int render_mapPreviewTexture_W; + int render_mapPreviewTexture_H; + + bool needToSetChangedGameSettings; + time_t lastSetChangedGameSettings; + bool updateDataSynchDetailText; + + int soundConnectionCount; + + //Console console; + ChatManager chatManager; + bool showFullConsole; + + string currentFactionName; + string currentMap; + JoinMenu returnMenuInfo; + bool settingsReceivedFromServer; + time_t lastNetworkSendPing; + int pingCount; + bool initialSettingsReceivedFromServer; + + string lastMapDataSynchError; + string lastTileDataSynchError; + string lastTechtreeDataSynchError; + + int8 switchSetupRequestFlagType; + string defaultPlayerName; + + bool enableFactionTexturePreview; + bool enableMapPreview; + + string currentTechName_factionPreview; + string currentFactionName_factionPreview; + string currentFactionLogo; + Texture2D *factionTexture; + ::Shared::Graphics::VideoPlayer * factionVideo; + bool factionVideoSwitchedOffVolume; + + MapPreview mapPreview; + + GraphicMessageBox mainMessageBox; + + std::string lastMissingMap; + std::string lastMissingTechtree; + std::string lastMissingTileSet; + + vector < string > mapFiles; + vector < string > techTreeFiles; + vector < string > tilesetFiles; + vector < string > factionFiles; - vector < string > playerSortedMaps[GameConstants::maxPlayers + 1]; - vector < string > - formattedPlayerSortedMaps[GameConstants::maxPlayers + 1]; - vector < string > formattedMapFiles; + vector < string > playerSortedMaps[GameConstants::maxPlayers + 1]; + vector < string > + formattedPlayerSortedMaps[GameConstants::maxPlayers + 1]; + vector < string > formattedMapFiles; - GraphicMessageBox ftpMessageBox; - FTPClientThread *ftpClientThread; - FTPMessageType ftpMissingDataType; - - SimpleTaskThread *modHttpServerThread; - std::vector < std::string > tilesetListRemote; - std::map < string, ModInfo > tilesetCacheList; - std::vector < std::string > techListRemote; - std::map < string, ModInfo > techCacheList; - std::vector < std::string > mapListRemote; - std::map < string, ModInfo > mapCacheList; + GraphicMessageBox ftpMessageBox; + FTPClientThread *ftpClientThread; + FTPMessageType ftpMissingDataType; + + SimpleTaskThread *modHttpServerThread; + std::vector < std::string > tilesetListRemote; + std::map < string, ModInfo > tilesetCacheList; + std::vector < std::string > techListRemote; + std::map < string, ModInfo > techCacheList; + std::vector < std::string > mapListRemote; + std::map < string, ModInfo > mapCacheList; - std::map < string, uint32 > mapCRCUpdateList; + std::map < string, uint32 > mapCRCUpdateList; - string getMissingMapFromFTPServer; - bool getMissingMapFromFTPServerInProgress; - time_t getMissingMapFromFTPServerLastPrompted; + string getMissingMapFromFTPServer; + bool getMissingMapFromFTPServerInProgress; + time_t getMissingMapFromFTPServerLastPrompted; - string getMissingTilesetFromFTPServer; - bool getMissingTilesetFromFTPServerInProgress; - time_t getMissingTilesetFromFTPServerLastPrompted; + string getMissingTilesetFromFTPServer; + bool getMissingTilesetFromFTPServerInProgress; + time_t getMissingTilesetFromFTPServerLastPrompted; - string getMissingTechtreeFromFTPServer; - bool getMissingTechtreeFromFTPServerInProgress; - time_t getMissingTechtreeFromFTPServerLastPrompted; + string getMissingTechtreeFromFTPServer; + bool getMissingTechtreeFromFTPServerInProgress; + time_t getMissingTechtreeFromFTPServerLastPrompted; - string getInProgressSavedGameFromFTPServer; - bool getInProgressSavedGameFromFTPServerInProgress; - bool readyToJoinInProgressGame; + string getInProgressSavedGameFromFTPServer; + bool getInProgressSavedGameFromFTPServerInProgress; + bool readyToJoinInProgressGame; - string lastCheckedCRCTilesetName; - string lastCheckedCRCTechtreeName; - string lastCheckedCRCMapName; - uint32 lastCheckedCRCTilesetValue; - uint32 lastCheckedCRCTechtreeValue; - uint32 lastCheckedCRCMapValue; - vector < pair < string, uint32 > >factionCRCList; - - std::map < string, pair < int, string > >fileFTPProgressList; - GraphicButton buttonCancelDownloads; - - GraphicLabel labelEnableSwitchTeamMode; - GraphicCheckBox checkBoxEnableSwitchTeamMode; - - GraphicLabel labelAllowTeamUnitSharing; - GraphicCheckBox checkBoxAllowTeamUnitSharing; - - GraphicLabel labelAllowTeamResourceSharing; - GraphicCheckBox checkBoxAllowTeamResourceSharing; - - GraphicLabel labelAISwitchTeamAcceptPercent; - GraphicListBox listBoxAISwitchTeamAcceptPercent; - GraphicLabel labelFallbackCpuMultiplier; - GraphicListBox listBoxFallbackCpuMultiplier; - - - GraphicButton buttonPlayNow; - - GraphicCheckBox checkBoxScenario; - GraphicLabel labelScenario; - GraphicListBox listBoxScenario; - vector < string > scenarioFiles; - ScenarioInfo scenarioInfo; - vector < string > dirList; - string autoloadScenarioName; - time_t previewLoadDelayTimer; - bool needToLoadTextures; - bool enableScenarioTexturePreview; - Texture2D *scenarioLogoTexture; + string lastCheckedCRCTilesetName; + string lastCheckedCRCTechtreeName; + string lastCheckedCRCMapName; + uint32 lastCheckedCRCTilesetValue; + uint32 lastCheckedCRCTechtreeValue; + uint32 lastCheckedCRCMapValue; + vector < pair < string, uint32 > >factionCRCList; + + std::map < string, pair < int, string > >fileFTPProgressList; + GraphicButton buttonCancelDownloads; + + GraphicLabel labelEnableSwitchTeamMode; + GraphicCheckBox checkBoxEnableSwitchTeamMode; + + GraphicLabel labelAllowTeamUnitSharing; + GraphicCheckBox checkBoxAllowTeamUnitSharing; + + GraphicLabel labelAllowTeamResourceSharing; + GraphicCheckBox checkBoxAllowTeamResourceSharing; + + GraphicLabel labelAISwitchTeamAcceptPercent; + GraphicListBox listBoxAISwitchTeamAcceptPercent; + GraphicLabel labelFallbackCpuMultiplier; + GraphicListBox listBoxFallbackCpuMultiplier; + + + GraphicButton buttonPlayNow; + + GraphicCheckBox checkBoxScenario; + GraphicLabel labelScenario; + GraphicListBox listBoxScenario; + vector < string > scenarioFiles; + ScenarioInfo scenarioInfo; + vector < string > dirList; + string autoloadScenarioName; + time_t previewLoadDelayTimer; + bool needToLoadTextures; + bool enableScenarioTexturePreview; + Texture2D *scenarioLogoTexture; - bool needToBroadcastServerSettings; - time_t broadcastServerSettingsDelayTimer; - int lastGameSettingsReceivedCount; - - time_t noReceiveTimer; + bool needToBroadcastServerSettings; + time_t broadcastServerSettingsDelayTimer; + int lastGameSettingsReceivedCount; + + time_t noReceiveTimer; + + bool launchingNewGame; + bool isfirstSwitchingMapMessage; + auto_ptr < TechTree > techTree; - bool launchingNewGame; - bool isfirstSwitchingMapMessage; - auto_ptr < TechTree > techTree; + GameSettings originalGamesettings; + bool validOriginalGameSettings; + GameSettings displayedGamesettings; + bool validDisplayedGamesettings; + + + public: + + MenuStateConnectedGame(Program * program, MainMenu * mainMenu, + JoinMenu joinMenuInfo = + jmSimple, bool openNetworkSlots = false); + virtual ~MenuStateConnectedGame(); - GameSettings originalGamesettings; - bool validOriginalGameSettings; - GameSettings displayedGamesettings; - bool validDisplayedGamesettings; - - - public: + void mouseClick(int x, int y, MouseButton mouseButton); + void mouseMove(int x, int y, const MouseState * mouseState); + void render(); + void update(); - MenuStateConnectedGame (Program * program, MainMenu * mainMenu, - JoinMenu joinMenuInfo = - jmSimple, bool openNetworkSlots = false); - virtual ~ MenuStateConnectedGame (); + virtual bool textInput(std::string text); + virtual void keyDown(SDL_KeyboardEvent key); + virtual void keyPress(SDL_KeyboardEvent c); + virtual void keyUp(SDL_KeyboardEvent key); + + virtual bool isInSpecialKeyCaptureEvent(); - void mouseClick (int x, int y, MouseButton mouseButton); - void mouseMove (int x, int y, const MouseState * mouseState); - void render (); - void update (); + virtual void reloadUI(); - virtual bool textInput (std::string text); - virtual void keyDown (SDL_KeyboardEvent key); - virtual void keyPress (SDL_KeyboardEvent c); - virtual void keyUp (SDL_KeyboardEvent key); - - virtual bool isInSpecialKeyCaptureEvent (); + virtual bool isVideoPlaying(); - virtual void reloadUI (); + private: - virtual bool isVideoPlaying (); - - private: - - bool hasNetworkGameSettings (); - bool loadFactions (const GameSettings * gameSettings, - bool errorOnNoFactions); - void returnToJoinMenu (); - string getHumanPlayerName (); - void setActiveInputLabel (GraphicLabel * newLable); - - void loadFactionTexture (string filepath); - bool loadMapInfo (string file, MapInfo * mapInfo, bool loadMapPreview); - void showMessageBox (const string & text, const string & header, - bool toggle); - - void showFTPMessageBox (const string & text, const string & header, - bool toggle); - virtual void FTPClient_CallbackEvent (string itemName, - FTP_Client_CallbackType type, - pair < FTP_Client_ResultType, - string > result, void *userdata); - - int32 getNetworkPlayerStatus (); - void cleanupMapPreviewTexture (); - - void mouseClickAdmin (int x, int y, MouseButton mouseButton, - string advanceToItemStartingWith); - void switchToNextMapGroup (const int direction); - void switchToMapGroup (int filterIndex); - string getCurrentMapFile (); - void loadGameSettings (GameSettings * gameSettings); - void reloadFactions (bool keepExistingSelectedItem, string scenario); - void PlayNow (bool saveGame); - bool isHeadlessAdmin (); - void broadCastGameSettingsToHeadlessServer (bool forceNow); - void updateResourceMultiplier (const int index); - - void RestoreLastGameSettings (); - void setupUIFromGameSettings (GameSettings * gameSettings, - bool errorOnMissingData); - - int setupMapList (string scenario); - int setupTechList (string scenario, bool forceLoad = false); - void setupTilesetList (string scenario); - - void loadScenarioInfo (string file, ScenarioInfo * scenarioInfo); - void initFactionPreview (const GameSettings * gameSettings); - - virtual void simpleTask (BaseThread * callingThread, void *userdata); - string refreshTilesetModInfo (string tilesetInfo); - string refreshTechModInfo (string techInfo); - string refreshMapModInfo (string mapInfo); - string getMapCRC (string mapName); - - void disconnectFromServer (); - }; - -}} //end namespace + bool hasNetworkGameSettings(); + bool loadFactions(const GameSettings * gameSettings, + bool errorOnNoFactions); + void returnToJoinMenu(); + string getHumanPlayerName(); + void setActiveInputLabel(GraphicLabel * newLable); + + void loadFactionTexture(string filepath); + bool loadMapInfo(string file, MapInfo * mapInfo, bool loadMapPreview); + void showMessageBox(const string & text, const string & header, + bool toggle); + + void showFTPMessageBox(const string & text, const string & header, + bool toggle); + virtual void FTPClient_CallbackEvent(string itemName, + FTP_Client_CallbackType type, + pair < FTP_Client_ResultType, + string > result, void *userdata); + + int32 getNetworkPlayerStatus(); + void cleanupMapPreviewTexture(); + + void mouseClickAdmin(int x, int y, MouseButton mouseButton, + string advanceToItemStartingWith); + void switchToNextMapGroup(const int direction); + void switchToMapGroup(int filterIndex); + string getCurrentMapFile(); + void loadGameSettings(GameSettings * gameSettings); + void reloadFactions(bool keepExistingSelectedItem, string scenario); + void PlayNow(bool saveGame); + bool isHeadlessAdmin(); + void broadCastGameSettingsToHeadlessServer(bool forceNow); + void updateResourceMultiplier(const int index); + + void RestoreLastGameSettings(); + void setupUIFromGameSettings(GameSettings * gameSettings, + bool errorOnMissingData); + + int setupMapList(string scenario); + int setupTechList(string scenario, bool forceLoad = false); + void setupTilesetList(string scenario); + + void loadScenarioInfo(string file, ScenarioInfo * scenarioInfo); + void initFactionPreview(const GameSettings * gameSettings); + + virtual void simpleTask(BaseThread * callingThread, void *userdata); + string refreshTilesetModInfo(string tilesetInfo); + string refreshTechModInfo(string techInfo); + string refreshMapModInfo(string mapInfo); + string getMapCRC(string mapName); + + void disconnectFromServer(); + }; + + } +} //end namespace #endif diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index 7cbfc2295..7a189625f 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -47,7072 +47,6279 @@ #include "gen_uuid.h" #include "leak_dumper.h" -namespace Glest -{ - namespace Game - { - - using namespace::Shared::Util; - - const int MASTERSERVER_BROADCAST_MAX_WAIT_RESPONSE_SECONDS = 15; - static const char *SAVED_GAME_FILENAME = "lastCustomGameSettings.mgg"; - static const char *DEFAULT_GAME_FILENAME = "data/defaultGameSetup.mgg"; - static const char *DEFAULT_NETWORKGAME_FILENAME = - "data/defaultNetworkGameSetup.mgg"; - - const int mapPreviewTexture_X = 5; - const int mapPreviewTexture_Y = 185; - const int mapPreviewTexture_W = 150; - const int mapPreviewTexture_H = 150; - - struct FormatString - { - void operator () (string & s) - { - s = formatString (s); - } - }; - -// ===================================================== -// class MenuStateCustomGame -// ===================================================== - enum THREAD_NOTIFIER_TYPE - { - tnt_MASTERSERVER = 1, - tnt_CLIENTS = 2 - }; - - MenuStateCustomGame::MenuStateCustomGame (Program * program, - MainMenu * mainMenu, - bool openNetworkSlots, - ParentMenuState - parentMenuState, - bool autostart, - GameSettings * settings, - bool masterserverMode, - string - autoloadScenarioName):MenuState - (program, mainMenu, "new-game") - { - try - { - - this->headlessServerMode = masterserverMode; - if (this->headlessServerMode == true) - { - printf ("Waiting for players to join and start a game...\n"); - } - - this->gameUUID = getUUIDAsString (); - - this->zoomedMap = false; - this->render_mapPreviewTexture_X = mapPreviewTexture_X; - this->render_mapPreviewTexture_Y = mapPreviewTexture_Y; - this->render_mapPreviewTexture_W = mapPreviewTexture_W; - this->render_mapPreviewTexture_H = mapPreviewTexture_H; - - this->lastMasterServerSettingsUpdateCount = 0; - this->masterserverModeMinimalResources = true; - this->parentMenuState = parentMenuState; - this->factionVideo = NULL; - factionVideoSwitchedOffVolume = false; - -//printf("this->masterserverMode = %d [%d]\n",this->masterserverMode,masterserverMode); - - forceWaitForShutdown = true; - this->autostart = autostart; - this->autoStartSettings = settings; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] autostart = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, autostart); - - containerName = "CustomGame"; - activeInputLabel = NULL; - showGeneralError = false; - generalErrorToShow = "---"; - currentFactionLogo = ""; - factionTexture = NULL; - currentTechName_factionPreview = ""; - currentFactionName_factionPreview = ""; - mapPreviewTexture = NULL; - hasCheckedForUPNP = false; - needToPublishDelayed = false; - mapPublishingDelayTimer = time (NULL); - headlessHasConnectedPlayer = false; - - lastCheckedCRCTilesetName = ""; - lastCheckedCRCTechtreeName = ""; - lastCheckedCRCMapName = ""; - - last_Forced_CheckedCRCTilesetName = ""; - last_Forced_CheckedCRCTechtreeName = ""; - last_Forced_CheckedCRCMapName = ""; - - lastCheckedCRCTilesetValue = 0; - lastCheckedCRCTechtreeValue = 0; - lastCheckedCRCMapValue = 0; - - publishToMasterserverThread = NULL; - publishToClientsThread = NULL; - - Lang & lang = Lang::getInstance (); - NetworkManager & networkManager = NetworkManager::getInstance (); - Config & config = Config::getInstance (); - defaultPlayerName = - config.getString ("NetPlayerName", Socket::getHostName ().c_str ()); - enableFactionTexturePreview = - config.getBool ("FactionPreview", "true"); - enableMapPreview = config.getBool ("MapPreview", "true"); - - showFullConsole = false; - - enableScenarioTexturePreview = - Config::getInstance ().getBool ("EnableScenarioTexturePreview", - "true"); - scenarioLogoTexture = NULL; - previewLoadDelayTimer = time (NULL); - needToLoadTextures = true; - this->autoloadScenarioName = autoloadScenarioName; - this->dirList = - Config::getInstance ().getPathListForType (ptScenarios); - - mainMessageBox.registerGraphicComponent (containerName, - "mainMessageBox"); - mainMessageBox.init (lang.getString ("Ok"), 500, 300); - mainMessageBox.setEnabled (false); - mainMessageBoxState = 0; - -//initialize network interface - NetworkManager::getInstance ().end (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - serverInitError = false; - try - { - networkManager.init (nrServer, openNetworkSlots); - } - catch (const std::exception & ex) - { - serverInitError = true; - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nNetwork init error:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - showGeneralError = true; - generalErrorToShow = szBuf; - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - needToSetChangedGameSettings = false; - needToRepublishToMasterserver = false; - needToBroadcastServerSettings = false; - lastGameSettingsreceivedCount = -1; - showMasterserverError = false; - tMasterserverErrorElapsed = 0; - masterServererErrorToShow = "---"; - lastSetChangedGameSettings = 0; - lastMasterserverPublishing = 0; - lastNetworkPing = 0; - soundConnectionCount = 0; - - techTree.reset (new TechTree (config.getPathListForType (ptTechs))); - - // Some of these values must also be changed to match those in - // menu_state_connected_game.cpp - int labelOffset = 23; - int setupPos = 605; - // mapHeadPos is the placement of the text "map", not the map itself - int mapHeadPos = 310; - int mapPos = mapHeadPos - labelOffset; - int aHeadPos = mapHeadPos - 90; - int aPos = aHeadPos - labelOffset; - int networkHeadPos = 700; - int networkPos = networkHeadPos - labelOffset; - int xoffset = 10; - -//create - int buttonx = 165; - int buttony = mapHeadPos - 150; - -// player status - listBoxPlayerStatus.registerGraphicComponent (containerName, - "listBoxPlayerStatus"); - listBoxPlayerStatus.init (buttonx, buttony, 165); - vector < string > playerStatuses; - playerStatuses.push_back (lang.getString ("PlayerStatusSetup")); - playerStatuses.push_back (lang.getString ("PlayerStatusBeRightBack")); - playerStatuses.push_back (lang.getString ("PlayerStatusReady")); - listBoxPlayerStatus.setItems (playerStatuses); - listBoxPlayerStatus.setSelectedItemIndex (2, true); - listBoxPlayerStatus.setTextColor (Vec3f (0.0f, 1.0f, 0.0f)); - listBoxPlayerStatus.setLighted (false); - listBoxPlayerStatus.setVisible (true); - buttonx += 180; - - buttonReturn.registerGraphicComponent (containerName, "buttonReturn"); - buttonReturn.init (buttonx, buttony, 125); - buttonx += 132; - - buttonRestoreLastSettings.registerGraphicComponent (containerName, - "buttonRestoreLastSettings"); - buttonRestoreLastSettings.init (buttonx, buttony, 240); - buttonx += 247; - - buttonPlayNow.registerGraphicComponent (containerName, - "buttonPlayNow"); - buttonPlayNow.init (buttonx, buttony, 125); - - labelLocalGameVersion.registerGraphicComponent (containerName, - "labelLocalGameVersion"); - labelLocalGameVersion.init (10, networkHeadPos + labelOffset); - - labelLocalIP.registerGraphicComponent (containerName, "labelLocalIP"); - labelLocalIP.init (360, networkHeadPos + labelOffset); - - string ipText = "none"; - std::vector < std::string > ipList = Socket::getLocalIPAddressList (); - if (ipList.empty () == false) - { - ipText = ""; - for (int idx = 0; idx < (int) ipList.size (); idx++) - { - string ip = ipList[idx]; - if (ipText != "") - { - ipText += ", "; - } - ipText += ip; - } - } - string serverPort = config.getString ("PortServer", - intToStr - (GameConstants:: - serverPort).c_str ()); - string externalPort = - config.getString ("PortExternal", serverPort.c_str ()); - labelLocalIP.setText (lang.getString ("LanIP") + ipText + " ( " + - serverPort + " / " + externalPort + " )"); - ServerSocket::setExternalPort (strToInt (externalPort)); - - if (EndsWith (glestVersionString, "-dev") == false) - { - labelLocalGameVersion.setText (glestVersionString); - } - else - { -//labelLocalGameVersion.setText(glestVersionString + " [" + getCompileDateTime() + ", " + getGITRevisionString() + "]"); - labelLocalGameVersion.setText (glestVersionString); - } - - xoffset = 65; -// MapFilter - labelMapFilter.registerGraphicComponent (containerName, - "labelMapFilter"); - labelMapFilter.init (xoffset + 325, mapHeadPos); - labelMapFilter.setText (lang.getString ("MapFilter")); - - listBoxMapFilter.registerGraphicComponent (containerName, - "listBoxMapFilter"); - listBoxMapFilter.init (xoffset + 325, mapPos, 80); - listBoxMapFilter.pushBackItem ("-"); - for (int i = 1; i < GameConstants::maxPlayers + 1; ++i) - { - listBoxMapFilter.pushBackItem (intToStr (i)); - } - listBoxMapFilter.setSelectedItemIndex (0); - -// Map - labelMap.registerGraphicComponent (containerName, "labelMap"); - labelMap.init (xoffset + 100, mapHeadPos); - labelMap.setText (lang.getString ("Map")); - -//map listBox - listBoxMap.registerGraphicComponent (containerName, "listBoxMap"); - listBoxMap.init (xoffset + 100, mapPos, 220); -// put them all in a set, to weed out duplicates (gbm & mgm with same name) -// will also ensure they are alphabetically listed (rather than how the OS provides them) - int initialMapSelection = setupMapList (""); - listBoxMap.setItems (formattedPlayerSortedMaps[0]); - listBoxMap.setSelectedItemIndex (initialMapSelection); - - labelMapInfo.registerGraphicComponent (containerName, "labelMapInfo"); - labelMapInfo.init (xoffset + 100, mapPos - labelOffset - 10, 200, 40); - - labelTileset.registerGraphicComponent (containerName, "labelTileset"); - labelTileset.init (xoffset + 500, mapHeadPos); - labelTileset.setText (lang.getString ("Tileset")); - -//tileset listBox - listBoxTileset.registerGraphicComponent (containerName, - "listBoxTileset"); - listBoxTileset.init (xoffset + 500, mapPos, 160); - - setupTilesetList (""); - Chrono seed (true); - srand ((unsigned int) seed.getCurTicks ()); - - listBoxTileset.setSelectedItemIndex (rand () % - listBoxTileset.getItemCount ()); - -//tech Tree listBox - int initialTechSelection = setupTechList ("", true); - - listBoxTechTree.registerGraphicComponent (containerName, - "listBoxTechTree"); - listBoxTechTree.init (xoffset + 700, mapPos, 180); - if (listBoxTechTree.getItemCount () > 0) - { - listBoxTechTree.setSelectedItemIndex (initialTechSelection); - } - - labelTechTree.registerGraphicComponent (containerName, - "labelTechTree"); - labelTechTree.init (xoffset + 700, mapHeadPos); - labelTechTree.setText (lang.getString ("TechTree")); - -// fog - o - war -// @350 ? 300 ? - labelFogOfWar.registerGraphicComponent (containerName, - "labelFogOfWar"); - labelFogOfWar.init (xoffset + 100, aHeadPos, 165); - labelFogOfWar.setText (lang.getString ("FogOfWar")); - - listBoxFogOfWar.registerGraphicComponent (containerName, - "listBoxFogOfWar"); - listBoxFogOfWar.init (xoffset + 100, aPos, 165); - listBoxFogOfWar.pushBackItem (lang.getString ("Enabled")); - listBoxFogOfWar.pushBackItem (lang.getString ("Explored")); - listBoxFogOfWar.pushBackItem (lang.getString ("Disabled")); - listBoxFogOfWar.setSelectedItemIndex (0); - -// Allow Observers - labelAllowObservers.registerGraphicComponent (containerName, - "labelAllowObservers"); - labelAllowObservers.init (xoffset + 325, aHeadPos, 80); - labelAllowObservers.setText (lang.getString ("AllowObservers")); - - checkBoxAllowObservers.registerGraphicComponent (containerName, - "checkBoxAllowObservers"); - checkBoxAllowObservers.init (xoffset + 325, aPos); - checkBoxAllowObservers.setValue (checkBoxAllowObservers.getValue ()); - - vector < string > rMultiplier; - for (int i = 0; i < 45; ++i) - { - rMultiplier.push_back (floatToStr (0.5f + 0.1f * i, 1)); - } - - labelFallbackCpuMultiplier.registerGraphicComponent (containerName, - "labelFallbackCpuMultiplier"); - labelFallbackCpuMultiplier.init (xoffset + 500, aHeadPos, 80); - labelFallbackCpuMultiplier.setText (lang.getString - ("FallbackCpuMultiplier")); - - listBoxFallbackCpuMultiplier.registerGraphicComponent (containerName, - "listBoxFallbackCpuMultiplier"); - listBoxFallbackCpuMultiplier.init (xoffset + 500, aPos, 80); - listBoxFallbackCpuMultiplier.setItems (rMultiplier); - listBoxFallbackCpuMultiplier.setSelectedItem ("1.0"); - -// Allow Switch Team Mode - labelEnableSwitchTeamMode.registerGraphicComponent (containerName, - "labelEnableSwitchTeamMode"); - labelEnableSwitchTeamMode.init (xoffset + 325, aHeadPos + 45, 80); - labelEnableSwitchTeamMode.setText (lang.getString - ("EnableSwitchTeamMode")); - - checkBoxEnableSwitchTeamMode.registerGraphicComponent (containerName, - "checkBoxEnableSwitchTeamMode"); - checkBoxEnableSwitchTeamMode.init (xoffset + 325, aPos + 45); - checkBoxEnableSwitchTeamMode.setValue (false); - - labelAISwitchTeamAcceptPercent.registerGraphicComponent - (containerName, "labelAISwitchTeamAcceptPercent"); - labelAISwitchTeamAcceptPercent.init (xoffset + 500, aHeadPos + 45, - 80); - labelAISwitchTeamAcceptPercent.setText (lang.getString - ("AISwitchTeamAcceptPercent")); - - listBoxAISwitchTeamAcceptPercent.registerGraphicComponent - (containerName, "listBoxAISwitchTeamAcceptPercent"); - listBoxAISwitchTeamAcceptPercent.init (xoffset + 500, aPos + 45, 80); - for (int i = 0; i <= 100; i = i + 10) - { - listBoxAISwitchTeamAcceptPercent.pushBackItem (intToStr (i)); - } - listBoxAISwitchTeamAcceptPercent.setSelectedItem (intToStr (30)); - - labelAllowNativeLanguageTechtree.registerGraphicComponent - (containerName, "labelAllowNativeLanguageTechtree"); - labelAllowNativeLanguageTechtree.init (xoffset + 700, aHeadPos + 45); - labelAllowNativeLanguageTechtree.setText (lang.getString - ("AllowNativeLanguageTechtree")); - - checkBoxAllowNativeLanguageTechtree.registerGraphicComponent - (containerName, "checkBoxAllowNativeLanguageTechtree"); - checkBoxAllowNativeLanguageTechtree.init (xoffset + 700, aPos + 45); - checkBoxAllowNativeLanguageTechtree.setValue (false); - -// Network Scenario - int scenarioX = xoffset + 700; - int scenarioY = aPos; - labelScenario.registerGraphicComponent (containerName, - "labelScenario"); - labelScenario.init (scenarioX, aHeadPos); - labelScenario.setText (lang.getString ("Scenario")); - listBoxScenario.registerGraphicComponent (containerName, - "listBoxScenario"); - listBoxScenario.init (scenarioX + 30, scenarioY, 190); - checkBoxScenario.registerGraphicComponent (containerName, - "checkBoxScenario"); - checkBoxScenario.init (scenarioX, scenarioY); - checkBoxScenario.setValue (false); - -//scenario listbox - vector < string > resultsScenarios; - findDirs (dirList, resultsScenarios); -// Filter out only scenarios with no network slots - for (int i = 0; i < (int) resultsScenarios.size (); ++i) - { - string scenario = resultsScenarios[i]; - string file = Scenario::getScenarioPath (dirList, scenario); - - try - { - if (file != "") - { - bool isTutorial = Scenario::isGameTutorial (file); - Scenario::loadScenarioInfo (file, &scenarioInfo, isTutorial); - - bool isNetworkScenario = false; - for (unsigned int j = 0; - isNetworkScenario == false - && j < (unsigned int) GameConstants::maxPlayers; ++j) - { - if (scenarioInfo.factionControls[j] == ctNetwork) - { - isNetworkScenario = true; - } - } - if (isNetworkScenario == true) - { - scenarioFiles.push_back (scenario); - } - } - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s %d]\nError loading scenario [%s]:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, scenario.c_str (), ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", - szBuf); - - showGeneralError = true; - generalErrorToShow = szBuf; -//throw megaglest_runtime_error(szBuf); - } - } - resultsScenarios.clear (); - for (int i = 0; i < (int) scenarioFiles.size (); ++i) - { - resultsScenarios.push_back (formatString (scenarioFiles[i])); - } - listBoxScenario.setItems (resultsScenarios); - if (resultsScenarios.empty () == true) - { - checkBoxScenario.setEnabled (false); - } -// Advanced Options - labelAdvanced.registerGraphicComponent (containerName, - "labelAdvanced"); - labelAdvanced.init (scenarioX, 80, 80); - labelAdvanced.setText (lang.getString ("AdvancedGameOptions")); - - checkBoxAdvanced.registerGraphicComponent (containerName, - "checkBoxAdvanced"); - checkBoxAdvanced.init (scenarioX, 80 - labelOffset); - checkBoxAdvanced.setValue (false); - -// network things -// PublishServer - xoffset = 90; - - labelPublishServer.registerGraphicComponent (containerName, - "labelPublishServer"); - labelPublishServer.init (20, networkHeadPos, 100); - labelPublishServer.setText (lang.getString ("PublishServer")); - - checkBoxPublishServer.registerGraphicComponent (containerName, - "checkBoxPublishServer"); - checkBoxPublishServer.init (20, networkPos); - - checkBoxPublishServer.setValue (false); - if ((this->headlessServerMode == true || - (openNetworkSlots == true && parentMenuState != pLanGame)) && - GlobalStaticFlags::isFlagSet (gsft_lan_mode) == false) - { - checkBoxPublishServer.setValue (true); - } - - labelGameName.registerGraphicComponent (containerName, - "labelGameName"); - labelGameName.init (20 + checkBoxPublishServer.getW () + 5, - networkPos, 200); - labelGameName.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelGameName. - setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - labelGameName.setText (createGameName ()); - labelGameName.setEditable (true); - labelGameName.setMaxEditWidth (20); - labelGameName.setMaxEditRenderWidth (200); - - - bool allowInProgressJoin = - Config::getInstance ().getBool ("EnableJoinInProgressGame", "true"); - labelAllowInGameJoinPlayer.registerGraphicComponent (containerName, - "labelAllowInGameJoinPlayer"); - labelAllowInGameJoinPlayer.init (50, networkPos - 30, 80); - labelAllowInGameJoinPlayer.setText (lang.getString - ("AllowInGameJoinPlayer")); - labelAllowInGameJoinPlayer.setVisible (allowInProgressJoin); - - checkBoxAllowInGameJoinPlayer.registerGraphicComponent (containerName, - "checkBoxAllowInGameJoinPlayer"); - checkBoxAllowInGameJoinPlayer.init (20, networkPos - 30); - checkBoxAllowInGameJoinPlayer.setValue (false); - checkBoxAllowInGameJoinPlayer.setVisible (allowInProgressJoin); - - - labelAllowTeamUnitSharing.registerGraphicComponent (containerName, - "labelAllowTeamUnitSharing"); - labelAllowTeamUnitSharing.init (xoffset + 410, 670, 80); - labelAllowTeamUnitSharing.setText (lang.getString - ("AllowTeamUnitSharing")); - labelAllowTeamUnitSharing.setVisible (true); - - checkBoxAllowTeamUnitSharing.registerGraphicComponent (containerName, - "checkBoxAllowTeamUnitSharing"); - checkBoxAllowTeamUnitSharing.init (xoffset + 612, 670); - checkBoxAllowTeamUnitSharing.setValue (false); - checkBoxAllowTeamUnitSharing.setVisible (true); - - labelAllowTeamResourceSharing.registerGraphicComponent (containerName, - "labelAllowTeamResourceSharing"); - labelAllowTeamResourceSharing.init (xoffset + 410, 640, 80); - labelAllowTeamResourceSharing.setText (lang.getString - ("AllowTeamResourceSharing")); - labelAllowTeamResourceSharing.setVisible (true); - - checkBoxAllowTeamResourceSharing.registerGraphicComponent - (containerName, "checkBoxAllowTeamResourceSharing"); - checkBoxAllowTeamResourceSharing.init (xoffset + 612, 640); - checkBoxAllowTeamResourceSharing.setValue (false); - checkBoxAllowTeamResourceSharing.setVisible (true); - - -// Network Pause for lagged clients - labelNetworkPauseGameForLaggedClients.registerGraphicComponent - (containerName, "labelNetworkPauseGameForLaggedClients"); - labelNetworkPauseGameForLaggedClients.init - (labelAllowTeamResourceSharing.getX (), networkHeadPos, 80); - labelNetworkPauseGameForLaggedClients.setText (lang.getString - ("NetworkPauseGameForLaggedClients")); - - checkBoxNetworkPauseGameForLaggedClients.registerGraphicComponent - (containerName, "checkBoxNetworkPauseGameForLaggedClients"); - checkBoxNetworkPauseGameForLaggedClients.init - (checkBoxAllowTeamResourceSharing.getX (), networkHeadPos); - checkBoxNetworkPauseGameForLaggedClients.setValue (true); - - //list boxes - xoffset = 5; - int rowHeight = 27; - - buttonClearBlockedPlayers.registerGraphicComponent (containerName, - "buttonClearBlockedPlayers"); - buttonClearBlockedPlayers.init (xoffset + 800, - setupPos - 30, - 134 + 2 + 50); - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - - labelPlayers[i].registerGraphicComponent (containerName, - "labelPlayers" + - intToStr (i)); - labelPlayers[i].init (xoffset - 1, - setupPos - 30 - i * rowHeight + 2); - labelPlayers[i]. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - labelPlayers[i]. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - - labelPlayerStatus[i].registerGraphicComponent (containerName, - "labelPlayerStatus" - + intToStr (i)); - labelPlayerStatus[i].init (xoffset + 14, - setupPos - 30 - i * rowHeight + 2); - labelPlayerNames[i].registerGraphicComponent (containerName, - "labelPlayerNames" + - intToStr (i)); - labelPlayerNames[i].init (xoffset + 30, - setupPos - 30 - i * rowHeight); - - listBoxControls[i].registerGraphicComponent (containerName, - "listBoxControls" + - intToStr (i)); - listBoxControls[i].init (xoffset + 160, - setupPos - 30 - i * rowHeight, 174); - - buttonBlockPlayers[i].registerGraphicComponent (containerName, - "buttonBlockPlayers" - + intToStr (i)); -//buttonBlockPlayers[i].init(xoffset+355, setupPos-30-i*rowHeight, 70); - buttonBlockPlayers[i].init (xoffset + 185, - setupPos - 30 - i * rowHeight, 124); - buttonBlockPlayers[i].setText (lang.getString ("BlockPlayer")); - buttonBlockPlayers[i]. - setFont (CoreData::getInstance ().getDisplayFontSmall ()); - buttonBlockPlayers[i]. - setFont3D (CoreData::getInstance ().getDisplayFontSmall3D ()); - - listBoxRMultiplier[i].registerGraphicComponent (containerName, - "listBoxRMultiplier" - + intToStr (i)); - listBoxRMultiplier[i].init (xoffset + 336, - setupPos - 30 - i * rowHeight, 70); - - listBoxFactions[i].registerGraphicComponent (containerName, - "listBoxFactions" + - intToStr (i)); - listBoxFactions[i].init (xoffset + 411, - setupPos - 30 - i * rowHeight, 247); - listBoxFactions[i].setLeftControlled (true); - - listBoxTeams[i].registerGraphicComponent (containerName, - "listBoxTeams" + - intToStr (i)); - listBoxTeams[i].init (xoffset + 660, - setupPos - 30 - i * rowHeight, 60); - listBoxTeams[i].setLighted (true); - - labelNetStatus[i].registerGraphicComponent (containerName, - "labelNetStatus" + - intToStr (i)); - labelNetStatus[i].init (xoffset + 726, - setupPos - 30 - i * rowHeight, 60); - labelNetStatus[i]. - setFont (CoreData::getInstance ().getDisplayFontSmall ()); - labelNetStatus[i]. - setFont3D (CoreData::getInstance ().getDisplayFontSmall3D ()); - } - - labelControl.registerGraphicComponent (containerName, "labelControl"); - labelControl.init (xoffset + 160, setupPos, 50, GraphicListBox::defH, - true); - labelControl.setText (lang.getString ("Control")); - - labelRMultiplier.registerGraphicComponent (containerName, - "labelRMultiplier"); - labelRMultiplier.init (xoffset + 310, setupPos, 50, - GraphicListBox::defH, true); - - labelFaction.registerGraphicComponent (containerName, "labelFaction"); - labelFaction.init (xoffset + 411, setupPos, 50, GraphicListBox::defH, - true); - labelFaction.setText (lang.getString ("Faction")); - - labelTeam.registerGraphicComponent (containerName, "labelTeam"); - labelTeam.init (xoffset + 660, setupPos, 50, GraphicListBox::defH, - true); - labelTeam.setText (lang.getString ("Team")); - - labelControl.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelControl.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - labelRMultiplier.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelRMultiplier. - setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - labelFaction.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelFaction.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - labelTeam.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelTeam.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - -//xoffset=100; - -//texts - buttonClearBlockedPlayers. - setText (lang.getString ("BlockPlayerClear")); - buttonReturn.setText (lang.getString ("Return")); - buttonPlayNow.setText (lang.getString ("PlayNow")); - buttonRestoreLastSettings.setText (lang.getString - ("ReloadLastGameSettings")); - - vector < string > controlItems; - controlItems.push_back (lang.getString ("Closed")); - controlItems.push_back (lang.getString ("CpuEasy")); - controlItems.push_back (lang.getString ("Cpu")); - controlItems.push_back (lang.getString ("CpuUltra")); - controlItems.push_back (lang.getString ("CpuZeta")); - controlItems.push_back (lang.getString ("Network")); - controlItems.push_back (lang.getString ("NetworkUnassigned")); - controlItems.push_back (lang.getString ("Human")); - - if (config.getBool ("EnableNetworkCpu", "false") == true) - { - controlItems.push_back (lang.getString ("NetworkCpuEasy")); - controlItems.push_back (lang.getString ("NetworkCpu")); - controlItems.push_back (lang.getString ("NetworkCpuUltra")); - controlItems.push_back (lang.getString ("NetworkCpuZeta")); - } - - vector < string > teamItems; - for (int i = 1; i <= GameConstants::maxPlayers; ++i) - { - teamItems.push_back (intToStr (i)); - } - for (int i = GameConstants::maxPlayers + 1; - i <= GameConstants::maxPlayers + GameConstants::specialFactions; - ++i) - { - teamItems.push_back (intToStr (i)); - } - - reloadFactions (false, ""); - - if (factionFiles.empty () == true) - { - showGeneralError = true; - generalErrorToShow = - "[#1] There are no factions for the tech tree [" + - techTreeFiles[listBoxTechTree.getSelectedItemIndex ()] + "]"; - } - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - labelPlayerStatus[i].setText (" "); - labelPlayerStatus[i]. - setTexture (CoreData::getInstance ().getStatusReadyTexture ()); - labelPlayerStatus[i].setH (16); - labelPlayerStatus[i].setW (12); - -//labelPlayers[i].setText(lang.getString("Player")+" "+intToStr(i)); - labelPlayers[i].setText (intToStr (i + 1)); - labelPlayerNames[i].setText ("*"); - labelPlayerNames[i].setMaxEditWidth (16); - labelPlayerNames[i].setMaxEditRenderWidth (127); - - listBoxTeams[i].setItems (teamItems); - listBoxTeams[i].setSelectedItemIndex (i); - lastSelectedTeamIndex[i] = listBoxTeams[i].getSelectedItemIndex (); - - listBoxControls[i].setItems (controlItems); - listBoxRMultiplier[i].setItems (rMultiplier); - listBoxRMultiplier[i].setSelectedItem ("1.0"); - labelNetStatus[i].setText (""); - } - - // I moved this block from loadMapInfo(), and modified it. It was - // setting the slots visible based on the number of hardMaxPlayers - // every time a new map was loaded. Trying it here instead, so the - // labels are made visible only once. Below, we'll be disabling slots - // that exceed hardMaxPlayers - for (int i = 0; i < GameConstants::maxPlayers; i++) - { - labelPlayers[i].setVisible (true); - labelPlayerNames[i].setVisible (true); - listBoxControls[i].setVisible (true); - listBoxFactions[i].setVisible (true); - listBoxTeams[i].setVisible (true); - labelNetStatus[i].setVisible (true); - } - - loadMapInfo (Config::getMapPath (getCurrentMapFile ()), &mapInfo, - true); - labelMapInfo.setText (mapInfo.desc); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//init controllers - if (serverInitError == false) - { - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - if (serverInterface == NULL) - { - throw megaglest_runtime_error ("serverInterface == NULL"); - } - if (this->headlessServerMode == true) - { - listBoxControls[0].setSelectedItemIndex (ctNetwork); - updateResourceMultiplier (0); - } - else - { - setSlotHuman (0); - updateResourceMultiplier (0); - } - labelPlayerNames[0].setText (""); - labelPlayerNames[0].setText (getHumanPlayerName ()); - - if (openNetworkSlots == true) - { - for (int i = 1; i < mapInfo.players; ++i) - { - listBoxControls[i].setSelectedItemIndex (ctNetwork); - } - } - else - { - listBoxControls[1].setSelectedItemIndex (ctCpu); - } - updateControllers (); - updateNetworkSlots (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - -// Ensure we have set the gamesettings at least once - GameSettings gameSettings; - loadGameSettings (&gameSettings); - - serverInterface->setGameSettings (&gameSettings, false); - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - updateAllResourceMultiplier (); - -// write hint to console: - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - - console.addLine (lang.getString ("ToSwitchOffMusicPress") + " - \"" + - configKeys.getString ("ToggleMusic") + "\""); - - chatManager.init (&console, -1, true); - - GraphicComponent::applyAllCustomProperties (containerName); - - static string mutexOwnerId = - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - string ("_") + intToStr (__LINE__); - publishToMasterserverThread = - new SimpleTaskThread (this, 0, 300, false, - (void *) tnt_MASTERSERVER); - publishToMasterserverThread->setUniqueID (mutexOwnerId); - - static string mutexOwnerId2 = - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - string ("_") + intToStr (__LINE__); - publishToClientsThread = - new SimpleTaskThread (this, 0, 200, false, (void *) tnt_CLIENTS, - false); - publishToClientsThread->setUniqueID (mutexOwnerId2); - - publishToMasterserverThread->start (); - publishToClientsThread->start (); - - if (openNetworkSlots == true) - { - string data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - - if (fileExists (data_path + DEFAULT_NETWORKGAME_FILENAME) == true) - loadGameSettings (data_path + DEFAULT_NETWORKGAME_FILENAME); - } - else - { - string data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - - if (fileExists (data_path + DEFAULT_GAME_FILENAME) == true) - loadGameSettings (data_path + DEFAULT_GAME_FILENAME); - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - throw megaglest_runtime_error (szBuf); - } - } - - string MenuStateCustomGame::createGameName (string controllingPlayer) - { - Config & config = Config::getInstance (); - string serverTitle = config.getString ("ServerTitle", ""); - - if (serverTitle != "" && controllingPlayer == "") - { - return serverTitle; - } - else if (this->headlessServerMode == true) - { - if (controllingPlayer != "") - { - return controllingPlayer + " controls"; - } - else - { - return "[H] " + defaultPlayerName; - } - } - else - { - string defaultPlayerNameEnd = - defaultPlayerName.substr (defaultPlayerName.size () - 1, 1); - if (defaultPlayerNameEnd == "s") - { - return defaultPlayerName + "' game"; - } - else - { - return defaultPlayerName + "'s game"; - } - } - } - - void MenuStateCustomGame::reloadUI () - { - Lang & lang = Lang::getInstance (); - Config & config = Config::getInstance (); - - console.resetFonts (); - mainMessageBox.init (lang.getString ("Ok"), 500, 300); - - - if (EndsWith (glestVersionString, "-dev") == false) - { - labelLocalGameVersion.setText (glestVersionString); - } - else - { -//labelLocalGameVersion.setText(glestVersionString + " [" + getCompileDateTime() + ", " + getGITRevisionString() + "]"); - labelLocalGameVersion.setText (glestVersionString); - } - -//vector teamItems, controlItems, results , rMultiplier; - - string ipText = "none"; - std::vector < std::string > ipList = Socket::getLocalIPAddressList (); - if (ipList.empty () == false) - { - ipText = ""; - for (int idx = 0; idx < (int) ipList.size (); idx++) - { - string ip = ipList[idx]; - if (ipText != "") - { - ipText += ", "; - } - ipText += ip; - } - } - string serverPort = config.getString ("PortServer", - intToStr - (GameConstants:: - serverPort).c_str ()); - string externalPort = - config.getString ("PortExternal", serverPort.c_str ()); - - labelLocalIP.setText (lang.getString ("LanIP") + ipText + " ( " + - serverPort + " / " + externalPort + " )"); - - labelMap.setText (lang.getString ("Map")); - - labelMapFilter.setText (lang.getString ("MapFilter")); - - labelTileset.setText (lang.getString ("Tileset")); - - labelTechTree.setText (lang.getString ("TechTree")); - - labelAllowNativeLanguageTechtree.setText (lang.getString - ("AllowNativeLanguageTechtree")); - - labelFogOfWar.setText (lang.getString ("FogOfWar")); - - std::vector < std::string > listBoxData; - listBoxData.push_back (lang.getString ("Enabled")); - listBoxData.push_back (lang.getString ("Explored")); - listBoxData.push_back (lang.getString ("Disabled")); - listBoxFogOfWar.setItems (listBoxData); - -// Allow Observers - labelAllowObservers.setText (lang.getString ("AllowObservers")); - -// Allow Switch Team Mode - labelEnableSwitchTeamMode. - setText (lang.getString ("EnableSwitchTeamMode")); - - labelAllowInGameJoinPlayer.setText (lang.getString - ("AllowInGameJoinPlayer")); - - labelAllowTeamUnitSharing. - setText (lang.getString ("AllowTeamUnitSharing")); - labelAllowTeamResourceSharing. - setText (lang.getString ("AllowTeamResourceSharing")); - - labelAISwitchTeamAcceptPercent.setText (lang.getString - ("AISwitchTeamAcceptPercent")); - - listBoxData.clear (); - -// Advanced Options - labelAdvanced.setText (lang.getString ("AdvancedGameOptions")); - - labelPublishServer.setText (lang.getString ("PublishServer")); - - labelGameName.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelGameName.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - - labelGameName.setText (createGameName ()); - - labelNetworkPauseGameForLaggedClients.setText (lang.getString - ("NetworkPauseGameForLaggedClients")); - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - buttonBlockPlayers[i].setText (lang.getString ("BlockPlayer")); - } - - labelControl.setText (lang.getString ("Control")); - - labelFaction.setText (lang.getString ("Faction")); - - labelTeam.setText (lang.getString ("Team")); - - labelControl.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelControl.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - labelRMultiplier.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelRMultiplier. - setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - labelFaction.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelFaction.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - labelTeam.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelTeam.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - -//texts - buttonClearBlockedPlayers.setText (lang.getString ("BlockPlayerClear")); - buttonReturn.setText (lang.getString ("Return")); - buttonPlayNow.setText (lang.getString ("PlayNow")); - buttonRestoreLastSettings.setText (lang.getString - ("ReloadLastGameSettings")); - - vector < string > controlItems; - controlItems.push_back (lang.getString ("Closed")); - controlItems.push_back (lang.getString ("CpuEasy")); - controlItems.push_back (lang.getString ("Cpu")); - controlItems.push_back (lang.getString ("CpuUltra")); - controlItems.push_back (lang.getString ("CpuZeta")); - controlItems.push_back (lang.getString ("Network")); - controlItems.push_back (lang.getString ("NetworkUnassigned")); - controlItems.push_back (lang.getString ("Human")); - - if (config.getBool ("EnableNetworkCpu", "false") == true) - { - controlItems.push_back (lang.getString ("NetworkCpuEasy")); - controlItems.push_back (lang.getString ("NetworkCpu")); - controlItems.push_back (lang.getString ("NetworkCpuUltra")); - controlItems.push_back (lang.getString ("NetworkCpuZeta")); - } - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - labelPlayers[i].setText (intToStr (i + 1)); - - listBoxControls[i].setItems (controlItems); - } - - labelFallbackCpuMultiplier.setText (lang.getString - ("FallbackCpuMultiplier")); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - vector < string > playerStatuses; - playerStatuses.push_back (lang.getString ("PlayerStatusSetup")); - playerStatuses.push_back (lang.getString ("PlayerStatusBeRightBack")); - playerStatuses.push_back (lang.getString ("PlayerStatusReady")); - listBoxPlayerStatus.setItems (playerStatuses); - - labelScenario.setText (lang.getString ("Scenario")); - - reloadFactions (true, - (checkBoxScenario.getValue () == - true ? - scenarioFiles[listBoxScenario.getSelectedItemIndex ()] - : "")); - -// write hint to console: - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - - console.addLine (lang.getString ("ToSwitchOffMusicPress") + " - \"" + - configKeys.getString ("ToggleMusic") + "\""); - - chatManager.init (&console, -1, true); - - GraphicComponent::reloadFontsForRegisterGraphicComponents - (containerName); - } - - void MenuStateCustomGame::cleanupThread (SimpleTaskThread ** thread) - { -//printf("LINE: %d *thread = %p\n",__LINE__,*thread); - - if (thread != NULL && *thread != NULL) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\n\n#1 cleanupThread callingThread [%p]\n", *thread); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - SimpleTaskThread *threadPtr = *thread; - int value = threadPtr->getUserdataAsInt (); - THREAD_NOTIFIER_TYPE threadType = (THREAD_NOTIFIER_TYPE) value; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\n\n#1. cleanupThread callingThread [%p] value = %d\n", - *thread, value); - - needToBroadcastServerSettings = false; - needToRepublishToMasterserver = false; - lastNetworkPing = time (NULL); - threadPtr->setThreadOwnerValid (false); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\n\n#1.. cleanupThread callingThread [%p] value = %d\n", - *thread, value); - - if (forceWaitForShutdown == true) - { - time_t elapsed = time (NULL); - threadPtr->signalQuit (); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\n\n#1a cleanupThread callingThread [%p]\n", *thread); - - for (; (threadPtr->canShutdown (false) == false || - threadPtr->getRunningStatus () == true) && - difftime ((long int) time (NULL), elapsed) <= 15;) - { -//sleep(150); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\n\n#1b cleanupThread callingThread [%p]\n", *thread); - - if (threadPtr->canShutdown (true) == true && - threadPtr->getRunningStatus () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\n\n#1c cleanupThread callingThread [%p]\n", *thread); - - delete threadPtr; -//printf("LINE: %d *thread = %p\n",__LINE__,*thread); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - } - else - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\n\n#1d cleanupThread callingThread [%p]\n", *thread); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s %d] Error cannot shutdown thread\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); -//SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("%s", szBuf); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", - szBuf); - - if (threadType == tnt_MASTERSERVER) - { - threadPtr->setOverrideShutdownTask (shutdownTaskStatic); - } - threadPtr->setDeleteSelfOnExecutionDone (true); - threadPtr->setDeleteAfterExecute (true); -//printf("LINE: %d *thread = %p\n",__LINE__,*thread); - } - threadPtr = NULL; -//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1e cleanupThread callingThread [%p]\n",*thread); - } - else - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\n\n#1f cleanupThread callingThread [%p]\n", *thread); - threadPtr->signalQuit (); - sleep (0); - if (threadPtr->canShutdown (true) == true && - threadPtr->getRunningStatus () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\n\n#1g cleanupThread callingThread [%p]\n", *thread); - delete threadPtr; -//printf("LINE: %d *thread = %p\n",__LINE__,*thread); - } - else - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\n\n#1h cleanupThread callingThread [%p]\n", *thread); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s %d] Error cannot shutdown thread\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); -//SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("%s", szBuf); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", - szBuf); - - if (threadType == tnt_MASTERSERVER) - { - threadPtr->setOverrideShutdownTask (shutdownTaskStatic); - } - threadPtr->setDeleteSelfOnExecutionDone (true); - threadPtr->setDeleteAfterExecute (true); -//printf("LINE: %d *thread = %p\n",__LINE__,*thread); - } - } - - *thread = NULL; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\n\n#2 cleanupThread callingThread [%p]\n", *thread); - } -//printf("LINE: %d *thread = %p\n",__LINE__,*thread); - } - - void MenuStateCustomGame::cleanup () - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (publishToMasterserverThread) - { -//printf("LINE: %d\n",__LINE__); - cleanupThread (&publishToMasterserverThread); - } - if (publishToClientsThread) - { -//printf("LINE: %d\n",__LINE__); - cleanupThread (&publishToClientsThread); - } - -//printf("LINE: %d\n",__LINE__); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - cleanupMapPreviewTexture (); - - if (factionVideo != NULL) - { - factionVideo->closePlayer (); - delete factionVideo; - factionVideo = NULL; - } - - if (forceWaitForShutdown == true) - { - NetworkManager::getInstance ().end (); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - MenuStateCustomGame::~MenuStateCustomGame () - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - - cleanup (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - } - - void MenuStateCustomGame::returnToParentMenu () - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - needToBroadcastServerSettings = false; - needToRepublishToMasterserver = false; - lastNetworkPing = time (NULL); - ParentMenuState parentMenuState = this->parentMenuState; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - forceWaitForShutdown = false; - if (parentMenuState == pMasterServer) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - cleanup (); - mainMenu->setState (new MenuStateMasterserver (program, mainMenu)); - } - else if (parentMenuState == pLanGame) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - cleanup (); - mainMenu->setState (new MenuStateJoinGame (program, mainMenu)); - } - else - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - cleanup (); - mainMenu->setState (new MenuStateNewGame (program, mainMenu)); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - void MenuStateCustomGame::mouseClick (int x, int y, - MouseButton mouseButton) - { - if (isMasterserverMode () == true) - { - return; - } - - try - { - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - int oldListBoxMapfilterIndex = - listBoxMapFilter.getSelectedItemIndex (); - - if (mainMessageBox.getEnabled ()) - { - int button = 0; - if (mainMessageBox.mouseClick (x, y, button)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - if (button == 0) - { - mainMessageBox.setEnabled (false); - } - } - } - else - { - string advanceToItemStartingWith = ""; - if (::Shared::Platform::Window::isKeyStateModPressed (KMOD_SHIFT) == - true) - { - const wchar_t lastKey =::Shared::Platform:: - Window::extractLastKeyPressed (); -// string helpString = ""; -// helpString = lastKey; -// printf("lastKey = '%s'\n",helpString.c_str()); - advanceToItemStartingWith = lastKey; - } - - if (mapPreviewTexture != NULL) - { -// printf("X: %d Y: %d [%d, %d, %d, %d]\n", -// x, y, -// this->render_mapPreviewTexture_X, this->render_mapPreviewTexture_X + this->render_mapPreviewTexture_W, -// this->render_mapPreviewTexture_Y, this->render_mapPreviewTexture_Y + this->render_mapPreviewTexture_H); - - if (x >= this->render_mapPreviewTexture_X - && x <= - this->render_mapPreviewTexture_X + - this->render_mapPreviewTexture_W - && y >= this->render_mapPreviewTexture_Y - && y <= - this->render_mapPreviewTexture_Y + - this->render_mapPreviewTexture_H) - { - - if (this->render_mapPreviewTexture_X == - mapPreviewTexture_X - && this->render_mapPreviewTexture_Y == - mapPreviewTexture_Y - && this->render_mapPreviewTexture_W == - mapPreviewTexture_W - && this->render_mapPreviewTexture_H == mapPreviewTexture_H) - { - - const Metrics & metrics = Metrics::getInstance (); - - this->render_mapPreviewTexture_X = 0; - this->render_mapPreviewTexture_Y = 0; - this->render_mapPreviewTexture_W = metrics.getVirtualW (); - this->render_mapPreviewTexture_H = metrics.getVirtualH (); - this->zoomedMap = true; - - cleanupMapPreviewTexture (); - } - else - { - this->render_mapPreviewTexture_X = mapPreviewTexture_X; - this->render_mapPreviewTexture_Y = mapPreviewTexture_Y; - this->render_mapPreviewTexture_W = mapPreviewTexture_W; - this->render_mapPreviewTexture_H = mapPreviewTexture_H; - this->zoomedMap = false; - - cleanupMapPreviewTexture (); - } - return; - } - if (this->zoomedMap == true) - { - return; - } - } - - if (activeInputLabel != NULL - && !(activeInputLabel->mouseClick (x, y))) - { - setActiveInputLabel (NULL); - } - if (buttonReturn.mouseClick (x, y) || serverInitError == true) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - soundRenderer.playFx (coreData.getClickSoundA ()); - - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - needToBroadcastServerSettings = false; - needToRepublishToMasterserver = false; - lastNetworkPing = time (NULL); - safeMutex.ReleaseLock (); - safeMutexCLI.ReleaseLock (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - returnToParentMenu (); - return; - } - else if (buttonPlayNow.mouseClick (x, y) - && buttonPlayNow.getEnabled ()) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - PlayNow (true); - return; - } - else if (buttonRestoreLastSettings.mouseClick (x, y) - && buttonRestoreLastSettings.getEnabled ()) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - - RestoreLastGameSettings (); - } - else if (listBoxMap.mouseClick (x, y, advanceToItemStartingWith)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", - getCurrentMapFile ().c_str ()); - - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - loadMapInfo (Config::getMapPath (getCurrentMapFile (), "", false), - &mapInfo, true); - labelMapInfo.setText (mapInfo.desc); - updateControllers (); - updateNetworkSlots (); - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { -//delay publishing for 5 seconds - needToPublishDelayed = true; - mapPublishingDelayTimer = time (NULL); - } - } - else if (checkBoxAdvanced.getValue () == 1 - && listBoxFogOfWar.mouseClick (x, y)) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - cleanupMapPreviewTexture (); - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - else if (checkBoxAdvanced.getValue () == 1 - && checkBoxAllowObservers.mouseClick (x, y)) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - reloadFactions (true, - (checkBoxScenario.getValue () == - true ? - scenarioFiles - [listBoxScenario.getSelectedItemIndex ()] : "")); - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - else if (checkBoxAllowInGameJoinPlayer.mouseClick (x, y)) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - serverInterface->setAllowInGameConnections - (checkBoxAllowInGameJoinPlayer.getValue () == true); - } - else if (checkBoxAdvanced.getValue () == 1 - && checkBoxAllowTeamUnitSharing.mouseClick (x, y)) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - else if (checkBoxAdvanced.getValue () == 1 - && checkBoxAllowTeamResourceSharing.mouseClick (x, y)) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - else if (checkBoxAllowNativeLanguageTechtree.mouseClick (x, y)) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - else if (checkBoxAdvanced.getValue () == 1 - && checkBoxEnableSwitchTeamMode.mouseClick (x, y)) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - else if (checkBoxAdvanced.getValue () == 1 - && listBoxAISwitchTeamAcceptPercent.getEnabled () - && listBoxAISwitchTeamAcceptPercent.mouseClick (x, y)) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - else if (checkBoxAdvanced.getValue () == 1 - && listBoxFallbackCpuMultiplier.getEditable () == true - && listBoxFallbackCpuMultiplier.mouseClick (x, y)) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - else if (checkBoxAdvanced.mouseClick (x, y)) - { - } - else - if (listBoxTileset.mouseClick (x, y, advanceToItemStartingWith)) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - if (hasNetworkGameSettings () == true) - { - -//delay publishing for 5 seconds - needToPublishDelayed = true; - mapPublishingDelayTimer = time (NULL); - } - } - else if (listBoxMapFilter.mouseClick (x, y)) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - switchToNextMapGroup (listBoxMapFilter.getSelectedItemIndex () - - oldListBoxMapfilterIndex); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s\n", - getCurrentMapFile ().c_str ()); - - loadMapInfo (Config::getMapPath (getCurrentMapFile ()), - &mapInfo, true); - labelMapInfo.setText (mapInfo.desc); - updateControllers (); - updateNetworkSlots (); - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - else - if (listBoxTechTree.mouseClick (x, y, advanceToItemStartingWith)) - { - reloadFactions (listBoxTechTree.getItemCount () <= 1, - (checkBoxScenario.getValue () == - true ? - scenarioFiles - [listBoxScenario.getSelectedItemIndex ()] : "")); - - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - else if (checkBoxPublishServer.mouseClick (x, y) - && checkBoxPublishServer.getEditable ()) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - needToRepublishToMasterserver = true; - soundRenderer.playFx (coreData.getClickSoundC ()); - - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - serverInterface-> - setPublishEnabled (checkBoxPublishServer.getValue () == true); - } - else if (labelGameName.mouseClick (x, y) - && checkBoxPublishServer.getEditable ()) - { - setActiveInputLabel (&labelGameName); - } - else if (checkBoxAdvanced.getValue () == 1 - && checkBoxNetworkPauseGameForLaggedClients.mouseClick (x, - y)) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - - soundRenderer.playFx (coreData.getClickSoundC ()); - } - else if (listBoxScenario.mouseClick (x, y) - || checkBoxScenario.mouseClick (x, y)) - { - processScenario (); - } - else - { - for (int i = 0; i < mapInfo.players; ++i) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - -// set multiplier - if (listBoxRMultiplier[i].mouseClick (x, y)) - { -//printf("Line: %d multiplier index: %d i: %d itemcount: %d\n",__LINE__,listBoxRMultiplier[i].getSelectedItemIndex(),i,listBoxRMultiplier[i].getItemCount()); - -//for(int indexData = 0; indexData < listBoxRMultiplier[i].getItemCount(); ++indexData) { -//string item = listBoxRMultiplier[i].getItem(indexData); - -//printf("Item index: %d value: %s\n",indexData,item.c_str()); -//} - } - -//ensure thet only 1 human player is present - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - ConnectionSlot *slot = serverInterface->getSlot (i, true); - - bool checkControTypeClicked = false; - int selectedControlItemIndex = - listBoxControls[i].getSelectedItemIndex (); - if (selectedControlItemIndex != ctNetwork - || (selectedControlItemIndex == ctNetwork - && (slot == NULL || slot->isConnected () == false))) - { - checkControTypeClicked = true; - } - -//printf("checkControTypeClicked = %d selectedControlItemIndex = %d i = %d\n",checkControTypeClicked,selectedControlItemIndex,i); - - if (selectedControlItemIndex != ctHuman && - checkControTypeClicked == true && - listBoxControls[i].mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - ControlType currentControlType = - static_cast < ControlType > - (listBoxControls[i].getSelectedItemIndex ()); - int slotsToChangeStart = i; - int slotsToChangeEnd = i; -// If control is pressed while changing player types then change all other slots to same type - if (::Shared::Platform:: - Window::isKeyStateModPressed (KMOD_CTRL) == true - && currentControlType != ctHuman) - { - slotsToChangeStart = 0; - slotsToChangeEnd = mapInfo.players - 1; - } - - for (int index = slotsToChangeStart; - index <= slotsToChangeEnd; ++index) - { - if (index != i - && static_cast < ControlType > - (listBoxControls[index].getSelectedItemIndex ()) != - ctHuman) - { - listBoxControls[index].setSelectedItemIndex - (listBoxControls[i].getSelectedItemIndex ()); - } -// Skip over networkunassigned - if (listBoxControls[index].getSelectedItemIndex () == - ctNetworkUnassigned - && selectedControlItemIndex != ctNetworkUnassigned) - { - listBoxControls[index].mouseClick (x, y); - } - -//look for human players - int humanIndex1 = -1; - int humanIndex2 = -1; - for (int j = 0; j < GameConstants::maxPlayers; ++j) - { - ControlType ct = - static_cast < ControlType > - (listBoxControls[j].getSelectedItemIndex ()); - if (ct == ctHuman) - { - if (humanIndex1 == -1) - { - humanIndex1 = j; - } - else - { - humanIndex2 = j; - } - } - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] humanIndex1 = %d, humanIndex2 = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - humanIndex1, humanIndex2); - -//no human - if (humanIndex1 == -1 && humanIndex2 == -1) - { - setSlotHuman (index); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] i = %d, labelPlayerNames[i].getText() [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, index, - labelPlayerNames - [index].getText ().c_str ()); - -//printf("humanIndex1 = %d humanIndex2 = %d i = %d listBoxControls[i].getSelectedItemIndex() = %d\n",humanIndex1,humanIndex2,i,listBoxControls[i].getSelectedItemIndex()); - } -//2 humans - else if (humanIndex1 != -1 && humanIndex2 != -1) - { - int closeSlotIndex = - (humanIndex1 == index ? humanIndex2 : humanIndex1); - int humanSlotIndex = - (closeSlotIndex == - humanIndex1 ? humanIndex2 : humanIndex1); - - string origPlayName = - labelPlayerNames[closeSlotIndex].getText (); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] closeSlotIndex = %d, origPlayName [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - closeSlotIndex, - origPlayName.c_str ()); - - listBoxControls[closeSlotIndex].setSelectedItemIndex - (ctClosed); - setSlotHuman (humanSlotIndex); - labelPlayerNames[humanSlotIndex].setText ((origPlayName != - "" ? - origPlayName : - getHumanPlayerName - ())); - } - updateNetworkSlots (); - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - updateResourceMultiplier (index); - } - } - else if (buttonClearBlockedPlayers.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - if (serverInterface != NULL) - { - ServerSocket *serverSocket = - serverInterface->getServerSocket (); - if (serverSocket != NULL) - { - serverSocket->clearBlockedIPAddress (); - } - } - } - else if (buttonBlockPlayers[i].mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - if (serverInterface != NULL) - { - if (serverInterface->getSlot (i, true) != NULL && - serverInterface->getSlot (i, true)->isConnected ()) - { - - ServerSocket *serverSocket = - serverInterface->getServerSocket (); - if (serverSocket != NULL) - { - serverSocket->addIPAddressToBlockedList - (serverInterface->getSlot (i, true)->getIpAddress ()); - - Lang & lang = Lang::getInstance (); - const vector < string > languageList = - serverInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages - (); - for (unsigned int j = 0; j < languageList.size (); ++j) - { - char szMsg[8096] = ""; - if (lang.hasString ("BlockPlayerServerMsg", - languageList[j]) == true) - { - snprintf (szMsg, 8096, - lang.getString - ("BlockPlayerServerMsg", - languageList[j]).c_str (), - serverInterface->getSlot (i, - true)->getIpAddress - ().c_str ()); - } - else - { - snprintf (szMsg, 8096, - "The server has temporarily blocked IP Address [%s] from this game.", - serverInterface->getSlot (i, - true)->getIpAddress - ().c_str ()); - } - - serverInterface->sendTextMessage (szMsg, -1, true, - languageList[j]); - } - sleep (1); - serverInterface->getSlot (i, true)->close (); - } - } - } - } - else - if (listBoxFactions[i].mouseClick - (x, y, advanceToItemStartingWith)) - { -// Disallow CPU players to be observers - if (factionFiles - [listBoxFactions[i].getSelectedItemIndex ()] == - formatString (GameConstants::OBSERVER_SLOTNAME) - && (listBoxControls[i].getSelectedItemIndex () == - ctCpuEasy - || listBoxControls[i].getSelectedItemIndex () == ctCpu - || listBoxControls[i].getSelectedItemIndex () == - ctCpuUltra - || listBoxControls[i].getSelectedItemIndex () == - ctCpuZeta)) - { - listBoxFactions[i].setSelectedItemIndex (0); - } -// - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - else if (listBoxTeams[i].mouseClick (x, y)) - { - if (factionFiles - [listBoxFactions[i].getSelectedItemIndex ()] != - formatString (GameConstants::OBSERVER_SLOTNAME)) - { - if (listBoxTeams[i].getSelectedItemIndex () + 1 != - (GameConstants::maxPlayers + fpt_Observer)) - { - lastSelectedTeamIndex[i] = - listBoxTeams[i].getSelectedItemIndex (); - } - } - else - { - lastSelectedTeamIndex[i] = -1; - } - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL);; - } - } - else if (labelPlayerNames[i].mouseClick (x, y)) - { - ControlType ct = - static_cast < ControlType > - (listBoxControls[i].getSelectedItemIndex ()); - if (ct == ctHuman) - { - setActiveInputLabel (&labelPlayerNames[i]); - break; - } - } - } - } - } - - if (hasNetworkGameSettings () == true - && listBoxPlayerStatus.mouseClick (x, y)) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - soundRenderer.playFx (coreData.getClickSoundC ()); - if (getNetworkPlayerStatus () == npst_PickSettings) - { - listBoxPlayerStatus.setTextColor (Vec3f (1.0f, 0.0f, 0.0f)); - listBoxPlayerStatus.setLighted (true); - } - else if (getNetworkPlayerStatus () == npst_BeRightBack) - { - listBoxPlayerStatus.setTextColor (Vec3f (1.0f, 1.0f, 0.0f)); - listBoxPlayerStatus.setLighted (true); - } - else if (getNetworkPlayerStatus () == npst_Ready) - { - listBoxPlayerStatus.setTextColor (Vec3f (0.0f, 1.0f, 0.0f)); - listBoxPlayerStatus.setLighted (false); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - showGeneralError = true; - generalErrorToShow = szBuf; - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - void MenuStateCustomGame::loadGameSettings (const std::string & fileName) - { -// Ensure we have set the gamesettings at least once - GameSettings gameSettings = loadGameSettingsFromFile (fileName); - if (gameSettings.getMap () == "") - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - loadGameSettings (&gameSettings); - } - - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - serverInterface->setGameSettings (&gameSettings, false); - - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor () - : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - - void MenuStateCustomGame::RestoreLastGameSettings () - { - loadGameSettings (SAVED_GAME_FILENAME); - } - - bool MenuStateCustomGame::checkNetworkPlayerDataSynch (bool checkMapCRC, - bool - checkTileSetCRC, - bool - checkTechTreeCRC) - { - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - - bool dataSynchCheckOk = true; - for (int i = 0; i < mapInfo.players; ++i) - { - if (listBoxControls[i].getSelectedItemIndex () == ctNetwork) - { - - MutexSafeWrapper safeMutex (serverInterface->getSlotMutex (i), - CODE_AT_LINE); - ConnectionSlot *slot = serverInterface->getSlot (i, false); - if (slot != NULL && slot->isConnected () && - (slot->getAllowDownloadDataSynch () == true || - slot->getAllowGameDataSynchCheck () == true)) - { - - if (checkMapCRC == true && - slot->getNetworkGameDataSynchCheckOkMap () == false) - { - dataSynchCheckOk = false; - break; - } - if (checkTileSetCRC == true && - slot->getNetworkGameDataSynchCheckOkTile () == false) - { - dataSynchCheckOk = false; - break; - } - if (checkTechTreeCRC == true && - slot->getNetworkGameDataSynchCheckOkTech () == false) - { - dataSynchCheckOk = false; - break; - } - } - } - } - - return dataSynchCheckOk; - } - - void MenuStateCustomGame::PlayNow (bool saveGame) - { - if (listBoxTechTree.getItemCount () <= 0) - { - mainMessageBoxState = 1; - - char szMsg[8096] = ""; - strcpy (szMsg, "Cannot start game.\nThere are no tech-trees!\n"); - printf ("%s", szMsg); - - showMessageBox (szMsg, "", false); - return; - } - - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor () - : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - if (saveGame == true) - { - saveGameSettingsToFile (SAVED_GAME_FILENAME); - } - - forceWaitForShutdown = false; - closeUnusedSlots (); - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - soundRenderer.playFx (coreData.getClickSoundC ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - std::vector < string > randomFactionSelectionList; - int RandomCount = 0; - for (int i = 0; i < mapInfo.players; ++i) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -// Check for random faction selection and choose the faction now - if (listBoxControls[i].getSelectedItemIndex () != ctClosed) - { - if (listBoxFactions[i].getSelectedItem () == - formatString (GameConstants::RANDOMFACTION_SLOTNAME) - && listBoxFactions[i].getItemCount () > 1) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] i = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, i); - -// Max 1000 tries to get a random, unused faction - for (int findRandomFaction = 1; findRandomFaction < 1000; - ++findRandomFaction) - { - Chrono seed (true); - srand ((unsigned int) seed.getCurTicks () + findRandomFaction); - - int selectedFactionIndex = - rand () % listBoxFactions[i].getItemCount (); - string selectedFactionName = - listBoxFactions[i].getItem (selectedFactionIndex); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] selectedFactionName [%s] selectedFactionIndex = %d, findRandomFaction = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, - selectedFactionName.c_str (), - selectedFactionIndex, - findRandomFaction); - - if (selectedFactionName != - formatString (GameConstants::RANDOMFACTION_SLOTNAME) - && selectedFactionName != - formatString (GameConstants::OBSERVER_SLOTNAME) - && std::find (randomFactionSelectionList.begin (), - randomFactionSelectionList.end (), - selectedFactionName) == - randomFactionSelectionList.end ()) - { - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - listBoxFactions[i].setSelectedItem (selectedFactionName); - randomFactionSelectionList.push_back (selectedFactionName); - break; - } - } - - if (listBoxFactions[i].getSelectedItem () == - formatString (GameConstants::RANDOMFACTION_SLOTNAME)) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] RandomCount = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, RandomCount); - -// Find first real faction and use it - int factionIndexToUse = RandomCount; - for (int useIdx = 0; - useIdx < listBoxFactions[i].getItemCount (); useIdx++) - { - string selectedFactionName = - listBoxFactions[i].getItem (useIdx); - if (selectedFactionName != - formatString (GameConstants::RANDOMFACTION_SLOTNAME) - && selectedFactionName != - formatString (GameConstants::OBSERVER_SLOTNAME)) - { - factionIndexToUse = useIdx; - break; - } - } - listBoxFactions[i].setSelectedItemIndex (factionIndexToUse); - randomFactionSelectionList.push_back (listBoxFactions[i].getItem - (factionIndexToUse)); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] i = %d, listBoxFactions[i].getSelectedItem() [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, i, - listBoxFactions[i].getSelectedItem (). - c_str ()); - - RandomCount++; - } - } - } - - if (RandomCount > 0) - { - needToSetChangedGameSettings = true; - } - - safeMutex.ReleaseLock (true); - safeMutexCLI.ReleaseLock (true); - GameSettings gameSettings; - loadGameSettings (&gameSettings, true); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - -// Send the game settings to each client if we have at least one networked client - safeMutex.Lock (); - safeMutexCLI.Lock (); - - bool dataSynchCheckOk = checkNetworkPlayerDataSynch (true, true, true); - -// Ensure we have no dangling network players - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - if (listBoxControls[i].getSelectedItemIndex () == ctNetworkUnassigned) - { - mainMessageBoxState = 1; - - Lang & lang = Lang::getInstance (); - string sMsg = ""; - if (lang.hasString ("NetworkSlotUnassignedErrorUI") == true) - { - sMsg = lang.getString ("NetworkSlotUnassignedErrorUI"); - } - else - { - sMsg = - "Cannot start game.\nSome player(s) are not in a network game slot!"; - } - - showMessageBox (sMsg, "", false); - - const vector < string > languageList = - serverInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int j = 0; j < languageList.size (); ++j) - { - char szMsg[8096] = ""; - if (lang.hasString ("NetworkSlotUnassignedError", - languageList[j]) == true) - { - string msg_string = - lang.getString ("NetworkSlotUnassignedError"); +namespace Glest { + namespace Game { + + using namespace::Shared::Util; + + const int MASTERSERVER_BROADCAST_MAX_WAIT_RESPONSE_SECONDS = 15; + static const char *SAVED_GAME_FILENAME = "lastCustomGameSettings.mgg"; + static const char *DEFAULT_GAME_FILENAME = "data/defaultGameSetup.mgg"; + static const char *DEFAULT_NETWORKGAME_FILENAME = + "data/defaultNetworkGameSetup.mgg"; + + const int mapPreviewTexture_X = 5; + const int mapPreviewTexture_Y = 185; + const int mapPreviewTexture_W = 150; + const int mapPreviewTexture_H = 150; + + struct FormatString { + void operator () (string & s) { + s = formatString(s); + } + }; + + // ===================================================== + // class MenuStateCustomGame + // ===================================================== + enum THREAD_NOTIFIER_TYPE { + tnt_MASTERSERVER = 1, + tnt_CLIENTS = 2 + }; + + MenuStateCustomGame::MenuStateCustomGame(Program * program, + MainMenu * mainMenu, + bool openNetworkSlots, + ParentMenuState + parentMenuState, + bool autostart, + GameSettings * settings, + bool masterserverMode, + string + autoloadScenarioName) :MenuState + (program, mainMenu, "new-game") { + try { + + this->headlessServerMode = masterserverMode; + if (this->headlessServerMode == true) { + printf("Waiting for players to join and start a game...\n"); + } + + this->gameUUID = getUUIDAsString(); + + this->zoomedMap = false; + this->render_mapPreviewTexture_X = mapPreviewTexture_X; + this->render_mapPreviewTexture_Y = mapPreviewTexture_Y; + this->render_mapPreviewTexture_W = mapPreviewTexture_W; + this->render_mapPreviewTexture_H = mapPreviewTexture_H; + + this->lastMasterServerSettingsUpdateCount = 0; + this->masterserverModeMinimalResources = true; + this->parentMenuState = parentMenuState; + this->factionVideo = NULL; + factionVideoSwitchedOffVolume = false; + + //printf("this->masterserverMode = %d [%d]\n",this->masterserverMode,masterserverMode); + + forceWaitForShutdown = true; + this->autostart = autostart; + this->autoStartSettings = settings; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] autostart = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, autostart); + + containerName = "CustomGame"; + activeInputLabel = NULL; + showGeneralError = false; + generalErrorToShow = "---"; + currentFactionLogo = ""; + factionTexture = NULL; + currentTechName_factionPreview = ""; + currentFactionName_factionPreview = ""; + mapPreviewTexture = NULL; + hasCheckedForUPNP = false; + needToPublishDelayed = false; + mapPublishingDelayTimer = time(NULL); + headlessHasConnectedPlayer = false; + + lastCheckedCRCTilesetName = ""; + lastCheckedCRCTechtreeName = ""; + lastCheckedCRCMapName = ""; + + last_Forced_CheckedCRCTilesetName = ""; + last_Forced_CheckedCRCTechtreeName = ""; + last_Forced_CheckedCRCMapName = ""; + + lastCheckedCRCTilesetValue = 0; + lastCheckedCRCTechtreeValue = 0; + lastCheckedCRCMapValue = 0; + + publishToMasterserverThread = NULL; + publishToClientsThread = NULL; + + Lang & lang = Lang::getInstance(); + NetworkManager & networkManager = NetworkManager::getInstance(); + Config & config = Config::getInstance(); + defaultPlayerName = + config.getString("NetPlayerName", Socket::getHostName().c_str()); + enableFactionTexturePreview = + config.getBool("FactionPreview", "true"); + enableMapPreview = config.getBool("MapPreview", "true"); + + showFullConsole = false; + + enableScenarioTexturePreview = + Config::getInstance().getBool("EnableScenarioTexturePreview", + "true"); + scenarioLogoTexture = NULL; + previewLoadDelayTimer = time(NULL); + needToLoadTextures = true; + this->autoloadScenarioName = autoloadScenarioName; + this->dirList = + Config::getInstance().getPathListForType(ptScenarios); + + mainMessageBox.registerGraphicComponent(containerName, + "mainMessageBox"); + mainMessageBox.init(lang.getString("Ok"), 500, 300); + mainMessageBox.setEnabled(false); + mainMessageBoxState = 0; + + //initialize network interface + NetworkManager::getInstance().end(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + serverInitError = false; + try { + networkManager.init(nrServer, openNetworkSlots); + } catch (const std::exception & ex) { + serverInitError = true; + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nNetwork init error:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + showGeneralError = true; + generalErrorToShow = szBuf; + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + needToSetChangedGameSettings = false; + needToRepublishToMasterserver = false; + needToBroadcastServerSettings = false; + lastGameSettingsreceivedCount = -1; + showMasterserverError = false; + tMasterserverErrorElapsed = 0; + masterServererErrorToShow = "---"; + lastSetChangedGameSettings = 0; + lastMasterserverPublishing = 0; + lastNetworkPing = 0; + soundConnectionCount = 0; + + techTree.reset(new TechTree(config.getPathListForType(ptTechs))); + + // Some of these values must also be changed to match those in + // menu_state_connected_game.cpp + int labelOffset = 23; + int setupPos = 605; + // mapHeadPos is the placement of the text "map", not the map itself + int mapHeadPos = 310; + int mapPos = mapHeadPos - labelOffset; + int aHeadPos = mapHeadPos - 90; + int aPos = aHeadPos - labelOffset; + int networkHeadPos = 700; + int networkPos = networkHeadPos - labelOffset; + int xoffset = 10; + + //create + int buttonx = 165; + int buttony = mapHeadPos - 150; + + // player status + listBoxPlayerStatus.registerGraphicComponent(containerName, + "listBoxPlayerStatus"); + listBoxPlayerStatus.init(buttonx, buttony, 165); + vector < string > playerStatuses; + playerStatuses.push_back(lang.getString("PlayerStatusSetup")); + playerStatuses.push_back(lang.getString("PlayerStatusBeRightBack")); + playerStatuses.push_back(lang.getString("PlayerStatusReady")); + listBoxPlayerStatus.setItems(playerStatuses); + listBoxPlayerStatus.setSelectedItemIndex(2, true); + listBoxPlayerStatus.setTextColor(Vec3f(0.0f, 1.0f, 0.0f)); + listBoxPlayerStatus.setLighted(false); + listBoxPlayerStatus.setVisible(true); + buttonx += 180; + + buttonReturn.registerGraphicComponent(containerName, "buttonReturn"); + buttonReturn.init(buttonx, buttony, 125); + buttonx += 132; + + buttonRestoreLastSettings.registerGraphicComponent(containerName, + "buttonRestoreLastSettings"); + buttonRestoreLastSettings.init(buttonx, buttony, 240); + buttonx += 247; + + buttonPlayNow.registerGraphicComponent(containerName, + "buttonPlayNow"); + buttonPlayNow.init(buttonx, buttony, 125); + + labelLocalGameVersion.registerGraphicComponent(containerName, + "labelLocalGameVersion"); + labelLocalGameVersion.init(10, networkHeadPos + labelOffset); + + labelLocalIP.registerGraphicComponent(containerName, "labelLocalIP"); + labelLocalIP.init(360, networkHeadPos + labelOffset); + + string ipText = "none"; + std::vector < std::string > ipList = Socket::getLocalIPAddressList(); + if (ipList.empty() == false) { + ipText = ""; + for (int idx = 0; idx < (int) ipList.size(); idx++) { + string ip = ipList[idx]; + if (ipText != "") { + ipText += ", "; + } + ipText += ip; + } + } + string serverPort = config.getString("PortServer", + intToStr + (GameConstants:: + serverPort).c_str()); + string externalPort = + config.getString("PortExternal", serverPort.c_str()); + labelLocalIP.setText(lang.getString("LanIP") + ipText + " ( " + + serverPort + " / " + externalPort + " )"); + ServerSocket::setExternalPort(strToInt(externalPort)); + + if (EndsWith(glestVersionString, "-dev") == false) { + labelLocalGameVersion.setText(glestVersionString); + } else { + //labelLocalGameVersion.setText(glestVersionString + " [" + getCompileDateTime() + ", " + getGITRevisionString() + "]"); + labelLocalGameVersion.setText(glestVersionString); + } + + xoffset = 65; + // MapFilter + labelMapFilter.registerGraphicComponent(containerName, + "labelMapFilter"); + labelMapFilter.init(xoffset + 325, mapHeadPos); + labelMapFilter.setText(lang.getString("MapFilter")); + + listBoxMapFilter.registerGraphicComponent(containerName, + "listBoxMapFilter"); + listBoxMapFilter.init(xoffset + 325, mapPos, 80); + listBoxMapFilter.pushBackItem("-"); + for (int i = 1; i < GameConstants::maxPlayers + 1; ++i) { + listBoxMapFilter.pushBackItem(intToStr(i)); + } + listBoxMapFilter.setSelectedItemIndex(0); + + // Map + labelMap.registerGraphicComponent(containerName, "labelMap"); + labelMap.init(xoffset + 100, mapHeadPos); + labelMap.setText(lang.getString("Map")); + + //map listBox + listBoxMap.registerGraphicComponent(containerName, "listBoxMap"); + listBoxMap.init(xoffset + 100, mapPos, 220); + // put them all in a set, to weed out duplicates (gbm & mgm with same name) + // will also ensure they are alphabetically listed (rather than how the OS provides them) + int initialMapSelection = setupMapList(""); + listBoxMap.setItems(formattedPlayerSortedMaps[0]); + listBoxMap.setSelectedItemIndex(initialMapSelection); + + labelMapInfo.registerGraphicComponent(containerName, "labelMapInfo"); + labelMapInfo.init(xoffset + 100, mapPos - labelOffset - 10, 200, 40); + + labelTileset.registerGraphicComponent(containerName, "labelTileset"); + labelTileset.init(xoffset + 500, mapHeadPos); + labelTileset.setText(lang.getString("Tileset")); + + //tileset listBox + listBoxTileset.registerGraphicComponent(containerName, + "listBoxTileset"); + listBoxTileset.init(xoffset + 500, mapPos, 160); + + setupTilesetList(""); + Chrono seed(true); + srand((unsigned int) seed.getCurTicks()); + + listBoxTileset.setSelectedItemIndex(rand() % + listBoxTileset.getItemCount()); + + //tech Tree listBox + int initialTechSelection = setupTechList("", true); + + listBoxTechTree.registerGraphicComponent(containerName, + "listBoxTechTree"); + listBoxTechTree.init(xoffset + 700, mapPos, 180); + if (listBoxTechTree.getItemCount() > 0) { + listBoxTechTree.setSelectedItemIndex(initialTechSelection); + } + + labelTechTree.registerGraphicComponent(containerName, + "labelTechTree"); + labelTechTree.init(xoffset + 700, mapHeadPos); + labelTechTree.setText(lang.getString("TechTree")); + + // fog - o - war + // @350 ? 300 ? + labelFogOfWar.registerGraphicComponent(containerName, + "labelFogOfWar"); + labelFogOfWar.init(xoffset + 100, aHeadPos, 165); + labelFogOfWar.setText(lang.getString("FogOfWar")); + + listBoxFogOfWar.registerGraphicComponent(containerName, + "listBoxFogOfWar"); + listBoxFogOfWar.init(xoffset + 100, aPos, 165); + listBoxFogOfWar.pushBackItem(lang.getString("Enabled")); + listBoxFogOfWar.pushBackItem(lang.getString("Explored")); + listBoxFogOfWar.pushBackItem(lang.getString("Disabled")); + listBoxFogOfWar.setSelectedItemIndex(0); + + // Allow Observers + labelAllowObservers.registerGraphicComponent(containerName, + "labelAllowObservers"); + labelAllowObservers.init(xoffset + 325, aHeadPos, 80); + labelAllowObservers.setText(lang.getString("AllowObservers")); + + checkBoxAllowObservers.registerGraphicComponent(containerName, + "checkBoxAllowObservers"); + checkBoxAllowObservers.init(xoffset + 325, aPos); + checkBoxAllowObservers.setValue(checkBoxAllowObservers.getValue()); + + vector < string > rMultiplier; + for (int i = 0; i < 45; ++i) { + rMultiplier.push_back(floatToStr(0.5f + 0.1f * i, 1)); + } + + labelFallbackCpuMultiplier.registerGraphicComponent(containerName, + "labelFallbackCpuMultiplier"); + labelFallbackCpuMultiplier.init(xoffset + 500, aHeadPos, 80); + labelFallbackCpuMultiplier.setText(lang.getString + ("FallbackCpuMultiplier")); + + listBoxFallbackCpuMultiplier.registerGraphicComponent(containerName, + "listBoxFallbackCpuMultiplier"); + listBoxFallbackCpuMultiplier.init(xoffset + 500, aPos, 80); + listBoxFallbackCpuMultiplier.setItems(rMultiplier); + listBoxFallbackCpuMultiplier.setSelectedItem("1.0"); + + // Allow Switch Team Mode + labelEnableSwitchTeamMode.registerGraphicComponent(containerName, + "labelEnableSwitchTeamMode"); + labelEnableSwitchTeamMode.init(xoffset + 325, aHeadPos + 45, 80); + labelEnableSwitchTeamMode.setText(lang.getString + ("EnableSwitchTeamMode")); + + checkBoxEnableSwitchTeamMode.registerGraphicComponent(containerName, + "checkBoxEnableSwitchTeamMode"); + checkBoxEnableSwitchTeamMode.init(xoffset + 325, aPos + 45); + checkBoxEnableSwitchTeamMode.setValue(false); + + labelAISwitchTeamAcceptPercent.registerGraphicComponent + (containerName, "labelAISwitchTeamAcceptPercent"); + labelAISwitchTeamAcceptPercent.init(xoffset + 500, aHeadPos + 45, + 80); + labelAISwitchTeamAcceptPercent.setText(lang.getString + ("AISwitchTeamAcceptPercent")); + + listBoxAISwitchTeamAcceptPercent.registerGraphicComponent + (containerName, "listBoxAISwitchTeamAcceptPercent"); + listBoxAISwitchTeamAcceptPercent.init(xoffset + 500, aPos + 45, 80); + for (int i = 0; i <= 100; i = i + 10) { + listBoxAISwitchTeamAcceptPercent.pushBackItem(intToStr(i)); + } + listBoxAISwitchTeamAcceptPercent.setSelectedItem(intToStr(30)); + + labelAllowNativeLanguageTechtree.registerGraphicComponent + (containerName, "labelAllowNativeLanguageTechtree"); + labelAllowNativeLanguageTechtree.init(xoffset + 700, aHeadPos + 45); + labelAllowNativeLanguageTechtree.setText(lang.getString + ("AllowNativeLanguageTechtree")); + + checkBoxAllowNativeLanguageTechtree.registerGraphicComponent + (containerName, "checkBoxAllowNativeLanguageTechtree"); + checkBoxAllowNativeLanguageTechtree.init(xoffset + 700, aPos + 45); + checkBoxAllowNativeLanguageTechtree.setValue(false); + + // Network Scenario + int scenarioX = xoffset + 700; + int scenarioY = aPos; + labelScenario.registerGraphicComponent(containerName, + "labelScenario"); + labelScenario.init(scenarioX, aHeadPos); + labelScenario.setText(lang.getString("Scenario")); + listBoxScenario.registerGraphicComponent(containerName, + "listBoxScenario"); + listBoxScenario.init(scenarioX + 30, scenarioY, 190); + checkBoxScenario.registerGraphicComponent(containerName, + "checkBoxScenario"); + checkBoxScenario.init(scenarioX, scenarioY); + checkBoxScenario.setValue(false); + + //scenario listbox + vector < string > resultsScenarios; + findDirs(dirList, resultsScenarios); + // Filter out only scenarios with no network slots + for (int i = 0; i < (int) resultsScenarios.size(); ++i) { + string scenario = resultsScenarios[i]; + string file = Scenario::getScenarioPath(dirList, scenario); + + try { + if (file != "") { + bool isTutorial = Scenario::isGameTutorial(file); + Scenario::loadScenarioInfo(file, &scenarioInfo, isTutorial); + + bool isNetworkScenario = false; + for (unsigned int j = 0; + isNetworkScenario == false + && j < (unsigned int) GameConstants::maxPlayers; ++j) { + if (scenarioInfo.factionControls[j] == ctNetwork) { + isNetworkScenario = true; + } + } + if (isNetworkScenario == true) { + scenarioFiles.push_back(scenario); + } + } + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s %d]\nError loading scenario [%s]:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, scenario.c_str(), ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", + szBuf); + + showGeneralError = true; + generalErrorToShow = szBuf; + //throw megaglest_runtime_error(szBuf); + } + } + resultsScenarios.clear(); + for (int i = 0; i < (int) scenarioFiles.size(); ++i) { + resultsScenarios.push_back(formatString(scenarioFiles[i])); + } + listBoxScenario.setItems(resultsScenarios); + if (resultsScenarios.empty() == true) { + checkBoxScenario.setEnabled(false); + } + // Advanced Options + labelAdvanced.registerGraphicComponent(containerName, + "labelAdvanced"); + labelAdvanced.init(scenarioX, 80, 80); + labelAdvanced.setText(lang.getString("AdvancedGameOptions")); + + checkBoxAdvanced.registerGraphicComponent(containerName, + "checkBoxAdvanced"); + checkBoxAdvanced.init(scenarioX, 80 - labelOffset); + checkBoxAdvanced.setValue(false); + + // network things + // PublishServer + xoffset = 90; + + labelPublishServer.registerGraphicComponent(containerName, + "labelPublishServer"); + labelPublishServer.init(20, networkHeadPos, 100); + labelPublishServer.setText(lang.getString("PublishServer")); + + checkBoxPublishServer.registerGraphicComponent(containerName, + "checkBoxPublishServer"); + checkBoxPublishServer.init(20, networkPos); + + checkBoxPublishServer.setValue(false); + if ((this->headlessServerMode == true || + (openNetworkSlots == true && parentMenuState != pLanGame)) && + GlobalStaticFlags::isFlagSet(gsft_lan_mode) == false) { + checkBoxPublishServer.setValue(true); + } + + labelGameName.registerGraphicComponent(containerName, + "labelGameName"); + labelGameName.init(20 + checkBoxPublishServer.getW() + 5, + networkPos, 200); + labelGameName.setFont(CoreData::getInstance().getMenuFontBig()); + labelGameName. + setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelGameName.setText(createGameName()); + labelGameName.setEditable(true); + labelGameName.setMaxEditWidth(20); + labelGameName.setMaxEditRenderWidth(200); + + + bool allowInProgressJoin = + Config::getInstance().getBool("EnableJoinInProgressGame", "true"); + labelAllowInGameJoinPlayer.registerGraphicComponent(containerName, + "labelAllowInGameJoinPlayer"); + labelAllowInGameJoinPlayer.init(50, networkPos - 30, 80); + labelAllowInGameJoinPlayer.setText(lang.getString + ("AllowInGameJoinPlayer")); + labelAllowInGameJoinPlayer.setVisible(allowInProgressJoin); + + checkBoxAllowInGameJoinPlayer.registerGraphicComponent(containerName, + "checkBoxAllowInGameJoinPlayer"); + checkBoxAllowInGameJoinPlayer.init(20, networkPos - 30); + checkBoxAllowInGameJoinPlayer.setValue(false); + checkBoxAllowInGameJoinPlayer.setVisible(allowInProgressJoin); + + + labelAllowTeamUnitSharing.registerGraphicComponent(containerName, + "labelAllowTeamUnitSharing"); + labelAllowTeamUnitSharing.init(xoffset + 410, 670, 80); + labelAllowTeamUnitSharing.setText(lang.getString + ("AllowTeamUnitSharing")); + labelAllowTeamUnitSharing.setVisible(true); + + checkBoxAllowTeamUnitSharing.registerGraphicComponent(containerName, + "checkBoxAllowTeamUnitSharing"); + checkBoxAllowTeamUnitSharing.init(xoffset + 612, 670); + checkBoxAllowTeamUnitSharing.setValue(false); + checkBoxAllowTeamUnitSharing.setVisible(true); + + labelAllowTeamResourceSharing.registerGraphicComponent(containerName, + "labelAllowTeamResourceSharing"); + labelAllowTeamResourceSharing.init(xoffset + 410, 640, 80); + labelAllowTeamResourceSharing.setText(lang.getString + ("AllowTeamResourceSharing")); + labelAllowTeamResourceSharing.setVisible(true); + + checkBoxAllowTeamResourceSharing.registerGraphicComponent + (containerName, "checkBoxAllowTeamResourceSharing"); + checkBoxAllowTeamResourceSharing.init(xoffset + 612, 640); + checkBoxAllowTeamResourceSharing.setValue(false); + checkBoxAllowTeamResourceSharing.setVisible(true); + + + // Network Pause for lagged clients + labelNetworkPauseGameForLaggedClients.registerGraphicComponent + (containerName, "labelNetworkPauseGameForLaggedClients"); + labelNetworkPauseGameForLaggedClients.init + (labelAllowTeamResourceSharing.getX(), networkHeadPos, 80); + labelNetworkPauseGameForLaggedClients.setText(lang.getString + ("NetworkPauseGameForLaggedClients")); + + checkBoxNetworkPauseGameForLaggedClients.registerGraphicComponent + (containerName, "checkBoxNetworkPauseGameForLaggedClients"); + checkBoxNetworkPauseGameForLaggedClients.init + (checkBoxAllowTeamResourceSharing.getX(), networkHeadPos); + checkBoxNetworkPauseGameForLaggedClients.setValue(true); + + //list boxes + xoffset = 5; + int rowHeight = 27; + + buttonClearBlockedPlayers.registerGraphicComponent(containerName, + "buttonClearBlockedPlayers"); + buttonClearBlockedPlayers.init(xoffset + 800, + setupPos - 30, + 134 + 2 + 50); + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + + labelPlayers[i].registerGraphicComponent(containerName, + "labelPlayers" + + intToStr(i)); + labelPlayers[i].init(xoffset - 1, + setupPos - 30 - i * rowHeight + 2); + labelPlayers[i]. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + labelPlayers[i]. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + + labelPlayerStatus[i].registerGraphicComponent(containerName, + "labelPlayerStatus" + + intToStr(i)); + labelPlayerStatus[i].init(xoffset + 14, + setupPos - 30 - i * rowHeight + 2); + labelPlayerNames[i].registerGraphicComponent(containerName, + "labelPlayerNames" + + intToStr(i)); + labelPlayerNames[i].init(xoffset + 30, + setupPos - 30 - i * rowHeight); + + listBoxControls[i].registerGraphicComponent(containerName, + "listBoxControls" + + intToStr(i)); + listBoxControls[i].init(xoffset + 160, + setupPos - 30 - i * rowHeight, 174); + + buttonBlockPlayers[i].registerGraphicComponent(containerName, + "buttonBlockPlayers" + + intToStr(i)); + //buttonBlockPlayers[i].init(xoffset+355, setupPos-30-i*rowHeight, 70); + buttonBlockPlayers[i].init(xoffset + 185, + setupPos - 30 - i * rowHeight, 124); + buttonBlockPlayers[i].setText(lang.getString("BlockPlayer")); + buttonBlockPlayers[i]. + setFont(CoreData::getInstance().getDisplayFontSmall()); + buttonBlockPlayers[i]. + setFont3D(CoreData::getInstance().getDisplayFontSmall3D()); + + listBoxRMultiplier[i].registerGraphicComponent(containerName, + "listBoxRMultiplier" + + intToStr(i)); + listBoxRMultiplier[i].init(xoffset + 336, + setupPos - 30 - i * rowHeight, 70); + + listBoxFactions[i].registerGraphicComponent(containerName, + "listBoxFactions" + + intToStr(i)); + listBoxFactions[i].init(xoffset + 411, + setupPos - 30 - i * rowHeight, 247); + listBoxFactions[i].setLeftControlled(true); + + listBoxTeams[i].registerGraphicComponent(containerName, + "listBoxTeams" + + intToStr(i)); + listBoxTeams[i].init(xoffset + 660, + setupPos - 30 - i * rowHeight, 60); + listBoxTeams[i].setLighted(true); + + labelNetStatus[i].registerGraphicComponent(containerName, + "labelNetStatus" + + intToStr(i)); + labelNetStatus[i].init(xoffset + 726, + setupPos - 30 - i * rowHeight, 60); + labelNetStatus[i]. + setFont(CoreData::getInstance().getDisplayFontSmall()); + labelNetStatus[i]. + setFont3D(CoreData::getInstance().getDisplayFontSmall3D()); + } + + labelControl.registerGraphicComponent(containerName, "labelControl"); + labelControl.init(xoffset + 160, setupPos, 50, GraphicListBox::defH, + true); + labelControl.setText(lang.getString("Control")); + + labelRMultiplier.registerGraphicComponent(containerName, + "labelRMultiplier"); + labelRMultiplier.init(xoffset + 310, setupPos, 50, + GraphicListBox::defH, true); + + labelFaction.registerGraphicComponent(containerName, "labelFaction"); + labelFaction.init(xoffset + 411, setupPos, 50, GraphicListBox::defH, + true); + labelFaction.setText(lang.getString("Faction")); + + labelTeam.registerGraphicComponent(containerName, "labelTeam"); + labelTeam.init(xoffset + 660, setupPos, 50, GraphicListBox::defH, + true); + labelTeam.setText(lang.getString("Team")); + + labelControl.setFont(CoreData::getInstance().getMenuFontBig()); + labelControl.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelRMultiplier.setFont(CoreData::getInstance().getMenuFontBig()); + labelRMultiplier. + setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelFaction.setFont(CoreData::getInstance().getMenuFontBig()); + labelFaction.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelTeam.setFont(CoreData::getInstance().getMenuFontBig()); + labelTeam.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + + //xoffset=100; + + //texts + buttonClearBlockedPlayers. + setText(lang.getString("BlockPlayerClear")); + buttonReturn.setText(lang.getString("Return")); + buttonPlayNow.setText(lang.getString("PlayNow")); + buttonRestoreLastSettings.setText(lang.getString + ("ReloadLastGameSettings")); + + vector < string > controlItems; + controlItems.push_back(lang.getString("Closed")); + controlItems.push_back(lang.getString("CpuEasy")); + controlItems.push_back(lang.getString("Cpu")); + controlItems.push_back(lang.getString("CpuUltra")); + controlItems.push_back(lang.getString("CpuZeta")); + controlItems.push_back(lang.getString("Network")); + controlItems.push_back(lang.getString("NetworkUnassigned")); + controlItems.push_back(lang.getString("Human")); + + if (config.getBool("EnableNetworkCpu", "false") == true) { + controlItems.push_back(lang.getString("NetworkCpuEasy")); + controlItems.push_back(lang.getString("NetworkCpu")); + controlItems.push_back(lang.getString("NetworkCpuUltra")); + controlItems.push_back(lang.getString("NetworkCpuZeta")); + } + + vector < string > teamItems; + for (int i = 1; i <= GameConstants::maxPlayers; ++i) { + teamItems.push_back(intToStr(i)); + } + for (int i = GameConstants::maxPlayers + 1; + i <= GameConstants::maxPlayers + GameConstants::specialFactions; + ++i) { + teamItems.push_back(intToStr(i)); + } + + reloadFactions(false, ""); + + if (factionFiles.empty() == true) { + showGeneralError = true; + generalErrorToShow = + "[#1] There are no factions for the tech tree [" + + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "]"; + } + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + labelPlayerStatus[i].setText(" "); + labelPlayerStatus[i]. + setTexture(CoreData::getInstance().getStatusReadyTexture()); + labelPlayerStatus[i].setH(16); + labelPlayerStatus[i].setW(12); + + //labelPlayers[i].setText(lang.getString("Player")+" "+intToStr(i)); + labelPlayers[i].setText(intToStr(i + 1)); + labelPlayerNames[i].setText("*"); + labelPlayerNames[i].setMaxEditWidth(16); + labelPlayerNames[i].setMaxEditRenderWidth(127); + + listBoxTeams[i].setItems(teamItems); + listBoxTeams[i].setSelectedItemIndex(i); + lastSelectedTeamIndex[i] = listBoxTeams[i].getSelectedItemIndex(); + + listBoxControls[i].setItems(controlItems); + listBoxRMultiplier[i].setItems(rMultiplier); + listBoxRMultiplier[i].setSelectedItem("1.0"); + labelNetStatus[i].setText(""); + } + + // I moved this block from loadMapInfo(), and modified it. It was + // setting the slots visible based on the number of hardMaxPlayers + // every time a new map was loaded. Trying it here instead, so the + // labels are made visible only once. Below, we'll be disabling slots + // that exceed hardMaxPlayers + for (int i = 0; i < GameConstants::maxPlayers; i++) { + labelPlayers[i].setVisible(true); + labelPlayerNames[i].setVisible(true); + listBoxControls[i].setVisible(true); + listBoxFactions[i].setVisible(true); + listBoxTeams[i].setVisible(true); + labelNetStatus[i].setVisible(true); + } + + loadMapInfo(Config::getMapPath(getCurrentMapFile()), &mapInfo, + true); + labelMapInfo.setText(mapInfo.desc); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //init controllers + if (serverInitError == false) { + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + if (serverInterface == NULL) { + throw megaglest_runtime_error("serverInterface == NULL"); + } + if (this->headlessServerMode == true) { + listBoxControls[0].setSelectedItemIndex(ctNetwork); + updateResourceMultiplier(0); + } else { + setSlotHuman(0); + updateResourceMultiplier(0); + } + labelPlayerNames[0].setText(""); + labelPlayerNames[0].setText(getHumanPlayerName()); + + if (openNetworkSlots == true) { + for (int i = 1; i < mapInfo.players; ++i) { + listBoxControls[i].setSelectedItemIndex(ctNetwork); + } + } else { + listBoxControls[1].setSelectedItemIndex(ctCpu); + } + updateControllers(); + updateNetworkSlots(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + // Ensure we have set the gamesettings at least once + GameSettings gameSettings; + loadGameSettings(&gameSettings); + + serverInterface->setGameSettings(&gameSettings, false); + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + updateAllResourceMultiplier(); + + // write hint to console: + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + + console.addLine(lang.getString("ToSwitchOffMusicPress") + " - \"" + + configKeys.getString("ToggleMusic") + "\""); + + chatManager.init(&console, -1, true); + + GraphicComponent::applyAllCustomProperties(containerName); + + static string mutexOwnerId = + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + string("_") + intToStr(__LINE__); + publishToMasterserverThread = + new SimpleTaskThread(this, 0, 300, false, + (void *) tnt_MASTERSERVER); + publishToMasterserverThread->setUniqueID(mutexOwnerId); + + static string mutexOwnerId2 = + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + string("_") + intToStr(__LINE__); + publishToClientsThread = + new SimpleTaskThread(this, 0, 200, false, (void *) tnt_CLIENTS, + false); + publishToClientsThread->setUniqueID(mutexOwnerId2); + + publishToMasterserverThread->start(); + publishToClientsThread->start(); + + if (openNetworkSlots == true) { + string data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + + if (fileExists(data_path + DEFAULT_NETWORKGAME_FILENAME) == true) + loadGameSettings(data_path + DEFAULT_NETWORKGAME_FILENAME); + } else { + string data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + + if (fileExists(data_path + DEFAULT_GAME_FILENAME) == true) + loadGameSettings(data_path + DEFAULT_GAME_FILENAME); + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + throw megaglest_runtime_error(szBuf); + } + } + + string MenuStateCustomGame::createGameName(string controllingPlayer) { + Config & config = Config::getInstance(); + string serverTitle = config.getString("ServerTitle", ""); + + if (serverTitle != "" && controllingPlayer == "") { + return serverTitle; + } else if (this->headlessServerMode == true) { + if (controllingPlayer != "") { + return controllingPlayer + " controls"; + } else { + return "[H] " + defaultPlayerName; + } + } else { + string defaultPlayerNameEnd = + defaultPlayerName.substr(defaultPlayerName.size() - 1, 1); + if (defaultPlayerNameEnd == "s") { + return defaultPlayerName + "' game"; + } else { + return defaultPlayerName + "'s game"; + } + } + } + + void MenuStateCustomGame::reloadUI() { + Lang & lang = Lang::getInstance(); + Config & config = Config::getInstance(); + + console.resetFonts(); + mainMessageBox.init(lang.getString("Ok"), 500, 300); + + + if (EndsWith(glestVersionString, "-dev") == false) { + labelLocalGameVersion.setText(glestVersionString); + } else { + //labelLocalGameVersion.setText(glestVersionString + " [" + getCompileDateTime() + ", " + getGITRevisionString() + "]"); + labelLocalGameVersion.setText(glestVersionString); + } + + //vector teamItems, controlItems, results , rMultiplier; + + string ipText = "none"; + std::vector < std::string > ipList = Socket::getLocalIPAddressList(); + if (ipList.empty() == false) { + ipText = ""; + for (int idx = 0; idx < (int) ipList.size(); idx++) { + string ip = ipList[idx]; + if (ipText != "") { + ipText += ", "; + } + ipText += ip; + } + } + string serverPort = config.getString("PortServer", + intToStr + (GameConstants:: + serverPort).c_str()); + string externalPort = + config.getString("PortExternal", serverPort.c_str()); + + labelLocalIP.setText(lang.getString("LanIP") + ipText + " ( " + + serverPort + " / " + externalPort + " )"); + + labelMap.setText(lang.getString("Map")); + + labelMapFilter.setText(lang.getString("MapFilter")); + + labelTileset.setText(lang.getString("Tileset")); + + labelTechTree.setText(lang.getString("TechTree")); + + labelAllowNativeLanguageTechtree.setText(lang.getString + ("AllowNativeLanguageTechtree")); + + labelFogOfWar.setText(lang.getString("FogOfWar")); + + std::vector < std::string > listBoxData; + listBoxData.push_back(lang.getString("Enabled")); + listBoxData.push_back(lang.getString("Explored")); + listBoxData.push_back(lang.getString("Disabled")); + listBoxFogOfWar.setItems(listBoxData); + + // Allow Observers + labelAllowObservers.setText(lang.getString("AllowObservers")); + + // Allow Switch Team Mode + labelEnableSwitchTeamMode. + setText(lang.getString("EnableSwitchTeamMode")); + + labelAllowInGameJoinPlayer.setText(lang.getString + ("AllowInGameJoinPlayer")); + + labelAllowTeamUnitSharing. + setText(lang.getString("AllowTeamUnitSharing")); + labelAllowTeamResourceSharing. + setText(lang.getString("AllowTeamResourceSharing")); + + labelAISwitchTeamAcceptPercent.setText(lang.getString + ("AISwitchTeamAcceptPercent")); + + listBoxData.clear(); + + // Advanced Options + labelAdvanced.setText(lang.getString("AdvancedGameOptions")); + + labelPublishServer.setText(lang.getString("PublishServer")); + + labelGameName.setFont(CoreData::getInstance().getMenuFontBig()); + labelGameName.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + + labelGameName.setText(createGameName()); + + labelNetworkPauseGameForLaggedClients.setText(lang.getString + ("NetworkPauseGameForLaggedClients")); + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + buttonBlockPlayers[i].setText(lang.getString("BlockPlayer")); + } + + labelControl.setText(lang.getString("Control")); + + labelFaction.setText(lang.getString("Faction")); + + labelTeam.setText(lang.getString("Team")); + + labelControl.setFont(CoreData::getInstance().getMenuFontBig()); + labelControl.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelRMultiplier.setFont(CoreData::getInstance().getMenuFontBig()); + labelRMultiplier. + setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelFaction.setFont(CoreData::getInstance().getMenuFontBig()); + labelFaction.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelTeam.setFont(CoreData::getInstance().getMenuFontBig()); + labelTeam.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + + //texts + buttonClearBlockedPlayers.setText(lang.getString("BlockPlayerClear")); + buttonReturn.setText(lang.getString("Return")); + buttonPlayNow.setText(lang.getString("PlayNow")); + buttonRestoreLastSettings.setText(lang.getString + ("ReloadLastGameSettings")); + + vector < string > controlItems; + controlItems.push_back(lang.getString("Closed")); + controlItems.push_back(lang.getString("CpuEasy")); + controlItems.push_back(lang.getString("Cpu")); + controlItems.push_back(lang.getString("CpuUltra")); + controlItems.push_back(lang.getString("CpuZeta")); + controlItems.push_back(lang.getString("Network")); + controlItems.push_back(lang.getString("NetworkUnassigned")); + controlItems.push_back(lang.getString("Human")); + + if (config.getBool("EnableNetworkCpu", "false") == true) { + controlItems.push_back(lang.getString("NetworkCpuEasy")); + controlItems.push_back(lang.getString("NetworkCpu")); + controlItems.push_back(lang.getString("NetworkCpuUltra")); + controlItems.push_back(lang.getString("NetworkCpuZeta")); + } + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + labelPlayers[i].setText(intToStr(i + 1)); + + listBoxControls[i].setItems(controlItems); + } + + labelFallbackCpuMultiplier.setText(lang.getString + ("FallbackCpuMultiplier")); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + vector < string > playerStatuses; + playerStatuses.push_back(lang.getString("PlayerStatusSetup")); + playerStatuses.push_back(lang.getString("PlayerStatusBeRightBack")); + playerStatuses.push_back(lang.getString("PlayerStatusReady")); + listBoxPlayerStatus.setItems(playerStatuses); + + labelScenario.setText(lang.getString("Scenario")); + + reloadFactions(true, + (checkBoxScenario.getValue() == + true ? + scenarioFiles[listBoxScenario.getSelectedItemIndex()] + : "")); + + // write hint to console: + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + + console.addLine(lang.getString("ToSwitchOffMusicPress") + " - \"" + + configKeys.getString("ToggleMusic") + "\""); + + chatManager.init(&console, -1, true); + + GraphicComponent::reloadFontsForRegisterGraphicComponents + (containerName); + } + + void MenuStateCustomGame::cleanupThread(SimpleTaskThread ** thread) { + //printf("LINE: %d *thread = %p\n",__LINE__,*thread); + + if (thread != NULL && *thread != NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\n\n#1 cleanupThread callingThread [%p]\n", *thread); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + SimpleTaskThread *threadPtr = *thread; + int value = threadPtr->getUserdataAsInt(); + THREAD_NOTIFIER_TYPE threadType = (THREAD_NOTIFIER_TYPE) value; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\n\n#1. cleanupThread callingThread [%p] value = %d\n", + *thread, value); + + needToBroadcastServerSettings = false; + needToRepublishToMasterserver = false; + lastNetworkPing = time(NULL); + threadPtr->setThreadOwnerValid(false); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\n\n#1.. cleanupThread callingThread [%p] value = %d\n", + *thread, value); + + if (forceWaitForShutdown == true) { + time_t elapsed = time(NULL); + threadPtr->signalQuit(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\n\n#1a cleanupThread callingThread [%p]\n", *thread); + + for (; (threadPtr->canShutdown(false) == false || + threadPtr->getRunningStatus() == true) && + difftime((long int) time(NULL), elapsed) <= 15;) { + //sleep(150); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\n\n#1b cleanupThread callingThread [%p]\n", *thread); + + if (threadPtr->canShutdown(true) == true && + threadPtr->getRunningStatus() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\n\n#1c cleanupThread callingThread [%p]\n", *thread); + + delete threadPtr; + //printf("LINE: %d *thread = %p\n",__LINE__,*thread); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\n\n#1d cleanupThread callingThread [%p]\n", *thread); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s %d] Error cannot shutdown thread\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("%s", szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", + szBuf); + + if (threadType == tnt_MASTERSERVER) { + threadPtr->setOverrideShutdownTask(shutdownTaskStatic); + } + threadPtr->setDeleteSelfOnExecutionDone(true); + threadPtr->setDeleteAfterExecute(true); + //printf("LINE: %d *thread = %p\n",__LINE__,*thread); + } + threadPtr = NULL; + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1e cleanupThread callingThread [%p]\n",*thread); + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\n\n#1f cleanupThread callingThread [%p]\n", *thread); + threadPtr->signalQuit(); + sleep(0); + if (threadPtr->canShutdown(true) == true && + threadPtr->getRunningStatus() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\n\n#1g cleanupThread callingThread [%p]\n", *thread); + delete threadPtr; + //printf("LINE: %d *thread = %p\n",__LINE__,*thread); + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\n\n#1h cleanupThread callingThread [%p]\n", *thread); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s %d] Error cannot shutdown thread\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("%s", szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", + szBuf); + + if (threadType == tnt_MASTERSERVER) { + threadPtr->setOverrideShutdownTask(shutdownTaskStatic); + } + threadPtr->setDeleteSelfOnExecutionDone(true); + threadPtr->setDeleteAfterExecute(true); + //printf("LINE: %d *thread = %p\n",__LINE__,*thread); + } + } + + *thread = NULL; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\n\n#2 cleanupThread callingThread [%p]\n", *thread); + } + //printf("LINE: %d *thread = %p\n",__LINE__,*thread); + } + + void MenuStateCustomGame::cleanup() { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (publishToMasterserverThread) { + //printf("LINE: %d\n",__LINE__); + cleanupThread(&publishToMasterserverThread); + } + if (publishToClientsThread) { + //printf("LINE: %d\n",__LINE__); + cleanupThread(&publishToClientsThread); + } + + //printf("LINE: %d\n",__LINE__); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + cleanupMapPreviewTexture(); + + if (factionVideo != NULL) { + factionVideo->closePlayer(); + delete factionVideo; + factionVideo = NULL; + } + + if (forceWaitForShutdown == true) { + NetworkManager::getInstance().end(); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + MenuStateCustomGame::~MenuStateCustomGame() { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + + cleanup(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + } + + void MenuStateCustomGame::returnToParentMenu() { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + needToBroadcastServerSettings = false; + needToRepublishToMasterserver = false; + lastNetworkPing = time(NULL); + ParentMenuState parentMenuState = this->parentMenuState; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + forceWaitForShutdown = false; + if (parentMenuState == pMasterServer) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + cleanup(); + mainMenu->setState(new MenuStateMasterserver(program, mainMenu)); + } else if (parentMenuState == pLanGame) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + cleanup(); + mainMenu->setState(new MenuStateJoinGame(program, mainMenu)); + } else { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + cleanup(); + mainMenu->setState(new MenuStateNewGame(program, mainMenu)); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + void MenuStateCustomGame::mouseClick(int x, int y, + MouseButton mouseButton) { + if (isMasterserverMode() == true) { + return; + } + + try { + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + int oldListBoxMapfilterIndex = + listBoxMapFilter.getSelectedItemIndex(); + + if (mainMessageBox.getEnabled()) { + int button = 0; + if (mainMessageBox.mouseClick(x, y, button)) { + soundRenderer.playFx(coreData.getClickSoundA()); + if (button == 0) { + mainMessageBox.setEnabled(false); + } + } + } else { + string advanceToItemStartingWith = ""; + if (::Shared::Platform::Window::isKeyStateModPressed(KMOD_SHIFT) == + true) { + const wchar_t lastKey = ::Shared::Platform:: + Window::extractLastKeyPressed(); + // string helpString = ""; + // helpString = lastKey; + // printf("lastKey = '%s'\n",helpString.c_str()); + advanceToItemStartingWith = lastKey; + } + + if (mapPreviewTexture != NULL) { + // printf("X: %d Y: %d [%d, %d, %d, %d]\n", + // x, y, + // this->render_mapPreviewTexture_X, this->render_mapPreviewTexture_X + this->render_mapPreviewTexture_W, + // this->render_mapPreviewTexture_Y, this->render_mapPreviewTexture_Y + this->render_mapPreviewTexture_H); + + if (x >= this->render_mapPreviewTexture_X + && x <= + this->render_mapPreviewTexture_X + + this->render_mapPreviewTexture_W + && y >= this->render_mapPreviewTexture_Y + && y <= + this->render_mapPreviewTexture_Y + + this->render_mapPreviewTexture_H) { + + if (this->render_mapPreviewTexture_X == + mapPreviewTexture_X + && this->render_mapPreviewTexture_Y == + mapPreviewTexture_Y + && this->render_mapPreviewTexture_W == + mapPreviewTexture_W + && this->render_mapPreviewTexture_H == mapPreviewTexture_H) { + + const Metrics & metrics = Metrics::getInstance(); + + this->render_mapPreviewTexture_X = 0; + this->render_mapPreviewTexture_Y = 0; + this->render_mapPreviewTexture_W = metrics.getVirtualW(); + this->render_mapPreviewTexture_H = metrics.getVirtualH(); + this->zoomedMap = true; + + cleanupMapPreviewTexture(); + } else { + this->render_mapPreviewTexture_X = mapPreviewTexture_X; + this->render_mapPreviewTexture_Y = mapPreviewTexture_Y; + this->render_mapPreviewTexture_W = mapPreviewTexture_W; + this->render_mapPreviewTexture_H = mapPreviewTexture_H; + this->zoomedMap = false; + + cleanupMapPreviewTexture(); + } + return; + } + if (this->zoomedMap == true) { + return; + } + } + + if (activeInputLabel != NULL + && !(activeInputLabel->mouseClick(x, y))) { + setActiveInputLabel(NULL); + } + if (buttonReturn.mouseClick(x, y) || serverInitError == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + soundRenderer.playFx(coreData.getClickSoundA()); + + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + needToBroadcastServerSettings = false; + needToRepublishToMasterserver = false; + lastNetworkPing = time(NULL); + safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + returnToParentMenu(); + return; + } else if (buttonPlayNow.mouseClick(x, y) + && buttonPlayNow.getEnabled()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + PlayNow(true); + return; + } else if (buttonRestoreLastSettings.mouseClick(x, y) + && buttonRestoreLastSettings.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundB()); + + RestoreLastGameSettings(); + } else if (listBoxMap.mouseClick(x, y, advanceToItemStartingWith)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", + getCurrentMapFile().c_str()); + + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + loadMapInfo(Config::getMapPath(getCurrentMapFile(), "", false), + &mapInfo, true); + labelMapInfo.setText(mapInfo.desc); + updateControllers(); + updateNetworkSlots(); + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + //delay publishing for 5 seconds + needToPublishDelayed = true; + mapPublishingDelayTimer = time(NULL); + } + } else if (checkBoxAdvanced.getValue() == 1 + && listBoxFogOfWar.mouseClick(x, y)) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + cleanupMapPreviewTexture(); + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } else if (checkBoxAdvanced.getValue() == 1 + && checkBoxAllowObservers.mouseClick(x, y)) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + reloadFactions(true, + (checkBoxScenario.getValue() == + true ? + scenarioFiles + [listBoxScenario.getSelectedItemIndex()] : "")); + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } else if (checkBoxAllowInGameJoinPlayer.mouseClick(x, y)) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + serverInterface->setAllowInGameConnections + (checkBoxAllowInGameJoinPlayer.getValue() == true); + } else if (checkBoxAdvanced.getValue() == 1 + && checkBoxAllowTeamUnitSharing.mouseClick(x, y)) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } else if (checkBoxAdvanced.getValue() == 1 + && checkBoxAllowTeamResourceSharing.mouseClick(x, y)) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } else if (checkBoxAllowNativeLanguageTechtree.mouseClick(x, y)) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } else if (checkBoxAdvanced.getValue() == 1 + && checkBoxEnableSwitchTeamMode.mouseClick(x, y)) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } else if (checkBoxAdvanced.getValue() == 1 + && listBoxAISwitchTeamAcceptPercent.getEnabled() + && listBoxAISwitchTeamAcceptPercent.mouseClick(x, y)) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } else if (checkBoxAdvanced.getValue() == 1 + && listBoxFallbackCpuMultiplier.getEditable() == true + && listBoxFallbackCpuMultiplier.mouseClick(x, y)) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } else if (checkBoxAdvanced.mouseClick(x, y)) { + } else + if (listBoxTileset.mouseClick(x, y, advanceToItemStartingWith)) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + if (hasNetworkGameSettings() == true) { + + //delay publishing for 5 seconds + needToPublishDelayed = true; + mapPublishingDelayTimer = time(NULL); + } + } else if (listBoxMapFilter.mouseClick(x, y)) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + switchToNextMapGroup(listBoxMapFilter.getSelectedItemIndex() - + oldListBoxMapfilterIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s\n", + getCurrentMapFile().c_str()); + + loadMapInfo(Config::getMapPath(getCurrentMapFile()), + &mapInfo, true); + labelMapInfo.setText(mapInfo.desc); + updateControllers(); + updateNetworkSlots(); + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } else + if (listBoxTechTree.mouseClick(x, y, advanceToItemStartingWith)) { + reloadFactions(listBoxTechTree.getItemCount() <= 1, + (checkBoxScenario.getValue() == + true ? + scenarioFiles + [listBoxScenario.getSelectedItemIndex()] : "")); + + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } else if (checkBoxPublishServer.mouseClick(x, y) + && checkBoxPublishServer.getEditable()) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + needToRepublishToMasterserver = true; + soundRenderer.playFx(coreData.getClickSoundC()); + + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + serverInterface-> + setPublishEnabled(checkBoxPublishServer.getValue() == true); + } else if (labelGameName.mouseClick(x, y) + && checkBoxPublishServer.getEditable()) { + setActiveInputLabel(&labelGameName); + } else if (checkBoxAdvanced.getValue() == 1 + && checkBoxNetworkPauseGameForLaggedClients.mouseClick(x, + y)) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + + soundRenderer.playFx(coreData.getClickSoundC()); + } else if (listBoxScenario.mouseClick(x, y) + || checkBoxScenario.mouseClick(x, y)) { + processScenario(); + } else { + for (int i = 0; i < mapInfo.players; ++i) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + // set multiplier + if (listBoxRMultiplier[i].mouseClick(x, y)) { + //printf("Line: %d multiplier index: %d i: %d itemcount: %d\n",__LINE__,listBoxRMultiplier[i].getSelectedItemIndex(),i,listBoxRMultiplier[i].getItemCount()); + + //for(int indexData = 0; indexData < listBoxRMultiplier[i].getItemCount(); ++indexData) { + //string item = listBoxRMultiplier[i].getItem(indexData); + + //printf("Item index: %d value: %s\n",indexData,item.c_str()); + //} + } + + //ensure thet only 1 human player is present + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + ConnectionSlot *slot = serverInterface->getSlot(i, true); + + bool checkControTypeClicked = false; + int selectedControlItemIndex = + listBoxControls[i].getSelectedItemIndex(); + if (selectedControlItemIndex != ctNetwork + || (selectedControlItemIndex == ctNetwork + && (slot == NULL || slot->isConnected() == false))) { + checkControTypeClicked = true; + } + + //printf("checkControTypeClicked = %d selectedControlItemIndex = %d i = %d\n",checkControTypeClicked,selectedControlItemIndex,i); + + if (selectedControlItemIndex != ctHuman && + checkControTypeClicked == true && + listBoxControls[i].mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + ControlType currentControlType = + static_cast + (listBoxControls[i].getSelectedItemIndex()); + int slotsToChangeStart = i; + int slotsToChangeEnd = i; + // If control is pressed while changing player types then change all other slots to same type + if (::Shared::Platform:: + Window::isKeyStateModPressed(KMOD_CTRL) == true + && currentControlType != ctHuman) { + slotsToChangeStart = 0; + slotsToChangeEnd = mapInfo.players - 1; + } + + for (int index = slotsToChangeStart; + index <= slotsToChangeEnd; ++index) { + if (index != i + && static_cast + (listBoxControls[index].getSelectedItemIndex()) != + ctHuman) { + listBoxControls[index].setSelectedItemIndex + (listBoxControls[i].getSelectedItemIndex()); + } + // Skip over networkunassigned + if (listBoxControls[index].getSelectedItemIndex() == + ctNetworkUnassigned + && selectedControlItemIndex != ctNetworkUnassigned) { + listBoxControls[index].mouseClick(x, y); + } + + //look for human players + int humanIndex1 = -1; + int humanIndex2 = -1; + for (int j = 0; j < GameConstants::maxPlayers; ++j) { + ControlType ct = + static_cast + (listBoxControls[j].getSelectedItemIndex()); + if (ct == ctHuman) { + if (humanIndex1 == -1) { + humanIndex1 = j; + } else { + humanIndex2 = j; + } + } + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] humanIndex1 = %d, humanIndex2 = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + humanIndex1, humanIndex2); + + //no human + if (humanIndex1 == -1 && humanIndex2 == -1) { + setSlotHuman(index); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] i = %d, labelPlayerNames[i].getText() [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, index, + labelPlayerNames + [index].getText().c_str()); + + //printf("humanIndex1 = %d humanIndex2 = %d i = %d listBoxControls[i].getSelectedItemIndex() = %d\n",humanIndex1,humanIndex2,i,listBoxControls[i].getSelectedItemIndex()); + } + //2 humans + else if (humanIndex1 != -1 && humanIndex2 != -1) { + int closeSlotIndex = + (humanIndex1 == index ? humanIndex2 : humanIndex1); + int humanSlotIndex = + (closeSlotIndex == + humanIndex1 ? humanIndex2 : humanIndex1); + + string origPlayName = + labelPlayerNames[closeSlotIndex].getText(); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] closeSlotIndex = %d, origPlayName [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + closeSlotIndex, + origPlayName.c_str()); + + listBoxControls[closeSlotIndex].setSelectedItemIndex + (ctClosed); + setSlotHuman(humanSlotIndex); + labelPlayerNames[humanSlotIndex].setText((origPlayName != + "" ? + origPlayName : + getHumanPlayerName + ())); + } + updateNetworkSlots(); + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + updateResourceMultiplier(index); + } + } else if (buttonClearBlockedPlayers.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundB()); + + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + if (serverInterface != NULL) { + ServerSocket *serverSocket = + serverInterface->getServerSocket(); + if (serverSocket != NULL) { + serverSocket->clearBlockedIPAddress(); + } + } + } else if (buttonBlockPlayers[i].mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundB()); + + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + if (serverInterface != NULL) { + if (serverInterface->getSlot(i, true) != NULL && + serverInterface->getSlot(i, true)->isConnected()) { + + ServerSocket *serverSocket = + serverInterface->getServerSocket(); + if (serverSocket != NULL) { + serverSocket->addIPAddressToBlockedList + (serverInterface->getSlot(i, true)->getIpAddress()); + + Lang & lang = Lang::getInstance(); + const vector < string > languageList = + serverInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages + (); + for (unsigned int j = 0; j < languageList.size(); ++j) { + char szMsg[8096] = ""; + if (lang.hasString("BlockPlayerServerMsg", + languageList[j]) == true) { + snprintf(szMsg, 8096, + lang.getString + ("BlockPlayerServerMsg", + languageList[j]).c_str(), + serverInterface->getSlot(i, + true)->getIpAddress + ().c_str()); + } else { + snprintf(szMsg, 8096, + "The server has temporarily blocked IP Address [%s] from this game.", + serverInterface->getSlot(i, + true)->getIpAddress + ().c_str()); + } + + serverInterface->sendTextMessage(szMsg, -1, true, + languageList[j]); + } + sleep(1); + serverInterface->getSlot(i, true)->close(); + } + } + } + } else + if (listBoxFactions[i].mouseClick + (x, y, advanceToItemStartingWith)) { + // Disallow CPU players to be observers + if (factionFiles + [listBoxFactions[i].getSelectedItemIndex()] == + formatString(GameConstants::OBSERVER_SLOTNAME) + && (listBoxControls[i].getSelectedItemIndex() == + ctCpuEasy + || listBoxControls[i].getSelectedItemIndex() == ctCpu + || listBoxControls[i].getSelectedItemIndex() == + ctCpuUltra + || listBoxControls[i].getSelectedItemIndex() == + ctCpuZeta)) { + listBoxFactions[i].setSelectedItemIndex(0); + } + // + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } else if (listBoxTeams[i].mouseClick(x, y)) { + if (factionFiles + [listBoxFactions[i].getSelectedItemIndex()] != + formatString(GameConstants::OBSERVER_SLOTNAME)) { + if (listBoxTeams[i].getSelectedItemIndex() + 1 != + (GameConstants::maxPlayers + fpt_Observer)) { + lastSelectedTeamIndex[i] = + listBoxTeams[i].getSelectedItemIndex(); + } + } else { + lastSelectedTeamIndex[i] = -1; + } + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL);; + } + } else if (labelPlayerNames[i].mouseClick(x, y)) { + ControlType ct = + static_cast + (listBoxControls[i].getSelectedItemIndex()); + if (ct == ctHuman) { + setActiveInputLabel(&labelPlayerNames[i]); + break; + } + } + } + } + } + + if (hasNetworkGameSettings() == true + && listBoxPlayerStatus.mouseClick(x, y)) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + soundRenderer.playFx(coreData.getClickSoundC()); + if (getNetworkPlayerStatus() == npst_PickSettings) { + listBoxPlayerStatus.setTextColor(Vec3f(1.0f, 0.0f, 0.0f)); + listBoxPlayerStatus.setLighted(true); + } else if (getNetworkPlayerStatus() == npst_BeRightBack) { + listBoxPlayerStatus.setTextColor(Vec3f(1.0f, 1.0f, 0.0f)); + listBoxPlayerStatus.setLighted(true); + } else if (getNetworkPlayerStatus() == npst_Ready) { + listBoxPlayerStatus.setTextColor(Vec3f(0.0f, 1.0f, 0.0f)); + listBoxPlayerStatus.setLighted(false); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + showGeneralError = true; + generalErrorToShow = szBuf; + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + void MenuStateCustomGame::loadGameSettings(const std::string & fileName) { + // Ensure we have set the gamesettings at least once + GameSettings gameSettings = loadGameSettingsFromFile(fileName); + if (gameSettings.getMap() == "") { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + loadGameSettings(&gameSettings); + } + + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + serverInterface->setGameSettings(&gameSettings, false); + + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor() + : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } + + void MenuStateCustomGame::RestoreLastGameSettings() { + loadGameSettings(SAVED_GAME_FILENAME); + } + + bool MenuStateCustomGame::checkNetworkPlayerDataSynch(bool checkMapCRC, + bool + checkTileSetCRC, + bool + checkTechTreeCRC) { + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + + bool dataSynchCheckOk = true; + for (int i = 0; i < mapInfo.players; ++i) { + if (listBoxControls[i].getSelectedItemIndex() == ctNetwork) { + + MutexSafeWrapper safeMutex(serverInterface->getSlotMutex(i), + CODE_AT_LINE); + ConnectionSlot *slot = serverInterface->getSlot(i, false); + if (slot != NULL && slot->isConnected() && + (slot->getAllowDownloadDataSynch() == true || + slot->getAllowGameDataSynchCheck() == true)) { + + if (checkMapCRC == true && + slot->getNetworkGameDataSynchCheckOkMap() == false) { + dataSynchCheckOk = false; + break; + } + if (checkTileSetCRC == true && + slot->getNetworkGameDataSynchCheckOkTile() == false) { + dataSynchCheckOk = false; + break; + } + if (checkTechTreeCRC == true && + slot->getNetworkGameDataSynchCheckOkTech() == false) { + dataSynchCheckOk = false; + break; + } + } + } + } + + return dataSynchCheckOk; + } + + void MenuStateCustomGame::PlayNow(bool saveGame) { + if (listBoxTechTree.getItemCount() <= 0) { + mainMessageBoxState = 1; + + char szMsg[8096] = ""; + strcpy(szMsg, "Cannot start game.\nThere are no tech-trees!\n"); + printf("%s", szMsg); + + showMessageBox(szMsg, "", false); + return; + } + + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor() + : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + if (saveGame == true) { + saveGameSettingsToFile(SAVED_GAME_FILENAME); + } + + forceWaitForShutdown = false; + closeUnusedSlots(); + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + soundRenderer.playFx(coreData.getClickSoundC()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + std::vector < string > randomFactionSelectionList; + int RandomCount = 0; + for (int i = 0; i < mapInfo.players; ++i) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + // Check for random faction selection and choose the faction now + if (listBoxControls[i].getSelectedItemIndex() != ctClosed) { + if (listBoxFactions[i].getSelectedItem() == + formatString(GameConstants::RANDOMFACTION_SLOTNAME) + && listBoxFactions[i].getItemCount() > 1) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] i = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, i); + + // Max 1000 tries to get a random, unused faction + for (int findRandomFaction = 1; findRandomFaction < 1000; + ++findRandomFaction) { + Chrono seed(true); + srand((unsigned int) seed.getCurTicks() + findRandomFaction); + + int selectedFactionIndex = + rand() % listBoxFactions[i].getItemCount(); + string selectedFactionName = + listBoxFactions[i].getItem(selectedFactionIndex); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] selectedFactionName [%s] selectedFactionIndex = %d, findRandomFaction = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, + selectedFactionName.c_str(), + selectedFactionIndex, + findRandomFaction); + + if (selectedFactionName != + formatString(GameConstants::RANDOMFACTION_SLOTNAME) + && selectedFactionName != + formatString(GameConstants::OBSERVER_SLOTNAME) + && std::find(randomFactionSelectionList.begin(), + randomFactionSelectionList.end(), + selectedFactionName) == + randomFactionSelectionList.end()) { + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + listBoxFactions[i].setSelectedItem(selectedFactionName); + randomFactionSelectionList.push_back(selectedFactionName); + break; + } + } + + if (listBoxFactions[i].getSelectedItem() == + formatString(GameConstants::RANDOMFACTION_SLOTNAME)) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] RandomCount = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, RandomCount); + + // Find first real faction and use it + int factionIndexToUse = RandomCount; + for (int useIdx = 0; + useIdx < listBoxFactions[i].getItemCount(); useIdx++) { + string selectedFactionName = + listBoxFactions[i].getItem(useIdx); + if (selectedFactionName != + formatString(GameConstants::RANDOMFACTION_SLOTNAME) + && selectedFactionName != + formatString(GameConstants::OBSERVER_SLOTNAME)) { + factionIndexToUse = useIdx; + break; + } + } + listBoxFactions[i].setSelectedItemIndex(factionIndexToUse); + randomFactionSelectionList.push_back(listBoxFactions[i].getItem + (factionIndexToUse)); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] i = %d, listBoxFactions[i].getSelectedItem() [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, i, + listBoxFactions[i].getSelectedItem(). + c_str()); + + RandomCount++; + } + } + } + + if (RandomCount > 0) { + needToSetChangedGameSettings = true; + } + + safeMutex.ReleaseLock(true); + safeMutexCLI.ReleaseLock(true); + GameSettings gameSettings; + loadGameSettings(&gameSettings, true); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + + // Send the game settings to each client if we have at least one networked client + safeMutex.Lock(); + safeMutexCLI.Lock(); + + bool dataSynchCheckOk = checkNetworkPlayerDataSynch(true, true, true); + + // Ensure we have no dangling network players + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + if (listBoxControls[i].getSelectedItemIndex() == ctNetworkUnassigned) { + mainMessageBoxState = 1; + + Lang & lang = Lang::getInstance(); + string sMsg = ""; + if (lang.hasString("NetworkSlotUnassignedErrorUI") == true) { + sMsg = lang.getString("NetworkSlotUnassignedErrorUI"); + } else { + sMsg = + "Cannot start game.\nSome player(s) are not in a network game slot!"; + } + + showMessageBox(sMsg, "", false); + + const vector < string > languageList = + serverInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int j = 0; j < languageList.size(); ++j) { + char szMsg[8096] = ""; + if (lang.hasString("NetworkSlotUnassignedError", + languageList[j]) == true) { + string msg_string = + lang.getString("NetworkSlotUnassignedError"); #ifdef WIN32 - strncpy (szMsg, msg_string.c_str (), - min ((int) msg_string.length (), 8095)); + strncpy(szMsg, msg_string.c_str(), + min((int) msg_string.length(), 8095)); #else - strncpy (szMsg, msg_string.c_str (), - std::min ((int) msg_string.length (), 8095)); + strncpy(szMsg, msg_string.c_str(), + std::min((int) msg_string.length(), 8095)); #endif - } - else - { - strcpy (szMsg, - "Cannot start game, some player(s) are not in a network game slot!"); - } - - serverInterface->sendTextMessage (szMsg, -1, true, - languageList[j]); - } - - safeMutex.ReleaseLock (); - safeMutexCLI.ReleaseLock (); - return; - } - } - - if (dataSynchCheckOk == false) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - mainMessageBoxState = 1; - showMessageBox - ("You cannot start the game because\none or more clients do not have the same game data!", - "Data Mismatch Error", false); - - safeMutex.ReleaseLock (); - safeMutexCLI.ReleaseLock (); - return; - } - else - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - if ((hasNetworkGameSettings () == true - && needToSetChangedGameSettings == true) || (RandomCount > 0)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - serverInterface->setGameSettings (&gameSettings, true); - serverInterface->broadcastGameSetup (&gameSettings); - - needToSetChangedGameSettings = false; - lastSetChangedGameSettings = time (NULL); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -// Last check, stop human player from being in same slot as network - if (isMasterserverMode () == false) - { - bool hasHuman = false; - for (int i = 0; i < mapInfo.players; ++i) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -// Check for random faction selection and choose the faction now - if (listBoxControls[i].getSelectedItemIndex () == ctHuman) - { - hasHuman = true; - break; - } - } - if (hasHuman == false) - { - mainMessageBoxState = 1; - - Lang & lang = Lang::getInstance (); - string sMsg = - lang.getString ("NetworkSlotNoHumanErrorUI", "", true); - showMessageBox (sMsg, "", false); - - const vector < string > languageList = - serverInterface-> - getGameSettings ()->getUniqueNetworkPlayerLanguages (); - for (unsigned int j = 0; j < languageList.size (); ++j) - { - sMsg = lang.getString ("NetworkSlotNoHumanError", "", true); - - serverInterface->sendTextMessage (sMsg, -1, true, - languageList[j]); - } - - safeMutex.ReleaseLock (); - safeMutexCLI.ReleaseLock (); - return; - } - } - -// Tell the server Interface whether or not to publish game status updates to masterserver - serverInterface->setNeedToRepublishToMasterserver - (checkBoxPublishServer.getValue () == true); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - bool bOkToStart = serverInterface->launchGame (&gameSettings); - if (bOkToStart == true) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (checkBoxPublishServer.getEditable () && - checkBoxPublishServer.getValue () == true) - { - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - needToRepublishToMasterserver = true; - lastMasterserverPublishing = 0; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - needToBroadcastServerSettings = false; - needToRepublishToMasterserver = false; - lastNetworkPing = time (NULL); - safeMutex.ReleaseLock (); - safeMutexCLI.ReleaseLock (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - assert (program != NULL); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - cleanup (); - Game *newGame = - new Game (program, &gameSettings, this->headlessServerMode); - forceWaitForShutdown = false; - program->setState (newGame); - return; - } - else - { - safeMutex.ReleaseLock (); - safeMutexCLI.ReleaseLock (); - } - } - } - - void MenuStateCustomGame::mouseMove (int x, int y, const MouseState * ms) - { - if (isMasterserverMode () == true) - { - return; - } - - if (mainMessageBox.getEnabled ()) - { - mainMessageBox.mouseMove (x, y); - } - buttonReturn.mouseMove (x, y); - buttonPlayNow.mouseMove (x, y); - buttonRestoreLastSettings.mouseMove (x, y); - buttonClearBlockedPlayers.mouseMove (x, y); - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - listBoxRMultiplier[i].mouseMove (x, y); - listBoxControls[i].mouseMove (x, y); - buttonBlockPlayers[i].mouseMove (x, y); - listBoxFactions[i].mouseMove (x, y); - listBoxTeams[i].mouseMove (x, y); - } - - listBoxMap.mouseMove (x, y); - - if (checkBoxAdvanced.getValue () == 1) - { - listBoxFogOfWar.mouseMove (x, y); - checkBoxAllowObservers.mouseMove (x, y); - - checkBoxEnableSwitchTeamMode.mouseMove (x, y); - listBoxAISwitchTeamAcceptPercent.mouseMove (x, y); - listBoxFallbackCpuMultiplier.mouseMove (x, y); - - labelNetworkPauseGameForLaggedClients.mouseMove (x, y); - checkBoxNetworkPauseGameForLaggedClients.mouseMove (x, y); - - labelAllowTeamUnitSharing.mouseMove (x, y); - checkBoxAllowTeamUnitSharing.mouseMove (x, y); - labelAllowTeamResourceSharing.mouseMove (x, y); - checkBoxAllowTeamResourceSharing.mouseMove (x, y); - } - checkBoxAllowInGameJoinPlayer.mouseMove (x, y); - - checkBoxAllowNativeLanguageTechtree.mouseMove (x, y); - - listBoxTileset.mouseMove (x, y); - listBoxMapFilter.mouseMove (x, y); - listBoxTechTree.mouseMove (x, y); - checkBoxPublishServer.mouseMove (x, y); - - checkBoxAdvanced.mouseMove (x, y); - - checkBoxScenario.mouseMove (x, y); - listBoxScenario.mouseMove (x, y); - } - - bool MenuStateCustomGame::isMasterserverMode () const - { - return (this->headlessServerMode == true - && this->masterserverModeMinimalResources == true); -//return false; - } - - bool MenuStateCustomGame::isVideoPlaying () - { - bool result = false; - if (factionVideo != NULL) - { - result = factionVideo->isPlaying (); - } - return result; - } - - void MenuStateCustomGame::render () - { - try - { - Renderer & renderer = Renderer::getInstance (); - - if (mainMessageBox.getEnabled () == false) - { - if (factionTexture != NULL) - { - if (factionVideo == NULL || factionVideo->isPlaying () == false) - { - renderer.renderTextureQuad (800, 600, 200, 150, - factionTexture, 1.0f); - } - } - } - if (factionVideo != NULL) - { - if (factionVideo->isPlaying () == true) - { - factionVideo->playFrame (false); - } - else - { - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == - false - &&::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer () == - true) - { - if (factionVideo != NULL) - { - factionVideo->closePlayer (); - delete factionVideo; - factionVideo = NULL; - - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - if (serverInterface != NULL) - { - initFactionPreview (serverInterface->getGameSettings ()); - } - } - } - } - } - - if (mainMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&mainMessageBox); - - renderer.renderButton (&buttonReturn); - } - else - { - if (mapPreviewTexture != NULL) - { -//renderer.renderTextureQuad(5,185,150,150,mapPreviewTexture,1.0f); - renderer.renderTextureQuad (this->render_mapPreviewTexture_X, - this->render_mapPreviewTexture_Y, - this->render_mapPreviewTexture_W, - this->render_mapPreviewTexture_H, - mapPreviewTexture, 1.0f); - if (this->zoomedMap == true) - { - return; - } -//printf("=================> Rendering map preview texture\n"); - } - if (scenarioLogoTexture != NULL) - { - renderer.renderTextureQuad (300, 350, 400, 300, - scenarioLogoTexture, 1.0f); -//renderer.renderBackground(scenarioLogoTexture); - } - - renderer.renderButton (&buttonReturn); - renderer.renderButton (&buttonPlayNow); - renderer.renderButton (&buttonRestoreLastSettings); - -// Get a reference to the player texture cache - std::map < int, Texture2D * >&crcPlayerTextureCache = - CacheManager::getCachedItem < std::map < int, - Texture2D * > >(GameConstants::playerTextureCacheLookupKey); - -// START - this code ensure player title and player names don't overlap - int offsetPosition = 0; - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - FontMetrics *fontMetrics = NULL; - if (Renderer::renderText3DEnabled == false) - { - fontMetrics = labelPlayers[i].getFont ()->getMetrics (); - } - else - { - fontMetrics = labelPlayers[i].getFont3D ()->getMetrics (); - } - if (fontMetrics == NULL) - { - throw megaglest_runtime_error ("fontMetrics == NULL"); - } - int curWidth = - (fontMetrics->getTextWidth (labelPlayers[i].getText ())); - int newOffsetPosition = labelPlayers[i].getX () + curWidth + 2; - -//printf("labelPlayers[i].getX() = %d curWidth = %d labelPlayerNames[i].getX() = %d offsetPosition = %d newOffsetPosition = %d [%s]\n",labelPlayers[i].getX(),curWidth,labelPlayerNames[i].getX(),offsetPosition,newOffsetPosition,labelPlayers[i].getText().c_str()); - - if (labelPlayers[i].getX () + curWidth >= - labelPlayerNames[i].getX ()) - { - if (offsetPosition < newOffsetPosition) - { - offsetPosition = newOffsetPosition; - } - } - } -// END - - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - if (hasNetworkGameSettings () == true) - { - renderer.renderListBox (&listBoxPlayerStatus); - if (serverInterface != NULL && - serverInterface->getServerSocket () != NULL) - { - renderer.renderButton (&buttonClearBlockedPlayers); - } - } - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - if (listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned) - { -//printf("Player #%d [%s] control = %d\n",i,labelPlayerNames[i].getText().c_str(),listBoxControls[i].getSelectedItemIndex()); - labelPlayers[i].setVisible (true); - labelPlayerNames[i].setVisible (true); - listBoxControls[i].setVisible (true); - listBoxFactions[i].setVisible (true); - listBoxTeams[i].setVisible (true); - labelNetStatus[i].setVisible (true); - } - - if (hasNetworkGameSettings () == true && - listBoxControls[i].getSelectedItemIndex () != ctClosed) - { - - renderer.renderLabel (&labelPlayerStatus[i]); - } - - if (crcPlayerTextureCache[i] != NULL) - { -// Render the player # label the player's color - Vec3f playerColor = - crcPlayerTextureCache[i]->getPixmap ()->getPixel3f (0, - 0); - renderer.renderLabel (&labelPlayers[i], &playerColor); - } - else - { - renderer.renderLabel (&labelPlayers[i]); - } - - if (offsetPosition > 0) - { - labelPlayerNames[i].setX (offsetPosition); - } - renderer.renderLabel (&labelPlayerNames[i]); - - renderer.renderListBox (&listBoxControls[i]); - - if (hasNetworkGameSettings () == true && - listBoxControls[i].getSelectedItemIndex () != ctClosed) - { - - renderer.renderLabel (&labelPlayerStatus[i]); - - if (listBoxControls[i].getSelectedItemIndex () == - ctNetwork - || listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned) - { - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - if (serverInterface != NULL - && serverInterface->getSlot (i, true) != NULL - && serverInterface->getSlot (i, true)->isConnected ()) - { - renderer.renderButton (&buttonBlockPlayers[i]); - } - } - } - - if (listBoxControls[i].getSelectedItemIndex () != ctClosed) - { - renderer.renderListBox (&listBoxRMultiplier[i]); - renderer.renderListBox (&listBoxFactions[i]); - - int teamnumber = listBoxTeams[i].getSelectedItemIndex (); - Vec3f teamcolor = Vec3f (1.0f, 1.0f, 1.0f); - if (teamnumber >= 0 && teamnumber < 8) - { - teamcolor = - crcPlayerTextureCache[teamnumber]-> - getPixmap ()->getPixel3f (0, 0); - } - listBoxTeams[i].setTextColor (teamcolor); - - renderer.renderListBox (&listBoxTeams[i]); - renderer.renderLabel (&labelNetStatus[i]); - } - } - - renderer.renderLabel (&labelLocalGameVersion); - renderer.renderLabel (&labelLocalIP); - renderer.renderLabel (&labelMap); - - if (checkBoxAdvanced.getValue () == 1) - { - renderer.renderLabel (&labelFogOfWar); - renderer.renderLabel (&labelAllowObservers); - renderer.renderLabel (&labelFallbackCpuMultiplier); - - renderer.renderLabel (&labelEnableSwitchTeamMode); - renderer.renderLabel (&labelAISwitchTeamAcceptPercent); - - renderer.renderListBox (&listBoxFogOfWar); - renderer.renderCheckBox (&checkBoxAllowObservers); - - renderer.renderCheckBox (&checkBoxEnableSwitchTeamMode); - renderer.renderListBox (&listBoxAISwitchTeamAcceptPercent); - renderer.renderListBox (&listBoxFallbackCpuMultiplier); - - renderer.renderLabel (&labelAllowTeamUnitSharing); - renderer.renderCheckBox (&checkBoxAllowTeamUnitSharing); - - renderer.renderLabel (&labelAllowTeamResourceSharing); - renderer.renderCheckBox (&checkBoxAllowTeamResourceSharing); - } - renderer.renderLabel (&labelAllowInGameJoinPlayer); - renderer.renderCheckBox (&checkBoxAllowInGameJoinPlayer); - - renderer.renderLabel (&labelTileset); - renderer.renderLabel (&labelMapFilter); - renderer.renderLabel (&labelTechTree); - renderer.renderLabel (&labelControl); - renderer.renderLabel (&labelFaction); - renderer.renderLabel (&labelTeam); - renderer.renderLabel (&labelMapInfo); - renderer.renderLabel (&labelAdvanced); - - renderer.renderListBox (&listBoxMap); - renderer.renderListBox (&listBoxTileset); - renderer.renderListBox (&listBoxMapFilter); - renderer.renderListBox (&listBoxTechTree); - renderer.renderCheckBox (&checkBoxAdvanced); - - if (checkBoxPublishServer.getEditable ()) - { - renderer.renderCheckBox (&checkBoxPublishServer); - renderer.renderLabel (&labelPublishServer); - renderer.renderLabel (&labelGameName); - if (checkBoxAdvanced.getValue () == 1) - { - renderer.renderLabel (&labelNetworkPauseGameForLaggedClients); - renderer.renderCheckBox - (&checkBoxNetworkPauseGameForLaggedClients); - } - } - - renderer.renderCheckBox (&checkBoxScenario); - renderer.renderLabel (&labelScenario); - if (checkBoxScenario.getValue () == true) - { - renderer.renderListBox (&listBoxScenario); - } - - renderer.renderLabel (&labelAllowNativeLanguageTechtree); - renderer.renderCheckBox (&checkBoxAllowNativeLanguageTechtree); - } - - if (program != NULL) - program->renderProgramMsgBox (); - - if (enableMapPreview == true && mapPreview.hasFileLoaded () == true) - { - - if (mapPreviewTexture == NULL) - { - bool renderAll = (listBoxFogOfWar.getSelectedItemIndex () == 2); -//printf("=================> Rendering map preview into a texture BEFORE (%p)\n", mapPreviewTexture); - -//renderer.renderMapPreview(&mapPreview, renderAll, 10, 350,&mapPreviewTexture); - renderer.renderMapPreview (&mapPreview, renderAll, - this->render_mapPreviewTexture_X, - this->render_mapPreviewTexture_Y, - &mapPreviewTexture); - -//printf("=================> Rendering map preview into a texture AFTER (%p)\n", mapPreviewTexture); - } - } - - if (mainMessageBox.getEnabled () == false) - { - if (hasNetworkGameSettings () == true) - { - renderer.renderChatManager (&chatManager); - } - } - renderer.renderConsole (&console, - showFullConsole ? consoleFull : - consoleStoredAndNormal); - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); -//throw megaglest_runtime_error(szBuf); - - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - showGeneralError = true; - generalErrorToShow = szBuf; - } - } - - void MenuStateCustomGame::switchSetupForSlots (SwitchSetupRequest ** - switchSetupRequests, - ServerInterface * - &serverInterface, - int startIndex, - int endIndex, - bool onlyNetworkUnassigned) - { - for (int i = startIndex; i < endIndex; ++i) - { - if (switchSetupRequests[i] != NULL) - { -//printf("Switch slot = %d control = %d newIndex = %d currentindex = %d onlyNetworkUnassigned = %d\n",i,listBoxControls[i].getSelectedItemIndex(),switchSetupRequests[i]->getToFactionIndex(),switchSetupRequests[i]->getCurrentFactionIndex(),onlyNetworkUnassigned); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] switchSetupRequests[i]->getSwitchFlags() = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - switchSetupRequests[i]->getSwitchFlags - ()); - - if (onlyNetworkUnassigned == true - && listBoxControls[i].getSelectedItemIndex () != - ctNetworkUnassigned) - { - if (i < mapInfo.players - || (i >= mapInfo.players - && listBoxControls[i].getSelectedItemIndex () != - ctNetwork)) - { - continue; - } - } - - if (listBoxControls[i].getSelectedItemIndex () == ctNetwork - || listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] switchSetupRequests[i]->getToFactionIndex() = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, - switchSetupRequests[i]->getToSlotIndex - ()); - - if (switchSetupRequests[i]->getToSlotIndex () != -1) - { - int newFactionIdx = switchSetupRequests[i]->getToSlotIndex (); - -//printf("switchSlot request from %d to %d\n",switchSetupRequests[i]->getCurrentFactionIndex(),switchSetupRequests[i]->getToFactionIndex()); - int switchFactionIdx = - switchSetupRequests[i]->getCurrentSlotIndex (); - if (serverInterface->switchSlot - (switchFactionIdx, newFactionIdx)) - { - try - { - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - ConnectionSlot *slot = - serverInterface->getSlot (newFactionIdx, true); - - if (switchSetupRequests[i]->getSelectedFactionName () != "" - && (slot != NULL - && switchSetupRequests[i]->getSelectedFactionName () - != Lang::getInstance ().getString ("DataMissing", - slot->getNetworkPlayerLanguage - (), true) - && switchSetupRequests[i]->getSelectedFactionName () - != "???DataMissing???")) - { - // I don't believe we need to check to see if Observers - // are allowed. If it's not, there should be not button on the client - // side that would allow them to switch to a slot > mapInfo.hardMaxPlayers - if (newFactionIdx <= mapInfo.hardMaxPlayers) - { - - listBoxFactions[newFactionIdx].setSelectedItem - (switchSetupRequests[i]->getSelectedFactionName ()); - } - else - { - listBoxFactions[newFactionIdx].setSelectedItem (GameConstants::OBSERVER_SLOTNAME); - } - - } - if (switchSetupRequests[i]->getToTeam () != -1) - { - if (newFactionIdx <= mapInfo.hardMaxPlayers) - { - listBoxTeams[newFactionIdx].setSelectedItemIndex - (switchSetupRequests[i]->getToTeam ()); - } - else - { - listBoxTeams[i].setSelectedItem (intToStr (GameConstants::maxPlayers + - fpt_Observer)); - } - } - if (switchSetupRequests[i]->getNetworkPlayerName () != "") - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] i = %d, labelPlayerNames[newFactionIdx].getText() [%s] switchSetupRequests[i]->getNetworkPlayerName() [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, i, - labelPlayerNames - [newFactionIdx].getText - ().c_str (), - switchSetupRequests - [i]->getNetworkPlayerName (). - c_str ()); - labelPlayerNames[newFactionIdx].setText - (switchSetupRequests[i]->getNetworkPlayerName ()); - } - - if (listBoxControls[switchFactionIdx].getSelectedItemIndex - () == ctNetworkUnassigned) - { - serverInterface->removeSlot (switchFactionIdx); - listBoxControls[switchFactionIdx].setSelectedItemIndex - (ctClosed); - - labelPlayers[switchFactionIdx].setVisible - (switchFactionIdx + 1 <= mapInfo.players); - labelPlayerNames[switchFactionIdx].setVisible - (switchFactionIdx + 1 <= mapInfo.players); - listBoxControls[switchFactionIdx].setVisible - (switchFactionIdx + 1 <= mapInfo.players); - listBoxFactions[switchFactionIdx].setVisible - (switchFactionIdx + 1 <= mapInfo.players); - listBoxTeams[switchFactionIdx].setVisible - (switchFactionIdx + 1 <= mapInfo.players); - labelNetStatus[switchFactionIdx].setVisible - (switchFactionIdx + 1 <= mapInfo.players); - } - } - catch (const runtime_error & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - e.what ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] caught exception error = [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - e.what ()); - } - } - } - else - { - try - { - int factionIdx = - switchSetupRequests[i]->getCurrentSlotIndex (); - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - ConnectionSlot *slot = - serverInterface->getSlot (factionIdx, true); - - if (switchSetupRequests[i]->getSelectedFactionName () != "" - && (slot != NULL - && switchSetupRequests[i]->getSelectedFactionName () - != Lang::getInstance ().getString ("DataMissing", - slot->getNetworkPlayerLanguage - (), true) - && switchSetupRequests[i]->getSelectedFactionName () - != "???DataMissing???")) - { - listBoxFactions[i].setSelectedItem (switchSetupRequests - [i]->getSelectedFactionName - ()); - } - if (switchSetupRequests[i]->getToTeam () != -1) - { - listBoxTeams[i].setSelectedItemIndex (switchSetupRequests - [i]->getToTeam ()); - } - - if ((switchSetupRequests[i]->getSwitchFlags () & - ssrft_NetworkPlayerName) == ssrft_NetworkPlayerName) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] i = %d, switchSetupRequests[i]->getSwitchFlags() = %d, switchSetupRequests[i]->getNetworkPlayerName() [%s], labelPlayerNames[i].getText() [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, i, - switchSetupRequests - [i]->getSwitchFlags (), - switchSetupRequests - [i]->getNetworkPlayerName (). - c_str (), - labelPlayerNames[i].getText (). - c_str ()); - - if (switchSetupRequests[i]->getNetworkPlayerName () != - GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) - { - labelPlayerNames[i].setText (switchSetupRequests - [i]->getNetworkPlayerName - ()); - } - else - { - labelPlayerNames[i].setText (""); - } - } - } - catch (const runtime_error & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, e.what ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] caught exception error = [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, e.what ()); - } - } - } - - delete switchSetupRequests[i]; - switchSetupRequests[i] = NULL; - } - } - } - - void MenuStateCustomGame::initFactionPreview (const GameSettings * - gameSettings) - { - string factionVideoUrl = ""; - string factionVideoUrlFallback = ""; - - string factionDefinitionXML = - Game::findFactionLogoFile (gameSettings, NULL, - currentFactionName_factionPreview + - ".xml"); - if (factionDefinitionXML != "" - && currentFactionName_factionPreview != - GameConstants::RANDOMFACTION_SLOTNAME - && currentFactionName_factionPreview != - GameConstants::OBSERVER_SLOTNAME - && fileExists (factionDefinitionXML) == true) - { - XmlTree xmlTree; - std::map < string, string > mapExtraTagReplacementValues; - xmlTree.load (factionDefinitionXML, - Properties::getTagReplacementValues - (&mapExtraTagReplacementValues)); - const XmlNode *factionNode = xmlTree.getRootNode (); - if (factionNode->hasAttribute ("faction-preview-video") == true) - { - factionVideoUrl = - factionNode->getAttribute ("faction-preview-video")->getValue (); - } - - factionVideoUrlFallback = - Game::findFactionLogoFile (gameSettings, NULL, "preview_video.*"); - if (factionVideoUrl == "") - { - factionVideoUrl = factionVideoUrlFallback; - factionVideoUrlFallback = ""; - } - } -//printf("currentFactionName_factionPreview [%s] random [%s] observer [%s] factionVideoUrl [%s]\n",currentFactionName_factionPreview.c_str(),GameConstants::RANDOMFACTION_SLOTNAME,GameConstants::OBSERVER_SLOTNAME,factionVideoUrl.c_str()); - - - if (factionVideoUrl != "") - { -//SoundRenderer &soundRenderer= SoundRenderer::getInstance(); - if (CoreData::getInstance ().getMenuMusic ()->getVolume () != 0) - { - CoreData::getInstance ().getMenuMusic ()->setVolume (0); - factionVideoSwitchedOffVolume = true; - } - - if (currentFactionLogo != factionVideoUrl) - { - currentFactionLogo = factionVideoUrl; - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false - &&::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer () == - true) - { - - if (factionVideo != NULL) - { - factionVideo->closePlayer (); - delete factionVideo; - factionVideo = NULL; - } - string introVideoFile = factionVideoUrl; - string introVideoFileFallback = factionVideoUrlFallback; - - Context *c = - GraphicsInterface::getInstance ().getCurrentContext (); - SDL_Window *window = - static_cast < - ContextGl * - >(c)->getPlatformContextGlPtr ()->getScreenWindow (); - SDL_Surface *screen = - static_cast < - ContextGl * - >(c)->getPlatformContextGlPtr ()->getScreenSurface (); - - string vlcPluginsPath = - Config::getInstance ().getString ("VideoPlayerPluginsPath", ""); -//printf("screen->w = %d screen->h = %d screen->format->BitsPerPixel = %d\n",screen->w,screen->h,screen->format->BitsPerPixel); - factionVideo = new VideoPlayer (&Renderer::getInstance (), - introVideoFile, - introVideoFileFallback, - window, - 0, 0, - screen->w, - screen->h, - screen->format->BitsPerPixel, - true, vlcPluginsPath, - SystemFlags::VERBOSE_MODE_ENABLED); - factionVideo->initPlayer (); - } - } - } - else - { -//SoundRenderer &soundRenderer= SoundRenderer::getInstance(); -//switch on music again!! - Config & config = Config::getInstance (); - float configVolume = (config.getInt ("SoundVolumeMusic") / 100.f); - if (factionVideoSwitchedOffVolume) - { - if (CoreData::getInstance ().getMenuMusic ()->getVolume () != - configVolume) - { - CoreData::getInstance (). - getMenuMusic ()->setVolume (configVolume); - } - factionVideoSwitchedOffVolume = false; - } - - if (factionVideo != NULL) - { - factionVideo->closePlayer (); - delete factionVideo; - factionVideo = NULL; - } - } - - if (factionVideo == NULL) - { - string factionLogo = Game::findFactionLogoFile (gameSettings, NULL, - GameConstants::PREVIEW_SCREEN_FILE_FILTER); - if (factionLogo == "") - { - factionLogo = Game::findFactionLogoFile (gameSettings, NULL); - } - if (currentFactionLogo != factionLogo) - { - currentFactionLogo = factionLogo; - loadFactionTexture (currentFactionLogo); - } - } - } - - void MenuStateCustomGame::publishToMasterserver () - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - int slotCountUsed = 0; - int slotCountHumans = 0; - int slotCountConnectedPlayers = 0; - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - GameSettings gameSettings; - loadGameSettings (&gameSettings); - Config & config = Config::getInstance (); -//string serverinfo=""; - - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - publishToServerInfo.clear (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - for (int i = 0; i < mapInfo.players; ++i) - { - if (listBoxControls[i].getSelectedItemIndex () != ctClosed) - { - slotCountUsed++; - } - - if (listBoxControls[i].getSelectedItemIndex () == ctNetwork - || listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned) - { - slotCountHumans++; - if (serverInterface->getSlot (i, true) != NULL && - serverInterface->getSlot (i, true)->isConnected ()) - { - slotCountConnectedPlayers++; - } - } - else if (listBoxControls[i].getSelectedItemIndex () == ctHuman) - { - slotCountHumans++; - slotCountConnectedPlayers++; - } - } - - publishToServerInfo["uuid"] = - Config::getInstance ().getString ("PlayerId", ""); - -//?status=waiting&system=linux&info=titus - publishToServerInfo["glestVersion"] = glestVersionString; - publishToServerInfo["platform"] = - getPlatformNameString (); - publishToServerInfo["binaryCompileDate"] = getCompileDateTime (); - -//game info: - publishToServerInfo["serverTitle"] = gameSettings.getGameName (); -//ip is automatically set - -//game setup info: - -//publishToServerInfo["tech"] = listBoxTechTree.getSelectedItem(); - publishToServerInfo["tech"] = - techTreeFiles[listBoxTechTree.getSelectedItemIndex ()]; -//publishToServerInfo["map"] = listBoxMap.getSelectedItem(); - publishToServerInfo["map"] = getCurrentMapFile (); -//publishToServerInfo["tileset"] = listBoxTileset.getSelectedItem(); - publishToServerInfo["tileset"] = - tilesetFiles[listBoxTileset.getSelectedItemIndex ()]; - - publishToServerInfo["activeSlots"] = intToStr (slotCountUsed); - publishToServerInfo["networkSlots"] = intToStr (slotCountHumans); - publishToServerInfo["connectedClients"] = - intToStr (slotCountConnectedPlayers); - - string serverPort = config.getString ("PortServer", - intToStr - (GameConstants:: - serverPort).c_str ()); - string externalPort = - config.getString ("PortExternal", serverPort.c_str ()); - publishToServerInfo["externalconnectport"] = externalPort; - publishToServerInfo["privacyPlease"] = - intToStr (config.getBool ("PrivacyPlease", "false")); - - publishToServerInfo["gameStatus"] = - intToStr (game_status_waiting_for_players); - if (slotCountHumans <= slotCountConnectedPlayers) - { - publishToServerInfo["gameStatus"] = - intToStr (game_status_waiting_for_start); - } - - publishToServerInfo["gameUUID"] = gameSettings.getGameUUID (); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - void MenuStateCustomGame::setupTask (BaseThread * callingThread, - void *userdata) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\n\nsetupTask callingThread [%p] userdata [%p]\n", - callingThread, userdata); - if (userdata != NULL) - { - int value = *((int *) &userdata); - THREAD_NOTIFIER_TYPE threadType = (THREAD_NOTIFIER_TYPE) value; -//printf("\n\nsetupTask callingThread [%p] userdata [%p]\n",callingThread,userdata); - if (threadType == tnt_MASTERSERVER) - { - MenuStateCustomGame::setupTaskStatic (callingThread); - } - } - } - void MenuStateCustomGame::shutdownTask (BaseThread * callingThread, - void *userdata) - { -//printf("\n\nshutdownTask callingThread [%p] userdata [%p]\n",callingThread,userdata); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("\n\nshutdownTask callingThread [%p] userdata [%p]\n", - callingThread, userdata); - if (userdata != NULL) - { - int value = *((int *) &userdata); - THREAD_NOTIFIER_TYPE threadType = (THREAD_NOTIFIER_TYPE) value; -//printf("\n\nshutdownTask callingThread [%p] userdata [%p]\n",callingThread,userdata); - if (threadType == tnt_MASTERSERVER) - { - MenuStateCustomGame::shutdownTaskStatic (callingThread); - } - } - } - void MenuStateCustomGame::setupTaskStatic (BaseThread * callingThread) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - - CURL *handle = SystemFlags::initHTTP (); - callingThread->setGenericData < CURL > (handle); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - } - void MenuStateCustomGame::shutdownTaskStatic (BaseThread * callingThread) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - -//printf("LINE: %d\n",__LINE__); - CURL *handle = callingThread->getGenericData < CURL > (); - SystemFlags::cleanupHTTP (&handle); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - } - - void MenuStateCustomGame::simpleTask (BaseThread * callingThread, - void *userdata) - { -//printf("\n\nSimple Task callingThread [%p] userdata [%p]\n",callingThread,userdata); - int value = *((int *) &userdata); -//printf("\n\nSimple Task callingThread [%p] userdata [%p] value = %d\n",callingThread,userdata,value); - - THREAD_NOTIFIER_TYPE threadType = (THREAD_NOTIFIER_TYPE) value; - if (threadType == tnt_MASTERSERVER) - { - simpleTaskForMasterServer (callingThread); - } - else if (threadType == tnt_CLIENTS) - { - simpleTaskForClients (callingThread); - } - } - - void MenuStateCustomGame::simpleTaskForMasterServer (BaseThread * - callingThread) - { - try - { -//printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - A\n"); - - MutexSafeWrapper - safeMutexThreadOwner (callingThread->getMutexThreadOwnerValid (), - string (__FILE__) + "_" + - intToStr (__LINE__)); - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - return; - } - -//printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - B\n"); - - MutexSafeWrapper - safeMutex (callingThread->getMutexThreadObjectAccessor (), - string (__FILE__) + "_" + intToStr (__LINE__)); - bool republish = (needToRepublishToMasterserver == true - && publishToServerInfo.empty () == false); - needToRepublishToMasterserver = false; - std::map < string, string > newPublishToServerInfo = - publishToServerInfo; - publishToServerInfo.clear (); - -//printf("simpleTask broadCastSettings = %d\n",broadCastSettings); - - if (callingThread->getQuitStatus () == true) - { - return; - } - -//printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - C\n"); - - if (republish == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - string request = Config::getInstance ().getString ("Masterserver"); - if (request != "") - { - endPathWithSlash (request, false); - } - request += "addServerInfo.php?"; - -//CURL *handle = SystemFlags::initHTTP(); - CURL *handle = callingThread->getGenericData < CURL > (); - - int paramIndex = 0; - for (std::map < string, string >::const_iterator iterMap = - newPublishToServerInfo.begin (); - iterMap != newPublishToServerInfo.end (); ++iterMap) - { - - request += iterMap->first; - request += "="; - request += SystemFlags::escapeURL (iterMap->second, handle); - - paramIndex++; - if (paramIndex < (int) newPublishToServerInfo.size ()) - { - request += "&"; - } - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("The Lobby request is:\n%s\n", request.c_str ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] the request is:\n%s\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - request.c_str ()); - safeMutex.ReleaseLock (true); - safeMutexThreadOwner.ReleaseLock (); - - std::string serverInfo = SystemFlags::getHTTP (request, handle); -//SystemFlags::cleanupHTTP(&handle); - - MutexSafeWrapper - safeMutexThreadOwner2 (callingThread->getMutexThreadOwnerValid (), - string (__FILE__) + "_" + - intToStr (__LINE__)); - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner2.isValidMutex () == false) - { - return; - } - safeMutex.Lock (); - -//printf("the result is:\n'%s'\n",serverInfo.c_str()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] the result is:\n'%s'\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - serverInfo.c_str ()); - -// uncomment to enable router setup check of this server - if (EndsWith (serverInfo, "OK") == false) - { - if (callingThread->getQuitStatus () == true) - { - return; - } - -// Give things another chance to see if we can get a connection from the master server - if (tMasterserverErrorElapsed > 0 && - difftime ((long int) time (NULL), - tMasterserverErrorElapsed) > - MASTERSERVER_BROADCAST_MAX_WAIT_RESPONSE_SECONDS) - { - showMasterserverError = true; - masterServererErrorToShow = - (serverInfo != "" ? serverInfo : "No Reply"); - } - else - { - if (tMasterserverErrorElapsed == 0) - { - tMasterserverErrorElapsed = time (NULL); - } - - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line %d] error checking response from masterserver elapsed seconds = %.2f / %d\nResponse:\n%s\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, __LINE__, - difftime ((long int) - time (NULL), - tMasterserverErrorElapsed), - MASTERSERVER_BROADCAST_MAX_WAIT_RESPONSE_SECONDS, - serverInfo.c_str ()); - - needToRepublishToMasterserver = true; - } - } - } - else - { - safeMutexThreadOwner.ReleaseLock (); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - D\n"); - - safeMutex.ReleaseLock (); - -//printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - F\n"); - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - if (callingThread->getQuitStatus () == false) - { -//throw megaglest_runtime_error(szBuf); - showGeneralError = true; - generalErrorToShow = ex.what (); - } - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - void MenuStateCustomGame::simpleTaskForClients (BaseThread * - callingThread) - { - try - { -//printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - A\n"); - - MutexSafeWrapper - safeMutexThreadOwner (callingThread->getMutexThreadOwnerValid (), - string (__FILE__) + "_" + - intToStr (__LINE__)); - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - return; - } - -//printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - B\n"); - - MutexSafeWrapper - safeMutex (callingThread->getMutexThreadObjectAccessor (), - string (__FILE__) + "_" + intToStr (__LINE__)); - bool broadCastSettings = needToBroadcastServerSettings; - -//printf("simpleTask broadCastSettings = %d\n",broadCastSettings); - - needToBroadcastServerSettings = false; - bool hasClientConnection = false; - - if (broadCastSettings == true) - { - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (false); - if (serverInterface != NULL) - { - hasClientConnection = serverInterface->hasClientConnection (); - } - } - bool needPing = - (difftime ((long int) time (NULL), lastNetworkPing) >= - GameConstants::networkPingInterval); - - if (callingThread->getQuitStatus () == true) - { - return; - } - -//printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - C\n"); - - safeMutexThreadOwner.ReleaseLock (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - D\n"); - - if (broadCastSettings == true) - { - MutexSafeWrapper - safeMutexThreadOwner2 (callingThread->getMutexThreadOwnerValid (), - string (__FILE__) + "_" + - intToStr (__LINE__)); - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner2.isValidMutex () == false) - { - return; - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - -//printf("simpleTask broadCastSettings = %d hasClientConnection = %d\n",broadCastSettings,hasClientConnection); - - if (callingThread->getQuitStatus () == true) - { - return; - } - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (false); - if (serverInterface != NULL) - { - lastGameSettingsreceivedCount++; - if (this->headlessServerMode == false - || (serverInterface->getGameSettingsUpdateCount () <= - lastMasterServerSettingsUpdateCount)) - { - GameSettings gameSettings; - loadGameSettings (&gameSettings); - -//printf("\n\n\n\n=====#2 got settings [%d] [%d]:\n%s\n",lastMasterServerSettingsUpdateCount,serverInterface->getGameSettingsUpdateCount(),gameSettings.toString().c_str()); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - serverInterface->setGameSettings (&gameSettings, false); - lastMasterServerSettingsUpdateCount = - serverInterface->getGameSettingsUpdateCount (); - - if (hasClientConnection == true) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - serverInterface->broadcastGameSetup (&gameSettings); - } - } - } - } - -//printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - E\n"); - - if (needPing == true) - { - MutexSafeWrapper - safeMutexThreadOwner2 (callingThread->getMutexThreadOwnerValid (), - string (__FILE__) + "_" + - intToStr (__LINE__)); - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner2.isValidMutex () == false) - { - return; - } - - lastNetworkPing = time (NULL); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] Sending nmtPing to clients\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (false); - if (serverInterface != NULL) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - NetworkMessagePing *msg = - new NetworkMessagePing (GameConstants::networkPingInterval, - time (NULL)); -//serverInterface->broadcastPing(&msg); - serverInterface->queueBroadcastMessage (msg); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - } - safeMutex.ReleaseLock (); - -//printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - F\n"); - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - if (callingThread->getQuitStatus () == false) - { -//throw megaglest_runtime_error(szBuf); - showGeneralError = true; - generalErrorToShow = ex.what (); - } - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - void MenuStateCustomGame::loadGameSettings (GameSettings * gameSettings, - bool forceCloseUnusedSlots) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - int factionCount = 0; - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (this->headlessServerMode == true - && serverInterface->getGameSettingsUpdateCount () > - lastMasterServerSettingsUpdateCount - && serverInterface->getGameSettings () != NULL) - { - const GameSettings *settings = serverInterface->getGameSettings (); -//printf("\n\n\n\n=====#3 got settings [%d] [%d]:\n%s\n",lastMasterServerSettingsUpdateCount,serverInterface->getGameSettingsUpdateCount(),settings->toString().c_str()); - - lastMasterServerSettingsUpdateCount = - serverInterface->getGameSettingsUpdateCount (); -//printf("#1 custom menu got map [%s]\n",settings->getMap().c_str()); - - setupUIFromGameSettings (*settings); - } - - gameSettings->setGameName (labelGameName.getText ()); - -// Test flags values -//gameSettings->setFlagTypes1(ft1_show_map_resources); -// - - if (checkBoxScenario.getValue () == true) - { - gameSettings->setScenario (scenarioInfo.name); - gameSettings->setScenarioDir (Scenario::getScenarioPath - (dirList, scenarioInfo.name)); - - gameSettings->setDefaultResources (scenarioInfo.defaultResources); - gameSettings->setDefaultUnits (scenarioInfo.defaultUnits); - gameSettings-> - setDefaultVictoryConditions (scenarioInfo.defaultVictoryConditions); - } - else - { - gameSettings->setScenario (""); - gameSettings->setScenarioDir (""); - } - - gameSettings->setGameUUID (this->gameUUID); - -//printf("scenarioInfo.name [%s] [%s] [%s]\n",scenarioInfo.name.c_str(),listBoxMap.getSelectedItem().c_str(),getCurrentMapFile().c_str()); - - gameSettings->setMapFilter (listBoxMapFilter.getSelectedItemIndex ()); - gameSettings->setDescription (formatString (getCurrentMapFile ())); - gameSettings->setMap (getCurrentMapFile ()); - if (tilesetFiles.empty () == false) - { - gameSettings->setTileset (tilesetFiles - [listBoxTileset.getSelectedItemIndex ()]); - } - if (techTreeFiles.empty () == false) - { - gameSettings->setTech (techTreeFiles - [listBoxTechTree.getSelectedItemIndex ()]); - } - - if (autoStartSettings != NULL) - { - gameSettings->setDefaultUnits (autoStartSettings->getDefaultUnits ()); - gameSettings-> - setDefaultResources (autoStartSettings->getDefaultResources ()); - gameSettings-> - setDefaultVictoryConditions - (autoStartSettings->getDefaultVictoryConditions ()); - } - else if (checkBoxScenario.getValue () == false) - { - gameSettings->setDefaultUnits (true); - gameSettings->setDefaultResources (true); - gameSettings->setDefaultVictoryConditions (true); - } - - gameSettings->setFogOfWar (listBoxFogOfWar.getSelectedItemIndex () == 0 - || listBoxFogOfWar.getSelectedItemIndex () == - 1); - - gameSettings->setAllowObservers (checkBoxAllowObservers.getValue () == - 1); - - uint32 valueFlags1 = gameSettings->getFlagTypes1 (); - if (listBoxFogOfWar.getSelectedItemIndex () == 1 || - listBoxFogOfWar.getSelectedItemIndex () == 2) - { - valueFlags1 |= ft1_show_map_resources; - gameSettings->setFlagTypes1 (valueFlags1); - } - else - { - valueFlags1 &= ~ft1_show_map_resources; - gameSettings->setFlagTypes1 (valueFlags1); - } - -//gameSettings->setEnableObserverModeAtEndGame(listBoxEnableObserverMode.getSelectedItemIndex() == 0); - gameSettings->setEnableObserverModeAtEndGame (true); -//gameSettings->setPathFinderType(static_cast(listBoxPathFinderType.getSelectedItemIndex())); - - valueFlags1 = gameSettings->getFlagTypes1 (); - if (checkBoxEnableSwitchTeamMode.getValue () == true) - { - valueFlags1 |= ft1_allow_team_switching; - gameSettings->setFlagTypes1 (valueFlags1); - } - else - { - valueFlags1 &= ~ft1_allow_team_switching; - gameSettings->setFlagTypes1 (valueFlags1); - } - gameSettings->setAiAcceptSwitchTeamPercentChance (strToInt - (listBoxAISwitchTeamAcceptPercent.getSelectedItem - ())); - gameSettings-> - setFallbackCpuMultiplier - (listBoxFallbackCpuMultiplier.getSelectedItemIndex ()); - - if (checkBoxAllowInGameJoinPlayer.getValue () == true) - { - valueFlags1 |= ft1_allow_in_game_joining; - gameSettings->setFlagTypes1 (valueFlags1); - } - else - { - valueFlags1 &= ~ft1_allow_in_game_joining; - gameSettings->setFlagTypes1 (valueFlags1); - } - - if (checkBoxAllowTeamUnitSharing.getValue () == true) - { - valueFlags1 |= ft1_allow_shared_team_units; - gameSettings->setFlagTypes1 (valueFlags1); - } - else - { - valueFlags1 &= ~ft1_allow_shared_team_units; - gameSettings->setFlagTypes1 (valueFlags1); - } - - if (checkBoxAllowTeamResourceSharing.getValue () == true) - { - valueFlags1 |= ft1_allow_shared_team_resources; - gameSettings->setFlagTypes1 (valueFlags1); - } - else - { - valueFlags1 &= ~ft1_allow_shared_team_resources; - gameSettings->setFlagTypes1 (valueFlags1); - } - - if (Config::getInstance ().getBool ("EnableNetworkGameSynchChecks", - "false") == true) - { -//printf("*WARNING* - EnableNetworkGameSynchChecks is enabled\n"); - - valueFlags1 |= ft1_network_synch_checks_verbose; - gameSettings->setFlagTypes1 (valueFlags1); - - } - else - { - valueFlags1 &= ~ft1_network_synch_checks_verbose; - gameSettings->setFlagTypes1 (valueFlags1); - - } - if (Config::getInstance ().getBool ("EnableNetworkGameSynchMonitor", - "false") == true) - { -//printf("*WARNING* - EnableNetworkGameSynchChecks is enabled\n"); - - valueFlags1 |= ft1_network_synch_checks; - gameSettings->setFlagTypes1 (valueFlags1); - - } - else - { - valueFlags1 &= ~ft1_network_synch_checks; - gameSettings->setFlagTypes1 (valueFlags1); - - } - - gameSettings->setNetworkAllowNativeLanguageTechtree - (checkBoxAllowNativeLanguageTechtree.getValue ()); - -// First save Used slots -//for(int i=0; iheadlessServerMode == true) - { -// switch slot to network, because no human in headless mode - listBoxControls[i].setSelectedItemIndex (ctNetwork); - updateResourceMultiplier (i); - } - - ControlType ct = - static_cast < ControlType > - (listBoxControls[i].getSelectedItemIndex ()); - - if (forceCloseUnusedSlots == true - && (ct == ctNetworkUnassigned || ct == ctNetwork)) - { - if (serverInterface != NULL && - (serverInterface->getSlot (i, true) == NULL || - serverInterface->getSlot (i, true)->isConnected () == false)) - { - if (checkBoxScenario.getValue () == false) - { -//printf("Closed A [%d] [%s]\n",i,labelPlayerNames[i].getText().c_str()); - - listBoxControls[i].setSelectedItemIndex (ctClosed); - ct = ctClosed; - } - } - } - else if (ct == ctNetworkUnassigned && i < mapInfo.players) - { - listBoxControls[i].setSelectedItemIndex (ctNetwork); - ct = ctNetwork; - } - - if (ct != ctClosed) - { - int slotIndex = factionCount; - gameSettings->setFactionControl (slotIndex, ct); - if (ct == ctHuman) - { - -// I'm putting this inside a ppd for now. I don't see it needs to be -// built in unless DEBUG is defined during building -andy5995 2018-01-26 + } else { + strcpy(szMsg, + "Cannot start game, some player(s) are not in a network game slot!"); + } + + serverInterface->sendTextMessage(szMsg, -1, true, + languageList[j]); + } + + safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); + return; + } + } + + if (dataSynchCheckOk == false) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + mainMessageBoxState = 1; + showMessageBox + ("You cannot start the game because\none or more clients do not have the same game data!", + "Data Mismatch Error", false); + + safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); + return; + } else { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + if ((hasNetworkGameSettings() == true + && needToSetChangedGameSettings == true) || (RandomCount > 0)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + serverInterface->setGameSettings(&gameSettings, true); + serverInterface->broadcastGameSetup(&gameSettings); + + needToSetChangedGameSettings = false; + lastSetChangedGameSettings = time(NULL); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + // Last check, stop human player from being in same slot as network + if (isMasterserverMode() == false) { + bool hasHuman = false; + for (int i = 0; i < mapInfo.players; ++i) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + // Check for random faction selection and choose the faction now + if (listBoxControls[i].getSelectedItemIndex() == ctHuman) { + hasHuman = true; + break; + } + } + if (hasHuman == false) { + mainMessageBoxState = 1; + + Lang & lang = Lang::getInstance(); + string sMsg = + lang.getString("NetworkSlotNoHumanErrorUI", "", true); + showMessageBox(sMsg, "", false); + + const vector < string > languageList = + serverInterface-> + getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int j = 0; j < languageList.size(); ++j) { + sMsg = lang.getString("NetworkSlotNoHumanError", "", true); + + serverInterface->sendTextMessage(sMsg, -1, true, + languageList[j]); + } + + safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); + return; + } + } + + // Tell the server Interface whether or not to publish game status updates to masterserver + serverInterface->setNeedToRepublishToMasterserver + (checkBoxPublishServer.getValue() == true); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + bool bOkToStart = serverInterface->launchGame(&gameSettings); + if (bOkToStart == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (checkBoxPublishServer.getEditable() && + checkBoxPublishServer.getValue() == true) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + needToRepublishToMasterserver = true; + lastMasterserverPublishing = 0; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + needToBroadcastServerSettings = false; + needToRepublishToMasterserver = false; + lastNetworkPing = time(NULL); + safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + assert(program != NULL); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + cleanup(); + Game *newGame = + new Game(program, &gameSettings, this->headlessServerMode); + forceWaitForShutdown = false; + program->setState(newGame); + return; + } else { + safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); + } + } + } + + void MenuStateCustomGame::mouseMove(int x, int y, const MouseState * ms) { + if (isMasterserverMode() == true) { + return; + } + + if (mainMessageBox.getEnabled()) { + mainMessageBox.mouseMove(x, y); + } + buttonReturn.mouseMove(x, y); + buttonPlayNow.mouseMove(x, y); + buttonRestoreLastSettings.mouseMove(x, y); + buttonClearBlockedPlayers.mouseMove(x, y); + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + listBoxRMultiplier[i].mouseMove(x, y); + listBoxControls[i].mouseMove(x, y); + buttonBlockPlayers[i].mouseMove(x, y); + listBoxFactions[i].mouseMove(x, y); + listBoxTeams[i].mouseMove(x, y); + } + + listBoxMap.mouseMove(x, y); + + if (checkBoxAdvanced.getValue() == 1) { + listBoxFogOfWar.mouseMove(x, y); + checkBoxAllowObservers.mouseMove(x, y); + + checkBoxEnableSwitchTeamMode.mouseMove(x, y); + listBoxAISwitchTeamAcceptPercent.mouseMove(x, y); + listBoxFallbackCpuMultiplier.mouseMove(x, y); + + labelNetworkPauseGameForLaggedClients.mouseMove(x, y); + checkBoxNetworkPauseGameForLaggedClients.mouseMove(x, y); + + labelAllowTeamUnitSharing.mouseMove(x, y); + checkBoxAllowTeamUnitSharing.mouseMove(x, y); + labelAllowTeamResourceSharing.mouseMove(x, y); + checkBoxAllowTeamResourceSharing.mouseMove(x, y); + } + checkBoxAllowInGameJoinPlayer.mouseMove(x, y); + + checkBoxAllowNativeLanguageTechtree.mouseMove(x, y); + + listBoxTileset.mouseMove(x, y); + listBoxMapFilter.mouseMove(x, y); + listBoxTechTree.mouseMove(x, y); + checkBoxPublishServer.mouseMove(x, y); + + checkBoxAdvanced.mouseMove(x, y); + + checkBoxScenario.mouseMove(x, y); + listBoxScenario.mouseMove(x, y); + } + + bool MenuStateCustomGame::isMasterserverMode() const { + return (this->headlessServerMode == true + && this->masterserverModeMinimalResources == true); + //return false; + } + + bool MenuStateCustomGame::isVideoPlaying() { + bool result = false; + if (factionVideo != NULL) { + result = factionVideo->isPlaying(); + } + return result; + } + + void MenuStateCustomGame::render() { + try { + Renderer & renderer = Renderer::getInstance(); + + if (mainMessageBox.getEnabled() == false) { + if (factionTexture != NULL) { + if (factionVideo == NULL || factionVideo->isPlaying() == false) { + renderer.renderTextureQuad(800, 600, 200, 150, + factionTexture, 1.0f); + } + } + } + if (factionVideo != NULL) { + if (factionVideo->isPlaying() == true) { + factionVideo->playFrame(false); + } else { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == + false + && ::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == + true) { + if (factionVideo != NULL) { + factionVideo->closePlayer(); + delete factionVideo; + factionVideo = NULL; + + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + if (serverInterface != NULL) { + initFactionPreview(serverInterface->getGameSettings()); + } + } + } + } + } + + if (mainMessageBox.getEnabled()) { + renderer.renderMessageBox(&mainMessageBox); + + renderer.renderButton(&buttonReturn); + } else { + if (mapPreviewTexture != NULL) { + //renderer.renderTextureQuad(5,185,150,150,mapPreviewTexture,1.0f); + renderer.renderTextureQuad(this->render_mapPreviewTexture_X, + this->render_mapPreviewTexture_Y, + this->render_mapPreviewTexture_W, + this->render_mapPreviewTexture_H, + mapPreviewTexture, 1.0f); + if (this->zoomedMap == true) { + return; + } + //printf("=================> Rendering map preview texture\n"); + } + if (scenarioLogoTexture != NULL) { + renderer.renderTextureQuad(300, 350, 400, 300, + scenarioLogoTexture, 1.0f); + //renderer.renderBackground(scenarioLogoTexture); + } + + renderer.renderButton(&buttonReturn); + renderer.renderButton(&buttonPlayNow); + renderer.renderButton(&buttonRestoreLastSettings); + + // Get a reference to the player texture cache + std::map < int, Texture2D * >&crcPlayerTextureCache = + CacheManager::getCachedItem < std::map < int, + Texture2D * > >(GameConstants::playerTextureCacheLookupKey); + + // START - this code ensure player title and player names don't overlap + int offsetPosition = 0; + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + FontMetrics *fontMetrics = NULL; + if (Renderer::renderText3DEnabled == false) { + fontMetrics = labelPlayers[i].getFont()->getMetrics(); + } else { + fontMetrics = labelPlayers[i].getFont3D()->getMetrics(); + } + if (fontMetrics == NULL) { + throw megaglest_runtime_error("fontMetrics == NULL"); + } + int curWidth = + (fontMetrics->getTextWidth(labelPlayers[i].getText())); + int newOffsetPosition = labelPlayers[i].getX() + curWidth + 2; + + //printf("labelPlayers[i].getX() = %d curWidth = %d labelPlayerNames[i].getX() = %d offsetPosition = %d newOffsetPosition = %d [%s]\n",labelPlayers[i].getX(),curWidth,labelPlayerNames[i].getX(),offsetPosition,newOffsetPosition,labelPlayers[i].getText().c_str()); + + if (labelPlayers[i].getX() + curWidth >= + labelPlayerNames[i].getX()) { + if (offsetPosition < newOffsetPosition) { + offsetPosition = newOffsetPosition; + } + } + } + // END + + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + if (hasNetworkGameSettings() == true) { + renderer.renderListBox(&listBoxPlayerStatus); + if (serverInterface != NULL && + serverInterface->getServerSocket() != NULL) { + renderer.renderButton(&buttonClearBlockedPlayers); + } + } + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + if (listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned) { + //printf("Player #%d [%s] control = %d\n",i,labelPlayerNames[i].getText().c_str(),listBoxControls[i].getSelectedItemIndex()); + labelPlayers[i].setVisible(true); + labelPlayerNames[i].setVisible(true); + listBoxControls[i].setVisible(true); + listBoxFactions[i].setVisible(true); + listBoxTeams[i].setVisible(true); + labelNetStatus[i].setVisible(true); + } + + if (hasNetworkGameSettings() == true && + listBoxControls[i].getSelectedItemIndex() != ctClosed) { + + renderer.renderLabel(&labelPlayerStatus[i]); + } + + if (crcPlayerTextureCache[i] != NULL) { + // Render the player # label the player's color + Vec3f playerColor = + crcPlayerTextureCache[i]->getPixmap()->getPixel3f(0, + 0); + renderer.renderLabel(&labelPlayers[i], &playerColor); + } else { + renderer.renderLabel(&labelPlayers[i]); + } + + if (offsetPosition > 0) { + labelPlayerNames[i].setX(offsetPosition); + } + renderer.renderLabel(&labelPlayerNames[i]); + + renderer.renderListBox(&listBoxControls[i]); + + if (hasNetworkGameSettings() == true && + listBoxControls[i].getSelectedItemIndex() != ctClosed) { + + renderer.renderLabel(&labelPlayerStatus[i]); + + if (listBoxControls[i].getSelectedItemIndex() == + ctNetwork + || listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned) { + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + if (serverInterface != NULL + && serverInterface->getSlot(i, true) != NULL + && serverInterface->getSlot(i, true)->isConnected()) { + renderer.renderButton(&buttonBlockPlayers[i]); + } + } + } + + if (listBoxControls[i].getSelectedItemIndex() != ctClosed) { + renderer.renderListBox(&listBoxRMultiplier[i]); + renderer.renderListBox(&listBoxFactions[i]); + + int teamnumber = listBoxTeams[i].getSelectedItemIndex(); + Vec3f teamcolor = Vec3f(1.0f, 1.0f, 1.0f); + if (teamnumber >= 0 && teamnumber < 8) { + teamcolor = + crcPlayerTextureCache[teamnumber]-> + getPixmap()->getPixel3f(0, 0); + } + listBoxTeams[i].setTextColor(teamcolor); + + renderer.renderListBox(&listBoxTeams[i]); + renderer.renderLabel(&labelNetStatus[i]); + } + } + + renderer.renderLabel(&labelLocalGameVersion); + renderer.renderLabel(&labelLocalIP); + renderer.renderLabel(&labelMap); + + if (checkBoxAdvanced.getValue() == 1) { + renderer.renderLabel(&labelFogOfWar); + renderer.renderLabel(&labelAllowObservers); + renderer.renderLabel(&labelFallbackCpuMultiplier); + + renderer.renderLabel(&labelEnableSwitchTeamMode); + renderer.renderLabel(&labelAISwitchTeamAcceptPercent); + + renderer.renderListBox(&listBoxFogOfWar); + renderer.renderCheckBox(&checkBoxAllowObservers); + + renderer.renderCheckBox(&checkBoxEnableSwitchTeamMode); + renderer.renderListBox(&listBoxAISwitchTeamAcceptPercent); + renderer.renderListBox(&listBoxFallbackCpuMultiplier); + + renderer.renderLabel(&labelAllowTeamUnitSharing); + renderer.renderCheckBox(&checkBoxAllowTeamUnitSharing); + + renderer.renderLabel(&labelAllowTeamResourceSharing); + renderer.renderCheckBox(&checkBoxAllowTeamResourceSharing); + } + renderer.renderLabel(&labelAllowInGameJoinPlayer); + renderer.renderCheckBox(&checkBoxAllowInGameJoinPlayer); + + renderer.renderLabel(&labelTileset); + renderer.renderLabel(&labelMapFilter); + renderer.renderLabel(&labelTechTree); + renderer.renderLabel(&labelControl); + renderer.renderLabel(&labelFaction); + renderer.renderLabel(&labelTeam); + renderer.renderLabel(&labelMapInfo); + renderer.renderLabel(&labelAdvanced); + + renderer.renderListBox(&listBoxMap); + renderer.renderListBox(&listBoxTileset); + renderer.renderListBox(&listBoxMapFilter); + renderer.renderListBox(&listBoxTechTree); + renderer.renderCheckBox(&checkBoxAdvanced); + + if (checkBoxPublishServer.getEditable()) { + renderer.renderCheckBox(&checkBoxPublishServer); + renderer.renderLabel(&labelPublishServer); + renderer.renderLabel(&labelGameName); + if (checkBoxAdvanced.getValue() == 1) { + renderer.renderLabel(&labelNetworkPauseGameForLaggedClients); + renderer.renderCheckBox + (&checkBoxNetworkPauseGameForLaggedClients); + } + } + + renderer.renderCheckBox(&checkBoxScenario); + renderer.renderLabel(&labelScenario); + if (checkBoxScenario.getValue() == true) { + renderer.renderListBox(&listBoxScenario); + } + + renderer.renderLabel(&labelAllowNativeLanguageTechtree); + renderer.renderCheckBox(&checkBoxAllowNativeLanguageTechtree); + } + + if (program != NULL) + program->renderProgramMsgBox(); + + if (enableMapPreview == true && mapPreview.hasFileLoaded() == true) { + + if (mapPreviewTexture == NULL) { + bool renderAll = (listBoxFogOfWar.getSelectedItemIndex() == 2); + //printf("=================> Rendering map preview into a texture BEFORE (%p)\n", mapPreviewTexture); + + //renderer.renderMapPreview(&mapPreview, renderAll, 10, 350,&mapPreviewTexture); + renderer.renderMapPreview(&mapPreview, renderAll, + this->render_mapPreviewTexture_X, + this->render_mapPreviewTexture_Y, + &mapPreviewTexture); + + //printf("=================> Rendering map preview into a texture AFTER (%p)\n", mapPreviewTexture); + } + } + + if (mainMessageBox.getEnabled() == false) { + if (hasNetworkGameSettings() == true) { + renderer.renderChatManager(&chatManager); + } + } + renderer.renderConsole(&console, + showFullConsole ? consoleFull : + consoleStoredAndNormal); + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + //throw megaglest_runtime_error(szBuf); + + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + showGeneralError = true; + generalErrorToShow = szBuf; + } + } + + void MenuStateCustomGame::switchSetupForSlots(SwitchSetupRequest ** + switchSetupRequests, + ServerInterface * + &serverInterface, + int startIndex, + int endIndex, + bool onlyNetworkUnassigned) { + for (int i = startIndex; i < endIndex; ++i) { + if (switchSetupRequests[i] != NULL) { + //printf("Switch slot = %d control = %d newIndex = %d currentindex = %d onlyNetworkUnassigned = %d\n",i,listBoxControls[i].getSelectedItemIndex(),switchSetupRequests[i]->getToFactionIndex(),switchSetupRequests[i]->getCurrentFactionIndex(),onlyNetworkUnassigned); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] switchSetupRequests[i]->getSwitchFlags() = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + switchSetupRequests[i]->getSwitchFlags + ()); + + if (onlyNetworkUnassigned == true + && listBoxControls[i].getSelectedItemIndex() != + ctNetworkUnassigned) { + if (i < mapInfo.players + || (i >= mapInfo.players + && listBoxControls[i].getSelectedItemIndex() != + ctNetwork)) { + continue; + } + } + + if (listBoxControls[i].getSelectedItemIndex() == ctNetwork + || listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] switchSetupRequests[i]->getToFactionIndex() = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, + switchSetupRequests[i]->getToSlotIndex + ()); + + if (switchSetupRequests[i]->getToSlotIndex() != -1) { + int newFactionIdx = switchSetupRequests[i]->getToSlotIndex(); + + //printf("switchSlot request from %d to %d\n",switchSetupRequests[i]->getCurrentFactionIndex(),switchSetupRequests[i]->getToFactionIndex()); + int switchFactionIdx = + switchSetupRequests[i]->getCurrentSlotIndex(); + if (serverInterface->switchSlot + (switchFactionIdx, newFactionIdx)) { + try { + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + ConnectionSlot *slot = + serverInterface->getSlot(newFactionIdx, true); + + if (switchSetupRequests[i]->getSelectedFactionName() != "" + && (slot != NULL + && switchSetupRequests[i]->getSelectedFactionName() + != Lang::getInstance().getString("DataMissing", + slot->getNetworkPlayerLanguage + (), true) + && switchSetupRequests[i]->getSelectedFactionName() + != "???DataMissing???")) { + // I don't believe we need to check to see if Observers + // are allowed. If it's not, there should be not button on the client + // side that would allow them to switch to a slot > mapInfo.hardMaxPlayers + if (newFactionIdx <= mapInfo.hardMaxPlayers) { + + listBoxFactions[newFactionIdx].setSelectedItem + (switchSetupRequests[i]->getSelectedFactionName()); + } else { + listBoxFactions[newFactionIdx].setSelectedItem(GameConstants::OBSERVER_SLOTNAME); + } + + } + if (switchSetupRequests[i]->getToTeam() != -1) { + if (newFactionIdx <= mapInfo.hardMaxPlayers) { + listBoxTeams[newFactionIdx].setSelectedItemIndex + (switchSetupRequests[i]->getToTeam()); + } else { + listBoxTeams[i].setSelectedItem(intToStr(GameConstants::maxPlayers + + fpt_Observer)); + } + } + if (switchSetupRequests[i]->getNetworkPlayerName() != "") { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] i = %d, labelPlayerNames[newFactionIdx].getText() [%s] switchSetupRequests[i]->getNetworkPlayerName() [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, i, + labelPlayerNames + [newFactionIdx].getText + ().c_str(), + switchSetupRequests + [i]->getNetworkPlayerName(). + c_str()); + labelPlayerNames[newFactionIdx].setText + (switchSetupRequests[i]->getNetworkPlayerName()); + } + + if (listBoxControls[switchFactionIdx].getSelectedItemIndex + () == ctNetworkUnassigned) { + serverInterface->removeSlot(switchFactionIdx); + listBoxControls[switchFactionIdx].setSelectedItemIndex + (ctClosed); + + labelPlayers[switchFactionIdx].setVisible + (switchFactionIdx + 1 <= mapInfo.players); + labelPlayerNames[switchFactionIdx].setVisible + (switchFactionIdx + 1 <= mapInfo.players); + listBoxControls[switchFactionIdx].setVisible + (switchFactionIdx + 1 <= mapInfo.players); + listBoxFactions[switchFactionIdx].setVisible + (switchFactionIdx + 1 <= mapInfo.players); + listBoxTeams[switchFactionIdx].setVisible + (switchFactionIdx + 1 <= mapInfo.players); + labelNetStatus[switchFactionIdx].setVisible + (switchFactionIdx + 1 <= mapInfo.players); + } + } catch (const runtime_error & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + e.what()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] caught exception error = [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + e.what()); + } + } + } else { + try { + int factionIdx = + switchSetupRequests[i]->getCurrentSlotIndex(); + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + ConnectionSlot *slot = + serverInterface->getSlot(factionIdx, true); + + if (switchSetupRequests[i]->getSelectedFactionName() != "" + && (slot != NULL + && switchSetupRequests[i]->getSelectedFactionName() + != Lang::getInstance().getString("DataMissing", + slot->getNetworkPlayerLanguage + (), true) + && switchSetupRequests[i]->getSelectedFactionName() + != "???DataMissing???")) { + listBoxFactions[i].setSelectedItem(switchSetupRequests + [i]->getSelectedFactionName + ()); + } + if (switchSetupRequests[i]->getToTeam() != -1) { + listBoxTeams[i].setSelectedItemIndex(switchSetupRequests + [i]->getToTeam()); + } + + if ((switchSetupRequests[i]->getSwitchFlags() & + ssrft_NetworkPlayerName) == ssrft_NetworkPlayerName) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] i = %d, switchSetupRequests[i]->getSwitchFlags() = %d, switchSetupRequests[i]->getNetworkPlayerName() [%s], labelPlayerNames[i].getText() [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, i, + switchSetupRequests + [i]->getSwitchFlags(), + switchSetupRequests + [i]->getNetworkPlayerName(). + c_str(), + labelPlayerNames[i].getText(). + c_str()); + + if (switchSetupRequests[i]->getNetworkPlayerName() != + GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) { + labelPlayerNames[i].setText(switchSetupRequests + [i]->getNetworkPlayerName + ()); + } else { + labelPlayerNames[i].setText(""); + } + } + } catch (const runtime_error & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, e.what()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] caught exception error = [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, e.what()); + } + } + } + + delete switchSetupRequests[i]; + switchSetupRequests[i] = NULL; + } + } + } + + void MenuStateCustomGame::initFactionPreview(const GameSettings * + gameSettings) { + string factionVideoUrl = ""; + string factionVideoUrlFallback = ""; + + string factionDefinitionXML = + Game::findFactionLogoFile(gameSettings, NULL, + currentFactionName_factionPreview + + ".xml"); + if (factionDefinitionXML != "" + && currentFactionName_factionPreview != + GameConstants::RANDOMFACTION_SLOTNAME + && currentFactionName_factionPreview != + GameConstants::OBSERVER_SLOTNAME + && fileExists(factionDefinitionXML) == true) { + XmlTree xmlTree; + std::map < string, string > mapExtraTagReplacementValues; + xmlTree.load(factionDefinitionXML, + Properties::getTagReplacementValues + (&mapExtraTagReplacementValues)); + const XmlNode *factionNode = xmlTree.getRootNode(); + if (factionNode->hasAttribute("faction-preview-video") == true) { + factionVideoUrl = + factionNode->getAttribute("faction-preview-video")->getValue(); + } + + factionVideoUrlFallback = + Game::findFactionLogoFile(gameSettings, NULL, "preview_video.*"); + if (factionVideoUrl == "") { + factionVideoUrl = factionVideoUrlFallback; + factionVideoUrlFallback = ""; + } + } + //printf("currentFactionName_factionPreview [%s] random [%s] observer [%s] factionVideoUrl [%s]\n",currentFactionName_factionPreview.c_str(),GameConstants::RANDOMFACTION_SLOTNAME,GameConstants::OBSERVER_SLOTNAME,factionVideoUrl.c_str()); + + + if (factionVideoUrl != "") { + //SoundRenderer &soundRenderer= SoundRenderer::getInstance(); + if (CoreData::getInstance().getMenuMusic()->getVolume() != 0) { + CoreData::getInstance().getMenuMusic()->setVolume(0); + factionVideoSwitchedOffVolume = true; + } + + if (currentFactionLogo != factionVideoUrl) { + currentFactionLogo = factionVideoUrl; + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false + && ::Shared::Graphics::VideoPlayer::hasBackEndVideoPlayer() == + true) { + + if (factionVideo != NULL) { + factionVideo->closePlayer(); + delete factionVideo; + factionVideo = NULL; + } + string introVideoFile = factionVideoUrl; + string introVideoFileFallback = factionVideoUrlFallback; + + Context *c = + GraphicsInterface::getInstance().getCurrentContext(); + SDL_Window *window = + static_cast < + ContextGl * + >(c)->getPlatformContextGlPtr()->getScreenWindow(); + SDL_Surface *screen = + static_cast < + ContextGl * + >(c)->getPlatformContextGlPtr()->getScreenSurface(); + + string vlcPluginsPath = + Config::getInstance().getString("VideoPlayerPluginsPath", ""); + //printf("screen->w = %d screen->h = %d screen->format->BitsPerPixel = %d\n",screen->w,screen->h,screen->format->BitsPerPixel); + factionVideo = new VideoPlayer(&Renderer::getInstance(), + introVideoFile, + introVideoFileFallback, + window, + 0, 0, + screen->w, + screen->h, + screen->format->BitsPerPixel, + true, vlcPluginsPath, + SystemFlags::VERBOSE_MODE_ENABLED); + factionVideo->initPlayer(); + } + } + } else { + //SoundRenderer &soundRenderer= SoundRenderer::getInstance(); + //switch on music again!! + Config & config = Config::getInstance(); + float configVolume = (config.getInt("SoundVolumeMusic") / 100.f); + if (factionVideoSwitchedOffVolume) { + if (CoreData::getInstance().getMenuMusic()->getVolume() != + configVolume) { + CoreData::getInstance(). + getMenuMusic()->setVolume(configVolume); + } + factionVideoSwitchedOffVolume = false; + } + + if (factionVideo != NULL) { + factionVideo->closePlayer(); + delete factionVideo; + factionVideo = NULL; + } + } + + if (factionVideo == NULL) { + string factionLogo = Game::findFactionLogoFile(gameSettings, NULL, + GameConstants::PREVIEW_SCREEN_FILE_FILTER); + if (factionLogo == "") { + factionLogo = Game::findFactionLogoFile(gameSettings, NULL); + } + if (currentFactionLogo != factionLogo) { + currentFactionLogo = factionLogo; + loadFactionTexture(currentFactionLogo); + } + } + } + + void MenuStateCustomGame::publishToMasterserver() { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + int slotCountUsed = 0; + int slotCountHumans = 0; + int slotCountConnectedPlayers = 0; + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + GameSettings gameSettings; + loadGameSettings(&gameSettings); + Config & config = Config::getInstance(); + //string serverinfo=""; + + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + publishToServerInfo.clear(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + for (int i = 0; i < mapInfo.players; ++i) { + if (listBoxControls[i].getSelectedItemIndex() != ctClosed) { + slotCountUsed++; + } + + if (listBoxControls[i].getSelectedItemIndex() == ctNetwork + || listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned) { + slotCountHumans++; + if (serverInterface->getSlot(i, true) != NULL && + serverInterface->getSlot(i, true)->isConnected()) { + slotCountConnectedPlayers++; + } + } else if (listBoxControls[i].getSelectedItemIndex() == ctHuman) { + slotCountHumans++; + slotCountConnectedPlayers++; + } + } + + publishToServerInfo["uuid"] = + Config::getInstance().getString("PlayerId", ""); + + //?status=waiting&system=linux&info=titus + publishToServerInfo["glestVersion"] = glestVersionString; + publishToServerInfo["platform"] = + getPlatformNameString(); + publishToServerInfo["binaryCompileDate"] = getCompileDateTime(); + + //game info: + publishToServerInfo["serverTitle"] = gameSettings.getGameName(); + //ip is automatically set + + //game setup info: + + //publishToServerInfo["tech"] = listBoxTechTree.getSelectedItem(); + publishToServerInfo["tech"] = + techTreeFiles[listBoxTechTree.getSelectedItemIndex()]; + //publishToServerInfo["map"] = listBoxMap.getSelectedItem(); + publishToServerInfo["map"] = getCurrentMapFile(); + //publishToServerInfo["tileset"] = listBoxTileset.getSelectedItem(); + publishToServerInfo["tileset"] = + tilesetFiles[listBoxTileset.getSelectedItemIndex()]; + + publishToServerInfo["activeSlots"] = intToStr(slotCountUsed); + publishToServerInfo["networkSlots"] = intToStr(slotCountHumans); + publishToServerInfo["connectedClients"] = + intToStr(slotCountConnectedPlayers); + + string serverPort = config.getString("PortServer", + intToStr + (GameConstants:: + serverPort).c_str()); + string externalPort = + config.getString("PortExternal", serverPort.c_str()); + publishToServerInfo["externalconnectport"] = externalPort; + publishToServerInfo["privacyPlease"] = + intToStr(config.getBool("PrivacyPlease", "false")); + + publishToServerInfo["gameStatus"] = + intToStr(game_status_waiting_for_players); + if (slotCountHumans <= slotCountConnectedPlayers) { + publishToServerInfo["gameStatus"] = + intToStr(game_status_waiting_for_start); + } + + publishToServerInfo["gameUUID"] = gameSettings.getGameUUID(); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + void MenuStateCustomGame::setupTask(BaseThread * callingThread, + void *userdata) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\n\nsetupTask callingThread [%p] userdata [%p]\n", + callingThread, userdata); + if (userdata != NULL) { + int value = *((int *) &userdata); + THREAD_NOTIFIER_TYPE threadType = (THREAD_NOTIFIER_TYPE) value; + //printf("\n\nsetupTask callingThread [%p] userdata [%p]\n",callingThread,userdata); + if (threadType == tnt_MASTERSERVER) { + MenuStateCustomGame::setupTaskStatic(callingThread); + } + } + } + void MenuStateCustomGame::shutdownTask(BaseThread * callingThread, + void *userdata) { + //printf("\n\nshutdownTask callingThread [%p] userdata [%p]\n",callingThread,userdata); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("\n\nshutdownTask callingThread [%p] userdata [%p]\n", + callingThread, userdata); + if (userdata != NULL) { + int value = *((int *) &userdata); + THREAD_NOTIFIER_TYPE threadType = (THREAD_NOTIFIER_TYPE) value; + //printf("\n\nshutdownTask callingThread [%p] userdata [%p]\n",callingThread,userdata); + if (threadType == tnt_MASTERSERVER) { + MenuStateCustomGame::shutdownTaskStatic(callingThread); + } + } + } + void MenuStateCustomGame::setupTaskStatic(BaseThread * callingThread) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + + CURL *handle = SystemFlags::initHTTP(); + callingThread->setGenericData < CURL >(handle); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + } + void MenuStateCustomGame::shutdownTaskStatic(BaseThread * callingThread) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + + //printf("LINE: %d\n",__LINE__); + CURL *handle = callingThread->getGenericData < CURL >(); + SystemFlags::cleanupHTTP(&handle); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + } + + void MenuStateCustomGame::simpleTask(BaseThread * callingThread, + void *userdata) { + //printf("\n\nSimple Task callingThread [%p] userdata [%p]\n",callingThread,userdata); + int value = *((int *) &userdata); + //printf("\n\nSimple Task callingThread [%p] userdata [%p] value = %d\n",callingThread,userdata,value); + + THREAD_NOTIFIER_TYPE threadType = (THREAD_NOTIFIER_TYPE) value; + if (threadType == tnt_MASTERSERVER) { + simpleTaskForMasterServer(callingThread); + } else if (threadType == tnt_CLIENTS) { + simpleTaskForClients(callingThread); + } + } + + void MenuStateCustomGame::simpleTaskForMasterServer(BaseThread * + callingThread) { + try { + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - A\n"); + + MutexSafeWrapper + safeMutexThreadOwner(callingThread->getMutexThreadOwnerValid(), + string(__FILE__) + "_" + + intToStr(__LINE__)); + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + return; + } + + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - B\n"); + + MutexSafeWrapper + safeMutex(callingThread->getMutexThreadObjectAccessor(), + string(__FILE__) + "_" + intToStr(__LINE__)); + bool republish = (needToRepublishToMasterserver == true + && publishToServerInfo.empty() == false); + needToRepublishToMasterserver = false; + std::map < string, string > newPublishToServerInfo = + publishToServerInfo; + publishToServerInfo.clear(); + + //printf("simpleTask broadCastSettings = %d\n",broadCastSettings); + + if (callingThread->getQuitStatus() == true) { + return; + } + + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - C\n"); + + if (republish == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + string request = Config::getInstance().getString("Masterserver"); + if (request != "") { + endPathWithSlash(request, false); + } + request += "addServerInfo.php?"; + + //CURL *handle = SystemFlags::initHTTP(); + CURL *handle = callingThread->getGenericData < CURL >(); + + int paramIndex = 0; + for (std::map < string, string >::const_iterator iterMap = + newPublishToServerInfo.begin(); + iterMap != newPublishToServerInfo.end(); ++iterMap) { + + request += iterMap->first; + request += "="; + request += SystemFlags::escapeURL(iterMap->second, handle); + + paramIndex++; + if (paramIndex < (int) newPublishToServerInfo.size()) { + request += "&"; + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("The Lobby request is:\n%s\n", request.c_str()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] the request is:\n%s\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + request.c_str()); + safeMutex.ReleaseLock(true); + safeMutexThreadOwner.ReleaseLock(); + + std::string serverInfo = SystemFlags::getHTTP(request, handle); + //SystemFlags::cleanupHTTP(&handle); + + MutexSafeWrapper + safeMutexThreadOwner2(callingThread->getMutexThreadOwnerValid(), + string(__FILE__) + "_" + + intToStr(__LINE__)); + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner2.isValidMutex() == false) { + return; + } + safeMutex.Lock(); + + //printf("the result is:\n'%s'\n",serverInfo.c_str()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] the result is:\n'%s'\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + serverInfo.c_str()); + + // uncomment to enable router setup check of this server + if (EndsWith(serverInfo, "OK") == false) { + if (callingThread->getQuitStatus() == true) { + return; + } + + // Give things another chance to see if we can get a connection from the master server + if (tMasterserverErrorElapsed > 0 && + difftime((long int) time(NULL), + tMasterserverErrorElapsed) > + MASTERSERVER_BROADCAST_MAX_WAIT_RESPONSE_SECONDS) { + showMasterserverError = true; + masterServererErrorToShow = + (serverInfo != "" ? serverInfo : "No Reply"); + } else { + if (tMasterserverErrorElapsed == 0) { + tMasterserverErrorElapsed = time(NULL); + } + + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line %d] error checking response from masterserver elapsed seconds = %.2f / %d\nResponse:\n%s\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, __LINE__, + difftime((long int) + time(NULL), + tMasterserverErrorElapsed), + MASTERSERVER_BROADCAST_MAX_WAIT_RESPONSE_SECONDS, + serverInfo.c_str()); + + needToRepublishToMasterserver = true; + } + } + } else { + safeMutexThreadOwner.ReleaseLock(); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - D\n"); + + safeMutex.ReleaseLock(); + + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - F\n"); + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + if (callingThread->getQuitStatus() == false) { + //throw megaglest_runtime_error(szBuf); + showGeneralError = true; + generalErrorToShow = ex.what(); + } + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + void MenuStateCustomGame::simpleTaskForClients(BaseThread * + callingThread) { + try { + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - A\n"); + + MutexSafeWrapper + safeMutexThreadOwner(callingThread->getMutexThreadOwnerValid(), + string(__FILE__) + "_" + + intToStr(__LINE__)); + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + return; + } + + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - B\n"); + + MutexSafeWrapper + safeMutex(callingThread->getMutexThreadObjectAccessor(), + string(__FILE__) + "_" + intToStr(__LINE__)); + bool broadCastSettings = needToBroadcastServerSettings; + + //printf("simpleTask broadCastSettings = %d\n",broadCastSettings); + + needToBroadcastServerSettings = false; + bool hasClientConnection = false; + + if (broadCastSettings == true) { + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(false); + if (serverInterface != NULL) { + hasClientConnection = serverInterface->hasClientConnection(); + } + } + bool needPing = + (difftime((long int) time(NULL), lastNetworkPing) >= + GameConstants::networkPingInterval); + + if (callingThread->getQuitStatus() == true) { + return; + } + + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - C\n"); + + safeMutexThreadOwner.ReleaseLock(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - D\n"); + + if (broadCastSettings == true) { + MutexSafeWrapper + safeMutexThreadOwner2(callingThread->getMutexThreadOwnerValid(), + string(__FILE__) + "_" + + intToStr(__LINE__)); + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner2.isValidMutex() == false) { + return; + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + //printf("simpleTask broadCastSettings = %d hasClientConnection = %d\n",broadCastSettings,hasClientConnection); + + if (callingThread->getQuitStatus() == true) { + return; + } + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(false); + if (serverInterface != NULL) { + lastGameSettingsreceivedCount++; + if (this->headlessServerMode == false + || (serverInterface->getGameSettingsUpdateCount() <= + lastMasterServerSettingsUpdateCount)) { + GameSettings gameSettings; + loadGameSettings(&gameSettings); + + //printf("\n\n\n\n=====#2 got settings [%d] [%d]:\n%s\n",lastMasterServerSettingsUpdateCount,serverInterface->getGameSettingsUpdateCount(),gameSettings.toString().c_str()); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + serverInterface->setGameSettings(&gameSettings, false); + lastMasterServerSettingsUpdateCount = + serverInterface->getGameSettingsUpdateCount(); + + if (hasClientConnection == true) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + serverInterface->broadcastGameSetup(&gameSettings); + } + } + } + } + + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - E\n"); + + if (needPing == true) { + MutexSafeWrapper + safeMutexThreadOwner2(callingThread->getMutexThreadOwnerValid(), + string(__FILE__) + "_" + + intToStr(__LINE__)); + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner2.isValidMutex() == false) { + return; + } + + lastNetworkPing = time(NULL); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] Sending nmtPing to clients\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(false); + if (serverInterface != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + NetworkMessagePing *msg = + new NetworkMessagePing(GameConstants::networkPingInterval, + time(NULL)); + //serverInterface->broadcastPing(&msg); + serverInterface->queueBroadcastMessage(msg); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + } + safeMutex.ReleaseLock(); + + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - F\n"); + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + if (callingThread->getQuitStatus() == false) { + //throw megaglest_runtime_error(szBuf); + showGeneralError = true; + generalErrorToShow = ex.what(); + } + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + void MenuStateCustomGame::loadGameSettings(GameSettings * gameSettings, + bool forceCloseUnusedSlots) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + int factionCount = 0; + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (this->headlessServerMode == true + && serverInterface->getGameSettingsUpdateCount() > + lastMasterServerSettingsUpdateCount + && serverInterface->getGameSettings() != NULL) { + const GameSettings *settings = serverInterface->getGameSettings(); + //printf("\n\n\n\n=====#3 got settings [%d] [%d]:\n%s\n",lastMasterServerSettingsUpdateCount,serverInterface->getGameSettingsUpdateCount(),settings->toString().c_str()); + + lastMasterServerSettingsUpdateCount = + serverInterface->getGameSettingsUpdateCount(); + //printf("#1 custom menu got map [%s]\n",settings->getMap().c_str()); + + setupUIFromGameSettings(*settings); + } + + gameSettings->setGameName(labelGameName.getText()); + + // Test flags values + //gameSettings->setFlagTypes1(ft1_show_map_resources); + // + + if (checkBoxScenario.getValue() == true) { + gameSettings->setScenario(scenarioInfo.name); + gameSettings->setScenarioDir(Scenario::getScenarioPath + (dirList, scenarioInfo.name)); + + gameSettings->setDefaultResources(scenarioInfo.defaultResources); + gameSettings->setDefaultUnits(scenarioInfo.defaultUnits); + gameSettings-> + setDefaultVictoryConditions(scenarioInfo.defaultVictoryConditions); + } else { + gameSettings->setScenario(""); + gameSettings->setScenarioDir(""); + } + + gameSettings->setGameUUID(this->gameUUID); + + //printf("scenarioInfo.name [%s] [%s] [%s]\n",scenarioInfo.name.c_str(),listBoxMap.getSelectedItem().c_str(),getCurrentMapFile().c_str()); + + gameSettings->setMapFilter(listBoxMapFilter.getSelectedItemIndex()); + gameSettings->setDescription(formatString(getCurrentMapFile())); + gameSettings->setMap(getCurrentMapFile()); + if (tilesetFiles.empty() == false) { + gameSettings->setTileset(tilesetFiles + [listBoxTileset.getSelectedItemIndex()]); + } + if (techTreeFiles.empty() == false) { + gameSettings->setTech(techTreeFiles + [listBoxTechTree.getSelectedItemIndex()]); + } + + if (autoStartSettings != NULL) { + gameSettings->setDefaultUnits(autoStartSettings->getDefaultUnits()); + gameSettings-> + setDefaultResources(autoStartSettings->getDefaultResources()); + gameSettings-> + setDefaultVictoryConditions + (autoStartSettings->getDefaultVictoryConditions()); + } else if (checkBoxScenario.getValue() == false) { + gameSettings->setDefaultUnits(true); + gameSettings->setDefaultResources(true); + gameSettings->setDefaultVictoryConditions(true); + } + + gameSettings->setFogOfWar(listBoxFogOfWar.getSelectedItemIndex() == 0 + || listBoxFogOfWar.getSelectedItemIndex() == + 1); + + gameSettings->setAllowObservers(checkBoxAllowObservers.getValue() == + 1); + + uint32 valueFlags1 = gameSettings->getFlagTypes1(); + if (listBoxFogOfWar.getSelectedItemIndex() == 1 || + listBoxFogOfWar.getSelectedItemIndex() == 2) { + valueFlags1 |= ft1_show_map_resources; + gameSettings->setFlagTypes1(valueFlags1); + } else { + valueFlags1 &= ~ft1_show_map_resources; + gameSettings->setFlagTypes1(valueFlags1); + } + + //gameSettings->setEnableObserverModeAtEndGame(listBoxEnableObserverMode.getSelectedItemIndex() == 0); + gameSettings->setEnableObserverModeAtEndGame(true); + //gameSettings->setPathFinderType(static_cast(listBoxPathFinderType.getSelectedItemIndex())); + + valueFlags1 = gameSettings->getFlagTypes1(); + if (checkBoxEnableSwitchTeamMode.getValue() == true) { + valueFlags1 |= ft1_allow_team_switching; + gameSettings->setFlagTypes1(valueFlags1); + } else { + valueFlags1 &= ~ft1_allow_team_switching; + gameSettings->setFlagTypes1(valueFlags1); + } + gameSettings->setAiAcceptSwitchTeamPercentChance(strToInt + (listBoxAISwitchTeamAcceptPercent.getSelectedItem + ())); + gameSettings-> + setFallbackCpuMultiplier + (listBoxFallbackCpuMultiplier.getSelectedItemIndex()); + + if (checkBoxAllowInGameJoinPlayer.getValue() == true) { + valueFlags1 |= ft1_allow_in_game_joining; + gameSettings->setFlagTypes1(valueFlags1); + } else { + valueFlags1 &= ~ft1_allow_in_game_joining; + gameSettings->setFlagTypes1(valueFlags1); + } + + if (checkBoxAllowTeamUnitSharing.getValue() == true) { + valueFlags1 |= ft1_allow_shared_team_units; + gameSettings->setFlagTypes1(valueFlags1); + } else { + valueFlags1 &= ~ft1_allow_shared_team_units; + gameSettings->setFlagTypes1(valueFlags1); + } + + if (checkBoxAllowTeamResourceSharing.getValue() == true) { + valueFlags1 |= ft1_allow_shared_team_resources; + gameSettings->setFlagTypes1(valueFlags1); + } else { + valueFlags1 &= ~ft1_allow_shared_team_resources; + gameSettings->setFlagTypes1(valueFlags1); + } + + if (Config::getInstance().getBool("EnableNetworkGameSynchChecks", + "false") == true) { + //printf("*WARNING* - EnableNetworkGameSynchChecks is enabled\n"); + + valueFlags1 |= ft1_network_synch_checks_verbose; + gameSettings->setFlagTypes1(valueFlags1); + + } else { + valueFlags1 &= ~ft1_network_synch_checks_verbose; + gameSettings->setFlagTypes1(valueFlags1); + + } + if (Config::getInstance().getBool("EnableNetworkGameSynchMonitor", + "false") == true) { + //printf("*WARNING* - EnableNetworkGameSynchChecks is enabled\n"); + + valueFlags1 |= ft1_network_synch_checks; + gameSettings->setFlagTypes1(valueFlags1); + + } else { + valueFlags1 &= ~ft1_network_synch_checks; + gameSettings->setFlagTypes1(valueFlags1); + + } + + gameSettings->setNetworkAllowNativeLanguageTechtree + (checkBoxAllowNativeLanguageTechtree.getValue()); + + // First save Used slots + //for(int i=0; iheadlessServerMode == true) { + // switch slot to network, because no human in headless mode + listBoxControls[i].setSelectedItemIndex(ctNetwork); + updateResourceMultiplier(i); + } + + ControlType ct = + static_cast + (listBoxControls[i].getSelectedItemIndex()); + + if (forceCloseUnusedSlots == true + && (ct == ctNetworkUnassigned || ct == ctNetwork)) { + if (serverInterface != NULL && + (serverInterface->getSlot(i, true) == NULL || + serverInterface->getSlot(i, true)->isConnected() == false)) { + if (checkBoxScenario.getValue() == false) { + //printf("Closed A [%d] [%s]\n",i,labelPlayerNames[i].getText().c_str()); + + listBoxControls[i].setSelectedItemIndex(ctClosed); + ct = ctClosed; + } + } + } else if (ct == ctNetworkUnassigned && i < mapInfo.players) { + listBoxControls[i].setSelectedItemIndex(ctNetwork); + ct = ctNetwork; + } + + if (ct != ctClosed) { + int slotIndex = factionCount; + gameSettings->setFactionControl(slotIndex, ct); + if (ct == ctHuman) { + + // I'm putting this inside a ppd for now. I don't see it needs to be + // built in unless DEBUG is defined during building -andy5995 2018-01-26 #ifdef DEBUG - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] i = %d, slotIndex = %d, getHumanPlayerName(i) [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, i, slotIndex, - getHumanPlayerName (i).c_str ()); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] i = %d, slotIndex = %d, getHumanPlayerName(i) [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, i, slotIndex, + getHumanPlayerName(i).c_str()); #endif - gameSettings->setThisFactionIndex (slotIndex); - gameSettings->setNetworkPlayerName (slotIndex, - getHumanPlayerName (i)); - gameSettings->setNetworkPlayerUUID (slotIndex, - Config:: - getInstance ().getString - ("PlayerId", "")); - gameSettings->setNetworkPlayerPlatform (slotIndex, - getPlatformNameString ()); - gameSettings->setNetworkPlayerStatuses (slotIndex, - getNetworkPlayerStatus - ()); - Lang & lang = Lang::getInstance (); - gameSettings->setNetworkPlayerLanguages (slotIndex, - lang.getLanguage ()); - } - else if (serverInterface != NULL - && serverInterface->getSlot (i, true) != NULL) - { - gameSettings->setNetworkPlayerLanguages (slotIndex, - serverInterface->getSlot - (i, - true)->getNetworkPlayerLanguage - ()); - } + gameSettings->setThisFactionIndex(slotIndex); + gameSettings->setNetworkPlayerName(slotIndex, + getHumanPlayerName(i)); + gameSettings->setNetworkPlayerUUID(slotIndex, + Config:: + getInstance().getString + ("PlayerId", "")); + gameSettings->setNetworkPlayerPlatform(slotIndex, + getPlatformNameString()); + gameSettings->setNetworkPlayerStatuses(slotIndex, + getNetworkPlayerStatus + ()); + Lang & lang = Lang::getInstance(); + gameSettings->setNetworkPlayerLanguages(slotIndex, + lang.getLanguage()); + } else if (serverInterface != NULL + && serverInterface->getSlot(i, true) != NULL) { + gameSettings->setNetworkPlayerLanguages(slotIndex, + serverInterface->getSlot + (i, + true)->getNetworkPlayerLanguage + ()); + } - gameSettings->setResourceMultiplierIndex (slotIndex, - listBoxRMultiplier - [i].getSelectedItemIndex - ()); + gameSettings->setResourceMultiplierIndex(slotIndex, + listBoxRMultiplier + [i].getSelectedItemIndex + ()); -// I'm putting this inside a ppd for now. I don't see it needs to be -// built in unless DEBUG is defined during building -andy5995 2018-01-26 + // I'm putting this inside a ppd for now. I don't see it needs to be + // built in unless DEBUG is defined during building -andy5995 2018-01-26 #ifdef DEBUG - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] i = %d, factionFiles[listBoxFactions[i].getSelectedItemIndex()] [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, i, - factionFiles[listBoxFactions - [i].getSelectedItemIndex - ()].c_str ()); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] i = %d, factionFiles[listBoxFactions[i].getSelectedItemIndex()] [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, i, + factionFiles[listBoxFactions + [i].getSelectedItemIndex + ()].c_str()); #endif - gameSettings->setFactionTypeName (slotIndex, - factionFiles[listBoxFactions - [i].getSelectedItemIndex - ()]); - if (factionFiles[listBoxFactions[i].getSelectedItemIndex ()] == - formatString (GameConstants::OBSERVER_SLOTNAME)) - { - listBoxTeams[i].setSelectedItem (intToStr - (GameConstants::maxPlayers + - fpt_Observer)); - } - else if (listBoxTeams[i].getSelectedItem () == - intToStr (GameConstants::maxPlayers + fpt_Observer)) - { + gameSettings->setFactionTypeName(slotIndex, + factionFiles[listBoxFactions + [i].getSelectedItemIndex + ()]); + if (factionFiles[listBoxFactions[i].getSelectedItemIndex()] == + formatString(GameConstants::OBSERVER_SLOTNAME)) { + listBoxTeams[i].setSelectedItem(intToStr + (GameConstants::maxPlayers + + fpt_Observer)); + } else if (listBoxTeams[i].getSelectedItem() == + intToStr(GameConstants::maxPlayers + fpt_Observer)) { -//printf("Line: %d lastSelectedTeamIndex[i] = %d \n",__LINE__,lastSelectedTeamIndex[i]); + //printf("Line: %d lastSelectedTeamIndex[i] = %d \n",__LINE__,lastSelectedTeamIndex[i]); - if ((listBoxControls[i].getSelectedItemIndex () == ctCpuEasy - || listBoxControls[i].getSelectedItemIndex () == ctCpu - || listBoxControls[i].getSelectedItemIndex () == - ctCpuUltra - || listBoxControls[i].getSelectedItemIndex () == - ctCpuZeta) && checkBoxScenario.getValue () == true) - { + if ((listBoxControls[i].getSelectedItemIndex() == ctCpuEasy + || listBoxControls[i].getSelectedItemIndex() == ctCpu + || listBoxControls[i].getSelectedItemIndex() == + ctCpuUltra + || listBoxControls[i].getSelectedItemIndex() == + ctCpuZeta) && checkBoxScenario.getValue() == true) { - } - else - { - if (lastSelectedTeamIndex[i] >= 0 - && lastSelectedTeamIndex[i] + 1 != - (GameConstants::maxPlayers + fpt_Observer)) - { - if (lastSelectedTeamIndex[i] == 0) - { - lastSelectedTeamIndex[i] = GameConstants::maxPlayers - 1; - } - else if (lastSelectedTeamIndex[i] == - GameConstants::maxPlayers - 1) - { - lastSelectedTeamIndex[i] = 0; - } + } else { + if (lastSelectedTeamIndex[i] >= 0 + && lastSelectedTeamIndex[i] + 1 != + (GameConstants::maxPlayers + fpt_Observer)) { + if (lastSelectedTeamIndex[i] == 0) { + lastSelectedTeamIndex[i] = GameConstants::maxPlayers - 1; + } else if (lastSelectedTeamIndex[i] == + GameConstants::maxPlayers - 1) { + lastSelectedTeamIndex[i] = 0; + } - listBoxTeams[i].setSelectedItemIndex (lastSelectedTeamIndex - [i]); - } - else - { - listBoxTeams[i].setSelectedItem (intToStr (1)); - } - } - } + listBoxTeams[i].setSelectedItemIndex(lastSelectedTeamIndex + [i]); + } else { + listBoxTeams[i].setSelectedItem(intToStr(1)); + } + } + } - gameSettings->setTeam (slotIndex, - listBoxTeams[i].getSelectedItemIndex ()); - gameSettings->setStartLocationIndex (slotIndex, i); + gameSettings->setTeam(slotIndex, + listBoxTeams[i].getSelectedItemIndex()); + gameSettings->setStartLocationIndex(slotIndex, i); - if (listBoxControls[i].getSelectedItemIndex () == ctNetwork || - listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned) - { - if (serverInterface != NULL && - serverInterface->getSlot (i, true) != NULL && - serverInterface->getSlot (i, true)->isConnected ()) - { + if (listBoxControls[i].getSelectedItemIndex() == ctNetwork || + listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned) { + if (serverInterface != NULL && + serverInterface->getSlot(i, true) != NULL && + serverInterface->getSlot(i, true)->isConnected()) { - gameSettings->setNetworkPlayerStatuses (slotIndex, - serverInterface->getSlot - (i, - true)->getNetworkPlayerStatus - ()); + gameSettings->setNetworkPlayerStatuses(slotIndex, + serverInterface->getSlot + (i, + true)->getNetworkPlayerStatus + ()); -// I'm putting this inside a ppd for now. I don't see it needs to be -// built in unless DEBUG is defined during building -andy5995 2018-01-26 + // I'm putting this inside a ppd for now. I don't see it needs to be + // built in unless DEBUG is defined during building -andy5995 2018-01-26 #ifdef DEBUG - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] i = %d, connectionSlot->getName() [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, i, - serverInterface->getSlot (i, - true)->getName - ().c_str ()); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] i = %d, connectionSlot->getName() [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, i, + serverInterface->getSlot(i, + true)->getName + ().c_str()); #endif - gameSettings->setNetworkPlayerName (slotIndex, - serverInterface->getSlot (i, - true)->getName - ()); - gameSettings->setNetworkPlayerUUID (i, - serverInterface->getSlot (i, - true)->getUUID - ()); - gameSettings->setNetworkPlayerPlatform (i, - serverInterface->getSlot - (i, - true)->getPlatform ()); - labelPlayerNames[i]. - setText (serverInterface->getSlot (i, true)->getName ()); - } - else - { + gameSettings->setNetworkPlayerName(slotIndex, + serverInterface->getSlot(i, + true)->getName + ()); + gameSettings->setNetworkPlayerUUID(i, + serverInterface->getSlot(i, + true)->getUUID + ()); + gameSettings->setNetworkPlayerPlatform(i, + serverInterface->getSlot + (i, + true)->getPlatform()); + labelPlayerNames[i]. + setText(serverInterface->getSlot(i, true)->getName()); + } else { -// I'm putting this inside a ppd for now. I don't see it needs to be -// built in unless DEBUG is defined during building -andy5995 2018-01-26 + // I'm putting this inside a ppd for now. I don't see it needs to be + // built in unless DEBUG is defined during building -andy5995 2018-01-26 #ifdef DEBUG - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] i = %d, playername unconnected\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, i); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] i = %d, playername unconnected\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, i); #endif - gameSettings->setNetworkPlayerName (slotIndex, - GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME); - labelPlayerNames[i].setText (""); - } - } - else if (listBoxControls[i].getSelectedItemIndex () != ctHuman) - { - AIPlayerCount++; + gameSettings->setNetworkPlayerName(slotIndex, + GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME); + labelPlayerNames[i].setText(""); + } + } else if (listBoxControls[i].getSelectedItemIndex() != ctHuman) { + AIPlayerCount++; #ifdef DEBUG - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] i = %d, playername is AI (blank)\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, i); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] i = %d, playername is AI (blank)\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, i); #endif - Lang & lang = Lang::getInstance (); - gameSettings->setNetworkPlayerName (slotIndex, - lang.getString ("AI") + - intToStr (AIPlayerCount)); - labelPlayerNames[i].setText (""); - } - if (listBoxControls[i].getSelectedItemIndex () == ctHuman) - { - setSlotHuman (i); - } - if (serverInterface != NULL - && serverInterface->getSlot (i, true) != NULL) - { - gameSettings->setNetworkPlayerUUID (slotIndex, - serverInterface->getSlot (i, - true)->getUUID - ()); - gameSettings->setNetworkPlayerPlatform (slotIndex, - serverInterface->getSlot - (i, - true)->getPlatform ()); - } + Lang & lang = Lang::getInstance(); + gameSettings->setNetworkPlayerName(slotIndex, + lang.getString("AI") + + intToStr(AIPlayerCount)); + labelPlayerNames[i].setText(""); + } + if (listBoxControls[i].getSelectedItemIndex() == ctHuman) { + setSlotHuman(i); + } + if (serverInterface != NULL + && serverInterface->getSlot(i, true) != NULL) { + gameSettings->setNetworkPlayerUUID(slotIndex, + serverInterface->getSlot(i, + true)->getUUID + ()); + gameSettings->setNetworkPlayerPlatform(slotIndex, + serverInterface->getSlot + (i, + true)->getPlatform()); + } - factionCount++; - } - else - { -//gameSettings->setNetworkPlayerName(""); - gameSettings->setNetworkPlayerStatuses (factionCount, npst_None); - labelPlayerNames[i].setText (""); - } - } + factionCount++; + } else { + //gameSettings->setNetworkPlayerName(""); + gameSettings->setNetworkPlayerStatuses(factionCount, npst_None); + labelPlayerNames[i].setText(""); + } + } -// Next save closed slots - int closedCount = 0; - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - ControlType ct = - static_cast < ControlType > - (listBoxControls[i].getSelectedItemIndex ()); - if (ct == ctClosed) - { - int slotIndex = factionCount + closedCount; + // Next save closed slots + int closedCount = 0; + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + ControlType ct = + static_cast + (listBoxControls[i].getSelectedItemIndex()); + if (ct == ctClosed) { + int slotIndex = factionCount + closedCount; - gameSettings->setFactionControl (slotIndex, ct); - gameSettings->setTeam (slotIndex, - listBoxTeams[i].getSelectedItemIndex ()); - gameSettings->setStartLocationIndex (slotIndex, i); -//gameSettings->setResourceMultiplierIndex(slotIndex, 10); - listBoxRMultiplier[i].setSelectedItem ("1.0"); - gameSettings->setResourceMultiplierIndex (slotIndex, - listBoxRMultiplier - [i].getSelectedItemIndex - ()); -//printf("Test multiplier = %s\n",listBoxRMultiplier[i].getSelectedItem().c_str()); + gameSettings->setFactionControl(slotIndex, ct); + gameSettings->setTeam(slotIndex, + listBoxTeams[i].getSelectedItemIndex()); + gameSettings->setStartLocationIndex(slotIndex, i); + //gameSettings->setResourceMultiplierIndex(slotIndex, 10); + listBoxRMultiplier[i].setSelectedItem("1.0"); + gameSettings->setResourceMultiplierIndex(slotIndex, + listBoxRMultiplier + [i].getSelectedItemIndex + ()); + //printf("Test multiplier = %s\n",listBoxRMultiplier[i].getSelectedItem().c_str()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] i = %d, factionFiles[listBoxFactions[i].getSelectedItemIndex()] [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, i, - factionFiles[listBoxFactions - [i].getSelectedItemIndex - ()].c_str ()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] i = %d, factionFiles[listBoxFactions[i].getSelectedItemIndex()] [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, i, + factionFiles[listBoxFactions + [i].getSelectedItemIndex + ()].c_str()); - gameSettings->setFactionTypeName (slotIndex, - factionFiles[listBoxFactions - [i].getSelectedItemIndex - ()]); - gameSettings->setNetworkPlayerName (slotIndex, - GameConstants::NETWORK_SLOT_CLOSED_SLOTNAME); - gameSettings->setNetworkPlayerUUID (slotIndex, ""); - gameSettings->setNetworkPlayerPlatform (slotIndex, ""); + gameSettings->setFactionTypeName(slotIndex, + factionFiles[listBoxFactions + [i].getSelectedItemIndex + ()]); + gameSettings->setNetworkPlayerName(slotIndex, + GameConstants::NETWORK_SLOT_CLOSED_SLOTNAME); + gameSettings->setNetworkPlayerUUID(slotIndex, ""); + gameSettings->setNetworkPlayerPlatform(slotIndex, ""); - closedCount++; - } - } + closedCount++; + } + } - gameSettings->setFactionCount (factionCount); + gameSettings->setFactionCount(factionCount); - Config & config = Config::getInstance (); - gameSettings->setEnableServerControlledAI (config.getBool - ("ServerControlledAI", - "true")); - gameSettings-> - setNetworkFramePeriod (config.getInt ("NetworkSendFrameCount", "20")); - gameSettings->setNetworkPauseGameForLaggedClients (((checkBoxNetworkPauseGameForLaggedClients.getValue () == true))); + Config & config = Config::getInstance(); + gameSettings->setEnableServerControlledAI(config.getBool + ("ServerControlledAI", + "true")); + gameSettings-> + setNetworkFramePeriod(config.getInt("NetworkSendFrameCount", "20")); + gameSettings->setNetworkPauseGameForLaggedClients(((checkBoxNetworkPauseGameForLaggedClients.getValue() == true))); - if (gameSettings->getTileset () != "") - { -// Check if client has different data, if so force a CRC refresh - bool forceRefresh = false; - if (checkNetworkPlayerDataSynch (false, true, false) == false && - last_Forced_CheckedCRCTilesetName != gameSettings->getTileset ()) - { - lastCheckedCRCTilesetName = ""; - forceRefresh = true; - last_Forced_CheckedCRCTilesetName = gameSettings->getTileset (); - } + if (gameSettings->getTileset() != "") { + // Check if client has different data, if so force a CRC refresh + bool forceRefresh = false; + if (checkNetworkPlayerDataSynch(false, true, false) == false && + last_Forced_CheckedCRCTilesetName != gameSettings->getTileset()) { + lastCheckedCRCTilesetName = ""; + forceRefresh = true; + last_Forced_CheckedCRCTilesetName = gameSettings->getTileset(); + } - if (lastCheckedCRCTilesetName != gameSettings->getTileset ()) - { -//console.addLine("Checking tileset CRC [" + gameSettings->getTileset() + "]"); - lastCheckedCRCTilesetValue = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTilesets, ""), - string ("/") + gameSettings->getTileset () + string ("/*"), - ".xml", NULL, forceRefresh); - if (lastCheckedCRCTilesetValue == 0) - { - lastCheckedCRCTilesetValue = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTilesets, ""), - string ("/") + gameSettings->getTileset () + string ("/*"), - ".xml", NULL, true); - } - lastCheckedCRCTilesetName = gameSettings->getTileset (); - } - gameSettings->setTilesetCRC (lastCheckedCRCTilesetValue); - } + if (lastCheckedCRCTilesetName != gameSettings->getTileset()) { + //console.addLine("Checking tileset CRC [" + gameSettings->getTileset() + "]"); + lastCheckedCRCTilesetValue = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTilesets, ""), + string("/") + gameSettings->getTileset() + string("/*"), + ".xml", NULL, forceRefresh); + if (lastCheckedCRCTilesetValue == 0) { + lastCheckedCRCTilesetValue = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTilesets, ""), + string("/") + gameSettings->getTileset() + string("/*"), + ".xml", NULL, true); + } + lastCheckedCRCTilesetName = gameSettings->getTileset(); + } + gameSettings->setTilesetCRC(lastCheckedCRCTilesetValue); + } - if (config.getBool ("DisableServerLobbyTechtreeCRCCheck", "false") == - false) - { - if (gameSettings->getTech () != "") - { -// Check if client has different data, if so force a CRC refresh - bool forceRefresh = false; - if (checkNetworkPlayerDataSynch (false, false, true) == false && - last_Forced_CheckedCRCTechtreeName != gameSettings->getTech ()) - { - lastCheckedCRCTechtreeName = ""; - forceRefresh = true; - last_Forced_CheckedCRCTechtreeName = gameSettings->getTech (); - } + if (config.getBool("DisableServerLobbyTechtreeCRCCheck", "false") == + false) { + if (gameSettings->getTech() != "") { + // Check if client has different data, if so force a CRC refresh + bool forceRefresh = false; + if (checkNetworkPlayerDataSynch(false, false, true) == false && + last_Forced_CheckedCRCTechtreeName != gameSettings->getTech()) { + lastCheckedCRCTechtreeName = ""; + forceRefresh = true; + last_Forced_CheckedCRCTechtreeName = gameSettings->getTech(); + } - if (lastCheckedCRCTechtreeName != gameSettings->getTech ()) - { -//console.addLine("Checking techtree CRC [" + gameSettings->getTech() + "]"); - lastCheckedCRCTechtreeValue = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), - "/" + gameSettings->getTech () + "/*", ".xml", NULL, - forceRefresh); - if (lastCheckedCRCTechtreeValue == 0) - { - lastCheckedCRCTechtreeValue = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), - "/" + gameSettings->getTech () + "/*", ".xml", NULL, true); - } + if (lastCheckedCRCTechtreeName != gameSettings->getTech()) { + //console.addLine("Checking techtree CRC [" + gameSettings->getTech() + "]"); + lastCheckedCRCTechtreeValue = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), + "/" + gameSettings->getTech() + "/*", ".xml", NULL, + forceRefresh); + if (lastCheckedCRCTechtreeValue == 0) { + lastCheckedCRCTechtreeValue = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), + "/" + gameSettings->getTech() + "/*", ".xml", NULL, true); + } - reloadFactions (true, - (checkBoxScenario.getValue () == - true ? - scenarioFiles - [listBoxScenario.getSelectedItemIndex ()] : "")); - factionCRCList.clear (); - for (unsigned int factionIdx = 0; - factionIdx < factionFiles.size (); ++factionIdx) - { - string factionName = factionFiles[factionIdx]; - if (factionName != GameConstants::RANDOMFACTION_SLOTNAME - && factionName != GameConstants::OBSERVER_SLOTNAME) - { -//factionCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + gameSettings->getTech() + "/factions/" + factionName + "/*", ".xml", NULL, true); - uint32 factionCRC = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, - ""), - "/" + - gameSettings->getTech - () + "/factions/" + factionName + "/*", - ".xml", - NULL); - if (factionCRC == 0) - { - factionCRC = - getFolderTreeContentsCheckSumRecursively - (config.getPathListForType (ptTechs, ""), - "/" + gameSettings->getTech () + - "/factions/" + factionName + "/*", ".xml", NULL, true); - } - factionCRCList.push_back (make_pair - (factionName, factionCRC)); - } - } -//console.addLine("Found factions: " + intToStr(factionCRCList.size())); - lastCheckedCRCTechtreeName = gameSettings->getTech (); - } + reloadFactions(true, + (checkBoxScenario.getValue() == + true ? + scenarioFiles + [listBoxScenario.getSelectedItemIndex()] : "")); + factionCRCList.clear(); + for (unsigned int factionIdx = 0; + factionIdx < factionFiles.size(); ++factionIdx) { + string factionName = factionFiles[factionIdx]; + if (factionName != GameConstants::RANDOMFACTION_SLOTNAME + && factionName != GameConstants::OBSERVER_SLOTNAME) { + //factionCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,""), "/" + gameSettings->getTech() + "/factions/" + factionName + "/*", ".xml", NULL, true); + uint32 factionCRC = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, + ""), + "/" + + gameSettings->getTech + () + "/factions/" + factionName + "/*", + ".xml", + NULL); + if (factionCRC == 0) { + factionCRC = + getFolderTreeContentsCheckSumRecursively + (config.getPathListForType(ptTechs, ""), + "/" + gameSettings->getTech() + + "/factions/" + factionName + "/*", ".xml", NULL, true); + } + factionCRCList.push_back(make_pair + (factionName, factionCRC)); + } + } + //console.addLine("Found factions: " + intToStr(factionCRCList.size())); + lastCheckedCRCTechtreeName = gameSettings->getTech(); + } - gameSettings->setFactionCRCList (factionCRCList); - gameSettings->setTechCRC (lastCheckedCRCTechtreeValue); - } - } + gameSettings->setFactionCRCList(factionCRCList); + gameSettings->setTechCRC(lastCheckedCRCTechtreeValue); + } + } - if (gameSettings->getMap () != "") - { -// Check if client has different data, if so force a CRC refresh -//bool forceRefresh = false; - if (checkNetworkPlayerDataSynch (true, false, false) == false && - last_Forced_CheckedCRCMapName != gameSettings->getMap ()) - { - lastCheckedCRCMapName = ""; -//forceRefresh = true; - last_Forced_CheckedCRCMapName = gameSettings->getMap (); - } + if (gameSettings->getMap() != "") { + // Check if client has different data, if so force a CRC refresh + //bool forceRefresh = false; + if (checkNetworkPlayerDataSynch(true, false, false) == false && + last_Forced_CheckedCRCMapName != gameSettings->getMap()) { + lastCheckedCRCMapName = ""; + //forceRefresh = true; + last_Forced_CheckedCRCMapName = gameSettings->getMap(); + } - if (lastCheckedCRCMapName != gameSettings->getMap ()) - { - Checksum checksum; - string file = - Config::getMapPath (gameSettings->getMap (), "", false); -//console.addLine("Checking map CRC [" + file + "]"); - checksum.addFile (file); - lastCheckedCRCMapValue = checksum.getSum (); - lastCheckedCRCMapName = gameSettings->getMap (); - } - gameSettings->setMapCRC (lastCheckedCRCMapValue); - } + if (lastCheckedCRCMapName != gameSettings->getMap()) { + Checksum checksum; + string file = + Config::getMapPath(gameSettings->getMap(), "", false); + //console.addLine("Checking map CRC [" + file + "]"); + checksum.addFile(file); + lastCheckedCRCMapValue = checksum.getSum(); + lastCheckedCRCMapName = gameSettings->getMap(); + } + gameSettings->setMapCRC(lastCheckedCRCMapValue); + } - if (this->headlessServerMode == true) - { - time_t clientConnectedTime = 0; - bool masterserver_admin_found = false; + if (this->headlessServerMode == true) { + time_t clientConnectedTime = 0; + bool masterserver_admin_found = false; - for (int i = 0; i < mapInfo.players; ++i) - { + for (int i = 0; i < mapInfo.players; ++i) { #ifdef DEBUG - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); #endif - if (listBoxControls[i].getSelectedItemIndex () == ctNetwork - || listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (serverInterface->getSlot (i, true) != NULL - && serverInterface->getSlot (i, true)->isConnected ()) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//printf("slot = %d serverInterface->getSlot(i)->getConnectedTime() = %d session key [%d]\n",i,serverInterface->getSlot(i)->getConnectedTime(),serverInterface->getSlot(i)->getSessionKey()); - - if (clientConnectedTime == 0 || - (serverInterface->getSlot (i, true)->getConnectedTime () > 0 - && serverInterface->getSlot (i, - true)->getConnectedTime () < - clientConnectedTime)) - { - clientConnectedTime = - serverInterface->getSlot (i, true)->getConnectedTime (); - gameSettings->setMasterserver_admin (serverInterface->getSlot - (i, - true)->getSessionKey - ()); - gameSettings->setMasterserver_admin_faction_index - (serverInterface->getSlot (i, true)->getPlayerIndex ()); - labelGameName.setText (createGameName - (serverInterface-> - getSlot (i, true)->getName ())); -//printf("slot = %d, admin key [%d] slot connected time[" MG_SIZE_T_SPECIFIER "] clientConnectedTime [" MG_SIZE_T_SPECIFIER "]\n",i,gameSettings->getMasterserver_admin(),serverInterface->getSlot(i)->getConnectedTime(),clientConnectedTime); - } - if (serverInterface->getSlot (i, true)->getSessionKey () == - gameSettings->getMasterserver_admin ()) - { - masterserver_admin_found = true; - } - } - } - } - if (masterserver_admin_found == false) - { - for (int i = mapInfo.players; i < GameConstants::maxPlayers; ++i) - { - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); -//ConnectionSlot *slot = serverInterface->getSlot(i); - - if (serverInterface->getSlot (i, true) != NULL - && serverInterface->getSlot (i, true)->isConnected ()) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//printf("slot = %d serverInterface->getSlot(i)->getConnectedTime() = %d session key [%d]\n",i,serverInterface->getSlot(i)->getConnectedTime(),serverInterface->getSlot(i)->getSessionKey()); - - if (clientConnectedTime == 0 || - (serverInterface->getSlot (i, true)->getConnectedTime () > 0 - && serverInterface->getSlot (i, - true)->getConnectedTime () < - clientConnectedTime)) - { - clientConnectedTime = - serverInterface->getSlot (i, true)->getConnectedTime (); - gameSettings->setMasterserver_admin (serverInterface->getSlot - (i, - true)->getSessionKey - ()); - gameSettings->setMasterserver_admin_faction_index - (serverInterface->getSlot (i, true)->getPlayerIndex ()); - labelGameName.setText (createGameName - (serverInterface-> - getSlot (i, true)->getName ())); -//printf("slot = %d, admin key [%d] slot connected time[" MG_SIZE_T_SPECIFIER "] clientConnectedTime [" MG_SIZE_T_SPECIFIER "]\n",i,gameSettings->getMasterserver_admin(),serverInterface->getSlot(i)->getConnectedTime(),clientConnectedTime); - } - if (serverInterface->getSlot (i, true)->getSessionKey () == - gameSettings->getMasterserver_admin ()) - { - masterserver_admin_found = true; - } - } - } - } - - if (masterserver_admin_found == false) - { - labelGameName.setText (createGameName ()); - } - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - void MenuStateCustomGame::saveGameSettingsToFile (std::string fileName) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - GameSettings gameSettings; - loadGameSettings (&gameSettings); - CoreData::getInstance ().saveGameSettingsToFile (fileName, - &gameSettings, - checkBoxAdvanced.getValue - ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - void MenuStateCustomGame::KeepCurrentHumanPlayerSlots (GameSettings & - gameSettings) - { -//look for human players - bool foundValidHumanControlTypeInFile = false; - for (int index2 = 0; index2 < GameConstants::maxPlayers; ++index2) - { - ControlType ctFile = - static_cast < ControlType > - (gameSettings.getFactionControl (index2)); - if (ctFile == ctHuman) - { - ControlType ctUI = - static_cast < ControlType > - (listBoxControls[index2].getSelectedItemIndex ()); - if (ctUI != ctNetwork && ctUI != ctNetworkUnassigned) - { - foundValidHumanControlTypeInFile = true; -//printf("Human found in file [%d]\n",index2); - } - else if (labelPlayerNames[index2].getText () == "") - { - foundValidHumanControlTypeInFile = true; - } - } - } - - for (int index = 0; index < GameConstants::maxPlayers; ++index) - { - ControlType ct = - static_cast < ControlType > - (listBoxControls[index].getSelectedItemIndex ()); - if (ct == ctHuman) - { -//printf("Human found in UI [%d] and file [%d]\n",index,foundControlType); - - if (foundValidHumanControlTypeInFile == false) - { - gameSettings.setFactionControl (index, ctHuman); - gameSettings.setNetworkPlayerName (index, getHumanPlayerName ()); - } - } - - ControlType ctFile = - static_cast < ControlType > - (gameSettings.getFactionControl (index)); - if (ctFile == ctHuman) - { - gameSettings.setFactionControl (index, ctHuman); - } - } - } - - GameSettings MenuStateCustomGame::loadGameSettingsFromFile (std::string - fileName) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - GameSettings gameSettings; - - GameSettings originalGameSettings; - loadGameSettings (&originalGameSettings); - - try - { - CoreData::getInstance ().loadGameSettingsFromFile (fileName, - &gameSettings); - KeepCurrentHumanPlayerSlots (gameSettings); - -// correct game settings for headless: - if (this->headlessServerMode == true) - { - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - if (gameSettings.getFactionControl (i) == ctHuman) - { - gameSettings.setFactionControl (i, ctNetwork); - } - } - } - setupUIFromGameSettings (gameSettings); - } - catch (const exception & ex) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - ex.what ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] ERROR = [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, ex.what ()); - - showMessageBox (ex.what (), "Error", false); - - setupUIFromGameSettings (originalGameSettings); - gameSettings = originalGameSettings; - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - return gameSettings; - } - - void MenuStateCustomGame::setupUIFromGameSettings (const GameSettings & - gameSettings) - { - string humanPlayerName = getHumanPlayerName (); - - string scenarioDir = ""; - checkBoxScenario.setValue ((gameSettings.getScenario () != "")); - if (checkBoxScenario.getValue () == true) - { - listBoxScenario.setSelectedItem (formatString - (gameSettings.getScenario ())); - - loadScenarioInfo (Scenario::getScenarioPath (dirList, - scenarioFiles - [listBoxScenario.getSelectedItemIndex - ()]), &scenarioInfo); - scenarioDir = - Scenario::getScenarioDir (dirList, gameSettings.getScenario ()); - -//printf("scenarioInfo.fogOfWar = %d scenarioInfo.fogOfWar_exploredFlag = %d\n",scenarioInfo.fogOfWar,scenarioInfo.fogOfWar_exploredFlag); - if (scenarioInfo.fogOfWar == false - && scenarioInfo.fogOfWar_exploredFlag == false) - { - listBoxFogOfWar.setSelectedItemIndex (2); - } - else if (scenarioInfo.fogOfWar_exploredFlag == true) - { - listBoxFogOfWar.setSelectedItemIndex (1); - } - else - { - listBoxFogOfWar.setSelectedItemIndex (0); - } - checkBoxAllowTeamUnitSharing. - setValue (scenarioInfo.allowTeamUnitSharing); - checkBoxAllowTeamResourceSharing. - setValue (scenarioInfo.allowTeamResourceSharing); - } - setupMapList (gameSettings.getScenario ()); - setupTechList (gameSettings.getScenario (), false); - setupTilesetList (gameSettings.getScenario ()); - - if (checkBoxScenario.getValue () == true) - { -//string file = Scenario::getScenarioPath(dirList, gameSettings.getScenario()); -//loadScenarioInfo(file, &scenarioInfo); - -//printf("#6.1 about to load map [%s]\n",scenarioInfo.mapName.c_str()); -//loadMapInfo(Config::getMapPath(scenarioInfo.mapName, scenarioDir, true), &mapInfo, false); -//printf("#6.2\n"); - - listBoxMapFilter.setSelectedItemIndex (0); - listBoxMap.setItems (formattedPlayerSortedMaps[mapInfo.hardMaxPlayers]); - listBoxMap.setSelectedItem (formatString (scenarioInfo.mapName)); - } - else - { -//printf("gameSettings.getMapFilter()=%d \n",gameSettings.getMapFilter()); - if (gameSettings.getMapFilter () == 0) - { - listBoxMapFilter.setSelectedItemIndex (0); - } - else - { - listBoxMapFilter.setSelectedItem (intToStr - (gameSettings.getMapFilter ())); - } - listBoxMap.setItems (formattedPlayerSortedMaps - [gameSettings.getMapFilter ()]); - } - -//printf("gameSettings.getMap() [%s] [%s]\n",gameSettings.getMap().c_str(),listBoxMap.getSelectedItem().c_str()); - - string mapFile = gameSettings.getMap (); - if (find (mapFiles.begin (), mapFiles.end (), mapFile) != - mapFiles.end ()) - { - mapFile = formatString (mapFile); - listBoxMap.setSelectedItem (mapFile); - - loadMapInfo (Config::getMapPath - (getCurrentMapFile (), scenarioDir, true), &mapInfo, - true); - labelMapInfo.setText (mapInfo.desc); - } - - string tilesetFile = gameSettings.getTileset (); - if (find (tilesetFiles.begin (), tilesetFiles.end (), tilesetFile) != - tilesetFiles.end ()) - { - tilesetFile = formatString (tilesetFile); - listBoxTileset.setSelectedItem (tilesetFile); - } - - string techtreeFile = gameSettings.getTech (); - if (find (techTreeFiles.begin (), techTreeFiles.end (), techtreeFile) != - techTreeFiles.end ()) - { - techtreeFile = formatString (techtreeFile); - listBoxTechTree.setSelectedItem (techtreeFile); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//gameSettings->setDefaultUnits(true); -//gameSettings->setDefaultResources(true); -//gameSettings->setDefaultVictoryConditions(true); - -//FogOfWar - if (checkBoxScenario.getValue () == false) - { - listBoxFogOfWar.setSelectedItemIndex (0); // default is 0! - if (gameSettings.getFogOfWar () == false) - { - listBoxFogOfWar.setSelectedItemIndex (2); - } - - if ((gameSettings.getFlagTypes1 () & ft1_show_map_resources) == - ft1_show_map_resources) - { - if (gameSettings.getFogOfWar () == true) - { - listBoxFogOfWar.setSelectedItemIndex (1); - } - } - } - -//printf("In [%s::%s line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - checkBoxAllowObservers.setValue (gameSettings.getAllowObservers () == - true ? true : false); -//listBoxEnableObserverMode.setSelectedItem(gameSettings.getEnableObserverModeAtEndGame() == true ? lang.getString("Yes") : lang.getString("No")); - - checkBoxEnableSwitchTeamMode.setValue ((gameSettings.getFlagTypes1 () & - ft1_allow_team_switching) == - ft1_allow_team_switching ? true : - false); - listBoxAISwitchTeamAcceptPercent.setSelectedItem (intToStr - (gameSettings.getAiAcceptSwitchTeamPercentChance - ())); - listBoxFallbackCpuMultiplier. - setSelectedItemIndex (gameSettings.getFallbackCpuMultiplier ()); - - checkBoxAllowInGameJoinPlayer.setValue ((gameSettings.getFlagTypes1 () & - ft1_allow_in_game_joining) == - ft1_allow_in_game_joining ? true - : false); - - checkBoxAllowTeamUnitSharing.setValue ((gameSettings.getFlagTypes1 () & - ft1_allow_shared_team_units) == - ft1_allow_shared_team_units ? - true : false); - checkBoxAllowTeamResourceSharing.setValue ((gameSettings.getFlagTypes1 - () & - ft1_allow_shared_team_resources) - == - ft1_allow_shared_team_resources - ? true : false); - - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - if (serverInterface != NULL) - { - serverInterface->setAllowInGameConnections - (checkBoxAllowInGameJoinPlayer.getValue () == true); - } - - checkBoxAllowNativeLanguageTechtree. - setValue (gameSettings.getNetworkAllowNativeLanguageTechtree ()); - -//listBoxPathFinderType.setSelectedItemIndex(gameSettings.getPathFinderType()); - -//listBoxEnableServerControlledAI.setSelectedItem(gameSettings.getEnableServerControlledAI() == true ? lang.getString("Yes") : lang.getString("No")); - -//labelNetworkFramePeriod.setText(lang.getString("NetworkFramePeriod")); - -//listBoxNetworkFramePeriod.setSelectedItem(intToStr(gameSettings.getNetworkFramePeriod()/10*10)); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - checkBoxNetworkPauseGameForLaggedClients. - setValue (gameSettings.getNetworkPauseGameForLaggedClients ()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - reloadFactions (false, - (checkBoxScenario.getValue () == - true ? - scenarioFiles[listBoxScenario.getSelectedItemIndex ()] - : "")); -//reloadFactions(true); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d] gameSettings.getFactionCount() = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - gameSettings.getFactionCount ()); - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - int slotIndex = gameSettings.getStartLocationIndex (i); - if (gameSettings.getFactionControl (i) < - listBoxControls[slotIndex].getItemCount ()) - { - listBoxControls[slotIndex]. - setSelectedItemIndex (gameSettings.getFactionControl (i)); - } - -//if(slotIndex == 0) printf("#2 slotIndex = %d, i = %d, multiplier = %d\n",slotIndex,i,listBoxRMultiplier[i].getSelectedItemIndex()); - - updateResourceMultiplier (slotIndex); - -//if(slotIndex == 0) printf("#3 slotIndex = %d, i = %d, multiplier = %d\n",slotIndex,i,listBoxRMultiplier[i].getSelectedItemIndex()); - - listBoxRMultiplier[slotIndex]. - setSelectedItemIndex (gameSettings.getResourceMultiplierIndex (i)); - -//if(slotIndex == 0) printf("#4 slotIndex = %d, i = %d, multiplier = %d\n",slotIndex,i,listBoxRMultiplier[i].getSelectedItemIndex()); - - listBoxTeams[slotIndex]. - setSelectedItemIndex (gameSettings.getTeam (i)); - - lastSelectedTeamIndex[slotIndex] = - listBoxTeams[slotIndex].getSelectedItemIndex (); - - string factionName = gameSettings.getFactionTypeName (i); - factionName = formatString (factionName); - -//printf("\n\n\n*** setupUIFromGameSettings A, i = %d, startLoc = %d, factioncontrol = %d, factionName [%s]\n",i,gameSettings.getStartLocationIndex(i),gameSettings.getFactionControl(i),factionName.c_str()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] factionName = [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, factionName.c_str ()); - - if (listBoxFactions[slotIndex].hasItem (factionName) == true) - { - listBoxFactions[slotIndex].setSelectedItem (factionName); - } - else - { - listBoxFactions[slotIndex].setSelectedItem (formatString - (GameConstants:: - RANDOMFACTION_SLOTNAME)); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] i = %d, gameSettings.getNetworkPlayerName(i) [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, i, - gameSettings. - getNetworkPlayerName (i).c_str ()); - -//labelPlayerNames[slotIndex].setText(gameSettings.getNetworkPlayerName(i)); - } - -//SetActivePlayerNameEditor(); - - updateControllers (); - updateNetworkSlots (); - - if (this->headlessServerMode == false && humanPlayerName != "") - { - for (int index = 0; index < GameConstants::maxPlayers; ++index) - { - ControlType ct = - static_cast < ControlType > - (listBoxControls[index].getSelectedItemIndex ()); - if (ct == ctHuman) - { - if (humanPlayerName != labelPlayerNames[index].getText ()) - { -//printf("Player name changing from [%s] to [%s]\n",labelPlayerNames[index].getText().c_str(),humanPlayerName.c_str()); - - labelPlayerNames[index].setText (""); - labelPlayerNames[index].setText (humanPlayerName); - } - } - } - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } -// ============ PRIVATE =========================== - - void MenuStateCustomGame::lastPlayerDisconnected () - { -// this is for headless mode only! -// if last player disconnects we load the network defaults. - if (this->headlessServerMode == false) - { - return; - } - - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - bool foundConnectedPlayer = false; - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - if (serverInterface->getSlot (i, true) != NULL && - (listBoxControls[i].getSelectedItemIndex () == ctNetwork || - listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned)) - { - if (serverInterface->getSlot (i, true)->isConnected () == true) - { - foundConnectedPlayer = true; - } - } - } - - if (!foundConnectedPlayer && headlessHasConnectedPlayer == true) - { -// load defaults - string data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - if (fileExists (data_path + DEFAULT_NETWORKGAME_FILENAME) == true) - loadGameSettings (data_path + DEFAULT_NETWORKGAME_FILENAME); - } - headlessHasConnectedPlayer = foundConnectedPlayer; - } - - bool MenuStateCustomGame::hasNetworkGameSettings () - { - bool hasNetworkSlot = false; - - try - { - for (int i = 0; i < mapInfo.players; ++i) - { - ControlType ct = - static_cast < ControlType > - (listBoxControls[i].getSelectedItemIndex ()); - if (ct != ctClosed) - { - if (ct == ctNetwork || ct == ctNetworkUnassigned) - { - hasNetworkSlot = true; - break; - } - } - } - if (hasNetworkSlot == false) - { - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - ControlType ct = - static_cast < ControlType > - (listBoxControls[i].getSelectedItemIndex ()); - if (ct != ctClosed) - { - if (ct == ctNetworkUnassigned) - { - hasNetworkSlot = true; - break; - } - } - } - } - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - ex.what ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - showGeneralError = true; - generalErrorToShow = szBuf; - } - - return hasNetworkSlot; - } - - void MenuStateCustomGame::loadMapInfo (string file, MapInfo * mapInfo, - bool loadMapPreview) - { - try - { - Lang & lang = Lang::getInstance (); - if (MapPreview::loadMapInfo - (file, mapInfo, lang.getString ("MaxPlayers"), - lang.getString ("Size"), true) == true) - { - // Though we prefer not to change the actual value of mapInfo->players, - // which is the number of players assigned when making the map, we still know - // the actual value from mapInfo.hardMaxPlayers. Changing it here means - // not having to change a variable name in many places of this file - // to implement enhanced observer mode (issue #13)' - if (checkBoxAllowObservers.getValue () == 1) - { - mapInfo->players = GameConstants::maxPlayers; - } - - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - if (serverInterface->getSlot (i, true) != NULL && - (listBoxControls[i].getSelectedItemIndex () == ctNetwork - || listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned)) - { - if (serverInterface->getSlot (i, true)->isConnected () == true) - { - if (i + 1 > mapInfo->players && - listBoxControls[i].getSelectedItemIndex () != - ctNetworkUnassigned) - { - listBoxControls[i].setSelectedItemIndex - (ctNetworkUnassigned); - } - } - } - } - -// Not painting properly so this is on hold - if (loadMapPreview == true) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - mapPreview.loadFromFile (file.c_str ()); - -//printf("Loading map preview MAP\n"); - cleanupMapPreviewTexture (); - } - } - } - catch (exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s] loading map [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - e.what (), file.c_str ()); - throw megaglest_runtime_error ("Error loading map file: [" + file + - "] msg: " + e.what ()); - } - } - - void MenuStateCustomGame::closeUnusedSlots () - { - try - { - if (checkBoxScenario.getValue () == false) - { - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); -//for(int i= 0; igetSlot (i, true) == NULL || - serverInterface->getSlot (i, - true)->isConnected () == - false - || serverInterface->getSlot (i, - true)->getConnectHasHandshaked - () == false) - { -//printf("Closed A [%d] [%s]\n",i,labelPlayerNames[i].getText().c_str()); - - listBoxControls[i].setSelectedItemIndex (ctClosed); - } - } - } - updateNetworkSlots (); - } - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw megaglest_runtime_error (szBuf); - } - } - - bool MenuStateCustomGame::textInput (std::string text) - { -//printf("In [%s::%s Line: %d] text [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,text.c_str()); - if (activeInputLabel != NULL) - { - bool handled = textInputEditLabel (text, &activeInputLabel); - if (handled == true && &labelGameName != activeInputLabel) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - } - else - { - if (hasNetworkGameSettings () == true) - { - chatManager.textInput (text); - } - } - return false; - } - - void MenuStateCustomGame::keyDown (SDL_KeyboardEvent key) - { - if (isMasterserverMode () == true) - { - return; - } - - if (activeInputLabel != NULL) - { - bool handled = keyDownEditLabel (key, &activeInputLabel); - if (handled == true) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - } - else - { -//send key to the chat manager - if (hasNetworkGameSettings () == true) - { - chatManager.keyDown (key); - } - if (chatManager.getEditEnabled () == false && - (::Shared::Platform::Window::isKeyStateModPressed (KMOD_SHIFT) == - false)) - { - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - -//if(key == configKeys.getCharKey("ShowFullConsole")) { - if (isKeyPressed (configKeys.getSDLKey ("ShowFullConsole"), key) - == true) - { - showFullConsole = true; - } -//Toggle music -//else if(key == configKeys.getCharKey("ToggleMusic")) { - else - if (isKeyPressed (configKeys.getSDLKey ("ToggleMusic"), key) - == true) - { - Config & config = Config::getInstance (); - Lang & lang = Lang::getInstance (); - - float configVolume = (config.getInt ("SoundVolumeMusic") / 100.f); - float currentVolume = - CoreData::getInstance ().getMenuMusic ()->getVolume (); - if (currentVolume > 0) - { - CoreData::getInstance ().getMenuMusic ()->setVolume (0.f); - console.addLine (lang.getString ("GameMusic") + " " + - lang.getString ("Off")); - } - else - { - CoreData::getInstance (). - getMenuMusic ()->setVolume (configVolume); -//If the config says zero, use the default music volume -//gameMusic->setVolume(configVolume ? configVolume : 0.9); - console.addLine (lang.getString ("GameMusic")); - } - } -//else if(key == configKeys.getCharKey("SaveGUILayout")) { - else - if (isKeyPressed (configKeys.getSDLKey ("SaveGUILayout"), key) - == true) - { - bool saved = - GraphicComponent::saveAllCustomProperties (containerName); - Lang & lang = Lang::getInstance (); - console.addLine (lang.getString ("GUILayoutSaved") + " [" + - (saved ? lang. - getString ("Yes") : lang.getString ("No")) + - "]"); - } - } - } - } - - void MenuStateCustomGame::keyPress (SDL_KeyboardEvent c) - { - if (isMasterserverMode () == true) - { - return; - } - - if (activeInputLabel != NULL) - { - bool handled = keyPressEditLabel (c, &activeInputLabel); - if (handled == true && &labelGameName != activeInputLabel) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - } - } - else - { - if (hasNetworkGameSettings () == true) - { - chatManager.keyPress (c); - } - } - } - - void MenuStateCustomGame::keyUp (SDL_KeyboardEvent key) - { - if (isMasterserverMode () == true) - { - return; - } - - if (activeInputLabel == NULL) - { - if (hasNetworkGameSettings () == true) - { - chatManager.keyUp (key); - } - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - - if (chatManager.getEditEnabled ()) - { -//send key to the chat manager - if (hasNetworkGameSettings () == true) - { - chatManager.keyUp (key); - } - } -//else if(key == configKeys.getCharKey("ShowFullConsole")) { - else - if (isKeyPressed (configKeys.getSDLKey ("ShowFullConsole"), key) - == true) - { - showFullConsole = false; - } - } - } - - void MenuStateCustomGame::showMessageBox (const string & text, - const string & header, - bool toggle) - { - if (!toggle) - { - mainMessageBox.setEnabled (false); - } - - if (!mainMessageBox.getEnabled ()) - { - mainMessageBox.setText (text); - mainMessageBox.setHeader (header); - mainMessageBox.setEnabled (true); - } - else - { - mainMessageBox.setEnabled (false); - } - } - - void MenuStateCustomGame::switchToNextMapGroup (const int direction) - { - int i = listBoxMapFilter.getSelectedItemIndex (); -// if there are no maps for the current selection we switch to next selection - while (formattedPlayerSortedMaps[i].empty ()) - { - i = i + direction; - if (i > GameConstants::maxPlayers) - { - i = 0; - } - if (i < 0) - { - i = GameConstants::maxPlayers; - } - } - listBoxMapFilter.setSelectedItemIndex (i); - listBoxMap.setItems (formattedPlayerSortedMaps[i]); - } - - string MenuStateCustomGame::getCurrentMapFile () - { - int i = listBoxMapFilter.getSelectedItemIndex (); - int mapIndex = listBoxMap.getSelectedItemIndex (); - if (playerSortedMaps[i].empty () == false) - { - return playerSortedMaps[i].at (mapIndex); - } - return ""; - } - - void MenuStateCustomGame::setActiveInputLabel (GraphicLabel * newLable) - { - MenuState::setActiveInputLabel (newLable, &activeInputLabel); - } - - string MenuStateCustomGame::getHumanPlayerName (int index) - { - string result = defaultPlayerName; - if (index < 0) - { - for (int j = 0; j < GameConstants::maxPlayers; ++j) - { - if (listBoxControls[j].getSelectedItemIndex () >= 0) - { - ControlType ct = - static_cast < ControlType > - (listBoxControls[j].getSelectedItemIndex ()); - if (ct == ctHuman) - { - index = j; - break; - } - } - } - } - - if (index >= 0 && index < GameConstants::maxPlayers && - labelPlayerNames[index].getText () != "" && - labelPlayerNames[index].getText () != - GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) - { - result = labelPlayerNames[index].getText (); - - if (activeInputLabel != NULL) - { - size_t found = result.find_last_of ("_"); - if (found != string::npos) - { - result = result.substr (0, found); - } - } - } - - return result; - } - - void MenuStateCustomGame::loadFactionTexture (string filepath) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (enableFactionTexturePreview == true) - { - if (filepath == "") - { - factionTexture = NULL; - } - else - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] filepath = [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - filepath.c_str ()); - - factionTexture = Renderer::findTexture (filepath); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } - } - } - - void MenuStateCustomGame::cleanupMapPreviewTexture () - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -//printf("CLEANUP map preview texture\n"); - - if (mapPreviewTexture != NULL) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - mapPreviewTexture->end (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - delete mapPreviewTexture; - mapPreviewTexture = NULL; - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - int32 MenuStateCustomGame::getNetworkPlayerStatus () - { - int32 result = npst_None; - switch (listBoxPlayerStatus.getSelectedItemIndex ()) - { - case 2: - result = npst_Ready; - break; - case 1: - result = npst_BeRightBack; - break; - case 0: - default: - result = npst_PickSettings; - break; - } - - return result; - } - - void MenuStateCustomGame::loadScenarioInfo (string file, - ScenarioInfo * scenarioInfo) - { -//printf("Load scenario file [%s]\n",file.c_str()); - bool isTutorial = Scenario::isGameTutorial (file); - Scenario::loadScenarioInfo (file, scenarioInfo, isTutorial); - -//cleanupPreviewTexture(); - previewLoadDelayTimer = time (NULL); - needToLoadTextures = true; - } - - bool MenuStateCustomGame::isInSpecialKeyCaptureEvent () - { - bool result = (chatManager.getEditEnabled () - || activeInputLabel != NULL); - return result; - } - - void MenuStateCustomGame::processScenario () - { - try - { - if (checkBoxScenario.getValue () == true) - { -//printf("listBoxScenario.getSelectedItemIndex() = %d [%s] scenarioFiles.size() = %d\n",listBoxScenario.getSelectedItemIndex(),listBoxScenario.getSelectedItem().c_str(),scenarioFiles.size()); - loadScenarioInfo (Scenario::getScenarioPath (dirList, - scenarioFiles - [listBoxScenario.getSelectedItemIndex - ()]), &scenarioInfo); - string scenarioDir = - Scenario::getScenarioDir (dirList, scenarioInfo.name); - -//printf("scenarioInfo.fogOfWar = %d scenarioInfo.fogOfWar_exploredFlag = %d\n",scenarioInfo.fogOfWar,scenarioInfo.fogOfWar_exploredFlag); - if (scenarioInfo.fogOfWar == false - && scenarioInfo.fogOfWar_exploredFlag == false) - { - listBoxFogOfWar.setSelectedItemIndex (2); - } - else if (scenarioInfo.fogOfWar_exploredFlag == true) - { - listBoxFogOfWar.setSelectedItemIndex (1); - } - else - { - listBoxFogOfWar.setSelectedItemIndex (0); - } - - checkBoxAllowTeamUnitSharing. - setValue (scenarioInfo.allowTeamUnitSharing); - checkBoxAllowTeamResourceSharing. - setValue (scenarioInfo.allowTeamResourceSharing); - - setupTechList (scenarioInfo.name, false); - listBoxTechTree.setSelectedItem (formatString - (scenarioInfo.techTreeName)); - reloadFactions (false, scenarioInfo.name); - - setupTilesetList (scenarioInfo.name); - listBoxTileset.setSelectedItem (formatString - (scenarioInfo.tilesetName)); - - checkBoxAllowObservers.setValue (false); - - setupMapList (scenarioInfo.name); - listBoxMap.setSelectedItem (formatString (scenarioInfo.mapName)); - loadMapInfo (Config::getMapPath - (getCurrentMapFile (), scenarioDir, true), &mapInfo, - true); - labelMapInfo.setText (mapInfo.desc); - -//printf("scenarioInfo.name [%s] [%s]\n",scenarioInfo.name.c_str(),listBoxMap.getSelectedItem().c_str()); - -// Loop twice to set the human slot or else it closes network slots in some cases - for (int humanIndex = 0; humanIndex < 2; ++humanIndex) - { - for (int i = 0; i < mapInfo.players; ++i) - { - listBoxRMultiplier[i].setSelectedItem (floatToStr - (scenarioInfo. - resourceMultipliers[i], - 1)); - - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - ConnectionSlot *slot = serverInterface->getSlot (i, true); - - int selectedControlItemIndex = - listBoxControls[i].getSelectedItemIndex (); - if (selectedControlItemIndex != ctNetwork - || (selectedControlItemIndex == ctNetwork - && (slot == NULL || slot->isConnected () == false))) - { - } - - listBoxControls[i]. - setSelectedItemIndex (scenarioInfo.factionControls[i]); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - -// Skip over networkunassigned -//if(listBoxControls[i].getSelectedItemIndex() == ctNetworkUnassigned && -// selectedControlItemIndex != ctNetworkUnassigned) { -// listBoxControls[i].mouseClick(x, y); -//} - -//look for human players - int humanIndex1 = -1; - int humanIndex2 = -1; - for (int j = 0; j < GameConstants::maxPlayers; ++j) - { - ControlType ct = - static_cast < ControlType > - (listBoxControls[j].getSelectedItemIndex ()); - if (ct == ctHuman) - { - if (humanIndex1 == -1) - { - humanIndex1 = j; - } - else - { - humanIndex2 = j; - } - } - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] humanIndex1 = %d, humanIndex2 = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, humanIndex1, humanIndex2); - -//no human - if (humanIndex1 == -1 && humanIndex2 == -1) - { - setSlotHuman (i); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] i = %d, labelPlayerNames[i].getText() [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, i, - labelPlayerNames[i].getText (). - c_str ()); - -//printf("humanIndex1 = %d humanIndex2 = %d i = %d listBoxControls[i].getSelectedItemIndex() = %d\n",humanIndex1,humanIndex2,i,listBoxControls[i].getSelectedItemIndex()); - } -//2 humans - else if (humanIndex1 != -1 && humanIndex2 != -1) - { - int closeSlotIndex = - (humanIndex1 == i ? humanIndex2 : humanIndex1); - int humanSlotIndex = - (closeSlotIndex == humanIndex1 ? humanIndex2 : humanIndex1); - - string origPlayName = - labelPlayerNames[closeSlotIndex].getText (); - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] closeSlotIndex = %d, origPlayName [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, closeSlotIndex, - origPlayName.c_str ()); -//printf("humanIndex1 = %d humanIndex2 = %d i = %d closeSlotIndex = %d humanSlotIndex = %d\n",humanIndex1,humanIndex2,i,closeSlotIndex,humanSlotIndex); - - listBoxControls[closeSlotIndex].setSelectedItemIndex - (ctClosed); - labelPlayerNames[humanSlotIndex].setText ((origPlayName != - "" ? origPlayName : - getHumanPlayerName - ())); - } - - ControlType ct = - static_cast < ControlType > - (listBoxControls[i].getSelectedItemIndex ()); - if (ct != ctClosed) - { -//updateNetworkSlots(); -//updateResourceMultiplier(i); - updateResourceMultiplier (i); - -//printf("Setting scenario faction i = %d [ %s]\n",i,scenarioInfo.factionTypeNames[i].c_str()); - listBoxFactions[i].setSelectedItem (formatString - (scenarioInfo.factionTypeNames - [i])); -//printf("DONE Setting scenario faction i = %d [ %s]\n",i,scenarioInfo.factionTypeNames[i].c_str()); - -// Disallow CPU players to be observers - if (factionFiles - [listBoxFactions[i].getSelectedItemIndex ()] == - formatString (GameConstants::OBSERVER_SLOTNAME) - && (listBoxControls[i].getSelectedItemIndex () == - ctCpuEasy - || listBoxControls[i].getSelectedItemIndex () == ctCpu - || listBoxControls[i].getSelectedItemIndex () == - ctCpuUltra - || listBoxControls[i].getSelectedItemIndex () == - ctCpuZeta)) - { - listBoxFactions[i].setSelectedItemIndex (0); - } -// - - listBoxTeams[i].setSelectedItem (intToStr - (scenarioInfo.teams[i])); - if (factionFiles[listBoxFactions[i].getSelectedItemIndex ()] - != formatString (GameConstants::OBSERVER_SLOTNAME)) - { - if (listBoxTeams[i].getSelectedItemIndex () + 1 != - (GameConstants::maxPlayers + fpt_Observer)) - { - lastSelectedTeamIndex[i] = - listBoxTeams[i].getSelectedItemIndex (); - } -// Alow Neutral cpu players - else if (listBoxControls[i].getSelectedItemIndex () == - ctCpuEasy - || listBoxControls[i].getSelectedItemIndex () == - ctCpu - || listBoxControls[i].getSelectedItemIndex () == - ctCpuUltra - || listBoxControls[i].getSelectedItemIndex () == - ctCpuZeta) - { - lastSelectedTeamIndex[i] = - listBoxTeams[i].getSelectedItemIndex (); - } - } - else - { - lastSelectedTeamIndex[i] = -1; - } - } - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL);; - } - } - } - - updateControllers (); - updateNetworkSlots (); - - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - } - if (hasNetworkGameSettings () == true) - { - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); - } - -//labelInfo.setText(scenarioInfo.desc); - } - else - { - setupMapList (""); - listBoxMap.setSelectedItem (formatString - (formattedPlayerSortedMaps[0][0])); - loadMapInfo (Config::getMapPath (getCurrentMapFile (), "", true), - &mapInfo, true); - - labelMapInfo.setText (mapInfo.desc); - - setupTechList ("", false); - reloadFactions (false, ""); - setupTilesetList (""); - updateControllers (); - } - SetupUIForScenarios (); - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - mainMessageBoxState = 1; - showMessageBox (szBuf, "Error detected", false); - } - } - - void MenuStateCustomGame::SetupUIForScenarios () - { - try - { - if (checkBoxScenario.getValue () == true) - { -// START - Disable changes to controls while in Scenario mode - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - listBoxControls[i].setEditable (false); - listBoxFactions[i].setEditable (false); - listBoxRMultiplier[i].setEditable (false); - listBoxTeams[i].setEditable (false); - } - listBoxFogOfWar.setEditable (false); - checkBoxAllowObservers.setEditable (false); - checkBoxAllowTeamUnitSharing.setEditable (false); - checkBoxAllowTeamResourceSharing.setEditable (false); -//listBoxPathFinderType.setEditable(false); - checkBoxEnableSwitchTeamMode.setEditable (false); - listBoxAISwitchTeamAcceptPercent.setEditable (false); - listBoxFallbackCpuMultiplier.setEditable (false); - listBoxMap.setEditable (false); - listBoxTileset.setEditable (false); - listBoxMapFilter.setEditable (false); - listBoxTechTree.setEditable (false); -// END - Disable changes to controls while in Scenario mode - } - else - { -// START - Disable changes to controls while in Scenario mode - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - listBoxControls[i].setEditable (true); - listBoxFactions[i].setEditable (true); - listBoxRMultiplier[i].setEditable (true); - listBoxTeams[i].setEditable (true); - } - listBoxFogOfWar.setEditable (true); - checkBoxAllowObservers.setEditable (true); - checkBoxAllowTeamUnitSharing.setEditable (true); - checkBoxAllowTeamResourceSharing.setEditable (true); -//listBoxPathFinderType.setEditable(true); - checkBoxEnableSwitchTeamMode.setEditable (true); - listBoxAISwitchTeamAcceptPercent.setEditable (true); - listBoxFallbackCpuMultiplier.setEditable (true); - listBoxMap.setEditable (true); - listBoxTileset.setEditable (true); - listBoxMapFilter.setEditable (true); - listBoxTechTree.setEditable (true); -// END - Disable changes to controls while in Scenario mode - } - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - throw megaglest_runtime_error (szBuf); - } - - } - - int MenuStateCustomGame::setupMapList (string scenario) - { - int initialMapSelection = 0; - - try - { - Config & config = Config::getInstance (); - vector < string > invalidMapList; - string scenarioDir = Scenario::getScenarioDir (dirList, scenario); - vector < string > pathList = - config.getPathListForType (ptMaps, scenarioDir); - vector < string > allMaps = - MapPreview::findAllValidMaps (pathList, scenarioDir, false, true, - &invalidMapList); - if (scenario != "") - { - vector < string > allMaps2 = - MapPreview:: - findAllValidMaps (config.getPathListForType (ptMaps, ""), "", - false, true, &invalidMapList); - copy (allMaps2.begin (), allMaps2.end (), - std::inserter (allMaps, allMaps.begin ())); - } -// sort map list non case sensitive - std::sort (allMaps.begin (), allMaps.end (), compareNonCaseSensitive); - - if (allMaps.empty ()) - { - throw megaglest_runtime_error ("No maps were found!"); - } - vector < string > results; - copy (allMaps.begin (), allMaps.end (), std::back_inserter (results)); - mapFiles = results; - - for (unsigned int i = 0; i < GameConstants::maxPlayers + 1; ++i) - { - playerSortedMaps[i].clear (); - formattedPlayerSortedMaps[i].clear (); - } - -// at index=0 fill in the whole list - copy (mapFiles.begin (), mapFiles.end (), - std::back_inserter (playerSortedMaps[0])); - copy (playerSortedMaps[0].begin (), playerSortedMaps[0].end (), - std::back_inserter (formattedPlayerSortedMaps[0])); - std::for_each (formattedPlayerSortedMaps[0].begin (), - formattedPlayerSortedMaps[0].end (), FormatString ()); - -// fill playerSortedMaps and formattedPlayerSortedMaps according to map player count - for (int i = 0; i < (int) mapFiles.size (); i++) - { // fetch info and put map in right list - loadMapInfo (Config::getMapPath - (mapFiles.at (i), scenarioDir, false), &mapInfo, - false); - - if (GameConstants::maxPlayers + 1 <= mapInfo.players) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Sorted map list [%d] does not match\ncurrent map playercount [%d]\nfor file [%s]\nmap [%s]", - GameConstants::maxPlayers + 1, mapInfo.players, - Config::getMapPath (mapFiles.at (i), "", - false).c_str (), - mapInfo.desc.c_str ()); - throw megaglest_runtime_error (szBuf); - } - playerSortedMaps[mapInfo.hardMaxPlayers].push_back (mapFiles.at (i)); - formattedPlayerSortedMaps[mapInfo.hardMaxPlayers].push_back (formatString - (mapFiles.at - (i))); - if (config.getString ("InitialMap", "Conflict") == - formattedPlayerSortedMaps[mapInfo.hardMaxPlayers].back ()) - { - initialMapSelection = i; - } - } - -//printf("#6 scenario [%s] [%s]\n",scenario.c_str(),scenarioDir.c_str()); - if (scenario != "") - { - string file = Scenario::getScenarioPath (dirList, scenario); - loadScenarioInfo (file, &scenarioInfo); - -//printf("#6.1 about to load map [%s]\n",scenarioInfo.mapName.c_str()); - loadMapInfo (Config::getMapPath - (scenarioInfo.mapName, scenarioDir, true), &mapInfo, - false); - - listBoxMapFilter.setSelectedItem (intToStr (mapInfo.players)); - listBoxMap.setItems (formattedPlayerSortedMaps[mapInfo.players]); - } - else - { - listBoxMapFilter.setSelectedItemIndex (0); - listBoxMap.setItems (formattedPlayerSortedMaps[0]); - } -//printf("#7\n"); - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - throw megaglest_runtime_error (szBuf); -//abort(); - } - - return initialMapSelection; - } - - int MenuStateCustomGame::setupTechList (string scenario, bool forceLoad) - { - int initialTechSelection = 0; - try - { - Config & config = Config::getInstance (); - - string scenarioDir = Scenario::getScenarioDir (dirList, scenario); - vector < string > results; - vector < string > techPaths = - config.getPathListForType (ptTechs, scenarioDir); - findDirs (techPaths, results); - - if (results.empty ()) - { -//throw megaglest_runtime_error("No tech-trees were found!"); - printf ("No tech-trees were found (custom)!\n"); - } - - techTreeFiles = results; - - vector < string > translatedTechs; - - for (unsigned int i = 0; i < results.size (); i++) - { -//printf("TECHS i = %d results [%s] scenario [%s]\n",i,results[i].c_str(),scenario.c_str()); - - results.at (i) = formatString (results.at (i)); - if (config.getString ("InitialTechTree", "Megapack") == - results.at (i)) - { - initialTechSelection = i; - } - string txTech = - techTree->getTranslatedName (techTreeFiles.at (i), forceLoad); - translatedTechs.push_back (formatString (txTech)); - } - - - listBoxTechTree.setItems (results, translatedTechs); - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - throw megaglest_runtime_error (szBuf); - } - - return initialTechSelection; - } - - void MenuStateCustomGame::reloadFactions (bool keepExistingSelectedItem, - string scenario) - { - try - { - Config & config = Config::getInstance (); - Lang & lang = Lang::getInstance (); - - vector < string > results; - string scenarioDir = Scenario::getScenarioDir (dirList, scenario); - vector < string > techPaths = - config.getPathListForType (ptTechs, scenarioDir); - -//printf("#1 techPaths.size() = %d scenarioDir [%s] [%s]\n",techPaths.size(),scenario.c_str(),scenarioDir.c_str()); - - if (listBoxTechTree.getItemCount () > 0) - { - for (int idx = 0; idx < (int) techPaths.size (); idx++) - { - string & techPath = techPaths[idx]; - endPathWithSlash (techPath); - string factionPath = - techPath + - techTreeFiles[listBoxTechTree.getSelectedItemIndex ()] + - "/factions/"; - findDirs (factionPath, results, false, false); - -//printf("idx = %d factionPath [%s] results.size() = %d\n",idx,factionPath.c_str(),results.size()); - - if (results.empty () == false) - { - break; - } - } - } - - if (results.empty () == true) - { -//throw megaglest_runtime_error("(2)There are no factions for the tech tree [" + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "]"); - showGeneralError = true; - if (listBoxTechTree.getItemCount () > 0) - { - generalErrorToShow = - "[#2] There are no factions for the tech tree [" + - techTreeFiles[listBoxTechTree.getSelectedItemIndex ()] + "]"; - } - else - { - generalErrorToShow = - "[#2] There are no factions since there is no tech tree!"; - } - } - -// results.push_back(formatString(GameConstants::RANDOMFACTION_SLOTNAME)); -// -// // Add special Observer Faction -// if(checkBoxAllowObservers.getValue() == 1) { -// results.push_back(formatString(GameConstants::OBSERVER_SLOTNAME)); -// } - - vector < string > translatedFactionNames; - factionFiles = results; - for (int i = 0; i < (int) results.size (); ++i) - { - results[i] = formatString (results[i]); - - string translatedString = ""; - if (listBoxTechTree.getItemCount () > 0) - { - translatedString = - techTree->getTranslatedFactionName (techTreeFiles - [listBoxTechTree.getSelectedItemIndex - ()], factionFiles[i]); - } -//printf("translatedString=%s formatString(results[i])=%s \n",translatedString.c_str(),formatString(results[i]).c_str() ); - if (toLower (translatedString) == toLower (results[i])) - { - translatedFactionNames.push_back (results[i]); - } - else - { - translatedFactionNames.push_back (results[i] + " (" + - translatedString + ")"); - } -//printf("FACTIONS i = %d results [%s]\n",i,results[i].c_str()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "Tech [%s] has faction [%s]\n", - techTreeFiles - [listBoxTechTree.getSelectedItemIndex - ()].c_str (), results[i].c_str ()); - } - results.push_back (formatString - (GameConstants::RANDOMFACTION_SLOTNAME)); - factionFiles.push_back (formatString - (GameConstants::RANDOMFACTION_SLOTNAME)); - translatedFactionNames.push_back ("*" + - lang.getString ("Random", "", - true) + "*"); - -// Add special Observer Faction - if (checkBoxAllowObservers.getValue () == 1) - { - results.push_back (formatString (GameConstants::OBSERVER_SLOTNAME)); - factionFiles.push_back (formatString - (GameConstants::OBSERVER_SLOTNAME)); - translatedFactionNames.push_back ("*" + - lang.getString ("Observer", "", - true) + "*"); - } - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - int originalIndex = listBoxFactions[i].getSelectedItemIndex (); - string originalValue = - (listBoxFactions[i].getItemCount () > - 0 ? listBoxFactions[i].getSelectedItem () : ""); - - listBoxFactions[i].setItems (results, translatedFactionNames); - if (keepExistingSelectedItem == false || - (checkBoxAllowObservers.getValue () == 0 && - originalValue == - formatString (GameConstants::OBSERVER_SLOTNAME))) - { - listBoxFactions[i].setSelectedItemIndex (i % results.size ()); - - if (originalValue == - formatString (GameConstants::OBSERVER_SLOTNAME) - && listBoxFactions[i].getSelectedItem () != - formatString (GameConstants::OBSERVER_SLOTNAME)) - { - if (listBoxTeams[i].getSelectedItem () == - intToStr (GameConstants::maxPlayers + fpt_Observer)) - { - listBoxTeams[i].setSelectedItem (intToStr (1)); - } - } - } - else if (originalIndex < (int) results.size ()) - { - listBoxFactions[i].setSelectedItemIndex (originalIndex); - } - } - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - throw megaglest_runtime_error (szBuf); - } - } - - void MenuStateCustomGame::setSlotHuman (int i) - { - if (labelPlayerNames[i].getEditable ()) - { - return; - } - listBoxControls[i].setSelectedItemIndex (ctHuman); - listBoxRMultiplier[i].setSelectedItem ("1.0"); - - labelPlayerNames[i].setText (getHumanPlayerName ()); - for (int j = 0; j < GameConstants::maxPlayers; ++j) - { - labelPlayerNames[j].setEditable (false); - } - labelPlayerNames[i].setEditable (true); - } - - void MenuStateCustomGame::setupTilesetList (string scenario) - { - try - { - Config & config = Config::getInstance (); - - string scenarioDir = Scenario::getScenarioDir (dirList, scenario); - - vector < string > results; - findDirs (config.getPathListForType (ptTilesets, scenarioDir), - results); - if (results.empty ()) - { - throw megaglest_runtime_error ("No tile-sets were found!"); - } - tilesetFiles = results; - std::for_each (results.begin (), results.end (), FormatString ()); - - listBoxTileset.setItems (results); - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - throw megaglest_runtime_error (szBuf); - } - - } - - } + if (listBoxControls[i].getSelectedItemIndex() == ctNetwork + || listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (serverInterface->getSlot(i, true) != NULL + && serverInterface->getSlot(i, true)->isConnected()) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //printf("slot = %d serverInterface->getSlot(i)->getConnectedTime() = %d session key [%d]\n",i,serverInterface->getSlot(i)->getConnectedTime(),serverInterface->getSlot(i)->getSessionKey()); + + if (clientConnectedTime == 0 || + (serverInterface->getSlot(i, true)->getConnectedTime() > 0 + && serverInterface->getSlot(i, + true)->getConnectedTime() < + clientConnectedTime)) { + clientConnectedTime = + serverInterface->getSlot(i, true)->getConnectedTime(); + gameSettings->setMasterserver_admin(serverInterface->getSlot + (i, + true)->getSessionKey + ()); + gameSettings->setMasterserver_admin_faction_index + (serverInterface->getSlot(i, true)->getPlayerIndex()); + labelGameName.setText(createGameName + (serverInterface-> + getSlot(i, true)->getName())); + //printf("slot = %d, admin key [%d] slot connected time[" MG_SIZE_T_SPECIFIER "] clientConnectedTime [" MG_SIZE_T_SPECIFIER "]\n",i,gameSettings->getMasterserver_admin(),serverInterface->getSlot(i)->getConnectedTime(),clientConnectedTime); + } + if (serverInterface->getSlot(i, true)->getSessionKey() == + gameSettings->getMasterserver_admin()) { + masterserver_admin_found = true; + } + } + } + } + if (masterserver_admin_found == false) { + for (int i = mapInfo.players; i < GameConstants::maxPlayers; ++i) { + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + //ConnectionSlot *slot = serverInterface->getSlot(i); + + if (serverInterface->getSlot(i, true) != NULL + && serverInterface->getSlot(i, true)->isConnected()) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //printf("slot = %d serverInterface->getSlot(i)->getConnectedTime() = %d session key [%d]\n",i,serverInterface->getSlot(i)->getConnectedTime(),serverInterface->getSlot(i)->getSessionKey()); + + if (clientConnectedTime == 0 || + (serverInterface->getSlot(i, true)->getConnectedTime() > 0 + && serverInterface->getSlot(i, + true)->getConnectedTime() < + clientConnectedTime)) { + clientConnectedTime = + serverInterface->getSlot(i, true)->getConnectedTime(); + gameSettings->setMasterserver_admin(serverInterface->getSlot + (i, + true)->getSessionKey + ()); + gameSettings->setMasterserver_admin_faction_index + (serverInterface->getSlot(i, true)->getPlayerIndex()); + labelGameName.setText(createGameName + (serverInterface-> + getSlot(i, true)->getName())); + //printf("slot = %d, admin key [%d] slot connected time[" MG_SIZE_T_SPECIFIER "] clientConnectedTime [" MG_SIZE_T_SPECIFIER "]\n",i,gameSettings->getMasterserver_admin(),serverInterface->getSlot(i)->getConnectedTime(),clientConnectedTime); + } + if (serverInterface->getSlot(i, true)->getSessionKey() == + gameSettings->getMasterserver_admin()) { + masterserver_admin_found = true; + } + } + } + } + + if (masterserver_admin_found == false) { + labelGameName.setText(createGameName()); + } + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + void MenuStateCustomGame::saveGameSettingsToFile(std::string fileName) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + GameSettings gameSettings; + loadGameSettings(&gameSettings); + CoreData::getInstance().saveGameSettingsToFile(fileName, + &gameSettings, + checkBoxAdvanced.getValue + ()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + void MenuStateCustomGame::KeepCurrentHumanPlayerSlots(GameSettings & + gameSettings) { + //look for human players + bool foundValidHumanControlTypeInFile = false; + for (int index2 = 0; index2 < GameConstants::maxPlayers; ++index2) { + ControlType ctFile = + static_cast + (gameSettings.getFactionControl(index2)); + if (ctFile == ctHuman) { + ControlType ctUI = + static_cast + (listBoxControls[index2].getSelectedItemIndex()); + if (ctUI != ctNetwork && ctUI != ctNetworkUnassigned) { + foundValidHumanControlTypeInFile = true; + //printf("Human found in file [%d]\n",index2); + } else if (labelPlayerNames[index2].getText() == "") { + foundValidHumanControlTypeInFile = true; + } + } + } + + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + ControlType ct = + static_cast + (listBoxControls[index].getSelectedItemIndex()); + if (ct == ctHuman) { + //printf("Human found in UI [%d] and file [%d]\n",index,foundControlType); + + if (foundValidHumanControlTypeInFile == false) { + gameSettings.setFactionControl(index, ctHuman); + gameSettings.setNetworkPlayerName(index, getHumanPlayerName()); + } + } + + ControlType ctFile = + static_cast + (gameSettings.getFactionControl(index)); + if (ctFile == ctHuman) { + gameSettings.setFactionControl(index, ctHuman); + } + } + } + + GameSettings MenuStateCustomGame::loadGameSettingsFromFile(std::string + fileName) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + GameSettings gameSettings; + + GameSettings originalGameSettings; + loadGameSettings(&originalGameSettings); + + try { + CoreData::getInstance().loadGameSettingsFromFile(fileName, + &gameSettings); + KeepCurrentHumanPlayerSlots(gameSettings); + + // correct game settings for headless: + if (this->headlessServerMode == true) { + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + if (gameSettings.getFactionControl(i) == ctHuman) { + gameSettings.setFactionControl(i, ctNetwork); + } + } + } + setupUIFromGameSettings(gameSettings); + } catch (const exception & ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + ex.what()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] ERROR = [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, ex.what()); + + showMessageBox(ex.what(), "Error", false); + + setupUIFromGameSettings(originalGameSettings); + gameSettings = originalGameSettings; + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + return gameSettings; + } + + void MenuStateCustomGame::setupUIFromGameSettings(const GameSettings & + gameSettings) { + string humanPlayerName = getHumanPlayerName(); + + string scenarioDir = ""; + checkBoxScenario.setValue((gameSettings.getScenario() != "")); + if (checkBoxScenario.getValue() == true) { + listBoxScenario.setSelectedItem(formatString + (gameSettings.getScenario())); + + loadScenarioInfo(Scenario::getScenarioPath(dirList, + scenarioFiles + [listBoxScenario.getSelectedItemIndex + ()]), &scenarioInfo); + scenarioDir = + Scenario::getScenarioDir(dirList, gameSettings.getScenario()); + + //printf("scenarioInfo.fogOfWar = %d scenarioInfo.fogOfWar_exploredFlag = %d\n",scenarioInfo.fogOfWar,scenarioInfo.fogOfWar_exploredFlag); + if (scenarioInfo.fogOfWar == false + && scenarioInfo.fogOfWar_exploredFlag == false) { + listBoxFogOfWar.setSelectedItemIndex(2); + } else if (scenarioInfo.fogOfWar_exploredFlag == true) { + listBoxFogOfWar.setSelectedItemIndex(1); + } else { + listBoxFogOfWar.setSelectedItemIndex(0); + } + checkBoxAllowTeamUnitSharing. + setValue(scenarioInfo.allowTeamUnitSharing); + checkBoxAllowTeamResourceSharing. + setValue(scenarioInfo.allowTeamResourceSharing); + } + setupMapList(gameSettings.getScenario()); + setupTechList(gameSettings.getScenario(), false); + setupTilesetList(gameSettings.getScenario()); + + if (checkBoxScenario.getValue() == true) { + //string file = Scenario::getScenarioPath(dirList, gameSettings.getScenario()); + //loadScenarioInfo(file, &scenarioInfo); + + //printf("#6.1 about to load map [%s]\n",scenarioInfo.mapName.c_str()); + //loadMapInfo(Config::getMapPath(scenarioInfo.mapName, scenarioDir, true), &mapInfo, false); + //printf("#6.2\n"); + + listBoxMapFilter.setSelectedItemIndex(0); + listBoxMap.setItems(formattedPlayerSortedMaps[mapInfo.hardMaxPlayers]); + listBoxMap.setSelectedItem(formatString(scenarioInfo.mapName)); + } else { + //printf("gameSettings.getMapFilter()=%d \n",gameSettings.getMapFilter()); + if (gameSettings.getMapFilter() == 0) { + listBoxMapFilter.setSelectedItemIndex(0); + } else { + listBoxMapFilter.setSelectedItem(intToStr + (gameSettings.getMapFilter())); + } + listBoxMap.setItems(formattedPlayerSortedMaps + [gameSettings.getMapFilter()]); + } + + //printf("gameSettings.getMap() [%s] [%s]\n",gameSettings.getMap().c_str(),listBoxMap.getSelectedItem().c_str()); + + string mapFile = gameSettings.getMap(); + if (find(mapFiles.begin(), mapFiles.end(), mapFile) != + mapFiles.end()) { + mapFile = formatString(mapFile); + listBoxMap.setSelectedItem(mapFile); + + loadMapInfo(Config::getMapPath + (getCurrentMapFile(), scenarioDir, true), &mapInfo, + true); + labelMapInfo.setText(mapInfo.desc); + } + + string tilesetFile = gameSettings.getTileset(); + if (find(tilesetFiles.begin(), tilesetFiles.end(), tilesetFile) != + tilesetFiles.end()) { + tilesetFile = formatString(tilesetFile); + listBoxTileset.setSelectedItem(tilesetFile); + } + + string techtreeFile = gameSettings.getTech(); + if (find(techTreeFiles.begin(), techTreeFiles.end(), techtreeFile) != + techTreeFiles.end()) { + techtreeFile = formatString(techtreeFile); + listBoxTechTree.setSelectedItem(techtreeFile); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //gameSettings->setDefaultUnits(true); + //gameSettings->setDefaultResources(true); + //gameSettings->setDefaultVictoryConditions(true); + + //FogOfWar + if (checkBoxScenario.getValue() == false) { + listBoxFogOfWar.setSelectedItemIndex(0); // default is 0! + if (gameSettings.getFogOfWar() == false) { + listBoxFogOfWar.setSelectedItemIndex(2); + } + + if ((gameSettings.getFlagTypes1() & ft1_show_map_resources) == + ft1_show_map_resources) { + if (gameSettings.getFogOfWar() == true) { + listBoxFogOfWar.setSelectedItemIndex(1); + } + } + } + + //printf("In [%s::%s line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + checkBoxAllowObservers.setValue(gameSettings.getAllowObservers() == + true ? true : false); + //listBoxEnableObserverMode.setSelectedItem(gameSettings.getEnableObserverModeAtEndGame() == true ? lang.getString("Yes") : lang.getString("No")); + + checkBoxEnableSwitchTeamMode.setValue((gameSettings.getFlagTypes1() & + ft1_allow_team_switching) == + ft1_allow_team_switching ? true : + false); + listBoxAISwitchTeamAcceptPercent.setSelectedItem(intToStr + (gameSettings.getAiAcceptSwitchTeamPercentChance + ())); + listBoxFallbackCpuMultiplier. + setSelectedItemIndex(gameSettings.getFallbackCpuMultiplier()); + + checkBoxAllowInGameJoinPlayer.setValue((gameSettings.getFlagTypes1() & + ft1_allow_in_game_joining) == + ft1_allow_in_game_joining ? true + : false); + + checkBoxAllowTeamUnitSharing.setValue((gameSettings.getFlagTypes1() & + ft1_allow_shared_team_units) == + ft1_allow_shared_team_units ? + true : false); + checkBoxAllowTeamResourceSharing.setValue((gameSettings.getFlagTypes1 + () & + ft1_allow_shared_team_resources) + == + ft1_allow_shared_team_resources + ? true : false); + + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + if (serverInterface != NULL) { + serverInterface->setAllowInGameConnections + (checkBoxAllowInGameJoinPlayer.getValue() == true); + } + + checkBoxAllowNativeLanguageTechtree. + setValue(gameSettings.getNetworkAllowNativeLanguageTechtree()); + + //listBoxPathFinderType.setSelectedItemIndex(gameSettings.getPathFinderType()); + + //listBoxEnableServerControlledAI.setSelectedItem(gameSettings.getEnableServerControlledAI() == true ? lang.getString("Yes") : lang.getString("No")); + + //labelNetworkFramePeriod.setText(lang.getString("NetworkFramePeriod")); + + //listBoxNetworkFramePeriod.setSelectedItem(intToStr(gameSettings.getNetworkFramePeriod()/10*10)); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + checkBoxNetworkPauseGameForLaggedClients. + setValue(gameSettings.getNetworkPauseGameForLaggedClients()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + reloadFactions(false, + (checkBoxScenario.getValue() == + true ? + scenarioFiles[listBoxScenario.getSelectedItemIndex()] + : "")); + //reloadFactions(true); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d] gameSettings.getFactionCount() = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + gameSettings.getFactionCount()); + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + int slotIndex = gameSettings.getStartLocationIndex(i); + if (gameSettings.getFactionControl(i) < + listBoxControls[slotIndex].getItemCount()) { + listBoxControls[slotIndex]. + setSelectedItemIndex(gameSettings.getFactionControl(i)); + } + + //if(slotIndex == 0) printf("#2 slotIndex = %d, i = %d, multiplier = %d\n",slotIndex,i,listBoxRMultiplier[i].getSelectedItemIndex()); + + updateResourceMultiplier(slotIndex); + + //if(slotIndex == 0) printf("#3 slotIndex = %d, i = %d, multiplier = %d\n",slotIndex,i,listBoxRMultiplier[i].getSelectedItemIndex()); + + listBoxRMultiplier[slotIndex]. + setSelectedItemIndex(gameSettings.getResourceMultiplierIndex(i)); + + //if(slotIndex == 0) printf("#4 slotIndex = %d, i = %d, multiplier = %d\n",slotIndex,i,listBoxRMultiplier[i].getSelectedItemIndex()); + + listBoxTeams[slotIndex]. + setSelectedItemIndex(gameSettings.getTeam(i)); + + lastSelectedTeamIndex[slotIndex] = + listBoxTeams[slotIndex].getSelectedItemIndex(); + + string factionName = gameSettings.getFactionTypeName(i); + factionName = formatString(factionName); + + //printf("\n\n\n*** setupUIFromGameSettings A, i = %d, startLoc = %d, factioncontrol = %d, factionName [%s]\n",i,gameSettings.getStartLocationIndex(i),gameSettings.getFactionControl(i),factionName.c_str()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] factionName = [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, factionName.c_str()); + + if (listBoxFactions[slotIndex].hasItem(factionName) == true) { + listBoxFactions[slotIndex].setSelectedItem(factionName); + } else { + listBoxFactions[slotIndex].setSelectedItem(formatString + (GameConstants:: + RANDOMFACTION_SLOTNAME)); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] i = %d, gameSettings.getNetworkPlayerName(i) [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, i, + gameSettings. + getNetworkPlayerName(i).c_str()); + + //labelPlayerNames[slotIndex].setText(gameSettings.getNetworkPlayerName(i)); + } + + //SetActivePlayerNameEditor(); + + updateControllers(); + updateNetworkSlots(); + + if (this->headlessServerMode == false && humanPlayerName != "") { + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + ControlType ct = + static_cast + (listBoxControls[index].getSelectedItemIndex()); + if (ct == ctHuman) { + if (humanPlayerName != labelPlayerNames[index].getText()) { + //printf("Player name changing from [%s] to [%s]\n",labelPlayerNames[index].getText().c_str(),humanPlayerName.c_str()); + + labelPlayerNames[index].setText(""); + labelPlayerNames[index].setText(humanPlayerName); + } + } + } + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } + // ============ PRIVATE =========================== + + void MenuStateCustomGame::lastPlayerDisconnected() { + // this is for headless mode only! + // if last player disconnects we load the network defaults. + if (this->headlessServerMode == false) { + return; + } + + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + bool foundConnectedPlayer = false; + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + if (serverInterface->getSlot(i, true) != NULL && + (listBoxControls[i].getSelectedItemIndex() == ctNetwork || + listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned)) { + if (serverInterface->getSlot(i, true)->isConnected() == true) { + foundConnectedPlayer = true; + } + } + } + + if (!foundConnectedPlayer && headlessHasConnectedPlayer == true) { + // load defaults + string data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + if (fileExists(data_path + DEFAULT_NETWORKGAME_FILENAME) == true) + loadGameSettings(data_path + DEFAULT_NETWORKGAME_FILENAME); + } + headlessHasConnectedPlayer = foundConnectedPlayer; + } + + bool MenuStateCustomGame::hasNetworkGameSettings() { + bool hasNetworkSlot = false; + + try { + for (int i = 0; i < mapInfo.players; ++i) { + ControlType ct = + static_cast + (listBoxControls[i].getSelectedItemIndex()); + if (ct != ctClosed) { + if (ct == ctNetwork || ct == ctNetworkUnassigned) { + hasNetworkSlot = true; + break; + } + } + } + if (hasNetworkSlot == false) { + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + ControlType ct = + static_cast + (listBoxControls[i].getSelectedItemIndex()); + if (ct != ctClosed) { + if (ct == ctNetworkUnassigned) { + hasNetworkSlot = true; + break; + } + } + } + } + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + ex.what()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + showGeneralError = true; + generalErrorToShow = szBuf; + } + + return hasNetworkSlot; + } + + void MenuStateCustomGame::loadMapInfo(string file, MapInfo * mapInfo, + bool loadMapPreview) { + try { + Lang & lang = Lang::getInstance(); + if (MapPreview::loadMapInfo + (file, mapInfo, lang.getString("MaxPlayers"), + lang.getString("Size"), true) == true) { + // Though we prefer not to change the actual value of mapInfo->players, + // which is the number of players assigned when making the map, we still know + // the actual value from mapInfo.hardMaxPlayers. Changing it here means + // not having to change a variable name in many places of this file + // to implement enhanced observer mode (issue #13)' + if (checkBoxAllowObservers.getValue() == 1) { + mapInfo->players = GameConstants::maxPlayers; + } + + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + if (serverInterface->getSlot(i, true) != NULL && + (listBoxControls[i].getSelectedItemIndex() == ctNetwork + || listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned)) { + if (serverInterface->getSlot(i, true)->isConnected() == true) { + if (i + 1 > mapInfo->players && + listBoxControls[i].getSelectedItemIndex() != + ctNetworkUnassigned) { + listBoxControls[i].setSelectedItemIndex + (ctNetworkUnassigned); + } + } + } + } + + // Not painting properly so this is on hold + if (loadMapPreview == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + mapPreview.loadFromFile(file.c_str()); + + //printf("Loading map preview MAP\n"); + cleanupMapPreviewTexture(); + } + } + } catch (exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s] loading map [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + e.what(), file.c_str()); + throw megaglest_runtime_error("Error loading map file: [" + file + + "] msg: " + e.what()); + } + } + + void MenuStateCustomGame::closeUnusedSlots() { + try { + if (checkBoxScenario.getValue() == false) { + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + //for(int i= 0; igetSlot(i, true) == NULL || + serverInterface->getSlot(i, + true)->isConnected() == + false + || serverInterface->getSlot(i, + true)->getConnectHasHandshaked + () == false) { + //printf("Closed A [%d] [%s]\n",i,labelPlayerNames[i].getText().c_str()); + + listBoxControls[i].setSelectedItemIndex(ctClosed); + } + } + } + updateNetworkSlots(); + } + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + } + + bool MenuStateCustomGame::textInput(std::string text) { + //printf("In [%s::%s Line: %d] text [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,text.c_str()); + if (activeInputLabel != NULL) { + bool handled = textInputEditLabel(text, &activeInputLabel); + if (handled == true && &labelGameName != activeInputLabel) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } + } else { + if (hasNetworkGameSettings() == true) { + chatManager.textInput(text); + } + } + return false; + } + + void MenuStateCustomGame::keyDown(SDL_KeyboardEvent key) { + if (isMasterserverMode() == true) { + return; + } + + if (activeInputLabel != NULL) { + bool handled = keyDownEditLabel(key, &activeInputLabel); + if (handled == true) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } + } else { + //send key to the chat manager + if (hasNetworkGameSettings() == true) { + chatManager.keyDown(key); + } + if (chatManager.getEditEnabled() == false && + (::Shared::Platform::Window::isKeyStateModPressed(KMOD_SHIFT) == + false)) { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + + //if(key == configKeys.getCharKey("ShowFullConsole")) { + if (isKeyPressed(configKeys.getSDLKey("ShowFullConsole"), key) + == true) { + showFullConsole = true; + } + //Toggle music + //else if(key == configKeys.getCharKey("ToggleMusic")) { + else + if (isKeyPressed(configKeys.getSDLKey("ToggleMusic"), key) + == true) { + Config & config = Config::getInstance(); + Lang & lang = Lang::getInstance(); + + float configVolume = (config.getInt("SoundVolumeMusic") / 100.f); + float currentVolume = + CoreData::getInstance().getMenuMusic()->getVolume(); + if (currentVolume > 0) { + CoreData::getInstance().getMenuMusic()->setVolume(0.f); + console.addLine(lang.getString("GameMusic") + " " + + lang.getString("Off")); + } else { + CoreData::getInstance(). + getMenuMusic()->setVolume(configVolume); + //If the config says zero, use the default music volume + //gameMusic->setVolume(configVolume ? configVolume : 0.9); + console.addLine(lang.getString("GameMusic")); + } + } + //else if(key == configKeys.getCharKey("SaveGUILayout")) { + else + if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), key) + == true) { + bool saved = + GraphicComponent::saveAllCustomProperties(containerName); + Lang & lang = Lang::getInstance(); + console.addLine(lang.getString("GUILayoutSaved") + " [" + + (saved ? lang. + getString("Yes") : lang.getString("No")) + + "]"); + } + } + } + } + + void MenuStateCustomGame::keyPress(SDL_KeyboardEvent c) { + if (isMasterserverMode() == true) { + return; + } + + if (activeInputLabel != NULL) { + bool handled = keyPressEditLabel(c, &activeInputLabel); + if (handled == true && &labelGameName != activeInputLabel) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + } + } else { + if (hasNetworkGameSettings() == true) { + chatManager.keyPress(c); + } + } + } + + void MenuStateCustomGame::keyUp(SDL_KeyboardEvent key) { + if (isMasterserverMode() == true) { + return; + } + + if (activeInputLabel == NULL) { + if (hasNetworkGameSettings() == true) { + chatManager.keyUp(key); + } + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + + if (chatManager.getEditEnabled()) { + //send key to the chat manager + if (hasNetworkGameSettings() == true) { + chatManager.keyUp(key); + } + } + //else if(key == configKeys.getCharKey("ShowFullConsole")) { + else + if (isKeyPressed(configKeys.getSDLKey("ShowFullConsole"), key) + == true) { + showFullConsole = false; + } + } + } + + void MenuStateCustomGame::showMessageBox(const string & text, + const string & header, + bool toggle) { + if (!toggle) { + mainMessageBox.setEnabled(false); + } + + if (!mainMessageBox.getEnabled()) { + mainMessageBox.setText(text); + mainMessageBox.setHeader(header); + mainMessageBox.setEnabled(true); + } else { + mainMessageBox.setEnabled(false); + } + } + + void MenuStateCustomGame::switchToNextMapGroup(const int direction) { + int i = listBoxMapFilter.getSelectedItemIndex(); + // if there are no maps for the current selection we switch to next selection + while (formattedPlayerSortedMaps[i].empty()) { + i = i + direction; + if (i > GameConstants::maxPlayers) { + i = 0; + } + if (i < 0) { + i = GameConstants::maxPlayers; + } + } + listBoxMapFilter.setSelectedItemIndex(i); + listBoxMap.setItems(formattedPlayerSortedMaps[i]); + } + + string MenuStateCustomGame::getCurrentMapFile() { + int i = listBoxMapFilter.getSelectedItemIndex(); + int mapIndex = listBoxMap.getSelectedItemIndex(); + if (playerSortedMaps[i].empty() == false) { + return playerSortedMaps[i].at(mapIndex); + } + return ""; + } + + void MenuStateCustomGame::setActiveInputLabel(GraphicLabel * newLable) { + MenuState::setActiveInputLabel(newLable, &activeInputLabel); + } + + string MenuStateCustomGame::getHumanPlayerName(int index) { + string result = defaultPlayerName; + if (index < 0) { + for (int j = 0; j < GameConstants::maxPlayers; ++j) { + if (listBoxControls[j].getSelectedItemIndex() >= 0) { + ControlType ct = + static_cast + (listBoxControls[j].getSelectedItemIndex()); + if (ct == ctHuman) { + index = j; + break; + } + } + } + } + + if (index >= 0 && index < GameConstants::maxPlayers && + labelPlayerNames[index].getText() != "" && + labelPlayerNames[index].getText() != + GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME) { + result = labelPlayerNames[index].getText(); + + if (activeInputLabel != NULL) { + size_t found = result.find_last_of("_"); + if (found != string::npos) { + result = result.substr(0, found); + } + } + } + + return result; + } + + void MenuStateCustomGame::loadFactionTexture(string filepath) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (enableFactionTexturePreview == true) { + if (filepath == "") { + factionTexture = NULL; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] filepath = [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + filepath.c_str()); + + factionTexture = Renderer::findTexture(filepath); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } + } + } + + void MenuStateCustomGame::cleanupMapPreviewTexture() { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //printf("CLEANUP map preview texture\n"); + + if (mapPreviewTexture != NULL) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + mapPreviewTexture->end(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + delete mapPreviewTexture; + mapPreviewTexture = NULL; + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + int32 MenuStateCustomGame::getNetworkPlayerStatus() { + int32 result = npst_None; + switch (listBoxPlayerStatus.getSelectedItemIndex()) { + case 2: + result = npst_Ready; + break; + case 1: + result = npst_BeRightBack; + break; + case 0: + default: + result = npst_PickSettings; + break; + } + + return result; + } + + void MenuStateCustomGame::loadScenarioInfo(string file, + ScenarioInfo * scenarioInfo) { + //printf("Load scenario file [%s]\n",file.c_str()); + bool isTutorial = Scenario::isGameTutorial(file); + Scenario::loadScenarioInfo(file, scenarioInfo, isTutorial); + + //cleanupPreviewTexture(); + previewLoadDelayTimer = time(NULL); + needToLoadTextures = true; + } + + bool MenuStateCustomGame::isInSpecialKeyCaptureEvent() { + bool result = (chatManager.getEditEnabled() + || activeInputLabel != NULL); + return result; + } + + void MenuStateCustomGame::processScenario() { + try { + if (checkBoxScenario.getValue() == true) { + //printf("listBoxScenario.getSelectedItemIndex() = %d [%s] scenarioFiles.size() = %d\n",listBoxScenario.getSelectedItemIndex(),listBoxScenario.getSelectedItem().c_str(),scenarioFiles.size()); + loadScenarioInfo(Scenario::getScenarioPath(dirList, + scenarioFiles + [listBoxScenario.getSelectedItemIndex + ()]), &scenarioInfo); + string scenarioDir = + Scenario::getScenarioDir(dirList, scenarioInfo.name); + + //printf("scenarioInfo.fogOfWar = %d scenarioInfo.fogOfWar_exploredFlag = %d\n",scenarioInfo.fogOfWar,scenarioInfo.fogOfWar_exploredFlag); + if (scenarioInfo.fogOfWar == false + && scenarioInfo.fogOfWar_exploredFlag == false) { + listBoxFogOfWar.setSelectedItemIndex(2); + } else if (scenarioInfo.fogOfWar_exploredFlag == true) { + listBoxFogOfWar.setSelectedItemIndex(1); + } else { + listBoxFogOfWar.setSelectedItemIndex(0); + } + + checkBoxAllowTeamUnitSharing. + setValue(scenarioInfo.allowTeamUnitSharing); + checkBoxAllowTeamResourceSharing. + setValue(scenarioInfo.allowTeamResourceSharing); + + setupTechList(scenarioInfo.name, false); + listBoxTechTree.setSelectedItem(formatString + (scenarioInfo.techTreeName)); + reloadFactions(false, scenarioInfo.name); + + setupTilesetList(scenarioInfo.name); + listBoxTileset.setSelectedItem(formatString + (scenarioInfo.tilesetName)); + + checkBoxAllowObservers.setValue(false); + + setupMapList(scenarioInfo.name); + listBoxMap.setSelectedItem(formatString(scenarioInfo.mapName)); + loadMapInfo(Config::getMapPath + (getCurrentMapFile(), scenarioDir, true), &mapInfo, + true); + labelMapInfo.setText(mapInfo.desc); + + //printf("scenarioInfo.name [%s] [%s]\n",scenarioInfo.name.c_str(),listBoxMap.getSelectedItem().c_str()); + + // Loop twice to set the human slot or else it closes network slots in some cases + for (int humanIndex = 0; humanIndex < 2; ++humanIndex) { + for (int i = 0; i < mapInfo.players; ++i) { + listBoxRMultiplier[i].setSelectedItem(floatToStr + (scenarioInfo. + resourceMultipliers[i], + 1)); + + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + ConnectionSlot *slot = serverInterface->getSlot(i, true); + + int selectedControlItemIndex = + listBoxControls[i].getSelectedItemIndex(); + if (selectedControlItemIndex != ctNetwork + || (selectedControlItemIndex == ctNetwork + && (slot == NULL || slot->isConnected() == false))) { + } + + listBoxControls[i]. + setSelectedItemIndex(scenarioInfo.factionControls[i]); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + // Skip over networkunassigned + //if(listBoxControls[i].getSelectedItemIndex() == ctNetworkUnassigned && + // selectedControlItemIndex != ctNetworkUnassigned) { + // listBoxControls[i].mouseClick(x, y); + //} + + //look for human players + int humanIndex1 = -1; + int humanIndex2 = -1; + for (int j = 0; j < GameConstants::maxPlayers; ++j) { + ControlType ct = + static_cast + (listBoxControls[j].getSelectedItemIndex()); + if (ct == ctHuman) { + if (humanIndex1 == -1) { + humanIndex1 = j; + } else { + humanIndex2 = j; + } + } + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] humanIndex1 = %d, humanIndex2 = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, humanIndex1, humanIndex2); + + //no human + if (humanIndex1 == -1 && humanIndex2 == -1) { + setSlotHuman(i); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] i = %d, labelPlayerNames[i].getText() [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, i, + labelPlayerNames[i].getText(). + c_str()); + + //printf("humanIndex1 = %d humanIndex2 = %d i = %d listBoxControls[i].getSelectedItemIndex() = %d\n",humanIndex1,humanIndex2,i,listBoxControls[i].getSelectedItemIndex()); + } + //2 humans + else if (humanIndex1 != -1 && humanIndex2 != -1) { + int closeSlotIndex = + (humanIndex1 == i ? humanIndex2 : humanIndex1); + int humanSlotIndex = + (closeSlotIndex == humanIndex1 ? humanIndex2 : humanIndex1); + + string origPlayName = + labelPlayerNames[closeSlotIndex].getText(); + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] closeSlotIndex = %d, origPlayName [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, closeSlotIndex, + origPlayName.c_str()); + //printf("humanIndex1 = %d humanIndex2 = %d i = %d closeSlotIndex = %d humanSlotIndex = %d\n",humanIndex1,humanIndex2,i,closeSlotIndex,humanSlotIndex); + + listBoxControls[closeSlotIndex].setSelectedItemIndex + (ctClosed); + labelPlayerNames[humanSlotIndex].setText((origPlayName != + "" ? origPlayName : + getHumanPlayerName + ())); + } + + ControlType ct = + static_cast + (listBoxControls[i].getSelectedItemIndex()); + if (ct != ctClosed) { + //updateNetworkSlots(); + //updateResourceMultiplier(i); + updateResourceMultiplier(i); + + //printf("Setting scenario faction i = %d [ %s]\n",i,scenarioInfo.factionTypeNames[i].c_str()); + listBoxFactions[i].setSelectedItem(formatString + (scenarioInfo.factionTypeNames + [i])); + //printf("DONE Setting scenario faction i = %d [ %s]\n",i,scenarioInfo.factionTypeNames[i].c_str()); + + // Disallow CPU players to be observers + if (factionFiles + [listBoxFactions[i].getSelectedItemIndex()] == + formatString(GameConstants::OBSERVER_SLOTNAME) + && (listBoxControls[i].getSelectedItemIndex() == + ctCpuEasy + || listBoxControls[i].getSelectedItemIndex() == ctCpu + || listBoxControls[i].getSelectedItemIndex() == + ctCpuUltra + || listBoxControls[i].getSelectedItemIndex() == + ctCpuZeta)) { + listBoxFactions[i].setSelectedItemIndex(0); + } + // + + listBoxTeams[i].setSelectedItem(intToStr + (scenarioInfo.teams[i])); + if (factionFiles[listBoxFactions[i].getSelectedItemIndex()] + != formatString(GameConstants::OBSERVER_SLOTNAME)) { + if (listBoxTeams[i].getSelectedItemIndex() + 1 != + (GameConstants::maxPlayers + fpt_Observer)) { + lastSelectedTeamIndex[i] = + listBoxTeams[i].getSelectedItemIndex(); + } + // Alow Neutral cpu players + else if (listBoxControls[i].getSelectedItemIndex() == + ctCpuEasy + || listBoxControls[i].getSelectedItemIndex() == + ctCpu + || listBoxControls[i].getSelectedItemIndex() == + ctCpuUltra + || listBoxControls[i].getSelectedItemIndex() == + ctCpuZeta) { + lastSelectedTeamIndex[i] = + listBoxTeams[i].getSelectedItemIndex(); + } + } else { + lastSelectedTeamIndex[i] = -1; + } + } + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL);; + } + } + } + + updateControllers(); + updateNetworkSlots(); + + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + } + if (hasNetworkGameSettings() == true) { + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + } + + //labelInfo.setText(scenarioInfo.desc); + } else { + setupMapList(""); + listBoxMap.setSelectedItem(formatString + (formattedPlayerSortedMaps[0][0])); + loadMapInfo(Config::getMapPath(getCurrentMapFile(), "", true), + &mapInfo, true); + + labelMapInfo.setText(mapInfo.desc); + + setupTechList("", false); + reloadFactions(false, ""); + setupTilesetList(""); + updateControllers(); + } + SetupUIForScenarios(); + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + mainMessageBoxState = 1; + showMessageBox(szBuf, "Error detected", false); + } + } + + void MenuStateCustomGame::SetupUIForScenarios() { + try { + if (checkBoxScenario.getValue() == true) { + // START - Disable changes to controls while in Scenario mode + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + listBoxControls[i].setEditable(false); + listBoxFactions[i].setEditable(false); + listBoxRMultiplier[i].setEditable(false); + listBoxTeams[i].setEditable(false); + } + listBoxFogOfWar.setEditable(false); + checkBoxAllowObservers.setEditable(false); + checkBoxAllowTeamUnitSharing.setEditable(false); + checkBoxAllowTeamResourceSharing.setEditable(false); + //listBoxPathFinderType.setEditable(false); + checkBoxEnableSwitchTeamMode.setEditable(false); + listBoxAISwitchTeamAcceptPercent.setEditable(false); + listBoxFallbackCpuMultiplier.setEditable(false); + listBoxMap.setEditable(false); + listBoxTileset.setEditable(false); + listBoxMapFilter.setEditable(false); + listBoxTechTree.setEditable(false); + // END - Disable changes to controls while in Scenario mode + } else { + // START - Disable changes to controls while in Scenario mode + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + listBoxControls[i].setEditable(true); + listBoxFactions[i].setEditable(true); + listBoxRMultiplier[i].setEditable(true); + listBoxTeams[i].setEditable(true); + } + listBoxFogOfWar.setEditable(true); + checkBoxAllowObservers.setEditable(true); + checkBoxAllowTeamUnitSharing.setEditable(true); + checkBoxAllowTeamResourceSharing.setEditable(true); + //listBoxPathFinderType.setEditable(true); + checkBoxEnableSwitchTeamMode.setEditable(true); + listBoxAISwitchTeamAcceptPercent.setEditable(true); + listBoxFallbackCpuMultiplier.setEditable(true); + listBoxMap.setEditable(true); + listBoxTileset.setEditable(true); + listBoxMapFilter.setEditable(true); + listBoxTechTree.setEditable(true); + // END - Disable changes to controls while in Scenario mode + } + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + throw megaglest_runtime_error(szBuf); + } + + } + + int MenuStateCustomGame::setupMapList(string scenario) { + int initialMapSelection = 0; + + try { + Config & config = Config::getInstance(); + vector < string > invalidMapList; + string scenarioDir = Scenario::getScenarioDir(dirList, scenario); + vector < string > pathList = + config.getPathListForType(ptMaps, scenarioDir); + vector < string > allMaps = + MapPreview::findAllValidMaps(pathList, scenarioDir, false, true, + &invalidMapList); + if (scenario != "") { + vector < string > allMaps2 = + MapPreview:: + findAllValidMaps(config.getPathListForType(ptMaps, ""), "", + false, true, &invalidMapList); + copy(allMaps2.begin(), allMaps2.end(), + std::inserter(allMaps, allMaps.begin())); + } + // sort map list non case sensitive + std::sort(allMaps.begin(), allMaps.end(), compareNonCaseSensitive); + + if (allMaps.empty()) { + throw megaglest_runtime_error("No maps were found!"); + } + vector < string > results; + copy(allMaps.begin(), allMaps.end(), std::back_inserter(results)); + mapFiles = results; + + for (unsigned int i = 0; i < GameConstants::maxPlayers + 1; ++i) { + playerSortedMaps[i].clear(); + formattedPlayerSortedMaps[i].clear(); + } + + // at index=0 fill in the whole list + copy(mapFiles.begin(), mapFiles.end(), + std::back_inserter(playerSortedMaps[0])); + copy(playerSortedMaps[0].begin(), playerSortedMaps[0].end(), + std::back_inserter(formattedPlayerSortedMaps[0])); + std::for_each(formattedPlayerSortedMaps[0].begin(), + formattedPlayerSortedMaps[0].end(), FormatString()); + + // fill playerSortedMaps and formattedPlayerSortedMaps according to map player count + for (int i = 0; i < (int) mapFiles.size(); i++) { // fetch info and put map in right list + loadMapInfo(Config::getMapPath + (mapFiles.at(i), scenarioDir, false), &mapInfo, + false); + + if (GameConstants::maxPlayers + 1 <= mapInfo.players) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Sorted map list [%d] does not match\ncurrent map playercount [%d]\nfor file [%s]\nmap [%s]", + GameConstants::maxPlayers + 1, mapInfo.players, + Config::getMapPath(mapFiles.at(i), "", + false).c_str(), + mapInfo.desc.c_str()); + throw megaglest_runtime_error(szBuf); + } + playerSortedMaps[mapInfo.hardMaxPlayers].push_back(mapFiles.at(i)); + formattedPlayerSortedMaps[mapInfo.hardMaxPlayers].push_back(formatString + (mapFiles.at + (i))); + if (config.getString("InitialMap", "Conflict") == + formattedPlayerSortedMaps[mapInfo.hardMaxPlayers].back()) { + initialMapSelection = i; + } + } + + //printf("#6 scenario [%s] [%s]\n",scenario.c_str(),scenarioDir.c_str()); + if (scenario != "") { + string file = Scenario::getScenarioPath(dirList, scenario); + loadScenarioInfo(file, &scenarioInfo); + + //printf("#6.1 about to load map [%s]\n",scenarioInfo.mapName.c_str()); + loadMapInfo(Config::getMapPath + (scenarioInfo.mapName, scenarioDir, true), &mapInfo, + false); + + listBoxMapFilter.setSelectedItem(intToStr(mapInfo.players)); + listBoxMap.setItems(formattedPlayerSortedMaps[mapInfo.players]); + } else { + listBoxMapFilter.setSelectedItemIndex(0); + listBoxMap.setItems(formattedPlayerSortedMaps[0]); + } + //printf("#7\n"); + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + throw megaglest_runtime_error(szBuf); + //abort(); + } + + return initialMapSelection; + } + + int MenuStateCustomGame::setupTechList(string scenario, bool forceLoad) { + int initialTechSelection = 0; + try { + Config & config = Config::getInstance(); + + string scenarioDir = Scenario::getScenarioDir(dirList, scenario); + vector < string > results; + vector < string > techPaths = + config.getPathListForType(ptTechs, scenarioDir); + findDirs(techPaths, results); + + if (results.empty()) { + //throw megaglest_runtime_error("No tech-trees were found!"); + printf("No tech-trees were found (custom)!\n"); + } + + techTreeFiles = results; + + vector < string > translatedTechs; + + for (unsigned int i = 0; i < results.size(); i++) { + //printf("TECHS i = %d results [%s] scenario [%s]\n",i,results[i].c_str(),scenario.c_str()); + + results.at(i) = formatString(results.at(i)); + if (config.getString("InitialTechTree", "Megapack") == + results.at(i)) { + initialTechSelection = i; + } + string txTech = + techTree->getTranslatedName(techTreeFiles.at(i), forceLoad); + translatedTechs.push_back(formatString(txTech)); + } + + + listBoxTechTree.setItems(results, translatedTechs); + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + throw megaglest_runtime_error(szBuf); + } + + return initialTechSelection; + } + + void MenuStateCustomGame::reloadFactions(bool keepExistingSelectedItem, + string scenario) { + try { + Config & config = Config::getInstance(); + Lang & lang = Lang::getInstance(); + + vector < string > results; + string scenarioDir = Scenario::getScenarioDir(dirList, scenario); + vector < string > techPaths = + config.getPathListForType(ptTechs, scenarioDir); + + //printf("#1 techPaths.size() = %d scenarioDir [%s] [%s]\n",techPaths.size(),scenario.c_str(),scenarioDir.c_str()); + + if (listBoxTechTree.getItemCount() > 0) { + for (int idx = 0; idx < (int) techPaths.size(); idx++) { + string & techPath = techPaths[idx]; + endPathWithSlash(techPath); + string factionPath = + techPath + + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + + "/factions/"; + findDirs(factionPath, results, false, false); + + //printf("idx = %d factionPath [%s] results.size() = %d\n",idx,factionPath.c_str(),results.size()); + + if (results.empty() == false) { + break; + } + } + } + + if (results.empty() == true) { + //throw megaglest_runtime_error("(2)There are no factions for the tech tree [" + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "]"); + showGeneralError = true; + if (listBoxTechTree.getItemCount() > 0) { + generalErrorToShow = + "[#2] There are no factions for the tech tree [" + + techTreeFiles[listBoxTechTree.getSelectedItemIndex()] + "]"; + } else { + generalErrorToShow = + "[#2] There are no factions since there is no tech tree!"; + } + } + + // results.push_back(formatString(GameConstants::RANDOMFACTION_SLOTNAME)); + // + // // Add special Observer Faction + // if(checkBoxAllowObservers.getValue() == 1) { + // results.push_back(formatString(GameConstants::OBSERVER_SLOTNAME)); + // } + + vector < string > translatedFactionNames; + factionFiles = results; + for (int i = 0; i < (int) results.size(); ++i) { + results[i] = formatString(results[i]); + + string translatedString = ""; + if (listBoxTechTree.getItemCount() > 0) { + translatedString = + techTree->getTranslatedFactionName(techTreeFiles + [listBoxTechTree.getSelectedItemIndex + ()], factionFiles[i]); + } + //printf("translatedString=%s formatString(results[i])=%s \n",translatedString.c_str(),formatString(results[i]).c_str() ); + if (toLower(translatedString) == toLower(results[i])) { + translatedFactionNames.push_back(results[i]); + } else { + translatedFactionNames.push_back(results[i] + " (" + + translatedString + ")"); + } + //printf("FACTIONS i = %d results [%s]\n",i,results[i].c_str()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "Tech [%s] has faction [%s]\n", + techTreeFiles + [listBoxTechTree.getSelectedItemIndex + ()].c_str(), results[i].c_str()); + } + results.push_back(formatString + (GameConstants::RANDOMFACTION_SLOTNAME)); + factionFiles.push_back(formatString + (GameConstants::RANDOMFACTION_SLOTNAME)); + translatedFactionNames.push_back("*" + + lang.getString("Random", "", + true) + "*"); + + // Add special Observer Faction + if (checkBoxAllowObservers.getValue() == 1) { + results.push_back(formatString(GameConstants::OBSERVER_SLOTNAME)); + factionFiles.push_back(formatString + (GameConstants::OBSERVER_SLOTNAME)); + translatedFactionNames.push_back("*" + + lang.getString("Observer", "", + true) + "*"); + } + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + int originalIndex = listBoxFactions[i].getSelectedItemIndex(); + string originalValue = + (listBoxFactions[i].getItemCount() > + 0 ? listBoxFactions[i].getSelectedItem() : ""); + + listBoxFactions[i].setItems(results, translatedFactionNames); + if (keepExistingSelectedItem == false || + (checkBoxAllowObservers.getValue() == 0 && + originalValue == + formatString(GameConstants::OBSERVER_SLOTNAME))) { + listBoxFactions[i].setSelectedItemIndex(i % results.size()); + + if (originalValue == + formatString(GameConstants::OBSERVER_SLOTNAME) + && listBoxFactions[i].getSelectedItem() != + formatString(GameConstants::OBSERVER_SLOTNAME)) { + if (listBoxTeams[i].getSelectedItem() == + intToStr(GameConstants::maxPlayers + fpt_Observer)) { + listBoxTeams[i].setSelectedItem(intToStr(1)); + } + } + } else if (originalIndex < (int) results.size()) { + listBoxFactions[i].setSelectedItemIndex(originalIndex); + } + } + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + throw megaglest_runtime_error(szBuf); + } + } + + void MenuStateCustomGame::setSlotHuman(int i) { + if (labelPlayerNames[i].getEditable()) { + return; + } + listBoxControls[i].setSelectedItemIndex(ctHuman); + listBoxRMultiplier[i].setSelectedItem("1.0"); + + labelPlayerNames[i].setText(getHumanPlayerName()); + for (int j = 0; j < GameConstants::maxPlayers; ++j) { + labelPlayerNames[j].setEditable(false); + } + labelPlayerNames[i].setEditable(true); + } + + void MenuStateCustomGame::setupTilesetList(string scenario) { + try { + Config & config = Config::getInstance(); + + string scenarioDir = Scenario::getScenarioDir(dirList, scenario); + + vector < string > results; + findDirs(config.getPathListForType(ptTilesets, scenarioDir), + results); + if (results.empty()) { + throw megaglest_runtime_error("No tile-sets were found!"); + } + tilesetFiles = results; + std::for_each(results.begin(), results.end(), FormatString()); + + listBoxTileset.setItems(results); + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + throw megaglest_runtime_error(szBuf); + } + + } + + } } //end namespace diff --git a/source/glest_game/menu/menu_state_custom_game.h b/source/glest_game/menu/menu_state_custom_game.h index b43e69af5..3fb829f96 100644 --- a/source/glest_game/menu/menu_state_custom_game.h +++ b/source/glest_game/menu/menu_state_custom_game.h @@ -32,385 +32,380 @@ # include "leak_dumper.h" using namespace - Shared::Map; +Shared::Map; -namespace Shared -{ - namespace Graphics - { - class VideoPlayer; - } +namespace Shared { + namespace Graphics { + class VideoPlayer; + } } -namespace Glest -{ - namespace Game - { - - class SwitchSetupRequest; - class ServerInterface; - class TechTree; - - enum ParentMenuState - { - pNewGame, - pMasterServer, - pLanGame - }; - -// =============================== -// class MenuStateCustomGame -// =============================== - - class MenuStateCustomGame: - public MenuState, public SimpleTaskCallbackInterface - { - private: - GraphicButton buttonReturn; - GraphicButton buttonPlayNow; - GraphicButton buttonRestoreLastSettings; - GraphicLabel labelControl; - GraphicLabel labelRMultiplier; - GraphicLabel labelFaction; - GraphicLabel labelTeam; - GraphicLabel labelMap; - GraphicLabel labelFogOfWar; - GraphicLabel labelTechTree; - GraphicLabel labelTileset; - GraphicLabel labelMapInfo; - GraphicLabel labelLocalGameVersion; - GraphicLabel labelLocalIP; - GraphicLabel labelGameName; - - GraphicListBox listBoxMap; - GraphicListBox listBoxFogOfWar; - GraphicListBox listBoxTechTree; - GraphicListBox listBoxTileset; - - vector < string > mapFiles; - vector < string > playerSortedMaps[GameConstants::maxPlayers + 1]; - vector < - string > formattedPlayerSortedMaps[GameConstants::maxPlayers + 1]; - vector < string > techTreeFiles; - vector < string > tilesetFiles; - vector < string > factionFiles; - GraphicLabel labelPlayers[GameConstants::maxPlayers]; - GraphicLabel labelPlayerNames[GameConstants::maxPlayers]; - GraphicListBox listBoxControls[GameConstants::maxPlayers]; - GraphicButton buttonBlockPlayers[GameConstants::maxPlayers]; - GraphicListBox listBoxRMultiplier[GameConstants::maxPlayers]; - GraphicListBox listBoxFactions[GameConstants::maxPlayers]; - GraphicListBox listBoxTeams[GameConstants::maxPlayers]; - GraphicLabel labelNetStatus[GameConstants::maxPlayers]; - MapInfo mapInfo; - - GraphicButton buttonClearBlockedPlayers; - - GraphicLabel labelPublishServer; - GraphicCheckBox checkBoxPublishServer; - - GraphicMessageBox mainMessageBox; - int - mainMessageBoxState; - - GraphicLabel labelNetworkPauseGameForLaggedClients; - GraphicCheckBox checkBoxNetworkPauseGameForLaggedClients; - - GraphicLabel labelMapFilter; - GraphicListBox listBoxMapFilter; - - GraphicLabel labelAdvanced; - GraphicCheckBox checkBoxAdvanced; - - GraphicLabel labelAllowObservers; - GraphicCheckBox checkBoxAllowObservers; - - GraphicLabel * - activeInputLabel; - - GraphicLabel labelPlayerStatus[GameConstants::maxPlayers]; - GraphicListBox listBoxPlayerStatus; - - GraphicLabel labelEnableSwitchTeamMode; - GraphicCheckBox checkBoxEnableSwitchTeamMode; - - GraphicLabel labelAISwitchTeamAcceptPercent; - GraphicListBox listBoxAISwitchTeamAcceptPercent; - GraphicLabel labelFallbackCpuMultiplier; - GraphicListBox listBoxFallbackCpuMultiplier; - - GraphicLabel labelAllowInGameJoinPlayer; - GraphicCheckBox checkBoxAllowInGameJoinPlayer; - - GraphicLabel labelAllowTeamUnitSharing; - GraphicCheckBox checkBoxAllowTeamUnitSharing; - - GraphicLabel labelAllowTeamResourceSharing; - GraphicCheckBox checkBoxAllowTeamResourceSharing; - - - GraphicLabel labelAllowNativeLanguageTechtree; - GraphicCheckBox checkBoxAllowNativeLanguageTechtree; - - GraphicCheckBox checkBoxScenario; - GraphicLabel labelScenario; - GraphicListBox listBoxScenario; - - vector < string > scenarioFiles; - ScenarioInfo scenarioInfo; - vector < string > dirList; - string autoloadScenarioName; - time_t previewLoadDelayTimer; - bool needToLoadTextures; - bool enableScenarioTexturePreview; - Texture2D * - scenarioLogoTexture; - - bool needToSetChangedGameSettings; - time_t lastSetChangedGameSettings; - time_t lastMasterserverPublishing; - time_t lastNetworkPing; - time_t mapPublishingDelayTimer; - bool needToPublishDelayed; - - bool headlessHasConnectedPlayer; - - bool needToRepublishToMasterserver; - bool needToBroadcastServerSettings; - std::map < string, string > publishToServerInfo; - SimpleTaskThread * - publishToMasterserverThread; - SimpleTaskThread * - publishToClientsThread; - - ParentMenuState parentMenuState; - int - soundConnectionCount; - - time_t tMasterserverErrorElapsed; - bool showMasterserverError; - string masterServererErrorToShow; - - bool showGeneralError; - string generalErrorToShow; - bool serverInitError; - -//Console console; - ChatManager chatManager; - bool showFullConsole; - - string lastMapDataSynchError; - string lastTileDataSynchError; - string lastTechtreeDataSynchError; - - string defaultPlayerName; - int8 switchSetupRequestFlagType; - - bool enableFactionTexturePreview; - bool enableMapPreview; - - string currentTechName_factionPreview; - string currentFactionName_factionPreview; - string currentFactionLogo; - Texture2D * - factionTexture; - ::Shared::Graphics::VideoPlayer * factionVideo; - bool factionVideoSwitchedOffVolume; - - MapPreview mapPreview; - Texture2D * - mapPreviewTexture; - bool zoomedMap; - int - render_mapPreviewTexture_X; - int - render_mapPreviewTexture_Y; - int - render_mapPreviewTexture_W; - int - render_mapPreviewTexture_H; - - bool autostart; - GameSettings * - autoStartSettings; - - std::map < int, int > - lastSelectedTeamIndex; - float - rMultiplierOffset; - bool hasCheckedForUPNP; - - string lastCheckedCRCTilesetName; - string lastCheckedCRCTechtreeName; - string lastCheckedCRCMapName; - - string last_Forced_CheckedCRCTilesetName; - string last_Forced_CheckedCRCTechtreeName; - string last_Forced_CheckedCRCMapName; - - uint32 lastCheckedCRCTilesetValue; - uint32 lastCheckedCRCTechtreeValue; - uint32 lastCheckedCRCMapValue; - vector < pair < string, uint32 > >factionCRCList; - - bool forceWaitForShutdown; - bool headlessServerMode; - bool masterserverModeMinimalResources; - int - lastMasterServerSettingsUpdateCount; - - auto_ptr < TechTree > techTree; - - string gameUUID; - - int - lastGameSettingsreceivedCount; - - public: - MenuStateCustomGame (Program * program, MainMenu * mainMenu, - bool openNetworkSlots = - false, ParentMenuState parentMenuState = - pNewGame, bool autostart = - false, GameSettings * settings = - NULL, bool masterserverMode = - false, string autoloadScenarioName = ""); - virtual ~ MenuStateCustomGame (); - - void - mouseClick (int x, int y, MouseButton mouseButton); - void - mouseMove (int x, int y, const MouseState * mouseState); - void - render (); - void - update (); - - virtual bool textInput (std::string text); - virtual void - keyDown (SDL_KeyboardEvent key); - virtual void - keyPress (SDL_KeyboardEvent c); - virtual void - keyUp (SDL_KeyboardEvent key); - - - virtual void - simpleTask (BaseThread * callingThread, void *userdata); - virtual void - setupTask (BaseThread * callingThread, void *userdata); - virtual void - shutdownTask (BaseThread * callingThread, void *userdata); - static void - setupTaskStatic (BaseThread * callingThread); - static void - shutdownTaskStatic (BaseThread * callingThread); - - virtual bool isInSpecialKeyCaptureEvent (); - virtual bool isMasterserverMode ()const; - - virtual bool isVideoPlaying (); - private: - - void - lastPlayerDisconnected (); - bool hasNetworkGameSettings (); - void - loadGameSettings (GameSettings * gameSettings, - bool forceCloseUnusedSlots = false); - void - loadMapInfo (string file, MapInfo * mapInfo, bool loadMapPreview); - void - cleanupMapPreviewTexture (); - - void - updateControllers (); - void - closeUnusedSlots (); - void - updateNetworkSlots (); - void - publishToMasterserver (); - void - returnToParentMenu (); - void - showMessageBox (const string & text, const string & header, - bool toggle); - - void - saveGameSettingsToFile (std::string fileName); - void - switchToNextMapGroup (const int direction); - void - updateAllResourceMultiplier (); - void - updateResourceMultiplier (const int index); - string getCurrentMapFile (); - void - setActiveInputLabel (GraphicLabel * newLable); - string getHumanPlayerName (int index = -1); - - void - loadFactionTexture (string filepath); - - GameSettings loadGameSettingsFromFile (std::string fileName); - void - loadGameSettings (const std::string & fileName); - void - RestoreLastGameSettings (); - void - PlayNow (bool saveGame); - - void - SetActivePlayerNameEditor (); - void - cleanup (); - - int32 getNetworkPlayerStatus (); - void - setupUIFromGameSettings (const GameSettings & gameSettings); - - void - switchSetupForSlots (SwitchSetupRequest ** switchSetupRequests, - ServerInterface * &serverInterface, int startIndex, - int endIndex, bool onlyNetworkUnassigned); - - string createGameName (string controllingPlayer = ""); - void - reloadUI (); - void - loadScenarioInfo (string file, ScenarioInfo * scenarioInfo); - void - processScenario (); - void - SetupUIForScenarios (); - int - setupMapList (string scenario); - int - setupTechList (string scenario, bool forceLoad = false); - void - reloadFactions (bool keepExistingSelectedItem, string scenario); - void - setupTilesetList (string scenario); - void - setSlotHuman (int i); - - void - initFactionPreview (const GameSettings * gameSettings); - - bool - checkNetworkPlayerDataSynch (bool checkMapCRC, bool checkTileSetCRC, - bool checkTechTreeCRC); - - void - cleanupThread (SimpleTaskThread ** thread); - void - simpleTaskForMasterServer (BaseThread * callingThread); - void - simpleTaskForClients (BaseThread * callingThread); - void - KeepCurrentHumanPlayerSlots (GameSettings & gameSettings); - }; - -}} //end namespace +namespace Glest { + namespace Game { + + class SwitchSetupRequest; + class ServerInterface; + class TechTree; + + enum ParentMenuState { + pNewGame, + pMasterServer, + pLanGame + }; + + // =============================== + // class MenuStateCustomGame + // =============================== + + class MenuStateCustomGame : + public MenuState, public SimpleTaskCallbackInterface { + private: + GraphicButton buttonReturn; + GraphicButton buttonPlayNow; + GraphicButton buttonRestoreLastSettings; + GraphicLabel labelControl; + GraphicLabel labelRMultiplier; + GraphicLabel labelFaction; + GraphicLabel labelTeam; + GraphicLabel labelMap; + GraphicLabel labelFogOfWar; + GraphicLabel labelTechTree; + GraphicLabel labelTileset; + GraphicLabel labelMapInfo; + GraphicLabel labelLocalGameVersion; + GraphicLabel labelLocalIP; + GraphicLabel labelGameName; + + GraphicListBox listBoxMap; + GraphicListBox listBoxFogOfWar; + GraphicListBox listBoxTechTree; + GraphicListBox listBoxTileset; + + vector < string > mapFiles; + vector < string > playerSortedMaps[GameConstants::maxPlayers + 1]; + vector < + string > formattedPlayerSortedMaps[GameConstants::maxPlayers + 1]; + vector < string > techTreeFiles; + vector < string > tilesetFiles; + vector < string > factionFiles; + GraphicLabel labelPlayers[GameConstants::maxPlayers]; + GraphicLabel labelPlayerNames[GameConstants::maxPlayers]; + GraphicListBox listBoxControls[GameConstants::maxPlayers]; + GraphicButton buttonBlockPlayers[GameConstants::maxPlayers]; + GraphicListBox listBoxRMultiplier[GameConstants::maxPlayers]; + GraphicListBox listBoxFactions[GameConstants::maxPlayers]; + GraphicListBox listBoxTeams[GameConstants::maxPlayers]; + GraphicLabel labelNetStatus[GameConstants::maxPlayers]; + MapInfo mapInfo; + + GraphicButton buttonClearBlockedPlayers; + + GraphicLabel labelPublishServer; + GraphicCheckBox checkBoxPublishServer; + + GraphicMessageBox mainMessageBox; + int + mainMessageBoxState; + + GraphicLabel labelNetworkPauseGameForLaggedClients; + GraphicCheckBox checkBoxNetworkPauseGameForLaggedClients; + + GraphicLabel labelMapFilter; + GraphicListBox listBoxMapFilter; + + GraphicLabel labelAdvanced; + GraphicCheckBox checkBoxAdvanced; + + GraphicLabel labelAllowObservers; + GraphicCheckBox checkBoxAllowObservers; + + GraphicLabel * + activeInputLabel; + + GraphicLabel labelPlayerStatus[GameConstants::maxPlayers]; + GraphicListBox listBoxPlayerStatus; + + GraphicLabel labelEnableSwitchTeamMode; + GraphicCheckBox checkBoxEnableSwitchTeamMode; + + GraphicLabel labelAISwitchTeamAcceptPercent; + GraphicListBox listBoxAISwitchTeamAcceptPercent; + GraphicLabel labelFallbackCpuMultiplier; + GraphicListBox listBoxFallbackCpuMultiplier; + + GraphicLabel labelAllowInGameJoinPlayer; + GraphicCheckBox checkBoxAllowInGameJoinPlayer; + + GraphicLabel labelAllowTeamUnitSharing; + GraphicCheckBox checkBoxAllowTeamUnitSharing; + + GraphicLabel labelAllowTeamResourceSharing; + GraphicCheckBox checkBoxAllowTeamResourceSharing; + + + GraphicLabel labelAllowNativeLanguageTechtree; + GraphicCheckBox checkBoxAllowNativeLanguageTechtree; + + GraphicCheckBox checkBoxScenario; + GraphicLabel labelScenario; + GraphicListBox listBoxScenario; + + vector < string > scenarioFiles; + ScenarioInfo scenarioInfo; + vector < string > dirList; + string autoloadScenarioName; + time_t previewLoadDelayTimer; + bool needToLoadTextures; + bool enableScenarioTexturePreview; + Texture2D * + scenarioLogoTexture; + + bool needToSetChangedGameSettings; + time_t lastSetChangedGameSettings; + time_t lastMasterserverPublishing; + time_t lastNetworkPing; + time_t mapPublishingDelayTimer; + bool needToPublishDelayed; + + bool headlessHasConnectedPlayer; + + bool needToRepublishToMasterserver; + bool needToBroadcastServerSettings; + std::map < string, string > publishToServerInfo; + SimpleTaskThread * + publishToMasterserverThread; + SimpleTaskThread * + publishToClientsThread; + + ParentMenuState parentMenuState; + int + soundConnectionCount; + + time_t tMasterserverErrorElapsed; + bool showMasterserverError; + string masterServererErrorToShow; + + bool showGeneralError; + string generalErrorToShow; + bool serverInitError; + + //Console console; + ChatManager chatManager; + bool showFullConsole; + + string lastMapDataSynchError; + string lastTileDataSynchError; + string lastTechtreeDataSynchError; + + string defaultPlayerName; + int8 switchSetupRequestFlagType; + + bool enableFactionTexturePreview; + bool enableMapPreview; + + string currentTechName_factionPreview; + string currentFactionName_factionPreview; + string currentFactionLogo; + Texture2D * + factionTexture; + ::Shared::Graphics::VideoPlayer * factionVideo; + bool factionVideoSwitchedOffVolume; + + MapPreview mapPreview; + Texture2D * + mapPreviewTexture; + bool zoomedMap; + int + render_mapPreviewTexture_X; + int + render_mapPreviewTexture_Y; + int + render_mapPreviewTexture_W; + int + render_mapPreviewTexture_H; + + bool autostart; + GameSettings * + autoStartSettings; + + std::map < int, int > + lastSelectedTeamIndex; + float + rMultiplierOffset; + bool hasCheckedForUPNP; + + string lastCheckedCRCTilesetName; + string lastCheckedCRCTechtreeName; + string lastCheckedCRCMapName; + + string last_Forced_CheckedCRCTilesetName; + string last_Forced_CheckedCRCTechtreeName; + string last_Forced_CheckedCRCMapName; + + uint32 lastCheckedCRCTilesetValue; + uint32 lastCheckedCRCTechtreeValue; + uint32 lastCheckedCRCMapValue; + vector < pair < string, uint32 > >factionCRCList; + + bool forceWaitForShutdown; + bool headlessServerMode; + bool masterserverModeMinimalResources; + int + lastMasterServerSettingsUpdateCount; + + auto_ptr < TechTree > techTree; + + string gameUUID; + + int + lastGameSettingsreceivedCount; + + public: + MenuStateCustomGame(Program * program, MainMenu * mainMenu, + bool openNetworkSlots = + false, ParentMenuState parentMenuState = + pNewGame, bool autostart = + false, GameSettings * settings = + NULL, bool masterserverMode = + false, string autoloadScenarioName = ""); + virtual ~MenuStateCustomGame(); + + void + mouseClick(int x, int y, MouseButton mouseButton); + void + mouseMove(int x, int y, const MouseState * mouseState); + void + render(); + void + update(); + + virtual bool textInput(std::string text); + virtual void + keyDown(SDL_KeyboardEvent key); + virtual void + keyPress(SDL_KeyboardEvent c); + virtual void + keyUp(SDL_KeyboardEvent key); + + + virtual void + simpleTask(BaseThread * callingThread, void *userdata); + virtual void + setupTask(BaseThread * callingThread, void *userdata); + virtual void + shutdownTask(BaseThread * callingThread, void *userdata); + static void + setupTaskStatic(BaseThread * callingThread); + static void + shutdownTaskStatic(BaseThread * callingThread); + + virtual bool isInSpecialKeyCaptureEvent(); + virtual bool isMasterserverMode()const; + + virtual bool isVideoPlaying(); + private: + + void + lastPlayerDisconnected(); + bool hasNetworkGameSettings(); + void + loadGameSettings(GameSettings * gameSettings, + bool forceCloseUnusedSlots = false); + void + loadMapInfo(string file, MapInfo * mapInfo, bool loadMapPreview); + void + cleanupMapPreviewTexture(); + + void + updateControllers(); + void + closeUnusedSlots(); + void + updateNetworkSlots(); + void + publishToMasterserver(); + void + returnToParentMenu(); + void + showMessageBox(const string & text, const string & header, + bool toggle); + + void + saveGameSettingsToFile(std::string fileName); + void + switchToNextMapGroup(const int direction); + void + updateAllResourceMultiplier(); + void + updateResourceMultiplier(const int index); + string getCurrentMapFile(); + void + setActiveInputLabel(GraphicLabel * newLable); + string getHumanPlayerName(int index = -1); + + void + loadFactionTexture(string filepath); + + GameSettings loadGameSettingsFromFile(std::string fileName); + void + loadGameSettings(const std::string & fileName); + void + RestoreLastGameSettings(); + void + PlayNow(bool saveGame); + + void + SetActivePlayerNameEditor(); + void + cleanup(); + + int32 getNetworkPlayerStatus(); + void + setupUIFromGameSettings(const GameSettings & gameSettings); + + void + switchSetupForSlots(SwitchSetupRequest ** switchSetupRequests, + ServerInterface * &serverInterface, int startIndex, + int endIndex, bool onlyNetworkUnassigned); + + string createGameName(string controllingPlayer = ""); + void + reloadUI(); + void + loadScenarioInfo(string file, ScenarioInfo * scenarioInfo); + void + processScenario(); + void + SetupUIForScenarios(); + int + setupMapList(string scenario); + int + setupTechList(string scenario, bool forceLoad = false); + void + reloadFactions(bool keepExistingSelectedItem, string scenario); + void + setupTilesetList(string scenario); + void + setSlotHuman(int i); + + void + initFactionPreview(const GameSettings * gameSettings); + + bool + checkNetworkPlayerDataSynch(bool checkMapCRC, bool checkTileSetCRC, + bool checkTechTreeCRC); + + void + cleanupThread(SimpleTaskThread ** thread); + void + simpleTaskForMasterServer(BaseThread * callingThread); + void + simpleTaskForClients(BaseThread * callingThread); + void + KeepCurrentHumanPlayerSlots(GameSettings & gameSettings); + }; + + } +} //end namespace #endif diff --git a/source/glest_game/menu/menu_state_custom_game_update.cpp b/source/glest_game/menu/menu_state_custom_game_update.cpp index 902d790fb..fbbcce85c 100644 --- a/source/glest_game/menu/menu_state_custom_game_update.cpp +++ b/source/glest_game/menu/menu_state_custom_game_update.cpp @@ -27,1272 +27,1108 @@ #include "server_interface.h" #include "network_manager.h" -namespace Glest -{ - namespace Game - { - const int MASTERSERVER_BROADCAST_PUBLISH_SECONDS = 6; - const int BROADCAST_SETTINGS_SECONDS = 4; - const int BROADCAST_MAP_DELAY_SECONDS = 5; - -// These functions are prototyped in menu_state_custom_game.h - - void MenuStateCustomGame::update () - { - Chrono chrono; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled) - chrono.start (); - -// Test openal buffer underrun issue -//sleep(200); -// END - - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - MutexSafeWrapper - safeMutexCLI ((publishToClientsThread != - NULL ? - publishToClientsThread->getMutexThreadObjectAccessor () - : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - try - { - if (serverInitError == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (showGeneralError) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - - showGeneralError = false; - mainMessageBoxState = 1; - showMessageBox (generalErrorToShow, "Error", false); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (this->headlessServerMode == false) - { - return; - } - } - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - Lang & lang = Lang::getInstance (); - - if (serverInterface != NULL - && serverInterface->getServerSocket () != NULL) - { - buttonClearBlockedPlayers. - setEditable (serverInterface->getServerSocket - ()->hasBlockedIPAddresses ()); - } - - if (this->autoloadScenarioName != "") - { - listBoxScenario.setSelectedItem (formatString - (this->autoloadScenarioName), - false); - lastSetChangedGameSettings = time (NULL); - if (serverInterface != NULL) - { - lastGameSettingsreceivedCount = - serverInterface->getGameSettingsUpdateCount (); - } - if (listBoxScenario.getSelectedItem () != - formatString (this->autoloadScenarioName)) - { - mainMessageBoxState = 1; - showMessageBox ("Could not find scenario name: " + - formatString (this->autoloadScenarioName), - "Scenario Missing", false); - this->autoloadScenarioName = ""; - } - else - { - loadScenarioInfo (Scenario::getScenarioPath (dirList, - scenarioFiles - [listBoxScenario.getSelectedItemIndex - ()]), - &scenarioInfo); -//labelInfo.setText(scenarioInfo.desc); - - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - CoreData & coreData = CoreData::getInstance (); - soundRenderer.playFx (coreData.getClickSoundC ()); -//launchGame(); - PlayNow (true); - return; - } - } - - if (needToLoadTextures) - { -// this delay is done to make it possible to switch faster - if (difftime ((long int) time (NULL), previewLoadDelayTimer) >= 2) - { -//loadScenarioPreviewTexture(); - needToLoadTextures = false; - } - } - -//bool haveAtLeastOneNetworkClientConnected = false; - bool hasOneNetworkSlotOpen = false; - int currentConnectionCount = 0; - Config & config = Config::getInstance (); - - bool masterServerErr = showMasterserverError; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (masterServerErr) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - if (EndsWith (masterServererErrorToShow, "wrong router setup") == - true) - { - masterServererErrorToShow = lang.getString ("WrongRouterSetup"); - } - - Lang & lang = Lang::getInstance (); - string publishText = " (disabling publish)"; - if (lang.hasString ("PublishDisabled") == true) - { - publishText = lang.getString ("PublishDisabled"); - } - - masterServererErrorToShow += "\n\n" + publishText; - showMasterserverError = false; - mainMessageBoxState = 1; - showMessageBox (masterServererErrorToShow, - lang.getString ("ErrorFromMasterserver"), false); - - if (this->headlessServerMode == false) - { - checkBoxPublishServer.setValue (false); - } - - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - serverInterface-> - setPublishEnabled (checkBoxPublishServer.getValue () == true); - } - else if (showGeneralError) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - showGeneralError = false; - mainMessageBoxState = 1; - showMessageBox (generalErrorToShow, "Error", false); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (this->headlessServerMode == true && serverInterface == NULL) - { - throw megaglest_runtime_error ("serverInterface == NULL"); - } - if (this->headlessServerMode == true - && serverInterface->getGameSettingsUpdateCount () > - lastMasterServerSettingsUpdateCount - && serverInterface->getGameSettings () != NULL) - { - const GameSettings *settings = serverInterface->getGameSettings (); -//printf("\n\n\n\n=====#1 got settings [%d] [%d]:\n%s\n",lastMasterServerSettingsUpdateCount,serverInterface->getGameSettingsUpdateCount(),settings->toString().c_str()); - - lastMasterServerSettingsUpdateCount = - serverInterface->getGameSettingsUpdateCount (); -//printf("#2 custom menu got map [%s]\n",settings->getMap().c_str()); - - setupUIFromGameSettings (*settings); - printf ("received Settings map filter=%d\n", - settings->getMapFilter ()); - - GameSettings gameSettings; - loadGameSettings (&gameSettings); - -//printf("\n\n\n\n=====#1.1 got settings [%d] [%d]:\n%s\n",lastMasterServerSettingsUpdateCount,serverInterface->getGameSettingsUpdateCount(),gameSettings.toString().c_str()); - - } - if (this->headlessServerMode == true - && serverInterface->getMasterserverAdminRequestLaunch () == true) - { - serverInterface->setMasterserverAdminRequestLaunch (false); - safeMutex.ReleaseLock (); - safeMutexCLI.ReleaseLock (); - - PlayNow (false); - return; - } - -// handle setting changes from clients - SwitchSetupRequest **switchSetupRequests = - serverInterface->getSwitchSetupRequests (); -//!!! - switchSetupForSlots (switchSetupRequests, serverInterface, 0, - mapInfo.players, false); - switchSetupForSlots (switchSetupRequests, serverInterface, - mapInfo.players, GameConstants::maxPlayers, - true); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - GameSettings gameSettings; - loadGameSettings (&gameSettings); - - listBoxAISwitchTeamAcceptPercent.setEnabled - (checkBoxEnableSwitchTeamMode.getValue ()); - - int factionCount = 0; - for (int i = 0; i < mapInfo.players; ++i) - { - if (hasNetworkGameSettings () == true) - { - if (listBoxControls[i].getSelectedItemIndex () != ctClosed) - { - int slotIndex = factionCount; - if (listBoxControls[i].getSelectedItemIndex () == ctHuman) - { - switch (gameSettings.getNetworkPlayerStatuses (slotIndex)) - { - case npst_BeRightBack: - labelPlayerStatus[i].setTexture (CoreData::getInstance - ().getStatusBRBTexture ()); - break; - case npst_Ready: - labelPlayerStatus[i].setTexture (CoreData::getInstance - ().getStatusReadyTexture - ()); - break; - case npst_PickSettings: - labelPlayerStatus[i].setTexture (CoreData::getInstance - ().getStatusNotReadyTexture - ()); - break; - case npst_Disconnected: - labelPlayerStatus[i].setTexture (NULL); - break; - - default: - labelPlayerStatus[i].setTexture (NULL); - break; - } - } - else - { - labelPlayerStatus[i].setTexture (NULL); - } - - factionCount++; - } - else - { - labelPlayerStatus[i].setTexture (NULL); - } - } - - if (listBoxControls[i].getSelectedItemIndex () == ctNetwork || - listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned) - { - hasOneNetworkSlotOpen = true; - - if (serverInterface->getSlot (i, true) != NULL && - serverInterface->getSlot (i, true)->isConnected ()) - { - - if (hasNetworkGameSettings () == true) - { - switch (serverInterface-> - getSlot (i, true)->getNetworkPlayerStatus ()) - { - case npst_BeRightBack: - labelPlayerStatus[i].setTexture (CoreData::getInstance - ().getStatusBRBTexture ()); - break; - case npst_Ready: - labelPlayerStatus[i].setTexture (CoreData::getInstance - ().getStatusReadyTexture - ()); - break; - case npst_PickSettings: - default: - labelPlayerStatus[i].setTexture (CoreData::getInstance - ().getStatusNotReadyTexture - ()); - break; - } - } - - serverInterface->getSlot (i, - true)->setName (labelPlayerNames[i]. - getText ()); - -//printf("FYI we have at least 1 client connected, slot = %d'\n",i); - -//haveAtLeastOneNetworkClientConnected = true; - if (serverInterface->getSlot (i, true) != NULL && - serverInterface->getSlot (i, - true)->getConnectHasHandshaked ()) - { - currentConnectionCount++; - } - string label = - (serverInterface->getSlot (i, true) != - NULL ? serverInterface->getSlot (i, - true)->getVersionString () : - ""); - - if (serverInterface->getSlot (i, true) != NULL && - serverInterface->getSlot (i, - true)->getAllowDownloadDataSynch - () == true - && serverInterface->getSlot (i, - true)->getAllowGameDataSynchCheck - () == true) - { - if (serverInterface->getSlot (i, - true)->getNetworkGameDataSynchCheckOk - () == false) - { - label += " -waiting to synch:"; - if (serverInterface->getSlot (i, - true)->getNetworkGameDataSynchCheckOkMap - () == false) - { - label = label + " map"; - } - if (serverInterface->getSlot (i, - true)->getNetworkGameDataSynchCheckOkTile - () == false) - { - label = label + " tile"; - } - if (serverInterface->getSlot (i, - true)->getNetworkGameDataSynchCheckOkTech - () == false) - { - label = label + " techtree"; - } - } - else - { - label += " - data synch is ok"; - } - } - else - { - if (serverInterface->getSlot (i, true) != NULL && - serverInterface->getSlot (i, - true)->getAllowGameDataSynchCheck - () == true - && serverInterface->getSlot (i, - true)->getNetworkGameDataSynchCheckOk - () == false) - { - label += " -synch mismatch:"; - - if (serverInterface->getSlot (i, true) != NULL - && serverInterface->getSlot (i, - true)->getNetworkGameDataSynchCheckOkMap - () == false) - { - label = label + " map"; - - if (serverInterface->getSlot (i, - true)->getReceivedDataSynchCheck - () == true - && lastMapDataSynchError != - "map CRC mismatch, " + listBoxMap.getSelectedItem ()) - { - lastMapDataSynchError = - "map CRC mismatch, " + listBoxMap.getSelectedItem (); - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - serverInterface->sendTextMessage (lastMapDataSynchError, - -1, true, ""); - } - } - - if (serverInterface->getSlot (i, true) != NULL && - serverInterface->getSlot (i, - true)->getNetworkGameDataSynchCheckOkTile - () == false) - { - label = label + " tile"; - - if (serverInterface->getSlot (i, - true)->getReceivedDataSynchCheck - () == true - && lastTileDataSynchError != - "tile CRC mismatch, " + - listBoxTileset.getSelectedItem ()) - { - lastTileDataSynchError = - "tile CRC mismatch, " + - listBoxTileset.getSelectedItem (); - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - serverInterface->sendTextMessage - (lastTileDataSynchError, -1, true, ""); - } - } - - if (serverInterface->getSlot (i, true) != NULL && - serverInterface->getSlot (i, - true)->getNetworkGameDataSynchCheckOkTech - () == false) - { - label = label + " techtree"; - - if (serverInterface->getSlot (i, - true)->getReceivedDataSynchCheck - () == true) - { - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - string report = serverInterface->getSlot (i, - true)->getNetworkGameDataSynchCheckTechMismatchReport - (); - - if (lastTechtreeDataSynchError != - "techtree CRC mismatch" + report) - { - lastTechtreeDataSynchError = - "techtree CRC mismatch" + report; - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] report: %s\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), - __FUNCTION__, - __LINE__, - report.c_str ()); - - serverInterface->sendTextMessage - ("techtree CRC mismatch", -1, true, ""); - vector < string > reportLineTokens; - Tokenize (report, reportLineTokens, "\n"); - for (int reportLine = 0; - reportLine < - (int) reportLineTokens.size (); ++reportLine) - { - serverInterface->sendTextMessage - (reportLineTokens[reportLine], -1, true, ""); - } - } - } - } - - if (serverInterface->getSlot (i, true) != NULL) - { - serverInterface->getSlot (i, - true)->setReceivedDataSynchCheck - (false); - } - } - } - -//float pingTime = serverInterface->getSlot(i)->getThreadedPingMS(serverInterface->getSlot(i)->getIpAddress().c_str()); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "%s", label.c_str ()); - - labelNetStatus[i].setText (szBuf); - } - else - { - string port = - "(" + intToStr (config.getInt ("PortServer")) + ")"; - labelNetStatus[i].setText ("--- " + port); - } - } - else - { - labelNetStatus[i].setText (""); - } - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (checkBoxScenario.getValue () == false) - { - // When scenario is checked the value for mapInfo.players is reset to - // hardMaxPlayers. This resets it. - mapInfo.players = checkBoxAllowObservers.getValue () == true ? - GameConstants::maxPlayers : - mapInfo.hardMaxPlayers; - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - if (i >= mapInfo.hardMaxPlayers) - { - if (checkBoxAllowObservers.getValue() == false) - { - listBoxControls[i].setSelectedItemIndex (ctClosed); - listBoxControls[i].setEditable (false); - listBoxControls[i].setEnabled (false); - } - else - { - if (listBoxControls[i].getSelectedItemIndex () != ctHuman) - { - listBoxControls[i].setSelectedItemIndex (ctNetwork); - } - listBoxControls[i].setEditable (i == GameConstants::maxPlayers - 1); - listBoxControls[i].setEnabled (i == GameConstants::maxPlayers - 1); - listBoxFactions[i].setSelectedItem (GameConstants::OBSERVER_SLOTNAME); - listBoxFactions[i].setEditable (false); - listBoxTeams[i].setSelectedItem (intToStr (GameConstants::maxPlayers + - fpt_Observer)); - listBoxTeams[i].setEditable (false); - } - - listBoxRMultiplier[i].setEditable (false); - listBoxRMultiplier[i].setEnabled (false); - listBoxRMultiplier[i].setVisible (false); - } - else if (listBoxControls[i].getSelectedItemIndex () != - ctNetworkUnassigned) - { - ConnectionSlot *slot = serverInterface->getSlot (i, true); - if ((listBoxControls[i].getSelectedItemIndex () != - ctNetwork) - || (listBoxControls[i].getSelectedItemIndex () == - ctNetwork && (slot == NULL - || slot->isConnected () == false))) - { - listBoxControls[i].setEditable (true); - listBoxControls[i].setEnabled (true); - listBoxFactions[i].setEditable (true); - listBoxTeams[i].setEditable (true); - - if (listBoxControls[i].getSelectedItemIndex () == ctNetwork && - listBoxFactions[i].getSelectedItem () == formatString (GameConstants::OBSERVER_SLOTNAME)) - { - listBoxFactions[i].setSelectedItemIndex (0); - } - } - else - { - listBoxControls[i].setEditable (false); - listBoxControls[i].setEnabled (false); - } - } - else - { - listBoxControls[i].setEditable (false); - listBoxControls[i].setEnabled (false); - } - } - } - else // if this is a scenario... - { - int i = mapInfo.players; - do - { - listBoxControls[i].setSelectedItemIndex (ctClosed); - listBoxControls[i].setEditable (false); - listBoxControls[i].setEnabled (false); - } while (++i < GameConstants::maxPlayers); - } - - // updateNetworkSlots (); - - bool checkDataSynch = - (serverInterface->getAllowGameDataSynchCheck () == true - && needToSetChangedGameSettings == true - && - ((difftime ((long int) time (NULL), lastSetChangedGameSettings) >= - BROADCAST_SETTINGS_SECONDS) - || (this->headlessServerMode == true))); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - -// Send the game settings to each client if we have at least one networked client - if (checkDataSynch == true) - { - serverInterface->setGameSettings (&gameSettings, false); - needToSetChangedGameSettings = false; - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (this->headlessServerMode == true || hasOneNetworkSlotOpen == true - || checkBoxAllowInGameJoinPlayer.getValue () == true) - { - if (this->headlessServerMode == true && - GlobalStaticFlags::isFlagSet (gsft_lan_mode) == false) - { - checkBoxPublishServer.setValue (true); - } - listBoxFallbackCpuMultiplier.setEditable (true); - checkBoxPublishServer.setEditable (true); - -// Masterserver always needs one network slot - if (this->headlessServerMode == true - && hasOneNetworkSlotOpen == false) - { - bool anyoneConnected = false; - for (int i = 0; i < mapInfo.players; ++i) - { - MutexSafeWrapper - safeMutex ((publishToMasterserverThread != - NULL ? - publishToMasterserverThread->getMutexThreadObjectAccessor - () : NULL), - string (__FILE__) + "_" + intToStr (__LINE__)); - - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - ConnectionSlot *slot = serverInterface->getSlot (i, true); - if (slot != NULL && slot->isConnected () == true) - { - anyoneConnected = true; - break; - } - } - - for (int i = 0; i < mapInfo.players; ++i) - { - if (anyoneConnected == false - && listBoxControls[i].getSelectedItemIndex () != ctNetwork) - { - listBoxControls[i].setSelectedItemIndex (ctNetwork); - } - } - - updateNetworkSlots (); - } - } - else - { - checkBoxPublishServer.setValue (false); - checkBoxPublishServer.setEditable (false); - listBoxFallbackCpuMultiplier.setEditable (false); - listBoxFallbackCpuMultiplier.setSelectedItem ("1.0"); - - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - serverInterface-> - setPublishEnabled (checkBoxPublishServer.getValue () == true); - } - - bool republishToMaster = - (difftime ((long int) time (NULL), lastMasterserverPublishing) >= - MASTERSERVER_BROADCAST_PUBLISH_SECONDS); - - if (republishToMaster == true) - { - if (checkBoxPublishServer.getValue () == true) - { - needToRepublishToMasterserver = true; - lastMasterserverPublishing = time (NULL); - } - } - - bool callPublishNow = (checkBoxPublishServer.getEditable () && - checkBoxPublishServer.getValue () == true && - needToRepublishToMasterserver == true); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (callPublishNow == true) - { -// give it to me baby, aha aha ... - publishToMasterserver (); - } - if (needToPublishDelayed) - { -// this delay is done to make it possible to switch over maps which are not meant to be distributed - if ((difftime ((long int) time (NULL), mapPublishingDelayTimer) >= - BROADCAST_MAP_DELAY_SECONDS) - || (this->headlessServerMode == true)) - { -// after 5 seconds we are allowed to publish again! - needToSetChangedGameSettings = true; - lastSetChangedGameSettings = time (NULL); -// set to normal.... - needToPublishDelayed = false; - } - } - if (needToPublishDelayed == false || headlessServerMode == true) - { - bool broadCastSettings = - (difftime ((long int) time (NULL), lastSetChangedGameSettings) - >= BROADCAST_SETTINGS_SECONDS); - - if (headlessServerMode == true) - { -// publish settings directly when we receive them - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - if (lastGameSettingsreceivedCount < - serverInterface->getGameSettingsUpdateCount ()) - { - needToBroadcastServerSettings = true; - lastSetChangedGameSettings = time (NULL); - lastGameSettingsreceivedCount = - serverInterface->getGameSettingsUpdateCount (); - } - } - - if (broadCastSettings == true) - { - needToBroadcastServerSettings = true; - lastSetChangedGameSettings = time (NULL); - } - - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - -//broadCastSettings = (difftime(time(NULL),lastSetChangedGameSettings) >= 2); -//if (broadCastSettings == true) {// reset timer here on bottom becasue used for different things -// lastSetChangedGameSettings = time(NULL); -//} - } - - if (this->headlessServerMode == true) - { - lastPlayerDisconnected (); - } - -//call the chat manager - chatManager.updateNetwork (); - -//console - console.update (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (currentConnectionCount > soundConnectionCount) - { - soundConnectionCount = currentConnectionCount; - static PlaySoundClip snd; - SoundRenderer::getInstance (). - playFx (snd.getSound (snd.sfxAttention)); -//switch on music again!! - Config & config = Config::getInstance (); - float configVolume = (config.getInt ("SoundVolumeMusic") / 100.f); - CoreData::getInstance ().getMenuMusic ()->setVolume (configVolume); - } - soundConnectionCount = currentConnectionCount; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (enableFactionTexturePreview == true) - { - if (currentTechName_factionPreview != gameSettings.getTech () || - currentFactionName_factionPreview != - gameSettings. - getFactionTypeName (gameSettings.getThisFactionIndex ())) - { - - currentTechName_factionPreview = gameSettings.getTech (); - currentFactionName_factionPreview = - gameSettings. - getFactionTypeName (gameSettings.getThisFactionIndex ()); - - initFactionPreview (&gameSettings); - } - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s Line: %d] took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - chrono.start (); - - if (autostart == true) - { - autostart = false; - safeMutex.ReleaseLock (); - safeMutexCLI.ReleaseLock (); - if (autoStartSettings != NULL) - { - - setupUIFromGameSettings (*autoStartSettings); - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - serverInterface->setGameSettings (autoStartSettings, false); - } - else - { - RestoreLastGameSettings (); - } - PlayNow ((autoStartSettings == NULL)); - return; - } - } - catch (megaglest_runtime_error & ex) - { -//abort(); -//printf("1111111bbbb ex.wantStackTrace() = %d\n",ex.wantStackTrace()); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - -//printf("2222222bbbb ex.wantStackTrace() = %d\n",ex.wantStackTrace()); - - showGeneralError = true; - generalErrorToShow = szBuf; - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - showGeneralError = true; - generalErrorToShow = szBuf; - } - } - - void MenuStateCustomGame::updateControllers () - { - try - { - bool humanPlayer = false; - - for (int i = 0; i < mapInfo.players; ++i) - { - if (listBoxControls[i].getSelectedItemIndex () == ctHuman) - { - humanPlayer = true; - } - } - - if (humanPlayer == false) - { - if (this->headlessServerMode == false) - { - bool foundNewSlotForHuman = false; - for (int i = 0; i < mapInfo.players; ++i) - { - if (listBoxControls[i].getSelectedItemIndex () == ctClosed) - { - setSlotHuman (i); - foundNewSlotForHuman = true; - break; - } - } - - if (foundNewSlotForHuman == false) - { - for (int i = 0; i < mapInfo.players; ++i) - { - if (listBoxControls[i].getSelectedItemIndex () == - ctClosed - || listBoxControls[i].getSelectedItemIndex () == - ctCpuEasy - || listBoxControls[i].getSelectedItemIndex () == - ctCpu - || listBoxControls[i].getSelectedItemIndex () == - ctCpuUltra - || listBoxControls[i].getSelectedItemIndex () == - ctCpuZeta) - { - setSlotHuman (i); - - foundNewSlotForHuman = true; - break; - } - } - } - - if (foundNewSlotForHuman == false) - { - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - ConnectionSlot *slot = serverInterface->getSlot (0, true); - if (slot != NULL && slot->isConnected () == true) - { - serverInterface->removeSlot (0); - } - setSlotHuman (0); - } - } - } - - for (int i = mapInfo.players; i < GameConstants::maxPlayers; ++i) - { - if (listBoxControls[i].getSelectedItemIndex () != ctNetwork && - listBoxControls[i].getSelectedItemIndex () != - ctNetworkUnassigned) - { -//printf("Closed A [%d] [%s]\n",i,labelPlayerNames[i].getText().c_str()); - - listBoxControls[i].setSelectedItemIndex (ctClosed); - } - } - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw megaglest_runtime_error (szBuf); - } - } - - void MenuStateCustomGame::updateNetworkSlots () - { - try - { - ServerInterface *serverInterface = - NetworkManager::getInstance ().getServerInterface (); - - if (hasNetworkGameSettings () == true) - { - if (hasCheckedForUPNP == false) - { - - if (checkBoxPublishServer.getValue () == true || - this->headlessServerMode == true) - { - - hasCheckedForUPNP = true; - serverInterface->getServerSocket ()->NETdiscoverUPnPDevices (); - } - } - } - else - { - hasCheckedForUPNP = false; - } - - for (int i = 0; i < GameConstants::maxPlayers; ++i) - { - ConnectionSlot *slot = serverInterface->getSlot (i, true); -//printf("A i = %d control type = %d slot [%p]\n",i,listBoxControls[i].getSelectedItemIndex(),slot); - - if (slot == NULL && - listBoxControls[i].getSelectedItemIndex () == ctNetwork) - { - try - { - serverInterface->addSlot (i); - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", - szBuf); - showGeneralError = true; - if (serverInterface->isPortBound () == false) - { - generalErrorToShow = - Lang::getInstance ().getString ("ErrorBindingPort") + - " : " + intToStr (serverInterface->getBindPort ()); - } - else - { - generalErrorToShow = ex.what (); - } - -// Revert network to CPU - listBoxControls[i].setSelectedItemIndex (ctCpu); - } - } - slot = serverInterface->getSlot (i, true); - if (slot != NULL) - { - if ((listBoxControls[i].getSelectedItemIndex () != ctNetwork) - || (listBoxControls[i].getSelectedItemIndex () == - ctNetwork && slot->isConnected () == false - && i >= mapInfo.players)) - { - if (slot->getCanAcceptConnections () == true) - { - slot->setCanAcceptConnections (false); - } - if (slot->isConnected () == true) - { - if (listBoxControls[i].getSelectedItemIndex () != - ctNetworkUnassigned) - { - listBoxControls[i].setSelectedItemIndex - (ctNetworkUnassigned); - } - } - else - { - serverInterface->removeSlot (i); - - if (listBoxControls[i].getSelectedItemIndex () == - ctNetworkUnassigned) - { - listBoxControls[i].setSelectedItemIndex (ctClosed); - } - } - } - else if (slot->getCanAcceptConnections () == false) - { - slot->setCanAcceptConnections (true); - } - } - } - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); -//throw megaglest_runtime_error(szBuf); - showGeneralError = true; - generalErrorToShow = szBuf; - - } - } - - void MenuStateCustomGame::updateAllResourceMultiplier () - { - for (int j = 0; j < GameConstants::maxPlayers; ++j) - { - updateResourceMultiplier (j); - } - } - - void MenuStateCustomGame::updateResourceMultiplier (const int index) - { -//printf("Line: %d multiplier index: %d index: %d\n",__LINE__,listBoxRMultiplier[index].getSelectedItemIndex(),index); - - ControlType ct = - static_cast < ControlType > - (listBoxControls[index].getSelectedItemIndex ()); - if (ct == ctCpuEasy || ct == ctNetworkCpuEasy) - { - listBoxRMultiplier[index].setSelectedItem (floatToStr - (GameConstants:: - easyMultiplier, 1)); - listBoxRMultiplier[index].setEnabled (checkBoxScenario.getValue () == - false); - } - else if (ct == ctCpu || ct == ctNetworkCpu) - { - listBoxRMultiplier[index].setSelectedItem (floatToStr - (GameConstants:: - normalMultiplier, 1)); - listBoxRMultiplier[index].setEnabled (checkBoxScenario.getValue () == - false); - } - else if (ct == ctCpuUltra || ct == ctNetworkCpuUltra) - { - listBoxRMultiplier[index].setSelectedItem (floatToStr - (GameConstants:: - ultraMultiplier, 1)); - listBoxRMultiplier[index].setEnabled (checkBoxScenario.getValue () == - false); - } - else if (ct == ctCpuZeta || ct == ctNetworkCpuZeta) - { - listBoxRMultiplier[index].setSelectedItem (floatToStr - (GameConstants:: - megaMultiplier, 1)); - listBoxRMultiplier[index].setEnabled (checkBoxScenario.getValue () == - false); - } -//if(ct == ctHuman || ct == ctNetwork || ct == ctClosed) { - else - { - listBoxRMultiplier[index].setSelectedItem (floatToStr - (GameConstants:: - normalMultiplier, 1)); - listBoxRMultiplier[index].setEnabled (false); -//!!!listBoxRMultiplier[index].setEnabled(checkBoxScenario.getValue() == false); - } - - listBoxRMultiplier[index]. - setEditable (listBoxRMultiplier[index].getEnabled ()); - listBoxRMultiplier[index].setVisible (ct != ctHuman && ct != ctNetwork - && ct != ctClosed); -//listBoxRMultiplier[index].setVisible(ct != ctClosed); - -//printf("Line: %d multiplier index: %d index: %d\n",__LINE__,listBoxRMultiplier[index].getSelectedItemIndex(),index); - } - } // end namespace +namespace Glest { + namespace Game { + const int MASTERSERVER_BROADCAST_PUBLISH_SECONDS = 6; + const int BROADCAST_SETTINGS_SECONDS = 4; + const int BROADCAST_MAP_DELAY_SECONDS = 5; + + // These functions are prototyped in menu_state_custom_game.h + + void MenuStateCustomGame::update() { + Chrono chrono; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled) + chrono.start(); + + // Test openal buffer underrun issue + //sleep(200); + // END + + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper + safeMutexCLI((publishToClientsThread != + NULL ? + publishToClientsThread->getMutexThreadObjectAccessor() + : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + try { + if (serverInitError == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (showGeneralError) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + + showGeneralError = false; + mainMessageBoxState = 1; + showMessageBox(generalErrorToShow, "Error", false); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (this->headlessServerMode == false) { + return; + } + } + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + Lang & lang = Lang::getInstance(); + + if (serverInterface != NULL + && serverInterface->getServerSocket() != NULL) { + buttonClearBlockedPlayers. + setEditable(serverInterface->getServerSocket + ()->hasBlockedIPAddresses()); + } + + if (this->autoloadScenarioName != "") { + listBoxScenario.setSelectedItem(formatString + (this->autoloadScenarioName), + false); + lastSetChangedGameSettings = time(NULL); + if (serverInterface != NULL) { + lastGameSettingsreceivedCount = + serverInterface->getGameSettingsUpdateCount(); + } + if (listBoxScenario.getSelectedItem() != + formatString(this->autoloadScenarioName)) { + mainMessageBoxState = 1; + showMessageBox("Could not find scenario name: " + + formatString(this->autoloadScenarioName), + "Scenario Missing", false); + this->autoloadScenarioName = ""; + } else { + loadScenarioInfo(Scenario::getScenarioPath(dirList, + scenarioFiles + [listBoxScenario.getSelectedItemIndex + ()]), + &scenarioInfo); + //labelInfo.setText(scenarioInfo.desc); + + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + CoreData & coreData = CoreData::getInstance(); + soundRenderer.playFx(coreData.getClickSoundC()); + //launchGame(); + PlayNow(true); + return; + } + } + + if (needToLoadTextures) { + // this delay is done to make it possible to switch faster + if (difftime((long int) time(NULL), previewLoadDelayTimer) >= 2) { + //loadScenarioPreviewTexture(); + needToLoadTextures = false; + } + } + + //bool haveAtLeastOneNetworkClientConnected = false; + bool hasOneNetworkSlotOpen = false; + int currentConnectionCount = 0; + Config & config = Config::getInstance(); + + bool masterServerErr = showMasterserverError; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (masterServerErr) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + if (EndsWith(masterServererErrorToShow, "wrong router setup") == + true) { + masterServererErrorToShow = lang.getString("WrongRouterSetup"); + } + + Lang & lang = Lang::getInstance(); + string publishText = " (disabling publish)"; + if (lang.hasString("PublishDisabled") == true) { + publishText = lang.getString("PublishDisabled"); + } + + masterServererErrorToShow += "\n\n" + publishText; + showMasterserverError = false; + mainMessageBoxState = 1; + showMessageBox(masterServererErrorToShow, + lang.getString("ErrorFromMasterserver"), false); + + if (this->headlessServerMode == false) { + checkBoxPublishServer.setValue(false); + } + + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + serverInterface-> + setPublishEnabled(checkBoxPublishServer.getValue() == true); + } else if (showGeneralError) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + showGeneralError = false; + mainMessageBoxState = 1; + showMessageBox(generalErrorToShow, "Error", false); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (this->headlessServerMode == true && serverInterface == NULL) { + throw megaglest_runtime_error("serverInterface == NULL"); + } + if (this->headlessServerMode == true + && serverInterface->getGameSettingsUpdateCount() > + lastMasterServerSettingsUpdateCount + && serverInterface->getGameSettings() != NULL) { + const GameSettings *settings = serverInterface->getGameSettings(); + //printf("\n\n\n\n=====#1 got settings [%d] [%d]:\n%s\n",lastMasterServerSettingsUpdateCount,serverInterface->getGameSettingsUpdateCount(),settings->toString().c_str()); + + lastMasterServerSettingsUpdateCount = + serverInterface->getGameSettingsUpdateCount(); + //printf("#2 custom menu got map [%s]\n",settings->getMap().c_str()); + + setupUIFromGameSettings(*settings); + printf("received Settings map filter=%d\n", + settings->getMapFilter()); + + GameSettings gameSettings; + loadGameSettings(&gameSettings); + + //printf("\n\n\n\n=====#1.1 got settings [%d] [%d]:\n%s\n",lastMasterServerSettingsUpdateCount,serverInterface->getGameSettingsUpdateCount(),gameSettings.toString().c_str()); + + } + if (this->headlessServerMode == true + && serverInterface->getMasterserverAdminRequestLaunch() == true) { + serverInterface->setMasterserverAdminRequestLaunch(false); + safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); + + PlayNow(false); + return; + } + + // handle setting changes from clients + SwitchSetupRequest **switchSetupRequests = + serverInterface->getSwitchSetupRequests(); + //!!! + switchSetupForSlots(switchSetupRequests, serverInterface, 0, + mapInfo.players, false); + switchSetupForSlots(switchSetupRequests, serverInterface, + mapInfo.players, GameConstants::maxPlayers, + true); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + GameSettings gameSettings; + loadGameSettings(&gameSettings); + + listBoxAISwitchTeamAcceptPercent.setEnabled + (checkBoxEnableSwitchTeamMode.getValue()); + + int factionCount = 0; + for (int i = 0; i < mapInfo.players; ++i) { + if (hasNetworkGameSettings() == true) { + if (listBoxControls[i].getSelectedItemIndex() != ctClosed) { + int slotIndex = factionCount; + if (listBoxControls[i].getSelectedItemIndex() == ctHuman) { + switch (gameSettings.getNetworkPlayerStatuses(slotIndex)) { + case npst_BeRightBack: + labelPlayerStatus[i].setTexture(CoreData::getInstance + ().getStatusBRBTexture()); + break; + case npst_Ready: + labelPlayerStatus[i].setTexture(CoreData::getInstance + ().getStatusReadyTexture + ()); + break; + case npst_PickSettings: + labelPlayerStatus[i].setTexture(CoreData::getInstance + ().getStatusNotReadyTexture + ()); + break; + case npst_Disconnected: + labelPlayerStatus[i].setTexture(NULL); + break; + + default: + labelPlayerStatus[i].setTexture(NULL); + break; + } + } else { + labelPlayerStatus[i].setTexture(NULL); + } + + factionCount++; + } else { + labelPlayerStatus[i].setTexture(NULL); + } + } + + if (listBoxControls[i].getSelectedItemIndex() == ctNetwork || + listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned) { + hasOneNetworkSlotOpen = true; + + if (serverInterface->getSlot(i, true) != NULL && + serverInterface->getSlot(i, true)->isConnected()) { + + if (hasNetworkGameSettings() == true) { + switch (serverInterface-> + getSlot(i, true)->getNetworkPlayerStatus()) { + case npst_BeRightBack: + labelPlayerStatus[i].setTexture(CoreData::getInstance + ().getStatusBRBTexture()); + break; + case npst_Ready: + labelPlayerStatus[i].setTexture(CoreData::getInstance + ().getStatusReadyTexture + ()); + break; + case npst_PickSettings: + default: + labelPlayerStatus[i].setTexture(CoreData::getInstance + ().getStatusNotReadyTexture + ()); + break; + } + } + + serverInterface->getSlot(i, + true)->setName(labelPlayerNames[i]. + getText()); + + //printf("FYI we have at least 1 client connected, slot = %d'\n",i); + + //haveAtLeastOneNetworkClientConnected = true; + if (serverInterface->getSlot(i, true) != NULL && + serverInterface->getSlot(i, + true)->getConnectHasHandshaked()) { + currentConnectionCount++; + } + string label = + (serverInterface->getSlot(i, true) != + NULL ? serverInterface->getSlot(i, + true)->getVersionString() : + ""); + + if (serverInterface->getSlot(i, true) != NULL && + serverInterface->getSlot(i, + true)->getAllowDownloadDataSynch + () == true + && serverInterface->getSlot(i, + true)->getAllowGameDataSynchCheck + () == true) { + if (serverInterface->getSlot(i, + true)->getNetworkGameDataSynchCheckOk + () == false) { + label += " -waiting to synch:"; + if (serverInterface->getSlot(i, + true)->getNetworkGameDataSynchCheckOkMap + () == false) { + label = label + " map"; + } + if (serverInterface->getSlot(i, + true)->getNetworkGameDataSynchCheckOkTile + () == false) { + label = label + " tile"; + } + if (serverInterface->getSlot(i, + true)->getNetworkGameDataSynchCheckOkTech + () == false) { + label = label + " techtree"; + } + } else { + label += " - data synch is ok"; + } + } else { + if (serverInterface->getSlot(i, true) != NULL && + serverInterface->getSlot(i, + true)->getAllowGameDataSynchCheck + () == true + && serverInterface->getSlot(i, + true)->getNetworkGameDataSynchCheckOk + () == false) { + label += " -synch mismatch:"; + + if (serverInterface->getSlot(i, true) != NULL + && serverInterface->getSlot(i, + true)->getNetworkGameDataSynchCheckOkMap + () == false) { + label = label + " map"; + + if (serverInterface->getSlot(i, + true)->getReceivedDataSynchCheck + () == true + && lastMapDataSynchError != + "map CRC mismatch, " + listBoxMap.getSelectedItem()) { + lastMapDataSynchError = + "map CRC mismatch, " + listBoxMap.getSelectedItem(); + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + serverInterface->sendTextMessage(lastMapDataSynchError, + -1, true, ""); + } + } + + if (serverInterface->getSlot(i, true) != NULL && + serverInterface->getSlot(i, + true)->getNetworkGameDataSynchCheckOkTile + () == false) { + label = label + " tile"; + + if (serverInterface->getSlot(i, + true)->getReceivedDataSynchCheck + () == true + && lastTileDataSynchError != + "tile CRC mismatch, " + + listBoxTileset.getSelectedItem()) { + lastTileDataSynchError = + "tile CRC mismatch, " + + listBoxTileset.getSelectedItem(); + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + serverInterface->sendTextMessage + (lastTileDataSynchError, -1, true, ""); + } + } + + if (serverInterface->getSlot(i, true) != NULL && + serverInterface->getSlot(i, + true)->getNetworkGameDataSynchCheckOkTech + () == false) { + label = label + " techtree"; + + if (serverInterface->getSlot(i, + true)->getReceivedDataSynchCheck + () == true) { + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + string report = serverInterface->getSlot(i, + true)->getNetworkGameDataSynchCheckTechMismatchReport + (); + + if (lastTechtreeDataSynchError != + "techtree CRC mismatch" + report) { + lastTechtreeDataSynchError = + "techtree CRC mismatch" + report; + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] report: %s\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), + __FUNCTION__, + __LINE__, + report.c_str()); + + serverInterface->sendTextMessage + ("techtree CRC mismatch", -1, true, ""); + vector < string > reportLineTokens; + Tokenize(report, reportLineTokens, "\n"); + for (int reportLine = 0; + reportLine < + (int) reportLineTokens.size(); ++reportLine) { + serverInterface->sendTextMessage + (reportLineTokens[reportLine], -1, true, ""); + } + } + } + } + + if (serverInterface->getSlot(i, true) != NULL) { + serverInterface->getSlot(i, + true)->setReceivedDataSynchCheck + (false); + } + } + } + + //float pingTime = serverInterface->getSlot(i)->getThreadedPingMS(serverInterface->getSlot(i)->getIpAddress().c_str()); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "%s", label.c_str()); + + labelNetStatus[i].setText(szBuf); + } else { + string port = + "(" + intToStr(config.getInt("PortServer")) + ")"; + labelNetStatus[i].setText("--- " + port); + } + } else { + labelNetStatus[i].setText(""); + } + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (checkBoxScenario.getValue() == false) { + // When scenario is checked the value for mapInfo.players is reset to + // hardMaxPlayers. This resets it. + mapInfo.players = checkBoxAllowObservers.getValue() == true ? + GameConstants::maxPlayers : + mapInfo.hardMaxPlayers; + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + if (i >= mapInfo.hardMaxPlayers) { + if (checkBoxAllowObservers.getValue() == false) { + listBoxControls[i].setSelectedItemIndex(ctClosed); + listBoxControls[i].setEditable(false); + listBoxControls[i].setEnabled(false); + } else { + if (listBoxControls[i].getSelectedItemIndex() != ctHuman) { + listBoxControls[i].setSelectedItemIndex(ctNetwork); + } + listBoxControls[i].setEditable(i == GameConstants::maxPlayers - 1); + listBoxControls[i].setEnabled(i == GameConstants::maxPlayers - 1); + listBoxFactions[i].setSelectedItem(GameConstants::OBSERVER_SLOTNAME); + listBoxFactions[i].setEditable(false); + listBoxTeams[i].setSelectedItem(intToStr(GameConstants::maxPlayers + + fpt_Observer)); + listBoxTeams[i].setEditable(false); + } + + listBoxRMultiplier[i].setEditable(false); + listBoxRMultiplier[i].setEnabled(false); + listBoxRMultiplier[i].setVisible(false); + } else if (listBoxControls[i].getSelectedItemIndex() != + ctNetworkUnassigned) { + ConnectionSlot *slot = serverInterface->getSlot(i, true); + if ((listBoxControls[i].getSelectedItemIndex() != + ctNetwork) + || (listBoxControls[i].getSelectedItemIndex() == + ctNetwork && (slot == NULL + || slot->isConnected() == false))) { + listBoxControls[i].setEditable(true); + listBoxControls[i].setEnabled(true); + listBoxFactions[i].setEditable(true); + listBoxTeams[i].setEditable(true); + + if (listBoxControls[i].getSelectedItemIndex() == ctNetwork && + listBoxFactions[i].getSelectedItem() == formatString(GameConstants::OBSERVER_SLOTNAME)) { + listBoxFactions[i].setSelectedItemIndex(0); + } + } else { + listBoxControls[i].setEditable(false); + listBoxControls[i].setEnabled(false); + } + } else { + listBoxControls[i].setEditable(false); + listBoxControls[i].setEnabled(false); + } + } + } else // if this is a scenario... + { + int i = mapInfo.players; + do { + listBoxControls[i].setSelectedItemIndex(ctClosed); + listBoxControls[i].setEditable(false); + listBoxControls[i].setEnabled(false); + } while (++i < GameConstants::maxPlayers); + } + + // updateNetworkSlots (); + + bool checkDataSynch = + (serverInterface->getAllowGameDataSynchCheck() == true + && needToSetChangedGameSettings == true + && + ((difftime((long int) time(NULL), lastSetChangedGameSettings) >= + BROADCAST_SETTINGS_SECONDS) + || (this->headlessServerMode == true))); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + // Send the game settings to each client if we have at least one networked client + if (checkDataSynch == true) { + serverInterface->setGameSettings(&gameSettings, false); + needToSetChangedGameSettings = false; + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (this->headlessServerMode == true || hasOneNetworkSlotOpen == true + || checkBoxAllowInGameJoinPlayer.getValue() == true) { + if (this->headlessServerMode == true && + GlobalStaticFlags::isFlagSet(gsft_lan_mode) == false) { + checkBoxPublishServer.setValue(true); + } + listBoxFallbackCpuMultiplier.setEditable(true); + checkBoxPublishServer.setEditable(true); + + // Masterserver always needs one network slot + if (this->headlessServerMode == true + && hasOneNetworkSlotOpen == false) { + bool anyoneConnected = false; + for (int i = 0; i < mapInfo.players; ++i) { + MutexSafeWrapper + safeMutex((publishToMasterserverThread != + NULL ? + publishToMasterserverThread->getMutexThreadObjectAccessor + () : NULL), + string(__FILE__) + "_" + intToStr(__LINE__)); + + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + ConnectionSlot *slot = serverInterface->getSlot(i, true); + if (slot != NULL && slot->isConnected() == true) { + anyoneConnected = true; + break; + } + } + + for (int i = 0; i < mapInfo.players; ++i) { + if (anyoneConnected == false + && listBoxControls[i].getSelectedItemIndex() != ctNetwork) { + listBoxControls[i].setSelectedItemIndex(ctNetwork); + } + } + + updateNetworkSlots(); + } + } else { + checkBoxPublishServer.setValue(false); + checkBoxPublishServer.setEditable(false); + listBoxFallbackCpuMultiplier.setEditable(false); + listBoxFallbackCpuMultiplier.setSelectedItem("1.0"); + + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + serverInterface-> + setPublishEnabled(checkBoxPublishServer.getValue() == true); + } + + bool republishToMaster = + (difftime((long int) time(NULL), lastMasterserverPublishing) >= + MASTERSERVER_BROADCAST_PUBLISH_SECONDS); + + if (republishToMaster == true) { + if (checkBoxPublishServer.getValue() == true) { + needToRepublishToMasterserver = true; + lastMasterserverPublishing = time(NULL); + } + } + + bool callPublishNow = (checkBoxPublishServer.getEditable() && + checkBoxPublishServer.getValue() == true && + needToRepublishToMasterserver == true); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (callPublishNow == true) { + // give it to me baby, aha aha ... + publishToMasterserver(); + } + if (needToPublishDelayed) { + // this delay is done to make it possible to switch over maps which are not meant to be distributed + if ((difftime((long int) time(NULL), mapPublishingDelayTimer) >= + BROADCAST_MAP_DELAY_SECONDS) + || (this->headlessServerMode == true)) { + // after 5 seconds we are allowed to publish again! + needToSetChangedGameSettings = true; + lastSetChangedGameSettings = time(NULL); + // set to normal.... + needToPublishDelayed = false; + } + } + if (needToPublishDelayed == false || headlessServerMode == true) { + bool broadCastSettings = + (difftime((long int) time(NULL), lastSetChangedGameSettings) + >= BROADCAST_SETTINGS_SECONDS); + + if (headlessServerMode == true) { + // publish settings directly when we receive them + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + if (lastGameSettingsreceivedCount < + serverInterface->getGameSettingsUpdateCount()) { + needToBroadcastServerSettings = true; + lastSetChangedGameSettings = time(NULL); + lastGameSettingsreceivedCount = + serverInterface->getGameSettingsUpdateCount(); + } + } + + if (broadCastSettings == true) { + needToBroadcastServerSettings = true; + lastSetChangedGameSettings = time(NULL); + } + + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + //broadCastSettings = (difftime(time(NULL),lastSetChangedGameSettings) >= 2); + //if (broadCastSettings == true) {// reset timer here on bottom becasue used for different things + // lastSetChangedGameSettings = time(NULL); + //} + } + + if (this->headlessServerMode == true) { + lastPlayerDisconnected(); + } + + //call the chat manager + chatManager.updateNetwork(); + + //console + console.update(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (currentConnectionCount > soundConnectionCount) { + soundConnectionCount = currentConnectionCount; + static PlaySoundClip snd; + SoundRenderer::getInstance(). + playFx(snd.getSound(snd.sfxAttention)); + //switch on music again!! + Config & config = Config::getInstance(); + float configVolume = (config.getInt("SoundVolumeMusic") / 100.f); + CoreData::getInstance().getMenuMusic()->setVolume(configVolume); + } + soundConnectionCount = currentConnectionCount; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (enableFactionTexturePreview == true) { + if (currentTechName_factionPreview != gameSettings.getTech() || + currentFactionName_factionPreview != + gameSettings. + getFactionTypeName(gameSettings.getThisFactionIndex())) { + + currentTechName_factionPreview = gameSettings.getTech(); + currentFactionName_factionPreview = + gameSettings. + getFactionTypeName(gameSettings.getThisFactionIndex()); + + initFactionPreview(&gameSettings); + } + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s Line: %d] took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + chrono.start(); + + if (autostart == true) { + autostart = false; + safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); + if (autoStartSettings != NULL) { + + setupUIFromGameSettings(*autoStartSettings); + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + serverInterface->setGameSettings(autoStartSettings, false); + } else { + RestoreLastGameSettings(); + } + PlayNow((autoStartSettings == NULL)); + return; + } + } catch (megaglest_runtime_error & ex) { + //abort(); + //printf("1111111bbbb ex.wantStackTrace() = %d\n",ex.wantStackTrace()); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + //printf("2222222bbbb ex.wantStackTrace() = %d\n",ex.wantStackTrace()); + + showGeneralError = true; + generalErrorToShow = szBuf; + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + showGeneralError = true; + generalErrorToShow = szBuf; + } + } + + void MenuStateCustomGame::updateControllers() { + try { + bool humanPlayer = false; + + for (int i = 0; i < mapInfo.players; ++i) { + if (listBoxControls[i].getSelectedItemIndex() == ctHuman) { + humanPlayer = true; + } + } + + if (humanPlayer == false) { + if (this->headlessServerMode == false) { + bool foundNewSlotForHuman = false; + for (int i = 0; i < mapInfo.players; ++i) { + if (listBoxControls[i].getSelectedItemIndex() == ctClosed) { + setSlotHuman(i); + foundNewSlotForHuman = true; + break; + } + } + + if (foundNewSlotForHuman == false) { + for (int i = 0; i < mapInfo.players; ++i) { + if (listBoxControls[i].getSelectedItemIndex() == + ctClosed + || listBoxControls[i].getSelectedItemIndex() == + ctCpuEasy + || listBoxControls[i].getSelectedItemIndex() == + ctCpu + || listBoxControls[i].getSelectedItemIndex() == + ctCpuUltra + || listBoxControls[i].getSelectedItemIndex() == + ctCpuZeta) { + setSlotHuman(i); + + foundNewSlotForHuman = true; + break; + } + } + } + + if (foundNewSlotForHuman == false) { + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + ConnectionSlot *slot = serverInterface->getSlot(0, true); + if (slot != NULL && slot->isConnected() == true) { + serverInterface->removeSlot(0); + } + setSlotHuman(0); + } + } + } + + for (int i = mapInfo.players; i < GameConstants::maxPlayers; ++i) { + if (listBoxControls[i].getSelectedItemIndex() != ctNetwork && + listBoxControls[i].getSelectedItemIndex() != + ctNetworkUnassigned) { + //printf("Closed A [%d] [%s]\n",i,labelPlayerNames[i].getText().c_str()); + + listBoxControls[i].setSelectedItemIndex(ctClosed); + } + } + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + } + + void MenuStateCustomGame::updateNetworkSlots() { + try { + ServerInterface *serverInterface = + NetworkManager::getInstance().getServerInterface(); + + if (hasNetworkGameSettings() == true) { + if (hasCheckedForUPNP == false) { + + if (checkBoxPublishServer.getValue() == true || + this->headlessServerMode == true) { + + hasCheckedForUPNP = true; + serverInterface->getServerSocket()->NETdiscoverUPnPDevices(); + } + } + } else { + hasCheckedForUPNP = false; + } + + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + ConnectionSlot *slot = serverInterface->getSlot(i, true); + //printf("A i = %d control type = %d slot [%p]\n",i,listBoxControls[i].getSelectedItemIndex(),slot); + + if (slot == NULL && + listBoxControls[i].getSelectedItemIndex() == ctNetwork) { + try { + serverInterface->addSlot(i); + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", + szBuf); + showGeneralError = true; + if (serverInterface->isPortBound() == false) { + generalErrorToShow = + Lang::getInstance().getString("ErrorBindingPort") + + " : " + intToStr(serverInterface->getBindPort()); + } else { + generalErrorToShow = ex.what(); + } + + // Revert network to CPU + listBoxControls[i].setSelectedItemIndex(ctCpu); + } + } + slot = serverInterface->getSlot(i, true); + if (slot != NULL) { + if ((listBoxControls[i].getSelectedItemIndex() != ctNetwork) + || (listBoxControls[i].getSelectedItemIndex() == + ctNetwork && slot->isConnected() == false + && i >= mapInfo.players)) { + if (slot->getCanAcceptConnections() == true) { + slot->setCanAcceptConnections(false); + } + if (slot->isConnected() == true) { + if (listBoxControls[i].getSelectedItemIndex() != + ctNetworkUnassigned) { + listBoxControls[i].setSelectedItemIndex + (ctNetworkUnassigned); + } + } else { + serverInterface->removeSlot(i); + + if (listBoxControls[i].getSelectedItemIndex() == + ctNetworkUnassigned) { + listBoxControls[i].setSelectedItemIndex(ctClosed); + } + } + } else if (slot->getCanAcceptConnections() == false) { + slot->setCanAcceptConnections(true); + } + } + } + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d]\nError detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + //throw megaglest_runtime_error(szBuf); + showGeneralError = true; + generalErrorToShow = szBuf; + + } + } + + void MenuStateCustomGame::updateAllResourceMultiplier() { + for (int j = 0; j < GameConstants::maxPlayers; ++j) { + updateResourceMultiplier(j); + } + } + + void MenuStateCustomGame::updateResourceMultiplier(const int index) { + //printf("Line: %d multiplier index: %d index: %d\n",__LINE__,listBoxRMultiplier[index].getSelectedItemIndex(),index); + + ControlType ct = + static_cast + (listBoxControls[index].getSelectedItemIndex()); + if (ct == ctCpuEasy || ct == ctNetworkCpuEasy) { + listBoxRMultiplier[index].setSelectedItem(floatToStr + (GameConstants:: + easyMultiplier, 1)); + listBoxRMultiplier[index].setEnabled(checkBoxScenario.getValue() == + false); + } else if (ct == ctCpu || ct == ctNetworkCpu) { + listBoxRMultiplier[index].setSelectedItem(floatToStr + (GameConstants:: + normalMultiplier, 1)); + listBoxRMultiplier[index].setEnabled(checkBoxScenario.getValue() == + false); + } else if (ct == ctCpuUltra || ct == ctNetworkCpuUltra) { + listBoxRMultiplier[index].setSelectedItem(floatToStr + (GameConstants:: + ultraMultiplier, 1)); + listBoxRMultiplier[index].setEnabled(checkBoxScenario.getValue() == + false); + } else if (ct == ctCpuZeta || ct == ctNetworkCpuZeta) { + listBoxRMultiplier[index].setSelectedItem(floatToStr + (GameConstants:: + megaMultiplier, 1)); + listBoxRMultiplier[index].setEnabled(checkBoxScenario.getValue() == + false); + } + //if(ct == ctHuman || ct == ctNetwork || ct == ctClosed) { + else { + listBoxRMultiplier[index].setSelectedItem(floatToStr + (GameConstants:: + normalMultiplier, 1)); + listBoxRMultiplier[index].setEnabled(false); + //!!!listBoxRMultiplier[index].setEnabled(checkBoxScenario.getValue() == false); + } + + listBoxRMultiplier[index]. + setEditable(listBoxRMultiplier[index].getEnabled()); + listBoxRMultiplier[index].setVisible(ct != ctHuman && ct != ctNetwork + && ct != ctClosed); + //listBoxRMultiplier[index].setVisible(ct != ctClosed); + + //printf("Line: %d multiplier index: %d index: %d\n",__LINE__,listBoxRMultiplier[index].getSelectedItemIndex(),index); + } + } // end namespace } diff --git a/source/glest_game/menu/menu_state_graphic_info.cpp b/source/glest_game/menu/menu_state_graphic_info.cpp index b59e920be..262266f00 100644 --- a/source/glest_game/menu/menu_state_graphic_info.cpp +++ b/source/glest_game/menu/menu_state_graphic_info.cpp @@ -19,192 +19,180 @@ #include "opengl.h" #include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class MenuStateGraphicInfo -// ===================================================== + // ===================================================== + // class MenuStateGraphicInfo + // ===================================================== - MenuStateGraphicInfo::MenuStateGraphicInfo (Program * program, - MainMenu * - mainMenu):MenuState (program, - mainMenu, - "info") - { - Lang & lang = Lang::getInstance (); + MenuStateGraphicInfo::MenuStateGraphicInfo(Program * program, + MainMenu * + mainMenu) :MenuState(program, + mainMenu, + "info") { + Lang & lang = Lang::getInstance(); - containerName = "GraphicInfo"; - buttonReturn.registerGraphicComponent (containerName, "buttonReturn"); - buttonReturn.init (650, 575, 125); + containerName = "GraphicInfo"; + buttonReturn.registerGraphicComponent(containerName, "buttonReturn"); + buttonReturn.init(650, 575, 125); - buttonReturn.setText (lang.getString ("Return")); + buttonReturn.setText(lang.getString("Return")); - labelInfo.registerGraphicComponent (containerName, "labelInfo"); - labelInfo.init (0, 730); + labelInfo.registerGraphicComponent(containerName, "labelInfo"); + labelInfo.init(0, 730); - labelMoreInfo.registerGraphicComponent (containerName, "labelMoreInfo"); - labelMoreInfo.init (0, 555); - labelMoreInfo.setFont (CoreData::getInstance ().getDisplayFontSmall ()); - labelMoreInfo.setFont3D (CoreData::getInstance (). - getDisplayFontSmall3D ()); + labelMoreInfo.registerGraphicComponent(containerName, "labelMoreInfo"); + labelMoreInfo.init(0, 555); + labelMoreInfo.setFont(CoreData::getInstance().getDisplayFontSmall()); + labelMoreInfo.setFont3D(CoreData::getInstance(). + getDisplayFontSmall3D()); - labelInternalInfo.registerGraphicComponent (containerName, - "labelInternalInfo"); - labelInternalInfo.init (300, 730); - labelInternalInfo.setFont (CoreData::getInstance (). - getDisplayFontSmall ()); - labelInternalInfo.setFont3D (CoreData::getInstance (). - getDisplayFontSmall3D ()); + labelInternalInfo.registerGraphicComponent(containerName, + "labelInternalInfo"); + labelInternalInfo.init(300, 730); + labelInternalInfo.setFont(CoreData::getInstance(). + getDisplayFontSmall()); + labelInternalInfo.setFont3D(CoreData::getInstance(). + getDisplayFontSmall3D()); - GraphicComponent::applyAllCustomProperties (containerName); + GraphicComponent::applyAllCustomProperties(containerName); - Renderer & renderer = Renderer::getInstance (); + Renderer & renderer = Renderer::getInstance(); - string glInfo = renderer.getGlInfo (); - string glMoreInfo = renderer.getGlMoreInfo (); - labelInfo.setText (glInfo); - labelMoreInfo.setText (glMoreInfo); + string glInfo = renderer.getGlInfo(); + string glMoreInfo = renderer.getGlMoreInfo(); + labelInfo.setText(glInfo); + labelMoreInfo.setText(glMoreInfo); - string strInternalInfo = ""; - strInternalInfo += "VBOSupported: " + boolToStr (getVBOSupported ()); - if (getenv ("MEGAGLEST_FONT") != NULL) - { - char *tryFont = getenv ("MEGAGLEST_FONT"); - strInternalInfo += "\nMEGAGLEST_FONT: " + string (tryFont); - } - strInternalInfo += - "\nforceLegacyFonts: " + boolToStr (Font::forceLegacyFonts); - strInternalInfo += - "\nrenderText3DEnabled: " + boolToStr (Renderer::renderText3DEnabled); - strInternalInfo += - "\nuseTextureCompression: " + - boolToStr (Texture::useTextureCompression); - strInternalInfo += - "\nfontIsRightToLeft: " + boolToStr (Font::fontIsRightToLeft); - strInternalInfo += - "\nscaleFontValue: " + floatToStr (Font::scaleFontValue); - strInternalInfo += - "\nscaleFontValueCenterHFactor: " + - floatToStr (Font::scaleFontValueCenterHFactor); - strInternalInfo += "\nlangHeightText: " + Font::langHeightText; - strInternalInfo += - "\nAllowAltEnterFullscreenToggle: " + - boolToStr (Window::getAllowAltEnterFullscreenToggle ()); - strInternalInfo += - "\nTryVSynch: " + boolToStr (Window::getTryVSynch ()); - strInternalInfo += - "\nVERBOSE_MODE_ENABLED: " + - boolToStr (SystemFlags::VERBOSE_MODE_ENABLED); - labelInternalInfo.setText (strInternalInfo); - } + string strInternalInfo = ""; + strInternalInfo += "VBOSupported: " + boolToStr(getVBOSupported()); + if (getenv("MEGAGLEST_FONT") != NULL) { + char *tryFont = getenv("MEGAGLEST_FONT"); + strInternalInfo += "\nMEGAGLEST_FONT: " + string(tryFont); + } + strInternalInfo += + "\nforceLegacyFonts: " + boolToStr(Font::forceLegacyFonts); + strInternalInfo += + "\nrenderText3DEnabled: " + boolToStr(Renderer::renderText3DEnabled); + strInternalInfo += + "\nuseTextureCompression: " + + boolToStr(Texture::useTextureCompression); + strInternalInfo += + "\nfontIsRightToLeft: " + boolToStr(Font::fontIsRightToLeft); + strInternalInfo += + "\nscaleFontValue: " + floatToStr(Font::scaleFontValue); + strInternalInfo += + "\nscaleFontValueCenterHFactor: " + + floatToStr(Font::scaleFontValueCenterHFactor); + strInternalInfo += "\nlangHeightText: " + Font::langHeightText; + strInternalInfo += + "\nAllowAltEnterFullscreenToggle: " + + boolToStr(Window::getAllowAltEnterFullscreenToggle()); + strInternalInfo += + "\nTryVSynch: " + boolToStr(Window::getTryVSynch()); + strInternalInfo += + "\nVERBOSE_MODE_ENABLED: " + + boolToStr(SystemFlags::VERBOSE_MODE_ENABLED); + labelInternalInfo.setText(strInternalInfo); + } - void MenuStateGraphicInfo::reloadUI () - { - Lang & lang = Lang::getInstance (); + void MenuStateGraphicInfo::reloadUI() { + Lang & lang = Lang::getInstance(); - console.resetFonts (); - buttonReturn.setText (lang.getString ("Return")); + console.resetFonts(); + buttonReturn.setText(lang.getString("Return")); - labelMoreInfo.setFont (CoreData::getInstance ().getDisplayFontSmall ()); - labelMoreInfo.setFont3D (CoreData::getInstance (). - getDisplayFontSmall3D ()); + labelMoreInfo.setFont(CoreData::getInstance().getDisplayFontSmall()); + labelMoreInfo.setFont3D(CoreData::getInstance(). + getDisplayFontSmall3D()); - labelInternalInfo.setFont (CoreData::getInstance (). - getDisplayFontSmall ()); - labelInternalInfo.setFont3D (CoreData::getInstance (). - getDisplayFontSmall3D ()); + labelInternalInfo.setFont(CoreData::getInstance(). + getDisplayFontSmall()); + labelInternalInfo.setFont3D(CoreData::getInstance(). + getDisplayFontSmall3D()); - Renderer & renderer = Renderer::getInstance (); + Renderer & renderer = Renderer::getInstance(); - string glInfo = renderer.getGlInfo (); - string glMoreInfo = renderer.getGlMoreInfo (); - labelInfo.setText (glInfo); - labelMoreInfo.setText (glMoreInfo); + string glInfo = renderer.getGlInfo(); + string glMoreInfo = renderer.getGlMoreInfo(); + labelInfo.setText(glInfo); + labelMoreInfo.setText(glMoreInfo); - string strInternalInfo = ""; - strInternalInfo += "VBOSupported: " + boolToStr (getVBOSupported ()); - if (getenv ("MEGAGLEST_FONT") != NULL) - { - char *tryFont = getenv ("MEGAGLEST_FONT"); - strInternalInfo += "\nMEGAGLEST_FONT: " + string (tryFont); - } - strInternalInfo += - "\nforceLegacyFonts: " + boolToStr (Font::forceLegacyFonts); - strInternalInfo += - "\nrenderText3DEnabled: " + boolToStr (Renderer::renderText3DEnabled); - strInternalInfo += - "\nuseTextureCompression: " + - boolToStr (Texture::useTextureCompression); - strInternalInfo += - "\nfontIsRightToLeft: " + boolToStr (Font::fontIsRightToLeft); - strInternalInfo += - "\nscaleFontValue: " + floatToStr (Font::scaleFontValue); - strInternalInfo += - "\nscaleFontValueCenterHFactor: " + - floatToStr (Font::scaleFontValueCenterHFactor); - strInternalInfo += "\nlangHeightText: " + Font::langHeightText; - strInternalInfo += - "\nAllowAltEnterFullscreenToggle: " + - boolToStr (Window::getAllowAltEnterFullscreenToggle ()); - strInternalInfo += - "\nTryVSynch: " + boolToStr (Window::getTryVSynch ()); - strInternalInfo += - "\nVERBOSE_MODE_ENABLED: " + - boolToStr (SystemFlags::VERBOSE_MODE_ENABLED); - labelInternalInfo.setText (strInternalInfo); + string strInternalInfo = ""; + strInternalInfo += "VBOSupported: " + boolToStr(getVBOSupported()); + if (getenv("MEGAGLEST_FONT") != NULL) { + char *tryFont = getenv("MEGAGLEST_FONT"); + strInternalInfo += "\nMEGAGLEST_FONT: " + string(tryFont); + } + strInternalInfo += + "\nforceLegacyFonts: " + boolToStr(Font::forceLegacyFonts); + strInternalInfo += + "\nrenderText3DEnabled: " + boolToStr(Renderer::renderText3DEnabled); + strInternalInfo += + "\nuseTextureCompression: " + + boolToStr(Texture::useTextureCompression); + strInternalInfo += + "\nfontIsRightToLeft: " + boolToStr(Font::fontIsRightToLeft); + strInternalInfo += + "\nscaleFontValue: " + floatToStr(Font::scaleFontValue); + strInternalInfo += + "\nscaleFontValueCenterHFactor: " + + floatToStr(Font::scaleFontValueCenterHFactor); + strInternalInfo += "\nlangHeightText: " + Font::langHeightText; + strInternalInfo += + "\nAllowAltEnterFullscreenToggle: " + + boolToStr(Window::getAllowAltEnterFullscreenToggle()); + strInternalInfo += + "\nTryVSynch: " + boolToStr(Window::getTryVSynch()); + strInternalInfo += + "\nVERBOSE_MODE_ENABLED: " + + boolToStr(SystemFlags::VERBOSE_MODE_ENABLED); + labelInternalInfo.setText(strInternalInfo); - GraphicComponent:: - reloadFontsForRegisterGraphicComponents (containerName); - } + GraphicComponent:: + reloadFontsForRegisterGraphicComponents(containerName); + } - void MenuStateGraphicInfo::mouseClick (int x, int y, - MouseButton mouseButton) - { - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); + void MenuStateGraphicInfo::mouseClick(int x, int y, + MouseButton mouseButton) { + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); - if (buttonReturn.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptionsGraphics (program, mainMenu)); - } - } + if (buttonReturn.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptionsGraphics(program, mainMenu)); + } + } - void MenuStateGraphicInfo::mouseMove (int x, int y, const MouseState * ms) - { - buttonReturn.mouseMove (x, y); - } + void MenuStateGraphicInfo::mouseMove(int x, int y, const MouseState * ms) { + buttonReturn.mouseMove(x, y); + } - void MenuStateGraphicInfo::render () - { + void MenuStateGraphicInfo::render() { - Renderer & renderer = Renderer::getInstance (); - //Lang &lang= Lang::getInstance(); + Renderer & renderer = Renderer::getInstance(); + //Lang &lang= Lang::getInstance(); - renderer.renderButton (&buttonReturn); - renderer.renderLabel (&labelInfo); - renderer.renderLabel (&labelInternalInfo); - renderer.renderLabel (&labelMoreInfo); + renderer.renderButton(&buttonReturn); + renderer.renderLabel(&labelInfo); + renderer.renderLabel(&labelInternalInfo); + renderer.renderLabel(&labelMoreInfo); - renderer.renderConsole (&console); - } + renderer.renderConsole(&console); + } - void MenuStateGraphicInfo::keyDown (SDL_KeyboardEvent key) - { - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - //if(key == configKeys.getCharKey("SaveGUILayout")) { - if (isKeyPressed (configKeys.getSDLKey ("SaveGUILayout"), key) == true) - { - GraphicComponent::saveAllCustomProperties (containerName); - //Lang &lang= Lang::getInstance(); - //console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ? lang.getString("Yes") : lang.getString("No"))+ "]"); - } - } + void MenuStateGraphicInfo::keyDown(SDL_KeyboardEvent key) { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + //if(key == configKeys.getCharKey("SaveGUILayout")) { + if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), key) == true) { + GraphicComponent::saveAllCustomProperties(containerName); + //Lang &lang= Lang::getInstance(); + //console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ? lang.getString("Yes") : lang.getString("No"))+ "]"); + } + } - } + } } //end namespace diff --git a/source/glest_game/menu/menu_state_graphic_info.h b/source/glest_game/menu/menu_state_graphic_info.h index 03bff0048..8a3f2430a 100644 --- a/source/glest_game/menu/menu_state_graphic_info.h +++ b/source/glest_game/menu/menu_state_graphic_info.h @@ -16,54 +16,52 @@ # include "leak_dumper.h" using namespace - Shared::Graphics::Gl; +Shared::Graphics::Gl; namespace - Glest -{ - namespace - Game - { + Glest { + namespace + Game { -// =============================== -// class MenuStateGraphicInfo -// =============================== + // =============================== + // class MenuStateGraphicInfo + // =============================== - class - MenuStateGraphicInfo: - public - MenuState - { - private: - GraphicButton - buttonReturn; - GraphicLabel - labelInfo; - GraphicLabel - labelMoreInfo; + class + MenuStateGraphicInfo : + public + MenuState { + private: + GraphicButton + buttonReturn; + GraphicLabel + labelInfo; + GraphicLabel + labelMoreInfo; - GraphicLabel - labelInternalInfo; + GraphicLabel + labelInternalInfo; - //string glInfo; - //string glMoreInfo; + //string glInfo; + //string glMoreInfo; - public: - MenuStateGraphicInfo (Program * program, MainMenu * mainMenu); + public: + MenuStateGraphicInfo(Program * program, MainMenu * mainMenu); - void - mouseClick (int x, int y, MouseButton mouseButton); - void - mouseMove (int x, int y, const MouseState * mouseState); - void - render (); - virtual void - keyDown (SDL_KeyboardEvent key); + void + mouseClick(int x, int y, MouseButton mouseButton); + void + mouseMove(int x, int y, const MouseState * mouseState); + void + render(); + virtual void + keyDown(SDL_KeyboardEvent key); - virtual void - reloadUI (); - }; + virtual void + reloadUI(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/menu/menu_state_join_game.cpp b/source/glest_game/menu/menu_state_join_game.cpp index a1d098022..5a83cc4e1 100644 --- a/source/glest_game/menu/menu_state_join_game.cpp +++ b/source/glest_game/menu/menu_state_join_game.cpp @@ -36,1093 +36,951 @@ #include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - using namespace::Shared::Util; + using namespace::Shared::Util; -// =============================== -// class MenuStateJoinGame -// =============================== + // =============================== + // class MenuStateJoinGame + // =============================== - const int MenuStateJoinGame::newServerIndex = 0; - const int MenuStateJoinGame::newPrevServerIndex = 1; - const int MenuStateJoinGame::foundServersIndex = 2; + const int MenuStateJoinGame::newServerIndex = 0; + const int MenuStateJoinGame::newPrevServerIndex = 1; + const int MenuStateJoinGame::foundServersIndex = 2; - const string MenuStateJoinGame::serverFileName = "servers.ini"; + const string MenuStateJoinGame::serverFileName = "servers.ini"; - MenuStateJoinGame::MenuStateJoinGame (Program * program, - MainMenu * mainMenu, - bool * - autoFindHost):MenuState (program, - mainMenu, - "join-game") - { - CommonInit (false, Ip (), -1); + MenuStateJoinGame::MenuStateJoinGame(Program * program, + MainMenu * mainMenu, + bool * + autoFindHost) :MenuState(program, + mainMenu, + "join-game") { + CommonInit(false, Ip(), -1); - if (autoFindHost != NULL && *autoFindHost == true) - { -//if(clientInterface->isConnected() == false) { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + if (autoFindHost != NULL && *autoFindHost == true) { + //if(clientInterface->isConnected() == false) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - buttonAutoFindServers.setEnabled (false); - buttonConnect.setEnabled (false); + buttonAutoFindServers.setEnabled(false); + buttonConnect.setEnabled(false); - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface *clientInterface = - networkManager.getClientInterface (); - clientInterface->discoverServers (this); -//} - } - } - MenuStateJoinGame::MenuStateJoinGame (Program * program, - MainMenu * mainMenu, bool connect, - Ip serverIp, - int - portNumberOverride):MenuState - (program, mainMenu, "join-game") - { - CommonInit (connect, serverIp, portNumberOverride); - } + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface *clientInterface = + networkManager.getClientInterface(); + clientInterface->discoverServers(this); + //} + } + } + MenuStateJoinGame::MenuStateJoinGame(Program * program, + MainMenu * mainMenu, bool connect, + Ip serverIp, + int + portNumberOverride) :MenuState + (program, mainMenu, "join-game") { + CommonInit(connect, serverIp, portNumberOverride); + } - void MenuStateJoinGame::CommonInit (bool connect, Ip serverIp, - int portNumberOverride) - { - containerName = "JoinGame"; - abortAutoFind = false; - autoConnectToServer = false; - Lang & lang = Lang::getInstance (); - Config & config = Config::getInstance (); - NetworkManager & networkManager = NetworkManager::getInstance (); - networkManager.end (); - networkManager.init (nrClient); + void MenuStateJoinGame::CommonInit(bool connect, Ip serverIp, + int portNumberOverride) { + containerName = "JoinGame"; + abortAutoFind = false; + autoConnectToServer = false; + Lang & lang = Lang::getInstance(); + Config & config = Config::getInstance(); + NetworkManager & networkManager = NetworkManager::getInstance(); + networkManager.end(); + networkManager.init(nrClient); - serversSavedFile = serverFileName; + serversSavedFile = serverFileName; - string serverListPath = config.getString ("ServerListPath", ""); - if (serverListPath != "") - { - endPathWithSlash (serverListPath); - } + string serverListPath = config.getString("ServerListPath", ""); + if (serverListPath != "") { + endPathWithSlash(serverListPath); + } - string userData = config.getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - serversSavedFile = userData + serversSavedFile; + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + serversSavedFile = userData + serversSavedFile; - if (fileExists (serversSavedFile) == true) - { - servers.load (serversSavedFile); - } - else if (fileExists (serverListPath + serverFileName) == true) - { - servers.load (serverListPath + serverFileName); - } - else if (fileExists (Properties::getApplicationPath () + serverFileName) - == true) - { - servers.load (Properties::getApplicationPath () + serverFileName); - } - else if (fileExists (serverFileName) == true) - { - servers.load (serverFileName); - } + if (fileExists(serversSavedFile) == true) { + servers.load(serversSavedFile); + } else if (fileExists(serverListPath + serverFileName) == true) { + servers.load(serverListPath + serverFileName); + } else if (fileExists(Properties::getApplicationPath() + serverFileName) + == true) { + servers.load(Properties::getApplicationPath() + serverFileName); + } else if (fileExists(serverFileName) == true) { + servers.load(serverFileName); + } -//buttons - buttonReturn.registerGraphicComponent (containerName, "buttonReturn"); - buttonReturn.init (250, 300, 150); - buttonReturn.setText (lang.getString ("Return")); + //buttons + buttonReturn.registerGraphicComponent(containerName, "buttonReturn"); + buttonReturn.init(250, 300, 150); + buttonReturn.setText(lang.getString("Return")); - buttonConnect.registerGraphicComponent (containerName, "buttonConnect"); - buttonConnect.init (425, 300, 150); - buttonConnect.setText (lang.getString ("Connect")); + buttonConnect.registerGraphicComponent(containerName, "buttonConnect"); + buttonConnect.init(425, 300, 150); + buttonConnect.setText(lang.getString("Connect")); - buttonCreateGame.registerGraphicComponent (containerName, - "buttonCreateGame"); - buttonCreateGame.init (600, 300, 150); - buttonCreateGame.setText (lang.getString ("HostGame")); + buttonCreateGame.registerGraphicComponent(containerName, + "buttonCreateGame"); + buttonCreateGame.init(600, 300, 150); + buttonCreateGame.setText(lang.getString("HostGame")); - buttonAutoFindServers.registerGraphicComponent (containerName, - "buttonAutoFindServers"); - buttonAutoFindServers.init (360, 250, 280); - buttonAutoFindServers.setText (lang.getString ("FindLANGames")); - buttonAutoFindServers.setEnabled (true); + buttonAutoFindServers.registerGraphicComponent(containerName, + "buttonAutoFindServers"); + buttonAutoFindServers.init(360, 250, 280); + buttonAutoFindServers.setText(lang.getString("FindLANGames")); + buttonAutoFindServers.setEnabled(true); - int labelXleft = 300; - int labelXright = 480; + int labelXleft = 300; + int labelXright = 480; -//server type label - labelServerType.registerGraphicComponent (containerName, - "labelServerType"); - labelServerType.init (labelXleft, 490); - labelServerType.setText (lang.getString ("ServerType")); + //server type label + labelServerType.registerGraphicComponent(containerName, + "labelServerType"); + labelServerType.init(labelXleft, 490); + labelServerType.setText(lang.getString("ServerType")); -//server type list box - listBoxServerType.registerGraphicComponent (containerName, - "listBoxServerType"); - listBoxServerType.init (labelXright, 490, 210); - listBoxServerType.pushBackItem (lang.getString ("ServerTypeNew")); - listBoxServerType.pushBackItem (lang.getString ("ServerTypePrevious")); - listBoxServerType.pushBackItem (lang.getString ("ServerTypeFound")); + //server type list box + listBoxServerType.registerGraphicComponent(containerName, + "listBoxServerType"); + listBoxServerType.init(labelXright, 490, 210); + listBoxServerType.pushBackItem(lang.getString("ServerTypeNew")); + listBoxServerType.pushBackItem(lang.getString("ServerTypePrevious")); + listBoxServerType.pushBackItem(lang.getString("ServerTypeFound")); -//server label - labelServer.registerGraphicComponent (containerName, "labelServer"); - labelServer.init (labelXleft, 460); - labelServer.setText (lang.getString ("Server")); + //server label + labelServer.registerGraphicComponent(containerName, "labelServer"); + labelServer.init(labelXleft, 460); + labelServer.setText(lang.getString("Server")); -//server listbox - listBoxServers.registerGraphicComponent (containerName, - "listBoxServers"); - listBoxServers.init (labelXright, 460, 210); - for (int i = 0; i < servers.getPropertyCount (); ++i) - { - listBoxServers.pushBackItem (servers.getKey (i)); - } + //server listbox + listBoxServers.registerGraphicComponent(containerName, + "listBoxServers"); + listBoxServers.init(labelXright, 460, 210); + for (int i = 0; i < servers.getPropertyCount(); ++i) { + listBoxServers.pushBackItem(servers.getKey(i)); + } -// found servers listbox - listBoxFoundServers.registerGraphicComponent (containerName, - "listBoxFoundServers"); - listBoxFoundServers.init (labelXright, 460, 210); + // found servers listbox + listBoxFoundServers.registerGraphicComponent(containerName, + "listBoxFoundServers"); + listBoxFoundServers.init(labelXright, 460, 210); -//server ip - labelServerIp.registerGraphicComponent (containerName, "labelServerIp"); - labelServerIp.setEditable (true); - labelServerIp.setMaxEditWidth (26); - labelServerIp.setMaxEditRenderWidth (210); - labelServerIp.init (labelXright, 460); + //server ip + labelServerIp.registerGraphicComponent(containerName, "labelServerIp"); + labelServerIp.setEditable(true); + labelServerIp.setMaxEditWidth(26); + labelServerIp.setMaxEditRenderWidth(210); + labelServerIp.init(labelXright, 460); -// server port - labelServerPortLabel.registerGraphicComponent (containerName, - "labelServerPortLabel"); - labelServerPortLabel.init (labelXleft, 430); - labelServerPortLabel.setText (lang.getString ("ServerPort")); + // server port + labelServerPortLabel.registerGraphicComponent(containerName, + "labelServerPortLabel"); + labelServerPortLabel.init(labelXleft, 430); + labelServerPortLabel.setText(lang.getString("ServerPort")); - labelServerPort.registerGraphicComponent (containerName, - "labelServerPort"); - labelServerPort.init (labelXright, 430); + labelServerPort.registerGraphicComponent(containerName, + "labelServerPort"); + labelServerPort.init(labelXright, 430); - string host = labelServerIp.getText (); - int portNumber = config.getInt ("PortServer", - intToStr (GameConstants::serverPort). - c_str ()); - std::vector < std::string > hostPartsList; - Tokenize (host, hostPartsList, ":"); - if (hostPartsList.size () > 1) - { - host = hostPartsList[0]; - replaceAll (hostPartsList[1], "_", ""); - portNumber = strToInt (hostPartsList[1]); - } + string host = labelServerIp.getText(); + int portNumber = config.getInt("PortServer", + intToStr(GameConstants::serverPort). + c_str()); + std::vector < std::string > hostPartsList; + Tokenize(host, hostPartsList, ":"); + if (hostPartsList.size() > 1) { + host = hostPartsList[0]; + replaceAll(hostPartsList[1], "_", ""); + portNumber = strToInt(hostPartsList[1]); + } - string port = " (" + intToStr (portNumber) + ")"; - labelServerPort.setText (port); + string port = " (" + intToStr(portNumber) + ")"; + labelServerPort.setText(port); - labelStatus.registerGraphicComponent (containerName, "labelStatus"); - labelStatus.init (labelXleft, 400); - labelStatus.setText (""); + labelStatus.registerGraphicComponent(containerName, "labelStatus"); + labelStatus.init(labelXleft, 400); + labelStatus.setText(""); - labelInfo.registerGraphicComponent (containerName, "labelInfo"); - labelInfo.init (labelXleft, 370); - labelInfo.setText (""); + labelInfo.registerGraphicComponent(containerName, "labelInfo"); + labelInfo.init(labelXleft, 370); + labelInfo.setText(""); - connected = false; - playerIndex = -1; + connected = false; + playerIndex = -1; -//server ip - if (connect == true) - { - string hostIP = serverIp.getString (); - if (portNumberOverride > 0) - { - hostIP += ":" + intToStr (portNumberOverride); - } + //server ip + if (connect == true) { + string hostIP = serverIp.getString(); + if (portNumberOverride > 0) { + hostIP += ":" + intToStr(portNumberOverride); + } - labelServerIp.setText (hostIP + "_"); + labelServerIp.setText(hostIP + "_"); - autoConnectToServer = true; - } - else - { - string hostIP = config.getString ("ServerIp"); - if (portNumberOverride > 0) - { - hostIP += ":" + intToStr (portNumberOverride); - } + autoConnectToServer = true; + } else { + string hostIP = config.getString("ServerIp"); + if (portNumberOverride > 0) { + hostIP += ":" + intToStr(portNumberOverride); + } - labelServerIp.setText (hostIP + "_"); - } + labelServerIp.setText(hostIP + "_"); + } - host = labelServerIp.getText (); - portNumber = - config.getInt ("PortServer", - intToStr (GameConstants::serverPort).c_str ()); - hostPartsList.clear (); - Tokenize (host, hostPartsList, ":"); - if (hostPartsList.size () > 1) - { - host = hostPartsList[0]; - replaceAll (hostPartsList[1], "_", ""); - portNumber = strToInt (hostPartsList[1]); - } + host = labelServerIp.getText(); + portNumber = + config.getInt("PortServer", + intToStr(GameConstants::serverPort).c_str()); + hostPartsList.clear(); + Tokenize(host, hostPartsList, ":"); + if (hostPartsList.size() > 1) { + host = hostPartsList[0]; + replaceAll(hostPartsList[1], "_", ""); + portNumber = strToInt(hostPartsList[1]); + } - port = " (" + intToStr (portNumber) + ")"; - labelServerPort.setText (port); + port = " (" + intToStr(portNumber) + ")"; + labelServerPort.setText(port); - GraphicComponent::applyAllCustomProperties (containerName); + GraphicComponent::applyAllCustomProperties(containerName); - chatManager.init (&console, -1); - } + chatManager.init(&console, -1); + } - void MenuStateJoinGame::reloadUI () - { - Lang & lang = Lang::getInstance (); - Config & config = Config::getInstance (); + void MenuStateJoinGame::reloadUI() { + Lang & lang = Lang::getInstance(); + Config & config = Config::getInstance(); - console.resetFonts (); + console.resetFonts(); - buttonReturn.setText (lang.getString ("Return")); - buttonConnect.setText (lang.getString ("Connect")); - buttonCreateGame.setText (lang.getString ("HostGame")); - buttonAutoFindServers.setText (lang.getString ("FindLANGames")); - labelServerType.setText (lang.getString ("ServerType")); + buttonReturn.setText(lang.getString("Return")); + buttonConnect.setText(lang.getString("Connect")); + buttonCreateGame.setText(lang.getString("HostGame")); + buttonAutoFindServers.setText(lang.getString("FindLANGames")); + labelServerType.setText(lang.getString("ServerType")); - std::vector < string > listboxData; - listboxData.push_back (lang.getString ("ServerTypeNew")); - listboxData.push_back (lang.getString ("ServerTypePrevious")); - listboxData.push_back (lang.getString ("ServerTypeFound")); - listBoxServerType.setItems (listboxData); + std::vector < string > listboxData; + listboxData.push_back(lang.getString("ServerTypeNew")); + listboxData.push_back(lang.getString("ServerTypePrevious")); + listboxData.push_back(lang.getString("ServerTypeFound")); + listBoxServerType.setItems(listboxData); - labelServer.setText (lang.getString ("Server")); + labelServer.setText(lang.getString("Server")); - labelServerPortLabel.setText (lang.getString ("ServerPort")); + labelServerPortLabel.setText(lang.getString("ServerPort")); - string host = labelServerIp.getText (); - int portNumber = config.getInt ("PortServer", - intToStr (GameConstants::serverPort). - c_str ()); - std::vector < std::string > hostPartsList; - Tokenize (host, hostPartsList, ":"); - if (hostPartsList.size () > 1) - { - host = hostPartsList[0]; - replaceAll (hostPartsList[1], "_", ""); - portNumber = strToInt (hostPartsList[1]); - } + string host = labelServerIp.getText(); + int portNumber = config.getInt("PortServer", + intToStr(GameConstants::serverPort). + c_str()); + std::vector < std::string > hostPartsList; + Tokenize(host, hostPartsList, ":"); + if (hostPartsList.size() > 1) { + host = hostPartsList[0]; + replaceAll(hostPartsList[1], "_", ""); + portNumber = strToInt(hostPartsList[1]); + } - string port = " (" + intToStr (portNumber) + ")"; - labelServerPort.setText (port); + string port = " (" + intToStr(portNumber) + ")"; + labelServerPort.setText(port); - chatManager.init (&console, -1); + chatManager.init(&console, -1); - GraphicComponent::reloadFontsForRegisterGraphicComponents - (containerName); - } + GraphicComponent::reloadFontsForRegisterGraphicComponents + (containerName); + } - MenuStateJoinGame::~MenuStateJoinGame () - { - abortAutoFind = true; + MenuStateJoinGame::~MenuStateJoinGame() { + abortAutoFind = true; #ifdef DEBUG - PRINT_DEBUG ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, - __LINE__); + PRINT_DEBUG("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, + __LINE__); #endif - } + } - void MenuStateJoinGame::DiscoveredServers (std::vector < string > - serverList) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + void MenuStateJoinGame::DiscoveredServers(std::vector < string > + serverList) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (abortAutoFind == true) - { - return; - } -// Testing multi-server -//serverList.push_back("test1"); -//serverList.push_back("test2"); -// + if (abortAutoFind == true) { + return; + } + // Testing multi-server + //serverList.push_back("test1"); + //serverList.push_back("test2"); + // #ifdef DEBUG - PRINT_DEBUG ("In [%s::%s Line: %d] serverList.size() = %d\n", __FILE__, - __FUNCTION__, __LINE__, (int) serverList.size ()); + PRINT_DEBUG("In [%s::%s Line: %d] serverList.size() = %d\n", __FILE__, + __FUNCTION__, __LINE__, (int) serverList.size()); #endif - autoConnectToServer = false; - buttonAutoFindServers.setEnabled (true); - buttonConnect.setEnabled (true); - if (serverList.empty () == false) - { - Config & config = Config::getInstance (); - string bestIPMatch = ""; - int serverGamePort = config.getInt ("PortServer", - intToStr (GameConstants:: - serverPort).c_str ()); - std::vector < std::string > localIPList = - Socket::getLocalIPAddressList (); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - - for (int idx = 0; idx < (int) serverList.size (); idx++) - { - - vector < string > paramPartPortsTokens; - Tokenize (serverList[idx], paramPartPortsTokens, ":"); - if (paramPartPortsTokens.size () >= 2 - && paramPartPortsTokens[1].length () > 0) - { - serverGamePort = strToInt (paramPartPortsTokens[1]); - } - - bestIPMatch = serverList[idx]; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] bestIPMatch = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - bestIPMatch.c_str ()); - if (localIPList.empty () == true) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, - __LINE__); - break; - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] bestIPMatch = [%s] localIPList[0] = [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - bestIPMatch.c_str (), - localIPList[0].c_str ()); - if (strncmp (localIPList[0].c_str (), serverList[idx].c_str (), 4) - == 0) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, - __LINE__); - break; - } - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - - if (bestIPMatch != "") - { - bestIPMatch += ":" + intToStr (serverGamePort); - } - labelServerIp.setText (bestIPMatch); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - - if (serverList.size () > 1) - { - listBoxServerType.setSelectedItemIndex (MenuStateJoinGame:: - foundServersIndex); - listBoxFoundServers.setItems (serverList); - } - else - { - autoConnectToServer = true; - } - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - } - - void MenuStateJoinGame::mouseClick (int x, int y, MouseButton mouseButton) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] START\n", __FILE__, - __FUNCTION__); - - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - NetworkManager & networkManager = NetworkManager::getInstance (); - ClientInterface *clientInterface = networkManager.getClientInterface (); - - if (clientInterface->isConnected () == false) - { -//server type - if (listBoxServerType.mouseClick (x, y)) - { - if (!listBoxServers.getText ().empty ()) - { - labelServerIp. - setText (servers.getString (listBoxServers.getText ()) + "_"); - } - } -//server list - else if (listBoxServerType.getSelectedItemIndex () == - newPrevServerIndex) - { - if (listBoxServers.mouseClick (x, y)) - { - labelServerIp. - setText (servers.getString (listBoxServers.getText ()) + "_"); - } - } - else if (listBoxServerType.getSelectedItemIndex () == - foundServersIndex) - { - if (listBoxFoundServers.mouseClick (x, y)) - { - labelServerIp.setText (listBoxFoundServers.getText ()); - } - } - - string host = labelServerIp.getText (); - Config & config = Config::getInstance (); - int portNumber = config.getInt ("PortServer", - intToStr (GameConstants::serverPort). - c_str ()); - std::vector < std::string > hostPartsList; - Tokenize (host, hostPartsList, ":"); - if (hostPartsList.size () > 1) - { - host = hostPartsList[0]; - replaceAll (hostPartsList[1], "_", ""); - portNumber = strToInt (hostPartsList[1]); - } - - string port = " (" + intToStr (portNumber) + ")"; - labelServerPort.setText (port); - - } - -//return - if (buttonReturn.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - - clientInterface->stopServerDiscovery (); - - if (clientInterface->getSocket () != NULL) - { -//if(clientInterface->isConnected() == true) { -// string sQuitText = Config::getInstance().getString("NetPlayerName",Socket::getHostName().c_str()) + " has chosen to leave the game!"; -// clientInterface->sendTextMessage(sQuitText,-1); -//} - clientInterface->close (); - } - abortAutoFind = true; - mainMenu->setState (new MenuStateNewGame (program, mainMenu)); - return; - } - -//connect - else if (buttonConnect.mouseClick (x, y) - && buttonConnect.getEnabled () == true) - { - ClientInterface *clientInterface = - networkManager.getClientInterface (); - - soundRenderer.playFx (coreData.getClickSoundB ()); - labelInfo.setText (""); - - if (clientInterface->isConnected ()) - { - clientInterface->reset (); - } - else - { - if (connectToServer () == true) - { - return; - } - } - } - else if (buttonCreateGame.mouseClick (x, y)) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - soundRenderer.playFx (coreData.getClickSoundB ()); - - clientInterface->stopServerDiscovery (); - if (clientInterface->getSocket () != NULL) - { - clientInterface->close (); - } - abortAutoFind = true; - mainMenu->setState (new - MenuStateCustomGame (program, mainMenu, true, - pLanGame)); - return; - } - - else if (buttonAutoFindServers.mouseClick (x, y) - && buttonAutoFindServers.getEnabled () == true) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - ClientInterface *clientInterface = - networkManager.getClientInterface (); - soundRenderer.playFx (coreData.getClickSoundB ()); - -// Triggers a thread which calls back into MenuStateJoinGame::DiscoveredServers -// with the results - if (clientInterface->isConnected () == false) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - buttonAutoFindServers.setEnabled (false); - buttonConnect.setEnabled (false); - clientInterface->discoverServers (this); - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] END\n", __FILE__, - __FUNCTION__); - } - - void MenuStateJoinGame::mouseMove (int x, int y, const MouseState * ms) - { - buttonReturn.mouseMove (x, y); - buttonConnect.mouseMove (x, y); - buttonAutoFindServers.mouseMove (x, y); - buttonCreateGame.mouseMove (x, y); - listBoxServerType.mouseMove (x, y); - -//hide-show options depending on the selection - if (listBoxServers.getSelectedItemIndex () == newServerIndex) - { - labelServerIp.mouseMove (x, y); - } - else if (listBoxServers.getSelectedItemIndex () == newPrevServerIndex) - { - listBoxServers.mouseMove (x, y); - } - else - { - listBoxFoundServers.mouseMove (x, y); - } - } - - void MenuStateJoinGame::render () - { - Renderer & renderer = Renderer::getInstance (); - - renderer.renderButton (&buttonReturn); - renderer.renderLabel (&labelServer); - renderer.renderLabel (&labelServerType); - renderer.renderLabel (&labelStatus); - renderer.renderLabel (&labelInfo); - renderer.renderLabel (&labelServerPort); - renderer.renderLabel (&labelServerPortLabel); - renderer.renderButton (&buttonConnect); - renderer.renderButton (&buttonCreateGame); - - renderer.renderButton (&buttonAutoFindServers); - renderer.renderListBox (&listBoxServerType); - - if (listBoxServerType.getSelectedItemIndex () == newServerIndex) - { - renderer.renderLabel (&labelServerIp); - } - else if (listBoxServerType.getSelectedItemIndex () == - newPrevServerIndex) - { - renderer.renderListBox (&listBoxServers); - } - else - { - renderer.renderListBox (&listBoxFoundServers); - } - - renderer.renderChatManager (&chatManager); - renderer.renderConsole (&console); - - if (program != NULL) - program->renderProgramMsgBox (); - } - - void MenuStateJoinGame::update () - { - ClientInterface *clientInterface = - NetworkManager::getInstance ().getClientInterface (); - Lang & lang = Lang::getInstance (); - -//update status label - if (clientInterface->isConnected ()) - { - buttonConnect.setText (lang.getString ("Disconnect")); - - if (clientInterface->getAllowDownloadDataSynch () == false) - { - string label = lang.getString ("ConnectedToServer"); - - if (!clientInterface->getServerName ().empty ()) - { - label = label + " " + clientInterface->getServerName (); - } - - if (clientInterface->getAllowGameDataSynchCheck () == true && - clientInterface->getNetworkGameDataSynchCheckOk () == false) - { - label = label + " - warning synch mismatch for:"; - if (clientInterface->getNetworkGameDataSynchCheckOkMap () == - false) - { - label = label + " map"; - } - if (clientInterface->getNetworkGameDataSynchCheckOkTile () == - false) - { - label = label + " tile"; - } - if (clientInterface->getNetworkGameDataSynchCheckOkTech () == - false) - { - label = label + " techtree"; - } - } - else if (clientInterface->getAllowGameDataSynchCheck () == true) - { - label += " - data synch is ok"; - } - labelStatus.setText (label); - } - else - { - string label = lang.getString ("ConnectedToServer"); - - if (!clientInterface->getServerName ().empty ()) - { - label = label + " " + clientInterface->getServerName (); - } - - if (clientInterface->getAllowGameDataSynchCheck () == true && - clientInterface->getNetworkGameDataSynchCheckOk () == false) - { - label = label + " - waiting to synch:"; - if (clientInterface->getNetworkGameDataSynchCheckOkMap () == - false) - { - label = label + " map"; - } - if (clientInterface->getNetworkGameDataSynchCheckOkTile () == - false) - { - label = label + " tile"; - } - if (clientInterface->getNetworkGameDataSynchCheckOkTech () == - false) - { - label = label + " techtree"; - } - } - else if (clientInterface->getAllowGameDataSynchCheck () == true) - { - label += " - data synch is ok"; - } - - labelStatus.setText (label); - } - } - else - { - buttonConnect.setText (lang.getString ("Connect")); - string connectedStatus = lang.getString ("NotConnected"); - if (buttonAutoFindServers.getEnabled () == false) - { - connectedStatus += " - searching for servers, please wait..."; - } - labelStatus.setText (connectedStatus); - labelInfo.setText (""); - } - -//process network messages - if (clientInterface->isConnected ()) - { -//update lobby - clientInterface->updateLobby (); - - clientInterface = - NetworkManager::getInstance ().getClientInterface (); - if (clientInterface != NULL && clientInterface->isConnected ()) - { -//call the chat manager - chatManager.updateNetwork (); - -//console - console.update (); - -//intro - if (clientInterface->getIntroDone ()) - { - labelInfo.setText (lang.getString ("WaitingHost")); - - string host = labelServerIp.getText (); - std::vector < std::string > hostPartsList; - Tokenize (host, hostPartsList, ":"); - if (hostPartsList.size () > 1) - { - host = hostPartsList[0]; - replaceAll (hostPartsList[1], "_", ""); - } - string saveHost = Ip (host).getString (); - if (hostPartsList.size () > 1) - { - saveHost += ":" + hostPartsList[1]; - } - - servers.setString (clientInterface->getServerName (), saveHost); - } - -//launch - if (clientInterface->getLaunchGame ()) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] clientInterface->getLaunchGame() - A\n", - __FILE__, __FUNCTION__); - - servers.save (serversSavedFile); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] clientInterface->getLaunchGame() - B\n", - __FILE__, __FUNCTION__); - - abortAutoFind = true; - clientInterface->stopServerDiscovery (); - program->setState (new - Game (program, - clientInterface->getGameSettings (), - false)); - return; - } - } - } - else if (autoConnectToServer == true) - { - autoConnectToServer = false; - if (connectToServer () == true) - { - return; - } - } - - if (clientInterface != NULL && clientInterface->getLaunchGame ()) - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] clientInterface->getLaunchGame() - D\n", - __FILE__, __FUNCTION__); - } - - bool MenuStateJoinGame::textInput (std::string text) - { - if (chatManager.getEditEnabled () == true) - { - return chatManager.textInput (text); - } - return false; - } - - void MenuStateJoinGame::keyDown (SDL_KeyboardEvent key) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = [%c][%d]\n", - __FILE__, __FUNCTION__, __LINE__, - key.keysym.sym, key.keysym.sym); - - ClientInterface *clientInterface = - NetworkManager::getInstance ().getClientInterface (); - if (clientInterface->isConnected () == false) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - - string text = labelServerIp.getText (); - if (isKeyPressed (SDLK_BACKSPACE, key) == true && text.length () > 0) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - size_t found = text.find_last_of ("_"); - if (found == string::npos) - { - text.erase (text.end () - 1); - } - else - { - if (text.size () > 1) - { - text.erase (text.end () - 2); - } - } - - labelServerIp.setText (text); - } -//else if(key == configKeys.getCharKey("SaveGUILayout")) { - else if (isKeyPressed (configKeys.getSDLKey ("SaveGUILayout"), key) == - true) - { - bool saved = - GraphicComponent::saveAllCustomProperties (containerName); - Lang & lang = Lang::getInstance (); - console.addLine (lang.getString ("GUILayoutSaved") + " [" + - (saved ? lang. - getString ("Yes") : lang.getString ("No")) + "]"); - } - } - else - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - -//send key to the chat manager - chatManager.keyDown (key); - - if (chatManager.getEditEnabled () == false) - { - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); -//if(key == configKeys.getCharKey("SaveGUILayout")) { - if (isKeyPressed (configKeys.getSDLKey ("SaveGUILayout"), key) == - true) - { - bool saved = - GraphicComponent::saveAllCustomProperties (containerName); - Lang & lang = Lang::getInstance (); - console.addLine (lang.getString ("GUILayoutSaved") + " [" + - (saved ? lang. - getString ("Yes") : lang.getString ("No")) + - "]"); - } - } - } - } - - void MenuStateJoinGame::keyPress (SDL_KeyboardEvent c) - { - ClientInterface *clientInterface = - NetworkManager::getInstance ().getClientInterface (); - - if (clientInterface->isConnected () == false) - { - int maxTextSize = 22; - -//Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); - - SDL_Keycode key = extractKeyPressed (c); - -//if(c>='0' && c<='9') { - if ((key >= SDLK_0 && key <= SDLK_9) || - (key >= SDLK_KP_0 && key <= SDLK_KP_9)) - { - if ((int) labelServerIp.getText ().size () < maxTextSize) - { - string text = labelServerIp.getText (); -//text.insert(text.end()-1, key); - char szCharText[26] = ""; - snprintf (szCharText, 26, "%c", key); - char *utfStr = ConvertToUTF8 (&szCharText[0]); - if (text.size () > 0) - { - text.insert (text.end () - 1, utfStr[0]); - } - else - { - text = utfStr[0]; - } - - delete[]utfStr; - - labelServerIp.setText (text); - } - } -//else if (c=='.') { - else if (key == SDLK_PERIOD) - { - if ((int) labelServerIp.getText ().size () < maxTextSize) - { - string text = labelServerIp.getText (); - if (text.size () > 0) - { - text.insert (text.end () - 1, '.'); - } - else - { - text = "."; - } - - labelServerIp.setText (text); - } - } -//else if (c==':') { - else if (key == SDLK_COLON) - { - if ((int) labelServerIp.getText ().size () < maxTextSize) - { - string text = labelServerIp.getText (); - if (text.size () > 0) - { - text.insert (text.end () - 1, ':'); - } - else - { - text = ":"; - } - - labelServerIp.setText (text); - } - } - } - else - { - chatManager.keyPress (c); - } - } - - bool MenuStateJoinGame::connectToServer () - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] START\n", __FILE__, - __FUNCTION__); - - Config & config = Config::getInstance (); - string host = labelServerIp.getText (); - int port = config.getInt ("PortServer", - intToStr (GameConstants::serverPort). - c_str ()); - std::vector < std::string > hostPartsList; - Tokenize (host, hostPartsList, ":"); - if (hostPartsList.size () > 1) - { - host = hostPartsList[0]; - replaceAll (hostPartsList[1], "_", ""); - port = strToInt (hostPartsList[1]); - } - Ip serverIp (host); - - ClientInterface *clientInterface = - NetworkManager::getInstance ().getClientInterface (); - clientInterface->connect (serverIp, port); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] server - [%s]\n", __FILE__, - __FUNCTION__, - serverIp.getString ().c_str ()); - - labelServerIp.setText (serverIp.getString () + '_'); - labelInfo.setText (""); - -//save server ip - if (config.getString ("ServerIp") != serverIp.getString ()) - { - config.setString ("ServerIp", serverIp.getString ()); - config.save (); - } - - for (time_t elapsedWait = time (NULL); - clientInterface->getIntroDone () == false && - clientInterface->isConnected () && - difftime (time (NULL), elapsedWait) <= 10;) - { - if (clientInterface->isConnected ()) - { -//update lobby - clientInterface->updateLobby (); - sleep (0); -//this->render(); - } - } - if (clientInterface->isConnected () == true && - clientInterface->getIntroDone () == true) - { - - string saveHost = Ip (host).getString (); - if (hostPartsList.size () > 1) - { - saveHost += ":" + hostPartsList[1]; - } - servers.setString (clientInterface->getServerName (), saveHost); - servers.save (serversSavedFile); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d] Using FTP port #: %d\n", - __FILE__, __FUNCTION__, __LINE__, - clientInterface->getServerFTPPort ()); - abortAutoFind = true; - clientInterface->stopServerDiscovery (); - mainMenu->setState (new MenuStateConnectedGame (program, mainMenu)); - return true; - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] END\n", __FILE__, - __FUNCTION__); - return false; - } - - } + autoConnectToServer = false; + buttonAutoFindServers.setEnabled(true); + buttonConnect.setEnabled(true); + if (serverList.empty() == false) { + Config & config = Config::getInstance(); + string bestIPMatch = ""; + int serverGamePort = config.getInt("PortServer", + intToStr(GameConstants:: + serverPort).c_str()); + std::vector < std::string > localIPList = + Socket::getLocalIPAddressList(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + for (int idx = 0; idx < (int) serverList.size(); idx++) { + + vector < string > paramPartPortsTokens; + Tokenize(serverList[idx], paramPartPortsTokens, ":"); + if (paramPartPortsTokens.size() >= 2 + && paramPartPortsTokens[1].length() > 0) { + serverGamePort = strToInt(paramPartPortsTokens[1]); + } + + bestIPMatch = serverList[idx]; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] bestIPMatch = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + bestIPMatch.c_str()); + if (localIPList.empty() == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, + __LINE__); + break; + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] bestIPMatch = [%s] localIPList[0] = [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + bestIPMatch.c_str(), + localIPList[0].c_str()); + if (strncmp(localIPList[0].c_str(), serverList[idx].c_str(), 4) + == 0) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, + __LINE__); + break; + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (bestIPMatch != "") { + bestIPMatch += ":" + intToStr(serverGamePort); + } + labelServerIp.setText(bestIPMatch); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (serverList.size() > 1) { + listBoxServerType.setSelectedItemIndex(MenuStateJoinGame:: + foundServersIndex); + listBoxFoundServers.setItems(serverList); + } else { + autoConnectToServer = true; + } + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void MenuStateJoinGame::mouseClick(int x, int y, MouseButton mouseButton) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] START\n", __FILE__, + __FUNCTION__); + + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + NetworkManager & networkManager = NetworkManager::getInstance(); + ClientInterface *clientInterface = networkManager.getClientInterface(); + + if (clientInterface->isConnected() == false) { + //server type + if (listBoxServerType.mouseClick(x, y)) { + if (!listBoxServers.getText().empty()) { + labelServerIp. + setText(servers.getString(listBoxServers.getText()) + "_"); + } + } + //server list + else if (listBoxServerType.getSelectedItemIndex() == + newPrevServerIndex) { + if (listBoxServers.mouseClick(x, y)) { + labelServerIp. + setText(servers.getString(listBoxServers.getText()) + "_"); + } + } else if (listBoxServerType.getSelectedItemIndex() == + foundServersIndex) { + if (listBoxFoundServers.mouseClick(x, y)) { + labelServerIp.setText(listBoxFoundServers.getText()); + } + } + + string host = labelServerIp.getText(); + Config & config = Config::getInstance(); + int portNumber = config.getInt("PortServer", + intToStr(GameConstants::serverPort). + c_str()); + std::vector < std::string > hostPartsList; + Tokenize(host, hostPartsList, ":"); + if (hostPartsList.size() > 1) { + host = hostPartsList[0]; + replaceAll(hostPartsList[1], "_", ""); + portNumber = strToInt(hostPartsList[1]); + } + + string port = " (" + intToStr(portNumber) + ")"; + labelServerPort.setText(port); + + } + + //return + if (buttonReturn.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + + clientInterface->stopServerDiscovery(); + + if (clientInterface->getSocket() != NULL) { + //if(clientInterface->isConnected() == true) { + // string sQuitText = Config::getInstance().getString("NetPlayerName",Socket::getHostName().c_str()) + " has chosen to leave the game!"; + // clientInterface->sendTextMessage(sQuitText,-1); + //} + clientInterface->close(); + } + abortAutoFind = true; + mainMenu->setState(new MenuStateNewGame(program, mainMenu)); + return; + } + + //connect + else if (buttonConnect.mouseClick(x, y) + && buttonConnect.getEnabled() == true) { + ClientInterface *clientInterface = + networkManager.getClientInterface(); + + soundRenderer.playFx(coreData.getClickSoundB()); + labelInfo.setText(""); + + if (clientInterface->isConnected()) { + clientInterface->reset(); + } else { + if (connectToServer() == true) { + return; + } + } + } else if (buttonCreateGame.mouseClick(x, y)) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + soundRenderer.playFx(coreData.getClickSoundB()); + + clientInterface->stopServerDiscovery(); + if (clientInterface->getSocket() != NULL) { + clientInterface->close(); + } + abortAutoFind = true; + mainMenu->setState(new + MenuStateCustomGame(program, mainMenu, true, + pLanGame)); + return; + } + + else if (buttonAutoFindServers.mouseClick(x, y) + && buttonAutoFindServers.getEnabled() == true) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + ClientInterface *clientInterface = + networkManager.getClientInterface(); + soundRenderer.playFx(coreData.getClickSoundB()); + + // Triggers a thread which calls back into MenuStateJoinGame::DiscoveredServers + // with the results + if (clientInterface->isConnected() == false) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + buttonAutoFindServers.setEnabled(false); + buttonConnect.setEnabled(false); + clientInterface->discoverServers(this); + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] END\n", __FILE__, + __FUNCTION__); + } + + void MenuStateJoinGame::mouseMove(int x, int y, const MouseState * ms) { + buttonReturn.mouseMove(x, y); + buttonConnect.mouseMove(x, y); + buttonAutoFindServers.mouseMove(x, y); + buttonCreateGame.mouseMove(x, y); + listBoxServerType.mouseMove(x, y); + + //hide-show options depending on the selection + if (listBoxServers.getSelectedItemIndex() == newServerIndex) { + labelServerIp.mouseMove(x, y); + } else if (listBoxServers.getSelectedItemIndex() == newPrevServerIndex) { + listBoxServers.mouseMove(x, y); + } else { + listBoxFoundServers.mouseMove(x, y); + } + } + + void MenuStateJoinGame::render() { + Renderer & renderer = Renderer::getInstance(); + + renderer.renderButton(&buttonReturn); + renderer.renderLabel(&labelServer); + renderer.renderLabel(&labelServerType); + renderer.renderLabel(&labelStatus); + renderer.renderLabel(&labelInfo); + renderer.renderLabel(&labelServerPort); + renderer.renderLabel(&labelServerPortLabel); + renderer.renderButton(&buttonConnect); + renderer.renderButton(&buttonCreateGame); + + renderer.renderButton(&buttonAutoFindServers); + renderer.renderListBox(&listBoxServerType); + + if (listBoxServerType.getSelectedItemIndex() == newServerIndex) { + renderer.renderLabel(&labelServerIp); + } else if (listBoxServerType.getSelectedItemIndex() == + newPrevServerIndex) { + renderer.renderListBox(&listBoxServers); + } else { + renderer.renderListBox(&listBoxFoundServers); + } + + renderer.renderChatManager(&chatManager); + renderer.renderConsole(&console); + + if (program != NULL) + program->renderProgramMsgBox(); + } + + void MenuStateJoinGame::update() { + ClientInterface *clientInterface = + NetworkManager::getInstance().getClientInterface(); + Lang & lang = Lang::getInstance(); + + //update status label + if (clientInterface->isConnected()) { + buttonConnect.setText(lang.getString("Disconnect")); + + if (clientInterface->getAllowDownloadDataSynch() == false) { + string label = lang.getString("ConnectedToServer"); + + if (!clientInterface->getServerName().empty()) { + label = label + " " + clientInterface->getServerName(); + } + + if (clientInterface->getAllowGameDataSynchCheck() == true && + clientInterface->getNetworkGameDataSynchCheckOk() == false) { + label = label + " - warning synch mismatch for:"; + if (clientInterface->getNetworkGameDataSynchCheckOkMap() == + false) { + label = label + " map"; + } + if (clientInterface->getNetworkGameDataSynchCheckOkTile() == + false) { + label = label + " tile"; + } + if (clientInterface->getNetworkGameDataSynchCheckOkTech() == + false) { + label = label + " techtree"; + } + } else if (clientInterface->getAllowGameDataSynchCheck() == true) { + label += " - data synch is ok"; + } + labelStatus.setText(label); + } else { + string label = lang.getString("ConnectedToServer"); + + if (!clientInterface->getServerName().empty()) { + label = label + " " + clientInterface->getServerName(); + } + + if (clientInterface->getAllowGameDataSynchCheck() == true && + clientInterface->getNetworkGameDataSynchCheckOk() == false) { + label = label + " - waiting to synch:"; + if (clientInterface->getNetworkGameDataSynchCheckOkMap() == + false) { + label = label + " map"; + } + if (clientInterface->getNetworkGameDataSynchCheckOkTile() == + false) { + label = label + " tile"; + } + if (clientInterface->getNetworkGameDataSynchCheckOkTech() == + false) { + label = label + " techtree"; + } + } else if (clientInterface->getAllowGameDataSynchCheck() == true) { + label += " - data synch is ok"; + } + + labelStatus.setText(label); + } + } else { + buttonConnect.setText(lang.getString("Connect")); + string connectedStatus = lang.getString("NotConnected"); + if (buttonAutoFindServers.getEnabled() == false) { + connectedStatus += " - searching for servers, please wait..."; + } + labelStatus.setText(connectedStatus); + labelInfo.setText(""); + } + + //process network messages + if (clientInterface->isConnected()) { + //update lobby + clientInterface->updateLobby(); + + clientInterface = + NetworkManager::getInstance().getClientInterface(); + if (clientInterface != NULL && clientInterface->isConnected()) { + //call the chat manager + chatManager.updateNetwork(); + + //console + console.update(); + + //intro + if (clientInterface->getIntroDone()) { + labelInfo.setText(lang.getString("WaitingHost")); + + string host = labelServerIp.getText(); + std::vector < std::string > hostPartsList; + Tokenize(host, hostPartsList, ":"); + if (hostPartsList.size() > 1) { + host = hostPartsList[0]; + replaceAll(hostPartsList[1], "_", ""); + } + string saveHost = Ip(host).getString(); + if (hostPartsList.size() > 1) { + saveHost += ":" + hostPartsList[1]; + } + + servers.setString(clientInterface->getServerName(), saveHost); + } + + //launch + if (clientInterface->getLaunchGame()) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] clientInterface->getLaunchGame() - A\n", + __FILE__, __FUNCTION__); + + servers.save(serversSavedFile); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] clientInterface->getLaunchGame() - B\n", + __FILE__, __FUNCTION__); + + abortAutoFind = true; + clientInterface->stopServerDiscovery(); + program->setState(new + Game(program, + clientInterface->getGameSettings(), + false)); + return; + } + } + } else if (autoConnectToServer == true) { + autoConnectToServer = false; + if (connectToServer() == true) { + return; + } + } + + if (clientInterface != NULL && clientInterface->getLaunchGame()) + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] clientInterface->getLaunchGame() - D\n", + __FILE__, __FUNCTION__); + } + + bool MenuStateJoinGame::textInput(std::string text) { + if (chatManager.getEditEnabled() == true) { + return chatManager.textInput(text); + } + return false; + } + + void MenuStateJoinGame::keyDown(SDL_KeyboardEvent key) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = [%c][%d]\n", + __FILE__, __FUNCTION__, __LINE__, + key.keysym.sym, key.keysym.sym); + + ClientInterface *clientInterface = + NetworkManager::getInstance().getClientInterface(); + if (clientInterface->isConnected() == false) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + + string text = labelServerIp.getText(); + if (isKeyPressed(SDLK_BACKSPACE, key) == true && text.length() > 0) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + size_t found = text.find_last_of("_"); + if (found == string::npos) { + text.erase(text.end() - 1); + } else { + if (text.size() > 1) { + text.erase(text.end() - 2); + } + } + + labelServerIp.setText(text); + } + //else if(key == configKeys.getCharKey("SaveGUILayout")) { + else if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), key) == + true) { + bool saved = + GraphicComponent::saveAllCustomProperties(containerName); + Lang & lang = Lang::getInstance(); + console.addLine(lang.getString("GUILayoutSaved") + " [" + + (saved ? lang. + getString("Yes") : lang.getString("No")) + "]"); + } + } else { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + //send key to the chat manager + chatManager.keyDown(key); + + if (chatManager.getEditEnabled() == false) { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + //if(key == configKeys.getCharKey("SaveGUILayout")) { + if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), key) == + true) { + bool saved = + GraphicComponent::saveAllCustomProperties(containerName); + Lang & lang = Lang::getInstance(); + console.addLine(lang.getString("GUILayoutSaved") + " [" + + (saved ? lang. + getString("Yes") : lang.getString("No")) + + "]"); + } + } + } + } + + void MenuStateJoinGame::keyPress(SDL_KeyboardEvent c) { + ClientInterface *clientInterface = + NetworkManager::getInstance().getClientInterface(); + + if (clientInterface->isConnected() == false) { + int maxTextSize = 22; + + //Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); + + SDL_Keycode key = extractKeyPressed(c); + + //if(c>='0' && c<='9') { + if ((key >= SDLK_0 && key <= SDLK_9) || + (key >= SDLK_KP_0 && key <= SDLK_KP_9)) { + if ((int) labelServerIp.getText().size() < maxTextSize) { + string text = labelServerIp.getText(); + //text.insert(text.end()-1, key); + char szCharText[26] = ""; + snprintf(szCharText, 26, "%c", key); + char *utfStr = ConvertToUTF8(&szCharText[0]); + if (text.size() > 0) { + text.insert(text.end() - 1, utfStr[0]); + } else { + text = utfStr[0]; + } + + delete[]utfStr; + + labelServerIp.setText(text); + } + } + //else if (c=='.') { + else if (key == SDLK_PERIOD) { + if ((int) labelServerIp.getText().size() < maxTextSize) { + string text = labelServerIp.getText(); + if (text.size() > 0) { + text.insert(text.end() - 1, '.'); + } else { + text = "."; + } + + labelServerIp.setText(text); + } + } + //else if (c==':') { + else if (key == SDLK_COLON) { + if ((int) labelServerIp.getText().size() < maxTextSize) { + string text = labelServerIp.getText(); + if (text.size() > 0) { + text.insert(text.end() - 1, ':'); + } else { + text = ":"; + } + + labelServerIp.setText(text); + } + } + } else { + chatManager.keyPress(c); + } + } + + bool MenuStateJoinGame::connectToServer() { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] START\n", __FILE__, + __FUNCTION__); + + Config & config = Config::getInstance(); + string host = labelServerIp.getText(); + int port = config.getInt("PortServer", + intToStr(GameConstants::serverPort). + c_str()); + std::vector < std::string > hostPartsList; + Tokenize(host, hostPartsList, ":"); + if (hostPartsList.size() > 1) { + host = hostPartsList[0]; + replaceAll(hostPartsList[1], "_", ""); + port = strToInt(hostPartsList[1]); + } + Ip serverIp(host); + + ClientInterface *clientInterface = + NetworkManager::getInstance().getClientInterface(); + clientInterface->connect(serverIp, port); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] server - [%s]\n", __FILE__, + __FUNCTION__, + serverIp.getString().c_str()); + + labelServerIp.setText(serverIp.getString() + '_'); + labelInfo.setText(""); + + //save server ip + if (config.getString("ServerIp") != serverIp.getString()) { + config.setString("ServerIp", serverIp.getString()); + config.save(); + } + + for (time_t elapsedWait = time(NULL); + clientInterface->getIntroDone() == false && + clientInterface->isConnected() && + difftime(time(NULL), elapsedWait) <= 10;) { + if (clientInterface->isConnected()) { + //update lobby + clientInterface->updateLobby(); + sleep(0); + //this->render(); + } + } + if (clientInterface->isConnected() == true && + clientInterface->getIntroDone() == true) { + + string saveHost = Ip(host).getString(); + if (hostPartsList.size() > 1) { + saveHost += ":" + hostPartsList[1]; + } + servers.setString(clientInterface->getServerName(), saveHost); + servers.save(serversSavedFile); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d] Using FTP port #: %d\n", + __FILE__, __FUNCTION__, __LINE__, + clientInterface->getServerFTPPort()); + abortAutoFind = true; + clientInterface->stopServerDiscovery(); + mainMenu->setState(new MenuStateConnectedGame(program, mainMenu)); + return true; + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] END\n", __FILE__, + __FUNCTION__); + return false; + } + + } } //end namespace diff --git a/source/glest_game/menu/menu_state_join_game.h b/source/glest_game/menu/menu_state_join_game.h index c6545fc29..6dd3c8b48 100644 --- a/source/glest_game/menu/menu_state_join_game.h +++ b/source/glest_game/menu/menu_state_join_game.h @@ -26,104 +26,101 @@ using Shared::Util::Properties; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - class NetworkMessageIntro; + class NetworkMessageIntro; -// =============================== -// class MenuStateJoinGame -// =============================== + // =============================== + // class MenuStateJoinGame + // =============================== - class MenuStateJoinGame: - public MenuState, public DiscoveredServersInterface - { - private: - static const int - newServerIndex; - static const int - newPrevServerIndex; - static const int - foundServersIndex; - static const - string - serverFileName; + class MenuStateJoinGame : + public MenuState, public DiscoveredServersInterface { + private: + static const int + newServerIndex; + static const int + newPrevServerIndex; + static const int + foundServersIndex; + static const + string + serverFileName; - private: - GraphicButton buttonReturn; - GraphicButton buttonConnect; - GraphicButton buttonAutoFindServers; - GraphicButton buttonCreateGame; + private: + GraphicButton buttonReturn; + GraphicButton buttonConnect; + GraphicButton buttonAutoFindServers; + GraphicButton buttonCreateGame; - GraphicLabel labelServer; - GraphicLabel labelServerType; - GraphicLabel labelServerIp; - GraphicLabel labelStatus; - GraphicLabel labelInfo; - GraphicListBox listBoxServerType; - GraphicListBox listBoxServers; - GraphicListBox listBoxFoundServers; - GraphicLabel labelServerPort; - GraphicLabel labelServerPortLabel; + GraphicLabel labelServer; + GraphicLabel labelServerType; + GraphicLabel labelServerIp; + GraphicLabel labelStatus; + GraphicLabel labelInfo; + GraphicListBox listBoxServerType; + GraphicListBox listBoxServers; + GraphicListBox listBoxFoundServers; + GraphicLabel labelServerPort; + GraphicLabel labelServerPortLabel; - bool connected; - int - playerIndex; - Properties servers; + bool connected; + int + playerIndex; + Properties servers; -//Console console; - ChatManager chatManager; + //Console console; + ChatManager chatManager; - string serversSavedFile; - bool abortAutoFind; - bool autoConnectToServer; + string serversSavedFile; + bool abortAutoFind; + bool autoConnectToServer; - public: - MenuStateJoinGame (Program * program, MainMenu * mainMenu, - bool connect = false, Ip serverIp = - Ip (), int portNumberOverride = -1); - MenuStateJoinGame (Program * program, MainMenu * mainMenu, - bool * autoFindHost); - virtual ~ MenuStateJoinGame (); + public: + MenuStateJoinGame(Program * program, MainMenu * mainMenu, + bool connect = false, Ip serverIp = + Ip(), int portNumberOverride = -1); + MenuStateJoinGame(Program * program, MainMenu * mainMenu, + bool * autoFindHost); + virtual ~MenuStateJoinGame(); - void - mouseClick (int x, int y, MouseButton mouseButton); - void - mouseMove (int x, int y, const MouseState * mouseState); - void - render (); - void - update (); + void + mouseClick(int x, int y, MouseButton mouseButton); + void + mouseMove(int x, int y, const MouseState * mouseState); + void + render(); + void + update(); - virtual - bool - textInput (std::string text); - virtual void - keyDown (SDL_KeyboardEvent key); - virtual void - keyPress (SDL_KeyboardEvent c); + virtual + bool + textInput(std::string text); + virtual void + keyDown(SDL_KeyboardEvent key); + virtual void + keyPress(SDL_KeyboardEvent c); - virtual - bool - isInSpecialKeyCaptureEvent () - { - return chatManager.getEditEnabled (); - } + virtual + bool + isInSpecialKeyCaptureEvent() { + return chatManager.getEditEnabled(); + } - void - reloadUI (); + void + reloadUI(); - private: + private: - void - CommonInit (bool connect, Ip serverIp, int portNumberOverride); - bool connectToServer (); - virtual void - DiscoveredServers (std::vector < string > serverList); - }; -}} //end namespace + void + CommonInit(bool connect, Ip serverIp, int portNumberOverride); + bool connectToServer(); + virtual void + DiscoveredServers(std::vector < string > serverList); + }; + } +} //end namespace #endif diff --git a/source/glest_game/menu/menu_state_keysetup.cpp b/source/glest_game/menu/menu_state_keysetup.cpp index 92c4eae04..95778d95c 100644 --- a/source/glest_game/menu/menu_state_keysetup.cpp +++ b/source/glest_game/menu/menu_state_keysetup.cpp @@ -27,841 +27,754 @@ #include "leak_dumper.h" -namespace Glest -{ - namespace Game - { - - -// ===================================================== -// class MenuStateKeysetup -// ===================================================== - - MenuStateKeysetup::MenuStateKeysetup (Program * program, - MainMenu * mainMenu, - ProgramState ** - parentUI):MenuState (program, - mainMenu, - "config"), - buttonOk ("KeySetup", "buttonOk"), buttonDefaults ("KeySetup", - "buttonDefaults"), - buttonReturn ("KeySetup", "buttonReturn"), - buttonKeyboardSetup ("KeySetup", "buttonKeyboardSetup"), - buttonVideoSection ("KeySetup", "buttonVideoSection"), - buttonAudioSection ("KeySetup", "buttonAudioSection"), - buttonMiscSection ("KeySetup", "buttonMiscSection"), - buttonNetworkSettings ("KeySetup", "buttonNetworkSettings"), - labelTitle ("KeySetup", "labelTitle"), keyScrollBar ("KeySetup", - "keyScrollBar"), - mainMessageBox ("KeySetup", "mainMessageBox"), - labelTestTitle ("KeySetup", "labelTestTitle"), - labelTestValue ("KeySetup", "labelTestValue") - { - try - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - containerName = "KeySetup"; - - keyButtonsLineHeight = 30; - keyButtonsHeight = 25; - keyButtonsWidth = 400; - keyButtonsXBase = 200; - keyButtonsYBase = 200 + 400 - keyButtonsLineHeight; - keyButtonsToRender = 400 / keyButtonsLineHeight; - int labelWidth = 100; - - this->parentUI = parentUI; - this->console.setOnlyChatMessagesInStoredLines (false); - hotkeyIndex = -1; - hotkeyChar = SDLK_UNKNOWN; - - Lang & lang = Lang::getInstance (); - int buttonStartPos = 170; - int buttonRowPos = 50; - if (this->parentUI == NULL) - { - int tabButtonWidth = 200; - int tabButtonHeight = 30; - - buttonAudioSection.init (0, 720, tabButtonWidth, tabButtonHeight); - buttonAudioSection.setFont (CoreData::getInstance (). - getMenuFontVeryBig ()); - buttonAudioSection.setFont3D (CoreData::getInstance (). - getMenuFontVeryBig3D ()); - buttonAudioSection.setText (lang.getString ("Audio")); - // Video Section - buttonVideoSection.init (200, 720, tabButtonWidth, - tabButtonHeight); - buttonVideoSection.setFont (CoreData::getInstance (). - getMenuFontVeryBig ()); - buttonVideoSection.setFont3D (CoreData::getInstance (). - getMenuFontVeryBig3D ()); - buttonVideoSection.setText (lang.getString ("Video")); - //currentLine-=lineOffset; - //MiscSection - buttonMiscSection.init (400, 720, tabButtonWidth, - tabButtonHeight); - buttonMiscSection.setFont (CoreData::getInstance (). - getMenuFontVeryBig ()); - buttonMiscSection.setFont3D (CoreData::getInstance (). - getMenuFontVeryBig3D ()); - buttonMiscSection.setText (lang.getString ("Misc")); - //NetworkSettings - buttonNetworkSettings.init (600, 720, tabButtonWidth, - tabButtonHeight); - buttonNetworkSettings.setFont (CoreData::getInstance (). - getMenuFontVeryBig ()); - buttonNetworkSettings.setFont3D (CoreData::getInstance (). - getMenuFontVeryBig3D ()); - buttonNetworkSettings.setText (lang.getString ("Network")); - - //KeyboardSetup - buttonKeyboardSetup.init (800, 700, tabButtonWidth, - tabButtonHeight + 20); - buttonKeyboardSetup.setFont (CoreData::getInstance (). - getMenuFontVeryBig ()); - buttonKeyboardSetup.setFont3D (CoreData::getInstance (). - getMenuFontVeryBig3D ()); - buttonKeyboardSetup.setText (lang.getString ("Keyboardsetup")); - } - // header - labelTitle.init (375, 650); - labelTitle.setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - labelTitle.setFont3D (CoreData::getInstance (). - getMenuFontVeryBig3D ()); - labelTitle.setText (lang.getString ("KeyboardsetupL")); - - labelTestTitle.init (keyButtonsXBase, 155); - labelTestTitle.setFont (CoreData::getInstance (). - getMenuFontNormal ()); - labelTestTitle.setFont3D (CoreData::getInstance (). - getMenuFontNormal3D ()); - labelTestTitle.setText (lang.getString ("KeyboardsetupTest")); - - labelTestValue.init (keyButtonsXBase, 155 - 28); - labelTestValue.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelTestValue.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - labelTestValue.setRenderBackground (true); - labelTestValue.setMaxEditRenderWidth (keyButtonsWidth); - labelTestValue.setText (""); - - // mainMassegeBox - mainMessageBox.init (lang.getString ("Ok")); - mainMessageBox.setEnabled (false); - mainMessageBoxState = 0; - - keyScrollBar.init (800, 200, false, 200, 20); - keyScrollBar.setLength (400); - keyScrollBar.setElementCount (0); - keyScrollBar.setVisibleSize (keyButtonsToRender); - keyScrollBar.setVisibleStart (0); - - // buttons - buttonOk.init (buttonStartPos, buttonRowPos, 100); - buttonOk.setText (lang.getString ("Save")); - - buttonReturn.init (buttonStartPos + 110, buttonRowPos, 100); - buttonReturn.setText (lang.getString ("Return")); - - buttonDefaults.init (buttonStartPos + 230, buttonRowPos, 125); - buttonDefaults.setText (lang.getString ("Defaults")); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - mergedProperties = configKeys.getMergedProperties (); - masterProperties = configKeys.getMasterProperties (); - //userProperties=configKeys.getUserProperties(); - userProperties.clear (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - //throw megaglest_runtime_error("Test!"); - - for (int i = 0; i < (int) mergedProperties.size (); ++i) - { - - string keyName = mergedProperties[i].second; - if (keyName.length () > 0) - { - //char c = configKeys.translateStringToCharKey(keyName); - SDL_Keycode c = configKeys.translateStringToSDLKey (keyName); - if (c > SDLK_UNKNOWN && c < SDL_NUM_SCANCODES) - { - SDL_Keycode keysym = static_cast < SDL_Keycode > (c); - // SDL skips capital letters - if (keysym >= 65 && keysym <= 90) - { - keysym = (SDL_Keycode) ((int) keysym + 32); - } - keyName = SDL_GetKeyName (keysym); - } - else - { - keyName = ""; - } - if (keyName == "unknown key" || keyName == "") - { - keyName = mergedProperties[i].second; - } - } - - GraphicButton *button = - new GraphicButton (containerName, - string ("ScrollButton") + intToStr (i)); - button->init (keyButtonsXBase, keyButtonsYBase, keyButtonsWidth, - keyButtonsHeight); - button->setText (mergedProperties[i].first); - keyButtons.push_back (button); - GraphicLabel *label = - new GraphicLabel (containerName, - string ("ScrollLabel") + intToStr (i)); - label->init (keyButtonsXBase + keyButtonsWidth + 5, keyButtonsYBase, - labelWidth, 20); - label->setRenderBackground (true); - label->setMaxEditRenderWidth (105); - label->setText (" " + keyName); - labels.push_back (label); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - keyScrollBar.init (keyButtonsXBase + keyButtonsWidth + labelWidth + - 20, 200, false, 200, 20); - keyScrollBar.setLength (400); - keyScrollBar.setElementCount ((int) keyButtons.size ()); - keyScrollBar.setVisibleSize (keyButtonsToRender); - keyScrollBar.setVisibleStart (0); - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] Error detected:\n%s\n", - __FILE__, __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - mainMessageBoxState = 1; - showMessageBox ("Error: " + string (ex.what ()), "Error detected", - false); - } - } - - void MenuStateKeysetup::reloadUI () - { - Lang & lang = Lang::getInstance (); - - labelTitle.setText (lang.getString ("KeyboardsetupL")); - labelTestTitle.setText (lang.getString ("KeyboardsetupTest")); - labelTestValue.setText (""); - - // mainMassegeBox - mainMessageBox.init (lang.getString ("Ok")); - - buttonOk.setText (lang.getString ("Save")); - buttonReturn.setText (lang.getString ("Return")); - buttonDefaults.setText (lang.getString ("Defaults")); - } - - void MenuStateKeysetup::cleanup () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - clearUserButtons (); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] END\n", __FILE__, - __FUNCTION__, __LINE__); - } - - MenuStateKeysetup::~MenuStateKeysetup () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - cleanup (); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] END\n", __FILE__, - __FUNCTION__, __LINE__); - } - - void MenuStateKeysetup::clearUserButtons () - { - while (!keyButtons.empty ()) - { - delete keyButtons.back (); - keyButtons.pop_back (); - } - while (!labels.empty ()) - { - delete labels.back (); - labels.pop_back (); - } - } - - void MenuStateKeysetup::mouseClick (int x, int y, MouseButton mouseButton) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - - if (mainMessageBox.getEnabled ()) - { - int button = 0; - if (mainMessageBox.mouseClick (x, y, button)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - if (button == 0) - { - mainMessageBox.setEnabled (false); - } - } - } - else if (keyScrollBar.mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - soundRenderer.playFx (coreData.getClickSoundB ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - else if (buttonReturn.mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - soundRenderer.playFx (coreData.getClickSoundB ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - if (this->parentUI != NULL) - { - // Set the parent pointer to NULL so the owner knows it was deleted - *this->parentUI = NULL; - // Delete the main menu - delete mainMenu; - return; - } - mainMenu->setState (new MenuStateRoot (program, mainMenu)); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - else if (buttonDefaults.mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - soundRenderer.playFx (coreData.getClickSoundB ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - string userKeysFile = configKeys.getFileName (true); - - bool result = removeFile (userKeysFile.c_str ()); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] delete file [%s] returned %d\n", - __FILE__, __FUNCTION__, __LINE__, userKeysFile.c_str (), - result); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] delete file [%s] returned %d\n", - __FILE__, __FUNCTION__, __LINE__, - userKeysFile.c_str (), result); - configKeys.reload (); - - if (this->parentUI != NULL) - { - // Set the parent pointer to NULL so the owner knows it was deleted - *this->parentUI = NULL; - // Delete the main menu - delete mainMenu; - return; - } - - mainMenu->setState (new MenuStateKeysetup (program, mainMenu)); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - else if (buttonOk.mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - soundRenderer.playFx (coreData.getClickSoundB ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - if (userProperties.empty () == false) - { - Config & config = Config::getInstance (); - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys), - std::pair < string, - string > (Config::glestkeys_ini_filename, - Config:: - glestuserkeys_ini_filename), - std::pair < bool, bool > (true, false), - config.getString ("GlestKeysIniPath", "")); - string userKeysFile = configKeys.getFileName (true); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line: %d] save file [%s] userProperties.size() = " - MG_SIZE_T_SPECIFIER "\n", __FILE__, __FUNCTION__, __LINE__, - userKeysFile.c_str (), userProperties.size ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] save file [%s] userProperties.size() = " - MG_SIZE_T_SPECIFIER "\n", __FILE__, - __FUNCTION__, __LINE__, - userKeysFile.c_str (), - userProperties.size ()); - - configKeys.setUserProperties (userProperties); - configKeys.save (); - configKeys.reload (); - } - - Lang & lang = Lang::getInstance (); - console.addLine (lang.getString ("SettingsSaved")); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - else if (keyScrollBar.getElementCount () != 0) - { - for (int i = keyScrollBar.getVisibleStart (); i - <= keyScrollBar.getVisibleEnd (); ++i) - { - if (keyButtons[i]->mouseClick (x, y)) - { - hotkeyIndex = i; - hotkeyChar = SDLK_UNKNOWN; - break; - } - } - } - - if (this->parentUI == NULL) - { - if (buttonKeyboardSetup.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - return; - } - else if (buttonAudioSection.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptionsSound (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - return; - } - else if (buttonNetworkSettings.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptionsNetwork (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - return; - } - else if (buttonMiscSection.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptions (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - return; - } - else if (buttonVideoSection.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptionsGraphics (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - return; - } - } - } - - void MenuStateKeysetup::mouseUp (int x, int y, - const MouseButton mouseButton) - { - if (mouseButton == mbLeft) - { - keyScrollBar.mouseUp (x, y); - } - } - - void MenuStateKeysetup::mouseMove (int x, int y, const MouseState * ms) - { - buttonReturn.mouseMove (x, y); - buttonOk.mouseMove (x, y); - if (this->parentUI == NULL) - { - buttonKeyboardSetup.mouseMove (x, y); - buttonAudioSection.mouseMove (x, y); - buttonNetworkSettings.mouseMove (x, y); - buttonMiscSection.mouseMove (x, y); - buttonVideoSection.mouseMove (x, y); - } - if (ms->get (mbLeft)) - { - keyScrollBar.mouseDown (x, y); - } - else - { - keyScrollBar.mouseMove (x, y); - } - - if (keyScrollBar.getElementCount () != 0) - { - for (int i = keyScrollBar.getVisibleStart (); - i <= keyScrollBar.getVisibleEnd (); ++i) - { - keyButtons[i]->mouseMove (x, y); - } - } - - } - - void MenuStateKeysetup::render () - { - Renderer & renderer = Renderer::getInstance (); - - //printf("MenuStateKeysetup::render A\n"); - - if (mainMessageBox.getEnabled ()) - { - //printf("MenuStateKeysetup::render B\n"); - renderer.renderMessageBox (&mainMessageBox); - } - else - { - //printf("MenuStateKeysetup::render C\n"); - renderer.renderButton (&buttonReturn); - renderer.renderButton (&buttonDefaults); - renderer.renderButton (&buttonOk); - if (this->parentUI == NULL) - { - renderer.renderButton (&buttonKeyboardSetup); - renderer.renderButton (&buttonVideoSection); - renderer.renderButton (&buttonAudioSection); - renderer.renderButton (&buttonMiscSection); - renderer.renderButton (&buttonNetworkSettings); - } - renderer.renderLabel (&labelTitle); - renderer.renderLabel (&labelTestTitle); - renderer.renderLabel (&labelTestValue); - - if (keyScrollBar.getElementCount () != 0) - { - for (int i = keyScrollBar.getVisibleStart (); - i <= keyScrollBar.getVisibleEnd (); ++i) - { - if (hotkeyIndex == i) - { - renderer.renderButton (keyButtons[i], &YELLOW); - } - else - { - renderer.renderButton (keyButtons[i]); - } - renderer.renderLabel (labels[i]); - } - } - renderer.renderScrollBar (&keyScrollBar); - } - - renderer.renderConsole (&console); - if (program != NULL) - program->renderProgramMsgBox (); - } - - void MenuStateKeysetup::update () - { - //printf("MenuStateKeysetup::update A\n"); - - if (keyScrollBar.getElementCount () != 0) - { - for (int i = keyScrollBar.getVisibleStart (); i - <= keyScrollBar.getVisibleEnd (); ++i) - { - keyButtons[i]->setY (keyButtonsYBase - keyButtonsLineHeight * (i - - - keyScrollBar. - getVisibleStart - ())); - labels[i]->setY (keyButtonsYBase - - keyButtonsLineHeight * (i - - keyScrollBar. - getVisibleStart ())); - } - } - - console.update (); - } - - - - void MenuStateKeysetup::showMessageBox (const string & text, - const string & header, - bool toggle) - { - if (!toggle) - { - mainMessageBox.setEnabled (false); - } - - if (!mainMessageBox.getEnabled ()) - { - mainMessageBox.setText (text); - mainMessageBox.setHeader (header); - mainMessageBox.setEnabled (true); - } - else - { - mainMessageBox.setEnabled (false); - } - } - - - void MenuStateKeysetup::keyDown (SDL_KeyboardEvent key) - { - hotkeyChar = extractKeyPressed (key); - //printf("\nkeyDown [%d]\n",hotkeyChar); - - string keyName = ""; - //if(hotkeyChar > SDLK_UNKNOWN && hotkeyChar < SDL_NUM_SCANCODES) { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] keyName [%s] char [%d][%d]\n", __FILE__, - __FUNCTION__, __LINE__, keyName.c_str (), hotkeyChar, - key.keysym.sym); - keyName = SDL_GetKeyName (hotkeyChar); - //printf ("In [%s::%s Line: %d] keyName [%s] char [%d][%d]\n",__FILE__,__FUNCTION__,__LINE__,keyName.c_str(),hotkeyChar,key.keysym.sym); - //} - //key = hotkeyChar; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] keyName [%s] char [%d][%d]\n", __FILE__, - __FUNCTION__, __LINE__, keyName.c_str (), hotkeyChar, - key.keysym.sym); - -// SDLKey keysym = SDLK_UNKNOWN; -// if(keyName == "unknown key" || keyName == "") { -// Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); -// keysym = configKeys.translateSpecialStringToSDLKey(hotkeyChar); -// -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] keysym [%d]\n",__FILE__,__FUNCTION__,__LINE__,keysym); -// -// // SDL skips capital letters -// if(keysym >= 65 && keysym <= 90) { -// keysym = (SDLKey)((int)keysym + 32); -// } -// //if(keysym < 255) { -// // key = keysym; -// //} -// keyName = SDL_GetKeyName(keysym); -// } - - char szCharText[20] = ""; - snprintf (szCharText, 20, "%c", hotkeyChar); - char *utfStr = ConvertToUTF8 (&szCharText[0]); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, " %s [%s][%d][%d][%d]", keyName.c_str (), - utfStr, key.keysym.sym, hotkeyChar, key.keysym.mod); - labelTestValue.setText (szBuf); - //printf ("In [%s::%s Line: %d] szBuf [%s]\n",__FILE__,__FUNCTION__,__LINE__,szBuf); - - delete[]utfStr; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] hotkeyChar [%d]\n", __FILE__, - __FUNCTION__, __LINE__, hotkeyChar); - } - - void MenuStateKeysetup::keyPress (SDL_KeyboardEvent c) - { - } - - void MenuStateKeysetup::keyUp (SDL_KeyboardEvent key) - { - //Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); - - if (hotkeyIndex >= 0) - { - if (hotkeyChar != 0) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] char [%d][%d]\n", __FILE__, - __FUNCTION__, __LINE__, hotkeyChar, key.keysym.sym); - - //string keyName = ""; - //if(hotkeyChar > SDLK_UNKNOWN && hotkeyChar < SDL_NUM_SCANCODES) { - - string keyName = SDL_GetKeyName (key.keysym.sym); - if (StartsWith (keyName, "Keypad ") == false) - { - keyName = SDL_GetKeyName (hotkeyChar); - key.keysym.sym = hotkeyChar; - } - //} - //key.keysym.sym = hotkeyChar; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] keyName [%s] char [%d][%d]\n", - __FILE__, __FUNCTION__, __LINE__, keyName.c_str (), - hotkeyChar, key.keysym.sym); - - //SDLKey keysym = SDLK_UNKNOWN; -// if(keyName == "unknown key" || keyName == "") { -// Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); -// keysym = configKeys.translateSpecialStringToSDLKey(hotkeyChar); -// -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] keysym [%d]\n",__FILE__,__FUNCTION__,__LINE__,keysym); -// -// // SDL skips capital letters -// if(keysym >= 65 && keysym <= 90) { -// keysym = (SDLKey)((int)keysym + 32); -// } -// if(keysym < 255) { -// key = keysym; -// } -// keyName = SDL_GetKeyName(keysym); -// } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] keyName [%s] char [%d][%d]\n", - __FILE__, __FUNCTION__, __LINE__, keyName.c_str (), - hotkeyChar, key.keysym.sym); - - if (keyName != "unknown key") - { - GraphicLabel *label = labels[hotkeyIndex]; - label->setText (keyName); - - pair < string, string > &nameValuePair = - mergedProperties[hotkeyIndex]; - - // Need to distinguish numeric keys to be translated to real keys - // from these ACTUAL sdl keys so surround in quotes. - //printf("KeyUp #1 keyName [%s]\n", keyName.c_str()); - - if (keyName.size () == 1 && keyName[0] >= '0' - && keyName[0] <= '9') - { - keyName = "'" + keyName + "'"; - } - //printf("KeyUp #2 keyName [%s]\n", keyName.c_str()); - - bool isNewUserKeyEntry = true; - for (int i = 0; i < (int) userProperties.size (); ++i) - { - string hotKeyName = userProperties[i].first; - if (nameValuePair.first == hotKeyName) - { -// if(keysym <= SDLK_ESCAPE || keysym > 255) { -// if(keysym <= SDLK_ESCAPE) { -// userProperties[i].second = intToStr(extractKeyPressed(key)); -// } -// else { -// userProperties[i].second = keyName; -// } -// } -// else { -// userProperties[i].second = ""; -// userProperties[i].second.push_back(extractKeyPressed(key)); -// } - userProperties[i].second = keyName; - isNewUserKeyEntry = false; - break; - } - } - if (isNewUserKeyEntry == true) - { - pair < string, string > newNameValuePair = nameValuePair; -// if(keysym <= SDLK_ESCAPE || keysym > 255) { -// if(keysym <= SDLK_ESCAPE) { -// newNameValuePair.second = intToStr(extractKeyPressed(key)); -// } -// else { -// newNameValuePair.second = keyName; -// } -// } -// else { -// newNameValuePair.second = extractKeyPressed(key); -// } - newNameValuePair.second = keyName; - userProperties.push_back (newNameValuePair); - } - } - } - hotkeyIndex = -1; - hotkeyChar = SDLK_UNKNOWN; - } - } - - - } +namespace Glest { + namespace Game { + + + // ===================================================== + // class MenuStateKeysetup + // ===================================================== + + MenuStateKeysetup::MenuStateKeysetup(Program * program, + MainMenu * mainMenu, + ProgramState ** + parentUI) :MenuState(program, + mainMenu, + "config"), + buttonOk("KeySetup", "buttonOk"), buttonDefaults("KeySetup", + "buttonDefaults"), + buttonReturn("KeySetup", "buttonReturn"), + buttonKeyboardSetup("KeySetup", "buttonKeyboardSetup"), + buttonVideoSection("KeySetup", "buttonVideoSection"), + buttonAudioSection("KeySetup", "buttonAudioSection"), + buttonMiscSection("KeySetup", "buttonMiscSection"), + buttonNetworkSettings("KeySetup", "buttonNetworkSettings"), + labelTitle("KeySetup", "labelTitle"), keyScrollBar("KeySetup", + "keyScrollBar"), + mainMessageBox("KeySetup", "mainMessageBox"), + labelTestTitle("KeySetup", "labelTestTitle"), + labelTestValue("KeySetup", "labelTestValue") { + try { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + containerName = "KeySetup"; + + keyButtonsLineHeight = 30; + keyButtonsHeight = 25; + keyButtonsWidth = 400; + keyButtonsXBase = 200; + keyButtonsYBase = 200 + 400 - keyButtonsLineHeight; + keyButtonsToRender = 400 / keyButtonsLineHeight; + int labelWidth = 100; + + this->parentUI = parentUI; + this->console.setOnlyChatMessagesInStoredLines(false); + hotkeyIndex = -1; + hotkeyChar = SDLK_UNKNOWN; + + Lang & lang = Lang::getInstance(); + int buttonStartPos = 170; + int buttonRowPos = 50; + if (this->parentUI == NULL) { + int tabButtonWidth = 200; + int tabButtonHeight = 30; + + buttonAudioSection.init(0, 720, tabButtonWidth, tabButtonHeight); + buttonAudioSection.setFont(CoreData::getInstance(). + getMenuFontVeryBig()); + buttonAudioSection.setFont3D(CoreData::getInstance(). + getMenuFontVeryBig3D()); + buttonAudioSection.setText(lang.getString("Audio")); + // Video Section + buttonVideoSection.init(200, 720, tabButtonWidth, + tabButtonHeight); + buttonVideoSection.setFont(CoreData::getInstance(). + getMenuFontVeryBig()); + buttonVideoSection.setFont3D(CoreData::getInstance(). + getMenuFontVeryBig3D()); + buttonVideoSection.setText(lang.getString("Video")); + //currentLine-=lineOffset; + //MiscSection + buttonMiscSection.init(400, 720, tabButtonWidth, + tabButtonHeight); + buttonMiscSection.setFont(CoreData::getInstance(). + getMenuFontVeryBig()); + buttonMiscSection.setFont3D(CoreData::getInstance(). + getMenuFontVeryBig3D()); + buttonMiscSection.setText(lang.getString("Misc")); + //NetworkSettings + buttonNetworkSettings.init(600, 720, tabButtonWidth, + tabButtonHeight); + buttonNetworkSettings.setFont(CoreData::getInstance(). + getMenuFontVeryBig()); + buttonNetworkSettings.setFont3D(CoreData::getInstance(). + getMenuFontVeryBig3D()); + buttonNetworkSettings.setText(lang.getString("Network")); + + //KeyboardSetup + buttonKeyboardSetup.init(800, 700, tabButtonWidth, + tabButtonHeight + 20); + buttonKeyboardSetup.setFont(CoreData::getInstance(). + getMenuFontVeryBig()); + buttonKeyboardSetup.setFont3D(CoreData::getInstance(). + getMenuFontVeryBig3D()); + buttonKeyboardSetup.setText(lang.getString("Keyboardsetup")); + } + // header + labelTitle.init(375, 650); + labelTitle.setFont(CoreData::getInstance().getMenuFontVeryBig()); + labelTitle.setFont3D(CoreData::getInstance(). + getMenuFontVeryBig3D()); + labelTitle.setText(lang.getString("KeyboardsetupL")); + + labelTestTitle.init(keyButtonsXBase, 155); + labelTestTitle.setFont(CoreData::getInstance(). + getMenuFontNormal()); + labelTestTitle.setFont3D(CoreData::getInstance(). + getMenuFontNormal3D()); + labelTestTitle.setText(lang.getString("KeyboardsetupTest")); + + labelTestValue.init(keyButtonsXBase, 155 - 28); + labelTestValue.setFont(CoreData::getInstance().getMenuFontBig()); + labelTestValue.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + labelTestValue.setRenderBackground(true); + labelTestValue.setMaxEditRenderWidth(keyButtonsWidth); + labelTestValue.setText(""); + + // mainMassegeBox + mainMessageBox.init(lang.getString("Ok")); + mainMessageBox.setEnabled(false); + mainMessageBoxState = 0; + + keyScrollBar.init(800, 200, false, 200, 20); + keyScrollBar.setLength(400); + keyScrollBar.setElementCount(0); + keyScrollBar.setVisibleSize(keyButtonsToRender); + keyScrollBar.setVisibleStart(0); + + // buttons + buttonOk.init(buttonStartPos, buttonRowPos, 100); + buttonOk.setText(lang.getString("Save")); + + buttonReturn.init(buttonStartPos + 110, buttonRowPos, 100); + buttonReturn.setText(lang.getString("Return")); + + buttonDefaults.init(buttonStartPos + 230, buttonRowPos, 125); + buttonDefaults.setText(lang.getString("Defaults")); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + mergedProperties = configKeys.getMergedProperties(); + masterProperties = configKeys.getMasterProperties(); + //userProperties=configKeys.getUserProperties(); + userProperties.clear(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + //throw megaglest_runtime_error("Test!"); + + for (int i = 0; i < (int) mergedProperties.size(); ++i) { + + string keyName = mergedProperties[i].second; + if (keyName.length() > 0) { + //char c = configKeys.translateStringToCharKey(keyName); + SDL_Keycode c = configKeys.translateStringToSDLKey(keyName); + if (c > SDLK_UNKNOWN && c < SDL_NUM_SCANCODES) { + SDL_Keycode keysym = static_cast (c); + // SDL skips capital letters + if (keysym >= 65 && keysym <= 90) { + keysym = (SDL_Keycode) ((int) keysym + 32); + } + keyName = SDL_GetKeyName(keysym); + } else { + keyName = ""; + } + if (keyName == "unknown key" || keyName == "") { + keyName = mergedProperties[i].second; + } + } + + GraphicButton *button = + new GraphicButton(containerName, + string("ScrollButton") + intToStr(i)); + button->init(keyButtonsXBase, keyButtonsYBase, keyButtonsWidth, + keyButtonsHeight); + button->setText(mergedProperties[i].first); + keyButtons.push_back(button); + GraphicLabel *label = + new GraphicLabel(containerName, + string("ScrollLabel") + intToStr(i)); + label->init(keyButtonsXBase + keyButtonsWidth + 5, keyButtonsYBase, + labelWidth, 20); + label->setRenderBackground(true); + label->setMaxEditRenderWidth(105); + label->setText(" " + keyName); + labels.push_back(label); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + keyScrollBar.init(keyButtonsXBase + keyButtonsWidth + labelWidth + + 20, 200, false, 200, 20); + keyScrollBar.setLength(400); + keyScrollBar.setElementCount((int) keyButtons.size()); + keyScrollBar.setVisibleSize(keyButtonsToRender); + keyScrollBar.setVisibleStart(0); + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] Error detected:\n%s\n", + __FILE__, __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + mainMessageBoxState = 1; + showMessageBox("Error: " + string(ex.what()), "Error detected", + false); + } + } + + void MenuStateKeysetup::reloadUI() { + Lang & lang = Lang::getInstance(); + + labelTitle.setText(lang.getString("KeyboardsetupL")); + labelTestTitle.setText(lang.getString("KeyboardsetupTest")); + labelTestValue.setText(""); + + // mainMassegeBox + mainMessageBox.init(lang.getString("Ok")); + + buttonOk.setText(lang.getString("Save")); + buttonReturn.setText(lang.getString("Return")); + buttonDefaults.setText(lang.getString("Defaults")); + } + + void MenuStateKeysetup::cleanup() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + clearUserButtons(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] END\n", __FILE__, + __FUNCTION__, __LINE__); + } + + MenuStateKeysetup::~MenuStateKeysetup() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + cleanup(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] END\n", __FILE__, + __FUNCTION__, __LINE__); + } + + void MenuStateKeysetup::clearUserButtons() { + while (!keyButtons.empty()) { + delete keyButtons.back(); + keyButtons.pop_back(); + } + while (!labels.empty()) { + delete labels.back(); + labels.pop_back(); + } + } + + void MenuStateKeysetup::mouseClick(int x, int y, MouseButton mouseButton) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + + if (mainMessageBox.getEnabled()) { + int button = 0; + if (mainMessageBox.mouseClick(x, y, button)) { + soundRenderer.playFx(coreData.getClickSoundA()); + if (button == 0) { + mainMessageBox.setEnabled(false); + } + } + } else if (keyScrollBar.mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + soundRenderer.playFx(coreData.getClickSoundB()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } else if (buttonReturn.mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + soundRenderer.playFx(coreData.getClickSoundB()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + if (this->parentUI != NULL) { + // Set the parent pointer to NULL so the owner knows it was deleted + *this->parentUI = NULL; + // Delete the main menu + delete mainMenu; + return; + } + mainMenu->setState(new MenuStateRoot(program, mainMenu)); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } else if (buttonDefaults.mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + soundRenderer.playFx(coreData.getClickSoundB()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + string userKeysFile = configKeys.getFileName(true); + + bool result = removeFile(userKeysFile.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] delete file [%s] returned %d\n", + __FILE__, __FUNCTION__, __LINE__, userKeysFile.c_str(), + result); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] delete file [%s] returned %d\n", + __FILE__, __FUNCTION__, __LINE__, + userKeysFile.c_str(), result); + configKeys.reload(); + + if (this->parentUI != NULL) { + // Set the parent pointer to NULL so the owner knows it was deleted + *this->parentUI = NULL; + // Delete the main menu + delete mainMenu; + return; + } + + mainMenu->setState(new MenuStateKeysetup(program, mainMenu)); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } else if (buttonOk.mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + soundRenderer.playFx(coreData.getClickSoundB()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + if (userProperties.empty() == false) { + Config & config = Config::getInstance(); + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys), + std::pair < string, + string >(Config::glestkeys_ini_filename, + Config:: + glestuserkeys_ini_filename), + std::pair < bool, bool >(true, false), + config.getString("GlestKeysIniPath", "")); + string userKeysFile = configKeys.getFileName(true); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line: %d] save file [%s] userProperties.size() = " + MG_SIZE_T_SPECIFIER "\n", __FILE__, __FUNCTION__, __LINE__, + userKeysFile.c_str(), userProperties.size()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] save file [%s] userProperties.size() = " + MG_SIZE_T_SPECIFIER "\n", __FILE__, + __FUNCTION__, __LINE__, + userKeysFile.c_str(), + userProperties.size()); + + configKeys.setUserProperties(userProperties); + configKeys.save(); + configKeys.reload(); + } + + Lang & lang = Lang::getInstance(); + console.addLine(lang.getString("SettingsSaved")); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } else if (keyScrollBar.getElementCount() != 0) { + for (int i = keyScrollBar.getVisibleStart(); i + <= keyScrollBar.getVisibleEnd(); ++i) { + if (keyButtons[i]->mouseClick(x, y)) { + hotkeyIndex = i; + hotkeyChar = SDLK_UNKNOWN; + break; + } + } + } + + if (this->parentUI == NULL) { + if (buttonKeyboardSetup.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + return; + } else if (buttonAudioSection.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptionsSound(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + return; + } else if (buttonNetworkSettings.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptionsNetwork(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + return; + } else if (buttonMiscSection.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptions(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + return; + } else if (buttonVideoSection.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptionsGraphics(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + return; + } + } + } + + void MenuStateKeysetup::mouseUp(int x, int y, + const MouseButton mouseButton) { + if (mouseButton == mbLeft) { + keyScrollBar.mouseUp(x, y); + } + } + + void MenuStateKeysetup::mouseMove(int x, int y, const MouseState * ms) { + buttonReturn.mouseMove(x, y); + buttonOk.mouseMove(x, y); + if (this->parentUI == NULL) { + buttonKeyboardSetup.mouseMove(x, y); + buttonAudioSection.mouseMove(x, y); + buttonNetworkSettings.mouseMove(x, y); + buttonMiscSection.mouseMove(x, y); + buttonVideoSection.mouseMove(x, y); + } + if (ms->get(mbLeft)) { + keyScrollBar.mouseDown(x, y); + } else { + keyScrollBar.mouseMove(x, y); + } + + if (keyScrollBar.getElementCount() != 0) { + for (int i = keyScrollBar.getVisibleStart(); + i <= keyScrollBar.getVisibleEnd(); ++i) { + keyButtons[i]->mouseMove(x, y); + } + } + + } + + void MenuStateKeysetup::render() { + Renderer & renderer = Renderer::getInstance(); + + //printf("MenuStateKeysetup::render A\n"); + + if (mainMessageBox.getEnabled()) { + //printf("MenuStateKeysetup::render B\n"); + renderer.renderMessageBox(&mainMessageBox); + } else { + //printf("MenuStateKeysetup::render C\n"); + renderer.renderButton(&buttonReturn); + renderer.renderButton(&buttonDefaults); + renderer.renderButton(&buttonOk); + if (this->parentUI == NULL) { + renderer.renderButton(&buttonKeyboardSetup); + renderer.renderButton(&buttonVideoSection); + renderer.renderButton(&buttonAudioSection); + renderer.renderButton(&buttonMiscSection); + renderer.renderButton(&buttonNetworkSettings); + } + renderer.renderLabel(&labelTitle); + renderer.renderLabel(&labelTestTitle); + renderer.renderLabel(&labelTestValue); + + if (keyScrollBar.getElementCount() != 0) { + for (int i = keyScrollBar.getVisibleStart(); + i <= keyScrollBar.getVisibleEnd(); ++i) { + if (hotkeyIndex == i) { + renderer.renderButton(keyButtons[i], &YELLOW); + } else { + renderer.renderButton(keyButtons[i]); + } + renderer.renderLabel(labels[i]); + } + } + renderer.renderScrollBar(&keyScrollBar); + } + + renderer.renderConsole(&console); + if (program != NULL) + program->renderProgramMsgBox(); + } + + void MenuStateKeysetup::update() { + //printf("MenuStateKeysetup::update A\n"); + + if (keyScrollBar.getElementCount() != 0) { + for (int i = keyScrollBar.getVisibleStart(); i + <= keyScrollBar.getVisibleEnd(); ++i) { + keyButtons[i]->setY(keyButtonsYBase - keyButtonsLineHeight * (i + - + keyScrollBar. + getVisibleStart + ())); + labels[i]->setY(keyButtonsYBase - + keyButtonsLineHeight * (i - + keyScrollBar. + getVisibleStart())); + } + } + + console.update(); + } + + + + void MenuStateKeysetup::showMessageBox(const string & text, + const string & header, + bool toggle) { + if (!toggle) { + mainMessageBox.setEnabled(false); + } + + if (!mainMessageBox.getEnabled()) { + mainMessageBox.setText(text); + mainMessageBox.setHeader(header); + mainMessageBox.setEnabled(true); + } else { + mainMessageBox.setEnabled(false); + } + } + + + void MenuStateKeysetup::keyDown(SDL_KeyboardEvent key) { + hotkeyChar = extractKeyPressed(key); + //printf("\nkeyDown [%d]\n",hotkeyChar); + + string keyName = ""; + //if(hotkeyChar > SDLK_UNKNOWN && hotkeyChar < SDL_NUM_SCANCODES) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] keyName [%s] char [%d][%d]\n", __FILE__, + __FUNCTION__, __LINE__, keyName.c_str(), hotkeyChar, + key.keysym.sym); + keyName = SDL_GetKeyName(hotkeyChar); + //printf ("In [%s::%s Line: %d] keyName [%s] char [%d][%d]\n",__FILE__,__FUNCTION__,__LINE__,keyName.c_str(),hotkeyChar,key.keysym.sym); + //} + //key = hotkeyChar; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] keyName [%s] char [%d][%d]\n", __FILE__, + __FUNCTION__, __LINE__, keyName.c_str(), hotkeyChar, + key.keysym.sym); + + // SDLKey keysym = SDLK_UNKNOWN; + // if(keyName == "unknown key" || keyName == "") { + // Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); + // keysym = configKeys.translateSpecialStringToSDLKey(hotkeyChar); + // + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] keysym [%d]\n",__FILE__,__FUNCTION__,__LINE__,keysym); + // + // // SDL skips capital letters + // if(keysym >= 65 && keysym <= 90) { + // keysym = (SDLKey)((int)keysym + 32); + // } + // //if(keysym < 255) { + // // key = keysym; + // //} + // keyName = SDL_GetKeyName(keysym); + // } + + char szCharText[20] = ""; + snprintf(szCharText, 20, "%c", hotkeyChar); + char *utfStr = ConvertToUTF8(&szCharText[0]); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, " %s [%s][%d][%d][%d]", keyName.c_str(), + utfStr, key.keysym.sym, hotkeyChar, key.keysym.mod); + labelTestValue.setText(szBuf); + //printf ("In [%s::%s Line: %d] szBuf [%s]\n",__FILE__,__FUNCTION__,__LINE__,szBuf); + + delete[]utfStr; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] hotkeyChar [%d]\n", __FILE__, + __FUNCTION__, __LINE__, hotkeyChar); + } + + void MenuStateKeysetup::keyPress(SDL_KeyboardEvent c) { + } + + void MenuStateKeysetup::keyUp(SDL_KeyboardEvent key) { + //Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); + + if (hotkeyIndex >= 0) { + if (hotkeyChar != 0) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] char [%d][%d]\n", __FILE__, + __FUNCTION__, __LINE__, hotkeyChar, key.keysym.sym); + + //string keyName = ""; + //if(hotkeyChar > SDLK_UNKNOWN && hotkeyChar < SDL_NUM_SCANCODES) { + + string keyName = SDL_GetKeyName(key.keysym.sym); + if (StartsWith(keyName, "Keypad ") == false) { + keyName = SDL_GetKeyName(hotkeyChar); + key.keysym.sym = hotkeyChar; + } + //} + //key.keysym.sym = hotkeyChar; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] keyName [%s] char [%d][%d]\n", + __FILE__, __FUNCTION__, __LINE__, keyName.c_str(), + hotkeyChar, key.keysym.sym); + + //SDLKey keysym = SDLK_UNKNOWN; + // if(keyName == "unknown key" || keyName == "") { + // Config &configKeys = Config::getInstance(std::pair(cfgMainKeys,cfgUserKeys)); + // keysym = configKeys.translateSpecialStringToSDLKey(hotkeyChar); + // + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] keysym [%d]\n",__FILE__,__FUNCTION__,__LINE__,keysym); + // + // // SDL skips capital letters + // if(keysym >= 65 && keysym <= 90) { + // keysym = (SDLKey)((int)keysym + 32); + // } + // if(keysym < 255) { + // key = keysym; + // } + // keyName = SDL_GetKeyName(keysym); + // } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] keyName [%s] char [%d][%d]\n", + __FILE__, __FUNCTION__, __LINE__, keyName.c_str(), + hotkeyChar, key.keysym.sym); + + if (keyName != "unknown key") { + GraphicLabel *label = labels[hotkeyIndex]; + label->setText(keyName); + + pair < string, string > &nameValuePair = + mergedProperties[hotkeyIndex]; + + // Need to distinguish numeric keys to be translated to real keys + // from these ACTUAL sdl keys so surround in quotes. + //printf("KeyUp #1 keyName [%s]\n", keyName.c_str()); + + if (keyName.size() == 1 && keyName[0] >= '0' + && keyName[0] <= '9') { + keyName = "'" + keyName + "'"; + } + //printf("KeyUp #2 keyName [%s]\n", keyName.c_str()); + + bool isNewUserKeyEntry = true; + for (int i = 0; i < (int) userProperties.size(); ++i) { + string hotKeyName = userProperties[i].first; + if (nameValuePair.first == hotKeyName) { + // if(keysym <= SDLK_ESCAPE || keysym > 255) { + // if(keysym <= SDLK_ESCAPE) { + // userProperties[i].second = intToStr(extractKeyPressed(key)); + // } + // else { + // userProperties[i].second = keyName; + // } + // } + // else { + // userProperties[i].second = ""; + // userProperties[i].second.push_back(extractKeyPressed(key)); + // } + userProperties[i].second = keyName; + isNewUserKeyEntry = false; + break; + } + } + if (isNewUserKeyEntry == true) { + pair < string, string > newNameValuePair = nameValuePair; + // if(keysym <= SDLK_ESCAPE || keysym > 255) { + // if(keysym <= SDLK_ESCAPE) { + // newNameValuePair.second = intToStr(extractKeyPressed(key)); + // } + // else { + // newNameValuePair.second = keyName; + // } + // } + // else { + // newNameValuePair.second = extractKeyPressed(key); + // } + newNameValuePair.second = keyName; + userProperties.push_back(newNameValuePair); + } + } + } + hotkeyIndex = -1; + hotkeyChar = SDLK_UNKNOWN; + } + } + + + } } //end namespace diff --git a/source/glest_game/menu/menu_state_keysetup.h b/source/glest_game/menu/menu_state_keysetup.h index 60e3a1fbf..e41d00e9e 100644 --- a/source/glest_game/menu/menu_state_keysetup.h +++ b/source/glest_game/menu/menu_state_keysetup.h @@ -16,91 +16,88 @@ # include "server_line.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// =============================== -// class -// =============================== - typedef vector < GraphicButton * >UserButtons; - typedef vector < GraphicLabel * >GraphicLabels; + // =============================== + // class + // =============================== + typedef vector < GraphicButton * >UserButtons; + typedef vector < GraphicLabel * >GraphicLabels; - class MenuStateKeysetup:public MenuState - { + class MenuStateKeysetup :public MenuState { - private: + private: - GraphicButton buttonOk; - GraphicButton buttonDefaults; - GraphicButton buttonReturn; + GraphicButton buttonOk; + GraphicButton buttonDefaults; + GraphicButton buttonReturn; - GraphicButton buttonKeyboardSetup; // configure the keyboard - GraphicButton buttonVideoSection; - GraphicButton buttonAudioSection; - GraphicButton buttonMiscSection; - GraphicButton buttonNetworkSettings; + GraphicButton buttonKeyboardSetup; // configure the keyboard + GraphicButton buttonVideoSection; + GraphicButton buttonAudioSection; + GraphicButton buttonMiscSection; + GraphicButton buttonNetworkSettings; - GraphicLabel labelTitle; + GraphicLabel labelTitle; - GraphicScrollBar keyScrollBar; - UserButtons keyButtons; - GraphicLabels labels; - int keyButtonsToRender; - int keyButtonsYBase; - int keyButtonsXBase; - int keyButtonsLineHeight; - int keyButtonsHeight; - int keyButtonsWidth; + GraphicScrollBar keyScrollBar; + UserButtons keyButtons; + GraphicLabels labels; + int keyButtonsToRender; + int keyButtonsYBase; + int keyButtonsXBase; + int keyButtonsLineHeight; + int keyButtonsHeight; + int keyButtonsWidth; - GraphicMessageBox mainMessageBox; - int mainMessageBoxState; - vector < pair < string, string > >mergedProperties; - vector < pair < string, string > >masterProperties; - vector < pair < string, string > >userProperties; + GraphicMessageBox mainMessageBox; + int mainMessageBoxState; + vector < pair < string, string > >mergedProperties; + vector < pair < string, string > >masterProperties; + vector < pair < string, string > >userProperties; - int hotkeyIndex; - //char hotkeyChar; - SDL_Keycode hotkeyChar; + int hotkeyIndex; + //char hotkeyChar; + SDL_Keycode hotkeyChar; - GraphicLabel labelTestTitle; - GraphicLabel labelTestValue; + GraphicLabel labelTestTitle; + GraphicLabel labelTestValue; - ProgramState **parentUI; + ProgramState **parentUI; - public: - MenuStateKeysetup (Program * program, MainMenu * mainMenu, - ProgramState ** parentUI = NULL); - virtual ~ MenuStateKeysetup (); + public: + MenuStateKeysetup(Program * program, MainMenu * mainMenu, + ProgramState ** parentUI = NULL); + virtual ~MenuStateKeysetup(); - void mouseClick (int x, int y, MouseButton mouseButton); - void mouseUp (int x, int y, const MouseButton mouseButton); - void mouseMove (int x, int y, const MouseState * mouseState); - void update (); - void render (); + void mouseClick(int x, int y, MouseButton mouseButton); + void mouseUp(int x, int y, const MouseButton mouseButton); + void mouseMove(int x, int y, const MouseState * mouseState); + void update(); + void render(); - virtual void keyDown (SDL_KeyboardEvent key); - virtual void keyPress (SDL_KeyboardEvent c); - virtual void keyUp (SDL_KeyboardEvent key); + virtual void keyDown(SDL_KeyboardEvent key); + virtual void keyPress(SDL_KeyboardEvent c); + virtual void keyUp(SDL_KeyboardEvent key); - virtual bool isInSpecialKeyCaptureEvent () - { - return true; - } + virtual bool isInSpecialKeyCaptureEvent() { + return true; + } - //static void setDisplayMessageFunction(DisplayMessageFunction pDisplayMessage) { pCB_DisplayMessage = pDisplayMessage; } + //static void setDisplayMessageFunction(DisplayMessageFunction pDisplayMessage) { pCB_DisplayMessage = pDisplayMessage; } - void reloadUI (); + void reloadUI(); - private: - void showMessageBox (const string & text, const string & header, - bool toggle); - void clearUserButtons (); - void cleanup (); - }; + private: + void showMessageBox(const string & text, const string & header, + bool toggle); + void clearUserButtons(); + void cleanup(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/menu/menu_state_load_game.cpp b/source/glest_game/menu/menu_state_load_game.cpp index 0ade8ab8b..66be69b07 100644 --- a/source/glest_game/menu/menu_state_load_game.cpp +++ b/source/glest_game/menu/menu_state_load_game.cpp @@ -23,609 +23,525 @@ #include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class MenuStateLoadGame -// ===================================================== + // ===================================================== + // class MenuStateLoadGame + // ===================================================== - MenuStateLoadGame::MenuStateLoadGame (Program * program, - MainMenu * - mainMenu):MenuState (program, - mainMenu, - "root") - { - containerName = "LoadGame"; - Lang & lang = Lang::getInstance (); + MenuStateLoadGame::MenuStateLoadGame(Program * program, + MainMenu * + mainMenu) :MenuState(program, + mainMenu, + "root") { + containerName = "LoadGame"; + Lang & lang = Lang::getInstance(); - int buttonWidth = 120; - int yPos = 40; - int xPos = 20; - int xSpacing = 20; - int slotsToRender = 20; - int slotWidth = 200; + int buttonWidth = 120; + int yPos = 40; + int xPos = 20; + int xSpacing = 20; + int slotsToRender = 20; + int slotWidth = 200; - slotLinesYBase = 650; - slotsLineHeight = 30; - previewTexture = NULL; - buttonToDelete = NULL; + slotLinesYBase = 650; + slotsLineHeight = 30; + previewTexture = NULL; + buttonToDelete = NULL; - selectedButton = NULL; + selectedButton = NULL; - string userData = - Config::getInstance ().getString ("UserData_Root", ""); - if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) != - "") - { - userData = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey); - } - if (userData != "") - { - endPathWithSlash (userData); - } - saveGameDir = userData + "saved/"; + string userData = + Config::getInstance().getString("UserData_Root", ""); + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != + "") { + userData = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey); + } + if (userData != "") { + endPathWithSlash(userData); + } + saveGameDir = userData + "saved/"; - lines[0].init (0, slotLinesYBase + slotsLineHeight); - lines[1].init (0, - slotLinesYBase - (slotsToRender - 1) * slotsLineHeight - - 5); + lines[0].init(0, slotLinesYBase + slotsLineHeight); + lines[1].init(0, + slotLinesYBase - (slotsToRender - 1) * slotsLineHeight - + 5); - headerLabel.registerGraphicComponent (containerName, "headerLabel"); - headerLabel.init (400, 730); - headerLabel.setFont (CoreData::getInstance ().getMenuFontBig ()); - headerLabel.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - headerLabel.setText (lang.getString ("LoadGameMenu")); + headerLabel.registerGraphicComponent(containerName, "headerLabel"); + headerLabel.init(400, 730); + headerLabel.setFont(CoreData::getInstance().getMenuFontBig()); + headerLabel.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + headerLabel.setText(lang.getString("LoadGameMenu")); - noSavedGamesLabel.registerGraphicComponent (containerName, - "noSavedGamesLabel"); - noSavedGamesLabel.init (20, 400); - noSavedGamesLabel.setFont (CoreData::getInstance ().getMenuFontBig ()); - noSavedGamesLabel.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - noSavedGamesLabel.setText (lang.getString ("NoSavedGames")); + noSavedGamesLabel.registerGraphicComponent(containerName, + "noSavedGamesLabel"); + noSavedGamesLabel.init(20, 400); + noSavedGamesLabel.setFont(CoreData::getInstance().getMenuFontBig()); + noSavedGamesLabel.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + noSavedGamesLabel.setText(lang.getString("NoSavedGames")); - savedGamesLabel.registerGraphicComponent (containerName, - "savedGamesLabel"); - savedGamesLabel.init (150, slotLinesYBase + slotsLineHeight + 10); - savedGamesLabel.setFont (CoreData::getInstance ().getMenuFontBig ()); - savedGamesLabel.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - savedGamesLabel.setText (lang.getString ("SavedGames")); + savedGamesLabel.registerGraphicComponent(containerName, + "savedGamesLabel"); + savedGamesLabel.init(150, slotLinesYBase + slotsLineHeight + 10); + savedGamesLabel.setFont(CoreData::getInstance().getMenuFontBig()); + savedGamesLabel.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + savedGamesLabel.setText(lang.getString("SavedGames")); - infoHeaderLabel.registerGraphicComponent (containerName, - "infoHeaderLabel"); - infoHeaderLabel.init (600, slotLinesYBase + slotsLineHeight + 10); - infoHeaderLabel.setFont (CoreData::getInstance ().getMenuFontBig ()); - infoHeaderLabel.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - infoHeaderLabel.setText (lang.getString ("SavegameInfo")); + infoHeaderLabel.registerGraphicComponent(containerName, + "infoHeaderLabel"); + infoHeaderLabel.init(600, slotLinesYBase + slotsLineHeight + 10); + infoHeaderLabel.setFont(CoreData::getInstance().getMenuFontBig()); + infoHeaderLabel.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + infoHeaderLabel.setText(lang.getString("SavegameInfo")); - versionWarningLabel.registerGraphicComponent (containerName, - "versionWarningLabel"); - versionWarningLabel.init (550, 350); - versionWarningLabel.setText (""); - versionWarningLabel.setTextColor (Vec3f (1.0f, 0.5f, 0.5f)); + versionWarningLabel.registerGraphicComponent(containerName, + "versionWarningLabel"); + versionWarningLabel.init(550, 350); + versionWarningLabel.setText(""); + versionWarningLabel.setTextColor(Vec3f(1.0f, 0.5f, 0.5f)); - infoTextLabel.registerGraphicComponent (containerName, "infoTextLabel"); - infoTextLabel.init (550, 310); - infoTextLabel.setText (""); + infoTextLabel.registerGraphicComponent(containerName, "infoTextLabel"); + infoTextLabel.init(550, 310); + infoTextLabel.setText(""); - abortButton.registerGraphicComponent (containerName, "abortButton"); - abortButton.init (xPos, yPos, buttonWidth); - abortButton.setText (lang.getString ("Abort")); - xPos += buttonWidth + xSpacing; - loadButton.registerGraphicComponent (containerName, "loadButton"); - loadButton.init (xPos, yPos, buttonWidth + 80); - loadButton.setText (lang.getString ("LoadGame")); - xPos += buttonWidth + 80 + xSpacing; - deleteButton.registerGraphicComponent (containerName, "deleteButton"); - deleteButton.init (xPos, yPos, buttonWidth); - deleteButton.setText (lang.getString ("Delete")); + abortButton.registerGraphicComponent(containerName, "abortButton"); + abortButton.init(xPos, yPos, buttonWidth); + abortButton.setText(lang.getString("Abort")); + xPos += buttonWidth + xSpacing; + loadButton.registerGraphicComponent(containerName, "loadButton"); + loadButton.init(xPos, yPos, buttonWidth + 80); + loadButton.setText(lang.getString("LoadGame")); + xPos += buttonWidth + 80 + xSpacing; + deleteButton.registerGraphicComponent(containerName, "deleteButton"); + deleteButton.init(xPos, yPos, buttonWidth); + deleteButton.setText(lang.getString("Delete")); - slotsScrollBar.init (500 - 20, - slotLinesYBase - slotsLineHeight * (slotsToRender - - 1), false, - slotWidth, 20); - slotsScrollBar.setLength (slotsLineHeight * slotsToRender); - slotsScrollBar.setElementCount (0); - slotsScrollBar.setVisibleSize (slotsToRender); - slotsScrollBar.setVisibleStart (0); + slotsScrollBar.init(500 - 20, + slotLinesYBase - slotsLineHeight * (slotsToRender - + 1), false, + slotWidth, 20); + slotsScrollBar.setLength(slotsLineHeight * slotsToRender); + slotsScrollBar.setElementCount(0); + slotsScrollBar.setVisibleSize(slotsToRender); + slotsScrollBar.setVisibleStart(0); - listFiles (); - slotsScrollBar.setElementCount ((int) filenames.size ()); + listFiles(); + slotsScrollBar.setElementCount((int) filenames.size()); - mainMessageBox.registerGraphicComponent (containerName, - "mainMessageBox"); - mainMessageBox.init (lang.getString ("Ok"), 450); - mainMessageBox.setEnabled (false); + mainMessageBox.registerGraphicComponent(containerName, + "mainMessageBox"); + mainMessageBox.init(lang.getString("Ok"), 450); + mainMessageBox.setEnabled(false); - GraphicComponent::applyAllCustomProperties (containerName); - } + GraphicComponent::applyAllCustomProperties(containerName); + } - MenuStateLoadGame::~MenuStateLoadGame () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - clearSlots (); + MenuStateLoadGame::~MenuStateLoadGame() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + clearSlots(); - cleanupTexture (&previewTexture); + cleanupTexture(&previewTexture); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] END\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] END\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } - void MenuStateLoadGame::cleanupTexture (Texture2D ** texture) - { - if (texture != NULL && *texture != NULL) - { - (*texture)->end (); - delete *texture; - *texture = NULL; - } - } + void MenuStateLoadGame::cleanupTexture(Texture2D ** texture) { + if (texture != NULL && *texture != NULL) { + (*texture)->end(); + delete *texture; + *texture = NULL; + } + } - void MenuStateLoadGame::clearSlots () - { - while (!slots.empty ()) - { - delete slots.back (); - slots.pop_back (); - slotsGB.pop_back (); - } - } + void MenuStateLoadGame::clearSlots() { + while (!slots.empty()) { + delete slots.back(); + slots.pop_back(); + slotsGB.pop_back(); + } + } - void MenuStateLoadGame::listFiles () - { - int keyButtonsXBase = 2; - int keyButtonsYBase = slotLinesYBase; - int keyButtonsWidth = 476; - int keyButtonsHeight = slotsLineHeight; + void MenuStateLoadGame::listFiles() { + int keyButtonsXBase = 2; + int keyButtonsYBase = slotLinesYBase; + int keyButtonsWidth = 476; + int keyButtonsHeight = slotsLineHeight; - clearSlots (); - // Save the file now - vector < string > paths; - paths.push_back (saveGameDir); - filenames.clear (); - findAll (paths, "*.xml", filenames, true, false, true); - sort (filenames.begin (), filenames.end ()); - for (int i = (int)filenames.size () - 1; i > -1; i--) - { - GraphicButton *button = new GraphicButton (); - button->init (keyButtonsXBase, keyButtonsYBase, keyButtonsWidth, - keyButtonsHeight); - button->setText (filenames[i]); + clearSlots(); + // Save the file now + vector < string > paths; + paths.push_back(saveGameDir); + filenames.clear(); + findAll(paths, "*.xml", filenames, true, false, true); + sort(filenames.begin(), filenames.end()); + for (int i = (int) filenames.size() - 1; i > -1; i--) { + GraphicButton *button = new GraphicButton(); + button->init(keyButtonsXBase, keyButtonsYBase, keyButtonsWidth, + keyButtonsHeight); + button->setText(filenames[i]); - slots.push_back (button); - slotsGB.push_back (button); - } - } + slots.push_back(button); + slotsGB.push_back(button); + } + } - void MenuStateLoadGame::reloadUI () - { - Lang & lang = Lang::getInstance (); + void MenuStateLoadGame::reloadUI() { + Lang & lang = Lang::getInstance(); - infoHeaderLabel.setText (lang.getString ("SavegameInfo")); - savedGamesLabel.setText (lang.getString ("SavedGames")); - noSavedGamesLabel.setText (lang.getString ("NoSavedGames")); - headerLabel.setText (lang.getString ("LoadGameMenu")); + infoHeaderLabel.setText(lang.getString("SavegameInfo")); + savedGamesLabel.setText(lang.getString("SavedGames")); + noSavedGamesLabel.setText(lang.getString("NoSavedGames")); + headerLabel.setText(lang.getString("LoadGameMenu")); - abortButton.setText (lang.getString ("Abort")); - deleteButton.setText (lang.getString ("Delete")); - loadButton.setText (lang.getString ("LoadGame")); + abortButton.setText(lang.getString("Abort")); + deleteButton.setText(lang.getString("Delete")); + loadButton.setText(lang.getString("LoadGame")); - mainMessageBox.init (lang.getString ("Ok"), 450); + mainMessageBox.init(lang.getString("Ok"), 450); - GraphicComponent:: - reloadFontsForRegisterGraphicComponents (containerName); - } + GraphicComponent:: + reloadFontsForRegisterGraphicComponents(containerName); + } - void MenuStateLoadGame::mouseClick (int x, int y, MouseButton mouseButton) - { + void MenuStateLoadGame::mouseClick(int x, int y, MouseButton mouseButton) { - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); - if (mainMessageBox.getEnabled ()) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - int button = 0; - if (mainMessageBox.mouseClick (x, y, button)) - { - mainMessageBox.setEnabled (false); + if (mainMessageBox.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundA()); + int button = 0; + if (mainMessageBox.mouseClick(x, y, button)) { + mainMessageBox.setEnabled(false); - Lang & lang = Lang::getInstance (); - mainMessageBox.init (lang.getString ("Ok"), 450); - } - } - if (abortButton.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateRoot (program, mainMenu)); - } - else if (deleteButton.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - if (selectedButton == NULL) - { - console.addStdMessage ("NothingSelected", true); - } - else - { - string slotname = selectedButton->getText (); - string filename = saveGameDir + selectedButton->getText () + ".xml"; - string jpgfilename = - saveGameDir + selectedButton->getText () + ".xml.jpg"; - string replayfilename = - saveGameDir + selectedButton->getText () + ".xml.replay"; + Lang & lang = Lang::getInstance(); + mainMessageBox.init(lang.getString("Ok"), 450); + } + } + if (abortButton.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateRoot(program, mainMenu)); + } else if (deleteButton.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundB()); + if (selectedButton == NULL) { + console.addStdMessage("NothingSelected", true); + } else { + string slotname = selectedButton->getText(); + string filename = saveGameDir + selectedButton->getText() + ".xml"; + string jpgfilename = + saveGameDir + selectedButton->getText() + ".xml.jpg"; + string replayfilename = + saveGameDir + selectedButton->getText() + ".xml.replay"; - Lang & lang = Lang::getInstance (); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("LoadGameDeletingFile", "", - true).c_str (), filename.c_str ()); - console.addLineOnly (szBuf); + Lang & lang = Lang::getInstance(); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("LoadGameDeletingFile", "", + true).c_str(), filename.c_str()); + console.addLineOnly(szBuf); - for (int i = 0; i < (int) slots.size (); i++) - { - if (slots[i] == selectedButton) - { - if (removeFile (filename) == true) - { - removeFile (jpgfilename); - removeFile (replayfilename); - cleanupTexture (&previewTexture); + for (int i = 0; i < (int) slots.size(); i++) { + if (slots[i] == selectedButton) { + if (removeFile(filename) == true) { + removeFile(jpgfilename); + removeFile(replayfilename); + cleanupTexture(&previewTexture); - infoTextLabel.setText (""); - listFiles (); - slotsScrollBar.setElementCount ((int) filenames.size ()); + infoTextLabel.setText(""); + listFiles(); + slotsScrollBar.setElementCount((int) filenames.size()); - selectedButton = NULL; - } - break; - } - } - } - } - else if (loadButton.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundB ()); + selectedButton = NULL; + } + break; + } + } + } + } else if (loadButton.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundB()); - if (selectedButton == NULL) - { - console.addStdMessage ("NothingSelected", true); - } - else - { - string filename = saveGameDir + selectedButton->getText () + ".xml"; + if (selectedButton == NULL) { + console.addStdMessage("NothingSelected", true); + } else { + string filename = saveGameDir + selectedButton->getText() + ".xml"; - Lang & lang = Lang::getInstance (); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("LoadGameLoadingFile", "", true).c_str (), - filename.c_str ()); - console.addLineOnly (szBuf); + Lang & lang = Lang::getInstance(); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("LoadGameLoadingFile", "", true).c_str(), + filename.c_str()); + console.addLineOnly(szBuf); - try - { - Game::loadGame (filename, program, false); - } - catch (const megaglest_runtime_error & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d]\nError [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); + try { + Game::loadGame(filename, program, false); + } catch (const megaglest_runtime_error & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d]\nError [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); - showMessageBox (ex.what (), lang.getString ("Notice"), false); - } - return; - } - } - else if (slotsScrollBar.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - } - else - { - if (slotsScrollBar.getElementCount () != 0) - { - for (int i = slotsScrollBar.getVisibleStart (); - i <= slotsScrollBar.getVisibleEnd (); ++i) - { - if (slots[i]->mouseClick (x, y) && selectedButton != slots[i]) - { - soundRenderer.playFx (coreData.getClickSoundB ()); + showMessageBox(ex.what(), lang.getString("Notice"), false); + } + return; + } + } else if (slotsScrollBar.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + } else { + if (slotsScrollBar.getElementCount() != 0) { + for (int i = slotsScrollBar.getVisibleStart(); + i <= slotsScrollBar.getVisibleEnd(); ++i) { + if (slots[i]->mouseClick(x, y) && selectedButton != slots[i]) { + soundRenderer.playFx(coreData.getClickSoundB()); - Lang & lang = Lang::getInstance (); - cleanupTexture (&previewTexture); - selectedButton = slots[i]; - string filename = - saveGameDir + selectedButton->getText () + ".xml"; - string screenShotFilename = filename + ".jpg"; - if (fileExists (screenShotFilename) == true) - { - try - { - previewTexture = - GraphicsInterface::getInstance ().getFactory ()-> - newTexture2D (); - if (previewTexture) - { - previewTexture->setMipmap (true); - previewTexture->load (screenShotFilename); - previewTexture->init (); - } - } - catch (const megaglest_runtime_error & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d]\nError [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); + Lang & lang = Lang::getInstance(); + cleanupTexture(&previewTexture); + selectedButton = slots[i]; + string filename = + saveGameDir + selectedButton->getText() + ".xml"; + string screenShotFilename = filename + ".jpg"; + if (fileExists(screenShotFilename) == true) { + try { + previewTexture = + GraphicsInterface::getInstance().getFactory()-> + newTexture2D(); + if (previewTexture) { + previewTexture->setMipmap(true); + previewTexture->load(screenShotFilename); + previewTexture->init(); + } + } catch (const megaglest_runtime_error & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d]\nError [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); - cleanupTexture (&previewTexture); - showMessageBox (ex.what (), lang.getString ("Notice"), - false); - } - } - else - { - previewTexture = NULL; - } + cleanupTexture(&previewTexture); + showMessageBox(ex.what(), lang.getString("Notice"), + false); + } + } else { + previewTexture = NULL; + } - if (fileExists (filename) == true) - { - // Xerces is infinitely slower than rapidxml - xml_engine_parser_type engine_type = XML_RAPIDXML_ENGINE; + if (fileExists(filename) == true) { + // Xerces is infinitely slower than rapidxml + xml_engine_parser_type engine_type = XML_RAPIDXML_ENGINE; #if defined(WANT_XERCES) - if (Config::getInstance (). - getBool ("ForceXMLLoadGameUsingXerces", "false") == true) - { - engine_type = XML_XERCES_ENGINE; - } + if (Config::getInstance(). + getBool("ForceXMLLoadGameUsingXerces", "false") == true) { + engine_type = XML_XERCES_ENGINE; + } #endif - XmlTree xmlTree (engine_type); + XmlTree xmlTree(engine_type); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Before load of XML\n"); - std::map < string, string > mapExtraTagReplacementValues; - try - { - xmlTree.load (filename, - Properties:: - getTagReplacementValues - (&mapExtraTagReplacementValues), true, false, - true); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Before load of XML\n"); + std::map < string, string > mapExtraTagReplacementValues; + try { + xmlTree.load(filename, + Properties:: + getTagReplacementValues + (&mapExtraTagReplacementValues), true, false, + true); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("After load of XML\n"); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("After load of XML\n"); - const XmlNode *rootNode = xmlTree.getRootNode (); - if (rootNode != NULL - && rootNode->hasChild ("zetaglest-saved-game") == true) - { - rootNode = rootNode->getChild ("zetaglest-saved-game"); - } + const XmlNode *rootNode = xmlTree.getRootNode(); + if (rootNode != NULL + && rootNode->hasChild("zetaglest-saved-game") == true) { + rootNode = rootNode->getChild("zetaglest-saved-game"); + } - if (rootNode == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Invalid XML saved game file: [%s]", - filename.c_str ()); - infoTextLabel.setText (szBuf); - return; - } + if (rootNode == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Invalid XML saved game file: [%s]", + filename.c_str()); + infoTextLabel.setText(szBuf); + return; + } - const XmlNode *versionNode = rootNode; - string gameVer = - versionNode->getAttribute ("version")->getValue (); - if (gameVer != glestVersionString - && checkVersionComptability (gameVer, - glestVersionString) == - false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("SavedGameBadVersion").c_str (), - gameVer.c_str (), glestVersionString.c_str ()); - versionWarningLabel.setText (szBuf); - } - else - { - versionWarningLabel.setText (""); - } - XmlNode *gameNode = rootNode->getChild ("Game"); - GameSettings newGameSettings; - newGameSettings.loadGame (gameNode); + const XmlNode *versionNode = rootNode; + string gameVer = + versionNode->getAttribute("version")->getValue(); + if (gameVer != glestVersionString + && checkVersionComptability(gameVer, + glestVersionString) == + false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("SavedGameBadVersion").c_str(), + gameVer.c_str(), glestVersionString.c_str()); + versionWarningLabel.setText(szBuf); + } else { + versionWarningLabel.setText(""); + } + XmlNode *gameNode = rootNode->getChild("Game"); + GameSettings newGameSettings; + newGameSettings.loadGame(gameNode); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("LoadSavedGameInfo").c_str (), - newGameSettings.getMap ().c_str (), - newGameSettings.getTileset ().c_str (), - newGameSettings.getTech ().c_str (), - newGameSettings.getScenario ().c_str (), - newGameSettings.getFactionCount (), - (newGameSettings.getThisFactionIndex () >= 0 - && newGameSettings.getThisFactionIndex () < - newGameSettings. - getFactionCount ()? newGameSettings. - getFactionTypeName (newGameSettings. - getThisFactionIndex ()). - c_str () : "")); - infoTextLabel.setText (szBuf); - } - catch (const megaglest_runtime_error & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s Line: %d]\nError [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("LoadSavedGameInfo").c_str(), + newGameSettings.getMap().c_str(), + newGameSettings.getTileset().c_str(), + newGameSettings.getTech().c_str(), + newGameSettings.getScenario().c_str(), + newGameSettings.getFactionCount(), + (newGameSettings.getThisFactionIndex() >= 0 + && newGameSettings.getThisFactionIndex() < + newGameSettings. + getFactionCount() ? newGameSettings. + getFactionTypeName(newGameSettings. + getThisFactionIndex()). + c_str() : "")); + infoTextLabel.setText(szBuf); + } catch (const megaglest_runtime_error & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d]\nError [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); - showMessageBox (ex.what (), lang.getString ("Notice"), - false); - } - } - else - { - infoTextLabel.setText (""); - } + showMessageBox(ex.what(), lang.getString("Notice"), + false); + } + } else { + infoTextLabel.setText(""); + } - break; - } - } - } - } - } + break; + } + } + } + } + } - void MenuStateLoadGame::mouseUp (int x, int y, - const MouseButton mouseButton) - { - if (mouseButton == mbLeft) - { - slotsScrollBar.mouseUp (x, y); - } - } + void MenuStateLoadGame::mouseUp(int x, int y, + const MouseButton mouseButton) { + if (mouseButton == mbLeft) { + slotsScrollBar.mouseUp(x, y); + } + } - void MenuStateLoadGame::mouseMove (int x, int y, const MouseState * ms) - { - abortButton.mouseMove (x, y); - deleteButton.mouseMove (x, y); - loadButton.mouseMove (x, y); - if (slotsScrollBar.getElementCount () != 0) - { - for (int i = slotsScrollBar.getVisibleStart (); - i <= slotsScrollBar.getVisibleEnd (); ++i) - { - slots[i]->mouseMove (x, y); - } - } - slotsScrollBar.mouseMove (x, y); - } + void MenuStateLoadGame::mouseMove(int x, int y, const MouseState * ms) { + abortButton.mouseMove(x, y); + deleteButton.mouseMove(x, y); + loadButton.mouseMove(x, y); + if (slotsScrollBar.getElementCount() != 0) { + for (int i = slotsScrollBar.getVisibleStart(); + i <= slotsScrollBar.getVisibleEnd(); ++i) { + slots[i]->mouseMove(x, y); + } + } + slotsScrollBar.mouseMove(x, y); + } - void MenuStateLoadGame::render () - { - Renderer & renderer = Renderer::getInstance (); + void MenuStateLoadGame::render() { + Renderer & renderer = Renderer::getInstance(); - renderer.renderLabel (&headerLabel); - renderer.renderLabel (&savedGamesLabel); - renderer.renderLabel (&infoHeaderLabel); - renderer.renderLabel (&infoTextLabel); - if (versionWarningLabel.getText () != "") - renderer.renderLabel (&versionWarningLabel); + renderer.renderLabel(&headerLabel); + renderer.renderLabel(&savedGamesLabel); + renderer.renderLabel(&infoHeaderLabel); + renderer.renderLabel(&infoTextLabel); + if (versionWarningLabel.getText() != "") + renderer.renderLabel(&versionWarningLabel); - renderer.renderButton (&abortButton); - renderer.renderButton (&deleteButton); - renderer.renderButton (&loadButton); + renderer.renderButton(&abortButton); + renderer.renderButton(&deleteButton); + renderer.renderButton(&loadButton); - for (int i = 0; i < (int) sizeof (lines) / (int) sizeof (lines[0]); ++i) - { - renderer.renderLine (&lines[i]); - } + for (int i = 0; i < (int) sizeof(lines) / (int) sizeof(lines[0]); ++i) { + renderer.renderLine(&lines[i]); + } - if (slotsScrollBar.getElementCount () == 0) - { - renderer.renderLabel (&noSavedGamesLabel); - } - else - { - for (int i = slotsScrollBar.getVisibleStart (); - i <= slotsScrollBar.getVisibleEnd (); ++i) - { - if (slots[i] == selectedButton) - { - bool lightedOverride = true; - renderer.renderButton (slots[i], &YELLOW, &lightedOverride); - } - else - { - renderer.renderButton (slots[i]); - } - } - } - renderer.renderScrollBar (&slotsScrollBar); + if (slotsScrollBar.getElementCount() == 0) { + renderer.renderLabel(&noSavedGamesLabel); + } else { + for (int i = slotsScrollBar.getVisibleStart(); + i <= slotsScrollBar.getVisibleEnd(); ++i) { + if (slots[i] == selectedButton) { + bool lightedOverride = true; + renderer.renderButton(slots[i], &YELLOW, &lightedOverride); + } else { + renderer.renderButton(slots[i]); + } + } + } + renderer.renderScrollBar(&slotsScrollBar); - if (previewTexture != NULL) - { - renderer.renderTextureQuad (550, - slotLinesYBase - 300 + slotsLineHeight, - 400, 300, previewTexture, 1.0f); - } + if (previewTexture != NULL) { + renderer.renderTextureQuad(550, + slotLinesYBase - 300 + slotsLineHeight, + 400, 300, previewTexture, 1.0f); + } - if (mainMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&mainMessageBox); - } + if (mainMessageBox.getEnabled()) { + renderer.renderMessageBox(&mainMessageBox); + } - renderer.renderConsole (&console); - if (program != NULL) - program->renderProgramMsgBox (); - } + renderer.renderConsole(&console); + if (program != NULL) + program->renderProgramMsgBox(); + } - void MenuStateLoadGame::update () - { - if (Config::getInstance ().getBool ("AutoTest")) - { - AutoTest::getInstance ().updateNewGame (program, mainMenu); - return; - } - slotsScrollBar.arrangeComponents (slotsGB); - console.update (); - } + void MenuStateLoadGame::update() { + if (Config::getInstance().getBool("AutoTest")) { + AutoTest::getInstance().updateNewGame(program, mainMenu); + return; + } + slotsScrollBar.arrangeComponents(slotsGB); + console.update(); + } - void MenuStateLoadGame::keyDown (SDL_KeyboardEvent key) - { - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - if (isKeyPressed (configKeys.getSDLKey ("SaveGUILayout"), key) == true) - { - GraphicComponent::saveAllCustomProperties (containerName); - } - } + void MenuStateLoadGame::keyDown(SDL_KeyboardEvent key) { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), key) == true) { + GraphicComponent::saveAllCustomProperties(containerName); + } + } - void MenuStateLoadGame::showMessageBox (const string & text, - const string & header, - bool toggle) - { - if (toggle == false) - { - mainMessageBox.setEnabled (false); - } + void MenuStateLoadGame::showMessageBox(const string & text, + const string & header, + bool toggle) { + if (toggle == false) { + mainMessageBox.setEnabled(false); + } - if (mainMessageBox.getEnabled () == false) - { - mainMessageBox.setText (text); - mainMessageBox.setHeader (header); - mainMessageBox.setEnabled (true); - } - else - { - mainMessageBox.setEnabled (false); - } - } + if (mainMessageBox.getEnabled() == false) { + mainMessageBox.setText(text); + mainMessageBox.setHeader(header); + mainMessageBox.setEnabled(true); + } else { + mainMessageBox.setEnabled(false); + } + } - } + } } //end namespace diff --git a/source/glest_game/menu/menu_state_load_game.h b/source/glest_game/menu/menu_state_load_game.h index 1d4c14028..6de689fb0 100644 --- a/source/glest_game/menu/menu_state_load_game.h +++ b/source/glest_game/menu/menu_state_load_game.h @@ -15,71 +15,69 @@ # include "main_menu.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// =============================== -// class MenuStateLoadGame -// =============================== -//typedef vector SaveSlotButtons; - class MenuStateLoadGame:public MenuState - { - private: - GraphicButton loadButton; - GraphicButton deleteButton; - GraphicButton abortButton; - vector < GraphicButton * >slots; - vector < GraphicComponent * >slotsGB; - vector < string > filenames; - GraphicScrollBar slotsScrollBar; - GraphicButton *selectedButton; + // =============================== + // class MenuStateLoadGame + // =============================== + //typedef vector SaveSlotButtons; + class MenuStateLoadGame :public MenuState { + private: + GraphicButton loadButton; + GraphicButton deleteButton; + GraphicButton abortButton; + vector < GraphicButton * >slots; + vector < GraphicComponent * >slotsGB; + vector < string > filenames; + GraphicScrollBar slotsScrollBar; + GraphicButton *selectedButton; - GraphicButton *buttonToDelete; + GraphicButton *buttonToDelete; - Texture2D *previewTexture; + Texture2D *previewTexture; - GraphicLabel headerLabel; - GraphicLabel noSavedGamesLabel; - GraphicLabel savedGamesLabel; - GraphicLabel infoHeaderLabel; - GraphicLabel infoTextLabel; - GraphicLabel versionWarningLabel; + GraphicLabel headerLabel; + GraphicLabel noSavedGamesLabel; + GraphicLabel savedGamesLabel; + GraphicLabel infoHeaderLabel; + GraphicLabel infoTextLabel; + GraphicLabel versionWarningLabel; - GraphicLine lines[2]; + GraphicLine lines[2]; - GraphicMessageBox mainMessageBox; + GraphicMessageBox mainMessageBox; - string saveGameDir; - int slotLinesYBase; - int slotsLineHeight; + string saveGameDir; + int slotLinesYBase; + int slotsLineHeight; - public: - MenuStateLoadGame (Program * program, MainMenu * mainMenu); - ~MenuStateLoadGame (); + public: + MenuStateLoadGame(Program * program, MainMenu * mainMenu); + ~MenuStateLoadGame(); - void mouseClick (int x, int y, MouseButton mouseButton); - void mouseUp (int x, int y, const MouseButton mouseButton); - void mouseMove (int x, int y, const MouseState * mouseState); - void update (); - void render (); - virtual void keyDown (SDL_KeyboardEvent key); + void mouseClick(int x, int y, MouseButton mouseButton); + void mouseUp(int x, int y, const MouseButton mouseButton); + void mouseMove(int x, int y, const MouseState * mouseState); + void update(); + void render(); + virtual void keyDown(SDL_KeyboardEvent key); - void reloadUI (); + void reloadUI(); - private: + private: - void clearSlots (); - void listFiles (); + void clearSlots(); + void listFiles(); - void showMessageBox (const string & text, const string & header, - bool toggle); + void showMessageBox(const string & text, const string & header, + bool toggle); - void cleanupTexture (Texture2D ** texture); - }; + void cleanupTexture(Texture2D ** texture); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/menu/menu_state_masterserver.cpp b/source/glest_game/menu/menu_state_masterserver.cpp index 059ce3a03..bd07f3e20 100644 --- a/source/glest_game/menu/menu_state_masterserver.cpp +++ b/source/glest_game/menu/menu_state_masterserver.cpp @@ -41,1851 +41,1662 @@ #include "cache_manager.h" #include "leak_dumper.h" -namespace Glest -{ - namespace Game - { - - DisplayMessageFunction MenuStateMasterserver::pCB_DisplayMessage = NULL; - - static string IRC_SERVER = "irc.freenode.net"; - static string IRC_CHANNEL = "#zetaglest-lobby"; - -// ===================================================== -// class MenuStateMasterserver -// ===================================================== - - MenuStateMasterserver::MenuStateMasterserver (Program * program, - MainMenu * - mainMenu):MenuState - (program, mainMenu, "masterserver"), - mutexIRCClient (new Mutex (CODE_AT_LINE)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("\n\n\n\n******************** ENTERING MASTERSERVER MENU\n\n\n\n\n"); - - containerName = "MasterServer"; - masterserverParseErrorShown = false; - updateFromMasterserverThread = NULL; - ircClient = NULL; - serverInfoString = "empty"; - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - Lang & lang = Lang::getInstance (); - - //Configure ConsolePosition - consoleIRC.setYPos (60); - consoleIRC.setFont (CoreData::getInstance ().getMenuFontNormal ()); - consoleIRC.setFont3D (CoreData::getInstance ().getMenuFontNormal3D ()); - consoleIRC.setLineHeight (18); - consoleIRC.setOnlyChatMessagesInStoredLines (false); - - serverLinesToRender = 8; - serverLinesLineHeight = 25; - serverLinesYBase = 680; - - userButtonsHeight = 20; - userButtonsWidth = 150; - userButtonsLineHeight = userButtonsHeight + 2; - userButtonsYBase = - serverLinesYBase - (serverLinesToRender) * serverLinesLineHeight - 90; - userButtonsToRender = userButtonsYBase / userButtonsLineHeight; - userButtonsXBase = 1000 - userButtonsWidth; - - userScrollBar.init (1000 - 20, 0, false, 200, 20); - userScrollBar.setLength (userButtonsYBase + userButtonsLineHeight); - userScrollBar.setElementCount (0); - userScrollBar.setVisibleSize (userButtonsToRender); - userScrollBar.setVisibleStart (0); - - userButtonsXBase = 1000 - userButtonsWidth - userScrollBar.getW (); - - serverScrollBar.init (1000 - 20, - serverLinesYBase - - serverLinesLineHeight * (serverLinesToRender - 1), - false, 200, 20); - serverScrollBar.setLength (serverLinesLineHeight * serverLinesToRender); - serverScrollBar.setElementCount (0); - serverScrollBar.setVisibleSize (serverLinesToRender); - serverScrollBar.setVisibleStart (0); - - lines[0].init (0, - userButtonsYBase + userButtonsLineHeight + - serverLinesLineHeight); - lines[1].init (userButtonsXBase - 5, 0, 5, - userButtonsYBase + 2 * userButtonsLineHeight); - lines[1].setHorizontal (false); - - autoRefreshTime = 0; - playServerFoundSound = false; - announcementLoaded = false; - - mainMessageBox.registerGraphicComponent (containerName, - "mainMessageBox"); - mainMessageBox.init (lang.getString ("Ok")); - mainMessageBox.setEnabled (false); - mainMessageBoxState = 0; - - lastRefreshTimer = time (NULL); - - // announcement - announcementLabel.registerGraphicComponent (containerName, - "announcementLabel"); - announcementLabel.init (10, 730); - announcementLabel.setFont (CoreData::getInstance ().getMenuFontBig ()); - announcementLabel.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - announcementLabel.setText (""); - - // versionInfo - versionInfoLabel.registerGraphicComponent (containerName, - "versionInfoLabel"); - versionInfoLabel.init (10, 680); - versionInfoLabel.setFont (CoreData::getInstance ().getMenuFontBig ()); - versionInfoLabel.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - versionInfoLabel.setText (""); - - // header - labelTitle.registerGraphicComponent (containerName, "labelTitle"); - labelTitle.init (410, serverLinesYBase + 45); - labelTitle.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelTitle.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - labelTitle.setText (lang.getString ("AvailableServers")); - - if (Config::getInstance ().getString ("Masterserver", "") == "") - { - labelTitle.setText ("*** " + lang.getString ("AvailableServers")); - } - - // bottom - int buttonPos = 230; - - // Titles for current games - START - int lineIndex = 0; - int lineOffset = 25 * lineIndex; - int i = 5; - int startOffset = serverLinesYBase + 23; - - //general info: - //i+=10; - glestVersionLabel.registerGraphicComponent (containerName, - "glestVersionLabel"); - glestVersionLabel.init (i, startOffset - lineOffset); - glestVersionLabel.setText (lang.getString ("MGVersion")); - - i += 80; - platformLabel.registerGraphicComponent (containerName, - "platformLabel"); - platformLabel.init (i + 15, startOffset - lineOffset); - platformLabel.setText (lang.getString ("MGPlatform")); - -// i+=50; -// binaryCompileDateLabel.registerGraphicComponent(containerName,"binaryCompileDateLabel"); -// binaryCompileDateLabel.init(i,startOffset-lineOffset); -// binaryCompileDateLabel.setText(lang.getString("MGBuildDateTime")); - - //game info: - i += 120; - serverTitleLabel.registerGraphicComponent (containerName, - "serverTitleLabel"); - serverTitleLabel.init (i, startOffset - lineOffset); - serverTitleLabel.setText (lang.getString ("MGGameTitle")); - - i += 170; - countryLabel.registerGraphicComponent (containerName, "countryLabel"); - countryLabel.init (i - 10, startOffset - lineOffset); - countryLabel.setText (lang.getString ("MGGameCountry")); - - i += 60; - -// ipAddressLabel.registerGraphicComponent(containerName,"ipAddressLabel"); -// ipAddressLabel.init(i,startOffset-lineOffset); -// ipAddressLabel.setText(lang.getString("MGGameIP")); -// i+=100; - - //game setup info: - techLabel.registerGraphicComponent (containerName, "techLabel"); - techLabel.init (i, startOffset - lineOffset); - techLabel.setText (lang.getString ("TechTree")); - - i += 165; - mapLabel.registerGraphicComponent (containerName, "mapLabel"); - mapLabel.init (i, startOffset - lineOffset); - mapLabel.setText (lang.getString ("Map")); - - i += 95; -// tilesetLabel.registerGraphicComponent(containerName,"tilesetLabel"); -// tilesetLabel.init(i,startOffset-lineOffset); -// tilesetLabel.setText(lang.getString("Tileset")); -// i+=100; - - activeSlotsLabel.registerGraphicComponent (containerName, - "activeSlotsLabel"); - activeSlotsLabel.init (i, startOffset - lineOffset); - activeSlotsLabel.setText (lang.getString ("MGGameSlots")); - - i += 50; - //externalConnectPort.registerGraphicComponent(containerName,"externalConnectPort"); - //externalConnectPort.init(i,startOffset-lineOffset); - //externalConnectPort.setText(lang.getString("Port")); - - i += 30; - statusLabel.registerGraphicComponent (containerName, "statusLabel"); - statusLabel.init (i + 5, startOffset - lineOffset); - statusLabel.setText (lang.getString ("MGGameStatus")); - - i += 130; - selectButton.registerGraphicComponent (containerName, "selectButton"); - selectButton.init (i - 5, startOffset - lineOffset); - selectButton.setText (lang.getString ("MGJoinGameSlots")); - - // Titles for current games - END - - buttonReturn.registerGraphicComponent (containerName, "buttonReturn"); - buttonReturn.init (50, buttonPos, 150); - - buttonCreateGame.registerGraphicComponent (containerName, - "buttonCreateGame"); - buttonCreateGame.init (275, buttonPos, 150); - - buttonRefresh.registerGraphicComponent (containerName, - "buttonRefresh"); - buttonRefresh.init (500, buttonPos, 150); - - buttonRefresh.setText (lang.getString ("RefreshList")); - buttonReturn.setText (lang.getString ("Return")); - buttonCreateGame.setText (lang.getString ("HostGame")); - labelAutoRefresh.setText (lang.getString ("AutoRefreshRate")); - - labelAutoRefresh.registerGraphicComponent (containerName, - "labelAutoRefresh"); - labelAutoRefresh.init (750, buttonPos + 30); - - listBoxAutoRefresh.registerGraphicComponent (containerName, - "listBoxAutoRefresh"); - listBoxAutoRefresh.init (750, buttonPos); - listBoxAutoRefresh.pushBackItem (lang.getString ("Off")); - listBoxAutoRefresh.pushBackItem ("10 s"); - listBoxAutoRefresh.pushBackItem ("20 s"); - listBoxAutoRefresh.pushBackItem ("30 s"); - listBoxAutoRefresh.setSelectedItemIndex (2); - autoRefreshTime = 10 * listBoxAutoRefresh.getSelectedItemIndex (); - - ircOnlinePeopleLabel.registerGraphicComponent (containerName, - "ircOnlinePeopleLabel"); - ircOnlinePeopleLabel.init (userButtonsXBase, - userButtonsYBase + userButtonsLineHeight); - ircOnlinePeopleLabel.setText (lang.getString ("IRCPeopleOnline")); - - ircOnlinePeopleStatusLabel.registerGraphicComponent (containerName, - "ircOnlinePeopleStatusLabel"); - ircOnlinePeopleStatusLabel.init (userButtonsXBase, - userButtonsYBase + - userButtonsLineHeight - 20); - ircOnlinePeopleStatusLabel.setText (""); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - NetworkManager::getInstance ().end (); - NetworkManager::getInstance ().init (nrClient); - - //console.addLine(lang.getString("ToSwitchOffMusicPress")+" - \""+configKeys.getCharKey("ToggleMusic")+"\""); - - GraphicComponent::applyAllCustomProperties (containerName); - - char szIRCNick[80] = ""; - Chrono seed (true); - srand ((unsigned int) seed.getCurTicks ()); - - int randomNickId = (rand () % 899) + 100; - string netPlayerName = - Config::getInstance ().getString ("NetPlayerName", - Socket::getHostName ().c_str ()); - string ircname = netPlayerName.substr (0, 9); - snprintf (szIRCNick, 80, "ZG_%s_%d", ircname.c_str (), randomNickId); - normalizeNick (szIRCNick); - - currentIrcNick = ircname; - consoleIRC.setStringToHighlight (currentIrcNick); - - lines[2].init (0, consoleIRC.getYPos () - 10, userButtonsXBase, 5); - chatManager.init (&consoleIRC, -1, true, szIRCNick); - chatManager.setXPos (0); - chatManager.setYPos (consoleIRC.getYPos () - 20); - chatManager.setFont (CoreData::getInstance ().getMenuFontNormal ()); - chatManager.setFont3D (CoreData::getInstance (). - getMenuFontNormal3D ()); - - needUpdateFromServer = true; - - static string mutexOwnerId = - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - string ("_") + intToStr (__LINE__); - updateFromMasterserverThread = new SimpleTaskThread (this, 0, 100); - updateFromMasterserverThread->setUniqueID (mutexOwnerId); - updateFromMasterserverThread->start (); - - if (Config::getInstance ().getString ("IRCServer", "") != "") - { - IRC_SERVER = Config::getInstance ().getString ("IRCServer"); - } - ircArgs.push_back (IRC_SERVER); - - if (Config::getInstance ().getString ("IRCNick", "") != "") - { - ircArgs.push_back (Config::getInstance ().getString ("IRCNick")); - } - else - { - ircArgs.push_back (szIRCNick); - } - - if (Config::getInstance ().getString ("IRCChannel", "") != "") - { - IRC_CHANNEL = Config::getInstance ().getString ("IRCChannel"); - } - ircArgs.push_back (IRC_CHANNEL); - - if (Config::getInstance ().getString ("IRCUsername", "") != "") - { - ircArgs.push_back (Config::getInstance ().getString ("IRCUsername")); - } - else - { - ircArgs.push_back (szIRCNick); - } - if (Config::getInstance ().getString ("IRCPassword", "") != "") - { - ircArgs.push_back ("identify " + - Config::getInstance ().getString ("IRCPassword")); - } - else - { - ircArgs.push_back (""); - } - - MutexSafeWrapper safeMutexIRCPtr (mutexIRCClient, - string (extractFileFromDirectoryPath - (__FILE__).c_str ()) + "_" + - intToStr (__LINE__)); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#1 IRCCLient Cache check\n"); - IRCThread *&ircThread = - CacheManager::getCachedItem < - IRCThread * >(GameConstants::ircClientCacheLookupKey); - - // Playername changed so restart the IRC Thread - if (ircThread != NULL && netPlayerName != ircThread->getPlayerName ()) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - ircThread->leaveChannel (); - ircThread->setCallbackObj (NULL); - ircThread->signalQuit (); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - ircThread = NULL; - } - - if (ircThread == NULL) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#2 IRCCLient Cache check\n"); - - static string mutexOwnerId = - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - string ("_") + intToStr (__LINE__); - ircThread = new IRCThread (ircArgs, this); - ircClient = ircThread; - ircClient->setUniqueID (mutexOwnerId); - ircClient->setPlayerName (netPlayerName); - ircClient->setGlestVersionString (glestVersionString); - ircClient->start (); - } - else - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("#3 IRCCLient Cache check\n"); - ircClient = ircThread; - ircClient->setCallbackObj (this); - ircClient->joinChannel (); - } - - if (netPlayerName == "newbie") - { - showMessageBox (lang.getString ("PlayerNameNotSetPrompt"), - lang.getString ("PlayerNameNotSetTitle"), false); - } - //showMessageBox("Go back and set your name in the game options!\n\nAt the moment you are just called >>newbie<< !","Player name not set!",false); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } - - void MenuStateMasterserver::reloadUI () - { - Lang & lang = Lang::getInstance (); - - console.resetFonts (); - consoleIRC.setFont (CoreData::getInstance ().getMenuFontNormal ()); - consoleIRC.setFont3D (CoreData::getInstance ().getMenuFontNormal3D ()); - - mainMessageBox.init (lang.getString ("Ok")); - - announcementLabel.setFont (CoreData::getInstance ().getMenuFontBig ()); - announcementLabel.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - - versionInfoLabel.setFont (CoreData::getInstance ().getMenuFontBig ()); - versionInfoLabel.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - - labelTitle.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelTitle.setFont3D (CoreData::getInstance ().getMenuFontBig3D ()); - labelTitle.setText (lang.getString ("AvailableServers")); - - if (Config::getInstance ().getString ("Masterserver", "") == "") - { - labelTitle.setText ("*** " + lang.getString ("AvailableServers")); - } - - glestVersionLabel.setText (lang.getString ("MGVersion")); - - platformLabel.setText (lang.getString ("MGPlatform")); - - serverTitleLabel.setText (lang.getString ("MGGameTitle")); - - countryLabel.setText (lang.getString ("MGGameCountry")); - - techLabel.setText (lang.getString ("TechTree")); - - mapLabel.setText (lang.getString ("Map")); - - activeSlotsLabel.setText (lang.getString ("MGGameSlots")); - - //externalConnectPort.setText(lang.getString("Port")); - - statusLabel.setText (lang.getString ("MGGameStatus")); - - selectButton.setText (lang.getString ("MGJoinGameSlots")); - - // Titles for current games - END - - buttonRefresh.setText (lang.getString ("RefreshList")); - buttonReturn.setText (lang.getString ("Return")); - buttonCreateGame.setText (lang.getString ("HostGame")); - labelAutoRefresh.setText (lang.getString ("AutoRefreshRate")); - - ircOnlinePeopleLabel.setText (lang.getString ("IRCPeopleOnline")); - - chatManager.setFont (CoreData::getInstance ().getMenuFontNormal ()); - chatManager.setFont3D (CoreData::getInstance ().getMenuFontNormal3D ()); - - GraphicComponent:: - reloadFontsForRegisterGraphicComponents (containerName); - } - -//void MenuStateMasterserver::setConsolePos(int yPos){ -// consoleIRC.setYPos(yPos); -// lines[2].setY(consoleIRC.getYPos()-10); -// chatManager.setYPos(consoleIRC.getYPos()-20); -//} - - void MenuStateMasterserver::setButtonLinePosition (int pos) - { - buttonReturn.setY (pos); - buttonCreateGame.setY (pos); - buttonRefresh.setY (pos); - labelAutoRefresh.setY (pos + 30); - listBoxAutoRefresh.setY (pos); - } - - void MenuStateMasterserver::IRC_CallbackEvent (IRCEventType evt, - const char *origin, - const char **params, - unsigned int count) - { - MutexSafeWrapper safeMutexIRCPtr (mutexIRCClient, - string (extractFileFromDirectoryPath - (__FILE__).c_str ()) + "_" + - intToStr (__LINE__)); - if (ircClient != NULL) - { - if (evt == IRC_evt_exitThread) - { - ircClient->leaveChannel (); - ircClient->setCallbackObj (NULL); - - ircClient = NULL; - } - else if (evt == IRC_evt_chatText) - { - //printf ("===> IRC: '%s' said in channel %s: %s\n",origin ? origin : "someone",params[0], params[1] ); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "%s: %s", origin ? origin : "someone", - params[1]); - string helpSTr = szBuf; - if (helpSTr.find (currentIrcNick) != string::npos) - { - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - static PlaySoundClip snd; - soundRenderer.playFx (snd.getSound (snd.sfxHighlight)); - } - consoleIRC.addLine (szBuf); - } - } - } - - void MenuStateMasterserver::cleanup () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - MutexSafeWrapper - safeMutex ((updateFromMasterserverThread != - NULL ? updateFromMasterserverThread-> - getMutexThreadObjectAccessor () : NULL), - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - "_" + intToStr (__LINE__)); - needUpdateFromServer = false; - safeMutex.ReleaseLock (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - -// if(updateFromMasterserverThread != NULL && -// updateFromMasterserverThread->canShutdown(true) == true) { -// if(updateFromMasterserverThread->shutdownAndWait() == true) { -// delete updateFromMasterserverThread; -// } -// } -// updateFromMasterserverThread = NULL; - if (updateFromMasterserverThread != NULL) - { - updateFromMasterserverThread->signalQuit (); - } - if (updateFromMasterserverThread != NULL - && updateFromMasterserverThread->canShutdown (false) == true - && updateFromMasterserverThread->getRunningStatus () == false) - { - //printf("#2 Ending client SLOT: %d\n",playerIndex); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugNetwork). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugNetwork, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - delete updateFromMasterserverThread; - if (SystemFlags::getSystemSettingType (SystemFlags::debugNetwork). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugNetwork, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - //else if(BaseThread::shutdownAndWait(slotThreadWorker) == true) { - else if (updateFromMasterserverThread != NULL - && updateFromMasterserverThread->canShutdown (true) == true) - { - if (updateFromMasterserverThread->getRunningStatus () == false) - { - //printf("#3 Ending client SLOT: %d\n",playerIndex); - if (SystemFlags::getSystemSettingType (SystemFlags::debugNetwork). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugNetwork, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - delete updateFromMasterserverThread; - if (SystemFlags::getSystemSettingType (SystemFlags::debugNetwork). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugNetwork, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - else - { - updateFromMasterserverThread->setDeleteSelfOnExecutionDone (true); - updateFromMasterserverThread->setDeleteAfterExecute (true); - } - } - //printf("#4 Ending client SLOT: %d\n",playerIndex); - updateFromMasterserverThread = NULL; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - clearServerLines (); - clearUserButtons (); - - MutexSafeWrapper safeMutexIRCPtr (mutexIRCClient, - string (extractFileFromDirectoryPath - (__FILE__).c_str ()) + "_" + - intToStr (__LINE__)); - if (ircClient != NULL) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - ircClient->leaveChannel (); - ircClient->setCallbackObj (NULL); - //ircClient->signalQuit(); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - ircClient = NULL; - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] END\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } - - MenuStateMasterserver::~MenuStateMasterserver () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - cleanup (); - - delete mutexIRCClient; - mutexIRCClient = NULL; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] END\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } - - void MenuStateMasterserver::clearServerLines () - { - while (!serverLines.empty ()) - { - delete serverLines.back (); - serverLines.pop_back (); - } - } - - void MenuStateMasterserver::clearUserButtons () - { - while (!userButtons.empty ()) - { - delete userButtons.back (); - userButtons.pop_back (); - } - } - - void MenuStateMasterserver::mouseClick (int x, int y, - MouseButton mouseButton) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - - if (mainMessageBox.getEnabled ()) - { - int button = 0; - if (mainMessageBox.mouseClick (x, y, button)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - if (button == 0) - { - mainMessageBox.setEnabled (false); - } - } - } - else if (userScrollBar.mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - soundRenderer.playFx (coreData.getClickSoundA ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } - else if (serverScrollBar.mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - soundRenderer.playFx (coreData.getClickSoundA ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } - else if (buttonRefresh.mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - MutexSafeWrapper - safeMutex ((updateFromMasterserverThread != - NULL ? updateFromMasterserverThread-> - getMutexThreadObjectAccessor () : NULL), - string (extractFileFromDirectoryPath (__FILE__). - c_str ()) + "_" + intToStr (__LINE__)); - soundRenderer.playFx (coreData.getClickSoundB ()); - needUpdateFromServer = true; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } - else if (buttonReturn.mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - soundRenderer.playFx (coreData.getClickSoundA ()); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - if (ircClient != NULL && ircClient->isConnected () == true - && ircClient->getHasJoinedChannel () == true) - { - ircClient->SendIRCCmdMessage (IRC_CHANNEL, - " << left the lobby"); - sleep (30); - } - cleanup (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - mainMenu->setState (new MenuStateNewGame (program, mainMenu)); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } - else if (buttonCreateGame.mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - MutexSafeWrapper - safeMutex ((updateFromMasterserverThread != - NULL ? updateFromMasterserverThread-> - getMutexThreadObjectAccessor () : NULL), - string (extractFileFromDirectoryPath (__FILE__). - c_str ()) + "_" + intToStr (__LINE__)); - soundRenderer.playFx (coreData.getClickSoundB ()); - needUpdateFromServer = false; - safeMutex.ReleaseLock (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - if (ircClient != NULL && ircClient->isConnected () == true - && ircClient->getHasJoinedChannel () == true) - { - ircClient->SendIRCCmdMessage (IRC_CHANNEL, - " << tries to create a game"); - sleep (30); - } - cleanup (); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - mainMenu-> - setState (new - MenuStateCustomGame (program, mainMenu, true, - pMasterServer)); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } - else if (listBoxAutoRefresh.mouseClick (x, y)) - { - MutexSafeWrapper - safeMutex ((updateFromMasterserverThread != - NULL ? updateFromMasterserverThread-> - getMutexThreadObjectAccessor () : NULL), - string (extractFileFromDirectoryPath (__FILE__). - c_str ()) + "_" + intToStr (__LINE__)); - soundRenderer.playFx (coreData.getClickSoundA ()); - autoRefreshTime = 10 * listBoxAutoRefresh.getSelectedItemIndex (); - } - else - { - MutexSafeWrapper - safeMutex ((updateFromMasterserverThread != - NULL ? updateFromMasterserverThread-> - getMutexThreadObjectAccessor () : NULL), - string (extractFileFromDirectoryPath (__FILE__). - c_str ()) + "_" + intToStr (__LINE__)); - bool clicked = false; - if (serverScrollBar.getElementCount () != 0) - { - for (int i = serverScrollBar.getVisibleStart (); - i <= serverScrollBar.getVisibleEnd (); ++i) - { - if (serverLines[i]->buttonMouseClick (x, y)) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - clicked = true; - soundRenderer.playFx (coreData.getClickSoundB ()); - string connectServerIP = - serverLines[i]->getMasterServerInfo ()->getIpAddress (); - int connectServerPort = - serverLines[i]->getMasterServerInfo ()-> - getExternalConnectPort (); - bool connected = - connectToServer (connectServerIP, connectServerPort); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - safeMutex.ReleaseLock (); - if (connected) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - - if (ircClient != NULL && ircClient->isConnected () == true - && ircClient->getHasJoinedChannel () == true) - { - ircClient->SendIRCCmdMessage (IRC_CHANNEL, - " << is connecting to '" + - serverLines[i]-> - getMasterServerInfo ()-> - getServerTitle () + "'"); - sleep (30); - } - cleanup (); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - mainMenu-> - setState (new - MenuStateConnectedGame (program, mainMenu, - jmMasterserver)); - } - break; - } - } - } - if (!clicked && userScrollBar.getElementCount () != 0) - { - for (int i = userScrollBar.getVisibleStart (); - i <= userScrollBar.getVisibleEnd (); ++i) - { - if (userButtons[i]->getEnabled () == true - && userButtons[i]->mouseClick (x, y)) - { - //clicked=true; - if (!chatManager.getEditEnabled ()) - { - chatManager.switchOnEdit (); - chatManager.addText (nickList[i] + " "); - } - else - { - chatManager.addText (nickList[i]); - } - break; - } - } - } - } - } - - void MenuStateMasterserver::mouseUp (int x, int y, - const MouseButton mouseButton) - { - if (mouseButton == mbLeft) - { - userScrollBar.mouseUp (x, y); - serverScrollBar.mouseUp (x, y); - } - } - - void MenuStateMasterserver::mouseMove (int x, int y, - const MouseState * ms) - { - MutexSafeWrapper - safeMutex ((updateFromMasterserverThread != - NULL ? updateFromMasterserverThread-> - getMutexThreadObjectAccessor () : NULL), - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - "_" + intToStr (__LINE__)); - - if (mainMessageBox.getEnabled ()) - { - mainMessageBox.mouseMove (x, y); - } - buttonRefresh.mouseMove (x, y); - buttonReturn.mouseMove (x, y); - buttonCreateGame.mouseMove (x, y); - if (ms->get (mbLeft)) - { - userScrollBar.mouseDown (x, y); - serverScrollBar.mouseDown (x, y); - } - else - { - userScrollBar.mouseMove (x, y); - serverScrollBar.mouseMove (x, y); - } - listBoxAutoRefresh.mouseMove (x, y); - - if (serverScrollBar.getElementCount () != 0) - { - for (int i = serverScrollBar.getVisibleStart (); - i <= serverScrollBar.getVisibleEnd (); ++i) - { - serverLines[i]->buttonMouseMove (x, y); - } - } - if (userScrollBar.getElementCount () != 0) - { - for (int i = userScrollBar.getVisibleStart (); - i <= userScrollBar.getVisibleEnd (); ++i) - { - if (userButtons[i]->getEnabled () == true) - { - userButtons[i]->mouseMove (x, y); - } - } - } - - } - - void MenuStateMasterserver::render () - { - Renderer & renderer = Renderer::getInstance (); - - MutexSafeWrapper - safeMutex ((updateFromMasterserverThread != - NULL ? updateFromMasterserverThread-> - getMutexThreadObjectAccessor () : NULL), - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - "_" + intToStr (__LINE__)); - if (mainMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&mainMessageBox); - } - else - { - renderer.renderLabel (&labelTitle, &GREEN); - renderer.renderLabel (&announcementLabel, &YELLOW); - renderer.renderLabel (&versionInfoLabel); - - // Render titles for server games listed - const Vec4f titleLabelColor = CYAN; - - //general info: - renderer.renderLabel (&glestVersionLabel, &titleLabelColor); - renderer.renderLabel (&platformLabel, &titleLabelColor); - //renderer.renderLabel(&binaryCompileDateLabel,&titleLabelColor); - - //game info: - renderer.renderLabel (&serverTitleLabel, &titleLabelColor); - renderer.renderLabel (&countryLabel, &titleLabelColor); - renderer.renderLabel (&statusLabel, &titleLabelColor); - //renderer.renderLabel(&ipAddressLabel,&titleLabelColor); - - //game setup info: - renderer.renderLabel (&techLabel, &titleLabelColor); - renderer.renderLabel (&mapLabel, &titleLabelColor); - //renderer.renderLabel(&tilesetLabel,&titleLabelColor); - renderer.renderLabel (&activeSlotsLabel, &titleLabelColor); - //renderer.renderLabel(&externalConnectPort,&titleLabelColor); - renderer.renderLabel (&selectButton, &titleLabelColor); - - Lang & lang = Lang::getInstance (); - MutexSafeWrapper safeMutexIRCPtr (mutexIRCClient, - string (extractFileFromDirectoryPath - (__FILE__).c_str ()) + "_" + - intToStr (__LINE__)); - if (ircClient != NULL && ircClient->isConnected () == true - && ircClient->getHasJoinedChannel () == true) - { - const Vec4f titleLabelColor = GREEN; - - if (ircOnlinePeopleStatusLabel.getText () != "") - { - ircOnlinePeopleStatusLabel.setText (""); - } - - renderer.renderLabel (&ircOnlinePeopleLabel, &titleLabelColor); - //renderer.renderLabel(&ircOnlinePeopleStatusLabel,&titleLabelColor); - } - else - { - const Vec4f titleLabelColor = RED; - - if (ircOnlinePeopleStatusLabel.getText () != - lang.getString ("Connecting")) - { - ircOnlinePeopleStatusLabel.setText (lang. - getString ("Connecting")); - } - - renderer.renderLabel (&ircOnlinePeopleLabel, &titleLabelColor); - renderer.renderLabel (&ircOnlinePeopleStatusLabel, - &titleLabelColor); - } - safeMutexIRCPtr.ReleaseLock (); - - //const Vec4f titleLabelColorList = YELLOW; - - if (serverScrollBar.getElementCount () != 0) - { - for (int i = serverScrollBar.getVisibleStart (); - i <= serverScrollBar.getVisibleEnd (); ++i) - { - serverLines[i]->render (); - } - } - renderer.renderScrollBar (&serverScrollBar); - - for (int i = 0; i < (int) sizeof (lines) / (int) sizeof (lines[0]); - ++i) - { - renderer.renderLine (&lines[i]); - } - renderer.renderButton (&buttonRefresh); - renderer.renderButton (&buttonReturn); - renderer.renderLabel (&labelAutoRefresh); - renderer.renderButton (&buttonCreateGame); - renderer.renderListBox (&listBoxAutoRefresh); - - if (userScrollBar.getElementCount () != 0) - { - for (int i = userScrollBar.getVisibleStart (); - i <= userScrollBar.getVisibleEnd (); ++i) - { - renderer.renderButton (userButtons[i]); - } - } - renderer.renderScrollBar (&userScrollBar); - if (ircClient != NULL && - ircClient->isConnected () == true && - ircClient->getHasJoinedChannel () == true) - { - renderer.renderChatManager (&chatManager); - } - renderer.renderConsole (&consoleIRC, consoleStoredOnly, 21); - - } - if (program != NULL) - program->renderProgramMsgBox (); - } - - void MenuStateMasterserver::update () - { - MutexSafeWrapper - safeMutex ((updateFromMasterserverThread != - NULL ? updateFromMasterserverThread-> - getMutexThreadObjectAccessor () : NULL), - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - "_" + intToStr (__LINE__)); - if (autoRefreshTime != 0 - && difftime (time (NULL), lastRefreshTimer) >= autoRefreshTime) - { - needUpdateFromServer = true; - lastRefreshTimer = time (NULL); - } - - // calculate button linepos: - setButtonLinePosition (serverLinesYBase - - (serverLinesToRender) * serverLinesLineHeight - - 30); - - if (playServerFoundSound) - { - static PlaySoundClip snd; - SoundRenderer::getInstance ().playFx (snd.getSound (snd.sfxNewServer)); - - //switch on music again!! - Config & config = Config::getInstance (); - float configVolume = (config.getInt ("SoundVolumeMusic") / 100.f); - CoreData::getInstance ().getMenuMusic ()->setVolume (configVolume); - - playServerFoundSound = false; - } - - //console.update(); - - //call the chat manager - chatManager.updateNetwork (); - - //console - consoleIRC.update (); - - MutexSafeWrapper safeMutexIRCPtr (mutexIRCClient, - string (extractFileFromDirectoryPath - (__FILE__).c_str ()) + "_" + - intToStr (__LINE__)); - if (ircClient != NULL) - { - nickList = ircClient->getNickList (); - - if (currentIrcNick != ircClient->getNick ()) - { - currentIrcNick = ircClient->getNick (); - consoleIRC.setStringToHighlight (currentIrcNick); - } - - bool isNew = false; - //check if there is something new - if (oldNickList.size () != nickList.size ()) - { - isNew = true; - } - else - { - for (unsigned int i = 0; i < nickList.size (); ++i) - { - if (nickList[i] != oldNickList[i]) - { - isNew = true; - break; - } - } - } - - if (isNew) - { - clearUserButtons (); - for (int i = 0; i < (int) nickList.size (); ++i) - { - GraphicButton *button = new GraphicButton (); - button->init (userButtonsXBase, userButtonsYBase, - userButtonsWidth, userButtonsHeight); - //button->init(userButtonsXBase,userButtonsYBase-userButtonsLineHeight*i,userButtonsWidth,userButtonsHeight); - button->setFont (CoreData::getInstance ().getDisplayFontSmall ()); - button->setFont3D (CoreData::getInstance (). - getDisplayFontSmall3D ()); - - if (strncmp (&nickList[i][0], "ZG_", 3) == 0) { - button->setText (nickList[i].substr(3,nickList[i].length()-7)); - } else { - button->setText (nickList[i]); - } - - if (strncmp (&nickList[i][0], "ZG_", 3) != 0 - || &nickList[i][0] == currentIrcNick) - { - button->setEnabled (false); - button->setEditable (false); - button->setCustomTexture (CoreData::getInstance (). - getCustomTexture ()); - button->setUseCustomTexture (true); - } - - userButtons.push_back (button); - - } - userScrollBar.setElementCount ((int) userButtons.size ()); - oldNickList = nickList; - chatManager.setAutoCompleteTextList (oldNickList); - } - if (userScrollBar.getElementCount () != 0) - { - for (int i = userScrollBar.getVisibleStart (); - i <= userScrollBar.getVisibleEnd (); ++i) - { - userButtons[i]->setY (userButtonsYBase - - userButtonsLineHeight * (i - - userScrollBar. - getVisibleStart - ())); - } - } - } - safeMutexIRCPtr.ReleaseLock (); - if (serverInfoString != "empty") - { - rebuildServerLines (serverInfoString); - serverInfoString = "empty"; - } - - serverScrollBar.setElementCount ((int) serverLines.size ()); - if (serverScrollBar.getElementCount () != 0) - { - for (int i = serverScrollBar.getVisibleStart (); - i <= serverScrollBar.getVisibleEnd (); ++i) - { - serverLines[i]->setY (serverLinesYBase - - serverLinesLineHeight * (i - - serverScrollBar. - getVisibleStart ())); - } - } - - if (threadedErrorMsg != "") - { - std::string sError = threadedErrorMsg; - threadedErrorMsg = ""; - - if (pCB_DisplayMessage != NULL) - { - pCB_DisplayMessage (sError.c_str (), false); - } - else - { - throw megaglest_runtime_error (sError.c_str ()); - } - } - } - - void MenuStateMasterserver::simpleTask (BaseThread * callingThread, - void *userdata) - { - if (callingThread->getQuitStatus () == true) - { - return; - } - MutexSafeWrapper safeMutex (callingThread-> - getMutexThreadObjectAccessor (), - string (extractFileFromDirectoryPath - (__FILE__).c_str ()) + "_" + - intToStr (__LINE__)); - bool needUpdate = needUpdateFromServer; - - if (needUpdate == true) - { - try - { - - if (callingThread->getQuitStatus () == true) - { - return; - } - - needUpdateFromServer = false; - - if (announcementLoaded == false) - { - string announcementURL = - Config::getInstance ().getString ("AnnouncementURL", - "http://zetaglest.dreamhosters.com/files/announcement.txt"); - if (announcementURL != "") - { - - safeMutex.ReleaseLock (true); - CURL *handle = SystemFlags::initHTTP (); - std::string announcementTxt = - SystemFlags::getHTTP (announcementURL, handle); - SystemFlags::cleanupHTTP (&handle); - if (callingThread->getQuitStatus () == true) - { - return; - } - safeMutex.Lock (); - - if (StartsWith - (announcementTxt, - "Announcement from Masterserver:") == true) - { - int newlineCount = 0; - size_t lastIndex = 0; - - //announcementLabel.setText(announcementTxt); - consoleIRC.addLine (announcementTxt, true, - Vec3f (1.0f, 1.0f, 0.0f)); - - while (true) - { - lastIndex = announcementTxt.find ("\n", lastIndex + 1); - if (lastIndex == string::npos) - { - break; - } - else - { - newlineCount++; - } - } - newlineCount--; // remove my own line - for (int i = 0; i < newlineCount; ++i) - { - consoleIRC.addLine (""); - } - } - } - consoleIRC. - addLine ("---------------------------------------------"); - string versionURL = - Config::getInstance ().getString ("VersionURL", - "http://zetaglest.dreamhosters.com/files/versions/") - + glestVersionString + ".txt"; - //printf("\nversionURL=%s\n",versionURL.c_str()); - if (versionURL != "") - { - safeMutex.ReleaseLock (true); - CURL *handle = SystemFlags::initHTTP (); - std::string versionTxt = - SystemFlags::getHTTP (versionURL, handle); - SystemFlags::cleanupHTTP (&handle); - if (callingThread->getQuitStatus () == true) - { - return; - } - safeMutex.Lock (); - - if (StartsWith (versionTxt, "Version info:") == true) - { - int newlineCount = 0; - size_t lastIndex = 0; - - //versionInfoLabel.setText(versionTxt); - consoleIRC.addLine (versionTxt, true, - Vec3f (1.0f, 0.0f, 0.0f)); - - while (true) - { - lastIndex = versionTxt.find ("\n", lastIndex + 1); - if (lastIndex == string::npos) - { - break; - } - else - { - newlineCount++; - } - } - newlineCount--; // remove my own line - for (int i = 0; i < newlineCount; ++i) - { - consoleIRC.addLine (""); - } - } - } - consoleIRC. - addLine ("---------------------------------------------"); - // write hint to console: - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - consoleIRC.addLine (Lang::getInstance (). - getString ("ToSwitchOffMusicPress") + - " - \"" + - configKeys.getString ("ToggleMusic") + "\""); - - announcementLoaded = true; - } - - //Lang &lang= Lang::getInstance(); - try - { - if (Config::getInstance ().getString ("Masterserver", "") != "") - { - - safeMutex.ReleaseLock (true); - CURL *handle = SystemFlags::initHTTP (); - - string playerUUID = - "?uuid=" + - SystemFlags::escapeURL (Config::getInstance (). - getString ("PlayerId", "")); - - string baseURL = - Config::getInstance ().getString ("Masterserver"); - if (baseURL != "") - { - endPathWithSlash (baseURL, false); - } - - std::string localServerInfoString = - SystemFlags::getHTTP (baseURL + "showServersForGlest.php" + - playerUUID, handle); - SystemFlags::cleanupHTTP (&handle); - if (callingThread->getQuitStatus () == true) - { - return; - } - safeMutex.Lock (); - - serverInfoString = localServerInfoString; - } - } - catch (const exception & ex) - { - serverInfoString = ex.what (); - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line %d] error during Internet game status update: [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - ex.what ()); - } - } - catch (const exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - e.what ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d, error [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - e.what ()); - threadedErrorMsg = e.what (); - } - } - } - - void MenuStateMasterserver::rebuildServerLines (const string & serverInfo) - { - int numberOfOldServerLines = (int) serverLines.size (); - clearServerLines (); - Lang & lang = Lang::getInstance (); - try - { - if (serverInfo != "") - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("--------------> serverInfo [%s]\n", serverInfo.c_str ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - std::vector < std::string > serverList; - Tokenize (serverInfo, serverList, "\n"); - for (int i = 0; i < (int) serverList.size (); i++) - { - string & server = serverList[i]; - if (trim (server) == "") - { - continue; - } - std::vector < std::string > serverEntities; - Tokenize (server, serverEntities, "|"); - const int MIN_FIELDS_EXPECTED = 14; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("--------------> server [%s] serverEntities.size() = " - MG_SIZE_T_SPECIFIER " MIN_FIELDS_EXPECTED = %d\n", - server.c_str (), serverEntities.size (), - MIN_FIELDS_EXPECTED); - - if ((int) serverEntities.size () >= MIN_FIELDS_EXPECTED) - { - labelTitle.setText (lang.getString ("AvailableServers")); - - if (Config::getInstance ().getString ("Masterserver", "") == "") - { - labelTitle.setText ("*** " + - lang.getString ("AvailableServers")); - } - - MasterServerInfo *masterServerInfo = new MasterServerInfo (); - - //general info: - masterServerInfo->setGlestVersion (serverEntities[0]); - masterServerInfo->setPlatform (serverEntities[1]); - masterServerInfo->setBinaryCompileDate (serverEntities[2]); - - //game info: - masterServerInfo->setServerTitle (serverEntities[3]); - masterServerInfo->setIpAddress (serverEntities[4]); - - //game setup info: - masterServerInfo->setTech (serverEntities[5]); - masterServerInfo->setMap (serverEntities[6]); - masterServerInfo->setTileset (serverEntities[7]); - masterServerInfo->setActiveSlots (strToInt (serverEntities[8])); - masterServerInfo-> - setNetworkSlots (strToInt (serverEntities[9])); - masterServerInfo-> - setConnectedClients (strToInt (serverEntities[10])); - masterServerInfo-> - setExternalConnectPort (strToInt (serverEntities[11])); - masterServerInfo->setCountry (serverEntities[12]); - masterServerInfo->setStatus (strToInt (serverEntities[13])); - - //printf("--------------> Country [%s] Status [%d]\n",masterServerInfo->getCountry().c_str(),masterServerInfo->getStatus()); - - //printf("Getting Ping time for host %s\n",masterServerInfo->getIpAddress().c_str()); - //float pingTime = Socket::getAveragePingMS(masterServerInfo->getIpAddress().c_str(),1); - //printf("Ping time = %f\n",pingTime); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "%s", - masterServerInfo->getServerTitle ().c_str ()); - masterServerInfo->setServerTitle (szBuf); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - serverLines. - push_back (new - ServerLine (masterServerInfo, i, serverLinesYBase, - serverLinesLineHeight, containerName)); - delete masterServerInfo; - } - else - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - Lang & lang = Lang::getInstance (); - labelTitle.setText ("*** " + - lang.getString ("AvailableServers") + "[" + - intToStr (serverEntities.size ()) + "][" + - intToStr (MIN_FIELDS_EXPECTED) + "] [" + - serverInfo + "]"); - - if (masterserverParseErrorShown == false) - { - masterserverParseErrorShown = true; - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line %d] error, no masterserver defined!\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } - - } - catch (const exception & ex) - { - labelTitle.setText ("*** " + lang.getString ("AvailableServers") + - " [" + ex.what () + "]"); - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line %d] error during Internet game status update: [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - ex.what ()); - } - - if ((int) serverLines.size () > numberOfOldServerLines) - { - playServerFoundSound = true; - } - } - - - bool MenuStateMasterserver::connectToServer (string ipString, int port) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] START ipString='%s'\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, ipString.c_str ()); - - ClientInterface *clientInterface = - NetworkManager::getInstance ().getClientInterface (); - //Config& config= Config::getInstance(); - Ip serverIp (ipString); - - //int serverPort = Config::getInstance().getInt("PortServer",intToStr(GameConstants::serverPort).c_str()); - int serverPort = port; - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] try to connect to [%s] serverPort = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, - serverIp.getString ().c_str (), serverPort); - clientInterface->connect (serverIp, serverPort); - if (clientInterface->isConnected () == false) - { - NetworkManager::getInstance ().end (); - NetworkManager::getInstance ().init (nrClient); - - mainMessageBoxState = 1; - Lang & lang = Lang::getInstance (); - showMessageBox (lang.getString ("CouldNotConnect"), - lang.getString ("ConnectionFailed"), false); - return false; - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] connection failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); - } - else - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] connected to [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, - serverIp.getString ().c_str ()); - - //save server ip - //config.setString("ServerIp", serverIp.getString()); - //config.save(); - - for (time_t elapsedWait = time (NULL); - clientInterface->getIntroDone () == false && - clientInterface->isConnected () && - difftime (time (NULL), elapsedWait) <= 8;) - { - if (clientInterface->isConnected ()) - { - //update lobby - clientInterface->updateLobby (); - sleep (0); - //this->render(); - } - } - if (clientInterface->isConnected () == true && - clientInterface->getIntroDone () == true) - { - return true; - } - - return false; - } - } - - void MenuStateMasterserver::showMessageBox (const string & text, - const string & header, - bool toggle) - { - if (!toggle) - { - mainMessageBox.setEnabled (false); - } - - if (!mainMessageBox.getEnabled ()) - { - mainMessageBox.setText (text); - mainMessageBox.setHeader (header); - mainMessageBox.setEnabled (true); - } - else - { - mainMessageBox.setEnabled (false); - } - } - - - bool MenuStateMasterserver::textInput (std::string text) - { - if (ircClient != NULL && ircClient->isConnected () == true - && ircClient->getHasJoinedChannel () == true) - { - return chatManager.textInput (text); - } - return false; - } - - void MenuStateMasterserver::keyDown (SDL_KeyboardEvent key) - { - //printf("In [%s::%s Line: %d] key [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,key.keysym.sym); - - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - - if (ircClient != NULL && ircClient->isConnected () == true - && ircClient->getHasJoinedChannel () == true) - { - //chatmanger only if connected to irc! - if (chatManager.getEditEnabled () == true) - { - //printf("keyDown key [%d] chatManager.getText() [%s]\n",key,chatManager.getText().c_str()); - MutexSafeWrapper safeMutexIRCPtr (mutexIRCClient, - string - (extractFileFromDirectoryPath - (__FILE__).c_str ()) + "_" + - intToStr (__LINE__)); - //if (key == vkReturn && ircClient != NULL) { - if (isKeyPressed (SDLK_RETURN, key, false) == true - && ircClient != NULL) - { - ircClient->SendIRCCmdMessage (IRC_CHANNEL, - chatManager.getText ()); - } - } - chatManager.keyDown (key); - } - if (chatManager.getEditEnabled () == false) - { - //if(key == configKeys.getCharKey("ToggleMusic")) { - if (isKeyPressed (configKeys.getSDLKey ("ToggleMusic"), key) == true) - { - Config & config = Config::getInstance (); - Lang & lang = Lang::getInstance (); - - float configVolume = (config.getInt ("SoundVolumeMusic") / 100.f); - float currentVolume = - CoreData::getInstance ().getMenuMusic ()->getVolume (); - if (currentVolume > 0) - { - CoreData::getInstance ().getMenuMusic ()->setVolume (0.f); - consoleIRC.addLine (lang.getString ("GameMusic") + " " + - lang.getString ("Off")); - } - else - { - CoreData::getInstance ().getMenuMusic ()-> - setVolume (configVolume); - //If the config says zero, use the default music volume - //gameMusic->setVolume(configVolume ? configVolume : 0.9); - consoleIRC.addLine (lang.getString ("GameMusic")); - } - } - //else if(key == configKeys.getCharKey("SaveGUILayout")) { - else if (isKeyPressed (configKeys.getSDLKey ("SaveGUILayout"), key) == - true) - { - bool saved = - GraphicComponent::saveAllCustomProperties (containerName); - Lang & lang = Lang::getInstance (); - consoleIRC.addLine (lang.getString ("GUILayoutSaved") + " [" + - (saved ? lang.getString ("Yes") : lang. - getString ("No")) + "]"); - } - } - } - - } +namespace Glest { + namespace Game { + + DisplayMessageFunction MenuStateMasterserver::pCB_DisplayMessage = NULL; + + static string IRC_SERVER = "irc.freenode.net"; + static string IRC_CHANNEL = "#zetaglest-lobby"; + + // ===================================================== + // class MenuStateMasterserver + // ===================================================== + + MenuStateMasterserver::MenuStateMasterserver(Program * program, + MainMenu * + mainMenu) :MenuState + (program, mainMenu, "masterserver"), + mutexIRCClient(new Mutex(CODE_AT_LINE)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("\n\n\n\n******************** ENTERING MASTERSERVER MENU\n\n\n\n\n"); + + containerName = "MasterServer"; + masterserverParseErrorShown = false; + updateFromMasterserverThread = NULL; + ircClient = NULL; + serverInfoString = "empty"; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + Lang & lang = Lang::getInstance(); + + //Configure ConsolePosition + consoleIRC.setYPos(60); + consoleIRC.setFont(CoreData::getInstance().getMenuFontNormal()); + consoleIRC.setFont3D(CoreData::getInstance().getMenuFontNormal3D()); + consoleIRC.setLineHeight(18); + consoleIRC.setOnlyChatMessagesInStoredLines(false); + + serverLinesToRender = 8; + serverLinesLineHeight = 25; + serverLinesYBase = 680; + + userButtonsHeight = 20; + userButtonsWidth = 150; + userButtonsLineHeight = userButtonsHeight + 2; + userButtonsYBase = + serverLinesYBase - (serverLinesToRender) * serverLinesLineHeight - 90; + userButtonsToRender = userButtonsYBase / userButtonsLineHeight; + userButtonsXBase = 1000 - userButtonsWidth; + + userScrollBar.init(1000 - 20, 0, false, 200, 20); + userScrollBar.setLength(userButtonsYBase + userButtonsLineHeight); + userScrollBar.setElementCount(0); + userScrollBar.setVisibleSize(userButtonsToRender); + userScrollBar.setVisibleStart(0); + + userButtonsXBase = 1000 - userButtonsWidth - userScrollBar.getW(); + + serverScrollBar.init(1000 - 20, + serverLinesYBase - + serverLinesLineHeight * (serverLinesToRender - 1), + false, 200, 20); + serverScrollBar.setLength(serverLinesLineHeight * serverLinesToRender); + serverScrollBar.setElementCount(0); + serverScrollBar.setVisibleSize(serverLinesToRender); + serverScrollBar.setVisibleStart(0); + + lines[0].init(0, + userButtonsYBase + userButtonsLineHeight + + serverLinesLineHeight); + lines[1].init(userButtonsXBase - 5, 0, 5, + userButtonsYBase + 2 * userButtonsLineHeight); + lines[1].setHorizontal(false); + + autoRefreshTime = 0; + playServerFoundSound = false; + announcementLoaded = false; + + mainMessageBox.registerGraphicComponent(containerName, + "mainMessageBox"); + mainMessageBox.init(lang.getString("Ok")); + mainMessageBox.setEnabled(false); + mainMessageBoxState = 0; + + lastRefreshTimer = time(NULL); + + // announcement + announcementLabel.registerGraphicComponent(containerName, + "announcementLabel"); + announcementLabel.init(10, 730); + announcementLabel.setFont(CoreData::getInstance().getMenuFontBig()); + announcementLabel.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + announcementLabel.setText(""); + + // versionInfo + versionInfoLabel.registerGraphicComponent(containerName, + "versionInfoLabel"); + versionInfoLabel.init(10, 680); + versionInfoLabel.setFont(CoreData::getInstance().getMenuFontBig()); + versionInfoLabel.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + versionInfoLabel.setText(""); + + // header + labelTitle.registerGraphicComponent(containerName, "labelTitle"); + labelTitle.init(410, serverLinesYBase + 45); + labelTitle.setFont(CoreData::getInstance().getMenuFontBig()); + labelTitle.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelTitle.setText(lang.getString("AvailableServers")); + + if (Config::getInstance().getString("Masterserver", "") == "") { + labelTitle.setText("*** " + lang.getString("AvailableServers")); + } + + // bottom + int buttonPos = 230; + + // Titles for current games - START + int lineIndex = 0; + int lineOffset = 25 * lineIndex; + int i = 5; + int startOffset = serverLinesYBase + 23; + + //general info: + //i+=10; + glestVersionLabel.registerGraphicComponent(containerName, + "glestVersionLabel"); + glestVersionLabel.init(i, startOffset - lineOffset); + glestVersionLabel.setText(lang.getString("MGVersion")); + + i += 80; + platformLabel.registerGraphicComponent(containerName, + "platformLabel"); + platformLabel.init(i + 15, startOffset - lineOffset); + platformLabel.setText(lang.getString("MGPlatform")); + + // i+=50; + // binaryCompileDateLabel.registerGraphicComponent(containerName,"binaryCompileDateLabel"); + // binaryCompileDateLabel.init(i,startOffset-lineOffset); + // binaryCompileDateLabel.setText(lang.getString("MGBuildDateTime")); + + //game info: + i += 120; + serverTitleLabel.registerGraphicComponent(containerName, + "serverTitleLabel"); + serverTitleLabel.init(i, startOffset - lineOffset); + serverTitleLabel.setText(lang.getString("MGGameTitle")); + + i += 170; + countryLabel.registerGraphicComponent(containerName, "countryLabel"); + countryLabel.init(i - 10, startOffset - lineOffset); + countryLabel.setText(lang.getString("MGGameCountry")); + + i += 60; + + // ipAddressLabel.registerGraphicComponent(containerName,"ipAddressLabel"); + // ipAddressLabel.init(i,startOffset-lineOffset); + // ipAddressLabel.setText(lang.getString("MGGameIP")); + // i+=100; + + //game setup info: + techLabel.registerGraphicComponent(containerName, "techLabel"); + techLabel.init(i, startOffset - lineOffset); + techLabel.setText(lang.getString("TechTree")); + + i += 165; + mapLabel.registerGraphicComponent(containerName, "mapLabel"); + mapLabel.init(i, startOffset - lineOffset); + mapLabel.setText(lang.getString("Map")); + + i += 95; + // tilesetLabel.registerGraphicComponent(containerName,"tilesetLabel"); + // tilesetLabel.init(i,startOffset-lineOffset); + // tilesetLabel.setText(lang.getString("Tileset")); + // i+=100; + + activeSlotsLabel.registerGraphicComponent(containerName, + "activeSlotsLabel"); + activeSlotsLabel.init(i, startOffset - lineOffset); + activeSlotsLabel.setText(lang.getString("MGGameSlots")); + + i += 50; + //externalConnectPort.registerGraphicComponent(containerName,"externalConnectPort"); + //externalConnectPort.init(i,startOffset-lineOffset); + //externalConnectPort.setText(lang.getString("Port")); + + i += 30; + statusLabel.registerGraphicComponent(containerName, "statusLabel"); + statusLabel.init(i + 5, startOffset - lineOffset); + statusLabel.setText(lang.getString("MGGameStatus")); + + i += 130; + selectButton.registerGraphicComponent(containerName, "selectButton"); + selectButton.init(i - 5, startOffset - lineOffset); + selectButton.setText(lang.getString("MGJoinGameSlots")); + + // Titles for current games - END + + buttonReturn.registerGraphicComponent(containerName, "buttonReturn"); + buttonReturn.init(50, buttonPos, 150); + + buttonCreateGame.registerGraphicComponent(containerName, + "buttonCreateGame"); + buttonCreateGame.init(275, buttonPos, 150); + + buttonRefresh.registerGraphicComponent(containerName, + "buttonRefresh"); + buttonRefresh.init(500, buttonPos, 150); + + buttonRefresh.setText(lang.getString("RefreshList")); + buttonReturn.setText(lang.getString("Return")); + buttonCreateGame.setText(lang.getString("HostGame")); + labelAutoRefresh.setText(lang.getString("AutoRefreshRate")); + + labelAutoRefresh.registerGraphicComponent(containerName, + "labelAutoRefresh"); + labelAutoRefresh.init(750, buttonPos + 30); + + listBoxAutoRefresh.registerGraphicComponent(containerName, + "listBoxAutoRefresh"); + listBoxAutoRefresh.init(750, buttonPos); + listBoxAutoRefresh.pushBackItem(lang.getString("Off")); + listBoxAutoRefresh.pushBackItem("10 s"); + listBoxAutoRefresh.pushBackItem("20 s"); + listBoxAutoRefresh.pushBackItem("30 s"); + listBoxAutoRefresh.setSelectedItemIndex(2); + autoRefreshTime = 10 * listBoxAutoRefresh.getSelectedItemIndex(); + + ircOnlinePeopleLabel.registerGraphicComponent(containerName, + "ircOnlinePeopleLabel"); + ircOnlinePeopleLabel.init(userButtonsXBase, + userButtonsYBase + userButtonsLineHeight); + ircOnlinePeopleLabel.setText(lang.getString("IRCPeopleOnline")); + + ircOnlinePeopleStatusLabel.registerGraphicComponent(containerName, + "ircOnlinePeopleStatusLabel"); + ircOnlinePeopleStatusLabel.init(userButtonsXBase, + userButtonsYBase + + userButtonsLineHeight - 20); + ircOnlinePeopleStatusLabel.setText(""); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + NetworkManager::getInstance().end(); + NetworkManager::getInstance().init(nrClient); + + //console.addLine(lang.getString("ToSwitchOffMusicPress")+" - \""+configKeys.getCharKey("ToggleMusic")+"\""); + + GraphicComponent::applyAllCustomProperties(containerName); + + char szIRCNick[80] = ""; + Chrono seed(true); + srand((unsigned int) seed.getCurTicks()); + + int randomNickId = (rand() % 899) + 100; + string netPlayerName = + Config::getInstance().getString("NetPlayerName", + Socket::getHostName().c_str()); + string ircname = netPlayerName.substr(0, 9); + snprintf(szIRCNick, 80, "ZG_%s_%d", ircname.c_str(), randomNickId); + normalizeNick(szIRCNick); + + currentIrcNick = ircname; + consoleIRC.setStringToHighlight(currentIrcNick); + + lines[2].init(0, consoleIRC.getYPos() - 10, userButtonsXBase, 5); + chatManager.init(&consoleIRC, -1, true, szIRCNick); + chatManager.setXPos(0); + chatManager.setYPos(consoleIRC.getYPos() - 20); + chatManager.setFont(CoreData::getInstance().getMenuFontNormal()); + chatManager.setFont3D(CoreData::getInstance(). + getMenuFontNormal3D()); + + needUpdateFromServer = true; + + static string mutexOwnerId = + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + string("_") + intToStr(__LINE__); + updateFromMasterserverThread = new SimpleTaskThread(this, 0, 100); + updateFromMasterserverThread->setUniqueID(mutexOwnerId); + updateFromMasterserverThread->start(); + + if (Config::getInstance().getString("IRCServer", "") != "") { + IRC_SERVER = Config::getInstance().getString("IRCServer"); + } + ircArgs.push_back(IRC_SERVER); + + if (Config::getInstance().getString("IRCNick", "") != "") { + ircArgs.push_back(Config::getInstance().getString("IRCNick")); + } else { + ircArgs.push_back(szIRCNick); + } + + if (Config::getInstance().getString("IRCChannel", "") != "") { + IRC_CHANNEL = Config::getInstance().getString("IRCChannel"); + } + ircArgs.push_back(IRC_CHANNEL); + + if (Config::getInstance().getString("IRCUsername", "") != "") { + ircArgs.push_back(Config::getInstance().getString("IRCUsername")); + } else { + ircArgs.push_back(szIRCNick); + } + if (Config::getInstance().getString("IRCPassword", "") != "") { + ircArgs.push_back("identify " + + Config::getInstance().getString("IRCPassword")); + } else { + ircArgs.push_back(""); + } + + MutexSafeWrapper safeMutexIRCPtr(mutexIRCClient, + string(extractFileFromDirectoryPath + (__FILE__).c_str()) + "_" + + intToStr(__LINE__)); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#1 IRCCLient Cache check\n"); + IRCThread *&ircThread = + CacheManager::getCachedItem < + IRCThread * >(GameConstants::ircClientCacheLookupKey); + + // Playername changed so restart the IRC Thread + if (ircThread != NULL && netPlayerName != ircThread->getPlayerName()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + ircThread->leaveChannel(); + ircThread->setCallbackObj(NULL); + ircThread->signalQuit(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + ircThread = NULL; + } + + if (ircThread == NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#2 IRCCLient Cache check\n"); + + static string mutexOwnerId = + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + string("_") + intToStr(__LINE__); + ircThread = new IRCThread(ircArgs, this); + ircClient = ircThread; + ircClient->setUniqueID(mutexOwnerId); + ircClient->setPlayerName(netPlayerName); + ircClient->setGlestVersionString(glestVersionString); + ircClient->start(); + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("#3 IRCCLient Cache check\n"); + ircClient = ircThread; + ircClient->setCallbackObj(this); + ircClient->joinChannel(); + } + + if (netPlayerName == "newbie") { + showMessageBox(lang.getString("PlayerNameNotSetPrompt"), + lang.getString("PlayerNameNotSetTitle"), false); + } + //showMessageBox("Go back and set your name in the game options!\n\nAt the moment you are just called >>newbie<< !","Player name not set!",false); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } + + void MenuStateMasterserver::reloadUI() { + Lang & lang = Lang::getInstance(); + + console.resetFonts(); + consoleIRC.setFont(CoreData::getInstance().getMenuFontNormal()); + consoleIRC.setFont3D(CoreData::getInstance().getMenuFontNormal3D()); + + mainMessageBox.init(lang.getString("Ok")); + + announcementLabel.setFont(CoreData::getInstance().getMenuFontBig()); + announcementLabel.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + + versionInfoLabel.setFont(CoreData::getInstance().getMenuFontBig()); + versionInfoLabel.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + + labelTitle.setFont(CoreData::getInstance().getMenuFontBig()); + labelTitle.setFont3D(CoreData::getInstance().getMenuFontBig3D()); + labelTitle.setText(lang.getString("AvailableServers")); + + if (Config::getInstance().getString("Masterserver", "") == "") { + labelTitle.setText("*** " + lang.getString("AvailableServers")); + } + + glestVersionLabel.setText(lang.getString("MGVersion")); + + platformLabel.setText(lang.getString("MGPlatform")); + + serverTitleLabel.setText(lang.getString("MGGameTitle")); + + countryLabel.setText(lang.getString("MGGameCountry")); + + techLabel.setText(lang.getString("TechTree")); + + mapLabel.setText(lang.getString("Map")); + + activeSlotsLabel.setText(lang.getString("MGGameSlots")); + + //externalConnectPort.setText(lang.getString("Port")); + + statusLabel.setText(lang.getString("MGGameStatus")); + + selectButton.setText(lang.getString("MGJoinGameSlots")); + + // Titles for current games - END + + buttonRefresh.setText(lang.getString("RefreshList")); + buttonReturn.setText(lang.getString("Return")); + buttonCreateGame.setText(lang.getString("HostGame")); + labelAutoRefresh.setText(lang.getString("AutoRefreshRate")); + + ircOnlinePeopleLabel.setText(lang.getString("IRCPeopleOnline")); + + chatManager.setFont(CoreData::getInstance().getMenuFontNormal()); + chatManager.setFont3D(CoreData::getInstance().getMenuFontNormal3D()); + + GraphicComponent:: + reloadFontsForRegisterGraphicComponents(containerName); + } + + //void MenuStateMasterserver::setConsolePos(int yPos){ + // consoleIRC.setYPos(yPos); + // lines[2].setY(consoleIRC.getYPos()-10); + // chatManager.setYPos(consoleIRC.getYPos()-20); + //} + + void MenuStateMasterserver::setButtonLinePosition(int pos) { + buttonReturn.setY(pos); + buttonCreateGame.setY(pos); + buttonRefresh.setY(pos); + labelAutoRefresh.setY(pos + 30); + listBoxAutoRefresh.setY(pos); + } + + void MenuStateMasterserver::IRC_CallbackEvent(IRCEventType evt, + const char *origin, + const char **params, + unsigned int count) { + MutexSafeWrapper safeMutexIRCPtr(mutexIRCClient, + string(extractFileFromDirectoryPath + (__FILE__).c_str()) + "_" + + intToStr(__LINE__)); + if (ircClient != NULL) { + if (evt == IRC_evt_exitThread) { + ircClient->leaveChannel(); + ircClient->setCallbackObj(NULL); + + ircClient = NULL; + } else if (evt == IRC_evt_chatText) { + //printf ("===> IRC: '%s' said in channel %s: %s\n",origin ? origin : "someone",params[0], params[1] ); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "%s: %s", origin ? origin : "someone", + params[1]); + string helpSTr = szBuf; + if (helpSTr.find(currentIrcNick) != string::npos) { + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + static PlaySoundClip snd; + soundRenderer.playFx(snd.getSound(snd.sfxHighlight)); + } + consoleIRC.addLine(szBuf); + } + } + } + + void MenuStateMasterserver::cleanup() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + MutexSafeWrapper + safeMutex((updateFromMasterserverThread != + NULL ? updateFromMasterserverThread-> + getMutexThreadObjectAccessor() : NULL), + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + "_" + intToStr(__LINE__)); + needUpdateFromServer = false; + safeMutex.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + // if(updateFromMasterserverThread != NULL && + // updateFromMasterserverThread->canShutdown(true) == true) { + // if(updateFromMasterserverThread->shutdownAndWait() == true) { + // delete updateFromMasterserverThread; + // } + // } + // updateFromMasterserverThread = NULL; + if (updateFromMasterserverThread != NULL) { + updateFromMasterserverThread->signalQuit(); + } + if (updateFromMasterserverThread != NULL + && updateFromMasterserverThread->canShutdown(false) == true + && updateFromMasterserverThread->getRunningStatus() == false) { + //printf("#2 Ending client SLOT: %d\n",playerIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugNetwork, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + delete updateFromMasterserverThread; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugNetwork, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + //else if(BaseThread::shutdownAndWait(slotThreadWorker) == true) { + else if (updateFromMasterserverThread != NULL + && updateFromMasterserverThread->canShutdown(true) == true) { + if (updateFromMasterserverThread->getRunningStatus() == false) { + //printf("#3 Ending client SLOT: %d\n",playerIndex); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugNetwork, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + delete updateFromMasterserverThread; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugNetwork, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } else { + updateFromMasterserverThread->setDeleteSelfOnExecutionDone(true); + updateFromMasterserverThread->setDeleteAfterExecute(true); + } + } + //printf("#4 Ending client SLOT: %d\n",playerIndex); + updateFromMasterserverThread = NULL; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + clearServerLines(); + clearUserButtons(); + + MutexSafeWrapper safeMutexIRCPtr(mutexIRCClient, + string(extractFileFromDirectoryPath + (__FILE__).c_str()) + "_" + + intToStr(__LINE__)); + if (ircClient != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + ircClient->leaveChannel(); + ircClient->setCallbackObj(NULL); + //ircClient->signalQuit(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + ircClient = NULL; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] END\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } + + MenuStateMasterserver::~MenuStateMasterserver() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + cleanup(); + + delete mutexIRCClient; + mutexIRCClient = NULL; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] END\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } + + void MenuStateMasterserver::clearServerLines() { + while (!serverLines.empty()) { + delete serverLines.back(); + serverLines.pop_back(); + } + } + + void MenuStateMasterserver::clearUserButtons() { + while (!userButtons.empty()) { + delete userButtons.back(); + userButtons.pop_back(); + } + } + + void MenuStateMasterserver::mouseClick(int x, int y, + MouseButton mouseButton) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + + if (mainMessageBox.getEnabled()) { + int button = 0; + if (mainMessageBox.mouseClick(x, y, button)) { + soundRenderer.playFx(coreData.getClickSoundA()); + if (button == 0) { + mainMessageBox.setEnabled(false); + } + } + } else if (userScrollBar.mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + soundRenderer.playFx(coreData.getClickSoundA()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } else if (serverScrollBar.mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + soundRenderer.playFx(coreData.getClickSoundA()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } else if (buttonRefresh.mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + MutexSafeWrapper + safeMutex((updateFromMasterserverThread != + NULL ? updateFromMasterserverThread-> + getMutexThreadObjectAccessor() : NULL), + string(extractFileFromDirectoryPath(__FILE__). + c_str()) + "_" + intToStr(__LINE__)); + soundRenderer.playFx(coreData.getClickSoundB()); + needUpdateFromServer = true; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } else if (buttonReturn.mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + soundRenderer.playFx(coreData.getClickSoundA()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + if (ircClient != NULL && ircClient->isConnected() == true + && ircClient->getHasJoinedChannel() == true) { + ircClient->SendIRCCmdMessage(IRC_CHANNEL, + " << left the lobby"); + sleep(30); + } + cleanup(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + mainMenu->setState(new MenuStateNewGame(program, mainMenu)); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } else if (buttonCreateGame.mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + MutexSafeWrapper + safeMutex((updateFromMasterserverThread != + NULL ? updateFromMasterserverThread-> + getMutexThreadObjectAccessor() : NULL), + string(extractFileFromDirectoryPath(__FILE__). + c_str()) + "_" + intToStr(__LINE__)); + soundRenderer.playFx(coreData.getClickSoundB()); + needUpdateFromServer = false; + safeMutex.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + if (ircClient != NULL && ircClient->isConnected() == true + && ircClient->getHasJoinedChannel() == true) { + ircClient->SendIRCCmdMessage(IRC_CHANNEL, + " << tries to create a game"); + sleep(30); + } + cleanup(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + mainMenu-> + setState(new + MenuStateCustomGame(program, mainMenu, true, + pMasterServer)); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } else if (listBoxAutoRefresh.mouseClick(x, y)) { + MutexSafeWrapper + safeMutex((updateFromMasterserverThread != + NULL ? updateFromMasterserverThread-> + getMutexThreadObjectAccessor() : NULL), + string(extractFileFromDirectoryPath(__FILE__). + c_str()) + "_" + intToStr(__LINE__)); + soundRenderer.playFx(coreData.getClickSoundA()); + autoRefreshTime = 10 * listBoxAutoRefresh.getSelectedItemIndex(); + } else { + MutexSafeWrapper + safeMutex((updateFromMasterserverThread != + NULL ? updateFromMasterserverThread-> + getMutexThreadObjectAccessor() : NULL), + string(extractFileFromDirectoryPath(__FILE__). + c_str()) + "_" + intToStr(__LINE__)); + bool clicked = false; + if (serverScrollBar.getElementCount() != 0) { + for (int i = serverScrollBar.getVisibleStart(); + i <= serverScrollBar.getVisibleEnd(); ++i) { + if (serverLines[i]->buttonMouseClick(x, y)) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + clicked = true; + soundRenderer.playFx(coreData.getClickSoundB()); + string connectServerIP = + serverLines[i]->getMasterServerInfo()->getIpAddress(); + int connectServerPort = + serverLines[i]->getMasterServerInfo()-> + getExternalConnectPort(); + bool connected = + connectToServer(connectServerIP, connectServerPort); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + safeMutex.ReleaseLock(); + if (connected) { + soundRenderer.playFx(coreData.getClickSoundB()); + + if (ircClient != NULL && ircClient->isConnected() == true + && ircClient->getHasJoinedChannel() == true) { + ircClient->SendIRCCmdMessage(IRC_CHANNEL, + " << is connecting to '" + + serverLines[i]-> + getMasterServerInfo()-> + getServerTitle() + "'"); + sleep(30); + } + cleanup(); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + mainMenu-> + setState(new + MenuStateConnectedGame(program, mainMenu, + jmMasterserver)); + } + break; + } + } + } + if (!clicked && userScrollBar.getElementCount() != 0) { + for (int i = userScrollBar.getVisibleStart(); + i <= userScrollBar.getVisibleEnd(); ++i) { + if (userButtons[i]->getEnabled() == true + && userButtons[i]->mouseClick(x, y)) { + //clicked=true; + if (!chatManager.getEditEnabled()) { + chatManager.switchOnEdit(); + chatManager.addText(nickList[i] + " "); + } else { + chatManager.addText(nickList[i]); + } + break; + } + } + } + } + } + + void MenuStateMasterserver::mouseUp(int x, int y, + const MouseButton mouseButton) { + if (mouseButton == mbLeft) { + userScrollBar.mouseUp(x, y); + serverScrollBar.mouseUp(x, y); + } + } + + void MenuStateMasterserver::mouseMove(int x, int y, + const MouseState * ms) { + MutexSafeWrapper + safeMutex((updateFromMasterserverThread != + NULL ? updateFromMasterserverThread-> + getMutexThreadObjectAccessor() : NULL), + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + "_" + intToStr(__LINE__)); + + if (mainMessageBox.getEnabled()) { + mainMessageBox.mouseMove(x, y); + } + buttonRefresh.mouseMove(x, y); + buttonReturn.mouseMove(x, y); + buttonCreateGame.mouseMove(x, y); + if (ms->get(mbLeft)) { + userScrollBar.mouseDown(x, y); + serverScrollBar.mouseDown(x, y); + } else { + userScrollBar.mouseMove(x, y); + serverScrollBar.mouseMove(x, y); + } + listBoxAutoRefresh.mouseMove(x, y); + + if (serverScrollBar.getElementCount() != 0) { + for (int i = serverScrollBar.getVisibleStart(); + i <= serverScrollBar.getVisibleEnd(); ++i) { + serverLines[i]->buttonMouseMove(x, y); + } + } + if (userScrollBar.getElementCount() != 0) { + for (int i = userScrollBar.getVisibleStart(); + i <= userScrollBar.getVisibleEnd(); ++i) { + if (userButtons[i]->getEnabled() == true) { + userButtons[i]->mouseMove(x, y); + } + } + } + + } + + void MenuStateMasterserver::render() { + Renderer & renderer = Renderer::getInstance(); + + MutexSafeWrapper + safeMutex((updateFromMasterserverThread != + NULL ? updateFromMasterserverThread-> + getMutexThreadObjectAccessor() : NULL), + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + "_" + intToStr(__LINE__)); + if (mainMessageBox.getEnabled()) { + renderer.renderMessageBox(&mainMessageBox); + } else { + renderer.renderLabel(&labelTitle, &GREEN); + renderer.renderLabel(&announcementLabel, &YELLOW); + renderer.renderLabel(&versionInfoLabel); + + // Render titles for server games listed + const Vec4f titleLabelColor = CYAN; + + //general info: + renderer.renderLabel(&glestVersionLabel, &titleLabelColor); + renderer.renderLabel(&platformLabel, &titleLabelColor); + //renderer.renderLabel(&binaryCompileDateLabel,&titleLabelColor); + + //game info: + renderer.renderLabel(&serverTitleLabel, &titleLabelColor); + renderer.renderLabel(&countryLabel, &titleLabelColor); + renderer.renderLabel(&statusLabel, &titleLabelColor); + //renderer.renderLabel(&ipAddressLabel,&titleLabelColor); + + //game setup info: + renderer.renderLabel(&techLabel, &titleLabelColor); + renderer.renderLabel(&mapLabel, &titleLabelColor); + //renderer.renderLabel(&tilesetLabel,&titleLabelColor); + renderer.renderLabel(&activeSlotsLabel, &titleLabelColor); + //renderer.renderLabel(&externalConnectPort,&titleLabelColor); + renderer.renderLabel(&selectButton, &titleLabelColor); + + Lang & lang = Lang::getInstance(); + MutexSafeWrapper safeMutexIRCPtr(mutexIRCClient, + string(extractFileFromDirectoryPath + (__FILE__).c_str()) + "_" + + intToStr(__LINE__)); + if (ircClient != NULL && ircClient->isConnected() == true + && ircClient->getHasJoinedChannel() == true) { + const Vec4f titleLabelColor = GREEN; + + if (ircOnlinePeopleStatusLabel.getText() != "") { + ircOnlinePeopleStatusLabel.setText(""); + } + + renderer.renderLabel(&ircOnlinePeopleLabel, &titleLabelColor); + //renderer.renderLabel(&ircOnlinePeopleStatusLabel,&titleLabelColor); + } else { + const Vec4f titleLabelColor = RED; + + if (ircOnlinePeopleStatusLabel.getText() != + lang.getString("Connecting")) { + ircOnlinePeopleStatusLabel.setText(lang. + getString("Connecting")); + } + + renderer.renderLabel(&ircOnlinePeopleLabel, &titleLabelColor); + renderer.renderLabel(&ircOnlinePeopleStatusLabel, + &titleLabelColor); + } + safeMutexIRCPtr.ReleaseLock(); + + //const Vec4f titleLabelColorList = YELLOW; + + if (serverScrollBar.getElementCount() != 0) { + for (int i = serverScrollBar.getVisibleStart(); + i <= serverScrollBar.getVisibleEnd(); ++i) { + serverLines[i]->render(); + } + } + renderer.renderScrollBar(&serverScrollBar); + + for (int i = 0; i < (int) sizeof(lines) / (int) sizeof(lines[0]); + ++i) { + renderer.renderLine(&lines[i]); + } + renderer.renderButton(&buttonRefresh); + renderer.renderButton(&buttonReturn); + renderer.renderLabel(&labelAutoRefresh); + renderer.renderButton(&buttonCreateGame); + renderer.renderListBox(&listBoxAutoRefresh); + + if (userScrollBar.getElementCount() != 0) { + for (int i = userScrollBar.getVisibleStart(); + i <= userScrollBar.getVisibleEnd(); ++i) { + renderer.renderButton(userButtons[i]); + } + } + renderer.renderScrollBar(&userScrollBar); + if (ircClient != NULL && + ircClient->isConnected() == true && + ircClient->getHasJoinedChannel() == true) { + renderer.renderChatManager(&chatManager); + } + renderer.renderConsole(&consoleIRC, consoleStoredOnly, 21); + + } + if (program != NULL) + program->renderProgramMsgBox(); + } + + void MenuStateMasterserver::update() { + MutexSafeWrapper + safeMutex((updateFromMasterserverThread != + NULL ? updateFromMasterserverThread-> + getMutexThreadObjectAccessor() : NULL), + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + "_" + intToStr(__LINE__)); + if (autoRefreshTime != 0 + && difftime(time(NULL), lastRefreshTimer) >= autoRefreshTime) { + needUpdateFromServer = true; + lastRefreshTimer = time(NULL); + } + + // calculate button linepos: + setButtonLinePosition(serverLinesYBase - + (serverLinesToRender) * serverLinesLineHeight - + 30); + + if (playServerFoundSound) { + static PlaySoundClip snd; + SoundRenderer::getInstance().playFx(snd.getSound(snd.sfxNewServer)); + + //switch on music again!! + Config & config = Config::getInstance(); + float configVolume = (config.getInt("SoundVolumeMusic") / 100.f); + CoreData::getInstance().getMenuMusic()->setVolume(configVolume); + + playServerFoundSound = false; + } + + //console.update(); + + //call the chat manager + chatManager.updateNetwork(); + + //console + consoleIRC.update(); + + MutexSafeWrapper safeMutexIRCPtr(mutexIRCClient, + string(extractFileFromDirectoryPath + (__FILE__).c_str()) + "_" + + intToStr(__LINE__)); + if (ircClient != NULL) { + nickList = ircClient->getNickList(); + + if (currentIrcNick != ircClient->getNick()) { + currentIrcNick = ircClient->getNick(); + consoleIRC.setStringToHighlight(currentIrcNick); + } + + bool isNew = false; + //check if there is something new + if (oldNickList.size() != nickList.size()) { + isNew = true; + } else { + for (unsigned int i = 0; i < nickList.size(); ++i) { + if (nickList[i] != oldNickList[i]) { + isNew = true; + break; + } + } + } + + if (isNew) { + clearUserButtons(); + for (int i = 0; i < (int) nickList.size(); ++i) { + GraphicButton *button = new GraphicButton(); + button->init(userButtonsXBase, userButtonsYBase, + userButtonsWidth, userButtonsHeight); + //button->init(userButtonsXBase,userButtonsYBase-userButtonsLineHeight*i,userButtonsWidth,userButtonsHeight); + button->setFont(CoreData::getInstance().getDisplayFontSmall()); + button->setFont3D(CoreData::getInstance(). + getDisplayFontSmall3D()); + + if (strncmp(&nickList[i][0], "ZG_", 3) == 0) { + button->setText(nickList[i].substr(3, nickList[i].length() - 7)); + } else { + button->setText(nickList[i]); + } + + if (strncmp(&nickList[i][0], "ZG_", 3) != 0 + || &nickList[i][0] == currentIrcNick) { + button->setEnabled(false); + button->setEditable(false); + button->setCustomTexture(CoreData::getInstance(). + getCustomTexture()); + button->setUseCustomTexture(true); + } + + userButtons.push_back(button); + + } + userScrollBar.setElementCount((int) userButtons.size()); + oldNickList = nickList; + chatManager.setAutoCompleteTextList(oldNickList); + } + if (userScrollBar.getElementCount() != 0) { + for (int i = userScrollBar.getVisibleStart(); + i <= userScrollBar.getVisibleEnd(); ++i) { + userButtons[i]->setY(userButtonsYBase - + userButtonsLineHeight * (i - + userScrollBar. + getVisibleStart + ())); + } + } + } + safeMutexIRCPtr.ReleaseLock(); + if (serverInfoString != "empty") { + rebuildServerLines(serverInfoString); + serverInfoString = "empty"; + } + + serverScrollBar.setElementCount((int) serverLines.size()); + if (serverScrollBar.getElementCount() != 0) { + for (int i = serverScrollBar.getVisibleStart(); + i <= serverScrollBar.getVisibleEnd(); ++i) { + serverLines[i]->setY(serverLinesYBase - + serverLinesLineHeight * (i - + serverScrollBar. + getVisibleStart())); + } + } + + if (threadedErrorMsg != "") { + std::string sError = threadedErrorMsg; + threadedErrorMsg = ""; + + if (pCB_DisplayMessage != NULL) { + pCB_DisplayMessage(sError.c_str(), false); + } else { + throw megaglest_runtime_error(sError.c_str()); + } + } + } + + void MenuStateMasterserver::simpleTask(BaseThread * callingThread, + void *userdata) { + if (callingThread->getQuitStatus() == true) { + return; + } + MutexSafeWrapper safeMutex(callingThread-> + getMutexThreadObjectAccessor(), + string(extractFileFromDirectoryPath + (__FILE__).c_str()) + "_" + + intToStr(__LINE__)); + bool needUpdate = needUpdateFromServer; + + if (needUpdate == true) { + try { + + if (callingThread->getQuitStatus() == true) { + return; + } + + needUpdateFromServer = false; + + if (announcementLoaded == false) { + string announcementURL = + Config::getInstance().getString("AnnouncementURL", + "http://zetaglest.dreamhosters.com/files/announcement.txt"); + if (announcementURL != "") { + + safeMutex.ReleaseLock(true); + CURL *handle = SystemFlags::initHTTP(); + std::string announcementTxt = + SystemFlags::getHTTP(announcementURL, handle); + SystemFlags::cleanupHTTP(&handle); + if (callingThread->getQuitStatus() == true) { + return; + } + safeMutex.Lock(); + + if (StartsWith + (announcementTxt, + "Announcement from Masterserver:") == true) { + int newlineCount = 0; + size_t lastIndex = 0; + + //announcementLabel.setText(announcementTxt); + consoleIRC.addLine(announcementTxt, true, + Vec3f(1.0f, 1.0f, 0.0f)); + + while (true) { + lastIndex = announcementTxt.find("\n", lastIndex + 1); + if (lastIndex == string::npos) { + break; + } else { + newlineCount++; + } + } + newlineCount--; // remove my own line + for (int i = 0; i < newlineCount; ++i) { + consoleIRC.addLine(""); + } + } + } + consoleIRC. + addLine("---------------------------------------------"); + string versionURL = + Config::getInstance().getString("VersionURL", + "http://zetaglest.dreamhosters.com/files/versions/") + + glestVersionString + ".txt"; + //printf("\nversionURL=%s\n",versionURL.c_str()); + if (versionURL != "") { + safeMutex.ReleaseLock(true); + CURL *handle = SystemFlags::initHTTP(); + std::string versionTxt = + SystemFlags::getHTTP(versionURL, handle); + SystemFlags::cleanupHTTP(&handle); + if (callingThread->getQuitStatus() == true) { + return; + } + safeMutex.Lock(); + + if (StartsWith(versionTxt, "Version info:") == true) { + int newlineCount = 0; + size_t lastIndex = 0; + + //versionInfoLabel.setText(versionTxt); + consoleIRC.addLine(versionTxt, true, + Vec3f(1.0f, 0.0f, 0.0f)); + + while (true) { + lastIndex = versionTxt.find("\n", lastIndex + 1); + if (lastIndex == string::npos) { + break; + } else { + newlineCount++; + } + } + newlineCount--; // remove my own line + for (int i = 0; i < newlineCount; ++i) { + consoleIRC.addLine(""); + } + } + } + consoleIRC. + addLine("---------------------------------------------"); + // write hint to console: + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + consoleIRC.addLine(Lang::getInstance(). + getString("ToSwitchOffMusicPress") + + " - \"" + + configKeys.getString("ToggleMusic") + "\""); + + announcementLoaded = true; + } + + //Lang &lang= Lang::getInstance(); + try { + if (Config::getInstance().getString("Masterserver", "") != "") { + + safeMutex.ReleaseLock(true); + CURL *handle = SystemFlags::initHTTP(); + + string playerUUID = + "?uuid=" + + SystemFlags::escapeURL(Config::getInstance(). + getString("PlayerId", "")); + + string baseURL = + Config::getInstance().getString("Masterserver"); + if (baseURL != "") { + endPathWithSlash(baseURL, false); + } + + std::string localServerInfoString = + SystemFlags::getHTTP(baseURL + "showServersForGlest.php" + + playerUUID, handle); + SystemFlags::cleanupHTTP(&handle); + if (callingThread->getQuitStatus() == true) { + return; + } + safeMutex.Lock(); + + serverInfoString = localServerInfoString; + } + } catch (const exception & ex) { + serverInfoString = ex.what(); + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line %d] error during Internet game status update: [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + ex.what()); + } + } catch (const exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + e.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d, error [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + e.what()); + threadedErrorMsg = e.what(); + } + } + } + + void MenuStateMasterserver::rebuildServerLines(const string & serverInfo) { + int numberOfOldServerLines = (int) serverLines.size(); + clearServerLines(); + Lang & lang = Lang::getInstance(); + try { + if (serverInfo != "") { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("--------------> serverInfo [%s]\n", serverInfo.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + std::vector < std::string > serverList; + Tokenize(serverInfo, serverList, "\n"); + for (int i = 0; i < (int) serverList.size(); i++) { + string & server = serverList[i]; + if (trim(server) == "") { + continue; + } + std::vector < std::string > serverEntities; + Tokenize(server, serverEntities, "|"); + const int MIN_FIELDS_EXPECTED = 14; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("--------------> server [%s] serverEntities.size() = " + MG_SIZE_T_SPECIFIER " MIN_FIELDS_EXPECTED = %d\n", + server.c_str(), serverEntities.size(), + MIN_FIELDS_EXPECTED); + + if ((int) serverEntities.size() >= MIN_FIELDS_EXPECTED) { + labelTitle.setText(lang.getString("AvailableServers")); + + if (Config::getInstance().getString("Masterserver", "") == "") { + labelTitle.setText("*** " + + lang.getString("AvailableServers")); + } + + MasterServerInfo *masterServerInfo = new MasterServerInfo(); + + //general info: + masterServerInfo->setGlestVersion(serverEntities[0]); + masterServerInfo->setPlatform(serverEntities[1]); + masterServerInfo->setBinaryCompileDate(serverEntities[2]); + + //game info: + masterServerInfo->setServerTitle(serverEntities[3]); + masterServerInfo->setIpAddress(serverEntities[4]); + + //game setup info: + masterServerInfo->setTech(serverEntities[5]); + masterServerInfo->setMap(serverEntities[6]); + masterServerInfo->setTileset(serverEntities[7]); + masterServerInfo->setActiveSlots(strToInt(serverEntities[8])); + masterServerInfo-> + setNetworkSlots(strToInt(serverEntities[9])); + masterServerInfo-> + setConnectedClients(strToInt(serverEntities[10])); + masterServerInfo-> + setExternalConnectPort(strToInt(serverEntities[11])); + masterServerInfo->setCountry(serverEntities[12]); + masterServerInfo->setStatus(strToInt(serverEntities[13])); + + //printf("--------------> Country [%s] Status [%d]\n",masterServerInfo->getCountry().c_str(),masterServerInfo->getStatus()); + + //printf("Getting Ping time for host %s\n",masterServerInfo->getIpAddress().c_str()); + //float pingTime = Socket::getAveragePingMS(masterServerInfo->getIpAddress().c_str(),1); + //printf("Ping time = %f\n",pingTime); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "%s", + masterServerInfo->getServerTitle().c_str()); + masterServerInfo->setServerTitle(szBuf); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + serverLines. + push_back(new + ServerLine(masterServerInfo, i, serverLinesYBase, + serverLinesLineHeight, containerName)); + delete masterServerInfo; + } else { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + Lang & lang = Lang::getInstance(); + labelTitle.setText("*** " + + lang.getString("AvailableServers") + "[" + + intToStr(serverEntities.size()) + "][" + + intToStr(MIN_FIELDS_EXPECTED) + "] [" + + serverInfo + "]"); + + if (masterserverParseErrorShown == false) { + masterserverParseErrorShown = true; + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line %d] error, no masterserver defined!\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } + + } catch (const exception & ex) { + labelTitle.setText("*** " + lang.getString("AvailableServers") + + " [" + ex.what() + "]"); + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line %d] error during Internet game status update: [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + ex.what()); + } + + if ((int) serverLines.size() > numberOfOldServerLines) { + playServerFoundSound = true; + } + } + + + bool MenuStateMasterserver::connectToServer(string ipString, int port) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] START ipString='%s'\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, ipString.c_str()); + + ClientInterface *clientInterface = + NetworkManager::getInstance().getClientInterface(); + //Config& config= Config::getInstance(); + Ip serverIp(ipString); + + //int serverPort = Config::getInstance().getInt("PortServer",intToStr(GameConstants::serverPort).c_str()); + int serverPort = port; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] try to connect to [%s] serverPort = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, + serverIp.getString().c_str(), serverPort); + clientInterface->connect(serverIp, serverPort); + if (clientInterface->isConnected() == false) { + NetworkManager::getInstance().end(); + NetworkManager::getInstance().init(nrClient); + + mainMessageBoxState = 1; + Lang & lang = Lang::getInstance(); + showMessageBox(lang.getString("CouldNotConnect"), + lang.getString("ConnectionFailed"), false); + return false; + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] connection failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] connected to [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, + serverIp.getString().c_str()); + + //save server ip + //config.setString("ServerIp", serverIp.getString()); + //config.save(); + + for (time_t elapsedWait = time(NULL); + clientInterface->getIntroDone() == false && + clientInterface->isConnected() && + difftime(time(NULL), elapsedWait) <= 8;) { + if (clientInterface->isConnected()) { + //update lobby + clientInterface->updateLobby(); + sleep(0); + //this->render(); + } + } + if (clientInterface->isConnected() == true && + clientInterface->getIntroDone() == true) { + return true; + } + + return false; + } + } + + void MenuStateMasterserver::showMessageBox(const string & text, + const string & header, + bool toggle) { + if (!toggle) { + mainMessageBox.setEnabled(false); + } + + if (!mainMessageBox.getEnabled()) { + mainMessageBox.setText(text); + mainMessageBox.setHeader(header); + mainMessageBox.setEnabled(true); + } else { + mainMessageBox.setEnabled(false); + } + } + + + bool MenuStateMasterserver::textInput(std::string text) { + if (ircClient != NULL && ircClient->isConnected() == true + && ircClient->getHasJoinedChannel() == true) { + return chatManager.textInput(text); + } + return false; + } + + void MenuStateMasterserver::keyDown(SDL_KeyboardEvent key) { + //printf("In [%s::%s Line: %d] key [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,key.keysym.sym); + + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + + if (ircClient != NULL && ircClient->isConnected() == true + && ircClient->getHasJoinedChannel() == true) { + //chatmanger only if connected to irc! + if (chatManager.getEditEnabled() == true) { + //printf("keyDown key [%d] chatManager.getText() [%s]\n",key,chatManager.getText().c_str()); + MutexSafeWrapper safeMutexIRCPtr(mutexIRCClient, + string + (extractFileFromDirectoryPath + (__FILE__).c_str()) + "_" + + intToStr(__LINE__)); + //if (key == vkReturn && ircClient != NULL) { + if (isKeyPressed(SDLK_RETURN, key, false) == true + && ircClient != NULL) { + ircClient->SendIRCCmdMessage(IRC_CHANNEL, + chatManager.getText()); + } + } + chatManager.keyDown(key); + } + if (chatManager.getEditEnabled() == false) { + //if(key == configKeys.getCharKey("ToggleMusic")) { + if (isKeyPressed(configKeys.getSDLKey("ToggleMusic"), key) == true) { + Config & config = Config::getInstance(); + Lang & lang = Lang::getInstance(); + + float configVolume = (config.getInt("SoundVolumeMusic") / 100.f); + float currentVolume = + CoreData::getInstance().getMenuMusic()->getVolume(); + if (currentVolume > 0) { + CoreData::getInstance().getMenuMusic()->setVolume(0.f); + consoleIRC.addLine(lang.getString("GameMusic") + " " + + lang.getString("Off")); + } else { + CoreData::getInstance().getMenuMusic()-> + setVolume(configVolume); + //If the config says zero, use the default music volume + //gameMusic->setVolume(configVolume ? configVolume : 0.9); + consoleIRC.addLine(lang.getString("GameMusic")); + } + } + //else if(key == configKeys.getCharKey("SaveGUILayout")) { + else if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), key) == + true) { + bool saved = + GraphicComponent::saveAllCustomProperties(containerName); + Lang & lang = Lang::getInstance(); + consoleIRC.addLine(lang.getString("GUILayoutSaved") + " [" + + (saved ? lang.getString("Yes") : lang. + getString("No")) + "]"); + } + } + } + + } } //end namespace diff --git a/source/glest_game/menu/menu_state_masterserver.h b/source/glest_game/menu/menu_state_masterserver.h index 0fabd00b1..d4582849e 100644 --- a/source/glest_game/menu/menu_state_masterserver.h +++ b/source/glest_game/menu/menu_state_masterserver.h @@ -33,148 +33,144 @@ # include "chat_manager.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// =============================== -// class MenuStateMasterserver -// =============================== - typedef vector < ServerLine * >ServerLines; - typedef vector < GraphicButton * >UserButtons; - typedef vector < MasterServerInfo * >MasterServerInfos; + // =============================== + // class MenuStateMasterserver + // =============================== + typedef vector < ServerLine * >ServerLines; + typedef vector < GraphicButton * >UserButtons; + typedef vector < MasterServerInfo * >MasterServerInfos; - class MenuStateMasterserver:public MenuState, - public SimpleTaskCallbackInterface, public IRCCallbackInterface - { + class MenuStateMasterserver :public MenuState, + public SimpleTaskCallbackInterface, public IRCCallbackInterface { - private: + private: - GraphicButton buttonRefresh; - GraphicButton buttonReturn; - GraphicButton buttonCreateGame; - GraphicLabel labelAutoRefresh; - GraphicListBox listBoxAutoRefresh; - GraphicLabel labelTitle; + GraphicButton buttonRefresh; + GraphicButton buttonReturn; + GraphicButton buttonCreateGame; + GraphicLabel labelAutoRefresh; + GraphicListBox listBoxAutoRefresh; + GraphicLabel labelTitle; - GraphicLabel announcementLabel; - GraphicLabel versionInfoLabel; + GraphicLabel announcementLabel; + GraphicLabel versionInfoLabel; - GraphicLine lines[3]; + GraphicLine lines[3]; - GraphicLabel glestVersionLabel; - GraphicLabel platformLabel; - //GraphicLabel binaryCompileDateLabel; + GraphicLabel glestVersionLabel; + GraphicLabel platformLabel; + //GraphicLabel binaryCompileDateLabel; - //game info: - GraphicLabel serverTitleLabel; - GraphicLabel countryLabel; - GraphicLabel statusLabel; + //game info: + GraphicLabel serverTitleLabel; + GraphicLabel countryLabel; + GraphicLabel statusLabel; - GraphicLabel ipAddressLabel; + GraphicLabel ipAddressLabel; - //game setup info: - GraphicLabel techLabel; - GraphicLabel mapLabel; - GraphicLabel tilesetLabel; - GraphicLabel activeSlotsLabel; + //game setup info: + GraphicLabel techLabel; + GraphicLabel mapLabel; + GraphicLabel tilesetLabel; + GraphicLabel activeSlotsLabel; - GraphicLabel externalConnectPort; + GraphicLabel externalConnectPort; - GraphicLabel selectButton; + GraphicLabel selectButton; - GraphicMessageBox mainMessageBox; - int mainMessageBoxState; + GraphicMessageBox mainMessageBox; + int mainMessageBoxState; - GraphicLabel ircOnlinePeopleLabel; - GraphicLabel ircOnlinePeopleStatusLabel; + GraphicLabel ircOnlinePeopleLabel; + GraphicLabel ircOnlinePeopleStatusLabel; - bool announcementLoaded; - bool needUpdateFromServer; - int autoRefreshTime; - time_t lastRefreshTimer; - SimpleTaskThread *updateFromMasterserverThread; - bool playServerFoundSound; - ServerLines serverLines; - string serverInfoString; - int serverLinesToRender; - int serverLinesYBase; - int serverLinesLineHeight; - GraphicScrollBar userScrollBar; - GraphicScrollBar serverScrollBar; - UserButtons userButtons; - UserButtons userButtonsToRemove; - int userButtonsToRender; - int userButtonsYBase; - int userButtonsXBase; - int userButtonsLineHeight; - int userButtonsHeight; - int userButtonsWidth; - string currentIrcNick; + bool announcementLoaded; + bool needUpdateFromServer; + int autoRefreshTime; + time_t lastRefreshTimer; + SimpleTaskThread *updateFromMasterserverThread; + bool playServerFoundSound; + ServerLines serverLines; + string serverInfoString; + int serverLinesToRender; + int serverLinesYBase; + int serverLinesLineHeight; + GraphicScrollBar userScrollBar; + GraphicScrollBar serverScrollBar; + UserButtons userButtons; + UserButtons userButtonsToRemove; + int userButtonsToRender; + int userButtonsYBase; + int userButtonsXBase; + int userButtonsLineHeight; + int userButtonsHeight; + int userButtonsWidth; + string currentIrcNick; - //Console console; + //Console console; - static DisplayMessageFunction pCB_DisplayMessage; - std::string threadedErrorMsg; + static DisplayMessageFunction pCB_DisplayMessage; + std::string threadedErrorMsg; - std::vector < string > ircArgs; - Mutex *mutexIRCClient; - IRCThread *ircClient; - std::vector < string > oldNickList; + std::vector < string > ircArgs; + Mutex *mutexIRCClient; + IRCThread *ircClient; + std::vector < string > oldNickList; - Console consoleIRC; - ChatManager chatManager; + Console consoleIRC; + ChatManager chatManager; - bool masterserverParseErrorShown; + bool masterserverParseErrorShown; - public: - MenuStateMasterserver (Program * program, MainMenu * mainMenu); - ~MenuStateMasterserver (); + public: + MenuStateMasterserver(Program * program, MainMenu * mainMenu); + ~MenuStateMasterserver(); - void mouseClick (int x, int y, MouseButton mouseButton); - void mouseUp (int x, int y, const MouseButton mouseButton); - void mouseMove (int x, int y, const MouseState * mouseState); - void update (); - void render (); + void mouseClick(int x, int y, MouseButton mouseButton); + void mouseUp(int x, int y, const MouseButton mouseButton); + void mouseMove(int x, int y, const MouseState * mouseState); + void update(); + void render(); - virtual bool textInput (std::string text); - virtual void keyDown (SDL_KeyboardEvent key); + virtual bool textInput(std::string text); + virtual void keyDown(SDL_KeyboardEvent key); - virtual void simpleTask (BaseThread * callingThread, void *userdata); - virtual bool isInSpecialKeyCaptureEvent () - { - return chatManager.getEditEnabled (); - } + virtual void simpleTask(BaseThread * callingThread, void *userdata); + virtual bool isInSpecialKeyCaptureEvent() { + return chatManager.getEditEnabled(); + } - static void setDisplayMessageFunction (DisplayMessageFunction - pDisplayMessage) - { - pCB_DisplayMessage = pDisplayMessage; - } + static void setDisplayMessageFunction(DisplayMessageFunction + pDisplayMessage) { + pCB_DisplayMessage = pDisplayMessage; + } - virtual void reloadUI (); + virtual void reloadUI(); - private: - void showMessageBox (const string & text, const string & header, - bool toggle); - bool connectToServer (string ipString, int port); - //void setConsolePos(int yPos); - void setButtonLinePosition (int pos); - void clearServerLines (); - void clearUserButtons (); - void rebuildServerLines (const string & serverInfo); - void cleanup (); - virtual void IRC_CallbackEvent (IRCEventType evt, const char *origin, - const char **params, - unsigned int count); + private: + void showMessageBox(const string & text, const string & header, + bool toggle); + bool connectToServer(string ipString, int port); + //void setConsolePos(int yPos); + void setButtonLinePosition(int pos); + void clearServerLines(); + void clearUserButtons(); + void rebuildServerLines(const string & serverInfo); + void cleanup(); + virtual void IRC_CallbackEvent(IRCEventType evt, const char *origin, + const char **params, + unsigned int count); - std::vector < string > nickList; + std::vector < string > nickList; - }; + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/menu/menu_state_mods.cpp b/source/glest_game/menu/menu_state_mods.cpp index e4475df9a..70b873a03 100644 --- a/source/glest_game/menu/menu_state_mods.cpp +++ b/source/glest_game/menu/menu_state_mods.cpp @@ -26,4014 +26,3555 @@ #include "leak_dumper.h" -namespace Glest -{ - namespace Game - { - - using namespace::Shared::Util; - - struct FormatString - { - void operator () (string & s) - { - s = formatString (s); - } - }; - - - -// =============================== -// class ModInfo -// =============================== - - ModInfo::ModInfo () - { - name = ""; - url = ""; - imageUrl = ""; - description = ""; - count = ""; - crc = ""; - type = mt_None; - } - - - -// ===================================================== -// class MenuStateConnectedGame -// ===================================================== - - MenuStateMods::MenuStateMods (Program * program, - MainMenu * mainMenu):MenuState (program, - mainMenu, - "mods") - { - - containerName = "Mods"; - Lang & lang = Lang::getInstance (); - Config & config = Config::getInstance (); - - modPreviewImage = NULL; - displayModPreviewImage.clear (); - - ftpClientThread = NULL; - selectedTechName = ""; - selectedTilesetName = ""; - selectedMapName = ""; - selectedScenarioName = ""; - modInfoSelected = NULL; - showFullConsole = false; - keyButtonsLineHeight = 20; - keyButtonsHeight = 20; - keyButtonsWidth = 200; - keyButtonsWidthTech = keyButtonsWidth; - keyButtonsWidthMap = keyButtonsWidth + 15; - keyButtonsWidthTil = keyButtonsWidth - 5; - keyButtonsWidthScen = keyButtonsWidth + 20; - scrollListsYPos = 700; - listBoxLength = 200; - keyButtonsYBase = scrollListsYPos; - keyButtonsToRender = listBoxLength / keyButtonsLineHeight; - labelWidth = 5; - keyButtonsXBase = 0; - modMenuState = mmst_None; - oldMenuState = mmst_None; - - int installButtonYPos = scrollListsYPos - listBoxLength - 20; - - int returnLineY = 80; - enableMapPreview = config.getBool ("MapPreview", "true"); - validMapPreview = false; - mapPreviewTexture = NULL; - - //create - techInfoXPos = 5; - keyTechScrollBarTitle1.registerGraphicComponent (containerName, - "keyTechScrollBarTitle1"); - keyTechScrollBarTitle1.init (techInfoXPos + 5, scrollListsYPos + 30, - labelWidth, 20); - keyTechScrollBarTitle1.setText (lang.getString ("TechTitle1")); - keyTechScrollBarTitle1.setFont (CoreData::getInstance (). - getMenuFontBig ()); - keyTechScrollBarTitle1.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - keyTechScrollBarTitle2.registerGraphicComponent (containerName, - "keyTechScrollBarTitle2"); - keyTechScrollBarTitle2.init (techInfoXPos - 10 + keyButtonsWidthTech, - scrollListsYPos + 17, labelWidth, 20); - keyTechScrollBarTitle2.setText (lang.getString ("TechTitle2")); - keyTechScrollBarTitle2.setFont (CoreData::getInstance (). - getMenuFontNormal ()); - keyTechScrollBarTitle2.setFont3D (CoreData::getInstance (). - getMenuFontNormal3D ()); - - mapInfoXPos = 260; - keyMapScrollBarTitle1.registerGraphicComponent (containerName, - "keyMapScrollBarTitle1"); - keyMapScrollBarTitle1.init (mapInfoXPos + 5, scrollListsYPos + 30, - labelWidth, 20); - keyMapScrollBarTitle1.setText (lang.getString ("MapTitle1")); - keyMapScrollBarTitle1.setFont (CoreData::getInstance (). - getMenuFontBig ()); - keyMapScrollBarTitle1.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - keyMapScrollBarTitle2.registerGraphicComponent (containerName, - "keyMapScrollBarTitle2"); - keyMapScrollBarTitle2.init (mapInfoXPos - 10 + keyButtonsWidthMap, - scrollListsYPos + 17, labelWidth, 20); - keyMapScrollBarTitle2.setText (lang.getString ("MapTitle2")); - keyMapScrollBarTitle2.setFont (CoreData::getInstance (). - getMenuFontNormal ()); - keyMapScrollBarTitle2.setFont3D (CoreData::getInstance (). - getMenuFontNormal3D ()); - - tilesetInfoXPos = 530; - keyTilesetScrollBarTitle1.registerGraphicComponent (containerName, - "keyTilesetScrollBarTitle1"); - keyTilesetScrollBarTitle1.init (tilesetInfoXPos + 5, - scrollListsYPos + 30, labelWidth, 20); - keyTilesetScrollBarTitle1.setText (lang.getString ("TilesetTitle1")); - keyTilesetScrollBarTitle1.setFont (CoreData::getInstance (). - getMenuFontBig ()); - keyTilesetScrollBarTitle1.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - - - scenarioInfoXPos = 755; - keyScenarioScrollBarTitle1.registerGraphicComponent (containerName, - "keyScenarioScrollBarTitle1"); - keyScenarioScrollBarTitle1.init (scenarioInfoXPos, scrollListsYPos + 30, - labelWidth, 20); - keyScenarioScrollBarTitle1.setText (lang.getString ("ScenarioTitle1")); - keyScenarioScrollBarTitle1.setFont (CoreData::getInstance (). - getMenuFontBig ()); - keyScenarioScrollBarTitle1.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - - mainMessageBoxState = ftpmsg_None; - mainMessageBox.registerGraphicComponent (containerName, - "mainMessageBox"); - mainMessageBox.init (lang.getString ("Yes"), lang.getString ("No"), - 450); - mainMessageBox.setEnabled (false); - - lineHorizontal.init (0, installButtonYPos - 60); - lineVertical.init (500, returnLineY, 5, - installButtonYPos - 60 - returnLineY); - lineVertical.setHorizontal (false); - lineReturn.init (0, returnLineY); - - modDescrLabel.registerGraphicComponent (containerName, "modDescrLabel"); - modDescrLabel.init (15, installButtonYPos - 60 - 20, 450, 20); - modDescrLabel.setWordWrap (true); - modDescrLabel.setText ("description is empty"); - - pleaseWaitLabel.registerGraphicComponent (containerName, - "pleaseWaitLabel"); - pleaseWaitLabel.init (50, installButtonYPos - 120, 450, 20); - pleaseWaitLabel.setText (""); - pleaseWaitLabel.setFont (CoreData::getInstance ().getMenuFontBig ()); - pleaseWaitLabel.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - - buttonReturn.registerGraphicComponent (containerName, "buttonReturn"); - buttonReturn.init (800, returnLineY - 30, 125); - buttonReturn.setText (lang.getString ("Return")); - - lineVerticalReturn.init (buttonReturn.getX () - 10, returnLineY - 80, 5, - 81); - lineVerticalReturn.setHorizontal (false); - - int buttonLineUpY = installButtonYPos + 10; - int buttonLineDownY = installButtonYPos - 20; - - int legendButtonY = buttonLineDownY - 30; - buttonInstalled.registerGraphicComponent (containerName, - "buttonInstalled"); - buttonInstalled.init (5, legendButtonY, 240); - buttonInstalled.setText (" " + lang.getString ("ModInstalled")); - buttonInstalled.setUseCustomTexture (true); - buttonInstalled.setCustomTexture (CoreData::getInstance (). - getOnServerInstalledTexture ()); - buttonInstalled.setEnabled (false); - - buttonAvailable.registerGraphicComponent (containerName, - "buttonAvailable"); - buttonAvailable.init (255, legendButtonY, 240); - buttonAvailable.setUseCustomTexture (true); - buttonAvailable.setCustomTexture (CoreData::getInstance (). - getOnServerTexture ()); - buttonAvailable.setText (" " + lang.getString ("ModAvailable")); - - buttonOnlyLocal.registerGraphicComponent (containerName, - "buttonOnlyLocal"); - buttonOnlyLocal.init (505, legendButtonY, 240); - buttonOnlyLocal.setUseCustomTexture (true); - buttonOnlyLocal.setCustomTexture (CoreData::getInstance (). - getNotOnServerTexture ()); - buttonOnlyLocal.setText (" " + lang.getString ("ModOnlyLocal")); - - buttonConflict.registerGraphicComponent (containerName, - "buttonConflict"); - buttonConflict.init (755, legendButtonY, 240); - buttonConflict.setUseCustomTexture (true); - buttonConflict.setCustomTexture (CoreData::getInstance (). - getOnServerDifferentTexture ()); - buttonConflict.setText (" " + lang.getString ("ModHasConflict")); - - - buttonInstallTech.registerGraphicComponent (containerName, - "buttonInstallTech"); - buttonInstallTech.init (techInfoXPos + 45, buttonLineUpY, 125); - buttonInstallTech.setText (lang.getString ("Install")); - buttonRemoveTech.registerGraphicComponent (containerName, - "buttonRemoveTech"); - buttonRemoveTech.init (techInfoXPos + 45, buttonLineDownY, 125); - buttonRemoveTech.setText (lang.getString ("Remove")); - - buttonInstallTileset.registerGraphicComponent (containerName, - "buttonInstallTileset"); - buttonInstallTileset.init (tilesetInfoXPos + 30, buttonLineUpY, 125); - buttonInstallTileset.setText (lang.getString ("Install")); - buttonRemoveTileset.registerGraphicComponent (containerName, - "buttonRemoveTileset"); - buttonRemoveTileset.init (tilesetInfoXPos + 30, buttonLineDownY, 125); - buttonRemoveTileset.setText (lang.getString ("Remove")); - - buttonInstallMap.registerGraphicComponent (containerName, - "buttonInstallMap"); - buttonInstallMap.init (mapInfoXPos + 50, buttonLineUpY, 125); - buttonInstallMap.setText (lang.getString ("Install")); - buttonRemoveMap.registerGraphicComponent (containerName, - "buttonRemoveMap"); - buttonRemoveMap.init (mapInfoXPos + 50, buttonLineDownY, 125); - buttonRemoveMap.setText (lang.getString ("Remove")); - - buttonInstallScenario.registerGraphicComponent (containerName, - "buttonInstallScenario"); - buttonInstallScenario.init (scenarioInfoXPos + 45, buttonLineUpY, 125); - buttonInstallScenario.setText (lang.getString ("Install")); - buttonRemoveScenario.registerGraphicComponent (containerName, - "buttonRemoveScenario"); - buttonRemoveScenario.init (scenarioInfoXPos + 45, buttonLineDownY, 125); - buttonRemoveScenario.setText (lang.getString ("Remove")); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - keyTilesetScrollBar.init (tilesetInfoXPos + keyButtonsWidthTil, - scrollListsYPos - listBoxLength + - keyButtonsLineHeight, false, 200, 20); - keyTilesetScrollBar.setLength (listBoxLength); - keyTilesetScrollBar.setElementCount (0); - keyTilesetScrollBar.setVisibleSize (keyButtonsToRender); - keyTilesetScrollBar.setVisibleStart (0); - - keyTechScrollBar.init (techInfoXPos + keyButtonsWidthTech + labelWidth + - 20, - scrollListsYPos - listBoxLength + - keyButtonsLineHeight, false, 200, 20); - keyTechScrollBar.setLength (listBoxLength); - keyTechScrollBar.setElementCount (0); - keyTechScrollBar.setVisibleSize (keyButtonsToRender); - keyTechScrollBar.setVisibleStart (0); - - keyMapScrollBar.init (mapInfoXPos + keyButtonsWidthMap + labelWidth + - 20, - scrollListsYPos - listBoxLength + - keyButtonsLineHeight, false, 200, 20); - keyMapScrollBar.setLength (listBoxLength); - keyMapScrollBar.setElementCount (0); - keyMapScrollBar.setVisibleSize (keyButtonsToRender); - keyMapScrollBar.setVisibleStart (0); - - keyScenarioScrollBar.init (scenarioInfoXPos + keyButtonsWidthScen, - scrollListsYPos - listBoxLength + - keyButtonsLineHeight, false, 200, 20); - keyScenarioScrollBar.setLength (listBoxLength); - keyScenarioScrollBar.setElementCount (0); - keyScenarioScrollBar.setVisibleSize (keyButtonsToRender); - keyScenarioScrollBar.setVisibleStart (0); - - GraphicComponent::applyAllCustomProperties (containerName); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - // Start http meta data thread - static string mutexOwnerId = - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - string ("_") + intToStr (__LINE__); - modHttpServerThread = new SimpleTaskThread (this, 0, 200); - modHttpServerThread->setUniqueID (mutexOwnerId); - modHttpServerThread->start (); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - // Setup File Transfer thread - findDirs (config.getPathListForType (ptTilesets), tilesetFiles); - findDirs (config.getPathListForType (ptTechs), techTreeFiles); - - vector < string > mapPathList = config.getPathListForType (ptMaps); - std::pair < string, string > mapsPath; - if (mapPathList.empty () == false) - { - mapsPath.first = mapPathList[0]; - } - if (mapPathList.size () > 1) - { - mapsPath.second = mapPathList[1]; - } - std::pair < string, string > tilesetsPath; - vector < string > tilesetsList = - Config::getInstance ().getPathListForType (ptTilesets); - if (tilesetsList.empty () == false) - { - tilesetsPath.first = tilesetsList[0]; - if (tilesetsList.size () > 1) - { - tilesetsPath.second = tilesetsList[1]; - } - } - - std::pair < string, string > techtreesPath; - vector < string > techtreesList = - Config::getInstance ().getPathListForType (ptTechs); - if (techtreesList.empty () == false) - { - techtreesPath.first = techtreesList[0]; - if (techtreesList.size () > 1) - { - techtreesPath.second = techtreesList[1]; - } - } - - std::pair < string, string > scenariosPath; - vector < string > scenariosList = - Config::getInstance ().getPathListForType (ptScenarios); - if (scenariosList.empty () == false) - { - scenariosPath.first = scenariosList[0]; - if (scenariosList.size () > 1) - { - scenariosPath.second = scenariosList[1]; - } - } - - string fileArchiveExtension = - config.getString ("FileArchiveExtension", ""); - string fileArchiveExtractCommand = - config.getString ("FileArchiveExtractCommand", ""); - string fileArchiveExtractCommandParameters = - config.getString ("FileArchiveExtractCommandParameters", ""); - int32 fileArchiveExtractCommandSuccessResult = - config.getInt ("FileArchiveExtractCommandSuccessResult", "0"); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - console.setOnlyChatMessagesInStoredLines (false); - - // Get path to temp files - string tempFilePath = "temp/"; - if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) != - "") - { - tempFilePath = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - tempFilePath; - } - else - { - string userData = config.getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - tempFilePath = userData + tempFilePath; - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Temp files path [%s]\n", tempFilePath.c_str ()); - - ftpClientThread = new FTPClientThread (-1, "", - mapsPath, tilesetsPath, - techtreesPath, scenariosPath, - this, fileArchiveExtension, - fileArchiveExtractCommand, - fileArchiveExtractCommandParameters, - fileArchiveExtractCommandSuccessResult, - tempFilePath); - ftpClientThread->start (); - - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - void MenuStateMods::reloadUI () - { - Lang & lang = Lang::getInstance (); - - console.resetFonts (); - keyTechScrollBarTitle1.setText (lang.getString ("TechTitle1")); - keyTechScrollBarTitle1.setFont (CoreData::getInstance (). - getMenuFontBig ()); - keyTechScrollBarTitle1.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - keyTechScrollBarTitle2.setText (lang.getString ("TechTitle2")); - keyTechScrollBarTitle2.setFont (CoreData::getInstance (). - getMenuFontNormal ()); - keyTechScrollBarTitle2.setFont3D (CoreData::getInstance (). - getMenuFontNormal3D ()); - - keyMapScrollBarTitle1.setText (lang.getString ("MapTitle1")); - keyMapScrollBarTitle1.setFont (CoreData::getInstance (). - getMenuFontBig ()); - keyMapScrollBarTitle1.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - keyMapScrollBarTitle2.setText (lang.getString ("MapTitle2")); - keyMapScrollBarTitle2.setFont (CoreData::getInstance (). - getMenuFontNormal ()); - keyMapScrollBarTitle2.setFont3D (CoreData::getInstance (). - getMenuFontNormal3D ()); - - keyTilesetScrollBarTitle1.setText (lang.getString ("TilesetTitle1")); - keyTilesetScrollBarTitle1.setFont (CoreData::getInstance (). - getMenuFontBig ()); - keyTilesetScrollBarTitle1.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - - pleaseWaitLabel.setText (""); - pleaseWaitLabel.setFont (CoreData::getInstance ().getMenuFontBig ()); - pleaseWaitLabel.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - - keyScenarioScrollBarTitle1.setText (lang.getString ("ScenarioTitle1")); - keyScenarioScrollBarTitle1.setFont (CoreData::getInstance (). - getMenuFontBig ()); - keyScenarioScrollBarTitle1.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - - mainMessageBox.init (lang.getString ("Yes"), lang.getString ("No"), - 450); - - modDescrLabel.setText ("description is empty"); - - buttonReturn.setText (lang.getString ("Return")); - - buttonInstalled.setText (lang.getString ("ModInstalled")); - - buttonAvailable.setText (lang.getString ("ModAvailable")); - - buttonOnlyLocal.setText (lang.getString ("ModOnlyLocal")); - - buttonConflict.setText (lang.getString ("ModHasConflict")); - - buttonInstallTech.setText (lang.getString ("Install")); - buttonRemoveTech.setText (lang.getString ("Remove")); - - buttonInstallTileset.setText (lang.getString ("Install")); - buttonRemoveTileset.setText (lang.getString ("Remove")); - - buttonInstallMap.setText (lang.getString ("Install")); - buttonRemoveMap.setText (lang.getString ("Remove")); - - buttonInstallScenario.setText (lang.getString ("Install")); - buttonRemoveScenario.setText (lang.getString ("Remove")); - - GraphicComponent:: - reloadFontsForRegisterGraphicComponents (containerName); - } - - void MenuStateMods::simpleTask (BaseThread * callingThread, - void *userdata) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutexThreadOwner (callingThread-> - getMutexThreadOwnerValid (), - mutexOwnerId); - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - callingThread->getMutexThreadOwnerValid ()->setOwnerId (mutexOwnerId); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - Lang & lang = Lang::getInstance (); - Config & config = Config::getInstance (); - string fileArchiveExtractCommand = - config.getString ("FileArchiveExtractCommand", ""); - int expectedResult = - config.getInt ("FileArchiveExtractCommandSuccessResult", "0"); - bool findArchive = - executeShellCommand (fileArchiveExtractCommand, expectedResult); - if (findArchive == false) - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - showMessageBox (lang.getString ("ModRequires7z"), - lang.getString ("Notice"), true); - } - - std::string techsMetaData = ""; - std::string tilesetsMetaData = ""; - std::string mapsMetaData = ""; - std::string scenariosMetaData = ""; - - modMenuState = mmst_Loading; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - if (config.getString ("Masterserver", "") != "") - { - string baseURL = config.getString ("Masterserver"); - if (baseURL != "") - { - endPathWithSlash (baseURL, false); - } - - string phpVersionParam = - config.getString ("phpVersionParam", "?version=0.1"); - string playerUUID = - "&uuid=" + - SystemFlags::escapeURL (Config::getInstance (). - getString ("PlayerId", "")); - string gameVersion = - "&glestVersion=" + SystemFlags::escapeURL (glestVersionString); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line %d] About to call first http url, base [%s]..\n", - __FILE__, __FUNCTION__, __LINE__, baseURL.c_str ()); - - CURL *handle = SystemFlags::initHTTP (); - CURLcode curlResult = CURLE_OK; - techsMetaData = - SystemFlags::getHTTP (baseURL + "showTechsForGlest.php" + - phpVersionParam + gameVersion + playerUUID, - handle, -1, &curlResult); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("techsMetaData [%s] curlResult = %d\n", - techsMetaData.c_str (), curlResult); - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - if (curlResult != CURLE_OK) - { - string curlError = curl_easy_strerror (curlResult); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModErrorGettingServerData").c_str (), - curlError.c_str ()); - console.addLine (string ("#1 ") + szBuf, true); - } - - if (curlResult == CURLE_OK || - (curlResult != CURLE_COULDNT_RESOLVE_HOST && - curlResult != CURLE_COULDNT_CONNECT)) - { - - tilesetsMetaData = - SystemFlags::getHTTP (baseURL + "showTilesetsForGlest.php" + - phpVersionParam + gameVersion, handle, -1, - &curlResult); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("tilesetsMetaData [%s]\n", tilesetsMetaData.c_str ()); - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - if (curlResult != CURLE_OK) - { - string curlError = curl_easy_strerror (curlResult); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModErrorGettingServerData").c_str (), - curlError.c_str ()); - console.addLine (string ("#2 ") + szBuf, true); - } - - mapsMetaData = - SystemFlags::getHTTP (baseURL + "showMapsForGlest.php" + - phpVersionParam + gameVersion, handle, -1, - &curlResult); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("mapsMetaData [%s]\n", mapsMetaData.c_str ()); - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - if (curlResult != CURLE_OK) - { - string curlError = curl_easy_strerror (curlResult); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModErrorGettingServerData").c_str (), - curlError.c_str ()); - console.addLine (string ("#3 ") + szBuf, true); - } - - scenariosMetaData = - SystemFlags::getHTTP (baseURL + "showScenariosForGlest.php" + - phpVersionParam + gameVersion, handle, -1, - &curlResult); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("scenariosMetaData [%s]\n", scenariosMetaData.c_str ()); - - if (curlResult != CURLE_OK) - { - string curlError = curl_easy_strerror (curlResult); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModErrorGettingServerData").c_str (), - curlError.c_str ()); - console.addLine (string ("#4 ") + szBuf, true); - } - } - SystemFlags::cleanupHTTP (&handle); - } - else - { - console.addLine (lang.getString ("MasterServerMissing"), true); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - tilesetListRemote.clear (); - Tokenize (tilesetsMetaData, tilesetListRemote, "\n"); - - modMenuState = mmst_CalculatingCRC; - - getTilesetsLocalList (); - for (unsigned int i = 0; i < tilesetListRemote.size (); i++) - { - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - string result = refreshTilesetModInfo (tilesetListRemote[i]); - if (result != "") - { - ModInfo modinfo; - modinfo = tilesetCacheList[result]; - GraphicButton *button = new GraphicButton (); - button->init (tilesetInfoXPos, keyButtonsYBase, keyButtonsWidthTil, - keyButtonsHeight); - button->setText (modinfo.name); - button->setUseCustomTexture (true); - button->setCustomTexture (CoreData::getInstance (). - getCustomTexture ()); - keyTilesetButtons.push_back (button); - } - } - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - for (unsigned int i = 0; i < tilesetFilesUserData.size (); i++) - { - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - string tilesetName = tilesetFilesUserData[i]; - bool alreadyHasTileset = - (tilesetCacheList.find (tilesetName) != tilesetCacheList.end ()); - if (alreadyHasTileset == false) - { - GraphicButton *button = new GraphicButton (); - button->init (tilesetInfoXPos, keyButtonsYBase, keyButtonsWidthTil, - keyButtonsHeight); - button->setText (tilesetName); - button->setUseCustomTexture (true); - button->setCustomTexture (CoreData::getInstance (). - getCustomTexture ()); - keyTilesetButtons.push_back (button); - } - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - techListRemote.clear (); - Tokenize (techsMetaData, techListRemote, "\n"); - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - getTechsLocalList (); - for (unsigned int i = 0; i < techListRemote.size (); i++) - { - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - string result = refreshTechModInfo (techListRemote[i]); - if (result != "") - { - ModInfo modinfo; - modinfo = techCacheList[result]; - - GraphicButton *button = new GraphicButton (); - button->init (techInfoXPos, keyButtonsYBase, keyButtonsWidthTech, - keyButtonsHeight); - button->setText (modinfo.name); - button->setUseCustomTexture (true); - button->setCustomTexture (CoreData::getInstance (). - getCustomTexture ()); - - keyTechButtons.push_back (button); - GraphicLabel *label = new GraphicLabel (); - label->init (techInfoXPos + keyButtonsWidthTech + 10, - keyButtonsYBase, labelWidth, 20); - label->setText (modinfo.count); - labelsTech.push_back (label); - } - } - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - for (unsigned int i = 0; i < techTreeFilesUserData.size (); i++) - { - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - string techName = techTreeFilesUserData[i]; - bool alreadyHasTech = - (techCacheList.find (techName) != techCacheList.end ()); - if (alreadyHasTech == false) - { - vector < string > techPaths = config.getPathListForType (ptTechs); - string & techPath = techPaths[1]; - endPathWithSlash (techPath); - vector < string > factions; - findAll (techPath + techName + "/factions/*.", factions, false, - false); - - GraphicButton *button = new GraphicButton (); - button->init (techInfoXPos, keyButtonsYBase, keyButtonsWidthTech, - keyButtonsHeight); - button->setText (techName); - button->setUseCustomTexture (true); - button->setCustomTexture (CoreData::getInstance (). - getCustomTexture ()); - keyTechButtons.push_back (button); - - int techFactionCount = (int) factions.size (); - GraphicLabel *label = new GraphicLabel (); - label->init (techInfoXPos + keyButtonsWidthTech + 10, - keyButtonsYBase, labelWidth, 20); - label->setText (intToStr (techFactionCount)); - labelsTech.push_back (label); - } - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - mapListRemote.clear (); - Tokenize (mapsMetaData, mapListRemote, "\n"); - - getMapsLocalList (); - for (unsigned int i = 0; i < mapListRemote.size (); i++) - { - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - string result = refreshMapModInfo (mapListRemote[i]); - if (result != "") - { - ModInfo modinfo; - modinfo = mapCacheList[result]; - - GraphicButton *button = new GraphicButton (); - button->init (mapInfoXPos, keyButtonsYBase, keyButtonsWidthMap, - keyButtonsHeight); - button->setText (modinfo.name); - button->setUseCustomTexture (true); - button->setCustomTexture (CoreData::getInstance (). - getCustomTexture ()); - keyMapButtons.push_back (button); - - GraphicLabel *label = new GraphicLabel (); - label->init (mapInfoXPos + keyButtonsWidthMap + 10, keyButtonsYBase, - labelWidth, 20); - label->setText (modinfo.count); - labelsMap.push_back (label); - } - } - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - for (unsigned int i = 0; i < mapFilesUserData.size (); i++) - { - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - string mapName = mapFilesUserData[i]; - bool alreadyHasMap = - (mapCacheList.find (mapName) != mapCacheList.end ()); - if (alreadyHasMap == false) - { - vector < string > mapPaths = config.getPathListForType (ptMaps); - string & mapPath = mapPaths[1]; - endPathWithSlash (mapPath); - mapPath += mapName; - MapInfo mapInfo = loadMapInfo (mapPath); - - GraphicButton *button = new GraphicButton (); - button->init (mapInfoXPos, keyButtonsYBase, keyButtonsWidthMap, - keyButtonsHeight); - button->setText (mapName); - button->setUseCustomTexture (true); - button->setCustomTexture (CoreData::getInstance (). - getCustomTexture ()); - keyMapButtons.push_back (button); - - int mapPlayerCount = mapInfo.players; - GraphicLabel *label = new GraphicLabel (); - label->init (mapInfoXPos + keyButtonsWidthMap + 10, keyButtonsYBase, - labelWidth, 20); - label->setText (intToStr (mapPlayerCount)); - labelsMap.push_back (label); - } - } - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - - scenarioListRemote.clear (); - Tokenize (scenariosMetaData, scenarioListRemote, "\n"); - - getScenariosLocalList (); - for (unsigned int i = 0; i < scenarioListRemote.size (); i++) - { - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - string result = refreshScenarioModInfo (scenarioListRemote[i]); - if (result != "") - { - ModInfo modinfo; - modinfo = scenarioCacheList[result]; - GraphicButton *button = new GraphicButton (); - button->init (scenarioInfoXPos, keyButtonsYBase, - keyButtonsWidthScen, keyButtonsHeight); - button->setText (modinfo.name); - button->setUseCustomTexture (true); - button->setCustomTexture (CoreData::getInstance (). - getCustomTexture ()); - keyScenarioButtons.push_back (button); - } - } - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - for (unsigned int i = 0; i < scenarioFilesUserData.size (); i++) - { - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - string scenarioName = scenarioFilesUserData[i]; - bool alreadyHasScenario = - (scenarioCacheList.find (scenarioName) != scenarioCacheList.end ()); - if (alreadyHasScenario == false) - { - vector < string > scenarioPaths = - config.getPathListForType (ptScenarios); - string & scenarioPath = scenarioPaths[1]; - endPathWithSlash (scenarioPath); - scenarioPath += scenarioName; - - GraphicButton *button = new GraphicButton (); - button->init (scenarioInfoXPos, keyButtonsYBase, - keyButtonsWidthScen, keyButtonsHeight); - button->setText (scenarioName); - button->setUseCustomTexture (true); - button->setCustomTexture (CoreData::getInstance (). - getCustomTexture ()); - keyScenarioButtons.push_back (button); - } - } - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - keyTilesetScrollBar.init (tilesetInfoXPos + keyButtonsWidthTil, - scrollListsYPos - listBoxLength + - keyButtonsLineHeight, false, 200, 20); - keyTilesetScrollBar.setLength (listBoxLength); - keyTilesetScrollBar.setElementCount ((int) keyTilesetButtons.size ()); - keyTilesetScrollBar.setVisibleSize (keyButtonsToRender); - keyTilesetScrollBar.setVisibleStart (0); - - keyTechScrollBar.init (techInfoXPos + keyButtonsWidthTech + labelWidth + - 20, - scrollListsYPos - listBoxLength + - keyButtonsLineHeight, false, 200, 20); - keyTechScrollBar.setLength (listBoxLength); - keyTechScrollBar.setElementCount ((int) keyTechButtons.size ()); - keyTechScrollBar.setVisibleSize (keyButtonsToRender); - keyTechScrollBar.setVisibleStart (0); - - keyMapScrollBar.init (mapInfoXPos + keyButtonsWidthMap + labelWidth + - 20, - scrollListsYPos - listBoxLength + - keyButtonsLineHeight, false, 200, 20); - keyMapScrollBar.setLength (listBoxLength); - keyMapScrollBar.setElementCount ((int) keyMapButtons.size ()); - keyMapScrollBar.setVisibleSize (keyButtonsToRender); - keyMapScrollBar.setVisibleStart (0); - - keyScenarioScrollBar.init (scenarioInfoXPos + keyButtonsWidthScen, - scrollListsYPos - listBoxLength + - keyButtonsLineHeight, false, 200, 20); - keyScenarioScrollBar.setLength (listBoxLength); - keyScenarioScrollBar.setElementCount ((int) keyScenarioButtons.size ()); - keyScenarioScrollBar.setVisibleSize (keyButtonsToRender); - keyScenarioScrollBar.setVisibleStart (0); - - modMenuState = mmst_None; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - if (modHttpServerThread != NULL) - { - modHttpServerThread->signalQuit (); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - } - - MapInfo MenuStateMods::loadMapInfo (string file) - { - try - { - Lang & lang = Lang::getInstance (); - // Not painting properly so this is on hold - MapPreview::loadMapInfo (file, &mapInfo, - lang.getString ("MaxPlayers"), - lang.getString ("Size"), true); - } - catch (exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s] loading map [%s]\n", - __FILE__, __FUNCTION__, __LINE__, e.what (), - file.c_str ()); - throw megaglest_runtime_error ("Error loading map file: [" + file + - "] msg: " + e.what ()); - } - - return mapInfo; - } - - void MenuStateMods::getTechsLocalList () - { - Config & config = Config::getInstance (); - vector < string > results; - findDirs (config.getPathListForType (ptTechs), results); - techTreeFiles = results; - - techTreeFilesUserData.clear (); - if (config.getPathListForType (ptTechs).size () > 1) - { - string path = config.getPathListForType (ptTechs)[1]; - endPathWithSlash (path); - findDirs (path, techTreeFilesUserData, false, false); - } - } - - string MenuStateMods::refreshTechModInfo (string techInfo) - { - std::vector < std::string > techInfoList; - Tokenize (techInfo, techInfoList, "|"); - if (techInfoList.size () >= 6) - { - Config & config = Config::getInstance (); - ModInfo modinfo; - modinfo.name = techInfoList[0]; - modinfo.count = techInfoList[1]; - modinfo.crc = techInfoList[2]; - modinfo.description = techInfoList[3]; - modinfo.url = techInfoList[4]; - modinfo.imageUrl = techInfoList[5]; - modinfo.type = mt_Techtree; - - string itemPath = - config.getPathListForType (ptTechs, - "")[1] + "/" + modinfo.name + - string ("/*"); - if (itemPath.empty () == false) - { - bool forceRefresh = - (mapCRCUpdateList.find (itemPath) == mapCRCUpdateList.end ()); - uint32 crc = - getFolderTreeContentsCheckSumRecursively (itemPath, ".xml", NULL, - forceRefresh); - if (crc == 0) - { - itemPath = - config.getPathListForType (ptTechs, - "")[0] + "/" + modinfo.name + - string ("/*"); - if (itemPath.empty () == false) - { - forceRefresh = - (mapCRCUpdateList.find (itemPath) == mapCRCUpdateList.end ()); - crc = - getFolderTreeContentsCheckSumRecursively (itemPath, ".xml", - NULL, forceRefresh); - } - } - modinfo.localCRC = uIntToStr (crc); - //printf("itemPath='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); - } - else - { - modinfo.localCRC = ""; - } - techCacheList[modinfo.name] = modinfo; - return modinfo.name; - } - return ""; - } - - void MenuStateMods::refreshTechs () - { - getTechsLocalList (); - for (int i = 0; i < (int) techListRemote.size (); i++) - { - refreshTechModInfo (techListRemote[i]); - } - } - - void MenuStateMods::getTilesetsLocalList () - { - Config & config = Config::getInstance (); - vector < string > results; - findDirs (config.getPathListForType (ptTilesets), results); - tilesetFiles = results; - - tilesetFilesUserData.clear (); - if (config.getPathListForType (ptTilesets).size () > 1) - { - string path = config.getPathListForType (ptTilesets)[1]; - endPathWithSlash (path); - findDirs (path, tilesetFilesUserData, false, false); - } - } - - string MenuStateMods::refreshTilesetModInfo (string tilesetInfo) - { - std::vector < std::string > tilesetInfoList; - Tokenize (tilesetInfo, tilesetInfoList, "|"); - if (tilesetInfoList.size () >= 5) - { - Config & config = Config::getInstance (); - ModInfo modinfo; - modinfo.name = tilesetInfoList[0]; - modinfo.crc = tilesetInfoList[1]; - modinfo.description = tilesetInfoList[2]; - modinfo.url = tilesetInfoList[3]; - modinfo.imageUrl = tilesetInfoList[4]; - modinfo.type = mt_Tileset; - - string itemPath = - config.getPathListForType (ptTilesets, - "")[1] + "/" + modinfo.name + - string ("/*"); - if (itemPath.empty () == false) - { - bool forceRefresh = - (mapCRCUpdateList.find (itemPath) == mapCRCUpdateList.end ()); - uint32 crc = - getFolderTreeContentsCheckSumRecursively (itemPath, ".xml", NULL, - forceRefresh); - if (crc == 0) - { - itemPath = - config.getPathListForType (ptTilesets, - "")[0] + "/" + modinfo.name + - string ("/*"); - if (itemPath.empty () == false) - { - forceRefresh = - (mapCRCUpdateList.find (itemPath) == mapCRCUpdateList.end ()); - crc = - getFolderTreeContentsCheckSumRecursively (itemPath, ".xml", - NULL, forceRefresh); - } - } - modinfo.localCRC = uIntToStr (crc); - //printf("itemPath='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); - - //printf("#1 refreshTilesetModInfo name [%s] modInfo.crc [%s] modInfo.localCRC [%s]\n",modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str()); - } - else - { - modinfo.localCRC = ""; - - //printf("#2 refreshTilesetModInfo name [%s] modInfo.crc [%s] modInfo.localCRC [%s]\n",modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str()); - } - - tilesetCacheList[modinfo.name] = modinfo; - return modinfo.name; - } - return ""; - } - - void MenuStateMods::refreshTilesets () - { - getTilesetsLocalList (); - for (int i = 0; i < (int) tilesetListRemote.size (); i++) - { - refreshTilesetModInfo (tilesetListRemote[i]); - } - } - - void MenuStateMods::getMapsLocalList () - { - -/* - Config &config = Config::getInstance(); - vector results; - set allMaps; - findAll(config.getPathListForType(ptMaps), "*.gbm", results, false, false); - copy(results.begin(), results.end(), std::inserter(allMaps, allMaps.begin())); - results.clear(); - findAll(config.getPathListForType(ptMaps), "*.mgm", results, false, false); - copy(results.begin(), results.end(), std::inserter(allMaps, allMaps.begin())); - results.clear(); - - copy(allMaps.begin(), allMaps.end(), std::back_inserter(results)); - mapFiles = results; - - mapFilesUserData.clear(); - if(config.getPathListForType(ptMaps).size() > 1) { - string path = config.getPathListForType(ptMaps)[1]; - endPathWithSlash(path); - - vector results2; - set allMaps2; - findAll(path + "*.gbm", results2, false, false); - copy(results2.begin(), results2.end(), std::inserter(allMaps2, allMaps2.begin())); - - results2.clear(); - findAll(path + "*.mgm", results2, false, false); - copy(results2.begin(), results2.end(), std::inserter(allMaps2, allMaps2.begin())); - - results2.clear(); - copy(allMaps2.begin(), allMaps2.end(), std::back_inserter(results2)); - mapFilesUserData = results2; - //printf("\n\nMap path [%s] mapFilesUserData.size() = %d\n\n\n",path.c_str(),mapFilesUserData.size()); +namespace Glest { + namespace Game { + + using namespace::Shared::Util; + + struct FormatString { + void operator () (string & s) { + s = formatString(s); + } + }; + + + + // =============================== + // class ModInfo + // =============================== + + ModInfo::ModInfo() { + name = ""; + url = ""; + imageUrl = ""; + description = ""; + count = ""; + crc = ""; + type = mt_None; + } + + + + // ===================================================== + // class MenuStateConnectedGame + // ===================================================== + + MenuStateMods::MenuStateMods(Program * program, + MainMenu * mainMenu) :MenuState(program, + mainMenu, + "mods") { + + containerName = "Mods"; + Lang & lang = Lang::getInstance(); + Config & config = Config::getInstance(); + + modPreviewImage = NULL; + displayModPreviewImage.clear(); + + ftpClientThread = NULL; + selectedTechName = ""; + selectedTilesetName = ""; + selectedMapName = ""; + selectedScenarioName = ""; + modInfoSelected = NULL; + showFullConsole = false; + keyButtonsLineHeight = 20; + keyButtonsHeight = 20; + keyButtonsWidth = 200; + keyButtonsWidthTech = keyButtonsWidth; + keyButtonsWidthMap = keyButtonsWidth + 15; + keyButtonsWidthTil = keyButtonsWidth - 5; + keyButtonsWidthScen = keyButtonsWidth + 20; + scrollListsYPos = 700; + listBoxLength = 200; + keyButtonsYBase = scrollListsYPos; + keyButtonsToRender = listBoxLength / keyButtonsLineHeight; + labelWidth = 5; + keyButtonsXBase = 0; + modMenuState = mmst_None; + oldMenuState = mmst_None; + + int installButtonYPos = scrollListsYPos - listBoxLength - 20; + + int returnLineY = 80; + enableMapPreview = config.getBool("MapPreview", "true"); + validMapPreview = false; + mapPreviewTexture = NULL; + + //create + techInfoXPos = 5; + keyTechScrollBarTitle1.registerGraphicComponent(containerName, + "keyTechScrollBarTitle1"); + keyTechScrollBarTitle1.init(techInfoXPos + 5, scrollListsYPos + 30, + labelWidth, 20); + keyTechScrollBarTitle1.setText(lang.getString("TechTitle1")); + keyTechScrollBarTitle1.setFont(CoreData::getInstance(). + getMenuFontBig()); + keyTechScrollBarTitle1.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + keyTechScrollBarTitle2.registerGraphicComponent(containerName, + "keyTechScrollBarTitle2"); + keyTechScrollBarTitle2.init(techInfoXPos - 10 + keyButtonsWidthTech, + scrollListsYPos + 17, labelWidth, 20); + keyTechScrollBarTitle2.setText(lang.getString("TechTitle2")); + keyTechScrollBarTitle2.setFont(CoreData::getInstance(). + getMenuFontNormal()); + keyTechScrollBarTitle2.setFont3D(CoreData::getInstance(). + getMenuFontNormal3D()); + + mapInfoXPos = 260; + keyMapScrollBarTitle1.registerGraphicComponent(containerName, + "keyMapScrollBarTitle1"); + keyMapScrollBarTitle1.init(mapInfoXPos + 5, scrollListsYPos + 30, + labelWidth, 20); + keyMapScrollBarTitle1.setText(lang.getString("MapTitle1")); + keyMapScrollBarTitle1.setFont(CoreData::getInstance(). + getMenuFontBig()); + keyMapScrollBarTitle1.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + keyMapScrollBarTitle2.registerGraphicComponent(containerName, + "keyMapScrollBarTitle2"); + keyMapScrollBarTitle2.init(mapInfoXPos - 10 + keyButtonsWidthMap, + scrollListsYPos + 17, labelWidth, 20); + keyMapScrollBarTitle2.setText(lang.getString("MapTitle2")); + keyMapScrollBarTitle2.setFont(CoreData::getInstance(). + getMenuFontNormal()); + keyMapScrollBarTitle2.setFont3D(CoreData::getInstance(). + getMenuFontNormal3D()); + + tilesetInfoXPos = 530; + keyTilesetScrollBarTitle1.registerGraphicComponent(containerName, + "keyTilesetScrollBarTitle1"); + keyTilesetScrollBarTitle1.init(tilesetInfoXPos + 5, + scrollListsYPos + 30, labelWidth, 20); + keyTilesetScrollBarTitle1.setText(lang.getString("TilesetTitle1")); + keyTilesetScrollBarTitle1.setFont(CoreData::getInstance(). + getMenuFontBig()); + keyTilesetScrollBarTitle1.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + + + scenarioInfoXPos = 755; + keyScenarioScrollBarTitle1.registerGraphicComponent(containerName, + "keyScenarioScrollBarTitle1"); + keyScenarioScrollBarTitle1.init(scenarioInfoXPos, scrollListsYPos + 30, + labelWidth, 20); + keyScenarioScrollBarTitle1.setText(lang.getString("ScenarioTitle1")); + keyScenarioScrollBarTitle1.setFont(CoreData::getInstance(). + getMenuFontBig()); + keyScenarioScrollBarTitle1.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + + mainMessageBoxState = ftpmsg_None; + mainMessageBox.registerGraphicComponent(containerName, + "mainMessageBox"); + mainMessageBox.init(lang.getString("Yes"), lang.getString("No"), + 450); + mainMessageBox.setEnabled(false); + + lineHorizontal.init(0, installButtonYPos - 60); + lineVertical.init(500, returnLineY, 5, + installButtonYPos - 60 - returnLineY); + lineVertical.setHorizontal(false); + lineReturn.init(0, returnLineY); + + modDescrLabel.registerGraphicComponent(containerName, "modDescrLabel"); + modDescrLabel.init(15, installButtonYPos - 60 - 20, 450, 20); + modDescrLabel.setWordWrap(true); + modDescrLabel.setText("description is empty"); + + pleaseWaitLabel.registerGraphicComponent(containerName, + "pleaseWaitLabel"); + pleaseWaitLabel.init(50, installButtonYPos - 120, 450, 20); + pleaseWaitLabel.setText(""); + pleaseWaitLabel.setFont(CoreData::getInstance().getMenuFontBig()); + pleaseWaitLabel.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + + buttonReturn.registerGraphicComponent(containerName, "buttonReturn"); + buttonReturn.init(800, returnLineY - 30, 125); + buttonReturn.setText(lang.getString("Return")); + + lineVerticalReturn.init(buttonReturn.getX() - 10, returnLineY - 80, 5, + 81); + lineVerticalReturn.setHorizontal(false); + + int buttonLineUpY = installButtonYPos + 10; + int buttonLineDownY = installButtonYPos - 20; + + int legendButtonY = buttonLineDownY - 30; + buttonInstalled.registerGraphicComponent(containerName, + "buttonInstalled"); + buttonInstalled.init(5, legendButtonY, 240); + buttonInstalled.setText(" " + lang.getString("ModInstalled")); + buttonInstalled.setUseCustomTexture(true); + buttonInstalled.setCustomTexture(CoreData::getInstance(). + getOnServerInstalledTexture()); + buttonInstalled.setEnabled(false); + + buttonAvailable.registerGraphicComponent(containerName, + "buttonAvailable"); + buttonAvailable.init(255, legendButtonY, 240); + buttonAvailable.setUseCustomTexture(true); + buttonAvailable.setCustomTexture(CoreData::getInstance(). + getOnServerTexture()); + buttonAvailable.setText(" " + lang.getString("ModAvailable")); + + buttonOnlyLocal.registerGraphicComponent(containerName, + "buttonOnlyLocal"); + buttonOnlyLocal.init(505, legendButtonY, 240); + buttonOnlyLocal.setUseCustomTexture(true); + buttonOnlyLocal.setCustomTexture(CoreData::getInstance(). + getNotOnServerTexture()); + buttonOnlyLocal.setText(" " + lang.getString("ModOnlyLocal")); + + buttonConflict.registerGraphicComponent(containerName, + "buttonConflict"); + buttonConflict.init(755, legendButtonY, 240); + buttonConflict.setUseCustomTexture(true); + buttonConflict.setCustomTexture(CoreData::getInstance(). + getOnServerDifferentTexture()); + buttonConflict.setText(" " + lang.getString("ModHasConflict")); + + + buttonInstallTech.registerGraphicComponent(containerName, + "buttonInstallTech"); + buttonInstallTech.init(techInfoXPos + 45, buttonLineUpY, 125); + buttonInstallTech.setText(lang.getString("Install")); + buttonRemoveTech.registerGraphicComponent(containerName, + "buttonRemoveTech"); + buttonRemoveTech.init(techInfoXPos + 45, buttonLineDownY, 125); + buttonRemoveTech.setText(lang.getString("Remove")); + + buttonInstallTileset.registerGraphicComponent(containerName, + "buttonInstallTileset"); + buttonInstallTileset.init(tilesetInfoXPos + 30, buttonLineUpY, 125); + buttonInstallTileset.setText(lang.getString("Install")); + buttonRemoveTileset.registerGraphicComponent(containerName, + "buttonRemoveTileset"); + buttonRemoveTileset.init(tilesetInfoXPos + 30, buttonLineDownY, 125); + buttonRemoveTileset.setText(lang.getString("Remove")); + + buttonInstallMap.registerGraphicComponent(containerName, + "buttonInstallMap"); + buttonInstallMap.init(mapInfoXPos + 50, buttonLineUpY, 125); + buttonInstallMap.setText(lang.getString("Install")); + buttonRemoveMap.registerGraphicComponent(containerName, + "buttonRemoveMap"); + buttonRemoveMap.init(mapInfoXPos + 50, buttonLineDownY, 125); + buttonRemoveMap.setText(lang.getString("Remove")); + + buttonInstallScenario.registerGraphicComponent(containerName, + "buttonInstallScenario"); + buttonInstallScenario.init(scenarioInfoXPos + 45, buttonLineUpY, 125); + buttonInstallScenario.setText(lang.getString("Install")); + buttonRemoveScenario.registerGraphicComponent(containerName, + "buttonRemoveScenario"); + buttonRemoveScenario.init(scenarioInfoXPos + 45, buttonLineDownY, 125); + buttonRemoveScenario.setText(lang.getString("Remove")); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + keyTilesetScrollBar.init(tilesetInfoXPos + keyButtonsWidthTil, + scrollListsYPos - listBoxLength + + keyButtonsLineHeight, false, 200, 20); + keyTilesetScrollBar.setLength(listBoxLength); + keyTilesetScrollBar.setElementCount(0); + keyTilesetScrollBar.setVisibleSize(keyButtonsToRender); + keyTilesetScrollBar.setVisibleStart(0); + + keyTechScrollBar.init(techInfoXPos + keyButtonsWidthTech + labelWidth + + 20, + scrollListsYPos - listBoxLength + + keyButtonsLineHeight, false, 200, 20); + keyTechScrollBar.setLength(listBoxLength); + keyTechScrollBar.setElementCount(0); + keyTechScrollBar.setVisibleSize(keyButtonsToRender); + keyTechScrollBar.setVisibleStart(0); + + keyMapScrollBar.init(mapInfoXPos + keyButtonsWidthMap + labelWidth + + 20, + scrollListsYPos - listBoxLength + + keyButtonsLineHeight, false, 200, 20); + keyMapScrollBar.setLength(listBoxLength); + keyMapScrollBar.setElementCount(0); + keyMapScrollBar.setVisibleSize(keyButtonsToRender); + keyMapScrollBar.setVisibleStart(0); + + keyScenarioScrollBar.init(scenarioInfoXPos + keyButtonsWidthScen, + scrollListsYPos - listBoxLength + + keyButtonsLineHeight, false, 200, 20); + keyScenarioScrollBar.setLength(listBoxLength); + keyScenarioScrollBar.setElementCount(0); + keyScenarioScrollBar.setVisibleSize(keyButtonsToRender); + keyScenarioScrollBar.setVisibleStart(0); + + GraphicComponent::applyAllCustomProperties(containerName); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + // Start http meta data thread + static string mutexOwnerId = + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + string("_") + intToStr(__LINE__); + modHttpServerThread = new SimpleTaskThread(this, 0, 200); + modHttpServerThread->setUniqueID(mutexOwnerId); + modHttpServerThread->start(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + // Setup File Transfer thread + findDirs(config.getPathListForType(ptTilesets), tilesetFiles); + findDirs(config.getPathListForType(ptTechs), techTreeFiles); + + vector < string > mapPathList = config.getPathListForType(ptMaps); + std::pair < string, string > mapsPath; + if (mapPathList.empty() == false) { + mapsPath.first = mapPathList[0]; + } + if (mapPathList.size() > 1) { + mapsPath.second = mapPathList[1]; + } + std::pair < string, string > tilesetsPath; + vector < string > tilesetsList = + Config::getInstance().getPathListForType(ptTilesets); + if (tilesetsList.empty() == false) { + tilesetsPath.first = tilesetsList[0]; + if (tilesetsList.size() > 1) { + tilesetsPath.second = tilesetsList[1]; + } + } + + std::pair < string, string > techtreesPath; + vector < string > techtreesList = + Config::getInstance().getPathListForType(ptTechs); + if (techtreesList.empty() == false) { + techtreesPath.first = techtreesList[0]; + if (techtreesList.size() > 1) { + techtreesPath.second = techtreesList[1]; + } + } + + std::pair < string, string > scenariosPath; + vector < string > scenariosList = + Config::getInstance().getPathListForType(ptScenarios); + if (scenariosList.empty() == false) { + scenariosPath.first = scenariosList[0]; + if (scenariosList.size() > 1) { + scenariosPath.second = scenariosList[1]; + } + } + + string fileArchiveExtension = + config.getString("FileArchiveExtension", ""); + string fileArchiveExtractCommand = + config.getString("FileArchiveExtractCommand", ""); + string fileArchiveExtractCommandParameters = + config.getString("FileArchiveExtractCommandParameters", ""); + int32 fileArchiveExtractCommandSuccessResult = + config.getInt("FileArchiveExtractCommandSuccessResult", "0"); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + console.setOnlyChatMessagesInStoredLines(false); + + // Get path to temp files + string tempFilePath = "temp/"; + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != + "") { + tempFilePath = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + tempFilePath; + } else { + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + tempFilePath = userData + tempFilePath; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Temp files path [%s]\n", tempFilePath.c_str()); + + ftpClientThread = new FTPClientThread(-1, "", + mapsPath, tilesetsPath, + techtreesPath, scenariosPath, + this, fileArchiveExtension, + fileArchiveExtractCommand, + fileArchiveExtractCommandParameters, + fileArchiveExtractCommandSuccessResult, + tempFilePath); + ftpClientThread->start(); + + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + void MenuStateMods::reloadUI() { + Lang & lang = Lang::getInstance(); + + console.resetFonts(); + keyTechScrollBarTitle1.setText(lang.getString("TechTitle1")); + keyTechScrollBarTitle1.setFont(CoreData::getInstance(). + getMenuFontBig()); + keyTechScrollBarTitle1.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + keyTechScrollBarTitle2.setText(lang.getString("TechTitle2")); + keyTechScrollBarTitle2.setFont(CoreData::getInstance(). + getMenuFontNormal()); + keyTechScrollBarTitle2.setFont3D(CoreData::getInstance(). + getMenuFontNormal3D()); + + keyMapScrollBarTitle1.setText(lang.getString("MapTitle1")); + keyMapScrollBarTitle1.setFont(CoreData::getInstance(). + getMenuFontBig()); + keyMapScrollBarTitle1.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + keyMapScrollBarTitle2.setText(lang.getString("MapTitle2")); + keyMapScrollBarTitle2.setFont(CoreData::getInstance(). + getMenuFontNormal()); + keyMapScrollBarTitle2.setFont3D(CoreData::getInstance(). + getMenuFontNormal3D()); + + keyTilesetScrollBarTitle1.setText(lang.getString("TilesetTitle1")); + keyTilesetScrollBarTitle1.setFont(CoreData::getInstance(). + getMenuFontBig()); + keyTilesetScrollBarTitle1.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + + pleaseWaitLabel.setText(""); + pleaseWaitLabel.setFont(CoreData::getInstance().getMenuFontBig()); + pleaseWaitLabel.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + + keyScenarioScrollBarTitle1.setText(lang.getString("ScenarioTitle1")); + keyScenarioScrollBarTitle1.setFont(CoreData::getInstance(). + getMenuFontBig()); + keyScenarioScrollBarTitle1.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + + mainMessageBox.init(lang.getString("Yes"), lang.getString("No"), + 450); + + modDescrLabel.setText("description is empty"); + + buttonReturn.setText(lang.getString("Return")); + + buttonInstalled.setText(lang.getString("ModInstalled")); + + buttonAvailable.setText(lang.getString("ModAvailable")); + + buttonOnlyLocal.setText(lang.getString("ModOnlyLocal")); + + buttonConflict.setText(lang.getString("ModHasConflict")); + + buttonInstallTech.setText(lang.getString("Install")); + buttonRemoveTech.setText(lang.getString("Remove")); + + buttonInstallTileset.setText(lang.getString("Install")); + buttonRemoveTileset.setText(lang.getString("Remove")); + + buttonInstallMap.setText(lang.getString("Install")); + buttonRemoveMap.setText(lang.getString("Remove")); + + buttonInstallScenario.setText(lang.getString("Install")); + buttonRemoveScenario.setText(lang.getString("Remove")); + + GraphicComponent:: + reloadFontsForRegisterGraphicComponents(containerName); + } + + void MenuStateMods::simpleTask(BaseThread * callingThread, + void *userdata) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutexThreadOwner(callingThread-> + getMutexThreadOwnerValid(), + mutexOwnerId); + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + callingThread->getMutexThreadOwnerValid()->setOwnerId(mutexOwnerId); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + Lang & lang = Lang::getInstance(); + Config & config = Config::getInstance(); + string fileArchiveExtractCommand = + config.getString("FileArchiveExtractCommand", ""); + int expectedResult = + config.getInt("FileArchiveExtractCommandSuccessResult", "0"); + bool findArchive = + executeShellCommand(fileArchiveExtractCommand, expectedResult); + if (findArchive == false) { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + showMessageBox(lang.getString("ModRequires7z"), + lang.getString("Notice"), true); + } + + std::string techsMetaData = ""; + std::string tilesetsMetaData = ""; + std::string mapsMetaData = ""; + std::string scenariosMetaData = ""; + + modMenuState = mmst_Loading; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (config.getString("Masterserver", "") != "") { + string baseURL = config.getString("Masterserver"); + if (baseURL != "") { + endPathWithSlash(baseURL, false); + } + + string phpVersionParam = + config.getString("phpVersionParam", "?version=0.1"); + string playerUUID = + "&uuid=" + + SystemFlags::escapeURL(Config::getInstance(). + getString("PlayerId", "")); + string gameVersion = + "&glestVersion=" + SystemFlags::escapeURL(glestVersionString); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line %d] About to call first http url, base [%s]..\n", + __FILE__, __FUNCTION__, __LINE__, baseURL.c_str()); + + CURL *handle = SystemFlags::initHTTP(); + CURLcode curlResult = CURLE_OK; + techsMetaData = + SystemFlags::getHTTP(baseURL + "showTechsForGlest.php" + + phpVersionParam + gameVersion + playerUUID, + handle, -1, &curlResult); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("techsMetaData [%s] curlResult = %d\n", + techsMetaData.c_str(), curlResult); + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + if (curlResult != CURLE_OK) { + string curlError = curl_easy_strerror(curlResult); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModErrorGettingServerData").c_str(), + curlError.c_str()); + console.addLine(string("#1 ") + szBuf, true); + } + + if (curlResult == CURLE_OK || + (curlResult != CURLE_COULDNT_RESOLVE_HOST && + curlResult != CURLE_COULDNT_CONNECT)) { + + tilesetsMetaData = + SystemFlags::getHTTP(baseURL + "showTilesetsForGlest.php" + + phpVersionParam + gameVersion, handle, -1, + &curlResult); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("tilesetsMetaData [%s]\n", tilesetsMetaData.c_str()); + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + if (curlResult != CURLE_OK) { + string curlError = curl_easy_strerror(curlResult); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModErrorGettingServerData").c_str(), + curlError.c_str()); + console.addLine(string("#2 ") + szBuf, true); + } + + mapsMetaData = + SystemFlags::getHTTP(baseURL + "showMapsForGlest.php" + + phpVersionParam + gameVersion, handle, -1, + &curlResult); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("mapsMetaData [%s]\n", mapsMetaData.c_str()); + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + if (curlResult != CURLE_OK) { + string curlError = curl_easy_strerror(curlResult); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModErrorGettingServerData").c_str(), + curlError.c_str()); + console.addLine(string("#3 ") + szBuf, true); + } + + scenariosMetaData = + SystemFlags::getHTTP(baseURL + "showScenariosForGlest.php" + + phpVersionParam + gameVersion, handle, -1, + &curlResult); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("scenariosMetaData [%s]\n", scenariosMetaData.c_str()); + + if (curlResult != CURLE_OK) { + string curlError = curl_easy_strerror(curlResult); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModErrorGettingServerData").c_str(), + curlError.c_str()); + console.addLine(string("#4 ") + szBuf, true); + } + } + SystemFlags::cleanupHTTP(&handle); + } else { + console.addLine(lang.getString("MasterServerMissing"), true); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + tilesetListRemote.clear(); + Tokenize(tilesetsMetaData, tilesetListRemote, "\n"); + + modMenuState = mmst_CalculatingCRC; + + getTilesetsLocalList(); + for (unsigned int i = 0; i < tilesetListRemote.size(); i++) { + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + string result = refreshTilesetModInfo(tilesetListRemote[i]); + if (result != "") { + ModInfo modinfo; + modinfo = tilesetCacheList[result]; + GraphicButton *button = new GraphicButton(); + button->init(tilesetInfoXPos, keyButtonsYBase, keyButtonsWidthTil, + keyButtonsHeight); + button->setText(modinfo.name); + button->setUseCustomTexture(true); + button->setCustomTexture(CoreData::getInstance(). + getCustomTexture()); + keyTilesetButtons.push_back(button); + } + } + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + for (unsigned int i = 0; i < tilesetFilesUserData.size(); i++) { + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + string tilesetName = tilesetFilesUserData[i]; + bool alreadyHasTileset = + (tilesetCacheList.find(tilesetName) != tilesetCacheList.end()); + if (alreadyHasTileset == false) { + GraphicButton *button = new GraphicButton(); + button->init(tilesetInfoXPos, keyButtonsYBase, keyButtonsWidthTil, + keyButtonsHeight); + button->setText(tilesetName); + button->setUseCustomTexture(true); + button->setCustomTexture(CoreData::getInstance(). + getCustomTexture()); + keyTilesetButtons.push_back(button); + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + techListRemote.clear(); + Tokenize(techsMetaData, techListRemote, "\n"); + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + getTechsLocalList(); + for (unsigned int i = 0; i < techListRemote.size(); i++) { + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + string result = refreshTechModInfo(techListRemote[i]); + if (result != "") { + ModInfo modinfo; + modinfo = techCacheList[result]; + + GraphicButton *button = new GraphicButton(); + button->init(techInfoXPos, keyButtonsYBase, keyButtonsWidthTech, + keyButtonsHeight); + button->setText(modinfo.name); + button->setUseCustomTexture(true); + button->setCustomTexture(CoreData::getInstance(). + getCustomTexture()); + + keyTechButtons.push_back(button); + GraphicLabel *label = new GraphicLabel(); + label->init(techInfoXPos + keyButtonsWidthTech + 10, + keyButtonsYBase, labelWidth, 20); + label->setText(modinfo.count); + labelsTech.push_back(label); + } + } + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + for (unsigned int i = 0; i < techTreeFilesUserData.size(); i++) { + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + string techName = techTreeFilesUserData[i]; + bool alreadyHasTech = + (techCacheList.find(techName) != techCacheList.end()); + if (alreadyHasTech == false) { + vector < string > techPaths = config.getPathListForType(ptTechs); + string & techPath = techPaths[1]; + endPathWithSlash(techPath); + vector < string > factions; + findAll(techPath + techName + "/factions/*.", factions, false, + false); + + GraphicButton *button = new GraphicButton(); + button->init(techInfoXPos, keyButtonsYBase, keyButtonsWidthTech, + keyButtonsHeight); + button->setText(techName); + button->setUseCustomTexture(true); + button->setCustomTexture(CoreData::getInstance(). + getCustomTexture()); + keyTechButtons.push_back(button); + + int techFactionCount = (int) factions.size(); + GraphicLabel *label = new GraphicLabel(); + label->init(techInfoXPos + keyButtonsWidthTech + 10, + keyButtonsYBase, labelWidth, 20); + label->setText(intToStr(techFactionCount)); + labelsTech.push_back(label); + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + mapListRemote.clear(); + Tokenize(mapsMetaData, mapListRemote, "\n"); + + getMapsLocalList(); + for (unsigned int i = 0; i < mapListRemote.size(); i++) { + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + string result = refreshMapModInfo(mapListRemote[i]); + if (result != "") { + ModInfo modinfo; + modinfo = mapCacheList[result]; + + GraphicButton *button = new GraphicButton(); + button->init(mapInfoXPos, keyButtonsYBase, keyButtonsWidthMap, + keyButtonsHeight); + button->setText(modinfo.name); + button->setUseCustomTexture(true); + button->setCustomTexture(CoreData::getInstance(). + getCustomTexture()); + keyMapButtons.push_back(button); + + GraphicLabel *label = new GraphicLabel(); + label->init(mapInfoXPos + keyButtonsWidthMap + 10, keyButtonsYBase, + labelWidth, 20); + label->setText(modinfo.count); + labelsMap.push_back(label); + } + } + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + for (unsigned int i = 0; i < mapFilesUserData.size(); i++) { + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + string mapName = mapFilesUserData[i]; + bool alreadyHasMap = + (mapCacheList.find(mapName) != mapCacheList.end()); + if (alreadyHasMap == false) { + vector < string > mapPaths = config.getPathListForType(ptMaps); + string & mapPath = mapPaths[1]; + endPathWithSlash(mapPath); + mapPath += mapName; + MapInfo mapInfo = loadMapInfo(mapPath); + + GraphicButton *button = new GraphicButton(); + button->init(mapInfoXPos, keyButtonsYBase, keyButtonsWidthMap, + keyButtonsHeight); + button->setText(mapName); + button->setUseCustomTexture(true); + button->setCustomTexture(CoreData::getInstance(). + getCustomTexture()); + keyMapButtons.push_back(button); + + int mapPlayerCount = mapInfo.players; + GraphicLabel *label = new GraphicLabel(); + label->init(mapInfoXPos + keyButtonsWidthMap + 10, keyButtonsYBase, + labelWidth, 20); + label->setText(intToStr(mapPlayerCount)); + labelsMap.push_back(label); + } + } + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + + scenarioListRemote.clear(); + Tokenize(scenariosMetaData, scenarioListRemote, "\n"); + + getScenariosLocalList(); + for (unsigned int i = 0; i < scenarioListRemote.size(); i++) { + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + string result = refreshScenarioModInfo(scenarioListRemote[i]); + if (result != "") { + ModInfo modinfo; + modinfo = scenarioCacheList[result]; + GraphicButton *button = new GraphicButton(); + button->init(scenarioInfoXPos, keyButtonsYBase, + keyButtonsWidthScen, keyButtonsHeight); + button->setText(modinfo.name); + button->setUseCustomTexture(true); + button->setCustomTexture(CoreData::getInstance(). + getCustomTexture()); + keyScenarioButtons.push_back(button); + } + } + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + for (unsigned int i = 0; i < scenarioFilesUserData.size(); i++) { + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + string scenarioName = scenarioFilesUserData[i]; + bool alreadyHasScenario = + (scenarioCacheList.find(scenarioName) != scenarioCacheList.end()); + if (alreadyHasScenario == false) { + vector < string > scenarioPaths = + config.getPathListForType(ptScenarios); + string & scenarioPath = scenarioPaths[1]; + endPathWithSlash(scenarioPath); + scenarioPath += scenarioName; + + GraphicButton *button = new GraphicButton(); + button->init(scenarioInfoXPos, keyButtonsYBase, + keyButtonsWidthScen, keyButtonsHeight); + button->setText(scenarioName); + button->setUseCustomTexture(true); + button->setCustomTexture(CoreData::getInstance(). + getCustomTexture()); + keyScenarioButtons.push_back(button); + } + } + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + keyTilesetScrollBar.init(tilesetInfoXPos + keyButtonsWidthTil, + scrollListsYPos - listBoxLength + + keyButtonsLineHeight, false, 200, 20); + keyTilesetScrollBar.setLength(listBoxLength); + keyTilesetScrollBar.setElementCount((int) keyTilesetButtons.size()); + keyTilesetScrollBar.setVisibleSize(keyButtonsToRender); + keyTilesetScrollBar.setVisibleStart(0); + + keyTechScrollBar.init(techInfoXPos + keyButtonsWidthTech + labelWidth + + 20, + scrollListsYPos - listBoxLength + + keyButtonsLineHeight, false, 200, 20); + keyTechScrollBar.setLength(listBoxLength); + keyTechScrollBar.setElementCount((int) keyTechButtons.size()); + keyTechScrollBar.setVisibleSize(keyButtonsToRender); + keyTechScrollBar.setVisibleStart(0); + + keyMapScrollBar.init(mapInfoXPos + keyButtonsWidthMap + labelWidth + + 20, + scrollListsYPos - listBoxLength + + keyButtonsLineHeight, false, 200, 20); + keyMapScrollBar.setLength(listBoxLength); + keyMapScrollBar.setElementCount((int) keyMapButtons.size()); + keyMapScrollBar.setVisibleSize(keyButtonsToRender); + keyMapScrollBar.setVisibleStart(0); + + keyScenarioScrollBar.init(scenarioInfoXPos + keyButtonsWidthScen, + scrollListsYPos - listBoxLength + + keyButtonsLineHeight, false, 200, 20); + keyScenarioScrollBar.setLength(listBoxLength); + keyScenarioScrollBar.setElementCount((int) keyScenarioButtons.size()); + keyScenarioScrollBar.setVisibleSize(keyButtonsToRender); + keyScenarioScrollBar.setVisibleStart(0); + + modMenuState = mmst_None; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (modHttpServerThread != NULL) { + modHttpServerThread->signalQuit(); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + MapInfo MenuStateMods::loadMapInfo(string file) { + try { + Lang & lang = Lang::getInstance(); + // Not painting properly so this is on hold + MapPreview::loadMapInfo(file, &mapInfo, + lang.getString("MaxPlayers"), + lang.getString("Size"), true); + } catch (exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s] loading map [%s]\n", + __FILE__, __FUNCTION__, __LINE__, e.what(), + file.c_str()); + throw megaglest_runtime_error("Error loading map file: [" + file + + "] msg: " + e.what()); + } + + return mapInfo; + } + + void MenuStateMods::getTechsLocalList() { + Config & config = Config::getInstance(); + vector < string > results; + findDirs(config.getPathListForType(ptTechs), results); + techTreeFiles = results; + + techTreeFilesUserData.clear(); + if (config.getPathListForType(ptTechs).size() > 1) { + string path = config.getPathListForType(ptTechs)[1]; + endPathWithSlash(path); + findDirs(path, techTreeFilesUserData, false, false); + } + } + + string MenuStateMods::refreshTechModInfo(string techInfo) { + std::vector < std::string > techInfoList; + Tokenize(techInfo, techInfoList, "|"); + if (techInfoList.size() >= 6) { + Config & config = Config::getInstance(); + ModInfo modinfo; + modinfo.name = techInfoList[0]; + modinfo.count = techInfoList[1]; + modinfo.crc = techInfoList[2]; + modinfo.description = techInfoList[3]; + modinfo.url = techInfoList[4]; + modinfo.imageUrl = techInfoList[5]; + modinfo.type = mt_Techtree; + + string itemPath = + config.getPathListForType(ptTechs, + "")[1] + "/" + modinfo.name + + string("/*"); + if (itemPath.empty() == false) { + bool forceRefresh = + (mapCRCUpdateList.find(itemPath) == mapCRCUpdateList.end()); + uint32 crc = + getFolderTreeContentsCheckSumRecursively(itemPath, ".xml", NULL, + forceRefresh); + if (crc == 0) { + itemPath = + config.getPathListForType(ptTechs, + "")[0] + "/" + modinfo.name + + string("/*"); + if (itemPath.empty() == false) { + forceRefresh = + (mapCRCUpdateList.find(itemPath) == mapCRCUpdateList.end()); + crc = + getFolderTreeContentsCheckSumRecursively(itemPath, ".xml", + NULL, forceRefresh); + } + } + modinfo.localCRC = uIntToStr(crc); + //printf("itemPath='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); + } else { + modinfo.localCRC = ""; + } + techCacheList[modinfo.name] = modinfo; + return modinfo.name; + } + return ""; + } + + void MenuStateMods::refreshTechs() { + getTechsLocalList(); + for (int i = 0; i < (int) techListRemote.size(); i++) { + refreshTechModInfo(techListRemote[i]); + } + } + + void MenuStateMods::getTilesetsLocalList() { + Config & config = Config::getInstance(); + vector < string > results; + findDirs(config.getPathListForType(ptTilesets), results); + tilesetFiles = results; + + tilesetFilesUserData.clear(); + if (config.getPathListForType(ptTilesets).size() > 1) { + string path = config.getPathListForType(ptTilesets)[1]; + endPathWithSlash(path); + findDirs(path, tilesetFilesUserData, false, false); + } + } + + string MenuStateMods::refreshTilesetModInfo(string tilesetInfo) { + std::vector < std::string > tilesetInfoList; + Tokenize(tilesetInfo, tilesetInfoList, "|"); + if (tilesetInfoList.size() >= 5) { + Config & config = Config::getInstance(); + ModInfo modinfo; + modinfo.name = tilesetInfoList[0]; + modinfo.crc = tilesetInfoList[1]; + modinfo.description = tilesetInfoList[2]; + modinfo.url = tilesetInfoList[3]; + modinfo.imageUrl = tilesetInfoList[4]; + modinfo.type = mt_Tileset; + + string itemPath = + config.getPathListForType(ptTilesets, + "")[1] + "/" + modinfo.name + + string("/*"); + if (itemPath.empty() == false) { + bool forceRefresh = + (mapCRCUpdateList.find(itemPath) == mapCRCUpdateList.end()); + uint32 crc = + getFolderTreeContentsCheckSumRecursively(itemPath, ".xml", NULL, + forceRefresh); + if (crc == 0) { + itemPath = + config.getPathListForType(ptTilesets, + "")[0] + "/" + modinfo.name + + string("/*"); + if (itemPath.empty() == false) { + forceRefresh = + (mapCRCUpdateList.find(itemPath) == mapCRCUpdateList.end()); + crc = + getFolderTreeContentsCheckSumRecursively(itemPath, ".xml", + NULL, forceRefresh); + } + } + modinfo.localCRC = uIntToStr(crc); + //printf("itemPath='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); + + //printf("#1 refreshTilesetModInfo name [%s] modInfo.crc [%s] modInfo.localCRC [%s]\n",modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str()); + } else { + modinfo.localCRC = ""; + + //printf("#2 refreshTilesetModInfo name [%s] modInfo.crc [%s] modInfo.localCRC [%s]\n",modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str()); + } + + tilesetCacheList[modinfo.name] = modinfo; + return modinfo.name; + } + return ""; + } + + void MenuStateMods::refreshTilesets() { + getTilesetsLocalList(); + for (int i = 0; i < (int) tilesetListRemote.size(); i++) { + refreshTilesetModInfo(tilesetListRemote[i]); + } + } + + void MenuStateMods::getMapsLocalList() { + + /* + Config &config = Config::getInstance(); + vector results; + set allMaps; + findAll(config.getPathListForType(ptMaps), "*.gbm", results, false, false); + copy(results.begin(), results.end(), std::inserter(allMaps, allMaps.begin())); + results.clear(); + findAll(config.getPathListForType(ptMaps), "*.mgm", results, false, false); + copy(results.begin(), results.end(), std::inserter(allMaps, allMaps.begin())); + results.clear(); + + copy(allMaps.begin(), allMaps.end(), std::back_inserter(results)); + mapFiles = results; + + mapFilesUserData.clear(); + if(config.getPathListForType(ptMaps).size() > 1) { + string path = config.getPathListForType(ptMaps)[1]; + endPathWithSlash(path); + + vector results2; + set allMaps2; + findAll(path + "*.gbm", results2, false, false); + copy(results2.begin(), results2.end(), std::inserter(allMaps2, allMaps2.begin())); + + results2.clear(); + findAll(path + "*.mgm", results2, false, false); + copy(results2.begin(), results2.end(), std::inserter(allMaps2, allMaps2.begin())); + + results2.clear(); + copy(allMaps2.begin(), allMaps2.end(), std::back_inserter(results2)); + mapFilesUserData = results2; + //printf("\n\nMap path [%s] mapFilesUserData.size() = %d\n\n\n",path.c_str(),mapFilesUserData.size()); + } + */ + + Config & config = Config::getInstance(); + string scenarioDir = ""; + vector < string > pathList = + config.getPathListForType(ptMaps, scenarioDir); + vector < string > invalidMapList; + vector < string > allMaps = + MapPreview::findAllValidMaps(pathList, scenarioDir, false, false, + &invalidMapList); + if (allMaps.empty()) { + throw megaglest_runtime_error("No maps were found!"); + } + vector < string > results; + copy(allMaps.begin(), allMaps.end(), std::back_inserter(results)); + mapFiles = results; + + mapFilesUserData = + MapPreview::findAllValidMaps(pathList, scenarioDir, true, false, + &invalidMapList); + } + + string MenuStateMods::refreshMapModInfo(string mapInfo) { + std::vector < std::string > mapInfoList; + Tokenize(mapInfo, mapInfoList, "|"); + if (mapInfoList.size() >= 6) { + //Config &config = Config::getInstance(); + ModInfo modinfo; + modinfo.name = mapInfoList[0]; + modinfo.count = mapInfoList[1]; + modinfo.crc = mapInfoList[2]; + modinfo.description = mapInfoList[3]; + modinfo.url = mapInfoList[4]; + modinfo.imageUrl = mapInfoList[5]; + modinfo.type = mt_Map; + modinfo.localCRC = getMapCRC(modinfo.name); + mapCacheList[modinfo.name] = modinfo; + return modinfo.name; + } + return ""; + } + + string MenuStateMods::getMapCRC(string mapName) { + Config & config = Config::getInstance(); + vector < string > mappaths = config.getPathListForType(ptMaps, ""); + string result = ""; + if (mappaths.empty() == false) { + Checksum checksum; + string itemPath = mappaths[1] + "/" + mapName; + if (fileExists(itemPath)) { + checksum.addFile(itemPath); + uint32 crc = checksum.getSum(); + result = uIntToStr(crc); + //printf("itemPath='%s' modinfo.name='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); + } else { + itemPath = mappaths[0] + "/" + mapName; + if (fileExists(itemPath)) { + checksum.addFile(itemPath); + uint32 crc = checksum.getSum(); + result = uIntToStr(crc); + //printf("itemPath='%s' modinfo.name='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); + } else { + result = ""; + } + } + } else { + result = ""; + } + return result; + } + + void MenuStateMods::refreshMaps() { + getMapsLocalList(); + for (int i = 0; i < (int) mapListRemote.size(); i++) { + refreshMapModInfo(mapListRemote[i]); + } + } + + void MenuStateMods::getScenariosLocalList() { + Config & config = Config::getInstance(); + vector < string > results; + findDirs(config.getPathListForType(ptScenarios), results); + scenarioFiles = results; + + scenarioFilesUserData.clear(); + if (config.getPathListForType(ptScenarios).size() > 1) { + string path = config.getPathListForType(ptScenarios)[1]; + endPathWithSlash(path); + findDirs(path, scenarioFilesUserData, false, false); + } + } + + string MenuStateMods::refreshScenarioModInfo(string scenarioInfo) { + std::vector < std::string > scenarioInfoList; + Tokenize(scenarioInfo, scenarioInfoList, "|"); + if (scenarioInfoList.size() >= 5) { + Config & config = Config::getInstance(); + ModInfo modinfo; + modinfo.name = scenarioInfoList[0]; + modinfo.crc = scenarioInfoList[1]; + modinfo.description = scenarioInfoList[2]; + modinfo.url = scenarioInfoList[3]; + modinfo.imageUrl = scenarioInfoList[4]; + modinfo.type = mt_Scenario; + + string itemPath = + config.getPathListForType(ptScenarios, + "")[1] + "/" + modinfo.name + + string("/*"); + if (itemPath.empty() == false) { + bool forceRefresh = + (mapCRCUpdateList.find(itemPath) == mapCRCUpdateList.end()); + uint32 crc = + getFolderTreeContentsCheckSumRecursively(itemPath, ".xml", NULL, + forceRefresh); + if (crc == 0) { + itemPath = + config.getPathListForType(ptScenarios, + "")[0] + "/" + modinfo.name + + string("/*"); + if (itemPath.empty() == false) { + forceRefresh = + (mapCRCUpdateList.find(itemPath) == mapCRCUpdateList.end()); + crc = + getFolderTreeContentsCheckSumRecursively(itemPath, ".xml", + NULL, forceRefresh); + } + } + modinfo.localCRC = uIntToStr(crc); + //printf(" itemPath='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); + } else { + modinfo.localCRC = ""; + } + scenarioCacheList[modinfo.name] = modinfo; + return modinfo.name; + } + return ""; + } + + void MenuStateMods::refreshScenarios() { + getScenariosLocalList(); + for (int i = 0; i < (int) scenarioListRemote.size(); i++) { + refreshScenarioModInfo(scenarioListRemote[i]); + } + } + + + void MenuStateMods::cleanUp() { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + if (modHttpServerThread != NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + modHttpServerThread->signalQuit(); + //modHttpServerThread->setThreadOwnerValid(false); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + if (modHttpServerThread->canShutdown(true) == true + && modHttpServerThread->shutdownAndWait() == true) { + delete modHttpServerThread; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + modHttpServerThread = NULL; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (ftpClientThread != NULL) { + ftpClientThread->setCallBackObject(NULL); + ftpClientThread->signalQuit(); + sleep(0); + if (ftpClientThread->canShutdown(true) == true && + ftpClientThread->shutdownAndWait() == true) { + delete ftpClientThread; + } else { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s %d] Error cannot shutdown ftpClientThread\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("%s", szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + //publishToMasterserverThread->cleanup(); + } + ftpClientThread = NULL; + + // ftpClientThread->signalQuit(); + // ftpClientThread->setCallBackObject(NULL); + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + // if( ftpClientThread->shutdownAndWait() == true) { + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + // delete ftpClientThread; + // } + // ftpClientThread = NULL; + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + clearUserButtons(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + cleanupPreviewTexture(); + cleanupMapPreviewTexture(); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + MenuStateMods::~MenuStateMods() { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + cleanUp(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void MenuStateMods::clearUserButtons() { + // Techs + while (!keyTechButtons.empty()) { + delete keyTechButtons.back(); + keyTechButtons.pop_back(); + } + keyTechScrollBar.setElementCount(0); + + while (!labelsTech.empty()) { + delete labelsTech.back(); + labelsTech.pop_back(); + } + + // Tilesets + while (!keyTilesetButtons.empty()) { + delete keyTilesetButtons.back(); + keyTilesetButtons.pop_back(); + } + keyTilesetScrollBar.setElementCount(0); + + // Maps + while (!keyMapButtons.empty()) { + delete keyMapButtons.back(); + keyMapButtons.pop_back(); + } + while (!labelsMap.empty()) { + delete labelsMap.back(); + labelsMap.pop_back(); + } + keyMapScrollBar.setElementCount(0); + + // Scenarios + while (!keyScenarioButtons.empty()) { + delete keyScenarioButtons.back(); + keyScenarioButtons.pop_back(); + } + keyScenarioScrollBar.setElementCount(0); + } + + void MenuStateMods::mouseClick(int x, int y, MouseButton mouseButton) { + + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + Lang & lang = Lang::getInstance(); + + if (buttonReturn.mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + soundRenderer.playFx(coreData.getClickSoundA()); + + if (fileFTPProgressList.empty() == false) { + mainMessageBoxState = ftpmsg_Quit; + mainMessageBox.init(lang.getString("Yes"), lang.getString("No"), + 450); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModDownloadInProgressCancelQuestion"). + c_str(), fileFTPProgressList.size()); + showMessageBox(szBuf, lang.getString("Question"), true); + } else { + cleanUp(); + mainMenu->setState(new MenuStateRoot(program, mainMenu)); + return; + } + } else if (mainMessageBox.getEnabled()) { + int button = 0; + if (mainMessageBox.mouseClick(x, y, button)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMessageBox.setEnabled(false); + mainMessageBox.init(lang.getString("Yes"), lang.getString("No"), + 450); + if (button == 0) { + if (mainMessageBoxState == ftpmsg_Quit) { + mainMessageBoxState = ftpmsg_None; + mainMenu->setState(new MenuStateRoot(program, mainMenu)); + return; + } else if (mainMessageBoxState == ftpmsg_GetMap || + mainMessageBoxState == ftpmsg_ReplaceMap) { + bool getItemAfterRemoval = + (mainMessageBoxState == ftpmsg_ReplaceMap); + mainMessageBoxState = ftpmsg_None; + + Config & config = Config::getInstance(); + vector < string > mapPaths = config.getPathListForType(ptMaps); + if (mapPaths.size() > 1) { + string removeMap = mapPaths[1]; + endPathWithSlash(removeMap); + removeMap += selectedMapName; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Removing Map [%s]\n", removeMap.c_str()); + removeFile(removeMap); + + bool remoteHasMap = + (mapCacheList.find(selectedMapName) != + mapCacheList.end()); + if (remoteHasMap == false) { + for (unsigned int i = 0; i < keyMapButtons.size(); ++i) { + GraphicButton *button = keyMapButtons[i]; + if (button != NULL + && button->getText() == selectedMapName) { + delete button; + keyMapButtons.erase(keyMapButtons.begin() + i); + labelsMap.erase(labelsMap.begin() + i); + keyMapScrollBar.setElementCount((int) keyMapButtons. + size()); + break; + } + } + } + + if (getItemAfterRemoval == false) { + selectedMapName = ""; + } + refreshMaps(); + Checksum::clearFileCache(); + + if (getItemAfterRemoval == true) { + string mapName = selectedMapName; + string mapURL = mapCacheList[mapName].url; + if (ftpClientThread != NULL) + ftpClientThread->addMapToRequests(mapName, mapURL); + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), + mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()-> + setOwnerId(mutexOwnerId); + fileFTPProgressList[mapName] = pair < int, string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + buttonInstallMap.setEnabled(false); + } + } + } else if (mainMessageBoxState == ftpmsg_GetTileset || + mainMessageBoxState == ftpmsg_ReplaceTileset) { + bool getItemAfterRemoval = + (mainMessageBoxState == ftpmsg_ReplaceTileset); + mainMessageBoxState = ftpmsg_None; + + Config & config = Config::getInstance(); + vector < string > tilesetPaths = + config.getPathListForType(ptTilesets); + if (tilesetPaths.size() > 1) { + string removeTileset = tilesetPaths[1]; + endPathWithSlash(removeTileset); + removeTileset += selectedTilesetName; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Removing Tileset [%s]\n", removeTileset.c_str()); + removeFolder(removeTileset); + + bool remoteHasTileset = + (tilesetCacheList.find(selectedTilesetName) != + tilesetCacheList.end()); + if (remoteHasTileset == false) { + //printf("\n\n\n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ remote DOES NOT have removed tileset [%s]\n\n\n",selectedTilesetName.c_str()); + + for (unsigned int i = 0; i < keyTilesetButtons.size(); ++i) { + GraphicButton *button = keyTilesetButtons[i]; + if (button != NULL + && button->getText() == selectedTilesetName) { + delete button; + keyTilesetButtons.erase(keyTilesetButtons.begin() + + i); + keyTilesetScrollBar. + setElementCount((int) keyTilesetButtons.size()); + break; + } + } + } + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), + mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()-> + setOwnerId(mutexOwnerId); + Checksum::clearFileCache(); + vector < string > paths = + Config::getInstance().getPathListForType(ptTilesets); + string pathSearchString = + string("/") + selectedTilesetName + string("/*"); + const string filterFileExt = ".xml"; + clearFolderTreeContentsCheckSum(paths, pathSearchString, + filterFileExt); + clearFolderTreeContentsCheckSumList(paths, pathSearchString, + filterFileExt); + safeMutexFTPProgress.ReleaseLock(); + + if (getItemAfterRemoval == false) { + selectedTilesetName = ""; + } + refreshTilesets(); + } + + if (getItemAfterRemoval == true) { + string tilesetName = selectedTilesetName; + string tilesetURL = tilesetCacheList[tilesetName].url; + if (ftpClientThread != NULL) + ftpClientThread->addTilesetToRequests(tilesetName, + tilesetURL); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), + mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()-> + setOwnerId(mutexOwnerId); + fileFTPProgressList[tilesetName] = + pair < int, string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + buttonInstallTileset.setEnabled(false); + } + } else if (mainMessageBoxState == ftpmsg_GetTechtree || + mainMessageBoxState == ftpmsg_ReplaceTechtree) { + bool getItemAfterRemoval = + (mainMessageBoxState == ftpmsg_ReplaceTechtree); + mainMessageBoxState = ftpmsg_None; + + Config & config = Config::getInstance(); + vector < string > techPaths = + config.getPathListForType(ptTechs); + if (techPaths.size() > 1) { + string removeTech = techPaths[1]; + endPathWithSlash(removeTech); + removeTech += selectedTechName; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Removing Techtree [%s]\n", removeTech.c_str()); + removeFolder(removeTech); + + bool remoteHasTech = + (techCacheList.find(selectedTechName) != + techCacheList.end()); + if (remoteHasTech == false) { + for (unsigned int i = 0; i < keyTechButtons.size(); ++i) { + GraphicButton *button = keyTechButtons[i]; + if (button != NULL + && button->getText() == selectedTechName) { + delete button; + keyTechButtons.erase(keyTechButtons.begin() + i); + labelsTech.erase(labelsTech.begin() + i); + keyTechScrollBar.setElementCount((int) keyTechButtons. + size()); + break; + } + } + } + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), + mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()-> + setOwnerId(mutexOwnerId); + // Clear the CRC file Cache + Checksum::clearFileCache(); + vector < string > paths = + Config::getInstance().getPathListForType(ptTechs); + string pathSearchString = + string("/") + selectedTechName + string("/*"); + const string filterFileExt = ".xml"; + clearFolderTreeContentsCheckSum(paths, pathSearchString, + filterFileExt); + clearFolderTreeContentsCheckSumList(paths, pathSearchString, + filterFileExt); + safeMutexFTPProgress.ReleaseLock(); + + if (getItemAfterRemoval == false) { + selectedTechName = ""; + } + refreshTechs(); + } + + if (getItemAfterRemoval == true) { + string techName = selectedTechName; + string techURL = techCacheList[techName].url; + if (ftpClientThread != NULL) + ftpClientThread->addTechtreeToRequests(techName, techURL); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), + mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()-> + setOwnerId(mutexOwnerId); + fileFTPProgressList[techName] = pair < int, string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + buttonInstallTech.setEnabled(false); + } + } else if (mainMessageBoxState == ftpmsg_GetScenario || + mainMessageBoxState == ftpmsg_ReplaceScenario) { + bool getItemAfterRemoval = + (mainMessageBoxState == ftpmsg_ReplaceScenario); + mainMessageBoxState = ftpmsg_None; + + Config & config = Config::getInstance(); + vector < string > scenarioPaths = + config.getPathListForType(ptScenarios); + if (scenarioPaths.size() > 1) { + string removeScenario = scenarioPaths[1]; + endPathWithSlash(removeScenario); + removeScenario += selectedScenarioName; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Removing Scenario [%s]\n", + removeScenario.c_str()); + removeFolder(removeScenario); + + bool remoteHasScenario = + (scenarioCacheList.find(selectedScenarioName) != + scenarioCacheList.end()); + if (remoteHasScenario == false) { + for (unsigned int i = 0; i < keyScenarioButtons.size(); + ++i) { + GraphicButton *button = keyScenarioButtons[i]; + if (button != NULL + && button->getText() == selectedScenarioName) { + delete button; + keyScenarioButtons.erase(keyScenarioButtons.begin() + + i); + keyScenarioScrollBar. + setElementCount((int) keyScenarioButtons.size()); + break; + } + } + } + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), + mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()-> + setOwnerId(mutexOwnerId); + Checksum::clearFileCache(); + vector < string > paths = + Config::getInstance().getPathListForType(ptScenarios); + string pathSearchString = + string("/") + selectedScenarioName + string("/*"); + const string filterFileExt = ".xml"; + clearFolderTreeContentsCheckSum(paths, pathSearchString, + filterFileExt); + clearFolderTreeContentsCheckSumList(paths, pathSearchString, + filterFileExt); + safeMutexFTPProgress.ReleaseLock(); + + if (getItemAfterRemoval == false) { + selectedScenarioName = ""; + } + refreshScenarios(); + } + + if (getItemAfterRemoval == true) { + string scenarioName = selectedScenarioName; + string scenarioURL = scenarioCacheList[scenarioName].url; + if (ftpClientThread != NULL) + ftpClientThread->addScenarioToRequests(scenarioName, + scenarioURL); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), + mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()-> + setOwnerId(mutexOwnerId); + fileFTPProgressList[scenarioName] = + pair < int, string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + buttonInstallScenario.setEnabled(false); + } + } + } + } + } else if (keyTechScrollBar.mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + soundRenderer.playFx(coreData.getClickSoundA()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } else if (keyTilesetScrollBar.mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + soundRenderer.playFx(coreData.getClickSoundA()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } else if (keyMapScrollBar.mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + soundRenderer.playFx(coreData.getClickSoundA()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } else if (keyScenarioScrollBar.mouseClick(x, y)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + soundRenderer.playFx(coreData.getClickSoundA()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } else if (buttonInstallTech.mouseClick(x, y) + && buttonInstallTech.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundB()); + if (selectedTechName != "") { + bool alreadyHasTech = + (std:: + find(techTreeFiles.begin(), techTreeFiles.end(), + selectedTechName) != techTreeFiles.end()); + if (alreadyHasTech == true) { + bool remoteHasTech = + (techCacheList.find(selectedTechName) != techCacheList.end()); + if (remoteHasTech == true) { + ModInfo & modInfo = techCacheList[selectedTechName]; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d] remote CRC [%s]\n", __FILE__, + __FUNCTION__, __LINE__, modInfo.crc.c_str()); + + Config & config = Config::getInstance(); + string itemPath = + config.getPathListForType(ptTechs, + "")[1] + "/" + selectedTechName + + string("/*"); + bool forceRefresh = + (mapCRCUpdateList.find(itemPath) == mapCRCUpdateList.end()); + if (strToUInt(modInfo.crc) != 0 + && strToUInt(modInfo.crc) != + getFolderTreeContentsCheckSumRecursively(itemPath, ".xml", + NULL, + forceRefresh)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d] local CRC [%u]\n", __FILE__, + __FUNCTION__, __LINE__, + getFolderTreeContentsCheckSumRecursively(itemPath, + ".xml", + NULL)); + + mainMessageBoxState = ftpmsg_ReplaceTechtree; + mainMessageBox.init(lang.getString("Yes"), + lang.getString("No"), 450); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModLocalRemoteMismatch").c_str(), + selectedTechName.c_str()); + showMessageBox(szBuf, lang.getString("Notice"), true); + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModTechAlreadyInstalled").c_str(), + selectedTechName.c_str()); + showMessageBox(szBuf, lang.getString("Notice"), true); + } + mapCRCUpdateList[itemPath] = true; + } + } else { + string techName = selectedTechName; + string techURL = techCacheList[techName].url; + if (ftpClientThread != NULL) + ftpClientThread->addTechtreeToRequests(techName, techURL); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), + mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + fileFTPProgressList[techName] = pair < int, string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + buttonInstallTech.setEnabled(false); + } + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + showMessageBox(lang.getString("ModSelectTechToInstall"), + lang.getString("Notice"), true); + } + } else if (buttonRemoveTech.mouseClick(x, y) + && buttonRemoveTech.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundB()); + if (selectedTechName != "") { + bool alreadyHasTech = + (std:: + find(techTreeFiles.begin(), techTreeFiles.end(), + selectedTechName) != techTreeFiles.end()); + if (alreadyHasTech == true) { + mainMessageBoxState = ftpmsg_GetTechtree; + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModRemoveTechConfirm").c_str(), + selectedTechName.c_str()); + showMessageBox(szBuf, lang.getString("Question"), true); + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModCannotRemoveTechNotInstalled"). + c_str(), selectedTechName.c_str()); + showMessageBox(szBuf, lang.getString("Notice"), true); + } + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + + showMessageBox(lang.getString("ModSelectTechToRemove"), + lang.getString("Notice"), true); + } + } + + else if (buttonInstallTileset.mouseClick(x, y) + && buttonInstallTileset.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundB()); + if (selectedTilesetName != "") { + bool alreadyHasTileset = + (std:: + find(tilesetFiles.begin(), tilesetFiles.end(), + selectedTilesetName) != tilesetFiles.end()); + if (alreadyHasTileset == true) { + bool remoteHasTileset = + (tilesetCacheList.find(selectedTilesetName) != + tilesetCacheList.end()); + if (remoteHasTileset) { + ModInfo & modInfo = tilesetCacheList[selectedTilesetName]; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d] remote CRC [%s]\n", __FILE__, + __FUNCTION__, __LINE__, modInfo.crc.c_str()); + + Config & config = Config::getInstance(); + string itemPath = + config.getPathListForType(ptTilesets, + "")[1] + "/" + + selectedTilesetName + string("/*"); + bool forceRefresh = + (mapCRCUpdateList.find(itemPath) == mapCRCUpdateList.end()); + + if (strToUInt(modInfo.crc) != 0 && + strToUInt(modInfo.crc) != + getFolderTreeContentsCheckSumRecursively(itemPath, ".xml", + NULL, + forceRefresh)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d] local CRC [%u] [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + getFolderTreeContentsCheckSumRecursively(itemPath, + ".xml", + NULL), + itemPath.c_str()); + + mainMessageBoxState = ftpmsg_ReplaceTileset; + mainMessageBox.init(lang.getString("Yes"), + lang.getString("No"), 450); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModLocalRemoteMismatch").c_str(), + selectedTilesetName.c_str()); + showMessageBox(szBuf, lang.getString("Notice"), true); + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModTilesetAlreadyInstalled"). + c_str(), selectedTilesetName.c_str()); + showMessageBox(szBuf, lang.getString("Notice"), true); + } + } + } else { + string tilesetName = selectedTilesetName; + string tilesetURL = tilesetCacheList[tilesetName].url; + if (ftpClientThread != NULL) + ftpClientThread->addTilesetToRequests(tilesetName, tilesetURL); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), + mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + fileFTPProgressList[tilesetName] = pair < int, string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + buttonInstallTileset.setEnabled(false); + } + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + showMessageBox(lang.getString("ModSelectTilesetToInstall"), + lang.getString("Notice"), true); + } + } else if (buttonRemoveTileset.mouseClick(x, y) + && buttonRemoveTileset.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundB()); + if (selectedTilesetName != "") { + bool alreadyHasTileset = + (std:: + find(tilesetFiles.begin(), tilesetFiles.end(), + selectedTilesetName) != tilesetFiles.end()); + if (alreadyHasTileset == true) { + mainMessageBoxState = ftpmsg_GetTileset; + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModRemoveTilesetConfirm").c_str(), + selectedTilesetName.c_str()); + showMessageBox(szBuf, lang.getString("Question"), true); + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModCannotRemoveTilesetNotInstalled"). + c_str(), selectedTilesetName.c_str()); + showMessageBox(szBuf, lang.getString("Notice"), true); + } + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + showMessageBox(lang.getString("ModSelectTilesetToRemove"), + lang.getString("Notice"), true); + } + } + + else if (buttonInstallMap.mouseClick(x, y) + && buttonInstallMap.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundB()); + if (selectedMapName != "") { + bool alreadyHasMap = + (std:: + find(mapFiles.begin(), mapFiles.end(), + selectedMapName) != mapFiles.end()); + if (alreadyHasMap == true) { + bool remoteHasMap = + (mapCacheList.find(selectedMapName) != mapCacheList.end()); + if (remoteHasMap) { + ModInfo & modInfo = mapCacheList[selectedMapName]; + if (modInfo.crc != modInfo.localCRC) { + mainMessageBoxState = ftpmsg_ReplaceMap; + mainMessageBox.init(lang.getString("Yes"), + lang.getString("No"), 450); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModLocalRemoteMismatch").c_str(), + selectedMapName.c_str()); + showMessageBox(szBuf, lang.getString("Notice"), true); + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModMapAlreadyInstalled").c_str(), + selectedMapName.c_str()); + showMessageBox(szBuf, lang.getString("Notice"), true); + } + } + } else { + string mapName = selectedMapName; + string mapURL = mapCacheList[mapName].url; + if (ftpClientThread != NULL) + ftpClientThread->addMapToRequests(mapName, mapURL); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), + mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + fileFTPProgressList[mapName] = pair < int, string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + buttonInstallMap.setEnabled(false); + } + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + showMessageBox(lang.getString("ModSelectMapToInstall"), + lang.getString("Notice"), true); + } + } else if (buttonRemoveMap.mouseClick(x, y) + && buttonRemoveMap.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundB()); + if (selectedMapName != "") { + bool alreadyHasMap = + (std:: + find(mapFiles.begin(), mapFiles.end(), + selectedMapName) != mapFiles.end()); + if (alreadyHasMap == true) { + mainMessageBoxState = ftpmsg_GetMap; + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModRemoveMapConfirm").c_str(), + selectedMapName.c_str()); + showMessageBox(szBuf, lang.getString("Question"), true); + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModCannotRemoveMapNotInstalled"). + c_str(), selectedMapName.c_str()); + showMessageBox(szBuf, lang.getString("Notice"), true); + } + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + showMessageBox(lang.getString("ModSelectMapToRemove"), + lang.getString("Notice"), true); + } + } + + else if (buttonInstallScenario.mouseClick(x, y) + && buttonInstallScenario.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundB()); + if (selectedScenarioName != "") { + bool alreadyHasScenario = + (std:: + find(scenarioFiles.begin(), scenarioFiles.end(), + selectedScenarioName) != scenarioFiles.end()); + if (alreadyHasScenario == true) { + bool remoteHasScenario = + (scenarioCacheList.find(selectedScenarioName) != + scenarioCacheList.end()); + if (remoteHasScenario) { + ModInfo & modInfo = scenarioCacheList[selectedScenarioName]; + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d] remote CRC [%s]\n", __FILE__, + __FUNCTION__, __LINE__, modInfo.crc.c_str()); + + Config & config = Config::getInstance(); + string itemPath = + config.getPathListForType(ptScenarios, + "")[1] + "/" + + selectedScenarioName + string("/*"); + bool forceRefresh = + (mapCRCUpdateList.find(itemPath) == mapCRCUpdateList.end()); + + if (strToUInt(modInfo.crc) != 0 && + strToUInt(modInfo.crc) != + getFolderTreeContentsCheckSumRecursively(itemPath, "", + NULL, + forceRefresh)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d] local CRC [%u]\n", __FILE__, + __FUNCTION__, __LINE__, + getFolderTreeContentsCheckSumRecursively(itemPath, + "", + NULL)); + + mainMessageBoxState = ftpmsg_ReplaceScenario; + mainMessageBox.init(lang.getString("Yes"), + lang.getString("No"), 450); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModLocalRemoteMismatch").c_str(), + selectedScenarioName.c_str()); + showMessageBox(szBuf, lang.getString("Notice"), true); + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModScenarioAlreadyInstalled"). + c_str(), selectedScenarioName.c_str()); + showMessageBox(szBuf, lang.getString("Notice"), true); + } + } + } else { + string scenarioName = selectedScenarioName; + string scenarioURL = scenarioCacheList[scenarioName].url; + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] adding file to download [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioURL.c_str()); + if (ftpClientThread != NULL) + ftpClientThread->addScenarioToRequests(scenarioName, + scenarioURL); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), + mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + fileFTPProgressList[scenarioName] = pair < int, string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + buttonInstallScenario.setEnabled(false); + } + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + showMessageBox(lang.getString("ModSelectScenarioToInstall"), + lang.getString("Notice"), true); + } + } else if (buttonRemoveScenario.mouseClick(x, y) + && buttonRemoveScenario.getEnabled()) { + soundRenderer.playFx(coreData.getClickSoundB()); + if (selectedScenarioName != "") { + bool alreadyHasScenario = + (std:: + find(scenarioFiles.begin(), scenarioFiles.end(), + selectedScenarioName) != scenarioFiles.end()); + if (alreadyHasScenario == true) { + mainMessageBoxState = ftpmsg_GetScenario; + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModRemoveScenarioConfirm").c_str(), + selectedScenarioName.c_str()); + showMessageBox(szBuf, lang.getString("Question"), true); + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModCannotRemoveScenarioNotInstalled"). + c_str(), selectedScenarioName.c_str()); + showMessageBox(szBuf, lang.getString("Notice"), true); + } + } else { + mainMessageBoxState = ftpmsg_None; + mainMessageBox.init(lang.getString("Ok"), 450); + showMessageBox(lang.getString("ModSelectScenarioToRemove"), + lang.getString("Notice"), true); + } + } + + else { + if (keyMapScrollBar.getElementCount() != 0) { + for (int i = keyMapScrollBar.getVisibleStart(); + i <= keyMapScrollBar.getVisibleEnd(); ++i) { + if (keyMapButtons[i]->mouseClick(x, y) + && keyMapButtons[i]->getEnabled()) { + string mapName = keyMapButtons[i]->getText(); + selectedTechName = ""; + selectedTilesetName = ""; + selectedMapName = ""; + selectedScenarioName = ""; + if (mapName != "") { + selectedMapName = mapName; + bool remoteHasMap = + (mapCacheList.find(mapName) != mapCacheList.end()); + if (remoteHasMap) { + showRemoteDesription(&mapCacheList[selectedMapName]); + if (mapCacheList[selectedMapName].localCRC != "") { + loadMapPreview(mapName); + } + } else { + showLocalDescription(mapName); + loadMapPreview(mapName); + } + + } + break; + } + } + } + if (keyTechScrollBar.getElementCount() != 0) { + for (int i = keyTechScrollBar.getVisibleStart(); + i <= keyTechScrollBar.getVisibleEnd(); ++i) { + if (keyTechButtons[i]->mouseClick(x, y) + && keyTechButtons[i]->getEnabled()) { + string techName = keyTechButtons[i]->getText(); + selectedTechName = ""; + selectedTilesetName = ""; + selectedMapName = ""; + selectedScenarioName = ""; + if (techName != "") { + selectedTechName = techName; + bool remoteHasTech = + (techCacheList.find(techName) != techCacheList.end()); + if (remoteHasTech) { + showRemoteDesription(&techCacheList[techName]); + } else { + showLocalDescription(techName); + } + } + break; + } + } + } + if (keyTilesetScrollBar.getElementCount() != 0) { + for (int i = keyTilesetScrollBar.getVisibleStart(); + i <= keyTilesetScrollBar.getVisibleEnd(); ++i) { + if (keyTilesetButtons[i]->mouseClick(x, y) + && keyTilesetButtons[i]->getEnabled()) { + string tilesetName = keyTilesetButtons[i]->getText(); + selectedTechName = ""; + selectedTilesetName = ""; + selectedMapName = ""; + selectedScenarioName = ""; + if (tilesetName != "") { + selectedTilesetName = tilesetName; + bool remoteHasTileset = + (tilesetCacheList.find(tilesetName) != + tilesetCacheList.end()); + if (remoteHasTileset) { + showRemoteDesription(&tilesetCacheList[tilesetName]); + } else { + showLocalDescription(tilesetName); + } + } + break; + } + } + } + if (keyScenarioScrollBar.getElementCount() != 0) { + for (int i = keyScenarioScrollBar.getVisibleStart(); + i <= keyScenarioScrollBar.getVisibleEnd(); ++i) { + if (keyScenarioButtons[i]->mouseClick(x, y) + && keyScenarioButtons[i]->getEnabled()) { + string scenarioName = keyScenarioButtons[i]->getText(); + selectedTechName = ""; + selectedTilesetName = ""; + selectedMapName = ""; + selectedScenarioName = ""; + if (scenarioName != "") { + selectedScenarioName = scenarioName; + bool remoteHasScenario = + (scenarioCacheList.find(scenarioName) != + scenarioCacheList.end()); + if (remoteHasScenario) { + showRemoteDesription(&scenarioCacheList[scenarioName]); + } else { + showLocalDescription(scenarioName); + } + + } + break; + } + } + } + + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + string MenuStateMods::getPreviewImageFileForMod(const ModInfo * modInfo) { + string fileName = ""; + if (modInfo->imageUrl != "") { + Config & config = Config::getInstance(); + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + string tempPath = userData + "temp/"; + if (isdir(tempPath.c_str()) == false) { + createDirectoryPaths(tempPath); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("### tempPath [%s] isdir = %d\n", tempPath.c_str(), + isdir(tempPath.c_str())); + + if (isdir(tempPath.c_str()) == true) { + fileName = tempPath; + switch (modInfo->type) { + case mt_Map: + fileName += "map_"; + break; + case mt_Tileset: + fileName += "tileset_"; + break; + case mt_Techtree: + fileName += "tech_"; + break; + case mt_Scenario: + fileName += "scenario_"; + break; + } + fileName += extractFileFromDirectoryPath(modInfo->imageUrl); + } + } + return fileName; + } + + + void MenuStateMods::showLocalDescription(string name) { + Lang & lang = Lang::getInstance(); + modInfoSelected = NULL; + cleanupPreviewTexture(); + validMapPreview = false; + cleanupMapPreviewTexture(); + modDescrLabel.setText(lang.getString("ModOnlyLocal") + ":\n'" + name + + "'"); + } + + void MenuStateMods::loadMapPreview(string mapName) { + Config & config = Config::getInstance(); + cleanupMapPreviewTexture(); + vector < string > mapPaths = config.getPathListForType(ptMaps); + string & mapPath = mapPaths[1]; + endPathWithSlash(mapPath); + mapPath += mapName; + MapInfo mapInfo = loadMapInfo(mapPath); + if (enableMapPreview == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + mapPreview.loadFromFile(mapPath.c_str()); + + //printf("Loading map preview MAP\n"); + cleanupMapPreviewTexture(); + validMapPreview = true; + } + } + + + + void MenuStateMods::showRemoteDesription(ModInfo * modInfo) { + //displayModPreviewImage = false; + modInfoSelected = modInfo; + validMapPreview = false; + cleanupMapPreviewTexture(); + + string modText = modInfo->description; + replaceAll(modText, "\\n", "\n"); + modDescrLabel.setText(modText); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("### modInfo->imageUrl [%s]\n", modInfo->imageUrl.c_str()); + + if (modInfo->imageUrl != "") { + cleanupPreviewTexture(); + string tempImage = getPreviewImageFileForMod(modInfo); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("### tempImage [%s] exists [%d]\n", tempImage.c_str(), + fileExists(tempImage)); + + if (tempImage != "" && fileExists(tempImage) == false) { + if (ftpClientThread != NULL) + ftpClientThread->addFileToRequests(tempImage, modInfo->imageUrl); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + fileFTPProgressList[tempImage] = pair < int, string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + + } else { + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + if (fileFTPProgressList.find(tempImage) == + fileFTPProgressList.end()) { + //displayModPreviewImage = true; + displayModPreviewImage[tempImage] = true; + } + safeMutexFTPProgress.ReleaseLock(); + } + } + } + + void MenuStateMods::mouseUp(int x, int y, const MouseButton mouseButton) { + if (mouseButton == mbLeft) { + keyTechScrollBar.mouseUp(x, y); + keyTilesetScrollBar.mouseUp(x, y); + keyMapScrollBar.mouseUp(x, y); + keyScenarioScrollBar.mouseUp(x, y); + } + } + + void MenuStateMods::mouseMove(int x, int y, const MouseState * ms) { + buttonReturn.mouseMove(x, y); + + if (mainMessageBox.getEnabled()) { + mainMessageBox.mouseMove(x, y); + } + + buttonInstallTech.mouseMove(x, y); + buttonRemoveTech.mouseMove(x, y); + buttonInstallTileset.mouseMove(x, y); + buttonRemoveTileset.mouseMove(x, y); + buttonInstallMap.mouseMove(x, y); + buttonRemoveMap.mouseMove(x, y); + buttonInstallScenario.mouseMove(x, y); + buttonRemoveScenario.mouseMove(x, y); + + if (ms->get(mbLeft)) { + keyMapScrollBar.mouseDown(x, y); + keyTechScrollBar.mouseDown(x, y); + keyTilesetScrollBar.mouseDown(x, y); + keyScenarioScrollBar.mouseDown(x, y); + } else { + keyMapScrollBar.mouseMove(x, y); + keyTechScrollBar.mouseMove(x, y); + keyTilesetScrollBar.mouseMove(x, y); + keyScenarioScrollBar.mouseMove(x, y); + } + + if (keyMapScrollBar.getElementCount() != 0) { + for (int i = keyMapScrollBar.getVisibleStart(); + i <= keyMapScrollBar.getVisibleEnd(); ++i) { + keyMapButtons[i]->mouseMove(x, y); + } + } + if (keyTechScrollBar.getElementCount() != 0) { + for (int i = keyTechScrollBar.getVisibleStart(); + i <= keyTechScrollBar.getVisibleEnd(); ++i) { + keyTechButtons[i]->mouseMove(x, y); + } + } + if (keyTilesetScrollBar.getElementCount() != 0) { + for (int i = keyTilesetScrollBar.getVisibleStart(); + i <= keyTilesetScrollBar.getVisibleEnd(); ++i) { + keyTilesetButtons[i]->mouseMove(x, y); + } + } + if (keyScenarioScrollBar.getElementCount() != 0) { + for (int i = keyScenarioScrollBar.getVisibleStart(); + i <= keyScenarioScrollBar.getVisibleEnd(); ++i) { + keyScenarioButtons[i]->mouseMove(x, y); + } + } + } + + void MenuStateMods::cleanupPreviewTexture() { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] scenarioLogoTexture [%p]\n", __FILE__, + __FUNCTION__, __LINE__, modPreviewImage); + + if (modPreviewImage != NULL) { + Renderer::getInstance().endTexture(rsGlobal, modPreviewImage, + false); + } + modPreviewImage = NULL; + } + + void MenuStateMods::cleanupMapPreviewTexture() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + //printf("CLEANUP map preview texture\n"); + if (mapPreviewTexture != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + mapPreviewTexture->end(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + delete mapPreviewTexture; + mapPreviewTexture = NULL; + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } + + + void MenuStateMods::render() { + try { + Renderer & renderer = Renderer::getInstance(); + + renderer.renderLine(&lineHorizontal); + renderer.renderLine(&lineVertical); + renderer.renderLine(&lineReturn); + renderer.renderLine(&lineVerticalReturn); + renderer.renderButton(&buttonReturn); + + renderer.renderButton(&buttonInstallTech); + renderer.renderButton(&buttonRemoveTech); + renderer.renderButton(&buttonInstallTileset); + renderer.renderButton(&buttonRemoveTileset); + renderer.renderButton(&buttonInstallMap); + renderer.renderButton(&buttonRemoveMap); + renderer.renderButton(&buttonInstallScenario); + renderer.renderButton(&buttonRemoveScenario); + + renderer.renderButton(&buttonInstalled); + renderer.renderButton(&buttonAvailable); + renderer.renderButton(&buttonConflict); + renderer.renderButton(&buttonOnlyLocal); + + renderer.renderLabel(&modDescrLabel); + if (modInfoSelected != NULL) { + string tempImage = getPreviewImageFileForMod(modInfoSelected); + if (displayModPreviewImage.find(tempImage) != + displayModPreviewImage.end() + && displayModPreviewImage[tempImage] == true) { + if (modPreviewImage == NULL) { + string tempImage = getPreviewImageFileForMod(modInfoSelected); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("### Render tempImage [%s] fileExists(tempImage) = %d\n", + tempImage.c_str(), fileExists(tempImage)); + + if (tempImage != "" && fileExists(tempImage) == true) { + cleanupPreviewTexture(); + modPreviewImage = Renderer::findTexture(tempImage); + } + } + if (modPreviewImage != NULL) { + renderer.renderTextureQuad(508, 90, 485, 325, modPreviewImage, + 1.0f); + } + } + } + + // Render Tech List + renderer.renderLabel(&keyTechScrollBarTitle1); + renderer.renderLabel(&keyTechScrollBarTitle2); + if (keyTechScrollBar.getElementCount() != 0) { + for (int i = keyTechScrollBar.getVisibleStart(); + i <= keyTechScrollBar.getVisibleEnd(); ++i) { + bool alreadyHasTech = + (std:: + find(techTreeFiles.begin(), techTreeFiles.end(), + keyTechButtons[i]->getText()) != techTreeFiles.end()); + if (keyTechButtons[i]->getText() == selectedTechName) { + bool lightedOverride = true; + renderer.renderButton(keyTechButtons[i], &WHITE, + &lightedOverride); + } else if (alreadyHasTech == true) { + Vec4f buttonColor = WHITE; + buttonColor.w = 0.75f; + bool remoteHasTech = + (techCacheList.find(keyTechButtons[i]->getText()) != + techCacheList.end()); + if (remoteHasTech) { + ModInfo & modInfo = + techCacheList[keyTechButtons[i]->getText()]; + if (modInfo.crc == modInfo.localCRC) { + keyTechButtons[i]-> + setCustomTexture(CoreData::getInstance(). + getOnServerInstalledTexture()); + } else { + //printf("modInfo.name=%s modInfo.crc=%s modInfo.localCRC=%s\n",modInfo.name.c_str(),modInfo.crc.c_str(),modInfo.localCRC.c_str()); + keyTechButtons[i]-> + setCustomTexture(CoreData::getInstance(). + getOnServerDifferentTexture()); + } + } else { + keyTechButtons[i]->setCustomTexture(CoreData::getInstance(). + getNotOnServerTexture + ()); + } + renderer.renderButton(keyTechButtons[i], &buttonColor); + } else { + Vec4f fontColor = + Vec4f(200.0f / 255.0f, 187.0f / 255.0f, 190.0f / 255.0f, + 0.75f); + //Vec4f fontColor=Vec4f(1.0f, 0.0f, 0.0f, 0.75f); + keyTechButtons[i]->setCustomTexture(CoreData::getInstance(). + getOnServerTexture()); + renderer.renderButton(keyTechButtons[i], &fontColor); + } + renderer.renderLabel(labelsTech[i]); + } + } + renderer.renderScrollBar(&keyTechScrollBar); + + // Render Tileset List + renderer.renderLabel(&keyTilesetScrollBarTitle1); + if (keyTilesetScrollBar.getElementCount() != 0) { + for (int i = keyTilesetScrollBar.getVisibleStart(); + i <= keyTilesetScrollBar.getVisibleEnd(); ++i) { + bool alreadyHasTileset = + (std:: + find(tilesetFiles.begin(), tilesetFiles.end(), + keyTilesetButtons[i]->getText()) != + tilesetFiles.end()); + if (keyTilesetButtons[i]->getText() == selectedTilesetName) { + bool lightedOverride = true; + renderer.renderButton(keyTilesetButtons[i], &WHITE, + &lightedOverride); + } else if (alreadyHasTileset == true) { + Vec4f buttonColor = WHITE; + buttonColor.w = 0.75f; + bool remoteHasTileset = + (tilesetCacheList.find(keyTilesetButtons[i]->getText()) != + tilesetCacheList.end()); + if (remoteHasTileset) { + ModInfo & modInfo = + tilesetCacheList[keyTilesetButtons[i]->getText()]; + + if (modInfo.crc == modInfo.localCRC) { + keyTilesetButtons[i]-> + setCustomTexture(CoreData::getInstance(). + getOnServerInstalledTexture()); + } else { + //printf("modInfo.name=%s modInfo.crc=%s modInfo.localCRC=%s\n",modInfo.name.c_str(),modInfo.crc.c_str(),modInfo.localCRC.c_str()); + //printf("name [%s] modInfo.crc [%s] modInfo.localCRC [%s]\n",modInfo.name.c_str(),modInfo.crc.c_str(),modInfo.localCRC.c_str()); + + keyTilesetButtons[i]-> + setCustomTexture(CoreData::getInstance(). + getOnServerDifferentTexture()); + } + } else { + keyTilesetButtons[i]-> + setCustomTexture(CoreData::getInstance(). + getNotOnServerTexture()); + } + renderer.renderButton(keyTilesetButtons[i], &buttonColor); + } else { + Vec4f fontColor = + Vec4f(200.0f / 255.0f, 187.0f / 255.0f, 190.0f / 255.0f, + 0.75f); + keyTilesetButtons[i]-> + setCustomTexture(CoreData::getInstance(). + getOnServerTexture()); + renderer.renderButton(keyTilesetButtons[i], &fontColor); + } + } + } + renderer.renderScrollBar(&keyTilesetScrollBar); + + // Render Map list + renderer.renderLabel(&keyMapScrollBarTitle1); + renderer.renderLabel(&keyMapScrollBarTitle2); + if (keyMapScrollBar.getElementCount() != 0) { + for (int i = keyMapScrollBar.getVisibleStart(); + i <= keyMapScrollBar.getVisibleEnd(); ++i) { + string mapNameToRender = keyMapButtons[i]->getText(); + bool alreadyHasMap = + (std:: + find(mapFiles.begin(), mapFiles.end(), + mapNameToRender) != mapFiles.end()); + if (keyMapButtons[i]->getText() == selectedMapName) { + bool lightedOverride = true; + renderer.renderButton(keyMapButtons[i], &WHITE, + &lightedOverride); + } else if (alreadyHasMap == true) { + Vec4f buttonColor = WHITE; + buttonColor.w = 0.75f; + bool remoteHasMap = + (mapCacheList.find(keyMapButtons[i]->getText()) != + mapCacheList.end()); + if (remoteHasMap) { + ModInfo & modInfo = + mapCacheList[keyMapButtons[i]->getText()]; + if (modInfo.crc == modInfo.localCRC) { + keyMapButtons[i]-> + setCustomTexture(CoreData::getInstance(). + getOnServerInstalledTexture()); + } else { + //printf("modInfo.name=%s modInfo.crc=%s modInfo.localCRC=%s\n",modInfo.name.c_str(),modInfo.crc.c_str(),modInfo.localCRC.c_str()); + keyMapButtons[i]-> + setCustomTexture(CoreData::getInstance(). + getOnServerDifferentTexture()); + } + } else { + keyMapButtons[i]->setCustomTexture(CoreData::getInstance(). + getNotOnServerTexture()); + } + renderer.renderButton(keyMapButtons[i], &buttonColor); + } else { + Vec4f fontColor = + Vec4f(200.0f / 255.0f, 187.0f / 255.0f, 190.0f / 255.0f, + 0.75f); + keyMapButtons[i]->setCustomTexture(CoreData::getInstance(). + getOnServerTexture()); + renderer.renderButton(keyMapButtons[i], &fontColor); + } + renderer.renderLabel(labelsMap[i]); + } + } + renderer.renderScrollBar(&keyMapScrollBar); + + // Render Scenario List + renderer.renderLabel(&keyScenarioScrollBarTitle1); + if (keyScenarioScrollBar.getElementCount() != 0) { + for (int i = keyScenarioScrollBar.getVisibleStart(); + i <= keyScenarioScrollBar.getVisibleEnd(); ++i) { + if (i >= (int) keyScenarioButtons.size()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "i >= keyScenarioButtons.size(), i = %d keyScenarioButtons.size() = %d", + i, (int) keyScenarioButtons.size()); + throw megaglest_runtime_error(szBuf); + } + bool alreadyHasScenario = + (std:: + find(scenarioFiles.begin(), scenarioFiles.end(), + keyScenarioButtons[i]->getText()) != + scenarioFiles.end()); + + if (keyScenarioButtons[i]->getText() == selectedScenarioName) { + bool lightedOverride = true; + renderer.renderButton(keyScenarioButtons[i], &WHITE, + &lightedOverride); + } else if (alreadyHasScenario == true) { + Vec4f buttonColor = WHITE; + buttonColor.w = 0.75f; + bool remoteHasScenario = + (scenarioCacheList.find(keyScenarioButtons[i]->getText()) != + scenarioCacheList.end()); + if (remoteHasScenario) { + ModInfo & modInfo = + scenarioCacheList[keyScenarioButtons[i]->getText()]; + if (modInfo.crc == modInfo.localCRC) { + keyScenarioButtons[i]-> + setCustomTexture(CoreData::getInstance(). + getOnServerInstalledTexture()); + } else { + //printf("modInfo.name=%s modInfo.crc=%s modInfo.localCRC=%s\n",modInfo.name.c_str(),modInfo.crc.c_str(),modInfo.localCRC.c_str()); + keyScenarioButtons[i]-> + setCustomTexture(CoreData::getInstance(). + getOnServerDifferentTexture()); + } + } else { + keyScenarioButtons[i]-> + setCustomTexture(CoreData::getInstance(). + getNotOnServerTexture()); + } + renderer.renderButton(keyScenarioButtons[i], &buttonColor); + } else { + Vec4f fontColor = + Vec4f(200.0f / 255.0f, 187.0f / 255.0f, 190.0f / 255.0f, + 0.75f); + keyScenarioButtons[i]-> + setCustomTexture(CoreData::getInstance(). + getOnServerTexture()); + renderer.renderButton(keyScenarioButtons[i], &fontColor); + } + } + } + renderer.renderScrollBar(&keyScenarioScrollBar); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + if (fileFTPProgressList.empty() == false) { + Lang & lang = Lang::getInstance(); + int xLocation = buttonReturn.getX(); + int yLocation = buttonReturn.getY() - 12; + for (std::map < string, pair < int, string > >::iterator iterMap = + fileFTPProgressList.begin(); + iterMap != fileFTPProgressList.end(); ++iterMap) { + + string progressLabelPrefix = + lang.getString("ModDownloading") + " " + + extractFileFromDirectoryPath(iterMap->first) + " "; + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nRendering file progress with the following prefix [%s]\n",progressLabelPrefix.c_str()); + + if (Renderer::renderText3DEnabled) { + renderer.renderProgressBar3D(iterMap->second.first, + //10, + //yLocation, + xLocation, + yLocation, + CoreData::getInstance(). + getDisplayFontSmall3D(), 185, + progressLabelPrefix, false); + } else { + renderer.renderProgressBar(iterMap->second.first, + //10, + //yLocation, + xLocation, + yLocation, + CoreData::getInstance(). + getDisplayFontSmall(), 185, + progressLabelPrefix, false); + } + + yLocation -= 14; + } + } + safeMutexFTPProgress.ReleaseLock(); + + renderer.renderConsole(&console, consoleNormal, 3); + + if (mainMessageBox.getEnabled()) { + renderer.renderMessageBox(&mainMessageBox); + } + + if (modMenuState != mmst_None) { + if (oldMenuState != modMenuState) { + Lang & lang = Lang::getInstance(); + if (modMenuState == mmst_Loading) { + pleaseWaitLabel.setText(lang. + getString + ("GettingModlistFromMasterserver")); + } else if (modMenuState == mmst_CalculatingCRC) { + pleaseWaitLabel.setText(lang. + getString + ("PleaseWaitCalculatingCRC")); + } + oldMenuState = modMenuState; + } + float anim = GraphicComponent::getAnim(); + if (anim < 0.5f) { + anim = 1.f - anim; + } + Vec4f colorWithAlpha = Vec4f(ORANGE.x, ORANGE.y, ORANGE.z, anim); + renderer.renderLabel(&pleaseWaitLabel, &colorWithAlpha); + } + if (validMapPreview) { + if (mapPreviewTexture != NULL) { + renderer.renderTextureQuad(5, 185, 150, 150, mapPreviewTexture, + 1.0f); + } + if (enableMapPreview && (mapPreview.hasFileLoaded() == true)) { + + int mouseX = mainMenu->getMouseX(); + int mouseY = mainMenu->getMouseY(); + int mouse2dAnim = mainMenu->getMouse2dAnim(); + + if (mapPreviewTexture == NULL) { + renderer.renderMouse2d(mouseX, mouseY, mouse2dAnim); + renderer.renderMapPreview(&mapPreview, true, 10, 350, + &mapPreviewTexture); + } + } + } + + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + } + + void MenuStateMods::update() { + Chrono chrono; + chrono.start(); + + //Lang &lang= Lang::getInstance(); + + // Tech List + if (keyTechScrollBar.getElementCount() != 0) { + for (int i = keyTechScrollBar.getVisibleStart(); + i <= keyTechScrollBar.getVisibleEnd(); ++i) { + if (i >= (int) keyTechButtons.size()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "i >= keyTechButtons.size(), i = %d, keyTechButtons.size() = %d", + i, (int) keyTechButtons.size()); + throw megaglest_runtime_error(szBuf); + } + + keyTechButtons[i]->setY(keyButtonsYBase - keyButtonsLineHeight * (i + - + keyTechScrollBar. + getVisibleStart + ())); + labelsTech[i]->setY(keyButtonsYBase - + keyButtonsLineHeight * (i - + keyTechScrollBar. + getVisibleStart())); + } + } + + // Tileset List + if (keyTilesetScrollBar.getElementCount() != 0) { + for (int i = keyTilesetScrollBar.getVisibleStart(); + i <= keyTilesetScrollBar.getVisibleEnd(); ++i) { + if (i >= (int) keyTilesetButtons.size()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "i >= keyTilesetButtons.size(), i = %d, keyTilesetButtons.size() = %d", + i, (int) keyTilesetButtons.size()); + throw megaglest_runtime_error(szBuf); + } + + int yPos = keyButtonsYBase - keyButtonsLineHeight * + (i - keyTilesetScrollBar.getVisibleStart()); + keyTilesetButtons[i]->setY(yPos); + } + } + + // Map List + if (keyMapScrollBar.getElementCount() != 0) { + for (int i = keyMapScrollBar.getVisibleStart(); + i <= keyMapScrollBar.getVisibleEnd(); ++i) { + if (i >= (int) keyMapButtons.size()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "i >= keyMapButtons.size(), i = %d, keyMapButtons.size() = %d", + i, (int) keyMapButtons.size()); + throw megaglest_runtime_error(szBuf); + } + + keyMapButtons[i]->setY(keyButtonsYBase - keyButtonsLineHeight * (i + - + keyMapScrollBar. + getVisibleStart + ())); + labelsMap[i]->setY(keyButtonsYBase - + keyButtonsLineHeight * (i - + keyMapScrollBar. + getVisibleStart())); + } + } + + // Scenario List + if (keyScenarioScrollBar.getElementCount() != 0) { + for (int i = keyScenarioScrollBar.getVisibleStart(); + i <= keyScenarioScrollBar.getVisibleEnd(); ++i) { + if (i >= (int) keyScenarioButtons.size()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "i >= keyScenarioButtons.size(), i = %d, keyScenarioButtons.size() = %d", + i, (int) keyScenarioButtons.size()); + throw megaglest_runtime_error(szBuf); + } + + int yPos = keyButtonsYBase - keyButtonsLineHeight * + (i - keyScenarioScrollBar.getVisibleStart()); + keyScenarioButtons[i]->setY(yPos); + } + } + + console.update(); + } + + void MenuStateMods::keyDown(SDL_KeyboardEvent key) { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + //if(key == configKeys.getCharKey("ShowFullConsole")) { + if (isKeyPressed(configKeys.getSDLKey("ShowFullConsole"), key) == + true) { + showFullConsole = true; + } + } + + void MenuStateMods::keyPress(SDL_KeyboardEvent c) { + } + + void MenuStateMods::keyUp(SDL_KeyboardEvent key) { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + //if(key== configKeys.getCharKey("ShowFullConsole")) { + if (isKeyPressed(configKeys.getSDLKey("ShowFullConsole"), key) == + true) { + showFullConsole = false; + } + } + + void MenuStateMods::showMessageBox(const string & text, + const string & header, bool toggle) { + if (toggle == false) { + mainMessageBox.setEnabled(false); + } + + if (mainMessageBox.getEnabled() == false) { + mainMessageBox.setText(text); + mainMessageBox.setHeader(header); + mainMessageBox.setEnabled(true); + } else { + mainMessageBox.setEnabled(false); + } + } + + void MenuStateMods::FTPClient_CallbackEvent(string itemName, + FTP_Client_CallbackType type, + pair < FTP_Client_ResultType, + string > result, + void *userdata) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + Lang & lang = Lang::getInstance(); + if (type == ftp_cct_DownloadProgress) { + FTPClientCallbackInterface::FtpProgressStats * stats = + (FTPClientCallbackInterface::FtpProgressStats *) userdata; + if (stats != NULL) { + int fileProgress = 0; + if (stats->download_total > 0) { + fileProgress = + ((stats->download_now / stats->download_total) * 100.0); + } + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP Callback for [%s] current file [%s] fileProgress = %d [now = %f, total = %f]\n",itemName.c_str(),stats->currentFilename.c_str(), fileProgress,stats->download_now,stats->download_total); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + pair < int, string > lastProgress = fileFTPProgressList[itemName]; + fileFTPProgressList[itemName] = + pair < int, string >(fileProgress, stats->currentFilename); + safeMutexFTPProgress.ReleaseLock(); + } + } else if (type == ftp_cct_ExtractProgress) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Got FTP extract Callback for [%s] result = %d [%s]\n", + itemName.c_str(), result.first, result.second.c_str()); + //printf("Got FTP extract Callback for [%s] result = %d [%s]\n",itemName.c_str(),result.first,result.second.c_str()); + + if (userdata == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("DataMissingExtractDownloadMod").c_str(), + itemName.c_str()); + //printf("%s\n",szBuf); + console.addLine(szBuf, true); + } else { + char *szBuf = (char *) userdata; + //printf("%s\n",szBuf); + console.addLine(szBuf); + } + } else if (type == ftp_cct_File) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Got FTP Callback for [%s] result = %d [%s]\n", + itemName.c_str(), result.first, result.second.c_str()); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + fileFTPProgressList.erase(itemName); + safeMutexFTPProgress.ReleaseLock(); + + //printf("### downloaded file [%s] result = %d\n",itemName.c_str(),result.first); + + if (result.first == ftp_crt_SUCCESS) { + displayModPreviewImage[itemName] = true; + } + } + + else if (type == ftp_cct_Map) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Got FTP Callback for [%s] result = %d [%s]\n", + itemName.c_str(), result.first, result.second.c_str()); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + fileFTPProgressList.erase(itemName); + safeMutexFTPProgress.ReleaseLock(); + selectedMapName = ""; + buttonInstallMap.setEnabled(true); + + if (result.first == ftp_crt_SUCCESS) { + refreshMaps(); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModDownloadMapSuccess").c_str(), + itemName.c_str()); + console.addLine(szBuf, true); + } else { + curl_version_info_data *curlVersion = + curl_version_info(CURLVERSION_NOW); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModDownloadMapFail").c_str(), + itemName.c_str(), curlVersion->version, + result.second.c_str()); + console.addLine(szBuf, true); + } + } else if (type == ftp_cct_Tileset) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Got FTP Callback for [%s] result = %d [%s]\n", + itemName.c_str(), result.first, result.second.c_str()); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + fileFTPProgressList.erase(itemName); + safeMutexFTPProgress.ReleaseLock(true); + + selectedTilesetName = ""; + buttonInstallTileset.setEnabled(true); + + if (result.first == ftp_crt_SUCCESS) { + refreshTilesets(); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModDownloadTilesetSuccess").c_str(), + itemName.c_str()); + console.addLine(szBuf, true); + // END + } else { + curl_version_info_data *curlVersion = + curl_version_info(CURLVERSION_NOW); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModDownloadTilesetFail").c_str(), + itemName.c_str(), curlVersion->version, + result.second.c_str()); + console.addLine(szBuf, true); + } + } else if (type == ftp_cct_Techtree) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Got FTP Callback for [%s] result = %d [%s]\n", + itemName.c_str(), result.first, result.second.c_str()); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + fileFTPProgressList.erase(itemName); + safeMutexFTPProgress.ReleaseLock(true); + + selectedTechName = ""; + buttonInstallTech.setEnabled(true); + + if (result.first == ftp_crt_SUCCESS) { + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModDownloadTechSuccess").c_str(), + itemName.c_str()); + console.addLine(szBuf, true); + + // START + // Clear the CRC Cache if it is populated + safeMutexFTPProgress.Lock(); + Checksum::clearFileCache(); + + vector < string > paths = + Config::getInstance().getPathListForType(ptTechs); + string pathSearchString = string("/") + itemName + string("/*"); + const string filterFileExt = ".xml"; + clearFolderTreeContentsCheckSum(paths, pathSearchString, + filterFileExt); + clearFolderTreeContentsCheckSumList(paths, pathSearchString, + filterFileExt); + + // Refresh CRC + Config & config = Config::getInstance(); + getFolderTreeContentsCheckSumRecursively(config. + getPathListForType + (ptTechs, ""), + string("/") + itemName + + string("/*"), ".xml", + NULL, true); + safeMutexFTPProgress.ReleaseLock(); + + refreshTechs(); + // END + } else { + curl_version_info_data *curlVersion = + curl_version_info(CURLVERSION_NOW); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModDownloadTechFail").c_str(), + itemName.c_str(), curlVersion->version, + result.second.c_str()); + console.addLine(szBuf, true); + } + } else if (type == ftp_cct_Scenario) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Got FTP Callback for [%s] result = %d [%s]\n", + itemName.c_str(), result.first, result.second.c_str()); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + fileFTPProgressList.erase(itemName); + safeMutexFTPProgress.ReleaseLock(true); + + selectedScenarioName = ""; + buttonInstallScenario.setEnabled(true); + + if (result.first == ftp_crt_SUCCESS) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModDownloadScenarioSuccess").c_str(), + itemName.c_str()); + console.addLine(szBuf, true); + + // START + // Clear the CRC Cache if it is populated + // + // Clear the CRC file Cache + safeMutexFTPProgress.Lock(); + Checksum::clearFileCache(); + + vector < string > paths = + Config::getInstance().getPathListForType(ptScenarios); + string pathSearchString = string("/") + itemName + string("/*"); + const string filterFileExt = ".xml"; + clearFolderTreeContentsCheckSum(paths, pathSearchString, + filterFileExt); + clearFolderTreeContentsCheckSumList(paths, pathSearchString, + filterFileExt); + + // Refresh CRC + Config & config = Config::getInstance(); + getFolderTreeContentsCheckSumRecursively(config. + getPathListForType + (ptScenarios, ""), + string("/") + itemName + + string("/*"), ".xml", + NULL, true); + safeMutexFTPProgress.ReleaseLock(); + + refreshScenarios(); + // END + } else { + curl_version_info_data *curlVersion = + curl_version_info(CURLVERSION_NOW); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("ModDownloadScenarioFail").c_str(), + itemName.c_str(), curlVersion->version, + result.second.c_str()); + console.addLine(szBuf, true); + } + } + + } + } -*/ - - Config & config = Config::getInstance (); - string scenarioDir = ""; - vector < string > pathList = - config.getPathListForType (ptMaps, scenarioDir); - vector < string > invalidMapList; - vector < string > allMaps = - MapPreview::findAllValidMaps (pathList, scenarioDir, false, false, - &invalidMapList); - if (allMaps.empty ()) - { - throw megaglest_runtime_error ("No maps were found!"); - } - vector < string > results; - copy (allMaps.begin (), allMaps.end (), std::back_inserter (results)); - mapFiles = results; - - mapFilesUserData = - MapPreview::findAllValidMaps (pathList, scenarioDir, true, false, - &invalidMapList); - } - - string MenuStateMods::refreshMapModInfo (string mapInfo) - { - std::vector < std::string > mapInfoList; - Tokenize (mapInfo, mapInfoList, "|"); - if (mapInfoList.size () >= 6) - { - //Config &config = Config::getInstance(); - ModInfo modinfo; - modinfo.name = mapInfoList[0]; - modinfo.count = mapInfoList[1]; - modinfo.crc = mapInfoList[2]; - modinfo.description = mapInfoList[3]; - modinfo.url = mapInfoList[4]; - modinfo.imageUrl = mapInfoList[5]; - modinfo.type = mt_Map; - modinfo.localCRC = getMapCRC (modinfo.name); - mapCacheList[modinfo.name] = modinfo; - return modinfo.name; - } - return ""; - } - - string MenuStateMods::getMapCRC (string mapName) - { - Config & config = Config::getInstance (); - vector < string > mappaths = config.getPathListForType (ptMaps, ""); - string result = ""; - if (mappaths.empty () == false) - { - Checksum checksum; - string itemPath = mappaths[1] + "/" + mapName; - if (fileExists (itemPath)) - { - checksum.addFile (itemPath); - uint32 crc = checksum.getSum (); - result = uIntToStr (crc); - //printf("itemPath='%s' modinfo.name='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); - } - else - { - itemPath = mappaths[0] + "/" + mapName; - if (fileExists (itemPath)) - { - checksum.addFile (itemPath); - uint32 crc = checksum.getSum (); - result = uIntToStr (crc); - //printf("itemPath='%s' modinfo.name='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.name.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); - } - else - { - result = ""; - } - } - } - else - { - result = ""; - } - return result; - } - - void MenuStateMods::refreshMaps () - { - getMapsLocalList (); - for (int i = 0; i < (int) mapListRemote.size (); i++) - { - refreshMapModInfo (mapListRemote[i]); - } - } - - void MenuStateMods::getScenariosLocalList () - { - Config & config = Config::getInstance (); - vector < string > results; - findDirs (config.getPathListForType (ptScenarios), results); - scenarioFiles = results; - - scenarioFilesUserData.clear (); - if (config.getPathListForType (ptScenarios).size () > 1) - { - string path = config.getPathListForType (ptScenarios)[1]; - endPathWithSlash (path); - findDirs (path, scenarioFilesUserData, false, false); - } - } - - string MenuStateMods::refreshScenarioModInfo (string scenarioInfo) - { - std::vector < std::string > scenarioInfoList; - Tokenize (scenarioInfo, scenarioInfoList, "|"); - if (scenarioInfoList.size () >= 5) - { - Config & config = Config::getInstance (); - ModInfo modinfo; - modinfo.name = scenarioInfoList[0]; - modinfo.crc = scenarioInfoList[1]; - modinfo.description = scenarioInfoList[2]; - modinfo.url = scenarioInfoList[3]; - modinfo.imageUrl = scenarioInfoList[4]; - modinfo.type = mt_Scenario; - - string itemPath = - config.getPathListForType (ptScenarios, - "")[1] + "/" + modinfo.name + - string ("/*"); - if (itemPath.empty () == false) - { - bool forceRefresh = - (mapCRCUpdateList.find (itemPath) == mapCRCUpdateList.end ()); - uint32 crc = - getFolderTreeContentsCheckSumRecursively (itemPath, ".xml", NULL, - forceRefresh); - if (crc == 0) - { - itemPath = - config.getPathListForType (ptScenarios, - "")[0] + "/" + modinfo.name + - string ("/*"); - if (itemPath.empty () == false) - { - forceRefresh = - (mapCRCUpdateList.find (itemPath) == mapCRCUpdateList.end ()); - crc = - getFolderTreeContentsCheckSumRecursively (itemPath, ".xml", - NULL, forceRefresh); - } - } - modinfo.localCRC = uIntToStr (crc); - //printf(" itemPath='%s' remote crc:'%s' local crc:'%s' crc='%d' \n",itemPath.c_str(),modinfo.crc.c_str(),modinfo.localCRC.c_str(),crc); - } - else - { - modinfo.localCRC = ""; - } - scenarioCacheList[modinfo.name] = modinfo; - return modinfo.name; - } - return ""; - } - - void MenuStateMods::refreshScenarios () - { - getScenariosLocalList (); - for (int i = 0; i < (int) scenarioListRemote.size (); i++) - { - refreshScenarioModInfo (scenarioListRemote[i]); - } - } - - - void MenuStateMods::cleanUp () - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - if (modHttpServerThread != NULL) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - modHttpServerThread->signalQuit (); - //modHttpServerThread->setThreadOwnerValid(false); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - if (modHttpServerThread->canShutdown (true) == true - && modHttpServerThread->shutdownAndWait () == true) - { - delete modHttpServerThread; - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - modHttpServerThread = NULL; - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - if (ftpClientThread != NULL) - { - ftpClientThread->setCallBackObject (NULL); - ftpClientThread->signalQuit (); - sleep (0); - if (ftpClientThread->canShutdown (true) == true && - ftpClientThread->shutdownAndWait () == true) - { - delete ftpClientThread; - } - else - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s %d] Error cannot shutdown ftpClientThread\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - //SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("%s", szBuf); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - //publishToMasterserverThread->cleanup(); - } - ftpClientThread = NULL; - -// ftpClientThread->signalQuit(); -// ftpClientThread->setCallBackObject(NULL); -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); -// if( ftpClientThread->shutdownAndWait() == true) { -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); -// delete ftpClientThread; -// } -// ftpClientThread = NULL; -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - clearUserButtons (); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - cleanupPreviewTexture (); - cleanupMapPreviewTexture (); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - } - - MenuStateMods::~MenuStateMods () - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - cleanUp (); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - } - - void MenuStateMods::clearUserButtons () - { - // Techs - while (!keyTechButtons.empty ()) - { - delete keyTechButtons.back (); - keyTechButtons.pop_back (); - } - keyTechScrollBar.setElementCount (0); - - while (!labelsTech.empty ()) - { - delete labelsTech.back (); - labelsTech.pop_back (); - } - - // Tilesets - while (!keyTilesetButtons.empty ()) - { - delete keyTilesetButtons.back (); - keyTilesetButtons.pop_back (); - } - keyTilesetScrollBar.setElementCount (0); - - // Maps - while (!keyMapButtons.empty ()) - { - delete keyMapButtons.back (); - keyMapButtons.pop_back (); - } - while (!labelsMap.empty ()) - { - delete labelsMap.back (); - labelsMap.pop_back (); - } - keyMapScrollBar.setElementCount (0); - - // Scenarios - while (!keyScenarioButtons.empty ()) - { - delete keyScenarioButtons.back (); - keyScenarioButtons.pop_back (); - } - keyScenarioScrollBar.setElementCount (0); - } - - void MenuStateMods::mouseClick (int x, int y, MouseButton mouseButton) - { - - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - Lang & lang = Lang::getInstance (); - - if (buttonReturn.mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - soundRenderer.playFx (coreData.getClickSoundA ()); - - if (fileFTPProgressList.empty () == false) - { - mainMessageBoxState = ftpmsg_Quit; - mainMessageBox.init (lang.getString ("Yes"), lang.getString ("No"), - 450); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModDownloadInProgressCancelQuestion"). - c_str (), fileFTPProgressList.size ()); - showMessageBox (szBuf, lang.getString ("Question"), true); - } - else - { - cleanUp (); - mainMenu->setState (new MenuStateRoot (program, mainMenu)); - return; - } - } - else if (mainMessageBox.getEnabled ()) - { - int button = 0; - if (mainMessageBox.mouseClick (x, y, button)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMessageBox.setEnabled (false); - mainMessageBox.init (lang.getString ("Yes"), lang.getString ("No"), - 450); - if (button == 0) - { - if (mainMessageBoxState == ftpmsg_Quit) - { - mainMessageBoxState = ftpmsg_None; - mainMenu->setState (new MenuStateRoot (program, mainMenu)); - return; - } - else if (mainMessageBoxState == ftpmsg_GetMap || - mainMessageBoxState == ftpmsg_ReplaceMap) - { - bool getItemAfterRemoval = - (mainMessageBoxState == ftpmsg_ReplaceMap); - mainMessageBoxState = ftpmsg_None; - - Config & config = Config::getInstance (); - vector < string > mapPaths = config.getPathListForType (ptMaps); - if (mapPaths.size () > 1) - { - string removeMap = mapPaths[1]; - endPathWithSlash (removeMap); - removeMap += selectedMapName; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Removing Map [%s]\n", removeMap.c_str ()); - removeFile (removeMap); - - bool remoteHasMap = - (mapCacheList.find (selectedMapName) != - mapCacheList.end ()); - if (remoteHasMap == false) - { - for (unsigned int i = 0; i < keyMapButtons.size (); ++i) - { - GraphicButton *button = keyMapButtons[i]; - if (button != NULL - && button->getText () == selectedMapName) - { - delete button; - keyMapButtons.erase (keyMapButtons.begin () + i); - labelsMap.erase (labelsMap.begin () + i); - keyMapScrollBar.setElementCount ((int) keyMapButtons. - size ()); - break; - } - } - } - - if (getItemAfterRemoval == false) - { - selectedMapName = ""; - } - refreshMaps (); - Checksum::clearFileCache (); - - if (getItemAfterRemoval == true) - { - string mapName = selectedMapName; - string mapURL = mapCacheList[mapName].url; - if (ftpClientThread != NULL) - ftpClientThread->addMapToRequests (mapName, mapURL); - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), - mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()-> - setOwnerId (mutexOwnerId); - fileFTPProgressList[mapName] = pair < int, string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - buttonInstallMap.setEnabled (false); - } - } - } - else if (mainMessageBoxState == ftpmsg_GetTileset || - mainMessageBoxState == ftpmsg_ReplaceTileset) - { - bool getItemAfterRemoval = - (mainMessageBoxState == ftpmsg_ReplaceTileset); - mainMessageBoxState = ftpmsg_None; - - Config & config = Config::getInstance (); - vector < string > tilesetPaths = - config.getPathListForType (ptTilesets); - if (tilesetPaths.size () > 1) - { - string removeTileset = tilesetPaths[1]; - endPathWithSlash (removeTileset); - removeTileset += selectedTilesetName; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Removing Tileset [%s]\n", removeTileset.c_str ()); - removeFolder (removeTileset); - - bool remoteHasTileset = - (tilesetCacheList.find (selectedTilesetName) != - tilesetCacheList.end ()); - if (remoteHasTileset == false) - { - //printf("\n\n\n$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ remote DOES NOT have removed tileset [%s]\n\n\n",selectedTilesetName.c_str()); - - for (unsigned int i = 0; i < keyTilesetButtons.size (); ++i) - { - GraphicButton *button = keyTilesetButtons[i]; - if (button != NULL - && button->getText () == selectedTilesetName) - { - delete button; - keyTilesetButtons.erase (keyTilesetButtons.begin () + - i); - keyTilesetScrollBar. - setElementCount ((int) keyTilesetButtons.size ()); - break; - } - } - } - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), - mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()-> - setOwnerId (mutexOwnerId); - Checksum::clearFileCache (); - vector < string > paths = - Config::getInstance ().getPathListForType (ptTilesets); - string pathSearchString = - string ("/") + selectedTilesetName + string ("/*"); - const string filterFileExt = ".xml"; - clearFolderTreeContentsCheckSum (paths, pathSearchString, - filterFileExt); - clearFolderTreeContentsCheckSumList (paths, pathSearchString, - filterFileExt); - safeMutexFTPProgress.ReleaseLock (); - - if (getItemAfterRemoval == false) - { - selectedTilesetName = ""; - } - refreshTilesets (); - } - - if (getItemAfterRemoval == true) - { - string tilesetName = selectedTilesetName; - string tilesetURL = tilesetCacheList[tilesetName].url; - if (ftpClientThread != NULL) - ftpClientThread->addTilesetToRequests (tilesetName, - tilesetURL); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), - mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()-> - setOwnerId (mutexOwnerId); - fileFTPProgressList[tilesetName] = - pair < int, string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - buttonInstallTileset.setEnabled (false); - } - } - else if (mainMessageBoxState == ftpmsg_GetTechtree || - mainMessageBoxState == ftpmsg_ReplaceTechtree) - { - bool getItemAfterRemoval = - (mainMessageBoxState == ftpmsg_ReplaceTechtree); - mainMessageBoxState = ftpmsg_None; - - Config & config = Config::getInstance (); - vector < string > techPaths = - config.getPathListForType (ptTechs); - if (techPaths.size () > 1) - { - string removeTech = techPaths[1]; - endPathWithSlash (removeTech); - removeTech += selectedTechName; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Removing Techtree [%s]\n", removeTech.c_str ()); - removeFolder (removeTech); - - bool remoteHasTech = - (techCacheList.find (selectedTechName) != - techCacheList.end ()); - if (remoteHasTech == false) - { - for (unsigned int i = 0; i < keyTechButtons.size (); ++i) - { - GraphicButton *button = keyTechButtons[i]; - if (button != NULL - && button->getText () == selectedTechName) - { - delete button; - keyTechButtons.erase (keyTechButtons.begin () + i); - labelsTech.erase (labelsTech.begin () + i); - keyTechScrollBar.setElementCount ((int) keyTechButtons. - size ()); - break; - } - } - } - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), - mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()-> - setOwnerId (mutexOwnerId); - // Clear the CRC file Cache - Checksum::clearFileCache (); - vector < string > paths = - Config::getInstance ().getPathListForType (ptTechs); - string pathSearchString = - string ("/") + selectedTechName + string ("/*"); - const string filterFileExt = ".xml"; - clearFolderTreeContentsCheckSum (paths, pathSearchString, - filterFileExt); - clearFolderTreeContentsCheckSumList (paths, pathSearchString, - filterFileExt); - safeMutexFTPProgress.ReleaseLock (); - - if (getItemAfterRemoval == false) - { - selectedTechName = ""; - } - refreshTechs (); - } - - if (getItemAfterRemoval == true) - { - string techName = selectedTechName; - string techURL = techCacheList[techName].url; - if (ftpClientThread != NULL) - ftpClientThread->addTechtreeToRequests (techName, techURL); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), - mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()-> - setOwnerId (mutexOwnerId); - fileFTPProgressList[techName] = pair < int, string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - buttonInstallTech.setEnabled (false); - } - } - else if (mainMessageBoxState == ftpmsg_GetScenario || - mainMessageBoxState == ftpmsg_ReplaceScenario) - { - bool getItemAfterRemoval = - (mainMessageBoxState == ftpmsg_ReplaceScenario); - mainMessageBoxState = ftpmsg_None; - - Config & config = Config::getInstance (); - vector < string > scenarioPaths = - config.getPathListForType (ptScenarios); - if (scenarioPaths.size () > 1) - { - string removeScenario = scenarioPaths[1]; - endPathWithSlash (removeScenario); - removeScenario += selectedScenarioName; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Removing Scenario [%s]\n", - removeScenario.c_str ()); - removeFolder (removeScenario); - - bool remoteHasScenario = - (scenarioCacheList.find (selectedScenarioName) != - scenarioCacheList.end ()); - if (remoteHasScenario == false) - { - for (unsigned int i = 0; i < keyScenarioButtons.size (); - ++i) - { - GraphicButton *button = keyScenarioButtons[i]; - if (button != NULL - && button->getText () == selectedScenarioName) - { - delete button; - keyScenarioButtons.erase (keyScenarioButtons.begin () + - i); - keyScenarioScrollBar. - setElementCount ((int) keyScenarioButtons.size ()); - break; - } - } - } - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), - mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()-> - setOwnerId (mutexOwnerId); - Checksum::clearFileCache (); - vector < string > paths = - Config::getInstance ().getPathListForType (ptScenarios); - string pathSearchString = - string ("/") + selectedScenarioName + string ("/*"); - const string filterFileExt = ".xml"; - clearFolderTreeContentsCheckSum (paths, pathSearchString, - filterFileExt); - clearFolderTreeContentsCheckSumList (paths, pathSearchString, - filterFileExt); - safeMutexFTPProgress.ReleaseLock (); - - if (getItemAfterRemoval == false) - { - selectedScenarioName = ""; - } - refreshScenarios (); - } - - if (getItemAfterRemoval == true) - { - string scenarioName = selectedScenarioName; - string scenarioURL = scenarioCacheList[scenarioName].url; - if (ftpClientThread != NULL) - ftpClientThread->addScenarioToRequests (scenarioName, - scenarioURL); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), - mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()-> - setOwnerId (mutexOwnerId); - fileFTPProgressList[scenarioName] = - pair < int, string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - buttonInstallScenario.setEnabled (false); - } - } - } - } - } - else if (keyTechScrollBar.mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - soundRenderer.playFx (coreData.getClickSoundA ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - else if (keyTilesetScrollBar.mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - soundRenderer.playFx (coreData.getClickSoundA ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - else if (keyMapScrollBar.mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - soundRenderer.playFx (coreData.getClickSoundA ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - else if (keyScenarioScrollBar.mouseClick (x, y)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - soundRenderer.playFx (coreData.getClickSoundA ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - else if (buttonInstallTech.mouseClick (x, y) - && buttonInstallTech.getEnabled ()) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - if (selectedTechName != "") - { - bool alreadyHasTech = - (std:: - find (techTreeFiles.begin (), techTreeFiles.end (), - selectedTechName) != techTreeFiles.end ()); - if (alreadyHasTech == true) - { - bool remoteHasTech = - (techCacheList.find (selectedTechName) != techCacheList.end ()); - if (remoteHasTech == true) - { - ModInfo & modInfo = techCacheList[selectedTechName]; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d] remote CRC [%s]\n", __FILE__, - __FUNCTION__, __LINE__, modInfo.crc.c_str ()); - - Config & config = Config::getInstance (); - string itemPath = - config.getPathListForType (ptTechs, - "")[1] + "/" + selectedTechName + - string ("/*"); - bool forceRefresh = - (mapCRCUpdateList.find (itemPath) == mapCRCUpdateList.end ()); - if (strToUInt (modInfo.crc) != 0 - && strToUInt (modInfo.crc) != - getFolderTreeContentsCheckSumRecursively (itemPath, ".xml", - NULL, - forceRefresh)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d] local CRC [%u]\n", __FILE__, - __FUNCTION__, __LINE__, - getFolderTreeContentsCheckSumRecursively (itemPath, - ".xml", - NULL)); - - mainMessageBoxState = ftpmsg_ReplaceTechtree; - mainMessageBox.init (lang.getString ("Yes"), - lang.getString ("No"), 450); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModLocalRemoteMismatch").c_str (), - selectedTechName.c_str ()); - showMessageBox (szBuf, lang.getString ("Notice"), true); - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModTechAlreadyInstalled").c_str (), - selectedTechName.c_str ()); - showMessageBox (szBuf, lang.getString ("Notice"), true); - } - mapCRCUpdateList[itemPath] = true; - } - } - else - { - string techName = selectedTechName; - string techURL = techCacheList[techName].url; - if (ftpClientThread != NULL) - ftpClientThread->addTechtreeToRequests (techName, techURL); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), - mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()->setOwnerId (mutexOwnerId); - fileFTPProgressList[techName] = pair < int, string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - buttonInstallTech.setEnabled (false); - } - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - showMessageBox (lang.getString ("ModSelectTechToInstall"), - lang.getString ("Notice"), true); - } - } - else if (buttonRemoveTech.mouseClick (x, y) - && buttonRemoveTech.getEnabled ()) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - if (selectedTechName != "") - { - bool alreadyHasTech = - (std:: - find (techTreeFiles.begin (), techTreeFiles.end (), - selectedTechName) != techTreeFiles.end ()); - if (alreadyHasTech == true) - { - mainMessageBoxState = ftpmsg_GetTechtree; - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModRemoveTechConfirm").c_str (), - selectedTechName.c_str ()); - showMessageBox (szBuf, lang.getString ("Question"), true); - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModCannotRemoveTechNotInstalled"). - c_str (), selectedTechName.c_str ()); - showMessageBox (szBuf, lang.getString ("Notice"), true); - } - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - - showMessageBox (lang.getString ("ModSelectTechToRemove"), - lang.getString ("Notice"), true); - } - } - - else if (buttonInstallTileset.mouseClick (x, y) - && buttonInstallTileset.getEnabled ()) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - if (selectedTilesetName != "") - { - bool alreadyHasTileset = - (std:: - find (tilesetFiles.begin (), tilesetFiles.end (), - selectedTilesetName) != tilesetFiles.end ()); - if (alreadyHasTileset == true) - { - bool remoteHasTileset = - (tilesetCacheList.find (selectedTilesetName) != - tilesetCacheList.end ()); - if (remoteHasTileset) - { - ModInfo & modInfo = tilesetCacheList[selectedTilesetName]; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d] remote CRC [%s]\n", __FILE__, - __FUNCTION__, __LINE__, modInfo.crc.c_str ()); - - Config & config = Config::getInstance (); - string itemPath = - config.getPathListForType (ptTilesets, - "")[1] + "/" + - selectedTilesetName + string ("/*"); - bool forceRefresh = - (mapCRCUpdateList.find (itemPath) == mapCRCUpdateList.end ()); - - if (strToUInt (modInfo.crc) != 0 && - strToUInt (modInfo.crc) != - getFolderTreeContentsCheckSumRecursively (itemPath, ".xml", - NULL, - forceRefresh)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d] local CRC [%u] [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - getFolderTreeContentsCheckSumRecursively (itemPath, - ".xml", - NULL), - itemPath.c_str ()); - - mainMessageBoxState = ftpmsg_ReplaceTileset; - mainMessageBox.init (lang.getString ("Yes"), - lang.getString ("No"), 450); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModLocalRemoteMismatch").c_str (), - selectedTilesetName.c_str ()); - showMessageBox (szBuf, lang.getString ("Notice"), true); - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModTilesetAlreadyInstalled"). - c_str (), selectedTilesetName.c_str ()); - showMessageBox (szBuf, lang.getString ("Notice"), true); - } - } - } - else - { - string tilesetName = selectedTilesetName; - string tilesetURL = tilesetCacheList[tilesetName].url; - if (ftpClientThread != NULL) - ftpClientThread->addTilesetToRequests (tilesetName, tilesetURL); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), - mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()->setOwnerId (mutexOwnerId); - fileFTPProgressList[tilesetName] = pair < int, string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - buttonInstallTileset.setEnabled (false); - } - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - showMessageBox (lang.getString ("ModSelectTilesetToInstall"), - lang.getString ("Notice"), true); - } - } - else if (buttonRemoveTileset.mouseClick (x, y) - && buttonRemoveTileset.getEnabled ()) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - if (selectedTilesetName != "") - { - bool alreadyHasTileset = - (std:: - find (tilesetFiles.begin (), tilesetFiles.end (), - selectedTilesetName) != tilesetFiles.end ()); - if (alreadyHasTileset == true) - { - mainMessageBoxState = ftpmsg_GetTileset; - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModRemoveTilesetConfirm").c_str (), - selectedTilesetName.c_str ()); - showMessageBox (szBuf, lang.getString ("Question"), true); - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModCannotRemoveTilesetNotInstalled"). - c_str (), selectedTilesetName.c_str ()); - showMessageBox (szBuf, lang.getString ("Notice"), true); - } - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - showMessageBox (lang.getString ("ModSelectTilesetToRemove"), - lang.getString ("Notice"), true); - } - } - - else if (buttonInstallMap.mouseClick (x, y) - && buttonInstallMap.getEnabled ()) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - if (selectedMapName != "") - { - bool alreadyHasMap = - (std:: - find (mapFiles.begin (), mapFiles.end (), - selectedMapName) != mapFiles.end ()); - if (alreadyHasMap == true) - { - bool remoteHasMap = - (mapCacheList.find (selectedMapName) != mapCacheList.end ()); - if (remoteHasMap) - { - ModInfo & modInfo = mapCacheList[selectedMapName]; - if (modInfo.crc != modInfo.localCRC) - { - mainMessageBoxState = ftpmsg_ReplaceMap; - mainMessageBox.init (lang.getString ("Yes"), - lang.getString ("No"), 450); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModLocalRemoteMismatch").c_str (), - selectedMapName.c_str ()); - showMessageBox (szBuf, lang.getString ("Notice"), true); - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModMapAlreadyInstalled").c_str (), - selectedMapName.c_str ()); - showMessageBox (szBuf, lang.getString ("Notice"), true); - } - } - } - else - { - string mapName = selectedMapName; - string mapURL = mapCacheList[mapName].url; - if (ftpClientThread != NULL) - ftpClientThread->addMapToRequests (mapName, mapURL); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), - mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()->setOwnerId (mutexOwnerId); - fileFTPProgressList[mapName] = pair < int, string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - buttonInstallMap.setEnabled (false); - } - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - showMessageBox (lang.getString ("ModSelectMapToInstall"), - lang.getString ("Notice"), true); - } - } - else if (buttonRemoveMap.mouseClick (x, y) - && buttonRemoveMap.getEnabled ()) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - if (selectedMapName != "") - { - bool alreadyHasMap = - (std:: - find (mapFiles.begin (), mapFiles.end (), - selectedMapName) != mapFiles.end ()); - if (alreadyHasMap == true) - { - mainMessageBoxState = ftpmsg_GetMap; - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModRemoveMapConfirm").c_str (), - selectedMapName.c_str ()); - showMessageBox (szBuf, lang.getString ("Question"), true); - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModCannotRemoveMapNotInstalled"). - c_str (), selectedMapName.c_str ()); - showMessageBox (szBuf, lang.getString ("Notice"), true); - } - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - showMessageBox (lang.getString ("ModSelectMapToRemove"), - lang.getString ("Notice"), true); - } - } - - else if (buttonInstallScenario.mouseClick (x, y) - && buttonInstallScenario.getEnabled ()) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - if (selectedScenarioName != "") - { - bool alreadyHasScenario = - (std:: - find (scenarioFiles.begin (), scenarioFiles.end (), - selectedScenarioName) != scenarioFiles.end ()); - if (alreadyHasScenario == true) - { - bool remoteHasScenario = - (scenarioCacheList.find (selectedScenarioName) != - scenarioCacheList.end ()); - if (remoteHasScenario) - { - ModInfo & modInfo = scenarioCacheList[selectedScenarioName]; - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d] remote CRC [%s]\n", __FILE__, - __FUNCTION__, __LINE__, modInfo.crc.c_str ()); - - Config & config = Config::getInstance (); - string itemPath = - config.getPathListForType (ptScenarios, - "")[1] + "/" + - selectedScenarioName + string ("/*"); - bool forceRefresh = - (mapCRCUpdateList.find (itemPath) == mapCRCUpdateList.end ()); - - if (strToUInt (modInfo.crc) != 0 && - strToUInt (modInfo.crc) != - getFolderTreeContentsCheckSumRecursively (itemPath, "", - NULL, - forceRefresh)) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d] local CRC [%u]\n", __FILE__, - __FUNCTION__, __LINE__, - getFolderTreeContentsCheckSumRecursively (itemPath, - "", - NULL)); - - mainMessageBoxState = ftpmsg_ReplaceScenario; - mainMessageBox.init (lang.getString ("Yes"), - lang.getString ("No"), 450); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModLocalRemoteMismatch").c_str (), - selectedScenarioName.c_str ()); - showMessageBox (szBuf, lang.getString ("Notice"), true); - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModScenarioAlreadyInstalled"). - c_str (), selectedScenarioName.c_str ()); - showMessageBox (szBuf, lang.getString ("Notice"), true); - } - } - } - else - { - string scenarioName = selectedScenarioName; - string scenarioURL = scenarioCacheList[scenarioName].url; - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] adding file to download [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioURL.c_str()); - if (ftpClientThread != NULL) - ftpClientThread->addScenarioToRequests (scenarioName, - scenarioURL); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), - mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()->setOwnerId (mutexOwnerId); - fileFTPProgressList[scenarioName] = pair < int, string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - buttonInstallScenario.setEnabled (false); - } - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - showMessageBox (lang.getString ("ModSelectScenarioToInstall"), - lang.getString ("Notice"), true); - } - } - else if (buttonRemoveScenario.mouseClick (x, y) - && buttonRemoveScenario.getEnabled ()) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - if (selectedScenarioName != "") - { - bool alreadyHasScenario = - (std:: - find (scenarioFiles.begin (), scenarioFiles.end (), - selectedScenarioName) != scenarioFiles.end ()); - if (alreadyHasScenario == true) - { - mainMessageBoxState = ftpmsg_GetScenario; - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModRemoveScenarioConfirm").c_str (), - selectedScenarioName.c_str ()); - showMessageBox (szBuf, lang.getString ("Question"), true); - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModCannotRemoveScenarioNotInstalled"). - c_str (), selectedScenarioName.c_str ()); - showMessageBox (szBuf, lang.getString ("Notice"), true); - } - } - else - { - mainMessageBoxState = ftpmsg_None; - mainMessageBox.init (lang.getString ("Ok"), 450); - showMessageBox (lang.getString ("ModSelectScenarioToRemove"), - lang.getString ("Notice"), true); - } - } - - else - { - if (keyMapScrollBar.getElementCount () != 0) - { - for (int i = keyMapScrollBar.getVisibleStart (); - i <= keyMapScrollBar.getVisibleEnd (); ++i) - { - if (keyMapButtons[i]->mouseClick (x, y) - && keyMapButtons[i]->getEnabled ()) - { - string mapName = keyMapButtons[i]->getText (); - selectedTechName = ""; - selectedTilesetName = ""; - selectedMapName = ""; - selectedScenarioName = ""; - if (mapName != "") - { - selectedMapName = mapName; - bool remoteHasMap = - (mapCacheList.find (mapName) != mapCacheList.end ()); - if (remoteHasMap) - { - showRemoteDesription (&mapCacheList[selectedMapName]); - if (mapCacheList[selectedMapName].localCRC != "") - { - loadMapPreview (mapName); - } - } - else - { - showLocalDescription (mapName); - loadMapPreview (mapName); - } - - } - break; - } - } - } - if (keyTechScrollBar.getElementCount () != 0) - { - for (int i = keyTechScrollBar.getVisibleStart (); - i <= keyTechScrollBar.getVisibleEnd (); ++i) - { - if (keyTechButtons[i]->mouseClick (x, y) - && keyTechButtons[i]->getEnabled ()) - { - string techName = keyTechButtons[i]->getText (); - selectedTechName = ""; - selectedTilesetName = ""; - selectedMapName = ""; - selectedScenarioName = ""; - if (techName != "") - { - selectedTechName = techName; - bool remoteHasTech = - (techCacheList.find (techName) != techCacheList.end ()); - if (remoteHasTech) - { - showRemoteDesription (&techCacheList[techName]); - } - else - { - showLocalDescription (techName); - } - } - break; - } - } - } - if (keyTilesetScrollBar.getElementCount () != 0) - { - for (int i = keyTilesetScrollBar.getVisibleStart (); - i <= keyTilesetScrollBar.getVisibleEnd (); ++i) - { - if (keyTilesetButtons[i]->mouseClick (x, y) - && keyTilesetButtons[i]->getEnabled ()) - { - string tilesetName = keyTilesetButtons[i]->getText (); - selectedTechName = ""; - selectedTilesetName = ""; - selectedMapName = ""; - selectedScenarioName = ""; - if (tilesetName != "") - { - selectedTilesetName = tilesetName; - bool remoteHasTileset = - (tilesetCacheList.find (tilesetName) != - tilesetCacheList.end ()); - if (remoteHasTileset) - { - showRemoteDesription (&tilesetCacheList[tilesetName]); - } - else - { - showLocalDescription (tilesetName); - } - } - break; - } - } - } - if (keyScenarioScrollBar.getElementCount () != 0) - { - for (int i = keyScenarioScrollBar.getVisibleStart (); - i <= keyScenarioScrollBar.getVisibleEnd (); ++i) - { - if (keyScenarioButtons[i]->mouseClick (x, y) - && keyScenarioButtons[i]->getEnabled ()) - { - string scenarioName = keyScenarioButtons[i]->getText (); - selectedTechName = ""; - selectedTilesetName = ""; - selectedMapName = ""; - selectedScenarioName = ""; - if (scenarioName != "") - { - selectedScenarioName = scenarioName; - bool remoteHasScenario = - (scenarioCacheList.find (scenarioName) != - scenarioCacheList.end ()); - if (remoteHasScenario) - { - showRemoteDesription (&scenarioCacheList[scenarioName]); - } - else - { - showLocalDescription (scenarioName); - } - - } - break; - } - } - } - - } - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - string MenuStateMods::getPreviewImageFileForMod (const ModInfo * modInfo) - { - string fileName = ""; - if (modInfo->imageUrl != "") - { - Config & config = Config::getInstance (); - string userData = config.getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - string tempPath = userData + "temp/"; - if (isdir (tempPath.c_str ()) == false) - { - createDirectoryPaths (tempPath); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("### tempPath [%s] isdir = %d\n", tempPath.c_str (), - isdir (tempPath.c_str ())); - - if (isdir (tempPath.c_str ()) == true) - { - fileName = tempPath; - switch (modInfo->type) - { - case mt_Map: - fileName += "map_"; - break; - case mt_Tileset: - fileName += "tileset_"; - break; - case mt_Techtree: - fileName += "tech_"; - break; - case mt_Scenario: - fileName += "scenario_"; - break; - } - fileName += extractFileFromDirectoryPath (modInfo->imageUrl); - } - } - return fileName; - } - - - void MenuStateMods::showLocalDescription (string name) - { - Lang & lang = Lang::getInstance (); - modInfoSelected = NULL; - cleanupPreviewTexture (); - validMapPreview = false; - cleanupMapPreviewTexture (); - modDescrLabel.setText (lang.getString ("ModOnlyLocal") + ":\n'" + name + - "'"); - } - - void MenuStateMods::loadMapPreview (string mapName) - { - Config & config = Config::getInstance (); - cleanupMapPreviewTexture (); - vector < string > mapPaths = config.getPathListForType (ptMaps); - string & mapPath = mapPaths[1]; - endPathWithSlash (mapPath); - mapPath += mapName; - MapInfo mapInfo = loadMapInfo (mapPath); - if (enableMapPreview == true) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - mapPreview.loadFromFile (mapPath.c_str ()); - - //printf("Loading map preview MAP\n"); - cleanupMapPreviewTexture (); - validMapPreview = true; - } - } - - - - void MenuStateMods::showRemoteDesription (ModInfo * modInfo) - { - //displayModPreviewImage = false; - modInfoSelected = modInfo; - validMapPreview = false; - cleanupMapPreviewTexture (); - - string modText = modInfo->description; - replaceAll (modText, "\\n", "\n"); - modDescrLabel.setText (modText); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("### modInfo->imageUrl [%s]\n", modInfo->imageUrl.c_str ()); - - if (modInfo->imageUrl != "") - { - cleanupPreviewTexture (); - string tempImage = getPreviewImageFileForMod (modInfo); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("### tempImage [%s] exists [%d]\n", tempImage.c_str (), - fileExists (tempImage)); - - if (tempImage != "" && fileExists (tempImage) == false) - { - if (ftpClientThread != NULL) - ftpClientThread->addFileToRequests (tempImage, modInfo->imageUrl); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()->setOwnerId (mutexOwnerId); - fileFTPProgressList[tempImage] = pair < int, string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - - } - else - { - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()->setOwnerId (mutexOwnerId); - if (fileFTPProgressList.find (tempImage) == - fileFTPProgressList.end ()) - { - //displayModPreviewImage = true; - displayModPreviewImage[tempImage] = true; - } - safeMutexFTPProgress.ReleaseLock (); - } - } - } - - void MenuStateMods::mouseUp (int x, int y, const MouseButton mouseButton) - { - if (mouseButton == mbLeft) - { - keyTechScrollBar.mouseUp (x, y); - keyTilesetScrollBar.mouseUp (x, y); - keyMapScrollBar.mouseUp (x, y); - keyScenarioScrollBar.mouseUp (x, y); - } - } - - void MenuStateMods::mouseMove (int x, int y, const MouseState * ms) - { - buttonReturn.mouseMove (x, y); - - if (mainMessageBox.getEnabled ()) - { - mainMessageBox.mouseMove (x, y); - } - - buttonInstallTech.mouseMove (x, y); - buttonRemoveTech.mouseMove (x, y); - buttonInstallTileset.mouseMove (x, y); - buttonRemoveTileset.mouseMove (x, y); - buttonInstallMap.mouseMove (x, y); - buttonRemoveMap.mouseMove (x, y); - buttonInstallScenario.mouseMove (x, y); - buttonRemoveScenario.mouseMove (x, y); - - if (ms->get (mbLeft)) - { - keyMapScrollBar.mouseDown (x, y); - keyTechScrollBar.mouseDown (x, y); - keyTilesetScrollBar.mouseDown (x, y); - keyScenarioScrollBar.mouseDown (x, y); - } - else - { - keyMapScrollBar.mouseMove (x, y); - keyTechScrollBar.mouseMove (x, y); - keyTilesetScrollBar.mouseMove (x, y); - keyScenarioScrollBar.mouseMove (x, y); - } - - if (keyMapScrollBar.getElementCount () != 0) - { - for (int i = keyMapScrollBar.getVisibleStart (); - i <= keyMapScrollBar.getVisibleEnd (); ++i) - { - keyMapButtons[i]->mouseMove (x, y); - } - } - if (keyTechScrollBar.getElementCount () != 0) - { - for (int i = keyTechScrollBar.getVisibleStart (); - i <= keyTechScrollBar.getVisibleEnd (); ++i) - { - keyTechButtons[i]->mouseMove (x, y); - } - } - if (keyTilesetScrollBar.getElementCount () != 0) - { - for (int i = keyTilesetScrollBar.getVisibleStart (); - i <= keyTilesetScrollBar.getVisibleEnd (); ++i) - { - keyTilesetButtons[i]->mouseMove (x, y); - } - } - if (keyScenarioScrollBar.getElementCount () != 0) - { - for (int i = keyScenarioScrollBar.getVisibleStart (); - i <= keyScenarioScrollBar.getVisibleEnd (); ++i) - { - keyScenarioButtons[i]->mouseMove (x, y); - } - } - } - - void MenuStateMods::cleanupPreviewTexture () - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] scenarioLogoTexture [%p]\n", __FILE__, - __FUNCTION__, __LINE__, modPreviewImage); - - if (modPreviewImage != NULL) - { - Renderer::getInstance ().endTexture (rsGlobal, modPreviewImage, - false); - } - modPreviewImage = NULL; - } - - void MenuStateMods::cleanupMapPreviewTexture () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - //printf("CLEANUP map preview texture\n"); - if (mapPreviewTexture != NULL) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - mapPreviewTexture->end (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - delete mapPreviewTexture; - mapPreviewTexture = NULL; - } - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } - - - void MenuStateMods::render () - { - try - { - Renderer & renderer = Renderer::getInstance (); - - renderer.renderLine (&lineHorizontal); - renderer.renderLine (&lineVertical); - renderer.renderLine (&lineReturn); - renderer.renderLine (&lineVerticalReturn); - renderer.renderButton (&buttonReturn); - - renderer.renderButton (&buttonInstallTech); - renderer.renderButton (&buttonRemoveTech); - renderer.renderButton (&buttonInstallTileset); - renderer.renderButton (&buttonRemoveTileset); - renderer.renderButton (&buttonInstallMap); - renderer.renderButton (&buttonRemoveMap); - renderer.renderButton (&buttonInstallScenario); - renderer.renderButton (&buttonRemoveScenario); - - renderer.renderButton (&buttonInstalled); - renderer.renderButton (&buttonAvailable); - renderer.renderButton (&buttonConflict); - renderer.renderButton (&buttonOnlyLocal); - - renderer.renderLabel (&modDescrLabel); - if (modInfoSelected != NULL) - { - string tempImage = getPreviewImageFileForMod (modInfoSelected); - if (displayModPreviewImage.find (tempImage) != - displayModPreviewImage.end () - && displayModPreviewImage[tempImage] == true) - { - if (modPreviewImage == NULL) - { - string tempImage = getPreviewImageFileForMod (modInfoSelected); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("### Render tempImage [%s] fileExists(tempImage) = %d\n", - tempImage.c_str (), fileExists (tempImage)); - - if (tempImage != "" && fileExists (tempImage) == true) - { - cleanupPreviewTexture (); - modPreviewImage = Renderer::findTexture (tempImage); - } - } - if (modPreviewImage != NULL) - { - renderer.renderTextureQuad (508, 90, 485, 325, modPreviewImage, - 1.0f); - } - } - } - - // Render Tech List - renderer.renderLabel (&keyTechScrollBarTitle1); - renderer.renderLabel (&keyTechScrollBarTitle2); - if (keyTechScrollBar.getElementCount () != 0) - { - for (int i = keyTechScrollBar.getVisibleStart (); - i <= keyTechScrollBar.getVisibleEnd (); ++i) - { - bool alreadyHasTech = - (std:: - find (techTreeFiles.begin (), techTreeFiles.end (), - keyTechButtons[i]->getText ()) != techTreeFiles.end ()); - if (keyTechButtons[i]->getText () == selectedTechName) - { - bool lightedOverride = true; - renderer.renderButton (keyTechButtons[i], &WHITE, - &lightedOverride); - } - else if (alreadyHasTech == true) - { - Vec4f buttonColor = WHITE; - buttonColor.w = 0.75f; - bool remoteHasTech = - (techCacheList.find (keyTechButtons[i]->getText ()) != - techCacheList.end ()); - if (remoteHasTech) - { - ModInfo & modInfo = - techCacheList[keyTechButtons[i]->getText ()]; - if (modInfo.crc == modInfo.localCRC) - { - keyTechButtons[i]-> - setCustomTexture (CoreData::getInstance (). - getOnServerInstalledTexture ()); - } - else - { - //printf("modInfo.name=%s modInfo.crc=%s modInfo.localCRC=%s\n",modInfo.name.c_str(),modInfo.crc.c_str(),modInfo.localCRC.c_str()); - keyTechButtons[i]-> - setCustomTexture (CoreData::getInstance (). - getOnServerDifferentTexture ()); - } - } - else - { - keyTechButtons[i]->setCustomTexture (CoreData::getInstance (). - getNotOnServerTexture - ()); - } - renderer.renderButton (keyTechButtons[i], &buttonColor); - } - else - { - Vec4f fontColor = - Vec4f (200.0f / 255.0f, 187.0f / 255.0f, 190.0f / 255.0f, - 0.75f); - //Vec4f fontColor=Vec4f(1.0f, 0.0f, 0.0f, 0.75f); - keyTechButtons[i]->setCustomTexture (CoreData::getInstance (). - getOnServerTexture ()); - renderer.renderButton (keyTechButtons[i], &fontColor); - } - renderer.renderLabel (labelsTech[i]); - } - } - renderer.renderScrollBar (&keyTechScrollBar); - - // Render Tileset List - renderer.renderLabel (&keyTilesetScrollBarTitle1); - if (keyTilesetScrollBar.getElementCount () != 0) - { - for (int i = keyTilesetScrollBar.getVisibleStart (); - i <= keyTilesetScrollBar.getVisibleEnd (); ++i) - { - bool alreadyHasTileset = - (std:: - find (tilesetFiles.begin (), tilesetFiles.end (), - keyTilesetButtons[i]->getText ()) != - tilesetFiles.end ()); - if (keyTilesetButtons[i]->getText () == selectedTilesetName) - { - bool lightedOverride = true; - renderer.renderButton (keyTilesetButtons[i], &WHITE, - &lightedOverride); - } - else if (alreadyHasTileset == true) - { - Vec4f buttonColor = WHITE; - buttonColor.w = 0.75f; - bool remoteHasTileset = - (tilesetCacheList.find (keyTilesetButtons[i]->getText ()) != - tilesetCacheList.end ()); - if (remoteHasTileset) - { - ModInfo & modInfo = - tilesetCacheList[keyTilesetButtons[i]->getText ()]; - - if (modInfo.crc == modInfo.localCRC) - { - keyTilesetButtons[i]-> - setCustomTexture (CoreData::getInstance (). - getOnServerInstalledTexture ()); - } - else - { - //printf("modInfo.name=%s modInfo.crc=%s modInfo.localCRC=%s\n",modInfo.name.c_str(),modInfo.crc.c_str(),modInfo.localCRC.c_str()); - //printf("name [%s] modInfo.crc [%s] modInfo.localCRC [%s]\n",modInfo.name.c_str(),modInfo.crc.c_str(),modInfo.localCRC.c_str()); - - keyTilesetButtons[i]-> - setCustomTexture (CoreData::getInstance (). - getOnServerDifferentTexture ()); - } - } - else - { - keyTilesetButtons[i]-> - setCustomTexture (CoreData::getInstance (). - getNotOnServerTexture ()); - } - renderer.renderButton (keyTilesetButtons[i], &buttonColor); - } - else - { - Vec4f fontColor = - Vec4f (200.0f / 255.0f, 187.0f / 255.0f, 190.0f / 255.0f, - 0.75f); - keyTilesetButtons[i]-> - setCustomTexture (CoreData::getInstance (). - getOnServerTexture ()); - renderer.renderButton (keyTilesetButtons[i], &fontColor); - } - } - } - renderer.renderScrollBar (&keyTilesetScrollBar); - - // Render Map list - renderer.renderLabel (&keyMapScrollBarTitle1); - renderer.renderLabel (&keyMapScrollBarTitle2); - if (keyMapScrollBar.getElementCount () != 0) - { - for (int i = keyMapScrollBar.getVisibleStart (); - i <= keyMapScrollBar.getVisibleEnd (); ++i) - { - string mapNameToRender = keyMapButtons[i]->getText (); - bool alreadyHasMap = - (std:: - find (mapFiles.begin (), mapFiles.end (), - mapNameToRender) != mapFiles.end ()); - if (keyMapButtons[i]->getText () == selectedMapName) - { - bool lightedOverride = true; - renderer.renderButton (keyMapButtons[i], &WHITE, - &lightedOverride); - } - else if (alreadyHasMap == true) - { - Vec4f buttonColor = WHITE; - buttonColor.w = 0.75f; - bool remoteHasMap = - (mapCacheList.find (keyMapButtons[i]->getText ()) != - mapCacheList.end ()); - if (remoteHasMap) - { - ModInfo & modInfo = - mapCacheList[keyMapButtons[i]->getText ()]; - if (modInfo.crc == modInfo.localCRC) - { - keyMapButtons[i]-> - setCustomTexture (CoreData::getInstance (). - getOnServerInstalledTexture ()); - } - else - { - //printf("modInfo.name=%s modInfo.crc=%s modInfo.localCRC=%s\n",modInfo.name.c_str(),modInfo.crc.c_str(),modInfo.localCRC.c_str()); - keyMapButtons[i]-> - setCustomTexture (CoreData::getInstance (). - getOnServerDifferentTexture ()); - } - } - else - { - keyMapButtons[i]->setCustomTexture (CoreData::getInstance (). - getNotOnServerTexture ()); - } - renderer.renderButton (keyMapButtons[i], &buttonColor); - } - else - { - Vec4f fontColor = - Vec4f (200.0f / 255.0f, 187.0f / 255.0f, 190.0f / 255.0f, - 0.75f); - keyMapButtons[i]->setCustomTexture (CoreData::getInstance (). - getOnServerTexture ()); - renderer.renderButton (keyMapButtons[i], &fontColor); - } - renderer.renderLabel (labelsMap[i]); - } - } - renderer.renderScrollBar (&keyMapScrollBar); - - // Render Scenario List - renderer.renderLabel (&keyScenarioScrollBarTitle1); - if (keyScenarioScrollBar.getElementCount () != 0) - { - for (int i = keyScenarioScrollBar.getVisibleStart (); - i <= keyScenarioScrollBar.getVisibleEnd (); ++i) - { - if (i >= (int) keyScenarioButtons.size ()) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "i >= keyScenarioButtons.size(), i = %d keyScenarioButtons.size() = %d", - i, (int) keyScenarioButtons.size ()); - throw megaglest_runtime_error (szBuf); - } - bool alreadyHasScenario = - (std:: - find (scenarioFiles.begin (), scenarioFiles.end (), - keyScenarioButtons[i]->getText ()) != - scenarioFiles.end ()); - - if (keyScenarioButtons[i]->getText () == selectedScenarioName) - { - bool lightedOverride = true; - renderer.renderButton (keyScenarioButtons[i], &WHITE, - &lightedOverride); - } - else if (alreadyHasScenario == true) - { - Vec4f buttonColor = WHITE; - buttonColor.w = 0.75f; - bool remoteHasScenario = - (scenarioCacheList.find (keyScenarioButtons[i]->getText ()) != - scenarioCacheList.end ()); - if (remoteHasScenario) - { - ModInfo & modInfo = - scenarioCacheList[keyScenarioButtons[i]->getText ()]; - if (modInfo.crc == modInfo.localCRC) - { - keyScenarioButtons[i]-> - setCustomTexture (CoreData::getInstance (). - getOnServerInstalledTexture ()); - } - else - { - //printf("modInfo.name=%s modInfo.crc=%s modInfo.localCRC=%s\n",modInfo.name.c_str(),modInfo.crc.c_str(),modInfo.localCRC.c_str()); - keyScenarioButtons[i]-> - setCustomTexture (CoreData::getInstance (). - getOnServerDifferentTexture ()); - } - } - else - { - keyScenarioButtons[i]-> - setCustomTexture (CoreData::getInstance (). - getNotOnServerTexture ()); - } - renderer.renderButton (keyScenarioButtons[i], &buttonColor); - } - else - { - Vec4f fontColor = - Vec4f (200.0f / 255.0f, 187.0f / 255.0f, 190.0f / 255.0f, - 0.75f); - keyScenarioButtons[i]-> - setCustomTexture (CoreData::getInstance (). - getOnServerTexture ()); - renderer.renderButton (keyScenarioButtons[i], &fontColor); - } - } - } - renderer.renderScrollBar (&keyScenarioScrollBar); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()->setOwnerId (mutexOwnerId); - if (fileFTPProgressList.empty () == false) - { - Lang & lang = Lang::getInstance (); - int xLocation = buttonReturn.getX (); - int yLocation = buttonReturn.getY () - 12; - for (std::map < string, pair < int, string > >::iterator iterMap = - fileFTPProgressList.begin (); - iterMap != fileFTPProgressList.end (); ++iterMap) - { - - string progressLabelPrefix = - lang.getString ("ModDownloading") + " " + - extractFileFromDirectoryPath (iterMap->first) + " "; - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nRendering file progress with the following prefix [%s]\n",progressLabelPrefix.c_str()); - - if (Renderer::renderText3DEnabled) - { - renderer.renderProgressBar3D (iterMap->second.first, - //10, - //yLocation, - xLocation, - yLocation, - CoreData::getInstance (). - getDisplayFontSmall3D (), 185, - progressLabelPrefix, false); - } - else - { - renderer.renderProgressBar (iterMap->second.first, - //10, - //yLocation, - xLocation, - yLocation, - CoreData::getInstance (). - getDisplayFontSmall (), 185, - progressLabelPrefix, false); - } - - yLocation -= 14; - } - } - safeMutexFTPProgress.ReleaseLock (); - - renderer.renderConsole (&console, consoleNormal, 3); - - if (mainMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&mainMessageBox); - } - - if (modMenuState != mmst_None) - { - if (oldMenuState != modMenuState) - { - Lang & lang = Lang::getInstance (); - if (modMenuState == mmst_Loading) - { - pleaseWaitLabel.setText (lang. - getString - ("GettingModlistFromMasterserver")); - } - else if (modMenuState == mmst_CalculatingCRC) - { - pleaseWaitLabel.setText (lang. - getString - ("PleaseWaitCalculatingCRC")); - } - oldMenuState = modMenuState; - } - float anim = GraphicComponent::getAnim (); - if (anim < 0.5f) - { - anim = 1.f - anim; - } - Vec4f colorWithAlpha = Vec4f (ORANGE.x, ORANGE.y, ORANGE.z, anim); - renderer.renderLabel (&pleaseWaitLabel, &colorWithAlpha); - } - if (validMapPreview) - { - if (mapPreviewTexture != NULL) - { - renderer.renderTextureQuad (5, 185, 150, 150, mapPreviewTexture, - 1.0f); - } - if (enableMapPreview && (mapPreview.hasFileLoaded () == true)) - { - - int mouseX = mainMenu->getMouseX (); - int mouseY = mainMenu->getMouseY (); - int mouse2dAnim = mainMenu->getMouse2dAnim (); - - if (mapPreviewTexture == NULL) - { - renderer.renderMouse2d (mouseX, mouseY, mouse2dAnim); - renderer.renderMapPreview (&mapPreview, true, 10, 350, - &mapPreviewTexture); - } - } - } - - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] error [%s]\n", __FILE__, - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw megaglest_runtime_error (szBuf); - } - } - - void MenuStateMods::update () - { - Chrono chrono; - chrono.start (); - - //Lang &lang= Lang::getInstance(); - - // Tech List - if (keyTechScrollBar.getElementCount () != 0) - { - for (int i = keyTechScrollBar.getVisibleStart (); - i <= keyTechScrollBar.getVisibleEnd (); ++i) - { - if (i >= (int) keyTechButtons.size ()) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "i >= keyTechButtons.size(), i = %d, keyTechButtons.size() = %d", - i, (int) keyTechButtons.size ()); - throw megaglest_runtime_error (szBuf); - } - - keyTechButtons[i]->setY (keyButtonsYBase - keyButtonsLineHeight * (i - - - keyTechScrollBar. - getVisibleStart - ())); - labelsTech[i]->setY (keyButtonsYBase - - keyButtonsLineHeight * (i - - keyTechScrollBar. - getVisibleStart ())); - } - } - - // Tileset List - if (keyTilesetScrollBar.getElementCount () != 0) - { - for (int i = keyTilesetScrollBar.getVisibleStart (); - i <= keyTilesetScrollBar.getVisibleEnd (); ++i) - { - if (i >= (int) keyTilesetButtons.size ()) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "i >= keyTilesetButtons.size(), i = %d, keyTilesetButtons.size() = %d", - i, (int) keyTilesetButtons.size ()); - throw megaglest_runtime_error (szBuf); - } - - int yPos = keyButtonsYBase - keyButtonsLineHeight * - (i - keyTilesetScrollBar.getVisibleStart ()); - keyTilesetButtons[i]->setY (yPos); - } - } - - // Map List - if (keyMapScrollBar.getElementCount () != 0) - { - for (int i = keyMapScrollBar.getVisibleStart (); - i <= keyMapScrollBar.getVisibleEnd (); ++i) - { - if (i >= (int) keyMapButtons.size ()) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "i >= keyMapButtons.size(), i = %d, keyMapButtons.size() = %d", - i, (int) keyMapButtons.size ()); - throw megaglest_runtime_error (szBuf); - } - - keyMapButtons[i]->setY (keyButtonsYBase - keyButtonsLineHeight * (i - - - keyMapScrollBar. - getVisibleStart - ())); - labelsMap[i]->setY (keyButtonsYBase - - keyButtonsLineHeight * (i - - keyMapScrollBar. - getVisibleStart ())); - } - } - - // Scenario List - if (keyScenarioScrollBar.getElementCount () != 0) - { - for (int i = keyScenarioScrollBar.getVisibleStart (); - i <= keyScenarioScrollBar.getVisibleEnd (); ++i) - { - if (i >= (int) keyScenarioButtons.size ()) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "i >= keyScenarioButtons.size(), i = %d, keyScenarioButtons.size() = %d", - i, (int) keyScenarioButtons.size ()); - throw megaglest_runtime_error (szBuf); - } - - int yPos = keyButtonsYBase - keyButtonsLineHeight * - (i - keyScenarioScrollBar.getVisibleStart ()); - keyScenarioButtons[i]->setY (yPos); - } - } - - console.update (); - } - - void MenuStateMods::keyDown (SDL_KeyboardEvent key) - { - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - //if(key == configKeys.getCharKey("ShowFullConsole")) { - if (isKeyPressed (configKeys.getSDLKey ("ShowFullConsole"), key) == - true) - { - showFullConsole = true; - } - } - - void MenuStateMods::keyPress (SDL_KeyboardEvent c) - { - } - - void MenuStateMods::keyUp (SDL_KeyboardEvent key) - { - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - //if(key== configKeys.getCharKey("ShowFullConsole")) { - if (isKeyPressed (configKeys.getSDLKey ("ShowFullConsole"), key) == - true) - { - showFullConsole = false; - } - } - - void MenuStateMods::showMessageBox (const string & text, - const string & header, bool toggle) - { - if (toggle == false) - { - mainMessageBox.setEnabled (false); - } - - if (mainMessageBox.getEnabled () == false) - { - mainMessageBox.setText (text); - mainMessageBox.setHeader (header); - mainMessageBox.setEnabled (true); - } - else - { - mainMessageBox.setEnabled (false); - } - } - - void MenuStateMods::FTPClient_CallbackEvent (string itemName, - FTP_Client_CallbackType type, - pair < FTP_Client_ResultType, - string > result, - void *userdata) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - Lang & lang = Lang::getInstance (); - if (type == ftp_cct_DownloadProgress) - { - FTPClientCallbackInterface::FtpProgressStats * stats = - (FTPClientCallbackInterface::FtpProgressStats *) userdata; - if (stats != NULL) - { - int fileProgress = 0; - if (stats->download_total > 0) - { - fileProgress = - ((stats->download_now / stats->download_total) * 100.0); - } - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP Callback for [%s] current file [%s] fileProgress = %d [now = %f, total = %f]\n",itemName.c_str(),stats->currentFilename.c_str(), fileProgress,stats->download_now,stats->download_total); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()->setOwnerId (mutexOwnerId); - pair < int, string > lastProgress = fileFTPProgressList[itemName]; - fileFTPProgressList[itemName] = - pair < int, string > (fileProgress, stats->currentFilename); - safeMutexFTPProgress.ReleaseLock (); - } - } - else if (type == ftp_cct_ExtractProgress) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Got FTP extract Callback for [%s] result = %d [%s]\n", - itemName.c_str (), result.first, result.second.c_str ()); - //printf("Got FTP extract Callback for [%s] result = %d [%s]\n",itemName.c_str(),result.first,result.second.c_str()); - - if (userdata == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("DataMissingExtractDownloadMod").c_str (), - itemName.c_str ()); - //printf("%s\n",szBuf); - console.addLine (szBuf, true); - } - else - { - char *szBuf = (char *) userdata; - //printf("%s\n",szBuf); - console.addLine (szBuf); - } - } - else if (type == ftp_cct_File) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Got FTP Callback for [%s] result = %d [%s]\n", - itemName.c_str (), result.first, result.second.c_str ()); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()->setOwnerId (mutexOwnerId); - fileFTPProgressList.erase (itemName); - safeMutexFTPProgress.ReleaseLock (); - - //printf("### downloaded file [%s] result = %d\n",itemName.c_str(),result.first); - - if (result.first == ftp_crt_SUCCESS) - { - displayModPreviewImage[itemName] = true; - } - } - - else if (type == ftp_cct_Map) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Got FTP Callback for [%s] result = %d [%s]\n", - itemName.c_str (), result.first, result.second.c_str ()); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()->setOwnerId (mutexOwnerId); - fileFTPProgressList.erase (itemName); - safeMutexFTPProgress.ReleaseLock (); - selectedMapName = ""; - buttonInstallMap.setEnabled (true); - - if (result.first == ftp_crt_SUCCESS) - { - refreshMaps (); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModDownloadMapSuccess").c_str (), - itemName.c_str ()); - console.addLine (szBuf, true); - } - else - { - curl_version_info_data *curlVersion = - curl_version_info (CURLVERSION_NOW); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModDownloadMapFail").c_str (), - itemName.c_str (), curlVersion->version, - result.second.c_str ()); - console.addLine (szBuf, true); - } - } - else if (type == ftp_cct_Tileset) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Got FTP Callback for [%s] result = %d [%s]\n", - itemName.c_str (), result.first, result.second.c_str ()); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()->setOwnerId (mutexOwnerId); - fileFTPProgressList.erase (itemName); - safeMutexFTPProgress.ReleaseLock (true); - - selectedTilesetName = ""; - buttonInstallTileset.setEnabled (true); - - if (result.first == ftp_crt_SUCCESS) - { - refreshTilesets (); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModDownloadTilesetSuccess").c_str (), - itemName.c_str ()); - console.addLine (szBuf, true); - // END - } - else - { - curl_version_info_data *curlVersion = - curl_version_info (CURLVERSION_NOW); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModDownloadTilesetFail").c_str (), - itemName.c_str (), curlVersion->version, - result.second.c_str ()); - console.addLine (szBuf, true); - } - } - else if (type == ftp_cct_Techtree) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Got FTP Callback for [%s] result = %d [%s]\n", - itemName.c_str (), result.first, result.second.c_str ()); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()->setOwnerId (mutexOwnerId); - fileFTPProgressList.erase (itemName); - safeMutexFTPProgress.ReleaseLock (true); - - selectedTechName = ""; - buttonInstallTech.setEnabled (true); - - if (result.first == ftp_crt_SUCCESS) - { - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModDownloadTechSuccess").c_str (), - itemName.c_str ()); - console.addLine (szBuf, true); - - // START - // Clear the CRC Cache if it is populated - safeMutexFTPProgress.Lock (); - Checksum::clearFileCache (); - - vector < string > paths = - Config::getInstance ().getPathListForType (ptTechs); - string pathSearchString = string ("/") + itemName + string ("/*"); - const string filterFileExt = ".xml"; - clearFolderTreeContentsCheckSum (paths, pathSearchString, - filterFileExt); - clearFolderTreeContentsCheckSumList (paths, pathSearchString, - filterFileExt); - - // Refresh CRC - Config & config = Config::getInstance (); - getFolderTreeContentsCheckSumRecursively (config. - getPathListForType - (ptTechs, ""), - string ("/") + itemName + - string ("/*"), ".xml", - NULL, true); - safeMutexFTPProgress.ReleaseLock (); - - refreshTechs (); - // END - } - else - { - curl_version_info_data *curlVersion = - curl_version_info (CURLVERSION_NOW); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModDownloadTechFail").c_str (), - itemName.c_str (), curlVersion->version, - result.second.c_str ()); - console.addLine (szBuf, true); - } - } - else if (type == ftp_cct_Scenario) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Got FTP Callback for [%s] result = %d [%s]\n", - itemName.c_str (), result.first, result.second.c_str ()); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()->setOwnerId (mutexOwnerId); - fileFTPProgressList.erase (itemName); - safeMutexFTPProgress.ReleaseLock (true); - - selectedScenarioName = ""; - buttonInstallScenario.setEnabled (true); - - if (result.first == ftp_crt_SUCCESS) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModDownloadScenarioSuccess").c_str (), - itemName.c_str ()); - console.addLine (szBuf, true); - - // START - // Clear the CRC Cache if it is populated - // - // Clear the CRC file Cache - safeMutexFTPProgress.Lock (); - Checksum::clearFileCache (); - - vector < string > paths = - Config::getInstance ().getPathListForType (ptScenarios); - string pathSearchString = string ("/") + itemName + string ("/*"); - const string filterFileExt = ".xml"; - clearFolderTreeContentsCheckSum (paths, pathSearchString, - filterFileExt); - clearFolderTreeContentsCheckSumList (paths, pathSearchString, - filterFileExt); - - // Refresh CRC - Config & config = Config::getInstance (); - getFolderTreeContentsCheckSumRecursively (config. - getPathListForType - (ptScenarios, ""), - string ("/") + itemName + - string ("/*"), ".xml", - NULL, true); - safeMutexFTPProgress.ReleaseLock (); - - refreshScenarios (); - // END - } - else - { - curl_version_info_data *curlVersion = - curl_version_info (CURLVERSION_NOW); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("ModDownloadScenarioFail").c_str (), - itemName.c_str (), curlVersion->version, - result.second.c_str ()); - console.addLine (szBuf, true); - } - } - - } - -}} //end namespace +} //end namespace diff --git a/source/glest_game/menu/menu_state_mods.h b/source/glest_game/menu/menu_state_mods.h index a83d2f29b..6d137fe54 100644 --- a/source/glest_game/menu/menu_state_mods.h +++ b/source/glest_game/menu/menu_state_mods.h @@ -19,212 +19,208 @@ # include # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - enum FTPMessageType - { - ftpmsg_None, - ftpmsg_GetMap, - ftpmsg_GetTileset, - ftpmsg_GetTechtree, - ftpmsg_GetScenario, + enum FTPMessageType { + ftpmsg_None, + ftpmsg_GetMap, + ftpmsg_GetTileset, + ftpmsg_GetTechtree, + ftpmsg_GetScenario, - ftpmsg_ReplaceMap, - ftpmsg_ReplaceTileset, - ftpmsg_ReplaceTechtree, - ftpmsg_ReplaceScenario, + ftpmsg_ReplaceMap, + ftpmsg_ReplaceTileset, + ftpmsg_ReplaceTechtree, + ftpmsg_ReplaceScenario, - ftpmsg_Quit - }; + ftpmsg_Quit + }; - enum ModMenuState - { - mmst_None, - mmst_Loading, - mmst_CalculatingCRC - }; + enum ModMenuState { + mmst_None, + mmst_Loading, + mmst_CalculatingCRC + }; - typedef vector < GraphicButton * >UserButtons; - typedef vector < GraphicLabel * >GraphicLabels; + typedef vector < GraphicButton * >UserButtons; + typedef vector < GraphicLabel * >GraphicLabels; -// =============================== -// class MenuStateMods -// =============================== - class MenuStateMods:public MenuState, public FTPClientCallbackInterface, - public SimpleTaskCallbackInterface - { - private: + // =============================== + // class MenuStateMods + // =============================== + class MenuStateMods :public MenuState, public FTPClientCallbackInterface, + public SimpleTaskCallbackInterface { + private: - GraphicButton buttonReturn; - GraphicLine lineHorizontal; - GraphicLine lineVertical; - GraphicLine lineReturn; - GraphicLine lineVerticalReturn; + GraphicButton buttonReturn; + GraphicLine lineHorizontal; + GraphicLine lineVertical; + GraphicLine lineReturn; + GraphicLine lineVerticalReturn; - GraphicMessageBox mainMessageBox; - FTPMessageType mainMessageBoxState; + GraphicMessageBox mainMessageBox; + FTPMessageType mainMessageBoxState; - int techInfoXPos; - int mapInfoXPos; - int tilesetInfoXPos; - int scenarioInfoXPos; - int labelWidth; - int scrollListsYPos; - int listBoxLength; + int techInfoXPos; + int mapInfoXPos; + int tilesetInfoXPos; + int scenarioInfoXPos; + int labelWidth; + int scrollListsYPos; + int listBoxLength; - GraphicButton buttonInstallTech; - GraphicButton buttonRemoveTech; - GraphicLabel keyTechScrollBarTitle1; - GraphicLabel keyTechScrollBarTitle2; - GraphicScrollBar keyTechScrollBar; - UserButtons keyTechButtons; - GraphicLabels labelsTech; + GraphicButton buttonInstallTech; + GraphicButton buttonRemoveTech; + GraphicLabel keyTechScrollBarTitle1; + GraphicLabel keyTechScrollBarTitle2; + GraphicScrollBar keyTechScrollBar; + UserButtons keyTechButtons; + GraphicLabels labelsTech; - GraphicButton buttonInstallTileset; - GraphicButton buttonRemoveTileset; - GraphicLabel keyTilesetScrollBarTitle1; - GraphicScrollBar keyTilesetScrollBar; - UserButtons keyTilesetButtons; + GraphicButton buttonInstallTileset; + GraphicButton buttonRemoveTileset; + GraphicLabel keyTilesetScrollBarTitle1; + GraphicScrollBar keyTilesetScrollBar; + UserButtons keyTilesetButtons; - GraphicButton buttonInstallMap; - GraphicButton buttonRemoveMap; - GraphicLabel keyMapScrollBarTitle1; - GraphicLabel keyMapScrollBarTitle2; - GraphicScrollBar keyMapScrollBar; - UserButtons keyMapButtons; - GraphicLabels labelsMap; + GraphicButton buttonInstallMap; + GraphicButton buttonRemoveMap; + GraphicLabel keyMapScrollBarTitle1; + GraphicLabel keyMapScrollBarTitle2; + GraphicScrollBar keyMapScrollBar; + UserButtons keyMapButtons; + GraphicLabels labelsMap; - GraphicButton buttonInstallScenario; - GraphicButton buttonRemoveScenario; - GraphicLabel keyScenarioScrollBarTitle1; - GraphicLabel keyScenarioScrollBarTitle2; - GraphicScrollBar keyScenarioScrollBar; - UserButtons keyScenarioButtons; + GraphicButton buttonInstallScenario; + GraphicButton buttonRemoveScenario; + GraphicLabel keyScenarioScrollBarTitle1; + GraphicLabel keyScenarioScrollBarTitle2; + GraphicScrollBar keyScenarioScrollBar; + UserButtons keyScenarioButtons; - GraphicLabel modDescrLabel; - Texture2D *modPreviewImage; - ModInfo *modInfoSelected; - map < string, bool > displayModPreviewImage; + GraphicLabel modDescrLabel; + Texture2D *modPreviewImage; + ModInfo *modInfoSelected; + map < string, bool > displayModPreviewImage; - GraphicButton buttonInstalled; - GraphicButton buttonAvailable; - GraphicButton buttonConflict; - GraphicButton buttonOnlyLocal; + GraphicButton buttonInstalled; + GraphicButton buttonAvailable; + GraphicButton buttonConflict; + GraphicButton buttonOnlyLocal; - GraphicLabel pleaseWaitLabel; - ModMenuState modMenuState; - ModMenuState oldMenuState; + GraphicLabel pleaseWaitLabel; + ModMenuState modMenuState; + ModMenuState oldMenuState; - bool enableMapPreview; - bool validMapPreview; - MapInfo mapInfo; - MapPreview mapPreview; - Texture2D *mapPreviewTexture; + bool enableMapPreview; + bool validMapPreview; + MapInfo mapInfo; + MapPreview mapPreview; + Texture2D *mapPreviewTexture; - int keyButtonsToRender; - int keyButtonsYBase; - int keyButtonsXBase; - int keyButtonsLineHeight; - int keyButtonsHeight; - int keyButtonsWidth; - int keyButtonsWidthTech; - int keyButtonsWidthMap; - int keyButtonsWidthTil; - int keyButtonsWidthScen; + int keyButtonsToRender; + int keyButtonsYBase; + int keyButtonsXBase; + int keyButtonsLineHeight; + int keyButtonsHeight; + int keyButtonsWidth; + int keyButtonsWidthTech; + int keyButtonsWidthMap; + int keyButtonsWidthTil; + int keyButtonsWidthScen; - //Console console; - bool showFullConsole; + //Console console; + bool showFullConsole; - string selectedTechName; - std::vector < std::string > techListRemote; - std::map < string, ModInfo > techCacheList; - vector < string > techTreeFiles; - vector < string > techTreeFilesUserData; + string selectedTechName; + std::vector < std::string > techListRemote; + std::map < string, ModInfo > techCacheList; + vector < string > techTreeFiles; + vector < string > techTreeFilesUserData; - string selectedTilesetName; - std::vector < std::string > tilesetListRemote; - std::map < string, ModInfo > tilesetCacheList; - vector < string > tilesetFiles; - vector < string > tilesetFilesUserData; + string selectedTilesetName; + std::vector < std::string > tilesetListRemote; + std::map < string, ModInfo > tilesetCacheList; + vector < string > tilesetFiles; + vector < string > tilesetFilesUserData; - string selectedMapName; - std::vector < std::string > mapListRemote; - std::map < string, ModInfo > mapCacheList; - vector < string > mapFiles; - vector < string > mapFilesUserData; + string selectedMapName; + std::vector < std::string > mapListRemote; + std::map < string, ModInfo > mapCacheList; + vector < string > mapFiles; + vector < string > mapFilesUserData; - string selectedScenarioName; - std::vector < std::string > scenarioListRemote; - std::map < string, ModInfo > scenarioCacheList; - vector < string > scenarioFiles; - vector < string > scenarioFilesUserData; + string selectedScenarioName; + std::vector < std::string > scenarioListRemote; + std::map < string, ModInfo > scenarioCacheList; + vector < string > scenarioFiles; + vector < string > scenarioFilesUserData; - FTPClientThread *ftpClientThread; - std::map < string, pair < int, string > >fileFTPProgressList; + FTPClientThread *ftpClientThread; + std::map < string, pair < int, string > >fileFTPProgressList; - SimpleTaskThread *modHttpServerThread; + SimpleTaskThread *modHttpServerThread; - void getTechsLocalList (); - string refreshTechModInfo (string techInfo); - void refreshTechs (); + void getTechsLocalList(); + string refreshTechModInfo(string techInfo); + void refreshTechs(); - void getTilesetsLocalList (); - string refreshTilesetModInfo (string tilesetInfo); - void refreshTilesets (); + void getTilesetsLocalList(); + string refreshTilesetModInfo(string tilesetInfo); + void refreshTilesets(); - void getMapsLocalList (); - string refreshMapModInfo (string mapInfo); - void refreshMaps (); - string getMapCRC (string mapName); + void getMapsLocalList(); + string refreshMapModInfo(string mapInfo); + void refreshMaps(); + string getMapCRC(string mapName); - void getScenariosLocalList (); - string refreshScenarioModInfo (string scenarioInfo); - void refreshScenarios (); + void getScenariosLocalList(); + string refreshScenarioModInfo(string scenarioInfo); + void refreshScenarios(); - void showLocalDescription (string name); - void loadMapPreview (string name); - void showRemoteDesription (ModInfo * modInfo); + void showLocalDescription(string name); + void loadMapPreview(string name); + void showRemoteDesription(ModInfo * modInfo); - std::map < string, bool > mapCRCUpdateList; - public: + std::map < string, bool > mapCRCUpdateList; + public: - MenuStateMods (Program * program, MainMenu * mainMenu); - virtual ~ MenuStateMods (); + MenuStateMods(Program * program, MainMenu * mainMenu); + virtual ~MenuStateMods(); - void mouseClick (int x, int y, MouseButton mouseButton); - void mouseUp (int x, int y, const MouseButton mouseButton); - void mouseMove (int x, int y, const MouseState * mouseState); - void render (); - void update (); + void mouseClick(int x, int y, MouseButton mouseButton); + void mouseUp(int x, int y, const MouseButton mouseButton); + void mouseMove(int x, int y, const MouseState * mouseState); + void render(); + void update(); - virtual void keyDown (SDL_KeyboardEvent key); - virtual void keyPress (SDL_KeyboardEvent c); - virtual void keyUp (SDL_KeyboardEvent key); + virtual void keyDown(SDL_KeyboardEvent key); + virtual void keyPress(SDL_KeyboardEvent c); + virtual void keyUp(SDL_KeyboardEvent key); - virtual void simpleTask (BaseThread * callingThread, void *userdata); + virtual void simpleTask(BaseThread * callingThread, void *userdata); - virtual void reloadUI (); + virtual void reloadUI(); - private: + private: - void cleanUp (); - MapInfo loadMapInfo (string file); - void showMessageBox (const string & text, const string & header, - bool toggle); - void clearUserButtons (); - virtual void FTPClient_CallbackEvent (string itemName, - FTP_Client_CallbackType type, - pair < FTP_Client_ResultType, - string > result, void *userdata); + void cleanUp(); + MapInfo loadMapInfo(string file); + void showMessageBox(const string & text, const string & header, + bool toggle); + void clearUserButtons(); + virtual void FTPClient_CallbackEvent(string itemName, + FTP_Client_CallbackType type, + pair < FTP_Client_ResultType, + string > result, void *userdata); - string getPreviewImageFileForMod (const ModInfo * modInfo); - void cleanupPreviewTexture (); - void cleanupMapPreviewTexture (); - }; + string getPreviewImageFileForMod(const ModInfo * modInfo); + void cleanupPreviewTexture(); + void cleanupMapPreviewTexture(); + }; -}} //end namespace + } +} //end namespace #endif /* MENU_STATE_MODS_H_ */ diff --git a/source/glest_game/menu/menu_state_new_game.cpp b/source/glest_game/menu/menu_state_new_game.cpp index 6d430fb12..2804090f0 100644 --- a/source/glest_game/menu/menu_state_new_game.cpp +++ b/source/glest_game/menu/menu_state_new_game.cpp @@ -28,169 +28,147 @@ #include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class MenuStateNewGame -// ===================================================== + // ===================================================== + // class MenuStateNewGame + // ===================================================== - MenuStateNewGame::MenuStateNewGame (Program * program, - MainMenu * - mainMenu):MenuState (program, - mainMenu, "root") - { - containerName = "NewGame"; - Lang & lang = Lang::getInstance (); + MenuStateNewGame::MenuStateNewGame(Program * program, + MainMenu * + mainMenu) :MenuState(program, + mainMenu, "root") { + containerName = "NewGame"; + Lang & lang = Lang::getInstance(); - int buttonWidth = 200; - int buttonXPosition = (1000 - buttonWidth) / 2; - int yPos = 465; - buttonTutorial.registerGraphicComponent (containerName, - "buttonTutorial"); - buttonTutorial.init (buttonXPosition, yPos, buttonWidth); - yPos -= 40; - buttonScenario.registerGraphicComponent (containerName, - "buttonScenario"); - buttonScenario.init (buttonXPosition, yPos, buttonWidth); - yPos -= 40; - buttonCustomGame.registerGraphicComponent (containerName, - "buttonCustomGame"); - buttonCustomGame.init (buttonXPosition, yPos, buttonWidth); - yPos -= 40; - buttonMasterserverGame.registerGraphicComponent (containerName, - "buttonMasterserverGame"); - buttonMasterserverGame.init (buttonXPosition, yPos, buttonWidth); - yPos -= 40; - buttonJoinGame.registerGraphicComponent (containerName, - "buttonJoinGame"); - buttonJoinGame.init (buttonXPosition, yPos, buttonWidth); - yPos -= 40; - buttonReturn.registerGraphicComponent (containerName, "buttonReturn"); - buttonReturn.init (buttonXPosition, yPos, buttonWidth); + int buttonWidth = 200; + int buttonXPosition = (1000 - buttonWidth) / 2; + int yPos = 465; + buttonTutorial.registerGraphicComponent(containerName, + "buttonTutorial"); + buttonTutorial.init(buttonXPosition, yPos, buttonWidth); + yPos -= 40; + buttonScenario.registerGraphicComponent(containerName, + "buttonScenario"); + buttonScenario.init(buttonXPosition, yPos, buttonWidth); + yPos -= 40; + buttonCustomGame.registerGraphicComponent(containerName, + "buttonCustomGame"); + buttonCustomGame.init(buttonXPosition, yPos, buttonWidth); + yPos -= 40; + buttonMasterserverGame.registerGraphicComponent(containerName, + "buttonMasterserverGame"); + buttonMasterserverGame.init(buttonXPosition, yPos, buttonWidth); + yPos -= 40; + buttonJoinGame.registerGraphicComponent(containerName, + "buttonJoinGame"); + buttonJoinGame.init(buttonXPosition, yPos, buttonWidth); + yPos -= 40; + buttonReturn.registerGraphicComponent(containerName, "buttonReturn"); + buttonReturn.init(buttonXPosition, yPos, buttonWidth); - buttonCustomGame.setText (lang.getString ("CustomGame")); - buttonScenario.setText (lang.getString ("Scenario")); - buttonJoinGame.setText (lang.getString ("JoinGame")); - buttonMasterserverGame.setText (lang.getString ("JoinInternetGame")); - buttonTutorial.setText (lang.getString ("Tutorial")); - buttonReturn.setText (lang.getString ("Return")); + buttonCustomGame.setText(lang.getString("CustomGame")); + buttonScenario.setText(lang.getString("Scenario")); + buttonJoinGame.setText(lang.getString("JoinGame")); + buttonMasterserverGame.setText(lang.getString("JoinInternetGame")); + buttonTutorial.setText(lang.getString("Tutorial")); + buttonReturn.setText(lang.getString("Return")); - GraphicComponent::applyAllCustomProperties (containerName); + GraphicComponent::applyAllCustomProperties(containerName); - NetworkManager::getInstance ().end (); - } + NetworkManager::getInstance().end(); + } - void MenuStateNewGame::reloadUI () - { - Lang & lang = Lang::getInstance (); + void MenuStateNewGame::reloadUI() { + Lang & lang = Lang::getInstance(); - buttonCustomGame.setText (lang.getString ("CustomGame")); - buttonScenario.setText (lang.getString ("Scenario")); - buttonJoinGame.setText (lang.getString ("JoinGame")); - buttonMasterserverGame.setText (lang.getString ("JoinInternetGame")); - buttonTutorial.setText (lang.getString ("Tutorial")); - buttonReturn.setText (lang.getString ("Return")); + buttonCustomGame.setText(lang.getString("CustomGame")); + buttonScenario.setText(lang.getString("Scenario")); + buttonJoinGame.setText(lang.getString("JoinGame")); + buttonMasterserverGame.setText(lang.getString("JoinInternetGame")); + buttonTutorial.setText(lang.getString("Tutorial")); + buttonReturn.setText(lang.getString("Return")); - GraphicComponent:: - reloadFontsForRegisterGraphicComponents (containerName); - } + GraphicComponent:: + reloadFontsForRegisterGraphicComponents(containerName); + } - void MenuStateNewGame::mouseClick (int x, int y, MouseButton mouseButton) - { + void MenuStateNewGame::mouseClick(int x, int y, MouseButton mouseButton) { - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); - if (buttonCustomGame.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - mainMenu->setState (new MenuStateCustomGame (program, mainMenu)); - } - else if (buttonScenario.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - mainMenu->setState (new MenuStateScenario (program, mainMenu, false, - Config::getInstance (). - getPathListForType - (ptScenarios))); - } - else if (buttonJoinGame.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - mainMenu->setState (new MenuStateJoinGame (program, mainMenu)); - } - else if (buttonMasterserverGame.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - mainMenu->setState (new MenuStateMasterserver (program, mainMenu)); - } - else if (buttonTutorial.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - mainMenu->setState (new MenuStateScenario (program, mainMenu, true, - Config::getInstance (). - getPathListForType - (ptTutorials))); - } - else if (buttonReturn.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - mainMenu->setState (new MenuStateRoot (program, mainMenu)); - } - } + if (buttonCustomGame.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundB()); + mainMenu->setState(new MenuStateCustomGame(program, mainMenu)); + } else if (buttonScenario.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundB()); + mainMenu->setState(new MenuStateScenario(program, mainMenu, false, + Config::getInstance(). + getPathListForType + (ptScenarios))); + } else if (buttonJoinGame.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundB()); + mainMenu->setState(new MenuStateJoinGame(program, mainMenu)); + } else if (buttonMasterserverGame.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundB()); + mainMenu->setState(new MenuStateMasterserver(program, mainMenu)); + } else if (buttonTutorial.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundB()); + mainMenu->setState(new MenuStateScenario(program, mainMenu, true, + Config::getInstance(). + getPathListForType + (ptTutorials))); + } else if (buttonReturn.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundB()); + mainMenu->setState(new MenuStateRoot(program, mainMenu)); + } + } - void MenuStateNewGame::mouseMove (int x, int y, const MouseState * ms) - { - buttonCustomGame.mouseMove (x, y); - buttonScenario.mouseMove (x, y); - buttonJoinGame.mouseMove (x, y); - buttonMasterserverGame.mouseMove (x, y); - buttonTutorial.mouseMove (x, y); - buttonReturn.mouseMove (x, y); - } + void MenuStateNewGame::mouseMove(int x, int y, const MouseState * ms) { + buttonCustomGame.mouseMove(x, y); + buttonScenario.mouseMove(x, y); + buttonJoinGame.mouseMove(x, y); + buttonMasterserverGame.mouseMove(x, y); + buttonTutorial.mouseMove(x, y); + buttonReturn.mouseMove(x, y); + } - void MenuStateNewGame::render () - { - Renderer & renderer = Renderer::getInstance (); + void MenuStateNewGame::render() { + Renderer & renderer = Renderer::getInstance(); - renderer.renderButton (&buttonCustomGame); - renderer.renderButton (&buttonScenario); - renderer.renderButton (&buttonJoinGame); - renderer.renderButton (&buttonMasterserverGame); - renderer.renderButton (&buttonTutorial); - renderer.renderButton (&buttonReturn); + renderer.renderButton(&buttonCustomGame); + renderer.renderButton(&buttonScenario); + renderer.renderButton(&buttonJoinGame); + renderer.renderButton(&buttonMasterserverGame); + renderer.renderButton(&buttonTutorial); + renderer.renderButton(&buttonReturn); - renderer.renderConsole (&console); - if (program != NULL) - program->renderProgramMsgBox (); - } + renderer.renderConsole(&console); + if (program != NULL) + program->renderProgramMsgBox(); + } - void MenuStateNewGame::update () - { - if (Config::getInstance ().getBool ("AutoTest")) - { - AutoTest::getInstance ().updateNewGame (program, mainMenu); - return; - } - console.update (); - } + void MenuStateNewGame::update() { + if (Config::getInstance().getBool("AutoTest")) { + AutoTest::getInstance().updateNewGame(program, mainMenu); + return; + } + console.update(); + } - void MenuStateNewGame::keyDown (SDL_KeyboardEvent key) - { - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - //if(key == configKeys.getCharKey("SaveGUILayout")) { - if (isKeyPressed (configKeys.getSDLKey ("SaveGUILayout"), key) == true) - { - GraphicComponent::saveAllCustomProperties (containerName); - //Lang &lang= Lang::getInstance(); - //console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ? lang.getString("Yes") : lang.getString("No"))+ "]"); - } - } + void MenuStateNewGame::keyDown(SDL_KeyboardEvent key) { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + //if(key == configKeys.getCharKey("SaveGUILayout")) { + if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), key) == true) { + GraphicComponent::saveAllCustomProperties(containerName); + //Lang &lang= Lang::getInstance(); + //console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ? lang.getString("Yes") : lang.getString("No"))+ "]"); + } + } - } + } } //end namespace diff --git a/source/glest_game/menu/menu_state_new_game.h b/source/glest_game/menu/menu_state_new_game.h index 71fe59c4a..42498d099 100644 --- a/source/glest_game/menu/menu_state_new_game.h +++ b/source/glest_game/menu/menu_state_new_game.h @@ -15,38 +15,36 @@ # include "main_menu.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// =============================== -// class MenuStateNewGame -// =============================== + // =============================== + // class MenuStateNewGame + // =============================== - class MenuStateNewGame:public MenuState - { - private: - GraphicButton buttonCustomGame; - GraphicButton buttonScenario; - GraphicButton buttonJoinGame; - GraphicButton buttonMasterserverGame; - GraphicButton buttonTutorial; - GraphicButton buttonReturn; + class MenuStateNewGame :public MenuState { + private: + GraphicButton buttonCustomGame; + GraphicButton buttonScenario; + GraphicButton buttonJoinGame; + GraphicButton buttonMasterserverGame; + GraphicButton buttonTutorial; + GraphicButton buttonReturn; - public: - MenuStateNewGame (Program * program, MainMenu * mainMenu); + public: + MenuStateNewGame(Program * program, MainMenu * mainMenu); - void mouseClick (int x, int y, MouseButton mouseButton); - void mouseMove (int x, int y, const MouseState * mouseState); - void update (); - void render (); - virtual void keyDown (SDL_KeyboardEvent key); + void mouseClick(int x, int y, MouseButton mouseButton); + void mouseMove(int x, int y, const MouseState * mouseState); + void update(); + void render(); + virtual void keyDown(SDL_KeyboardEvent key); - void reloadUI (); - }; + void reloadUI(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/menu/menu_state_options.cpp b/source/glest_game/menu/menu_state_options.cpp index 022fac0bd..7d79dd8ac 100644 --- a/source/glest_game/menu/menu_state_options.cpp +++ b/source/glest_game/menu/menu_state_options.cpp @@ -29,1497 +29,1357 @@ #include "leak_dumper.h" using namespace - Shared::Util; +Shared::Util; namespace - Glest -{ - namespace - Game - { - -// ===================================================== -// class MenuStateOptions -// ===================================================== - MenuStateOptions::MenuStateOptions (Program * program, - MainMenu * mainMenu, - ProgramState ** parentUI): - MenuState (program, mainMenu, "config"), - buttonOk ("Options", "buttonOk"), - buttonReturn ("Options", "buttonReturn"), - labelLang ("Options", "labelLang"), - listBoxLang ("Options", "listBoxLang"), - labelPlayerName ("Options", "labelPlayerName"), - labelPlayerNameLabel ("Options", "labelPlayerNameLabel"), - buttonKeyboardSetup ("Options", "buttonKeyboardSetup"), - buttonVideoSection ("Options", "buttonVideoSection"), - buttonAudioSection ("Options", "buttonAudioSection"), - buttonMiscSection ("Options", "buttonMiscSection"), - buttonNetworkSettings ("Options", "buttonNetworkSettings"), - labelFontSizeAdjustment ("Options", "labelFontSizeAdjustment"), - listFontSizeAdjustment ("Options", "listFontSizeAdjustment"), - mainMessageBox ("Options", "mainMessageBox"), - labelScreenShotType ("Options", "labelScreenShotType"), - listBoxScreenShotType ("Options", "listBoxScreenShotType"), - labelDisableScreenshotConsoleText ("Options", - "labelDisableScreenshotConsoleText"), - checkBoxDisableScreenshotConsoleText ("Options", - "checkBoxDisableScreenshotConsoleText"), - labelMouseMoveScrollsWorld ("Options", "labelMouseMoveScrollsWorld"), - checkBoxMouseMoveScrollsWorld ("Options", - "checkBoxMouseMoveScrollsWorld"), - labelCameraMoveSpeed ("Options", "labelCameraMoveSpeed"), - listCameraMoveSpeed ("Options", "listCameraMoveSpeed"), - labelVisibleHud ("Options", "labelVisibleHud"), - checkBoxVisibleHud ("Options", "checkBoxVisibleHud"), - labelHealthBars ("Options", "labelHealthBars"), - listBoxHealthBars ("Options", "listBoxHealthBars"), - labelTimeDisplay ("Options", "labelTimeDisplay"), - checkBoxTimeDisplay ("Options", "checkBoxTimeDisplay"), - labelChatStaysActive ("Options", "labelChatStaysActive"), - checkBoxChatStaysActive ("Options", "checkBoxChatStaysActive"), - labelLuaDisableSecuritySandbox ("Options", - "labelLuaDisableSecuritySandbox"), - checkBoxLuaDisableSecuritySandbox ("Options", - "checkBoxLuaDisableSecuritySandbox"), - luaMessageBox ("Options", "luaMessageBox"), - labelCustomTranslation ("Options", "labelCustomTranslation"), - checkBoxCustomTranslation ("Options", "checkBoxCustomTranslation"), - buttonGetNewLanguageFiles ("Options", "buttonGetNewLanguageFiles"), - buttonDeleteNewLanguageFiles ("Options", "buttonDeleteNewLanguageFiles"), - labelTransifexUserLabel ("Options", "labelTransifexUserLabel"), - labelTransifexUser ("Options", "labelTransifexUser"), - labelTransifexPwdLabel ("Options", "labelTransifexPwdLabel"), - labelTransifexPwd ("Options", "labelTransifexPwd"), - labelTransifexI18NLabel ("Options", "labelTransifexI18NLabel"), - labelTransifexI18N ("Options", "labelTransifexI18N") - { - try - { - containerName = "Options"; - this-> - parentUI = parentUI; - Lang & - lang = Lang::getInstance (); - Config & - config = Config::getInstance (); - - this-> - console. - setOnlyChatMessagesInStoredLines (false); - activeInputLabel = NULL; - - int - leftLabelStart = 100; - int - leftColumnStart = leftLabelStart + 300; - int - buttonRowPos = 50; - int - buttonStartPos = 170; - int - lineOffset = 30; - int - tabButtonWidth = 200; - int - tabButtonHeight = 30; - - mainMessageBox. - init (lang.getString ("Ok")); - mainMessageBox. - setEnabled (false); - mainMessageBoxState = 0; - - buttonAudioSection. - init (0, 720, tabButtonWidth, tabButtonHeight); - buttonAudioSection. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonAudioSection. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonAudioSection. - setText (lang.getString ("Audio")); - // Video Section - buttonVideoSection. - init (200, 720, tabButtonWidth, tabButtonHeight); - buttonVideoSection. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonVideoSection. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonVideoSection. - setText (lang.getString ("Video")); - //MiscSection - buttonMiscSection. - init (400, 700, tabButtonWidth, tabButtonHeight + 20); - buttonMiscSection. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonMiscSection. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonMiscSection. - setText (lang.getString ("Misc")); - //NetworkSettings - buttonNetworkSettings. - init (600, 720, tabButtonWidth, tabButtonHeight); - buttonNetworkSettings. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonNetworkSettings. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonNetworkSettings. - setText (lang.getString ("Network")); - - //KeyboardSetup - buttonKeyboardSetup. - init (800, 720, tabButtonWidth, tabButtonHeight); - buttonKeyboardSetup. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonKeyboardSetup. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonKeyboardSetup. - setText (lang.getString ("Keyboardsetup")); - - int - currentLine = 650; // reset line pos - int - currentLabelStart = leftLabelStart; // set to right side - int - currentColumnStart = leftColumnStart; // set to right side - - //lang - labelLang. - init (currentLabelStart, currentLine); - labelLang. - setText (lang.getString ("Language")); - - listBoxLang. - init (currentColumnStart, currentLine, 375); - vector < - string > - langResults; - - languageList = Lang::getInstance ().getDiscoveredLanguageList (true); - for (map < string, string >::iterator iterMap = languageList.begin (); - iterMap != languageList.end (); ++iterMap) - { - langResults.push_back (iterMap->first + "-" + iterMap->second); - } - - listBoxLang. - setItems (langResults); - - pair < - string, - string > - defaultLang = - Lang::getInstance ().getNavtiveNameFromLanguageName (config. - getString - ("Lang")); - if (defaultLang.first == "" && defaultLang.second == "") - { - defaultLang = - Lang::getInstance (). - getNavtiveNameFromLanguageName (Lang::getInstance (). - getDefaultLanguage ()); - } - listBoxLang. - setSelectedItem (defaultLang.second + "-" + defaultLang.first); - currentLine -= lineOffset; - - //playerName - labelPlayerNameLabel.init (currentLabelStart, currentLine); - labelPlayerNameLabel.setText (lang.getString ("Playername")); - - labelPlayerName.init (currentColumnStart, currentLine); - labelPlayerName.setText (config. - getString ("NetPlayerName", - Socket::getHostName ().c_str ())); - labelPlayerName.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelPlayerName.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - labelPlayerName.setEditable (true); - labelPlayerName.setMaxEditWidth (16); - labelPlayerName.setMaxEditRenderWidth (200); - currentLine -= lineOffset; - - //FontSizeAdjustment - labelFontSizeAdjustment.init (currentLabelStart, currentLine); - labelFontSizeAdjustment.setText (lang. - getString ("FontSizeAdjustment")); - - listFontSizeAdjustment.init (currentColumnStart, currentLine, 80); - for (int i = -5; i <= 5; i += 1) - { - listFontSizeAdjustment.pushBackItem (intToStr (i)); - } - listFontSizeAdjustment. - setSelectedItem (intToStr (config.getInt ("FontSizeAdjustment"))); - - currentLine -= lineOffset; - // Screenshot type flag - labelScreenShotType.init (currentLabelStart, currentLine); - labelScreenShotType.setText (lang.getString ("ScreenShotFileType")); - - listBoxScreenShotType.init (currentColumnStart, currentLine, 80); - listBoxScreenShotType.pushBackItem ("bmp"); - listBoxScreenShotType.pushBackItem ("jpg"); - listBoxScreenShotType.pushBackItem ("png"); - listBoxScreenShotType.pushBackItem ("tga"); - listBoxScreenShotType.setSelectedItem (config. - getString - ("ScreenShotFileType", "jpg")); - - currentLine -= lineOffset; - - labelDisableScreenshotConsoleText.init (currentLabelStart, - currentLine); - labelDisableScreenshotConsoleText.setText (lang. - getString - ("ScreenShotConsoleText")); - - checkBoxDisableScreenshotConsoleText.init (currentColumnStart, - currentLine); - checkBoxDisableScreenshotConsoleText.setValue (!config. - getBool - ("DisableScreenshotConsoleText", - "false")); - - currentLine -= lineOffset; - - labelMouseMoveScrollsWorld.init (currentLabelStart, currentLine); - labelMouseMoveScrollsWorld.setText (lang. - getString ("MouseScrollsWorld")); - - checkBoxMouseMoveScrollsWorld.init (currentColumnStart, currentLine); - checkBoxMouseMoveScrollsWorld.setValue (config. - getBool - ("MouseMoveScrollsWorld", - "true")); - currentLine -= lineOffset; - - //CameraMoveSpeed - labelCameraMoveSpeed.init (currentLabelStart, currentLine); - labelCameraMoveSpeed.setText (lang.getString ("CameraMoveSpeed")); - - listCameraMoveSpeed.init (currentColumnStart, currentLine, 80); - for (int i = 15; i <= 50; i += 5) - { - listCameraMoveSpeed.pushBackItem (intToStr (i)); - } - listCameraMoveSpeed. - setSelectedItem (intToStr - ((int) - (config.getFloat ("CameraMoveSpeed", "15")))); - currentLine -= lineOffset; - - labelVisibleHud.init (currentLabelStart, currentLine); - labelVisibleHud.setText (lang.getString ("VisibleHUD")); - - checkBoxVisibleHud.init (currentColumnStart, currentLine); - checkBoxVisibleHud.setValue (config.getBool ("VisibleHud", "true")); - - currentLine -= lineOffset; - - labelHealthBars.init (currentLabelStart, currentLine); - labelHealthBars.setText (lang.getString ("Healthbar")); - - listBoxHealthBars.init (currentColumnStart, currentLine, 375); - listBoxHealthBars.pushBackItem (lang. - getString - ("HealthbarsFactionDefault")); - listBoxHealthBars.pushBackItem (lang.getString ("HealthbarsOff")); - listBoxHealthBars.pushBackItem (lang.getString ("HealthbarsAlways")); - listBoxHealthBars.pushBackItem (lang. - getString ("HealthbarsIfNeeded")); - listBoxHealthBars.pushBackItem (lang. - getString ("HealthbarsSelected")); - listBoxHealthBars.pushBackItem (lang. - getString - ("HealthbarsSelectedOrNeeded")); - - int - hpMode = config.getInt ("HealthBarMode", "4"); - int - hpIndex = 0; - switch (hpMode) - { - case hbvUndefined: - hpIndex = 0; - break; - case hbvOff: - hpIndex = 1; - break; - case hbvAlways: - hpIndex = 2; - break; - case hbvIfNeeded: - hpIndex = 3; - break; - case hbvSelected: - hpIndex = 4; - break; - case hbvSelected | hbvIfNeeded: - hpIndex = 5; - break; - default: - hpIndex = 0; - break; - } - - listBoxHealthBars.setSelectedItemIndex (hpIndex); - - currentLine -= lineOffset; - - labelChatStaysActive.init (currentLabelStart, currentLine); - labelChatStaysActive.setText (lang.getString ("ChatStaysActive")); - - checkBoxChatStaysActive.init (currentColumnStart, currentLine); - checkBoxChatStaysActive.setValue (config. - getBool ("ChatStaysActive", - "false")); - - currentLine -= lineOffset; - - labelTimeDisplay.init (currentLabelStart, currentLine); - labelTimeDisplay.setText (lang.getString ("TimeDisplay")); - - checkBoxTimeDisplay.init (currentColumnStart, currentLine); - checkBoxTimeDisplay.setValue (config.getBool ("TimeDisplay", "true")); - - currentLine -= lineOffset; - - labelLuaDisableSecuritySandbox.init (currentLabelStart, currentLine); - labelLuaDisableSecuritySandbox.setText (lang. - getString - ("LuaDisableSecuritySandbox")); - - checkBoxLuaDisableSecuritySandbox.init (currentColumnStart, - currentLine); - checkBoxLuaDisableSecuritySandbox.setValue (config. - getBool - ("DisableLuaSandbox", - "false")); - - luaMessageBox.init (lang.getString ("Yes"), lang.getString ("No")); - luaMessageBox.setEnabled (false); - luaMessageBoxState = 0; - - currentLine -= lineOffset; - - currentLine -= lineOffset / 2; - - // buttons - buttonOk.init (buttonStartPos, buttonRowPos, 100); - buttonOk.setText (lang.getString ("Save")); - - buttonReturn.init (buttonStartPos + 110, buttonRowPos, 100); - buttonReturn.setText (lang.getString ("Return")); - - // Transifex related UI - currentLine -= lineOffset * 3; - labelCustomTranslation.init (currentLabelStart, currentLine); - labelCustomTranslation.setText (lang.getString ("CustomTranslation")); - - checkBoxCustomTranslation.init (currentColumnStart, currentLine); - checkBoxCustomTranslation.setValue (false); - currentLine -= lineOffset; - - labelTransifexUserLabel.init (currentLabelStart, currentLine); - labelTransifexUserLabel.setText (lang. - getString ("TransifexUserName")); - - labelTransifexPwdLabel.init (currentLabelStart + 260, currentLine); - labelTransifexPwdLabel.setText (lang.getString ("TransifexPwd")); - - labelTransifexI18NLabel.init (currentLabelStart + 520, currentLine); - labelTransifexI18NLabel.setText (lang.getString ("TransifexI18N")); - - currentLine -= lineOffset; - - labelTransifexUser.init (currentLabelStart, currentLine); - labelTransifexUser.setEditable (true); - labelTransifexUser.setMaxEditWidth (28); - labelTransifexUser.setMaxEditRenderWidth (250); - labelTransifexUser.setText (config. - getString ("TranslationGetURLUser", - "")); - - labelTransifexPwd.init (currentLabelStart + 260, currentLine); - labelTransifexPwd.setIsPassword (true); - labelTransifexPwd.setEditable (true); - labelTransifexPwd.setMaxEditWidth (28); - labelTransifexPwd.setMaxEditRenderWidth (250); - labelTransifexPwd.setText (config. - getString ("TranslationGetURLPassword", - "")); - - labelTransifexI18N.init (currentLabelStart + 520, currentLine); - labelTransifexI18N.setEditable (true); - labelTransifexI18N.setMaxEditWidth (6); - labelTransifexI18N.setMaxEditRenderWidth (70); - labelTransifexI18N.setText (config. - getString ("TranslationGetURLLanguage", - "en")); - currentLine -= lineOffset; - - buttonGetNewLanguageFiles.init (currentLabelStart, currentLine, 250); - buttonGetNewLanguageFiles.setText (lang. - getString - ("TransifexGetLanguageFiles")); - - buttonDeleteNewLanguageFiles.init (currentLabelStart + 260, - currentLine, 250); - buttonDeleteNewLanguageFiles.setText (lang. - getString - ("TransifexDeleteLanguageFiles")); - - setupTransifexUI (); - - GraphicComponent::applyAllCustomProperties (containerName); - } - catch (exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error loading options: %s\n", - __FILE__, __FUNCTION__, __LINE__, - e.what ()); - throw - megaglest_runtime_error (string ("Error loading options msg: ") + - e.what ()); - } - } - - MenuStateOptions::~MenuStateOptions () - { - } - - void - MenuStateOptions::reloadUI () - { - Lang & lang = Lang::getInstance (); - - mainMessageBox.init (lang.getString ("Ok")); - luaMessageBox.init (lang.getString ("Yes"), lang.getString ("No")); - - buttonAudioSection.setText (lang.getString ("Audio")); - buttonVideoSection.setText (lang.getString ("Video")); - buttonMiscSection.setText (lang.getString ("Misc")); - buttonNetworkSettings.setText (lang.getString ("Network")); - buttonKeyboardSetup.setText (lang.getString ("Keyboardsetup")); - - labelVisibleHud.setText (lang.getString ("VisibleHUD")); - labelHealthBars.setText (lang.getString ("Healthbar")); - labelChatStaysActive.setText (lang.getString ("ChatStaysActive")); - labelTimeDisplay.setText (lang.getString ("TimeDisplay")); - - labelLuaDisableSecuritySandbox.setText (lang. - getString - ("LuaDisableSecuritySandbox")); - labelLang.setText (lang.getString ("Language")); - labelPlayerNameLabel.setText (lang.getString ("Playername")); - labelFontSizeAdjustment.setText (lang.getString ("FontSizeAdjustment")); - labelScreenShotType.setText (lang.getString ("ScreenShotFileType")); - labelDisableScreenshotConsoleText.setText (lang. - getString - ("ScreenShotConsoleText")); - labelMouseMoveScrollsWorld.setText (lang. - getString ("MouseScrollsWorld")); - labelCameraMoveSpeed.setText (lang.getString ("CameraMoveSpeed")); - - buttonOk.setText (lang.getString ("Save")); - buttonReturn.setText (lang.getString ("Return")); - - labelCustomTranslation.setText (lang.getString ("CustomTranslation")); - buttonGetNewLanguageFiles.setText (lang. - getString - ("TransifexGetLanguageFiles")); - buttonDeleteNewLanguageFiles.setText (lang. - getString - ("TransifexDeleteLanguageFiles")); - labelTransifexUserLabel.setText (lang.getString ("TransifexUserName")); - labelTransifexPwdLabel.setText (lang.getString ("TransifexPwd")); - labelTransifexI18NLabel.setText (lang.getString ("TransifexI18N")); - } - - void - MenuStateOptions::setupTransifexUI () - { - buttonGetNewLanguageFiles.setEnabled (checkBoxCustomTranslation. - getValue ()); - buttonDeleteNewLanguageFiles.setEnabled (checkBoxCustomTranslation. - getValue ()); - labelTransifexUserLabel.setEnabled (checkBoxCustomTranslation. - getValue ()); - labelTransifexUser.setEnabled (checkBoxCustomTranslation.getValue ()); - labelTransifexPwdLabel.setEnabled (checkBoxCustomTranslation. - getValue ()); - labelTransifexPwd.setEnabled (checkBoxCustomTranslation.getValue ()); - labelTransifexI18NLabel.setEnabled (checkBoxCustomTranslation. - getValue ()); - labelTransifexI18N.setEnabled (checkBoxCustomTranslation.getValue ()); - } - - void - MenuStateOptions::showMessageBox (const string & text, - const string & header, bool toggle) - { - if (!toggle) - { - mainMessageBox.setEnabled (false); - } - - if (!mainMessageBox.getEnabled ()) - { - mainMessageBox.setText (text); - mainMessageBox.setHeader (header); - mainMessageBox.setEnabled (true); - } - else - { - mainMessageBox.setEnabled (false); - } - } - - void - MenuStateOptions::showLuaMessageBox (const string & text, - const string & header, bool toggle) - { - if (!toggle) - { - luaMessageBox.setEnabled (false); - } - - if (!luaMessageBox.getEnabled ()) - { - luaMessageBox.setText (text); - luaMessageBox.setHeader (header); - luaMessageBox.setEnabled (true); - } - else - { - luaMessageBox.setEnabled (false); - } - } - - void - MenuStateOptions::mouseClick (int x, int y, MouseButton mouseButton) - { - - Config & config = Config::getInstance (); - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - - if (mainMessageBox.getEnabled ()) - { - int - button = 0; - if (mainMessageBox.mouseClick (x, y, button)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - if (button == 0) - { - if (mainMessageBoxState == 1) - { - mainMessageBoxState = 0; - mainMessageBox.setEnabled (false); - saveConfig (); - - Lang & lang = Lang::getInstance (); - mainMessageBox.init (lang.getString ("Ok")); - mainMenu->setState (new MenuStateRoot (program, mainMenu)); - } - else - { - mainMessageBox.setEnabled (false); - - Lang & lang = Lang::getInstance (); - mainMessageBox.init (lang.getString ("Ok")); - } - } - else - { - if (mainMessageBoxState == 1) - { - mainMessageBoxState = 0; - mainMessageBox.setEnabled (false); - - Lang & lang = Lang::getInstance (); - mainMessageBox.init (lang.getString ("Ok")); - } - } - } - } - else if (luaMessageBox.getEnabled ()) - { - int - button = 0; - if (luaMessageBox.mouseClick (x, y, button)) - { - checkBoxLuaDisableSecuritySandbox.setValue (false); - soundRenderer.playFx (coreData.getClickSoundA ()); - if (button == 0) - { - if (luaMessageBoxState == 1) - { - checkBoxLuaDisableSecuritySandbox.setValue (true); - } - } - luaMessageBox.setEnabled (false); - } - } - else if (checkBoxLuaDisableSecuritySandbox.mouseClick (x, y)) - { - if (checkBoxLuaDisableSecuritySandbox.getValue () == true) - { - checkBoxLuaDisableSecuritySandbox.setValue (false); - - luaMessageBoxState = 1; - Lang & lang = Lang::getInstance (); - showLuaMessageBox (lang. - getString ("LuaDisableSecuritySandboxWarning"), - lang.getString ("Question"), false); - } - } - else if (buttonOk.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - - string - currentFontSizeAdjustment = config.getString ("FontSizeAdjustment"); - string - selectedFontSizeAdjustment = - listFontSizeAdjustment.getSelectedItem (); - if (currentFontSizeAdjustment != selectedFontSizeAdjustment) - { - mainMessageBoxState = 1; - Lang & lang = Lang::getInstance (); - showMessageBox (lang.getString ("RestartNeeded"), - lang.getString ("FontSizeAdjustmentChanged"), - false); - return; - } - saveConfig (); - //mainMenu->setState(new MenuStateRoot(program, mainMenu)); - reloadUI (); - return; - } - else if (buttonReturn.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - if (this->parentUI != NULL) - { - *this->parentUI = NULL; - delete * - this-> - parentUI; - } - mainMenu->setState (new MenuStateRoot (program, mainMenu)); - return; - } - else if (buttonKeyboardSetup.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateKeysetup (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - //showMessageBox("Not implemented yet", "Keyboard setup", false); - return; - } - else if (buttonAudioSection.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptionsSound (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - return; - } - else if (buttonNetworkSettings.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptionsNetwork (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - return; - } - else if (buttonMiscSection.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - //mainMenu->setState(new MenuStateOptions(program, mainMenu,this->parentUI)); // open keyboard shortcuts setup screen - return; - } - else if (buttonVideoSection.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptionsGraphics (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - return; - } - else if (checkBoxCustomTranslation.mouseClick (x, y)) - { - setupTransifexUI (); - } - else if (buttonDeleteNewLanguageFiles.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - - setActiveInputLable (NULL); - - if (labelTransifexI18N.getText () != "") - { - Lang & lang = Lang::getInstance (); - string - language = lang.getLanguageFile (labelTransifexI18N.getText ()); - replaceAll (language, "(", ""); - replaceAll (language, ")", ""); - - if (language != "") - { - bool - foundFilesToDelete = false; - - Config & config = Config::getInstance (); - string - data_path = config.getString ("UserData_Root", ""); - if (data_path != "") - { - endPathWithSlash (data_path); - } - - if (data_path != "") - { - - string - txnURLFileListMapping = - Config::getInstance (). - getString ("TranslationGetURLFileListMapping"); - vector < string > languageFileMappings; - Tokenize (txnURLFileListMapping, languageFileMappings, "|"); - - Config & config = Config::getInstance (); - - // Cleanup Scenarios - vector < string > scenarioPaths = - config.getPathListForType (ptScenarios); - if (scenarioPaths.size () > 1) - { - string & scenarioPath = scenarioPaths[1]; - endPathWithSlash (scenarioPath); - - vector < string > scenarioList; - findDirs (scenarioPath, scenarioList, false, false); - for (unsigned int i = 0; i < scenarioList.size (); ++i) - { - string - scenario = scenarioList[i]; - - vector < string > langResults; - findAll (scenarioPath + scenario + "/*.lng", langResults, - false, false); - for (unsigned int j = 0; j < langResults.size (); ++j) - { - string - testLanguage = langResults[j]; - - string - removeLngFile = - scenarioPath + scenario + "/" + testLanguage; - - if (EndsWith (testLanguage, language + ".lng") == true) - { - - for (unsigned int k = 0; - k < languageFileMappings.size (); ++k) - { - string - mapping = languageFileMappings[k]; - replaceAll (mapping, "$language", language); - - //printf("Comparing found [%s] with [%s]\n",removeLngFile.c_str(),mapping.c_str()); - - if (EndsWith (removeLngFile, mapping) == true) - { - printf ("About to delete file [%s]\n", - removeLngFile.c_str ()); - removeFile (removeLngFile); - foundFilesToDelete = true; - break; - } - } - } - } - } - } - - // Cleanup tutorials - vector < string > tutorialPaths = - config.getPathListForType (ptTutorials); - if (tutorialPaths.size () > 1) - { - string & tutorialPath = tutorialPaths[1]; - endPathWithSlash (tutorialPath); - - vector < string > tutorialList; - findDirs (tutorialPath, tutorialList, false, false); - for (unsigned int i = 0; i < tutorialList.size (); ++i) - { - string - tutorial = tutorialList[i]; - - vector < string > langResults; - findAll (tutorialPath + tutorial + "/*.lng", langResults, - false, false); - for (unsigned int j = 0; j < langResults.size (); ++j) - { - string - testLanguage = langResults[j]; - - string - removeLngFile = - tutorialPath + tutorial + "/" + testLanguage; - if (EndsWith (testLanguage, language + ".lng") == true) - { - - - for (unsigned int k = 0; - k < languageFileMappings.size (); ++k) - { - string - mapping = languageFileMappings[k]; - replaceAll (mapping, "$language", language); - - //printf("Comparing found [%s] with [%s]\n",removeLngFile.c_str(),mapping.c_str()); - - if (EndsWith (removeLngFile, mapping) == true) - { - printf ("About to delete file [%s]\n", - removeLngFile.c_str ()); - removeFile (removeLngFile); - foundFilesToDelete = true; - break; - } - } - } - } - } - } - - // Cleanup main and hint language files - string - mainLngFile = data_path + "data/lang/" + language + ".lng"; - if (fileExists (mainLngFile) == true) - { - - for (unsigned int k = 0; k < languageFileMappings.size (); - ++k) - { - string - mapping = languageFileMappings[k]; - replaceAll (mapping, "$language", language); - - if (EndsWith (mainLngFile, mapping) == true) - { - printf ("About to delete file [%s]\n", - mainLngFile.c_str ()); - removeFile (mainLngFile); - foundFilesToDelete = true; - break; - } - } - } - - string - hintLngFile = - data_path + "data/lang/hint/hint_" + language + ".lng"; - if (fileExists (hintLngFile) == true) - { - for (unsigned int k = 0; k < languageFileMappings.size (); - ++k) - { - string - mapping = languageFileMappings[k]; - replaceAll (mapping, "$language", language); - - if (EndsWith (hintLngFile, mapping) == true) - { - printf ("About to delete file [%s]\n", - hintLngFile.c_str ()); - removeFile (hintLngFile); - foundFilesToDelete = true; - break; - } - } - } - } - - if (lang.isLanguageLocal (toLower (language)) == true) - { - lang.loadGameStrings (toLower (language)); - } - - if (foundFilesToDelete == true) - { - mainMessageBoxState = 0; - Lang & lang = Lang::getInstance (); - showMessageBox (lang.getString ("TransifexDeleteSuccess"), - lang.getString ("Notice"), false); - } - } - } - } - else if (buttonGetNewLanguageFiles.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - - setActiveInputLable (NULL); - - string - orig_txnURLUser = - Config::getInstance ().getString ("TranslationGetURLUser"); - //string orig_txnURLPwd = Config::getInstance().getString("TranslationGetURLPassword",""); - string - orig_txnURLLang = - Config::getInstance ().getString ("TranslationGetURLLanguage"); - - Config::getInstance ().setString ("TranslationGetURLUser", - labelTransifexUser.getText ()); - Config::getInstance ().setString ("TranslationGetURLPassword", - labelTransifexPwd.getText (), true); - Config::getInstance ().setString ("TranslationGetURLLanguage", - labelTransifexI18N.getText ()); - - bool - saveChanges = (orig_txnURLUser != labelTransifexUser.getText () || - orig_txnURLLang != labelTransifexI18N.getText ()); - - string - txnURL = Config::getInstance ().getString ("TranslationGetURL"); - string - txnURLUser = - Config::getInstance ().getString ("TranslationGetURLUser"); - string - txnURLPwd = - Config::getInstance ().getString ("TranslationGetURLPassword"); - string - txnURLLang = - Config::getInstance ().getString ("TranslationGetURLLanguage"); - string - txnURLFileList = - Config::getInstance ().getString ("TranslationGetURLFileList"); - string - txnURLFileListMapping = - Config::getInstance (). - getString ("TranslationGetURLFileListMapping"); - - string - txnURLDetails = - Config::getInstance ().getString ("TranslationGetURLDetails"); - - string - credentials = txnURLUser + ":" + txnURLPwd; - - printf ("URL1 [%s] credentials [%s]\n", txnURL.c_str (), - credentials.c_str ()); - - //txnURLUser = SystemFlags::escapeURL(txnURLUser,handle); - //replaceAll(txnURL,"$user",txnURLUser); - - //printf("URL2 [%s]\n",txnURL.c_str()); - - //txnURLPwd = SystemFlags::escapeURL(txnURLPwd,handle); - //replaceAll(txnURL,"$password",txnURLPwd); - - //printf("URL3 [%s]\n",txnURL.c_str()); - - replaceAll (txnURL, "$language", txnURLLang); - - printf ("URL4 [%s]\n", txnURL.c_str ()); - - //txnURLFileList - vector < string > languageFiles; - Tokenize (txnURLFileList, languageFiles, "|"); - - vector < string > languageFileMappings; - Tokenize (txnURLFileListMapping, languageFileMappings, "|"); - - printf ("URL5 file count = " MG_SIZE_T_SPECIFIER ", " - MG_SIZE_T_SPECIFIER " [%s]\n", languageFiles.size (), - languageFileMappings.size (), - (languageFiles.empty () == - false ? languageFiles[0].c_str () : "")); - - if (languageFiles.empty () == false) - { - - bool - gotDownloads = false; - bool - reloadLanguage = false; - string - langName = ""; - - CURL * - handle = SystemFlags::initHTTP (); - for (unsigned int i = 0; i < languageFiles.size (); ++i) - { - string - fileURL = txnURL; - replaceAll (fileURL, "$file", languageFiles[i]); - - if (langName == "") - { - // Get language name for file - string - fileURLDetails = txnURLDetails; - replaceAll (fileURLDetails, "$file", languageFiles[0]); - - printf (" i = %u Trying [%s]\n", i, fileURLDetails.c_str ()); - curl_easy_setopt (handle, CURLOPT_VERBOSE, 1); - curl_easy_setopt (handle, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt (handle, CURLOPT_USERPWD, - credentials.c_str ()); - std::string fileDataDetails = - SystemFlags::getHTTP (fileURLDetails, handle); - - // "available_languages": [ - // { - // "code_aliases": " ", - // "code": "ca", - // "name": "Catalan" - // }, - // { - // "code_aliases": " ", - // "code": "zh", - // "name": "Chinese" - // }, - // curl -i -L --user softcoder -X GET https://www.transifex.com/api/2/project/megaglest/resource/main-language-file/?details - - string - search_detail_key = "\"code\": \"" + txnURLLang + "\""; - size_t - posDetails = fileDataDetails.find (search_detail_key, 0); - if (posDetails != fileDataDetails.npos) - { - posDetails = - fileDataDetails.find ("\"name\": \"", - posDetails + - search_detail_key.length ()); - - if (posDetails != fileDataDetails.npos) - { - - size_t - posDetailsEnd = - fileDataDetails.find ("\"", posDetails + 9); - - langName = - fileDataDetails.substr (posDetails + 9, - posDetailsEnd - (posDetails + 9)); - replaceAll (langName, ",", ""); - replaceAll (langName, "\\", ""); - replaceAll (langName, "/", ""); - replaceAll (langName, "?", ""); - replaceAll (langName, ":", ""); - replaceAll (langName, "@", ""); - replaceAll (langName, "!", ""); - replaceAll (langName, "*", ""); - replaceAll (langName, "(", ""); - replaceAll (langName, ")", ""); - langName = trim (langName); - replaceAll (langName, " ", "-"); - } - - printf ("PARSED Language filename [%s]\n", langName.c_str ()); - } - } - - printf ("i = %u Trying [%s]\n", i, fileURL.c_str ()); - curl_easy_setopt (handle, CURLOPT_VERBOSE, 1); - curl_easy_setopt (handle, CURLOPT_SSL_VERIFYPEER, 0L); - curl_easy_setopt (handle, CURLOPT_USERPWD, credentials.c_str ()); - std::string fileData = SystemFlags::getHTTP (fileURL, handle); - - // "content": " - // ", - // "mimetype": "text/plain" - size_t - pos = fileData.find ("\"content\": \"", 0); - if (pos != fileData.npos) - { - fileData = fileData.substr (pos + 12, fileData.length ()); - - pos = fileData.find ("\",\n", 0); - if (pos != fileData.npos) - { - fileData = fileData.substr (0, pos); - } - - replaceAll (fileData, "\\\\n", "$requires-newline$"); - replaceAll (fileData, "\\n", "\n"); - replaceAll (fileData, "$requires-newline$", "\\n"); - - //replaceAll(fileData,""","\""); - replaceAllHTMLEntities (fileData); - - - printf ("PARSED Language text\n[%s]\n", fileData.c_str ()); - - //vector languageName; - //Tokenize(fileData,languageName," "); - //printf("PARSED Language Name guessed to be [%s]\n",languageName[1].c_str()); - - //string data_path= getGameReadWritePath(GameConstants::path_data_CacheLookupKey); - //if(data_path != ""){ - //endPathWithSlash(data_path); - //} - Config & config = Config::getInstance (); - string - data_path = config.getString ("UserData_Root", ""); - if (data_path != "") - { - endPathWithSlash (data_path); - } - - string - outputFile = languageFileMappings[i]; - replaceAll (outputFile, "$language", toLower (langName)); - //string lngFile = getGameCustomCoreDataPath(data_path, "data/lang/" + toLower(languageName[1]) + ".lng"); - string - lngFile = getGameCustomCoreDataPath (data_path, outputFile); - - string - lngPath = extractDirectoryPathFromFile (lngFile); - createDirectoryPaths (lngPath); - - printf ("Save data to Language Name [%s]\n", lngFile.c_str ()); - saveDataToFile (lngFile, fileData); - gotDownloads = true; - - reloadLanguage = true; - if (saveChanges == true) - { - saveChanges = false; - config.save (); - } - } - else - { - printf ("UNPARSED Language text\n[%s]\n", fileData.c_str ()); - } - } - - SystemFlags::cleanupHTTP (&handle); - - if (reloadLanguage == true && langName != "") - { - Lang & lang = Lang::getInstance (); - if (lang.isLanguageLocal (toLower (langName)) == true) - { - lang.loadGameStrings (toLower (langName)); - } - } - - if (gotDownloads == true) - { - mainMessageBoxState = 0; - Lang & lang = Lang::getInstance (); - showMessageBox (lang.getString ("TransifexDownloadSuccess") + - "\n" + langName, lang.getString ("Notice"), - false); - } - } - return; - } - else if (labelPlayerName.mouseClick (x, y) - && (activeInputLabel != &labelPlayerName)) - { - setActiveInputLable (&labelPlayerName); - } - else if (labelTransifexUser.mouseClick (x, y) - && (activeInputLabel != &labelTransifexUser)) - { - setActiveInputLable (&labelTransifexUser); - } - else if (labelTransifexPwd.mouseClick (x, y) - && (activeInputLabel != &labelTransifexPwd)) - { - setActiveInputLable (&labelTransifexPwd); - } - else if (labelTransifexI18N.mouseClick (x, y) - && (activeInputLabel != &labelTransifexI18N)) - { - setActiveInputLable (&labelTransifexI18N); - } - else - { - listBoxLang.mouseClick (x, y); - listFontSizeAdjustment.mouseClick (x, y); - - listBoxScreenShotType.mouseClick (x, y); - - checkBoxDisableScreenshotConsoleText.mouseClick (x, y); - checkBoxMouseMoveScrollsWorld.mouseClick (x, y); - listCameraMoveSpeed.mouseClick (x, y); - checkBoxVisibleHud.mouseClick (x, y); - listBoxHealthBars.mouseClick (x, y); - checkBoxChatStaysActive.mouseClick (x, y); - checkBoxTimeDisplay.mouseClick (x, y); - checkBoxLuaDisableSecuritySandbox.mouseClick (x, y); - } - } - - void - MenuStateOptions::mouseMove (int x, int y, const MouseState * ms) - { - if (mainMessageBox.getEnabled ()) - { - mainMessageBox.mouseMove (x, y); - } - if (luaMessageBox.getEnabled ()) - { - luaMessageBox.mouseMove (x, y); - } - - buttonOk.mouseMove (x, y); - buttonReturn.mouseMove (x, y); - buttonKeyboardSetup.mouseMove (x, y); - buttonAudioSection.mouseMove (x, y); - buttonNetworkSettings.mouseMove (x, y); - buttonMiscSection.mouseMove (x, y); - buttonVideoSection.mouseMove (x, y); - buttonGetNewLanguageFiles.mouseMove (x, y); - buttonDeleteNewLanguageFiles.mouseMove (x, y); - listBoxLang.mouseMove (x, y); - listBoxLang.mouseMove (x, y); - listFontSizeAdjustment.mouseMove (x, y); - listBoxScreenShotType.mouseMove (x, y); - checkBoxDisableScreenshotConsoleText.mouseMove (x, y); - checkBoxMouseMoveScrollsWorld.mouseMove (x, y); - listCameraMoveSpeed.mouseMove (x, y); - listBoxHealthBars.mouseMove (x, y); - checkBoxVisibleHud.mouseMove (x, y); - checkBoxChatStaysActive.mouseMove (x, y); - checkBoxTimeDisplay.mouseMove (x, y); - checkBoxLuaDisableSecuritySandbox.mouseMove (x, y); - checkBoxCustomTranslation.mouseMove (x, y); - } - - bool - MenuStateOptions::isInSpecialKeyCaptureEvent () - { - return (activeInputLabel != NULL); - } - - void - MenuStateOptions::keyDown (SDL_KeyboardEvent key) - { - if (activeInputLabel != NULL) - { - keyDownEditLabel (key, &activeInputLabel); - } - } - - bool - MenuStateOptions::textInput (std::string text) - { - if (activeInputLabel != NULL) - { - //printf("[%d]\n",c); fflush(stdout); - if (&labelPlayerName == activeInputLabel || - &labelTransifexUser == activeInputLabel || - &labelTransifexPwd == activeInputLabel || - &labelTransifexI18N == activeInputLabel) - { - return textInputEditLabel (text, &activeInputLabel); - } - } - return false; - } - - void - MenuStateOptions::keyPress (SDL_KeyboardEvent c) - { - if (activeInputLabel != NULL) - { - keyPressEditLabel (c, &activeInputLabel); - } - else - { - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - if (isKeyPressed (configKeys.getSDLKey ("SaveGUILayout"), c) == true) - { - GraphicComponent::saveAllCustomProperties (containerName); - //Lang &lang= Lang::getInstance(); - //console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ? lang.getString("Yes") : lang.getString("No"))+ "]"); - } - } - } - - void - MenuStateOptions::render () - { - Renderer & renderer = Renderer::getInstance (); -// char szBuf[8096]=""; -// snprintf(szBuf,8096,"\nIn [%s::%s Line: %d]\n\nRender options menu [%p]!\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this); -// printf(szBuf); - - if (mainMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&mainMessageBox); - } - else if (luaMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&luaMessageBox); - } - else - { - renderer.renderButton (&buttonOk); - renderer.renderButton (&buttonReturn); - renderer.renderButton (&buttonKeyboardSetup); - renderer.renderButton (&buttonVideoSection); - renderer.renderButton (&buttonAudioSection); - renderer.renderButton (&buttonMiscSection); - renderer.renderButton (&buttonNetworkSettings); - - renderer.renderLabel (&labelCustomTranslation); - renderer.renderCheckBox (&checkBoxCustomTranslation); - - if (buttonGetNewLanguageFiles.getEnabled ()) - renderer.renderButton (&buttonGetNewLanguageFiles); - if (buttonDeleteNewLanguageFiles.getEnabled ()) - renderer.renderButton (&buttonDeleteNewLanguageFiles); - if (labelTransifexUserLabel.getEnabled ()) - renderer.renderLabel (&labelTransifexUserLabel); - if (labelTransifexPwdLabel.getEnabled ()) - renderer.renderLabel (&labelTransifexPwdLabel); - if (labelTransifexI18NLabel.getEnabled ()) - renderer.renderLabel (&labelTransifexI18NLabel); - if (labelTransifexUser.getEnabled ()) - renderer.renderLabel (&labelTransifexUser); - if (labelTransifexPwd.getEnabled ()) - renderer.renderLabel (&labelTransifexPwd); - if (labelTransifexI18N.getEnabled ()) - renderer.renderLabel (&labelTransifexI18N); - - renderer.renderListBox (&listBoxLang); - renderer.renderLabel (&labelLang); - renderer.renderLabel (&labelPlayerNameLabel); - renderer.renderLabel (&labelPlayerName); - renderer.renderListBox (&listFontSizeAdjustment); - renderer.renderLabel (&labelFontSizeAdjustment); - - renderer.renderLabel (&labelScreenShotType); - renderer.renderListBox (&listBoxScreenShotType); - - renderer.renderLabel (&labelDisableScreenshotConsoleText); - renderer.renderCheckBox (&checkBoxDisableScreenshotConsoleText); - - renderer.renderLabel (&labelMouseMoveScrollsWorld); - renderer.renderCheckBox (&checkBoxMouseMoveScrollsWorld); - renderer.renderLabel (&labelCameraMoveSpeed); - renderer.renderListBox (&listCameraMoveSpeed); - - renderer.renderLabel (&labelVisibleHud); - renderer.renderLabel (&labelHealthBars); - renderer.renderListBox (&listBoxHealthBars); - renderer.renderLabel (&labelChatStaysActive); - renderer.renderLabel (&labelTimeDisplay); - - renderer.renderLabel (&labelLuaDisableSecuritySandbox); - renderer.renderCheckBox (&checkBoxLuaDisableSecuritySandbox); - - renderer.renderCheckBox (&checkBoxVisibleHud); - renderer.renderCheckBox (&checkBoxChatStaysActive); - renderer.renderCheckBox (&checkBoxTimeDisplay); - - } - - renderer.renderConsole (&console); - if (program != NULL) - program->renderProgramMsgBox (); - } - - void - MenuStateOptions::saveConfig () - { - Config & config = Config::getInstance (); - Lang & lang = Lang::getInstance (); - setActiveInputLable (NULL); - - if (labelPlayerName.getText ().length () > 0) - { - config.setString ("NetPlayerName", labelPlayerName.getText ()); - } - //Copy values - map < string, string >::iterator iterMap = languageList.begin (); - std::advance (iterMap, listBoxLang.getSelectedItemIndex ()); - - config.setString ("Lang", iterMap->first); - lang.loadGameStrings (config.getString ("Lang")); - - config.setString ("FontSizeAdjustment", - listFontSizeAdjustment.getSelectedItem ()); - config.setString ("ScreenShotFileType", - listBoxScreenShotType.getSelectedItem ()); - - config.setBool ("DisableScreenshotConsoleText", - !checkBoxDisableScreenshotConsoleText.getValue ()); - config.setBool ("MouseMoveScrollsWorld", - checkBoxMouseMoveScrollsWorld.getValue ()); - config.setString ("CameraMoveSpeed", - listCameraMoveSpeed.getSelectedItem ()); - - int - hpIndex = listBoxHealthBars.getSelectedItemIndex (); - int - hpMode = hbvUndefined; - switch (hpIndex) - { - case 0: - hpMode = hbvUndefined; - break; - case 1: - hpMode = hbvOff; - break; - case 2: - hpMode = hbvAlways; - break; - case 3: - hpMode = hbvIfNeeded; - break; - case 4: - hpMode = hbvSelected; - break; - case 5: - hpMode = hbvSelected | hbvIfNeeded; - break; - default: - hpMode = hbvUndefined; - break; - } - - config.setInt ("HealthBarMode", hpMode); - config.setBool ("VisibleHud", checkBoxVisibleHud.getValue ()); - config.setBool ("ChatStaysActive", checkBoxChatStaysActive.getValue ()); - config.setBool ("TimeDisplay", checkBoxTimeDisplay.getValue ()); - - config.setBool ("DisableLuaSandbox", - checkBoxLuaDisableSecuritySandbox.getValue ()); - config.save (); - - if (config.getBool ("DisableLuaSandbox", "false") == true) - { - LuaScript::setDisableSandbox (true); - } - Renderer::getInstance ().loadConfig (); - console.addLine (lang.getString ("SettingsSaved")); - } - - void - MenuStateOptions::setActiveInputLable (GraphicLabel * newLable) - { - MenuState::setActiveInputLabel (newLable, &activeInputLabel); - - if (newLable == &labelTransifexPwd) - { - labelTransifexPwd.setIsPassword (false); - } - else - { - labelTransifexPwd.setIsPassword (true); - } - } - - } + Glest { + namespace + Game { + + // ===================================================== + // class MenuStateOptions + // ===================================================== + MenuStateOptions::MenuStateOptions(Program * program, + MainMenu * mainMenu, + ProgramState ** parentUI) : + MenuState(program, mainMenu, "config"), + buttonOk("Options", "buttonOk"), + buttonReturn("Options", "buttonReturn"), + labelLang("Options", "labelLang"), + listBoxLang("Options", "listBoxLang"), + labelPlayerName("Options", "labelPlayerName"), + labelPlayerNameLabel("Options", "labelPlayerNameLabel"), + buttonKeyboardSetup("Options", "buttonKeyboardSetup"), + buttonVideoSection("Options", "buttonVideoSection"), + buttonAudioSection("Options", "buttonAudioSection"), + buttonMiscSection("Options", "buttonMiscSection"), + buttonNetworkSettings("Options", "buttonNetworkSettings"), + labelFontSizeAdjustment("Options", "labelFontSizeAdjustment"), + listFontSizeAdjustment("Options", "listFontSizeAdjustment"), + mainMessageBox("Options", "mainMessageBox"), + labelScreenShotType("Options", "labelScreenShotType"), + listBoxScreenShotType("Options", "listBoxScreenShotType"), + labelDisableScreenshotConsoleText("Options", + "labelDisableScreenshotConsoleText"), + checkBoxDisableScreenshotConsoleText("Options", + "checkBoxDisableScreenshotConsoleText"), + labelMouseMoveScrollsWorld("Options", "labelMouseMoveScrollsWorld"), + checkBoxMouseMoveScrollsWorld("Options", + "checkBoxMouseMoveScrollsWorld"), + labelCameraMoveSpeed("Options", "labelCameraMoveSpeed"), + listCameraMoveSpeed("Options", "listCameraMoveSpeed"), + labelVisibleHud("Options", "labelVisibleHud"), + checkBoxVisibleHud("Options", "checkBoxVisibleHud"), + labelHealthBars("Options", "labelHealthBars"), + listBoxHealthBars("Options", "listBoxHealthBars"), + labelTimeDisplay("Options", "labelTimeDisplay"), + checkBoxTimeDisplay("Options", "checkBoxTimeDisplay"), + labelChatStaysActive("Options", "labelChatStaysActive"), + checkBoxChatStaysActive("Options", "checkBoxChatStaysActive"), + labelLuaDisableSecuritySandbox("Options", + "labelLuaDisableSecuritySandbox"), + checkBoxLuaDisableSecuritySandbox("Options", + "checkBoxLuaDisableSecuritySandbox"), + luaMessageBox("Options", "luaMessageBox"), + labelCustomTranslation("Options", "labelCustomTranslation"), + checkBoxCustomTranslation("Options", "checkBoxCustomTranslation"), + buttonGetNewLanguageFiles("Options", "buttonGetNewLanguageFiles"), + buttonDeleteNewLanguageFiles("Options", "buttonDeleteNewLanguageFiles"), + labelTransifexUserLabel("Options", "labelTransifexUserLabel"), + labelTransifexUser("Options", "labelTransifexUser"), + labelTransifexPwdLabel("Options", "labelTransifexPwdLabel"), + labelTransifexPwd("Options", "labelTransifexPwd"), + labelTransifexI18NLabel("Options", "labelTransifexI18NLabel"), + labelTransifexI18N("Options", "labelTransifexI18N") { + try { + containerName = "Options"; + this-> + parentUI = parentUI; + Lang & + lang = Lang::getInstance(); + Config & + config = Config::getInstance(); + + this-> + console. + setOnlyChatMessagesInStoredLines(false); + activeInputLabel = NULL; + + int + leftLabelStart = 100; + int + leftColumnStart = leftLabelStart + 300; + int + buttonRowPos = 50; + int + buttonStartPos = 170; + int + lineOffset = 30; + int + tabButtonWidth = 200; + int + tabButtonHeight = 30; + + mainMessageBox. + init(lang.getString("Ok")); + mainMessageBox. + setEnabled(false); + mainMessageBoxState = 0; + + buttonAudioSection. + init(0, 720, tabButtonWidth, tabButtonHeight); + buttonAudioSection. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonAudioSection. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonAudioSection. + setText(lang.getString("Audio")); + // Video Section + buttonVideoSection. + init(200, 720, tabButtonWidth, tabButtonHeight); + buttonVideoSection. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonVideoSection. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonVideoSection. + setText(lang.getString("Video")); + //MiscSection + buttonMiscSection. + init(400, 700, tabButtonWidth, tabButtonHeight + 20); + buttonMiscSection. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonMiscSection. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonMiscSection. + setText(lang.getString("Misc")); + //NetworkSettings + buttonNetworkSettings. + init(600, 720, tabButtonWidth, tabButtonHeight); + buttonNetworkSettings. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonNetworkSettings. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonNetworkSettings. + setText(lang.getString("Network")); + + //KeyboardSetup + buttonKeyboardSetup. + init(800, 720, tabButtonWidth, tabButtonHeight); + buttonKeyboardSetup. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonKeyboardSetup. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonKeyboardSetup. + setText(lang.getString("Keyboardsetup")); + + int + currentLine = 650; // reset line pos + int + currentLabelStart = leftLabelStart; // set to right side + int + currentColumnStart = leftColumnStart; // set to right side + + //lang + labelLang. + init(currentLabelStart, currentLine); + labelLang. + setText(lang.getString("Language")); + + listBoxLang. + init(currentColumnStart, currentLine, 375); + vector < + string > + langResults; + + languageList = Lang::getInstance().getDiscoveredLanguageList(true); + for (map < string, string >::iterator iterMap = languageList.begin(); + iterMap != languageList.end(); ++iterMap) { + langResults.push_back(iterMap->first + "-" + iterMap->second); + } + + listBoxLang. + setItems(langResults); + + pair < + string, + string > + defaultLang = + Lang::getInstance().getNavtiveNameFromLanguageName(config. + getString + ("Lang")); + if (defaultLang.first == "" && defaultLang.second == "") { + defaultLang = + Lang::getInstance(). + getNavtiveNameFromLanguageName(Lang::getInstance(). + getDefaultLanguage()); + } + listBoxLang. + setSelectedItem(defaultLang.second + "-" + defaultLang.first); + currentLine -= lineOffset; + + //playerName + labelPlayerNameLabel.init(currentLabelStart, currentLine); + labelPlayerNameLabel.setText(lang.getString("Playername")); + + labelPlayerName.init(currentColumnStart, currentLine); + labelPlayerName.setText(config. + getString("NetPlayerName", + Socket::getHostName().c_str())); + labelPlayerName.setFont(CoreData::getInstance().getMenuFontBig()); + labelPlayerName.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + labelPlayerName.setEditable(true); + labelPlayerName.setMaxEditWidth(16); + labelPlayerName.setMaxEditRenderWidth(200); + currentLine -= lineOffset; + + //FontSizeAdjustment + labelFontSizeAdjustment.init(currentLabelStart, currentLine); + labelFontSizeAdjustment.setText(lang. + getString("FontSizeAdjustment")); + + listFontSizeAdjustment.init(currentColumnStart, currentLine, 80); + for (int i = -5; i <= 5; i += 1) { + listFontSizeAdjustment.pushBackItem(intToStr(i)); + } + listFontSizeAdjustment. + setSelectedItem(intToStr(config.getInt("FontSizeAdjustment"))); + + currentLine -= lineOffset; + // Screenshot type flag + labelScreenShotType.init(currentLabelStart, currentLine); + labelScreenShotType.setText(lang.getString("ScreenShotFileType")); + + listBoxScreenShotType.init(currentColumnStart, currentLine, 80); + listBoxScreenShotType.pushBackItem("bmp"); + listBoxScreenShotType.pushBackItem("jpg"); + listBoxScreenShotType.pushBackItem("png"); + listBoxScreenShotType.pushBackItem("tga"); + listBoxScreenShotType.setSelectedItem(config. + getString + ("ScreenShotFileType", "jpg")); + + currentLine -= lineOffset; + + labelDisableScreenshotConsoleText.init(currentLabelStart, + currentLine); + labelDisableScreenshotConsoleText.setText(lang. + getString + ("ScreenShotConsoleText")); + + checkBoxDisableScreenshotConsoleText.init(currentColumnStart, + currentLine); + checkBoxDisableScreenshotConsoleText.setValue(!config. + getBool + ("DisableScreenshotConsoleText", + "false")); + + currentLine -= lineOffset; + + labelMouseMoveScrollsWorld.init(currentLabelStart, currentLine); + labelMouseMoveScrollsWorld.setText(lang. + getString("MouseScrollsWorld")); + + checkBoxMouseMoveScrollsWorld.init(currentColumnStart, currentLine); + checkBoxMouseMoveScrollsWorld.setValue(config. + getBool + ("MouseMoveScrollsWorld", + "true")); + currentLine -= lineOffset; + + //CameraMoveSpeed + labelCameraMoveSpeed.init(currentLabelStart, currentLine); + labelCameraMoveSpeed.setText(lang.getString("CameraMoveSpeed")); + + listCameraMoveSpeed.init(currentColumnStart, currentLine, 80); + for (int i = 15; i <= 50; i += 5) { + listCameraMoveSpeed.pushBackItem(intToStr(i)); + } + listCameraMoveSpeed. + setSelectedItem(intToStr + ((int) + (config.getFloat("CameraMoveSpeed", "15")))); + currentLine -= lineOffset; + + labelVisibleHud.init(currentLabelStart, currentLine); + labelVisibleHud.setText(lang.getString("VisibleHUD")); + + checkBoxVisibleHud.init(currentColumnStart, currentLine); + checkBoxVisibleHud.setValue(config.getBool("VisibleHud", "true")); + + currentLine -= lineOffset; + + labelHealthBars.init(currentLabelStart, currentLine); + labelHealthBars.setText(lang.getString("Healthbar")); + + listBoxHealthBars.init(currentColumnStart, currentLine, 375); + listBoxHealthBars.pushBackItem(lang. + getString + ("HealthbarsFactionDefault")); + listBoxHealthBars.pushBackItem(lang.getString("HealthbarsOff")); + listBoxHealthBars.pushBackItem(lang.getString("HealthbarsAlways")); + listBoxHealthBars.pushBackItem(lang. + getString("HealthbarsIfNeeded")); + listBoxHealthBars.pushBackItem(lang. + getString("HealthbarsSelected")); + listBoxHealthBars.pushBackItem(lang. + getString + ("HealthbarsSelectedOrNeeded")); + + int + hpMode = config.getInt("HealthBarMode", "4"); + int + hpIndex = 0; + switch (hpMode) { + case hbvUndefined: + hpIndex = 0; + break; + case hbvOff: + hpIndex = 1; + break; + case hbvAlways: + hpIndex = 2; + break; + case hbvIfNeeded: + hpIndex = 3; + break; + case hbvSelected: + hpIndex = 4; + break; + case hbvSelected | hbvIfNeeded: + hpIndex = 5; + break; + default: + hpIndex = 0; + break; + } + + listBoxHealthBars.setSelectedItemIndex(hpIndex); + + currentLine -= lineOffset; + + labelChatStaysActive.init(currentLabelStart, currentLine); + labelChatStaysActive.setText(lang.getString("ChatStaysActive")); + + checkBoxChatStaysActive.init(currentColumnStart, currentLine); + checkBoxChatStaysActive.setValue(config. + getBool("ChatStaysActive", + "false")); + + currentLine -= lineOffset; + + labelTimeDisplay.init(currentLabelStart, currentLine); + labelTimeDisplay.setText(lang.getString("TimeDisplay")); + + checkBoxTimeDisplay.init(currentColumnStart, currentLine); + checkBoxTimeDisplay.setValue(config.getBool("TimeDisplay", "true")); + + currentLine -= lineOffset; + + labelLuaDisableSecuritySandbox.init(currentLabelStart, currentLine); + labelLuaDisableSecuritySandbox.setText(lang. + getString + ("LuaDisableSecuritySandbox")); + + checkBoxLuaDisableSecuritySandbox.init(currentColumnStart, + currentLine); + checkBoxLuaDisableSecuritySandbox.setValue(config. + getBool + ("DisableLuaSandbox", + "false")); + + luaMessageBox.init(lang.getString("Yes"), lang.getString("No")); + luaMessageBox.setEnabled(false); + luaMessageBoxState = 0; + + currentLine -= lineOffset; + + currentLine -= lineOffset / 2; + + // buttons + buttonOk.init(buttonStartPos, buttonRowPos, 100); + buttonOk.setText(lang.getString("Save")); + + buttonReturn.init(buttonStartPos + 110, buttonRowPos, 100); + buttonReturn.setText(lang.getString("Return")); + + // Transifex related UI + currentLine -= lineOffset * 3; + labelCustomTranslation.init(currentLabelStart, currentLine); + labelCustomTranslation.setText(lang.getString("CustomTranslation")); + + checkBoxCustomTranslation.init(currentColumnStart, currentLine); + checkBoxCustomTranslation.setValue(false); + currentLine -= lineOffset; + + labelTransifexUserLabel.init(currentLabelStart, currentLine); + labelTransifexUserLabel.setText(lang. + getString("TransifexUserName")); + + labelTransifexPwdLabel.init(currentLabelStart + 260, currentLine); + labelTransifexPwdLabel.setText(lang.getString("TransifexPwd")); + + labelTransifexI18NLabel.init(currentLabelStart + 520, currentLine); + labelTransifexI18NLabel.setText(lang.getString("TransifexI18N")); + + currentLine -= lineOffset; + + labelTransifexUser.init(currentLabelStart, currentLine); + labelTransifexUser.setEditable(true); + labelTransifexUser.setMaxEditWidth(28); + labelTransifexUser.setMaxEditRenderWidth(250); + labelTransifexUser.setText(config. + getString("TranslationGetURLUser", + "")); + + labelTransifexPwd.init(currentLabelStart + 260, currentLine); + labelTransifexPwd.setIsPassword(true); + labelTransifexPwd.setEditable(true); + labelTransifexPwd.setMaxEditWidth(28); + labelTransifexPwd.setMaxEditRenderWidth(250); + labelTransifexPwd.setText(config. + getString("TranslationGetURLPassword", + "")); + + labelTransifexI18N.init(currentLabelStart + 520, currentLine); + labelTransifexI18N.setEditable(true); + labelTransifexI18N.setMaxEditWidth(6); + labelTransifexI18N.setMaxEditRenderWidth(70); + labelTransifexI18N.setText(config. + getString("TranslationGetURLLanguage", + "en")); + currentLine -= lineOffset; + + buttonGetNewLanguageFiles.init(currentLabelStart, currentLine, 250); + buttonGetNewLanguageFiles.setText(lang. + getString + ("TransifexGetLanguageFiles")); + + buttonDeleteNewLanguageFiles.init(currentLabelStart + 260, + currentLine, 250); + buttonDeleteNewLanguageFiles.setText(lang. + getString + ("TransifexDeleteLanguageFiles")); + + setupTransifexUI(); + + GraphicComponent::applyAllCustomProperties(containerName); + } catch (exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error loading options: %s\n", + __FILE__, __FUNCTION__, __LINE__, + e.what()); + throw + megaglest_runtime_error(string("Error loading options msg: ") + + e.what()); + } + } + + MenuStateOptions::~MenuStateOptions() { + } + + void + MenuStateOptions::reloadUI() { + Lang & lang = Lang::getInstance(); + + mainMessageBox.init(lang.getString("Ok")); + luaMessageBox.init(lang.getString("Yes"), lang.getString("No")); + + buttonAudioSection.setText(lang.getString("Audio")); + buttonVideoSection.setText(lang.getString("Video")); + buttonMiscSection.setText(lang.getString("Misc")); + buttonNetworkSettings.setText(lang.getString("Network")); + buttonKeyboardSetup.setText(lang.getString("Keyboardsetup")); + + labelVisibleHud.setText(lang.getString("VisibleHUD")); + labelHealthBars.setText(lang.getString("Healthbar")); + labelChatStaysActive.setText(lang.getString("ChatStaysActive")); + labelTimeDisplay.setText(lang.getString("TimeDisplay")); + + labelLuaDisableSecuritySandbox.setText(lang. + getString + ("LuaDisableSecuritySandbox")); + labelLang.setText(lang.getString("Language")); + labelPlayerNameLabel.setText(lang.getString("Playername")); + labelFontSizeAdjustment.setText(lang.getString("FontSizeAdjustment")); + labelScreenShotType.setText(lang.getString("ScreenShotFileType")); + labelDisableScreenshotConsoleText.setText(lang. + getString + ("ScreenShotConsoleText")); + labelMouseMoveScrollsWorld.setText(lang. + getString("MouseScrollsWorld")); + labelCameraMoveSpeed.setText(lang.getString("CameraMoveSpeed")); + + buttonOk.setText(lang.getString("Save")); + buttonReturn.setText(lang.getString("Return")); + + labelCustomTranslation.setText(lang.getString("CustomTranslation")); + buttonGetNewLanguageFiles.setText(lang. + getString + ("TransifexGetLanguageFiles")); + buttonDeleteNewLanguageFiles.setText(lang. + getString + ("TransifexDeleteLanguageFiles")); + labelTransifexUserLabel.setText(lang.getString("TransifexUserName")); + labelTransifexPwdLabel.setText(lang.getString("TransifexPwd")); + labelTransifexI18NLabel.setText(lang.getString("TransifexI18N")); + } + + void + MenuStateOptions::setupTransifexUI() { + buttonGetNewLanguageFiles.setEnabled(checkBoxCustomTranslation. + getValue()); + buttonDeleteNewLanguageFiles.setEnabled(checkBoxCustomTranslation. + getValue()); + labelTransifexUserLabel.setEnabled(checkBoxCustomTranslation. + getValue()); + labelTransifexUser.setEnabled(checkBoxCustomTranslation.getValue()); + labelTransifexPwdLabel.setEnabled(checkBoxCustomTranslation. + getValue()); + labelTransifexPwd.setEnabled(checkBoxCustomTranslation.getValue()); + labelTransifexI18NLabel.setEnabled(checkBoxCustomTranslation. + getValue()); + labelTransifexI18N.setEnabled(checkBoxCustomTranslation.getValue()); + } + + void + MenuStateOptions::showMessageBox(const string & text, + const string & header, bool toggle) { + if (!toggle) { + mainMessageBox.setEnabled(false); + } + + if (!mainMessageBox.getEnabled()) { + mainMessageBox.setText(text); + mainMessageBox.setHeader(header); + mainMessageBox.setEnabled(true); + } else { + mainMessageBox.setEnabled(false); + } + } + + void + MenuStateOptions::showLuaMessageBox(const string & text, + const string & header, bool toggle) { + if (!toggle) { + luaMessageBox.setEnabled(false); + } + + if (!luaMessageBox.getEnabled()) { + luaMessageBox.setText(text); + luaMessageBox.setHeader(header); + luaMessageBox.setEnabled(true); + } else { + luaMessageBox.setEnabled(false); + } + } + + void + MenuStateOptions::mouseClick(int x, int y, MouseButton mouseButton) { + + Config & config = Config::getInstance(); + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + + if (mainMessageBox.getEnabled()) { + int + button = 0; + if (mainMessageBox.mouseClick(x, y, button)) { + soundRenderer.playFx(coreData.getClickSoundA()); + if (button == 0) { + if (mainMessageBoxState == 1) { + mainMessageBoxState = 0; + mainMessageBox.setEnabled(false); + saveConfig(); + + Lang & lang = Lang::getInstance(); + mainMessageBox.init(lang.getString("Ok")); + mainMenu->setState(new MenuStateRoot(program, mainMenu)); + } else { + mainMessageBox.setEnabled(false); + + Lang & lang = Lang::getInstance(); + mainMessageBox.init(lang.getString("Ok")); + } + } else { + if (mainMessageBoxState == 1) { + mainMessageBoxState = 0; + mainMessageBox.setEnabled(false); + + Lang & lang = Lang::getInstance(); + mainMessageBox.init(lang.getString("Ok")); + } + } + } + } else if (luaMessageBox.getEnabled()) { + int + button = 0; + if (luaMessageBox.mouseClick(x, y, button)) { + checkBoxLuaDisableSecuritySandbox.setValue(false); + soundRenderer.playFx(coreData.getClickSoundA()); + if (button == 0) { + if (luaMessageBoxState == 1) { + checkBoxLuaDisableSecuritySandbox.setValue(true); + } + } + luaMessageBox.setEnabled(false); + } + } else if (checkBoxLuaDisableSecuritySandbox.mouseClick(x, y)) { + if (checkBoxLuaDisableSecuritySandbox.getValue() == true) { + checkBoxLuaDisableSecuritySandbox.setValue(false); + + luaMessageBoxState = 1; + Lang & lang = Lang::getInstance(); + showLuaMessageBox(lang. + getString("LuaDisableSecuritySandboxWarning"), + lang.getString("Question"), false); + } + } else if (buttonOk.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + + string + currentFontSizeAdjustment = config.getString("FontSizeAdjustment"); + string + selectedFontSizeAdjustment = + listFontSizeAdjustment.getSelectedItem(); + if (currentFontSizeAdjustment != selectedFontSizeAdjustment) { + mainMessageBoxState = 1; + Lang & lang = Lang::getInstance(); + showMessageBox(lang.getString("RestartNeeded"), + lang.getString("FontSizeAdjustmentChanged"), + false); + return; + } + saveConfig(); + //mainMenu->setState(new MenuStateRoot(program, mainMenu)); + reloadUI(); + return; + } else if (buttonReturn.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + if (this->parentUI != NULL) { + *this->parentUI = NULL; + delete * + this-> + parentUI; + } + mainMenu->setState(new MenuStateRoot(program, mainMenu)); + return; + } else if (buttonKeyboardSetup.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateKeysetup(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + //showMessageBox("Not implemented yet", "Keyboard setup", false); + return; + } else if (buttonAudioSection.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptionsSound(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + return; + } else if (buttonNetworkSettings.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptionsNetwork(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + return; + } else if (buttonMiscSection.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + //mainMenu->setState(new MenuStateOptions(program, mainMenu,this->parentUI)); // open keyboard shortcuts setup screen + return; + } else if (buttonVideoSection.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptionsGraphics(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + return; + } else if (checkBoxCustomTranslation.mouseClick(x, y)) { + setupTransifexUI(); + } else if (buttonDeleteNewLanguageFiles.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + + setActiveInputLable(NULL); + + if (labelTransifexI18N.getText() != "") { + Lang & lang = Lang::getInstance(); + string + language = lang.getLanguageFile(labelTransifexI18N.getText()); + replaceAll(language, "(", ""); + replaceAll(language, ")", ""); + + if (language != "") { + bool + foundFilesToDelete = false; + + Config & config = Config::getInstance(); + string + data_path = config.getString("UserData_Root", ""); + if (data_path != "") { + endPathWithSlash(data_path); + } + + if (data_path != "") { + + string + txnURLFileListMapping = + Config::getInstance(). + getString("TranslationGetURLFileListMapping"); + vector < string > languageFileMappings; + Tokenize(txnURLFileListMapping, languageFileMappings, "|"); + + Config & config = Config::getInstance(); + + // Cleanup Scenarios + vector < string > scenarioPaths = + config.getPathListForType(ptScenarios); + if (scenarioPaths.size() > 1) { + string & scenarioPath = scenarioPaths[1]; + endPathWithSlash(scenarioPath); + + vector < string > scenarioList; + findDirs(scenarioPath, scenarioList, false, false); + for (unsigned int i = 0; i < scenarioList.size(); ++i) { + string + scenario = scenarioList[i]; + + vector < string > langResults; + findAll(scenarioPath + scenario + "/*.lng", langResults, + false, false); + for (unsigned int j = 0; j < langResults.size(); ++j) { + string + testLanguage = langResults[j]; + + string + removeLngFile = + scenarioPath + scenario + "/" + testLanguage; + + if (EndsWith(testLanguage, language + ".lng") == true) { + + for (unsigned int k = 0; + k < languageFileMappings.size(); ++k) { + string + mapping = languageFileMappings[k]; + replaceAll(mapping, "$language", language); + + //printf("Comparing found [%s] with [%s]\n",removeLngFile.c_str(),mapping.c_str()); + + if (EndsWith(removeLngFile, mapping) == true) { + printf("About to delete file [%s]\n", + removeLngFile.c_str()); + removeFile(removeLngFile); + foundFilesToDelete = true; + break; + } + } + } + } + } + } + + // Cleanup tutorials + vector < string > tutorialPaths = + config.getPathListForType(ptTutorials); + if (tutorialPaths.size() > 1) { + string & tutorialPath = tutorialPaths[1]; + endPathWithSlash(tutorialPath); + + vector < string > tutorialList; + findDirs(tutorialPath, tutorialList, false, false); + for (unsigned int i = 0; i < tutorialList.size(); ++i) { + string + tutorial = tutorialList[i]; + + vector < string > langResults; + findAll(tutorialPath + tutorial + "/*.lng", langResults, + false, false); + for (unsigned int j = 0; j < langResults.size(); ++j) { + string + testLanguage = langResults[j]; + + string + removeLngFile = + tutorialPath + tutorial + "/" + testLanguage; + if (EndsWith(testLanguage, language + ".lng") == true) { + + + for (unsigned int k = 0; + k < languageFileMappings.size(); ++k) { + string + mapping = languageFileMappings[k]; + replaceAll(mapping, "$language", language); + + //printf("Comparing found [%s] with [%s]\n",removeLngFile.c_str(),mapping.c_str()); + + if (EndsWith(removeLngFile, mapping) == true) { + printf("About to delete file [%s]\n", + removeLngFile.c_str()); + removeFile(removeLngFile); + foundFilesToDelete = true; + break; + } + } + } + } + } + } + + // Cleanup main and hint language files + string + mainLngFile = data_path + "data/lang/" + language + ".lng"; + if (fileExists(mainLngFile) == true) { + + for (unsigned int k = 0; k < languageFileMappings.size(); + ++k) { + string + mapping = languageFileMappings[k]; + replaceAll(mapping, "$language", language); + + if (EndsWith(mainLngFile, mapping) == true) { + printf("About to delete file [%s]\n", + mainLngFile.c_str()); + removeFile(mainLngFile); + foundFilesToDelete = true; + break; + } + } + } + + string + hintLngFile = + data_path + "data/lang/hint/hint_" + language + ".lng"; + if (fileExists(hintLngFile) == true) { + for (unsigned int k = 0; k < languageFileMappings.size(); + ++k) { + string + mapping = languageFileMappings[k]; + replaceAll(mapping, "$language", language); + + if (EndsWith(hintLngFile, mapping) == true) { + printf("About to delete file [%s]\n", + hintLngFile.c_str()); + removeFile(hintLngFile); + foundFilesToDelete = true; + break; + } + } + } + } + + if (lang.isLanguageLocal(toLower(language)) == true) { + lang.loadGameStrings(toLower(language)); + } + + if (foundFilesToDelete == true) { + mainMessageBoxState = 0; + Lang & lang = Lang::getInstance(); + showMessageBox(lang.getString("TransifexDeleteSuccess"), + lang.getString("Notice"), false); + } + } + } + } else if (buttonGetNewLanguageFiles.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + + setActiveInputLable(NULL); + + string + orig_txnURLUser = + Config::getInstance().getString("TranslationGetURLUser"); + //string orig_txnURLPwd = Config::getInstance().getString("TranslationGetURLPassword",""); + string + orig_txnURLLang = + Config::getInstance().getString("TranslationGetURLLanguage"); + + Config::getInstance().setString("TranslationGetURLUser", + labelTransifexUser.getText()); + Config::getInstance().setString("TranslationGetURLPassword", + labelTransifexPwd.getText(), true); + Config::getInstance().setString("TranslationGetURLLanguage", + labelTransifexI18N.getText()); + + bool + saveChanges = (orig_txnURLUser != labelTransifexUser.getText() || + orig_txnURLLang != labelTransifexI18N.getText()); + + string + txnURL = Config::getInstance().getString("TranslationGetURL"); + string + txnURLUser = + Config::getInstance().getString("TranslationGetURLUser"); + string + txnURLPwd = + Config::getInstance().getString("TranslationGetURLPassword"); + string + txnURLLang = + Config::getInstance().getString("TranslationGetURLLanguage"); + string + txnURLFileList = + Config::getInstance().getString("TranslationGetURLFileList"); + string + txnURLFileListMapping = + Config::getInstance(). + getString("TranslationGetURLFileListMapping"); + + string + txnURLDetails = + Config::getInstance().getString("TranslationGetURLDetails"); + + string + credentials = txnURLUser + ":" + txnURLPwd; + + printf("URL1 [%s] credentials [%s]\n", txnURL.c_str(), + credentials.c_str()); + + //txnURLUser = SystemFlags::escapeURL(txnURLUser,handle); + //replaceAll(txnURL,"$user",txnURLUser); + + //printf("URL2 [%s]\n",txnURL.c_str()); + + //txnURLPwd = SystemFlags::escapeURL(txnURLPwd,handle); + //replaceAll(txnURL,"$password",txnURLPwd); + + //printf("URL3 [%s]\n",txnURL.c_str()); + + replaceAll(txnURL, "$language", txnURLLang); + + printf("URL4 [%s]\n", txnURL.c_str()); + + //txnURLFileList + vector < string > languageFiles; + Tokenize(txnURLFileList, languageFiles, "|"); + + vector < string > languageFileMappings; + Tokenize(txnURLFileListMapping, languageFileMappings, "|"); + + printf("URL5 file count = " MG_SIZE_T_SPECIFIER ", " + MG_SIZE_T_SPECIFIER " [%s]\n", languageFiles.size(), + languageFileMappings.size(), + (languageFiles.empty() == + false ? languageFiles[0].c_str() : "")); + + if (languageFiles.empty() == false) { + + bool + gotDownloads = false; + bool + reloadLanguage = false; + string + langName = ""; + + CURL * + handle = SystemFlags::initHTTP(); + for (unsigned int i = 0; i < languageFiles.size(); ++i) { + string + fileURL = txnURL; + replaceAll(fileURL, "$file", languageFiles[i]); + + if (langName == "") { + // Get language name for file + string + fileURLDetails = txnURLDetails; + replaceAll(fileURLDetails, "$file", languageFiles[0]); + + printf(" i = %u Trying [%s]\n", i, fileURLDetails.c_str()); + curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); + curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(handle, CURLOPT_USERPWD, + credentials.c_str()); + std::string fileDataDetails = + SystemFlags::getHTTP(fileURLDetails, handle); + + // "available_languages": [ + // { + // "code_aliases": " ", + // "code": "ca", + // "name": "Catalan" + // }, + // { + // "code_aliases": " ", + // "code": "zh", + // "name": "Chinese" + // }, + // curl -i -L --user softcoder -X GET https://www.transifex.com/api/2/project/megaglest/resource/main-language-file/?details + + string + search_detail_key = "\"code\": \"" + txnURLLang + "\""; + size_t + posDetails = fileDataDetails.find(search_detail_key, 0); + if (posDetails != fileDataDetails.npos) { + posDetails = + fileDataDetails.find("\"name\": \"", + posDetails + + search_detail_key.length()); + + if (posDetails != fileDataDetails.npos) { + + size_t + posDetailsEnd = + fileDataDetails.find("\"", posDetails + 9); + + langName = + fileDataDetails.substr(posDetails + 9, + posDetailsEnd - (posDetails + 9)); + replaceAll(langName, ",", ""); + replaceAll(langName, "\\", ""); + replaceAll(langName, "/", ""); + replaceAll(langName, "?", ""); + replaceAll(langName, ":", ""); + replaceAll(langName, "@", ""); + replaceAll(langName, "!", ""); + replaceAll(langName, "*", ""); + replaceAll(langName, "(", ""); + replaceAll(langName, ")", ""); + langName = trim(langName); + replaceAll(langName, " ", "-"); + } + + printf("PARSED Language filename [%s]\n", langName.c_str()); + } + } + + printf("i = %u Trying [%s]\n", i, fileURL.c_str()); + curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); + curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(handle, CURLOPT_USERPWD, credentials.c_str()); + std::string fileData = SystemFlags::getHTTP(fileURL, handle); + + // "content": " + // ", + // "mimetype": "text/plain" + size_t + pos = fileData.find("\"content\": \"", 0); + if (pos != fileData.npos) { + fileData = fileData.substr(pos + 12, fileData.length()); + + pos = fileData.find("\",\n", 0); + if (pos != fileData.npos) { + fileData = fileData.substr(0, pos); + } + + replaceAll(fileData, "\\\\n", "$requires-newline$"); + replaceAll(fileData, "\\n", "\n"); + replaceAll(fileData, "$requires-newline$", "\\n"); + + //replaceAll(fileData,""","\""); + replaceAllHTMLEntities(fileData); + + + printf("PARSED Language text\n[%s]\n", fileData.c_str()); + + //vector languageName; + //Tokenize(fileData,languageName," "); + //printf("PARSED Language Name guessed to be [%s]\n",languageName[1].c_str()); + + //string data_path= getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + //if(data_path != ""){ + //endPathWithSlash(data_path); + //} + Config & config = Config::getInstance(); + string + data_path = config.getString("UserData_Root", ""); + if (data_path != "") { + endPathWithSlash(data_path); + } + + string + outputFile = languageFileMappings[i]; + replaceAll(outputFile, "$language", toLower(langName)); + //string lngFile = getGameCustomCoreDataPath(data_path, "data/lang/" + toLower(languageName[1]) + ".lng"); + string + lngFile = getGameCustomCoreDataPath(data_path, outputFile); + + string + lngPath = extractDirectoryPathFromFile(lngFile); + createDirectoryPaths(lngPath); + + printf("Save data to Language Name [%s]\n", lngFile.c_str()); + saveDataToFile(lngFile, fileData); + gotDownloads = true; + + reloadLanguage = true; + if (saveChanges == true) { + saveChanges = false; + config.save(); + } + } else { + printf("UNPARSED Language text\n[%s]\n", fileData.c_str()); + } + } + + SystemFlags::cleanupHTTP(&handle); + + if (reloadLanguage == true && langName != "") { + Lang & lang = Lang::getInstance(); + if (lang.isLanguageLocal(toLower(langName)) == true) { + lang.loadGameStrings(toLower(langName)); + } + } + + if (gotDownloads == true) { + mainMessageBoxState = 0; + Lang & lang = Lang::getInstance(); + showMessageBox(lang.getString("TransifexDownloadSuccess") + + "\n" + langName, lang.getString("Notice"), + false); + } + } + return; + } else if (labelPlayerName.mouseClick(x, y) + && (activeInputLabel != &labelPlayerName)) { + setActiveInputLable(&labelPlayerName); + } else if (labelTransifexUser.mouseClick(x, y) + && (activeInputLabel != &labelTransifexUser)) { + setActiveInputLable(&labelTransifexUser); + } else if (labelTransifexPwd.mouseClick(x, y) + && (activeInputLabel != &labelTransifexPwd)) { + setActiveInputLable(&labelTransifexPwd); + } else if (labelTransifexI18N.mouseClick(x, y) + && (activeInputLabel != &labelTransifexI18N)) { + setActiveInputLable(&labelTransifexI18N); + } else { + listBoxLang.mouseClick(x, y); + listFontSizeAdjustment.mouseClick(x, y); + + listBoxScreenShotType.mouseClick(x, y); + + checkBoxDisableScreenshotConsoleText.mouseClick(x, y); + checkBoxMouseMoveScrollsWorld.mouseClick(x, y); + listCameraMoveSpeed.mouseClick(x, y); + checkBoxVisibleHud.mouseClick(x, y); + listBoxHealthBars.mouseClick(x, y); + checkBoxChatStaysActive.mouseClick(x, y); + checkBoxTimeDisplay.mouseClick(x, y); + checkBoxLuaDisableSecuritySandbox.mouseClick(x, y); + } + } + + void + MenuStateOptions::mouseMove(int x, int y, const MouseState * ms) { + if (mainMessageBox.getEnabled()) { + mainMessageBox.mouseMove(x, y); + } + if (luaMessageBox.getEnabled()) { + luaMessageBox.mouseMove(x, y); + } + + buttonOk.mouseMove(x, y); + buttonReturn.mouseMove(x, y); + buttonKeyboardSetup.mouseMove(x, y); + buttonAudioSection.mouseMove(x, y); + buttonNetworkSettings.mouseMove(x, y); + buttonMiscSection.mouseMove(x, y); + buttonVideoSection.mouseMove(x, y); + buttonGetNewLanguageFiles.mouseMove(x, y); + buttonDeleteNewLanguageFiles.mouseMove(x, y); + listBoxLang.mouseMove(x, y); + listBoxLang.mouseMove(x, y); + listFontSizeAdjustment.mouseMove(x, y); + listBoxScreenShotType.mouseMove(x, y); + checkBoxDisableScreenshotConsoleText.mouseMove(x, y); + checkBoxMouseMoveScrollsWorld.mouseMove(x, y); + listCameraMoveSpeed.mouseMove(x, y); + listBoxHealthBars.mouseMove(x, y); + checkBoxVisibleHud.mouseMove(x, y); + checkBoxChatStaysActive.mouseMove(x, y); + checkBoxTimeDisplay.mouseMove(x, y); + checkBoxLuaDisableSecuritySandbox.mouseMove(x, y); + checkBoxCustomTranslation.mouseMove(x, y); + } + + bool + MenuStateOptions::isInSpecialKeyCaptureEvent() { + return (activeInputLabel != NULL); + } + + void + MenuStateOptions::keyDown(SDL_KeyboardEvent key) { + if (activeInputLabel != NULL) { + keyDownEditLabel(key, &activeInputLabel); + } + } + + bool + MenuStateOptions::textInput(std::string text) { + if (activeInputLabel != NULL) { + //printf("[%d]\n",c); fflush(stdout); + if (&labelPlayerName == activeInputLabel || + &labelTransifexUser == activeInputLabel || + &labelTransifexPwd == activeInputLabel || + &labelTransifexI18N == activeInputLabel) { + return textInputEditLabel(text, &activeInputLabel); + } + } + return false; + } + + void + MenuStateOptions::keyPress(SDL_KeyboardEvent c) { + if (activeInputLabel != NULL) { + keyPressEditLabel(c, &activeInputLabel); + } else { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), c) == true) { + GraphicComponent::saveAllCustomProperties(containerName); + //Lang &lang= Lang::getInstance(); + //console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ? lang.getString("Yes") : lang.getString("No"))+ "]"); + } + } + } + + void + MenuStateOptions::render() { + Renderer & renderer = Renderer::getInstance(); + // char szBuf[8096]=""; + // snprintf(szBuf,8096,"\nIn [%s::%s Line: %d]\n\nRender options menu [%p]!\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this); + // printf(szBuf); + + if (mainMessageBox.getEnabled()) { + renderer.renderMessageBox(&mainMessageBox); + } else if (luaMessageBox.getEnabled()) { + renderer.renderMessageBox(&luaMessageBox); + } else { + renderer.renderButton(&buttonOk); + renderer.renderButton(&buttonReturn); + renderer.renderButton(&buttonKeyboardSetup); + renderer.renderButton(&buttonVideoSection); + renderer.renderButton(&buttonAudioSection); + renderer.renderButton(&buttonMiscSection); + renderer.renderButton(&buttonNetworkSettings); + + renderer.renderLabel(&labelCustomTranslation); + renderer.renderCheckBox(&checkBoxCustomTranslation); + + if (buttonGetNewLanguageFiles.getEnabled()) + renderer.renderButton(&buttonGetNewLanguageFiles); + if (buttonDeleteNewLanguageFiles.getEnabled()) + renderer.renderButton(&buttonDeleteNewLanguageFiles); + if (labelTransifexUserLabel.getEnabled()) + renderer.renderLabel(&labelTransifexUserLabel); + if (labelTransifexPwdLabel.getEnabled()) + renderer.renderLabel(&labelTransifexPwdLabel); + if (labelTransifexI18NLabel.getEnabled()) + renderer.renderLabel(&labelTransifexI18NLabel); + if (labelTransifexUser.getEnabled()) + renderer.renderLabel(&labelTransifexUser); + if (labelTransifexPwd.getEnabled()) + renderer.renderLabel(&labelTransifexPwd); + if (labelTransifexI18N.getEnabled()) + renderer.renderLabel(&labelTransifexI18N); + + renderer.renderListBox(&listBoxLang); + renderer.renderLabel(&labelLang); + renderer.renderLabel(&labelPlayerNameLabel); + renderer.renderLabel(&labelPlayerName); + renderer.renderListBox(&listFontSizeAdjustment); + renderer.renderLabel(&labelFontSizeAdjustment); + + renderer.renderLabel(&labelScreenShotType); + renderer.renderListBox(&listBoxScreenShotType); + + renderer.renderLabel(&labelDisableScreenshotConsoleText); + renderer.renderCheckBox(&checkBoxDisableScreenshotConsoleText); + + renderer.renderLabel(&labelMouseMoveScrollsWorld); + renderer.renderCheckBox(&checkBoxMouseMoveScrollsWorld); + renderer.renderLabel(&labelCameraMoveSpeed); + renderer.renderListBox(&listCameraMoveSpeed); + + renderer.renderLabel(&labelVisibleHud); + renderer.renderLabel(&labelHealthBars); + renderer.renderListBox(&listBoxHealthBars); + renderer.renderLabel(&labelChatStaysActive); + renderer.renderLabel(&labelTimeDisplay); + + renderer.renderLabel(&labelLuaDisableSecuritySandbox); + renderer.renderCheckBox(&checkBoxLuaDisableSecuritySandbox); + + renderer.renderCheckBox(&checkBoxVisibleHud); + renderer.renderCheckBox(&checkBoxChatStaysActive); + renderer.renderCheckBox(&checkBoxTimeDisplay); + + } + + renderer.renderConsole(&console); + if (program != NULL) + program->renderProgramMsgBox(); + } + + void + MenuStateOptions::saveConfig() { + Config & config = Config::getInstance(); + Lang & lang = Lang::getInstance(); + setActiveInputLable(NULL); + + if (labelPlayerName.getText().length() > 0) { + config.setString("NetPlayerName", labelPlayerName.getText()); + } + //Copy values + map < string, string >::iterator iterMap = languageList.begin(); + std::advance(iterMap, listBoxLang.getSelectedItemIndex()); + + config.setString("Lang", iterMap->first); + lang.loadGameStrings(config.getString("Lang")); + + config.setString("FontSizeAdjustment", + listFontSizeAdjustment.getSelectedItem()); + config.setString("ScreenShotFileType", + listBoxScreenShotType.getSelectedItem()); + + config.setBool("DisableScreenshotConsoleText", + !checkBoxDisableScreenshotConsoleText.getValue()); + config.setBool("MouseMoveScrollsWorld", + checkBoxMouseMoveScrollsWorld.getValue()); + config.setString("CameraMoveSpeed", + listCameraMoveSpeed.getSelectedItem()); + + int + hpIndex = listBoxHealthBars.getSelectedItemIndex(); + int + hpMode = hbvUndefined; + switch (hpIndex) { + case 0: + hpMode = hbvUndefined; + break; + case 1: + hpMode = hbvOff; + break; + case 2: + hpMode = hbvAlways; + break; + case 3: + hpMode = hbvIfNeeded; + break; + case 4: + hpMode = hbvSelected; + break; + case 5: + hpMode = hbvSelected | hbvIfNeeded; + break; + default: + hpMode = hbvUndefined; + break; + } + + config.setInt("HealthBarMode", hpMode); + config.setBool("VisibleHud", checkBoxVisibleHud.getValue()); + config.setBool("ChatStaysActive", checkBoxChatStaysActive.getValue()); + config.setBool("TimeDisplay", checkBoxTimeDisplay.getValue()); + + config.setBool("DisableLuaSandbox", + checkBoxLuaDisableSecuritySandbox.getValue()); + config.save(); + + if (config.getBool("DisableLuaSandbox", "false") == true) { + LuaScript::setDisableSandbox(true); + } + Renderer::getInstance().loadConfig(); + console.addLine(lang.getString("SettingsSaved")); + } + + void + MenuStateOptions::setActiveInputLable(GraphicLabel * newLable) { + MenuState::setActiveInputLabel(newLable, &activeInputLabel); + + if (newLable == &labelTransifexPwd) { + labelTransifexPwd.setIsPassword(false); + } else { + labelTransifexPwd.setIsPassword(true); + } + } + + } } //end namespace diff --git a/source/glest_game/menu/menu_state_options.h b/source/glest_game/menu/menu_state_options.h index 48653bb3a..4ce0f266e 100644 --- a/source/glest_game/menu/menu_state_options.h +++ b/source/glest_game/menu/menu_state_options.h @@ -15,110 +15,108 @@ # include "main_menu.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// =============================== -// class MenuStateOptions -// =============================== + // =============================== + // class MenuStateOptions + // =============================== - class MenuStateOptions:public MenuState - { - private: - GraphicButton buttonOk; - GraphicButton buttonReturn; + class MenuStateOptions :public MenuState { + private: + GraphicButton buttonOk; + GraphicButton buttonReturn; - GraphicLabel labelLang; - GraphicListBox listBoxLang; - GraphicLabel labelPlayerName; - GraphicLabel labelPlayerNameLabel; - GraphicLabel *activeInputLabel; + GraphicLabel labelLang; + GraphicListBox listBoxLang; + GraphicLabel labelPlayerName; + GraphicLabel labelPlayerNameLabel; + GraphicLabel *activeInputLabel; - GraphicButton buttonKeyboardSetup; // configure the keyboard - GraphicButton buttonVideoSection; - GraphicButton buttonAudioSection; - GraphicButton buttonMiscSection; - GraphicButton buttonNetworkSettings; + GraphicButton buttonKeyboardSetup; // configure the keyboard + GraphicButton buttonVideoSection; + GraphicButton buttonAudioSection; + GraphicButton buttonMiscSection; + GraphicButton buttonNetworkSettings; - GraphicLabel labelFontSizeAdjustment; - GraphicListBox listFontSizeAdjustment; + GraphicLabel labelFontSizeAdjustment; + GraphicListBox listFontSizeAdjustment; - GraphicMessageBox mainMessageBox; - int mainMessageBoxState; + GraphicMessageBox mainMessageBox; + int mainMessageBoxState; - GraphicLabel labelScreenShotType; - GraphicListBox listBoxScreenShotType; + GraphicLabel labelScreenShotType; + GraphicListBox listBoxScreenShotType; - GraphicLabel labelDisableScreenshotConsoleText; - GraphicCheckBox checkBoxDisableScreenshotConsoleText; + GraphicLabel labelDisableScreenshotConsoleText; + GraphicCheckBox checkBoxDisableScreenshotConsoleText; - GraphicLabel labelMouseMoveScrollsWorld; - GraphicCheckBox checkBoxMouseMoveScrollsWorld; + GraphicLabel labelMouseMoveScrollsWorld; + GraphicCheckBox checkBoxMouseMoveScrollsWorld; - GraphicLabel labelCameraMoveSpeed; - GraphicListBox listCameraMoveSpeed; + GraphicLabel labelCameraMoveSpeed; + GraphicListBox listCameraMoveSpeed; - GraphicLabel labelVisibleHud; - GraphicCheckBox checkBoxVisibleHud; - GraphicLabel labelHealthBars; - GraphicListBox listBoxHealthBars; + GraphicLabel labelVisibleHud; + GraphicCheckBox checkBoxVisibleHud; + GraphicLabel labelHealthBars; + GraphicListBox listBoxHealthBars; - GraphicLabel labelTimeDisplay; - GraphicCheckBox checkBoxTimeDisplay; - GraphicLabel labelChatStaysActive; - GraphicCheckBox checkBoxChatStaysActive; + GraphicLabel labelTimeDisplay; + GraphicCheckBox checkBoxTimeDisplay; + GraphicLabel labelChatStaysActive; + GraphicCheckBox checkBoxChatStaysActive; - GraphicLabel labelLuaDisableSecuritySandbox; - GraphicCheckBox checkBoxLuaDisableSecuritySandbox; + GraphicLabel labelLuaDisableSecuritySandbox; + GraphicCheckBox checkBoxLuaDisableSecuritySandbox; - GraphicMessageBox luaMessageBox; - int luaMessageBoxState; + GraphicMessageBox luaMessageBox; + int luaMessageBoxState; - map < string, string > languageList; + map < string, string > languageList; - GraphicLabel labelCustomTranslation; - GraphicCheckBox checkBoxCustomTranslation; + GraphicLabel labelCustomTranslation; + GraphicCheckBox checkBoxCustomTranslation; - GraphicButton buttonGetNewLanguageFiles; - GraphicButton buttonDeleteNewLanguageFiles; - GraphicLabel labelTransifexUserLabel; - GraphicLabel labelTransifexUser; - GraphicLabel labelTransifexPwdLabel; - GraphicLabel labelTransifexPwd; - GraphicLabel labelTransifexI18NLabel; - GraphicLabel labelTransifexI18N; + GraphicButton buttonGetNewLanguageFiles; + GraphicButton buttonDeleteNewLanguageFiles; + GraphicLabel labelTransifexUserLabel; + GraphicLabel labelTransifexUser; + GraphicLabel labelTransifexPwdLabel; + GraphicLabel labelTransifexPwd; + GraphicLabel labelTransifexI18NLabel; + GraphicLabel labelTransifexI18N; - ProgramState **parentUI; + ProgramState **parentUI; - public: - MenuStateOptions (Program * program, MainMenu * mainMenu, - ProgramState ** parentUI = NULL); - virtual ~ MenuStateOptions (); + public: + MenuStateOptions(Program * program, MainMenu * mainMenu, + ProgramState ** parentUI = NULL); + virtual ~MenuStateOptions(); - void mouseClick (int x, int y, MouseButton mouseButton); - void mouseMove (int x, int y, const MouseState * mouseState); - void render (); - virtual bool textInput (std::string text); - virtual void keyDown (SDL_KeyboardEvent key); - virtual void keyPress (SDL_KeyboardEvent c); - virtual bool isInSpecialKeyCaptureEvent (); + void mouseClick(int x, int y, MouseButton mouseButton); + void mouseMove(int x, int y, const MouseState * mouseState); + void render(); + virtual bool textInput(std::string text); + virtual void keyDown(SDL_KeyboardEvent key); + virtual void keyPress(SDL_KeyboardEvent c); + virtual bool isInSpecialKeyCaptureEvent(); - virtual void reloadUI (); + virtual void reloadUI(); - private: - void saveConfig (); - void setActiveInputLable (GraphicLabel * newLable); - void showMessageBox (const string & text, const string & header, - bool toggle); - void showLuaMessageBox (const string & text, const string & header, - bool toggle); + private: + void saveConfig(); + void setActiveInputLable(GraphicLabel * newLable); + void showMessageBox(const string & text, const string & header, + bool toggle); + void showLuaMessageBox(const string & text, const string & header, + bool toggle); - void setupTransifexUI (); - }; + void setupTransifexUI(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/menu/menu_state_options_graphics.cpp b/source/glest_game/menu/menu_state_options_graphics.cpp index b43f80301..6ae1a1471 100644 --- a/source/glest_game/menu/menu_state_options_graphics.cpp +++ b/source/glest_game/menu/menu_state_options_graphics.cpp @@ -30,1170 +30,1079 @@ #include "leak_dumper.h" using namespace - Shared::Util; +Shared::Util; namespace - Glest -{ - namespace - Game - { - -// ===================================================== -// class MenuStateOptions -// ===================================================== - MenuStateOptionsGraphics::MenuStateOptionsGraphics (Program * program, - MainMenu * mainMenu, - ProgramState ** - parentUI): - MenuState (program, mainMenu, "config"), - buttonOk ("Options_Graphics", "buttonOk"), - buttonReturn ("Options_Graphics", "buttonReturn"), - buttonAutoConfig ("Options_Graphics", "buttonAutoConfig"), - buttonVideoInfo ("Options_Graphics", "buttonVideoInfo"), - buttonKeyboardSetup ("Options_Graphics", "buttonKeyboardSetup"), - buttonVideoSection ("Options_Graphics", "buttonVideoSection"), - buttonAudioSection ("Options_Graphics", "buttonAudioSection"), - buttonMiscSection ("Options_Graphics", "buttonMiscSection"), - buttonNetworkSettings ("Options_Graphics", "buttonNetworkSettings"), - labelShadows ("Options_Graphics", "labelShadows"), - listBoxShadows ("Options_Graphics", "listBoxShadows"), - labelFilter ("Options_Graphics", "labelFilter"), - listBoxFilter ("Options_Graphics", "listBoxFilter"), - labelFilterMaxAnisotropy ("Options_Graphics", "labelFilterMaxAnisotropy"), - listBoxFilterMaxAnisotropy ("Options_Graphics", - "listBoxFilterMaxAnisotropy"), - labelTextures3D ("Options_Graphics", "labelTextures3D"), - checkBoxTextures3D ("Options_Graphics", "checkBoxTextures3D"), - labelLights ("Options_Graphics", "labelLights"), - listBoxLights ("Options_Graphics", "listBoxLights"), - labelUnitParticles ("Options_Graphics", "labelUnitParticles"), - checkBoxUnitParticles ("Options_Graphics", "checkBoxUnitParticles"), - labelTilesetParticles ("Options_Graphics", "labelTilesetParticles"), - checkBoxTilesetParticles ("Options_Graphics", "checkBoxTilesetParticles"), - labelAnimatedTilesetObjects ("Options_Graphics", - "labelAnimatedTilesetObjects"), - listBoxAnimatedTilesetObjects ("Options_Graphics", - "listBoxAnimatedTilesetObjects"), - labelScreenModes ("Options_Graphics", "labelScreenModes"), - listBoxScreenModes ("Options_Graphics", "listBoxScreenModes"), - labelFullscreenWindowed ("Options_Graphics", "labelFullscreenWindowed"), - checkBoxFullscreenWindowed ("Options_Graphics", - "checkBoxFullscreenWindowed"), - labelMapPreview ("Options_Graphics", "labelMapPreview"), - checkBoxMapPreview ("Options_Graphics", "checkBoxMapPreview"), - mainMessageBox ("Options_Graphics", "mainMessageBox"), - labelEnableTextureCompression ("Options_Graphics", - "labelEnableTextureCompression"), - checkBoxEnableTextureCompression ("Options_Graphics", - "checkBoxEnableTextureCompression"), - labelRainEffect ("Options_Graphics", "labelRainEffect"), - labelRainEffectSeparator ("Options_Graphics", "labelRainEffectSeparator"), - checkBoxRainEffect ("Options_Graphics", "checkBoxRainEffect"), - checkBoxRainEffectMenu ("Options_Graphics", "checkBoxRainEffectMenu"), - labelGammaCorrection ("Options_Graphics", "labelGammaCorrection"), - listBoxGammaCorrection ("Options_Graphics", "listBoxGammaCorrection"), - labelShadowIntensity ("Options_Graphics", "labelShadowIntensity"), - listBoxShadowIntensity ("Options_Graphics", "listBoxShadowIntensity"), - labelShadowTextureSize ("Options_Graphics", "labelShadowTextureSize"), - listBoxShadowTextureSize ("Options_Graphics", "listBoxShadowTextureSize"), - labelVideos ("Options_Graphics", "labelVideos"), - checkBoxVideos ("Options_Graphics", "checkBoxVideos"), - labelSelectionType ("Options_Graphics", "labelSelectionType"), - listBoxSelectionType ("Options_Graphics", "listBoxSelectionType") - { - try - { - containerName = "Options_Graphics"; - this-> - parentUI = parentUI; - Lang & - lang = Lang::getInstance (); - Config & - config = Config::getInstance (); - this-> - console. - setOnlyChatMessagesInStoredLines (false); - screenModeChangedTimer = time (NULL); // just init - - ::Shared::PlatformCommon::getFullscreenVideoModes (&modeInfos, - !config. - getBool - ("Windowed")); - - int - leftLabelStart = 100; - int - leftColumnStart = leftLabelStart + 300; - int - buttonRowPos = 50; - int - buttonStartPos = 170; - int - lineOffset = 30; - int - tabButtonWidth = 200; - int - tabButtonHeight = 30; - - mainMessageBox. - init (lang.getString ("Ok")); - mainMessageBox. - setEnabled (false); - mainMessageBoxState = 0; - - buttonAudioSection. - init (0, 720, tabButtonWidth, tabButtonHeight); - buttonAudioSection. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonAudioSection. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonAudioSection. - setText (lang.getString ("Audio")); - // Video Section - buttonVideoSection. - init (200, 700, tabButtonWidth, tabButtonHeight + 20); - buttonVideoSection. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonVideoSection. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonVideoSection. - setText (lang.getString ("Video")); - //MiscSection - buttonMiscSection. - init (400, 720, tabButtonWidth, tabButtonHeight); - buttonMiscSection. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonMiscSection. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonMiscSection. - setText (lang.getString ("Misc")); - //NetworkSettings - buttonNetworkSettings. - init (600, 720, tabButtonWidth, tabButtonHeight); - buttonNetworkSettings. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonNetworkSettings. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonNetworkSettings. - setText (lang.getString ("Network")); - - //KeyboardSetup - buttonKeyboardSetup. - init (800, 720, tabButtonWidth, tabButtonHeight); - buttonKeyboardSetup. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonKeyboardSetup. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonKeyboardSetup. - setText (lang.getString ("Keyboardsetup")); - - int - currentLine = 650; // reset line pos - int - currentLabelStart = leftLabelStart; // set to right side - int - currentColumnStart = leftColumnStart; // set to right side - - //resolution - labelScreenModes. - init (currentLabelStart, currentLine); - labelScreenModes. - setText (lang.getString ("Resolution")); - - listBoxScreenModes. - init (currentColumnStart, currentLine, 200); - - string - currentResString = config.getString ("ScreenWidth") + "x" + - config.getString ("ScreenHeight") + "-" + - intToStr (config.getInt ("ColorBits")); - bool - currentResolutionFound = false; - for (vector < ModeInfo >::const_iterator it = modeInfos.begin (); - it != modeInfos.end (); ++it) - { - if ((*it).getString () == currentResString) - { - currentResolutionFound = true; - } - listBoxScreenModes. - pushBackItem ((*it).getString ()); - } - if (currentResolutionFound == false) - { - listBoxScreenModes.pushBackItem (currentResString); - } - listBoxScreenModes.setSelectedItem (currentResString); - currentLine -= lineOffset; - - - //FullscreenWindowed - labelFullscreenWindowed.init (currentLabelStart, currentLine); - - checkBoxFullscreenWindowed.init (currentColumnStart, currentLine); - labelFullscreenWindowed.setText (lang.getString ("Windowed")); - checkBoxFullscreenWindowed.setValue (config.getBool ("Windowed")); - currentLine -= lineOffset; - - //gammaCorrection - labelGammaCorrection.init (currentLabelStart, currentLine); - labelGammaCorrection.setText (lang.getString ("GammaCorrection")); - - listBoxGammaCorrection.init (currentColumnStart, currentLine, 200); - for (float f = 0.5; f < 3.0f; f = f + 0.1f) - { - listBoxGammaCorrection.pushBackItem (floatToStr (f)); - } - float - gammaValue = config.getFloat ("GammaValue", "1.0"); - if (gammaValue == 0.0f) - gammaValue = 1.0f; - listBoxGammaCorrection.setSelectedItem (floatToStr (gammaValue), - false); - - currentLine -= lineOffset; - - //filter - labelFilter.init (currentLabelStart, currentLine); - labelFilter.setText (lang.getString ("Filter")); - - listBoxFilter.init (currentColumnStart, currentLine, 200); - listBoxFilter.pushBackItem ("Bilinear"); - listBoxFilter.pushBackItem ("Trilinear"); - listBoxFilter.setSelectedItem (config.getString ("Filter")); - currentLine -= lineOffset; - - //FilterMaxAnisotropy - labelFilterMaxAnisotropy.init (currentLabelStart, currentLine); - labelFilterMaxAnisotropy.setText (lang. - getString ("FilterMaxAnisotropy")); - - listBoxFilterMaxAnisotropy.init (currentColumnStart, currentLine, - 200); - listBoxFilterMaxAnisotropy.pushBackItem ("1"); - listBoxFilterMaxAnisotropy.pushBackItem ("2"); - listBoxFilterMaxAnisotropy.pushBackItem ("4"); - listBoxFilterMaxAnisotropy.pushBackItem ("8"); - listBoxFilterMaxAnisotropy.pushBackItem ("16"); - listBoxFilterMaxAnisotropy.setSelectedItem (config. - getString - ("FilterMaxAnisotropy", - "1")); - currentLine -= lineOffset; - - //selectionType - labelSelectionType.init (currentLabelStart, currentLine); - labelSelectionType.setText (lang.getString ("SelectionType")); - - listBoxSelectionType.init (currentColumnStart, currentLine, 250); - listBoxSelectionType.pushBackItem ("SelectBuffer (nvidia)"); - listBoxSelectionType.pushBackItem ("ColorPicking (default)"); - listBoxSelectionType.pushBackItem ("FrustumPicking (bad)"); - - const string - selectionType = - toLower (config.getString ("SelectionType", Config::colorPicking)); - if (selectionType == Config::colorPicking) - listBoxSelectionType.setSelectedItemIndex (1); - else if (selectionType == Config::frustumPicking) - listBoxSelectionType.setSelectedItemIndex (2); - else - listBoxSelectionType.setSelectedItemIndex (0); - currentLine -= lineOffset; - - //shadows - labelShadows.init (currentLabelStart, currentLine); - labelShadows.setText (lang.getString ("Shadows")); - - listBoxShadows.init (currentColumnStart, currentLine, 250); - for (int i = 0; i < Renderer::sCount; ++i) - { - listBoxShadows.pushBackItem (lang. - getString (Renderer:: - shadowsToStr (static_cast < - Renderer:: - Shadows > - (i)))); - } - string - str = config.getString ("Shadows"); - listBoxShadows. - setSelectedItemIndex (clamp - (Renderer::strToShadows (str), 0, - Renderer::sCount - 1)); - currentLine -= lineOffset; - - //shadows - labelShadowTextureSize.init (currentLabelStart, currentLine); - labelShadowTextureSize.setText (lang.getString ("ShadowTextureSize")); - - listBoxShadowTextureSize.init (currentColumnStart, currentLine, 200); - listBoxShadowTextureSize.pushBackItem ("256"); - listBoxShadowTextureSize.pushBackItem ("512"); - listBoxShadowTextureSize.pushBackItem ("1024"); - listBoxShadowTextureSize.setSelectedItemIndex (1, false); - listBoxShadowTextureSize. - setSelectedItem (intToStr - (config.getInt ("ShadowTextureSize", "512")), - false); - currentLine -= lineOffset; - - //shadows - labelShadowIntensity.init (currentLabelStart, currentLine); - labelShadowIntensity.setText (lang.getString ("ShadowIntensity")); - - listBoxShadowIntensity.init (currentColumnStart, currentLine, 200); - for (float f = 0.5f; f < 3.0f; f = f + 0.1f) - { - listBoxShadowIntensity.pushBackItem (floatToStr (f)); - } - float - shadowIntensity = config.getFloat ("ShadowIntensity", "1.0"); - if (shadowIntensity <= 0.0f) - shadowIntensity = 1.0f; - listBoxShadowIntensity.setSelectedItem (floatToStr (shadowIntensity), - false); - - currentLine -= lineOffset; - - //textures 3d - labelTextures3D.init (currentLabelStart, currentLine); - - checkBoxTextures3D.init (currentColumnStart, currentLine); - labelTextures3D.setText (lang.getString ("Textures3D")); - checkBoxTextures3D.setValue (config.getBool ("Textures3D")); - currentLine -= lineOffset; - - //lights - labelLights.init (currentLabelStart, currentLine); - labelLights.setText (lang.getString ("MaxLights")); - - listBoxLights.init (currentColumnStart, currentLine, 80); - for (int i = 1; i <= 8; ++i) - { - listBoxLights.pushBackItem (intToStr (i)); - } - listBoxLights. - setSelectedItemIndex (clamp - (config.getInt ("MaxLights") - 1, 0, 7)); - currentLine -= lineOffset; - - //unit particles - labelUnitParticles.init (currentLabelStart, currentLine); - labelUnitParticles.setText (lang.getString ("ShowUnitParticles")); - - checkBoxUnitParticles.init (currentColumnStart, currentLine); - checkBoxUnitParticles.setValue (config. - getBool ("UnitParticles", "true")); - currentLine -= lineOffset; - - //tileset particles - labelTilesetParticles.init (currentLabelStart, currentLine); - labelTilesetParticles.setText (lang. - getString ("ShowTilesetParticles")); - - checkBoxTilesetParticles.init (currentColumnStart, currentLine); - checkBoxTilesetParticles.setValue (config. - getBool ("TilesetParticles", - "true")); - currentLine -= lineOffset; - - //animated tileset objects - labelAnimatedTilesetObjects.init (currentLabelStart, currentLine); - labelAnimatedTilesetObjects.setText (lang. - getString - ("AnimatedTilesetObjects")); - - listBoxAnimatedTilesetObjects.init (currentColumnStart, currentLine, - 80); - listBoxAnimatedTilesetObjects.pushBackItem ("0"); - listBoxAnimatedTilesetObjects.pushBackItem ("10"); - listBoxAnimatedTilesetObjects.pushBackItem ("25"); - listBoxAnimatedTilesetObjects.pushBackItem ("50"); - listBoxAnimatedTilesetObjects.pushBackItem ("100"); - listBoxAnimatedTilesetObjects.pushBackItem ("300"); - listBoxAnimatedTilesetObjects.pushBackItem ("500"); - listBoxAnimatedTilesetObjects.pushBackItem ("∞"); - listBoxAnimatedTilesetObjects.setSelectedItem ("∞", true); - listBoxAnimatedTilesetObjects.setSelectedItem (config. - getString - ("AnimatedTilesetObjects", - "-1"), false); - currentLine -= lineOffset; - - //unit particles - labelMapPreview.init (currentLabelStart, currentLine); - labelMapPreview.setText (lang.getString ("ShowMapPreview")); - - checkBoxMapPreview.init (currentColumnStart, currentLine); - checkBoxMapPreview.setValue (config.getBool ("MapPreview", "true")); - currentLine -= lineOffset; - - // Texture Compression flag - labelEnableTextureCompression.init (currentLabelStart, currentLine); - labelEnableTextureCompression.setText (lang. - getString - ("EnableTextureCompression")); - - checkBoxEnableTextureCompression.init (currentColumnStart, - currentLine); - checkBoxEnableTextureCompression.setValue (config. - getBool - ("EnableTextureCompression", - "false")); - currentLine -= lineOffset; - - labelRainEffect.init (currentLabelStart, currentLine); - labelRainEffect.setText (lang.getString ("RainEffectMenuGame")); - - checkBoxRainEffectMenu.init (currentColumnStart, currentLine); - checkBoxRainEffectMenu.setValue (config. - getBool ("RainEffectMenu", "true")); - - labelRainEffectSeparator.init (currentColumnStart + 30, currentLine); - labelRainEffectSeparator.setText ("/"); - - checkBoxRainEffect.init (currentColumnStart + 42, currentLine); - checkBoxRainEffect.setValue (config.getBool ("RainEffect", "true")); - currentLine -= lineOffset; - - labelVideos.init (currentLabelStart, currentLine); - labelVideos.setText (lang.getString ("EnableVideos")); - - checkBoxVideos.init (currentColumnStart, currentLine); - checkBoxVideos.setValue (config.getBool ("EnableVideos", "true")); - - // end - - // external server port - - // buttons - buttonOk.init (buttonStartPos, buttonRowPos, 100); - buttonOk.setText (lang.getString ("Save")); - buttonReturn.setText (lang.getString ("Return")); - - buttonReturn.init (buttonStartPos + 110, buttonRowPos, 100); - buttonAutoConfig.setText (lang.getString ("AutoConfig")); - - buttonAutoConfig.init (buttonStartPos + 230, buttonRowPos, 175); - - buttonVideoInfo.setText (lang.getString ("VideoInfo")); - buttonVideoInfo.init (buttonStartPos + 415, buttonRowPos, 175); // was 620 - - GraphicComponent::applyAllCustomProperties (containerName); - } - catch (exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error loading options: %s\n", - __FILE__, __FUNCTION__, __LINE__, - e.what ()); - throw - megaglest_runtime_error (string ("Error loading options msg: ") + - e.what ()); - } - } - - void - MenuStateOptionsGraphics::reloadUI () - { - Lang & lang = Lang::getInstance (); - - mainMessageBox.init (lang.getString ("Ok")); - - buttonAudioSection.setText (lang.getString ("Audio")); - buttonVideoSection.setText (lang.getString ("Video")); - buttonMiscSection.setText (lang.getString ("Misc")); - buttonNetworkSettings.setText (lang.getString ("Network")); - - std::vector < string > listboxData; - listboxData.push_back ("None"); - listboxData.push_back ("OpenAL"); - - labelScreenModes.setText (lang.getString ("Resolution")); - - labelFullscreenWindowed.setText (lang.getString ("Windowed")); - labelFilter.setText (lang.getString ("Filter")); - - listboxData.clear (); - listboxData.push_back ("Bilinear"); - listboxData.push_back ("Trilinear"); - listBoxFilter.setItems (listboxData); - - labelFilterMaxAnisotropy.setText (lang. - getString ("FilterMaxAnisotropy")); - listboxData.clear (); - listboxData.push_back ("1"); - listboxData.push_back ("2"); - listboxData.push_back ("4"); - listboxData.push_back ("8"); - listboxData.push_back ("16"); - listBoxFilterMaxAnisotropy.setItems (listboxData); - - listboxData.clear (); - for (float f = 0.0; f < 2.1f; f = f + 0.1f) - { - listboxData.push_back (floatToStr (f)); - } - listBoxGammaCorrection.setItems (listboxData); - - - listboxData.clear (); - for (float f = 0.5; f < 3.0f; f = f + 0.1f) - { - listboxData.push_back (floatToStr (f)); - } - listBoxShadowIntensity.setItems (listboxData); - - - labelShadows.setText (lang.getString ("Shadows")); - labelShadowTextureSize.setText (lang.getString ("ShadowTextureSize")); - - labelShadowIntensity.setText (lang.getString ("ShadowIntensity")); - labelGammaCorrection.setText (lang.getString ("GammaCorrection")); - - listboxData.clear (); - for (int i = 0; i < Renderer::sCount; ++i) - { - listboxData.push_back (lang. - getString (Renderer:: - shadowsToStr (static_cast < - Renderer::Shadows > - (i)))); - } - listBoxShadows.setItems (listboxData); - - labelTextures3D.setText (lang.getString ("Textures3D")); - labelLights.setText (lang.getString ("MaxLights")); - labelUnitParticles.setText (lang.getString ("ShowUnitParticles")); - labelTilesetParticles.setText (lang.getString ("ShowTilesetParticles")); - labelAnimatedTilesetObjects.setText (lang. - getString - ("AnimatedTilesetObjects")); - labelMapPreview.setText (lang.getString ("ShowMapPreview")); - labelEnableTextureCompression.setText (lang. - getString - ("EnableTextureCompression")); - labelRainEffect.setText (lang.getString ("RainEffectMenuGame")); - labelVideos.setText (lang.getString ("EnableVideos")); - - buttonOk.setText (lang.getString ("Save")); - buttonReturn.setText (lang.getString ("Return")); - buttonAutoConfig.setText (lang.getString ("AutoConfig")); - buttonVideoInfo.setText (lang.getString ("VideoInfo")); - - labelSelectionType.setText (lang.getString ("SelectionType")); - } - - - void - MenuStateOptionsGraphics::showMessageBox (const string & text, - const string & header, - bool toggle) - { - if (!toggle) - { - mainMessageBox.setEnabled (false); - } - - if (!mainMessageBox.getEnabled ()) - { - mainMessageBox.setText (text); - mainMessageBox.setHeader (header); - mainMessageBox.setEnabled (true); - } - else - { - mainMessageBox.setEnabled (false); - } - } - - void - MenuStateOptionsGraphics::revertScreenMode () - { - Config & config = Config::getInstance (); - //!!! - // Revert resolution or fullscreen - checkBoxFullscreenWindowed.setValue (config.getBool ("Windowed")); - string - currentResString = config.getString ("ScreenWidth") + "x" + - config.getString ("ScreenHeight") + "-" + - intToStr (config.getInt ("ColorBits")); - listBoxScreenModes.setSelectedItem (currentResString); - - - changeVideoModeFullScreen (!config.getBool ("Windowed")); - WindowGl * - window = this->program->getWindow (); - window->ChangeVideoMode (true, - config.getInt ("ScreenWidth"), - config.getInt ("ScreenHeight"), - !config.getBool ("Windowed"), - config.getInt ("ColorBits"), - config.getInt ("DepthBits"), - config.getInt ("StencilBits"), - config.getBool ("HardwareAcceleration", - "false"), - config.getBool ("FullScreenAntiAliasing", - "false"), - config.getFloat ("GammaValue", "0.0")); - Metrics::reload (this->program->getWindow ()->getScreenWidth (), - this->program->getWindow ()->getScreenHeight ()); - window->setText (config.getString ("WindowTitle", "ZetaGlest")); - - this->mainMenu->init (); - } - - void - MenuStateOptionsGraphics::update () - { - if (mainMessageBox.getEnabled () && (mainMessageBoxState == 1)) - { - int - waitTime = 10; - if ((time (NULL) - screenModeChangedTimer > waitTime)) - { - mainMessageBoxState = 0; - mainMessageBox.setEnabled (false); - - Lang & lang = Lang::getInstance (); - mainMessageBox.init (lang.getString ("Ok")); - - revertScreenMode (); - } - else - { - Lang & lang = Lang::getInstance (); - int - timeToShow = waitTime - time (NULL) + screenModeChangedTimer; - // show timer in button - mainMessageBox.getButton (0)->setText (lang.getString ("Ok") + - " (" + - intToStr (timeToShow) + ")"); - } - } - } - - void - MenuStateOptionsGraphics::mouseClick (int x, int y, - MouseButton mouseButton) - { - - Config & config = Config::getInstance (); - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - - - - if (mainMessageBox.getEnabled ()) - { - int - button = 0; - - if (mainMessageBox.mouseClick (x, y, button)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - if (button == 0) - { - if (mainMessageBoxState == 1) - { - mainMessageBoxState = 0; - mainMessageBox.setEnabled (false); - saveConfig (); - - Lang & lang = Lang::getInstance (); - mainMessageBox.init (lang.getString ("Ok")); - //mainMenu->setState(new MenuStateOptions(program, mainMenu)); - } - else - { - mainMessageBox.setEnabled (false); - - Lang & lang = Lang::getInstance (); - mainMessageBox.init (lang.getString ("Ok")); - } - } - else - { - if (mainMessageBoxState == 1) - { - mainMessageBoxState = 0; - mainMessageBox.setEnabled (false); - - Lang & lang = Lang::getInstance (); - mainMessageBox.init (lang.getString ("Ok")); - - revertScreenMode (); - } - } - } - } - else if (buttonOk.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - Lang & lang = Lang::getInstance (); - bool - selectedFullscreenWindowed = checkBoxFullscreenWindowed.getValue (); - string - currentResolution = - config.getString ("ScreenWidth") + "x" + - config.getString ("ScreenHeight") + "-" + - intToStr (config.getInt ("ColorBits")); - string - selectedResolution = listBoxScreenModes.getSelectedItem (); - bool - currentFullscreenWindowed = config.getBool ("Windowed"); - if (currentResolution != selectedResolution - || currentFullscreenWindowed != selectedFullscreenWindowed) - { - - changeVideoModeFullScreen (!selectedFullscreenWindowed); - const ModeInfo * - selectedMode = NULL; - for (vector < ModeInfo >::const_iterator it = modeInfos.begin (); - it != modeInfos.end (); ++it) - { - if ((*it).getString () == selectedResolution) - { - //config.setInt("ScreenWidth",(*it).width); - //config.setInt("ScreenHeight",(*it).height); - //config.setInt("ColorBits",(*it).depth); - selectedMode = &(*it); - } - } - if (selectedMode == NULL) - { // if we cannot find the selectedResolution we try it with current one - for (vector < ModeInfo >::const_iterator it = modeInfos.begin (); - it != modeInfos.end (); ++it) - { - if ((*it).getString () == currentResolution) - { - //config.setInt("ScreenWidth",(*it).width); - //config.setInt("ScreenHeight",(*it).height); - //config.setInt("ColorBits",(*it).depth); - selectedMode = &(*it); - } - } - } - if (selectedMode == NULL) - { - throw - megaglest_runtime_error ("selectedMode == NULL"); - } + Glest { + namespace + Game { + + // ===================================================== + // class MenuStateOptions + // ===================================================== + MenuStateOptionsGraphics::MenuStateOptionsGraphics(Program * program, + MainMenu * mainMenu, + ProgramState ** + parentUI) : + MenuState(program, mainMenu, "config"), + buttonOk("Options_Graphics", "buttonOk"), + buttonReturn("Options_Graphics", "buttonReturn"), + buttonAutoConfig("Options_Graphics", "buttonAutoConfig"), + buttonVideoInfo("Options_Graphics", "buttonVideoInfo"), + buttonKeyboardSetup("Options_Graphics", "buttonKeyboardSetup"), + buttonVideoSection("Options_Graphics", "buttonVideoSection"), + buttonAudioSection("Options_Graphics", "buttonAudioSection"), + buttonMiscSection("Options_Graphics", "buttonMiscSection"), + buttonNetworkSettings("Options_Graphics", "buttonNetworkSettings"), + labelShadows("Options_Graphics", "labelShadows"), + listBoxShadows("Options_Graphics", "listBoxShadows"), + labelFilter("Options_Graphics", "labelFilter"), + listBoxFilter("Options_Graphics", "listBoxFilter"), + labelFilterMaxAnisotropy("Options_Graphics", "labelFilterMaxAnisotropy"), + listBoxFilterMaxAnisotropy("Options_Graphics", + "listBoxFilterMaxAnisotropy"), + labelTextures3D("Options_Graphics", "labelTextures3D"), + checkBoxTextures3D("Options_Graphics", "checkBoxTextures3D"), + labelLights("Options_Graphics", "labelLights"), + listBoxLights("Options_Graphics", "listBoxLights"), + labelUnitParticles("Options_Graphics", "labelUnitParticles"), + checkBoxUnitParticles("Options_Graphics", "checkBoxUnitParticles"), + labelTilesetParticles("Options_Graphics", "labelTilesetParticles"), + checkBoxTilesetParticles("Options_Graphics", "checkBoxTilesetParticles"), + labelAnimatedTilesetObjects("Options_Graphics", + "labelAnimatedTilesetObjects"), + listBoxAnimatedTilesetObjects("Options_Graphics", + "listBoxAnimatedTilesetObjects"), + labelScreenModes("Options_Graphics", "labelScreenModes"), + listBoxScreenModes("Options_Graphics", "listBoxScreenModes"), + labelFullscreenWindowed("Options_Graphics", "labelFullscreenWindowed"), + checkBoxFullscreenWindowed("Options_Graphics", + "checkBoxFullscreenWindowed"), + labelMapPreview("Options_Graphics", "labelMapPreview"), + checkBoxMapPreview("Options_Graphics", "checkBoxMapPreview"), + mainMessageBox("Options_Graphics", "mainMessageBox"), + labelEnableTextureCompression("Options_Graphics", + "labelEnableTextureCompression"), + checkBoxEnableTextureCompression("Options_Graphics", + "checkBoxEnableTextureCompression"), + labelRainEffect("Options_Graphics", "labelRainEffect"), + labelRainEffectSeparator("Options_Graphics", "labelRainEffectSeparator"), + checkBoxRainEffect("Options_Graphics", "checkBoxRainEffect"), + checkBoxRainEffectMenu("Options_Graphics", "checkBoxRainEffectMenu"), + labelGammaCorrection("Options_Graphics", "labelGammaCorrection"), + listBoxGammaCorrection("Options_Graphics", "listBoxGammaCorrection"), + labelShadowIntensity("Options_Graphics", "labelShadowIntensity"), + listBoxShadowIntensity("Options_Graphics", "listBoxShadowIntensity"), + labelShadowTextureSize("Options_Graphics", "labelShadowTextureSize"), + listBoxShadowTextureSize("Options_Graphics", "listBoxShadowTextureSize"), + labelVideos("Options_Graphics", "labelVideos"), + checkBoxVideos("Options_Graphics", "checkBoxVideos"), + labelSelectionType("Options_Graphics", "labelSelectionType"), + listBoxSelectionType("Options_Graphics", "listBoxSelectionType") { + try { + containerName = "Options_Graphics"; + this-> + parentUI = parentUI; + Lang & + lang = Lang::getInstance(); + Config & + config = Config::getInstance(); + this-> + console. + setOnlyChatMessagesInStoredLines(false); + screenModeChangedTimer = time(NULL); // just init + + ::Shared::PlatformCommon::getFullscreenVideoModes(&modeInfos, + !config. + getBool + ("Windowed")); + + int + leftLabelStart = 100; + int + leftColumnStart = leftLabelStart + 300; + int + buttonRowPos = 50; + int + buttonStartPos = 170; + int + lineOffset = 30; + int + tabButtonWidth = 200; + int + tabButtonHeight = 30; + + mainMessageBox. + init(lang.getString("Ok")); + mainMessageBox. + setEnabled(false); + mainMessageBoxState = 0; + + buttonAudioSection. + init(0, 720, tabButtonWidth, tabButtonHeight); + buttonAudioSection. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonAudioSection. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonAudioSection. + setText(lang.getString("Audio")); + // Video Section + buttonVideoSection. + init(200, 700, tabButtonWidth, tabButtonHeight + 20); + buttonVideoSection. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonVideoSection. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonVideoSection. + setText(lang.getString("Video")); + //MiscSection + buttonMiscSection. + init(400, 720, tabButtonWidth, tabButtonHeight); + buttonMiscSection. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonMiscSection. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonMiscSection. + setText(lang.getString("Misc")); + //NetworkSettings + buttonNetworkSettings. + init(600, 720, tabButtonWidth, tabButtonHeight); + buttonNetworkSettings. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonNetworkSettings. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonNetworkSettings. + setText(lang.getString("Network")); + + //KeyboardSetup + buttonKeyboardSetup. + init(800, 720, tabButtonWidth, tabButtonHeight); + buttonKeyboardSetup. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonKeyboardSetup. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonKeyboardSetup. + setText(lang.getString("Keyboardsetup")); + + int + currentLine = 650; // reset line pos + int + currentLabelStart = leftLabelStart; // set to right side + int + currentColumnStart = leftColumnStart; // set to right side + + //resolution + labelScreenModes. + init(currentLabelStart, currentLine); + labelScreenModes. + setText(lang.getString("Resolution")); + + listBoxScreenModes. + init(currentColumnStart, currentLine, 200); + + string + currentResString = config.getString("ScreenWidth") + "x" + + config.getString("ScreenHeight") + "-" + + intToStr(config.getInt("ColorBits")); + bool + currentResolutionFound = false; + for (vector < ModeInfo >::const_iterator it = modeInfos.begin(); + it != modeInfos.end(); ++it) { + if ((*it).getString() == currentResString) { + currentResolutionFound = true; + } + listBoxScreenModes. + pushBackItem((*it).getString()); + } + if (currentResolutionFound == false) { + listBoxScreenModes.pushBackItem(currentResString); + } + listBoxScreenModes.setSelectedItem(currentResString); + currentLine -= lineOffset; + + + //FullscreenWindowed + labelFullscreenWindowed.init(currentLabelStart, currentLine); + + checkBoxFullscreenWindowed.init(currentColumnStart, currentLine); + labelFullscreenWindowed.setText(lang.getString("Windowed")); + checkBoxFullscreenWindowed.setValue(config.getBool("Windowed")); + currentLine -= lineOffset; + + //gammaCorrection + labelGammaCorrection.init(currentLabelStart, currentLine); + labelGammaCorrection.setText(lang.getString("GammaCorrection")); + + listBoxGammaCorrection.init(currentColumnStart, currentLine, 200); + for (float f = 0.5; f < 3.0f; f = f + 0.1f) { + listBoxGammaCorrection.pushBackItem(floatToStr(f)); + } + float + gammaValue = config.getFloat("GammaValue", "1.0"); + if (gammaValue == 0.0f) + gammaValue = 1.0f; + listBoxGammaCorrection.setSelectedItem(floatToStr(gammaValue), + false); + + currentLine -= lineOffset; + + //filter + labelFilter.init(currentLabelStart, currentLine); + labelFilter.setText(lang.getString("Filter")); + + listBoxFilter.init(currentColumnStart, currentLine, 200); + listBoxFilter.pushBackItem("Bilinear"); + listBoxFilter.pushBackItem("Trilinear"); + listBoxFilter.setSelectedItem(config.getString("Filter")); + currentLine -= lineOffset; + + //FilterMaxAnisotropy + labelFilterMaxAnisotropy.init(currentLabelStart, currentLine); + labelFilterMaxAnisotropy.setText(lang. + getString("FilterMaxAnisotropy")); + + listBoxFilterMaxAnisotropy.init(currentColumnStart, currentLine, + 200); + listBoxFilterMaxAnisotropy.pushBackItem("1"); + listBoxFilterMaxAnisotropy.pushBackItem("2"); + listBoxFilterMaxAnisotropy.pushBackItem("4"); + listBoxFilterMaxAnisotropy.pushBackItem("8"); + listBoxFilterMaxAnisotropy.pushBackItem("16"); + listBoxFilterMaxAnisotropy.setSelectedItem(config. + getString + ("FilterMaxAnisotropy", + "1")); + currentLine -= lineOffset; + + //selectionType + labelSelectionType.init(currentLabelStart, currentLine); + labelSelectionType.setText(lang.getString("SelectionType")); + + listBoxSelectionType.init(currentColumnStart, currentLine, 250); + listBoxSelectionType.pushBackItem("SelectBuffer (nvidia)"); + listBoxSelectionType.pushBackItem("ColorPicking (default)"); + listBoxSelectionType.pushBackItem("FrustumPicking (bad)"); + + const string + selectionType = + toLower(config.getString("SelectionType", Config::colorPicking)); + if (selectionType == Config::colorPicking) + listBoxSelectionType.setSelectedItemIndex(1); + else if (selectionType == Config::frustumPicking) + listBoxSelectionType.setSelectedItemIndex(2); + else + listBoxSelectionType.setSelectedItemIndex(0); + currentLine -= lineOffset; + + //shadows + labelShadows.init(currentLabelStart, currentLine); + labelShadows.setText(lang.getString("Shadows")); + + listBoxShadows.init(currentColumnStart, currentLine, 250); + for (int i = 0; i < Renderer::sCount; ++i) { + listBoxShadows.pushBackItem(lang. + getString(Renderer:: + shadowsToStr(static_cast < + Renderer:: + Shadows> + (i)))); + } + string + str = config.getString("Shadows"); + listBoxShadows. + setSelectedItemIndex(clamp + (Renderer::strToShadows(str), 0, + Renderer::sCount - 1)); + currentLine -= lineOffset; + + //shadows + labelShadowTextureSize.init(currentLabelStart, currentLine); + labelShadowTextureSize.setText(lang.getString("ShadowTextureSize")); + + listBoxShadowTextureSize.init(currentColumnStart, currentLine, 200); + listBoxShadowTextureSize.pushBackItem("256"); + listBoxShadowTextureSize.pushBackItem("512"); + listBoxShadowTextureSize.pushBackItem("1024"); + listBoxShadowTextureSize.setSelectedItemIndex(1, false); + listBoxShadowTextureSize. + setSelectedItem(intToStr + (config.getInt("ShadowTextureSize", "512")), + false); + currentLine -= lineOffset; + + //shadows + labelShadowIntensity.init(currentLabelStart, currentLine); + labelShadowIntensity.setText(lang.getString("ShadowIntensity")); + + listBoxShadowIntensity.init(currentColumnStart, currentLine, 200); + for (float f = 0.5f; f < 3.0f; f = f + 0.1f) { + listBoxShadowIntensity.pushBackItem(floatToStr(f)); + } + float + shadowIntensity = config.getFloat("ShadowIntensity", "1.0"); + if (shadowIntensity <= 0.0f) + shadowIntensity = 1.0f; + listBoxShadowIntensity.setSelectedItem(floatToStr(shadowIntensity), + false); + + currentLine -= lineOffset; + + //textures 3d + labelTextures3D.init(currentLabelStart, currentLine); + + checkBoxTextures3D.init(currentColumnStart, currentLine); + labelTextures3D.setText(lang.getString("Textures3D")); + checkBoxTextures3D.setValue(config.getBool("Textures3D")); + currentLine -= lineOffset; + + //lights + labelLights.init(currentLabelStart, currentLine); + labelLights.setText(lang.getString("MaxLights")); + + listBoxLights.init(currentColumnStart, currentLine, 80); + for (int i = 1; i <= 8; ++i) { + listBoxLights.pushBackItem(intToStr(i)); + } + listBoxLights. + setSelectedItemIndex(clamp + (config.getInt("MaxLights") - 1, 0, 7)); + currentLine -= lineOffset; + + //unit particles + labelUnitParticles.init(currentLabelStart, currentLine); + labelUnitParticles.setText(lang.getString("ShowUnitParticles")); + + checkBoxUnitParticles.init(currentColumnStart, currentLine); + checkBoxUnitParticles.setValue(config. + getBool("UnitParticles", "true")); + currentLine -= lineOffset; + + //tileset particles + labelTilesetParticles.init(currentLabelStart, currentLine); + labelTilesetParticles.setText(lang. + getString("ShowTilesetParticles")); + + checkBoxTilesetParticles.init(currentColumnStart, currentLine); + checkBoxTilesetParticles.setValue(config. + getBool("TilesetParticles", + "true")); + currentLine -= lineOffset; + + //animated tileset objects + labelAnimatedTilesetObjects.init(currentLabelStart, currentLine); + labelAnimatedTilesetObjects.setText(lang. + getString + ("AnimatedTilesetObjects")); + + listBoxAnimatedTilesetObjects.init(currentColumnStart, currentLine, + 80); + listBoxAnimatedTilesetObjects.pushBackItem("0"); + listBoxAnimatedTilesetObjects.pushBackItem("10"); + listBoxAnimatedTilesetObjects.pushBackItem("25"); + listBoxAnimatedTilesetObjects.pushBackItem("50"); + listBoxAnimatedTilesetObjects.pushBackItem("100"); + listBoxAnimatedTilesetObjects.pushBackItem("300"); + listBoxAnimatedTilesetObjects.pushBackItem("500"); + listBoxAnimatedTilesetObjects.pushBackItem("∞"); + listBoxAnimatedTilesetObjects.setSelectedItem("∞", true); + listBoxAnimatedTilesetObjects.setSelectedItem(config. + getString + ("AnimatedTilesetObjects", + "-1"), false); + currentLine -= lineOffset; + + //unit particles + labelMapPreview.init(currentLabelStart, currentLine); + labelMapPreview.setText(lang.getString("ShowMapPreview")); + + checkBoxMapPreview.init(currentColumnStart, currentLine); + checkBoxMapPreview.setValue(config.getBool("MapPreview", "true")); + currentLine -= lineOffset; + + // Texture Compression flag + labelEnableTextureCompression.init(currentLabelStart, currentLine); + labelEnableTextureCompression.setText(lang. + getString + ("EnableTextureCompression")); + + checkBoxEnableTextureCompression.init(currentColumnStart, + currentLine); + checkBoxEnableTextureCompression.setValue(config. + getBool + ("EnableTextureCompression", + "false")); + currentLine -= lineOffset; + + labelRainEffect.init(currentLabelStart, currentLine); + labelRainEffect.setText(lang.getString("RainEffectMenuGame")); + + checkBoxRainEffectMenu.init(currentColumnStart, currentLine); + checkBoxRainEffectMenu.setValue(config. + getBool("RainEffectMenu", "true")); + + labelRainEffectSeparator.init(currentColumnStart + 30, currentLine); + labelRainEffectSeparator.setText("/"); + + checkBoxRainEffect.init(currentColumnStart + 42, currentLine); + checkBoxRainEffect.setValue(config.getBool("RainEffect", "true")); + currentLine -= lineOffset; + + labelVideos.init(currentLabelStart, currentLine); + labelVideos.setText(lang.getString("EnableVideos")); + + checkBoxVideos.init(currentColumnStart, currentLine); + checkBoxVideos.setValue(config.getBool("EnableVideos", "true")); + + // end + + // external server port + + // buttons + buttonOk.init(buttonStartPos, buttonRowPos, 100); + buttonOk.setText(lang.getString("Save")); + buttonReturn.setText(lang.getString("Return")); + + buttonReturn.init(buttonStartPos + 110, buttonRowPos, 100); + buttonAutoConfig.setText(lang.getString("AutoConfig")); + + buttonAutoConfig.init(buttonStartPos + 230, buttonRowPos, 175); + + buttonVideoInfo.setText(lang.getString("VideoInfo")); + buttonVideoInfo.init(buttonStartPos + 415, buttonRowPos, 175); // was 620 + + GraphicComponent::applyAllCustomProperties(containerName); + } catch (exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error loading options: %s\n", + __FILE__, __FUNCTION__, __LINE__, + e.what()); + throw + megaglest_runtime_error(string("Error loading options msg: ") + + e.what()); + } + } + + void + MenuStateOptionsGraphics::reloadUI() { + Lang & lang = Lang::getInstance(); + + mainMessageBox.init(lang.getString("Ok")); + + buttonAudioSection.setText(lang.getString("Audio")); + buttonVideoSection.setText(lang.getString("Video")); + buttonMiscSection.setText(lang.getString("Misc")); + buttonNetworkSettings.setText(lang.getString("Network")); + + std::vector < string > listboxData; + listboxData.push_back("None"); + listboxData.push_back("OpenAL"); + + labelScreenModes.setText(lang.getString("Resolution")); + + labelFullscreenWindowed.setText(lang.getString("Windowed")); + labelFilter.setText(lang.getString("Filter")); + + listboxData.clear(); + listboxData.push_back("Bilinear"); + listboxData.push_back("Trilinear"); + listBoxFilter.setItems(listboxData); + + labelFilterMaxAnisotropy.setText(lang. + getString("FilterMaxAnisotropy")); + listboxData.clear(); + listboxData.push_back("1"); + listboxData.push_back("2"); + listboxData.push_back("4"); + listboxData.push_back("8"); + listboxData.push_back("16"); + listBoxFilterMaxAnisotropy.setItems(listboxData); + + listboxData.clear(); + for (float f = 0.0; f < 2.1f; f = f + 0.1f) { + listboxData.push_back(floatToStr(f)); + } + listBoxGammaCorrection.setItems(listboxData); + + + listboxData.clear(); + for (float f = 0.5; f < 3.0f; f = f + 0.1f) { + listboxData.push_back(floatToStr(f)); + } + listBoxShadowIntensity.setItems(listboxData); + + + labelShadows.setText(lang.getString("Shadows")); + labelShadowTextureSize.setText(lang.getString("ShadowTextureSize")); + + labelShadowIntensity.setText(lang.getString("ShadowIntensity")); + labelGammaCorrection.setText(lang.getString("GammaCorrection")); + + listboxData.clear(); + for (int i = 0; i < Renderer::sCount; ++i) { + listboxData.push_back(lang. + getString(Renderer:: + shadowsToStr(static_cast < + Renderer::Shadows> + (i)))); + } + listBoxShadows.setItems(listboxData); + + labelTextures3D.setText(lang.getString("Textures3D")); + labelLights.setText(lang.getString("MaxLights")); + labelUnitParticles.setText(lang.getString("ShowUnitParticles")); + labelTilesetParticles.setText(lang.getString("ShowTilesetParticles")); + labelAnimatedTilesetObjects.setText(lang. + getString + ("AnimatedTilesetObjects")); + labelMapPreview.setText(lang.getString("ShowMapPreview")); + labelEnableTextureCompression.setText(lang. + getString + ("EnableTextureCompression")); + labelRainEffect.setText(lang.getString("RainEffectMenuGame")); + labelVideos.setText(lang.getString("EnableVideos")); + + buttonOk.setText(lang.getString("Save")); + buttonReturn.setText(lang.getString("Return")); + buttonAutoConfig.setText(lang.getString("AutoConfig")); + buttonVideoInfo.setText(lang.getString("VideoInfo")); + + labelSelectionType.setText(lang.getString("SelectionType")); + } + + + void + MenuStateOptionsGraphics::showMessageBox(const string & text, + const string & header, + bool toggle) { + if (!toggle) { + mainMessageBox.setEnabled(false); + } + + if (!mainMessageBox.getEnabled()) { + mainMessageBox.setText(text); + mainMessageBox.setHeader(header); + mainMessageBox.setEnabled(true); + } else { + mainMessageBox.setEnabled(false); + } + } + + void + MenuStateOptionsGraphics::revertScreenMode() { + Config & config = Config::getInstance(); + //!!! + // Revert resolution or fullscreen + checkBoxFullscreenWindowed.setValue(config.getBool("Windowed")); + string + currentResString = config.getString("ScreenWidth") + "x" + + config.getString("ScreenHeight") + "-" + + intToStr(config.getInt("ColorBits")); + listBoxScreenModes.setSelectedItem(currentResString); + + + changeVideoModeFullScreen(!config.getBool("Windowed")); + WindowGl * + window = this->program->getWindow(); + window->ChangeVideoMode(true, + config.getInt("ScreenWidth"), + config.getInt("ScreenHeight"), + !config.getBool("Windowed"), + config.getInt("ColorBits"), + config.getInt("DepthBits"), + config.getInt("StencilBits"), + config.getBool("HardwareAcceleration", + "false"), + config.getBool("FullScreenAntiAliasing", + "false"), + config.getFloat("GammaValue", "0.0")); + Metrics::reload(this->program->getWindow()->getScreenWidth(), + this->program->getWindow()->getScreenHeight()); + window->setText(config.getString("WindowTitle", "ZetaGlest")); + + this->mainMenu->init(); + } + + void + MenuStateOptionsGraphics::update() { + if (mainMessageBox.getEnabled() && (mainMessageBoxState == 1)) { + int + waitTime = 10; + if ((time(NULL) - screenModeChangedTimer > waitTime)) { + mainMessageBoxState = 0; + mainMessageBox.setEnabled(false); + + Lang & lang = Lang::getInstance(); + mainMessageBox.init(lang.getString("Ok")); + + revertScreenMode(); + } else { + Lang & lang = Lang::getInstance(); + int + timeToShow = waitTime - time(NULL) + screenModeChangedTimer; + // show timer in button + mainMessageBox.getButton(0)->setText(lang.getString("Ok") + + " (" + + intToStr(timeToShow) + ")"); + } + } + } + + void + MenuStateOptionsGraphics::mouseClick(int x, int y, + MouseButton mouseButton) { + + Config & config = Config::getInstance(); + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + + + + if (mainMessageBox.getEnabled()) { + int + button = 0; + + if (mainMessageBox.mouseClick(x, y, button)) { + soundRenderer.playFx(coreData.getClickSoundA()); + if (button == 0) { + if (mainMessageBoxState == 1) { + mainMessageBoxState = 0; + mainMessageBox.setEnabled(false); + saveConfig(); + + Lang & lang = Lang::getInstance(); + mainMessageBox.init(lang.getString("Ok")); + //mainMenu->setState(new MenuStateOptions(program, mainMenu)); + } else { + mainMessageBox.setEnabled(false); + + Lang & lang = Lang::getInstance(); + mainMessageBox.init(lang.getString("Ok")); + } + } else { + if (mainMessageBoxState == 1) { + mainMessageBoxState = 0; + mainMessageBox.setEnabled(false); + + Lang & lang = Lang::getInstance(); + mainMessageBox.init(lang.getString("Ok")); + + revertScreenMode(); + } + } + } + } else if (buttonOk.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + Lang & lang = Lang::getInstance(); + bool + selectedFullscreenWindowed = checkBoxFullscreenWindowed.getValue(); + string + currentResolution = + config.getString("ScreenWidth") + "x" + + config.getString("ScreenHeight") + "-" + + intToStr(config.getInt("ColorBits")); + string + selectedResolution = listBoxScreenModes.getSelectedItem(); + bool + currentFullscreenWindowed = config.getBool("Windowed"); + if (currentResolution != selectedResolution + || currentFullscreenWindowed != selectedFullscreenWindowed) { + + changeVideoModeFullScreen(!selectedFullscreenWindowed); + const ModeInfo * + selectedMode = NULL; + for (vector < ModeInfo >::const_iterator it = modeInfos.begin(); + it != modeInfos.end(); ++it) { + if ((*it).getString() == selectedResolution) { + //config.setInt("ScreenWidth",(*it).width); + //config.setInt("ScreenHeight",(*it).height); + //config.setInt("ColorBits",(*it).depth); + selectedMode = &(*it); + } + } + if (selectedMode == NULL) { // if we cannot find the selectedResolution we try it with current one + for (vector < ModeInfo >::const_iterator it = modeInfos.begin(); + it != modeInfos.end(); ++it) { + if ((*it).getString() == currentResolution) { + //config.setInt("ScreenWidth",(*it).width); + //config.setInt("ScreenHeight",(*it).height); + //config.setInt("ColorBits",(*it).depth); + selectedMode = &(*it); + } + } + } + if (selectedMode == NULL) { + throw + megaglest_runtime_error("selectedMode == NULL"); + } #if defined(__APPLE__) - mainMessageBoxState = 1; - mainMessageBox.init (lang.getString ("Ok"), - lang.getString ("Cancel")); - screenModeChangedTimer = time (NULL); + mainMessageBoxState = 1; + mainMessageBox.init(lang.getString("Ok"), + lang.getString("Cancel")); + screenModeChangedTimer = time(NULL); - showMessageBox (lang.getString ("RestartNeeded"), - lang.getString ("ResolutionChanged"), false); + showMessageBox(lang.getString("RestartNeeded"), + lang.getString("ResolutionChanged"), false); #else - WindowGl * - window = this->program->getWindow (); - window->ChangeVideoMode (true, - selectedMode->width, - selectedMode->height, - !selectedFullscreenWindowed, - selectedMode->depth, - config.getInt ("DepthBits"), - config.getInt ("StencilBits"), - config.getBool ("HardwareAcceleration", - "false"), - config.getBool ("FullScreenAntiAliasing", - "false"), - strToFloat (listBoxGammaCorrection. - getSelectedItem ())); + WindowGl * + window = this->program->getWindow(); + window->ChangeVideoMode(true, + selectedMode->width, + selectedMode->height, + !selectedFullscreenWindowed, + selectedMode->depth, + config.getInt("DepthBits"), + config.getInt("StencilBits"), + config.getBool("HardwareAcceleration", + "false"), + config.getBool("FullScreenAntiAliasing", + "false"), + strToFloat(listBoxGammaCorrection. + getSelectedItem())); - Metrics::reload (this->program->getWindow ()->getScreenWidth (), - this->program->getWindow ()->getScreenHeight ()); + Metrics::reload(this->program->getWindow()->getScreenWidth(), + this->program->getWindow()->getScreenHeight()); - this->mainMenu->init (); + this->mainMenu->init(); - mainMessageBoxState = 1; - mainMessageBox.init (lang.getString ("Ok"), - lang.getString ("Cancel")); - screenModeChangedTimer = time (NULL); + mainMessageBoxState = 1; + mainMessageBox.init(lang.getString("Ok"), + lang.getString("Cancel")); + screenModeChangedTimer = time(NULL); - showMessageBox (lang.getString ("ResolutionChanged"), - lang.getString ("Notice"), false); + showMessageBox(lang.getString("ResolutionChanged"), + lang.getString("Notice"), false); #endif - //No saveConfig() here! this is done by the messageBox - return; - } - saveConfig (); - return; - } - else if (buttonReturn.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); + //No saveConfig() here! this is done by the messageBox + return; + } + saveConfig(); + return; + } else if (buttonReturn.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); - // reset the gamma to former value - string - currentGammaCorrection = config.getString ("GammaValue", "1.0"); - string - selectedGammaCorrection = listBoxGammaCorrection.getSelectedItem (); - if (currentGammaCorrection != selectedGammaCorrection) - { - float - gammaValue = strToFloat (currentGammaCorrection); - if (gammaValue == 0.0f) - gammaValue = 1.0f; - if (gammaValue != 0.0) - { - program->getWindow ()->setGamma (gammaValue); - } - } - if (this->parentUI != NULL) - { - *this->parentUI = NULL; - delete * - this-> - parentUI; - } - mainMenu->setState (new MenuStateRoot (program, mainMenu)); - return; - } - else if (buttonKeyboardSetup.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - //mainMenu->setState(new MenuStateKeysetup(program, mainMenu)); // open keyboard shortcuts setup screen - //mainMenu->setState(new MenuStateOptionsGraphics(program, mainMenu)); // open keyboard shortcuts setup screen - //mainMenu->setState(new MenuStateOptionsNetwork(program, mainMenu)); // open keyboard shortcuts setup screen - mainMenu->setState (new MenuStateKeysetup (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - //showMessageBox("Not implemented yet", "Keyboard setup", false); - return; - } - else if (buttonAudioSection.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptionsSound (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - return; - } - else if (buttonNetworkSettings.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptionsNetwork (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - return; - } - else if (buttonMiscSection.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptions (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - return; - } - else if (buttonVideoSection.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - //mainMenu->setState(new MenuStateOptionsGraphics(program, mainMenu,this->parentUI)); // open keyboard shortcuts setup screen - return; - } - else if (buttonAutoConfig.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - Renderer::getInstance ().autoConfig (); - //saveConfig(); - mainMenu->setState (new MenuStateOptionsGraphics (program, mainMenu)); - return; - } - else if (buttonVideoInfo.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateGraphicInfo (program, mainMenu)); - return; - } - else - { - listBoxSelectionType.mouseClick (x, y); - listBoxShadows.mouseClick (x, y); - listBoxAnimatedTilesetObjects.mouseClick (x, y); - listBoxShadowTextureSize.mouseClick (x, y); - listBoxShadowIntensity.mouseClick (x, y); - listBoxFilter.mouseClick (x, y); - listBoxFilterMaxAnisotropy.mouseClick (x, y); - if (listBoxGammaCorrection.mouseClick (x, y)) - { - float - gammaValue = - strToFloat (listBoxGammaCorrection.getSelectedItem ()); - if (gammaValue != 0.0) - { - program->getWindow ()->setGamma (gammaValue); - } - } - checkBoxTextures3D.mouseClick (x, y); - checkBoxUnitParticles.mouseClick (x, y); - checkBoxTilesetParticles.mouseClick (x, y); - checkBoxMapPreview.mouseClick (x, y); - listBoxLights.mouseClick (x, y); - listBoxScreenModes.mouseClick (x, y); - checkBoxFullscreenWindowed.mouseClick (x, y); - checkBoxEnableTextureCompression.mouseClick (x, y); - checkBoxRainEffect.mouseClick (x, y); - checkBoxRainEffectMenu.mouseClick (x, y); + // reset the gamma to former value + string + currentGammaCorrection = config.getString("GammaValue", "1.0"); + string + selectedGammaCorrection = listBoxGammaCorrection.getSelectedItem(); + if (currentGammaCorrection != selectedGammaCorrection) { + float + gammaValue = strToFloat(currentGammaCorrection); + if (gammaValue == 0.0f) + gammaValue = 1.0f; + if (gammaValue != 0.0) { + program->getWindow()->setGamma(gammaValue); + } + } + if (this->parentUI != NULL) { + *this->parentUI = NULL; + delete * + this-> + parentUI; + } + mainMenu->setState(new MenuStateRoot(program, mainMenu)); + return; + } else if (buttonKeyboardSetup.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + //mainMenu->setState(new MenuStateKeysetup(program, mainMenu)); // open keyboard shortcuts setup screen + //mainMenu->setState(new MenuStateOptionsGraphics(program, mainMenu)); // open keyboard shortcuts setup screen + //mainMenu->setState(new MenuStateOptionsNetwork(program, mainMenu)); // open keyboard shortcuts setup screen + mainMenu->setState(new MenuStateKeysetup(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + //showMessageBox("Not implemented yet", "Keyboard setup", false); + return; + } else if (buttonAudioSection.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptionsSound(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + return; + } else if (buttonNetworkSettings.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptionsNetwork(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + return; + } else if (buttonMiscSection.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptions(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + return; + } else if (buttonVideoSection.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + //mainMenu->setState(new MenuStateOptionsGraphics(program, mainMenu,this->parentUI)); // open keyboard shortcuts setup screen + return; + } else if (buttonAutoConfig.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + Renderer::getInstance().autoConfig(); + //saveConfig(); + mainMenu->setState(new MenuStateOptionsGraphics(program, mainMenu)); + return; + } else if (buttonVideoInfo.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateGraphicInfo(program, mainMenu)); + return; + } else { + listBoxSelectionType.mouseClick(x, y); + listBoxShadows.mouseClick(x, y); + listBoxAnimatedTilesetObjects.mouseClick(x, y); + listBoxShadowTextureSize.mouseClick(x, y); + listBoxShadowIntensity.mouseClick(x, y); + listBoxFilter.mouseClick(x, y); + listBoxFilterMaxAnisotropy.mouseClick(x, y); + if (listBoxGammaCorrection.mouseClick(x, y)) { + float + gammaValue = + strToFloat(listBoxGammaCorrection.getSelectedItem()); + if (gammaValue != 0.0) { + program->getWindow()->setGamma(gammaValue); + } + } + checkBoxTextures3D.mouseClick(x, y); + checkBoxUnitParticles.mouseClick(x, y); + checkBoxTilesetParticles.mouseClick(x, y); + checkBoxMapPreview.mouseClick(x, y); + listBoxLights.mouseClick(x, y); + listBoxScreenModes.mouseClick(x, y); + checkBoxFullscreenWindowed.mouseClick(x, y); + checkBoxEnableTextureCompression.mouseClick(x, y); + checkBoxRainEffect.mouseClick(x, y); + checkBoxRainEffectMenu.mouseClick(x, y); - checkBoxVideos.mouseClick (x, y); - } - } + checkBoxVideos.mouseClick(x, y); + } + } - void - MenuStateOptionsGraphics::mouseMove (int x, int y, const MouseState * ms) - { - if (mainMessageBox.getEnabled ()) - { - mainMessageBox.mouseMove (x, y); - } + void + MenuStateOptionsGraphics::mouseMove(int x, int y, const MouseState * ms) { + if (mainMessageBox.getEnabled()) { + mainMessageBox.mouseMove(x, y); + } - buttonOk.mouseMove (x, y); - buttonReturn.mouseMove (x, y); - buttonKeyboardSetup.mouseMove (x, y); - buttonAudioSection.mouseMove (x, y); - buttonNetworkSettings.mouseMove (x, y); - buttonMiscSection.mouseMove (x, y); - buttonVideoSection.mouseMove (x, y); - buttonAutoConfig.mouseMove (x, y); - buttonVideoInfo.mouseMove (x, y); - listBoxFilter.mouseMove (x, y); - listBoxFilterMaxAnisotropy.mouseMove (x, y); - listBoxGammaCorrection.mouseMove (x, y); - listBoxShadowIntensity.mouseMove (x, y); - listBoxSelectionType.mouseMove (x, y); - listBoxShadows.mouseMove (x, y); - checkBoxTextures3D.mouseMove (x, y); - checkBoxUnitParticles.mouseMove (x, y); - checkBoxTilesetParticles.mouseMove (x, y); - labelAnimatedTilesetObjects.mouseMove (x, y); - listBoxAnimatedTilesetObjects.mouseMove (x, y); - checkBoxTilesetParticles.mouseMove (x, y); - checkBoxMapPreview.mouseMove (x, y); - listBoxLights.mouseMove (x, y); - listBoxScreenModes.mouseMove (x, y); - checkBoxFullscreenWindowed.mouseMove (x, y); - checkBoxEnableTextureCompression.mouseMove (x, y); + buttonOk.mouseMove(x, y); + buttonReturn.mouseMove(x, y); + buttonKeyboardSetup.mouseMove(x, y); + buttonAudioSection.mouseMove(x, y); + buttonNetworkSettings.mouseMove(x, y); + buttonMiscSection.mouseMove(x, y); + buttonVideoSection.mouseMove(x, y); + buttonAutoConfig.mouseMove(x, y); + buttonVideoInfo.mouseMove(x, y); + listBoxFilter.mouseMove(x, y); + listBoxFilterMaxAnisotropy.mouseMove(x, y); + listBoxGammaCorrection.mouseMove(x, y); + listBoxShadowIntensity.mouseMove(x, y); + listBoxSelectionType.mouseMove(x, y); + listBoxShadows.mouseMove(x, y); + checkBoxTextures3D.mouseMove(x, y); + checkBoxUnitParticles.mouseMove(x, y); + checkBoxTilesetParticles.mouseMove(x, y); + labelAnimatedTilesetObjects.mouseMove(x, y); + listBoxAnimatedTilesetObjects.mouseMove(x, y); + checkBoxTilesetParticles.mouseMove(x, y); + checkBoxMapPreview.mouseMove(x, y); + listBoxLights.mouseMove(x, y); + listBoxScreenModes.mouseMove(x, y); + checkBoxFullscreenWindowed.mouseMove(x, y); + checkBoxEnableTextureCompression.mouseMove(x, y); - checkBoxRainEffect.mouseMove (x, y); - checkBoxRainEffectMenu.mouseMove (x, y); + checkBoxRainEffect.mouseMove(x, y); + checkBoxRainEffectMenu.mouseMove(x, y); - checkBoxVideos.mouseMove (x, y); - } + checkBoxVideos.mouseMove(x, y); + } -//bool MenuStateOptionsGraphics::isInSpecialKeyCaptureEvent() { -// return (activeInputLabel != NULL); -//} -// -//void MenuStateOptionsGraphics::keyDown(SDL_KeyboardEvent key) { -// if(activeInputLabel != NULL) { -// keyDownEditLabel(key, &activeInputLabel); -// } -//} + //bool MenuStateOptionsGraphics::isInSpecialKeyCaptureEvent() { + // return (activeInputLabel != NULL); + //} + // + //void MenuStateOptionsGraphics::keyDown(SDL_KeyboardEvent key) { + // if(activeInputLabel != NULL) { + // keyDownEditLabel(key, &activeInputLabel); + // } + //} - void - MenuStateOptionsGraphics::keyPress (SDL_KeyboardEvent c) - { -// if(activeInputLabel != NULL) { -// //printf("[%d]\n",c); fflush(stdout); -// if( &labelPlayerName == activeInputLabel || -// &labelTransifexUser == activeInputLabel || -// &labelTransifexPwd == activeInputLabel || -// &labelTransifexI18N == activeInputLabel) { -// textInputEditLabel(c, &activeInputLabel); -// } -// } -// else { - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - if (isKeyPressed (configKeys.getSDLKey ("SaveGUILayout"), c) == true) - { - GraphicComponent::saveAllCustomProperties (containerName); - //Lang &lang= Lang::getInstance(); - //console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ? lang.getString("Yes") : lang.getString("No"))+ "]"); - } -// } - } + void + MenuStateOptionsGraphics::keyPress(SDL_KeyboardEvent c) { + // if(activeInputLabel != NULL) { + // //printf("[%d]\n",c); fflush(stdout); + // if( &labelPlayerName == activeInputLabel || + // &labelTransifexUser == activeInputLabel || + // &labelTransifexPwd == activeInputLabel || + // &labelTransifexI18N == activeInputLabel) { + // textInputEditLabel(c, &activeInputLabel); + // } + // } + // else { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), c) == true) { + GraphicComponent::saveAllCustomProperties(containerName); + //Lang &lang= Lang::getInstance(); + //console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ? lang.getString("Yes") : lang.getString("No"))+ "]"); + } + // } + } - void - MenuStateOptionsGraphics::render () - { - Renderer & renderer = Renderer::getInstance (); + void + MenuStateOptionsGraphics::render() { + Renderer & renderer = Renderer::getInstance(); - if (mainMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&mainMessageBox); - } - else - { - renderer.renderButton (&buttonOk); - renderer.renderButton (&buttonReturn); - renderer.renderButton (&buttonKeyboardSetup); - renderer.renderButton (&buttonVideoSection); - renderer.renderButton (&buttonAudioSection); - renderer.renderButton (&buttonMiscSection); - renderer.renderButton (&buttonNetworkSettings); - renderer.renderButton (&buttonAutoConfig); - renderer.renderButton (&buttonVideoInfo); - renderer.renderListBox (&listBoxShadows); - renderer.renderCheckBox (&checkBoxTextures3D); - renderer.renderCheckBox (&checkBoxUnitParticles); - renderer.renderCheckBox (&checkBoxTilesetParticles); - renderer.renderCheckBox (&checkBoxMapPreview); - renderer.renderListBox (&listBoxLights); - renderer.renderListBox (&listBoxFilter); - renderer.renderListBox (&listBoxFilterMaxAnisotropy); - renderer.renderListBox (&listBoxGammaCorrection); - renderer.renderListBox (&listBoxShadowIntensity); - renderer.renderLabel (&labelShadows); - renderer.renderLabel (&labelTextures3D); - renderer.renderLabel (&labelUnitParticles); - renderer.renderLabel (&labelTilesetParticles); - renderer.renderListBox (&listBoxAnimatedTilesetObjects); - renderer.renderLabel (&labelAnimatedTilesetObjects); - renderer.renderLabel (&labelMapPreview); - renderer.renderLabel (&labelLights); - renderer.renderLabel (&labelFilter); - renderer.renderLabel (&labelFilterMaxAnisotropy); - renderer.renderLabel (&labelGammaCorrection); - renderer.renderLabel (&labelShadowIntensity); - renderer.renderLabel (&labelScreenModes); - renderer.renderListBox (&listBoxScreenModes); - renderer.renderLabel (&labelFullscreenWindowed); - renderer.renderCheckBox (&checkBoxFullscreenWindowed); + if (mainMessageBox.getEnabled()) { + renderer.renderMessageBox(&mainMessageBox); + } else { + renderer.renderButton(&buttonOk); + renderer.renderButton(&buttonReturn); + renderer.renderButton(&buttonKeyboardSetup); + renderer.renderButton(&buttonVideoSection); + renderer.renderButton(&buttonAudioSection); + renderer.renderButton(&buttonMiscSection); + renderer.renderButton(&buttonNetworkSettings); + renderer.renderButton(&buttonAutoConfig); + renderer.renderButton(&buttonVideoInfo); + renderer.renderListBox(&listBoxShadows); + renderer.renderCheckBox(&checkBoxTextures3D); + renderer.renderCheckBox(&checkBoxUnitParticles); + renderer.renderCheckBox(&checkBoxTilesetParticles); + renderer.renderCheckBox(&checkBoxMapPreview); + renderer.renderListBox(&listBoxLights); + renderer.renderListBox(&listBoxFilter); + renderer.renderListBox(&listBoxFilterMaxAnisotropy); + renderer.renderListBox(&listBoxGammaCorrection); + renderer.renderListBox(&listBoxShadowIntensity); + renderer.renderLabel(&labelShadows); + renderer.renderLabel(&labelTextures3D); + renderer.renderLabel(&labelUnitParticles); + renderer.renderLabel(&labelTilesetParticles); + renderer.renderListBox(&listBoxAnimatedTilesetObjects); + renderer.renderLabel(&labelAnimatedTilesetObjects); + renderer.renderLabel(&labelMapPreview); + renderer.renderLabel(&labelLights); + renderer.renderLabel(&labelFilter); + renderer.renderLabel(&labelFilterMaxAnisotropy); + renderer.renderLabel(&labelGammaCorrection); + renderer.renderLabel(&labelShadowIntensity); + renderer.renderLabel(&labelScreenModes); + renderer.renderListBox(&listBoxScreenModes); + renderer.renderLabel(&labelFullscreenWindowed); + renderer.renderCheckBox(&checkBoxFullscreenWindowed); - renderer.renderLabel (&labelEnableTextureCompression); - renderer.renderCheckBox (&checkBoxEnableTextureCompression); + renderer.renderLabel(&labelEnableTextureCompression); + renderer.renderCheckBox(&checkBoxEnableTextureCompression); - renderer.renderLabel (&labelRainEffect); - renderer.renderCheckBox (&checkBoxRainEffect); - renderer.renderLabel (&labelRainEffectSeparator); - renderer.renderCheckBox (&checkBoxRainEffectMenu); + renderer.renderLabel(&labelRainEffect); + renderer.renderCheckBox(&checkBoxRainEffect); + renderer.renderLabel(&labelRainEffectSeparator); + renderer.renderCheckBox(&checkBoxRainEffectMenu); - renderer.renderLabel (&labelShadowTextureSize); - renderer.renderListBox (&listBoxShadowTextureSize); + renderer.renderLabel(&labelShadowTextureSize); + renderer.renderListBox(&listBoxShadowTextureSize); - renderer.renderLabel (&labelSelectionType); - renderer.renderListBox (&listBoxSelectionType); + renderer.renderLabel(&labelSelectionType); + renderer.renderListBox(&listBoxSelectionType); - renderer.renderLabel (&labelVideos); - renderer.renderCheckBox (&checkBoxVideos); - } + renderer.renderLabel(&labelVideos); + renderer.renderCheckBox(&checkBoxVideos); + } - renderer.renderConsole (&console); - if (program != NULL) - program->renderProgramMsgBox (); - } + renderer.renderConsole(&console); + if (program != NULL) + program->renderProgramMsgBox(); + } - void - MenuStateOptionsGraphics::saveConfig () - { - Config & config = Config::getInstance (); - Lang & lang = Lang::getInstance (); - //setActiveInputLable(NULL); + void + MenuStateOptionsGraphics::saveConfig() { + Config & config = Config::getInstance(); + Lang & lang = Lang::getInstance(); + //setActiveInputLable(NULL); - int - selectionTypeindex = listBoxSelectionType.getSelectedItemIndex (); - if (selectionTypeindex == 0) - { - config.setString ("SelectionType", Config::selectBufPicking); - } - else if (selectionTypeindex == 1) - { - config.setString ("SelectionType", Config::colorPicking); - } - else if (selectionTypeindex == 2) - { - config.setString ("SelectionType", Config::frustumPicking); - } + int + selectionTypeindex = listBoxSelectionType.getSelectedItemIndex(); + if (selectionTypeindex == 0) { + config.setString("SelectionType", Config::selectBufPicking); + } else if (selectionTypeindex == 1) { + config.setString("SelectionType", Config::colorPicking); + } else if (selectionTypeindex == 2) { + config.setString("SelectionType", Config::frustumPicking); + } - int - index = listBoxShadows.getSelectedItemIndex (); - config.setString ("Shadows", - Renderer::shadowsToStr (static_cast < - Renderer::Shadows > (index))); + int + index = listBoxShadows.getSelectedItemIndex(); + config.setString("Shadows", + Renderer::shadowsToStr(static_cast < + Renderer::Shadows> (index))); - string - texSizeString = listBoxShadowTextureSize.getSelectedItem (); - config.setInt ("ShadowTextureSize", strToInt (texSizeString)); + string + texSizeString = listBoxShadowTextureSize.getSelectedItem(); + config.setInt("ShadowTextureSize", strToInt(texSizeString)); - config.setBool ("Windowed", checkBoxFullscreenWindowed.getValue ()); - config.setString ("Filter", listBoxFilter.getSelectedItem ()); - config.setInt ("FilterMaxAnisotropy", - strToInt (listBoxFilterMaxAnisotropy. - getSelectedItem ())); - config.setFloat ("GammaValue", - strToFloat (listBoxGammaCorrection. - getSelectedItem ())); - config.setFloat ("ShadowIntensity", - strToFloat (listBoxShadowIntensity. - getSelectedItem ())); - config.setBool ("Textures3D", checkBoxTextures3D.getValue ()); - config.setBool ("UnitParticles", (checkBoxUnitParticles.getValue ())); - config.setBool ("TilesetParticles", - (checkBoxTilesetParticles.getValue ())); - config.setBool ("MapPreview", checkBoxMapPreview.getValue ()); - config.setInt ("MaxLights", listBoxLights.getSelectedItemIndex () + 1); + config.setBool("Windowed", checkBoxFullscreenWindowed.getValue()); + config.setString("Filter", listBoxFilter.getSelectedItem()); + config.setInt("FilterMaxAnisotropy", + strToInt(listBoxFilterMaxAnisotropy. + getSelectedItem())); + config.setFloat("GammaValue", + strToFloat(listBoxGammaCorrection. + getSelectedItem())); + config.setFloat("ShadowIntensity", + strToFloat(listBoxShadowIntensity. + getSelectedItem())); + config.setBool("Textures3D", checkBoxTextures3D.getValue()); + config.setBool("UnitParticles", (checkBoxUnitParticles.getValue())); + config.setBool("TilesetParticles", + (checkBoxTilesetParticles.getValue())); + config.setBool("MapPreview", checkBoxMapPreview.getValue()); + config.setInt("MaxLights", listBoxLights.getSelectedItemIndex() + 1); - if (listBoxAnimatedTilesetObjects.getSelectedItem () == "∞") - { - config.setInt ("AnimatedTilesetObjects", -1); - } - else - { - config.setInt ("AnimatedTilesetObjects", - atoi (listBoxAnimatedTilesetObjects.getSelectedItem (). - c_str ())); - } + if (listBoxAnimatedTilesetObjects.getSelectedItem() == "∞") { + config.setInt("AnimatedTilesetObjects", -1); + } else { + config.setInt("AnimatedTilesetObjects", + atoi(listBoxAnimatedTilesetObjects.getSelectedItem(). + c_str())); + } - config.setBool ("RainEffect", checkBoxRainEffect.getValue ()); - config.setBool ("RainEffectMenu", checkBoxRainEffectMenu.getValue ()); + config.setBool("RainEffect", checkBoxRainEffect.getValue()); + config.setBool("RainEffectMenu", checkBoxRainEffectMenu.getValue()); - config.setBool ("EnableTextureCompression", - checkBoxEnableTextureCompression.getValue ()); + config.setBool("EnableTextureCompression", + checkBoxEnableTextureCompression.getValue()); - config.setBool ("EnableVideos", checkBoxVideos.getValue ()); + config.setBool("EnableVideos", checkBoxVideos.getValue()); - string - currentResolution = - config.getString ("ScreenWidth") + "x" + - config.getString ("ScreenHeight"); - string - selectedResolution = listBoxScreenModes.getSelectedItem (); - if (currentResolution != selectedResolution) - { - for (vector < ModeInfo >::const_iterator it = modeInfos.begin (); - it != modeInfos.end (); ++it) - { - if ((*it).getString () == selectedResolution) - { - config.setInt ("ScreenWidth", (*it).width); - config.setInt ("ScreenHeight", (*it).height); - config.setInt ("ColorBits", (*it).depth); - } - } - } + string + currentResolution = + config.getString("ScreenWidth") + "x" + + config.getString("ScreenHeight"); + string + selectedResolution = listBoxScreenModes.getSelectedItem(); + if (currentResolution != selectedResolution) { + for (vector < ModeInfo >::const_iterator it = modeInfos.begin(); + it != modeInfos.end(); ++it) { + if ((*it).getString() == selectedResolution) { + config.setInt("ScreenWidth", (*it).width); + config.setInt("ScreenHeight", (*it).height); + config.setInt("ColorBits", (*it).depth); + } + } + } - config.save (); + config.save(); - if (config.getBool ("DisableLuaSandbox", "false") == true) - { - LuaScript::setDisableSandbox (true); - } + if (config.getBool("DisableLuaSandbox", "false") == true) { + LuaScript::setDisableSandbox(true); + } - Renderer::getInstance ().loadConfig (); - console.addLine (lang.getString ("SettingsSaved")); - } + Renderer::getInstance().loadConfig(); + console.addLine(lang.getString("SettingsSaved")); + } -//void MenuStateOptionsGraphics::setActiveInputLable(GraphicLabel *newLable) { -// MenuState::setActiveInputLabel(newLable,&activeInputLabel); -// -// if(newLable == &labelTransifexPwd) { -// labelTransifexPwd.setIsPassword(false); -// } -// else { -// labelTransifexPwd.setIsPassword(true); -// } -//} + //void MenuStateOptionsGraphics::setActiveInputLable(GraphicLabel *newLable) { + // MenuState::setActiveInputLabel(newLable,&activeInputLabel); + // + // if(newLable == &labelTransifexPwd) { + // labelTransifexPwd.setIsPassword(false); + // } + // else { + // labelTransifexPwd.setIsPassword(true); + // } + //} - } + } } //end namespace diff --git a/source/glest_game/menu/menu_state_options_graphics.h b/source/glest_game/menu/menu_state_options_graphics.h index ac7cf9898..867427a84 100644 --- a/source/glest_game/menu/menu_state_options_graphics.h +++ b/source/glest_game/menu/menu_state_options_graphics.h @@ -15,114 +15,112 @@ # include "main_menu.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// =============================== -// class MenuStateOptionsGraphics -// =============================== + // =============================== + // class MenuStateOptionsGraphics + // =============================== - class MenuStateOptionsGraphics:public MenuState - { - private: + class MenuStateOptionsGraphics :public MenuState { + private: - GraphicButton buttonOk; - GraphicButton buttonReturn; - GraphicButton buttonAutoConfig; - GraphicButton buttonVideoInfo; + GraphicButton buttonOk; + GraphicButton buttonReturn; + GraphicButton buttonAutoConfig; + GraphicButton buttonVideoInfo; - GraphicButton buttonKeyboardSetup; // configure the keyboard - GraphicButton buttonVideoSection; - GraphicButton buttonAudioSection; - GraphicButton buttonMiscSection; - GraphicButton buttonNetworkSettings; + GraphicButton buttonKeyboardSetup; // configure the keyboard + GraphicButton buttonVideoSection; + GraphicButton buttonAudioSection; + GraphicButton buttonMiscSection; + GraphicButton buttonNetworkSettings; - GraphicLabel labelShadows; - GraphicListBox listBoxShadows; - GraphicLabel labelFilter; - GraphicListBox listBoxFilter; - GraphicLabel labelFilterMaxAnisotropy; - GraphicListBox listBoxFilterMaxAnisotropy; + GraphicLabel labelShadows; + GraphicListBox listBoxShadows; + GraphicLabel labelFilter; + GraphicListBox listBoxFilter; + GraphicLabel labelFilterMaxAnisotropy; + GraphicListBox listBoxFilterMaxAnisotropy; - GraphicLabel labelTextures3D; - GraphicCheckBox checkBoxTextures3D; - GraphicLabel labelLights; - GraphicListBox listBoxLights; - GraphicLabel labelUnitParticles; - GraphicCheckBox checkBoxUnitParticles; + GraphicLabel labelTextures3D; + GraphicCheckBox checkBoxTextures3D; + GraphicLabel labelLights; + GraphicListBox listBoxLights; + GraphicLabel labelUnitParticles; + GraphicCheckBox checkBoxUnitParticles; - GraphicLabel labelTilesetParticles; - GraphicCheckBox checkBoxTilesetParticles; - GraphicLabel labelAnimatedTilesetObjects; - GraphicListBox listBoxAnimatedTilesetObjects; + GraphicLabel labelTilesetParticles; + GraphicCheckBox checkBoxTilesetParticles; + GraphicLabel labelAnimatedTilesetObjects; + GraphicListBox listBoxAnimatedTilesetObjects; - GraphicLabel labelScreenModes; - GraphicListBox listBoxScreenModes; - vector < ModeInfo > modeInfos; + GraphicLabel labelScreenModes; + GraphicListBox listBoxScreenModes; + vector < ModeInfo > modeInfos; - GraphicLabel labelFullscreenWindowed; - GraphicCheckBox checkBoxFullscreenWindowed; + GraphicLabel labelFullscreenWindowed; + GraphicCheckBox checkBoxFullscreenWindowed; - GraphicLabel labelMapPreview; - GraphicCheckBox checkBoxMapPreview; + GraphicLabel labelMapPreview; + GraphicCheckBox checkBoxMapPreview; - GraphicMessageBox mainMessageBox; - int mainMessageBoxState; + GraphicMessageBox mainMessageBox; + int mainMessageBoxState; - GraphicLabel labelEnableTextureCompression; - GraphicCheckBox checkBoxEnableTextureCompression; + GraphicLabel labelEnableTextureCompression; + GraphicCheckBox checkBoxEnableTextureCompression; - GraphicLabel labelRainEffect; - GraphicLabel labelRainEffectSeparator; - GraphicCheckBox checkBoxRainEffect; - GraphicCheckBox checkBoxRainEffectMenu; + GraphicLabel labelRainEffect; + GraphicLabel labelRainEffectSeparator; + GraphicCheckBox checkBoxRainEffect; + GraphicCheckBox checkBoxRainEffectMenu; - GraphicLabel labelGammaCorrection; - GraphicListBox listBoxGammaCorrection; + GraphicLabel labelGammaCorrection; + GraphicListBox listBoxGammaCorrection; - GraphicLabel labelShadowIntensity; - GraphicListBox listBoxShadowIntensity; + GraphicLabel labelShadowIntensity; + GraphicListBox listBoxShadowIntensity; - GraphicLabel labelShadowTextureSize; - GraphicListBox listBoxShadowTextureSize; + GraphicLabel labelShadowTextureSize; + GraphicListBox listBoxShadowTextureSize; - GraphicLabel labelVideos; - GraphicCheckBox checkBoxVideos; + GraphicLabel labelVideos; + GraphicCheckBox checkBoxVideos; - GraphicLabel labelSelectionType; - GraphicListBox listBoxSelectionType; + GraphicLabel labelSelectionType; + GraphicListBox listBoxSelectionType; - ProgramState **parentUI; - time_t screenModeChangedTimer; + ProgramState **parentUI; + time_t screenModeChangedTimer; - public: - MenuStateOptionsGraphics (Program * program, MainMenu * mainMenu, - ProgramState ** parentUI = NULL); + public: + MenuStateOptionsGraphics(Program * program, MainMenu * mainMenu, + ProgramState ** parentUI = NULL); - void mouseClick (int x, int y, MouseButton mouseButton); - void mouseMove (int x, int y, const MouseState * mouseState); - void render (); - //virtual void keyDown(SDL_KeyboardEvent key); - virtual void keyPress (SDL_KeyboardEvent c); - //virtual bool isInSpecialKeyCaptureEvent(); + void mouseClick(int x, int y, MouseButton mouseButton); + void mouseMove(int x, int y, const MouseState * mouseState); + void render(); + //virtual void keyDown(SDL_KeyboardEvent key); + virtual void keyPress(SDL_KeyboardEvent c); + //virtual bool isInSpecialKeyCaptureEvent(); - virtual void reloadUI (); + virtual void reloadUI(); - private: - void saveConfig (); - void setActiveInputLable (GraphicLabel * newLable); - void showMessageBox (const string & text, const string & header, - bool toggle); - void revertScreenMode (); - void setupTransifexUI (); - virtual void update (); - }; + private: + void saveConfig(); + void setActiveInputLable(GraphicLabel * newLable); + void showMessageBox(const string & text, const string & header, + bool toggle); + void revertScreenMode(); + void setupTransifexUI(); + virtual void update(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/menu/menu_state_options_network.cpp b/source/glest_game/menu/menu_state_options_network.cpp index 21b140ea2..e6034a57c 100644 --- a/source/glest_game/menu/menu_state_options_network.cpp +++ b/source/glest_game/menu/menu_state_options_network.cpp @@ -29,619 +29,569 @@ #include "leak_dumper.h" using namespace - Shared::Util; +Shared::Util; namespace - Glest -{ - namespace - Game - { - -// ===================================================== -// class MenuStateOptions -// ===================================================== - MenuStateOptionsNetwork::MenuStateOptionsNetwork (Program * program, - MainMenu * mainMenu, - ProgramState ** - parentUI): - MenuState (program, mainMenu, "config"), - buttonOk ("Options_Network", "buttonOk"), - buttonReturn ("Options_Network", "buttonReturn"), - buttonKeyboardSetup ("Options_Network", "buttonKeyboardSetup"), - buttonVideoSection ("Options_Network", "buttonVideoSection"), - buttonAudioSection ("Options_Network", "buttonAudioSection"), - buttonMiscSection ("Options_Network", "buttonMiscSection"), - buttonNetworkSettings ("Options_Network", "buttonNetworkSettings"), - mainMessageBox ("Options_Network", "mainMessageBox"), - labelExternalPort ("Options_Network", "labelExternalPort"), - labelServerPortLabel ("Options_Network", "labelServerPortLabel"), - labelPublishServerExternalPort ("Options_Network", - "labelPublishServerExternalPort"), - listBoxServerPort ("Options_Network", "listBoxServerPort"), - labelEnableFTP ("Options_Network", "labelEnableFTP"), - checkBoxEnableFTP ("Options_Network", "checkBoxEnableFTP"), - labelEnableFTPServer ("Options_Network", "labelEnableFTPServer"), - checkBoxEnableFTPServer ("Options_Network", "checkBoxEnableFTPServer"), - labelFTPServerPortLabel ("Options_Network", "labelFTPServerPortLabel"), - labelFTPServerPort ("Options_Network", "labelFTPServerPort"), - labelFTPServerDataPortsLabel ("Options_Network", - "labelFTPServerDataPortsLabel"), - labelFTPServerDataPorts ("Options_Network", "labelFTPServerDataPorts"), - labelEnableFTPServerInternetTilesetXfer ("Options_Network", - "labelEnableFTPServerInternetTilesetXfer"), - checkBoxEnableFTPServerInternetTilesetXfer ("Options_Network", - "checkBoxEnableFTPServerInternetTilesetXfer"), - labelEnableFTPServerInternetTechtreeXfer ("Options_Network", - "labelEnableFTPServerInternetTechtreeXfer"), - checkBoxEnableFTPServerInternetTechtreeXfer ("Options_Network", - "checkBoxEnableFTPServerInternetTechtreeXfer"), - labelEnablePrivacy ("Options_Network", "labelEnablePrivacy"), - checkBoxEnablePrivacy ("Options_Network", "checkBoxEnablePrivacy") - { - try - { - containerName = "Options_Network"; - Lang & - lang = Lang::getInstance (); - Config & - config = Config::getInstance (); - this-> - parentUI = parentUI; - this-> - console. - setOnlyChatMessagesInStoredLines (false); - - int - leftLabelStart = 100; - int - leftColumnStart = leftLabelStart + 300; - int - buttonRowPos = 50; - int - buttonStartPos = 170; - int - lineOffset = 30; - int - tabButtonWidth = 200; - int - tabButtonHeight = 30; - - mainMessageBox. - init (lang.getString ("Ok")); - mainMessageBox. - setEnabled (false); - mainMessageBoxState = 0; - - buttonAudioSection. - init (0, 720, tabButtonWidth, tabButtonHeight); - buttonAudioSection. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonAudioSection. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonAudioSection. - setText (lang.getString ("Audio")); - // Video Section - buttonVideoSection. - init (200, 720, tabButtonWidth, tabButtonHeight); - buttonVideoSection. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonVideoSection. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonVideoSection. - setText (lang.getString ("Video")); - //currentLine-=lineOffset; - //MiscSection - buttonMiscSection. - init (400, 720, tabButtonWidth, tabButtonHeight); - buttonMiscSection. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonMiscSection. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonMiscSection. - setText (lang.getString ("Misc")); - //NetworkSettings - buttonNetworkSettings. - init (600, 700, tabButtonWidth, tabButtonHeight + 20); - buttonNetworkSettings. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonNetworkSettings. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonNetworkSettings. - setText (lang.getString ("Network")); - - //KeyboardSetup - buttonKeyboardSetup. - init (800, 720, tabButtonWidth, tabButtonHeight); - buttonKeyboardSetup. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonKeyboardSetup. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonKeyboardSetup. - setText (lang.getString ("Keyboardsetup")); - - int - currentLine = 650; // reset line pos - int - currentLabelStart = leftLabelStart; // set to right side - int - currentColumnStart = leftColumnStart; // set to right side - - - // external server port - labelPublishServerExternalPort. - init (currentLabelStart, currentLine, 150); - labelPublishServerExternalPort. - setText (lang.getString ("PublishServerExternalPort")); - - labelExternalPort. - init (currentColumnStart, currentLine); - string - extPort = config.getString ("PortExternal", "not set"); - if (extPort == "not set" || extPort == "0") - { - extPort = " --- "; - } - else - { - extPort = "!!! " + extPort + " !!!"; - } - labelExternalPort. - setText (extPort); - - currentLine -= lineOffset; - // server port - labelServerPortLabel.init (currentLabelStart, currentLine); - labelServerPortLabel.setText (lang.getString ("ServerPort")); - - listBoxServerPort.init (currentColumnStart, currentLine, 160); - - string - portListString = - config.getString ("PortList", - intToStr (GameConstants::serverPort).c_str ()); - std::vector < std::string > portList; - Tokenize (portListString, portList, ","); - - string - currentPort = - config.getString ("PortServer", - intToStr (GameConstants::serverPort).c_str ()); - int - portSelectionIndex = 0; - for (int idx = 0; idx < (int) portList.size (); idx++) - { - if (portList[idx] != "" - && IsNumeric (portList[idx].c_str (), false)) - { - listBoxServerPort.pushBackItem (portList[idx]); - if (currentPort == portList[idx]) - { - portSelectionIndex = idx; - } - } - } - listBoxServerPort.setSelectedItemIndex (portSelectionIndex); - - currentLine -= lineOffset; - labelFTPServerPortLabel.init (currentLabelStart, currentLine); - labelFTPServerPortLabel.setText (lang.getString ("FTPServerPort")); - - int - FTPPort = - config.getInt ("FTPServerPort", - intToStr (ServerSocket::getFTPServerPort ()). - c_str ()); - labelFTPServerPort.init (currentColumnStart, currentLine); - labelFTPServerPort.setText (intToStr (FTPPort)); - currentLine -= lineOffset; - labelFTPServerDataPortsLabel.init (currentLabelStart, currentLine); - labelFTPServerDataPortsLabel.setText (lang. - getString - ("FTPServerDataPort")); - - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "%d - %d", FTPPort + 1, - FTPPort + GameConstants::maxPlayers); - - labelFTPServerDataPorts.init (currentColumnStart, currentLine); - labelFTPServerDataPorts.setText (szBuf); - currentLine -= lineOffset; - labelEnableFTPServer.init (currentLabelStart, currentLine); - labelEnableFTPServer.setText (lang.getString ("EnableFTPServer")); - - checkBoxEnableFTPServer.init (currentColumnStart, currentLine); - checkBoxEnableFTPServer.setValue (config. - getBool ("EnableFTPServer", - "true")); - currentLine -= lineOffset; - // FTP Config - start - labelEnableFTP.init (currentLabelStart, currentLine); - labelEnableFTP.setText (lang.getString ("EnableFTP")); - - checkBoxEnableFTP.init (currentColumnStart, currentLine); - checkBoxEnableFTP.setValue (config.getBool ("EnableFTPXfer", "true")); - currentLine -= lineOffset; - - labelEnableFTPServerInternetTilesetXfer.init (currentLabelStart, - currentLine); - labelEnableFTPServerInternetTilesetXfer.setText (lang. - getString - ("EnableFTPServerInternetTilesetXfer")); - - checkBoxEnableFTPServerInternetTilesetXfer.init (currentColumnStart, - currentLine); - checkBoxEnableFTPServerInternetTilesetXfer.setValue (config. - getBool - ("EnableFTPServerInternetTilesetXfer", - "true")); - - currentLine -= lineOffset; - - labelEnableFTPServerInternetTechtreeXfer.init (currentLabelStart, - currentLine); - labelEnableFTPServerInternetTechtreeXfer.setText (lang. - getString - ("EnableFTPServerInternetTechtreeXfer")); - - checkBoxEnableFTPServerInternetTechtreeXfer.init (currentColumnStart, - currentLine); - checkBoxEnableFTPServerInternetTechtreeXfer.setValue (config. - getBool - ("EnableFTPServerInternetTechtreeXfer", - "true")); - - currentLine -= lineOffset; - - - // FTP config end - - // Privacy flag - labelEnablePrivacy.init (currentLabelStart, currentLine); - labelEnablePrivacy.setText (lang.getString ("PrivacyPlease")); - - checkBoxEnablePrivacy.init (currentColumnStart, currentLine); - checkBoxEnablePrivacy.setValue (config. - getBool ("PrivacyPlease", "false")); - //currentLine-=lineOffset; - // end - - // buttons - buttonOk.init (buttonStartPos, buttonRowPos, 100); - buttonOk.setText (lang.getString ("Save")); - - buttonReturn.setText (lang.getString ("Return")); - buttonReturn.init (buttonStartPos + 110, buttonRowPos, 100); - - GraphicComponent::applyAllCustomProperties (containerName); - } - catch (exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error loading options: %s\n", - __FILE__, __FUNCTION__, __LINE__, - e.what ()); - throw - megaglest_runtime_error (string ("Error loading options msg: ") + - e.what ()); - } - } - - void - MenuStateOptionsNetwork::reloadUI () - { - Lang & lang = Lang::getInstance (); - - mainMessageBox.init (lang.getString ("Ok")); - - buttonAudioSection.setText (lang.getString ("Audio")); - buttonVideoSection.setText (lang.getString ("Video")); - buttonMiscSection.setText (lang.getString ("Misc")); - buttonNetworkSettings.setText (lang.getString ("Network")); - - std::vector < string > listboxData; - listboxData.push_back ("None"); - listboxData.push_back ("OpenAL"); - - listboxData.clear (); - listboxData.push_back ("Bilinear"); - listboxData.push_back ("Trilinear"); - - listboxData.clear (); - for (float f = 0.0; f < 2.1f; f = f + 0.1f) - { - listboxData.push_back (floatToStr (f)); - } - listboxData.clear (); - for (int i = 0; i < Renderer::sCount; ++i) - { - listboxData.push_back (lang. - getString (Renderer:: - shadowsToStr (static_cast < - Renderer::Shadows > - (i)))); - } - - - labelServerPortLabel.setText (lang.getString ("ServerPort")); - labelPublishServerExternalPort.setText (lang. - getString - ("PublishServerExternalPort")); - labelEnableFTP.setText (lang.getString ("EnableFTP")); - labelEnableFTPServer.setText (lang.getString ("EnableFTPServer")); - labelFTPServerPortLabel.setText (lang.getString ("FTPServerPort")); - labelFTPServerDataPortsLabel.setText (lang. - getString ("FTPServerDataPort")); - labelEnableFTPServerInternetTilesetXfer.setText (lang. - getString - ("EnableFTPServerInternetTilesetXfer")); - labelEnableFTPServerInternetTechtreeXfer.setText (lang. - getString - ("EnableFTPServerInternetTechtreeXfer")); - labelEnablePrivacy.setText (lang.getString ("PrivacyPlease")); - buttonOk.setText (lang.getString ("Save")); - buttonReturn.setText (lang.getString ("Return")); - } - - void - MenuStateOptionsNetwork::mouseClick (int x, int y, - MouseButton mouseButton) - { - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - - if (mainMessageBox.getEnabled ()) - { - int - button = 0; - if (mainMessageBox.mouseClick (x, y, button)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - if (button == 0) - { - if (mainMessageBoxState == 1) - { - mainMessageBoxState = 0; - mainMessageBox.setEnabled (false); - saveConfig (); - - Lang & lang = Lang::getInstance (); - mainMessageBox.init (lang.getString ("Ok")); - mainMenu->setState (new MenuStateOptions (program, mainMenu)); - } - else - { - mainMessageBox.setEnabled (false); - - Lang & lang = Lang::getInstance (); - mainMessageBox.init (lang.getString ("Ok")); - } - } - - } - } - else if (buttonOk.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - saveConfig (); - //mainMenu->setState(new MenuStateOptions(program, mainMenu,this->parentUI)); - return; - } - else if (buttonReturn.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - if (this->parentUI != NULL) - { - *this->parentUI = NULL; - delete * - this-> - parentUI; - } - mainMenu->setState (new MenuStateRoot (program, mainMenu)); - return; - } - else if (buttonAudioSection.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptionsSound (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - return; - } - else if (buttonNetworkSettings.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - //mainMenu->setState(new MenuStateOptionsNetwork(program, mainMenu,this->parentUI)); // open keyboard shortcuts setup screen - return; - } - else if (buttonMiscSection.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptions (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - return; - } - else if (buttonVideoSection.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptionsGraphics (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - return; - } - else if (buttonKeyboardSetup.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateKeysetup (program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen - //showMessageBox("Not implemented yet", "Keyboard setup", false); - return; - } - else - { - if (listBoxServerPort.mouseClick (x, y)) - { - int - selectedPort = strToInt (listBoxServerPort.getSelectedItem ()); - if (selectedPort < 10000) - { - selectedPort = GameConstants::serverPort; - } - // use the following ports for ftp - char - szBuf[8096] = ""; - snprintf (szBuf, 8096, "%d - %d", selectedPort + 2, - selectedPort + 1 + GameConstants::maxPlayers); - labelFTPServerPort.setText (intToStr (selectedPort + 1)); - labelFTPServerDataPorts.setText (szBuf); - } - - checkBoxEnableFTP.mouseClick (x, y); - checkBoxEnableFTPServer.mouseClick (x, y); - - checkBoxEnableFTPServerInternetTilesetXfer.mouseClick (x, y); - checkBoxEnableFTPServerInternetTechtreeXfer.mouseClick (x, y); - - checkBoxEnablePrivacy.mouseClick (x, y); - } - } - - void - MenuStateOptionsNetwork::mouseMove (int x, int y, const MouseState * ms) - { - if (mainMessageBox.getEnabled ()) - { - mainMessageBox.mouseMove (x, y); - } - - buttonOk.mouseMove (x, y); - buttonReturn.mouseMove (x, y); - buttonKeyboardSetup.mouseMove (x, y); - buttonAudioSection.mouseMove (x, y); - buttonNetworkSettings.mouseMove (x, y); - buttonMiscSection.mouseMove (x, y); - buttonVideoSection.mouseMove (x, y); - listBoxServerPort.mouseMove (x, y); - checkBoxEnableFTP.mouseMove (x, y); - checkBoxEnableFTPServer.mouseMove (x, y); - checkBoxEnableFTPServerInternetTilesetXfer.mouseMove (x, y); - checkBoxEnableFTPServerInternetTechtreeXfer.mouseMove (x, y); - checkBoxEnablePrivacy.mouseMove (x, y); - } - -//bool MenuStateOptionsNetwork::isInSpecialKeyCaptureEvent() { -// return (activeInputLabel != NULL); -//} -// -//void MenuStateOptionsNetwork::keyDown(SDL_KeyboardEvent key) { -// if(activeInputLabel != NULL) { -// keyDownEditLabel(key, &activeInputLabel); -// } -//} - - void - MenuStateOptionsNetwork::keyPress (SDL_KeyboardEvent c) - { -// if(activeInputLabel != NULL) { -// //printf("[%d]\n",c); fflush(stdout); -// if( &labelPlayerName == activeInputLabel || -// &labelTransifexUser == activeInputLabel || -// &labelTransifexPwd == activeInputLabel || -// &labelTransifexI18N == activeInputLabel) { -// textInputEditLabel(c, &activeInputLabel); -// } -// } -// else { - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - if (isKeyPressed (configKeys.getSDLKey ("SaveGUILayout"), c) == true) - { - GraphicComponent::saveAllCustomProperties (containerName); - //Lang &lang= Lang::getInstance(); - //console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ? lang.getString("Yes") : lang.getString("No"))+ "]"); - } -// } - } - - void - MenuStateOptionsNetwork::render () - { - Renderer & renderer = Renderer::getInstance (); - - if (mainMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&mainMessageBox); - } - else - { - renderer.renderButton (&buttonOk); - renderer.renderButton (&buttonReturn); - renderer.renderButton (&buttonKeyboardSetup); - renderer.renderButton (&buttonVideoSection); - renderer.renderButton (&buttonAudioSection); - renderer.renderButton (&buttonMiscSection); - renderer.renderButton (&buttonNetworkSettings); - renderer.renderLabel (&labelServerPortLabel); - renderer.renderLabel (&labelExternalPort); - renderer.renderLabel (&labelPublishServerExternalPort); - renderer.renderListBox (&listBoxServerPort); - - - renderer.renderLabel (&labelEnableFTP); - renderer.renderCheckBox (&checkBoxEnableFTP); - - renderer.renderLabel (&labelEnableFTPServer); - renderer.renderCheckBox (&checkBoxEnableFTPServer); - - renderer.renderLabel (&labelFTPServerPortLabel); - renderer.renderLabel (&labelFTPServerPort); - renderer.renderLabel (&labelFTPServerDataPortsLabel); - renderer.renderLabel (&labelFTPServerDataPorts); - - renderer.renderLabel (&labelEnableFTPServerInternetTilesetXfer); - renderer.renderCheckBox (&checkBoxEnableFTPServerInternetTilesetXfer); - renderer.renderLabel (&labelEnableFTPServerInternetTechtreeXfer); - renderer. - renderCheckBox (&checkBoxEnableFTPServerInternetTechtreeXfer); - - renderer.renderLabel (&labelEnablePrivacy); - renderer.renderCheckBox (&checkBoxEnablePrivacy); - - } - - renderer.renderConsole (&console); - if (program != NULL) - program->renderProgramMsgBox (); - } - - void - MenuStateOptionsNetwork::saveConfig () - { - Config & config = Config::getInstance (); - Lang & lang = Lang::getInstance (); - setActiveInputLable (NULL); - - - lang.loadGameStrings (config.getString ("Lang")); - - config.setString ("PortServer", listBoxServerPort.getSelectedItem ()); - config.setInt ("FTPServerPort", config.getInt ("PortServer") + 1); - config.setBool ("EnableFTPXfer", checkBoxEnableFTP.getValue ()); - config.setBool ("EnableFTPServer", checkBoxEnableFTPServer.getValue ()); - - config.setBool ("EnableFTPServerInternetTilesetXfer", - checkBoxEnableFTPServerInternetTilesetXfer.getValue ()); - config.setBool ("EnableFTPServerInternetTechtreeXfer", - checkBoxEnableFTPServerInternetTechtreeXfer. - getValue ()); - - config.setBool ("PrivacyPlease", checkBoxEnablePrivacy.getValue ()); - - config.save (); - - Renderer::getInstance ().loadConfig (); - console.addLine (lang.getString ("SettingsSaved")); - } - - void - MenuStateOptionsNetwork::setActiveInputLable (GraphicLabel * newLable) - { - } - -}} //end namespace + Glest { + namespace + Game { + + // ===================================================== + // class MenuStateOptions + // ===================================================== + MenuStateOptionsNetwork::MenuStateOptionsNetwork(Program * program, + MainMenu * mainMenu, + ProgramState ** + parentUI) : + MenuState(program, mainMenu, "config"), + buttonOk("Options_Network", "buttonOk"), + buttonReturn("Options_Network", "buttonReturn"), + buttonKeyboardSetup("Options_Network", "buttonKeyboardSetup"), + buttonVideoSection("Options_Network", "buttonVideoSection"), + buttonAudioSection("Options_Network", "buttonAudioSection"), + buttonMiscSection("Options_Network", "buttonMiscSection"), + buttonNetworkSettings("Options_Network", "buttonNetworkSettings"), + mainMessageBox("Options_Network", "mainMessageBox"), + labelExternalPort("Options_Network", "labelExternalPort"), + labelServerPortLabel("Options_Network", "labelServerPortLabel"), + labelPublishServerExternalPort("Options_Network", + "labelPublishServerExternalPort"), + listBoxServerPort("Options_Network", "listBoxServerPort"), + labelEnableFTP("Options_Network", "labelEnableFTP"), + checkBoxEnableFTP("Options_Network", "checkBoxEnableFTP"), + labelEnableFTPServer("Options_Network", "labelEnableFTPServer"), + checkBoxEnableFTPServer("Options_Network", "checkBoxEnableFTPServer"), + labelFTPServerPortLabel("Options_Network", "labelFTPServerPortLabel"), + labelFTPServerPort("Options_Network", "labelFTPServerPort"), + labelFTPServerDataPortsLabel("Options_Network", + "labelFTPServerDataPortsLabel"), + labelFTPServerDataPorts("Options_Network", "labelFTPServerDataPorts"), + labelEnableFTPServerInternetTilesetXfer("Options_Network", + "labelEnableFTPServerInternetTilesetXfer"), + checkBoxEnableFTPServerInternetTilesetXfer("Options_Network", + "checkBoxEnableFTPServerInternetTilesetXfer"), + labelEnableFTPServerInternetTechtreeXfer("Options_Network", + "labelEnableFTPServerInternetTechtreeXfer"), + checkBoxEnableFTPServerInternetTechtreeXfer("Options_Network", + "checkBoxEnableFTPServerInternetTechtreeXfer"), + labelEnablePrivacy("Options_Network", "labelEnablePrivacy"), + checkBoxEnablePrivacy("Options_Network", "checkBoxEnablePrivacy") { + try { + containerName = "Options_Network"; + Lang & + lang = Lang::getInstance(); + Config & + config = Config::getInstance(); + this-> + parentUI = parentUI; + this-> + console. + setOnlyChatMessagesInStoredLines(false); + + int + leftLabelStart = 100; + int + leftColumnStart = leftLabelStart + 300; + int + buttonRowPos = 50; + int + buttonStartPos = 170; + int + lineOffset = 30; + int + tabButtonWidth = 200; + int + tabButtonHeight = 30; + + mainMessageBox. + init(lang.getString("Ok")); + mainMessageBox. + setEnabled(false); + mainMessageBoxState = 0; + + buttonAudioSection. + init(0, 720, tabButtonWidth, tabButtonHeight); + buttonAudioSection. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonAudioSection. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonAudioSection. + setText(lang.getString("Audio")); + // Video Section + buttonVideoSection. + init(200, 720, tabButtonWidth, tabButtonHeight); + buttonVideoSection. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonVideoSection. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonVideoSection. + setText(lang.getString("Video")); + //currentLine-=lineOffset; + //MiscSection + buttonMiscSection. + init(400, 720, tabButtonWidth, tabButtonHeight); + buttonMiscSection. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonMiscSection. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonMiscSection. + setText(lang.getString("Misc")); + //NetworkSettings + buttonNetworkSettings. + init(600, 700, tabButtonWidth, tabButtonHeight + 20); + buttonNetworkSettings. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonNetworkSettings. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonNetworkSettings. + setText(lang.getString("Network")); + + //KeyboardSetup + buttonKeyboardSetup. + init(800, 720, tabButtonWidth, tabButtonHeight); + buttonKeyboardSetup. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonKeyboardSetup. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonKeyboardSetup. + setText(lang.getString("Keyboardsetup")); + + int + currentLine = 650; // reset line pos + int + currentLabelStart = leftLabelStart; // set to right side + int + currentColumnStart = leftColumnStart; // set to right side + + + // external server port + labelPublishServerExternalPort. + init(currentLabelStart, currentLine, 150); + labelPublishServerExternalPort. + setText(lang.getString("PublishServerExternalPort")); + + labelExternalPort. + init(currentColumnStart, currentLine); + string + extPort = config.getString("PortExternal", "not set"); + if (extPort == "not set" || extPort == "0") { + extPort = " --- "; + } else { + extPort = "!!! " + extPort + " !!!"; + } + labelExternalPort. + setText(extPort); + + currentLine -= lineOffset; + // server port + labelServerPortLabel.init(currentLabelStart, currentLine); + labelServerPortLabel.setText(lang.getString("ServerPort")); + + listBoxServerPort.init(currentColumnStart, currentLine, 160); + + string + portListString = + config.getString("PortList", + intToStr(GameConstants::serverPort).c_str()); + std::vector < std::string > portList; + Tokenize(portListString, portList, ","); + + string + currentPort = + config.getString("PortServer", + intToStr(GameConstants::serverPort).c_str()); + int + portSelectionIndex = 0; + for (int idx = 0; idx < (int) portList.size(); idx++) { + if (portList[idx] != "" + && IsNumeric(portList[idx].c_str(), false)) { + listBoxServerPort.pushBackItem(portList[idx]); + if (currentPort == portList[idx]) { + portSelectionIndex = idx; + } + } + } + listBoxServerPort.setSelectedItemIndex(portSelectionIndex); + + currentLine -= lineOffset; + labelFTPServerPortLabel.init(currentLabelStart, currentLine); + labelFTPServerPortLabel.setText(lang.getString("FTPServerPort")); + + int + FTPPort = + config.getInt("FTPServerPort", + intToStr(ServerSocket::getFTPServerPort()). + c_str()); + labelFTPServerPort.init(currentColumnStart, currentLine); + labelFTPServerPort.setText(intToStr(FTPPort)); + currentLine -= lineOffset; + labelFTPServerDataPortsLabel.init(currentLabelStart, currentLine); + labelFTPServerDataPortsLabel.setText(lang. + getString + ("FTPServerDataPort")); + + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "%d - %d", FTPPort + 1, + FTPPort + GameConstants::maxPlayers); + + labelFTPServerDataPorts.init(currentColumnStart, currentLine); + labelFTPServerDataPorts.setText(szBuf); + currentLine -= lineOffset; + labelEnableFTPServer.init(currentLabelStart, currentLine); + labelEnableFTPServer.setText(lang.getString("EnableFTPServer")); + + checkBoxEnableFTPServer.init(currentColumnStart, currentLine); + checkBoxEnableFTPServer.setValue(config. + getBool("EnableFTPServer", + "true")); + currentLine -= lineOffset; + // FTP Config - start + labelEnableFTP.init(currentLabelStart, currentLine); + labelEnableFTP.setText(lang.getString("EnableFTP")); + + checkBoxEnableFTP.init(currentColumnStart, currentLine); + checkBoxEnableFTP.setValue(config.getBool("EnableFTPXfer", "true")); + currentLine -= lineOffset; + + labelEnableFTPServerInternetTilesetXfer.init(currentLabelStart, + currentLine); + labelEnableFTPServerInternetTilesetXfer.setText(lang. + getString + ("EnableFTPServerInternetTilesetXfer")); + + checkBoxEnableFTPServerInternetTilesetXfer.init(currentColumnStart, + currentLine); + checkBoxEnableFTPServerInternetTilesetXfer.setValue(config. + getBool + ("EnableFTPServerInternetTilesetXfer", + "true")); + + currentLine -= lineOffset; + + labelEnableFTPServerInternetTechtreeXfer.init(currentLabelStart, + currentLine); + labelEnableFTPServerInternetTechtreeXfer.setText(lang. + getString + ("EnableFTPServerInternetTechtreeXfer")); + + checkBoxEnableFTPServerInternetTechtreeXfer.init(currentColumnStart, + currentLine); + checkBoxEnableFTPServerInternetTechtreeXfer.setValue(config. + getBool + ("EnableFTPServerInternetTechtreeXfer", + "true")); + + currentLine -= lineOffset; + + + // FTP config end + + // Privacy flag + labelEnablePrivacy.init(currentLabelStart, currentLine); + labelEnablePrivacy.setText(lang.getString("PrivacyPlease")); + + checkBoxEnablePrivacy.init(currentColumnStart, currentLine); + checkBoxEnablePrivacy.setValue(config. + getBool("PrivacyPlease", "false")); + //currentLine-=lineOffset; + // end + + // buttons + buttonOk.init(buttonStartPos, buttonRowPos, 100); + buttonOk.setText(lang.getString("Save")); + + buttonReturn.setText(lang.getString("Return")); + buttonReturn.init(buttonStartPos + 110, buttonRowPos, 100); + + GraphicComponent::applyAllCustomProperties(containerName); + } catch (exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error loading options: %s\n", + __FILE__, __FUNCTION__, __LINE__, + e.what()); + throw + megaglest_runtime_error(string("Error loading options msg: ") + + e.what()); + } + } + + void + MenuStateOptionsNetwork::reloadUI() { + Lang & lang = Lang::getInstance(); + + mainMessageBox.init(lang.getString("Ok")); + + buttonAudioSection.setText(lang.getString("Audio")); + buttonVideoSection.setText(lang.getString("Video")); + buttonMiscSection.setText(lang.getString("Misc")); + buttonNetworkSettings.setText(lang.getString("Network")); + + std::vector < string > listboxData; + listboxData.push_back("None"); + listboxData.push_back("OpenAL"); + + listboxData.clear(); + listboxData.push_back("Bilinear"); + listboxData.push_back("Trilinear"); + + listboxData.clear(); + for (float f = 0.0; f < 2.1f; f = f + 0.1f) { + listboxData.push_back(floatToStr(f)); + } + listboxData.clear(); + for (int i = 0; i < Renderer::sCount; ++i) { + listboxData.push_back(lang. + getString(Renderer:: + shadowsToStr(static_cast < + Renderer::Shadows> + (i)))); + } + + + labelServerPortLabel.setText(lang.getString("ServerPort")); + labelPublishServerExternalPort.setText(lang. + getString + ("PublishServerExternalPort")); + labelEnableFTP.setText(lang.getString("EnableFTP")); + labelEnableFTPServer.setText(lang.getString("EnableFTPServer")); + labelFTPServerPortLabel.setText(lang.getString("FTPServerPort")); + labelFTPServerDataPortsLabel.setText(lang. + getString("FTPServerDataPort")); + labelEnableFTPServerInternetTilesetXfer.setText(lang. + getString + ("EnableFTPServerInternetTilesetXfer")); + labelEnableFTPServerInternetTechtreeXfer.setText(lang. + getString + ("EnableFTPServerInternetTechtreeXfer")); + labelEnablePrivacy.setText(lang.getString("PrivacyPlease")); + buttonOk.setText(lang.getString("Save")); + buttonReturn.setText(lang.getString("Return")); + } + + void + MenuStateOptionsNetwork::mouseClick(int x, int y, + MouseButton mouseButton) { + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + + if (mainMessageBox.getEnabled()) { + int + button = 0; + if (mainMessageBox.mouseClick(x, y, button)) { + soundRenderer.playFx(coreData.getClickSoundA()); + if (button == 0) { + if (mainMessageBoxState == 1) { + mainMessageBoxState = 0; + mainMessageBox.setEnabled(false); + saveConfig(); + + Lang & lang = Lang::getInstance(); + mainMessageBox.init(lang.getString("Ok")); + mainMenu->setState(new MenuStateOptions(program, mainMenu)); + } else { + mainMessageBox.setEnabled(false); + + Lang & lang = Lang::getInstance(); + mainMessageBox.init(lang.getString("Ok")); + } + } + + } + } else if (buttonOk.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + saveConfig(); + //mainMenu->setState(new MenuStateOptions(program, mainMenu,this->parentUI)); + return; + } else if (buttonReturn.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + if (this->parentUI != NULL) { + *this->parentUI = NULL; + delete * + this-> + parentUI; + } + mainMenu->setState(new MenuStateRoot(program, mainMenu)); + return; + } else if (buttonAudioSection.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptionsSound(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + return; + } else if (buttonNetworkSettings.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + //mainMenu->setState(new MenuStateOptionsNetwork(program, mainMenu,this->parentUI)); // open keyboard shortcuts setup screen + return; + } else if (buttonMiscSection.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptions(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + return; + } else if (buttonVideoSection.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptionsGraphics(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + return; + } else if (buttonKeyboardSetup.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateKeysetup(program, mainMenu, this->parentUI)); // open keyboard shortcuts setup screen + //showMessageBox("Not implemented yet", "Keyboard setup", false); + return; + } else { + if (listBoxServerPort.mouseClick(x, y)) { + int + selectedPort = strToInt(listBoxServerPort.getSelectedItem()); + if (selectedPort < 10000) { + selectedPort = GameConstants::serverPort; + } + // use the following ports for ftp + char + szBuf[8096] = ""; + snprintf(szBuf, 8096, "%d - %d", selectedPort + 2, + selectedPort + 1 + GameConstants::maxPlayers); + labelFTPServerPort.setText(intToStr(selectedPort + 1)); + labelFTPServerDataPorts.setText(szBuf); + } + + checkBoxEnableFTP.mouseClick(x, y); + checkBoxEnableFTPServer.mouseClick(x, y); + + checkBoxEnableFTPServerInternetTilesetXfer.mouseClick(x, y); + checkBoxEnableFTPServerInternetTechtreeXfer.mouseClick(x, y); + + checkBoxEnablePrivacy.mouseClick(x, y); + } + } + + void + MenuStateOptionsNetwork::mouseMove(int x, int y, const MouseState * ms) { + if (mainMessageBox.getEnabled()) { + mainMessageBox.mouseMove(x, y); + } + + buttonOk.mouseMove(x, y); + buttonReturn.mouseMove(x, y); + buttonKeyboardSetup.mouseMove(x, y); + buttonAudioSection.mouseMove(x, y); + buttonNetworkSettings.mouseMove(x, y); + buttonMiscSection.mouseMove(x, y); + buttonVideoSection.mouseMove(x, y); + listBoxServerPort.mouseMove(x, y); + checkBoxEnableFTP.mouseMove(x, y); + checkBoxEnableFTPServer.mouseMove(x, y); + checkBoxEnableFTPServerInternetTilesetXfer.mouseMove(x, y); + checkBoxEnableFTPServerInternetTechtreeXfer.mouseMove(x, y); + checkBoxEnablePrivacy.mouseMove(x, y); + } + + //bool MenuStateOptionsNetwork::isInSpecialKeyCaptureEvent() { + // return (activeInputLabel != NULL); + //} + // + //void MenuStateOptionsNetwork::keyDown(SDL_KeyboardEvent key) { + // if(activeInputLabel != NULL) { + // keyDownEditLabel(key, &activeInputLabel); + // } + //} + + void + MenuStateOptionsNetwork::keyPress(SDL_KeyboardEvent c) { + // if(activeInputLabel != NULL) { + // //printf("[%d]\n",c); fflush(stdout); + // if( &labelPlayerName == activeInputLabel || + // &labelTransifexUser == activeInputLabel || + // &labelTransifexPwd == activeInputLabel || + // &labelTransifexI18N == activeInputLabel) { + // textInputEditLabel(c, &activeInputLabel); + // } + // } + // else { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), c) == true) { + GraphicComponent::saveAllCustomProperties(containerName); + //Lang &lang= Lang::getInstance(); + //console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ? lang.getString("Yes") : lang.getString("No"))+ "]"); + } + // } + } + + void + MenuStateOptionsNetwork::render() { + Renderer & renderer = Renderer::getInstance(); + + if (mainMessageBox.getEnabled()) { + renderer.renderMessageBox(&mainMessageBox); + } else { + renderer.renderButton(&buttonOk); + renderer.renderButton(&buttonReturn); + renderer.renderButton(&buttonKeyboardSetup); + renderer.renderButton(&buttonVideoSection); + renderer.renderButton(&buttonAudioSection); + renderer.renderButton(&buttonMiscSection); + renderer.renderButton(&buttonNetworkSettings); + renderer.renderLabel(&labelServerPortLabel); + renderer.renderLabel(&labelExternalPort); + renderer.renderLabel(&labelPublishServerExternalPort); + renderer.renderListBox(&listBoxServerPort); + + + renderer.renderLabel(&labelEnableFTP); + renderer.renderCheckBox(&checkBoxEnableFTP); + + renderer.renderLabel(&labelEnableFTPServer); + renderer.renderCheckBox(&checkBoxEnableFTPServer); + + renderer.renderLabel(&labelFTPServerPortLabel); + renderer.renderLabel(&labelFTPServerPort); + renderer.renderLabel(&labelFTPServerDataPortsLabel); + renderer.renderLabel(&labelFTPServerDataPorts); + + renderer.renderLabel(&labelEnableFTPServerInternetTilesetXfer); + renderer.renderCheckBox(&checkBoxEnableFTPServerInternetTilesetXfer); + renderer.renderLabel(&labelEnableFTPServerInternetTechtreeXfer); + renderer. + renderCheckBox(&checkBoxEnableFTPServerInternetTechtreeXfer); + + renderer.renderLabel(&labelEnablePrivacy); + renderer.renderCheckBox(&checkBoxEnablePrivacy); + + } + + renderer.renderConsole(&console); + if (program != NULL) + program->renderProgramMsgBox(); + } + + void + MenuStateOptionsNetwork::saveConfig() { + Config & config = Config::getInstance(); + Lang & lang = Lang::getInstance(); + setActiveInputLable(NULL); + + + lang.loadGameStrings(config.getString("Lang")); + + config.setString("PortServer", listBoxServerPort.getSelectedItem()); + config.setInt("FTPServerPort", config.getInt("PortServer") + 1); + config.setBool("EnableFTPXfer", checkBoxEnableFTP.getValue()); + config.setBool("EnableFTPServer", checkBoxEnableFTPServer.getValue()); + + config.setBool("EnableFTPServerInternetTilesetXfer", + checkBoxEnableFTPServerInternetTilesetXfer.getValue()); + config.setBool("EnableFTPServerInternetTechtreeXfer", + checkBoxEnableFTPServerInternetTechtreeXfer. + getValue()); + + config.setBool("PrivacyPlease", checkBoxEnablePrivacy.getValue()); + + config.save(); + + Renderer::getInstance().loadConfig(); + console.addLine(lang.getString("SettingsSaved")); + } + + void + MenuStateOptionsNetwork::setActiveInputLable(GraphicLabel * newLable) { + } + + } +} //end namespace diff --git a/source/glest_game/menu/menu_state_options_network.h b/source/glest_game/menu/menu_state_options_network.h index 750d93112..4d4d78750 100644 --- a/source/glest_game/menu/menu_state_options_network.h +++ b/source/glest_game/menu/menu_state_options_network.h @@ -15,81 +15,79 @@ # include "main_menu.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// =============================== -// class MenuStateOptionsNetwork -// =============================== + // =============================== + // class MenuStateOptionsNetwork + // =============================== - class MenuStateOptionsNetwork:public MenuState - { - private: + class MenuStateOptionsNetwork :public MenuState { + private: - GraphicButton buttonOk; - GraphicButton buttonReturn; + GraphicButton buttonOk; + GraphicButton buttonReturn; - GraphicButton buttonKeyboardSetup; // configure the keyboard - GraphicButton buttonVideoSection; - GraphicButton buttonAudioSection; - GraphicButton buttonMiscSection; - GraphicButton buttonNetworkSettings; + GraphicButton buttonKeyboardSetup; // configure the keyboard + GraphicButton buttonVideoSection; + GraphicButton buttonAudioSection; + GraphicButton buttonMiscSection; + GraphicButton buttonNetworkSettings; - GraphicMessageBox mainMessageBox; - int mainMessageBoxState; + GraphicMessageBox mainMessageBox; + int mainMessageBoxState; - GraphicLabel labelExternalPort; - GraphicLabel labelServerPortLabel; + GraphicLabel labelExternalPort; + GraphicLabel labelServerPortLabel; - GraphicLabel labelPublishServerExternalPort; - GraphicListBox listBoxServerPort; + GraphicLabel labelPublishServerExternalPort; + GraphicListBox listBoxServerPort; - GraphicLabel labelEnableFTP; - GraphicCheckBox checkBoxEnableFTP; + GraphicLabel labelEnableFTP; + GraphicCheckBox checkBoxEnableFTP; - GraphicLabel labelEnableFTPServer; - GraphicCheckBox checkBoxEnableFTPServer; + GraphicLabel labelEnableFTPServer; + GraphicCheckBox checkBoxEnableFTPServer; - GraphicLabel labelFTPServerPortLabel; - GraphicLabel labelFTPServerPort; + GraphicLabel labelFTPServerPortLabel; + GraphicLabel labelFTPServerPort; - GraphicLabel labelFTPServerDataPortsLabel; - GraphicLabel labelFTPServerDataPorts; + GraphicLabel labelFTPServerDataPortsLabel; + GraphicLabel labelFTPServerDataPorts; - GraphicLabel labelEnableFTPServerInternetTilesetXfer; - GraphicCheckBox checkBoxEnableFTPServerInternetTilesetXfer; + GraphicLabel labelEnableFTPServerInternetTilesetXfer; + GraphicCheckBox checkBoxEnableFTPServerInternetTilesetXfer; - GraphicLabel labelEnableFTPServerInternetTechtreeXfer; - GraphicCheckBox checkBoxEnableFTPServerInternetTechtreeXfer; + GraphicLabel labelEnableFTPServerInternetTechtreeXfer; + GraphicCheckBox checkBoxEnableFTPServerInternetTechtreeXfer; - GraphicLabel labelEnablePrivacy; - GraphicCheckBox checkBoxEnablePrivacy; + GraphicLabel labelEnablePrivacy; + GraphicCheckBox checkBoxEnablePrivacy; - ProgramState **parentUI; + ProgramState **parentUI; - public: - MenuStateOptionsNetwork (Program * program, MainMenu * mainMenu, - ProgramState ** parentUI = NULL); + public: + MenuStateOptionsNetwork(Program * program, MainMenu * mainMenu, + ProgramState ** parentUI = NULL); - void mouseClick (int x, int y, MouseButton mouseButton); - void mouseMove (int x, int y, const MouseState * mouseState); - void render (); - //virtual void keyDown(SDL_KeyboardEvent key); - virtual void keyPress (SDL_KeyboardEvent c); - //virtual bool isInSpecialKeyCaptureEvent(); + void mouseClick(int x, int y, MouseButton mouseButton); + void mouseMove(int x, int y, const MouseState * mouseState); + void render(); + //virtual void keyDown(SDL_KeyboardEvent key); + virtual void keyPress(SDL_KeyboardEvent c); + //virtual bool isInSpecialKeyCaptureEvent(); - virtual void reloadUI (); + virtual void reloadUI(); - private: - void saveConfig (); - void setActiveInputLable (GraphicLabel * newLable); - //void showMessageBox(const string &text, const string &header, bool toggle); - }; + private: + void saveConfig(); + void setActiveInputLable(GraphicLabel * newLable); + //void showMessageBox(const string &text, const string &header, bool toggle); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/menu/menu_state_options_sound.cpp b/source/glest_game/menu/menu_state_options_sound.cpp index d958f3b28..5701f885d 100644 --- a/source/glest_game/menu/menu_state_options_sound.cpp +++ b/source/glest_game/menu/menu_state_options_sound.cpp @@ -29,527 +29,479 @@ #include "leak_dumper.h" using namespace - Shared::Util; +Shared::Util; namespace - Glest -{ - namespace - Game - { + Glest { + namespace + Game { -// ===================================================== -// class MenuStateOptions -// ===================================================== - MenuStateOptionsSound::MenuStateOptionsSound (Program * program, - MainMenu * mainMenu, - ProgramState ** parentUI): - MenuState (program, mainMenu, "config"), - buttonOk ("Options_Sound", "buttonOk"), - buttonReturn ("Options_Sound", "buttonReturn"), - buttonKeyboardSetup ("Options_Sound", "buttonKeyboardSetup"), - buttonVideoSection ("Options_Sound", "buttonVideoSection"), - buttonAudioSection ("Options_Sound", "buttonAudioSection"), - buttonMiscSection ("Options_Sound", "buttonMiscSection"), - buttonNetworkSettings ("Options_Sound", "buttonNetworkSettings"), - labelSoundFactory ("Options_Sound", "labelSoundFactory"), - listBoxSoundFactory ("Options_Sound", "listBoxSoundFactory"), - labelVolumeFx ("Options_Sound", "labelVolumeFx"), - listBoxVolumeFx ("Options_Sound", "listBoxVolumeFx"), - labelVolumeAmbient ("Options_Sound", "labelVolumeAmbient"), - listBoxVolumeAmbient ("Options_Sound", "listBoxVolumeAmbient"), - labelVolumeMusic ("Options_Sound", "labelVolumeMusic"), - listBoxVolumeMusic ("Options_Sound", "listBoxVolumeMusic"), - mainMessageBox ("Options_Sound", "mainMessageBox") - { - try - { - containerName = "Options_Sound"; - this-> - parentUI = parentUI; - Lang & - lang = Lang::getInstance (); - Config & - config = Config::getInstance (); - this-> - console. - setOnlyChatMessagesInStoredLines (false); + // ===================================================== + // class MenuStateOptions + // ===================================================== + MenuStateOptionsSound::MenuStateOptionsSound(Program * program, + MainMenu * mainMenu, + ProgramState ** parentUI) : + MenuState(program, mainMenu, "config"), + buttonOk("Options_Sound", "buttonOk"), + buttonReturn("Options_Sound", "buttonReturn"), + buttonKeyboardSetup("Options_Sound", "buttonKeyboardSetup"), + buttonVideoSection("Options_Sound", "buttonVideoSection"), + buttonAudioSection("Options_Sound", "buttonAudioSection"), + buttonMiscSection("Options_Sound", "buttonMiscSection"), + buttonNetworkSettings("Options_Sound", "buttonNetworkSettings"), + labelSoundFactory("Options_Sound", "labelSoundFactory"), + listBoxSoundFactory("Options_Sound", "listBoxSoundFactory"), + labelVolumeFx("Options_Sound", "labelVolumeFx"), + listBoxVolumeFx("Options_Sound", "listBoxVolumeFx"), + labelVolumeAmbient("Options_Sound", "labelVolumeAmbient"), + listBoxVolumeAmbient("Options_Sound", "listBoxVolumeAmbient"), + labelVolumeMusic("Options_Sound", "labelVolumeMusic"), + listBoxVolumeMusic("Options_Sound", "listBoxVolumeMusic"), + mainMessageBox("Options_Sound", "mainMessageBox") { + try { + containerName = "Options_Sound"; + this-> + parentUI = parentUI; + Lang & + lang = Lang::getInstance(); + Config & + config = Config::getInstance(); + this-> + console. + setOnlyChatMessagesInStoredLines(false); - int - leftLabelStart = 100; - int - leftColumnStart = leftLabelStart + 300; - int - buttonRowPos = 50; - int - buttonStartPos = 170; - int - lineOffset = 30; - int - tabButtonWidth = 200; - int - tabButtonHeight = 30; + int + leftLabelStart = 100; + int + leftColumnStart = leftLabelStart + 300; + int + buttonRowPos = 50; + int + buttonStartPos = 170; + int + lineOffset = 30; + int + tabButtonWidth = 200; + int + tabButtonHeight = 30; - mainMessageBox. - init (lang.getString ("Ok")); - mainMessageBox. - setEnabled (false); - mainMessageBoxState = 0; + mainMessageBox. + init(lang.getString("Ok")); + mainMessageBox. + setEnabled(false); + mainMessageBoxState = 0; - buttonAudioSection. - init (0, 700, tabButtonWidth, tabButtonHeight + 20); - buttonAudioSection. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonAudioSection. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonAudioSection. - setText (lang.getString ("Audio")); - // Video Section - buttonVideoSection. - init (200, 720, tabButtonWidth, tabButtonHeight); - buttonVideoSection. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonVideoSection. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonVideoSection. - setText (lang.getString ("Video")); - //currentLine-=lineOffset; - //MiscSection - buttonMiscSection. - init (400, 720, tabButtonWidth, tabButtonHeight); - buttonMiscSection. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonMiscSection. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonMiscSection. - setText (lang.getString ("Misc")); - //NetworkSettings - buttonNetworkSettings. - init (600, 720, tabButtonWidth, tabButtonHeight); - buttonNetworkSettings. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonNetworkSettings. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonNetworkSettings. - setText (lang.getString ("Network")); + buttonAudioSection. + init(0, 700, tabButtonWidth, tabButtonHeight + 20); + buttonAudioSection. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonAudioSection. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonAudioSection. + setText(lang.getString("Audio")); + // Video Section + buttonVideoSection. + init(200, 720, tabButtonWidth, tabButtonHeight); + buttonVideoSection. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonVideoSection. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonVideoSection. + setText(lang.getString("Video")); + //currentLine-=lineOffset; + //MiscSection + buttonMiscSection. + init(400, 720, tabButtonWidth, tabButtonHeight); + buttonMiscSection. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonMiscSection. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonMiscSection. + setText(lang.getString("Misc")); + //NetworkSettings + buttonNetworkSettings. + init(600, 720, tabButtonWidth, tabButtonHeight); + buttonNetworkSettings. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonNetworkSettings. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonNetworkSettings. + setText(lang.getString("Network")); - //KeyboardSetup - buttonKeyboardSetup. - init (800, 720, tabButtonWidth, tabButtonHeight); - buttonKeyboardSetup. - setFont (CoreData::getInstance ().getMenuFontVeryBig ()); - buttonKeyboardSetup. - setFont3D (CoreData::getInstance ().getMenuFontVeryBig3D ()); - buttonKeyboardSetup. - setText (lang.getString ("Keyboardsetup")); + //KeyboardSetup + buttonKeyboardSetup. + init(800, 720, tabButtonWidth, tabButtonHeight); + buttonKeyboardSetup. + setFont(CoreData::getInstance().getMenuFontVeryBig()); + buttonKeyboardSetup. + setFont3D(CoreData::getInstance().getMenuFontVeryBig3D()); + buttonKeyboardSetup. + setText(lang.getString("Keyboardsetup")); - int - currentLine = 650; // reset line pos - int - currentLabelStart = leftLabelStart; // set to right side - int - currentColumnStart = leftColumnStart; // set to right side + int + currentLine = 650; // reset line pos + int + currentLabelStart = leftLabelStart; // set to right side + int + currentColumnStart = leftColumnStart; // set to right side - //soundboxes - labelSoundFactory. - init (currentLabelStart, currentLine); - labelSoundFactory. - setText (lang.getString ("SoundAndMusic2")); + //soundboxes + labelSoundFactory. + init(currentLabelStart, currentLine); + labelSoundFactory. + setText(lang.getString("SoundAndMusic2")); - listBoxSoundFactory. - init (currentColumnStart, currentLine, 175); - listBoxSoundFactory. - pushBackItem (lang.getString ("None")); - listBoxSoundFactory. - pushBackItem ("OpenAL"); + listBoxSoundFactory. + init(currentColumnStart, currentLine, 175); + listBoxSoundFactory. + pushBackItem(lang.getString("None")); + listBoxSoundFactory. + pushBackItem("OpenAL"); - string - FSoundMode = config.getString ("FactorySound"); - string - FSoundModeT = lang.getString (config.getString ("FactorySound")); - if (FSoundModeT != "???" + FSoundMode + "???") - { - FSoundMode = FSoundModeT; - } - listBoxSoundFactory. - setSelectedItem (FSoundMode); - currentLine -= - lineOffset; + string + FSoundMode = config.getString("FactorySound"); + string + FSoundModeT = lang.getString(config.getString("FactorySound")); + if (FSoundModeT != "???" + FSoundMode + "???") { + FSoundMode = FSoundModeT; + } + listBoxSoundFactory. + setSelectedItem(FSoundMode); + currentLine -= + lineOffset; - labelVolumeFx. - init (currentLabelStart, currentLine); - labelVolumeFx. - setText (lang.getString ("FxVolume")); + labelVolumeFx. + init(currentLabelStart, currentLine); + labelVolumeFx. + setText(lang.getString("FxVolume")); - listBoxVolumeFx. - init (currentColumnStart, currentLine, 80); - currentLine -= - lineOffset; + listBoxVolumeFx. + init(currentColumnStart, currentLine, 80); + currentLine -= + lineOffset; - labelVolumeAmbient. - init (currentLabelStart, currentLine); + labelVolumeAmbient. + init(currentLabelStart, currentLine); - listBoxVolumeAmbient. - init (currentColumnStart, currentLine, 80); - labelVolumeAmbient. - setText (lang.getString ("AmbientVolume")); - currentLine -= - lineOffset; + listBoxVolumeAmbient. + init(currentColumnStart, currentLine, 80); + labelVolumeAmbient. + setText(lang.getString("AmbientVolume")); + currentLine -= + lineOffset; - labelVolumeMusic. - init (currentLabelStart, currentLine); + labelVolumeMusic. + init(currentLabelStart, currentLine); - listBoxVolumeMusic. - init (currentColumnStart, currentLine, 80); - labelVolumeMusic. - setText (lang.getString ("MusicVolume")); - //currentLine-=lineOffset; + listBoxVolumeMusic. + init(currentColumnStart, currentLine, 80); + labelVolumeMusic. + setText(lang.getString("MusicVolume")); + //currentLine-=lineOffset; - for (int i = 0; i <= 100; i += 5) - { - listBoxVolumeFx.pushBackItem (intToStr (i)); - listBoxVolumeAmbient. - pushBackItem (intToStr (i)); - listBoxVolumeMusic. - pushBackItem (intToStr (i)); - } - listBoxVolumeFx. - setSelectedItem (intToStr (config.getInt ("SoundVolumeFx") / 5 * 5)); - listBoxVolumeAmbient. - setSelectedItem (intToStr - (config.getInt ("SoundVolumeAmbient") / 5 * 5)); - listBoxVolumeMusic. - setSelectedItem (intToStr - (config.getInt ("SoundVolumeMusic") / 5 * 5)); + for (int i = 0; i <= 100; i += 5) { + listBoxVolumeFx.pushBackItem(intToStr(i)); + listBoxVolumeAmbient. + pushBackItem(intToStr(i)); + listBoxVolumeMusic. + pushBackItem(intToStr(i)); + } + listBoxVolumeFx. + setSelectedItem(intToStr(config.getInt("SoundVolumeFx") / 5 * 5)); + listBoxVolumeAmbient. + setSelectedItem(intToStr + (config.getInt("SoundVolumeAmbient") / 5 * 5)); + listBoxVolumeMusic. + setSelectedItem(intToStr + (config.getInt("SoundVolumeMusic") / 5 * 5)); - //currentLine-=lineOffset/2; + //currentLine-=lineOffset/2; - ////////////////////////////////////////////////////////////////// - ///////// RIGHT SIDE - ////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////// + ///////// RIGHT SIDE + ////////////////////////////////////////////////////////////////// - //currentLine=700; // reset line pos - //currentLabelStart=rightLabelStart; // set to right side - //currentColumnStart=rightColumnStart; // set to right side + //currentLine=700; // reset line pos + //currentLabelStart=rightLabelStart; // set to right side + //currentColumnStart=rightColumnStart; // set to right side - // buttons - buttonOk.init (buttonStartPos, buttonRowPos, 100); - buttonOk.setText (lang.getString ("Save")); - buttonReturn.setText (lang.getString ("Return")); + // buttons + buttonOk.init(buttonStartPos, buttonRowPos, 100); + buttonOk.setText(lang.getString("Save")); + buttonReturn.setText(lang.getString("Return")); - buttonReturn.init (buttonStartPos + 110, buttonRowPos, 100); + buttonReturn.init(buttonStartPos + 110, buttonRowPos, 100); - GraphicComponent::applyAllCustomProperties (containerName); - } - catch (exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error loading options: %s\n", - __FILE__, __FUNCTION__, __LINE__, - e.what ()); - throw - megaglest_runtime_error (string ("Error loading options msg: ") + - e.what ()); - } - } + GraphicComponent::applyAllCustomProperties(containerName); + } catch (exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error loading options: %s\n", + __FILE__, __FUNCTION__, __LINE__, + e.what()); + throw + megaglest_runtime_error(string("Error loading options msg: ") + + e.what()); + } + } - void - MenuStateOptionsSound::reloadUI () - { - Lang & lang = Lang::getInstance (); + void + MenuStateOptionsSound::reloadUI() { + Lang & lang = Lang::getInstance(); - mainMessageBox.init (lang.getString ("Ok")); + mainMessageBox.init(lang.getString("Ok")); - buttonAudioSection.setText (lang.getString ("Audio")); - buttonVideoSection.setText (lang.getString ("Video")); - buttonMiscSection.setText (lang.getString ("Misc")); - buttonNetworkSettings.setText (lang.getString ("Network")); - labelSoundFactory.setText (lang.getString ("SoundAndMusic2")); + buttonAudioSection.setText(lang.getString("Audio")); + buttonVideoSection.setText(lang.getString("Video")); + buttonMiscSection.setText(lang.getString("Misc")); + buttonNetworkSettings.setText(lang.getString("Network")); + labelSoundFactory.setText(lang.getString("SoundAndMusic2")); - std::vector < string > listboxData; - listboxData.push_back (lang.getString ("None")); - listboxData.push_back ("OpenAL"); + std::vector < string > listboxData; + listboxData.push_back(lang.getString("None")); + listboxData.push_back("OpenAL"); - listBoxSoundFactory.setItems (listboxData); + listBoxSoundFactory.setItems(listboxData); - labelVolumeFx.setText (lang.getString ("FxVolume")); - labelVolumeAmbient.setText (lang.getString ("AmbientVolume")); - labelVolumeMusic.setText (lang.getString ("MusicVolume")); + labelVolumeFx.setText(lang.getString("FxVolume")); + labelVolumeAmbient.setText(lang.getString("AmbientVolume")); + labelVolumeMusic.setText(lang.getString("MusicVolume")); - listboxData.clear (); + listboxData.clear(); - buttonOk.setText (lang.getString ("Save")); - buttonReturn.setText (lang.getString ("Return")); - } + buttonOk.setText(lang.getString("Save")); + buttonReturn.setText(lang.getString("Return")); + } - void - MenuStateOptionsSound::mouseClick (int x, int y, MouseButton mouseButton) - { + void + MenuStateOptionsSound::mouseClick(int x, int y, MouseButton mouseButton) { - //Config &config= Config::getInstance(); - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); + //Config &config= Config::getInstance(); + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); - if (mainMessageBox.getEnabled ()) - { - int - button = 0; - if (mainMessageBox.mouseClick (x, y, button)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - if (button == 0) - { - if (mainMessageBoxState == 1) - { - mainMessageBoxState = 0; - mainMessageBox.setEnabled (false); - saveConfig (); + if (mainMessageBox.getEnabled()) { + int + button = 0; + if (mainMessageBox.mouseClick(x, y, button)) { + soundRenderer.playFx(coreData.getClickSoundA()); + if (button == 0) { + if (mainMessageBoxState == 1) { + mainMessageBoxState = 0; + mainMessageBox.setEnabled(false); + saveConfig(); - Lang & lang = Lang::getInstance (); - mainMessageBox.init (lang.getString ("Ok")); - mainMenu->setState (new MenuStateOptions (program, mainMenu)); - } - else - { - mainMessageBox.setEnabled (false); + Lang & lang = Lang::getInstance(); + mainMessageBox.init(lang.getString("Ok")); + mainMenu->setState(new MenuStateOptions(program, mainMenu)); + } else { + mainMessageBox.setEnabled(false); - Lang & lang = Lang::getInstance (); - mainMessageBox.init (lang.getString ("Ok")); - } - } - else - { - if (mainMessageBoxState == 1) - { - mainMessageBoxState = 0; - mainMessageBox.setEnabled (false); + Lang & lang = Lang::getInstance(); + mainMessageBox.init(lang.getString("Ok")); + } + } else { + if (mainMessageBoxState == 1) { + mainMessageBoxState = 0; + mainMessageBox.setEnabled(false); - Lang & lang = Lang::getInstance (); - mainMessageBox.init (lang.getString ("Ok")); + Lang & lang = Lang::getInstance(); + mainMessageBox.init(lang.getString("Ok")); - this->mainMenu->init (); - } - } - } - } - else if (buttonOk.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - saveConfig (); - //mainMenu->setState(new MenuStateOptions(program, mainMenu)); - return; - } - else if (buttonReturn.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - if (this->parentUI != NULL) - { - *this->parentUI = NULL; - delete * - this-> - parentUI; - } - mainMenu->setState (new MenuStateRoot (program, mainMenu)); - return; - } - else if (buttonKeyboardSetup.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - //mainMenu->setState(new MenuStateKeysetup(program, mainMenu)); // open keyboard shortcuts setup screen - //mainMenu->setState(new MenuStateOptionsGraphics(program, mainMenu)); // open keyboard shortcuts setup screen - //mainMenu->setState(new MenuStateOptionsNetwork(program, mainMenu)); // open keyboard shortcuts setup screen - mainMenu->setState (new MenuStateKeysetup (program, mainMenu)); // open keyboard shortcuts setup screen - //showMessageBox("Not implemented yet", "Keyboard setup", false); - return; - } - else if (buttonAudioSection.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - //mainMenu->setState(new MenuStateOptionsSound(program, mainMenu)); // open keyboard shortcuts setup screen - return; - } - else if (buttonNetworkSettings.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptionsNetwork (program, mainMenu)); // open keyboard shortcuts setup screen - return; - } - else if (buttonMiscSection.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptions (program, mainMenu)); // open keyboard shortcuts setup screen - return; - } - else if (buttonVideoSection.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateOptionsGraphics (program, mainMenu)); // open keyboard shortcuts setup screen - return; - } - else - { - listBoxSoundFactory.mouseClick (x, y); - listBoxVolumeFx.mouseClick (x, y); - listBoxVolumeAmbient.mouseClick (x, y); - listBoxVolumeMusic.mouseClick (x, y); - } - } + this->mainMenu->init(); + } + } + } + } else if (buttonOk.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + saveConfig(); + //mainMenu->setState(new MenuStateOptions(program, mainMenu)); + return; + } else if (buttonReturn.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + if (this->parentUI != NULL) { + *this->parentUI = NULL; + delete * + this-> + parentUI; + } + mainMenu->setState(new MenuStateRoot(program, mainMenu)); + return; + } else if (buttonKeyboardSetup.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + //mainMenu->setState(new MenuStateKeysetup(program, mainMenu)); // open keyboard shortcuts setup screen + //mainMenu->setState(new MenuStateOptionsGraphics(program, mainMenu)); // open keyboard shortcuts setup screen + //mainMenu->setState(new MenuStateOptionsNetwork(program, mainMenu)); // open keyboard shortcuts setup screen + mainMenu->setState(new MenuStateKeysetup(program, mainMenu)); // open keyboard shortcuts setup screen + //showMessageBox("Not implemented yet", "Keyboard setup", false); + return; + } else if (buttonAudioSection.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + //mainMenu->setState(new MenuStateOptionsSound(program, mainMenu)); // open keyboard shortcuts setup screen + return; + } else if (buttonNetworkSettings.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptionsNetwork(program, mainMenu)); // open keyboard shortcuts setup screen + return; + } else if (buttonMiscSection.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptions(program, mainMenu)); // open keyboard shortcuts setup screen + return; + } else if (buttonVideoSection.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateOptionsGraphics(program, mainMenu)); // open keyboard shortcuts setup screen + return; + } else { + listBoxSoundFactory.mouseClick(x, y); + listBoxVolumeFx.mouseClick(x, y); + listBoxVolumeAmbient.mouseClick(x, y); + listBoxVolumeMusic.mouseClick(x, y); + } + } - void - MenuStateOptionsSound::mouseMove (int x, int y, const MouseState * ms) - { - if (mainMessageBox.getEnabled ()) - { - mainMessageBox.mouseMove (x, y); - } - buttonOk.mouseMove (x, y); - buttonReturn.mouseMove (x, y); - buttonKeyboardSetup.mouseMove (x, y); - buttonAudioSection.mouseMove (x, y); - buttonNetworkSettings.mouseMove (x, y); - buttonMiscSection.mouseMove (x, y); - buttonVideoSection.mouseMove (x, y); + void + MenuStateOptionsSound::mouseMove(int x, int y, const MouseState * ms) { + if (mainMessageBox.getEnabled()) { + mainMessageBox.mouseMove(x, y); + } + buttonOk.mouseMove(x, y); + buttonReturn.mouseMove(x, y); + buttonKeyboardSetup.mouseMove(x, y); + buttonAudioSection.mouseMove(x, y); + buttonNetworkSettings.mouseMove(x, y); + buttonMiscSection.mouseMove(x, y); + buttonVideoSection.mouseMove(x, y); - listBoxSoundFactory.mouseMove (x, y); - listBoxVolumeFx.mouseMove (x, y); - listBoxVolumeAmbient.mouseMove (x, y); - listBoxVolumeMusic.mouseMove (x, y); - } + listBoxSoundFactory.mouseMove(x, y); + listBoxVolumeFx.mouseMove(x, y); + listBoxVolumeAmbient.mouseMove(x, y); + listBoxVolumeMusic.mouseMove(x, y); + } -//bool MenuStateOptionsSound::isInSpecialKeyCaptureEvent() { -// return (activeInputLabel != NULL); -//} -// -//void MenuStateOptionsSound::keyDown(SDL_KeyboardEvent key) { -// if(activeInputLabel != NULL) { -// keyDownEditLabel(key, &activeInputLabel); -// } -//} + //bool MenuStateOptionsSound::isInSpecialKeyCaptureEvent() { + // return (activeInputLabel != NULL); + //} + // + //void MenuStateOptionsSound::keyDown(SDL_KeyboardEvent key) { + // if(activeInputLabel != NULL) { + // keyDownEditLabel(key, &activeInputLabel); + // } + //} - void - MenuStateOptionsSound::keyPress (SDL_KeyboardEvent c) - { -// if(activeInputLabel != NULL) { -// //printf("[%d]\n",c); fflush(stdout); -// if( &labelPlayerName == activeInputLabel || -// &labelTransifexUser == activeInputLabel || -// &labelTransifexPwd == activeInputLabel || -// &labelTransifexI18N == activeInputLabel) { -// textInputEditLabel(c, &activeInputLabel); -// } -// } -// else { - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - if (isKeyPressed (configKeys.getSDLKey ("SaveGUILayout"), c) == true) - { - GraphicComponent::saveAllCustomProperties (containerName); - //Lang &lang= Lang::getInstance(); - //console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ? lang.getString("Yes") : lang.getString("No"))+ "]"); - } -// } - } + void + MenuStateOptionsSound::keyPress(SDL_KeyboardEvent c) { + // if(activeInputLabel != NULL) { + // //printf("[%d]\n",c); fflush(stdout); + // if( &labelPlayerName == activeInputLabel || + // &labelTransifexUser == activeInputLabel || + // &labelTransifexPwd == activeInputLabel || + // &labelTransifexI18N == activeInputLabel) { + // textInputEditLabel(c, &activeInputLabel); + // } + // } + // else { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), c) == true) { + GraphicComponent::saveAllCustomProperties(containerName); + //Lang &lang= Lang::getInstance(); + //console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ? lang.getString("Yes") : lang.getString("No"))+ "]"); + } + // } + } - void - MenuStateOptionsSound::render () - { - Renderer & renderer = Renderer::getInstance (); + void + MenuStateOptionsSound::render() { + Renderer & renderer = Renderer::getInstance(); - if (mainMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&mainMessageBox); - } - else - { - renderer.renderButton (&buttonOk); - renderer.renderButton (&buttonReturn); - renderer.renderButton (&buttonKeyboardSetup); - renderer.renderButton (&buttonVideoSection); - renderer.renderButton (&buttonAudioSection); - renderer.renderButton (&buttonMiscSection); - renderer.renderButton (&buttonNetworkSettings); - renderer.renderListBox (&listBoxSoundFactory); - renderer.renderLabel (&labelSoundFactory); + if (mainMessageBox.getEnabled()) { + renderer.renderMessageBox(&mainMessageBox); + } else { + renderer.renderButton(&buttonOk); + renderer.renderButton(&buttonReturn); + renderer.renderButton(&buttonKeyboardSetup); + renderer.renderButton(&buttonVideoSection); + renderer.renderButton(&buttonAudioSection); + renderer.renderButton(&buttonMiscSection); + renderer.renderButton(&buttonNetworkSettings); + renderer.renderListBox(&listBoxSoundFactory); + renderer.renderLabel(&labelSoundFactory); - renderer.renderListBox (&listBoxVolumeFx); - renderer.renderLabel (&labelVolumeFx); - renderer.renderListBox (&listBoxVolumeAmbient); - renderer.renderLabel (&labelVolumeAmbient); - renderer.renderListBox (&listBoxVolumeMusic); - renderer.renderLabel (&labelVolumeMusic); + renderer.renderListBox(&listBoxVolumeFx); + renderer.renderLabel(&labelVolumeFx); + renderer.renderListBox(&listBoxVolumeAmbient); + renderer.renderLabel(&labelVolumeAmbient); + renderer.renderListBox(&listBoxVolumeMusic); + renderer.renderLabel(&labelVolumeMusic); - } + } - renderer.renderConsole (&console); - if (program != NULL) - program->renderProgramMsgBox (); - } + renderer.renderConsole(&console); + if (program != NULL) + program->renderProgramMsgBox(); + } - void - MenuStateOptionsSound::saveConfig () - { - Config & config = Config::getInstance (); - Lang & lang = Lang::getInstance (); - setActiveInputLable (NULL); + void + MenuStateOptionsSound::saveConfig() { + Config & config = Config::getInstance(); + Lang & lang = Lang::getInstance(); + setActiveInputLable(NULL); - int - FSoundIndex = listBoxSoundFactory.getSelectedItemIndex (); - string - FSoundMode; - switch (FSoundIndex) - { - case 0: - FSoundMode = "None"; - break; - case 1: - FSoundMode = "OpenAL"; - break; - } - config.setString ("FactorySound", FSoundMode); + int + FSoundIndex = listBoxSoundFactory.getSelectedItemIndex(); + string + FSoundMode; + switch (FSoundIndex) { + case 0: + FSoundMode = "None"; + break; + case 1: + FSoundMode = "OpenAL"; + break; + } + config.setString("FactorySound", FSoundMode); - config.setString ("SoundVolumeFx", listBoxVolumeFx.getSelectedItem ()); - config.setString ("SoundVolumeAmbient", - listBoxVolumeAmbient.getSelectedItem ()); - CoreData::getInstance ().getMenuMusic ()-> - setVolume (strToInt (listBoxVolumeMusic.getSelectedItem ()) / 100.f); - config.setString ("SoundVolumeMusic", - listBoxVolumeMusic.getSelectedItem ()); + config.setString("SoundVolumeFx", listBoxVolumeFx.getSelectedItem()); + config.setString("SoundVolumeAmbient", + listBoxVolumeAmbient.getSelectedItem()); + CoreData::getInstance().getMenuMusic()-> + setVolume(strToInt(listBoxVolumeMusic.getSelectedItem()) / 100.f); + config.setString("SoundVolumeMusic", + listBoxVolumeMusic.getSelectedItem()); - config.save (); + config.save(); - if (config.getBool ("DisableLuaSandbox", "false") == true) - { - LuaScript::setDisableSandbox (true); - } + if (config.getBool("DisableLuaSandbox", "false") == true) { + LuaScript::setDisableSandbox(true); + } - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - soundRenderer.stopAllSounds (); - program->stopSoundSystem (); - soundRenderer.init (program->getWindow ()); - soundRenderer.loadConfig (); - soundRenderer.setMusicVolume (CoreData::getInstance ().getMenuMusic ()); - program->startSoundSystem (); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + soundRenderer.stopAllSounds(); + program->stopSoundSystem(); + soundRenderer.init(program->getWindow()); + soundRenderer.loadConfig(); + soundRenderer.setMusicVolume(CoreData::getInstance().getMenuMusic()); + program->startSoundSystem(); - if (CoreData::getInstance ().hasMainMenuVideoFilename () == false) - { - soundRenderer.playMusic (CoreData::getInstance ().getMenuMusic ()); - } + if (CoreData::getInstance().hasMainMenuVideoFilename() == false) { + soundRenderer.playMusic(CoreData::getInstance().getMenuMusic()); + } - Renderer::getInstance ().loadConfig (); - console.addLine (lang.getString ("SettingsSaved")); - } + Renderer::getInstance().loadConfig(); + console.addLine(lang.getString("SettingsSaved")); + } - void - MenuStateOptionsSound::setActiveInputLable (GraphicLabel * newLable) - { - } + void + MenuStateOptionsSound::setActiveInputLable(GraphicLabel * newLable) { + } -}} //end namespace + } +} //end namespace diff --git a/source/glest_game/menu/menu_state_options_sound.h b/source/glest_game/menu/menu_state_options_sound.h index c8ea1cb50..f29498ce7 100644 --- a/source/glest_game/menu/menu_state_options_sound.h +++ b/source/glest_game/menu/menu_state_options_sound.h @@ -15,65 +15,63 @@ # include "main_menu.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// =============================== -// class MenuStateOptionsSound -// =============================== + // =============================== + // class MenuStateOptionsSound + // =============================== - class MenuStateOptionsSound:public MenuState - { - private: + class MenuStateOptionsSound :public MenuState { + private: - GraphicButton buttonOk; - GraphicButton buttonReturn; + GraphicButton buttonOk; + GraphicButton buttonReturn; - GraphicButton buttonKeyboardSetup; // configure the keyboard - GraphicButton buttonVideoSection; - GraphicButton buttonAudioSection; - GraphicButton buttonMiscSection; - GraphicButton buttonNetworkSettings; + GraphicButton buttonKeyboardSetup; // configure the keyboard + GraphicButton buttonVideoSection; + GraphicButton buttonAudioSection; + GraphicButton buttonMiscSection; + GraphicButton buttonNetworkSettings; - GraphicLabel labelSoundFactory; - GraphicListBox listBoxSoundFactory; + GraphicLabel labelSoundFactory; + GraphicListBox listBoxSoundFactory; - GraphicLabel labelVolumeFx; - GraphicListBox listBoxVolumeFx; + GraphicLabel labelVolumeFx; + GraphicListBox listBoxVolumeFx; - GraphicLabel labelVolumeAmbient; - GraphicListBox listBoxVolumeAmbient; + GraphicLabel labelVolumeAmbient; + GraphicListBox listBoxVolumeAmbient; - GraphicLabel labelVolumeMusic; - GraphicListBox listBoxVolumeMusic; + GraphicLabel labelVolumeMusic; + GraphicListBox listBoxVolumeMusic; - GraphicMessageBox mainMessageBox; - int mainMessageBoxState; + GraphicMessageBox mainMessageBox; + int mainMessageBoxState; - ProgramState **parentUI; + ProgramState **parentUI; - public: - MenuStateOptionsSound (Program * program, MainMenu * mainMenu, - ProgramState ** parentUI = NULL); + public: + MenuStateOptionsSound(Program * program, MainMenu * mainMenu, + ProgramState ** parentUI = NULL); - void mouseClick (int x, int y, MouseButton mouseButton); - void mouseMove (int x, int y, const MouseState * mouseState); - void render (); - //virtual void keyDown(SDL_KeyboardEvent key); - virtual void keyPress (SDL_KeyboardEvent c); - //virtual bool isInSpecialKeyCaptureEvent(); + void mouseClick(int x, int y, MouseButton mouseButton); + void mouseMove(int x, int y, const MouseState * mouseState); + void render(); + //virtual void keyDown(SDL_KeyboardEvent key); + virtual void keyPress(SDL_KeyboardEvent c); + //virtual bool isInSpecialKeyCaptureEvent(); - virtual void reloadUI (); + virtual void reloadUI(); - private: - void saveConfig (); - void setActiveInputLable (GraphicLabel * newLable); - //void showMessageBox(const string &text, const string &header, bool toggle); - }; + private: + void saveConfig(); + void setActiveInputLable(GraphicLabel * newLable); + //void showMessageBox(const string &text, const string &header, bool toggle); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/menu/menu_state_root.cpp b/source/glest_game/menu/menu_state_root.cpp index 12e6b3b58..9b7b48fca 100644 --- a/source/glest_game/menu/menu_state_root.cpp +++ b/source/glest_game/menu/menu_state_root.cpp @@ -31,1115 +31,978 @@ #include "leak_dumper.h" -namespace Glest -{ - namespace Game - { - -// ===================================================== -// class MenuStateRoot -// ===================================================== - - bool MenuStateRoot::gameUpdateChecked = false; - - MenuStateRoot::MenuStateRoot (Program * program, - MainMenu * mainMenu):MenuState (program, - mainMenu, - "root"), - updatesHttpServerThread (NULL), buttonNewGame ("MainMenu", - "buttonNewGame"), - buttonLoadGame ("MainMenu", "buttonLoadGame"), buttonMods ("MainMenu", - "buttonMods"), - buttonOptions ("MainMenu", "buttonOptions"), buttonAbout ("MainMenu", - "buttonAbout"), - buttonExit ("MainMenu", "buttonExit"), labelVersion ("MainMenu", - "labelVersion"), - labelGreeting ("MainMenu", "labelGreeting"), mainMessageBox ("MainMenu", - "mainMessageBox"), - errorMessageBox ("MainMenu", "errorMessageBox"), - ftpMessageBox ("MainMenu", "ftpMessageBox"), popupMenu ("MainMenu", - "popupMenu") - { - containerName = "MainMenu"; - - ftpClientThread = NULL; - lastDownloadProgress = 0; - - Lang & lang = Lang::getInstance (); - int yPos = 440; - int buttonWidth = 200; - int buttonXPosition = (1000 - buttonWidth) / 2; - - - //labelVersion.registerGraphicComponent(containerName,"labelVersion"); - if (EndsWith (glestVersionString, "-dev") == false) - { - labelVersion.init (525, yPos); - labelVersion.setText (glestVersionString); - } - else - { - labelVersion.init (buttonXPosition, yPos); - //labelVersion.setText(glestVersionString + " [" + getCompileDateTime() + ", " + getGITRevisionString() + "]"); - labelVersion.setText (glestVersionString); - } - - labelGreeting.init (labelVersion.getX (), labelVersion.getY () - 16); - labelGreeting.setText (""); - - Steam *steamInstance = - CacheManager::getCachedItem < - Steam * >(GameConstants::steamCacheInstanceKey); - if (steamInstance != NULL) - { - string steamPlayerName = steamInstance->userName (); - labelGreeting.setText ("Welcome Steam Player: " + steamPlayerName); - } - - yPos -= 55; - //buttonNewGame.registerGraphicComponent(containerName,"buttonNewGame"); - buttonNewGame.init (buttonXPosition, yPos, buttonWidth); - yPos -= 40; - //buttonLoadGame.registerGraphicComponent(containerName,"buttonLoadGame"); - buttonLoadGame.init (buttonXPosition, yPos, buttonWidth); - yPos -= 40; - //buttonMods.registerGraphicComponent(containerName,"buttonMods"); - buttonMods.init (buttonXPosition, yPos, buttonWidth); - yPos -= 40; - //buttonOptions.registerGraphicComponent(containerName,"buttonOptions"); - buttonOptions.init (buttonXPosition, yPos, buttonWidth); - yPos -= 40; - //buttonAbout.registerGraphicComponent(containerName,"buttonAbout"); - buttonAbout.init (buttonXPosition, yPos, buttonWidth); - yPos -= 40; - //buttonExit.registerGraphicComponent(containerName,"buttonExit"); - buttonExit.init (buttonXPosition, yPos, buttonWidth); - - buttonNewGame.setText (lang.getString ("NewGame")); - buttonLoadGame.setText (lang.getString ("LoadGame")); - buttonMods.setText (lang.getString ("Mods")); - buttonOptions.setText (lang.getString ("Options")); - buttonAbout.setText (lang.getString ("About")); - buttonExit.setText (lang.getString ("Exit")); - - //mesage box - //mainMessageBox.registerGraphicComponent(containerName,"mainMessageBox"); - mainMessageBox.init (lang.getString ("Yes"), lang.getString ("No")); - mainMessageBox.setEnabled (false); - - //errorMessageBox.registerGraphicComponent(containerName,"errorMessageBox"); - errorMessageBox.init (lang.getString ("Ok")); - errorMessageBox.setEnabled (false); - - //ftpMessageBox.registerGraphicComponent(containerName,"ftpMessageBox"); - ftpMessageBox.init (lang.getString ("Yes"), lang.getString ("No")); - ftpMessageBox.setEnabled (false); - - //PopupMenu popupMenu; - std::vector < string > menuItems; - menuItems.push_back ("1"); - menuItems.push_back ("2"); - menuItems.push_back ("3"); - //popupMenu.registerGraphicComponentOnlyFontCallbacks(containerName, "popupMenu"); - popupMenu.setW (100); - popupMenu.setH (100); - popupMenu.init ("Test Menu", menuItems); - popupMenu.setEnabled (false); - popupMenu.setVisible (false); - - GraphicComponent::applyAllCustomProperties (containerName); - } - - MenuStateRoot::~MenuStateRoot () - { - if (updatesHttpServerThread != NULL) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - updatesHttpServerThread->setSimpleTaskInterfaceValid (false); - updatesHttpServerThread->signalQuit (); - updatesHttpServerThread->setThreadOwnerValid (false); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - if (updatesHttpServerThread->canShutdown (true) == true - && updatesHttpServerThread->shutdownAndWait () == true) - { - delete updatesHttpServerThread; - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - updatesHttpServerThread = NULL; - } - - if (ftpClientThread != NULL) - { - ftpClientThread->setCallBackObject (NULL); - ftpClientThread->signalQuit (); - sleep (0); - if (ftpClientThread->canShutdown (true) == true && - ftpClientThread->shutdownAndWait () == true) - { - delete ftpClientThread; - } - else - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s %d] Error cannot shutdown ftpClientThread\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - //SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("%s", szBuf); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - //publishToMasterserverThread->cleanup(); - } - ftpClientThread = NULL; - -// ftpClientThread->signalQuit(); -// ftpClientThread->setCallBackObject(NULL); -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); -// if( ftpClientThread->shutdownAndWait() == true) { -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); -// delete ftpClientThread; -// } -// ftpClientThread = NULL; -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - - } - - void MenuStateRoot::reloadUI () - { - Lang & lang = Lang::getInstance (); - - console.resetFonts (); - - if (EndsWith (glestVersionString, "-dev") == false) - { - labelVersion.setText (glestVersionString); - } - else - { - //labelVersion.setText(glestVersionString + " [" + getCompileDateTime() + ", " + getGITRevisionString() + "]"); - labelVersion.setText (glestVersionString); - } - - buttonNewGame.setText (lang.getString ("NewGame")); - buttonLoadGame.setText (lang.getString ("LoadGame")); - buttonMods.setText (lang.getString ("Mods")); - buttonOptions.setText (lang.getString ("Options")); - buttonAbout.setText (lang.getString ("About")); - buttonExit.setText (lang.getString ("Exit")); - - mainMessageBox.init (lang.getString ("Yes"), lang.getString ("No")); - errorMessageBox.init (lang.getString ("Ok")); - ftpMessageBox.init (lang.getString ("Yes"), lang.getString ("No")); - - console.resetFonts (); - - GraphicComponent:: - reloadFontsForRegisterGraphicComponents (containerName); - } - - void MenuStateRoot::mouseClick (int x, int y, MouseButton mouseButton) - { - try - { - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - - if (popupMenu.mouseClick (x, y)) - { - //std::pair result = popupMenu.mouseClickedMenuItem(x, y); - popupMenu.mouseClickedMenuItem (x, y); - - //printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first); - } - //exit message box, has to be the last thing to do in this function - else if (mainMessageBox.getEnabled ()) - { - int button = 0; - if (mainMessageBox.mouseClick (x, y, button)) - { - if (button == 0) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - soundRenderer.playFx (coreData.getClickSoundA ()); - program->exit (); - } - else - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - //close message box - mainMessageBox.setEnabled (false); - } - } - } - //exit message box, has to be the last thing to do in this function - else if (errorMessageBox.getEnabled ()) - { - int button = 0; - if (mainMessageBox.mouseClick (x, y, button)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - //close message box - errorMessageBox.setEnabled (false); - } - } - - else if (ftpMessageBox.getEnabled ()) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - - int button = 0; - if (ftpMessageBox.mouseClick (x, y, button)) - { - ftpMessageBox.setEnabled (false); - if (button == 0) - { - startFTPClientIfRequired (); - - lastDownloadProgress = 0; - printf ("Adding ftpFileName [%s] ftpFileURL [%s]\n", - ftpFileName.c_str (), ftpFileURL.c_str ()); - if (ftpClientThread != NULL) - ftpClientThread->addTempFileToRequests (ftpFileName, - ftpFileURL); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), - mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()-> - setOwnerId (mutexOwnerId); - fileFTPProgressList[ftpFileName] = pair < int, string > (0, ""); - safeMutexFTPProgress.ReleaseLock (); - } - } - } - else if (mainMessageBox.getEnabled () == false - && buttonNewGame.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - mainMenu->setState (new MenuStateNewGame (program, mainMenu)); - } - else if (mainMessageBox.getEnabled () == false - && buttonLoadGame.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - mainMenu->setState (new MenuStateLoadGame (program, mainMenu)); - } - else if (mainMessageBox.getEnabled () == false - && buttonMods.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - mainMenu->setState (new MenuStateMods (program, mainMenu)); - } - else if (mainMessageBox.getEnabled () == false - && buttonOptions.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - mainMenu->setState (new MenuStateOptions (program, mainMenu)); - } - else if (mainMessageBox.getEnabled () == false - && buttonAbout.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundB ()); - mainMenu->setState (new MenuStateAbout (program, mainMenu)); - } - else if (buttonExit.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - program->exit (); - } - } - catch (exception & e) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d]\nError in menu event:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, e.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - showErrorMessageBox (szBuf, "", true); - } - } - - void MenuStateRoot::startFTPClientIfRequired () - { - if (ftpClientThread == NULL) - { - // Setup File Transfer thread - Config & config = Config::getInstance (); - - vector < string > tilesetFiles; - vector < string > tilesetFilesUserData; - - vector < string > techTreeFiles; - vector < string > techTreeFilesUserData; - - - findDirs (config.getPathListForType (ptTilesets), tilesetFiles); - findDirs (config.getPathListForType (ptTechs), techTreeFiles); - - vector < string > mapPathList = config.getPathListForType (ptMaps); - std::pair < string, string > mapsPath; - if (mapPathList.empty () == false) - { - mapsPath.first = mapPathList[0]; - } - if (mapPathList.size () > 1) - { - mapsPath.second = mapPathList[1]; - } - std::pair < string, string > tilesetsPath; - vector < string > tilesetsList = - Config::getInstance ().getPathListForType (ptTilesets); - if (tilesetsList.empty () == false) - { - tilesetsPath.first = tilesetsList[0]; - if (tilesetsList.size () > 1) - { - tilesetsPath.second = tilesetsList[1]; - } - } - - std::pair < string, string > techtreesPath; - vector < string > techtreesList = - Config::getInstance ().getPathListForType (ptTechs); - if (techtreesList.empty () == false) - { - techtreesPath.first = techtreesList[0]; - if (techtreesList.size () > 1) - { - techtreesPath.second = techtreesList[1]; - } - } - - std::pair < string, string > scenariosPath; - vector < string > scenariosList = - Config::getInstance ().getPathListForType (ptScenarios); - if (scenariosList.empty () == false) - { - scenariosPath.first = scenariosList[0]; - if (scenariosList.size () > 1) - { - scenariosPath.second = scenariosList[1]; - } - } - - string fileArchiveExtension = - config.getString ("FileArchiveExtension", ""); - string fileArchiveExtractCommand = - config.getString ("FileArchiveExtractCommand", ""); - string fileArchiveExtractCommandParameters = - config.getString ("FileArchiveExtractCommandParameters", ""); - int32 fileArchiveExtractCommandSuccessResult = - config.getInt ("FileArchiveExtractCommandSuccessResult", "0"); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - console.setOnlyChatMessagesInStoredLines (false); - - // Get path to temp files - string tempFilePath = "temp/"; - if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) != - "") - { - tempFilePath = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - tempFilePath; - } - else - { - string userData = config.getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - tempFilePath = userData + tempFilePath; - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Temp files path [%s]\n", tempFilePath.c_str ()); - - ftpClientThread = new FTPClientThread (-1, "", - mapsPath, tilesetsPath, - techtreesPath, scenariosPath, - this, fileArchiveExtension, - fileArchiveExtractCommand, - fileArchiveExtractCommandParameters, - fileArchiveExtractCommandSuccessResult, - tempFilePath); - ftpClientThread->start (); - - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - } - } - - void MenuStateRoot::FTPClient_CallbackEvent (string itemName, - FTP_Client_CallbackType type, - pair < FTP_Client_ResultType, - string > result, - void *userdata) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - Lang & lang = Lang::getInstance (); - if (type == ftp_cct_DownloadProgress) - { - FTPClientCallbackInterface::FtpProgressStats * stats = - (FTPClientCallbackInterface::FtpProgressStats *) userdata; - if (stats != NULL) - { - int fileProgress = 0; - if (stats->download_total > 0) - { - fileProgress = - ((stats->download_now / stats->download_total) * 100.0); - } - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP Callback for [%s] current file [%s] fileProgress = %d [now = %f, total = %f]\n",itemName.c_str(),stats->currentFilename.c_str(), fileProgress,stats->download_now,stats->download_total); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()->setOwnerId (mutexOwnerId); - pair < int, string > lastProgress = fileFTPProgressList[itemName]; - fileFTPProgressList[itemName] = - pair < int, string > (fileProgress, stats->currentFilename); - safeMutexFTPProgress.ReleaseLock (); - - if (itemName != "" - && (lastDownloadProgress < fileProgress - && fileProgress % 25 == 0)) - { - lastDownloadProgress = fileProgress; - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "Downloaded %d%% of file: %s", - fileProgress, itemName.c_str ()); - console.addLine (szBuf); - } - } - } - else if (type == ftp_cct_ExtractProgress) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Got FTP extract Callback for [%s] result = %d [%s]\n", - itemName.c_str (), result.first, result.second.c_str ()); - printf ("Got FTP extract Callback for [%s] result = %d [%s]\n", - itemName.c_str (), result.first, result.second.c_str ()); - - if (userdata == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - lang.getString ("DataMissingExtractDownloadMod").c_str (), - itemName.c_str ()); - //printf("%s\n",szBuf); - console.addLine (szBuf, true); - } - else - { - char *szBuf = (char *) userdata; - //printf("%s\n",szBuf); - console.addLine (szBuf); - } - } - else if (type == ftp_cct_TempFile) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Got FTP Callback for [%s] result = %d [%s]\n", - itemName.c_str (), result.first, result.second.c_str ()); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper - safeMutexFTPProgress ((ftpClientThread != - NULL ? ftpClientThread-> - getProgressMutex () : NULL), mutexOwnerId); - if (ftpClientThread != NULL - && ftpClientThread->getProgressMutex () != NULL) - ftpClientThread->getProgressMutex ()->setOwnerId (mutexOwnerId); - fileFTPProgressList.erase (itemName); - safeMutexFTPProgress.ReleaseLock (); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("### downloaded TEMP file [%s] result = %d\n", - itemName.c_str (), result.first); - - if (result.first == ftp_crt_SUCCESS) - { - // Get path to temp files - string tempFilePath = "temp/"; - if (getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) - != "") - { - tempFilePath = - getGameReadWritePath (GameConstants::path_logs_CacheLookupKey) + - tempFilePath; - } - else - { - Config & config = Config::getInstance (); - string userData = config.getString ("UserData_Root", ""); - if (userData != "") - { - endPathWithSlash (userData); - } - tempFilePath = userData + tempFilePath; - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("Temp files path [%s]\n", tempFilePath.c_str ()); - - // Delete the downloaded archive - if (fileExists (tempFilePath + itemName)) - { - removeFile (tempFilePath + itemName); - } - - bool result = upgradeFilesInTemp (); - if (result == false) - { - string binaryName = - Properties::getApplicationPath () + - extractFileFromDirectoryPath (PlatformExceptionHandler:: - application_binary); - string binaryNameOld = - Properties::getApplicationPath () + - extractFileFromDirectoryPath (PlatformExceptionHandler:: - application_binary) + "__REMOVE"; - bool resultRename = renameFile (binaryName, binaryNameOld); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Rename: [%s] to [%s] result = %d\n",binaryName.c_str(),binaryNameOld.c_str(),resultRename); - printf ("#1 Rename: [%s] to [%s] result = %d errno = %d\n", - binaryName.c_str (), binaryNameOld.c_str (), resultRename, - errno); - - //result = upgradeFilesInTemp(); - binaryName = - Properties::getApplicationPath () + - extractFileFromDirectoryPath (PlatformExceptionHandler:: - application_binary); - binaryNameOld = - tempFilePath + - extractFileFromDirectoryPath (PlatformExceptionHandler:: - application_binary); - resultRename = renameFile (binaryNameOld, binaryName); - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Rename: [%s] to [%s] result = %d\n",binaryName.c_str(),binaryNameOld.c_str(),resultRename); - printf ("#2 Rename: [%s] to [%s] result = %d errno = %d\n", - binaryNameOld.c_str (), binaryName.c_str (), resultRename, - errno); - } - - console.addLine ("Successfully updated, please restart!", true); - } - else - { - curl_version_info_data *curlVersion = - curl_version_info (CURLVERSION_NOW); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "FAILED to download the updates: [%s] using CURL version [%s] [%s]", - itemName.c_str (), curlVersion->version, - result.second.c_str ()); - console.addLine (szBuf, true); - showErrorMessageBox (szBuf, "ERROR", false); - } - } - } - - - void MenuStateRoot::mouseMove (int x, int y, const MouseState * ms) - { - popupMenu.mouseMove (x, y); - buttonNewGame.mouseMove (x, y); - buttonLoadGame.mouseMove (x, y); - buttonMods.mouseMove (x, y); - buttonOptions.mouseMove (x, y); - buttonAbout.mouseMove (x, y); - buttonExit.mouseMove (x, y); - if (mainMessageBox.getEnabled ()) - { - mainMessageBox.mouseMove (x, y); - } - if (errorMessageBox.getEnabled ()) - { - errorMessageBox.mouseMove (x, y); - } - if (ftpMessageBox.getEnabled ()) - { - ftpMessageBox.mouseMove (x, y); - } - } - - bool MenuStateRoot::isMasterserverMode () const - { - return GlobalStaticFlags::getIsNonGraphicalModeEnabled (); - } - - void MenuStateRoot::render () - { - if (isMasterserverMode () == true) - { - return; - } - Renderer & renderer = Renderer::getInstance (); - CoreData & coreData = CoreData::getInstance (); - const Metrics & metrics = Metrics::getInstance (); - - int w = 400; - int h = 200; - int yPos = 510; - - int logoMainX = (metrics.getVirtualW () - w) / 2; - int logoMainY = yPos - h / 2; - int logoMainW = w; - int logoMainH = h; - logoMainX = - Config::getInstance ().getInt (string (containerName) + "_MainLogo_x", - intToStr (logoMainX).c_str ()); - logoMainY = - Config::getInstance ().getInt (string (containerName) + "_MainLogo_y", - intToStr (logoMainY).c_str ()); - logoMainW = - Config::getInstance ().getInt (string (containerName) + "_MainLogo_w", - intToStr (logoMainW).c_str ()); - logoMainH = - Config::getInstance ().getInt (string (containerName) + "_MainLogo_h", - intToStr (logoMainH).c_str ()); - - renderer.renderTextureQuad (logoMainX, logoMainY, logoMainW, logoMainH, - coreData.getLogoTexture (), - GraphicComponent::getFade ()); - - int maxLogoWidth = 0; - for (int idx = 0; idx < (int) coreData.getLogoTextureExtraCount (); - ++idx) - { - Texture2D *extraLogo = coreData.getLogoTextureExtra (idx); - maxLogoWidth += extraLogo->getPixmap ()->getW (); - } - - int currentX = (metrics.getVirtualW () - maxLogoWidth) / 2; - int currentY = 50; - for (int idx = 0; idx < (int) coreData.getLogoTextureExtraCount (); - ++idx) - { - Texture2D *extraLogo = coreData.getLogoTextureExtra (idx); - - logoMainX = currentX; - logoMainY = currentY; - logoMainW = extraLogo->getPixmap ()->getW (); - logoMainH = extraLogo->getPixmap ()->getH (); - - string logoTagName = - string (containerName) + "_ExtraLogo" + intToStr (idx + 1) + "_"; - logoMainX = - Config::getInstance ().getInt (logoTagName + "x", - intToStr (logoMainX).c_str ()); - logoMainY = - Config::getInstance ().getInt (logoTagName + "y", - intToStr (logoMainY).c_str ()); - logoMainW = - Config::getInstance ().getInt (logoTagName + "w", - intToStr (logoMainW).c_str ()); - logoMainH = - Config::getInstance ().getInt (logoTagName + "h", - intToStr (logoMainH).c_str ()); - - renderer.renderTextureQuad (logoMainX, logoMainY, - logoMainW, logoMainH, - extraLogo, GraphicComponent::getFade ()); - - currentX += extraLogo->getPixmap ()->getW (); - } - - renderer.renderButton (&buttonNewGame); - renderer.renderButton (&buttonLoadGame); - renderer.renderButton (&buttonMods); - renderer.renderButton (&buttonOptions); - renderer.renderButton (&buttonAbout); - renderer.renderButton (&buttonExit); - renderer.renderLabel (&labelVersion); - renderer.renderLabel (&labelGreeting); - - renderer.renderConsole (&console); - - renderer.renderPopupMenu (&popupMenu); - - //exit message box - if (mainMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&mainMessageBox); - } - if (errorMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&errorMessageBox); - } - if (ftpMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&ftpMessageBox); - } - - if (program != NULL) - program->renderProgramMsgBox (); - } - - void MenuStateRoot::update () - { - if (Config::getInstance ().getBool ("AutoTest")) - { - if (AutoTest::getInstance ().mustExitGame () == false) - { - AutoTest::getInstance ().updateRoot (program, mainMenu); - } - else - { - program->exit (); - } - return; - } - - if (gameUpdateChecked == false) - { - gameUpdateChecked = true; - - string updateCheckURL = - Config::getInstance ().getString ("UpdateCheckURL", ""); - if (updateCheckURL != "") - { - static string mutexOwnerId = - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - string ("_") + intToStr (__LINE__); - updatesHttpServerThread = new SimpleTaskThread (this, 1, 200); - updatesHttpServerThread->setUniqueID (mutexOwnerId); - updatesHttpServerThread->start (); - } - } - - console.update (); - } - - void MenuStateRoot::simpleTask (BaseThread * callingThread, - void *userdata) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutexThreadOwner (callingThread-> - getMutexThreadOwnerValid (), - mutexOwnerId); - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - return; - } - - callingThread->getMutexThreadOwnerValid ()->setOwnerId (mutexOwnerId); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); - - - string updateCheckURL = - Config::getInstance ().getString ("UpdateCheckURL", ""); - if (updateCheckURL != "") - { - - string baseURL = updateCheckURL; - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line %d] About to call first http url, base [%s]..\n", - __FILE__, __FUNCTION__, __LINE__, baseURL.c_str ()); - - CURL *handle = SystemFlags::initHTTP (); - CURLcode curlResult = CURLE_OK; - string updateMetaData = - SystemFlags::getHTTP (baseURL, handle, -1, &curlResult); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("techsMetaData [%s] curlResult = %d\n", - updateMetaData.c_str (), curlResult); - - if (callingThread->getQuitStatus () == true - || safeMutexThreadOwner.isValidMutex () == false) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, - __LINE__); - return; - } - - if (curlResult != CURLE_OK) - { - string curlError = curl_easy_strerror (curlResult); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line %d] curlError [%s]..\n", __FILE__, - __FUNCTION__, __LINE__, curlError.c_str ()); - - char szMsg[8096] = ""; - snprintf (szMsg, 8096, - "An error was detected while checking for new updates\n%s", - curlError.c_str ()); - showErrorMessageBox (szMsg, "ERROR", false); - } - - if (curlResult == CURLE_OK || - (curlResult != CURLE_COULDNT_RESOLVE_HOST && - curlResult != CURLE_COULDNT_CONNECT)) - { - - Properties props; - props.loadFromText (updateMetaData); - - int compareResult = - compareMajorMinorVersion (glestVersionString, - props.getString ("LatestGameVersion", - "")); - if (compareResult == 0) - { - if (glestVersionString != - props.getString ("LatestGameVersion", "")) - { - compareResult = -1; - } - } - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("compareResult = %d local [%s] remote [%s]\n", - compareResult, glestVersionString.c_str (), - props.getString ("LatestGameVersion", "").c_str ()); - - if (compareResult < 0) - { - - string downloadBinaryKey = - "LatestGameBinaryUpdateArchiveURL-" + - getPlatformTypeNameString () + getPlatformArchTypeNameString (); - if (props.hasString (downloadBinaryKey)) - { - ftpFileName = - extractFileFromDirectoryPath (props. - getString (downloadBinaryKey)); - ftpFileURL = props.getString (downloadBinaryKey); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("Checking update key downloadBinaryKey [%s] ftpFileURL [%s]\n", - downloadBinaryKey.c_str (), ftpFileURL.c_str ()); - - if (props.getBool ("AllowUpdateDownloads", "false") == false - || ftpFileURL == "") - { - char szMsg[8096] = ""; - snprintf (szMsg, 8096, - "A new update was detected: %s\nUpdate Date: %s\nPlease visit zetaglest.github.io for details!", - props.getString ("LatestGameVersion", "?").c_str (), - props.getString ("LatestGameVersionReleaseDate", - "?").c_str ()); - showFTPMessageBox (szMsg, "Update", false, true); - } - else - { - char szMsg[8096] = ""; - snprintf (szMsg, 8096, - "A new update was detected: %s\nUpdate Date: %s\nDownload update now?", - props.getString ("LatestGameVersion", "?").c_str (), - props.getString ("LatestGameVersionReleaseDate", - "?").c_str ()); - showFTPMessageBox (szMsg, "Update", false, false); - } - } - } - SystemFlags::cleanupHTTP (&handle); - } - } - - void MenuStateRoot::keyDown (SDL_KeyboardEvent key) - { - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] key = [%c] [%d]\n", - __FILE__, __FUNCTION__, __LINE__, - key.keysym.sym, key.keysym.sym); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] key = [%d - %c]\n", __FILE__, - __FUNCTION__, __LINE__, key.keysym.sym, key.keysym.sym); - - //printf("\n\n\nIN MENU STATE ROOT KEYDOWN!!!\n\n\n"); - - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - //exit - //if(key == configKeys.getCharKey("ExitKey")) { - //printf("Check Root menu exit key!\n"); - if (isKeyPressed (configKeys.getSDLKey ("ExitKey"), key) == true) - { - Lang & lang = Lang::getInstance (); - showMessageBox (lang.getString ("ExitGameQuestion"), "", true); - } - //else if(mainMessageBox.getEnabled() == true && key == vkReturn) { - else if (mainMessageBox.getEnabled () == true - && isKeyPressed (SDLK_RETURN, key) == true) - { - //SDL_keysym keystate = Window::getKeystate(); - SDL_keysym keystate = key.keysym; - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] keystate.mod [%d]\n", - __FILE__, __FUNCTION__, __LINE__, - keystate.mod); - - //printf("---> keystate.mod [%d]\n",keystate.mod); - if (keystate.mod & (KMOD_LALT | KMOD_RALT)) - { - } - else - { - //printf("EXITING ---> keystate.mod [%d]\n",keystate.mod); - program->exit (); - } - } - //else if(key == configKeys.getCharKey("SaveGUILayout")) { - else if (isKeyPressed (configKeys.getSDLKey ("SaveGUILayout"), key) == - true) - { - GraphicComponent::saveAllCustomProperties (containerName); - //Lang &lang= Lang::getInstance(); - //console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ? lang.getString("Yes") : lang.getString("No"))+ "]"); - } - - } - - void MenuStateRoot::showMessageBox (const string & text, - const string & header, bool toggle) - { - if (toggle == false) - { - mainMessageBox.setEnabled (false); - } - - if (mainMessageBox.getEnabled () == false) - { - mainMessageBox.setText (text); - mainMessageBox.setHeader (header); - mainMessageBox.setEnabled (true); - } - else - { - mainMessageBox.setEnabled (false); - } - } - - void MenuStateRoot::showErrorMessageBox (const string & text, - const string & header, - bool toggle) - { - if (toggle == false) - { - errorMessageBox.setEnabled (false); - } - - if (errorMessageBox.getEnabled () == false) - { - errorMessageBox.setText (text); - errorMessageBox.setHeader (header); - errorMessageBox.setEnabled (true); - } - else - { - errorMessageBox.setEnabled (false); - } - } - - void MenuStateRoot::showFTPMessageBox (const string & text, - const string & header, bool toggle, - bool okOnly) - { - if (toggle == false) - { - ftpMessageBox.setEnabled (false); - } - - Lang & lang = Lang::getInstance (); - if (okOnly) - { - ftpMessageBox.init (lang.getString ("Ok")); - } - else - { - ftpMessageBox.init (lang.getString ("Yes"), lang.getString ("No")); - } - - if (ftpMessageBox.getEnabled () == false) - { - ftpMessageBox.setText (text); - ftpMessageBox.setHeader (header); - ftpMessageBox.setEnabled (true); - } - else - { - ftpMessageBox.setEnabled (false); - } - } - - - } +namespace Glest { + namespace Game { + + // ===================================================== + // class MenuStateRoot + // ===================================================== + + bool MenuStateRoot::gameUpdateChecked = false; + + MenuStateRoot::MenuStateRoot(Program * program, + MainMenu * mainMenu) :MenuState(program, + mainMenu, + "root"), + updatesHttpServerThread(NULL), buttonNewGame("MainMenu", + "buttonNewGame"), + buttonLoadGame("MainMenu", "buttonLoadGame"), buttonMods("MainMenu", + "buttonMods"), + buttonOptions("MainMenu", "buttonOptions"), buttonAbout("MainMenu", + "buttonAbout"), + buttonExit("MainMenu", "buttonExit"), labelVersion("MainMenu", + "labelVersion"), + labelGreeting("MainMenu", "labelGreeting"), mainMessageBox("MainMenu", + "mainMessageBox"), + errorMessageBox("MainMenu", "errorMessageBox"), + ftpMessageBox("MainMenu", "ftpMessageBox"), popupMenu("MainMenu", + "popupMenu") { + containerName = "MainMenu"; + + ftpClientThread = NULL; + lastDownloadProgress = 0; + + Lang & lang = Lang::getInstance(); + int yPos = 440; + int buttonWidth = 200; + int buttonXPosition = (1000 - buttonWidth) / 2; + + + //labelVersion.registerGraphicComponent(containerName,"labelVersion"); + if (EndsWith(glestVersionString, "-dev") == false) { + labelVersion.init(525, yPos); + labelVersion.setText(glestVersionString); + } else { + labelVersion.init(buttonXPosition, yPos); + //labelVersion.setText(glestVersionString + " [" + getCompileDateTime() + ", " + getGITRevisionString() + "]"); + labelVersion.setText(glestVersionString); + } + + labelGreeting.init(labelVersion.getX(), labelVersion.getY() - 16); + labelGreeting.setText(""); + + Steam *steamInstance = + CacheManager::getCachedItem < + Steam * >(GameConstants::steamCacheInstanceKey); + if (steamInstance != NULL) { + string steamPlayerName = steamInstance->userName(); + labelGreeting.setText("Welcome Steam Player: " + steamPlayerName); + } + + yPos -= 55; + //buttonNewGame.registerGraphicComponent(containerName,"buttonNewGame"); + buttonNewGame.init(buttonXPosition, yPos, buttonWidth); + yPos -= 40; + //buttonLoadGame.registerGraphicComponent(containerName,"buttonLoadGame"); + buttonLoadGame.init(buttonXPosition, yPos, buttonWidth); + yPos -= 40; + //buttonMods.registerGraphicComponent(containerName,"buttonMods"); + buttonMods.init(buttonXPosition, yPos, buttonWidth); + yPos -= 40; + //buttonOptions.registerGraphicComponent(containerName,"buttonOptions"); + buttonOptions.init(buttonXPosition, yPos, buttonWidth); + yPos -= 40; + //buttonAbout.registerGraphicComponent(containerName,"buttonAbout"); + buttonAbout.init(buttonXPosition, yPos, buttonWidth); + yPos -= 40; + //buttonExit.registerGraphicComponent(containerName,"buttonExit"); + buttonExit.init(buttonXPosition, yPos, buttonWidth); + + buttonNewGame.setText(lang.getString("NewGame")); + buttonLoadGame.setText(lang.getString("LoadGame")); + buttonMods.setText(lang.getString("Mods")); + buttonOptions.setText(lang.getString("Options")); + buttonAbout.setText(lang.getString("About")); + buttonExit.setText(lang.getString("Exit")); + + //mesage box + //mainMessageBox.registerGraphicComponent(containerName,"mainMessageBox"); + mainMessageBox.init(lang.getString("Yes"), lang.getString("No")); + mainMessageBox.setEnabled(false); + + //errorMessageBox.registerGraphicComponent(containerName,"errorMessageBox"); + errorMessageBox.init(lang.getString("Ok")); + errorMessageBox.setEnabled(false); + + //ftpMessageBox.registerGraphicComponent(containerName,"ftpMessageBox"); + ftpMessageBox.init(lang.getString("Yes"), lang.getString("No")); + ftpMessageBox.setEnabled(false); + + //PopupMenu popupMenu; + std::vector < string > menuItems; + menuItems.push_back("1"); + menuItems.push_back("2"); + menuItems.push_back("3"); + //popupMenu.registerGraphicComponentOnlyFontCallbacks(containerName, "popupMenu"); + popupMenu.setW(100); + popupMenu.setH(100); + popupMenu.init("Test Menu", menuItems); + popupMenu.setEnabled(false); + popupMenu.setVisible(false); + + GraphicComponent::applyAllCustomProperties(containerName); + } + + MenuStateRoot::~MenuStateRoot() { + if (updatesHttpServerThread != NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + updatesHttpServerThread->setSimpleTaskInterfaceValid(false); + updatesHttpServerThread->signalQuit(); + updatesHttpServerThread->setThreadOwnerValid(false); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + if (updatesHttpServerThread->canShutdown(true) == true + && updatesHttpServerThread->shutdownAndWait() == true) { + delete updatesHttpServerThread; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + updatesHttpServerThread = NULL; + } + + if (ftpClientThread != NULL) { + ftpClientThread->setCallBackObject(NULL); + ftpClientThread->signalQuit(); + sleep(0); + if (ftpClientThread->canShutdown(true) == true && + ftpClientThread->shutdownAndWait() == true) { + delete ftpClientThread; + } else { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s %d] Error cannot shutdown ftpClientThread\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("%s", szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + //publishToMasterserverThread->cleanup(); + } + ftpClientThread = NULL; + + // ftpClientThread->signalQuit(); + // ftpClientThread->setCallBackObject(NULL); + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + // if( ftpClientThread->shutdownAndWait() == true) { + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + // delete ftpClientThread; + // } + // ftpClientThread = NULL; + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + + } + + void MenuStateRoot::reloadUI() { + Lang & lang = Lang::getInstance(); + + console.resetFonts(); + + if (EndsWith(glestVersionString, "-dev") == false) { + labelVersion.setText(glestVersionString); + } else { + //labelVersion.setText(glestVersionString + " [" + getCompileDateTime() + ", " + getGITRevisionString() + "]"); + labelVersion.setText(glestVersionString); + } + + buttonNewGame.setText(lang.getString("NewGame")); + buttonLoadGame.setText(lang.getString("LoadGame")); + buttonMods.setText(lang.getString("Mods")); + buttonOptions.setText(lang.getString("Options")); + buttonAbout.setText(lang.getString("About")); + buttonExit.setText(lang.getString("Exit")); + + mainMessageBox.init(lang.getString("Yes"), lang.getString("No")); + errorMessageBox.init(lang.getString("Ok")); + ftpMessageBox.init(lang.getString("Yes"), lang.getString("No")); + + console.resetFonts(); + + GraphicComponent:: + reloadFontsForRegisterGraphicComponents(containerName); + } + + void MenuStateRoot::mouseClick(int x, int y, MouseButton mouseButton) { + try { + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + + if (popupMenu.mouseClick(x, y)) { + //std::pair result = popupMenu.mouseClickedMenuItem(x, y); + popupMenu.mouseClickedMenuItem(x, y); + + //printf("In popup callback menuItemSelected [%s] menuIndexSelected = %d\n",result.second.c_str(),result.first); + } + //exit message box, has to be the last thing to do in this function + else if (mainMessageBox.getEnabled()) { + int button = 0; + if (mainMessageBox.mouseClick(x, y, button)) { + if (button == 0) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + soundRenderer.playFx(coreData.getClickSoundA()); + program->exit(); + } else { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + //close message box + mainMessageBox.setEnabled(false); + } + } + } + //exit message box, has to be the last thing to do in this function + else if (errorMessageBox.getEnabled()) { + int button = 0; + if (mainMessageBox.mouseClick(x, y, button)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + //close message box + errorMessageBox.setEnabled(false); + } + } + + else if (ftpMessageBox.getEnabled()) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + + int button = 0; + if (ftpMessageBox.mouseClick(x, y, button)) { + ftpMessageBox.setEnabled(false); + if (button == 0) { + startFTPClientIfRequired(); + + lastDownloadProgress = 0; + printf("Adding ftpFileName [%s] ftpFileURL [%s]\n", + ftpFileName.c_str(), ftpFileURL.c_str()); + if (ftpClientThread != NULL) + ftpClientThread->addTempFileToRequests(ftpFileName, + ftpFileURL); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), + mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()-> + setOwnerId(mutexOwnerId); + fileFTPProgressList[ftpFileName] = pair < int, string >(0, ""); + safeMutexFTPProgress.ReleaseLock(); + } + } + } else if (mainMessageBox.getEnabled() == false + && buttonNewGame.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundB()); + mainMenu->setState(new MenuStateNewGame(program, mainMenu)); + } else if (mainMessageBox.getEnabled() == false + && buttonLoadGame.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundB()); + mainMenu->setState(new MenuStateLoadGame(program, mainMenu)); + } else if (mainMessageBox.getEnabled() == false + && buttonMods.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundB()); + mainMenu->setState(new MenuStateMods(program, mainMenu)); + } else if (mainMessageBox.getEnabled() == false + && buttonOptions.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundB()); + mainMenu->setState(new MenuStateOptions(program, mainMenu)); + } else if (mainMessageBox.getEnabled() == false + && buttonAbout.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundB()); + mainMenu->setState(new MenuStateAbout(program, mainMenu)); + } else if (buttonExit.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + program->exit(); + } + } catch (exception & e) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d]\nError in menu event:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, e.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + showErrorMessageBox(szBuf, "", true); + } + } + + void MenuStateRoot::startFTPClientIfRequired() { + if (ftpClientThread == NULL) { + // Setup File Transfer thread + Config & config = Config::getInstance(); + + vector < string > tilesetFiles; + vector < string > tilesetFilesUserData; + + vector < string > techTreeFiles; + vector < string > techTreeFilesUserData; + + + findDirs(config.getPathListForType(ptTilesets), tilesetFiles); + findDirs(config.getPathListForType(ptTechs), techTreeFiles); + + vector < string > mapPathList = config.getPathListForType(ptMaps); + std::pair < string, string > mapsPath; + if (mapPathList.empty() == false) { + mapsPath.first = mapPathList[0]; + } + if (mapPathList.size() > 1) { + mapsPath.second = mapPathList[1]; + } + std::pair < string, string > tilesetsPath; + vector < string > tilesetsList = + Config::getInstance().getPathListForType(ptTilesets); + if (tilesetsList.empty() == false) { + tilesetsPath.first = tilesetsList[0]; + if (tilesetsList.size() > 1) { + tilesetsPath.second = tilesetsList[1]; + } + } + + std::pair < string, string > techtreesPath; + vector < string > techtreesList = + Config::getInstance().getPathListForType(ptTechs); + if (techtreesList.empty() == false) { + techtreesPath.first = techtreesList[0]; + if (techtreesList.size() > 1) { + techtreesPath.second = techtreesList[1]; + } + } + + std::pair < string, string > scenariosPath; + vector < string > scenariosList = + Config::getInstance().getPathListForType(ptScenarios); + if (scenariosList.empty() == false) { + scenariosPath.first = scenariosList[0]; + if (scenariosList.size() > 1) { + scenariosPath.second = scenariosList[1]; + } + } + + string fileArchiveExtension = + config.getString("FileArchiveExtension", ""); + string fileArchiveExtractCommand = + config.getString("FileArchiveExtractCommand", ""); + string fileArchiveExtractCommandParameters = + config.getString("FileArchiveExtractCommandParameters", ""); + int32 fileArchiveExtractCommandSuccessResult = + config.getInt("FileArchiveExtractCommandSuccessResult", "0"); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + console.setOnlyChatMessagesInStoredLines(false); + + // Get path to temp files + string tempFilePath = "temp/"; + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != + "") { + tempFilePath = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + tempFilePath; + } else { + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + tempFilePath = userData + tempFilePath; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Temp files path [%s]\n", tempFilePath.c_str()); + + ftpClientThread = new FTPClientThread(-1, "", + mapsPath, tilesetsPath, + techtreesPath, scenariosPath, + this, fileArchiveExtension, + fileArchiveExtractCommand, + fileArchiveExtractCommandParameters, + fileArchiveExtractCommandSuccessResult, + tempFilePath); + ftpClientThread->start(); + + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + } + + void MenuStateRoot::FTPClient_CallbackEvent(string itemName, + FTP_Client_CallbackType type, + pair < FTP_Client_ResultType, + string > result, + void *userdata) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + Lang & lang = Lang::getInstance(); + if (type == ftp_cct_DownloadProgress) { + FTPClientCallbackInterface::FtpProgressStats * stats = + (FTPClientCallbackInterface::FtpProgressStats *) userdata; + if (stats != NULL) { + int fileProgress = 0; + if (stats->download_total > 0) { + fileProgress = + ((stats->download_now / stats->download_total) * 100.0); + } + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got FTP Callback for [%s] current file [%s] fileProgress = %d [now = %f, total = %f]\n",itemName.c_str(),stats->currentFilename.c_str(), fileProgress,stats->download_now,stats->download_total); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + pair < int, string > lastProgress = fileFTPProgressList[itemName]; + fileFTPProgressList[itemName] = + pair < int, string >(fileProgress, stats->currentFilename); + safeMutexFTPProgress.ReleaseLock(); + + if (itemName != "" + && (lastDownloadProgress < fileProgress + && fileProgress % 25 == 0)) { + lastDownloadProgress = fileProgress; + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Downloaded %d%% of file: %s", + fileProgress, itemName.c_str()); + console.addLine(szBuf); + } + } + } else if (type == ftp_cct_ExtractProgress) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Got FTP extract Callback for [%s] result = %d [%s]\n", + itemName.c_str(), result.first, result.second.c_str()); + printf("Got FTP extract Callback for [%s] result = %d [%s]\n", + itemName.c_str(), result.first, result.second.c_str()); + + if (userdata == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + lang.getString("DataMissingExtractDownloadMod").c_str(), + itemName.c_str()); + //printf("%s\n",szBuf); + console.addLine(szBuf, true); + } else { + char *szBuf = (char *) userdata; + //printf("%s\n",szBuf); + console.addLine(szBuf); + } + } else if (type == ftp_cct_TempFile) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Got FTP Callback for [%s] result = %d [%s]\n", + itemName.c_str(), result.first, result.second.c_str()); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper + safeMutexFTPProgress((ftpClientThread != + NULL ? ftpClientThread-> + getProgressMutex() : NULL), mutexOwnerId); + if (ftpClientThread != NULL + && ftpClientThread->getProgressMutex() != NULL) + ftpClientThread->getProgressMutex()->setOwnerId(mutexOwnerId); + fileFTPProgressList.erase(itemName); + safeMutexFTPProgress.ReleaseLock(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("### downloaded TEMP file [%s] result = %d\n", + itemName.c_str(), result.first); + + if (result.first == ftp_crt_SUCCESS) { + // Get path to temp files + string tempFilePath = "temp/"; + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + != "") { + tempFilePath = + getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + + tempFilePath; + } else { + Config & config = Config::getInstance(); + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + tempFilePath = userData + tempFilePath; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("Temp files path [%s]\n", tempFilePath.c_str()); + + // Delete the downloaded archive + if (fileExists(tempFilePath + itemName)) { + removeFile(tempFilePath + itemName); + } + + bool result = upgradeFilesInTemp(); + if (result == false) { + string binaryName = + Properties::getApplicationPath() + + extractFileFromDirectoryPath(PlatformExceptionHandler:: + application_binary); + string binaryNameOld = + Properties::getApplicationPath() + + extractFileFromDirectoryPath(PlatformExceptionHandler:: + application_binary) + "__REMOVE"; + bool resultRename = renameFile(binaryName, binaryNameOld); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Rename: [%s] to [%s] result = %d\n",binaryName.c_str(),binaryNameOld.c_str(),resultRename); + printf("#1 Rename: [%s] to [%s] result = %d errno = %d\n", + binaryName.c_str(), binaryNameOld.c_str(), resultRename, + errno); + + //result = upgradeFilesInTemp(); + binaryName = + Properties::getApplicationPath() + + extractFileFromDirectoryPath(PlatformExceptionHandler:: + application_binary); + binaryNameOld = + tempFilePath + + extractFileFromDirectoryPath(PlatformExceptionHandler:: + application_binary); + resultRename = renameFile(binaryNameOld, binaryName); + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Rename: [%s] to [%s] result = %d\n",binaryName.c_str(),binaryNameOld.c_str(),resultRename); + printf("#2 Rename: [%s] to [%s] result = %d errno = %d\n", + binaryNameOld.c_str(), binaryName.c_str(), resultRename, + errno); + } + + console.addLine("Successfully updated, please restart!", true); + } else { + curl_version_info_data *curlVersion = + curl_version_info(CURLVERSION_NOW); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "FAILED to download the updates: [%s] using CURL version [%s] [%s]", + itemName.c_str(), curlVersion->version, + result.second.c_str()); + console.addLine(szBuf, true); + showErrorMessageBox(szBuf, "ERROR", false); + } + } + } + + + void MenuStateRoot::mouseMove(int x, int y, const MouseState * ms) { + popupMenu.mouseMove(x, y); + buttonNewGame.mouseMove(x, y); + buttonLoadGame.mouseMove(x, y); + buttonMods.mouseMove(x, y); + buttonOptions.mouseMove(x, y); + buttonAbout.mouseMove(x, y); + buttonExit.mouseMove(x, y); + if (mainMessageBox.getEnabled()) { + mainMessageBox.mouseMove(x, y); + } + if (errorMessageBox.getEnabled()) { + errorMessageBox.mouseMove(x, y); + } + if (ftpMessageBox.getEnabled()) { + ftpMessageBox.mouseMove(x, y); + } + } + + bool MenuStateRoot::isMasterserverMode() const { + return GlobalStaticFlags::getIsNonGraphicalModeEnabled(); + } + + void MenuStateRoot::render() { + if (isMasterserverMode() == true) { + return; + } + Renderer & renderer = Renderer::getInstance(); + CoreData & coreData = CoreData::getInstance(); + const Metrics & metrics = Metrics::getInstance(); + + int w = 400; + int h = 200; + int yPos = 510; + + int logoMainX = (metrics.getVirtualW() - w) / 2; + int logoMainY = yPos - h / 2; + int logoMainW = w; + int logoMainH = h; + logoMainX = + Config::getInstance().getInt(string(containerName) + "_MainLogo_x", + intToStr(logoMainX).c_str()); + logoMainY = + Config::getInstance().getInt(string(containerName) + "_MainLogo_y", + intToStr(logoMainY).c_str()); + logoMainW = + Config::getInstance().getInt(string(containerName) + "_MainLogo_w", + intToStr(logoMainW).c_str()); + logoMainH = + Config::getInstance().getInt(string(containerName) + "_MainLogo_h", + intToStr(logoMainH).c_str()); + + renderer.renderTextureQuad(logoMainX, logoMainY, logoMainW, logoMainH, + coreData.getLogoTexture(), + GraphicComponent::getFade()); + + int maxLogoWidth = 0; + for (int idx = 0; idx < (int) coreData.getLogoTextureExtraCount(); + ++idx) { + Texture2D *extraLogo = coreData.getLogoTextureExtra(idx); + maxLogoWidth += extraLogo->getPixmap()->getW(); + } + + int currentX = (metrics.getVirtualW() - maxLogoWidth) / 2; + int currentY = 50; + for (int idx = 0; idx < (int) coreData.getLogoTextureExtraCount(); + ++idx) { + Texture2D *extraLogo = coreData.getLogoTextureExtra(idx); + + logoMainX = currentX; + logoMainY = currentY; + logoMainW = extraLogo->getPixmap()->getW(); + logoMainH = extraLogo->getPixmap()->getH(); + + string logoTagName = + string(containerName) + "_ExtraLogo" + intToStr(idx + 1) + "_"; + logoMainX = + Config::getInstance().getInt(logoTagName + "x", + intToStr(logoMainX).c_str()); + logoMainY = + Config::getInstance().getInt(logoTagName + "y", + intToStr(logoMainY).c_str()); + logoMainW = + Config::getInstance().getInt(logoTagName + "w", + intToStr(logoMainW).c_str()); + logoMainH = + Config::getInstance().getInt(logoTagName + "h", + intToStr(logoMainH).c_str()); + + renderer.renderTextureQuad(logoMainX, logoMainY, + logoMainW, logoMainH, + extraLogo, GraphicComponent::getFade()); + + currentX += extraLogo->getPixmap()->getW(); + } + + renderer.renderButton(&buttonNewGame); + renderer.renderButton(&buttonLoadGame); + renderer.renderButton(&buttonMods); + renderer.renderButton(&buttonOptions); + renderer.renderButton(&buttonAbout); + renderer.renderButton(&buttonExit); + renderer.renderLabel(&labelVersion); + renderer.renderLabel(&labelGreeting); + + renderer.renderConsole(&console); + + renderer.renderPopupMenu(&popupMenu); + + //exit message box + if (mainMessageBox.getEnabled()) { + renderer.renderMessageBox(&mainMessageBox); + } + if (errorMessageBox.getEnabled()) { + renderer.renderMessageBox(&errorMessageBox); + } + if (ftpMessageBox.getEnabled()) { + renderer.renderMessageBox(&ftpMessageBox); + } + + if (program != NULL) + program->renderProgramMsgBox(); + } + + void MenuStateRoot::update() { + if (Config::getInstance().getBool("AutoTest")) { + if (AutoTest::getInstance().mustExitGame() == false) { + AutoTest::getInstance().updateRoot(program, mainMenu); + } else { + program->exit(); + } + return; + } + + if (gameUpdateChecked == false) { + gameUpdateChecked = true; + + string updateCheckURL = + Config::getInstance().getString("UpdateCheckURL", ""); + if (updateCheckURL != "") { + static string mutexOwnerId = + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + string("_") + intToStr(__LINE__); + updatesHttpServerThread = new SimpleTaskThread(this, 1, 200); + updatesHttpServerThread->setUniqueID(mutexOwnerId); + updatesHttpServerThread->start(); + } + } + + console.update(); + } + + void MenuStateRoot::simpleTask(BaseThread * callingThread, + void *userdata) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutexThreadOwner(callingThread-> + getMutexThreadOwnerValid(), + mutexOwnerId); + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + + callingThread->getMutexThreadOwnerValid()->setOwnerId(mutexOwnerId); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, __LINE__); + + + string updateCheckURL = + Config::getInstance().getString("UpdateCheckURL", ""); + if (updateCheckURL != "") { + + string baseURL = updateCheckURL; + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line %d] About to call first http url, base [%s]..\n", + __FILE__, __FUNCTION__, __LINE__, baseURL.c_str()); + + CURL *handle = SystemFlags::initHTTP(); + CURLcode curlResult = CURLE_OK; + string updateMetaData = + SystemFlags::getHTTP(baseURL, handle, -1, &curlResult); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("techsMetaData [%s] curlResult = %d\n", + updateMetaData.c_str(), curlResult); + + if (callingThread->getQuitStatus() == true + || safeMutexThreadOwner.isValidMutex() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d]\n", __FILE__, __FUNCTION__, + __LINE__); + return; + } + + if (curlResult != CURLE_OK) { + string curlError = curl_easy_strerror(curlResult); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line %d] curlError [%s]..\n", __FILE__, + __FUNCTION__, __LINE__, curlError.c_str()); + + char szMsg[8096] = ""; + snprintf(szMsg, 8096, + "An error was detected while checking for new updates\n%s", + curlError.c_str()); + showErrorMessageBox(szMsg, "ERROR", false); + } + + if (curlResult == CURLE_OK || + (curlResult != CURLE_COULDNT_RESOLVE_HOST && + curlResult != CURLE_COULDNT_CONNECT)) { + + Properties props; + props.loadFromText(updateMetaData); + + int compareResult = + compareMajorMinorVersion(glestVersionString, + props.getString("LatestGameVersion", + "")); + if (compareResult == 0) { + if (glestVersionString != + props.getString("LatestGameVersion", "")) { + compareResult = -1; + } + } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("compareResult = %d local [%s] remote [%s]\n", + compareResult, glestVersionString.c_str(), + props.getString("LatestGameVersion", "").c_str()); + + if (compareResult < 0) { + + string downloadBinaryKey = + "LatestGameBinaryUpdateArchiveURL-" + + getPlatformTypeNameString() + getPlatformArchTypeNameString(); + if (props.hasString(downloadBinaryKey)) { + ftpFileName = + extractFileFromDirectoryPath(props. + getString(downloadBinaryKey)); + ftpFileURL = props.getString(downloadBinaryKey); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("Checking update key downloadBinaryKey [%s] ftpFileURL [%s]\n", + downloadBinaryKey.c_str(), ftpFileURL.c_str()); + + if (props.getBool("AllowUpdateDownloads", "false") == false + || ftpFileURL == "") { + char szMsg[8096] = ""; + snprintf(szMsg, 8096, + "A new update was detected: %s\nUpdate Date: %s\nPlease visit zetaglest.github.io for details!", + props.getString("LatestGameVersion", "?").c_str(), + props.getString("LatestGameVersionReleaseDate", + "?").c_str()); + showFTPMessageBox(szMsg, "Update", false, true); + } else { + char szMsg[8096] = ""; + snprintf(szMsg, 8096, + "A new update was detected: %s\nUpdate Date: %s\nDownload update now?", + props.getString("LatestGameVersion", "?").c_str(), + props.getString("LatestGameVersionReleaseDate", + "?").c_str()); + showFTPMessageBox(szMsg, "Update", false, false); + } + } + } + SystemFlags::cleanupHTTP(&handle); + } + } + + void MenuStateRoot::keyDown(SDL_KeyboardEvent key) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] key = [%c] [%d]\n", + __FILE__, __FUNCTION__, __LINE__, + key.keysym.sym, key.keysym.sym); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] key = [%d - %c]\n", __FILE__, + __FUNCTION__, __LINE__, key.keysym.sym, key.keysym.sym); + + //printf("\n\n\nIN MENU STATE ROOT KEYDOWN!!!\n\n\n"); + + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + //exit + //if(key == configKeys.getCharKey("ExitKey")) { + //printf("Check Root menu exit key!\n"); + if (isKeyPressed(configKeys.getSDLKey("ExitKey"), key) == true) { + Lang & lang = Lang::getInstance(); + showMessageBox(lang.getString("ExitGameQuestion"), "", true); + } + //else if(mainMessageBox.getEnabled() == true && key == vkReturn) { + else if (mainMessageBox.getEnabled() == true + && isKeyPressed(SDLK_RETURN, key) == true) { + //SDL_keysym keystate = Window::getKeystate(); + SDL_keysym keystate = key.keysym; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] keystate.mod [%d]\n", + __FILE__, __FUNCTION__, __LINE__, + keystate.mod); + + //printf("---> keystate.mod [%d]\n",keystate.mod); + if (keystate.mod & (KMOD_LALT | KMOD_RALT)) { + } else { + //printf("EXITING ---> keystate.mod [%d]\n",keystate.mod); + program->exit(); + } + } + //else if(key == configKeys.getCharKey("SaveGUILayout")) { + else if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), key) == + true) { + GraphicComponent::saveAllCustomProperties(containerName); + //Lang &lang= Lang::getInstance(); + //console.addLine(lang.getString("GUILayoutSaved") + " [" + (saved ? lang.getString("Yes") : lang.getString("No"))+ "]"); + } + + } + + void MenuStateRoot::showMessageBox(const string & text, + const string & header, bool toggle) { + if (toggle == false) { + mainMessageBox.setEnabled(false); + } + + if (mainMessageBox.getEnabled() == false) { + mainMessageBox.setText(text); + mainMessageBox.setHeader(header); + mainMessageBox.setEnabled(true); + } else { + mainMessageBox.setEnabled(false); + } + } + + void MenuStateRoot::showErrorMessageBox(const string & text, + const string & header, + bool toggle) { + if (toggle == false) { + errorMessageBox.setEnabled(false); + } + + if (errorMessageBox.getEnabled() == false) { + errorMessageBox.setText(text); + errorMessageBox.setHeader(header); + errorMessageBox.setEnabled(true); + } else { + errorMessageBox.setEnabled(false); + } + } + + void MenuStateRoot::showFTPMessageBox(const string & text, + const string & header, bool toggle, + bool okOnly) { + if (toggle == false) { + ftpMessageBox.setEnabled(false); + } + + Lang & lang = Lang::getInstance(); + if (okOnly) { + ftpMessageBox.init(lang.getString("Ok")); + } else { + ftpMessageBox.init(lang.getString("Yes"), lang.getString("No")); + } + + if (ftpMessageBox.getEnabled() == false) { + ftpMessageBox.setText(text); + ftpMessageBox.setHeader(header); + ftpMessageBox.setEnabled(true); + } else { + ftpMessageBox.setEnabled(false); + } + } + + + } } //end namespace diff --git a/source/glest_game/menu/menu_state_root.h b/source/glest_game/menu/menu_state_root.h index 4d810dcce..82576c72d 100644 --- a/source/glest_game/menu/menu_state_root.h +++ b/source/glest_game/menu/menu_state_root.h @@ -18,74 +18,72 @@ # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// =============================== -// class MenuStateRoot -// =============================== + // =============================== + // class MenuStateRoot + // =============================== - class GraphicMessageBox; - class PopupMenu; + class GraphicMessageBox; + class PopupMenu; - class MenuStateRoot:public MenuState, public SimpleTaskCallbackInterface, - public FTPClientCallbackInterface - { - private: - GraphicButton buttonNewGame; - GraphicButton buttonLoadGame; - GraphicButton buttonMods; - GraphicButton buttonOptions; - GraphicButton buttonAbout; - GraphicButton buttonExit; - GraphicLabel labelVersion; - GraphicLabel labelGreeting; + class MenuStateRoot :public MenuState, public SimpleTaskCallbackInterface, + public FTPClientCallbackInterface { + private: + GraphicButton buttonNewGame; + GraphicButton buttonLoadGame; + GraphicButton buttonMods; + GraphicButton buttonOptions; + GraphicButton buttonAbout; + GraphicButton buttonExit; + GraphicLabel labelVersion; + GraphicLabel labelGreeting; - GraphicMessageBox mainMessageBox; - GraphicMessageBox errorMessageBox; - GraphicMessageBox ftpMessageBox; + GraphicMessageBox mainMessageBox; + GraphicMessageBox errorMessageBox; + GraphicMessageBox ftpMessageBox; - PopupMenu popupMenu; + PopupMenu popupMenu; - static bool gameUpdateChecked; - SimpleTaskThread *updatesHttpServerThread; - FTPClientThread *ftpClientThread; - std::map < string, pair < int, string > >fileFTPProgressList; - string ftpFileName; - string ftpFileURL; - int lastDownloadProgress; + static bool gameUpdateChecked; + SimpleTaskThread *updatesHttpServerThread; + FTPClientThread *ftpClientThread; + std::map < string, pair < int, string > >fileFTPProgressList; + string ftpFileName; + string ftpFileURL; + int lastDownloadProgress; - virtual void simpleTask (BaseThread * callingThread, void *userdata); - void startFTPClientIfRequired (); - virtual void FTPClient_CallbackEvent (string itemName, - FTP_Client_CallbackType type, - pair < FTP_Client_ResultType, - string > result, void *userdata); + virtual void simpleTask(BaseThread * callingThread, void *userdata); + void startFTPClientIfRequired(); + virtual void FTPClient_CallbackEvent(string itemName, + FTP_Client_CallbackType type, + pair < FTP_Client_ResultType, + string > result, void *userdata); - public: - MenuStateRoot (Program * program, MainMenu * mainMenu); - virtual ~ MenuStateRoot (); + public: + MenuStateRoot(Program * program, MainMenu * mainMenu); + virtual ~MenuStateRoot(); - void mouseClick (int x, int y, MouseButton mouseButton); - void mouseMove (int x, int y, const MouseState * mouseState); - void render (); - void update (); - virtual void keyDown (SDL_KeyboardEvent key); + void mouseClick(int x, int y, MouseButton mouseButton); + void mouseMove(int x, int y, const MouseState * mouseState); + void render(); + void update(); + virtual void keyDown(SDL_KeyboardEvent key); - void showMessageBox (const string & text, const string & header, - bool toggle); - void showErrorMessageBox (const string & text, const string & header, - bool toggle); - void showFTPMessageBox (const string & text, const string & header, - bool toggle, bool okOnly); + void showMessageBox(const string & text, const string & header, + bool toggle); + void showErrorMessageBox(const string & text, const string & header, + bool toggle); + void showFTPMessageBox(const string & text, const string & header, + bool toggle, bool okOnly); - virtual bool isMasterserverMode () const; - virtual void reloadUI (); - }; + virtual bool isMasterserverMode() const; + virtual void reloadUI(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/menu/menu_state_scenario.cpp b/source/glest_game/menu/menu_state_scenario.cpp index 9b0589818..9e7aa3c77 100644 --- a/source/glest_game/menu/menu_state_scenario.cpp +++ b/source/glest_game/menu/menu_state_scenario.cpp @@ -23,688 +23,596 @@ #include "leak_dumper.h" -namespace Glest -{ - namespace Game - { - - using namespace::Shared::Xml; - -// ===================================================== -// class MenuStateScenario -// ===================================================== - - MenuStateScenario::MenuStateScenario (Program * program, - MainMenu * mainMenu, - bool isTutorialMode, - const vector < string > &dirList, - string - autoloadScenarioName):MenuState - (program, mainMenu, "scenario") - { - containerName = "Scenario"; - this->isTutorialMode = isTutorialMode; - - enableScenarioTexturePreview = - Config::getInstance ().getBool ("EnableScenarioTexturePreview", - "true"); - scenarioLogoTexture = NULL; - previewLoadDelayTimer = time (NULL); - needToLoadTextures = true; - - Lang & lang = Lang::getInstance (); - NetworkManager & networkManager = NetworkManager::getInstance (); - try - { - networkManager.init (nrServer); - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] Error detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - mainMessageBoxState = 1; - showMessageBox ("Error: " + string (ex.what ()), "Error detected", - false); - } - - mainMessageBox.registerGraphicComponent (containerName, - "mainMessageBox"); - mainMessageBox.init (lang.getString ("Ok")); - mainMessageBox.setEnabled (false); - mainMessageBoxState = 0; - - this->autoloadScenarioName = autoloadScenarioName; - vector < string > results; - - this->dirList = dirList; - - int buttonStartY = 50; - int buttonStartX = 70; - - buttonReturn.registerGraphicComponent (containerName, "buttonReturn"); - buttonReturn.init (buttonStartX, buttonStartY, 125); - buttonReturn.setText (lang.getString ("Return")); - - buttonPlayNow.registerGraphicComponent (containerName, "buttonPlayNow"); - buttonPlayNow.init (buttonStartX + 150, buttonStartY, 125); - buttonPlayNow.setText (lang.getString ("PlayNow")); - - int startY = 700; - int startX = 50; - - labelScenario.registerGraphicComponent (containerName, "labelScenario"); - labelScenario.init (startX, startY); - - listBoxScenario.registerGraphicComponent (containerName, - "listBoxScenario"); - listBoxScenario.init (startX, startY - 30, 290); - - labelScenarioName.registerGraphicComponent (containerName, - "labelScenarioName"); - labelScenarioName.init (startX, startY - 80); - labelScenarioName.setFont (CoreData::getInstance ().getMenuFontBig ()); - labelScenarioName.setFont3D (CoreData::getInstance (). - getMenuFontBig3D ()); - - labelInfo.registerGraphicComponent (containerName, "labelInfo"); - labelInfo.init (startX, startY - 110); - labelInfo.setFont (CoreData::getInstance ().getMenuFontNormal ()); - labelInfo.setFont3D (CoreData::getInstance ().getMenuFontNormal3D ()); - - if (this->isTutorialMode == true) - { - labelScenario.setText (lang.getString ("Tutorial")); - } - else - { - labelScenario.setText (lang.getString ("Scenario")); - } - - //scenario listbox - findDirs (dirList, results); - scenarioFiles = results; - //printf("scenarioFiles[0] [%s]\n",scenarioFiles[0].c_str()); - - if (results.empty () == true) - { - //throw megaglest_runtime_error("There are no scenarios found to load"); - mainMessageBoxState = 1; - if (this->isTutorialMode == true) - { - showMessageBox ("Error: There are no tutorials found to load", - "Error detected", false); - } - else - { - showMessageBox ("Error: There are no scenarios found to load", - "Error detected", false); - } - } - - std::map < string, string > scenarioErrors; - for (int i = 0; i < (int) results.size (); ++i) - { - results[i] = formatString (results[i]); - } - listBoxScenario.setItems (results); - - try - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line: %d] listBoxScenario.getSelectedItemIndex() = %d scenarioFiles.size() = %d\n", - extractFileFromDirectoryPath (__FILE__).c_str (), __FUNCTION__, - __LINE__, listBoxScenario.getSelectedItemIndex (), - (int) scenarioFiles.size ()); - - if (listBoxScenario.getItemCount () > 0 - && listBoxScenario.getSelectedItemIndex () >= 0 - && listBoxScenario.getSelectedItemIndex () < - (int) scenarioFiles.size ()) - { - string scenarioPath = - Scenario::getScenarioPath (dirList, - scenarioFiles[listBoxScenario. - getSelectedItemIndex - ()]); - //printf("scenarioPath [%s]\n",scenarioPath.c_str()); - - loadScenarioInfo (scenarioPath, &scenarioInfo); - labelInfo.setText (scenarioInfo.desc); - if (scenarioInfo.namei18n != "") - { - labelScenarioName.setText (scenarioInfo.namei18n); - } - else - { - labelScenarioName.setText (listBoxScenario.getSelectedItem ()); - } - } - - GraphicComponent::applyAllCustomProperties (containerName); - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] Error detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - mainMessageBoxState = 1; - showMessageBox ("Error: " + string (ex.what ()), "Error detected", - false); - } - - if (scenarioErrors.empty () == false) - { - mainMessageBoxState = 1; - - string errorMsg = ""; - for (std::map < string, string >::iterator iterMap = - scenarioErrors.begin (); iterMap != scenarioErrors.end (); - ++iterMap) - { - errorMsg += - "scenario: " + iterMap->first + " error text: " + - iterMap->second.substr (0, 400) + "\n"; - } - showMessageBox ("Error loading scenario(s): " + errorMsg, - "Error detected", false); - } - } - - void MenuStateScenario::reloadUI () - { - Lang & lang = Lang::getInstance (); - - console.resetFonts (); - mainMessageBox.init (lang.getString ("Ok")); - labelInfo.setFont (CoreData::getInstance ().getMenuFontNormal ()); - labelInfo.setFont3D (CoreData::getInstance ().getMenuFontNormal3D ()); - - labelScenarioName.setFont (CoreData::getInstance (). - getMenuFontNormal ()); - labelScenarioName.setFont3D (CoreData::getInstance (). - getMenuFontNormal3D ()); - - buttonReturn.setText (lang.getString ("Return")); - buttonPlayNow.setText (lang.getString ("PlayNow")); - - labelScenario.setText (lang.getString ("Scenario")); - - GraphicComponent:: - reloadFontsForRegisterGraphicComponents (containerName); - } - - MenuStateScenario::~MenuStateScenario () - { - cleanupPreviewTexture (); - } - - void MenuStateScenario::cleanupPreviewTexture () - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] scenarioLogoTexture [%p]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, scenarioLogoTexture); - - if (scenarioLogoTexture != NULL) - { - Renderer::getInstance ().endTexture (rsGlobal, scenarioLogoTexture, - false); - } - scenarioLogoTexture = NULL; - } - - void MenuStateScenario::mouseClick (int x, int y, MouseButton mouseButton) - { - CoreData & coreData = CoreData::getInstance (); - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - string advanceToItemStartingWith = ""; - - if (mainMessageBox.getEnabled ()) - { - int button = 0; - if (mainMessageBox.mouseClick (x, y, button)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - if (button == 0) - { - mainMessageBox.setEnabled (false); - - if (scenarioFiles.empty () == true && mainMessageBoxState == 1) - { - mainMenu->setState (new MenuStateNewGame (program, mainMenu)); - return; - } - } - } - return; - } - else - { - if (::Shared::Platform::Window::isKeyStateModPressed (KMOD_SHIFT) == - true) - { - const wchar_t lastKey =::Shared::Platform::Window:: - extractLastKeyPressed (); -// xxx: -// string hehe=lastKey; -// printf("lastKey = %d [%c] '%s'\n",lastKey,lastKey,hehe); - advanceToItemStartingWith = lastKey; - } - } - - if (buttonReturn.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundA ()); - mainMenu->setState (new MenuStateNewGame (program, mainMenu)); - return; - } - else if (buttonPlayNow.mouseClick (x, y)) - { - soundRenderer.playFx (coreData.getClickSoundC ()); - launchGame (); - return; - } - else if (listBoxScenario.mouseClick (x, y, advanceToItemStartingWith)) - { - try - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line: %d] listBoxScenario.getSelectedItemIndex() = %d scenarioFiles.size() = %d\n", - extractFileFromDirectoryPath (__FILE__).c_str (), __FUNCTION__, - __LINE__, listBoxScenario.getSelectedItemIndex (), - (int) scenarioFiles.size ()); - - if (listBoxScenario.getItemCount () > 0 - && listBoxScenario.getSelectedItemIndex () >= 0 - && listBoxScenario.getSelectedItemIndex () < - (int) scenarioFiles.size ()) - { - loadScenarioInfo (Scenario:: - getScenarioPath (dirList, - scenarioFiles[listBoxScenario. - getSelectedItemIndex - ()]), - &scenarioInfo); - labelInfo.setText (scenarioInfo.desc); - if (scenarioInfo.namei18n != "") - { - labelScenarioName.setText (scenarioInfo.namei18n); - } - else - { - labelScenarioName.setText (listBoxScenario.getSelectedItem ()); - } - } - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] Error detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", szBuf); - - mainMessageBoxState = 1; - showMessageBox ("Error: " + string (ex.what ()), "Error detected", - false); - } - } - } - - void MenuStateScenario::mouseMove (int x, int y, const MouseState * ms) - { - - if (mainMessageBox.getEnabled ()) - { - mainMessageBox.mouseMove (x, y); - } - - listBoxScenario.mouseMove (x, y); - - buttonReturn.mouseMove (x, y); - buttonPlayNow.mouseMove (x, y); - } - - void MenuStateScenario::render () - { - - Renderer & renderer = Renderer::getInstance (); - - if (scenarioLogoTexture != NULL) - { - renderer.renderTextureQuad (450, 200, 533, 400, scenarioLogoTexture, - 1.0f); - //renderer.renderBackground(scenarioLogoTexture); - } - - if (mainMessageBox.getEnabled ()) - { - renderer.renderMessageBox (&mainMessageBox); - } - else - { - renderer.renderLabel (&labelInfo); - renderer.renderLabel (&labelScenarioName); - - renderer.renderLabel (&labelScenario); - renderer.renderListBox (&listBoxScenario); - - renderer.renderButton (&buttonReturn); - renderer.renderButton (&buttonPlayNow); - } - renderer.renderConsole (&console); - if (program != NULL) - program->renderProgramMsgBox (); - } - - void MenuStateScenario::update () - { - if (Config::getInstance ().getBool ("AutoTest")) - { - AutoTest::getInstance ().updateScenario (this); - return; - } - if (this->autoloadScenarioName != "") - { - string scenarioPath = - Scenario::getScenarioPath (dirList, this->autoloadScenarioName); - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("[%s:%s] Line: %d this->autoloadScenarioName [%s] scenarioPath [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->autoloadScenarioName.c_str(),scenarioPath.c_str()); - printf - ("[%s:%s] Line: %d this->autoloadScenarioName [%s] scenarioPath [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), __FUNCTION__, - __LINE__, this->autoloadScenarioName.c_str (), - scenarioPath.c_str ()); - - loadScenarioInfo (scenarioPath, &scenarioInfo); - //if(scenarioInfo.namei18n != "") { - // this->autoloadScenarioName = scenarioInfo.namei18n; - //} - //else { - this->autoloadScenarioName = - formatString (this->autoloadScenarioName); - //} - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("[%s:%s] Line: %d this->autoloadScenarioName [%s] scenarioPath [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->autoloadScenarioName.c_str(),scenarioPath.c_str()); - printf - ("[%s:%s] Line: %d this->autoloadScenarioName [%s] scenarioPath [%s] file [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), __FUNCTION__, - __LINE__, this->autoloadScenarioName.c_str (), - scenarioPath.c_str (), scenarioInfo.file.c_str ()); - - listBoxScenario.setSelectedItem (this->autoloadScenarioName, false); - - if (listBoxScenario.getSelectedItem () != this->autoloadScenarioName) - { - mainMessageBoxState = 1; - showMessageBox ("Could not find scenario name: " + - this->autoloadScenarioName, "Scenario Missing", - false); - this->autoloadScenarioName = ""; - } - else - { - try - { - this->autoloadScenarioName = ""; - if (listBoxScenario.getItemCount () > 0 - && listBoxScenario.getSelectedItemIndex () >= 0 - && listBoxScenario.getSelectedItemIndex () < - (int) scenarioFiles.size ()) - { - - printf - ("[%s:%s] Line: %d scenarioFiles[listBoxScenario.getSelectedItemIndex()] [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, - scenarioFiles[listBoxScenario.getSelectedItemIndex ()]. - c_str ()); - - loadScenarioInfo (Scenario:: - getScenarioPath (dirList, - scenarioFiles - [listBoxScenario. - getSelectedItemIndex ()]), - &scenarioInfo); - - printf ("[%s:%s] Line: %d scenarioInfo.file [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, scenarioInfo.file.c_str ()); - - labelInfo.setText (scenarioInfo.desc); - if (scenarioInfo.namei18n != "") - { - labelScenarioName.setText (scenarioInfo.namei18n); - } - else - { - labelScenarioName.setText (listBoxScenario. - getSelectedItem ()); - } - - SoundRenderer & soundRenderer = SoundRenderer::getInstance (); - CoreData & coreData = CoreData::getInstance (); - soundRenderer.playFx (coreData.getClickSoundC ()); - launchGame (); - return; - } - } - catch (const std::exception & ex) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] Error detected:\n%s\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, ex.what ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, "%s", - szBuf); - - mainMessageBoxState = 1; - showMessageBox ("Error: " + string (ex.what ()), "Error detected", - false); - } - } - } - - if (needToLoadTextures) - { - // this delay is done to make it possible to switch faster - if (difftime (time (NULL), previewLoadDelayTimer) >= 2) - { - loadScenarioPreviewTexture (); - needToLoadTextures = false; - } - } - console.update (); - } - - void MenuStateScenario::launchGame () - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] scenarioInfo.file [%s] [%s][%s][%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, scenarioInfo.file.c_str (), - scenarioInfo.tilesetName.c_str (), - scenarioInfo.mapName.c_str (), - scenarioInfo.techTreeName.c_str ()); - - if (scenarioInfo.file != "" && scenarioInfo.tilesetName != "" - && scenarioInfo.mapName != "" && scenarioInfo.techTreeName != "") - { - GameSettings gameSettings; - loadGameSettings (&scenarioInfo, &gameSettings); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] gameSettings.getScenarioDir() [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, - gameSettings.getScenarioDir ().c_str ()); - - const vector < string > pathTechList = - Config::getInstance ().getPathListForType (ptTechs, - gameSettings. - getScenarioDir ()); - if (TechTree::exists (gameSettings.getTech (), pathTechList) == false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Line ref: %d Error: cannot find techtree [%s]\n", - __LINE__, scenarioInfo.techTreeName.c_str ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - - mainMessageBoxState = 1; - showMessageBox (szBuf, "Error detected", false); - - return; - } - program->setState (new Game (program, &gameSettings, false)); - return; - } - } - - void MenuStateScenario::setScenario (int i) - { - listBoxScenario.setSelectedItemIndex (i); - loadScenarioInfo (Scenario:: - getScenarioPath (dirList, - scenarioFiles[listBoxScenario. - getSelectedItemIndex - ()]), &scenarioInfo); - } - - void MenuStateScenario::loadScenarioInfo (string file, - ScenarioInfo * scenarioInfo) - { - bool isTutorial = Scenario::isGameTutorial (file); - - cleanupPreviewTexture (); - needToLoadTextures = false; - - if (Scenario::loadScenarioInfo (file, scenarioInfo, isTutorial) == true) - { - previewLoadDelayTimer = time (NULL); - needToLoadTextures = true; - } - } - - void MenuStateScenario::loadScenarioPreviewTexture () - { - if (enableScenarioTexturePreview == true) - { - //if(listBoxScenario.getSelectedItemIndex() >= 0) { - if (listBoxScenario.getItemCount () > 0 - && listBoxScenario.getSelectedItemIndex () >= 0 - && listBoxScenario.getSelectedItemIndex () < - (int) scenarioFiles.size ()) - { - GameSettings gameSettings; - loadGameSettings (&scenarioInfo, &gameSettings); - - string scenarioLogo = ""; - bool loadingImageUsed = false; - - Game::extractScenarioLogoFile (&gameSettings, scenarioLogo, - loadingImageUsed); - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("In [%s::%s Line: %d] scenarioLogo [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, scenarioLogo.c_str ()); - - if (scenarioLogo != "") - { - cleanupPreviewTexture (); - scenarioLogoTexture = Renderer::findTexture (scenarioLogo); - } - else - { - cleanupPreviewTexture (); - scenarioLogoTexture = NULL; - } - } - } - } - - void MenuStateScenario::loadGameSettings (const ScenarioInfo * - scenarioInfo, - GameSettings * gameSettings) - { - if (listBoxScenario.getSelectedItemIndex () < 0) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "listBoxScenario.getSelectedItemIndex() < 0, = %d", - listBoxScenario.getSelectedItemIndex ()); - throw megaglest_runtime_error (szBuf); - } - else if (listBoxScenario.getSelectedItemIndex () >= - (int) scenarioFiles.size ()) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "listBoxScenario.getSelectedItemIndex() >= scenarioFiles.size(), = [%d][%d]", - listBoxScenario.getSelectedItemIndex (), - (int) scenarioFiles.size ()); - throw megaglest_runtime_error (szBuf); - } - - Scenario::loadGameSettings (dirList, scenarioInfo, gameSettings, - formatString (scenarioFiles - [listBoxScenario. - getSelectedItemIndex ()])); - } - - void MenuStateScenario::showMessageBox (const string & text, - const string & header, - bool toggle) - { - if (!toggle) - { - mainMessageBox.setEnabled (false); - } - - if (!mainMessageBox.getEnabled ()) - { - mainMessageBox.setText (text); - mainMessageBox.setHeader (header); - mainMessageBox.setEnabled (true); - } - else - { - mainMessageBox.setEnabled (false); - } - } - - void MenuStateScenario::keyDown (SDL_KeyboardEvent key) - { - Config & configKeys = - Config::getInstance (std::pair < ConfigType, - ConfigType > (cfgMainKeys, cfgUserKeys)); - if (isKeyPressed (configKeys.getSDLKey ("SaveGUILayout"), key) == true) - { - GraphicComponent::saveAllCustomProperties (containerName); - } - } - - } +namespace Glest { + namespace Game { + + using namespace::Shared::Xml; + + // ===================================================== + // class MenuStateScenario + // ===================================================== + + MenuStateScenario::MenuStateScenario(Program * program, + MainMenu * mainMenu, + bool isTutorialMode, + const vector < string > &dirList, + string + autoloadScenarioName) :MenuState + (program, mainMenu, "scenario") { + containerName = "Scenario"; + this->isTutorialMode = isTutorialMode; + + enableScenarioTexturePreview = + Config::getInstance().getBool("EnableScenarioTexturePreview", + "true"); + scenarioLogoTexture = NULL; + previewLoadDelayTimer = time(NULL); + needToLoadTextures = true; + + Lang & lang = Lang::getInstance(); + NetworkManager & networkManager = NetworkManager::getInstance(); + try { + networkManager.init(nrServer); + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] Error detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + mainMessageBoxState = 1; + showMessageBox("Error: " + string(ex.what()), "Error detected", + false); + } + + mainMessageBox.registerGraphicComponent(containerName, + "mainMessageBox"); + mainMessageBox.init(lang.getString("Ok")); + mainMessageBox.setEnabled(false); + mainMessageBoxState = 0; + + this->autoloadScenarioName = autoloadScenarioName; + vector < string > results; + + this->dirList = dirList; + + int buttonStartY = 50; + int buttonStartX = 70; + + buttonReturn.registerGraphicComponent(containerName, "buttonReturn"); + buttonReturn.init(buttonStartX, buttonStartY, 125); + buttonReturn.setText(lang.getString("Return")); + + buttonPlayNow.registerGraphicComponent(containerName, "buttonPlayNow"); + buttonPlayNow.init(buttonStartX + 150, buttonStartY, 125); + buttonPlayNow.setText(lang.getString("PlayNow")); + + int startY = 700; + int startX = 50; + + labelScenario.registerGraphicComponent(containerName, "labelScenario"); + labelScenario.init(startX, startY); + + listBoxScenario.registerGraphicComponent(containerName, + "listBoxScenario"); + listBoxScenario.init(startX, startY - 30, 290); + + labelScenarioName.registerGraphicComponent(containerName, + "labelScenarioName"); + labelScenarioName.init(startX, startY - 80); + labelScenarioName.setFont(CoreData::getInstance().getMenuFontBig()); + labelScenarioName.setFont3D(CoreData::getInstance(). + getMenuFontBig3D()); + + labelInfo.registerGraphicComponent(containerName, "labelInfo"); + labelInfo.init(startX, startY - 110); + labelInfo.setFont(CoreData::getInstance().getMenuFontNormal()); + labelInfo.setFont3D(CoreData::getInstance().getMenuFontNormal3D()); + + if (this->isTutorialMode == true) { + labelScenario.setText(lang.getString("Tutorial")); + } else { + labelScenario.setText(lang.getString("Scenario")); + } + + //scenario listbox + findDirs(dirList, results); + scenarioFiles = results; + //printf("scenarioFiles[0] [%s]\n",scenarioFiles[0].c_str()); + + if (results.empty() == true) { + //throw megaglest_runtime_error("There are no scenarios found to load"); + mainMessageBoxState = 1; + if (this->isTutorialMode == true) { + showMessageBox("Error: There are no tutorials found to load", + "Error detected", false); + } else { + showMessageBox("Error: There are no scenarios found to load", + "Error detected", false); + } + } + + std::map < string, string > scenarioErrors; + for (int i = 0; i < (int) results.size(); ++i) { + results[i] = formatString(results[i]); + } + listBoxScenario.setItems(results); + + try { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line: %d] listBoxScenario.getSelectedItemIndex() = %d scenarioFiles.size() = %d\n", + extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, + __LINE__, listBoxScenario.getSelectedItemIndex(), + (int) scenarioFiles.size()); + + if (listBoxScenario.getItemCount() > 0 + && listBoxScenario.getSelectedItemIndex() >= 0 + && listBoxScenario.getSelectedItemIndex() < + (int) scenarioFiles.size()) { + string scenarioPath = + Scenario::getScenarioPath(dirList, + scenarioFiles[listBoxScenario. + getSelectedItemIndex + ()]); + //printf("scenarioPath [%s]\n",scenarioPath.c_str()); + + loadScenarioInfo(scenarioPath, &scenarioInfo); + labelInfo.setText(scenarioInfo.desc); + if (scenarioInfo.namei18n != "") { + labelScenarioName.setText(scenarioInfo.namei18n); + } else { + labelScenarioName.setText(listBoxScenario.getSelectedItem()); + } + } + + GraphicComponent::applyAllCustomProperties(containerName); + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] Error detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + mainMessageBoxState = 1; + showMessageBox("Error: " + string(ex.what()), "Error detected", + false); + } + + if (scenarioErrors.empty() == false) { + mainMessageBoxState = 1; + + string errorMsg = ""; + for (std::map < string, string >::iterator iterMap = + scenarioErrors.begin(); iterMap != scenarioErrors.end(); + ++iterMap) { + errorMsg += + "scenario: " + iterMap->first + " error text: " + + iterMap->second.substr(0, 400) + "\n"; + } + showMessageBox("Error loading scenario(s): " + errorMsg, + "Error detected", false); + } + } + + void MenuStateScenario::reloadUI() { + Lang & lang = Lang::getInstance(); + + console.resetFonts(); + mainMessageBox.init(lang.getString("Ok")); + labelInfo.setFont(CoreData::getInstance().getMenuFontNormal()); + labelInfo.setFont3D(CoreData::getInstance().getMenuFontNormal3D()); + + labelScenarioName.setFont(CoreData::getInstance(). + getMenuFontNormal()); + labelScenarioName.setFont3D(CoreData::getInstance(). + getMenuFontNormal3D()); + + buttonReturn.setText(lang.getString("Return")); + buttonPlayNow.setText(lang.getString("PlayNow")); + + labelScenario.setText(lang.getString("Scenario")); + + GraphicComponent:: + reloadFontsForRegisterGraphicComponents(containerName); + } + + MenuStateScenario::~MenuStateScenario() { + cleanupPreviewTexture(); + } + + void MenuStateScenario::cleanupPreviewTexture() { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] scenarioLogoTexture [%p]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, scenarioLogoTexture); + + if (scenarioLogoTexture != NULL) { + Renderer::getInstance().endTexture(rsGlobal, scenarioLogoTexture, + false); + } + scenarioLogoTexture = NULL; + } + + void MenuStateScenario::mouseClick(int x, int y, MouseButton mouseButton) { + CoreData & coreData = CoreData::getInstance(); + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + string advanceToItemStartingWith = ""; + + if (mainMessageBox.getEnabled()) { + int button = 0; + if (mainMessageBox.mouseClick(x, y, button)) { + soundRenderer.playFx(coreData.getClickSoundA()); + if (button == 0) { + mainMessageBox.setEnabled(false); + + if (scenarioFiles.empty() == true && mainMessageBoxState == 1) { + mainMenu->setState(new MenuStateNewGame(program, mainMenu)); + return; + } + } + } + return; + } else { + if (::Shared::Platform::Window::isKeyStateModPressed(KMOD_SHIFT) == + true) { + const wchar_t lastKey = ::Shared::Platform::Window:: + extractLastKeyPressed(); + // xxx: + // string hehe=lastKey; + // printf("lastKey = %d [%c] '%s'\n",lastKey,lastKey,hehe); + advanceToItemStartingWith = lastKey; + } + } + + if (buttonReturn.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundA()); + mainMenu->setState(new MenuStateNewGame(program, mainMenu)); + return; + } else if (buttonPlayNow.mouseClick(x, y)) { + soundRenderer.playFx(coreData.getClickSoundC()); + launchGame(); + return; + } else if (listBoxScenario.mouseClick(x, y, advanceToItemStartingWith)) { + try { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line: %d] listBoxScenario.getSelectedItemIndex() = %d scenarioFiles.size() = %d\n", + extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, + __LINE__, listBoxScenario.getSelectedItemIndex(), + (int) scenarioFiles.size()); + + if (listBoxScenario.getItemCount() > 0 + && listBoxScenario.getSelectedItemIndex() >= 0 + && listBoxScenario.getSelectedItemIndex() < + (int) scenarioFiles.size()) { + loadScenarioInfo(Scenario:: + getScenarioPath(dirList, + scenarioFiles[listBoxScenario. + getSelectedItemIndex + ()]), + &scenarioInfo); + labelInfo.setText(scenarioInfo.desc); + if (scenarioInfo.namei18n != "") { + labelScenarioName.setText(scenarioInfo.namei18n); + } else { + labelScenarioName.setText(listBoxScenario.getSelectedItem()); + } + } + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] Error detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + + mainMessageBoxState = 1; + showMessageBox("Error: " + string(ex.what()), "Error detected", + false); + } + } + } + + void MenuStateScenario::mouseMove(int x, int y, const MouseState * ms) { + + if (mainMessageBox.getEnabled()) { + mainMessageBox.mouseMove(x, y); + } + + listBoxScenario.mouseMove(x, y); + + buttonReturn.mouseMove(x, y); + buttonPlayNow.mouseMove(x, y); + } + + void MenuStateScenario::render() { + + Renderer & renderer = Renderer::getInstance(); + + if (scenarioLogoTexture != NULL) { + renderer.renderTextureQuad(450, 200, 533, 400, scenarioLogoTexture, + 1.0f); + //renderer.renderBackground(scenarioLogoTexture); + } + + if (mainMessageBox.getEnabled()) { + renderer.renderMessageBox(&mainMessageBox); + } else { + renderer.renderLabel(&labelInfo); + renderer.renderLabel(&labelScenarioName); + + renderer.renderLabel(&labelScenario); + renderer.renderListBox(&listBoxScenario); + + renderer.renderButton(&buttonReturn); + renderer.renderButton(&buttonPlayNow); + } + renderer.renderConsole(&console); + if (program != NULL) + program->renderProgramMsgBox(); + } + + void MenuStateScenario::update() { + if (Config::getInstance().getBool("AutoTest")) { + AutoTest::getInstance().updateScenario(this); + return; + } + if (this->autoloadScenarioName != "") { + string scenarioPath = + Scenario::getScenarioPath(dirList, this->autoloadScenarioName); + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("[%s:%s] Line: %d this->autoloadScenarioName [%s] scenarioPath [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->autoloadScenarioName.c_str(),scenarioPath.c_str()); + printf + ("[%s:%s] Line: %d this->autoloadScenarioName [%s] scenarioPath [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, + __LINE__, this->autoloadScenarioName.c_str(), + scenarioPath.c_str()); + + loadScenarioInfo(scenarioPath, &scenarioInfo); + //if(scenarioInfo.namei18n != "") { + // this->autoloadScenarioName = scenarioInfo.namei18n; + //} + //else { + this->autoloadScenarioName = + formatString(this->autoloadScenarioName); + //} + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("[%s:%s] Line: %d this->autoloadScenarioName [%s] scenarioPath [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->autoloadScenarioName.c_str(),scenarioPath.c_str()); + printf + ("[%s:%s] Line: %d this->autoloadScenarioName [%s] scenarioPath [%s] file [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, + __LINE__, this->autoloadScenarioName.c_str(), + scenarioPath.c_str(), scenarioInfo.file.c_str()); + + listBoxScenario.setSelectedItem(this->autoloadScenarioName, false); + + if (listBoxScenario.getSelectedItem() != this->autoloadScenarioName) { + mainMessageBoxState = 1; + showMessageBox("Could not find scenario name: " + + this->autoloadScenarioName, "Scenario Missing", + false); + this->autoloadScenarioName = ""; + } else { + try { + this->autoloadScenarioName = ""; + if (listBoxScenario.getItemCount() > 0 + && listBoxScenario.getSelectedItemIndex() >= 0 + && listBoxScenario.getSelectedItemIndex() < + (int) scenarioFiles.size()) { + + printf + ("[%s:%s] Line: %d scenarioFiles[listBoxScenario.getSelectedItemIndex()] [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, + scenarioFiles[listBoxScenario.getSelectedItemIndex()]. + c_str()); + + loadScenarioInfo(Scenario:: + getScenarioPath(dirList, + scenarioFiles + [listBoxScenario. + getSelectedItemIndex()]), + &scenarioInfo); + + printf("[%s:%s] Line: %d scenarioInfo.file [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, scenarioInfo.file.c_str()); + + labelInfo.setText(scenarioInfo.desc); + if (scenarioInfo.namei18n != "") { + labelScenarioName.setText(scenarioInfo.namei18n); + } else { + labelScenarioName.setText(listBoxScenario. + getSelectedItem()); + } + + SoundRenderer & soundRenderer = SoundRenderer::getInstance(); + CoreData & coreData = CoreData::getInstance(); + soundRenderer.playFx(coreData.getClickSoundC()); + launchGame(); + return; + } + } catch (const std::exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] Error detected:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", + szBuf); + + mainMessageBoxState = 1; + showMessageBox("Error: " + string(ex.what()), "Error detected", + false); + } + } + } + + if (needToLoadTextures) { + // this delay is done to make it possible to switch faster + if (difftime(time(NULL), previewLoadDelayTimer) >= 2) { + loadScenarioPreviewTexture(); + needToLoadTextures = false; + } + } + console.update(); + } + + void MenuStateScenario::launchGame() { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] scenarioInfo.file [%s] [%s][%s][%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, scenarioInfo.file.c_str(), + scenarioInfo.tilesetName.c_str(), + scenarioInfo.mapName.c_str(), + scenarioInfo.techTreeName.c_str()); + + if (scenarioInfo.file != "" && scenarioInfo.tilesetName != "" + && scenarioInfo.mapName != "" && scenarioInfo.techTreeName != "") { + GameSettings gameSettings; + loadGameSettings(&scenarioInfo, &gameSettings); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] gameSettings.getScenarioDir() [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, + gameSettings.getScenarioDir().c_str()); + + const vector < string > pathTechList = + Config::getInstance().getPathListForType(ptTechs, + gameSettings. + getScenarioDir()); + if (TechTree::exists(gameSettings.getTech(), pathTechList) == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Line ref: %d Error: cannot find techtree [%s]\n", + __LINE__, scenarioInfo.techTreeName.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + + mainMessageBoxState = 1; + showMessageBox(szBuf, "Error detected", false); + + return; + } + program->setState(new Game(program, &gameSettings, false)); + return; + } + } + + void MenuStateScenario::setScenario(int i) { + listBoxScenario.setSelectedItemIndex(i); + loadScenarioInfo(Scenario:: + getScenarioPath(dirList, + scenarioFiles[listBoxScenario. + getSelectedItemIndex + ()]), &scenarioInfo); + } + + void MenuStateScenario::loadScenarioInfo(string file, + ScenarioInfo * scenarioInfo) { + bool isTutorial = Scenario::isGameTutorial(file); + + cleanupPreviewTexture(); + needToLoadTextures = false; + + if (Scenario::loadScenarioInfo(file, scenarioInfo, isTutorial) == true) { + previewLoadDelayTimer = time(NULL); + needToLoadTextures = true; + } + } + + void MenuStateScenario::loadScenarioPreviewTexture() { + if (enableScenarioTexturePreview == true) { + //if(listBoxScenario.getSelectedItemIndex() >= 0) { + if (listBoxScenario.getItemCount() > 0 + && listBoxScenario.getSelectedItemIndex() >= 0 + && listBoxScenario.getSelectedItemIndex() < + (int) scenarioFiles.size()) { + GameSettings gameSettings; + loadGameSettings(&scenarioInfo, &gameSettings); + + string scenarioLogo = ""; + bool loadingImageUsed = false; + + Game::extractScenarioLogoFile(&gameSettings, scenarioLogo, + loadingImageUsed); + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] scenarioLogo [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, scenarioLogo.c_str()); + + if (scenarioLogo != "") { + cleanupPreviewTexture(); + scenarioLogoTexture = Renderer::findTexture(scenarioLogo); + } else { + cleanupPreviewTexture(); + scenarioLogoTexture = NULL; + } + } + } + } + + void MenuStateScenario::loadGameSettings(const ScenarioInfo * + scenarioInfo, + GameSettings * gameSettings) { + if (listBoxScenario.getSelectedItemIndex() < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "listBoxScenario.getSelectedItemIndex() < 0, = %d", + listBoxScenario.getSelectedItemIndex()); + throw megaglest_runtime_error(szBuf); + } else if (listBoxScenario.getSelectedItemIndex() >= + (int) scenarioFiles.size()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "listBoxScenario.getSelectedItemIndex() >= scenarioFiles.size(), = [%d][%d]", + listBoxScenario.getSelectedItemIndex(), + (int) scenarioFiles.size()); + throw megaglest_runtime_error(szBuf); + } + + Scenario::loadGameSettings(dirList, scenarioInfo, gameSettings, + formatString(scenarioFiles + [listBoxScenario. + getSelectedItemIndex()])); + } + + void MenuStateScenario::showMessageBox(const string & text, + const string & header, + bool toggle) { + if (!toggle) { + mainMessageBox.setEnabled(false); + } + + if (!mainMessageBox.getEnabled()) { + mainMessageBox.setText(text); + mainMessageBox.setHeader(header); + mainMessageBox.setEnabled(true); + } else { + mainMessageBox.setEnabled(false); + } + } + + void MenuStateScenario::keyDown(SDL_KeyboardEvent key) { + Config & configKeys = + Config::getInstance(std::pair < ConfigType, + ConfigType >(cfgMainKeys, cfgUserKeys)); + if (isKeyPressed(configKeys.getSDLKey("SaveGUILayout"), key) == true) { + GraphicComponent::saveAllCustomProperties(containerName); + } + } + + } } //end namespace diff --git a/source/glest_game/menu/menu_state_scenario.h b/source/glest_game/menu/menu_state_scenario.h index dc6557c13..61c4f7fe5 100644 --- a/source/glest_game/menu/menu_state_scenario.h +++ b/source/glest_game/menu/menu_state_scenario.h @@ -15,83 +15,80 @@ # include "main_menu.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// =============================== -// class MenuStateScenario -// =============================== + // =============================== + // class MenuStateScenario + // =============================== - class MenuStateScenario:public MenuState - { - private: + class MenuStateScenario :public MenuState { + private: - GraphicButton buttonReturn; - GraphicButton buttonPlayNow; + GraphicButton buttonReturn; + GraphicButton buttonPlayNow; - GraphicLabel labelInfo; - GraphicLabel labelScenario; - GraphicListBox listBoxScenario; - GraphicLabel labelScenarioName; + GraphicLabel labelInfo; + GraphicLabel labelScenario; + GraphicListBox listBoxScenario; + GraphicLabel labelScenarioName; - vector < string > scenarioFiles; + vector < string > scenarioFiles; - ScenarioInfo scenarioInfo; - vector < string > dirList; + ScenarioInfo scenarioInfo; + vector < string > dirList; - GraphicMessageBox mainMessageBox; - int mainMessageBoxState; + GraphicMessageBox mainMessageBox; + int mainMessageBoxState; - string autoloadScenarioName; + string autoloadScenarioName; - time_t previewLoadDelayTimer; - bool needToLoadTextures; + time_t previewLoadDelayTimer; + bool needToLoadTextures; - bool enableScenarioTexturePreview; - Texture2D *scenarioLogoTexture; + bool enableScenarioTexturePreview; + Texture2D *scenarioLogoTexture; - bool isTutorialMode; + bool isTutorialMode; - public: - MenuStateScenario (Program * program, MainMenu * mainMenu, - bool isTutorialMode, - const vector < string > &dirList, - string autoloadScenarioName = ""); - virtual ~ MenuStateScenario (); + public: + MenuStateScenario(Program * program, MainMenu * mainMenu, + bool isTutorialMode, + const vector < string > &dirList, + string autoloadScenarioName = ""); + virtual ~MenuStateScenario(); - void mouseClick (int x, int y, MouseButton mouseButton); - void mouseMove (int x, int y, const MouseState * mouseState); - void render (); - void update (); + void mouseClick(int x, int y, MouseButton mouseButton); + void mouseMove(int x, int y, const MouseState * mouseState); + void render(); + void update(); - void launchGame (); - void setScenario (int i); - int getScenarioCount () const - { - return listBoxScenario.getItemCount (); - } + void launchGame(); + void setScenario(int i); + int getScenarioCount() const { + return listBoxScenario.getItemCount(); + } - virtual void keyDown (SDL_KeyboardEvent key); + virtual void keyDown(SDL_KeyboardEvent key); - virtual void reloadUI (); + virtual void reloadUI(); - private: + private: - void loadScenarioInfo (string file, ScenarioInfo * scenarioInfo); - void loadGameSettings (const ScenarioInfo * scenarioInfo, - GameSettings * gameSettings); - void loadScenarioPreviewTexture (); - Difficulty computeDifficulty (const ScenarioInfo * scenarioInfo); - void showMessageBox (const string & text, const string & header, - bool toggle); + void loadScenarioInfo(string file, ScenarioInfo * scenarioInfo); + void loadGameSettings(const ScenarioInfo * scenarioInfo, + GameSettings * gameSettings); + void loadScenarioPreviewTexture(); + Difficulty computeDifficulty(const ScenarioInfo * scenarioInfo); + void showMessageBox(const string & text, const string & header, + bool toggle); - void cleanupPreviewTexture (); - }; + void cleanupPreviewTexture(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/menu/server_line.cpp b/source/glest_game/menu/server_line.cpp index 66f4f1689..9650b1c98 100644 --- a/source/glest_game/menu/server_line.cpp +++ b/source/glest_game/menu/server_line.cpp @@ -21,342 +21,316 @@ #include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class ServerLine -// ===================================================== + // ===================================================== + // class ServerLine + // ===================================================== - ServerLine::ServerLine (MasterServerInfo * mServerInfo, int lineIndex, - int baseY, int lineHeight, - const char *containerName) - { - this->containerName = containerName; - this->countryTexture = NULL; - Lang & lang = Lang::getInstance (); + ServerLine::ServerLine(MasterServerInfo * mServerInfo, int lineIndex, + int baseY, int lineHeight, + const char *containerName) { + this->containerName = containerName; + this->countryTexture = NULL; + Lang & lang = Lang::getInstance(); - this->lineHeight = lineHeight; - int lineOffset = lineHeight * lineIndex; - masterServerInfo = *mServerInfo; - int i = 5; - this->baseY = baseY; - Vec3f color = Vec3f (1.0f, 1.0f, 1.0f); + this->lineHeight = lineHeight; + int lineOffset = lineHeight * lineIndex; + masterServerInfo = *mServerInfo; + int i = 5; + this->baseY = baseY; + Vec3f color = Vec3f(1.0f, 1.0f, 1.0f); - if (masterServerInfo.getConnectedClients () == 0) - { - color = Vec3f (0.6f, 0.7f, 1.0f); - } + if (masterServerInfo.getConnectedClients() == 0) { + color = Vec3f(0.6f, 0.7f, 1.0f); + } - //general info: - //i+= 10; - glestVersionLabel.init (i, baseY - lineOffset); - glestVersionLabel.setRenderBackground (true); - glestVersionLabel.setMaxEditRenderWidth (970); // use background for whole line - glestVersionLabel.setTextColor (color); - glestVersionLabel.setText (" " + masterServerInfo.getGlestVersion ()); - glestVersionLabel.setFont (CoreData::getInstance (). - getDisplayFontSmall ()); - glestVersionLabel.setFont3D (CoreData::getInstance (). - getDisplayFontSmall3D ()); + //general info: + //i+= 10; + glestVersionLabel.init(i, baseY - lineOffset); + glestVersionLabel.setRenderBackground(true); + glestVersionLabel.setMaxEditRenderWidth(970); // use background for whole line + glestVersionLabel.setTextColor(color); + glestVersionLabel.setText(" " + masterServerInfo.getGlestVersion()); + glestVersionLabel.setFont(CoreData::getInstance(). + getDisplayFontSmall()); + glestVersionLabel.setFont3D(CoreData::getInstance(). + getDisplayFontSmall3D()); - i += 80; - string platform = masterServerInfo.getPlatform (); - size_t revOffset = platform.find ("-Rev"); - if (revOffset != platform.npos) - { - platform = platform.substr (0, revOffset); - } + i += 80; + string platform = masterServerInfo.getPlatform(); + size_t revOffset = platform.find("-Rev"); + if (revOffset != platform.npos) { + platform = platform.substr(0, revOffset); + } - platformLabel.init (i, baseY - lineOffset); - platformLabel.setTextColor (color); - platformLabel.setText (platform); - platformLabel.setFont (CoreData::getInstance ().getDisplayFontSmall ()); - platformLabel.setFont3D (CoreData::getInstance (). - getDisplayFontSmall3D ()); + platformLabel.init(i, baseY - lineOffset); + platformLabel.setTextColor(color); + platformLabel.setText(platform); + platformLabel.setFont(CoreData::getInstance().getDisplayFontSmall()); + platformLabel.setFont3D(CoreData::getInstance(). + getDisplayFontSmall3D()); - // i+=50; - // registeredObjNameList.push_back("binaryCompileDateLabel" + intToStr(lineIndex)); - // binaryCompileDateLabel.registerGraphicComponent(containerName,"binaryCompileDateLabel" + intToStr(lineIndex)); - // binaryCompileDateLabel.init(i,baseY-lineOffset); - // binaryCompileDateLabel.setText(masterServerInfo.getBinaryCompileDate()); + // i+=50; + // registeredObjNameList.push_back("binaryCompileDateLabel" + intToStr(lineIndex)); + // binaryCompileDateLabel.registerGraphicComponent(containerName,"binaryCompileDateLabel" + intToStr(lineIndex)); + // binaryCompileDateLabel.init(i,baseY-lineOffset); + // binaryCompileDateLabel.setText(masterServerInfo.getBinaryCompileDate()); - //game info: - i += 120; - serverTitleLabel.init (i, baseY - lineOffset); - serverTitleLabel.setTextColor (color); - serverTitleLabel.setText (masterServerInfo.getServerTitle ()); + //game info: + i += 120; + serverTitleLabel.init(i, baseY - lineOffset); + serverTitleLabel.setTextColor(color); + serverTitleLabel.setText(masterServerInfo.getServerTitle()); - i += 170; - country.init (i, baseY - lineOffset); - country.setTextColor (color); - country.setText (masterServerInfo.getCountry ()); + i += 170; + country.init(i, baseY - lineOffset); + country.setTextColor(color); + country.setText(masterServerInfo.getCountry()); - string data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - string countryLogoPath = data_path + "data/core/misc_textures/flags"; + string data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + string countryLogoPath = data_path + "data/core/misc_textures/flags"; - Config & config = Config::getInstance (); - if (config.getString ("CountryTexturePath", "") != "") - { - countryLogoPath = config.getString ("CountryTexturePath", ""); - } - endPathWithSlash (countryLogoPath); + Config & config = Config::getInstance(); + if (config.getString("CountryTexturePath", "") != "") { + countryLogoPath = config.getString("CountryTexturePath", ""); + } + endPathWithSlash(countryLogoPath); - string logoFile = - countryLogoPath + toLower (masterServerInfo.getCountry ()) + ".png"; - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] logoFile [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - logoFile.c_str ()); + string logoFile = + countryLogoPath + toLower(masterServerInfo.getCountry()) + ".png"; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] logoFile [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + logoFile.c_str()); - if (fileExists (logoFile) == true) - { - countryTexture = - GraphicsInterface::getInstance ().getFactory ()->newTexture2D (); - //loadingTexture = renderer.newTexture2D(rsGlobal); - countryTexture->setMipmap (true); - //loadingTexture->getPixmap()->load(filepath); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] logoFile [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - logoFile.c_str ()); - countryTexture->load (logoFile); + if (fileExists(logoFile) == true) { + countryTexture = + GraphicsInterface::getInstance().getFactory()->newTexture2D(); + //loadingTexture = renderer.newTexture2D(rsGlobal); + countryTexture->setMipmap(true); + //loadingTexture->getPixmap()->load(filepath); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] logoFile [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + logoFile.c_str()); + countryTexture->load(logoFile); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - Renderer & renderer = Renderer::getInstance (); - renderer.initTexture (rsGlobal, countryTexture); - } + Renderer & renderer = Renderer::getInstance(); + renderer.initTexture(rsGlobal, countryTexture); + } - i += 60; - // ipAddressLabel.init(i,baseY-lineOffset); - // ipAddressLabel.setText(masterServerInfo.getIpAddress()); - // i+=100; + i += 60; + // ipAddressLabel.init(i,baseY-lineOffset); + // ipAddressLabel.setText(masterServerInfo.getIpAddress()); + // i+=100; - wrongVersionLabel.init (i, baseY - lineOffset); - wrongVersionLabel.setTextColor (Vec3f (1.0f, 0.0f, 0.0f)); - wrongVersionLabel.setText (lang.getString ("IncompatibleVersion")); + wrongVersionLabel.init(i, baseY - lineOffset); + wrongVersionLabel.setTextColor(Vec3f(1.0f, 0.0f, 0.0f)); + wrongVersionLabel.setText(lang.getString("IncompatibleVersion")); - //game setup info: - techLabel.init (i, baseY - lineOffset); - techLabel.setTextColor (color); - techLabel.setText (masterServerInfo.getTech ()); + //game setup info: + techLabel.init(i, baseY - lineOffset); + techLabel.setTextColor(color); + techLabel.setText(masterServerInfo.getTech()); - i += 130; - mapLabel.init (i, baseY - lineOffset); - mapLabel.setTextColor (color); - mapLabel.setText (masterServerInfo.getMap ()); - i += 130; + i += 130; + mapLabel.init(i, baseY - lineOffset); + mapLabel.setTextColor(color); + mapLabel.setText(masterServerInfo.getMap()); + i += 130; - // tilesetLabel.init(i,baseY-lineOffset); - // tilesetLabel.setText(masterServerInfo.getTileset()); - // i+=100; + // tilesetLabel.init(i,baseY-lineOffset); + // tilesetLabel.setText(masterServerInfo.getTileset()); + // i+=100; - activeSlotsLabel.init (i, baseY - lineOffset); - activeSlotsLabel.setTextColor (color); - activeSlotsLabel. - setText (intToStr (masterServerInfo.getActiveSlots ()) + "/" + - intToStr (masterServerInfo.getNetworkSlots ()) + "/" + - intToStr (masterServerInfo.getConnectedClients ())); + activeSlotsLabel.init(i, baseY - lineOffset); + activeSlotsLabel.setTextColor(color); + activeSlotsLabel. + setText(intToStr(masterServerInfo.getActiveSlots()) + "/" + + intToStr(masterServerInfo.getNetworkSlots()) + "/" + + intToStr(masterServerInfo.getConnectedClients())); - i += 50; - //externalConnectPort.init(i, baseY - lineOffset); - //externalConnectPort.setTextColor(color); - //externalConnectPort.setText(intToStr(masterServerInfo.getExternalConnectPort())); + i += 50; + //externalConnectPort.init(i, baseY - lineOffset); + //externalConnectPort.setTextColor(color); + //externalConnectPort.setText(intToStr(masterServerInfo.getExternalConnectPort())); - i += 30; - status.init (i - 10, baseY - lineOffset); - status.setTextColor (color); - status.setText (lang. - getString ("MGGameStatus" + - intToStr (masterServerInfo.getStatus ()))); + i += 30; + status.init(i - 10, baseY - lineOffset); + status.setTextColor(color); + status.setText(lang. + getString("MGGameStatus" + + intToStr(masterServerInfo.getStatus()))); - i += 130; - selectButton.init (i + 25, baseY - lineOffset, 35, lineHeight - 5); - selectButton.setText (">"); - selectButton.setAlwaysLighted (true); + i += 130; + selectButton.init(i + 25, baseY - lineOffset, 35, lineHeight - 5); + selectButton.setText(">"); + selectButton.setAlwaysLighted(true); - //printf("glestVersionString [%s] masterServerInfo->getGlestVersion() [%s]\n",glestVersionString.c_str(),masterServerInfo->getGlestVersion().c_str()); - compatible = - checkVersionComptability (glestVersionString, - masterServerInfo.getGlestVersion ()); - selectButton.setEnabled (compatible); - selectButton.setEditable (compatible); + //printf("glestVersionString [%s] masterServerInfo->getGlestVersion() [%s]\n",glestVersionString.c_str(),masterServerInfo->getGlestVersion().c_str()); + compatible = + checkVersionComptability(glestVersionString, + masterServerInfo.getGlestVersion()); + selectButton.setEnabled(compatible); + selectButton.setEditable(compatible); - } + } - void ServerLine::reloadUI () - { - Lang & lang = Lang::getInstance (); + void ServerLine::reloadUI() { + Lang & lang = Lang::getInstance(); - glestVersionLabel.setText (masterServerInfo.getGlestVersion ()); + glestVersionLabel.setText(masterServerInfo.getGlestVersion()); - string platform = masterServerInfo.getPlatform (); - size_t revOffset = platform.find ("-Rev"); - if (revOffset != platform.npos) - { - platform = platform.substr (0, revOffset); - } + string platform = masterServerInfo.getPlatform(); + size_t revOffset = platform.find("-Rev"); + if (revOffset != platform.npos) { + platform = platform.substr(0, revOffset); + } - platformLabel.setText (platform); + platformLabel.setText(platform); - serverTitleLabel.setText (masterServerInfo.getServerTitle ()); + serverTitleLabel.setText(masterServerInfo.getServerTitle()); - country.setText (masterServerInfo.getCountry ()); + country.setText(masterServerInfo.getCountry()); - wrongVersionLabel.setText (lang.getString ("IncompatibleVersion")); + wrongVersionLabel.setText(lang.getString("IncompatibleVersion")); - techLabel.setText (masterServerInfo.getTech ()); + techLabel.setText(masterServerInfo.getTech()); - mapLabel.setText (masterServerInfo.getMap ()); - activeSlotsLabel. - setText (intToStr (masterServerInfo.getActiveSlots ()) + "/" + - intToStr (masterServerInfo.getNetworkSlots ()) + "/" + - intToStr (masterServerInfo.getConnectedClients ())); + mapLabel.setText(masterServerInfo.getMap()); + activeSlotsLabel. + setText(intToStr(masterServerInfo.getActiveSlots()) + "/" + + intToStr(masterServerInfo.getNetworkSlots()) + "/" + + intToStr(masterServerInfo.getConnectedClients())); - //externalConnectPort.setText(intToStr(masterServerInfo.getExternalConnectPort())); + //externalConnectPort.setText(intToStr(masterServerInfo.getExternalConnectPort())); - status.setText (lang. - getString ("MGGameStatus" + - intToStr (masterServerInfo.getStatus ()))); + status.setText(lang. + getString("MGGameStatus" + + intToStr(masterServerInfo.getStatus()))); - GraphicComponent:: - reloadFontsForRegisterGraphicComponents (containerName); - } + GraphicComponent:: + reloadFontsForRegisterGraphicComponents(containerName); + } - ServerLine::~ServerLine () - { - //delete masterServerInfo; + ServerLine::~ServerLine() { + //delete masterServerInfo; - if (countryTexture != NULL) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + if (countryTexture != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - countryTexture->end (); - delete countryTexture; + countryTexture->end(); + delete countryTexture; - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); - //delete loadingTexture; - countryTexture = NULL; - } - } + //delete loadingTexture; + countryTexture = NULL; + } + } - bool ServerLine::buttonMouseClick (int x, int y) - { - return selectButton.mouseClick (x, y); - } + bool ServerLine::buttonMouseClick(int x, int y) { + return selectButton.mouseClick(x, y); + } - bool ServerLine::buttonMouseMove (int x, int y) - { - return selectButton.mouseMove (x, y); - } + bool ServerLine::buttonMouseMove(int x, int y) { + return selectButton.mouseMove(x, y); + } - void ServerLine::render () - { - Renderer & renderer = Renderer::getInstance (); - //general info: - renderer.renderLabel (&glestVersionLabel); - renderer.renderLabel (&platformLabel); - //renderer.renderLabel(&binaryCompileDateLabel); + void ServerLine::render() { + Renderer & renderer = Renderer::getInstance(); + //general info: + renderer.renderLabel(&glestVersionLabel); + renderer.renderLabel(&platformLabel); + //renderer.renderLabel(&binaryCompileDateLabel); - //game info: - renderer.renderLabel (&serverTitleLabel); - if (countryTexture != NULL) - { - renderer.renderTextureQuad (country.getX () + 1, country.getY () + 4, - countryTexture->getTextureWidth (), - countryTexture->getTextureHeight (), - countryTexture, 0.7f); - } - else - { - renderer.renderLabel (&country); - } - if (compatible) - { - if (selectButton.getEnabled () == true) - { - //renderer.renderLabel(&ipAddressLabel); - //game setup info: - renderer.renderLabel (&techLabel); - renderer.renderLabel (&mapLabel); - //renderer.renderLabel(&tilesetLabel); - renderer.renderLabel (&activeSlotsLabel); - //renderer.renderLabel(&externalConnectPort); - renderer.renderLabel (&status); - } - } - else - { - renderer.renderLabel (&wrongVersionLabel); - } - renderer.renderLabel (&status); + //game info: + renderer.renderLabel(&serverTitleLabel); + if (countryTexture != NULL) { + renderer.renderTextureQuad(country.getX() + 1, country.getY() + 4, + countryTexture->getTextureWidth(), + countryTexture->getTextureHeight(), + countryTexture, 0.7f); + } else { + renderer.renderLabel(&country); + } + if (compatible) { + if (selectButton.getEnabled() == true) { + //renderer.renderLabel(&ipAddressLabel); + //game setup info: + renderer.renderLabel(&techLabel); + renderer.renderLabel(&mapLabel); + //renderer.renderLabel(&tilesetLabel); + renderer.renderLabel(&activeSlotsLabel); + //renderer.renderLabel(&externalConnectPort); + renderer.renderLabel(&status); + } + } else { + renderer.renderLabel(&wrongVersionLabel); + } + renderer.renderLabel(&status); - bool joinEnabled = - (masterServerInfo.getNetworkSlots () > - masterServerInfo.getConnectedClients ()); - if (joinEnabled == true) - { - if (compatible) - { - selectButton.setEnabled (true); - selectButton.setVisible (true); - renderer.renderButton (&selectButton); - } - } - else - { - selectButton.setEnabled (false); - selectButton.setVisible (false); - } - } + bool joinEnabled = + (masterServerInfo.getNetworkSlots() > + masterServerInfo.getConnectedClients()); + if (joinEnabled == true) { + if (compatible) { + selectButton.setEnabled(true); + selectButton.setVisible(true); + renderer.renderButton(&selectButton); + } + } else { + selectButton.setEnabled(false); + selectButton.setVisible(false); + } + } - void ServerLine::setY (int y) - { - selectButton.setY (y); + void ServerLine::setY(int y) { + selectButton.setY(y); - //general info: - glestVersionLabel.setY (y); - platformLabel.setY (y); - //binaryCompileDateLabel.setY(y); + //general info: + glestVersionLabel.setY(y); + platformLabel.setY(y); + //binaryCompileDateLabel.setY(y); - //game info: - serverTitleLabel.setY (y); - country.setY (y); - status.setY (y); - //ipAddressLabel.setY(y); + //game info: + serverTitleLabel.setY(y); + country.setY(y); + status.setY(y); + //ipAddressLabel.setY(y); - //game setup info: - techLabel.setY (y); - mapLabel.setY (y); - //tilesetLabel.setY(y); - activeSlotsLabel.setY (y); + //game setup info: + techLabel.setY(y); + mapLabel.setY(y); + //tilesetLabel.setY(y); + activeSlotsLabel.setY(y); - //externalConnectPort.setY(y); + //externalConnectPort.setY(y); - } + } - } + } } //end namespace diff --git a/source/glest_game/menu/server_line.h b/source/glest_game/menu/server_line.h index 9750c08c4..d1ca2a000 100644 --- a/source/glest_game/menu/server_line.h +++ b/source/glest_game/menu/server_line.h @@ -24,71 +24,67 @@ # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// =============================== -// ServerLine -// =============================== + // =============================== + // ServerLine + // =============================== - class ServerLine - { - private: + class ServerLine { + private: - MasterServerInfo masterServerInfo; - int lineHeight; - int baseY; - bool compatible; - GraphicButton selectButton; - GraphicLabel wrongVersionLabel; + MasterServerInfo masterServerInfo; + int lineHeight; + int baseY; + bool compatible; + GraphicButton selectButton; + GraphicLabel wrongVersionLabel; - //general info: - GraphicLabel glestVersionLabel; - GraphicLabel platformLabel; - //GraphicLabel binaryCompileDateLabel; + //general info: + GraphicLabel glestVersionLabel; + GraphicLabel platformLabel; + //GraphicLabel binaryCompileDateLabel; - //game info: - GraphicLabel serverTitleLabel; - GraphicLabel ipAddressLabel; + //game info: + GraphicLabel serverTitleLabel; + GraphicLabel ipAddressLabel; - //game setup info: - GraphicLabel techLabel; - GraphicLabel mapLabel; - GraphicLabel tilesetLabel; - GraphicLabel activeSlotsLabel; + //game setup info: + GraphicLabel techLabel; + GraphicLabel mapLabel; + GraphicLabel tilesetLabel; + GraphicLabel activeSlotsLabel; - GraphicLabel externalConnectPort; + GraphicLabel externalConnectPort; - GraphicLabel country; - GraphicLabel status; + GraphicLabel country; + GraphicLabel status; - Texture2D *countryTexture; + Texture2D *countryTexture; - const char *containerName; + const char *containerName; - public: - ServerLine (MasterServerInfo * mServerInfo, int lineIndex, int baseY, - int lineHeight, const char *containerName); - virtual ~ ServerLine (); - MasterServerInfo *getMasterServerInfo () - { - return &masterServerInfo; - } - const int getLineHeight () const - { - return lineHeight; - } - bool buttonMouseClick (int x, int y); - bool buttonMouseMove (int x, int y); - void setY (int y); - //void setIndex(int value); - void render (); + public: + ServerLine(MasterServerInfo * mServerInfo, int lineIndex, int baseY, + int lineHeight, const char *containerName); + virtual ~ServerLine(); + MasterServerInfo *getMasterServerInfo() { + return &masterServerInfo; + } + const int getLineHeight() const { + return lineHeight; + } + bool buttonMouseClick(int x, int y); + bool buttonMouseMove(int x, int y); + void setY(int y); + //void setIndex(int value); + void render(); - virtual void reloadUI (); - }; + virtual void reloadUI(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/network/client_interface.cpp b/source/glest_game/network/client_interface.cpp index 93105bd0e..0d6b72b9e 100644 --- a/source/glest_game/network/client_interface.cpp +++ b/source/glest_game/network/client_interface.cpp @@ -46,1139 +46,566 @@ using namespace Shared::Util; #endif -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -const bool debugClientInterfacePerf = false; + const bool debugClientInterfacePerf = false; -const int ClientInterface::messageWaitTimeout = 10000; //10 seconds -const int ClientInterface::waitSleepTime = 10; -const int ClientInterface::maxNetworkCommandListSendTimeWait = 5; + const int ClientInterface::messageWaitTimeout = 10000; //10 seconds + const int ClientInterface::waitSleepTime = 10; + const int ClientInterface::maxNetworkCommandListSendTimeWait = 5; -// ===================================================== -// class ClientInterfaceThread -// ===================================================== + // ===================================================== + // class ClientInterfaceThread + // ===================================================== -ClientInterfaceThread::ClientInterfaceThread(ClientInterface *client) : BaseThread() { - this->clientInterface = client; - this->uniqueID = "ClientInterfaceThread"; -} - -ClientInterfaceThread::~ClientInterfaceThread() { - this->clientInterface = NULL; -} - -void ClientInterfaceThread::setQuitStatus(bool value) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d value = %d\n",__FILE__,__FUNCTION__,__LINE__,value); - - BaseThread::setQuitStatus(value); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); -} - -bool ClientInterfaceThread::canShutdown(bool deleteSelfIfShutdownDelayed) { - bool ret = (getExecutingTask() == false); - if(ret == false && deleteSelfIfShutdownDelayed == true) { - setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed); - deleteSelfIfRequired(); - signalQuit(); - } - - return ret; -} - -void ClientInterfaceThread::execute() { - RunningStatusSafeWrapper runningStatus(this); - try { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ****************** STARTING worker thread this = %p\n",__FILE__,__FUNCTION__,__LINE__,this); - - // Set socket to non blocking - if(clientInterface != NULL && clientInterface->getSocket(true) != NULL) { - clientInterface->getSocket(true)->setBlock(false); + ClientInterfaceThread::ClientInterfaceThread(ClientInterface *client) : BaseThread() { + this->clientInterface = client; + this->uniqueID = "ClientInterfaceThread"; } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("ClientInterfaceThread::exec Line: %d\n",__LINE__); + ClientInterfaceThread::~ClientInterfaceThread() { + this->clientInterface = NULL; + } - time_t clientSimulationLagStartTime = 0; - Chrono chrono; - for(;this->clientInterface != NULL;) { + void ClientInterfaceThread::setQuitStatus(bool value) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] Line: %d value = %d\n", __FILE__, __FUNCTION__, __LINE__, value); - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; + BaseThread::setQuitStatus(value); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] Line: %d\n", __FILE__, __FUNCTION__, __LINE__); + } + + bool ClientInterfaceThread::canShutdown(bool deleteSelfIfShutdownDelayed) { + bool ret = (getExecutingTask() == false); + if (ret == false && deleteSelfIfShutdownDelayed == true) { + setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed); + deleteSelfIfRequired(); + signalQuit(); } - ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); + return ret; + } - if(debugClientInterfacePerf == true) printf("START === Client thread\n"); + void ClientInterfaceThread::execute() { + RunningStatusSafeWrapper runningStatus(this); + try { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ****************** STARTING worker thread this = %p\n", __FILE__, __FUNCTION__, __LINE__, this); - //printf("ClientInterfaceThread::exec Line: %d\n",__LINE__); - - uint64 loopCount = 0; - if(debugClientInterfacePerf == true) { - chrono.start(); - } - while( this->getQuitStatus() == false && - clientInterface != NULL) { - //printf("ClientInterfaceThread::exec Line: %d this->getQuitStatus(): %d\n",__LINE__,this->getQuitStatus()); - - // START: Test simulating lag for the client - int simulateLag = Config::getInstance().getInt("SimulateClientLag","0"); - if(simulateLag > 0) { - if(clientSimulationLagStartTime == 0) { - clientSimulationLagStartTime = time(NULL); - } - if(difftime((long int)time(NULL),clientSimulationLagStartTime) <= Config::getInstance().getInt("SimulateClientLagDurationSeconds","0")) { - sleep(simulateLag); - } + // Set socket to non blocking + if (clientInterface != NULL && clientInterface->getSocket(true) != NULL) { + clientInterface->getSocket(true)->setBlock(false); } - // END: Test simulating lag for the client - clientInterface->updateNetworkFrame(); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("ClientInterfaceThread::exec Line: %d\n", __LINE__); - //printf("ClientInterfaceThread::exec Line: %d this->getQuitStatus(): %d\n",__LINE__,this->getQuitStatus()); + time_t clientSimulationLagStartTime = 0; + Chrono chrono; + for (; this->clientInterface != NULL;) { - if(debugClientInterfacePerf == true) { - loopCount++; - if(chrono.getMillis() >= 1000) { - printf("Client thread loopCount = %llu\n",(long long unsigned int)loopCount); + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } - loopCount = 0; - //sleep(0); + ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); + + if (debugClientInterfacePerf == true) printf("START === Client thread\n"); + + //printf("ClientInterfaceThread::exec Line: %d\n",__LINE__); + + uint64 loopCount = 0; + if (debugClientInterfacePerf == true) { chrono.start(); } - } - } - - if(debugClientInterfacePerf == true) { - printf("END === Client thread\n"); - } - - //printf("ClientInterfaceThread::exec Line: %d\n",__LINE__); - - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; - } - - //printf("ClientInterfaceThread::exec Line: %d\n",__LINE__); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("ClientInterfaceThread::exec Line: %d\n",__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ****************** ENDING worker thread this = %p\n",__FILE__,__FUNCTION__,__LINE__,this); - } - catch(const exception &ex) { - - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(clientInterface == NULL || clientInterface->getSocket(true) == NULL || clientInterface->getSocket(true)->isConnected() == true) { - throw megaglest_runtime_error(ex.what()); - } - } - catch(...) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - throw megaglest_runtime_error(szBuf); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); -} - -// ===================================================== -// class ClientInterface -// ===================================================== - -ClientInterface::ClientInterface() : GameNetworkInterface() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] constructor for %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this); - - networkCommandListThreadAccessor = new Mutex(CODE_AT_LINE); - networkCommandListThread = NULL; - cachedPendingCommandsIndex = 0; - cachedLastPendingFrameCount = 0; - timeClientWaitedForLastMessage = 0; - - flagAccessor = new Mutex(CODE_AT_LINE); - - clientSocket = NULL; - sessionKey = 0; - launchGame = false; - introDone = false; - - this->joinGameInProgress = false; - this->joinGameInProgressLaunch = false; - this->readyForInGameJoin = false; - this->resumeInGameJoin = false; - - quitThreadAccessor = new Mutex(CODE_AT_LINE); - setQuitThread(false); - - playerIndex = -1; - gameSettingsReceivedCount = 0; - setGameSettingsReceived(false); - gameSettingsReceivedCount = 0; - connectedTime = 0; - port = 0; - serverFTPPort = 0; - - gotIntro = false; - lastNetworkCommandListSendTime = 0; - currentFrameCount = 0; - lastSentFrameCount = 0; - clientSimulationLagStartTime = 0; - - networkGameDataSynchCheckOkMap = false; - networkGameDataSynchCheckOkTile = false; - networkGameDataSynchCheckOkTech = false; - this->setNetworkGameDataSynchCheckTechMismatchReport(""); - this->setReceivedDataSynchCheck(false); -} - -void ClientInterface::shutdownNetworkCommandListThread(MutexSafeWrapper &safeMutexWrapper) { - if(networkCommandListThread != NULL) { - //printf("START === shutdownNetworkCommandListThread\n"); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n",__FUNCTION__,__LINE__); - - setQuitThread(true); - networkCommandListThread->signalQuit(); - safeMutexWrapper.ReleaseLock(true); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n",__FUNCTION__,__LINE__); - - Chrono chronoElapsed(true); - for(;chronoElapsed.getMillis() <= 10000;) { - safeMutexWrapper.Lock(); - if(networkCommandListThread != NULL && - networkCommandListThread->canShutdown(false) == false && - networkCommandListThread->getRunningStatus() == true) { - - safeMutexWrapper.ReleaseLock(true); - if(chronoElapsed.getMillis() % 1000 == 0) { - sleep(1); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n",__FUNCTION__,__LINE__); - } - } - else { - safeMutexWrapper.ReleaseLock(true); - break; - } - //printf("%s Line: %d\n",__FUNCTION__,__LINE__); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n chronoElapsed.getMillis(): %lld",__FUNCTION__,__LINE__,(long long int)chronoElapsed.getMillis()); - //printf("A === shutdownNetworkCommandListThread\n"); - - safeMutexWrapper.Lock(); - if(networkCommandListThread != NULL && - networkCommandListThread->canShutdown(true)) { - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n",__FUNCTION__,__LINE__); - - delete networkCommandListThread; - networkCommandListThread = NULL; - } - else { - networkCommandListThread = NULL; - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n",__FUNCTION__,__LINE__); - //printf("END === shutdownNetworkCommandListThread\n"); - } -} - -ClientInterface::~ClientInterface() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] destructor for %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this); - //printf("START === Client destructor\n"); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n",__FUNCTION__,__LINE__); - - MutexSafeWrapper safeMutex(networkCommandListThreadAccessor,CODE_AT_LINE); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n",__FUNCTION__,__LINE__); - - shutdownNetworkCommandListThread(safeMutex); - //printf("A === Client destructor\n"); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n",__FUNCTION__,__LINE__); - - if(clientSocket != NULL && - clientSocket->isConnected() == true) { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n",__FUNCTION__,__LINE__); - - Lang &lang= Lang::getInstance(); - const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); - for(unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { - - string sQuitText = "has chosen to leave the game!"; - if(lang.hasString("PlayerLeftGame",languageList[langIndex]) == true) { - sQuitText = lang.getString("PlayerLeftGame",languageList[langIndex]); - } - - if(clientSocket != NULL && clientSocket->isConnected() == true) { - sendTextMessage(sQuitText,-1,false,languageList[langIndex]); - } - } - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n",__FUNCTION__,__LINE__); - - //printf("B === Client destructor\n"); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - close(false); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n",__FUNCTION__,__LINE__); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n",__FUNCTION__,__LINE__); - - //printf("C === Client destructor\n"); - - networkCommandListThreadAccessor = NULL; - safeMutex.ReleaseLock(false,true); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n",__FUNCTION__,__LINE__); - - delete flagAccessor; - flagAccessor = NULL; - //printf("END === Client destructor\n"); - - delete quitThreadAccessor; - quitThreadAccessor = NULL; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n",__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -bool ClientInterface::getQuitThread() { - MutexSafeWrapper safeMutex(quitThreadAccessor,CODE_AT_LINE); - return this->quitThread; -} -void ClientInterface::setQuitThread(bool value) { - MutexSafeWrapper safeMutex(quitThreadAccessor,CODE_AT_LINE); - this->quitThread = value; -} - -bool ClientInterface::getQuit() { - MutexSafeWrapper safeMutex(quitThreadAccessor,CODE_AT_LINE); - return this->quit; -} -void ClientInterface::setQuit(bool value) { - MutexSafeWrapper safeMutex(quitThreadAccessor,CODE_AT_LINE); - this->quit = value; -} - -bool ClientInterface::getJoinGameInProgress() { - MutexSafeWrapper safeMutex(flagAccessor,CODE_AT_LINE); - return joinGameInProgress; -} -bool ClientInterface::getJoinGameInProgressLaunch() { - MutexSafeWrapper safeMutex(flagAccessor,CODE_AT_LINE); - return joinGameInProgressLaunch; -} - -bool ClientInterface::getReadyForInGameJoin() { - MutexSafeWrapper safeMutex(flagAccessor,CODE_AT_LINE); - return readyForInGameJoin; -} - -bool ClientInterface::getResumeInGameJoin() { - MutexSafeWrapper safeMutex(flagAccessor,CODE_AT_LINE); - return resumeInGameJoin; -} - -void ClientInterface::connect(const Ip &ip, int port) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); - - this->ip = ip; - this->port = port; - - MutexSafeWrapper safeMutex(networkCommandListThreadAccessor,CODE_AT_LINE); - shutdownNetworkCommandListThread(safeMutex); - - delete clientSocket; - clientSocket = NULL; - - safeMutex.ReleaseLock(); - - clientSocket = new ClientSocket(); - clientSocket->setBlock(false); - clientSocket->connect(ip, port); - connectedTime = time(NULL); - //clientSocket->setBlock(true); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END - socket = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,clientSocket->getSocketId()); -} - -void ClientInterface::reset() { - if(getSocket() != NULL) { - Lang &lang= Lang::getInstance(); - const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); - for(unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { - - string sQuitText = "has chosen to leave the game!"; - if(lang.hasString("PlayerLeftGame",languageList[langIndex]) == true) { - sQuitText = lang.getString("PlayerLeftGame",languageList[langIndex]); - } - sendTextMessage(sQuitText,-1,false,languageList[langIndex]); - } - close(); - } -} - -void ClientInterface::update() { - bool wasConnected = this->isConnected(); - if(gotIntro == true && - wasConnected == false) { - string playerNameStr = getHumanPlayerName(); - - Lang &lang= Lang::getInstance(); - - char szBuf1[8096]=""; - string statusTextFormat= lang.getString("PlayerDisconnected"); - snprintf(szBuf1,8096,statusTextFormat.c_str(),playerNameStr.c_str()); - - DisplayErrorMessage(szBuf1); - setQuit(true); - return; - } - - try { - NetworkMessageCommandList networkMessageCommandList(currentFrameCount); - for(int index = 0; index < GameConstants::maxPlayers; ++index) { - networkMessageCommandList.setNetworkPlayerFactionCRC(index,this->getNetworkPlayerFactionCRC(index)); - } - - //send as many commands as we can - while(requestedCommands.empty() == false) { - if(networkMessageCommandList.addCommand(&requestedCommands.back())) { - requestedCommands.pop_back(); - } - else { - break; - } - } - - double lastSendElapsed = difftime((long int)time(NULL),lastNetworkCommandListSendTime); - - // If we are on a frame that should send packets or we have commands - // to send now, send it now. - if((currentFrameCount >= this->gameSettings.getNetworkFramePeriod() && - currentFrameCount % this->gameSettings.getNetworkFramePeriod() == 0) || - networkMessageCommandList.getCommandCount() > 0) { - - if(lastSentFrameCount < currentFrameCount || - networkMessageCommandList.getCommandCount() > 0) { - - lastSentFrameCount = currentFrameCount; - sendMessage(&networkMessageCommandList); - - lastNetworkCommandListSendTime = time(NULL); - lastSendElapsed = 0; - } - } - - // If we have not sent anything for maxNetworkCommandListSendTimeWait - // seconds, send one now. - if(lastNetworkCommandListSendTime > 0 && - lastSendElapsed >= ClientInterface::maxNetworkCommandListSendTimeWait) { - - lastSentFrameCount = currentFrameCount; - sendMessage(&networkMessageCommandList); - lastNetworkCommandListSendTime = time(NULL); - } - - // Possible cause of out of synch since we have more commands that need - // to be sent in this frame - if(requestedCommands.empty() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING / ERROR, requestedCommands.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,requestedCommands.size()); - - string sMsg = "may go out of synch: client requestedCommands.size() = " + intToStr(requestedCommands.size()); - sendTextMessage(sMsg,-1, true,""); - sleep(1); - } - } - catch(const megaglest_runtime_error &ex) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - - if(this->isConnected() == false) { - if(gotIntro == false || wasConnected == false) { - string sErr = string(extractFileFromDirectoryPath(__FILE__).c_str()) + "::" + string(__FUNCTION__) + " network error: " + string(ex.what()); - DisplayErrorMessage(sErr); - } - - setQuit(true); - } - else { - throw megaglest_runtime_error(ex.what()); - } - } -} - -std::string ClientInterface::getIpAddress(bool mutexLock) { - string result = ""; - //MutexSafeWrapper safeMutexSlot((mutexLock == true ? mutexSocket : NULL),CODE_AT_LINE); - if(clientSocket != NULL) { - result = clientSocket->getIpAddress(); - } - return result; -} - -std::string ClientInterface::getServerIpAddress() { - return this->ip.getString(); -} - -void ClientInterface::updateLobby() { - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - - NetworkMessageType networkMessageType = getNextMessageType(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - switch(networkMessageType) - { - case nmtInvalid: - break; - - case nmtIntro: - { - NetworkMessageIntro networkMessageIntro; - if(receiveMessage(&networkMessageIntro)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - gotIntro = true; - sessionKey = networkMessageIntro.getSessionId(); - versionString = networkMessageIntro.getVersionString(); - playerIndex = networkMessageIntro.getPlayerIndex(); - serverName = networkMessageIntro.getName(); - serverUUID = networkMessageIntro.getPlayerUUID(); - serverPlatform = networkMessageIntro.getPlayerPlatform(); - serverFTPPort = networkMessageIntro.getFtpPort(); - - if(playerIndex < 0 || playerIndex >= GameConstants::maxPlayers) { - throw megaglest_runtime_error("playerIndex < 0 || playerIndex >= GameConstants::maxPlayers"); - } - - MutexSafeWrapper safeMutexFlags(flagAccessor,CODE_AT_LINE); - this->joinGameInProgress = (networkMessageIntro.getGameInProgress() != 0); - this->joinGameInProgressLaunch = false; - safeMutexFlags.ReleaseLock(); - - //printf("Client got intro playerIndex = %d\n",playerIndex); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got NetworkMessageIntro, networkMessageIntro.getGameState() = %d, versionString [%s], sessionKey = %d, playerIndex = %d, serverFTPPort = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageIntro.getGameState(),versionString.c_str(),sessionKey,playerIndex,serverFTPPort); - - //check consistency - bool compatible = checkVersionComptability(networkMessageIntro.getVersionString(), getNetworkVersionGITString()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got NetworkMessageIntro, networkMessageIntro.getGameState() = %d, versionString [%s], sessionKey = %d, playerIndex = %d, serverFTPPort = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageIntro.getGameState(),versionString.c_str(),sessionKey,playerIndex,serverFTPPort); - - if(compatible == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - bool versionMatched = false; - string platformFreeVersion = getNetworkPlatformFreeVersionString(); - string sErr = ""; - - if(strncmp(platformFreeVersion.c_str(),networkMessageIntro.getVersionString().c_str(),strlen(platformFreeVersion.c_str())) != 0) { - string playerNameStr = getHumanPlayerName(); - sErr = "Server and client binary mismatch!\nYou have to use the exactly same binaries!\n\nServer: " + networkMessageIntro.getVersionString() + - "\nClient: " + getNetworkVersionGITString() + " player [" + playerNameStr + "]"; - printf("%s\n",sErr.c_str()); - - sendTextMessage("Server and client binary mismatch!!",-1, true,""); - sendTextMessage(" Server:" + networkMessageIntro.getVersionString(),-1, true,""); - sendTextMessage(" Client: "+ getNetworkVersionGITString(),-1, true,""); - sendTextMessage(" Client player [" + playerNameStr + "]",-1, true,""); - } - else { - versionMatched = true; - string playerNameStr = getHumanPlayerName(); - sErr = "Warning, Server and client are using the same version but different platforms.\n\nServer: " + networkMessageIntro.getVersionString() + - "\nClient: " + getNetworkVersionGITString() + " player [" + playerNameStr + "]"; - //printf("%s\n",sErr.c_str()); - } - - // error message and disconnect only if checked - if(Config::getInstance().getBool("PlatformConsistencyChecks","true") && - versionMatched == false) { - - DisplayErrorMessage(sErr); - sleep(1); - - setQuit(true); - close(); - return; - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(networkMessageIntro.getGameState() == nmgstOk) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //send intro message - Lang &lang= Lang::getInstance(); - NetworkMessageIntro sendNetworkMessageIntro( - sessionKey,getNetworkVersionGITString(), - getHumanPlayerName(), - -1, - nmgstOk, - this->getSocket()->getConnectedIPAddress(), - serverFTPPort, - lang.getLanguage(), - networkMessageIntro.getGameInProgress(), - Config::getInstance().getString("PlayerId",""), - getPlatformNameString()); - sendMessage(&sendNetworkMessageIntro); - - //printf("Got intro sending client details to server\n"); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(clientSocket == NULL || - clientSocket->isConnected() == false) { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - string sErr = "Disconnected from server during intro handshake."; - DisplayErrorMessage(sErr); - setQuit(true); - close(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return; - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - introDone = true; - } - } - else if(networkMessageIntro.getGameState() == nmgstNoSlots) { - string sErr = "Cannot join the server because there are no open slots for new players."; - DisplayErrorMessage(sErr); - setQuit(true); - close(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return; - } - else { - string sErr = "Unknown response from server: " + intToStr(networkMessageIntro.getGameState()); - DisplayErrorMessage(sErr); - setQuit(true); - close(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return; - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - } - } - break; - - case nmtPing: - { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtPing\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); - - NetworkMessagePing networkMessagePing; - if(receiveMessage(&networkMessagePing)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - this->setLastPingInfo(networkMessagePing); - } - } - break; - - case nmtSynchNetworkGameData: - { - NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData; - - if(receiveMessage(&networkMessageSynchNetworkGameData)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got NetworkMessageSynchNetworkGameData, getTechCRCFileCount() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageSynchNetworkGameData.getTechCRCFileCount()); - - this->setLastPingInfoToNow(); - - networkGameDataSynchCheckOkMap = false; - networkGameDataSynchCheckOkTile = false; - networkGameDataSynchCheckOkTech = false; - this->setNetworkGameDataSynchCheckTechMismatchReport(""); - this->setReceivedDataSynchCheck(false); - - uint32 tilesetCRC = 0; - uint32 techCRC = 0; - uint32 mapCRC = 0; - vector > vctFileList; - - try { - Config &config = Config::getInstance(); - string scenarioDir = ""; - if(gameSettings.getScenarioDir() != "") { - - scenarioDir = gameSettings.getScenarioDir(); - if(EndsWith(scenarioDir, ".xml") == true) { - scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4); - scenarioDir = scenarioDir.erase(scenarioDir.size() - gameSettings.getScenario().size(), gameSettings.getScenario().size() + 1); + while (this->getQuitStatus() == false && + clientInterface != NULL) { + //printf("ClientInterfaceThread::exec Line: %d this->getQuitStatus(): %d\n",__LINE__,this->getQuitStatus()); + + // START: Test simulating lag for the client + int simulateLag = Config::getInstance().getInt("SimulateClientLag", "0"); + if (simulateLag > 0) { + if (clientSimulationLagStartTime == 0) { + clientSimulationLagStartTime = time(NULL); + } + if (difftime((long int) time(NULL), clientSimulationLagStartTime) <= Config::getInstance().getInt("SimulateClientLagDurationSeconds", "0")) { + sleep(simulateLag); + } } + // END: Test simulating lag for the client - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,gameSettings.getScenarioDir().c_str(),gameSettings.getScenario().c_str(),scenarioDir.c_str()); - } + clientInterface->updateNetworkFrame(); - // check the checksum's - tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + networkMessageSynchNetworkGameData.getTileset() + string("/*"), ".xml", NULL); + //printf("ClientInterfaceThread::exec Line: %d this->getQuitStatus(): %d\n",__LINE__,this->getQuitStatus()); - this->setNetworkGameDataSynchCheckOkTile((tilesetCRC == networkMessageSynchNetworkGameData.getTilesetCRC())); + if (debugClientInterfacePerf == true) { + loopCount++; + if (chrono.getMillis() >= 1000) { + printf("Client thread loopCount = %llu\n", (long long unsigned int)loopCount); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] tilesetCRC info, local = %d, remote = %d, networkMessageSynchNetworkGameData.getTileset() = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,tilesetCRC,networkMessageSynchNetworkGameData.getTilesetCRC(),networkMessageSynchNetworkGameData.getTileset().c_str()); - - //tech, load before map because of resources - techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,scenarioDir), string("/") + networkMessageSynchNetworkGameData.getTech() + string("/*"), ".xml", NULL); - - this->setNetworkGameDataSynchCheckOkTech((techCRC == networkMessageSynchNetworkGameData.getTechCRC())); - - if(this->getNetworkGameDataSynchCheckOkTech() == false) { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - string pathSearchString = "/" + networkMessageSynchNetworkGameData.getTech() + "/*"; - vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),pathSearchString, ".xml", NULL); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - string report = networkMessageSynchNetworkGameData.getTechCRCFileMismatchReport(vctFileList); - this->setNetworkGameDataSynchCheckTechMismatchReport(report); - - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] techCRC info, local = %d, remote = %d, networkMessageSynchNetworkGameData.getTech() = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,techCRC,networkMessageSynchNetworkGameData.getTechCRC(),networkMessageSynchNetworkGameData.getTech().c_str()); - - //map - Checksum checksum; - string file = Config::getMapPath(networkMessageSynchNetworkGameData.getMap(),scenarioDir, false); - if(file != "") { - checksum.addFile(file); - mapCRC = checksum.getSum(); - } - this->setNetworkGameDataSynchCheckOkMap((mapCRC == networkMessageSynchNetworkGameData.getMapCRC())); - this->setReceivedDataSynchCheck(true); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] mapCRC info, local = %d, remote = %d, file = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,mapCRC,networkMessageSynchNetworkGameData.getMapCRC(),file.c_str()); - } - catch(const runtime_error &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - string sErr = ex.what(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error during processing, sErr = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,sErr.c_str()); - - DisplayErrorMessage(sErr); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - NetworkMessageSynchNetworkGameDataStatus sendNetworkMessageSynchNetworkGameDataStatus(mapCRC,tilesetCRC,techCRC,vctFileList); - sendMessage(&sendNetworkMessageSynchNetworkGameDataStatus); - } - } - break; - - case nmtSynchNetworkGameDataFileCRCCheck: - { - NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck; - if(receiveMessage(&networkMessageSynchNetworkGameDataFileCRCCheck)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - this->setLastPingInfoToNow(); - - Checksum checksum; - string file = networkMessageSynchNetworkGameDataFileCRCCheck.getFileName(); - checksum.addFile(file); - uint32 fileCRC = checksum.getSum(); - - if(fileCRC != networkMessageSynchNetworkGameDataFileCRCCheck.getFileCRC()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataFileCRCCheck localCRC = %d, remoteCRC = %d, file [%s]\n", - extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,fileCRC, - networkMessageSynchNetworkGameDataFileCRCCheck.getFileCRC(), - networkMessageSynchNetworkGameDataFileCRCCheck.getFileName().c_str()); - - // Here we initiate a download of missing or mismatched content - - NetworkMessageSynchNetworkGameDataFileGet sendNetworkMessageSynchNetworkGameDataFileGet(networkMessageSynchNetworkGameDataFileCRCCheck.getFileName()); - sendMessage(&sendNetworkMessageSynchNetworkGameDataFileGet); - - FileTransferInfo fileInfo; - fileInfo.hostType = eClient; - fileInfo.serverIP = this->ip.getString(); - fileInfo.serverPort = this->port; - fileInfo.fileName = networkMessageSynchNetworkGameDataFileCRCCheck.getFileName(); - - FileTransferSocketThread *fileXferThread = new FileTransferSocketThread(fileInfo); - fileXferThread->start(); - } - - if(networkMessageSynchNetworkGameDataFileCRCCheck.getFileIndex() < networkMessageSynchNetworkGameDataFileCRCCheck.getTotalFileCount()) - { - NetworkMessageSynchNetworkGameDataFileCRCCheck sendNetworkMessageSynchNetworkGameDataFileCRCCheck( - networkMessageSynchNetworkGameDataFileCRCCheck.getTotalFileCount(), - networkMessageSynchNetworkGameDataFileCRCCheck.getFileIndex() + 1, - 0, - ""); - sendMessage(&sendNetworkMessageSynchNetworkGameDataFileCRCCheck); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - } - } - break; - - case nmtText: - { - NetworkMessageText networkMessageText; - if(receiveMessage(&networkMessageText)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - this->setLastPingInfoToNow(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtText\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); - - ChatMsgInfo msg(networkMessageText.getText().c_str(),networkMessageText.getTeamIndex(),networkMessageText.getPlayerIndex(),networkMessageText.getTargetLanguage()); - this->addChatInfo(msg); - } - } - break; - - case nmtMarkCell: - { - NetworkMessageMarkCell networkMessageMarkCell; - if(receiveMessage(&networkMessageMarkCell)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - this->setLastPingInfoToNow(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtMarkCell\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); - - MarkedCell msg(networkMessageMarkCell.getTarget(), - networkMessageMarkCell.getFactionIndex(), - networkMessageMarkCell.getText().c_str(), - networkMessageMarkCell.getPlayerIndex()); - this->addMarkedCell(msg); - } - } - break; - case nmtUnMarkCell: - { - NetworkMessageUnMarkCell networkMessageMarkCell; - if(receiveMessage(&networkMessageMarkCell)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - this->setLastPingInfoToNow(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtMarkCell\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); - - UnMarkedCell msg(networkMessageMarkCell.getTarget(), - networkMessageMarkCell.getFactionIndex()); - this->addUnMarkedCell(msg); - } - } - break; - case nmtHighlightCell: - { - NetworkMessageHighlightCell networkMessageHighlightCell; - if(receiveMessage(&networkMessageHighlightCell)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - this->setLastPingInfoToNow(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtHighlightCell\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); - - MarkedCell msg(networkMessageHighlightCell.getTarget(), - networkMessageHighlightCell.getFactionIndex(), - "none",-1); - this->setHighlightedCell(msg); - } - } - break; - - case nmtLaunch: - case nmtBroadCastSetup: - { - //printf("#1 Got new game setup playerIndex = %d!\n",playerIndex); - - NetworkMessageLaunch networkMessageLaunch; - if(receiveMessage(&networkMessageLaunch, networkMessageType)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - this->setLastPingInfoToNow(); - - if(networkMessageLaunch.getMessageType() == nmtLaunch) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got nmtLaunch\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - else if(networkMessageLaunch.getMessageType() == nmtBroadCastSetup) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got nmtBroadCastSetup\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got networkMessageLaunch.getMessageType() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType()); - - char szBuf[1024]=""; - snprintf(szBuf,1023,"In [%s::%s Line: %d] Invalid networkMessageLaunch.getMessageType() = %d",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType()); - throw megaglest_runtime_error(szBuf); - } - - networkMessageLaunch.buildGameSettings(&gameSettings); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - //printf("Client got game settings playerIndex = %d lookingfor match...\n",playerIndex); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got networkMessageLaunch.getMessageType() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType()); - //replace server player by network - for(int factionIndex = 0; factionIndex 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - } - } - break; - case nmtPlayerIndexMessage: - { - PlayerIndexMessage playerIndexMessage(-1); - if(receiveMessage(&playerIndexMessage)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - this->setLastPingInfoToNow(); - playerIndex= playerIndexMessage.getPlayerIndex(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtPlayerIndexMessage, playerIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,playerIndex); - } - - //printf("Got player index changed msg: %d\n",playerIndex); - } - break; - - case nmtReady: - { - NetworkMessageReady networkMessageReady; - if(receiveMessage(&networkMessageReady)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - this->setLastPingInfoToNow(); - MutexSafeWrapper safeMutexFlags(flagAccessor,CODE_AT_LINE); - this->readyForInGameJoin = true; - } - - //printf("ClientInterface got nmtReady this->readyForInGameJoin: %d\n",this->readyForInGameJoin); - } - break; - - case nmtCommandList: - { - - //make sure we read the message - //time_t receiveTimeElapsed = time(NULL); - NetworkMessageCommandList networkMessageCommandList; - bool gotCmd = receiveMessage(&networkMessageCommandList); - if(gotCmd == false) { - throw megaglest_runtime_error("error retrieving nmtCommandList returned false!"); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - this->setLastPingInfoToNow(); - } - break; - - case nmtQuit: - { - //time_t receiveTimeElapsed = time(NULL); - NetworkMessageQuit networkMessageQuit; - bool gotCmd = receiveMessage(&networkMessageQuit); - if(gotCmd == false) { - throw megaglest_runtime_error("error retrieving nmtQuit returned false!"); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - this->setLastPingInfoToNow(); - setQuit(true); - close(); - } - break; - - case nmtLoadingStatusMessage: - { - NetworkMessageLoadingStatus networkMessageLoadingStatus(nmls_NONE); - if(receiveMessage(&networkMessageLoadingStatus)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - this->setLastPingInfoToNow(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - } - break; - - default: - { - string sErr = string(extractFileFromDirectoryPath(__FILE__).c_str()) + "::" + string(__FUNCTION__) + " Unexpected network message: " + intToStr(networkMessageType); - //throw megaglest_runtime_error(string(extractFileFromDirectoryPath(__FILE__).c_str()) + "::" + string(__FUNCTION__) + " Unexpected network message: " + intToStr(networkMessageType)); - sendTextMessage("Unexpected network message: " + intToStr(networkMessageType),-1, true,""); - DisplayErrorMessage(sErr); - sleep(1); - - setQuit(true); - close(); - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - - if( clientSocket != NULL && clientSocket->isConnected() == true && - gotIntro == false && difftime((long int)time(NULL),connectedTime) > GameConstants::maxClientConnectHandshakeSecs) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] difftime(time(NULL),connectedTime) = %f\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,difftime((long int)time(NULL),connectedTime)); - close(); - } - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); -} - -void ClientInterface::updateNetworkFrame() { - this->updateFrame(NULL); -} - -void ClientInterface::updateFrame(int *checkFrame) { - //printf("#1 ClientInterface::updateFrame\n"); - - //printf("In updateFrame: %d\n",(checkFrame ? *checkFrame : -1)); - - if(isConnected() == true && getQuitThread() == false) { - //printf("#2 ClientInterface::updateFrame\n"); - - uint64 loopCount = 0; - Chrono chronoPerf; - if(debugClientInterfacePerf == true) { - chronoPerf.start(); - } - - int waitMicroseconds = (checkFrame == NULL ? 10 : 0); - - bool done= false; - while(done == false && getQuitThread() == false) { - //printf("BEFORE Client get networkMessageType\n"); - - - //wait for the next message - NetworkMessageType networkMessageType = waitForMessage(waitMicroseconds); - - //printf("AFTER Client got networkMessageType = %d\n",networkMessageType); - - //check we have an expected message - //NetworkMessageType networkMessageType= getNextMessageType(); - - //printf("Got Network networkMessageType: %d\n",networkMessageType); - - switch(networkMessageType) - { - case nmtCommandList: - { - - //make sure we read the message - //time_t receiveTimeElapsed = time(NULL); - NetworkMessageCommandList networkMessageCommandList; - bool gotCmd = receiveMessage(&networkMessageCommandList); - if(gotCmd == false) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] error retrieving nmtCommandList returned false!\n",__FILE__,__FUNCTION__,__LINE__); - if(isConnected() == false) { - setQuit(true); - close(); - return; + loopCount = 0; + //sleep(0); + chrono.start(); + } } - - throw megaglest_runtime_error("error retrieving nmtCommandList returned false!"); } - //printf("Client Thread getFrameCount(): %d getCommandCount(): %d\n",networkMessageCommandList.getFrameCount(),networkMessageCommandList.getCommandCount()); + if (debugClientInterfacePerf == true) { + printf("END === Client thread\n"); + } - MutexSafeWrapper safeMutex(networkCommandListThreadAccessor,CODE_AT_LINE); - cachedLastPendingFrameCount = networkMessageCommandList.getFrameCount(); - //printf("cachedLastPendingFrameCount = %lld\n",(long long int)cachedLastPendingFrameCount); + //printf("ClientInterfaceThread::exec Line: %d\n",__LINE__); - //check that we are in the right frame - if(checkFrame != NULL) { - if(networkMessageCommandList.getFrameCount() != *checkFrame) { - string sErr = "Player: " + getHumanPlayerName() + - " got a Network synchronization error, frame counts do not match, server frameCount = " + - intToStr(networkMessageCommandList.getFrameCount()) + ", local frameCount = " + - intToStr(*checkFrame); - sendTextMessage(sErr,-1, true,""); - DisplayErrorMessage(sErr); + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } + + //printf("ClientInterfaceThread::exec Line: %d\n",__LINE__); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("ClientInterfaceThread::exec Line: %d\n", __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ****************** ENDING worker thread this = %p\n", __FILE__, __FUNCTION__, __LINE__, this); + } catch (const exception &ex) { + + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (clientInterface == NULL || clientInterface->getSocket(true) == NULL || clientInterface->getSocket(true)->isConnected() == true) { + throw megaglest_runtime_error(ex.what()); + } + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] Line: %d\n", __FILE__, __FUNCTION__, __LINE__); + } + + // ===================================================== + // class ClientInterface + // ===================================================== + + ClientInterface::ClientInterface() : GameNetworkInterface() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] constructor for %p\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, this); + + networkCommandListThreadAccessor = new Mutex(CODE_AT_LINE); + networkCommandListThread = NULL; + cachedPendingCommandsIndex = 0; + cachedLastPendingFrameCount = 0; + timeClientWaitedForLastMessage = 0; + + flagAccessor = new Mutex(CODE_AT_LINE); + + clientSocket = NULL; + sessionKey = 0; + launchGame = false; + introDone = false; + + this->joinGameInProgress = false; + this->joinGameInProgressLaunch = false; + this->readyForInGameJoin = false; + this->resumeInGameJoin = false; + + quitThreadAccessor = new Mutex(CODE_AT_LINE); + setQuitThread(false); + + playerIndex = -1; + gameSettingsReceivedCount = 0; + setGameSettingsReceived(false); + gameSettingsReceivedCount = 0; + connectedTime = 0; + port = 0; + serverFTPPort = 0; + + gotIntro = false; + lastNetworkCommandListSendTime = 0; + currentFrameCount = 0; + lastSentFrameCount = 0; + clientSimulationLagStartTime = 0; + + networkGameDataSynchCheckOkMap = false; + networkGameDataSynchCheckOkTile = false; + networkGameDataSynchCheckOkTech = false; + this->setNetworkGameDataSynchCheckTechMismatchReport(""); + this->setReceivedDataSynchCheck(false); + } + + void ClientInterface::shutdownNetworkCommandListThread(MutexSafeWrapper &safeMutexWrapper) { + if (networkCommandListThread != NULL) { + //printf("START === shutdownNetworkCommandListThread\n"); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n", __FUNCTION__, __LINE__); + + setQuitThread(true); + networkCommandListThread->signalQuit(); + safeMutexWrapper.ReleaseLock(true); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n", __FUNCTION__, __LINE__); + + Chrono chronoElapsed(true); + for (; chronoElapsed.getMillis() <= 10000;) { + safeMutexWrapper.Lock(); + if (networkCommandListThread != NULL && + networkCommandListThread->canShutdown(false) == false && + networkCommandListThread->getRunningStatus() == true) { + + safeMutexWrapper.ReleaseLock(true); + if (chronoElapsed.getMillis() % 1000 == 0) { sleep(1); - - setQuit(true); - close(); - return; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n", __FUNCTION__, __LINE__); } - for(int index = 0; index < GameConstants::maxPlayers; ++index) { - printf("Frame: %d faction: %d local CRC: %u Remote CRC: %u\n",*checkFrame,index,getNetworkPlayerFactionCRC(index),networkMessageCommandList.getNetworkPlayerFactionCRC(index)); + } else { + safeMutexWrapper.ReleaseLock(true); + break; + } + //printf("%s Line: %d\n",__FUNCTION__,__LINE__); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n chronoElapsed.getMillis(): %lld", __FUNCTION__, __LINE__, (long long int)chronoElapsed.getMillis()); + //printf("A === shutdownNetworkCommandListThread\n"); + + safeMutexWrapper.Lock(); + if (networkCommandListThread != NULL && + networkCommandListThread->canShutdown(true)) { + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n", __FUNCTION__, __LINE__); + + delete networkCommandListThread; + networkCommandListThread = NULL; + } else { + networkCommandListThread = NULL; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n", __FUNCTION__, __LINE__); + //printf("END === shutdownNetworkCommandListThread\n"); + } + } + + ClientInterface::~ClientInterface() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] destructor for %p\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, this); + //printf("START === Client destructor\n"); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n", __FUNCTION__, __LINE__); + + MutexSafeWrapper safeMutex(networkCommandListThreadAccessor, CODE_AT_LINE); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n", __FUNCTION__, __LINE__); + + shutdownNetworkCommandListThread(safeMutex); + //printf("A === Client destructor\n"); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n", __FUNCTION__, __LINE__); + + if (clientSocket != NULL && + clientSocket->isConnected() == true) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n", __FUNCTION__, __LINE__); + + Lang &lang = Lang::getInstance(); + const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); + for (unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { + + string sQuitText = "has chosen to leave the game!"; + if (lang.hasString("PlayerLeftGame", languageList[langIndex]) == true) { + sQuitText = lang.getString("PlayerLeftGame", languageList[langIndex]); + } + + if (clientSocket != NULL && clientSocket->isConnected() == true) { + sendTextMessage(sQuitText, -1, false, languageList[langIndex]); + } + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n", __FUNCTION__, __LINE__); + + //printf("B === Client destructor\n"); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + close(false); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n", __FUNCTION__, __LINE__); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n", __FUNCTION__, __LINE__); + + //printf("C === Client destructor\n"); + + networkCommandListThreadAccessor = NULL; + safeMutex.ReleaseLock(false, true); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n", __FUNCTION__, __LINE__); + + delete flagAccessor; + flagAccessor = NULL; + //printf("END === Client destructor\n"); + + delete quitThreadAccessor; + quitThreadAccessor = NULL; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s Line: %d\n", __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + bool ClientInterface::getQuitThread() { + MutexSafeWrapper safeMutex(quitThreadAccessor, CODE_AT_LINE); + return this->quitThread; + } + void ClientInterface::setQuitThread(bool value) { + MutexSafeWrapper safeMutex(quitThreadAccessor, CODE_AT_LINE); + this->quitThread = value; + } + + bool ClientInterface::getQuit() { + MutexSafeWrapper safeMutex(quitThreadAccessor, CODE_AT_LINE); + return this->quit; + } + void ClientInterface::setQuit(bool value) { + MutexSafeWrapper safeMutex(quitThreadAccessor, CODE_AT_LINE); + this->quit = value; + } + + bool ClientInterface::getJoinGameInProgress() { + MutexSafeWrapper safeMutex(flagAccessor, CODE_AT_LINE); + return joinGameInProgress; + } + bool ClientInterface::getJoinGameInProgressLaunch() { + MutexSafeWrapper safeMutex(flagAccessor, CODE_AT_LINE); + return joinGameInProgressLaunch; + } + + bool ClientInterface::getReadyForInGameJoin() { + MutexSafeWrapper safeMutex(flagAccessor, CODE_AT_LINE); + return readyForInGameJoin; + } + + bool ClientInterface::getResumeInGameJoin() { + MutexSafeWrapper safeMutex(flagAccessor, CODE_AT_LINE); + return resumeInGameJoin; + } + + void ClientInterface::connect(const Ip &ip, int port) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] START\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + + this->ip = ip; + this->port = port; + + MutexSafeWrapper safeMutex(networkCommandListThreadAccessor, CODE_AT_LINE); + shutdownNetworkCommandListThread(safeMutex); + + delete clientSocket; + clientSocket = NULL; + + safeMutex.ReleaseLock(); + + clientSocket = new ClientSocket(); + clientSocket->setBlock(false); + clientSocket->connect(ip, port); + connectedTime = time(NULL); + //clientSocket->setBlock(true); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] END - socket = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, clientSocket->getSocketId()); + } + + void ClientInterface::reset() { + if (getSocket() != NULL) { + Lang &lang = Lang::getInstance(); + const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); + for (unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { + + string sQuitText = "has chosen to leave the game!"; + if (lang.hasString("PlayerLeftGame", languageList[langIndex]) == true) { + sQuitText = lang.getString("PlayerLeftGame", languageList[langIndex]); + } + sendTextMessage(sQuitText, -1, false, languageList[langIndex]); + } + close(); + } + } + + void ClientInterface::update() { + bool wasConnected = this->isConnected(); + if (gotIntro == true && + wasConnected == false) { + string playerNameStr = getHumanPlayerName(); + + Lang &lang = Lang::getInstance(); + + char szBuf1[8096] = ""; + string statusTextFormat = lang.getString("PlayerDisconnected"); + snprintf(szBuf1, 8096, statusTextFormat.c_str(), playerNameStr.c_str()); + + DisplayErrorMessage(szBuf1); + setQuit(true); + return; + } + + try { + NetworkMessageCommandList networkMessageCommandList(currentFrameCount); + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + networkMessageCommandList.setNetworkPlayerFactionCRC(index, this->getNetworkPlayerFactionCRC(index)); + } + + //send as many commands as we can + while (requestedCommands.empty() == false) { + if (networkMessageCommandList.addCommand(&requestedCommands.back())) { + requestedCommands.pop_back(); + } else { + break; + } + } + + double lastSendElapsed = difftime((long int) time(NULL), lastNetworkCommandListSendTime); + + // If we are on a frame that should send packets or we have commands + // to send now, send it now. + if ((currentFrameCount >= this->gameSettings.getNetworkFramePeriod() && + currentFrameCount % this->gameSettings.getNetworkFramePeriod() == 0) || + networkMessageCommandList.getCommandCount() > 0) { + + if (lastSentFrameCount < currentFrameCount || + networkMessageCommandList.getCommandCount() > 0) { + + lastSentFrameCount = currentFrameCount; + sendMessage(&networkMessageCommandList); + + lastNetworkCommandListSendTime = time(NULL); + lastSendElapsed = 0; + } + } + + // If we have not sent anything for maxNetworkCommandListSendTimeWait + // seconds, send one now. + if (lastNetworkCommandListSendTime > 0 && + lastSendElapsed >= ClientInterface::maxNetworkCommandListSendTimeWait) { + + lastSentFrameCount = currentFrameCount; + sendMessage(&networkMessageCommandList); + lastNetworkCommandListSendTime = time(NULL); + } + + // Possible cause of out of synch since we have more commands that need + // to be sent in this frame + if (requestedCommands.empty() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] WARNING / ERROR, requestedCommands.size() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, requestedCommands.size()); + + string sMsg = "may go out of synch: client requestedCommands.size() = " + intToStr(requestedCommands.size()); + sendTextMessage(sMsg, -1, true, ""); + sleep(1); + } + } catch (const megaglest_runtime_error &ex) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + + if (this->isConnected() == false) { + if (gotIntro == false || wasConnected == false) { + string sErr = string(extractFileFromDirectoryPath(__FILE__).c_str()) + "::" + string(__FUNCTION__) + " network error: " + string(ex.what()); + DisplayErrorMessage(sErr); + } + + setQuit(true); + } else { + throw megaglest_runtime_error(ex.what()); + } + } + } + + std::string ClientInterface::getIpAddress(bool mutexLock) { + string result = ""; + //MutexSafeWrapper safeMutexSlot((mutexLock == true ? mutexSocket : NULL),CODE_AT_LINE); + if (clientSocket != NULL) { + result = clientSocket->getIpAddress(); + } + return result; + } + + std::string ClientInterface::getServerIpAddress() { + return this->ip.getString(); + } + + void ClientInterface::updateLobby() { + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + + NetworkMessageType networkMessageType = getNextMessageType(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + switch (networkMessageType) { + case nmtInvalid: + break; + + case nmtIntro: + { + NetworkMessageIntro networkMessageIntro; + if (receiveMessage(&networkMessageIntro)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + gotIntro = true; + sessionKey = networkMessageIntro.getSessionId(); + versionString = networkMessageIntro.getVersionString(); + playerIndex = networkMessageIntro.getPlayerIndex(); + serverName = networkMessageIntro.getName(); + serverUUID = networkMessageIntro.getPlayerUUID(); + serverPlatform = networkMessageIntro.getPlayerPlatform(); + serverFTPPort = networkMessageIntro.getFtpPort(); + + if (playerIndex < 0 || playerIndex >= GameConstants::maxPlayers) { + throw megaglest_runtime_error("playerIndex < 0 || playerIndex >= GameConstants::maxPlayers"); + } + + MutexSafeWrapper safeMutexFlags(flagAccessor, CODE_AT_LINE); + this->joinGameInProgress = (networkMessageIntro.getGameInProgress() != 0); + this->joinGameInProgressLaunch = false; + safeMutexFlags.ReleaseLock(); + + //printf("Client got intro playerIndex = %d\n",playerIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got NetworkMessageIntro, networkMessageIntro.getGameState() = %d, versionString [%s], sessionKey = %d, playerIndex = %d, serverFTPPort = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageIntro.getGameState(), versionString.c_str(), sessionKey, playerIndex, serverFTPPort); + + //check consistency + bool compatible = checkVersionComptability(networkMessageIntro.getVersionString(), getNetworkVersionGITString()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got NetworkMessageIntro, networkMessageIntro.getGameState() = %d, versionString [%s], sessionKey = %d, playerIndex = %d, serverFTPPort = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageIntro.getGameState(), versionString.c_str(), sessionKey, playerIndex, serverFTPPort); + + if (compatible == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + bool versionMatched = false; + string platformFreeVersion = getNetworkPlatformFreeVersionString(); + string sErr = ""; + + if (strncmp(platformFreeVersion.c_str(), networkMessageIntro.getVersionString().c_str(), strlen(platformFreeVersion.c_str())) != 0) { + string playerNameStr = getHumanPlayerName(); + sErr = "Server and client binary mismatch!\nYou have to use the exactly same binaries!\n\nServer: " + networkMessageIntro.getVersionString() + + "\nClient: " + getNetworkVersionGITString() + " player [" + playerNameStr + "]"; + printf("%s\n", sErr.c_str()); + + sendTextMessage("Server and client binary mismatch!!", -1, true, ""); + sendTextMessage(" Server:" + networkMessageIntro.getVersionString(), -1, true, ""); + sendTextMessage(" Client: " + getNetworkVersionGITString(), -1, true, ""); + sendTextMessage(" Client player [" + playerNameStr + "]", -1, true, ""); + } else { + versionMatched = true; + string playerNameStr = getHumanPlayerName(); + sErr = "Warning, Server and client are using the same version but different platforms.\n\nServer: " + networkMessageIntro.getVersionString() + + "\nClient: " + getNetworkVersionGITString() + " player [" + playerNameStr + "]"; + //printf("%s\n",sErr.c_str()); + } + + // error message and disconnect only if checked + if (Config::getInstance().getBool("PlatformConsistencyChecks", "true") && + versionMatched == false) { - if(networkMessageCommandList.getNetworkPlayerFactionCRC(index) != getNetworkPlayerFactionCRC(index)) { - string sErr = "Player: " + getHumanPlayerName() + - " got a Network CRC error, CRC's do not match, server CRC = " + - uIntToStr(networkMessageCommandList.getNetworkPlayerFactionCRC(index)) + ", local CRC = " + - uIntToStr(getNetworkPlayerFactionCRC(index)); - sendTextMessage(sErr,-1, true,""); DisplayErrorMessage(sErr); sleep(1); @@ -1187,1132 +614,1675 @@ void ClientInterface::updateFrame(int *checkFrame) { return; } } - } - cachedPendingCommands[networkMessageCommandList.getFrameCount()].reserve(networkMessageCommandList.getCommandCount()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - // give all commands - for(int i= 0; i < networkMessageCommandList.getCommandCount(); ++i) { - //pendingCommands.push_back(*networkMessageCommandList.getCommand(i)); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - //if(networkMessageCommandList.getCommand(i)->getNetworkCommandType() == nctPauseResume) { - //printf("Network cmd type: %d [%d] frame: %d\n",networkMessageCommandList.getCommand(i)->getNetworkCommandType(),nctPauseResume,networkMessageCommandList.getFrameCount()); - //} + if (networkMessageIntro.getGameState() == nmgstOk) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - cachedPendingCommands[networkMessageCommandList.getFrameCount()].push_back(*networkMessageCommandList.getCommand(i)); + //send intro message + Lang &lang = Lang::getInstance(); + NetworkMessageIntro sendNetworkMessageIntro( + sessionKey, getNetworkVersionGITString(), + getHumanPlayerName(), + -1, + nmgstOk, + this->getSocket()->getConnectedIPAddress(), + serverFTPPort, + lang.getLanguage(), + networkMessageIntro.getGameInProgress(), + Config::getInstance().getString("PlayerId", ""), + getPlatformNameString()); + sendMessage(&sendNetworkMessageIntro); - if(cachedPendingCommandCRCs.find(networkMessageCommandList.getFrameCount()) == cachedPendingCommandCRCs.end()) { - cachedPendingCommandCRCs[networkMessageCommandList.getFrameCount()].reserve(GameConstants::maxPlayers); - for(int index = 0; index < GameConstants::maxPlayers; ++index) { - cachedPendingCommandCRCs[networkMessageCommandList.getFrameCount()].push_back(networkMessageCommandList.getNetworkPlayerFactionCRC(index)); + //printf("Got intro sending client details to server\n"); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (clientSocket == NULL || + clientSocket->isConnected() == false) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + string sErr = "Disconnected from server during intro handshake."; + DisplayErrorMessage(sErr); + setQuit(true); + close(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + return; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + introDone = true; } + } else if (networkMessageIntro.getGameState() == nmgstNoSlots) { + string sErr = "Cannot join the server because there are no open slots for new players."; + DisplayErrorMessage(sErr); + setQuit(true); + close(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + return; + } else { + string sErr = "Unknown response from server: " + intToStr(networkMessageIntro.getGameState()); + DisplayErrorMessage(sErr); + setQuit(true); + close(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + return; } + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); } - safeMutex.ReleaseLock(); - - done = true; } break; case nmtPing: { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtPing\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] got nmtPing\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); NetworkMessagePing networkMessagePing; - if(receiveMessage(&networkMessagePing)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (receiveMessage(&networkMessagePing)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); this->setLastPingInfo(networkMessagePing); } } break; - case nmtQuit: + case nmtSynchNetworkGameData: { - NetworkMessageQuit networkMessageQuit; - bool gotCmd = receiveMessage(&networkMessageQuit); - if(gotCmd == false) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] error retrieving nmtQuit returned false!\n",__FILE__,__FUNCTION__,__LINE__); - if(isConnected() == false) { - setQuit(true); - close(); - return; + NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData; + + if (receiveMessage(&networkMessageSynchNetworkGameData)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got NetworkMessageSynchNetworkGameData, getTechCRCFileCount() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageSynchNetworkGameData.getTechCRCFileCount()); + + this->setLastPingInfoToNow(); + + networkGameDataSynchCheckOkMap = false; + networkGameDataSynchCheckOkTile = false; + networkGameDataSynchCheckOkTech = false; + this->setNetworkGameDataSynchCheckTechMismatchReport(""); + this->setReceivedDataSynchCheck(false); + + uint32 tilesetCRC = 0; + uint32 techCRC = 0; + uint32 mapCRC = 0; + vector > vctFileList; + + try { + Config &config = Config::getInstance(); + string scenarioDir = ""; + if (gameSettings.getScenarioDir() != "") { + + scenarioDir = gameSettings.getScenarioDir(); + if (EndsWith(scenarioDir, ".xml") == true) { + scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4); + scenarioDir = scenarioDir.erase(scenarioDir.size() - gameSettings.getScenario().size(), gameSettings.getScenario().size() + 1); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, gameSettings.getScenarioDir().c_str(), gameSettings.getScenario().c_str(), scenarioDir.c_str()); + } + + // check the checksum's + tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets, scenarioDir), string("/") + networkMessageSynchNetworkGameData.getTileset() + string("/*"), ".xml", NULL); + + this->setNetworkGameDataSynchCheckOkTile((tilesetCRC == networkMessageSynchNetworkGameData.getTilesetCRC())); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] tilesetCRC info, local = %d, remote = %d, networkMessageSynchNetworkGameData.getTileset() = [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, tilesetCRC, networkMessageSynchNetworkGameData.getTilesetCRC(), networkMessageSynchNetworkGameData.getTileset().c_str()); + + //tech, load before map because of resources + techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs, scenarioDir), string("/") + networkMessageSynchNetworkGameData.getTech() + string("/*"), ".xml", NULL); + + this->setNetworkGameDataSynchCheckOkTech((techCRC == networkMessageSynchNetworkGameData.getTechCRC())); + + if (this->getNetworkGameDataSynchCheckOkTech() == false) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + string pathSearchString = "/" + networkMessageSynchNetworkGameData.getTech() + "/*"; + vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs, scenarioDir), pathSearchString, ".xml", NULL); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + string report = networkMessageSynchNetworkGameData.getTechCRCFileMismatchReport(vctFileList); + this->setNetworkGameDataSynchCheckTechMismatchReport(report); + + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] techCRC info, local = %d, remote = %d, networkMessageSynchNetworkGameData.getTech() = [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, techCRC, networkMessageSynchNetworkGameData.getTechCRC(), networkMessageSynchNetworkGameData.getTech().c_str()); + + //map + Checksum checksum; + string file = Config::getMapPath(networkMessageSynchNetworkGameData.getMap(), scenarioDir, false); + if (file != "") { + checksum.addFile(file); + mapCRC = checksum.getSum(); + } + this->setNetworkGameDataSynchCheckOkMap((mapCRC == networkMessageSynchNetworkGameData.getMapCRC())); + this->setReceivedDataSynchCheck(true); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] mapCRC info, local = %d, remote = %d, file = [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, mapCRC, networkMessageSynchNetworkGameData.getMapCRC(), file.c_str()); + } catch (const runtime_error &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + string sErr = ex.what(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error during processing, sErr = [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, sErr.c_str()); + + DisplayErrorMessage(sErr); } - //throw megaglest_runtime_error("error retrieving nmtQuit returned false!"); - setQuit(true); - done = true; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + NetworkMessageSynchNetworkGameDataStatus sendNetworkMessageSynchNetworkGameDataStatus(mapCRC, tilesetCRC, techCRC, vctFileList); + sendMessage(&sendNetworkMessageSynchNetworkGameDataStatus); + } + } + break; + + case nmtSynchNetworkGameDataFileCRCCheck: + { + NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck; + if (receiveMessage(&networkMessageSynchNetworkGameDataFileCRCCheck)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + this->setLastPingInfoToNow(); + + Checksum checksum; + string file = networkMessageSynchNetworkGameDataFileCRCCheck.getFileName(); + checksum.addFile(file); + uint32 fileCRC = checksum.getSum(); + + if (fileCRC != networkMessageSynchNetworkGameDataFileCRCCheck.getFileCRC()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] got nmtSynchNetworkGameDataFileCRCCheck localCRC = %d, remoteCRC = %d, file [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, fileCRC, + networkMessageSynchNetworkGameDataFileCRCCheck.getFileCRC(), + networkMessageSynchNetworkGameDataFileCRCCheck.getFileName().c_str()); + + // Here we initiate a download of missing or mismatched content + + NetworkMessageSynchNetworkGameDataFileGet sendNetworkMessageSynchNetworkGameDataFileGet(networkMessageSynchNetworkGameDataFileCRCCheck.getFileName()); + sendMessage(&sendNetworkMessageSynchNetworkGameDataFileGet); + + FileTransferInfo fileInfo; + fileInfo.hostType = eClient; + fileInfo.serverIP = this->ip.getString(); + fileInfo.serverPort = this->port; + fileInfo.fileName = networkMessageSynchNetworkGameDataFileCRCCheck.getFileName(); + + FileTransferSocketThread *fileXferThread = new FileTransferSocketThread(fileInfo); + fileXferThread->start(); + } + + if (networkMessageSynchNetworkGameDataFileCRCCheck.getFileIndex() < networkMessageSynchNetworkGameDataFileCRCCheck.getTotalFileCount()) { + NetworkMessageSynchNetworkGameDataFileCRCCheck sendNetworkMessageSynchNetworkGameDataFileCRCCheck( + networkMessageSynchNetworkGameDataFileCRCCheck.getTotalFileCount(), + networkMessageSynchNetworkGameDataFileCRCCheck.getFileIndex() + 1, + 0, + ""); + sendMessage(&sendNetworkMessageSynchNetworkGameDataFileCRCCheck); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); } - setQuit(true); - done = true; } break; case nmtText: { NetworkMessageText networkMessageText; - bool gotCmd = receiveMessage(&networkMessageText); - if(gotCmd == false) { + if (receiveMessage(&networkMessageText)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] error retrieving nmtText returned false!\n",__FILE__,__FUNCTION__,__LINE__); - if(isConnected() == false) { + this->setLastPingInfoToNow(); - setQuit(true); - close(); - return; - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] got nmtText\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); - throw megaglest_runtime_error("error retrieving nmtText returned false!"); + ChatMsgInfo msg(networkMessageText.getText().c_str(), networkMessageText.getTeamIndex(), networkMessageText.getPlayerIndex(), networkMessageText.getTargetLanguage()); + this->addChatInfo(msg); } - - ChatMsgInfo msg(networkMessageText.getText().c_str(),networkMessageText.getTeamIndex(),networkMessageText.getPlayerIndex(),networkMessageText.getTargetLanguage()); - this->addChatInfo(msg); } break; - case nmtMarkCell: - { - NetworkMessageMarkCell networkMessageMarkCell; - if(receiveMessage(&networkMessageMarkCell)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtMarkCell\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); + case nmtMarkCell: + { + NetworkMessageMarkCell networkMessageMarkCell; + if (receiveMessage(&networkMessageMarkCell)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - MarkedCell msg(networkMessageMarkCell.getTarget(), - networkMessageMarkCell.getFactionIndex(), - networkMessageMarkCell.getText().c_str(), - networkMessageMarkCell.getPlayerIndex()); - this->addMarkedCell(msg); - } - } - break; + this->setLastPingInfoToNow(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] got nmtMarkCell\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); - case nmtUnMarkCell: - { - NetworkMessageUnMarkCell networkMessageMarkCell; - if(receiveMessage(&networkMessageMarkCell)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtMarkCell\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); + MarkedCell msg(networkMessageMarkCell.getTarget(), + networkMessageMarkCell.getFactionIndex(), + networkMessageMarkCell.getText().c_str(), + networkMessageMarkCell.getPlayerIndex()); + this->addMarkedCell(msg); + } + } + break; + case nmtUnMarkCell: + { + NetworkMessageUnMarkCell networkMessageMarkCell; + if (receiveMessage(&networkMessageMarkCell)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - UnMarkedCell msg(networkMessageMarkCell.getTarget(), - networkMessageMarkCell.getFactionIndex()); - this->addUnMarkedCell(msg); - } - } - break; - case nmtHighlightCell: - { - NetworkMessageHighlightCell networkMessageHighlightCell; - if(receiveMessage(&networkMessageHighlightCell)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtHighlightCell\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); + this->setLastPingInfoToNow(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] got nmtMarkCell\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); - MarkedCell msg(networkMessageHighlightCell.getTarget(), - networkMessageHighlightCell.getFactionIndex(), - "none",-1); - this->setHighlightedCell(msg); - } - } - break; + UnMarkedCell msg(networkMessageMarkCell.getTarget(), + networkMessageMarkCell.getFactionIndex()); + this->addUnMarkedCell(msg); + } + } + break; + case nmtHighlightCell: + { + NetworkMessageHighlightCell networkMessageHighlightCell; + if (receiveMessage(&networkMessageHighlightCell)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + this->setLastPingInfoToNow(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] got nmtHighlightCell\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + + MarkedCell msg(networkMessageHighlightCell.getTarget(), + networkMessageHighlightCell.getFactionIndex(), + "none", -1); + this->setHighlightedCell(msg); + } + } + break; case nmtLaunch: case nmtBroadCastSetup: { - //printf("#2 Got new game setup playerIndex = %d!\n",playerIndex); + //printf("#1 Got new game setup playerIndex = %d!\n",playerIndex); NetworkMessageLaunch networkMessageLaunch; - if(receiveMessage(&networkMessageLaunch,networkMessageType)) { + if (receiveMessage(&networkMessageLaunch, networkMessageType)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - if(networkMessageLaunch.getMessageType() == nmtLaunch) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got nmtLaunch\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - else if(networkMessageLaunch.getMessageType() == nmtBroadCastSetup) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got nmtBroadCastSetup\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got networkMessageLaunch.getMessageType() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType()); + this->setLastPingInfoToNow(); - char szBuf[1024]=""; - snprintf(szBuf,1023,"In [%s::%s Line: %d] Invalid networkMessageLaunch.getMessageType() = %d",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType()); + if (networkMessageLaunch.getMessageType() == nmtLaunch) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Lined: %d] got nmtLaunch\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } else if (networkMessageLaunch.getMessageType() == nmtBroadCastSetup) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Lined: %d] got nmtBroadCastSetup\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Lined: %d] got networkMessageLaunch.getMessageType() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageLaunch.getMessageType()); + + char szBuf[1024] = ""; + snprintf(szBuf, 1023, "In [%s::%s Line: %d] Invalid networkMessageLaunch.getMessageType() = %d", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageLaunch.getMessageType()); throw megaglest_runtime_error(szBuf); } networkMessageLaunch.buildGameSettings(&gameSettings); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got networkMessageLaunch.getMessageType() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + //printf("Client got game settings playerIndex = %d lookingfor match...\n",playerIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Lined: %d] got networkMessageLaunch.getMessageType() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageLaunch.getMessageType()); //replace server player by network - for(int i= 0; i 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + } + } + break; + case nmtPlayerIndexMessage: + { + PlayerIndexMessage playerIndexMessage(-1); + if (receiveMessage(&playerIndexMessage)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + this->setLastPingInfoToNow(); + playerIndex = playerIndexMessage.getPlayerIndex(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got nmtPlayerIndexMessage, playerIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, playerIndex); + } + + //printf("Got player index changed msg: %d\n",playerIndex); + } + break; + + case nmtReady: + { + NetworkMessageReady networkMessageReady; + if (receiveMessage(&networkMessageReady)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + this->setLastPingInfoToNow(); + MutexSafeWrapper safeMutexFlags(flagAccessor, CODE_AT_LINE); + this->readyForInGameJoin = true; + } + + //printf("ClientInterface got nmtReady this->readyForInGameJoin: %d\n",this->readyForInGameJoin); + } + break; + + case nmtCommandList: + { + + //make sure we read the message + //time_t receiveTimeElapsed = time(NULL); + NetworkMessageCommandList networkMessageCommandList; + bool gotCmd = receiveMessage(&networkMessageCommandList); + if (gotCmd == false) { + throw megaglest_runtime_error("error retrieving nmtCommandList returned false!"); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + this->setLastPingInfoToNow(); + } + break; + + case nmtQuit: + { + //time_t receiveTimeElapsed = time(NULL); + NetworkMessageQuit networkMessageQuit; + bool gotCmd = receiveMessage(&networkMessageQuit); + if (gotCmd == false) { + throw megaglest_runtime_error("error retrieving nmtQuit returned false!"); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + this->setLastPingInfoToNow(); + setQuit(true); + close(); + } + break; + + case nmtLoadingStatusMessage: + { + NetworkMessageLoadingStatus networkMessageLoadingStatus(nmls_NONE); + if (receiveMessage(&networkMessageLoadingStatus)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + this->setLastPingInfoToNow(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); } } break; - - case nmtLoadingStatusMessage: - break; - - case nmtInvalid: - break; - default: - { - sendTextMessage("Unexpected message in client interface: " + intToStr(networkMessageType),-1, true,""); - DisplayErrorMessage(string(extractFileFromDirectoryPath(__FILE__).c_str()) + "::" + string(__FUNCTION__) + " Unexpected message in client interface: " + intToStr(networkMessageType)); + { + string sErr = string(extractFileFromDirectoryPath(__FILE__).c_str()) + "::" + string(__FUNCTION__) + " Unexpected network message: " + intToStr(networkMessageType); + //throw megaglest_runtime_error(string(extractFileFromDirectoryPath(__FILE__).c_str()) + "::" + string(__FUNCTION__) + " Unexpected network message: " + intToStr(networkMessageType)); + sendTextMessage("Unexpected network message: " + intToStr(networkMessageType), -1, true, ""); + DisplayErrorMessage(sErr); sleep(1); setQuit(true); close(); - done = true; - } - break; + } } - if(isConnected() == false && getQuit() == true) { - done = true; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + if (clientSocket != NULL && clientSocket->isConnected() == true && + gotIntro == false && difftime((long int) time(NULL), connectedTime) > GameConstants::maxClientConnectHandshakeSecs) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] difftime(time(NULL),connectedTime) = %f\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, difftime((long int) time(NULL), connectedTime)); + close(); } - if(debugClientInterfacePerf == true) { - loopCount++; - if(chronoPerf.getMillis() >= 1000) { - printf("Client updateFrame loopCount = %llu\n",(long long unsigned int)loopCount); + //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); + //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + } - loopCount = 0; - //sleep(0); + void ClientInterface::updateNetworkFrame() { + this->updateFrame(NULL); + } + + void ClientInterface::updateFrame(int *checkFrame) { + //printf("#1 ClientInterface::updateFrame\n"); + + //printf("In updateFrame: %d\n",(checkFrame ? *checkFrame : -1)); + + if (isConnected() == true && getQuitThread() == false) { + //printf("#2 ClientInterface::updateFrame\n"); + + uint64 loopCount = 0; + Chrono chronoPerf; + if (debugClientInterfacePerf == true) { chronoPerf.start(); } - } - } - if(done == true) { - MutexSafeWrapper safeMutex(networkCommandListThreadAccessor,CODE_AT_LINE); - cachedPendingCommandsIndex++; - } - } - //printf("#3 ClientInterface::updateFrame\n"); -} + int waitMicroseconds = (checkFrame == NULL ? 10 : 0); -uint64 ClientInterface::getCachedLastPendingFrameCount() { - MutexSafeWrapper safeMutex(networkCommandListThreadAccessor,CODE_AT_LINE); - uint64 result = cachedLastPendingFrameCount; - return result; -} + bool done = false; + while (done == false && getQuitThread() == false) { + //printf("BEFORE Client get networkMessageType\n"); -int64 ClientInterface::getTimeClientWaitedForLastMessage() { - MutexSafeWrapper safeMutex(networkCommandListThreadAccessor,CODE_AT_LINE); - uint64 result = timeClientWaitedForLastMessage; - return result; -} -bool ClientInterface::getNetworkCommand(int frameCount, int currentCachedPendingCommandsIndex) { - bool result = false; - bool waitForData = false; - uint64 copyCachedLastPendingFrameCount = 0; - uint64 waitCount = 0; - uint64 frameCountAsUInt64 = frameCount; - timeClientWaitedForLastMessage = 0; + //wait for the next message + NetworkMessageType networkMessageType = waitForMessage(waitMicroseconds); - //printf("In getNetworkCommand: %d [%d]\n",frameCount,currentCachedPendingCommandsIndex); + //printf("AFTER Client got networkMessageType = %d\n",networkMessageType); - if(getQuit() == false && getQuitThread() == false) { + //check we have an expected message + //NetworkMessageType networkMessageType= getNextMessageType(); - Chrono chrono; - MutexSafeWrapper safeMutex(NULL,CODE_AT_LINE); + //printf("Got Network networkMessageType: %d\n",networkMessageType); - for(;getQuit() == false && getQuitThread() == false;) { + switch (networkMessageType) { + case nmtCommandList: + { - if(safeMutex.isValidMutex() == false) { - safeMutex.setMutex(networkCommandListThreadAccessor,CODE_AT_LINE); - } - else { - safeMutex.Lock(); - } - copyCachedLastPendingFrameCount = cachedLastPendingFrameCount; + //make sure we read the message + //time_t receiveTimeElapsed = time(NULL); + NetworkMessageCommandList networkMessageCommandList; + bool gotCmd = receiveMessage(&networkMessageCommandList); + if (gotCmd == false) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] error retrieving nmtCommandList returned false!\n", __FILE__, __FUNCTION__, __LINE__); + if (isConnected() == false) { + setQuit(true); + close(); + return; + } - if(cachedPendingCommands.find(frameCount) != cachedPendingCommands.end()) { + throw megaglest_runtime_error("error retrieving nmtCommandList returned false!"); + } - Commands &frameCmdList = cachedPendingCommands[frameCount]; + //printf("Client Thread getFrameCount(): %d getCommandCount(): %d\n",networkMessageCommandList.getFrameCount(),networkMessageCommandList.getCommandCount()); - //printf("In getNetworkCommand frameCmdList.size(): %d\n",(int)frameCmdList.size()); + MutexSafeWrapper safeMutex(networkCommandListThreadAccessor, CODE_AT_LINE); + cachedLastPendingFrameCount = networkMessageCommandList.getFrameCount(); + //printf("cachedLastPendingFrameCount = %lld\n",(long long int)cachedLastPendingFrameCount); - if(frameCmdList.empty() == false) { - for(int index = 0; index < (int)frameCmdList.size(); ++index) { - pendingCommands.push_back(frameCmdList[index]); - } - cachedPendingCommands[frameCount].clear(); + //check that we are in the right frame + if (checkFrame != NULL) { + if (networkMessageCommandList.getFrameCount() != *checkFrame) { + string sErr = "Player: " + getHumanPlayerName() + + " got a Network synchronization error, frame counts do not match, server frameCount = " + + intToStr(networkMessageCommandList.getFrameCount()) + ", local frameCount = " + + intToStr(*checkFrame); + sendTextMessage(sErr, -1, true, ""); + DisplayErrorMessage(sErr); + sleep(1); - if(frameCount >= 0) { - for(int index = 0; index < GameConstants::maxPlayers; ++index) { - //printf("X**X Frame: %d faction: %d local CRC: %u Remote CRC: %u\n",frameCount,index,getNetworkPlayerFactionCRC(index),cachedPendingCommandCRCs[frameCount][index]); + setQuit(true); + close(); + return; + } + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + printf("Frame: %d faction: %d local CRC: %u Remote CRC: %u\n", *checkFrame, index, getNetworkPlayerFactionCRC(index), networkMessageCommandList.getNetworkPlayerFactionCRC(index)); - if(cachedPendingCommandCRCs[frameCount][index] != getNetworkPlayerFactionCRC(index)) { + if (networkMessageCommandList.getNetworkPlayerFactionCRC(index) != getNetworkPlayerFactionCRC(index)) { + string sErr = "Player: " + getHumanPlayerName() + + " got a Network CRC error, CRC's do not match, server CRC = " + + uIntToStr(networkMessageCommandList.getNetworkPlayerFactionCRC(index)) + ", local CRC = " + + uIntToStr(getNetworkPlayerFactionCRC(index)); + sendTextMessage(sErr, -1, true, ""); + DisplayErrorMessage(sErr); + sleep(1); - printf("X**X Frame: %d faction: %d local CRC: %u Remote CRC: %u\n",frameCount,index,getNetworkPlayerFactionCRC(index),cachedPendingCommandCRCs[frameCount][index]); + setQuit(true); + close(); + return; + } + } + } - string sErr = "Player: " + getHumanPlayerName() + - " got a Network CRC error, CRC's do not match, server CRC = " + - uIntToStr(cachedPendingCommandCRCs[frameCount][index]) + ", local CRC = " + - uIntToStr(getNetworkPlayerFactionCRC(index)); - sendTextMessage(sErr,-1, true,""); - DisplayErrorMessage(sErr); - sleep(1); + cachedPendingCommands[networkMessageCommandList.getFrameCount()].reserve(networkMessageCommandList.getCommandCount()); - setQuit(true); - close(); + // give all commands + for (int i = 0; i < networkMessageCommandList.getCommandCount(); ++i) { + //pendingCommands.push_back(*networkMessageCommandList.getCommand(i)); + + //if(networkMessageCommandList.getCommand(i)->getNetworkCommandType() == nctPauseResume) { + //printf("Network cmd type: %d [%d] frame: %d\n",networkMessageCommandList.getCommand(i)->getNetworkCommandType(),nctPauseResume,networkMessageCommandList.getFrameCount()); + //} + + cachedPendingCommands[networkMessageCommandList.getFrameCount()].push_back(*networkMessageCommandList.getCommand(i)); + + if (cachedPendingCommandCRCs.find(networkMessageCommandList.getFrameCount()) == cachedPendingCommandCRCs.end()) { + cachedPendingCommandCRCs[networkMessageCommandList.getFrameCount()].reserve(GameConstants::maxPlayers); + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + cachedPendingCommandCRCs[networkMessageCommandList.getFrameCount()].push_back(networkMessageCommandList.getNetworkPlayerFactionCRC(index)); + } + } + } + safeMutex.ReleaseLock(); + + done = true; + } + break; + + case nmtPing: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] got nmtPing\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + + NetworkMessagePing networkMessagePing; + if (receiveMessage(&networkMessagePing)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + this->setLastPingInfo(networkMessagePing); } } + break; + + case nmtQuit: + { + NetworkMessageQuit networkMessageQuit; + bool gotCmd = receiveMessage(&networkMessageQuit); + if (gotCmd == false) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] error retrieving nmtQuit returned false!\n", __FILE__, __FUNCTION__, __LINE__); + if (isConnected() == false) { + setQuit(true); + close(); + return; + } + + //throw megaglest_runtime_error("error retrieving nmtQuit returned false!"); + setQuit(true); + done = true; + } + setQuit(true); + done = true; + } + break; + + case nmtText: + { + NetworkMessageText networkMessageText; + bool gotCmd = receiveMessage(&networkMessageText); + if (gotCmd == false) { + + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] error retrieving nmtText returned false!\n", __FILE__, __FUNCTION__, __LINE__); + if (isConnected() == false) { + + setQuit(true); + close(); + return; + } + + throw megaglest_runtime_error("error retrieving nmtText returned false!"); + } + + ChatMsgInfo msg(networkMessageText.getText().c_str(), networkMessageText.getTeamIndex(), networkMessageText.getPlayerIndex(), networkMessageText.getTargetLanguage()); + this->addChatInfo(msg); + } + break; + + case nmtMarkCell: + { + NetworkMessageMarkCell networkMessageMarkCell; + if (receiveMessage(&networkMessageMarkCell)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] got nmtMarkCell\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + + MarkedCell msg(networkMessageMarkCell.getTarget(), + networkMessageMarkCell.getFactionIndex(), + networkMessageMarkCell.getText().c_str(), + networkMessageMarkCell.getPlayerIndex()); + this->addMarkedCell(msg); + } + } + break; + + case nmtUnMarkCell: + { + NetworkMessageUnMarkCell networkMessageMarkCell; + if (receiveMessage(&networkMessageMarkCell)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] got nmtMarkCell\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + + UnMarkedCell msg(networkMessageMarkCell.getTarget(), + networkMessageMarkCell.getFactionIndex()); + this->addUnMarkedCell(msg); + } + } + break; + case nmtHighlightCell: + { + NetworkMessageHighlightCell networkMessageHighlightCell; + if (receiveMessage(&networkMessageHighlightCell)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] got nmtHighlightCell\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + + MarkedCell msg(networkMessageHighlightCell.getTarget(), + networkMessageHighlightCell.getFactionIndex(), + "none", -1); + this->setHighlightedCell(msg); + } + } + break; + + + case nmtLaunch: + case nmtBroadCastSetup: + { + //printf("#2 Got new game setup playerIndex = %d!\n",playerIndex); + + NetworkMessageLaunch networkMessageLaunch; + if (receiveMessage(&networkMessageLaunch, networkMessageType)) { + + if (networkMessageLaunch.getMessageType() == nmtLaunch) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Lined: %d] got nmtLaunch\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } else if (networkMessageLaunch.getMessageType() == nmtBroadCastSetup) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Lined: %d] got nmtBroadCastSetup\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Lined: %d] got networkMessageLaunch.getMessageType() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageLaunch.getMessageType()); + + char szBuf[1024] = ""; + snprintf(szBuf, 1023, "In [%s::%s Line: %d] Invalid networkMessageLaunch.getMessageType() = %d", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageLaunch.getMessageType()); + throw megaglest_runtime_error(szBuf); + } + + networkMessageLaunch.buildGameSettings(&gameSettings); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Lined: %d] got networkMessageLaunch.getMessageType() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageLaunch.getMessageType()); + //replace server player by network + for (int i = 0; i < gameSettings.getFactionCount(); ++i) { + //replace by network + if (gameSettings.getFactionControl(i) == ctHuman) { + gameSettings.setFactionControl(i, ctNetwork); + } + + //printf("i = %d gameSettings.getStartLocationIndex(i) = %d playerIndex = %d!\n",i,gameSettings.getStartLocationIndex(i),playerIndex); + + //set the faction index + if (gameSettings.getStartLocationIndex(i) == playerIndex) { + //printf("Setting my factionindex to: %d for playerIndex: %d\n",i,playerIndex); + + gameSettings.setThisFactionIndex(i); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] gameSettings.getThisFactionIndex(i) = %d, playerIndex = %d, i = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, gameSettings.getThisFactionIndex(), playerIndex, i); + } + } + } + } + break; + + + case nmtLoadingStatusMessage: + break; + + case nmtInvalid: + break; + + default: + { + sendTextMessage("Unexpected message in client interface: " + intToStr(networkMessageType), -1, true, ""); + DisplayErrorMessage(string(extractFileFromDirectoryPath(__FILE__).c_str()) + "::" + string(__FUNCTION__) + " Unexpected message in client interface: " + intToStr(networkMessageType)); + sleep(1); + + setQuit(true); + close(); + done = true; + } + break; } - cachedPendingCommandCRCs.erase(frameCount); - } - if(waitForData == true) { - timeClientWaitedForLastMessage = chrono.getMillis(); - chrono.stop(); - } - safeMutex.ReleaseLock(true); - result = true; - break; + if (isConnected() == false && getQuit() == true) { + done = true; + } + + if (debugClientInterfacePerf == true) { + loopCount++; + if (chronoPerf.getMillis() >= 1000) { + printf("Client updateFrame loopCount = %llu\n", (long long unsigned int)loopCount); + + loopCount = 0; + //sleep(0); + chronoPerf.start(); + } + } + } + + if (done == true) { + MutexSafeWrapper safeMutex(networkCommandListThreadAccessor, CODE_AT_LINE); + cachedPendingCommandsIndex++; + } } - else { - safeMutex.ReleaseLock(true); - // No data for this frame - if(waitForData == false) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Client waiting for packet for frame: %d, copyCachedLastPendingFrameCount = %lld\n",frameCount,(long long int)copyCachedLastPendingFrameCount); - chrono.start(); - } - if(copyCachedLastPendingFrameCount > frameCountAsUInt64) { - break; - } + //printf("#3 ClientInterface::updateFrame\n"); + } + + uint64 ClientInterface::getCachedLastPendingFrameCount() { + MutexSafeWrapper safeMutex(networkCommandListThreadAccessor, CODE_AT_LINE); + uint64 result = cachedLastPendingFrameCount; + return result; + } + + int64 ClientInterface::getTimeClientWaitedForLastMessage() { + MutexSafeWrapper safeMutex(networkCommandListThreadAccessor, CODE_AT_LINE); + uint64 result = timeClientWaitedForLastMessage; + return result; + } + + bool ClientInterface::getNetworkCommand(int frameCount, int currentCachedPendingCommandsIndex) { + bool result = false; + bool waitForData = false; + uint64 copyCachedLastPendingFrameCount = 0; + uint64 waitCount = 0; + uint64 frameCountAsUInt64 = frameCount; + timeClientWaitedForLastMessage = 0; + + //printf("In getNetworkCommand: %d [%d]\n",frameCount,currentCachedPendingCommandsIndex); + + if (getQuit() == false && getQuitThread() == false) { + + Chrono chrono; + MutexSafeWrapper safeMutex(NULL, CODE_AT_LINE); + + for (; getQuit() == false && getQuitThread() == false;) { + + if (safeMutex.isValidMutex() == false) { + safeMutex.setMutex(networkCommandListThreadAccessor, CODE_AT_LINE); + } else { + safeMutex.Lock(); + } + copyCachedLastPendingFrameCount = cachedLastPendingFrameCount; + + if (cachedPendingCommands.find(frameCount) != cachedPendingCommands.end()) { + + Commands &frameCmdList = cachedPendingCommands[frameCount]; + + //printf("In getNetworkCommand frameCmdList.size(): %d\n",(int)frameCmdList.size()); + + if (frameCmdList.empty() == false) { + for (int index = 0; index < (int) frameCmdList.size(); ++index) { + pendingCommands.push_back(frameCmdList[index]); + } + cachedPendingCommands[frameCount].clear(); + + if (frameCount >= 0) { + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + //printf("X**X Frame: %d faction: %d local CRC: %u Remote CRC: %u\n",frameCount,index,getNetworkPlayerFactionCRC(index),cachedPendingCommandCRCs[frameCount][index]); + + if (cachedPendingCommandCRCs[frameCount][index] != getNetworkPlayerFactionCRC(index)) { + + printf("X**X Frame: %d faction: %d local CRC: %u Remote CRC: %u\n", frameCount, index, getNetworkPlayerFactionCRC(index), cachedPendingCommandCRCs[frameCount][index]); + + string sErr = "Player: " + getHumanPlayerName() + + " got a Network CRC error, CRC's do not match, server CRC = " + + uIntToStr(cachedPendingCommandCRCs[frameCount][index]) + ", local CRC = " + + uIntToStr(getNetworkPlayerFactionCRC(index)); + sendTextMessage(sErr, -1, true, ""); + DisplayErrorMessage(sErr); + sleep(1); + + setQuit(true); + close(); + } + } + } + cachedPendingCommandCRCs.erase(frameCount); + } + if (waitForData == true) { + timeClientWaitedForLastMessage = chrono.getMillis(); + chrono.stop(); + } + safeMutex.ReleaseLock(true); + + result = true; + break; + } else { + safeMutex.ReleaseLock(true); + // No data for this frame + if (waitForData == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Client waiting for packet for frame: %d, copyCachedLastPendingFrameCount = %lld\n", frameCount, (long long int)copyCachedLastPendingFrameCount); + chrono.start(); + } + if (copyCachedLastPendingFrameCount > frameCountAsUInt64) { + break; + } + + if (waitForData == false) { + waitForData = true; + sleep(0); + } + + waitCount++; + //printf("Client waiting for packet for frame: %d, currentCachedPendingCommandsIndex = %d, cachedPendingCommandsIndex = %lld\n",frameCount,currentCachedPendingCommandsIndex,(long long int)cachedPendingCommandsIndex); + } + } + } + if (waitForData == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Client waiting for packet FINISHED for frame: %d, copyCachedLastPendingFrameCount = %lld waitCount = %llu\n", frameCount, (long long int)copyCachedLastPendingFrameCount, (long long unsigned int)waitCount); + } + + return result; + } + + void ClientInterface::updateKeyframe(int frameCount) { + currentFrameCount = frameCount; + + //printf("In updateKeyFrame: %d\n",currentFrameCount); + + if (getQuit() == false && getQuitThread() == false) { + if (networkCommandListThread == NULL) { + static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); + networkCommandListThread = new ClientInterfaceThread(this); + networkCommandListThread->setUniqueID(mutexOwnerId); + networkCommandListThread->start(); - if(waitForData == false) { - waitForData = true; sleep(0); } - waitCount++; - //printf("Client waiting for packet for frame: %d, currentCachedPendingCommandsIndex = %d, cachedPendingCommandsIndex = %lld\n",frameCount,currentCachedPendingCommandsIndex,(long long int)cachedPendingCommandsIndex); + getNetworkCommand(frameCount, cachedPendingCommandsIndex); } } - } - if(waitForData == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Client waiting for packet FINISHED for frame: %d, copyCachedLastPendingFrameCount = %lld waitCount = %llu\n",frameCount,(long long int)copyCachedLastPendingFrameCount,(long long unsigned int)waitCount); - } - return result; -} - -void ClientInterface::updateKeyframe(int frameCount) { - currentFrameCount = frameCount; - - //printf("In updateKeyFrame: %d\n",currentFrameCount); - - if(getQuit() == false && getQuitThread() == false) { - if(networkCommandListThread == NULL) { - static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); - networkCommandListThread = new ClientInterfaceThread(this); - networkCommandListThread->setUniqueID(mutexOwnerId); - networkCommandListThread->start(); - - sleep(0); + bool ClientInterface::isMasterServerAdminOverride() { + return (gameSettings.getMasterserver_admin() == this->getSessionKey()); } - getNetworkCommand(frameCount,cachedPendingCommandsIndex); - } -} + void ClientInterface::waitUntilReady(Checksum* checksum) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); -bool ClientInterface::isMasterServerAdminOverride() { - return (gameSettings.getMasterserver_admin() == this->getSessionKey()); -} + MutexSafeWrapper safeMutexFlags(flagAccessor, CODE_AT_LINE); + bool signalServerWhenReadyToStartJoinedGame = this->readyForInGameJoin; + this->readyForInGameJoin = false; + safeMutexFlags.ReleaseLock(); -void ClientInterface::waitUntilReady(Checksum* checksum) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + Logger &logger = Logger::getInstance(); - MutexSafeWrapper safeMutexFlags(flagAccessor,CODE_AT_LINE); - bool signalServerWhenReadyToStartJoinedGame = this->readyForInGameJoin; - this->readyForInGameJoin = false; - safeMutexFlags.ReleaseLock(); + Chrono chrono; + chrono.start(); - Logger &logger= Logger::getInstance(); + // FOR TESTING ONLY - delay to see the client count up while waiting + //sleep(5000); - Chrono chrono; - chrono.start(); + //clientSocket->setBlock(true); + //send ready message + NetworkMessageReady networkMessageReady; + sendMessage(&networkMessageReady); - // FOR TESTING ONLY - delay to see the client count up while waiting - //sleep(5000); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - //clientSocket->setBlock(true); - //send ready message - NetworkMessageReady networkMessageReady; - sendMessage(&networkMessageReady); + NetworkMessageLoadingStatus networkMessageLoadingStatus(nmls_NONE); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + Lang &lang = Lang::getInstance(); - NetworkMessageLoadingStatus networkMessageLoadingStatus(nmls_NONE); + int64 lastMillisCheck = 0; + uint64 waitLoopIterationCount = 0; + uint64 MAX_LOOP_COUNT_BEFORE_SLEEP = 100; + MAX_LOOP_COUNT_BEFORE_SLEEP = Config::getInstance().getInt("NetworkClientLoopGameLoadingCap", intToStr(MAX_LOOP_COUNT_BEFORE_SLEEP).c_str()); + if (MAX_LOOP_COUNT_BEFORE_SLEEP == 0) { + MAX_LOOP_COUNT_BEFORE_SLEEP = 1; + } + int sleepMillis = Config::getInstance().getInt("NetworkClientLoopGameLoadingCapSleepMillis", "10"); - Lang &lang= Lang::getInstance(); + //wait until we get a ready message from the server + while (true) { + // FOR TESTING ONLY - delay to see the client count up while waiting + //sleep(2000); - int64 lastMillisCheck = 0; - uint64 waitLoopIterationCount = 0; - uint64 MAX_LOOP_COUNT_BEFORE_SLEEP = 100; - MAX_LOOP_COUNT_BEFORE_SLEEP = Config::getInstance().getInt("NetworkClientLoopGameLoadingCap",intToStr(MAX_LOOP_COUNT_BEFORE_SLEEP).c_str()); - if(MAX_LOOP_COUNT_BEFORE_SLEEP == 0) { - MAX_LOOP_COUNT_BEFORE_SLEEP = 1; - } - int sleepMillis = Config::getInstance().getInt("NetworkClientLoopGameLoadingCapSleepMillis","10"); - - //wait until we get a ready message from the server - while(true) { - // FOR TESTING ONLY - delay to see the client count up while waiting - //sleep(2000); - - waitLoopIterationCount++; - if(waitLoopIterationCount > 0 && - waitLoopIterationCount % MAX_LOOP_COUNT_BEFORE_SLEEP == 0) { - sleep(sleepMillis); - waitLoopIterationCount = 0; - } - - if(isConnected() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - string sErr = "Error, Server has disconnected!"; - DisplayErrorMessage(sErr); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - setQuit(true); - close(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return; - } - NetworkMessageType networkMessageType = getNextMessageType(); - - // consume old messages from the lobby - bool discarded = shouldDiscardNetworkMessage(networkMessageType); - if(discarded == false) { - if(networkMessageType == nmtReady) { - if(receiveMessage(&networkMessageReady)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - break; + waitLoopIterationCount++; + if (waitLoopIterationCount > 0 && + waitLoopIterationCount % MAX_LOOP_COUNT_BEFORE_SLEEP == 0) { + sleep(sleepMillis); + waitLoopIterationCount = 0; } - } - else if(networkMessageType == nmtLoadingStatusMessage) { - if(receiveMessage(&networkMessageLoadingStatus)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - } - else if(networkMessageType == nmtQuit) { - NetworkMessageQuit networkMessageQuit; - if(receiveMessage(&networkMessageQuit)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - DisplayErrorMessage(lang.getString("GameCancelledByUser")); + if (isConnected() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + string sErr = "Error, Server has disconnected!"; + DisplayErrorMessage(sErr); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); setQuit(true); close(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); return; + } + NetworkMessageType networkMessageType = getNextMessageType(); + // consume old messages from the lobby + bool discarded = shouldDiscardNetworkMessage(networkMessageType); + if (discarded == false) { + if (networkMessageType == nmtReady) { + if (receiveMessage(&networkMessageReady)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + break; + } + } else if (networkMessageType == nmtLoadingStatusMessage) { + if (receiveMessage(&networkMessageLoadingStatus)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + } else if (networkMessageType == nmtQuit) { + NetworkMessageQuit networkMessageQuit; + if (receiveMessage(&networkMessageQuit)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + DisplayErrorMessage(lang.getString("GameCancelledByUser")); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + setQuit(true); + close(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + return; + + } + } else if (networkMessageType == nmtCommandList) { + //make sure we read the message + NetworkMessageCommandList networkMessageCommandList; + bool gotCmd = receiveMessage(&networkMessageCommandList); + if (gotCmd == false) { + throw megaglest_runtime_error("error retrieving nmtCommandList returned false!"); + } + } else if (networkMessageType == nmtInvalid) { + if (chrono.getMillis() > readyWaitTimeout) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + Lang &lang = Lang::getInstance(); + const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); + for (unsigned int i = 0; i < languageList.size(); ++i) { + string sErr = "Timeout waiting for server"; + if (lang.hasString("TimeoutWaitingForServer", languageList[i]) == true) { + sErr = lang.getString("TimeoutWaitingForServer", languageList[i]); + } + bool echoLocal = lang.isLanguageLocal(lang.getLanguage()); + sendTextMessage(sErr, -1, echoLocal, languageList[i]); + + if (echoLocal) { + DisplayErrorMessage(sErr); + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + sleep(1); + setQuit(true); + close(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + return; + } else { + if (chrono.getMillis() % 100 == 0) { + lastMillisCheck = (chrono.getMillis() / 1000); + + char szBuf[8096] = ""; + string updateTextFormat = "Waiting for network: %lld seconds elapsed (maximum wait time: %d seconds)"; + if (lang.hasString("NetworkGameClientLoadStatus") == true) { + updateTextFormat = lang.getString("NetworkGameClientLoadStatus"); + } + + string waitForHosts = ""; + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER1_CONNECTED) == nmls_PLAYER1_CONNECTED) { + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER1_READY) != nmls_PLAYER1_READY) { + if (waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(0); + } + } + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER2_CONNECTED) == nmls_PLAYER2_CONNECTED) { + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER2_READY) != nmls_PLAYER2_READY) { + if (waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(1); + } + } + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER3_CONNECTED) == nmls_PLAYER3_CONNECTED) { + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER3_READY) != nmls_PLAYER3_READY) { + if (waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(2); + } + } + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER4_CONNECTED) == nmls_PLAYER4_CONNECTED) { + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER4_READY) != nmls_PLAYER4_READY) { + if (waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(3); + } + } + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER5_CONNECTED) == nmls_PLAYER5_CONNECTED) { + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER5_READY) != nmls_PLAYER5_READY) { + if (waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(4); + } + } + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER6_CONNECTED) == nmls_PLAYER6_CONNECTED) { + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER6_READY) != nmls_PLAYER6_READY) { + if (waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(5); + } + } + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER7_CONNECTED) == nmls_PLAYER7_CONNECTED) { + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER7_READY) != nmls_PLAYER7_READY) { + if (waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(6); + } + } + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER8_CONNECTED) == nmls_PLAYER8_CONNECTED) { + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER8_READY) != nmls_PLAYER8_READY) { + if (waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(7); + } + } + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER9_CONNECTED) == nmls_PLAYER9_CONNECTED) { + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER9_READY) != nmls_PLAYER9_READY) { + if (waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(7); + } + } + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER10_CONNECTED) == nmls_PLAYER10_CONNECTED) { + if ((networkMessageLoadingStatus.getStatus() & nmls_PLAYER10_READY) != nmls_PLAYER10_READY) { + if (waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(7); + } + } + + if (waitForHosts == "") { + waitForHosts = lang.getString("Server"); + } + snprintf(szBuf, 8096, updateTextFormat.c_str(), (long long int)lastMillisCheck, int(readyWaitTimeout / 1000)); + + char szBuf1[8096] = ""; + string statusTextFormat = "Waiting for players: %s"; + if (lang.hasString("NetworkGameStatusWaiting") == true) { + statusTextFormat = lang.getString("NetworkGameStatusWaiting"); + } + snprintf(szBuf1, 8096, statusTextFormat.c_str(), waitForHosts.c_str()); + + logger.add(szBuf, true, szBuf1); + + sleep(0); + } + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + sendTextMessage("Unexpected network message: " + intToStr(networkMessageType), -1, true, ""); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + DisplayErrorMessage(string(extractFileFromDirectoryPath(__FILE__).c_str()) + "::" + string(__FUNCTION__) + " Unexpected network message: " + intToStr(networkMessageType)); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + sleep(1); + setQuit(true); + close(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + return; + } + + Shared::Platform::Window::handleEvent(); + // sleep a bit + sleep(waitSleepTime); } } - else if(networkMessageType == nmtCommandList) { - //make sure we read the message - NetworkMessageCommandList networkMessageCommandList; - bool gotCmd = receiveMessage(&networkMessageCommandList); - if(gotCmd == false) { - throw megaglest_runtime_error("error retrieving nmtCommandList returned false!"); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + //check checksum + if (getJoinGameInProgress() == false && + networkMessageReady.getChecksum() != checksum->getSum()) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + Lang &lang = Lang::getInstance(); + const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); + for (unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { + + string sErr = "Checksum error, you don't have the same data as the server"; + if (lang.hasString("CheckSumGameLoadError", languageList[langIndex]) == true) { + sErr = lang.getString("CheckSumGameLoadError", languageList[langIndex]); + } + bool echoLocal = lang.isLanguageLocal(lang.getLanguage()); + sendTextMessage(sErr, -1, echoLocal, languageList[langIndex]); + + string playerNameStr = "Player with error is: " + getHumanPlayerName(); + if (lang.hasString("CheckSumGameLoadPlayer", languageList[langIndex]) == true) { + playerNameStr = lang.getString("CheckSumGameLoadPlayer", languageList[langIndex]) + " " + getHumanPlayerName(); + } + sendTextMessage(playerNameStr, -1, echoLocal, languageList[langIndex]); + + string sErr1 = "Client Checksum: " + intToStr(checksum->getSum()); + if (lang.hasString("CheckSumGameLoadClient", languageList[langIndex]) == true) { + sErr1 = lang.getString("CheckSumGameLoadClient", languageList[langIndex]) + " " + intToStr(checksum->getSum()); + } + + sendTextMessage(sErr1, -1, echoLocal, languageList[langIndex]); + + string sErr2 = "Server Checksum: " + intToStr(networkMessageReady.getChecksum()); + if (lang.hasString("CheckSumGameLoadServer", languageList[langIndex]) == true) { + sErr2 = lang.getString("CheckSumGameLoadServer", languageList[langIndex]) + " " + intToStr(networkMessageReady.getChecksum()); + } + sendTextMessage(sErr2, -1, echoLocal, languageList[langIndex]); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d %s %s %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, sErr.c_str(), sErr1.c_str(), sErr2.c_str()); + + if (echoLocal == true) { + if (Config::getInstance().getBool("NetworkConsistencyChecks")) { + // error message and disconnect only if checked + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + string niceError = sErr + string("\n") + sErr1 + string("\n") + sErr2; + DisplayErrorMessage(niceError); + } + } } - } - else if(networkMessageType == nmtInvalid) { - if(chrono.getMillis() > readyWaitTimeout) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - Lang &lang= Lang::getInstance(); - const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); - for(unsigned int i = 0; i < languageList.size(); ++i) { - string sErr = "Timeout waiting for server"; - if(lang.hasString("TimeoutWaitingForServer",languageList[i]) == true) { - sErr = lang.getString("TimeoutWaitingForServer",languageList[i]); - } - bool echoLocal = lang.isLanguageLocal(lang.getLanguage()); - sendTextMessage(sErr,-1,echoLocal,languageList[i]); - - if(echoLocal) { - DisplayErrorMessage(sErr); - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (Config::getInstance().getBool("NetworkConsistencyChecks")) { + // error message and disconnect only if checked + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); sleep(1); setQuit(true); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + close(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return; } - else { - if(chrono.getMillis() % 100 == 0) { - lastMillisCheck = (chrono.getMillis() / 1000); - - char szBuf[8096]=""; - string updateTextFormat = "Waiting for network: %lld seconds elapsed (maximum wait time: %d seconds)"; - if(lang.hasString("NetworkGameClientLoadStatus") == true) { - updateTextFormat = lang.getString("NetworkGameClientLoadStatus"); - } - - string waitForHosts = ""; - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER1_CONNECTED) == nmls_PLAYER1_CONNECTED) { - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER1_READY) != nmls_PLAYER1_READY) { - if(waitForHosts != "") { - waitForHosts += ", "; - } - waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(0); - } - } - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER2_CONNECTED) == nmls_PLAYER2_CONNECTED) { - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER2_READY) != nmls_PLAYER2_READY) { - if(waitForHosts != "") { - waitForHosts += ", "; - } - waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(1); - } - } - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER3_CONNECTED) == nmls_PLAYER3_CONNECTED) { - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER3_READY) != nmls_PLAYER3_READY) { - if(waitForHosts != "") { - waitForHosts += ", "; - } - waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(2); - } - } - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER4_CONNECTED) == nmls_PLAYER4_CONNECTED) { - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER4_READY) != nmls_PLAYER4_READY) { - if(waitForHosts != "") { - waitForHosts += ", "; - } - waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(3); - } - } - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER5_CONNECTED) == nmls_PLAYER5_CONNECTED) { - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER5_READY) != nmls_PLAYER5_READY) { - if(waitForHosts != "") { - waitForHosts += ", "; - } - waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(4); - } - } - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER6_CONNECTED) == nmls_PLAYER6_CONNECTED) { - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER6_READY) != nmls_PLAYER6_READY) { - if(waitForHosts != "") { - waitForHosts += ", "; - } - waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(5); - } - } - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER7_CONNECTED) == nmls_PLAYER7_CONNECTED) { - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER7_READY) != nmls_PLAYER7_READY) { - if(waitForHosts != "") { - waitForHosts += ", "; - } - waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(6); - } - } - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER8_CONNECTED) == nmls_PLAYER8_CONNECTED) { - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER8_READY) != nmls_PLAYER8_READY) { - if(waitForHosts != "") { - waitForHosts += ", "; - } - waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(7); - } - } - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER9_CONNECTED) == nmls_PLAYER9_CONNECTED) { - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER9_READY) != nmls_PLAYER9_READY) { - if(waitForHosts != "") { - waitForHosts += ", "; - } - waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(7); - } - } - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER10_CONNECTED) == nmls_PLAYER10_CONNECTED) { - if((networkMessageLoadingStatus.getStatus() & nmls_PLAYER10_READY) != nmls_PLAYER10_READY) { - if(waitForHosts != "") { - waitForHosts += ", "; - } - waitForHosts += gameSettings.getNetworkPlayerNameByPlayerIndex(7); - } - } - - if(waitForHosts == "") { - waitForHosts = lang.getString("Server"); - } - snprintf(szBuf,8096,updateTextFormat.c_str(),(long long int)lastMillisCheck,int(readyWaitTimeout / 1000)); - - char szBuf1[8096]=""; - string statusTextFormat = "Waiting for players: %s"; - if(lang.hasString("NetworkGameStatusWaiting") == true) { - statusTextFormat = lang.getString("NetworkGameStatusWaiting"); - } - snprintf(szBuf1,8096,statusTextFormat.c_str(),waitForHosts.c_str()); - - logger.add(szBuf, true, szBuf1); - - sleep(0); - } - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - sendTextMessage("Unexpected network message: " + intToStr(networkMessageType),-1, true,""); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - DisplayErrorMessage(string(extractFileFromDirectoryPath(__FILE__).c_str()) + "::" + string(__FUNCTION__) + " Unexpected network message: " + intToStr(networkMessageType)); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - sleep(1); - setQuit(true); - close(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); return; } - Shared::Platform::Window::handleEvent(); - // sleep a bit - sleep(waitSleepTime); - } - } + MutexSafeWrapper safeMutexFlags2(flagAccessor, CODE_AT_LINE); + this->joinGameInProgress = false; + this->joinGameInProgressLaunch = false; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + //printf("Client signalServerWhenReadyToStartJoinedGame = %d\n",signalServerWhenReadyToStartJoinedGame); + if (signalServerWhenReadyToStartJoinedGame == true) { - //check checksum - if(getJoinGameInProgress() == false && - networkMessageReady.getChecksum() != checksum->getSum()) { + Lang &lang = Lang::getInstance(); + const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); + for (unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - Lang &lang= Lang::getInstance(); - const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); - for(unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { - - string sErr = "Checksum error, you don't have the same data as the server"; - if(lang.hasString("CheckSumGameLoadError",languageList[langIndex]) == true) { - sErr = lang.getString("CheckSumGameLoadError",languageList[langIndex]); - } - bool echoLocal = lang.isLanguageLocal(lang.getLanguage()); - sendTextMessage(sErr,-1,echoLocal,languageList[langIndex]); - - string playerNameStr = "Player with error is: " + getHumanPlayerName(); - if(lang.hasString("CheckSumGameLoadPlayer",languageList[langIndex]) == true) { - playerNameStr = lang.getString("CheckSumGameLoadPlayer",languageList[langIndex]) + " " + getHumanPlayerName(); - } - sendTextMessage(playerNameStr,-1,echoLocal,languageList[langIndex]); - - string sErr1 = "Client Checksum: " + intToStr(checksum->getSum()); - if(lang.hasString("CheckSumGameLoadClient",languageList[langIndex]) == true) { - sErr1 = lang.getString("CheckSumGameLoadClient",languageList[langIndex]) + " " + intToStr(checksum->getSum()); - } - - sendTextMessage(sErr1,-1,echoLocal,languageList[langIndex]); - - string sErr2 = "Server Checksum: " + intToStr(networkMessageReady.getChecksum()); - if(lang.hasString("CheckSumGameLoadServer",languageList[langIndex]) == true) { - sErr2 = lang.getString("CheckSumGameLoadServer",languageList[langIndex]) + " " + intToStr(networkMessageReady.getChecksum()); - } - sendTextMessage(sErr2,-1,echoLocal,languageList[langIndex]); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d %s %s %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,sErr.c_str(),sErr1.c_str(),sErr2.c_str()); - - if(echoLocal == true) { - if(Config::getInstance().getBool("NetworkConsistencyChecks")) { - // error message and disconnect only if checked - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - string niceError = sErr + string("\n") + sErr1 + string("\n") + sErr2; - DisplayErrorMessage(niceError); - } - } - } - - if(Config::getInstance().getBool("NetworkConsistencyChecks")) { - // error message and disconnect only if checked - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - sleep(1); - setQuit(true); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - close(); - } - return; - } - - MutexSafeWrapper safeMutexFlags2(flagAccessor,CODE_AT_LINE); - this->joinGameInProgress = false; - this->joinGameInProgressLaunch = false; - - //printf("Client signalServerWhenReadyToStartJoinedGame = %d\n",signalServerWhenReadyToStartJoinedGame); - if(signalServerWhenReadyToStartJoinedGame == true) { - - Lang &lang= Lang::getInstance(); - const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); - for(unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { - - string sText = "Player: %s is joining the game now."; - if(lang.hasString("JoinPlayerToCurrentGameLaunchDone",languageList[langIndex]) == true) { - sText = lang.getString("JoinPlayerToCurrentGameLaunchDone",languageList[langIndex]); - } - - if(clientSocket != NULL && clientSocket->isConnected() == true) { - string playerNameStr = getHumanPlayerName(); - char szBuf[8096]=""; - snprintf(szBuf,8096,sText.c_str(),playerNameStr.c_str()); - - sendTextMessage(szBuf,-1,false,languageList[langIndex]); - } - } - - this->resumeInGameJoin = true; - safeMutexFlags2.ReleaseLock(); - } - else { - safeMutexFlags2.ReleaseLock(); - // delay the start a bit, so clients have more room to get messages - // This is to ensure clients don't start ahead of the server and thus - // constantly freeze because they are waiting for the server to catch up - sleep(120); - } - - // This triggers LAG update packets to begin as required - lastNetworkCommandListSendTime = time(NULL); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); -} - -void ClientInterface::sendResumeGameMessage() { - NetworkMessageReady networkMessageReady; - sendMessage(&networkMessageReady); -} - -void ClientInterface::sendTextMessage(const string &text, int teamIndex, bool echoLocal, - string targetLanguage) { - - string humanPlayerName = getHumanPlayerName(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] humanPlayerName = [%s] playerIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,humanPlayerName.c_str(),playerIndex); - - NetworkMessageText networkMessageText(text, teamIndex,playerIndex,targetLanguage); - sendMessage(&networkMessageText); - - if(echoLocal == true) { - ChatMsgInfo msg(networkMessageText.getText().c_str(),networkMessageText.getTeamIndex(),networkMessageText.getPlayerIndex(),targetLanguage); - this->addChatInfo(msg); - } -} - -void ClientInterface::sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note,int playerIndex) { - string humanPlayerName = getHumanPlayerName(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] humanPlayerName = [%s] playerIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,humanPlayerName.c_str(),playerIndex); - - NetworkMessageMarkCell networkMessageMarkCell(targetPos,factionIndex, note,playerIndex); - sendMessage(&networkMessageMarkCell); -} - -void ClientInterface::sendHighlightCellMessage(Vec2i targetPos, int factionIndex) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,playerIndex); - - NetworkMessageHighlightCell networkMessageHighlightCell(targetPos,factionIndex); - sendMessage(&networkMessageHighlightCell); -} - -void ClientInterface::sendUnMarkCellMessage(Vec2i targetPos, int factionIndex) { - string humanPlayerName = getHumanPlayerName(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] humanPlayerName = [%s] playerIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,humanPlayerName.c_str(),playerIndex); - - NetworkMessageUnMarkCell networkMessageMarkCell(targetPos,factionIndex); - sendMessage(&networkMessageMarkCell); -} - -void ClientInterface::sendPingMessage(int32 pingFrequency, int64 pingTime) { - NetworkMessagePing networkMessagePing(pingFrequency,pingTime); - sendMessage(&networkMessagePing); -} - -string ClientInterface::getNetworkStatus() { - std::string label = Lang::getInstance().getString("Server") + ": " + serverName; - //float pingTime = getThreadedPingMS(getServerIpAddress().c_str()); - char szBuf[8096]=""; - snprintf(szBuf,8096,"%s",label.c_str()); - - return szBuf; -} - -NetworkMessageType ClientInterface::waitForMessage(int waitMicroseconds) -{ - // Debug! -/* - sendTextMessage("Timeout waiting for message",-1); - DisplayErrorMessage("Timeout waiting for message"); - quit= true; - close(); - return; -*/ - - uint64 loopCount = 0; - Chrono chronoPerf; - if(debugClientInterfacePerf == true) { - chronoPerf.start(); - } - - Chrono chrono; - chrono.start(); - - NetworkMessageType msg = nmtInvalid; - while( msg == nmtInvalid && - getQuitThread() == false) { - - msg = getNextMessageType(waitMicroseconds); - if(msg == nmtInvalid) { - if(getSocket() == NULL || (chrono.getMillis() % 250 == 0 && isConnected() == false)) { - if(getQuit() == false) { - //throw megaglest_runtime_error("Disconnected"); - //sendTextMessage("Server has Disconnected.",-1); - DisplayErrorMessage("Server has Disconnected."); - setQuit(true); - } - close(); - return msg; - } - - if(chrono.getMillis() > messageWaitTimeout) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - Lang &lang= Lang::getInstance(); - const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); - for(unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { - - string msg = "Timeout waiting for message."; - if(lang.hasString("TimeoutWaitingForMessage",languageList[langIndex]) == true) { - msg = lang.getString("TimeoutWaitingForMessage",languageList[langIndex]); - } - - sendTextMessage(msg,-1, lang.isLanguageLocal(languageList[langIndex]),languageList[langIndex]); - if(lang.isLanguageLocal(languageList[langIndex]) == true) { - DisplayErrorMessage(msg); + string sText = "Player: %s is joining the game now."; + if (lang.hasString("JoinPlayerToCurrentGameLaunchDone", languageList[langIndex]) == true) { + sText = lang.getString("JoinPlayerToCurrentGameLaunchDone", languageList[langIndex]); } - } - sleep(1); - setQuit(true); - close(); - return msg; + if (clientSocket != NULL && clientSocket->isConnected() == true) { + string playerNameStr = getHumanPlayerName(); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, sText.c_str(), playerNameStr.c_str()); + + sendTextMessage(szBuf, -1, false, languageList[langIndex]); + } + } + + this->resumeInGameJoin = true; + safeMutexFlags2.ReleaseLock(); + } else { + safeMutexFlags2.ReleaseLock(); + // delay the start a bit, so clients have more room to get messages + // This is to ensure clients don't start ahead of the server and thus + // constantly freeze because they are waiting for the server to catch up + sleep(120); } - // Sleep every x milli-seconds we wait to let other threads work - else if(chrono.getMillis() % 2 == 0) { - sleep(1); - } - else { - sleep(0); + + // This triggers LAG update packets to begin as required + lastNetworkCommandListSendTime = time(NULL); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] END\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + } + + void ClientInterface::sendResumeGameMessage() { + NetworkMessageReady networkMessageReady; + sendMessage(&networkMessageReady); + } + + void ClientInterface::sendTextMessage(const string &text, int teamIndex, bool echoLocal, + string targetLanguage) { + + string humanPlayerName = getHumanPlayerName(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] humanPlayerName = [%s] playerIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, humanPlayerName.c_str(), playerIndex); + + NetworkMessageText networkMessageText(text, teamIndex, playerIndex, targetLanguage); + sendMessage(&networkMessageText); + + if (echoLocal == true) { + ChatMsgInfo msg(networkMessageText.getText().c_str(), networkMessageText.getTeamIndex(), networkMessageText.getPlayerIndex(), targetLanguage); + this->addChatInfo(msg); } } - if(debugClientInterfacePerf == true) { - loopCount++; - if(chronoPerf.getMillis() >= 100) { - printf("Client waitForMessage loopCount = %llu\n",(long long unsigned int)loopCount); + void ClientInterface::sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note, int playerIndex) { + string humanPlayerName = getHumanPlayerName(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] humanPlayerName = [%s] playerIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, humanPlayerName.c_str(), playerIndex); - loopCount = 0; + NetworkMessageMarkCell networkMessageMarkCell(targetPos, factionIndex, note, playerIndex); + sendMessage(&networkMessageMarkCell); + } + + void ClientInterface::sendHighlightCellMessage(Vec2i targetPos, int factionIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] playerIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, playerIndex); + + NetworkMessageHighlightCell networkMessageHighlightCell(targetPos, factionIndex); + sendMessage(&networkMessageHighlightCell); + } + + void ClientInterface::sendUnMarkCellMessage(Vec2i targetPos, int factionIndex) { + string humanPlayerName = getHumanPlayerName(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] humanPlayerName = [%s] playerIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, humanPlayerName.c_str(), playerIndex); + + NetworkMessageUnMarkCell networkMessageMarkCell(targetPos, factionIndex); + sendMessage(&networkMessageMarkCell); + } + + void ClientInterface::sendPingMessage(int32 pingFrequency, int64 pingTime) { + NetworkMessagePing networkMessagePing(pingFrequency, pingTime); + sendMessage(&networkMessagePing); + } + + string ClientInterface::getNetworkStatus() { + std::string label = Lang::getInstance().getString("Server") + ": " + serverName; + //float pingTime = getThreadedPingMS(getServerIpAddress().c_str()); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "%s", label.c_str()); + + return szBuf; + } + + NetworkMessageType ClientInterface::waitForMessage(int waitMicroseconds) { + // Debug! + /* + sendTextMessage("Timeout waiting for message",-1); + DisplayErrorMessage("Timeout waiting for message"); + quit= true; + close(); + return; + */ + + uint64 loopCount = 0; + Chrono chronoPerf; + if (debugClientInterfacePerf == true) { chronoPerf.start(); } + + Chrono chrono; + chrono.start(); + + NetworkMessageType msg = nmtInvalid; + while (msg == nmtInvalid && + getQuitThread() == false) { + + msg = getNextMessageType(waitMicroseconds); + if (msg == nmtInvalid) { + if (getSocket() == NULL || (chrono.getMillis() % 250 == 0 && isConnected() == false)) { + if (getQuit() == false) { + //throw megaglest_runtime_error("Disconnected"); + //sendTextMessage("Server has Disconnected.",-1); + DisplayErrorMessage("Server has Disconnected."); + setQuit(true); + } + close(); + return msg; + } + + if (chrono.getMillis() > messageWaitTimeout) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + Lang &lang = Lang::getInstance(); + const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); + for (unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { + + string msg = "Timeout waiting for message."; + if (lang.hasString("TimeoutWaitingForMessage", languageList[langIndex]) == true) { + msg = lang.getString("TimeoutWaitingForMessage", languageList[langIndex]); + } + + sendTextMessage(msg, -1, lang.isLanguageLocal(languageList[langIndex]), languageList[langIndex]); + if (lang.isLanguageLocal(languageList[langIndex]) == true) { + DisplayErrorMessage(msg); + } + } + + sleep(1); + setQuit(true); + close(); + return msg; + } + // Sleep every x milli-seconds we wait to let other threads work + else if (chrono.getMillis() % 2 == 0) { + sleep(1); + } else { + sleep(0); + } + } + + if (debugClientInterfacePerf == true) { + loopCount++; + if (chronoPerf.getMillis() >= 100) { + printf("Client waitForMessage loopCount = %llu\n", (long long unsigned int)loopCount); + + loopCount = 0; + chronoPerf.start(); + } + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] waiting took %lld msecs, msg = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis(), msg); + + return msg; } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] waiting took %lld msecs, msg = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),msg); + void ClientInterface::quitGame(bool userManuallyQuit) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] userManuallyQuit = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, userManuallyQuit); - return msg; -} + if (clientSocket != NULL && userManuallyQuit == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); -void ClientInterface::quitGame(bool userManuallyQuit) -{ - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] userManuallyQuit = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,userManuallyQuit); + Lang &lang = Lang::getInstance(); + const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); + for (unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { - if(clientSocket != NULL && userManuallyQuit == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + string msg = "has chosen to leave the game!"; + if (lang.hasString("PlayerLeftGame", languageList[langIndex]) == true) { + msg = lang.getString("PlayerLeftGame", languageList[langIndex]); + } - Lang &lang= Lang::getInstance(); - const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); - for(unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { - - string msg = "has chosen to leave the game!"; - if(lang.hasString("PlayerLeftGame",languageList[langIndex]) == true) { - msg = lang.getString("PlayerLeftGame",languageList[langIndex]); - } - - sendTextMessage(msg,-1, lang.isLanguageLocal(languageList[langIndex]),languageList[langIndex]); - } - sleep(1); - close(); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void ClientInterface::close(bool lockMutex) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] START, clientSocket = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,clientSocket); - - MutexSafeWrapper safeMutex(NULL,CODE_AT_LINE); - if(lockMutex == true) { - safeMutex.setMutex(networkCommandListThreadAccessor,CODE_AT_LINE); - } - shutdownNetworkCommandListThread(safeMutex); - - delete clientSocket; - clientSocket = NULL; - - safeMutex.ReleaseLock(); - - connectedTime = 0; - gotIntro = false; - - MutexSafeWrapper safeMutexFlags(flagAccessor,CODE_AT_LINE); - this->joinGameInProgress = false; - this->joinGameInProgressLaunch = false; - this->readyForInGameJoin = false; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] END\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void ClientInterface::close() { - close(true); -} - -void ClientInterface::discoverServers(DiscoveredServersInterface *cb) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - ClientSocket::discoverServers(cb); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} -void ClientInterface::stopServerDiscovery() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - ClientSocket::stopBroadCastClientThread(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void ClientInterface::sendSwitchSetupRequest(string selectedFactionName, int8 currentSlotIndex, - int8 toSlotIndex,int8 toTeam, string networkPlayerName, - int8 networkPlayerStatus, int8 flags, - string language) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] networkPlayerName [%s] flags = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkPlayerName.c_str(),flags); - SwitchSetupRequest message = SwitchSetupRequest(selectedFactionName, - currentSlotIndex, toSlotIndex,toTeam,networkPlayerName, - networkPlayerStatus, flags,language); - sendMessage(&message); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -bool ClientInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMessageType) { - bool discard = false; - - switch(networkMessageType) { - case nmtIntro: - { - discard = true; - NetworkMessageIntro msg = NetworkMessageIntro(); - this->receiveMessage(&msg); + sendTextMessage(msg, -1, lang.isLanguageLocal(languageList[langIndex]), languageList[langIndex]); + } + sleep(1); + close(); } - break; - case nmtPing: - { - discard = true; - NetworkMessagePing msg = NetworkMessagePing(); - this->receiveMessage(&msg); - this->setLastPingInfo(msg); - } - break; - case nmtLaunch: - { - discard = true; - NetworkMessageLaunch msg = NetworkMessageLaunch(); - this->receiveMessage(&msg); - } - break; - case nmtText: - { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtText\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - discard = true; - NetworkMessageText netMsg = NetworkMessageText(); - this->receiveMessage(&netMsg); - ChatMsgInfo msg(netMsg.getText().c_str(),netMsg.getTeamIndex(),netMsg.getPlayerIndex(),netMsg.getTargetLanguage()); - this->addChatInfo(msg); - } - break; - - case nmtMarkCell: - { - discard = true; - NetworkMessageMarkCell networkMessageMarkCell; - receiveMessage(&networkMessageMarkCell); - - MarkedCell msg(networkMessageMarkCell.getTarget(), - networkMessageMarkCell.getFactionIndex(), - networkMessageMarkCell.getText().c_str(), - networkMessageMarkCell.getPlayerIndex()); - this->addMarkedCell(msg); - } - break; - - case nmtUnMarkCell: - { - discard = true; - NetworkMessageUnMarkCell networkMessageMarkCell; - receiveMessage(&networkMessageMarkCell); - - UnMarkedCell msg(networkMessageMarkCell.getTarget(), - networkMessageMarkCell.getFactionIndex()); - this->addUnMarkedCell(msg); - } - break; - - case nmtHighlightCell: - { - discard = true; - NetworkMessageHighlightCell networkMessageHighlightCell; - receiveMessage(&networkMessageHighlightCell); - - MarkedCell msg(networkMessageHighlightCell.getTarget(), - networkMessageHighlightCell.getFactionIndex(), - "none",-1); - this->setHighlightedCell(msg); - } - break; - - case nmtSynchNetworkGameData: - { - discard = true; - NetworkMessageSynchNetworkGameData msg = NetworkMessageSynchNetworkGameData(); - this->receiveMessage(&msg); - } - break; - case nmtSynchNetworkGameDataStatus: - { - discard = true; - NetworkMessageSynchNetworkGameDataStatus msg = NetworkMessageSynchNetworkGameDataStatus(); - this->receiveMessage(&msg); - } - break; - case nmtSynchNetworkGameDataFileCRCCheck: - { - discard = true; - NetworkMessageSynchNetworkGameDataFileCRCCheck msg = NetworkMessageSynchNetworkGameDataFileCRCCheck(); - this->receiveMessage(&msg); - } - break; - case nmtSynchNetworkGameDataFileGet: - { - discard = true; - NetworkMessageSynchNetworkGameDataFileGet msg = NetworkMessageSynchNetworkGameDataFileGet(); - this->receiveMessage(&msg); - } - break; - case nmtSwitchSetupRequest: - { - discard = true; - SwitchSetupRequest msg = SwitchSetupRequest(); - this->receiveMessage(&msg); - } - break; - case nmtBroadCastSetup: - { - discard = true; - NetworkMessageLaunch msg = NetworkMessageLaunch(); - this->receiveMessage(&msg); - } - break; - - case nmtPlayerIndexMessage: - { - discard = true; - PlayerIndexMessage msg = PlayerIndexMessage(0); - this->receiveMessage(&msg); - } - break; - } - - return discard; -} - -string ClientInterface::getHumanPlayerName(int index) { - string result = Config::getInstance().getString("NetPlayerName",Socket::getHostName().c_str()); - - if(index >= 0 || gameSettings.getThisFactionIndex() >= 0) { - if(index < 0) { - index = gameSettings.getThisFactionIndex(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Lined: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); } - if(gameSettings.getNetworkPlayerName(index) != "") { - result = gameSettings.getNetworkPlayerName(index); + + void ClientInterface::close(bool lockMutex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] START, clientSocket = %p\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, clientSocket); + + MutexSafeWrapper safeMutex(NULL, CODE_AT_LINE); + if (lockMutex == true) { + safeMutex.setMutex(networkCommandListThreadAccessor, CODE_AT_LINE); + } + shutdownNetworkCommandListThread(safeMutex); + + delete clientSocket; + clientSocket = NULL; + + safeMutex.ReleaseLock(); + + connectedTime = 0; + gotIntro = false; + + MutexSafeWrapper safeMutexFlags(flagAccessor, CODE_AT_LINE); + this->joinGameInProgress = false; + this->joinGameInProgressLaunch = false; + this->readyForInGameJoin = false; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] END\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); } + + void ClientInterface::close() { + close(true); + } + + void ClientInterface::discoverServers(DiscoveredServersInterface *cb) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + ClientSocket::discoverServers(cb); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + void ClientInterface::stopServerDiscovery() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + ClientSocket::stopBroadCastClientThread(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void ClientInterface::sendSwitchSetupRequest(string selectedFactionName, int8 currentSlotIndex, + int8 toSlotIndex, int8 toTeam, string networkPlayerName, + int8 networkPlayerStatus, int8 flags, + string language) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] networkPlayerName [%s] flags = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkPlayerName.c_str(), flags); + SwitchSetupRequest message = SwitchSetupRequest(selectedFactionName, + currentSlotIndex, toSlotIndex, toTeam, networkPlayerName, + networkPlayerStatus, flags, language); + sendMessage(&message); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + bool ClientInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMessageType) { + bool discard = false; + + switch (networkMessageType) { + case nmtIntro: + { + discard = true; + NetworkMessageIntro msg = NetworkMessageIntro(); + this->receiveMessage(&msg); + } + break; + case nmtPing: + { + discard = true; + NetworkMessagePing msg = NetworkMessagePing(); + this->receiveMessage(&msg); + this->setLastPingInfo(msg); + } + break; + case nmtLaunch: + { + discard = true; + NetworkMessageLaunch msg = NetworkMessageLaunch(); + this->receiveMessage(&msg); + } + break; + case nmtText: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got nmtText\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + discard = true; + NetworkMessageText netMsg = NetworkMessageText(); + this->receiveMessage(&netMsg); + + ChatMsgInfo msg(netMsg.getText().c_str(), netMsg.getTeamIndex(), netMsg.getPlayerIndex(), netMsg.getTargetLanguage()); + this->addChatInfo(msg); + } + break; + + case nmtMarkCell: + { + discard = true; + NetworkMessageMarkCell networkMessageMarkCell; + receiveMessage(&networkMessageMarkCell); + + MarkedCell msg(networkMessageMarkCell.getTarget(), + networkMessageMarkCell.getFactionIndex(), + networkMessageMarkCell.getText().c_str(), + networkMessageMarkCell.getPlayerIndex()); + this->addMarkedCell(msg); + } + break; + + case nmtUnMarkCell: + { + discard = true; + NetworkMessageUnMarkCell networkMessageMarkCell; + receiveMessage(&networkMessageMarkCell); + + UnMarkedCell msg(networkMessageMarkCell.getTarget(), + networkMessageMarkCell.getFactionIndex()); + this->addUnMarkedCell(msg); + } + break; + + case nmtHighlightCell: + { + discard = true; + NetworkMessageHighlightCell networkMessageHighlightCell; + receiveMessage(&networkMessageHighlightCell); + + MarkedCell msg(networkMessageHighlightCell.getTarget(), + networkMessageHighlightCell.getFactionIndex(), + "none", -1); + this->setHighlightedCell(msg); + } + break; + + case nmtSynchNetworkGameData: + { + discard = true; + NetworkMessageSynchNetworkGameData msg = NetworkMessageSynchNetworkGameData(); + this->receiveMessage(&msg); + } + break; + case nmtSynchNetworkGameDataStatus: + { + discard = true; + NetworkMessageSynchNetworkGameDataStatus msg = NetworkMessageSynchNetworkGameDataStatus(); + this->receiveMessage(&msg); + } + break; + case nmtSynchNetworkGameDataFileCRCCheck: + { + discard = true; + NetworkMessageSynchNetworkGameDataFileCRCCheck msg = NetworkMessageSynchNetworkGameDataFileCRCCheck(); + this->receiveMessage(&msg); + } + break; + case nmtSynchNetworkGameDataFileGet: + { + discard = true; + NetworkMessageSynchNetworkGameDataFileGet msg = NetworkMessageSynchNetworkGameDataFileGet(); + this->receiveMessage(&msg); + } + break; + case nmtSwitchSetupRequest: + { + discard = true; + SwitchSetupRequest msg = SwitchSetupRequest(); + this->receiveMessage(&msg); + } + break; + case nmtBroadCastSetup: + { + discard = true; + NetworkMessageLaunch msg = NetworkMessageLaunch(); + this->receiveMessage(&msg); + } + break; + + case nmtPlayerIndexMessage: + { + discard = true; + PlayerIndexMessage msg = PlayerIndexMessage(0); + this->receiveMessage(&msg); + } + break; + } + + return discard; + } + + string ClientInterface::getHumanPlayerName(int index) { + string result = Config::getInstance().getString("NetPlayerName", Socket::getHostName().c_str()); + + if (index >= 0 || gameSettings.getThisFactionIndex() >= 0) { + if (index < 0) { + index = gameSettings.getThisFactionIndex(); + } + if (gameSettings.getNetworkPlayerName(index) != "") { + result = gameSettings.getNetworkPlayerName(index); + } + } + + return result; + } + + void ClientInterface::setGameSettings(GameSettings *serverGameSettings) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] START\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + + gameSettings = *serverGameSettings; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] END\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + } + + void ClientInterface::broadcastGameSetup(const GameSettings *gameSettings) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + NetworkMessageLaunch networkMessageLaunch(gameSettings, nmtBroadCastSetup); + sendMessage(&networkMessageLaunch); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void ClientInterface::broadcastGameStart(const GameSettings *gameSettings) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + MutexSafeWrapper safeMutexFlags(flagAccessor, CODE_AT_LINE); + if (this->joinGameInProgress == true) { + this->joinGameInProgressLaunch = true; + } + safeMutexFlags.ReleaseLock(); + + //printf("Sending game launch joinGameInProgress: %d\n",joinGameInProgress); + + NetworkMessageLaunch networkMessageLaunch(gameSettings, nmtLaunch); + sendMessage(&networkMessageLaunch); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void ClientInterface::setGameSettingsReceived(bool value) { + //printf("In [%s:%s] Line: %d gameSettingsReceived = %d value = %d, gameSettingsReceivedCount = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,gameSettingsReceived,value,gameSettingsReceivedCount); + gameSettingsReceived = value; + gameSettingsReceivedCount++; + } + } - - return result; -} - -void ClientInterface::setGameSettings(GameSettings *serverGameSettings) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); - - gameSettings = *serverGameSettings; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); -} - -void ClientInterface::broadcastGameSetup(const GameSettings *gameSettings) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - NetworkMessageLaunch networkMessageLaunch(gameSettings, nmtBroadCastSetup); - sendMessage(&networkMessageLaunch); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void ClientInterface::broadcastGameStart(const GameSettings *gameSettings) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - MutexSafeWrapper safeMutexFlags(flagAccessor,CODE_AT_LINE); - if(this->joinGameInProgress == true) { - this->joinGameInProgressLaunch = true; - } - safeMutexFlags.ReleaseLock(); - - //printf("Sending game launch joinGameInProgress: %d\n",joinGameInProgress); - - NetworkMessageLaunch networkMessageLaunch(gameSettings, nmtLaunch); - sendMessage(&networkMessageLaunch); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void ClientInterface::setGameSettingsReceived(bool value) { - //printf("In [%s:%s] Line: %d gameSettingsReceived = %d value = %d, gameSettingsReceivedCount = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,gameSettingsReceived,value,gameSettingsReceivedCount); - gameSettingsReceived = value; - gameSettingsReceivedCount++; -} - -}}//end namespace +}//end namespace diff --git a/source/glest_game/network/client_interface.h b/source/glest_game/network/client_interface.h index 221ac3a8f..b5a5ce331 100644 --- a/source/glest_game/network/client_interface.h +++ b/source/glest_game/network/client_interface.h @@ -24,8 +24,8 @@ #define _GLEST_GAME_CLIENTINTERFACE_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -37,181 +37,216 @@ using Shared::Platform::Ip; using Shared::Platform::ClientSocket; using std::vector; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -class ClientInterface; + class ClientInterface; -class ClientInterfaceThread : public BaseThread, public SlaveThreadControllerInterface { -protected: + class ClientInterfaceThread : public BaseThread, public SlaveThreadControllerInterface { + protected: - ClientInterface *clientInterface; + ClientInterface * clientInterface; - virtual void setQuitStatus(bool value); + virtual void setQuitStatus(bool value); -public: - explicit ClientInterfaceThread(ClientInterface *client); - virtual ~ClientInterfaceThread(); - virtual void execute(); + public: + explicit ClientInterfaceThread(ClientInterface *client); + virtual ~ClientInterfaceThread(); + virtual void execute(); - virtual void setMasterController(MasterSlaveThreadController *master) { } - virtual void signalSlave(void *userdata) { } + virtual void setMasterController(MasterSlaveThreadController *master) { + } + virtual void signalSlave(void *userdata) { + } - virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false); -}; + virtual bool canShutdown(bool deleteSelfIfShutdownDelayed = false); + }; -// ===================================================== -// class ClientInterface -// ===================================================== + // ===================================================== + // class ClientInterface + // ===================================================== -class ClientInterface: public GameNetworkInterface { -private: - static const int messageWaitTimeout; - static const int waitSleepTime; - static const int maxNetworkCommandListSendTimeWait; + class ClientInterface : public GameNetworkInterface { + private: + static const int messageWaitTimeout; + static const int waitSleepTime; + static const int maxNetworkCommandListSendTimeWait; -private: - ClientSocket *clientSocket; - string serverName; - bool introDone; - bool launchGame; - int playerIndex; - bool gameSettingsReceived; - int gameSettingsReceivedCount; - time_t connectedTime; - bool gotIntro; + private: + ClientSocket * clientSocket; + string serverName; + bool introDone; + bool launchGame; + int playerIndex; + bool gameSettingsReceived; + int gameSettingsReceivedCount; + time_t connectedTime; + bool gotIntro; - Ip ip; - int port; + Ip ip; + int port; - int currentFrameCount; - int lastSentFrameCount; - time_t lastNetworkCommandListSendTime; + int currentFrameCount; + int lastSentFrameCount; + time_t lastNetworkCommandListSendTime; - time_t clientSimulationLagStartTime; - string versionString; - int sessionKey; - int serverFTPPort; + time_t clientSimulationLagStartTime; + string versionString; + int sessionKey; + int serverFTPPort; - string serverUUID; - string serverPlatform; + string serverUUID; + string serverPlatform; - ClientInterfaceThread *networkCommandListThread; + ClientInterfaceThread *networkCommandListThread; - Mutex *networkCommandListThreadAccessor; - std::map cachedPendingCommands; //commands ready to be given - std::map > cachedPendingCommandCRCs; //commands ready to be given - uint64 cachedPendingCommandsIndex; - uint64 cachedLastPendingFrameCount; - int64 timeClientWaitedForLastMessage; + Mutex *networkCommandListThreadAccessor; + std::map cachedPendingCommands; //commands ready to be given + std::map > cachedPendingCommandCRCs; //commands ready to be given + uint64 cachedPendingCommandsIndex; + uint64 cachedLastPendingFrameCount; + int64 timeClientWaitedForLastMessage; - Mutex *flagAccessor; - bool joinGameInProgress; - bool joinGameInProgressLaunch; - bool readyForInGameJoin; - bool resumeInGameJoin; + Mutex *flagAccessor; + bool joinGameInProgress; + bool joinGameInProgressLaunch; + bool readyForInGameJoin; + bool resumeInGameJoin; - Mutex *quitThreadAccessor; - bool quitThread; + Mutex *quitThreadAccessor; + bool quitThread; - bool getQuitThread(); - void setQuitThread(bool value); - bool getQuit(); - void setQuit(bool value); + bool getQuitThread(); + void setQuitThread(bool value); + bool getQuit(); + void setQuit(bool value); -public: - ClientInterface(); - virtual ~ClientInterface(); + public: + ClientInterface(); + virtual ~ClientInterface(); - virtual std::string getIpAddress(bool mutexLock=true); - virtual Socket* getSocket(bool mutexLock=true) {return clientSocket;} - virtual void close(); + virtual std::string getIpAddress(bool mutexLock = true); + virtual Socket* getSocket(bool mutexLock = true) { + return clientSocket; + } + virtual void close(); - bool getJoinGameInProgress(); - bool getJoinGameInProgressLaunch(); + bool getJoinGameInProgress(); + bool getJoinGameInProgressLaunch(); - bool getReadyForInGameJoin(); + bool getReadyForInGameJoin(); - bool getResumeInGameJoin(); - void sendResumeGameMessage(); + bool getResumeInGameJoin(); + void sendResumeGameMessage(); - uint64 getCachedLastPendingFrameCount(); - int64 getTimeClientWaitedForLastMessage(); + uint64 getCachedLastPendingFrameCount(); + int64 getTimeClientWaitedForLastMessage(); - //message processing - virtual void update(); - virtual void updateLobby(); - virtual void updateKeyframe(int frameCount); - virtual void setKeyframe(int frameCount) { currentFrameCount = frameCount; } - virtual void waitUntilReady(Checksum* checksum); + //message processing + virtual void update(); + virtual void updateLobby(); + virtual void updateKeyframe(int frameCount); + virtual void setKeyframe(int frameCount) { + currentFrameCount = frameCount; + } + virtual void waitUntilReady(Checksum* checksum); - // message sending - virtual void sendTextMessage(const string &text, int teamIndex, bool echoLocal, - string targetLanguage); - virtual void quitGame(bool userManuallyQuit); + // message sending + virtual void sendTextMessage(const string &text, int teamIndex, bool echoLocal, + string targetLanguage); + virtual void quitGame(bool userManuallyQuit); - virtual void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note,int playerIndex); - virtual void sendUnMarkCellMessage(Vec2i targetPos, int factionIndex); - virtual void sendHighlightCellMessage(Vec2i targetPos, int factionIndex); - //misc - virtual string getNetworkStatus() ; + virtual void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note, int playerIndex); + virtual void sendUnMarkCellMessage(Vec2i targetPos, int factionIndex); + virtual void sendHighlightCellMessage(Vec2i targetPos, int factionIndex); + //misc + virtual string getNetworkStatus(); - //accessors - string getServerName() const {return serverName;} - bool getLaunchGame() const {return launchGame;} - bool getIntroDone() const {return introDone;} - bool getGameSettingsReceived() const {return gameSettingsReceived;} - void setGameSettingsReceived(bool value); + //accessors + string getServerName() const { + return serverName; + } + bool getLaunchGame() const { + return launchGame; + } + bool getIntroDone() const { + return introDone; + } + bool getGameSettingsReceived() const { + return gameSettingsReceived; + } + void setGameSettingsReceived(bool value); - int getGameSettingsReceivedCount() const { return gameSettingsReceivedCount; } + int getGameSettingsReceivedCount() const { + return gameSettingsReceivedCount; + } - int getPlayerIndex() const {return playerIndex;} + int getPlayerIndex() const { + return playerIndex; + } - void connect(const Ip &ip, int port); - void reset(); + void connect(const Ip &ip, int port); + void reset(); - void discoverServers(DiscoveredServersInterface *cb); - void stopServerDiscovery(); + void discoverServers(DiscoveredServersInterface *cb); + void stopServerDiscovery(); - void sendSwitchSetupRequest(string selectedFactionName, int8 currentSlotIndex, - int8 toSlotIndex, int8 toTeam,string networkPlayerName, - int8 networkPlayerStatus, int8 flags, - string language); - virtual bool getConnectHasHandshaked() const { return gotIntro; } - std::string getServerIpAddress(); + void sendSwitchSetupRequest(string selectedFactionName, int8 currentSlotIndex, + int8 toSlotIndex, int8 toTeam, string networkPlayerName, + int8 networkPlayerStatus, int8 flags, + string language); + virtual bool getConnectHasHandshaked() const { + return gotIntro; + } + std::string getServerIpAddress(); - int getCurrentFrameCount() const { return currentFrameCount; } + int getCurrentFrameCount() const { + return currentFrameCount; + } - virtual void sendPingMessage(int32 pingFrequency, int64 pingTime); + virtual void sendPingMessage(int32 pingFrequency, int64 pingTime); - const string &getVersionString() const {return versionString;} - virtual string getHumanPlayerName(int index=-1); - virtual int getHumanPlayerIndex() const {return playerIndex;} - int getServerFTPPort() const { return serverFTPPort; } + const string &getVersionString() const { + return versionString; + } + virtual string getHumanPlayerName(int index = -1); + virtual int getHumanPlayerIndex() const { + return playerIndex; + } + int getServerFTPPort() const { + return serverFTPPort; + } - int getSessionKey() const { return sessionKey; } - bool isMasterServerAdminOverride(); + int getSessionKey() const { + return sessionKey; + } + bool isMasterServerAdminOverride(); - void setGameSettings(GameSettings *serverGameSettings); - void broadcastGameSetup(const GameSettings *gameSettings); - void broadcastGameStart(const GameSettings *gameSettings); + void setGameSettings(GameSettings *serverGameSettings); + void broadcastGameSetup(const GameSettings *gameSettings); + void broadcastGameStart(const GameSettings *gameSettings); - void updateNetworkFrame(); + void updateNetworkFrame(); - virtual void saveGame(XmlNode *rootNode) {}; + virtual void saveGame(XmlNode *rootNode) { + }; -protected: + protected: - Mutex * getServerSynchAccessor() { return NULL; } - NetworkMessageType waitForMessage(int waitMicroseconds=0); - bool shouldDiscardNetworkMessage(NetworkMessageType networkMessageType); + Mutex * getServerSynchAccessor() { + return NULL; + } + NetworkMessageType waitForMessage(int waitMicroseconds = 0); + bool shouldDiscardNetworkMessage(NetworkMessageType networkMessageType); - void updateFrame(int *checkFrame); - void shutdownNetworkCommandListThread(MutexSafeWrapper &safeMutexWrapper); - bool getNetworkCommand(int frameCount, int currentCachedPendingCommandsIndex); + void updateFrame(int *checkFrame); + void shutdownNetworkCommandListThread(MutexSafeWrapper &safeMutexWrapper); + bool getNetworkCommand(int frameCount, int currentCachedPendingCommandsIndex); - void close(bool lockMutex); -}; + void close(bool lockMutex); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/glest_game/network/connection_slot.cpp b/source/glest_game/network/connection_slot.cpp index dcaac4362..6b368739f 100644 --- a/source/glest_game/network/connection_slot.cpp +++ b/source/glest_game/network/connection_slot.cpp @@ -33,1630 +33,1586 @@ using namespace std; using namespace Shared::Util; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class ConnectionSlotThread -// ===================================================== + // ===================================================== + // class ConnectionSlotThread + // ===================================================== -ConnectionSlotThread::ConnectionSlotThread(int slotIndex) : BaseThread() { - this->masterController = NULL; - this->triggerIdMutex = new Mutex(CODE_AT_LINE); - this->slotIndex = slotIndex; - this->slotInterface = NULL; - uniqueID = "ConnectionSlotThread"; - eventList.clear(); - eventList.reserve(1000); + ConnectionSlotThread::ConnectionSlotThread(int slotIndex) : BaseThread() { + this->masterController = NULL; + this->triggerIdMutex = new Mutex(CODE_AT_LINE); + this->slotIndex = slotIndex; + this->slotInterface = NULL; + uniqueID = "ConnectionSlotThread"; + eventList.clear(); + eventList.reserve(1000); - triggerGameStarted = new Mutex(CODE_AT_LINE); - gameStarted = false; -} - -ConnectionSlotThread::ConnectionSlotThread(ConnectionSlotCallbackInterface *slotInterface,int slotIndex) : BaseThread() { - this->masterController = NULL; - this->triggerIdMutex = new Mutex(CODE_AT_LINE); - this->slotIndex = slotIndex; - this->slotInterface = slotInterface; - uniqueID = "ConnectionSlotThread"; - eventList.clear(); - - triggerGameStarted = new Mutex(CODE_AT_LINE); - gameStarted = false; -} - -ConnectionSlotThread::~ConnectionSlotThread() { - delete triggerIdMutex; - triggerIdMutex = NULL; - - delete triggerGameStarted; - triggerGameStarted = NULL; -} - -void ConnectionSlotThread::setQuitStatus(bool value) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d value = %d\n",__FILE__,__FUNCTION__,__LINE__,value); - - BaseThread::setQuitStatus(value); - if(value == true) { - signalUpdate(NULL); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); -} - -void ConnectionSlotThread::signalUpdate(ConnectionSlotEvent *event) { - if(event != NULL) { - MutexSafeWrapper safeMutex(triggerIdMutex,CODE_AT_LINE); - eventList.push_back(*event); - } - if(getGameStarted() == true && getQuitStatus() == true) { - return; - } - semTaskSignalled.signal(); -} - -void ConnectionSlotThread::setTaskCompleted(int eventId) { - if(eventId > 0) { - MutexSafeWrapper safeMutex(triggerIdMutex,CODE_AT_LINE); - for(int index = 0; index < (int)eventList.size(); ++index) { - ConnectionSlotEvent &slotEvent = eventList[index]; - if(slotEvent.eventId == eventId) { - slotEvent.eventCompleted = true; - break; - } + triggerGameStarted = new Mutex(CODE_AT_LINE); + gameStarted = false; } - } -} -//void ConnectionSlotThread::purgeAllEvents() { -// MutexSafeWrapper safeMutex(triggerIdMutex,CODE_AT_LINE); -// eventList.clear(); -//} + ConnectionSlotThread::ConnectionSlotThread(ConnectionSlotCallbackInterface *slotInterface, int slotIndex) : BaseThread() { + this->masterController = NULL; + this->triggerIdMutex = new Mutex(CODE_AT_LINE); + this->slotIndex = slotIndex; + this->slotInterface = slotInterface; + uniqueID = "ConnectionSlotThread"; + eventList.clear(); -void ConnectionSlotThread::setAllEventsCompleted() { - MutexSafeWrapper safeMutex(triggerIdMutex,CODE_AT_LINE); - for(int index = 0; index < (int)eventList.size(); ++index) { - ConnectionSlotEvent &slotEvent = eventList[index]; - if(slotEvent.eventCompleted == false) { - slotEvent.eventCompleted = true; - } - } -} - -void ConnectionSlotThread::purgeCompletedEvents() { - MutexSafeWrapper safeMutex(triggerIdMutex,CODE_AT_LINE); - for(int index = (int)eventList.size() - 1; index >= 0; index--) { - ConnectionSlotEvent &slotEvent = eventList[index]; - if(slotEvent.eventCompleted == true) { - eventList.erase(eventList.begin() + index); - } - } -} - -bool ConnectionSlotThread::canShutdown(bool deleteSelfIfShutdownDelayed) { - bool ret = (getExecutingTask() == false); - if(ret == false && deleteSelfIfShutdownDelayed == true) { - setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed); - deleteSelfIfRequired(); - signalQuit(); - } - - return ret; -} - -bool ConnectionSlotThread::isSignalCompleted(ConnectionSlotEvent *event) { - bool result = false; - if(event != NULL) { - MutexSafeWrapper safeMutex(triggerIdMutex,CODE_AT_LINE); - for(int index = 0; index < (int)eventList.size(); ++index) { - ConnectionSlotEvent &slotEvent = eventList[index]; - if(slotEvent.eventId == event->eventId) { - result = slotEvent.eventCompleted; - break; - } - } - } - return result; -} - -void ConnectionSlotThread::slotUpdateTask(ConnectionSlotEvent *event) { - if(event != NULL && event->connectionSlot != NULL) { - if(event->eventType == eSendSocketData) { - event->connectionSlot->sendMessage(event->networkMessage); + triggerGameStarted = new Mutex(CODE_AT_LINE); + gameStarted = false; } - else if(event->eventType == eReceiveSocketData) { - event->connectionSlot->updateSlot(event); + + ConnectionSlotThread::~ConnectionSlotThread() { + delete triggerIdMutex; + triggerIdMutex = NULL; + + delete triggerGameStarted; + triggerGameStarted = NULL; } - } -} -void ConnectionSlotThread::signalSlave(void *userdata) { - std::map *eventList = (std::map *)userdata; - ConnectionSlotEvent &event = (*eventList)[slotIndex]; - signalUpdate(&event); -} + void ConnectionSlotThread::setQuitStatus(bool value) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d value = %d\n", __FILE__, __FUNCTION__, __LINE__, value); -bool ConnectionSlotThread::getGameStarted() { - MutexSafeWrapper safeMutexGameStarted(triggerGameStarted,CODE_AT_LINE); - return gameStarted; -} -void ConnectionSlotThread::setGameStarted(bool value) { - MutexSafeWrapper safeMutexGameStarted(triggerGameStarted,CODE_AT_LINE); - if(gameStarted != value) { - gameStarted = value; + BaseThread::setQuitStatus(value); + if (value == true) { + signalUpdate(NULL); + } - if(gameStarted == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", __FILE__, __FUNCTION__, __LINE__); + } + + void ConnectionSlotThread::signalUpdate(ConnectionSlotEvent *event) { + if (event != NULL) { + MutexSafeWrapper safeMutex(triggerIdMutex, CODE_AT_LINE); + eventList.push_back(*event); + } + if (getGameStarted() == true && getQuitStatus() == true) { + return; + } semTaskSignalled.signal(); } - } -} -void ConnectionSlotThread::execute() { - RunningStatusSafeWrapper runningStatus(this); - try { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - //printf("Starting client SLOT thread: %d\n",slotIndex); + void ConnectionSlotThread::setTaskCompleted(int eventId) { + if (eventId > 0) { + MutexSafeWrapper safeMutex(triggerIdMutex, CODE_AT_LINE); + for (int index = 0; index < (int) eventList.size(); ++index) { + ConnectionSlotEvent &slotEvent = eventList[index]; + if (slotEvent.eventId == eventId) { + slotEvent.eventCompleted = true; + break; + } + } + } + } - for(;this->slotInterface != NULL;) { - if(getQuitStatus() == true) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; + //void ConnectionSlotThread::purgeAllEvents() { + // MutexSafeWrapper safeMutex(triggerIdMutex,CODE_AT_LINE); + // eventList.clear(); + //} + + void ConnectionSlotThread::setAllEventsCompleted() { + MutexSafeWrapper safeMutex(triggerIdMutex, CODE_AT_LINE); + for (int index = 0; index < (int) eventList.size(); ++index) { + ConnectionSlotEvent &slotEvent = eventList[index]; + if (slotEvent.eventCompleted == false) { + slotEvent.eventCompleted = true; + } + } + } + + void ConnectionSlotThread::purgeCompletedEvents() { + MutexSafeWrapper safeMutex(triggerIdMutex, CODE_AT_LINE); + for (int index = (int) eventList.size() - 1; index >= 0; index--) { + ConnectionSlotEvent &slotEvent = eventList[index]; + if (slotEvent.eventCompleted == true) { + eventList.erase(eventList.begin() + index); + } + } + } + + bool ConnectionSlotThread::canShutdown(bool deleteSelfIfShutdownDelayed) { + bool ret = (getExecutingTask() == false); + if (ret == false && deleteSelfIfShutdownDelayed == true) { + setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed); + deleteSelfIfRequired(); + signalQuit(); } - // Does this game allow joining in progress play and is this slot - // not already connected to a client? - if( this->slotInterface->getAllowInGameConnections() == true && - this->slotInterface->isClientConnected(slotIndex) == false) { - //printf("#1 Non connected slot: %d waiting for client connection..\n",slotIndex); - sleep(100); + return ret; + } - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; + bool ConnectionSlotThread::isSignalCompleted(ConnectionSlotEvent *event) { + bool result = false; + if (event != NULL) { + MutexSafeWrapper safeMutex(triggerIdMutex, CODE_AT_LINE); + for (int index = 0; index < (int) eventList.size(); ++index) { + ConnectionSlotEvent &slotEvent = eventList[index]; + if (slotEvent.eventId == event->eventId) { + result = slotEvent.eventCompleted; + break; + } } - - //printf("Slot thread slotIndex: %d eventCount: %d\n",slotIndex,eventCount); - - ConnectionSlotEvent eventCopy; - eventCopy.eventType = eReceiveSocketData; - eventCopy.connectionSlot = this->slotInterface->getSlot(slotIndex,true); - - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; - } - - ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); - this->slotUpdateTask(&eventCopy); } - else { - // If the game already started? - if(getGameStarted() == true) { - //printf("#A Checking action for slot: %d\n",slotIndex); + return result; + } - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; - } - - ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); - - // If the slot or socket are NULL the connection was lost - // so exit the thread - MutexSafeWrapper safeMutex(this->slotInterface->getSlotMutex(slotIndex),CODE_AT_LINE); - ConnectionSlot *slot = this->slotInterface->getSlot(slotIndex,false); - if(slot == NULL) { - break; - } - Socket *socket = slot->getSocket(true); - if(socket == NULL) { - break; - } - - PLATFORM_SOCKET socketId = socket->getSocketId(); - safeMutex.ReleaseLock(); - - // Avoid mutex locking - //bool socketHasReadData = Socket::hasDataToRead(socket->getSocketId()); - bool socketHasReadData = Socket::hasDataToReadWithWait(socketId,150000); - - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; - } - - ConnectionSlotEvent eventCopy; - eventCopy.eventType = eReceiveSocketData; - eventCopy.connectionSlot = this->slotInterface->getSlot(slotIndex,true); - eventCopy.eventId = slotIndex; - eventCopy.socketTriggered = socketHasReadData; - - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; - } - - this->slotUpdateTask(&eventCopy); + void ConnectionSlotThread::slotUpdateTask(ConnectionSlotEvent *event) { + if (event != NULL && event->connectionSlot != NULL) { + if (event->eventType == eSendSocketData) { + event->connectionSlot->sendMessage(event->networkMessage); + } else if (event->eventType == eReceiveSocketData) { + event->connectionSlot->updateSlot(event); } - // Game has not yet started - else { - //printf("#1 Checking action for slot: %d\n",slotIndex); + } + } - if(getGameStarted() == true) { - continue; - } - //printf("#2 Checking action for slot: %d\n",slotIndex); + void ConnectionSlotThread::signalSlave(void *userdata) { + std::map *eventList = (std::map *)userdata; + ConnectionSlotEvent &event = (*eventList)[slotIndex]; + signalUpdate(&event); + } - semTaskSignalled.waitTillSignalled(); - //printf("#3 Checking action for slot: %d\n",slotIndex); + bool ConnectionSlotThread::getGameStarted() { + MutexSafeWrapper safeMutexGameStarted(triggerGameStarted, CODE_AT_LINE); + return gameStarted; + } + void ConnectionSlotThread::setGameStarted(bool value) { + MutexSafeWrapper safeMutexGameStarted(triggerGameStarted, CODE_AT_LINE); + if (gameStarted != value) { + gameStarted = value; - if(getGameStarted() == true) { - continue; - } - //printf("#4 Checking action for slot: %d\n",slotIndex); + if (gameStarted == true) { + semTaskSignalled.signal(); + } + } + } - static string masterSlaveOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MasterSlaveThreadControllerSafeWrapper safeMasterController(masterController,20000,masterSlaveOwnerId); - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + void ConnectionSlotThread::execute() { + RunningStatusSafeWrapper runningStatus(this); + try { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + //printf("Starting client SLOT thread: %d\n",slotIndex); + + for (; this->slotInterface != NULL;) { + if (getQuitStatus() == true) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); break; } - MutexSafeWrapper safeMutex(triggerIdMutex,CODE_AT_LINE); - int eventCount = (int)eventList.size(); + // Does this game allow joining in progress play and is this slot + // not already connected to a client? + if (this->slotInterface->getAllowInGameConnections() == true && + this->slotInterface->isClientConnected(slotIndex) == false) { + //printf("#1 Non connected slot: %d waiting for client connection..\n",slotIndex); + sleep(100); - //printf("Slot thread slotIndex: %d eventCount: %d\n",slotIndex,eventCount); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Slot thread slotIndex: %d eventCount: %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex,eventCount); + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } + + //printf("Slot thread slotIndex: %d eventCount: %d\n",slotIndex,eventCount); - if(eventCount > 0) { ConnectionSlotEvent eventCopy; - for(int i = 0; i < (int)eventList.size(); ++i) { - ConnectionSlotEvent &slotEvent = eventList[i]; - if(slotEvent.eventCompleted == false) { - eventCopy = slotEvent; + eventCopy.eventType = eReceiveSocketData; + eventCopy.connectionSlot = this->slotInterface->getSlot(slotIndex, true); + + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } + + ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); + this->slotUpdateTask(&eventCopy); + } else { + // If the game already started? + if (getGameStarted() == true) { + //printf("#A Checking action for slot: %d\n",slotIndex); + + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); break; } - } - safeMutex.ReleaseLock(); - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; - } - - if(eventCopy.eventId > 0) { ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex,eventCount,(int)eventCopy.eventId); - //printf("#1 Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",slotIndex,eventCount,(int)eventCopy.eventId); + // If the slot or socket are NULL the connection was lost + // so exit the thread + MutexSafeWrapper safeMutex(this->slotInterface->getSlotMutex(slotIndex), CODE_AT_LINE); + ConnectionSlot *slot = this->slotInterface->getSlot(slotIndex, false); + if (slot == NULL) { + break; + } + Socket *socket = slot->getSocket(true); + if (socket == NULL) { + break; + } + + PLATFORM_SOCKET socketId = socket->getSocketId(); + safeMutex.ReleaseLock(); + + // Avoid mutex locking + //bool socketHasReadData = Socket::hasDataToRead(socket->getSocketId()); + bool socketHasReadData = Socket::hasDataToReadWithWait(socketId, 150000); + + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } + + ConnectionSlotEvent eventCopy; + eventCopy.eventType = eReceiveSocketData; + eventCopy.connectionSlot = this->slotInterface->getSlot(slotIndex, true); + eventCopy.eventId = slotIndex; + eventCopy.socketTriggered = socketHasReadData; + + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } this->slotUpdateTask(&eventCopy); - setTaskCompleted(eventCopy.eventId); + } + // Game has not yet started + else { + //printf("#1 Checking action for slot: %d\n",slotIndex); - //printf("#2 Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",slotIndex,eventCount,(int)eventCopy.eventId); + if (getGameStarted() == true) { + continue; + } + //printf("#2 Checking action for slot: %d\n",slotIndex); + + semTaskSignalled.waitTillSignalled(); + //printf("#3 Checking action for slot: %d\n",slotIndex); + + if (getGameStarted() == true) { + continue; + } + //printf("#4 Checking action for slot: %d\n",slotIndex); + + static string masterSlaveOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MasterSlaveThreadControllerSafeWrapper safeMasterController(masterController, 20000, masterSlaveOwnerId); + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } + + MutexSafeWrapper safeMutex(triggerIdMutex, CODE_AT_LINE); + int eventCount = (int) eventList.size(); + + //printf("Slot thread slotIndex: %d eventCount: %d\n",slotIndex,eventCount); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] Slot thread slotIndex: %d eventCount: %d\n", __FILE__, __FUNCTION__, __LINE__, slotIndex, eventCount); + + if (eventCount > 0) { + ConnectionSlotEvent eventCopy; + for (int i = 0; i < (int) eventList.size(); ++i) { + ConnectionSlotEvent &slotEvent = eventList[i]; + if (slotEvent.eventCompleted == false) { + eventCopy = slotEvent; + break; + } + } + safeMutex.ReleaseLock(); + + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } + + if (eventCopy.eventId > 0) { + ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n", __FILE__, __FUNCTION__, __LINE__, slotIndex, eventCount, (int) eventCopy.eventId); + //printf("#1 Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",slotIndex,eventCount,(int)eventCopy.eventId); + + this->slotUpdateTask(&eventCopy); + setTaskCompleted(eventCopy.eventId); + + //printf("#2 Slot thread slotIndex: %d eventCount: %d eventCopy.eventId: %d\n",slotIndex,eventCount,(int)eventCopy.eventId); + } + } } } + + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } } + + //printf("Ending client SLOT thread: %d\n",slotIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } catch (const exception &ex) { + + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + throw megaglest_runtime_error(ex.what()); } - - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", __FILE__, __FUNCTION__, __LINE__); } - //printf("Ending client SLOT thread: %d\n",slotIndex); + // ===================================================== + // class ConnectionSlot + // ===================================================== - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - catch(const exception &ex) { + ConnectionSlot::ConnectionSlot(ServerInterface* serverInterface, int playerIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", __FILE__, __FUNCTION__, __LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + this->mutexSocket = new Mutex(CODE_AT_LINE); + this->socket = NULL; + this->mutexCloseConnection = new Mutex(CODE_AT_LINE); + this->mutexPendingNetworkCommandList = new Mutex(CODE_AT_LINE); + this->socketSynchAccessor = new Mutex(CODE_AT_LINE); + this->connectedRemoteIPAddress = 0; + this->sessionKey = 0; + this->serverInterface = serverInterface; + this->playerIndex = playerIndex; + this->playerStatus = npst_None; + this->playerLanguage = ""; + this->playerUUID = ""; + this->platform = ""; + this->currentFrameCount = 0; + this->currentLagCount = 0; + this->graceLagCtr = 0; + this->gotLagCountWarning = false; + this->lastReceiveCommandListTime = 0; + this->receivedNetworkGameStatus = false; - throw megaglest_runtime_error(ex.what()); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); -} + this->autoPauseGameCountForLag = 0; + this->skipLagCheck = false; + this->joinGameInProgress = false; + this->canAcceptConnections = true; + this->startInGameConnectionLaunch = false; + this->pauseForInGameConnection = false; + this->unPauseForInGameConnection = false; + this->sentSavedGameInfo = false; -// ===================================================== -// class ConnectionSlot -// ===================================================== + this->ready = false; + this->gotIntro = false; + this->connectedTime = 0; -ConnectionSlot::ConnectionSlot(ServerInterface* serverInterface, int playerIndex) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); - - this->mutexSocket = new Mutex(CODE_AT_LINE); - this->socket = NULL; - this->mutexCloseConnection = new Mutex(CODE_AT_LINE); - this->mutexPendingNetworkCommandList = new Mutex(CODE_AT_LINE); - this->socketSynchAccessor = new Mutex(CODE_AT_LINE); - this->connectedRemoteIPAddress = 0; - this->sessionKey = 0; - this->serverInterface = serverInterface; - this->playerIndex = playerIndex; - this->playerStatus = npst_None; - this->playerLanguage = ""; - this->playerUUID = ""; - this->platform = ""; - this->currentFrameCount = 0; - this->currentLagCount = 0; - this->graceLagCtr = 0; - this->gotLagCountWarning = false; - this->lastReceiveCommandListTime = 0; - this->receivedNetworkGameStatus = false; - - this->autoPauseGameCountForLag = 0; - this->skipLagCheck = false; - this->joinGameInProgress = false; - this->canAcceptConnections = true; - this->startInGameConnectionLaunch = false; - this->pauseForInGameConnection = false; - this->unPauseForInGameConnection = false; - this->sentSavedGameInfo = false; - - this->ready = false; - this->gotIntro = false; - this->connectedTime = 0; - - this->networkGameDataSynchCheckOkMap = false; - this->networkGameDataSynchCheckOkTile = false; - this->networkGameDataSynchCheckOkTech = false; - this->setNetworkGameDataSynchCheckTechMismatchReport(""); - this->setReceivedDataSynchCheck(false); - - this->clearChatInfo(); - - this->setSocket(NULL); - this->slotThreadWorker = NULL; - static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); - this->slotThreadWorker = new ConnectionSlotThread(this->serverInterface,playerIndex); - this->slotThreadWorker->setUniqueID(mutexOwnerId); - this->slotThreadWorker->start(); -} - -ConnectionSlot::~ConnectionSlot() { - //printf("===> Destructor for ConnectionSlot = %d\n",playerIndex); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] START\n",__FILE__,__FUNCTION__,__LINE__); - - //printf("Deleting connection slot\n"); - close(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //printf("#1 Ending client SLOT: %d slotThreadWorker: %p\n",playerIndex,slotThreadWorker); - if(slotThreadWorker != NULL) { - slotThreadWorker->signalQuit(); - } - if( slotThreadWorker != NULL && - slotThreadWorker->canShutdown(false) == true && - slotThreadWorker->getRunningStatus() == false) { - //printf("#2 Ending client SLOT: %d\n",playerIndex); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - delete slotThreadWorker; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - else if(slotThreadWorker != NULL && - slotThreadWorker->canShutdown(true) == true) { - - if(slotThreadWorker->getRunningStatus() == false) { - //printf("#3 Ending client SLOT: %d\n",playerIndex); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - delete slotThreadWorker; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - else { - slotThreadWorker->setDeleteSelfOnExecutionDone(true); - slotThreadWorker->setDeleteAfterExecute(true); - } - } - //printf("#4 Ending client SLOT: %d\n",playerIndex); - slotThreadWorker = NULL; - - delete socketSynchAccessor; - socketSynchAccessor = NULL; - - delete mutexPendingNetworkCommandList; - mutexPendingNetworkCommandList = NULL; - - delete mutexCloseConnection; - mutexCloseConnection = NULL; - - delete mutexSocket; - mutexSocket = NULL; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__); -} - -int ConnectionSlot::getAutoPauseGameCountForLag() { - return autoPauseGameCountForLag; -} - -void ConnectionSlot::incrementAutoPauseGameCountForLag() { - autoPauseGameCountForLag++; -} - -bool ConnectionSlot::getGameStarted() { - bool result = false; - if(this->slotThreadWorker != NULL) { - result = this->slotThreadWorker->getGameStarted(); - } - return result; -} -void ConnectionSlot::setGameStarted(bool value) { - if(this->slotThreadWorker != NULL) { - this->slotThreadWorker->setGameStarted(value); - } -} - -void ConnectionSlot::setPlayerIndex(int value) { - playerIndex = value; - - if(this->slotThreadWorker != NULL) { - this->slotThreadWorker->setSlotIndex(playerIndex); - } -} - -void ConnectionSlot::setReady() { - this->ready= true; - this->skipLagCheck = false; - this->joinGameInProgress = false; - this->sentSavedGameInfo = false; -} - -void ConnectionSlot::updateSlot(ConnectionSlotEvent *event) { - if(event != NULL) { - bool &socketTriggered = event->socketTriggered; - bool checkForNewClients = - (serverInterface->getGameHasBeenInitiated() == false || - serverInterface->getAllowInGameConnections() == true); - - //if((serverInterface->getGameHasBeenInitiated() == false || - // (serverInterface->getAllowInGameConnections() == true && this->isConnected() == false) || - // socketTriggered == true)) { - if(socketTriggered == true || - ((serverInterface->getGameHasBeenInitiated() == false || - serverInterface->getAllowInGameConnections() == true) && - this->isConnected() == false)) { - - this->update(checkForNewClients,event->triggerId); - } - //} - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -string ConnectionSlot::getIpAddress(bool mutexLock) { - string result = ""; - MutexSafeWrapper safeMutexSlot((mutexLock == true ? mutexSocket : NULL),CODE_AT_LINE); - if(socket != NULL) { - result = socket->getIpAddress(); - } - return result; -} - -void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { - try { - clearThreadErrorList(); - - if(slotThreadWorker != NULL) { - slotThreadWorker->purgeCompletedEvents(); - } - - pair socketInfo = this->getSocketInfo(); - if(socketInfo.second == NULL) { - if(networkGameDataSynchCheckOkMap) networkGameDataSynchCheckOkMap = false; - if(networkGameDataSynchCheckOkTile) networkGameDataSynchCheckOkTile = false; - if(networkGameDataSynchCheckOkTech) networkGameDataSynchCheckOkTech = false; + this->networkGameDataSynchCheckOkMap = false; + this->networkGameDataSynchCheckOkTile = false; + this->networkGameDataSynchCheckOkTech = false; + this->setNetworkGameDataSynchCheckTechMismatchReport(""); this->setReceivedDataSynchCheck(false); - // Is the listener socket ready to be read? - if(checkForNewClients == true && this->canAcceptConnections == true) { + this->clearChatInfo(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] BEFORE accept new client connection, serverInterface->getOpenSlotCount() = %d\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getOpenSlotCount()); + this->setSocket(NULL); + this->slotThreadWorker = NULL; + static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); + this->slotThreadWorker = new ConnectionSlotThread(this->serverInterface, playerIndex); + this->slotThreadWorker->setUniqueID(mutexOwnerId); + this->slotThreadWorker->start(); + } - //printf("Checking for new connections...\n"); - bool hasData = (serverInterface->getServerSocket() != NULL && - serverInterface->getServerSocket()->hasDataToRead() == true); - //printf("Server socket hasData: %d\n",hasData); + ConnectionSlot::~ConnectionSlot() { + //printf("===> Destructor for ConnectionSlot = %d\n",playerIndex); - if(hasData == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to accept new client connection playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] START\n", __FILE__, __FUNCTION__, __LINE__); - Socket *newSocket = serverInterface->getServerSocket()->accept(false); + //printf("Deleting connection slot\n"); + close(); - //printf("Server socket newSocket: %p\n",newSocket); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] called accept new client connection playerIndex = %d newSocket = %p\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,newSocket); - if(newSocket != NULL) { - // Set Socket as non-blocking - newSocket->setBlock(false); + //printf("#1 Ending client SLOT: %d slotThreadWorker: %p\n",playerIndex,slotThreadWorker); + if (slotThreadWorker != NULL) { + slotThreadWorker->signalQuit(); + } + if (slotThreadWorker != NULL && + slotThreadWorker->canShutdown(false) == true && + slotThreadWorker->getRunningStatus() == false) { + //printf("#2 Ending client SLOT: %d\n",playerIndex); - MutexSafeWrapper safeMutex(mutexCloseConnection,CODE_AT_LINE); - this->setSocket(newSocket); - safeMutex.ReleaseLock(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - this->connectedTime = time(NULL); - this->clearChatInfo(); - this->name = ""; - this->playerStatus = npst_PickSettings; - this->playerLanguage = ""; - this->playerUUID = ""; - this->platform = ""; - this->ready = false; - this->vctFileList.clear(); - this->receivedNetworkGameStatus = false; - this->gotIntro = false; + delete slotThreadWorker; - MutexSafeWrapper safeMutexSlot1(mutexPendingNetworkCommandList,CODE_AT_LINE); - this->vctPendingNetworkCommandList.clear(); - safeMutexSlot1.ReleaseLock(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } else if (slotThreadWorker != NULL && + slotThreadWorker->canShutdown(true) == true) { - this->currentFrameCount = 0; - this->currentLagCount = 0; - this->lastReceiveCommandListTime = 0; - this->gotLagCountWarning = false; - this->versionString = ""; + if (slotThreadWorker->getRunningStatus() == false) { + //printf("#3 Ending client SLOT: %d\n",playerIndex); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - serverInterface->updateListen(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex); - } - else { - close(); - return; - } + delete slotThreadWorker; - //send intro message when connected - if(this->isConnected() == true) { - //printf("Server socket newSocket is connected: %d\n",playerIndex); - - Chrono seed(true); - srand((unsigned int)seed.getCurTicks() / (this->playerIndex + 1)); - - sessionKey = rand() % 1000000; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] accepted new client connection, serverInterface->getOpenSlotCount() = %d, sessionKey = %d\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getOpenSlotCount(),sessionKey); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] client will be assigned to the next open slot\n",__FILE__,__FUNCTION__,__LINE__); - - NetworkMessageIntro networkMessageIntro( - sessionKey, - getNetworkVersionGITString(), - getHostName(), - playerIndex, - nmgstOk, - 0, - ServerSocket::getFTPServerPort(), - "", - serverInterface->getGameHasBeenInitiated(), - Config::getInstance().getString("PlayerId",""), - getPlatformNameString()); - sendMessage(&networkMessageIntro); - - if(this->serverInterface->getGameHasBeenInitiated() == true) { - setGameStarted(true); - } - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } else { + slotThreadWorker->setDeleteSelfOnExecutionDone(true); + slotThreadWorker->setDeleteAfterExecute(true); } } + //printf("#4 Ending client SLOT: %d\n",playerIndex); + slotThreadWorker = NULL; + + delete socketSynchAccessor; + socketSynchAccessor = NULL; + + delete mutexPendingNetworkCommandList; + mutexPendingNetworkCommandList = NULL; + + delete mutexCloseConnection; + mutexCloseConnection = NULL; + + delete mutexSocket; + mutexSocket = NULL; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] END\n", __FILE__, __FUNCTION__); } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(socketInfo.first == true) { - this->clearChatInfo(); + int ConnectionSlot::getAutoPauseGameCountForLag() { + return autoPauseGameCountForLag; + } - bool gotTextMsg = true; - bool gotCellMarkerMsg = true; - bool waitForLaggingClient = false; - bool waitedForLaggingClient = false; + void ConnectionSlot::incrementAutoPauseGameCountForLag() { + autoPauseGameCountForLag++; + } - //printf("Update slot: %d this->hasDataToRead(): %d\n",this->playerIndex,this->hasDataToRead()); + bool ConnectionSlot::getGameStarted() { + bool result = false; + if (this->slotThreadWorker != NULL) { + result = this->slotThreadWorker->getGameStarted(); + } + return result; + } + void ConnectionSlot::setGameStarted(bool value) { + if (this->slotThreadWorker != NULL) { + this->slotThreadWorker->setGameStarted(value); + } + } - for(;waitForLaggingClient == true || - (this->hasDataToRead() == true && - (gotTextMsg == true || gotCellMarkerMsg == true));) { + void ConnectionSlot::setPlayerIndex(int value) { + playerIndex = value; - //printf("Server slot checking for waitForLaggingClient = %d this->hasDataToRead() = %d gotTextMsg = %d gotCellMarkerMsg = %d\n",waitForLaggingClient,this->hasDataToRead(),gotTextMsg,gotCellMarkerMsg); + if (this->slotThreadWorker != NULL) { + this->slotThreadWorker->setSlotIndex(playerIndex); + } + } - waitForLaggingClient = false; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] polling for networkMessageType...\n",__FILE__,__FUNCTION__,__LINE__); + void ConnectionSlot::setReady() { + this->ready = true; + this->skipLagCheck = false; + this->joinGameInProgress = false; + this->sentSavedGameInfo = false; + } - NetworkMessageType networkMessageType= getNextMessageType(); + void ConnectionSlot::updateSlot(ConnectionSlotEvent *event) { + if (event != NULL) { + bool &socketTriggered = event->socketTriggered; + bool checkForNewClients = + (serverInterface->getGameHasBeenInitiated() == false || + serverInterface->getAllowInGameConnections() == true); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] networkMessageType = %d\n",__FILE__,__FUNCTION__,__LINE__,networkMessageType); + //if((serverInterface->getGameHasBeenInitiated() == false || + // (serverInterface->getAllowInGameConnections() == true && this->isConnected() == false) || + // socketTriggered == true)) { + if (socketTriggered == true || + ((serverInterface->getGameHasBeenInitiated() == false || + serverInterface->getAllowInGameConnections() == true) && + this->isConnected() == false)) { - gotTextMsg = false; - gotCellMarkerMsg = false; - //process incoming commands - switch(networkMessageType) { + this->update(checkForNewClients, event->triggerId); + } + //} + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } - case nmtInvalid: - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtInvalid\n",__FILE__,__FUNCTION__,__LINE__); - break; + string ConnectionSlot::getIpAddress(bool mutexLock) { + string result = ""; + MutexSafeWrapper safeMutexSlot((mutexLock == true ? mutexSocket : NULL), CODE_AT_LINE); + if (socket != NULL) { + result = socket->getIpAddress(); + } + return result; + } - case nmtPing: - { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtPing\n",__FILE__,__FUNCTION__); + void ConnectionSlot::update(bool checkForNewClients, int lockedSlotIndex) { + try { + clearThreadErrorList(); - // client REQUIRES a ping before completing intro - // authentication - NetworkMessagePing networkMessagePing; - if(receiveMessage(&networkMessagePing)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - lastPingInfo = networkMessagePing; - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + if (slotThreadWorker != NULL) { + slotThreadWorker->purgeCompletedEvents(); + } + + pair socketInfo = this->getSocketInfo(); + if (socketInfo.second == NULL) { + if (networkGameDataSynchCheckOkMap) networkGameDataSynchCheckOkMap = false; + if (networkGameDataSynchCheckOkTile) networkGameDataSynchCheckOkTile = false; + if (networkGameDataSynchCheckOkTech) networkGameDataSynchCheckOkTech = false; + this->setReceivedDataSynchCheck(false); + + // Is the listener socket ready to be read? + if (checkForNewClients == true && this->canAcceptConnections == true) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] BEFORE accept new client connection, serverInterface->getOpenSlotCount() = %d\n", __FILE__, __FUNCTION__, __LINE__, serverInterface->getOpenSlotCount()); + + //printf("Checking for new connections...\n"); + bool hasData = (serverInterface->getServerSocket() != NULL && + serverInterface->getServerSocket()->hasDataToRead() == true); + //printf("Server socket hasData: %d\n",hasData); + + if (hasData == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] about to accept new client connection playerIndex = %d\n", __FILE__, __FUNCTION__, __LINE__, playerIndex); + + Socket *newSocket = serverInterface->getServerSocket()->accept(false); + + //printf("Server socket newSocket: %p\n",newSocket); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] called accept new client connection playerIndex = %d newSocket = %p\n", __FILE__, __FUNCTION__, __LINE__, playerIndex, newSocket); + if (newSocket != NULL) { + // Set Socket as non-blocking + newSocket->setBlock(false); + + MutexSafeWrapper safeMutex(mutexCloseConnection, CODE_AT_LINE); + this->setSocket(newSocket); + safeMutex.ReleaseLock(); + + this->connectedTime = time(NULL); + this->clearChatInfo(); + this->name = ""; + this->playerStatus = npst_PickSettings; + this->playerLanguage = ""; + this->playerUUID = ""; + this->platform = ""; + this->ready = false; + this->vctFileList.clear(); + this->receivedNetworkGameStatus = false; + this->gotIntro = false; + + MutexSafeWrapper safeMutexSlot1(mutexPendingNetworkCommandList, CODE_AT_LINE); + this->vctPendingNetworkCommandList.clear(); + safeMutexSlot1.ReleaseLock(); + + this->currentFrameCount = 0; + this->currentLagCount = 0; + this->lastReceiveCommandListTime = 0; + this->gotLagCountWarning = false; + this->versionString = ""; + + serverInterface->updateListen(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] playerIndex = %d\n", __FILE__, __FUNCTION__, __LINE__, playerIndex); + } else { close(); return; } - } - break; - case nmtText: - { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtText gotIntro = %d\n",__FILE__,__FUNCTION__,__LINE__,gotIntro); + //send intro message when connected + if (this->isConnected() == true) { + //printf("Server socket newSocket is connected: %d\n",playerIndex); - if(gotIntro == true) { - NetworkMessageText networkMessageText; - if(receiveMessage(&networkMessageText)) { - ChatMsgInfo msg(networkMessageText.getText().c_str(),networkMessageText.getTeamIndex(),networkMessageText.getPlayerIndex(),networkMessageText.getTargetLanguage()); - this->addChatInfo(msg); - gotTextMsg = true; + Chrono seed(true); + srand((unsigned int) seed.getCurTicks() / (this->playerIndex + 1)); + + sessionKey = rand() % 1000000; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] accepted new client connection, serverInterface->getOpenSlotCount() = %d, sessionKey = %d\n", __FILE__, __FUNCTION__, __LINE__, serverInterface->getOpenSlotCount(), sessionKey); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] client will be assigned to the next open slot\n", __FILE__, __FUNCTION__, __LINE__); + + NetworkMessageIntro networkMessageIntro( + sessionKey, + getNetworkVersionGITString(), + getHostName(), + playerIndex, + nmgstOk, + 0, + ServerSocket::getFTPServerPort(), + "", + serverInterface->getGameHasBeenInitiated(), + Config::getInstance().getString("PlayerId", ""), + getPlatformNameString()); + sendMessage(&networkMessageIntro); + + if (this->serverInterface->getGameHasBeenInitiated() == true) { + setGameStarted(true); } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; } } - break; + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - case nmtMarkCell: - { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtMarkCell gotIntro = %d\n",__FILE__,__FUNCTION__,__LINE__,gotIntro); + if (socketInfo.first == true) { + this->clearChatInfo(); - if(gotIntro == true) { - NetworkMessageMarkCell networkMessageMarkCell; - if(receiveMessage(&networkMessageMarkCell)) { - MarkedCell msg(networkMessageMarkCell.getTarget(), - networkMessageMarkCell.getFactionIndex(), - networkMessageMarkCell.getText().c_str(), - networkMessageMarkCell.getPlayerIndex()); + bool gotTextMsg = true; + bool gotCellMarkerMsg = true; + bool waitForLaggingClient = false; + bool waitedForLaggingClient = false; - this->addMarkedCell(msg); - gotCellMarkerMsg = true; - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - break; + //printf("Update slot: %d this->hasDataToRead(): %d\n",this->playerIndex,this->hasDataToRead()); - case nmtUnMarkCell: - { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtUnMarkCell gotIntro = %d\n",__FILE__,__FUNCTION__,__LINE__,gotIntro); + for (; waitForLaggingClient == true || + (this->hasDataToRead() == true && + (gotTextMsg == true || gotCellMarkerMsg == true));) { - if(gotIntro == true) { - NetworkMessageUnMarkCell networkMessageMarkCell; - if(receiveMessage(&networkMessageMarkCell)) { - UnMarkedCell msg(networkMessageMarkCell.getTarget(), - networkMessageMarkCell.getFactionIndex()); + //printf("Server slot checking for waitForLaggingClient = %d this->hasDataToRead() = %d gotTextMsg = %d gotCellMarkerMsg = %d\n",waitForLaggingClient,this->hasDataToRead(),gotTextMsg,gotCellMarkerMsg); - this->addUnMarkedCell(msg); - gotCellMarkerMsg = true; - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - break; + waitForLaggingClient = false; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] polling for networkMessageType...\n", __FILE__, __FUNCTION__, __LINE__); - case nmtHighlightCell: - { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtMarkCell gotIntro = %d\n",__FILE__,__FUNCTION__,__LINE__,gotIntro); + NetworkMessageType networkMessageType = getNextMessageType(); - if(gotIntro == true) { - NetworkMessageHighlightCell networkMessageHighlightCell; - if(receiveMessage(&networkMessageHighlightCell)) { - MarkedCell msg(networkMessageHighlightCell.getTarget(), - networkMessageHighlightCell.getFactionIndex(),"none",-1); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] networkMessageType = %d\n", __FILE__, __FUNCTION__, __LINE__, networkMessageType); - this->setHighlightedCell(msg); - gotCellMarkerMsg = true; - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - break; + gotTextMsg = false; + gotCellMarkerMsg = false; + //process incoming commands + switch (networkMessageType) { - //command list - case nmtCommandList: { + case nmtInvalid: + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got nmtInvalid\n", __FILE__, __FUNCTION__, __LINE__); + break; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtCommandList gotIntro = %d\n",__FILE__,__FUNCTION__,__LINE__,gotIntro); + case nmtPing: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] got nmtPing\n", __FILE__, __FUNCTION__); - if(gotIntro == true) { - NetworkMessageCommandList networkMessageCommandList; - if(receiveMessage(&networkMessageCommandList)) { - currentFrameCount = networkMessageCommandList.getFrameCount(); - lastReceiveCommandListTime = time(NULL); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] currentFrameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,currentFrameCount); - - MutexSafeWrapper safeMutexSlot(mutexPendingNetworkCommandList,CODE_AT_LINE); - for(int i = 0; i < networkMessageCommandList.getCommandCount(); ++i) { - vctPendingNetworkCommandList.push_back(*networkMessageCommandList.getCommand(i)); + // client REQUIRES a ping before completing intro + // authentication + NetworkMessagePing networkMessagePing; + if (receiveMessage(&networkMessagePing)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + lastPingInfo = networkMessagePing; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } - //printf("Got commands from client frame: %d count: %d\n",currentFrameCount,vctPendingNetworkCommandList.size()); - - //printf("#2 Server slot got currentFrameCount = %d\n",currentFrameCount); } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - break; + break; - //process intro messages - case nmtIntro: - { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtIntro\n",__FILE__,__FUNCTION__); + case nmtText: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got nmtText gotIntro = %d\n", __FILE__, __FUNCTION__, __LINE__, gotIntro); - NetworkMessageIntro networkMessageIntro; - if(receiveMessage(&networkMessageIntro)) { - int32 msgSessionId = networkMessageIntro.getSessionId(); - this->name= networkMessageIntro.getName(); - this->versionString = networkMessageIntro.getVersionString(); - this->connectedRemoteIPAddress = networkMessageIntro.getExternalIp(); - this->playerLanguage = networkMessageIntro.getPlayerLanguage(); - this->playerUUID = networkMessageIntro.getPlayerUUID(); - this->platform = networkMessageIntro.getPlayerPlatform(); - - //printf("Got uuid from client [%s]\n",this->playerUUID.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got name [%s] versionString [%s], msgSessionId = %d\n",__FILE__,__FUNCTION__,name.c_str(),versionString.c_str(),msgSessionId); - - if(msgSessionId != sessionKey) { - string playerNameStr = name; - string sErr = "Client gave invalid sessionid for player [" + playerNameStr + "] actual [" + intToStr(msgSessionId) + "] expected [" + intToStr(sessionKey) + "]"; - printf("%s\n",sErr.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,sErr.c_str()); - - close(); - return; - } - else if(this->playerUUID == "") { - string playerNameStr = name; - string sErr = "Client gave an invalid UUID for player [" + playerNameStr + "]"; - printf("%s\n",sErr.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,sErr.c_str()); - - close(); - return; - } - else { - //check consistency - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - bool compatible = checkVersionComptability(getNetworkVersionGITString(), networkMessageIntro.getVersionString()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(compatible == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - bool versionMatched = false; - string platformFreeVersion = getNetworkPlatformFreeVersionString(); - string sErr = ""; - - if(strncmp(platformFreeVersion.c_str(),networkMessageIntro.getVersionString().c_str(),strlen(platformFreeVersion.c_str())) != 0) { - string playerNameStr = name; - sErr = "Server and client binary mismatch!\nYou have to use the exactly same binaries!\n\nServer: " + getNetworkVersionGITString() + - "\nClient: " + networkMessageIntro.getVersionString() + " player [" + playerNameStr + "]"; - printf("%s\n",sErr.c_str()); - - serverInterface->sendTextMessage("Server and client binary mismatch!!",-1, true,"",lockedSlotIndex); - serverInterface->sendTextMessage(" Server:" + getNetworkVersionGITString(),-1, true,"",lockedSlotIndex); - serverInterface->sendTextMessage(" Client: "+ networkMessageIntro.getVersionString(),-1, true,"",lockedSlotIndex); - serverInterface->sendTextMessage(" Client player [" + playerNameStr + "]",-1, true,"",lockedSlotIndex); - } - else { - versionMatched = true; - - string playerNameStr = name; - sErr = "Warning, Server and client are using the same version but different platforms.\n\nServer: " + getNetworkVersionGITString() + - "\nClient: " + networkMessageIntro.getVersionString() + " player [" + playerNameStr + "]"; - //printf("%s\n",sErr.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,sErr.c_str()); - } - - if(Config::getInstance().getBool("PlatformConsistencyChecks","true") && - versionMatched == false) { // error message and disconnect only if checked - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,sErr.c_str()); + if (gotIntro == true) { + NetworkMessageText networkMessageText; + if (receiveMessage(&networkMessageText)) { + ChatMsgInfo msg(networkMessageText.getText().c_str(), networkMessageText.getTeamIndex(), networkMessageText.getPlayerIndex(), networkMessageText.getTargetLanguage()); + this->addChatInfo(msg); + gotTextMsg = true; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); close(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,sErr.c_str()); return; } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - gotIntro = true; - - int factionIndex = this->serverInterface->gameSettings.getFactionIndexForStartLocation(playerIndex); - this->serverInterface->addClientToServerIPAddress(this->getSocket()->getConnectedIPAddress(this->getSocket()->getIpAddress()),this->connectedRemoteIPAddress); - - this->serverInterface->gameSettings.setNetworkPlayerUUID(factionIndex,this->playerUUID); - this->serverInterface->gameSettings.setNetworkPlayerPlatform(factionIndex,this->platform); - - if(serverInterface->getGameHasBeenInitiated() == true && - serverInterface->getAllowInGameConnections() == true) { - this->serverInterface->gameSettings.setNetworkPlayerStatuses(factionIndex,npst_None); - } - - if(getAllowGameDataSynchCheck() == true && serverInterface->getGameSettings() != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] sending NetworkMessageSynchNetworkGameData\n",__FILE__,__FUNCTION__,__LINE__); - - NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData(serverInterface->getGameSettings()); - sendMessage(&networkMessageSynchNetworkGameData); - } - - if(serverInterface->getGameHasBeenInitiated() == true && - serverInterface->getAllowInGameConnections() == true) { - - ConnectionSlot *slot = serverInterface->findSlotForUUID(this->playerUUID,true); - if(slot != NULL) { - slot->setJoinGameInProgressFlags(); - slot->setPauseForInGameConnection(true); - - serverInterface->switchSlot(this->playerIndex,slot->getPlayerIndex()); - } - else { - setJoinGameInProgressFlags(); - this->setPauseForInGameConnection(true); - } - } - else { - ConnectionSlot *slot = serverInterface->findSlotForUUID(this->playerUUID,true); - if(slot != NULL) { - serverInterface->switchSlot(this->playerIndex,slot->getPlayerIndex()); - } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - break; + break; - case nmtLaunch: - case nmtBroadCastSetup: - { - if(gotIntro == true) { - if(this->serverInterface->getGameSettings() == NULL || - (joinGameInProgress == false && sessionKey != this->serverInterface->getGameSettings()->getMasterserver_admin())) { - string playerNameStr = name; - string sErr = "Client has invalid admin sessionid for player [" + playerNameStr + "]"; - printf("%s\n",sErr.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,sErr.c_str()); + case nmtMarkCell: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got nmtMarkCell gotIntro = %d\n", __FILE__, __FUNCTION__, __LINE__, gotIntro); - close(); - return; + if (gotIntro == true) { + NetworkMessageMarkCell networkMessageMarkCell; + if (receiveMessage(&networkMessageMarkCell)) { + MarkedCell msg(networkMessageMarkCell.getTarget(), + networkMessageMarkCell.getFactionIndex(), + networkMessageMarkCell.getText().c_str(), + networkMessageMarkCell.getPlayerIndex()); + + this->addMarkedCell(msg); + gotCellMarkerMsg = true; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } } + break; - NetworkMessageLaunch networkMessageLaunch; - if(receiveMessage(&networkMessageLaunch,networkMessageType)) { - if(networkMessageLaunch.getMessageType() == nmtLaunch) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got nmtLaunch\n",__FILE__,__FUNCTION__,__LINE__); - //printf("Got launch request from client joinGameInProgress = %d joinGameInProgress = %d!\n",joinGameInProgress,joinGameInProgress); + case nmtUnMarkCell: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got nmtUnMarkCell gotIntro = %d\n", __FILE__, __FUNCTION__, __LINE__, gotIntro); + + if (gotIntro == true) { + NetworkMessageUnMarkCell networkMessageMarkCell; + if (receiveMessage(&networkMessageMarkCell)) { + UnMarkedCell msg(networkMessageMarkCell.getTarget(), + networkMessageMarkCell.getFactionIndex()); + + this->addUnMarkedCell(msg); + gotCellMarkerMsg = true; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } - else if(networkMessageLaunch.getMessageType() == nmtBroadCastSetup) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got nmtBroadCastSetup\n",__FILE__,__FUNCTION__,__LINE__); + } + break; + + case nmtHighlightCell: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got nmtMarkCell gotIntro = %d\n", __FILE__, __FUNCTION__, __LINE__, gotIntro); + + if (gotIntro == true) { + NetworkMessageHighlightCell networkMessageHighlightCell; + if (receiveMessage(&networkMessageHighlightCell)) { + MarkedCell msg(networkMessageHighlightCell.getTarget(), + networkMessageHighlightCell.getFactionIndex(), "none", -1); + + this->setHighlightedCell(msg); + gotCellMarkerMsg = true; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Lined: %d] got networkMessageLaunch.getMessageType() = %d\n",__FILE__,__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType()); + } + break; - char szBuf[1024]=""; - snprintf(szBuf,1023,"In [%s::%s Line: %d] Invalid networkMessageLaunch.getMessageType() = %d",__FILE__,__FUNCTION__,__LINE__,networkMessageLaunch.getMessageType()); - throw megaglest_runtime_error(szBuf); - } + //command list + case nmtCommandList: { - int minHeadLessPlayersRequired = Config::getInstance().getInt("MinHeadlessPlayersRequired","2"); - if(this->joinGameInProgress == false && - networkMessageLaunch.getMessageType() == nmtLaunch && - this->ready == false && - this->serverInterface->getConnectedSlotCount(true) < minHeadLessPlayersRequired) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got nmtCommandList gotIntro = %d\n", __FILE__, __FUNCTION__, __LINE__, gotIntro); - Lang &lang= Lang::getInstance(); - const vector languageList = this->serverInterface->getGameSettings()->getUniqueNetworkPlayerLanguages(); - for(unsigned int index = 0; index < languageList.size(); ++index) { - char szBuf[4096]=""; - string msgTemplate = "You must have have at least %d player(s) connected to start this game!"; - if(lang.hasString("HeadlessAdminRequiresMorePlayers",languageList[index]) == true) { - msgTemplate = lang.getString("HeadlessAdminRequiresMorePlayers",languageList[index]); + if (gotIntro == true) { + NetworkMessageCommandList networkMessageCommandList; + if (receiveMessage(&networkMessageCommandList)) { + currentFrameCount = networkMessageCommandList.getFrameCount(); + lastReceiveCommandListTime = time(NULL); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] currentFrameCount = %d\n", __FILE__, __FUNCTION__, __LINE__, currentFrameCount); + + MutexSafeWrapper safeMutexSlot(mutexPendingNetworkCommandList, CODE_AT_LINE); + for (int i = 0; i < networkMessageCommandList.getCommandCount(); ++i) { + vctPendingNetworkCommandList.push_back(*networkMessageCommandList.getCommand(i)); } - #ifdef WIN32 - _snprintf(szBuf,4095,msgTemplate.c_str(),minHeadLessPlayersRequired); - #else - snprintf(szBuf,4095,msgTemplate.c_str(),minHeadLessPlayersRequired); - #endif - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,szBuf); + //printf("Got commands from client frame: %d count: %d\n",currentFrameCount,vctPendingNetworkCommandList.size()); - string sMsg = szBuf; - bool echoLocal = lang.isLanguageLocal(languageList[index]); - this->serverInterface->sendTextMessage(sMsg,-1, echoLocal, languageList[index], this->getPlayerIndex()); - } + //printf("#2 Server slot got currentFrameCount = %d\n",currentFrameCount); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } - else { - if(this->joinGameInProgress == false) { - GameSettings gameSettingsBuffer; - networkMessageLaunch.buildGameSettings(&gameSettingsBuffer); + } + break; - //printf("Connection slot got networkMessageLaunch.getMessageType() = %d, got map [%s]\n",networkMessageLaunch.getMessageType(),gameSettings.getMap().c_str()); - //printf("\n\n\n\n=====Connection slot got settings:\n%s\n",gameSettings.toString().c_str()); + //process intro messages + case nmtIntro: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] got nmtIntro\n", __FILE__, __FUNCTION__); - this->serverInterface->broadcastGameSetup(&gameSettingsBuffer, true); - } + NetworkMessageIntro networkMessageIntro; + if (receiveMessage(&networkMessageIntro)) { + int32 msgSessionId = networkMessageIntro.getSessionId(); + this->name = networkMessageIntro.getName(); + this->versionString = networkMessageIntro.getVersionString(); + this->connectedRemoteIPAddress = networkMessageIntro.getExternalIp(); + this->playerLanguage = networkMessageIntro.getPlayerLanguage(); + this->playerUUID = networkMessageIntro.getPlayerUUID(); + this->platform = networkMessageIntro.getPlayerPlatform(); - if(this->joinGameInProgress == false && - networkMessageLaunch.getMessageType() == nmtLaunch) { + //printf("Got uuid from client [%s]\n",this->playerUUID.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] got name [%s] versionString [%s], msgSessionId = %d\n", __FILE__, __FUNCTION__, name.c_str(), versionString.c_str(), msgSessionId); - this->serverInterface->setMasterserverAdminRequestLaunch(true); - } - else if(this->joinGameInProgress == true && - networkMessageLaunch.getMessageType() == nmtLaunch) { - //printf("!!! setStartInGameConnectionLaunch for client joinGameInProgress = %d!\n",joinGameInProgress); + if (msgSessionId != sessionKey) { + string playerNameStr = name; + string sErr = "Client gave invalid sessionid for player [" + playerNameStr + "] actual [" + intToStr(msgSessionId) + "] expected [" + intToStr(sessionKey) + "]"; + printf("%s\n", sErr.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] %s\n", __FILE__, __FUNCTION__, __LINE__, sErr.c_str()); + + close(); + return; + } else if (this->playerUUID == "") { + string playerNameStr = name; + string sErr = "Client gave an invalid UUID for player [" + playerNameStr + "]"; + printf("%s\n", sErr.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] %s\n", __FILE__, __FUNCTION__, __LINE__, sErr.c_str()); + + close(); + return; + } else { + //check consistency + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + bool compatible = checkVersionComptability(getNetworkVersionGITString(), networkMessageIntro.getVersionString()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (compatible == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + bool versionMatched = false; + string platformFreeVersion = getNetworkPlatformFreeVersionString(); + string sErr = ""; + + if (strncmp(platformFreeVersion.c_str(), networkMessageIntro.getVersionString().c_str(), strlen(platformFreeVersion.c_str())) != 0) { + string playerNameStr = name; + sErr = "Server and client binary mismatch!\nYou have to use the exactly same binaries!\n\nServer: " + getNetworkVersionGITString() + + "\nClient: " + networkMessageIntro.getVersionString() + " player [" + playerNameStr + "]"; + printf("%s\n", sErr.c_str()); + + serverInterface->sendTextMessage("Server and client binary mismatch!!", -1, true, "", lockedSlotIndex); + serverInterface->sendTextMessage(" Server:" + getNetworkVersionGITString(), -1, true, "", lockedSlotIndex); + serverInterface->sendTextMessage(" Client: " + networkMessageIntro.getVersionString(), -1, true, "", lockedSlotIndex); + serverInterface->sendTextMessage(" Client player [" + playerNameStr + "]", -1, true, "", lockedSlotIndex); + } else { + versionMatched = true; + + string playerNameStr = name; + sErr = "Warning, Server and client are using the same version but different platforms.\n\nServer: " + getNetworkVersionGITString() + + "\nClient: " + networkMessageIntro.getVersionString() + " player [" + playerNameStr + "]"; + //printf("%s\n",sErr.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] %s\n", __FILE__, __FUNCTION__, __LINE__, sErr.c_str()); + } + + if (Config::getInstance().getBool("PlatformConsistencyChecks", "true") && + versionMatched == false) { // error message and disconnect only if checked + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] %s\n", __FILE__, __FUNCTION__, __LINE__, sErr.c_str()); + close(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] %s\n", __FILE__, __FUNCTION__, __LINE__, sErr.c_str()); + return; + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + gotIntro = true; int factionIndex = this->serverInterface->gameSettings.getFactionIndexForStartLocation(playerIndex); - this->serverInterface->gameSettings.setFactionControl(factionIndex,ctNetwork); - this->serverInterface->gameSettings.setNetworkPlayerName(factionIndex,this->name); - this->serverInterface->gameSettings.setNetworkPlayerUUID(factionIndex,this->playerUUID); - this->serverInterface->gameSettings.setNetworkPlayerPlatform(factionIndex,this->platform); + this->serverInterface->addClientToServerIPAddress(this->getSocket()->getConnectedIPAddress(this->getSocket()->getIpAddress()), this->connectedRemoteIPAddress); - if(this->serverInterface->gameSettings.getNetworkPlayerStatuses(factionIndex) == npst_Disconnected) { - this->serverInterface->gameSettings.setNetworkPlayerStatuses(factionIndex,npst_None); + this->serverInterface->gameSettings.setNetworkPlayerUUID(factionIndex, this->playerUUID); + this->serverInterface->gameSettings.setNetworkPlayerPlatform(factionIndex, this->platform); + + if (serverInterface->getGameHasBeenInitiated() == true && + serverInterface->getAllowInGameConnections() == true) { + this->serverInterface->gameSettings.setNetworkPlayerStatuses(factionIndex, npst_None); } - this->serverInterface->broadcastGameSetup(&this->serverInterface->gameSettings, true); + if (getAllowGameDataSynchCheck() == true && serverInterface->getGameSettings() != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] sending NetworkMessageSynchNetworkGameData\n", __FILE__, __FUNCTION__, __LINE__); - this->setStartInGameConnectionLaunch(true); + NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData(serverInterface->getGameSettings()); + sendMessage(&networkMessageSynchNetworkGameData); + } + + if (serverInterface->getGameHasBeenInitiated() == true && + serverInterface->getAllowInGameConnections() == true) { + + ConnectionSlot *slot = serverInterface->findSlotForUUID(this->playerUUID, true); + if (slot != NULL) { + slot->setJoinGameInProgressFlags(); + slot->setPauseForInGameConnection(true); + + serverInterface->switchSlot(this->playerIndex, slot->getPlayerIndex()); + } else { + setJoinGameInProgressFlags(); + this->setPauseForInGameConnection(true); + } + } else { + ConnectionSlot *slot = serverInterface->findSlotForUUID(this->playerUUID, true); + if (slot != NULL) { + serverInterface->switchSlot(this->playerIndex, slot->getPlayerIndex()); + } + } } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - break; + break; - //process datasynch messages - case nmtSynchNetworkGameDataStatus: - { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtSynchNetworkGameDataStatus, gotIntro = %d\n",__FILE__,__FUNCTION__,__LINE__,gotIntro); + case nmtLaunch: + case nmtBroadCastSetup: + { + if (gotIntro == true) { + if (this->serverInterface->getGameSettings() == NULL || + (joinGameInProgress == false && sessionKey != this->serverInterface->getGameSettings()->getMasterserver_admin())) { + string playerNameStr = name; + string sErr = "Client has invalid admin sessionid for player [" + playerNameStr + "]"; + printf("%s\n", sErr.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] %s\n", __FILE__, __FUNCTION__, __LINE__, sErr.c_str()); - if(gotIntro == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - NetworkMessageSynchNetworkGameDataStatus networkMessageSynchNetworkGameDataStatus; - if(receiveMessage(&networkMessageSynchNetworkGameDataStatus)) { - this->setNetworkGameDataSynchCheckTechMismatchReport(""); - this->setReceivedDataSynchCheck(false); - - Config &config = Config::getInstance(); - string scenarioDir = ""; - if(serverInterface->getGameSettings()->getScenarioDir() != "") { - scenarioDir = serverInterface->getGameSettings()->getScenarioDir(); - if(EndsWith(scenarioDir, ".xml") == true) { - scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4); - scenarioDir = scenarioDir.erase(scenarioDir.size() - serverInterface->getGameSettings()->getScenario().size(), serverInterface->getGameSettings()->getScenario().size() + 1); + close(); + return; } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getGameSettings()->getScenarioDir().c_str(),serverInterface->getGameSettings()->getScenario().c_str(),scenarioDir.c_str()); + NetworkMessageLaunch networkMessageLaunch; + if (receiveMessage(&networkMessageLaunch, networkMessageType)) { + if (networkMessageLaunch.getMessageType() == nmtLaunch) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Lined: %d] got nmtLaunch\n", __FILE__, __FUNCTION__, __LINE__); + //printf("Got launch request from client joinGameInProgress = %d joinGameInProgress = %d!\n",joinGameInProgress,joinGameInProgress); + } else if (networkMessageLaunch.getMessageType() == nmtBroadCastSetup) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Lined: %d] got nmtBroadCastSetup\n", __FILE__, __FUNCTION__, __LINE__); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Lined: %d] got networkMessageLaunch.getMessageType() = %d\n", __FILE__, __FUNCTION__, __LINE__, networkMessageLaunch.getMessageType()); + + char szBuf[1024] = ""; + snprintf(szBuf, 1023, "In [%s::%s Line: %d] Invalid networkMessageLaunch.getMessageType() = %d", __FILE__, __FUNCTION__, __LINE__, networkMessageLaunch.getMessageType()); + throw megaglest_runtime_error(szBuf); + } + + int minHeadLessPlayersRequired = Config::getInstance().getInt("MinHeadlessPlayersRequired", "2"); + if (this->joinGameInProgress == false && + networkMessageLaunch.getMessageType() == nmtLaunch && + this->ready == false && + this->serverInterface->getConnectedSlotCount(true) < minHeadLessPlayersRequired) { + + Lang &lang = Lang::getInstance(); + const vector languageList = this->serverInterface->getGameSettings()->getUniqueNetworkPlayerLanguages(); + for (unsigned int index = 0; index < languageList.size(); ++index) { + char szBuf[4096] = ""; + string msgTemplate = "You must have have at least %d player(s) connected to start this game!"; + if (lang.hasString("HeadlessAdminRequiresMorePlayers", languageList[index]) == true) { + msgTemplate = lang.getString("HeadlessAdminRequiresMorePlayers", languageList[index]); + } +#ifdef WIN32 + _snprintf(szBuf, 4095, msgTemplate.c_str(), minHeadLessPlayersRequired); +#else + snprintf(szBuf, 4095, msgTemplate.c_str(), minHeadLessPlayersRequired); +#endif + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] %s\n", __FILE__, __FUNCTION__, __LINE__, szBuf); + + string sMsg = szBuf; + bool echoLocal = lang.isLanguageLocal(languageList[index]); + this->serverInterface->sendTextMessage(sMsg, -1, echoLocal, languageList[index], this->getPlayerIndex()); + } + } else { + if (this->joinGameInProgress == false) { + GameSettings gameSettingsBuffer; + networkMessageLaunch.buildGameSettings(&gameSettingsBuffer); + + //printf("Connection slot got networkMessageLaunch.getMessageType() = %d, got map [%s]\n",networkMessageLaunch.getMessageType(),gameSettings.getMap().c_str()); + //printf("\n\n\n\n=====Connection slot got settings:\n%s\n",gameSettings.toString().c_str()); + + this->serverInterface->broadcastGameSetup(&gameSettingsBuffer, true); + } + + if (this->joinGameInProgress == false && + networkMessageLaunch.getMessageType() == nmtLaunch) { + + this->serverInterface->setMasterserverAdminRequestLaunch(true); + } else if (this->joinGameInProgress == true && + networkMessageLaunch.getMessageType() == nmtLaunch) { + //printf("!!! setStartInGameConnectionLaunch for client joinGameInProgress = %d!\n",joinGameInProgress); + + int factionIndex = this->serverInterface->gameSettings.getFactionIndexForStartLocation(playerIndex); + this->serverInterface->gameSettings.setFactionControl(factionIndex, ctNetwork); + this->serverInterface->gameSettings.setNetworkPlayerName(factionIndex, this->name); + this->serverInterface->gameSettings.setNetworkPlayerUUID(factionIndex, this->playerUUID); + this->serverInterface->gameSettings.setNetworkPlayerPlatform(factionIndex, this->platform); + + if (this->serverInterface->gameSettings.getNetworkPlayerStatuses(factionIndex) == npst_Disconnected) { + this->serverInterface->gameSettings.setNetworkPlayerStatuses(factionIndex, npst_None); + } + + this->serverInterface->broadcastGameSetup(&this->serverInterface->gameSettings, true); + + this->setStartInGameConnectionLaunch(true); + } + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } + } + break; - //tileset - uint32 tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + serverInterface->getGameSettings()->getTileset() + string("/*"), ".xml", NULL); - uint32 techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,scenarioDir), "/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", NULL); - Checksum checksum; - string file = Config::getMapPath(serverInterface->getGameSettings()->getMap(),scenarioDir,false); - checksum.addFile(file); - uint32 mapCRC = checksum.getSum(); + //process datasynch messages + case nmtSynchNetworkGameDataStatus: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got nmtSynchNetworkGameDataStatus, gotIntro = %d\n", __FILE__, __FUNCTION__, __LINE__, gotIntro); - networkGameDataSynchCheckOkMap = (networkMessageSynchNetworkGameDataStatus.getMapCRC() == mapCRC); - networkGameDataSynchCheckOkTile = (networkMessageSynchNetworkGameDataStatus.getTilesetCRC() == tilesetCRC); - networkGameDataSynchCheckOkTech = (networkMessageSynchNetworkGameDataStatus.getTechCRC() == techCRC); + if (gotIntro == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - // For testing - //techCRC++; - - if( networkGameDataSynchCheckOkMap == true && - networkGameDataSynchCheckOkTile == true && - networkGameDataSynchCheckOkTech == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] client data synch ok\n",__FILE__,__FUNCTION__); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] mapCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,mapCRC,networkMessageSynchNetworkGameDataStatus.getMapCRC()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] tilesetCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,tilesetCRC,networkMessageSynchNetworkGameDataStatus.getTilesetCRC()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] techCRC = %d, remote = %d\n",__FILE__,__FUNCTION__,techCRC,networkMessageSynchNetworkGameDataStatus.getTechCRC()); - - if(allowDownloadDataSynch == true) { - // Now get all filenames with their CRC values and send to the client - vctFileList.clear(); + NetworkMessageSynchNetworkGameDataStatus networkMessageSynchNetworkGameDataStatus; + if (receiveMessage(&networkMessageSynchNetworkGameDataStatus)) { + this->setNetworkGameDataSynchCheckTechMismatchReport(""); + this->setReceivedDataSynchCheck(false); Config &config = Config::getInstance(); string scenarioDir = ""; - if(serverInterface->getGameSettings()->getScenarioDir() != "") { + if (serverInterface->getGameSettings()->getScenarioDir() != "") { scenarioDir = serverInterface->getGameSettings()->getScenarioDir(); - if(EndsWith(scenarioDir, ".xml") == true) { + if (EndsWith(scenarioDir, ".xml") == true) { scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4); scenarioDir = scenarioDir.erase(scenarioDir.size() - serverInterface->getGameSettings()->getScenario().size(), serverInterface->getGameSettings()->getScenario().size() + 1); } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getGameSettings()->getScenarioDir().c_str(),serverInterface->getGameSettings()->getScenario().c_str(),scenarioDir.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n", __FILE__, __FUNCTION__, __LINE__, serverInterface->getGameSettings()->getScenarioDir().c_str(), serverInterface->getGameSettings()->getScenario().c_str(), scenarioDir.c_str()); } - if(networkGameDataSynchCheckOkTile == false) { - if(tilesetCRC == 0) { - vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + serverInterface->getGameSettings()->getTileset() + string("/*"), "", &vctFileList); - } - else { - vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets,scenarioDir), "/" + serverInterface->getGameSettings()->getTileset() + "/*", ".xml", &vctFileList); - } - } - if(networkGameDataSynchCheckOkTech == false) { - if(techCRC == 0) { - vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),"/" + serverInterface->getGameSettings()->getTech() + "/*", "", &vctFileList); - } - else { - vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),"/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", &vctFileList); - } + //tileset + uint32 tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets, scenarioDir), string("/") + serverInterface->getGameSettings()->getTileset() + string("/*"), ".xml", NULL); + uint32 techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs, scenarioDir), "/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", NULL); + Checksum checksum; + string file = Config::getMapPath(serverInterface->getGameSettings()->getMap(), scenarioDir, false); + checksum.addFile(file); + uint32 mapCRC = checksum.getSum(); - string report = networkMessageSynchNetworkGameDataStatus.getTechCRCFileMismatchReport(serverInterface->getGameSettings()->getTech(),vctFileList); - this->setNetworkGameDataSynchCheckTechMismatchReport(report); - } - if(networkGameDataSynchCheckOkMap == false) { - vctFileList.push_back(std::pair(Config::getMapPath(serverInterface->getGameSettings()->getMap(),scenarioDir,false),mapCRC)); + networkGameDataSynchCheckOkMap = (networkMessageSynchNetworkGameDataStatus.getMapCRC() == mapCRC); + networkGameDataSynchCheckOkTile = (networkMessageSynchNetworkGameDataStatus.getTilesetCRC() == tilesetCRC); + networkGameDataSynchCheckOkTech = (networkMessageSynchNetworkGameDataStatus.getTechCRC() == techCRC); + + // For testing + //techCRC++; + + if (networkGameDataSynchCheckOkMap == true && + networkGameDataSynchCheckOkTile == true && + networkGameDataSynchCheckOkTech == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] client data synch ok\n", __FILE__, __FUNCTION__); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] mapCRC = %d, remote = %d\n", __FILE__, __FUNCTION__, mapCRC, networkMessageSynchNetworkGameDataStatus.getMapCRC()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] tilesetCRC = %d, remote = %d\n", __FILE__, __FUNCTION__, tilesetCRC, networkMessageSynchNetworkGameDataStatus.getTilesetCRC()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] techCRC = %d, remote = %d\n", __FILE__, __FUNCTION__, techCRC, networkMessageSynchNetworkGameDataStatus.getTechCRC()); + + if (allowDownloadDataSynch == true) { + // Now get all filenames with their CRC values and send to the client + vctFileList.clear(); + + Config &config = Config::getInstance(); + string scenarioDir = ""; + if (serverInterface->getGameSettings()->getScenarioDir() != "") { + scenarioDir = serverInterface->getGameSettings()->getScenarioDir(); + if (EndsWith(scenarioDir, ".xml") == true) { + scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4); + scenarioDir = scenarioDir.erase(scenarioDir.size() - serverInterface->getGameSettings()->getScenario().size(), serverInterface->getGameSettings()->getScenario().size() + 1); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n", __FILE__, __FUNCTION__, __LINE__, serverInterface->getGameSettings()->getScenarioDir().c_str(), serverInterface->getGameSettings()->getScenario().c_str(), scenarioDir.c_str()); + } + + if (networkGameDataSynchCheckOkTile == false) { + if (tilesetCRC == 0) { + vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets, scenarioDir), string("/") + serverInterface->getGameSettings()->getTileset() + string("/*"), "", &vctFileList); + } else { + vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTilesets, scenarioDir), "/" + serverInterface->getGameSettings()->getTileset() + "/*", ".xml", &vctFileList); + } + } + if (networkGameDataSynchCheckOkTech == false) { + if (techCRC == 0) { + vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs, scenarioDir), "/" + serverInterface->getGameSettings()->getTech() + "/*", "", &vctFileList); + } else { + vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs, scenarioDir), "/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", &vctFileList); + } + + string report = networkMessageSynchNetworkGameDataStatus.getTechCRCFileMismatchReport(serverInterface->getGameSettings()->getTech(), vctFileList); + this->setNetworkGameDataSynchCheckTechMismatchReport(report); + } + if (networkGameDataSynchCheckOkMap == false) { + vctFileList.push_back(std::pair(Config::getMapPath(serverInterface->getGameSettings()->getMap(), scenarioDir, false), mapCRC)); + } + + NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck((int) vctFileList.size(), 1, vctFileList[0].second, vctFileList[0].first); + sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck); + } else { + if (networkGameDataSynchCheckOkTech == false) { + vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs, scenarioDir), "/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", NULL); + + string report = networkMessageSynchNetworkGameDataStatus.getTechCRCFileMismatchReport(serverInterface->getGameSettings()->getTech(), vctFileList); + this->setNetworkGameDataSynchCheckTechMismatchReport(report); + } + } } - NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck((int)vctFileList.size(), 1, vctFileList[0].second, vctFileList[0].first); - sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck); - } - else { - if(networkGameDataSynchCheckOkTech == false) { - vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),"/" + serverInterface->getGameSettings()->getTech() + "/*", ".xml", NULL); - - string report = networkMessageSynchNetworkGameDataStatus.getTechCRCFileMismatchReport(serverInterface->getGameSettings()->getTech(),vctFileList); - this->setNetworkGameDataSynchCheckTechMismatchReport(report); - } + this->setReceivedDataSynchCheck(true); + receivedNetworkGameStatus = true; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } - - this->setReceivedDataSynchCheck(true); - receivedNetworkGameStatus = true; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - break; + break; - case nmtSynchNetworkGameDataFileCRCCheck: - { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataFileCRCCheck\n",__FILE__,__FUNCTION__); - - if(gotIntro == true) { - NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck; - if(receiveMessage(&networkMessageSynchNetworkGameDataFileCRCCheck)) + case nmtSynchNetworkGameDataFileCRCCheck: { - int fileIndex = networkMessageSynchNetworkGameDataFileCRCCheck.getFileIndex(); - NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck((int)vctFileList.size(), fileIndex, vctFileList[fileIndex-1].second, vctFileList[fileIndex-1].first); - sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - break; - case nmtSynchNetworkGameDataFileGet: - { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] got nmtSynchNetworkGameDataFileCRCCheck\n", __FILE__, __FUNCTION__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got nmtSynchNetworkGameDataFileGet\n",__FILE__,__FUNCTION__); - - if(gotIntro == true) { - NetworkMessageSynchNetworkGameDataFileGet networkMessageSynchNetworkGameDataFileGet; - if(receiveMessage(&networkMessageSynchNetworkGameDataFileGet)) { - FileTransferInfo fileInfo; - fileInfo.hostType = eServer; - //fileInfo.serverIP = this->ip.getString(); - fileInfo.serverPort = Config::getInstance().getInt("PortServer",intToStr(GameConstants::serverPort).c_str()); - fileInfo.fileName = networkMessageSynchNetworkGameDataFileGet.getFileName(); - - FileTransferSocketThread *fileXferThread = new FileTransferSocketThread(fileInfo); - fileXferThread->start(); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } - } - break; - - case nmtSwitchSetupRequest: - { - //printf("Got nmtSwitchSetupRequest A gotIntro = %d\n",gotIntro); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got nmtSwitchSetupRequest gotIntro = %d\n",__FILE__,__FUNCTION__,__LINE__,gotIntro); - - if(gotIntro == true) { - //printf("Got nmtSwitchSetupRequest B\n"); - - SwitchSetupRequest switchSetupRequest; - if(receiveMessage(&switchSetupRequest)) { - MutexSafeWrapper safeMutex(getServerSynchAccessor(),CODE_AT_LINE); - - int slotIdx = switchSetupRequest.getCurrentSlotIndex(); - //int newSlotIdx = switchSetupRequest.getToSlotIndex(); - //printf("slotIdx = %d newSlotIdx = %d\n",slotIdx,newSlotIdx); - - if(serverInterface->getSwitchSetupRequests(slotIdx) == NULL) { - serverInterface->setSwitchSetupRequests(slotIdx,new SwitchSetupRequest()); + if (gotIntro == true) { + NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck; + if (receiveMessage(&networkMessageSynchNetworkGameDataFileCRCCheck)) { + int fileIndex = networkMessageSynchNetworkGameDataFileCRCCheck.getFileIndex(); + NetworkMessageSynchNetworkGameDataFileCRCCheck networkMessageSynchNetworkGameDataFileCRCCheck((int) vctFileList.size(), fileIndex, vctFileList[fileIndex - 1].second, vctFileList[fileIndex - 1].first); + sendMessage(&networkMessageSynchNetworkGameDataFileCRCCheck); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } - *(serverInterface->getSwitchSetupRequests(slotIdx)) = switchSetupRequest; - - //printf("slotIdx = %d newSlotIdx = %d\n",serverInterface->getSwitchSetupRequests(slotIdx)->getCurrentSlotIndex(),serverInterface->getSwitchSetupRequests(slotIdx)->getToSlotIndex()); - - this->playerStatus = switchSetupRequest.getNetworkPlayerStatus(); - this->name = switchSetupRequest.getNetworkPlayerName(); - this->playerLanguage = switchSetupRequest.getNetworkPlayerLanguage(); - - //printf("Got nmtSwitchSetupRequest C\n"); - //printf("In [%s::%s Line %d] networkPlayerName [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getSwitchSetupRequests()[factionIdx]->getNetworkPlayerName().c_str()); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] networkPlayerName [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getSwitchSetupRequests()[slotIdx]->getNetworkPlayerName().c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] factionIdx = %d, switchSetupRequest.getNetworkPlayerName() [%s] switchSetupRequest.getNetworkPlayerStatus() = %d, switchSetupRequest.getSwitchFlags() = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIdx,switchSetupRequest.getNetworkPlayerName().c_str(),switchSetupRequest.getNetworkPlayerStatus(),switchSetupRequest.getSwitchFlags()); } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; + break; + + case nmtSynchNetworkGameDataFileGet: + { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] got nmtSynchNetworkGameDataFileGet\n", __FILE__, __FUNCTION__); + + if (gotIntro == true) { + NetworkMessageSynchNetworkGameDataFileGet networkMessageSynchNetworkGameDataFileGet; + if (receiveMessage(&networkMessageSynchNetworkGameDataFileGet)) { + FileTransferInfo fileInfo; + fileInfo.hostType = eServer; + //fileInfo.serverIP = this->ip.getString(); + fileInfo.serverPort = Config::getInstance().getInt("PortServer", intToStr(GameConstants::serverPort).c_str()); + fileInfo.fileName = networkMessageSynchNetworkGameDataFileGet.getFileName(); + + FileTransferSocketThread *fileXferThread = new FileTransferSocketThread(fileInfo); + fileXferThread->start(); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; - } + break; - break; - } + case nmtSwitchSetupRequest: + { + //printf("Got nmtSwitchSetupRequest A gotIntro = %d\n",gotIntro); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got nmtSwitchSetupRequest gotIntro = %d\n", __FILE__, __FUNCTION__, __LINE__, gotIntro); - case nmtReady: - { - NetworkMessageReady networkMessageReady; - this->receiveMessage(&networkMessageReady); + if (gotIntro == true) { + //printf("Got nmtSwitchSetupRequest B\n"); - // its simply ignored here. Probably we are starting a game - //printf("Got ready message from client slot joinGameInProgress = %d\n",joinGameInProgress); - if(joinGameInProgress == true) { - NetworkMessageReady networkMessageReady(0); - this->sendMessage(&networkMessageReady); - this->setGameStarted(true); + SwitchSetupRequest switchSetupRequest; + if (receiveMessage(&switchSetupRequest)) { + MutexSafeWrapper safeMutex(getServerSynchAccessor(), CODE_AT_LINE); - this->currentFrameCount = serverInterface->getCurrentFrameCount(); - //printf("#2 Server slot got currentFrameCount = %d\n",currentFrameCount); + int slotIdx = switchSetupRequest.getCurrentSlotIndex(); + //int newSlotIdx = switchSetupRequest.getToSlotIndex(); + //printf("slotIdx = %d newSlotIdx = %d\n",slotIdx,newSlotIdx); - this->currentLagCount = 0; - this->lastReceiveCommandListTime = time(NULL); + if (serverInterface->getSwitchSetupRequests(slotIdx) == NULL) { + serverInterface->setSwitchSetupRequests(slotIdx, new SwitchSetupRequest()); + } + *(serverInterface->getSwitchSetupRequests(slotIdx)) = switchSetupRequest; - this->setReady(); - } - // unpause the game - else { - this->setUnPauseForInGameConnection(true); - } - break; - } - case nmtLoadingStatusMessage: - break; + //printf("slotIdx = %d newSlotIdx = %d\n",serverInterface->getSwitchSetupRequests(slotIdx)->getCurrentSlotIndex(),serverInterface->getSwitchSetupRequests(slotIdx)->getToSlotIndex()); - default: - { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] networkMessageType = %d\n",__FILE__,__FUNCTION__,__LINE__,networkMessageType); + this->playerStatus = switchSetupRequest.getNetworkPlayerStatus(); + this->name = switchSetupRequest.getNetworkPlayerName(); + this->playerLanguage = switchSetupRequest.getNetworkPlayerLanguage(); - if(gotIntro == true) { - //throw megaglest_runtime_error("Unexpected message in connection slot: " + intToStr(networkMessageType)); - string sErr = "Unexpected message in connection slot: " + intToStr(networkMessageType); - //sendTextMessage(sErr,-1); - //DisplayErrorMessage(sErr); - threadErrorList.push_back(sErr); - return; + //printf("Got nmtSwitchSetupRequest C\n"); + //printf("In [%s::%s Line %d] networkPlayerName [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getSwitchSetupRequests()[factionIdx]->getNetworkPlayerName().c_str()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] networkPlayerName [%s]\n", __FILE__, __FUNCTION__, __LINE__, serverInterface->getSwitchSetupRequests()[slotIdx]->getNetworkPlayerName().c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] factionIdx = %d, switchSetupRequest.getNetworkPlayerName() [%s] switchSetupRequest.getNetworkPlayerStatus() = %d, switchSetupRequest.getSwitchFlags() = %d\n", __FILE__, __FUNCTION__, __LINE__, slotIdx, switchSetupRequest.getNetworkPlayerName().c_str(), switchSetupRequest.getNetworkPlayerStatus(), switchSetupRequest.getSwitchFlags()); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; + } + + break; } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got invalid message type before intro, disconnecting socket.\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,networkMessageType,this->playerIndex,this->getIpAddress().c_str()); - this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); - close(); - return; + case nmtReady: + { + NetworkMessageReady networkMessageReady; + this->receiveMessage(&networkMessageReady); + + // its simply ignored here. Probably we are starting a game + //printf("Got ready message from client slot joinGameInProgress = %d\n",joinGameInProgress); + if (joinGameInProgress == true) { + NetworkMessageReady networkMessageReady(0); + this->sendMessage(&networkMessageReady); + this->setGameStarted(true); + + this->currentFrameCount = serverInterface->getCurrentFrameCount(); + //printf("#2 Server slot got currentFrameCount = %d\n",currentFrameCount); + + this->currentLagCount = 0; + this->lastReceiveCommandListTime = time(NULL); + + this->setReady(); + } + // unpause the game + else { + this->setUnPauseForInGameConnection(true); + } + break; } - } - } + case nmtLoadingStatusMessage: + break; - //printf("#3 Server slot got currentFrameCount = %d\n",currentFrameCount); + default: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] networkMessageType = %d\n", __FILE__, __FUNCTION__, __LINE__, networkMessageType); - // This may end up continuously lagging and not disconnecting players who have - // just the 'wrong' amount of lag (but not enough to be horrible for a disconnect) - if(Config::getInstance().getBool("AutoClientLagCorrection","true") == true) { - double LAG_CHECK_GRACE_PERIOD = 15; + if (gotIntro == true) { + //throw megaglest_runtime_error("Unexpected message in connection slot: " + intToStr(networkMessageType)); + string sErr = "Unexpected message in connection slot: " + intToStr(networkMessageType); + //sendTextMessage(sErr,-1); + //DisplayErrorMessage(sErr); + threadErrorList.push_back(sErr); + return; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got invalid message type before intro, disconnecting socket.\n", __FILE__, __FUNCTION__, __LINE__); - //printf("#4 Server slot got currentFrameCount = %d\n",currentFrameCount); - - if(this->serverInterface->getGameStartTime() > 0 && - difftime((long int)time(NULL),this->serverInterface->getGameStartTime()) >= LAG_CHECK_GRACE_PERIOD && - difftime((long int)time(NULL),this->getConnectedTime()) >= LAG_CHECK_GRACE_PERIOD) { - if(this->isConnected() == true && this->gotIntro == true && this->skipLagCheck == false) { - double clientLag = this->serverInterface->getCurrentFrameCount() - this->getCurrentFrameCount(); - double clientLagCount = (gameSettings.getNetworkFramePeriod() > 0 ? (clientLag / gameSettings.getNetworkFramePeriod()) : 0); - double clientLagTime = difftime((long int)time(NULL),this->getLastReceiveCommandListTime()); - - double maxFrameCountLagAllowed = 10; - double maxClientLagTimeAllowed = 8; - - // New lag check - if((clientLagCount > maxFrameCountLagAllowed) || - (maxClientLagTimeAllowed > 0 && clientLagTime > maxClientLagTimeAllowed)) { - - waitForLaggingClient = true; - if(waitedForLaggingClient == false) { - waitedForLaggingClient = true; - printf("*TESTING*: START Waiting for lagging client playerIndex = %d [%s] clientLagCount = %f [%f]\n",playerIndex,name.c_str(),clientLagCount,clientLagTime); + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d]\nInvalid message type before intro handshake [%d]\nDisconnecting socket for slot: %d [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, networkMessageType, this->playerIndex, this->getIpAddress().c_str()); + this->serverInterface->notifyBadClientConnectAttempt(this->getIpAddress()); + close(); + return; } } } + + //printf("#3 Server slot got currentFrameCount = %d\n",currentFrameCount); + + // This may end up continuously lagging and not disconnecting players who have + // just the 'wrong' amount of lag (but not enough to be horrible for a disconnect) + if (Config::getInstance().getBool("AutoClientLagCorrection", "true") == true) { + double LAG_CHECK_GRACE_PERIOD = 15; + + //printf("#4 Server slot got currentFrameCount = %d\n",currentFrameCount); + + if (this->serverInterface->getGameStartTime() > 0 && + difftime((long int) time(NULL), this->serverInterface->getGameStartTime()) >= LAG_CHECK_GRACE_PERIOD && + difftime((long int) time(NULL), this->getConnectedTime()) >= LAG_CHECK_GRACE_PERIOD) { + if (this->isConnected() == true && this->gotIntro == true && this->skipLagCheck == false) { + double clientLag = this->serverInterface->getCurrentFrameCount() - this->getCurrentFrameCount(); + double clientLagCount = (gameSettings.getNetworkFramePeriod() > 0 ? (clientLag / gameSettings.getNetworkFramePeriod()) : 0); + double clientLagTime = difftime((long int) time(NULL), this->getLastReceiveCommandListTime()); + + double maxFrameCountLagAllowed = 10; + double maxClientLagTimeAllowed = 8; + + // New lag check + if ((clientLagCount > maxFrameCountLagAllowed) || + (maxClientLagTimeAllowed > 0 && clientLagTime > maxClientLagTimeAllowed)) { + + waitForLaggingClient = true; + if (waitedForLaggingClient == false) { + waitedForLaggingClient = true; + printf("*TESTING*: START Waiting for lagging client playerIndex = %d [%s] clientLagCount = %f [%f]\n", playerIndex, name.c_str(), clientLagCount, clientLagTime); + } + } + } + } + + //printf("#5 Server slot got currentFrameCount = %d\n",currentFrameCount); + } + //printf("#5a Server slot got currentFrameCount = %d\n",currentFrameCount); } - //printf("#5 Server slot got currentFrameCount = %d\n",currentFrameCount); + //printf("#6 Server slot got currentFrameCount = %d\n",currentFrameCount); + + if (waitedForLaggingClient == true) { + printf("*TESTING*: FINISHED Waiting for lagging client playerIndex = %d [%s]\n", playerIndex, name.c_str()); + } + + //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); + + validateConnection(); + + //printf("#7 Server slot got currentFrameCount = %d\n",currentFrameCount); + + //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] calling close...\n", __FILE__, __FUNCTION__, __LINE__); + + //printf("Closing connection slot socketInfo.first = %d\n",socketInfo.first); + + close(); + + //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); } - //printf("#5a Server slot got currentFrameCount = %d\n",currentFrameCount); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error detected [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); - //printf("#6 Server slot got currentFrameCount = %d\n",currentFrameCount); - - if(waitedForLaggingClient == true) { - printf("*TESTING*: FINISHED Waiting for lagging client playerIndex = %d [%s]\n",playerIndex,name.c_str()); - } - - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - - validateConnection(); - - //printf("#7 Server slot got currentFrameCount = %d\n",currentFrameCount); + threadErrorList.push_back(ex.what()); //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] calling close...\n",__FILE__,__FUNCTION__,__LINE__); - //printf("Closing connection slot socketInfo.first = %d\n",socketInfo.first); + //printf("#8 Server slot got currentFrameCount = %d\n",currentFrameCount); + //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); + } + void ConnectionSlot::validateConnection() { + if (this->isConnected() == true && + gotIntro == false && connectedTime > 0 && + difftime((long int) time(NULL), connectedTime) > GameConstants::maxClientConnectHandshakeSecs) { + + //printf("Closing connection slot timed out!\n"); close(); + } + } - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); + //void ConnectionSlot::resetJoinGameInProgressFlags() { + // this->gotIntro = false; + // this->skipLagCheck = false; + // this->joinGameInProgress = false; + // this->ready = false; + //} + + void ConnectionSlot::setJoinGameInProgressFlags() { + this->gotIntro = true; + this->skipLagCheck = true; + this->joinGameInProgress = true; + this->ready = false; + this->sentSavedGameInfo = false; + } + + void ConnectionSlot::close() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s LINE: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //printf("Closing slot for playerIndex = %d\n",playerIndex); + //if(serverInterface->getAllowInGameConnections() == true) { + //printf("Closing connection slot!\n"); + //} + //printf("ConnectionSlot::close() #1 this->getSocket() = %p\n",this->getSocket()); + + this->gotIntro = false; + this->skipLagCheck = false; + this->joinGameInProgress = false; + this->sentSavedGameInfo = false; + this->pauseForInGameConnection = false; + this->unPauseForInGameConnection = false; + this->ready = false; + this->connectedTime = 0; + + if (this->slotThreadWorker != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + this->slotThreadWorker->setAllEventsCompleted(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //printf("ConnectionSlot::close() #2 this->getSocket() = %p\n",this->getSocket()); + + MutexSafeWrapper safeMutex(mutexCloseConnection, CODE_AT_LINE); + bool updateServerListener = (this->getSocket() != NULL); + + //printf("ConnectionSlot::close() #3 this->getSocket() = %p updateServerListener = %d\n",this->getSocket(),updateServerListener); + + this->deleteSocket(); + safeMutex.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s LINE: %d]\n", __FILE__, __FUNCTION__, __LINE__); + //printf("Closing slot for playerIndex = %d updateServerListener = %d ready = %d\n",playerIndex,updateServerListener,ready); + + if (updateServerListener == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s LINE: %d]\n", __FILE__, __FUNCTION__, __LINE__); + serverInterface->updateListen(); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] END\n", __FILE__, __FUNCTION__); } - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - threadErrorList.push_back(ex.what()); - - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - } - - //printf("#8 Server slot got currentFrameCount = %d\n",currentFrameCount); - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); -} - -void ConnectionSlot::validateConnection() { - if(this->isConnected() == true && - gotIntro == false && connectedTime > 0 && - difftime((long int)time(NULL),connectedTime) > GameConstants::maxClientConnectHandshakeSecs) { - - //printf("Closing connection slot timed out!\n"); - close(); - } -} - -//void ConnectionSlot::resetJoinGameInProgressFlags() { -// this->gotIntro = false; -// this->skipLagCheck = false; -// this->joinGameInProgress = false; -// this->ready = false; -//} - -void ConnectionSlot::setJoinGameInProgressFlags() { - this->gotIntro = true; - this->skipLagCheck = true; - this->joinGameInProgress = true; - this->ready = false; - this->sentSavedGameInfo = false; -} - -void ConnectionSlot::close() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s LINE: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //printf("Closing slot for playerIndex = %d\n",playerIndex); - //if(serverInterface->getAllowInGameConnections() == true) { - //printf("Closing connection slot!\n"); - //} - //printf("ConnectionSlot::close() #1 this->getSocket() = %p\n",this->getSocket()); - - this->gotIntro = false; - this->skipLagCheck = false; - this->joinGameInProgress = false; - this->sentSavedGameInfo = false; - this->pauseForInGameConnection = false; - this->unPauseForInGameConnection = false; - this->ready = false; - this->connectedTime = 0; - - if(this->slotThreadWorker != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - this->slotThreadWorker->setAllEventsCompleted(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //printf("ConnectionSlot::close() #2 this->getSocket() = %p\n",this->getSocket()); - - MutexSafeWrapper safeMutex(mutexCloseConnection,CODE_AT_LINE); - bool updateServerListener = (this->getSocket() != NULL); - - //printf("ConnectionSlot::close() #3 this->getSocket() = %p updateServerListener = %d\n",this->getSocket(),updateServerListener); - - this->deleteSocket(); - safeMutex.ReleaseLock(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s LINE: %d]\n",__FILE__,__FUNCTION__,__LINE__); - //printf("Closing slot for playerIndex = %d updateServerListener = %d ready = %d\n",playerIndex,updateServerListener,ready); - - if(updateServerListener == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s LINE: %d]\n",__FILE__,__FUNCTION__,__LINE__); - serverInterface->updateListen(); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",__FILE__,__FUNCTION__); -} - -Mutex * ConnectionSlot::getServerSynchAccessor() { - return (serverInterface != NULL ? serverInterface->getServerSynchAccessor() : NULL); -} - -void ConnectionSlot::signalUpdate(ConnectionSlotEvent *event) { - if(slotThreadWorker != NULL) { - slotThreadWorker->signalUpdate(event); - } -} - -bool ConnectionSlot::updateCompleted(ConnectionSlotEvent *event) { - bool waitingForThread = (slotThreadWorker != NULL && - slotThreadWorker->isSignalCompleted(event) == false && - slotThreadWorker->getQuitStatus() == false && - slotThreadWorker->getRunningStatus() == true); - - return (waitingForThread == false); -} - -void ConnectionSlot::sendMessage(NetworkMessage* networkMessage) { - MutexSafeWrapper safeMutex(socketSynchAccessor,CODE_AT_LINE); - - // Skip text messages not intended for the players preferred language - NetworkMessageText *textMsg = dynamic_cast(networkMessage); - if(textMsg != NULL) { - //printf("\n\n\n~~~ SERVER HAS NetworkMessageText target [%s] player [%s] msg[%s]\n\n\n",textMsg->getTargetLanguage().c_str(),this->getNetworkPlayerLanguage().c_str(), textMsg->getText().c_str()); - if(textMsg->getTargetLanguage() != "" && - textMsg->getTargetLanguage() != this->getNetworkPlayerLanguage()) { - return; + Mutex * ConnectionSlot::getServerSynchAccessor() { + return (serverInterface != NULL ? serverInterface->getServerSynchAccessor() : NULL); } - } - NetworkInterface::sendMessage(networkMessage); -} - -string ConnectionSlot::getHumanPlayerName(int index) { - return serverInterface->getHumanPlayerName(index); -} - -vector ConnectionSlot::getPendingNetworkCommandList(bool clearList) { - vector ret; - MutexSafeWrapper safeMutexSlot(mutexPendingNetworkCommandList,CODE_AT_LINE); - if(vctPendingNetworkCommandList.empty() == false) { - ret = vctPendingNetworkCommandList; - if(clearList == true) { - vctPendingNetworkCommandList.clear(); + void ConnectionSlot::signalUpdate(ConnectionSlotEvent *event) { + if (slotThreadWorker != NULL) { + slotThreadWorker->signalUpdate(event); + } } - } - return ret; -} + bool ConnectionSlot::updateCompleted(ConnectionSlotEvent *event) { + bool waitingForThread = (slotThreadWorker != NULL && + slotThreadWorker->isSignalCompleted(event) == false && + slotThreadWorker->getQuitStatus() == false && + slotThreadWorker->getRunningStatus() == true); -//void ConnectionSlot::clearPendingNetworkCommandList() { -// MutexSafeWrapper safeMutexSlot(mutexPendingNetworkCommandList,CODE_AT_LINE); -// if(vctPendingNetworkCommandList.empty() == false) { -// vctPendingNetworkCommandList.clear(); -// } -//} + return (waitingForThread == false); + } -bool ConnectionSlot::hasValidSocketId() { - bool result = false; - MutexSafeWrapper safeMutexSlot(mutexSocket,CODE_AT_LINE); - if(socket != NULL && socket->getSocketId() > 0) { - result = true; - } - return result; + void ConnectionSlot::sendMessage(NetworkMessage* networkMessage) { + MutexSafeWrapper safeMutex(socketSynchAccessor, CODE_AT_LINE); -} + // Skip text messages not intended for the players preferred language + NetworkMessageText *textMsg = dynamic_cast(networkMessage); + if (textMsg != NULL) { + //printf("\n\n\n~~~ SERVER HAS NetworkMessageText target [%s] player [%s] msg[%s]\n\n\n",textMsg->getTargetLanguage().c_str(),this->getNetworkPlayerLanguage().c_str(), textMsg->getText().c_str()); + if (textMsg->getTargetLanguage() != "" && + textMsg->getTargetLanguage() != this->getNetworkPlayerLanguage()) { + return; + } + } -bool ConnectionSlot::isConnected() { - bool result = false; - MutexSafeWrapper safeMutexSlot(mutexSocket,CODE_AT_LINE); - if(socket != NULL && socket->isConnected() == true) { - result = true; - } - return result; -} + NetworkInterface::sendMessage(networkMessage); + } + + string ConnectionSlot::getHumanPlayerName(int index) { + return serverInterface->getHumanPlayerName(index); + } + + vector ConnectionSlot::getPendingNetworkCommandList(bool clearList) { + vector ret; + MutexSafeWrapper safeMutexSlot(mutexPendingNetworkCommandList, CODE_AT_LINE); + if (vctPendingNetworkCommandList.empty() == false) { + ret = vctPendingNetworkCommandList; + if (clearList == true) { + vctPendingNetworkCommandList.clear(); + } + } + + return ret; + } + + //void ConnectionSlot::clearPendingNetworkCommandList() { + // MutexSafeWrapper safeMutexSlot(mutexPendingNetworkCommandList,CODE_AT_LINE); + // if(vctPendingNetworkCommandList.empty() == false) { + // vctPendingNetworkCommandList.clear(); + // } + //} + + bool ConnectionSlot::hasValidSocketId() { + bool result = false; + MutexSafeWrapper safeMutexSlot(mutexSocket, CODE_AT_LINE); + if (socket != NULL && socket->getSocketId() > 0) { + result = true; + } + return result; + + } + + bool ConnectionSlot::isConnected() { + bool result = false; + MutexSafeWrapper safeMutexSlot(mutexSocket, CODE_AT_LINE); + if (socket != NULL && socket->isConnected() == true) { + result = true; + } + return result; + } + + PLATFORM_SOCKET ConnectionSlot::getSocketId() { + PLATFORM_SOCKET result = 0; + MutexSafeWrapper safeMutexSlot(mutexSocket, CODE_AT_LINE); + if (socket != NULL) { + result = socket->getSocketId(); + } + return result; + } + + pair ConnectionSlot::getSocketInfo() { + pair result; + MutexSafeWrapper safeMutexSlot(mutexSocket, CODE_AT_LINE); + result.first = (socket != NULL && socket->isConnected()); + result.second = socket; + + return result; + + } + + Socket* ConnectionSlot::getSocket(bool mutexLock) { + MutexSafeWrapper safeMutexSlot(NULL, CODE_AT_LINE); + if (mutexLock == true) { + safeMutexSlot.setMutex(mutexSocket, CODE_AT_LINE); + } + return socket; + } + + void ConnectionSlot::setSocket(Socket *newSocket) { + MutexSafeWrapper safeMutexSlot(mutexSocket, CODE_AT_LINE); + socket = newSocket; + } + + void ConnectionSlot::deleteSocket() { + MutexSafeWrapper safeMutexSlot(mutexSocket, CODE_AT_LINE); + delete socket; + socket = NULL; + } + + bool ConnectionSlot::hasDataToRead() { + bool result = false; + + MutexSafeWrapper safeMutexSlot(mutexSocket, CODE_AT_LINE); + if (socket != NULL && socket->hasDataToRead() == true) { + result = true; + } + + return result; + } -PLATFORM_SOCKET ConnectionSlot::getSocketId() { - PLATFORM_SOCKET result = 0; - MutexSafeWrapper safeMutexSlot(mutexSocket,CODE_AT_LINE); - if(socket != NULL) { - result = socket->getSocketId(); } - return result; -} - -pair ConnectionSlot::getSocketInfo() { - pair result; - MutexSafeWrapper safeMutexSlot(mutexSocket,CODE_AT_LINE); - result.first = (socket != NULL && socket->isConnected()); - result.second = socket; - - return result; - -} - -Socket* ConnectionSlot::getSocket(bool mutexLock) { - MutexSafeWrapper safeMutexSlot(NULL,CODE_AT_LINE); - if(mutexLock == true) { - safeMutexSlot.setMutex(mutexSocket,CODE_AT_LINE); - } - return socket; -} - -void ConnectionSlot::setSocket(Socket *newSocket) { - MutexSafeWrapper safeMutexSlot(mutexSocket,CODE_AT_LINE); - socket = newSocket; -} - -void ConnectionSlot::deleteSocket() { - MutexSafeWrapper safeMutexSlot(mutexSocket,CODE_AT_LINE); - delete socket; - socket = NULL; -} - -bool ConnectionSlot::hasDataToRead() { - bool result = false; - - MutexSafeWrapper safeMutexSlot(mutexSocket,CODE_AT_LINE); - if(socket != NULL && socket->hasDataToRead() == true) { - result = true; - } - - return result; -} - -}}//end namespace +}//end namespace diff --git a/source/glest_game/network/connection_slot.h b/source/glest_game/network/connection_slot.h index b4165ed2e..bac4f24fe 100644 --- a/source/glest_game/network/connection_slot.h +++ b/source/glest_game/network/connection_slot.h @@ -33,263 +33,350 @@ using Shared::Platform::ServerSocket; using Shared::Platform::Socket; using std::vector; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -class ServerInterface; -class ConnectionSlot; + class ServerInterface; + class ConnectionSlot; -// ===================================================== -// class ConnectionSlotThread -// ===================================================== + // ===================================================== + // class ConnectionSlotThread + // ===================================================== -enum ConnectionSlotEventType -{ - eNone, - eReceiveSocketData, - eSendSocketData -}; + enum ConnectionSlotEventType { + eNone, + eReceiveSocketData, + eSendSocketData + }; -class ConnectionSlotEvent { -public: + class ConnectionSlotEvent { + public: + + ConnectionSlotEvent() { + eventType = eNone; + triggerId = -1; + connectionSlot = NULL; + networkMessage = NULL; + socketTriggered = false; + eventCompleted = false; + eventId = -1; + } + + int64 triggerId; + ConnectionSlot* connectionSlot; + ConnectionSlotEventType eventType; + NetworkMessage *networkMessage; + bool socketTriggered; + bool eventCompleted; + int64 eventId; + }; + + // + // This interface describes the methods a callback object must implement + // + class ConnectionSlotCallbackInterface { + public: + virtual bool isClientConnected(int index) = 0; + virtual bool getAllowInGameConnections() const = 0; + virtual ConnectionSlot *getSlot(int index, bool lockMutex) = 0; + virtual Mutex *getSlotMutex(int index) = 0; + + virtual void slotUpdateTask(ConnectionSlotEvent *event) = 0; + virtual ~ConnectionSlotCallbackInterface() { + } + }; + + class ConnectionSlotThread : public BaseThread, public SlaveThreadControllerInterface { + protected: + + ConnectionSlotCallbackInterface * slotInterface; + Semaphore semTaskSignalled; + Mutex *triggerIdMutex; + vector eventList; + int slotIndex; + MasterSlaveThreadController *masterController; + + Mutex *triggerGameStarted; + bool gameStarted; + + virtual void setQuitStatus(bool value); + virtual void setTaskCompleted(int eventId); + + void slotUpdateTask(ConnectionSlotEvent *event); + + public: + explicit ConnectionSlotThread(int slotIndex); + ConnectionSlotThread(ConnectionSlotCallbackInterface *slotInterface, int slotIndex); + virtual ~ConnectionSlotThread(); + + bool getGameStarted(); + void setGameStarted(bool value); + + virtual void setMasterController(MasterSlaveThreadController *master) { + masterController = master; + } + virtual void signalSlave(void *userdata); + + virtual void execute(); + void signalUpdate(ConnectionSlotEvent *event); + bool isSignalCompleted(ConnectionSlotEvent *event); + + int getSlotIndex() const { + return slotIndex; + } + void setSlotIndex(int index) { + this->slotIndex = index; + } + + void purgeCompletedEvents(); + //void purgeAllEvents(); + void setAllEventsCompleted(); + + virtual bool canShutdown(bool deleteSelfIfShutdownDelayed = false); + }; + + // ===================================================== + // class ConnectionSlot + // ===================================================== + + class ConnectionSlot : public NetworkInterface { + private: + ServerInterface * serverInterface; + + Mutex *mutexSocket; + Socket* socket; + int playerIndex; + string name; + bool ready; + vector > vctFileList; + bool receivedNetworkGameStatus; + time_t connectedTime; + bool gotIntro; + + Mutex *mutexCloseConnection; + + Mutex *mutexPendingNetworkCommandList; + vector vctPendingNetworkCommandList; + ConnectionSlotThread* slotThreadWorker; + int currentFrameCount; + int currentLagCount; + int graceLagCtr; + time_t lastReceiveCommandListTime; + bool gotLagCountWarning; + string versionString; + int sessionKey; + uint32 connectedRemoteIPAddress; + int playerStatus; + string playerLanguage; + string playerUUID; + string platform; + + bool skipLagCheck; + bool joinGameInProgress; + bool canAcceptConnections; + bool startInGameConnectionLaunch; + bool pauseForInGameConnection; + bool unPauseForInGameConnection; + bool sentSavedGameInfo; + + int autoPauseGameCountForLag; + + public: + ConnectionSlot(ServerInterface* serverInterface, int playerIndex); + ~ConnectionSlot(); + + int getAutoPauseGameCountForLag(); + void incrementAutoPauseGameCountForLag(); + + bool getGameStarted(); + void setGameStarted(bool value); + + bool getStartInGameConnectionLaunch() const { + return startInGameConnectionLaunch; + } + void setStartInGameConnectionLaunch(bool value) { + startInGameConnectionLaunch = value; + } + + bool getPauseForInGameConnection() const { + return pauseForInGameConnection; + } + void setPauseForInGameConnection(bool value) { + pauseForInGameConnection = value; + } + + bool getUnPauseForInGameConnection() const { + return unPauseForInGameConnection; + } + void setUnPauseForInGameConnection(bool value) { + unPauseForInGameConnection = value; + } + + bool getSkipLagCheck() const { + return skipLagCheck; + } + bool getJoinGameInProgress() const { + return joinGameInProgress; + } + + int getGraceLagCtr() { + return graceLagCtr++; + } + void resetGraceLagCtr() { + graceLagCtr = 0; + } + + bool getSentSavedGameInfo() const { + return sentSavedGameInfo; + } + void setSentSavedGameInfo(bool value) { + sentSavedGameInfo = value; + } + + ConnectionSlotThread *getWorkerThread() { + return slotThreadWorker; + } + + void update(bool checkForNewClients, int lockedSlotIndex); + void setPlayerIndex(int value); + int getPlayerIndex() const { + return playerIndex; + } + + uint32 getConnectedRemoteIPAddress() const { + return connectedRemoteIPAddress; + } + + void setReady(); + const string &getName() const { + return name; + } + const string &getUUID() const { + return playerUUID; + } + const string &getPlatform() const { + return platform; + } + void setName(string value) { + name = value; + } + bool isReady() const { + return ready; + } + + virtual std::string getIpAddress(bool mutexLock = true); + + virtual Socket* getSocket(bool mutexLock = true); + pair getSocketInfo(); + + virtual void close(); + //virtual bool getFogOfWar(); + + bool getReceivedNetworkGameStatus() const { + return receivedNetworkGameStatus; + } + void setReceivedNetworkGameStatus(bool value) { + receivedNetworkGameStatus = value; + } + + bool hasValidSocketId(); + virtual bool getConnectHasHandshaked() const { + return gotIntro; + } + std::vector getThreadErrorList() const { + return threadErrorList; + } + void clearThreadErrorList() { + threadErrorList.clear(); + } + + vector getPendingNetworkCommandList(bool clearList = false); + //void clearPendingNetworkCommandList(); + + void signalUpdate(ConnectionSlotEvent *event); + bool updateCompleted(ConnectionSlotEvent *event); + + virtual void sendMessage(NetworkMessage* networkMessage); + int getCurrentFrameCount() const { + return currentFrameCount; + } + + int getCurrentLagCount() const { + return currentLagCount; + } + void setCurrentLagCount(int value) { + currentLagCount = value; + } + + time_t getLastReceiveCommandListTime() const { + return lastReceiveCommandListTime; + } + + bool getLagCountWarning() const { + return gotLagCountWarning; + } + void setLagCountWarning(bool value) { + gotLagCountWarning = value; + } + + const string &getVersionString() const { + return versionString; + } + + void validateConnection(); + virtual string getHumanPlayerName(int index = -1); + virtual int getHumanPlayerIndex() const { + return playerIndex; + } + + int getNetworkPlayerStatus() const { + return playerStatus; + } + + string getNetworkPlayerLanguage() const { + return playerLanguage; + } + + time_t getConnectedTime() const { + return connectedTime; + } + int getSessionKey() const { + return sessionKey; + } + + void updateSlot(ConnectionSlotEvent *event); + virtual bool isConnected(); + + PLATFORM_SOCKET getSocketId(); + + void setCanAcceptConnections(bool value) { + canAcceptConnections = value; + } + bool getCanAcceptConnections() const { + return canAcceptConnections; + } + + virtual void saveGame(XmlNode *rootNode) { + }; + + //void resetJoinGameInProgressFlags(); + void setJoinGameInProgressFlags(); + + protected: + + Mutex * getServerSynchAccessor(); + std::vector threadErrorList; + Mutex *socketSynchAccessor; + + void setSocket(Socket *newSocket); + void deleteSocket(); + virtual void update() { + } + + bool hasDataToRead(); + }; - ConnectionSlotEvent() { - eventType = eNone; - triggerId = -1; - connectionSlot = NULL; - networkMessage = NULL; - socketTriggered = false; - eventCompleted = false; - eventId = -1; } - - int64 triggerId; - ConnectionSlot* connectionSlot; - ConnectionSlotEventType eventType; - NetworkMessage *networkMessage; - bool socketTriggered; - bool eventCompleted; - int64 eventId; -}; - -// -// This interface describes the methods a callback object must implement -// -class ConnectionSlotCallbackInterface { -public: - virtual bool isClientConnected(int index) = 0; - virtual bool getAllowInGameConnections() const = 0; - virtual ConnectionSlot *getSlot(int index, bool lockMutex) = 0; - virtual Mutex *getSlotMutex(int index) = 0; - - virtual void slotUpdateTask(ConnectionSlotEvent *event) = 0; - virtual ~ConnectionSlotCallbackInterface() {} -}; - -class ConnectionSlotThread : public BaseThread, public SlaveThreadControllerInterface -{ -protected: - - ConnectionSlotCallbackInterface *slotInterface; - Semaphore semTaskSignalled; - Mutex *triggerIdMutex; - vector eventList; - int slotIndex; - MasterSlaveThreadController *masterController; - - Mutex *triggerGameStarted; - bool gameStarted; - - virtual void setQuitStatus(bool value); - virtual void setTaskCompleted(int eventId); - - void slotUpdateTask(ConnectionSlotEvent *event); - -public: - explicit ConnectionSlotThread(int slotIndex); - ConnectionSlotThread(ConnectionSlotCallbackInterface *slotInterface,int slotIndex); - virtual ~ConnectionSlotThread(); - - bool getGameStarted(); - void setGameStarted(bool value); - - virtual void setMasterController(MasterSlaveThreadController *master) { masterController = master; } - virtual void signalSlave(void *userdata); - - virtual void execute(); - void signalUpdate(ConnectionSlotEvent *event); - bool isSignalCompleted(ConnectionSlotEvent *event); - - int getSlotIndex() const {return slotIndex; } - void setSlotIndex(int index) { this->slotIndex = index; } - - void purgeCompletedEvents(); - //void purgeAllEvents(); - void setAllEventsCompleted(); - - virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false); -}; - -// ===================================================== -// class ConnectionSlot -// ===================================================== - -class ConnectionSlot: public NetworkInterface { -private: - ServerInterface* serverInterface; - - Mutex *mutexSocket; - Socket* socket; - int playerIndex; - string name; - bool ready; - vector > vctFileList; - bool receivedNetworkGameStatus; - time_t connectedTime; - bool gotIntro; - - Mutex *mutexCloseConnection; - - Mutex *mutexPendingNetworkCommandList; - vector vctPendingNetworkCommandList; - ConnectionSlotThread* slotThreadWorker; - int currentFrameCount; - int currentLagCount; - int graceLagCtr; - time_t lastReceiveCommandListTime; - bool gotLagCountWarning; - string versionString; - int sessionKey; - uint32 connectedRemoteIPAddress; - int playerStatus; - string playerLanguage; - string playerUUID; - string platform; - - bool skipLagCheck; - bool joinGameInProgress; - bool canAcceptConnections; - bool startInGameConnectionLaunch; - bool pauseForInGameConnection; - bool unPauseForInGameConnection; - bool sentSavedGameInfo; - - int autoPauseGameCountForLag; - -public: - ConnectionSlot(ServerInterface* serverInterface, int playerIndex); - ~ConnectionSlot(); - - int getAutoPauseGameCountForLag(); - void incrementAutoPauseGameCountForLag(); - - bool getGameStarted(); - void setGameStarted(bool value); - - bool getStartInGameConnectionLaunch() const { return startInGameConnectionLaunch; } - void setStartInGameConnectionLaunch(bool value) { startInGameConnectionLaunch = value; } - - bool getPauseForInGameConnection() const { return pauseForInGameConnection; } - void setPauseForInGameConnection(bool value) { pauseForInGameConnection = value; } - - bool getUnPauseForInGameConnection() const { return unPauseForInGameConnection; } - void setUnPauseForInGameConnection(bool value) { unPauseForInGameConnection = value; } - - bool getSkipLagCheck() const { return skipLagCheck; } - bool getJoinGameInProgress() const { return joinGameInProgress; } - - int getGraceLagCtr() { return graceLagCtr++; } - void resetGraceLagCtr() { graceLagCtr = 0; } - - bool getSentSavedGameInfo() const { return sentSavedGameInfo; } - void setSentSavedGameInfo(bool value) { sentSavedGameInfo = value; } - - ConnectionSlotThread *getWorkerThread() { return slotThreadWorker; } - - void update(bool checkForNewClients,int lockedSlotIndex); - void setPlayerIndex(int value); - int getPlayerIndex() const {return playerIndex;} - - uint32 getConnectedRemoteIPAddress() const { return connectedRemoteIPAddress; } - - void setReady(); - const string &getName() const {return name;} - const string &getUUID() const {return playerUUID;} - const string &getPlatform() const { return platform; } - void setName(string value) {name = value;} - bool isReady() const {return ready;} - - virtual std::string getIpAddress(bool mutexLock=true); - - virtual Socket* getSocket(bool mutexLock=true); - pair getSocketInfo(); - - virtual void close(); - //virtual bool getFogOfWar(); - - bool getReceivedNetworkGameStatus() const { return receivedNetworkGameStatus; } - void setReceivedNetworkGameStatus(bool value) { receivedNetworkGameStatus = value; } - - bool hasValidSocketId(); - virtual bool getConnectHasHandshaked() const { return gotIntro; } - std::vector getThreadErrorList() const { return threadErrorList; } - void clearThreadErrorList() { threadErrorList.clear(); } - - vector getPendingNetworkCommandList(bool clearList=false); - //void clearPendingNetworkCommandList(); - - void signalUpdate(ConnectionSlotEvent *event); - bool updateCompleted(ConnectionSlotEvent *event); - - virtual void sendMessage(NetworkMessage* networkMessage); - int getCurrentFrameCount() const { return currentFrameCount; } - - int getCurrentLagCount() const { return currentLagCount; } - void setCurrentLagCount(int value) { currentLagCount = value; } - - time_t getLastReceiveCommandListTime() const { return lastReceiveCommandListTime; } - - bool getLagCountWarning() const { return gotLagCountWarning; } - void setLagCountWarning(bool value) { gotLagCountWarning = value; } - - const string &getVersionString() const {return versionString;} - - void validateConnection(); - virtual string getHumanPlayerName(int index=-1); - virtual int getHumanPlayerIndex() const {return playerIndex;} - - int getNetworkPlayerStatus() const { return playerStatus;} - - string getNetworkPlayerLanguage() const { return playerLanguage; } - - time_t getConnectedTime() const { return connectedTime; } - int getSessionKey() const { return sessionKey; } - - void updateSlot(ConnectionSlotEvent *event); - virtual bool isConnected(); - - PLATFORM_SOCKET getSocketId(); - - void setCanAcceptConnections(bool value) { canAcceptConnections = value; } - bool getCanAcceptConnections() const { return canAcceptConnections; } - - virtual void saveGame(XmlNode *rootNode) {}; - - //void resetJoinGameInProgressFlags(); - void setJoinGameInProgressFlags(); - -protected: - - Mutex * getServerSynchAccessor(); - std::vector threadErrorList; - Mutex *socketSynchAccessor; - - void setSocket(Socket *newSocket); - void deleteSocket(); - virtual void update() {} - - bool hasDataToRead(); -}; - -}}//end namespace +}//end namespace #endif diff --git a/source/glest_game/network/masterserver_info.h b/source/glest_game/network/masterserver_info.h index dae40d32e..f6f13d83a 100644 --- a/source/glest_game/network/masterserver_info.h +++ b/source/glest_game/network/masterserver_info.h @@ -18,77 +18,135 @@ using std::string; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// =========================================================== -// class ParticleSystemType -// -/// A type of particle system -// =========================================================== + // =========================================================== + // class ParticleSystemType + // + /// A type of particle system + // =========================================================== -class MasterServerInfo { -protected: - //general info: - string glestVersion; - string platform; - string binaryCompileDate; - - //game info: - string serverTitle; - string ipAddress; - - //game setup info: - string tech; - string map; - string tileset; - int activeSlots; - int networkSlots; - int connectedClients; - int externalconnectport; - string country; - int status; + class MasterServerInfo { + protected: + //general info: + string glestVersion; + string platform; + string binaryCompileDate; -public: - const string &getGlestVersion() const {return glestVersion;} - const string &getPlatform() const {return platform;} - const string &getBinaryCompileDate() const {return binaryCompileDate;} - - const string &getServerTitle() const {return serverTitle;} - const string &getIpAddress() const {return ipAddress;} - - const string &getTech() const {return tech;} - const string &getMap() const {return map;} - const string &getTileset() const {return tileset;} - const int getActiveSlots() const {return activeSlots;} - const int getNetworkSlots() const {return networkSlots;} - const int getConnectedClients() const {return connectedClients;} - const int getExternalConnectPort() const {return externalconnectport;} - const string &getCountry() const { return country;} - const int getStatus() const { return status;} - - - //general info: - void setGlestVersion(string value) { glestVersion = value; } - void setPlatform(string value) { platform = value; } - void setBinaryCompileDate(string value) { binaryCompileDate = value; } - - //game info: - void setServerTitle(string value) { serverTitle = value; } - void setIpAddress(string value) { ipAddress = value; } - - //game setup info: - void setTech(string value) { tech = value; } - void setMap(string value) { map = value; } - void setTileset(string value) { tileset = value; } - - void setActiveSlots(int value) { activeSlots = value; } - void setNetworkSlots(int value) { networkSlots = value; } - void setConnectedClients(int value) { connectedClients = value; } - void setExternalConnectPort(int value) { externalconnectport = value; } - void setCountry(string value) { country = value; } - void setStatus(int value) { status = value; } -}; + //game info: + string serverTitle; + string ipAddress; -}}//end namespace + //game setup info: + string tech; + string map; + string tileset; + int activeSlots; + int networkSlots; + int connectedClients; + int externalconnectport; + string country; + int status; + + public: + const string &getGlestVersion() const { + return glestVersion; + } + const string &getPlatform() const { + return platform; + } + const string &getBinaryCompileDate() const { + return binaryCompileDate; + } + + const string &getServerTitle() const { + return serverTitle; + } + const string &getIpAddress() const { + return ipAddress; + } + + const string &getTech() const { + return tech; + } + const string &getMap() const { + return map; + } + const string &getTileset() const { + return tileset; + } + const int getActiveSlots() const { + return activeSlots; + } + const int getNetworkSlots() const { + return networkSlots; + } + const int getConnectedClients() const { + return connectedClients; + } + const int getExternalConnectPort() const { + return externalconnectport; + } + const string &getCountry() const { + return country; + } + const int getStatus() const { + return status; + } + + + //general info: + void setGlestVersion(string value) { + glestVersion = value; + } + void setPlatform(string value) { + platform = value; + } + void setBinaryCompileDate(string value) { + binaryCompileDate = value; + } + + //game info: + void setServerTitle(string value) { + serverTitle = value; + } + void setIpAddress(string value) { + ipAddress = value; + } + + //game setup info: + void setTech(string value) { + tech = value; + } + void setMap(string value) { + map = value; + } + void setTileset(string value) { + tileset = value; + } + + void setActiveSlots(int value) { + activeSlots = value; + } + void setNetworkSlots(int value) { + networkSlots = value; + } + void setConnectedClients(int value) { + connectedClients = value; + } + void setExternalConnectPort(int value) { + externalconnectport = value; + } + void setCountry(string value) { + country = value; + } + void setStatus(int value) { + status = value; + } + }; + + } +}//end namespace #endif diff --git a/source/glest_game/network/network_interface.cpp b/source/glest_game/network/network_interface.cpp index 0eb959479..be8a9aa35 100644 --- a/source/glest_game/network/network_interface.cpp +++ b/source/glest_game/network/network_interface.cpp @@ -26,571 +26,556 @@ using namespace Shared::Platform; using namespace Shared::Util; using namespace std; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class NetworkInterface -// ===================================================== + // ===================================================== + // class NetworkInterface + // ===================================================== -const int NetworkInterface::readyWaitTimeout= 99000; // 99 seconds to 0 looks good on the screen + const int NetworkInterface::readyWaitTimeout = 99000; // 99 seconds to 0 looks good on the screen -bool NetworkInterface::allowGameDataSynchCheck = false; -bool NetworkInterface::allowDownloadDataSynch = false; -DisplayMessageFunction NetworkInterface::pCB_DisplayMessage = NULL; + bool NetworkInterface::allowGameDataSynchCheck = false; + bool NetworkInterface::allowDownloadDataSynch = false; + DisplayMessageFunction NetworkInterface::pCB_DisplayMessage = NULL; -Vec3f MarkedCell::static_system_marker_color(MAGENTA.x,MAGENTA.y,MAGENTA.z); + Vec3f MarkedCell::static_system_marker_color(MAGENTA.x, MAGENTA.y, MAGENTA.z); -NetworkInterface::NetworkInterface() { - networkAccessMutex = new Mutex(CODE_AT_LINE); + NetworkInterface::NetworkInterface() { + networkAccessMutex = new Mutex(CODE_AT_LINE); - networkGameDataSynchCheckOkMap=false; - networkGameDataSynchCheckOkTile=false; - networkGameDataSynchCheckOkTech=false; - receivedDataSynchCheck=false; + networkGameDataSynchCheckOkMap = false; + networkGameDataSynchCheckOkTile = false; + networkGameDataSynchCheckOkTech = false; + receivedDataSynchCheck = false; - networkPlayerFactionCRCMutex = new Mutex(CODE_AT_LINE); - for(unsigned int index = 0; index < (unsigned int)GameConstants::maxPlayers; ++index) { - networkPlayerFactionCRC[index] = 0; - } -} - -void NetworkInterface::init() { - networkAccessMutex = NULL; - - networkGameDataSynchCheckOkMap=false; - networkGameDataSynchCheckOkTile=false; - networkGameDataSynchCheckOkTech=false; - receivedDataSynchCheck=false; - - gameSettings = GameSettings(); - - networkPlayerFactionCRCMutex = NULL; - for(unsigned int index = 0; index < (unsigned int)GameConstants::maxPlayers; ++index) { - networkPlayerFactionCRC[index] = 0; - } -} - -NetworkInterface::~NetworkInterface() { - delete networkAccessMutex; - networkAccessMutex = NULL; - - delete networkPlayerFactionCRCMutex; - networkPlayerFactionCRCMutex = NULL; -} - -uint32 NetworkInterface::getNetworkPlayerFactionCRC(int index) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkPlayerFactionCRCMutex,mutexOwnerId); - - return networkPlayerFactionCRC[index]; -} -void NetworkInterface::setNetworkPlayerFactionCRC(int index, uint32 crc) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkPlayerFactionCRCMutex,mutexOwnerId); - - networkPlayerFactionCRC[index]=crc; -} - -void NetworkInterface::addChatInfo(const ChatMsgInfo &msg) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); - - chatTextList.push_back(msg); -} - -void NetworkInterface::addMarkedCell(const MarkedCell &msg) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); - - markedCellList.push_back(msg); -} -void NetworkInterface::addUnMarkedCell(const UnMarkedCell &msg) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); - - unmarkedCellList.push_back(msg); -} - -void NetworkInterface::sendMessage(NetworkMessage* networkMessage){ - Socket* socket= getSocket(false); - - networkMessage->send(socket); -} - -NetworkMessageType NetworkInterface::getNextMessageType(int waitMilliseconds) { - Socket* socket= getSocket(false); - int8 messageType= nmtInvalid; - -/* - if(socket != NULL && - ((waitMilliseconds <= 0 && socket->hasDataToRead() == true) || - (waitMilliseconds > 0 && socket->hasDataToReadWithWait(waitMilliseconds) == true))) { - //peek message type - int dataSize = socket->getDataToRead(); - if(dataSize >= (int)sizeof(messageType)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,dataSize); - - int iPeek = socket->peek(&messageType, sizeof(messageType)); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,iPeek,messageType,sizeof(messageType)); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] PEEK WARNING, socket->getDataToRead() messageType = %d [size = %d], dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,messageType,sizeof(messageType),dataSize); + networkPlayerFactionCRCMutex = new Mutex(CODE_AT_LINE); + for (unsigned int index = 0; index < (unsigned int) GameConstants::maxPlayers; ++index) { + networkPlayerFactionCRC[index] = 0; + } } - //sanity check new message type - if(messageType < 0 || messageType >= nmtCount) { - if(getConnectHasHandshaked() == true) { - throw megaglest_runtime_error("Invalid message type: " + intToStr(messageType)); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Invalid message type = %d (no packet handshake yet so ignored)\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,messageType); - } - } - } + void NetworkInterface::init() { + networkAccessMutex = NULL; - return static_cast(messageType); -*/ + networkGameDataSynchCheckOkMap = false; + networkGameDataSynchCheckOkTile = false; + networkGameDataSynchCheckOkTech = false; + receivedDataSynchCheck = false; + gameSettings = GameSettings(); - // According to here: https://support.microsoft.com/en-us/kb/192599 - // its a terrible sin to use MSG_PEEK so lets try an alternative - - /* - int bytesReceived = socket->receive(&messageType, sizeof(messageType), true); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,bytesReceived,messageType,sizeof(messageType)); - - return static_cast(messageType); - */ - - - if(socket != NULL && - ((waitMilliseconds <= 0 && socket->hasDataToRead() == true) || - (waitMilliseconds > 0 && socket->hasDataToReadWithWait(waitMilliseconds) == true))) { - //peek message type - int dataSize = socket->getDataToRead(); - if(dataSize >= (int)sizeof(messageType)) { - //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,dataSize); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] before recv\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - -// int iPeek = socket->peek(&messageType, sizeof(messageType)); -// if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,iPeek,messageType,sizeof(messageType)); -// if(iPeek > 0) { - int bytesReceived = socket->receive(&messageType, sizeof(messageType), true); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,bytesReceived,messageType,sizeof(messageType)); - //} - } - //else { - // if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] PEEK WARNING, socket->getDataToRead() messageType = %d [size = %d], dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,messageType,sizeof(messageType),dataSize); - //} - - if (socket->isSocketValid() == false) { - return nmtInvalid; + networkPlayerFactionCRCMutex = NULL; + for (unsigned int index = 0; index < (unsigned int) GameConstants::maxPlayers; ++index) { + networkPlayerFactionCRC[index] = 0; + } } - //sanity check new message type - if(messageType < 0 || messageType >= nmtCount) { - if(getConnectHasHandshaked() == true) { - throw megaglest_runtime_error("Invalid message type: " + intToStr(messageType)); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Invalid message type = %d (no packet handshake yet so ignored)\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,messageType); - } - } - } - return static_cast(messageType); + NetworkInterface::~NetworkInterface() { + delete networkAccessMutex; + networkAccessMutex = NULL; -} - -bool NetworkInterface::receiveMessage(NetworkMessage* networkMessage){ - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); - - Socket* socket= getSocket(false); - - return networkMessage->receive(socket); -} - -bool NetworkInterface::receiveMessage(NetworkMessage* networkMessage, NetworkMessageType type) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); - - Socket* socket = getSocket(false); - - return networkMessage->receive(socket, type); -} - -bool NetworkInterface::isConnected(){ - bool result = (getSocket()!=NULL && getSocket()->isConnected()); - return result; -} - -void NetworkInterface::setLastPingInfo(const NetworkMessagePing &ping) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); - - this->lastPingInfo = ping; -} - -void NetworkInterface::setLastPingInfoToNow() { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); - - this->lastPingInfo.setPingReceivedLocalTime(time(NULL)); -} - -NetworkMessagePing NetworkInterface::getLastPingInfo() { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); - - return lastPingInfo; -} -double NetworkInterface::getLastPingLag() { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); - - return difftime((long int)time(NULL),lastPingInfo.getPingReceivedLocalTime()); -} - -void NetworkInterface::DisplayErrorMessage(string sErr, bool closeSocket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] sErr [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,sErr.c_str()); - //SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] sErr [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,sErr.c_str()); - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] sErr [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,sErr.c_str()); - - if(closeSocket == true && getSocket() != NULL) { - close(); - } - - if(pCB_DisplayMessage != NULL) { - pCB_DisplayMessage(sErr.c_str(), false); - } - else { - throw megaglest_runtime_error(sErr); - } -} - -std::vector NetworkInterface::getChatTextList(bool clearList) { - std::vector result; - - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); - - if(chatTextList.empty() == false) { - result = chatTextList; - - if(clearList == true) { - chatTextList.clear(); + delete networkPlayerFactionCRCMutex; + networkPlayerFactionCRCMutex = NULL; } - } - return result; -} -void NetworkInterface::clearChatInfo() { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); + uint32 NetworkInterface::getNetworkPlayerFactionCRC(int index) { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkPlayerFactionCRCMutex, mutexOwnerId); - if(chatTextList.empty() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] chatTextList.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chatTextList.size()); - chatTextList.clear(); - } -} - -std::vector NetworkInterface::getMarkedCellList(bool clearList) { - std::vector result; - - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); - - if(markedCellList.empty() == false) { - result = markedCellList; - - if(clearList == true) { - markedCellList.clear(); + return networkPlayerFactionCRC[index]; } - } - return result; -} + void NetworkInterface::setNetworkPlayerFactionCRC(int index, uint32 crc) { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkPlayerFactionCRCMutex, mutexOwnerId); -void NetworkInterface::clearMarkedCellList() { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); - - if(markedCellList.empty() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] markedCellList.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,markedCellList.size()); - markedCellList.clear(); - } -} - -std::vector NetworkInterface::getUnMarkedCellList(bool clearList) { - std::vector result; - - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); - - if(unmarkedCellList.empty() == false) { - result = unmarkedCellList; - - if(clearList == true) { - unmarkedCellList.clear(); + networkPlayerFactionCRC[index] = crc; } - } - return result; -} -void NetworkInterface::clearUnMarkedCellList() { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); + void NetworkInterface::addChatInfo(const ChatMsgInfo &msg) { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); - if(unmarkedCellList.empty() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unmarkedCellList.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,unmarkedCellList.size()); - unmarkedCellList.clear(); - } -} - -std::vector NetworkInterface::getHighlightedCellList(bool clearList) { - std::vector result; - - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); - - if(highlightedCellList.empty() == false) { - result = highlightedCellList; - - if(clearList == true) { - highlightedCellList.clear(); + chatTextList.push_back(msg); } - } - return result; -} -void NetworkInterface::clearHighlightedCellList() { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); + void NetworkInterface::addMarkedCell(const MarkedCell &msg) { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); - if(highlightedCellList.empty() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] markedCellList.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,markedCellList.size()); - highlightedCellList.clear(); - } -} - -void NetworkInterface::setHighlightedCell(const MarkedCell &msg){ - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId); - - for(int idx = 0; idx < (int)highlightedCellList.size(); idx++) { - MarkedCell mc = highlightedCellList[idx]; - if(mc.getFactionIndex()==msg.getFactionIndex()){ - highlightedCellList.erase(highlightedCellList.begin()+ idx); - break; + markedCellList.push_back(msg); } + void NetworkInterface::addUnMarkedCell(const UnMarkedCell &msg) { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); + + unmarkedCellList.push_back(msg); + } + + void NetworkInterface::sendMessage(NetworkMessage* networkMessage) { + Socket* socket = getSocket(false); + + networkMessage->send(socket); + } + + NetworkMessageType NetworkInterface::getNextMessageType(int waitMilliseconds) { + Socket* socket = getSocket(false); + int8 messageType = nmtInvalid; + + /* + if(socket != NULL && + ((waitMilliseconds <= 0 && socket->hasDataToRead() == true) || + (waitMilliseconds > 0 && socket->hasDataToReadWithWait(waitMilliseconds) == true))) { + //peek message type + int dataSize = socket->getDataToRead(); + if(dataSize >= (int)sizeof(messageType)) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,dataSize); + + int iPeek = socket->peek(&messageType, sizeof(messageType)); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,iPeek,messageType,sizeof(messageType)); + } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] PEEK WARNING, socket->getDataToRead() messageType = %d [size = %d], dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,messageType,sizeof(messageType),dataSize); + } + + //sanity check new message type + if(messageType < 0 || messageType >= nmtCount) { + if(getConnectHasHandshaked() == true) { + throw megaglest_runtime_error("Invalid message type: " + intToStr(messageType)); + } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Invalid message type = %d (no packet handshake yet so ignored)\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,messageType); + } + } + } + + return static_cast(messageType); + */ + + + // According to here: https://support.microsoft.com/en-us/kb/192599 + // its a terrible sin to use MSG_PEEK so lets try an alternative + + /* + int bytesReceived = socket->receive(&messageType, sizeof(messageType), true); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,bytesReceived,messageType,sizeof(messageType)); + + return static_cast(messageType); + */ + + + if (socket != NULL && + ((waitMilliseconds <= 0 && socket->hasDataToRead() == true) || + (waitMilliseconds > 0 && socket->hasDataToReadWithWait(waitMilliseconds) == true))) { + //peek message type + int dataSize = socket->getDataToRead(); + if (dataSize >= (int)sizeof(messageType)) { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,dataSize); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] before recv\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + // int iPeek = socket->peek(&messageType, sizeof(messageType)); + // if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,iPeek,messageType,sizeof(messageType)); + // if(iPeek > 0) { + int bytesReceived = socket->receive(&messageType, sizeof(messageType), true); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, bytesReceived, messageType, sizeof(messageType)); + //} + } + //else { + // if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] PEEK WARNING, socket->getDataToRead() messageType = %d [size = %d], dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,messageType,sizeof(messageType),dataSize); + //} + + if (socket->isSocketValid() == false) { + return nmtInvalid; + } + //sanity check new message type + if (messageType < 0 || messageType >= nmtCount) { + if (getConnectHasHandshaked() == true) { + throw megaglest_runtime_error("Invalid message type: " + intToStr(messageType)); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] Invalid message type = %d (no packet handshake yet so ignored)\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, messageType); + } + } + } + + return static_cast(messageType); + + } + + bool NetworkInterface::receiveMessage(NetworkMessage* networkMessage) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + + Socket* socket = getSocket(false); + + return networkMessage->receive(socket); + } + + bool NetworkInterface::receiveMessage(NetworkMessage* networkMessage, NetworkMessageType type) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + + Socket* socket = getSocket(false); + + return networkMessage->receive(socket, type); + } + + bool NetworkInterface::isConnected() { + bool result = (getSocket() != NULL && getSocket()->isConnected()); + return result; + } + + void NetworkInterface::setLastPingInfo(const NetworkMessagePing &ping) { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); + + this->lastPingInfo = ping; + } + + void NetworkInterface::setLastPingInfoToNow() { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); + + this->lastPingInfo.setPingReceivedLocalTime(time(NULL)); + } + + NetworkMessagePing NetworkInterface::getLastPingInfo() { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); + + return lastPingInfo; + } + double NetworkInterface::getLastPingLag() { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); + + return difftime((long int) time(NULL), lastPingInfo.getPingReceivedLocalTime()); + } + + void NetworkInterface::DisplayErrorMessage(string sErr, bool closeSocket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] sErr [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, sErr.c_str()); + //SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] sErr [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,sErr.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] sErr [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, sErr.c_str()); + + if (closeSocket == true && getSocket() != NULL) { + close(); + } + + if (pCB_DisplayMessage != NULL) { + pCB_DisplayMessage(sErr.c_str(), false); + } else { + throw megaglest_runtime_error(sErr); + } + } + + std::vector NetworkInterface::getChatTextList(bool clearList) { + std::vector result; + + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); + + if (chatTextList.empty() == false) { + result = chatTextList; + + if (clearList == true) { + chatTextList.clear(); + } + } + return result; + } + + void NetworkInterface::clearChatInfo() { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); + + if (chatTextList.empty() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] chatTextList.size() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chatTextList.size()); + chatTextList.clear(); + } + } + + std::vector NetworkInterface::getMarkedCellList(bool clearList) { + std::vector result; + + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); + + if (markedCellList.empty() == false) { + result = markedCellList; + + if (clearList == true) { + markedCellList.clear(); + } + } + return result; + } + + void NetworkInterface::clearMarkedCellList() { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); + + if (markedCellList.empty() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] markedCellList.size() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, markedCellList.size()); + markedCellList.clear(); + } + } + + std::vector NetworkInterface::getUnMarkedCellList(bool clearList) { + std::vector result; + + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); + + if (unmarkedCellList.empty() == false) { + result = unmarkedCellList; + + if (clearList == true) { + unmarkedCellList.clear(); + } + } + return result; + } + + void NetworkInterface::clearUnMarkedCellList() { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); + + if (unmarkedCellList.empty() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] unmarkedCellList.size() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, unmarkedCellList.size()); + unmarkedCellList.clear(); + } + } + + std::vector NetworkInterface::getHighlightedCellList(bool clearList) { + std::vector result; + + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); + + if (highlightedCellList.empty() == false) { + result = highlightedCellList; + + if (clearList == true) { + highlightedCellList.clear(); + } + } + return result; + } + + void NetworkInterface::clearHighlightedCellList() { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); + + if (highlightedCellList.empty() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] markedCellList.size() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, markedCellList.size()); + highlightedCellList.clear(); + } + } + + void NetworkInterface::setHighlightedCell(const MarkedCell &msg) { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(networkAccessMutex, mutexOwnerId); + + for (int idx = 0; idx < (int) highlightedCellList.size(); idx++) { + MarkedCell mc = highlightedCellList[idx]; + if (mc.getFactionIndex() == msg.getFactionIndex()) { + highlightedCellList.erase(highlightedCellList.begin() + idx); + break; + } + } + highlightedCellList.push_back(msg); + } + + float NetworkInterface::getThreadedPingMS(std::string host) { + float result = -1; + + if (getSocket() != NULL) { + result = getSocket()->getThreadedPingMS(host); + } + return result; + } + + // ===================================================== + // class GameNetworkInterface + // ===================================================== + + GameNetworkInterface::GameNetworkInterface() { + quit = false; + } + + void GameNetworkInterface::requestCommand(const NetworkCommand *networkCommand, bool insertAtStart) { + assert(networkCommand != NULL); + Mutex *mutex = getServerSynchAccessor(); + + if (insertAtStart == false) { + MutexSafeWrapper safeMutex(mutex, string(__FILE__) + "_" + intToStr(__LINE__)); + requestedCommands.push_back(*networkCommand); + } else { + MutexSafeWrapper safeMutex(mutex, string(__FILE__) + "_" + intToStr(__LINE__)); + requestedCommands.insert(requestedCommands.begin(), *networkCommand); + } + } + + // ===================================================== + // class FileTransferSocketThread + // ===================================================== + + const int32 SEND_FILE = 0x20; + const int32 ACK = 0x47; + + FileTransferSocketThread::FileTransferSocketThread(FileTransferInfo fileInfo) : info(fileInfo) { + this->info.serverPort += 100; + } + + void FileTransferSocketThread::execute() { + if (info.hostType == eServer) { + ServerSocket serverSocket; + serverSocket.bind(this->info.serverPort); + serverSocket.listen(1); + Socket *clientSocket = serverSocket.accept(); + + char data[513] = ""; + memset(data, 0, 256); + + clientSocket->receive(data, 256, true); + if (*data == SEND_FILE) { + FileInfo file; + + memcpy(&file, data + 1, sizeof(file)); + + *data = ACK; + clientSocket->send(data, 256); + + Checksum checksum; + checksum.addFile(file.fileName); + file.filecrc = checksum.getSum(); + + ifstream infile(file.fileName.c_str(), ios::in | ios::binary | ios::ate); + if (infile.is_open() == true) { + file.filesize = infile.tellg(); + infile.seekg(0, ios::beg); + + memset(data, 0, 256); + *data = SEND_FILE; + memcpy(data + 1, &file, sizeof(file)); + + clientSocket->send(data, 256); + clientSocket->receive(data, 256, true); + if (*data != ACK) { + //transfer error + } + + int remain = file.filesize % 512; + int packs = (file.filesize - remain) / 512; + + while (packs--) { + infile.read(data, 512); + //if(!ReadFile(file,data,512,&read,NULL)) + // ; //read error + //if(written!=pack) + // ; //read error + clientSocket->send(data, 512); + clientSocket->receive(data, 256, true); + if (*data != ACK) { + //transfer error + } + } + + infile.read(data, remain); + //if(!ReadFile(file,data,remain,&read,NULL)) + // ; //read error + //if(written!=pack) + // ; //read error + + clientSocket->send(data, remain); + clientSocket->receive(data, 256, true); + if (*data != ACK) { + //transfer error + } + + infile.close(); + } + } + + delete clientSocket; + } else { + Ip ip(this->info.serverIP); + ClientSocket clientSocket; + clientSocket.connect(this->info.serverIP, this->info.serverPort); + + if (clientSocket.isConnected() == true) { + FileInfo file; + file.fileName = this->info.fileName; + //file.filesize = + //file.filecrc = this->info. + + string path = extractDirectoryPathFromFile(file.fileName); + createDirectoryPaths(path); + ofstream outFile(file.fileName.c_str(), ios_base::binary | ios_base::out); + if (outFile.is_open() == true) { + char data[513] = ""; + memset(data, 0, 256); + *data = SEND_FILE; + memcpy(data + 1, &file, sizeof(file)); + + clientSocket.send(data, 256); + clientSocket.receive(data, 256, true); + if (*data != ACK) { + //transfer error + } + + clientSocket.receive(data, 256, true); + if (*data == SEND_FILE) { + memcpy(&file, data + 1, sizeof(file)); + *data = ACK; + clientSocket.send(data, 256); + + int remain = file.filesize % 512; + int packs = (file.filesize - remain) / 512; + + while (packs--) { + clientSocket.receive(data, 512, true); + + outFile.write(data, 512); + if (outFile.bad()) { + //int ii = 0; + } + //if(!WriteFile(file,data,512,&written,NULL)) + // ; //write error + //if(written != pack) + // ; //write error + *data = ACK; + clientSocket.send(data, 256); + } + clientSocket.receive(data, remain, true); + + outFile.write(data, remain); + if (outFile.bad()) { + //int ii = 0; + } + + //if(!WriteFile(file,data,remain,&written,NULL)) + // ; //write error + //if(written!=pack) + // ; //write error + *data = ACK; + clientSocket.send(data, 256); + + Checksum checksum; + checksum.addFile(file.fileName); + uint32 crc = checksum.getSum(); + if (file.filecrc != crc) { + //int ii = 0; + } + + //if(calc_crc(file)!=info.crc) + // ; //transfeer error + } + + outFile.close(); + } + } + } + } + + } - highlightedCellList.push_back(msg); -} - -float NetworkInterface::getThreadedPingMS(std::string host) { - float result = -1; - - if(getSocket() != NULL) { - result = getSocket()->getThreadedPingMS(host); - } - return result; -} - -// ===================================================== -// class GameNetworkInterface -// ===================================================== - -GameNetworkInterface::GameNetworkInterface(){ - quit= false; -} - -void GameNetworkInterface::requestCommand(const NetworkCommand *networkCommand, bool insertAtStart) { - assert(networkCommand != NULL); - Mutex *mutex = getServerSynchAccessor(); - - if(insertAtStart == false) { - MutexSafeWrapper safeMutex(mutex,string(__FILE__) + "_" + intToStr(__LINE__)); - requestedCommands.push_back(*networkCommand); - } - else { - MutexSafeWrapper safeMutex(mutex,string(__FILE__) + "_" + intToStr(__LINE__)); - requestedCommands.insert(requestedCommands.begin(),*networkCommand); - } -} - -// ===================================================== -// class FileTransferSocketThread -// ===================================================== - -const int32 SEND_FILE = 0x20; -const int32 ACK = 0x47; - -FileTransferSocketThread::FileTransferSocketThread(FileTransferInfo fileInfo) : info(fileInfo) { - this->info.serverPort += 100; -} - -void FileTransferSocketThread::execute() -{ - if(info.hostType == eServer) - { - ServerSocket serverSocket; - serverSocket.bind(this->info.serverPort); - serverSocket.listen(1); - Socket *clientSocket = serverSocket.accept(); - - char data[513]=""; - memset(data, 0, 256); - - clientSocket->receive(data,256, true); - if(*data == SEND_FILE) - { - FileInfo file; - - memcpy(&file, data+1, sizeof(file)); - - *data=ACK; - clientSocket->send(data,256); - - Checksum checksum; - checksum.addFile(file.fileName); - file.filecrc = checksum.getSum(); - - ifstream infile(file.fileName.c_str(), ios::in | ios::binary | ios::ate); - if(infile.is_open() == true) - { - file.filesize = infile.tellg(); - infile.seekg (0, ios::beg); - - memset(data, 0, 256); - *data=SEND_FILE; - memcpy(data+1,&file,sizeof(file)); - - clientSocket->send(data,256); - clientSocket->receive(data,256, true); - if(*data != ACK) { - //transfer error - } - - int remain=file.filesize % 512 ; - int packs=(file.filesize-remain)/512; - - while(packs--) - { - infile.read(data,512); - //if(!ReadFile(file,data,512,&read,NULL)) - // ; //read error - //if(written!=pack) - // ; //read error - clientSocket->send(data,512); - clientSocket->receive(data,256, true); - if(*data!=ACK) { - //transfer error - } - } - - infile.read(data,remain); - //if(!ReadFile(file,data,remain,&read,NULL)) - // ; //read error - //if(written!=pack) - // ; //read error - - clientSocket->send(data,remain); - clientSocket->receive(data,256, true); - if(*data!=ACK) { - //transfer error - } - - infile.close(); - } - } - - delete clientSocket; - } - else - { - Ip ip(this->info.serverIP); - ClientSocket clientSocket; - clientSocket.connect(this->info.serverIP, this->info.serverPort); - - if(clientSocket.isConnected() == true) - { - FileInfo file; - file.fileName = this->info.fileName; - //file.filesize = - //file.filecrc = this->info. - - string path = extractDirectoryPathFromFile(file.fileName); - createDirectoryPaths(path); - ofstream outFile(file.fileName.c_str(), ios_base::binary | ios_base::out); - if(outFile.is_open() == true) - { - char data[513]=""; - memset(data, 0, 256); - *data=SEND_FILE; - memcpy(data+1,&file,sizeof(file)); - - clientSocket.send(data,256); - clientSocket.receive(data,256, true); - if(*data!=ACK) { - //transfer error - } - - clientSocket.receive(data,256,true); - if(*data == SEND_FILE) - { - memcpy(&file, data+1, sizeof(file)); - *data=ACK; - clientSocket.send(data,256); - - int remain = file.filesize % 512 ; - int packs = (file.filesize-remain) / 512; - - while(packs--) - { - clientSocket.receive(data,512,true); - - outFile.write(data, 512); - if(outFile.bad()) - { - //int ii = 0; - } - //if(!WriteFile(file,data,512,&written,NULL)) - // ; //write error - //if(written != pack) - // ; //write error - *data=ACK; - clientSocket.send(data,256); - } - clientSocket.receive(data,remain,true); - - outFile.write(data, remain); - if(outFile.bad()) - { - //int ii = 0; - } - - //if(!WriteFile(file,data,remain,&written,NULL)) - // ; //write error - //if(written!=pack) - // ; //write error - *data=ACK; - clientSocket.send(data,256); - - Checksum checksum; - checksum.addFile(file.fileName); - uint32 crc = checksum.getSum(); - if(file.filecrc != crc) - { - //int ii = 0; - } - - //if(calc_crc(file)!=info.crc) - // ; //transfeer error - } - - outFile.close(); - } - } - } -} - - -}}//end namespace +}//end namespace diff --git a/source/glest_game/network/network_interface.h b/source/glest_game/network/network_interface.h index 939097179..8b878e063 100644 --- a/source/glest_game/network/network_interface.h +++ b/source/glest_game/network/network_interface.h @@ -13,8 +13,8 @@ #define _GLEST_GAME_NETWORKINTERFACE_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -34,389 +34,464 @@ using Shared::Util::Checksum; using namespace Shared::Util; using namespace Shared::Platform; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class NetworkInterface -// ===================================================== + // ===================================================== + // class NetworkInterface + // ===================================================== -// -// This interface describes the methods to notify when a client is lagging -// -class ClientLagCallbackInterface { -public: - virtual bool clientLagHandler(int slotIndex, bool networkPauseGameForLaggedClients) = 0; + // + // This interface describes the methods to notify when a client is lagging + // + class ClientLagCallbackInterface { + public: + virtual bool clientLagHandler(int slotIndex, bool networkPauseGameForLaggedClients) = 0; - virtual ~ClientLagCallbackInterface() {} -}; + virtual ~ClientLagCallbackInterface() { + } + }; -class ChatMsgInfo { + class ChatMsgInfo { + + protected: + + void copyAll(const ChatMsgInfo &obj) { + this->chatText = obj.chatText.c_str(); + this->chatTeamIndex = obj.chatTeamIndex; + this->chatPlayerIndex = obj.chatPlayerIndex; + this->targetLanguage = obj.targetLanguage; + } + public: + + ChatMsgInfo() { + this->chatText = ""; + this->chatTeamIndex = -1; + this->chatPlayerIndex = -1; + this->targetLanguage = ""; + } + ChatMsgInfo(string chatText, int chatTeamIndex, int chatPlayerIndex, + string targetLanguage) { + this->chatText = chatText; + this->chatTeamIndex = chatTeamIndex; + this->chatPlayerIndex = chatPlayerIndex; + this->targetLanguage = targetLanguage; + } + ChatMsgInfo(const ChatMsgInfo& obj) { + copyAll(obj); + } + ChatMsgInfo & operator=(const ChatMsgInfo & obj) { + copyAll(obj); + return *this; + } + + string chatText; + int chatTeamIndex; + int chatPlayerIndex; + string targetLanguage; + + }; + + class MarkedCell { + protected: + Vec2i targetPos; + const Faction *faction; + int factionIndex; + int playerIndex; + string note; + int aliveCount; + + public: + static Vec3f static_system_marker_color; + + MarkedCell() { + faction = NULL; + factionIndex = -1; + playerIndex = -1; + note = ""; + aliveCount = 200; + } + MarkedCell(Vec2i targetPos, const Faction *faction, string note, int playerIndex) { + this->targetPos = targetPos; + this->faction = faction; + this->factionIndex = -1; + this->playerIndex = playerIndex; + this->note = note; + aliveCount = 200; + } + MarkedCell(Vec2i targetPos, int factionIndex, string note, int playerIndex) { + this->targetPos = targetPos; + this->faction = NULL; + this->factionIndex = factionIndex; + this->playerIndex = playerIndex; + this->note = note; + aliveCount = 200; + } + + Vec2i getTargetPos() const { + return targetPos; + } + const Faction * getFaction() const { + return faction; + } + void setFaction(const Faction *faction) { + this->faction = faction; + } + int getFactionIndex() const { + return factionIndex; + } + string getNote() const { + return note; + } + void decrementAliveCount() { + this->aliveCount--; + } + int getAliveCount() const { + return aliveCount; + } + void setAliveCount(int value) { + this->aliveCount = value; + } + int getPlayerIndex() const { + return playerIndex; + } + + void setNote(string value) { + note = value; + } + void setPlayerIndex(int value) { + playerIndex = value; + } + }; + + class UnMarkedCell { + protected: + Vec2i targetPos; + const Faction *faction; + int factionIndex; + + public: + UnMarkedCell() { + faction = NULL; + factionIndex = -1; + } + UnMarkedCell(Vec2i targetPos, const Faction *faction) { + this->targetPos = targetPos; + this->faction = faction; + this->factionIndex = -1; + } + UnMarkedCell(Vec2i targetPos, int factionIndex) { + this->targetPos = targetPos; + this->faction = NULL; + this->factionIndex = factionIndex; + } + + Vec2i getTargetPos() const { + return targetPos; + } + const Faction * getFaction() const { + return faction; + } + void setFaction(const Faction *faction) { + this->faction = faction; + } + int getFactionIndex() const { + return factionIndex; + } + }; + + typedef int(*DisplayMessageFunction)(const char *msg, bool exit); + + class NetworkInterface { + + protected: + static bool allowGameDataSynchCheck; + static bool allowDownloadDataSynch; + bool networkGameDataSynchCheckOkMap; + bool networkGameDataSynchCheckOkTile; + bool networkGameDataSynchCheckOkTech; + string networkGameDataSynchCheckTechMismatchReport; + bool receivedDataSynchCheck; + + NetworkMessagePing lastPingInfo; + + std::vector chatTextList; + std::vector markedCellList; + std::vector unmarkedCellList; + + static DisplayMessageFunction pCB_DisplayMessage; + void DisplayErrorMessage(string sErr, bool closeSocket = true); + + virtual Mutex * getServerSynchAccessor() = 0; + + std::vector highlightedCellList; + + Mutex *networkAccessMutex; + + void init(); + + Mutex *networkPlayerFactionCRCMutex; + uint32 networkPlayerFactionCRC[GameConstants::maxPlayers]; + + public: + static const int readyWaitTimeout; + GameSettings gameSettings; + + public: + NetworkInterface(); + virtual ~NetworkInterface(); + + NetworkInterface(const NetworkInterface& obj) { + init(); + throw megaglest_runtime_error("class NetworkInterface is NOT safe to copy!"); + } + NetworkInterface & operator=(const NetworkInterface& obj) { + init(); + throw megaglest_runtime_error("class NetworkInterface is NOT safe to assign!"); + } + + uint32 getNetworkPlayerFactionCRC(int index); + void setNetworkPlayerFactionCRC(int index, uint32 crc); + + virtual Socket* getSocket(bool mutexLock = true) = 0; + + virtual void close() = 0; + virtual string getHumanPlayerName(int index = -1) = 0; + virtual int getHumanPlayerIndex() const = 0; + + static void setDisplayMessageFunction(DisplayMessageFunction pDisplayMessage) { + pCB_DisplayMessage = pDisplayMessage; + } + static DisplayMessageFunction getDisplayMessageFunction() { + return pCB_DisplayMessage; + } + + virtual std::string getIpAddress(bool mutexLock = true) = 0; + string getIp() const { + return Socket::getIp(); + } + string getHostName() const { + return Socket::getHostName(); + } + + virtual void sendMessage(NetworkMessage* networkMessage); + NetworkMessageType getNextMessageType(int waitMilliseconds = 0); + bool receiveMessage(NetworkMessage* networkMessage); + bool receiveMessage(NetworkMessage* networkMessage, NetworkMessageType type); + + virtual bool isConnected(); + + const virtual GameSettings * getGameSettings() { + return &gameSettings; + } + GameSettings * getGameSettingsPtr() { + return &gameSettings; + } + + static void setAllowDownloadDataSynch(bool value) { + allowDownloadDataSynch = value; + } + static bool getAllowDownloadDataSynch() { + return allowDownloadDataSynch; + } + + static void setAllowGameDataSynchCheck(bool value) { + allowGameDataSynchCheck = value; + } + static bool getAllowGameDataSynchCheck() { + return allowGameDataSynchCheck; + } + + virtual bool getNetworkGameDataSynchCheckOk() { + return (networkGameDataSynchCheckOkMap && networkGameDataSynchCheckOkTile && networkGameDataSynchCheckOkTech); + } + virtual void setNetworkGameDataSynchCheckOkMap(bool value) { + networkGameDataSynchCheckOkMap = value; + } + virtual void setNetworkGameDataSynchCheckOkTile(bool value) { + networkGameDataSynchCheckOkTile = value; + } + virtual void setNetworkGameDataSynchCheckOkTech(bool value) { + networkGameDataSynchCheckOkTech = value; + } + virtual bool getNetworkGameDataSynchCheckOkMap() { + return networkGameDataSynchCheckOkMap; + } + virtual bool getNetworkGameDataSynchCheckOkTile() { + return networkGameDataSynchCheckOkTile; + } + virtual bool getNetworkGameDataSynchCheckOkTech() { + return networkGameDataSynchCheckOkTech; + } + + std::vector getChatTextList(bool clearList); + void clearChatInfo(); + void addChatInfo(const ChatMsgInfo &msg); + + std::vector getMarkedCellList(bool clearList); + void clearMarkedCellList(); + void addMarkedCell(const MarkedCell &msg); + + std::vector getUnMarkedCellList(bool clearList); + void clearUnMarkedCellList(); + void addUnMarkedCell(const UnMarkedCell &msg); + + std::vector getHighlightedCellList(bool clearList); + void clearHighlightedCellList(); + void setHighlightedCell(const MarkedCell &msg); + + virtual bool getConnectHasHandshaked() const = 0; + + void setLastPingInfo(const NetworkMessagePing &ping); + void setLastPingInfoToNow(); + NetworkMessagePing getLastPingInfo(); + double getLastPingLag(); + + float getThreadedPingMS(std::string host); + + string getNetworkGameDataSynchCheckTechMismatchReport() const { + return networkGameDataSynchCheckTechMismatchReport; + } + void setNetworkGameDataSynchCheckTechMismatchReport(string value) { + networkGameDataSynchCheckTechMismatchReport = value; + } + + bool getReceivedDataSynchCheck() const { + return receivedDataSynchCheck; + } + void setReceivedDataSynchCheck(bool value) { + receivedDataSynchCheck = value; + } + + virtual void saveGame(XmlNode *rootNode) = 0; + //static void loadGame(string name); + + }; + + // ===================================================== + // class GameNetworkInterface + // + // Adds functions common to servers and clients + // but not connection slots + // ===================================================== + + class GameNetworkInterface : public NetworkInterface { + + protected: + typedef vector Commands; + + Commands requestedCommands; //commands requested by the user + Commands pendingCommands; //commands ready to be given + bool quit; + + public: + GameNetworkInterface(); + virtual ~GameNetworkInterface() { + } + + //message processimg + virtual void update() = 0; + virtual void updateLobby() = 0; + virtual void updateKeyframe(int frameCount) = 0; + virtual void setKeyframe(int frameCount) = 0; + virtual void waitUntilReady(Checksum* checksum) = 0; + + //message sending + virtual void sendTextMessage(const string &text, int teamIndex, bool echoLocal, + string targetLanguage) = 0; + virtual void quitGame(bool userManuallyQuit) = 0; + + virtual void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note, int playerIndex) = 0; + virtual void sendUnMarkCellMessage(Vec2i targetPos, int factionIndex) = 0; + virtual void sendHighlightCellMessage(Vec2i targetPos, int factionIndex) = 0; + + + //misc + virtual string getNetworkStatus() = 0; + + //access functions + void requestCommand(const NetworkCommand *networkCommand, bool insertAtStart = false); + int getPendingCommandCount() const { + return (int) pendingCommands.size(); + } + NetworkCommand* getPendingCommand(int i) { + return &pendingCommands[i]; + } + void clearPendingCommands() { + pendingCommands.clear(); + } + bool getQuit() const { + return quit; + } + }; + + // ===================================================== + // class FileTransferSocketThread + // ===================================================== + + enum FileTransferHostType { + eClient, + eServer + }; + + enum FileTransferOperationType { + eSend, + eReceive + }; + + class FileTransferInfo { + private: + + void CopyAll(const FileTransferInfo &obj) { + hostType = obj.hostType; + serverIP = obj.serverIP; + serverPort = obj.serverPort; + opType = obj.opType; + fileName = obj.fileName; + } + + public: + FileTransferInfo() { + hostType = eClient; + serverIP = ""; + serverPort = 0; + opType = eSend; + fileName = ""; + } + FileTransferInfo(const FileTransferInfo &obj) { + CopyAll(obj); + } + FileTransferInfo &operator=(const FileTransferInfo &obj) { + CopyAll(obj); + return *this; + } + + FileTransferHostType hostType; + string serverIP; + int32 serverPort; + FileTransferOperationType opType; + string fileName; + }; + + class FileInfo { + public: + string fileName; + int64 filesize; + uint32 filecrc; + }; + + class FileTransferSocketThread : public Thread { + private: + FileTransferInfo info; + + public: + explicit FileTransferSocketThread(FileTransferInfo fileInfo); + virtual void execute(); + }; -protected: - void copyAll(const ChatMsgInfo &obj) { - this->chatText = obj.chatText.c_str(); - this->chatTeamIndex = obj.chatTeamIndex; - this->chatPlayerIndex = obj.chatPlayerIndex; - this->targetLanguage = obj.targetLanguage; } -public: - - ChatMsgInfo() { - this->chatText = ""; - this->chatTeamIndex = -1; - this->chatPlayerIndex = -1; - this->targetLanguage = ""; - } - ChatMsgInfo(string chatText, int chatTeamIndex, int chatPlayerIndex, - string targetLanguage) { - this->chatText = chatText; - this->chatTeamIndex = chatTeamIndex; - this->chatPlayerIndex = chatPlayerIndex; - this->targetLanguage = targetLanguage; - } - ChatMsgInfo(const ChatMsgInfo& obj) { - copyAll(obj); - } - ChatMsgInfo & operator=(const ChatMsgInfo & obj) { - copyAll(obj); - return *this; - } - - string chatText; - int chatTeamIndex; - int chatPlayerIndex; - string targetLanguage; - -}; - -class MarkedCell { -protected: - Vec2i targetPos; - const Faction *faction; - int factionIndex; - int playerIndex; - string note; - int aliveCount; - -public: - static Vec3f static_system_marker_color; - - MarkedCell() { - faction = NULL; - factionIndex = -1; - playerIndex = -1; - note = ""; - aliveCount=200; - } - MarkedCell(Vec2i targetPos,const Faction *faction,string note, int playerIndex) { - this->targetPos = targetPos; - this->faction = faction; - this->factionIndex = -1; - this->playerIndex = playerIndex; - this->note = note; - aliveCount=200; - } - MarkedCell(Vec2i targetPos,int factionIndex,string note, int playerIndex) { - this->targetPos = targetPos; - this->faction = NULL; - this->factionIndex = factionIndex; - this->playerIndex = playerIndex; - this->note = note; - aliveCount=200; - } - - Vec2i getTargetPos() const { return targetPos; } - const Faction * getFaction() const { return faction; } - void setFaction(const Faction *faction) { this->faction = faction; } - int getFactionIndex() const { return factionIndex; } - string getNote() const { return note; } - void decrementAliveCount() { this->aliveCount--; } - int getAliveCount() const { return aliveCount; } - void setAliveCount(int value) { this->aliveCount = value; } - int getPlayerIndex() const { return playerIndex; } - - void setNote(string value) { note = value; } - void setPlayerIndex(int value) { playerIndex = value; } -}; - -class UnMarkedCell { -protected: - Vec2i targetPos; - const Faction *faction; - int factionIndex; - -public: - UnMarkedCell() { - faction = NULL; - factionIndex = -1; - } - UnMarkedCell(Vec2i targetPos,const Faction *faction) { - this->targetPos = targetPos; - this->faction = faction; - this->factionIndex = -1; - } - UnMarkedCell(Vec2i targetPos,int factionIndex) { - this->targetPos = targetPos; - this->faction = NULL; - this->factionIndex = factionIndex; - } - - Vec2i getTargetPos() const { return targetPos; } - const Faction * getFaction() const { return faction; } - void setFaction(const Faction *faction) { this->faction = faction; } - int getFactionIndex() const { return factionIndex; } -}; - -typedef int (*DisplayMessageFunction)(const char *msg, bool exit); - -class NetworkInterface { - -protected: - static bool allowGameDataSynchCheck; - static bool allowDownloadDataSynch; - bool networkGameDataSynchCheckOkMap; - bool networkGameDataSynchCheckOkTile; - bool networkGameDataSynchCheckOkTech; - string networkGameDataSynchCheckTechMismatchReport; - bool receivedDataSynchCheck; - - NetworkMessagePing lastPingInfo; - - std::vector chatTextList; - std::vector markedCellList; - std::vector unmarkedCellList; - - static DisplayMessageFunction pCB_DisplayMessage; - void DisplayErrorMessage(string sErr, bool closeSocket=true); - - virtual Mutex * getServerSynchAccessor() = 0; - - std::vector highlightedCellList; - - Mutex *networkAccessMutex; - - void init(); - - Mutex *networkPlayerFactionCRCMutex; - uint32 networkPlayerFactionCRC[GameConstants::maxPlayers]; - -public: - static const int readyWaitTimeout; - GameSettings gameSettings; - -public: - NetworkInterface(); - virtual ~NetworkInterface(); - - NetworkInterface(const NetworkInterface& obj) { - init(); - throw megaglest_runtime_error("class NetworkInterface is NOT safe to copy!"); - } - NetworkInterface & operator=(const NetworkInterface& obj) { - init(); - throw megaglest_runtime_error("class NetworkInterface is NOT safe to assign!"); - } - - uint32 getNetworkPlayerFactionCRC(int index); - void setNetworkPlayerFactionCRC(int index, uint32 crc); - - virtual Socket* getSocket(bool mutexLock=true)= 0; - - virtual void close()= 0; - virtual string getHumanPlayerName(int index=-1) = 0; - virtual int getHumanPlayerIndex() const = 0; - - static void setDisplayMessageFunction(DisplayMessageFunction pDisplayMessage) { pCB_DisplayMessage = pDisplayMessage; } - static DisplayMessageFunction getDisplayMessageFunction() { return pCB_DisplayMessage; } - - virtual std::string getIpAddress(bool mutexLock=true) = 0; - string getIp() const {return Socket::getIp();} - string getHostName() const {return Socket::getHostName();} - - virtual void sendMessage(NetworkMessage* networkMessage); - NetworkMessageType getNextMessageType(int waitMilliseconds=0); - bool receiveMessage(NetworkMessage* networkMessage); - bool receiveMessage(NetworkMessage* networkMessage, NetworkMessageType type); - - virtual bool isConnected(); - - const virtual GameSettings * getGameSettings() { return &gameSettings; } - GameSettings * getGameSettingsPtr() { return &gameSettings; } - - static void setAllowDownloadDataSynch(bool value) { allowDownloadDataSynch = value; } - static bool getAllowDownloadDataSynch() { return allowDownloadDataSynch; } - - static void setAllowGameDataSynchCheck(bool value) { allowGameDataSynchCheck = value; } - static bool getAllowGameDataSynchCheck() { return allowGameDataSynchCheck; } - - virtual bool getNetworkGameDataSynchCheckOk() { return (networkGameDataSynchCheckOkMap && networkGameDataSynchCheckOkTile && networkGameDataSynchCheckOkTech); } - virtual void setNetworkGameDataSynchCheckOkMap(bool value) { networkGameDataSynchCheckOkMap = value; } - virtual void setNetworkGameDataSynchCheckOkTile(bool value) { networkGameDataSynchCheckOkTile = value; } - virtual void setNetworkGameDataSynchCheckOkTech(bool value) { networkGameDataSynchCheckOkTech = value; } - virtual bool getNetworkGameDataSynchCheckOkMap() { return networkGameDataSynchCheckOkMap; } - virtual bool getNetworkGameDataSynchCheckOkTile() { return networkGameDataSynchCheckOkTile; } - virtual bool getNetworkGameDataSynchCheckOkTech() { return networkGameDataSynchCheckOkTech; } - - std::vector getChatTextList(bool clearList); - void clearChatInfo(); - void addChatInfo(const ChatMsgInfo &msg); - - std::vector getMarkedCellList(bool clearList); - void clearMarkedCellList(); - void addMarkedCell(const MarkedCell &msg); - - std::vector getUnMarkedCellList(bool clearList); - void clearUnMarkedCellList(); - void addUnMarkedCell(const UnMarkedCell &msg); - - std::vector getHighlightedCellList(bool clearList); - void clearHighlightedCellList(); - void setHighlightedCell(const MarkedCell &msg); - - virtual bool getConnectHasHandshaked() const= 0; - - void setLastPingInfo(const NetworkMessagePing &ping); - void setLastPingInfoToNow(); - NetworkMessagePing getLastPingInfo(); - double getLastPingLag(); - - float getThreadedPingMS(std::string host); - - string getNetworkGameDataSynchCheckTechMismatchReport() const {return networkGameDataSynchCheckTechMismatchReport;} - void setNetworkGameDataSynchCheckTechMismatchReport(string value) {networkGameDataSynchCheckTechMismatchReport = value;} - - bool getReceivedDataSynchCheck() const {return receivedDataSynchCheck;} - void setReceivedDataSynchCheck(bool value) { receivedDataSynchCheck = value; } - - virtual void saveGame(XmlNode *rootNode) = 0; - //static void loadGame(string name); - -}; - -// ===================================================== -// class GameNetworkInterface -// -// Adds functions common to servers and clients -// but not connection slots -// ===================================================== - -class GameNetworkInterface: public NetworkInterface { - -protected: - typedef vector Commands; - - Commands requestedCommands; //commands requested by the user - Commands pendingCommands; //commands ready to be given - bool quit; - -public: - GameNetworkInterface(); - virtual ~GameNetworkInterface(){} - - //message processimg - virtual void update()= 0; - virtual void updateLobby()= 0; - virtual void updateKeyframe(int frameCount)= 0; - virtual void setKeyframe(int frameCount)= 0; - virtual void waitUntilReady(Checksum* checksum)= 0; - - //message sending - virtual void sendTextMessage(const string &text, int teamIndex,bool echoLocal, - string targetLanguage)= 0; - virtual void quitGame(bool userManuallyQuit)=0; - - virtual void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note,int playerIndex) = 0; - virtual void sendUnMarkCellMessage(Vec2i targetPos, int factionIndex) = 0; - virtual void sendHighlightCellMessage(Vec2i targetPos, int factionIndex) = 0; - - - //misc - virtual string getNetworkStatus() = 0; - - //access functions - void requestCommand(const NetworkCommand *networkCommand, bool insertAtStart=false); - int getPendingCommandCount() const {return (int)pendingCommands.size();} - NetworkCommand* getPendingCommand(int i) {return &pendingCommands[i];} - void clearPendingCommands() {pendingCommands.clear();} - bool getQuit() const {return quit;} -}; - -// ===================================================== -// class FileTransferSocketThread -// ===================================================== - -enum FileTransferHostType -{ - eClient, - eServer -}; - -enum FileTransferOperationType -{ - eSend, - eReceive -}; - -class FileTransferInfo -{ -private: - - void CopyAll(const FileTransferInfo &obj) - { - hostType = obj.hostType; - serverIP = obj.serverIP; - serverPort = obj.serverPort; - opType = obj.opType; - fileName = obj.fileName; - } - -public: - FileTransferInfo() - { - hostType = eClient; - serverIP = ""; - serverPort = 0; - opType = eSend; - fileName = ""; - } - FileTransferInfo(const FileTransferInfo &obj) - { - CopyAll(obj); - } - FileTransferInfo &operator=(const FileTransferInfo &obj) - { - CopyAll(obj); - return *this; - } - - FileTransferHostType hostType; - string serverIP; - int32 serverPort; - FileTransferOperationType opType; - string fileName; -}; - -class FileInfo -{ -public: - string fileName; - int64 filesize; - uint32 filecrc; -}; - -class FileTransferSocketThread : public Thread -{ -private: - FileTransferInfo info; - -public: - explicit FileTransferSocketThread(FileTransferInfo fileInfo); - virtual void execute(); -}; - - -}}//end namespace +}//end namespace #endif diff --git a/source/glest_game/network/network_manager.cpp b/source/glest_game/network/network_manager.cpp index 4b24ce11c..42d8df954 100644 --- a/source/glest_game/network/network_manager.cpp +++ b/source/glest_game/network/network_manager.cpp @@ -15,126 +15,127 @@ using namespace Shared::Util; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class NetworkManager -// ===================================================== + // ===================================================== + // class NetworkManager + // ===================================================== -NetworkManager &NetworkManager::getInstance(){ - static NetworkManager networkManager; - return networkManager; -} + NetworkManager &NetworkManager::getInstance() { + static NetworkManager networkManager; + return networkManager; + } -NetworkManager::NetworkManager() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + NetworkManager::NetworkManager() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - gameNetworkInterface= NULL; - networkRole= nrIdle; + gameNetworkInterface = NULL; + networkRole = nrIdle; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] this->networkRole = %d gameNetworkInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->networkRole,gameNetworkInterface); -} + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] this->networkRole = %d gameNetworkInterface [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->networkRole, gameNetworkInterface); + } -NetworkManager::~NetworkManager() { - end(); -} + NetworkManager::~NetworkManager() { + end(); + } -void NetworkManager::init(NetworkRole networkRole, bool publishEnabled) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] this->networkRole = %d, networkRole = %d, gameNetworkInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->networkRole,networkRole,gameNetworkInterface); + void NetworkManager::init(NetworkRole networkRole, bool publishEnabled) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] this->networkRole = %d, networkRole = %d, gameNetworkInterface [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->networkRole, networkRole, gameNetworkInterface); - //assert(gameNetworkInterface==NULL); - NetworkMessage::resetNetworkPacketStats(); - this->networkRole = networkRole; + //assert(gameNetworkInterface==NULL); + NetworkMessage::resetNetworkPacketStats(); + this->networkRole = networkRole; + + if (networkRole == nrServer) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] this->networkRole = %d, networkRole = %d, gameNetworkInterface [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->networkRole, networkRole, gameNetworkInterface); + gameNetworkInterface = new ServerInterface(publishEnabled, NULL); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] this->networkRole = %d, networkRole = %d, gameNetworkInterface [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->networkRole, networkRole, gameNetworkInterface); + gameNetworkInterface = new ClientInterface(); + } + + //printf("==========] CREATING gameNetworkInterface [%p]\n",gameNetworkInterface); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] this->networkRole = %d gameNetworkInterface [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->networkRole, gameNetworkInterface); + } + + void NetworkManager::initServerInterfaces(ClientLagCallbackInterface *intf) { + ServerInterface *server = getServerInterface(); + server->setClientLagCallbackInterface(intf); + } + + void NetworkManager::end() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] this->networkRole = %d gameNetworkInterface [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->networkRole, gameNetworkInterface); + //printf("In [%s::%s] Line: %d gameNetworkInterface = %p\n",__FILE__,__FUNCTION__,__LINE__,gameNetworkInterface); + //printf("==========] DELETING gameNetworkInterface [%p]\n",gameNetworkInterface); + + delete gameNetworkInterface; + gameNetworkInterface = NULL; + networkRole = nrIdle; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] this->networkRole = %d gameNetworkInterface [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->networkRole, gameNetworkInterface); + } + + void NetworkManager::update() { + if (gameNetworkInterface != NULL) { + gameNetworkInterface->update(); + } + } + + bool NetworkManager::isNetworkGame() { + return networkRole == nrClient || (networkRole == nrServer && getServerInterface()->getSlotCount() > 0); + } + + bool NetworkManager::isNetworkGameWithConnectedClients() { + return networkRole == nrClient || (networkRole == nrServer && getServerInterface()->getConnectedSlotCount(true) > 0); + } + + GameNetworkInterface* NetworkManager::getGameNetworkInterface(bool throwErrorOnNull) { + if (throwErrorOnNull) { + //assert(gameNetworkInterface!=NULL); + + if (gameNetworkInterface == NULL) { + throw megaglest_runtime_error("gameNetworkInterface==NULL"); + } + } + return gameNetworkInterface; + } + + ServerInterface* NetworkManager::getServerInterface(bool throwErrorOnNull) { + if (throwErrorOnNull) { + //assert(gameNetworkInterface!=NULL); + if (gameNetworkInterface == NULL) { + throw megaglest_runtime_error("gameNetworkInterface==NULL"); + } + + assert(networkRole == nrServer); + if (networkRole != nrServer) { + throw megaglest_runtime_error("networkRole!=nrServer"); + } + } + return dynamic_cast(gameNetworkInterface); + } + + ClientInterface* NetworkManager::getClientInterface(bool throwErrorOnNull) { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] this->networkRole = %d gameNetworkInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->networkRole,gameNetworkInterface); + + if (throwErrorOnNull) { + //assert(gameNetworkInterface!=NULL); + if (gameNetworkInterface == NULL) { + throw megaglest_runtime_error("gameNetworkInterface==NULL"); + } + + assert(networkRole == nrClient); + if (networkRole != nrClient) { + throw megaglest_runtime_error("networkRole!=nrClient"); + } + } + return dynamic_cast(gameNetworkInterface); + } - if(networkRole == nrServer) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] this->networkRole = %d, networkRole = %d, gameNetworkInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->networkRole,networkRole,gameNetworkInterface); - gameNetworkInterface = new ServerInterface(publishEnabled,NULL); } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] this->networkRole = %d, networkRole = %d, gameNetworkInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->networkRole,networkRole,gameNetworkInterface); - gameNetworkInterface = new ClientInterface(); - } - - //printf("==========] CREATING gameNetworkInterface [%p]\n",gameNetworkInterface); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] this->networkRole = %d gameNetworkInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->networkRole,gameNetworkInterface); -} - -void NetworkManager::initServerInterfaces(ClientLagCallbackInterface *intf) { - ServerInterface *server = getServerInterface(); - server->setClientLagCallbackInterface(intf); -} - -void NetworkManager::end() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] this->networkRole = %d gameNetworkInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->networkRole,gameNetworkInterface); - //printf("In [%s::%s] Line: %d gameNetworkInterface = %p\n",__FILE__,__FUNCTION__,__LINE__,gameNetworkInterface); - //printf("==========] DELETING gameNetworkInterface [%p]\n",gameNetworkInterface); - - delete gameNetworkInterface; - gameNetworkInterface= NULL; - networkRole= nrIdle; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] this->networkRole = %d gameNetworkInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->networkRole,gameNetworkInterface); -} - -void NetworkManager::update() { - if(gameNetworkInterface!=NULL) { - gameNetworkInterface->update(); - } -} - -bool NetworkManager::isNetworkGame() { - return networkRole==nrClient || (networkRole==nrServer && getServerInterface()->getSlotCount() > 0); -} - -bool NetworkManager::isNetworkGameWithConnectedClients() { - return networkRole==nrClient || (networkRole==nrServer && getServerInterface()->getConnectedSlotCount(true) > 0); -} - -GameNetworkInterface* NetworkManager::getGameNetworkInterface(bool throwErrorOnNull) { - if(throwErrorOnNull) { - //assert(gameNetworkInterface!=NULL); - - if(gameNetworkInterface==NULL) { - throw megaglest_runtime_error("gameNetworkInterface==NULL"); - } - } - return gameNetworkInterface; -} - -ServerInterface* NetworkManager::getServerInterface(bool throwErrorOnNull) { - if(throwErrorOnNull) { - //assert(gameNetworkInterface!=NULL); - if(gameNetworkInterface==NULL) { - throw megaglest_runtime_error("gameNetworkInterface==NULL"); - } - - assert(networkRole==nrServer); - if(networkRole!=nrServer) { - throw megaglest_runtime_error("networkRole!=nrServer"); - } - } - return dynamic_cast(gameNetworkInterface); -} - -ClientInterface* NetworkManager::getClientInterface(bool throwErrorOnNull) { - //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] this->networkRole = %d gameNetworkInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->networkRole,gameNetworkInterface); - - if(throwErrorOnNull) { - //assert(gameNetworkInterface!=NULL); - if(gameNetworkInterface==NULL) { - throw megaglest_runtime_error("gameNetworkInterface==NULL"); - } - - assert(networkRole==nrClient); - if(networkRole!=nrClient) { - throw megaglest_runtime_error("networkRole!=nrClient"); - } - } - return dynamic_cast(gameNetworkInterface); -} - -}}//end namespace +}//end namespace diff --git a/source/glest_game/network/network_manager.h b/source/glest_game/network/network_manager.h index 028c8e1de..e37f25a16 100644 --- a/source/glest_game/network/network_manager.h +++ b/source/glest_game/network/network_manager.h @@ -21,38 +21,42 @@ using Shared::Util::Checksum; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class NetworkManager -// ===================================================== + // ===================================================== + // class NetworkManager + // ===================================================== -class NetworkManager { -private: - GameNetworkInterface* gameNetworkInterface; - NetworkRole networkRole; + class NetworkManager { + private: + GameNetworkInterface * gameNetworkInterface; + NetworkRole networkRole; -public: - static NetworkManager &getInstance(); + public: + static NetworkManager &getInstance(); - NetworkManager(); - virtual ~NetworkManager(); + NetworkManager(); + virtual ~NetworkManager(); - void init(NetworkRole networkRole,bool publishEnabled=false); - void end(); - void update(); + void init(NetworkRole networkRole, bool publishEnabled = false); + void end(); + void update(); - bool isNetworkGame(); - bool isNetworkGameWithConnectedClients(); + bool isNetworkGame(); + bool isNetworkGameWithConnectedClients(); - GameNetworkInterface* getGameNetworkInterface(bool throwErrorOnNull=true); - ServerInterface* getServerInterface(bool throwErrorOnNull=true); - ClientInterface* getClientInterface(bool throwErrorOnNull=true); - NetworkRole getNetworkRole() const { return networkRole; } + GameNetworkInterface* getGameNetworkInterface(bool throwErrorOnNull = true); + ServerInterface* getServerInterface(bool throwErrorOnNull = true); + ClientInterface* getClientInterface(bool throwErrorOnNull = true); + NetworkRole getNetworkRole() const { + return networkRole; + } - void initServerInterfaces(ClientLagCallbackInterface *intf); -}; + void initServerInterfaces(ClientLagCallbackInterface *intf); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/glest_game/network/network_message.cpp b/source/glest_game/network/network_message.cpp index 14eaee67b..8ff07fb98 100644 --- a/source/glest_game/network/network_message.cpp +++ b/source/glest_game/network/network_message.cpp @@ -42,1705 +42,1684 @@ using namespace Shared::Util; using namespace std; using std::min; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -bool NetworkMessage::useOldProtocol = true; + bool NetworkMessage::useOldProtocol = true; -auto_ptr NetworkMessage::mutexMessageStats(new Mutex(CODE_AT_LINE)); -Chrono NetworkMessage::statsTimer; -Chrono NetworkMessage::lastSend; -Chrono NetworkMessage::lastRecv; -std::map NetworkMessage::mapMessageStats; + auto_ptr NetworkMessage::mutexMessageStats(new Mutex(CODE_AT_LINE)); + Chrono NetworkMessage::statsTimer; + Chrono NetworkMessage::lastSend; + Chrono NetworkMessage::lastRecv; + std::map NetworkMessage::mapMessageStats; -// ===================================================== -// class NetworkMessage -// ===================================================== + // ===================================================== + // class NetworkMessage + // ===================================================== -bool NetworkMessage::receive(Socket* socket, void* data, int dataSize, bool tryReceiveUntilDataSizeMet) { - if(socket != NULL) { - int dataReceived = socket->receive(data, dataSize, tryReceiveUntilDataSizeMet); - if(dataReceived != dataSize) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING, dataReceived = %d dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,dataReceived,dataSize); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nIn [%s::%s Line: %d] WARNING, dataReceived = %d dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,dataReceived,dataSize); + bool NetworkMessage::receive(Socket* socket, void* data, int dataSize, bool tryReceiveUntilDataSizeMet) { + if (socket != NULL) { + int dataReceived = socket->receive(data, dataSize, tryReceiveUntilDataSizeMet); + if (dataReceived != dataSize) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] WARNING, dataReceived = %d dataSize = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, dataReceived, dataSize); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nIn [%s::%s Line: %d] WARNING, dataReceived = %d dataSize = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, dataReceived, dataSize); - if(socket != NULL && socket->isSocketValid() == true) { - throw megaglest_runtime_error("Error receiving NetworkMessage, dataReceived = " + intToStr(dataReceived) + ", dataSize = " + intToStr(dataSize)); + if (socket != NULL && socket->isSocketValid() == true) { + throw megaglest_runtime_error("Error receiving NetworkMessage, dataReceived = " + intToStr(dataReceived) + ", dataSize = " + intToStr(dataSize)); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] socket has been disconnected\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] dataSize = %d, dataReceived = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, dataSize, dataReceived); + + dump_packet("\nINCOMING PACKET:\n", data, dataSize, false); + return true; + } } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket has been disconnected\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] dataSize = %d, dataReceived = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,dataSize,dataReceived); - - dump_packet("\nINCOMING PACKET:\n",data, dataSize, false); - return true; - } - } - return false; - -} - -void NetworkMessage::send(Socket* socket, const void* data, int dataSize) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket = %p, data = %p, dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,socket,data,dataSize); - - if(socket != NULL) { - dump_packet("\nOUTGOING PACKET:\n",data, dataSize, true); - int sendResult = socket->send(data, dataSize); - if(sendResult != dataSize) { - if(socket != NULL && socket->isSocketValid() == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error sending NetworkMessage, sendResult = %d, dataSize = %d",sendResult,dataSize); - throw megaglest_runtime_error(szBuf); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d socket has been disconnected\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - } - } -} - -void NetworkMessage::send(Socket* socket, const void* data, int dataSize, int8 messageType) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket = %p, data = %p, dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,socket,data,dataSize); - - if(socket != NULL) { - int msgTypeSize = sizeof(messageType); - int fullMsgSize = msgTypeSize + dataSize; - - char *out_buffer = new char[fullMsgSize]; - memcpy(out_buffer,&messageType,msgTypeSize); - memcpy(&out_buffer[msgTypeSize],(const char *)data,dataSize); - - dump_packet("\nOUTGOING PACKET:\n",out_buffer, fullMsgSize, true); - int sendResult = socket->send(out_buffer, fullMsgSize); - if(sendResult != fullMsgSize) { - delete [] out_buffer; - if(socket != NULL && socket->isSocketValid() == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error sending NetworkMessage, sendResult = %d, dataSize = %d",sendResult,fullMsgSize); - throw megaglest_runtime_error(szBuf); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d socket has been disconnected\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - } - else { - delete [] out_buffer; - } - } -} - -void NetworkMessage::send(Socket* socket, const void* data, int dataSize, int8 messageType, uint32 compressedLength) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket = %p, data = %p, dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,socket,data,dataSize); - - if(socket != NULL) { - int msgTypeSize = sizeof(messageType); - int compressedSize = sizeof(compressedLength); - int fullMsgSize = msgTypeSize + compressedSize + dataSize; - - char *out_buffer = new char[fullMsgSize]; - memcpy(out_buffer,&messageType,msgTypeSize); - memcpy(&out_buffer[msgTypeSize],&compressedLength,compressedSize); - memcpy(&out_buffer[msgTypeSize+compressedSize],(const char *)data,dataSize); - - dump_packet("\nOUTGOING PACKET:\n",out_buffer, fullMsgSize, true); - int sendResult = socket->send(out_buffer, fullMsgSize); - if(sendResult != fullMsgSize) { - delete [] out_buffer; - if(socket != NULL && socket->isSocketValid() == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error sending NetworkMessage, sendResult = %d, dataSize = %d",sendResult,fullMsgSize); - throw megaglest_runtime_error(szBuf); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d socket has been disconnected\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - } - else { - delete [] out_buffer; - } - } -} - -void NetworkMessage::resetNetworkPacketStats() { - NetworkMessage::statsTimer.stop(); - NetworkMessage::lastSend.stop(); - NetworkMessage::lastRecv.stop(); - NetworkMessage::mapMessageStats.clear(); -} - -string NetworkMessage::getNetworkPacketStats() { - string result = "Current Timer Milliseconds: " + intToStr(NetworkMessage::statsTimer.getMillis()) + "\n"; - - for(std::map::iterator iterMap = mapMessageStats.begin(); - iterMap != mapMessageStats.end(); ++iterMap) { - switch(iterMap->first) { - case netmsgstPacketsPerMillisecondSend: - result += "send p / msec: " + intToStr(iterMap->second) + (iterMap->second > 10 ? " ****WARNING WIN32 LIMIT EXCEEDED****" : "") + "\n"; - break; - case netmsgstPacketsPerSecondSend: - result += "send p / sec: " + intToStr(iterMap->second) + "\n"; - break; - case netmsgstAverageSendSize: - result += "send avg size: " + intToStr(iterMap->second) + "\n"; - break; - - case netmsgstPacketsPerMillisecondRecv: - result += "recv p / msec: " + intToStr(iterMap->second) + "\n"; - break; - case netmsgstPacketsPerSecondRecv: - result += "recv p / sec: " + intToStr(iterMap->second) + (iterMap->second > 10 ? " ****WARNING WIN32 LIMIT EXCEEDED****" : "") + "\n"; - break; - case netmsgstAverageRecvSize: - result += "recv avg size: " + intToStr(iterMap->second) + "\n"; - break; + return false; } - } - return result; -} -void NetworkMessage::dump_packet(string label, const void* data, int dataSize, bool isSend) { - Config &config = Config::getInstance(); - if( config.getBool("DebugNetworkPacketStats","false") == true) { + void NetworkMessage::send(Socket* socket, const void* data, int dataSize) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] socket = %p, data = %p, dataSize = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, socket, data, dataSize); - MutexSafeWrapper safeMutex(NetworkMessage::mutexMessageStats.get()); - - if(NetworkMessage::statsTimer.isStarted() == false) { - NetworkMessage::statsTimer.start(); - } - - bool secondChanged = false; - if(NetworkMessage::statsTimer.getSeconds() - NetworkMessage::mapMessageStats[netmsgstLastEvent] >= 3) { - - NetworkMessage::mapMessageStats[netmsgstLastEvent] = NetworkMessage::statsTimer.getSeconds(); - secondChanged = true; - } - - if(isSend == true) { - if(NetworkMessage::lastSend.isStarted() == false) { - NetworkMessage::lastSend.start(); - } - int64 millisecondsSinceLastSend = NetworkMessage::lastSend.getMillis(); - int64 secondsSinceLastSend = NetworkMessage::lastSend.getSeconds(); - - //char szBuf[8096]=""; - //snprintf(szBuf,8095,"\nSEND check cur [%lld] last [%lld]\n", (long long)millisecondsSinceLastSend,(long long)NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondSend_last] ); - //printf("%s",szBuf); - - if(millisecondsSinceLastSend == NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondSend_last]) { - NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondSend_current_count]++; - - } - else { - NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondSend_last] = millisecondsSinceLastSend; - NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondSend] = - (NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondSend] + - NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondSend_current_count]) / 2; - } - - if(secondsSinceLastSend == NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondSend_last]) { - NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondSend_current_count]++; - - } - else { - NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondSend_last] = secondsSinceLastSend; - NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondSend] = - (NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondSend] + - NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondSend_current_count]) / 2; - } - - NetworkMessage::mapMessageStats[netmsgstAverageSendSize] = - (NetworkMessage::mapMessageStats[netmsgstAverageSendSize] + - dataSize) / 2; - } - else { - if(NetworkMessage::lastRecv.isStarted() == false) { - NetworkMessage::lastRecv.start(); - } - int64 millisecondsSinceLastRecv = NetworkMessage::lastRecv.getMillis(); - int64 secondsSinceLastRecv = NetworkMessage::lastRecv.getSeconds(); - - //char szBuf[8096]=""; - //snprintf(szBuf,8095,"\nRECV check cur [%lld] last [%lld]\n", (long long)millisecondsSinceLastRecv,(long long)NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondRecv_last] ); - //printf("%s",szBuf); - - if(millisecondsSinceLastRecv == NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondRecv_last]) { - NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondRecv_current_count]++; - - } - else { - NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondRecv_last] = millisecondsSinceLastRecv; - NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondRecv] = - (NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondRecv] + - NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondRecv_current_count]) / 2; - } - - if(secondsSinceLastRecv == NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondRecv_last]) { - NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondRecv_current_count]++; - - } - else { - NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondRecv_last] = secondsSinceLastRecv; - NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondRecv] = - (NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondRecv] + - NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondRecv_current_count]) / 2; - } - - NetworkMessage::mapMessageStats[netmsgstAverageRecvSize] = - (NetworkMessage::mapMessageStats[netmsgstAverageRecvSize] + - dataSize) / 2; - } - - if(secondChanged == true) { - printf("%s",NetworkMessage::getNetworkPacketStats().c_str()); - } - } - - if( config.getBool("DebugNetworkPackets","false") == true || - config.getBool("DebugNetworkPacketSizes","false") == true) { - - printf("%s DataSize = %d",label.c_str(),dataSize); - - if(config.getBool("DebugNetworkPackets","false") == true) { - - printf("\n"); - const char *buf = static_cast(data); - for(unsigned int index = 0; index < (unsigned int)dataSize; ++index) { - - printf("%u[%X][%d] ",index,buf[index],buf[index]); - if(index % 10 == 0) { - printf("\n"); + if (socket != NULL) { + dump_packet("\nOUTGOING PACKET:\n", data, dataSize, true); + int sendResult = socket->send(data, dataSize); + if (sendResult != dataSize) { + if (socket != NULL && socket->isSocketValid() == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error sending NetworkMessage, sendResult = %d, dataSize = %d", sendResult, dataSize); + throw megaglest_runtime_error(szBuf); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d socket has been disconnected\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } } } } - printf("\n======= END =======\n"); - } -} -// ===================================================== -// class NetworkMessageIntro -// ===================================================== -NetworkMessageIntro::NetworkMessageIntro() { - messageType= -1; - data.sessionId= -1; - data.playerIndex= -1; - data.gameState = nmgstInvalid; - data.externalIp = 0; - data.ftpPort = 0; - data.gameInProgress = 0; -} + void NetworkMessage::send(Socket* socket, const void* data, int dataSize, int8 messageType) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] socket = %p, data = %p, dataSize = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, socket, data, dataSize); -NetworkMessageIntro::NetworkMessageIntro(int32 sessionId,const string &versionString, - const string &name, int playerIndex, - NetworkGameStateType gameState, - uint32 externalIp, - uint32 ftpPort, - const string &playerLanguage, - int gameInProgress, const string &playerUUID, - const string &platform) { - messageType = nmtIntro; - data.sessionId = sessionId; - data.versionString = versionString; - data.name = name; - data.playerIndex = static_cast(playerIndex); - data.gameState = static_cast(gameState); - data.externalIp = externalIp; - data.ftpPort = ftpPort; - data.language = playerLanguage; - data.gameInProgress = gameInProgress; - data.playerUUID = playerUUID; - data.platform = platform; -} + if (socket != NULL) { + int msgTypeSize = sizeof(messageType); + int fullMsgSize = msgTypeSize + dataSize; -const char * NetworkMessageIntro::getPackedMessageFormat() const { - return "cl128s32shcLL60sc60s60s"; -} + char *out_buffer = new char[fullMsgSize]; + memcpy(out_buffer, &messageType, msgTypeSize); + memcpy(&out_buffer[msgTypeSize], (const char *) data, dataSize); -unsigned int NetworkMessageIntro::getPackedSize() { - static unsigned int result = 0; - if(result == 0) { - Data packedData; - packedData.externalIp = 0; - packedData.ftpPort = 0; - packedData.gameInProgress = 0; - packedData.gameState = 0; - messageType = nmtIntro; - packedData.playerIndex = 0; - packedData.sessionId = 0; + dump_packet("\nOUTGOING PACKET:\n", out_buffer, fullMsgSize, true); + int sendResult = socket->send(out_buffer, fullMsgSize); + if (sendResult != fullMsgSize) { + delete[] out_buffer; + if (socket != NULL && socket->isSocketValid() == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error sending NetworkMessage, sendResult = %d, dataSize = %d", sendResult, fullMsgSize); + throw megaglest_runtime_error(szBuf); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d socket has been disconnected\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + } else { + delete[] out_buffer; + } + } + } - unsigned char *buf = new unsigned char[sizeof(packedData)*3]; - result = pack(buf, getPackedMessageFormat(), + void NetworkMessage::send(Socket* socket, const void* data, int dataSize, int8 messageType, uint32 compressedLength) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] socket = %p, data = %p, dataSize = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, socket, data, dataSize); + + if (socket != NULL) { + int msgTypeSize = sizeof(messageType); + int compressedSize = sizeof(compressedLength); + int fullMsgSize = msgTypeSize + compressedSize + dataSize; + + char *out_buffer = new char[fullMsgSize]; + memcpy(out_buffer, &messageType, msgTypeSize); + memcpy(&out_buffer[msgTypeSize], &compressedLength, compressedSize); + memcpy(&out_buffer[msgTypeSize + compressedSize], (const char *) data, dataSize); + + dump_packet("\nOUTGOING PACKET:\n", out_buffer, fullMsgSize, true); + int sendResult = socket->send(out_buffer, fullMsgSize); + if (sendResult != fullMsgSize) { + delete[] out_buffer; + if (socket != NULL && socket->isSocketValid() == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error sending NetworkMessage, sendResult = %d, dataSize = %d", sendResult, fullMsgSize); + throw megaglest_runtime_error(szBuf); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d socket has been disconnected\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + } else { + delete[] out_buffer; + } + } + } + + void NetworkMessage::resetNetworkPacketStats() { + NetworkMessage::statsTimer.stop(); + NetworkMessage::lastSend.stop(); + NetworkMessage::lastRecv.stop(); + NetworkMessage::mapMessageStats.clear(); + } + + string NetworkMessage::getNetworkPacketStats() { + string result = "Current Timer Milliseconds: " + intToStr(NetworkMessage::statsTimer.getMillis()) + "\n"; + + for (std::map::iterator iterMap = mapMessageStats.begin(); + iterMap != mapMessageStats.end(); ++iterMap) { + switch (iterMap->first) { + case netmsgstPacketsPerMillisecondSend: + result += "send p / msec: " + intToStr(iterMap->second) + (iterMap->second > 10 ? " ****WARNING WIN32 LIMIT EXCEEDED****" : "") + "\n"; + break; + case netmsgstPacketsPerSecondSend: + result += "send p / sec: " + intToStr(iterMap->second) + "\n"; + break; + case netmsgstAverageSendSize: + result += "send avg size: " + intToStr(iterMap->second) + "\n"; + break; + + case netmsgstPacketsPerMillisecondRecv: + result += "recv p / msec: " + intToStr(iterMap->second) + "\n"; + break; + case netmsgstPacketsPerSecondRecv: + result += "recv p / sec: " + intToStr(iterMap->second) + (iterMap->second > 10 ? " ****WARNING WIN32 LIMIT EXCEEDED****" : "") + "\n"; + break; + case netmsgstAverageRecvSize: + result += "recv avg size: " + intToStr(iterMap->second) + "\n"; + break; + + } + } + return result; + } + + void NetworkMessage::dump_packet(string label, const void* data, int dataSize, bool isSend) { + Config &config = Config::getInstance(); + if (config.getBool("DebugNetworkPacketStats", "false") == true) { + + MutexSafeWrapper safeMutex(NetworkMessage::mutexMessageStats.get()); + + if (NetworkMessage::statsTimer.isStarted() == false) { + NetworkMessage::statsTimer.start(); + } + + bool secondChanged = false; + if (NetworkMessage::statsTimer.getSeconds() - NetworkMessage::mapMessageStats[netmsgstLastEvent] >= 3) { + + NetworkMessage::mapMessageStats[netmsgstLastEvent] = NetworkMessage::statsTimer.getSeconds(); + secondChanged = true; + } + + if (isSend == true) { + if (NetworkMessage::lastSend.isStarted() == false) { + NetworkMessage::lastSend.start(); + } + int64 millisecondsSinceLastSend = NetworkMessage::lastSend.getMillis(); + int64 secondsSinceLastSend = NetworkMessage::lastSend.getSeconds(); + + //char szBuf[8096]=""; + //snprintf(szBuf,8095,"\nSEND check cur [%lld] last [%lld]\n", (long long)millisecondsSinceLastSend,(long long)NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondSend_last] ); + //printf("%s",szBuf); + + if (millisecondsSinceLastSend == NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondSend_last]) { + NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondSend_current_count]++; + + } else { + NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondSend_last] = millisecondsSinceLastSend; + NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondSend] = + (NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondSend] + + NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondSend_current_count]) / 2; + } + + if (secondsSinceLastSend == NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondSend_last]) { + NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondSend_current_count]++; + + } else { + NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondSend_last] = secondsSinceLastSend; + NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondSend] = + (NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondSend] + + NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondSend_current_count]) / 2; + } + + NetworkMessage::mapMessageStats[netmsgstAverageSendSize] = + (NetworkMessage::mapMessageStats[netmsgstAverageSendSize] + + dataSize) / 2; + } else { + if (NetworkMessage::lastRecv.isStarted() == false) { + NetworkMessage::lastRecv.start(); + } + int64 millisecondsSinceLastRecv = NetworkMessage::lastRecv.getMillis(); + int64 secondsSinceLastRecv = NetworkMessage::lastRecv.getSeconds(); + + //char szBuf[8096]=""; + //snprintf(szBuf,8095,"\nRECV check cur [%lld] last [%lld]\n", (long long)millisecondsSinceLastRecv,(long long)NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondRecv_last] ); + //printf("%s",szBuf); + + if (millisecondsSinceLastRecv == NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondRecv_last]) { + NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondRecv_current_count]++; + + } else { + NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondRecv_last] = millisecondsSinceLastRecv; + NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondRecv] = + (NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondRecv] + + NetworkMessage::mapMessageStats[netmsgstPacketsPerMillisecondRecv_current_count]) / 2; + } + + if (secondsSinceLastRecv == NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondRecv_last]) { + NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondRecv_current_count]++; + + } else { + NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondRecv_last] = secondsSinceLastRecv; + NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondRecv] = + (NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondRecv] + + NetworkMessage::mapMessageStats[netmsgstPacketsPerSecondRecv_current_count]) / 2; + } + + NetworkMessage::mapMessageStats[netmsgstAverageRecvSize] = + (NetworkMessage::mapMessageStats[netmsgstAverageRecvSize] + + dataSize) / 2; + } + + if (secondChanged == true) { + printf("%s", NetworkMessage::getNetworkPacketStats().c_str()); + } + } + + if (config.getBool("DebugNetworkPackets", "false") == true || + config.getBool("DebugNetworkPacketSizes", "false") == true) { + + printf("%s DataSize = %d", label.c_str(), dataSize); + + if (config.getBool("DebugNetworkPackets", "false") == true) { + + printf("\n"); + const char *buf = static_cast(data); + for (unsigned int index = 0; index < (unsigned int) dataSize; ++index) { + + printf("%u[%X][%d] ", index, buf[index], buf[index]); + if (index % 10 == 0) { + printf("\n"); + } + } + } + printf("\n======= END =======\n"); + } + } + + // ===================================================== + // class NetworkMessageIntro + // ===================================================== + NetworkMessageIntro::NetworkMessageIntro() { + messageType = -1; + data.sessionId = -1; + data.playerIndex = -1; + data.gameState = nmgstInvalid; + data.externalIp = 0; + data.ftpPort = 0; + data.gameInProgress = 0; + } + + NetworkMessageIntro::NetworkMessageIntro(int32 sessionId, const string &versionString, + const string &name, int playerIndex, + NetworkGameStateType gameState, + uint32 externalIp, + uint32 ftpPort, + const string &playerLanguage, + int gameInProgress, const string &playerUUID, + const string &platform) { + messageType = nmtIntro; + data.sessionId = sessionId; + data.versionString = versionString; + data.name = name; + data.playerIndex = static_cast(playerIndex); + data.gameState = static_cast(gameState); + data.externalIp = externalIp; + data.ftpPort = ftpPort; + data.language = playerLanguage; + data.gameInProgress = gameInProgress; + data.playerUUID = playerUUID; + data.platform = platform; + } + + const char * NetworkMessageIntro::getPackedMessageFormat() const { + return "cl128s32shcLL60sc60s60s"; + } + + unsigned int NetworkMessageIntro::getPackedSize() { + static unsigned int result = 0; + if (result == 0) { + Data packedData; + packedData.externalIp = 0; + packedData.ftpPort = 0; + packedData.gameInProgress = 0; + packedData.gameState = 0; + messageType = nmtIntro; + packedData.playerIndex = 0; + packedData.sessionId = 0; + + unsigned char *buf = new unsigned char[sizeof(packedData) * 3]; + result = pack(buf, getPackedMessageFormat(), + messageType, + packedData.sessionId, + packedData.versionString.getBuffer(), + packedData.name.getBuffer(), + packedData.playerIndex, + packedData.gameState, + packedData.externalIp, + packedData.ftpPort, + packedData.language.getBuffer(), + data.gameInProgress, + packedData.playerUUID.getBuffer(), + packedData.platform.getBuffer()); + delete[] buf; + } + return result; + } + void NetworkMessageIntro::unpackMessage(unsigned char *buf) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nIn [%s] about to unpack...\n", __FUNCTION__); + unpack(buf, getPackedMessageFormat(), + &messageType, + &data.sessionId, + data.versionString.getBuffer(), + data.name.getBuffer(), + &data.playerIndex, + &data.gameState, + &data.externalIp, + &data.ftpPort, + data.language.getBuffer(), + &data.gameInProgress, + data.playerUUID.getBuffer(), + data.platform.getBuffer()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] unpacked data:\n%s\n", __FUNCTION__, this->toString().c_str()); + } + + unsigned char * NetworkMessageIntro::packMessage() { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nIn [%s] about to pack...\n", __FUNCTION__); + pack(buf, getPackedMessageFormat(), messageType, - packedData.sessionId, - packedData.versionString.getBuffer(), - packedData.name.getBuffer(), - packedData.playerIndex, - packedData.gameState, - packedData.externalIp, - packedData.ftpPort, - packedData.language.getBuffer(), + data.sessionId, + data.versionString.getBuffer(), + data.name.getBuffer(), + data.playerIndex, + data.gameState, + data.externalIp, + data.ftpPort, + data.language.getBuffer(), data.gameInProgress, - packedData.playerUUID.getBuffer(), - packedData.platform.getBuffer()); - delete [] buf; - } - return result; -} -void NetworkMessageIntro::unpackMessage(unsigned char *buf) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nIn [%s] about to unpack...\n",__FUNCTION__); - unpack(buf, getPackedMessageFormat(), - &messageType, - &data.sessionId, - data.versionString.getBuffer(), - data.name.getBuffer(), - &data.playerIndex, - &data.gameState, - &data.externalIp, - &data.ftpPort, - data.language.getBuffer(), - &data.gameInProgress, - data.playerUUID.getBuffer(), - data.platform.getBuffer()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] unpacked data:\n%s\n",__FUNCTION__,this->toString().c_str()); -} - -unsigned char * NetworkMessageIntro::packMessage() { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nIn [%s] about to pack...\n",__FUNCTION__); - pack(buf, getPackedMessageFormat(), - messageType, - data.sessionId, - data.versionString.getBuffer(), - data.name.getBuffer(), - data.playerIndex, - data.gameState, - data.externalIp, - data.ftpPort, - data.language.getBuffer(), - data.gameInProgress, - data.playerUUID.getBuffer(), - data.platform.getBuffer()); - return buf; -} - -string NetworkMessageIntro::toString() const { - string result = "messageType = " + intToStr(messageType); - result += " sessionId = " + intToStr(data.sessionId); - result += " versionString = " + data.versionString.getString(); - result += " name = " + data.name.getString(); - result += " playerIndex = " + intToStr(data.playerIndex); - result += " gameState = " + intToStr(data.gameState); - result += " externalIp = " + uIntToStr(data.externalIp); - result += " ftpPort = " + uIntToStr(data.ftpPort); - result += " language = " + data.language.getString(); - result += " gameInProgress = " + uIntToStr(data.gameInProgress); - result += " playerUUID = " + data.playerUUID.getString(); - result += " platform = " + data.platform.getString(); - - return result; -} - -bool NetworkMessageIntro::receive(Socket* socket) { - bool result = false; - if(useOldProtocol == true) { - result = NetworkMessage::receive(socket, &data, sizeof(data), true); - if(result == true) { - messageType = this->getNetworkMessageType(); + data.playerUUID.getBuffer(), + data.platform.getBuffer()); + return buf; } - } - else { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - result = NetworkMessage::receive(socket, buf, getPackedSize(), true); - unpackMessage(buf); - //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); - delete [] buf; - } - fromEndian(); - data.name.nullTerminate(); - data.versionString.nullTerminate(); - data.language.nullTerminate(); - data.playerUUID.nullTerminate(); - data.platform.nullTerminate(); + string NetworkMessageIntro::toString() const { + string result = "messageType = " + intToStr(messageType); + result += " sessionId = " + intToStr(data.sessionId); + result += " versionString = " + data.versionString.getString(); + result += " name = " + data.name.getString(); + result += " playerIndex = " + intToStr(data.playerIndex); + result += " gameState = " + intToStr(data.gameState); + result += " externalIp = " + uIntToStr(data.externalIp); + result += " ftpPort = " + uIntToStr(data.ftpPort); + result += " language = " + data.language.getString(); + result += " gameInProgress = " + uIntToStr(data.gameInProgress); + result += " playerUUID = " + data.playerUUID.getString(); + result += " platform = " + data.platform.getString(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] get nmtIntro, data.playerIndex = %d, data.sessionId = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,data.playerIndex,data.sessionId); - return result; -} + return result; + } -void NetworkMessageIntro::send(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] sending nmtIntro, data.playerIndex = %d, data.sessionId = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,data.playerIndex,data.sessionId); - assert(messageType == nmtIntro); - toEndian(); + bool NetworkMessageIntro::receive(Socket* socket) { + bool result = false; + if (useOldProtocol == true) { + result = NetworkMessage::receive(socket, &data, sizeof(data), true); + if (result == true) { + messageType = this->getNetworkMessageType(); + } + } else { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + result = NetworkMessage::receive(socket, buf, getPackedSize(), true); + unpackMessage(buf); + //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); + delete[] buf; + } + fromEndian(); - if(useOldProtocol == true) { - //NetworkMessage::send(socket, &messageType, sizeof(messageType)); - NetworkMessage::send(socket, &data, sizeof(data),messageType); - } - else { - unsigned char *buf = packMessage(); - //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); - //NetworkMessage::send(socket, &data, sizeof(data)); - NetworkMessage::send(socket, buf, getPackedSize()); - delete [] buf; - } -} + data.name.nullTerminate(); + data.versionString.nullTerminate(); + data.language.nullTerminate(); + data.playerUUID.nullTerminate(); + data.platform.nullTerminate(); -void NetworkMessageIntro::toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); - data.sessionId = Shared::PlatformByteOrder::toCommonEndian(data.sessionId); - data.playerIndex = Shared::PlatformByteOrder::toCommonEndian(data.playerIndex); - data.gameState = Shared::PlatformByteOrder::toCommonEndian(data.gameState); - data.externalIp = Shared::PlatformByteOrder::toCommonEndian(data.externalIp); - data.ftpPort = Shared::PlatformByteOrder::toCommonEndian(data.ftpPort); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] get nmtIntro, data.playerIndex = %d, data.sessionId = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, data.playerIndex, data.sessionId); + return result; + } - data.gameInProgress = Shared::PlatformByteOrder::toCommonEndian(data.gameInProgress); - } -} -void NetworkMessageIntro::fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); - data.sessionId = Shared::PlatformByteOrder::fromCommonEndian(data.sessionId); - data.playerIndex = Shared::PlatformByteOrder::fromCommonEndian(data.playerIndex); - data.gameState = Shared::PlatformByteOrder::fromCommonEndian(data.gameState); - data.externalIp = Shared::PlatformByteOrder::fromCommonEndian(data.externalIp); - data.ftpPort = Shared::PlatformByteOrder::fromCommonEndian(data.ftpPort); + void NetworkMessageIntro::send(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] sending nmtIntro, data.playerIndex = %d, data.sessionId = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, data.playerIndex, data.sessionId); + assert(messageType == nmtIntro); + toEndian(); - data.gameInProgress = Shared::PlatformByteOrder::fromCommonEndian(data.gameInProgress); - } -} + if (useOldProtocol == true) { + //NetworkMessage::send(socket, &messageType, sizeof(messageType)); + NetworkMessage::send(socket, &data, sizeof(data), messageType); + } else { + unsigned char *buf = packMessage(); + //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); + //NetworkMessage::send(socket, &data, sizeof(data)); + NetworkMessage::send(socket, buf, getPackedSize()); + delete[] buf; + } + } -// ===================================================== -// class NetworkMessagePing -// ===================================================== + void NetworkMessageIntro::toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); + data.sessionId = Shared::PlatformByteOrder::toCommonEndian(data.sessionId); + data.playerIndex = Shared::PlatformByteOrder::toCommonEndian(data.playerIndex); + data.gameState = Shared::PlatformByteOrder::toCommonEndian(data.gameState); + data.externalIp = Shared::PlatformByteOrder::toCommonEndian(data.externalIp); + data.ftpPort = Shared::PlatformByteOrder::toCommonEndian(data.ftpPort); -NetworkMessagePing::NetworkMessagePing(){ - messageType = nmtPing; - data.pingFrequency = 0; - data.pingTime = 0; - pingReceivedLocalTime = 0; -} + data.gameInProgress = Shared::PlatformByteOrder::toCommonEndian(data.gameInProgress); + } + } + void NetworkMessageIntro::fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); + data.sessionId = Shared::PlatformByteOrder::fromCommonEndian(data.sessionId); + data.playerIndex = Shared::PlatformByteOrder::fromCommonEndian(data.playerIndex); + data.gameState = Shared::PlatformByteOrder::fromCommonEndian(data.gameState); + data.externalIp = Shared::PlatformByteOrder::fromCommonEndian(data.externalIp); + data.ftpPort = Shared::PlatformByteOrder::fromCommonEndian(data.ftpPort); -NetworkMessagePing::NetworkMessagePing(int32 pingFrequency, int64 pingTime){ - messageType= nmtPing; - data.pingFrequency= pingFrequency; - data.pingTime= pingTime; - pingReceivedLocalTime=0; -} + data.gameInProgress = Shared::PlatformByteOrder::fromCommonEndian(data.gameInProgress); + } + } -const char * NetworkMessagePing::getPackedMessageFormat() const { - return "clq"; -} + // ===================================================== + // class NetworkMessagePing + // ===================================================== -unsigned int NetworkMessagePing::getPackedSize() { - static unsigned int result = 0; - if(result == 0) { - Data packedData; - messageType = 0; - packedData.pingFrequency = 0; - packedData.pingTime = 0; - unsigned char *buf = new unsigned char[sizeof(packedData)*3]; - result = pack(buf, getPackedMessageFormat(), + NetworkMessagePing::NetworkMessagePing() { + messageType = nmtPing; + data.pingFrequency = 0; + data.pingTime = 0; + pingReceivedLocalTime = 0; + } + + NetworkMessagePing::NetworkMessagePing(int32 pingFrequency, int64 pingTime) { + messageType = nmtPing; + data.pingFrequency = pingFrequency; + data.pingTime = pingTime; + pingReceivedLocalTime = 0; + } + + const char * NetworkMessagePing::getPackedMessageFormat() const { + return "clq"; + } + + unsigned int NetworkMessagePing::getPackedSize() { + static unsigned int result = 0; + if (result == 0) { + Data packedData; + messageType = 0; + packedData.pingFrequency = 0; + packedData.pingTime = 0; + unsigned char *buf = new unsigned char[sizeof(packedData) * 3]; + result = pack(buf, getPackedMessageFormat(), + messageType, + packedData.pingFrequency, + packedData.pingTime); + delete[] buf; + } + return result; + } + void NetworkMessagePing::unpackMessage(unsigned char *buf) { + unpack(buf, getPackedMessageFormat(), + &messageType, + &data.pingFrequency, + &data.pingTime); + } + + unsigned char * NetworkMessagePing::packMessage() { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + pack(buf, getPackedMessageFormat(), messageType, - packedData.pingFrequency, - packedData.pingTime); - delete [] buf; - } - return result; -} -void NetworkMessagePing::unpackMessage(unsigned char *buf) { - unpack(buf, getPackedMessageFormat(), - &messageType, - &data.pingFrequency, - &data.pingTime); -} - -unsigned char * NetworkMessagePing::packMessage() { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - pack(buf, getPackedMessageFormat(), - messageType, - data.pingFrequency, - data.pingTime); - return buf; -} - -bool NetworkMessagePing::receive(Socket* socket){ - bool result = false; - if(useOldProtocol == true) { - result = NetworkMessage::receive(socket, &data, sizeof(data), true); - if(result == true) { - messageType = this->getNetworkMessageType(); + data.pingFrequency, + data.pingTime); + return buf; } - } - else { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - result = NetworkMessage::receive(socket, buf, getPackedSize(), true); - unpackMessage(buf); - //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); - delete [] buf; - } - fromEndian(); - pingReceivedLocalTime = time(NULL); - return result; -} + bool NetworkMessagePing::receive(Socket* socket) { + bool result = false; + if (useOldProtocol == true) { + result = NetworkMessage::receive(socket, &data, sizeof(data), true); + if (result == true) { + messageType = this->getNetworkMessageType(); + } + } else { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + result = NetworkMessage::receive(socket, buf, getPackedSize(), true); + unpackMessage(buf); + //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); + delete[] buf; + } + fromEndian(); -void NetworkMessagePing::send(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtPing\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - assert(messageType == nmtPing); - toEndian(); + pingReceivedLocalTime = time(NULL); + return result; + } - if(useOldProtocol == true) { - //NetworkMessage::send(socket, &messageType, sizeof(messageType)); - NetworkMessage::send(socket, &data, sizeof(data), messageType); - } - else { - unsigned char *buf = packMessage(); - //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); - //NetworkMessage::send(socket, &data, sizeof(data)); - NetworkMessage::send(socket, buf, getPackedSize()); - delete [] buf; - } -} + void NetworkMessagePing::send(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] nmtPing\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + assert(messageType == nmtPing); + toEndian(); -void NetworkMessagePing::toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); - data.pingFrequency = Shared::PlatformByteOrder::toCommonEndian(data.pingFrequency); - data.pingTime = Shared::PlatformByteOrder::toCommonEndian(data.pingTime); - } -} -void NetworkMessagePing::fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); - data.pingFrequency = Shared::PlatformByteOrder::fromCommonEndian(data.pingFrequency); - data.pingTime = Shared::PlatformByteOrder::fromCommonEndian(data.pingTime); - } -} + if (useOldProtocol == true) { + //NetworkMessage::send(socket, &messageType, sizeof(messageType)); + NetworkMessage::send(socket, &data, sizeof(data), messageType); + } else { + unsigned char *buf = packMessage(); + //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); + //NetworkMessage::send(socket, &data, sizeof(data)); + NetworkMessage::send(socket, buf, getPackedSize()); + delete[] buf; + } + } -// ===================================================== -// class NetworkMessageReady -// ===================================================== + void NetworkMessagePing::toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); + data.pingFrequency = Shared::PlatformByteOrder::toCommonEndian(data.pingFrequency); + data.pingTime = Shared::PlatformByteOrder::toCommonEndian(data.pingTime); + } + } + void NetworkMessagePing::fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); + data.pingFrequency = Shared::PlatformByteOrder::fromCommonEndian(data.pingFrequency); + data.pingTime = Shared::PlatformByteOrder::fromCommonEndian(data.pingTime); + } + } -NetworkMessageReady::NetworkMessageReady() { - messageType = nmtReady; - data.checksum= 0; -} + // ===================================================== + // class NetworkMessageReady + // ===================================================== -NetworkMessageReady::NetworkMessageReady(uint32 checksum) { - messageType = nmtReady; - data.checksum= checksum; -} + NetworkMessageReady::NetworkMessageReady() { + messageType = nmtReady; + data.checksum = 0; + } -const char * NetworkMessageReady::getPackedMessageFormat() const { - return "cL"; -} + NetworkMessageReady::NetworkMessageReady(uint32 checksum) { + messageType = nmtReady; + data.checksum = checksum; + } -unsigned int NetworkMessageReady::getPackedSize() { - static unsigned int result = 0; - if(result == 0) { - Data packedData; - packedData.checksum = 0; - messageType = 0; - unsigned char *buf = new unsigned char[sizeof(packedData)*3]; - result = pack(buf, getPackedMessageFormat(), + const char * NetworkMessageReady::getPackedMessageFormat() const { + return "cL"; + } + + unsigned int NetworkMessageReady::getPackedSize() { + static unsigned int result = 0; + if (result == 0) { + Data packedData; + packedData.checksum = 0; + messageType = 0; + unsigned char *buf = new unsigned char[sizeof(packedData) * 3]; + result = pack(buf, getPackedMessageFormat(), + messageType, + packedData.checksum); + delete[] buf; + } + return result; + } + void NetworkMessageReady::unpackMessage(unsigned char *buf) { + unpack(buf, getPackedMessageFormat(), + &messageType, + &data.checksum); + } + + unsigned char * NetworkMessageReady::packMessage() { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + pack(buf, getPackedMessageFormat(), messageType, - packedData.checksum); - delete [] buf; - } - return result; -} -void NetworkMessageReady::unpackMessage(unsigned char *buf) { - unpack(buf, getPackedMessageFormat(), - &messageType, - &data.checksum); -} - -unsigned char * NetworkMessageReady::packMessage() { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - pack(buf, getPackedMessageFormat(), - messageType, - data.checksum); - return buf; -} - -bool NetworkMessageReady::receive(Socket* socket){ - bool result = false; - if(useOldProtocol == true) { - result = NetworkMessage::receive(socket, &data, sizeof(data), true); - if(result == true) { - messageType = this->getNetworkMessageType(); + data.checksum); + return buf; } - } - else { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - //bool result = NetworkMessage::receive(socket, buf, getPackedSize(), true); - NetworkMessage::receive(socket, buf, getPackedSize(), true); - unpackMessage(buf); - //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); - delete [] buf; - } - fromEndian(); - return result; -} -void NetworkMessageReady::send(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtReady\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - assert(messageType == nmtReady); - toEndian(); - - if(useOldProtocol == true) { - //NetworkMessage::send(socket, &messageType, sizeof(messageType)); - NetworkMessage::send(socket, &data, sizeof(data), messageType); - } - else { - unsigned char *buf = packMessage(); - //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); - NetworkMessage::send(socket, buf, getPackedSize()); - delete [] buf; - } -} - -void NetworkMessageReady::toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); - data.checksum = Shared::PlatformByteOrder::toCommonEndian(data.checksum); - } -} -void NetworkMessageReady::fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); - data.checksum = Shared::PlatformByteOrder::fromCommonEndian(data.checksum); - } -} - -// ===================================================== -// class NetworkMessageLaunch -// ===================================================== - -NetworkMessageLaunch::NetworkMessageLaunch() { - messageType = -1; - compressedLength = 0; - for(unsigned int i = 0; i < (unsigned int)maxFactionCRCCount; ++i) { - data.factionNameList[i] = ""; - data.factionCRCList[i] = 0; - } - data.aiAcceptSwitchTeamPercentChance = 0; - data.cpuReplacementMultiplier = 10 ; - data.masterserver_admin = -1; - data.masterserver_admin_factionIndex = -1; -} - -NetworkMessageLaunch::NetworkMessageLaunch(const GameSettings *gameSettings,int8 messageType) { - this->messageType = messageType; - compressedLength = 0; - - data.mapFilter = gameSettings->getMapFilter(); - data.mapCRC = gameSettings->getMapCRC(); - data.tilesetCRC = gameSettings->getTilesetCRC(); - data.techCRC = gameSettings->getTechCRC(); - - for(unsigned int i = 0; i < (unsigned int)maxFactionCRCCount; ++i) { - data.factionNameList[i] = ""; - data.factionCRCList[i] = 0; - } - - vector > factionCRCList = gameSettings->getFactionCRCList(); - for(unsigned int i = 0; i < factionCRCList.size() && i < (unsigned int)maxFactionCRCCount; ++i) { - data.factionNameList[i] = factionCRCList[i].first; - data.factionCRCList[i] = factionCRCList[i].second; - } - - data.description= gameSettings->getDescription(); - data.map= gameSettings->getMap(); - data.tileset= gameSettings->getTileset(); - data.tech= gameSettings->getTech(); - data.factionCount= gameSettings->getFactionCount(); - data.thisFactionIndex= gameSettings->getThisFactionIndex(); - data.defaultResources= gameSettings->getDefaultResources(); - data.defaultUnits= gameSettings->getDefaultUnits(); - data.defaultVictoryConditions= gameSettings->getDefaultVictoryConditions(); - data.fogOfWar = gameSettings->getFogOfWar(); - data.allowObservers = gameSettings->getAllowObservers(); - data.enableObserverModeAtEndGame = gameSettings->getEnableObserverModeAtEndGame(); - data.enableServerControlledAI = gameSettings->getEnableServerControlledAI(); - data.networkFramePeriod = gameSettings->getNetworkFramePeriod(); - data.networkPauseGameForLaggedClients = gameSettings->getNetworkPauseGameForLaggedClients(); - data.pathFinderType = gameSettings->getPathFinderType(); - data.flagTypes1 = gameSettings->getFlagTypes1(); - - //for(int i= 0; i < data.factionCount; ++i) { - for(int i= 0; i < GameConstants::maxPlayers; ++i) { - data.factionTypeNames[i]= gameSettings->getFactionTypeName(i); - data.networkPlayerNames[i]= gameSettings->getNetworkPlayerName(i); - data.networkPlayerPlatform[i]= gameSettings->getNetworkPlayerPlatform(i); - data.networkPlayerStatuses[i] = gameSettings->getNetworkPlayerStatuses(i); - data.networkPlayerLanguages[i] = gameSettings->getNetworkPlayerLanguages(i); - data.factionControls[i]= gameSettings->getFactionControl(i); - data.resourceMultiplierIndex[i]= gameSettings->getResourceMultiplierIndex(i); - data.teams[i]= gameSettings->getTeam(i); - data.startLocationIndex[i]= gameSettings->getStartLocationIndex(i); - - data.networkPlayerUUID[i] = gameSettings->getNetworkPlayerUUID(i); - //printf("Build netmsg for index: %d [%s]\n",i,data.networkPlayerUUID[i].getString().c_str()); - } - data.cpuReplacementMultiplier = gameSettings->getFallbackCpuMultiplier(); - data.aiAcceptSwitchTeamPercentChance = gameSettings->getAiAcceptSwitchTeamPercentChance(); - data.masterserver_admin = gameSettings->getMasterserver_admin(); - data.masterserver_admin_factionIndex = gameSettings->getMasterserver_admin_faction_index(); - - data.scenario = gameSettings->getScenario(); - data.gameUUID = gameSettings->getGameUUID(); - - data.networkAllowNativeLanguageTechtree = gameSettings->getNetworkAllowNativeLanguageTechtree(); -} - -void NetworkMessageLaunch::buildGameSettings(GameSettings *gameSettings) const { - gameSettings->setDescription(data.description.getString()); - gameSettings->setMap(data.map.getString()); - gameSettings->setTileset(data.tileset.getString()); - gameSettings->setTech(data.tech.getString()); - gameSettings->setFactionCount(data.factionCount); - gameSettings->setThisFactionIndex(data.thisFactionIndex); - gameSettings->setDefaultResources((data.defaultResources != 0)); - gameSettings->setDefaultUnits((data.defaultUnits != 0)); - gameSettings->setDefaultVictoryConditions((data.defaultVictoryConditions != 0)); - gameSettings->setFogOfWar((data.fogOfWar != 0)); - gameSettings->setAllowObservers((data.allowObservers != 0)); - - gameSettings->setEnableObserverModeAtEndGame((data.enableObserverModeAtEndGame != 0)); - gameSettings->setEnableServerControlledAI((data.enableServerControlledAI != 0)); - gameSettings->setNetworkFramePeriod(data.networkFramePeriod); - gameSettings->setNetworkPauseGameForLaggedClients((data.networkPauseGameForLaggedClients != 0)); - gameSettings->setPathFinderType(static_cast(data.pathFinderType)); - gameSettings->setFlagTypes1(data.flagTypes1); - - gameSettings->setMapCRC(data.mapCRC); - gameSettings->setMapFilter(data.mapFilter); - gameSettings->setTilesetCRC(data.tilesetCRC); - gameSettings->setTechCRC(data.techCRC); - - vector > factionCRCList; - for(unsigned int i = 0; i < (unsigned int)maxFactionCRCCount; ++i) { - if(data.factionNameList[i].getString() != "") { - factionCRCList.push_back(make_pair(data.factionNameList[i].getString(),data.factionCRCList[i])); + bool NetworkMessageReady::receive(Socket* socket) { + bool result = false; + if (useOldProtocol == true) { + result = NetworkMessage::receive(socket, &data, sizeof(data), true); + if (result == true) { + messageType = this->getNetworkMessageType(); + } + } else { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + //bool result = NetworkMessage::receive(socket, buf, getPackedSize(), true); + NetworkMessage::receive(socket, buf, getPackedSize(), true); + unpackMessage(buf); + //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); + delete[] buf; + } + fromEndian(); + return result; } - } - gameSettings->setFactionCRCList(factionCRCList); - //for(int i= 0; i < data.factionCount; ++i) { - for(int i= 0; i < GameConstants::maxPlayers; ++i) { - gameSettings->setFactionTypeName(i, data.factionTypeNames[i].getString()); - gameSettings->setNetworkPlayerName(i,data.networkPlayerNames[i].getString()); - gameSettings->setNetworkPlayerPlatform(i,data.networkPlayerPlatform[i].getString()); - gameSettings->setNetworkPlayerStatuses(i, data.networkPlayerStatuses[i]); - gameSettings->setNetworkPlayerLanguages(i, data.networkPlayerLanguages[i].getString()); - gameSettings->setFactionControl(i, static_cast(data.factionControls[i])); - gameSettings->setResourceMultiplierIndex(i,data.resourceMultiplierIndex[i]); - gameSettings->setTeam(i, data.teams[i]); - gameSettings->setStartLocationIndex(i, data.startLocationIndex[i]); + void NetworkMessageReady::send(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] nmtReady\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + assert(messageType == nmtReady); + toEndian(); - gameSettings->setNetworkPlayerUUID(i,data.networkPlayerUUID[i].getString()); - gameSettings->setNetworkPlayerPlatform(i,data.networkPlayerPlatform[i].getString()); - //printf("Build game settings for index: %d [%s]\n",i,data.networkPlayerUUID[i].getString().c_str()); - } - - gameSettings->setAiAcceptSwitchTeamPercentChance(data.aiAcceptSwitchTeamPercentChance); - gameSettings->setFallbackCpuMultiplier(data.cpuReplacementMultiplier); - - gameSettings->setMasterserver_admin(data.masterserver_admin); - gameSettings->setMasterserver_admin_faction_index(data.masterserver_admin_factionIndex); - - gameSettings->setScenario(data.scenario.getString()); - - gameSettings->setGameUUID(data.gameUUID.getString()); - - gameSettings->setNetworkAllowNativeLanguageTechtree((data.networkAllowNativeLanguageTechtree != 0)); -} - -vector > NetworkMessageLaunch::getFactionCRCList() const { - - vector > factionCRCList; - for(unsigned int i = 0; i < (unsigned int)maxFactionCRCCount; ++i) { - if(data.factionNameList[i].getString() != "") { - factionCRCList.push_back(make_pair(data.factionNameList[i].getString(),data.factionCRCList[i])); + if (useOldProtocol == true) { + //NetworkMessage::send(socket, &messageType, sizeof(messageType)); + NetworkMessage::send(socket, &data, sizeof(data), messageType); + } else { + unsigned char *buf = packMessage(); + //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); + NetworkMessage::send(socket, buf, getPackedSize()); + delete[] buf; + } } - } - return factionCRCList; -} -const char * NetworkMessageLaunch::getPackedMessageFormat() const { - return "c256s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60sllllllll60s60s60s60s60s60s60s60sLLL60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60sLLLLLLLLLLLLLLLLLLLLcccccccccccccccccccccccccccccccccccccccccCccLccll256s60s60s60s60s60s60s60s60sc60s"; -} - -unsigned int NetworkMessageLaunch::getPackedSize() { - static unsigned int result = 0; - if(result == 0) { - Data packedData; - packedData.aiAcceptSwitchTeamPercentChance = 0; - packedData.allowObservers = 0; - packedData.cpuReplacementMultiplier = 0; - packedData.defaultResources = 0; - packedData.defaultUnits = 0; - packedData.defaultVictoryConditions = 0; - packedData.enableObserverModeAtEndGame = 0; - packedData.enableServerControlledAI = 0; - for(unsigned int index =0; index < (unsigned int)maxFactionCRCCount; ++index) { - packedData.factionCRCList[index] = 0; + void NetworkMessageReady::toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); + data.checksum = Shared::PlatformByteOrder::toCommonEndian(data.checksum); + } } - for(unsigned int index =0; index < (unsigned int)GameConstants::maxPlayers; ++index) { - packedData.factionControls[index] = 0; - packedData.networkPlayerStatuses[index] = 0; - packedData.resourceMultiplierIndex[index] = 0; - packedData.startLocationIndex[index] = 0; - packedData.teams[index] = 0; + void NetworkMessageReady::fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); + data.checksum = Shared::PlatformByteOrder::fromCommonEndian(data.checksum); + } } - packedData.factionCount = 0; - packedData.flagTypes1 = 0; - packedData.fogOfWar = 0; - packedData.mapCRC = 0; - packedData.mapFilter = 0; - packedData.masterserver_admin = 0; - packedData.masterserver_admin_factionIndex = 0; - messageType = 0; - packedData.networkAllowNativeLanguageTechtree = 0; - packedData.networkFramePeriod = 0; - packedData.networkPauseGameForLaggedClients = 0; - packedData.pathFinderType = 0; - packedData.techCRC = 0; - packedData.thisFactionIndex = 0; - packedData.tilesetCRC = 0; - unsigned char *buf = new unsigned char[sizeof(packedData)*3]; - result = pack(buf, getPackedMessageFormat(), - messageType, - packedData.description.getBuffer(), - packedData.map.getBuffer(), - packedData.tileset.getBuffer(), - packedData.tech.getBuffer(), - packedData.factionTypeNames[0].getBuffer(), - packedData.factionTypeNames[1].getBuffer(), - packedData.factionTypeNames[2].getBuffer(), - packedData.factionTypeNames[3].getBuffer(), - packedData.factionTypeNames[4].getBuffer(), - packedData.factionTypeNames[5].getBuffer(), - packedData.factionTypeNames[6].getBuffer(), - packedData.factionTypeNames[7].getBuffer(), - packedData.networkPlayerNames[0].getBuffer(), - packedData.networkPlayerNames[1].getBuffer(), - packedData.networkPlayerNames[2].getBuffer(), - packedData.networkPlayerNames[3].getBuffer(), - packedData.networkPlayerNames[4].getBuffer(), - packedData.networkPlayerNames[5].getBuffer(), - packedData.networkPlayerNames[6].getBuffer(), - packedData.networkPlayerNames[7].getBuffer(), - packedData.networkPlayerPlatform[0].getBuffer(), - packedData.networkPlayerPlatform[1].getBuffer(), - packedData.networkPlayerPlatform[2].getBuffer(), - packedData.networkPlayerPlatform[3].getBuffer(), - packedData.networkPlayerPlatform[4].getBuffer(), - packedData.networkPlayerPlatform[5].getBuffer(), - packedData.networkPlayerPlatform[6].getBuffer(), - packedData.networkPlayerPlatform[7].getBuffer(), - packedData.networkPlayerStatuses[0], - packedData.networkPlayerStatuses[1], - packedData.networkPlayerStatuses[2], - packedData.networkPlayerStatuses[3], - packedData.networkPlayerStatuses[4], - packedData.networkPlayerStatuses[5], - packedData.networkPlayerStatuses[6], - packedData.networkPlayerStatuses[7], - packedData.networkPlayerLanguages[0].getBuffer(), - packedData.networkPlayerLanguages[1].getBuffer(), - packedData.networkPlayerLanguages[2].getBuffer(), - packedData.networkPlayerLanguages[3].getBuffer(), - packedData.networkPlayerLanguages[4].getBuffer(), - packedData.networkPlayerLanguages[5].getBuffer(), - packedData.networkPlayerLanguages[6].getBuffer(), - packedData.networkPlayerLanguages[7].getBuffer(), - packedData.mapCRC, - packedData.mapFilter, - packedData.tilesetCRC, - packedData.techCRC, - packedData.factionNameList[0].getBuffer(), - packedData.factionNameList[1].getBuffer(), - packedData.factionNameList[2].getBuffer(), - packedData.factionNameList[3].getBuffer(), - packedData.factionNameList[4].getBuffer(), - packedData.factionNameList[5].getBuffer(), - packedData.factionNameList[6].getBuffer(), - packedData.factionNameList[7].getBuffer(), - packedData.factionNameList[8].getBuffer(), - packedData.factionNameList[9].getBuffer(), - packedData.factionNameList[10].getBuffer(), - packedData.factionNameList[11].getBuffer(), - packedData.factionNameList[12].getBuffer(), - packedData.factionNameList[13].getBuffer(), - packedData.factionNameList[14].getBuffer(), - packedData.factionNameList[15].getBuffer(), - packedData.factionNameList[16].getBuffer(), - packedData.factionNameList[17].getBuffer(), - packedData.factionNameList[18].getBuffer(), - packedData.factionNameList[19].getBuffer(), - packedData.factionCRCList[0], - packedData.factionCRCList[1], - packedData.factionCRCList[2], - packedData.factionCRCList[3], - packedData.factionCRCList[4], - packedData.factionCRCList[5], - packedData.factionCRCList[6], - packedData.factionCRCList[7], - packedData.factionCRCList[8], - packedData.factionCRCList[9], - packedData.factionCRCList[10], - packedData.factionCRCList[11], - packedData.factionCRCList[12], - packedData.factionCRCList[13], - packedData.factionCRCList[14], - packedData.factionCRCList[15], - packedData.factionCRCList[16], - packedData.factionCRCList[17], - packedData.factionCRCList[18], - packedData.factionCRCList[19], - packedData.factionControls[0], - packedData.factionControls[1], - packedData.factionControls[2], - packedData.factionControls[3], - packedData.factionControls[4], - packedData.factionControls[5], - packedData.factionControls[6], - packedData.factionControls[7], - packedData.resourceMultiplierIndex[0], - packedData.resourceMultiplierIndex[1], - packedData.resourceMultiplierIndex[2], - packedData.resourceMultiplierIndex[3], - packedData.resourceMultiplierIndex[4], - packedData.resourceMultiplierIndex[5], - packedData.resourceMultiplierIndex[6], - packedData.resourceMultiplierIndex[7], - packedData.thisFactionIndex, - packedData.factionCount, - packedData.teams[0], - packedData.teams[1], - packedData.teams[2], - packedData.teams[3], - packedData.teams[4], - packedData.teams[5], - packedData.teams[6], - packedData.teams[7], - packedData.startLocationIndex[0], - packedData.startLocationIndex[1], - packedData.startLocationIndex[2], - packedData.startLocationIndex[3], - packedData.startLocationIndex[4], - packedData.startLocationIndex[5], - packedData.startLocationIndex[6], - packedData.startLocationIndex[7], - packedData.defaultResources, - packedData.defaultUnits, - packedData.defaultVictoryConditions, - packedData.fogOfWar, - packedData.allowObservers, - packedData.enableObserverModeAtEndGame, - packedData.enableServerControlledAI, - packedData.networkFramePeriod, - packedData.networkPauseGameForLaggedClients, - packedData.pathFinderType, - packedData.flagTypes1, - packedData.aiAcceptSwitchTeamPercentChance, - packedData.cpuReplacementMultiplier, - packedData.masterserver_admin, - packedData.masterserver_admin_factionIndex, - packedData.scenario.getBuffer(), - packedData.networkPlayerUUID[0].getBuffer(), - packedData.networkPlayerUUID[1].getBuffer(), - packedData.networkPlayerUUID[2].getBuffer(), - packedData.networkPlayerUUID[3].getBuffer(), - packedData.networkPlayerUUID[4].getBuffer(), - packedData.networkPlayerUUID[5].getBuffer(), - packedData.networkPlayerUUID[6].getBuffer(), - packedData.networkPlayerUUID[7].getBuffer(), - packedData.networkAllowNativeLanguageTechtree, - packedData.gameUUID.getBuffer() - ); - delete [] buf; - } - return result; -} -void NetworkMessageLaunch::unpackMessage(unsigned char *buf) { - unpack(buf, getPackedMessageFormat(), - &messageType, - data.description.getBuffer(), - data.map.getBuffer(), - data.tileset.getBuffer(), - data.tech.getBuffer(), - data.factionTypeNames[0].getBuffer(), - data.factionTypeNames[1].getBuffer(), - data.factionTypeNames[2].getBuffer(), - data.factionTypeNames[3].getBuffer(), - data.factionTypeNames[4].getBuffer(), - data.factionTypeNames[5].getBuffer(), - data.factionTypeNames[6].getBuffer(), - data.factionTypeNames[7].getBuffer(), - data.networkPlayerNames[0].getBuffer(), - data.networkPlayerNames[1].getBuffer(), - data.networkPlayerNames[2].getBuffer(), - data.networkPlayerNames[3].getBuffer(), - data.networkPlayerNames[4].getBuffer(), - data.networkPlayerNames[5].getBuffer(), - data.networkPlayerNames[6].getBuffer(), - data.networkPlayerNames[7].getBuffer(), - data.networkPlayerPlatform[0].getBuffer(), - data.networkPlayerPlatform[1].getBuffer(), - data.networkPlayerPlatform[2].getBuffer(), - data.networkPlayerPlatform[3].getBuffer(), - data.networkPlayerPlatform[4].getBuffer(), - data.networkPlayerPlatform[5].getBuffer(), - data.networkPlayerPlatform[6].getBuffer(), - data.networkPlayerPlatform[7].getBuffer(), - &data.networkPlayerStatuses[0], - &data.networkPlayerStatuses[1], - &data.networkPlayerStatuses[2], - &data.networkPlayerStatuses[3], - &data.networkPlayerStatuses[4], - &data.networkPlayerStatuses[5], - &data.networkPlayerStatuses[6], - &data.networkPlayerStatuses[7], - data.networkPlayerLanguages[0].getBuffer(), - data.networkPlayerLanguages[1].getBuffer(), - data.networkPlayerLanguages[2].getBuffer(), - data.networkPlayerLanguages[3].getBuffer(), - data.networkPlayerLanguages[4].getBuffer(), - data.networkPlayerLanguages[5].getBuffer(), - data.networkPlayerLanguages[6].getBuffer(), - data.networkPlayerLanguages[7].getBuffer(), - &data.mapFilter, - &data.mapCRC, - &data.tilesetCRC, - &data.techCRC, - data.factionNameList[0].getBuffer(), - data.factionNameList[1].getBuffer(), - data.factionNameList[2].getBuffer(), - data.factionNameList[3].getBuffer(), - data.factionNameList[4].getBuffer(), - data.factionNameList[5].getBuffer(), - data.factionNameList[6].getBuffer(), - data.factionNameList[7].getBuffer(), - data.factionNameList[8].getBuffer(), - data.factionNameList[9].getBuffer(), - data.factionNameList[10].getBuffer(), - data.factionNameList[11].getBuffer(), - data.factionNameList[12].getBuffer(), - data.factionNameList[13].getBuffer(), - data.factionNameList[14].getBuffer(), - data.factionNameList[15].getBuffer(), - data.factionNameList[16].getBuffer(), - data.factionNameList[17].getBuffer(), - data.factionNameList[18].getBuffer(), - data.factionNameList[19].getBuffer(), - &data.factionCRCList[0], - &data.factionCRCList[1], - &data.factionCRCList[2], - &data.factionCRCList[3], - &data.factionCRCList[4], - &data.factionCRCList[5], - &data.factionCRCList[6], - &data.factionCRCList[7], - &data.factionCRCList[8], - &data.factionCRCList[9], - &data.factionCRCList[10], - &data.factionCRCList[11], - &data.factionCRCList[12], - &data.factionCRCList[13], - &data.factionCRCList[14], - &data.factionCRCList[15], - &data.factionCRCList[16], - &data.factionCRCList[17], - &data.factionCRCList[18], - &data.factionCRCList[19], - &data.factionControls[0], - &data.factionControls[1], - &data.factionControls[2], - &data.factionControls[3], - &data.factionControls[4], - &data.factionControls[5], - &data.factionControls[6], - &data.factionControls[7], - &data.resourceMultiplierIndex[0], - &data.resourceMultiplierIndex[1], - &data.resourceMultiplierIndex[2], - &data.resourceMultiplierIndex[3], - &data.resourceMultiplierIndex[4], - &data.resourceMultiplierIndex[5], - &data.resourceMultiplierIndex[6], - &data.resourceMultiplierIndex[7], - &data.thisFactionIndex, - &data.factionCount, - &data.teams[0], - &data.teams[1], - &data.teams[2], - &data.teams[3], - &data.teams[4], - &data.teams[5], - &data.teams[6], - &data.teams[7], - &data.startLocationIndex[0], - &data.startLocationIndex[1], - &data.startLocationIndex[2], - &data.startLocationIndex[3], - &data.startLocationIndex[4], - &data.startLocationIndex[5], - &data.startLocationIndex[6], - &data.startLocationIndex[7], - &data.defaultResources, - &data.defaultUnits, - &data.defaultVictoryConditions, - &data.fogOfWar, - &data.allowObservers, - &data.enableObserverModeAtEndGame, - &data.enableServerControlledAI, - &data.networkFramePeriod, - &data.networkPauseGameForLaggedClients, - &data.pathFinderType, - &data.flagTypes1, - &data.aiAcceptSwitchTeamPercentChance, - &data.cpuReplacementMultiplier, - &data.masterserver_admin, - &data.masterserver_admin_factionIndex, - data.scenario.getBuffer(), - data.networkPlayerUUID[0].getBuffer(), - data.networkPlayerUUID[1].getBuffer(), - data.networkPlayerUUID[2].getBuffer(), - data.networkPlayerUUID[3].getBuffer(), - data.networkPlayerUUID[4].getBuffer(), - data.networkPlayerUUID[5].getBuffer(), - data.networkPlayerUUID[6].getBuffer(), - data.networkPlayerUUID[7].getBuffer(), - &data.networkAllowNativeLanguageTechtree, - data.gameUUID.getBuffer() - ); -} + // ===================================================== + // class NetworkMessageLaunch + // ===================================================== -unsigned char * NetworkMessageLaunch::packMessage() { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - pack(buf, getPackedMessageFormat(), - messageType, - data.description.getBuffer(), - data.map.getBuffer(), - data.tileset.getBuffer(), - data.tech.getBuffer(), - data.factionTypeNames[0].getBuffer(), - data.factionTypeNames[1].getBuffer(), - data.factionTypeNames[2].getBuffer(), - data.factionTypeNames[3].getBuffer(), - data.factionTypeNames[4].getBuffer(), - data.factionTypeNames[5].getBuffer(), - data.factionTypeNames[6].getBuffer(), - data.factionTypeNames[7].getBuffer(), - data.networkPlayerNames[0].getBuffer(), - data.networkPlayerNames[1].getBuffer(), - data.networkPlayerNames[2].getBuffer(), - data.networkPlayerNames[3].getBuffer(), - data.networkPlayerNames[4].getBuffer(), - data.networkPlayerNames[5].getBuffer(), - data.networkPlayerNames[6].getBuffer(), - data.networkPlayerNames[7].getBuffer(), - data.networkPlayerPlatform[0].getBuffer(), - data.networkPlayerPlatform[1].getBuffer(), - data.networkPlayerPlatform[2].getBuffer(), - data.networkPlayerPlatform[3].getBuffer(), - data.networkPlayerPlatform[4].getBuffer(), - data.networkPlayerPlatform[5].getBuffer(), - data.networkPlayerPlatform[6].getBuffer(), - data.networkPlayerPlatform[7].getBuffer(), - data.networkPlayerStatuses[0], - data.networkPlayerStatuses[1], - data.networkPlayerStatuses[2], - data.networkPlayerStatuses[3], - data.networkPlayerStatuses[4], - data.networkPlayerStatuses[5], - data.networkPlayerStatuses[6], - data.networkPlayerStatuses[7], - data.networkPlayerLanguages[0].getBuffer(), - data.networkPlayerLanguages[1].getBuffer(), - data.networkPlayerLanguages[2].getBuffer(), - data.networkPlayerLanguages[3].getBuffer(), - data.networkPlayerLanguages[4].getBuffer(), - data.networkPlayerLanguages[5].getBuffer(), - data.networkPlayerLanguages[6].getBuffer(), - data.networkPlayerLanguages[7].getBuffer(), - data.mapFilter, - data.mapCRC, - data.tilesetCRC, - data.techCRC, - data.factionNameList[0].getBuffer(), - data.factionNameList[1].getBuffer(), - data.factionNameList[2].getBuffer(), - data.factionNameList[3].getBuffer(), - data.factionNameList[4].getBuffer(), - data.factionNameList[5].getBuffer(), - data.factionNameList[6].getBuffer(), - data.factionNameList[7].getBuffer(), - data.factionNameList[8].getBuffer(), - data.factionNameList[9].getBuffer(), - data.factionNameList[10].getBuffer(), - data.factionNameList[11].getBuffer(), - data.factionNameList[12].getBuffer(), - data.factionNameList[13].getBuffer(), - data.factionNameList[14].getBuffer(), - data.factionNameList[15].getBuffer(), - data.factionNameList[16].getBuffer(), - data.factionNameList[17].getBuffer(), - data.factionNameList[18].getBuffer(), - data.factionNameList[19].getBuffer(), - data.factionCRCList[0], - data.factionCRCList[1], - data.factionCRCList[2], - data.factionCRCList[3], - data.factionCRCList[4], - data.factionCRCList[5], - data.factionCRCList[6], - data.factionCRCList[7], - data.factionCRCList[8], - data.factionCRCList[9], - data.factionCRCList[10], - data.factionCRCList[11], - data.factionCRCList[12], - data.factionCRCList[13], - data.factionCRCList[14], - data.factionCRCList[15], - data.factionCRCList[16], - data.factionCRCList[17], - data.factionCRCList[18], - data.factionCRCList[19], - data.factionControls[0], - data.factionControls[1], - data.factionControls[2], - data.factionControls[3], - data.factionControls[4], - data.factionControls[5], - data.factionControls[6], - data.factionControls[7], - data.resourceMultiplierIndex[0], - data.resourceMultiplierIndex[1], - data.resourceMultiplierIndex[2], - data.resourceMultiplierIndex[3], - data.resourceMultiplierIndex[4], - data.resourceMultiplierIndex[5], - data.resourceMultiplierIndex[6], - data.resourceMultiplierIndex[7], - data.thisFactionIndex, - data.factionCount, - data.teams[0], - data.teams[1], - data.teams[2], - data.teams[3], - data.teams[4], - data.teams[5], - data.teams[6], - data.teams[7], - data.startLocationIndex[0], - data.startLocationIndex[1], - data.startLocationIndex[2], - data.startLocationIndex[3], - data.startLocationIndex[4], - data.startLocationIndex[5], - data.startLocationIndex[6], - data.startLocationIndex[7], - data.defaultResources, - data.defaultUnits, - data.defaultVictoryConditions, - data.fogOfWar, - data.allowObservers, - data.enableObserverModeAtEndGame, - data.enableServerControlledAI, - data.networkFramePeriod, - data.networkPauseGameForLaggedClients, - data.pathFinderType, - data.flagTypes1, - data.aiAcceptSwitchTeamPercentChance, - data.cpuReplacementMultiplier, - data.masterserver_admin, - data.masterserver_admin_factionIndex, - data.scenario.getBuffer(), - data.networkPlayerUUID[0].getBuffer(), - data.networkPlayerUUID[1].getBuffer(), - data.networkPlayerUUID[2].getBuffer(), - data.networkPlayerUUID[3].getBuffer(), - data.networkPlayerUUID[4].getBuffer(), - data.networkPlayerUUID[5].getBuffer(), - data.networkPlayerUUID[6].getBuffer(), - data.networkPlayerUUID[7].getBuffer(), - data.networkAllowNativeLanguageTechtree, - data.gameUUID.getBuffer() + NetworkMessageLaunch::NetworkMessageLaunch() { + messageType = -1; + compressedLength = 0; + for (unsigned int i = 0; i < (unsigned int) maxFactionCRCCount; ++i) { + data.factionNameList[i] = ""; + data.factionCRCList[i] = 0; + } + data.aiAcceptSwitchTeamPercentChance = 0; + data.cpuReplacementMultiplier = 10; + data.masterserver_admin = -1; + data.masterserver_admin_factionIndex = -1; + } + + NetworkMessageLaunch::NetworkMessageLaunch(const GameSettings *gameSettings, int8 messageType) { + this->messageType = messageType; + compressedLength = 0; + + data.mapFilter = gameSettings->getMapFilter(); + data.mapCRC = gameSettings->getMapCRC(); + data.tilesetCRC = gameSettings->getTilesetCRC(); + data.techCRC = gameSettings->getTechCRC(); + + for (unsigned int i = 0; i < (unsigned int) maxFactionCRCCount; ++i) { + data.factionNameList[i] = ""; + data.factionCRCList[i] = 0; + } + + vector > factionCRCList = gameSettings->getFactionCRCList(); + for (unsigned int i = 0; i < factionCRCList.size() && i < (unsigned int) maxFactionCRCCount; ++i) { + data.factionNameList[i] = factionCRCList[i].first; + data.factionCRCList[i] = factionCRCList[i].second; + } + + data.description = gameSettings->getDescription(); + data.map = gameSettings->getMap(); + data.tileset = gameSettings->getTileset(); + data.tech = gameSettings->getTech(); + data.factionCount = gameSettings->getFactionCount(); + data.thisFactionIndex = gameSettings->getThisFactionIndex(); + data.defaultResources = gameSettings->getDefaultResources(); + data.defaultUnits = gameSettings->getDefaultUnits(); + data.defaultVictoryConditions = gameSettings->getDefaultVictoryConditions(); + data.fogOfWar = gameSettings->getFogOfWar(); + data.allowObservers = gameSettings->getAllowObservers(); + data.enableObserverModeAtEndGame = gameSettings->getEnableObserverModeAtEndGame(); + data.enableServerControlledAI = gameSettings->getEnableServerControlledAI(); + data.networkFramePeriod = gameSettings->getNetworkFramePeriod(); + data.networkPauseGameForLaggedClients = gameSettings->getNetworkPauseGameForLaggedClients(); + data.pathFinderType = gameSettings->getPathFinderType(); + data.flagTypes1 = gameSettings->getFlagTypes1(); + + //for(int i= 0; i < data.factionCount; ++i) { + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + data.factionTypeNames[i] = gameSettings->getFactionTypeName(i); + data.networkPlayerNames[i] = gameSettings->getNetworkPlayerName(i); + data.networkPlayerPlatform[i] = gameSettings->getNetworkPlayerPlatform(i); + data.networkPlayerStatuses[i] = gameSettings->getNetworkPlayerStatuses(i); + data.networkPlayerLanguages[i] = gameSettings->getNetworkPlayerLanguages(i); + data.factionControls[i] = gameSettings->getFactionControl(i); + data.resourceMultiplierIndex[i] = gameSettings->getResourceMultiplierIndex(i); + data.teams[i] = gameSettings->getTeam(i); + data.startLocationIndex[i] = gameSettings->getStartLocationIndex(i); + + data.networkPlayerUUID[i] = gameSettings->getNetworkPlayerUUID(i); + //printf("Build netmsg for index: %d [%s]\n",i,data.networkPlayerUUID[i].getString().c_str()); + } + data.cpuReplacementMultiplier = gameSettings->getFallbackCpuMultiplier(); + data.aiAcceptSwitchTeamPercentChance = gameSettings->getAiAcceptSwitchTeamPercentChance(); + data.masterserver_admin = gameSettings->getMasterserver_admin(); + data.masterserver_admin_factionIndex = gameSettings->getMasterserver_admin_faction_index(); + + data.scenario = gameSettings->getScenario(); + data.gameUUID = gameSettings->getGameUUID(); + + data.networkAllowNativeLanguageTechtree = gameSettings->getNetworkAllowNativeLanguageTechtree(); + } + + void NetworkMessageLaunch::buildGameSettings(GameSettings *gameSettings) const { + gameSettings->setDescription(data.description.getString()); + gameSettings->setMap(data.map.getString()); + gameSettings->setTileset(data.tileset.getString()); + gameSettings->setTech(data.tech.getString()); + gameSettings->setFactionCount(data.factionCount); + gameSettings->setThisFactionIndex(data.thisFactionIndex); + gameSettings->setDefaultResources((data.defaultResources != 0)); + gameSettings->setDefaultUnits((data.defaultUnits != 0)); + gameSettings->setDefaultVictoryConditions((data.defaultVictoryConditions != 0)); + gameSettings->setFogOfWar((data.fogOfWar != 0)); + gameSettings->setAllowObservers((data.allowObservers != 0)); + + gameSettings->setEnableObserverModeAtEndGame((data.enableObserverModeAtEndGame != 0)); + gameSettings->setEnableServerControlledAI((data.enableServerControlledAI != 0)); + gameSettings->setNetworkFramePeriod(data.networkFramePeriod); + gameSettings->setNetworkPauseGameForLaggedClients((data.networkPauseGameForLaggedClients != 0)); + gameSettings->setPathFinderType(static_cast(data.pathFinderType)); + gameSettings->setFlagTypes1(data.flagTypes1); + + gameSettings->setMapCRC(data.mapCRC); + gameSettings->setMapFilter(data.mapFilter); + gameSettings->setTilesetCRC(data.tilesetCRC); + gameSettings->setTechCRC(data.techCRC); + + vector > factionCRCList; + for (unsigned int i = 0; i < (unsigned int) maxFactionCRCCount; ++i) { + if (data.factionNameList[i].getString() != "") { + factionCRCList.push_back(make_pair(data.factionNameList[i].getString(), data.factionCRCList[i])); + } + } + gameSettings->setFactionCRCList(factionCRCList); + + //for(int i= 0; i < data.factionCount; ++i) { + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + gameSettings->setFactionTypeName(i, data.factionTypeNames[i].getString()); + gameSettings->setNetworkPlayerName(i, data.networkPlayerNames[i].getString()); + gameSettings->setNetworkPlayerPlatform(i, data.networkPlayerPlatform[i].getString()); + gameSettings->setNetworkPlayerStatuses(i, data.networkPlayerStatuses[i]); + gameSettings->setNetworkPlayerLanguages(i, data.networkPlayerLanguages[i].getString()); + gameSettings->setFactionControl(i, static_cast(data.factionControls[i])); + gameSettings->setResourceMultiplierIndex(i, data.resourceMultiplierIndex[i]); + gameSettings->setTeam(i, data.teams[i]); + gameSettings->setStartLocationIndex(i, data.startLocationIndex[i]); + + gameSettings->setNetworkPlayerUUID(i, data.networkPlayerUUID[i].getString()); + gameSettings->setNetworkPlayerPlatform(i, data.networkPlayerPlatform[i].getString()); + //printf("Build game settings for index: %d [%s]\n",i,data.networkPlayerUUID[i].getString().c_str()); + } + + gameSettings->setAiAcceptSwitchTeamPercentChance(data.aiAcceptSwitchTeamPercentChance); + gameSettings->setFallbackCpuMultiplier(data.cpuReplacementMultiplier); + + gameSettings->setMasterserver_admin(data.masterserver_admin); + gameSettings->setMasterserver_admin_faction_index(data.masterserver_admin_factionIndex); + + gameSettings->setScenario(data.scenario.getString()); + + gameSettings->setGameUUID(data.gameUUID.getString()); + + gameSettings->setNetworkAllowNativeLanguageTechtree((data.networkAllowNativeLanguageTechtree != 0)); + } + + vector > NetworkMessageLaunch::getFactionCRCList() const { + + vector > factionCRCList; + for (unsigned int i = 0; i < (unsigned int) maxFactionCRCCount; ++i) { + if (data.factionNameList[i].getString() != "") { + factionCRCList.push_back(make_pair(data.factionNameList[i].getString(), data.factionCRCList[i])); + } + } + return factionCRCList; + } + + const char * NetworkMessageLaunch::getPackedMessageFormat() const { + return "c256s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60sllllllll60s60s60s60s60s60s60s60sLLL60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60sLLLLLLLLLLLLLLLLLLLLcccccccccccccccccccccccccccccccccccccccccCccLccll256s60s60s60s60s60s60s60s60sc60s"; + } + + unsigned int NetworkMessageLaunch::getPackedSize() { + static unsigned int result = 0; + if (result == 0) { + Data packedData; + packedData.aiAcceptSwitchTeamPercentChance = 0; + packedData.allowObservers = 0; + packedData.cpuReplacementMultiplier = 0; + packedData.defaultResources = 0; + packedData.defaultUnits = 0; + packedData.defaultVictoryConditions = 0; + packedData.enableObserverModeAtEndGame = 0; + packedData.enableServerControlledAI = 0; + for (unsigned int index = 0; index < (unsigned int) maxFactionCRCCount; ++index) { + packedData.factionCRCList[index] = 0; + } + for (unsigned int index = 0; index < (unsigned int) GameConstants::maxPlayers; ++index) { + packedData.factionControls[index] = 0; + packedData.networkPlayerStatuses[index] = 0; + packedData.resourceMultiplierIndex[index] = 0; + packedData.startLocationIndex[index] = 0; + packedData.teams[index] = 0; + } + packedData.factionCount = 0; + packedData.flagTypes1 = 0; + packedData.fogOfWar = 0; + packedData.mapCRC = 0; + packedData.mapFilter = 0; + packedData.masterserver_admin = 0; + packedData.masterserver_admin_factionIndex = 0; + messageType = 0; + packedData.networkAllowNativeLanguageTechtree = 0; + packedData.networkFramePeriod = 0; + packedData.networkPauseGameForLaggedClients = 0; + packedData.pathFinderType = 0; + packedData.techCRC = 0; + packedData.thisFactionIndex = 0; + packedData.tilesetCRC = 0; + + unsigned char *buf = new unsigned char[sizeof(packedData) * 3]; + result = pack(buf, getPackedMessageFormat(), + messageType, + packedData.description.getBuffer(), + packedData.map.getBuffer(), + packedData.tileset.getBuffer(), + packedData.tech.getBuffer(), + packedData.factionTypeNames[0].getBuffer(), + packedData.factionTypeNames[1].getBuffer(), + packedData.factionTypeNames[2].getBuffer(), + packedData.factionTypeNames[3].getBuffer(), + packedData.factionTypeNames[4].getBuffer(), + packedData.factionTypeNames[5].getBuffer(), + packedData.factionTypeNames[6].getBuffer(), + packedData.factionTypeNames[7].getBuffer(), + packedData.networkPlayerNames[0].getBuffer(), + packedData.networkPlayerNames[1].getBuffer(), + packedData.networkPlayerNames[2].getBuffer(), + packedData.networkPlayerNames[3].getBuffer(), + packedData.networkPlayerNames[4].getBuffer(), + packedData.networkPlayerNames[5].getBuffer(), + packedData.networkPlayerNames[6].getBuffer(), + packedData.networkPlayerNames[7].getBuffer(), + packedData.networkPlayerPlatform[0].getBuffer(), + packedData.networkPlayerPlatform[1].getBuffer(), + packedData.networkPlayerPlatform[2].getBuffer(), + packedData.networkPlayerPlatform[3].getBuffer(), + packedData.networkPlayerPlatform[4].getBuffer(), + packedData.networkPlayerPlatform[5].getBuffer(), + packedData.networkPlayerPlatform[6].getBuffer(), + packedData.networkPlayerPlatform[7].getBuffer(), + packedData.networkPlayerStatuses[0], + packedData.networkPlayerStatuses[1], + packedData.networkPlayerStatuses[2], + packedData.networkPlayerStatuses[3], + packedData.networkPlayerStatuses[4], + packedData.networkPlayerStatuses[5], + packedData.networkPlayerStatuses[6], + packedData.networkPlayerStatuses[7], + packedData.networkPlayerLanguages[0].getBuffer(), + packedData.networkPlayerLanguages[1].getBuffer(), + packedData.networkPlayerLanguages[2].getBuffer(), + packedData.networkPlayerLanguages[3].getBuffer(), + packedData.networkPlayerLanguages[4].getBuffer(), + packedData.networkPlayerLanguages[5].getBuffer(), + packedData.networkPlayerLanguages[6].getBuffer(), + packedData.networkPlayerLanguages[7].getBuffer(), + packedData.mapCRC, + packedData.mapFilter, + packedData.tilesetCRC, + packedData.techCRC, + packedData.factionNameList[0].getBuffer(), + packedData.factionNameList[1].getBuffer(), + packedData.factionNameList[2].getBuffer(), + packedData.factionNameList[3].getBuffer(), + packedData.factionNameList[4].getBuffer(), + packedData.factionNameList[5].getBuffer(), + packedData.factionNameList[6].getBuffer(), + packedData.factionNameList[7].getBuffer(), + packedData.factionNameList[8].getBuffer(), + packedData.factionNameList[9].getBuffer(), + packedData.factionNameList[10].getBuffer(), + packedData.factionNameList[11].getBuffer(), + packedData.factionNameList[12].getBuffer(), + packedData.factionNameList[13].getBuffer(), + packedData.factionNameList[14].getBuffer(), + packedData.factionNameList[15].getBuffer(), + packedData.factionNameList[16].getBuffer(), + packedData.factionNameList[17].getBuffer(), + packedData.factionNameList[18].getBuffer(), + packedData.factionNameList[19].getBuffer(), + packedData.factionCRCList[0], + packedData.factionCRCList[1], + packedData.factionCRCList[2], + packedData.factionCRCList[3], + packedData.factionCRCList[4], + packedData.factionCRCList[5], + packedData.factionCRCList[6], + packedData.factionCRCList[7], + packedData.factionCRCList[8], + packedData.factionCRCList[9], + packedData.factionCRCList[10], + packedData.factionCRCList[11], + packedData.factionCRCList[12], + packedData.factionCRCList[13], + packedData.factionCRCList[14], + packedData.factionCRCList[15], + packedData.factionCRCList[16], + packedData.factionCRCList[17], + packedData.factionCRCList[18], + packedData.factionCRCList[19], + packedData.factionControls[0], + packedData.factionControls[1], + packedData.factionControls[2], + packedData.factionControls[3], + packedData.factionControls[4], + packedData.factionControls[5], + packedData.factionControls[6], + packedData.factionControls[7], + packedData.resourceMultiplierIndex[0], + packedData.resourceMultiplierIndex[1], + packedData.resourceMultiplierIndex[2], + packedData.resourceMultiplierIndex[3], + packedData.resourceMultiplierIndex[4], + packedData.resourceMultiplierIndex[5], + packedData.resourceMultiplierIndex[6], + packedData.resourceMultiplierIndex[7], + packedData.thisFactionIndex, + packedData.factionCount, + packedData.teams[0], + packedData.teams[1], + packedData.teams[2], + packedData.teams[3], + packedData.teams[4], + packedData.teams[5], + packedData.teams[6], + packedData.teams[7], + packedData.startLocationIndex[0], + packedData.startLocationIndex[1], + packedData.startLocationIndex[2], + packedData.startLocationIndex[3], + packedData.startLocationIndex[4], + packedData.startLocationIndex[5], + packedData.startLocationIndex[6], + packedData.startLocationIndex[7], + packedData.defaultResources, + packedData.defaultUnits, + packedData.defaultVictoryConditions, + packedData.fogOfWar, + packedData.allowObservers, + packedData.enableObserverModeAtEndGame, + packedData.enableServerControlledAI, + packedData.networkFramePeriod, + packedData.networkPauseGameForLaggedClients, + packedData.pathFinderType, + packedData.flagTypes1, + packedData.aiAcceptSwitchTeamPercentChance, + packedData.cpuReplacementMultiplier, + packedData.masterserver_admin, + packedData.masterserver_admin_factionIndex, + packedData.scenario.getBuffer(), + packedData.networkPlayerUUID[0].getBuffer(), + packedData.networkPlayerUUID[1].getBuffer(), + packedData.networkPlayerUUID[2].getBuffer(), + packedData.networkPlayerUUID[3].getBuffer(), + packedData.networkPlayerUUID[4].getBuffer(), + packedData.networkPlayerUUID[5].getBuffer(), + packedData.networkPlayerUUID[6].getBuffer(), + packedData.networkPlayerUUID[7].getBuffer(), + packedData.networkAllowNativeLanguageTechtree, + packedData.gameUUID.getBuffer() + ); + delete[] buf; + } + return result; + } + void NetworkMessageLaunch::unpackMessage(unsigned char *buf) { + unpack(buf, getPackedMessageFormat(), + &messageType, + data.description.getBuffer(), + data.map.getBuffer(), + data.tileset.getBuffer(), + data.tech.getBuffer(), + data.factionTypeNames[0].getBuffer(), + data.factionTypeNames[1].getBuffer(), + data.factionTypeNames[2].getBuffer(), + data.factionTypeNames[3].getBuffer(), + data.factionTypeNames[4].getBuffer(), + data.factionTypeNames[5].getBuffer(), + data.factionTypeNames[6].getBuffer(), + data.factionTypeNames[7].getBuffer(), + data.networkPlayerNames[0].getBuffer(), + data.networkPlayerNames[1].getBuffer(), + data.networkPlayerNames[2].getBuffer(), + data.networkPlayerNames[3].getBuffer(), + data.networkPlayerNames[4].getBuffer(), + data.networkPlayerNames[5].getBuffer(), + data.networkPlayerNames[6].getBuffer(), + data.networkPlayerNames[7].getBuffer(), + data.networkPlayerPlatform[0].getBuffer(), + data.networkPlayerPlatform[1].getBuffer(), + data.networkPlayerPlatform[2].getBuffer(), + data.networkPlayerPlatform[3].getBuffer(), + data.networkPlayerPlatform[4].getBuffer(), + data.networkPlayerPlatform[5].getBuffer(), + data.networkPlayerPlatform[6].getBuffer(), + data.networkPlayerPlatform[7].getBuffer(), + &data.networkPlayerStatuses[0], + &data.networkPlayerStatuses[1], + &data.networkPlayerStatuses[2], + &data.networkPlayerStatuses[3], + &data.networkPlayerStatuses[4], + &data.networkPlayerStatuses[5], + &data.networkPlayerStatuses[6], + &data.networkPlayerStatuses[7], + data.networkPlayerLanguages[0].getBuffer(), + data.networkPlayerLanguages[1].getBuffer(), + data.networkPlayerLanguages[2].getBuffer(), + data.networkPlayerLanguages[3].getBuffer(), + data.networkPlayerLanguages[4].getBuffer(), + data.networkPlayerLanguages[5].getBuffer(), + data.networkPlayerLanguages[6].getBuffer(), + data.networkPlayerLanguages[7].getBuffer(), + &data.mapFilter, + &data.mapCRC, + &data.tilesetCRC, + &data.techCRC, + data.factionNameList[0].getBuffer(), + data.factionNameList[1].getBuffer(), + data.factionNameList[2].getBuffer(), + data.factionNameList[3].getBuffer(), + data.factionNameList[4].getBuffer(), + data.factionNameList[5].getBuffer(), + data.factionNameList[6].getBuffer(), + data.factionNameList[7].getBuffer(), + data.factionNameList[8].getBuffer(), + data.factionNameList[9].getBuffer(), + data.factionNameList[10].getBuffer(), + data.factionNameList[11].getBuffer(), + data.factionNameList[12].getBuffer(), + data.factionNameList[13].getBuffer(), + data.factionNameList[14].getBuffer(), + data.factionNameList[15].getBuffer(), + data.factionNameList[16].getBuffer(), + data.factionNameList[17].getBuffer(), + data.factionNameList[18].getBuffer(), + data.factionNameList[19].getBuffer(), + &data.factionCRCList[0], + &data.factionCRCList[1], + &data.factionCRCList[2], + &data.factionCRCList[3], + &data.factionCRCList[4], + &data.factionCRCList[5], + &data.factionCRCList[6], + &data.factionCRCList[7], + &data.factionCRCList[8], + &data.factionCRCList[9], + &data.factionCRCList[10], + &data.factionCRCList[11], + &data.factionCRCList[12], + &data.factionCRCList[13], + &data.factionCRCList[14], + &data.factionCRCList[15], + &data.factionCRCList[16], + &data.factionCRCList[17], + &data.factionCRCList[18], + &data.factionCRCList[19], + &data.factionControls[0], + &data.factionControls[1], + &data.factionControls[2], + &data.factionControls[3], + &data.factionControls[4], + &data.factionControls[5], + &data.factionControls[6], + &data.factionControls[7], + &data.resourceMultiplierIndex[0], + &data.resourceMultiplierIndex[1], + &data.resourceMultiplierIndex[2], + &data.resourceMultiplierIndex[3], + &data.resourceMultiplierIndex[4], + &data.resourceMultiplierIndex[5], + &data.resourceMultiplierIndex[6], + &data.resourceMultiplierIndex[7], + &data.thisFactionIndex, + &data.factionCount, + &data.teams[0], + &data.teams[1], + &data.teams[2], + &data.teams[3], + &data.teams[4], + &data.teams[5], + &data.teams[6], + &data.teams[7], + &data.startLocationIndex[0], + &data.startLocationIndex[1], + &data.startLocationIndex[2], + &data.startLocationIndex[3], + &data.startLocationIndex[4], + &data.startLocationIndex[5], + &data.startLocationIndex[6], + &data.startLocationIndex[7], + &data.defaultResources, + &data.defaultUnits, + &data.defaultVictoryConditions, + &data.fogOfWar, + &data.allowObservers, + &data.enableObserverModeAtEndGame, + &data.enableServerControlledAI, + &data.networkFramePeriod, + &data.networkPauseGameForLaggedClients, + &data.pathFinderType, + &data.flagTypes1, + &data.aiAcceptSwitchTeamPercentChance, + &data.cpuReplacementMultiplier, + &data.masterserver_admin, + &data.masterserver_admin_factionIndex, + data.scenario.getBuffer(), + data.networkPlayerUUID[0].getBuffer(), + data.networkPlayerUUID[1].getBuffer(), + data.networkPlayerUUID[2].getBuffer(), + data.networkPlayerUUID[3].getBuffer(), + data.networkPlayerUUID[4].getBuffer(), + data.networkPlayerUUID[5].getBuffer(), + data.networkPlayerUUID[6].getBuffer(), + data.networkPlayerUUID[7].getBuffer(), + &data.networkAllowNativeLanguageTechtree, + data.gameUUID.getBuffer() ); - return buf; -} + } -bool NetworkMessageLaunch::receive(Socket* socket, NetworkMessageType type) { - bool result = receive(socket); - messageType = type; - return result; -} + unsigned char * NetworkMessageLaunch::packMessage() { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + pack(buf, getPackedMessageFormat(), + messageType, + data.description.getBuffer(), + data.map.getBuffer(), + data.tileset.getBuffer(), + data.tech.getBuffer(), + data.factionTypeNames[0].getBuffer(), + data.factionTypeNames[1].getBuffer(), + data.factionTypeNames[2].getBuffer(), + data.factionTypeNames[3].getBuffer(), + data.factionTypeNames[4].getBuffer(), + data.factionTypeNames[5].getBuffer(), + data.factionTypeNames[6].getBuffer(), + data.factionTypeNames[7].getBuffer(), + data.networkPlayerNames[0].getBuffer(), + data.networkPlayerNames[1].getBuffer(), + data.networkPlayerNames[2].getBuffer(), + data.networkPlayerNames[3].getBuffer(), + data.networkPlayerNames[4].getBuffer(), + data.networkPlayerNames[5].getBuffer(), + data.networkPlayerNames[6].getBuffer(), + data.networkPlayerNames[7].getBuffer(), + data.networkPlayerPlatform[0].getBuffer(), + data.networkPlayerPlatform[1].getBuffer(), + data.networkPlayerPlatform[2].getBuffer(), + data.networkPlayerPlatform[3].getBuffer(), + data.networkPlayerPlatform[4].getBuffer(), + data.networkPlayerPlatform[5].getBuffer(), + data.networkPlayerPlatform[6].getBuffer(), + data.networkPlayerPlatform[7].getBuffer(), + data.networkPlayerStatuses[0], + data.networkPlayerStatuses[1], + data.networkPlayerStatuses[2], + data.networkPlayerStatuses[3], + data.networkPlayerStatuses[4], + data.networkPlayerStatuses[5], + data.networkPlayerStatuses[6], + data.networkPlayerStatuses[7], + data.networkPlayerLanguages[0].getBuffer(), + data.networkPlayerLanguages[1].getBuffer(), + data.networkPlayerLanguages[2].getBuffer(), + data.networkPlayerLanguages[3].getBuffer(), + data.networkPlayerLanguages[4].getBuffer(), + data.networkPlayerLanguages[5].getBuffer(), + data.networkPlayerLanguages[6].getBuffer(), + data.networkPlayerLanguages[7].getBuffer(), + data.mapFilter, + data.mapCRC, + data.tilesetCRC, + data.techCRC, + data.factionNameList[0].getBuffer(), + data.factionNameList[1].getBuffer(), + data.factionNameList[2].getBuffer(), + data.factionNameList[3].getBuffer(), + data.factionNameList[4].getBuffer(), + data.factionNameList[5].getBuffer(), + data.factionNameList[6].getBuffer(), + data.factionNameList[7].getBuffer(), + data.factionNameList[8].getBuffer(), + data.factionNameList[9].getBuffer(), + data.factionNameList[10].getBuffer(), + data.factionNameList[11].getBuffer(), + data.factionNameList[12].getBuffer(), + data.factionNameList[13].getBuffer(), + data.factionNameList[14].getBuffer(), + data.factionNameList[15].getBuffer(), + data.factionNameList[16].getBuffer(), + data.factionNameList[17].getBuffer(), + data.factionNameList[18].getBuffer(), + data.factionNameList[19].getBuffer(), + data.factionCRCList[0], + data.factionCRCList[1], + data.factionCRCList[2], + data.factionCRCList[3], + data.factionCRCList[4], + data.factionCRCList[5], + data.factionCRCList[6], + data.factionCRCList[7], + data.factionCRCList[8], + data.factionCRCList[9], + data.factionCRCList[10], + data.factionCRCList[11], + data.factionCRCList[12], + data.factionCRCList[13], + data.factionCRCList[14], + data.factionCRCList[15], + data.factionCRCList[16], + data.factionCRCList[17], + data.factionCRCList[18], + data.factionCRCList[19], + data.factionControls[0], + data.factionControls[1], + data.factionControls[2], + data.factionControls[3], + data.factionControls[4], + data.factionControls[5], + data.factionControls[6], + data.factionControls[7], + data.resourceMultiplierIndex[0], + data.resourceMultiplierIndex[1], + data.resourceMultiplierIndex[2], + data.resourceMultiplierIndex[3], + data.resourceMultiplierIndex[4], + data.resourceMultiplierIndex[5], + data.resourceMultiplierIndex[6], + data.resourceMultiplierIndex[7], + data.thisFactionIndex, + data.factionCount, + data.teams[0], + data.teams[1], + data.teams[2], + data.teams[3], + data.teams[4], + data.teams[5], + data.teams[6], + data.teams[7], + data.startLocationIndex[0], + data.startLocationIndex[1], + data.startLocationIndex[2], + data.startLocationIndex[3], + data.startLocationIndex[4], + data.startLocationIndex[5], + data.startLocationIndex[6], + data.startLocationIndex[7], + data.defaultResources, + data.defaultUnits, + data.defaultVictoryConditions, + data.fogOfWar, + data.allowObservers, + data.enableObserverModeAtEndGame, + data.enableServerControlledAI, + data.networkFramePeriod, + data.networkPauseGameForLaggedClients, + data.pathFinderType, + data.flagTypes1, + data.aiAcceptSwitchTeamPercentChance, + data.cpuReplacementMultiplier, + data.masterserver_admin, + data.masterserver_admin_factionIndex, + data.scenario.getBuffer(), + data.networkPlayerUUID[0].getBuffer(), + data.networkPlayerUUID[1].getBuffer(), + data.networkPlayerUUID[2].getBuffer(), + data.networkPlayerUUID[3].getBuffer(), + data.networkPlayerUUID[4].getBuffer(), + data.networkPlayerUUID[5].getBuffer(), + data.networkPlayerUUID[6].getBuffer(), + data.networkPlayerUUID[7].getBuffer(), + data.networkAllowNativeLanguageTechtree, + data.gameUUID.getBuffer() + ); + return buf; + } -bool NetworkMessageLaunch::receive(Socket* socket) { - //printf("Receive NetworkMessageLaunch\n"); - bool result = false; + bool NetworkMessageLaunch::receive(Socket* socket, NetworkMessageType type) { + bool result = receive(socket); + messageType = type; + return result; + } - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + bool NetworkMessageLaunch::receive(Socket* socket) { + //printf("Receive NetworkMessageLaunch\n"); + bool result = false; - if(useOldProtocol == true) { + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + if (useOldProtocol == true) { - //printf("UnCompressed launch packet before read compressed size\n"); - result = NetworkMessage::receive(socket, &compressedLength, sizeof(compressedLength), true); - //printf("UnCompressed launch packet after read compressed size: %d\n",compressedLength); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + //printf("UnCompressed launch packet before read compressed size\n"); + result = NetworkMessage::receive(socket, &compressedLength, sizeof(compressedLength), true); + //printf("UnCompressed launch packet after read compressed size: %d\n",compressedLength); - if(result == true && compressedLength > 0 && socket != NULL && socket->isSocketValid()) { - //printf("UnCompressed launch packet before: %u after: %d\n",compressedLength,(int)getDataSize()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - unsigned char *compressedMessage = new unsigned char[compressedLength+1]; - memset(compressedMessage,0,compressedLength+1); + if (result == true && compressedLength > 0 && socket != NULL && socket->isSocketValid()) { + //printf("UnCompressed launch packet before: %u after: %d\n",compressedLength,(int)getDataSize()); - result = NetworkMessage::receive(socket, compressedMessage, compressedLength, true); - //printf("UnCompressed launch packet READ returned: %d\n",result); + unsigned char *compressedMessage = new unsigned char[compressedLength + 1]; + memset(compressedMessage, 0, compressedLength + 1); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + result = NetworkMessage::receive(socket, compressedMessage, compressedLength, true); + //printf("UnCompressed launch packet READ returned: %d\n",result); - if(result == true && socket != NULL && socket->isSocketValid()) { - //printf("UnCompressed launch packet before decompress\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); -// printf("\n"); -// const unsigned char *buf = static_cast(compressedMessage); -// for(unsigned int index = 0; index < (unsigned int)compressedLength; ++index) { -// printf("%u[%X][%d] ",index,buf[index],buf[index]); -// if(index % 10 == 0) { -// printf("\n"); -// } -// } -// printf("\n"); + if (result == true && socket != NULL && socket->isSocketValid()) { + //printf("UnCompressed launch packet before decompress\n"); - unsigned long buffer_size = compressedLength; - std::pair decompressedBuffer = - Shared::CompressionUtil::extractMemoryToMemory(compressedMessage, buffer_size, maxNetworkMessageSize); + // printf("\n"); + // const unsigned char *buf = static_cast(compressedMessage); + // for(unsigned int index = 0; index < (unsigned int)compressedLength; ++index) { + // printf("%u[%X][%d] ",index,buf[index],buf[index]); + // if(index % 10 == 0) { + // printf("\n"); + // } + // } + // printf("\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + unsigned long buffer_size = compressedLength; + std::pair decompressedBuffer = + Shared::CompressionUtil::extractMemoryToMemory(compressedMessage, buffer_size, maxNetworkMessageSize); - unsigned char *decompressed_buffer = decompressedBuffer.first; - memcpy(&data,decompressed_buffer,decompressedBuffer.second); - delete [] decompressed_buffer; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + unsigned char *decompressed_buffer = decompressedBuffer.first; + memcpy(&data, decompressed_buffer, decompressedBuffer.second); + delete[] decompressed_buffer; - //printf("SUCCESS UnCompressed launch packet before: %u after: %lu\n",compressedLength,decompressedBuffer.second); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + //printf("SUCCESS UnCompressed launch packet before: %u after: %lu\n",compressedLength,decompressedBuffer.second); + } + delete[] compressedMessage; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + } else if (result == true) { + //printf("Normal launch packet detected (uncompressed)\n"); + result = NetworkMessage::receive(socket, &data, sizeof(data), true); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + } + } else { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + result = NetworkMessage::receive(socket, buf, getPackedSize(), true); + unpackMessage(buf); + //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); + delete[] buf; } - delete [] compressedMessage; + fromEndian(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + + data.description.nullTerminate(); + data.map.nullTerminate(); + data.tileset.nullTerminate(); + data.tech.nullTerminate(); + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + data.factionTypeNames[i].nullTerminate(); + data.networkPlayerNames[i].nullTerminate(); + data.networkPlayerPlatform[i].nullTerminate(); + data.networkPlayerLanguages[i].nullTerminate(); + + data.networkPlayerUUID[i].nullTerminate(); + } + for (unsigned int i = 0; i < (unsigned int) maxFactionCRCCount; ++i) { + data.factionNameList[i].nullTerminate(); + } + + data.scenario.nullTerminate(); + + data.gameUUID.nullTerminate(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + + //for(int i= 0; i < GameConstants::maxPlayers; ++i){ + // printf("Receive index: %d resource multiplier index: %d sizeof(data): %d\n",i,data.resourceMultiplierIndex[i],sizeof(data)); + //} + + return result; } - else if(result == true) { - //printf("Normal launch packet detected (uncompressed)\n"); - result = NetworkMessage::receive(socket, &data, sizeof(data), true); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + unsigned char * NetworkMessageLaunch::getData() { + unsigned char *buffer = new unsigned char[getDataSize()]; + memcpy(buffer, &data, getDataSize()); + return buffer; } - } - else { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - result = NetworkMessage::receive(socket, buf, getPackedSize(), true); - unpackMessage(buf); - //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); - delete [] buf; - } - fromEndian(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) chrono.start(); + std::pair NetworkMessageLaunch::getCompressedMessage() { + unsigned char *buffer = this->getData(); + std::pair result = + Shared::CompressionUtil::compressMemoryToMemory(buffer, getDataSize()); + delete[] buffer; + return result; + } - data.description.nullTerminate(); - data.map.nullTerminate(); - data.tileset.nullTerminate(); - data.tech.nullTerminate(); - for(int i= 0; i < GameConstants::maxPlayers; ++i){ - data.factionTypeNames[i].nullTerminate(); - data.networkPlayerNames[i].nullTerminate(); - data.networkPlayerPlatform[i].nullTerminate(); - data.networkPlayerLanguages[i].nullTerminate(); + void NetworkMessageLaunch::send(Socket* socket) { + //printf("Sending NetworkMessageLaunch\n"); - data.networkPlayerUUID[i].nullTerminate(); - } - for(unsigned int i = 0; i < (unsigned int)maxFactionCRCCount; ++i) { - data.factionNameList[i].nullTerminate(); - } + //for(int i= 0; i < GameConstants::maxPlayers; ++i){ + // printf("Send index: %d resource multiplier index: %d sizeof(data): %d\n",i,data.resourceMultiplierIndex[i],sizeof(data)); + //} - data.scenario.nullTerminate(); + if (messageType == nmtLaunch) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] nmtLaunch\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] messageType = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, messageType); + } + toEndian(); - data.gameUUID.nullTerminate(); + if (useOldProtocol == true) { + ////NetworkMessage::send(socket, &messageType, sizeof(messageType)); + //NetworkMessage::send(socket, &data, sizeof(data), messageType); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); + std::pair compressionResult = getCompressedMessage(); + compressedLength = compressionResult.second; + //printf("Compressed launch packet before: %d after: %lu\n",(int)getDataSize(),compressionResult.second); - //for(int i= 0; i < GameConstants::maxPlayers; ++i){ - // printf("Receive index: %d resource multiplier index: %d sizeof(data): %d\n",i,data.resourceMultiplierIndex[i],sizeof(data)); - //} + // printf("\n"); + // const unsigned char *buf = static_cast(compressionResult.first); + // for(unsigned int index = 0; index < (unsigned int)compressionResult.second; ++index) { + // printf("%u[%X][%d] ",index,buf[index],buf[index]); + // if(index % 10 == 0) { + // printf("\n"); + // } + // } + // printf("\n"); - return result; -} - -unsigned char * NetworkMessageLaunch::getData() { - unsigned char *buffer = new unsigned char[getDataSize()]; - memcpy(buffer,&data,getDataSize()); - return buffer; -} - -std::pair NetworkMessageLaunch::getCompressedMessage() { - unsigned char *buffer = this->getData(); - std::pair result = - Shared::CompressionUtil::compressMemoryToMemory(buffer,getDataSize()); - delete [] buffer; - return result; -} - -void NetworkMessageLaunch::send(Socket* socket) { - //printf("Sending NetworkMessageLaunch\n"); - - //for(int i= 0; i < GameConstants::maxPlayers; ++i){ - // printf("Send index: %d resource multiplier index: %d sizeof(data): %d\n",i,data.resourceMultiplierIndex[i],sizeof(data)); - //} - - if(messageType == nmtLaunch) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtLaunch\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] messageType = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,messageType); - } - toEndian(); - - if(useOldProtocol == true) { - ////NetworkMessage::send(socket, &messageType, sizeof(messageType)); - //NetworkMessage::send(socket, &data, sizeof(data), messageType); - - std::pair compressionResult = getCompressedMessage(); - compressedLength = compressionResult.second; - //printf("Compressed launch packet before: %d after: %lu\n",(int)getDataSize(),compressionResult.second); - -// printf("\n"); -// const unsigned char *buf = static_cast(compressionResult.first); -// for(unsigned int index = 0; index < (unsigned int)compressionResult.second; ++index) { -// printf("%u[%X][%d] ",index,buf[index],buf[index]); -// if(index % 10 == 0) { -// printf("\n"); -// } -// } -// printf("\n"); - -/* - NetworkMessage::send(socket, &messageType, sizeof(messageType)); - if(socket != NULL && socket->isSocketValid()) { - NetworkMessage::send(socket, &compressedLength, sizeof(compressedLength)); - if(socket != NULL && socket->isSocketValid()) { - NetworkMessage::send(socket, compressionResult.first, compressionResult.second); + /* + NetworkMessage::send(socket, &messageType, sizeof(messageType)); + if(socket != NULL && socket->isSocketValid()) { + NetworkMessage::send(socket, &compressedLength, sizeof(compressedLength)); + if(socket != NULL && socket->isSocketValid()) { + NetworkMessage::send(socket, compressionResult.first, compressionResult.second); + } + } + */ + NetworkMessage::send(socket, compressionResult.first, compressionResult.second, messageType, compressedLength); + delete[] compressionResult.first; + //printf("Compressed launch packet SENT\n"); + } else { + unsigned char *buf = packMessage(); + //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); + NetworkMessage::send(socket, buf, getPackedSize()); + delete[] buf; } } -*/ - NetworkMessage::send(socket, compressionResult.first, compressionResult.second, messageType, compressedLength); - delete [] compressionResult.first; - //printf("Compressed launch packet SENT\n"); - } - else { - unsigned char *buf = packMessage(); - //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); - NetworkMessage::send(socket, buf, getPackedSize()); - delete [] buf; - } -} -void NetworkMessageLaunch::toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); - for(int i= 0; i < GameConstants::maxPlayers; ++i){ - data.networkPlayerStatuses[i] = Shared::PlatformByteOrder::toCommonEndian(data.networkPlayerStatuses[i]); - data.factionCRCList[i] = Shared::PlatformByteOrder::toCommonEndian(data.factionCRCList[i]); - data.factionControls[i] = Shared::PlatformByteOrder::toCommonEndian(data.factionControls[i]); - data.resourceMultiplierIndex[i] = Shared::PlatformByteOrder::toCommonEndian(data.resourceMultiplierIndex[i]); - data.teams[i] = Shared::PlatformByteOrder::toCommonEndian(data.teams[i]); - data.startLocationIndex[i] = Shared::PlatformByteOrder::toCommonEndian(data.startLocationIndex[i]); + void NetworkMessageLaunch::toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + data.networkPlayerStatuses[i] = Shared::PlatformByteOrder::toCommonEndian(data.networkPlayerStatuses[i]); + data.factionCRCList[i] = Shared::PlatformByteOrder::toCommonEndian(data.factionCRCList[i]); + data.factionControls[i] = Shared::PlatformByteOrder::toCommonEndian(data.factionControls[i]); + data.resourceMultiplierIndex[i] = Shared::PlatformByteOrder::toCommonEndian(data.resourceMultiplierIndex[i]); + data.teams[i] = Shared::PlatformByteOrder::toCommonEndian(data.teams[i]); + data.startLocationIndex[i] = Shared::PlatformByteOrder::toCommonEndian(data.startLocationIndex[i]); + } + data.mapFilter = Shared::PlatformByteOrder::toCommonEndian(data.mapFilter); + data.mapCRC = Shared::PlatformByteOrder::toCommonEndian(data.mapCRC); + data.tilesetCRC = Shared::PlatformByteOrder::toCommonEndian(data.tilesetCRC); + data.techCRC = Shared::PlatformByteOrder::toCommonEndian(data.techCRC); + data.thisFactionIndex = Shared::PlatformByteOrder::toCommonEndian(data.thisFactionIndex); + data.factionCount = Shared::PlatformByteOrder::toCommonEndian(data.factionCount); + data.defaultResources = Shared::PlatformByteOrder::toCommonEndian(data.defaultResources); + data.defaultUnits = Shared::PlatformByteOrder::toCommonEndian(data.defaultUnits); + + data.defaultVictoryConditions = Shared::PlatformByteOrder::toCommonEndian(data.defaultVictoryConditions); + data.fogOfWar = Shared::PlatformByteOrder::toCommonEndian(data.fogOfWar); + data.allowObservers = Shared::PlatformByteOrder::toCommonEndian(data.allowObservers); + data.enableObserverModeAtEndGame = Shared::PlatformByteOrder::toCommonEndian(data.enableObserverModeAtEndGame); + data.enableServerControlledAI = Shared::PlatformByteOrder::toCommonEndian(data.enableServerControlledAI); + data.networkFramePeriod = Shared::PlatformByteOrder::toCommonEndian(data.networkFramePeriod); + data.networkPauseGameForLaggedClients = Shared::PlatformByteOrder::toCommonEndian(data.networkPauseGameForLaggedClients); + data.pathFinderType = Shared::PlatformByteOrder::toCommonEndian(data.pathFinderType); + data.flagTypes1 = Shared::PlatformByteOrder::toCommonEndian(data.flagTypes1); + + data.aiAcceptSwitchTeamPercentChance = Shared::PlatformByteOrder::toCommonEndian(data.aiAcceptSwitchTeamPercentChance); + data.cpuReplacementMultiplier = Shared::PlatformByteOrder::toCommonEndian(data.cpuReplacementMultiplier); + data.masterserver_admin = Shared::PlatformByteOrder::toCommonEndian(data.masterserver_admin); + data.masterserver_admin_factionIndex = Shared::PlatformByteOrder::toCommonEndian(data.masterserver_admin_factionIndex); + + data.networkAllowNativeLanguageTechtree = Shared::PlatformByteOrder::toCommonEndian(data.networkAllowNativeLanguageTechtree); + } } - data.mapFilter = Shared::PlatformByteOrder::toCommonEndian(data.mapFilter); - data.mapCRC = Shared::PlatformByteOrder::toCommonEndian(data.mapCRC); - data.tilesetCRC = Shared::PlatformByteOrder::toCommonEndian(data.tilesetCRC); - data.techCRC = Shared::PlatformByteOrder::toCommonEndian(data.techCRC); - data.thisFactionIndex = Shared::PlatformByteOrder::toCommonEndian(data.thisFactionIndex); - data.factionCount = Shared::PlatformByteOrder::toCommonEndian(data.factionCount); - data.defaultResources = Shared::PlatformByteOrder::toCommonEndian(data.defaultResources); - data.defaultUnits = Shared::PlatformByteOrder::toCommonEndian(data.defaultUnits); - data.defaultVictoryConditions = Shared::PlatformByteOrder::toCommonEndian(data.defaultVictoryConditions); - data.fogOfWar = Shared::PlatformByteOrder::toCommonEndian(data.fogOfWar); - data.allowObservers = Shared::PlatformByteOrder::toCommonEndian(data.allowObservers); - data.enableObserverModeAtEndGame = Shared::PlatformByteOrder::toCommonEndian(data.enableObserverModeAtEndGame); - data.enableServerControlledAI = Shared::PlatformByteOrder::toCommonEndian(data.enableServerControlledAI); - data.networkFramePeriod = Shared::PlatformByteOrder::toCommonEndian(data.networkFramePeriod); - data.networkPauseGameForLaggedClients = Shared::PlatformByteOrder::toCommonEndian(data.networkPauseGameForLaggedClients); - data.pathFinderType = Shared::PlatformByteOrder::toCommonEndian(data.pathFinderType); - data.flagTypes1 = Shared::PlatformByteOrder::toCommonEndian(data.flagTypes1); + void NetworkMessageLaunch::fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + data.networkPlayerStatuses[i] = Shared::PlatformByteOrder::fromCommonEndian(data.networkPlayerStatuses[i]); + data.factionCRCList[i] = Shared::PlatformByteOrder::fromCommonEndian(data.factionCRCList[i]); + data.factionControls[i] = Shared::PlatformByteOrder::fromCommonEndian(data.factionControls[i]); + data.resourceMultiplierIndex[i] = Shared::PlatformByteOrder::fromCommonEndian(data.resourceMultiplierIndex[i]); + data.teams[i] = Shared::PlatformByteOrder::fromCommonEndian(data.teams[i]); + data.startLocationIndex[i] = Shared::PlatformByteOrder::fromCommonEndian(data.startLocationIndex[i]); + } + data.mapFilter = Shared::PlatformByteOrder::fromCommonEndian(data.mapFilter); + data.mapCRC = Shared::PlatformByteOrder::fromCommonEndian(data.mapCRC); + data.tilesetCRC = Shared::PlatformByteOrder::fromCommonEndian(data.tilesetCRC); + data.techCRC = Shared::PlatformByteOrder::fromCommonEndian(data.techCRC); + data.thisFactionIndex = Shared::PlatformByteOrder::fromCommonEndian(data.thisFactionIndex); + data.factionCount = Shared::PlatformByteOrder::fromCommonEndian(data.factionCount); + data.defaultResources = Shared::PlatformByteOrder::fromCommonEndian(data.defaultResources); + data.defaultUnits = Shared::PlatformByteOrder::fromCommonEndian(data.defaultUnits); - data.aiAcceptSwitchTeamPercentChance = Shared::PlatformByteOrder::toCommonEndian(data.aiAcceptSwitchTeamPercentChance); - data.cpuReplacementMultiplier = Shared::PlatformByteOrder::toCommonEndian(data.cpuReplacementMultiplier); - data.masterserver_admin = Shared::PlatformByteOrder::toCommonEndian(data.masterserver_admin); - data.masterserver_admin_factionIndex = Shared::PlatformByteOrder::toCommonEndian(data.masterserver_admin_factionIndex); + data.defaultVictoryConditions = Shared::PlatformByteOrder::fromCommonEndian(data.defaultVictoryConditions); + data.fogOfWar = Shared::PlatformByteOrder::fromCommonEndian(data.fogOfWar); + data.allowObservers = Shared::PlatformByteOrder::fromCommonEndian(data.allowObservers); + data.enableObserverModeAtEndGame = Shared::PlatformByteOrder::fromCommonEndian(data.enableObserverModeAtEndGame); + data.enableServerControlledAI = Shared::PlatformByteOrder::fromCommonEndian(data.enableServerControlledAI); + data.networkFramePeriod = Shared::PlatformByteOrder::fromCommonEndian(data.networkFramePeriod); + data.networkPauseGameForLaggedClients = Shared::PlatformByteOrder::fromCommonEndian(data.networkPauseGameForLaggedClients); + data.pathFinderType = Shared::PlatformByteOrder::fromCommonEndian(data.pathFinderType); + data.flagTypes1 = Shared::PlatformByteOrder::fromCommonEndian(data.flagTypes1); - data.networkAllowNativeLanguageTechtree = Shared::PlatformByteOrder::toCommonEndian(data.networkAllowNativeLanguageTechtree); - } -} + data.aiAcceptSwitchTeamPercentChance = Shared::PlatformByteOrder::fromCommonEndian(data.aiAcceptSwitchTeamPercentChance); + data.cpuReplacementMultiplier = Shared::PlatformByteOrder::fromCommonEndian(data.cpuReplacementMultiplier); + data.masterserver_admin = Shared::PlatformByteOrder::fromCommonEndian(data.masterserver_admin); + data.masterserver_admin_factionIndex = Shared::PlatformByteOrder::fromCommonEndian(data.masterserver_admin_factionIndex); -void NetworkMessageLaunch::fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); - for(int i= 0; i < GameConstants::maxPlayers; ++i){ - data.networkPlayerStatuses[i] = Shared::PlatformByteOrder::fromCommonEndian(data.networkPlayerStatuses[i]); - data.factionCRCList[i] = Shared::PlatformByteOrder::fromCommonEndian(data.factionCRCList[i]); - data.factionControls[i] = Shared::PlatformByteOrder::fromCommonEndian(data.factionControls[i]); - data.resourceMultiplierIndex[i] = Shared::PlatformByteOrder::fromCommonEndian(data.resourceMultiplierIndex[i]); - data.teams[i] = Shared::PlatformByteOrder::fromCommonEndian(data.teams[i]); - data.startLocationIndex[i] = Shared::PlatformByteOrder::fromCommonEndian(data.startLocationIndex[i]); + data.networkAllowNativeLanguageTechtree = Shared::PlatformByteOrder::fromCommonEndian(data.networkAllowNativeLanguageTechtree); + } } - data.mapFilter = Shared::PlatformByteOrder::fromCommonEndian(data.mapFilter); - data.mapCRC = Shared::PlatformByteOrder::fromCommonEndian(data.mapCRC); - data.tilesetCRC = Shared::PlatformByteOrder::fromCommonEndian(data.tilesetCRC); - data.techCRC = Shared::PlatformByteOrder::fromCommonEndian(data.techCRC); - data.thisFactionIndex = Shared::PlatformByteOrder::fromCommonEndian(data.thisFactionIndex); - data.factionCount = Shared::PlatformByteOrder::fromCommonEndian(data.factionCount); - data.defaultResources = Shared::PlatformByteOrder::fromCommonEndian(data.defaultResources); - data.defaultUnits = Shared::PlatformByteOrder::fromCommonEndian(data.defaultUnits); - data.defaultVictoryConditions = Shared::PlatformByteOrder::fromCommonEndian(data.defaultVictoryConditions); - data.fogOfWar = Shared::PlatformByteOrder::fromCommonEndian(data.fogOfWar); - data.allowObservers = Shared::PlatformByteOrder::fromCommonEndian(data.allowObservers); - data.enableObserverModeAtEndGame = Shared::PlatformByteOrder::fromCommonEndian(data.enableObserverModeAtEndGame); - data.enableServerControlledAI = Shared::PlatformByteOrder::fromCommonEndian(data.enableServerControlledAI); - data.networkFramePeriod = Shared::PlatformByteOrder::fromCommonEndian(data.networkFramePeriod); - data.networkPauseGameForLaggedClients = Shared::PlatformByteOrder::fromCommonEndian(data.networkPauseGameForLaggedClients); - data.pathFinderType = Shared::PlatformByteOrder::fromCommonEndian(data.pathFinderType); - data.flagTypes1 = Shared::PlatformByteOrder::fromCommonEndian(data.flagTypes1); + // ===================================================== + // class NetworkMessageLaunch + // ===================================================== - data.aiAcceptSwitchTeamPercentChance = Shared::PlatformByteOrder::fromCommonEndian(data.aiAcceptSwitchTeamPercentChance); - data.cpuReplacementMultiplier = Shared::PlatformByteOrder::fromCommonEndian(data.cpuReplacementMultiplier); - data.masterserver_admin = Shared::PlatformByteOrder::fromCommonEndian(data.masterserver_admin); - data.masterserver_admin_factionIndex = Shared::PlatformByteOrder::fromCommonEndian(data.masterserver_admin_factionIndex); + NetworkMessageCommandList::NetworkMessageCommandList(int32 frameCount) { + data.messageType = nmtCommandList; + data.header.frameCount = frameCount; + data.header.commandCount = 0; + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + data.header.networkPlayerFactionCRC[index] = 0; + } + } - data.networkAllowNativeLanguageTechtree = Shared::PlatformByteOrder::fromCommonEndian(data.networkAllowNativeLanguageTechtree); - } -} + bool NetworkMessageCommandList::addCommand(const NetworkCommand* networkCommand) { + data.commands.push_back(*networkCommand); + data.header.commandCount++; + return true; + } -// ===================================================== -// class NetworkMessageLaunch -// ===================================================== + const char * NetworkMessageCommandList::getPackedMessageFormatHeader() const { + return "cHlLLLLLLLL"; + } -NetworkMessageCommandList::NetworkMessageCommandList(int32 frameCount) { - data.messageType = nmtCommandList; - data.header.frameCount= frameCount; - data.header.commandCount= 0; - for(int index = 0; index < GameConstants::maxPlayers; ++index) { - data.header.networkPlayerFactionCRC[index]=0; - } -} + unsigned int NetworkMessageCommandList::getPackedSizeHeader() { + static unsigned int result = 0; + if (result == 0) { + Data packedData; + init(packedData); + unsigned char *buf = new unsigned char[sizeof(packedData) * 3]; + result = pack(buf, getPackedMessageFormatHeader(), + packedData.messageType, + packedData.header.commandCount, + packedData.header.frameCount, + packedData.header.networkPlayerFactionCRC[0], + packedData.header.networkPlayerFactionCRC[1], + packedData.header.networkPlayerFactionCRC[2], + packedData.header.networkPlayerFactionCRC[3], + packedData.header.networkPlayerFactionCRC[4], + packedData.header.networkPlayerFactionCRC[5], + packedData.header.networkPlayerFactionCRC[6], + packedData.header.networkPlayerFactionCRC[7]); + delete[] buf; + } + return result; + } + void NetworkMessageCommandList::unpackMessageHeader(unsigned char *buf) { + unpack(buf, getPackedMessageFormatHeader(), + &data.messageType, + &data.header.commandCount, + &data.header.frameCount, + &data.header.networkPlayerFactionCRC[0], + &data.header.networkPlayerFactionCRC[1], + &data.header.networkPlayerFactionCRC[2], + &data.header.networkPlayerFactionCRC[3], + &data.header.networkPlayerFactionCRC[4], + &data.header.networkPlayerFactionCRC[5], + &data.header.networkPlayerFactionCRC[6], + &data.header.networkPlayerFactionCRC[7]); + } -bool NetworkMessageCommandList::addCommand(const NetworkCommand* networkCommand){ - data.commands.push_back(*networkCommand); - data.header.commandCount++; - return true; -} + unsigned char * NetworkMessageCommandList::packMessageHeader() { + unsigned char *buf = new unsigned char[getPackedSizeHeader() + 1]; + pack(buf, getPackedMessageFormatHeader(), + data.messageType, + data.header.commandCount, + data.header.frameCount, + data.header.networkPlayerFactionCRC[0], + data.header.networkPlayerFactionCRC[1], + data.header.networkPlayerFactionCRC[2], + data.header.networkPlayerFactionCRC[3], + data.header.networkPlayerFactionCRC[4], + data.header.networkPlayerFactionCRC[5], + data.header.networkPlayerFactionCRC[6], + data.header.networkPlayerFactionCRC[7]); + return buf; + } -const char * NetworkMessageCommandList::getPackedMessageFormatHeader() const { - return "cHlLLLLLLLL"; -} + const char * NetworkMessageCommandList::getPackedMessageFormatDetail() const { + return "hlhhhhlccHccll"; + } -unsigned int NetworkMessageCommandList::getPackedSizeHeader() { - static unsigned int result = 0; - if(result == 0) { - Data packedData; - init(packedData); - unsigned char *buf = new unsigned char[sizeof(packedData)*3]; - result = pack(buf, getPackedMessageFormatHeader(), - packedData.messageType, - packedData.header.commandCount, - packedData.header.frameCount, - packedData.header.networkPlayerFactionCRC[0], - packedData.header.networkPlayerFactionCRC[1], - packedData.header.networkPlayerFactionCRC[2], - packedData.header.networkPlayerFactionCRC[3], - packedData.header.networkPlayerFactionCRC[4], - packedData.header.networkPlayerFactionCRC[5], - packedData.header.networkPlayerFactionCRC[6], - packedData.header.networkPlayerFactionCRC[7]); - delete [] buf; - } - return result; -} -void NetworkMessageCommandList::unpackMessageHeader(unsigned char *buf) { - unpack(buf, getPackedMessageFormatHeader(), - &data.messageType, - &data.header.commandCount, - &data.header.frameCount, - &data.header.networkPlayerFactionCRC[0], - &data.header.networkPlayerFactionCRC[1], - &data.header.networkPlayerFactionCRC[2], - &data.header.networkPlayerFactionCRC[3], - &data.header.networkPlayerFactionCRC[4], - &data.header.networkPlayerFactionCRC[5], - &data.header.networkPlayerFactionCRC[6], - &data.header.networkPlayerFactionCRC[7]); -} - -unsigned char * NetworkMessageCommandList::packMessageHeader() { - unsigned char *buf = new unsigned char[getPackedSizeHeader()+1]; - pack(buf, getPackedMessageFormatHeader(), - data.messageType, - data.header.commandCount, - data.header.frameCount, - data.header.networkPlayerFactionCRC[0], - data.header.networkPlayerFactionCRC[1], - data.header.networkPlayerFactionCRC[2], - data.header.networkPlayerFactionCRC[3], - data.header.networkPlayerFactionCRC[4], - data.header.networkPlayerFactionCRC[5], - data.header.networkPlayerFactionCRC[6], - data.header.networkPlayerFactionCRC[7]); - return buf; -} - -const char * NetworkMessageCommandList::getPackedMessageFormatDetail() const { - return "hlhhhhlccHccll"; -} - -unsigned int NetworkMessageCommandList::getPackedSizeDetail(int count) { - unsigned int result = 0; - //if(result == 0) { - for(unsigned int i = 0; i < (unsigned int)count; ++i) { - NetworkCommand packedData; - unsigned char *buf = new unsigned char[sizeof(NetworkCommand)*3]; - result += pack(buf, getPackedMessageFormatDetail(), + unsigned int NetworkMessageCommandList::getPackedSizeDetail(int count) { + unsigned int result = 0; + //if(result == 0) { + for (unsigned int i = 0; i < (unsigned int) count; ++i) { + NetworkCommand packedData; + unsigned char *buf = new unsigned char[sizeof(NetworkCommand) * 3]; + result += pack(buf, getPackedMessageFormatDetail(), packedData.networkCommandType, packedData.unitId, packedData.unitTypeId, @@ -1755,1957 +1734,1920 @@ unsigned int NetworkMessageCommandList::getPackedSizeDetail(int count) { packedData.commandStateType, packedData.commandStateValue, packedData.unitCommandGroupId); - delete [] buf; + delete[] buf; + } + //} + return result; } - //} - return result; -} -void NetworkMessageCommandList::unpackMessageDetail(unsigned char *buf,int count) { - data.commands.clear(); - data.commands.resize(count); - //unsigned int bytes_processed_total = 0; - unsigned char *bufMove = buf; - for(unsigned int i = 0; i < (unsigned int)count; ++i) { - unsigned int bytes_processed = unpack(bufMove, getPackedMessageFormatDetail(), - &data.commands[i].networkCommandType, - &data.commands[i].unitId, - &data.commands[i].unitTypeId, - &data.commands[i].commandTypeId, - &data.commands[i].positionX, - &data.commands[i].positionY, - &data.commands[i].targetId, - &data.commands[i].wantQueue, - &data.commands[i].fromFactionIndex, - &data.commands[i].unitFactionUnitCount, - &data.commands[i].unitFactionIndex, - &data.commands[i].commandStateType, - &data.commands[i].commandStateValue, - &data.commands[i].unitCommandGroupId); - bufMove += bytes_processed; - //bytes_processed_total += bytes_processed; - } - //printf("\nUnPacked detail size = %u\n",bytes_processed_total); -} - -unsigned char * NetworkMessageCommandList::packMessageDetail(uint16 totalCommand) { - int packetSize = getPackedSizeDetail(totalCommand) +1; - unsigned char *buf = new unsigned char[packetSize]; - unsigned char *bufMove = buf; - //unsigned int bytes_processed_total = 0; - for(unsigned int i = 0; i < totalCommand; ++i) { - unsigned int bytes_processed = pack(bufMove, getPackedMessageFormatDetail(), - data.commands[i].networkCommandType, - data.commands[i].unitId, - data.commands[i].unitTypeId, - data.commands[i].commandTypeId, - data.commands[i].positionX, - data.commands[i].positionY, - data.commands[i].targetId, - data.commands[i].wantQueue, - data.commands[i].fromFactionIndex, - data.commands[i].unitFactionUnitCount, - data.commands[i].unitFactionIndex, - data.commands[i].commandStateType, - data.commands[i].commandStateValue, - data.commands[i].unitCommandGroupId); - bufMove += bytes_processed; - //bytes_processed_total += bytes_processed; - } - //printf("\nPacked detail size = %u, allocated = %d\n",bytes_processed_total,packetSize); - return buf; -} - -bool NetworkMessageCommandList::receive(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - unsigned char *buf = NULL; - bool result = false; - if(useOldProtocol == true) { - result = NetworkMessage::receive(socket, &data.header, commandListHeaderSize, true); - if(result == true) { - data.messageType = this->getNetworkMessageType(); + void NetworkMessageCommandList::unpackMessageDetail(unsigned char *buf, int count) { + data.commands.clear(); + data.commands.resize(count); + //unsigned int bytes_processed_total = 0; + unsigned char *bufMove = buf; + for (unsigned int i = 0; i < (unsigned int) count; ++i) { + unsigned int bytes_processed = unpack(bufMove, getPackedMessageFormatDetail(), + &data.commands[i].networkCommandType, + &data.commands[i].unitId, + &data.commands[i].unitTypeId, + &data.commands[i].commandTypeId, + &data.commands[i].positionX, + &data.commands[i].positionY, + &data.commands[i].targetId, + &data.commands[i].wantQueue, + &data.commands[i].fromFactionIndex, + &data.commands[i].unitFactionUnitCount, + &data.commands[i].unitFactionIndex, + &data.commands[i].commandStateType, + &data.commands[i].commandStateValue, + &data.commands[i].unitCommandGroupId); + bufMove += bytes_processed; + //bytes_processed_total += bytes_processed; + } + //printf("\nUnPacked detail size = %u\n",bytes_processed_total); } - //printf("!!! =====> IN Network hdr cmd get frame: %d data.header.commandCount: %u\n",data.header.frameCount,data.header.commandCount); - } - else { - buf = new unsigned char[getPackedSizeHeader()+1]; - result = NetworkMessage::receive(socket, buf, getPackedSizeHeader(), true); - unpackMessageHeader(buf); - //if(data.header.commandCount) printf("\n\nGot packet size = %u data.messageType = %d\n%s\ncommandcount [%u] framecount [%d]\n",getPackedSizeHeader(),data.header.messageType,buf,data.header.commandCount,data.header.frameCount); - delete [] buf; - } - fromEndianHeader(); - - if(result == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got header, messageType = %d, commandCount = %u, frameCount = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,data.messageType,data.header.commandCount,data.header.frameCount); - - //printf("!!! =====> IN Network cmd get frame: %d data.header.commandCount: %u\n",data.header.frameCount,data.header.commandCount); - - if(data.header.commandCount > 0) { - data.commands.resize(data.header.commandCount); - - if(useOldProtocol == true) { - int totalMsgSize = (sizeof(NetworkCommand) * data.header.commandCount); - result = NetworkMessage::receive(socket, &data.commands[0], totalMsgSize, true); - -// if(data.commands[0].getNetworkCommandType() == nctPauseResume) { -// printf("=====> IN Network cmd type: %d [%d] frame: %d\n",data.commands[0].getNetworkCommandType(),nctPauseResume,data.header.frameCount); -// } + unsigned char * NetworkMessageCommandList::packMessageDetail(uint16 totalCommand) { + int packetSize = getPackedSizeDetail(totalCommand) + 1; + unsigned char *buf = new unsigned char[packetSize]; + unsigned char *bufMove = buf; + //unsigned int bytes_processed_total = 0; + for (unsigned int i = 0; i < totalCommand; ++i) { + unsigned int bytes_processed = pack(bufMove, getPackedMessageFormatDetail(), + data.commands[i].networkCommandType, + data.commands[i].unitId, + data.commands[i].unitTypeId, + data.commands[i].commandTypeId, + data.commands[i].positionX, + data.commands[i].positionY, + data.commands[i].targetId, + data.commands[i].wantQueue, + data.commands[i].fromFactionIndex, + data.commands[i].unitFactionUnitCount, + data.commands[i].unitFactionIndex, + data.commands[i].commandStateType, + data.commands[i].commandStateValue, + data.commands[i].unitCommandGroupId); + bufMove += bytes_processed; + //bytes_processed_total += bytes_processed; } - else { - //int totalMsgSize = (sizeof(NetworkCommand) * data.header.commandCount); - //result = NetworkMessage::receive(socket, &data.commands[0], totalMsgSize, true); - buf = new unsigned char[getPackedSizeDetail(data.header.commandCount)+1]; - result = NetworkMessage::receive(socket, buf, getPackedSizeDetail(data.header.commandCount), true); - unpackMessageDetail(buf,data.header.commandCount); - //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); - delete [] buf; + //printf("\nPacked detail size = %u, allocated = %d\n",bytes_processed_total,packetSize); + return buf; + } + + bool NetworkMessageCommandList::receive(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + unsigned char *buf = NULL; + bool result = false; + if (useOldProtocol == true) { + result = NetworkMessage::receive(socket, &data.header, commandListHeaderSize, true); + if (result == true) { + data.messageType = this->getNetworkMessageType(); + } + + //printf("!!! =====> IN Network hdr cmd get frame: %d data.header.commandCount: %u\n",data.header.frameCount,data.header.commandCount); + } else { + buf = new unsigned char[getPackedSizeHeader() + 1]; + result = NetworkMessage::receive(socket, buf, getPackedSizeHeader(), true); + unpackMessageHeader(buf); + //if(data.header.commandCount) printf("\n\nGot packet size = %u data.messageType = %d\n%s\ncommandcount [%u] framecount [%d]\n",getPackedSizeHeader(),data.header.messageType,buf,data.header.commandCount,data.header.frameCount); + delete[] buf; } - fromEndianDetail(); + fromEndianHeader(); -// for(int idx = 0 ; idx < data.header.commandCount; ++idx) { -// const NetworkCommand &cmd = data.commands[idx]; -// printf("========> Got index = %d / %u, got networkCommand [%s]\n",idx, data.header.commandCount,cmd.toString().c_str()); -// } + if (result == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got header, messageType = %d, commandCount = %u, frameCount = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, data.messageType, data.header.commandCount, data.header.frameCount); - if(result == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled == true) { - for(int idx = 0 ; idx < data.header.commandCount; ++idx) { + //printf("!!! =====> IN Network cmd get frame: %d data.header.commandCount: %u\n",data.header.frameCount,data.header.commandCount); + + if (data.header.commandCount > 0) { + data.commands.resize(data.header.commandCount); + + if (useOldProtocol == true) { + int totalMsgSize = (sizeof(NetworkCommand) * data.header.commandCount); + result = NetworkMessage::receive(socket, &data.commands[0], totalMsgSize, true); + + // if(data.commands[0].getNetworkCommandType() == nctPauseResume) { + // printf("=====> IN Network cmd type: %d [%d] frame: %d\n",data.commands[0].getNetworkCommandType(),nctPauseResume,data.header.frameCount); + // } + } else { + //int totalMsgSize = (sizeof(NetworkCommand) * data.header.commandCount); + //result = NetworkMessage::receive(socket, &data.commands[0], totalMsgSize, true); + buf = new unsigned char[getPackedSizeDetail(data.header.commandCount) + 1]; + result = NetworkMessage::receive(socket, buf, getPackedSizeDetail(data.header.commandCount), true); + unpackMessageDetail(buf, data.header.commandCount); + //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); + delete[] buf; + } + fromEndianDetail(); + + // for(int idx = 0 ; idx < data.header.commandCount; ++idx) { + // const NetworkCommand &cmd = data.commands[idx]; + // printf("========> Got index = %d / %u, got networkCommand [%s]\n",idx, data.header.commandCount,cmd.toString().c_str()); + // } + + if (result == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled == true) { + for (int idx = 0; idx < data.header.commandCount; ++idx) { + const NetworkCommand &cmd = data.commands[idx]; + + SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] index = %d, received networkCommand [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, idx, cmd.toString().c_str()); + } + } + } else { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR Failed to get command data, totalMsgSize = %d.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,totalMsgSize); + } + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] ERROR header not received as expected\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] ERROR header not received as expected\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + return result; + + } + + unsigned char * NetworkMessageCommandList::getData() { + int headerSize = sizeof(data.header); + uint16 totalCommand = data.header.commandCount; + int detailSize = (sizeof(NetworkCommand) * totalCommand); + int fullBufferSize = headerSize + detailSize; + + unsigned char *buffer = new unsigned char[fullBufferSize]; + memcpy(buffer, &data.header, headerSize); + memcpy(&buffer[headerSize], &data.commands[0], detailSize); + return buffer; + } + + void NetworkMessageCommandList::send(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] nmtCommandList, frameCount = %d, data.header.commandCount = %d, data.header.messageType = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, data.header.frameCount, data.header.commandCount, data.messageType); + + assert(data.messageType == nmtCommandList); + uint16 totalCommand = data.header.commandCount; + toEndianHeader(); + toEndianDetail(totalCommand); + + unsigned char *buf = NULL; + //bool result = false; + if (useOldProtocol == true) { + //printf("<===== OUT Network hdr cmd type: frame: %d totalCommand: %u [%u]\n",data.header.frameCount,totalCommand,data.header.commandCount); + //NetworkMessage::send(socket, &data.messageType, sizeof(data.messageType)); + + //NetworkMessage::send(socket, &data.header, commandListHeaderSize, data.messageType); + unsigned char *send_buffer = getData(); + int headerSize = sizeof(data.header); + uint16 totalCommand = data.header.commandCount; + int detailSize = (sizeof(NetworkCommand) * totalCommand); + int fullBufferSize = headerSize + detailSize; + NetworkMessage::send(socket, send_buffer, fullBufferSize, data.messageType); + delete[] send_buffer; + } else { + //NetworkMessage::send(socket, &data.header, commandListHeaderSize); + buf = packMessageHeader(); + //if(totalCommand) printf("\n\nSend packet size = %u data.messageType = %d\n%s\ncommandcount [%u] framecount [%d]\n",getPackedSizeHeader(),data.header.messageType,buf,totalCommand,data.header.frameCount); + NetworkMessage::send(socket, buf, getPackedSizeHeader()); + delete[] buf; + } + + if (totalCommand > 0) { + //printf("\n#2 Send packet commandcount [%u] framecount [%d]\n",totalCommand,data.header.frameCount); + //toEndianDetail(totalCommand); + //printf("\n#3 Send packet commandcount [%u] framecount [%d]\n",totalCommand,data.header.frameCount); + + //bool result = false; + if (useOldProtocol == true) { + // if(data.commands[0].getNetworkCommandType() == nctPauseResume) { + // printf("<===== OUT Network cmd type: %d [%d] frame: %d totalCommand: %u [%u]\n",data.commands[0].getNetworkCommandType(),nctPauseResume,data.header.frameCount,totalCommand,data.header.commandCount); + // } + //NetworkMessage::send(socket, &data.commands[0], (sizeof(NetworkCommand) * totalCommand)); + } else { + buf = packMessageDetail(totalCommand); + //printf("\n#4 Send packet commandcount [%u] framecount [%d]\n",totalCommand,data.header.frameCount); + //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); + NetworkMessage::send(socket, buf, getPackedSizeDetail(totalCommand)); + //printf("\n#5 Send packet commandcount [%u] framecount [%d]\n",totalCommand,data.header.frameCount); + delete[] buf; + //printf("\n#6 Send packet commandcount [%u] framecount [%d]\n",totalCommand,data.header.frameCount); + + // for(int idx = 0 ; idx < totalCommand; ++idx) { + // const NetworkCommand &cmd = data.commands[idx]; + // printf("========> Send index = %d / %u, sent networkCommand [%s]\n",idx, totalCommand,cmd.toString().c_str()); + // } + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled == true) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] messageType = %d, frameCount = %d, data.commandCount = %d\n", + extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, data.messageType, data.header.frameCount, data.header.commandCount); + + if (totalCommand > 0) { + for (int idx = 0; idx < totalCommand; ++idx) { const NetworkCommand &cmd = data.commands[idx]; - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] index = %d, received networkCommand [%s]\n", - extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,idx, cmd.toString().c_str()); + SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] index = %d, sent networkCommand [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, idx, cmd.toString().c_str()); + } + + SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] END of loop, nmtCommandList, frameCount = %d, data.header.commandCount = %d, data.header.messageType = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, data.header.frameCount, totalCommand, data.messageType); + } + } + } + + void NetworkMessageCommandList::toEndianHeader() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + data.messageType = Shared::PlatformByteOrder::toCommonEndian(data.messageType); + data.header.commandCount = Shared::PlatformByteOrder::toCommonEndian(data.header.commandCount); + data.header.frameCount = Shared::PlatformByteOrder::toCommonEndian(data.header.frameCount); + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + data.header.networkPlayerFactionCRC[index] = Shared::PlatformByteOrder::toCommonEndian(data.header.networkPlayerFactionCRC[index]); + } + } + } + void NetworkMessageCommandList::fromEndianHeader() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + data.messageType = Shared::PlatformByteOrder::fromCommonEndian(data.messageType); + data.header.commandCount = Shared::PlatformByteOrder::fromCommonEndian(data.header.commandCount); + data.header.frameCount = Shared::PlatformByteOrder::fromCommonEndian(data.header.frameCount); + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + data.header.networkPlayerFactionCRC[index] = Shared::PlatformByteOrder::fromCommonEndian(data.header.networkPlayerFactionCRC[index]); + } + } + } + + void NetworkMessageCommandList::toEndianDetail(uint16 totalCommand) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + if (totalCommand > 0) { + for (int idx = 0; idx < totalCommand; ++idx) { + NetworkCommand &cmd = data.commands[idx]; + cmd.toEndian(); } } } - else { - //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR Failed to get command data, totalMsgSize = %d.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,totalMsgSize); + } + + void NetworkMessageCommandList::fromEndianDetail() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + if (data.header.commandCount > 0) { + for (int idx = 0; idx < data.header.commandCount; ++idx) { + NetworkCommand &cmd = data.commands[idx]; + cmd.fromEndian(); + } + } } } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR header not received as expected\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] ERROR header not received as expected\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - return result; -} + // ===================================================== + // class NetworkMessageText + // ===================================================== -unsigned char * NetworkMessageCommandList::getData() { - int headerSize = sizeof(data.header); - uint16 totalCommand = data.header.commandCount; - int detailSize = (sizeof(NetworkCommand) * totalCommand); - int fullBufferSize = headerSize + detailSize; - - unsigned char *buffer = new unsigned char[fullBufferSize]; - memcpy(buffer,&data.header,headerSize); - memcpy(&buffer[headerSize],&data.commands[0],detailSize); - return buffer; -} - -void NetworkMessageCommandList::send(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtCommandList, frameCount = %d, data.header.commandCount = %d, data.header.messageType = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,data.header.frameCount,data.header.commandCount,data.messageType); - - assert(data.messageType == nmtCommandList); - uint16 totalCommand = data.header.commandCount; - toEndianHeader(); - toEndianDetail(totalCommand); - - unsigned char *buf = NULL; - //bool result = false; - if(useOldProtocol == true) { - //printf("<===== OUT Network hdr cmd type: frame: %d totalCommand: %u [%u]\n",data.header.frameCount,totalCommand,data.header.commandCount); - //NetworkMessage::send(socket, &data.messageType, sizeof(data.messageType)); - - //NetworkMessage::send(socket, &data.header, commandListHeaderSize, data.messageType); - unsigned char *send_buffer = getData(); - int headerSize = sizeof(data.header); - uint16 totalCommand = data.header.commandCount; - int detailSize = (sizeof(NetworkCommand) * totalCommand); - int fullBufferSize = headerSize + detailSize; - NetworkMessage::send(socket, send_buffer, fullBufferSize, data.messageType); - delete [] send_buffer; - } - else { - //NetworkMessage::send(socket, &data.header, commandListHeaderSize); - buf = packMessageHeader(); - //if(totalCommand) printf("\n\nSend packet size = %u data.messageType = %d\n%s\ncommandcount [%u] framecount [%d]\n",getPackedSizeHeader(),data.header.messageType,buf,totalCommand,data.header.frameCount); - NetworkMessage::send(socket, buf, getPackedSizeHeader()); - delete [] buf; - } - - if(totalCommand > 0) { - //printf("\n#2 Send packet commandcount [%u] framecount [%d]\n",totalCommand,data.header.frameCount); - //toEndianDetail(totalCommand); - //printf("\n#3 Send packet commandcount [%u] framecount [%d]\n",totalCommand,data.header.frameCount); - - //bool result = false; - if(useOldProtocol == true) { -// if(data.commands[0].getNetworkCommandType() == nctPauseResume) { -// printf("<===== OUT Network cmd type: %d [%d] frame: %d totalCommand: %u [%u]\n",data.commands[0].getNetworkCommandType(),nctPauseResume,data.header.frameCount,totalCommand,data.header.commandCount); -// } - //NetworkMessage::send(socket, &data.commands[0], (sizeof(NetworkCommand) * totalCommand)); + NetworkMessageText::NetworkMessageText() { + messageType = nmtText; } - else { - buf = packMessageDetail(totalCommand); - //printf("\n#4 Send packet commandcount [%u] framecount [%d]\n",totalCommand,data.header.frameCount); - //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); - NetworkMessage::send(socket, buf, getPackedSizeDetail(totalCommand)); - //printf("\n#5 Send packet commandcount [%u] framecount [%d]\n",totalCommand,data.header.frameCount); - delete [] buf; - //printf("\n#6 Send packet commandcount [%u] framecount [%d]\n",totalCommand,data.header.frameCount); - - // for(int idx = 0 ; idx < totalCommand; ++idx) { - // const NetworkCommand &cmd = data.commands[idx]; - // printf("========> Send index = %d / %u, sent networkCommand [%s]\n",idx, totalCommand,cmd.toString().c_str()); - // } - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled == true) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] messageType = %d, frameCount = %d, data.commandCount = %d\n", - extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,data.messageType,data.header.frameCount,data.header.commandCount); - - if (totalCommand > 0) { - for(int idx = 0 ; idx < totalCommand; ++idx) { - const NetworkCommand &cmd = data.commands[idx]; - - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] index = %d, sent networkCommand [%s]\n", - extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,idx, cmd.toString().c_str()); - } - - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] END of loop, nmtCommandList, frameCount = %d, data.header.commandCount = %d, data.header.messageType = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,data.header.frameCount,totalCommand,data.messageType); - } - } -} - -void NetworkMessageCommandList::toEndianHeader() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - data.messageType = Shared::PlatformByteOrder::toCommonEndian(data.messageType); - data.header.commandCount = Shared::PlatformByteOrder::toCommonEndian(data.header.commandCount); - data.header.frameCount = Shared::PlatformByteOrder::toCommonEndian(data.header.frameCount); - for(int index = 0; index < GameConstants::maxPlayers; ++index) { - data.header.networkPlayerFactionCRC[index] = Shared::PlatformByteOrder::toCommonEndian(data.header.networkPlayerFactionCRC[index]); - } - } -} -void NetworkMessageCommandList::fromEndianHeader() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - data.messageType = Shared::PlatformByteOrder::fromCommonEndian(data.messageType); - data.header.commandCount = Shared::PlatformByteOrder::fromCommonEndian(data.header.commandCount); - data.header.frameCount = Shared::PlatformByteOrder::fromCommonEndian(data.header.frameCount); - for(int index = 0; index < GameConstants::maxPlayers; ++index) { - data.header.networkPlayerFactionCRC[index] = Shared::PlatformByteOrder::fromCommonEndian(data.header.networkPlayerFactionCRC[index]); - } - } -} - -void NetworkMessageCommandList::toEndianDetail(uint16 totalCommand) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - if(totalCommand > 0) { - for(int idx = 0 ; idx < totalCommand; ++idx) { - NetworkCommand &cmd = data.commands[idx]; - cmd.toEndian(); + NetworkMessageText::NetworkMessageText(const string &text, int teamIndex, int playerIndex, + const string targetLanguage) { + if ((int) text.length() >= maxTextStringSize) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] WARNING / ERROR - text [%s] length = %d, max = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, text.c_str(), text.length(), maxTextStringSize); } - } - } -} -void NetworkMessageCommandList::fromEndianDetail() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - if(data.header.commandCount > 0) { - for(int idx = 0 ; idx < data.header.commandCount; ++idx) { - NetworkCommand &cmd = data.commands[idx]; - cmd.fromEndian(); + messageType = nmtText; + data.text = text.substr(0, maxTextStringSize); + data.teamIndex = teamIndex; + data.playerIndex = playerIndex; + data.targetLanguage = targetLanguage; + } + + NetworkMessageText * NetworkMessageText::getCopy() const { + NetworkMessageText *copy = new NetworkMessageText(); + copy->data = this->data; + return copy; + } + + const char * NetworkMessageText::getPackedMessageFormat() const { + return "c500scc60s"; + } + + unsigned int NetworkMessageText::getPackedSize() { + static unsigned int result = 0; + if (result == 0) { + Data packedData; + messageType = nmtText; + packedData.playerIndex = 0; + packedData.teamIndex = 0; + unsigned char *buf = new unsigned char[sizeof(packedData) * 3]; + result = pack(buf, getPackedMessageFormat(), + messageType, + packedData.text.getBuffer(), + packedData.teamIndex, + packedData.playerIndex, + packedData.targetLanguage.getBuffer()); + delete[] buf; } + return result; + } + void NetworkMessageText::unpackMessage(unsigned char *buf) { + unpack(buf, getPackedMessageFormat(), + &messageType, + data.text.getBuffer(), + &data.teamIndex, + &data.playerIndex, + data.targetLanguage.getBuffer()); } - } -} -// ===================================================== -// class NetworkMessageText -// ===================================================== - -NetworkMessageText::NetworkMessageText() { - messageType = nmtText; -} -NetworkMessageText::NetworkMessageText(const string &text, int teamIndex, int playerIndex, - const string targetLanguage) { - if((int)text.length() >= maxTextStringSize) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING / ERROR - text [%s] length = %d, max = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,text.c_str(),text.length(),maxTextStringSize); - } - - messageType = nmtText; - data.text = text.substr(0,maxTextStringSize); - data.teamIndex = teamIndex; - data.playerIndex = playerIndex; - data.targetLanguage = targetLanguage; -} - -NetworkMessageText * NetworkMessageText::getCopy() const { - NetworkMessageText *copy = new NetworkMessageText(); - copy->data = this->data; - return copy; -} - -const char * NetworkMessageText::getPackedMessageFormat() const { - return "c500scc60s"; -} - -unsigned int NetworkMessageText::getPackedSize() { - static unsigned int result = 0; - if(result == 0) { - Data packedData; - messageType = nmtText; - packedData.playerIndex = 0; - packedData.teamIndex = 0; - unsigned char *buf = new unsigned char[sizeof(packedData)*3]; - result = pack(buf, getPackedMessageFormat(), + unsigned char * NetworkMessageText::packMessage() { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + pack(buf, getPackedMessageFormat(), messageType, - packedData.text.getBuffer(), - packedData.teamIndex, - packedData.playerIndex, - packedData.targetLanguage.getBuffer()); - delete [] buf; - } - return result; -} -void NetworkMessageText::unpackMessage(unsigned char *buf) { - unpack(buf, getPackedMessageFormat(), - &messageType, - data.text.getBuffer(), - &data.teamIndex, - &data.playerIndex, - data.targetLanguage.getBuffer()); -} - -unsigned char * NetworkMessageText::packMessage() { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - pack(buf, getPackedMessageFormat(), - messageType, - data.text.getBuffer(), - data.teamIndex, - data.playerIndex, - data.targetLanguage.getBuffer()); - return buf; -} - -bool NetworkMessageText::receive(Socket* socket) { - bool result = false; - if(useOldProtocol == true) { - result = NetworkMessage::receive(socket, &data, sizeof(data), true); - if(result == true) { - messageType = this->getNetworkMessageType(); + data.text.getBuffer(), + data.teamIndex, + data.playerIndex, + data.targetLanguage.getBuffer()); + return buf; } - } - else { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - result = NetworkMessage::receive(socket, buf, getPackedSize(), true); - unpackMessage(buf); - //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); - delete [] buf; - } - fromEndian(); - data.text.nullTerminate(); - data.targetLanguage.nullTerminate(); + bool NetworkMessageText::receive(Socket* socket) { + bool result = false; + if (useOldProtocol == true) { + result = NetworkMessage::receive(socket, &data, sizeof(data), true); + if (result == true) { + messageType = this->getNetworkMessageType(); + } + } else { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + result = NetworkMessage::receive(socket, buf, getPackedSize(), true); + unpackMessage(buf); + //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); + delete[] buf; + } + fromEndian(); - return result; -} + data.text.nullTerminate(); + data.targetLanguage.nullTerminate(); -void NetworkMessageText::send(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtText\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + return result; + } - assert(messageType == nmtText); - toEndian(); + void NetworkMessageText::send(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] nmtText\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - if(useOldProtocol == true) { - //NetworkMessage::send(socket, &messageType, sizeof(messageType)); - NetworkMessage::send(socket, &data, sizeof(data), messageType); - } - else { - unsigned char *buf = packMessage(); - //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); - NetworkMessage::send(socket, buf, getPackedSize()); - delete [] buf; - } -} + assert(messageType == nmtText); + toEndian(); -void NetworkMessageText::toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); - data.teamIndex = Shared::PlatformByteOrder::toCommonEndian(data.teamIndex); - data.playerIndex = Shared::PlatformByteOrder::toCommonEndian(data.playerIndex); - } -} -void NetworkMessageText::fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); - data.teamIndex = Shared::PlatformByteOrder::fromCommonEndian(data.teamIndex); - data.playerIndex = Shared::PlatformByteOrder::fromCommonEndian(data.playerIndex); - } -} + if (useOldProtocol == true) { + //NetworkMessage::send(socket, &messageType, sizeof(messageType)); + NetworkMessage::send(socket, &data, sizeof(data), messageType); + } else { + unsigned char *buf = packMessage(); + //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); + NetworkMessage::send(socket, buf, getPackedSize()); + delete[] buf; + } + } -// ===================================================== -// class NetworkMessageQuit -// ===================================================== + void NetworkMessageText::toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); + data.teamIndex = Shared::PlatformByteOrder::toCommonEndian(data.teamIndex); + data.playerIndex = Shared::PlatformByteOrder::toCommonEndian(data.playerIndex); + } + } + void NetworkMessageText::fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); + data.teamIndex = Shared::PlatformByteOrder::fromCommonEndian(data.teamIndex); + data.playerIndex = Shared::PlatformByteOrder::fromCommonEndian(data.playerIndex); + } + } -NetworkMessageQuit::NetworkMessageQuit(){ - messageType = nmtQuit; -} + // ===================================================== + // class NetworkMessageQuit + // ===================================================== -const char * NetworkMessageQuit::getPackedMessageFormat() const { - return "c"; -} + NetworkMessageQuit::NetworkMessageQuit() { + messageType = nmtQuit; + } -unsigned int NetworkMessageQuit::getPackedSize() { - static unsigned int result = 0; - if(result == 0) { - //Data packedData; - messageType = 0; - unsigned char *buf = new unsigned char[sizeof(messageType)*3]; - result = pack(buf, getPackedMessageFormat(), + const char * NetworkMessageQuit::getPackedMessageFormat() const { + return "c"; + } + + unsigned int NetworkMessageQuit::getPackedSize() { + static unsigned int result = 0; + if (result == 0) { + //Data packedData; + messageType = 0; + unsigned char *buf = new unsigned char[sizeof(messageType) * 3]; + result = pack(buf, getPackedMessageFormat(), + messageType); + delete[] buf; + } + return result; + } + void NetworkMessageQuit::unpackMessage(unsigned char *buf) { + unpack(buf, getPackedMessageFormat(), + &messageType); + } + + unsigned char * NetworkMessageQuit::packMessage() { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + pack(buf, getPackedMessageFormat(), messageType); - delete [] buf; - } - return result; -} -void NetworkMessageQuit::unpackMessage(unsigned char *buf) { - unpack(buf, getPackedMessageFormat(), - &messageType); -} + return buf; + } -unsigned char * NetworkMessageQuit::packMessage() { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - pack(buf, getPackedMessageFormat(), - messageType); - return buf; -} - -bool NetworkMessageQuit::receive(Socket* socket) { - bool result = false; - if(useOldProtocol == true) { - result = NetworkMessage::receive(socket, &messageType, sizeof(messageType),true); - } - else { - //fromEndian(); - unsigned char *buf = new unsigned char[getPackedSize()+1]; - result = NetworkMessage::receive(socket, buf, getPackedSize(), true); - unpackMessage(buf); - //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); - delete [] buf; - } - fromEndian(); - - return result; -} - -void NetworkMessageQuit::send(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtQuit\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - assert(messageType == nmtQuit); - toEndian(); - - if(useOldProtocol == true) { - NetworkMessage::send(socket, &messageType, sizeof(messageType)); - } - else { - unsigned char *buf = packMessage(); - //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); - NetworkMessage::send(socket, buf, getPackedSize()); - delete [] buf; - } -} - -void NetworkMessageQuit::toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); - } -} -void NetworkMessageQuit::fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); - } -} - -// ===================================================== -// class NetworkMessageSynchNetworkGameData -// ===================================================== - -NetworkMessageSynchNetworkGameData::NetworkMessageSynchNetworkGameData(const GameSettings *gameSettings) -{ - data.messageType= nmtSynchNetworkGameData; - - if(gameSettings == NULL) { - throw std::runtime_error("gameSettings == NULL"); - } - data.header.map = gameSettings->getMap(); - data.header.tileset = gameSettings->getTileset(); - data.header.tech = gameSettings->getTech(); - - Config &config = Config::getInstance(); - string scenarioDir = ""; - if(gameSettings->getScenarioDir() != "") { - scenarioDir = gameSettings->getScenarioDir(); - if(EndsWith(scenarioDir, ".xml") == true) { - scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4); - scenarioDir = scenarioDir.erase(scenarioDir.size() - gameSettings->getScenario().size(), gameSettings->getScenario().size() + 1); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,gameSettings->getScenarioDir().c_str(),gameSettings->getScenario().c_str(),scenarioDir.c_str()); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - data.header.tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets,scenarioDir), string("/") + gameSettings->getTileset() + string("/*"), ".xml", NULL); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] data.tilesetCRC = %d, [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__, data.header.tilesetCRC,gameSettings->getTileset().c_str()); - - //tech, load before map because of resources - data.header.techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs,scenarioDir), string("/") + gameSettings->getTech() + string("/*"), ".xml", NULL); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] data.techCRC = %d, [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__, data.header.techCRC,gameSettings->getTech().c_str()); - - vector > vctFileList; - vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs,scenarioDir),string("/") + gameSettings->getTech() + string("/*"), ".xml",&vctFileList); - data.header.techCRCFileCount = min((int)vctFileList.size(),(int)maxFileCRCCount); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] vctFileList.size() = %d, maxFileCRCCount = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__, vctFileList.size(),maxFileCRCCount); - - for(int idx =0; idx < (int)data.header.techCRCFileCount; ++idx) { - const std::pair &fileInfo = vctFileList[idx]; - data.detail.techCRCFileList[idx] = fileInfo.first; - data.detail.techCRCFileCRCList[idx] = fileInfo.second; - } - - //map - Checksum checksum; - string file = Config::getMapPath(gameSettings->getMap(),scenarioDir,false); - checksum.addFile(file); - data.header.mapCRC = checksum.getSum(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] data.mapCRC = %d, [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__, data.header.mapCRC,gameSettings->getMap().c_str()); -} - -string NetworkMessageSynchNetworkGameData::getTechCRCFileMismatchReport(vector > &vctFileList) { - string result = "Techtree: [" + data.header.tech.getString() + "] Filecount local: " + intToStr(vctFileList.size()) + " remote: " + intToStr(data.header.techCRCFileCount) + "\n"; - if(vctFileList.size() <= 0) { - result = result + "Local player has no files.\n"; - } - else if(data.header.techCRCFileCount <= 0) { - result = result + "Remote player has no files.\n"; - } - else { - for(int idx = 0; idx < (int)vctFileList.size(); ++idx) { - std::pair &fileInfo = vctFileList[idx]; - bool fileFound = false; - uint32 remoteCRC = 0; - for(int j = 0; j < (int)data.header.techCRCFileCount; ++j) { - string networkFile = data.detail.techCRCFileList[j].getString(); - uint32 &networkFileCRC = data.detail.techCRCFileCRCList[j]; - if(fileInfo.first == networkFile) { - fileFound = true; - remoteCRC = networkFileCRC; - break; - } + bool NetworkMessageQuit::receive(Socket* socket) { + bool result = false; + if (useOldProtocol == true) { + result = NetworkMessage::receive(socket, &messageType, sizeof(messageType), true); + } else { + //fromEndian(); + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + result = NetworkMessage::receive(socket, buf, getPackedSize(), true); + unpackMessage(buf); + //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); + delete[] buf; } + fromEndian(); - if(fileFound == false) { - result = result + "local file [" + fileInfo.first + "] missing remotely.\n"; - } - else if(fileInfo.second != remoteCRC) { - result = result + "local file [" + fileInfo.first + "] CRC mismatch.\n"; + return result; + } + + void NetworkMessageQuit::send(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] nmtQuit\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + assert(messageType == nmtQuit); + toEndian(); + + if (useOldProtocol == true) { + NetworkMessage::send(socket, &messageType, sizeof(messageType)); + } else { + unsigned char *buf = packMessage(); + //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); + NetworkMessage::send(socket, buf, getPackedSize()); + delete[] buf; } } - for(int i = 0; i < (int)data.header.techCRCFileCount; ++i) { - string networkFile = data.detail.techCRCFileList[i].getString(); - uint32 &networkFileCRC = data.detail.techCRCFileCRCList[i]; - bool fileFound = false; - uint32 localCRC = 0; - for(int idx = 0; idx < (int)vctFileList.size(); ++idx) { - std::pair &fileInfo = vctFileList[idx]; - if(networkFile == fileInfo.first) { - fileFound = true; - localCRC = fileInfo.second; - break; - } - } - - if(fileFound == false) { - result = result + "remote file [" + networkFile + "] missing locally.\n"; - } - else if(networkFileCRC != localCRC) { - result = result + "remote file [" + networkFile + "] CRC mismatch.\n"; + void NetworkMessageQuit::toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); } } - } - return result; -} - -const char * NetworkMessageSynchNetworkGameData::getPackedMessageFormatHeader() const { - return "c255s255s255sLLLL"; -} - -unsigned int NetworkMessageSynchNetworkGameData::getPackedSizeHeader() { - static unsigned int result = 0; - if(result == 0) { - Data packedData; - packedData.messageType=0; - unsigned char *buf = new unsigned char[sizeof(packedData)*3]; - result = pack(buf, getPackedMessageFormatHeader(), - packedData.messageType, - packedData.header.map.getBuffer(), - packedData.header.tileset.getBuffer(), - packedData.header.tech.getBuffer(), - packedData.header.mapCRC, - packedData.header.tilesetCRC, - packedData.header.techCRC, - packedData.header.techCRCFileCount); - delete [] buf; - } - return result; -} -void NetworkMessageSynchNetworkGameData::unpackMessageHeader(unsigned char *buf) { - unpack(buf, getPackedMessageFormatHeader(), - &data.messageType, - data.header.map.getBuffer(), - data.header.tileset.getBuffer(), - data.header.tech.getBuffer(), - &data.header.mapCRC, - &data.header.tilesetCRC, - &data.header.techCRC, - &data.header.techCRCFileCount); -} - -unsigned char * NetworkMessageSynchNetworkGameData::packMessageHeader() { - unsigned char *buf = new unsigned char[getPackedSizeHeader()+1]; - pack(buf, getPackedMessageFormatHeader(), - data.messageType, - data.header.map.getBuffer(), - data.header.tileset.getBuffer(), - data.header.tech.getBuffer(), - data.header.mapCRC, - data.header.tilesetCRC, - data.header.techCRC, - data.header.techCRCFileCount); - - return buf; -} - -unsigned int NetworkMessageSynchNetworkGameData::getPackedSizeDetail() { - static unsigned int result = 0; - if(result == 0) { - DataDetail packedData; - for(unsigned int index = 0; index < (unsigned int)maxFileCRCCount; ++index) { - packedData.techCRCFileCRCList[index] = 0; - } - unsigned char *buf = new unsigned char[sizeof(DataDetail)*3]; - - for(unsigned int i = 0; i < (unsigned int)maxFileCRCCount; ++i) { - result += pack(buf, "255s", - packedData.techCRCFileList[i].getBuffer()); - buf += result; - } - for(unsigned int i = 0; i < (unsigned int)maxFileCRCCount; ++i) { - result += pack(buf, "L", - packedData.techCRCFileCRCList[i]); - buf += result; - } - - delete [] buf; - } - return result; -} -void NetworkMessageSynchNetworkGameData::unpackMessageDetail(unsigned char *buf) { - for(unsigned int i = 0; i < (unsigned int)maxFileCRCCount; ++i) { - unsigned int bytes_processed = unpack(buf, "255s", - data.detail.techCRCFileList[i].getBuffer()); - buf += bytes_processed; - } - for(unsigned int i = 0; i < (unsigned int)maxFileCRCCount; ++i) { - unsigned int bytes_processed = unpack(buf, "L", - &data.detail.techCRCFileCRCList[i]); - buf += bytes_processed; - } -} - -unsigned char * NetworkMessageSynchNetworkGameData::packMessageDetail() { - unsigned char *buf = new unsigned char[sizeof(DataDetail)*3 +1]; - unsigned char *bufMove = buf; - for(unsigned int i = 0; i < (unsigned int)maxFileCRCCount; ++i) { - unsigned int bytes_processed = pack(bufMove, "255s", - data.detail.techCRCFileList[i].getBuffer()); - bufMove += bytes_processed; - } - for(unsigned int i = 0; i < (unsigned int)maxFileCRCCount; ++i) { - unsigned int bytes_processed = pack(bufMove, "L", - data.detail.techCRCFileCRCList[i]); - bufMove += bytes_processed; - } - - return buf; -} - - -bool NetworkMessageSynchNetworkGameData::receive(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to get nmtSynchNetworkGameData\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - data.header.techCRCFileCount = 0; - bool result = NetworkMessage::receive(socket, &data.header, HeaderSize, true); - fromEndianHeader(); - if(result == true) { - data.messageType = nmtSynchNetworkGameData; - } - - if(result == true && data.header.techCRCFileCount > 0) { - data.header.map.nullTerminate(); - data.header.tileset.nullTerminate(); - data.header.tech.nullTerminate(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] messageType = %d, data.techCRCFileCount = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,data.messageType,data.header.techCRCFileCount); - - - - // Here we loop possibly multiple times - int packetLoopCount = 1; - if(data.header.techCRCFileCount > (uint32)NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount) { - packetLoopCount = (data.header.techCRCFileCount / NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount); - if(data.header.techCRCFileCount % NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount > 0) { - packetLoopCount++; + void NetworkMessageQuit::fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); } } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] packetLoopCount = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,packetLoopCount); + // ===================================================== + // class NetworkMessageSynchNetworkGameData + // ===================================================== - for(int iPacketLoop = 0; result == true && iPacketLoop < packetLoopCount; ++iPacketLoop) { + NetworkMessageSynchNetworkGameData::NetworkMessageSynchNetworkGameData(const GameSettings *gameSettings) { + data.messageType = nmtSynchNetworkGameData; - int packetIndex = iPacketLoop * NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount; - int maxFileCountPerPacket = maxFileCRCPacketCount; - int packetFileCount = min((uint32)maxFileCountPerPacket,data.header.techCRCFileCount - packetIndex); - int packetDetail1DataSize = (DetailSize1 * packetFileCount); - int packetDetail2DataSize = (DetailSize2 * packetFileCount); + if (gameSettings == NULL) { + throw std::runtime_error("gameSettings == NULL"); + } + data.header.map = gameSettings->getMap(); + data.header.tileset = gameSettings->getTileset(); + data.header.tech = gameSettings->getTech(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] iPacketLoop = %d, packetIndex = %d, maxFileCountPerPacket = %d, packetFileCount = %d, packetDetail1DataSize = %d, packetDetail2DataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,iPacketLoop,packetIndex,maxFileCountPerPacket,packetFileCount,packetDetail1DataSize,packetDetail2DataSize); - - // Wait a max of x seconds for this message - result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[packetIndex], packetDetail1DataSize, true); - if(result == true) { - for(unsigned int i = 0; i < data.header.techCRCFileCount; ++i) { - data.detail.techCRCFileList[i].nullTerminate(); + Config &config = Config::getInstance(); + string scenarioDir = ""; + if (gameSettings->getScenarioDir() != "") { + scenarioDir = gameSettings->getScenarioDir(); + if (EndsWith(scenarioDir, ".xml") == true) { + scenarioDir = scenarioDir.erase(scenarioDir.size() - 4, 4); + scenarioDir = scenarioDir.erase(scenarioDir.size() - gameSettings->getScenario().size(), gameSettings->getScenario().size() + 1); } - result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[packetIndex], packetDetail2DataSize, true); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] gameSettings.getScenarioDir() = [%s] gameSettings.getScenario() = [%s] scenarioDir = [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, gameSettings->getScenarioDir().c_str(), gameSettings->getScenario().c_str(), scenarioDir.c_str()); } - } - fromEndianDetail(); - } - return result; -} + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); -void NetworkMessageSynchNetworkGameData::send(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to send nmtSynchNetworkGameData\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + data.header.tilesetCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTilesets, scenarioDir), string("/") + gameSettings->getTileset() + string("/*"), ".xml", NULL); - assert(data.messageType == nmtSynchNetworkGameData); - uint32 totalFileCount = data.header.techCRCFileCount; - toEndianHeader(); - NetworkMessage::send(socket, &data, HeaderSize); - if(totalFileCount > 0) { - // Here we loop possibly multiple times - int packetLoopCount = 1; - if(totalFileCount > (uint32)NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount) { - packetLoopCount = (totalFileCount / NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount); - if(totalFileCount % NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount > 0) { - packetLoopCount++; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] data.tilesetCRC = %d, [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, data.header.tilesetCRC, gameSettings->getTileset().c_str()); + + //tech, load before map because of resources + data.header.techCRC = getFolderTreeContentsCheckSumRecursively(config.getPathListForType(ptTechs, scenarioDir), string("/") + gameSettings->getTech() + string("/*"), ".xml", NULL); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] data.techCRC = %d, [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, data.header.techCRC, gameSettings->getTech().c_str()); + + vector > vctFileList; + vctFileList = getFolderTreeContentsCheckSumListRecursively(config.getPathListForType(ptTechs, scenarioDir), string("/") + gameSettings->getTech() + string("/*"), ".xml", &vctFileList); + data.header.techCRCFileCount = min((int) vctFileList.size(), (int) maxFileCRCCount); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] vctFileList.size() = %d, maxFileCRCCount = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, vctFileList.size(), maxFileCRCCount); + + for (int idx = 0; idx < (int) data.header.techCRCFileCount; ++idx) { + const std::pair &fileInfo = vctFileList[idx]; + data.detail.techCRCFileList[idx] = fileInfo.first; + data.detail.techCRCFileCRCList[idx] = fileInfo.second; } + + //map + Checksum checksum; + string file = Config::getMapPath(gameSettings->getMap(), scenarioDir, false); + checksum.addFile(file); + data.header.mapCRC = checksum.getSum(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] data.mapCRC = %d, [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, data.header.mapCRC, gameSettings->getMap().c_str()); } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] packetLoopCount = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,packetLoopCount); + string NetworkMessageSynchNetworkGameData::getTechCRCFileMismatchReport(vector > &vctFileList) { + string result = "Techtree: [" + data.header.tech.getString() + "] Filecount local: " + intToStr(vctFileList.size()) + " remote: " + intToStr(data.header.techCRCFileCount) + "\n"; + if (vctFileList.size() <= 0) { + result = result + "Local player has no files.\n"; + } else if (data.header.techCRCFileCount <= 0) { + result = result + "Remote player has no files.\n"; + } else { + for (int idx = 0; idx < (int) vctFileList.size(); ++idx) { + std::pair &fileInfo = vctFileList[idx]; + bool fileFound = false; + uint32 remoteCRC = 0; + for (int j = 0; j < (int) data.header.techCRCFileCount; ++j) { + string networkFile = data.detail.techCRCFileList[j].getString(); + uint32 &networkFileCRC = data.detail.techCRCFileCRCList[j]; + if (fileInfo.first == networkFile) { + fileFound = true; + remoteCRC = networkFileCRC; + break; + } + } - for(int iPacketLoop = 0; iPacketLoop < packetLoopCount; ++iPacketLoop) { - - int packetIndex = iPacketLoop * NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount; - int maxFileCountPerPacket = maxFileCRCPacketCount; - int packetFileCount = min((uint32)maxFileCountPerPacket,totalFileCount - packetIndex); - - NetworkMessage::send(socket, &data.detail.techCRCFileList[packetIndex], (DetailSize1 * packetFileCount)); - NetworkMessage::send(socket, &data.detail.techCRCFileCRCList[packetIndex], (DetailSize2 * packetFileCount)); - } - toEndianDetail(totalFileCount); - } -} - -void NetworkMessageSynchNetworkGameData::toEndianHeader() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - data.messageType = Shared::PlatformByteOrder::toCommonEndian(data.messageType); - data.header.mapCRC = Shared::PlatformByteOrder::toCommonEndian(data.header.mapCRC); - data.header.tilesetCRC = Shared::PlatformByteOrder::toCommonEndian(data.header.tilesetCRC); - data.header.techCRC = Shared::PlatformByteOrder::toCommonEndian(data.header.techCRC); - data.header.techCRCFileCount = Shared::PlatformByteOrder::toCommonEndian(data.header.techCRCFileCount); - } -} -void NetworkMessageSynchNetworkGameData::fromEndianHeader() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - data.messageType = Shared::PlatformByteOrder::fromCommonEndian(data.messageType); - data.header.mapCRC = Shared::PlatformByteOrder::fromCommonEndian(data.header.mapCRC); - data.header.tilesetCRC = Shared::PlatformByteOrder::fromCommonEndian(data.header.tilesetCRC); - data.header.techCRC = Shared::PlatformByteOrder::fromCommonEndian(data.header.techCRC); - data.header.techCRCFileCount = Shared::PlatformByteOrder::fromCommonEndian(data.header.techCRCFileCount); - } -} - -void NetworkMessageSynchNetworkGameData::toEndianDetail(uint32 totalFileCount) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - for(unsigned int i = 0; i < totalFileCount; ++i) { - data.detail.techCRCFileCRCList[i] = Shared::PlatformByteOrder::toCommonEndian(data.detail.techCRCFileCRCList[i]); - } - } -} -void NetworkMessageSynchNetworkGameData::fromEndianDetail() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - for(unsigned int i = 0; i < data.header.techCRCFileCount; ++i) { - data.detail.techCRCFileCRCList[i] = Shared::PlatformByteOrder::fromCommonEndian(data.detail.techCRCFileCRCList[i]); - } - } -} - -// ===================================================== -// class NetworkMessageSynchNetworkGameDataStatus -// ===================================================== - -NetworkMessageSynchNetworkGameDataStatus::NetworkMessageSynchNetworkGameDataStatus(uint32 mapCRC, uint32 tilesetCRC, uint32 techCRC, vector > &vctFileList) -{ - data.messageType= nmtSynchNetworkGameDataStatus; - - data.header.tilesetCRC = tilesetCRC; - data.header.techCRC = techCRC; - data.header.mapCRC = mapCRC; - - data.header.techCRCFileCount = min((int)vctFileList.size(),(int)maxFileCRCCount); - for(unsigned int idx =0; idx < data.header.techCRCFileCount; ++idx) { - const std::pair &fileInfo = vctFileList[idx]; - data.detail.techCRCFileList[idx] = fileInfo.first; - data.detail.techCRCFileCRCList[idx] = fileInfo.second; - } -} - -string NetworkMessageSynchNetworkGameDataStatus::getTechCRCFileMismatchReport(string techtree, vector > &vctFileList) { - string result = "Techtree: [" + techtree + "] Filecount local: " + intToStr(vctFileList.size()) + " remote: " + intToStr(data.header.techCRCFileCount) + "\n"; - if(vctFileList.size() <= 0) { - result = result + "Local player has no files.\n"; - } - else if(data.header.techCRCFileCount <= 0) { - result = result + "Remote player has no files.\n"; - } - else { - for(int idx = 0; idx < (int)vctFileList.size(); ++idx) { - std::pair &fileInfo = vctFileList[idx]; - bool fileFound = false; - uint32 remoteCRC = 0; - for(int j = 0; j < (int)data.header.techCRCFileCount; ++j) { - string networkFile = data.detail.techCRCFileList[j].getString(); - uint32 &networkFileCRC = data.detail.techCRCFileCRCList[j]; - if(fileInfo.first == networkFile) { - fileFound = true; - remoteCRC = networkFileCRC; - break; - } - } - - if(fileFound == false) { - result = result + "local file [" + fileInfo.first + "] missing remotely.\n"; - } - else if(fileInfo.second != remoteCRC) { - result = result + "local file [" + fileInfo.first + "] CRC mismatch.\n"; - } - } - - for(int i = 0; i < (int)data.header.techCRCFileCount; ++i) { - string networkFile = data.detail.techCRCFileList[i].getString(); - uint32 &networkFileCRC = data.detail.techCRCFileCRCList[i]; - bool fileFound = false; - uint32 localCRC = 0; - for(int idx = 0; idx < (int)vctFileList.size(); ++idx) { - std::pair &fileInfo = vctFileList[idx]; - - if(networkFile == fileInfo.first) { - fileFound = true; - localCRC = fileInfo.second; - break; - } - } - - if(fileFound == false) { - result = result + "remote file [" + networkFile + "] missing locally.\n"; - } - else if(networkFileCRC != localCRC) { - result = result + "remote file [" + networkFile + "] CRC mismatch.\n"; - } - } - } - return result; -} - -bool NetworkMessageSynchNetworkGameDataStatus::receive(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to get nmtSynchNetworkGameDataStatus\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - data.header.techCRCFileCount = 0; - - bool result = NetworkMessage::receive(socket, &data.header, HeaderSize, true); - if(result == true && data.header.techCRCFileCount > 0) { - fromEndianHeader(); - // Here we loop possibly multiple times - uint32 packetLoopCount = 1; - if(data.header.techCRCFileCount > NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount) { - packetLoopCount = (data.header.techCRCFileCount / NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount); - if(data.header.techCRCFileCount % NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount > 0) { - packetLoopCount++; - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] packetLoopCount = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,packetLoopCount); - - for(uint32 iPacketLoop = 0; iPacketLoop < packetLoopCount; ++iPacketLoop) { - - uint32 packetIndex = iPacketLoop * NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount; - uint32 maxFileCountPerPacket = maxFileCRCPacketCount; - uint32 packetFileCount = min((uint32)maxFileCountPerPacket,data.header.techCRCFileCount - packetIndex); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] iPacketLoop = %u, packetIndex = %u, packetFileCount = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,iPacketLoop,packetIndex,packetFileCount); - - result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[packetIndex], ((uint32)DetailSize1 * packetFileCount),true); - if(result == true) { - for(int i = 0; i < (int)data.header.techCRCFileCount; ++i) { - data.detail.techCRCFileList[i].nullTerminate(); + if (fileFound == false) { + result = result + "local file [" + fileInfo.first + "] missing remotely.\n"; + } else if (fileInfo.second != remoteCRC) { + result = result + "local file [" + fileInfo.first + "] CRC mismatch.\n"; + } } - // Wait a max of x seconds for this message - result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[packetIndex], ((uint32)DetailSize2 * packetFileCount),true); + for (int i = 0; i < (int) data.header.techCRCFileCount; ++i) { + string networkFile = data.detail.techCRCFileList[i].getString(); + uint32 &networkFileCRC = data.detail.techCRCFileCRCList[i]; + bool fileFound = false; + uint32 localCRC = 0; + for (int idx = 0; idx < (int) vctFileList.size(); ++idx) { + std::pair &fileInfo = vctFileList[idx]; + if (networkFile == fileInfo.first) { + fileFound = true; + localCRC = fileInfo.second; + break; + } + } + + if (fileFound == false) { + result = result + "remote file [" + networkFile + "] missing locally.\n"; + } else if (networkFileCRC != localCRC) { + result = result + "remote file [" + networkFile + "] CRC mismatch.\n"; + } + } } + return result; } - fromEndianDetail(); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] result = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result); + const char * NetworkMessageSynchNetworkGameData::getPackedMessageFormatHeader() const { + return "c255s255s255sLLLL"; + } - return result; -} + unsigned int NetworkMessageSynchNetworkGameData::getPackedSizeHeader() { + static unsigned int result = 0; + if (result == 0) { + Data packedData; + packedData.messageType = 0; + unsigned char *buf = new unsigned char[sizeof(packedData) * 3]; + result = pack(buf, getPackedMessageFormatHeader(), + packedData.messageType, + packedData.header.map.getBuffer(), + packedData.header.tileset.getBuffer(), + packedData.header.tech.getBuffer(), + packedData.header.mapCRC, + packedData.header.tilesetCRC, + packedData.header.techCRC, + packedData.header.techCRCFileCount); + delete[] buf; + } + return result; + } + void NetworkMessageSynchNetworkGameData::unpackMessageHeader(unsigned char *buf) { + unpack(buf, getPackedMessageFormatHeader(), + &data.messageType, + data.header.map.getBuffer(), + data.header.tileset.getBuffer(), + data.header.tech.getBuffer(), + &data.header.mapCRC, + &data.header.tilesetCRC, + &data.header.techCRC, + &data.header.techCRCFileCount); + } -void NetworkMessageSynchNetworkGameDataStatus::send(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to send nmtSynchNetworkGameDataStatus, data.header.techCRCFileCount = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,data.header.techCRCFileCount); + unsigned char * NetworkMessageSynchNetworkGameData::packMessageHeader() { + unsigned char *buf = new unsigned char[getPackedSizeHeader() + 1]; + pack(buf, getPackedMessageFormatHeader(), + data.messageType, + data.header.map.getBuffer(), + data.header.tileset.getBuffer(), + data.header.tech.getBuffer(), + data.header.mapCRC, + data.header.tilesetCRC, + data.header.techCRC, + data.header.techCRCFileCount); - assert(data.messageType == nmtSynchNetworkGameDataStatus); - uint32 totalFileCount = data.header.techCRCFileCount; - toEndianHeader(); - NetworkMessage::send(socket, &data, HeaderSize); - if(totalFileCount > 0) { - // Here we loop possibly multiple times - int packetLoopCount = 1; - if(totalFileCount > NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount) { - packetLoopCount = (totalFileCount / NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount); - if(totalFileCount % NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount > 0) { - packetLoopCount++; + return buf; + } + + unsigned int NetworkMessageSynchNetworkGameData::getPackedSizeDetail() { + static unsigned int result = 0; + if (result == 0) { + DataDetail packedData; + for (unsigned int index = 0; index < (unsigned int) maxFileCRCCount; ++index) { + packedData.techCRCFileCRCList[index] = 0; + } + unsigned char *buf = new unsigned char[sizeof(DataDetail) * 3]; + + for (unsigned int i = 0; i < (unsigned int) maxFileCRCCount; ++i) { + result += pack(buf, "255s", + packedData.techCRCFileList[i].getBuffer()); + buf += result; + } + for (unsigned int i = 0; i < (unsigned int) maxFileCRCCount; ++i) { + result += pack(buf, "L", + packedData.techCRCFileCRCList[i]); + buf += result; + } + + delete[] buf; + } + return result; + } + void NetworkMessageSynchNetworkGameData::unpackMessageDetail(unsigned char *buf) { + for (unsigned int i = 0; i < (unsigned int) maxFileCRCCount; ++i) { + unsigned int bytes_processed = unpack(buf, "255s", + data.detail.techCRCFileList[i].getBuffer()); + buf += bytes_processed; + } + for (unsigned int i = 0; i < (unsigned int) maxFileCRCCount; ++i) { + unsigned int bytes_processed = unpack(buf, "L", + &data.detail.techCRCFileCRCList[i]); + buf += bytes_processed; } } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] packetLoopCount = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,packetLoopCount); + unsigned char * NetworkMessageSynchNetworkGameData::packMessageDetail() { + unsigned char *buf = new unsigned char[sizeof(DataDetail) * 3 + 1]; + unsigned char *bufMove = buf; + for (unsigned int i = 0; i < (unsigned int) maxFileCRCCount; ++i) { + unsigned int bytes_processed = pack(bufMove, "255s", + data.detail.techCRCFileList[i].getBuffer()); + bufMove += bytes_processed; + } + for (unsigned int i = 0; i < (unsigned int) maxFileCRCCount; ++i) { + unsigned int bytes_processed = pack(bufMove, "L", + data.detail.techCRCFileCRCList[i]); + bufMove += bytes_processed; + } - toEndianDetail(totalFileCount); - for(int iPacketLoop = 0; iPacketLoop < packetLoopCount; ++iPacketLoop) { - - int packetIndex = iPacketLoop * NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount; - int maxFileCountPerPacket = maxFileCRCPacketCount; - int packetFileCount = min((uint32)maxFileCountPerPacket,totalFileCount - packetIndex); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] packetLoop = %d, packetIndex = %d, packetFileCount = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,iPacketLoop,packetIndex,packetFileCount); - - NetworkMessage::send(socket, &data.detail.techCRCFileList[packetIndex], (DetailSize1 * packetFileCount)); - NetworkMessage::send(socket, &data.detail.techCRCFileCRCList[packetIndex], (DetailSize2 * packetFileCount)); + return buf; } - } -} -void NetworkMessageSynchNetworkGameDataStatus::toEndianHeader() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - data.messageType = Shared::PlatformByteOrder::toCommonEndian(data.messageType); - data.header.mapCRC = Shared::PlatformByteOrder::toCommonEndian(data.header.mapCRC); - data.header.tilesetCRC = Shared::PlatformByteOrder::toCommonEndian(data.header.tilesetCRC); - data.header.techCRC = Shared::PlatformByteOrder::toCommonEndian(data.header.techCRC); - data.header.techCRCFileCount = Shared::PlatformByteOrder::toCommonEndian(data.header.techCRCFileCount); - } -} -void NetworkMessageSynchNetworkGameDataStatus::fromEndianHeader() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - data.messageType = Shared::PlatformByteOrder::fromCommonEndian(data.messageType); - data.header.mapCRC = Shared::PlatformByteOrder::fromCommonEndian(data.header.mapCRC); - data.header.tilesetCRC = Shared::PlatformByteOrder::fromCommonEndian(data.header.tilesetCRC); - data.header.techCRC = Shared::PlatformByteOrder::fromCommonEndian(data.header.techCRC); - data.header.techCRCFileCount = Shared::PlatformByteOrder::fromCommonEndian(data.header.techCRCFileCount); - } -} + bool NetworkMessageSynchNetworkGameData::receive(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] about to get nmtSynchNetworkGameData\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); -void NetworkMessageSynchNetworkGameDataStatus::toEndianDetail(uint32 totalFileCount) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - for(unsigned int i = 0; i < totalFileCount; ++i) { - data.detail.techCRCFileCRCList[i] = Shared::PlatformByteOrder::toCommonEndian(data.detail.techCRCFileCRCList[i]); + data.header.techCRCFileCount = 0; + bool result = NetworkMessage::receive(socket, &data.header, HeaderSize, true); + fromEndianHeader(); + if (result == true) { + data.messageType = nmtSynchNetworkGameData; + } + + if (result == true && data.header.techCRCFileCount > 0) { + data.header.map.nullTerminate(); + data.header.tileset.nullTerminate(); + data.header.tech.nullTerminate(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] messageType = %d, data.techCRCFileCount = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, data.messageType, data.header.techCRCFileCount); + + + + // Here we loop possibly multiple times + int packetLoopCount = 1; + if (data.header.techCRCFileCount > (uint32) NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount) { + packetLoopCount = (data.header.techCRCFileCount / NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount); + if (data.header.techCRCFileCount % NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount > 0) { + packetLoopCount++; + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] packetLoopCount = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, packetLoopCount); + + for (int iPacketLoop = 0; result == true && iPacketLoop < packetLoopCount; ++iPacketLoop) { + + int packetIndex = iPacketLoop * NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount; + int maxFileCountPerPacket = maxFileCRCPacketCount; + int packetFileCount = min((uint32) maxFileCountPerPacket, data.header.techCRCFileCount - packetIndex); + int packetDetail1DataSize = (DetailSize1 * packetFileCount); + int packetDetail2DataSize = (DetailSize2 * packetFileCount); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] iPacketLoop = %d, packetIndex = %d, maxFileCountPerPacket = %d, packetFileCount = %d, packetDetail1DataSize = %d, packetDetail2DataSize = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, iPacketLoop, packetIndex, maxFileCountPerPacket, packetFileCount, packetDetail1DataSize, packetDetail2DataSize); + + // Wait a max of x seconds for this message + result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[packetIndex], packetDetail1DataSize, true); + if (result == true) { + for (unsigned int i = 0; i < data.header.techCRCFileCount; ++i) { + data.detail.techCRCFileList[i].nullTerminate(); + } + + result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[packetIndex], packetDetail2DataSize, true); + } + } + fromEndianDetail(); + } + + return result; } - } -} -void NetworkMessageSynchNetworkGameDataStatus::fromEndianDetail() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - for(unsigned int i = 0; i < data.header.techCRCFileCount; ++i) { - data.detail.techCRCFileCRCList[i] = Shared::PlatformByteOrder::fromCommonEndian(data.detail.techCRCFileCRCList[i]); + + void NetworkMessageSynchNetworkGameData::send(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] about to send nmtSynchNetworkGameData\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + assert(data.messageType == nmtSynchNetworkGameData); + uint32 totalFileCount = data.header.techCRCFileCount; + toEndianHeader(); + NetworkMessage::send(socket, &data, HeaderSize); + if (totalFileCount > 0) { + // Here we loop possibly multiple times + int packetLoopCount = 1; + if (totalFileCount > (uint32) NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount) { + packetLoopCount = (totalFileCount / NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount); + if (totalFileCount % NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount > 0) { + packetLoopCount++; + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] packetLoopCount = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, packetLoopCount); + + for (int iPacketLoop = 0; iPacketLoop < packetLoopCount; ++iPacketLoop) { + + int packetIndex = iPacketLoop * NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount; + int maxFileCountPerPacket = maxFileCRCPacketCount; + int packetFileCount = min((uint32) maxFileCountPerPacket, totalFileCount - packetIndex); + + NetworkMessage::send(socket, &data.detail.techCRCFileList[packetIndex], (DetailSize1 * packetFileCount)); + NetworkMessage::send(socket, &data.detail.techCRCFileCRCList[packetIndex], (DetailSize2 * packetFileCount)); + } + toEndianDetail(totalFileCount); + } } - } -} -// ===================================================== -// class NetworkMessageSynchNetworkGameDataFileCRCCheck -// ===================================================== + void NetworkMessageSynchNetworkGameData::toEndianHeader() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + data.messageType = Shared::PlatformByteOrder::toCommonEndian(data.messageType); + data.header.mapCRC = Shared::PlatformByteOrder::toCommonEndian(data.header.mapCRC); + data.header.tilesetCRC = Shared::PlatformByteOrder::toCommonEndian(data.header.tilesetCRC); + data.header.techCRC = Shared::PlatformByteOrder::toCommonEndian(data.header.techCRC); + data.header.techCRCFileCount = Shared::PlatformByteOrder::toCommonEndian(data.header.techCRCFileCount); + } + } + void NetworkMessageSynchNetworkGameData::fromEndianHeader() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + data.messageType = Shared::PlatformByteOrder::fromCommonEndian(data.messageType); + data.header.mapCRC = Shared::PlatformByteOrder::fromCommonEndian(data.header.mapCRC); + data.header.tilesetCRC = Shared::PlatformByteOrder::fromCommonEndian(data.header.tilesetCRC); + data.header.techCRC = Shared::PlatformByteOrder::fromCommonEndian(data.header.techCRC); + data.header.techCRCFileCount = Shared::PlatformByteOrder::fromCommonEndian(data.header.techCRCFileCount); + } + } -NetworkMessageSynchNetworkGameDataFileCRCCheck::NetworkMessageSynchNetworkGameDataFileCRCCheck() { - messageType= nmtSynchNetworkGameDataFileCRCCheck; -} + void NetworkMessageSynchNetworkGameData::toEndianDetail(uint32 totalFileCount) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + for (unsigned int i = 0; i < totalFileCount; ++i) { + data.detail.techCRCFileCRCList[i] = Shared::PlatformByteOrder::toCommonEndian(data.detail.techCRCFileCRCList[i]); + } + } + } + void NetworkMessageSynchNetworkGameData::fromEndianDetail() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + for (unsigned int i = 0; i < data.header.techCRCFileCount; ++i) { + data.detail.techCRCFileCRCList[i] = Shared::PlatformByteOrder::fromCommonEndian(data.detail.techCRCFileCRCList[i]); + } + } + } -NetworkMessageSynchNetworkGameDataFileCRCCheck::NetworkMessageSynchNetworkGameDataFileCRCCheck( - uint32 totalFileCount, uint32 fileIndex, uint32 fileCRC, const string fileName) -{ - messageType= nmtSynchNetworkGameDataFileCRCCheck; + // ===================================================== + // class NetworkMessageSynchNetworkGameDataStatus + // ===================================================== - data.totalFileCount = totalFileCount; - data.fileIndex = fileIndex; - data.fileCRC = fileCRC; - data.fileName = fileName; -} + NetworkMessageSynchNetworkGameDataStatus::NetworkMessageSynchNetworkGameDataStatus(uint32 mapCRC, uint32 tilesetCRC, uint32 techCRC, vector > &vctFileList) { + data.messageType = nmtSynchNetworkGameDataStatus; -const char * NetworkMessageSynchNetworkGameDataFileCRCCheck::getPackedMessageFormat() const { - return "cLLL256s"; -} + data.header.tilesetCRC = tilesetCRC; + data.header.techCRC = techCRC; + data.header.mapCRC = mapCRC; -unsigned int NetworkMessageSynchNetworkGameDataFileCRCCheck::getPackedSize() { - static unsigned int result = 0; - if(result == 0) { - Data packedData; - packedData.fileCRC = 0; - packedData.fileIndex = 0; - messageType = nmtSynchNetworkGameDataFileCRCCheck; - packedData.totalFileCount = 0; + data.header.techCRCFileCount = min((int) vctFileList.size(), (int) maxFileCRCCount); + for (unsigned int idx = 0; idx < data.header.techCRCFileCount; ++idx) { + const std::pair &fileInfo = vctFileList[idx]; + data.detail.techCRCFileList[idx] = fileInfo.first; + data.detail.techCRCFileCRCList[idx] = fileInfo.second; + } + } - unsigned char *buf = new unsigned char[sizeof(packedData)*3]; - result = pack(buf, getPackedMessageFormat(), + string NetworkMessageSynchNetworkGameDataStatus::getTechCRCFileMismatchReport(string techtree, vector > &vctFileList) { + string result = "Techtree: [" + techtree + "] Filecount local: " + intToStr(vctFileList.size()) + " remote: " + intToStr(data.header.techCRCFileCount) + "\n"; + if (vctFileList.size() <= 0) { + result = result + "Local player has no files.\n"; + } else if (data.header.techCRCFileCount <= 0) { + result = result + "Remote player has no files.\n"; + } else { + for (int idx = 0; idx < (int) vctFileList.size(); ++idx) { + std::pair &fileInfo = vctFileList[idx]; + bool fileFound = false; + uint32 remoteCRC = 0; + for (int j = 0; j < (int) data.header.techCRCFileCount; ++j) { + string networkFile = data.detail.techCRCFileList[j].getString(); + uint32 &networkFileCRC = data.detail.techCRCFileCRCList[j]; + if (fileInfo.first == networkFile) { + fileFound = true; + remoteCRC = networkFileCRC; + break; + } + } + + if (fileFound == false) { + result = result + "local file [" + fileInfo.first + "] missing remotely.\n"; + } else if (fileInfo.second != remoteCRC) { + result = result + "local file [" + fileInfo.first + "] CRC mismatch.\n"; + } + } + + for (int i = 0; i < (int) data.header.techCRCFileCount; ++i) { + string networkFile = data.detail.techCRCFileList[i].getString(); + uint32 &networkFileCRC = data.detail.techCRCFileCRCList[i]; + bool fileFound = false; + uint32 localCRC = 0; + for (int idx = 0; idx < (int) vctFileList.size(); ++idx) { + std::pair &fileInfo = vctFileList[idx]; + + if (networkFile == fileInfo.first) { + fileFound = true; + localCRC = fileInfo.second; + break; + } + } + + if (fileFound == false) { + result = result + "remote file [" + networkFile + "] missing locally.\n"; + } else if (networkFileCRC != localCRC) { + result = result + "remote file [" + networkFile + "] CRC mismatch.\n"; + } + } + } + return result; + } + + bool NetworkMessageSynchNetworkGameDataStatus::receive(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] about to get nmtSynchNetworkGameDataStatus\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + data.header.techCRCFileCount = 0; + + bool result = NetworkMessage::receive(socket, &data.header, HeaderSize, true); + if (result == true && data.header.techCRCFileCount > 0) { + fromEndianHeader(); + // Here we loop possibly multiple times + uint32 packetLoopCount = 1; + if (data.header.techCRCFileCount > NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount) { + packetLoopCount = (data.header.techCRCFileCount / NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount); + if (data.header.techCRCFileCount % NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount > 0) { + packetLoopCount++; + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] packetLoopCount = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, packetLoopCount); + + for (uint32 iPacketLoop = 0; iPacketLoop < packetLoopCount; ++iPacketLoop) { + + uint32 packetIndex = iPacketLoop * NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount; + uint32 maxFileCountPerPacket = maxFileCRCPacketCount; + uint32 packetFileCount = min((uint32) maxFileCountPerPacket, data.header.techCRCFileCount - packetIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] iPacketLoop = %u, packetIndex = %u, packetFileCount = %u\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, iPacketLoop, packetIndex, packetFileCount); + + result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[packetIndex], ((uint32) DetailSize1 * packetFileCount), true); + if (result == true) { + for (int i = 0; i < (int) data.header.techCRCFileCount; ++i) { + data.detail.techCRCFileList[i].nullTerminate(); + } + + // Wait a max of x seconds for this message + result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[packetIndex], ((uint32) DetailSize2 * packetFileCount), true); + } + } + fromEndianDetail(); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] result = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, result); + + return result; + } + + void NetworkMessageSynchNetworkGameDataStatus::send(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] about to send nmtSynchNetworkGameDataStatus, data.header.techCRCFileCount = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, data.header.techCRCFileCount); + + assert(data.messageType == nmtSynchNetworkGameDataStatus); + uint32 totalFileCount = data.header.techCRCFileCount; + toEndianHeader(); + NetworkMessage::send(socket, &data, HeaderSize); + if (totalFileCount > 0) { + // Here we loop possibly multiple times + int packetLoopCount = 1; + if (totalFileCount > NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount) { + packetLoopCount = (totalFileCount / NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount); + if (totalFileCount % NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount > 0) { + packetLoopCount++; + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] packetLoopCount = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, packetLoopCount); + + toEndianDetail(totalFileCount); + for (int iPacketLoop = 0; iPacketLoop < packetLoopCount; ++iPacketLoop) { + + int packetIndex = iPacketLoop * NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount; + int maxFileCountPerPacket = maxFileCRCPacketCount; + int packetFileCount = min((uint32) maxFileCountPerPacket, totalFileCount - packetIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] packetLoop = %d, packetIndex = %d, packetFileCount = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, iPacketLoop, packetIndex, packetFileCount); + + NetworkMessage::send(socket, &data.detail.techCRCFileList[packetIndex], (DetailSize1 * packetFileCount)); + NetworkMessage::send(socket, &data.detail.techCRCFileCRCList[packetIndex], (DetailSize2 * packetFileCount)); + } + } + } + + void NetworkMessageSynchNetworkGameDataStatus::toEndianHeader() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + data.messageType = Shared::PlatformByteOrder::toCommonEndian(data.messageType); + data.header.mapCRC = Shared::PlatformByteOrder::toCommonEndian(data.header.mapCRC); + data.header.tilesetCRC = Shared::PlatformByteOrder::toCommonEndian(data.header.tilesetCRC); + data.header.techCRC = Shared::PlatformByteOrder::toCommonEndian(data.header.techCRC); + data.header.techCRCFileCount = Shared::PlatformByteOrder::toCommonEndian(data.header.techCRCFileCount); + } + } + + void NetworkMessageSynchNetworkGameDataStatus::fromEndianHeader() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + data.messageType = Shared::PlatformByteOrder::fromCommonEndian(data.messageType); + data.header.mapCRC = Shared::PlatformByteOrder::fromCommonEndian(data.header.mapCRC); + data.header.tilesetCRC = Shared::PlatformByteOrder::fromCommonEndian(data.header.tilesetCRC); + data.header.techCRC = Shared::PlatformByteOrder::fromCommonEndian(data.header.techCRC); + data.header.techCRCFileCount = Shared::PlatformByteOrder::fromCommonEndian(data.header.techCRCFileCount); + } + } + + void NetworkMessageSynchNetworkGameDataStatus::toEndianDetail(uint32 totalFileCount) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + for (unsigned int i = 0; i < totalFileCount; ++i) { + data.detail.techCRCFileCRCList[i] = Shared::PlatformByteOrder::toCommonEndian(data.detail.techCRCFileCRCList[i]); + } + } + } + void NetworkMessageSynchNetworkGameDataStatus::fromEndianDetail() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + for (unsigned int i = 0; i < data.header.techCRCFileCount; ++i) { + data.detail.techCRCFileCRCList[i] = Shared::PlatformByteOrder::fromCommonEndian(data.detail.techCRCFileCRCList[i]); + } + } + } + + // ===================================================== + // class NetworkMessageSynchNetworkGameDataFileCRCCheck + // ===================================================== + + NetworkMessageSynchNetworkGameDataFileCRCCheck::NetworkMessageSynchNetworkGameDataFileCRCCheck() { + messageType = nmtSynchNetworkGameDataFileCRCCheck; + } + + NetworkMessageSynchNetworkGameDataFileCRCCheck::NetworkMessageSynchNetworkGameDataFileCRCCheck( + uint32 totalFileCount, uint32 fileIndex, uint32 fileCRC, const string fileName) { + messageType = nmtSynchNetworkGameDataFileCRCCheck; + + data.totalFileCount = totalFileCount; + data.fileIndex = fileIndex; + data.fileCRC = fileCRC; + data.fileName = fileName; + } + + const char * NetworkMessageSynchNetworkGameDataFileCRCCheck::getPackedMessageFormat() const { + return "cLLL256s"; + } + + unsigned int NetworkMessageSynchNetworkGameDataFileCRCCheck::getPackedSize() { + static unsigned int result = 0; + if (result == 0) { + Data packedData; + packedData.fileCRC = 0; + packedData.fileIndex = 0; + messageType = nmtSynchNetworkGameDataFileCRCCheck; + packedData.totalFileCount = 0; + + unsigned char *buf = new unsigned char[sizeof(packedData) * 3]; + result = pack(buf, getPackedMessageFormat(), + messageType, + packedData.totalFileCount, + packedData.fileIndex, + packedData.fileCRC, + packedData.fileName.getBuffer()); + delete[] buf; + } + return result; + } + void NetworkMessageSynchNetworkGameDataFileCRCCheck::unpackMessage(unsigned char *buf) { + unpack(buf, getPackedMessageFormat(), + &messageType, + &data.totalFileCount, + &data.fileIndex, + &data.fileCRC, + data.fileName.getBuffer()); + } + + unsigned char * NetworkMessageSynchNetworkGameDataFileCRCCheck::packMessage() { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + pack(buf, getPackedMessageFormat(), messageType, - packedData.totalFileCount, - packedData.fileIndex, - packedData.fileCRC, - packedData.fileName.getBuffer()); - delete [] buf; - } - return result; -} -void NetworkMessageSynchNetworkGameDataFileCRCCheck::unpackMessage(unsigned char *buf) { - unpack(buf, getPackedMessageFormat(), - &messageType, - &data.totalFileCount, - &data.fileIndex, - &data.fileCRC, - data.fileName.getBuffer()); -} + data.totalFileCount, + data.fileIndex, + data.fileCRC, + data.fileName.getBuffer()); + return buf; + } -unsigned char * NetworkMessageSynchNetworkGameDataFileCRCCheck::packMessage() { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - pack(buf, getPackedMessageFormat(), - messageType, - data.totalFileCount, - data.fileIndex, - data.fileCRC, - data.fileName.getBuffer()); - return buf; -} + bool NetworkMessageSynchNetworkGameDataFileCRCCheck::receive(Socket* socket) { + bool result = false; + if (useOldProtocol == true) { + result = NetworkMessage::receive(socket, &data, sizeof(data), true); + } else { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + result = NetworkMessage::receive(socket, buf, getPackedSize(), true); + unpackMessage(buf); + //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); + delete[] buf; + } + fromEndian(); + data.fileName.nullTerminate(); -bool NetworkMessageSynchNetworkGameDataFileCRCCheck::receive(Socket* socket) { - bool result = false; - if(useOldProtocol == true) { - result = NetworkMessage::receive(socket, &data, sizeof(data),true); - } - else { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - result = NetworkMessage::receive(socket, buf, getPackedSize(), true); - unpackMessage(buf); - //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); - delete [] buf; - } - fromEndian(); - data.fileName.nullTerminate(); + return result; + } - return result; -} + void NetworkMessageSynchNetworkGameDataFileCRCCheck::send(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] nmtSynchNetworkGameDataFileCRCCheck\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); -void NetworkMessageSynchNetworkGameDataFileCRCCheck::send(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtSynchNetworkGameDataFileCRCCheck\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + assert(messageType == nmtSynchNetworkGameDataFileCRCCheck); + toEndian(); - assert(messageType == nmtSynchNetworkGameDataFileCRCCheck); - toEndian(); + if (useOldProtocol == true) { + //NetworkMessage::send(socket, &messageType, sizeof(messageType)); + NetworkMessage::send(socket, &data, sizeof(data), messageType); + } else { + unsigned char *buf = packMessage(); + //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); + NetworkMessage::send(socket, buf, getPackedSize()); + delete[] buf; + } + } - if(useOldProtocol == true) { - //NetworkMessage::send(socket, &messageType, sizeof(messageType)); - NetworkMessage::send(socket, &data, sizeof(data), messageType); - } - else { - unsigned char *buf = packMessage(); - //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); - NetworkMessage::send(socket, buf, getPackedSize()); - delete [] buf; - } -} + void NetworkMessageSynchNetworkGameDataFileCRCCheck::toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); + data.totalFileCount = Shared::PlatformByteOrder::toCommonEndian(data.totalFileCount); + data.fileIndex = Shared::PlatformByteOrder::toCommonEndian(data.fileIndex); + data.fileCRC = Shared::PlatformByteOrder::toCommonEndian(data.fileCRC); + } + } -void NetworkMessageSynchNetworkGameDataFileCRCCheck::toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); - data.totalFileCount = Shared::PlatformByteOrder::toCommonEndian(data.totalFileCount); - data.fileIndex = Shared::PlatformByteOrder::toCommonEndian(data.fileIndex); - data.fileCRC = Shared::PlatformByteOrder::toCommonEndian(data.fileCRC); - } -} + void NetworkMessageSynchNetworkGameDataFileCRCCheck::fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); + data.totalFileCount = Shared::PlatformByteOrder::fromCommonEndian(data.totalFileCount); + data.fileIndex = Shared::PlatformByteOrder::fromCommonEndian(data.fileIndex); + data.fileCRC = Shared::PlatformByteOrder::fromCommonEndian(data.fileCRC); + } + } + // ===================================================== + // class NetworkMessageSynchNetworkGameDataFileGet + // ===================================================== + NetworkMessageSynchNetworkGameDataFileGet::NetworkMessageSynchNetworkGameDataFileGet() { + messageType = nmtSynchNetworkGameDataFileGet; + } + NetworkMessageSynchNetworkGameDataFileGet::NetworkMessageSynchNetworkGameDataFileGet(const string fileName) { + messageType = nmtSynchNetworkGameDataFileGet; + data.fileName = fileName; + } -void NetworkMessageSynchNetworkGameDataFileCRCCheck::fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); - data.totalFileCount = Shared::PlatformByteOrder::fromCommonEndian(data.totalFileCount); - data.fileIndex = Shared::PlatformByteOrder::fromCommonEndian(data.fileIndex); - data.fileCRC = Shared::PlatformByteOrder::fromCommonEndian(data.fileCRC); - } -} -// ===================================================== -// class NetworkMessageSynchNetworkGameDataFileGet -// ===================================================== -NetworkMessageSynchNetworkGameDataFileGet::NetworkMessageSynchNetworkGameDataFileGet() { - messageType= nmtSynchNetworkGameDataFileGet; -} -NetworkMessageSynchNetworkGameDataFileGet::NetworkMessageSynchNetworkGameDataFileGet(const string fileName) { - messageType= nmtSynchNetworkGameDataFileGet; - data.fileName = fileName; -} + const char * NetworkMessageSynchNetworkGameDataFileGet::getPackedMessageFormat() const { + return "c256s"; + } -const char * NetworkMessageSynchNetworkGameDataFileGet::getPackedMessageFormat() const { - return "c256s"; -} + unsigned int NetworkMessageSynchNetworkGameDataFileGet::getPackedSize() { + static unsigned int result = 0; + if (result == 0) { + Data packedData; + messageType = nmtSynchNetworkGameDataFileGet; + unsigned char *buf = new unsigned char[sizeof(packedData) * 3]; + result = pack(buf, getPackedMessageFormat(), + messageType, + packedData.fileName.getBuffer()); + delete[] buf; + } + return result; + } + void NetworkMessageSynchNetworkGameDataFileGet::unpackMessage(unsigned char *buf) { + unpack(buf, getPackedMessageFormat(), + &messageType, + data.fileName.getBuffer()); + } -unsigned int NetworkMessageSynchNetworkGameDataFileGet::getPackedSize() { - static unsigned int result = 0; - if(result == 0) { - Data packedData; - messageType = nmtSynchNetworkGameDataFileGet; - unsigned char *buf = new unsigned char[sizeof(packedData)*3]; - result = pack(buf, getPackedMessageFormat(), + unsigned char * NetworkMessageSynchNetworkGameDataFileGet::packMessage() { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + pack(buf, getPackedMessageFormat(), messageType, - packedData.fileName.getBuffer()); - delete [] buf; - } - return result; -} -void NetworkMessageSynchNetworkGameDataFileGet::unpackMessage(unsigned char *buf) { - unpack(buf, getPackedMessageFormat(), - &messageType, - data.fileName.getBuffer()); -} + data.fileName.getBuffer()); + return buf; + } -unsigned char * NetworkMessageSynchNetworkGameDataFileGet::packMessage() { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - pack(buf, getPackedMessageFormat(), - messageType, - data.fileName.getBuffer()); - return buf; -} + bool NetworkMessageSynchNetworkGameDataFileGet::receive(Socket* socket) { + bool result = false; + if (useOldProtocol == true) { + result = NetworkMessage::receive(socket, &data, sizeof(data), true); + } else { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + result = NetworkMessage::receive(socket, buf, getPackedSize(), true); + unpackMessage(buf); + //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); + delete[] buf; + } + fromEndian(); + data.fileName.nullTerminate(); -bool NetworkMessageSynchNetworkGameDataFileGet::receive(Socket* socket) { - bool result = false; - if(useOldProtocol == true) { - result = NetworkMessage::receive(socket, &data, sizeof(data),true); - } - else { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - result = NetworkMessage::receive(socket, buf, getPackedSize(), true); - unpackMessage(buf); - //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); - delete [] buf; - } - fromEndian(); - data.fileName.nullTerminate(); + return result; + } - return result; -} + void NetworkMessageSynchNetworkGameDataFileGet::send(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] nmtSynchNetworkGameDataFileGet\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); -void NetworkMessageSynchNetworkGameDataFileGet::send(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtSynchNetworkGameDataFileGet\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + assert(messageType == nmtSynchNetworkGameDataFileGet); + toEndian(); + if (useOldProtocol == true) { + //NetworkMessage::send(socket, &messageType, sizeof(messageType)); + NetworkMessage::send(socket, &data, sizeof(data), messageType); + } else { + unsigned char *buf = packMessage(); + //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); + NetworkMessage::send(socket, buf, getPackedSize()); + delete[] buf; + } + } - assert(messageType == nmtSynchNetworkGameDataFileGet); - toEndian(); - if(useOldProtocol == true) { - //NetworkMessage::send(socket, &messageType, sizeof(messageType)); - NetworkMessage::send(socket, &data, sizeof(data), messageType); - } - else { - unsigned char *buf = packMessage(); - //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); - NetworkMessage::send(socket, buf, getPackedSize()); - delete [] buf; - } -} - -void NetworkMessageSynchNetworkGameDataFileGet::toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); - } -} -void NetworkMessageSynchNetworkGameDataFileGet::fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); - } -} + void NetworkMessageSynchNetworkGameDataFileGet::toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); + } + } + void NetworkMessageSynchNetworkGameDataFileGet::fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); + } + } -// ===================================================== -// class SwitchSetupRequest -// ===================================================== + // ===================================================== + // class SwitchSetupRequest + // ===================================================== -SwitchSetupRequest::SwitchSetupRequest() { - messageType= nmtSwitchSetupRequest; - data.selectedFactionName=""; - data.currentSlotIndex=-1; - data.toSlotIndex=-1; - data.toTeam = -1; - data.networkPlayerName=""; - data.networkPlayerStatus = npst_None; - data.switchFlags = ssrft_None; - data.language = ""; -} - -SwitchSetupRequest::SwitchSetupRequest(string selectedFactionName, int8 currentFactionIndex, - int8 toFactionIndex,int8 toTeam,string networkPlayerName, - int8 networkPlayerStatus, int8 flags, - string language) { - messageType= nmtSwitchSetupRequest; - data.selectedFactionName=selectedFactionName; - data.currentSlotIndex=currentFactionIndex; - data.toSlotIndex=toFactionIndex; - data.toTeam = toTeam; - data.networkPlayerName=networkPlayerName; - data.networkPlayerStatus=networkPlayerStatus; - data.switchFlags = flags; - data.language = language; -} - -const char * SwitchSetupRequest::getPackedMessageFormat() const { - return "c256sccc80scc60s"; -} - -unsigned int SwitchSetupRequest::getPackedSize() { - static unsigned int result = 0; - if(result == 0) { - Data packedData; - packedData.currentSlotIndex = 0; - messageType = nmtSwitchSetupRequest; - packedData.networkPlayerStatus = 0; - packedData.switchFlags = 0; - packedData.toSlotIndex = 0; - packedData.toTeam = 0; - - unsigned char *buf = new unsigned char[sizeof(Data)*3]; - result = pack(buf, getPackedMessageFormat(), - messageType, - packedData.selectedFactionName.getBuffer(), - packedData.currentSlotIndex, - packedData.toSlotIndex, - packedData.toTeam, - packedData.networkPlayerName.getBuffer(), - packedData.networkPlayerStatus, - packedData.switchFlags, - packedData.language.getBuffer()); - delete [] buf; - } - return result; -} -void SwitchSetupRequest::unpackMessage(unsigned char *buf) { - unpack(buf, getPackedMessageFormat(), - &messageType, - data.selectedFactionName.getBuffer(), - &data.currentSlotIndex, - &data.toSlotIndex, - &data.toTeam, - data.networkPlayerName.getBuffer(), - &data.networkPlayerStatus, - &data.switchFlags, - data.language.getBuffer()); -} - -unsigned char * SwitchSetupRequest::packMessage() { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - pack(buf, getPackedMessageFormat(), - messageType, - data.selectedFactionName.getBuffer(), - data.currentSlotIndex, - data.toSlotIndex, - data.toTeam, - data.networkPlayerName.getBuffer(), - data.networkPlayerStatus, - data.switchFlags, - data.language.getBuffer()); - return buf; -} - -bool SwitchSetupRequest::receive(Socket* socket) { - bool result = false; - if(useOldProtocol == true) { - - result = NetworkMessage::receive(socket, &data, sizeof(data), true); - if(result == true) { + SwitchSetupRequest::SwitchSetupRequest() { messageType = nmtSwitchSetupRequest; + data.selectedFactionName = ""; + data.currentSlotIndex = -1; + data.toSlotIndex = -1; + data.toTeam = -1; + data.networkPlayerName = ""; + data.networkPlayerStatus = npst_None; + data.switchFlags = ssrft_None; + data.language = ""; } - } - else { - //fromEndian(); - unsigned char *buf = new unsigned char[getPackedSize()+1]; - result = NetworkMessage::receive(socket, buf, getPackedSize(), true); - unpackMessage(buf); - //printf("Got packet size = %u data.messageType = %d\n%s\nTeam = %d faction [%s] currentFactionIndex = %d toFactionIndex = %d\n",getPackedSize(),data.messageType,buf,data.toTeam,data.selectedFactionName.getBuffer(),data.currentFactionIndex,data.toFactionIndex); - delete [] buf; - } - fromEndian(); + SwitchSetupRequest::SwitchSetupRequest(string selectedFactionName, int8 currentFactionIndex, + int8 toFactionIndex, int8 toTeam, string networkPlayerName, + int8 networkPlayerStatus, int8 flags, + string language) { + messageType = nmtSwitchSetupRequest; + data.selectedFactionName = selectedFactionName; + data.currentSlotIndex = currentFactionIndex; + data.toSlotIndex = toFactionIndex; + data.toTeam = toTeam; + data.networkPlayerName = networkPlayerName; + data.networkPlayerStatus = networkPlayerStatus; + data.switchFlags = flags; + data.language = language; + } - data.selectedFactionName.nullTerminate(); - data.networkPlayerName.nullTerminate(); - data.language.nullTerminate(); + const char * SwitchSetupRequest::getPackedMessageFormat() const { + return "c256sccc80scc60s"; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] data.networkPlayerName [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,data.networkPlayerName.getString().c_str()); + unsigned int SwitchSetupRequest::getPackedSize() { + static unsigned int result = 0; + if (result == 0) { + Data packedData; + packedData.currentSlotIndex = 0; + messageType = nmtSwitchSetupRequest; + packedData.networkPlayerStatus = 0; + packedData.switchFlags = 0; + packedData.toSlotIndex = 0; + packedData.toTeam = 0; - return result; -} + unsigned char *buf = new unsigned char[sizeof(Data) * 3]; + result = pack(buf, getPackedMessageFormat(), + messageType, + packedData.selectedFactionName.getBuffer(), + packedData.currentSlotIndex, + packedData.toSlotIndex, + packedData.toTeam, + packedData.networkPlayerName.getBuffer(), + packedData.networkPlayerStatus, + packedData.switchFlags, + packedData.language.getBuffer()); + delete[] buf; + } + return result; + } + void SwitchSetupRequest::unpackMessage(unsigned char *buf) { + unpack(buf, getPackedMessageFormat(), + &messageType, + data.selectedFactionName.getBuffer(), + &data.currentSlotIndex, + &data.toSlotIndex, + &data.toTeam, + data.networkPlayerName.getBuffer(), + &data.networkPlayerStatus, + &data.switchFlags, + data.language.getBuffer()); + } -void SwitchSetupRequest::send(Socket* socket) { - assert(messageType == nmtSwitchSetupRequest); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] data.networkPlayerName [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,data.networkPlayerName.getString().c_str()); - toEndian(); - - if(useOldProtocol == true) { - //NetworkMessage::send(socket, &messageType, sizeof(messageType)); - NetworkMessage::send(socket, &data, sizeof(data), messageType); - } - else { - unsigned char *buf = packMessage(); - //printf("Send packet size = %u data.messageType = %d\n%s\nTeam = %d faction [%s] currentFactionIndex = %d toFactionIndex = %d\n",getPackedSize(),data.messageType,buf,data.toTeam,data.selectedFactionName.getBuffer(),data.currentFactionIndex,data.toFactionIndex); - NetworkMessage::send(socket, buf, getPackedSize()); - delete [] buf; - } -} - -void SwitchSetupRequest::toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); - data.currentSlotIndex = Shared::PlatformByteOrder::toCommonEndian(data.currentSlotIndex); - data.toSlotIndex = Shared::PlatformByteOrder::toCommonEndian(data.toSlotIndex); - data.toTeam = Shared::PlatformByteOrder::toCommonEndian(data.toTeam); - data.networkPlayerStatus = Shared::PlatformByteOrder::toCommonEndian(data.networkPlayerStatus); - data.switchFlags = Shared::PlatformByteOrder::toCommonEndian(data.switchFlags); - } -} -void SwitchSetupRequest::fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); - data.currentSlotIndex = Shared::PlatformByteOrder::fromCommonEndian(data.currentSlotIndex); - data.toSlotIndex = Shared::PlatformByteOrder::fromCommonEndian(data.toSlotIndex); - data.toTeam = Shared::PlatformByteOrder::fromCommonEndian(data.toTeam); - data.networkPlayerStatus = Shared::PlatformByteOrder::fromCommonEndian(data.networkPlayerStatus); - data.switchFlags = Shared::PlatformByteOrder::fromCommonEndian(data.switchFlags); - } -} - -// ===================================================== -// class PlayerIndexMessage -// ===================================================== -PlayerIndexMessage::PlayerIndexMessage(int16 playerIndex) { - messageType = nmtPlayerIndexMessage; - data.playerIndex=playerIndex; -} - -const char * PlayerIndexMessage::getPackedMessageFormat() const { - return "ch"; -} - -unsigned int PlayerIndexMessage::getPackedSize() { - static unsigned int result = 0; - if(result == 0) { - Data packedData; - messageType = 0; - packedData.playerIndex = 0; - unsigned char *buf = new unsigned char[sizeof(packedData)*3]; - result = pack(buf, getPackedMessageFormat(), + unsigned char * SwitchSetupRequest::packMessage() { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + pack(buf, getPackedMessageFormat(), messageType, - packedData.playerIndex); - delete [] buf; - } - return result; -} -void PlayerIndexMessage::unpackMessage(unsigned char *buf) { - unpack(buf, getPackedMessageFormat(), - &messageType, - &data.playerIndex); -} + data.selectedFactionName.getBuffer(), + data.currentSlotIndex, + data.toSlotIndex, + data.toTeam, + data.networkPlayerName.getBuffer(), + data.networkPlayerStatus, + data.switchFlags, + data.language.getBuffer()); + return buf; + } -unsigned char * PlayerIndexMessage::packMessage() { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - pack(buf, getPackedMessageFormat(), - messageType, - data.playerIndex); - return buf; -} + bool SwitchSetupRequest::receive(Socket* socket) { + bool result = false; + if (useOldProtocol == true) { -bool PlayerIndexMessage::receive(Socket* socket) { - bool result = false; - if(useOldProtocol == true) { - result = NetworkMessage::receive(socket, &data, sizeof(data), true); - if(result == true) { + result = NetworkMessage::receive(socket, &data, sizeof(data), true); + if (result == true) { + messageType = nmtSwitchSetupRequest; + } + + } else { + //fromEndian(); + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + result = NetworkMessage::receive(socket, buf, getPackedSize(), true); + unpackMessage(buf); + //printf("Got packet size = %u data.messageType = %d\n%s\nTeam = %d faction [%s] currentFactionIndex = %d toFactionIndex = %d\n",getPackedSize(),data.messageType,buf,data.toTeam,data.selectedFactionName.getBuffer(),data.currentFactionIndex,data.toFactionIndex); + delete[] buf; + } + fromEndian(); + + data.selectedFactionName.nullTerminate(); + data.networkPlayerName.nullTerminate(); + data.language.nullTerminate(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] data.networkPlayerName [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, data.networkPlayerName.getString().c_str()); + + return result; + } + + void SwitchSetupRequest::send(Socket* socket) { + assert(messageType == nmtSwitchSetupRequest); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] data.networkPlayerName [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, data.networkPlayerName.getString().c_str()); + toEndian(); + + if (useOldProtocol == true) { + //NetworkMessage::send(socket, &messageType, sizeof(messageType)); + NetworkMessage::send(socket, &data, sizeof(data), messageType); + } else { + unsigned char *buf = packMessage(); + //printf("Send packet size = %u data.messageType = %d\n%s\nTeam = %d faction [%s] currentFactionIndex = %d toFactionIndex = %d\n",getPackedSize(),data.messageType,buf,data.toTeam,data.selectedFactionName.getBuffer(),data.currentFactionIndex,data.toFactionIndex); + NetworkMessage::send(socket, buf, getPackedSize()); + delete[] buf; + } + } + + void SwitchSetupRequest::toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); + data.currentSlotIndex = Shared::PlatformByteOrder::toCommonEndian(data.currentSlotIndex); + data.toSlotIndex = Shared::PlatformByteOrder::toCommonEndian(data.toSlotIndex); + data.toTeam = Shared::PlatformByteOrder::toCommonEndian(data.toTeam); + data.networkPlayerStatus = Shared::PlatformByteOrder::toCommonEndian(data.networkPlayerStatus); + data.switchFlags = Shared::PlatformByteOrder::toCommonEndian(data.switchFlags); + } + } + void SwitchSetupRequest::fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); + data.currentSlotIndex = Shared::PlatformByteOrder::fromCommonEndian(data.currentSlotIndex); + data.toSlotIndex = Shared::PlatformByteOrder::fromCommonEndian(data.toSlotIndex); + data.toTeam = Shared::PlatformByteOrder::fromCommonEndian(data.toTeam); + data.networkPlayerStatus = Shared::PlatformByteOrder::fromCommonEndian(data.networkPlayerStatus); + data.switchFlags = Shared::PlatformByteOrder::fromCommonEndian(data.switchFlags); + } + } + + // ===================================================== + // class PlayerIndexMessage + // ===================================================== + PlayerIndexMessage::PlayerIndexMessage(int16 playerIndex) { messageType = nmtPlayerIndexMessage; + data.playerIndex = playerIndex; } - } - else { - //fromEndian(); - unsigned char *buf = new unsigned char[getPackedSize()+1]; - result = NetworkMessage::receive(socket, buf, getPackedSize(), true); - unpackMessage(buf); - //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); - delete [] buf; - } - fromEndian(); + const char * PlayerIndexMessage::getPackedMessageFormat() const { + return "ch"; + } - return result; -} + unsigned int PlayerIndexMessage::getPackedSize() { + static unsigned int result = 0; + if (result == 0) { + Data packedData; + messageType = 0; + packedData.playerIndex = 0; + unsigned char *buf = new unsigned char[sizeof(packedData) * 3]; + result = pack(buf, getPackedMessageFormat(), + messageType, + packedData.playerIndex); + delete[] buf; + } + return result; + } + void PlayerIndexMessage::unpackMessage(unsigned char *buf) { + unpack(buf, getPackedMessageFormat(), + &messageType, + &data.playerIndex); + } -void PlayerIndexMessage::send(Socket* socket) { - assert(messageType == nmtPlayerIndexMessage); - toEndian(); - - if(useOldProtocol == true) { - //NetworkMessage::send(socket, &messageType, sizeof(messageType)); - NetworkMessage::send(socket, &data, sizeof(data), messageType); - } - else { - unsigned char *buf = packMessage(); - //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); - //NetworkMessage::send(socket, &data, sizeof(data)); - NetworkMessage::send(socket, buf, getPackedSize()); - delete [] buf; - } -} - -void PlayerIndexMessage::toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); - data.playerIndex = Shared::PlatformByteOrder::toCommonEndian(data.playerIndex); - } -} -void PlayerIndexMessage::fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); - data.playerIndex = Shared::PlatformByteOrder::fromCommonEndian(data.playerIndex); - } -} - -// ===================================================== -// class NetworkMessageLoadingStatus -// ===================================================== -NetworkMessageLoadingStatus::NetworkMessageLoadingStatus(uint32 status) -{ - messageType = nmtLoadingStatusMessage; - data.status=status; -} - -const char * NetworkMessageLoadingStatus::getPackedMessageFormat() const { - return "cL"; -} - -unsigned int NetworkMessageLoadingStatus::getPackedSize() { - static unsigned int result = 0; - if(result == 0) { - Data packedData; - messageType = 0; - packedData.status = 0; - unsigned char *buf = new unsigned char[sizeof(packedData)*3]; - result = pack(buf, getPackedMessageFormat(), + unsigned char * PlayerIndexMessage::packMessage() { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + pack(buf, getPackedMessageFormat(), messageType, - packedData.status); - delete [] buf; - } - return result; -} -void NetworkMessageLoadingStatus::unpackMessage(unsigned char *buf) { - unpack(buf, getPackedMessageFormat(), - &messageType, - &data.status); -} + data.playerIndex); + return buf; + } -unsigned char * NetworkMessageLoadingStatus::packMessage() { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - pack(buf, getPackedMessageFormat(), - messageType, - data.status); - return buf; -} + bool PlayerIndexMessage::receive(Socket* socket) { + bool result = false; + if (useOldProtocol == true) { + result = NetworkMessage::receive(socket, &data, sizeof(data), true); + if (result == true) { + messageType = nmtPlayerIndexMessage; + } -bool NetworkMessageLoadingStatus::receive(Socket* socket) { - bool result = false; - if(useOldProtocol == true) { - result = NetworkMessage::receive(socket, &data, sizeof(data), true); - if(result == true) { + } else { + //fromEndian(); + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + result = NetworkMessage::receive(socket, buf, getPackedSize(), true); + unpackMessage(buf); + //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); + delete[] buf; + } + fromEndian(); + + return result; + } + + void PlayerIndexMessage::send(Socket* socket) { + assert(messageType == nmtPlayerIndexMessage); + toEndian(); + + if (useOldProtocol == true) { + //NetworkMessage::send(socket, &messageType, sizeof(messageType)); + NetworkMessage::send(socket, &data, sizeof(data), messageType); + } else { + unsigned char *buf = packMessage(); + //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); + //NetworkMessage::send(socket, &data, sizeof(data)); + NetworkMessage::send(socket, buf, getPackedSize()); + delete[] buf; + } + } + + void PlayerIndexMessage::toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); + data.playerIndex = Shared::PlatformByteOrder::toCommonEndian(data.playerIndex); + } + } + void PlayerIndexMessage::fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); + data.playerIndex = Shared::PlatformByteOrder::fromCommonEndian(data.playerIndex); + } + } + + // ===================================================== + // class NetworkMessageLoadingStatus + // ===================================================== + NetworkMessageLoadingStatus::NetworkMessageLoadingStatus(uint32 status) { messageType = nmtLoadingStatusMessage; + data.status = status; } - } - else { - //fromEndian(); - unsigned char *buf = new unsigned char[getPackedSize()+1]; - result = NetworkMessage::receive(socket, buf, getPackedSize(), true); - unpackMessage(buf); - //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); - delete [] buf; - } - fromEndian(); - return result; -} + const char * NetworkMessageLoadingStatus::getPackedMessageFormat() const { + return "cL"; + } -void NetworkMessageLoadingStatus::send(Socket* socket) { - assert(messageType == nmtLoadingStatusMessage); - toEndian(); + unsigned int NetworkMessageLoadingStatus::getPackedSize() { + static unsigned int result = 0; + if (result == 0) { + Data packedData; + messageType = 0; + packedData.status = 0; + unsigned char *buf = new unsigned char[sizeof(packedData) * 3]; + result = pack(buf, getPackedMessageFormat(), + messageType, + packedData.status); + delete[] buf; + } + return result; + } + void NetworkMessageLoadingStatus::unpackMessage(unsigned char *buf) { + unpack(buf, getPackedMessageFormat(), + &messageType, + &data.status); + } - if(useOldProtocol == true) { - //NetworkMessage::send(socket, &messageType, sizeof(messageType)); - NetworkMessage::send(socket, &data, sizeof(data), messageType); - } - else { - unsigned char *buf = packMessage(); - //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); - NetworkMessage::send(socket, buf, getPackedSize()); - delete [] buf; - } -} - -void NetworkMessageLoadingStatus::toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); - data.status = Shared::PlatformByteOrder::toCommonEndian(data.status); - } -} -void NetworkMessageLoadingStatus::fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); - data.status = Shared::PlatformByteOrder::fromCommonEndian(data.status); - } -} - -// ===================================================== -// class NetworkMessageMarkCell -// ===================================================== -NetworkMessageMarkCell::NetworkMessageMarkCell() { - messageType = nmtMarkCell; -} - -NetworkMessageMarkCell::NetworkMessageMarkCell(Vec2i target, int factionIndex, const string &text, int playerIndex) { - if((int)text.length() >= maxTextStringSize) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING / ERROR - text [%s] length = %d, max = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,text.c_str(),text.length(),maxTextStringSize); - } - - messageType = nmtMarkCell; - data.text = text; - data.targetX = target.x; - data.targetY = target.y; - data.factionIndex = factionIndex; - data.playerIndex = playerIndex; -} - -NetworkMessageMarkCell * NetworkMessageMarkCell::getCopy() const { - NetworkMessageMarkCell *copy = new NetworkMessageMarkCell(); - copy->data = this->data; - return copy; -} - -const char * NetworkMessageMarkCell::getPackedMessageFormat() const { - return "chhcc500s"; -} - -unsigned int NetworkMessageMarkCell::getPackedSize() { - static unsigned int result = 0; - if(result == 0) { - Data packedData; - packedData.factionIndex = 0; - messageType = nmtMarkCell; - packedData.playerIndex = 0; - packedData.targetX = 0; - packedData.targetY = 0; - - unsigned char *buf = new unsigned char[sizeof(packedData)*3]; - result = pack(buf, getPackedMessageFormat(), + unsigned char * NetworkMessageLoadingStatus::packMessage() { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + pack(buf, getPackedMessageFormat(), messageType, - packedData.targetX, - packedData.targetY, - packedData.factionIndex, - packedData.playerIndex, - packedData.text.getBuffer()); - delete [] buf; - } - return result; -} -void NetworkMessageMarkCell::unpackMessage(unsigned char *buf) { - unpack(buf, getPackedMessageFormat(), - &messageType, - &data.targetX, - &data.targetY, - &data.factionIndex, - &data.playerIndex, - data.text.getBuffer()); + data.status); + return buf; + } -} + bool NetworkMessageLoadingStatus::receive(Socket* socket) { + bool result = false; + if (useOldProtocol == true) { + result = NetworkMessage::receive(socket, &data, sizeof(data), true); + if (result == true) { + messageType = nmtLoadingStatusMessage; + } + } else { + //fromEndian(); + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + result = NetworkMessage::receive(socket, buf, getPackedSize(), true); + unpackMessage(buf); + //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); + delete[] buf; + } + fromEndian(); -unsigned char * NetworkMessageMarkCell::packMessage() { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - pack(buf, getPackedMessageFormat(), - messageType, - data.targetX, - data.targetY, - data.factionIndex, - data.playerIndex, - data.text.getBuffer()); + return result; + } - return buf; -} + void NetworkMessageLoadingStatus::send(Socket* socket) { + assert(messageType == nmtLoadingStatusMessage); + toEndian(); -bool NetworkMessageMarkCell::receive(Socket* socket){ - bool result = false; - if(useOldProtocol == true) { - result = NetworkMessage::receive(socket, &data, sizeof(data), true); - if(result == true) { + if (useOldProtocol == true) { + //NetworkMessage::send(socket, &messageType, sizeof(messageType)); + NetworkMessage::send(socket, &data, sizeof(data), messageType); + } else { + unsigned char *buf = packMessage(); + //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); + NetworkMessage::send(socket, buf, getPackedSize()); + delete[] buf; + } + } + + void NetworkMessageLoadingStatus::toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); + data.status = Shared::PlatformByteOrder::toCommonEndian(data.status); + } + } + void NetworkMessageLoadingStatus::fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); + data.status = Shared::PlatformByteOrder::fromCommonEndian(data.status); + } + } + + // ===================================================== + // class NetworkMessageMarkCell + // ===================================================== + NetworkMessageMarkCell::NetworkMessageMarkCell() { messageType = nmtMarkCell; } - } - else { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - result = NetworkMessage::receive(socket, buf, getPackedSize(), true); - unpackMessage(buf); - //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); - delete [] buf; - } - fromEndian(); - data.text.nullTerminate(); - return result; -} + NetworkMessageMarkCell::NetworkMessageMarkCell(Vec2i target, int factionIndex, const string &text, int playerIndex) { + if ((int) text.length() >= maxTextStringSize) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] WARNING / ERROR - text [%s] length = %d, max = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, text.c_str(), text.length(), maxTextStringSize); + } -void NetworkMessageMarkCell::send(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtMarkCell\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + messageType = nmtMarkCell; + data.text = text; + data.targetX = target.x; + data.targetY = target.y; + data.factionIndex = factionIndex; + data.playerIndex = playerIndex; + } - assert(messageType == nmtMarkCell); - toEndian(); + NetworkMessageMarkCell * NetworkMessageMarkCell::getCopy() const { + NetworkMessageMarkCell *copy = new NetworkMessageMarkCell(); + copy->data = this->data; + return copy; + } - if(useOldProtocol == true) { - //NetworkMessage::send(socket, &messageType, sizeof(messageType)); - NetworkMessage::send(socket, &data, sizeof(data), messageType); - } - else { - unsigned char *buf = packMessage(); - //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); - NetworkMessage::send(socket, buf, getPackedSize()); - delete [] buf; - } -} + const char * NetworkMessageMarkCell::getPackedMessageFormat() const { + return "chhcc500s"; + } -void NetworkMessageMarkCell::toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); - data.targetX = Shared::PlatformByteOrder::toCommonEndian(data.targetX); - data.targetY = Shared::PlatformByteOrder::toCommonEndian(data.targetY); - data.factionIndex = Shared::PlatformByteOrder::toCommonEndian(data.factionIndex); - data.playerIndex = Shared::PlatformByteOrder::toCommonEndian(data.playerIndex); - } -} -void NetworkMessageMarkCell::fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); - data.targetX = Shared::PlatformByteOrder::fromCommonEndian(data.targetX); - data.targetY = Shared::PlatformByteOrder::fromCommonEndian(data.targetY); - data.factionIndex = Shared::PlatformByteOrder::fromCommonEndian(data.factionIndex); - data.playerIndex = Shared::PlatformByteOrder::fromCommonEndian(data.playerIndex); - } -} + unsigned int NetworkMessageMarkCell::getPackedSize() { + static unsigned int result = 0; + if (result == 0) { + Data packedData; + packedData.factionIndex = 0; + messageType = nmtMarkCell; + packedData.playerIndex = 0; + packedData.targetX = 0; + packedData.targetY = 0; -// ===================================================== -// class NetworkMessageUnMarkCell -// ===================================================== + unsigned char *buf = new unsigned char[sizeof(packedData) * 3]; + result = pack(buf, getPackedMessageFormat(), + messageType, + packedData.targetX, + packedData.targetY, + packedData.factionIndex, + packedData.playerIndex, + packedData.text.getBuffer()); + delete[] buf; + } + return result; + } + void NetworkMessageMarkCell::unpackMessage(unsigned char *buf) { + unpack(buf, getPackedMessageFormat(), + &messageType, + &data.targetX, + &data.targetY, + &data.factionIndex, + &data.playerIndex, + data.text.getBuffer()); -NetworkMessageUnMarkCell::NetworkMessageUnMarkCell() { - messageType = nmtUnMarkCell; - data.targetX = 0; - data.targetY = 0; - data.factionIndex = 0; -} + } -NetworkMessageUnMarkCell::NetworkMessageUnMarkCell(Vec2i target, int factionIndex) { - messageType = nmtUnMarkCell; - data.targetX = target.x; - data.targetY = target.y; - data.factionIndex = factionIndex; -} - -NetworkMessageUnMarkCell * NetworkMessageUnMarkCell::getCopy() const { - NetworkMessageUnMarkCell *copy = new NetworkMessageUnMarkCell(); - copy->data = this->data; - return copy; -} - -const char * NetworkMessageUnMarkCell::getPackedMessageFormat() const { - return "chhc"; -} - -unsigned int NetworkMessageUnMarkCell::getPackedSize() { - static unsigned int result = 0; - if(result == 0) { - Data packedData; - packedData.factionIndex = 0; - messageType = 0; - packedData.targetX = 0; - packedData.targetY = 0; - unsigned char *buf = new unsigned char[sizeof(packedData)*3]; - result = pack(buf, getPackedMessageFormat(), + unsigned char * NetworkMessageMarkCell::packMessage() { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + pack(buf, getPackedMessageFormat(), messageType, - packedData.targetX, - packedData.targetY, - packedData.factionIndex); - delete [] buf; - } - return result; -} -void NetworkMessageUnMarkCell::unpackMessage(unsigned char *buf) { - unpack(buf, getPackedMessageFormat(), - &messageType, - &data.targetX, - &data.targetY, - &data.factionIndex); + data.targetX, + data.targetY, + data.factionIndex, + data.playerIndex, + data.text.getBuffer()); -} + return buf; + } -unsigned char * NetworkMessageUnMarkCell::packMessage() { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - pack(buf, getPackedMessageFormat(), - messageType, - data.targetX, - data.targetY, - data.factionIndex); + bool NetworkMessageMarkCell::receive(Socket* socket) { + bool result = false; + if (useOldProtocol == true) { + result = NetworkMessage::receive(socket, &data, sizeof(data), true); + if (result == true) { + messageType = nmtMarkCell; + } + } else { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + result = NetworkMessage::receive(socket, buf, getPackedSize(), true); + unpackMessage(buf); + //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); + delete[] buf; + } + fromEndian(); - return buf; -} + data.text.nullTerminate(); + return result; + } -bool NetworkMessageUnMarkCell::receive(Socket* socket){ - bool result = false; - if(useOldProtocol == true) { - result = NetworkMessage::receive(socket, &data, sizeof(data), true); - if(result == true) { + void NetworkMessageMarkCell::send(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] nmtMarkCell\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + assert(messageType == nmtMarkCell); + toEndian(); + + if (useOldProtocol == true) { + //NetworkMessage::send(socket, &messageType, sizeof(messageType)); + NetworkMessage::send(socket, &data, sizeof(data), messageType); + } else { + unsigned char *buf = packMessage(); + //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); + NetworkMessage::send(socket, buf, getPackedSize()); + delete[] buf; + } + } + + void NetworkMessageMarkCell::toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); + data.targetX = Shared::PlatformByteOrder::toCommonEndian(data.targetX); + data.targetY = Shared::PlatformByteOrder::toCommonEndian(data.targetY); + data.factionIndex = Shared::PlatformByteOrder::toCommonEndian(data.factionIndex); + data.playerIndex = Shared::PlatformByteOrder::toCommonEndian(data.playerIndex); + } + } + void NetworkMessageMarkCell::fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); + data.targetX = Shared::PlatformByteOrder::fromCommonEndian(data.targetX); + data.targetY = Shared::PlatformByteOrder::fromCommonEndian(data.targetY); + data.factionIndex = Shared::PlatformByteOrder::fromCommonEndian(data.factionIndex); + data.playerIndex = Shared::PlatformByteOrder::fromCommonEndian(data.playerIndex); + } + } + + // ===================================================== + // class NetworkMessageUnMarkCell + // ===================================================== + + NetworkMessageUnMarkCell::NetworkMessageUnMarkCell() { messageType = nmtUnMarkCell; + data.targetX = 0; + data.targetY = 0; + data.factionIndex = 0; } - } - else { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - result = NetworkMessage::receive(socket, buf, getPackedSize(), true); - unpackMessage(buf); - //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); - delete [] buf; - } - fromEndian(); - return result; -} + NetworkMessageUnMarkCell::NetworkMessageUnMarkCell(Vec2i target, int factionIndex) { + messageType = nmtUnMarkCell; + data.targetX = target.x; + data.targetY = target.y; + data.factionIndex = factionIndex; + } -void NetworkMessageUnMarkCell::send(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtUnMarkCell\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + NetworkMessageUnMarkCell * NetworkMessageUnMarkCell::getCopy() const { + NetworkMessageUnMarkCell *copy = new NetworkMessageUnMarkCell(); + copy->data = this->data; + return copy; + } - assert(messageType == nmtUnMarkCell); - toEndian(); + const char * NetworkMessageUnMarkCell::getPackedMessageFormat() const { + return "chhc"; + } - if(useOldProtocol == true) { - //NetworkMessage::send(socket, &messageType, sizeof(messageType)); - NetworkMessage::send(socket, &data, sizeof(data), messageType); - } - else { - unsigned char *buf = packMessage(); - //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); - NetworkMessage::send(socket, buf, getPackedSize()); - delete [] buf; - } -} + unsigned int NetworkMessageUnMarkCell::getPackedSize() { + static unsigned int result = 0; + if (result == 0) { + Data packedData; + packedData.factionIndex = 0; + messageType = 0; + packedData.targetX = 0; + packedData.targetY = 0; + unsigned char *buf = new unsigned char[sizeof(packedData) * 3]; + result = pack(buf, getPackedMessageFormat(), + messageType, + packedData.targetX, + packedData.targetY, + packedData.factionIndex); + delete[] buf; + } + return result; + } + void NetworkMessageUnMarkCell::unpackMessage(unsigned char *buf) { + unpack(buf, getPackedMessageFormat(), + &messageType, + &data.targetX, + &data.targetY, + &data.factionIndex); -void NetworkMessageUnMarkCell::toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); - data.targetX = Shared::PlatformByteOrder::toCommonEndian(data.targetX); - data.targetY = Shared::PlatformByteOrder::toCommonEndian(data.targetY); - data.factionIndex = Shared::PlatformByteOrder::toCommonEndian(data.factionIndex); - } -} -void NetworkMessageUnMarkCell::fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); - data.targetX = Shared::PlatformByteOrder::fromCommonEndian(data.targetX); - data.targetY = Shared::PlatformByteOrder::fromCommonEndian(data.targetY); - data.factionIndex = Shared::PlatformByteOrder::fromCommonEndian(data.factionIndex); - } -} + } -// ===================================================== -// class NetworkMessageHighlightCell -// ===================================================== - -NetworkMessageHighlightCell::NetworkMessageHighlightCell() { - messageType = nmtHighlightCell; - data.targetX = 0; - data.targetY = 0; - data.factionIndex = 0; -} - -NetworkMessageHighlightCell::NetworkMessageHighlightCell(Vec2i target, int factionIndex) { - messageType = nmtHighlightCell; - data.targetX = target.x; - data.targetY = target.y; - data.factionIndex = factionIndex; -} - -const char * NetworkMessageHighlightCell::getPackedMessageFormat() const { - return "chhc"; -} - -unsigned int NetworkMessageHighlightCell::getPackedSize() { - static unsigned int result = 0; - if(result == 0) { - Data packedData; - packedData.factionIndex = 0; - messageType = 0; - packedData.targetX = 0; - packedData.targetY = 0; - unsigned char *buf = new unsigned char[sizeof(packedData)*3]; - result = pack(buf, getPackedMessageFormat(), + unsigned char * NetworkMessageUnMarkCell::packMessage() { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + pack(buf, getPackedMessageFormat(), messageType, - packedData.targetX, - packedData.targetY, - packedData.factionIndex); - delete [] buf; - } - return result; -} -void NetworkMessageHighlightCell::unpackMessage(unsigned char *buf) { - unpack(buf, getPackedMessageFormat(), - &messageType, - &data.targetX, - &data.targetY, - &data.factionIndex); + data.targetX, + data.targetY, + data.factionIndex); -} - -unsigned char * NetworkMessageHighlightCell::packMessage() { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - pack(buf, getPackedMessageFormat(), - messageType, - data.targetX, - data.targetY, - data.factionIndex); - - return buf; -} - -bool NetworkMessageHighlightCell::receive(Socket* socket) { - bool result = false; - if(useOldProtocol == true) { - result = NetworkMessage::receive(socket, &data, sizeof(data), true); - if(result == true) { - messageType = nmtHighlightCell; + return buf; } - } - else { - unsigned char *buf = new unsigned char[getPackedSize()+1]; - result = NetworkMessage::receive(socket, buf, getPackedSize(), true); - unpackMessage(buf); - //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); - delete [] buf; - } - fromEndian(); - return result; -} -void NetworkMessageHighlightCell::send(Socket* socket) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] nmtMarkCell\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + bool NetworkMessageUnMarkCell::receive(Socket* socket) { + bool result = false; + if (useOldProtocol == true) { + result = NetworkMessage::receive(socket, &data, sizeof(data), true); + if (result == true) { + messageType = nmtUnMarkCell; + } + } else { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + result = NetworkMessage::receive(socket, buf, getPackedSize(), true); + unpackMessage(buf); + //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); + delete[] buf; + } + fromEndian(); - assert(messageType == nmtHighlightCell); - toEndian(); + return result; + } - if(useOldProtocol == true) { - //NetworkMessage::send(socket, &messageType, sizeof(messageType)); - NetworkMessage::send(socket, &data, sizeof(data), messageType); - } - else { - unsigned char *buf = packMessage(); - //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); - NetworkMessage::send(socket, buf, getPackedSize()); - delete [] buf; - } -} + void NetworkMessageUnMarkCell::send(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] nmtUnMarkCell\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); -void NetworkMessageHighlightCell::toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); - data.targetX = Shared::PlatformByteOrder::toCommonEndian(data.targetX); - data.targetY = Shared::PlatformByteOrder::toCommonEndian(data.targetY); - data.factionIndex = Shared::PlatformByteOrder::toCommonEndian(data.factionIndex); - } -} -void NetworkMessageHighlightCell::fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); - data.targetX = Shared::PlatformByteOrder::fromCommonEndian(data.targetX); - data.targetY = Shared::PlatformByteOrder::fromCommonEndian(data.targetY); - data.factionIndex = Shared::PlatformByteOrder::fromCommonEndian(data.factionIndex); - } -} + assert(messageType == nmtUnMarkCell); + toEndian(); -}}//end namespace + if (useOldProtocol == true) { + //NetworkMessage::send(socket, &messageType, sizeof(messageType)); + NetworkMessage::send(socket, &data, sizeof(data), messageType); + } else { + unsigned char *buf = packMessage(); + //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); + NetworkMessage::send(socket, buf, getPackedSize()); + delete[] buf; + } + } + + void NetworkMessageUnMarkCell::toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); + data.targetX = Shared::PlatformByteOrder::toCommonEndian(data.targetX); + data.targetY = Shared::PlatformByteOrder::toCommonEndian(data.targetY); + data.factionIndex = Shared::PlatformByteOrder::toCommonEndian(data.factionIndex); + } + } + void NetworkMessageUnMarkCell::fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); + data.targetX = Shared::PlatformByteOrder::fromCommonEndian(data.targetX); + data.targetY = Shared::PlatformByteOrder::fromCommonEndian(data.targetY); + data.factionIndex = Shared::PlatformByteOrder::fromCommonEndian(data.factionIndex); + } + } + + // ===================================================== + // class NetworkMessageHighlightCell + // ===================================================== + + NetworkMessageHighlightCell::NetworkMessageHighlightCell() { + messageType = nmtHighlightCell; + data.targetX = 0; + data.targetY = 0; + data.factionIndex = 0; + } + + NetworkMessageHighlightCell::NetworkMessageHighlightCell(Vec2i target, int factionIndex) { + messageType = nmtHighlightCell; + data.targetX = target.x; + data.targetY = target.y; + data.factionIndex = factionIndex; + } + + const char * NetworkMessageHighlightCell::getPackedMessageFormat() const { + return "chhc"; + } + + unsigned int NetworkMessageHighlightCell::getPackedSize() { + static unsigned int result = 0; + if (result == 0) { + Data packedData; + packedData.factionIndex = 0; + messageType = 0; + packedData.targetX = 0; + packedData.targetY = 0; + unsigned char *buf = new unsigned char[sizeof(packedData) * 3]; + result = pack(buf, getPackedMessageFormat(), + messageType, + packedData.targetX, + packedData.targetY, + packedData.factionIndex); + delete[] buf; + } + return result; + } + void NetworkMessageHighlightCell::unpackMessage(unsigned char *buf) { + unpack(buf, getPackedMessageFormat(), + &messageType, + &data.targetX, + &data.targetY, + &data.factionIndex); + + } + + unsigned char * NetworkMessageHighlightCell::packMessage() { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + pack(buf, getPackedMessageFormat(), + messageType, + data.targetX, + data.targetY, + data.factionIndex); + + return buf; + } + + bool NetworkMessageHighlightCell::receive(Socket* socket) { + bool result = false; + if (useOldProtocol == true) { + result = NetworkMessage::receive(socket, &data, sizeof(data), true); + if (result == true) { + messageType = nmtHighlightCell; + } + } else { + unsigned char *buf = new unsigned char[getPackedSize() + 1]; + result = NetworkMessage::receive(socket, buf, getPackedSize(), true); + unpackMessage(buf); + //printf("Got packet size = %u data.messageType = %d\n%s\n",getPackedSize(),data.messageType,buf); + delete[] buf; + } + fromEndian(); + return result; + } + + void NetworkMessageHighlightCell::send(Socket* socket) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] nmtMarkCell\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + assert(messageType == nmtHighlightCell); + toEndian(); + + if (useOldProtocol == true) { + //NetworkMessage::send(socket, &messageType, sizeof(messageType)); + NetworkMessage::send(socket, &data, sizeof(data), messageType); + } else { + unsigned char *buf = packMessage(); + //printf("Send packet size = %u data.messageType = %d\n[%s]\n",getPackedSize(),data.messageType,buf); + NetworkMessage::send(socket, buf, getPackedSize()); + delete[] buf; + } + } + + void NetworkMessageHighlightCell::toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::toCommonEndian(messageType); + data.targetX = Shared::PlatformByteOrder::toCommonEndian(data.targetX); + data.targetY = Shared::PlatformByteOrder::toCommonEndian(data.targetY); + data.factionIndex = Shared::PlatformByteOrder::toCommonEndian(data.factionIndex); + } + } + void NetworkMessageHighlightCell::fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + messageType = Shared::PlatformByteOrder::fromCommonEndian(messageType); + data.targetX = Shared::PlatformByteOrder::fromCommonEndian(data.targetX); + data.targetY = Shared::PlatformByteOrder::fromCommonEndian(data.targetY); + data.factionIndex = Shared::PlatformByteOrder::fromCommonEndian(data.factionIndex); + } + } + + } +}//end namespace diff --git a/source/glest_game/network/network_message.h b/source/glest_game/network/network_message.h index fda5c29b3..f203a5311 100644 --- a/source/glest_game/network/network_message.h +++ b/source/glest_game/network/network_message.h @@ -36,1196 +36,1400 @@ using Shared::Platform::int8; using Shared::Platform::uint8; using Shared::Platform::int16; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -class GameSettings; + class GameSettings; -enum NetworkMessageType { - nmtInvalid, - nmtIntro, - nmtPing, - nmtReady, - nmtLaunch, - nmtCommandList, - nmtText, - nmtQuit, - nmtSynchNetworkGameData, - nmtSynchNetworkGameDataStatus, - nmtSynchNetworkGameDataFileCRCCheck, - nmtSynchNetworkGameDataFileGet, - nmtBroadCastSetup, - nmtSwitchSetupRequest, - nmtPlayerIndexMessage, - nmtLoadingStatusMessage, - nmtMarkCell, - nmtUnMarkCell, - nmtHighlightCell, -// nmtCompressedPacket, + enum NetworkMessageType { + nmtInvalid, + nmtIntro, + nmtPing, + nmtReady, + nmtLaunch, + nmtCommandList, + nmtText, + nmtQuit, + nmtSynchNetworkGameData, + nmtSynchNetworkGameDataStatus, + nmtSynchNetworkGameDataFileCRCCheck, + nmtSynchNetworkGameDataFileGet, + nmtBroadCastSetup, + nmtSwitchSetupRequest, + nmtPlayerIndexMessage, + nmtLoadingStatusMessage, + nmtMarkCell, + nmtUnMarkCell, + nmtHighlightCell, + // nmtCompressedPacket, - nmtCount -}; + nmtCount + }; -enum NetworkGameStateType { - nmgstInvalid, - nmgstOk, - nmgstNoSlots, + enum NetworkGameStateType { + nmgstInvalid, + nmgstOk, + nmgstNoSlots, - nmgstCount -}; + nmgstCount + }; -static const int maxLanguageStringSize= 60; -static const int maxNetworkMessageSize= 20000; + static const int maxLanguageStringSize = 60; + static const int maxNetworkMessageSize = 20000; -// ===================================================== -// class NetworkMessage -// ===================================================== + // ===================================================== + // class NetworkMessage + // ===================================================== -enum NetworkMessageStatisticType { - netmsgstPacketsPerMillisecondSend, - netmsgstPacketsPerMillisecondSend_current_count, - netmsgstPacketsPerMillisecondSend_last, + enum NetworkMessageStatisticType { + netmsgstPacketsPerMillisecondSend, + netmsgstPacketsPerMillisecondSend_current_count, + netmsgstPacketsPerMillisecondSend_last, - netmsgstPacketsPerSecondSend, - netmsgstPacketsPerSecondSend_current_count, - netmsgstPacketsPerSecondSend_last, + netmsgstPacketsPerSecondSend, + netmsgstPacketsPerSecondSend_current_count, + netmsgstPacketsPerSecondSend_last, - netmsgstAverageSendSize, + netmsgstAverageSendSize, - // --------------------------------------------- - netmsgstPacketsPerMillisecondRecv, - netmsgstPacketsPerMillisecondRecv_current_count, - netmsgstPacketsPerMillisecondRecv_last, + // --------------------------------------------- + netmsgstPacketsPerMillisecondRecv, + netmsgstPacketsPerMillisecondRecv_current_count, + netmsgstPacketsPerMillisecondRecv_last, - netmsgstPacketsPerSecondRecv, - netmsgstPacketsPerSecondRecv_current_count, - netmsgstPacketsPerSecondRecv_last, + netmsgstPacketsPerSecondRecv, + netmsgstPacketsPerSecondRecv_current_count, + netmsgstPacketsPerSecondRecv_last, - netmsgstAverageRecvSize, + netmsgstAverageRecvSize, - netmsgstLastEvent + netmsgstLastEvent -}; + }; -class NetworkMessage { -private: + class NetworkMessage { + private: - static auto_ptr mutexMessageStats; - static Chrono statsTimer; - static Chrono lastSend; - static Chrono lastRecv; - static std::map mapMessageStats; + static auto_ptr mutexMessageStats; + static Chrono statsTimer; + static Chrono lastSend; + static Chrono lastRecv; + static std::map mapMessageStats; -public: - static void resetNetworkPacketStats(); - static string getNetworkPacketStats(); + public: + static void resetNetworkPacketStats(); + static string getNetworkPacketStats(); - static bool useOldProtocol; - virtual ~NetworkMessage(){} - virtual bool receive(Socket* socket)= 0; - virtual bool receive(Socket* socket, NetworkMessageType type) { return receive(socket); }; + static bool useOldProtocol; + virtual ~NetworkMessage() { + } + virtual bool receive(Socket* socket) = 0; + virtual bool receive(Socket* socket, NetworkMessageType type) { + return receive(socket); + }; - virtual void send(Socket* socket) = 0; - virtual size_t getDataSize() const = 0; - virtual unsigned char * getData() { return NULL; } + virtual void send(Socket* socket) = 0; + virtual size_t getDataSize() const = 0; + virtual unsigned char * getData() { + return NULL; + } - virtual NetworkMessageType getNetworkMessageType() const = 0; + virtual NetworkMessageType getNetworkMessageType() const = 0; - void dump_packet(string label, const void* data, int dataSize, bool isSend); + void dump_packet(string label, const void* data, int dataSize, bool isSend); -protected: - //bool peek(Socket* socket, void* data, int dataSize); - bool receive(Socket* socket, void* data, int dataSize,bool tryReceiveUntilDataSizeMet); - void send(Socket* socket, const void* data, int dataSize); - void send(Socket* socket, const void* data, int dataSize, int8 messageType); - void send(Socket* socket, const void* data, int dataSize, int8 messageType, uint32 compressedLength); + protected: + //bool peek(Socket* socket, void* data, int dataSize); + bool receive(Socket* socket, void* data, int dataSize, bool tryReceiveUntilDataSizeMet); + void send(Socket* socket, const void* data, int dataSize); + void send(Socket* socket, const void* data, int dataSize, int8 messageType); + void send(Socket* socket, const void* data, int dataSize, int8 messageType, uint32 compressedLength); - virtual const char * getPackedMessageFormat() const = 0; - virtual unsigned int getPackedSize() = 0; - virtual void unpackMessage(unsigned char *buf) = 0; - virtual unsigned char * packMessage() = 0; -}; + virtual const char * getPackedMessageFormat() const = 0; + virtual unsigned int getPackedSize() = 0; + virtual void unpackMessage(unsigned char *buf) = 0; + virtual unsigned char * packMessage() = 0; + }; -// ===================================================== -// class NetworkMessageIntro -// -// Message sent from the server to the client -// when the client connects and vice versa -// ===================================================== + // ===================================================== + // class NetworkMessageIntro + // + // Message sent from the server to the client + // when the client connects and vice versa + // ===================================================== #pragma pack(push, 1) -class NetworkMessageIntro: public NetworkMessage{ -private: - static const int maxVersionStringSize= 128; - static const int maxNameSize= 32; - static const int maxSmallStringSize= 60; + class NetworkMessageIntro : public NetworkMessage { + private: + static const int maxVersionStringSize = 128; + static const int maxNameSize = 32; + static const int maxSmallStringSize = 60; -private: - int8 messageType; - struct Data { - int32 sessionId; - NetworkString versionString; - NetworkString name; - int16 playerIndex; - int8 gameState; - uint32 externalIp; - uint32 ftpPort; - NetworkString language; - int8 gameInProgress; - NetworkString playerUUID; - NetworkString platform; - }; + private: + int8 messageType; + struct Data { + int32 sessionId; + NetworkString versionString; + NetworkString name; + int16 playerIndex; + int8 gameState; + uint32 externalIp; + uint32 ftpPort; + NetworkString language; + int8 gameInProgress; + NetworkString playerUUID; + NetworkString platform; + }; - void toEndian(); - void fromEndian(); + void toEndian(); + void fromEndian(); -private: - Data data; + private: + Data data; -protected: + protected: -public: - NetworkMessageIntro(); - NetworkMessageIntro(int32 sessionId, const string &versionString, - const string &name, int playerIndex, NetworkGameStateType gameState, - uint32 externalIp, uint32 ftpPort, const string &playerLanguage, - int gameInProgress, const string &playerUUID, const string &platform); + public: + NetworkMessageIntro(); + NetworkMessageIntro(int32 sessionId, const string &versionString, + const string &name, int playerIndex, NetworkGameStateType gameState, + uint32 externalIp, uint32 ftpPort, const string &playerLanguage, + int gameInProgress, const string &playerUUID, const string &platform); - virtual const char * getPackedMessageFormat() const; - virtual unsigned int getPackedSize(); - virtual void unpackMessage(unsigned char *buf); - virtual unsigned char * packMessage(); + virtual const char * getPackedMessageFormat() const; + virtual unsigned int getPackedSize(); + virtual void unpackMessage(unsigned char *buf); + virtual unsigned char * packMessage(); - virtual size_t getDataSize() const { return sizeof(Data); } + virtual size_t getDataSize() const { + return sizeof(Data); + } - virtual NetworkMessageType getNetworkMessageType() const { - return nmtIntro; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtIntro; + } - int32 getSessionId() const { return data.sessionId;} - string getVersionString() const { return data.versionString.getString(); } - string getName() const { return data.name.getString(); } - int getPlayerIndex() const { return data.playerIndex; } - NetworkGameStateType getGameState() const { return static_cast(data.gameState); } - uint32 getExternalIp() const { return data.externalIp;} - uint32 getFtpPort() const { return data.ftpPort; } - string getPlayerLanguage() const { return data.language.getString(); } - uint8 getGameInProgress() const { return data.gameInProgress; } + int32 getSessionId() const { + return data.sessionId; + } + string getVersionString() const { + return data.versionString.getString(); + } + string getName() const { + return data.name.getString(); + } + int getPlayerIndex() const { + return data.playerIndex; + } + NetworkGameStateType getGameState() const { + return static_cast(data.gameState); + } + uint32 getExternalIp() const { + return data.externalIp; + } + uint32 getFtpPort() const { + return data.ftpPort; + } + string getPlayerLanguage() const { + return data.language.getString(); + } + uint8 getGameInProgress() const { + return data.gameInProgress; + } - string getPlayerUUID() const { return data.playerUUID.getString();} - string getPlayerPlatform() const { return data.platform.getString();} + string getPlayerUUID() const { + return data.playerUUID.getString(); + } + string getPlayerPlatform() const { + return data.platform.getString(); + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); - string toString() const; -}; + string toString() const; + }; #pragma pack(pop) -// ===================================================== -// class NetworkMessagePing -// -// Message sent at any time -// ===================================================== + // ===================================================== + // class NetworkMessagePing + // + // Message sent at any time + // ===================================================== #pragma pack(push, 1) -class NetworkMessagePing: public NetworkMessage{ -private: - int8 messageType; - struct Data{ - int32 pingFrequency; - int64 pingTime; - }; - void toEndian(); - void fromEndian(); + class NetworkMessagePing : public NetworkMessage { + private: + int8 messageType; + struct Data { + int32 pingFrequency; + int64 pingTime; + }; + void toEndian(); + void fromEndian(); -private: - Data data; - int64 pingReceivedLocalTime; + private: + Data data; + int64 pingReceivedLocalTime; -protected: - virtual const char * getPackedMessageFormat() const; - virtual unsigned int getPackedSize(); - virtual void unpackMessage(unsigned char *buf); - virtual unsigned char * packMessage(); + protected: + virtual const char * getPackedMessageFormat() const; + virtual unsigned int getPackedSize(); + virtual void unpackMessage(unsigned char *buf); + virtual unsigned char * packMessage(); -public: - NetworkMessagePing(); - NetworkMessagePing(int32 pingFrequency, int64 pingTime); + public: + NetworkMessagePing(); + NetworkMessagePing(int32 pingFrequency, int64 pingTime); - virtual size_t getDataSize() const { return sizeof(Data); } + virtual size_t getDataSize() const { + return sizeof(Data); + } - virtual NetworkMessageType getNetworkMessageType() const { - return nmtPing; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtPing; + } - int32 getPingFrequency() const {return data.pingFrequency;} - int64 getPingTime() const {return data.pingTime;} - int64 getPingReceivedLocalTime() const { return pingReceivedLocalTime; } - void setPingReceivedLocalTime(int64 pingTime) { pingReceivedLocalTime = pingTime; } + int32 getPingFrequency() const { + return data.pingFrequency; + } + int64 getPingTime() const { + return data.pingTime; + } + int64 getPingReceivedLocalTime() const { + return pingReceivedLocalTime; + } + void setPingReceivedLocalTime(int64 pingTime) { + pingReceivedLocalTime = pingTime; + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); -}; + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); + }; #pragma pack(pop) -// ===================================================== -// class NetworkMessageReady -// -// Message sent at the beginning of the game -// ===================================================== + // ===================================================== + // class NetworkMessageReady + // + // Message sent at the beginning of the game + // ===================================================== #pragma pack(push, 1) -class NetworkMessageReady: public NetworkMessage{ -private: - int8 messageType; - struct Data{ - uint32 checksum; - }; - void toEndian(); - void fromEndian(); + class NetworkMessageReady : public NetworkMessage { + private: + int8 messageType; + struct Data { + uint32 checksum; + }; + void toEndian(); + void fromEndian(); -private: - Data data; + private: + Data data; -protected: - virtual const char * getPackedMessageFormat() const; - virtual unsigned int getPackedSize(); - virtual void unpackMessage(unsigned char *buf); - virtual unsigned char * packMessage(); + protected: + virtual const char * getPackedMessageFormat() const; + virtual unsigned int getPackedSize(); + virtual void unpackMessage(unsigned char *buf); + virtual unsigned char * packMessage(); -public: - NetworkMessageReady(); - explicit NetworkMessageReady(uint32 checksum); + public: + NetworkMessageReady(); + explicit NetworkMessageReady(uint32 checksum); - virtual size_t getDataSize() const { return sizeof(Data); } + virtual size_t getDataSize() const { + return sizeof(Data); + } - virtual NetworkMessageType getNetworkMessageType() const { - return nmtReady; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtReady; + } - uint32 getChecksum() const {return data.checksum;} + uint32 getChecksum() const { + return data.checksum; + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); -}; + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); + }; #pragma pack(pop) -// ===================================================== -// class NetworkMessageLaunch -// -// Message sent from the server to the client -// to launch the game -// ===================================================== + // ===================================================== + // class NetworkMessageLaunch + // + // Message sent from the server to the client + // to launch the game + // ===================================================== #pragma pack(push, 1) -class NetworkMessageLaunch: public NetworkMessage { -private: - static const int maxStringSize= 256; - static const int maxSmallStringSize= 60; - static const int maxFactionCRCCount= 20; + class NetworkMessageLaunch : public NetworkMessage { + private: + static const int maxStringSize = 256; + static const int maxSmallStringSize = 60; + static const int maxFactionCRCCount = 20; -private: + private: - int8 messageType; - uint32 compressedLength; - struct Data { - NetworkString description; - NetworkString map; - NetworkString tileset; - NetworkString tech; - NetworkString factionTypeNames[GameConstants::maxPlayers]; //faction names - NetworkString networkPlayerNames[GameConstants::maxPlayers]; //networkPlayerNames - NetworkString networkPlayerPlatform[GameConstants::maxPlayers]; - int32 networkPlayerStatuses[GameConstants::maxPlayers]; //networkPlayerStatuses - NetworkString networkPlayerLanguages[GameConstants::maxPlayers]; + int8 messageType; + uint32 compressedLength; + struct Data { + NetworkString description; + NetworkString map; + NetworkString tileset; + NetworkString tech; + NetworkString factionTypeNames[GameConstants::maxPlayers]; //faction names + NetworkString networkPlayerNames[GameConstants::maxPlayers]; //networkPlayerNames + NetworkString networkPlayerPlatform[GameConstants::maxPlayers]; + int32 networkPlayerStatuses[GameConstants::maxPlayers]; //networkPlayerStatuses + NetworkString networkPlayerLanguages[GameConstants::maxPlayers]; - uint32 mapCRC; - int8 mapFilter; - uint32 tilesetCRC; - uint32 techCRC; - NetworkString factionNameList[maxFactionCRCCount]; - uint32 factionCRCList[maxFactionCRCCount]; + uint32 mapCRC; + int8 mapFilter; + uint32 tilesetCRC; + uint32 techCRC; + NetworkString factionNameList[maxFactionCRCCount]; + uint32 factionCRCList[maxFactionCRCCount]; - int8 factionControls[GameConstants::maxPlayers]; - int8 resourceMultiplierIndex[GameConstants::maxPlayers]; + int8 factionControls[GameConstants::maxPlayers]; + int8 resourceMultiplierIndex[GameConstants::maxPlayers]; - int8 thisFactionIndex; - int8 factionCount; - int8 teams[GameConstants::maxPlayers]; - int8 startLocationIndex[GameConstants::maxPlayers]; + int8 thisFactionIndex; + int8 factionCount; + int8 teams[GameConstants::maxPlayers]; + int8 startLocationIndex[GameConstants::maxPlayers]; - int8 defaultResources; - int8 defaultUnits; - int8 defaultVictoryConditions; - int8 fogOfWar; - int8 allowObservers; - int8 enableObserverModeAtEndGame; - int8 enableServerControlledAI; - uint8 networkFramePeriod; // allowed values 0 - 255 - int8 networkPauseGameForLaggedClients; - int8 pathFinderType; - uint32 flagTypes1; + int8 defaultResources; + int8 defaultUnits; + int8 defaultVictoryConditions; + int8 fogOfWar; + int8 allowObservers; + int8 enableObserverModeAtEndGame; + int8 enableServerControlledAI; + uint8 networkFramePeriod; // allowed values 0 - 255 + int8 networkPauseGameForLaggedClients; + int8 pathFinderType; + uint32 flagTypes1; - int8 aiAcceptSwitchTeamPercentChance; - int8 cpuReplacementMultiplier; - int32 masterserver_admin; - int32 masterserver_admin_factionIndex; + int8 aiAcceptSwitchTeamPercentChance; + int8 cpuReplacementMultiplier; + int32 masterserver_admin; + int32 masterserver_admin_factionIndex; - NetworkString scenario; + NetworkString scenario; - NetworkString networkPlayerUUID[GameConstants::maxPlayers]; + NetworkString networkPlayerUUID[GameConstants::maxPlayers]; - int8 networkAllowNativeLanguageTechtree; - NetworkString gameUUID; - }; - void toEndian(); - void fromEndian(); - std::pair getCompressedMessage(); -private: - Data data; + int8 networkAllowNativeLanguageTechtree; + NetworkString gameUUID; + }; + void toEndian(); + void fromEndian(); + std::pair getCompressedMessage(); + private: + Data data; -protected: - virtual const char * getPackedMessageFormat() const; - virtual unsigned int getPackedSize(); - virtual void unpackMessage(unsigned char *buf); - virtual unsigned char * packMessage(); + protected: + virtual const char * getPackedMessageFormat() const; + virtual unsigned int getPackedSize(); + virtual void unpackMessage(unsigned char *buf); + virtual unsigned char * packMessage(); -public: - NetworkMessageLaunch(); - NetworkMessageLaunch(const GameSettings *gameSettings,int8 messageType); + public: + NetworkMessageLaunch(); + NetworkMessageLaunch(const GameSettings *gameSettings, int8 messageType); - virtual size_t getDataSize() const { return sizeof(Data); } - virtual unsigned char * getData(); + virtual size_t getDataSize() const { + return sizeof(Data); + } + virtual unsigned char * getData(); - virtual NetworkMessageType getNetworkMessageType() const { - return nmtLaunch; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtLaunch; + } - void buildGameSettings(GameSettings *gameSettings) const; - int getMessageType() const { return messageType; } + void buildGameSettings(GameSettings *gameSettings) const; + int getMessageType() const { + return messageType; + } - int getMapCRC() const { return data.mapCRC; } - int getTilesetCRC() const { return data.tilesetCRC; } - int getTechCRC() const { return data.techCRC; } - vector > getFactionCRCList() const; + int getMapCRC() const { + return data.mapCRC; + } + int getTilesetCRC() const { + return data.tilesetCRC; + } + int getTechCRC() const { + return data.techCRC; + } + vector > getFactionCRCList() const; - virtual bool receive(Socket* socket); - virtual bool receive(Socket* socket, NetworkMessageType type); + virtual bool receive(Socket* socket); + virtual bool receive(Socket* socket, NetworkMessageType type); - virtual void send(Socket* socket); -}; + virtual void send(Socket* socket); + }; #pragma pack(pop) -// ===================================================== -// class CommandList -// -// Message to order a commands to several units -// ===================================================== + // ===================================================== + // class CommandList + // + // Message to order a commands to several units + // ===================================================== #pragma pack(push, 1) -class NetworkMessageCommandList: public NetworkMessage { + class NetworkMessageCommandList : public NetworkMessage { -private: + private: - struct DataHeader { + struct DataHeader { - uint16 commandCount; - int32 frameCount; - uint32 networkPlayerFactionCRC[GameConstants::maxPlayers]; - }; + uint16 commandCount; + int32 frameCount; + uint32 networkPlayerFactionCRC[GameConstants::maxPlayers]; + }; - static const int32 commandListHeaderSize = sizeof(DataHeader); + static const int32 commandListHeaderSize = sizeof(DataHeader); - struct Data { - int8 messageType; - DataHeader header; - std::vector commands; - }; - void init(Data &data_ref) { - data_ref.messageType = 0; - data_ref.header.commandCount = 0; - data_ref.header.frameCount = 0; - for(int index = 0; index < GameConstants::maxPlayers; ++index) { - data_ref.header.networkPlayerFactionCRC[index] = 0; - } - } - void toEndianHeader(); - void fromEndianHeader(); - void toEndianDetail(uint16 totalCommand); - void fromEndianDetail(); + struct Data { + int8 messageType; + DataHeader header; + std::vector commands; + }; + void init(Data &data_ref) { + data_ref.messageType = 0; + data_ref.header.commandCount = 0; + data_ref.header.frameCount = 0; + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + data_ref.header.networkPlayerFactionCRC[index] = 0; + } + } + void toEndianHeader(); + void fromEndianHeader(); + void toEndianDetail(uint16 totalCommand); + void fromEndianDetail(); -private: - Data data; + private: + Data data; -protected: - virtual const char * getPackedMessageFormat() const { return NULL; } - virtual unsigned int getPackedSize() { return 0; } - virtual void unpackMessage(unsigned char *buf) { }; - virtual unsigned char * packMessage() { return NULL; } + protected: + virtual const char * getPackedMessageFormat() const { + return NULL; + } + virtual unsigned int getPackedSize() { + return 0; + } + virtual void unpackMessage(unsigned char *buf) { + }; + virtual unsigned char * packMessage() { + return NULL; + } - const char * getPackedMessageFormatHeader() const; - unsigned int getPackedSizeHeader(); - void unpackMessageHeader(unsigned char *buf); - unsigned char * packMessageHeader(); + const char * getPackedMessageFormatHeader() const; + unsigned int getPackedSizeHeader(); + void unpackMessageHeader(unsigned char *buf); + unsigned char * packMessageHeader(); - const char * getPackedMessageFormatDetail() const; - unsigned int getPackedSizeDetail(int count); - void unpackMessageDetail(unsigned char *buf,int count); - unsigned char * packMessageDetail(uint16 totalCommand); + const char * getPackedMessageFormatDetail() const; + unsigned int getPackedSizeDetail(int count); + void unpackMessageDetail(unsigned char *buf, int count); + unsigned char * packMessageDetail(uint16 totalCommand); -public: - explicit NetworkMessageCommandList(int32 frameCount= -1); + public: + explicit NetworkMessageCommandList(int32 frameCount = -1); - virtual size_t getDataSize() const { return sizeof(Data); } - virtual unsigned char * getData(); + virtual size_t getDataSize() const { + return sizeof(Data); + } + virtual unsigned char * getData(); - virtual NetworkMessageType getNetworkMessageType() const { - return nmtCommandList; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtCommandList; + } - bool addCommand(const NetworkCommand* networkCommand); + bool addCommand(const NetworkCommand* networkCommand); - void clear() {data.header.commandCount= 0;} - int getCommandCount() const {return data.header.commandCount;} - int getFrameCount() const {return data.header.frameCount;} - uint32 getNetworkPlayerFactionCRC(int index) const {return data.header.networkPlayerFactionCRC[index];} - void setNetworkPlayerFactionCRC(int index, uint32 crc) { data.header.networkPlayerFactionCRC[index]=crc;} + void clear() { + data.header.commandCount = 0; + } + int getCommandCount() const { + return data.header.commandCount; + } + int getFrameCount() const { + return data.header.frameCount; + } + uint32 getNetworkPlayerFactionCRC(int index) const { + return data.header.networkPlayerFactionCRC[index]; + } + void setNetworkPlayerFactionCRC(int index, uint32 crc) { + data.header.networkPlayerFactionCRC[index] = crc; + } - const NetworkCommand* getCommand(int i) const {return &data.commands[i];} + const NetworkCommand* getCommand(int i) const { + return &data.commands[i]; + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); -}; + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); + }; #pragma pack(pop) -// ===================================================== -// class NetworkMessageText -// -// Chat text message -// ===================================================== + // ===================================================== + // class NetworkMessageText + // + // Chat text message + // ===================================================== #pragma pack(push, 1) -class NetworkMessageText: public NetworkMessage { -private: - static const int maxTextStringSize= 500; + class NetworkMessageText : public NetworkMessage { + private: + static const int maxTextStringSize = 500; -private: - int8 messageType; - struct Data{ + private: + int8 messageType; + struct Data { - NetworkString text; - int8 teamIndex; - int8 playerIndex; - NetworkString targetLanguage; - }; - void toEndian(); - void fromEndian(); + NetworkString text; + int8 teamIndex; + int8 playerIndex; + NetworkString targetLanguage; + }; + void toEndian(); + void fromEndian(); -private: - Data data; + private: + Data data; -protected: - virtual const char * getPackedMessageFormat() const; - virtual unsigned int getPackedSize(); - virtual void unpackMessage(unsigned char *buf); - virtual unsigned char * packMessage(); + protected: + virtual const char * getPackedMessageFormat() const; + virtual unsigned int getPackedSize(); + virtual void unpackMessage(unsigned char *buf); + virtual unsigned char * packMessage(); -public: - NetworkMessageText(); - NetworkMessageText(const string &text, int teamIndex, int playerIndex, - const string targetLanguage); + public: + NetworkMessageText(); + NetworkMessageText(const string &text, int teamIndex, int playerIndex, + const string targetLanguage); - virtual size_t getDataSize() const { return sizeof(Data); } + virtual size_t getDataSize() const { + return sizeof(Data); + } - virtual NetworkMessageType getNetworkMessageType() const { - return nmtText; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtText; + } - string getText() const {return data.text.getString();} - int getTeamIndex() const {return data.teamIndex;} - int getPlayerIndex() const {return data.playerIndex;} - string getTargetLanguage() const {return data.targetLanguage.getString();} + string getText() const { + return data.text.getString(); + } + int getTeamIndex() const { + return data.teamIndex; + } + int getPlayerIndex() const { + return data.playerIndex; + } + string getTargetLanguage() const { + return data.targetLanguage.getString(); + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); - NetworkMessageText * getCopy() const; -}; + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); + NetworkMessageText * getCopy() const; + }; #pragma pack(pop) -// ===================================================== -// class NetworkMessageQuit -// -// Message sent at the beginning of the game -// ===================================================== + // ===================================================== + // class NetworkMessageQuit + // + // Message sent at the beginning of the game + // ===================================================== #pragma pack(push, 1) -class NetworkMessageQuit: public NetworkMessage{ -private: + class NetworkMessageQuit : public NetworkMessage { + private: - int8 messageType; - //struct Data{ - // int8 messageType; - //}; - void toEndian(); - void fromEndian(); + int8 messageType; + //struct Data{ + // int8 messageType; + //}; + void toEndian(); + void fromEndian(); -private: - //Data data; + private: + //Data data; -protected: - virtual const char * getPackedMessageFormat() const; - virtual unsigned int getPackedSize(); - virtual void unpackMessage(unsigned char *buf); - virtual unsigned char * packMessage(); + protected: + virtual const char * getPackedMessageFormat() const; + virtual unsigned int getPackedSize(); + virtual void unpackMessage(unsigned char *buf); + virtual unsigned char * packMessage(); -public: - NetworkMessageQuit(); + public: + NetworkMessageQuit(); - //virtual size_t getDataSize() const { return sizeof(Data); } - virtual size_t getDataSize() const { return 0; } + //virtual size_t getDataSize() const { return sizeof(Data); } + virtual size_t getDataSize() const { + return 0; + } - virtual NetworkMessageType getNetworkMessageType() const { - return nmtQuit; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtQuit; + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); -}; + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); + }; #pragma pack(pop) -// ===================================================== -// class NetworkMessageSynchNetworkGameData -// -// Message sent at the beginning of a network game -// ===================================================== + // ===================================================== + // class NetworkMessageSynchNetworkGameData + // + // Message sent at the beginning of a network game + // ===================================================== #pragma pack(push, 1) -class NetworkMessageSynchNetworkGameData: public NetworkMessage{ + class NetworkMessageSynchNetworkGameData : public NetworkMessage { -private: + private: -static const int maxStringSize= 255; -static const int maxFileCRCCount= 1500; -static const int maxFileCRCPacketCount= 25; + static const int maxStringSize = 255; + static const int maxFileCRCCount = 1500; + static const int maxFileCRCPacketCount = 25; -private: + private: - struct DataHeader { - NetworkString map; - NetworkString tileset; - NetworkString tech; + struct DataHeader { + NetworkString map; + NetworkString tileset; + NetworkString tech; - uint32 mapCRC; - uint32 tilesetCRC; - uint32 techCRC; + uint32 mapCRC; + uint32 tilesetCRC; + uint32 techCRC; - uint32 techCRCFileCount; - }; + uint32 techCRCFileCount; + }; - static const int32 HeaderSize = sizeof(DataHeader); + static const int32 HeaderSize = sizeof(DataHeader); - struct DataDetail { - NetworkString techCRCFileList[maxFileCRCCount]; - uint32 techCRCFileCRCList[maxFileCRCCount]; - }; + struct DataDetail { + NetworkString techCRCFileList[maxFileCRCCount]; + uint32 techCRCFileCRCList[maxFileCRCCount]; + }; - static const int32 DetailSize1 = sizeof(NetworkString); - static const int32 DetailSize2 = sizeof(uint32); + static const int32 DetailSize1 = sizeof(NetworkString); + static const int32 DetailSize2 = sizeof(uint32); - struct Data { - int8 messageType; - DataHeader header; - DataDetail detail; - }; - void toEndianHeader(); - void fromEndianHeader(); - void toEndianDetail(uint32 totalFileCount); - void fromEndianDetail(); + struct Data { + int8 messageType; + DataHeader header; + DataDetail detail; + }; + void toEndianHeader(); + void fromEndianHeader(); + void toEndianDetail(uint32 totalFileCount); + void fromEndianDetail(); -private: - Data data; + private: + Data data; -protected: - virtual const char * getPackedMessageFormat() const { return NULL; } - virtual unsigned int getPackedSize() { return 0; } - virtual void unpackMessage(unsigned char *buf) { }; - virtual unsigned char * packMessage() { return NULL; } + protected: + virtual const char * getPackedMessageFormat() const { + return NULL; + } + virtual unsigned int getPackedSize() { + return 0; + } + virtual void unpackMessage(unsigned char *buf) { + }; + virtual unsigned char * packMessage() { + return NULL; + } - const char * getPackedMessageFormatHeader() const; - unsigned int getPackedSizeHeader(); - void unpackMessageHeader(unsigned char *buf); - unsigned char * packMessageHeader(); + const char * getPackedMessageFormatHeader() const; + unsigned int getPackedSizeHeader(); + void unpackMessageHeader(unsigned char *buf); + unsigned char * packMessageHeader(); - unsigned int getPackedSizeDetail(); - void unpackMessageDetail(unsigned char *buf); - unsigned char * packMessageDetail(); + unsigned int getPackedSizeDetail(); + void unpackMessageDetail(unsigned char *buf); + unsigned char * packMessageDetail(); -public: - NetworkMessageSynchNetworkGameData() {}; - explicit NetworkMessageSynchNetworkGameData(const GameSettings *gameSettings); + public: + NetworkMessageSynchNetworkGameData() { + }; + explicit NetworkMessageSynchNetworkGameData(const GameSettings *gameSettings); - virtual size_t getDataSize() const { return sizeof(Data); } + virtual size_t getDataSize() const { + return sizeof(Data); + } - virtual NetworkMessageType getNetworkMessageType() const { - return nmtSynchNetworkGameData; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtSynchNetworkGameData; + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); - string getMap() const {return data.header.map.getString();} - string getTileset() const {return data.header.tileset.getString();} - string getTech() const {return data.header.tech.getString();} + string getMap() const { + return data.header.map.getString(); + } + string getTileset() const { + return data.header.tileset.getString(); + } + string getTech() const { + return data.header.tech.getString(); + } - uint32 getMapCRC() const {return data.header.mapCRC;} - uint32 getTilesetCRC() const {return data.header.tilesetCRC;} - uint32 getTechCRC() const {return data.header.techCRC;} + uint32 getMapCRC() const { + return data.header.mapCRC; + } + uint32 getTilesetCRC() const { + return data.header.tilesetCRC; + } + uint32 getTechCRC() const { + return data.header.techCRC; + } - uint32 getTechCRCFileCount() const {return data.header.techCRCFileCount;} - const NetworkString * getTechCRCFileList() const {return &data.detail.techCRCFileList[0];} - const uint32 * getTechCRCFileCRCList() const {return data.detail.techCRCFileCRCList;} + uint32 getTechCRCFileCount() const { + return data.header.techCRCFileCount; + } + const NetworkString * getTechCRCFileList() const { + return &data.detail.techCRCFileList[0]; + } + const uint32 * getTechCRCFileCRCList() const { + return data.detail.techCRCFileCRCList; + } - string getTechCRCFileMismatchReport(vector > &vctFileList); -}; + string getTechCRCFileMismatchReport(vector > &vctFileList); + }; #pragma pack(pop) -// ===================================================== -// class NetworkMessageSynchNetworkGameDataStatus -// -// Message sent at the beggining of a network game -// ===================================================== + // ===================================================== + // class NetworkMessageSynchNetworkGameDataStatus + // + // Message sent at the beggining of a network game + // ===================================================== #pragma pack(push, 1) -class NetworkMessageSynchNetworkGameDataStatus: public NetworkMessage{ + class NetworkMessageSynchNetworkGameDataStatus : public NetworkMessage { -private: + private: -static const int maxStringSize= 255; -static const int maxFileCRCCount= 1500; -static const uint32 maxFileCRCPacketCount= 25; + static const int maxStringSize = 255; + static const int maxFileCRCCount = 1500; + static const uint32 maxFileCRCPacketCount = 25; -private: + private: - struct DataHeader { - uint32 mapCRC; - uint32 tilesetCRC; - uint32 techCRC; + struct DataHeader { + uint32 mapCRC; + uint32 tilesetCRC; + uint32 techCRC; - uint32 techCRCFileCount; - }; - static const int32 HeaderSize = sizeof(DataHeader); + uint32 techCRCFileCount; + }; + static const int32 HeaderSize = sizeof(DataHeader); - struct DataDetail { - NetworkString techCRCFileList[maxFileCRCCount]; - uint32 techCRCFileCRCList[maxFileCRCCount]; - }; + struct DataDetail { + NetworkString techCRCFileList[maxFileCRCCount]; + uint32 techCRCFileCRCList[maxFileCRCCount]; + }; - static const int32 DetailSize1 = sizeof(NetworkString); - static const int32 DetailSize2 = sizeof(uint32); + static const int32 DetailSize1 = sizeof(NetworkString); + static const int32 DetailSize2 = sizeof(uint32); - struct Data { - int8 messageType; - DataHeader header; - DataDetail detail; - }; - void toEndianHeader(); - void fromEndianHeader(); - void toEndianDetail(uint32 totalFileCount); - void fromEndianDetail(); + struct Data { + int8 messageType; + DataHeader header; + DataDetail detail; + }; + void toEndianHeader(); + void fromEndianHeader(); + void toEndianDetail(uint32 totalFileCount); + void fromEndianDetail(); -private: - Data data; + private: + Data data; -protected: - virtual const char * getPackedMessageFormat() const { return NULL; } - virtual unsigned int getPackedSize() { return 0; } - virtual void unpackMessage(unsigned char *buf) { }; - virtual unsigned char * packMessage() { return NULL; } + protected: + virtual const char * getPackedMessageFormat() const { + return NULL; + } + virtual unsigned int getPackedSize() { + return 0; + } + virtual void unpackMessage(unsigned char *buf) { + }; + virtual unsigned char * packMessage() { + return NULL; + } -public: - NetworkMessageSynchNetworkGameDataStatus() {}; - NetworkMessageSynchNetworkGameDataStatus(uint32 mapCRC, uint32 tilesetCRC, uint32 techCRC, vector > &vctFileList); + public: + NetworkMessageSynchNetworkGameDataStatus() { + }; + NetworkMessageSynchNetworkGameDataStatus(uint32 mapCRC, uint32 tilesetCRC, uint32 techCRC, vector > &vctFileList); - virtual size_t getDataSize() const { return sizeof(Data); } + virtual size_t getDataSize() const { + return sizeof(Data); + } - virtual NetworkMessageType getNetworkMessageType() const { - return nmtSynchNetworkGameDataStatus; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtSynchNetworkGameDataStatus; + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); - uint32 getMapCRC() const {return data.header.mapCRC;} - uint32 getTilesetCRC() const {return data.header.tilesetCRC;} - uint32 getTechCRC() const {return data.header.techCRC;} + uint32 getMapCRC() const { + return data.header.mapCRC; + } + uint32 getTilesetCRC() const { + return data.header.tilesetCRC; + } + uint32 getTechCRC() const { + return data.header.techCRC; + } - uint32 getTechCRCFileCount() const {return data.header.techCRCFileCount;} - const NetworkString * getTechCRCFileList() const {return &data.detail.techCRCFileList[0];} - const uint32 * getTechCRCFileCRCList() const {return data.detail.techCRCFileCRCList;} + uint32 getTechCRCFileCount() const { + return data.header.techCRCFileCount; + } + const NetworkString * getTechCRCFileList() const { + return &data.detail.techCRCFileList[0]; + } + const uint32 * getTechCRCFileCRCList() const { + return data.detail.techCRCFileCRCList; + } - string getTechCRCFileMismatchReport(string techtree, vector > &vctFileList); + string getTechCRCFileMismatchReport(string techtree, vector > &vctFileList); -}; + }; #pragma pack(pop) -// ===================================================== -// class NetworkMessageSynchNetworkGameDataFileCRCCheck -// -// Message sent at the beginning of a network game -// ===================================================== + // ===================================================== + // class NetworkMessageSynchNetworkGameDataFileCRCCheck + // + // Message sent at the beginning of a network game + // ===================================================== #pragma pack(push, 1) -class NetworkMessageSynchNetworkGameDataFileCRCCheck: public NetworkMessage{ + class NetworkMessageSynchNetworkGameDataFileCRCCheck : public NetworkMessage { -private: + private: -static const int maxStringSize= 256; + static const int maxStringSize = 256; -private: - int8 messageType; - struct Data{ + private: + int8 messageType; + struct Data { - uint32 totalFileCount; - uint32 fileIndex; - uint32 fileCRC; - NetworkString fileName; - }; - void toEndian(); - void fromEndian(); + uint32 totalFileCount; + uint32 fileIndex; + uint32 fileCRC; + NetworkString fileName; + }; + void toEndian(); + void fromEndian(); -private: - Data data; + private: + Data data; -protected: - virtual const char * getPackedMessageFormat() const; - virtual unsigned int getPackedSize(); - virtual void unpackMessage(unsigned char *buf); - virtual unsigned char * packMessage(); + protected: + virtual const char * getPackedMessageFormat() const; + virtual unsigned int getPackedSize(); + virtual void unpackMessage(unsigned char *buf); + virtual unsigned char * packMessage(); -public: - NetworkMessageSynchNetworkGameDataFileCRCCheck(); - NetworkMessageSynchNetworkGameDataFileCRCCheck(uint32 totalFileCount, uint32 fileIndex, uint32 fileCRC, const string fileName); + public: + NetworkMessageSynchNetworkGameDataFileCRCCheck(); + NetworkMessageSynchNetworkGameDataFileCRCCheck(uint32 totalFileCount, uint32 fileIndex, uint32 fileCRC, const string fileName); - virtual size_t getDataSize() const { return sizeof(Data); } + virtual size_t getDataSize() const { + return sizeof(Data); + } - virtual NetworkMessageType getNetworkMessageType() const { - return nmtSynchNetworkGameDataFileCRCCheck; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtSynchNetworkGameDataFileCRCCheck; + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); - uint32 getTotalFileCount() const {return data.totalFileCount;} - uint32 getFileIndex() const {return data.fileIndex;} - uint32 getFileCRC() const {return data.fileCRC;} - string getFileName() const {return data.fileName.getString();} -}; + uint32 getTotalFileCount() const { + return data.totalFileCount; + } + uint32 getFileIndex() const { + return data.fileIndex; + } + uint32 getFileCRC() const { + return data.fileCRC; + } + string getFileName() const { + return data.fileName.getString(); + } + }; #pragma pack(pop) -// ===================================================== -// class NetworkMessageSynchNetworkGameDataFileGet -// -// Message sent at the beginning of a network game -// ===================================================== + // ===================================================== + // class NetworkMessageSynchNetworkGameDataFileGet + // + // Message sent at the beginning of a network game + // ===================================================== #pragma pack(push, 1) -class NetworkMessageSynchNetworkGameDataFileGet: public NetworkMessage{ + class NetworkMessageSynchNetworkGameDataFileGet : public NetworkMessage { -private: + private: -static const int maxStringSize= 256; + static const int maxStringSize = 256; -private: + private: - int8 messageType; - struct Data{ + int8 messageType; + struct Data { - NetworkString fileName; - }; - void toEndian(); - void fromEndian(); + NetworkString fileName; + }; + void toEndian(); + void fromEndian(); -private: - Data data; + private: + Data data; -protected: - virtual const char * getPackedMessageFormat() const; - virtual unsigned int getPackedSize(); - virtual void unpackMessage(unsigned char *buf); - virtual unsigned char * packMessage(); + protected: + virtual const char * getPackedMessageFormat() const; + virtual unsigned int getPackedSize(); + virtual void unpackMessage(unsigned char *buf); + virtual unsigned char * packMessage(); -public: - NetworkMessageSynchNetworkGameDataFileGet(); - explicit NetworkMessageSynchNetworkGameDataFileGet(const string fileName); + public: + NetworkMessageSynchNetworkGameDataFileGet(); + explicit NetworkMessageSynchNetworkGameDataFileGet(const string fileName); - virtual size_t getDataSize() const { return sizeof(Data); } + virtual size_t getDataSize() const { + return sizeof(Data); + } - virtual NetworkMessageType getNetworkMessageType() const { - return nmtSynchNetworkGameDataFileGet; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtSynchNetworkGameDataFileGet; + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); - string getFileName() const {return data.fileName.getString();} -}; + string getFileName() const { + return data.fileName.getString(); + } + }; #pragma pack(pop) -// ===================================================== -// class SwitchSetupRequest -// -// Message sent from the client to the server -// to switch its settings -// ===================================================== + // ===================================================== + // class SwitchSetupRequest + // + // Message sent from the client to the server + // to switch its settings + // ===================================================== -// Each bit represents which item in the packet has a changed value -enum SwitchSetupRequestFlagType { - ssrft_None = 0x00, - ssrft_SelectedFactionName = 0x01, - ssrft_CurrentFactionIndex = 0x02, - ssrft_ToFactionIndex = 0x04, - ssrft_ToTeam = 0x08, - ssrft_NetworkPlayerName = 0x10, - ssrft_PlayerStatus = 0x20 -}; + // Each bit represents which item in the packet has a changed value + enum SwitchSetupRequestFlagType { + ssrft_None = 0x00, + ssrft_SelectedFactionName = 0x01, + ssrft_CurrentFactionIndex = 0x02, + ssrft_ToFactionIndex = 0x04, + ssrft_ToTeam = 0x08, + ssrft_NetworkPlayerName = 0x10, + ssrft_PlayerStatus = 0x20 + }; #pragma pack(push, 1) -class SwitchSetupRequest: public NetworkMessage{ -private: - static const int maxStringSize= 256; - static const int maxPlayernameStringSize= 80; + class SwitchSetupRequest : public NetworkMessage { + private: + static const int maxStringSize = 256; + static const int maxPlayernameStringSize = 80; -private: + private: - int8 messageType; - struct Data { + int8 messageType; + struct Data { - NetworkString selectedFactionName; //wanted faction name - int8 currentSlotIndex; - int8 toSlotIndex; - int8 toTeam; - NetworkString networkPlayerName; - int8 networkPlayerStatus; - int8 switchFlags; - NetworkString language; - }; - void toEndian(); - void fromEndian(); + NetworkString selectedFactionName; //wanted faction name + int8 currentSlotIndex; + int8 toSlotIndex; + int8 toTeam; + NetworkString networkPlayerName; + int8 networkPlayerStatus; + int8 switchFlags; + NetworkString language; + }; + void toEndian(); + void fromEndian(); -private: - Data data; + private: + Data data; -public: - virtual const char * getPackedMessageFormat() const; - virtual unsigned int getPackedSize(); - virtual void unpackMessage(unsigned char *buf); - virtual unsigned char * packMessage(); + public: + virtual const char * getPackedMessageFormat() const; + virtual unsigned int getPackedSize(); + virtual void unpackMessage(unsigned char *buf); + virtual unsigned char * packMessage(); -public: - SwitchSetupRequest(); - SwitchSetupRequest( string selectedFactionName, int8 currentFactionIndex, - int8 toFactionIndex,int8 toTeam,string networkPlayerName, - int8 networkPlayerStatus, int8 flags, - string language); + public: + SwitchSetupRequest(); + SwitchSetupRequest(string selectedFactionName, int8 currentFactionIndex, + int8 toFactionIndex, int8 toTeam, string networkPlayerName, + int8 networkPlayerStatus, int8 flags, + string language); - virtual size_t getDataSize() const { return sizeof(Data); } + virtual size_t getDataSize() const { + return sizeof(Data); + } - virtual NetworkMessageType getNetworkMessageType() const { - return nmtSwitchSetupRequest; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtSwitchSetupRequest; + } - string getSelectedFactionName() const {return data.selectedFactionName.getString();} - int getCurrentSlotIndex() const {return data.currentSlotIndex;} - int getToSlotIndex() const {return data.toSlotIndex;} - int getToTeam() const {return data.toTeam;} - string getNetworkPlayerName() const {return data.networkPlayerName.getString(); } - int getSwitchFlags() const {return data.switchFlags;} - void addSwitchFlag(SwitchSetupRequestFlagType flag) { data.switchFlags |= flag;} - void clearSwitchFlag(SwitchSetupRequestFlagType flag) { data.switchFlags &= ~flag;} + string getSelectedFactionName() const { + return data.selectedFactionName.getString(); + } + int getCurrentSlotIndex() const { + return data.currentSlotIndex; + } + int getToSlotIndex() const { + return data.toSlotIndex; + } + int getToTeam() const { + return data.toTeam; + } + string getNetworkPlayerName() const { + return data.networkPlayerName.getString(); + } + int getSwitchFlags() const { + return data.switchFlags; + } + void addSwitchFlag(SwitchSetupRequestFlagType flag) { + data.switchFlags |= flag; + } + void clearSwitchFlag(SwitchSetupRequestFlagType flag) { + data.switchFlags &= ~flag; + } - int getNetworkPlayerStatus() const { return data.networkPlayerStatus; } - string getNetworkPlayerLanguage() const { return data.language.getString(); } + int getNetworkPlayerStatus() const { + return data.networkPlayerStatus; + } + string getNetworkPlayerLanguage() const { + return data.language.getString(); + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); -}; + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); + }; #pragma pack(pop) -// ===================================================== -// class PlayerIndexMessage -// -// Message sent from the server to the clients -// to tell them about a slot change ( caused by another client ) -// ===================================================== + // ===================================================== + // class PlayerIndexMessage + // + // Message sent from the server to the clients + // to tell them about a slot change ( caused by another client ) + // ===================================================== #pragma pack(push, 1) -class PlayerIndexMessage: public NetworkMessage{ + class PlayerIndexMessage : public NetworkMessage { -private: + private: - int8 messageType; - struct Data { + int8 messageType; + struct Data { - int16 playerIndex; - }; - void toEndian(); - void fromEndian(); + int16 playerIndex; + }; + void toEndian(); + void fromEndian(); -private: - Data data; + private: + Data data; -protected: - virtual const char * getPackedMessageFormat() const; - virtual unsigned int getPackedSize(); - virtual void unpackMessage(unsigned char *buf); - virtual unsigned char * packMessage(); + protected: + virtual const char * getPackedMessageFormat() const; + virtual unsigned int getPackedSize(); + virtual void unpackMessage(unsigned char *buf); + virtual unsigned char * packMessage(); -public: - explicit PlayerIndexMessage( int16 playerIndex); + public: + explicit PlayerIndexMessage(int16 playerIndex); - virtual size_t getDataSize() const { return sizeof(Data); } + virtual size_t getDataSize() const { + return sizeof(Data); + } - virtual NetworkMessageType getNetworkMessageType() const { - return nmtPlayerIndexMessage; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtPlayerIndexMessage; + } - int16 getPlayerIndex() const {return data.playerIndex;} + int16 getPlayerIndex() const { + return data.playerIndex; + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); -}; + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); + }; #pragma pack(pop) -// ===================================================== -// class NetworkMessageLoadingStatus -// -// Message sent during game loading -// ===================================================== + // ===================================================== + // class NetworkMessageLoadingStatus + // + // Message sent during game loading + // ===================================================== -enum NetworkMessageLoadingStatusType { - nmls_NONE = 0x00, + enum NetworkMessageLoadingStatusType { + nmls_NONE = 0x00, - nmls_PLAYER1_CONNECTED = 0x01, - nmls_PLAYER2_CONNECTED = 0x02, - nmls_PLAYER3_CONNECTED = 0x04, - nmls_PLAYER4_CONNECTED = 0x08, - nmls_PLAYER5_CONNECTED = 0x10, - nmls_PLAYER6_CONNECTED = 0x20, - nmls_PLAYER7_CONNECTED = 0x40, - nmls_PLAYER8_CONNECTED = 0x80, - nmls_PLAYER9_CONNECTED = 0x160, - nmls_PLAYER10_CONNECTED = 0x320, + nmls_PLAYER1_CONNECTED = 0x01, + nmls_PLAYER2_CONNECTED = 0x02, + nmls_PLAYER3_CONNECTED = 0x04, + nmls_PLAYER4_CONNECTED = 0x08, + nmls_PLAYER5_CONNECTED = 0x10, + nmls_PLAYER6_CONNECTED = 0x20, + nmls_PLAYER7_CONNECTED = 0x40, + nmls_PLAYER8_CONNECTED = 0x80, + nmls_PLAYER9_CONNECTED = 0x160, + nmls_PLAYER10_CONNECTED = 0x320, - nmls_PLAYER1_READY = 0x100, - nmls_PLAYER2_READY = 0x200, - nmls_PLAYER3_READY = 0x400, - nmls_PLAYER4_READY = 0x1000, - nmls_PLAYER5_READY = 0x2000, - nmls_PLAYER6_READY = 0x4000, - nmls_PLAYER7_READY = 0x8000, - nmls_PLAYER8_READY = 0x10000, - nmls_PLAYER9_READY = 0x12000, - nmls_PLAYER10_READY = 0x14000 -}; + nmls_PLAYER1_READY = 0x100, + nmls_PLAYER2_READY = 0x200, + nmls_PLAYER3_READY = 0x400, + nmls_PLAYER4_READY = 0x1000, + nmls_PLAYER5_READY = 0x2000, + nmls_PLAYER6_READY = 0x4000, + nmls_PLAYER7_READY = 0x8000, + nmls_PLAYER8_READY = 0x10000, + nmls_PLAYER9_READY = 0x12000, + nmls_PLAYER10_READY = 0x14000 + }; #pragma pack(push, 1) -class NetworkMessageLoadingStatus : public NetworkMessage { -private: + class NetworkMessageLoadingStatus : public NetworkMessage { + private: - int8 messageType; - struct Data { + int8 messageType; + struct Data { - uint32 status; - }; - void toEndian(); - void fromEndian(); + uint32 status; + }; + void toEndian(); + void fromEndian(); -private: - Data data; + private: + Data data; -protected: - virtual const char * getPackedMessageFormat() const; - virtual unsigned int getPackedSize(); - virtual void unpackMessage(unsigned char *buf); - virtual unsigned char * packMessage(); + protected: + virtual const char * getPackedMessageFormat() const; + virtual unsigned int getPackedSize(); + virtual void unpackMessage(unsigned char *buf); + virtual unsigned char * packMessage(); -public: - NetworkMessageLoadingStatus(); - explicit NetworkMessageLoadingStatus(uint32 status); + public: + NetworkMessageLoadingStatus(); + explicit NetworkMessageLoadingStatus(uint32 status); - virtual size_t getDataSize() const { return sizeof(Data); } + virtual size_t getDataSize() const { + return sizeof(Data); + } - virtual NetworkMessageType getNetworkMessageType() const { - return nmtLoadingStatusMessage; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtLoadingStatusMessage; + } - uint32 getStatus() const {return data.status;} + uint32 getStatus() const { + return data.status; + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); -}; + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); + }; #pragma pack(pop) -// ===================================================== -// class NetworkMessageMarkCell -// -// Mark a Cell message nmtMarkCell -// ===================================================== + // ===================================================== + // class NetworkMessageMarkCell + // + // Mark a Cell message nmtMarkCell + // ===================================================== #pragma pack(push, 1) -class NetworkMessageMarkCell: public NetworkMessage { -private: - static const int maxTextStringSize= 500; + class NetworkMessageMarkCell : public NetworkMessage { + private: + static const int maxTextStringSize = 500; -private: + private: - int8 messageType; - struct Data{ + int8 messageType; + struct Data { - int16 targetX; - int16 targetY; - int8 factionIndex; - int8 playerIndex; - NetworkString text; - }; - void toEndian(); - void fromEndian(); + int16 targetX; + int16 targetY; + int8 factionIndex; + int8 playerIndex; + NetworkString text; + }; + void toEndian(); + void fromEndian(); -private: - Data data; + private: + Data data; -protected: - virtual const char * getPackedMessageFormat() const; - virtual unsigned int getPackedSize(); - virtual void unpackMessage(unsigned char *buf); - virtual unsigned char * packMessage(); + protected: + virtual const char * getPackedMessageFormat() const; + virtual unsigned int getPackedSize(); + virtual void unpackMessage(unsigned char *buf); + virtual unsigned char * packMessage(); -public: - NetworkMessageMarkCell(); - NetworkMessageMarkCell(Vec2i target, int factionIndex, const string &text, int playerIndex); + public: + NetworkMessageMarkCell(); + NetworkMessageMarkCell(Vec2i target, int factionIndex, const string &text, int playerIndex); - virtual size_t getDataSize() const { return sizeof(Data); } + virtual size_t getDataSize() const { + return sizeof(Data); + } - virtual NetworkMessageType getNetworkMessageType() const { - return nmtMarkCell; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtMarkCell; + } - string getText() const { return data.text.getString(); } - Vec2i getTarget() const { return Vec2i(data.targetX,data.targetY); } - int getFactionIndex() const { return data.factionIndex; } - int getPlayerIndex() const { return data.playerIndex; } + string getText() const { + return data.text.getString(); + } + Vec2i getTarget() const { + return Vec2i(data.targetX, data.targetY); + } + int getFactionIndex() const { + return data.factionIndex; + } + int getPlayerIndex() const { + return data.playerIndex; + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); - NetworkMessageMarkCell * getCopy() const; -}; + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); + NetworkMessageMarkCell * getCopy() const; + }; #pragma pack(pop) -// ===================================================== -// class NetworkUnMessageMarkCell -// -// Mark a Cell message nmtUnMarkCell -// ===================================================== + // ===================================================== + // class NetworkUnMessageMarkCell + // + // Mark a Cell message nmtUnMarkCell + // ===================================================== #pragma pack(push, 1) -class NetworkMessageUnMarkCell: public NetworkMessage { + class NetworkMessageUnMarkCell : public NetworkMessage { -private: + private: - int8 messageType; - struct Data { + int8 messageType; + struct Data { - int16 targetX; - int16 targetY; - int8 factionIndex; - }; - void toEndian(); - void fromEndian(); + int16 targetX; + int16 targetY; + int8 factionIndex; + }; + void toEndian(); + void fromEndian(); -private: - Data data; + private: + Data data; -protected: - virtual const char * getPackedMessageFormat() const; - virtual unsigned int getPackedSize(); - virtual void unpackMessage(unsigned char *buf); - virtual unsigned char * packMessage(); + protected: + virtual const char * getPackedMessageFormat() const; + virtual unsigned int getPackedSize(); + virtual void unpackMessage(unsigned char *buf); + virtual unsigned char * packMessage(); -public: - NetworkMessageUnMarkCell(); - NetworkMessageUnMarkCell(Vec2i target, int factionIndex); + public: + NetworkMessageUnMarkCell(); + NetworkMessageUnMarkCell(Vec2i target, int factionIndex); - virtual size_t getDataSize() const { return sizeof(Data); } + virtual size_t getDataSize() const { + return sizeof(Data); + } - virtual NetworkMessageType getNetworkMessageType() const { - return nmtUnMarkCell; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtUnMarkCell; + } - Vec2i getTarget() const { return Vec2i(data.targetX,data.targetY); } - int getFactionIndex() const { return data.factionIndex; } + Vec2i getTarget() const { + return Vec2i(data.targetX, data.targetY); + } + int getFactionIndex() const { + return data.factionIndex; + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); - NetworkMessageUnMarkCell * getCopy() const; -}; + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); + NetworkMessageUnMarkCell * getCopy() const; + }; #pragma pack(pop) -// ===================================================== -// class NetworkHighlightCellMessage -// -// Highlight a Cell message -// ===================================================== + // ===================================================== + // class NetworkHighlightCellMessage + // + // Highlight a Cell message + // ===================================================== #pragma pack(push, 1) -class NetworkMessageHighlightCell: public NetworkMessage { -private: - static const int maxTextStringSize= 500; + class NetworkMessageHighlightCell : public NetworkMessage { + private: + static const int maxTextStringSize = 500; -private: + private: - int8 messageType; - struct Data{ + int8 messageType; + struct Data { - int16 targetX; - int16 targetY; - int8 factionIndex; - }; - void toEndian(); - void fromEndian(); + int16 targetX; + int16 targetY; + int8 factionIndex; + }; + void toEndian(); + void fromEndian(); -private: - Data data; + private: + Data data; -protected: - virtual const char * getPackedMessageFormat() const; - virtual unsigned int getPackedSize(); - virtual void unpackMessage(unsigned char *buf); - virtual unsigned char * packMessage(); + protected: + virtual const char * getPackedMessageFormat() const; + virtual unsigned int getPackedSize(); + virtual void unpackMessage(unsigned char *buf); + virtual unsigned char * packMessage(); -public: - NetworkMessageHighlightCell(); - NetworkMessageHighlightCell(Vec2i target, int factionIndex); + public: + NetworkMessageHighlightCell(); + NetworkMessageHighlightCell(Vec2i target, int factionIndex); - virtual size_t getDataSize() const { return sizeof(Data); } + virtual size_t getDataSize() const { + return sizeof(Data); + } - virtual NetworkMessageType getNetworkMessageType() const { - return nmtHighlightCell; - } + virtual NetworkMessageType getNetworkMessageType() const { + return nmtHighlightCell; + } - Vec2i getTarget() const { return Vec2i(data.targetX,data.targetY); } - int getFactionIndex() const { return data.factionIndex; } + Vec2i getTarget() const { + return Vec2i(data.targetX, data.targetY); + } + int getFactionIndex() const { + return data.factionIndex; + } - virtual bool receive(Socket* socket); - virtual void send(Socket* socket); -}; + virtual bool receive(Socket* socket); + virtual void send(Socket* socket); + }; #pragma pack(pop) -}}//end namespace + } +}//end namespace #endif diff --git a/source/glest_game/network/network_protocol.cpp b/source/glest_game/network/network_protocol.cpp index fdb3adfa6..574b31494 100644 --- a/source/glest_game/network/network_protocol.cpp +++ b/source/glest_game/network/network_protocol.cpp @@ -20,11 +20,12 @@ using namespace Shared::Platform; using namespace Shared::Util; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { #pragma pack(push, 1) -// macros for packing floats and doubles: + // macros for packing floats and doubles: #define pack754_16(f) (pack754((f), 16, 5)) #define pack754_32(f) (pack754((f), 32, 8)) #define pack754_64(f) (pack754((f), 64, 11)) @@ -35,551 +36,549 @@ namespace Glest{ namespace Game{ /* ** pack754() -- pack a floating point number into IEEE-754 format */ -unsigned long long int pack754(long double f, unsigned bits, unsigned expbits) -{ - long double fnorm; - int shift; - long long sign, exp, significand; - unsigned significandbits = bits - expbits - 1; // -1 for sign bit + unsigned long long int pack754(long double f, unsigned bits, unsigned expbits) { + long double fnorm; + int shift; + long long sign, exp, significand; + unsigned significandbits = bits - expbits - 1; // -1 for sign bit - if (f == 0.0) return 0; // get this special case out of the way + if (f == 0.0) return 0; // get this special case out of the way - // check sign and begin normalization - if (f < 0) { sign = 1; fnorm = -f; } - else { sign = 0; fnorm = f; } - - // get the normalized form of f and track the exponent - shift = 0; - while(fnorm >= 2.0) { fnorm /= 2.0; shift++; } - while(fnorm < 1.0) { fnorm *= 2.0; shift--; } - fnorm = fnorm - 1.0; - - // calculate the binary form (non-float) of the significand data - significand = fnorm * ((1LL<>significandbits)&((1LL< 0) { result *= 2.0; shift--; } - while(shift < 0) { result /= 2.0; shift++; } - - // sign it - result *= ((i>>(bits-1))&1) ? -1.0: 1.0; - - return result; -} - -/* -** packi16() -- store a 16-bit int into a char buffer (like htons()) -*/ -void packi16(unsigned char *buf, uint16 i) -{ - *buf++ = i>>8; *buf++ = i; -} - -/* -** packi32() -- store a 32-bit int into a char buffer (like htonl()) -*/ -void packi32(unsigned char *buf, uint32 i) -{ - *buf++ = i>>24; *buf++ = i>>16; - *buf++ = i>>8; *buf++ = i; -} - -/* -** packi64() -- store a 64-bit int into a char buffer (like htonl()) -*/ -void packi64(unsigned char *buf, uint64 i) -{ - *buf++ = i>>56; *buf++ = i>>48; - *buf++ = i>>40; *buf++ = i>>32; - *buf++ = i>>24; *buf++ = i>>16; - *buf++ = i>>8; *buf++ = i; -} - -/* -** unpacki16() -- unpack a 16-bit int from a char buffer (like ntohs()) -*/ -int16 unpacki16(unsigned char *buf) -{ - uint16 i2 = ((uint16)buf[0]<<8) | buf[1]; - int16 i; - - // change unsigned numbers to signed - if (i2 <= 0x7fffu) { - i = i2; - } - else { - i = -1 - (uint16)(0xffffu - i2); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("IN [%s] [%d] [%d] [%d] [%u]\n",__FUNCTION__,buf[0],buf[1],i,i2); - } - - return i; -} - -/* -** unpacku16() -- unpack a 16-bit unsigned from a char buffer (like ntohs()) -*/ -uint16 unpacku16(unsigned char *buf) -{ - return ((uint16)buf[0]<<8) | buf[1]; -} - -/* -** unpacki32() -- unpack a 32-bit int from a char buffer (like ntohl()) -*/ -int32 unpacki32(unsigned char *buf) -{ - uint32 i2 = ((uint32)buf[0]<<24) | - ((uint32)buf[1]<<16) | - ((uint32)buf[2]<<8) | - buf[3]; - int32 i; - - // change unsigned numbers to signed - if (i2 <= 0x7fffffffu) { - i = i2; - } - else { - i = -1 - (int32)(0xffffffffu - i2); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("IN [%s] [%d] [%d] [%d] [%d] [%d] [%u]\n",__FUNCTION__,buf[0],buf[1],buf[2],buf[3],i,i2); - } - - return i; -} - -/* -** unpacku32() -- unpack a 32-bit unsigned from a char buffer (like ntohl()) -*/ -uint32 unpacku32(unsigned char *buf) -{ - return ((uint32)buf[0]<<24) | - ((uint32)buf[1]<<16) | - ((uint32)buf[2]<<8) | - buf[3]; -} - -/* -** unpacki64() -- unpack a 64-bit int from a char buffer (like ntohl()) -*/ -int64 unpacki64(unsigned char *buf) -{ - uint64 i2 = ((uint64)buf[0]<<56) | - ((uint64)buf[1]<<48) | - ((uint64)buf[2]<<40) | - ((uint64)buf[3]<<32) | - ((uint64)buf[4]<<24) | - ((uint64)buf[5]<<16) | - ((uint64)buf[6]<<8) | - buf[7]; - int64 i; - - // change unsigned numbers to signed - if (i2 <= 0x7fffffffffffffffull) { - i = i2; - } - else { - i = -1 -(int64)(0xffffffffffffffffull - i2); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("IN [%s] [%d] [%d] [%d] [%d] [%d] [%d] [%d] [%d] [" MG_I64_SPECIFIER "] [" MG_I64U_SPECIFIER "]\n",__FUNCTION__,buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],i,i2); - } - - return i; -} - -/* -** unpacku64() -- unpack a 64-bit unsigned from a char buffer (like ntohl()) -*/ -uint64 unpacku64(unsigned char *buf) -{ - return ((uint64)buf[0]<<56) | - ((uint64)buf[1]<<48) | - ((uint64)buf[2]<<40) | - ((uint64)buf[3]<<32) | - ((uint64)buf[4]<<24) | - ((uint64)buf[5]<<16) | - ((uint64)buf[6]<<8) | - buf[7]; -} - -/* -** pack() -- store data dictated by the format string in the buffer -** -** bits |signed unsigned float string -** -----+---------------------------------- -** 8 | c C -** 16 | h H f -** 32 | l L d -** 64 | q Q g -** - | s -** -** (16-bit unsigned length is automatically prepended to strings) -*/ - -unsigned int pack(unsigned char *buf, const char *format, ...) { - va_list ap; - - int8 c; // 8-bit - uint8 C; - - int16 h; // 16-bit - uint16 H; - - int32 l; // 32-bit - uint32 L; - - int64 q; // 64-bit - uint64 Q; - - float f; // floats - double d; - long double g; - unsigned long long int fhold; - - char *s; // strings - uint16 len; - - unsigned int size = 0; - - uint16 maxstrlen=0; - - unsigned char *bufStart = buf; - - va_start(ap, format); - - for(; *format != '\0'; format++) { - switch(*format) { - case 'c': // 8-bit - size += 1; - c = (int8)va_arg(ap, int); // promoted - *buf++ = (unsigned char)c; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("pack int8 = %d [%X] c = %d [%X] buf pos = %lu\n",*(buf-1),*(buf-1),c,c,(unsigned long)(buf - bufStart)); - break; - - case 'C': // 8-bit unsigned - size += 1; - C = (uint8)va_arg(ap, unsigned int); // promoted - *buf++ = (unsigned char)C; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("pack uint8 = %u [%X] C = %u [%X] buf pos = %lu\n",*(buf-1),*(buf-1),C,C,(unsigned long)(buf - bufStart)); - break; - - case 'h': // 16-bit - size += 2; - h = (int16)va_arg(ap, int); - packi16(buf, h); - buf += 2; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("pack int16 = %d [%X] h = %d [%X] buf pos = %lu\n",*(buf-2),*(buf-2),h,h,(unsigned long)(buf - bufStart)); - break; - - case 'H': // 16-bit unsigned - size += 2; - H = (uint16)va_arg(ap, unsigned int); - packi16(buf, H); - buf += 2; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("pack uint16 = %u [%X] H = %u [%X] buf pos = %lu\n",*(buf-2),*(buf-2),H,H,(unsigned long)(buf - bufStart)); - break; - - case 'l': // 32-bit - size += 4; - l = va_arg(ap, int32); - packi32(buf, l); - buf += 4; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("pack int32 = %d [%X] l = %d [%X] buf pos = %lu\n",*(buf-4),*(buf-4),l,l,(unsigned long)(buf - bufStart)); - break; - - case 'L': // 32-bit unsigned - size += 4; - L = va_arg(ap, uint32); - packi32(buf, L); - buf += 4; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("pack uint32 = %u [%X] L = %u [%X] buf pos = %lu\n",*(buf-4),*(buf-4),L,L,(unsigned long)(buf - bufStart)); - break; - - case 'q': // 64-bit - size += 8; - q = va_arg(ap, int64); - packi64(buf, q); - buf += 8; - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("pack int64 = " MG_I64_SPECIFIER " [%X] q = " MG_I64_SPECIFIER " [%lX] buf pos = %lu\n",(int64)*(buf-8),*(buf-8),q,q,(unsigned long)(buf - bufStart)); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("pack int64 = " MG_I64_SPECIFIER " [%X] q = " MG_I64_SPECIFIER " buf pos = %lu\n",(int64)*(buf-8),*(buf-8),q,(unsigned long)(buf - bufStart)); - break; - - case 'Q': // 64-bit unsigned - size += 8; - Q = va_arg(ap, uint64); - packi64(buf, Q); - buf += 8; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("pack uint64 = " MG_I64U_SPECIFIER " [%X] Q = " MG_I64U_SPECIFIER " buf pos = %lu\n",(uint64)*(buf-8),*(buf-8),Q,(unsigned long)(buf - bufStart)); - break; - - case 'f': // float-16 - size += 2; - f = (float)va_arg(ap, double); // promoted - fhold = pack754_16(f); // convert to IEEE 754 - packi16(buf, fhold); - buf += 2; - break; - - case 'd': // float-32 - size += 4; - d = va_arg(ap, double); - fhold = pack754_32(d); // convert to IEEE 754 - packi32(buf, fhold); - buf += 4; - break; - - case 'g': // float-64 - size += 8; - g = va_arg(ap, long double); - fhold = pack754_64(g); // convert to IEEE 754 - packi64(buf, fhold); - buf += 8; - break; - - case 's': // string - s = va_arg(ap, char*); - len = (uint16)strlen(s); - if (maxstrlen > 0 && len < maxstrlen) - len = maxstrlen - 1; - - size += len + 2; - packi16(buf, len); - buf += 2; - - memcpy(buf, s, len); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("pack string size = %d [%X] len = %d str [%s] buf pos = %lu\n",*(buf-2),*(buf-2),len,s,(unsigned long)(buf - bufStart)); - - buf += len; - break; - - default: - if (isdigit(*format)) { // track max str len - maxstrlen = maxstrlen * 10 + (*format-'0'); + // check sign and begin normalization + if (f < 0) { + sign = 1; fnorm = -f; + } else { + sign = 0; fnorm = f; } - break; + + // get the normalized form of f and track the exponent + shift = 0; + while (fnorm >= 2.0) { + fnorm /= 2.0; shift++; + } + while (fnorm < 1.0) { + fnorm *= 2.0; shift--; + } + fnorm = fnorm - 1.0; + + // calculate the binary form (non-float) of the significand data + significand = fnorm * ((1LL << significandbits) + 0.5f); + + // get the biased exponent + exp = (long long) shift + ((1 << (expbits - 1)) - 1); // shift + bias + + // return the final answer + return (sign << (bits - 1)) | (exp << (bits - expbits - 1)) | significand; } - if (!isdigit(*format)) maxstrlen = 0; + /* + ** unpack754() -- unpack a floating point number from IEEE-754 format + */ + long double unpack754(unsigned long long int i, unsigned bits, unsigned expbits) { + long double result; + long long shift; + unsigned bias; + unsigned significandbits = bits - expbits - 1; // -1 for sign bit - } + if (i == 0) return 0.0; - va_end(ap); + // pull the significand + result = (i&((1LL << significandbits) - 1)); // mask + result /= (1LL << significandbits); // convert back to float + result += 1.0f; // add the one back on - return size; -} - -/* -** unpack() -- unpack data dictated by the format string into the buffer -** -** bits |signed unsigned float string -** -----+---------------------------------- -** 8 | c C -** 16 | h H f -** 32 | l L d -** 64 | q Q g -** - | s -** -** (string is extracted based on its stored length, but 's' can be -** prepended with a max length) -*/ -unsigned int unpack(unsigned char *buf, const char *format, ...) { - va_list ap; - - int8 *c; // 8-bit - uint8 *C; - - int16 *h; // 16-bit - uint16 *H; - - int32 *l; // 32-bit - uint32 *L; - - int64 *q; // 64-bit - uint64 *Q; - - unsigned long long int fhold; - - char *s; - uint16 len, maxstrlen=0, count; - - unsigned int size = 0; - - unsigned char *bufStart = buf; - - va_start(ap, format); - - for(; *format != '\0'; format++) { - switch(*format) { - case 'c': // 8-bit - c = va_arg(ap, int8*); -// if (*buf <= 0x7f) { -// *c = *buf++; -// size += 1; -// } // re-sign -// else { -// *c = -1 - (unsigned char)(0xffu - *buf); -// } - *c = (int8)*buf++; - size += 1; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack int8 = %d [%X] c = %d [%X] buf pos = %lu\n",*(buf-1),*(buf-1),*c,*c,(unsigned long)(buf - bufStart)); - break; - - case 'C': // 8-bit unsigned - C = va_arg(ap, uint8*); - *C = (uint8)*buf++; - size += 1; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack uint8 = %u [%X] C = %u [%X] buf pos = %lu\n",*(buf-1),*(buf-1),*C,*C,(unsigned long)(buf - bufStart)); - break; - - case 'h': // 16-bit - h = va_arg(ap, int16*); - *h = unpacki16(buf); - buf += 2; - size += 2; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack int16 = %d [%X] h = %d [%X] buf pos = %lu\n",*(buf-2),*(buf-2),*h,*h,(unsigned long)(buf - bufStart)); - break; - - case 'H': // 16-bit unsigned - H = va_arg(ap, uint16*); - *H = unpacku16(buf); - buf += 2; - size += 2; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack uint16 = %u [%X] H = %u [%X] buf pos = %lu\n",*(buf-2),*(buf-2),*H,*H,(unsigned long)(buf - bufStart)); - break; - - case 'l': // 32-bit - l = va_arg(ap, int32*); - *l = unpacki32(buf); - buf += 4; - size += 4; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack int32 = %d [%X] l = %d [%X] buf pos = %lu\n",*(buf-4),*(buf-4),*l,*l,(unsigned long)(buf - bufStart)); - break; - - case 'L': // 32-bit unsigned - L = va_arg(ap, uint32*); - *L = unpacku32(buf); - buf += 4; - size += 4; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack uint32 = %u [%X] L = %u [%X] buf pos = %lu\n",*(buf-4),*(buf-4),*L,*L,(unsigned long)(buf - bufStart)); - break; - - case 'q': // 64-bit - q = va_arg(ap, int64*); - *q = unpacki64(buf); - buf += 8; - size += 8; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack int64 = " MG_I64_SPECIFIER " [%X] q = " MG_I64_SPECIFIER " buf pos = %lu\n",(int64)*(buf-8),*(buf-8),*q,(unsigned long)(buf - bufStart)); - break; - - case 'Q': // 64-bit unsigned - Q = va_arg(ap, uint64*); - *Q = unpacku64(buf); - buf += 8; - size += 8; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack uint64 = " MG_I64U_SPECIFIER " [%X] Q = " MG_I64U_SPECIFIER " buf pos = %lu\n",(uint64)*(buf-8),*(buf-8),*Q,(unsigned long)(buf - bufStart)); - break; - - case 'f': // float - { - float *f = va_arg(ap, float*); - fhold = unpacku16(buf); - *f = unpack754_16(fhold); - buf += 2; - size += 2; + // deal with the exponent + bias = (1 << (expbits - 1)) - 1; + shift = ((i >> significandbits)&((1LL << expbits) - 1)) - bias; + while (shift > 0) { + result *= 2.0; shift--; } - break; - - case 'd': // float-32 - { - double *d = va_arg(ap, double*); - fhold = unpacku32(buf); - *d = unpack754_32(fhold); - buf += 4; - size += 4; + while (shift < 0) { + result /= 2.0; shift++; } - break; - case 'g': // float-64 - { - long double *g = va_arg(ap, long double*); - fhold = unpacku64(buf); - *g = unpack754_64(fhold); - buf += 8; - size += 8; - } - break; + // sign it + result *= ((i >> (bits - 1)) & 1) ? -1.0 : 1.0; - case 's': // string - s = va_arg(ap, char*); - len = unpacku16(buf); - buf += 2; - if (maxstrlen > 0 && len > maxstrlen) - count = maxstrlen - 1; - else - count = len; - - memcpy(s, buf, count); - s[count] = '\0'; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack string size = %d [%X] count = %d len = %d str [%s] buf pos = %lu\n",*(buf-2),*(buf-2),count,len,s,(unsigned long)(buf - bufStart)); - - buf += len; - size += len; - break; - - default: - if (isdigit(*format)) { // track max str len - maxstrlen = maxstrlen * 10 + (*format-'0'); - } - break; + return result; } - if (!isdigit(*format)) maxstrlen = 0; - } + /* + ** packi16() -- store a 16-bit int into a char buffer (like htons()) + */ + void packi16(unsigned char *buf, uint16 i) { + *buf++ = i >> 8; *buf++ = i; + } - va_end(ap); + /* + ** packi32() -- store a 32-bit int into a char buffer (like htonl()) + */ + void packi32(unsigned char *buf, uint32 i) { + *buf++ = i >> 24; *buf++ = i >> 16; + *buf++ = i >> 8; *buf++ = i; + } - return size; -} + /* + ** packi64() -- store a 64-bit int into a char buffer (like htonl()) + */ + void packi64(unsigned char *buf, uint64 i) { + *buf++ = i >> 56; *buf++ = i >> 48; + *buf++ = i >> 40; *buf++ = i >> 32; + *buf++ = i >> 24; *buf++ = i >> 16; + *buf++ = i >> 8; *buf++ = i; + } + + /* + ** unpacki16() -- unpack a 16-bit int from a char buffer (like ntohs()) + */ + int16 unpacki16(unsigned char *buf) { + uint16 i2 = ((uint16) buf[0] << 8) | buf[1]; + int16 i; + + // change unsigned numbers to signed + if (i2 <= 0x7fffu) { + i = i2; + } else { + i = -1 - (uint16) (0xffffu - i2); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("IN [%s] [%d] [%d] [%d] [%u]\n", __FUNCTION__, buf[0], buf[1], i, i2); + } + + return i; + } + + /* + ** unpacku16() -- unpack a 16-bit unsigned from a char buffer (like ntohs()) + */ + uint16 unpacku16(unsigned char *buf) { + return ((uint16) buf[0] << 8) | buf[1]; + } + + /* + ** unpacki32() -- unpack a 32-bit int from a char buffer (like ntohl()) + */ + int32 unpacki32(unsigned char *buf) { + uint32 i2 = ((uint32) buf[0] << 24) | + ((uint32) buf[1] << 16) | + ((uint32) buf[2] << 8) | + buf[3]; + int32 i; + + // change unsigned numbers to signed + if (i2 <= 0x7fffffffu) { + i = i2; + } else { + i = -1 - (int32) (0xffffffffu - i2); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("IN [%s] [%d] [%d] [%d] [%d] [%d] [%u]\n", __FUNCTION__, buf[0], buf[1], buf[2], buf[3], i, i2); + } + + return i; + } + + /* + ** unpacku32() -- unpack a 32-bit unsigned from a char buffer (like ntohl()) + */ + uint32 unpacku32(unsigned char *buf) { + return ((uint32) buf[0] << 24) | + ((uint32) buf[1] << 16) | + ((uint32) buf[2] << 8) | + buf[3]; + } + + /* + ** unpacki64() -- unpack a 64-bit int from a char buffer (like ntohl()) + */ + int64 unpacki64(unsigned char *buf) { + uint64 i2 = ((uint64) buf[0] << 56) | + ((uint64) buf[1] << 48) | + ((uint64) buf[2] << 40) | + ((uint64) buf[3] << 32) | + ((uint64) buf[4] << 24) | + ((uint64) buf[5] << 16) | + ((uint64) buf[6] << 8) | + buf[7]; + int64 i; + + // change unsigned numbers to signed + if (i2 <= 0x7fffffffffffffffull) { + i = i2; + } else { + i = -1 - (int64) (0xffffffffffffffffull - i2); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("IN [%s] [%d] [%d] [%d] [%d] [%d] [%d] [%d] [%d] [" MG_I64_SPECIFIER "] [" MG_I64U_SPECIFIER "]\n", __FUNCTION__, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], i, i2); + } + + return i; + } + + /* + ** unpacku64() -- unpack a 64-bit unsigned from a char buffer (like ntohl()) + */ + uint64 unpacku64(unsigned char *buf) { + return ((uint64) buf[0] << 56) | + ((uint64) buf[1] << 48) | + ((uint64) buf[2] << 40) | + ((uint64) buf[3] << 32) | + ((uint64) buf[4] << 24) | + ((uint64) buf[5] << 16) | + ((uint64) buf[6] << 8) | + buf[7]; + } + + /* + ** pack() -- store data dictated by the format string in the buffer + ** + ** bits |signed unsigned float string + ** -----+---------------------------------- + ** 8 | c C + ** 16 | h H f + ** 32 | l L d + ** 64 | q Q g + ** - | s + ** + ** (16-bit unsigned length is automatically prepended to strings) + */ + + unsigned int pack(unsigned char *buf, const char *format, ...) { + va_list ap; + + int8 c; // 8-bit + uint8 C; + + int16 h; // 16-bit + uint16 H; + + int32 l; // 32-bit + uint32 L; + + int64 q; // 64-bit + uint64 Q; + + float f; // floats + double d; + long double g; + unsigned long long int fhold; + + char *s; // strings + uint16 len; + + unsigned int size = 0; + + uint16 maxstrlen = 0; + + unsigned char *bufStart = buf; + + va_start(ap, format); + + for (; *format != '\0'; format++) { + switch (*format) { + case 'c': // 8-bit + size += 1; + c = (int8) va_arg(ap, int); // promoted + *buf++ = (unsigned char) c; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("pack int8 = %d [%X] c = %d [%X] buf pos = %lu\n", *(buf - 1), *(buf - 1), c, c, (unsigned long) (buf - bufStart)); + break; + + case 'C': // 8-bit unsigned + size += 1; + C = (uint8) va_arg(ap, unsigned int); // promoted + *buf++ = (unsigned char) C; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("pack uint8 = %u [%X] C = %u [%X] buf pos = %lu\n", *(buf - 1), *(buf - 1), C, C, (unsigned long) (buf - bufStart)); + break; + + case 'h': // 16-bit + size += 2; + h = (int16) va_arg(ap, int); + packi16(buf, h); + buf += 2; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("pack int16 = %d [%X] h = %d [%X] buf pos = %lu\n", *(buf - 2), *(buf - 2), h, h, (unsigned long) (buf - bufStart)); + break; + + case 'H': // 16-bit unsigned + size += 2; + H = (uint16) va_arg(ap, unsigned int); + packi16(buf, H); + buf += 2; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("pack uint16 = %u [%X] H = %u [%X] buf pos = %lu\n", *(buf - 2), *(buf - 2), H, H, (unsigned long) (buf - bufStart)); + break; + + case 'l': // 32-bit + size += 4; + l = va_arg(ap, int32); + packi32(buf, l); + buf += 4; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("pack int32 = %d [%X] l = %d [%X] buf pos = %lu\n", *(buf - 4), *(buf - 4), l, l, (unsigned long) (buf - bufStart)); + break; + + case 'L': // 32-bit unsigned + size += 4; + L = va_arg(ap, uint32); + packi32(buf, L); + buf += 4; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("pack uint32 = %u [%X] L = %u [%X] buf pos = %lu\n", *(buf - 4), *(buf - 4), L, L, (unsigned long) (buf - bufStart)); + break; + + case 'q': // 64-bit + size += 8; + q = va_arg(ap, int64); + packi64(buf, q); + buf += 8; + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("pack int64 = " MG_I64_SPECIFIER " [%X] q = " MG_I64_SPECIFIER " [%lX] buf pos = %lu\n",(int64)*(buf-8),*(buf-8),q,q,(unsigned long)(buf - bufStart)); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("pack int64 = " MG_I64_SPECIFIER " [%X] q = " MG_I64_SPECIFIER " buf pos = %lu\n", (int64)*(buf - 8), *(buf - 8), q, (unsigned long) (buf - bufStart)); + break; + + case 'Q': // 64-bit unsigned + size += 8; + Q = va_arg(ap, uint64); + packi64(buf, Q); + buf += 8; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("pack uint64 = " MG_I64U_SPECIFIER " [%X] Q = " MG_I64U_SPECIFIER " buf pos = %lu\n", (uint64)*(buf - 8), *(buf - 8), Q, (unsigned long) (buf - bufStart)); + break; + + case 'f': // float-16 + size += 2; + f = (float) va_arg(ap, double); // promoted + fhold = pack754_16(f); // convert to IEEE 754 + packi16(buf, fhold); + buf += 2; + break; + + case 'd': // float-32 + size += 4; + d = va_arg(ap, double); + fhold = pack754_32(d); // convert to IEEE 754 + packi32(buf, fhold); + buf += 4; + break; + + case 'g': // float-64 + size += 8; + g = va_arg(ap, long double); + fhold = pack754_64(g); // convert to IEEE 754 + packi64(buf, fhold); + buf += 8; + break; + + case 's': // string + s = va_arg(ap, char*); + len = (uint16) strlen(s); + if (maxstrlen > 0 && len < maxstrlen) + len = maxstrlen - 1; + + size += len + 2; + packi16(buf, len); + buf += 2; + + memcpy(buf, s, len); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("pack string size = %d [%X] len = %d str [%s] buf pos = %lu\n", *(buf - 2), *(buf - 2), len, s, (unsigned long) (buf - bufStart)); + + buf += len; + break; + + default: + if (isdigit(*format)) { // track max str len + maxstrlen = maxstrlen * 10 + (*format - '0'); + } + break; + } + + if (!isdigit(*format)) maxstrlen = 0; + + } + + va_end(ap); + + return size; + } + + /* + ** unpack() -- unpack data dictated by the format string into the buffer + ** + ** bits |signed unsigned float string + ** -----+---------------------------------- + ** 8 | c C + ** 16 | h H f + ** 32 | l L d + ** 64 | q Q g + ** - | s + ** + ** (string is extracted based on its stored length, but 's' can be + ** prepended with a max length) + */ + unsigned int unpack(unsigned char *buf, const char *format, ...) { + va_list ap; + + int8 *c; // 8-bit + uint8 *C; + + int16 *h; // 16-bit + uint16 *H; + + int32 *l; // 32-bit + uint32 *L; + + int64 *q; // 64-bit + uint64 *Q; + + unsigned long long int fhold; + + char *s; + uint16 len, maxstrlen = 0, count; + + unsigned int size = 0; + + unsigned char *bufStart = buf; + + va_start(ap, format); + + for (; *format != '\0'; format++) { + switch (*format) { + case 'c': // 8-bit + c = va_arg(ap, int8*); + // if (*buf <= 0x7f) { + // *c = *buf++; + // size += 1; + // } // re-sign + // else { + // *c = -1 - (unsigned char)(0xffu - *buf); + // } + *c = (int8) *buf++; + size += 1; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack int8 = %d [%X] c = %d [%X] buf pos = %lu\n", *(buf - 1), *(buf - 1), *c, *c, (unsigned long) (buf - bufStart)); + break; + + case 'C': // 8-bit unsigned + C = va_arg(ap, uint8*); + *C = (uint8) *buf++; + size += 1; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack uint8 = %u [%X] C = %u [%X] buf pos = %lu\n", *(buf - 1), *(buf - 1), *C, *C, (unsigned long) (buf - bufStart)); + break; + + case 'h': // 16-bit + h = va_arg(ap, int16*); + *h = unpacki16(buf); + buf += 2; + size += 2; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack int16 = %d [%X] h = %d [%X] buf pos = %lu\n", *(buf - 2), *(buf - 2), *h, *h, (unsigned long) (buf - bufStart)); + break; + + case 'H': // 16-bit unsigned + H = va_arg(ap, uint16*); + *H = unpacku16(buf); + buf += 2; + size += 2; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack uint16 = %u [%X] H = %u [%X] buf pos = %lu\n", *(buf - 2), *(buf - 2), *H, *H, (unsigned long) (buf - bufStart)); + break; + + case 'l': // 32-bit + l = va_arg(ap, int32*); + *l = unpacki32(buf); + buf += 4; + size += 4; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack int32 = %d [%X] l = %d [%X] buf pos = %lu\n", *(buf - 4), *(buf - 4), *l, *l, (unsigned long) (buf - bufStart)); + break; + + case 'L': // 32-bit unsigned + L = va_arg(ap, uint32*); + *L = unpacku32(buf); + buf += 4; + size += 4; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack uint32 = %u [%X] L = %u [%X] buf pos = %lu\n", *(buf - 4), *(buf - 4), *L, *L, (unsigned long) (buf - bufStart)); + break; + + case 'q': // 64-bit + q = va_arg(ap, int64*); + *q = unpacki64(buf); + buf += 8; + size += 8; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack int64 = " MG_I64_SPECIFIER " [%X] q = " MG_I64_SPECIFIER " buf pos = %lu\n", (int64)*(buf - 8), *(buf - 8), *q, (unsigned long) (buf - bufStart)); + break; + + case 'Q': // 64-bit unsigned + Q = va_arg(ap, uint64*); + *Q = unpacku64(buf); + buf += 8; + size += 8; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack uint64 = " MG_I64U_SPECIFIER " [%X] Q = " MG_I64U_SPECIFIER " buf pos = %lu\n", (uint64)*(buf - 8), *(buf - 8), *Q, (unsigned long) (buf - bufStart)); + break; + + case 'f': // float + { + float *f = va_arg(ap, float*); + fhold = unpacku16(buf); + *f = unpack754_16(fhold); + buf += 2; + size += 2; + } + break; + + case 'd': // float-32 + { + double *d = va_arg(ap, double*); + fhold = unpacku32(buf); + *d = unpack754_32(fhold); + buf += 4; + size += 4; + } + break; + + case 'g': // float-64 + { + long double *g = va_arg(ap, long double*); + fhold = unpacku64(buf); + *g = unpack754_64(fhold); + buf += 8; + size += 8; + } + break; + + case 's': // string + s = va_arg(ap, char*); + len = unpacku16(buf); + buf += 2; + if (maxstrlen > 0 && len > maxstrlen) + count = maxstrlen - 1; + else + count = len; + + memcpy(s, buf, count); + s[count] = '\0'; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("unpack string size = %d [%X] count = %d len = %d str [%s] buf pos = %lu\n", *(buf - 2), *(buf - 2), count, len, s, (unsigned long) (buf - bufStart)); + + buf += len; + size += len; + break; + + default: + if (isdigit(*format)) { // track max str len + maxstrlen = maxstrlen * 10 + (*format - '0'); + } + break; + } + + if (!isdigit(*format)) maxstrlen = 0; + } + + va_end(ap); + + return size; + } #pragma pack(pop) -}} + } +} diff --git a/source/glest_game/network/network_protocol.h b/source/glest_game/network/network_protocol.h index eb23fb1bd..706e9ee98 100644 --- a/source/glest_game/network/network_protocol.h +++ b/source/glest_game/network/network_protocol.h @@ -12,11 +12,13 @@ #ifndef NETWORK_PROTOCOL_H_ #define NETWORK_PROTOCOL_H_ -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -unsigned int pack(unsigned char *buf, const char *format, ...); -unsigned int unpack(unsigned char *buf, const char *format, ...); + unsigned int pack(unsigned char *buf, const char *format, ...); + unsigned int unpack(unsigned char *buf, const char *format, ...); -}}; + } +}; #endif /* NETWORK_PROTOCOL_H_ */ diff --git a/source/glest_game/network/network_types.cpp b/source/glest_game/network/network_types.cpp index 62b73425a..4f0791335 100644 --- a/source/glest_game/network/network_types.cpp +++ b/source/glest_game/network/network_types.cpp @@ -20,186 +20,187 @@ using namespace Shared::Util; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class NetworkCommand -// ===================================================== + // ===================================================== + // class NetworkCommand + // ===================================================== -NetworkCommand::NetworkCommand(World *world, int networkCommandType, int unitId, - int commandTypeId, const Vec2i &pos, int unitTypeId, - int targetId, int facing, bool wantQueue, - CommandStateType commandStateType, - int commandStateValue, int unitCommandGroupId) - : networkCommandType(networkCommandType) - , unitId(unitId) - , unitTypeId(unitTypeId) - , commandTypeId(commandTypeId) - , positionX(pos.x) - , positionY(pos.y) - , wantQueue(wantQueue) - , commandStateType(commandStateType) - , commandStateValue(commandStateValue) - , unitCommandGroupId(unitCommandGroupId) - , unitFactionUnitCount(0) - , unitFactionIndex(0) { + NetworkCommand::NetworkCommand(World *world, int networkCommandType, int unitId, + int commandTypeId, const Vec2i &pos, int unitTypeId, + int targetId, int facing, bool wantQueue, + CommandStateType commandStateType, + int commandStateValue, int unitCommandGroupId) + : networkCommandType(networkCommandType) + , unitId(unitId) + , unitTypeId(unitTypeId) + , commandTypeId(commandTypeId) + , positionX(pos.x) + , positionY(pos.y) + , wantQueue(wantQueue) + , commandStateType(commandStateType) + , commandStateValue(commandStateValue) + , unitCommandGroupId(unitCommandGroupId) + , unitFactionUnitCount(0) + , unitFactionIndex(0) { - assert(targetId == -1 || facing == -1); - this->targetId = targetId >= 0 ? targetId : facing; - this->fromFactionIndex = world->getThisFactionIndex(); + assert(targetId == -1 || facing == -1); + this->targetId = targetId >= 0 ? targetId : facing; + this->fromFactionIndex = world->getThisFactionIndex(); - if(this->networkCommandType == nctGiveCommand) { - const Unit *unit= world->findUnitById(this->unitId); + if (this->networkCommandType == nctGiveCommand) { + const Unit *unit = world->findUnitById(this->unitId); - //validate unit - if(unit != NULL) { - this->unitFactionIndex = unit->getFaction()->getIndex(); - this->unitFactionUnitCount = unit->getFaction()->getUnitCount(); + //validate unit + if (unit != NULL) { + this->unitFactionIndex = unit->getFaction()->getIndex(); + this->unitFactionUnitCount = unit->getFaction()->getUnitCount(); - //const UnitType *unitType= world->findUnitTypeById(unit->getFaction()->getType(), this->unitTypeId); - const CommandType *ct = unit->getType()->findCommandTypeById(this->commandTypeId); - if(ct != NULL && ct->getClass() == ccBuild) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str()); - CardinalDir::assertDirValid(facing); - assert(targetId == -1); - } - } - } + //const UnitType *unitType= world->findUnitTypeById(unit->getFaction()->getType(), this->unitTypeId); + const CommandType *ct = unit->getType()->findCommandTypeById(this->commandTypeId); + if (ct != NULL && ct->getClass() == ccBuild) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] %s\n", __FILE__, __FUNCTION__, __LINE__, toString().c_str()); + CardinalDir::assertDirValid(facing); + assert(targetId == -1); + } + } + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Created NetworkCommand as follows:\n%s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str()); -} + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] Created NetworkCommand as follows:\n%s\n", __FILE__, __FUNCTION__, __LINE__, toString().c_str()); + } -void NetworkCommand::preprocessNetworkCommand(World *world) { - if(networkCommandType == nctGiveCommand) { - const Unit *unit= world->findUnitById(unitId); + void NetworkCommand::preprocessNetworkCommand(World *world) { + if (networkCommandType == nctGiveCommand) { + const Unit *unit = world->findUnitById(unitId); - //validate unit - if(unit != NULL) { - //const UnitType *unitType= world->findUnitTypeById(unit->getFaction()->getType(), unitTypeId); - const CommandType *ct = unit->getType()->findCommandTypeById(commandTypeId); - if(ct != NULL && ct->getClass() == ccBuild && targetId >= 0) { - CardinalDir::assertDirValid(targetId); - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] (unit == NULL) %s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str()); - } - } -} + //validate unit + if (unit != NULL) { + //const UnitType *unitType= world->findUnitTypeById(unit->getFaction()->getType(), unitTypeId); + const CommandType *ct = unit->getType()->findCommandTypeById(commandTypeId); + if (ct != NULL && ct->getClass() == ccBuild && targetId >= 0) { + CardinalDir::assertDirValid(targetId); + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] (unit == NULL) %s\n", __FILE__, __FUNCTION__, __LINE__, toString().c_str()); + } + } + } -string NetworkCommand::toString() const { - char szBuf[8096]=""; - snprintf(szBuf,8096,"networkCommandType = %d\nunitId = %d\ncommandTypeId = %d\npositionX = %d\npositionY = %d\nunitTypeId = %d\ntargetId = %d\nwantQueue= %d\nfromFactionIndex = %d\nunitFactionUnitCount = %d\nunitFactionIndex = %d, commandStateType = %d, commandStateValue = %d, unitCommandGroupId = %d", - networkCommandType,unitId,commandTypeId,positionX,positionY,unitTypeId,targetId,wantQueue, - fromFactionIndex,unitFactionUnitCount,unitFactionIndex,commandStateType,commandStateValue, - unitCommandGroupId); + string NetworkCommand::toString() const { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "networkCommandType = %d\nunitId = %d\ncommandTypeId = %d\npositionX = %d\npositionY = %d\nunitTypeId = %d\ntargetId = %d\nwantQueue= %d\nfromFactionIndex = %d\nunitFactionUnitCount = %d\nunitFactionIndex = %d, commandStateType = %d, commandStateValue = %d, unitCommandGroupId = %d", + networkCommandType, unitId, commandTypeId, positionX, positionY, unitTypeId, targetId, wantQueue, + fromFactionIndex, unitFactionUnitCount, unitFactionIndex, commandStateType, commandStateValue, + unitCommandGroupId); - string result = szBuf; - return result; -} + string result = szBuf; + return result; + } -void NetworkCommand::toEndian() { - networkCommandType = ::Shared::PlatformByteOrder::toCommonEndian(networkCommandType); - unitId = ::Shared::PlatformByteOrder::toCommonEndian(unitId); - unitTypeId = ::Shared::PlatformByteOrder::toCommonEndian(unitTypeId); - commandTypeId = ::Shared::PlatformByteOrder::toCommonEndian(commandTypeId); - positionX = ::Shared::PlatformByteOrder::toCommonEndian(positionX); - positionY = ::Shared::PlatformByteOrder::toCommonEndian(positionY); - targetId = ::Shared::PlatformByteOrder::toCommonEndian(targetId); - wantQueue = ::Shared::PlatformByteOrder::toCommonEndian(wantQueue); - fromFactionIndex = ::Shared::PlatformByteOrder::toCommonEndian(fromFactionIndex); - unitFactionUnitCount = ::Shared::PlatformByteOrder::toCommonEndian(unitFactionUnitCount); - unitFactionIndex = ::Shared::PlatformByteOrder::toCommonEndian(unitFactionIndex); - commandStateType = ::Shared::PlatformByteOrder::toCommonEndian(commandStateType); - commandStateValue = ::Shared::PlatformByteOrder::toCommonEndian(commandStateValue); - unitCommandGroupId = ::Shared::PlatformByteOrder::toCommonEndian(unitCommandGroupId); + void NetworkCommand::toEndian() { + networkCommandType = ::Shared::PlatformByteOrder::toCommonEndian(networkCommandType); + unitId = ::Shared::PlatformByteOrder::toCommonEndian(unitId); + unitTypeId = ::Shared::PlatformByteOrder::toCommonEndian(unitTypeId); + commandTypeId = ::Shared::PlatformByteOrder::toCommonEndian(commandTypeId); + positionX = ::Shared::PlatformByteOrder::toCommonEndian(positionX); + positionY = ::Shared::PlatformByteOrder::toCommonEndian(positionY); + targetId = ::Shared::PlatformByteOrder::toCommonEndian(targetId); + wantQueue = ::Shared::PlatformByteOrder::toCommonEndian(wantQueue); + fromFactionIndex = ::Shared::PlatformByteOrder::toCommonEndian(fromFactionIndex); + unitFactionUnitCount = ::Shared::PlatformByteOrder::toCommonEndian(unitFactionUnitCount); + unitFactionIndex = ::Shared::PlatformByteOrder::toCommonEndian(unitFactionIndex); + commandStateType = ::Shared::PlatformByteOrder::toCommonEndian(commandStateType); + commandStateValue = ::Shared::PlatformByteOrder::toCommonEndian(commandStateValue); + unitCommandGroupId = ::Shared::PlatformByteOrder::toCommonEndian(unitCommandGroupId); -} -void NetworkCommand::fromEndian() { - networkCommandType = ::Shared::PlatformByteOrder::fromCommonEndian(networkCommandType); - unitId = ::Shared::PlatformByteOrder::fromCommonEndian(unitId); - unitTypeId = ::Shared::PlatformByteOrder::fromCommonEndian(unitTypeId); - commandTypeId = ::Shared::PlatformByteOrder::fromCommonEndian(commandTypeId); - positionX = ::Shared::PlatformByteOrder::fromCommonEndian(positionX); - positionY = ::Shared::PlatformByteOrder::fromCommonEndian(positionY); - targetId = ::Shared::PlatformByteOrder::fromCommonEndian(targetId); - wantQueue = ::Shared::PlatformByteOrder::fromCommonEndian(wantQueue); - fromFactionIndex = ::Shared::PlatformByteOrder::fromCommonEndian(fromFactionIndex); - unitFactionUnitCount = ::Shared::PlatformByteOrder::fromCommonEndian(unitFactionUnitCount); - unitFactionIndex = ::Shared::PlatformByteOrder::fromCommonEndian(unitFactionIndex); - commandStateType = ::Shared::PlatformByteOrder::fromCommonEndian(commandStateType); - commandStateValue = ::Shared::PlatformByteOrder::fromCommonEndian(commandStateValue); - unitCommandGroupId = ::Shared::PlatformByteOrder::fromCommonEndian(unitCommandGroupId); -} + } + void NetworkCommand::fromEndian() { + networkCommandType = ::Shared::PlatformByteOrder::fromCommonEndian(networkCommandType); + unitId = ::Shared::PlatformByteOrder::fromCommonEndian(unitId); + unitTypeId = ::Shared::PlatformByteOrder::fromCommonEndian(unitTypeId); + commandTypeId = ::Shared::PlatformByteOrder::fromCommonEndian(commandTypeId); + positionX = ::Shared::PlatformByteOrder::fromCommonEndian(positionX); + positionY = ::Shared::PlatformByteOrder::fromCommonEndian(positionY); + targetId = ::Shared::PlatformByteOrder::fromCommonEndian(targetId); + wantQueue = ::Shared::PlatformByteOrder::fromCommonEndian(wantQueue); + fromFactionIndex = ::Shared::PlatformByteOrder::fromCommonEndian(fromFactionIndex); + unitFactionUnitCount = ::Shared::PlatformByteOrder::fromCommonEndian(unitFactionUnitCount); + unitFactionIndex = ::Shared::PlatformByteOrder::fromCommonEndian(unitFactionIndex); + commandStateType = ::Shared::PlatformByteOrder::fromCommonEndian(commandStateType); + commandStateValue = ::Shared::PlatformByteOrder::fromCommonEndian(commandStateValue); + unitCommandGroupId = ::Shared::PlatformByteOrder::fromCommonEndian(unitCommandGroupId); + } -XmlNode * NetworkCommand::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *networkCommandNode = rootNode->addChild("NetworkCommand"); + XmlNode * NetworkCommand::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *networkCommandNode = rootNode->addChild("NetworkCommand"); -// int16 networkCommandType; - networkCommandNode->addAttribute("networkCommandType",intToStr(networkCommandType), mapTagReplacements); -// int32 unitId; - networkCommandNode->addAttribute("unitId",intToStr(unitId), mapTagReplacements); -// int16 unitTypeId; - networkCommandNode->addAttribute("unitTypeId",intToStr(unitTypeId), mapTagReplacements); -// int16 commandTypeId; - networkCommandNode->addAttribute("commandTypeId",intToStr(commandTypeId), mapTagReplacements); -// int16 positionX; - networkCommandNode->addAttribute("positionX",intToStr(positionX), mapTagReplacements); -// int16 positionY; - networkCommandNode->addAttribute("positionY",intToStr(positionY), mapTagReplacements); -// int32 targetId; - networkCommandNode->addAttribute("targetId",intToStr(targetId), mapTagReplacements); -// int8 wantQueue; - networkCommandNode->addAttribute("wantQueue",intToStr(wantQueue), mapTagReplacements); -// int8 fromFactionIndex; - networkCommandNode->addAttribute("fromFactionIndex",intToStr(fromFactionIndex), mapTagReplacements); -// uint16 unitFactionUnitCount; - networkCommandNode->addAttribute("unitFactionUnitCount",intToStr(unitFactionUnitCount), mapTagReplacements); -// int8 unitFactionIndex; - networkCommandNode->addAttribute("unitFactionIndex",intToStr(unitFactionIndex), mapTagReplacements); -// int8 commandStateType; - networkCommandNode->addAttribute("commandStateType",intToStr(commandStateType), mapTagReplacements); -// int32 commandStateValue; - networkCommandNode->addAttribute("commandStateValue",intToStr(commandStateValue), mapTagReplacements); -// int32 unitCommandGroupId; - networkCommandNode->addAttribute("unitCommandGroupId",intToStr(unitCommandGroupId), mapTagReplacements); + // int16 networkCommandType; + networkCommandNode->addAttribute("networkCommandType", intToStr(networkCommandType), mapTagReplacements); + // int32 unitId; + networkCommandNode->addAttribute("unitId", intToStr(unitId), mapTagReplacements); + // int16 unitTypeId; + networkCommandNode->addAttribute("unitTypeId", intToStr(unitTypeId), mapTagReplacements); + // int16 commandTypeId; + networkCommandNode->addAttribute("commandTypeId", intToStr(commandTypeId), mapTagReplacements); + // int16 positionX; + networkCommandNode->addAttribute("positionX", intToStr(positionX), mapTagReplacements); + // int16 positionY; + networkCommandNode->addAttribute("positionY", intToStr(positionY), mapTagReplacements); + // int32 targetId; + networkCommandNode->addAttribute("targetId", intToStr(targetId), mapTagReplacements); + // int8 wantQueue; + networkCommandNode->addAttribute("wantQueue", intToStr(wantQueue), mapTagReplacements); + // int8 fromFactionIndex; + networkCommandNode->addAttribute("fromFactionIndex", intToStr(fromFactionIndex), mapTagReplacements); + // uint16 unitFactionUnitCount; + networkCommandNode->addAttribute("unitFactionUnitCount", intToStr(unitFactionUnitCount), mapTagReplacements); + // int8 unitFactionIndex; + networkCommandNode->addAttribute("unitFactionIndex", intToStr(unitFactionIndex), mapTagReplacements); + // int8 commandStateType; + networkCommandNode->addAttribute("commandStateType", intToStr(commandStateType), mapTagReplacements); + // int32 commandStateValue; + networkCommandNode->addAttribute("commandStateValue", intToStr(commandStateValue), mapTagReplacements); + // int32 unitCommandGroupId; + networkCommandNode->addAttribute("unitCommandGroupId", intToStr(unitCommandGroupId), mapTagReplacements); - return networkCommandNode; -} + return networkCommandNode; + } -void NetworkCommand::loadGame(const XmlNode *rootNode) { - const XmlNode *networkCommandNode = rootNode; + void NetworkCommand::loadGame(const XmlNode *rootNode) { + const XmlNode *networkCommandNode = rootNode; -// int16 networkCommandType; - networkCommandType = networkCommandNode->getAttribute("networkCommandType")->getIntValue(); -// int32 unitId; - unitId = networkCommandNode->getAttribute("unitId")->getIntValue(); -// int16 unitTypeId; - unitTypeId = networkCommandNode->getAttribute("unitTypeId")->getIntValue(); -// int16 commandTypeId; - commandTypeId = networkCommandNode->getAttribute("commandTypeId")->getIntValue(); -// int16 positionX; - positionX = networkCommandNode->getAttribute("positionX")->getIntValue(); -// int16 positionY; - positionY = networkCommandNode->getAttribute("positionY")->getIntValue(); -// int32 targetId; - targetId = networkCommandNode->getAttribute("targetId")->getIntValue(); -// int8 wantQueue; - wantQueue = networkCommandNode->getAttribute("wantQueue")->getIntValue(); -// int8 fromFactionIndex; - fromFactionIndex = networkCommandNode->getAttribute("fromFactionIndex")->getIntValue(); -// uint16 unitFactionUnitCount; - unitFactionUnitCount = networkCommandNode->getAttribute("unitFactionUnitCount")->getIntValue(); -// int8 unitFactionIndex; - unitFactionIndex = networkCommandNode->getAttribute("unitFactionIndex")->getIntValue(); -// int8 commandStateType; - commandStateType = networkCommandNode->getAttribute("commandStateType")->getIntValue(); -// int32 commandStateValue; - commandStateValue = networkCommandNode->getAttribute("commandStateValue")->getIntValue(); -// int32 unitCommandGroupId; - unitCommandGroupId = networkCommandNode->getAttribute("unitCommandGroupId")->getIntValue(); -} + // int16 networkCommandType; + networkCommandType = networkCommandNode->getAttribute("networkCommandType")->getIntValue(); + // int32 unitId; + unitId = networkCommandNode->getAttribute("unitId")->getIntValue(); + // int16 unitTypeId; + unitTypeId = networkCommandNode->getAttribute("unitTypeId")->getIntValue(); + // int16 commandTypeId; + commandTypeId = networkCommandNode->getAttribute("commandTypeId")->getIntValue(); + // int16 positionX; + positionX = networkCommandNode->getAttribute("positionX")->getIntValue(); + // int16 positionY; + positionY = networkCommandNode->getAttribute("positionY")->getIntValue(); + // int32 targetId; + targetId = networkCommandNode->getAttribute("targetId")->getIntValue(); + // int8 wantQueue; + wantQueue = networkCommandNode->getAttribute("wantQueue")->getIntValue(); + // int8 fromFactionIndex; + fromFactionIndex = networkCommandNode->getAttribute("fromFactionIndex")->getIntValue(); + // uint16 unitFactionUnitCount; + unitFactionUnitCount = networkCommandNode->getAttribute("unitFactionUnitCount")->getIntValue(); + // int8 unitFactionIndex; + unitFactionIndex = networkCommandNode->getAttribute("unitFactionIndex")->getIntValue(); + // int8 commandStateType; + commandStateType = networkCommandNode->getAttribute("commandStateType")->getIntValue(); + // int32 commandStateValue; + commandStateValue = networkCommandNode->getAttribute("commandStateValue")->getIntValue(); + // int32 unitCommandGroupId; + unitCommandGroupId = networkCommandNode->getAttribute("unitCommandGroupId")->getIntValue(); + } -}}//end namespace + } +}//end namespace diff --git a/source/glest_game/network/network_types.h b/source/glest_game/network/network_types.h index 224935821..17d37b9f7 100644 --- a/source/glest_game/network/network_types.h +++ b/source/glest_game/network/network_types.h @@ -13,8 +13,8 @@ #define _GLEST_GAME_NETWORKTYPES_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -32,137 +32,169 @@ using Shared::Platform::uint16; using Shared::Platform::int32; using Shared::Graphics::Vec2i; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -class World; -// ===================================================== -// class NetworkString -// ===================================================== + class World; + // ===================================================== + // class NetworkString + // ===================================================== #pragma pack(push, 1) -template -class NetworkString{ -private: - char buffer[S]; + template + class NetworkString { + private: + char buffer[S]; -public: - NetworkString() { - memset(buffer, 0, S); - } - NetworkString & operator=(const string& str) { - // ensure we don't have a buffer overflow - int maxBufferSize = sizeof(buffer) / sizeof(buffer[0]); - strncpy(buffer, str.c_str(), min(S-1,maxBufferSize-1)); + public: + NetworkString() { + memset(buffer, 0, S); + } + NetworkString & operator=(const string& str) { + // ensure we don't have a buffer overflow + int maxBufferSize = sizeof(buffer) / sizeof(buffer[0]); + strncpy(buffer, str.c_str(), min(S - 1, maxBufferSize - 1)); - return *this; - } - void nullTerminate() { - int maxBufferSize = sizeof(buffer) / sizeof(buffer[0]); - buffer[maxBufferSize-1] = '\0'; - } + return *this; + } + void nullTerminate() { + int maxBufferSize = sizeof(buffer) / sizeof(buffer[0]); + buffer[maxBufferSize - 1] = '\0'; + } - char *getBuffer() { return &buffer[0]; } - string getString() const { return (buffer[0] != '\0' ? buffer : ""); } -}; + char *getBuffer() { + return &buffer[0]; + } + string getString() const { + return (buffer[0] != '\0' ? buffer : ""); + } + }; #pragma pack(pop) -// ===================================================== -// class NetworkCommand -// ===================================================== + // ===================================================== + // class NetworkCommand + // ===================================================== -enum NetworkCommandType { - nctGiveCommand, - nctCancelCommand, - nctSetMeetingPoint, - nctSwitchTeam, - nctSwitchTeamVote, - nctPauseResume, - nctPlayerStatusChange, - nctDisconnectNetworkPlayer - //nctNetworkCommand -}; + enum NetworkCommandType { + nctGiveCommand, + nctCancelCommand, + nctSetMeetingPoint, + nctSwitchTeam, + nctSwitchTeamVote, + nctPauseResume, + nctPlayerStatusChange, + nctDisconnectNetworkPlayer + //nctNetworkCommand + }; -//enum NetworkCommandSubType { -// ncstRotateUnit -//}; + //enum NetworkCommandSubType { + // ncstRotateUnit + //}; #pragma pack(push, 1) -class NetworkCommand { + class NetworkCommand { -public: - NetworkCommand() { - networkCommandType=0; - unitId=0; - unitTypeId=0; - commandTypeId=0; - positionX=0; - positionY=0; - targetId=0; - wantQueue=0; - fromFactionIndex=0; - unitFactionUnitCount=0; - unitFactionIndex=0; - commandStateType=0; - commandStateValue=0; - unitCommandGroupId=0; - } + public: + NetworkCommand() { + networkCommandType = 0; + unitId = 0; + unitTypeId = 0; + commandTypeId = 0; + positionX = 0; + positionY = 0; + targetId = 0; + wantQueue = 0; + fromFactionIndex = 0; + unitFactionUnitCount = 0; + unitFactionIndex = 0; + commandStateType = 0; + commandStateValue = 0; + unitCommandGroupId = 0; + } - NetworkCommand( - World *world, - int networkCommandType, - int unitId, - int commandTypeId= -1, - const Vec2i &pos= Vec2i(0), - int unitTypeId= -1, - int targetId= -1, - int facing= -1, - bool wantQueue = false, - CommandStateType commandStateType = cst_None, - int commandTypeStateValue = -1, - int unitCommandGroupId = -1); + NetworkCommand( + World *world, + int networkCommandType, + int unitId, + int commandTypeId = -1, + const Vec2i &pos = Vec2i(0), + int unitTypeId = -1, + int targetId = -1, + int facing = -1, + bool wantQueue = false, + CommandStateType commandStateType = cst_None, + int commandTypeStateValue = -1, + int unitCommandGroupId = -1); - int16 networkCommandType; - int32 unitId; - int16 unitTypeId; - int16 commandTypeId; - int16 positionX; - int16 positionY; - int32 targetId; - int8 wantQueue; - int8 fromFactionIndex; - uint16 unitFactionUnitCount; - int8 unitFactionIndex; - int8 commandStateType; - int32 commandStateValue; - int32 unitCommandGroupId; + int16 networkCommandType; + int32 unitId; + int16 unitTypeId; + int16 commandTypeId; + int16 positionX; + int16 positionY; + int32 targetId; + int8 wantQueue; + int8 fromFactionIndex; + uint16 unitFactionUnitCount; + int8 unitFactionIndex; + int8 commandStateType; + int32 commandStateValue; + int32 unitCommandGroupId; - NetworkCommandType getNetworkCommandType() const {return static_cast(networkCommandType);} - int getUnitId() const {return unitId;} - int getCommandTypeId() const {return commandTypeId;} - Vec2i getPosition() const {return Vec2i(positionX, positionY);} - int getUnitTypeId() const {return unitTypeId;} - int getTargetId() const {return targetId;} - int getWantQueue() const {return wantQueue;} - int getFromFactionIndex() const {return fromFactionIndex;} - int getUnitFactionUnitCount() const {return unitFactionUnitCount;} - int getUnitFactionIndex() const {return unitFactionIndex;} + NetworkCommandType getNetworkCommandType() const { + return static_cast(networkCommandType); + } + int getUnitId() const { + return unitId; + } + int getCommandTypeId() const { + return commandTypeId; + } + Vec2i getPosition() const { + return Vec2i(positionX, positionY); + } + int getUnitTypeId() const { + return unitTypeId; + } + int getTargetId() const { + return targetId; + } + int getWantQueue() const { + return wantQueue; + } + int getFromFactionIndex() const { + return fromFactionIndex; + } + int getUnitFactionUnitCount() const { + return unitFactionUnitCount; + } + int getUnitFactionIndex() const { + return unitFactionIndex; + } - CommandStateType getCommandStateType() const {return static_cast(commandStateType);} - int getCommandStateValue() const {return commandStateValue;} + CommandStateType getCommandStateType() const { + return static_cast(commandStateType); + } + int getCommandStateValue() const { + return commandStateValue; + } - int getUnitCommandGroupId() const { return unitCommandGroupId; } + int getUnitCommandGroupId() const { + return unitCommandGroupId; + } - void preprocessNetworkCommand(World *world); - string toString() const; + void preprocessNetworkCommand(World *world); + string toString() const; - void toEndian(); - void fromEndian(); + void toEndian(); + void fromEndian(); - XmlNode * saveGame(XmlNode *rootNode); - void loadGame(const XmlNode *rootNode); -}; + XmlNode * saveGame(XmlNode *rootNode); + void loadGame(const XmlNode *rootNode); + }; #pragma pack(pop) -}}//end namespace + } +}//end namespace #endif diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index 42916dd3c..4325f1086 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -48,3263 +48,3222 @@ using namespace Shared::Platform; using namespace Shared::Util; using namespace Shared::Map; -namespace Glest { namespace Game { +namespace Glest { + namespace Game { -double maxFrameCountLagAllowed = 30; -double maxClientLagTimeAllowed = 25; -double maxFrameCountLagAllowedEver = 30; -double maxClientLagTimeAllowedEver = 25; + double maxFrameCountLagAllowed = 30; + double maxClientLagTimeAllowed = 25; + double maxFrameCountLagAllowedEver = 30; + double maxClientLagTimeAllowedEver = 25; -double warnFrameCountLagPercent = 0.50; -double LAG_CHECK_GRACE_PERIOD = 15; -double LAG_CHECK_INTERVAL_PERIOD = 4; -int GRACE_LAG_CTR_LIMIT = 5; + double warnFrameCountLagPercent = 0.50; + double LAG_CHECK_GRACE_PERIOD = 15; + double LAG_CHECK_INTERVAL_PERIOD = 4; + int GRACE_LAG_CTR_LIMIT = 5; -const int MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS = 15000; -const int MAX_CLIENT_PAUSE_FOR_LAG_COUNT = 3; -const int MAX_SLOT_THREAD_WAIT_TIME_MILLISECONDS = 1500; -const int MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS = 30; + const int MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS = 15000; + const int MAX_CLIENT_PAUSE_FOR_LAG_COUNT = 3; + const int MAX_SLOT_THREAD_WAIT_TIME_MILLISECONDS = 1500; + const int MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS = 30; -const int MAX_EMPTY_NETWORK_COMMAND_LIST_BROADCAST_INTERVAL_MILLISECONDS = 4000; + const int MAX_EMPTY_NETWORK_COMMAND_LIST_BROADCAST_INTERVAL_MILLISECONDS = 4000; -ServerInterface::ServerInterface(bool publishEnabled, ClientLagCallbackInterface *clientLagCallbackInterface) : GameNetworkInterface() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + ServerInterface::ServerInterface(bool publishEnabled, ClientLagCallbackInterface *clientLagCallbackInterface) : GameNetworkInterface() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - this->clientLagCallbackInterface = clientLagCallbackInterface; - this->clientsAutoPausedDueToLag = false; + this->clientLagCallbackInterface = clientLagCallbackInterface; + this->clientsAutoPausedDueToLag = false; - allowInGameConnections = false; - gameLaunched = false; + allowInGameConnections = false; + gameLaunched = false; - serverSynchAccessor = new Mutex(CODE_AT_LINE); - switchSetupRequestsSynchAccessor = new Mutex(CODE_AT_LINE); + serverSynchAccessor = new Mutex(CODE_AT_LINE); + switchSetupRequestsSynchAccessor = new Mutex(CODE_AT_LINE); - for(int index = 0; index < GameConstants::maxPlayers; ++index) { - slotAccessorMutexes[index] = new Mutex(CODE_AT_LINE); - } - masterServerThreadAccessor = new Mutex(CODE_AT_LINE); - textMessageQueueThreadAccessor = new Mutex(CODE_AT_LINE); - broadcastMessageQueueThreadAccessor = new Mutex(CODE_AT_LINE); - inBroadcastMessageThreadAccessor = new Mutex(CODE_AT_LINE); + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + slotAccessorMutexes[index] = new Mutex(CODE_AT_LINE); + } + masterServerThreadAccessor = new Mutex(CODE_AT_LINE); + textMessageQueueThreadAccessor = new Mutex(CODE_AT_LINE); + broadcastMessageQueueThreadAccessor = new Mutex(CODE_AT_LINE); + inBroadcastMessageThreadAccessor = new Mutex(CODE_AT_LINE); - serverSocketAdmin = NULL; - nextEventId = 1; - gameHasBeenInitiated = false; - exitServer = false; - gameSettingsUpdateCount = 0; - currentFrameCount = 0; - gameStartTime = 0; - resumeGameStartTime = 0; - publishToMasterserverThread = NULL; - lastMasterserverHeartbeatTime = 0; - needToRepublishToMasterserver = false; - ftpServer = NULL; - inBroadcastMessage = false; - lastGlobalLagCheckTime = 0; - masterserverAdminRequestLaunch = false; - lastListenerSlotCheckTime = 0; + serverSocketAdmin = NULL; + nextEventId = 1; + gameHasBeenInitiated = false; + exitServer = false; + gameSettingsUpdateCount = 0; + currentFrameCount = 0; + gameStartTime = 0; + resumeGameStartTime = 0; + publishToMasterserverThread = NULL; + lastMasterserverHeartbeatTime = 0; + needToRepublishToMasterserver = false; + ftpServer = NULL; + inBroadcastMessage = false; + lastGlobalLagCheckTime = 0; + masterserverAdminRequestLaunch = false; + lastListenerSlotCheckTime = 0; - // This is an admin port listening only on the localhost intended to - // give current connection status info + // This is an admin port listening only on the localhost intended to + // give current connection status info #ifndef __APPLE__ - try { - serverSocketAdmin = new ServerSocket(true); - serverSocketAdmin->setBlock(false); - serverSocketAdmin->setBindPort(Config::getInstance().getInt("ServerAdminPort", intToStr(GameConstants::serverAdminPort).c_str())); - serverSocketAdmin->setBindSpecificAddress(Config::getInstance().getString("ServerAdminBindAddress", "127.0.0.1")); - serverSocketAdmin->listen(5); - } - catch(const std::exception &ex) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] Warning Server admin port bind/listen error:\n%s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); + try { + serverSocketAdmin = new ServerSocket(true); + serverSocketAdmin->setBlock(false); + serverSocketAdmin->setBindPort(Config::getInstance().getInt("ServerAdminPort", intToStr(GameConstants::serverAdminPort).c_str())); + serverSocketAdmin->setBindSpecificAddress(Config::getInstance().getString("ServerAdminBindAddress", "127.0.0.1")); + serverSocketAdmin->listen(5); + } catch (const std::exception &ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Warning Server admin port bind/listen error:\n%s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s",szBuf); - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + } #endif - maxFrameCountLagAllowed = Config::getInstance().getInt("MaxFrameCountLagAllowed", intToStr(maxFrameCountLagAllowed).c_str()); - maxFrameCountLagAllowedEver = Config::getInstance().getInt("MaxFrameCountLagAllowedEver", intToStr(maxFrameCountLagAllowedEver).c_str()); - maxClientLagTimeAllowedEver = Config::getInstance().getInt("MaxClientLagTimeAllowedEver", intToStr(maxClientLagTimeAllowedEver).c_str()); - maxClientLagTimeAllowed = Config::getInstance().getInt("MaxClientLagTimeAllowed", intToStr(maxClientLagTimeAllowed).c_str()); - warnFrameCountLagPercent = Config::getInstance().getFloat("WarnFrameCountLagPercent", doubleToStr(warnFrameCountLagPercent).c_str()); + maxFrameCountLagAllowed = Config::getInstance().getInt("MaxFrameCountLagAllowed", intToStr(maxFrameCountLagAllowed).c_str()); + maxFrameCountLagAllowedEver = Config::getInstance().getInt("MaxFrameCountLagAllowedEver", intToStr(maxFrameCountLagAllowedEver).c_str()); + maxClientLagTimeAllowedEver = Config::getInstance().getInt("MaxClientLagTimeAllowedEver", intToStr(maxClientLagTimeAllowedEver).c_str()); + maxClientLagTimeAllowed = Config::getInstance().getInt("MaxClientLagTimeAllowed", intToStr(maxClientLagTimeAllowed).c_str()); + warnFrameCountLagPercent = Config::getInstance().getFloat("WarnFrameCountLagPercent", doubleToStr(warnFrameCountLagPercent).c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] maxFrameCountLagAllowed = %f, maxFrameCountLagAllowedEver = %f, maxClientLagTimeAllowed = %f, maxClientLagTimeAllowedEver = %f\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,maxFrameCountLagAllowed,maxFrameCountLagAllowedEver,maxClientLagTimeAllowed,maxClientLagTimeAllowedEver); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] maxFrameCountLagAllowed = %f, maxFrameCountLagAllowedEver = %f, maxClientLagTimeAllowed = %f, maxClientLagTimeAllowedEver = %f\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, maxFrameCountLagAllowed, maxFrameCountLagAllowedEver, maxClientLagTimeAllowed, maxClientLagTimeAllowedEver); - for(int index = 0; index < GameConstants::maxPlayers; ++index) { - slots[index] = NULL; - switchSetupRequests[index] = NULL; - } + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + slots[index] = NULL; + switchSetupRequests[index] = NULL; + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - serverSocket.setBlock(false); - serverSocket.setBindPort(Config::getInstance().getInt("PortServer", intToStr(GameConstants::serverPort).c_str())); + serverSocket.setBlock(false); + serverSocket.setBindPort(Config::getInstance().getInt("PortServer", intToStr(GameConstants::serverPort).c_str())); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - gameStatsThreadAccessor = new Mutex(CODE_AT_LINE); - gameStats = NULL; + gameStatsThreadAccessor = new Mutex(CODE_AT_LINE); + gameStats = NULL; - Config &config = Config::getInstance(); - string scenarioDir = ""; - vector pathList = config.getPathListForType(ptMaps,scenarioDir); - vector invalidMapList; - vector allMaps = MapPreview::findAllValidMaps(pathList,scenarioDir,false,true,&invalidMapList); - if (allMaps.empty()) { - //throw megaglest_runtime_error("No maps were found!"); - printf("No maps were found (srv)!\n"); - } - std::sort(allMaps.begin(),allMaps.end(),compareNonCaseSensitive); - vector results; - copy(allMaps.begin(), allMaps.end(), std::back_inserter(results)); - mapFiles = results; + Config &config = Config::getInstance(); + string scenarioDir = ""; + vector pathList = config.getPathListForType(ptMaps, scenarioDir); + vector invalidMapList; + vector allMaps = MapPreview::findAllValidMaps(pathList, scenarioDir, false, true, &invalidMapList); + if (allMaps.empty()) { + //throw megaglest_runtime_error("No maps were found!"); + printf("No maps were found (srv)!\n"); + } + std::sort(allMaps.begin(), allMaps.end(), compareNonCaseSensitive); + vector results; + copy(allMaps.begin(), allMaps.end(), std::back_inserter(results)); + mapFiles = results; - //player Sorted maps - //////////////////// - for(unsigned int i = 0; i < GameConstants::maxPlayers+1; ++i) { - playerSortedMaps[i].clear(); - } + //player Sorted maps + //////////////////// + for (unsigned int i = 0; i < GameConstants::maxPlayers + 1; ++i) { + playerSortedMaps[i].clear(); + } - // at index=0 fill in the whole list - copy(mapFiles.begin(), mapFiles.end(), std::back_inserter(playerSortedMaps[0])); + // at index=0 fill in the whole list + copy(mapFiles.begin(), mapFiles.end(), std::back_inserter(playerSortedMaps[0])); - MapInfo mapInfo; - // fill playerSortedMaps according to map player count - for(int i= 0; i < (int)mapFiles.size(); i++){// fetch info and put map in right list - //printf("mapFiles.at(i) %s allMaps.at[i] %s\n",mapFiles[i].c_str(),allMaps.at(i).c_str()); - MapPreview::loadMapInfo(Config::getMapPath(mapFiles.at(i)), &mapInfo, "MaxPlayers","Size",true) ; - playerSortedMaps[mapInfo.players].push_back(mapFiles.at(i)); - } - /////////////////// + MapInfo mapInfo; + // fill playerSortedMaps according to map player count + for (int i = 0; i < (int) mapFiles.size(); i++) {// fetch info and put map in right list + //printf("mapFiles.at(i) %s allMaps.at[i] %s\n",mapFiles[i].c_str(),allMaps.at(i).c_str()); + MapPreview::loadMapInfo(Config::getMapPath(mapFiles.at(i)), &mapInfo, "MaxPlayers", "Size", true); + playerSortedMaps[mapInfo.players].push_back(mapFiles.at(i)); + } + /////////////////// - results.clear(); - findDirs(config.getPathListForType(ptTilesets), results); - if (results.empty()) { - //throw megaglest_runtime_error("No tile-sets were found!"); - printf("No tile-sets were found (srv)!"); - } - tilesetFiles = results; + results.clear(); + findDirs(config.getPathListForType(ptTilesets), results); + if (results.empty()) { + //throw megaglest_runtime_error("No tile-sets were found!"); + printf("No tile-sets were found (srv)!"); + } + tilesetFiles = results; - results.clear(); - findDirs(config.getPathListForType(ptTechs), results); - if(results.empty()) { - //throw megaglest_runtime_error("No tech-trees were found!"); - printf("No tech-trees were found (srv)!\n"); - } - techTreeFiles = results; + results.clear(); + findDirs(config.getPathListForType(ptTechs), results); + if (results.empty()) { + //throw megaglest_runtime_error("No tech-trees were found!"); + printf("No tech-trees were found (srv)!\n"); + } + techTreeFiles = results; - if(Config::getInstance().getBool("EnableFTPServer","true") == true) { - std::pair mapsPath; - vector pathList = Config::getInstance().getPathListForType(ptMaps); - if(pathList.empty() == false) { - mapsPath.first = pathList[0]; - if(pathList.size() > 1) { - mapsPath.second = pathList[1]; + if (Config::getInstance().getBool("EnableFTPServer", "true") == true) { + std::pair mapsPath; + vector pathList = Config::getInstance().getPathListForType(ptMaps); + if (pathList.empty() == false) { + mapsPath.first = pathList[0]; + if (pathList.size() > 1) { + mapsPath.second = pathList[1]; + } + } + + std::pair tilesetsPath; + vector tilesetsList = Config::getInstance().getPathListForType(ptTilesets); + if (tilesetsList.empty() == false) { + tilesetsPath.first = tilesetsList[0]; + if (tilesetsList.size() > 1) { + tilesetsPath.second = tilesetsList[1]; + } + } + + std::pair techtreesPath; + vector techtreesList = Config::getInstance().getPathListForType(ptTechs); + if (techtreesList.empty() == false) { + techtreesPath.first = techtreesList[0]; + if (techtreesList.size() > 1) { + techtreesPath.second = techtreesList[1]; + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + int portNumber = Config::getInstance().getInt("FTPServerPort", intToStr(ServerSocket::getFTPServerPort()).c_str()); + ServerSocket::setFTPServerPort(portNumber); + //printf("In [%s::%s] portNumber = %d ServerSocket::getFTPServerPort() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,portNumber,ServerSocket::getFTPServerPort()); + + bool allowInternetTilesetFileTransfers = Config::getInstance().getBool("EnableFTPServerInternetTilesetXfer", "true"); + bool allowInternetTechtreeFileTransfers = Config::getInstance().getBool("EnableFTPServerInternetTechtreeXfer", "true"); + + // Get path to temp files + string tempFilePath = "temp/"; + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { + tempFilePath = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + tempFilePath; + } else { + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + tempFilePath = userData + tempFilePath; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Temp files path [%s]\n", tempFilePath.c_str()); + + ftpServer = new FTPServerThread(mapsPath, tilesetsPath, techtreesPath, + publishEnabled, allowInternetTilesetFileTransfers, + allowInternetTechtreeFileTransfers, portNumber, GameConstants::maxPlayers, + this, tempFilePath); + ftpServer->start(); + } + + if (publishToMasterserverThread == NULL) { + if (needToRepublishToMasterserver == true || GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); + publishToMasterserverThread = new SimpleTaskThread(this, 0, 125); + publishToMasterserverThread->setUniqueID(mutexOwnerId); + publishToMasterserverThread->start(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, needToRepublishToMasterserver); + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void ServerInterface::setPublishEnabled(bool value) { + if (ftpServer != NULL) { + ftpServer->setInternetEnabled(value); } } - std::pair tilesetsPath; - vector tilesetsList = Config::getInstance().getPathListForType(ptTilesets); - if(tilesetsList.empty() == false) { - tilesetsPath.first = tilesetsList[0]; - if(tilesetsList.size() > 1) { - tilesetsPath.second = tilesetsList[1]; - } - } + void ServerInterface::shutdownMasterserverPublishThread() { + MutexSafeWrapper safeMutex(masterServerThreadAccessor, CODE_AT_LINE); - std::pair techtreesPath; - vector techtreesList = Config::getInstance().getPathListForType(ptTechs); - if(techtreesList.empty() == false) { - techtreesPath.first = techtreesList[0]; - if(techtreesList.size() > 1) { - techtreesPath.second = techtreesList[1]; - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - int portNumber = Config::getInstance().getInt("FTPServerPort",intToStr(ServerSocket::getFTPServerPort()).c_str()); - ServerSocket::setFTPServerPort(portNumber); - //printf("In [%s::%s] portNumber = %d ServerSocket::getFTPServerPort() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,portNumber,ServerSocket::getFTPServerPort()); - - bool allowInternetTilesetFileTransfers = Config::getInstance().getBool("EnableFTPServerInternetTilesetXfer","true"); - bool allowInternetTechtreeFileTransfers = Config::getInstance().getBool("EnableFTPServerInternetTechtreeXfer","true"); - - // Get path to temp files - string tempFilePath = "temp/"; - if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { - tempFilePath = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + tempFilePath; - } - else { - string userData = config.getString("UserData_Root",""); - if(userData != "") { - endPathWithSlash(userData); - } - tempFilePath = userData + tempFilePath; - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Temp files path [%s]\n",tempFilePath.c_str()); - - ftpServer = new FTPServerThread(mapsPath,tilesetsPath,techtreesPath, - publishEnabled,allowInternetTilesetFileTransfers, - allowInternetTechtreeFileTransfers,portNumber,GameConstants::maxPlayers, - this,tempFilePath); - ftpServer->start(); - } - - if(publishToMasterserverThread == NULL) { - if(needToRepublishToMasterserver == true || GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); - publishToMasterserverThread = new SimpleTaskThread(this,0,125); - publishToMasterserverThread->setUniqueID(mutexOwnerId); - publishToMasterserverThread->start(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,needToRepublishToMasterserver); - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void ServerInterface::setPublishEnabled(bool value) { - if(ftpServer != NULL) { - ftpServer->setInternetEnabled(value); - } -} - -void ServerInterface::shutdownMasterserverPublishThread() { - MutexSafeWrapper safeMutex(masterServerThreadAccessor,CODE_AT_LINE); - - if(publishToMasterserverThread != NULL) { - time_t elapsed = time(NULL); - publishToMasterserverThread->signalQuit(); - for(;publishToMasterserverThread->canShutdown(false) == false && - difftime((long int)time(NULL),elapsed) <= 15;) { - //sleep(150); - } - if(publishToMasterserverThread->canShutdown(true)) { - delete publishToMasterserverThread; - publishToMasterserverThread = NULL; - } - } -} - -ServerInterface::~ServerInterface() { - //printf("===> Destructor for ServerInterface\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - masterController.clearSlaves(true); - exitServer = true; - for(int index = 0; index < GameConstants::maxPlayers; ++index) { - if(slots[index] != NULL) { - MutexSafeWrapper safeMutex(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - delete slots[index]; - slots[index] = NULL; - } - - if(switchSetupRequests[index] != NULL) { - delete switchSetupRequests[index]; - switchSetupRequests[index] = NULL; - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - close(); - shutdownFTPServer(); - shutdownMasterserverPublishThread(); - - lastMasterserverHeartbeatTime = 0; - if(needToRepublishToMasterserver == true) { - simpleTask(NULL,NULL); - } - - for(int index = 0; index < GameConstants::maxPlayers; ++index) { - delete slotAccessorMutexes[index]; - slotAccessorMutexes[index] = NULL; - } - - delete textMessageQueueThreadAccessor; - textMessageQueueThreadAccessor = NULL; - - delete broadcastMessageQueueThreadAccessor; - broadcastMessageQueueThreadAccessor = NULL; - - delete inBroadcastMessageThreadAccessor; - inBroadcastMessageThreadAccessor = NULL; - - delete serverSynchAccessor; - serverSynchAccessor = NULL; - - delete masterServerThreadAccessor; - masterServerThreadAccessor = NULL; - - delete serverSocketAdmin; - serverSocketAdmin = NULL; - - for(int index = 0; index < (int)broadcastMessageQueue.size(); ++index) { - pair &item = broadcastMessageQueue[index]; - if(item.first != NULL) { - delete item.first; - } - item.first = NULL; - } - broadcastMessageQueue.clear(); - - delete switchSetupRequestsSynchAccessor; - switchSetupRequestsSynchAccessor = NULL; - - delete gameStatsThreadAccessor; - gameStatsThreadAccessor = NULL; - - delete gameStats; - gameStats = NULL; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -SwitchSetupRequest ** ServerInterface::getSwitchSetupRequests() { - MutexSafeWrapper safeMutex(switchSetupRequestsSynchAccessor,CODE_AT_LINE); - return &switchSetupRequests[0]; -} - -SwitchSetupRequest * ServerInterface::getSwitchSetupRequests(int index) { - MutexSafeWrapper safeMutex(switchSetupRequestsSynchAccessor,CODE_AT_LINE); - return switchSetupRequests[index]; -} - -void ServerInterface::setSwitchSetupRequests(int index,SwitchSetupRequest *ptr) { - MutexSafeWrapper safeMutex(switchSetupRequestsSynchAccessor,CODE_AT_LINE); - switchSetupRequests[index] = ptr; -} - -int ServerInterface::isValidClientType(uint32 clientIp) { - int result = 0; - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - MutexSafeWrapper safeMutex(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - if(slots[index] != NULL) { - Socket *socket = slots[index]->getSocket(); - if(socket != NULL) { - uint32 slotIp = socket->getConnectedIPAddress(socket->getIpAddress()); - if(slotIp == clientIp) { - result = 1; - break; + if (publishToMasterserverThread != NULL) { + time_t elapsed = time(NULL); + publishToMasterserverThread->signalQuit(); + for (; publishToMasterserverThread->canShutdown(false) == false && + difftime((long int) time(NULL), elapsed) <= 15;) { + //sleep(150); + } + if (publishToMasterserverThread->canShutdown(true)) { + delete publishToMasterserverThread; + publishToMasterserverThread = NULL; } } } - } - return result; -} -int ServerInterface::isClientAllowedToGetFile(uint32 clientIp, const char *username, const char *filename) { - int result = 1; + ServerInterface::~ServerInterface() { + //printf("===> Destructor for ServerInterface\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - if( username != NULL && - strlen(username) > 0 && - filename != NULL && - strlen(filename) > 0) { - string user = username; - string file = filename; + masterController.clearSlaves(true); + exitServer = true; + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + if (slots[index] != NULL) { + MutexSafeWrapper safeMutex(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + delete slots[index]; + slots[index] = NULL; + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d username [%s] file [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,username,filename); - - if(StartsWith(user,"tilesets") == true && EndsWith(file,"7z") == false) { - if(Config::getInstance().getBool("DisableFTPServerXferUncompressedTilesets","false") == true) { - result = 0; + if (switchSetupRequests[index] != NULL) { + delete switchSetupRequests[index]; + switchSetupRequests[index] = NULL; + } } - else { - char szIP[100] = ""; - Ip::Inet_NtoA(clientIp,szIP); - string clientIP = szIP; - std::vector serverList = Socket::getLocalIPAddressList(); - result = 0; - for(unsigned int index = 0; index < serverList.size(); ++index) { - string serverIP = serverList[index]; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + close(); + shutdownFTPServer(); + shutdownMasterserverPublishThread(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d clientIP [%s] serverIP [%s] %d / %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,clientIP.c_str(),serverIP.c_str(),index,serverList.size()); + lastMasterserverHeartbeatTime = 0; + if (needToRepublishToMasterserver == true) { + simpleTask(NULL, NULL); + } - vector clientTokens; - Tokenize(clientIP,clientTokens,"."); + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + delete slotAccessorMutexes[index]; + slotAccessorMutexes[index] = NULL; + } - vector serverTokens; - Tokenize(serverIP,serverTokens,"."); + delete textMessageQueueThreadAccessor; + textMessageQueueThreadAccessor = NULL; - if(clientTokens.size() == 4 && serverTokens.size() == 4) { - if( clientTokens[0] == serverTokens[0] || - clientTokens[1] == serverTokens[1] || - clientTokens[2] == serverTokens[2]) { + delete broadcastMessageQueueThreadAccessor; + broadcastMessageQueueThreadAccessor = NULL; + + delete inBroadcastMessageThreadAccessor; + inBroadcastMessageThreadAccessor = NULL; + + delete serverSynchAccessor; + serverSynchAccessor = NULL; + + delete masterServerThreadAccessor; + masterServerThreadAccessor = NULL; + + delete serverSocketAdmin; + serverSocketAdmin = NULL; + + for (int index = 0; index < (int) broadcastMessageQueue.size(); ++index) { + pair &item = broadcastMessageQueue[index]; + if (item.first != NULL) { + delete item.first; + } + item.first = NULL; + } + broadcastMessageQueue.clear(); + + delete switchSetupRequestsSynchAccessor; + switchSetupRequestsSynchAccessor = NULL; + + delete gameStatsThreadAccessor; + gameStatsThreadAccessor = NULL; + + delete gameStats; + gameStats = NULL; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + SwitchSetupRequest ** ServerInterface::getSwitchSetupRequests() { + MutexSafeWrapper safeMutex(switchSetupRequestsSynchAccessor, CODE_AT_LINE); + return &switchSetupRequests[0]; + } + + SwitchSetupRequest * ServerInterface::getSwitchSetupRequests(int index) { + MutexSafeWrapper safeMutex(switchSetupRequestsSynchAccessor, CODE_AT_LINE); + return switchSetupRequests[index]; + } + + void ServerInterface::setSwitchSetupRequests(int index, SwitchSetupRequest *ptr) { + MutexSafeWrapper safeMutex(switchSetupRequestsSynchAccessor, CODE_AT_LINE); + switchSetupRequests[index] = ptr; + } + + int ServerInterface::isValidClientType(uint32 clientIp) { + int result = 0; + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + MutexSafeWrapper safeMutex(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + if (slots[index] != NULL) { + Socket *socket = slots[index]->getSocket(); + if (socket != NULL) { + uint32 slotIp = socket->getConnectedIPAddress(socket->getIpAddress()); + if (slotIp == clientIp) { result = 1; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d clientIP [%s] IS NOT BLOCKED\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,clientIP.c_str()); - break; } } } } + return result; } - } - return result; -} -void ServerInterface::addClientToServerIPAddress(uint32 clientIp, uint32 ServerIp) { - FTPServerThread::addClientToServerIPAddress(clientIp, ServerIp); -} + int ServerInterface::isClientAllowedToGetFile(uint32 clientIp, const char *username, const char *filename) { + int result = 1; -void ServerInterface::addSlot(int playerIndex) { - //printf("Adding slot for playerIndex = %d, serverSocket.isPortBound() = %d\n",playerIndex,serverSocket.isPortBound()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (username != NULL && + strlen(username) > 0 && + filename != NULL && + strlen(filename) > 0) { + string user = username; + string file = filename; - if(playerIndex < 0 || playerIndex >= GameConstants::maxPlayers) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] playerIndex is invalid = %d",extractFileFromDirectoryPath(extractFileFromDirectoryPath(__FILE__).c_str()).c_str(),__FUNCTION__,__LINE__,playerIndex); - throw megaglest_runtime_error(szBuf); - } - MutexSafeWrapper safeMutex(serverSynchAccessor,CODE_AT_LINE); - if(serverSocketAdmin != NULL && serverSocketAdmin->isSocketValid() == false) { - serverSocketAdmin->listen(5); - } - if(serverSocket.isPortBound() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - serverSocket.bind(serverSocket.getBindPort()); - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d username [%s] file [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, username, filename); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (StartsWith(user, "tilesets") == true && EndsWith(file, "7z") == false) { + if (Config::getInstance().getBool("DisableFTPServerXferUncompressedTilesets", "false") == true) { + result = 0; + } else { + char szIP[100] = ""; + Ip::Inet_NtoA(clientIp, szIP); + string clientIP = szIP; + std::vector serverList = Socket::getLocalIPAddressList(); - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[playerIndex],CODE_AT_LINE_X(playerIndex)); + result = 0; + for (unsigned int index = 0; index < serverList.size(); ++index) { + string serverIP = serverList[index]; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d clientIP [%s] serverIP [%s] %d / %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, clientIP.c_str(), serverIP.c_str(), index, serverList.size()); - ConnectionSlot *slot = slots[playerIndex]; - if(slot != NULL) { - slots[playerIndex] = NULL; - } - slots[playerIndex] = new ConnectionSlot(this, playerIndex); + vector clientTokens; + Tokenize(clientIP, clientTokens, "."); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + vector serverTokens; + Tokenize(serverIP, serverTokens, "."); - safeMutexSlot.ReleaseLock(); - delete slot; + if (clientTokens.size() == 4 && serverTokens.size() == 4) { + if (clientTokens[0] == serverTokens[0] || + clientTokens[1] == serverTokens[1] || + clientTokens[2] == serverTokens[2]) { + result = 1; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d clientIP [%s] IS NOT BLOCKED\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, clientIP.c_str()); - safeMutex.ReleaseLock(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - updateListen(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void ServerInterface::removeSlot(int playerIndex, int lockedSlotIndex) { - //printf("Removing slot for playerIndex = %d, serverSocket.isPortBound() = %d\n",playerIndex,serverSocket.isPortBound()); - - if(playerIndex < 0 || playerIndex >= GameConstants::maxPlayers) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] playerIndex is invalid = %d",extractFileFromDirectoryPath(extractFileFromDirectoryPath(__FILE__).c_str()).c_str(),__FUNCTION__,__LINE__,playerIndex); - throw megaglest_runtime_error(szBuf); - } - - Lang &lang= Lang::getInstance(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); - - MutexSafeWrapper safeMutex(serverSynchAccessor,CODE_AT_LINE); - MutexSafeWrapper safeMutexSlot(NULL,CODE_AT_LINE_X(playerIndex)); - if(playerIndex != lockedSlotIndex) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); - safeMutexSlot.setMutex(slotAccessorMutexes[playerIndex],CODE_AT_LINE_X(playerIndex)); - } - - vector msgList; - ConnectionSlot *slot = slots[playerIndex]; - bool notifyDisconnect = false; - const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); - if(slot != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); - - if(slot->getLastReceiveCommandListTime() > 0) { - char szBuf[4096] = ""; - - for(unsigned int index = 0; index < languageList.size(); ++index) { - string msgTemplate = "Player %s, disconnected from the game."; - if(lang.hasString("PlayerDisconnected",languageList[index]) == true) { - msgTemplate = lang.getString("PlayerDisconnected",languageList[index]); - } -#ifdef WIN32 - _snprintf(szBuf,4095,msgTemplate.c_str(),slot->getName().c_str()); -#else - snprintf(szBuf,4095,msgTemplate.c_str(),slot->getName().c_str()); -#endif - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,szBuf); - - msgList.push_back(szBuf); - } - - notifyDisconnect = true; - } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); - - slots[playerIndex]= NULL; - safeMutexSlot.ReleaseLock(); - safeMutex.ReleaseLock(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); - - if(slot != NULL) slot->close(); - delete slot; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); - - updateListen(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); - - if(notifyDisconnect == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); - - for(unsigned int index = 0; index < languageList.size(); ++index) { - bool localEcho = lang.isLanguageLocal(languageList[index]); - queueTextMessage(msgList[index],-1, localEcho, languageList[index]); - } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,playerIndex,lockedSlotIndex); -} - -bool ServerInterface::switchSlot(int fromPlayerIndex, int toPlayerIndex) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - bool result = false; - - //printf("#1 Server is switching slots\n"); - - if(fromPlayerIndex < 0 || fromPlayerIndex >= GameConstants::maxPlayers) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] fromPlayerIndex is invalid = %d",extractFileFromDirectoryPath(extractFileFromDirectoryPath(__FILE__).c_str()).c_str(),__FUNCTION__,__LINE__,fromPlayerIndex); - throw megaglest_runtime_error(szBuf); - } - - if(toPlayerIndex < 0 || toPlayerIndex >= GameConstants::maxPlayers) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] toPlayerIndex is invalid = %d",extractFileFromDirectoryPath(extractFileFromDirectoryPath(__FILE__).c_str()).c_str(),__FUNCTION__,__LINE__,toPlayerIndex); - throw megaglest_runtime_error(szBuf); - } - - if(fromPlayerIndex == toPlayerIndex) { - return false; - } - - MutexSafeWrapper safeMutex(serverSynchAccessor,CODE_AT_LINE); - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[fromPlayerIndex],CODE_AT_LINE_X(fromPlayerIndex)); - MutexSafeWrapper safeMutexSlot2(slotAccessorMutexes[toPlayerIndex],CODE_AT_LINE_X(toPlayerIndex)); - - //printf("#1a Server is switching slots\n"); - - if(slots[toPlayerIndex] != NULL && - slots[toPlayerIndex]->hasValidSocketId() == false) { - - //printf("#2 Server is switching slots\n"); - - slots[fromPlayerIndex]->setPlayerIndex(toPlayerIndex); - slots[toPlayerIndex]->setPlayerIndex(fromPlayerIndex); - ConnectionSlot *tmp = slots[toPlayerIndex]; - slots[toPlayerIndex] = slots[fromPlayerIndex]; - slots[fromPlayerIndex] = tmp; - - safeMutex.ReleaseLock(); - - PlayerIndexMessage playerIndexMessage(toPlayerIndex); - slots[toPlayerIndex]->sendMessage(&playerIndexMessage); - - //slots[fromPlayerIndex]->resetJoinGameInProgressFlags(); - //slots[toPlayerIndex]->setJoinGameInProgressFlags(); - - safeMutexSlot.ReleaseLock(); - safeMutexSlot2.ReleaseLock(); - result = true; - updateListen(); - } - else { - //printf("#3 Server is switching slots aborted, is slot already connected?\n"); - - safeMutexSlot.ReleaseLock(); - safeMutexSlot2.ReleaseLock(); - safeMutex.ReleaseLock(); - } - //printf("#4 Server is switching slots\n"); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return result; -} - -Mutex *ServerInterface::getSlotMutex(int playerIndex) { - return slotAccessorMutexes[playerIndex]; -} - -ConnectionSlot *ServerInterface::getSlot(int playerIndex, bool lockMutex) { - if(playerIndex < 0 || playerIndex >= GameConstants::maxPlayers) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] playerIndex is invalid = %d",extractFileFromDirectoryPath(extractFileFromDirectoryPath(__FILE__).c_str()).c_str(),__FUNCTION__,__LINE__,playerIndex); - throw megaglest_runtime_error(szBuf); - } - - MutexSafeWrapper safeMutexSlot((lockMutex == true ? slotAccessorMutexes[playerIndex] : NULL),CODE_AT_LINE_X(playerIndex)); - ConnectionSlot *result = slots[playerIndex]; - return result; -} - -bool ServerInterface::isClientConnected(int playerIndex) { - if(playerIndex < 0 || playerIndex >= GameConstants::maxPlayers) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] playerIndex is invalid = %d",extractFileFromDirectoryPath(extractFileFromDirectoryPath(__FILE__).c_str()).c_str(),__FUNCTION__,__LINE__,playerIndex); - throw megaglest_runtime_error(szBuf); - } - - bool result = false; - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[playerIndex],CODE_AT_LINE_X(playerIndex)); - if(slots[playerIndex] != NULL && slots[playerIndex]->isConnected() == true) { - result = true; - } - return result; -} - -bool ServerInterface::hasClientConnection() { - bool result = false; - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - if(isClientConnected(index) == true) { - result = true; - break; - } - } - return result; -} - -int ServerInterface::getSlotCount() { - int slotCount = 0; - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - if(slots[index] != NULL) { - ++slotCount; - } - } - return slotCount; -} - -int ServerInterface::getConnectedSlotCount(bool authenticated) { - int connectedSlotCount = 0; - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - if(slots[index] != NULL && slots[index]->isConnected() == true) { - if(authenticated == false || - (authenticated == true && slots[index]->getConnectHasHandshaked() == true)) { - ++connectedSlotCount; - } - } - } - return connectedSlotCount; -} - -int64 ServerInterface::getNextEventId() { - nextEventId++; - if(nextEventId > INT_MAX) { - nextEventId = 1; - } - return nextEventId; -} - -std::pair ServerInterface::clientLagCheck(ConnectionSlot *connectionSlot, bool skipNetworkBroadCast) { - std::pair clientLagExceededOrWarned = std::make_pair(false, false); - static bool alreadyInLagCheck = false; - - if(alreadyInLagCheck == true || - (connectionSlot != NULL && (connectionSlot->getSkipLagCheck() == true || - connectionSlot->getConnectHasHandshaked() == false))) { - return clientLagExceededOrWarned; - } - - try { - alreadyInLagCheck = true; - - if((gameStartTime > 0 && - difftime((long int)time(NULL),gameStartTime) >= LAG_CHECK_GRACE_PERIOD) && - (resumeGameStartTime == 0 || - (resumeGameStartTime > 0 && - difftime((long int)time(NULL),resumeGameStartTime) >= LAG_CHECK_GRACE_PERIOD))) { - if(connectionSlot != NULL && connectionSlot->isConnected() == true) { - - double clientLag = this->getCurrentFrameCount() - connectionSlot->getCurrentFrameCount(); - double clientLagCount = (gameSettings.getNetworkFramePeriod() > 0 ? (clientLag / gameSettings.getNetworkFramePeriod()) : 0); - connectionSlot->setCurrentLagCount(clientLagCount); - - double clientLagTime = difftime((long int)time(NULL),connectionSlot->getLastReceiveCommandListTime()); - - if(this->getCurrentFrameCount() > 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, clientLag = %f, clientLagCount = %f, this->getCurrentFrameCount() = %d, connectionSlot->getCurrentFrameCount() = %d, clientLagTime = %f\n", - extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__, - connectionSlot->getPlayerIndex(), - clientLag,clientLagCount, - this->getCurrentFrameCount(), - connectionSlot->getCurrentFrameCount(), - clientLagTime); - } - - // TEST LAG Error and warnings!!! - //clientLagCount = maxFrameCountLagAllowed + 1; - //clientLagTime = maxClientLagTimeAllowed + 1; - /* - if(difftime(time(NULL),gameStartTime) >= LAG_CHECK_GRACE_PERIOD + 5) { - clientLagTime = maxClientLagTimeAllowed + 1; - } - else if(difftime(time(NULL),gameStartTime) >= LAG_CHECK_GRACE_PERIOD) { - clientLagTime = (maxClientLagTimeAllowed * warnFrameCountLagPercent) + 1; - } - */ - // END test - - - //printf("skipNetworkBroadCast [%d] clientLagCount [%f][%f][%f] clientLagTime [%f][%f][%f]\n",skipNetworkBroadCast,clientLagCount,(maxFrameCountLagAllowed * warnFrameCountLagPercent),maxFrameCountLagAllowed,clientLagTime,(maxClientLagTimeAllowed * warnFrameCountLagPercent),maxClientLagTimeAllowed); - - // New lag check - if((maxFrameCountLagAllowed > 0 && clientLagCount > maxFrameCountLagAllowed) || - (maxClientLagTimeAllowed > 0 && clientLagTime > maxClientLagTimeAllowed) || - (maxFrameCountLagAllowedEver > 0 && clientLagCount > maxFrameCountLagAllowedEver) || - ( maxClientLagTimeAllowedEver > 0 && clientLagTime > maxClientLagTimeAllowedEver)) { - - clientLagExceededOrWarned.first = true; - //printf("#1 Client Warned\n"); - - Lang &lang= Lang::getInstance(); - const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); - for(unsigned int index = 0; index < languageList.size(); ++index) { - char szBuf[4096]=""; - - string msgTemplate = "DROPPING %s, exceeded max allowed LAG count of %f [time = %f], clientLag = %f [%f], disconnecting client."; - if(lang.hasString("ClientLagDropping") == true) { - msgTemplate = lang.getString("ClientLagDropping",languageList[index]); - } - if(gameSettings.getNetworkPauseGameForLaggedClients() == true && - ((maxFrameCountLagAllowedEver <= 0 || clientLagCount <= maxFrameCountLagAllowedEver) && - (maxClientLagTimeAllowedEver <= 0 || clientLagTime <= maxClientLagTimeAllowedEver))) { - msgTemplate = "PAUSING GAME TEMPORARILY for %s, exceeded max allowed LAG count of %f [time = %f], clientLag = %f [%f], waiting for client to catch up..."; - if(lang.hasString("ClientLagPausing") == true) { - msgTemplate = lang.getString("ClientLagPausing",languageList[index]); + break; + } } } + } + } + } + return result; + } + + void ServerInterface::addClientToServerIPAddress(uint32 clientIp, uint32 ServerIp) { + FTPServerThread::addClientToServerIPAddress(clientIp, ServerIp); + } + + void ServerInterface::addSlot(int playerIndex) { + //printf("Adding slot for playerIndex = %d, serverSocket.isPortBound() = %d\n",playerIndex,serverSocket.isPortBound()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (playerIndex < 0 || playerIndex >= GameConstants::maxPlayers) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] playerIndex is invalid = %d", extractFileFromDirectoryPath(extractFileFromDirectoryPath(__FILE__).c_str()).c_str(), __FUNCTION__, __LINE__, playerIndex); + throw megaglest_runtime_error(szBuf); + } + MutexSafeWrapper safeMutex(serverSynchAccessor, CODE_AT_LINE); + if (serverSocketAdmin != NULL && serverSocketAdmin->isSocketValid() == false) { + serverSocketAdmin->listen(5); + } + if (serverSocket.isPortBound() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + serverSocket.bind(serverSocket.getBindPort()); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[playerIndex], CODE_AT_LINE_X(playerIndex)); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + ConnectionSlot *slot = slots[playerIndex]; + if (slot != NULL) { + slots[playerIndex] = NULL; + } + slots[playerIndex] = new ConnectionSlot(this, playerIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + safeMutexSlot.ReleaseLock(); + delete slot; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + safeMutex.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + updateListen(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void ServerInterface::removeSlot(int playerIndex, int lockedSlotIndex) { + //printf("Removing slot for playerIndex = %d, serverSocket.isPortBound() = %d\n",playerIndex,serverSocket.isPortBound()); + + if (playerIndex < 0 || playerIndex >= GameConstants::maxPlayers) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] playerIndex is invalid = %d", extractFileFromDirectoryPath(extractFileFromDirectoryPath(__FILE__).c_str()).c_str(), __FUNCTION__, __LINE__, playerIndex); + throw megaglest_runtime_error(szBuf); + } + + Lang &lang = Lang::getInstance(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, playerIndex, lockedSlotIndex); + + MutexSafeWrapper safeMutex(serverSynchAccessor, CODE_AT_LINE); + MutexSafeWrapper safeMutexSlot(NULL, CODE_AT_LINE_X(playerIndex)); + if (playerIndex != lockedSlotIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, playerIndex, lockedSlotIndex); + safeMutexSlot.setMutex(slotAccessorMutexes[playerIndex], CODE_AT_LINE_X(playerIndex)); + } + + vector msgList; + ConnectionSlot *slot = slots[playerIndex]; + bool notifyDisconnect = false; + const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); + if (slot != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, playerIndex, lockedSlotIndex); + + if (slot->getLastReceiveCommandListTime() > 0) { + char szBuf[4096] = ""; + + for (unsigned int index = 0; index < languageList.size(); ++index) { + string msgTemplate = "Player %s, disconnected from the game."; + if (lang.hasString("PlayerDisconnected", languageList[index]) == true) { + msgTemplate = lang.getString("PlayerDisconnected", languageList[index]); + } #ifdef WIN32 - _snprintf(szBuf,4095,msgTemplate.c_str(),connectionSlot->getName().c_str() ,maxFrameCountLagAllowed,maxClientLagTimeAllowed,clientLagCount,clientLagTime); + _snprintf(szBuf, 4095, msgTemplate.c_str(), slot->getName().c_str()); #else - snprintf(szBuf,4095,msgTemplate.c_str(),connectionSlot->getName().c_str(),maxFrameCountLagAllowed,maxClientLagTimeAllowed,clientLagCount,clientLagTime); + snprintf(szBuf, 4095, msgTemplate.c_str(), slot->getName().c_str()); #endif - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, szBuf); - if(skipNetworkBroadCast == false) { - string sMsg = szBuf; - bool echoLocal = lang.isLanguageLocal(languageList[index]); - sendTextMessage(sMsg,-1, echoLocal, languageList[index], connectionSlot->getPlayerIndex()); - } - } - - if((gameSettings.getNetworkPauseGameForLaggedClients() == false || - (maxFrameCountLagAllowedEver > 0 && clientLagCount > maxFrameCountLagAllowedEver) || - (maxClientLagTimeAllowedEver > 0 && clientLagTime > maxClientLagTimeAllowedEver) && - connectionSlot->getGraceLagCtr() > GRACE_LAG_CTR_LIMIT)) { - - //printf("Closing connection slot lagged out!\n"); - connectionSlot->close(); - // not needed now, but will be needed when in-game joins and rejoins - // are used - connectionSlot->resetGraceLagCtr(); + msgList.push_back(szBuf); } - } - // New lag check warning - else if((maxFrameCountLagAllowed > 0 && warnFrameCountLagPercent > 0 && - clientLagCount > (maxFrameCountLagAllowed * warnFrameCountLagPercent)) || - (maxClientLagTimeAllowed > 0 && warnFrameCountLagPercent > 0 && - clientLagTime > (maxClientLagTimeAllowed * warnFrameCountLagPercent)) ) { - - clientLagExceededOrWarned.second = true; - //printf("#2 Client Warned\n"); - - if(connectionSlot->getLagCountWarning() == false) { - connectionSlot->setLagCountWarning(true); - - Lang &lang= Lang::getInstance(); - const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); - for(unsigned int index = 0; index < languageList.size(); ++index) { - char szBuf[4096]=""; - - string msgTemplate = "LAG WARNING for %s, may exceed max allowed LAG count of %f [time = %f], clientLag = %f [%f], WARNING..."; - if(lang.hasString("ClientLagWarning") == true) { - msgTemplate = lang.getString("ClientLagWarning",languageList[index]); - } - - #ifdef WIN32 - _snprintf(szBuf,4095,msgTemplate.c_str(),connectionSlot->getName().c_str(),maxFrameCountLagAllowed,maxClientLagTimeAllowed,clientLagCount,clientLagTime); - #else - snprintf(szBuf,4095,msgTemplate.c_str(),connectionSlot->getName().c_str(),maxFrameCountLagAllowed,maxClientLagTimeAllowed,clientLagCount,clientLagTime); - #endif - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,szBuf); - - if(skipNetworkBroadCast == false) { - string sMsg = szBuf; - bool echoLocal = lang.isLanguageLocal(languageList[index]); - sendTextMessage(sMsg,-1, echoLocal, languageList[index], connectionSlot->getPlayerIndex()); - } - } - } - } - else if(connectionSlot->getLagCountWarning() == true) { - connectionSlot->setLagCountWarning(false); + notifyDisconnect = true; } } - } - } - catch(const exception &ex) { - alreadyInLagCheck = false; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, playerIndex, lockedSlotIndex); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - throw megaglest_runtime_error(ex.what()); - } + slots[playerIndex] = NULL; + safeMutexSlot.ReleaseLock(); + safeMutex.ReleaseLock(); - alreadyInLagCheck = false; - return clientLagExceededOrWarned; -} + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, playerIndex, lockedSlotIndex); -void ServerInterface::updateSocketTriggeredList(std::map & socketTriggeredList) { - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - ConnectionSlot *connectionSlot = slots[index]; - if(connectionSlot != NULL) { - PLATFORM_SOCKET clientSocket = connectionSlot->getSocketId(); - if(Socket::isSocketValid(&clientSocket) == true) { - socketTriggeredList[clientSocket] = false; - } - } - } -} + if (slot != NULL) slot->close(); + delete slot; -void ServerInterface::validateConnectedClients() { - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - ConnectionSlot* connectionSlot = slots[index]; - if(connectionSlot != NULL) { - connectionSlot->validateConnection(); - } - } -} + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, playerIndex, lockedSlotIndex); -bool ServerInterface::signalClientReceiveCommands(ConnectionSlot *connectionSlot, - int slotIndex, bool socketTriggered, ConnectionSlotEvent & event) { - bool slotSignalled = false; + updateListen(); - event.eventType = eReceiveSocketData; - event.networkMessage = NULL; - event.connectionSlot = connectionSlot; - event.socketTriggered = socketTriggered; - event.triggerId = slotIndex; - event.eventId = getNextEventId(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, playerIndex, lockedSlotIndex); - if(connectionSlot != NULL) { - if(socketTriggered == true || connectionSlot->isConnected() == false) { - connectionSlot->signalUpdate(&event); - slotSignalled = true; - } - } - return slotSignalled; -} + if (notifyDisconnect == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, playerIndex, lockedSlotIndex); -void ServerInterface::signalClientsToRecieveData(std::map &socketTriggeredList, - std::map &eventList, - std::map & mapSlotSignalledList) { - //printf("====================================In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //printf("Signal clients get new data\n"); - const bool newThreadManager = Config::getInstance().getBool("EnableNewThreadManager","false"); - if(newThreadManager == true) { - masterController.clearSlaves(true); - std::vector slaveThreadList; - for(int i= 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[i],CODE_AT_LINE_X(i)); - ConnectionSlot* connectionSlot = slots[i]; - - bool socketTriggered = false; - - if(connectionSlot != NULL) { - PLATFORM_SOCKET clientSocket = connectionSlot->getSocketId(); - if(Socket::isSocketValid(&clientSocket)) { - socketTriggered = socketTriggeredList[clientSocket]; - } - else if(this->getGameHasBeenInitiated() == true && - this->getAllowInGameConnections() == true) { - socketTriggeredList[clientSocket] = true; - socketTriggered = socketTriggeredList[clientSocket]; + for (unsigned int index = 0; index < languageList.size(); ++index) { + bool localEcho = lang.isLanguageLocal(languageList[index]); + queueTextMessage(msgList[index], -1, localEcho, languageList[index]); } } - ConnectionSlotEvent &event = eventList[i]; - event.eventType = eReceiveSocketData; - event.networkMessage = NULL; - event.connectionSlot = connectionSlot; - event.socketTriggered = socketTriggered; - event.triggerId = i; - event.eventId = getNextEventId(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] playerIndex = %d, lockedSlotIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, playerIndex, lockedSlotIndex); + } - if(connectionSlot != NULL) { - if(socketTriggered == true || connectionSlot->isConnected() == false) { - if(connectionSlot->getWorkerThread() != NULL) { - slaveThreadList.push_back(connectionSlot->getWorkerThread()); - mapSlotSignalledList[i] = true; + bool ServerInterface::switchSlot(int fromPlayerIndex, int toPlayerIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + bool result = false; + + //printf("#1 Server is switching slots\n"); + + if (fromPlayerIndex < 0 || fromPlayerIndex >= GameConstants::maxPlayers) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] fromPlayerIndex is invalid = %d", extractFileFromDirectoryPath(extractFileFromDirectoryPath(__FILE__).c_str()).c_str(), __FUNCTION__, __LINE__, fromPlayerIndex); + throw megaglest_runtime_error(szBuf); + } + + if (toPlayerIndex < 0 || toPlayerIndex >= GameConstants::maxPlayers) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] toPlayerIndex is invalid = %d", extractFileFromDirectoryPath(extractFileFromDirectoryPath(__FILE__).c_str()).c_str(), __FUNCTION__, __LINE__, toPlayerIndex); + throw megaglest_runtime_error(szBuf); + } + + if (fromPlayerIndex == toPlayerIndex) { + return false; + } + + MutexSafeWrapper safeMutex(serverSynchAccessor, CODE_AT_LINE); + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[fromPlayerIndex], CODE_AT_LINE_X(fromPlayerIndex)); + MutexSafeWrapper safeMutexSlot2(slotAccessorMutexes[toPlayerIndex], CODE_AT_LINE_X(toPlayerIndex)); + + //printf("#1a Server is switching slots\n"); + + if (slots[toPlayerIndex] != NULL && + slots[toPlayerIndex]->hasValidSocketId() == false) { + + //printf("#2 Server is switching slots\n"); + + slots[fromPlayerIndex]->setPlayerIndex(toPlayerIndex); + slots[toPlayerIndex]->setPlayerIndex(fromPlayerIndex); + ConnectionSlot *tmp = slots[toPlayerIndex]; + slots[toPlayerIndex] = slots[fromPlayerIndex]; + slots[fromPlayerIndex] = tmp; + + safeMutex.ReleaseLock(); + + PlayerIndexMessage playerIndexMessage(toPlayerIndex); + slots[toPlayerIndex]->sendMessage(&playerIndexMessage); + + //slots[fromPlayerIndex]->resetJoinGameInProgressFlags(); + //slots[toPlayerIndex]->setJoinGameInProgressFlags(); + + safeMutexSlot.ReleaseLock(); + safeMutexSlot2.ReleaseLock(); + result = true; + updateListen(); + } else { + //printf("#3 Server is switching slots aborted, is slot already connected?\n"); + + safeMutexSlot.ReleaseLock(); + safeMutexSlot2.ReleaseLock(); + safeMutex.ReleaseLock(); + } + //printf("#4 Server is switching slots\n"); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + return result; + } + + Mutex *ServerInterface::getSlotMutex(int playerIndex) { + return slotAccessorMutexes[playerIndex]; + } + + ConnectionSlot *ServerInterface::getSlot(int playerIndex, bool lockMutex) { + if (playerIndex < 0 || playerIndex >= GameConstants::maxPlayers) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] playerIndex is invalid = %d", extractFileFromDirectoryPath(extractFileFromDirectoryPath(__FILE__).c_str()).c_str(), __FUNCTION__, __LINE__, playerIndex); + throw megaglest_runtime_error(szBuf); + } + + MutexSafeWrapper safeMutexSlot((lockMutex == true ? slotAccessorMutexes[playerIndex] : NULL), CODE_AT_LINE_X(playerIndex)); + ConnectionSlot *result = slots[playerIndex]; + return result; + } + + bool ServerInterface::isClientConnected(int playerIndex) { + if (playerIndex < 0 || playerIndex >= GameConstants::maxPlayers) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] playerIndex is invalid = %d", extractFileFromDirectoryPath(extractFileFromDirectoryPath(__FILE__).c_str()).c_str(), __FUNCTION__, __LINE__, playerIndex); + throw megaglest_runtime_error(szBuf); + } + + bool result = false; + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[playerIndex], CODE_AT_LINE_X(playerIndex)); + if (slots[playerIndex] != NULL && slots[playerIndex]->isConnected() == true) { + result = true; + } + return result; + } + + bool ServerInterface::hasClientConnection() { + bool result = false; + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + if (isClientConnected(index) == true) { + result = true; + break; + } + } + return result; + } + + int ServerInterface::getSlotCount() { + int slotCount = 0; + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + if (slots[index] != NULL) { + ++slotCount; + } + } + return slotCount; + } + + int ServerInterface::getConnectedSlotCount(bool authenticated) { + int connectedSlotCount = 0; + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + if (slots[index] != NULL && slots[index]->isConnected() == true) { + if (authenticated == false || + (authenticated == true && slots[index]->getConnectHasHandshaked() == true)) { + ++connectedSlotCount; } } } + return connectedSlotCount; } - masterController.setSlaves(slaveThreadList); - masterController.signalSlaves(&eventList); - } - else { - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - ConnectionSlot *connectionSlot = slots[index]; - if(connectionSlot != NULL) { - bool socketTriggered = false; - PLATFORM_SOCKET clientSocket = connectionSlot->getSocketId(); - if(Socket::isSocketValid(&clientSocket)) { - socketTriggered = socketTriggeredList[clientSocket]; - } - - ConnectionSlotEvent &event = eventList[index]; - bool socketSignalled = signalClientReceiveCommands(connectionSlot,index,socketTriggered,event); - if(connectionSlot != NULL && socketTriggered == true) { - mapSlotSignalledList[index] = socketSignalled; - } + int64 ServerInterface::getNextEventId() { + nextEventId++; + if (nextEventId > INT_MAX) { + nextEventId = 1; } + return nextEventId; } - } -} -void ServerInterface::checkForCompletedClientsUsingThreadManager( - std::map &mapSlotSignalledList, std::vector& errorMsgList) { + std::pair ServerInterface::clientLagCheck(ConnectionSlot *connectionSlot, bool skipNetworkBroadCast) { + std::pair clientLagExceededOrWarned = std::make_pair(false, false); + static bool alreadyInLagCheck = false; - masterController.waitTillSlavesTrigger(MAX_SLOT_THREAD_WAIT_TIME_MILLISECONDS); - masterController.clearSlaves(true); - - for (int i = 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[i],CODE_AT_LINE_X(i)); - - ConnectionSlot* connectionSlot = slots[i]; - if (connectionSlot != NULL && mapSlotSignalledList[i] == true) { + if (alreadyInLagCheck == true || + (connectionSlot != NULL && (connectionSlot->getSkipLagCheck() == true || + connectionSlot->getConnectHasHandshaked() == false))) { + return clientLagExceededOrWarned; + } try { - std::vector errorList = - connectionSlot->getThreadErrorList(); - // Collect any collected errors from threads - if (errorList.empty() == false) { - for (int iErrIdx = 0; iErrIdx < (int) errorList.size();++iErrIdx) { - string &sErr = errorList[iErrIdx]; + alreadyInLagCheck = true; - if (sErr != "") { - errorMsgList.push_back(sErr); + if ((gameStartTime > 0 && + difftime((long int) time(NULL), gameStartTime) >= LAG_CHECK_GRACE_PERIOD) && + (resumeGameStartTime == 0 || + (resumeGameStartTime > 0 && + difftime((long int) time(NULL), resumeGameStartTime) >= LAG_CHECK_GRACE_PERIOD))) { + if (connectionSlot != NULL && connectionSlot->isConnected() == true) { + + double clientLag = this->getCurrentFrameCount() - connectionSlot->getCurrentFrameCount(); + double clientLagCount = (gameSettings.getNetworkFramePeriod() > 0 ? (clientLag / gameSettings.getNetworkFramePeriod()) : 0); + connectionSlot->setCurrentLagCount(clientLagCount); + + double clientLagTime = difftime((long int) time(NULL), connectionSlot->getLastReceiveCommandListTime()); + + if (this->getCurrentFrameCount() > 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] playerIndex = %d, clientLag = %f, clientLagCount = %f, this->getCurrentFrameCount() = %d, connectionSlot->getCurrentFrameCount() = %d, clientLagTime = %f\n", + extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, + connectionSlot->getPlayerIndex(), + clientLag, clientLagCount, + this->getCurrentFrameCount(), + connectionSlot->getCurrentFrameCount(), + clientLagTime); + } + + // TEST LAG Error and warnings!!! + //clientLagCount = maxFrameCountLagAllowed + 1; + //clientLagTime = maxClientLagTimeAllowed + 1; + /* + if(difftime(time(NULL),gameStartTime) >= LAG_CHECK_GRACE_PERIOD + 5) { + clientLagTime = maxClientLagTimeAllowed + 1; + } + else if(difftime(time(NULL),gameStartTime) >= LAG_CHECK_GRACE_PERIOD) { + clientLagTime = (maxClientLagTimeAllowed * warnFrameCountLagPercent) + 1; + } + */ + // END test + + + //printf("skipNetworkBroadCast [%d] clientLagCount [%f][%f][%f] clientLagTime [%f][%f][%f]\n",skipNetworkBroadCast,clientLagCount,(maxFrameCountLagAllowed * warnFrameCountLagPercent),maxFrameCountLagAllowed,clientLagTime,(maxClientLagTimeAllowed * warnFrameCountLagPercent),maxClientLagTimeAllowed); + + // New lag check + if ((maxFrameCountLagAllowed > 0 && clientLagCount > maxFrameCountLagAllowed) || + (maxClientLagTimeAllowed > 0 && clientLagTime > maxClientLagTimeAllowed) || + (maxFrameCountLagAllowedEver > 0 && clientLagCount > maxFrameCountLagAllowedEver) || + (maxClientLagTimeAllowedEver > 0 && clientLagTime > maxClientLagTimeAllowedEver)) { + + clientLagExceededOrWarned.first = true; + //printf("#1 Client Warned\n"); + + Lang &lang = Lang::getInstance(); + const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); + for (unsigned int index = 0; index < languageList.size(); ++index) { + char szBuf[4096] = ""; + + string msgTemplate = "DROPPING %s, exceeded max allowed LAG count of %f [time = %f], clientLag = %f [%f], disconnecting client."; + if (lang.hasString("ClientLagDropping") == true) { + msgTemplate = lang.getString("ClientLagDropping", languageList[index]); + } + if (gameSettings.getNetworkPauseGameForLaggedClients() == true && + ((maxFrameCountLagAllowedEver <= 0 || clientLagCount <= maxFrameCountLagAllowedEver) && + (maxClientLagTimeAllowedEver <= 0 || clientLagTime <= maxClientLagTimeAllowedEver))) { + msgTemplate = "PAUSING GAME TEMPORARILY for %s, exceeded max allowed LAG count of %f [time = %f], clientLag = %f [%f], waiting for client to catch up..."; + if (lang.hasString("ClientLagPausing") == true) { + msgTemplate = lang.getString("ClientLagPausing", languageList[index]); + } + } +#ifdef WIN32 + _snprintf(szBuf, 4095, msgTemplate.c_str(), connectionSlot->getName().c_str(), maxFrameCountLagAllowed, maxClientLagTimeAllowed, clientLagCount, clientLagTime); +#else + snprintf(szBuf, 4095, msgTemplate.c_str(), connectionSlot->getName().c_str(), maxFrameCountLagAllowed, maxClientLagTimeAllowed, clientLagCount, clientLagTime); +#endif + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, szBuf); + + if (skipNetworkBroadCast == false) { + string sMsg = szBuf; + bool echoLocal = lang.isLanguageLocal(languageList[index]); + sendTextMessage(sMsg, -1, echoLocal, languageList[index], connectionSlot->getPlayerIndex()); + } + } + + if ((gameSettings.getNetworkPauseGameForLaggedClients() == false || + (maxFrameCountLagAllowedEver > 0 && clientLagCount > maxFrameCountLagAllowedEver) || + (maxClientLagTimeAllowedEver > 0 && clientLagTime > maxClientLagTimeAllowedEver) && + connectionSlot->getGraceLagCtr() > GRACE_LAG_CTR_LIMIT)) { + + //printf("Closing connection slot lagged out!\n"); + connectionSlot->close(); + // not needed now, but will be needed when in-game joins and rejoins + // are used + connectionSlot->resetGraceLagCtr(); + } + + } + // New lag check warning + else if ((maxFrameCountLagAllowed > 0 && warnFrameCountLagPercent > 0 && + clientLagCount > (maxFrameCountLagAllowed * warnFrameCountLagPercent)) || + (maxClientLagTimeAllowed > 0 && warnFrameCountLagPercent > 0 && + clientLagTime > (maxClientLagTimeAllowed * warnFrameCountLagPercent))) { + + clientLagExceededOrWarned.second = true; + //printf("#2 Client Warned\n"); + + if (connectionSlot->getLagCountWarning() == false) { + connectionSlot->setLagCountWarning(true); + + Lang &lang = Lang::getInstance(); + const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); + for (unsigned int index = 0; index < languageList.size(); ++index) { + char szBuf[4096] = ""; + + string msgTemplate = "LAG WARNING for %s, may exceed max allowed LAG count of %f [time = %f], clientLag = %f [%f], WARNING..."; + if (lang.hasString("ClientLagWarning") == true) { + msgTemplate = lang.getString("ClientLagWarning", languageList[index]); + } + +#ifdef WIN32 + _snprintf(szBuf, 4095, msgTemplate.c_str(), connectionSlot->getName().c_str(), maxFrameCountLagAllowed, maxClientLagTimeAllowed, clientLagCount, clientLagTime); +#else + snprintf(szBuf, 4095, msgTemplate.c_str(), connectionSlot->getName().c_str(), maxFrameCountLagAllowed, maxClientLagTimeAllowed, clientLagCount, clientLagTime); +#endif + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, szBuf); + + if (skipNetworkBroadCast == false) { + string sMsg = szBuf; + bool echoLocal = lang.isLanguageLocal(languageList[index]); + sendTextMessage(sMsg, -1, echoLocal, languageList[index], connectionSlot->getPlayerIndex()); + } + } + } + } else if (connectionSlot->getLagCountWarning() == true) { + connectionSlot->setLagCountWarning(false); } } - connectionSlot->clearThreadErrorList(); } } catch (const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); + alreadyInLagCheck = false; - errorMsgList.push_back(ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] ERROR [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + throw megaglest_runtime_error(ex.what()); } + + alreadyInLagCheck = false; + return clientLagExceededOrWarned; } - } -} -void ServerInterface::checkForCompletedClientsUsingLoop( - std::map& mapSlotSignalledList, std::vector &errorMsgList, - std::map &eventList) { - - //time_t waitForThreadElapsed = time(NULL); - Chrono waitForThreadElapsed(true); - - std::map slotsCompleted; - for (bool threadsDone = false; exitServer == false && threadsDone == false && - waitForThreadElapsed.getMillis() <= MAX_SLOT_THREAD_WAIT_TIME_MILLISECONDS;) { - - threadsDone = true; - // Examine all threads for completion of delegation - for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - - ConnectionSlot *connectionSlot = slots[index]; - if (connectionSlot != NULL && connectionSlot->isConnected() == true && - mapSlotSignalledList[index] == true && - connectionSlot->getJoinGameInProgress() == false && - slotsCompleted.find(index) == slotsCompleted.end()) { - - try { - std::vector errorList = connectionSlot->getThreadErrorList(); - // Collect any collected errors from threads - if (errorList.empty() == false) { - - for (int iErrIdx = 0; iErrIdx < (int) errorList.size();++iErrIdx) { - - string &sErr = errorList[iErrIdx]; - if (sErr != "") { - errorMsgList.push_back(sErr); - } - } - connectionSlot->clearThreadErrorList(); - } - - // Not done waiting for data yet - bool updateFinished = (connectionSlot != NULL ? connectionSlot->updateCompleted(&eventList[index]) : true); - if (updateFinished == false) { - threadsDone = false; - break; - } - else { - slotsCompleted[index] = true; - } - } - catch (const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - - errorMsgList.push_back(ex.what()); - } - } - } - } -} - -std::string ServerInterface::getIpAddress(bool mutexLock) { - string result = serverSocket.getIpAddress(); - return result; -} - -void ServerInterface::setClientLagCallbackInterface(ClientLagCallbackInterface *intf) { - this->clientLagCallbackInterface = intf; -} - -bool ServerInterface::getClientsAutoPausedDueToLag() { - return this->clientsAutoPausedDueToLag; -} - -void ServerInterface::checkForCompletedClients(std::map & mapSlotSignalledList, - std::vector &errorMsgList, - std::map &eventList) { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - const bool newThreadManager = Config::getInstance().getBool("EnableNewThreadManager","false"); - if(newThreadManager == true) { - checkForCompletedClientsUsingThreadManager(mapSlotSignalledList, errorMsgList); - } - else { - checkForCompletedClientsUsingLoop(mapSlotSignalledList, errorMsgList, eventList); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void ServerInterface::checkForAutoPauseForLaggingClient(int index,ConnectionSlot* connectionSlot) { - - if (gameSettings.getNetworkPauseGameForLaggedClients() == true && - this->clientsAutoPausedDueToLag == false) { - if (connectionSlot != NULL && connectionSlot->isConnected() == true) { - if (connectionSlot->getAutoPauseGameCountForLag() < MAX_CLIENT_PAUSE_FOR_LAG_COUNT) { - if (this->clientLagCallbackInterface != NULL) { - - if (this->clientsAutoPausedDueToLagTimer.isStarted() == false || - this->clientsAutoPausedDueToLagTimer.getMillis() >= MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS) { - - connectionSlot->incrementAutoPauseGameCountForLag(); - - this->clientsAutoPausedDueToLag = true; - if ((this->clientLagCallbackInterface->clientLagHandler(index, true) == false) && - connectionSlot->getGraceLagCtr() > GRACE_LAG_CTR_LIMIT) { - connectionSlot->close(); - connectionSlot->resetGraceLagCtr(); - } - else { - if (this->clientsAutoPausedDueToLagTimer.isStarted()== true) { - - this->clientsAutoPausedDueToLagTimer.reset(); - this->clientsAutoPausedDueToLagTimer.stop(); - } - this->clientsAutoPausedDueToLagTimer.start(); - } + void ServerInterface::updateSocketTriggeredList(std::map & socketTriggeredList) { + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + ConnectionSlot *connectionSlot = slots[index]; + if (connectionSlot != NULL) { + PLATFORM_SOCKET clientSocket = connectionSlot->getSocketId(); + if (Socket::isSocketValid(&clientSocket) == true) { + socketTriggeredList[clientSocket] = false; } } } } - } -} -void ServerInterface::checkForLaggingClients(std::map &mapSlotSignalledList, - std::map &eventList, - std::map &socketTriggeredList, - std::vector &errorMsgList) { - bool lastGlobalLagCheckTimeUpdate = false; - if(gameHasBeenInitiated == true) { - - //time_t waitForClientsElapsed = time(NULL); - Chrono waitForClientsElapsed(true); - //time_t waitForThreadElapsed = time(NULL); - Chrono waitForThreadElapsed(true); - std::map slotsCompleted; - std::map slotsWarnedList; - - for(bool threadsDone = false; - exitServer == false && threadsDone == false && - waitForThreadElapsed.getMillis() <= MAX_SLOT_THREAD_WAIT_TIME_MILLISECONDS;) { - - threadsDone = true; - // Examine all threads for completion of delegation - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - //printf("#1 Check lag for i: %d\n",i); - - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); + void ServerInterface::validateConnectedClients() { + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); ConnectionSlot* connectionSlot = slots[index]; + if (connectionSlot != NULL) { + connectionSlot->validateConnection(); + } + } + } - if(connectionSlot != NULL && connectionSlot->isConnected() == true && - connectionSlot->getSkipLagCheck() == false && - mapSlotSignalledList[index] == true && - slotsCompleted.find(index) == slotsCompleted.end()) { + bool ServerInterface::signalClientReceiveCommands(ConnectionSlot *connectionSlot, + int slotIndex, bool socketTriggered, ConnectionSlotEvent & event) { + bool slotSignalled = false; + + event.eventType = eReceiveSocketData; + event.networkMessage = NULL; + event.connectionSlot = connectionSlot; + event.socketTriggered = socketTriggered; + event.triggerId = slotIndex; + event.eventId = getNextEventId(); + + if (connectionSlot != NULL) { + if (socketTriggered == true || connectionSlot->isConnected() == false) { + connectionSlot->signalUpdate(&event); + slotSignalled = true; + } + } + return slotSignalled; + } + + void ServerInterface::signalClientsToRecieveData(std::map &socketTriggeredList, + std::map &eventList, + std::map & mapSlotSignalledList) { + //printf("====================================In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //printf("Signal clients get new data\n"); + const bool newThreadManager = Config::getInstance().getBool("EnableNewThreadManager", "false"); + if (newThreadManager == true) { + masterController.clearSlaves(true); + std::vector slaveThreadList; + for (int i = 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[i], CODE_AT_LINE_X(i)); + ConnectionSlot* connectionSlot = slots[i]; + + bool socketTriggered = false; + + if (connectionSlot != NULL) { + PLATFORM_SOCKET clientSocket = connectionSlot->getSocketId(); + if (Socket::isSocketValid(&clientSocket)) { + socketTriggered = socketTriggeredList[clientSocket]; + } else if (this->getGameHasBeenInitiated() == true && + this->getAllowInGameConnections() == true) { + socketTriggeredList[clientSocket] = true; + socketTriggered = socketTriggeredList[clientSocket]; + } + } + ConnectionSlotEvent &event = eventList[i]; + event.eventType = eReceiveSocketData; + event.networkMessage = NULL; + event.connectionSlot = connectionSlot; + event.socketTriggered = socketTriggered; + event.triggerId = i; + event.eventId = getNextEventId(); + + if (connectionSlot != NULL) { + if (socketTriggered == true || connectionSlot->isConnected() == false) { + if (connectionSlot->getWorkerThread() != NULL) { + slaveThreadList.push_back(connectionSlot->getWorkerThread()); + mapSlotSignalledList[i] = true; + } + } + } + } + masterController.setSlaves(slaveThreadList); + masterController.signalSlaves(&eventList); + } else { + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + ConnectionSlot *connectionSlot = slots[index]; + + if (connectionSlot != NULL) { + bool socketTriggered = false; + PLATFORM_SOCKET clientSocket = connectionSlot->getSocketId(); + if (Socket::isSocketValid(&clientSocket)) { + socketTriggered = socketTriggeredList[clientSocket]; + } + + ConnectionSlotEvent &event = eventList[index]; + bool socketSignalled = signalClientReceiveCommands(connectionSlot, index, socketTriggered, event); + if (connectionSlot != NULL && socketTriggered == true) { + mapSlotSignalledList[index] = socketSignalled; + } + } + } + } + } + + void ServerInterface::checkForCompletedClientsUsingThreadManager( + std::map &mapSlotSignalledList, std::vector& errorMsgList) { + + masterController.waitTillSlavesTrigger(MAX_SLOT_THREAD_WAIT_TIME_MILLISECONDS); + masterController.clearSlaves(true); + + for (int i = 0; exitServer == false && i < GameConstants::maxPlayers; ++i) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[i], CODE_AT_LINE_X(i)); + + ConnectionSlot* connectionSlot = slots[i]; + if (connectionSlot != NULL && mapSlotSignalledList[i] == true) { - //printf("#2 Check lag for i: %d playerindex: %d name [%s] socket: %d\n",i,connectionSlot->getPlayerIndex(),connectionSlot->getName().c_str(),connectionSlot->getSocketId()); try { - std::vector errorList = connectionSlot->getThreadErrorList(); - // Show any collected errors from threads - if(errorList.empty() == false) { - for(int iErrIdx = 0; iErrIdx < (int)errorList.size(); ++iErrIdx) { + std::vector errorList = + connectionSlot->getThreadErrorList(); + // Collect any collected errors from threads + if (errorList.empty() == false) { + for (int iErrIdx = 0; iErrIdx < (int) errorList.size(); ++iErrIdx) { string &sErr = errorList[iErrIdx]; - if(sErr != "") { + + if (sErr != "") { errorMsgList.push_back(sErr); } } connectionSlot->clearThreadErrorList(); } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error detected [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); - // Not done waiting for data yet - bool updateFinished = (connectionSlot != NULL ? connectionSlot->updateCompleted(&eventList[index]) : true); - if(updateFinished == false) { - //printf("#2a Check lag for i: %d\n",i); - threadsDone = false; - break; - } - else { - // New lag check - std::pair clientLagExceededOrWarned = std::make_pair(false,false); - if( gameHasBeenInitiated == true && connectionSlot != NULL && - connectionSlot->isConnected() == true) { - clientLagExceededOrWarned = clientLagCheck(connectionSlot,slotsWarnedList[index]); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] clientLagExceededOrWarned.first = %d, clientLagExceededOrWarned.second = %d, gameSettings.getNetworkPauseGameForLaggedClients() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,clientLagExceededOrWarned.first,clientLagExceededOrWarned.second,gameSettings.getNetworkPauseGameForLaggedClients()); - - if(clientLagExceededOrWarned.first == true) { - slotsWarnedList[index] = true; - } - } - // If the client has exceeded lag and the server wants - // to pause while they catch up, re-trigger the - // client reader thread - if((clientLagExceededOrWarned.second == true && - gameSettings.getNetworkPauseGameForLaggedClients() == true)) { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d, clientLagExceededOrWarned.first = %d, clientLagExceededOrWarned.second = %d, waitForClientsElapsed.getMillis() = %d, MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,clientLagExceededOrWarned.first,clientLagExceededOrWarned.second,(int)waitForClientsElapsed.getMillis(),MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS); - - checkForAutoPauseForLaggingClient(index, connectionSlot); - - slotsCompleted[index] = true; - } - else { - slotsCompleted[index] = true; - } - } - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); errorMsgList.push_back(ex.what()); } } + } + } - //printf("#3 Check lag for i: %d\n",i); - if(connectionSlot != NULL && - connectionSlot->isConnected() == true && - connectionSlot->getSkipLagCheck() == false) { - //printf("#4 Check lag for i: %d\n",i); + void ServerInterface::checkForCompletedClientsUsingLoop( + std::map& mapSlotSignalledList, std::vector &errorMsgList, + std::map &eventList) { + + //time_t waitForThreadElapsed = time(NULL); + Chrono waitForThreadElapsed(true); + + std::map slotsCompleted; + for (bool threadsDone = false; exitServer == false && threadsDone == false && + waitForThreadElapsed.getMillis() <= MAX_SLOT_THREAD_WAIT_TIME_MILLISECONDS;) { + + threadsDone = true; + // Examine all threads for completion of delegation + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + + ConnectionSlot *connectionSlot = slots[index]; + if (connectionSlot != NULL && connectionSlot->isConnected() == true && + mapSlotSignalledList[index] == true && + connectionSlot->getJoinGameInProgress() == false && + slotsCompleted.find(index) == slotsCompleted.end()) { + + try { + std::vector errorList = connectionSlot->getThreadErrorList(); + // Collect any collected errors from threads + if (errorList.empty() == false) { + + for (int iErrIdx = 0; iErrIdx < (int) errorList.size(); ++iErrIdx) { + + string &sErr = errorList[iErrIdx]; + if (sErr != "") { + errorMsgList.push_back(sErr); + } + } + connectionSlot->clearThreadErrorList(); + } + + // Not done waiting for data yet + bool updateFinished = (connectionSlot != NULL ? connectionSlot->updateCompleted(&eventList[index]) : true); + if (updateFinished == false) { + threadsDone = false; + break; + } else { + slotsCompleted[index] = true; + } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error detected [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + + errorMsgList.push_back(ex.what()); + } + } + } + } + } + + std::string ServerInterface::getIpAddress(bool mutexLock) { + string result = serverSocket.getIpAddress(); + return result; + } + + void ServerInterface::setClientLagCallbackInterface(ClientLagCallbackInterface *intf) { + this->clientLagCallbackInterface = intf; + } + + bool ServerInterface::getClientsAutoPausedDueToLag() { + return this->clientsAutoPausedDueToLag; + } + + void ServerInterface::checkForCompletedClients(std::map & mapSlotSignalledList, + std::vector &errorMsgList, + std::map &eventList) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + const bool newThreadManager = Config::getInstance().getBool("EnableNewThreadManager", "false"); + if (newThreadManager == true) { + checkForCompletedClientsUsingThreadManager(mapSlotSignalledList, errorMsgList); + } else { + checkForCompletedClientsUsingLoop(mapSlotSignalledList, errorMsgList, eventList); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void ServerInterface::checkForAutoPauseForLaggingClient(int index, ConnectionSlot* connectionSlot) { + + if (gameSettings.getNetworkPauseGameForLaggedClients() == true && + this->clientsAutoPausedDueToLag == false) { + if (connectionSlot != NULL && connectionSlot->isConnected() == true) { + if (connectionSlot->getAutoPauseGameCountForLag() < MAX_CLIENT_PAUSE_FOR_LAG_COUNT) { + if (this->clientLagCallbackInterface != NULL) { + + if (this->clientsAutoPausedDueToLagTimer.isStarted() == false || + this->clientsAutoPausedDueToLagTimer.getMillis() >= MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS) { + + connectionSlot->incrementAutoPauseGameCountForLag(); + + this->clientsAutoPausedDueToLag = true; + if ((this->clientLagCallbackInterface->clientLagHandler(index, true) == false) && + connectionSlot->getGraceLagCtr() > GRACE_LAG_CTR_LIMIT) { + connectionSlot->close(); + connectionSlot->resetGraceLagCtr(); + } else { + if (this->clientsAutoPausedDueToLagTimer.isStarted() == true) { + + this->clientsAutoPausedDueToLagTimer.reset(); + this->clientsAutoPausedDueToLagTimer.stop(); + } + this->clientsAutoPausedDueToLagTimer.start(); + } + } + } + } + } + } + } + + void ServerInterface::checkForLaggingClients(std::map &mapSlotSignalledList, + std::map &eventList, + std::map &socketTriggeredList, + std::vector &errorMsgList) { + bool lastGlobalLagCheckTimeUpdate = false; + if (gameHasBeenInitiated == true) { + + //time_t waitForClientsElapsed = time(NULL); + Chrono waitForClientsElapsed(true); + //time_t waitForThreadElapsed = time(NULL); + Chrono waitForThreadElapsed(true); + std::map slotsCompleted; + std::map slotsWarnedList; + + for (bool threadsDone = false; + exitServer == false && threadsDone == false && + waitForThreadElapsed.getMillis() <= MAX_SLOT_THREAD_WAIT_TIME_MILLISECONDS;) { + + threadsDone = true; + // Examine all threads for completion of delegation + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + //printf("#1 Check lag for i: %d\n",i); + + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + ConnectionSlot* connectionSlot = slots[index]; + + if (connectionSlot != NULL && connectionSlot->isConnected() == true && + connectionSlot->getSkipLagCheck() == false && + mapSlotSignalledList[index] == true && + slotsCompleted.find(index) == slotsCompleted.end()) { + + //printf("#2 Check lag for i: %d playerindex: %d name [%s] socket: %d\n",i,connectionSlot->getPlayerIndex(),connectionSlot->getName().c_str(),connectionSlot->getSocketId()); + try { + std::vector errorList = connectionSlot->getThreadErrorList(); + // Show any collected errors from threads + if (errorList.empty() == false) { + for (int iErrIdx = 0; iErrIdx < (int) errorList.size(); ++iErrIdx) { + string &sErr = errorList[iErrIdx]; + if (sErr != "") { + errorMsgList.push_back(sErr); + } + } + connectionSlot->clearThreadErrorList(); + } + + // Not done waiting for data yet + bool updateFinished = (connectionSlot != NULL ? connectionSlot->updateCompleted(&eventList[index]) : true); + if (updateFinished == false) { + //printf("#2a Check lag for i: %d\n",i); + threadsDone = false; + break; + } else { + // New lag check + std::pair clientLagExceededOrWarned = std::make_pair(false, false); + if (gameHasBeenInitiated == true && connectionSlot != NULL && + connectionSlot->isConnected() == true) { + clientLagExceededOrWarned = clientLagCheck(connectionSlot, slotsWarnedList[index]); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] clientLagExceededOrWarned.first = %d, clientLagExceededOrWarned.second = %d, gameSettings.getNetworkPauseGameForLaggedClients() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, clientLagExceededOrWarned.first, clientLagExceededOrWarned.second, gameSettings.getNetworkPauseGameForLaggedClients()); + + if (clientLagExceededOrWarned.first == true) { + slotsWarnedList[index] = true; + } + } + // If the client has exceeded lag and the server wants + // to pause while they catch up, re-trigger the + // client reader thread + if ((clientLagExceededOrWarned.second == true && + gameSettings.getNetworkPauseGameForLaggedClients() == true)) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d, clientLagExceededOrWarned.first = %d, clientLagExceededOrWarned.second = %d, waitForClientsElapsed.getMillis() = %d, MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, clientLagExceededOrWarned.first, clientLagExceededOrWarned.second, (int) waitForClientsElapsed.getMillis(), MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS); + + checkForAutoPauseForLaggingClient(index, connectionSlot); + + slotsCompleted[index] = true; + } else { + slotsCompleted[index] = true; + } + } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error detected [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + errorMsgList.push_back(ex.what()); + } + } + + //printf("#3 Check lag for i: %d\n",i); + if (connectionSlot != NULL && + connectionSlot->isConnected() == true && + connectionSlot->getSkipLagCheck() == false) { + //printf("#4 Check lag for i: %d\n",i); + + try { + if (gameHasBeenInitiated == true && + difftime((long int) time(NULL), gameStartTime) >= LAG_CHECK_GRACE_PERIOD && + difftime((long int) time(NULL), lastGlobalLagCheckTime) >= LAG_CHECK_INTERVAL_PERIOD) { + + //printf("\n\n\n^^^^^^^^^^^^^^ PART A\n\n\n"); + + // New lag check + std::pair clientLagExceededOrWarned = std::make_pair(false, false); + if (connectionSlot != NULL && connectionSlot->isConnected() == true) { + //printf("\n\n\n^^^^^^^^^^^^^^ PART B\n\n\n"); + + lastGlobalLagCheckTimeUpdate = true; + clientLagExceededOrWarned = clientLagCheck(connectionSlot, slotsWarnedList[index]); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] clientLagExceededOrWarned.first = %d, clientLagExceededOrWarned.second = %d, gameSettings.getNetworkPauseGameForLaggedClients() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, clientLagExceededOrWarned.first, clientLagExceededOrWarned.second, gameSettings.getNetworkPauseGameForLaggedClients()); + + if (clientLagExceededOrWarned.first == true) { + slotsWarnedList[index] = true; + } + + // If the client has exceeded lag and the server wants + // to pause while they catch up, re-trigger the + // client reader thread + if ((clientLagExceededOrWarned.second == true && + gameSettings.getNetworkPauseGameForLaggedClients() == true)) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d, clientLagExceededOrWarned.first = %d, clientLagExceededOrWarned.second = %d, waitForClientsElapsed.getMillis() = %d, MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, clientLagExceededOrWarned.first, clientLagExceededOrWarned.second, (int) waitForClientsElapsed.getMillis(), MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS); + + checkForAutoPauseForLaggingClient(index, connectionSlot); + } + } + } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error detected [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + errorMsgList.push_back(ex.what()); + } + } + + //printf("#5 Check lag for i: %d\n",i); + } + } + } + if (lastGlobalLagCheckTimeUpdate == true) { + lastGlobalLagCheckTime = time(NULL); + } + } + + void ServerInterface::executeNetworkCommandsFromClients() { + if (gameHasBeenInitiated == true) { + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + ConnectionSlot* connectionSlot = slots[index]; + if (connectionSlot != NULL && connectionSlot->isConnected() == true) { + vector pendingList = connectionSlot->getPendingNetworkCommandList(true); + if (pendingList.empty() == false) { + for (int idx = 0; exitServer == false && idx < (int) pendingList.size(); ++idx) { + NetworkCommand &cmd = pendingList[idx]; + this->requestCommand(&cmd); + } + //printf("Executed: %d commands from slot: %d\n",pendingList.size(),index); + } + } + } + } + } + + void ServerInterface::dispatchPendingChatMessages(std::vector &errorMsgList) { + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + ConnectionSlot *connectionSlot = slots[index]; + + if (connectionSlot != NULL && + connectionSlot->getChatTextList(false).empty() == false) { + try { + std::vector chatText = connectionSlot->getChatTextList(true); + for (int chatIdx = 0; + exitServer == false && slots[index] != NULL && + chatIdx < (int) chatText.size(); chatIdx++) { + + connectionSlot = slots[index]; + if (connectionSlot != NULL) { + ChatMsgInfo msg(chatText[chatIdx]); + this->addChatInfo(msg); + + string newChatText = msg.chatText.c_str(); + int newChatTeamIndex = msg.chatTeamIndex; + int newChatPlayerIndex = msg.chatPlayerIndex; + string newChatLanguage = msg.targetLanguage; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] #1 about to broadcast nmtText chatText [%s] chatTeamIndex = %d, newChatPlayerIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, newChatText.c_str(), newChatTeamIndex, newChatPlayerIndex); + + if (newChatLanguage == "" || + newChatLanguage == connectionSlot->getNetworkPlayerLanguage()) { + + NetworkMessageText networkMessageText(newChatText.c_str(), newChatTeamIndex, newChatPlayerIndex, newChatLanguage); + broadcastMessage(&networkMessageText, connectionSlot->getPlayerIndex(), index); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] after broadcast nmtText chatText [%s] chatTeamIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, newChatText.c_str(), newChatTeamIndex); + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] index = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, index); + // Its possible that the slot is disconnected here + // so check the original pointer again + if (slots[index] != NULL) { + slots[index]->clearChatInfo(); + } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error detected [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + errorMsgList.push_back(ex.what()); + } + } + } + } + + void ServerInterface::dispatchPendingMarkCellMessages(std::vector &errorMsgList) { + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + ConnectionSlot* connectionSlot = slots[index]; + + if (connectionSlot != NULL && + connectionSlot->getMarkedCellList(false).empty() == false) { try { - if(gameHasBeenInitiated == true && - difftime((long int)time(NULL),gameStartTime) >= LAG_CHECK_GRACE_PERIOD && - difftime((long int)time(NULL),lastGlobalLagCheckTime) >= LAG_CHECK_INTERVAL_PERIOD) { + std::vector chatText = connectionSlot->getMarkedCellList(true); + for (int chatIdx = 0; + exitServer == false && slots[index] != NULL && + chatIdx < (int) chatText.size(); chatIdx++) { - //printf("\n\n\n^^^^^^^^^^^^^^ PART A\n\n\n"); + connectionSlot = slots[index]; + if (connectionSlot != NULL) { + MarkedCell msg(chatText[chatIdx]); + this->addMarkedCell(msg); - // New lag check - std::pair clientLagExceededOrWarned = std::make_pair(false,false); - if( connectionSlot != NULL && connectionSlot->isConnected() == true) { - //printf("\n\n\n^^^^^^^^^^^^^^ PART B\n\n\n"); - - lastGlobalLagCheckTimeUpdate = true; - clientLagExceededOrWarned = clientLagCheck(connectionSlot,slotsWarnedList[index]); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] clientLagExceededOrWarned.first = %d, clientLagExceededOrWarned.second = %d, gameSettings.getNetworkPauseGameForLaggedClients() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,clientLagExceededOrWarned.first,clientLagExceededOrWarned.second,gameSettings.getNetworkPauseGameForLaggedClients()); - - if(clientLagExceededOrWarned.first == true) { - slotsWarnedList[index] = true; - } - - // If the client has exceeded lag and the server wants - // to pause while they catch up, re-trigger the - // client reader thread - if((clientLagExceededOrWarned.second == true && - gameSettings.getNetworkPauseGameForLaggedClients() == true)) { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d, clientLagExceededOrWarned.first = %d, clientLagExceededOrWarned.second = %d, waitForClientsElapsed.getMillis() = %d, MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,clientLagExceededOrWarned.first,clientLagExceededOrWarned.second,(int)waitForClientsElapsed.getMillis(),MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS); - - checkForAutoPauseForLaggingClient(index, connectionSlot); - } + NetworkMessageMarkCell networkMessageMarkCell(msg.getTargetPos(), msg.getFactionIndex(), msg.getNote(), msg.getPlayerIndex()); + broadcastMessage(&networkMessageMarkCell, connectionSlot->getPlayerIndex(), index); + //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtText chatText [%s] chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex); } } - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] i = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, index); + // Its possible that the slot is disconnected here + // so check the original pointer again + if (slots[index] != NULL) { + slots[index]->clearMarkedCellList(); + } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error detected [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); errorMsgList.push_back(ex.what()); } } - - //printf("#5 Check lag for i: %d\n",i); } } - } - if(lastGlobalLagCheckTimeUpdate == true) { - lastGlobalLagCheckTime = time(NULL); - } -} + void ServerInterface::dispatchPendingHighlightCellMessages(std::vector &errorMsgList) { + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { -void ServerInterface::executeNetworkCommandsFromClients() { - if(gameHasBeenInitiated == true) { - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - ConnectionSlot* connectionSlot= slots[index]; - if(connectionSlot != NULL && connectionSlot->isConnected() == true) { - vector pendingList = connectionSlot->getPendingNetworkCommandList(true); - if(pendingList.empty() == false) { - for(int idx = 0; exitServer == false && idx < (int)pendingList.size(); ++idx) { - NetworkCommand &cmd = pendingList[idx]; - this->requestCommand(&cmd); - } - //printf("Executed: %d commands from slot: %d\n",pendingList.size(),index); - } - } - } - } -} + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + ConnectionSlot* connectionSlot = slots[index]; + if (connectionSlot != NULL && + connectionSlot->getHighlightedCellList(false).empty() == false) { -void ServerInterface::dispatchPendingChatMessages(std::vector &errorMsgList) { - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + try { + std::vector highlightedCells = connectionSlot->getHighlightedCellList(true); + for (int chatIdx = 0; + exitServer == false && slots[index] != NULL && + chatIdx < (int) highlightedCells.size(); chatIdx++) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - ConnectionSlot *connectionSlot = slots[index]; + connectionSlot = slots[index]; + if (connectionSlot != NULL) { + MarkedCell msg(highlightedCells[chatIdx]); + this->setHighlightedCell(msg); - if(connectionSlot != NULL && - connectionSlot->getChatTextList(false).empty() == false) { - try { - std::vector chatText = connectionSlot->getChatTextList(true); - for(int chatIdx = 0; - exitServer == false && slots[index] != NULL && - chatIdx < (int)chatText.size(); chatIdx++) { - - connectionSlot = slots[index]; - if(connectionSlot != NULL) { - ChatMsgInfo msg(chatText[chatIdx]); - this->addChatInfo(msg); - - string newChatText = msg.chatText.c_str(); - int newChatTeamIndex = msg.chatTeamIndex; - int newChatPlayerIndex = msg.chatPlayerIndex; - string newChatLanguage = msg.targetLanguage; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 about to broadcast nmtText chatText [%s] chatTeamIndex = %d, newChatPlayerIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex,newChatPlayerIndex); - - if(newChatLanguage == "" || - newChatLanguage == connectionSlot->getNetworkPlayerLanguage()) { - - NetworkMessageText networkMessageText(newChatText.c_str(),newChatTeamIndex,newChatPlayerIndex,newChatLanguage); - broadcastMessage(&networkMessageText, connectionSlot->getPlayerIndex(),index); + NetworkMessageHighlightCell networkMessageHighlightCell(msg.getTargetPos(), msg.getFactionIndex()); + broadcastMessage(&networkMessageHighlightCell, connectionSlot->getPlayerIndex(), index); + } } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtText chatText [%s] chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex); - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] index = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,index); - // Its possible that the slot is disconnected here - // so check the original pointer again - if(slots[index] != NULL) { - slots[index]->clearChatInfo(); - } - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - errorMsgList.push_back(ex.what()); - } - } - } -} - -void ServerInterface::dispatchPendingMarkCellMessages(std::vector &errorMsgList) { - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - ConnectionSlot* connectionSlot= slots[index]; - - if(connectionSlot != NULL && - connectionSlot->getMarkedCellList(false).empty() == false) { - - try { - std::vector chatText = connectionSlot->getMarkedCellList(true); - for(int chatIdx = 0; - exitServer == false && slots[index] != NULL && - chatIdx < (int)chatText.size(); chatIdx++) { - - connectionSlot= slots[index]; - if(connectionSlot != NULL) { - MarkedCell msg(chatText[chatIdx]); - this->addMarkedCell(msg); - - NetworkMessageMarkCell networkMessageMarkCell(msg.getTargetPos(),msg.getFactionIndex(),msg.getNote(),msg.getPlayerIndex()); - broadcastMessage(&networkMessageMarkCell, connectionSlot->getPlayerIndex(),index); - //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtText chatText [%s] chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex); - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] i = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,index); - // Its possible that the slot is disconnected here - // so check the original pointer again - if(slots[index] != NULL) { - slots[index]->clearMarkedCellList(); - } - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - errorMsgList.push_back(ex.what()); - } - } - } -} -void ServerInterface::dispatchPendingHighlightCellMessages(std::vector &errorMsgList) { - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - ConnectionSlot* connectionSlot= slots[index]; - if(connectionSlot != NULL && - connectionSlot->getHighlightedCellList(false).empty() == false) { - - try { - std::vector highlightedCells = connectionSlot->getHighlightedCellList(true); - for(int chatIdx = 0; - exitServer == false && slots[index] != NULL && - chatIdx < (int)highlightedCells.size(); chatIdx++) { - - connectionSlot= slots[index]; - if(connectionSlot != NULL) { - MarkedCell msg(highlightedCells[chatIdx]); - this->setHighlightedCell(msg); - - NetworkMessageHighlightCell networkMessageHighlightCell(msg.getTargetPos(),msg.getFactionIndex()); - broadcastMessage(&networkMessageHighlightCell, connectionSlot->getPlayerIndex(),index); - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] index = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,index); - // Its possible that the slot is disconnected here - // so check the original pointer again - if(slots[index] != NULL) { - slots[index]->clearHighlightedCellList(); - } - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - errorMsgList.push_back(ex.what()); - } - } - } -} - -void ServerInterface::dispatchPendingUnMarkCellMessages(std::vector &errorMsgList) { - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - ConnectionSlot* connectionSlot= slots[index]; - if(connectionSlot != NULL && - connectionSlot->getUnMarkedCellList(false).empty() == false) { - - try { - std::vector chatText = connectionSlot->getUnMarkedCellList(true); - for(int chatIdx = 0; - exitServer == false && slots[index] != NULL && - chatIdx < (int)chatText.size(); chatIdx++) { - - connectionSlot = slots[index]; - if(connectionSlot != NULL) { - UnMarkedCell msg(chatText[chatIdx]); - this->addUnMarkedCell(msg); - - NetworkMessageUnMarkCell networkMessageMarkCell(msg.getTargetPos(),msg.getFactionIndex()); - broadcastMessage(&networkMessageMarkCell, connectionSlot->getPlayerIndex(),index); - //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtText chatText [%s] chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex); - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] i = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,index); - // Its possible that the slot is disconnected here - // so check the original pointer again - if(slots[index] != NULL) { - slots[index]->clearUnMarkedCellList(); - } - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - errorMsgList.push_back(ex.what()); - } - } - } -} - -void ServerInterface::checkForAutoResumeForLaggingClients() { - if (gameSettings.getNetworkPauseGameForLaggedClients() == true && - this->clientsAutoPausedDueToLag == true && - this->clientsAutoPausedDueToLagTimer.getMillis() >= MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS) { - - //printf("this->clientsAutoPausedDueToLag: %d [%lld]\n",this->clientsAutoPausedDueToLag,(long long)this->clientsAutoPausedDueToLagTimer.getMillis()); - if (this->clientLagCallbackInterface != NULL) { - - this->clientsAutoPausedDueToLag = false; - this->clientLagCallbackInterface->clientLagHandler(-1, false); - - this->clientsAutoPausedDueToLagTimer.reset(); - this->clientsAutoPausedDueToLagTimer.stop(); - this->clientsAutoPausedDueToLagTimer.start(); - } - } -} - -void ServerInterface::update() { - //printf("\nServerInterface::update -- A\n"); - - std::vector errorMsgList; - try { - // The first thing we will do is check all clients to ensure they have - // properly identified themselves within the alloted time period - validateConnectedClients(); - - //printf("\nServerInterface::update -- B\n"); - - processTextMessageQueue(); - processBroadCastMessageQueue(); - - checkForAutoResumeForLaggingClients(); - - //printf("\nServerInterface::update -- C\n"); - - std::map socketTriggeredList; - //update all slots - updateSocketTriggeredList(socketTriggeredList); - - //printf("\nServerInterface::update -- D\n"); - - if(gameHasBeenInitiated == false || - socketTriggeredList.empty() == false) { - //printf("\nServerInterface::update -- E\n"); - - std::map eventList; - - bool hasData = false; - if(gameHasBeenInitiated == false) { - hasData = Socket::hasDataToRead(socketTriggeredList); - } - else { - hasData = true; - } - - if(hasData && SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] hasData == true\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); - - if(gameHasBeenInitiated == false || hasData == true) { - //printf("START Server update #2\n"); - std::map mapSlotSignalledList; - - // Step #1 tell all connection slot worker threads to receive socket data - if(gameHasBeenInitiated == false) { - signalClientsToRecieveData(socketTriggeredList, eventList, mapSlotSignalledList); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #2\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //printf("START Server update #2\n"); - if(gameHasBeenInitiated == false || hasData == true) { - //printf("START Server update #3\n"); - - // Step #2 check all connection slot worker threads for completed status - if(gameHasBeenInitiated == false) { - checkForCompletedClients(mapSlotSignalledList,errorMsgList, eventList); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #3\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //printf("START Server update #4\n"); - //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - // Step #3 check clients for any lagging scenarios and try to deal with them - if(gameHasBeenInitiated == false) { - checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #4\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //printf("START Server update #5\n"); - //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - // Step #4 dispatch network commands to the pending list so that they are done in proper order - executeNetworkCommandsFromClients(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ============ Step #5\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //printf("START Server update #6\n"); - //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - // Step #5 dispatch pending chat messages - dispatchPendingChatMessages(errorMsgList); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - dispatchPendingMarkCellMessages(errorMsgList); - dispatchPendingUnMarkCellMessages(errorMsgList); - - dispatchPendingHighlightCellMessages(errorMsgList); - - if(gameHasBeenInitiated == true && - difftime((long int)time(NULL),gameStartTime) >= LAG_CHECK_GRACE_PERIOD && - difftime((long int)time(NULL),lastGlobalLagCheckTime) >= LAG_CHECK_INTERVAL_PERIOD) { - - std::map mapSlotSignalledList; - checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList); - } - //printf("START Server update #7\n"); - } - else if(gameHasBeenInitiated == true && - difftime((long int)time(NULL),gameStartTime) >= LAG_CHECK_GRACE_PERIOD && - difftime((long int)time(NULL),lastGlobalLagCheckTime) >= LAG_CHECK_INTERVAL_PERIOD) { - - //printf("Skip network data process because hasData == false\n"); - //printf("START Server update #8\n"); - - std::map mapSlotSignalledList; - checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList); - } - //printf("START Server update #9\n"); - } - else if(gameHasBeenInitiated == true && - difftime((long int)time(NULL),gameStartTime) >= LAG_CHECK_GRACE_PERIOD && - difftime((long int)time(NULL),lastGlobalLagCheckTime) >= LAG_CHECK_INTERVAL_PERIOD) { - - //printf("\nServerInterface::update -- E1\n"); - //printf("START Server update #10\n"); - - std::map mapSlotSignalledList; - checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList); - } - //printf("START Server update #11\n"); - } - else if(gameHasBeenInitiated == true && - difftime((long int)time(NULL),gameStartTime) >= LAG_CHECK_GRACE_PERIOD && - difftime((long int)time(NULL),lastGlobalLagCheckTime) >= LAG_CHECK_INTERVAL_PERIOD) { - - //printf("\nServerInterface::update -- F\n"); - //printf("START Server update #12\n"); - - std::map eventList; - std::map mapSlotSignalledList; - - checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList,errorMsgList); - } - //printf("START Server update #13\n"); - - // Check if we need to switch masterserver admin to a new player because original admin disconnected - if(gameHasBeenInitiated == true && - this->gameSettings.getMasterserver_admin() > 0) { - - bool foundAdminSlot = false; - int iFirstConnectedSlot = -1; - for(int index = 0; index < GameConstants::maxPlayers; ++index) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - if(slots[index] != NULL && slots[index]->isConnected() == true) { - if(iFirstConnectedSlot < 0) { - iFirstConnectedSlot = index; - } - if(this->gameSettings.getMasterserver_admin() == slots[index]->getSessionKey()) { - foundAdminSlot = true; - break; - } - } - } - - if(foundAdminSlot == false && iFirstConnectedSlot >= 0) { - printf("Switching masterserver admin to slot#%d...\n",iFirstConnectedSlot); - - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[iFirstConnectedSlot],CODE_AT_LINE_X(iFirstConnectedSlot)); - if(slots[iFirstConnectedSlot] != NULL) { - string sMsg = "Switching player to admin mode: " + slots[iFirstConnectedSlot]->getName(); - sendTextMessage(sMsg,-1, true,""); - - this->gameSettings.setMasterserver_admin(slots[iFirstConnectedSlot]->getSessionKey()); - this->gameSettings.setMasterserver_admin_faction_index(slots[iFirstConnectedSlot]->getPlayerIndex()); - - safeMutexSlot.ReleaseLock(); - this->broadcastGameSetup(&this->gameSettings); - } - } - } - //printf("\nServerInterface::update -- G\n"); - //printf("START Server update #14\n"); - - checkListenerSlots(); - - //printf("START Server update #15\n"); - } - catch(const exception &ex) { - //printf("\nServerInterface::update -- H\n"); - - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - errorMsgList.push_back(ex.what()); - } - - if(errorMsgList.empty() == false){ - for(int iErrIdx = 0; iErrIdx < (int)errorMsgList.size(); ++iErrIdx) { - string &sErr = errorMsgList[iErrIdx]; - if(sErr != "") { - DisplayErrorMessage(sErr); - } - } - } -} - -void ServerInterface::updateKeyframe(int frameCount) { - currentFrameCount = frameCount; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] currentFrameCount = %d, requestedCommands.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,currentFrameCount,requestedCommands.size()); - - NetworkMessageCommandList networkMessageCommandList(frameCount); - for(int index = 0; index < GameConstants::maxPlayers; ++index) { - networkMessageCommandList.setNetworkPlayerFactionCRC(index,this->getNetworkPlayerFactionCRC(index)); - } - - while(requestedCommands.empty() == false) { - // First add the command to the broadcast list (for all clients) - if(networkMessageCommandList.addCommand(&requestedCommands.back())) { - // Add the command to the local server command list - pendingCommands.push_back(requestedCommands.back()); - requestedCommands.pop_back(); - } - else { - break; - } - } - - try { - // Possible cause of out of synch since we have more commands that need - // to be sent in this frame - if(requestedCommands.empty() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING / ERROR, requestedCommands.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,requestedCommands.size()); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] WARNING / ERROR, requestedCommands.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,requestedCommands.size()); - - string sMsg = "may go out of synch: server requestedCommands.size() = " + intToStr(requestedCommands.size()); - sendTextMessage(sMsg,-1, true,""); - } - - // broadcast commands - // If we have more than 0 commands to send, automatically broadcast them - bool sendBroadcastMessage = (networkMessageCommandList.getCommandCount() > 0); - if(sendBroadcastMessage == false) { - - // Is auto pause due to lag NOT enabled - if(this->getClientsAutoPausedDueToLag() == false) { - - // ****NOTE: - // We always need to broadcast when not pause as clients - // look for broadcasts every network frame. - sendBroadcastMessage = true; - } - // Auto pause is enabled due to client lagging, only send empty command - // broadcasts every MAX_EMPTY_NETWORK_COMMAND_LIST_BROADCAST_INTERVAL_MILLISECONDS - else if(this->getClientsAutoPausedDueToLag() == true && - (lastBroadcastCommandsTimer.isStarted() == false || - lastBroadcastCommandsTimer.getMillis() >= MAX_EMPTY_NETWORK_COMMAND_LIST_BROADCAST_INTERVAL_MILLISECONDS)) { - - sendBroadcastMessage = true; - } - } - - if(sendBroadcastMessage == true) { - - if(lastBroadcastCommandsTimer.isStarted() == false) { - lastBroadcastCommandsTimer.start(); - } - else { - lastBroadcastCommandsTimer.stop(); - lastBroadcastCommandsTimer.reset(); - lastBroadcastCommandsTimer.start(); - } - broadcastMessage(&networkMessageCommandList); - } - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - DisplayErrorMessage(ex.what()); - } -} - -bool ServerInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMessageType, - ConnectionSlot *connectionSlot) { - bool discard = false; - if(connectionSlot != NULL) { - switch(networkMessageType) { - case nmtIntro: - { - discard = true; - NetworkMessageIntro msg = NetworkMessageIntro(); - connectionSlot->receiveMessage(&msg); - } - break; - case nmtPing: - { - discard = true; - NetworkMessagePing msg = NetworkMessagePing(); - connectionSlot->receiveMessage(&msg); - lastPingInfo = msg; - } - break; - - case nmtLaunch: - { - discard = true; - NetworkMessageLaunch msg = NetworkMessageLaunch(); - connectionSlot->receiveMessage(&msg); - } - break; - case nmtText: - { - discard = true; - NetworkMessageText netMsg = NetworkMessageText(); - connectionSlot->receiveMessage(&netMsg); - - ChatMsgInfo msg(netMsg.getText().c_str(),netMsg.getTeamIndex(),netMsg.getPlayerIndex(),netMsg.getTargetLanguage()); - this->addChatInfo(msg); - - string newChatText = msg.chatText.c_str(); - //string newChatSender = msg.chatSender.c_str(); - int newChatTeamIndex = msg.chatTeamIndex; - int newChatPlayerIndex = msg.chatPlayerIndex; - string newChatLanguage = msg.targetLanguage.c_str(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 about to broadcast nmtText chatText [%s] chatTeamIndex = %d, newChatPlayerIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex,newChatPlayerIndex); - - NetworkMessageText networkMessageText(newChatText.c_str(),newChatTeamIndex,newChatPlayerIndex,newChatLanguage); - broadcastMessage(&networkMessageText, connectionSlot->getPlayerIndex()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtText chatText [%s] chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex); - - } - break; - - case nmtMarkCell: - { - discard = true; - NetworkMessageMarkCell networkMessageMarkCell; - connectionSlot->receiveMessage(&networkMessageMarkCell); - - MarkedCell msg(networkMessageMarkCell.getTarget(), - networkMessageMarkCell.getFactionIndex(), - networkMessageMarkCell.getText().c_str(), - networkMessageMarkCell.getPlayerIndex()); - - this->addMarkedCell(msg); - - NetworkMessageMarkCell networkMessageMarkCellBroadcast( - networkMessageMarkCell.getTarget(), - networkMessageMarkCell.getFactionIndex(), - networkMessageMarkCell.getText().c_str(), - networkMessageMarkCell.getPlayerIndex()); - broadcastMessage(&networkMessageMarkCellBroadcast, connectionSlot->getPlayerIndex()); - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtMarkCell chatText [%s] chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex); - - } - break; - - case nmtUnMarkCell: - { - discard = true; - NetworkMessageUnMarkCell networkMessageMarkCell; - connectionSlot->receiveMessage(&networkMessageMarkCell); - - UnMarkedCell msg(networkMessageMarkCell.getTarget(), - networkMessageMarkCell.getFactionIndex()); - - this->addUnMarkedCell(msg); - - NetworkMessageUnMarkCell networkMessageMarkCellBroadcast( - networkMessageMarkCell.getTarget(), - networkMessageMarkCell.getFactionIndex()); - broadcastMessage(&networkMessageMarkCellBroadcast, connectionSlot->getPlayerIndex()); - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtMarkCell chatText [%s] chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex); - - } - break; - case nmtHighlightCell: - { - discard = true; - NetworkMessageHighlightCell networkMessageHighlightCell; - connectionSlot->receiveMessage(&networkMessageHighlightCell); - - MarkedCell msg(networkMessageHighlightCell.getTarget(), - networkMessageHighlightCell.getFactionIndex(), - "none",-1); - - this->setHighlightedCell(msg); - - NetworkMessageHighlightCell networkMessageHighlightCellBroadcast( - networkMessageHighlightCell.getTarget(), - networkMessageHighlightCell.getFactionIndex()); - broadcastMessage(&networkMessageHighlightCellBroadcast, connectionSlot->getPlayerIndex()); - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtMarkCell chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatTeamIndex); - - } - break; - - case nmtSynchNetworkGameData: - { - discard = true; - NetworkMessageSynchNetworkGameData msg = NetworkMessageSynchNetworkGameData(); - connectionSlot->receiveMessage(&msg); - } - break; - case nmtSynchNetworkGameDataStatus: - { - discard = true; - NetworkMessageSynchNetworkGameDataStatus msg = NetworkMessageSynchNetworkGameDataStatus(); - connectionSlot->receiveMessage(&msg); - } - break; - case nmtSynchNetworkGameDataFileCRCCheck: - { - discard = true; - NetworkMessageSynchNetworkGameDataFileCRCCheck msg = NetworkMessageSynchNetworkGameDataFileCRCCheck(); - connectionSlot->receiveMessage(&msg); - } - break; - case nmtSynchNetworkGameDataFileGet: - { - discard = true; - NetworkMessageSynchNetworkGameDataFileGet msg = NetworkMessageSynchNetworkGameDataFileGet(); - connectionSlot->receiveMessage(&msg); - } - break; - case nmtSwitchSetupRequest: - { - discard = true; - SwitchSetupRequest msg = SwitchSetupRequest(); - connectionSlot->receiveMessage(&msg); - } - break; - case nmtPlayerIndexMessage: - { - discard = true; - PlayerIndexMessage msg = PlayerIndexMessage(0); - connectionSlot->receiveMessage(&msg); - } - break; - } - } - return discard; -} - -void ServerInterface::waitUntilReady(Checksum *checksum) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] START\n",__FUNCTION__); - Logger & logger = Logger::getInstance(); - gameHasBeenInitiated = true; - Chrono chrono; - chrono.start(); - - bool allReady = false; - - if(Config::getInstance().getBool("EnableGameServerLoadCancel","false") == true) { - logger.setCancelLoadingEnabled(true); - } - - Lang &lang = Lang::getInstance(); - uint64 waitLoopIterationCount = 0; - uint64 MAX_LOOP_COUNT_BEFORE_SLEEP = 10; - MAX_LOOP_COUNT_BEFORE_SLEEP = Config::getInstance().getInt("NetworkServerLoopGameLoadingCap",intToStr(MAX_LOOP_COUNT_BEFORE_SLEEP).c_str()); - if(MAX_LOOP_COUNT_BEFORE_SLEEP == 0) { - MAX_LOOP_COUNT_BEFORE_SLEEP = 1; - } - int sleepMillis = Config::getInstance().getInt("NetworkServerLoopGameLoadingCapSleepMillis","10"); - int64 lastStatusUpdate = 0; - - while(exitServer == false && - allReady == false && - logger.getCancelLoading() == false) { - - waitLoopIterationCount++; - if(waitLoopIterationCount > 0 && - waitLoopIterationCount % MAX_LOOP_COUNT_BEFORE_SLEEP == 0) { - - sleep(sleepMillis); - waitLoopIterationCount = 0; - } - vector waitingForHosts; - allReady= true; - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - ConnectionSlot* connectionSlot= slots[index]; - if(connectionSlot != NULL && connectionSlot->isConnected() == true) { - if(connectionSlot->isReady() == false) { - - NetworkMessageType networkMessageType= connectionSlot->getNextMessageType(); - - // consume old messages from the lobby - bool discarded = shouldDiscardNetworkMessage(networkMessageType,connectionSlot); - if(discarded == false) { - - NetworkMessageReady networkMessageReady; - if(networkMessageType == nmtReady && - connectionSlot->receiveMessage(&networkMessageReady)) { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] networkMessageType==nmtReady\n",__FUNCTION__); - - connectionSlot->setReady(); - connectionSlot->setGameStarted(true); - } - else if(networkMessageType != nmtInvalid) { - string sErr = "Unexpected network message: " + intToStr(networkMessageType); - sendTextMessage(sErr,-1, true,"",index); - DisplayErrorMessage(sErr); - logger.setCancelLoading(false); - return; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] index = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, index); + // Its possible that the slot is disconnected here + // so check the original pointer again + if (slots[index] != NULL) { + slots[index]->clearHighlightedCellList(); } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error detected [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + errorMsgList.push_back(ex.what()); } - waitingForHosts.push_back(connectionSlot->getName()); - allReady= false; } } } - //check for timeout - if(allReady == false) { - if(chrono.getMillis() > readyWaitTimeout) { - Lang &lang= Lang::getInstance(); - const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); - for(unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { - string sErr = "Timeout waiting for clients."; - if(lang.hasString("TimeoutWaitingForClients") == true) { - sErr = lang.getString("TimeoutWaitingForClients",languageList[langIndex]); - } - bool localEcho = lang.isLanguageLocal(languageList[langIndex]); - sendTextMessage(sErr,-1, localEcho, languageList[langIndex]); - if(localEcho == true) { - DisplayErrorMessage(sErr); - } - } - logger.setCancelLoading(false); - return; - } - else { - if(chrono.getMillis() - lastStatusUpdate > 200) { - lastStatusUpdate = chrono.getMillis(); + void ServerInterface::dispatchPendingUnMarkCellMessages(std::vector &errorMsgList) { + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - string waitForHosts = ""; - for(int hostIndex = 0; hostIndex < (int)waitingForHosts.size(); hostIndex++) { - if(waitForHosts != "") { - waitForHosts += ", "; + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + ConnectionSlot* connectionSlot = slots[index]; + if (connectionSlot != NULL && + connectionSlot->getUnMarkedCellList(false).empty() == false) { + + try { + std::vector chatText = connectionSlot->getUnMarkedCellList(true); + for (int chatIdx = 0; + exitServer == false && slots[index] != NULL && + chatIdx < (int) chatText.size(); chatIdx++) { + + connectionSlot = slots[index]; + if (connectionSlot != NULL) { + UnMarkedCell msg(chatText[chatIdx]); + this->addUnMarkedCell(msg); + + NetworkMessageUnMarkCell networkMessageMarkCell(msg.getTargetPos(), msg.getFactionIndex()); + broadcastMessage(&networkMessageMarkCell, connectionSlot->getPlayerIndex(), index); + //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtText chatText [%s] chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex); + } } - waitForHosts += waitingForHosts[hostIndex]; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] i = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, index); + // Its possible that the slot is disconnected here + // so check the original pointer again + if (slots[index] != NULL) { + slots[index]->clearUnMarkedCellList(); + } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error detected [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + errorMsgList.push_back(ex.what()); + } + } + } + } + + void ServerInterface::checkForAutoResumeForLaggingClients() { + if (gameSettings.getNetworkPauseGameForLaggedClients() == true && + this->clientsAutoPausedDueToLag == true && + this->clientsAutoPausedDueToLagTimer.getMillis() >= MAX_CLIENT_WAIT_SECONDS_FOR_PAUSE_MILLISECONDS) { + + //printf("this->clientsAutoPausedDueToLag: %d [%lld]\n",this->clientsAutoPausedDueToLag,(long long)this->clientsAutoPausedDueToLagTimer.getMillis()); + if (this->clientLagCallbackInterface != NULL) { + + this->clientsAutoPausedDueToLag = false; + this->clientLagCallbackInterface->clientLagHandler(-1, false); + + this->clientsAutoPausedDueToLagTimer.reset(); + this->clientsAutoPausedDueToLagTimer.stop(); + this->clientsAutoPausedDueToLagTimer.start(); + } + } + } + + void ServerInterface::update() { + //printf("\nServerInterface::update -- A\n"); + + std::vector errorMsgList; + try { + // The first thing we will do is check all clients to ensure they have + // properly identified themselves within the alloted time period + validateConnectedClients(); + + //printf("\nServerInterface::update -- B\n"); + + processTextMessageQueue(); + processBroadCastMessageQueue(); + + checkForAutoResumeForLaggingClients(); + + //printf("\nServerInterface::update -- C\n"); + + std::map socketTriggeredList; + //update all slots + updateSocketTriggeredList(socketTriggeredList); + + //printf("\nServerInterface::update -- D\n"); + + if (gameHasBeenInitiated == false || + socketTriggeredList.empty() == false) { + //printf("\nServerInterface::update -- E\n"); + + std::map eventList; + + bool hasData = false; + if (gameHasBeenInitiated == false) { + hasData = Socket::hasDataToRead(socketTriggeredList); + } else { + hasData = true; } - char szBuf[8096]=""; - string updateTextFormat = lang.getString("NetworkGameServerLoadStatus"); - if(updateTextFormat == "" || - updateTextFormat[0] == '?') { + if (hasData && SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] hasData == true\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); - updateTextFormat = "Waiting for network: %lld seconds elapsed (maximum wait time: %d seconds)"; + if (gameHasBeenInitiated == false || hasData == true) { + //printf("START Server update #2\n"); + std::map mapSlotSignalledList; + + // Step #1 tell all connection slot worker threads to receive socket data + if (gameHasBeenInitiated == false) { + signalClientsToRecieveData(socketTriggeredList, eventList, mapSlotSignalledList); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] ============ Step #2\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + //printf("START Server update #2\n"); + if (gameHasBeenInitiated == false || hasData == true) { + //printf("START Server update #3\n"); + + // Step #2 check all connection slot worker threads for completed status + if (gameHasBeenInitiated == false) { + checkForCompletedClients(mapSlotSignalledList, errorMsgList, eventList); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] ============ Step #3\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + //printf("START Server update #4\n"); + //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + // Step #3 check clients for any lagging scenarios and try to deal with them + if (gameHasBeenInitiated == false) { + checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList, errorMsgList); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] ============ Step #4\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + //printf("START Server update #5\n"); + //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // Step #4 dispatch network commands to the pending list so that they are done in proper order + executeNetworkCommandsFromClients(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] ============ Step #5\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + //printf("START Server update #6\n"); + //printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // Step #5 dispatch pending chat messages + dispatchPendingChatMessages(errorMsgList); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + dispatchPendingMarkCellMessages(errorMsgList); + dispatchPendingUnMarkCellMessages(errorMsgList); + + dispatchPendingHighlightCellMessages(errorMsgList); + + if (gameHasBeenInitiated == true && + difftime((long int) time(NULL), gameStartTime) >= LAG_CHECK_GRACE_PERIOD && + difftime((long int) time(NULL), lastGlobalLagCheckTime) >= LAG_CHECK_INTERVAL_PERIOD) { + + std::map mapSlotSignalledList; + checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList, errorMsgList); + } + //printf("START Server update #7\n"); + } else if (gameHasBeenInitiated == true && + difftime((long int) time(NULL), gameStartTime) >= LAG_CHECK_GRACE_PERIOD && + difftime((long int) time(NULL), lastGlobalLagCheckTime) >= LAG_CHECK_INTERVAL_PERIOD) { + + //printf("Skip network data process because hasData == false\n"); + //printf("START Server update #8\n"); + + std::map mapSlotSignalledList; + checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList, errorMsgList); + } + //printf("START Server update #9\n"); + } else if (gameHasBeenInitiated == true && + difftime((long int) time(NULL), gameStartTime) >= LAG_CHECK_GRACE_PERIOD && + difftime((long int) time(NULL), lastGlobalLagCheckTime) >= LAG_CHECK_INTERVAL_PERIOD) { + + //printf("\nServerInterface::update -- E1\n"); + //printf("START Server update #10\n"); + + std::map mapSlotSignalledList; + checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList, errorMsgList); } - snprintf(szBuf,8096,updateTextFormat.c_str(),(long long int)(chrono.getMillis() / 1000),int(readyWaitTimeout / 1000)); + //printf("START Server update #11\n"); + } else if (gameHasBeenInitiated == true && + difftime((long int) time(NULL), gameStartTime) >= LAG_CHECK_GRACE_PERIOD && + difftime((long int) time(NULL), lastGlobalLagCheckTime) >= LAG_CHECK_INTERVAL_PERIOD) { - char szBuf1[8096]=""; - string statusTextFormat = lang.getString("NetworkGameStatusWaiting"); - if(statusTextFormat == "" || - statusTextFormat[0] == '?') { + //printf("\nServerInterface::update -- F\n"); + //printf("START Server update #12\n"); - statusTextFormat = "Waiting for players: %s"; - } - snprintf(szBuf1,8096,statusTextFormat.c_str(),waitForHosts.c_str()); + std::map eventList; + std::map mapSlotSignalledList; - logger.add(szBuf, true, szBuf1); + checkForLaggingClients(mapSlotSignalledList, eventList, socketTriggeredList, errorMsgList); + } + //printf("START Server update #13\n"); - uint32 loadingStatus = nmls_NONE; - //send ready message after, so clients start delayed - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex],CODE_AT_LINE_X(slotIndex)); - ConnectionSlot *connectionSlot= slots[slotIndex]; - if(connectionSlot != NULL && connectionSlot->isConnected() == true) { - // FIXME: maxPlayers is declared in game_constants.h. Code such as - // this must be updated when maxPlayers is changed - // - // The PLAYER vars are enum'ed in network_message.h - switch(slotIndex) { - case 0: - loadingStatus |= nmls_PLAYER1_CONNECTED; - if(connectionSlot->isReady()) { - loadingStatus |= nmls_PLAYER1_READY; - } - break; - case 1: - loadingStatus |= nmls_PLAYER2_CONNECTED; - if(connectionSlot->isReady()) { - loadingStatus |= nmls_PLAYER2_READY; - } - break; - case 2: - loadingStatus |= nmls_PLAYER3_CONNECTED; - if(connectionSlot->isReady()) { - loadingStatus |= nmls_PLAYER3_READY; - } - break; - case 3: - loadingStatus |= nmls_PLAYER4_CONNECTED; - if(connectionSlot->isReady()) { - loadingStatus |= nmls_PLAYER4_READY; - } - break; - case 4: - loadingStatus |= nmls_PLAYER5_CONNECTED; - if(connectionSlot->isReady()) { - loadingStatus |= nmls_PLAYER5_READY; - } - break; - case 5: - loadingStatus |= nmls_PLAYER6_CONNECTED; - if(connectionSlot->isReady()) { - loadingStatus |= nmls_PLAYER6_READY; - } - break; - case 6: - loadingStatus |= nmls_PLAYER7_CONNECTED; - if(connectionSlot->isReady()) { - loadingStatus |= nmls_PLAYER7_READY; - } - break; - case 7: - loadingStatus |= nmls_PLAYER8_CONNECTED; - if(connectionSlot->isReady()) { - loadingStatus |= nmls_PLAYER8_READY; - } - break; - case 8: - loadingStatus |= nmls_PLAYER9_CONNECTED; - if(connectionSlot->isReady()) { - loadingStatus |= nmls_PLAYER9_READY; - } - break; - case 9: - loadingStatus |= nmls_PLAYER10_CONNECTED; - if(connectionSlot->isReady()) { - loadingStatus |= nmls_PLAYER10_READY; - } - break; + // Check if we need to switch masterserver admin to a new player because original admin disconnected + if (gameHasBeenInitiated == true && + this->gameSettings.getMasterserver_admin() > 0) { + bool foundAdminSlot = false; + int iFirstConnectedSlot = -1; + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + if (slots[index] != NULL && slots[index]->isConnected() == true) { + if (iFirstConnectedSlot < 0) { + iFirstConnectedSlot = index; + } + if (this->gameSettings.getMasterserver_admin() == slots[index]->getSessionKey()) { + foundAdminSlot = true; + break; } } } - // send loading status message - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex],CODE_AT_LINE_X(slotIndex)); - ConnectionSlot* connectionSlot= slots[slotIndex]; - if(connectionSlot != NULL && connectionSlot->isConnected() == true) { - NetworkMessageLoadingStatus networkMessageLoadingStatus(loadingStatus); - connectionSlot->sendMessage(&networkMessageLoadingStatus); + if (foundAdminSlot == false && iFirstConnectedSlot >= 0) { + printf("Switching masterserver admin to slot#%d...\n", iFirstConnectedSlot); + + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[iFirstConnectedSlot], CODE_AT_LINE_X(iFirstConnectedSlot)); + if (slots[iFirstConnectedSlot] != NULL) { + string sMsg = "Switching player to admin mode: " + slots[iFirstConnectedSlot]->getName(); + sendTextMessage(sMsg, -1, true, ""); + + this->gameSettings.setMasterserver_admin(slots[iFirstConnectedSlot]->getSessionKey()); + this->gameSettings.setMasterserver_admin_faction_index(slots[iFirstConnectedSlot]->getPlayerIndex()); + + safeMutexSlot.ReleaseLock(); + this->broadcastGameSetup(&this->gameSettings); } } - - sleep(0); } + //printf("\nServerInterface::update -- G\n"); + //printf("START Server update #14\n"); + + checkListenerSlots(); + + //printf("START Server update #15\n"); + } catch (const exception &ex) { + //printf("\nServerInterface::update -- H\n"); + + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error detected [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + errorMsgList.push_back(ex.what()); } - } - Shared::Platform::Window::handleEvent(); - } - - if(logger.getCancelLoading() == true) { - Lang &lang= Lang::getInstance(); - const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); - for(unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { - - string sErr = lang.getString("GameCancelledByUser",languageList[langIndex]); - bool localEcho = lang.isLanguageLocal(languageList[langIndex]); - sendTextMessage(sErr,-1, localEcho,languageList[langIndex]); - - if(localEcho == true) { - DisplayErrorMessage(sErr); - } - } - quitGame(true); - logger.setCancelLoading(false); - return; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] PART B (telling client we are ready!\n",__FUNCTION__); - try { - //send ready message after, so clients start delayed - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex],CODE_AT_LINE_X(slotIndex)); - ConnectionSlot* connectionSlot= slots[slotIndex]; - if(connectionSlot != NULL && connectionSlot->isConnected() == true) { - NetworkMessageReady networkMessageReady(checksum->getSum()); - connectionSlot->sendMessage(&networkMessageReady); - connectionSlot->setGameStarted(true); - } - } - - gameStartTime = time(NULL); - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error detected [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - DisplayErrorMessage(ex.what()); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] END\n",__FUNCTION__); -} - -void ServerInterface::processBroadCastMessageQueue() { - MutexSafeWrapper safeMutexSlot(broadcastMessageQueueThreadAccessor,CODE_AT_LINE); - if(broadcastMessageQueue.empty() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] broadcastMessageQueue.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,broadcastMessageQueue.size()); - for(int index = 0; index < (int)broadcastMessageQueue.size(); ++index) { - pair &item = broadcastMessageQueue[index]; - if(item.first != NULL) { - this->broadcastMessage(item.first,item.second); - delete item.first; - } - item.first = NULL; - } - broadcastMessageQueue.clear(); - } -} - -void ServerInterface::queueBroadcastMessage(NetworkMessage *networkMessage, int excludeSlot) { - MutexSafeWrapper safeMutexSlot(broadcastMessageQueueThreadAccessor,CODE_AT_LINE); - pair item; - item.first = networkMessage; - item.second = excludeSlot; - broadcastMessageQueue.push_back(item); -} - -void ServerInterface::processTextMessageQueue() { - MutexSafeWrapper safeMutexSlot(textMessageQueueThreadAccessor,CODE_AT_LINE); - if(textMessageQueue.empty() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] textMessageQueue.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,textMessageQueue.size()); - for(int index = 0; index < (int)textMessageQueue.size(); ++index) { - TextMessageQueue &item = textMessageQueue[index]; - sendTextMessage(item.text, item.teamIndex, item.echoLocal, item.targetLanguage); - } - textMessageQueue.clear(); - } -} - -void ServerInterface::queueTextMessage(const string & text, int teamIndex, - bool echoLocal, string targetLanguage) { - //printf("Line: %d text [%s]\n",__LINE__,text.c_str()); - - MutexSafeWrapper safeMutexSlot(textMessageQueueThreadAccessor,CODE_AT_LINE); - TextMessageQueue item; - item.text = text; - item.teamIndex = teamIndex; - item.echoLocal = echoLocal; - item.targetLanguage = targetLanguage; - textMessageQueue.push_back(item); -} - -void ServerInterface::sendTextMessage(const string & text, int teamIndex, - bool echoLocal,string targetLanguage) { - sendTextMessage(text, teamIndex, echoLocal, targetLanguage, -1); -} - -void ServerInterface::sendTextMessage(const string& text, int teamIndex, bool echoLocal, - string targetLanguage, int lockedSlotIndex) { - //printf("Line: %d text [%s] echoLocal = %d\n",__LINE__,text.c_str(),echoLocal); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] text [%s] teamIndex = %d, echoLocal = %d, lockedSlotIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,text.c_str(),teamIndex,echoLocal,lockedSlotIndex); - - NetworkMessageText networkMessageText(text, teamIndex, getHumanPlayerIndex(), targetLanguage); - broadcastMessage(&networkMessageText, -1, lockedSlotIndex); - - if(echoLocal == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - ChatMsgInfo msg(text.c_str(),teamIndex,networkMessageText.getPlayerIndex(), targetLanguage); - this->addChatInfo(msg); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void ServerInterface::sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note,int playerIndex) { - sendMarkCellMessage(targetPos, factionIndex, note, playerIndex, -1); -} - -void ServerInterface::sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note, int playerIndex, int lockedSlotIndex) { - NetworkMessageMarkCell networkMessageMarkCell(targetPos,factionIndex, note, playerIndex); - broadcastMessage(&networkMessageMarkCell, -1, lockedSlotIndex); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void ServerInterface::sendHighlightCellMessage(Vec2i targetPos, int factionIndex) { - sendHighlightCellMessage(targetPos, factionIndex, -1); -} - -void ServerInterface::sendHighlightCellMessage(Vec2i targetPos, int factionIndex, int lockedSlotIndex) { - NetworkMessageHighlightCell networkMessageHighlightCell(targetPos,factionIndex); - broadcastMessage(&networkMessageHighlightCell, -1, lockedSlotIndex); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void ServerInterface::sendUnMarkCellMessage(Vec2i targetPos, int factionIndex) { - sendUnMarkCellMessage(targetPos, factionIndex, -1); -} - -void ServerInterface::sendUnMarkCellMessage(Vec2i targetPos, int factionIndex, int lockedSlotIndex) { - NetworkMessageUnMarkCell networkMessageMarkCell(targetPos,factionIndex); - broadcastMessage(&networkMessageMarkCell, -1, lockedSlotIndex); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void ServerInterface::quitGame(bool userManuallyQuit) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - NetworkMessageQuit networkMessageQuit; - broadcastMessage(&networkMessageQuit); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -string ServerInterface::getNetworkStatus() { - Lang &lang = Lang::getInstance(); - string str = ""; - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - ConnectionSlot *connectionSlot= slots[index]; - - str += intToStr(index)+ ": "; - - if(connectionSlot!= NULL) { - if(connectionSlot->isConnected()) { - int clientLagCount = connectionSlot->getCurrentLagCount(); - double lastClientCommandListTimeLag = difftime((long int)time(NULL),connectionSlot->getLastReceiveCommandListTime()); - //float pingTime = connectionSlot->getThreadedPingMS(connectionSlot->getIpAddress().c_str()); - char szBuf[8096]=""; - snprintf(szBuf,8096,", lag = %d [%.2f]",clientLagCount,lastClientCommandListTimeLag); - str += connectionSlot->getName() + " [" + connectionSlot->getUUID() + "] " + string(szBuf); - } - } - else { - str += lang.getString("NotConnected"); - } - - str += '\n'; - } - return str; -} - -bool ServerInterface::launchGame(const GameSettings *gameSettings) { - bool bOkToStart = true; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - for(int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { - - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - ConnectionSlot *connectionSlot= slots[index]; - if(connectionSlot != NULL && - (connectionSlot->getAllowDownloadDataSynch() == true || connectionSlot->getAllowGameDataSynchCheck() == true) && - connectionSlot->isConnected()) { - - if(connectionSlot->getNetworkGameDataSynchCheckOk() == false) { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] map [%d] tile [%d] techtree [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,connectionSlot->getNetworkGameDataSynchCheckOkMap(),connectionSlot->getNetworkGameDataSynchCheckOkTile(),connectionSlot->getNetworkGameDataSynchCheckOkTech()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] map [%d] tile [%d] techtree [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,connectionSlot->getNetworkGameDataSynchCheckOkMap(),connectionSlot->getNetworkGameDataSynchCheckOkTile(),connectionSlot->getNetworkGameDataSynchCheckOkTech()); - - bOkToStart = false; - break; - } - } - } - if(bOkToStart == true) { - - bool useInGameBlockingClientSockets = Config::getInstance().getBool("EnableInGameBlockingSockets","true"); - if(useInGameBlockingClientSockets == true) { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - for(int index = 0; index < GameConstants::maxPlayers; ++index) { - - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index],CODE_AT_LINE_X(index)); - ConnectionSlot *connectionSlot= slots[index]; - if(connectionSlot != NULL && connectionSlot->isConnected()) { - connectionSlot->getSocket()->setBlock(true); - } - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - bool requiresUPNPTrigger = false; - for(int startIndex = 0; startIndex < GameConstants::maxPlayers; ++startIndex) { - - int factionIndex = gameSettings->getFactionIndexForStartLocation(startIndex); - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[startIndex],CODE_AT_LINE_X(startIndex)); - ConnectionSlot *connectionSlot= slots[startIndex]; - if((connectionSlot == NULL || connectionSlot->isConnected() == false) && - this->getAllowInGameConnections() == true) { - - // Open slots for joining in progress game - if(gameSettings->getFactionControl(factionIndex) != ctClosed && - gameSettings->getFactionControl(factionIndex) != ctHuman) { - - //printf("Opening slot for in game connections for slot: %d, faction: %d\n",i,factionIndex); - if(connectionSlot == NULL) { - addSlot(startIndex); - connectionSlot = slots[startIndex]; - requiresUPNPTrigger = true; - } - connectionSlot->setCanAcceptConnections(true); - } - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,needToRepublishToMasterserver); - - if(this->getAllowInGameConnections() == false) { - serverSocket.stopBroadCastThread(); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,needToRepublishToMasterserver); - - this->gameSettings = *gameSettings; - //printf("#1 Data synch: lmap %u ltile: %d ltech: %u\n",gameSettings->getMapCRC(),gameSettings->getTilesetCRC(),gameSettings->getTechCRC()); - - NetworkMessageLaunch networkMessageLaunch(gameSettings,nmtLaunch); - broadcastMessage(&networkMessageLaunch); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,needToRepublishToMasterserver); - - shutdownMasterserverPublishThread(); - MutexSafeWrapper safeMutex(masterServerThreadAccessor,CODE_AT_LINE); - lastMasterserverHeartbeatTime = 0; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ftpServer = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ftpServer); - - if(this->getAllowInGameConnections() == false) { - shutdownFTPServer(); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,needToRepublishToMasterserver); - - if(publishToMasterserverThread == NULL) { - if(needToRepublishToMasterserver == true || - GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - - static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); - publishToMasterserverThread = new SimpleTaskThread(this,0,125); - publishToMasterserverThread->setUniqueID(mutexOwnerId); - publishToMasterserverThread->start(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,needToRepublishToMasterserver); - } - } - - if(this->getAllowInGameConnections() == false) { - shutdownFTPServer(); - } - - if((needToRepublishToMasterserver == true || - GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) && - requiresUPNPTrigger == true) { - - this->getServerSocket()->NETdiscoverUPnPDevices(); - } - - gameLaunched = true; - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - return bOkToStart; -} - -void ServerInterface::shutdownFTPServer() { - if(ftpServer != NULL) { - ftpServer->shutdownAndWait(); - delete ftpServer; - ftpServer = NULL; - } -} - -void ServerInterface::checkListenerSlots() { - if(gameLaunched == true && - this->getAllowInGameConnections() == true) { - - if(difftime((long int)time(NULL),lastListenerSlotCheckTime) >= 7) { - - lastListenerSlotCheckTime = time(NULL); - bool useInGameBlockingClientSockets = Config::getInstance().getBool("EnableInGameBlockingSockets","true"); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - for(int startIndex = 0; startIndex < GameConstants::maxPlayers; ++startIndex) { - - int factionIndex = gameSettings.getFactionIndexForStartLocation(startIndex); - if(gameSettings.getFactionControl(factionIndex) != ctClosed && - gameSettings.getFactionControl(factionIndex) != ctHuman) { - - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[startIndex],CODE_AT_LINE_X(startIndex)); - ConnectionSlot *connectionSlot= slots[startIndex]; - // Open slots for joining in progress game - if(connectionSlot == NULL) { - printf("Opening slot for in game connections, slot: %d, factionindex: %d name: %s\n",startIndex,factionIndex,gameSettings.getFactionTypeName(factionIndex).c_str()); - - addSlot(startIndex); - connectionSlot = slots[startIndex]; - if(useInGameBlockingClientSockets == true) { - connectionSlot->getSocket()->setBlock(true); - } - connectionSlot->setCanAcceptConnections(true); - } - else if(connectionSlot != NULL && - connectionSlot->getCanAcceptConnections() == false && - connectionSlot->isConnected() == false) { - printf("Removing slot for in game connections, slot: %d, factionindex: %d name: %s\n",startIndex,factionIndex,gameSettings.getFactionTypeName(factionIndex).c_str()); - - this->removeSlot(startIndex); + if (errorMsgList.empty() == false) { + for (int iErrIdx = 0; iErrIdx < (int) errorMsgList.size(); ++iErrIdx) { + string &sErr = errorMsgList[iErrIdx]; + if (sErr != "") { + DisplayErrorMessage(sErr); } } } } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,needToRepublishToMasterserver); -} -void ServerInterface::broadcastGameSetup(GameSettings *gameSettingsBuffer, bool setGameSettingsBuffer) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + void ServerInterface::updateKeyframe(int frameCount) { + currentFrameCount = frameCount; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] currentFrameCount = %d, requestedCommands.size() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, currentFrameCount, requestedCommands.size()); - if(gameSettingsBuffer == NULL) { - throw megaglest_runtime_error("gameSettingsBuffer == NULL"); - } - for(unsigned int factionIndex = 0; factionIndex < (unsigned int)gameSettingsBuffer->getFactionCount(); ++factionIndex) { - - int slotIndex = gameSettingsBuffer->getStartLocationIndex(factionIndex); - if(gameSettingsBuffer->getFactionControl(factionIndex) == ctNetwork && - isClientConnected(slotIndex) == false) { - - gameSettingsBuffer->setNetworkPlayerName(factionIndex,GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME); - } - } - if(setGameSettingsBuffer == true) { - validateGameSettings(gameSettingsBuffer); - } - - MutexSafeWrapper safeMutex(serverSynchAccessor,CODE_AT_LINE); - if(setGameSettingsBuffer == true) { - gameSettings = *gameSettingsBuffer; - gameSettingsUpdateCount++; - } - - NetworkMessageLaunch networkMessageLaunch(gameSettingsBuffer, nmtBroadCastSetup); - broadcastMessage(&networkMessageLaunch); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void ServerInterface::broadcastMessage(NetworkMessage *networkMessage, int excludeSlot, int lockedSlotIndex) { - try { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - MutexSafeWrapper safeMutexSlotBroadCastAccessor(inBroadcastMessageThreadAccessor,CODE_AT_LINE); - if(inBroadcastMessage == true && - dynamic_cast(networkMessage) != NULL) { - - safeMutexSlotBroadCastAccessor.ReleaseLock(); - NetworkMessageText *txtMsg = dynamic_cast(networkMessage); - if(txtMsg != NULL) { - NetworkMessageText *msgCopy = txtMsg->getCopy(); - queueBroadcastMessage(msgCopy, excludeSlot); - } - return; - } - else { - inBroadcastMessage = true; - safeMutexSlotBroadCastAccessor.ReleaseLock(true); - } - - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - MutexSafeWrapper safeMutexSlot(NULL,CODE_AT_LINE_X(slotIndex)); - if(slotIndex != lockedSlotIndex) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] i = %d, lockedSlotIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,slotIndex,lockedSlotIndex); - safeMutexSlot.setMutex(slotAccessorMutexes[slotIndex],CODE_AT_LINE_X(slotIndex)); + NetworkMessageCommandList networkMessageCommandList(frameCount); + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + networkMessageCommandList.setNetworkPlayerFactionCRC(index, this->getNetworkPlayerFactionCRC(index)); } - ConnectionSlot* connectionSlot= slots[slotIndex]; - - if(slotIndex != excludeSlot && connectionSlot != NULL) { - if(connectionSlot->isConnected()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] before sendMessage\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - connectionSlot->sendMessage(networkMessage); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after sendMessage\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - if(gameHasBeenInitiated == true && connectionSlot->isConnected() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 before removeSlot for slot# %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,slotIndex); - - if(this->getAllowInGameConnections() == false) { - removeSlot(slotIndex,slotIndex); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 after removeSlot for slot# %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,slotIndex); - } - } - else if(slotIndex == excludeSlot && gameHasBeenInitiated == true && - connectionSlot != NULL && connectionSlot->isConnected() == false) { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 before removeSlot for slot# %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,slotIndex); - - if(this->getAllowInGameConnections() == false) { - removeSlot(slotIndex,slotIndex); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 after removeSlot for slot# %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,slotIndex); - } - } - - safeMutexSlotBroadCastAccessor.Lock(); - - inBroadcastMessage = false; - - safeMutexSlotBroadCastAccessor.ReleaseLock(); - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - - MutexSafeWrapper safeMutexSlotBroadCastAccessor(inBroadcastMessageThreadAccessor,CODE_AT_LINE); - inBroadcastMessage = false; - safeMutexSlotBroadCastAccessor.ReleaseLock(); - - string sMsg = ex.what(); - sendTextMessage(sMsg,-1, true, "", lockedSlotIndex); - } -} - -void ServerInterface::broadcastMessageToConnectedClients(NetworkMessage *networkMessage, int excludeSlot) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - try { - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex],CODE_AT_LINE_X(slotIndex)); - ConnectionSlot *connectionSlot= slots[slotIndex]; - - if(slotIndex != excludeSlot && connectionSlot != NULL) { - if(connectionSlot->isConnected()) { - connectionSlot->sendMessage(networkMessage); - } - } - } - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - DisplayErrorMessage(ex.what()); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void ServerInterface::updateListen() { - if(gameHasBeenInitiated == true && - this->getAllowInGameConnections() == false) { - return; - } - - int openSlotCount = 0; - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - - bool isSlotOpen = (slots[slotIndex] != NULL && slots[slotIndex]->isConnected() == false); - if(isSlotOpen == true) { - ++openSlotCount; - } - } - - serverSocket.listen(openSlotCount); -} - -int ServerInterface::getOpenSlotCount() { - int openSlotCount = 0; - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - - bool isSlotOpen = (slots[slotIndex] != NULL && slots[slotIndex]->isConnected() == false); - if(isSlotOpen == true) { - ++openSlotCount; - } - } - return openSlotCount; -} - -int ServerInterface::getGameSettingsUpdateCount() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START gameSettingsUpdateCount = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,gameSettingsUpdateCount); - - MutexSafeWrapper safeMutex(serverSynchAccessor,CODE_AT_LINE); - int result = gameSettingsUpdateCount; - safeMutex.ReleaseLock(); - return result; -} - -void ServerInterface::validateGameSettings(GameSettings *serverGameSettings) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); - - MutexSafeWrapper safeMutex(serverSynchAccessor,CODE_AT_LINE); - string mapFile = serverGameSettings->getMap(); - //printf("Trying to set map to [%s]. Current map is [%s]\n",serverGameSettings->getMap().c_str(),gameSettings.getMap().c_str()); - if(gameSettings.getMapFilter()!=serverGameSettings->getMapFilter()){ - if( playerSortedMaps[serverGameSettings->getMapFilter()].size()==0){ - serverGameSettings->setMapFilter(0); - } - } - int playerIndex=serverGameSettings->getMapFilter(); - if(find(playerSortedMaps[playerIndex].begin(),playerSortedMaps[playerIndex].end(),mapFile) == playerSortedMaps[playerIndex].end()) { - // switch to closest map - string foundMap = ""; - for (int i = 0 ;i < (int)playerSortedMaps[playerIndex].size(); ++i) { - foundMap=playerSortedMaps[playerIndex][i]; - if(toLower(foundMap)>toLower(serverGameSettings->getMap())){ - break; - } - } - printf("map %s not found on this server. Switching to map %s\n",serverGameSettings->getMap().c_str(),foundMap.c_str()); - serverGameSettings->setMap(foundMap); - } - Checksum checksum; - string file = Config::getMapPath(serverGameSettings->getMap(),"",false); - checksum.addFile(file); - serverGameSettings->setMapCRC(checksum.getSum()); - - string tilesetFile = serverGameSettings->getTileset(); - if(find(tilesetFiles.begin(),tilesetFiles.end(),tilesetFile) == tilesetFiles.end()) { - printf("Reverting tileset from [%s] to [%s]\n",serverGameSettings->getTileset().c_str(),gameSettings.getTileset().c_str()); - - serverGameSettings->setTileset(gameSettings.getTileset()); - serverGameSettings->setTilesetCRC(gameSettings.getTilesetCRC()); - } - - string techtreeFile = serverGameSettings->getTech(); - if(find(techTreeFiles.begin(),techTreeFiles.end(),techtreeFile) == techTreeFiles.end()) { - printf("Reverting tech from [%s] to [%s]\n",serverGameSettings->getTech().c_str(),gameSettings.getTech().c_str()); - - serverGameSettings->setTech(gameSettings.getTech()); - serverGameSettings->setTechCRC(gameSettings.getTechCRC()); - } -} - -void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool waitForClientAck) { - MutexSafeWrapper safeMutex(serverSynchAccessor,CODE_AT_LINE); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START gameSettingsUpdateCount = %d, waitForClientAck = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,gameSettingsUpdateCount,waitForClientAck); - - if(serverGameSettings->getScenario() == "") { - string mapFile = serverGameSettings->getMap(); - if(find(mapFiles.begin(),mapFiles.end(),mapFile) == mapFiles.end()) { - printf("Reverting map from [%s] to [%s]\n",serverGameSettings->getMap().c_str(),gameSettings.getMap().c_str()); - - serverGameSettings->setMapFilter(gameSettings.getMapFilter()); - serverGameSettings->setMap(gameSettings.getMap()); - serverGameSettings->setMapCRC(gameSettings.getMapCRC()); - } - - string tilesetFile = serverGameSettings->getTileset(); - if(find(tilesetFiles.begin(),tilesetFiles.end(),tilesetFile) == tilesetFiles.end()) { - printf("Reverting tileset from [%s] to [%s]\n",serverGameSettings->getTileset().c_str(),gameSettings.getTileset().c_str()); - - serverGameSettings->setTileset(gameSettings.getTileset()); - serverGameSettings->setTilesetCRC(gameSettings.getTilesetCRC()); - } - - string techtreeFile = serverGameSettings->getTech(); - if(find(techTreeFiles.begin(),techTreeFiles.end(),techtreeFile) == techTreeFiles.end()) { - printf("Reverting tech from [%s] to [%s]\n",serverGameSettings->getTech().c_str(),gameSettings.getTech().c_str()); - - serverGameSettings->setTech(gameSettings.getTech()); - serverGameSettings->setTechCRC(gameSettings.getTechCRC()); - } - } - - gameSettings = *serverGameSettings; - - if(getAllowGameDataSynchCheck() == true) { - if(waitForClientAck == true && gameSettingsUpdateCount > 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Waiting for client acks #1\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); - - time_t tStart = time(NULL); - bool gotAckFromAllClients = false; - while(gotAckFromAllClients == false && difftime((long int)time(NULL),tStart) <= 5) { - gotAckFromAllClients = true; - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - //printf("===> START slot %d - About to setGameSettings #1\n",i); - - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex],CODE_AT_LINE_X(slotIndex)); - ConnectionSlot *connectionSlot = slots[slotIndex]; - if(connectionSlot != NULL && connectionSlot->isConnected()) { - if(connectionSlot->getReceivedNetworkGameStatus() == false) { - gotAckFromAllClients = false; - } - - connectionSlot->update(true,slotIndex); - } - //printf("===> END slot %d - About to setGameSettings #1\n",i); - } - } - } - - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex],CODE_AT_LINE_X(slotIndex)); - ConnectionSlot *connectionSlot = slots[slotIndex]; - if(connectionSlot != NULL && connectionSlot->isConnected()) { - connectionSlot->setReceivedNetworkGameStatus(false); - } - } - - NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData(getGameSettings()); - broadcastMessageToConnectedClients(&networkMessageSynchNetworkGameData); - - if(waitForClientAck == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Waiting for client acks #2\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); - - time_t tStart = time(NULL); - bool gotAckFromAllClients = false; - while(gotAckFromAllClients == false && difftime((long int)time(NULL),tStart) <= 5) { - gotAckFromAllClients = true; - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - //printf("===> START slot %d - About to setGameSettings 2\n",slotIndex); - - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex],CODE_AT_LINE_X(slotIndex)); - ConnectionSlot *connectionSlot = slots[slotIndex]; - if(connectionSlot != NULL && connectionSlot->isConnected()) { - if(connectionSlot->getReceivedNetworkGameStatus() == false) { - gotAckFromAllClients = false; - } - - connectionSlot->update(true,slotIndex); - } - //printf("===> END slot %d - About to setGameSettings 2\n",slotIndex); - } - } - } - - } - gameSettingsUpdateCount++; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); -} - -void ServerInterface::close() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); -} - -string ServerInterface::getHumanPlayerName(int index) { - string result = Config::getInstance().getString("NetPlayerName", Socket::getHostName().c_str()); - if(index >= 0 || gameSettings.getThisFactionIndex() >= 0) { - if(index < 0) { - index = gameSettings.getThisFactionIndex(); - } - if(gameSettings.getNetworkPlayerName(index) != "") { - result = gameSettings.getNetworkPlayerName(index); - } - } - - return result; -} - -int ServerInterface::getHumanPlayerIndex() const { - return gameSettings.getStartLocationIndex(gameSettings.getThisFactionIndex()); -} - -std::map ServerInterface::publishToMasterserver() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - int slotCountUsed = 1; - int slotCountHumans = 1; - int slotCountConnectedPlayers = 1; - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - slotCountUsed = 0; - slotCountHumans = 0; - slotCountConnectedPlayers = 0; - } - - Config & config = Config::getInstance(); - std::map < string, string > publishToServerInfo; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex],CODE_AT_LINE_X(slotIndex)); - if(slots[slotIndex] != NULL) { - slotCountUsed++; - slotCountHumans++; - ConnectionSlot* connectionSlot= slots[slotIndex]; - if((connectionSlot!=NULL) && (connectionSlot->isConnected())) { - slotCountConnectedPlayers++; - } - } - } - publishToServerInfo["uuid"] = Config::getInstance().getString("PlayerId",""); - publishToServerInfo["glestVersion"] = glestVersionString; - publishToServerInfo["platform"] = getPlatformNameString(); - publishToServerInfo["binaryCompileDate"] = getCompileDateTime(); - publishToServerInfo["serverTitle"] = this->getGameSettings()->getGameName(); - publishToServerInfo["tech"] = this->getGameSettings()->getTech(); - publishToServerInfo["map"] = this->getGameSettings()->getMap(); - publishToServerInfo["tileset"] = this->getGameSettings()->getTileset(); - - bool updateSlots = true; - MutexSafeWrapper safeMutex2(gameStatsThreadAccessor,CODE_AT_LINE); - if(gameStats != NULL) { - for(int factionIndex = 0; factionIndex < gameStats->getFactionCount(); ++factionIndex) { - if(gameStats->getVictory(factionIndex) == true) { - updateSlots = false; - break; - } - } - } - safeMutex2.ReleaseLock(); - - if(updateSlots == true) { - publishToServerInfo["activeSlots"] = intToStr(slotCountUsed); - publishToServerInfo["networkSlots"] = intToStr(slotCountHumans); - publishToServerInfo["connectedClients"] = intToStr(slotCountConnectedPlayers); - } - - string serverPort = config.getString("PortServer", intToStr(GameConstants::serverPort).c_str()); - string externalPort = config.getString("PortExternal", serverPort.c_str()); - publishToServerInfo["externalconnectport"] = externalPort; - publishToServerInfo["privacyPlease"] = intToStr(config.getBool("PrivacyPlease","false")); - publishToServerInfo["gameStatus"] = intToStr(game_status_in_progress); - - if(publishToMasterserverThread == NULL) { - publishToServerInfo["gameCmd"] = "gameOver"; - publishToServerInfo["gameStatus"] = intToStr(game_status_finished); - } - - //printf("Host game id = %s\n",this->getGameSettings()->getGameUUID().c_str()); - publishToServerInfo["gameUUID"] = this->getGameSettings()->getGameUUID(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return publishToServerInfo; -} - -std::map ServerInterface::publishToMasterserverStats() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - MutexSafeWrapper safeMutex(gameStatsThreadAccessor,CODE_AT_LINE); - std::map < string, string > publishToServerInfo; - if(gameStats != NULL) { - publishToServerInfo["gameUUID"] = this->getGameSettings()->getGameUUID(); - publishToServerInfo["tech"] = this->getGameSettings()->getTech(); - publishToServerInfo["factionCount"] = intToStr(gameStats->getFactionCount()); - publishToServerInfo["framesPlayed"] = intToStr(gameStats->getFramesPlayed()); - publishToServerInfo["framesToCalculatePlaytime"] = intToStr(gameStats->getFramesToCalculatePlaytime()); - publishToServerInfo["maxConcurrentUnitCount"] = intToStr(gameStats->getMaxConcurrentUnitCount()); - publishToServerInfo["totalEndGameConcurrentUnitCount"] = intToStr(gameStats->getTotalEndGameConcurrentUnitCount()); - publishToServerInfo["isHeadlessServer"] = intToStr(gameStats->getIsMasterserverMode()); - - for(int factionIndex = 0; factionIndex < gameStats->getFactionCount(); ++factionIndex) { - publishToServerInfo["factionIndex_" + intToStr(factionIndex)] = intToStr(factionIndex); - publishToServerInfo["controlType_" + intToStr(factionIndex)] = intToStr(gameStats->getControl(factionIndex)); - publishToServerInfo["resourceMultiplier_" + intToStr(factionIndex)] = floatToStr(gameStats->getResourceMultiplier(factionIndex)); - publishToServerInfo["factionTypeName_" + intToStr(factionIndex)] = gameStats->getFactionTypeName(factionIndex); - publishToServerInfo["personalityType_" + intToStr(factionIndex)] = intToStr(gameStats->getPersonalityType(factionIndex)); - publishToServerInfo["teamIndex_" + intToStr(factionIndex)] = intToStr(gameStats->getTeam(factionIndex)); - publishToServerInfo["wonGame_" + intToStr(factionIndex)] = intToStr(gameStats->getVictory(factionIndex)); - publishToServerInfo["killCount_" + intToStr(factionIndex)] = intToStr(gameStats->getKills(factionIndex)); - publishToServerInfo["enemyKillCount_" + intToStr(factionIndex)] = intToStr(gameStats->getEnemyKills(factionIndex)); - publishToServerInfo["deathCount_" + intToStr(factionIndex)] = intToStr(gameStats->getDeaths(factionIndex)); - publishToServerInfo["unitsProducedCount_" + intToStr(factionIndex)] = intToStr(gameStats->getUnitsProduced(factionIndex)); - publishToServerInfo["resourceHarvestedCount_" + intToStr(factionIndex)] = intToStr(gameStats->getResourcesHarvested(factionIndex)); - publishToServerInfo["playerName_" + intToStr(factionIndex)] = gameStats->getPlayerName(factionIndex); - publishToServerInfo["quitBeforeGameEnd_" + intToStr(factionIndex)] = intToStr(gameStats->getPlayerLeftBeforeEnd(factionIndex)); - publishToServerInfo["quitTime_" + intToStr(factionIndex)] = intToStr(gameStats->getTimePlayerLeft(factionIndex)); - publishToServerInfo["playerUUID_" + intToStr(factionIndex)] = this->getGameSettings()->getNetworkPlayerUUID(factionIndex); - publishToServerInfo["platform_" + intToStr(factionIndex)] = this->getGameSettings()->getNetworkPlayerPlatform(factionIndex); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - return publishToServerInfo; -} - -void ServerInterface::setGameStats(Stats *stats) { - if(stats == NULL) { - return; - } - MutexSafeWrapper safeMutex(gameStatsThreadAccessor,CODE_AT_LINE); - if(gameStats == NULL) { - gameStats = new Stats(); - } - *gameStats = *stats; -} - -void ServerInterface::simpleTask(BaseThread *callingThread,void *userdata) { - MutexSafeWrapper safeMutex(masterServerThreadAccessor,CODE_AT_LINE); - - if(difftime((long int)time(NULL),lastMasterserverHeartbeatTime) >= MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Checking to see masterserver needs an update of the game status [%d] callingThread [%p] publishToMasterserverThread [%p]\n",needToRepublishToMasterserver,callingThread,publishToMasterserverThread); - - lastMasterserverHeartbeatTime = time(NULL); - if(needToRepublishToMasterserver == true) { - try { - if(Config::getInstance().getString("Masterserver","") != "") { - string request = Config::getInstance().getString("Masterserver"); - if(request != "") { - endPathWithSlash(request,false); - } - request += "addServerInfo.php?"; - - std::map newPublishToServerInfo = publishToMasterserver(); - - CURL *handle = SystemFlags::initHTTP(); - for(std::map::const_iterator iterMap = newPublishToServerInfo.begin(); - iterMap != newPublishToServerInfo.end(); ++iterMap) { - - request += iterMap->first; - request += "="; - request += SystemFlags::escapeURL(iterMap->second,handle); - request += "&"; - } - - //printf("The Host request is:\n%s\n",request.c_str()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("The Host request is:\n%s\n",request.c_str()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d] the request is:\n%s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,request.c_str()); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Calling masterserver [%s]...\n",request.c_str()); - - std::string serverInfo = SystemFlags::getHTTP(request,handle); - //printf("Result:\n%s\n",serverInfo .c_str()); - - string requestStats = Config::getInstance().getString("Masterserver"); - if(requestStats != "") { - endPathWithSlash(requestStats,false); - } - requestStats += "addGameStats.php?"; - - std::map newPublishToServerInfoStats = publishToMasterserverStats(); - if(newPublishToServerInfoStats.empty() == false) { - for(std::map::const_iterator iterMap = newPublishToServerInfoStats.begin(); - iterMap != newPublishToServerInfoStats.end(); ++iterMap) { - - requestStats += iterMap->first; - requestStats += "="; - requestStats += SystemFlags::escapeURL(iterMap->second,handle); - requestStats += "&"; - } - - //printf("The Host stats request is:\n%s\n",requestStats.c_str()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("The Host request is:\n%s\n",requestStats.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d] the request is:\n%s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,requestStats.c_str()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Calling masterserver [%s]...\n",requestStats.c_str()); - - std::string serverInfoStats = SystemFlags::getHTTP(requestStats,handle); - //printf("Result:\n%s\n",serverInfoStats .c_str()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d] the result is:\n'%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,serverInfoStats.c_str()); - } - - SystemFlags::cleanupHTTP(&handle); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Done Calling masterserver\n"); - - //printf("the result is:\n'%s'\n",serverInfo.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d] the result is:\n'%s'\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,serverInfo.c_str()); - } - else { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line %d] error, no masterserver defined!\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line %d] error during game status update: [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - } - } - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - DumpStatsToLog(false); - } - } - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - //printf("Attempt Accept\n"); - if(serverSocketAdmin != NULL) { - Socket *cli = serverSocketAdmin->accept(false); - if(cli != NULL) { - printf("Got status request connection, dumping info...\n"); - - string data = DumpStatsToLog(true); - cli->send(data.c_str(),(int)data.length()); - cli->disconnectSocket(); - } - } - } -} - -std::string ServerInterface::DumpStatsToLog(bool dumpToStringOnly) const { - string headlessLogFile = Config::getInstance().getString("HeadlessLogFile","headless.log"); - if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { - headlessLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + headlessLogFile ; - } - else { - string userData = Config::getInstance().getString("UserData_Root",""); - if(userData != "") { - endPathWithSlash(userData); - } - headlessLogFile = userData + headlessLogFile ; - } - - ostringstream out; - out << "=========================================" << std::endl; - out << "Headless Server Current Game information:" << std::endl; - out << "=========================================" << std::endl; - - int connectedSlotCount = 0; - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex],CODE_AT_LINE_X(slotIndex)); - ConnectionSlot *slot = slots[slotIndex]; - if(slot != NULL) { - - connectedSlotCount++; - out << "Network connection for index: " << slotIndex << std::endl; - out << "------------------------------" << std::endl; - out << "Connected: " << boolToStr(slot->isConnected()) << std::endl; - out << "Handshake received: " << boolToStr(slot->getConnectHasHandshaked()) << std::endl; - if(slot->isConnected() == true) { - - time_t connectTime = slot->getConnectedTime(); - //struct tm *loctime = localtime (&connectTime); - struct tm loctime = threadsafe_localtime(connectTime); - char szBuf[8096] = ""; - strftime(szBuf,100,"%Y-%m-%d %H:%M:%S",&loctime); - - const int HOURS_IN_DAY = 24; - const int MINUTES_IN_HOUR = 60; - const int SECONDS_IN_MINUTE = 60; - int InSeconds = difftime((long int)time(NULL),slot->getConnectedTime()); - // compute seconds - int seconds = InSeconds % SECONDS_IN_MINUTE ; - // throw away seconds used in previous statement and convert to minutes - int InMinutes = InSeconds / SECONDS_IN_MINUTE ; - // compute minutes - int minutes = InMinutes % MINUTES_IN_HOUR ; - - // throw away minutes used in previous statement and convert to hours - int InHours = InMinutes / MINUTES_IN_HOUR ; - // compute hours - int hours = InHours % HOURS_IN_DAY ; - - out << "Connected at: " << szBuf << std::endl; - out << "Connection duration: " << hours << " hours " << minutes << " minutes " << seconds << " seconds." << std::endl; - out << "Player Index: " << slot->getPlayerIndex() << std::endl; - out << "IP Address: " << slot->getIpAddress() << std::endl; - out << "Player name: " << slot->getName() << std::endl; - out << "Player uuid: " << slot->getUUID() << std::endl; - out << "Language: " << slot->getNetworkPlayerLanguage() << std::endl; - out << "Game Version: " << slot->getVersionString() << std::endl; - out << "Session id: " << slot->getSessionKey() << std::endl; - out << "Socket id: " << slot->getSocketId() << std::endl; - } - } - } - out << "Total Slot Count: " << connectedSlotCount << std::endl; - out << "=========================================" << std::endl; - - std::string result = out.str(); - - if(dumpToStringOnly == false) { - -#if defined(WIN32) && !defined(__MINGW32__) - FILE *fp = _wfopen(utf8_decode(headlessLogFile ).c_str(), L"w"); - std::ofstream logFile(fp); -#else - std::ofstream logFile; - logFile.open(headlessLogFile .c_str(), ios_base::out | ios_base::trunc); -#endif - logFile << result; - logFile.close(); -#if defined(WIN32) && !defined(__MINGW32__) - if(fp) { - fclose(fp); - } -#endif - } - - return result; -} - -void ServerInterface::notifyBadClientConnectAttempt(string ipAddress) { - //printf("In [%s::%s Line: %d] ipAddress [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ipAddress.c_str()); - - if(badClientConnectIPList.find(ipAddress) == badClientConnectIPList.end()) { - badClientConnectIPList[ipAddress] = make_pair(0,(long int)time(NULL)); - } - - pair &lastBadConnectionAttempt = badClientConnectIPList[ipAddress]; - - const uint64 BLOCK_BAD_CLIENT_CONNECT_MAX_SECONDS = Config::getInstance().getInt("BlockBadClientConnectMaxSeconds", "60"); - const uint64 BLOCK_BAD_CLIENT_CONNECT_MAX_ATTEMPTS = Config::getInstance().getInt("BlockBadClientConnectMaxAttempts", "6"); - bool addToBlockedClientsList = false; - - if(difftime((long int)time(NULL),lastBadConnectionAttempt.second) <= BLOCK_BAD_CLIENT_CONNECT_MAX_SECONDS) { - - if(lastBadConnectionAttempt.first+1 > BLOCK_BAD_CLIENT_CONNECT_MAX_ATTEMPTS) { - addToBlockedClientsList = true; - } - } - else { - // Reset after x seconds - lastBadConnectionAttempt.first = 0; - } - - if(this->getAllowInGameConnections() == true) { - printf("notifyBadClientConnectAttempt() #1: %s!\n",ipAddress.c_str()); - } - - if(addToBlockedClientsList == true) { - serverSocket.addIPAddressToBlockedList(ipAddress); - } - - lastBadConnectionAttempt.first++; - lastBadConnectionAttempt.second = time(NULL); -} - -bool ServerInterface::getStartInGameConnectionLaunch() { - bool result = false; - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - MutexSafeWrapper safeMutex(slotAccessorMutexes[slotIndex],CODE_AT_LINE_X(slotIndex)); - if(slots[slotIndex] != NULL) { - - ConnectionSlot *slot = slots[slotIndex]; - if(slot->getStartInGameConnectionLaunch() == true) { - result = true; - break; - } - } - } - return result; -} - -bool ServerInterface::getPauseForInGameConnection() { - bool result = false; - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - MutexSafeWrapper safeMutex(slotAccessorMutexes[slotIndex],CODE_AT_LINE_X(slotIndex)); - if(slots[slotIndex] != NULL) { - - ConnectionSlot *slot = slots[slotIndex]; - if(slot->getPauseForInGameConnection() == true) { - result = true; - break; - } - } - } - return result; -} - -bool ServerInterface::getUnPauseForInGameConnection() { - bool result = false; - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - MutexSafeWrapper safeMutex(slotAccessorMutexes[slotIndex],CODE_AT_LINE_X(slotIndex)); - if(slots[slotIndex] != NULL) { - - ConnectionSlot *slot = slots[slotIndex]; - if(slot->isConnected() == true) { - if(slot->isReady() == true) { - result = true; - if(slot->getUnPauseForInGameConnection() == false) { - result = false; - break; - } - } - else { - result = false; + while (requestedCommands.empty() == false) { + // First add the command to the broadcast list (for all clients) + if (networkMessageCommandList.addCommand(&requestedCommands.back())) { + // Add the command to the local server command list + pendingCommands.push_back(requestedCommands.back()); + requestedCommands.pop_back(); + } else { break; } } + + try { + // Possible cause of out of synch since we have more commands that need + // to be sent in this frame + if (requestedCommands.empty() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] WARNING / ERROR, requestedCommands.size() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, requestedCommands.size()); + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] WARNING / ERROR, requestedCommands.size() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, requestedCommands.size()); + + string sMsg = "may go out of synch: server requestedCommands.size() = " + intToStr(requestedCommands.size()); + sendTextMessage(sMsg, -1, true, ""); + } + + // broadcast commands + // If we have more than 0 commands to send, automatically broadcast them + bool sendBroadcastMessage = (networkMessageCommandList.getCommandCount() > 0); + if (sendBroadcastMessage == false) { + + // Is auto pause due to lag NOT enabled + if (this->getClientsAutoPausedDueToLag() == false) { + + // ****NOTE: + // We always need to broadcast when not pause as clients + // look for broadcasts every network frame. + sendBroadcastMessage = true; + } + // Auto pause is enabled due to client lagging, only send empty command + // broadcasts every MAX_EMPTY_NETWORK_COMMAND_LIST_BROADCAST_INTERVAL_MILLISECONDS + else if (this->getClientsAutoPausedDueToLag() == true && + (lastBroadcastCommandsTimer.isStarted() == false || + lastBroadcastCommandsTimer.getMillis() >= MAX_EMPTY_NETWORK_COMMAND_LIST_BROADCAST_INTERVAL_MILLISECONDS)) { + + sendBroadcastMessage = true; + } + } + + if (sendBroadcastMessage == true) { + + if (lastBroadcastCommandsTimer.isStarted() == false) { + lastBroadcastCommandsTimer.start(); + } else { + lastBroadcastCommandsTimer.stop(); + lastBroadcastCommandsTimer.reset(); + lastBroadcastCommandsTimer.start(); + } + broadcastMessage(&networkMessageCommandList); + } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error detected [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + DisplayErrorMessage(ex.what()); + } } - } - if(result == true) { - resumeGameStartTime = time(NULL); - } - return result; -} -ConnectionSlot * ServerInterface::findSlotForUUID(string uuid, bool unConnectedOnly) { - ConnectionSlot *result = NULL; - if(uuid != "") { - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + bool ServerInterface::shouldDiscardNetworkMessage(NetworkMessageType networkMessageType, + ConnectionSlot *connectionSlot) { + bool discard = false; + if (connectionSlot != NULL) { + switch (networkMessageType) { + case nmtIntro: + { + discard = true; + NetworkMessageIntro msg = NetworkMessageIntro(); + connectionSlot->receiveMessage(&msg); + } + break; + case nmtPing: + { + discard = true; + NetworkMessagePing msg = NetworkMessagePing(); + connectionSlot->receiveMessage(&msg); + lastPingInfo = msg; + } + break; - MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex],CODE_AT_LINE_X(slotIndex)); - ConnectionSlot *connectionSlot= slots[slotIndex]; + case nmtLaunch: + { + discard = true; + NetworkMessageLaunch msg = NetworkMessageLaunch(); + connectionSlot->receiveMessage(&msg); + } + break; + case nmtText: + { + discard = true; + NetworkMessageText netMsg = NetworkMessageText(); + connectionSlot->receiveMessage(&netMsg); - if(connectionSlot != NULL) { - if(connectionSlot->getUUID() == uuid) { - if(unConnectedOnly == false || - (unConnectedOnly == true && connectionSlot->isConnected() == false)) { + ChatMsgInfo msg(netMsg.getText().c_str(), netMsg.getTeamIndex(), netMsg.getPlayerIndex(), netMsg.getTargetLanguage()); + this->addChatInfo(msg); - if(result == NULL || - (result->getConnectedTime() > connectionSlot->getConnectedTime())) + string newChatText = msg.chatText.c_str(); + //string newChatSender = msg.chatSender.c_str(); + int newChatTeamIndex = msg.chatTeamIndex; + int newChatPlayerIndex = msg.chatPlayerIndex; + string newChatLanguage = msg.targetLanguage.c_str(); - result = connectionSlot; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] #1 about to broadcast nmtText chatText [%s] chatTeamIndex = %d, newChatPlayerIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, newChatText.c_str(), newChatTeamIndex, newChatPlayerIndex); + + NetworkMessageText networkMessageText(newChatText.c_str(), newChatTeamIndex, newChatPlayerIndex, newChatLanguage); + broadcastMessage(&networkMessageText, connectionSlot->getPlayerIndex()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] after broadcast nmtText chatText [%s] chatTeamIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, newChatText.c_str(), newChatTeamIndex); + + } + break; + + case nmtMarkCell: + { + discard = true; + NetworkMessageMarkCell networkMessageMarkCell; + connectionSlot->receiveMessage(&networkMessageMarkCell); + + MarkedCell msg(networkMessageMarkCell.getTarget(), + networkMessageMarkCell.getFactionIndex(), + networkMessageMarkCell.getText().c_str(), + networkMessageMarkCell.getPlayerIndex()); + + this->addMarkedCell(msg); + + NetworkMessageMarkCell networkMessageMarkCellBroadcast( + networkMessageMarkCell.getTarget(), + networkMessageMarkCell.getFactionIndex(), + networkMessageMarkCell.getText().c_str(), + networkMessageMarkCell.getPlayerIndex()); + broadcastMessage(&networkMessageMarkCellBroadcast, connectionSlot->getPlayerIndex()); + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtMarkCell chatText [%s] chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex); + + } + break; + + case nmtUnMarkCell: + { + discard = true; + NetworkMessageUnMarkCell networkMessageMarkCell; + connectionSlot->receiveMessage(&networkMessageMarkCell); + + UnMarkedCell msg(networkMessageMarkCell.getTarget(), + networkMessageMarkCell.getFactionIndex()); + + this->addUnMarkedCell(msg); + + NetworkMessageUnMarkCell networkMessageMarkCellBroadcast( + networkMessageMarkCell.getTarget(), + networkMessageMarkCell.getFactionIndex()); + broadcastMessage(&networkMessageMarkCellBroadcast, connectionSlot->getPlayerIndex()); + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtMarkCell chatText [%s] chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatText.c_str(),newChatTeamIndex); + + } + break; + case nmtHighlightCell: + { + discard = true; + NetworkMessageHighlightCell networkMessageHighlightCell; + connectionSlot->receiveMessage(&networkMessageHighlightCell); + + MarkedCell msg(networkMessageHighlightCell.getTarget(), + networkMessageHighlightCell.getFactionIndex(), + "none", -1); + + this->setHighlightedCell(msg); + + NetworkMessageHighlightCell networkMessageHighlightCellBroadcast( + networkMessageHighlightCell.getTarget(), + networkMessageHighlightCell.getFactionIndex()); + broadcastMessage(&networkMessageHighlightCellBroadcast, connectionSlot->getPlayerIndex()); + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] after broadcast nmtMarkCell chatTeamIndex = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,newChatTeamIndex); + + } + break; + + case nmtSynchNetworkGameData: + { + discard = true; + NetworkMessageSynchNetworkGameData msg = NetworkMessageSynchNetworkGameData(); + connectionSlot->receiveMessage(&msg); + } + break; + case nmtSynchNetworkGameDataStatus: + { + discard = true; + NetworkMessageSynchNetworkGameDataStatus msg = NetworkMessageSynchNetworkGameDataStatus(); + connectionSlot->receiveMessage(&msg); + } + break; + case nmtSynchNetworkGameDataFileCRCCheck: + { + discard = true; + NetworkMessageSynchNetworkGameDataFileCRCCheck msg = NetworkMessageSynchNetworkGameDataFileCRCCheck(); + connectionSlot->receiveMessage(&msg); + } + break; + case nmtSynchNetworkGameDataFileGet: + { + discard = true; + NetworkMessageSynchNetworkGameDataFileGet msg = NetworkMessageSynchNetworkGameDataFileGet(); + connectionSlot->receiveMessage(&msg); + } + break; + case nmtSwitchSetupRequest: + { + discard = true; + SwitchSetupRequest msg = SwitchSetupRequest(); + connectionSlot->receiveMessage(&msg); + } + break; + case nmtPlayerIndexMessage: + { + discard = true; + PlayerIndexMessage msg = PlayerIndexMessage(0); + connectionSlot->receiveMessage(&msg); + } + break; + } + } + return discard; + } + + void ServerInterface::waitUntilReady(Checksum *checksum) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s] START\n", __FUNCTION__); + Logger & logger = Logger::getInstance(); + gameHasBeenInitiated = true; + Chrono chrono; + chrono.start(); + + bool allReady = false; + + if (Config::getInstance().getBool("EnableGameServerLoadCancel", "false") == true) { + logger.setCancelLoadingEnabled(true); + } + + Lang &lang = Lang::getInstance(); + uint64 waitLoopIterationCount = 0; + uint64 MAX_LOOP_COUNT_BEFORE_SLEEP = 10; + MAX_LOOP_COUNT_BEFORE_SLEEP = Config::getInstance().getInt("NetworkServerLoopGameLoadingCap", intToStr(MAX_LOOP_COUNT_BEFORE_SLEEP).c_str()); + if (MAX_LOOP_COUNT_BEFORE_SLEEP == 0) { + MAX_LOOP_COUNT_BEFORE_SLEEP = 1; + } + int sleepMillis = Config::getInstance().getInt("NetworkServerLoopGameLoadingCapSleepMillis", "10"); + int64 lastStatusUpdate = 0; + + while (exitServer == false && + allReady == false && + logger.getCancelLoading() == false) { + + waitLoopIterationCount++; + if (waitLoopIterationCount > 0 && + waitLoopIterationCount % MAX_LOOP_COUNT_BEFORE_SLEEP == 0) { + + sleep(sleepMillis); + waitLoopIterationCount = 0; + } + vector waitingForHosts; + allReady = true; + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + ConnectionSlot* connectionSlot = slots[index]; + if (connectionSlot != NULL && connectionSlot->isConnected() == true) { + if (connectionSlot->isReady() == false) { + + NetworkMessageType networkMessageType = connectionSlot->getNextMessageType(); + + // consume old messages from the lobby + bool discarded = shouldDiscardNetworkMessage(networkMessageType, connectionSlot); + if (discarded == false) { + + NetworkMessageReady networkMessageReady; + if (networkMessageType == nmtReady && + connectionSlot->receiveMessage(&networkMessageReady)) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s] networkMessageType==nmtReady\n", __FUNCTION__); + + connectionSlot->setReady(); + connectionSlot->setGameStarted(true); + } else if (networkMessageType != nmtInvalid) { + string sErr = "Unexpected network message: " + intToStr(networkMessageType); + sendTextMessage(sErr, -1, true, "", index); + DisplayErrorMessage(sErr); + logger.setCancelLoading(false); + return; + } + } + waitingForHosts.push_back(connectionSlot->getName()); + allReady = false; + } + } + } + + //check for timeout + if (allReady == false) { + if (chrono.getMillis() > readyWaitTimeout) { + Lang &lang = Lang::getInstance(); + const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); + for (unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { + string sErr = "Timeout waiting for clients."; + if (lang.hasString("TimeoutWaitingForClients") == true) { + sErr = lang.getString("TimeoutWaitingForClients", languageList[langIndex]); + } + bool localEcho = lang.isLanguageLocal(languageList[langIndex]); + sendTextMessage(sErr, -1, localEcho, languageList[langIndex]); + if (localEcho == true) { + DisplayErrorMessage(sErr); + } + } + logger.setCancelLoading(false); + return; + } else { + if (chrono.getMillis() - lastStatusUpdate > 200) { + lastStatusUpdate = chrono.getMillis(); + + string waitForHosts = ""; + for (int hostIndex = 0; hostIndex < (int) waitingForHosts.size(); hostIndex++) { + if (waitForHosts != "") { + waitForHosts += ", "; + } + waitForHosts += waitingForHosts[hostIndex]; + } + + char szBuf[8096] = ""; + string updateTextFormat = lang.getString("NetworkGameServerLoadStatus"); + if (updateTextFormat == "" || + updateTextFormat[0] == '?') { + + updateTextFormat = "Waiting for network: %lld seconds elapsed (maximum wait time: %d seconds)"; + } + snprintf(szBuf, 8096, updateTextFormat.c_str(), (long long int)(chrono.getMillis() / 1000), int(readyWaitTimeout / 1000)); + + char szBuf1[8096] = ""; + string statusTextFormat = lang.getString("NetworkGameStatusWaiting"); + if (statusTextFormat == "" || + statusTextFormat[0] == '?') { + + statusTextFormat = "Waiting for players: %s"; + } + snprintf(szBuf1, 8096, statusTextFormat.c_str(), waitForHosts.c_str()); + + logger.add(szBuf, true, szBuf1); + + uint32 loadingStatus = nmls_NONE; + //send ready message after, so clients start delayed + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex], CODE_AT_LINE_X(slotIndex)); + ConnectionSlot *connectionSlot = slots[slotIndex]; + if (connectionSlot != NULL && connectionSlot->isConnected() == true) { + // FIXME: maxPlayers is declared in game_constants.h. Code such as + // this must be updated when maxPlayers is changed + // + // The PLAYER vars are enum'ed in network_message.h + switch (slotIndex) { + case 0: + loadingStatus |= nmls_PLAYER1_CONNECTED; + if (connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER1_READY; + } + break; + case 1: + loadingStatus |= nmls_PLAYER2_CONNECTED; + if (connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER2_READY; + } + break; + case 2: + loadingStatus |= nmls_PLAYER3_CONNECTED; + if (connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER3_READY; + } + break; + case 3: + loadingStatus |= nmls_PLAYER4_CONNECTED; + if (connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER4_READY; + } + break; + case 4: + loadingStatus |= nmls_PLAYER5_CONNECTED; + if (connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER5_READY; + } + break; + case 5: + loadingStatus |= nmls_PLAYER6_CONNECTED; + if (connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER6_READY; + } + break; + case 6: + loadingStatus |= nmls_PLAYER7_CONNECTED; + if (connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER7_READY; + } + break; + case 7: + loadingStatus |= nmls_PLAYER8_CONNECTED; + if (connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER8_READY; + } + break; + case 8: + loadingStatus |= nmls_PLAYER9_CONNECTED; + if (connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER9_READY; + } + break; + case 9: + loadingStatus |= nmls_PLAYER10_CONNECTED; + if (connectionSlot->isReady()) { + loadingStatus |= nmls_PLAYER10_READY; + } + break; + + } + } + } + + // send loading status message + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex], CODE_AT_LINE_X(slotIndex)); + ConnectionSlot* connectionSlot = slots[slotIndex]; + if (connectionSlot != NULL && connectionSlot->isConnected() == true) { + NetworkMessageLoadingStatus networkMessageLoadingStatus(loadingStatus); + connectionSlot->sendMessage(&networkMessageLoadingStatus); + } + } + + sleep(0); + } + } + } + + Shared::Platform::Window::handleEvent(); + } + + if (logger.getCancelLoading() == true) { + Lang &lang = Lang::getInstance(); + const vector languageList = this->gameSettings.getUniqueNetworkPlayerLanguages(); + for (unsigned int langIndex = 0; langIndex < languageList.size(); ++langIndex) { + + string sErr = lang.getString("GameCancelledByUser", languageList[langIndex]); + bool localEcho = lang.isLanguageLocal(languageList[langIndex]); + sendTextMessage(sErr, -1, localEcho, languageList[langIndex]); + + if (localEcho == true) { + DisplayErrorMessage(sErr); + } + } + quitGame(true); + logger.setCancelLoading(false); + return; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s] PART B (telling client we are ready!\n", __FUNCTION__); + try { + //send ready message after, so clients start delayed + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex], CODE_AT_LINE_X(slotIndex)); + ConnectionSlot* connectionSlot = slots[slotIndex]; + if (connectionSlot != NULL && connectionSlot->isConnected() == true) { + NetworkMessageReady networkMessageReady(checksum->getSum()); + connectionSlot->sendMessage(&networkMessageReady); + connectionSlot->setGameStarted(true); + } + } + + gameStartTime = time(NULL); + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error detected [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + DisplayErrorMessage(ex.what()); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s] END\n", __FUNCTION__); + } + + void ServerInterface::processBroadCastMessageQueue() { + MutexSafeWrapper safeMutexSlot(broadcastMessageQueueThreadAccessor, CODE_AT_LINE); + if (broadcastMessageQueue.empty() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] broadcastMessageQueue.size() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, broadcastMessageQueue.size()); + for (int index = 0; index < (int) broadcastMessageQueue.size(); ++index) { + pair &item = broadcastMessageQueue[index]; + if (item.first != NULL) { + this->broadcastMessage(item.first, item.second); + delete item.first; + } + item.first = NULL; + } + broadcastMessageQueue.clear(); + } + } + + void ServerInterface::queueBroadcastMessage(NetworkMessage *networkMessage, int excludeSlot) { + MutexSafeWrapper safeMutexSlot(broadcastMessageQueueThreadAccessor, CODE_AT_LINE); + pair item; + item.first = networkMessage; + item.second = excludeSlot; + broadcastMessageQueue.push_back(item); + } + + void ServerInterface::processTextMessageQueue() { + MutexSafeWrapper safeMutexSlot(textMessageQueueThreadAccessor, CODE_AT_LINE); + if (textMessageQueue.empty() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] textMessageQueue.size() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, textMessageQueue.size()); + for (int index = 0; index < (int) textMessageQueue.size(); ++index) { + TextMessageQueue &item = textMessageQueue[index]; + sendTextMessage(item.text, item.teamIndex, item.echoLocal, item.targetLanguage); + } + textMessageQueue.clear(); + } + } + + void ServerInterface::queueTextMessage(const string & text, int teamIndex, + bool echoLocal, string targetLanguage) { + //printf("Line: %d text [%s]\n",__LINE__,text.c_str()); + + MutexSafeWrapper safeMutexSlot(textMessageQueueThreadAccessor, CODE_AT_LINE); + TextMessageQueue item; + item.text = text; + item.teamIndex = teamIndex; + item.echoLocal = echoLocal; + item.targetLanguage = targetLanguage; + textMessageQueue.push_back(item); + } + + void ServerInterface::sendTextMessage(const string & text, int teamIndex, + bool echoLocal, string targetLanguage) { + sendTextMessage(text, teamIndex, echoLocal, targetLanguage, -1); + } + + void ServerInterface::sendTextMessage(const string& text, int teamIndex, bool echoLocal, + string targetLanguage, int lockedSlotIndex) { + //printf("Line: %d text [%s] echoLocal = %d\n",__LINE__,text.c_str(),echoLocal); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] text [%s] teamIndex = %d, echoLocal = %d, lockedSlotIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, text.c_str(), teamIndex, echoLocal, lockedSlotIndex); + + NetworkMessageText networkMessageText(text, teamIndex, getHumanPlayerIndex(), targetLanguage); + broadcastMessage(&networkMessageText, -1, lockedSlotIndex); + + if (echoLocal == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + ChatMsgInfo msg(text.c_str(), teamIndex, networkMessageText.getPlayerIndex(), targetLanguage); + this->addChatInfo(msg); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void ServerInterface::sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note, int playerIndex) { + sendMarkCellMessage(targetPos, factionIndex, note, playerIndex, -1); + } + + void ServerInterface::sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note, int playerIndex, int lockedSlotIndex) { + NetworkMessageMarkCell networkMessageMarkCell(targetPos, factionIndex, note, playerIndex); + broadcastMessage(&networkMessageMarkCell, -1, lockedSlotIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void ServerInterface::sendHighlightCellMessage(Vec2i targetPos, int factionIndex) { + sendHighlightCellMessage(targetPos, factionIndex, -1); + } + + void ServerInterface::sendHighlightCellMessage(Vec2i targetPos, int factionIndex, int lockedSlotIndex) { + NetworkMessageHighlightCell networkMessageHighlightCell(targetPos, factionIndex); + broadcastMessage(&networkMessageHighlightCell, -1, lockedSlotIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void ServerInterface::sendUnMarkCellMessage(Vec2i targetPos, int factionIndex) { + sendUnMarkCellMessage(targetPos, factionIndex, -1); + } + + void ServerInterface::sendUnMarkCellMessage(Vec2i targetPos, int factionIndex, int lockedSlotIndex) { + NetworkMessageUnMarkCell networkMessageMarkCell(targetPos, factionIndex); + broadcastMessage(&networkMessageMarkCell, -1, lockedSlotIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void ServerInterface::quitGame(bool userManuallyQuit) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + NetworkMessageQuit networkMessageQuit; + broadcastMessage(&networkMessageQuit); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + string ServerInterface::getNetworkStatus() { + Lang &lang = Lang::getInstance(); + string str = ""; + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + ConnectionSlot *connectionSlot = slots[index]; + + str += intToStr(index) + ": "; + + if (connectionSlot != NULL) { + if (connectionSlot->isConnected()) { + int clientLagCount = connectionSlot->getCurrentLagCount(); + double lastClientCommandListTimeLag = difftime((long int) time(NULL), connectionSlot->getLastReceiveCommandListTime()); + //float pingTime = connectionSlot->getThreadedPingMS(connectionSlot->getIpAddress().c_str()); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, ", lag = %d [%.2f]", clientLagCount, lastClientCommandListTimeLag); + str += connectionSlot->getName() + " [" + connectionSlot->getUUID() + "] " + string(szBuf); + } + } else { + str += lang.getString("NotConnected"); + } + + str += '\n'; + } + return str; + } + + bool ServerInterface::launchGame(const GameSettings *gameSettings) { + bool bOkToStart = true; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + for (int index = 0; exitServer == false && index < GameConstants::maxPlayers; ++index) { + + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + ConnectionSlot *connectionSlot = slots[index]; + if (connectionSlot != NULL && + (connectionSlot->getAllowDownloadDataSynch() == true || connectionSlot->getAllowGameDataSynchCheck() == true) && + connectionSlot->isConnected()) { + + if (connectionSlot->getNetworkGameDataSynchCheckOk() == false) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] map [%d] tile [%d] techtree [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, connectionSlot->getNetworkGameDataSynchCheckOkMap(), connectionSlot->getNetworkGameDataSynchCheckOkTile(), connectionSlot->getNetworkGameDataSynchCheckOkTech()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] map [%d] tile [%d] techtree [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, connectionSlot->getNetworkGameDataSynchCheckOkMap(), connectionSlot->getNetworkGameDataSynchCheckOkTile(), connectionSlot->getNetworkGameDataSynchCheckOkTech()); + + bOkToStart = false; + break; + } + } + } + if (bOkToStart == true) { + + bool useInGameBlockingClientSockets = Config::getInstance().getBool("EnableInGameBlockingSockets", "true"); + if (useInGameBlockingClientSockets == true) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + for (int index = 0; index < GameConstants::maxPlayers; ++index) { + + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[index], CODE_AT_LINE_X(index)); + ConnectionSlot *connectionSlot = slots[index]; + if (connectionSlot != NULL && connectionSlot->isConnected()) { + connectionSlot->getSocket()->setBlock(true); + } + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + bool requiresUPNPTrigger = false; + for (int startIndex = 0; startIndex < GameConstants::maxPlayers; ++startIndex) { + + int factionIndex = gameSettings->getFactionIndexForStartLocation(startIndex); + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[startIndex], CODE_AT_LINE_X(startIndex)); + ConnectionSlot *connectionSlot = slots[startIndex]; + if ((connectionSlot == NULL || connectionSlot->isConnected() == false) && + this->getAllowInGameConnections() == true) { + + // Open slots for joining in progress game + if (gameSettings->getFactionControl(factionIndex) != ctClosed && + gameSettings->getFactionControl(factionIndex) != ctHuman) { + + //printf("Opening slot for in game connections for slot: %d, faction: %d\n",i,factionIndex); + if (connectionSlot == NULL) { + addSlot(startIndex); + connectionSlot = slots[startIndex]; + requiresUPNPTrigger = true; + } + connectionSlot->setCanAcceptConnections(true); + } + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, needToRepublishToMasterserver); + + if (this->getAllowInGameConnections() == false) { + serverSocket.stopBroadCastThread(); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, needToRepublishToMasterserver); + + this->gameSettings = *gameSettings; + //printf("#1 Data synch: lmap %u ltile: %d ltech: %u\n",gameSettings->getMapCRC(),gameSettings->getTilesetCRC(),gameSettings->getTechCRC()); + + NetworkMessageLaunch networkMessageLaunch(gameSettings, nmtLaunch); + broadcastMessage(&networkMessageLaunch); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, needToRepublishToMasterserver); + + shutdownMasterserverPublishThread(); + MutexSafeWrapper safeMutex(masterServerThreadAccessor, CODE_AT_LINE); + lastMasterserverHeartbeatTime = 0; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] ftpServer = %p\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ftpServer); + + if (this->getAllowInGameConnections() == false) { + shutdownFTPServer(); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, needToRepublishToMasterserver); + + if (publishToMasterserverThread == NULL) { + if (needToRepublishToMasterserver == true || + GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + + static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); + publishToMasterserverThread = new SimpleTaskThread(this, 0, 125); + publishToMasterserverThread->setUniqueID(mutexOwnerId); + publishToMasterserverThread->start(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, needToRepublishToMasterserver); + } + } + + if (this->getAllowInGameConnections() == false) { + shutdownFTPServer(); + } + + if ((needToRepublishToMasterserver == true || + GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) && + requiresUPNPTrigger == true) { + + this->getServerSocket()->NETdiscoverUPnPDevices(); + } + + gameLaunched = true; + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + return bOkToStart; + } + + void ServerInterface::shutdownFTPServer() { + if (ftpServer != NULL) { + ftpServer->shutdownAndWait(); + delete ftpServer; + ftpServer = NULL; + } + } + + void ServerInterface::checkListenerSlots() { + if (gameLaunched == true && + this->getAllowInGameConnections() == true) { + + if (difftime((long int) time(NULL), lastListenerSlotCheckTime) >= 7) { + + lastListenerSlotCheckTime = time(NULL); + bool useInGameBlockingClientSockets = Config::getInstance().getBool("EnableInGameBlockingSockets", "true"); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + for (int startIndex = 0; startIndex < GameConstants::maxPlayers; ++startIndex) { + + int factionIndex = gameSettings.getFactionIndexForStartLocation(startIndex); + if (gameSettings.getFactionControl(factionIndex) != ctClosed && + gameSettings.getFactionControl(factionIndex) != ctHuman) { + + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[startIndex], CODE_AT_LINE_X(startIndex)); + ConnectionSlot *connectionSlot = slots[startIndex]; + // Open slots for joining in progress game + if (connectionSlot == NULL) { + printf("Opening slot for in game connections, slot: %d, factionindex: %d name: %s\n", startIndex, factionIndex, gameSettings.getFactionTypeName(factionIndex).c_str()); + + addSlot(startIndex); + connectionSlot = slots[startIndex]; + if (useInGameBlockingClientSockets == true) { + connectionSlot->getSocket()->setBlock(true); + } + connectionSlot->setCanAcceptConnections(true); + } else if (connectionSlot != NULL && + connectionSlot->getCanAcceptConnections() == false && + connectionSlot->isConnected() == false) { + printf("Removing slot for in game connections, slot: %d, factionindex: %d name: %s\n", startIndex, factionIndex, gameSettings.getFactionTypeName(factionIndex).c_str()); + + this->removeSlot(startIndex); + } + } + } + } + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] needToRepublishToMasterserver = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, needToRepublishToMasterserver); + } + + void ServerInterface::broadcastGameSetup(GameSettings *gameSettingsBuffer, bool setGameSettingsBuffer) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (gameSettingsBuffer == NULL) { + throw megaglest_runtime_error("gameSettingsBuffer == NULL"); + } + for (unsigned int factionIndex = 0; factionIndex < (unsigned int) gameSettingsBuffer->getFactionCount(); ++factionIndex) { + + int slotIndex = gameSettingsBuffer->getStartLocationIndex(factionIndex); + if (gameSettingsBuffer->getFactionControl(factionIndex) == ctNetwork && + isClientConnected(slotIndex) == false) { + + gameSettingsBuffer->setNetworkPlayerName(factionIndex, GameConstants::NETWORK_SLOT_UNCONNECTED_SLOTNAME); + } + } + if (setGameSettingsBuffer == true) { + validateGameSettings(gameSettingsBuffer); + } + + MutexSafeWrapper safeMutex(serverSynchAccessor, CODE_AT_LINE); + if (setGameSettingsBuffer == true) { + gameSettings = *gameSettingsBuffer; + gameSettingsUpdateCount++; + } + + NetworkMessageLaunch networkMessageLaunch(gameSettingsBuffer, nmtBroadCastSetup); + broadcastMessage(&networkMessageLaunch); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void ServerInterface::broadcastMessage(NetworkMessage *networkMessage, int excludeSlot, int lockedSlotIndex) { + try { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + MutexSafeWrapper safeMutexSlotBroadCastAccessor(inBroadcastMessageThreadAccessor, CODE_AT_LINE); + if (inBroadcastMessage == true && + dynamic_cast(networkMessage) != NULL) { + + safeMutexSlotBroadCastAccessor.ReleaseLock(); + NetworkMessageText *txtMsg = dynamic_cast(networkMessage); + if (txtMsg != NULL) { + NetworkMessageText *msgCopy = txtMsg->getCopy(); + queueBroadcastMessage(msgCopy, excludeSlot); + } + return; + } else { + inBroadcastMessage = true; + safeMutexSlotBroadCastAccessor.ReleaseLock(true); + } + + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + MutexSafeWrapper safeMutexSlot(NULL, CODE_AT_LINE_X(slotIndex)); + if (slotIndex != lockedSlotIndex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] i = %d, lockedSlotIndex = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, slotIndex, lockedSlotIndex); + safeMutexSlot.setMutex(slotAccessorMutexes[slotIndex], CODE_AT_LINE_X(slotIndex)); + } + + ConnectionSlot* connectionSlot = slots[slotIndex]; + + if (slotIndex != excludeSlot && connectionSlot != NULL) { + if (connectionSlot->isConnected()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] before sendMessage\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + connectionSlot->sendMessage(networkMessage); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] after sendMessage\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + if (gameHasBeenInitiated == true && connectionSlot->isConnected() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] #1 before removeSlot for slot# %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, slotIndex); + + if (this->getAllowInGameConnections() == false) { + removeSlot(slotIndex, slotIndex); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] #1 after removeSlot for slot# %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, slotIndex); + } + } else if (slotIndex == excludeSlot && gameHasBeenInitiated == true && + connectionSlot != NULL && connectionSlot->isConnected() == false) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] #2 before removeSlot for slot# %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, slotIndex); + + if (this->getAllowInGameConnections() == false) { + removeSlot(slotIndex, slotIndex); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] #2 after removeSlot for slot# %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, slotIndex); + } + } + + safeMutexSlotBroadCastAccessor.Lock(); + + inBroadcastMessage = false; + + safeMutexSlotBroadCastAccessor.ReleaseLock(); + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] ERROR [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + + MutexSafeWrapper safeMutexSlotBroadCastAccessor(inBroadcastMessageThreadAccessor, CODE_AT_LINE); + inBroadcastMessage = false; + safeMutexSlotBroadCastAccessor.ReleaseLock(); + + string sMsg = ex.what(); + sendTextMessage(sMsg, -1, true, "", lockedSlotIndex); + } + } + + void ServerInterface::broadcastMessageToConnectedClients(NetworkMessage *networkMessage, int excludeSlot) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + try { + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex], CODE_AT_LINE_X(slotIndex)); + ConnectionSlot *connectionSlot = slots[slotIndex]; + + if (slotIndex != excludeSlot && connectionSlot != NULL) { + if (connectionSlot->isConnected()) { + connectionSlot->sendMessage(networkMessage); + } + } + } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] ERROR [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + DisplayErrorMessage(ex.what()); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void ServerInterface::updateListen() { + if (gameHasBeenInitiated == true && + this->getAllowInGameConnections() == false) { + return; + } + + int openSlotCount = 0; + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + + bool isSlotOpen = (slots[slotIndex] != NULL && slots[slotIndex]->isConnected() == false); + if (isSlotOpen == true) { + ++openSlotCount; + } + } + + serverSocket.listen(openSlotCount); + } + + int ServerInterface::getOpenSlotCount() { + int openSlotCount = 0; + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + + bool isSlotOpen = (slots[slotIndex] != NULL && slots[slotIndex]->isConnected() == false); + if (isSlotOpen == true) { + ++openSlotCount; + } + } + return openSlotCount; + } + + int ServerInterface::getGameSettingsUpdateCount() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] START gameSettingsUpdateCount = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, gameSettingsUpdateCount); + + MutexSafeWrapper safeMutex(serverSynchAccessor, CODE_AT_LINE); + int result = gameSettingsUpdateCount; + safeMutex.ReleaseLock(); + return result; + } + + void ServerInterface::validateGameSettings(GameSettings *serverGameSettings) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + + MutexSafeWrapper safeMutex(serverSynchAccessor, CODE_AT_LINE); + string mapFile = serverGameSettings->getMap(); + //printf("Trying to set map to [%s]. Current map is [%s]\n",serverGameSettings->getMap().c_str(),gameSettings.getMap().c_str()); + if (gameSettings.getMapFilter() != serverGameSettings->getMapFilter()) { + if (playerSortedMaps[serverGameSettings->getMapFilter()].size() == 0) { + serverGameSettings->setMapFilter(0); + } + } + int playerIndex = serverGameSettings->getMapFilter(); + if (find(playerSortedMaps[playerIndex].begin(), playerSortedMaps[playerIndex].end(), mapFile) == playerSortedMaps[playerIndex].end()) { + // switch to closest map + string foundMap = ""; + for (int i = 0; i < (int) playerSortedMaps[playerIndex].size(); ++i) { + foundMap = playerSortedMaps[playerIndex][i]; + if (toLower(foundMap) > toLower(serverGameSettings->getMap())) { + break; + } + } + printf("map %s not found on this server. Switching to map %s\n", serverGameSettings->getMap().c_str(), foundMap.c_str()); + serverGameSettings->setMap(foundMap); + } + Checksum checksum; + string file = Config::getMapPath(serverGameSettings->getMap(), "", false); + checksum.addFile(file); + serverGameSettings->setMapCRC(checksum.getSum()); + + string tilesetFile = serverGameSettings->getTileset(); + if (find(tilesetFiles.begin(), tilesetFiles.end(), tilesetFile) == tilesetFiles.end()) { + printf("Reverting tileset from [%s] to [%s]\n", serverGameSettings->getTileset().c_str(), gameSettings.getTileset().c_str()); + + serverGameSettings->setTileset(gameSettings.getTileset()); + serverGameSettings->setTilesetCRC(gameSettings.getTilesetCRC()); + } + + string techtreeFile = serverGameSettings->getTech(); + if (find(techTreeFiles.begin(), techTreeFiles.end(), techtreeFile) == techTreeFiles.end()) { + printf("Reverting tech from [%s] to [%s]\n", serverGameSettings->getTech().c_str(), gameSettings.getTech().c_str()); + + serverGameSettings->setTech(gameSettings.getTech()); + serverGameSettings->setTechCRC(gameSettings.getTechCRC()); + } + } + + void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool waitForClientAck) { + MutexSafeWrapper safeMutex(serverSynchAccessor, CODE_AT_LINE); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] START gameSettingsUpdateCount = %d, waitForClientAck = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, gameSettingsUpdateCount, waitForClientAck); + + if (serverGameSettings->getScenario() == "") { + string mapFile = serverGameSettings->getMap(); + if (find(mapFiles.begin(), mapFiles.end(), mapFile) == mapFiles.end()) { + printf("Reverting map from [%s] to [%s]\n", serverGameSettings->getMap().c_str(), gameSettings.getMap().c_str()); + + serverGameSettings->setMapFilter(gameSettings.getMapFilter()); + serverGameSettings->setMap(gameSettings.getMap()); + serverGameSettings->setMapCRC(gameSettings.getMapCRC()); + } + + string tilesetFile = serverGameSettings->getTileset(); + if (find(tilesetFiles.begin(), tilesetFiles.end(), tilesetFile) == tilesetFiles.end()) { + printf("Reverting tileset from [%s] to [%s]\n", serverGameSettings->getTileset().c_str(), gameSettings.getTileset().c_str()); + + serverGameSettings->setTileset(gameSettings.getTileset()); + serverGameSettings->setTilesetCRC(gameSettings.getTilesetCRC()); + } + + string techtreeFile = serverGameSettings->getTech(); + if (find(techTreeFiles.begin(), techTreeFiles.end(), techtreeFile) == techTreeFiles.end()) { + printf("Reverting tech from [%s] to [%s]\n", serverGameSettings->getTech().c_str(), gameSettings.getTech().c_str()); + + serverGameSettings->setTech(gameSettings.getTech()); + serverGameSettings->setTechCRC(gameSettings.getTechCRC()); + } + } + + gameSettings = *serverGameSettings; + + if (getAllowGameDataSynchCheck() == true) { + if (waitForClientAck == true && gameSettingsUpdateCount > 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Waiting for client acks #1\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + + time_t tStart = time(NULL); + bool gotAckFromAllClients = false; + while (gotAckFromAllClients == false && difftime((long int) time(NULL), tStart) <= 5) { + gotAckFromAllClients = true; + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + //printf("===> START slot %d - About to setGameSettings #1\n",i); + + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex], CODE_AT_LINE_X(slotIndex)); + ConnectionSlot *connectionSlot = slots[slotIndex]; + if (connectionSlot != NULL && connectionSlot->isConnected()) { + if (connectionSlot->getReceivedNetworkGameStatus() == false) { + gotAckFromAllClients = false; + } + + connectionSlot->update(true, slotIndex); + } + //printf("===> END slot %d - About to setGameSettings #1\n",i); + } + } + } + + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex], CODE_AT_LINE_X(slotIndex)); + ConnectionSlot *connectionSlot = slots[slotIndex]; + if (connectionSlot != NULL && connectionSlot->isConnected()) { + connectionSlot->setReceivedNetworkGameStatus(false); + } + } + + NetworkMessageSynchNetworkGameData networkMessageSynchNetworkGameData(getGameSettings()); + broadcastMessageToConnectedClients(&networkMessageSynchNetworkGameData); + + if (waitForClientAck == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Waiting for client acks #2\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + + time_t tStart = time(NULL); + bool gotAckFromAllClients = false; + while (gotAckFromAllClients == false && difftime((long int) time(NULL), tStart) <= 5) { + gotAckFromAllClients = true; + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + //printf("===> START slot %d - About to setGameSettings 2\n",slotIndex); + + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex], CODE_AT_LINE_X(slotIndex)); + ConnectionSlot *connectionSlot = slots[slotIndex]; + if (connectionSlot != NULL && connectionSlot->isConnected()) { + if (connectionSlot->getReceivedNetworkGameStatus() == false) { + gotAckFromAllClients = false; + } + + connectionSlot->update(true, slotIndex); + } + //printf("===> END slot %d - About to setGameSettings 2\n",slotIndex); + } + } + } + + } + gameSettingsUpdateCount++; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] END\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + } + + void ServerInterface::close() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] START\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__); + } + + string ServerInterface::getHumanPlayerName(int index) { + string result = Config::getInstance().getString("NetPlayerName", Socket::getHostName().c_str()); + if (index >= 0 || gameSettings.getThisFactionIndex() >= 0) { + if (index < 0) { + index = gameSettings.getThisFactionIndex(); + } + if (gameSettings.getNetworkPlayerName(index) != "") { + result = gameSettings.getNetworkPlayerName(index); + } + } + + return result; + } + + int ServerInterface::getHumanPlayerIndex() const { + return gameSettings.getStartLocationIndex(gameSettings.getThisFactionIndex()); + } + + std::map ServerInterface::publishToMasterserver() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + int slotCountUsed = 1; + int slotCountHumans = 1; + int slotCountConnectedPlayers = 1; + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + slotCountUsed = 0; + slotCountHumans = 0; + slotCountConnectedPlayers = 0; + } + + Config & config = Config::getInstance(); + std::map < string, string > publishToServerInfo; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex], CODE_AT_LINE_X(slotIndex)); + if (slots[slotIndex] != NULL) { + slotCountUsed++; + slotCountHumans++; + ConnectionSlot* connectionSlot = slots[slotIndex]; + if ((connectionSlot != NULL) && (connectionSlot->isConnected())) { + slotCountConnectedPlayers++; + } + } + } + publishToServerInfo["uuid"] = Config::getInstance().getString("PlayerId", ""); + publishToServerInfo["glestVersion"] = glestVersionString; + publishToServerInfo["platform"] = getPlatformNameString(); + publishToServerInfo["binaryCompileDate"] = getCompileDateTime(); + publishToServerInfo["serverTitle"] = this->getGameSettings()->getGameName(); + publishToServerInfo["tech"] = this->getGameSettings()->getTech(); + publishToServerInfo["map"] = this->getGameSettings()->getMap(); + publishToServerInfo["tileset"] = this->getGameSettings()->getTileset(); + + bool updateSlots = true; + MutexSafeWrapper safeMutex2(gameStatsThreadAccessor, CODE_AT_LINE); + if (gameStats != NULL) { + for (int factionIndex = 0; factionIndex < gameStats->getFactionCount(); ++factionIndex) { + if (gameStats->getVictory(factionIndex) == true) { + updateSlots = false; + break; + } + } + } + safeMutex2.ReleaseLock(); + + if (updateSlots == true) { + publishToServerInfo["activeSlots"] = intToStr(slotCountUsed); + publishToServerInfo["networkSlots"] = intToStr(slotCountHumans); + publishToServerInfo["connectedClients"] = intToStr(slotCountConnectedPlayers); + } + + string serverPort = config.getString("PortServer", intToStr(GameConstants::serverPort).c_str()); + string externalPort = config.getString("PortExternal", serverPort.c_str()); + publishToServerInfo["externalconnectport"] = externalPort; + publishToServerInfo["privacyPlease"] = intToStr(config.getBool("PrivacyPlease", "false")); + publishToServerInfo["gameStatus"] = intToStr(game_status_in_progress); + + if (publishToMasterserverThread == NULL) { + publishToServerInfo["gameCmd"] = "gameOver"; + publishToServerInfo["gameStatus"] = intToStr(game_status_finished); + } + + //printf("Host game id = %s\n",this->getGameSettings()->getGameUUID().c_str()); + publishToServerInfo["gameUUID"] = this->getGameSettings()->getGameUUID(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + return publishToServerInfo; + } + + std::map ServerInterface::publishToMasterserverStats() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + MutexSafeWrapper safeMutex(gameStatsThreadAccessor, CODE_AT_LINE); + std::map < string, string > publishToServerInfo; + if (gameStats != NULL) { + publishToServerInfo["gameUUID"] = this->getGameSettings()->getGameUUID(); + publishToServerInfo["tech"] = this->getGameSettings()->getTech(); + publishToServerInfo["factionCount"] = intToStr(gameStats->getFactionCount()); + publishToServerInfo["framesPlayed"] = intToStr(gameStats->getFramesPlayed()); + publishToServerInfo["framesToCalculatePlaytime"] = intToStr(gameStats->getFramesToCalculatePlaytime()); + publishToServerInfo["maxConcurrentUnitCount"] = intToStr(gameStats->getMaxConcurrentUnitCount()); + publishToServerInfo["totalEndGameConcurrentUnitCount"] = intToStr(gameStats->getTotalEndGameConcurrentUnitCount()); + publishToServerInfo["isHeadlessServer"] = intToStr(gameStats->getIsMasterserverMode()); + + for (int factionIndex = 0; factionIndex < gameStats->getFactionCount(); ++factionIndex) { + publishToServerInfo["factionIndex_" + intToStr(factionIndex)] = intToStr(factionIndex); + publishToServerInfo["controlType_" + intToStr(factionIndex)] = intToStr(gameStats->getControl(factionIndex)); + publishToServerInfo["resourceMultiplier_" + intToStr(factionIndex)] = floatToStr(gameStats->getResourceMultiplier(factionIndex)); + publishToServerInfo["factionTypeName_" + intToStr(factionIndex)] = gameStats->getFactionTypeName(factionIndex); + publishToServerInfo["personalityType_" + intToStr(factionIndex)] = intToStr(gameStats->getPersonalityType(factionIndex)); + publishToServerInfo["teamIndex_" + intToStr(factionIndex)] = intToStr(gameStats->getTeam(factionIndex)); + publishToServerInfo["wonGame_" + intToStr(factionIndex)] = intToStr(gameStats->getVictory(factionIndex)); + publishToServerInfo["killCount_" + intToStr(factionIndex)] = intToStr(gameStats->getKills(factionIndex)); + publishToServerInfo["enemyKillCount_" + intToStr(factionIndex)] = intToStr(gameStats->getEnemyKills(factionIndex)); + publishToServerInfo["deathCount_" + intToStr(factionIndex)] = intToStr(gameStats->getDeaths(factionIndex)); + publishToServerInfo["unitsProducedCount_" + intToStr(factionIndex)] = intToStr(gameStats->getUnitsProduced(factionIndex)); + publishToServerInfo["resourceHarvestedCount_" + intToStr(factionIndex)] = intToStr(gameStats->getResourcesHarvested(factionIndex)); + publishToServerInfo["playerName_" + intToStr(factionIndex)] = gameStats->getPlayerName(factionIndex); + publishToServerInfo["quitBeforeGameEnd_" + intToStr(factionIndex)] = intToStr(gameStats->getPlayerLeftBeforeEnd(factionIndex)); + publishToServerInfo["quitTime_" + intToStr(factionIndex)] = intToStr(gameStats->getTimePlayerLeft(factionIndex)); + publishToServerInfo["playerUUID_" + intToStr(factionIndex)] = this->getGameSettings()->getNetworkPlayerUUID(factionIndex); + publishToServerInfo["platform_" + intToStr(factionIndex)] = this->getGameSettings()->getNetworkPlayerPlatform(factionIndex); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + return publishToServerInfo; + } + + void ServerInterface::setGameStats(Stats *stats) { + if (stats == NULL) { + return; + } + MutexSafeWrapper safeMutex(gameStatsThreadAccessor, CODE_AT_LINE); + if (gameStats == NULL) { + gameStats = new Stats(); + } + *gameStats = *stats; + } + + void ServerInterface::simpleTask(BaseThread *callingThread, void *userdata) { + MutexSafeWrapper safeMutex(masterServerThreadAccessor, CODE_AT_LINE); + + if (difftime((long int) time(NULL), lastMasterserverHeartbeatTime) >= MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Checking to see masterserver needs an update of the game status [%d] callingThread [%p] publishToMasterserverThread [%p]\n", needToRepublishToMasterserver, callingThread, publishToMasterserverThread); + + lastMasterserverHeartbeatTime = time(NULL); + if (needToRepublishToMasterserver == true) { + try { + if (Config::getInstance().getString("Masterserver", "") != "") { + string request = Config::getInstance().getString("Masterserver"); + if (request != "") { + endPathWithSlash(request, false); + } + request += "addServerInfo.php?"; + + std::map newPublishToServerInfo = publishToMasterserver(); + + CURL *handle = SystemFlags::initHTTP(); + for (std::map::const_iterator iterMap = newPublishToServerInfo.begin(); + iterMap != newPublishToServerInfo.end(); ++iterMap) { + + request += iterMap->first; + request += "="; + request += SystemFlags::escapeURL(iterMap->second, handle); + request += "&"; + } + + //printf("The Host request is:\n%s\n",request.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("The Host request is:\n%s\n", request.c_str()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line %d] the request is:\n%s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, request.c_str()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Calling masterserver [%s]...\n", request.c_str()); + + std::string serverInfo = SystemFlags::getHTTP(request, handle); + //printf("Result:\n%s\n",serverInfo .c_str()); + + string requestStats = Config::getInstance().getString("Masterserver"); + if (requestStats != "") { + endPathWithSlash(requestStats, false); + } + requestStats += "addGameStats.php?"; + + std::map newPublishToServerInfoStats = publishToMasterserverStats(); + if (newPublishToServerInfoStats.empty() == false) { + for (std::map::const_iterator iterMap = newPublishToServerInfoStats.begin(); + iterMap != newPublishToServerInfoStats.end(); ++iterMap) { + + requestStats += iterMap->first; + requestStats += "="; + requestStats += SystemFlags::escapeURL(iterMap->second, handle); + requestStats += "&"; + } + + //printf("The Host stats request is:\n%s\n",requestStats.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("The Host request is:\n%s\n", requestStats.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line %d] the request is:\n%s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, requestStats.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Calling masterserver [%s]...\n", requestStats.c_str()); + + std::string serverInfoStats = SystemFlags::getHTTP(requestStats, handle); + //printf("Result:\n%s\n",serverInfoStats .c_str()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line %d] the result is:\n'%s'\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, serverInfoStats.c_str()); + } + + SystemFlags::cleanupHTTP(&handle); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Done Calling masterserver\n"); + + //printf("the result is:\n'%s'\n",serverInfo.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line %d] the result is:\n'%s'\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, serverInfo.c_str()); + } else { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line %d] error, no masterserver defined!\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line %d] error during game status update: [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + } + } + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + DumpStatsToLog(false); + } + } + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + //printf("Attempt Accept\n"); + if (serverSocketAdmin != NULL) { + Socket *cli = serverSocketAdmin->accept(false); + if (cli != NULL) { + printf("Got status request connection, dumping info...\n"); + + string data = DumpStatsToLog(true); + cli->send(data.c_str(), (int) data.length()); + cli->disconnectSocket(); } } } } - } - return result; -} -void ServerInterface::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *serverInterfaceNode = rootNode->addChild("ServerInterface"); - - for(int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { - MutexSafeWrapper safeMutex(slotAccessorMutexes[slotIndex],CODE_AT_LINE_X(slotIndex)); - if(slots[slotIndex] != NULL) { - - XmlNode *slotNode = serverInterfaceNode->addChild("Slot"); - - ConnectionSlot *slot = slots[slotIndex]; - if(slot != NULL) { - slotNode->addAttribute("isconnected",intToStr(slot->isConnected()), mapTagReplacements); - slotNode->addAttribute("sessionkey",intToStr(slot->getSessionKey()), mapTagReplacements); - slotNode->addAttribute("ipaddress",slot->getSocket(false)->getIpAddress(), mapTagReplacements); - slotNode->addAttribute("name",slot->getName(), mapTagReplacements); - slotNode->addAttribute("uuid",slot->getUUID(), mapTagReplacements); + std::string ServerInterface::DumpStatsToLog(bool dumpToStringOnly) const { + string headlessLogFile = Config::getInstance().getString("HeadlessLogFile", "headless.log"); + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { + headlessLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + headlessLogFile; + } else { + string userData = Config::getInstance().getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + headlessLogFile = userData + headlessLogFile; } - else { - slotNode->addAttribute("isconnected",intToStr(false), mapTagReplacements); + + ostringstream out; + out << "=========================================" << std::endl; + out << "Headless Server Current Game information:" << std::endl; + out << "=========================================" << std::endl; + + int connectedSlotCount = 0; + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex], CODE_AT_LINE_X(slotIndex)); + ConnectionSlot *slot = slots[slotIndex]; + if (slot != NULL) { + + connectedSlotCount++; + out << "Network connection for index: " << slotIndex << std::endl; + out << "------------------------------" << std::endl; + out << "Connected: " << boolToStr(slot->isConnected()) << std::endl; + out << "Handshake received: " << boolToStr(slot->getConnectHasHandshaked()) << std::endl; + if (slot->isConnected() == true) { + + time_t connectTime = slot->getConnectedTime(); + //struct tm *loctime = localtime (&connectTime); + struct tm loctime = threadsafe_localtime(connectTime); + char szBuf[8096] = ""; + strftime(szBuf, 100, "%Y-%m-%d %H:%M:%S", &loctime); + + const int HOURS_IN_DAY = 24; + const int MINUTES_IN_HOUR = 60; + const int SECONDS_IN_MINUTE = 60; + int InSeconds = difftime((long int) time(NULL), slot->getConnectedTime()); + // compute seconds + int seconds = InSeconds % SECONDS_IN_MINUTE; + // throw away seconds used in previous statement and convert to minutes + int InMinutes = InSeconds / SECONDS_IN_MINUTE; + // compute minutes + int minutes = InMinutes % MINUTES_IN_HOUR; + + // throw away minutes used in previous statement and convert to hours + int InHours = InMinutes / MINUTES_IN_HOUR; + // compute hours + int hours = InHours % HOURS_IN_DAY; + + out << "Connected at: " << szBuf << std::endl; + out << "Connection duration: " << hours << " hours " << minutes << " minutes " << seconds << " seconds." << std::endl; + out << "Player Index: " << slot->getPlayerIndex() << std::endl; + out << "IP Address: " << slot->getIpAddress() << std::endl; + out << "Player name: " << slot->getName() << std::endl; + out << "Player uuid: " << slot->getUUID() << std::endl; + out << "Language: " << slot->getNetworkPlayerLanguage() << std::endl; + out << "Game Version: " << slot->getVersionString() << std::endl; + out << "Session id: " << slot->getSessionKey() << std::endl; + out << "Socket id: " << slot->getSocketId() << std::endl; + } + } + } + out << "Total Slot Count: " << connectedSlotCount << std::endl; + out << "=========================================" << std::endl; + + std::string result = out.str(); + + if (dumpToStringOnly == false) { + +#if defined(WIN32) && !defined(__MINGW32__) + FILE *fp = _wfopen(utf8_decode(headlessLogFile).c_str(), L"w"); + std::ofstream logFile(fp); +#else + std::ofstream logFile; + logFile.open(headlessLogFile.c_str(), ios_base::out | ios_base::trunc); +#endif + logFile << result; + logFile.close(); +#if defined(WIN32) && !defined(__MINGW32__) + if (fp) { + fclose(fp); + } +#endif + } + + return result; + } + + void ServerInterface::notifyBadClientConnectAttempt(string ipAddress) { + //printf("In [%s::%s Line: %d] ipAddress [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ipAddress.c_str()); + + if (badClientConnectIPList.find(ipAddress) == badClientConnectIPList.end()) { + badClientConnectIPList[ipAddress] = make_pair(0, (long int) time(NULL)); + } + + pair &lastBadConnectionAttempt = badClientConnectIPList[ipAddress]; + + const uint64 BLOCK_BAD_CLIENT_CONNECT_MAX_SECONDS = Config::getInstance().getInt("BlockBadClientConnectMaxSeconds", "60"); + const uint64 BLOCK_BAD_CLIENT_CONNECT_MAX_ATTEMPTS = Config::getInstance().getInt("BlockBadClientConnectMaxAttempts", "6"); + bool addToBlockedClientsList = false; + + if (difftime((long int) time(NULL), lastBadConnectionAttempt.second) <= BLOCK_BAD_CLIENT_CONNECT_MAX_SECONDS) { + + if (lastBadConnectionAttempt.first + 1 > BLOCK_BAD_CLIENT_CONNECT_MAX_ATTEMPTS) { + addToBlockedClientsList = true; + } + } else { + // Reset after x seconds + lastBadConnectionAttempt.first = 0; + } + + if (this->getAllowInGameConnections() == true) { + printf("notifyBadClientConnectAttempt() #1: %s!\n", ipAddress.c_str()); + } + + if (addToBlockedClientsList == true) { + serverSocket.addIPAddressToBlockedList(ipAddress); + } + + lastBadConnectionAttempt.first++; + lastBadConnectionAttempt.second = time(NULL); + } + + bool ServerInterface::getStartInGameConnectionLaunch() { + bool result = false; + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + MutexSafeWrapper safeMutex(slotAccessorMutexes[slotIndex], CODE_AT_LINE_X(slotIndex)); + if (slots[slotIndex] != NULL) { + + ConnectionSlot *slot = slots[slotIndex]; + if (slot->getStartInGameConnectionLaunch() == true) { + result = true; + break; + } + } + } + return result; + } + + bool ServerInterface::getPauseForInGameConnection() { + bool result = false; + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + MutexSafeWrapper safeMutex(slotAccessorMutexes[slotIndex], CODE_AT_LINE_X(slotIndex)); + if (slots[slotIndex] != NULL) { + + ConnectionSlot *slot = slots[slotIndex]; + if (slot->getPauseForInGameConnection() == true) { + result = true; + break; + } + } + } + return result; + } + + bool ServerInterface::getUnPauseForInGameConnection() { + bool result = false; + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + MutexSafeWrapper safeMutex(slotAccessorMutexes[slotIndex], CODE_AT_LINE_X(slotIndex)); + if (slots[slotIndex] != NULL) { + + ConnectionSlot *slot = slots[slotIndex]; + if (slot->isConnected() == true) { + if (slot->isReady() == true) { + result = true; + if (slot->getUnPauseForInGameConnection() == false) { + result = false; + break; + } + } else { + result = false; + break; + } + } + } + } + if (result == true) { + resumeGameStartTime = time(NULL); + } + return result; + } + + ConnectionSlot * ServerInterface::findSlotForUUID(string uuid, bool unConnectedOnly) { + ConnectionSlot *result = NULL; + if (uuid != "") { + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + + MutexSafeWrapper safeMutexSlot(slotAccessorMutexes[slotIndex], CODE_AT_LINE_X(slotIndex)); + ConnectionSlot *connectionSlot = slots[slotIndex]; + + if (connectionSlot != NULL) { + if (connectionSlot->getUUID() == uuid) { + if (unConnectedOnly == false || + (unConnectedOnly == true && connectionSlot->isConnected() == false)) { + + if (result == NULL || + (result->getConnectedTime() > connectionSlot->getConnectedTime())) + + result = connectionSlot; + } + } + } + } + } + return result; + } + + void ServerInterface::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *serverInterfaceNode = rootNode->addChild("ServerInterface"); + + for (int slotIndex = 0; exitServer == false && slotIndex < GameConstants::maxPlayers; ++slotIndex) { + MutexSafeWrapper safeMutex(slotAccessorMutexes[slotIndex], CODE_AT_LINE_X(slotIndex)); + if (slots[slotIndex] != NULL) { + + XmlNode *slotNode = serverInterfaceNode->addChild("Slot"); + + ConnectionSlot *slot = slots[slotIndex]; + if (slot != NULL) { + slotNode->addAttribute("isconnected", intToStr(slot->isConnected()), mapTagReplacements); + slotNode->addAttribute("sessionkey", intToStr(slot->getSessionKey()), mapTagReplacements); + slotNode->addAttribute("ipaddress", slot->getSocket(false)->getIpAddress(), mapTagReplacements); + slotNode->addAttribute("name", slot->getName(), mapTagReplacements); + slotNode->addAttribute("uuid", slot->getUUID(), mapTagReplacements); + } else { + slotNode->addAttribute("isconnected", intToStr(false), mapTagReplacements); + } + } } } - } -} -}}//end namespace + } +}//end namespace diff --git a/source/glest_game/network/server_interface.h b/source/glest_game/network/server_interface.h index 62e0ef9f7..ef2fe2b00 100644 --- a/source/glest_game/network/server_interface.h +++ b/source/glest_game/network/server_interface.h @@ -24,8 +24,8 @@ #define _GLEST_GAME_SERVERINTERFACE_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -38,269 +38,293 @@ using std::vector; using Shared::Platform::ServerSocket; -namespace Shared { namespace PlatformCommon { class FTPServerThread; }} +namespace Shared { + namespace PlatformCommon { + class FTPServerThread; + } +} -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -class Stats; -// ===================================================== -// class ServerInterface -// ===================================================== + class Stats; + // ===================================================== + // class ServerInterface + // ===================================================== -class ServerInterface: public GameNetworkInterface, - public ConnectionSlotCallbackInterface, - // This is for publishing game status to the masterserver - public SimpleTaskCallbackInterface, - public FTPClientValidationInterface { + class ServerInterface : public GameNetworkInterface, + public ConnectionSlotCallbackInterface, + // This is for publishing game status to the masterserver + public SimpleTaskCallbackInterface, + public FTPClientValidationInterface { -class TextMessageQueue { -public: - string text; - int teamIndex; - bool echoLocal; - string targetLanguage; -}; + class TextMessageQueue { + public: + string text; + int teamIndex; + bool echoLocal; + string targetLanguage; + }; -private: - ConnectionSlot* slots[GameConstants::maxPlayers]; - Mutex *slotAccessorMutexes[GameConstants::maxPlayers]; + private: + ConnectionSlot * slots[GameConstants::maxPlayers]; + Mutex *slotAccessorMutexes[GameConstants::maxPlayers]; - ServerSocket serverSocket; + ServerSocket serverSocket; - Mutex *switchSetupRequestsSynchAccessor; - SwitchSetupRequest* switchSetupRequests[GameConstants::maxPlayers]; + Mutex *switchSetupRequestsSynchAccessor; + SwitchSetupRequest* switchSetupRequests[GameConstants::maxPlayers]; - Mutex *serverSynchAccessor; - int currentFrameCount; + Mutex *serverSynchAccessor; + int currentFrameCount; - time_t gameStartTime; + time_t gameStartTime; - time_t lastGlobalLagCheckTime; + time_t lastGlobalLagCheckTime; - SimpleTaskThread *publishToMasterserverThread; - Mutex *masterServerThreadAccessor; - time_t lastMasterserverHeartbeatTime; - bool needToRepublishToMasterserver; + SimpleTaskThread *publishToMasterserverThread; + Mutex *masterServerThreadAccessor; + time_t lastMasterserverHeartbeatTime; + bool needToRepublishToMasterserver; - ::Shared::PlatformCommon::FTPServerThread *ftpServer; - bool exitServer; - int64 nextEventId; + ::Shared::PlatformCommon::FTPServerThread *ftpServer; + bool exitServer; + int64 nextEventId; - Mutex *textMessageQueueThreadAccessor; - vector textMessageQueue; + Mutex *textMessageQueueThreadAccessor; + vector textMessageQueue; - Mutex *broadcastMessageQueueThreadAccessor; - vector > broadcastMessageQueue; + Mutex *broadcastMessageQueueThreadAccessor; + vector > broadcastMessageQueue; - Mutex *inBroadcastMessageThreadAccessor; - bool inBroadcastMessage; + Mutex *inBroadcastMessageThreadAccessor; + bool inBroadcastMessage; - bool masterserverAdminRequestLaunch; + bool masterserverAdminRequestLaunch; + + vector mapFiles; + vector playerSortedMaps[GameConstants::maxPlayers + 1]; + vector techTreeFiles; + vector tilesetFiles; + + map > badClientConnectIPList; + + ServerSocket *serverSocketAdmin; + MasterSlaveThreadController masterController; - vector mapFiles; - vector playerSortedMaps[GameConstants::maxPlayers+1]; - vector techTreeFiles; - vector tilesetFiles; - - map > badClientConnectIPList; - - ServerSocket *serverSocketAdmin; - MasterSlaveThreadController masterController; - - bool gameHasBeenInitiated; - int gameSettingsUpdateCount; - - bool allowInGameConnections; - bool gameLaunched; - time_t lastListenerSlotCheckTime; - - time_t resumeGameStartTime; - - Mutex *gameStatsThreadAccessor; - Stats *gameStats; - - bool clientsAutoPausedDueToLag; - Chrono clientsAutoPausedDueToLagTimer; - Chrono lastBroadcastCommandsTimer; - ClientLagCallbackInterface *clientLagCallbackInterface; - -public: - ServerInterface(bool publishEnabled, ClientLagCallbackInterface *clientLagCallbackInterface); - virtual ~ServerInterface(); - - bool getClientsAutoPausedDueToLag(); - void setClientLagCallbackInterface(ClientLagCallbackInterface *intf); - void setGameStats(Stats *gameStats); - - virtual Socket* getSocket(bool mutexLock=true) {return &serverSocket;} - virtual std::string getIpAddress(bool mutexLock=true); - - time_t getGameStartTime() const { return gameStartTime; } - - virtual bool getAllowInGameConnections() const { return allowInGameConnections; } - void setAllowInGameConnections(bool value) { allowInGameConnections = value; } - - bool getStartInGameConnectionLaunch(); - bool getPauseForInGameConnection(); - bool getUnPauseForInGameConnection(); - - void shutdownFTPServer(); - - virtual void close(); - virtual void update(); - virtual void updateLobby() { }; - virtual void updateKeyframe(int frameCount); - virtual void setKeyframe(int frameCount) { currentFrameCount = frameCount; } - - virtual void waitUntilReady(Checksum *checksum); - virtual void sendTextMessage(const string & text, int teamIndex, bool echoLocal, string targetLanguage); - void sendTextMessage(const string & text, int teamIndex, bool echoLocal, string targetLanguage, int lockedSlotIndex); - - void queueTextMessage(const string & text, int teamIndex, bool echoLocal, string targetLanguage); - - virtual void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note,int playerIndex); - void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note, int playerIndex, int lockedSlotIndex); - - virtual void sendHighlightCellMessage(Vec2i targetPos, int factionIndex); - void sendHighlightCellMessage(Vec2i targetPos, int factionIndex, int lockedSlotIndex); - - virtual void sendUnMarkCellMessage(Vec2i targetPos, int factionIndex); - void sendUnMarkCellMessage(Vec2i targetPos, int factionIndex, int lockedSlotIndex); - - virtual void quitGame(bool userManuallyQuit); - virtual string getNetworkStatus(); - ServerSocket *getServerSocket() { - return &serverSocket; - } - - SwitchSetupRequest **getSwitchSetupRequests(); - SwitchSetupRequest *getSwitchSetupRequests(int index); - void setSwitchSetupRequests(int index,SwitchSetupRequest *ptr); - Mutex * getSwitchSetupRequestsMutex() { return switchSetupRequestsSynchAccessor; } - - void addSlot(int playerIndex); - bool switchSlot(int fromPlayerIndex, int toPlayerIndex); - void removeSlot(int playerIndex, int lockedSlotIndex = -1); - virtual ConnectionSlot *getSlot(int playerIndex, bool lockMutex); - virtual Mutex *getSlotMutex(int playerIndex); - int getSlotCount(); - int getConnectedSlotCount(bool authenticated); - - int getOpenSlotCount(); - bool launchGame(const GameSettings *gameSettings); - void validateGameSettings(GameSettings *serverGameSettings); - void setGameSettings(GameSettings *serverGameSettings, bool waitForClientAck); - void broadcastGameSetup(GameSettings *gameSettingsBuffer, bool setGameSettingsBuffer=false); - - int getGameSettingsUpdateCount(); - - bool getMasterserverAdminRequestLaunch() const { return masterserverAdminRequestLaunch; } - void setMasterserverAdminRequestLaunch(bool value) { masterserverAdminRequestLaunch = value; } - - void updateListen(); - virtual bool getConnectHasHandshaked() const { - return false; - } - - virtual void slotUpdateTask(ConnectionSlotEvent *event) { }; - bool hasClientConnection(); - virtual bool isClientConnected(int index); - - int getCurrentFrameCount() const { - return currentFrameCount; - } - - std::pair clientLagCheck(ConnectionSlot *connectionSlot, bool skipNetworkBroadCast = false); - bool signalClientReceiveCommands(ConnectionSlot *connectionSlot, int slotIndex, bool socketTriggered, ConnectionSlotEvent & event); - void updateSocketTriggeredList(std::map & socketTriggeredList); - bool isPortBound() const { - return serverSocket.isPortBound(); - } - - int getBindPort() const { - return serverSocket.getBindPort(); - } - - void broadcastPing(NetworkMessagePing *networkMessage, int excludeSlot = -1) { - this->broadcastMessage(networkMessage, excludeSlot); - } - - void queueBroadcastMessage(NetworkMessage *networkMessage, int excludeSlot = -1); - virtual string getHumanPlayerName(int index = -1); - virtual int getHumanPlayerIndex() const; - bool getNeedToRepublishToMasterserver() const { - return needToRepublishToMasterserver; - } - - void setNeedToRepublishToMasterserver(bool value) { - needToRepublishToMasterserver = value; - } - - void setPublishEnabled(bool value); - - bool getGameHasBeenInitiated() const { - return gameHasBeenInitiated; - } - -public: - Mutex *getServerSynchAccessor() { - return serverSynchAccessor; - } - - virtual void simpleTask(BaseThread *callingThread,void *userdata); - void addClientToServerIPAddress(uint32 clientIp, uint32 ServerIp); - virtual int isValidClientType(uint32 clientIp); - virtual int isClientAllowedToGetFile(uint32 clientIp, const char *username, const char *filename); - - void notifyBadClientConnectAttempt(string ipAddress); - std::string DumpStatsToLog(bool dumpToStringOnly) const; - - virtual void saveGame(XmlNode *rootNode); - - void broadcastMessage(NetworkMessage *networkMessage, int excludeSlot = -1, int lockedSlotIndex = -1); - - ConnectionSlot * findSlotForUUID(string uuid, bool unConnectedOnly=true); - -private: - - void broadcastMessageToConnectedClients(NetworkMessage *networkMessage, int excludeSlot = -1); - bool shouldDiscardNetworkMessage(NetworkMessageType networkMessageType, ConnectionSlot *connectionSlot); - void updateSlot(ConnectionSlotEvent *event); - void validateConnectedClients(); - - std::map publishToMasterserver(); - std::map publishToMasterserverStats(); - - int64 getNextEventId(); - void processTextMessageQueue(); - void processBroadCastMessageQueue(); - void checkListenerSlots(); - void checkForCompletedClientsUsingThreadManager( - std::map& mapSlotSignalledList, - std::vector& errorMsgList); - void checkForCompletedClientsUsingLoop( - std::map& mapSlotSignalledList, - std::vector& errorMsgList, - std::map& eventList); - void checkForAutoPauseForLaggingClient(int index, - ConnectionSlot* connectionSlot); - void checkForAutoResumeForLaggingClients(); - -protected: - void signalClientsToRecieveData(std::map & socketTriggeredList, std::map & eventList, std::map & mapSlotSignalledList); - void checkForCompletedClients(std::map & mapSlotSignalledList,std::vector &errorMsgList,std::map &eventList); - void checkForLaggingClients(std::map &mapSlotSignalledList, std::map &eventList, std::map &socketTriggeredList,std::vector &errorMsgList); - void executeNetworkCommandsFromClients(); - void dispatchPendingChatMessages(std::vector &errorMsgList); - void dispatchPendingMarkCellMessages(std::vector &errorMsgList); - void dispatchPendingUnMarkCellMessages(std::vector &errorMsgList); - void dispatchPendingHighlightCellMessages(std::vector &errorMsgList); - - void shutdownMasterserverPublishThread(); - - -}; - -}}//end namespace + bool gameHasBeenInitiated; + int gameSettingsUpdateCount; + + bool allowInGameConnections; + bool gameLaunched; + time_t lastListenerSlotCheckTime; + + time_t resumeGameStartTime; + + Mutex *gameStatsThreadAccessor; + Stats *gameStats; + + bool clientsAutoPausedDueToLag; + Chrono clientsAutoPausedDueToLagTimer; + Chrono lastBroadcastCommandsTimer; + ClientLagCallbackInterface *clientLagCallbackInterface; + + public: + ServerInterface(bool publishEnabled, ClientLagCallbackInterface *clientLagCallbackInterface); + virtual ~ServerInterface(); + + bool getClientsAutoPausedDueToLag(); + void setClientLagCallbackInterface(ClientLagCallbackInterface *intf); + void setGameStats(Stats *gameStats); + + virtual Socket* getSocket(bool mutexLock = true) { + return &serverSocket; + } + virtual std::string getIpAddress(bool mutexLock = true); + + time_t getGameStartTime() const { + return gameStartTime; + } + + virtual bool getAllowInGameConnections() const { + return allowInGameConnections; + } + void setAllowInGameConnections(bool value) { + allowInGameConnections = value; + } + + bool getStartInGameConnectionLaunch(); + bool getPauseForInGameConnection(); + bool getUnPauseForInGameConnection(); + + void shutdownFTPServer(); + + virtual void close(); + virtual void update(); + virtual void updateLobby() { + }; + virtual void updateKeyframe(int frameCount); + virtual void setKeyframe(int frameCount) { + currentFrameCount = frameCount; + } + + virtual void waitUntilReady(Checksum *checksum); + virtual void sendTextMessage(const string & text, int teamIndex, bool echoLocal, string targetLanguage); + void sendTextMessage(const string & text, int teamIndex, bool echoLocal, string targetLanguage, int lockedSlotIndex); + + void queueTextMessage(const string & text, int teamIndex, bool echoLocal, string targetLanguage); + + virtual void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note, int playerIndex); + void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note, int playerIndex, int lockedSlotIndex); + + virtual void sendHighlightCellMessage(Vec2i targetPos, int factionIndex); + void sendHighlightCellMessage(Vec2i targetPos, int factionIndex, int lockedSlotIndex); + + virtual void sendUnMarkCellMessage(Vec2i targetPos, int factionIndex); + void sendUnMarkCellMessage(Vec2i targetPos, int factionIndex, int lockedSlotIndex); + + virtual void quitGame(bool userManuallyQuit); + virtual string getNetworkStatus(); + ServerSocket *getServerSocket() { + return &serverSocket; + } + + SwitchSetupRequest **getSwitchSetupRequests(); + SwitchSetupRequest *getSwitchSetupRequests(int index); + void setSwitchSetupRequests(int index, SwitchSetupRequest *ptr); + Mutex * getSwitchSetupRequestsMutex() { + return switchSetupRequestsSynchAccessor; + } + + void addSlot(int playerIndex); + bool switchSlot(int fromPlayerIndex, int toPlayerIndex); + void removeSlot(int playerIndex, int lockedSlotIndex = -1); + virtual ConnectionSlot *getSlot(int playerIndex, bool lockMutex); + virtual Mutex *getSlotMutex(int playerIndex); + int getSlotCount(); + int getConnectedSlotCount(bool authenticated); + + int getOpenSlotCount(); + bool launchGame(const GameSettings *gameSettings); + void validateGameSettings(GameSettings *serverGameSettings); + void setGameSettings(GameSettings *serverGameSettings, bool waitForClientAck); + void broadcastGameSetup(GameSettings *gameSettingsBuffer, bool setGameSettingsBuffer = false); + + int getGameSettingsUpdateCount(); + + bool getMasterserverAdminRequestLaunch() const { + return masterserverAdminRequestLaunch; + } + void setMasterserverAdminRequestLaunch(bool value) { + masterserverAdminRequestLaunch = value; + } + + void updateListen(); + virtual bool getConnectHasHandshaked() const { + return false; + } + + virtual void slotUpdateTask(ConnectionSlotEvent *event) { + }; + bool hasClientConnection(); + virtual bool isClientConnected(int index); + + int getCurrentFrameCount() const { + return currentFrameCount; + } + + std::pair clientLagCheck(ConnectionSlot *connectionSlot, bool skipNetworkBroadCast = false); + bool signalClientReceiveCommands(ConnectionSlot *connectionSlot, int slotIndex, bool socketTriggered, ConnectionSlotEvent & event); + void updateSocketTriggeredList(std::map & socketTriggeredList); + bool isPortBound() const { + return serverSocket.isPortBound(); + } + + int getBindPort() const { + return serverSocket.getBindPort(); + } + + void broadcastPing(NetworkMessagePing *networkMessage, int excludeSlot = -1) { + this->broadcastMessage(networkMessage, excludeSlot); + } + + void queueBroadcastMessage(NetworkMessage *networkMessage, int excludeSlot = -1); + virtual string getHumanPlayerName(int index = -1); + virtual int getHumanPlayerIndex() const; + bool getNeedToRepublishToMasterserver() const { + return needToRepublishToMasterserver; + } + + void setNeedToRepublishToMasterserver(bool value) { + needToRepublishToMasterserver = value; + } + + void setPublishEnabled(bool value); + + bool getGameHasBeenInitiated() const { + return gameHasBeenInitiated; + } + + public: + Mutex * getServerSynchAccessor() { + return serverSynchAccessor; + } + + virtual void simpleTask(BaseThread *callingThread, void *userdata); + void addClientToServerIPAddress(uint32 clientIp, uint32 ServerIp); + virtual int isValidClientType(uint32 clientIp); + virtual int isClientAllowedToGetFile(uint32 clientIp, const char *username, const char *filename); + + void notifyBadClientConnectAttempt(string ipAddress); + std::string DumpStatsToLog(bool dumpToStringOnly) const; + + virtual void saveGame(XmlNode *rootNode); + + void broadcastMessage(NetworkMessage *networkMessage, int excludeSlot = -1, int lockedSlotIndex = -1); + + ConnectionSlot * findSlotForUUID(string uuid, bool unConnectedOnly = true); + + private: + + void broadcastMessageToConnectedClients(NetworkMessage *networkMessage, int excludeSlot = -1); + bool shouldDiscardNetworkMessage(NetworkMessageType networkMessageType, ConnectionSlot *connectionSlot); + void updateSlot(ConnectionSlotEvent *event); + void validateConnectedClients(); + + std::map publishToMasterserver(); + std::map publishToMasterserverStats(); + + int64 getNextEventId(); + void processTextMessageQueue(); + void processBroadCastMessageQueue(); + void checkListenerSlots(); + void checkForCompletedClientsUsingThreadManager( + std::map& mapSlotSignalledList, + std::vector& errorMsgList); + void checkForCompletedClientsUsingLoop( + std::map& mapSlotSignalledList, + std::vector& errorMsgList, + std::map& eventList); + void checkForAutoPauseForLaggingClient(int index, + ConnectionSlot* connectionSlot); + void checkForAutoResumeForLaggingClients(); + + protected: + void signalClientsToRecieveData(std::map & socketTriggeredList, std::map & eventList, std::map & mapSlotSignalledList); + void checkForCompletedClients(std::map & mapSlotSignalledList, std::vector &errorMsgList, std::map &eventList); + void checkForLaggingClients(std::map &mapSlotSignalledList, std::map &eventList, std::map &socketTriggeredList, std::vector &errorMsgList); + void executeNetworkCommandsFromClients(); + void dispatchPendingChatMessages(std::vector &errorMsgList); + void dispatchPendingMarkCellMessages(std::vector &errorMsgList); + void dispatchPendingUnMarkCellMessages(std::vector &errorMsgList); + void dispatchPendingHighlightCellMessages(std::vector &errorMsgList); + + void shutdownMasterserverPublishThread(); + + + }; + + } +}//end namespace #endif diff --git a/source/glest_game/sound/sound_container.cpp b/source/glest_game/sound/sound_container.cpp index 2b1f2f40f..a09b46420 100644 --- a/source/glest_game/sound/sound_container.cpp +++ b/source/glest_game/sound/sound_container.cpp @@ -16,30 +16,32 @@ using namespace Shared::Util; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class SoundContainer -// ===================================================== + // ===================================================== + // class SoundContainer + // ===================================================== -SoundContainer::SoundContainer(){ - lastSound= -1; -} - -StaticSound *SoundContainer::getRandSound() const{ - switch(sounds.size()){ - case 0: - return NULL; - case 1: - return sounds[0]; - default: - int soundIndex= random.randRange(0, (int)sounds.size()-1); - if(soundIndex==lastSound){ - soundIndex= (lastSound+1) % sounds.size(); + SoundContainer::SoundContainer() { + lastSound = -1; } - lastSound= soundIndex; - return sounds[soundIndex]; - } -} -}}//end namespace + StaticSound *SoundContainer::getRandSound() const { + switch (sounds.size()) { + case 0: + return NULL; + case 1: + return sounds[0]; + default: + int soundIndex = random.randRange(0, (int) sounds.size() - 1); + if (soundIndex == lastSound) { + soundIndex = (lastSound + 1) % sounds.size(); + } + lastSound = soundIndex; + return sounds[soundIndex]; + } + } + + } +}//end namespace diff --git a/source/glest_game/sound/sound_container.h b/source/glest_game/sound/sound_container.h index ee4c058e2..e74d669d9 100644 --- a/source/glest_game/sound/sound_container.h +++ b/source/glest_game/sound/sound_container.h @@ -13,8 +13,8 @@ #define _GLEST_GAME_SOUNDCONTAINER_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -26,35 +26,47 @@ using std::vector; using Shared::Util::RandomGen; using Shared::Sound::StaticSound; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class SoundContainer -// -/// Holds a list of sounds that are usually played at random -// ===================================================== + // ===================================================== + // class SoundContainer + // + /// Holds a list of sounds that are usually played at random + // ===================================================== -class SoundContainer{ -public: - typedef vector Sounds; + class SoundContainer { + public: + typedef vector Sounds; -private: - Sounds sounds; - mutable RandomGen random; - mutable int lastSound; + private: + Sounds sounds; + mutable RandomGen random; + mutable int lastSound; -public: - SoundContainer(); + public: + SoundContainer(); - void resize(int size) {sounds.resize(size);} - StaticSound *&operator[](int i) {return sounds[i];} + void resize(int size) { + sounds.resize(size); + } + StaticSound *&operator[](int i) { + return sounds[i]; + } - const Sounds &getSounds() const {return sounds;} - void clearSounds() {sounds.clear();} - Sounds *getSoundsPtr() {return &sounds;} - StaticSound *getRandSound() const; -}; + const Sounds &getSounds() const { + return sounds; + } + void clearSounds() { + sounds.clear(); + } + Sounds *getSoundsPtr() { + return &sounds; + } + StaticSound *getRandSound() const; + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/glest_game/sound/sound_renderer.cpp b/source/glest_game/sound/sound_renderer.cpp index 7d0948095..4ded3fba8 100644 --- a/source/glest_game/sound/sound_renderer.cpp +++ b/source/glest_game/sound/sound_renderer.cpp @@ -21,260 +21,261 @@ using namespace Shared::Util; using namespace Shared::Graphics; using namespace Shared::Sound; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -const int SoundRenderer::ambientFade= 6000; -const float SoundRenderer::audibleDist= 50.f; + const int SoundRenderer::ambientFade = 6000; + const float SoundRenderer::audibleDist = 50.f; -// ===================================================== -// class SoundRenderer -// ===================================================== + // ===================================================== + // class SoundRenderer + // ===================================================== -SoundRenderer::SoundRenderer() : mutex(new Mutex(CODE_AT_LINE)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); + SoundRenderer::SoundRenderer() : mutex(new Mutex(CODE_AT_LINE)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); - soundPlayer = NULL; - loadConfig(); + soundPlayer = NULL; + loadConfig(); - Config &config= Config::getInstance(); - runThreadSafe = config.getBool("ThreadedSoundStream","true"); + Config &config = Config::getInstance(); + runThreadSafe = config.getBool("ThreadedSoundStream", "true"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] runThreadSafe = %d\n",__FILE__,__FUNCTION__,__LINE__,runThreadSafe); -} - -bool SoundRenderer::init(Window *window) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - - SoundInterface &si= SoundInterface::getInstance(); - FactoryRepository &fr= FactoryRepository::getInstance(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - Config &config= Config::getInstance(); - si.setFactory(fr.getSoundFactory(config.getString("FactorySound"))); - - cleanup(); - stopAllSounds(); - - MutexSafeWrapper safeMutex(NULL,string(__FILE__) + "_" + intToStr(__LINE__)); - if(runThreadSafe == true) { - safeMutex.setMutex(mutex); - } - - soundPlayer= si.newSoundPlayer(); - if(soundPlayer != NULL) { - SoundPlayerParams soundPlayerParams; - soundPlayerParams.staticBufferCount= config.getInt("SoundStaticBuffers"); - soundPlayerParams.strBufferCount= config.getInt("SoundStreamingBuffers"); - soundPlayer->init(&soundPlayerParams); - } - safeMutex.ReleaseLock(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - - return wasInitOk(); -} - -void SoundRenderer::cleanup() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - - stopAllSounds(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - - MutexSafeWrapper safeMutex(NULL,string(__FILE__) + "_" + intToStr(__LINE__)); - if(runThreadSafe == true) { - safeMutex.setMutex(mutex); - } - delete soundPlayer; - soundPlayer = NULL; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -bool SoundRenderer::wasInitOk() const { - bool result = false; - if(soundPlayer != NULL) { - result = soundPlayer->wasInitOk(); - } - else { - Config &config= Config::getInstance(); - if(config.getString("FactorySound") == "" || - config.getString("FactorySound") == "None") { - result = true; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] runThreadSafe = %d\n", __FILE__, __FUNCTION__, __LINE__, runThreadSafe); } - } - return result; -} -SoundRenderer::~SoundRenderer() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); + bool SoundRenderer::init(Window *window) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); - cleanup(); + SoundInterface &si = SoundInterface::getInstance(); + FactoryRepository &fr = FactoryRepository::getInstance(); - delete mutex; - mutex = NULL; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + Config &config = Config::getInstance(); + si.setFactory(fr.getSoundFactory(config.getString("FactorySound"))); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); -} + cleanup(); + stopAllSounds(); -SoundRenderer &SoundRenderer::getInstance() { - static SoundRenderer soundRenderer; - return soundRenderer; -} - -void SoundRenderer::update() { - if(wasInitOk() == true && soundPlayer != NULL) { - MutexSafeWrapper safeMutex(NULL,string(__FILE__) + "_" + intToStr(__LINE__)); - if(runThreadSafe == true) { - safeMutex.setMutex(mutex); - } - if(soundPlayer) { - soundPlayer->updateStreams(); - } - } -} - -// ======================= Music ============================ - -void SoundRenderer::playMusic(StrSound *strSound) { - if(strSound != NULL) { - strSound->setVolume(musicVolume); - strSound->restart(); - if(soundPlayer != NULL) { - MutexSafeWrapper safeMutex(NULL,string(__FILE__) + "_" + intToStr(__LINE__)); - if(runThreadSafe == true) { - safeMutex.setMutex(mutex); - } - - if(soundPlayer) { - soundPlayer->play(strSound); + MutexSafeWrapper safeMutex(NULL, string(__FILE__) + "_" + intToStr(__LINE__)); + if (runThreadSafe == true) { + safeMutex.setMutex(mutex); } + + soundPlayer = si.newSoundPlayer(); + if (soundPlayer != NULL) { + SoundPlayerParams soundPlayerParams; + soundPlayerParams.staticBufferCount = config.getInt("SoundStaticBuffers"); + soundPlayerParams.strBufferCount = config.getInt("SoundStreamingBuffers"); + soundPlayer->init(&soundPlayerParams); + } + safeMutex.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + + return wasInitOk(); } - } -} -void SoundRenderer::setMusicVolume(StrSound *strSound) { - if(strSound != NULL) { - strSound->setVolume(musicVolume); - } -} + void SoundRenderer::cleanup() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); -void SoundRenderer::stopMusic(StrSound *strSound) { - if(soundPlayer != NULL) { - MutexSafeWrapper safeMutex(NULL,string(__FILE__) + "_" + intToStr(__LINE__)); - if(runThreadSafe == true) { - safeMutex.setMutex(mutex); - } + stopAllSounds(); - if(soundPlayer) { - soundPlayer->stop(strSound); - if(strSound != NULL) { - if(strSound->getNext() != NULL) { - soundPlayer->stop(strSound->getNext()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + + MutexSafeWrapper safeMutex(NULL, string(__FILE__) + "_" + intToStr(__LINE__)); + if (runThreadSafe == true) { + safeMutex.setMutex(mutex); + } + delete soundPlayer; + soundPlayer = NULL; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + bool SoundRenderer::wasInitOk() const { + bool result = false; + if (soundPlayer != NULL) { + result = soundPlayer->wasInitOk(); + } else { + Config &config = Config::getInstance(); + if (config.getString("FactorySound") == "" || + config.getString("FactorySound") == "None") { + result = true; + } + } + return result; + } + + SoundRenderer::~SoundRenderer() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + + cleanup(); + + delete mutex; + mutex = NULL; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + SoundRenderer &SoundRenderer::getInstance() { + static SoundRenderer soundRenderer; + return soundRenderer; + } + + void SoundRenderer::update() { + if (wasInitOk() == true && soundPlayer != NULL) { + MutexSafeWrapper safeMutex(NULL, string(__FILE__) + "_" + intToStr(__LINE__)); + if (runThreadSafe == true) { + safeMutex.setMutex(mutex); + } + if (soundPlayer) { + soundPlayer->updateStreams(); } } } - } -} -// ======================= Fx ============================ + // ======================= Music ============================ -void SoundRenderer::playFx(StaticSound *staticSound, Vec3f soundPos, Vec3f camPos) { - if(staticSound!=NULL){ - float d= soundPos.dist(camPos); + void SoundRenderer::playMusic(StrSound *strSound) { + if (strSound != NULL) { + strSound->setVolume(musicVolume); + strSound->restart(); + if (soundPlayer != NULL) { + MutexSafeWrapper safeMutex(NULL, string(__FILE__) + "_" + intToStr(__LINE__)); + if (runThreadSafe == true) { + safeMutex.setMutex(mutex); + } - if(d < audibleDist){ - float vol= (1.f-d/audibleDist)*fxVolume; - float correctedVol= std::log10(std::log10(vol*9+1)*9+1); - - staticSound->setVolume(correctedVol); - - if(soundPlayer != NULL) { - MutexSafeWrapper safeMutex(NULL,string(__FILE__) + "_" + intToStr(__LINE__)); - if(runThreadSafe == true) { - safeMutex.setMutex(mutex); - } - - if(soundPlayer) { - soundPlayer->play(staticSound); + if (soundPlayer) { + soundPlayer->play(strSound); + } } } } - } -} -void SoundRenderer::playFx(StaticSound *staticSound, bool force) { - if(staticSound!=NULL){ - staticSound->setVolume(fxVolume); - if(soundPlayer != NULL) { - MutexSafeWrapper safeMutex(NULL,string(__FILE__) + "_" + intToStr(__LINE__)); - if(runThreadSafe == true) { - safeMutex.setMutex(mutex); - } - - if(soundPlayer) { - soundPlayer->play(staticSound, force); + void SoundRenderer::setMusicVolume(StrSound *strSound) { + if (strSound != NULL) { + strSound->setVolume(musicVolume); } } - } -} -// ======================= Ambient ============================ + void SoundRenderer::stopMusic(StrSound *strSound) { + if (soundPlayer != NULL) { + MutexSafeWrapper safeMutex(NULL, string(__FILE__) + "_" + intToStr(__LINE__)); + if (runThreadSafe == true) { + safeMutex.setMutex(mutex); + } -void SoundRenderer::playAmbient(StrSound *strSound) { - if(strSound != NULL) { - strSound->setVolume(ambientVolume); - if(soundPlayer != NULL) { - MutexSafeWrapper safeMutex(NULL,string(__FILE__) + "_" + intToStr(__LINE__)); - if(runThreadSafe == true) { - safeMutex.setMutex(mutex); - } - - if(soundPlayer) { - soundPlayer->play(strSound, ambientFade); + if (soundPlayer) { + soundPlayer->stop(strSound); + if (strSound != NULL) { + if (strSound->getNext() != NULL) { + soundPlayer->stop(strSound->getNext()); + } + } + } } } + + // ======================= Fx ============================ + + void SoundRenderer::playFx(StaticSound *staticSound, Vec3f soundPos, Vec3f camPos) { + if (staticSound != NULL) { + float d = soundPos.dist(camPos); + + if (d < audibleDist) { + float vol = (1.f - d / audibleDist)*fxVolume; + float correctedVol = std::log10(std::log10(vol * 9 + 1) * 9 + 1); + + staticSound->setVolume(correctedVol); + + if (soundPlayer != NULL) { + MutexSafeWrapper safeMutex(NULL, string(__FILE__) + "_" + intToStr(__LINE__)); + if (runThreadSafe == true) { + safeMutex.setMutex(mutex); + } + + if (soundPlayer) { + soundPlayer->play(staticSound); + } + } + } + } + } + + void SoundRenderer::playFx(StaticSound *staticSound, bool force) { + if (staticSound != NULL) { + staticSound->setVolume(fxVolume); + if (soundPlayer != NULL) { + MutexSafeWrapper safeMutex(NULL, string(__FILE__) + "_" + intToStr(__LINE__)); + if (runThreadSafe == true) { + safeMutex.setMutex(mutex); + } + + if (soundPlayer) { + soundPlayer->play(staticSound, force); + } + } + } + } + + // ======================= Ambient ============================ + + void SoundRenderer::playAmbient(StrSound *strSound) { + if (strSound != NULL) { + strSound->setVolume(ambientVolume); + if (soundPlayer != NULL) { + MutexSafeWrapper safeMutex(NULL, string(__FILE__) + "_" + intToStr(__LINE__)); + if (runThreadSafe == true) { + safeMutex.setMutex(mutex); + } + + if (soundPlayer) { + soundPlayer->play(strSound, ambientFade); + } + } + } + } + + void SoundRenderer::stopAmbient(StrSound *strSound) { + if (soundPlayer != NULL) { + MutexSafeWrapper safeMutex(NULL, string(__FILE__) + "_" + intToStr(__LINE__)); + if (runThreadSafe == true) { + safeMutex.setMutex(mutex); + } + + if (soundPlayer) { + soundPlayer->stop(strSound, ambientFade); + } + } + } + + // ======================= Misc ============================ + + void SoundRenderer::stopAllSounds(int64 fadeOff) { + if (soundPlayer != NULL) { + MutexSafeWrapper safeMutex(NULL, string(__FILE__) + "_" + intToStr(__LINE__)); + if (runThreadSafe == true) { + safeMutex.setMutex(mutex); + } + + if (soundPlayer) { + soundPlayer->stopAllSounds(fadeOff); + } + } + } + + bool SoundRenderer::isVolumeTurnedOff() const { + return (fxVolume <= 0 && musicVolume <= 0 && ambientVolume <= 0); + } + + void SoundRenderer::loadConfig() { + Config &config = Config::getInstance(); + + fxVolume = config.getInt("SoundVolumeFx") / 100.f; + musicVolume = config.getInt("SoundVolumeMusic") / 100.f; + ambientVolume = config.getInt("SoundVolumeAmbient") / 100.f; + } + } -} - -void SoundRenderer::stopAmbient(StrSound *strSound) { - if(soundPlayer != NULL) { - MutexSafeWrapper safeMutex(NULL,string(__FILE__) + "_" + intToStr(__LINE__)); - if(runThreadSafe == true) { - safeMutex.setMutex(mutex); - } - - if(soundPlayer) { - soundPlayer->stop(strSound, ambientFade); - } - } -} - -// ======================= Misc ============================ - -void SoundRenderer::stopAllSounds(int64 fadeOff) { - if(soundPlayer != NULL) { - MutexSafeWrapper safeMutex(NULL,string(__FILE__) + "_" + intToStr(__LINE__)); - if(runThreadSafe == true) { - safeMutex.setMutex(mutex); - } - - if(soundPlayer) { - soundPlayer->stopAllSounds(fadeOff); - } - } -} - -bool SoundRenderer::isVolumeTurnedOff() const { - return (fxVolume <= 0 && musicVolume <= 0 && ambientVolume <= 0); -} - -void SoundRenderer::loadConfig() { - Config &config= Config::getInstance(); - - fxVolume= config.getInt("SoundVolumeFx")/100.f; - musicVolume= config.getInt("SoundVolumeMusic")/100.f; - ambientVolume= config.getInt("SoundVolumeAmbient")/100.f; -} - -}}//end namespace +}//end namespace diff --git a/source/glest_game/sound/sound_renderer.h b/source/glest_game/sound/sound_renderer.h index 0f17196b4..cdf730f1f 100644 --- a/source/glest_game/sound/sound_renderer.h +++ b/source/glest_game/sound/sound_renderer.h @@ -13,8 +13,8 @@ #define _GLEST_GAME_SOUNDRENDERER_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include "sound.h" @@ -25,73 +25,81 @@ #include "platform_common.h" #include "leak_dumper.h" -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -using ::Shared::Sound::StrSound; -using ::Shared::Sound::StaticSound; -using ::Shared::Sound::SoundPlayer; -using ::Shared::Graphics::Vec3f; -using namespace ::Shared::PlatformCommon; + using ::Shared::Sound::StrSound; + using ::Shared::Sound::StaticSound; + using ::Shared::Sound::SoundPlayer; + using ::Shared::Graphics::Vec3f; + using namespace ::Shared::PlatformCommon; -// ===================================================== -// class SoundRenderer -// -/// Wrapper to acces the shared library sound engine -// ===================================================== + // ===================================================== + // class SoundRenderer + // + /// Wrapper to acces the shared library sound engine + // ===================================================== -class SoundRenderer : public SimpleTaskCallbackInterface { -public: - static const int ambientFade; - static const float audibleDist; -private: - SoundPlayer *soundPlayer; + class SoundRenderer : public SimpleTaskCallbackInterface { + public: + static const int ambientFade; + static const float audibleDist; + private: + SoundPlayer * soundPlayer; - //volume - float fxVolume; - float musicVolume; - float ambientVolume; + //volume + float fxVolume; + float musicVolume; + float ambientVolume; - Mutex *mutex; - bool runThreadSafe; + Mutex *mutex; + bool runThreadSafe; -private: - SoundRenderer(); + private: + SoundRenderer(); - void cleanup(); + void cleanup(); -public: - //misc - virtual ~SoundRenderer(); - static SoundRenderer &getInstance(); - bool init(Window *window); - void update(); - virtual void simpleTask(BaseThread *callingThread,void *userdata) { update(); } - SoundPlayer *getSoundPlayer() const {return soundPlayer;} + public: + //misc + virtual ~SoundRenderer(); + static SoundRenderer &getInstance(); + bool init(Window *window); + void update(); + virtual void simpleTask(BaseThread *callingThread, void *userdata) { + update(); + } + SoundPlayer *getSoundPlayer() const { + return soundPlayer; + } - //music - void playMusic(StrSound *strSound); - void setMusicVolume(StrSound *strSound); - void stopMusic(StrSound *strSound); + //music + void playMusic(StrSound *strSound); + void setMusicVolume(StrSound *strSound); + void stopMusic(StrSound *strSound); - //fx - void playFx(StaticSound *staticSound, Vec3f soundPos, Vec3f camPos); - void playFx(StaticSound *staticSound, bool force=false); + //fx + void playFx(StaticSound *staticSound, Vec3f soundPos, Vec3f camPos); + void playFx(StaticSound *staticSound, bool force = false); - //ambient - void playAmbient(StrSound *strSound); - void stopAmbient(StrSound *strSound); + //ambient + void playAmbient(StrSound *strSound); + void stopAmbient(StrSound *strSound); - //misc - void stopAllSounds(int64 fadeOff=0); - void loadConfig(); + //misc + void stopAllSounds(int64 fadeOff = 0); + void loadConfig(); - bool wasInitOk() const; + bool wasInitOk() const; - bool runningThreaded() const { return runThreadSafe; } + bool runningThreaded() const { + return runThreadSafe; + } - bool isVolumeTurnedOff() const; -}; + bool isVolumeTurnedOff() const; + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/glest_game/steam/steam.cpp b/source/glest_game/steam/steam.cpp index 01371dc16..d2e9c2c55 100644 --- a/source/glest_game/steam/steam.cpp +++ b/source/glest_game/steam/steam.cpp @@ -5,308 +5,308 @@ #include "steamshim_child.h" #include "platform_common.h" -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -std::map Steam::SteamStatNameTypes = Steam::create_map(); + std::map Steam::SteamStatNameTypes = Steam::create_map(); -// Language map -static inline std::map gen_langToCode() -{ - std::map map; - map["brazilian"] = "pt_BR"; - map["bulgarian"] = "bg"; - map["czech"] = "cz"; - map["danish"] = "da"; - map["dutch"] = "nl"; - map["english"] = "en"; - map["finnish"] = "fi"; - map["french"] = "fr"; - map["german"] = "de"; - map["greek"] = "el"; - map["hungarian"] = "hu"; - map["italian"] = "it"; - map["japanese"] = "ja"; - map["koreana"] = "ko"; - map["korean"] = "ko"; - map["norwegian"] = "no"; - map["polish"] = "pl"; - map["portuguese"] = "pt"; - map["romanian"] = "ro"; - map["russian"] = "ru"; - map["schinese"] = "zh_CN"; - map["spanish"] = "es"; - map["swedish"] = "sv"; - map["tchinese"] = "zh_TW"; - map["thai"] = "th"; - map["turkish"] = "tr"; - map["ukrainian"] = "uk"; - return map; -} -static const std::map langToCode = gen_langToCode(); + // Language map + static inline std::map gen_langToCode() { + std::map map; + map["brazilian"] = "pt_BR"; + map["bulgarian"] = "bg"; + map["czech"] = "cz"; + map["danish"] = "da"; + map["dutch"] = "nl"; + map["english"] = "en"; + map["finnish"] = "fi"; + map["french"] = "fr"; + map["german"] = "de"; + map["greek"] = "el"; + map["hungarian"] = "hu"; + map["italian"] = "it"; + map["japanese"] = "ja"; + map["koreana"] = "ko"; + map["korean"] = "ko"; + map["norwegian"] = "no"; + map["polish"] = "pl"; + map["portuguese"] = "pt"; + map["romanian"] = "ro"; + map["russian"] = "ru"; + map["schinese"] = "zh_CN"; + map["spanish"] = "es"; + map["swedish"] = "sv"; + map["tchinese"] = "zh_TW"; + map["thai"] = "th"; + map["turkish"] = "tr"; + map["ukrainian"] = "uk"; + return map; + } + static const std::map langToCode = gen_langToCode(); -static std::string steamToIsoLang(const char *steamLang) { - //printf("Steam language [%s]\n",steamLang); - std::map::const_iterator it = langToCode.find(steamLang); - if (it != langToCode.end()) { - return it->second; - } - return "en"; -} - -// SteamPrivate -struct SteamPrivate { - static bool debugEnabled; - std::map achievements; - std::map stats; - - std::string userName; - std::string lang; - - SteamPrivate() { - if(debugEnabled) printf("\nCreating private steam state container\n"); - STEAMSHIM_getPersonaName(); - STEAMSHIM_getCurrentGameLanguage(); - STEAMSHIM_requestStats(); - STEAMSHIM_EventType statsReceived = SHIMEVENT_STATSRECEIVED; - - Shared::PlatformCommon::Chrono timerStats; - timerStats.start(); - while(update(&statsReceived) == NULL && timerStats.getMillis() < 2500) { - SDL_Delay(100); + static std::string steamToIsoLang(const char *steamLang) { + //printf("Steam language [%s]\n",steamLang); + std::map::const_iterator it = langToCode.find(steamLang); + if (it != langToCode.end()) { + return it->second; + } + return "en"; } - refreshAllStats(); - } + // SteamPrivate + struct SteamPrivate { + static bool debugEnabled; + std::map achievements; + std::map stats; - static void setDebugEnabled(bool value) { - debugEnabled = value; - } + std::string userName; + std::string lang; - void refreshAllStats() { - achievements.clear(); - stats.clear(); + SteamPrivate() { + if (debugEnabled) printf("\nCreating private steam state container\n"); + STEAMSHIM_getPersonaName(); + STEAMSHIM_getCurrentGameLanguage(); + STEAMSHIM_requestStats(); + STEAMSHIM_EventType statsReceived = SHIMEVENT_STATSRECEIVED; - for(int index = 0; index < EnumParser::getCount(); ++index) { - SteamStatName statName = static_cast(index); - string statNameStr = EnumParser::getString(statName); - SteamStatType statType = Steam::getSteamStatNameType(statNameStr); - switch(statType) { - case stat_int: - STEAMSHIM_getStatI(statNameStr.c_str()); - break; - case stat_float: - STEAMSHIM_getStatF(statNameStr.c_str()); - break; - default: + Shared::PlatformCommon::Chrono timerStats; + timerStats.start(); + while (update(&statsReceived) == NULL && timerStats.getMillis() < 2500) { + SDL_Delay(100); + } + + refreshAllStats(); + } + + static void setDebugEnabled(bool value) { + debugEnabled = value; + } + + void refreshAllStats() { + achievements.clear(); + stats.clear(); + + for (int index = 0; index < EnumParser::getCount(); ++index) { + SteamStatName statName = static_cast(index); + string statNameStr = EnumParser::getString(statName); + SteamStatType statType = Steam::getSteamStatNameType(statNameStr); + switch (statType) { + case stat_int: + STEAMSHIM_getStatI(statNameStr.c_str()); + break; + case stat_float: + STEAMSHIM_getStatF(statNameStr.c_str()); + break; + default: + break; + } + } + for (int index = 0; index < EnumParser::getCount(); ++index) { + SteamAchievementName achName = static_cast(index); + string achNameStr = EnumParser::getString(achName); + STEAMSHIM_getAchievement(achNameStr.c_str()); + } + + Shared::PlatformCommon::Chrono timer; + timer.start(); + while (!initialized() && timer.getMillis() < 2500) { + SDL_Delay(100); + update(); + } + } + + void setAchievement(const char *name, bool set) { + achievements[name] = set; + STEAMSHIM_setAchievement(name, set); + } + + void updateAchievement(const char *name, bool isSet) { + achievements[name] = isSet; + } + + bool isAchievementSet(const char *name) { + return achievements[name]; + } + + void updateStat(const char *name, double value) { + stats[name] = value; + } + + int getStatAsInt(const char *name) const { + std::map::const_iterator iterFind = stats.find(name); + if (iterFind != stats.end()) { + return iterFind->second; + } + return 0; + } + double getStatAsDouble(const char *name) const { + std::map::const_iterator iterFind = stats.find(name); + if (iterFind != stats.end()) { + return iterFind->second; + } + return 0; + } + + void setStatAsInt(const char *name, int value) { + STEAMSHIM_setStatI(name, value); + update(); + } + void setStatAsFloat(const char *name, float value) { + STEAMSHIM_setStatF(name, value); + update(); + } + // void clearLocalStats() { + // stats.clear(); + // } + + const STEAMSHIM_Event * update(STEAMSHIM_EventType *waitForEvent = NULL) { + const STEAMSHIM_Event *e; + while ((e = STEAMSHIM_pump()) != 0) { + // Handle events + switch (e->type) { + case SHIMEVENT_GETACHIEVEMENT: + if (debugEnabled) printf("\nGot Shim event SHIMEVENT_GETACHIEVEMENT name [%s] value [%d] isOk = %d\n", e->name, e->ivalue, e->okay); + if (e->okay) { + updateAchievement(e->name, e->ivalue); + } + break; + case SHIMEVENT_SETACHIEVEMENT: + if (debugEnabled) printf("\nGot Shim event SHIMEVENT_SETACHIEVEMENT for name [%s] value [%d] isOk = %d\n", e->name, e->ivalue, e->okay); + break; + case SHIMEVENT_GETPERSONANAME: + if (debugEnabled) printf("\nGot Shim event SHIMEVENT_GETPERSONANAME isOk = %d value [%s]\n", e->okay, e->name); + userName = e->name; + break; + case SHIMEVENT_GETCURRENTGAMELANGUAGE: + if (debugEnabled) printf("\nGot Shim event SHIMEVENT_GETCURRENTGAMELANGUAGE isOk = %d value [%s]\n", e->okay, e->name); + lang = steamToIsoLang(e->name); + break; + case SHIMEVENT_STATSRECEIVED: + if (debugEnabled) printf("\nGot Shim event SHIMEVENT_STATSRECEIVED isOk = %d\n", e->okay); + break; + case SHIMEVENT_STATSSTORED: + if (debugEnabled) printf("\nGot Shim event SHIMEVENT_STATSSTORED isOk = %d\n", e->okay); + break; + case SHIMEVENT_GETSTATI: + if (debugEnabled) printf("\nGot Shim event SHIMEVENT_GETSTATI for stat [%s] value [%d] isOk = %d\n", e->name, e->ivalue, e->okay); + if (e->okay) { + updateStat(e->name, e->ivalue); + } + break; + case SHIMEVENT_GETSTATF: + if (debugEnabled) printf("\nGot Shim event SHIMEVENT_GETSTATF for stat [%s] value [%f] isOk = %d\n", e->name, e->fvalue, e->okay); + if (e->okay) { + updateStat(e->name, e->fvalue); + } + break; + case SHIMEVENT_SETSTATI: + if (debugEnabled) printf("\nGot Shim event SHIMEVENT_SETSTATI for stat [%s] value [%d] isOk = %d\n", e->name, e->ivalue, e->okay); + break; + case SHIMEVENT_SETSTATF: + if (debugEnabled) printf("\nGot Shim event SHIMEVENT_SETSTATF for stat [%s] value [%f] isOk = %d\n", e->name, e->fvalue, e->okay); + break; + default: + if (debugEnabled) printf("\nGot Shim event [%d] isOk = %d\n", e->type, e->okay); + break; + } + if (waitForEvent != NULL && *waitForEvent == e->type) { + return e; + } + } + return NULL; + } + + bool initialized() { + return !userName.empty() + && !lang.empty() + && (int) stats.size() >= EnumParser::getCount() + && (int) achievements.size() >= EnumParser::getCount(); + } + }; + + bool SteamPrivate::debugEnabled = false; + + /* Steam */ + Steam::Steam() : p(new SteamPrivate()) { + } + + Steam::~Steam() { + delete p; + } + + const std::string &Steam::userName() const { + return p->userName; + } + + const std::string &Steam::lang() const { + return p->lang; + } + + void Steam::resetStats(const int bAlsoAchievements) const { + STEAMSHIM_resetStats(false); + p->update(); + } + + void Steam::storeStats() const { + STEAMSHIM_storeStats(); + STEAMSHIM_EventType statsStored = SHIMEVENT_STATSSTORED; + + Shared::PlatformCommon::Chrono timer; + timer.start(); + while (timer.getMillis() < 2500) { + SDL_Delay(100); + const STEAMSHIM_Event *evt = p->update(&statsStored); + if (evt != NULL && evt->type == statsStored) { break; + } } } - for(int index = 0; index < EnumParser::getCount(); ++index) { - SteamAchievementName achName = static_cast(index); - string achNameStr = EnumParser::getString(achName); - STEAMSHIM_getAchievement(achNameStr.c_str()); + + int Steam::getStatAsInt(const char *name) const { + return p->getStatAsInt(name); } - Shared::PlatformCommon::Chrono timer; - timer.start(); - while(!initialized() && timer.getMillis() < 2500) { - SDL_Delay(100); - update(); + double Steam::getStatAsDouble(const char *name) const { + return p->getStatAsDouble(name); } - } - void setAchievement(const char *name, bool set) { - achievements[name] = set; - STEAMSHIM_setAchievement(name, set); - } - - void updateAchievement(const char *name, bool isSet) { - achievements[name] = isSet; - } - - bool isAchievementSet(const char *name) { - return achievements[name]; - } - - void updateStat(const char *name, double value) { - stats[name] = value; - } - - int getStatAsInt(const char *name) const { - std::map::const_iterator iterFind = stats.find(name); - if(iterFind != stats.end()) { - return iterFind->second; + void Steam::setStatAsInt(const char *name, int value) { + p->setStatAsInt(name, value); } - return 0; - } - double getStatAsDouble(const char *name) const { - std::map::const_iterator iterFind = stats.find(name); - if(iterFind != stats.end()) { - return iterFind->second; + void Steam::setStatAsDouble(const char *name, double value) { + p->setStatAsFloat(name, value); } - return 0; - } - void setStatAsInt(const char *name, int value) { - STEAMSHIM_setStatI(name, value); - update(); - } - void setStatAsFloat(const char *name, float value) { - STEAMSHIM_setStatF(name, value); - update(); - } -// void clearLocalStats() { -// stats.clear(); -// } - - const STEAMSHIM_Event * update(STEAMSHIM_EventType *waitForEvent=NULL) { - const STEAMSHIM_Event *e; - while ((e = STEAMSHIM_pump()) != 0) { - // Handle events - switch (e->type) - { - case SHIMEVENT_GETACHIEVEMENT: - if(debugEnabled) printf("\nGot Shim event SHIMEVENT_GETACHIEVEMENT name [%s] value [%d] isOk = %d\n",e->name,e->ivalue,e->okay); - if(e->okay) { - updateAchievement(e->name, e->ivalue); - } - break; - case SHIMEVENT_SETACHIEVEMENT: - if(debugEnabled) printf("\nGot Shim event SHIMEVENT_SETACHIEVEMENT for name [%s] value [%d] isOk = %d\n",e->name,e->ivalue,e->okay); - break; - case SHIMEVENT_GETPERSONANAME: - if(debugEnabled) printf("\nGot Shim event SHIMEVENT_GETPERSONANAME isOk = %d value [%s]\n",e->okay,e->name); - userName = e->name; - break; - case SHIMEVENT_GETCURRENTGAMELANGUAGE: - if(debugEnabled) printf("\nGot Shim event SHIMEVENT_GETCURRENTGAMELANGUAGE isOk = %d value [%s]\n",e->okay,e->name); - lang = steamToIsoLang(e->name); - break; - case SHIMEVENT_STATSRECEIVED: - if(debugEnabled) printf("\nGot Shim event SHIMEVENT_STATSRECEIVED isOk = %d\n",e->okay); - break; - case SHIMEVENT_STATSSTORED: - if(debugEnabled) printf("\nGot Shim event SHIMEVENT_STATSSTORED isOk = %d\n",e->okay); - break; - case SHIMEVENT_GETSTATI: - if(debugEnabled) printf("\nGot Shim event SHIMEVENT_GETSTATI for stat [%s] value [%d] isOk = %d\n",e->name,e->ivalue,e->okay); - if(e->okay) { - updateStat(e->name, e->ivalue); - } - break; - case SHIMEVENT_GETSTATF: - if(debugEnabled) printf("\nGot Shim event SHIMEVENT_GETSTATF for stat [%s] value [%f] isOk = %d\n",e->name,e->fvalue,e->okay); - if(e->okay) { - updateStat(e->name, e->fvalue); - } - break; - case SHIMEVENT_SETSTATI: - if(debugEnabled) printf("\nGot Shim event SHIMEVENT_SETSTATI for stat [%s] value [%d] isOk = %d\n",e->name,e->ivalue,e->okay); - break; - case SHIMEVENT_SETSTATF: - if(debugEnabled) printf("\nGot Shim event SHIMEVENT_SETSTATF for stat [%s] value [%f] isOk = %d\n",e->name,e->fvalue,e->okay); - break; - default: - if(debugEnabled) printf("\nGot Shim event [%d] isOk = %d\n",e->type,e->okay); - break; + void Steam::requestRefreshStats() { + STEAMSHIM_requestStats(); + STEAMSHIM_EventType statsReceived = SHIMEVENT_STATSRECEIVED; + Shared::PlatformCommon::Chrono timerStats; + timerStats.start(); + while (p->update(&statsReceived) == NULL && timerStats.getMillis() < 2500) { + SDL_Delay(100); } - if(waitForEvent != NULL && *waitForEvent == e->type) { - return e; - } - } - return NULL; - } - - bool initialized() { - return !userName.empty() - && !lang.empty() - && (int)stats.size() >= EnumParser::getCount() - && (int)achievements.size() >= EnumParser::getCount(); - } -}; - -bool SteamPrivate::debugEnabled = false; - -/* Steam */ -Steam::Steam() : p(new SteamPrivate()) { -} - -Steam::~Steam() { - delete p; -} - -const std::string &Steam::userName() const { - return p->userName; -} - -const std::string &Steam::lang() const { - return p->lang; -} - -void Steam::resetStats(const int bAlsoAchievements) const { - STEAMSHIM_resetStats(false); - p->update(); -} - -void Steam::storeStats() const { - STEAMSHIM_storeStats(); - STEAMSHIM_EventType statsStored = SHIMEVENT_STATSSTORED; - - Shared::PlatformCommon::Chrono timer; - timer.start(); - while(timer.getMillis() < 2500) { - SDL_Delay(100); - const STEAMSHIM_Event *evt = p->update(&statsStored); - if(evt != NULL && evt->type == statsStored) { - break; + p->refreshAllStats(); } + + SteamStatType Steam::getSteamStatNameType(string value) { + return SteamStatNameTypes[value]; + } + + void Steam::unlock(const char *name) { + p->setAchievement(name, true); + } + + void Steam::lock(const char *name) { + p->setAchievement(name, false); + } + + bool Steam::isUnlocked(const char *name) { + return p->isAchievementSet(name); + } + + void Steam::setDebugEnabled(bool value) { + SteamPrivate::setDebugEnabled(value); + } + } -} - -int Steam::getStatAsInt(const char *name) const { - return p->getStatAsInt(name); -} - -double Steam::getStatAsDouble(const char *name) const { - return p->getStatAsDouble(name); -} - -void Steam::setStatAsInt(const char *name, int value) { - p->setStatAsInt(name, value); -} -void Steam::setStatAsDouble(const char *name, double value) { - p->setStatAsFloat(name, value); -} - -void Steam::requestRefreshStats() { - STEAMSHIM_requestStats(); - STEAMSHIM_EventType statsReceived = SHIMEVENT_STATSRECEIVED; - Shared::PlatformCommon::Chrono timerStats; - timerStats.start(); - while(p->update(&statsReceived) == NULL && timerStats.getMillis() < 2500) { - SDL_Delay(100); - } - p->refreshAllStats(); -} - -SteamStatType Steam::getSteamStatNameType(string value) { - return SteamStatNameTypes[value]; -} - -void Steam::unlock(const char *name) { - p->setAchievement(name, true); -} - -void Steam::lock(const char *name) { - p->setAchievement(name, false); -} - -bool Steam::isUnlocked(const char *name) { - return p->isAchievementSet(name); -} - -void Steam::setDebugEnabled(bool value) { - SteamPrivate::setDebugEnabled(value); -} - -}}//end namespace +}//end namespace diff --git a/source/glest_game/steam/steam.h b/source/glest_game/steam/steam.h index 10b867719..e459ec956 100644 --- a/source/glest_game/steam/steam.h +++ b/source/glest_game/steam/steam.h @@ -5,98 +5,99 @@ #include #include "game_constants.h" -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -struct SteamPrivate; + struct SteamPrivate; -enum SteamStatName { - stat_online_wins, - stat_online_loses, - stat_online_kills, - stat_online_kills_enemy, - stat_online_deaths, - stat_online_units, - stat_online_resources_harvested, - stat_online_quit_before_end, - stat_online_minutes_played -}; + enum SteamStatName { + stat_online_wins, + stat_online_loses, + stat_online_kills, + stat_online_kills_enemy, + stat_online_deaths, + stat_online_units, + stat_online_resources_harvested, + stat_online_quit_before_end, + stat_online_minutes_played + }; -enum SteamStatType { - stat_int, - stat_float, - stat_avg -}; + enum SteamStatType { + stat_int, + stat_float, + stat_avg + }; -template <> -inline EnumParser::EnumParser() { - enumMap["stat_online_wins"] = stat_online_wins; - enumMap["stat_online_loses"] = stat_online_loses; - enumMap["stat_online_kills"] = stat_online_kills; - enumMap["stat_online_kills_enemy"] = stat_online_kills_enemy; - enumMap["stat_online_deaths"] = stat_online_deaths; - enumMap["stat_online_units"] = stat_online_units; - enumMap["stat_online_resources_harvested"] = stat_online_resources_harvested; - enumMap["stat_online_quit_before_end"] = stat_online_quit_before_end; - enumMap["stat_online_minutes_played"] = stat_online_minutes_played; -} + template <> + inline EnumParser::EnumParser() { + enumMap["stat_online_wins"] = stat_online_wins; + enumMap["stat_online_loses"] = stat_online_loses; + enumMap["stat_online_kills"] = stat_online_kills; + enumMap["stat_online_kills_enemy"] = stat_online_kills_enemy; + enumMap["stat_online_deaths"] = stat_online_deaths; + enumMap["stat_online_units"] = stat_online_units; + enumMap["stat_online_resources_harvested"] = stat_online_resources_harvested; + enumMap["stat_online_quit_before_end"] = stat_online_quit_before_end; + enumMap["stat_online_minutes_played"] = stat_online_minutes_played; + } -enum SteamAchievementName { - ACH_WIN_ONE_GAME, - ACH_WIN_ONE_GAME_ONLINE -}; + enum SteamAchievementName { + ACH_WIN_ONE_GAME, + ACH_WIN_ONE_GAME_ONLINE + }; -template <> -inline EnumParser::EnumParser() { - enumMap["ACH_WIN_ONE_GAME"] = ACH_WIN_ONE_GAME; - enumMap["ACH_WIN_ONE_GAME_ONLINE"] = ACH_WIN_ONE_GAME_ONLINE; -} + template <> + inline EnumParser::EnumParser() { + enumMap["ACH_WIN_ONE_GAME"] = ACH_WIN_ONE_GAME; + enumMap["ACH_WIN_ONE_GAME_ONLINE"] = ACH_WIN_ONE_GAME_ONLINE; + } -class Steam -{ -public: - void unlock(const char *name); - void lock(const char *name); - bool isUnlocked(const char *name); + class Steam { + public: + void unlock(const char *name); + void lock(const char *name); + bool isUnlocked(const char *name); - static SteamStatType getSteamStatNameType(string value); + static SteamStatType getSteamStatNameType(string value); - const std::string &userName() const; - const std::string &lang() const; + const std::string &userName() const; + const std::string &lang() const; - void resetStats(const int bAlsoAchievements) const; - void storeStats() const; - int getStatAsInt(const char *name) const; - double getStatAsDouble(const char *name) const; - void setStatAsInt(const char *name, int value); - void setStatAsDouble(const char *name, double value); + void resetStats(const int bAlsoAchievements) const; + void storeStats() const; + int getStatAsInt(const char *name) const; + double getStatAsDouble(const char *name) const; + void setStatAsInt(const char *name, int value); + void setStatAsDouble(const char *name, double value); - void requestRefreshStats(); - static void setDebugEnabled(bool value); + void requestRefreshStats(); + static void setDebugEnabled(bool value); - Steam(); - ~Steam(); + Steam(); + ~Steam(); -private: - //friend struct SharedStatePrivate; + private: + //friend struct SharedStatePrivate; - SteamPrivate *p; - static std::map SteamStatNameTypes; + SteamPrivate * p; + static std::map SteamStatNameTypes; + + static std::map create_map() { + std::map steamStatNameTypes; + steamStatNameTypes["stat_online_wins"] = stat_int; + steamStatNameTypes["stat_online_loses"] = stat_int; + steamStatNameTypes["stat_online_kills"] = stat_int; + steamStatNameTypes["stat_online_kills_enemy"] = stat_int; + steamStatNameTypes["stat_online_deaths"] = stat_int; + steamStatNameTypes["stat_online_units"] = stat_int; + steamStatNameTypes["stat_online_resources_harvested"] = stat_int; + steamStatNameTypes["stat_online_quit_before_end"] = stat_int; + steamStatNameTypes["stat_online_minutes_played"] = stat_float; + return steamStatNameTypes; + } + }; - static std::map create_map() { - std::map steamStatNameTypes; - steamStatNameTypes["stat_online_wins"] = stat_int; - steamStatNameTypes["stat_online_loses"] = stat_int; - steamStatNameTypes["stat_online_kills"] = stat_int; - steamStatNameTypes["stat_online_kills_enemy"] = stat_int; - steamStatNameTypes["stat_online_deaths"] = stat_int; - steamStatNameTypes["stat_online_units"] = stat_int; - steamStatNameTypes["stat_online_resources_harvested"] = stat_int; - steamStatNameTypes["stat_online_quit_before_end"] = stat_int; - steamStatNameTypes["stat_online_minutes_played"] = stat_float; - return steamStatNameTypes; } -}; - -}}//end namespace +}//end namespace #endif // STEAM_H diff --git a/source/glest_game/steamshim/steamshim_child.c b/source/glest_game/steamshim/steamshim_child.c index be456a6ec..012ab5579 100644 --- a/source/glest_game/steamshim/steamshim_child.c +++ b/source/glest_game/steamshim/steamshim_child.c @@ -28,7 +28,8 @@ typedef int PipeType; #ifdef STEAMSHIM_DEBUG #define dbgpipe printf #else -static inline void dbgpipe(const char *fmt, ...) {} +static inline void dbgpipe(const char *fmt, ...) { +} #endif static int writePipe(PipeType fd, const void *buf, const unsigned int _len); @@ -40,76 +41,69 @@ static int pipeReady(PipeType fd); #ifdef _WIN32 -static int pipeReady(PipeType fd) -{ - DWORD avail = 0; - return (PeekNamedPipe(fd, NULL, 0, NULL, &avail, NULL) && (avail > 0)); +static int pipeReady(PipeType fd) { + DWORD avail = 0; + return (PeekNamedPipe(fd, NULL, 0, NULL, &avail, NULL) && (avail > 0)); } /* pipeReady */ -static int writePipe(PipeType fd, const void *buf, const unsigned int _len) -{ - const DWORD len = (DWORD) _len; - DWORD bw = 0; - return ((WriteFile(fd, buf, len, &bw, NULL) != 0) && (bw == len)); +static int writePipe(PipeType fd, const void *buf, const unsigned int _len) { + const DWORD len = (DWORD) _len; + DWORD bw = 0; + return ((WriteFile(fd, buf, len, &bw, NULL) != 0) && (bw == len)); } /* writePipe */ -static int readPipe(PipeType fd, void *buf, const unsigned int _len) -{ - const DWORD len = (DWORD) _len; - DWORD br = 0; - return ReadFile(fd, buf, len, &br, NULL) ? (int) br : -1; +static int readPipe(PipeType fd, void *buf, const unsigned int _len) { + const DWORD len = (DWORD) _len; + DWORD br = 0; + return ReadFile(fd, buf, len, &br, NULL) ? (int) br : -1; } /* readPipe */ -static void closePipe(PipeType fd) -{ - CloseHandle(fd); +static void closePipe(PipeType fd) { + CloseHandle(fd); } /* closePipe */ -static char *getEnvVar(const char *key, char *buf, const size_t buflen) -{ - const DWORD rc = GetEnvironmentVariableA(key, buf, buflen); - /* rc doesn't count null char, hence "<". */ - return ((rc > 0) && (rc < buflen)) ? buf : NULL; +static char *getEnvVar(const char *key, char *buf, const size_t buflen) { + const DWORD rc = GetEnvironmentVariableA(key, buf, buflen); + /* rc doesn't count null char, hence "<". */ + return ((rc > 0) && (rc < buflen)) ? buf : NULL; } /* getEnvVar */ #else -static int pipeReady(PipeType fd) -{ - int rc; - struct pollfd pfd = { fd, POLLIN | POLLERR | POLLHUP, 0 }; - while (((rc = poll(&pfd, 1, 0)) == -1) && (errno == EINTR)) { /*spin*/ } - return (rc == 1); +static int pipeReady(PipeType fd) { + int rc; + struct pollfd pfd = { fd, POLLIN | POLLERR | POLLHUP, 0 }; + while (((rc = poll(&pfd, 1, 0)) == -1) && (errno == EINTR)) { /*spin*/ + } + return (rc == 1); } /* pipeReady */ -static int writePipe(PipeType fd, const void *buf, const unsigned int _len) -{ - const ssize_t len = (ssize_t) _len; - ssize_t bw; - while (((bw = write(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/ } - return (bw == len); +static int writePipe(PipeType fd, const void *buf, const unsigned int _len) { + const ssize_t len = (ssize_t) _len; + ssize_t bw; + while (((bw = write(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/ + } + return (bw == len); } /* writePipe */ -static int readPipe(PipeType fd, void *buf, const unsigned int _len) -{ - const ssize_t len = (ssize_t) _len; - ssize_t br; - while (((br = read(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/ } - return (int) br; +static int readPipe(PipeType fd, void *buf, const unsigned int _len) { + const ssize_t len = (ssize_t) _len; + ssize_t br; + while (((br = read(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/ + } + return (int) br; } /* readPipe */ -static void closePipe(PipeType fd) -{ - close(fd); +static void closePipe(PipeType fd) { + close(fd); } /* closePipe */ -static char *getEnvVar(const char *key, char *buf, const size_t buflen) -{ - const char *envr = getenv(key); - if (!envr || (strlen(envr) >= buflen)) - return NULL; - strcpy(buf, envr); - return buf; +static char *getEnvVar(const char *key, char *buf, const size_t buflen) { + const char *envr = getenv(key); + if (!envr || (strlen(envr) >= buflen)) + return NULL; + strcpy(buf, envr); + return buf; } /* getEnvVar */ #endif @@ -118,346 +112,316 @@ static char *getEnvVar(const char *key, char *buf, const size_t buflen) static PipeType GPipeRead = NULLPIPE; static PipeType GPipeWrite = NULLPIPE; -typedef enum ShimCmd -{ - SHIMCMD_BYE, - SHIMCMD_PUMP, - SHIMCMD_REQUESTSTATS, - SHIMCMD_STORESTATS, - SHIMCMD_SETACHIEVEMENT, - SHIMCMD_GETACHIEVEMENT, - SHIMCMD_RESETSTATS, - SHIMCMD_SETSTATI, - SHIMCMD_GETSTATI, - SHIMCMD_SETSTATF, - SHIMCMD_GETSTATF, - SHIMCMD_GETPERSONANAME, - SHIMCMD_GETCURRENTGAMELANGUAGE, +typedef enum ShimCmd { + SHIMCMD_BYE, + SHIMCMD_PUMP, + SHIMCMD_REQUESTSTATS, + SHIMCMD_STORESTATS, + SHIMCMD_SETACHIEVEMENT, + SHIMCMD_GETACHIEVEMENT, + SHIMCMD_RESETSTATS, + SHIMCMD_SETSTATI, + SHIMCMD_GETSTATI, + SHIMCMD_SETSTATF, + SHIMCMD_GETSTATF, + SHIMCMD_GETPERSONANAME, + SHIMCMD_GETCURRENTGAMELANGUAGE, } ShimCmd; -static int write1ByteCmd(const uint8 b1) -{ - const uint8 buf[] = { 1, b1 }; - return writePipe(GPipeWrite, buf, sizeof (buf)); +static int write1ByteCmd(const uint8 b1) { + const uint8 buf[] = { 1, b1 }; + return writePipe(GPipeWrite, buf, sizeof(buf)); } /* write1ByteCmd */ -static int write2ByteCmd(const uint8 b1, const uint8 b2) -{ - const uint8 buf[] = { 2, b1, b2 }; - return writePipe(GPipeWrite, buf, sizeof (buf)); +static int write2ByteCmd(const uint8 b1, const uint8 b2) { + const uint8 buf[] = { 2, b1, b2 }; + return writePipe(GPipeWrite, buf, sizeof(buf)); } /* write2ByteCmd */ -static inline int writeBye(void) -{ - dbgpipe("Child sending SHIMCMD_BYE().\n"); - return write1ByteCmd(SHIMCMD_BYE); +static inline int writeBye(void) { + dbgpipe("Child sending SHIMCMD_BYE().\n"); + return write1ByteCmd(SHIMCMD_BYE); } // writeBye -static int initPipes(void) -{ - char buf[64]; +static int initPipes(void) { + char buf[64]; - if (!getEnvVar("STEAMSHIM_READHANDLE", buf, sizeof (buf))) - return 0; - GPipeRead = (PipeType) strtoull(buf, 0, 10); + if (!getEnvVar("STEAMSHIM_READHANDLE", buf, sizeof(buf))) + return 0; + GPipeRead = (PipeType) strtoull(buf, 0, 10); - if (!getEnvVar("STEAMSHIM_WRITEHANDLE", buf, sizeof (buf))) - return 0; - GPipeWrite = (PipeType) strtoull(buf, 0, 10); + if (!getEnvVar("STEAMSHIM_WRITEHANDLE", buf, sizeof(buf))) + return 0; + GPipeWrite = (PipeType) strtoull(buf, 0, 10); - return ((GPipeRead != NULLPIPE) && (GPipeWrite != NULLPIPE)); + return ((GPipeRead != NULLPIPE) && (GPipeWrite != NULLPIPE)); } /* initPipes */ -int STEAMSHIM_init(void) -{ +int STEAMSHIM_init(void) { printf("Initializing Steam Shim...\n"); - dbgpipe("Child init start.\n"); - if (!initPipes()) - { - dbgpipe("Child init failed.\n"); - return 0; - } /* if */ + dbgpipe("Child init start.\n"); + if (!initPipes()) { + dbgpipe("Child init failed.\n"); + return 0; + } /* if */ #ifndef _WIN32 - signal(SIGPIPE, SIG_IGN); + signal(SIGPIPE, SIG_IGN); #endif - printf("Init of Steam Shim successful!\n"); - dbgpipe("Child init success!\n"); - return 1; + printf("Init of Steam Shim successful!\n"); + dbgpipe("Child init success!\n"); + return 1; } /* STEAMSHIM_init */ -void STEAMSHIM_deinit(void) -{ - dbgpipe("Child deinit.\n"); - if (GPipeWrite != NULLPIPE) - { - writeBye(); - closePipe(GPipeWrite); - } /* if */ +void STEAMSHIM_deinit(void) { + dbgpipe("Child deinit.\n"); + if (GPipeWrite != NULLPIPE) { + writeBye(); + closePipe(GPipeWrite); + } /* if */ - if (GPipeRead != NULLPIPE) - closePipe(GPipeRead); + if (GPipeRead != NULLPIPE) + closePipe(GPipeRead); - GPipeRead = GPipeWrite = NULLPIPE; + GPipeRead = GPipeWrite = NULLPIPE; #ifndef _WIN32 - signal(SIGPIPE, SIG_DFL); + signal(SIGPIPE, SIG_DFL); #endif } /* STEAMSHIM_deinit */ -static inline int isAlive(void) -{ - return ((GPipeRead != NULLPIPE) && (GPipeWrite != NULLPIPE)); +static inline int isAlive(void) { + return ((GPipeRead != NULLPIPE) && (GPipeWrite != NULLPIPE)); } /* isAlive */ -static inline int isDead(void) -{ - return !isAlive(); +static inline int isDead(void) { + return !isAlive(); } /* isDead */ -int STEAMSHIM_alive(void) -{ - return isAlive(); +int STEAMSHIM_alive(void) { + return isAlive(); } /* STEAMSHIM_alive */ -static const STEAMSHIM_Event *processEvent(const uint8 *buf, size_t buflen) -{ - static STEAMSHIM_Event event; - const STEAMSHIM_EventType type = (STEAMSHIM_EventType) *(buf++); - buflen--; +static const STEAMSHIM_Event *processEvent(const uint8 *buf, size_t buflen) { + static STEAMSHIM_Event event; + const STEAMSHIM_EventType type = (STEAMSHIM_EventType) *(buf++); + buflen--; - memset(&event, '\0', sizeof (event)); - event.type = type; - event.okay = 1; + memset(&event, '\0', sizeof(event)); + event.type = type; + event.okay = 1; - #ifdef STEAMSHIM_DEBUG - if (0) {} - #define PRINTGOTEVENT(x) else if (type == x) printf("Child got " #x ".\n") - PRINTGOTEVENT(SHIMEVENT_BYE); - PRINTGOTEVENT(SHIMEVENT_STATSRECEIVED); - PRINTGOTEVENT(SHIMEVENT_STATSSTORED); - PRINTGOTEVENT(SHIMEVENT_SETACHIEVEMENT); - PRINTGOTEVENT(SHIMEVENT_GETACHIEVEMENT); - PRINTGOTEVENT(SHIMEVENT_RESETSTATS); - PRINTGOTEVENT(SHIMEVENT_SETSTATI); - PRINTGOTEVENT(SHIMEVENT_GETSTATI); - PRINTGOTEVENT(SHIMEVENT_SETSTATF); - PRINTGOTEVENT(SHIMEVENT_GETSTATF); - PRINTGOTEVENT(SHIMEVENT_GETPERSONANAME); - PRINTGOTEVENT(SHIMEVENT_GETCURRENTGAMELANGUAGE); - #undef PRINTGOTEVENT - else printf("Child got unknown shimevent %d.\n", (int) type); - #endif +#ifdef STEAMSHIM_DEBUG + if (0) { + } +#define PRINTGOTEVENT(x) else if (type == x) printf("Child got " #x ".\n") + PRINTGOTEVENT(SHIMEVENT_BYE); + PRINTGOTEVENT(SHIMEVENT_STATSRECEIVED); + PRINTGOTEVENT(SHIMEVENT_STATSSTORED); + PRINTGOTEVENT(SHIMEVENT_SETACHIEVEMENT); + PRINTGOTEVENT(SHIMEVENT_GETACHIEVEMENT); + PRINTGOTEVENT(SHIMEVENT_RESETSTATS); + PRINTGOTEVENT(SHIMEVENT_SETSTATI); + PRINTGOTEVENT(SHIMEVENT_GETSTATI); + PRINTGOTEVENT(SHIMEVENT_SETSTATF); + PRINTGOTEVENT(SHIMEVENT_GETSTATF); + PRINTGOTEVENT(SHIMEVENT_GETPERSONANAME); + PRINTGOTEVENT(SHIMEVENT_GETCURRENTGAMELANGUAGE); +#undef PRINTGOTEVENT +else printf("Child got unknown shimevent %d.\n", (int) type); +#endif - switch (type) - { - case SHIMEVENT_BYE: - break; +switch (type) { + case SHIMEVENT_BYE: + break; - case SHIMEVENT_STATSRECEIVED: - case SHIMEVENT_STATSSTORED: - if (!buflen) return NULL; - event.okay = *(buf++) ? 1 : 0; - break; + case SHIMEVENT_STATSRECEIVED: + case SHIMEVENT_STATSSTORED: + if (!buflen) return NULL; + event.okay = *(buf++) ? 1 : 0; + break; - case SHIMEVENT_SETACHIEVEMENT: - if (buflen < 3) return NULL; - event.ivalue = *(buf++) ? 1 : 0; - event.okay = *(buf++) ? 1 : 0; - strcpy(event.name, (const char *) buf); - break; + case SHIMEVENT_SETACHIEVEMENT: + if (buflen < 3) return NULL; + event.ivalue = *(buf++) ? 1 : 0; + event.okay = *(buf++) ? 1 : 0; + strcpy(event.name, (const char *) buf); + break; - case SHIMEVENT_GETACHIEVEMENT: - if (buflen < 10) return NULL; - event.ivalue = (int) *(buf++); - if (event.ivalue == 2) - event.ivalue = event.okay = 0; - event.epochsecs = (long long unsigned) *((uint64 *) buf); - buf += sizeof (uint64); - strcpy(event.name, (const char *) buf); - break; + case SHIMEVENT_GETACHIEVEMENT: + if (buflen < 10) return NULL; + event.ivalue = (int) *(buf++); + if (event.ivalue == 2) + event.ivalue = event.okay = 0; + event.epochsecs = (long long unsigned) *((uint64 *) buf); + buf += sizeof(uint64); + strcpy(event.name, (const char *) buf); + break; - case SHIMEVENT_RESETSTATS: - if (buflen != 2) return NULL; - event.ivalue = *(buf++) ? 1 : 0; - event.okay = *(buf++) ? 1 : 0; - break; + case SHIMEVENT_RESETSTATS: + if (buflen != 2) return NULL; + event.ivalue = *(buf++) ? 1 : 0; + event.okay = *(buf++) ? 1 : 0; + break; - case SHIMEVENT_SETSTATI: - case SHIMEVENT_GETSTATI: - event.okay = *(buf++) ? 1 : 0; - event.ivalue = (int) *((int32 *) buf); - buf += sizeof (int32); - strcpy(event.name, (const char *) buf); - break; + case SHIMEVENT_SETSTATI: + case SHIMEVENT_GETSTATI: + event.okay = *(buf++) ? 1 : 0; + event.ivalue = (int) *((int32 *) buf); + buf += sizeof(int32); + strcpy(event.name, (const char *) buf); + break; - case SHIMEVENT_SETSTATF: - case SHIMEVENT_GETSTATF: - event.okay = *(buf++) ? 1 : 0; - event.fvalue = (int) *((float *) buf); - buf += sizeof (float); - strcpy(event.name, (const char *) buf); - break; + case SHIMEVENT_SETSTATF: + case SHIMEVENT_GETSTATF: + event.okay = *(buf++) ? 1 : 0; + event.fvalue = (int) *((float *) buf); + buf += sizeof(float); + strcpy(event.name, (const char *) buf); + break; - case SHIMEVENT_GETPERSONANAME: - case SHIMEVENT_GETCURRENTGAMELANGUAGE: - strcpy(event.name, (const char *) buf); - break; + case SHIMEVENT_GETPERSONANAME: + case SHIMEVENT_GETCURRENTGAMELANGUAGE: + strcpy(event.name, (const char *) buf); + break; - default: /* uh oh */ - return NULL; - } /* switch */ + default: /* uh oh */ + return NULL; +} /* switch */ - return &event; +return &event; } /* processEvent */ -const STEAMSHIM_Event *STEAMSHIM_pump(void) -{ - static uint8 buf[256]; - static int br = 0; - int evlen = (br > 0) ? ((int) buf[0]) : 0; +const STEAMSHIM_Event *STEAMSHIM_pump(void) { + static uint8 buf[256]; + static int br = 0; + int evlen = (br > 0) ? ((int) buf[0]) : 0; - if (isDead()) - return NULL; + if (isDead()) + return NULL; - if (br <= evlen) /* we have an incomplete commmand. Try to read more. */ - { - if (pipeReady(GPipeRead)) - { - const int morebr = readPipe(GPipeRead, buf + br, sizeof (buf) - br); - if (morebr > 0) - br += morebr; - else /* uh oh */ - { - dbgpipe("Child readPipe failed! Shutting down.\n"); - STEAMSHIM_deinit(); /* kill it all. */ - } /* else */ - } /* if */ - } /* if */ + if (br <= evlen) /* we have an incomplete commmand. Try to read more. */ + { + if (pipeReady(GPipeRead)) { + const int morebr = readPipe(GPipeRead, buf + br, sizeof(buf) - br); + if (morebr > 0) + br += morebr; + else /* uh oh */ + { + dbgpipe("Child readPipe failed! Shutting down.\n"); + STEAMSHIM_deinit(); /* kill it all. */ + } /* else */ + } /* if */ + } /* if */ - if (evlen && (br > evlen)) - { - const STEAMSHIM_Event *retval = processEvent(buf+1, evlen); - br -= evlen + 1; - if (br > 0) - memmove(buf, buf+evlen+1, br); - return retval; - } /* if */ + if (evlen && (br > evlen)) { + const STEAMSHIM_Event *retval = processEvent(buf + 1, evlen); + br -= evlen + 1; + if (br > 0) + memmove(buf, buf + evlen + 1, br); + return retval; + } /* if */ - /* Run Steam event loop. */ - if (br == 0) - { - dbgpipe("Child sending SHIMCMD_PUMP().\n"); - write1ByteCmd(SHIMCMD_PUMP); - } /* if */ + /* Run Steam event loop. */ + if (br == 0) { + dbgpipe("Child sending SHIMCMD_PUMP().\n"); + write1ByteCmd(SHIMCMD_PUMP); + } /* if */ - return NULL; + return NULL; } /* STEAMSHIM_pump */ -void STEAMSHIM_requestStats(void) -{ - if (isDead()) return; - dbgpipe("Child sending SHIMCMD_REQUESTSTATS().\n"); - write1ByteCmd(SHIMCMD_REQUESTSTATS); +void STEAMSHIM_requestStats(void) { + if (isDead()) return; + dbgpipe("Child sending SHIMCMD_REQUESTSTATS().\n"); + write1ByteCmd(SHIMCMD_REQUESTSTATS); } /* STEAMSHIM_requestStats */ -void STEAMSHIM_storeStats(void) -{ - if (isDead()) return; - dbgpipe("Child sending SHIMCMD_STORESTATS().\n"); - write1ByteCmd(SHIMCMD_STORESTATS); +void STEAMSHIM_storeStats(void) { + if (isDead()) return; + dbgpipe("Child sending SHIMCMD_STORESTATS().\n"); + write1ByteCmd(SHIMCMD_STORESTATS); } /* STEAMSHIM_storeStats */ -void STEAMSHIM_setAchievement(const char *name, const int enable) -{ - uint8 buf[256]; - uint8 *ptr = buf+1; - if (isDead()) return; - dbgpipe("Child sending SHIMCMD_SETACHIEVEMENT('%s', %senable).\n", name, enable ? "" : "!"); - *(ptr++) = (uint8) SHIMCMD_SETACHIEVEMENT; - *(ptr++) = enable ? 1 : 0; - strcpy((char *) ptr, name); - ptr += strlen(name) + 1; - buf[0] = (uint8) ((ptr-1) - buf); - writePipe(GPipeWrite, buf, buf[0] + 1); +void STEAMSHIM_setAchievement(const char *name, const int enable) { + uint8 buf[256]; + uint8 *ptr = buf + 1; + if (isDead()) return; + dbgpipe("Child sending SHIMCMD_SETACHIEVEMENT('%s', %senable).\n", name, enable ? "" : "!"); + *(ptr++) = (uint8) SHIMCMD_SETACHIEVEMENT; + *(ptr++) = enable ? 1 : 0; + strcpy((char *) ptr, name); + ptr += strlen(name) + 1; + buf[0] = (uint8) ((ptr - 1) - buf); + writePipe(GPipeWrite, buf, buf[0] + 1); } /* STEAMSHIM_setAchievement */ -void STEAMSHIM_getAchievement(const char *name) -{ - uint8 buf[256]; - uint8 *ptr = buf+1; - if (isDead()) return; - dbgpipe("Child sending SHIMCMD_GETACHIEVEMENT('%s').\n", name); - *(ptr++) = (uint8) SHIMCMD_GETACHIEVEMENT; - strcpy((char *) ptr, name); - ptr += strlen(name) + 1; - buf[0] = (uint8) ((ptr-1) - buf); - writePipe(GPipeWrite, buf, buf[0] + 1); +void STEAMSHIM_getAchievement(const char *name) { + uint8 buf[256]; + uint8 *ptr = buf + 1; + if (isDead()) return; + dbgpipe("Child sending SHIMCMD_GETACHIEVEMENT('%s').\n", name); + *(ptr++) = (uint8) SHIMCMD_GETACHIEVEMENT; + strcpy((char *) ptr, name); + ptr += strlen(name) + 1; + buf[0] = (uint8) ((ptr - 1) - buf); + writePipe(GPipeWrite, buf, buf[0] + 1); } /* STEAMSHIM_getAchievement */ -void STEAMSHIM_resetStats(const int bAlsoAchievements) -{ - if (isDead()) return; - dbgpipe("Child sending SHIMCMD_RESETSTATS(%salsoAchievements).\n", bAlsoAchievements ? "" : "!"); - write2ByteCmd(SHIMCMD_RESETSTATS, bAlsoAchievements ? 1 : 0); +void STEAMSHIM_resetStats(const int bAlsoAchievements) { + if (isDead()) return; + dbgpipe("Child sending SHIMCMD_RESETSTATS(%salsoAchievements).\n", bAlsoAchievements ? "" : "!"); + write2ByteCmd(SHIMCMD_RESETSTATS, bAlsoAchievements ? 1 : 0); } /* STEAMSHIM_resetStats */ -static void writeStatThing(const ShimCmd cmd, const char *name, const void *val, const size_t vallen) -{ - uint8 buf[256]; - uint8 *ptr = buf+1; - if (isDead()) return; - *(ptr++) = (uint8) cmd; - if (vallen) - { - memcpy(ptr, val, vallen); - ptr += vallen; - } /* if */ - strcpy((char *) ptr, name); - ptr += strlen(name) + 1; - buf[0] = (uint8) ((ptr-1) - buf); - writePipe(GPipeWrite, buf, buf[0] + 1); +static void writeStatThing(const ShimCmd cmd, const char *name, const void *val, const size_t vallen) { + uint8 buf[256]; + uint8 *ptr = buf + 1; + if (isDead()) return; + *(ptr++) = (uint8) cmd; + if (vallen) { + memcpy(ptr, val, vallen); + ptr += vallen; + } /* if */ + strcpy((char *) ptr, name); + ptr += strlen(name) + 1; + buf[0] = (uint8) ((ptr - 1) - buf); + writePipe(GPipeWrite, buf, buf[0] + 1); } /* writeStatThing */ -void STEAMSHIM_setStatI(const char *name, const int _val) -{ - const int32 val = (int32) _val; - dbgpipe("Child sending SHIMCMD_SETSTATI('%s', val %d).\n", name, val); - writeStatThing(SHIMCMD_SETSTATI, name, &val, sizeof (val)); +void STEAMSHIM_setStatI(const char *name, const int _val) { + const int32 val = (int32) _val; + dbgpipe("Child sending SHIMCMD_SETSTATI('%s', val %d).\n", name, val); + writeStatThing(SHIMCMD_SETSTATI, name, &val, sizeof(val)); } /* STEAMSHIM_setStatI */ -void STEAMSHIM_getStatI(const char *name) -{ - dbgpipe("Child sending SHIMCMD_GETSTATI('%s').\n", name); - writeStatThing(SHIMCMD_GETSTATI, name, NULL, 0); +void STEAMSHIM_getStatI(const char *name) { + dbgpipe("Child sending SHIMCMD_GETSTATI('%s').\n", name); + writeStatThing(SHIMCMD_GETSTATI, name, NULL, 0); } /* STEAMSHIM_getStatI */ -void STEAMSHIM_setStatF(const char *name, const float val) -{ - dbgpipe("Child sending SHIMCMD_SETSTATF('%s', val %f).\n", name, val); - writeStatThing(SHIMCMD_SETSTATF, name, &val, sizeof (val)); +void STEAMSHIM_setStatF(const char *name, const float val) { + dbgpipe("Child sending SHIMCMD_SETSTATF('%s', val %f).\n", name, val); + writeStatThing(SHIMCMD_SETSTATF, name, &val, sizeof(val)); } /* STEAMSHIM_setStatF */ -void STEAMSHIM_getStatF(const char *name) -{ - dbgpipe("Child sending SHIMCMD_GETSTATF('%s').\n", name); - writeStatThing(SHIMCMD_GETSTATF, name, NULL, 0); +void STEAMSHIM_getStatF(const char *name) { + dbgpipe("Child sending SHIMCMD_GETSTATF('%s').\n", name); + writeStatThing(SHIMCMD_GETSTATF, name, NULL, 0); } /* STEAMSHIM_getStatF */ -void STEAMSHIM_getPersonaName() -{ - if (isDead()) return; - dbgpipe("Child sending SHIMCMD_GETPERSONANAME().\n"); - write1ByteCmd(SHIMCMD_GETPERSONANAME); +void STEAMSHIM_getPersonaName() { + if (isDead()) return; + dbgpipe("Child sending SHIMCMD_GETPERSONANAME().\n"); + write1ByteCmd(SHIMCMD_GETPERSONANAME); } /* STEAMSHIM_getPersonaName */ -void STEAMSHIM_getCurrentGameLanguage() -{ - if (isDead()) return; - dbgpipe("Child sending SHIMCMD_GETCURRENTGAMELANGUAGE().\n"); - write1ByteCmd(SHIMCMD_GETCURRENTGAMELANGUAGE); +void STEAMSHIM_getCurrentGameLanguage() { + if (isDead()) return; + dbgpipe("Child sending SHIMCMD_GETCURRENTGAMELANGUAGE().\n"); + write1ByteCmd(SHIMCMD_GETCURRENTGAMELANGUAGE); } /* STEAMSHIM_getCurrentGameLanguage */ /* end of steamshim_child.c ... */ diff --git a/source/glest_game/steamshim/steamshim_child.h b/source/glest_game/steamshim/steamshim_child.h index 0e3d3a9d3..233f81ab3 100644 --- a/source/glest_game/steamshim/steamshim_child.h +++ b/source/glest_game/steamshim/steamshim_child.h @@ -5,48 +5,46 @@ extern "C" { #endif -typedef enum STEAMSHIM_EventType -{ - SHIMEVENT_BYE, - SHIMEVENT_STATSRECEIVED, - SHIMEVENT_STATSSTORED, - SHIMEVENT_SETACHIEVEMENT, - SHIMEVENT_GETACHIEVEMENT, - SHIMEVENT_RESETSTATS, - SHIMEVENT_SETSTATI, - SHIMEVENT_GETSTATI, - SHIMEVENT_SETSTATF, - SHIMEVENT_GETSTATF, - SHIMEVENT_GETPERSONANAME, - SHIMEVENT_GETCURRENTGAMELANGUAGE, -} STEAMSHIM_EventType; + typedef enum STEAMSHIM_EventType { + SHIMEVENT_BYE, + SHIMEVENT_STATSRECEIVED, + SHIMEVENT_STATSSTORED, + SHIMEVENT_SETACHIEVEMENT, + SHIMEVENT_GETACHIEVEMENT, + SHIMEVENT_RESETSTATS, + SHIMEVENT_SETSTATI, + SHIMEVENT_GETSTATI, + SHIMEVENT_SETSTATF, + SHIMEVENT_GETSTATF, + SHIMEVENT_GETPERSONANAME, + SHIMEVENT_GETCURRENTGAMELANGUAGE, + } STEAMSHIM_EventType; -/* not all of these fields make sense in a given event. */ -typedef struct STEAMSHIM_Event -{ - STEAMSHIM_EventType type; - int okay; - int ivalue; - float fvalue; - unsigned long long epochsecs; - char name[256]; -} STEAMSHIM_Event; + /* not all of these fields make sense in a given event. */ + typedef struct STEAMSHIM_Event { + STEAMSHIM_EventType type; + int okay; + int ivalue; + float fvalue; + unsigned long long epochsecs; + char name[256]; + } STEAMSHIM_Event; -int STEAMSHIM_init(void); /* non-zero on success, zero on failure. */ -void STEAMSHIM_deinit(void); -int STEAMSHIM_alive(void); -const STEAMSHIM_Event *STEAMSHIM_pump(void); -void STEAMSHIM_requestStats(void); -void STEAMSHIM_storeStats(void); -void STEAMSHIM_setAchievement(const char *name, const int enable); -void STEAMSHIM_getAchievement(const char *name); -void STEAMSHIM_resetStats(const int bAlsoAchievements); -void STEAMSHIM_setStatI(const char *name, const int _val); -void STEAMSHIM_getStatI(const char *name); -void STEAMSHIM_setStatF(const char *name, const float val); -void STEAMSHIM_getStatF(const char *name); -void STEAMSHIM_getPersonaName(); -void STEAMSHIM_getCurrentGameLanguage(); + int STEAMSHIM_init(void); /* non-zero on success, zero on failure. */ + void STEAMSHIM_deinit(void); + int STEAMSHIM_alive(void); + const STEAMSHIM_Event *STEAMSHIM_pump(void); + void STEAMSHIM_requestStats(void); + void STEAMSHIM_storeStats(void); + void STEAMSHIM_setAchievement(const char *name, const int enable); + void STEAMSHIM_getAchievement(const char *name); + void STEAMSHIM_resetStats(const int bAlsoAchievements); + void STEAMSHIM_setStatI(const char *name, const int _val); + void STEAMSHIM_getStatI(const char *name); + void STEAMSHIM_setStatF(const char *name, const float val); + void STEAMSHIM_getStatF(const char *name); + void STEAMSHIM_getPersonaName(); + void STEAMSHIM_getCurrentGameLanguage(); #ifdef __cplusplus } diff --git a/source/glest_game/type_instances/command.cpp b/source/glest_game/type_instances/command.cpp index f0f92d175..6fb123b8e 100644 --- a/source/glest_game/type_instances/command.cpp +++ b/source/glest_game/type_instances/command.cpp @@ -21,281 +21,254 @@ using namespace Shared::Util; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class Command -// ===================================================== - Command::Command ():unitRef () - { - this->commandType = NULL; - unitType = NULL; - stateType = cst_None; - stateValue = -1; - unitCommandGroupId = -1; - } + // ===================================================== + // class Command + // ===================================================== + Command::Command() :unitRef() { + this->commandType = NULL; + unitType = NULL; + stateType = cst_None; + stateValue = -1; + unitCommandGroupId = -1; + } - Command::Command (const CommandType * ct, const Vec2i & pos):unitRef () - { - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ct = [%p]\n",__FILE__,__FUNCTION__,__LINE__,ct); + Command::Command(const CommandType * ct, const Vec2i & pos) :unitRef() { + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ct = [%p]\n",__FILE__,__FUNCTION__,__LINE__,ct); - this->commandType = ct; - this->pos = pos; - this->originalPos = this->pos; - unitType = NULL; - stateType = cst_None; - stateValue = -1; - unitCommandGroupId = -1; - } + this->commandType = ct; + this->pos = pos; + this->originalPos = this->pos; + unitType = NULL; + stateType = cst_None; + stateValue = -1; + unitCommandGroupId = -1; + } - Command::Command (const CommandType * ct, Unit * unit) - { - this->commandType = ct; - this->pos = Vec2i (0); - this->originalPos = this->pos; - this->unitRef = unit; - unitType = NULL; - if (unit != NULL) - { - //unit->resetHighlight(); is in gui now - pos = unit->getCellPos (); - } - stateType = cst_None; - stateValue = -1; - unitCommandGroupId = -1; - } + Command::Command(const CommandType * ct, Unit * unit) { + this->commandType = ct; + this->pos = Vec2i(0); + this->originalPos = this->pos; + this->unitRef = unit; + unitType = NULL; + if (unit != NULL) { + //unit->resetHighlight(); is in gui now + pos = unit->getCellPos(); + } + stateType = cst_None; + stateValue = -1; + unitCommandGroupId = -1; + } - Command::Command (const CommandType * ct, const Vec2i & pos, - const UnitType * unitType, - CardinalDir facing):unitRef () - { - this->commandType = ct; - this->pos = pos; - this->originalPos = this->pos; - this->unitType = unitType; - this->facing = facing; - stateType = cst_None; - stateValue = -1; - unitCommandGroupId = -1; + Command::Command(const CommandType * ct, const Vec2i & pos, + const UnitType * unitType, + CardinalDir facing) :unitRef() { + this->commandType = ct; + this->pos = pos; + this->originalPos = this->pos; + this->unitType = unitType; + this->facing = facing; + stateType = cst_None; + stateValue = -1; + unitCommandGroupId = -1; - //if(this->unitType != NULL) { - // SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unitType = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->unitType->toString().c_str()); - //} - } + //if(this->unitType != NULL) { + // SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unitType = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->unitType->toString().c_str()); + //} + } - int Command::getPriority () - { - if (this->commandType->commandTypeClass == ccAttack - && getUnit () == NULL) - { - return 5; // attacks to the ground have low priority - } - return this->commandType->getTypePriority (); - } -// =============== set =============== + int Command::getPriority() { + if (this->commandType->commandTypeClass == ccAttack + && getUnit() == NULL) { + return 5; // attacks to the ground have low priority + } + return this->commandType->getTypePriority(); + } + // =============== set =============== - void Command::setCommandType (const CommandType * commandType) - { - this->commandType = commandType; - } + void Command::setCommandType(const CommandType * commandType) { + this->commandType = commandType; + } - void Command::setPos (const Vec2i & pos) - { - this->pos = pos; - } + void Command::setPos(const Vec2i & pos) { + this->pos = pos; + } -//void Command::setOriginalPos(const Vec2i &pos) { -// this->originalPos= pos; -//} + //void Command::setOriginalPos(const Vec2i &pos) { + // this->originalPos= pos; + //} - void Command::setPosToOriginalPos () - { - this->pos = this->originalPos; - } + void Command::setPosToOriginalPos() { + this->pos = this->originalPos; + } - void Command::setUnit (Unit * unit) - { - this->unitRef = unit; - } + void Command::setUnit(Unit * unit) { + this->unitRef = unit; + } - std::string Command::toString (bool translatedValue) const - { - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__); + std::string Command::toString(bool translatedValue) const { + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__); - std::string result = ""; - if (commandType != NULL) - { - result = - "commandType id = " + intToStr (commandType->getId ()) + - ", desc = " + commandType->toString (translatedValue); - } - else - { - result = "commandType = NULL"; - } - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__); + std::string result = ""; + if (commandType != NULL) { + result = + "commandType id = " + intToStr(commandType->getId()) + + ", desc = " + commandType->toString(translatedValue); + } else { + result = "commandType = NULL"; + } + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__); - result += - ", pos = " + pos.getString () + ", originalPos = " + - originalPos.getString () + ", facing = " + intToStr (facing.asInt ()); + result += + ", pos = " + pos.getString() + ", originalPos = " + + originalPos.getString() + ", facing = " + intToStr(facing.asInt()); - //if(unitRef.getUnit() != NULL) { - if (unitRef.getUnitId () >= 0) - { - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__); + //if(unitRef.getUnit() != NULL) { + if (unitRef.getUnitId() >= 0) { + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__); - result += - ", unitRef.getUnit() id = " + intToStr (unitRef.getUnitId ()); + result += + ", unitRef.getUnit() id = " + intToStr(unitRef.getUnitId()); - // The code below causes a STACK OVERFLOW! - //if(unitRef.getUnit() != NULL) { - // result += ", unitRef.getUnit() = " + unitRef.getUnit()->toString(); - //} - } + // The code below causes a STACK OVERFLOW! + //if(unitRef.getUnit() != NULL) { + // result += ", unitRef.getUnit() = " + unitRef.getUnit()->toString(); + //} + } - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__); - if (unitType != NULL) - { - result += ", unitTypeId = " + intToStr (unitType->getId ()); - result += - ", unitTypeDesc = " + unitType->getReqDesc (translatedValue); - } + if (unitType != NULL) { + result += ", unitTypeId = " + intToStr(unitType->getId()); + result += + ", unitTypeDesc = " + unitType->getReqDesc(translatedValue); + } - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__, __LINE__); - result += - ", stateType = " + intToStr (stateType) + ", stateValue = " + - intToStr (stateValue); + result += + ", stateType = " + intToStr(stateType) + ", stateValue = " + + intToStr(stateValue); - result += ", unitCommandGroupId = " + intToStr (unitCommandGroupId); + result += ", unitCommandGroupId = " + intToStr(unitCommandGroupId); - return result; - } + return result; + } - Checksum Command::getCRC () - { - Checksum crcForCmd; + Checksum Command::getCRC() { + Checksum crcForCmd; - crcForCmd.addInt (commandType->getId ()); - crcForCmd.addInt (originalPos.x); - crcForCmd.addInt (originalPos.y); - crcForCmd.addInt (pos.x); - crcForCmd.addInt (pos.y); - crcForCmd.addInt (unitRef.getUnitId ()); - crcForCmd.addInt (facing); - if (unitType != NULL) - { - crcForCmd.addInt (unitType->getId ()); - } - crcForCmd.addInt (stateType); - crcForCmd.addInt (stateValue); - crcForCmd.addInt (unitCommandGroupId); + crcForCmd.addInt(commandType->getId()); + crcForCmd.addInt(originalPos.x); + crcForCmd.addInt(originalPos.y); + crcForCmd.addInt(pos.x); + crcForCmd.addInt(pos.y); + crcForCmd.addInt(unitRef.getUnitId()); + crcForCmd.addInt(facing); + if (unitType != NULL) { + crcForCmd.addInt(unitType->getId()); + } + crcForCmd.addInt(stateType); + crcForCmd.addInt(stateValue); + crcForCmd.addInt(unitCommandGroupId); - return crcForCmd; - } + return crcForCmd; + } - void Command::saveGame (XmlNode * rootNode, Faction * faction) - { - std::map < string, string > mapTagReplacements; - XmlNode *commandNode = rootNode->addChild ("Command"); + void Command::saveGame(XmlNode * rootNode, Faction * faction) { + std::map < string, string > mapTagReplacements; + XmlNode *commandNode = rootNode->addChild("Command"); -// const CommandType *commandType; - if (commandType != NULL) - { - commandNode->addAttribute ("commandType", - intToStr (commandType->getId ()), - mapTagReplacements); - } -// Vec2i originalPos; - commandNode->addAttribute ("originalPos", originalPos.getString (), - mapTagReplacements); -// Vec2i pos; - commandNode->addAttribute ("pos", pos.getString (), mapTagReplacements); -// UnitReference unitRef; //target unit, used to move and attack optionally - unitRef.saveGame (commandNode); -// CardinalDir facing; // facing, for build command - commandNode->addAttribute ("facing", intToStr (facing), - mapTagReplacements); -// const UnitType *unitType; //used for build - if (unitType != NULL) - { - commandNode->addAttribute ("unitTypeId", - intToStr (unitType->getId ()), - mapTagReplacements); - commandNode->addAttribute ("unitTypeFactionIndex", - intToStr (faction->getIndex ()), - mapTagReplacements); - } -// CommandStateType stateType; - commandNode->addAttribute ("stateType", intToStr (stateType), - mapTagReplacements); -// int stateValue; - commandNode->addAttribute ("stateValue", intToStr (stateValue), - mapTagReplacements); -// int unitCommandGroupId; - commandNode->addAttribute ("unitCommandGroupId", - intToStr (unitCommandGroupId), - mapTagReplacements); - } + // const CommandType *commandType; + if (commandType != NULL) { + commandNode->addAttribute("commandType", + intToStr(commandType->getId()), + mapTagReplacements); + } + // Vec2i originalPos; + commandNode->addAttribute("originalPos", originalPos.getString(), + mapTagReplacements); + // Vec2i pos; + commandNode->addAttribute("pos", pos.getString(), mapTagReplacements); + // UnitReference unitRef; //target unit, used to move and attack optionally + unitRef.saveGame(commandNode); + // CardinalDir facing; // facing, for build command + commandNode->addAttribute("facing", intToStr(facing), + mapTagReplacements); + // const UnitType *unitType; //used for build + if (unitType != NULL) { + commandNode->addAttribute("unitTypeId", + intToStr(unitType->getId()), + mapTagReplacements); + commandNode->addAttribute("unitTypeFactionIndex", + intToStr(faction->getIndex()), + mapTagReplacements); + } + // CommandStateType stateType; + commandNode->addAttribute("stateType", intToStr(stateType), + mapTagReplacements); + // int stateValue; + commandNode->addAttribute("stateValue", intToStr(stateValue), + mapTagReplacements); + // int unitCommandGroupId; + commandNode->addAttribute("unitCommandGroupId", + intToStr(unitCommandGroupId), + mapTagReplacements); + } - Command *Command::loadGame (const XmlNode * rootNode, const UnitType * ut, - World * world) - { - Command *result = new Command (); - const XmlNode *commandNode = rootNode; + Command *Command::loadGame(const XmlNode * rootNode, const UnitType * ut, + World * world) { + Command *result = new Command(); + const XmlNode *commandNode = rootNode; - //description = commandNode->getAttribute("description")->getValue(); + //description = commandNode->getAttribute("description")->getValue(); - // const CommandType *commandType; - if (commandNode->hasAttribute ("commandType") == true) - { - int cmdTypeId = - commandNode->getAttribute ("commandType")->getIntValue (); - result->commandType = ut->findCommandTypeById (cmdTypeId); - } - // Vec2i originalPos; - result->originalPos = - Vec2i::strToVec2 (commandNode->getAttribute ("originalPos")-> - getValue ()); - // Vec2i pos; - result->pos = - Vec2i::strToVec2 (commandNode->getAttribute ("pos")->getValue ()); - // UnitReference unitRef; //target unit, used to move and attack optionally - result->unitRef.loadGame (commandNode, world); - // CardinalDir facing; // facing, for build command - result->facing = - static_cast < CardinalDir > - (commandNode->getAttribute ("facing")->getIntValue ()); - // const UnitType *unitType; //used for build - if (commandNode->hasAttribute ("unitTypeId") == true) - { - //result->unitType = ut; - int unitTypeId = - commandNode->getAttribute ("unitTypeId")->getIntValue (); - int unitTypeFactionIndex = - commandNode->getAttribute ("unitTypeFactionIndex")->getIntValue (); - Faction *faction = world->getFaction (unitTypeFactionIndex); - result->unitType = - world->findUnitTypeById (faction->getType (), unitTypeId); - } - // CommandStateType stateType; - result->stateType = - static_cast < CommandStateType > - (commandNode->getAttribute ("stateType")->getIntValue ()); - // int stateValue; - result->stateValue = - commandNode->getAttribute ("stateValue")->getIntValue (); - // int unitCommandGroupId; - result->unitCommandGroupId = - commandNode->getAttribute ("unitCommandGroupId")->getIntValue (); + // const CommandType *commandType; + if (commandNode->hasAttribute("commandType") == true) { + int cmdTypeId = + commandNode->getAttribute("commandType")->getIntValue(); + result->commandType = ut->findCommandTypeById(cmdTypeId); + } + // Vec2i originalPos; + result->originalPos = + Vec2i::strToVec2(commandNode->getAttribute("originalPos")-> + getValue()); + // Vec2i pos; + result->pos = + Vec2i::strToVec2(commandNode->getAttribute("pos")->getValue()); + // UnitReference unitRef; //target unit, used to move and attack optionally + result->unitRef.loadGame(commandNode, world); + // CardinalDir facing; // facing, for build command + result->facing = + static_cast + (commandNode->getAttribute("facing")->getIntValue()); + // const UnitType *unitType; //used for build + if (commandNode->hasAttribute("unitTypeId") == true) { + //result->unitType = ut; + int unitTypeId = + commandNode->getAttribute("unitTypeId")->getIntValue(); + int unitTypeFactionIndex = + commandNode->getAttribute("unitTypeFactionIndex")->getIntValue(); + Faction *faction = world->getFaction(unitTypeFactionIndex); + result->unitType = + world->findUnitTypeById(faction->getType(), unitTypeId); + } + // CommandStateType stateType; + result->stateType = + static_cast + (commandNode->getAttribute("stateType")->getIntValue()); + // int stateValue; + result->stateValue = + commandNode->getAttribute("stateValue")->getIntValue(); + // int unitCommandGroupId; + result->unitCommandGroupId = + commandNode->getAttribute("unitCommandGroupId")->getIntValue(); - return result; - } + return result; + } - } + } } //end namespace diff --git a/source/glest_game/type_instances/command.h b/source/glest_game/type_instances/command.h index c67f45b6c..bafa491a0 100644 --- a/source/glest_game/type_instances/command.h +++ b/source/glest_game/type_instances/command.h @@ -23,127 +23,111 @@ # include "game_constants.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - using Shared::Graphics::Vec2i; + using Shared::Graphics::Vec2i; - class CommandType; + class CommandType; - enum CommandStateType - { - cst_None, - cst_linkedUnit, - cst_EmergencyReturnResource - }; + enum CommandStateType { + cst_None, + cst_linkedUnit, + cst_EmergencyReturnResource + }; -// ===================================================== -// class Command -// -/// A unit command -// ===================================================== + // ===================================================== + // class Command + // + /// A unit command + // ===================================================== - class Command - { - private: - const CommandType *commandType; - Vec2i originalPos; - Vec2i pos; - UnitReference unitRef; //target unit, used to move and attack optionally - CardinalDir facing; // facing, for build command - const UnitType *unitType; //used for build + class Command { + private: + const CommandType *commandType; + Vec2i originalPos; + Vec2i pos; + UnitReference unitRef; //target unit, used to move and attack optionally + CardinalDir facing; // facing, for build command + const UnitType *unitType; //used for build - CommandStateType stateType; - int stateValue; + CommandStateType stateType; + int stateValue; - int unitCommandGroupId; + int unitCommandGroupId; - Command (); - public: - //constructor - Command (const CommandType * ct, const Vec2i & pos = Vec2i (0)); - Command (const CommandType * ct, Unit * unit); - Command (const CommandType * ct, const Vec2i & pos, - const UnitType * unitType, CardinalDir facing); + Command(); + public: + //constructor + Command(const CommandType * ct, const Vec2i & pos = Vec2i(0)); + Command(const CommandType * ct, Unit * unit); + Command(const CommandType * ct, const Vec2i & pos, + const UnitType * unitType, CardinalDir facing); - virtual ~ Command () - { - } - //get - inline const CommandType *getCommandType () const - { - return commandType; - } - inline Vec2i getPos () const - { - return pos; - } - inline Vec2i getOriginalPos () const - { - return originalPos; - } - inline Unit *getUnit () const - { - return unitRef.getUnit (); - } - inline const UnitType *getUnitType () const - { - return unitType; - } - inline CardinalDir getFacing () const - { - return facing; - } + virtual ~Command() { + } + //get + inline const CommandType *getCommandType() const { + return commandType; + } + inline Vec2i getPos() const { + return pos; + } + inline Vec2i getOriginalPos() const { + return originalPos; + } + inline Unit *getUnit() const { + return unitRef.getUnit(); + } + inline const UnitType *getUnitType() const { + return unitType; + } + inline CardinalDir getFacing() const { + return facing; + } - //Priority: commands of higher priority will cancel commands of lower priority - virtual int getPriority (); + //Priority: commands of higher priority will cancel commands of lower priority + virtual int getPriority(); - //set - void setCommandType (const CommandType * commandType); - void setPos (const Vec2i & pos); - //void setOriginalPos(const Vec2i &pos); - void setPosToOriginalPos (); + //set + void setCommandType(const CommandType * commandType); + void setPos(const Vec2i & pos); + //void setOriginalPos(const Vec2i &pos); + void setPosToOriginalPos(); - void setUnit (Unit * unit); + void setUnit(Unit * unit); - inline void setStateType (CommandStateType value) - { - stateType = value; - } - inline CommandStateType getStateType () const - { - return stateType; - } + inline void setStateType(CommandStateType value) { + stateType = value; + } + inline CommandStateType getStateType() const { + return stateType; + } - inline void setStateValue (int value) - { - stateValue = value; - } - inline int getStateValue () const - { - return stateValue; - } + inline void setStateValue(int value) { + stateValue = value; + } + inline int getStateValue() const { + return stateValue; + } - inline void setUnitCommandGroupId (int value) - { - unitCommandGroupId = value; - } - inline int getUnitCommandGroupId () const - { - return unitCommandGroupId; - } + inline void setUnitCommandGroupId(int value) { + unitCommandGroupId = value; + } + inline int getUnitCommandGroupId() const { + return unitCommandGroupId; + } - std::string toString (bool translatedValue) const; + std::string toString(bool translatedValue) const; - void saveGame (XmlNode * rootNode, Faction * faction); - static Command *loadGame (const XmlNode * rootNode, const UnitType * ut, - World * world); + void saveGame(XmlNode * rootNode, Faction * faction); + static Command *loadGame(const XmlNode * rootNode, const UnitType * ut, + World * world); - Checksum getCRC (); - }; + Checksum getCRC(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/type_instances/faction.cpp b/source/glest_game/type_instances/faction.cpp index 94bf01c23..e12c60045 100644 --- a/source/glest_game/type_instances/faction.cpp +++ b/source/glest_game/type_instances/faction.cpp @@ -28,3492 +28,3004 @@ using namespace Shared::Util; using Shared::Util::RandomGen; -namespace Glest -{ - namespace Game - { - - bool CommandGroupUnitSorterId::operator () (const int l, const int r) - { - const Unit *lUnit = faction->findUnit (l); - const Unit *rUnit = faction->findUnit (r); - - if (!lUnit) - { - printf ("Error lUnit == NULL for id = %d factionIndex = %d\n", l, - faction->getIndex ()); - - for (unsigned int i = 0; i < (unsigned int) faction->getUnitCount (); - ++i) - { - printf ("%u / %d id = %d [%s]\n", i, faction->getUnitCount (), - faction->getUnit (i)->getId (), - faction->getUnit (i)->getType ()->getName (false).c_str ()); - } - } - if (!rUnit) - { - printf ("Error rUnit == NULL for id = %d factionIndex = %d\n", r, - faction->getIndex ()); - - for (unsigned int i = 0; i < (unsigned int) faction->getUnitCount (); - ++i) - { - printf ("%u / %d id = %d [%s]\n", i, faction->getUnitCount (), - faction->getUnit (i)->getId (), - faction->getUnit (i)->getType ()->getName (false).c_str ()); - } - } - - CommandGroupUnitSorter sorter; - return sorter.compare (lUnit, rUnit); - } - - bool CommandGroupUnitSorter::operator () (const Unit * l, const Unit * r) - { - return compare (l, r); - } - - bool CommandGroupUnitSorter::compare (const Unit * l, const Unit * r) - { - //printf("l [%p] r [%p] <>",l,r); - - if (!l) - { - printf ("Error l == NULL\n"); - } - if (!r) - { - printf ("Error r == NULL\n"); - } - - assert (l && r); - - if (l == NULL || r == NULL) - printf ("Unit l [%s - %d] r [%s - %d]\n", - (l != - NULL ? l->getType ()->getName (false).c_str () : "null"), - (l != NULL ? l->getId () : -1), - (r != - NULL ? r->getType ()->getName (false).c_str () : "null"), - (r != NULL ? r->getId () : -1)); - - - bool result = false; - // If comparer is null or dead - if (r == NULL || r->isAlive () == false) - { - // if source is null or dead also - if ((l == NULL || l->isAlive () == false)) - { - return false; - } - return true; - } - else if ((l == NULL || l->isAlive () == false)) - { - return false; - } - -// const Command *command= l->getCurrrentCommandThreadSafe(); -// const Command *commandPeer = r->getCurrrentCommandThreadSafe(); - const Command *command = l->getCurrCommand (); - const Command *commandPeer = r->getCurrCommand (); - - //Command *command= this->unit->getCurrCommand(); - - // Are we moving or attacking - if (command != NULL && command->getCommandType () != NULL && - (command->getCommandType ()->getClass () == ccMove || - command->getCommandType ()->getClass () == ccAttack) && - command->getUnitCommandGroupId () > 0) - { - int curCommandGroupId = command->getUnitCommandGroupId (); - - //Command *commandPeer = j.unit->getCurrrentCommandThreadSafe(); - //Command *commandPeer = j.unit->getCurrCommand(); - - // is comparer a valid command - if (commandPeer == NULL || commandPeer->getCommandType () == NULL) - { - result = true; - } - // is comparer command the same type? - else if (commandPeer->getCommandType ()->getClass () != - command->getCommandType ()->getClass ()) - { - result = true; - } - // is comparer command groupid invalid? - else if (commandPeer->getUnitCommandGroupId () < 0) - { - result = true; - } - // If comparer command group id is less than current group id - else if (curCommandGroupId != commandPeer->getUnitCommandGroupId ()) - { - result = curCommandGroupId < commandPeer->getUnitCommandGroupId (); - } - else - { - float unitDist = l->getCenteredPos ().dist (command->getPos ()); - float unitDistPeer = - r->getCenteredPos ().dist (commandPeer->getPos ()); - - // Closest unit in commandgroup - result = (unitDist < unitDistPeer); - } - } - else if (command == NULL && commandPeer != NULL) - { - result = false; - } -// else if(command == NULL && j.unit->getCurrrentCommandThreadSafe() == NULL) { -// return this->unit->getId() < j.unit->getId(); -// } - else - { - //Command *commandPeer = j.unit->getCurrrentCommandThreadSafe(); - //if( commandPeer != NULL && commandPeer->getCommandType() != NULL && - // (commandPeer->getCommandType()->getClass() != ccMove && - // commandPeer->getCommandType()->getClass() != ccAttack)) { - result = (l->getId () < r->getId ()); - //} - //else { - // result = (l->getId() < r->getId()); - //} - } - - //printf("Sorting, unit [%d - %s] cmd [%s] | unit2 [%d - %s] cmd [%s] result = %d\n",this->unit->getId(),this->unit->getFullName().c_str(),(this->unit->getCurrCommand() == NULL ? "NULL" : this->unit->getCurrCommand()->toString().c_str()),j.unit->getId(),j.unit->getFullName().c_str(),(j.unit->getCurrCommand() == NULL ? "NULL" : j.unit->getCurrCommand()->toString().c_str()),result); - - return result; - } - - void Faction::sortUnitsByCommandGroups () - { - MutexSafeWrapper safeMutex (unitsMutex, - string (__FILE__) + "_" + - intToStr (__LINE__)); - //printf("====== sortUnitsByCommandGroups for faction # %d [%s] unitCount = %d\n",this->getIndex(),this->getType()->getName().c_str(),units.size()); - //for(unsigned int i = 0; i < units.size(); ++i) { - // printf("%d / %d [%p] <>",i,units.size(),&units[i]); -// // printf("i = %d [%p]\n",i,&units[i]); -// if(Unit::isUnitDeleted(units[i]) == true) { -// printf("i = %d [%p]\n",i,&units[i]); -// throw megaglest_runtime_error("unit already deleted!"); -// } - //} - //printf("\nSorting\n"); - - //std::sort(units.begin(),units.end(),CommandGroupUnitSorter()); - - //printf("====== Done sorting for faction # %d [%s] unitCount = %d\n",this->getIndex(),this->getType()->getName().c_str(),units.size()); - - //unsigned int originalUnitSize = (unsigned int)units.size(); - - std::vector < int >unitIds; - for (unsigned int i = 0; i < units.size (); ++i) - { - int unitId = units[i]->getId (); - if (this->findUnit (unitId) == NULL) - { - printf - ("#1 Error unitId not found for id = %d [%s] factionIndex = %d\n", - unitId, units[i]->getType ()->getName (false).c_str (), - this->getIndex ()); - - for (unsigned int j = 0; j < units.size (); ++j) - { - printf ("%u / %d id = %d [%s]\n", j, (int) units.size (), - units[j]->getId (), - units[j]->getType ()->getName (false).c_str ()); - } - } - unitIds.push_back (unitId); - } - CommandGroupUnitSorterId sorter; - sorter.faction = this; - std::stable_sort (unitIds.begin (), unitIds.end (), sorter); - - units.clear (); - for (unsigned int i = 0; i < unitIds.size (); ++i) - { - - int unitId = unitIds[i]; - if (this->findUnit (unitId) == NULL) - { - printf ("#2 Error unitId not found for id = %d factionIndex = %d\n", - unitId, this->getIndex ()); - - for (unsigned int j = 0; j < units.size (); ++j) - { - printf ("%u / %d id = %d [%s]\n", j, (int) units.size (), - units[j]->getId (), - units[j]->getType ()->getName (false).c_str ()); - } - } - - units.push_back (this->findUnit (unitId)); - } - - //assert(originalUnitSize == units.size()); - } - -// ===================================================== -// class FactionThread -// ===================================================== - - FactionThread::FactionThread (Faction * faction):BaseThread () - { - this->triggerIdMutex = new Mutex (CODE_AT_LINE); - this->faction = faction; - this->masterController = NULL; - uniqueID = "FactionThread"; - } - - FactionThread::~FactionThread () - { - this->faction = NULL; - this->masterController = NULL; - delete this->triggerIdMutex; - this->triggerIdMutex = NULL; - } - - void FactionThread::setQuitStatus (bool value) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d value = %d\n", - __FILE__, __FUNCTION__, __LINE__, value); - - BaseThread::setQuitStatus (value); - if (value == true) - { - signalPathfinder (-1); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", __FILE__, - __FUNCTION__, __LINE__); - } - - void FactionThread::signalPathfinder (int frameIndex) - { - if (frameIndex >= 0) - { - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (triggerIdMutex, mutexOwnerId); - this->frameIndex.first = frameIndex; - this->frameIndex.second = false; - - safeMutex.ReleaseLock (); - } - semTaskSignalled.signal (); - } - - void FactionThread::setTaskCompleted (int frameIndex) - { - if (frameIndex >= 0) - { - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (triggerIdMutex, mutexOwnerId); - if (this->frameIndex.first == frameIndex) - { - this->frameIndex.second = true; - } - safeMutex.ReleaseLock (); - } - } - - bool FactionThread::canShutdown (bool deleteSelfIfShutdownDelayed) - { - bool ret = (getExecutingTask () == false); - if (ret == false && deleteSelfIfShutdownDelayed == true) - { - setDeleteSelfOnExecutionDone (deleteSelfIfShutdownDelayed); - deleteSelfIfRequired (); - signalQuit (); - } - - return ret; - } - - bool FactionThread::isSignalPathfinderCompleted (int frameIndex) - { - if (getRunningStatus () == false) - { - return true; - } - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (triggerIdMutex, mutexOwnerId); - //bool result = (event != NULL ? event->eventCompleted : true); - bool result = (this->frameIndex.first == frameIndex - && this->frameIndex.second == true); - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] worker thread this = %p, this->frameIndex.first = %d, this->frameIndex.second = %d\n",__FILE__,__FUNCTION__,__LINE__,this,this->frameIndex.first,this->frameIndex.second); - - safeMutex.ReleaseLock (); - return result; - } - - void FactionThread::execute () - { - string codeLocation = "1"; - RunningStatusSafeWrapper runningStatus (this); - try - { - //setRunningStatus(true); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line: %d] ****************** STARTING worker thread this = %p\n", - __FILE__, __FUNCTION__, __LINE__, this); - - bool minorDebugPerformance = false; - Chrono chrono; - - codeLocation = "2"; - //unsigned int idx = 0; - for (; this->faction != NULL;) - { - if (getQuitStatus () == true) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - break; - } - - semTaskSignalled.waitTillSignalled (); - - codeLocation = "3"; - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - static string masterSlaveOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MasterSlaveThreadControllerSafeWrapper - safeMasterController (masterController, 20000, - masterSlaveOwnerId); - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if (getQuitStatus () == true) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - break; - } - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (triggerIdMutex, mutexOwnerId); - bool executeTask = (this->frameIndex.first >= 0); - int currentTriggeredFrameIndex = this->frameIndex.first; - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] frameIndex = %d this = %p executeTask = %d\n",__FILE__,__FUNCTION__,__LINE__,frameIndex.first, this, executeTask); - - safeMutex.ReleaseLock (); - - codeLocation = "5"; - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if (executeTask == true) - { - codeLocation = "6"; - ExecutingTaskSafeWrapper safeExecutingTaskMutex (this); - - if (this->faction == NULL) - { - throw megaglest_runtime_error ("this->faction == NULL"); - } - World *world = this->faction->getWorld (); - if (world == NULL) - { - throw megaglest_runtime_error ("world == NULL"); - } - - codeLocation = "7"; - //Config &config= Config::getInstance(); - //bool sortedUnitsAllowed = config.getBool("AllowGroupedUnitCommands","true"); - //bool sortedUnitsAllowed = false; - //if(sortedUnitsAllowed == true) { - - /// TODO: Why does this cause and OOS? - //this->faction->sortUnitsByCommandGroups (); - - //} - - codeLocation = "8"; - static string mutexOwnerId2 = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (faction->getUnitMutex (), - mutexOwnerId2); - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - if (minorDebugPerformance) - chrono.start (); - - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - codeLocation = "9"; - int unitCount = this->faction->getUnitCount (); - for (int j = 0; j < unitCount; ++j) - { - codeLocation = "10"; - Unit *unit = this->faction->getUnit (j); - if (unit == NULL) - { - throw megaglest_runtime_error ("unit == NULL"); - } - - codeLocation = "11"; - int64 elapsed1 = 0; - if (minorDebugPerformance) - elapsed1 = chrono.getMillis (); - - bool update = unit->needToUpdate (); - - codeLocation = "12"; - if (minorDebugPerformance - && (chrono.getMillis () - elapsed1) >= 1) - printf - ("Faction [%d - %s] #1-unit threaded updates on frame: %d for [%d] unit # %d, unitCount = %d, took [%lld] msecs\n", - faction->getStartLocationIndex (), - faction->getType ()->getName (false).c_str (), - currentTriggeredFrameIndex, - faction->getUnitPathfindingListCount (), j, unitCount, - (long long int) chrono.getMillis () - elapsed1); - - //update = true; - if (update == true) - { - codeLocation = "13"; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true) - { - int64 updateProgressValue = unit->getUpdateProgress (); - int64 speed = - unit->getCurrSkill ()->getTotalSpeed (unit-> - getTotalUpgrade ()); - int64 df = unit->getDiagonalFactor (); - int64 hf = unit->getHeightFactor (); - bool changedActiveCommand = unit->isChangedActiveCommand (); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "unit->needToUpdate() returned: %d updateProgressValue: %lld speed: %lld changedActiveCommand: %d df: %lld hf: %lld", - update, (long long int) updateProgressValue, - (long long int) speed, changedActiveCommand, - (long long int) df, (long long int) hf); - unit->logSynchDataThreaded (__FILE__, __LINE__, szBuf); - } - - int64 elapsed2 = 0; - if (minorDebugPerformance) - elapsed2 = chrono.getMillis (); - - if (world->getUnitUpdater () == NULL) - { - throw - megaglest_runtime_error - ("world->getUnitUpdater() == NULL"); - } - - world->getUnitUpdater ()->updateUnitCommand (unit, - currentTriggeredFrameIndex); - - codeLocation = "15"; - if (minorDebugPerformance - && (chrono.getMillis () - elapsed2) >= 1) - printf - ("Faction [%d - %s] #2-unit threaded updates on frame: %d for [%d] unit # %d, unitCount = %d, took [%lld] msecs\n", - faction->getStartLocationIndex (), - faction->getType ()->getName (false).c_str (), - currentTriggeredFrameIndex, - faction->getUnitPathfindingListCount (), j, unitCount, - (long long int) chrono.getMillis () - elapsed2); - } - else - { - codeLocation = "16"; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true) - { - int64 updateProgressValue = unit->getUpdateProgress (); - int64 speed = - unit->getCurrSkill ()->getTotalSpeed (unit-> - getTotalUpgrade ()); - int64 df = unit->getDiagonalFactor (); - int64 hf = unit->getHeightFactor (); - bool changedActiveCommand = unit->isChangedActiveCommand (); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "unit->needToUpdate() returned: %d updateProgressValue: %lld speed: %lld changedActiveCommand: %d df: %lld hf: %lld", - update, (long long int) updateProgressValue, - (long long int) speed, changedActiveCommand, - (long long int) df, (long long int) hf); - unit->logSynchDataThreaded (__FILE__, __LINE__, szBuf); - } - } - } - - codeLocation = "17"; - if (minorDebugPerformance && chrono.getMillis () >= 1) - printf - ("Faction [%d - %s] threaded updates on frame: %d for [%d] units took [%lld] msecs\n", - faction->getStartLocationIndex (), - faction->getType ()->getName (false).c_str (), - currentTriggeredFrameIndex, - faction->getUnitPathfindingListCount (), - (long long int) chrono.getMillis ()); - - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - safeMutex.ReleaseLock (); - - codeLocation = "18"; - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - setTaskCompleted (currentTriggeredFrameIndex); - - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - codeLocation = "19"; - if (getQuitStatus () == true) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - break; - } - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("In [%s::%s Line: %d] ****************** ENDING worker thread this = %p\n", - __FILE__, __FUNCTION__, __LINE__, this); - } - catch (const exception & ex) - { - //setRunningStatus(false); - - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Loc [%s] Error [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - codeLocation.c_str (), ex.what ()); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - throw megaglest_runtime_error (ex.what ()); - } - catch ( ...) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "In [%s::%s %d] UNKNOWN error Loc [%s]\n", - __FILE__, __FUNCTION__, __LINE__, codeLocation.c_str ()); - SystemFlags::OutputDebug (SystemFlags::debugError, szBuf); - throw megaglest_runtime_error (szBuf); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s] Line: %d\n", __FILE__, - __FUNCTION__, __LINE__); - } - - -// ===================================================== -// class Faction -// ===================================================== - - Faction::Faction () - { - init (); - } - - void Faction::init () - { - unitsMutex = new Mutex (CODE_AT_LINE); - texture = NULL; - //lastResourceTargettListPurge = 0; - cachingDisabled = false; - factionDisconnectHandled = false; - workerThread = NULL; - - world = NULL; - scriptManager = NULL; - factionType = NULL; - index = 0; - teamIndex = 0; - startLocationIndex = 0; - thisFaction = false; - currentSwitchTeamVoteFactionIndex = -1; - allowSharedTeamUnits = false; - - loadWorldNode = NULL; - techTree = NULL; - - control = ctClosed; - - overridePersonalityType = fpt_EndCount; - - upgradeManager = UpgradeManager (); - } - - Faction::~Faction () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - //Renderer &renderer= Renderer::getInstance(); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - //renderer.endTexture(rsGame,texture); - //texture->end(); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - if (workerThread != NULL) - { - workerThread->signalQuit (); - if (workerThread->shutdownAndWait () == true) - { - delete workerThread; - } - workerThread = NULL; - } - - MutexSafeWrapper safeMutex (unitsMutex, - string (__FILE__) + "_" + - intToStr (__LINE__)); - deleteValues (units.begin (), units.end ()); - units.clear (); - - safeMutex.ReleaseLock (); - - //delete texture; - texture = NULL; - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - delete unitsMutex; - unitsMutex = NULL; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - void Faction::end () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - if (workerThread != NULL) - { - workerThread->signalQuit (); - if (workerThread->shutdownAndWait () == true) - { - delete workerThread; - } - workerThread = NULL; - } - - MutexSafeWrapper safeMutex (unitsMutex, - string (__FILE__) + "_" + - intToStr (__LINE__)); - deleteValues (units.begin (), units.end ()); - units.clear (); - - safeMutex.ReleaseLock (); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - void Faction::notifyUnitAliveStatusChange (const Unit * unit) - { - if (unit != NULL) - { - if (unit->isAlive () == true) - { - aliveUnitListCache[unit->getId ()] = unit; - - if (unit->getType ()->isMobile () == true) - { - mobileUnitListCache[unit->getId ()] = unit; - } - } - else - { - aliveUnitListCache.erase (unit->getId ()); - mobileUnitListCache.erase (unit->getId ()); - beingBuiltUnitListCache.erase (unit->getId ()); - } - } - } - - void Faction::notifyUnitTypeChange (const Unit * unit, - const UnitType * newType) - { - if (unit != NULL) - { - if (unit->getType ()->isMobile () == true) - { - mobileUnitListCache.erase (unit->getId ()); - } - - if (newType != NULL && newType->isMobile () == true) - { - mobileUnitListCache[unit->getId ()] = unit; - } - } - } - - void Faction::notifyUnitSkillTypeChange (const Unit * unit, - const SkillType * newType) - { - if (unit != NULL) - { - if (unit->isBeingBuilt () == true) - { - beingBuiltUnitListCache.erase (unit->getId ()); - } - if (newType != NULL && newType->getClass () == scBeBuilt) - { - beingBuiltUnitListCache[unit->getId ()] = unit; - } - } - } - - bool Faction::hasAliveUnits (bool filterMobileUnits, - bool filterBuiltUnits) const - { - bool result = false; - if (aliveUnitListCache.empty () == false) - { - if (filterMobileUnits == true) - { - result = (mobileUnitListCache.empty () == false); - } - else - { - result = true; - } - - if (result == true && filterBuiltUnits == true) - { - result = (beingBuiltUnitListCache.empty () == true); - } - } - return result; - } - - FactionPersonalityType Faction::getPersonalityType () const - { - if (overridePersonalityType != fpt_EndCount) - { - return overridePersonalityType; - } - return factionType->getPersonalityType (); - } - - int Faction:: - getAIBehaviorStaticOverideValue (AIBehaviorStaticValueCategory type) - const - { - return factionType->getAIBehaviorStaticOverideValue (type); - } - - void Faction::addUnitToMovingList (int unitId) - { - unitsMovingList[unitId] = getWorld ()->getFrameCount (); - } - void Faction::removeUnitFromMovingList (int unitId) - { - unitsMovingList.erase (unitId); - } - -//int Faction::getUnitMovingListCount() { -// return (int)unitsMovingList.size(); -//} - - void Faction::addUnitToPathfindingList (int unitId) - { - //printf("ADD (1) Faction [%d - %s] threaded updates for [%d] units\n",this->getStartLocationIndex(),this->getType()->getName().c_str(),unitsPathfindingList.size()); - unitsPathfindingList[unitId] = getWorld ()->getFrameCount (); - //printf("ADD (2) Faction [%d - %s] threaded updates for [%d] units\n",this->getStartLocationIndex(),this->getType()->getName().c_str(),unitsPathfindingList.size()); - } -//void Faction::removeUnitFromPathfindingList(int unitId) { -// unitsPathfindingList.erase(unitId); -//} - - int Faction::getUnitPathfindingListCount () - { - //printf("GET Faction [%d - %s] threaded updates for [%d] units\n",this->getStartLocationIndex(),this->getType()->getName().c_str(),unitsPathfindingList.size()); - return (int) unitsPathfindingList.size (); - } - - void Faction::clearUnitsPathfinding () - { - //printf("CLEAR Faction [%d - %s] threaded updates for [%d] units\n",this->getStartLocationIndex(),this->getType()->getName().c_str(),unitsPathfindingList.size()); - if (unitsPathfindingList.empty () == false) - { - unitsPathfindingList.clear (); - } - } - - bool Faction::canUnitsPathfind () - { - bool result = true; - if (control == ctCpuEasy || control == ctCpu || - control == ctCpuUltra || control == ctCpuZeta) - { - //printf("AI player for faction index: %d (%s) current pathfinding: %d\n",index,factionType->getName().c_str(),getUnitPathfindingListCount()); - - const int MAX_UNITS_PATHFINDING_PER_FRAME = 10; - result = - (getUnitPathfindingListCount () <= MAX_UNITS_PATHFINDING_PER_FRAME); - if (result == false) - { - //printf("WARNING limited AI player for faction index: %d (%s) current pathfinding: %d\n",index,factionType->getName().c_str(),getUnitPathfindingListCount()); - } - } - return result; - } - - void Faction::setLockedUnitForFaction (const UnitType * ut, bool lock) - { - if (lock) - { - lockedUnits.insert (ut); - } - else - { - std::set < const UnitType *>::iterator it; - it = lockedUnits.find (ut); - if (it != lockedUnits.end ()) - { - lockedUnits.erase (it); - } - } - - } - - void Faction::signalWorkerThread (int frameIndex) - { - if (workerThread != NULL) - { - workerThread->signalPathfinder (frameIndex); - } - } - - bool Faction::isWorkerThreadSignalCompleted (int frameIndex) - { - if (workerThread != NULL) - { - return workerThread->isSignalPathfinderCompleted (frameIndex); - } - return true; - } - - - void Faction::init (FactionType * factionType, ControlType control, - TechTree * techTree, Game * game, int factionIndex, - int teamIndex, int startLocationIndex, - bool thisFaction, bool giveResources, - const XmlNode * loadWorldNode) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - this->techTree = techTree; - this->loadWorldNode = loadWorldNode; - this->control = control; - this->factionType = factionType; - this->startLocationIndex = startLocationIndex; - this->index = factionIndex; - this->teamIndex = teamIndex; - this->thisFaction = thisFaction; - this->world = game->getWorld (); - this->scriptManager = game->getScriptManager (); - //cachingDisabled = (Config::getInstance().getBool("DisableCaching","false") == true); - cachingDisabled = false; - - resources.resize (techTree->getResourceTypeCount ()); - store.resize (techTree->getResourceTypeCount ()); - - if (loadWorldNode == NULL) - { - for (int index = 0; index < techTree->getResourceTypeCount (); - ++index) - { - const ResourceType *rt = techTree->getResourceType (index); - int resourceAmount = - giveResources ? factionType->getStartingResourceAmount (rt) : 0; - resources[index].init (rt, resourceAmount); - store[index].init (rt, 0); - - this->world->initTeamResource (rt, this->teamIndex, 0); - } - } - //initialize cache - for (int index = 0; index < techTree->getResourceTypeCount (); ++index) - { - const ResourceType *rt = techTree->getResourceType (index); - this->updateUnitTypeWithResourceCostCache (rt); - } - - texture = Renderer::getInstance ().newTexture2D (rsGame); - string data_path = - getGameReadWritePath (GameConstants::path_data_CacheLookupKey); - if (texture) - { - string playerTexture = - getGameCustomCoreDataPath (data_path, - "data/core/faction_textures/faction" + - intToStr (startLocationIndex) + ".tga"); - texture->load (playerTexture); - } - - if (loadWorldNode != NULL) - { - loadGame (loadWorldNode, this->index, game->getGameSettings (), - game->getWorld ()); - } - - if (game->getGameSettings ()->getPathFinderType () == pfBasic) - { - if (workerThread != NULL) - { - workerThread->signalQuit (); - if (workerThread->shutdownAndWait () == true) - { - delete workerThread; - } - workerThread = NULL; - } - static string mutexOwnerId = - string (extractFileFromDirectoryPath (__FILE__).c_str ()) + - string ("_") + intToStr (__LINE__); - this->workerThread = new FactionThread (this); - this->workerThread->setUniqueID (mutexOwnerId); - this->workerThread->start (); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - -// ================== get ================== - - bool Faction::hasUnitTypeWithResourceCostInCache (const ResourceType * rt) const - { - std::string resourceTypeName = rt->getName (false); - std::map < std::string, bool >::const_iterator iterFind = - resourceTypeCostCache.find (resourceTypeName); - if (iterFind != resourceTypeCostCache.end ()) - { - return iterFind->second; - } - return false; - } - void Faction::updateUnitTypeWithResourceCostCache (const ResourceType * - rt) - { - std::string resourceTypeName = rt->getName (false); - - if (resourceTypeCostCache.find (resourceTypeName) == - resourceTypeCostCache.end ()) - { - resourceTypeCostCache[resourceTypeName] = - hasUnitTypeWithResouceCost (rt); - } - } - - bool Faction::hasUnitTypeWithResouceCost (const ResourceType * rt) - { - for (int factionUnitTypeIndex = 0; - factionUnitTypeIndex < getType ()->getUnitTypeCount (); - ++factionUnitTypeIndex) - { - - const UnitType *ut = getType ()->getUnitType (factionUnitTypeIndex); - if (ut->getCost (rt) != NULL) - { - return true; - } - } - return false; - } - - const Resource *Faction::getResource (const ResourceType * rt, - bool localFactionOnly) const - { - - if (localFactionOnly == false && - world != NULL && world->getGame () != NULL) - { - - Game *game = world->getGame (); - if (game->isFlagType1BitEnabled (ft1_allow_shared_team_resources) == - true) - { - return world->getResourceForTeam (rt, this->getTeam ()); - } - } - - for (int index = 0; index < (int) resources.size (); ++index) - { - if (rt == resources[index].getType ()) - { - return &resources[index]; - } - } - - printf ("ERROR cannot find resource type [%s] in list:\n", - (rt != NULL ? rt->getName ().c_str () : "null")); - for (int i = 0; i < (int) resources.size (); ++i) - { - printf ("Index %d [%s]", i, - resources[i].getType ()->getName ().c_str ()); - } - - assert (false); - return NULL; - } - - int Faction::getStoreAmount (const ResourceType * rt, - bool localFactionOnly) const - { - - if (localFactionOnly == false && - world != NULL && world->getGame () != NULL) - { - - Game *game = world->getGame (); - if (game->isFlagType1BitEnabled (ft1_allow_shared_team_resources) == - true) - { - return world->getStoreAmountForTeam (rt, this->getTeam ()); - } - } - - for (int index = 0; index < (int) store.size (); ++index) - { - if (rt == store[index].getType ()) - { - return store[index].getAmount (); - } - } - printf ("ERROR cannot find store type [%s] in list:\n", - (rt != NULL ? rt->getName ().c_str () : "null")); - for (int i = 0; i < (int) store.size (); ++i) - { - printf ("Index %d [%s]", i, store[i].getType ()->getName ().c_str ()); - } - - assert (false); - return 0; - } - - bool Faction::getCpuControl (bool enableServerControlledAI, - bool isNetworkGame, NetworkRole role) const - { - bool result = false; - if (enableServerControlledAI == false || isNetworkGame == false) - { - result = (control == ctCpuEasy || control == ctCpu - || control == ctCpuUltra || control == ctCpuZeta); - } - else - { - if (isNetworkGame == true) - { - if (role == nrServer) - { - result = (control == ctCpuEasy || control == ctCpu - || control == ctCpuUltra || control == ctCpuZeta); - } - else - { - result = (control == ctNetworkCpuEasy || control == ctNetworkCpu - || control == ctNetworkCpuUltra - || control == ctNetworkCpuZeta); - } - } - } - - return result; - } - - bool Faction::getCpuControl () const - { - return control == ctCpuEasy || control == ctCpu || control == ctCpuUltra - || control == ctCpuZeta || control == ctNetworkCpuEasy - || control == ctNetworkCpu || control == ctNetworkCpuUltra - || control == ctNetworkCpuZeta; - } - -// ==================== upgrade manager ==================== - - void Faction::startUpgrade (const UpgradeType * ut) - { - upgradeManager.startUpgrade (ut, index); - } - - void Faction::cancelUpgrade (const UpgradeType * ut) - { - upgradeManager.cancelUpgrade (ut); - } - - void Faction::finishUpgrade (const UpgradeType * ut) - { - upgradeManager.finishUpgrade (ut); - if (world->getThisFaction () != NULL - && this->getIndex () == world->getThisFaction ()->getIndex ()) - { - Console *console = world->getGame ()->getConsole (); - console->addStdMessage ("UpgradeFinished", - ": " + formatString (ut->getName (true))); - } - for (int i = 0; i < getUnitCount (); ++i) - { - getUnit (i)->applyUpgrade (ut); - } - } - -// ==================== reqs ==================== - -//checks if all required units and upgrades are present and maxUnitCount is within limit - bool Faction::reqsOk (const RequirableType * rt) const - { - assert (rt != NULL); - //required units - for (int i = 0; i < rt->getUnitReqCount (); ++i) - { - bool found = false; - for (int j = 0; j < getUnitCount (); ++j) - { - Unit *unit = getUnit (j); - const UnitType *ut = unit->getType (); - if (rt->getUnitReq (i) == ut && unit->isOperative ()) - { - found = true; - break; - } - } - if (found == false) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - return false; - } - } - - //required upgrades - for (int i = 0; i < rt->getUpgradeReqCount (); ++i) - { - if (upgradeManager.isUpgraded (rt->getUpgradeReq (i)) == false) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - return false; - } - } - - if (dynamic_cast < const UnitType * >(rt) != NULL) - { - const UnitType *producedUnitType = - dynamic_cast < const UnitType * >(rt); - if (producedUnitType != NULL - && producedUnitType->getMaxUnitCount () > 0) - { - if (producedUnitType->getMaxUnitCount () <= - getCountForMaxUnitCount (producedUnitType)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - return false; - } - } - - if (producedUnitType != NULL && isUnitLocked (producedUnitType)) - { - return false; - } - } - - return true; - } - - int Faction::getCountForMaxUnitCount (const UnitType * unitType) const - { - int count = 0; - //calculate current unit count - for (int j = 0; j < getUnitCount (); ++j) - { - Unit *unit = getUnit (j); - const UnitType *currentUt = unit->getType (); - if (unitType == currentUt && unit->isOperative ()) - { - count++; - } - //check if there is any command active which already produces this unit - count = count + unit->getCountOfProducedUnits (unitType); - } - return count; - } - - - bool Faction::reqsOk (const CommandType * ct) const - { - assert (ct != NULL); - if (ct == NULL) - { - throw megaglest_runtime_error ("In [Faction::reqsOk] ct == NULL"); - } - - if (ct->getProduced () != NULL && reqsOk (ct->getProduced ()) == false) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] reqsOk FAILED\n", - __FILE__, __FUNCTION__, __LINE__); - return false; - } - - if (ct->getClass () == ccUpgrade) - { - const UpgradeCommandType *uct = - static_cast < const UpgradeCommandType * >(ct); - if (upgradeManager.isUpgradingOrUpgraded (uct->getProducedUpgrade ())) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] upgrade check FAILED\n", - __FILE__, __FUNCTION__, __LINE__); - return false; - } - } - - return reqsOk (static_cast < const RequirableType * >(ct)); - } - -// ================== cost application ================== - -//apply costs except static production (start building/production) - bool Faction::applyCosts (const ProducibleType * p, - const CommandType * ct) - { - bool ignoreResourceCosts = false; - if (ct != NULL && ct->getClass () == ccMorph) - { - const MorphCommandType *mct = - dynamic_cast < const MorphCommandType * >(ct); - if (mct != NULL) - { - ignoreResourceCosts = mct->getIgnoreResourceRequirements (); - } - } - - if (ignoreResourceCosts == false) - { - if (checkCosts (p, ct) == false) - { - return false; - } - - assert (p != NULL); - //for each unit cost spend it - //pass 2, decrease resources, except negative static costs (ie: farms) - for (int i = 0; i < p->getCostCount (); ++i) - { - const Resource *r = p->getCost (i); - if (r == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "cannot apply costs for p [%s] %d of %d costs resource is null", - p->getName (false).c_str (), i, p->getCostCount ()); - throw megaglest_runtime_error (szBuf); - } - - const ResourceType *rt = r->getType (); - if (rt == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "cannot apply costs for p [%s] %d of %d costs resourcetype [%s] is null", - p->getName (false).c_str (), i, p->getCostCount (), - r->getDescription (false).c_str ()); - throw megaglest_runtime_error (szBuf); - } - int cost = r->getAmount (); - if ((cost > 0 || (rt->getClass () != rcStatic)) - && rt->getClass () != rcConsumable) - { - incResourceAmount (rt, -(cost)); - } - - } - } - return true; - } - -//apply discount (when a morph ends) - void Faction::applyDiscount (const ProducibleType * p, int discount) - { - assert (p != NULL); - //increase resources - for (int i = 0; i < p->getCostCount (); ++i) - { - const ResourceType *rt = p->getCost (i)->getType (); - assert (rt != NULL); - int cost = p->getCost (i)->getAmount (); - if ((cost > 0 || (rt->getClass () != rcStatic)) - && rt->getClass () != rcConsumable) - { - incResourceAmount (rt, cost * discount / 100); - } - } - } - -//apply static production (for starting units) - void Faction::applyStaticCosts (const ProducibleType * p, - const CommandType * ct) - { - assert (p != NULL); - bool ignoreResourceCosts = false; - if (ct != NULL && ct->getClass () == ccMorph) - { - const MorphCommandType *mct = - dynamic_cast < const MorphCommandType * >(ct); - if (mct != NULL) - { - ignoreResourceCosts = mct->getIgnoreResourceRequirements (); - } - } - - if (ignoreResourceCosts == false) - { - //decrease static resources - for (int i = 0; i < p->getCostCount (); ++i) - { - const ResourceType *rt = p->getCost (i)->getType (); - //assert(rt != NULL); - if (rt == NULL) - { - throw megaglest_runtime_error (string (__FUNCTION__) + - " rt == NULL for ProducibleType [" - + p->getName (false) + - "] index: " + intToStr (i)); - } - if (rt->getClass () == rcStatic) - { - int cost = p->getCost (i)->getAmount (); - if (cost > 0) - { - incResourceAmount (rt, -cost); - } - } - } - } - } - -//apply static production (when a mana source is done) - void Faction::applyStaticProduction (const ProducibleType * p, - const CommandType * ct) - { - assert (p != NULL); - - bool ignoreResourceCosts = false; - if (ct != NULL && ct->getClass () == ccMorph) - { - const MorphCommandType *mct = - dynamic_cast < const MorphCommandType * >(ct); - if (mct != NULL) - { - ignoreResourceCosts = mct->getIgnoreResourceRequirements (); - } - } - - if (ignoreResourceCosts == false) - { - //decrease static resources - for (int i = 0; i < p->getCostCount (); ++i) - { - const ResourceType *rt = p->getCost (i)->getType (); - assert (rt != NULL); - if (rt->getClass () == rcStatic) - { - int cost = p->getCost (i)->getAmount (); - if (cost < 0) - { - incResourceAmount (rt, -cost); - } - } - } - } - } - -//deapply all costs except static production (usually when a building is cancelled) - void Faction::deApplyCosts (const ProducibleType * p, - const CommandType * ct) - { - assert (p != NULL); - - bool ignoreResourceCosts = false; - if (ct != NULL && ct->getClass () == ccMorph) - { - const MorphCommandType *mct = - dynamic_cast < const MorphCommandType * >(ct); - if (mct != NULL) - { - ignoreResourceCosts = mct->getIgnoreResourceRequirements (); - } - } - - if (ignoreResourceCosts == false) - { - //increase resources - for (int i = 0; i < p->getCostCount (); ++i) - { - const ResourceType *rt = p->getCost (i)->getType (); - assert (rt != NULL); - int cost = p->getCost (i)->getAmount (); - if ((cost > 0 || (rt->getClass () != rcStatic)) - && rt->getClass () != rcConsumable) - { - incResourceAmount (rt, cost); - } - } - } - } - -//deapply static costs (usually when a unit dies) - void Faction::deApplyStaticCosts (const ProducibleType * p, - const CommandType * ct) - { - assert (p != NULL); - - bool ignoreResourceCosts = false; - if (ct != NULL && ct->getClass () == ccMorph) - { - const MorphCommandType *mct = - dynamic_cast < const MorphCommandType * >(ct); - if (mct != NULL) - { - ignoreResourceCosts = mct->getIgnoreResourceRequirements (); - } - } - - if (ignoreResourceCosts == false) - { - //decrease resources - for (int i = 0; i < p->getCostCount (); ++i) - { - const ResourceType *rt = p->getCost (i)->getType (); - assert (rt != NULL); - if (rt->getClass () == rcStatic) - { - if (rt->getRecoup_cost () == true) - { - int cost = p->getCost (i)->getAmount (); - incResourceAmount (rt, cost); - } - } - } - } - } - -//deapply static costs, but not negative costs, for when building gets killed - void Faction::deApplyStaticConsumption (const ProducibleType * p, - const CommandType * ct) - { - assert (p != NULL); - - bool ignoreResourceCosts = false; - if (ct != NULL && ct->getClass () == ccMorph) - { - const MorphCommandType *mct = - dynamic_cast < const MorphCommandType * >(ct); - if (mct != NULL) - { - ignoreResourceCosts = mct->getIgnoreResourceRequirements (); - } - } - - if (ignoreResourceCosts == false) - { - //decrease resources - for (int i = 0; i < p->getCostCount (); ++i) - { - const ResourceType *rt = p->getCost (i)->getType (); - assert (rt != NULL); - if (rt->getClass () == rcStatic) - { - int cost = p->getCost (i)->getAmount (); - if (cost > 0) - { - incResourceAmount (rt, cost); - } - } - } - } - } - -//apply resource on interval (cosumable resouces) - void Faction::applyCostsOnInterval (const ResourceType * rtApply) - { - - // For each Resource type we store in the int a total consumed value, then - // a vector of units that consume the resource type - std::map < const ResourceType *, std::pair < int, - std::vector > >resourceIntervalUsage; - - // count up consumables usage for the interval - for (int j = 0; j < getUnitCount (); ++j) - { - Unit *unit = getUnit (j); - if (unit->isOperative () == true) - { - for (int k = 0; k < unit->getType ()->getCostCount (); ++k) - { - const Resource *resource = unit->getType ()->getCost (k); - if (resource->getType () == rtApply - && resource->getType ()->getClass () == rcConsumable - && resource->getAmount () != 0) - { - if (resourceIntervalUsage.find (resource->getType ()) == - resourceIntervalUsage.end ()) - { - resourceIntervalUsage[resource->getType ()] = - make_pair < int, std::vector >(0, - std::vector < - Unit * >()); - } - // Negative cost means accumulate the resource type - resourceIntervalUsage[resource->getType ()].first += - -resource->getAmount (); - - // If the cost > 0 then the unit is a consumer - if (resource->getAmount () > 0) - { - resourceIntervalUsage[resource->getType ()].second. - push_back (unit); - } - } - } - } - } - - // Apply consumable resource usage - if (resourceIntervalUsage.empty () == false) - { - for (std::map < const ResourceType *, std::pair < int, - std::vector < Unit * > > >::iterator iter = - resourceIntervalUsage.begin (); - iter != resourceIntervalUsage.end (); ++iter) - { - // Apply resource type usage to faction resource store - const ResourceType *rt = iter->first; - int resourceTypeUsage = iter->second.first; - incResourceAmount (rt, resourceTypeUsage); - - // Check if we have any unit consumers - if (getResource (rt)->getAmount () < 0) - { - resetResourceAmount (rt); - - // Apply consequences to consumer units of this resource type - std::vector < Unit * >&resourceConsumers = iter->second.second; - - for (int i = 0; i < (int) resourceConsumers.size (); ++i) - { - Unit *unit = resourceConsumers[i]; - - //decrease unit hp - if (scriptManager->getPlayerModifiers (this->index)-> - getConsumeEnabled () == true) - { - bool decHpResult = - unit->decHp (unit->getType ()-> - getTotalMaxHp (unit->getTotalUpgrade ()) / 3); - if (decHpResult) - { - unit->setCauseOfDeath (ucodStarvedResource); - world->getStats ()->die (unit->getFactionIndex (), - unit->getType ()-> - getCountUnitDeathInStats ()); - scriptManager->onUnitDied (unit); - } - StaticSound *sound = - static_cast < - const DieSkillType * - >(unit->getType ()->getFirstStOfClass (scDie))->getSound (); - if (sound != NULL - && (thisFaction == true - || world->showWorldForPlayer (world-> - getThisTeamIndex ()) == - true)) - { - SoundRenderer::getInstance ().playFx (sound); - } - } - } - } - } - } - } - - bool Faction::checkCosts (const ProducibleType * pt, - const CommandType * ct) - { - assert (pt != NULL); - - bool ignoreResourceCosts = false; - if (ct != NULL && ct->getClass () == ccMorph) - { - const MorphCommandType *mct = - dynamic_cast < const MorphCommandType * >(ct); - if (mct != NULL) - { - ignoreResourceCosts = mct->getIgnoreResourceRequirements (); - } - //printf("Checking costs = %d for commandtype:\n%s\n",ignoreResourceCosts,mct->getDesc(NULL).c_str()); - } - - if (ignoreResourceCosts == false) - { - //for each unit cost check if enough resources - for (int i = 0; i < pt->getCostCount (); ++i) - { - const ResourceType *rt = pt->getCost (i)->getType (); - int cost = pt->getCost (i)->getAmount (); - if (cost > 0) - { - int available = getResource (rt)->getAmount (); - if (cost > available) - { - return false; - } - } - } - } - - return true; - } - -// ================== diplomacy ================== - - bool Faction::isAlly (const Faction * faction) - { - assert (faction != NULL); - return (teamIndex == faction->getTeam () || - faction->getTeam () == - GameConstants::maxPlayers - 1 + fpt_Observer); - } - -// ================== misc ================== - - void Faction::incResourceAmount (const ResourceType * rt, int amount) - { - if (world != NULL && world->getGame () != NULL - && world->getGame ()-> - isFlagType1BitEnabled (ft1_allow_shared_team_resources) == true) - { - for (int i = 0; i < (int) resources.size (); ++i) - { - Resource *r = &resources[i]; - if (r->getType () == rt) - { - r->setAmount (r->getAmount () + amount); - if (r->getType ()->getClass () != rcStatic - && (getResource (rt, false)->getAmount () + amount) > - getStoreAmount (rt, false)) - { - r->setAmount (getStoreAmount (rt, false) - - (getResource (rt, false)->getAmount () - - r->getAmount ())); - } - return; - } - } - } - else - { - for (int i = 0; i < (int) resources.size (); ++i) - { - Resource *r = &resources[i]; - if (r->getType () == rt) - { - r->setAmount (r->getAmount () + amount); - if (r->getType ()->getClass () != rcStatic - && r->getAmount () > getStoreAmount (rt)) - { - r->setAmount (getStoreAmount (rt)); - } - return; - } - } - } - assert (false); - } - - void Faction::setResourceBalance (const ResourceType * rt, int balance) - { - for (int i = 0; i < (int) resources.size (); ++i) - { - Resource *r = &resources[i]; - if (r->getType () == rt) - { - r->setBalance (balance); - return; - } - } - assert (false); - } - - Unit *Faction::findUnit (int id) const - { - UnitMap::const_iterator itFound = unitMap.find (id); - if (itFound == unitMap.end ()) - { - return NULL; - } - return itFound->second; - } - - void Faction::addUnit (Unit * unit) - { - MutexSafeWrapper safeMutex (unitsMutex, - string (__FILE__) + "_" + - intToStr (__LINE__)); - units.push_back (unit); - unitMap[unit->getId ()] = unit; - } - - void Faction::removeUnit (Unit * unit) - { - MutexSafeWrapper safeMutex (unitsMutex, - string (__FILE__) + "_" + - intToStr (__LINE__)); - - assert (units.size () == unitMap.size ()); - - int unitId = unit->getId (); - for (int i = 0; i < (int) units.size (); ++i) - { - if (units[i]->getId () == unitId) - { - units.erase (units.begin () + i); - unitMap.erase (unitId); - assert (units.size () == unitMap.size ()); - return; - } - } - - throw megaglest_runtime_error ("Could not remove unit from faction!"); - //assert(false); - } - - void Faction::addStore (const UnitType * unitType) - { - assert (unitType != NULL); - for (int newUnitStoredResourceIndex = 0; - newUnitStoredResourceIndex < unitType->getStoredResourceCount (); - ++newUnitStoredResourceIndex) - { - const Resource *newUnitStoredResource = - unitType->getStoredResource (newUnitStoredResourceIndex); - - for (int currentStoredResourceIndex = 0; - currentStoredResourceIndex < (int) store.size (); - ++currentStoredResourceIndex) - { - Resource *storedResource = &store[currentStoredResourceIndex]; - - if (storedResource->getType () == newUnitStoredResource->getType ()) - { - storedResource->setAmount (storedResource->getAmount () + - newUnitStoredResource->getAmount ()); - } - } - } - } - - void Faction::removeStore (const UnitType * unitType) - { - assert (unitType != NULL); - for (int i = 0; i < unitType->getStoredResourceCount (); ++i) - { - const Resource *r = unitType->getStoredResource (i); - for (int j = 0; j < (int) store.size (); ++j) - { - Resource *storedResource = &store[j]; - if (storedResource->getType () == r->getType ()) - { - storedResource->setAmount (storedResource->getAmount () - - r->getAmount ()); - } - } - } - limitResourcesToStore (); - } - - void Faction::limitResourcesToStore () - { - if (world != NULL && world->getGame () != NULL - && world->getGame ()-> - isFlagType1BitEnabled (ft1_allow_shared_team_resources) == true) - { - for (int i = 0; i < (int) resources.size (); ++i) - { - Resource *r = &resources[i]; - const ResourceType *rt = r->getType (); - if (rt->getClass () != rcStatic - && (getResource (rt, false)->getAmount ()) > getStoreAmount (rt, - false)) - { - r->setAmount (getStoreAmount (rt, false) - - (getResource (rt, false)->getAmount () - - r->getAmount ())); - } - } - } - else - { - for (int i = 0; i < (int) resources.size (); ++i) - { - Resource *r = &resources[i]; - Resource *s = &store[i]; - if (r->getType ()->getClass () != rcStatic - && r->getAmount () > s->getAmount ()) - { - r->setAmount (s->getAmount ()); - } - } - } - } - - void Faction::resetResourceAmount (const ResourceType * rt) - { - for (int i = 0; i < (int) resources.size (); ++i) - { - if (resources[i].getType () == rt) - { - resources[i].setAmount (0); - return; - } - } - assert (false); - } - - bool Faction::isResourceTargetInCache (const Vec2i & pos, - bool incrementUseCounter) - { - bool result = false; - - if (cachingDisabled == false) - { - if (cacheResourceTargetList.empty () == false) - { - std::map < Vec2i, int >::iterator iter = - cacheResourceTargetList.find (pos); - - result = (iter != cacheResourceTargetList.end ()); - if (result == true && incrementUseCounter == true) - { - iter->second++; - } - } - } - - return result; - } - - void Faction::addResourceTargetToCache (const Vec2i & pos, - bool incrementUseCounter) - { - if (cachingDisabled == false) - { - - bool duplicateEntry = - isResourceTargetInCache (pos, incrementUseCounter); - //bool duplicateEntry = false; - - if (duplicateEntry == false) - { - cacheResourceTargetList[pos] = 1; - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "[addResourceTargetToCache] pos [%s]cacheResourceTargetList.size() [" - MG_SIZE_T_SPECIFIER "]", pos.getString ().c_str (), - cacheResourceTargetList.size ()); - - //unit->logSynchData(szBuf); - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "----------------------------------- START [%d] ------------------------------------------------\n", - getFrameCount ()); - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "[%s::%d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __LINE__); - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, "%s\n", - szBuf); - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "------------------------------------ END [%d] -------------------------------------------------\n", - getFrameCount ()); - } - } - } - } - - void Faction::removeResourceTargetFromCache (const Vec2i & pos) - { - if (cachingDisabled == false) - { - if (cacheResourceTargetList.empty () == false) - { - std::map < Vec2i, int >::iterator iter = - cacheResourceTargetList.find (pos); - - if (iter != cacheResourceTargetList.end ()) - { - cacheResourceTargetList.erase (pos); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "[removeResourceTargetFromCache] pos [%s]cacheResourceTargetList.size() [" - MG_SIZE_T_SPECIFIER "]", pos.getString ().c_str (), - cacheResourceTargetList.size ()); - - //unit->logSynchData(szBuf); - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "----------------------------------- START [%d] ------------------------------------------------\n", - getFrameCount ()); - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "[%s::%d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __LINE__); - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, "%s\n", - szBuf); - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "------------------------------------ END [%d] -------------------------------------------------\n", - getFrameCount ()); - } - } - } - } - } - - void Faction::addCloseResourceTargetToCache (const Vec2i & pos) - { - if (cachingDisabled == false) - { - if (cachedCloseResourceTargetLookupList.find (pos) == - cachedCloseResourceTargetLookupList.end ()) - { - const Map *map = world->getMap (); - const int harvestDistance = 5; - - for (int j = -harvestDistance; j <= harvestDistance; ++j) - { - for (int k = -harvestDistance; k <= harvestDistance; ++k) - { - Vec2i newPos = pos + Vec2i (j, k); - if (isResourceTargetInCache (newPos) == false) - { - if (map->isInside (newPos.x, newPos.y)) - { - Resource *r = - map->getSurfaceCell (map->toSurfCoords (newPos))-> - getResource (); - if (r != NULL) - { - addResourceTargetToCache (newPos); - //cacheResourceTargetList[newPos] = 1; - } - } - } - } - } - - cachedCloseResourceTargetLookupList[pos] = true; - } - } - } - - Vec2i Faction::getClosestResourceTypeTargetFromCache (Unit * unit, - const ResourceType * - type, - int frameIndex) - { - Vec2i result (-1); - - if (cachingDisabled == false) - { - if (cacheResourceTargetList.empty () == false) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "cacheResourceTargetList.size() [" MG_SIZE_T_SPECIFIER - "]", cacheResourceTargetList.size ()); - - if (frameIndex < 0) - { - unit->logSynchData (__FILE__, __LINE__, szBuf); - } - else - { - unit->logSynchDataThreaded (__FILE__, __LINE__, szBuf); - } - } - - - std::vector < Vec2i > deleteList; - - const int harvestDistance = 5; - const Map *map = world->getMap (); - Vec2i pos = unit->getPos (); - - bool foundCloseResource = false; - // First look immediately around the unit's position - - // 0 means start looking leftbottom to top right -// if(Thread::isCurrentThreadMainThread() == false) { -// throw megaglest_runtime_error("#1 Invalid access to Faction random from outside main thread current id = " + -// intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId())); -// } - int tryRadius = random.randRange (0, 1); - //int tryRadius = unit->getRandom(true)->randRange(0,1); - //int tryRadius = 0; - if (tryRadius == 0) - { - for (int j = -harvestDistance; - j <= harvestDistance && foundCloseResource == false; ++j) - { - for (int k = -harvestDistance; - k <= harvestDistance && foundCloseResource == false; ++k) - { - Vec2i newPos = pos + Vec2i (j, k); - if (map->isInside (newPos) == true - && isResourceTargetInCache (newPos) == false) - { - const SurfaceCell *sc = - map->getSurfaceCell (map->toSurfCoords (newPos)); - if (sc != NULL && sc->getResource () != NULL) - { - const Resource *resource = sc->getResource (); - if (resource->getType () != NULL - && resource->getType () == type) - { - if (result.x < 0 - || unit->getPos ().dist (newPos) < - unit->getPos ().dist (result)) - { - if (unit->isBadHarvestPos (newPos) == false) - { - result = newPos; - foundCloseResource = true; - break; - } - } - } - } - else - { - deleteList.push_back (newPos); - } - } - } - } - } - // start looking topright to leftbottom - else - { - for (int j = harvestDistance; - j >= -harvestDistance && foundCloseResource == false; --j) - { - for (int k = harvestDistance; - k >= -harvestDistance && foundCloseResource == false; --k) - { - Vec2i newPos = pos + Vec2i (j, k); - if (map->isInside (newPos) == true - && isResourceTargetInCache (newPos) == false) - { - const SurfaceCell *sc = - map->getSurfaceCell (map->toSurfCoords (newPos)); - if (sc != NULL && sc->getResource () != NULL) - { - const Resource *resource = sc->getResource (); - if (resource->getType () != NULL - && resource->getType () == type) - { - if (result.x < 0 - || unit->getPos ().dist (newPos) < - unit->getPos ().dist (result)) - { - if (unit->isBadHarvestPos (newPos) == false) - { - result = newPos; - foundCloseResource = true; - break; - } - } - } - } - else - { - deleteList.push_back (newPos); - } - } - } - } - } - - if (foundCloseResource == false) - { - // Now check the whole cache - for (std::map < Vec2i, int >::iterator iter = - cacheResourceTargetList.begin (); - iter != cacheResourceTargetList.end () - && foundCloseResource == false; ++iter) - { - const Vec2i & cache = iter->first; - if (map->isInside (cache) == true) - { - const SurfaceCell *sc = - map->getSurfaceCell (map->toSurfCoords (cache)); - if (sc != NULL && sc->getResource () != NULL) - { - const Resource *resource = sc->getResource (); - if (resource->getType () != NULL - && resource->getType () == type) - { - if (result.x < 0 - || unit->getPos ().dist (cache) < - unit->getPos ().dist (result)) - { - if (unit->isBadHarvestPos (cache) == false) - { - result = cache; - // Close enough to our position, no more looking - if (unit->getPos ().dist (result) <= - (harvestDistance * 2)) - { - foundCloseResource = true; - break; - } - } - } - } - } - else - { - deleteList.push_back (cache); - } - } - else - { - deleteList.push_back (cache); - } - } - } - - if (deleteList.empty () == false) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == - true) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "[cleaning old resource targets] deleteList.size() [" - MG_SIZE_T_SPECIFIER - "] cacheResourceTargetList.size() [" - MG_SIZE_T_SPECIFIER "] result [%s]", - deleteList.size (), cacheResourceTargetList.size (), - result.getString ().c_str ()); - - if (frameIndex < 0) - { - unit->logSynchData (__FILE__, __LINE__, szBuf); - } - else - { - unit->logSynchDataThreaded (__FILE__, __LINE__, szBuf); - } - } - - cleanupResourceTypeTargetCache (&deleteList, frameIndex); - } - } - } - - return result; - } - -// CANNOT MODIFY the cache here since the AI calls this method and the AI is only controlled -// by the server for network games and it would cause out of synch since clients do not call -// this method so DO NOT modify the cache here! - Vec2i Faction::getClosestResourceTypeTargetFromCache (const Vec2i & pos, - const ResourceType * - type) - { - Vec2i result (-1); - if (cachingDisabled == false) - { - if (cacheResourceTargetList.empty () == false) - { - //std::vector deleteList; - - const int harvestDistance = 5; - const Map *map = world->getMap (); - - bool foundCloseResource = false; - - // 0 means start looking leftbottom to top right -// if(Thread::isCurrentThreadMainThread() == false) { -// throw megaglest_runtime_error("#2 Invalid access to Faction random from outside main thread current id = " + -// intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId())); -// } - int tryRadius = random.randRange (0, 1); - if (tryRadius == 0) - { - // First look immediately around the given position - for (int j = -harvestDistance; - j <= harvestDistance && foundCloseResource == false; ++j) - { - for (int k = -harvestDistance; - k <= harvestDistance && foundCloseResource == false; ++k) - { - Vec2i newPos = pos + Vec2i (j, k); - if (map->isInside (newPos) == true - && isResourceTargetInCache (newPos) == false) - { - const SurfaceCell *sc = - map->getSurfaceCell (map->toSurfCoords (newPos)); - if (sc != NULL && sc->getResource () != NULL) - { - const Resource *resource = sc->getResource (); - if (resource->getType () != NULL - && resource->getType () == type) - { - if (result.x < 0 - || pos.dist (newPos) < pos.dist (result)) - { - result = newPos; - foundCloseResource = true; - break; - } - } - } - //else { - // deleteList.push_back(newPos); - //} - } - } - } - } - else - { - // First look immediately around the given position - for (int j = harvestDistance; - j >= -harvestDistance && foundCloseResource == false; --j) - { - for (int k = harvestDistance; - k >= -harvestDistance && foundCloseResource == false; --k) - { - Vec2i newPos = pos + Vec2i (j, k); - if (map->isInside (newPos) == true - && isResourceTargetInCache (newPos) == false) - { - const SurfaceCell *sc = - map->getSurfaceCell (map->toSurfCoords (newPos)); - if (sc != NULL && sc->getResource () != NULL) - { - const Resource *resource = sc->getResource (); - if (resource->getType () != NULL - && resource->getType () == type) - { - if (result.x < 0 - || pos.dist (newPos) < pos.dist (result)) - { - result = newPos; - foundCloseResource = true; - break; - } - } - } - //else { - // deleteList.push_back(newPos); - //} - } - } - } - } - - if (foundCloseResource == false) - { - // Now check the whole cache - for (std::map < Vec2i, int >::iterator iter = - cacheResourceTargetList.begin (); - iter != cacheResourceTargetList.end () - && foundCloseResource == false; ++iter) - { - const Vec2i & cache = iter->first; - if (map->isInside (cache) == true) - { - const SurfaceCell *sc = - map->getSurfaceCell (map->toSurfCoords (cache)); - if (sc != NULL && sc->getResource () != NULL) - { - const Resource *resource = sc->getResource (); - if (resource->getType () != NULL - && resource->getType () == type) - { - if (result.x < 0 || pos.dist (cache) < pos.dist (result)) - { - result = cache; - // Close enough to our position, no more looking - if (pos.dist (result) <= (harvestDistance * 2)) - { - foundCloseResource = true; - break; - } - } - } - } - //else { - // deleteList.push_back(cache); - //} - } - //else { - // deleteList.push_back(cache); - //} - } - } - } - } - - return result; - } - - void Faction::cleanupResourceTypeTargetCache (std::vector < Vec2i > - *deleteListPtr, - int frameIndex) - { - if (cachingDisabled == false) - { - if (cacheResourceTargetList.empty () == false) - { - const int cleanupInterval = (GameConstants::updateFps * 5); - bool needToCleanup = (getFrameCount () % cleanupInterval == 0); - - if (deleteListPtr != NULL || needToCleanup == true) - { - std::vector < Vec2i > deleteList; - - if (deleteListPtr != NULL) - { - deleteList = *deleteListPtr; - } - else - { - for (std::map < Vec2i, int >::iterator iter = - cacheResourceTargetList.begin (); - iter != cacheResourceTargetList.end (); ++iter) - { - const Vec2i & cache = iter->first; - - if (world->getMap ()-> - getSurfaceCell (world->getMap ()->toSurfCoords (cache)) != - NULL) - { - Resource *resource = - world->getMap ()->getSurfaceCell (world->getMap ()-> - toSurfCoords (cache))-> - getResource (); - if (resource == NULL) - { - deleteList.push_back (cache); - } - } - else - { - deleteList.push_back (cache); - } - } - } - - if (deleteList.empty () == false) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "[cleaning old resource targets] deleteList.size() [" - MG_SIZE_T_SPECIFIER - "] cacheResourceTargetList.size() [" - MG_SIZE_T_SPECIFIER "], needToCleanup [%d]", - deleteList.size (), cacheResourceTargetList.size (), - needToCleanup); - //unit->logSynchData(szBuf); - - char szBuf1[8096] = ""; - snprintf (szBuf1, 8096, - "----------------------------------- START [%d] ------------------------------------------------\n", - getFrameCount ()); - string logDataText = szBuf1; - - snprintf (szBuf1, 8096, "[%s::%d]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __LINE__); - logDataText += szBuf1; - - snprintf (szBuf1, 8096, "%s\n", szBuf); - logDataText += szBuf1; - - snprintf (szBuf1, 8096, - "------------------------------------ END [%d] -------------------------------------------------\n", - getFrameCount ()); - logDataText += szBuf1; - - if (frameIndex < 0) - { - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - "%s", logDataText.c_str ()); - } - else - { - addWorldSynchThreadedLogList (logDataText); - } - } - - for (int i = 0; i < (int) deleteList.size (); ++i) - { - Vec2i & cache = deleteList[i]; - cacheResourceTargetList.erase (cache); - } - } - } - } - } - } - -//std::vector Faction::findCachedPath(const Vec2i &target, Unit *unit) { -// std::vector result; -// if(cachingDisabled == false) { -// if(successfulPathFinderTargetList.find(target) == successfulPathFinderTargetList.end()) { -// // Lets find the shortest and most successful path already taken by a -// // similar sized unit -// -// bool foundCachedPath = false; -// std::vector &cacheList = successfulPathFinderTargetList[target]; -// int unitSize = unit->getType()->getSize(); -// for(int i = 0; i < cacheList.size(); ++i) { -// FactionPathSuccessCache &cache = cacheList[i]; -// if(cache.unitSize <= unitSize) { -// vector, int> > &pathQueue = cache.pathQueue; -// -// for(int j = 0; j < pathQueue.size(); ++j) { -// // Now start at the end of the path and see how many nodes -// // until we reach a cell near the unit's current position -// std::pair, int> &path = pathQueue[j]; -// -// for(int k = path.first.size() - 1; k >= 0; --k) { -// if(world->getMap()->canMove(unit, unit->getPos(), path.first[k]) == true) { -// if(foundCachedPath == false) { -// for(int l = k; l < path.first.size(); ++l) { -// result.push_back(path.first[l]); -// } -// } -// else { -// if(result.size() > (path.first.size() - k)) { -// for(int l = k; l < path.first.size(); ++l) { -// result.push_back(path.first[l]); -// } -// } -// } -// foundCachedPath = true; -// -// break; -// } -// } -// } -// } -// } -// } -// } -// -// return result; -//} - -//void Faction::addCachedPath(const Vec2i &target, Unit *unit) { -// if(cachingDisabled == false) { -// if(successfulPathFinderTargetList.find(target) == successfulPathFinderTargetList.end()) { -// FactionPathSuccessCache cache; -// cache.unitSize = unit->getType()->getSize(); -// cache.pathQueue.push_back(make_pair, int>(unit->getCurrentTargetPathTaken().second,1)); -// successfulPathFinderTargetList[target].push_back(cache); -// } -// else { -// bool finishedAdd = false; -// std::pair > currentTargetPathTaken = unit->getCurrentTargetPathTaken(); -// std::vector &cacheList = successfulPathFinderTargetList[target]; -// int unitSize = unit->getType()->getSize(); -// -// for(int i = 0; i < cacheList.size() && finishedAdd == false; ++i) { -// FactionPathSuccessCache &cache = cacheList[i]; -// if(cache.unitSize <= unitSize) { -// vector, int> > &pathQueue = cache.pathQueue; -// -// for(int j = 0; j < pathQueue.size() && finishedAdd == false; ++j) { -// // Now start at the end of the path and see how many nodes are the same -// std::pair, int> &path = pathQueue[j]; -// int minPathSize = std::min(path.first.size(),currentTargetPathTaken.second.size()); -// int intersectIndex = -1; -// -// for(int k = 0; k < minPathSize; ++k) { -// if(path.first[path.first.size() - k - 1] != currentTargetPathTaken.second[currentTargetPathTaken.second.size() - k - 1]) { -// intersectIndex = k; -// break; -// } -// } -// -// // New path is same or longer than old path so replace -// // old path with new -// if(intersectIndex + 1 == path.first.size()) { -// path.first = currentTargetPathTaken.second; -// path.second++; -// finishedAdd = true; -// } -// // Old path is same or longer than new path so -// // do nothing -// else if(intersectIndex + 1 == currentTargetPathTaken.second.size()) { -// path.second++; -// finishedAdd = true; -// } -// } -// -// // If new path is >= 10 cells add it -// if(finishedAdd == false && currentTargetPathTaken.second.size() >= 10) { -// pathQueue.push_back(make_pair, int>(currentTargetPathTaken.second,1)); -// } -// } -// } -// } -// } -//} - - void Faction::deletePixels () - { - if (factionType != NULL) - { - factionType->deletePixels (); - } - } - -//Unit * Faction::findClosestUnitWithSkillClass( const Vec2i &pos,const CommandClass &cmdClass, -// const std::vector &skillClassList, -// const UnitType *unitType) { -// Unit *result = NULL; -// -///* -// std::map >::iterator iterFind = cacheUnitCommandClassList.find(cmdClass); -// if(iterFind != cacheUnitCommandClassList.end()) { -// for(std::map::iterator iter = iterFind->second.begin(); -// iter != iterFind->second.end(); ++iter) { -// Unit *curUnit = findUnit(iter->second); -// if(curUnit != NULL) { -// -// const CommandType *cmdType = curUnit->getType()->getFirstCtOfClass(cmdClass); -// bool isUnitPossibleCandidate = (cmdType != NULL); -// if(skillClassList.empty() == false) { -// isUnitPossibleCandidate = false; -// -// for(int j = 0; j < skillClassList.size(); ++j) { -// SkillClass skValue = skillClassList[j]; -// if(curUnit->getCurrSkill()->getClass() == skValue) { -// isUnitPossibleCandidate = true; -// break; -// } -// } -// } -// -// if(isUnitPossibleCandidate == true) { -// if(result == NULL || curUnit->getPos().dist(pos) < result->getPos().dist(pos)) { -// result = curUnit; -// } -// } -// } -// } -// } -//*/ -// -// //if(result == NULL) { -// for(int i = 0; i < getUnitCount(); ++i) { -// Unit *curUnit = getUnit(i); -// -// bool isUnitPossibleCandidate = false; -// -// const CommandType *cmdType = curUnit->getType()->getFirstCtOfClass(cmdClass); -// if(cmdType != NULL) { -// const RepairCommandType *rct = dynamic_cast(cmdType); -// if(rct != NULL && rct->isRepairableUnitType(unitType)) { -// isUnitPossibleCandidate = true; -// } -// } -// else { -// isUnitPossibleCandidate = false; -// } -// -// if(isUnitPossibleCandidate == true && skillClassList.empty() == false) { -// isUnitPossibleCandidate = false; -// -// for(int j = 0; j < (int)skillClassList.size(); ++j) { -// SkillClass skValue = skillClassList[j]; -// if(curUnit->getCurrSkill()->getClass() == skValue) { -// isUnitPossibleCandidate = true; -// break; -// } -// } -// } -// -// -// if(isUnitPossibleCandidate == true) { -// //cacheUnitCommandClassList[cmdClass][curUnit->getId()] = curUnit->getId(); -// -// if(result == NULL || curUnit->getPos().dist(pos) < result->getPos().dist(pos)) { -// result = curUnit; -// } -// } -// } -// //} -// return result; -//} - - int Faction::getFrameCount () - { - int frameCount = 0; - const Game *game = Renderer::getInstance ().getGame (); - if (game != NULL && game->getWorld () != NULL) - { - frameCount = game->getWorld ()->getFrameCount (); - } - - return frameCount; - } - - const SwitchTeamVote *Faction::getFirstSwitchTeamVote () const - { - const SwitchTeamVote *vote = NULL; - if (switchTeamVotes.empty () == false) - { - for (std::map < int, SwitchTeamVote >::const_iterator iterMap = - switchTeamVotes.begin (); iterMap != switchTeamVotes.end (); - ++iterMap) - { - const SwitchTeamVote & curVote = iterMap->second; - if (curVote.voted == false) - { - vote = &curVote; - break; - } - } - } - - return vote; - } - - SwitchTeamVote *Faction::getSwitchTeamVote (int factionIndex) - { - SwitchTeamVote *vote = NULL; - if (switchTeamVotes.find (factionIndex) != switchTeamVotes.end ()) - { - vote = &switchTeamVotes[factionIndex]; - } - - return vote; - } - - void Faction::setSwitchTeamVote (SwitchTeamVote & vote) - { - switchTeamVotes[vote.factionIndex] = vote; - } - - bool Faction::canCreateUnit (const UnitType * ut, bool checkBuild, - bool checkProduce, bool checkMorph) const - { - // Now check that at least 1 other unit can produce, build or morph this unit - bool foundUnit = false; - for (int l = 0; l < this->getUnitCount () && foundUnit == false; ++l) - { - const UnitType *unitType2 = this->getUnit (l)->getType (); - - for (int j = 0; - j < unitType2->getCommandTypeCount () && foundUnit == false; ++j) - { - const CommandType *cmdType = unitType2->getCommandType (j); - if (cmdType != NULL) - { - // Check if this is a produce command - if (checkProduce == true && cmdType->getClass () == ccProduce) - { - const ProduceCommandType *produce = - dynamic_cast < const ProduceCommandType * >(cmdType); - if (produce != NULL) - { - const UnitType *produceUnit = produce->getProducedUnit (); - - if (produceUnit != NULL && - ut->getId () != unitType2->getId () && - ut->getName (false) == produceUnit->getName (false)) - { - foundUnit = true; - break; - } - } - } - // Check if this is a build command - else if (checkBuild == true && cmdType->getClass () == ccBuild) - { - const BuildCommandType *build = - dynamic_cast < const BuildCommandType * >(cmdType); - if (build != NULL) - { - for (int k = 0; - k < build->getBuildingCount () && foundUnit == false; - ++k) - { - const UnitType *buildUnit = build->getBuilding (k); - - if (buildUnit != NULL && - ut->getId () != unitType2->getId () && - ut->getName (false) == buildUnit->getName (false)) - { - foundUnit = true; - break; - } - } - } - } - // Check if this is a morph command - else if (checkMorph == true && cmdType->getClass () == ccMorph) - { - const MorphCommandType *morph = - dynamic_cast < const MorphCommandType * >(cmdType); - if (morph != NULL) - { - const UnitType *morphUnit = morph->getMorphUnit (); - - if (morphUnit != NULL && - ut->getId () != unitType2->getId () && - ut->getName (false) == morphUnit->getName (false)) - { - foundUnit = true; - break; - } - } - } - } - } - } - - return foundUnit; - } - - void Faction::clearCaches () - { - cacheResourceTargetList.clear (); - cachedCloseResourceTargetLookupList.clear (); - - //aliveUnitListCache.clear(); - //mobileUnitListCache.clear(); - //beingBuiltUnitListCache.clear(); - - unsigned int unitCount = this->getUnitCount (); - for (unsigned int i = 0; i < unitCount; ++i) - { - Unit *unit = this->getUnit (i); - if (unit != NULL) - { - unit->clearCaches (); - } - } - } - - uint64 Faction::getCacheKBytes (uint64 * cache1Size, uint64 * cache2Size, - uint64 * cache3Size, uint64 * cache4Size, - uint64 * cache5Size) - { - uint64 cache1Count = 0; - uint64 cache2Count = 0; - uint64 cache3Count = 0; - uint64 cache4Count = 0; - uint64 cache5Count = 0; - - for (std::map < Vec2i, int >::iterator iterMap1 = - cacheResourceTargetList.begin (); - iterMap1 != cacheResourceTargetList.end (); ++iterMap1) - { - cache1Count++; - } - for (std::map < Vec2i, bool >::iterator iterMap1 = - cachedCloseResourceTargetLookupList.begin (); - iterMap1 != cachedCloseResourceTargetLookupList.end (); ++iterMap1) - { - cache2Count++; - } - for (std::map < int, const Unit * >::iterator iterMap1 = - aliveUnitListCache.begin (); iterMap1 != aliveUnitListCache.end (); - ++iterMap1) - { - cache3Count++; - } - for (std::map < int, const Unit * >::iterator iterMap1 = - mobileUnitListCache.begin (); - iterMap1 != mobileUnitListCache.end (); ++iterMap1) - { - cache4Count++; - } - for (std::map < int, const Unit * >::iterator iterMap1 = - beingBuiltUnitListCache.begin (); - iterMap1 != beingBuiltUnitListCache.end (); ++iterMap1) - { - cache5Count++; - } - - if (cache1Size) - { - *cache1Size = cache1Count; - } - if (cache2Size) - { - *cache2Size = cache2Count; - } - if (cache3Size) - { - *cache3Size = cache3Count; - } - if (cache4Size) - { - *cache4Size = cache4Count; - } - if (cache5Size) - { - *cache5Size = cache5Count; - } - - uint64 totalBytes = cache1Count * sizeof (int); - totalBytes += cache2Count * sizeof (bool); - totalBytes += cache3Count * (sizeof (int) + sizeof (const Unit *)); - totalBytes += cache4Count * (sizeof (int) + sizeof (const Unit *)); - totalBytes += cache5Count * (sizeof (int) + sizeof (const Unit *)); - - totalBytes /= 1000; - - return totalBytes; - } - - string Faction::getCacheStats () - { - string result = ""; - - int cache1Count = 0; - int cache2Count = 0; - - for (std::map < Vec2i, int >::iterator iterMap1 = - cacheResourceTargetList.begin (); - iterMap1 != cacheResourceTargetList.end (); ++iterMap1) - { - cache1Count++; - } - for (std::map < Vec2i, bool >::iterator iterMap1 = - cachedCloseResourceTargetLookupList.begin (); - iterMap1 != cachedCloseResourceTargetLookupList.end (); ++iterMap1) - { - cache2Count++; - } - - uint64 totalBytes = cache1Count * sizeof (int); - totalBytes += cache2Count * sizeof (bool); - - totalBytes /= 1000; - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "cache1Count [%d] cache2Count [%d] total KB: %s", - cache1Count, cache2Count, formatNumber (totalBytes).c_str ()); - result = szBuf; - return result; - } - - std::string Faction::toString (bool crcMode) const - { - std::string result = "FactionIndex = " + intToStr (this->index) + "\n"; - result += "teamIndex = " + intToStr (this->teamIndex) + "\n"; - result += - "startLocationIndex = " + intToStr (this->startLocationIndex) + "\n"; - if (crcMode == false) - { - result += "thisFaction = " + intToStr (this->thisFaction) + "\n"; - result += "control = " + intToStr (this->control) + "\n"; - } - - if (this->factionType != NULL) - { - result += this->factionType->toString () + "\n"; - } - - result += this->upgradeManager.toString () + "\n"; - - result += "ResourceCount = " + intToStr (resources.size ()) + "\n"; - for (int idx = 0; idx < (int) resources.size (); idx++) - { - result += - "index = " + intToStr (idx) + " " + resources[idx].toString () + - "\n"; - } - - result += "StoreCount = " + intToStr (store.size ()) + "\n"; - for (int idx = 0; idx < (int) store.size (); idx++) - { - result += - "index = " + intToStr (idx) + " " + store[idx].toString () + "\n"; - } - - result += "Allies = " + intToStr (allies.size ()) + "\n"; - for (int idx = 0; idx < (int) allies.size (); idx++) - { - result += - "index = " + intToStr (idx) + " name: " + - allies[idx]->factionType->getName (false) + " factionindex = " + - intToStr (allies[idx]->index) + "\n"; - } - - result += "Units = " + intToStr (units.size ()) + "\n"; - for (int idx = 0; idx < (int) units.size (); idx++) - { - result += units[idx]->toString (crcMode) + "\n"; - } - - return result; - } - - void Faction::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode *factionNode = rootNode->addChild ("Faction"); - - upgradeManager.saveGame (factionNode); - for (unsigned int i = 0; i < resources.size (); ++i) - { - Resource & resource = resources[i]; - resource.saveGame (factionNode); - } - XmlNode *storeNode = factionNode->addChild ("Store"); - for (unsigned int i = 0; i < store.size (); ++i) - { - Resource & resource = store[i]; - resource.saveGame (storeNode); - } - - for (unsigned int i = 0; i < allies.size (); ++i) - { - Faction *ally = allies[i]; - XmlNode *allyNode = factionNode->addChild ("Ally"); - allyNode->addAttribute ("allyFactionIndex", - intToStr (ally->getIndex ()), - mapTagReplacements); - } - for (unsigned int i = 0; i < units.size (); ++i) - { - Unit *unit = units[i]; - unit->saveGame (factionNode); - } - - factionNode->addAttribute ("control", intToStr (control), - mapTagReplacements); - - factionNode->addAttribute ("overridePersonalityType", - intToStr (overridePersonalityType), - mapTagReplacements); - factionNode->addAttribute ("factiontype", factionType->getName (false), - mapTagReplacements); - factionNode->addAttribute ("index", intToStr (index), - mapTagReplacements); - factionNode->addAttribute ("teamIndex", intToStr (teamIndex), - mapTagReplacements); - factionNode->addAttribute ("startLocationIndex", - intToStr (startLocationIndex), - mapTagReplacements); - factionNode->addAttribute ("thisFaction", intToStr (thisFaction), - mapTagReplacements); - - for (std::map < Vec2i, int >::iterator iterMap = - cacheResourceTargetList.begin (); - iterMap != cacheResourceTargetList.end (); ++iterMap) - { - XmlNode *cacheResourceTargetListNode = - factionNode->addChild ("cacheResourceTargetList"); - - cacheResourceTargetListNode->addAttribute ("key", - iterMap->first. - getString (), - mapTagReplacements); - cacheResourceTargetListNode->addAttribute ("value", - intToStr (iterMap->second), - mapTagReplacements); - } - - for (std::map < Vec2i, bool >::iterator iterMap = - cachedCloseResourceTargetLookupList.begin (); - iterMap != cachedCloseResourceTargetLookupList.end (); ++iterMap) - { - XmlNode *cachedCloseResourceTargetLookupListNode = - factionNode->addChild ("cachedCloseResourceTargetLookupList"); - - cachedCloseResourceTargetLookupListNode->addAttribute ("key", - iterMap->first. - getString (), - mapTagReplacements); - cachedCloseResourceTargetLookupListNode->addAttribute ("value", - intToStr - (iterMap-> - second), - mapTagReplacements); - } - - factionNode->addAttribute ("random", intToStr (random.getLastNumber ()), - mapTagReplacements); - factionNode->addAttribute ("currentSwitchTeamVoteFactionIndex", - intToStr (currentSwitchTeamVoteFactionIndex), - mapTagReplacements); - factionNode->addAttribute ("allowSharedTeamUnits", - intToStr (allowSharedTeamUnits), - mapTagReplacements); - - for (std::set < const UnitType * >::iterator iterMap = - lockedUnits.begin (); iterMap != lockedUnits.end (); ++iterMap) - { - XmlNode *lockedUnitsListNode = - factionNode->addChild ("lockedUnitList"); - const UnitType *ut = *iterMap; - - lockedUnitsListNode->addAttribute ("value", ut->getName (false), - mapTagReplacements); - } - - for (std::map < int, int >::iterator iterMap = unitsMovingList.begin (); - iterMap != unitsMovingList.end (); ++iterMap) - { - XmlNode *unitsMovingListNode = - factionNode->addChild ("unitsMovingList"); - - unitsMovingListNode->addAttribute ("key", intToStr (iterMap->first), - mapTagReplacements); - unitsMovingListNode->addAttribute ("value", - intToStr (iterMap->second), - mapTagReplacements); - } - - for (std::map < int, int >::iterator iterMap = - unitsPathfindingList.begin (); - iterMap != unitsPathfindingList.end (); ++iterMap) - { - XmlNode *unitsPathfindingListNode = - factionNode->addChild ("unitsPathfindingList"); - - unitsPathfindingListNode->addAttribute ("key", - intToStr (iterMap->first), - mapTagReplacements); - unitsPathfindingListNode->addAttribute ("value", - intToStr (iterMap->second), - mapTagReplacements); - } - } - - void Faction::loadGame (const XmlNode * rootNode, int factionIndex, - GameSettings * settings, World * world) - { - XmlNode *factionNode = NULL; - vector < XmlNode * >factionNodeList = - rootNode->getChildList ("Faction"); - for (unsigned int i = 0; i < factionNodeList.size (); ++i) - { - XmlNode *node = factionNodeList[i]; - if (node->getAttribute ("index")->getIntValue () == factionIndex) - { - factionNode = node; - break; - } - } - - if (factionNode != NULL) - { - - allies.clear (); - vector < XmlNode * >allyNodeList = factionNode->getChildList ("Ally"); - for (unsigned int i = 0; i < allyNodeList.size (); ++i) - { - XmlNode *allyNode = allyNodeList[i]; - - int allyFactionIndex = - allyNode->getAttribute ("allyFactionIndex")->getIntValue (); - allies.push_back (world->getFaction (allyFactionIndex)); - } - - vector < XmlNode * >unitNodeList = factionNode->getChildList ("Unit"); - for (unsigned int i = 0; i < unitNodeList.size (); ++i) - { - XmlNode *unitNode = unitNodeList[i]; - Unit *unit = Unit::loadGame (unitNode, settings, this, world); - this->addUnit (unit); - } - - for (unsigned int i = 0; i < resources.size (); ++i) - { - Resource & resource = resources[i]; - resource.loadGame (factionNode, i, techTree); - } - XmlNode *storeNode = factionNode->getChild ("Store"); - for (unsigned int i = 0; i < store.size (); ++i) - { - Resource & resource = store[i]; - resource.loadGame (storeNode, i, techTree); - } - - upgradeManager.loadGame (factionNode, this); - - control = - static_cast < ControlType > - (factionNode->getAttribute ("control")->getIntValue ()); - - if (factionNode->hasAttribute ("overridePersonalityType") == true) - { - overridePersonalityType = - static_cast < FactionPersonalityType > - (factionNode->getAttribute ("overridePersonalityType")-> - getIntValue ()); - } - - teamIndex = factionNode->getAttribute ("teamIndex")->getIntValue (); - - startLocationIndex = - factionNode->getAttribute ("startLocationIndex")->getIntValue (); - - thisFaction = - factionNode->getAttribute ("thisFaction")->getIntValue () != 0; - - if (factionNode->hasAttribute ("allowSharedTeamUnits") == true) - { - allowSharedTeamUnits = - factionNode->getAttribute ("allowSharedTeamUnits")-> - getIntValue () != 0; - } - - vector < XmlNode * >cacheResourceTargetListNodeList = - factionNode->getChildList ("cacheResourceTargetList"); - for (unsigned int i = 0; i < cacheResourceTargetListNodeList.size (); - ++i) - { - XmlNode *cacheResourceTargetListNode = - cacheResourceTargetListNodeList[i]; - - Vec2i vec = - Vec2i::strToVec2 (cacheResourceTargetListNode-> - getAttribute ("key")->getValue ()); - cacheResourceTargetList[vec] = - cacheResourceTargetListNode->getAttribute ("value")-> - getIntValue (); - } - vector < XmlNode * >cachedCloseResourceTargetLookupListNodeList = - factionNode->getChildList ("cachedCloseResourceTargetLookupList"); - for (unsigned int i = 0; - i < cachedCloseResourceTargetLookupListNodeList.size (); ++i) - { - XmlNode *cachedCloseResourceTargetLookupListNode = - cachedCloseResourceTargetLookupListNodeList[i]; - - Vec2i vec = - Vec2i::strToVec2 (cachedCloseResourceTargetLookupListNode-> - getAttribute ("key")->getValue ()); - cachedCloseResourceTargetLookupList[vec] = - cachedCloseResourceTargetLookupListNode->getAttribute ("value")-> - getIntValue () != 0; - } - - random.setLastNumber (factionNode->getAttribute ("random")-> - getIntValue ()); - - vector < XmlNode * >lockedUnitsListNodeList = - factionNode->getChildList ("lockedUnitList"); - for (unsigned int i = 0; i < lockedUnitsListNodeList.size (); ++i) - { - XmlNode *lockedUnitsListNode = lockedUnitsListNodeList[i]; - - string unitName = - lockedUnitsListNode->getAttribute ("value")->getValue (); - lockedUnits.insert (getType ()->getUnitType (unitName)); - } - - vector < XmlNode * >unitsMovingListNodeList = - factionNode->getChildList ("unitsMovingList"); - for (unsigned int i = 0; i < unitsMovingListNodeList.size (); ++i) - { - XmlNode *unitsMovingListNode = unitsMovingListNodeList[i]; - - int unitId = - unitsMovingListNode->getAttribute ("key")->getIntValue (); - unitsMovingList[unitId] = - unitsMovingListNode->getAttribute ("value")->getIntValue (); - } - vector < XmlNode * >unitsPathfindingListNodeList = - factionNode->getChildList ("unitsPathfindingList"); - for (unsigned int i = 0; i < unitsPathfindingListNodeList.size (); - ++i) - { - XmlNode *unitsPathfindingListNode = unitsPathfindingListNodeList[i]; - - int unitId = - unitsPathfindingListNode->getAttribute ("key")->getIntValue (); - unitsPathfindingList[unitId] = - unitsPathfindingListNode->getAttribute ("value")->getIntValue (); - } - } - } - - Checksum Faction::getCRC () - { - const bool consoleDebug = false; - - Checksum crcForFaction; - - // UpgradeManager upgradeManager; - - for (unsigned int i = 0; i < resources.size (); ++i) - { - Resource & resource = resources[i]; - //crcForFaction.addSum(resource.getCRC().getSum()); - uint32 crc = resource.getCRC ().getSum (); - crcForFaction.addBytes (&crc, sizeof (uint32)); - } - - if (consoleDebug) - { - if (getWorld ()->getFrameCount () % 40 == 0) - { - printf ("#1 Frame #: %d Faction: %d CRC: %u\n", - getWorld ()->getFrameCount (), index, - crcForFaction.getSum ()); - } - } - - for (unsigned int i = 0; i < store.size (); ++i) - { - Resource & resource = store[i]; - //crcForFaction.addSum(resource.getCRC().getSum()); - uint32 crc = resource.getCRC ().getSum (); - crcForFaction.addBytes (&crc, sizeof (uint32)); - } - - if (consoleDebug) - { - if (getWorld ()->getFrameCount () % 40 == 0) - { - printf ("#2 Frame #: %d Faction: %d CRC: %u\n", - getWorld ()->getFrameCount (), index, - crcForFaction.getSum ()); - } - } - - for (unsigned int i = 0; i < units.size (); ++i) - { - Unit *unit = units[i]; - //crcForFaction.addSum(unit->getCRC().getSum()); - uint32 crc = unit->getCRC ().getSum (); - crcForFaction.addBytes (&crc, sizeof (uint32)); - } - - if (consoleDebug) - { - if (getWorld ()->getFrameCount () % 40 == 0) - { - printf ("#3 Frame #: %d Faction: %d CRC: %u\n", - getWorld ()->getFrameCount (), index, - crcForFaction.getSum ()); - } - } - - return crcForFaction; - } - - void Faction::addCRC_DetailsForWorldFrame (int worldFrameCount, - bool isNetworkServer) - { - unsigned int MAX_FRAME_CACHE = 250; - if (isNetworkServer == true) - { - MAX_FRAME_CACHE += 250; - } - crcWorldFrameDetails[worldFrameCount] = this->toString (true); - //if(worldFrameCount <= 0) printf("Adding world frame: %d log entries: %lld\n",worldFrameCount,(long long int)crcWorldFrameDetails.size()); - - for (unsigned int i = 0; i < units.size (); ++i) - { - Unit *unit = units[i]; - - unit->getRandom ()->clearLastCaller (); - unit->clearNetworkCRCDecHpList (); - unit->clearParticleInfo (); - } - - if ((unsigned int) crcWorldFrameDetails.size () > MAX_FRAME_CACHE) - { - //printf("===> Removing older world frame log entries: %lld\n",(long long int)crcWorldFrameDetails.size()); - - for (; - (unsigned int) crcWorldFrameDetails.size () - MAX_FRAME_CACHE > - 0;) - { - crcWorldFrameDetails.erase (crcWorldFrameDetails.begin ()); - } - } - } - - string Faction::getCRC_DetailsForWorldFrame (int worldFrameCount) - { - if (crcWorldFrameDetails.empty ()) - { - return ""; - } - return crcWorldFrameDetails[worldFrameCount]; - } - - std::pair < int, - string > - Faction::getCRC_DetailsForWorldFrameIndex (int worldFrameIndex) const - { - if (crcWorldFrameDetails.empty ()) - { - return make_pair < int, string > (0, ""); - } - std::map < int, string >::const_iterator iterMap = - crcWorldFrameDetails.begin (); - std::advance (iterMap, worldFrameIndex); - if (iterMap == crcWorldFrameDetails.end ()) - { - return make_pair < int, string > (0, ""); - } - return std::pair < int, string > (iterMap->first, iterMap->second); - } - - string Faction::getCRC_DetailsForWorldFrames () const - { - string result = ""; - for (std::map < int, string >::const_iterator iterMap = - crcWorldFrameDetails.begin (); - iterMap != crcWorldFrameDetails.end (); ++iterMap) - { - result += - string - ("============================================================================\n"); - result += - string ("** world frame: ") + intToStr (iterMap->first) + - string (" detail: ") + iterMap->second; - } - return result; - } - - uint64 Faction::getCRC_DetailsForWorldFrameCount () const - { - return crcWorldFrameDetails.size (); - } - - } +namespace Glest { + namespace Game { + + bool CommandGroupUnitSorterId::operator () (const int l, const int r) { + const Unit *lUnit = faction->findUnit(l); + const Unit *rUnit = faction->findUnit(r); + + if (!lUnit) { + printf("Error lUnit == NULL for id = %d factionIndex = %d\n", l, + faction->getIndex()); + + for (unsigned int i = 0; i < (unsigned int) faction->getUnitCount(); + ++i) { + printf("%u / %d id = %d [%s]\n", i, faction->getUnitCount(), + faction->getUnit(i)->getId(), + faction->getUnit(i)->getType()->getName(false).c_str()); + } + } + if (!rUnit) { + printf("Error rUnit == NULL for id = %d factionIndex = %d\n", r, + faction->getIndex()); + + for (unsigned int i = 0; i < (unsigned int) faction->getUnitCount(); + ++i) { + printf("%u / %d id = %d [%s]\n", i, faction->getUnitCount(), + faction->getUnit(i)->getId(), + faction->getUnit(i)->getType()->getName(false).c_str()); + } + } + + CommandGroupUnitSorter sorter; + return sorter.compare(lUnit, rUnit); + } + + bool CommandGroupUnitSorter::operator () (const Unit * l, const Unit * r) { + return compare(l, r); + } + + bool CommandGroupUnitSorter::compare(const Unit * l, const Unit * r) { + //printf("l [%p] r [%p] <>",l,r); + + if (!l) { + printf("Error l == NULL\n"); + } + if (!r) { + printf("Error r == NULL\n"); + } + + assert(l && r); + + if (l == NULL || r == NULL) + printf("Unit l [%s - %d] r [%s - %d]\n", + (l != + NULL ? l->getType()->getName(false).c_str() : "null"), + (l != NULL ? l->getId() : -1), + (r != + NULL ? r->getType()->getName(false).c_str() : "null"), + (r != NULL ? r->getId() : -1)); + + + bool result = false; + // If comparer is null or dead + if (r == NULL || r->isAlive() == false) { + // if source is null or dead also + if ((l == NULL || l->isAlive() == false)) { + return false; + } + return true; + } else if ((l == NULL || l->isAlive() == false)) { + return false; + } + + // const Command *command= l->getCurrrentCommandThreadSafe(); + // const Command *commandPeer = r->getCurrrentCommandThreadSafe(); + const Command *command = l->getCurrCommand(); + const Command *commandPeer = r->getCurrCommand(); + + //Command *command= this->unit->getCurrCommand(); + + // Are we moving or attacking + if (command != NULL && command->getCommandType() != NULL && + (command->getCommandType()->getClass() == ccMove || + command->getCommandType()->getClass() == ccAttack) && + command->getUnitCommandGroupId() > 0) { + int curCommandGroupId = command->getUnitCommandGroupId(); + + //Command *commandPeer = j.unit->getCurrrentCommandThreadSafe(); + //Command *commandPeer = j.unit->getCurrCommand(); + + // is comparer a valid command + if (commandPeer == NULL || commandPeer->getCommandType() == NULL) { + result = true; + } + // is comparer command the same type? + else if (commandPeer->getCommandType()->getClass() != + command->getCommandType()->getClass()) { + result = true; + } + // is comparer command groupid invalid? + else if (commandPeer->getUnitCommandGroupId() < 0) { + result = true; + } + // If comparer command group id is less than current group id + else if (curCommandGroupId != commandPeer->getUnitCommandGroupId()) { + result = curCommandGroupId < commandPeer->getUnitCommandGroupId(); + } else { + float unitDist = l->getCenteredPos().dist(command->getPos()); + float unitDistPeer = + r->getCenteredPos().dist(commandPeer->getPos()); + + // Closest unit in commandgroup + result = (unitDist < unitDistPeer); + } + } else if (command == NULL && commandPeer != NULL) { + result = false; + } + // else if(command == NULL && j.unit->getCurrrentCommandThreadSafe() == NULL) { + // return this->unit->getId() < j.unit->getId(); + // } + else { + //Command *commandPeer = j.unit->getCurrrentCommandThreadSafe(); + //if( commandPeer != NULL && commandPeer->getCommandType() != NULL && + // (commandPeer->getCommandType()->getClass() != ccMove && + // commandPeer->getCommandType()->getClass() != ccAttack)) { + result = (l->getId() < r->getId()); + //} + //else { + // result = (l->getId() < r->getId()); + //} + } + + //printf("Sorting, unit [%d - %s] cmd [%s] | unit2 [%d - %s] cmd [%s] result = %d\n",this->unit->getId(),this->unit->getFullName().c_str(),(this->unit->getCurrCommand() == NULL ? "NULL" : this->unit->getCurrCommand()->toString().c_str()),j.unit->getId(),j.unit->getFullName().c_str(),(j.unit->getCurrCommand() == NULL ? "NULL" : j.unit->getCurrCommand()->toString().c_str()),result); + + return result; + } + + void Faction::sortUnitsByCommandGroups() { + MutexSafeWrapper safeMutex(unitsMutex, + string(__FILE__) + "_" + + intToStr(__LINE__)); + //printf("====== sortUnitsByCommandGroups for faction # %d [%s] unitCount = %d\n",this->getIndex(),this->getType()->getName().c_str(),units.size()); + //for(unsigned int i = 0; i < units.size(); ++i) { + // printf("%d / %d [%p] <>",i,units.size(),&units[i]); + // // printf("i = %d [%p]\n",i,&units[i]); + // if(Unit::isUnitDeleted(units[i]) == true) { + // printf("i = %d [%p]\n",i,&units[i]); + // throw megaglest_runtime_error("unit already deleted!"); + // } + //} + //printf("\nSorting\n"); + + //std::sort(units.begin(),units.end(),CommandGroupUnitSorter()); + + //printf("====== Done sorting for faction # %d [%s] unitCount = %d\n",this->getIndex(),this->getType()->getName().c_str(),units.size()); + + //unsigned int originalUnitSize = (unsigned int)units.size(); + + std::vector < int >unitIds; + for (unsigned int i = 0; i < units.size(); ++i) { + int unitId = units[i]->getId(); + if (this->findUnit(unitId) == NULL) { + printf + ("#1 Error unitId not found for id = %d [%s] factionIndex = %d\n", + unitId, units[i]->getType()->getName(false).c_str(), + this->getIndex()); + + for (unsigned int j = 0; j < units.size(); ++j) { + printf("%u / %d id = %d [%s]\n", j, (int) units.size(), + units[j]->getId(), + units[j]->getType()->getName(false).c_str()); + } + } + unitIds.push_back(unitId); + } + CommandGroupUnitSorterId sorter; + sorter.faction = this; + std::stable_sort(unitIds.begin(), unitIds.end(), sorter); + + units.clear(); + for (unsigned int i = 0; i < unitIds.size(); ++i) { + + int unitId = unitIds[i]; + if (this->findUnit(unitId) == NULL) { + printf("#2 Error unitId not found for id = %d factionIndex = %d\n", + unitId, this->getIndex()); + + for (unsigned int j = 0; j < units.size(); ++j) { + printf("%u / %d id = %d [%s]\n", j, (int) units.size(), + units[j]->getId(), + units[j]->getType()->getName(false).c_str()); + } + } + + units.push_back(this->findUnit(unitId)); + } + + //assert(originalUnitSize == units.size()); + } + + // ===================================================== + // class FactionThread + // ===================================================== + + FactionThread::FactionThread(Faction * faction) :BaseThread() { + this->triggerIdMutex = new Mutex(CODE_AT_LINE); + this->faction = faction; + this->masterController = NULL; + uniqueID = "FactionThread"; + } + + FactionThread::~FactionThread() { + this->faction = NULL; + this->masterController = NULL; + delete this->triggerIdMutex; + this->triggerIdMutex = NULL; + } + + void FactionThread::setQuitStatus(bool value) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d value = %d\n", + __FILE__, __FUNCTION__, __LINE__, value); + + BaseThread::setQuitStatus(value); + if (value == true) { + signalPathfinder(-1); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", __FILE__, + __FUNCTION__, __LINE__); + } + + void FactionThread::signalPathfinder(int frameIndex) { + if (frameIndex >= 0) { + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(triggerIdMutex, mutexOwnerId); + this->frameIndex.first = frameIndex; + this->frameIndex.second = false; + + safeMutex.ReleaseLock(); + } + semTaskSignalled.signal(); + } + + void FactionThread::setTaskCompleted(int frameIndex) { + if (frameIndex >= 0) { + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(triggerIdMutex, mutexOwnerId); + if (this->frameIndex.first == frameIndex) { + this->frameIndex.second = true; + } + safeMutex.ReleaseLock(); + } + } + + bool FactionThread::canShutdown(bool deleteSelfIfShutdownDelayed) { + bool ret = (getExecutingTask() == false); + if (ret == false && deleteSelfIfShutdownDelayed == true) { + setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed); + deleteSelfIfRequired(); + signalQuit(); + } + + return ret; + } + + bool FactionThread::isSignalPathfinderCompleted(int frameIndex) { + if (getRunningStatus() == false) { + return true; + } + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(triggerIdMutex, mutexOwnerId); + //bool result = (event != NULL ? event->eventCompleted : true); + bool result = (this->frameIndex.first == frameIndex + && this->frameIndex.second == true); + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] worker thread this = %p, this->frameIndex.first = %d, this->frameIndex.second = %d\n",__FILE__,__FUNCTION__,__LINE__,this,this->frameIndex.first,this->frameIndex.second); + + safeMutex.ReleaseLock(); + return result; + } + + void FactionThread::execute() { + string codeLocation = "1"; + RunningStatusSafeWrapper runningStatus(this); + try { + //setRunningStatus(true); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line: %d] ****************** STARTING worker thread this = %p\n", + __FILE__, __FUNCTION__, __LINE__, this); + + bool minorDebugPerformance = false; + Chrono chrono; + + codeLocation = "2"; + //unsigned int idx = 0; + for (; this->faction != NULL;) { + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + break; + } + + semTaskSignalled.waitTillSignalled(); + + codeLocation = "3"; + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + static string masterSlaveOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MasterSlaveThreadControllerSafeWrapper + safeMasterController(masterController, 20000, + masterSlaveOwnerId); + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + break; + } + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(triggerIdMutex, mutexOwnerId); + bool executeTask = (this->frameIndex.first >= 0); + int currentTriggeredFrameIndex = this->frameIndex.first; + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] frameIndex = %d this = %p executeTask = %d\n",__FILE__,__FUNCTION__,__LINE__,frameIndex.first, this, executeTask); + + safeMutex.ReleaseLock(); + + codeLocation = "5"; + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if (executeTask == true) { + codeLocation = "6"; + ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); + + if (this->faction == NULL) { + throw megaglest_runtime_error("this->faction == NULL"); + } + World *world = this->faction->getWorld(); + if (world == NULL) { + throw megaglest_runtime_error("world == NULL"); + } + + codeLocation = "7"; + //Config &config= Config::getInstance(); + //bool sortedUnitsAllowed = config.getBool("AllowGroupedUnitCommands","true"); + //bool sortedUnitsAllowed = false; + //if(sortedUnitsAllowed == true) { + + /// TODO: Why does this cause and OOS? + //this->faction->sortUnitsByCommandGroups (); + + //} + + codeLocation = "8"; + static string mutexOwnerId2 = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(faction->getUnitMutex(), + mutexOwnerId2); + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + if (minorDebugPerformance) + chrono.start(); + + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + codeLocation = "9"; + int unitCount = this->faction->getUnitCount(); + for (int j = 0; j < unitCount; ++j) { + codeLocation = "10"; + Unit *unit = this->faction->getUnit(j); + if (unit == NULL) { + throw megaglest_runtime_error("unit == NULL"); + } + + codeLocation = "11"; + int64 elapsed1 = 0; + if (minorDebugPerformance) + elapsed1 = chrono.getMillis(); + + bool update = unit->needToUpdate(); + + codeLocation = "12"; + if (minorDebugPerformance + && (chrono.getMillis() - elapsed1) >= 1) + printf + ("Faction [%d - %s] #1-unit threaded updates on frame: %d for [%d] unit # %d, unitCount = %d, took [%lld] msecs\n", + faction->getStartLocationIndex(), + faction->getType()->getName(false).c_str(), + currentTriggeredFrameIndex, + faction->getUnitPathfindingListCount(), j, unitCount, + (long long int) chrono.getMillis() - elapsed1); + + //update = true; + if (update == true) { + codeLocation = "13"; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true) { + int64 updateProgressValue = unit->getUpdateProgress(); + int64 speed = + unit->getCurrSkill()->getTotalSpeed(unit-> + getTotalUpgrade()); + int64 df = unit->getDiagonalFactor(); + int64 hf = unit->getHeightFactor(); + bool changedActiveCommand = unit->isChangedActiveCommand(); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "unit->needToUpdate() returned: %d updateProgressValue: %lld speed: %lld changedActiveCommand: %d df: %lld hf: %lld", + update, (long long int) updateProgressValue, + (long long int) speed, changedActiveCommand, + (long long int) df, (long long int) hf); + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } + + int64 elapsed2 = 0; + if (minorDebugPerformance) + elapsed2 = chrono.getMillis(); + + if (world->getUnitUpdater() == NULL) { + throw + megaglest_runtime_error + ("world->getUnitUpdater() == NULL"); + } + + world->getUnitUpdater()->updateUnitCommand(unit, + currentTriggeredFrameIndex); + + codeLocation = "15"; + if (minorDebugPerformance + && (chrono.getMillis() - elapsed2) >= 1) + printf + ("Faction [%d - %s] #2-unit threaded updates on frame: %d for [%d] unit # %d, unitCount = %d, took [%lld] msecs\n", + faction->getStartLocationIndex(), + faction->getType()->getName(false).c_str(), + currentTriggeredFrameIndex, + faction->getUnitPathfindingListCount(), j, unitCount, + (long long int) chrono.getMillis() - elapsed2); + } else { + codeLocation = "16"; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true) { + int64 updateProgressValue = unit->getUpdateProgress(); + int64 speed = + unit->getCurrSkill()->getTotalSpeed(unit-> + getTotalUpgrade()); + int64 df = unit->getDiagonalFactor(); + int64 hf = unit->getHeightFactor(); + bool changedActiveCommand = unit->isChangedActiveCommand(); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "unit->needToUpdate() returned: %d updateProgressValue: %lld speed: %lld changedActiveCommand: %d df: %lld hf: %lld", + update, (long long int) updateProgressValue, + (long long int) speed, changedActiveCommand, + (long long int) df, (long long int) hf); + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } + } + } + + codeLocation = "17"; + if (minorDebugPerformance && chrono.getMillis() >= 1) + printf + ("Faction [%d - %s] threaded updates on frame: %d for [%d] units took [%lld] msecs\n", + faction->getStartLocationIndex(), + faction->getType()->getName(false).c_str(), + currentTriggeredFrameIndex, + faction->getUnitPathfindingListCount(), + (long long int) chrono.getMillis()); + + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + safeMutex.ReleaseLock(); + + codeLocation = "18"; + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + setTaskCompleted(currentTriggeredFrameIndex); + + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + codeLocation = "19"; + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + break; + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("In [%s::%s Line: %d] ****************** ENDING worker thread this = %p\n", + __FILE__, __FUNCTION__, __LINE__, this); + } catch (const exception & ex) { + //setRunningStatus(false); + + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Loc [%s] Error [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + codeLocation.c_str(), ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + throw megaglest_runtime_error(ex.what()); + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error Loc [%s]\n", + __FILE__, __FUNCTION__, __LINE__, codeLocation.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s] Line: %d\n", __FILE__, + __FUNCTION__, __LINE__); + } + + + // ===================================================== + // class Faction + // ===================================================== + + Faction::Faction() { + init(); + } + + void Faction::init() { + unitsMutex = new Mutex(CODE_AT_LINE); + texture = NULL; + //lastResourceTargettListPurge = 0; + cachingDisabled = false; + factionDisconnectHandled = false; + workerThread = NULL; + + world = NULL; + scriptManager = NULL; + factionType = NULL; + index = 0; + teamIndex = 0; + startLocationIndex = 0; + thisFaction = false; + currentSwitchTeamVoteFactionIndex = -1; + allowSharedTeamUnits = false; + + loadWorldNode = NULL; + techTree = NULL; + + control = ctClosed; + + overridePersonalityType = fpt_EndCount; + + upgradeManager = UpgradeManager(); + } + + Faction::~Faction() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + //Renderer &renderer= Renderer::getInstance(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + //renderer.endTexture(rsGame,texture); + //texture->end(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + if (workerThread != NULL) { + workerThread->signalQuit(); + if (workerThread->shutdownAndWait() == true) { + delete workerThread; + } + workerThread = NULL; + } + + MutexSafeWrapper safeMutex(unitsMutex, + string(__FILE__) + "_" + + intToStr(__LINE__)); + deleteValues(units.begin(), units.end()); + units.clear(); + + safeMutex.ReleaseLock(); + + //delete texture; + texture = NULL; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + delete unitsMutex; + unitsMutex = NULL; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + void Faction::end() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + if (workerThread != NULL) { + workerThread->signalQuit(); + if (workerThread->shutdownAndWait() == true) { + delete workerThread; + } + workerThread = NULL; + } + + MutexSafeWrapper safeMutex(unitsMutex, + string(__FILE__) + "_" + + intToStr(__LINE__)); + deleteValues(units.begin(), units.end()); + units.clear(); + + safeMutex.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + void Faction::notifyUnitAliveStatusChange(const Unit * unit) { + if (unit != NULL) { + if (unit->isAlive() == true) { + aliveUnitListCache[unit->getId()] = unit; + + if (unit->getType()->isMobile() == true) { + mobileUnitListCache[unit->getId()] = unit; + } + } else { + aliveUnitListCache.erase(unit->getId()); + mobileUnitListCache.erase(unit->getId()); + beingBuiltUnitListCache.erase(unit->getId()); + } + } + } + + void Faction::notifyUnitTypeChange(const Unit * unit, + const UnitType * newType) { + if (unit != NULL) { + if (unit->getType()->isMobile() == true) { + mobileUnitListCache.erase(unit->getId()); + } + + if (newType != NULL && newType->isMobile() == true) { + mobileUnitListCache[unit->getId()] = unit; + } + } + } + + void Faction::notifyUnitSkillTypeChange(const Unit * unit, + const SkillType * newType) { + if (unit != NULL) { + if (unit->isBeingBuilt() == true) { + beingBuiltUnitListCache.erase(unit->getId()); + } + if (newType != NULL && newType->getClass() == scBeBuilt) { + beingBuiltUnitListCache[unit->getId()] = unit; + } + } + } + + bool Faction::hasAliveUnits(bool filterMobileUnits, + bool filterBuiltUnits) const { + bool result = false; + if (aliveUnitListCache.empty() == false) { + if (filterMobileUnits == true) { + result = (mobileUnitListCache.empty() == false); + } else { + result = true; + } + + if (result == true && filterBuiltUnits == true) { + result = (beingBuiltUnitListCache.empty() == true); + } + } + return result; + } + + FactionPersonalityType Faction::getPersonalityType() const { + if (overridePersonalityType != fpt_EndCount) { + return overridePersonalityType; + } + return factionType->getPersonalityType(); + } + + int Faction:: + getAIBehaviorStaticOverideValue(AIBehaviorStaticValueCategory type) + const { + return factionType->getAIBehaviorStaticOverideValue(type); + } + + void Faction::addUnitToMovingList(int unitId) { + unitsMovingList[unitId] = getWorld()->getFrameCount(); + } + void Faction::removeUnitFromMovingList(int unitId) { + unitsMovingList.erase(unitId); + } + + //int Faction::getUnitMovingListCount() { + // return (int)unitsMovingList.size(); + //} + + void Faction::addUnitToPathfindingList(int unitId) { + //printf("ADD (1) Faction [%d - %s] threaded updates for [%d] units\n",this->getStartLocationIndex(),this->getType()->getName().c_str(),unitsPathfindingList.size()); + unitsPathfindingList[unitId] = getWorld()->getFrameCount(); + //printf("ADD (2) Faction [%d - %s] threaded updates for [%d] units\n",this->getStartLocationIndex(),this->getType()->getName().c_str(),unitsPathfindingList.size()); + } + //void Faction::removeUnitFromPathfindingList(int unitId) { + // unitsPathfindingList.erase(unitId); + //} + + int Faction::getUnitPathfindingListCount() { + //printf("GET Faction [%d - %s] threaded updates for [%d] units\n",this->getStartLocationIndex(),this->getType()->getName().c_str(),unitsPathfindingList.size()); + return (int) unitsPathfindingList.size(); + } + + void Faction::clearUnitsPathfinding() { + //printf("CLEAR Faction [%d - %s] threaded updates for [%d] units\n",this->getStartLocationIndex(),this->getType()->getName().c_str(),unitsPathfindingList.size()); + if (unitsPathfindingList.empty() == false) { + unitsPathfindingList.clear(); + } + } + + bool Faction::canUnitsPathfind() { + bool result = true; + if (control == ctCpuEasy || control == ctCpu || + control == ctCpuUltra || control == ctCpuZeta) { + //printf("AI player for faction index: %d (%s) current pathfinding: %d\n",index,factionType->getName().c_str(),getUnitPathfindingListCount()); + + const int MAX_UNITS_PATHFINDING_PER_FRAME = 10; + result = + (getUnitPathfindingListCount() <= MAX_UNITS_PATHFINDING_PER_FRAME); + if (result == false) { + //printf("WARNING limited AI player for faction index: %d (%s) current pathfinding: %d\n",index,factionType->getName().c_str(),getUnitPathfindingListCount()); + } + } + return result; + } + + void Faction::setLockedUnitForFaction(const UnitType * ut, bool lock) { + if (lock) { + lockedUnits.insert(ut); + } else { + std::set < const UnitType *>::iterator it; + it = lockedUnits.find(ut); + if (it != lockedUnits.end()) { + lockedUnits.erase(it); + } + } + + } + + void Faction::signalWorkerThread(int frameIndex) { + if (workerThread != NULL) { + workerThread->signalPathfinder(frameIndex); + } + } + + bool Faction::isWorkerThreadSignalCompleted(int frameIndex) { + if (workerThread != NULL) { + return workerThread->isSignalPathfinderCompleted(frameIndex); + } + return true; + } + + + void Faction::init(FactionType * factionType, ControlType control, + TechTree * techTree, Game * game, int factionIndex, + int teamIndex, int startLocationIndex, + bool thisFaction, bool giveResources, + const XmlNode * loadWorldNode) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + this->techTree = techTree; + this->loadWorldNode = loadWorldNode; + this->control = control; + this->factionType = factionType; + this->startLocationIndex = startLocationIndex; + this->index = factionIndex; + this->teamIndex = teamIndex; + this->thisFaction = thisFaction; + this->world = game->getWorld(); + this->scriptManager = game->getScriptManager(); + //cachingDisabled = (Config::getInstance().getBool("DisableCaching","false") == true); + cachingDisabled = false; + + resources.resize(techTree->getResourceTypeCount()); + store.resize(techTree->getResourceTypeCount()); + + if (loadWorldNode == NULL) { + for (int index = 0; index < techTree->getResourceTypeCount(); + ++index) { + const ResourceType *rt = techTree->getResourceType(index); + int resourceAmount = + giveResources ? factionType->getStartingResourceAmount(rt) : 0; + resources[index].init(rt, resourceAmount); + store[index].init(rt, 0); + + this->world->initTeamResource(rt, this->teamIndex, 0); + } + } + //initialize cache + for (int index = 0; index < techTree->getResourceTypeCount(); ++index) { + const ResourceType *rt = techTree->getResourceType(index); + this->updateUnitTypeWithResourceCostCache(rt); + } + + texture = Renderer::getInstance().newTexture2D(rsGame); + string data_path = + getGameReadWritePath(GameConstants::path_data_CacheLookupKey); + if (texture) { + string playerTexture = + getGameCustomCoreDataPath(data_path, + "data/core/faction_textures/faction" + + intToStr(startLocationIndex) + ".tga"); + texture->load(playerTexture); + } + + if (loadWorldNode != NULL) { + loadGame(loadWorldNode, this->index, game->getGameSettings(), + game->getWorld()); + } + + if (game->getGameSettings()->getPathFinderType() == pfBasic) { + if (workerThread != NULL) { + workerThread->signalQuit(); + if (workerThread->shutdownAndWait() == true) { + delete workerThread; + } + workerThread = NULL; + } + static string mutexOwnerId = + string(extractFileFromDirectoryPath(__FILE__).c_str()) + + string("_") + intToStr(__LINE__); + this->workerThread = new FactionThread(this); + this->workerThread->setUniqueID(mutexOwnerId); + this->workerThread->start(); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + // ================== get ================== + + bool Faction::hasUnitTypeWithResourceCostInCache(const ResourceType * rt) const { + std::string resourceTypeName = rt->getName(false); + std::map < std::string, bool >::const_iterator iterFind = + resourceTypeCostCache.find(resourceTypeName); + if (iterFind != resourceTypeCostCache.end()) { + return iterFind->second; + } + return false; + } + void Faction::updateUnitTypeWithResourceCostCache(const ResourceType * + rt) { + std::string resourceTypeName = rt->getName(false); + + if (resourceTypeCostCache.find(resourceTypeName) == + resourceTypeCostCache.end()) { + resourceTypeCostCache[resourceTypeName] = + hasUnitTypeWithResouceCost(rt); + } + } + + bool Faction::hasUnitTypeWithResouceCost(const ResourceType * rt) { + for (int factionUnitTypeIndex = 0; + factionUnitTypeIndex < getType()->getUnitTypeCount(); + ++factionUnitTypeIndex) { + + const UnitType *ut = getType()->getUnitType(factionUnitTypeIndex); + if (ut->getCost(rt) != NULL) { + return true; + } + } + return false; + } + + const Resource *Faction::getResource(const ResourceType * rt, + bool localFactionOnly) const { + + if (localFactionOnly == false && + world != NULL && world->getGame() != NULL) { + + Game *game = world->getGame(); + if (game->isFlagType1BitEnabled(ft1_allow_shared_team_resources) == + true) { + return world->getResourceForTeam(rt, this->getTeam()); + } + } + + for (int index = 0; index < (int) resources.size(); ++index) { + if (rt == resources[index].getType()) { + return &resources[index]; + } + } + + printf("ERROR cannot find resource type [%s] in list:\n", + (rt != NULL ? rt->getName().c_str() : "null")); + for (int i = 0; i < (int) resources.size(); ++i) { + printf("Index %d [%s]", i, + resources[i].getType()->getName().c_str()); + } + + assert(false); + return NULL; + } + + int Faction::getStoreAmount(const ResourceType * rt, + bool localFactionOnly) const { + + if (localFactionOnly == false && + world != NULL && world->getGame() != NULL) { + + Game *game = world->getGame(); + if (game->isFlagType1BitEnabled(ft1_allow_shared_team_resources) == + true) { + return world->getStoreAmountForTeam(rt, this->getTeam()); + } + } + + for (int index = 0; index < (int) store.size(); ++index) { + if (rt == store[index].getType()) { + return store[index].getAmount(); + } + } + printf("ERROR cannot find store type [%s] in list:\n", + (rt != NULL ? rt->getName().c_str() : "null")); + for (int i = 0; i < (int) store.size(); ++i) { + printf("Index %d [%s]", i, store[i].getType()->getName().c_str()); + } + + assert(false); + return 0; + } + + bool Faction::getCpuControl(bool enableServerControlledAI, + bool isNetworkGame, NetworkRole role) const { + bool result = false; + if (enableServerControlledAI == false || isNetworkGame == false) { + result = (control == ctCpuEasy || control == ctCpu + || control == ctCpuUltra || control == ctCpuZeta); + } else { + if (isNetworkGame == true) { + if (role == nrServer) { + result = (control == ctCpuEasy || control == ctCpu + || control == ctCpuUltra || control == ctCpuZeta); + } else { + result = (control == ctNetworkCpuEasy || control == ctNetworkCpu + || control == ctNetworkCpuUltra + || control == ctNetworkCpuZeta); + } + } + } + + return result; + } + + bool Faction::getCpuControl() const { + return control == ctCpuEasy || control == ctCpu || control == ctCpuUltra + || control == ctCpuZeta || control == ctNetworkCpuEasy + || control == ctNetworkCpu || control == ctNetworkCpuUltra + || control == ctNetworkCpuZeta; + } + + // ==================== upgrade manager ==================== + + void Faction::startUpgrade(const UpgradeType * ut) { + upgradeManager.startUpgrade(ut, index); + } + + void Faction::cancelUpgrade(const UpgradeType * ut) { + upgradeManager.cancelUpgrade(ut); + } + + void Faction::finishUpgrade(const UpgradeType * ut) { + upgradeManager.finishUpgrade(ut); + if (world->getThisFaction() != NULL + && this->getIndex() == world->getThisFaction()->getIndex()) { + Console *console = world->getGame()->getConsole(); + console->addStdMessage("UpgradeFinished", + ": " + formatString(ut->getName(true))); + } + for (int i = 0; i < getUnitCount(); ++i) { + getUnit(i)->applyUpgrade(ut); + } + } + + // ==================== reqs ==================== + + //checks if all required units and upgrades are present and maxUnitCount is within limit + bool Faction::reqsOk(const RequirableType * rt) const { + assert(rt != NULL); + //required units + for (int i = 0; i < rt->getUnitReqCount(); ++i) { + bool found = false; + for (int j = 0; j < getUnitCount(); ++j) { + Unit *unit = getUnit(j); + const UnitType *ut = unit->getType(); + if (rt->getUnitReq(i) == ut && unit->isOperative()) { + found = true; + break; + } + } + if (found == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + return false; + } + } + + //required upgrades + for (int i = 0; i < rt->getUpgradeReqCount(); ++i) { + if (upgradeManager.isUpgraded(rt->getUpgradeReq(i)) == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + return false; + } + } + + if (dynamic_cast (rt) != NULL) { + const UnitType *producedUnitType = + dynamic_cast (rt); + if (producedUnitType != NULL + && producedUnitType->getMaxUnitCount() > 0) { + if (producedUnitType->getMaxUnitCount() <= + getCountForMaxUnitCount(producedUnitType)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + return false; + } + } + + if (producedUnitType != NULL && isUnitLocked(producedUnitType)) { + return false; + } + } + + return true; + } + + int Faction::getCountForMaxUnitCount(const UnitType * unitType) const { + int count = 0; + //calculate current unit count + for (int j = 0; j < getUnitCount(); ++j) { + Unit *unit = getUnit(j); + const UnitType *currentUt = unit->getType(); + if (unitType == currentUt && unit->isOperative()) { + count++; + } + //check if there is any command active which already produces this unit + count = count + unit->getCountOfProducedUnits(unitType); + } + return count; + } + + + bool Faction::reqsOk(const CommandType * ct) const { + assert(ct != NULL); + if (ct == NULL) { + throw megaglest_runtime_error("In [Faction::reqsOk] ct == NULL"); + } + + if (ct->getProduced() != NULL && reqsOk(ct->getProduced()) == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] reqsOk FAILED\n", + __FILE__, __FUNCTION__, __LINE__); + return false; + } + + if (ct->getClass() == ccUpgrade) { + const UpgradeCommandType *uct = + static_cast (ct); + if (upgradeManager.isUpgradingOrUpgraded(uct->getProducedUpgrade())) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] upgrade check FAILED\n", + __FILE__, __FUNCTION__, __LINE__); + return false; + } + } + + return reqsOk(static_cast (ct)); + } + + // ================== cost application ================== + + //apply costs except static production (start building/production) + bool Faction::applyCosts(const ProducibleType * p, + const CommandType * ct) { + bool ignoreResourceCosts = false; + if (ct != NULL && ct->getClass() == ccMorph) { + const MorphCommandType *mct = + dynamic_cast (ct); + if (mct != NULL) { + ignoreResourceCosts = mct->getIgnoreResourceRequirements(); + } + } + + if (ignoreResourceCosts == false) { + if (checkCosts(p, ct) == false) { + return false; + } + + assert(p != NULL); + //for each unit cost spend it + //pass 2, decrease resources, except negative static costs (ie: farms) + for (int i = 0; i < p->getCostCount(); ++i) { + const Resource *r = p->getCost(i); + if (r == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "cannot apply costs for p [%s] %d of %d costs resource is null", + p->getName(false).c_str(), i, p->getCostCount()); + throw megaglest_runtime_error(szBuf); + } + + const ResourceType *rt = r->getType(); + if (rt == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "cannot apply costs for p [%s] %d of %d costs resourcetype [%s] is null", + p->getName(false).c_str(), i, p->getCostCount(), + r->getDescription(false).c_str()); + throw megaglest_runtime_error(szBuf); + } + int cost = r->getAmount(); + if ((cost > 0 || (rt->getClass() != rcStatic)) + && rt->getClass() != rcConsumable) { + incResourceAmount(rt, -(cost)); + } + + } + } + return true; + } + + //apply discount (when a morph ends) + void Faction::applyDiscount(const ProducibleType * p, int discount) { + assert(p != NULL); + //increase resources + for (int i = 0; i < p->getCostCount(); ++i) { + const ResourceType *rt = p->getCost(i)->getType(); + assert(rt != NULL); + int cost = p->getCost(i)->getAmount(); + if ((cost > 0 || (rt->getClass() != rcStatic)) + && rt->getClass() != rcConsumable) { + incResourceAmount(rt, cost * discount / 100); + } + } + } + + //apply static production (for starting units) + void Faction::applyStaticCosts(const ProducibleType * p, + const CommandType * ct) { + assert(p != NULL); + bool ignoreResourceCosts = false; + if (ct != NULL && ct->getClass() == ccMorph) { + const MorphCommandType *mct = + dynamic_cast (ct); + if (mct != NULL) { + ignoreResourceCosts = mct->getIgnoreResourceRequirements(); + } + } + + if (ignoreResourceCosts == false) { + //decrease static resources + for (int i = 0; i < p->getCostCount(); ++i) { + const ResourceType *rt = p->getCost(i)->getType(); + //assert(rt != NULL); + if (rt == NULL) { + throw megaglest_runtime_error(string(__FUNCTION__) + + " rt == NULL for ProducibleType [" + + p->getName(false) + + "] index: " + intToStr(i)); + } + if (rt->getClass() == rcStatic) { + int cost = p->getCost(i)->getAmount(); + if (cost > 0) { + incResourceAmount(rt, -cost); + } + } + } + } + } + + //apply static production (when a mana source is done) + void Faction::applyStaticProduction(const ProducibleType * p, + const CommandType * ct) { + assert(p != NULL); + + bool ignoreResourceCosts = false; + if (ct != NULL && ct->getClass() == ccMorph) { + const MorphCommandType *mct = + dynamic_cast (ct); + if (mct != NULL) { + ignoreResourceCosts = mct->getIgnoreResourceRequirements(); + } + } + + if (ignoreResourceCosts == false) { + //decrease static resources + for (int i = 0; i < p->getCostCount(); ++i) { + const ResourceType *rt = p->getCost(i)->getType(); + assert(rt != NULL); + if (rt->getClass() == rcStatic) { + int cost = p->getCost(i)->getAmount(); + if (cost < 0) { + incResourceAmount(rt, -cost); + } + } + } + } + } + + //deapply all costs except static production (usually when a building is cancelled) + void Faction::deApplyCosts(const ProducibleType * p, + const CommandType * ct) { + assert(p != NULL); + + bool ignoreResourceCosts = false; + if (ct != NULL && ct->getClass() == ccMorph) { + const MorphCommandType *mct = + dynamic_cast (ct); + if (mct != NULL) { + ignoreResourceCosts = mct->getIgnoreResourceRequirements(); + } + } + + if (ignoreResourceCosts == false) { + //increase resources + for (int i = 0; i < p->getCostCount(); ++i) { + const ResourceType *rt = p->getCost(i)->getType(); + assert(rt != NULL); + int cost = p->getCost(i)->getAmount(); + if ((cost > 0 || (rt->getClass() != rcStatic)) + && rt->getClass() != rcConsumable) { + incResourceAmount(rt, cost); + } + } + } + } + + //deapply static costs (usually when a unit dies) + void Faction::deApplyStaticCosts(const ProducibleType * p, + const CommandType * ct) { + assert(p != NULL); + + bool ignoreResourceCosts = false; + if (ct != NULL && ct->getClass() == ccMorph) { + const MorphCommandType *mct = + dynamic_cast (ct); + if (mct != NULL) { + ignoreResourceCosts = mct->getIgnoreResourceRequirements(); + } + } + + if (ignoreResourceCosts == false) { + //decrease resources + for (int i = 0; i < p->getCostCount(); ++i) { + const ResourceType *rt = p->getCost(i)->getType(); + assert(rt != NULL); + if (rt->getClass() == rcStatic) { + if (rt->getRecoup_cost() == true) { + int cost = p->getCost(i)->getAmount(); + incResourceAmount(rt, cost); + } + } + } + } + } + + //deapply static costs, but not negative costs, for when building gets killed + void Faction::deApplyStaticConsumption(const ProducibleType * p, + const CommandType * ct) { + assert(p != NULL); + + bool ignoreResourceCosts = false; + if (ct != NULL && ct->getClass() == ccMorph) { + const MorphCommandType *mct = + dynamic_cast (ct); + if (mct != NULL) { + ignoreResourceCosts = mct->getIgnoreResourceRequirements(); + } + } + + if (ignoreResourceCosts == false) { + //decrease resources + for (int i = 0; i < p->getCostCount(); ++i) { + const ResourceType *rt = p->getCost(i)->getType(); + assert(rt != NULL); + if (rt->getClass() == rcStatic) { + int cost = p->getCost(i)->getAmount(); + if (cost > 0) { + incResourceAmount(rt, cost); + } + } + } + } + } + + //apply resource on interval (cosumable resouces) + void Faction::applyCostsOnInterval(const ResourceType * rtApply) { + + // For each Resource type we store in the int a total consumed value, then + // a vector of units that consume the resource type + std::map < const ResourceType *, std::pair < int, + std::vector > >resourceIntervalUsage; + + // count up consumables usage for the interval + for (int j = 0; j < getUnitCount(); ++j) { + Unit *unit = getUnit(j); + if (unit->isOperative() == true) { + for (int k = 0; k < unit->getType()->getCostCount(); ++k) { + const Resource *resource = unit->getType()->getCost(k); + if (resource->getType() == rtApply + && resource->getType()->getClass() == rcConsumable + && resource->getAmount() != 0) { + if (resourceIntervalUsage.find(resource->getType()) == + resourceIntervalUsage.end()) { + resourceIntervalUsage[resource->getType()] = + make_pair < int, std::vector >(0, + std::vector < + Unit * >()); + } + // Negative cost means accumulate the resource type + resourceIntervalUsage[resource->getType()].first += + -resource->getAmount(); + + // If the cost > 0 then the unit is a consumer + if (resource->getAmount() > 0) { + resourceIntervalUsage[resource->getType()].second. + push_back(unit); + } + } + } + } + } + + // Apply consumable resource usage + if (resourceIntervalUsage.empty() == false) { + for (std::map < const ResourceType *, std::pair < int, + std::vector < Unit * > > >::iterator iter = + resourceIntervalUsage.begin(); + iter != resourceIntervalUsage.end(); ++iter) { + // Apply resource type usage to faction resource store + const ResourceType *rt = iter->first; + int resourceTypeUsage = iter->second.first; + incResourceAmount(rt, resourceTypeUsage); + + // Check if we have any unit consumers + if (getResource(rt)->getAmount() < 0) { + resetResourceAmount(rt); + + // Apply consequences to consumer units of this resource type + std::vector < Unit * >&resourceConsumers = iter->second.second; + + for (int i = 0; i < (int) resourceConsumers.size(); ++i) { + Unit *unit = resourceConsumers[i]; + + //decrease unit hp + if (scriptManager->getPlayerModifiers(this->index)-> + getConsumeEnabled() == true) { + bool decHpResult = + unit->decHp(unit->getType()-> + getTotalMaxHp(unit->getTotalUpgrade()) / 3); + if (decHpResult) { + unit->setCauseOfDeath(ucodStarvedResource); + world->getStats()->die(unit->getFactionIndex(), + unit->getType()-> + getCountUnitDeathInStats()); + scriptManager->onUnitDied(unit); + } + StaticSound *sound = + static_cast < + const DieSkillType * + >(unit->getType()->getFirstStOfClass(scDie))->getSound(); + if (sound != NULL + && (thisFaction == true + || world->showWorldForPlayer(world-> + getThisTeamIndex()) == + true)) { + SoundRenderer::getInstance().playFx(sound); + } + } + } + } + } + } + } + + bool Faction::checkCosts(const ProducibleType * pt, + const CommandType * ct) { + assert(pt != NULL); + + bool ignoreResourceCosts = false; + if (ct != NULL && ct->getClass() == ccMorph) { + const MorphCommandType *mct = + dynamic_cast (ct); + if (mct != NULL) { + ignoreResourceCosts = mct->getIgnoreResourceRequirements(); + } + //printf("Checking costs = %d for commandtype:\n%s\n",ignoreResourceCosts,mct->getDesc(NULL).c_str()); + } + + if (ignoreResourceCosts == false) { + //for each unit cost check if enough resources + for (int i = 0; i < pt->getCostCount(); ++i) { + const ResourceType *rt = pt->getCost(i)->getType(); + int cost = pt->getCost(i)->getAmount(); + if (cost > 0) { + int available = getResource(rt)->getAmount(); + if (cost > available) { + return false; + } + } + } + } + + return true; + } + + // ================== diplomacy ================== + + bool Faction::isAlly(const Faction * faction) { + assert(faction != NULL); + return (teamIndex == faction->getTeam() || + faction->getTeam() == + GameConstants::maxPlayers - 1 + fpt_Observer); + } + + // ================== misc ================== + + void Faction::incResourceAmount(const ResourceType * rt, int amount) { + if (world != NULL && world->getGame() != NULL + && world->getGame()-> + isFlagType1BitEnabled(ft1_allow_shared_team_resources) == true) { + for (int i = 0; i < (int) resources.size(); ++i) { + Resource *r = &resources[i]; + if (r->getType() == rt) { + r->setAmount(r->getAmount() + amount); + if (r->getType()->getClass() != rcStatic + && (getResource(rt, false)->getAmount() + amount) > + getStoreAmount(rt, false)) { + r->setAmount(getStoreAmount(rt, false) - + (getResource(rt, false)->getAmount() - + r->getAmount())); + } + return; + } + } + } else { + for (int i = 0; i < (int) resources.size(); ++i) { + Resource *r = &resources[i]; + if (r->getType() == rt) { + r->setAmount(r->getAmount() + amount); + if (r->getType()->getClass() != rcStatic + && r->getAmount() > getStoreAmount(rt)) { + r->setAmount(getStoreAmount(rt)); + } + return; + } + } + } + assert(false); + } + + void Faction::setResourceBalance(const ResourceType * rt, int balance) { + for (int i = 0; i < (int) resources.size(); ++i) { + Resource *r = &resources[i]; + if (r->getType() == rt) { + r->setBalance(balance); + return; + } + } + assert(false); + } + + Unit *Faction::findUnit(int id) const { + UnitMap::const_iterator itFound = unitMap.find(id); + if (itFound == unitMap.end()) { + return NULL; + } + return itFound->second; + } + + void Faction::addUnit(Unit * unit) { + MutexSafeWrapper safeMutex(unitsMutex, + string(__FILE__) + "_" + + intToStr(__LINE__)); + units.push_back(unit); + unitMap[unit->getId()] = unit; + } + + void Faction::removeUnit(Unit * unit) { + MutexSafeWrapper safeMutex(unitsMutex, + string(__FILE__) + "_" + + intToStr(__LINE__)); + + assert(units.size() == unitMap.size()); + + int unitId = unit->getId(); + for (int i = 0; i < (int) units.size(); ++i) { + if (units[i]->getId() == unitId) { + units.erase(units.begin() + i); + unitMap.erase(unitId); + assert(units.size() == unitMap.size()); + return; + } + } + + throw megaglest_runtime_error("Could not remove unit from faction!"); + //assert(false); + } + + void Faction::addStore(const UnitType * unitType) { + assert(unitType != NULL); + for (int newUnitStoredResourceIndex = 0; + newUnitStoredResourceIndex < unitType->getStoredResourceCount(); + ++newUnitStoredResourceIndex) { + const Resource *newUnitStoredResource = + unitType->getStoredResource(newUnitStoredResourceIndex); + + for (int currentStoredResourceIndex = 0; + currentStoredResourceIndex < (int) store.size(); + ++currentStoredResourceIndex) { + Resource *storedResource = &store[currentStoredResourceIndex]; + + if (storedResource->getType() == newUnitStoredResource->getType()) { + storedResource->setAmount(storedResource->getAmount() + + newUnitStoredResource->getAmount()); + } + } + } + } + + void Faction::removeStore(const UnitType * unitType) { + assert(unitType != NULL); + for (int i = 0; i < unitType->getStoredResourceCount(); ++i) { + const Resource *r = unitType->getStoredResource(i); + for (int j = 0; j < (int) store.size(); ++j) { + Resource *storedResource = &store[j]; + if (storedResource->getType() == r->getType()) { + storedResource->setAmount(storedResource->getAmount() - + r->getAmount()); + } + } + } + limitResourcesToStore(); + } + + void Faction::limitResourcesToStore() { + if (world != NULL && world->getGame() != NULL + && world->getGame()-> + isFlagType1BitEnabled(ft1_allow_shared_team_resources) == true) { + for (int i = 0; i < (int) resources.size(); ++i) { + Resource *r = &resources[i]; + const ResourceType *rt = r->getType(); + if (rt->getClass() != rcStatic + && (getResource(rt, false)->getAmount()) > getStoreAmount(rt, + false)) { + r->setAmount(getStoreAmount(rt, false) - + (getResource(rt, false)->getAmount() - + r->getAmount())); + } + } + } else { + for (int i = 0; i < (int) resources.size(); ++i) { + Resource *r = &resources[i]; + Resource *s = &store[i]; + if (r->getType()->getClass() != rcStatic + && r->getAmount() > s->getAmount()) { + r->setAmount(s->getAmount()); + } + } + } + } + + void Faction::resetResourceAmount(const ResourceType * rt) { + for (int i = 0; i < (int) resources.size(); ++i) { + if (resources[i].getType() == rt) { + resources[i].setAmount(0); + return; + } + } + assert(false); + } + + bool Faction::isResourceTargetInCache(const Vec2i & pos, + bool incrementUseCounter) { + bool result = false; + + if (cachingDisabled == false) { + if (cacheResourceTargetList.empty() == false) { + std::map < Vec2i, int >::iterator iter = + cacheResourceTargetList.find(pos); + + result = (iter != cacheResourceTargetList.end()); + if (result == true && incrementUseCounter == true) { + iter->second++; + } + } + } + + return result; + } + + void Faction::addResourceTargetToCache(const Vec2i & pos, + bool incrementUseCounter) { + if (cachingDisabled == false) { + + bool duplicateEntry = + isResourceTargetInCache(pos, incrementUseCounter); + //bool duplicateEntry = false; + + if (duplicateEntry == false) { + cacheResourceTargetList[pos] = 1; + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "[addResourceTargetToCache] pos [%s]cacheResourceTargetList.size() [" + MG_SIZE_T_SPECIFIER "]", pos.getString().c_str(), + cacheResourceTargetList.size()); + + //unit->logSynchData(szBuf); + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "----------------------------------- START [%d] ------------------------------------------------\n", + getFrameCount()); + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "[%s::%d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, "%s\n", + szBuf); + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "------------------------------------ END [%d] -------------------------------------------------\n", + getFrameCount()); + } + } + } + } + + void Faction::removeResourceTargetFromCache(const Vec2i & pos) { + if (cachingDisabled == false) { + if (cacheResourceTargetList.empty() == false) { + std::map < Vec2i, int >::iterator iter = + cacheResourceTargetList.find(pos); + + if (iter != cacheResourceTargetList.end()) { + cacheResourceTargetList.erase(pos); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "[removeResourceTargetFromCache] pos [%s]cacheResourceTargetList.size() [" + MG_SIZE_T_SPECIFIER "]", pos.getString().c_str(), + cacheResourceTargetList.size()); + + //unit->logSynchData(szBuf); + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "----------------------------------- START [%d] ------------------------------------------------\n", + getFrameCount()); + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "[%s::%d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, "%s\n", + szBuf); + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "------------------------------------ END [%d] -------------------------------------------------\n", + getFrameCount()); + } + } + } + } + } + + void Faction::addCloseResourceTargetToCache(const Vec2i & pos) { + if (cachingDisabled == false) { + if (cachedCloseResourceTargetLookupList.find(pos) == + cachedCloseResourceTargetLookupList.end()) { + const Map *map = world->getMap(); + const int harvestDistance = 5; + + for (int j = -harvestDistance; j <= harvestDistance; ++j) { + for (int k = -harvestDistance; k <= harvestDistance; ++k) { + Vec2i newPos = pos + Vec2i(j, k); + if (isResourceTargetInCache(newPos) == false) { + if (map->isInside(newPos.x, newPos.y)) { + Resource *r = + map->getSurfaceCell(map->toSurfCoords(newPos))-> + getResource(); + if (r != NULL) { + addResourceTargetToCache(newPos); + //cacheResourceTargetList[newPos] = 1; + } + } + } + } + } + + cachedCloseResourceTargetLookupList[pos] = true; + } + } + } + + Vec2i Faction::getClosestResourceTypeTargetFromCache(Unit * unit, + const ResourceType * + type, + int frameIndex) { + Vec2i result(-1); + + if (cachingDisabled == false) { + if (cacheResourceTargetList.empty() == false) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "cacheResourceTargetList.size() [" MG_SIZE_T_SPECIFIER + "]", cacheResourceTargetList.size()); + + if (frameIndex < 0) { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } + } + + + std::vector < Vec2i > deleteList; + + const int harvestDistance = 5; + const Map *map = world->getMap(); + Vec2i pos = unit->getPos(); + + bool foundCloseResource = false; + // First look immediately around the unit's position + + // 0 means start looking leftbottom to top right + // if(Thread::isCurrentThreadMainThread() == false) { + // throw megaglest_runtime_error("#1 Invalid access to Faction random from outside main thread current id = " + + // intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId())); + // } + int tryRadius = random.randRange(0, 1); + //int tryRadius = unit->getRandom(true)->randRange(0,1); + //int tryRadius = 0; + if (tryRadius == 0) { + for (int j = -harvestDistance; + j <= harvestDistance && foundCloseResource == false; ++j) { + for (int k = -harvestDistance; + k <= harvestDistance && foundCloseResource == false; ++k) { + Vec2i newPos = pos + Vec2i(j, k); + if (map->isInside(newPos) == true + && isResourceTargetInCache(newPos) == false) { + const SurfaceCell *sc = + map->getSurfaceCell(map->toSurfCoords(newPos)); + if (sc != NULL && sc->getResource() != NULL) { + const Resource *resource = sc->getResource(); + if (resource->getType() != NULL + && resource->getType() == type) { + if (result.x < 0 + || unit->getPos().dist(newPos) < + unit->getPos().dist(result)) { + if (unit->isBadHarvestPos(newPos) == false) { + result = newPos; + foundCloseResource = true; + break; + } + } + } + } else { + deleteList.push_back(newPos); + } + } + } + } + } + // start looking topright to leftbottom + else { + for (int j = harvestDistance; + j >= -harvestDistance && foundCloseResource == false; --j) { + for (int k = harvestDistance; + k >= -harvestDistance && foundCloseResource == false; --k) { + Vec2i newPos = pos + Vec2i(j, k); + if (map->isInside(newPos) == true + && isResourceTargetInCache(newPos) == false) { + const SurfaceCell *sc = + map->getSurfaceCell(map->toSurfCoords(newPos)); + if (sc != NULL && sc->getResource() != NULL) { + const Resource *resource = sc->getResource(); + if (resource->getType() != NULL + && resource->getType() == type) { + if (result.x < 0 + || unit->getPos().dist(newPos) < + unit->getPos().dist(result)) { + if (unit->isBadHarvestPos(newPos) == false) { + result = newPos; + foundCloseResource = true; + break; + } + } + } + } else { + deleteList.push_back(newPos); + } + } + } + } + } + + if (foundCloseResource == false) { + // Now check the whole cache + for (std::map < Vec2i, int >::iterator iter = + cacheResourceTargetList.begin(); + iter != cacheResourceTargetList.end() + && foundCloseResource == false; ++iter) { + const Vec2i & cache = iter->first; + if (map->isInside(cache) == true) { + const SurfaceCell *sc = + map->getSurfaceCell(map->toSurfCoords(cache)); + if (sc != NULL && sc->getResource() != NULL) { + const Resource *resource = sc->getResource(); + if (resource->getType() != NULL + && resource->getType() == type) { + if (result.x < 0 + || unit->getPos().dist(cache) < + unit->getPos().dist(result)) { + if (unit->isBadHarvestPos(cache) == false) { + result = cache; + // Close enough to our position, no more looking + if (unit->getPos().dist(result) <= + (harvestDistance * 2)) { + foundCloseResource = true; + break; + } + } + } + } + } else { + deleteList.push_back(cache); + } + } else { + deleteList.push_back(cache); + } + } + } + + if (deleteList.empty() == false) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == + true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "[cleaning old resource targets] deleteList.size() [" + MG_SIZE_T_SPECIFIER + "] cacheResourceTargetList.size() [" + MG_SIZE_T_SPECIFIER "] result [%s]", + deleteList.size(), cacheResourceTargetList.size(), + result.getString().c_str()); + + if (frameIndex < 0) { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } + } + + cleanupResourceTypeTargetCache(&deleteList, frameIndex); + } + } + } + + return result; + } + + // CANNOT MODIFY the cache here since the AI calls this method and the AI is only controlled + // by the server for network games and it would cause out of synch since clients do not call + // this method so DO NOT modify the cache here! + Vec2i Faction::getClosestResourceTypeTargetFromCache(const Vec2i & pos, + const ResourceType * + type) { + Vec2i result(-1); + if (cachingDisabled == false) { + if (cacheResourceTargetList.empty() == false) { + //std::vector deleteList; + + const int harvestDistance = 5; + const Map *map = world->getMap(); + + bool foundCloseResource = false; + + // 0 means start looking leftbottom to top right + // if(Thread::isCurrentThreadMainThread() == false) { + // throw megaglest_runtime_error("#2 Invalid access to Faction random from outside main thread current id = " + + // intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId())); + // } + int tryRadius = random.randRange(0, 1); + if (tryRadius == 0) { + // First look immediately around the given position + for (int j = -harvestDistance; + j <= harvestDistance && foundCloseResource == false; ++j) { + for (int k = -harvestDistance; + k <= harvestDistance && foundCloseResource == false; ++k) { + Vec2i newPos = pos + Vec2i(j, k); + if (map->isInside(newPos) == true + && isResourceTargetInCache(newPos) == false) { + const SurfaceCell *sc = + map->getSurfaceCell(map->toSurfCoords(newPos)); + if (sc != NULL && sc->getResource() != NULL) { + const Resource *resource = sc->getResource(); + if (resource->getType() != NULL + && resource->getType() == type) { + if (result.x < 0 + || pos.dist(newPos) < pos.dist(result)) { + result = newPos; + foundCloseResource = true; + break; + } + } + } + //else { + // deleteList.push_back(newPos); + //} + } + } + } + } else { + // First look immediately around the given position + for (int j = harvestDistance; + j >= -harvestDistance && foundCloseResource == false; --j) { + for (int k = harvestDistance; + k >= -harvestDistance && foundCloseResource == false; --k) { + Vec2i newPos = pos + Vec2i(j, k); + if (map->isInside(newPos) == true + && isResourceTargetInCache(newPos) == false) { + const SurfaceCell *sc = + map->getSurfaceCell(map->toSurfCoords(newPos)); + if (sc != NULL && sc->getResource() != NULL) { + const Resource *resource = sc->getResource(); + if (resource->getType() != NULL + && resource->getType() == type) { + if (result.x < 0 + || pos.dist(newPos) < pos.dist(result)) { + result = newPos; + foundCloseResource = true; + break; + } + } + } + //else { + // deleteList.push_back(newPos); + //} + } + } + } + } + + if (foundCloseResource == false) { + // Now check the whole cache + for (std::map < Vec2i, int >::iterator iter = + cacheResourceTargetList.begin(); + iter != cacheResourceTargetList.end() + && foundCloseResource == false; ++iter) { + const Vec2i & cache = iter->first; + if (map->isInside(cache) == true) { + const SurfaceCell *sc = + map->getSurfaceCell(map->toSurfCoords(cache)); + if (sc != NULL && sc->getResource() != NULL) { + const Resource *resource = sc->getResource(); + if (resource->getType() != NULL + && resource->getType() == type) { + if (result.x < 0 || pos.dist(cache) < pos.dist(result)) { + result = cache; + // Close enough to our position, no more looking + if (pos.dist(result) <= (harvestDistance * 2)) { + foundCloseResource = true; + break; + } + } + } + } + //else { + // deleteList.push_back(cache); + //} + } + //else { + // deleteList.push_back(cache); + //} + } + } + } + } + + return result; + } + + void Faction::cleanupResourceTypeTargetCache(std::vector < Vec2i > + *deleteListPtr, + int frameIndex) { + if (cachingDisabled == false) { + if (cacheResourceTargetList.empty() == false) { + const int cleanupInterval = (GameConstants::updateFps * 5); + bool needToCleanup = (getFrameCount() % cleanupInterval == 0); + + if (deleteListPtr != NULL || needToCleanup == true) { + std::vector < Vec2i > deleteList; + + if (deleteListPtr != NULL) { + deleteList = *deleteListPtr; + } else { + for (std::map < Vec2i, int >::iterator iter = + cacheResourceTargetList.begin(); + iter != cacheResourceTargetList.end(); ++iter) { + const Vec2i & cache = iter->first; + + if (world->getMap()-> + getSurfaceCell(world->getMap()->toSurfCoords(cache)) != + NULL) { + Resource *resource = + world->getMap()->getSurfaceCell(world->getMap()-> + toSurfCoords(cache))-> + getResource(); + if (resource == NULL) { + deleteList.push_back(cache); + } + } else { + deleteList.push_back(cache); + } + } + } + + if (deleteList.empty() == false) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "[cleaning old resource targets] deleteList.size() [" + MG_SIZE_T_SPECIFIER + "] cacheResourceTargetList.size() [" + MG_SIZE_T_SPECIFIER "], needToCleanup [%d]", + deleteList.size(), cacheResourceTargetList.size(), + needToCleanup); + //unit->logSynchData(szBuf); + + char szBuf1[8096] = ""; + snprintf(szBuf1, 8096, + "----------------------------------- START [%d] ------------------------------------------------\n", + getFrameCount()); + string logDataText = szBuf1; + + snprintf(szBuf1, 8096, "[%s::%d]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __LINE__); + logDataText += szBuf1; + + snprintf(szBuf1, 8096, "%s\n", szBuf); + logDataText += szBuf1; + + snprintf(szBuf1, 8096, + "------------------------------------ END [%d] -------------------------------------------------\n", + getFrameCount()); + logDataText += szBuf1; + + if (frameIndex < 0) { + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + "%s", logDataText.c_str()); + } else { + addWorldSynchThreadedLogList(logDataText); + } + } + + for (int i = 0; i < (int) deleteList.size(); ++i) { + Vec2i & cache = deleteList[i]; + cacheResourceTargetList.erase(cache); + } + } + } + } + } + } + + //std::vector Faction::findCachedPath(const Vec2i &target, Unit *unit) { + // std::vector result; + // if(cachingDisabled == false) { + // if(successfulPathFinderTargetList.find(target) == successfulPathFinderTargetList.end()) { + // // Lets find the shortest and most successful path already taken by a + // // similar sized unit + // + // bool foundCachedPath = false; + // std::vector &cacheList = successfulPathFinderTargetList[target]; + // int unitSize = unit->getType()->getSize(); + // for(int i = 0; i < cacheList.size(); ++i) { + // FactionPathSuccessCache &cache = cacheList[i]; + // if(cache.unitSize <= unitSize) { + // vector, int> > &pathQueue = cache.pathQueue; + // + // for(int j = 0; j < pathQueue.size(); ++j) { + // // Now start at the end of the path and see how many nodes + // // until we reach a cell near the unit's current position + // std::pair, int> &path = pathQueue[j]; + // + // for(int k = path.first.size() - 1; k >= 0; --k) { + // if(world->getMap()->canMove(unit, unit->getPos(), path.first[k]) == true) { + // if(foundCachedPath == false) { + // for(int l = k; l < path.first.size(); ++l) { + // result.push_back(path.first[l]); + // } + // } + // else { + // if(result.size() > (path.first.size() - k)) { + // for(int l = k; l < path.first.size(); ++l) { + // result.push_back(path.first[l]); + // } + // } + // } + // foundCachedPath = true; + // + // break; + // } + // } + // } + // } + // } + // } + // } + // + // return result; + //} + + //void Faction::addCachedPath(const Vec2i &target, Unit *unit) { + // if(cachingDisabled == false) { + // if(successfulPathFinderTargetList.find(target) == successfulPathFinderTargetList.end()) { + // FactionPathSuccessCache cache; + // cache.unitSize = unit->getType()->getSize(); + // cache.pathQueue.push_back(make_pair, int>(unit->getCurrentTargetPathTaken().second,1)); + // successfulPathFinderTargetList[target].push_back(cache); + // } + // else { + // bool finishedAdd = false; + // std::pair > currentTargetPathTaken = unit->getCurrentTargetPathTaken(); + // std::vector &cacheList = successfulPathFinderTargetList[target]; + // int unitSize = unit->getType()->getSize(); + // + // for(int i = 0; i < cacheList.size() && finishedAdd == false; ++i) { + // FactionPathSuccessCache &cache = cacheList[i]; + // if(cache.unitSize <= unitSize) { + // vector, int> > &pathQueue = cache.pathQueue; + // + // for(int j = 0; j < pathQueue.size() && finishedAdd == false; ++j) { + // // Now start at the end of the path and see how many nodes are the same + // std::pair, int> &path = pathQueue[j]; + // int minPathSize = std::min(path.first.size(),currentTargetPathTaken.second.size()); + // int intersectIndex = -1; + // + // for(int k = 0; k < minPathSize; ++k) { + // if(path.first[path.first.size() - k - 1] != currentTargetPathTaken.second[currentTargetPathTaken.second.size() - k - 1]) { + // intersectIndex = k; + // break; + // } + // } + // + // // New path is same or longer than old path so replace + // // old path with new + // if(intersectIndex + 1 == path.first.size()) { + // path.first = currentTargetPathTaken.second; + // path.second++; + // finishedAdd = true; + // } + // // Old path is same or longer than new path so + // // do nothing + // else if(intersectIndex + 1 == currentTargetPathTaken.second.size()) { + // path.second++; + // finishedAdd = true; + // } + // } + // + // // If new path is >= 10 cells add it + // if(finishedAdd == false && currentTargetPathTaken.second.size() >= 10) { + // pathQueue.push_back(make_pair, int>(currentTargetPathTaken.second,1)); + // } + // } + // } + // } + // } + //} + + void Faction::deletePixels() { + if (factionType != NULL) { + factionType->deletePixels(); + } + } + + //Unit * Faction::findClosestUnitWithSkillClass( const Vec2i &pos,const CommandClass &cmdClass, + // const std::vector &skillClassList, + // const UnitType *unitType) { + // Unit *result = NULL; + // + ///* + // std::map >::iterator iterFind = cacheUnitCommandClassList.find(cmdClass); + // if(iterFind != cacheUnitCommandClassList.end()) { + // for(std::map::iterator iter = iterFind->second.begin(); + // iter != iterFind->second.end(); ++iter) { + // Unit *curUnit = findUnit(iter->second); + // if(curUnit != NULL) { + // + // const CommandType *cmdType = curUnit->getType()->getFirstCtOfClass(cmdClass); + // bool isUnitPossibleCandidate = (cmdType != NULL); + // if(skillClassList.empty() == false) { + // isUnitPossibleCandidate = false; + // + // for(int j = 0; j < skillClassList.size(); ++j) { + // SkillClass skValue = skillClassList[j]; + // if(curUnit->getCurrSkill()->getClass() == skValue) { + // isUnitPossibleCandidate = true; + // break; + // } + // } + // } + // + // if(isUnitPossibleCandidate == true) { + // if(result == NULL || curUnit->getPos().dist(pos) < result->getPos().dist(pos)) { + // result = curUnit; + // } + // } + // } + // } + // } + //*/ + // + // //if(result == NULL) { + // for(int i = 0; i < getUnitCount(); ++i) { + // Unit *curUnit = getUnit(i); + // + // bool isUnitPossibleCandidate = false; + // + // const CommandType *cmdType = curUnit->getType()->getFirstCtOfClass(cmdClass); + // if(cmdType != NULL) { + // const RepairCommandType *rct = dynamic_cast(cmdType); + // if(rct != NULL && rct->isRepairableUnitType(unitType)) { + // isUnitPossibleCandidate = true; + // } + // } + // else { + // isUnitPossibleCandidate = false; + // } + // + // if(isUnitPossibleCandidate == true && skillClassList.empty() == false) { + // isUnitPossibleCandidate = false; + // + // for(int j = 0; j < (int)skillClassList.size(); ++j) { + // SkillClass skValue = skillClassList[j]; + // if(curUnit->getCurrSkill()->getClass() == skValue) { + // isUnitPossibleCandidate = true; + // break; + // } + // } + // } + // + // + // if(isUnitPossibleCandidate == true) { + // //cacheUnitCommandClassList[cmdClass][curUnit->getId()] = curUnit->getId(); + // + // if(result == NULL || curUnit->getPos().dist(pos) < result->getPos().dist(pos)) { + // result = curUnit; + // } + // } + // } + // //} + // return result; + //} + + int Faction::getFrameCount() { + int frameCount = 0; + const Game *game = Renderer::getInstance().getGame(); + if (game != NULL && game->getWorld() != NULL) { + frameCount = game->getWorld()->getFrameCount(); + } + + return frameCount; + } + + const SwitchTeamVote *Faction::getFirstSwitchTeamVote() const { + const SwitchTeamVote *vote = NULL; + if (switchTeamVotes.empty() == false) { + for (std::map < int, SwitchTeamVote >::const_iterator iterMap = + switchTeamVotes.begin(); iterMap != switchTeamVotes.end(); + ++iterMap) { + const SwitchTeamVote & curVote = iterMap->second; + if (curVote.voted == false) { + vote = &curVote; + break; + } + } + } + + return vote; + } + + SwitchTeamVote *Faction::getSwitchTeamVote(int factionIndex) { + SwitchTeamVote *vote = NULL; + if (switchTeamVotes.find(factionIndex) != switchTeamVotes.end()) { + vote = &switchTeamVotes[factionIndex]; + } + + return vote; + } + + void Faction::setSwitchTeamVote(SwitchTeamVote & vote) { + switchTeamVotes[vote.factionIndex] = vote; + } + + bool Faction::canCreateUnit(const UnitType * ut, bool checkBuild, + bool checkProduce, bool checkMorph) const { + // Now check that at least 1 other unit can produce, build or morph this unit + bool foundUnit = false; + for (int l = 0; l < this->getUnitCount() && foundUnit == false; ++l) { + const UnitType *unitType2 = this->getUnit(l)->getType(); + + for (int j = 0; + j < unitType2->getCommandTypeCount() && foundUnit == false; ++j) { + const CommandType *cmdType = unitType2->getCommandType(j); + if (cmdType != NULL) { + // Check if this is a produce command + if (checkProduce == true && cmdType->getClass() == ccProduce) { + const ProduceCommandType *produce = + dynamic_cast (cmdType); + if (produce != NULL) { + const UnitType *produceUnit = produce->getProducedUnit(); + + if (produceUnit != NULL && + ut->getId() != unitType2->getId() && + ut->getName(false) == produceUnit->getName(false)) { + foundUnit = true; + break; + } + } + } + // Check if this is a build command + else if (checkBuild == true && cmdType->getClass() == ccBuild) { + const BuildCommandType *build = + dynamic_cast (cmdType); + if (build != NULL) { + for (int k = 0; + k < build->getBuildingCount() && foundUnit == false; + ++k) { + const UnitType *buildUnit = build->getBuilding(k); + + if (buildUnit != NULL && + ut->getId() != unitType2->getId() && + ut->getName(false) == buildUnit->getName(false)) { + foundUnit = true; + break; + } + } + } + } + // Check if this is a morph command + else if (checkMorph == true && cmdType->getClass() == ccMorph) { + const MorphCommandType *morph = + dynamic_cast (cmdType); + if (morph != NULL) { + const UnitType *morphUnit = morph->getMorphUnit(); + + if (morphUnit != NULL && + ut->getId() != unitType2->getId() && + ut->getName(false) == morphUnit->getName(false)) { + foundUnit = true; + break; + } + } + } + } + } + } + + return foundUnit; + } + + void Faction::clearCaches() { + cacheResourceTargetList.clear(); + cachedCloseResourceTargetLookupList.clear(); + + //aliveUnitListCache.clear(); + //mobileUnitListCache.clear(); + //beingBuiltUnitListCache.clear(); + + unsigned int unitCount = this->getUnitCount(); + for (unsigned int i = 0; i < unitCount; ++i) { + Unit *unit = this->getUnit(i); + if (unit != NULL) { + unit->clearCaches(); + } + } + } + + uint64 Faction::getCacheKBytes(uint64 * cache1Size, uint64 * cache2Size, + uint64 * cache3Size, uint64 * cache4Size, + uint64 * cache5Size) { + uint64 cache1Count = 0; + uint64 cache2Count = 0; + uint64 cache3Count = 0; + uint64 cache4Count = 0; + uint64 cache5Count = 0; + + for (std::map < Vec2i, int >::iterator iterMap1 = + cacheResourceTargetList.begin(); + iterMap1 != cacheResourceTargetList.end(); ++iterMap1) { + cache1Count++; + } + for (std::map < Vec2i, bool >::iterator iterMap1 = + cachedCloseResourceTargetLookupList.begin(); + iterMap1 != cachedCloseResourceTargetLookupList.end(); ++iterMap1) { + cache2Count++; + } + for (std::map < int, const Unit * >::iterator iterMap1 = + aliveUnitListCache.begin(); iterMap1 != aliveUnitListCache.end(); + ++iterMap1) { + cache3Count++; + } + for (std::map < int, const Unit * >::iterator iterMap1 = + mobileUnitListCache.begin(); + iterMap1 != mobileUnitListCache.end(); ++iterMap1) { + cache4Count++; + } + for (std::map < int, const Unit * >::iterator iterMap1 = + beingBuiltUnitListCache.begin(); + iterMap1 != beingBuiltUnitListCache.end(); ++iterMap1) { + cache5Count++; + } + + if (cache1Size) { + *cache1Size = cache1Count; + } + if (cache2Size) { + *cache2Size = cache2Count; + } + if (cache3Size) { + *cache3Size = cache3Count; + } + if (cache4Size) { + *cache4Size = cache4Count; + } + if (cache5Size) { + *cache5Size = cache5Count; + } + + uint64 totalBytes = cache1Count * sizeof(int); + totalBytes += cache2Count * sizeof(bool); + totalBytes += cache3Count * (sizeof(int) + sizeof(const Unit *)); + totalBytes += cache4Count * (sizeof(int) + sizeof(const Unit *)); + totalBytes += cache5Count * (sizeof(int) + sizeof(const Unit *)); + + totalBytes /= 1000; + + return totalBytes; + } + + string Faction::getCacheStats() { + string result = ""; + + int cache1Count = 0; + int cache2Count = 0; + + for (std::map < Vec2i, int >::iterator iterMap1 = + cacheResourceTargetList.begin(); + iterMap1 != cacheResourceTargetList.end(); ++iterMap1) { + cache1Count++; + } + for (std::map < Vec2i, bool >::iterator iterMap1 = + cachedCloseResourceTargetLookupList.begin(); + iterMap1 != cachedCloseResourceTargetLookupList.end(); ++iterMap1) { + cache2Count++; + } + + uint64 totalBytes = cache1Count * sizeof(int); + totalBytes += cache2Count * sizeof(bool); + + totalBytes /= 1000; + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "cache1Count [%d] cache2Count [%d] total KB: %s", + cache1Count, cache2Count, formatNumber(totalBytes).c_str()); + result = szBuf; + return result; + } + + std::string Faction::toString(bool crcMode) const { + std::string result = "FactionIndex = " + intToStr(this->index) + "\n"; + result += "teamIndex = " + intToStr(this->teamIndex) + "\n"; + result += + "startLocationIndex = " + intToStr(this->startLocationIndex) + "\n"; + if (crcMode == false) { + result += "thisFaction = " + intToStr(this->thisFaction) + "\n"; + result += "control = " + intToStr(this->control) + "\n"; + } + + if (this->factionType != NULL) { + result += this->factionType->toString() + "\n"; + } + + result += this->upgradeManager.toString() + "\n"; + + result += "ResourceCount = " + intToStr(resources.size()) + "\n"; + for (int idx = 0; idx < (int) resources.size(); idx++) { + result += + "index = " + intToStr(idx) + " " + resources[idx].toString() + + "\n"; + } + + result += "StoreCount = " + intToStr(store.size()) + "\n"; + for (int idx = 0; idx < (int) store.size(); idx++) { + result += + "index = " + intToStr(idx) + " " + store[idx].toString() + "\n"; + } + + result += "Allies = " + intToStr(allies.size()) + "\n"; + for (int idx = 0; idx < (int) allies.size(); idx++) { + result += + "index = " + intToStr(idx) + " name: " + + allies[idx]->factionType->getName(false) + " factionindex = " + + intToStr(allies[idx]->index) + "\n"; + } + + result += "Units = " + intToStr(units.size()) + "\n"; + for (int idx = 0; idx < (int) units.size(); idx++) { + result += units[idx]->toString(crcMode) + "\n"; + } + + return result; + } + + void Faction::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode *factionNode = rootNode->addChild("Faction"); + + upgradeManager.saveGame(factionNode); + for (unsigned int i = 0; i < resources.size(); ++i) { + Resource & resource = resources[i]; + resource.saveGame(factionNode); + } + XmlNode *storeNode = factionNode->addChild("Store"); + for (unsigned int i = 0; i < store.size(); ++i) { + Resource & resource = store[i]; + resource.saveGame(storeNode); + } + + for (unsigned int i = 0; i < allies.size(); ++i) { + Faction *ally = allies[i]; + XmlNode *allyNode = factionNode->addChild("Ally"); + allyNode->addAttribute("allyFactionIndex", + intToStr(ally->getIndex()), + mapTagReplacements); + } + for (unsigned int i = 0; i < units.size(); ++i) { + Unit *unit = units[i]; + unit->saveGame(factionNode); + } + + factionNode->addAttribute("control", intToStr(control), + mapTagReplacements); + + factionNode->addAttribute("overridePersonalityType", + intToStr(overridePersonalityType), + mapTagReplacements); + factionNode->addAttribute("factiontype", factionType->getName(false), + mapTagReplacements); + factionNode->addAttribute("index", intToStr(index), + mapTagReplacements); + factionNode->addAttribute("teamIndex", intToStr(teamIndex), + mapTagReplacements); + factionNode->addAttribute("startLocationIndex", + intToStr(startLocationIndex), + mapTagReplacements); + factionNode->addAttribute("thisFaction", intToStr(thisFaction), + mapTagReplacements); + + for (std::map < Vec2i, int >::iterator iterMap = + cacheResourceTargetList.begin(); + iterMap != cacheResourceTargetList.end(); ++iterMap) { + XmlNode *cacheResourceTargetListNode = + factionNode->addChild("cacheResourceTargetList"); + + cacheResourceTargetListNode->addAttribute("key", + iterMap->first. + getString(), + mapTagReplacements); + cacheResourceTargetListNode->addAttribute("value", + intToStr(iterMap->second), + mapTagReplacements); + } + + for (std::map < Vec2i, bool >::iterator iterMap = + cachedCloseResourceTargetLookupList.begin(); + iterMap != cachedCloseResourceTargetLookupList.end(); ++iterMap) { + XmlNode *cachedCloseResourceTargetLookupListNode = + factionNode->addChild("cachedCloseResourceTargetLookupList"); + + cachedCloseResourceTargetLookupListNode->addAttribute("key", + iterMap->first. + getString(), + mapTagReplacements); + cachedCloseResourceTargetLookupListNode->addAttribute("value", + intToStr + (iterMap-> + second), + mapTagReplacements); + } + + factionNode->addAttribute("random", intToStr(random.getLastNumber()), + mapTagReplacements); + factionNode->addAttribute("currentSwitchTeamVoteFactionIndex", + intToStr(currentSwitchTeamVoteFactionIndex), + mapTagReplacements); + factionNode->addAttribute("allowSharedTeamUnits", + intToStr(allowSharedTeamUnits), + mapTagReplacements); + + for (std::set < const UnitType * >::iterator iterMap = + lockedUnits.begin(); iterMap != lockedUnits.end(); ++iterMap) { + XmlNode *lockedUnitsListNode = + factionNode->addChild("lockedUnitList"); + const UnitType *ut = *iterMap; + + lockedUnitsListNode->addAttribute("value", ut->getName(false), + mapTagReplacements); + } + + for (std::map < int, int >::iterator iterMap = unitsMovingList.begin(); + iterMap != unitsMovingList.end(); ++iterMap) { + XmlNode *unitsMovingListNode = + factionNode->addChild("unitsMovingList"); + + unitsMovingListNode->addAttribute("key", intToStr(iterMap->first), + mapTagReplacements); + unitsMovingListNode->addAttribute("value", + intToStr(iterMap->second), + mapTagReplacements); + } + + for (std::map < int, int >::iterator iterMap = + unitsPathfindingList.begin(); + iterMap != unitsPathfindingList.end(); ++iterMap) { + XmlNode *unitsPathfindingListNode = + factionNode->addChild("unitsPathfindingList"); + + unitsPathfindingListNode->addAttribute("key", + intToStr(iterMap->first), + mapTagReplacements); + unitsPathfindingListNode->addAttribute("value", + intToStr(iterMap->second), + mapTagReplacements); + } + } + + void Faction::loadGame(const XmlNode * rootNode, int factionIndex, + GameSettings * settings, World * world) { + XmlNode *factionNode = NULL; + vector < XmlNode * >factionNodeList = + rootNode->getChildList("Faction"); + for (unsigned int i = 0; i < factionNodeList.size(); ++i) { + XmlNode *node = factionNodeList[i]; + if (node->getAttribute("index")->getIntValue() == factionIndex) { + factionNode = node; + break; + } + } + + if (factionNode != NULL) { + + allies.clear(); + vector < XmlNode * >allyNodeList = factionNode->getChildList("Ally"); + for (unsigned int i = 0; i < allyNodeList.size(); ++i) { + XmlNode *allyNode = allyNodeList[i]; + + int allyFactionIndex = + allyNode->getAttribute("allyFactionIndex")->getIntValue(); + allies.push_back(world->getFaction(allyFactionIndex)); + } + + vector < XmlNode * >unitNodeList = factionNode->getChildList("Unit"); + for (unsigned int i = 0; i < unitNodeList.size(); ++i) { + XmlNode *unitNode = unitNodeList[i]; + Unit *unit = Unit::loadGame(unitNode, settings, this, world); + this->addUnit(unit); + } + + for (unsigned int i = 0; i < resources.size(); ++i) { + Resource & resource = resources[i]; + resource.loadGame(factionNode, i, techTree); + } + XmlNode *storeNode = factionNode->getChild("Store"); + for (unsigned int i = 0; i < store.size(); ++i) { + Resource & resource = store[i]; + resource.loadGame(storeNode, i, techTree); + } + + upgradeManager.loadGame(factionNode, this); + + control = + static_cast + (factionNode->getAttribute("control")->getIntValue()); + + if (factionNode->hasAttribute("overridePersonalityType") == true) { + overridePersonalityType = + static_cast + (factionNode->getAttribute("overridePersonalityType")-> + getIntValue()); + } + + teamIndex = factionNode->getAttribute("teamIndex")->getIntValue(); + + startLocationIndex = + factionNode->getAttribute("startLocationIndex")->getIntValue(); + + thisFaction = + factionNode->getAttribute("thisFaction")->getIntValue() != 0; + + if (factionNode->hasAttribute("allowSharedTeamUnits") == true) { + allowSharedTeamUnits = + factionNode->getAttribute("allowSharedTeamUnits")-> + getIntValue() != 0; + } + + vector < XmlNode * >cacheResourceTargetListNodeList = + factionNode->getChildList("cacheResourceTargetList"); + for (unsigned int i = 0; i < cacheResourceTargetListNodeList.size(); + ++i) { + XmlNode *cacheResourceTargetListNode = + cacheResourceTargetListNodeList[i]; + + Vec2i vec = + Vec2i::strToVec2(cacheResourceTargetListNode-> + getAttribute("key")->getValue()); + cacheResourceTargetList[vec] = + cacheResourceTargetListNode->getAttribute("value")-> + getIntValue(); + } + vector < XmlNode * >cachedCloseResourceTargetLookupListNodeList = + factionNode->getChildList("cachedCloseResourceTargetLookupList"); + for (unsigned int i = 0; + i < cachedCloseResourceTargetLookupListNodeList.size(); ++i) { + XmlNode *cachedCloseResourceTargetLookupListNode = + cachedCloseResourceTargetLookupListNodeList[i]; + + Vec2i vec = + Vec2i::strToVec2(cachedCloseResourceTargetLookupListNode-> + getAttribute("key")->getValue()); + cachedCloseResourceTargetLookupList[vec] = + cachedCloseResourceTargetLookupListNode->getAttribute("value")-> + getIntValue() != 0; + } + + random.setLastNumber(factionNode->getAttribute("random")-> + getIntValue()); + + vector < XmlNode * >lockedUnitsListNodeList = + factionNode->getChildList("lockedUnitList"); + for (unsigned int i = 0; i < lockedUnitsListNodeList.size(); ++i) { + XmlNode *lockedUnitsListNode = lockedUnitsListNodeList[i]; + + string unitName = + lockedUnitsListNode->getAttribute("value")->getValue(); + lockedUnits.insert(getType()->getUnitType(unitName)); + } + + vector < XmlNode * >unitsMovingListNodeList = + factionNode->getChildList("unitsMovingList"); + for (unsigned int i = 0; i < unitsMovingListNodeList.size(); ++i) { + XmlNode *unitsMovingListNode = unitsMovingListNodeList[i]; + + int unitId = + unitsMovingListNode->getAttribute("key")->getIntValue(); + unitsMovingList[unitId] = + unitsMovingListNode->getAttribute("value")->getIntValue(); + } + vector < XmlNode * >unitsPathfindingListNodeList = + factionNode->getChildList("unitsPathfindingList"); + for (unsigned int i = 0; i < unitsPathfindingListNodeList.size(); + ++i) { + XmlNode *unitsPathfindingListNode = unitsPathfindingListNodeList[i]; + + int unitId = + unitsPathfindingListNode->getAttribute("key")->getIntValue(); + unitsPathfindingList[unitId] = + unitsPathfindingListNode->getAttribute("value")->getIntValue(); + } + } + } + + Checksum Faction::getCRC() { + const bool consoleDebug = false; + + Checksum crcForFaction; + + // UpgradeManager upgradeManager; + + for (unsigned int i = 0; i < resources.size(); ++i) { + Resource & resource = resources[i]; + //crcForFaction.addSum(resource.getCRC().getSum()); + uint32 crc = resource.getCRC().getSum(); + crcForFaction.addBytes(&crc, sizeof(uint32)); + } + + if (consoleDebug) { + if (getWorld()->getFrameCount() % 40 == 0) { + printf("#1 Frame #: %d Faction: %d CRC: %u\n", + getWorld()->getFrameCount(), index, + crcForFaction.getSum()); + } + } + + for (unsigned int i = 0; i < store.size(); ++i) { + Resource & resource = store[i]; + //crcForFaction.addSum(resource.getCRC().getSum()); + uint32 crc = resource.getCRC().getSum(); + crcForFaction.addBytes(&crc, sizeof(uint32)); + } + + if (consoleDebug) { + if (getWorld()->getFrameCount() % 40 == 0) { + printf("#2 Frame #: %d Faction: %d CRC: %u\n", + getWorld()->getFrameCount(), index, + crcForFaction.getSum()); + } + } + + for (unsigned int i = 0; i < units.size(); ++i) { + Unit *unit = units[i]; + //crcForFaction.addSum(unit->getCRC().getSum()); + uint32 crc = unit->getCRC().getSum(); + crcForFaction.addBytes(&crc, sizeof(uint32)); + } + + if (consoleDebug) { + if (getWorld()->getFrameCount() % 40 == 0) { + printf("#3 Frame #: %d Faction: %d CRC: %u\n", + getWorld()->getFrameCount(), index, + crcForFaction.getSum()); + } + } + + return crcForFaction; + } + + void Faction::addCRC_DetailsForWorldFrame(int worldFrameCount, + bool isNetworkServer) { + unsigned int MAX_FRAME_CACHE = 250; + if (isNetworkServer == true) { + MAX_FRAME_CACHE += 250; + } + crcWorldFrameDetails[worldFrameCount] = this->toString(true); + //if(worldFrameCount <= 0) printf("Adding world frame: %d log entries: %lld\n",worldFrameCount,(long long int)crcWorldFrameDetails.size()); + + for (unsigned int i = 0; i < units.size(); ++i) { + Unit *unit = units[i]; + + unit->getRandom()->clearLastCaller(); + unit->clearNetworkCRCDecHpList(); + unit->clearParticleInfo(); + } + + if ((unsigned int) crcWorldFrameDetails.size() > MAX_FRAME_CACHE) { + //printf("===> Removing older world frame log entries: %lld\n",(long long int)crcWorldFrameDetails.size()); + + for (; + (unsigned int) crcWorldFrameDetails.size() - MAX_FRAME_CACHE > + 0;) { + crcWorldFrameDetails.erase(crcWorldFrameDetails.begin()); + } + } + } + + string Faction::getCRC_DetailsForWorldFrame(int worldFrameCount) { + if (crcWorldFrameDetails.empty()) { + return ""; + } + return crcWorldFrameDetails[worldFrameCount]; + } + + std::pair < int, + string > + Faction::getCRC_DetailsForWorldFrameIndex(int worldFrameIndex) const { + if (crcWorldFrameDetails.empty()) { + return make_pair < int, string >(0, ""); + } + std::map < int, string >::const_iterator iterMap = + crcWorldFrameDetails.begin(); + std::advance(iterMap, worldFrameIndex); + if (iterMap == crcWorldFrameDetails.end()) { + return make_pair < int, string >(0, ""); + } + return std::pair < int, string >(iterMap->first, iterMap->second); + } + + string Faction::getCRC_DetailsForWorldFrames() const { + string result = ""; + for (std::map < int, string >::const_iterator iterMap = + crcWorldFrameDetails.begin(); + iterMap != crcWorldFrameDetails.end(); ++iterMap) { + result += + string + ("============================================================================\n"); + result += + string("** world frame: ") + intToStr(iterMap->first) + + string(" detail: ") + iterMap->second; + } + return result; + } + + uint64 Faction::getCRC_DetailsForWorldFrameCount() const { + return crcWorldFrameDetails.size(); + } + + } } //end namespace diff --git a/source/glest_game/type_instances/faction.h b/source/glest_game/type_instances/faction.h index 46b29f0a1..a1e75a5f9 100644 --- a/source/glest_game/type_instances/faction.h +++ b/source/glest_game/type_instances/faction.h @@ -36,511 +36,458 @@ using std::set; using Shared::Graphics::Texture2D; using namespace Shared::PlatformCommon; -namespace Glest -{ - namespace Game - { - - class Unit; - class TechTree; - class FactionType; - class ProducibleType; - class RequirableType; - class CommandType; - class UnitType; - class Game; - class ScriptManager; - class World; - class Faction; - class GameSettings; - class SurfaceCell; - - class FowAlphaCellsLookupItem - { - public: - - std::map < Vec2i, float >surfPosAlphaList; - }; - - class ExploredCellsLookupItem - { - public: - - ExploredCellsLookupItem () - { - ExploredCellsLookupItemCacheTimerCountIndex = 0; - } - int ExploredCellsLookupItemCacheTimerCountIndex; - std::vector < SurfaceCell * >exploredCellList; - std::vector < SurfaceCell * >visibleCellList; - - static time_t lastDebug; - }; - -// ===================================================== -// class Faction -// -/// Each of the game players -// ===================================================== - - struct CommandGroupUnitSorter - { - bool operator () (const Unit * l, const Unit * r); - bool compare (const Unit * l, const Unit * r); - }; - - struct CommandGroupUnitSorterId - { - Faction *faction; - bool operator () (const int l, const int r); - }; - - class FactionThread:public BaseThread, - public SlaveThreadControllerInterface - { - protected: - - Faction * faction; - Semaphore semTaskSignalled; - Mutex *triggerIdMutex; - std::pair < int, bool > frameIndex; - MasterSlaveThreadController *masterController; - - virtual void setQuitStatus (bool value); - virtual void setTaskCompleted (int frameIndex); - virtual bool canShutdown (bool deleteSelfIfShutdownDelayed = false); - - public: - explicit FactionThread (Faction * faction); - virtual ~ FactionThread (); - virtual void execute (); - - virtual void setMasterController (MasterSlaveThreadController * master) - { - masterController = master; - } - virtual void signalSlave (void *userdata) - { - signalPathfinder (*((int *) (userdata))); - } - - void signalPathfinder (int frameIndex); - bool isSignalPathfinderCompleted (int frameIndex); - }; - - class SwitchTeamVote - { - public: - - int factionIndex; - int oldTeam; - int newTeam; - bool voted; - bool allowSwitchTeam; - }; - - class Faction - { - private: - typedef vector < Resource > Resources; - typedef vector < Resource > Store; - typedef vector < Faction * >Allies; - typedef vector < Unit * >Units; - typedef map < int, Unit * >UnitMap; - - private: - UpgradeManager upgradeManager; - - Resources resources; - Store store; - Allies allies; - - Mutex *unitsMutex; - Units units; - UnitMap unitMap; - World *world; - ScriptManager *scriptManager; - - FactionPersonalityType overridePersonalityType; - ControlType control; - - Texture2D *texture; - FactionType *factionType; - - int index; - int teamIndex; - int startLocationIndex; - - bool thisFaction; - - bool factionDisconnectHandled; - - bool cachingDisabled; - std::map < Vec2i, int >cacheResourceTargetList; - std::map < Vec2i, bool > cachedCloseResourceTargetLookupList; - - RandomGen random; - FactionThread *workerThread; - - std::map < int, SwitchTeamVote > switchTeamVotes; - int currentSwitchTeamVoteFactionIndex; - - bool allowSharedTeamUnits; - set < int >livingUnits; - set < Unit * >livingUnitsp; - - std::map < int, int >unitsMovingList; - std::map < int, int >unitsPathfindingList; - - std::set < const UnitType *>lockedUnits; - - TechTree *techTree; - const XmlNode *loadWorldNode; - - std::vector < string > worldSynchThreadedLogList; - - std::map < int, string > crcWorldFrameDetails; - - std::map < int, const Unit *>aliveUnitListCache; - std::map < int, const Unit *>mobileUnitListCache; - std::map < int, const Unit *>beingBuiltUnitListCache; - - std::map < std::string, bool > resourceTypeCostCache; - - public: - Faction (); - ~Faction (); - - Faction (const Faction & obj) - { - init (); - throw megaglest_runtime_error ("class Faction is NOT safe to copy!"); - } - Faction & operator= (const Faction & obj) - { - init (); - throw - megaglest_runtime_error ("class Faction is NOT safe to assign!"); - } - - void notifyUnitAliveStatusChange (const Unit * unit); - void notifyUnitTypeChange (const Unit * unit, const UnitType * newType); - void notifyUnitSkillTypeChange (const Unit * unit, - const SkillType * newType); - bool hasAliveUnits (bool filterMobileUnits, - bool filterBuiltUnits) const; - - inline void addWorldSynchThreadedLogList (const string & data) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true) - { - worldSynchThreadedLogList.push_back (data); - } - } - inline void clearWorldSynchThreadedLogList () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true) - { - worldSynchThreadedLogList.clear (); - } - } - inline void dumpWorldSynchThreadedLogList () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch). - enabled == true) - { - if (worldSynchThreadedLogList.empty () == false) - { - for (unsigned int index = 0; - index < worldSynchThreadedLogList.size (); ++index) - { - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, - worldSynchThreadedLogList[index]. - c_str ()); - } - worldSynchThreadedLogList.clear (); - } - } - } - - inline void addLivingUnits (int id) - { - livingUnits.insert (id); - } - inline void addLivingUnitsp (Unit * unit) - { - livingUnitsp.insert (unit); - } - - inline bool isUnitInLivingUnitsp (Unit * unit) - { - return (livingUnitsp.find (unit) != livingUnitsp.end ()); - } - inline void deleteLivingUnits (int id) - { - livingUnits.erase (id); - } - inline void deleteLivingUnitsp (Unit * unit) - { - livingUnitsp.erase (unit); - } - - //std::map unitsMovingList; - void addUnitToMovingList (int unitId); - void removeUnitFromMovingList (int unitId); - //int getUnitMovingListCount(); - - void addUnitToPathfindingList (int unitId); - //void removeUnitFromPathfindingList(int unitId); - int getUnitPathfindingListCount (); - void clearUnitsPathfinding (); - bool canUnitsPathfind (); - - void setLockedUnitForFaction (const UnitType * ut, bool lock); - bool isUnitLocked (const UnitType * ut) const - { - return lockedUnits.find (ut) != lockedUnits.end (); - } - - void init (FactionType * factionType, ControlType control, - TechTree * techTree, Game * game, int factionIndex, - int teamIndex, int startLocationIndex, bool thisFaction, - bool giveResources, const XmlNode * loadWorldNode = NULL); - void end (); - - inline bool getFactionDisconnectHandled () const - { - return factionDisconnectHandled; - } - void setFactionDisconnectHandled (bool value) - { - factionDisconnectHandled = value; - } - - //get - const Resource *getResource (const ResourceType * rt, - bool localFactionOnly = false) const; - inline const Resource *getResource (int i) const - { - return &resources[i]; - } - int getStoreAmount (const ResourceType * rt, bool localFactionOnly = - false) const; - inline const FactionType *getType () const - { - return factionType; - } - inline int getIndex () const - { - return index; - } - - inline int getTeam () const - { - return teamIndex; - } - void setTeam (int team) - { - teamIndex = team; - } - - inline TechTree *getTechTree () const - { - return techTree; - } - const SwitchTeamVote *getFirstSwitchTeamVote () const; - SwitchTeamVote *getSwitchTeamVote (int factionIndex); - void setSwitchTeamVote (SwitchTeamVote & vote); - inline int getCurrentSwitchTeamVoteFactionIndex () const - { - return currentSwitchTeamVoteFactionIndex; - } - void setCurrentSwitchTeamVoteFactionIndex (int index) - { - currentSwitchTeamVoteFactionIndex = index; - } - - bool getCpuControl (bool enableServerControlledAI, bool isNetworkGame, - NetworkRole role) const; - bool getCpuControl () const; - inline bool getCpuEasyControl () const - { - return control == ctCpuEasy; - } - inline bool getCpuUltraControl () const - { - return control == ctCpuUltra; - } - inline bool getCpuZetaControl () const - { - return control == ctCpuZeta; - } - inline ControlType getControlType () const - { - return control; - } - - FactionPersonalityType getPersonalityType () const; - void setPersonalityType (FactionPersonalityType pType) - { - overridePersonalityType = pType; - } - int getAIBehaviorStaticOverideValue (AIBehaviorStaticValueCategory type) - const; - - inline Unit *getUnit (int i) const - { - Unit *result = units[i]; - return result; - } - inline int getUnitCount () const - { - int result = (int) units.size (); - return result; - } - inline Mutex *getUnitMutex () - { - return unitsMutex; - } - - inline const UpgradeManager *getUpgradeManager () const - { - return &upgradeManager; - } - inline const Texture2D *getTexture () const - { - return texture; - } - inline int getStartLocationIndex () const - { - return startLocationIndex; - } - inline bool getThisFaction () const - { - return thisFaction; - } - - //upgrades - void startUpgrade (const UpgradeType * ut); - void cancelUpgrade (const UpgradeType * ut); - void finishUpgrade (const UpgradeType * ut); - - //cost application - bool applyCosts (const ProducibleType * p, const CommandType * ct); - void applyDiscount (const ProducibleType * p, int discount); - void applyStaticCosts (const ProducibleType * p, - const CommandType * ct); - void applyStaticProduction (const ProducibleType * p, - const CommandType * ct); - void deApplyCosts (const ProducibleType * p, const CommandType * ct); - void deApplyStaticCosts (const ProducibleType * p, - const CommandType * ct); - void deApplyStaticConsumption (const ProducibleType * p, - const CommandType * ct); - void applyCostsOnInterval (const ResourceType * rtApply); - bool checkCosts (const ProducibleType * pt, const CommandType * ct); - - //reqs - bool reqsOk (const RequirableType * rt) const; - bool reqsOk (const CommandType * ct) const; - int getCountForMaxUnitCount (const UnitType * unitType) const; - - //diplomacy - bool isAlly (const Faction * faction); - - //other - Unit *findUnit (int id) const; - void addUnit (Unit * unit); - void removeUnit (Unit * unit); - void addStore (const UnitType * unitType); - void removeStore (const UnitType * unitType); - - //resources - void incResourceAmount (const ResourceType * rt, int amount); - void setResourceBalance (const ResourceType * rt, int balance); - - void setControlType (ControlType value) - { - control = value; - } - - bool isResourceTargetInCache (const Vec2i & pos, - bool incrementUseCounter = false); - void addResourceTargetToCache (const Vec2i & pos, - bool incrementUseCounter = true); - void removeResourceTargetFromCache (const Vec2i & pos); - void addCloseResourceTargetToCache (const Vec2i & pos); - Vec2i getClosestResourceTypeTargetFromCache (Unit * unit, - const ResourceType * type, - int frameIndex); - Vec2i getClosestResourceTypeTargetFromCache (const Vec2i & pos, - const ResourceType * type); - void cleanupResourceTypeTargetCache (std::vector < Vec2i > - *deleteListPtr, int frameIndex); - inline int getCacheResourceTargetListSize () const - { - return (int) cacheResourceTargetList.size (); - } - -// Unit * findClosestUnitWithSkillClass(const Vec2i &pos,const CommandClass &cmdClass, -// const std::vector &skillClassList, -// const UnitType *unitType); - - void deletePixels (); - - inline World *getWorld () - { - return world; - } - int getFrameCount (); - - void signalWorkerThread (int frameIndex); - bool isWorkerThreadSignalCompleted (int frameIndex); - FactionThread *getWorkerThread () - { - return workerThread; - } - - void limitResourcesToStore (); - - void sortUnitsByCommandGroups (); - - bool canCreateUnit (const UnitType * ut, bool checkBuild, - bool checkProduce, bool checkMorph) const; - - string getCacheStats (); - uint64 getCacheKBytes (uint64 * cache1Size, uint64 * cache2Size, - uint64 * cache3Size, uint64 * cache4Size, - uint64 * cache5Size); - - std::string toString (bool crcMode = false) const; - - void saveGame (XmlNode * rootNode); - void loadGame (const XmlNode * rootNode, int factionIndex, - GameSettings * settings, World * world); - - void clearCaches (); - - Checksum getCRC (); - void addCRC_DetailsForWorldFrame (int worldFrameCount, - bool isNetworkServer); - string getCRC_DetailsForWorldFrame (int worldFrameCount); - std::pair < int, - string > getCRC_DetailsForWorldFrameIndex (int worldFrameIndex) const; - string getCRC_DetailsForWorldFrames () const; - uint64 getCRC_DetailsForWorldFrameCount () const; - - void updateUnitTypeWithResourceCostCache (const ResourceType * rt); - bool hasUnitTypeWithResourceCostInCache (const ResourceType * rt) const; - - private: - void init (); - void resetResourceAmount (const ResourceType * rt); - bool hasUnitTypeWithResouceCost (const ResourceType * rt); - }; - -}} //end namespace +namespace Glest { + namespace Game { + + class Unit; + class TechTree; + class FactionType; + class ProducibleType; + class RequirableType; + class CommandType; + class UnitType; + class Game; + class ScriptManager; + class World; + class Faction; + class GameSettings; + class SurfaceCell; + + class FowAlphaCellsLookupItem { + public: + + std::map < Vec2i, float >surfPosAlphaList; + }; + + class ExploredCellsLookupItem { + public: + + ExploredCellsLookupItem() { + ExploredCellsLookupItemCacheTimerCountIndex = 0; + } + int ExploredCellsLookupItemCacheTimerCountIndex; + std::vector < SurfaceCell * >exploredCellList; + std::vector < SurfaceCell * >visibleCellList; + + static time_t lastDebug; + }; + + // ===================================================== + // class Faction + // + /// Each of the game players + // ===================================================== + + struct CommandGroupUnitSorter { + bool operator () (const Unit * l, const Unit * r); + bool compare(const Unit * l, const Unit * r); + }; + + struct CommandGroupUnitSorterId { + Faction *faction; + bool operator () (const int l, const int r); + }; + + class FactionThread :public BaseThread, + public SlaveThreadControllerInterface { + protected: + + Faction * faction; + Semaphore semTaskSignalled; + Mutex *triggerIdMutex; + std::pair < int, bool > frameIndex; + MasterSlaveThreadController *masterController; + + virtual void setQuitStatus(bool value); + virtual void setTaskCompleted(int frameIndex); + virtual bool canShutdown(bool deleteSelfIfShutdownDelayed = false); + + public: + explicit FactionThread(Faction * faction); + virtual ~FactionThread(); + virtual void execute(); + + virtual void setMasterController(MasterSlaveThreadController * master) { + masterController = master; + } + virtual void signalSlave(void *userdata) { + signalPathfinder(*((int *) (userdata))); + } + + void signalPathfinder(int frameIndex); + bool isSignalPathfinderCompleted(int frameIndex); + }; + + class SwitchTeamVote { + public: + + int factionIndex; + int oldTeam; + int newTeam; + bool voted; + bool allowSwitchTeam; + }; + + class Faction { + private: + typedef vector < Resource > Resources; + typedef vector < Resource > Store; + typedef vector < Faction * >Allies; + typedef vector < Unit * >Units; + typedef map < int, Unit * >UnitMap; + + private: + UpgradeManager upgradeManager; + + Resources resources; + Store store; + Allies allies; + + Mutex *unitsMutex; + Units units; + UnitMap unitMap; + World *world; + ScriptManager *scriptManager; + + FactionPersonalityType overridePersonalityType; + ControlType control; + + Texture2D *texture; + FactionType *factionType; + + int index; + int teamIndex; + int startLocationIndex; + + bool thisFaction; + + bool factionDisconnectHandled; + + bool cachingDisabled; + std::map < Vec2i, int >cacheResourceTargetList; + std::map < Vec2i, bool > cachedCloseResourceTargetLookupList; + + RandomGen random; + FactionThread *workerThread; + + std::map < int, SwitchTeamVote > switchTeamVotes; + int currentSwitchTeamVoteFactionIndex; + + bool allowSharedTeamUnits; + set < int >livingUnits; + set < Unit * >livingUnitsp; + + std::map < int, int >unitsMovingList; + std::map < int, int >unitsPathfindingList; + + std::set < const UnitType *>lockedUnits; + + TechTree *techTree; + const XmlNode *loadWorldNode; + + std::vector < string > worldSynchThreadedLogList; + + std::map < int, string > crcWorldFrameDetails; + + std::map < int, const Unit *>aliveUnitListCache; + std::map < int, const Unit *>mobileUnitListCache; + std::map < int, const Unit *>beingBuiltUnitListCache; + + std::map < std::string, bool > resourceTypeCostCache; + + public: + Faction(); + ~Faction(); + + Faction(const Faction & obj) { + init(); + throw megaglest_runtime_error("class Faction is NOT safe to copy!"); + } + Faction & operator= (const Faction & obj) { + init(); + throw + megaglest_runtime_error("class Faction is NOT safe to assign!"); + } + + void notifyUnitAliveStatusChange(const Unit * unit); + void notifyUnitTypeChange(const Unit * unit, const UnitType * newType); + void notifyUnitSkillTypeChange(const Unit * unit, + const SkillType * newType); + bool hasAliveUnits(bool filterMobileUnits, + bool filterBuiltUnits) const; + + inline void addWorldSynchThreadedLogList(const string & data) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true) { + worldSynchThreadedLogList.push_back(data); + } + } + inline void clearWorldSynchThreadedLogList() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true) { + worldSynchThreadedLogList.clear(); + } + } + inline void dumpWorldSynchThreadedLogList() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch). + enabled == true) { + if (worldSynchThreadedLogList.empty() == false) { + for (unsigned int index = 0; + index < worldSynchThreadedLogList.size(); ++index) { + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, + worldSynchThreadedLogList[index]. + c_str()); + } + worldSynchThreadedLogList.clear(); + } + } + } + + inline void addLivingUnits(int id) { + livingUnits.insert(id); + } + inline void addLivingUnitsp(Unit * unit) { + livingUnitsp.insert(unit); + } + + inline bool isUnitInLivingUnitsp(Unit * unit) { + return (livingUnitsp.find(unit) != livingUnitsp.end()); + } + inline void deleteLivingUnits(int id) { + livingUnits.erase(id); + } + inline void deleteLivingUnitsp(Unit * unit) { + livingUnitsp.erase(unit); + } + + //std::map unitsMovingList; + void addUnitToMovingList(int unitId); + void removeUnitFromMovingList(int unitId); + //int getUnitMovingListCount(); + + void addUnitToPathfindingList(int unitId); + //void removeUnitFromPathfindingList(int unitId); + int getUnitPathfindingListCount(); + void clearUnitsPathfinding(); + bool canUnitsPathfind(); + + void setLockedUnitForFaction(const UnitType * ut, bool lock); + bool isUnitLocked(const UnitType * ut) const { + return lockedUnits.find(ut) != lockedUnits.end(); + } + + void init(FactionType * factionType, ControlType control, + TechTree * techTree, Game * game, int factionIndex, + int teamIndex, int startLocationIndex, bool thisFaction, + bool giveResources, const XmlNode * loadWorldNode = NULL); + void end(); + + inline bool getFactionDisconnectHandled() const { + return factionDisconnectHandled; + } + void setFactionDisconnectHandled(bool value) { + factionDisconnectHandled = value; + } + + //get + const Resource *getResource(const ResourceType * rt, + bool localFactionOnly = false) const; + inline const Resource *getResource(int i) const { + return &resources[i]; + } + int getStoreAmount(const ResourceType * rt, bool localFactionOnly = + false) const; + inline const FactionType *getType() const { + return factionType; + } + inline int getIndex() const { + return index; + } + + inline int getTeam() const { + return teamIndex; + } + void setTeam(int team) { + teamIndex = team; + } + + inline TechTree *getTechTree() const { + return techTree; + } + const SwitchTeamVote *getFirstSwitchTeamVote() const; + SwitchTeamVote *getSwitchTeamVote(int factionIndex); + void setSwitchTeamVote(SwitchTeamVote & vote); + inline int getCurrentSwitchTeamVoteFactionIndex() const { + return currentSwitchTeamVoteFactionIndex; + } + void setCurrentSwitchTeamVoteFactionIndex(int index) { + currentSwitchTeamVoteFactionIndex = index; + } + + bool getCpuControl(bool enableServerControlledAI, bool isNetworkGame, + NetworkRole role) const; + bool getCpuControl() const; + inline bool getCpuEasyControl() const { + return control == ctCpuEasy; + } + inline bool getCpuUltraControl() const { + return control == ctCpuUltra; + } + inline bool getCpuZetaControl() const { + return control == ctCpuZeta; + } + inline ControlType getControlType() const { + return control; + } + + FactionPersonalityType getPersonalityType() const; + void setPersonalityType(FactionPersonalityType pType) { + overridePersonalityType = pType; + } + int getAIBehaviorStaticOverideValue(AIBehaviorStaticValueCategory type) + const; + + inline Unit *getUnit(int i) const { + Unit *result = units[i]; + return result; + } + inline int getUnitCount() const { + int result = (int) units.size(); + return result; + } + inline Mutex *getUnitMutex() { + return unitsMutex; + } + + inline const UpgradeManager *getUpgradeManager() const { + return &upgradeManager; + } + inline const Texture2D *getTexture() const { + return texture; + } + inline int getStartLocationIndex() const { + return startLocationIndex; + } + inline bool getThisFaction() const { + return thisFaction; + } + + //upgrades + void startUpgrade(const UpgradeType * ut); + void cancelUpgrade(const UpgradeType * ut); + void finishUpgrade(const UpgradeType * ut); + + //cost application + bool applyCosts(const ProducibleType * p, const CommandType * ct); + void applyDiscount(const ProducibleType * p, int discount); + void applyStaticCosts(const ProducibleType * p, + const CommandType * ct); + void applyStaticProduction(const ProducibleType * p, + const CommandType * ct); + void deApplyCosts(const ProducibleType * p, const CommandType * ct); + void deApplyStaticCosts(const ProducibleType * p, + const CommandType * ct); + void deApplyStaticConsumption(const ProducibleType * p, + const CommandType * ct); + void applyCostsOnInterval(const ResourceType * rtApply); + bool checkCosts(const ProducibleType * pt, const CommandType * ct); + + //reqs + bool reqsOk(const RequirableType * rt) const; + bool reqsOk(const CommandType * ct) const; + int getCountForMaxUnitCount(const UnitType * unitType) const; + + //diplomacy + bool isAlly(const Faction * faction); + + //other + Unit *findUnit(int id) const; + void addUnit(Unit * unit); + void removeUnit(Unit * unit); + void addStore(const UnitType * unitType); + void removeStore(const UnitType * unitType); + + //resources + void incResourceAmount(const ResourceType * rt, int amount); + void setResourceBalance(const ResourceType * rt, int balance); + + void setControlType(ControlType value) { + control = value; + } + + bool isResourceTargetInCache(const Vec2i & pos, + bool incrementUseCounter = false); + void addResourceTargetToCache(const Vec2i & pos, + bool incrementUseCounter = true); + void removeResourceTargetFromCache(const Vec2i & pos); + void addCloseResourceTargetToCache(const Vec2i & pos); + Vec2i getClosestResourceTypeTargetFromCache(Unit * unit, + const ResourceType * type, + int frameIndex); + Vec2i getClosestResourceTypeTargetFromCache(const Vec2i & pos, + const ResourceType * type); + void cleanupResourceTypeTargetCache(std::vector < Vec2i > + *deleteListPtr, int frameIndex); + inline int getCacheResourceTargetListSize() const { + return (int) cacheResourceTargetList.size(); + } + + // Unit * findClosestUnitWithSkillClass(const Vec2i &pos,const CommandClass &cmdClass, + // const std::vector &skillClassList, + // const UnitType *unitType); + + void deletePixels(); + + inline World *getWorld() { + return world; + } + int getFrameCount(); + + void signalWorkerThread(int frameIndex); + bool isWorkerThreadSignalCompleted(int frameIndex); + FactionThread *getWorkerThread() { + return workerThread; + } + + void limitResourcesToStore(); + + void sortUnitsByCommandGroups(); + + bool canCreateUnit(const UnitType * ut, bool checkBuild, + bool checkProduce, bool checkMorph) const; + + string getCacheStats(); + uint64 getCacheKBytes(uint64 * cache1Size, uint64 * cache2Size, + uint64 * cache3Size, uint64 * cache4Size, + uint64 * cache5Size); + + std::string toString(bool crcMode = false) const; + + void saveGame(XmlNode * rootNode); + void loadGame(const XmlNode * rootNode, int factionIndex, + GameSettings * settings, World * world); + + void clearCaches(); + + Checksum getCRC(); + void addCRC_DetailsForWorldFrame(int worldFrameCount, + bool isNetworkServer); + string getCRC_DetailsForWorldFrame(int worldFrameCount); + std::pair < int, + string > getCRC_DetailsForWorldFrameIndex(int worldFrameIndex) const; + string getCRC_DetailsForWorldFrames() const; + uint64 getCRC_DetailsForWorldFrameCount() const; + + void updateUnitTypeWithResourceCostCache(const ResourceType * rt); + bool hasUnitTypeWithResourceCostInCache(const ResourceType * rt) const; + + private: + void init(); + void resetResourceAmount(const ResourceType * rt); + bool hasUnitTypeWithResouceCost(const ResourceType * rt); + }; + + } +} //end namespace #endif diff --git a/source/glest_game/type_instances/object.cpp b/source/glest_game/type_instances/object.cpp index 54c2f4d59..592d5d6e4 100644 --- a/source/glest_game/type_instances/object.cpp +++ b/source/glest_game/type_instances/object.cpp @@ -26,382 +26,324 @@ using namespace Shared::Util; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - ObjectStateInterface *Object::stateCallback = NULL; + ObjectStateInterface *Object::stateCallback = NULL; -// ===================================================== -// class Object -// ===================================================== + // ===================================================== + // class Object + // ===================================================== - Object::Object (ObjectType * objectType, const Vec3f & pos, - const Vec2i & mapPos):BaseColorPickEntity () - { - RandomGen random; + Object::Object(ObjectType * objectType, const Vec3f & pos, + const Vec2i & mapPos) :BaseColorPickEntity() { + RandomGen random; - random.init (static_cast < int >(pos.x * pos.z)); - this->lastRenderFrame = 0; - this->objectType = objectType; - resource = NULL; - highlight = 0.f; - animated = false; - this->mapPos = mapPos; - this->pos = - pos + Vec3f (random.randRange (-0.6f, 0.6f), 0.0f, - random.randRange (-0.6f, 0.6f)); - rotation = random.randRange (0.f, 360.f); - if (objectType != NULL) - { - variation = random.randRange (0, objectType->getModelCount () - 1); - TilesetModelType *tmt = objectType->getTilesetModelType (variation); - if (tmt->getRotationAllowed () != true) - { - rotation = 0; - } - if (tmt->getRandomPositionEnabled () != true) - { - this->pos = pos; - } - animated = tmt->getAnimSpeed () > 0; - } - else - { - variation = 0; - } - visible = false; - animProgress = 0.0f; - } + random.init(static_cast (pos.x * pos.z)); + this->lastRenderFrame = 0; + this->objectType = objectType; + resource = NULL; + highlight = 0.f; + animated = false; + this->mapPos = mapPos; + this->pos = + pos + Vec3f(random.randRange(-0.6f, 0.6f), 0.0f, + random.randRange(-0.6f, 0.6f)); + rotation = random.randRange(0.f, 360.f); + if (objectType != NULL) { + variation = random.randRange(0, objectType->getModelCount() - 1); + TilesetModelType *tmt = objectType->getTilesetModelType(variation); + if (tmt->getRotationAllowed() != true) { + rotation = 0; + } + if (tmt->getRandomPositionEnabled() != true) { + this->pos = pos; + } + animated = tmt->getAnimSpeed() > 0; + } else { + variation = 0; + } + visible = false; + animProgress = 0.0f; + } - Object::~Object () - { - Renderer & renderer = Renderer::getInstance (); - // fade(and by this remove) all unit particle systems - while (unitParticleSystems.empty () == false) - { - bool particleValid = - renderer.validateParticleSystemStillExists (unitParticleSystems. - back (), rsGame); - if (particleValid == true) - { - unitParticleSystems.back ()->fade (); - } - unitParticleSystems.pop_back (); - } - Renderer::getInstance ().removeParticleSystemsForParticleOwner (this, - rsGame); - renderer.removeObjectFromQuadCache (this); - if (stateCallback) - { - stateCallback->removingObjectEvent (this); - } - delete resource; - resource = NULL; + Object::~Object() { + Renderer & renderer = Renderer::getInstance(); + // fade(and by this remove) all unit particle systems + while (unitParticleSystems.empty() == false) { + bool particleValid = + renderer.validateParticleSystemStillExists(unitParticleSystems. + back(), rsGame); + if (particleValid == true) { + unitParticleSystems.back()->fade(); + } + unitParticleSystems.pop_back(); + } + Renderer::getInstance().removeParticleSystemsForParticleOwner(this, + rsGame); + renderer.removeObjectFromQuadCache(this); + if (stateCallback) { + stateCallback->removingObjectEvent(this); + } + delete resource; + resource = NULL; - } + } - void Object::end () - { - // set Objects to fading and remove them from list. - // its needed because otherwise they will be accessed from the destructor - while (unitParticleSystems.empty () == false) - { - bool particleValid = - Renderer::getInstance (). - validateParticleSystemStillExists (unitParticleSystems.back (), - rsGame); - if (particleValid == true) - { - unitParticleSystems.back ()->fade (); - } - unitParticleSystems.pop_back (); - } - } + void Object::end() { + // set Objects to fading and remove them from list. + // its needed because otherwise they will be accessed from the destructor + while (unitParticleSystems.empty() == false) { + bool particleValid = + Renderer::getInstance(). + validateParticleSystemStillExists(unitParticleSystems.back(), + rsGame); + if (particleValid == true) { + unitParticleSystems.back()->fade(); + } + unitParticleSystems.pop_back(); + } + } - void Object::initParticles () - { - if (this->objectType == NULL) - { - return; - } - if (this->objectType->getTilesetModelType (variation)->hasParticles ()) - { - ModelParticleSystemTypes *particleTypes = - this->objectType->getTilesetModelType (variation)-> - getParticleTypes (); - initParticlesFromTypes (particleTypes); - } - } + void Object::initParticles() { + if (this->objectType == NULL) { + return; + } + if (this->objectType->getTilesetModelType(variation)->hasParticles()) { + ModelParticleSystemTypes *particleTypes = + this->objectType->getTilesetModelType(variation)-> + getParticleTypes(); + initParticlesFromTypes(particleTypes); + } + } - void Object::initParticlesFromTypes (const ModelParticleSystemTypes * - particleTypes) - { - bool showTilesetParticles = - Config::getInstance ().getBool ("TilesetParticles", "true"); - if (showTilesetParticles == true - && GlobalStaticFlags::getIsNonGraphicalModeEnabled () == false - && particleTypes->empty () == false - && unitParticleSystems.empty () == true) - { - for (ObjectParticleSystemTypes::const_iterator it = - particleTypes->begin (); it != particleTypes->end (); ++it) - { - UnitParticleSystem *ups = new UnitParticleSystem (200); - ups->setParticleOwner (this); - ups->setParticleType ((*it)); - (*it)->setValues (ups); - ups->setPos (this->pos); - ups->setRotation (this->rotation); - ups->setFactionColor (Vec3f (0, 0, 0)); - ups->setVisible (false); - this->unitParticleSystems.push_back (ups); - Renderer::getInstance ().manageParticleSystem (ups, rsGame); - } - } - } + void Object::initParticlesFromTypes(const ModelParticleSystemTypes * + particleTypes) { + bool showTilesetParticles = + Config::getInstance().getBool("TilesetParticles", "true"); + if (showTilesetParticles == true + && GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false + && particleTypes->empty() == false + && unitParticleSystems.empty() == true) { + for (ObjectParticleSystemTypes::const_iterator it = + particleTypes->begin(); it != particleTypes->end(); ++it) { + UnitParticleSystem *ups = new UnitParticleSystem(200); + ups->setParticleOwner(this); + ups->setParticleType((*it)); + (*it)->setValues(ups); + ups->setPos(this->pos); + ups->setRotation(this->rotation); + ups->setFactionColor(Vec3f(0, 0, 0)); + ups->setVisible(false); + this->unitParticleSystems.push_back(ups); + Renderer::getInstance().manageParticleSystem(ups, rsGame); + } + } + } - void Object::end (ParticleSystem * particleSystem) - { - vector < UnitParticleSystem * >::iterator iterFind = - find (unitParticleSystems.begin (), unitParticleSystems.end (), - particleSystem); - if (iterFind != unitParticleSystems.end ()) - { - unitParticleSystems.erase (iterFind); - } - } + void Object::end(ParticleSystem * particleSystem) { + vector < UnitParticleSystem * >::iterator iterFind = + find(unitParticleSystems.begin(), unitParticleSystems.end(), + particleSystem); + if (iterFind != unitParticleSystems.end()) { + unitParticleSystems.erase(iterFind); + } + } - void Object::setHeight (float height) - { - pos.y = height; + void Object::setHeight(float height) { + pos.y = height; - for (UnitParticleSystems::iterator it = unitParticleSystems.begin (); - it != unitParticleSystems.end (); ++it) - { - bool particleValid = - Renderer::getInstance ().validateParticleSystemStillExists ((*it), - rsGame); - if (particleValid == true) - { - (*it)->setPos (this->pos); - } - } - } + for (UnitParticleSystems::iterator it = unitParticleSystems.begin(); + it != unitParticleSystems.end(); ++it) { + bool particleValid = + Renderer::getInstance().validateParticleSystemStillExists((*it), + rsGame); + if (particleValid == true) { + (*it)->setPos(this->pos); + } + } + } - void Object::updateHighlight () - { - //highlight - if (highlight > 0.f) - { - //const Game *game = Renderer::getInstance().getGame(); - //highlight -= 1.f / (Game::highlightTime * game->getWorld()->getUpdateFps(-1)); - highlight -= 1.f / (Game::highlightTime * GameConstants::updateFps); - } - } + void Object::updateHighlight() { + //highlight + if (highlight > 0.f) { + //const Game *game = Renderer::getInstance().getGame(); + //highlight -= 1.f / (Game::highlightTime * game->getWorld()->getUpdateFps(-1)); + highlight -= 1.f / (Game::highlightTime * GameConstants::updateFps); + } + } - void Object::update () - { - //if(objectType != NULL && objectType->getTilesetModelType(variation) != NULL && - // objectType->getTilesetModelType(variation)->getAnimSpeed() != 0.0) { - if (animated == true) - { -// printf("#1 Object updating [%s] Speed [%d] animProgress [%f]\n",this->objectType->getTilesetModelType(variation)->getModel()->getFileName().c_str(),objectType->getTilesetModelType(variation)->getAnimSpeed(),animProgress); + void Object::update() { + //if(objectType != NULL && objectType->getTilesetModelType(variation) != NULL && + // objectType->getTilesetModelType(variation)->getAnimSpeed() != 0.0) { + if (animated == true) { + // printf("#1 Object updating [%s] Speed [%d] animProgress [%f]\n",this->objectType->getTilesetModelType(variation)->getModel()->getFileName().c_str(),objectType->getTilesetModelType(variation)->getAnimSpeed(),animProgress); - if (objectType != NULL - && objectType->getTilesetModelType (variation) != NULL) - { - float heightFactor = 1.f; - const float speedDivider = 100.f; - float speedDenominator = (speedDivider * GameConstants::updateFps); + if (objectType != NULL + && objectType->getTilesetModelType(variation) != NULL) { + float heightFactor = 1.f; + const float speedDivider = 100.f; + float speedDenominator = (speedDivider * GameConstants::updateFps); - // smooth TwoFrameanimations - float f = 1.0f; - if (objectType->getTilesetModelType (variation)-> - getSmoothTwoFrameAnim () == true) - { - f = abs (std::sin (animProgress * 2 * 3.16)) + 0.4f; - } + // smooth TwoFrameanimations + float f = 1.0f; + if (objectType->getTilesetModelType(variation)-> + getSmoothTwoFrameAnim() == true) { + f = abs(std::sin(animProgress * 2 * 3.16)) + 0.4f; + } - float newAnimProgress = - animProgress + - f * - (((float) objectType->getTilesetModelType (variation)-> - getAnimSpeed () * heightFactor) / speedDenominator); + float newAnimProgress = + animProgress + + f * + (((float) objectType->getTilesetModelType(variation)-> + getAnimSpeed() * heightFactor) / speedDenominator); - animProgress = newAnimProgress; - if (animProgress > 1.f) - { - animProgress = 0.f; - } - } - } - } + animProgress = newAnimProgress; + if (animProgress > 1.f) { + animProgress = 0.f; + } + } + } + } - void Object::resetHighlight () - { - highlight = 1.f; - } + void Object::resetHighlight() { + highlight = 1.f; + } - Model *Object::getModelPtr () const - { - Model *result = NULL; - if (objectType == NULL) - { - if (resource != NULL && resource->getType () != NULL) - { - result = resource->getType ()->getModel (); - } - } - else - { - result = objectType->getTilesetModelType (variation)->getModel (); - } - return result; - } + Model *Object::getModelPtr() const { + Model *result = NULL; + if (objectType == NULL) { + if (resource != NULL && resource->getType() != NULL) { + result = resource->getType()->getModel(); + } + } else { + result = objectType->getTilesetModelType(variation)->getModel(); + } + return result; + } - const Model *Object::getModel () const - { - Model *result = NULL; - if (objectType == NULL) - { - if (resource != NULL && resource->getType () != NULL) - { - result = resource->getType ()->getModel (); - } - } - else - { - result = objectType->getTilesetModelType (variation)->getModel (); - } - return result; - } + const Model *Object::getModel() const { + Model *result = NULL; + if (objectType == NULL) { + if (resource != NULL && resource->getType() != NULL) { + result = resource->getType()->getModel(); + } + } else { + result = objectType->getTilesetModelType(variation)->getModel(); + } + return result; + } - bool Object::getWalkable () const - { - return objectType == NULL ? false : objectType->getWalkable (); - } + bool Object::getWalkable() const { + return objectType == NULL ? false : objectType->getWalkable(); + } - void Object::setResource (const ResourceType * resourceType, - const Vec2i & pos) - { - delete resource; - resource = new Resource (); - resource->init (resourceType, pos); - initParticlesFromTypes (resourceType->getObjectParticleSystemTypes ()); - } + void Object::setResource(const ResourceType * resourceType, + const Vec2i & pos) { + delete resource; + resource = new Resource(); + resource->init(resourceType, pos); + initParticlesFromTypes(resourceType->getObjectParticleSystemTypes()); + } - void Object::setVisible (bool visible) - { - this->visible = visible; - for (UnitParticleSystems::iterator it = unitParticleSystems.begin (); - it != unitParticleSystems.end (); ++it) - { - bool particleValid = - Renderer::getInstance ().validateParticleSystemStillExists ((*it), - rsGame); - if (particleValid == true) - { - (*it)->setVisible (visible); - } - } - } + void Object::setVisible(bool visible) { + this->visible = visible; + for (UnitParticleSystems::iterator it = unitParticleSystems.begin(); + it != unitParticleSystems.end(); ++it) { + bool particleValid = + Renderer::getInstance().validateParticleSystemStillExists((*it), + rsGame); + if (particleValid == true) { + (*it)->setVisible(visible); + } + } + } - string Object::getUniquePickName () const - { - string result = ""; - if (resource != NULL) - { - result += resource->getDescription (false) + " : "; - } - result += mapPos.getString (); - return result; - } + string Object::getUniquePickName() const { + string result = ""; + if (resource != NULL) { + result += resource->getDescription(false) + " : "; + } + result += mapPos.getString(); + return result; + } - void Object::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode *objectNode = rootNode->addChild ("Object"); + void Object::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode *objectNode = rootNode->addChild("Object"); -// ObjectType *objectType; - if (objectType != NULL) - { - objectNode->addAttribute ("objectType", - intToStr (objectType->getClass ()), - mapTagReplacements); - } -// vector unitParticleSystems; - for (unsigned int i = 0; i < unitParticleSystems.size (); ++i) - { - UnitParticleSystem *ptr = unitParticleSystems[i]; - if (ptr != NULL) - { - ptr->saveGame (objectNode); - } - } -// Resource *resource; - if (resource != NULL) - { - resource->saveGame (objectNode); - } -// Vec3f pos; - objectNode->addAttribute ("pos", pos.getString (), mapTagReplacements); -// float rotation; - objectNode->addAttribute ("rotation", floatToStr (rotation, 6), - mapTagReplacements); -// int variation; - objectNode->addAttribute ("variation", intToStr (variation), - mapTagReplacements); -// int lastRenderFrame; - objectNode->addAttribute ("lastRenderFrame", intToStr (lastRenderFrame), - mapTagReplacements); -// Vec2i mapPos; - objectNode->addAttribute ("mapPos", mapPos.getString (), - mapTagReplacements); -// bool visible; - objectNode->addAttribute ("visible", intToStr (visible), - mapTagReplacements); - } + // ObjectType *objectType; + if (objectType != NULL) { + objectNode->addAttribute("objectType", + intToStr(objectType->getClass()), + mapTagReplacements); + } + // vector unitParticleSystems; + for (unsigned int i = 0; i < unitParticleSystems.size(); ++i) { + UnitParticleSystem *ptr = unitParticleSystems[i]; + if (ptr != NULL) { + ptr->saveGame(objectNode); + } + } + // Resource *resource; + if (resource != NULL) { + resource->saveGame(objectNode); + } + // Vec3f pos; + objectNode->addAttribute("pos", pos.getString(), mapTagReplacements); + // float rotation; + objectNode->addAttribute("rotation", floatToStr(rotation, 6), + mapTagReplacements); + // int variation; + objectNode->addAttribute("variation", intToStr(variation), + mapTagReplacements); + // int lastRenderFrame; + objectNode->addAttribute("lastRenderFrame", intToStr(lastRenderFrame), + mapTagReplacements); + // Vec2i mapPos; + objectNode->addAttribute("mapPos", mapPos.getString(), + mapTagReplacements); + // bool visible; + objectNode->addAttribute("visible", intToStr(visible), + mapTagReplacements); + } - void Object::loadGame (const XmlNode * rootNode, - const TechTree * techTree) - { - const XmlNode *objectNode = rootNode->getChild ("Object"); + void Object::loadGame(const XmlNode * rootNode, + const TechTree * techTree) { + const XmlNode *objectNode = rootNode->getChild("Object"); - //description = objectNode->getAttribute("description")->getValue(); + //description = objectNode->getAttribute("description")->getValue(); - // ObjectType *objectType; -// if(objectType != NULL) { -// objectNode->addAttribute("objectType",intToStr(objectType->getClass()), mapTagReplacements); -// } -// // vector unitParticleSystems; -// for(unsigned int i = 0; i < unitParticleSystems.size(); ++i) { -// UnitParticleSystem *ptr= unitParticleSystems[i]; -// if(ptr != NULL) { -// ptr->saveGame(objectNode); -// } -// } - // Resource *resource; - if (resource != NULL) - { - resource->loadGame (objectNode, 0, techTree); - } - // Vec3f pos; - pos = Vec3f::strToVec3 (objectNode->getAttribute ("pos")->getValue ()); - // float rotation; - rotation = objectNode->getAttribute ("rotation")->getFloatValue (); - // int variation; - variation = objectNode->getAttribute ("variation")->getIntValue (); - // int lastRenderFrame; - lastRenderFrame = - objectNode->getAttribute ("lastRenderFrame")->getIntValue (); - // Vec2i mapPos; - mapPos = - Vec2i::strToVec2 (objectNode->getAttribute ("mapPos")->getValue ()); - // bool visible; - visible = objectNode->getAttribute ("visible")->getIntValue () != 0; - } + // ObjectType *objectType; + // if(objectType != NULL) { + // objectNode->addAttribute("objectType",intToStr(objectType->getClass()), mapTagReplacements); + // } + // // vector unitParticleSystems; + // for(unsigned int i = 0; i < unitParticleSystems.size(); ++i) { + // UnitParticleSystem *ptr= unitParticleSystems[i]; + // if(ptr != NULL) { + // ptr->saveGame(objectNode); + // } + // } + // Resource *resource; + if (resource != NULL) { + resource->loadGame(objectNode, 0, techTree); + } + // Vec3f pos; + pos = Vec3f::strToVec3(objectNode->getAttribute("pos")->getValue()); + // float rotation; + rotation = objectNode->getAttribute("rotation")->getFloatValue(); + // int variation; + variation = objectNode->getAttribute("variation")->getIntValue(); + // int lastRenderFrame; + lastRenderFrame = + objectNode->getAttribute("lastRenderFrame")->getIntValue(); + // Vec2i mapPos; + mapPos = + Vec2i::strToVec2(objectNode->getAttribute("mapPos")->getValue()); + // bool visible; + visible = objectNode->getAttribute("visible")->getIntValue() != 0; + } - } + } } //end namespace diff --git a/source/glest_game/type_instances/object.h b/source/glest_game/type_instances/object.h index 6e6ed1da8..a2c19536a 100644 --- a/source/glest_game/type_instances/object.h +++ b/source/glest_game/type_instances/object.h @@ -23,150 +23,131 @@ # include "object_type.h" # include "tileset_model_type.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - class ObjectType; - class ResourceType; - class Resource; - class TechTree; + class ObjectType; + class ResourceType; + class Resource; + class TechTree; - using Shared::Graphics::Model; - using Shared::Graphics::Vec2i; - using Shared::Graphics::Vec3f; - using Shared::Graphics::UnitParticleSystem; + using Shared::Graphics::Model; + using Shared::Graphics::Vec2i; + using Shared::Graphics::Vec3f; + using Shared::Graphics::UnitParticleSystem; -// ===================================================== -// class Object -// -/// A map object: tree, stone... -// ===================================================== + // ===================================================== + // class Object + // + /// A map object: tree, stone... + // ===================================================== - class Object; + class Object; - class ObjectStateInterface - { - public: - virtual void removingObjectEvent (Object * object) = 0; - virtual ~ ObjectStateInterface () - { - } - }; + class ObjectStateInterface { + public: + virtual void removingObjectEvent(Object * object) = 0; + virtual ~ObjectStateInterface() { + } + }; - class Object:public BaseColorPickEntity, public ParticleOwner - { - private: - typedef vector < UnitParticleSystem * >UnitParticleSystems; + class Object :public BaseColorPickEntity, public ParticleOwner { + private: + typedef vector < UnitParticleSystem * >UnitParticleSystems; - private: - ObjectType * objectType; - vector < UnitParticleSystem * >unitParticleSystems; - Resource *resource; - Vec3f pos; - float rotation; - int variation; - int lastRenderFrame; - Vec2i mapPos; - bool visible; - bool animated; - float animProgress; - float highlight; + private: + ObjectType * objectType; + vector < UnitParticleSystem * >unitParticleSystems; + Resource *resource; + Vec3f pos; + float rotation; + int variation; + int lastRenderFrame; + Vec2i mapPos; + bool visible; + bool animated; + float animProgress; + float highlight; - static ObjectStateInterface *stateCallback; + static ObjectStateInterface *stateCallback; - public: - Object (ObjectType * objectType, const Vec3f & pos, - const Vec2i & mapPos); - virtual ~ Object (); + public: + Object(ObjectType * objectType, const Vec3f & pos, + const Vec2i & mapPos); + virtual ~Object(); - virtual void end (); //to kill particles - virtual void logParticleInfo (string info) - { - }; - void initParticles (); - void initParticlesFromTypes (const ModelParticleSystemTypes * - particleTypes); - static void setStateCallback (ObjectStateInterface * value) - { - stateCallback = value; - } + virtual void end(); //to kill particles + virtual void logParticleInfo(string info) { + }; + void initParticles(); + void initParticlesFromTypes(const ModelParticleSystemTypes * + particleTypes); + static void setStateCallback(ObjectStateInterface * value) { + stateCallback = value; + } - const ObjectType *getType () const - { - return objectType; - } - Resource *getResource () const - { - return resource; - } - Vec3f getPos () const - { - return pos; - } - bool isVisible () const - { - return visible; - } - const Vec3f & getConstPos () const - { - return pos; - } - float getRotation () const - { - return rotation; - } - const Model *getModel () const; - Model *getModelPtr () const; - bool getWalkable () const; - bool isAnimated () const - { - return animated; - } + const ObjectType *getType() const { + return objectType; + } + Resource *getResource() const { + return resource; + } + Vec3f getPos() const { + return pos; + } + bool isVisible() const { + return visible; + } + const Vec3f & getConstPos() const { + return pos; + } + float getRotation() const { + return rotation; + } + const Model *getModel() const; + Model *getModelPtr() const; + bool getWalkable() const; + bool isAnimated() const { + return animated; + } - float getHightlight () const - { - return highlight; - } - bool isHighlighted () const - { - return highlight > 0.f; - } - void resetHighlight (); + float getHightlight() const { + return highlight; + } + bool isHighlighted() const { + return highlight > 0.f; + } + void resetHighlight(); - void setResource (const ResourceType * resourceType, const Vec2i & pos); - void setHeight (float height); - void setVisible (bool visible); + void setResource(const ResourceType * resourceType, const Vec2i & pos); + void setHeight(float height); + void setVisible(bool visible); - int getLastRenderFrame () const - { - return lastRenderFrame; - } - void setLastRenderFrame (int value) - { - lastRenderFrame = value; - } + int getLastRenderFrame() const { + return lastRenderFrame; + } + void setLastRenderFrame(int value) { + lastRenderFrame = value; + } - const Vec2i & getMapPos () const - { - return mapPos; - } + const Vec2i & getMapPos() const { + return mapPos; + } - void updateHighlight (); - void update (); - float getAnimProgress () const - { - return animProgress; - } + void updateHighlight(); + void update(); + float getAnimProgress() const { + return animProgress; + } - virtual string getUniquePickName () const; - void saveGame (XmlNode * rootNode); - void loadGame (const XmlNode * rootNode, const TechTree * techTree); + virtual string getUniquePickName() const; + void saveGame(XmlNode * rootNode); + void loadGame(const XmlNode * rootNode, const TechTree * techTree); - virtual void end (ParticleSystem * particleSystem); - }; + virtual void end(ParticleSystem * particleSystem); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/type_instances/resource.cpp b/source/glest_game/type_instances/resource.cpp index 3a607a556..691caeadd 100644 --- a/source/glest_game/type_instances/resource.cpp +++ b/source/glest_game/type_instances/resource.cpp @@ -22,165 +22,148 @@ using namespace Shared::Graphics; using namespace Shared::Util; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class Resource -// ===================================================== + // ===================================================== + // class Resource + // ===================================================== - Resource::Resource () - { - this->type = NULL; - this->amount = 0; - pos = Vec2i (0); - balance = 0; + Resource::Resource() { + this->type = NULL; + this->amount = 0; + pos = Vec2i(0); + balance = 0; - addItemToVault (&this->amount, this->amount); - addItemToVault (&this->balance, this->balance); - } + addItemToVault(&this->amount, this->amount); + addItemToVault(&this->balance, this->balance); + } - void Resource::init (const ResourceType * rt, int amount) - { - this->type = rt; - this->amount = amount; - pos = Vec2i (0); - balance = 0; + void Resource::init(const ResourceType * rt, int amount) { + this->type = rt; + this->amount = amount; + pos = Vec2i(0); + balance = 0; - addItemToVault (&this->amount, this->amount); - addItemToVault (&this->balance, this->balance); - } + addItemToVault(&this->amount, this->amount); + addItemToVault(&this->balance, this->balance); + } - void Resource::init (const ResourceType * rt, const Vec2i & pos) - { - this->type = rt; - amount = rt->getDefResPerPatch (); - this->pos = pos; + void Resource::init(const ResourceType * rt, const Vec2i & pos) { + this->type = rt; + amount = rt->getDefResPerPatch(); + this->pos = pos; - addItemToVault (&this->amount, this->amount); - addItemToVault (&this->balance, this->balance); - } + addItemToVault(&this->amount, this->amount); + addItemToVault(&this->balance, this->balance); + } - string Resource::getDescription (bool translatedValue) const - { - string str; + string Resource::getDescription(bool translatedValue) const { + string str; - str += type->getName (translatedValue); - str += "\n"; - str += intToStr (amount); - str += "/"; - str += intToStr (type->getDefResPerPatch ()); + str += type->getName(translatedValue); + str += "\n"; + str += intToStr(amount); + str += "/"; + str += intToStr(type->getDefResPerPatch()); - return str; - } + return str; + } - int Resource::getAmount () const - { - checkItemInVault (&this->amount, this->amount); - return amount; - } + int Resource::getAmount() const { + checkItemInVault(&this->amount, this->amount); + return amount; + } - int Resource::getBalance () const - { - checkItemInVault (&this->balance, this->balance); - return balance; - } + int Resource::getBalance() const { + checkItemInVault(&this->balance, this->balance); + return balance; + } - void Resource::setAmount (int amount) - { - checkItemInVault (&this->amount, this->amount); - this->amount = amount; - addItemToVault (&this->amount, this->amount); - } + void Resource::setAmount(int amount) { + checkItemInVault(&this->amount, this->amount); + this->amount = amount; + addItemToVault(&this->amount, this->amount); + } - void Resource::setBalance (int balance) - { - checkItemInVault (&this->balance, this->balance); - this->balance = balance; - addItemToVault (&this->balance, this->balance); - } + void Resource::setBalance(int balance) { + checkItemInVault(&this->balance, this->balance); + this->balance = balance; + addItemToVault(&this->balance, this->balance); + } - bool Resource::decAmount (int i) - { - checkItemInVault (&this->amount, this->amount); - amount -= i; - addItemToVault (&this->amount, this->amount); + bool Resource::decAmount(int i) { + checkItemInVault(&this->amount, this->amount); + amount -= i; + addItemToVault(&this->amount, this->amount); - if (amount > 0) - { - return false; - } - return true; - } + if (amount > 0) { + return false; + } + return true; + } - void Resource::saveGame (XmlNode * rootNode) const - { - std::map < string, string > mapTagReplacements; - XmlNode *resourceNode = rootNode->addChild ("Resource"); + void Resource::saveGame(XmlNode * rootNode) const { + std::map < string, string > mapTagReplacements; + XmlNode *resourceNode = rootNode->addChild("Resource"); -// int amount; - resourceNode->addAttribute ("amount", intToStr (amount), - mapTagReplacements); -// const ResourceType *type; - resourceNode->addAttribute ("type", type->getName (), - mapTagReplacements); -// Vec2i pos; - resourceNode->addAttribute ("pos", pos.getString (), - mapTagReplacements); -// int balance; - resourceNode->addAttribute ("balance", intToStr (balance), - mapTagReplacements); - } + // int amount; + resourceNode->addAttribute("amount", intToStr(amount), + mapTagReplacements); + // const ResourceType *type; + resourceNode->addAttribute("type", type->getName(), + mapTagReplacements); + // Vec2i pos; + resourceNode->addAttribute("pos", pos.getString(), + mapTagReplacements); + // int balance; + resourceNode->addAttribute("balance", intToStr(balance), + mapTagReplacements); + } - void Resource::loadGame (const XmlNode * rootNode, int index, - const TechTree * techTree) - { - vector < XmlNode * >resourceNodeList = - rootNode->getChildList ("Resource"); + void Resource::loadGame(const XmlNode * rootNode, int index, + const TechTree * techTree) { + vector < XmlNode * >resourceNodeList = + rootNode->getChildList("Resource"); - if (index < (int) resourceNodeList.size ()) - { - XmlNode *resourceNode = resourceNodeList[index]; + if (index < (int) resourceNodeList.size()) { + XmlNode *resourceNode = resourceNodeList[index]; - amount = resourceNode->getAttribute ("amount")->getIntValue (); - type = - techTree->getResourceType (resourceNode->getAttribute ("type")-> - getValue ()); - pos = - Vec2i::strToVec2 (resourceNode->getAttribute ("pos")->getValue ()); - balance = resourceNode->getAttribute ("balance")->getIntValue (); - } - } + amount = resourceNode->getAttribute("amount")->getIntValue(); + type = + techTree->getResourceType(resourceNode->getAttribute("type")-> + getValue()); + pos = + Vec2i::strToVec2(resourceNode->getAttribute("pos")->getValue()); + balance = resourceNode->getAttribute("balance")->getIntValue(); + } + } - std::string Resource::toString ()const - { - std::string result = - "resource name = " + this->getDescription (false) + "\n"; - result += "amount = " + intToStr (this->amount) + "\n"; - result += "type = " + this->type->getName (false) + "\n"; - result += - "type resources per patch = " + - intToStr (type->getDefResPerPatch ()) + "\n"; - result += "pos = " + this->pos.getString () + "\n"; - result += "balance = " + intToStr (this->balance) + "\n"; + std::string Resource::toString()const { + std::string result = + "resource name = " + this->getDescription(false) + "\n"; + result += "amount = " + intToStr(this->amount) + "\n"; + result += "type = " + this->type->getName(false) + "\n"; + result += + "type resources per patch = " + + intToStr(type->getDefResPerPatch()) + "\n"; + result += "pos = " + this->pos.getString() + "\n"; + result += "balance = " + intToStr(this->balance) + "\n"; - return result; - } + return result; + } - Checksum Resource::getCRC () - { - Checksum crcForResource; + Checksum Resource::getCRC() { + Checksum crcForResource; - crcForResource.addInt (amount); - crcForResource.addString (type->getName (false)); - crcForResource.addInt (pos.x); - crcForResource.addInt (pos.y); - crcForResource.addInt (balance); + crcForResource.addInt(amount); + crcForResource.addString(type->getName(false)); + crcForResource.addInt(pos.x); + crcForResource.addInt(pos.y); + crcForResource.addInt(balance); - return crcForResource; - } + return crcForResource; + } - } + } } //end namespace diff --git a/source/glest_game/type_instances/resource.h b/source/glest_game/type_instances/resource.h index e9a23fef2..de107ee9c 100644 --- a/source/glest_game/type_instances/resource.h +++ b/source/glest_game/type_instances/resource.h @@ -26,61 +26,57 @@ using std::string; using std::map; using Shared::Xml::XmlNode; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - using Shared::Graphics::Vec2i; - using Shared::PlatformCommon::ValueCheckerVault; + using Shared::Graphics::Vec2i; + using Shared::PlatformCommon::ValueCheckerVault; - class ResourceType; - class TechTree; -// ===================================================== -// class Resource -// -/// Amount of a given ResourceType -// ===================================================== + class ResourceType; + class TechTree; + // ===================================================== + // class Resource + // + /// Amount of a given ResourceType + // ===================================================== - class Resource:public ValueCheckerVault - { - private: - int amount; - const ResourceType *type; - Vec2i pos; - int balance; + class Resource :public ValueCheckerVault { + private: + int amount; + const ResourceType *type; + Vec2i pos; + int balance; - public: - Resource (); - void init (const ResourceType * rt, int amount); - void init (const ResourceType * rt, const Vec2i & pos); + public: + Resource(); + void init(const ResourceType * rt, int amount); + void init(const ResourceType * rt, const Vec2i & pos); - const ResourceType *getType () const - { - return type; - } - Vec2i getPos () const - { - return pos; - } + const ResourceType *getType() const { + return type; + } + Vec2i getPos() const { + return pos; + } - int getAmount () const; - int getBalance () const; - string getDescription (bool translatedValue) const; + int getAmount() const; + int getBalance() const; + string getDescription(bool translatedValue) const; - void setAmount (int amount); - void setBalance (int balance); + void setAmount(int amount); + void setBalance(int balance); - bool decAmount (int i); + bool decAmount(int i); - void saveGame (XmlNode * rootNode) const; - void loadGame (const XmlNode * rootNode, int index, - const TechTree * techTree); + void saveGame(XmlNode * rootNode) const; + void loadGame(const XmlNode * rootNode, int index, + const TechTree * techTree); - std::string toString () const; - Checksum getCRC (); - }; + std::string toString() const; + Checksum getCRC(); + }; -}} // end namespace + } +} // end namespace #endif diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 9de364203..1d17ed258 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -33,8194 +33,7218 @@ using namespace Shared::Graphics; using namespace Shared::Util; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - const int CHANGE_COMMAND_SPEED = 325; - const uint32 MIN_FRAMECOUNT_CHANGE_COMMAND_SPEED = 160; + const int CHANGE_COMMAND_SPEED = 325; + const uint32 MIN_FRAMECOUNT_CHANGE_COMMAND_SPEED = 160; -//Mutex Unit::mutexDeletedUnits; -//map Unit::deletedUnits; + //Mutex Unit::mutexDeletedUnits; + //map Unit::deletedUnits; - const int UnitPathBasic::maxBlockCount = GameConstants::updateFps / 2; + const int UnitPathBasic::maxBlockCount = GameConstants::updateFps / 2; #ifdef LEAK_CHECK_UNITS - std::map < UnitPathBasic *, bool > UnitPathBasic::mapMemoryList; - std::map < Unit *, bool > Unit::mapMemoryList; - std::map < UnitPathInterface *, int >Unit::mapMemoryList2; + std::map < UnitPathBasic *, bool > UnitPathBasic::mapMemoryList; + std::map < Unit *, bool > Unit::mapMemoryList; + std::map < UnitPathInterface *, int >Unit::mapMemoryList2; #endif - UnitPathBasic::UnitPathBasic ():UnitPathInterface () - { + UnitPathBasic::UnitPathBasic() :UnitPathInterface() { #ifdef LEAK_CHECK_UNITS - UnitPathBasic::mapMemoryList[this] = true; + UnitPathBasic::mapMemoryList[this] = true; #endif - this->blockCount = 0; - this->pathQueue.clear (); - this->map = NULL; - } + this->blockCount = 0; + this->pathQueue.clear(); + this->map = NULL; + } - UnitPathBasic::~UnitPathBasic () - { - this->blockCount = 0; - this->pathQueue.clear (); - this->map = NULL; + UnitPathBasic::~UnitPathBasic() { + this->blockCount = 0; + this->pathQueue.clear(); + this->map = NULL; #ifdef LEAK_CHECK_UNITS - UnitPathBasic::mapMemoryList.erase (this); + UnitPathBasic::mapMemoryList.erase(this); #endif - } + } #ifdef LEAK_CHECK_UNITS - void UnitPathBasic::dumpMemoryList () - { - printf ("===== START report of Unfreed UnitPathBasic pointers =====\n"); - for (std::map < UnitPathBasic *, bool >::iterator iterMap = - UnitPathBasic::mapMemoryList.begin (); - iterMap != UnitPathBasic::mapMemoryList.end (); ++iterMap) - { - printf ("************** ==> Unfreed UnitPathBasic pointer [%p]\n", - iterMap->first); - - if (Unit::mapMemoryList2.find (iterMap->first) != - Unit::mapMemoryList2.end ()) - { - printf ("Found owner unit id [%d]\n", - Unit::mapMemoryList2[iterMap->first]); - } - } - } -#endif - - void UnitPathBasic::clearCaches () - { - this->blockCount = 0; - this->pathQueue.clear (); - } - - bool UnitPathBasic::isEmpty () const - { - return pathQueue.empty (); - } - - bool UnitPathBasic::isBlocked () const - { - return blockCount >= maxBlockCount; - } - - bool UnitPathBasic::isStuck () const - { - return (isBlocked () == true && blockCount >= (maxBlockCount * 2)); - } - - void UnitPathBasic::clear () - { - pathQueue.clear (); - blockCount = 0; - } - - void UnitPathBasic::incBlockCount () - { - pathQueue.clear (); - blockCount++; - } - - void UnitPathBasic::add (const Vec2i & path) - { - if (this->map != NULL) - { - if (this->map->isInside (path) == false) - { - throw megaglest_runtime_error ("Invalid map path position = " + - path.getString () + " map w x h = " + - intToStr (map->getW ()) + " " + - intToStr (map->getH ())); - } - else if (this-> - map->isInsideSurface (this->map->toSurfCoords (path)) == - false) - { - throw - megaglest_runtime_error ("Invalid map surface path position = " + - path.getString () + - " map surface w x h = " + - intToStr (map->getSurfaceW ()) + " " + - intToStr (map->getSurfaceH ())); - } - } - - if (Thread::isCurrentThreadMainThread () == false) - { - throw - megaglest_runtime_error - ("Invalid access to UnitPathBasic add from outside main thread current id = " - + intToStr (Thread::getCurrentThreadId ()) + " main = " + - intToStr (Thread::getMainThreadId ())); - } - - pathQueue.push_back (path); - } - - Vec2i UnitPathBasic::pop (bool removeFrontPos) - { - if (pathQueue.empty () == true) - { - throw megaglest_runtime_error ("pathQueue.size() = " + - intToStr (pathQueue.size ())); - } - Vec2i p = pathQueue.front (); - if (removeFrontPos == true) - { - if (Thread::isCurrentThreadMainThread () == false) - { - throw - megaglest_runtime_error - ("Invalid access to UnitPathBasic delete from outside main thread current id = " - + intToStr (Thread::getCurrentThreadId ()) + " main = " + - intToStr (Thread::getMainThreadId ())); - } - - pathQueue.erase (pathQueue.begin ()); - } - return p; - } - std::string UnitPathBasic::toString ()const - { - std::string result = - "unit path blockCount = " + intToStr (blockCount) + - "\npathQueue size = " + intToStr (pathQueue.size ()); - for (int idx = 0; idx < (int) pathQueue.size (); ++idx) - { - result += - " index = " + intToStr (idx) + " value = " + - pathQueue[idx].getString (); - } - - return result; - } - - void UnitPathBasic::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode *unitPathBasicNode = rootNode->addChild ("UnitPathBasic"); - -// int blockCount; - unitPathBasicNode->addAttribute ("blockCount", intToStr (blockCount), - mapTagReplacements); -// vector pathQueue; - for (unsigned int i = 0; i < pathQueue.size (); ++i) - { - Vec2i & vec = pathQueue[i]; - - XmlNode *pathQueueNode = unitPathBasicNode->addChild ("pathQueue"); - pathQueueNode->addAttribute ("vec", vec.getString (), - mapTagReplacements); - } - } - - void UnitPathBasic::loadGame (const XmlNode * rootNode) - { - const XmlNode *unitPathBasicNode = rootNode->getChild ("UnitPathBasic"); - - blockCount = - unitPathBasicNode->getAttribute ("blockCount")->getIntValue (); - - pathQueue.clear (); - vector < XmlNode * >pathqueueNodeList = - unitPathBasicNode->getChildList ("pathQueue"); - for (unsigned int i = 0; i < pathqueueNodeList.size (); ++i) - { - XmlNode *node = pathqueueNodeList[i]; - - Vec2i vec = - Vec2i::strToVec2 (node->getAttribute ("vec")->getValue ()); - pathQueue.push_back (vec); - } - } - - Checksum UnitPathBasic::getCRC () - { - Checksum crcForPath; - - crcForPath.addInt (blockCount); - crcForPath.addInt ((int) pathQueue.size ()); - - return crcForPath; - } - -// ===================================================== -// class UnitPath -// ===================================================== - -//void WaypointPath::condense() { -// if (size() < 2) { -// return; -// } -// iterator prev, curr; -// prev = curr = begin(); -// while (++curr != end()) { -// if (prev->dist(*curr) < 3.f) { -// prev = erase(prev); -// } else { -// ++prev; -// } -// } -//} - - std::string UnitPath::toString ()const - { - std::string result = - "unit path blockCount = " + intToStr (blockCount) + - " pathQueue size = " + intToStr (size ()); - result += " path = "; - for (const_iterator it = begin (); it != end (); ++it) - { - result += " [" + intToStr (it->x) + "," + intToStr (it->y) + "]"; - } - - return result; - } - -// ===================================================== -// class UnitReference -// ===================================================== - - UnitReference::UnitReference () - { - id = -1; - faction = NULL; - } - - UnitReference & UnitReference::operator= (const Unit * unit) - { - if (unit == NULL) - { - id = -1; - faction = NULL; - } - else - { - id = unit->getId (); - faction = unit->getFaction (); - } - - return *this; - } - - Unit *UnitReference::getUnit () const - { - if (faction != NULL) - { - return faction->findUnit (id); - } - return NULL; - } - - void UnitReference::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode *unitRefNode = rootNode->addChild ("UnitReference"); - - unitRefNode->addAttribute ("id", intToStr (id), mapTagReplacements); - if (faction != NULL) - { - unitRefNode->addAttribute ("factionIndex", - intToStr (faction->getIndex ()), - mapTagReplacements); - } - } - - void UnitReference::loadGame (const XmlNode * rootNode, World * world) - { - const XmlNode *unitRefNode = rootNode->getChild ("UnitReference"); - - id = unitRefNode->getAttribute ("id")->getIntValue (); - if (unitRefNode->hasAttribute ("factionIndex") == true) - { - int factionIndex = - unitRefNode->getAttribute ("factionIndex")->getIntValue (); - if (factionIndex >= world->getFactionCount ()) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "factionIndex >= world->getFactionCount() [%d] : [%d]", - factionIndex, world->getFactionCount ()); - throw megaglest_runtime_error (szBuf); - } - faction = world->getFaction (factionIndex); - } - } - - const bool checkMemory = false; - static map < void *, int >memoryObjectList; - - UnitAttackBoostEffect::UnitAttackBoostEffect () - { - if (checkMemory) - { - printf ("++ Create UnitAttackBoostEffect [%p] before count = %d\n", - this, memoryObjectList[this]); - memoryObjectList[this]++; - printf ("++ Create UnitAttackBoostEffect [%p] after count = %d\n", - this, memoryObjectList[this]); - } - - unitId = -1; - unitPtr = NULL; - boost = NULL; - source = NULL; - ups = NULL; - upst = NULL; - } - - UnitAttackBoostEffect::~UnitAttackBoostEffect () - { - if (checkMemory) - { - printf ("-- Delete UnitAttackBoostEffect [%p] count = %d\n", this, - memoryObjectList[this]); - memoryObjectList[this]--; - assert (memoryObjectList[this] == 0); - } - - if (ups != NULL) - { - bool particleValid = - Renderer::getInstance ().validateParticleSystemStillExists (ups, - rsGame); - if (particleValid == true) - { - ups->fade (); - - vector < UnitParticleSystem * >particleSystemToRemove; - particleSystemToRemove.push_back (ups); - - Renderer:: - getInstance ().cleanupUnitParticleSystems (particleSystemToRemove, - rsGame); - ups = NULL; - } - } - - delete upst; - upst = NULL; - } - - const Unit *UnitAttackBoostEffect::getSource () - { - if (source == NULL && unitPtr != NULL && unitId > 0) - { - source = unitPtr->getFaction ()->findUnit (unitId); - - //printf("#1 Get source - boost effect unitId = %d unitPtr = %s source = %p\n",unitId,unitPtr->getFullName(false).c_str(),source); - } - //printf("#2 Get source - boost effect unitId = %d unitPtr = %s source = %p\n",unitId,unitPtr->getFullName(false).c_str(),source); - return source; - } - - void UnitAttackBoostEffect::setSource (const Unit * unit) - { - source = unit; - } - - void UnitAttackBoostEffect:: - applyLoadedAttackBoostParticles (UnitParticleSystemType * upstPtr, - const XmlNode * node, Unit * unit) - { - if (upstPtr != NULL) - { - bool showUnitParticles = - Config::getInstance ().getBool ("UnitParticles", "true"); - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == true) - { - showUnitParticles = false; - } - if (showUnitParticles == true) - { - upst = new UnitParticleSystemType (); - *upst = *upstPtr; - upst->loadGame (node); - - ups = new UnitParticleSystem (200); - //ups->loadGame(node2); - ups->setParticleOwner (unit); - ups->setParticleType (upst); - - upst->setValues (ups); - ups->setPos (unit->getCurrVectorForParticlesystems ()); - ups->setRotation (unit->getRotation ()); - unit->setMeshPosInParticleSystem (ups); - if (unit->getFaction ()->getTexture ()) - { - ups->setFactionColor (unit->getFaction ()-> - getTexture ()->getPixmapConst ()-> - getPixel3f (0, 0)); - } - //printf("Adding attack boost particle to deferred buffer: %p\n",ups); - Renderer:: - getInstance ().addToDeferredParticleSystemList (make_pair - (ups, rsGame)); - } - } - } - - void UnitAttackBoostEffect::loadGame (const XmlNode * rootNode, - Unit * unit, World * world, - bool applyToOriginator) - { - const XmlNode *unitAttackBoostEffectNode = rootNode; - - if (unitAttackBoostEffectNode->hasAttribute ("source") == true) - { - unitId = - unitAttackBoostEffectNode->getAttribute ("source")->getIntValue (); - unitPtr = unit; - source = unit->getFaction ()->findUnit (unitId); - -// printf("#1 Loaded boost effect unitId = %d unitPtr = [%d - %s] source = %p\n", -// unitId,unitPtr->getId(),unitPtr->getType()->getName(false).c_str(),source); - } - - // Lets determine the originator unit's attack boost based on the skill used to trigger it - if (unitAttackBoostEffectNode->hasAttribute ("source-faction") == true) - { - string factionName = - unitAttackBoostEffectNode-> - getAttribute ("source-faction")->getValue (); - string unitTypeName = - unitAttackBoostEffectNode-> - getAttribute ("source-unit-type")->getValue (); - string skillTypeName = - unitAttackBoostEffectNode-> - getAttribute ("source-skill-type")->getValue (); - SkillClass skillClass = - static_cast < SkillClass > - (unitAttackBoostEffectNode-> - getAttribute ("source-skill-class")->getIntValue ()); - - const UnitType *unitType = - world->findUnitTypeByName (factionName, unitTypeName); - if (unitType != NULL) - { - const SkillType *skillType = - unitType->getSkillType (skillTypeName, skillClass); - if (skillType != NULL) - { - boost = skillType->getAttackBoost (); - -// printf("#2 boost effect unitId = %d unitPtr = [%d - %s] source = %p attackBoost src [%p] dest [%p]\n", -// unitId,unitPtr->getId(),unitPtr->getType()->getName(false).c_str(), -// source,boost->unitParticleSystemTypeForSourceUnit,boost->unitParticleSystemTypeForAffectedUnit); - } - } - } - - if (boost != NULL) - { -// printf("unit [%d - %s] applyToOriginator: %d src [%p] dest [%p] Boost attackBoost->enabled = %d:\n%s\n", -// unit->getId(),unit->getType()->getName(false).c_str(),applyToOriginator,boost->unitParticleSystemTypeForSourceUnit,boost->unitParticleSystemTypeForAffectedUnit,boost->enabled,boost->getDesc(false).c_str()); - - if (applyToOriginator == true) - { - applyLoadedAttackBoostParticles - (boost->unitParticleSystemTypeForSourceUnit, - unitAttackBoostEffectNode, unit); - } - else - { - applyLoadedAttackBoostParticles - (boost->unitParticleSystemTypeForAffectedUnit, - unitAttackBoostEffectNode, unit); - } - } - else - { - printf - ("******!!!! unit [%d - %s] applyToOriginator: %d NO BOOST FOUND!!!\n", - unit->getId (), unit->getType ()->getName (false).c_str (), - applyToOriginator); - } - } - - void UnitAttackBoostEffect::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode *unitAttackBoostEffectNode = - rootNode->addChild ("UnitAttackBoostEffect"); - -// const AttackBoost *boost; - if (boost != NULL) - { - boost->saveGame (unitAttackBoostEffectNode); - } -// const Unit *source; - if (getSource () != NULL) - { - unitAttackBoostEffectNode->addAttribute ("source", - intToStr (getSource ()->getId - ()), - mapTagReplacements); - - unitAttackBoostEffectNode->addAttribute ("source-faction", - getSource ()-> - getFaction ()->getType ()-> - getName (false), - mapTagReplacements); - unitAttackBoostEffectNode->addAttribute ("source-unit-type", - getSource ()-> - getType ()->getName (false), - mapTagReplacements); - unitAttackBoostEffectNode->addAttribute ("source-skill-type", - getSource ()->getCurrSkill - ()->getName (), - mapTagReplacements); - unitAttackBoostEffectNode->addAttribute ("source-skill-class", - intToStr (getSource - ()->getCurrSkill - ()->getClass ()), - mapTagReplacements); - } -// UnitParticleSystem *ups; - if (ups != NULL - && Renderer::getInstance ().validateParticleSystemStillExists (ups, - rsGame) - == true) - { - ups->saveGame (unitAttackBoostEffectNode); - } - -// UnitParticleSystemType *upst; - if (upst != NULL) - { - upst->saveGame (unitAttackBoostEffectNode); - } - } - - UnitAttackBoostEffectOriginator::UnitAttackBoostEffectOriginator () - { - skillType = NULL; - currentAppliedEffect = NULL; - } - - UnitAttackBoostEffectOriginator::~UnitAttackBoostEffectOriginator () - { - delete currentAppliedEffect; - currentAppliedEffect = NULL; - } - - void UnitAttackBoostEffectOriginator::loadGame (const XmlNode * rootNode, - Unit * unit, - World * world) - { - const XmlNode *unitAttackBoostEffectOriginatorNode = - rootNode->getChild ("UnitAttackBoostEffectOriginator"); - - SkillClass skillClass = scStop; - string skillTypeName = - unitAttackBoostEffectOriginatorNode-> - getAttribute ("skillType")->getValue (); - if (unitAttackBoostEffectOriginatorNode->hasAttribute ("skillClass") == - false) - { - int skillCount = unit->getType ()->getSkillTypeCount (); - for (int index = 0; index < skillCount; ++index) - { - const SkillType *st = unit->getType ()->getSkillType (index); - if (st->getName () == skillTypeName) - { - skillClass = st->getClass (); - break; - } - } - } - else - { - skillClass = - static_cast < SkillClass > - (unitAttackBoostEffectOriginatorNode-> - getAttribute ("skillClass")->getIntValue ()); - } - - this->skillType = - unit->getType ()->getSkillType (skillTypeName, skillClass); - - if (unitAttackBoostEffectOriginatorNode->hasChild - ("currentAttackBoostUnits") == true) - { - vector < XmlNode * >currentAttackBoostUnitsNodeList = - unitAttackBoostEffectOriginatorNode->getChildList - ("currentAttackBoostUnits"); - for (unsigned int i = 0; i < currentAttackBoostUnitsNodeList.size (); - ++i) - { - XmlNode *node = currentAttackBoostUnitsNodeList[i]; - - int unitId = node->getAttribute ("value")->getIntValue (); - currentAttackBoostUnits.push_back (unitId); - } - } - - if (unitAttackBoostEffectOriginatorNode->hasChild - ("UnitAttackBoostEffect") == true) - { - currentAppliedEffect = new UnitAttackBoostEffect (); - currentAppliedEffect->loadGame (unitAttackBoostEffectOriginatorNode, - unit, world, true); - } - } - - void UnitAttackBoostEffectOriginator::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode *unitAttackBoostEffectOriginatorNode = - rootNode->addChild ("UnitAttackBoostEffectOriginator"); - -// const SkillType *skillType; - if (skillType != NULL) - { - unitAttackBoostEffectOriginatorNode->addAttribute ("skillType", - skillType->getName - (), - mapTagReplacements); - unitAttackBoostEffectOriginatorNode->addAttribute ("skillClass", - intToStr - (skillType->getClass - ()), - mapTagReplacements); - } -// std::vector currentAttackBoostUnits; - for (unsigned int i = 0; i < currentAttackBoostUnits.size (); ++i) - { - XmlNode *currentAttackBoostUnitsNode = - unitAttackBoostEffectOriginatorNode->addChild - ("currentAttackBoostUnits"); - currentAttackBoostUnitsNode->addAttribute ("value", - intToStr - (currentAttackBoostUnits - [i]), mapTagReplacements); - } -// UnitAttackBoostEffect *currentAppliedEffect; - if (currentAppliedEffect != NULL) - { - currentAppliedEffect->saveGame (unitAttackBoostEffectOriginatorNode); - } - } - -// ===================================================== -// class Unit -// ===================================================== - - const float Unit::ANIMATION_SPEED_MULTIPLIER = 100000.f; -//const float Unit::PROGRESS_SPEED_MULTIPLIER = 100000.f; - const int64 Unit::PROGRESS_SPEED_MULTIPLIER = 100000; - - const int Unit::speedDivider = 100; - const int Unit::maxDeadCount = 1000; //time in until the corpse disapears - should be about 40 seconds - const int Unit::invalidId = -1; - -//set Unit::livingUnits; -//set Unit::livingUnitsp; - -// ============================ Constructor & destructor ============================= - - Game *Unit::game = NULL; - - Unit::Unit (int id, UnitPathInterface * unitpath, const Vec2i & pos, - const UnitType * type, Faction * faction, Map * map, - CardinalDir placeFacing):BaseColorPickEntity (), id (id) - { -#ifdef LEAK_CHECK_UNITS - Unit::mapMemoryList[this] = true; -#endif - - mutexCommands = new Mutex (CODE_AT_LINE); - changedActiveCommand = false; - lastChangedActiveCommandFrame = 0; - changedActiveCommandFrame = 0; - - lastSynchDataString = ""; - modelFacing = CardinalDir (CardinalDir::NORTH); - lastStuckFrame = 0; - lastStuckPos = Vec2i (0, 0); - lastPathfindFailedFrame = 0; - lastPathfindFailedPos = Vec2i (0, 0); - usePathfinderExtendedMaxNodes = false; - this->currentAttackBoostOriginatorEffect.skillType = NULL; - lastAttackerUnitId = -1; - lastAttackedUnitId = -1; - causeOfDeath = ucodNone; - pathfindFailedConsecutiveFrameCount = 0; - - lastSynchDataString = ""; - lastFile = ""; - lastLine = 0; - lastSource = ""; - - targetRotationZ = .0f; - targetRotationX = .0f; - rotationZ = .0f; - rotationX = .0f; - - this->fire = NULL; - this->unitPath = unitpath; - this->unitPath->setMap (map); - - //RandomGen random; - random.init (id); - random.setDisableLastCallerTracking (isNetworkCRCEnabled () == false); - pathFindRefreshCellCount = - random.randRange (10, 20, intToStr (__LINE__)); - - if (map->isInside (pos) == false - || map->isInsideSurface (map->toSurfCoords (pos)) == false) - { - throw megaglest_runtime_error ("#2 Invalid path position = " + - pos.getString ()); - } - - this->pos = pos; - - this->faction = faction; - this->preMorph_type = NULL; - this->type = type; - setType (this->type); - - this->map = map; - this->targetRef = NULL; - this->targetField = fLand; - this->targetVec = Vec3f (0.0); - this->targetPos = Vec2i (0); - this->lastRenderFrame = 0; - this->visible = true; - this->retryCurrCommandCount = 0; - this->screenPos = Vec3f (0.0); - this->ignoreCheckCommand = false; - this->inBailOutAttempt = false; - this->lastHarvestResourceTarget.first = Vec2i (0); - this->morphFieldsBlocked = false; - //this->lastBadHarvestListPurge = 0; - this->oldTotalSight = 0; - - level = NULL; - loadType = NULL; - - setModelFacing (placeFacing); - - Config & config = Config::getInstance (); - showUnitParticles = config.getBool ("UnitParticles", "true"); - maxQueuedCommandDisplayCount = - config.getInt ("MaxQueuedCommandDisplayCount", "15"); - - if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == true) - { - showUnitParticles = false; - } - - lastPos = pos; - progress = 0; - this->lastAnimProgress = 0; - this->animProgress = 0; - progress2 = 0; - kills = 0; - enemyKills = 0; - loadCount = 0; - ep = 0; - deadCount = 0; - hp = type->getMaxHp () / 20; - toBeUndertaken = false; - - highlight = 0.f; - meetingPos = pos; - setAlive (true); - - if (type->hasSkillClass (scBeBuilt) == false) - { - float rot = 0.f; - random.init (id); - rot += random.randRange (-5, 5, intToStr (__LINE__)); - rotation = rot; - lastRotation = rot; - targetRotation = rot; - } - // else it was set appropriately in setModelFacing() - - if (getType ()->getField (fAir)) - { - currField = fAir; - } - if (getType ()->getField (fLand)) - { - currField = fLand; - } - - computeTotalUpgrade (); - - //starting skill - this->lastModelIndexForCurrSkillType = -1; - this->animationRandomCycleCount = 0; - this->currSkill = getType ()->getFirstStOfClass (scStop); - this->setCurrSkill (this->currSkill); - this->currentAttackBoostOriginatorEffect.skillType = this->currSkill; - - this->faction->addLivingUnits (id); - this->faction->addLivingUnitsp (this); - - addItemToVault (&this->hp, this->hp); - addItemToVault (&this->ep, this->ep); - - calculateFogOfWarRadius (); - -// if(isUnitDeleted(this) == true) { -// MutexSafeWrapper safeMutex(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__)); -// deletedUnits.erase(this); -// } - - logSynchData (extractFileFromDirectoryPath (__FILE__).c_str (), - __LINE__); - } - - Unit::~Unit () - { - badHarvestPosList.clear (); - - this->faction->deleteLivingUnits (id); - this->faction->deleteLivingUnitsp (this); - - //remove commands - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - - changedActiveCommand = false; - while (commands.empty () == false) - { - delete commands.back (); - commands.pop_back (); - } - safeMutex.ReleaseLock (); - - cleanupAllParticlesystems (); - - while (currentAttackBoostEffects.empty () == false) - { - //UnitAttackBoostEffect &effect = currentAttackBoostEffects.back(); - UnitAttackBoostEffect *ab = currentAttackBoostEffects.back (); - delete ab; - currentAttackBoostEffects.pop_back (); - } - - delete currentAttackBoostOriginatorEffect.currentAppliedEffect; - currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL; - - //Renderer::getInstance().cleanupParticleSystems(attackParticleSystems,rsGame); - Renderer::getInstance ().removeParticleSystemsForParticleOwner (this, - rsGame); - - -#ifdef LEAK_CHECK_UNITS - Unit::mapMemoryList2[this->unitPath] = this->getId (); -#endif - - delete this->unitPath; - this->unitPath = NULL; - - Renderer & renderer = Renderer::getInstance (); - renderer.removeUnitFromQuadCache (this); - if (game != NULL) - { - game->removeUnitFromSelection (this); - } - - //MutexSafeWrapper safeMutex1(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__)); - //deletedUnits[this]=true; - - delete mutexCommands; - mutexCommands = NULL; - -#ifdef LEAK_CHECK_UNITS - Unit::mapMemoryList.erase (this); -#endif - } - - void Unit::cleanupAllParticlesystems () - { - - Renderer:: - getInstance ().cleanupUnitParticleSystems (unitParticleSystems, - rsGame); - - Renderer::getInstance ().cleanupParticleSystems (fireParticleSystems, - rsGame); - // Must set this to null of it will be used below in stopDamageParticles() - - if (Renderer:: - getInstance ().validateParticleSystemStillExists (this->fire, - rsGame) == false) - { - this->fire = NULL; - } - - // fade(and by this remove) all unit particle systems - queuedUnitParticleSystemTypes.clear (); - while (unitParticleSystems.empty () == false) - { - if (Renderer:: - getInstance ().validateParticleSystemStillExists - (unitParticleSystems.back (), rsGame) == true) - { - unitParticleSystems.back ()->fade (); - } - unitParticleSystems.pop_back (); - } - stopDamageParticles (true); - - } - - ParticleSystem *Unit::getFire () const - { - if (this->fire != NULL && - Renderer::getInstance (). - validateParticleSystemStillExists (this->fire, rsGame) == false) - { - return NULL; - } - return this->fire; - } - - void Unit::setType (const UnitType * newType) - { - this->faction->notifyUnitTypeChange (this, newType); - this->type = newType; - } - - void Unit::setAlive (bool value) - { - this->alive = value; - this->faction->notifyUnitAliveStatusChange (this); - } - -#ifdef LEAK_CHECK_UNITS - void Unit::dumpMemoryList () - { - printf ("===== START report of Unfreed Unit pointers =====\n"); - for (std::map < Unit *, bool >::iterator iterMap = - Unit::mapMemoryList.begin (); - iterMap != Unit::mapMemoryList.end (); ++iterMap) - { - printf ("************** ==> Unfreed Unit pointer [%p]\n", - iterMap->first); - } - } -#endif - - bool Unit::isNetworkCRCEnabled () - { - bool isNetworkCRCEnabled = false; - - if (game != NULL) - { - if (game->isFlagType1BitEnabled (ft1_network_synch_checks_verbose) == - true) - { - isNetworkCRCEnabled = true; - } - else if (game->isFlagType1BitEnabled (ft1_network_synch_checks) == - true) - { - isNetworkCRCEnabled = true; - } - } - return isNetworkCRCEnabled; - } - - void Unit::clearNetworkCRCDecHpList () - { - if (networkCRCDecHpList.empty () == false) - { - networkCRCDecHpList.clear (); - } - } - void Unit::clearParticleInfo () - { - if (networkCRCParticleInfoList.empty () == false) - { - networkCRCParticleInfoList.clear (); - } - } - - void Unit::addNetworkCRCDecHp (string info) - { - if (isNetworkCRCEnabled () == true) - { - networkCRCDecHpList.push_back (info); - } - } - - void Unit::logParticleInfo (string info) - { - if (isNetworkCRCEnabled () == true) - { - networkCRCParticleInfoList.push_back (info); - } - } - string Unit::getParticleInfo () const - { - string result = ""; - if (networkCRCParticleInfoList.empty () == false) - { - for (unsigned int index = 0; - index < networkCRCParticleInfoList.size (); ++index) - { - result += networkCRCParticleInfoList[index] + "|"; - } - } - return result; - } - - void Unit::end (ParticleSystem * particleSystem) - { - if (particleSystem == fire) - { - fire = NULL; - } - - vector < ParticleSystem * >::iterator iterFind = - find (attackParticleSystems.begin (), attackParticleSystems.end (), - particleSystem); - if (iterFind != attackParticleSystems.end ()) - { - attackParticleSystems.erase (iterFind); - return; - } - vector < UnitParticleSystem * >::iterator iterFind1 = - find (smokeParticleSystems.begin (), smokeParticleSystems.end (), - particleSystem); - if (iterFind1 != smokeParticleSystems.end ()) - { - smokeParticleSystems.erase (iterFind1); - return; - } - iterFind = - find (fireParticleSystems.begin (), fireParticleSystems.end (), - particleSystem); - if (iterFind != fireParticleSystems.end ()) - { - fireParticleSystems.erase (iterFind); - return; - } - iterFind1 = - find (damageParticleSystems.begin (), damageParticleSystems.end (), - particleSystem); - if (iterFind1 != damageParticleSystems.end ()) - { - damageParticleSystems.erase (iterFind1); - return; - } - - iterFind1 = - find (unitParticleSystems.begin (), unitParticleSystems.end (), - particleSystem); - if (iterFind1 != unitParticleSystems.end ()) - { - unitParticleSystems.erase (iterFind1); - return; - } - } - -//bool Unit::isUnitDeleted(void *unit) { -// bool result = false; -// MutexSafeWrapper safeMutex(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__)); -// if(deletedUnits.find(unit) != deletedUnits.end()) { -// result = true; -// } -// return result; -//} - - void Unit::setModelFacing (CardinalDir value) - { - modelFacing = value; - lastRotation = targetRotation = rotation = value * 90.f; - } - -//void Unit::setCurrField(Field currField) { -// Field original_field = this->currField; -// -// this->currField = currField; -// -// if(original_field != this->currField) { -// //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); -// game->getScriptManager()->onUnitTriggerEvent(this,utet_FieldChanged); -// //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); -// } -//} -// ====================================== get ====================================== - - Vec2i Unit::getCenteredPos () const - { - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - return pos + Vec2i (type->getSize () / 2, type->getSize () / 2); - } - - Vec2f Unit::getFloatCenteredPos () const - { - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - return Vec2f (truncateDecimal < - float >(pos.x - 0.5f + type->getSize () / 2.f, 6), - truncateDecimal < - float >(pos.y - 0.5f + type->getSize () / 2.f, 6)); - } - - Vec2i Unit::getCellPos () const - { - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - if (type->hasCellMap ()) - { - if (type->hasEmptyCellMap () == false || - type->getAllowEmptyCellMap () == true) - { - - //find nearest pos to center that is free - Vec2i centeredPos = getCenteredPos (); - float nearestDist = -1.f; - Vec2i nearestPos = pos; - - for (int i = 0; i < type->getSize (); ++i) - { - for (int j = 0; j < type->getSize (); ++j) - { - if (type->getCellMapCell (i, j, modelFacing)) - { - Vec2i currPos = pos + Vec2i (i, j); - float dist = currPos.dist (centeredPos); - if (nearestDist == -1.f || dist < nearestDist) - { - nearestDist = dist; - nearestPos = currPos; - } - } - } - } - return nearestPos; - } - } - return pos; - } - - - - void Unit::calculateXZRotation () - { - //if(type->getProperty(UnitType::pRotatedClimb) && currSkill->getClass()==scMove){ - //if(currSkill->getClass()==scMove) - if (lastPos != pos) - { // targetPosCalc ( maybe also sometimes needed if no move ? terrain flatting... ) - SurfaceCell *sc = map->getSurfaceCell (Map::toSurfCoords (pos)); - const Vec3f normal = sc->getNormal (); - -#ifdef USE_STREFLOP - targetRotationZ = - radToDeg (streflop::atan2 - (static_cast < streflop::Simple > (abs (normal.x)), - static_cast < streflop::Simple > (abs (normal.y)))); -#else - targetRotationZ = radToDeg (atan2 (abs (normal.x), abs (normal.y))); -#endif - - if ((normal.y < 0 || normal.x < 0) && !(normal.y < 0 && normal.x < 0)) - { - targetRotationZ = targetRotationZ * -1; - } - targetRotationZ = targetRotationZ * -1; - -#ifdef USE_STREFLOP - targetRotationX = - radToDeg (streflop::atan2 - (static_cast < streflop::Simple > (abs (normal.z)), - static_cast < streflop::Simple > (abs (normal.y)))); -#else - targetRotationX = radToDeg (atan2 (abs (normal.z), abs (normal.y))); -#endif - - if ((normal.y < 0 || normal.z < 0) && !(normal.y < 0 && normal.z < 0)) - { - targetRotationX = targetRotationX * -1; - } - } - - //For smooth rotation we now softly adjust the angle - int adjustStep = 1; - if (rotationZ < targetRotationZ) - { - if (rotationZ + adjustStep > targetRotationZ) - { - rotationZ = targetRotationZ; - } - else - { - rotationZ = rotationZ + adjustStep; - } - } - else if (rotationZ > targetRotationZ) - { - if (rotationZ - adjustStep < targetRotationZ) - { - rotationZ = targetRotationZ; - } - else - { - rotationZ = rotationZ - adjustStep; - } - } - - if (rotationX < targetRotationX) - { - if (rotationX + adjustStep > targetRotationX) - { - rotationX = targetRotationX; - } - else - { - rotationX = rotationX + adjustStep; - } - } - else if (rotationX > targetRotationX) - { - if (rotationX - adjustStep < targetRotationX) - { - rotationX = targetRotationX; - } - else - { - rotationX = rotationX - adjustStep; - } - } - } - - float Unit::getRotationZ () const - { - return rotationZ; - } - - float Unit::getRotationX () const - { - return rotationX; - } - - int Unit::getProductionPercent () const - { - if (anyCommand ()) - { - const ProducibleType *produced = - commands.front ()->getCommandType ()->getProduced (); - if (produced != NULL) - { - if (produced->getProductionTime () == 0) - { - return 0; - } - return clamp (progress2 * 100 / produced->getProductionTime (), 0, - 100); - } - } - return -1; - } - - float Unit::getProgressRatio () const - { - if (anyCommand ()) - { - const ProducibleType *produced = - commands.front ()->getCommandType ()->getProduced (); - if (produced != NULL) - { - if (produced->getProductionTime () == 0) - { - return 0.f; - } - - float help = progress2; - return clamp (help / produced->getProductionTime (), 0.f, 1.f); - } - } - return -1; - } - - float Unit::getHpRatio () const - { - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - float maxHpAllowed = type->getTotalMaxHp (&totalUpgrade); - if (maxHpAllowed == 0.f) - { - return 0.f; - } - return clamp (static_cast < float >(hp) / maxHpAllowed, 0.f, 1.f); - } - - float Unit::getEpRatio () const - { - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - if (type->getTotalMaxHp (&totalUpgrade) == 0) - { - return 0.f; - } - else - { - float maxEpAllowed = type->getTotalMaxEp (&totalUpgrade); - if (maxEpAllowed == 0.f) - { - return 0.f; - } - return clamp (static_cast < float >(ep) / maxEpAllowed, 0.f, 1.f); - } - } - - const Level *Unit::getNextLevel () const - { - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - if (level == NULL && type->getLevelCount () > 0) - { - return type->getLevel (0); - } - else - { - for (int i = 1; i < type->getLevelCount (); ++i) - { - if (type->getLevel (i - 1) == level) - { - return type->getLevel (i); - } - } - } - return NULL; - } - - string Unit::getFullName (bool translatedValue) const - { - string str = ""; - if (level != NULL) - { - str += (level->getName (translatedValue) + " "); - } - if (type == NULL) - { - throw - megaglest_runtime_error ("type == NULL in Unit::getFullName()!"); - } - str += type->getName (translatedValue); - return str; - } - -// ====================================== is ====================================== - - bool Unit::isOperative () const - { - return isAlive () && isBuilt (); - } - - bool Unit::isAnimProgressBound () const - { - if (currSkill == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - bool result = false; - if (currSkill->getClass () == scBeBuilt) - { - const BeBuiltSkillType *skill = - dynamic_cast < const BeBuiltSkillType * >(currSkill); - if (skill != NULL) - { - result = skill->getAnimProgressBound (); - } - } - else if (currSkill->getClass () == scProduce) - { - const ProduceSkillType *skill = - dynamic_cast < const ProduceSkillType * >(currSkill); - if (skill != NULL) - { - result = skill->getAnimProgressBound (); - } - } - else if (currSkill->getClass () == scUpgrade) - { - const UpgradeSkillType *skill = - dynamic_cast < const UpgradeSkillType * >(currSkill); - if (skill != NULL) - { - result = skill->getAnimProgressBound (); - } - } - else if (currSkill->getClass () == scMorph) - { - const MorphSkillType *skill = - dynamic_cast < const MorphSkillType * >(currSkill); - if (skill != NULL) - { - result = skill->getAnimProgressBound (); - } - } - return result; - } - - bool Unit::isBeingBuilt () const - { - if (currSkill == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - return (currSkill->getClass () == scBeBuilt); - } - - bool Unit::isBuilt () const - { - return (isBeingBuilt () == false); - } - - bool Unit::isBuildCommandPending () const - { - bool result = false; - - Command *command = this->getCurrCommand (); - if (command != NULL) - { - const BuildCommandType *bct = - dynamic_cast < - const BuildCommandType * >(command->getCommandType ()); - if (bct != NULL) - { - if (this->getCurrSkill ()->getClass () != scBuild) - { - result = true; - } - } - } - - return result; - } - - UnitBuildInfo Unit::getBuildCommandPendingInfo () const - { - UnitBuildInfo result; - - Command *command = this->getCurrCommand (); - if (command != NULL) - { - const BuildCommandType *bct = - dynamic_cast < - const BuildCommandType * >(command->getCommandType ()); - if (bct != NULL) - { - result.pos = command->getOriginalPos (); - result.facing = command->getFacing (); - result.buildUnit = command->getUnitType (); - result.unit = this; - } - } - - return result; - } - - bool Unit::isAlly (const Unit * unit) const - { - if (unit == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: unit == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - return faction->isAlly (unit->getFaction ()); - } - - bool Unit::isDamaged () const - { - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - return hp < type->getTotalMaxHp (&totalUpgrade); - } - - bool Unit::isInteresting (InterestingUnitType iut) const - { - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - switch (iut) - { - case iutIdleHarvester: - if (type->hasCommandClass (ccHarvest)) - { - if (commands.empty () == false) - { - const CommandType *ct = commands.front ()->getCommandType (); - if (ct != NULL) - { - return ct->getClass () == ccStop; - } - } - } - return false; - - case iutBuiltBuilding: - return type->hasSkillClass (scBeBuilt) && isBuilt (); - case iutProducer: - return type->hasSkillClass (scProduce); - case iutDamaged: - return isDamaged (); - case iutStore: - return type->getStoredResourceCount () > 0; - default: - return false; - } - } - -// ====================================== set ====================================== - - void Unit::setCurrSkill (const SkillType * currSkill) - { - if (currSkill == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - if (this->currSkill == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: this->currSkill == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - if (this->currSkill->getClass () == scMove && - currSkill->getClass () != scMove) - { - faction->removeUnitFromMovingList (this->getId ()); - } - else if (this->currSkill->getClass () != scMove && - currSkill->getClass () == scMove) - { - faction->addUnitToMovingList (this->getId ()); - } - - changedActiveCommand = false; - if (currSkill->getClass () != this->currSkill->getClass () || - currSkill->getName () != this->currSkill->getName ()) - { - this->animProgress = 0; - this->lastAnimProgress = 0; - - queuedUnitParticleSystemTypes.clear (); - while (unitParticleSystems.empty () == false) - { - if (Renderer:: - getInstance ().validateParticleSystemStillExists - (unitParticleSystems.back (), rsGame) == true) - { - unitParticleSystems.back ()->fade (); - } - unitParticleSystems.pop_back (); - } - - Command *cmd = getCurrrentCommandThreadSafe (); - - // Set mew fog of war skill type if need be - if (cmd != NULL && cmd->getCommandType () != NULL && - cmd->getCommandType ()-> - hasFogOfWarSkillType (currSkill->getName ())) - { - const FogOfWarSkillType *fowst = - cmd->getCommandType ()->getFogOfWarSkillType (); - - // Remove old fog of war skill type if need be - game->getWorld ()->removeFogOfWarSkillTypeFromList (this); - - game->getWorld ()->addFogOfWarSkillType (this, fowst); - } - else - { - // Remove old fog of war skill type if need be - game->getWorld ()->removeFogOfWarSkillType (this); - } - } - if (showUnitParticles == true && - currSkill->unitParticleSystemTypes.empty () == false && - unitParticleSystems.empty () == true) - { - //printf("START - particle system type\n"); - - /* - for(UnitParticleSystemTypes::const_iterator it= currSkill->unitParticleSystemTypes.begin(); - it != currSkill->unitParticleSystemTypes.end(); ++it) { - if((*it)->getStartTime() == 0.0) { - //printf("Adding NON-queued particle system type [%s] [%f] [%f]\n",(*it)->getType().c_str(),(*it)->getStartTime(),(*it)->getEndTime()); - - UnitParticleSystem *ups = new UnitParticleSystem(200); - ups->setParticleOwner(this); - ups->setParticleType((*it)); - - (*it)->setValues(ups); - ups->setPos(getCurrVector()); - ups->setRotation(getRotation()); - ups->setUnitModel(getCurrentModelPtr()); - if(getFaction()->getTexture()) { - ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); - } - unitParticleSystems.push_back(ups); - Renderer::getInstance().manageParticleSystem(ups, rsGame); - } - else { - //printf("Adding queued particle system type [%s] [%f] [%f]\n",(*it)->getType().c_str(),(*it)->getStartTime(),(*it)->getEndTime()); - - queuedUnitParticleSystemTypes.push_back(*it); - } - } - */ - checkCustomizedUnitParticleListTriggers - (currSkill->unitParticleSystemTypes, true); - } - - if (this->currSkill != currSkill) - { - this->lastModelIndexForCurrSkillType = -1; - this->animationRandomCycleCount = 0; - } - - if (faction != NULL) - faction->notifyUnitSkillTypeChange (this, currSkill); - const SkillType *original_skill = this->currSkill; - this->currSkill = currSkill; - - if (original_skill != this->currSkill) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_SkillChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - } - - void Unit::setCurrSkill (SkillClass sc) - { - if (getType () == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: getType() == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - setCurrSkill (getType ()->getFirstStOfClass (sc)); - } - - void Unit::setTarget (const Unit * unit) - { - - if (unit == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: unit == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - //find a free pos in cellmap - setTargetPos (unit->getCellPos ()); - - //ser field and vector - targetField = unit->getCurrField (); - targetVec = unit->getCurrVectorAsTarget (); - targetRef = unit; - } - - RandomGen *Unit::getRandom (bool threadAccessAllowed) - { - if (threadAccessAllowed == false - && Thread::isCurrentThreadMainThread () == false) - { - throw - megaglest_runtime_error - ("Invalid access to unit random from outside main thread current id = " - + intToStr (Thread::getCurrentThreadId ()) + " main = " + - intToStr (Thread::getMainThreadId ())); - } - return &random; - } - - void Unit::setPos (const Vec2i & pos, bool clearPathFinder, bool threaded) - { - if (map->isInside (pos) == false - || map->isInsideSurface (map->toSurfCoords (pos)) == false) - { - throw megaglest_runtime_error ("#3 Invalid path position = " + - pos.getString ()); - } - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - - if (threaded) - { - logSynchDataThreaded (extractFileFromDirectoryPath (__FILE__).c_str - (), __LINE__); - } - else - { - logSynchData (extractFileFromDirectoryPath (__FILE__).c_str (), - __LINE__); - } - - if (clearPathFinder == true && this->unitPath != NULL) - { - this->unitPath->clear (); - } - //Vec2i oldLastPos = this->lastPos; - this->lastPos = this->pos; - this->pos = pos; - - map->clampPos (this->pos); - this->meetingPos = pos - Vec2i (1); - map->clampPos (this->meetingPos); - - safeMutex.ReleaseLock (); - - refreshPos (); - - if (threaded) - { - logSynchDataThreaded (extractFileFromDirectoryPath (__FILE__).c_str - (), __LINE__); - } - else - { - logSynchData (extractFileFromDirectoryPath (__FILE__).c_str (), - __LINE__); - } - } - - void Unit::refreshPos (bool forceRefresh) - { - // Attempt to improve performance - this->exploreCells (forceRefresh); - calculateFogOfWarRadius (forceRefresh); - } - - FowAlphaCellsLookupItem Unit::getFogOfWarRadius (bool useCache) const - { - if (useCache == true) - { - return cachedFow; - } - - //iterate through all cells - int sightRange = - this->getType ()->getTotalSight (this->getTotalUpgrade ()); - int radius = sightRange + World::indirectSightRange; - PosCircularIterator pci (map, this->getPosNotThreadSafe (), radius); - FowAlphaCellsLookupItem result; - while (pci.next ()) - { - const Vec2i sightpos = pci.getPos (); - Vec2i surfPos = Map::toSurfCoords (sightpos); - - //compute max alpha - float maxAlpha = 0.0f; - if (surfPos.x > 1 && surfPos.y > 1 && - surfPos.x < map->getSurfaceW () - 2 && - surfPos.y < map->getSurfaceH () - 2) - { - maxAlpha = 1.f; - } - else if (surfPos.x > 0 && surfPos.y > 0 && - surfPos.x < map->getSurfaceW () - 1 && - surfPos.y < map->getSurfaceH () - 1) - { - maxAlpha = 0.3f; - } - - //compute alpha - float alpha = maxAlpha; - float dist = this->getPosNotThreadSafe ().dist (sightpos); - if (dist > sightRange) - { - alpha = - clamp (1.f - (dist - sightRange) / (World::indirectSightRange), - 0.f, maxAlpha); - } - result.surfPosAlphaList[surfPos] = alpha; - } - return result; - } - - void Unit::calculateFogOfWarRadius (bool forceRefresh) - { - if (game->getWorld ()->getFogOfWar () == true) - { - if (forceRefresh || this->pos != this->cachedFowPos) - { - cachedFow = getFogOfWarRadius (false); - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - this->cachedFowPos = this->pos; - } - } - } - - void Unit::setTargetPos (const Vec2i & targetPos, bool threaded) - { - - if (map->isInside (targetPos) == false - || map->isInsideSurface (map->toSurfCoords (targetPos)) == false) - { - throw megaglest_runtime_error ("#4 Invalid path position = " + - targetPos.getString ()); - } - - Vec2i relPos = targetPos - pos; - //map->clampPos(relPos); - - Vec2f relPosf = Vec2f ((float) relPos.x, (float) relPos.y); -#ifdef USE_STREFLOP - targetRotation = - radToDeg (streflop::atan2 - (static_cast < streflop::Simple > (relPosf.x), - static_cast < streflop::Simple > (relPosf.y))); -#else - targetRotation = radToDeg (atan2 (relPosf.x, relPosf.y)); -#endif - targetRotation = truncateDecimal < float >(targetRotation, 6); - - targetRef = NULL; - - this->targetPos = targetPos; - map->clampPos (this->targetPos); - - if (threaded) - { - logSynchDataThreaded (extractFileFromDirectoryPath (__FILE__).c_str - (), __LINE__); - } - else - { - logSynchData (extractFileFromDirectoryPath (__FILE__).c_str (), - __LINE__); - } - } - - void Unit::addAttackParticleSystem (ParticleSystem * ps) - { - attackParticleSystems.push_back (ps); - } - - void Unit::setVisible (const bool visible) - { - this->visible = visible; - - if (unitParticleSystems.empty () == false) - { - for (UnitParticleSystems::iterator it = unitParticleSystems.begin (); - it != unitParticleSystems.end (); ++it) - { - if (Renderer:: - getInstance ().validateParticleSystemStillExists ((*it), - rsGame) == - true) - { - (*it)->setVisible (visible); - } - } - } - if (damageParticleSystems.empty () == false) - { - for (UnitParticleSystems::iterator it = - damageParticleSystems.begin (); - it != damageParticleSystems.end (); ++it) - { - if (Renderer:: - getInstance ().validateParticleSystemStillExists ((*it), - rsGame) == - true) - { - (*it)->setVisible (visible); - } - } - } - if (smokeParticleSystems.empty () == false) - { - for (UnitParticleSystems::iterator it = smokeParticleSystems.begin (); - it != smokeParticleSystems.end (); ++it) - { - if (Renderer:: - getInstance ().validateParticleSystemStillExists ((*it), - rsGame) == - true) - { - if ((*it)->getVisible () != visible) - { - //printf("Changing visibility for smoke particle system to: %d\n",visible); - (*it)->setVisible (visible); - } - } - } - } - - //if(attackParticleSystems.empty() == false) { - // for(vector::iterator it= attackParticleSystems.begin(); it != attackParticleSystems.end(); ++it) { - // if(Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame) == true) { - // Not sure this is a good idea since the unit be not be visible but the attack particle might be. - // This means you won't see the attacking projectile until the unit moves into view. - //(*it)->setVisible(visible); - // } - // } - //} - - if (currentAttackBoostEffects.empty () == false) - { - for (unsigned int i = 0; i < currentAttackBoostEffects.size (); ++i) - { - UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; - if (effect != NULL && effect->ups != NULL) - { - bool particleValid = - Renderer:: - getInstance ().validateParticleSystemStillExists (effect->ups, - rsGame); - if (particleValid == true) - { - effect->ups->setVisible (visible); - } - } - } - } - if (currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) - { - if (currentAttackBoostOriginatorEffect.currentAppliedEffect->ups != - NULL) - { - bool particleValid = - Renderer::getInstance ().validateParticleSystemStillExists - (currentAttackBoostOriginatorEffect.currentAppliedEffect->ups, - rsGame); - if (particleValid == true) - { - currentAttackBoostOriginatorEffect.currentAppliedEffect-> - ups->setVisible (visible); - } - } - } - } - -// =============================== Render related ================================== - - Model *Unit::getCurrentModelPtr () - { - if (currSkill == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - int currentModelIndexForCurrSkillType = lastModelIndexForCurrSkillType; - Model *result = - currSkill->getAnimation (getAnimProgressAsFloat (), this, - &lastModelIndexForCurrSkillType, - &animationRandomCycleCount); - if (currentModelIndexForCurrSkillType != lastModelIndexForCurrSkillType) - { - animationRandomCycleCount++; - if (currSkill != NULL - && animationRandomCycleCount >= currSkill->getAnimationCount ()) - { - animationRandomCycleCount = 0; - } - } - return result; - } - -//const Model *Unit::getCurrentModel() { -// if(currSkill == NULL) { -// char szBuf[8096]=""; -// snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); -// throw megaglest_runtime_error(szBuf); -// } -// -// int currentModelIndexForCurrSkillType = lastModelIndexForCurrSkillType; -// const Model *result = currSkill->getAnimation(getAnimProgressAsFloat(),this,&lastModelIndexForCurrSkillType, &animationRandomCycleCount); -// if(currentModelIndexForCurrSkillType != lastModelIndexForCurrSkillType) { -// animationRandomCycleCount++; -// if(currSkill != NULL && animationRandomCycleCount >= currSkill->getAnimationCount()) { -// animationRandomCycleCount = 0; -// } -// } -// return result; -//} - - bool Unit::checkModelStateInfoForNewHpValue () - { - bool result = false; - if (currSkill != NULL && currSkill->getAnimationCount () > 1) - { - if (lastModelIndexForCurrSkillType >= 0) - { - const AnimationAttributes attributes = - currSkill->getAnimationAttribute (lastModelIndexForCurrSkillType); - if (attributes.fromHp != 0 || attributes.toHp != 0) - { - //printf("Check for RESET model state for [%d - %s] HP = %d [%d to %d]\n",this->id,this->getType()->getName().c_str(),this->getHp(),attributes.fromHp,attributes.toHp); - //if(this->getHp() >= attributes.fromHp && this->getHp() <= attributes.toHp) { - if (this->getHp () < attributes.fromHp - || this->getHp () > attributes.toHp) - { - //printf("RESET model state for [%d - %s] HP = %d [%d to %d]\n",this->id,this->getType()->getName().c_str(),this->getHp(),attributes.fromHp,attributes.toHp); - - lastModelIndexForCurrSkillType = -1; - animationRandomCycleCount = 0; - result = true; - } - } - else - { - //printf("Check for RESET #2 model state for [%d - %s] HP = %d [%d to %d] for skill [%s]\n",this->id,this->getType()->getName().c_str(),this->getHp(),attributes.fromHp,attributes.toHp,currSkill->getName().c_str()); - } - } - } - - return result; - } - - Vec3f Unit::getCurrVectorForParticlesystems () const - { - if (getFaction ()->getType ()->isFlatParticlePositions ()) - { - return getCurrVectorFlat (); - } - else - { - return getCurrMidHeightVector (); - } - } - - Vec3f Unit::getCurrMidHeightVector () const - { - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - Vec3f result = - getCurrVectorFlat () + Vec3f (0.f, type->getHeight () / 2.f, 0.f); - result.x = truncateDecimal < float >(result.x, 6); - result.y = truncateDecimal < float >(result.y, 6); - result.z = truncateDecimal < float >(result.z, 6); - - return result; - } - - Vec3f Unit::getCurrVectorAsTarget () const - { - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - Vec3f result = - getCurrVectorFlat () + Vec3f (0.f, type->getTargetHeight () / 2.f, - 0.f); - result.x = truncateDecimal < float >(result.x, 6); - result.y = truncateDecimal < float >(result.y, 6); - result.z = truncateDecimal < float >(result.z, 6); - - return result; - } - - Vec3f Unit::getCurrBurnVector () const - { - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - Vec3f result = - getCurrVectorFlat () + Vec3f (0.f, type->getBurnHeight () / 2.f, 0.f); - result.x = truncateDecimal < float >(result.x, 6); - result.y = truncateDecimal < float >(result.y, 6); - result.z = truncateDecimal < float >(result.z, 6); - - return result; - } - - Vec3f Unit::getCurrVectorFlat () const - { - return getVectorFlat (lastPos, pos); - } - - float Unit::getProgressAsFloat () const - { - float result = - (static_cast < float >(progress) / static_cast < - float >(PROGRESS_SPEED_MULTIPLIER)); - result = truncateDecimal < float >(result, 6); - return result; - } - - Vec3f Unit::getVectorFlat (const Vec2i & lastPosValue, - const Vec2i & curPosValue) const - { - Vec3f v; - - float y1 = computeHeight (lastPosValue); - float y2 = computeHeight (curPosValue); - - if (currSkill->getClass () == scMove) - { - float progressAsFloat = getProgressAsFloat (); - - v.x = - lastPosValue.x + progressAsFloat * (curPosValue.x - lastPosValue.x); - v.z = - lastPosValue.y + progressAsFloat * (curPosValue.y - lastPosValue.y); - v.y = y1 + progressAsFloat * (y2 - y1); - - v.x = truncateDecimal < float >(v.x, 6); - v.y = truncateDecimal < float >(v.y, 6); - v.z = truncateDecimal < float >(v.z, 6); - } - else - { - v.x = static_cast < float >(curPosValue.x); - v.z = static_cast < float >(curPosValue.y); - v.y = y2; - - v.x = truncateDecimal < float >(v.x, 6); - v.y = truncateDecimal < float >(v.y, 6); - v.z = truncateDecimal < float >(v.z, 6); - } - v.x += type->getSize () / 2.f - 0.5f; - v.z += type->getSize () / 2.f - 0.5f; - - v.x = truncateDecimal < float >(v.x, 6); - v.z = truncateDecimal < float >(v.z, 6); - - return v; - } - -// =================== Command list related =================== - -//any command - bool Unit::anyCommand (bool validateCommandtype) const - { - bool result = false; - if (validateCommandtype == false) - { - result = (commands.empty () == false); - } - else - { - for (Commands::const_iterator it = commands.begin (); - it != commands.end (); ++it) - { - const CommandType *ct = (*it)->getCommandType (); - if (ct != NULL && ct->getClass () != ccStop) - { - result = true; - break; - } - } - } - - return result; - } - -//return current command, assert that there is always one command - Command *Unit::getCurrrentCommandThreadSafe () - { - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - - if (commands.empty () == false) - { - return commands.front (); - } - - return NULL; - } - - void Unit::replaceCurrCommand (Command * cmd) - { - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - - assert (commands.empty () == false); - commands.front () = cmd; - this->setCurrentUnitTitle (""); - } - -//returns the size of the commands - unsigned int Unit::getCommandSize () const - { - return (unsigned int) commands.size (); - } - -//return current command, assert that there is always one command - int Unit::getCountOfProducedUnits (const UnitType * ut) const - { - int count = 0; - for (Commands::const_iterator it = commands.begin (); - it != commands.end (); ++it) - { - const CommandType *ct = (*it)->getCommandType (); - if (ct->getClass () == ccProduce || ct->getClass () == ccMorph) - { - const UnitType *producedUnitType = - static_cast < const UnitType * >(ct->getProduced ()); - if (producedUnitType == ut) - { - count++; - } - } - if (ct->getClass () == ccBuild) - { - const UnitType *builtUnitType = (*it)->getUnitType (); - if (builtUnitType == ut) - { - count++; - } - } - } - return count; - } - -//give one command (clear, and push back) - std::pair < CommandResult, string > Unit::giveCommand (Command * command, - bool tryQueue) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugUnitCommands).enabled) - SystemFlags::OutputDebug (SystemFlags::debugUnitCommands, - "\n======================\nUnit Command tryQueue = %d\nUnit Info:\n%s\nCommand Info:\n%s\n", - tryQueue, this->toString ().c_str (), - command->toString (false).c_str ()); - - std::pair < CommandResult, string > result (crFailUndefined, ""); - changedActiveCommand = false; - - Chrono chrono; - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled) - chrono.start (); - - if (command == NULL) - { - throw megaglest_runtime_error ("command == NULL"); - } - if (command->getCommandType () == NULL) - { - throw megaglest_runtime_error ("command->getCommandType() == NULL"); - } - - const int command_priority = command->getPriority (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - - //printf("In [%s::%s] Line: %d unit [%d - %s] command [%s] tryQueue = %d command->getCommandType()->isQueuable(tryQueue) = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->getId(),this->getType()->getName().c_str(), command->getCommandType()->getName().c_str(), tryQueue,command->getCommandType()->isQueuable(tryQueue)); - - - if (command->getCommandType ()->isQueuable (tryQueue)) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - if (SystemFlags::getSystemSettingType - (SystemFlags::debugUnitCommands).enabled) - SystemFlags::OutputDebug (SystemFlags::debugUnitCommands, - "In [%s::%s Line: %d] Command is Queable\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - if (command->getCommandType ()->isQueuable () == qAlways && tryQueue) - { - // Its a produce or upgrade command called without queued key - // in this case we must NOT delete lower priority commands! - // we just queue it! - - } - else - { - //Delete all lower-prioirty commands - for (list < Command * >::iterator i = commands.begin (); - i != commands.end ();) - { - if ((*i)->getPriority () < command_priority) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugUnitCommands).enabled) - SystemFlags::OutputDebug (SystemFlags::debugUnitCommands, - "In [%s::%s Line: %d] Deleting lower priority command [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, - (*i)->toString (false).c_str ()); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - - deleteQueuedCommand (*i); - i = commands.erase (i); - - safeMutex.ReleaseLock (); - } - else - { - ++i; - } - } - } - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - - //cancel current command if it is not queuable - if (commands.empty () == false && - commands.back ()->getCommandType ()->isQueueAppendable () == - false) - { - if (SystemFlags::getSystemSettingType - (SystemFlags::debugUnitCommands).enabled) - SystemFlags::OutputDebug (SystemFlags::debugUnitCommands, - "In [%s::%s Line: %d] Cancel command because last one is NOT queable [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, - commands.back ()-> - toString (false).c_str ()); - - cancelCommand (); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - } - else - { - //empty command queue - if (SystemFlags::getSystemSettingType - (SystemFlags::debugUnitCommands).enabled) - SystemFlags::OutputDebug (SystemFlags::debugUnitCommands, - "In [%s::%s Line: %d] Clear commands because current is NOT queable.\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - bool willChangedActiveCommand = (commands.empty () == false); - if (willChangedActiveCommand == true) - { - - CommandClass currCommandClass = - getCurrCommand ()->getCommandType ()->getClass (); - CommandClass commandClass = command->getCommandType ()->getClass (); - if (currCommandClass == commandClass) - { - - willChangedActiveCommand = false; - } - else if (currCommandClass == ccAttack || - currCommandClass == ccAttackStopped || - commandClass == ccAttack || - commandClass == ccAttackStopped) - { - - willChangedActiveCommand = true; - } - else - { - willChangedActiveCommand = false; - } - } - - if (willChangedActiveCommand == true) - { - - lastChangedActiveCommandFrame = changedActiveCommandFrame; - changedActiveCommandFrame = getFrameCount (); - - //printf("Line: %d getCurrCommand() [%s] command [%s]\n",__LINE__,getCurrCommand()->toString(false).c_str(),command->toString(false).c_str()); - } - - clearCommands (); - changedActiveCommand = willChangedActiveCommand; - - //printf("In [%s::%s] Line: %d cleared existing commands\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, chrono.getMillis ()); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - - //check command - result = checkCommand (command); - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugUnitCommands).enabled) - SystemFlags::OutputDebug (SystemFlags::debugUnitCommands, - "In [%s::%s Line: %d] checkCommand returned: [%d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - result.first); - - //printf("In [%s::%s] Line: %d check command returned %d, commands.size() = %d\n[%s]\n\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result,commands.size(),command->toString().c_str()); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - - if (result.first == crSuccess) - { - applyCommand (command); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - - //push back command - if (result.first == crSuccess) - { - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - - commands.push_back (command); - - safeMutex.ReleaseLock (); - } - else - { - delete command; - changedActiveCommand = false; - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugPerformance).enabled - && chrono.getMillis () > 0) - SystemFlags::OutputDebug (SystemFlags::debugPerformance, - "In [%s::%s] Line: %d took msecs: %lld\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, __LINE__, - chrono.getMillis ()); - - return result; - } - -//pop front (used when order is done) - CommandResult Unit::finishCommand () - { - changedActiveCommand = false; - retryCurrCommandCount = 0; - // Reset the progress when task completed. - resetProgress2 (); - this->setCurrentUnitTitle (""); - //is empty? - if (commands.empty ()) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - return crFailUndefined; - } - - //pop front - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - - delete commands.front (); - commands.erase (commands.begin ()); - - safeMutex.ReleaseLock (true); - - this->unitPath->clear (); - - while (commands.empty () == false) - { - if (commands.front ()->getUnit () != NULL - && this->faction->isUnitInLivingUnitsp (commands. - front ()->getUnit ()) == - false) - { - safeMutex.Lock (); - delete commands.front (); - commands.erase (commands.begin ()); - safeMutex.ReleaseLock (true); - } - else - { - break; - } - } - - return crSuccess; - } - -//to cancel a command - CommandResult Unit::cancelCommand () - { - changedActiveCommand = false; - retryCurrCommandCount = 0; - - this->setCurrentUnitTitle (""); - - //is empty? - if (commands.empty ()) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - return crFailUndefined; - } - - //undo command - undoCommand (commands.back ()); - - //delete ans pop command - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - - delete commands.back (); - commands.pop_back (); - - // Reset the progress if the last command in the queue was cancelled. - // We don't want to reset the progress if we're not removing the last command, - // because then the progress of the actual command in progress. - /// TODO: extra if statement below needed adding make the reset function properly. Can this be avoided? - if (commands.empty()) resetProgress2(); - - safeMutex.ReleaseLock (); - - //clear routes - this->unitPath->clear (); - - - - return crSuccess; - } - -// =================== route stack =================== - - void Unit::create (bool startingUnit) - { - faction->addUnit (this); - map->putUnitCells (this, pos); - if (startingUnit) - { - faction->applyStaticCosts (type, NULL); - } - } - - void Unit::born (const CommandType * ct) - { - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - faction->addStore (type); - faction->applyStaticProduction (type, ct); - setCurrSkill (scStop); - - checkItemInVault (&this->hp, this->hp); - int original_hp = this->hp; - - - //set hp from start hp - checkItemInVault (&this->ep, this->ep); - if (type->getStartHpType () == UnitType::stValue) - { - this->hp = type->getStartHpValue (); - } - else - { - this->hp = - type->getTotalMaxHp (&totalUpgrade) * - type->getStartHpPercentage () / 100; - } - - if (original_hp != this->hp) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault (&this->hp, this->hp); - - //set ep from start ep - checkItemInVault (&this->ep, this->ep); - if (type->getStartEpType () == UnitType::stValue) - { - this->ep = type->getStartEpValue (); - } - else - { - this->ep = - type->getTotalMaxEp (&totalUpgrade) * - type->getStartEpPercentage () / 100; - } - } - - void Unit::kill () - { - //no longer needs static resources - if (isBeingBuilt ()) - { - faction->deApplyStaticConsumption (type, - (getCurrCommand () != - NULL ? - getCurrCommand ()->getCommandType - () : NULL)); - } - else - { - faction->deApplyStaticCosts (type, - (getCurrCommand () != - NULL ? - getCurrCommand ()->getCommandType () : - NULL)); - } - - //do the cleaning - //clear commands ( and their blocking fields ) - clearCommands (); - - map->clearUnitCells (this, pos, true); - if (isBeingBuilt () == false) - { - faction->removeStore (type); - } - setCurrSkill (scDie); - - notifyObservers (UnitObserver::eKill); - - - UnitUpdater *unitUpdater = game->getWorld ()->getUnitUpdater (); - //unitUpdater->clearUnitPrecache(this); - unitUpdater->removeUnitPrecache (this); - } - - void Unit::undertake () - { - try - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] about to undertake unit id = %d [%s] [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, this->id, - this->getFullName (false).c_str (), - this->getDesc (false).c_str ()); - - // Remove any units that were previously in attack-boost range - if (currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.empty () == false - && currentAttackBoostOriginatorEffect.skillType != NULL) - { - for (unsigned int i = 0; - i < - currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.size (); ++i) - { - // Remove attack boost upgrades from unit - int findUnitId = - currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; - Unit *affectedUnit = game->getWorld ()->findUnitById (findUnitId); - if (affectedUnit != NULL) - { - affectedUnit->deapplyAttackBoost - (currentAttackBoostOriginatorEffect.skillType-> - getAttackBoost (), this); - } - - //printf("!!!! DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); - } - currentAttackBoostOriginatorEffect.currentAttackBoostUnits.clear (); - } - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - UnitUpdater *unitUpdater = game->getWorld ()->getUnitUpdater (); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - //unitUpdater->clearUnitPrecache(this); - unitUpdater->removeUnitPrecache (this); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - this->faction->deleteLivingUnits (id); - this->faction->deleteLivingUnitsp (this); - - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - - faction->removeUnit (this); - } - catch (const megaglest_runtime_error & ex) - { - string sErrBuf = ""; - if (ex.wantStackTrace () == true) - { - char szErrBuf[8096] = ""; - snprintf (szErrBuf, 8096, "In [%s::%s %d]", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - sErrBuf = - string (szErrBuf) + string ("\nerror [") + string (ex.what ()) + - string ("]\n"); - } - else - { - sErrBuf = ex.what (); - } - SystemFlags::OutputDebug (SystemFlags::debugError, sErrBuf.c_str ()); - - throw; - } - catch (const std::exception & ex) - { - char szErrBuf[8096] = ""; - snprintf (szErrBuf, 8096, "In [%s::%s %d]", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__); - string sErrBuf = - string (szErrBuf) + string ("\nerror [") + string (ex.what ()) + - string ("]\n"); - SystemFlags::OutputDebug (SystemFlags::debugError, sErrBuf.c_str ()); - - throw; - } - } - -// =================== Referencers =================== - - void Unit::addObserver (UnitObserver * unitObserver) - { - observers.push_back (unitObserver); - } - -//void Unit::removeObserver(UnitObserver *unitObserver){ -// observers.remove(unitObserver); -//} - - void Unit::notifyObservers (UnitObserver::Event event) - { - for (Observers::iterator it = observers.begin (); - it != observers.end (); ++it) - { - (*it)->unitEvent (event, this); - } - } - -// =================== Other =================== - - void Unit::resetHighlight () - { - highlight = 1.f; - } - - const CommandType *Unit::computeCommandType (const Vec2i & pos, - const Unit * - targetUnit) const - { - const CommandType *commandType = NULL; - - if (map->isInside (pos) == false - || map->isInsideSurface (map->toSurfCoords (pos)) == false) - { - throw megaglest_runtime_error ("#6 Invalid path position = " + - pos.getString ()); - } - - SurfaceCell *sc = map->getSurfaceCell (Map::toSurfCoords (pos)); - - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - //printf("Line: %d Unit::computeCommandType pos [%s] targetUnit [%s]\n",__LINE__,pos.getString().c_str(),(targetUnit != NULL ? targetUnit->getType()->getName().c_str() : "(null)")); - if (targetUnit != NULL) - { - //attack enemies - if (isAlly (targetUnit) == false) - { - commandType = - type->getFirstAttackCommand (targetUnit->getCurrField ()); - } - //repair allies - else - { - if (targetUnit->isBuilt () == false - || targetUnit->isDamaged () == true) - { - commandType = - type->getFirstRepairCommand (targetUnit->getType ()); - } - - //printf("Line: %d Unit::computeCommandType pos [%s] targetUnit [%s] commandType [%p]\n",__LINE__,pos.getString().c_str(),(targetUnit != NULL ? targetUnit->getType()->getName().c_str() : "(null)"),commandType); - - if (commandType == NULL && targetUnit != NULL) - { - //Command *command= this->getCurrCommand(); - //const HarvestCommandType *hct= dynamic_cast((command != NULL ? command->getCommandType() : NULL)); - - // Check if we can return whatever resources we have - if (targetUnit->getFactionIndex () == this->getFactionIndex () && - targetUnit->isOperative () == true && - this->getLoadType () != NULL && this->getLoadCount () != 0 && - targetUnit->getType () != NULL && - targetUnit->getType ()->getStore (this->getLoadType ()) > 0) - { - - commandType = type->getFirstHarvestEmergencyReturnCommand (); - } - } - } - } - else - { - //check harvest command - Resource *resource = sc->getResource (); - if (resource != NULL) - { - commandType = - type->getFirstHarvestCommand (resource->getType (), - this->getFaction ()); - } - } - - if (targetUnit == NULL && commandType == NULL) - { - const Vec2i unitTargetPos = pos; - Cell *cell = map->getCell (unitTargetPos); - if (cell != NULL && cell->getUnit (this->getCurrField ()) != NULL) - { - Unit *targetUnit = cell->getUnit (this->getCurrField ()); - if (targetUnit != NULL) - { - // Check if we want to help build (repair) any buildings instead of just moving - if (targetUnit->getFactionIndex () == this->getFactionIndex () && - (targetUnit->isBuilt () == false - || targetUnit->isDamaged () == true)) - { - const RepairCommandType *rct = - this->getType ()-> - getFirstRepairCommand (targetUnit->getType ()); - if (rct != NULL) - { - commandType = - type->getFirstRepairCommand (targetUnit->getType ()); - //printf("************ Unit will repair building built = %d, repair = %d\n",targetUnit->isBuilt(),targetUnit->isDamaged()); - } - } - } - } - } - - // Default command is the class of the unit (i.e. attack for attackers, walk for walkers). - // The default command is executed when a unit is produced and sent to a meeting point - // or when the unit is selected and right clicked to a position. - if (commandType == NULL) - { - // move - // commandType = type->getFirstCtOfClass (ccMove); - - // attack - // Is the unit class warrior? if yes, attack by default, else walk. - commandType = - type->getFirstCtOfClass (this->getType ()-> - isOfClass (ucWarrior) ? ccAttack : ccMove); - - // FIXME: I think a better solution would be to have a hotkey for this, - // the user can decide, and toggle in-game -andy5995 2018-02-03 - } - - return commandType; - } - - int64 Unit::getUpdateProgress () - { - if (progress > PROGRESS_SPEED_MULTIPLIER) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: progress > " MG_I64_SPECIFIER - ", progress = [" MG_I64_SPECIFIER "]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, PROGRESS_SPEED_MULTIPLIER, - progress); - throw megaglest_runtime_error (szBuf); - } - - if (currSkill == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - int64 newProgress = progress; - if (currSkill->getClass () != scDie) - { - //speed - int speed = currSkill->getTotalSpeed (&totalUpgrade); - - if (changedActiveCommand == true) - { - if (changedActiveCommandFrame - lastChangedActiveCommandFrame >= - MIN_FRAMECOUNT_CHANGE_COMMAND_SPEED) - { - //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] skill [%s] command [%s]\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,currSkill->toString(false).c_str(),getCurrCommand()->toString(false).c_str()); - //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] total = %u\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,(changedActiveCommandFrame - lastChangedActiveCommandFrame)); - speed = CHANGE_COMMAND_SPEED; - } - } - - //speed modifier - int64 diagonalFactor = getDiagonalFactor (); - int64 heightFactor = getHeightFactor (PROGRESS_SPEED_MULTIPLIER); - - //update progresses -// const Game *game = Renderer::getInstance().getGame(); -// if(game == NULL) { -// throw megaglest_runtime_error("game == NULL"); -// } -// if(game->getWorld() == NULL) { -// throw megaglest_runtime_error("game->getWorld() == NULL"); -// } - - newProgress = getUpdatedProgress (progress, GameConstants::updateFps, - speed, diagonalFactor, - heightFactor); - - } - return newProgress; - } - - bool Unit::needToUpdate () - { - bool return_value = false; - if (currSkill->getClass () != scDie) - { - int newProgress = getUpdateProgress (); - if (newProgress >= PROGRESS_SPEED_MULTIPLIER) - { - return_value = true; - } - } - return return_value; - } - - int64 Unit::getDiagonalFactor () - { - //speed modifier - int64 diagonalFactor = PROGRESS_SPEED_MULTIPLIER; - if (currSkill->getClass () == scMove) - { - //if moving in diagonal move slower - Vec2i dest = pos - lastPos; - if (abs (dest.x) + abs (dest.y) == 2) - { - //diagonalFactor = 0.71f * PROGRESS_SPEED_MULTIPLIER; - diagonalFactor = 71 * (PROGRESS_SPEED_MULTIPLIER / 100); - } - } - return diagonalFactor; - } - - int64 Unit::getHeightFactor (int64 speedMultiplier) - { - int64 heightFactor = speedMultiplier; - if (currSkill->getClass () == scMove) - { - //if moving to an higher cell move slower else move faster - Cell *unitCell = map->getCell (pos); - if (unitCell == NULL) - { - throw megaglest_runtime_error ("unitCell == NULL"); - } - - Cell *targetCell = map->getCell (targetPos); - if (targetCell == NULL) - { - throw megaglest_runtime_error ("targetCell == NULL"); - } - - int64 heightDiff = ((truncateDecimal < float >(unitCell->getHeight (), - 2) * - speedMultiplier) -(truncateDecimal < - float >(targetCell-> - getHeight (), - 2) * - speedMultiplier)); - //heightFactor= clamp(speedMultiplier + heightDiff / (5.f * speedMultiplier), 0.2f * speedMultiplier, 5.f * speedMultiplier); - heightFactor = - clamp (speedMultiplier + heightDiff / (5 * speedMultiplier), - (2 * (speedMultiplier / 10)), 5 * speedMultiplier); - } - - return heightFactor; - } - - int64 Unit::getSpeedDenominator (int64 updateFPS) - { - int64 speedDenominator = - (speedDivider * updateFPS) * PROGRESS_SPEED_MULTIPLIER; - return speedDenominator; - } - int64 Unit::getUpdatedProgress (int64 currentProgress, int64 updateFPS, - int64 speed, int64 diagonalFactor, - int64 heightFactor) - { - - int64 speedDenominator = getSpeedDenominator (updateFPS); - int64 newProgress = currentProgress; - int64 progressIncrease = - ((speed * diagonalFactor * heightFactor) / speedDenominator); - // Ensure we increment at least a value of 1 of the action will be stuck infinitely - if (speed > 0 && diagonalFactor > 0 && heightFactor > 0 - && progressIncrease == 0) - { - progressIncrease = 1; - } - - if (isNetworkCRCEnabled () == true) - { - float height = map->getCell (pos)->getHeight (); - float airHeight = game->getWorld ()->getTileset ()->getAirHeight (); - int cellUnitHeight = -1; - int cellObjectHeight = -1; - - Unit *unit = map->getCell (pos)->getUnit (fLand); - if (unit != NULL && unit->getType ()->getHeight () > airHeight) - { - cellUnitHeight = unit->getType ()->getHeight (); - } - else - { - SurfaceCell *sc = map->getSurfaceCell (map->toSurfCoords (pos)); - if (sc != NULL && sc->getObject () != NULL - && sc->getObject ()->getType () != NULL) - { - if (sc->getObject ()->getType ()->getHeight () > airHeight) - { - cellObjectHeight = sc->getObject ()->getType ()->getHeight (); - } - } - } - - - char szBuf[8096] = ""; - snprintf (szBuf, 8095, - "currentProgress = " MG_I64_SPECIFIER " updateFPS = " - MG_I64_SPECIFIER " speed = " MG_I64_SPECIFIER - " diagonalFactor = " MG_I64_SPECIFIER " heightFactor = " - MG_I64_SPECIFIER " speedDenominator = " MG_I64_SPECIFIER - " progressIncrease = " MG_I64_SPECIFIER " [" - MG_I64_SPECIFIER - "] height [%f] airHeight [%f] cellUnitHeight [%d] cellObjectHeight [%d] skill [%s] pos [%s] lastpos [%s]", - currentProgress, updateFPS, speed, diagonalFactor, - heightFactor, speedDenominator, progressIncrease, - ((speed * diagonalFactor * heightFactor) / - speedDenominator), height, airHeight, cellUnitHeight, - cellObjectHeight, - (currSkill != - NULL ? currSkill->getName ().c_str () : "none"), - pos.getString ().c_str (), lastPos.getString ().c_str ()); - networkCRCLogInfo = szBuf; - - //printf("%s\n",szBuf); - } - - newProgress += progressIncrease; - -// if(currSkill->getClass() == scMove || (currSkill->getClass() == scStop && this->loadCount > 0)) { -// printf("speedDenominator: " MG_I64_SPECIFIER " currentProgress: " MG_I64_SPECIFIER " speed: " MG_I64_SPECIFIER " diagonalFactor: " MG_I64_SPECIFIER " heightFactor: " MG_I64_SPECIFIER " progressIncrease: " MG_I64_SPECIFIER " newProgress: " MG_I64_SPECIFIER " TOP #: " MG_I64_SPECIFIER "\n",speedDenominator,currentProgress,speed,diagonalFactor,heightFactor,progressIncrease,newProgress,(speed * diagonalFactor * heightFactor)); -// } - - return newProgress; - } - - void Unit::updateAttackBoostProgress (const Game * game) - { - const bool debugBoost = false; - if (debugBoost) - printf - ("===================== START Unit [%d - %s] skill: %s affected unit size: " - MG_SIZE_T_SPECIFIER "\n", this->id, - this->getType ()->getName (false).c_str (), - currSkill->getBoostDesc (false).c_str (), - currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.size ()); - - if (currSkill != currentAttackBoostOriginatorEffect.skillType) - { - - if (debugBoost) - printf ("Line: %d new [%s]\n", __LINE__, - (currentAttackBoostOriginatorEffect.skillType != - NULL ? currentAttackBoostOriginatorEffect. - skillType->getBoostDesc (false).c_str () : "")); - - if (currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) - { - delete currentAttackBoostOriginatorEffect.currentAppliedEffect; - currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL; - - //printf("- #1 DE-APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); - } - - // Remove any units that were previously in range - if (currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.empty () == false - && currentAttackBoostOriginatorEffect.skillType != NULL) - { - for (unsigned int i = 0; - i < - currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.size (); ++i) - { - // Remove attack boost upgrades from unit - - int findUnitId = - currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; - Unit *affectedUnit = game->getWorld ()->findUnitById (findUnitId); - if (affectedUnit != NULL) - { - affectedUnit->deapplyAttackBoost - (currentAttackBoostOriginatorEffect.skillType-> - getAttackBoost (), this); - } - - //printf("- #1 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); - } - currentAttackBoostOriginatorEffect.currentAttackBoostUnits.clear (); - } - - if (debugBoost) - printf ("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n", - __LINE__, - currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.size ()); - - currentAttackBoostOriginatorEffect.skillType = currSkill; - - if (currSkill->isAttackBoostEnabled () == true) - { - if (debugBoost) - printf ("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n", - __LINE__, - currentAttackBoostOriginatorEffect.currentAttackBoostUnits. - size ()); - - // Search for units in range of this unit which apply to the - // attack-boost and temporarily upgrade them - UnitUpdater *unitUpdater = - this->game->getWorld ()->getUnitUpdater (); - - const AttackBoost *attackBoost = currSkill->getAttackBoost (); - vector < Unit * >candidates = unitUpdater->findUnitsInRange (this, - attackBoost->radius); - - if (debugBoost) - printf ("Line: %d candidates unit size: " MG_SIZE_T_SPECIFIER - " attackBoost: %s\n", __LINE__, candidates.size (), - attackBoost->getDesc (false).c_str ()); - for (unsigned int i = 0; i < candidates.size (); ++i) - { - Unit *affectedUnit = candidates[i]; - if (attackBoost->isAffected (this, affectedUnit) == true) - { - if (affectedUnit->applyAttackBoost (attackBoost, this) == true) - { - currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.push_back (affectedUnit->getId ()); - //printf("+ #1 APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); - } - } - } - - if (debugBoost) - printf ("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n", - __LINE__, - currentAttackBoostOriginatorEffect.currentAttackBoostUnits. - size ()); - - if (showUnitParticles == true) - { - if (currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.empty () == false) - { - if (attackBoost->unitParticleSystemTypeForSourceUnit != NULL) - { - currentAttackBoostOriginatorEffect.currentAppliedEffect = - new UnitAttackBoostEffect (); - currentAttackBoostOriginatorEffect. - currentAppliedEffect->upst = new UnitParticleSystemType (); - *currentAttackBoostOriginatorEffect. - currentAppliedEffect->upst = - *attackBoost->unitParticleSystemTypeForSourceUnit; - //effect.upst = boost->unitParticleSystemTypeForAffectedUnit; - - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups = - new UnitParticleSystem (200); - currentAttackBoostOriginatorEffect.currentAppliedEffect-> - ups->setParticleOwner (this); - currentAttackBoostOriginatorEffect.currentAppliedEffect-> - ups->setParticleType - (currentAttackBoostOriginatorEffect.currentAppliedEffect-> - upst); - - currentAttackBoostOriginatorEffect. - currentAppliedEffect->upst-> - setValues - (currentAttackBoostOriginatorEffect.currentAppliedEffect-> - ups); - currentAttackBoostOriginatorEffect.currentAppliedEffect-> - ups->setPos (getCurrVectorForParticlesystems ()); - currentAttackBoostOriginatorEffect.currentAppliedEffect-> - ups->setRotation (getRotation ()); - setMeshPosInParticleSystem - (currentAttackBoostOriginatorEffect. - currentAppliedEffect->ups); - - if (getFaction ()->getTexture ()) - { - currentAttackBoostOriginatorEffect. - currentAppliedEffect->ups-> - setFactionColor (getFaction ()->getTexture ()-> - getPixmapConst ()->getPixel3f (0, 0)); - } - Renderer:: - getInstance ().manageParticleSystem - (currentAttackBoostOriginatorEffect.currentAppliedEffect-> - ups, rsGame); - //printf("+ #1 APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); - } - } - } - } - } - else - { - if (currSkill->isAttackBoostEnabled () == true) - { - if (debugBoost) - printf ("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n", - __LINE__, - currentAttackBoostOriginatorEffect.currentAttackBoostUnits. - size ()); - - // Search for units in range of this unit which apply to the - // attack-boost and temporarily upgrade them - UnitUpdater *unitUpdater = - this->game->getWorld ()->getUnitUpdater (); - - const AttackBoost *attackBoost = currSkill->getAttackBoost (); - vector < Unit * >candidates = - unitUpdater->findUnitsInRange (this, attackBoost->radius); - vector < int >candidateValidIdList; - candidateValidIdList.reserve (candidates.size ()); - - if (debugBoost) - printf ("Line: %d candidates unit size: " MG_SIZE_T_SPECIFIER - " attackBoost: %s\n", __LINE__, candidates.size (), - attackBoost->getDesc (false).c_str ()); - - for (unsigned int i = 0; i < candidates.size (); ++i) - { - Unit *affectedUnit = candidates[i]; - candidateValidIdList.push_back (affectedUnit->getId ()); - - std::vector < int >::iterator iterFound = - std:: - find - (currentAttackBoostOriginatorEffect.currentAttackBoostUnits. - begin (), - currentAttackBoostOriginatorEffect.currentAttackBoostUnits. - end (), - affectedUnit->getId ()); - - if (attackBoost->isAffected (this, affectedUnit) == true) - { - if (iterFound == - currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.end ()) - { - if (affectedUnit->applyAttackBoost (attackBoost, this) == - true) - { - currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.push_back (affectedUnit-> - getId ()); - - //printf("+ #2 APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); - } - } - } - else - { - if (iterFound != - currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.end ()) - { - affectedUnit->deapplyAttackBoost - (currentAttackBoostOriginatorEffect.skillType-> - getAttackBoost (), this); - currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.erase (iterFound); - - //printf("- #2 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); - } - } - } - - // Now remove any units that were in the list of boosted units but - // are no longer in range - if (currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.empty () == false) - { - for (int i = - (int) - currentAttackBoostOriginatorEffect.currentAttackBoostUnits. - size () - 1; i >= 0; --i) - { - int findUnitId = - currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; - - std::vector < int >::iterator iterFound = - std::find (candidateValidIdList.begin (), - candidateValidIdList.end (), - findUnitId); - if (iterFound == candidateValidIdList.end ()) - { - Unit *affectedUnit = - game->getWorld ()->findUnitById (findUnitId); - if (affectedUnit != NULL) - { - affectedUnit->deapplyAttackBoost - (currentAttackBoostOriginatorEffect.skillType-> - getAttackBoost (), this); - - if (debugBoost) - printf - ("Removed attack boost from Unit [%d - %s] since they are NO LONGER in range\n", - affectedUnit->id, - affectedUnit->getType ()->getName (false).c_str ()); - - } - currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.erase - (currentAttackBoostOriginatorEffect.currentAttackBoostUnits. - begin () + i); - } - } - } - - if (debugBoost) - printf ("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n", - __LINE__, - currentAttackBoostOriginatorEffect.currentAttackBoostUnits. - size ()); - - if (showUnitParticles == true) - { - if (currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.empty () == false) - { - if (attackBoost->unitParticleSystemTypeForSourceUnit != NULL - && currentAttackBoostOriginatorEffect.currentAppliedEffect - == NULL) - { - - currentAttackBoostOriginatorEffect.currentAppliedEffect = - new UnitAttackBoostEffect (); - currentAttackBoostOriginatorEffect. - currentAppliedEffect->upst = new UnitParticleSystemType (); - *currentAttackBoostOriginatorEffect. - currentAppliedEffect->upst = - *attackBoost->unitParticleSystemTypeForSourceUnit; - //effect.upst = boost->unitParticleSystemTypeForAffectedUnit; - - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups = - new UnitParticleSystem (200); - currentAttackBoostOriginatorEffect.currentAppliedEffect-> - ups->setParticleOwner (this); - currentAttackBoostOriginatorEffect.currentAppliedEffect-> - ups->setParticleType - (currentAttackBoostOriginatorEffect.currentAppliedEffect-> - upst); - - currentAttackBoostOriginatorEffect. - currentAppliedEffect->upst-> - setValues - (currentAttackBoostOriginatorEffect.currentAppliedEffect-> - ups); - currentAttackBoostOriginatorEffect.currentAppliedEffect-> - ups->setPos (getCurrVectorForParticlesystems ()); - currentAttackBoostOriginatorEffect.currentAppliedEffect-> - ups->setRotation (getRotation ()); - setMeshPosInParticleSystem - (currentAttackBoostOriginatorEffect. - currentAppliedEffect->ups); - - if (getFaction ()->getTexture ()) - { - currentAttackBoostOriginatorEffect. - currentAppliedEffect->ups-> - setFactionColor (getFaction ()-> - getTexture ()->getPixmapConst ()-> - getPixel3f (0, 0)); - } - Renderer:: - getInstance ().manageParticleSystem - (currentAttackBoostOriginatorEffect.currentAppliedEffect-> - ups, rsGame); - - //printf("+ #2 APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); - } - } - else - if (currentAttackBoostOriginatorEffect.currentAttackBoostUnits. - empty () == true) - { - if (currentAttackBoostOriginatorEffect.currentAppliedEffect != - NULL) - { - delete - currentAttackBoostOriginatorEffect.currentAppliedEffect; - currentAttackBoostOriginatorEffect.currentAppliedEffect = - NULL; - - //printf("- #2 DE-APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); - } - } - } - } - } - - if (debugBoost) - { - if (currSkill->isAttackBoostEnabled () == true) - { - printf ("Unit [%d - %s] has attackboost enabled: %s\n", this->id, - this->getType ()->getName (false).c_str (), - currSkill->getBoostDesc (false).c_str ()); - - if (currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.empty () == false) - { - printf - ("Found affected units currentAttackBoostOriginatorEffect.skillType [%p]\n", - currentAttackBoostOriginatorEffect.skillType); - - for (unsigned int i = 0; - i < - currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.size (); ++i) - { - int unitnum = - currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; - printf ("affected unit #: %u - %d\n", i, unitnum); - } - } - } - } - } - - bool Unit::update () - { - assert (progress <= PROGRESS_SPEED_MULTIPLIER); - - //highlight - if (highlight > 0.f) - { - const Game *game = Renderer::getInstance ().getGame (); - highlight -= - 1.f / (Game::highlightTime * - game->getWorld ()->getUpdateFps (this->getFactionIndex ())); - } - - if (currSkill == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - //speed - int speed = currSkill->getTotalSpeed (&totalUpgrade); - - if (oldTotalSight != - getType ()->getTotalSight (this->getTotalUpgrade ())) - { - oldTotalSight = getType ()->getTotalSight (this->getTotalUpgrade ()); - // refresh FogOfWar and so on, because sight ha changed since last update - refreshPos (true); - } - - if (changedActiveCommand) - { - if (changedActiveCommandFrame - lastChangedActiveCommandFrame >= - MIN_FRAMECOUNT_CHANGE_COMMAND_SPEED) - { - //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] skill [%s] command [%s]\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,currSkill->toString(false).c_str(),getCurrCommand()->toString(false).c_str()); - //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] total = %u\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,(changedActiveCommandFrame - lastChangedActiveCommandFrame)); - speed = CHANGE_COMMAND_SPEED; - } - } - - //speed modifier - int64 diagonalFactor = getDiagonalFactor (); - int64 heightFactor = getHeightFactor (PROGRESS_SPEED_MULTIPLIER); - - //update progresses - this->lastAnimProgress = this->animProgress; - const Game *game = Renderer::getInstance ().getGame (); - - if (animProgress == 0) - { - AnimCycleStarts (); - } - progress = getUpdatedProgress (progress, - GameConstants::updateFps, - speed, diagonalFactor, heightFactor); - - //printf("Test progress = %d for unit [%d - %s]\n",progress,id,getType()->getName().c_str()); - - if (isAnimProgressBound () == true) - { - float targetProgress = 0; - if (currSkill->getClass () == scBeBuilt) - { - targetProgress = this->getHpRatio (); - } - if (currSkill->getClass () == scProduce) - { - targetProgress = this->getProgressRatio (); - } - if (currSkill->getClass () == scUpgrade) - { - targetProgress = this->getProgressRatio (); - } - if (currSkill->getClass () == scMorph) - { - targetProgress = this->getProgressRatio (); - } - - float targetProgressIntValue = - targetProgress * ANIMATION_SPEED_MULTIPLIER; - if (this->animProgress < targetProgressIntValue) - { - float diff = targetProgressIntValue - this->animProgress; - float progressIncrease = - static_cast < float >(this->animProgress) + diff / static_cast < - float >(GameConstants::updateFps); - // Ensure we increment at least a value of 1 of the action will be stuck infinitely - if (diff > 0.f && GameConstants::updateFps > 0 - && progressIncrease == 0.f) - { - progressIncrease = 1.f; - } - - //if(currSkill->getClass() == scBeBuilt) { - // printf("targetProgress: %.10f this->animProgress: %d diff: %.10f GameConstants::updateFps: %d progressIncrease: %.10f\n",targetProgress,this->animProgress,diff,GameConstants::updateFps,progressIncrease); - //} - - this->animProgress = progressIncrease; - - //if(currSkill->getClass() == scBeBuilt) { - // printf("Unit build progress: %d anim: %d\n",progress,this->animProgress); - //} - } - } - else - { - int64 heightFactor = getHeightFactor (ANIMATION_SPEED_MULTIPLIER); - int64 speedDenominator = speedDivider * - game->getWorld ()->getUpdateFps (this->getFactionIndex ()); - - // Override the animation speed for attacks that have upgraded the attack speed - int animSpeed = currSkill->getAnimSpeed (); - if (currSkill->getClass () == scAttack) - { - int animSpeedBoost = - ((AttackSkillType *) - currSkill)->getAnimSpeedBoost (&totalUpgrade); - animSpeed += animSpeedBoost; - } - - int64 progressIncrease = - (animSpeed * heightFactor) / speedDenominator; - // Ensure we increment at least a value of 1 of the action will be stuck infinitely - if (currSkill->getAnimSpeed () > 0 && heightFactor > 0 - && progressIncrease == 0) - { - progressIncrease = 1; - } - this->animProgress += progressIncrease; - //this->animProgress += (currSkill->getAnimSpeed() * heightFactor) / speedDenominator; - - //if(currSkill->getClass() == scDie) { - // printf("Unit died progress: %d anim: %d\n",progress,this->animProgress); - //} - } - //update target - updateTarget (); - - //rotation - if (currSkill->getClass () != scStop) - { - const int rotFactor = 2; - if (getProgressAsFloat () < 1.f / rotFactor) - { - if (type->getFirstStOfClass (scMove)) - { - if (abs ((int) (lastRotation - targetRotation)) < 180) - rotation = lastRotation + (targetRotation - lastRotation) * - getProgressAsFloat () * rotFactor; - else - { - float rotationTerm = - targetRotation > lastRotation ? -360.f : +360.f; - rotation = - lastRotation + (targetRotation - lastRotation + - rotationTerm) * getProgressAsFloat () * - rotFactor; - } - } - } - } - - if (type->getProperty (UnitType::pRotatedClimb)) - { - calculateXZRotation (); - } - else - { - rotationZ = .0f; - rotationX = .0f; - } - - if (Renderer:: - getInstance ().validateParticleSystemStillExists (this->fire, - rsGame) == false) - { - this->fire = NULL; - } - - if (this->fire != NULL) - { - this->fire->setPos (getCurrBurnVector ()); - } - for (UnitParticleSystems::iterator it = unitParticleSystems.begin (); - it != unitParticleSystems.end (); ++it) - { - if (Renderer:: - getInstance ().validateParticleSystemStillExists ((*it), - rsGame) == true) - { - (*it)->setPos (getCurrVectorForParticlesystems ()); - (*it)->setRotation (getRotation ()); - setMeshPosInParticleSystem (*it); - } - } - for (UnitParticleSystems::iterator it = damageParticleSystems.begin (); - it != damageParticleSystems.end (); ++it) - { - if (Renderer:: - getInstance ().validateParticleSystemStillExists ((*it), - rsGame) == true) - { - (*it)->setPos (getCurrVectorForParticlesystems ()); - (*it)->setRotation (getRotation ()); - setMeshPosInParticleSystem (*it); - } - } - - for (UnitParticleSystems::iterator it = smokeParticleSystems.begin (); - it != smokeParticleSystems.end (); ++it) - { - if (Renderer:: - getInstance ().validateParticleSystemStillExists ((*it), - rsGame) == true) - { - (*it)->setPos (getCurrMidHeightVector ()); - (*it)->setRotation (getRotation ()); - setMeshPosInParticleSystem (*it); - } - } - - //printf("Unit has attack boost? unit = [%d - %s] size = %d\n",this->getId(), this->getType()->getName(false).c_str(),(int)currentAttackBoostEffects.size()); - for (unsigned int i = 0; i < currentAttackBoostEffects.size (); ++i) - { - UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; - if (effect != NULL && effect->ups != NULL) - { - bool particleValid = - Renderer:: - getInstance ().validateParticleSystemStillExists (effect->ups, - rsGame); - if (particleValid == true) - { - effect->ups->setPos (getCurrVectorForParticlesystems ()); - effect->ups->setRotation (getRotation ()); - setMeshPosInParticleSystem (effect->ups); - } - - //printf("i = %d particleValid = %d\n",i,particleValid); - } - //printf("i = %d effect = %p effect->ups = %p\n",i,effect,(effect ? effect->ups : NULL)); - } - - - if (currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) - { - if (currentAttackBoostOriginatorEffect.currentAppliedEffect->ups != - NULL) - { - bool particleValid = - Renderer::getInstance ().validateParticleSystemStillExists - (currentAttackBoostOriginatorEffect.currentAppliedEffect->ups, - rsGame); - if (particleValid == true) - { - currentAttackBoostOriginatorEffect.currentAppliedEffect-> - ups->setPos (getCurrVectorForParticlesystems ()); - currentAttackBoostOriginatorEffect.currentAppliedEffect-> - ups->setRotation (getRotation ()); - setMeshPosInParticleSystem - (currentAttackBoostOriginatorEffect.currentAppliedEffect->ups); - } - } - } - - //checks - if (this->animProgress > ANIMATION_SPEED_MULTIPLIER) - { - bool canCycle = - currSkill->CanCycleNextRandomAnimation (&animationRandomCycleCount); - this->animProgress = - currSkill->getClass () == scDie ? ANIMATION_SPEED_MULTIPLIER : 0; - if (canCycle == true) - { - this->lastModelIndexForCurrSkillType = -1; - } - } - - bool return_value = false; - //checks - if (progress >= PROGRESS_SPEED_MULTIPLIER) - { - lastRotation = targetRotation; - if (currSkill->getClass () != scDie) - { - progress = 0; - return_value = true; - } - else - { - progress = PROGRESS_SPEED_MULTIPLIER; - deadCount++; - if (deadCount >= maxDeadCount) - { - toBeUndertaken = true; - return_value = false; - } - } - } - - updateAttackBoostProgress (game); - - if (return_value) - { - changedActiveCommand = false; - } - - return return_value; - } - - void Unit::updateTimedParticles () - { - //!!! - // Start new particle systems based on start time - if (queuedUnitParticleSystemTypes.empty () == false) - { - for (int i = (int)queuedUnitParticleSystemTypes.size () - 1; i >= 0; - i--) - { - UnitParticleSystemType *pst = queuedUnitParticleSystemTypes[i]; - if (pst != NULL) - { - if (truncateDecimal < float >(pst->getStartTime (), 6) <= - truncateDecimal < float >(getAnimProgressAsFloat (), 6)) - { - - UnitParticleSystem *ups = new UnitParticleSystem (200); - ups->setParticleOwner (this); - ups->setParticleType (pst); - - pst->setValues (ups); - ups->setPos (getCurrVectorForParticlesystems ()); - ups->setRotation (getRotation ()); - setMeshPosInParticleSystem (ups); - - if (getFaction ()->getTexture ()) - { - ups->setFactionColor (getFaction ()-> - getTexture ()->getPixmapConst ()-> - getPixel3f (0, 0)); - } - unitParticleSystems.push_back (ups); - Renderer::getInstance ().manageParticleSystem (ups, rsGame); - - queuedUnitParticleSystemTypes.erase - (queuedUnitParticleSystemTypes.begin () + i); - } - } - else - { - queuedUnitParticleSystemTypes.erase - (queuedUnitParticleSystemTypes.begin () + i); - } - } - } - - // End existing systems based on end time - if (unitParticleSystems.empty () == false) - { - for (int i = (int)unitParticleSystems.size () - 1; i >= 0; i--) - { - UnitParticleSystem *ps = unitParticleSystems[i]; - if (ps != NULL) - { - if (Renderer:: - getInstance ().validateParticleSystemStillExists (ps, - rsGame) == - true) - { - float pst = ps->getStartTime (); - float pet = ps->getEndTime (); - float particleStartTime = truncateDecimal < float >(pst, 6); - float particleEndTime = truncateDecimal < float >(pet, 6); - - if (particleStartTime != 0.0 || particleEndTime != 1.0) - { - float animProgressTime = - truncateDecimal < float >(getAnimProgressAsFloat (), 6); - if (animProgressTime >= 0.99 - || animProgressTime >= particleEndTime) - { - - ps->fade (); - unitParticleSystems.erase (unitParticleSystems.begin () + - i); - } - } - } - } - } - } - } - - bool Unit::unitHasAttackBoost (const AttackBoost * boost, - const Unit * source) - { - bool result = false; - for (unsigned int i = 0; i < currentAttackBoostEffects.size (); ++i) - { - UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; - if (effect != NULL && effect->boost->name == boost->name && - effect->getSource ()->getType ()->getId () == - source->getType ()->getId ()) - { - result = true; - break; - } - } - - //printf("Unit has attack boost? source = [%d - %s] [%p] boost [%s] result = %d\n",source->getId(), source->getType()->getName(false).c_str(),source,boost->name.c_str(),result); - - return result; - } - - bool Unit::applyAttackBoost (const AttackBoost * boost, - const Unit * source) - { - if (boost == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: boost == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - //printf("APPLYING ATTACK BOOST to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); - - bool shouldApplyAttackBoost = true; - if (boost->allowMultipleBoosts == false) - { - // Check if we already have this boost from this unit type and multiples - // are not allowed - bool alreadyHasAttackBoost = this->unitHasAttackBoost (boost, source); - if (alreadyHasAttackBoost == true) - { - shouldApplyAttackBoost = false; - } - } - - if (shouldApplyAttackBoost == true) - { - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("=== APPLYING ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n", - this->getType ()->getName (false).c_str (), this->getId (), - source->getType ()->getName (false).c_str (), source->getId (), - hp); - - UnitAttackBoostEffect *effect = new UnitAttackBoostEffect (); - effect->boost = boost; - effect->setSource (source); - - bool wasAlive = alive; - int originalHp = hp; - int prevMaxHp = totalUpgrade.getMaxHp (); - int prevMaxHpRegen = totalUpgrade.getMaxHpRegeneration (); - //printf("#1 wasAlive = %d hp = %d boosthp = %d\n",wasAlive,hp,boost->boostUpgrade.getMaxHp()); - - totalUpgrade.apply (source->getId (), &boost->boostUpgrade, this); - - checkItemInVault (&this->hp, this->hp); - //hp += boost->boostUpgrade.getMaxHp(); - int original_hp = this->hp; - this->hp += (totalUpgrade.getMaxHp () - prevMaxHp); - if (original_hp != this->hp) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault (&this->hp, this->hp); - - //regenerate hp upgrade / or boost - if (totalUpgrade.getMaxHpRegeneration () != 0) - { - checkItemInVault (&this->hp, this->hp); - - //printf("BEFORE Apply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); - int original_hp = this->hp; - this->hp += (totalUpgrade.getMaxHpRegeneration () - prevMaxHpRegen); - if (original_hp != this->hp) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - //if(hp > type->getTotalMaxHp(&totalUpgrade)) { - // hp = type->getTotalMaxHp(&totalUpgrade); - //} - addItemToVault (&this->hp, this->hp); - - //printf("AFTER Apply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); - } - - checkModelStateInfoForNewHpValue (); - - if (originalHp < hp) - { - this->setLastAttackerUnitId (source->getId ()); - } - //printf("#2 wasAlive = %d hp = %d boosthp = %d\n",wasAlive,hp,boost->boostUpgrade.getMaxHp()); - - if (showUnitParticles == true) - { - if (boost->unitParticleSystemTypeForAffectedUnit != NULL) - { - effect->upst = new UnitParticleSystemType (); - *effect->upst = *boost->unitParticleSystemTypeForAffectedUnit; - //effect.upst = boost->unitParticleSystemTypeForAffectedUnit; - - effect->ups = new UnitParticleSystem (200); - effect->ups->setParticleOwner (this); - effect->ups->setParticleType (effect->upst); - - effect->upst->setValues (effect->ups); - effect->ups->setPos (getCurrVectorForParticlesystems ()); - effect->ups->setRotation (getRotation ()); - setMeshPosInParticleSystem (effect->ups); - if (getFaction ()->getTexture ()) - { - effect->ups->setFactionColor (getFaction ()-> - getTexture ()->getPixmapConst ()-> - getPixel3f (0, 0)); - } - Renderer::getInstance ().manageParticleSystem (effect->ups, - rsGame); - } - } - currentAttackBoostEffects.push_back (effect); - - if (wasAlive == true) - { - //startDamageParticles - - if (originalHp > this->hp) - { - startDamageParticles (); - } - - //stop DamageParticles on death - if (this->hp <= 0) - { - setAlive (false); - this->hp = 0; - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - addItemToVault (&this->hp, this->hp); - checkModelStateInfoForNewHpValue (); - - stopDamageParticles (true); - - this->setLastAttackerUnitId (source->getId ()); - this->setCauseOfDeath (ucodAttackBoost); - Unit::game->getWorld ()->getStats ()->die (getFactionIndex (), - getType - ()->getCountUnitDeathInStats - ()); - game->getScriptManager ()->onUnitDied (this); - - StaticSound *sound = - static_cast < - const DieSkillType * - >(this->getType ()->getFirstStOfClass (scDie))->getSound (); - if (sound != NULL - && (this->getFactionIndex () == - Unit::game->getWorld ()->getThisFactionIndex () - || (game-> - getWorld ()->showWorldForPlayer (game-> - getWorld - ()->getThisTeamIndex - ()) == true))) - { - SoundRenderer::getInstance ().playFx (sound); - } - - if (this->isDead () - && this->getCurrSkill ()->getClass () != scDie) - { - this->kill (); - } - } - } - - //printf("APPLYING ATTACK BOOST END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("APPLIED ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n", - this->getType ()->getName (false).c_str (), this->getId (), - source->getType ()->getName (false).c_str (), source->getId (), - hp); - - return shouldApplyAttackBoost; - } - - void Unit::deapplyAttackBoost (const AttackBoost * boost, - const Unit * source) - { - if (boost == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: boost == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("=== DE-APPLYING ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n", - this->getType ()->getName (false).c_str (), this->getId (), - source->getType ()->getName (false).c_str (), source->getId (), - hp); - - bool wasAlive = alive; - int originalHp = hp; - int prevMaxHp = totalUpgrade.getMaxHp (); - int prevMaxHpRegen = totalUpgrade.getMaxHpRegeneration (); - totalUpgrade.deapply (source->getId (), &boost->boostUpgrade, - this->getId ()); - - checkItemInVault (&this->hp, this->hp); - int original_hp = this->hp; - //hp -= boost->boostUpgrade.getMaxHp(); - this->hp -= (prevMaxHp - totalUpgrade.getMaxHp ()); - if (original_hp != this->hp) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault (&this->hp, this->hp); - - //regenerate hp upgrade / or boost - if (totalUpgrade.getMaxHpRegeneration () != 0) - { - checkItemInVault (&this->hp, this->hp); - - //printf("BEFORE DeApply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); - int original_hp = this->hp; - this->hp -= (totalUpgrade.getMaxHpRegeneration () - prevMaxHpRegen); - if (original_hp != this->hp) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - //if(hp > totalUpgrade.getMaxHp()) { - // hp = totalUpgrade.getMaxHp(); - //} - addItemToVault (&this->hp, this->hp); - - //printf("AFTER DeApply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); - } - - if (originalHp < hp) - { - this->setLastAttackerUnitId (source->getId ()); - } - - if (wasAlive == true) - { - //printf("DE-APPLYING ATTACK BOOST wasalive = true to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); - - //startDamageParticles - if (originalHp > this->hp) - { - startDamageParticles (); - } - - //stop DamageParticles on death - if (this->hp <= 0) - { - setAlive (false); - this->hp = 0; - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - addItemToVault (&this->hp, this->hp); - - checkModelStateInfoForNewHpValue (); - - stopDamageParticles (true); - - this->setLastAttackerUnitId (source->getId ()); - this->setCauseOfDeath (ucodAttackBoost); - - Unit::game->getWorld ()->getStats ()->die (getFactionIndex (), - getType - ()->getCountUnitDeathInStats - ()); - game->getScriptManager ()->onUnitDied (this); - - StaticSound *sound = - static_cast < - const DieSkillType * - >(this->getType ()->getFirstStOfClass (scDie))->getSound (); - if (sound != NULL - && (this->getFactionIndex () == - Unit::game->getWorld ()->getThisFactionIndex () - || (game-> - getWorld ()->showWorldForPlayer (game-> - getWorld - ()->getThisTeamIndex - ()) == true))) - { - SoundRenderer::getInstance ().playFx (sound); - } - - if (this->isDead () && this->getCurrSkill ()->getClass () != scDie) - { - this->kill (); - } - } - } - - checkModelStateInfoForNewHpValue (); - - //printf("DE-APPLYING ATTACK BOOST BEFORE END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); - - for (unsigned int i = 0; i < currentAttackBoostEffects.size (); ++i) - { - UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; - if (effect != NULL && effect->boost == boost - && effect->getSource () == source) - { - delete effect; - currentAttackBoostEffects. - erase (currentAttackBoostEffects.begin () + i); - break; - } - } - - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("DE-APPLIED ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n", - this->getType ()->getName (false).c_str (), this->getId (), - source->getType ()->getName (false).c_str (), source->getId (), - hp); - - //printf("DE-APPLYING ATTACK BOOST END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); - } - - void Unit::tick () - { - - if (isAlive ()) - { - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - //if(this->getType()->getName() == "spearman") printf("Unit [%d - %s] start tick hp = %d\n",this->getId(),this->getType()->getName().c_str(),hp); - - - //regenerate hp upgrade / or boost - if (type->getTotalMaxHpRegeneration (&totalUpgrade) != 0) - { - if (currSkill->getClass () != scBeBuilt) - { - if (type->getTotalMaxHpRegeneration (&totalUpgrade) >= 0) - { - checkItemInVault (&this->hp, this->hp); - int original_hp = this->hp; - this->hp += type->getTotalMaxHpRegeneration (&totalUpgrade); - if (this->hp > type->getTotalMaxHp (&totalUpgrade)) - { - this->hp = type->getTotalMaxHp (&totalUpgrade); - } - if (original_hp != this->hp) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault (&this->hp, this->hp); - - checkModelStateInfoForNewHpValue (); - //if(this->getType()->getName() == "spearman") printf("tick hp#2 [type->getTotalMaxHpRegeneration(&totalUpgrade)] = %d type->getTotalMaxHp(&totalUpgrade) [%d] newhp = %d\n",type->getTotalMaxHpRegeneration(&totalUpgrade),type->getTotalMaxHp(&totalUpgrade),hp); - } - // If we have negative regeneration then check if the unit should die - else - { - bool decHpResult = - decHp (-type->getTotalMaxHpRegeneration (&totalUpgrade)); - if (decHpResult) - { - this->setCauseOfDeath (ucodStarvedRegeneration); - - Unit::game->getWorld ()->getStats ()->die (getFactionIndex (), - getType - ()->getCountUnitDeathInStats - ()); - game->getScriptManager ()->onUnitDied (this); - } - StaticSound *sound = - static_cast < - const DieSkillType * - >(this->getType ()->getFirstStOfClass (scDie))->getSound (); - if (sound != NULL - && (this->getFactionIndex () == - Unit::game->getWorld ()->getThisFactionIndex () - || (game-> - getWorld ()->showWorldForPlayer (game-> - getWorld - ()->getThisTeamIndex - ()) == true))) - { - SoundRenderer::getInstance ().playFx (sound); - } - } - } - } - //regenerate hp - else - { - if (type->getTotalMaxHpRegeneration (&totalUpgrade) >= 0) - { - if (currSkill->getClass () != scBeBuilt) - { - checkItemInVault (&this->hp, this->hp); - int original_hp = this->hp; - this->hp += type->getTotalMaxHpRegeneration (&totalUpgrade); - if (this->hp > type->getTotalMaxHp (&totalUpgrade)) - { - this->hp = type->getTotalMaxHp (&totalUpgrade); - } - if (original_hp != this->hp) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault (&this->hp, this->hp); - - checkModelStateInfoForNewHpValue (); - //if(this->getType()->getName() == "spearman") printf("tick hp#1 [type->getHpRegeneration()] = %d type->getTotalMaxHp(&totalUpgrade) [%d] newhp = %d\n",type->getHpRegeneration(),type->getTotalMaxHp(&totalUpgrade),hp); - } - } - // If we have negative regeneration then check if the unit should die - else - { - bool decHpResult = - decHp (-type->getTotalMaxHpRegeneration (&totalUpgrade)); - if (decHpResult) - { - this->setCauseOfDeath (ucodStarvedRegeneration); - - Unit::game->getWorld ()->getStats ()->die (getFactionIndex (), - getType - ()->getCountUnitDeathInStats - ()); - game->getScriptManager ()->onUnitDied (this); - } - StaticSound *sound = - static_cast < - const DieSkillType * - >(this->getType ()->getFirstStOfClass (scDie))->getSound (); - if (sound != NULL - && (this->getFactionIndex () == - Unit::game->getWorld ()->getThisFactionIndex () - || (game-> - getWorld ()->showWorldForPlayer (game-> - getWorld - ()->getThisTeamIndex - ()) == true))) - { - SoundRenderer::getInstance ().playFx (sound); - } - } - } - - //stop DamageParticles - stopDamageParticles (false); - - checkItemInVault (&this->ep, this->ep); - //regenerate ep -// ep += type->getEpRegeneration(); -// if(ep > type->getTotalMaxEp(&totalUpgrade)){ -// ep = type->getTotalMaxEp(&totalUpgrade); -// } -// addItemToVault(&this->ep,this->ep); - - if (!isBeingBuilt ()) - { - //regenerate ep upgrade / or boost - checkItemInVault (&this->ep, this->ep); - //regenerate ep - int original_ep = this->ep; - this->ep += type->getTotalMaxEpRegeneration (&totalUpgrade); - if (this->ep > type->getTotalMaxEp (&totalUpgrade)) - { - this->ep = type->getTotalMaxEp (&totalUpgrade); - } - if (original_ep != this->ep) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_EPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault (&this->ep, this->ep); - } - } - } - - int Unit::update2 () - { - progress2++; - return progress2; - } - - bool Unit::computeEp () - { - - if (currSkill == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - //if not enough ep - if (this->ep - currSkill->getEpCost () < 0) - { - return true; - } - - checkItemInVault (&this->ep, this->ep); - int original_ep = this->ep; - //decrease ep - this->ep -= currSkill->getEpCost (); - if (original_ep != this->ep) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, utet_EPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault (&this->ep, this->ep); - - if (getType () == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: getType() == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - if (this->ep > getType ()->getTotalMaxEp (&totalUpgrade)) - { - int original_ep = this->ep; - this->ep = getType ()->getTotalMaxEp (&totalUpgrade); - if (original_ep != this->ep) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_EPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - } - addItemToVault (&this->ep, this->ep); - - return false; - } - - bool Unit::repair () - { - - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - //increase hp - checkItemInVault (&this->hp, this->hp); - int original_hp = this->hp; - if (type->getProductionTime () + 1 == 0) - { - throw - megaglest_runtime_error - ("Detected divide by 0 condition: type->getProductionTime() + 1 == 0"); - } - this->hp += getType ()->getMaxHp () / type->getProductionTime () + 1; - if (this->hp > (getType ()->getTotalMaxHp (&totalUpgrade))) - { - this->hp = getType ()->getTotalMaxHp (&totalUpgrade); - if (original_hp != this->hp) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault (&this->hp, this->hp); - return true; - } - if (original_hp != this->hp) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault (&this->hp, this->hp); - - checkModelStateInfoForNewHpValue (); - - //stop DamageParticles - stopDamageParticles (false); - - return false; - } - -//decrements HP and returns if dead - bool Unit::decHp (int decrementValue) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8095, "this->hp = %d, decrementValue = %d", this->hp, - decrementValue); - addNetworkCRCDecHp (szBuf); - - if (this->hp == 0) - { - return false; - } - - checkItemInVault (&this->hp, this->hp); - int original_hp = this->hp; - this->hp -= decrementValue; - if (original_hp != this->hp) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault (&this->hp, this->hp); - - checkModelStateInfoForNewHpValue (); - - if (type == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - //startDamageParticles - startDamageParticles (); - - //stop DamageParticles on death - if (this->hp <= 0) - { - setAlive (false); - this->hp = 0; - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - addItemToVault (&this->hp, this->hp); - - checkModelStateInfoForNewHpValue (); - - stopDamageParticles (true); - return true; - } - return false; - } - - string Unit::getDescExtension (bool translatedValue) const - { - Lang & lang = Lang::getInstance (); - string str = "\n"; - - if (commands.empty () == false && commands.size () > 1) - { - Commands::const_iterator it = commands.begin (); - for (unsigned int i = 0; - i < min ((size_t) maxQueuedCommandDisplayCount, - commands.size ()); ++i) - { - const CommandType *ct = (*it)->getCommandType (); - if (i == 0) - { - str += "\n" + lang.getString ("OrdersOnQueue") + ": "; - } - str += - "\n#" + intToStr (i + 1) + " " + ct->getName (translatedValue); - ++it; - } - } - - return str; - } - - string Unit::getDesc (bool translatedValue) const - { - - Lang & lang = Lang::getInstance (); - - //hp - string str = "\n"; - - //maxUnitCount - if (type->getMaxUnitCount () > 0) - { - str += - lang.getString ("MaxUnitCount") + ": " + - intToStr (faction->getCountForMaxUnitCount (type)) + "/" + - intToStr (type->getMaxUnitCount ()); - } - - str += - "\n" + lang.getString ("Hp") + ": " + intToStr (hp) + "/" + - intToStr (type->getTotalMaxHp (&totalUpgrade)); - if (type->getHpRegeneration () != 0 - || totalUpgrade.getMaxHpRegeneration () != 0) - { - str += - " (" + lang.getString ("Regeneration") + ": " + - intToStr (type->getHpRegeneration ()); - if (totalUpgrade.getMaxHpRegeneration () != 0) - { - str += "+" + intToStr (totalUpgrade.getMaxHpRegeneration ()); - } - str += ")"; - } - - //ep - if (getType ()->getMaxEp () != 0) - { - str += - "\n" + lang.getString ("Ep") + ": " + intToStr (ep) + "/" + - intToStr (type->getTotalMaxEp (&totalUpgrade)); - } - if (type->getEpRegeneration () != 0 - || totalUpgrade.getMaxEpRegeneration () != 0) - { - str += - " (" + lang.getString ("Regeneration") + ": " + - intToStr (type->getEpRegeneration ()); - if (totalUpgrade.getMaxEpRegeneration () != 0) - { - str += "+" + intToStr (totalUpgrade.getMaxEpRegeneration ()); - } - str += ")"; - } - - //armor - str += - "\n" + lang.getString ("Armor") + ": " + - intToStr (getType ()->getArmor ()); - if (totalUpgrade.getArmor () != 0) - { - str += "+" + intToStr (totalUpgrade.getArmor ()); - } - str += - " (" + getType ()->getArmorType ()->getName (translatedValue) + ")"; - - //sight - str += - "\n" + lang.getString ("Sight") + ": " + - intToStr (getType ()->getSight ()); - if (totalUpgrade.getSight () != 0) - { - str += "+" + intToStr (totalUpgrade.getSight ()); - } - - //kills - const Level *nextLevel = getNextLevel (); - if (enemyKills > 0 || nextLevel != NULL) - { - str += "\n" + lang.getString ("Kills") + ": " + intToStr (enemyKills); - if (nextLevel != NULL) - { - str += - " (" + nextLevel->getName (translatedValue) + ": " + - intToStr (nextLevel->getKills ()) + ")"; - } - } - - //str+= "\nskl: "+scToStr(currSkill->getClass()); - - //load - if (loadCount != 0) - { - str += - "\n" + lang.getString ("Load") + ": " + intToStr (loadCount) + - " " + loadType->getName (translatedValue); - } - - //consumable production - for (int i = 0; i < getType ()->getCostCount (); ++i) - { - const Resource *r = getType ()->getCost (i); - if (r->getType ()->getClass () == rcConsumable) - { - str += "\n"; - str += - r->getAmount () < - 0 ? lang.getString ("Produce") + - ": " : lang.getString ("Consume") + ": "; - str += - intToStr (abs (r->getAmount ())) + " " + - r->getType ()->getName (translatedValue); - } - } - - //command info - if (commands.empty () == false) - { - str += - "\n" + - commands.front ()->getCommandType ()->getName (translatedValue); - if (commands.size () > 1) - { - str += - "\n" + lang.getString ("OrdersOnQueue") + ": " + - intToStr (commands.size ()); - } - } - else - { - //can store - if (getType ()->getStoredResourceCount () > 0) - { - for (int i = 0; i < getType ()->getStoredResourceCount (); ++i) - { - const Resource *r = getType ()->getStoredResource (i); - str += "\n" + lang.getString ("Store") + ": "; - str += - intToStr (r->getAmount ()) + " " + - r->getType ()->getName (translatedValue); - } - } - } - - return str; - } - - void Unit::applyUpgrade (const UpgradeType * upgradeType) - { - if (upgradeType == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: upgradeType == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - if (upgradeType->isAffected (type)) - { - totalUpgrade.sum (upgradeType, this); - - checkItemInVault (&this->hp, this->hp); - int original_hp = this->hp; - this->hp += upgradeType->getMaxHp (); - this->hp = max (0, this->hp); - if (original_hp != this->hp) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault (&this->hp, this->hp); - - checkModelStateInfoForNewHpValue (); - } - } - - void Unit::computeTotalUpgrade () - { - faction->getUpgradeManager ()->computeTotalUpgrade (this, - &totalUpgrade); - } - - void Unit::incKills (int team) - { - ++kills; - if (team != this->getTeam ()) - { - ++enemyKills; - } - - checkUnitLevel (); - } - - void Unit::checkUnitLevel () - { - const Level *nextLevel = getNextLevel (); - if (nextLevel != NULL && this->enemyKills >= nextLevel->getKills ()) - { - this->level = nextLevel; - - int maxHp = this->totalUpgrade.getMaxHp (); - totalUpgrade.incLevel (type); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_LevelChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - - checkItemInVault (&this->hp, this->hp); - int original_hp = this->hp; - this->hp += totalUpgrade.getMaxHp () - maxHp; - if (original_hp != this->hp) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault (&this->hp, this->hp); - - checkModelStateInfoForNewHpValue (); - } - } - - void Unit::morphAttackBoosts (Unit * unit) - { - // Remove any units that were previously in range - if (currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.empty () == false - && currentAttackBoostOriginatorEffect.skillType != NULL) - { - for (int i = - (int)currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.size () - 1; i >= 0; --i) - { - // Remove attack boost upgrades from unit - - int findUnitId = - currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; - Unit *affectedUnit = game->getWorld ()->findUnitById (findUnitId); - if (affectedUnit != NULL - && affectedUnit->getId () == unit->getId ()) - { - affectedUnit->deapplyAttackBoost - (currentAttackBoostOriginatorEffect.skillType-> - getAttackBoost (), this); - - currentAttackBoostOriginatorEffect. - currentAttackBoostUnits.erase - (currentAttackBoostOriginatorEffect.currentAttackBoostUnits. - begin () + i); - } - - //printf("- #1 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); - } - } - } - - bool Unit::morph (const MorphCommandType * mct, int frameIndex) - { - - if (mct == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: mct == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - const UnitType *morphUnitType = mct->getMorphUnit (); - - if (morphUnitType == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: morphUnitType == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - Field morphUnitField = fLand; - if (morphUnitType->getField (fAir)) - { - morphUnitField = fAir; - } - if (morphUnitType->getField (fLand)) - { - morphUnitField = fLand; - } - - map->clearUnitCells (this, pos, false); - if (map->canMorph (pos, this, morphUnitType)) - { - map->clearUnitCells (this, pos, true); - faction->deApplyStaticCosts (type, mct); - - //printf("Now unapply attack-boost for unit [%d - %s]\n",this->getId(),this->getType()->getName().c_str()); - // De apply attack boosts for morphed unit - for (int i = (int)currentAttackBoostEffects.size () - 1; i >= 0; --i) - { - UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; - if (effect != NULL) - { - Unit *sourceUnit = - game->getWorld ()->findUnitById (effect-> - getSource ()->getId ()); - if (sourceUnit == NULL) - { - throw megaglest_runtime_error ("sourceUnit == NULL"); - } - sourceUnit->morphAttackBoosts (this); - } - } - - //stopDamageParticles(true); - cleanupAllParticlesystems (); - - checkItemInVault (&this->hp, this->hp); - int original_hp = this->hp; - this->hp += morphUnitType->getMaxHp () - type->getMaxHp (); - if (original_hp != this->hp) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault (&this->hp, this->hp); - - checkModelStateInfoForNewHpValue (); - - this->preMorph_type = this->type; - this->setType (morphUnitType); - Field original_field = this->currField; - this->currField = morphUnitField; - computeTotalUpgrade (); - map->putUnitCells (this, this->pos, false, frameIndex < 0); - - this->faction->applyDiscount (morphUnitType, mct->getDiscount ()); - // add new storage - this->faction->addStore (this->type); - // remove former storage - this->faction->removeStore (this->preMorph_type); - this->faction->applyStaticProduction (morphUnitType, mct); - - this->level = NULL; - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_LevelChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - checkUnitLevel (); - - if (original_field != this->currField) - { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager ()->onUnitTriggerEvent (this, - utet_FieldChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - - return true; - } - else - { - return false; - } - } - - -// ==================== PRIVATE ==================== - - float Unit::computeHeight (const Vec2i & pos) const - { - //printf("CRASHING FOR UNIT: %d alive = %d\n",this->getId(),this->isAlive()); - //printf("[%s]\n",this->getType()->getName().c_str()); - if (map->isInside (pos) == false - || map->isInsideSurface (map->toSurfCoords (pos)) == false) - { - //printf("CRASHING FOR UNIT: %d [%s] alive = %d\n",this->getId(),this->getType()->getName().c_str(),this->isAlive()); - //abort(); - throw megaglest_runtime_error ("#7 Invalid path position = " + - pos.getString ()); - } - - float height = map->getCell (pos)->getHeight (); - - if (currField == fAir) - { - float airHeight = game->getWorld ()->getTileset ()->getAirHeight (); - airHeight = truncateDecimal < float >(airHeight, 6); - - height += airHeight; - height = truncateDecimal < float >(height, 6); - - Unit *unit = map->getCell (pos)->getUnit (fLand); - if (unit != NULL && unit->getType ()->getHeight () > airHeight) - { - height += - (std::min ((float) unit->getType ()->getHeight (), - Tileset::standardAirHeight * 3) - airHeight); - height = truncateDecimal < float >(height, 6); - } - else - { - SurfaceCell *sc = map->getSurfaceCell (map->toSurfCoords (pos)); - if (sc != NULL && sc->getObject () != NULL - && sc->getObject ()->getType () != NULL) - { - if (sc->getObject ()->getType ()->getHeight () > airHeight) - { - height += - (std::min ((float) sc->getObject ()->getType ()->getHeight (), - Tileset::standardAirHeight * 3) - airHeight); - height = truncateDecimal < float >(height, 6); - } - } - } - } - - return height; - } - - void Unit::AnimCycleStarts () - { - // we need to queue timed particles if progress starts - queueTimedParticles (currSkill->unitParticleSystemTypes); - } - - void Unit::updateTarget () - { - Unit *target = targetRef.getUnit (); - if (target != NULL) - { - - //update target pos - targetPos = target->getCellPos (); - Vec2i relPos = targetPos - pos; - Vec2f relPosf = Vec2f ((float) relPos.x, (float) relPos.y); -#ifdef USE_STREFLOP - targetRotation = - radToDeg (streflop::atan2 - (static_cast < streflop::Simple > (relPosf.x), - static_cast < streflop::Simple > (relPosf.y))); -#else - targetRotation = radToDeg (atan2 (relPosf.x, relPosf.y)); -#endif - targetVec = target->getCurrVectorAsTarget (); - } - } - - void Unit::clearCommands () - { - - this->setCurrentUnitTitle (""); - this->unitPath->clear (); - while (commands.empty () == false) - { - undoCommand (commands.back ()); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - - delete commands.back (); - commands.pop_back (); - - safeMutex.ReleaseLock (); - } - changedActiveCommand = false; - } - - void Unit::deleteQueuedCommand (Command * command) - { - if (getCurrCommand () == command) - { - this->setCurrentUnitTitle (""); - this->unitPath->clear (); - } - undoCommand (command); - delete command; - } - - - std::pair < CommandResult, string > Unit::checkCommand (Command * command) const - { - std::pair < CommandResult, string > result (crSuccess, ""); - - if (command == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - //if not operative or has not command type => fail - if (isOperative () == false || - command->getUnit () == this || - getType ()->hasCommandType (command->getCommandType ()) == false || - (ignoreCheckCommand == false - && this->getFaction ()->reqsOk (command->getCommandType ()) == - false)) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d] isOperative() = %d, command->getUnit() = %p, getType()->hasCommandType(command->getCommandType()) = %d, this->getFaction()->reqsOk(command->getCommandType()) = %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, isOperative (), - command->getUnit (), - getType ()-> - hasCommandType (command->getCommandType - ()), - this->getFaction ()-> - reqsOk (command->getCommandType ())); - - // Allow self healing if able to heal own unit type - if (command->getUnit () == this && - command->getCommandType ()->getClass () == ccRepair && - this->getType ()->getFirstRepairCommand (this->getType ()) != - NULL) - { - - } - else - { - //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); - - result.first = crFailUndefined; - return result; - } - } - - //if pos is not inside the world (if comand has not a pos, pos is (0, 0) and is inside world - if (map->isInside (command->getPos ()) == false) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); - - result.first = crFailUndefined; - return result; - } - - //check produced - if (command->getCommandType () == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - const ProducibleType *produced = - command->getCommandType ()->getProduced (); - if (produced != NULL) - { - if (ignoreCheckCommand == false - && faction->reqsOk (produced) == false) - { - //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); - //printf("To produce this unit you need:\n%s\n",produced->getUnitAndUpgradeReqDesc().c_str()); - result.first = crFailReqs; - - Lang & lang = Lang::getInstance (); - result.second = - " - " + lang.getString ("Reqs") + " : " + - produced->getUnitAndUpgradeReqDesc (false, - this->showTranslatedTechTree - ()); - return result; - } - - if (ignoreCheckCommand == false && - faction->checkCosts (produced, - command->getCommandType ()) == false) - { - //printf("To produce this unit you need:\n%s\n",produced->getResourceReqDesc().c_str()); - //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); - result.first = crFailRes; - Lang & lang = Lang::getInstance (); - result.second = - " - " + lang.getString ("Reqs") + " : " + - produced->getResourceReqDesc (false, - this->showTranslatedTechTree ()); - return result; - } - } - - //build command specific, check resources and requirements for building - if (command->getCommandType ()->getClass () == ccBuild) - { - const UnitType *builtUnit = command->getUnitType (); - - if (builtUnit == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: builtUnit == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - if (faction->reqsOk (builtUnit) == false) - { - //printf("To build this unit you need:\n%s\n",builtUnit->getUnitAndUpgradeReqDesc().c_str()); - //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); - result.first = crFailReqs; - Lang & lang = Lang::getInstance (); - result.second = - " - " + lang.getString ("Reqs") + " : " + - builtUnit->getUnitAndUpgradeReqDesc (false, - this->showTranslatedTechTree - ()); - return result; - } - if (faction->checkCosts (builtUnit, NULL) == false) - { - //printf("To build this unit you need:\n%s\n",builtUnit->getResourceReqDesc().c_str()); - //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); - result.first = crFailRes; - Lang & lang = Lang::getInstance (); - result.second = - " - " + lang.getString ("Reqs") + " : " + - builtUnit->getResourceReqDesc (false, - this->showTranslatedTechTree ()); - return result; - } - } - //upgrade command specific, check that upgrade is not upgraded - else if (command->getCommandType ()->getClass () == ccUpgrade) - { - const UpgradeCommandType *uct = - static_cast < - const UpgradeCommandType * >(command->getCommandType ()); - - if (uct == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - if (faction-> - getUpgradeManager ()->isUpgradingOrUpgraded (uct-> - getProducedUpgrade - ())) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugLUA).enabled) - SystemFlags::OutputDebug (SystemFlags::debugLUA, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__); - //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); - result.first = crFailUndefined; - return result; - } - } - - return result; - } - - void Unit::applyCommand (Command * command) - { - if (command == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - else if (command->getCommandType () == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - //check produced - const ProducibleType *produced = - command->getCommandType ()->getProduced (); - if (produced != NULL) - { - faction->applyCosts (produced, command->getCommandType ()); - } - - //build command specific - if (command->getCommandType ()->getClass () == ccBuild) - { - faction->applyCosts (command->getUnitType (), - command->getCommandType ()); - } - //upgrade command specific - else if (command->getCommandType ()->getClass () == ccUpgrade) - { - const UpgradeCommandType *uct = - static_cast < - const UpgradeCommandType * >(command->getCommandType ()); - - if (uct == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - faction->startUpgrade (uct->getProducedUpgrade ()); - } - } - - CommandResult Unit::undoCommand (Command * command) - { - - if (command == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - else if (command->getCommandType () == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - if (getCurrCommand () == command - && command->getCommandType ()->getClass () == ccMorph - && this->currSkill->getClass () == scMorph) - { - // clear cells of morphed unit and set those of current unit! - map->clearUnitCells (this, this->getPos ()); - map->putUnitCells (this, this->getPos (), true); - } - //return cost - const ProducibleType *produced = - command->getCommandType ()->getProduced (); - if (produced != NULL) - { - faction->deApplyCosts (produced, command->getCommandType ()); - } - - //return building cost if not already building it or dead - if (command->getCommandType ()->getClass () == ccBuild) - { - if (currSkill->getClass () != scBuild - && currSkill->getClass () != scDie) - { - faction->deApplyCosts (command->getUnitType (), - command->getCommandType ()); - } - } - - //upgrade command cancel from list - if (command->getCommandType ()->getClass () == ccUpgrade) - { - const UpgradeCommandType *uct = - static_cast < - const UpgradeCommandType * >(command->getCommandType ()); - if (uct == NULL) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, this->toString ().c_str ()); - throw megaglest_runtime_error (szBuf); - } - - faction->cancelUpgrade (uct->getProducedUpgrade ()); - } - - retryCurrCommandCount = 0; - this->setCurrentUnitTitle (""); - - return crSuccess; - } - - void Unit::stopDamageParticles (bool force) - { - if (force == true || (hp > type->getTotalMaxHp (&totalUpgrade) / 2)) - { - //printf("Checking to stop damageparticles for unit [%s - %d] hp = %d\n",this->getType()->getName().c_str(),this->getId(),hp); - - if (Renderer:: - getInstance ().validateParticleSystemStillExists (this->fire, - rsGame) == - false) - { - this->fire = NULL; - } - - // stop fire - if (this->fire != NULL) - { - this->fire->fade (); - this->fire = NULL; - } - // stop additional particles - - - if (smokeParticleSystems.empty () == false) - { - //printf("Checking to stop smokeparticles for unit [%s - %d] hp = %d\n",this->getType()->getName().c_str(),this->getId(),hp); - - for (int i = (int)smokeParticleSystems.size () - 1; i >= 0; --i) - { - UnitParticleSystem *ps = smokeParticleSystems[i]; - if (Renderer:: - getInstance ().validateParticleSystemStillExists (ps, - rsGame) == - true) - { - ps->fade (); - } - smokeParticleSystems.pop_back (); - } - } - - if (damageParticleSystems.empty () == false) - { - //printf("Checking to stop damageparticles for unit [%s - %d] hp = %d\n",this->getType()->getName().c_str(),this->getId(),hp); - - for (int i = (int)damageParticleSystems.size () - 1; i >= 0; --i) - { - UnitParticleSystem *ps = damageParticleSystems[i]; - UnitParticleSystemType *pst = NULL; - int foundParticleIndexType = -2; - if (Renderer:: - getInstance ().validateParticleSystemStillExists (ps, - rsGame) == - true) - { - for (std::map < int, UnitParticleSystem * >::iterator iterMap = - damageParticleSystemsInUse.begin (); - iterMap != damageParticleSystemsInUse.end (); ++iterMap) - { - if (iterMap->second == ps) - { - foundParticleIndexType = iterMap->first; - if (foundParticleIndexType >= 0) - { - pst = - type->damageParticleSystemTypes[foundParticleIndexType]; - break; - } - } - } - } - if (force == true - || (pst != NULL && pst->getMinmaxEnabled () == false)) - { - damageParticleSystemsInUse.erase (foundParticleIndexType); - if (Renderer:: - getInstance ().validateParticleSystemStillExists (ps, - rsGame) == - true) - { - ps->fade (); - } - damageParticleSystems.pop_back (); - } - } - } - } - - checkCustomizedParticleTriggers (force); - } - - void Unit:: - checkCustomizedUnitParticleListTriggers (const UnitParticleSystemTypes & - unitParticleSystemTypesList, - bool applySkillChangeParticles) - { - if (showUnitParticles == true) - { - vector < ParticleSystemTypeInterface * >systemTypesInUse; - - if (unitParticleSystems.empty () == false) - { - for (int index = (int)unitParticleSystems.size () - 1; index >= 0; - index--) - { - UnitParticleSystem *ps = unitParticleSystems[index]; - if (ps != NULL) - { - if (Renderer:: - getInstance ().validateParticleSystemStillExists (ps, - rsGame) == - true) - { - - bool stopParticle = false; - if ((ps->getParticleType () != NULL && - ps->getParticleType ()->getMinmaxEnabled ())) - { - - if (ps->getParticleType () != NULL) - { - if (ps->getParticleType ()->getMinmaxIsPercent () == - false) - { - if (hp < ps->getParticleType ()->getMinHp () - || hp > ps->getParticleType ()->getMaxHp ()) - { - stopParticle = true; - - //printf("STOP Particle line: %d\n",__LINE__); - } - } - else - { - int hpPercent = - (hp / type->getTotalMaxHp (&totalUpgrade) * 100); - if (hpPercent < ps->getParticleType ()->getMinHp () - || hpPercent > ps->getParticleType ()->getMaxHp ()) - { - stopParticle = true; - - //printf("STOP Particle line: %d\n",__LINE__); - } - } - } - - if (stopParticle == true) - { - ps->fade (); - unitParticleSystems.erase (unitParticleSystems.begin () + - index); - } - } - - if (ps->getParticleType () != NULL && stopParticle == false) - { - systemTypesInUse.push_back (ps->getParticleType ()); - } - } - } - } - } - - //printf("Check Particle start line: %d size: %d\n",__LINE__,(int)unitParticleSystemTypesList.size()); - - if (unitParticleSystemTypesList.empty () == false) - { - - //for(unsigned int index = 0; index < unitParticleSystemTypesList.size(); ++index) { - for (UnitParticleSystemTypes::const_iterator iterParticleType = - unitParticleSystemTypesList.begin (); - iterParticleType != unitParticleSystemTypesList.end (); - ++iterParticleType) - { - UnitParticleSystemType *pst = *iterParticleType; - - vector < ParticleSystemTypeInterface * >::iterator iterFind = - std::find (systemTypesInUse.begin (), systemTypesInUse.end (), - pst); - - //printf("Check Particle line: %d isenabled: %d already in use: %d\n",__LINE__,pst->getMinmaxEnabled(),(iterFind == systemTypesInUse.end())); - - bool showParticle = applySkillChangeParticles; - if (pst->getMinmaxEnabled () == true) - { - - //printf("Check Particle line: %d isenabled: %d already in use: %d\n",__LINE__,pst->getMinmaxEnabled(),(iterFind != systemTypesInUse.end())); - - showParticle = false; - if (iterFind == systemTypesInUse.end ()) - { - if (pst->getMinmaxIsPercent () == false) - { - if (hp >= pst->getMinHp () && hp <= pst->getMaxHp ()) - { - showParticle = true; - - //printf("START Particle line: %d\n",__LINE__); - } - } - else - { - int hpPercent = - (hp / type->getTotalMaxHp (&totalUpgrade) * 100); - if (hpPercent >= pst->getMinHp () - && hpPercent <= pst->getMaxHp ()) - { - showParticle = true; - - //printf("START Particle line: %d\n",__LINE__); - } - } - } - } - if (showParticle == true) - { - if (pst->getStartTime () == 0.0) - { - UnitParticleSystem *ups = new UnitParticleSystem (200); - ups->setParticleOwner (this); - ups->setParticleType (pst); - - pst->setValues (ups); - ups->setPos (getCurrVectorForParticlesystems ()); - ups->setRotation (getRotation ()); - setMeshPosInParticleSystem (ups); - if (getFaction ()->getTexture ()) - { - ups->setFactionColor (getFaction ()-> - getTexture ()->getPixmapConst ()-> - getPixel3f (0, 0)); - } - unitParticleSystems.push_back (ups); - Renderer::getInstance ().manageParticleSystem (ups, rsGame); - } - else - { - // do nothing, timed particles are handled below in queueTimedParticles() - } - } - } - } - } - } - - void Unit:: - queueTimedParticles (const UnitParticleSystemTypes & - unitParticleSystemTypesList) - { - if (showUnitParticles == true) - { - for (UnitParticleSystemTypes::const_iterator iterParticleType = - unitParticleSystemTypesList.begin (); - iterParticleType != unitParticleSystemTypesList.end (); - ++iterParticleType) - { - UnitParticleSystemType *pst = *iterParticleType; - if (pst->getMinmaxEnabled () == false) - { - if (pst->getStartTime () != 0.0) - { - queuedUnitParticleSystemTypes.push_back (pst); - } - } - } - } - } - - void Unit::setMeshPosInParticleSystem (UnitParticleSystem * ups) - { - if (ups->getMeshName () != "") - { - string meshName = ups->getMeshName (); - Model *model = getCurrentModelPtr (); - - // as it can happen that anim progress is a bit out of range we correct it to get something valid for the particle positions. - float currentAnimProgress = getAnimProgressAsFloat (); - if (currentAnimProgress > 1.f || currentAnimProgress < 0.f) - { - currentAnimProgress = 0.f; - } - model->updateInterpolationVertices (currentAnimProgress, isAlive () - && !isAnimProgressBound ()); - - bool foundMesh = false; - for (unsigned int i = 0; i < model->getMeshCount (); i++) - { - //printf("meshName=%s\n",unitModel->getMesh(i)->getName().c_str()); - if (model->getMesh (i)->getName () == meshName) - { - const InterpolationData *data = - model->getMesh (i)->getInterpolationData (); - const Vec3f *verticepos = data->getVertices (); - ups->setMeshPos (Vec3f - (verticepos->x, verticepos->y, verticepos->z)); - foundMesh = true; - break; - } - } - if (foundMesh == false) - { - string meshesFound = model->getMesh (0)->getName (); - for (unsigned i = 1; i < model->getMeshCount (); i++) - { - meshesFound += ", " + model->getMesh (i)->getName (); - } - - string errorString = - "Warning: Particle system is trying to find mesh '" + meshName + - "', but just found:\n'" + meshesFound + "' in file:\n'" + - model->getFileName () + "'\n"; - //throw megaglest_runtime_error(errorString); - printf ("%s", errorString.c_str ()); - } - } - } - - void Unit::checkCustomizedUnitParticleTriggers () - { - if (currSkill != NULL) - { - checkCustomizedUnitParticleListTriggers - (currSkill->unitParticleSystemTypes, false); - } - } - - void Unit::checkCustomizedParticleTriggers (bool force) - { - // - // Now check if we have special pre-exisitng hp triggered particles and - // end those that should no longer display - // - // end s particles - if (damageParticleSystems.empty () == false) - { - for (int i = (int)damageParticleSystems.size () - 1; i >= 0; --i) - { - UnitParticleSystem *ps = damageParticleSystems[i]; - UnitParticleSystemType *pst = NULL; - int foundParticleIndexType = -2; - if (Renderer:: - getInstance ().validateParticleSystemStillExists (ps, - rsGame) == - true) - { - for (std::map < int, UnitParticleSystem * >::iterator iterMap = - damageParticleSystemsInUse.begin (); - iterMap != damageParticleSystemsInUse.end (); ++iterMap) - { - if (iterMap->second == ps) - { - foundParticleIndexType = iterMap->first; - if (foundParticleIndexType >= 0) - { - pst = - type->damageParticleSystemTypes[foundParticleIndexType]; - break; - } - } - } - } - - if (force == true - || (pst != NULL && pst->getMinmaxEnabled () == true)) - { - bool stopParticle = force; - if (force == false) - { - if (pst->getMinmaxIsPercent () == false) - { - if (hp < pst->getMinHp () || hp > pst->getMaxHp ()) - { - stopParticle = true; - } - } - else - { - int hpPercent = - (hp / type->getTotalMaxHp (&totalUpgrade) * 100); - if (hpPercent < pst->getMinHp () - || hpPercent > pst->getMaxHp ()) - { - stopParticle = true; - } - } - } - - //printf("CHECKING to STOP customized particle trigger by HP [%d to %d percentbased = %d] current hp = %d stopParticle = %d\n",pst->getMinHp(),pst->getMaxHp(),pst->getMinmaxIsPercent(),hp,stopParticle); - - if (stopParticle == true) - { - //printf("STOPPING customized particle trigger by HP [%d to %d] current hp = %d\n",pst->getMinHp(),pst->getMaxHp(),hp); - - damageParticleSystemsInUse.erase (foundParticleIndexType); - if (Renderer:: - getInstance ().validateParticleSystemStillExists (ps, - rsGame) == - true) - { - ps->fade (); - } - damageParticleSystems.pop_back (); - } - } - } - } - - // - // Now check if we have new special hp triggered particles to display - // - //start additional particles - if (showUnitParticles && - type->damageParticleSystemTypes.empty () == false && - force == false && alive == true) - { - for (unsigned int i = 0; i < type->damageParticleSystemTypes.size (); - ++i) - { - UnitParticleSystemType *pst = type->damageParticleSystemTypes[i]; - - if (pst->getMinmaxEnabled () == true - && damageParticleSystemsInUse.find (i) == - damageParticleSystemsInUse.end ()) - { - bool showParticle = false; - if (pst->getMinmaxIsPercent () == false) - { - if (hp >= pst->getMinHp () && hp <= pst->getMaxHp ()) - { - showParticle = true; - } - } - else - { - int hpPercent = - (hp / type->getTotalMaxHp (&totalUpgrade) * 100); - if (hpPercent >= pst->getMinHp () - && hpPercent <= pst->getMaxHp ()) - { - showParticle = true; - } - } - - //printf("CHECKING to START customized particle trigger by HP [%d to %d percentbased = %d] current hp = %d showParticle = %d\n",pst->getMinHp(),pst->getMaxHp(),pst->getMinmaxIsPercent(),hp,showParticle); - - if (showParticle == true) - { - //printf("STARTING customized particle trigger by HP [%d to %d] current hp = %d\n",pst->getMinHp(),pst->getMaxHp(),hp); - - UnitParticleSystem *ups = new UnitParticleSystem (200); - ups->setParticleOwner (this); - ups->setParticleType (pst); - - pst->setValues (ups); - ups->setPos (getCurrVectorForParticlesystems ()); - ups->setRotation (getRotation ()); - setMeshPosInParticleSystem (ups); - if (getFaction ()->getTexture ()) - { - ups->setFactionColor (getFaction ()-> - getTexture ()->getPixmapConst ()-> - getPixel3f (0, 0)); - } - damageParticleSystems.push_back (ups); - damageParticleSystemsInUse[i] = ups; - Renderer::getInstance ().manageParticleSystem (ups, rsGame); - } - } - } - } - - checkCustomizedUnitParticleTriggers (); - } - - void Unit::startDamageParticles () - { - if (hp < type->getTotalMaxHp (&totalUpgrade) / 2 && hp > 0 - && alive == true) - { - //start additional particles - if (showUnitParticles && - type->damageParticleSystemTypes.empty () == false) - { - for (unsigned int i = 0; - i < type->damageParticleSystemTypes.size (); ++i) - { - UnitParticleSystemType *pst = type->damageParticleSystemTypes[i]; - - if (pst->getMinmaxEnabled () == false - && damageParticleSystemsInUse.find (i) == - damageParticleSystemsInUse.end ()) - { - UnitParticleSystem *ups = new UnitParticleSystem (200); - ups->setParticleOwner (this); - ups->setParticleType (pst); - - pst->setValues (ups); - ups->setPos (getCurrVectorForParticlesystems ()); - ups->setRotation (getRotation ()); - setMeshPosInParticleSystem (ups); - if (getFaction ()->getTexture ()) - { - ups->setFactionColor (getFaction ()-> - getTexture ()->getPixmapConst ()-> - getPixel3f (0, 0)); - } - damageParticleSystems.push_back (ups); - damageParticleSystemsInUse[i] = ups; - Renderer::getInstance ().manageParticleSystem (ups, rsGame); - } - } - } - - // start fire - if (type->getProperty (UnitType::pBurnable) && this->fire == NULL) - { - FireParticleSystem *fps = new FireParticleSystem (200); - fps->setParticleOwner (this); - const Game *game = Renderer::getInstance ().getGame (); - fps->setSpeed (2.5f / - game->getWorld ()-> - getUpdateFps (this->getFactionIndex ())); - fps->setPos (getCurrBurnVector ()); - fps->setRadius (type->getSize () / 3.f); - fps->setTexture (CoreData::getInstance ().getFireTexture ()); - fps->setParticleSize (type->getSize () / 3.f); - this->fire = fps; - fireParticleSystems.push_back (fps); - - Renderer::getInstance ().manageParticleSystem (fps, rsGame); - if (showUnitParticles == true) - { - // smoke - UnitParticleSystem *ups = new UnitParticleSystem (400); - ups->setParticleOwner (this); - ups->setColorNoEnergy (Vec4f (0.0f, 0.0f, 0.0f, 0.13f)); - ups->setColor (Vec4f (0.115f, 0.115f, 0.115f, 0.22f)); - ups->setPos (getCurrBurnVector ()); - ups->setRotation (getRotation ()); - setMeshPosInParticleSystem (ups); - ups->setBlendMode (ups->strToBlendMode ("black")); - ups->setOffset (Vec3f (0, 2, 0)); - ups->setDirection (Vec3f (0, 1, -0.2f)); - ups->setRadius (type->getSize () / 3.f); - ups->setShape (::Shared::Graphics::UnitParticleSystem::sLinear); - ups->setTexture (CoreData::getInstance ().getFireTexture ()); - const Game *game = Renderer::getInstance ().getGame (); - ups->setSpeed (2.0f / - game->getWorld ()-> - getUpdateFps (this->getFactionIndex ())); - ups->setGravity (0.0004f); - ups->setEmissionRate (1); - ups->setMaxParticleEnergy (150); - ups->setSizeNoEnergy (type->getSize () * 0.6f); - ups->setParticleSize (type->getSize () * 0.8f); - smokeParticleSystems.push_back (ups); - //damageParticleSystemsInUse[-1] = ups; - Renderer::getInstance ().manageParticleSystem (ups, rsGame); - } - } - } - - checkCustomizedParticleTriggers (false); - } - - void Unit::setMeetingPos (const Vec2i & meetingPos) - { - this->meetingPos = meetingPos; - map->clampPos (this->meetingPos); - - if (map->isInside (this->meetingPos) == false - || map->isInsideSurface (map->toSurfCoords (this->meetingPos)) == - false) - { - throw megaglest_runtime_error ("#8 Invalid path position = " + - this->meetingPos.getString ()); - } - - logSynchData (extractFileFromDirectoryPath (__FILE__).c_str (), - __LINE__); - } - - bool Unit::isMeetingPointSettable () const - { - return (type != NULL ? type->getMeetingPoint () : false); - } - - uint32 Unit::getFrameCount () const - { - uint32 frameCount = 0; - //const Game *game = Renderer::getInstance().getGame(); - if (game != NULL && game->getWorld () != NULL) - { - int frameCountAsInt = game->getWorld ()->getFrameCount (); - if (frameCountAsInt >= 0) - { - frameCount = frameCountAsInt; - } - } - - return frameCount; - } - - void Unit::exploreCells (bool forceRefresh) - { - if (this->isOperative () == true) - { - const Vec2i & newPos = this->getCenteredPos (); - int sightRange = - this->getType ()->getTotalSight (this->getTotalUpgrade ()); - int teamIndex = this->getTeam (); - - if (game == NULL) - { - throw megaglest_runtime_error ("game == NULL"); - } - else if (game->getWorld () == NULL) - { - throw megaglest_runtime_error ("game->getWorld() == NULL"); - } - - // Try the local unit exploration cache - if (!forceRefresh && - cacheExploredCellsKey.first == newPos && - cacheExploredCellsKey.second == sightRange) - { - game->getWorld ()->exploreCells (teamIndex, cacheExploredCells); - } - else - { - // Try the world exploration scan or possible cache - cacheExploredCells = - game->getWorld ()->exploreCells (newPos, sightRange, teamIndex, - this); - - // Cache the result for this unit - cacheExploredCellsKey.first = newPos; - cacheExploredCellsKey.second = sightRange; - } - } - } - - void Unit::logSynchData (string file, int line, string source) - { - logSynchDataCommon (file, line, source, false); - } - void Unit::logSynchDataThreaded (string file, int line, string source) - { - logSynchDataCommon (file, line, source, true); - } - void Unit::logSynchDataCommon (string file, int line, string source, - bool threadedMode) - { - if (SystemFlags:: - getSystemSettingType (SystemFlags::debugWorldSynch).enabled == true) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "FrameCount [%d] Unit = %d [%s][%s] pos = %s, lastPos = %s, targetPos = %s, targetVec = %s, meetingPos = %s, progress [" - MG_I64_SPECIFIER - "], progress2 [%d] random [%d]\nUnit Path [%s]\n", - getFrameCount (), id, getFullName (false).c_str (), - faction->getType ()->getName (false).c_str (), - //getDesc().c_str(), - pos.getString ().c_str (), - lastPos.getString ().c_str (), - targetPos.getString ().c_str (), - targetVec.getString ().c_str (), - meetingPos.getString ().c_str (), -// lastRotation, -// targetRotation, -// rotation, - progress, - progress2, - random.getLastNumber (), - (unitPath != - NULL ? unitPath->toString ().c_str () : "NULL")); - - if (lastSynchDataString != string (szBuf) || - lastFile != file || lastLine != line || lastSource != source) - { - lastSynchDataString = string (szBuf); - lastFile = file; - lastSource = source; - - char szBufDataText[8096] = ""; - snprintf (szBufDataText, 8096, - "----------------------------------- START [FRAME %d UNIT: %d - %s] ------------------------------------------------\n", - getFrameCount (), this->id, - this->getType ()->getName (false).c_str ()); - string logDataText = szBufDataText; - - snprintf (szBufDataText, 8096, "[%s::%d]\n", - extractFileFromDirectoryPath (file).c_str (), line); - logDataText += szBufDataText; - - if (source != "") - { - snprintf (szBufDataText, 8096, "%s ", source.c_str ()); - logDataText += szBufDataText; - } - snprintf (szBufDataText, 8096, "%s\n", szBuf); - logDataText += szBufDataText; - snprintf (szBufDataText, 8096, - "------------------------------------ END [FRAME %d UNIT: %d - %s] ------------------------------------------------\n", - getFrameCount (), this->id, - this->getType ()->getName (false).c_str ()); - logDataText += szBufDataText; -/* - SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"----------------------------------- START [FRAME %d UNIT: %d - %s] ------------------------------------------------\n",getFrameCount(),this->id,this->getType()->getName().c_str()); - SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"[%s::%d]\n",extractFileFromDirectoryPath(file).c_str(),line); - if(source != "") { - SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"%s ",source.c_str()); + void UnitPathBasic::dumpMemoryList() { + printf("===== START report of Unfreed UnitPathBasic pointers =====\n"); + for (std::map < UnitPathBasic *, bool >::iterator iterMap = + UnitPathBasic::mapMemoryList.begin(); + iterMap != UnitPathBasic::mapMemoryList.end(); ++iterMap) { + printf("************** ==> Unfreed UnitPathBasic pointer [%p]\n", + iterMap->first); + + if (Unit::mapMemoryList2.find(iterMap->first) != + Unit::mapMemoryList2.end()) { + printf("Found owner unit id [%d]\n", + Unit::mapMemoryList2[iterMap->first]); + } } - SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"%s\n",szBuf); - SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"------------------------------------ END [FRAME %d UNIT: %d - %s] ------------------------------------------------\n",getFrameCount(),this->id,this->getType()->getName().c_str()); -*/ - if (threadedMode == false) - { - SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, "%s", - logDataText.c_str ()); - } - else - { - this->faction->addWorldSynchThreadedLogList (logDataText); - } - } - } - } - - void Unit::addBadHarvestPos (const Vec2i & value) - { - //Chrono chron; - //chron.start(); - badHarvestPosList[value] = getFrameCount (); - cleanupOldBadHarvestPos (); - } - -//void Unit::removeBadHarvestPos(const Vec2i &value) { -// std::map::iterator iter = badHarvestPosList.find(value); -// if(iter != badHarvestPosList.end()) { -// badHarvestPosList.erase(value); -// } -// cleanupOldBadHarvestPos(); -//} - - void Unit::cleanupOldBadHarvestPos () - { - const unsigned int cleanupInterval = (GameConstants::updateFps * 5); - bool needToCleanup = (getFrameCount () % cleanupInterval == 0); - - //printf("========================> cleanupOldBadHarvestPos() [%d] badHarvestPosList.size [%ld] cleanupInterval [%d] getFrameCount() [%d] needToCleanup [%d]\n",getFrameCount(),badHarvestPosList.size(),cleanupInterval,getFrameCount(),needToCleanup); - - if (needToCleanup == true) - { - //printf("========================> cleanupOldBadHarvestPos() [%d] badHarvestPosList.size [%ld]\n",getFrameCount(),badHarvestPosList.size()); - - std::vector < Vec2i > purgeList; - for (std::map < Vec2i, int >::iterator iter = - badHarvestPosList.begin (); iter != badHarvestPosList.end (); - ++iter) - { - if (getFrameCount () - iter->second >= cleanupInterval) - { - //printf("cleanupOldBadHarvestPos() [%d][%d]\n",getFrameCount(),iter->second); - purgeList.push_back (iter->first); - } - } - - if (purgeList.empty () == false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "[cleaning old bad harvest targets] purgeList.size() [" - MG_SIZE_T_SPECIFIER "]", purgeList.size ()); - logSynchData (extractFileFromDirectoryPath (__FILE__).c_str (), - __LINE__, szBuf); - - for (int i = 0; i < (int) purgeList.size (); ++i) - { - const Vec2i & item = purgeList[i]; - badHarvestPosList.erase (item); - } - } - } - } - - void Unit::setLastHarvestResourceTarget (const Vec2i * pos) - { - if (pos == NULL) - { - lastHarvestResourceTarget.first = Vec2i (0); - //lastHarvestResourceTarget.second = 0; - } - else - { - const Vec2i resourceLocation = *pos; - if (resourceLocation != lastHarvestResourceTarget.first) - { - lastHarvestResourceTarget.first = resourceLocation; - - //Chrono chron; - //chron.start(); - lastHarvestResourceTarget.second = getFrameCount (); - } - else - { - // If we cannot harvest for > 10 seconds tag the position - // as a bad one - const unsigned int addInterval = (GameConstants::updateFps * 5); - if (lastHarvestResourceTarget.second - getFrameCount () >= - addInterval) - { - //printf("-----------------------> setLastHarvestResourceTarget() [%d][%d]\n",getFrameCount(),lastHarvestResourceTarget.second); - addBadHarvestPos (resourceLocation); - } - } - } - } - -//void Unit::addCurrentTargetPathTakenCell(const Vec2i &target,const Vec2i &cell) { -// if(currentTargetPathTaken.first != target) { -// currentTargetPathTaken.second.clear(); -// } -// currentTargetPathTaken.first = target; -// currentTargetPathTaken.second.push_back(cell); -//} - - void Unit::setLastPathfindFailedFrameToCurrentFrame () - { - lastPathfindFailedFrame = getFrameCount (); - } - - bool Unit::isLastPathfindFailedFrameWithinCurrentFrameTolerance () const - { - //static const bool enablePathfinderEnlargeMaxNodes = Config::getInstance().getBool("EnablePathfinderEnlargeMaxNodes","false"); - static const bool enablePathfinderEnlargeMaxNodes = false; - bool result = enablePathfinderEnlargeMaxNodes; - if (enablePathfinderEnlargeMaxNodes) - { - const uint32 MIN_FRAME_ELAPSED_RETRY = 960; - result = - (getFrameCount () - lastPathfindFailedFrame >= - MIN_FRAME_ELAPSED_RETRY); - } - return result; - } - - void Unit::setLastStuckFrameToCurrentFrame () - { - lastStuckFrame = getFrameCount (); - } - - bool Unit::isLastStuckFrameWithinCurrentFrameTolerance (bool evalMode) - { - //const int MIN_FRAME_ELAPSED_RETRY = 300; - const uint32 MAX_BLOCKED_FRAME_THRESHOLD = 25000; - uint32 MIN_FRAME_ELAPSED_RETRY = 6; - if (lastStuckFrame < MAX_BLOCKED_FRAME_THRESHOLD) - { - if (evalMode == true) - { - MIN_FRAME_ELAPSED_RETRY = 4; - } - else - { - MIN_FRAME_ELAPSED_RETRY = - random.randRange (2, 6, intToStr (__LINE__)); - } - } - else - { - if (evalMode == true) - { - MIN_FRAME_ELAPSED_RETRY = 7; - } - else - { - MIN_FRAME_ELAPSED_RETRY = - random.randRange (6, 8, intToStr (__LINE__)); - } - } - bool result (getFrameCount () - lastStuckFrame <= - (MIN_FRAME_ELAPSED_RETRY * 100)); - return result; - } - - Vec2i Unit::getPosWithCellMapSet () const - { - Vec2i cellMapPos = - this->getType ()->getFirstOccupiedCellInCellMap (pos); - return cellMapPos; - } - - string Unit::getUniquePickName () const - { - string result = intToStr (id) + " - " + type->getName (false) + " : "; - result += pos.getString (); - return result; - } - - Vec2i Unit::getPos () - { - Vec2i result; - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - result = this->pos; - safeMutex.ReleaseLock (); - - return result; - } - - void Unit::clearCaches () - { - cachedFow.surfPosAlphaList.clear (); - cachedFowPos = Vec2i (0, 0); - - cacheExploredCells.exploredCellList.clear (); - cacheExploredCells.visibleCellList.clear (); - cacheExploredCellsKey.first = Vec2i (-1, -1); - cacheExploredCellsKey.second = -1; - - if (unitPath != NULL) - { - unitPath->clearCaches (); - } - - lastHarvestedResourcePos = Vec2i (0, 0); - } - - bool Unit::showTranslatedTechTree () const - { - return (this->game != - NULL ? this->game->showTranslatedTechTree () : true); - } - - string Unit::getNetworkCRCDecHpList () const - { - string result = ""; - if (networkCRCDecHpList.empty () == false) - { - for (unsigned int index = 0; index < networkCRCDecHpList.size (); - ++index) - { - result += networkCRCDecHpList[index] + " "; - } - } - return result; - } - std::string Unit::toString (bool crcMode) const - { - std::string result = ""; - - result += "id = " + intToStr (this->id); - if (this->type != NULL) - { - result += - " name [" + this->type->getName (false) + "][" + - intToStr (this->type->getId ()) + "]"; - } - - if (this->faction != NULL) - { - result += - "\nFactionIndex = " + intToStr (this->faction->getIndex ()) + "\n"; - result += - "teamIndex = " + intToStr (this->faction->getTeam ()) + "\n"; - result += - "startLocationIndex = " + - intToStr (this->faction->getStartLocationIndex ()) + "\n"; - if (crcMode == false) - { - result += - "thisFaction = " + intToStr (this->faction->getThisFaction ()) + - "\n"; - result += - "control = " + intToStr (this->faction->getControlType ()) + "\n"; - } - if (this->faction->getType () != NULL) - { - result += - "factionName = " + this->faction->getType ()->getName (false) + - "\n"; - } - } - - result += " hp = " + intToStr (this->hp); - result += " ep = " + intToStr (this->ep); - result += " loadCount = " + intToStr (this->loadCount); - result += " deadCount = " + intToStr (this->deadCount); - result += " progress = " + intToStr (this->progress); - result += "\n"; - result += "networkCRCLogInfo = " + networkCRCLogInfo; - result += "\n"; - if (crcMode == false) - { - result += " lastAnimProgress = " + intToStr (this->lastAnimProgress); - result += " animProgress = " + intToStr (this->animProgress); - result += " highlight = " + floatToStr (this->highlight, 6); - } - result += " progress2 = " + intToStr (this->progress2); - result += " kills = " + intToStr (this->kills); - result += " enemyKills = " + intToStr (this->enemyKills); - result += "\n"; - - // WARNING!!! Don't access the Unit pointer in this->targetRef in this method or it causes - // a stack overflow - if (this->targetRef.getUnitId () >= 0) - { - //result += " targetRef = " + this->targetRef.getUnit()->toString(); - result += - " targetRef = " + intToStr (this->targetRef.getUnitId ()) + - " - factionIndex = " + - intToStr (this->targetRef.getUnitFaction ()->getIndex ()); - } - - result += " currField = " + intToStr (this->currField); - result += " targetField = " + intToStr (this->targetField); - if (level != NULL) - { - result += " level = " + level->getName (); - } - result += "\n"; - result += " pos = " + pos.getString (); - result += " lastPos = " + lastPos.getString (); - result += "\n"; - result += " targetPos = " + targetPos.getString (); - result += " targetVec = " + targetVec.getString (); - result += " meetingPos = " + meetingPos.getString (); - result += "\n"; - - if (crcMode == false) - { - result += " lastRotation = " + floatToStr (this->lastRotation, 6); - result += " targetRotation = " + floatToStr (this->targetRotation, 6); - result += " rotation = " + floatToStr (this->rotation, 6); - } - - if (loadType != NULL) - { - result += " loadType = " + loadType->getName (); - } - - if (currSkill != NULL) - { - result += " currSkill = " + currSkill->getName (); - } - result += "\n"; - - result += " toBeUndertaken = " + intToStr (this->toBeUndertaken); - result += " alive = " + intToStr (this->alive); - result += " showUnitParticles = " + intToStr (this->showUnitParticles); - - result += " totalUpgrade = " + totalUpgrade.toString (); - result += " " + this->unitPath->toString () + "\n"; - result += "\n"; - - result += "Command count = " + intToStr (commands.size ()) + "\n"; - - int cmdIdx = 0; - for (Commands::const_iterator iterList = commands.begin (); - iterList != commands.end (); ++iterList) - { - result += " index = " + intToStr (cmdIdx) + " "; - const Command *cmd = *iterList; - if (cmd != NULL) - { - result += cmd->toString (false) + "\n"; - } - cmdIdx++; - } - result += "\n"; - -// int obsIdx = 0; -// for(Observers::const_iterator iterList = observers.begin(); iterList != observers.end(); ++iterList) { -// const UnitObserver *observer = *iterList; -// if(observer != NULL) { -// } -// -// obsIdx++; -// } - - result += "\n"; - - result += "modelFacing = " + intToStr (modelFacing.asInt ()) + "\n"; - - result += - "retryCurrCommandCount = " + intToStr (retryCurrCommandCount) + "\n"; - - result += "screenPos = " + screenPos.getString () + "\n"; - - result += "currentUnitTitle = " + currentUnitTitle + "\n"; - - result += "inBailOutAttempt = " + intToStr (inBailOutAttempt) + "\n"; - - result += "random = " + intToStr (random.getLastNumber ()) + "\n"; - if (this->random.getLastCaller () != "") - { - result += "randomlastCaller = " + random.getLastCaller () + "\n"; - } - result += - "pathFindRefreshCellCount = " + intToStr (pathFindRefreshCellCount) + - "\n"; - - result += - "currentPathFinderDesiredFinalPos = " + - currentPathFinderDesiredFinalPos.getString () + "\n"; - - result += "lastStuckFrame = " + uIntToStr (lastStuckFrame) + "\n"; - result += "lastStuckPos = " + lastStuckPos.getString () + "\n"; - - if (attackParticleSystems.empty () == false) - { - result += - "attackParticleSystems count = " + - intToStr (attackParticleSystems.size ()) + "\n"; - } - if (networkCRCParticleLogInfo != "") - { - result += - "networkCRCParticleLogInfo = " + networkCRCParticleLogInfo + "\n"; - } - if (networkCRCDecHpList.empty () == false) - { - result += - "getNetworkCRCDecHpList() = " + getNetworkCRCDecHpList () + "\n"; - } - - if (getParticleInfo () != "") - { - result += "getParticleInfo() = " + getParticleInfo () + "\n"; - } - for (unsigned int index = 0; index < attackParticleSystems.size (); - ++index) - { - ParticleSystem *ps = attackParticleSystems[index]; - if (ps != NULL && - Renderer::getInstance ().validateParticleSystemStillExists (ps, - rsGame) - == true) - { - - result += - "attackParticleSystems #" + intToStr (index) + " = " + - ps->toString () + "\n"; - } - } - - return result; - } - - void Unit::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode *unitNode = rootNode->addChild ("Unit"); - -// const int id; - unitNode->addAttribute ("id", intToStr (id), mapTagReplacements); - // For info purposes only - unitNode->addAttribute ("name", type->getName (false), - mapTagReplacements); - -// int hp; - unitNode->addAttribute ("hp", intToStr (hp), mapTagReplacements); -// int ep; - unitNode->addAttribute ("ep", intToStr (ep), mapTagReplacements); -// int loadCount; - unitNode->addAttribute ("loadCount", intToStr (loadCount), - mapTagReplacements); -// int deadCount; - unitNode->addAttribute ("deadCount", intToStr (deadCount), - mapTagReplacements); -// float progress; //between 0 and 1 - unitNode->addAttribute ("progress", intToStr (progress), - mapTagReplacements); -// float lastAnimProgress; //between 0 and 1 - unitNode->addAttribute ("lastAnimProgress", intToStr (lastAnimProgress), - mapTagReplacements); -// float animProgress; //between 0 and 1 - unitNode->addAttribute ("animProgress", intToStr (animProgress), - mapTagReplacements); -// float highlight; - unitNode->addAttribute ("highlight", floatToStr (highlight, 6), - mapTagReplacements); -// int progress2; - unitNode->addAttribute ("progress2", intToStr (progress2), - mapTagReplacements); -// int kills; - unitNode->addAttribute ("kills", intToStr (kills), mapTagReplacements); -// int enemyKills; - unitNode->addAttribute ("enemyKills", intToStr (enemyKills), - mapTagReplacements); -// UnitReference targetRef; - targetRef.saveGame (unitNode); -// -// Field currField; - unitNode->addAttribute ("currField", intToStr (currField), - mapTagReplacements); -// Field targetField; - unitNode->addAttribute ("targetField", intToStr (targetField), - mapTagReplacements); -// const Level *level; - if (level != NULL) - { - level->saveGame (unitNode); - } -// Vec2i pos; - unitNode->addAttribute ("pos", pos.getString (), mapTagReplacements); -// Vec2i lastPos; - unitNode->addAttribute ("lastPos", lastPos.getString (), - mapTagReplacements); -// Vec2i targetPos; //absolute target pos - unitNode->addAttribute ("targetPos", targetPos.getString (), - mapTagReplacements); -// Vec3f targetVec; - unitNode->addAttribute ("targetVec", targetVec.getString (), - mapTagReplacements); -// Vec2i meetingPos; - unitNode->addAttribute ("meetingPos", meetingPos.getString (), - mapTagReplacements); -// -// float lastRotation; //in degrees - unitNode->addAttribute ("lastRotation", floatToStr (lastRotation, 6), - mapTagReplacements); -// float targetRotation; - unitNode->addAttribute ("targetRotation", - floatToStr (targetRotation, 6), - mapTagReplacements); -// float rotation; - unitNode->addAttribute ("rotation", floatToStr (rotation, 6), - mapTagReplacements); -// float targetRotationZ; - unitNode->addAttribute ("targetRotationZ", - floatToStr (targetRotationZ, 6), - mapTagReplacements); -// float targetRotationX; - unitNode->addAttribute ("targetRotationX", - floatToStr (targetRotationX, 6), - mapTagReplacements); -// float rotationZ; - unitNode->addAttribute ("rotationZ", floatToStr (rotationZ, 6), - mapTagReplacements); -// float rotationX; - unitNode->addAttribute ("rotationX", floatToStr (rotationX, 6), - mapTagReplacements); -// const UnitType *type; - unitNode->addAttribute ("type", type->getName (false), - mapTagReplacements); - - unitNode->addAttribute ("preMorph_type", - (preMorph_type != - NULL ? preMorph_type->getName (false) : ""), - mapTagReplacements); - -// const ResourceType *loadType; - if (loadType != NULL) - { - unitNode->addAttribute ("loadType", loadType->getName (), - mapTagReplacements); - } -// const SkillType *currSkill; - if (currSkill != NULL) - { - unitNode->addAttribute ("currSkillName", currSkill->getName (), - mapTagReplacements); - unitNode->addAttribute ("currSkillClass", - intToStr (currSkill->getClass ()), - mapTagReplacements); - } -// int lastModelIndexForCurrSkillType; - unitNode->addAttribute ("lastModelIndexForCurrSkillType", - intToStr (lastModelIndexForCurrSkillType), - mapTagReplacements); -// int animationRandomCycleCount; - unitNode->addAttribute ("animationRandomCycleCount", - intToStr (animationRandomCycleCount), - mapTagReplacements); -// -// bool toBeUndertaken; - unitNode->addAttribute ("toBeUndertaken", intToStr (toBeUndertaken), - mapTagReplacements); -// bool alive; - unitNode->addAttribute ("alive", intToStr (alive), mapTagReplacements); -// bool showUnitParticles; - unitNode->addAttribute ("showUnitParticles", - intToStr (showUnitParticles), - mapTagReplacements); -// Faction *faction; -// ParticleSystem *fire; - int linkFireIndex = -1; - if (this->fire != NULL - && Renderer:: - getInstance ().validateParticleSystemStillExists (this->fire, - rsGame) == true) - { - //fire->saveGame(unitNode); - bool fireInSystemList = false; - if (fireParticleSystems.empty () == false) - { - for (unsigned int i = 0; i < fireParticleSystems.size (); ++i) - { - ParticleSystem *ps = fireParticleSystems[i]; - if (ps == this->fire) - { - linkFireIndex = i; - fireInSystemList = true; - break; - } - } - } - if (fireInSystemList == false) - { - this->fire->saveGame (unitNode); - } - } -// TotalUpgrade totalUpgrade; - totalUpgrade.saveGame (unitNode); -// Map *map; -// -// UnitPathInterface *unitPath; - unitPath->saveGame (unitNode); -// WaypointPath waypointPath; -// -// Commands commands; - for (Commands::iterator it = commands.begin (); it != commands.end (); - ++it) - { - (*it)->saveGame (unitNode, faction); - } -// Observers observers; - //for(Observers::iterator it = observers.begin(); it != observers.end(); ++it) { - // (*it)->saveGame(unitNode); - //} - -// vector unitParticleSystems; - if (unitParticleSystems.empty () == false) - { - XmlNode *unitParticleSystemsNode = - unitNode->addChild ("unitParticleSystems"); - - for (unsigned int i = 0; i < unitParticleSystems.size (); ++i) - { - UnitParticleSystem *ups = unitParticleSystems[i]; - if (ups != NULL - && Renderer:: - getInstance ().validateParticleSystemStillExists (ups, - rsGame) == - true) - { - ups->saveGame (unitParticleSystemsNode); - } - } - } -// vector queuedUnitParticleSystemTypes; - if (queuedUnitParticleSystemTypes.empty () == false) - { - XmlNode *queuedUnitParticleSystemTypesNode = - unitNode->addChild ("queuedUnitParticleSystemTypes"); - for (unsigned int i = 0; i < queuedUnitParticleSystemTypes.size (); - ++i) - { - UnitParticleSystemType *upst = queuedUnitParticleSystemTypes[i]; - if (upst != NULL) - { - upst->saveGame (queuedUnitParticleSystemTypesNode); - } - } - } -// UnitParticleSystems damageParticleSystems; - if (damageParticleSystems.empty () == false) - { - XmlNode *damageParticleSystemsNode = - unitNode->addChild ("damageParticleSystems"); - for (unsigned int i = 0; i < damageParticleSystems.size (); ++i) - { - UnitParticleSystem *ups = damageParticleSystems[i]; - if (ups != NULL - && Renderer:: - getInstance ().validateParticleSystemStillExists (ups, - rsGame) == - true) - { - ups->saveGame (damageParticleSystemsNode); - } - } - } -// std::map damageParticleSystemsInUse; - if (damageParticleSystemsInUse.empty () == false) - { - XmlNode *damageParticleSystemsInUseNode = - unitNode->addChild ("damageParticleSystemsInUse"); - - for (std::map < int, UnitParticleSystem * >::const_iterator iterMap = - damageParticleSystemsInUse.begin (); - iterMap != damageParticleSystemsInUse.end (); ++iterMap) - { - if (iterMap->second != NULL - && Renderer:: - getInstance ().validateParticleSystemStillExists (iterMap-> - second, - rsGame) == - true) - { - XmlNode *damageParticleSystemsInUseNode2 = - damageParticleSystemsInUseNode->addChild - ("damageParticleSystemsInUse"); - - damageParticleSystemsInUseNode2->addAttribute ("key", - intToStr - (iterMap->first), - mapTagReplacements); - iterMap->second->saveGame (damageParticleSystemsInUseNode2); - } - } - } - -// vector fireParticleSystems; - if (fireParticleSystems.empty () == false) - { - XmlNode *fireParticleSystemsNode = - unitNode->addChild ("fireParticleSystems"); - - if (linkFireIndex >= 0) - { - fireParticleSystemsNode->addAttribute ("fireParticleLink", - intToStr (linkFireIndex), - mapTagReplacements); - } - - for (unsigned int i = 0; i < fireParticleSystems.size (); ++i) - { - ParticleSystem *ps = fireParticleSystems[i]; - if (ps != NULL - && Renderer:: - getInstance ().validateParticleSystemStillExists (ps, - rsGame) == - true) - { - ps->saveGame (fireParticleSystemsNode); - } - } - } - -// vector smokeParticleSystems; - if (smokeParticleSystems.empty () == false) - { - XmlNode *smokeParticleSystemsNode = - unitNode->addChild ("smokeParticleSystems"); - for (unsigned int i = 0; i < smokeParticleSystems.size (); ++i) - { - UnitParticleSystem *ups = smokeParticleSystems[i]; - if (ups != NULL - && Renderer:: - getInstance ().validateParticleSystemStillExists (ups, - rsGame) == - true) - { - ups->saveGame (smokeParticleSystemsNode); - //printf("Saving smoke particles:\n[%s]\n",ups->toString().c_str()); - } - } - } - -// CardinalDir modelFacing; - unitNode->addAttribute ("modelFacing", intToStr (modelFacing), - mapTagReplacements); - -// std::string lastSynchDataString; - unitNode->addAttribute ("lastSynchDataString", lastSynchDataString, - mapTagReplacements); -// std::string lastFile; - unitNode->addAttribute ("lastFile", lastFile, mapTagReplacements); -// int lastLine; - unitNode->addAttribute ("lastLine", intToStr (lastLine), - mapTagReplacements); -// std::string lastSource; - unitNode->addAttribute ("lastSource", lastSource, mapTagReplacements); -// int lastRenderFrame; - unitNode->addAttribute ("lastRenderFrame", intToStr (lastRenderFrame), - mapTagReplacements); -// bool visible; - unitNode->addAttribute ("visible", intToStr (visible), - mapTagReplacements); -// int retryCurrCommandCount; - unitNode->addAttribute ("retryCurrCommandCount", - intToStr (retryCurrCommandCount), - mapTagReplacements); -// Vec3f screenPos; - unitNode->addAttribute ("screenPos", screenPos.getString (), - mapTagReplacements); -// string currentUnitTitle; - unitNode->addAttribute ("currentUnitTitle", currentUnitTitle, - mapTagReplacements); -// -// bool inBailOutAttempt; - unitNode->addAttribute ("inBailOutAttempt", intToStr (inBailOutAttempt), - mapTagReplacements); -// //std::vector > badHarvestPosList; -// std::map badHarvestPosList; - for (std::map < Vec2i, int >::const_iterator iterMap = - badHarvestPosList.begin (); iterMap != badHarvestPosList.end (); - ++iterMap) - { - XmlNode *badHarvestPosListNode = - unitNode->addChild ("badHarvestPosList"); - - badHarvestPosListNode->addAttribute ("key", - iterMap->first.getString (), - mapTagReplacements); - badHarvestPosListNode->addAttribute ("value", - intToStr (iterMap->second), - mapTagReplacements); - } - -// //time_t lastBadHarvestListPurge; -// std::pair lastHarvestResourceTarget; - XmlNode *lastHarvestResourceTargetNode = - unitNode->addChild ("lastHarvestResourceTarget"); - lastHarvestResourceTargetNode->addAttribute ("key", - lastHarvestResourceTarget.first. - getString (), - mapTagReplacements); - lastHarvestResourceTargetNode->addAttribute ("value", - intToStr - (lastHarvestResourceTarget.second), - mapTagReplacements); - -// //std::pair > currentTargetPathTaken; -// static Game *game; -// -// bool ignoreCheckCommand; - unitNode->addAttribute ("ignoreCheckCommand", - intToStr (ignoreCheckCommand), - mapTagReplacements); -// uint32 lastStuckFrame; - unitNode->addAttribute ("lastStuckFrame", uIntToStr (lastStuckFrame), - mapTagReplacements); -// Vec2i lastStuckPos; - unitNode->addAttribute ("lastStuckPos", lastStuckPos.getString (), - mapTagReplacements); -// uint32 lastPathfindFailedFrame; - unitNode->addAttribute ("lastPathfindFailedFrame", - intToStr (lastPathfindFailedFrame), - mapTagReplacements); -// Vec2i lastPathfindFailedPos; - unitNode->addAttribute ("lastPathfindFailedPos", - lastPathfindFailedPos.getString (), - mapTagReplacements); -// bool usePathfinderExtendedMaxNodes; - unitNode->addAttribute ("usePathfinderExtendedMaxNodes", - intToStr (usePathfinderExtendedMaxNodes), - mapTagReplacements); -// int maxQueuedCommandDisplayCount; - unitNode->addAttribute ("maxQueuedCommandDisplayCount", - intToStr (maxQueuedCommandDisplayCount), - mapTagReplacements); -// UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect; - currentAttackBoostOriginatorEffect.saveGame (unitNode); -// std::vector currentAttackBoostEffects; - for (unsigned int i = 0; i < currentAttackBoostEffects.size (); ++i) - { - UnitAttackBoostEffect *uabe = currentAttackBoostEffects[i]; - if (uabe != NULL) - { - uabe->saveGame (unitNode); - } - } - -// Mutex *mutexCommands; -// -// //static Mutex mutexDeletedUnits; -// //static std::map deletedUnits; -// -// bool changedActiveCommand; - unitNode->addAttribute ("changedActiveCommand", - intToStr (changedActiveCommand), - mapTagReplacements); -// int lastAttackerUnitId; - unitNode->addAttribute ("lastAttackerUnitId", - intToStr (lastAttackerUnitId), - mapTagReplacements); -// int lastAttackedUnitId; - unitNode->addAttribute ("lastAttackedUnitId", - intToStr (lastAttackedUnitId), - mapTagReplacements); -// CauseOfDeathType causeOfDeath; - unitNode->addAttribute ("causeOfDeath", intToStr (causeOfDeath), - mapTagReplacements); - - //pathfindFailedConsecutiveFrameCount - unitNode->addAttribute ("pathfindFailedConsecutiveFrameCount", - intToStr (pathfindFailedConsecutiveFrameCount), - mapTagReplacements); - - unitNode->addAttribute ("currentPathFinderDesiredFinalPos", - currentPathFinderDesiredFinalPos.getString (), - mapTagReplacements); - - unitNode->addAttribute ("random", intToStr (random.getLastNumber ()), - mapTagReplacements); - unitNode->addAttribute ("pathFindRefreshCellCount", - intToStr (pathFindRefreshCellCount), - mapTagReplacements); - } - - Unit *Unit::loadGame (const XmlNode * rootNode, GameSettings * settings, - Faction * faction, World * world) - { - const XmlNode *unitNode = rootNode; - - int newUnitId = unitNode->getAttribute ("id")->getIntValue (); - Vec2i newUnitPos = - Vec2i::strToVec2 (unitNode->getAttribute ("pos")->getValue ()); - string newUnitType = unitNode->getAttribute ("type")->getValue (); - const UnitType *ut = faction->getType ()->getUnitType (newUnitType); - CardinalDir newModelFacing = - static_cast < CardinalDir > - (unitNode->getAttribute ("modelFacing")->getIntValue ()); - -// Unit *result = new Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, -// const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing) : BaseColorPickEntity(), id(id) { - - UnitPathInterface *newpath = NULL; - switch (settings->getPathFinderType ()) - { - case pfBasic: - newpath = new UnitPathBasic (); - break; - default: - throw - megaglest_runtime_error ("detected unsupported pathfinder type!"); - } - - newpath->loadGame (unitNode); - //Unit *result = new Unit(getNextUnitId(f), newpath, Vec2i(0), ut, f, &map, CardinalDir::NORTH); - //Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing); - Unit *result = new Unit (newUnitId, newpath, newUnitPos, ut, faction, - world->getMapPtr (), newModelFacing); - - if (unitNode->hasAttribute ("preMorph_name") == true) - { - string newUnitType_preMorph = - unitNode->getAttribute ("preMorph_name")->getValue (); - const UnitType *ut_premorph = - faction->getType ()->getUnitType (newUnitType_preMorph); - result->preMorph_type = ut_premorph; - } - - result->lastRotation = - unitNode->getAttribute ("lastRotation")->getFloatValue (); - result->targetRotation = - unitNode->getAttribute ("targetRotation")->getFloatValue (); - result->rotation = - unitNode->getAttribute ("rotation")->getFloatValue (); - - //world->placeUnitAtLocation(newUnitPos, generationArea, unit, true); - //result->setPos(newUnitPos); - //Vec2i meetingPos = newUnitPos-Vec2i(1); - //result->setMeetingPos(meetingPos); - result->pos = newUnitPos; - result->lastPos = - Vec2i::strToVec2 (unitNode->getAttribute ("lastPos")->getValue ()); - result->meetingPos = - Vec2i::strToVec2 (unitNode->getAttribute ("meetingPos")->getValue ()); - // Attempt to improve performance - //result->exploreCells(); - //result->calculateFogOfWarRadius(); - // -------------------------- - - result->hp = unitNode->getAttribute ("hp")->getIntValue (); -// int ep; - result->ep = unitNode->getAttribute ("ep")->getIntValue (); -// int loadCount; - result->loadCount = - unitNode->getAttribute ("loadCount")->getIntValue (); -// int deadCount; - result->deadCount = - unitNode->getAttribute ("deadCount")->getIntValue (); -// float progress; //between 0 and 1 - try - { - result->progress = - unitNode->getAttribute ("progress")->getIntValue (); - } -#ifdef WIN32 - catch (const exception &) - { -#else - catch (const exception & ex) - { + } #endif - result->progress = - unitNode->getAttribute ("progress")->getFloatValue (); - } -// float lastAnimProgress; //between 0 and 1 - try - { - result->lastAnimProgress = - unitNode->getAttribute ("lastAnimProgress")->getIntValue (); - } -#ifdef WIN32 - catch (const exception &) - { -#else - catch (const exception & ex) - { + + void UnitPathBasic::clearCaches() { + this->blockCount = 0; + this->pathQueue.clear(); + } + + bool UnitPathBasic::isEmpty() const { + return pathQueue.empty(); + } + + bool UnitPathBasic::isBlocked() const { + return blockCount >= maxBlockCount; + } + + bool UnitPathBasic::isStuck() const { + return (isBlocked() == true && blockCount >= (maxBlockCount * 2)); + } + + void UnitPathBasic::clear() { + pathQueue.clear(); + blockCount = 0; + } + + void UnitPathBasic::incBlockCount() { + pathQueue.clear(); + blockCount++; + } + + void UnitPathBasic::add(const Vec2i & path) { + if (this->map != NULL) { + if (this->map->isInside(path) == false) { + throw megaglest_runtime_error("Invalid map path position = " + + path.getString() + " map w x h = " + + intToStr(map->getW()) + " " + + intToStr(map->getH())); + } else if (this-> + map->isInsideSurface(this->map->toSurfCoords(path)) == + false) { + throw + megaglest_runtime_error("Invalid map surface path position = " + + path.getString() + + " map surface w x h = " + + intToStr(map->getSurfaceW()) + " " + + intToStr(map->getSurfaceH())); + } + } + + if (Thread::isCurrentThreadMainThread() == false) { + throw + megaglest_runtime_error + ("Invalid access to UnitPathBasic add from outside main thread current id = " + + intToStr(Thread::getCurrentThreadId()) + " main = " + + intToStr(Thread::getMainThreadId())); + } + + pathQueue.push_back(path); + } + + Vec2i UnitPathBasic::pop(bool removeFrontPos) { + if (pathQueue.empty() == true) { + throw megaglest_runtime_error("pathQueue.size() = " + + intToStr(pathQueue.size())); + } + Vec2i p = pathQueue.front(); + if (removeFrontPos == true) { + if (Thread::isCurrentThreadMainThread() == false) { + throw + megaglest_runtime_error + ("Invalid access to UnitPathBasic delete from outside main thread current id = " + + intToStr(Thread::getCurrentThreadId()) + " main = " + + intToStr(Thread::getMainThreadId())); + } + + pathQueue.erase(pathQueue.begin()); + } + return p; + } + std::string UnitPathBasic::toString()const { + std::string result = + "unit path blockCount = " + intToStr(blockCount) + + "\npathQueue size = " + intToStr(pathQueue.size()); + for (int idx = 0; idx < (int) pathQueue.size(); ++idx) { + result += + " index = " + intToStr(idx) + " value = " + + pathQueue[idx].getString(); + } + + return result; + } + + void UnitPathBasic::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode *unitPathBasicNode = rootNode->addChild("UnitPathBasic"); + + // int blockCount; + unitPathBasicNode->addAttribute("blockCount", intToStr(blockCount), + mapTagReplacements); + // vector pathQueue; + for (unsigned int i = 0; i < pathQueue.size(); ++i) { + Vec2i & vec = pathQueue[i]; + + XmlNode *pathQueueNode = unitPathBasicNode->addChild("pathQueue"); + pathQueueNode->addAttribute("vec", vec.getString(), + mapTagReplacements); + } + } + + void UnitPathBasic::loadGame(const XmlNode * rootNode) { + const XmlNode *unitPathBasicNode = rootNode->getChild("UnitPathBasic"); + + blockCount = + unitPathBasicNode->getAttribute("blockCount")->getIntValue(); + + pathQueue.clear(); + vector < XmlNode * >pathqueueNodeList = + unitPathBasicNode->getChildList("pathQueue"); + for (unsigned int i = 0; i < pathqueueNodeList.size(); ++i) { + XmlNode *node = pathqueueNodeList[i]; + + Vec2i vec = + Vec2i::strToVec2(node->getAttribute("vec")->getValue()); + pathQueue.push_back(vec); + } + } + + Checksum UnitPathBasic::getCRC() { + Checksum crcForPath; + + crcForPath.addInt(blockCount); + crcForPath.addInt((int) pathQueue.size()); + + return crcForPath; + } + + // ===================================================== + // class UnitPath + // ===================================================== + + //void WaypointPath::condense() { + // if (size() < 2) { + // return; + // } + // iterator prev, curr; + // prev = curr = begin(); + // while (++curr != end()) { + // if (prev->dist(*curr) < 3.f) { + // prev = erase(prev); + // } else { + // ++prev; + // } + // } + //} + + std::string UnitPath::toString()const { + std::string result = + "unit path blockCount = " + intToStr(blockCount) + + " pathQueue size = " + intToStr(size()); + result += " path = "; + for (const_iterator it = begin(); it != end(); ++it) { + result += " [" + intToStr(it->x) + "," + intToStr(it->y) + "]"; + } + + return result; + } + + // ===================================================== + // class UnitReference + // ===================================================== + + UnitReference::UnitReference() { + id = -1; + faction = NULL; + } + + UnitReference & UnitReference::operator= (const Unit * unit) { + if (unit == NULL) { + id = -1; + faction = NULL; + } else { + id = unit->getId(); + faction = unit->getFaction(); + } + + return *this; + } + + Unit *UnitReference::getUnit() const { + if (faction != NULL) { + return faction->findUnit(id); + } + return NULL; + } + + void UnitReference::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode *unitRefNode = rootNode->addChild("UnitReference"); + + unitRefNode->addAttribute("id", intToStr(id), mapTagReplacements); + if (faction != NULL) { + unitRefNode->addAttribute("factionIndex", + intToStr(faction->getIndex()), + mapTagReplacements); + } + } + + void UnitReference::loadGame(const XmlNode * rootNode, World * world) { + const XmlNode *unitRefNode = rootNode->getChild("UnitReference"); + + id = unitRefNode->getAttribute("id")->getIntValue(); + if (unitRefNode->hasAttribute("factionIndex") == true) { + int factionIndex = + unitRefNode->getAttribute("factionIndex")->getIntValue(); + if (factionIndex >= world->getFactionCount()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "factionIndex >= world->getFactionCount() [%d] : [%d]", + factionIndex, world->getFactionCount()); + throw megaglest_runtime_error(szBuf); + } + faction = world->getFaction(factionIndex); + } + } + + const bool checkMemory = false; + static map < void *, int >memoryObjectList; + + UnitAttackBoostEffect::UnitAttackBoostEffect() { + if (checkMemory) { + printf("++ Create UnitAttackBoostEffect [%p] before count = %d\n", + this, memoryObjectList[this]); + memoryObjectList[this]++; + printf("++ Create UnitAttackBoostEffect [%p] after count = %d\n", + this, memoryObjectList[this]); + } + + unitId = -1; + unitPtr = NULL; + boost = NULL; + source = NULL; + ups = NULL; + upst = NULL; + } + + UnitAttackBoostEffect::~UnitAttackBoostEffect() { + if (checkMemory) { + printf("-- Delete UnitAttackBoostEffect [%p] count = %d\n", this, + memoryObjectList[this]); + memoryObjectList[this]--; + assert(memoryObjectList[this] == 0); + } + + if (ups != NULL) { + bool particleValid = + Renderer::getInstance().validateParticleSystemStillExists(ups, + rsGame); + if (particleValid == true) { + ups->fade(); + + vector < UnitParticleSystem * >particleSystemToRemove; + particleSystemToRemove.push_back(ups); + + Renderer:: + getInstance().cleanupUnitParticleSystems(particleSystemToRemove, + rsGame); + ups = NULL; + } + } + + delete upst; + upst = NULL; + } + + const Unit *UnitAttackBoostEffect::getSource() { + if (source == NULL && unitPtr != NULL && unitId > 0) { + source = unitPtr->getFaction()->findUnit(unitId); + + //printf("#1 Get source - boost effect unitId = %d unitPtr = %s source = %p\n",unitId,unitPtr->getFullName(false).c_str(),source); + } + //printf("#2 Get source - boost effect unitId = %d unitPtr = %s source = %p\n",unitId,unitPtr->getFullName(false).c_str(),source); + return source; + } + + void UnitAttackBoostEffect::setSource(const Unit * unit) { + source = unit; + } + + void UnitAttackBoostEffect:: + applyLoadedAttackBoostParticles(UnitParticleSystemType * upstPtr, + const XmlNode * node, Unit * unit) { + if (upstPtr != NULL) { + bool showUnitParticles = + Config::getInstance().getBool("UnitParticles", "true"); + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + showUnitParticles = false; + } + if (showUnitParticles == true) { + upst = new UnitParticleSystemType(); + *upst = *upstPtr; + upst->loadGame(node); + + ups = new UnitParticleSystem(200); + //ups->loadGame(node2); + ups->setParticleOwner(unit); + ups->setParticleType(upst); + + upst->setValues(ups); + ups->setPos(unit->getCurrVectorForParticlesystems()); + ups->setRotation(unit->getRotation()); + unit->setMeshPosInParticleSystem(ups); + if (unit->getFaction()->getTexture()) { + ups->setFactionColor(unit->getFaction()-> + getTexture()->getPixmapConst()-> + getPixel3f(0, 0)); + } + //printf("Adding attack boost particle to deferred buffer: %p\n",ups); + Renderer:: + getInstance().addToDeferredParticleSystemList(make_pair + (ups, rsGame)); + } + } + } + + void UnitAttackBoostEffect::loadGame(const XmlNode * rootNode, + Unit * unit, World * world, + bool applyToOriginator) { + const XmlNode *unitAttackBoostEffectNode = rootNode; + + if (unitAttackBoostEffectNode->hasAttribute("source") == true) { + unitId = + unitAttackBoostEffectNode->getAttribute("source")->getIntValue(); + unitPtr = unit; + source = unit->getFaction()->findUnit(unitId); + + // printf("#1 Loaded boost effect unitId = %d unitPtr = [%d - %s] source = %p\n", + // unitId,unitPtr->getId(),unitPtr->getType()->getName(false).c_str(),source); + } + + // Lets determine the originator unit's attack boost based on the skill used to trigger it + if (unitAttackBoostEffectNode->hasAttribute("source-faction") == true) { + string factionName = + unitAttackBoostEffectNode-> + getAttribute("source-faction")->getValue(); + string unitTypeName = + unitAttackBoostEffectNode-> + getAttribute("source-unit-type")->getValue(); + string skillTypeName = + unitAttackBoostEffectNode-> + getAttribute("source-skill-type")->getValue(); + SkillClass skillClass = + static_cast + (unitAttackBoostEffectNode-> + getAttribute("source-skill-class")->getIntValue()); + + const UnitType *unitType = + world->findUnitTypeByName(factionName, unitTypeName); + if (unitType != NULL) { + const SkillType *skillType = + unitType->getSkillType(skillTypeName, skillClass); + if (skillType != NULL) { + boost = skillType->getAttackBoost(); + + // printf("#2 boost effect unitId = %d unitPtr = [%d - %s] source = %p attackBoost src [%p] dest [%p]\n", + // unitId,unitPtr->getId(),unitPtr->getType()->getName(false).c_str(), + // source,boost->unitParticleSystemTypeForSourceUnit,boost->unitParticleSystemTypeForAffectedUnit); + } + } + } + + if (boost != NULL) { + // printf("unit [%d - %s] applyToOriginator: %d src [%p] dest [%p] Boost attackBoost->enabled = %d:\n%s\n", + // unit->getId(),unit->getType()->getName(false).c_str(),applyToOriginator,boost->unitParticleSystemTypeForSourceUnit,boost->unitParticleSystemTypeForAffectedUnit,boost->enabled,boost->getDesc(false).c_str()); + + if (applyToOriginator == true) { + applyLoadedAttackBoostParticles + (boost->unitParticleSystemTypeForSourceUnit, + unitAttackBoostEffectNode, unit); + } else { + applyLoadedAttackBoostParticles + (boost->unitParticleSystemTypeForAffectedUnit, + unitAttackBoostEffectNode, unit); + } + } else { + printf + ("******!!!! unit [%d - %s] applyToOriginator: %d NO BOOST FOUND!!!\n", + unit->getId(), unit->getType()->getName(false).c_str(), + applyToOriginator); + } + } + + void UnitAttackBoostEffect::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode *unitAttackBoostEffectNode = + rootNode->addChild("UnitAttackBoostEffect"); + + // const AttackBoost *boost; + if (boost != NULL) { + boost->saveGame(unitAttackBoostEffectNode); + } + // const Unit *source; + if (getSource() != NULL) { + unitAttackBoostEffectNode->addAttribute("source", + intToStr(getSource()->getId + ()), + mapTagReplacements); + + unitAttackBoostEffectNode->addAttribute("source-faction", + getSource()-> + getFaction()->getType()-> + getName(false), + mapTagReplacements); + unitAttackBoostEffectNode->addAttribute("source-unit-type", + getSource()-> + getType()->getName(false), + mapTagReplacements); + unitAttackBoostEffectNode->addAttribute("source-skill-type", + getSource()->getCurrSkill + ()->getName(), + mapTagReplacements); + unitAttackBoostEffectNode->addAttribute("source-skill-class", + intToStr(getSource + ()->getCurrSkill + ()->getClass()), + mapTagReplacements); + } + // UnitParticleSystem *ups; + if (ups != NULL + && Renderer::getInstance().validateParticleSystemStillExists(ups, + rsGame) + == true) { + ups->saveGame(unitAttackBoostEffectNode); + } + + // UnitParticleSystemType *upst; + if (upst != NULL) { + upst->saveGame(unitAttackBoostEffectNode); + } + } + + UnitAttackBoostEffectOriginator::UnitAttackBoostEffectOriginator() { + skillType = NULL; + currentAppliedEffect = NULL; + } + + UnitAttackBoostEffectOriginator::~UnitAttackBoostEffectOriginator() { + delete currentAppliedEffect; + currentAppliedEffect = NULL; + } + + void UnitAttackBoostEffectOriginator::loadGame(const XmlNode * rootNode, + Unit * unit, + World * world) { + const XmlNode *unitAttackBoostEffectOriginatorNode = + rootNode->getChild("UnitAttackBoostEffectOriginator"); + + SkillClass skillClass = scStop; + string skillTypeName = + unitAttackBoostEffectOriginatorNode-> + getAttribute("skillType")->getValue(); + if (unitAttackBoostEffectOriginatorNode->hasAttribute("skillClass") == + false) { + int skillCount = unit->getType()->getSkillTypeCount(); + for (int index = 0; index < skillCount; ++index) { + const SkillType *st = unit->getType()->getSkillType(index); + if (st->getName() == skillTypeName) { + skillClass = st->getClass(); + break; + } + } + } else { + skillClass = + static_cast + (unitAttackBoostEffectOriginatorNode-> + getAttribute("skillClass")->getIntValue()); + } + + this->skillType = + unit->getType()->getSkillType(skillTypeName, skillClass); + + if (unitAttackBoostEffectOriginatorNode->hasChild + ("currentAttackBoostUnits") == true) { + vector < XmlNode * >currentAttackBoostUnitsNodeList = + unitAttackBoostEffectOriginatorNode->getChildList + ("currentAttackBoostUnits"); + for (unsigned int i = 0; i < currentAttackBoostUnitsNodeList.size(); + ++i) { + XmlNode *node = currentAttackBoostUnitsNodeList[i]; + + int unitId = node->getAttribute("value")->getIntValue(); + currentAttackBoostUnits.push_back(unitId); + } + } + + if (unitAttackBoostEffectOriginatorNode->hasChild + ("UnitAttackBoostEffect") == true) { + currentAppliedEffect = new UnitAttackBoostEffect(); + currentAppliedEffect->loadGame(unitAttackBoostEffectOriginatorNode, + unit, world, true); + } + } + + void UnitAttackBoostEffectOriginator::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode *unitAttackBoostEffectOriginatorNode = + rootNode->addChild("UnitAttackBoostEffectOriginator"); + + // const SkillType *skillType; + if (skillType != NULL) { + unitAttackBoostEffectOriginatorNode->addAttribute("skillType", + skillType->getName + (), + mapTagReplacements); + unitAttackBoostEffectOriginatorNode->addAttribute("skillClass", + intToStr + (skillType->getClass + ()), + mapTagReplacements); + } + // std::vector currentAttackBoostUnits; + for (unsigned int i = 0; i < currentAttackBoostUnits.size(); ++i) { + XmlNode *currentAttackBoostUnitsNode = + unitAttackBoostEffectOriginatorNode->addChild + ("currentAttackBoostUnits"); + currentAttackBoostUnitsNode->addAttribute("value", + intToStr + (currentAttackBoostUnits + [i]), mapTagReplacements); + } + // UnitAttackBoostEffect *currentAppliedEffect; + if (currentAppliedEffect != NULL) { + currentAppliedEffect->saveGame(unitAttackBoostEffectOriginatorNode); + } + } + + // ===================================================== + // class Unit + // ===================================================== + + const float Unit::ANIMATION_SPEED_MULTIPLIER = 100000.f; + //const float Unit::PROGRESS_SPEED_MULTIPLIER = 100000.f; + const int64 Unit::PROGRESS_SPEED_MULTIPLIER = 100000; + + const int Unit::speedDivider = 100; + const int Unit::maxDeadCount = 1000; //time in until the corpse disapears - should be about 40 seconds + const int Unit::invalidId = -1; + + //set Unit::livingUnits; + //set Unit::livingUnitsp; + + // ============================ Constructor & destructor ============================= + + Game *Unit::game = NULL; + + Unit::Unit(int id, UnitPathInterface * unitpath, const Vec2i & pos, + const UnitType * type, Faction * faction, Map * map, + CardinalDir placeFacing) :BaseColorPickEntity(), id(id) { +#ifdef LEAK_CHECK_UNITS + Unit::mapMemoryList[this] = true; #endif - result->lastAnimProgress = - unitNode->getAttribute ("lastAnimProgress")->getFloatValue (); - } -// float animProgress; //between 0 and 1 - try - { - result->animProgress = - unitNode->getAttribute ("animProgress")->getIntValue (); - } -#ifdef WIN32 - catch (const exception &) - { -#else - catch (const exception & ex) - { + mutexCommands = new Mutex(CODE_AT_LINE); + changedActiveCommand = false; + lastChangedActiveCommandFrame = 0; + changedActiveCommandFrame = 0; + + lastSynchDataString = ""; + modelFacing = CardinalDir(CardinalDir::NORTH); + lastStuckFrame = 0; + lastStuckPos = Vec2i(0, 0); + lastPathfindFailedFrame = 0; + lastPathfindFailedPos = Vec2i(0, 0); + usePathfinderExtendedMaxNodes = false; + this->currentAttackBoostOriginatorEffect.skillType = NULL; + lastAttackerUnitId = -1; + lastAttackedUnitId = -1; + causeOfDeath = ucodNone; + pathfindFailedConsecutiveFrameCount = 0; + + lastSynchDataString = ""; + lastFile = ""; + lastLine = 0; + lastSource = ""; + + targetRotationZ = .0f; + targetRotationX = .0f; + rotationZ = .0f; + rotationX = .0f; + + this->fire = NULL; + this->unitPath = unitpath; + this->unitPath->setMap(map); + + //RandomGen random; + random.init(id); + random.setDisableLastCallerTracking(isNetworkCRCEnabled() == false); + pathFindRefreshCellCount = + random.randRange(10, 20, intToStr(__LINE__)); + + if (map->isInside(pos) == false + || map->isInsideSurface(map->toSurfCoords(pos)) == false) { + throw megaglest_runtime_error("#2 Invalid path position = " + + pos.getString()); + } + + this->pos = pos; + + this->faction = faction; + this->preMorph_type = NULL; + this->type = type; + setType(this->type); + + this->map = map; + this->targetRef = NULL; + this->targetField = fLand; + this->targetVec = Vec3f(0.0); + this->targetPos = Vec2i(0); + this->lastRenderFrame = 0; + this->visible = true; + this->retryCurrCommandCount = 0; + this->screenPos = Vec3f(0.0); + this->ignoreCheckCommand = false; + this->inBailOutAttempt = false; + this->lastHarvestResourceTarget.first = Vec2i(0); + this->morphFieldsBlocked = false; + //this->lastBadHarvestListPurge = 0; + this->oldTotalSight = 0; + + level = NULL; + loadType = NULL; + + setModelFacing(placeFacing); + + Config & config = Config::getInstance(); + showUnitParticles = config.getBool("UnitParticles", "true"); + maxQueuedCommandDisplayCount = + config.getInt("MaxQueuedCommandDisplayCount", "15"); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + showUnitParticles = false; + } + + lastPos = pos; + progress = 0; + this->lastAnimProgress = 0; + this->animProgress = 0; + progress2 = 0; + kills = 0; + enemyKills = 0; + loadCount = 0; + ep = 0; + deadCount = 0; + hp = type->getMaxHp() / 20; + toBeUndertaken = false; + + highlight = 0.f; + meetingPos = pos; + setAlive(true); + + if (type->hasSkillClass(scBeBuilt) == false) { + float rot = 0.f; + random.init(id); + rot += random.randRange(-5, 5, intToStr(__LINE__)); + rotation = rot; + lastRotation = rot; + targetRotation = rot; + } + // else it was set appropriately in setModelFacing() + + if (getType()->getField(fAir)) { + currField = fAir; + } + if (getType()->getField(fLand)) { + currField = fLand; + } + + computeTotalUpgrade(); + + //starting skill + this->lastModelIndexForCurrSkillType = -1; + this->animationRandomCycleCount = 0; + this->currSkill = getType()->getFirstStOfClass(scStop); + this->setCurrSkill(this->currSkill); + this->currentAttackBoostOriginatorEffect.skillType = this->currSkill; + + this->faction->addLivingUnits(id); + this->faction->addLivingUnitsp(this); + + addItemToVault(&this->hp, this->hp); + addItemToVault(&this->ep, this->ep); + + calculateFogOfWarRadius(); + + // if(isUnitDeleted(this) == true) { + // MutexSafeWrapper safeMutex(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__)); + // deletedUnits.erase(this); + // } + + logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), + __LINE__); + } + + Unit::~Unit() { + badHarvestPosList.clear(); + + this->faction->deleteLivingUnits(id); + this->faction->deleteLivingUnitsp(this); + + //remove commands + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands, mutexOwnerId); + + changedActiveCommand = false; + while (commands.empty() == false) { + delete commands.back(); + commands.pop_back(); + } + safeMutex.ReleaseLock(); + + cleanupAllParticlesystems(); + + while (currentAttackBoostEffects.empty() == false) { + //UnitAttackBoostEffect &effect = currentAttackBoostEffects.back(); + UnitAttackBoostEffect *ab = currentAttackBoostEffects.back(); + delete ab; + currentAttackBoostEffects.pop_back(); + } + + delete currentAttackBoostOriginatorEffect.currentAppliedEffect; + currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL; + + //Renderer::getInstance().cleanupParticleSystems(attackParticleSystems,rsGame); + Renderer::getInstance().removeParticleSystemsForParticleOwner(this, + rsGame); + + +#ifdef LEAK_CHECK_UNITS + Unit::mapMemoryList2[this->unitPath] = this->getId(); #endif - result->animProgress = - unitNode->getAttribute ("animProgress")->getFloatValue (); - } - -// float highlight; - result->highlight = - unitNode->getAttribute ("highlight")->getFloatValue (); -// int progress2; - result->progress2 = - unitNode->getAttribute ("progress2")->getIntValue (); -// int kills; - result->kills = unitNode->getAttribute ("kills")->getIntValue (); -// int enemyKills; - result->enemyKills = - unitNode->getAttribute ("enemyKills")->getIntValue (); -// UnitReference targetRef; -// targetRef.saveGame(unitNode); - result->targetRef.loadGame (unitNode, world); -// -// Field currField; - result->currField = - static_cast < Field > - (unitNode->getAttribute ("currField")->getIntValue ()); -// Field targetField; - result->targetField = - static_cast < Field > - (unitNode->getAttribute ("targetField")->getIntValue ()); -// const Level *level; -// if(level != NULL) { -// level->saveGame(unitNode); -// } - result->level = Level::loadGame (unitNode, ut); -// Vec2i pos; - result->pos = - Vec2i::strToVec2 (unitNode->getAttribute ("pos")->getValue ()); -// Vec2i lastPos; - result->lastPos = - Vec2i::strToVec2 (unitNode->getAttribute ("lastPos")->getValue ()); -// Vec2i targetPos; //absolute target pos - result->targetPos = - Vec2i::strToVec2 (unitNode->getAttribute ("targetPos")->getValue ()); -// Vec3f targetVec; - result->targetVec = - Vec3f::strToVec3 (unitNode->getAttribute ("targetVec")->getValue ()); -// Vec2i meetingPos; - result->meetingPos = - Vec2i::strToVec2 (unitNode->getAttribute ("meetingPos")->getValue ()); -// -// float lastRotation; //in degrees - result->lastRotation = - unitNode->getAttribute ("lastRotation")->getFloatValue (); -// float targetRotation; - result->targetRotation = - unitNode->getAttribute ("targetRotation")->getFloatValue (); -// float rotation; - result->rotation = - unitNode->getAttribute ("rotation")->getFloatValue (); -// float targetRotationZ; - result->targetRotationZ = - unitNode->getAttribute ("targetRotationZ")->getFloatValue (); -// float targetRotationX; - result->targetRotationX = - unitNode->getAttribute ("targetRotationX")->getFloatValue (); -// float rotationZ; - result->rotationZ = - unitNode->getAttribute ("rotationZ")->getFloatValue (); -// float rotationX; - result->rotationX = - unitNode->getAttribute ("rotationX")->getFloatValue (); -// const UnitType *type; -// unitNode->addAttribute("type",type->getName(), mapTagReplacements); -// const ResourceType *loadType; -// if(loadType != NULL) { -// unitNode->addAttribute("loadType",loadType->getName(), mapTagReplacements); -// } - if (unitNode->hasAttribute ("loadType") == true) - { - string loadTypeName = - unitNode->getAttribute ("loadType")->getValue (); - result->loadType = - world->getTechTree ()->getResourceType (loadTypeName); - } -// const SkillType *currSkill; -// if(currSkill != NULL) { -// unitNode->addAttribute("currSkill",currSkill->getName(), mapTagReplacements); -// } - if (unitNode->hasAttribute ("currSkillName") == true) - { - string skillTypeName = - unitNode->getAttribute ("currSkillName")->getValue (); - SkillClass skillClass = - static_cast < SkillClass > - (unitNode->getAttribute ("currSkillClass")->getIntValue ()); - result->currSkill = ut->getSkillType (skillTypeName, skillClass); - result->setCurrSkill (result->currSkill); - } - -// int lastModelIndexForCurrSkillType; - result->lastModelIndexForCurrSkillType = - unitNode-> - getAttribute ("lastModelIndexForCurrSkillType")->getIntValue (); -// int animationRandomCycleCount; - result->animationRandomCycleCount = - unitNode->getAttribute ("animationRandomCycleCount")->getIntValue (); -// -// bool toBeUndertaken; - result->toBeUndertaken = - unitNode->getAttribute ("toBeUndertaken")->getIntValue () != 0; -// bool alive; - result->setAlive (unitNode->getAttribute ("alive")->getIntValue () != - 0); -// bool showUnitParticles; - result->showUnitParticles = - unitNode->getAttribute ("showUnitParticles")->getIntValue () != 0; -// Faction *faction; -// ParticleSystem *fire; -// if(fire != NULL) { -// fire->saveGame(unitNode); -// } - if (unitNode->hasChild ("FireParticleSystem") == true) - { - XmlNode *fireNode = unitNode->getChild ("FireParticleSystem"); - result->fire = new FireParticleSystem (); - result->fire->setParticleOwner (result); - result->fire->loadGame (fireNode); - //result->fire->setTexture(CoreData::getInstance().getFireTexture()); - result->fireParticleSystems.push_back (result->fire); - - //printf("Load MAIN fire particle result->fire = %p\n",result->fire); - - Renderer:: - getInstance ().addToDeferredParticleSystemList (make_pair - (result->fire, - rsGame)); - } - -// TotalUpgrade totalUpgrade; - result->totalUpgrade.loadGame (unitNode); -// Map *map; -// -// UnitPathInterface *unitPath; -// unitPath->saveGame(unitNode); -// WaypointPath waypointPath; -// -// Commands commands; -// for(Commands::iterator it = commands.begin(); it != commands.end(); ++it) { -// (*it)->saveGame(unitNode); -// } - vector < XmlNode * >commandNodeList = - unitNode->getChildList ("Command"); - for (unsigned int i = 0; i < commandNodeList.size (); ++i) - { - XmlNode *node = commandNodeList[i]; - Command *command = Command::loadGame (node, ut, world); - - static string mutexOwnerId = - string (__FILE__) + string ("_") + intToStr (__LINE__); - MutexSafeWrapper safeMutex (result->mutexCommands, mutexOwnerId); - result->commands.push_back (command); - safeMutex.ReleaseLock (); - } -// Observers observers; - //for(Observers::iterator it = observers.begin(); it != observers.end(); ++it) { - // (*it)->saveGame(unitNode); - //} - -// vector unitParticleSystems; -// for(unsigned int i = 0; i < unitParticleSystems.size(); ++i) { -// UnitParticleSystem *ups= unitParticleSystems[i]; -// ups->saveGame(unitNode); -// } - if (unitNode->hasChild ("unitParticleSystems") == true) - { - XmlNode *unitParticleSystemsNode = - unitNode->getChild ("unitParticleSystems"); - vector < XmlNode * >unitParticleSystemNodeList = - unitParticleSystemsNode->getChildList ("UnitParticleSystem"); - for (unsigned int i = 0; i < unitParticleSystemNodeList.size (); ++i) - { - XmlNode *node = unitParticleSystemNodeList[i]; - - UnitParticleSystem *ups = new UnitParticleSystem (); - ups->setParticleOwner (result); - ups->loadGame (node); - result->unitParticleSystems.push_back (ups); - - //Renderer::getInstance().manageParticleSystem(result->fire, rsGame); - Renderer:: - getInstance ().addToDeferredParticleSystemList (make_pair - (ups, rsGame)); - } - } - -// vector queuedUnitParticleSystemTypes; -// for(unsigned int i = 0; i < queuedUnitParticleSystemTypes.size(); ++i) { -// UnitParticleSystemType *upst= queuedUnitParticleSystemTypes[i]; -// upst->saveGame(unitNode); -// } - -// UnitParticleSystems damageParticleSystems; -// for(unsigned int i = 0; i < damageParticleSystems.size(); ++i) { -// UnitParticleSystem *ups= damageParticleSystems[i]; -// ups->saveGame(unitNode); -// } - if (unitNode->hasChild ("damageParticleSystems") == true) - { - XmlNode *damageParticleSystemsNode = - unitNode->getChild ("damageParticleSystems"); - vector < XmlNode * >unitParticleSystemNodeList = - damageParticleSystemsNode->getChildList ("UnitParticleSystem"); - for (unsigned int i = 0; i < unitParticleSystemNodeList.size (); ++i) - { - XmlNode *node = unitParticleSystemNodeList[i]; - - UnitParticleSystem *ups = new UnitParticleSystem (); - ups->setParticleOwner (result); - ups->loadGame (node); - result->damageParticleSystems.push_back (ups); - result->damageParticleSystemsInUse[i] = ups; - - //Renderer::getInstance().manageParticleSystem(result->fire, rsGame); - Renderer:: - getInstance ().addToDeferredParticleSystemList (make_pair - (ups, rsGame)); - } - } - -// std::map damageParticleSystemsInUse; -// for(std::map::const_iterator iterMap = damageParticleSystemsInUse.begin(); -// iterMap != damageParticleSystemsInUse.end(); ++iterMap) { -// XmlNode *damageParticleSystemsInUseNode = unitNode->addChild("damageParticleSystemsInUse"); -// -// damageParticleSystemsInUseNode->addAttribute("key",intToStr(iterMap->first), mapTagReplacements); -// iterMap->second->saveGame(damageParticleSystemsInUseNode); -// } -// if(unitNode->hasChild("damageParticleSystemsInUse") == true) { -// XmlNode *damageParticleSystemsInUseNode = unitNode->getChild("damageParticleSystemsInUse"); -// vector damageParticleSystemsInUseNode2 = damageParticleSystemsInUseNode->getChildList("damageParticleSystemsInUse"); -// for(unsigned int i = 0; i < damageParticleSystemsInUseNode2.size(); ++i) { -// XmlNode *d2Node = damageParticleSystemsInUseNode2[i]; -// -// vector unitParticleSystemNodeList = damageParticleSystemsInUseNode->getChildList("UnitParticleSystem"); -// for(unsigned int i = 0; i < unitParticleSystemNodeList.size(); ++i) { -// XmlNode *node = unitParticleSystemNodeList[i]; -// -// UnitParticleSystem *ups = new UnitParticleSystem(); -// ups->loadGame(node); -// result->unitParticleSystems.push_back(ups); -// -// //Renderer::getInstance().manageParticleSystem(result->fire, rsGame); -// Renderer::getInstance().addToDeferredParticleSystemList(make_pair(ups, rsGame)); -// } -// -// } - -// vector fireParticleSystems; -// for(unsigned int i = 0; i < fireParticleSystems.size(); ++i) { -// ParticleSystem *ps= fireParticleSystems[i]; -// ps->saveGame(unitNode); -// } - if (unitNode->hasChild ("fireParticleSystems") == true) - { - XmlNode *fireParticleSystemsNode = - unitNode->getChild ("fireParticleSystems"); - - int linkFireIndex = -1; - if (fireParticleSystemsNode->hasAttribute ("fireParticleLink") == - true) - { - linkFireIndex = - fireParticleSystemsNode-> - getAttribute ("fireParticleLink")->getIntValue (); - } - - vector < XmlNode * >unitParticleSystemNodeList = - fireParticleSystemsNode->getChildList ("FireParticleSystem"); - for (int i = 0; i < (int) unitParticleSystemNodeList.size (); ++i) - { - XmlNode *node = unitParticleSystemNodeList[i]; - - if (result->fire == NULL || linkFireIndex != i) - { - FireParticleSystem *ups = new FireParticleSystem (); - ups->setParticleOwner (result); - ups->loadGame (node); - //ups->setTexture(CoreData::getInstance().getFireTexture()); - result->fireParticleSystems.push_back (ups); - - //printf("Load fire particle i = %d linkFireIndex = %d result->fire = %p ups = %p\n",i,linkFireIndex,result->fire,ups); - - if (result->fire == NULL && linkFireIndex >= 0 - && linkFireIndex == i) - { - result->fire = ups; - } - Renderer:: - getInstance ().addToDeferredParticleSystemList (make_pair - (ups, rsGame)); - } - } - } - -// vector smokeParticleSystems; -// for(unsigned int i = 0; i < smokeParticleSystems.size(); ++i) { -// UnitParticleSystem *ups= smokeParticleSystems[i]; -// ups->saveGame(unitNode); -// } - if (unitNode->hasChild ("smokeParticleSystems") == true) - { - XmlNode *smokeParticleSystemsNode = - unitNode->getChild ("smokeParticleSystems"); - vector < XmlNode * >unitParticleSystemNodeList = - smokeParticleSystemsNode->getChildList ("UnitParticleSystem"); - for (unsigned int i = 0; i < unitParticleSystemNodeList.size (); ++i) - { - XmlNode *node = unitParticleSystemNodeList[i]; - -// printf("Load Smoke particle i = %d\n",i); - UnitParticleSystem *ups = new UnitParticleSystem (); - ups->setParticleOwner (result); - ups->loadGame (node); - //ups->setTexture(CoreData::getInstance().getFireTexture()); - result->smokeParticleSystems.push_back (ups); - - Renderer:: - getInstance ().addToDeferredParticleSystemList (make_pair - (ups, rsGame)); - - //printf("Loading smoke particles:\n[%s]\n",ups->toString().c_str()); - } - } - -// CardinalDir modelFacing; -// unitNode->addAttribute("modelFacing",intToStr(modelFacing), mapTagReplacements); - -// std::string lastSynchDataString; -// unitNode->addAttribute("lastSynchDataString",lastSynchDataString, mapTagReplacements); -// std::string lastFile; -// unitNode->addAttribute("lastFile",lastFile, mapTagReplacements); -// int lastLine; -// unitNode->addAttribute("lastLine",intToStr(lastLine), mapTagReplacements); -// std::string lastSource; -// unitNode->addAttribute("lastSource",lastSource, mapTagReplacements); -// int lastRenderFrame; - result->lastRenderFrame = - unitNode->getAttribute ("lastRenderFrame")->getIntValue (); -// bool visible; - result->visible = - unitNode->getAttribute ("visible")->getIntValue () != 0; -// int retryCurrCommandCount; - result->retryCurrCommandCount = - unitNode->getAttribute ("retryCurrCommandCount")->getIntValue (); -// Vec3f screenPos; - result->screenPos = - Vec3f::strToVec3 (unitNode->getAttribute ("screenPos")->getValue ()); -// string currentUnitTitle; - result->currentUnitTitle = - unitNode->getAttribute ("currentUnitTitle")->getValue (); -// -// bool inBailOutAttempt; - result->inBailOutAttempt = - unitNode->getAttribute ("inBailOutAttempt")->getIntValue () != 0; -// //std::vector > badHarvestPosList; -// std::map badHarvestPosList; -// for(std::map::const_iterator iterMap = badHarvestPosList.begin(); -// iterMap != badHarvestPosList.end(); ++iterMap) { -// XmlNode *badHarvestPosListNode = unitNode->addChild("badHarvestPosList"); -// -// badHarvestPosListNode->addAttribute("key",iterMap->first.getString(), mapTagReplacements); -// badHarvestPosListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); -// } - -// //time_t lastBadHarvestListPurge; -// std::pair lastHarvestResourceTarget; - const XmlNode *lastHarvestResourceTargetNode = - unitNode->getChild ("lastHarvestResourceTarget"); -// lastHarvestResourceTargetNode->addAttribute("key",lastHarvestResourceTarget.first.getString(), mapTagReplacements); -// lastHarvestResourceTargetNode->addAttribute("value",intToStr(lastHarvestResourceTarget.second), mapTagReplacements); - - result->lastHarvestResourceTarget = - make_pair (Vec2i::strToVec2 - (lastHarvestResourceTargetNode->getAttribute ("key")-> - getValue ()), - lastHarvestResourceTargetNode-> - getAttribute ("value")->getIntValue ()); - -// //std::pair > currentTargetPathTaken; -// static Game *game; -// -// bool ignoreCheckCommand; - result->ignoreCheckCommand = - unitNode->getAttribute ("ignoreCheckCommand")->getIntValue () != 0; -// uint32 lastStuckFrame; - result->lastStuckFrame = - unitNode->getAttribute ("lastStuckFrame")->getIntValue (); -// Vec2i lastStuckPos; - result->lastStuckPos = - Vec2i::strToVec2 (unitNode-> - getAttribute ("lastStuckPos")->getValue ()); -// uint32 lastPathfindFailedFrame; - result->lastPathfindFailedFrame = - unitNode->getAttribute ("lastPathfindFailedFrame")->getIntValue (); -// Vec2i lastPathfindFailedPos; - result->lastPathfindFailedPos = - Vec2i::strToVec2 (unitNode-> - getAttribute ("lastPathfindFailedPos")->getValue - ()); -// bool usePathfinderExtendedMaxNodes; - result->usePathfinderExtendedMaxNodes = - unitNode-> - getAttribute ("usePathfinderExtendedMaxNodes")->getIntValue () != 0; -// int maxQueuedCommandDisplayCount; - result->maxQueuedCommandDisplayCount = - unitNode-> - getAttribute ("maxQueuedCommandDisplayCount")->getIntValue (); -// UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect; - - // !!! TODO: Softcoder - in progress work to load attack boosts, not working properly yet - result->currentAttackBoostOriginatorEffect.loadGame (unitNode, result, - world); - -// std::vector currentAttackBoostEffects; -// for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) { -// UnitAttackBoostEffect *uabe= currentAttackBoostEffects[i]; -// uabe->saveGame(unitNode); -// } - - // !!! TODO: Softcoder - in progress work to load attack boosts, not working properly yet - if (unitNode->hasChild ("UnitAttackBoostEffect") == true) - { - vector < XmlNode * >unitParticleSystemNodeList = - unitNode->getChildList ("UnitAttackBoostEffect"); - for (unsigned int i = 0; i < unitParticleSystemNodeList.size (); ++i) - { - XmlNode *node = unitParticleSystemNodeList[i]; - - UnitAttackBoostEffect *attackBoostEffect = - new UnitAttackBoostEffect (); - attackBoostEffect->loadGame (node, result, world, false); - - result->currentAttackBoostEffects.push_back (attackBoostEffect); - } - } - //printf("Unit [%d - %s] has currentAttackBoostEffects count: %d\n",result->getId(),result->getType()->getName(false).c_str(),(int)result->currentAttackBoostEffects.size()); - - -// Mutex *mutexCommands; -// -// //static Mutex mutexDeletedUnits; -// //static std::map deletedUnits; -// -// bool changedActiveCommand; - result->changedActiveCommand = - unitNode->getAttribute ("changedActiveCommand")->getIntValue () != 0; -// int lastAttackerUnitId; - result->lastAttackerUnitId = - unitNode->getAttribute ("lastAttackerUnitId")->getIntValue (); -// int lastAttackedUnitId; - result->lastAttackedUnitId = - unitNode->getAttribute ("lastAttackedUnitId")->getIntValue (); -// CauseOfDeathType causeOfDeath; - result->causeOfDeath = - static_cast < CauseOfDeathType > - (unitNode->getAttribute ("causeOfDeath")->getIntValue ()); - - result->pathfindFailedConsecutiveFrameCount = - unitNode-> - getAttribute ("pathfindFailedConsecutiveFrameCount")->getIntValue (); - - if (result->alive) - { - world->getMapPtr ()->putUnitCells (result, newUnitPos); - //result->born(); - } - - result->pos = newUnitPos; - result->lastPos = - Vec2i::strToVec2 (unitNode->getAttribute ("lastPos")->getValue ()); - result->meetingPos = - Vec2i::strToVec2 (unitNode->getAttribute ("meetingPos")->getValue ()); - - if (unitNode->hasAttribute ("currentPathFinderDesiredFinalPos")) - { - result->currentPathFinderDesiredFinalPos = - Vec2i::strToVec2 (unitNode->getAttribute - ("currentPathFinderDesiredFinalPos")->getValue - ()); - } - - if (unitNode->hasAttribute ("random")) - { - result->random.setLastNumber (unitNode-> - getAttribute ("random")->getIntValue - ()); - } - if (unitNode->hasAttribute ("pathFindRefreshCellCount")) - { - result->pathFindRefreshCellCount = - unitNode->getAttribute ("pathFindRefreshCellCount")->getIntValue (); - } - - //result->exploreCells(); - //result->calculateFogOfWarRadius(); - - return result; - } - - Checksum Unit::getCRC () - { - const bool consoleDebug = false; - - Checksum crcForUnit; - - crcForUnit.addInt (id); - crcForUnit.addInt (hp); - crcForUnit.addInt (ep); - crcForUnit.addInt (loadCount); - crcForUnit.addInt (deadCount); - - if (consoleDebug) - printf ("#1 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - - crcForUnit.addInt64 (progress); - crcForUnit.addInt64 (lastAnimProgress); - crcForUnit.addInt64 (animProgress); - - if (consoleDebug) - printf ("#2 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - - //float highlight; - crcForUnit.addInt (progress2); - crcForUnit.addInt (kills); - crcForUnit.addInt (enemyKills); - crcForUnit.addInt (morphFieldsBlocked); - - if (consoleDebug) - printf ("#3 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - - //UnitReference targetRef; - - crcForUnit.addInt (currField); - crcForUnit.addInt (targetField); - - if (consoleDebug) - printf ("#4 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - - //const Level *level; - if (level != NULL) - { - crcForUnit.addString (level->getName (false)); - } - - if (consoleDebug) - printf ("#5 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - - crcForUnit.addInt (pos.x); - crcForUnit.addInt (pos.y); - crcForUnit.addInt (lastPos.x); - crcForUnit.addInt (lastPos.y); - crcForUnit.addInt (targetPos.x); - crcForUnit.addInt (targetPos.y); - - if (consoleDebug) - printf ("#6 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - - //Vec3f targetVec; - - crcForUnit.addInt (meetingPos.x); - crcForUnit.addInt (meetingPos.y); - - if (consoleDebug) - printf ("#7 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - - //float lastRotation; - //float targetRotation; - //float rotation; - //float targetRotationZ; - //float targetRotationX; - //float rotationZ; - //float rotationX; - - //const UnitType *preMorph_type; - if (preMorph_type != NULL) - { - crcForUnit.addString (preMorph_type->getName (false)); - } - - if (consoleDebug) - printf ("#8 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - - //const UnitType *type; - if (type != NULL) - { - crcForUnit.addString (type->getName (false)); - } - - //const ResourceType *loadType; - if (loadType != NULL) - { - crcForUnit.addString (loadType->getName (false)); - } - - //const SkillType *currSkill; - if (currSkill != NULL) - { - crcForUnit.addString (currSkill->getName ()); - } - - //printf("#9 Unit: %d CRC: %u lastModelIndexForCurrSkillType: %d\n",id,crcForUnit.getSum(),lastModelIndexForCurrSkillType); - //printf("#9a Unit: %d CRC: %u\n",id,crcForUnit.getSum()); - //crcForUnit.addInt(lastModelIndexForCurrSkillType); - if (consoleDebug) - printf ("#9 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); + delete this->unitPath; + this->unitPath = NULL; - //crcForUnit.addInt(animationRandomCycleCount); - //printf("#9b Unit: %d CRC: %u\n",id,crcForUnit.getSum()); + Renderer & renderer = Renderer::getInstance(); + renderer.removeUnitFromQuadCache(this); + if (game != NULL) { + game->removeUnitFromSelection(this); + } - crcForUnit.addInt (toBeUndertaken); + //MutexSafeWrapper safeMutex1(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__)); + //deletedUnits[this]=true; - if (consoleDebug) - printf ("#9c Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - - crcForUnit.addInt (alive); - //bool showUnitParticles; + delete mutexCommands; + mutexCommands = NULL; - if (consoleDebug) - printf ("#10 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); +#ifdef LEAK_CHECK_UNITS + Unit::mapMemoryList.erase(this); +#endif + } - //Faction *faction; - //ParticleSystem *fire; - if (fire != NULL) - { - crcForUnit.addInt (fire->getActive ()); - } - - //TotalUpgrade totalUpgrade; - uint32 crc = totalUpgrade.getCRC ().getSum (); - crcForUnit.addBytes (&crc, sizeof (uint32)); + void Unit::cleanupAllParticlesystems() { - //Map *map; - //UnitPathInterface *unitPath; - if (unitPath != NULL) - { - uint32 crc = unitPath->getCRC ().getSum (); - crcForUnit.addBytes (&crc, sizeof (uint32)); - } - //WaypointPath waypointPath; + Renderer:: + getInstance().cleanupUnitParticleSystems(unitParticleSystems, + rsGame); - if (consoleDebug) - printf ("#11 Unit: %d CRC: %u commands.size(): " MG_SIZE_T_SPECIFIER - "\n", id, crcForUnit.getSum (), commands.size ()); + Renderer::getInstance().cleanupParticleSystems(fireParticleSystems, + rsGame); + // Must set this to null of it will be used below in stopDamageParticles() - //Commands commands; - if (commands.empty () == false) - { - crcForUnit.addInt ((int) commands.size ()); - for (Commands::const_iterator it = commands.begin (); - it != commands.end (); ++it) - { - uint32 crc = (*it)->getCRC ().getSum (); - crcForUnit.addBytes (&crc, sizeof (uint32)); - } - } + if (Renderer:: + getInstance().validateParticleSystemStillExists(this->fire, + rsGame) == false) { + this->fire = NULL; + } - //printf("#11 Unit: %d CRC: %u observers.size(): %ld\n",id,crcForUnit.getSum(),observers.size()); + // fade(and by this remove) all unit particle systems + queuedUnitParticleSystemTypes.clear(); + while (unitParticleSystems.empty() == false) { + if (Renderer:: + getInstance().validateParticleSystemStillExists + (unitParticleSystems.back(), rsGame) == true) { + unitParticleSystems.back()->fade(); + } + unitParticleSystems.pop_back(); + } + stopDamageParticles(true); - //Observers observers; - //crcForUnit.addInt64((int64)observers.size()); + } - if (consoleDebug) - printf ("#11 Unit: %d CRC: %u damageParticleSystems.size(): " - MG_SIZE_T_SPECIFIER "\n", id, crcForUnit.getSum (), - damageParticleSystems.size ()); + ParticleSystem *Unit::getFire() const { + if (this->fire != NULL && + Renderer::getInstance(). + validateParticleSystemStillExists(this->fire, rsGame) == false) { + return NULL; + } + return this->fire; + } - //vector unitParticleSystems; - //vector queuedUnitParticleSystemTypes; + void Unit::setType(const UnitType * newType) { + this->faction->notifyUnitTypeChange(this, newType); + this->type = newType; + } - //UnitParticleSystems damageParticleSystems; - crcForUnit.addInt ((int) damageParticleSystems.size ()); + void Unit::setAlive(bool value) { + this->alive = value; + this->faction->notifyUnitAliveStatusChange(this); + } - if (consoleDebug) - printf ("#12 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); +#ifdef LEAK_CHECK_UNITS + void Unit::dumpMemoryList() { + printf("===== START report of Unfreed Unit pointers =====\n"); + for (std::map < Unit *, bool >::iterator iterMap = + Unit::mapMemoryList.begin(); + iterMap != Unit::mapMemoryList.end(); ++iterMap) { + printf("************** ==> Unfreed Unit pointer [%p]\n", + iterMap->first); + } + } +#endif - //std::map damageParticleSystemsInUse; + bool Unit::isNetworkCRCEnabled() { + bool isNetworkCRCEnabled = false; - //vector fireParticleSystems; - //vector smokeParticleSystems; - - //CardinalDir modelFacing; - crcForUnit.addInt (modelFacing); - - //std::string lastSynchDataString; - //std::string lastFile; - //int lastLine; - //std::string lastSource; - //int lastRenderFrame; - //bool visible; - - //int retryCurrCommandCount; - - //Vec3f screenPos; - //string currentUnitTitle; - - if (consoleDebug) - printf ("#13 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); + if (game != NULL) { + if (game->isFlagType1BitEnabled(ft1_network_synch_checks_verbose) == + true) { + isNetworkCRCEnabled = true; + } else if (game->isFlagType1BitEnabled(ft1_network_synch_checks) == + true) { + isNetworkCRCEnabled = true; + } + } + return isNetworkCRCEnabled; + } - crcForUnit.addInt (inBailOutAttempt); - - crcForUnit.addInt ((int) badHarvestPosList.size ()); - //crcForUnit.addInt(lastHarvestResourceTarget.first()); + void Unit::clearNetworkCRCDecHpList() { + if (networkCRCDecHpList.empty() == false) { + networkCRCDecHpList.clear(); + } + } + void Unit::clearParticleInfo() { + if (networkCRCParticleInfoList.empty() == false) { + networkCRCParticleInfoList.clear(); + } + } - if (consoleDebug) - printf ("#14 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); + void Unit::addNetworkCRCDecHp(string info) { + if (isNetworkCRCEnabled() == true) { + networkCRCDecHpList.push_back(info); + } + } - //static Game *game; - //bool ignoreCheckCommand; - - //uint32 lastStuckFrame; - crcForUnit.addUInt (lastStuckFrame); - //Vec2i lastStuckPos; - crcForUnit.addInt (lastStuckPos.x); - crcForUnit.addInt (lastStuckPos.y); - - //uint32 lastPathfindFailedFrame; - //Vec2i lastPathfindFailedPos; - //bool usePathfinderExtendedMaxNodes; - //int maxQueuedCommandDisplayCount; - - //UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect; - crcForUnit. - addInt ((int) - currentAttackBoostOriginatorEffect.currentAttackBoostUnits. - size ()); - - if (consoleDebug) - printf ("#15 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - - //std::vector currentAttackBoostEffects; - - //Mutex *mutexCommands; - - //bool changedActiveCommand; - - //int lastAttackerUnitId; - //int lastAttackedUnitId; - //CauseOfDeathType causeOfDeath; + void Unit::logParticleInfo(string info) { + if (isNetworkCRCEnabled() == true) { + networkCRCParticleInfoList.push_back(info); + } + } + string Unit::getParticleInfo() const { + string result = ""; + if (networkCRCParticleInfoList.empty() == false) { + for (unsigned int index = 0; + index < networkCRCParticleInfoList.size(); ++index) { + result += networkCRCParticleInfoList[index] + "|"; + } + } + return result; + } - //uint32 pathfindFailedConsecutiveFrameCount; - crcForUnit.addString (this-> - currentPathFinderDesiredFinalPos.getString ()); + void Unit::end(ParticleSystem * particleSystem) { + if (particleSystem == fire) { + fire = NULL; + } - crcForUnit.addInt (random.getLastNumber ()); - if (this->random.getLastCaller () != "") - { - crcForUnit.addString (this->random.getLastCaller ()); - } + vector < ParticleSystem * >::iterator iterFind = + find(attackParticleSystems.begin(), attackParticleSystems.end(), + particleSystem); + if (iterFind != attackParticleSystems.end()) { + attackParticleSystems.erase(iterFind); + return; + } + vector < UnitParticleSystem * >::iterator iterFind1 = + find(smokeParticleSystems.begin(), smokeParticleSystems.end(), + particleSystem); + if (iterFind1 != smokeParticleSystems.end()) { + smokeParticleSystems.erase(iterFind1); + return; + } + iterFind = + find(fireParticleSystems.begin(), fireParticleSystems.end(), + particleSystem); + if (iterFind != fireParticleSystems.end()) { + fireParticleSystems.erase(iterFind); + return; + } + iterFind1 = + find(damageParticleSystems.begin(), damageParticleSystems.end(), + particleSystem); + if (iterFind1 != damageParticleSystems.end()) { + damageParticleSystems.erase(iterFind1); + return; + } - if (consoleDebug) - printf ("#16 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); + iterFind1 = + find(unitParticleSystems.begin(), unitParticleSystems.end(), + particleSystem); + if (iterFind1 != unitParticleSystems.end()) { + unitParticleSystems.erase(iterFind1); + return; + } + } - //int pathFindRefreshCellCount; + //bool Unit::isUnitDeleted(void *unit) { + // bool result = false; + // MutexSafeWrapper safeMutex(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__)); + // if(deletedUnits.find(unit) != deletedUnits.end()) { + // result = true; + // } + // return result; + //} - //FowAlphaCellsLookupItem cachedFow; - //Vec2i cachedFowPos; + void Unit::setModelFacing(CardinalDir value) { + modelFacing = value; + lastRotation = targetRotation = rotation = value * 90.f; + } - crcForUnit.addInt (lastHarvestedResourcePos.x); - crcForUnit.addInt (lastHarvestedResourcePos.y); + //void Unit::setCurrField(Field currField) { + // Field original_field = this->currField; + // + // this->currField = currField; + // + // if(original_field != this->currField) { + // //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + // game->getScriptManager()->onUnitTriggerEvent(this,utet_FieldChanged); + // //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + // } + //} + // ====================================== get ====================================== - if (consoleDebug) - printf ("#17 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); + Vec2i Unit::getCenteredPos() const { + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands, mutexOwnerId); - if (this->getParticleInfo () != "") - { - crcForUnit.addString (this->getParticleInfo ()); - } + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } - crcForUnit.addInt ((int) attackParticleSystems.size ()); - if (isNetworkCRCEnabled () == true) - { - for (unsigned int index = 0; index < attackParticleSystems.size (); - ++index) - { - ParticleSystem *ps = attackParticleSystems[index]; - if (ps != NULL && - Renderer::getInstance ().validateParticleSystemStillExists (ps, - rsGame) - == true) - { - uint32 crc = ps->getCRC ().getSum (); - crcForUnit.addBytes (&crc, sizeof (uint32)); - } - } - } + return pos + Vec2i(type->getSize() / 2, type->getSize() / 2); + } - if (this->networkCRCParticleLogInfo != "") - { - crcForUnit.addString (this->networkCRCParticleLogInfo); - } + Vec2f Unit::getFloatCenteredPos() const { + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands, mutexOwnerId); - return crcForUnit; - } + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } - } -} //end namespace + return Vec2f(truncateDecimal < + float >(pos.x - 0.5f + type->getSize() / 2.f, 6), + truncateDecimal < + float >(pos.y - 0.5f + type->getSize() / 2.f, 6)); + } + + Vec2i Unit::getCellPos() const { + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + if (type->hasCellMap()) { + if (type->hasEmptyCellMap() == false || + type->getAllowEmptyCellMap() == true) { + + //find nearest pos to center that is free + Vec2i centeredPos = getCenteredPos(); + float nearestDist = -1.f; + Vec2i nearestPos = pos; + + for (int i = 0; i < type->getSize(); ++i) { + for (int j = 0; j < type->getSize(); ++j) { + if (type->getCellMapCell(i, j, modelFacing)) { + Vec2i currPos = pos + Vec2i(i, j); + float dist = currPos.dist(centeredPos); + if (nearestDist == -1.f || dist < nearestDist) { + nearestDist = dist; + nearestPos = currPos; + } + } + } + } + return nearestPos; + } + } + return pos; + } + + + + void Unit::calculateXZRotation() { + //if(type->getProperty(UnitType::pRotatedClimb) && currSkill->getClass()==scMove){ + //if(currSkill->getClass()==scMove) + if (lastPos != pos) { // targetPosCalc ( maybe also sometimes needed if no move ? terrain flatting... ) + SurfaceCell *sc = map->getSurfaceCell(Map::toSurfCoords(pos)); + const Vec3f normal = sc->getNormal(); + +#ifdef USE_STREFLOP + targetRotationZ = + radToDeg(streflop::atan2 + (static_cast (abs(normal.x)), + static_cast (abs(normal.y)))); +#else + targetRotationZ = radToDeg(atan2(abs(normal.x), abs(normal.y))); +#endif + + if ((normal.y < 0 || normal.x < 0) && !(normal.y < 0 && normal.x < 0)) { + targetRotationZ = targetRotationZ * -1; + } + targetRotationZ = targetRotationZ * -1; + +#ifdef USE_STREFLOP + targetRotationX = + radToDeg(streflop::atan2 + (static_cast (abs(normal.z)), + static_cast (abs(normal.y)))); +#else + targetRotationX = radToDeg(atan2(abs(normal.z), abs(normal.y))); +#endif + + if ((normal.y < 0 || normal.z < 0) && !(normal.y < 0 && normal.z < 0)) { + targetRotationX = targetRotationX * -1; + } + } + + //For smooth rotation we now softly adjust the angle + int adjustStep = 1; + if (rotationZ < targetRotationZ) { + if (rotationZ + adjustStep > targetRotationZ) { + rotationZ = targetRotationZ; + } else { + rotationZ = rotationZ + adjustStep; + } + } else if (rotationZ > targetRotationZ) { + if (rotationZ - adjustStep < targetRotationZ) { + rotationZ = targetRotationZ; + } else { + rotationZ = rotationZ - adjustStep; + } + } + + if (rotationX < targetRotationX) { + if (rotationX + adjustStep > targetRotationX) { + rotationX = targetRotationX; + } else { + rotationX = rotationX + adjustStep; + } + } else if (rotationX > targetRotationX) { + if (rotationX - adjustStep < targetRotationX) { + rotationX = targetRotationX; + } else { + rotationX = rotationX - adjustStep; + } + } + } + + float Unit::getRotationZ() const { + return rotationZ; + } + + float Unit::getRotationX() const { + return rotationX; + } + + int Unit::getProductionPercent() const { + if (anyCommand()) { + const ProducibleType *produced = + commands.front()->getCommandType()->getProduced(); + if (produced != NULL) { + if (produced->getProductionTime() == 0) { + return 0; + } + return clamp(progress2 * 100 / produced->getProductionTime(), 0, + 100); + } + } + return -1; + } + + float Unit::getProgressRatio() const { + if (anyCommand()) { + const ProducibleType *produced = + commands.front()->getCommandType()->getProduced(); + if (produced != NULL) { + if (produced->getProductionTime() == 0) { + return 0.f; + } + + float help = progress2; + return clamp(help / produced->getProductionTime(), 0.f, 1.f); + } + } + return -1; + } + + float Unit::getHpRatio() const { + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + float maxHpAllowed = type->getTotalMaxHp(&totalUpgrade); + if (maxHpAllowed == 0.f) { + return 0.f; + } + return clamp(static_cast (hp) / maxHpAllowed, 0.f, 1.f); + } + + float Unit::getEpRatio() const { + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + if (type->getTotalMaxHp(&totalUpgrade) == 0) { + return 0.f; + } else { + float maxEpAllowed = type->getTotalMaxEp(&totalUpgrade); + if (maxEpAllowed == 0.f) { + return 0.f; + } + return clamp(static_cast (ep) / maxEpAllowed, 0.f, 1.f); + } + } + + const Level *Unit::getNextLevel() const { + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + if (level == NULL && type->getLevelCount() > 0) { + return type->getLevel(0); + } else { + for (int i = 1; i < type->getLevelCount(); ++i) { + if (type->getLevel(i - 1) == level) { + return type->getLevel(i); + } + } + } + return NULL; + } + + string Unit::getFullName(bool translatedValue) const { + string str = ""; + if (level != NULL) { + str += (level->getName(translatedValue) + " "); + } + if (type == NULL) { + throw + megaglest_runtime_error("type == NULL in Unit::getFullName()!"); + } + str += type->getName(translatedValue); + return str; + } + + // ====================================== is ====================================== + + bool Unit::isOperative() const { + return isAlive() && isBuilt(); + } + + bool Unit::isAnimProgressBound() const { + if (currSkill == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + bool result = false; + if (currSkill->getClass() == scBeBuilt) { + const BeBuiltSkillType *skill = + dynamic_cast (currSkill); + if (skill != NULL) { + result = skill->getAnimProgressBound(); + } + } else if (currSkill->getClass() == scProduce) { + const ProduceSkillType *skill = + dynamic_cast (currSkill); + if (skill != NULL) { + result = skill->getAnimProgressBound(); + } + } else if (currSkill->getClass() == scUpgrade) { + const UpgradeSkillType *skill = + dynamic_cast (currSkill); + if (skill != NULL) { + result = skill->getAnimProgressBound(); + } + } else if (currSkill->getClass() == scMorph) { + const MorphSkillType *skill = + dynamic_cast (currSkill); + if (skill != NULL) { + result = skill->getAnimProgressBound(); + } + } + return result; + } + + bool Unit::isBeingBuilt() const { + if (currSkill == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + return (currSkill->getClass() == scBeBuilt); + } + + bool Unit::isBuilt() const { + return (isBeingBuilt() == false); + } + + bool Unit::isBuildCommandPending() const { + bool result = false; + + Command *command = this->getCurrCommand(); + if (command != NULL) { + const BuildCommandType *bct = + dynamic_cast < + const BuildCommandType *>(command->getCommandType()); + if (bct != NULL) { + if (this->getCurrSkill()->getClass() != scBuild) { + result = true; + } + } + } + + return result; + } + + UnitBuildInfo Unit::getBuildCommandPendingInfo() const { + UnitBuildInfo result; + + Command *command = this->getCurrCommand(); + if (command != NULL) { + const BuildCommandType *bct = + dynamic_cast < + const BuildCommandType *>(command->getCommandType()); + if (bct != NULL) { + result.pos = command->getOriginalPos(); + result.facing = command->getFacing(); + result.buildUnit = command->getUnitType(); + result.unit = this; + } + } + + return result; + } + + bool Unit::isAlly(const Unit * unit) const { + if (unit == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: unit == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + return faction->isAlly(unit->getFaction()); + } + + bool Unit::isDamaged() const { + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + return hp < type->getTotalMaxHp(&totalUpgrade); + } + + bool Unit::isInteresting(InterestingUnitType iut) const { + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + switch (iut) { + case iutIdleHarvester: + if (type->hasCommandClass(ccHarvest)) { + if (commands.empty() == false) { + const CommandType *ct = commands.front()->getCommandType(); + if (ct != NULL) { + return ct->getClass() == ccStop; + } + } + } + return false; + + case iutBuiltBuilding: + return type->hasSkillClass(scBeBuilt) && isBuilt(); + case iutProducer: + return type->hasSkillClass(scProduce); + case iutDamaged: + return isDamaged(); + case iutStore: + return type->getStoredResourceCount() > 0; + default: + return false; + } + } + + // ====================================== set ====================================== + + void Unit::setCurrSkill(const SkillType * currSkill) { + if (currSkill == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + if (this->currSkill == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: this->currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + if (this->currSkill->getClass() == scMove && + currSkill->getClass() != scMove) { + faction->removeUnitFromMovingList(this->getId()); + } else if (this->currSkill->getClass() != scMove && + currSkill->getClass() == scMove) { + faction->addUnitToMovingList(this->getId()); + } + + changedActiveCommand = false; + if (currSkill->getClass() != this->currSkill->getClass() || + currSkill->getName() != this->currSkill->getName()) { + this->animProgress = 0; + this->lastAnimProgress = 0; + + queuedUnitParticleSystemTypes.clear(); + while (unitParticleSystems.empty() == false) { + if (Renderer:: + getInstance().validateParticleSystemStillExists + (unitParticleSystems.back(), rsGame) == true) { + unitParticleSystems.back()->fade(); + } + unitParticleSystems.pop_back(); + } + + Command *cmd = getCurrrentCommandThreadSafe(); + + // Set mew fog of war skill type if need be + if (cmd != NULL && cmd->getCommandType() != NULL && + cmd->getCommandType()-> + hasFogOfWarSkillType(currSkill->getName())) { + const FogOfWarSkillType *fowst = + cmd->getCommandType()->getFogOfWarSkillType(); + + // Remove old fog of war skill type if need be + game->getWorld()->removeFogOfWarSkillTypeFromList(this); + + game->getWorld()->addFogOfWarSkillType(this, fowst); + } else { + // Remove old fog of war skill type if need be + game->getWorld()->removeFogOfWarSkillType(this); + } + } + if (showUnitParticles == true && + currSkill->unitParticleSystemTypes.empty() == false && + unitParticleSystems.empty() == true) { + //printf("START - particle system type\n"); + + /* + for(UnitParticleSystemTypes::const_iterator it= currSkill->unitParticleSystemTypes.begin(); + it != currSkill->unitParticleSystemTypes.end(); ++it) { + if((*it)->getStartTime() == 0.0) { + //printf("Adding NON-queued particle system type [%s] [%f] [%f]\n",(*it)->getType().c_str(),(*it)->getStartTime(),(*it)->getEndTime()); + + UnitParticleSystem *ups = new UnitParticleSystem(200); + ups->setParticleOwner(this); + ups->setParticleType((*it)); + + (*it)->setValues(ups); + ups->setPos(getCurrVector()); + ups->setRotation(getRotation()); + ups->setUnitModel(getCurrentModelPtr()); + if(getFaction()->getTexture()) { + ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); + } + unitParticleSystems.push_back(ups); + Renderer::getInstance().manageParticleSystem(ups, rsGame); + } + else { + //printf("Adding queued particle system type [%s] [%f] [%f]\n",(*it)->getType().c_str(),(*it)->getStartTime(),(*it)->getEndTime()); + + queuedUnitParticleSystemTypes.push_back(*it); + } + } + */ + checkCustomizedUnitParticleListTriggers + (currSkill->unitParticleSystemTypes, true); + } + + if (this->currSkill != currSkill) { + this->lastModelIndexForCurrSkillType = -1; + this->animationRandomCycleCount = 0; + } + + if (faction != NULL) + faction->notifyUnitSkillTypeChange(this, currSkill); + const SkillType *original_skill = this->currSkill; + this->currSkill = currSkill; + + if (original_skill != this->currSkill) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_SkillChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + } + + void Unit::setCurrSkill(SkillClass sc) { + if (getType() == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: getType() == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + setCurrSkill(getType()->getFirstStOfClass(sc)); + } + + void Unit::setTarget(const Unit * unit) { + + if (unit == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: unit == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + //find a free pos in cellmap + setTargetPos(unit->getCellPos()); + + //ser field and vector + targetField = unit->getCurrField(); + targetVec = unit->getCurrVectorAsTarget(); + targetRef = unit; + } + + RandomGen *Unit::getRandom(bool threadAccessAllowed) { + if (threadAccessAllowed == false + && Thread::isCurrentThreadMainThread() == false) { + throw + megaglest_runtime_error + ("Invalid access to unit random from outside main thread current id = " + + intToStr(Thread::getCurrentThreadId()) + " main = " + + intToStr(Thread::getMainThreadId())); + } + return &random; + } + + void Unit::setPos(const Vec2i & pos, bool clearPathFinder, bool threaded) { + if (map->isInside(pos) == false + || map->isInsideSurface(map->toSurfCoords(pos)) == false) { + throw megaglest_runtime_error("#3 Invalid path position = " + + pos.getString()); + } + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands, mutexOwnerId); + + if (threaded) { + logSynchDataThreaded(extractFileFromDirectoryPath(__FILE__).c_str + (), __LINE__); + } else { + logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), + __LINE__); + } + + if (clearPathFinder == true && this->unitPath != NULL) { + this->unitPath->clear(); + } + //Vec2i oldLastPos = this->lastPos; + this->lastPos = this->pos; + this->pos = pos; + + map->clampPos(this->pos); + this->meetingPos = pos - Vec2i(1); + map->clampPos(this->meetingPos); + + safeMutex.ReleaseLock(); + + refreshPos(); + + if (threaded) { + logSynchDataThreaded(extractFileFromDirectoryPath(__FILE__).c_str + (), __LINE__); + } else { + logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), + __LINE__); + } + } + + void Unit::refreshPos(bool forceRefresh) { + // Attempt to improve performance + this->exploreCells(forceRefresh); + calculateFogOfWarRadius(forceRefresh); + } + + FowAlphaCellsLookupItem Unit::getFogOfWarRadius(bool useCache) const { + if (useCache == true) { + return cachedFow; + } + + //iterate through all cells + int sightRange = + this->getType()->getTotalSight(this->getTotalUpgrade()); + int radius = sightRange + World::indirectSightRange; + PosCircularIterator pci(map, this->getPosNotThreadSafe(), radius); + FowAlphaCellsLookupItem result; + while (pci.next()) { + const Vec2i sightpos = pci.getPos(); + Vec2i surfPos = Map::toSurfCoords(sightpos); + + //compute max alpha + float maxAlpha = 0.0f; + if (surfPos.x > 1 && surfPos.y > 1 && + surfPos.x < map->getSurfaceW() - 2 && + surfPos.y < map->getSurfaceH() - 2) { + maxAlpha = 1.f; + } else if (surfPos.x > 0 && surfPos.y > 0 && + surfPos.x < map->getSurfaceW() - 1 && + surfPos.y < map->getSurfaceH() - 1) { + maxAlpha = 0.3f; + } + + //compute alpha + float alpha = maxAlpha; + float dist = this->getPosNotThreadSafe().dist(sightpos); + if (dist > sightRange) { + alpha = + clamp(1.f - (dist - sightRange) / (World::indirectSightRange), + 0.f, maxAlpha); + } + result.surfPosAlphaList[surfPos] = alpha; + } + return result; + } + + void Unit::calculateFogOfWarRadius(bool forceRefresh) { + if (game->getWorld()->getFogOfWar() == true) { + if (forceRefresh || this->pos != this->cachedFowPos) { + cachedFow = getFogOfWarRadius(false); + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands, mutexOwnerId); + this->cachedFowPos = this->pos; + } + } + } + + void Unit::setTargetPos(const Vec2i & targetPos, bool threaded) { + + if (map->isInside(targetPos) == false + || map->isInsideSurface(map->toSurfCoords(targetPos)) == false) { + throw megaglest_runtime_error("#4 Invalid path position = " + + targetPos.getString()); + } + + Vec2i relPos = targetPos - pos; + //map->clampPos(relPos); + + Vec2f relPosf = Vec2f((float) relPos.x, (float) relPos.y); +#ifdef USE_STREFLOP + targetRotation = + radToDeg(streflop::atan2 + (static_cast (relPosf.x), + static_cast (relPosf.y))); +#else + targetRotation = radToDeg(atan2(relPosf.x, relPosf.y)); +#endif + targetRotation = truncateDecimal < float >(targetRotation, 6); + + targetRef = NULL; + + this->targetPos = targetPos; + map->clampPos(this->targetPos); + + if (threaded) { + logSynchDataThreaded(extractFileFromDirectoryPath(__FILE__).c_str + (), __LINE__); + } else { + logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), + __LINE__); + } + } + + void Unit::addAttackParticleSystem(ParticleSystem * ps) { + attackParticleSystems.push_back(ps); + } + + void Unit::setVisible(const bool visible) { + this->visible = visible; + + if (unitParticleSystems.empty() == false) { + for (UnitParticleSystems::iterator it = unitParticleSystems.begin(); + it != unitParticleSystems.end(); ++it) { + if (Renderer:: + getInstance().validateParticleSystemStillExists((*it), + rsGame) == + true) { + (*it)->setVisible(visible); + } + } + } + if (damageParticleSystems.empty() == false) { + for (UnitParticleSystems::iterator it = + damageParticleSystems.begin(); + it != damageParticleSystems.end(); ++it) { + if (Renderer:: + getInstance().validateParticleSystemStillExists((*it), + rsGame) == + true) { + (*it)->setVisible(visible); + } + } + } + if (smokeParticleSystems.empty() == false) { + for (UnitParticleSystems::iterator it = smokeParticleSystems.begin(); + it != smokeParticleSystems.end(); ++it) { + if (Renderer:: + getInstance().validateParticleSystemStillExists((*it), + rsGame) == + true) { + if ((*it)->getVisible() != visible) { + //printf("Changing visibility for smoke particle system to: %d\n",visible); + (*it)->setVisible(visible); + } + } + } + } + + //if(attackParticleSystems.empty() == false) { + // for(vector::iterator it= attackParticleSystems.begin(); it != attackParticleSystems.end(); ++it) { + // if(Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame) == true) { + // Not sure this is a good idea since the unit be not be visible but the attack particle might be. + // This means you won't see the attacking projectile until the unit moves into view. + //(*it)->setVisible(visible); + // } + // } + //} + + if (currentAttackBoostEffects.empty() == false) { + for (unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) { + UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; + if (effect != NULL && effect->ups != NULL) { + bool particleValid = + Renderer:: + getInstance().validateParticleSystemStillExists(effect->ups, + rsGame); + if (particleValid == true) { + effect->ups->setVisible(visible); + } + } + } + } + if (currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) { + if (currentAttackBoostOriginatorEffect.currentAppliedEffect->ups != + NULL) { + bool particleValid = + Renderer::getInstance().validateParticleSystemStillExists + (currentAttackBoostOriginatorEffect.currentAppliedEffect->ups, + rsGame); + if (particleValid == true) { + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups->setVisible(visible); + } + } + } + } + + // =============================== Render related ================================== + + Model *Unit::getCurrentModelPtr() { + if (currSkill == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + int currentModelIndexForCurrSkillType = lastModelIndexForCurrSkillType; + Model *result = + currSkill->getAnimation(getAnimProgressAsFloat(), this, + &lastModelIndexForCurrSkillType, + &animationRandomCycleCount); + if (currentModelIndexForCurrSkillType != lastModelIndexForCurrSkillType) { + animationRandomCycleCount++; + if (currSkill != NULL + && animationRandomCycleCount >= currSkill->getAnimationCount()) { + animationRandomCycleCount = 0; + } + } + return result; + } + + //const Model *Unit::getCurrentModel() { + // if(currSkill == NULL) { + // char szBuf[8096]=""; + // snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); + // throw megaglest_runtime_error(szBuf); + // } + // + // int currentModelIndexForCurrSkillType = lastModelIndexForCurrSkillType; + // const Model *result = currSkill->getAnimation(getAnimProgressAsFloat(),this,&lastModelIndexForCurrSkillType, &animationRandomCycleCount); + // if(currentModelIndexForCurrSkillType != lastModelIndexForCurrSkillType) { + // animationRandomCycleCount++; + // if(currSkill != NULL && animationRandomCycleCount >= currSkill->getAnimationCount()) { + // animationRandomCycleCount = 0; + // } + // } + // return result; + //} + + bool Unit::checkModelStateInfoForNewHpValue() { + bool result = false; + if (currSkill != NULL && currSkill->getAnimationCount() > 1) { + if (lastModelIndexForCurrSkillType >= 0) { + const AnimationAttributes attributes = + currSkill->getAnimationAttribute(lastModelIndexForCurrSkillType); + if (attributes.fromHp != 0 || attributes.toHp != 0) { + //printf("Check for RESET model state for [%d - %s] HP = %d [%d to %d]\n",this->id,this->getType()->getName().c_str(),this->getHp(),attributes.fromHp,attributes.toHp); + //if(this->getHp() >= attributes.fromHp && this->getHp() <= attributes.toHp) { + if (this->getHp() < attributes.fromHp + || this->getHp() > attributes.toHp) { + //printf("RESET model state for [%d - %s] HP = %d [%d to %d]\n",this->id,this->getType()->getName().c_str(),this->getHp(),attributes.fromHp,attributes.toHp); + + lastModelIndexForCurrSkillType = -1; + animationRandomCycleCount = 0; + result = true; + } + } else { + //printf("Check for RESET #2 model state for [%d - %s] HP = %d [%d to %d] for skill [%s]\n",this->id,this->getType()->getName().c_str(),this->getHp(),attributes.fromHp,attributes.toHp,currSkill->getName().c_str()); + } + } + } + + return result; + } + + Vec3f Unit::getCurrVectorForParticlesystems() const { + if (getFaction()->getType()->isFlatParticlePositions()) { + return getCurrVectorFlat(); + } else { + return getCurrMidHeightVector(); + } + } + + Vec3f Unit::getCurrMidHeightVector() const { + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + Vec3f result = + getCurrVectorFlat() + Vec3f(0.f, type->getHeight() / 2.f, 0.f); + result.x = truncateDecimal < float >(result.x, 6); + result.y = truncateDecimal < float >(result.y, 6); + result.z = truncateDecimal < float >(result.z, 6); + + return result; + } + + Vec3f Unit::getCurrVectorAsTarget() const { + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + Vec3f result = + getCurrVectorFlat() + Vec3f(0.f, type->getTargetHeight() / 2.f, + 0.f); + result.x = truncateDecimal < float >(result.x, 6); + result.y = truncateDecimal < float >(result.y, 6); + result.z = truncateDecimal < float >(result.z, 6); + + return result; + } + + Vec3f Unit::getCurrBurnVector() const { + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + Vec3f result = + getCurrVectorFlat() + Vec3f(0.f, type->getBurnHeight() / 2.f, 0.f); + result.x = truncateDecimal < float >(result.x, 6); + result.y = truncateDecimal < float >(result.y, 6); + result.z = truncateDecimal < float >(result.z, 6); + + return result; + } + + Vec3f Unit::getCurrVectorFlat() const { + return getVectorFlat(lastPos, pos); + } + + float Unit::getProgressAsFloat() const { + float result = + (static_cast (progress) / static_cast < + float>(PROGRESS_SPEED_MULTIPLIER)); + result = truncateDecimal < float >(result, 6); + return result; + } + + Vec3f Unit::getVectorFlat(const Vec2i & lastPosValue, + const Vec2i & curPosValue) const { + Vec3f v; + + float y1 = computeHeight(lastPosValue); + float y2 = computeHeight(curPosValue); + + if (currSkill->getClass() == scMove) { + float progressAsFloat = getProgressAsFloat(); + + v.x = + lastPosValue.x + progressAsFloat * (curPosValue.x - lastPosValue.x); + v.z = + lastPosValue.y + progressAsFloat * (curPosValue.y - lastPosValue.y); + v.y = y1 + progressAsFloat * (y2 - y1); + + v.x = truncateDecimal < float >(v.x, 6); + v.y = truncateDecimal < float >(v.y, 6); + v.z = truncateDecimal < float >(v.z, 6); + } else { + v.x = static_cast (curPosValue.x); + v.z = static_cast (curPosValue.y); + v.y = y2; + + v.x = truncateDecimal < float >(v.x, 6); + v.y = truncateDecimal < float >(v.y, 6); + v.z = truncateDecimal < float >(v.z, 6); + } + v.x += type->getSize() / 2.f - 0.5f; + v.z += type->getSize() / 2.f - 0.5f; + + v.x = truncateDecimal < float >(v.x, 6); + v.z = truncateDecimal < float >(v.z, 6); + + return v; + } + + // =================== Command list related =================== + + //any command + bool Unit::anyCommand(bool validateCommandtype) const { + bool result = false; + if (validateCommandtype == false) { + result = (commands.empty() == false); + } else { + for (Commands::const_iterator it = commands.begin(); + it != commands.end(); ++it) { + const CommandType *ct = (*it)->getCommandType(); + if (ct != NULL && ct->getClass() != ccStop) { + result = true; + break; + } + } + } + + return result; + } + + //return current command, assert that there is always one command + Command *Unit::getCurrrentCommandThreadSafe() { + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands, mutexOwnerId); + + if (commands.empty() == false) { + return commands.front(); + } + + return NULL; + } + + void Unit::replaceCurrCommand(Command * cmd) { + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands, mutexOwnerId); + + assert(commands.empty() == false); + commands.front() = cmd; + this->setCurrentUnitTitle(""); + } + + //returns the size of the commands + unsigned int Unit::getCommandSize() const { + return (unsigned int) commands.size(); + } + + //return current command, assert that there is always one command + int Unit::getCountOfProducedUnits(const UnitType * ut) const { + int count = 0; + for (Commands::const_iterator it = commands.begin(); + it != commands.end(); ++it) { + const CommandType *ct = (*it)->getCommandType(); + if (ct->getClass() == ccProduce || ct->getClass() == ccMorph) { + const UnitType *producedUnitType = + static_cast (ct->getProduced()); + if (producedUnitType == ut) { + count++; + } + } + if (ct->getClass() == ccBuild) { + const UnitType *builtUnitType = (*it)->getUnitType(); + if (builtUnitType == ut) { + count++; + } + } + } + return count; + } + + //give one command (clear, and push back) + std::pair < CommandResult, string > Unit::giveCommand(Command * command, + bool tryQueue) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugUnitCommands).enabled) + SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, + "\n======================\nUnit Command tryQueue = %d\nUnit Info:\n%s\nCommand Info:\n%s\n", + tryQueue, this->toString().c_str(), + command->toString(false).c_str()); + + std::pair < CommandResult, string > result(crFailUndefined, ""); + changedActiveCommand = false; + + Chrono chrono; + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled) + chrono.start(); + + if (command == NULL) { + throw megaglest_runtime_error("command == NULL"); + } + if (command->getCommandType() == NULL) { + throw megaglest_runtime_error("command->getCommandType() == NULL"); + } + + const int command_priority = command->getPriority(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + + //printf("In [%s::%s] Line: %d unit [%d - %s] command [%s] tryQueue = %d command->getCommandType()->isQueuable(tryQueue) = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->getId(),this->getType()->getName().c_str(), command->getCommandType()->getName().c_str(), tryQueue,command->getCommandType()->isQueuable(tryQueue)); + + + if (command->getCommandType()->isQueuable(tryQueue)) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + if (SystemFlags::getSystemSettingType + (SystemFlags::debugUnitCommands).enabled) + SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, + "In [%s::%s Line: %d] Command is Queable\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + if (command->getCommandType()->isQueuable() == qAlways && tryQueue) { + // Its a produce or upgrade command called without queued key + // in this case we must NOT delete lower priority commands! + // we just queue it! + + } else { + //Delete all lower-prioirty commands + for (list < Command * >::iterator i = commands.begin(); + i != commands.end();) { + if ((*i)->getPriority() < command_priority) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugUnitCommands).enabled) + SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, + "In [%s::%s Line: %d] Deleting lower priority command [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, + (*i)->toString(false).c_str()); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands, mutexOwnerId); + + deleteQueuedCommand(*i); + i = commands.erase(i); + + safeMutex.ReleaseLock(); + } else { + ++i; + } + } + } + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + + //cancel current command if it is not queuable + if (commands.empty() == false && + commands.back()->getCommandType()->isQueueAppendable() == + false) { + if (SystemFlags::getSystemSettingType + (SystemFlags::debugUnitCommands).enabled) + SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, + "In [%s::%s Line: %d] Cancel command because last one is NOT queable [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, + commands.back()-> + toString(false).c_str()); + + cancelCommand(); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + } else { + //empty command queue + if (SystemFlags::getSystemSettingType + (SystemFlags::debugUnitCommands).enabled) + SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, + "In [%s::%s Line: %d] Clear commands because current is NOT queable.\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + bool willChangedActiveCommand = (commands.empty() == false); + if (willChangedActiveCommand == true) { + + CommandClass currCommandClass = + getCurrCommand()->getCommandType()->getClass(); + CommandClass commandClass = command->getCommandType()->getClass(); + if (currCommandClass == commandClass) { + + willChangedActiveCommand = false; + } else if (currCommandClass == ccAttack || + currCommandClass == ccAttackStopped || + commandClass == ccAttack || + commandClass == ccAttackStopped) { + + willChangedActiveCommand = true; + } else { + willChangedActiveCommand = false; + } + } + + if (willChangedActiveCommand == true) { + + lastChangedActiveCommandFrame = changedActiveCommandFrame; + changedActiveCommandFrame = getFrameCount(); + + //printf("Line: %d getCurrCommand() [%s] command [%s]\n",__LINE__,getCurrCommand()->toString(false).c_str(),command->toString(false).c_str()); + } + + clearCommands(); + changedActiveCommand = willChangedActiveCommand; + + //printf("In [%s::%s] Line: %d cleared existing commands\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, chrono.getMillis()); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + + //check command + result = checkCommand(command); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugUnitCommands).enabled) + SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, + "In [%s::%s Line: %d] checkCommand returned: [%d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + result.first); + + //printf("In [%s::%s] Line: %d check command returned %d, commands.size() = %d\n[%s]\n\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result,commands.size(),command->toString().c_str()); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + + if (result.first == crSuccess) { + applyCommand(command); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + + //push back command + if (result.first == crSuccess) { + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands, mutexOwnerId); + + commands.push_back(command); + + safeMutex.ReleaseLock(); + } else { + delete command; + changedActiveCommand = false; + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugPerformance).enabled + && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, __LINE__, + chrono.getMillis()); + + return result; + } + + //pop front (used when order is done) + CommandResult Unit::finishCommand() { + changedActiveCommand = false; + retryCurrCommandCount = 0; + // Reset the progress when task completed. + resetProgress2(); + this->setCurrentUnitTitle(""); + //is empty? + if (commands.empty()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + return crFailUndefined; + } + + //pop front + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands, mutexOwnerId); + + delete commands.front(); + commands.erase(commands.begin()); + + safeMutex.ReleaseLock(true); + + this->unitPath->clear(); + + while (commands.empty() == false) { + if (commands.front()->getUnit() != NULL + && this->faction->isUnitInLivingUnitsp(commands. + front()->getUnit()) == + false) { + safeMutex.Lock(); + delete commands.front(); + commands.erase(commands.begin()); + safeMutex.ReleaseLock(true); + } else { + break; + } + } + + return crSuccess; + } + + //to cancel a command + CommandResult Unit::cancelCommand() { + changedActiveCommand = false; + retryCurrCommandCount = 0; + + this->setCurrentUnitTitle(""); + + //is empty? + if (commands.empty()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + return crFailUndefined; + } + + //undo command + undoCommand(commands.back()); + + //delete ans pop command + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands, mutexOwnerId); + + delete commands.back(); + commands.pop_back(); + + // Reset the progress if the last command in the queue was cancelled. + // We don't want to reset the progress if we're not removing the last command, + // because then the progress of the actual command in progress. + /// TODO: extra if statement below needed adding make the reset function properly. Can this be avoided? + if (commands.empty()) resetProgress2(); + + safeMutex.ReleaseLock(); + + //clear routes + this->unitPath->clear(); + + + + return crSuccess; + } + + // =================== route stack =================== + + void Unit::create(bool startingUnit) { + faction->addUnit(this); + map->putUnitCells(this, pos); + if (startingUnit) { + faction->applyStaticCosts(type, NULL); + } + } + + void Unit::born(const CommandType * ct) { + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + faction->addStore(type); + faction->applyStaticProduction(type, ct); + setCurrSkill(scStop); + + checkItemInVault(&this->hp, this->hp); + int original_hp = this->hp; + + + //set hp from start hp + checkItemInVault(&this->ep, this->ep); + if (type->getStartHpType() == UnitType::stValue) { + this->hp = type->getStartHpValue(); + } else { + this->hp = + type->getTotalMaxHp(&totalUpgrade) * + type->getStartHpPercentage() / 100; + } + + if (original_hp != this->hp) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault(&this->hp, this->hp); + + //set ep from start ep + checkItemInVault(&this->ep, this->ep); + if (type->getStartEpType() == UnitType::stValue) { + this->ep = type->getStartEpValue(); + } else { + this->ep = + type->getTotalMaxEp(&totalUpgrade) * + type->getStartEpPercentage() / 100; + } + } + + void Unit::kill() { + //no longer needs static resources + if (isBeingBuilt()) { + faction->deApplyStaticConsumption(type, + (getCurrCommand() != + NULL ? + getCurrCommand()->getCommandType + () : NULL)); + } else { + faction->deApplyStaticCosts(type, + (getCurrCommand() != + NULL ? + getCurrCommand()->getCommandType() : + NULL)); + } + + //do the cleaning + //clear commands ( and their blocking fields ) + clearCommands(); + + map->clearUnitCells(this, pos, true); + if (isBeingBuilt() == false) { + faction->removeStore(type); + } + setCurrSkill(scDie); + + notifyObservers(UnitObserver::eKill); + + + UnitUpdater *unitUpdater = game->getWorld()->getUnitUpdater(); + //unitUpdater->clearUnitPrecache(this); + unitUpdater->removeUnitPrecache(this); + } + + void Unit::undertake() { + try { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] about to undertake unit id = %d [%s] [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, this->id, + this->getFullName(false).c_str(), + this->getDesc(false).c_str()); + + // Remove any units that were previously in attack-boost range + if (currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.empty() == false + && currentAttackBoostOriginatorEffect.skillType != NULL) { + for (unsigned int i = 0; + i < + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.size(); ++i) { + // Remove attack boost upgrades from unit + int findUnitId = + currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; + Unit *affectedUnit = game->getWorld()->findUnitById(findUnitId); + if (affectedUnit != NULL) { + affectedUnit->deapplyAttackBoost + (currentAttackBoostOriginatorEffect.skillType-> + getAttackBoost(), this); + } + + //printf("!!!! DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); + } + currentAttackBoostOriginatorEffect.currentAttackBoostUnits.clear(); + } + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + UnitUpdater *unitUpdater = game->getWorld()->getUnitUpdater(); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + //unitUpdater->clearUnitPrecache(this); + unitUpdater->removeUnitPrecache(this); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + this->faction->deleteLivingUnits(id); + this->faction->deleteLivingUnitsp(this); + + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + + faction->removeUnit(this); + } catch (const megaglest_runtime_error & ex) { + string sErrBuf = ""; + if (ex.wantStackTrace() == true) { + char szErrBuf[8096] = ""; + snprintf(szErrBuf, 8096, "In [%s::%s %d]", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + sErrBuf = + string(szErrBuf) + string("\nerror [") + string(ex.what()) + + string("]\n"); + } else { + sErrBuf = ex.what(); + } + SystemFlags::OutputDebug(SystemFlags::debugError, sErrBuf.c_str()); + + throw; + } catch (const std::exception & ex) { + char szErrBuf[8096] = ""; + snprintf(szErrBuf, 8096, "In [%s::%s %d]", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__); + string sErrBuf = + string(szErrBuf) + string("\nerror [") + string(ex.what()) + + string("]\n"); + SystemFlags::OutputDebug(SystemFlags::debugError, sErrBuf.c_str()); + + throw; + } + } + + // =================== Referencers =================== + + void Unit::addObserver(UnitObserver * unitObserver) { + observers.push_back(unitObserver); + } + + //void Unit::removeObserver(UnitObserver *unitObserver){ + // observers.remove(unitObserver); + //} + + void Unit::notifyObservers(UnitObserver::Event event) { + for (Observers::iterator it = observers.begin(); + it != observers.end(); ++it) { + (*it)->unitEvent(event, this); + } + } + + // =================== Other =================== + + void Unit::resetHighlight() { + highlight = 1.f; + } + + const CommandType *Unit::computeCommandType(const Vec2i & pos, + const Unit * + targetUnit) const { + const CommandType *commandType = NULL; + + if (map->isInside(pos) == false + || map->isInsideSurface(map->toSurfCoords(pos)) == false) { + throw megaglest_runtime_error("#6 Invalid path position = " + + pos.getString()); + } + + SurfaceCell *sc = map->getSurfaceCell(Map::toSurfCoords(pos)); + + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + //printf("Line: %d Unit::computeCommandType pos [%s] targetUnit [%s]\n",__LINE__,pos.getString().c_str(),(targetUnit != NULL ? targetUnit->getType()->getName().c_str() : "(null)")); + if (targetUnit != NULL) { + //attack enemies + if (isAlly(targetUnit) == false) { + commandType = + type->getFirstAttackCommand(targetUnit->getCurrField()); + } + //repair allies + else { + if (targetUnit->isBuilt() == false + || targetUnit->isDamaged() == true) { + commandType = + type->getFirstRepairCommand(targetUnit->getType()); + } + + //printf("Line: %d Unit::computeCommandType pos [%s] targetUnit [%s] commandType [%p]\n",__LINE__,pos.getString().c_str(),(targetUnit != NULL ? targetUnit->getType()->getName().c_str() : "(null)"),commandType); + + if (commandType == NULL && targetUnit != NULL) { + //Command *command= this->getCurrCommand(); + //const HarvestCommandType *hct= dynamic_cast((command != NULL ? command->getCommandType() : NULL)); + + // Check if we can return whatever resources we have + if (targetUnit->getFactionIndex() == this->getFactionIndex() && + targetUnit->isOperative() == true && + this->getLoadType() != NULL && this->getLoadCount() != 0 && + targetUnit->getType() != NULL && + targetUnit->getType()->getStore(this->getLoadType()) > 0) { + + commandType = type->getFirstHarvestEmergencyReturnCommand(); + } + } + } + } else { + //check harvest command + Resource *resource = sc->getResource(); + if (resource != NULL) { + commandType = + type->getFirstHarvestCommand(resource->getType(), + this->getFaction()); + } + } + + if (targetUnit == NULL && commandType == NULL) { + const Vec2i unitTargetPos = pos; + Cell *cell = map->getCell(unitTargetPos); + if (cell != NULL && cell->getUnit(this->getCurrField()) != NULL) { + Unit *targetUnit = cell->getUnit(this->getCurrField()); + if (targetUnit != NULL) { + // Check if we want to help build (repair) any buildings instead of just moving + if (targetUnit->getFactionIndex() == this->getFactionIndex() && + (targetUnit->isBuilt() == false + || targetUnit->isDamaged() == true)) { + const RepairCommandType *rct = + this->getType()-> + getFirstRepairCommand(targetUnit->getType()); + if (rct != NULL) { + commandType = + type->getFirstRepairCommand(targetUnit->getType()); + //printf("************ Unit will repair building built = %d, repair = %d\n",targetUnit->isBuilt(),targetUnit->isDamaged()); + } + } + } + } + } + + // Default command is the class of the unit (i.e. attack for attackers, walk for walkers). + // The default command is executed when a unit is produced and sent to a meeting point + // or when the unit is selected and right clicked to a position. + if (commandType == NULL) { + // move + // commandType = type->getFirstCtOfClass (ccMove); + + // attack + // Is the unit class warrior? if yes, attack by default, else walk. + commandType = + type->getFirstCtOfClass(this->getType()-> + isOfClass(ucWarrior) ? ccAttack : ccMove); + + // FIXME: I think a better solution would be to have a hotkey for this, + // the user can decide, and toggle in-game -andy5995 2018-02-03 + } + + return commandType; + } + + int64 Unit::getUpdateProgress() { + if (progress > PROGRESS_SPEED_MULTIPLIER) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: progress > " MG_I64_SPECIFIER + ", progress = [" MG_I64_SPECIFIER "]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, PROGRESS_SPEED_MULTIPLIER, + progress); + throw megaglest_runtime_error(szBuf); + } + + if (currSkill == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + int64 newProgress = progress; + if (currSkill->getClass() != scDie) { + //speed + int speed = currSkill->getTotalSpeed(&totalUpgrade); + + if (changedActiveCommand == true) { + if (changedActiveCommandFrame - lastChangedActiveCommandFrame >= + MIN_FRAMECOUNT_CHANGE_COMMAND_SPEED) { + //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] skill [%s] command [%s]\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,currSkill->toString(false).c_str(),getCurrCommand()->toString(false).c_str()); + //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] total = %u\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,(changedActiveCommandFrame - lastChangedActiveCommandFrame)); + speed = CHANGE_COMMAND_SPEED; + } + } + + //speed modifier + int64 diagonalFactor = getDiagonalFactor(); + int64 heightFactor = getHeightFactor(PROGRESS_SPEED_MULTIPLIER); + + //update progresses + // const Game *game = Renderer::getInstance().getGame(); + // if(game == NULL) { + // throw megaglest_runtime_error("game == NULL"); + // } + // if(game->getWorld() == NULL) { + // throw megaglest_runtime_error("game->getWorld() == NULL"); + // } + + newProgress = getUpdatedProgress(progress, GameConstants::updateFps, + speed, diagonalFactor, + heightFactor); + + } + return newProgress; + } + + bool Unit::needToUpdate() { + bool return_value = false; + if (currSkill->getClass() != scDie) { + int newProgress = getUpdateProgress(); + if (newProgress >= PROGRESS_SPEED_MULTIPLIER) { + return_value = true; + } + } + return return_value; + } + + int64 Unit::getDiagonalFactor() { + //speed modifier + int64 diagonalFactor = PROGRESS_SPEED_MULTIPLIER; + if (currSkill->getClass() == scMove) { + //if moving in diagonal move slower + Vec2i dest = pos - lastPos; + if (abs(dest.x) + abs(dest.y) == 2) { + //diagonalFactor = 0.71f * PROGRESS_SPEED_MULTIPLIER; + diagonalFactor = 71 * (PROGRESS_SPEED_MULTIPLIER / 100); + } + } + return diagonalFactor; + } + + int64 Unit::getHeightFactor(int64 speedMultiplier) { + int64 heightFactor = speedMultiplier; + if (currSkill->getClass() == scMove) { + //if moving to an higher cell move slower else move faster + Cell *unitCell = map->getCell(pos); + if (unitCell == NULL) { + throw megaglest_runtime_error("unitCell == NULL"); + } + + Cell *targetCell = map->getCell(targetPos); + if (targetCell == NULL) { + throw megaglest_runtime_error("targetCell == NULL"); + } + + int64 heightDiff = ((truncateDecimal < float >(unitCell->getHeight(), + 2) * + speedMultiplier) - (truncateDecimal < + float >(targetCell-> + getHeight(), + 2) * + speedMultiplier)); + //heightFactor= clamp(speedMultiplier + heightDiff / (5.f * speedMultiplier), 0.2f * speedMultiplier, 5.f * speedMultiplier); + heightFactor = + clamp(speedMultiplier + heightDiff / (5 * speedMultiplier), + (2 * (speedMultiplier / 10)), 5 * speedMultiplier); + } + + return heightFactor; + } + + int64 Unit::getSpeedDenominator(int64 updateFPS) { + int64 speedDenominator = + (speedDivider * updateFPS) * PROGRESS_SPEED_MULTIPLIER; + return speedDenominator; + } + int64 Unit::getUpdatedProgress(int64 currentProgress, int64 updateFPS, + int64 speed, int64 diagonalFactor, + int64 heightFactor) { + + int64 speedDenominator = getSpeedDenominator(updateFPS); + int64 newProgress = currentProgress; + int64 progressIncrease = + ((speed * diagonalFactor * heightFactor) / speedDenominator); + // Ensure we increment at least a value of 1 of the action will be stuck infinitely + if (speed > 0 && diagonalFactor > 0 && heightFactor > 0 + && progressIncrease == 0) { + progressIncrease = 1; + } + + if (isNetworkCRCEnabled() == true) { + float height = map->getCell(pos)->getHeight(); + float airHeight = game->getWorld()->getTileset()->getAirHeight(); + int cellUnitHeight = -1; + int cellObjectHeight = -1; + + Unit *unit = map->getCell(pos)->getUnit(fLand); + if (unit != NULL && unit->getType()->getHeight() > airHeight) { + cellUnitHeight = unit->getType()->getHeight(); + } else { + SurfaceCell *sc = map->getSurfaceCell(map->toSurfCoords(pos)); + if (sc != NULL && sc->getObject() != NULL + && sc->getObject()->getType() != NULL) { + if (sc->getObject()->getType()->getHeight() > airHeight) { + cellObjectHeight = sc->getObject()->getType()->getHeight(); + } + } + } + + + char szBuf[8096] = ""; + snprintf(szBuf, 8095, + "currentProgress = " MG_I64_SPECIFIER " updateFPS = " + MG_I64_SPECIFIER " speed = " MG_I64_SPECIFIER + " diagonalFactor = " MG_I64_SPECIFIER " heightFactor = " + MG_I64_SPECIFIER " speedDenominator = " MG_I64_SPECIFIER + " progressIncrease = " MG_I64_SPECIFIER " [" + MG_I64_SPECIFIER + "] height [%f] airHeight [%f] cellUnitHeight [%d] cellObjectHeight [%d] skill [%s] pos [%s] lastpos [%s]", + currentProgress, updateFPS, speed, diagonalFactor, + heightFactor, speedDenominator, progressIncrease, + ((speed * diagonalFactor * heightFactor) / + speedDenominator), height, airHeight, cellUnitHeight, + cellObjectHeight, + (currSkill != + NULL ? currSkill->getName().c_str() : "none"), + pos.getString().c_str(), lastPos.getString().c_str()); + networkCRCLogInfo = szBuf; + + //printf("%s\n",szBuf); + } + + newProgress += progressIncrease; + + // if(currSkill->getClass() == scMove || (currSkill->getClass() == scStop && this->loadCount > 0)) { + // printf("speedDenominator: " MG_I64_SPECIFIER " currentProgress: " MG_I64_SPECIFIER " speed: " MG_I64_SPECIFIER " diagonalFactor: " MG_I64_SPECIFIER " heightFactor: " MG_I64_SPECIFIER " progressIncrease: " MG_I64_SPECIFIER " newProgress: " MG_I64_SPECIFIER " TOP #: " MG_I64_SPECIFIER "\n",speedDenominator,currentProgress,speed,diagonalFactor,heightFactor,progressIncrease,newProgress,(speed * diagonalFactor * heightFactor)); + // } + + return newProgress; + } + + void Unit::updateAttackBoostProgress(const Game * game) { + const bool debugBoost = false; + if (debugBoost) + printf + ("===================== START Unit [%d - %s] skill: %s affected unit size: " + MG_SIZE_T_SPECIFIER "\n", this->id, + this->getType()->getName(false).c_str(), + currSkill->getBoostDesc(false).c_str(), + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.size()); + + if (currSkill != currentAttackBoostOriginatorEffect.skillType) { + + if (debugBoost) + printf("Line: %d new [%s]\n", __LINE__, + (currentAttackBoostOriginatorEffect.skillType != + NULL ? currentAttackBoostOriginatorEffect. + skillType->getBoostDesc(false).c_str() : "")); + + if (currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) { + delete currentAttackBoostOriginatorEffect.currentAppliedEffect; + currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL; + + //printf("- #1 DE-APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); + } + + // Remove any units that were previously in range + if (currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.empty() == false + && currentAttackBoostOriginatorEffect.skillType != NULL) { + for (unsigned int i = 0; + i < + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.size(); ++i) { + // Remove attack boost upgrades from unit + + int findUnitId = + currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; + Unit *affectedUnit = game->getWorld()->findUnitById(findUnitId); + if (affectedUnit != NULL) { + affectedUnit->deapplyAttackBoost + (currentAttackBoostOriginatorEffect.skillType-> + getAttackBoost(), this); + } + + //printf("- #1 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); + } + currentAttackBoostOriginatorEffect.currentAttackBoostUnits.clear(); + } + + if (debugBoost) + printf("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n", + __LINE__, + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.size()); + + currentAttackBoostOriginatorEffect.skillType = currSkill; + + if (currSkill->isAttackBoostEnabled() == true) { + if (debugBoost) + printf("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n", + __LINE__, + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + size()); + + // Search for units in range of this unit which apply to the + // attack-boost and temporarily upgrade them + UnitUpdater *unitUpdater = + this->game->getWorld()->getUnitUpdater(); + + const AttackBoost *attackBoost = currSkill->getAttackBoost(); + vector < Unit * >candidates = unitUpdater->findUnitsInRange(this, + attackBoost->radius); + + if (debugBoost) + printf("Line: %d candidates unit size: " MG_SIZE_T_SPECIFIER + " attackBoost: %s\n", __LINE__, candidates.size(), + attackBoost->getDesc(false).c_str()); + for (unsigned int i = 0; i < candidates.size(); ++i) { + Unit *affectedUnit = candidates[i]; + if (attackBoost->isAffected(this, affectedUnit) == true) { + if (affectedUnit->applyAttackBoost(attackBoost, this) == true) { + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.push_back(affectedUnit->getId()); + //printf("+ #1 APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); + } + } + } + + if (debugBoost) + printf("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n", + __LINE__, + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + size()); + + if (showUnitParticles == true) { + if (currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.empty() == false) { + if (attackBoost->unitParticleSystemTypeForSourceUnit != NULL) { + currentAttackBoostOriginatorEffect.currentAppliedEffect = + new UnitAttackBoostEffect(); + currentAttackBoostOriginatorEffect. + currentAppliedEffect->upst = new UnitParticleSystemType(); + *currentAttackBoostOriginatorEffect. + currentAppliedEffect->upst = + *attackBoost->unitParticleSystemTypeForSourceUnit; + //effect.upst = boost->unitParticleSystemTypeForAffectedUnit; + + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups = + new UnitParticleSystem(200); + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups->setParticleOwner(this); + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups->setParticleType + (currentAttackBoostOriginatorEffect.currentAppliedEffect-> + upst); + + currentAttackBoostOriginatorEffect. + currentAppliedEffect->upst-> + setValues + (currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups); + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups->setPos(getCurrVectorForParticlesystems()); + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups->setRotation(getRotation()); + setMeshPosInParticleSystem + (currentAttackBoostOriginatorEffect. + currentAppliedEffect->ups); + + if (getFaction()->getTexture()) { + currentAttackBoostOriginatorEffect. + currentAppliedEffect->ups-> + setFactionColor(getFaction()->getTexture()-> + getPixmapConst()->getPixel3f(0, 0)); + } + Renderer:: + getInstance().manageParticleSystem + (currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups, rsGame); + //printf("+ #1 APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); + } + } + } + } + } else { + if (currSkill->isAttackBoostEnabled() == true) { + if (debugBoost) + printf("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n", + __LINE__, + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + size()); + + // Search for units in range of this unit which apply to the + // attack-boost and temporarily upgrade them + UnitUpdater *unitUpdater = + this->game->getWorld()->getUnitUpdater(); + + const AttackBoost *attackBoost = currSkill->getAttackBoost(); + vector < Unit * >candidates = + unitUpdater->findUnitsInRange(this, attackBoost->radius); + vector < int >candidateValidIdList; + candidateValidIdList.reserve(candidates.size()); + + if (debugBoost) + printf("Line: %d candidates unit size: " MG_SIZE_T_SPECIFIER + " attackBoost: %s\n", __LINE__, candidates.size(), + attackBoost->getDesc(false).c_str()); + + for (unsigned int i = 0; i < candidates.size(); ++i) { + Unit *affectedUnit = candidates[i]; + candidateValidIdList.push_back(affectedUnit->getId()); + + std::vector < int >::iterator iterFound = + std:: + find + (currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + begin(), + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + end(), + affectedUnit->getId()); + + if (attackBoost->isAffected(this, affectedUnit) == true) { + if (iterFound == + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.end()) { + if (affectedUnit->applyAttackBoost(attackBoost, this) == + true) { + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.push_back(affectedUnit-> + getId()); + + //printf("+ #2 APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); + } + } + } else { + if (iterFound != + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.end()) { + affectedUnit->deapplyAttackBoost + (currentAttackBoostOriginatorEffect.skillType-> + getAttackBoost(), this); + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.erase(iterFound); + + //printf("- #2 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); + } + } + } + + // Now remove any units that were in the list of boosted units but + // are no longer in range + if (currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.empty() == false) { + for (int i = + (int) + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + size() - 1; i >= 0; --i) { + int findUnitId = + currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; + + std::vector < int >::iterator iterFound = + std::find(candidateValidIdList.begin(), + candidateValidIdList.end(), + findUnitId); + if (iterFound == candidateValidIdList.end()) { + Unit *affectedUnit = + game->getWorld()->findUnitById(findUnitId); + if (affectedUnit != NULL) { + affectedUnit->deapplyAttackBoost + (currentAttackBoostOriginatorEffect.skillType-> + getAttackBoost(), this); + + if (debugBoost) + printf + ("Removed attack boost from Unit [%d - %s] since they are NO LONGER in range\n", + affectedUnit->id, + affectedUnit->getType()->getName(false).c_str()); + + } + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.erase + (currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + begin() + i); + } + } + } + + if (debugBoost) + printf("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n", + __LINE__, + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + size()); + + if (showUnitParticles == true) { + if (currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.empty() == false) { + if (attackBoost->unitParticleSystemTypeForSourceUnit != NULL + && currentAttackBoostOriginatorEffect.currentAppliedEffect + == NULL) { + + currentAttackBoostOriginatorEffect.currentAppliedEffect = + new UnitAttackBoostEffect(); + currentAttackBoostOriginatorEffect. + currentAppliedEffect->upst = new UnitParticleSystemType(); + *currentAttackBoostOriginatorEffect. + currentAppliedEffect->upst = + *attackBoost->unitParticleSystemTypeForSourceUnit; + //effect.upst = boost->unitParticleSystemTypeForAffectedUnit; + + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups = + new UnitParticleSystem(200); + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups->setParticleOwner(this); + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups->setParticleType + (currentAttackBoostOriginatorEffect.currentAppliedEffect-> + upst); + + currentAttackBoostOriginatorEffect. + currentAppliedEffect->upst-> + setValues + (currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups); + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups->setPos(getCurrVectorForParticlesystems()); + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups->setRotation(getRotation()); + setMeshPosInParticleSystem + (currentAttackBoostOriginatorEffect. + currentAppliedEffect->ups); + + if (getFaction()->getTexture()) { + currentAttackBoostOriginatorEffect. + currentAppliedEffect->ups-> + setFactionColor(getFaction()-> + getTexture()->getPixmapConst()-> + getPixel3f(0, 0)); + } + Renderer:: + getInstance().manageParticleSystem + (currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups, rsGame); + + //printf("+ #2 APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); + } + } else + if (currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + empty() == true) { + if (currentAttackBoostOriginatorEffect.currentAppliedEffect != + NULL) { + delete + currentAttackBoostOriginatorEffect.currentAppliedEffect; + currentAttackBoostOriginatorEffect.currentAppliedEffect = + NULL; + + //printf("- #2 DE-APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); + } + } + } + } + } + + if (debugBoost) { + if (currSkill->isAttackBoostEnabled() == true) { + printf("Unit [%d - %s] has attackboost enabled: %s\n", this->id, + this->getType()->getName(false).c_str(), + currSkill->getBoostDesc(false).c_str()); + + if (currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.empty() == false) { + printf + ("Found affected units currentAttackBoostOriginatorEffect.skillType [%p]\n", + currentAttackBoostOriginatorEffect.skillType); + + for (unsigned int i = 0; + i < + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.size(); ++i) { + int unitnum = + currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; + printf("affected unit #: %u - %d\n", i, unitnum); + } + } + } + } + } + + bool Unit::update() { + assert(progress <= PROGRESS_SPEED_MULTIPLIER); + + //highlight + if (highlight > 0.f) { + const Game *game = Renderer::getInstance().getGame(); + highlight -= + 1.f / (Game::highlightTime * + game->getWorld()->getUpdateFps(this->getFactionIndex())); + } + + if (currSkill == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + //speed + int speed = currSkill->getTotalSpeed(&totalUpgrade); + + if (oldTotalSight != + getType()->getTotalSight(this->getTotalUpgrade())) { + oldTotalSight = getType()->getTotalSight(this->getTotalUpgrade()); + // refresh FogOfWar and so on, because sight ha changed since last update + refreshPos(true); + } + + if (changedActiveCommand) { + if (changedActiveCommandFrame - lastChangedActiveCommandFrame >= + MIN_FRAMECOUNT_CHANGE_COMMAND_SPEED) { + //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] skill [%s] command [%s]\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,currSkill->toString(false).c_str(),getCurrCommand()->toString(false).c_str()); + //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] total = %u\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,(changedActiveCommandFrame - lastChangedActiveCommandFrame)); + speed = CHANGE_COMMAND_SPEED; + } + } + + //speed modifier + int64 diagonalFactor = getDiagonalFactor(); + int64 heightFactor = getHeightFactor(PROGRESS_SPEED_MULTIPLIER); + + //update progresses + this->lastAnimProgress = this->animProgress; + const Game *game = Renderer::getInstance().getGame(); + + if (animProgress == 0) { + AnimCycleStarts(); + } + progress = getUpdatedProgress(progress, + GameConstants::updateFps, + speed, diagonalFactor, heightFactor); + + //printf("Test progress = %d for unit [%d - %s]\n",progress,id,getType()->getName().c_str()); + + if (isAnimProgressBound() == true) { + float targetProgress = 0; + if (currSkill->getClass() == scBeBuilt) { + targetProgress = this->getHpRatio(); + } + if (currSkill->getClass() == scProduce) { + targetProgress = this->getProgressRatio(); + } + if (currSkill->getClass() == scUpgrade) { + targetProgress = this->getProgressRatio(); + } + if (currSkill->getClass() == scMorph) { + targetProgress = this->getProgressRatio(); + } + + float targetProgressIntValue = + targetProgress * ANIMATION_SPEED_MULTIPLIER; + if (this->animProgress < targetProgressIntValue) { + float diff = targetProgressIntValue - this->animProgress; + float progressIncrease = + static_cast (this->animProgress) + diff / static_cast < + float>(GameConstants::updateFps); + // Ensure we increment at least a value of 1 of the action will be stuck infinitely + if (diff > 0.f && GameConstants::updateFps > 0 + && progressIncrease == 0.f) { + progressIncrease = 1.f; + } + + //if(currSkill->getClass() == scBeBuilt) { + // printf("targetProgress: %.10f this->animProgress: %d diff: %.10f GameConstants::updateFps: %d progressIncrease: %.10f\n",targetProgress,this->animProgress,diff,GameConstants::updateFps,progressIncrease); + //} + + this->animProgress = progressIncrease; + + //if(currSkill->getClass() == scBeBuilt) { + // printf("Unit build progress: %d anim: %d\n",progress,this->animProgress); + //} + } + } else { + int64 heightFactor = getHeightFactor(ANIMATION_SPEED_MULTIPLIER); + int64 speedDenominator = speedDivider * + game->getWorld()->getUpdateFps(this->getFactionIndex()); + + // Override the animation speed for attacks that have upgraded the attack speed + int animSpeed = currSkill->getAnimSpeed(); + if (currSkill->getClass() == scAttack) { + int animSpeedBoost = + ((AttackSkillType *) + currSkill)->getAnimSpeedBoost(&totalUpgrade); + animSpeed += animSpeedBoost; + } + + int64 progressIncrease = + (animSpeed * heightFactor) / speedDenominator; + // Ensure we increment at least a value of 1 of the action will be stuck infinitely + if (currSkill->getAnimSpeed() > 0 && heightFactor > 0 + && progressIncrease == 0) { + progressIncrease = 1; + } + this->animProgress += progressIncrease; + //this->animProgress += (currSkill->getAnimSpeed() * heightFactor) / speedDenominator; + + //if(currSkill->getClass() == scDie) { + // printf("Unit died progress: %d anim: %d\n",progress,this->animProgress); + //} + } + //update target + updateTarget(); + + //rotation + if (currSkill->getClass() != scStop) { + const int rotFactor = 2; + if (getProgressAsFloat() < 1.f / rotFactor) { + if (type->getFirstStOfClass(scMove)) { + if (abs((int) (lastRotation - targetRotation)) < 180) + rotation = lastRotation + (targetRotation - lastRotation) * + getProgressAsFloat() * rotFactor; + else { + float rotationTerm = + targetRotation > lastRotation ? -360.f : +360.f; + rotation = + lastRotation + (targetRotation - lastRotation + + rotationTerm) * getProgressAsFloat() * + rotFactor; + } + } + } + } + + if (type->getProperty(UnitType::pRotatedClimb)) { + calculateXZRotation(); + } else { + rotationZ = .0f; + rotationX = .0f; + } + + if (Renderer:: + getInstance().validateParticleSystemStillExists(this->fire, + rsGame) == false) { + this->fire = NULL; + } + + if (this->fire != NULL) { + this->fire->setPos(getCurrBurnVector()); + } + for (UnitParticleSystems::iterator it = unitParticleSystems.begin(); + it != unitParticleSystems.end(); ++it) { + if (Renderer:: + getInstance().validateParticleSystemStillExists((*it), + rsGame) == true) { + (*it)->setPos(getCurrVectorForParticlesystems()); + (*it)->setRotation(getRotation()); + setMeshPosInParticleSystem(*it); + } + } + for (UnitParticleSystems::iterator it = damageParticleSystems.begin(); + it != damageParticleSystems.end(); ++it) { + if (Renderer:: + getInstance().validateParticleSystemStillExists((*it), + rsGame) == true) { + (*it)->setPos(getCurrVectorForParticlesystems()); + (*it)->setRotation(getRotation()); + setMeshPosInParticleSystem(*it); + } + } + + for (UnitParticleSystems::iterator it = smokeParticleSystems.begin(); + it != smokeParticleSystems.end(); ++it) { + if (Renderer:: + getInstance().validateParticleSystemStillExists((*it), + rsGame) == true) { + (*it)->setPos(getCurrMidHeightVector()); + (*it)->setRotation(getRotation()); + setMeshPosInParticleSystem(*it); + } + } + + //printf("Unit has attack boost? unit = [%d - %s] size = %d\n",this->getId(), this->getType()->getName(false).c_str(),(int)currentAttackBoostEffects.size()); + for (unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) { + UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; + if (effect != NULL && effect->ups != NULL) { + bool particleValid = + Renderer:: + getInstance().validateParticleSystemStillExists(effect->ups, + rsGame); + if (particleValid == true) { + effect->ups->setPos(getCurrVectorForParticlesystems()); + effect->ups->setRotation(getRotation()); + setMeshPosInParticleSystem(effect->ups); + } + + //printf("i = %d particleValid = %d\n",i,particleValid); + } + //printf("i = %d effect = %p effect->ups = %p\n",i,effect,(effect ? effect->ups : NULL)); + } + + + if (currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) { + if (currentAttackBoostOriginatorEffect.currentAppliedEffect->ups != + NULL) { + bool particleValid = + Renderer::getInstance().validateParticleSystemStillExists + (currentAttackBoostOriginatorEffect.currentAppliedEffect->ups, + rsGame); + if (particleValid == true) { + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups->setPos(getCurrVectorForParticlesystems()); + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups->setRotation(getRotation()); + setMeshPosInParticleSystem + (currentAttackBoostOriginatorEffect.currentAppliedEffect->ups); + } + } + } + + //checks + if (this->animProgress > ANIMATION_SPEED_MULTIPLIER) { + bool canCycle = + currSkill->CanCycleNextRandomAnimation(&animationRandomCycleCount); + this->animProgress = + currSkill->getClass() == scDie ? ANIMATION_SPEED_MULTIPLIER : 0; + if (canCycle == true) { + this->lastModelIndexForCurrSkillType = -1; + } + } + + bool return_value = false; + //checks + if (progress >= PROGRESS_SPEED_MULTIPLIER) { + lastRotation = targetRotation; + if (currSkill->getClass() != scDie) { + progress = 0; + return_value = true; + } else { + progress = PROGRESS_SPEED_MULTIPLIER; + deadCount++; + if (deadCount >= maxDeadCount) { + toBeUndertaken = true; + return_value = false; + } + } + } + + updateAttackBoostProgress(game); + + if (return_value) { + changedActiveCommand = false; + } + + return return_value; + } + + void Unit::updateTimedParticles() { + //!!! + // Start new particle systems based on start time + if (queuedUnitParticleSystemTypes.empty() == false) { + for (int i = (int) queuedUnitParticleSystemTypes.size() - 1; i >= 0; + i--) { + UnitParticleSystemType *pst = queuedUnitParticleSystemTypes[i]; + if (pst != NULL) { + if (truncateDecimal < float >(pst->getStartTime(), 6) <= + truncateDecimal < float >(getAnimProgressAsFloat(), 6)) { + + UnitParticleSystem *ups = new UnitParticleSystem(200); + ups->setParticleOwner(this); + ups->setParticleType(pst); + + pst->setValues(ups); + ups->setPos(getCurrVectorForParticlesystems()); + ups->setRotation(getRotation()); + setMeshPosInParticleSystem(ups); + + if (getFaction()->getTexture()) { + ups->setFactionColor(getFaction()-> + getTexture()->getPixmapConst()-> + getPixel3f(0, 0)); + } + unitParticleSystems.push_back(ups); + Renderer::getInstance().manageParticleSystem(ups, rsGame); + + queuedUnitParticleSystemTypes.erase + (queuedUnitParticleSystemTypes.begin() + i); + } + } else { + queuedUnitParticleSystemTypes.erase + (queuedUnitParticleSystemTypes.begin() + i); + } + } + } + + // End existing systems based on end time + if (unitParticleSystems.empty() == false) { + for (int i = (int) unitParticleSystems.size() - 1; i >= 0; i--) { + UnitParticleSystem *ps = unitParticleSystems[i]; + if (ps != NULL) { + if (Renderer:: + getInstance().validateParticleSystemStillExists(ps, + rsGame) == + true) { + float pst = ps->getStartTime(); + float pet = ps->getEndTime(); + float particleStartTime = truncateDecimal < float >(pst, 6); + float particleEndTime = truncateDecimal < float >(pet, 6); + + if (particleStartTime != 0.0 || particleEndTime != 1.0) { + float animProgressTime = + truncateDecimal < float >(getAnimProgressAsFloat(), 6); + if (animProgressTime >= 0.99 + || animProgressTime >= particleEndTime) { + + ps->fade(); + unitParticleSystems.erase(unitParticleSystems.begin() + + i); + } + } + } + } + } + } + } + + bool Unit::unitHasAttackBoost(const AttackBoost * boost, + const Unit * source) { + bool result = false; + for (unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) { + UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; + if (effect != NULL && effect->boost->name == boost->name && + effect->getSource()->getType()->getId() == + source->getType()->getId()) { + result = true; + break; + } + } + + //printf("Unit has attack boost? source = [%d - %s] [%p] boost [%s] result = %d\n",source->getId(), source->getType()->getName(false).c_str(),source,boost->name.c_str(),result); + + return result; + } + + bool Unit::applyAttackBoost(const AttackBoost * boost, + const Unit * source) { + if (boost == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: boost == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + //printf("APPLYING ATTACK BOOST to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); + + bool shouldApplyAttackBoost = true; + if (boost->allowMultipleBoosts == false) { + // Check if we already have this boost from this unit type and multiples + // are not allowed + bool alreadyHasAttackBoost = this->unitHasAttackBoost(boost, source); + if (alreadyHasAttackBoost == true) { + shouldApplyAttackBoost = false; + } + } + + if (shouldApplyAttackBoost == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("=== APPLYING ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n", + this->getType()->getName(false).c_str(), this->getId(), + source->getType()->getName(false).c_str(), source->getId(), + hp); + + UnitAttackBoostEffect *effect = new UnitAttackBoostEffect(); + effect->boost = boost; + effect->setSource(source); + + bool wasAlive = alive; + int originalHp = hp; + int prevMaxHp = totalUpgrade.getMaxHp(); + int prevMaxHpRegen = totalUpgrade.getMaxHpRegeneration(); + //printf("#1 wasAlive = %d hp = %d boosthp = %d\n",wasAlive,hp,boost->boostUpgrade.getMaxHp()); + + totalUpgrade.apply(source->getId(), &boost->boostUpgrade, this); + + checkItemInVault(&this->hp, this->hp); + //hp += boost->boostUpgrade.getMaxHp(); + int original_hp = this->hp; + this->hp += (totalUpgrade.getMaxHp() - prevMaxHp); + if (original_hp != this->hp) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault(&this->hp, this->hp); + + //regenerate hp upgrade / or boost + if (totalUpgrade.getMaxHpRegeneration() != 0) { + checkItemInVault(&this->hp, this->hp); + + //printf("BEFORE Apply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); + int original_hp = this->hp; + this->hp += (totalUpgrade.getMaxHpRegeneration() - prevMaxHpRegen); + if (original_hp != this->hp) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + //if(hp > type->getTotalMaxHp(&totalUpgrade)) { + // hp = type->getTotalMaxHp(&totalUpgrade); + //} + addItemToVault(&this->hp, this->hp); + + //printf("AFTER Apply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); + } + + checkModelStateInfoForNewHpValue(); + + if (originalHp < hp) { + this->setLastAttackerUnitId(source->getId()); + } + //printf("#2 wasAlive = %d hp = %d boosthp = %d\n",wasAlive,hp,boost->boostUpgrade.getMaxHp()); + + if (showUnitParticles == true) { + if (boost->unitParticleSystemTypeForAffectedUnit != NULL) { + effect->upst = new UnitParticleSystemType(); + *effect->upst = *boost->unitParticleSystemTypeForAffectedUnit; + //effect.upst = boost->unitParticleSystemTypeForAffectedUnit; + + effect->ups = new UnitParticleSystem(200); + effect->ups->setParticleOwner(this); + effect->ups->setParticleType(effect->upst); + + effect->upst->setValues(effect->ups); + effect->ups->setPos(getCurrVectorForParticlesystems()); + effect->ups->setRotation(getRotation()); + setMeshPosInParticleSystem(effect->ups); + if (getFaction()->getTexture()) { + effect->ups->setFactionColor(getFaction()-> + getTexture()->getPixmapConst()-> + getPixel3f(0, 0)); + } + Renderer::getInstance().manageParticleSystem(effect->ups, + rsGame); + } + } + currentAttackBoostEffects.push_back(effect); + + if (wasAlive == true) { + //startDamageParticles + + if (originalHp > this->hp) { + startDamageParticles(); + } + + //stop DamageParticles on death + if (this->hp <= 0) { + setAlive(false); + this->hp = 0; + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + addItemToVault(&this->hp, this->hp); + checkModelStateInfoForNewHpValue(); + + stopDamageParticles(true); + + this->setLastAttackerUnitId(source->getId()); + this->setCauseOfDeath(ucodAttackBoost); + Unit::game->getWorld()->getStats()->die(getFactionIndex(), + getType + ()->getCountUnitDeathInStats + ()); + game->getScriptManager()->onUnitDied(this); + + StaticSound *sound = + static_cast < + const DieSkillType * + >(this->getType()->getFirstStOfClass(scDie))->getSound(); + if (sound != NULL + && (this->getFactionIndex() == + Unit::game->getWorld()->getThisFactionIndex() + || (game-> + getWorld()->showWorldForPlayer(game-> + getWorld + ()->getThisTeamIndex + ()) == true))) { + SoundRenderer::getInstance().playFx(sound); + } + + if (this->isDead() + && this->getCurrSkill()->getClass() != scDie) { + this->kill(); + } + } + } + + //printf("APPLYING ATTACK BOOST END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("APPLIED ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n", + this->getType()->getName(false).c_str(), this->getId(), + source->getType()->getName(false).c_str(), source->getId(), + hp); + + return shouldApplyAttackBoost; + } + + void Unit::deapplyAttackBoost(const AttackBoost * boost, + const Unit * source) { + if (boost == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: boost == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("=== DE-APPLYING ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n", + this->getType()->getName(false).c_str(), this->getId(), + source->getType()->getName(false).c_str(), source->getId(), + hp); + + bool wasAlive = alive; + int originalHp = hp; + int prevMaxHp = totalUpgrade.getMaxHp(); + int prevMaxHpRegen = totalUpgrade.getMaxHpRegeneration(); + totalUpgrade.deapply(source->getId(), &boost->boostUpgrade, + this->getId()); + + checkItemInVault(&this->hp, this->hp); + int original_hp = this->hp; + //hp -= boost->boostUpgrade.getMaxHp(); + this->hp -= (prevMaxHp - totalUpgrade.getMaxHp()); + if (original_hp != this->hp) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault(&this->hp, this->hp); + + //regenerate hp upgrade / or boost + if (totalUpgrade.getMaxHpRegeneration() != 0) { + checkItemInVault(&this->hp, this->hp); + + //printf("BEFORE DeApply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); + int original_hp = this->hp; + this->hp -= (totalUpgrade.getMaxHpRegeneration() - prevMaxHpRegen); + if (original_hp != this->hp) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + //if(hp > totalUpgrade.getMaxHp()) { + // hp = totalUpgrade.getMaxHp(); + //} + addItemToVault(&this->hp, this->hp); + + //printf("AFTER DeApply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); + } + + if (originalHp < hp) { + this->setLastAttackerUnitId(source->getId()); + } + + if (wasAlive == true) { + //printf("DE-APPLYING ATTACK BOOST wasalive = true to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); + + //startDamageParticles + if (originalHp > this->hp) { + startDamageParticles(); + } + + //stop DamageParticles on death + if (this->hp <= 0) { + setAlive(false); + this->hp = 0; + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + addItemToVault(&this->hp, this->hp); + + checkModelStateInfoForNewHpValue(); + + stopDamageParticles(true); + + this->setLastAttackerUnitId(source->getId()); + this->setCauseOfDeath(ucodAttackBoost); + + Unit::game->getWorld()->getStats()->die(getFactionIndex(), + getType + ()->getCountUnitDeathInStats + ()); + game->getScriptManager()->onUnitDied(this); + + StaticSound *sound = + static_cast < + const DieSkillType * + >(this->getType()->getFirstStOfClass(scDie))->getSound(); + if (sound != NULL + && (this->getFactionIndex() == + Unit::game->getWorld()->getThisFactionIndex() + || (game-> + getWorld()->showWorldForPlayer(game-> + getWorld + ()->getThisTeamIndex + ()) == true))) { + SoundRenderer::getInstance().playFx(sound); + } + + if (this->isDead() && this->getCurrSkill()->getClass() != scDie) { + this->kill(); + } + } + } + + checkModelStateInfoForNewHpValue(); + + //printf("DE-APPLYING ATTACK BOOST BEFORE END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); + + for (unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) { + UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; + if (effect != NULL && effect->boost == boost + && effect->getSource() == source) { + delete effect; + currentAttackBoostEffects. + erase(currentAttackBoostEffects.begin() + i); + break; + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("DE-APPLIED ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n", + this->getType()->getName(false).c_str(), this->getId(), + source->getType()->getName(false).c_str(), source->getId(), + hp); + + //printf("DE-APPLYING ATTACK BOOST END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); + } + + void Unit::tick() { + + if (isAlive()) { + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + //if(this->getType()->getName() == "spearman") printf("Unit [%d - %s] start tick hp = %d\n",this->getId(),this->getType()->getName().c_str(),hp); + + + //regenerate hp upgrade / or boost + if (type->getTotalMaxHpRegeneration(&totalUpgrade) != 0) { + if (currSkill->getClass() != scBeBuilt) { + if (type->getTotalMaxHpRegeneration(&totalUpgrade) >= 0) { + checkItemInVault(&this->hp, this->hp); + int original_hp = this->hp; + this->hp += type->getTotalMaxHpRegeneration(&totalUpgrade); + if (this->hp > type->getTotalMaxHp(&totalUpgrade)) { + this->hp = type->getTotalMaxHp(&totalUpgrade); + } + if (original_hp != this->hp) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault(&this->hp, this->hp); + + checkModelStateInfoForNewHpValue(); + //if(this->getType()->getName() == "spearman") printf("tick hp#2 [type->getTotalMaxHpRegeneration(&totalUpgrade)] = %d type->getTotalMaxHp(&totalUpgrade) [%d] newhp = %d\n",type->getTotalMaxHpRegeneration(&totalUpgrade),type->getTotalMaxHp(&totalUpgrade),hp); + } + // If we have negative regeneration then check if the unit should die + else { + bool decHpResult = + decHp(-type->getTotalMaxHpRegeneration(&totalUpgrade)); + if (decHpResult) { + this->setCauseOfDeath(ucodStarvedRegeneration); + + Unit::game->getWorld()->getStats()->die(getFactionIndex(), + getType + ()->getCountUnitDeathInStats + ()); + game->getScriptManager()->onUnitDied(this); + } + StaticSound *sound = + static_cast < + const DieSkillType * + >(this->getType()->getFirstStOfClass(scDie))->getSound(); + if (sound != NULL + && (this->getFactionIndex() == + Unit::game->getWorld()->getThisFactionIndex() + || (game-> + getWorld()->showWorldForPlayer(game-> + getWorld + ()->getThisTeamIndex + ()) == true))) { + SoundRenderer::getInstance().playFx(sound); + } + } + } + } + //regenerate hp + else { + if (type->getTotalMaxHpRegeneration(&totalUpgrade) >= 0) { + if (currSkill->getClass() != scBeBuilt) { + checkItemInVault(&this->hp, this->hp); + int original_hp = this->hp; + this->hp += type->getTotalMaxHpRegeneration(&totalUpgrade); + if (this->hp > type->getTotalMaxHp(&totalUpgrade)) { + this->hp = type->getTotalMaxHp(&totalUpgrade); + } + if (original_hp != this->hp) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault(&this->hp, this->hp); + + checkModelStateInfoForNewHpValue(); + //if(this->getType()->getName() == "spearman") printf("tick hp#1 [type->getHpRegeneration()] = %d type->getTotalMaxHp(&totalUpgrade) [%d] newhp = %d\n",type->getHpRegeneration(),type->getTotalMaxHp(&totalUpgrade),hp); + } + } + // If we have negative regeneration then check if the unit should die + else { + bool decHpResult = + decHp(-type->getTotalMaxHpRegeneration(&totalUpgrade)); + if (decHpResult) { + this->setCauseOfDeath(ucodStarvedRegeneration); + + Unit::game->getWorld()->getStats()->die(getFactionIndex(), + getType + ()->getCountUnitDeathInStats + ()); + game->getScriptManager()->onUnitDied(this); + } + StaticSound *sound = + static_cast < + const DieSkillType * + >(this->getType()->getFirstStOfClass(scDie))->getSound(); + if (sound != NULL + && (this->getFactionIndex() == + Unit::game->getWorld()->getThisFactionIndex() + || (game-> + getWorld()->showWorldForPlayer(game-> + getWorld + ()->getThisTeamIndex + ()) == true))) { + SoundRenderer::getInstance().playFx(sound); + } + } + } + + //stop DamageParticles + stopDamageParticles(false); + + checkItemInVault(&this->ep, this->ep); + //regenerate ep + // ep += type->getEpRegeneration(); + // if(ep > type->getTotalMaxEp(&totalUpgrade)){ + // ep = type->getTotalMaxEp(&totalUpgrade); + // } + // addItemToVault(&this->ep,this->ep); + + if (!isBeingBuilt()) { + //regenerate ep upgrade / or boost + checkItemInVault(&this->ep, this->ep); + //regenerate ep + int original_ep = this->ep; + this->ep += type->getTotalMaxEpRegeneration(&totalUpgrade); + if (this->ep > type->getTotalMaxEp(&totalUpgrade)) { + this->ep = type->getTotalMaxEp(&totalUpgrade); + } + if (original_ep != this->ep) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_EPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault(&this->ep, this->ep); + } + } + } + + int Unit::update2() { + progress2++; + return progress2; + } + + bool Unit::computeEp() { + + if (currSkill == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + //if not enough ep + if (this->ep - currSkill->getEpCost() < 0) { + return true; + } + + checkItemInVault(&this->ep, this->ep); + int original_ep = this->ep; + //decrease ep + this->ep -= currSkill->getEpCost(); + if (original_ep != this->ep) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, utet_EPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault(&this->ep, this->ep); + + if (getType() == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: getType() == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + if (this->ep > getType()->getTotalMaxEp(&totalUpgrade)) { + int original_ep = this->ep; + this->ep = getType()->getTotalMaxEp(&totalUpgrade); + if (original_ep != this->ep) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_EPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + } + addItemToVault(&this->ep, this->ep); + + return false; + } + + bool Unit::repair() { + + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + //increase hp + checkItemInVault(&this->hp, this->hp); + int original_hp = this->hp; + if (type->getProductionTime() + 1 == 0) { + throw + megaglest_runtime_error + ("Detected divide by 0 condition: type->getProductionTime() + 1 == 0"); + } + this->hp += getType()->getMaxHp() / type->getProductionTime() + 1; + if (this->hp > (getType()->getTotalMaxHp(&totalUpgrade))) { + this->hp = getType()->getTotalMaxHp(&totalUpgrade); + if (original_hp != this->hp) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault(&this->hp, this->hp); + return true; + } + if (original_hp != this->hp) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault(&this->hp, this->hp); + + checkModelStateInfoForNewHpValue(); + + //stop DamageParticles + stopDamageParticles(false); + + return false; + } + + //decrements HP and returns if dead + bool Unit::decHp(int decrementValue) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "this->hp = %d, decrementValue = %d", this->hp, + decrementValue); + addNetworkCRCDecHp(szBuf); + + if (this->hp == 0) { + return false; + } + + checkItemInVault(&this->hp, this->hp); + int original_hp = this->hp; + this->hp -= decrementValue; + if (original_hp != this->hp) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault(&this->hp, this->hp); + + checkModelStateInfoForNewHpValue(); + + if (type == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + //startDamageParticles + startDamageParticles(); + + //stop DamageParticles on death + if (this->hp <= 0) { + setAlive(false); + this->hp = 0; + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + addItemToVault(&this->hp, this->hp); + + checkModelStateInfoForNewHpValue(); + + stopDamageParticles(true); + return true; + } + return false; + } + + string Unit::getDescExtension(bool translatedValue) const { + Lang & lang = Lang::getInstance(); + string str = "\n"; + + if (commands.empty() == false && commands.size() > 1) { + Commands::const_iterator it = commands.begin(); + for (unsigned int i = 0; + i < min((size_t) maxQueuedCommandDisplayCount, + commands.size()); ++i) { + const CommandType *ct = (*it)->getCommandType(); + if (i == 0) { + str += "\n" + lang.getString("OrdersOnQueue") + ": "; + } + str += + "\n#" + intToStr(i + 1) + " " + ct->getName(translatedValue); + ++it; + } + } + + return str; + } + + string Unit::getDesc(bool translatedValue) const { + + Lang & lang = Lang::getInstance(); + + //hp + string str = "\n"; + + //maxUnitCount + if (type->getMaxUnitCount() > 0) { + str += + lang.getString("MaxUnitCount") + ": " + + intToStr(faction->getCountForMaxUnitCount(type)) + "/" + + intToStr(type->getMaxUnitCount()); + } + + str += + "\n" + lang.getString("Hp") + ": " + intToStr(hp) + "/" + + intToStr(type->getTotalMaxHp(&totalUpgrade)); + if (type->getHpRegeneration() != 0 + || totalUpgrade.getMaxHpRegeneration() != 0) { + str += + " (" + lang.getString("Regeneration") + ": " + + intToStr(type->getHpRegeneration()); + if (totalUpgrade.getMaxHpRegeneration() != 0) { + str += "+" + intToStr(totalUpgrade.getMaxHpRegeneration()); + } + str += ")"; + } + + //ep + if (getType()->getMaxEp() != 0) { + str += + "\n" + lang.getString("Ep") + ": " + intToStr(ep) + "/" + + intToStr(type->getTotalMaxEp(&totalUpgrade)); + } + if (type->getEpRegeneration() != 0 + || totalUpgrade.getMaxEpRegeneration() != 0) { + str += + " (" + lang.getString("Regeneration") + ": " + + intToStr(type->getEpRegeneration()); + if (totalUpgrade.getMaxEpRegeneration() != 0) { + str += "+" + intToStr(totalUpgrade.getMaxEpRegeneration()); + } + str += ")"; + } + + //armor + str += + "\n" + lang.getString("Armor") + ": " + + intToStr(getType()->getArmor()); + if (totalUpgrade.getArmor() != 0) { + str += "+" + intToStr(totalUpgrade.getArmor()); + } + str += + " (" + getType()->getArmorType()->getName(translatedValue) + ")"; + + //sight + str += + "\n" + lang.getString("Sight") + ": " + + intToStr(getType()->getSight()); + if (totalUpgrade.getSight() != 0) { + str += "+" + intToStr(totalUpgrade.getSight()); + } + + //kills + const Level *nextLevel = getNextLevel(); + if (enemyKills > 0 || nextLevel != NULL) { + str += "\n" + lang.getString("Kills") + ": " + intToStr(enemyKills); + if (nextLevel != NULL) { + str += + " (" + nextLevel->getName(translatedValue) + ": " + + intToStr(nextLevel->getKills()) + ")"; + } + } + + //str+= "\nskl: "+scToStr(currSkill->getClass()); + + //load + if (loadCount != 0) { + str += + "\n" + lang.getString("Load") + ": " + intToStr(loadCount) + + " " + loadType->getName(translatedValue); + } + + //consumable production + for (int i = 0; i < getType()->getCostCount(); ++i) { + const Resource *r = getType()->getCost(i); + if (r->getType()->getClass() == rcConsumable) { + str += "\n"; + str += + r->getAmount() < + 0 ? lang.getString("Produce") + + ": " : lang.getString("Consume") + ": "; + str += + intToStr(abs(r->getAmount())) + " " + + r->getType()->getName(translatedValue); + } + } + + //command info + if (commands.empty() == false) { + str += + "\n" + + commands.front()->getCommandType()->getName(translatedValue); + if (commands.size() > 1) { + str += + "\n" + lang.getString("OrdersOnQueue") + ": " + + intToStr(commands.size()); + } + } else { + //can store + if (getType()->getStoredResourceCount() > 0) { + for (int i = 0; i < getType()->getStoredResourceCount(); ++i) { + const Resource *r = getType()->getStoredResource(i); + str += "\n" + lang.getString("Store") + ": "; + str += + intToStr(r->getAmount()) + " " + + r->getType()->getName(translatedValue); + } + } + } + + return str; + } + + void Unit::applyUpgrade(const UpgradeType * upgradeType) { + if (upgradeType == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: upgradeType == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + if (upgradeType->isAffected(type)) { + totalUpgrade.sum(upgradeType, this); + + checkItemInVault(&this->hp, this->hp); + int original_hp = this->hp; + this->hp += upgradeType->getMaxHp(); + this->hp = max(0, this->hp); + if (original_hp != this->hp) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault(&this->hp, this->hp); + + checkModelStateInfoForNewHpValue(); + } + } + + void Unit::computeTotalUpgrade() { + faction->getUpgradeManager()->computeTotalUpgrade(this, + &totalUpgrade); + } + + void Unit::incKills(int team) { + ++kills; + if (team != this->getTeam()) { + ++enemyKills; + } + + checkUnitLevel(); + } + + void Unit::checkUnitLevel() { + const Level *nextLevel = getNextLevel(); + if (nextLevel != NULL && this->enemyKills >= nextLevel->getKills()) { + this->level = nextLevel; + + int maxHp = this->totalUpgrade.getMaxHp(); + totalUpgrade.incLevel(type); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_LevelChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + + checkItemInVault(&this->hp, this->hp); + int original_hp = this->hp; + this->hp += totalUpgrade.getMaxHp() - maxHp; + if (original_hp != this->hp) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault(&this->hp, this->hp); + + checkModelStateInfoForNewHpValue(); + } + } + + void Unit::morphAttackBoosts(Unit * unit) { + // Remove any units that were previously in range + if (currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.empty() == false + && currentAttackBoostOriginatorEffect.skillType != NULL) { + for (int i = + (int) currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.size() - 1; i >= 0; --i) { + // Remove attack boost upgrades from unit + + int findUnitId = + currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; + Unit *affectedUnit = game->getWorld()->findUnitById(findUnitId); + if (affectedUnit != NULL + && affectedUnit->getId() == unit->getId()) { + affectedUnit->deapplyAttackBoost + (currentAttackBoostOriginatorEffect.skillType-> + getAttackBoost(), this); + + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.erase + (currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + begin() + i); + } + + //printf("- #1 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); + } + } + } + + bool Unit::morph(const MorphCommandType * mct, int frameIndex) { + + if (mct == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: mct == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + const UnitType *morphUnitType = mct->getMorphUnit(); + + if (morphUnitType == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: morphUnitType == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + Field morphUnitField = fLand; + if (morphUnitType->getField(fAir)) { + morphUnitField = fAir; + } + if (morphUnitType->getField(fLand)) { + morphUnitField = fLand; + } + + map->clearUnitCells(this, pos, false); + if (map->canMorph(pos, this, morphUnitType)) { + map->clearUnitCells(this, pos, true); + faction->deApplyStaticCosts(type, mct); + + //printf("Now unapply attack-boost for unit [%d - %s]\n",this->getId(),this->getType()->getName().c_str()); + // De apply attack boosts for morphed unit + for (int i = (int) currentAttackBoostEffects.size() - 1; i >= 0; --i) { + UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; + if (effect != NULL) { + Unit *sourceUnit = + game->getWorld()->findUnitById(effect-> + getSource()->getId()); + if (sourceUnit == NULL) { + throw megaglest_runtime_error("sourceUnit == NULL"); + } + sourceUnit->morphAttackBoosts(this); + } + } + + //stopDamageParticles(true); + cleanupAllParticlesystems(); + + checkItemInVault(&this->hp, this->hp); + int original_hp = this->hp; + this->hp += morphUnitType->getMaxHp() - type->getMaxHp(); + if (original_hp != this->hp) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault(&this->hp, this->hp); + + checkModelStateInfoForNewHpValue(); + + this->preMorph_type = this->type; + this->setType(morphUnitType); + Field original_field = this->currField; + this->currField = morphUnitField; + computeTotalUpgrade(); + map->putUnitCells(this, this->pos, false, frameIndex < 0); + + this->faction->applyDiscount(morphUnitType, mct->getDiscount()); + // add new storage + this->faction->addStore(this->type); + // remove former storage + this->faction->removeStore(this->preMorph_type); + this->faction->applyStaticProduction(morphUnitType, mct); + + this->level = NULL; + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_LevelChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + checkUnitLevel(); + + if (original_field != this->currField) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager()->onUnitTriggerEvent(this, + utet_FieldChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + + return true; + } else { + return false; + } + } + + + // ==================== PRIVATE ==================== + + float Unit::computeHeight(const Vec2i & pos) const { + //printf("CRASHING FOR UNIT: %d alive = %d\n",this->getId(),this->isAlive()); + //printf("[%s]\n",this->getType()->getName().c_str()); + if (map->isInside(pos) == false + || map->isInsideSurface(map->toSurfCoords(pos)) == false) { + //printf("CRASHING FOR UNIT: %d [%s] alive = %d\n",this->getId(),this->getType()->getName().c_str(),this->isAlive()); + //abort(); + throw megaglest_runtime_error("#7 Invalid path position = " + + pos.getString()); + } + + float height = map->getCell(pos)->getHeight(); + + if (currField == fAir) { + float airHeight = game->getWorld()->getTileset()->getAirHeight(); + airHeight = truncateDecimal < float >(airHeight, 6); + + height += airHeight; + height = truncateDecimal < float >(height, 6); + + Unit *unit = map->getCell(pos)->getUnit(fLand); + if (unit != NULL && unit->getType()->getHeight() > airHeight) { + height += + (std::min((float) unit->getType()->getHeight(), + Tileset::standardAirHeight * 3) - airHeight); + height = truncateDecimal < float >(height, 6); + } else { + SurfaceCell *sc = map->getSurfaceCell(map->toSurfCoords(pos)); + if (sc != NULL && sc->getObject() != NULL + && sc->getObject()->getType() != NULL) { + if (sc->getObject()->getType()->getHeight() > airHeight) { + height += + (std::min((float) sc->getObject()->getType()->getHeight(), + Tileset::standardAirHeight * 3) - airHeight); + height = truncateDecimal < float >(height, 6); + } + } + } + } + + return height; + } + + void Unit::AnimCycleStarts() { + // we need to queue timed particles if progress starts + queueTimedParticles(currSkill->unitParticleSystemTypes); + } + + void Unit::updateTarget() { + Unit *target = targetRef.getUnit(); + if (target != NULL) { + + //update target pos + targetPos = target->getCellPos(); + Vec2i relPos = targetPos - pos; + Vec2f relPosf = Vec2f((float) relPos.x, (float) relPos.y); +#ifdef USE_STREFLOP + targetRotation = + radToDeg(streflop::atan2 + (static_cast (relPosf.x), + static_cast (relPosf.y))); +#else + targetRotation = radToDeg(atan2(relPosf.x, relPosf.y)); +#endif + targetVec = target->getCurrVectorAsTarget(); + } + } + + void Unit::clearCommands() { + + this->setCurrentUnitTitle(""); + this->unitPath->clear(); + while (commands.empty() == false) { + undoCommand(commands.back()); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands, mutexOwnerId); + + delete commands.back(); + commands.pop_back(); + + safeMutex.ReleaseLock(); + } + changedActiveCommand = false; + } + + void Unit::deleteQueuedCommand(Command * command) { + if (getCurrCommand() == command) { + this->setCurrentUnitTitle(""); + this->unitPath->clear(); + } + undoCommand(command); + delete command; + } + + + std::pair < CommandResult, string > Unit::checkCommand(Command * command) const { + std::pair < CommandResult, string > result(crSuccess, ""); + + if (command == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + //if not operative or has not command type => fail + if (isOperative() == false || + command->getUnit() == this || + getType()->hasCommandType(command->getCommandType()) == false || + (ignoreCheckCommand == false + && this->getFaction()->reqsOk(command->getCommandType()) == + false)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d] isOperative() = %d, command->getUnit() = %p, getType()->hasCommandType(command->getCommandType()) = %d, this->getFaction()->reqsOk(command->getCommandType()) = %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, isOperative(), + command->getUnit(), + getType()-> + hasCommandType(command->getCommandType + ()), + this->getFaction()-> + reqsOk(command->getCommandType())); + + // Allow self healing if able to heal own unit type + if (command->getUnit() == this && + command->getCommandType()->getClass() == ccRepair && + this->getType()->getFirstRepairCommand(this->getType()) != + NULL) { + + } else { + //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); + + result.first = crFailUndefined; + return result; + } + } + + //if pos is not inside the world (if comand has not a pos, pos is (0, 0) and is inside world + if (map->isInside(command->getPos()) == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); + + result.first = crFailUndefined; + return result; + } + + //check produced + if (command->getCommandType() == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + const ProducibleType *produced = + command->getCommandType()->getProduced(); + if (produced != NULL) { + if (ignoreCheckCommand == false + && faction->reqsOk(produced) == false) { + //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); + //printf("To produce this unit you need:\n%s\n",produced->getUnitAndUpgradeReqDesc().c_str()); + result.first = crFailReqs; + + Lang & lang = Lang::getInstance(); + result.second = + " - " + lang.getString("Reqs") + " : " + + produced->getUnitAndUpgradeReqDesc(false, + this->showTranslatedTechTree + ()); + return result; + } + + if (ignoreCheckCommand == false && + faction->checkCosts(produced, + command->getCommandType()) == false) { + //printf("To produce this unit you need:\n%s\n",produced->getResourceReqDesc().c_str()); + //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); + result.first = crFailRes; + Lang & lang = Lang::getInstance(); + result.second = + " - " + lang.getString("Reqs") + " : " + + produced->getResourceReqDesc(false, + this->showTranslatedTechTree()); + return result; + } + } + + //build command specific, check resources and requirements for building + if (command->getCommandType()->getClass() == ccBuild) { + const UnitType *builtUnit = command->getUnitType(); + + if (builtUnit == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: builtUnit == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + if (faction->reqsOk(builtUnit) == false) { + //printf("To build this unit you need:\n%s\n",builtUnit->getUnitAndUpgradeReqDesc().c_str()); + //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); + result.first = crFailReqs; + Lang & lang = Lang::getInstance(); + result.second = + " - " + lang.getString("Reqs") + " : " + + builtUnit->getUnitAndUpgradeReqDesc(false, + this->showTranslatedTechTree + ()); + return result; + } + if (faction->checkCosts(builtUnit, NULL) == false) { + //printf("To build this unit you need:\n%s\n",builtUnit->getResourceReqDesc().c_str()); + //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); + result.first = crFailRes; + Lang & lang = Lang::getInstance(); + result.second = + " - " + lang.getString("Reqs") + " : " + + builtUnit->getResourceReqDesc(false, + this->showTranslatedTechTree()); + return result; + } + } + //upgrade command specific, check that upgrade is not upgraded + else if (command->getCommandType()->getClass() == ccUpgrade) { + const UpgradeCommandType *uct = + static_cast < + const UpgradeCommandType *>(command->getCommandType()); + + if (uct == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + if (faction-> + getUpgradeManager()->isUpgradingOrUpgraded(uct-> + getProducedUpgrade + ())) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug(SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__); + //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); + result.first = crFailUndefined; + return result; + } + } + + return result; + } + + void Unit::applyCommand(Command * command) { + if (command == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } else if (command->getCommandType() == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + //check produced + const ProducibleType *produced = + command->getCommandType()->getProduced(); + if (produced != NULL) { + faction->applyCosts(produced, command->getCommandType()); + } + + //build command specific + if (command->getCommandType()->getClass() == ccBuild) { + faction->applyCosts(command->getUnitType(), + command->getCommandType()); + } + //upgrade command specific + else if (command->getCommandType()->getClass() == ccUpgrade) { + const UpgradeCommandType *uct = + static_cast < + const UpgradeCommandType *>(command->getCommandType()); + + if (uct == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + faction->startUpgrade(uct->getProducedUpgrade()); + } + } + + CommandResult Unit::undoCommand(Command * command) { + + if (command == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } else if (command->getCommandType() == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + if (getCurrCommand() == command + && command->getCommandType()->getClass() == ccMorph + && this->currSkill->getClass() == scMorph) { + // clear cells of morphed unit and set those of current unit! + map->clearUnitCells(this, this->getPos()); + map->putUnitCells(this, this->getPos(), true); + } + //return cost + const ProducibleType *produced = + command->getCommandType()->getProduced(); + if (produced != NULL) { + faction->deApplyCosts(produced, command->getCommandType()); + } + + //return building cost if not already building it or dead + if (command->getCommandType()->getClass() == ccBuild) { + if (currSkill->getClass() != scBuild + && currSkill->getClass() != scDie) { + faction->deApplyCosts(command->getUnitType(), + command->getCommandType()); + } + } + + //upgrade command cancel from list + if (command->getCommandType()->getClass() == ccUpgrade) { + const UpgradeCommandType *uct = + static_cast < + const UpgradeCommandType *>(command->getCommandType()); + if (uct == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, this->toString().c_str()); + throw megaglest_runtime_error(szBuf); + } + + faction->cancelUpgrade(uct->getProducedUpgrade()); + } + + retryCurrCommandCount = 0; + this->setCurrentUnitTitle(""); + + return crSuccess; + } + + void Unit::stopDamageParticles(bool force) { + if (force == true || (hp > type->getTotalMaxHp(&totalUpgrade) / 2)) { + //printf("Checking to stop damageparticles for unit [%s - %d] hp = %d\n",this->getType()->getName().c_str(),this->getId(),hp); + + if (Renderer:: + getInstance().validateParticleSystemStillExists(this->fire, + rsGame) == + false) { + this->fire = NULL; + } + + // stop fire + if (this->fire != NULL) { + this->fire->fade(); + this->fire = NULL; + } + // stop additional particles + + + if (smokeParticleSystems.empty() == false) { + //printf("Checking to stop smokeparticles for unit [%s - %d] hp = %d\n",this->getType()->getName().c_str(),this->getId(),hp); + + for (int i = (int) smokeParticleSystems.size() - 1; i >= 0; --i) { + UnitParticleSystem *ps = smokeParticleSystems[i]; + if (Renderer:: + getInstance().validateParticleSystemStillExists(ps, + rsGame) == + true) { + ps->fade(); + } + smokeParticleSystems.pop_back(); + } + } + + if (damageParticleSystems.empty() == false) { + //printf("Checking to stop damageparticles for unit [%s - %d] hp = %d\n",this->getType()->getName().c_str(),this->getId(),hp); + + for (int i = (int) damageParticleSystems.size() - 1; i >= 0; --i) { + UnitParticleSystem *ps = damageParticleSystems[i]; + UnitParticleSystemType *pst = NULL; + int foundParticleIndexType = -2; + if (Renderer:: + getInstance().validateParticleSystemStillExists(ps, + rsGame) == + true) { + for (std::map < int, UnitParticleSystem * >::iterator iterMap = + damageParticleSystemsInUse.begin(); + iterMap != damageParticleSystemsInUse.end(); ++iterMap) { + if (iterMap->second == ps) { + foundParticleIndexType = iterMap->first; + if (foundParticleIndexType >= 0) { + pst = + type->damageParticleSystemTypes[foundParticleIndexType]; + break; + } + } + } + } + if (force == true + || (pst != NULL && pst->getMinmaxEnabled() == false)) { + damageParticleSystemsInUse.erase(foundParticleIndexType); + if (Renderer:: + getInstance().validateParticleSystemStillExists(ps, + rsGame) == + true) { + ps->fade(); + } + damageParticleSystems.pop_back(); + } + } + } + } + + checkCustomizedParticleTriggers(force); + } + + void Unit:: + checkCustomizedUnitParticleListTriggers(const UnitParticleSystemTypes & + unitParticleSystemTypesList, + bool applySkillChangeParticles) { + if (showUnitParticles == true) { + vector < ParticleSystemTypeInterface * >systemTypesInUse; + + if (unitParticleSystems.empty() == false) { + for (int index = (int) unitParticleSystems.size() - 1; index >= 0; + index--) { + UnitParticleSystem *ps = unitParticleSystems[index]; + if (ps != NULL) { + if (Renderer:: + getInstance().validateParticleSystemStillExists(ps, + rsGame) == + true) { + + bool stopParticle = false; + if ((ps->getParticleType() != NULL && + ps->getParticleType()->getMinmaxEnabled())) { + + if (ps->getParticleType() != NULL) { + if (ps->getParticleType()->getMinmaxIsPercent() == + false) { + if (hp < ps->getParticleType()->getMinHp() + || hp > ps->getParticleType()->getMaxHp()) { + stopParticle = true; + + //printf("STOP Particle line: %d\n",__LINE__); + } + } else { + int hpPercent = + (hp / type->getTotalMaxHp(&totalUpgrade) * 100); + if (hpPercent < ps->getParticleType()->getMinHp() + || hpPercent > ps->getParticleType()->getMaxHp()) { + stopParticle = true; + + //printf("STOP Particle line: %d\n",__LINE__); + } + } + } + + if (stopParticle == true) { + ps->fade(); + unitParticleSystems.erase(unitParticleSystems.begin() + + index); + } + } + + if (ps->getParticleType() != NULL && stopParticle == false) { + systemTypesInUse.push_back(ps->getParticleType()); + } + } + } + } + } + + //printf("Check Particle start line: %d size: %d\n",__LINE__,(int)unitParticleSystemTypesList.size()); + + if (unitParticleSystemTypesList.empty() == false) { + + //for(unsigned int index = 0; index < unitParticleSystemTypesList.size(); ++index) { + for (UnitParticleSystemTypes::const_iterator iterParticleType = + unitParticleSystemTypesList.begin(); + iterParticleType != unitParticleSystemTypesList.end(); + ++iterParticleType) { + UnitParticleSystemType *pst = *iterParticleType; + + vector < ParticleSystemTypeInterface * >::iterator iterFind = + std::find(systemTypesInUse.begin(), systemTypesInUse.end(), + pst); + + //printf("Check Particle line: %d isenabled: %d already in use: %d\n",__LINE__,pst->getMinmaxEnabled(),(iterFind == systemTypesInUse.end())); + + bool showParticle = applySkillChangeParticles; + if (pst->getMinmaxEnabled() == true) { + + //printf("Check Particle line: %d isenabled: %d already in use: %d\n",__LINE__,pst->getMinmaxEnabled(),(iterFind != systemTypesInUse.end())); + + showParticle = false; + if (iterFind == systemTypesInUse.end()) { + if (pst->getMinmaxIsPercent() == false) { + if (hp >= pst->getMinHp() && hp <= pst->getMaxHp()) { + showParticle = true; + + //printf("START Particle line: %d\n",__LINE__); + } + } else { + int hpPercent = + (hp / type->getTotalMaxHp(&totalUpgrade) * 100); + if (hpPercent >= pst->getMinHp() + && hpPercent <= pst->getMaxHp()) { + showParticle = true; + + //printf("START Particle line: %d\n",__LINE__); + } + } + } + } + if (showParticle == true) { + if (pst->getStartTime() == 0.0) { + UnitParticleSystem *ups = new UnitParticleSystem(200); + ups->setParticleOwner(this); + ups->setParticleType(pst); + + pst->setValues(ups); + ups->setPos(getCurrVectorForParticlesystems()); + ups->setRotation(getRotation()); + setMeshPosInParticleSystem(ups); + if (getFaction()->getTexture()) { + ups->setFactionColor(getFaction()-> + getTexture()->getPixmapConst()-> + getPixel3f(0, 0)); + } + unitParticleSystems.push_back(ups); + Renderer::getInstance().manageParticleSystem(ups, rsGame); + } else { + // do nothing, timed particles are handled below in queueTimedParticles() + } + } + } + } + } + } + + void Unit:: + queueTimedParticles(const UnitParticleSystemTypes & + unitParticleSystemTypesList) { + if (showUnitParticles == true) { + for (UnitParticleSystemTypes::const_iterator iterParticleType = + unitParticleSystemTypesList.begin(); + iterParticleType != unitParticleSystemTypesList.end(); + ++iterParticleType) { + UnitParticleSystemType *pst = *iterParticleType; + if (pst->getMinmaxEnabled() == false) { + if (pst->getStartTime() != 0.0) { + queuedUnitParticleSystemTypes.push_back(pst); + } + } + } + } + } + + void Unit::setMeshPosInParticleSystem(UnitParticleSystem * ups) { + if (ups->getMeshName() != "") { + string meshName = ups->getMeshName(); + Model *model = getCurrentModelPtr(); + + // as it can happen that anim progress is a bit out of range we correct it to get something valid for the particle positions. + float currentAnimProgress = getAnimProgressAsFloat(); + if (currentAnimProgress > 1.f || currentAnimProgress < 0.f) { + currentAnimProgress = 0.f; + } + model->updateInterpolationVertices(currentAnimProgress, isAlive() + && !isAnimProgressBound()); + + bool foundMesh = false; + for (unsigned int i = 0; i < model->getMeshCount(); i++) { + //printf("meshName=%s\n",unitModel->getMesh(i)->getName().c_str()); + if (model->getMesh(i)->getName() == meshName) { + const InterpolationData *data = + model->getMesh(i)->getInterpolationData(); + const Vec3f *verticepos = data->getVertices(); + ups->setMeshPos(Vec3f + (verticepos->x, verticepos->y, verticepos->z)); + foundMesh = true; + break; + } + } + if (foundMesh == false) { + string meshesFound = model->getMesh(0)->getName(); + for (unsigned i = 1; i < model->getMeshCount(); i++) { + meshesFound += ", " + model->getMesh(i)->getName(); + } + + string errorString = + "Warning: Particle system is trying to find mesh '" + meshName + + "', but just found:\n'" + meshesFound + "' in file:\n'" + + model->getFileName() + "'\n"; + //throw megaglest_runtime_error(errorString); + printf("%s", errorString.c_str()); + } + } + } + + void Unit::checkCustomizedUnitParticleTriggers() { + if (currSkill != NULL) { + checkCustomizedUnitParticleListTriggers + (currSkill->unitParticleSystemTypes, false); + } + } + + void Unit::checkCustomizedParticleTriggers(bool force) { + // + // Now check if we have special pre-exisitng hp triggered particles and + // end those that should no longer display + // + // end s particles + if (damageParticleSystems.empty() == false) { + for (int i = (int) damageParticleSystems.size() - 1; i >= 0; --i) { + UnitParticleSystem *ps = damageParticleSystems[i]; + UnitParticleSystemType *pst = NULL; + int foundParticleIndexType = -2; + if (Renderer:: + getInstance().validateParticleSystemStillExists(ps, + rsGame) == + true) { + for (std::map < int, UnitParticleSystem * >::iterator iterMap = + damageParticleSystemsInUse.begin(); + iterMap != damageParticleSystemsInUse.end(); ++iterMap) { + if (iterMap->second == ps) { + foundParticleIndexType = iterMap->first; + if (foundParticleIndexType >= 0) { + pst = + type->damageParticleSystemTypes[foundParticleIndexType]; + break; + } + } + } + } + + if (force == true + || (pst != NULL && pst->getMinmaxEnabled() == true)) { + bool stopParticle = force; + if (force == false) { + if (pst->getMinmaxIsPercent() == false) { + if (hp < pst->getMinHp() || hp > pst->getMaxHp()) { + stopParticle = true; + } + } else { + int hpPercent = + (hp / type->getTotalMaxHp(&totalUpgrade) * 100); + if (hpPercent < pst->getMinHp() + || hpPercent > pst->getMaxHp()) { + stopParticle = true; + } + } + } + + //printf("CHECKING to STOP customized particle trigger by HP [%d to %d percentbased = %d] current hp = %d stopParticle = %d\n",pst->getMinHp(),pst->getMaxHp(),pst->getMinmaxIsPercent(),hp,stopParticle); + + if (stopParticle == true) { + //printf("STOPPING customized particle trigger by HP [%d to %d] current hp = %d\n",pst->getMinHp(),pst->getMaxHp(),hp); + + damageParticleSystemsInUse.erase(foundParticleIndexType); + if (Renderer:: + getInstance().validateParticleSystemStillExists(ps, + rsGame) == + true) { + ps->fade(); + } + damageParticleSystems.pop_back(); + } + } + } + } + + // + // Now check if we have new special hp triggered particles to display + // + //start additional particles + if (showUnitParticles && + type->damageParticleSystemTypes.empty() == false && + force == false && alive == true) { + for (unsigned int i = 0; i < type->damageParticleSystemTypes.size(); + ++i) { + UnitParticleSystemType *pst = type->damageParticleSystemTypes[i]; + + if (pst->getMinmaxEnabled() == true + && damageParticleSystemsInUse.find(i) == + damageParticleSystemsInUse.end()) { + bool showParticle = false; + if (pst->getMinmaxIsPercent() == false) { + if (hp >= pst->getMinHp() && hp <= pst->getMaxHp()) { + showParticle = true; + } + } else { + int hpPercent = + (hp / type->getTotalMaxHp(&totalUpgrade) * 100); + if (hpPercent >= pst->getMinHp() + && hpPercent <= pst->getMaxHp()) { + showParticle = true; + } + } + + //printf("CHECKING to START customized particle trigger by HP [%d to %d percentbased = %d] current hp = %d showParticle = %d\n",pst->getMinHp(),pst->getMaxHp(),pst->getMinmaxIsPercent(),hp,showParticle); + + if (showParticle == true) { + //printf("STARTING customized particle trigger by HP [%d to %d] current hp = %d\n",pst->getMinHp(),pst->getMaxHp(),hp); + + UnitParticleSystem *ups = new UnitParticleSystem(200); + ups->setParticleOwner(this); + ups->setParticleType(pst); + + pst->setValues(ups); + ups->setPos(getCurrVectorForParticlesystems()); + ups->setRotation(getRotation()); + setMeshPosInParticleSystem(ups); + if (getFaction()->getTexture()) { + ups->setFactionColor(getFaction()-> + getTexture()->getPixmapConst()-> + getPixel3f(0, 0)); + } + damageParticleSystems.push_back(ups); + damageParticleSystemsInUse[i] = ups; + Renderer::getInstance().manageParticleSystem(ups, rsGame); + } + } + } + } + + checkCustomizedUnitParticleTriggers(); + } + + void Unit::startDamageParticles() { + if (hp < type->getTotalMaxHp(&totalUpgrade) / 2 && hp > 0 + && alive == true) { + //start additional particles + if (showUnitParticles && + type->damageParticleSystemTypes.empty() == false) { + for (unsigned int i = 0; + i < type->damageParticleSystemTypes.size(); ++i) { + UnitParticleSystemType *pst = type->damageParticleSystemTypes[i]; + + if (pst->getMinmaxEnabled() == false + && damageParticleSystemsInUse.find(i) == + damageParticleSystemsInUse.end()) { + UnitParticleSystem *ups = new UnitParticleSystem(200); + ups->setParticleOwner(this); + ups->setParticleType(pst); + + pst->setValues(ups); + ups->setPos(getCurrVectorForParticlesystems()); + ups->setRotation(getRotation()); + setMeshPosInParticleSystem(ups); + if (getFaction()->getTexture()) { + ups->setFactionColor(getFaction()-> + getTexture()->getPixmapConst()-> + getPixel3f(0, 0)); + } + damageParticleSystems.push_back(ups); + damageParticleSystemsInUse[i] = ups; + Renderer::getInstance().manageParticleSystem(ups, rsGame); + } + } + } + + // start fire + if (type->getProperty(UnitType::pBurnable) && this->fire == NULL) { + FireParticleSystem *fps = new FireParticleSystem(200); + fps->setParticleOwner(this); + const Game *game = Renderer::getInstance().getGame(); + fps->setSpeed(2.5f / + game->getWorld()-> + getUpdateFps(this->getFactionIndex())); + fps->setPos(getCurrBurnVector()); + fps->setRadius(type->getSize() / 3.f); + fps->setTexture(CoreData::getInstance().getFireTexture()); + fps->setParticleSize(type->getSize() / 3.f); + this->fire = fps; + fireParticleSystems.push_back(fps); + + Renderer::getInstance().manageParticleSystem(fps, rsGame); + if (showUnitParticles == true) { + // smoke + UnitParticleSystem *ups = new UnitParticleSystem(400); + ups->setParticleOwner(this); + ups->setColorNoEnergy(Vec4f(0.0f, 0.0f, 0.0f, 0.13f)); + ups->setColor(Vec4f(0.115f, 0.115f, 0.115f, 0.22f)); + ups->setPos(getCurrBurnVector()); + ups->setRotation(getRotation()); + setMeshPosInParticleSystem(ups); + ups->setBlendMode(ups->strToBlendMode("black")); + ups->setOffset(Vec3f(0, 2, 0)); + ups->setDirection(Vec3f(0, 1, -0.2f)); + ups->setRadius(type->getSize() / 3.f); + ups->setShape(::Shared::Graphics::UnitParticleSystem::sLinear); + ups->setTexture(CoreData::getInstance().getFireTexture()); + const Game *game = Renderer::getInstance().getGame(); + ups->setSpeed(2.0f / + game->getWorld()-> + getUpdateFps(this->getFactionIndex())); + ups->setGravity(0.0004f); + ups->setEmissionRate(1); + ups->setMaxParticleEnergy(150); + ups->setSizeNoEnergy(type->getSize() * 0.6f); + ups->setParticleSize(type->getSize() * 0.8f); + smokeParticleSystems.push_back(ups); + //damageParticleSystemsInUse[-1] = ups; + Renderer::getInstance().manageParticleSystem(ups, rsGame); + } + } + } + + checkCustomizedParticleTriggers(false); + } + + void Unit::setMeetingPos(const Vec2i & meetingPos) { + this->meetingPos = meetingPos; + map->clampPos(this->meetingPos); + + if (map->isInside(this->meetingPos) == false + || map->isInsideSurface(map->toSurfCoords(this->meetingPos)) == + false) { + throw megaglest_runtime_error("#8 Invalid path position = " + + this->meetingPos.getString()); + } + + logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), + __LINE__); + } + + bool Unit::isMeetingPointSettable() const { + return (type != NULL ? type->getMeetingPoint() : false); + } + + uint32 Unit::getFrameCount() const { + uint32 frameCount = 0; + //const Game *game = Renderer::getInstance().getGame(); + if (game != NULL && game->getWorld() != NULL) { + int frameCountAsInt = game->getWorld()->getFrameCount(); + if (frameCountAsInt >= 0) { + frameCount = frameCountAsInt; + } + } + + return frameCount; + } + + void Unit::exploreCells(bool forceRefresh) { + if (this->isOperative() == true) { + const Vec2i & newPos = this->getCenteredPos(); + int sightRange = + this->getType()->getTotalSight(this->getTotalUpgrade()); + int teamIndex = this->getTeam(); + + if (game == NULL) { + throw megaglest_runtime_error("game == NULL"); + } else if (game->getWorld() == NULL) { + throw megaglest_runtime_error("game->getWorld() == NULL"); + } + + // Try the local unit exploration cache + if (!forceRefresh && + cacheExploredCellsKey.first == newPos && + cacheExploredCellsKey.second == sightRange) { + game->getWorld()->exploreCells(teamIndex, cacheExploredCells); + } else { + // Try the world exploration scan or possible cache + cacheExploredCells = + game->getWorld()->exploreCells(newPos, sightRange, teamIndex, + this); + + // Cache the result for this unit + cacheExploredCellsKey.first = newPos; + cacheExploredCellsKey.second = sightRange; + } + } + } + + void Unit::logSynchData(string file, int line, string source) { + logSynchDataCommon(file, line, source, false); + } + void Unit::logSynchDataThreaded(string file, int line, string source) { + logSynchDataCommon(file, line, source, true); + } + void Unit::logSynchDataCommon(string file, int line, string source, + bool threadedMode) { + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "FrameCount [%d] Unit = %d [%s][%s] pos = %s, lastPos = %s, targetPos = %s, targetVec = %s, meetingPos = %s, progress [" + MG_I64_SPECIFIER + "], progress2 [%d] random [%d]\nUnit Path [%s]\n", + getFrameCount(), id, getFullName(false).c_str(), + faction->getType()->getName(false).c_str(), + //getDesc().c_str(), + pos.getString().c_str(), + lastPos.getString().c_str(), + targetPos.getString().c_str(), + targetVec.getString().c_str(), + meetingPos.getString().c_str(), + // lastRotation, + // targetRotation, + // rotation, + progress, + progress2, + random.getLastNumber(), + (unitPath != + NULL ? unitPath->toString().c_str() : "NULL")); + + if (lastSynchDataString != string(szBuf) || + lastFile != file || lastLine != line || lastSource != source) { + lastSynchDataString = string(szBuf); + lastFile = file; + lastSource = source; + + char szBufDataText[8096] = ""; + snprintf(szBufDataText, 8096, + "----------------------------------- START [FRAME %d UNIT: %d - %s] ------------------------------------------------\n", + getFrameCount(), this->id, + this->getType()->getName(false).c_str()); + string logDataText = szBufDataText; + + snprintf(szBufDataText, 8096, "[%s::%d]\n", + extractFileFromDirectoryPath(file).c_str(), line); + logDataText += szBufDataText; + + if (source != "") { + snprintf(szBufDataText, 8096, "%s ", source.c_str()); + logDataText += szBufDataText; + } + snprintf(szBufDataText, 8096, "%s\n", szBuf); + logDataText += szBufDataText; + snprintf(szBufDataText, 8096, + "------------------------------------ END [FRAME %d UNIT: %d - %s] ------------------------------------------------\n", + getFrameCount(), this->id, + this->getType()->getName(false).c_str()); + logDataText += szBufDataText; + /* + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"----------------------------------- START [FRAME %d UNIT: %d - %s] ------------------------------------------------\n",getFrameCount(),this->id,this->getType()->getName().c_str()); + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"[%s::%d]\n",extractFileFromDirectoryPath(file).c_str(),line); + if(source != "") { + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"%s ",source.c_str()); + } + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"%s\n",szBuf); + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"------------------------------------ END [FRAME %d UNIT: %d - %s] ------------------------------------------------\n",getFrameCount(),this->id,this->getType()->getName().c_str()); + */ + if (threadedMode == false) { + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, "%s", + logDataText.c_str()); + } else { + this->faction->addWorldSynchThreadedLogList(logDataText); + } + } + } + } + + void Unit::addBadHarvestPos(const Vec2i & value) { + //Chrono chron; + //chron.start(); + badHarvestPosList[value] = getFrameCount(); + cleanupOldBadHarvestPos(); + } + + //void Unit::removeBadHarvestPos(const Vec2i &value) { + // std::map::iterator iter = badHarvestPosList.find(value); + // if(iter != badHarvestPosList.end()) { + // badHarvestPosList.erase(value); + // } + // cleanupOldBadHarvestPos(); + //} + + void Unit::cleanupOldBadHarvestPos() { + const unsigned int cleanupInterval = (GameConstants::updateFps * 5); + bool needToCleanup = (getFrameCount() % cleanupInterval == 0); + + //printf("========================> cleanupOldBadHarvestPos() [%d] badHarvestPosList.size [%ld] cleanupInterval [%d] getFrameCount() [%d] needToCleanup [%d]\n",getFrameCount(),badHarvestPosList.size(),cleanupInterval,getFrameCount(),needToCleanup); + + if (needToCleanup == true) { + //printf("========================> cleanupOldBadHarvestPos() [%d] badHarvestPosList.size [%ld]\n",getFrameCount(),badHarvestPosList.size()); + + std::vector < Vec2i > purgeList; + for (std::map < Vec2i, int >::iterator iter = + badHarvestPosList.begin(); iter != badHarvestPosList.end(); + ++iter) { + if (getFrameCount() - iter->second >= cleanupInterval) { + //printf("cleanupOldBadHarvestPos() [%d][%d]\n",getFrameCount(),iter->second); + purgeList.push_back(iter->first); + } + } + + if (purgeList.empty() == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "[cleaning old bad harvest targets] purgeList.size() [" + MG_SIZE_T_SPECIFIER "]", purgeList.size()); + logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), + __LINE__, szBuf); + + for (int i = 0; i < (int) purgeList.size(); ++i) { + const Vec2i & item = purgeList[i]; + badHarvestPosList.erase(item); + } + } + } + } + + void Unit::setLastHarvestResourceTarget(const Vec2i * pos) { + if (pos == NULL) { + lastHarvestResourceTarget.first = Vec2i(0); + //lastHarvestResourceTarget.second = 0; + } else { + const Vec2i resourceLocation = *pos; + if (resourceLocation != lastHarvestResourceTarget.first) { + lastHarvestResourceTarget.first = resourceLocation; + + //Chrono chron; + //chron.start(); + lastHarvestResourceTarget.second = getFrameCount(); + } else { + // If we cannot harvest for > 10 seconds tag the position + // as a bad one + const unsigned int addInterval = (GameConstants::updateFps * 5); + if (lastHarvestResourceTarget.second - getFrameCount() >= + addInterval) { + //printf("-----------------------> setLastHarvestResourceTarget() [%d][%d]\n",getFrameCount(),lastHarvestResourceTarget.second); + addBadHarvestPos(resourceLocation); + } + } + } + } + + //void Unit::addCurrentTargetPathTakenCell(const Vec2i &target,const Vec2i &cell) { + // if(currentTargetPathTaken.first != target) { + // currentTargetPathTaken.second.clear(); + // } + // currentTargetPathTaken.first = target; + // currentTargetPathTaken.second.push_back(cell); + //} + + void Unit::setLastPathfindFailedFrameToCurrentFrame() { + lastPathfindFailedFrame = getFrameCount(); + } + + bool Unit::isLastPathfindFailedFrameWithinCurrentFrameTolerance() const { + //static const bool enablePathfinderEnlargeMaxNodes = Config::getInstance().getBool("EnablePathfinderEnlargeMaxNodes","false"); + static const bool enablePathfinderEnlargeMaxNodes = false; + bool result = enablePathfinderEnlargeMaxNodes; + if (enablePathfinderEnlargeMaxNodes) { + const uint32 MIN_FRAME_ELAPSED_RETRY = 960; + result = + (getFrameCount() - lastPathfindFailedFrame >= + MIN_FRAME_ELAPSED_RETRY); + } + return result; + } + + void Unit::setLastStuckFrameToCurrentFrame() { + lastStuckFrame = getFrameCount(); + } + + bool Unit::isLastStuckFrameWithinCurrentFrameTolerance(bool evalMode) { + //const int MIN_FRAME_ELAPSED_RETRY = 300; + const uint32 MAX_BLOCKED_FRAME_THRESHOLD = 25000; + uint32 MIN_FRAME_ELAPSED_RETRY = 6; + if (lastStuckFrame < MAX_BLOCKED_FRAME_THRESHOLD) { + if (evalMode == true) { + MIN_FRAME_ELAPSED_RETRY = 4; + } else { + MIN_FRAME_ELAPSED_RETRY = + random.randRange(2, 6, intToStr(__LINE__)); + } + } else { + if (evalMode == true) { + MIN_FRAME_ELAPSED_RETRY = 7; + } else { + MIN_FRAME_ELAPSED_RETRY = + random.randRange(6, 8, intToStr(__LINE__)); + } + } + bool result(getFrameCount() - lastStuckFrame <= + (MIN_FRAME_ELAPSED_RETRY * 100)); + return result; + } + + Vec2i Unit::getPosWithCellMapSet() const { + Vec2i cellMapPos = + this->getType()->getFirstOccupiedCellInCellMap(pos); + return cellMapPos; + } + + string Unit::getUniquePickName() const { + string result = intToStr(id) + " - " + type->getName(false) + " : "; + result += pos.getString(); + return result; + } + + Vec2i Unit::getPos() { + Vec2i result; + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(mutexCommands, mutexOwnerId); + result = this->pos; + safeMutex.ReleaseLock(); + + return result; + } + + void Unit::clearCaches() { + cachedFow.surfPosAlphaList.clear(); + cachedFowPos = Vec2i(0, 0); + + cacheExploredCells.exploredCellList.clear(); + cacheExploredCells.visibleCellList.clear(); + cacheExploredCellsKey.first = Vec2i(-1, -1); + cacheExploredCellsKey.second = -1; + + if (unitPath != NULL) { + unitPath->clearCaches(); + } + + lastHarvestedResourcePos = Vec2i(0, 0); + } + + bool Unit::showTranslatedTechTree() const { + return (this->game != + NULL ? this->game->showTranslatedTechTree() : true); + } + + string Unit::getNetworkCRCDecHpList() const { + string result = ""; + if (networkCRCDecHpList.empty() == false) { + for (unsigned int index = 0; index < networkCRCDecHpList.size(); + ++index) { + result += networkCRCDecHpList[index] + " "; + } + } + return result; + } + std::string Unit::toString(bool crcMode) const { + std::string result = ""; + + result += "id = " + intToStr(this->id); + if (this->type != NULL) { + result += + " name [" + this->type->getName(false) + "][" + + intToStr(this->type->getId()) + "]"; + } + + if (this->faction != NULL) { + result += + "\nFactionIndex = " + intToStr(this->faction->getIndex()) + "\n"; + result += + "teamIndex = " + intToStr(this->faction->getTeam()) + "\n"; + result += + "startLocationIndex = " + + intToStr(this->faction->getStartLocationIndex()) + "\n"; + if (crcMode == false) { + result += + "thisFaction = " + intToStr(this->faction->getThisFaction()) + + "\n"; + result += + "control = " + intToStr(this->faction->getControlType()) + "\n"; + } + if (this->faction->getType() != NULL) { + result += + "factionName = " + this->faction->getType()->getName(false) + + "\n"; + } + } + + result += " hp = " + intToStr(this->hp); + result += " ep = " + intToStr(this->ep); + result += " loadCount = " + intToStr(this->loadCount); + result += " deadCount = " + intToStr(this->deadCount); + result += " progress = " + intToStr(this->progress); + result += "\n"; + result += "networkCRCLogInfo = " + networkCRCLogInfo; + result += "\n"; + if (crcMode == false) { + result += " lastAnimProgress = " + intToStr(this->lastAnimProgress); + result += " animProgress = " + intToStr(this->animProgress); + result += " highlight = " + floatToStr(this->highlight, 6); + } + result += " progress2 = " + intToStr(this->progress2); + result += " kills = " + intToStr(this->kills); + result += " enemyKills = " + intToStr(this->enemyKills); + result += "\n"; + + // WARNING!!! Don't access the Unit pointer in this->targetRef in this method or it causes + // a stack overflow + if (this->targetRef.getUnitId() >= 0) { + //result += " targetRef = " + this->targetRef.getUnit()->toString(); + result += + " targetRef = " + intToStr(this->targetRef.getUnitId()) + + " - factionIndex = " + + intToStr(this->targetRef.getUnitFaction()->getIndex()); + } + + result += " currField = " + intToStr(this->currField); + result += " targetField = " + intToStr(this->targetField); + if (level != NULL) { + result += " level = " + level->getName(); + } + result += "\n"; + result += " pos = " + pos.getString(); + result += " lastPos = " + lastPos.getString(); + result += "\n"; + result += " targetPos = " + targetPos.getString(); + result += " targetVec = " + targetVec.getString(); + result += " meetingPos = " + meetingPos.getString(); + result += "\n"; + + if (crcMode == false) { + result += " lastRotation = " + floatToStr(this->lastRotation, 6); + result += " targetRotation = " + floatToStr(this->targetRotation, 6); + result += " rotation = " + floatToStr(this->rotation, 6); + } + + if (loadType != NULL) { + result += " loadType = " + loadType->getName(); + } + + if (currSkill != NULL) { + result += " currSkill = " + currSkill->getName(); + } + result += "\n"; + + result += " toBeUndertaken = " + intToStr(this->toBeUndertaken); + result += " alive = " + intToStr(this->alive); + result += " showUnitParticles = " + intToStr(this->showUnitParticles); + + result += " totalUpgrade = " + totalUpgrade.toString(); + result += " " + this->unitPath->toString() + "\n"; + result += "\n"; + + result += "Command count = " + intToStr(commands.size()) + "\n"; + + int cmdIdx = 0; + for (Commands::const_iterator iterList = commands.begin(); + iterList != commands.end(); ++iterList) { + result += " index = " + intToStr(cmdIdx) + " "; + const Command *cmd = *iterList; + if (cmd != NULL) { + result += cmd->toString(false) + "\n"; + } + cmdIdx++; + } + result += "\n"; + + // int obsIdx = 0; + // for(Observers::const_iterator iterList = observers.begin(); iterList != observers.end(); ++iterList) { + // const UnitObserver *observer = *iterList; + // if(observer != NULL) { + // } + // + // obsIdx++; + // } + + result += "\n"; + + result += "modelFacing = " + intToStr(modelFacing.asInt()) + "\n"; + + result += + "retryCurrCommandCount = " + intToStr(retryCurrCommandCount) + "\n"; + + result += "screenPos = " + screenPos.getString() + "\n"; + + result += "currentUnitTitle = " + currentUnitTitle + "\n"; + + result += "inBailOutAttempt = " + intToStr(inBailOutAttempt) + "\n"; + + result += "random = " + intToStr(random.getLastNumber()) + "\n"; + if (this->random.getLastCaller() != "") { + result += "randomlastCaller = " + random.getLastCaller() + "\n"; + } + result += + "pathFindRefreshCellCount = " + intToStr(pathFindRefreshCellCount) + + "\n"; + + result += + "currentPathFinderDesiredFinalPos = " + + currentPathFinderDesiredFinalPos.getString() + "\n"; + + result += "lastStuckFrame = " + uIntToStr(lastStuckFrame) + "\n"; + result += "lastStuckPos = " + lastStuckPos.getString() + "\n"; + + if (attackParticleSystems.empty() == false) { + result += + "attackParticleSystems count = " + + intToStr(attackParticleSystems.size()) + "\n"; + } + if (networkCRCParticleLogInfo != "") { + result += + "networkCRCParticleLogInfo = " + networkCRCParticleLogInfo + "\n"; + } + if (networkCRCDecHpList.empty() == false) { + result += + "getNetworkCRCDecHpList() = " + getNetworkCRCDecHpList() + "\n"; + } + + if (getParticleInfo() != "") { + result += "getParticleInfo() = " + getParticleInfo() + "\n"; + } + for (unsigned int index = 0; index < attackParticleSystems.size(); + ++index) { + ParticleSystem *ps = attackParticleSystems[index]; + if (ps != NULL && + Renderer::getInstance().validateParticleSystemStillExists(ps, + rsGame) + == true) { + + result += + "attackParticleSystems #" + intToStr(index) + " = " + + ps->toString() + "\n"; + } + } + + return result; + } + + void Unit::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode *unitNode = rootNode->addChild("Unit"); + + // const int id; + unitNode->addAttribute("id", intToStr(id), mapTagReplacements); + // For info purposes only + unitNode->addAttribute("name", type->getName(false), + mapTagReplacements); + + // int hp; + unitNode->addAttribute("hp", intToStr(hp), mapTagReplacements); + // int ep; + unitNode->addAttribute("ep", intToStr(ep), mapTagReplacements); + // int loadCount; + unitNode->addAttribute("loadCount", intToStr(loadCount), + mapTagReplacements); + // int deadCount; + unitNode->addAttribute("deadCount", intToStr(deadCount), + mapTagReplacements); + // float progress; //between 0 and 1 + unitNode->addAttribute("progress", intToStr(progress), + mapTagReplacements); + // float lastAnimProgress; //between 0 and 1 + unitNode->addAttribute("lastAnimProgress", intToStr(lastAnimProgress), + mapTagReplacements); + // float animProgress; //between 0 and 1 + unitNode->addAttribute("animProgress", intToStr(animProgress), + mapTagReplacements); + // float highlight; + unitNode->addAttribute("highlight", floatToStr(highlight, 6), + mapTagReplacements); + // int progress2; + unitNode->addAttribute("progress2", intToStr(progress2), + mapTagReplacements); + // int kills; + unitNode->addAttribute("kills", intToStr(kills), mapTagReplacements); + // int enemyKills; + unitNode->addAttribute("enemyKills", intToStr(enemyKills), + mapTagReplacements); + // UnitReference targetRef; + targetRef.saveGame(unitNode); + // + // Field currField; + unitNode->addAttribute("currField", intToStr(currField), + mapTagReplacements); + // Field targetField; + unitNode->addAttribute("targetField", intToStr(targetField), + mapTagReplacements); + // const Level *level; + if (level != NULL) { + level->saveGame(unitNode); + } + // Vec2i pos; + unitNode->addAttribute("pos", pos.getString(), mapTagReplacements); + // Vec2i lastPos; + unitNode->addAttribute("lastPos", lastPos.getString(), + mapTagReplacements); + // Vec2i targetPos; //absolute target pos + unitNode->addAttribute("targetPos", targetPos.getString(), + mapTagReplacements); + // Vec3f targetVec; + unitNode->addAttribute("targetVec", targetVec.getString(), + mapTagReplacements); + // Vec2i meetingPos; + unitNode->addAttribute("meetingPos", meetingPos.getString(), + mapTagReplacements); + // + // float lastRotation; //in degrees + unitNode->addAttribute("lastRotation", floatToStr(lastRotation, 6), + mapTagReplacements); + // float targetRotation; + unitNode->addAttribute("targetRotation", + floatToStr(targetRotation, 6), + mapTagReplacements); + // float rotation; + unitNode->addAttribute("rotation", floatToStr(rotation, 6), + mapTagReplacements); + // float targetRotationZ; + unitNode->addAttribute("targetRotationZ", + floatToStr(targetRotationZ, 6), + mapTagReplacements); + // float targetRotationX; + unitNode->addAttribute("targetRotationX", + floatToStr(targetRotationX, 6), + mapTagReplacements); + // float rotationZ; + unitNode->addAttribute("rotationZ", floatToStr(rotationZ, 6), + mapTagReplacements); + // float rotationX; + unitNode->addAttribute("rotationX", floatToStr(rotationX, 6), + mapTagReplacements); + // const UnitType *type; + unitNode->addAttribute("type", type->getName(false), + mapTagReplacements); + + unitNode->addAttribute("preMorph_type", + (preMorph_type != + NULL ? preMorph_type->getName(false) : ""), + mapTagReplacements); + + // const ResourceType *loadType; + if (loadType != NULL) { + unitNode->addAttribute("loadType", loadType->getName(), + mapTagReplacements); + } + // const SkillType *currSkill; + if (currSkill != NULL) { + unitNode->addAttribute("currSkillName", currSkill->getName(), + mapTagReplacements); + unitNode->addAttribute("currSkillClass", + intToStr(currSkill->getClass()), + mapTagReplacements); + } + // int lastModelIndexForCurrSkillType; + unitNode->addAttribute("lastModelIndexForCurrSkillType", + intToStr(lastModelIndexForCurrSkillType), + mapTagReplacements); + // int animationRandomCycleCount; + unitNode->addAttribute("animationRandomCycleCount", + intToStr(animationRandomCycleCount), + mapTagReplacements); + // + // bool toBeUndertaken; + unitNode->addAttribute("toBeUndertaken", intToStr(toBeUndertaken), + mapTagReplacements); + // bool alive; + unitNode->addAttribute("alive", intToStr(alive), mapTagReplacements); + // bool showUnitParticles; + unitNode->addAttribute("showUnitParticles", + intToStr(showUnitParticles), + mapTagReplacements); + // Faction *faction; + // ParticleSystem *fire; + int linkFireIndex = -1; + if (this->fire != NULL + && Renderer:: + getInstance().validateParticleSystemStillExists(this->fire, + rsGame) == true) { + //fire->saveGame(unitNode); + bool fireInSystemList = false; + if (fireParticleSystems.empty() == false) { + for (unsigned int i = 0; i < fireParticleSystems.size(); ++i) { + ParticleSystem *ps = fireParticleSystems[i]; + if (ps == this->fire) { + linkFireIndex = i; + fireInSystemList = true; + break; + } + } + } + if (fireInSystemList == false) { + this->fire->saveGame(unitNode); + } + } + // TotalUpgrade totalUpgrade; + totalUpgrade.saveGame(unitNode); + // Map *map; + // + // UnitPathInterface *unitPath; + unitPath->saveGame(unitNode); + // WaypointPath waypointPath; + // + // Commands commands; + for (Commands::iterator it = commands.begin(); it != commands.end(); + ++it) { + (*it)->saveGame(unitNode, faction); + } + // Observers observers; + //for(Observers::iterator it = observers.begin(); it != observers.end(); ++it) { + // (*it)->saveGame(unitNode); + //} + + // vector unitParticleSystems; + if (unitParticleSystems.empty() == false) { + XmlNode *unitParticleSystemsNode = + unitNode->addChild("unitParticleSystems"); + + for (unsigned int i = 0; i < unitParticleSystems.size(); ++i) { + UnitParticleSystem *ups = unitParticleSystems[i]; + if (ups != NULL + && Renderer:: + getInstance().validateParticleSystemStillExists(ups, + rsGame) == + true) { + ups->saveGame(unitParticleSystemsNode); + } + } + } + // vector queuedUnitParticleSystemTypes; + if (queuedUnitParticleSystemTypes.empty() == false) { + XmlNode *queuedUnitParticleSystemTypesNode = + unitNode->addChild("queuedUnitParticleSystemTypes"); + for (unsigned int i = 0; i < queuedUnitParticleSystemTypes.size(); + ++i) { + UnitParticleSystemType *upst = queuedUnitParticleSystemTypes[i]; + if (upst != NULL) { + upst->saveGame(queuedUnitParticleSystemTypesNode); + } + } + } + // UnitParticleSystems damageParticleSystems; + if (damageParticleSystems.empty() == false) { + XmlNode *damageParticleSystemsNode = + unitNode->addChild("damageParticleSystems"); + for (unsigned int i = 0; i < damageParticleSystems.size(); ++i) { + UnitParticleSystem *ups = damageParticleSystems[i]; + if (ups != NULL + && Renderer:: + getInstance().validateParticleSystemStillExists(ups, + rsGame) == + true) { + ups->saveGame(damageParticleSystemsNode); + } + } + } + // std::map damageParticleSystemsInUse; + if (damageParticleSystemsInUse.empty() == false) { + XmlNode *damageParticleSystemsInUseNode = + unitNode->addChild("damageParticleSystemsInUse"); + + for (std::map < int, UnitParticleSystem * >::const_iterator iterMap = + damageParticleSystemsInUse.begin(); + iterMap != damageParticleSystemsInUse.end(); ++iterMap) { + if (iterMap->second != NULL + && Renderer:: + getInstance().validateParticleSystemStillExists(iterMap-> + second, + rsGame) == + true) { + XmlNode *damageParticleSystemsInUseNode2 = + damageParticleSystemsInUseNode->addChild + ("damageParticleSystemsInUse"); + + damageParticleSystemsInUseNode2->addAttribute("key", + intToStr + (iterMap->first), + mapTagReplacements); + iterMap->second->saveGame(damageParticleSystemsInUseNode2); + } + } + } + + // vector fireParticleSystems; + if (fireParticleSystems.empty() == false) { + XmlNode *fireParticleSystemsNode = + unitNode->addChild("fireParticleSystems"); + + if (linkFireIndex >= 0) { + fireParticleSystemsNode->addAttribute("fireParticleLink", + intToStr(linkFireIndex), + mapTagReplacements); + } + + for (unsigned int i = 0; i < fireParticleSystems.size(); ++i) { + ParticleSystem *ps = fireParticleSystems[i]; + if (ps != NULL + && Renderer:: + getInstance().validateParticleSystemStillExists(ps, + rsGame) == + true) { + ps->saveGame(fireParticleSystemsNode); + } + } + } + + // vector smokeParticleSystems; + if (smokeParticleSystems.empty() == false) { + XmlNode *smokeParticleSystemsNode = + unitNode->addChild("smokeParticleSystems"); + for (unsigned int i = 0; i < smokeParticleSystems.size(); ++i) { + UnitParticleSystem *ups = smokeParticleSystems[i]; + if (ups != NULL + && Renderer:: + getInstance().validateParticleSystemStillExists(ups, + rsGame) == + true) { + ups->saveGame(smokeParticleSystemsNode); + //printf("Saving smoke particles:\n[%s]\n",ups->toString().c_str()); + } + } + } + + // CardinalDir modelFacing; + unitNode->addAttribute("modelFacing", intToStr(modelFacing), + mapTagReplacements); + + // std::string lastSynchDataString; + unitNode->addAttribute("lastSynchDataString", lastSynchDataString, + mapTagReplacements); + // std::string lastFile; + unitNode->addAttribute("lastFile", lastFile, mapTagReplacements); + // int lastLine; + unitNode->addAttribute("lastLine", intToStr(lastLine), + mapTagReplacements); + // std::string lastSource; + unitNode->addAttribute("lastSource", lastSource, mapTagReplacements); + // int lastRenderFrame; + unitNode->addAttribute("lastRenderFrame", intToStr(lastRenderFrame), + mapTagReplacements); + // bool visible; + unitNode->addAttribute("visible", intToStr(visible), + mapTagReplacements); + // int retryCurrCommandCount; + unitNode->addAttribute("retryCurrCommandCount", + intToStr(retryCurrCommandCount), + mapTagReplacements); + // Vec3f screenPos; + unitNode->addAttribute("screenPos", screenPos.getString(), + mapTagReplacements); + // string currentUnitTitle; + unitNode->addAttribute("currentUnitTitle", currentUnitTitle, + mapTagReplacements); + // + // bool inBailOutAttempt; + unitNode->addAttribute("inBailOutAttempt", intToStr(inBailOutAttempt), + mapTagReplacements); + // //std::vector > badHarvestPosList; + // std::map badHarvestPosList; + for (std::map < Vec2i, int >::const_iterator iterMap = + badHarvestPosList.begin(); iterMap != badHarvestPosList.end(); + ++iterMap) { + XmlNode *badHarvestPosListNode = + unitNode->addChild("badHarvestPosList"); + + badHarvestPosListNode->addAttribute("key", + iterMap->first.getString(), + mapTagReplacements); + badHarvestPosListNode->addAttribute("value", + intToStr(iterMap->second), + mapTagReplacements); + } + + // //time_t lastBadHarvestListPurge; + // std::pair lastHarvestResourceTarget; + XmlNode *lastHarvestResourceTargetNode = + unitNode->addChild("lastHarvestResourceTarget"); + lastHarvestResourceTargetNode->addAttribute("key", + lastHarvestResourceTarget.first. + getString(), + mapTagReplacements); + lastHarvestResourceTargetNode->addAttribute("value", + intToStr + (lastHarvestResourceTarget.second), + mapTagReplacements); + + // //std::pair > currentTargetPathTaken; + // static Game *game; + // + // bool ignoreCheckCommand; + unitNode->addAttribute("ignoreCheckCommand", + intToStr(ignoreCheckCommand), + mapTagReplacements); + // uint32 lastStuckFrame; + unitNode->addAttribute("lastStuckFrame", uIntToStr(lastStuckFrame), + mapTagReplacements); + // Vec2i lastStuckPos; + unitNode->addAttribute("lastStuckPos", lastStuckPos.getString(), + mapTagReplacements); + // uint32 lastPathfindFailedFrame; + unitNode->addAttribute("lastPathfindFailedFrame", + intToStr(lastPathfindFailedFrame), + mapTagReplacements); + // Vec2i lastPathfindFailedPos; + unitNode->addAttribute("lastPathfindFailedPos", + lastPathfindFailedPos.getString(), + mapTagReplacements); + // bool usePathfinderExtendedMaxNodes; + unitNode->addAttribute("usePathfinderExtendedMaxNodes", + intToStr(usePathfinderExtendedMaxNodes), + mapTagReplacements); + // int maxQueuedCommandDisplayCount; + unitNode->addAttribute("maxQueuedCommandDisplayCount", + intToStr(maxQueuedCommandDisplayCount), + mapTagReplacements); + // UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect; + currentAttackBoostOriginatorEffect.saveGame(unitNode); + // std::vector currentAttackBoostEffects; + for (unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) { + UnitAttackBoostEffect *uabe = currentAttackBoostEffects[i]; + if (uabe != NULL) { + uabe->saveGame(unitNode); + } + } + + // Mutex *mutexCommands; + // + // //static Mutex mutexDeletedUnits; + // //static std::map deletedUnits; + // + // bool changedActiveCommand; + unitNode->addAttribute("changedActiveCommand", + intToStr(changedActiveCommand), + mapTagReplacements); + // int lastAttackerUnitId; + unitNode->addAttribute("lastAttackerUnitId", + intToStr(lastAttackerUnitId), + mapTagReplacements); + // int lastAttackedUnitId; + unitNode->addAttribute("lastAttackedUnitId", + intToStr(lastAttackedUnitId), + mapTagReplacements); + // CauseOfDeathType causeOfDeath; + unitNode->addAttribute("causeOfDeath", intToStr(causeOfDeath), + mapTagReplacements); + + //pathfindFailedConsecutiveFrameCount + unitNode->addAttribute("pathfindFailedConsecutiveFrameCount", + intToStr(pathfindFailedConsecutiveFrameCount), + mapTagReplacements); + + unitNode->addAttribute("currentPathFinderDesiredFinalPos", + currentPathFinderDesiredFinalPos.getString(), + mapTagReplacements); + + unitNode->addAttribute("random", intToStr(random.getLastNumber()), + mapTagReplacements); + unitNode->addAttribute("pathFindRefreshCellCount", + intToStr(pathFindRefreshCellCount), + mapTagReplacements); + } + + Unit *Unit::loadGame(const XmlNode * rootNode, GameSettings * settings, + Faction * faction, World * world) { + const XmlNode *unitNode = rootNode; + + int newUnitId = unitNode->getAttribute("id")->getIntValue(); + Vec2i newUnitPos = + Vec2i::strToVec2(unitNode->getAttribute("pos")->getValue()); + string newUnitType = unitNode->getAttribute("type")->getValue(); + const UnitType *ut = faction->getType()->getUnitType(newUnitType); + CardinalDir newModelFacing = + static_cast + (unitNode->getAttribute("modelFacing")->getIntValue()); + + // Unit *result = new Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, + // const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing) : BaseColorPickEntity(), id(id) { + + UnitPathInterface *newpath = NULL; + switch (settings->getPathFinderType()) { + case pfBasic: + newpath = new UnitPathBasic(); + break; + default: + throw + megaglest_runtime_error("detected unsupported pathfinder type!"); + } + + newpath->loadGame(unitNode); + //Unit *result = new Unit(getNextUnitId(f), newpath, Vec2i(0), ut, f, &map, CardinalDir::NORTH); + //Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing); + Unit *result = new Unit(newUnitId, newpath, newUnitPos, ut, faction, + world->getMapPtr(), newModelFacing); + + if (unitNode->hasAttribute("preMorph_name") == true) { + string newUnitType_preMorph = + unitNode->getAttribute("preMorph_name")->getValue(); + const UnitType *ut_premorph = + faction->getType()->getUnitType(newUnitType_preMorph); + result->preMorph_type = ut_premorph; + } + + result->lastRotation = + unitNode->getAttribute("lastRotation")->getFloatValue(); + result->targetRotation = + unitNode->getAttribute("targetRotation")->getFloatValue(); + result->rotation = + unitNode->getAttribute("rotation")->getFloatValue(); + + //world->placeUnitAtLocation(newUnitPos, generationArea, unit, true); + //result->setPos(newUnitPos); + //Vec2i meetingPos = newUnitPos-Vec2i(1); + //result->setMeetingPos(meetingPos); + result->pos = newUnitPos; + result->lastPos = + Vec2i::strToVec2(unitNode->getAttribute("lastPos")->getValue()); + result->meetingPos = + Vec2i::strToVec2(unitNode->getAttribute("meetingPos")->getValue()); + // Attempt to improve performance + //result->exploreCells(); + //result->calculateFogOfWarRadius(); + // -------------------------- + + result->hp = unitNode->getAttribute("hp")->getIntValue(); + // int ep; + result->ep = unitNode->getAttribute("ep")->getIntValue(); + // int loadCount; + result->loadCount = + unitNode->getAttribute("loadCount")->getIntValue(); + // int deadCount; + result->deadCount = + unitNode->getAttribute("deadCount")->getIntValue(); + // float progress; //between 0 and 1 + try { + result->progress = + unitNode->getAttribute("progress")->getIntValue(); + } +#ifdef WIN32 + catch (const exception &) { +#else + catch (const exception & ex) { +#endif + result->progress = + unitNode->getAttribute("progress")->getFloatValue(); + } + // float lastAnimProgress; //between 0 and 1 + try { + result->lastAnimProgress = + unitNode->getAttribute("lastAnimProgress")->getIntValue(); + } +#ifdef WIN32 + catch (const exception &) { +#else + catch (const exception & ex) { +#endif + result->lastAnimProgress = + unitNode->getAttribute("lastAnimProgress")->getFloatValue(); + } + + // float animProgress; //between 0 and 1 + try { + result->animProgress = + unitNode->getAttribute("animProgress")->getIntValue(); + } +#ifdef WIN32 + catch (const exception &) { +#else + catch (const exception & ex) { +#endif + result->animProgress = + unitNode->getAttribute("animProgress")->getFloatValue(); + } + + // float highlight; + result->highlight = + unitNode->getAttribute("highlight")->getFloatValue(); + // int progress2; + result->progress2 = + unitNode->getAttribute("progress2")->getIntValue(); + // int kills; + result->kills = unitNode->getAttribute("kills")->getIntValue(); + // int enemyKills; + result->enemyKills = + unitNode->getAttribute("enemyKills")->getIntValue(); + // UnitReference targetRef; + // targetRef.saveGame(unitNode); + result->targetRef.loadGame(unitNode, world); + // + // Field currField; + result->currField = + static_cast + (unitNode->getAttribute("currField")->getIntValue()); + // Field targetField; + result->targetField = + static_cast + (unitNode->getAttribute("targetField")->getIntValue()); + // const Level *level; + // if(level != NULL) { + // level->saveGame(unitNode); + // } + result->level = Level::loadGame(unitNode, ut); + // Vec2i pos; + result->pos = + Vec2i::strToVec2(unitNode->getAttribute("pos")->getValue()); + // Vec2i lastPos; + result->lastPos = + Vec2i::strToVec2(unitNode->getAttribute("lastPos")->getValue()); + // Vec2i targetPos; //absolute target pos + result->targetPos = + Vec2i::strToVec2(unitNode->getAttribute("targetPos")->getValue()); + // Vec3f targetVec; + result->targetVec = + Vec3f::strToVec3(unitNode->getAttribute("targetVec")->getValue()); + // Vec2i meetingPos; + result->meetingPos = + Vec2i::strToVec2(unitNode->getAttribute("meetingPos")->getValue()); + // + // float lastRotation; //in degrees + result->lastRotation = + unitNode->getAttribute("lastRotation")->getFloatValue(); + // float targetRotation; + result->targetRotation = + unitNode->getAttribute("targetRotation")->getFloatValue(); + // float rotation; + result->rotation = + unitNode->getAttribute("rotation")->getFloatValue(); + // float targetRotationZ; + result->targetRotationZ = + unitNode->getAttribute("targetRotationZ")->getFloatValue(); + // float targetRotationX; + result->targetRotationX = + unitNode->getAttribute("targetRotationX")->getFloatValue(); + // float rotationZ; + result->rotationZ = + unitNode->getAttribute("rotationZ")->getFloatValue(); + // float rotationX; + result->rotationX = + unitNode->getAttribute("rotationX")->getFloatValue(); + // const UnitType *type; + // unitNode->addAttribute("type",type->getName(), mapTagReplacements); + // const ResourceType *loadType; + // if(loadType != NULL) { + // unitNode->addAttribute("loadType",loadType->getName(), mapTagReplacements); + // } + if (unitNode->hasAttribute("loadType") == true) { + string loadTypeName = + unitNode->getAttribute("loadType")->getValue(); + result->loadType = + world->getTechTree()->getResourceType(loadTypeName); + } + // const SkillType *currSkill; + // if(currSkill != NULL) { + // unitNode->addAttribute("currSkill",currSkill->getName(), mapTagReplacements); + // } + if (unitNode->hasAttribute("currSkillName") == true) { + string skillTypeName = + unitNode->getAttribute("currSkillName")->getValue(); + SkillClass skillClass = + static_cast + (unitNode->getAttribute("currSkillClass")->getIntValue()); + result->currSkill = ut->getSkillType(skillTypeName, skillClass); + result->setCurrSkill(result->currSkill); + } + + // int lastModelIndexForCurrSkillType; + result->lastModelIndexForCurrSkillType = + unitNode-> + getAttribute("lastModelIndexForCurrSkillType")->getIntValue(); + // int animationRandomCycleCount; + result->animationRandomCycleCount = + unitNode->getAttribute("animationRandomCycleCount")->getIntValue(); + // + // bool toBeUndertaken; + result->toBeUndertaken = + unitNode->getAttribute("toBeUndertaken")->getIntValue() != 0; + // bool alive; + result->setAlive(unitNode->getAttribute("alive")->getIntValue() != + 0); + // bool showUnitParticles; + result->showUnitParticles = + unitNode->getAttribute("showUnitParticles")->getIntValue() != 0; + // Faction *faction; + // ParticleSystem *fire; + // if(fire != NULL) { + // fire->saveGame(unitNode); + // } + if (unitNode->hasChild("FireParticleSystem") == true) { + XmlNode *fireNode = unitNode->getChild("FireParticleSystem"); + result->fire = new FireParticleSystem(); + result->fire->setParticleOwner(result); + result->fire->loadGame(fireNode); + //result->fire->setTexture(CoreData::getInstance().getFireTexture()); + result->fireParticleSystems.push_back(result->fire); + + //printf("Load MAIN fire particle result->fire = %p\n",result->fire); + + Renderer:: + getInstance().addToDeferredParticleSystemList(make_pair + (result->fire, + rsGame)); + } + + // TotalUpgrade totalUpgrade; + result->totalUpgrade.loadGame(unitNode); + // Map *map; + // + // UnitPathInterface *unitPath; + // unitPath->saveGame(unitNode); + // WaypointPath waypointPath; + // + // Commands commands; + // for(Commands::iterator it = commands.begin(); it != commands.end(); ++it) { + // (*it)->saveGame(unitNode); + // } + vector < XmlNode * >commandNodeList = + unitNode->getChildList("Command"); + for (unsigned int i = 0; i < commandNodeList.size(); ++i) { + XmlNode *node = commandNodeList[i]; + Command *command = Command::loadGame(node, ut, world); + + static string mutexOwnerId = + string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(result->mutexCommands, mutexOwnerId); + result->commands.push_back(command); + safeMutex.ReleaseLock(); + } + // Observers observers; + //for(Observers::iterator it = observers.begin(); it != observers.end(); ++it) { + // (*it)->saveGame(unitNode); + //} + + // vector unitParticleSystems; + // for(unsigned int i = 0; i < unitParticleSystems.size(); ++i) { + // UnitParticleSystem *ups= unitParticleSystems[i]; + // ups->saveGame(unitNode); + // } + if (unitNode->hasChild("unitParticleSystems") == true) { + XmlNode *unitParticleSystemsNode = + unitNode->getChild("unitParticleSystems"); + vector < XmlNode * >unitParticleSystemNodeList = + unitParticleSystemsNode->getChildList("UnitParticleSystem"); + for (unsigned int i = 0; i < unitParticleSystemNodeList.size(); ++i) { + XmlNode *node = unitParticleSystemNodeList[i]; + + UnitParticleSystem *ups = new UnitParticleSystem(); + ups->setParticleOwner(result); + ups->loadGame(node); + result->unitParticleSystems.push_back(ups); + + //Renderer::getInstance().manageParticleSystem(result->fire, rsGame); + Renderer:: + getInstance().addToDeferredParticleSystemList(make_pair + (ups, rsGame)); + } + } + + // vector queuedUnitParticleSystemTypes; + // for(unsigned int i = 0; i < queuedUnitParticleSystemTypes.size(); ++i) { + // UnitParticleSystemType *upst= queuedUnitParticleSystemTypes[i]; + // upst->saveGame(unitNode); + // } + + // UnitParticleSystems damageParticleSystems; + // for(unsigned int i = 0; i < damageParticleSystems.size(); ++i) { + // UnitParticleSystem *ups= damageParticleSystems[i]; + // ups->saveGame(unitNode); + // } + if (unitNode->hasChild("damageParticleSystems") == true) { + XmlNode *damageParticleSystemsNode = + unitNode->getChild("damageParticleSystems"); + vector < XmlNode * >unitParticleSystemNodeList = + damageParticleSystemsNode->getChildList("UnitParticleSystem"); + for (unsigned int i = 0; i < unitParticleSystemNodeList.size(); ++i) { + XmlNode *node = unitParticleSystemNodeList[i]; + + UnitParticleSystem *ups = new UnitParticleSystem(); + ups->setParticleOwner(result); + ups->loadGame(node); + result->damageParticleSystems.push_back(ups); + result->damageParticleSystemsInUse[i] = ups; + + //Renderer::getInstance().manageParticleSystem(result->fire, rsGame); + Renderer:: + getInstance().addToDeferredParticleSystemList(make_pair + (ups, rsGame)); + } + } + + // std::map damageParticleSystemsInUse; + // for(std::map::const_iterator iterMap = damageParticleSystemsInUse.begin(); + // iterMap != damageParticleSystemsInUse.end(); ++iterMap) { + // XmlNode *damageParticleSystemsInUseNode = unitNode->addChild("damageParticleSystemsInUse"); + // + // damageParticleSystemsInUseNode->addAttribute("key",intToStr(iterMap->first), mapTagReplacements); + // iterMap->second->saveGame(damageParticleSystemsInUseNode); + // } + // if(unitNode->hasChild("damageParticleSystemsInUse") == true) { + // XmlNode *damageParticleSystemsInUseNode = unitNode->getChild("damageParticleSystemsInUse"); + // vector damageParticleSystemsInUseNode2 = damageParticleSystemsInUseNode->getChildList("damageParticleSystemsInUse"); + // for(unsigned int i = 0; i < damageParticleSystemsInUseNode2.size(); ++i) { + // XmlNode *d2Node = damageParticleSystemsInUseNode2[i]; + // + // vector unitParticleSystemNodeList = damageParticleSystemsInUseNode->getChildList("UnitParticleSystem"); + // for(unsigned int i = 0; i < unitParticleSystemNodeList.size(); ++i) { + // XmlNode *node = unitParticleSystemNodeList[i]; + // + // UnitParticleSystem *ups = new UnitParticleSystem(); + // ups->loadGame(node); + // result->unitParticleSystems.push_back(ups); + // + // //Renderer::getInstance().manageParticleSystem(result->fire, rsGame); + // Renderer::getInstance().addToDeferredParticleSystemList(make_pair(ups, rsGame)); + // } + // + // } + + // vector fireParticleSystems; + // for(unsigned int i = 0; i < fireParticleSystems.size(); ++i) { + // ParticleSystem *ps= fireParticleSystems[i]; + // ps->saveGame(unitNode); + // } + if (unitNode->hasChild("fireParticleSystems") == true) { + XmlNode *fireParticleSystemsNode = + unitNode->getChild("fireParticleSystems"); + + int linkFireIndex = -1; + if (fireParticleSystemsNode->hasAttribute("fireParticleLink") == + true) { + linkFireIndex = + fireParticleSystemsNode-> + getAttribute("fireParticleLink")->getIntValue(); + } + + vector < XmlNode * >unitParticleSystemNodeList = + fireParticleSystemsNode->getChildList("FireParticleSystem"); + for (int i = 0; i < (int) unitParticleSystemNodeList.size(); ++i) { + XmlNode *node = unitParticleSystemNodeList[i]; + + if (result->fire == NULL || linkFireIndex != i) { + FireParticleSystem *ups = new FireParticleSystem(); + ups->setParticleOwner(result); + ups->loadGame(node); + //ups->setTexture(CoreData::getInstance().getFireTexture()); + result->fireParticleSystems.push_back(ups); + + //printf("Load fire particle i = %d linkFireIndex = %d result->fire = %p ups = %p\n",i,linkFireIndex,result->fire,ups); + + if (result->fire == NULL && linkFireIndex >= 0 + && linkFireIndex == i) { + result->fire = ups; + } + Renderer:: + getInstance().addToDeferredParticleSystemList(make_pair + (ups, rsGame)); + } + } + } + + // vector smokeParticleSystems; + // for(unsigned int i = 0; i < smokeParticleSystems.size(); ++i) { + // UnitParticleSystem *ups= smokeParticleSystems[i]; + // ups->saveGame(unitNode); + // } + if (unitNode->hasChild("smokeParticleSystems") == true) { + XmlNode *smokeParticleSystemsNode = + unitNode->getChild("smokeParticleSystems"); + vector < XmlNode * >unitParticleSystemNodeList = + smokeParticleSystemsNode->getChildList("UnitParticleSystem"); + for (unsigned int i = 0; i < unitParticleSystemNodeList.size(); ++i) { + XmlNode *node = unitParticleSystemNodeList[i]; + + // printf("Load Smoke particle i = %d\n",i); + UnitParticleSystem *ups = new UnitParticleSystem(); + ups->setParticleOwner(result); + ups->loadGame(node); + //ups->setTexture(CoreData::getInstance().getFireTexture()); + result->smokeParticleSystems.push_back(ups); + + Renderer:: + getInstance().addToDeferredParticleSystemList(make_pair + (ups, rsGame)); + + //printf("Loading smoke particles:\n[%s]\n",ups->toString().c_str()); + } + } + + // CardinalDir modelFacing; + // unitNode->addAttribute("modelFacing",intToStr(modelFacing), mapTagReplacements); + + // std::string lastSynchDataString; + // unitNode->addAttribute("lastSynchDataString",lastSynchDataString, mapTagReplacements); + // std::string lastFile; + // unitNode->addAttribute("lastFile",lastFile, mapTagReplacements); + // int lastLine; + // unitNode->addAttribute("lastLine",intToStr(lastLine), mapTagReplacements); + // std::string lastSource; + // unitNode->addAttribute("lastSource",lastSource, mapTagReplacements); + // int lastRenderFrame; + result->lastRenderFrame = + unitNode->getAttribute("lastRenderFrame")->getIntValue(); + // bool visible; + result->visible = + unitNode->getAttribute("visible")->getIntValue() != 0; + // int retryCurrCommandCount; + result->retryCurrCommandCount = + unitNode->getAttribute("retryCurrCommandCount")->getIntValue(); + // Vec3f screenPos; + result->screenPos = + Vec3f::strToVec3(unitNode->getAttribute("screenPos")->getValue()); + // string currentUnitTitle; + result->currentUnitTitle = + unitNode->getAttribute("currentUnitTitle")->getValue(); + // + // bool inBailOutAttempt; + result->inBailOutAttempt = + unitNode->getAttribute("inBailOutAttempt")->getIntValue() != 0; + // //std::vector > badHarvestPosList; + // std::map badHarvestPosList; + // for(std::map::const_iterator iterMap = badHarvestPosList.begin(); + // iterMap != badHarvestPosList.end(); ++iterMap) { + // XmlNode *badHarvestPosListNode = unitNode->addChild("badHarvestPosList"); + // + // badHarvestPosListNode->addAttribute("key",iterMap->first.getString(), mapTagReplacements); + // badHarvestPosListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + // } + + // //time_t lastBadHarvestListPurge; + // std::pair lastHarvestResourceTarget; + const XmlNode *lastHarvestResourceTargetNode = + unitNode->getChild("lastHarvestResourceTarget"); + // lastHarvestResourceTargetNode->addAttribute("key",lastHarvestResourceTarget.first.getString(), mapTagReplacements); + // lastHarvestResourceTargetNode->addAttribute("value",intToStr(lastHarvestResourceTarget.second), mapTagReplacements); + + result->lastHarvestResourceTarget = + make_pair(Vec2i::strToVec2 + (lastHarvestResourceTargetNode->getAttribute("key")-> + getValue()), + lastHarvestResourceTargetNode-> + getAttribute("value")->getIntValue()); + + // //std::pair > currentTargetPathTaken; + // static Game *game; + // + // bool ignoreCheckCommand; + result->ignoreCheckCommand = + unitNode->getAttribute("ignoreCheckCommand")->getIntValue() != 0; + // uint32 lastStuckFrame; + result->lastStuckFrame = + unitNode->getAttribute("lastStuckFrame")->getIntValue(); + // Vec2i lastStuckPos; + result->lastStuckPos = + Vec2i::strToVec2(unitNode-> + getAttribute("lastStuckPos")->getValue()); + // uint32 lastPathfindFailedFrame; + result->lastPathfindFailedFrame = + unitNode->getAttribute("lastPathfindFailedFrame")->getIntValue(); + // Vec2i lastPathfindFailedPos; + result->lastPathfindFailedPos = + Vec2i::strToVec2(unitNode-> + getAttribute("lastPathfindFailedPos")->getValue + ()); + // bool usePathfinderExtendedMaxNodes; + result->usePathfinderExtendedMaxNodes = + unitNode-> + getAttribute("usePathfinderExtendedMaxNodes")->getIntValue() != 0; + // int maxQueuedCommandDisplayCount; + result->maxQueuedCommandDisplayCount = + unitNode-> + getAttribute("maxQueuedCommandDisplayCount")->getIntValue(); + // UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect; + + // !!! TODO: Softcoder - in progress work to load attack boosts, not working properly yet + result->currentAttackBoostOriginatorEffect.loadGame(unitNode, result, + world); + + // std::vector currentAttackBoostEffects; + // for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) { + // UnitAttackBoostEffect *uabe= currentAttackBoostEffects[i]; + // uabe->saveGame(unitNode); + // } + + // !!! TODO: Softcoder - in progress work to load attack boosts, not working properly yet + if (unitNode->hasChild("UnitAttackBoostEffect") == true) { + vector < XmlNode * >unitParticleSystemNodeList = + unitNode->getChildList("UnitAttackBoostEffect"); + for (unsigned int i = 0; i < unitParticleSystemNodeList.size(); ++i) { + XmlNode *node = unitParticleSystemNodeList[i]; + + UnitAttackBoostEffect *attackBoostEffect = + new UnitAttackBoostEffect(); + attackBoostEffect->loadGame(node, result, world, false); + + result->currentAttackBoostEffects.push_back(attackBoostEffect); + } + } + //printf("Unit [%d - %s] has currentAttackBoostEffects count: %d\n",result->getId(),result->getType()->getName(false).c_str(),(int)result->currentAttackBoostEffects.size()); + + + // Mutex *mutexCommands; + // + // //static Mutex mutexDeletedUnits; + // //static std::map deletedUnits; + // + // bool changedActiveCommand; + result->changedActiveCommand = + unitNode->getAttribute("changedActiveCommand")->getIntValue() != 0; + // int lastAttackerUnitId; + result->lastAttackerUnitId = + unitNode->getAttribute("lastAttackerUnitId")->getIntValue(); + // int lastAttackedUnitId; + result->lastAttackedUnitId = + unitNode->getAttribute("lastAttackedUnitId")->getIntValue(); + // CauseOfDeathType causeOfDeath; + result->causeOfDeath = + static_cast + (unitNode->getAttribute("causeOfDeath")->getIntValue()); + + result->pathfindFailedConsecutiveFrameCount = + unitNode-> + getAttribute("pathfindFailedConsecutiveFrameCount")->getIntValue(); + + if (result->alive) { + world->getMapPtr()->putUnitCells(result, newUnitPos); + //result->born(); + } + + result->pos = newUnitPos; + result->lastPos = + Vec2i::strToVec2(unitNode->getAttribute("lastPos")->getValue()); + result->meetingPos = + Vec2i::strToVec2(unitNode->getAttribute("meetingPos")->getValue()); + + if (unitNode->hasAttribute("currentPathFinderDesiredFinalPos")) { + result->currentPathFinderDesiredFinalPos = + Vec2i::strToVec2(unitNode->getAttribute + ("currentPathFinderDesiredFinalPos")->getValue + ()); + } + + if (unitNode->hasAttribute("random")) { + result->random.setLastNumber(unitNode-> + getAttribute("random")->getIntValue + ()); + } + if (unitNode->hasAttribute("pathFindRefreshCellCount")) { + result->pathFindRefreshCellCount = + unitNode->getAttribute("pathFindRefreshCellCount")->getIntValue(); + } + + //result->exploreCells(); + //result->calculateFogOfWarRadius(); + + return result; + } + + Checksum Unit::getCRC() { + const bool consoleDebug = false; + + Checksum crcForUnit; + + crcForUnit.addInt(id); + crcForUnit.addInt(hp); + crcForUnit.addInt(ep); + crcForUnit.addInt(loadCount); + crcForUnit.addInt(deadCount); + + if (consoleDebug) + printf("#1 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + crcForUnit.addInt64(progress); + crcForUnit.addInt64(lastAnimProgress); + crcForUnit.addInt64(animProgress); + + if (consoleDebug) + printf("#2 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + //float highlight; + crcForUnit.addInt(progress2); + crcForUnit.addInt(kills); + crcForUnit.addInt(enemyKills); + crcForUnit.addInt(morphFieldsBlocked); + + if (consoleDebug) + printf("#3 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + //UnitReference targetRef; + + crcForUnit.addInt(currField); + crcForUnit.addInt(targetField); + + if (consoleDebug) + printf("#4 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + //const Level *level; + if (level != NULL) { + crcForUnit.addString(level->getName(false)); + } + + if (consoleDebug) + printf("#5 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + crcForUnit.addInt(pos.x); + crcForUnit.addInt(pos.y); + crcForUnit.addInt(lastPos.x); + crcForUnit.addInt(lastPos.y); + crcForUnit.addInt(targetPos.x); + crcForUnit.addInt(targetPos.y); + + if (consoleDebug) + printf("#6 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + //Vec3f targetVec; + + crcForUnit.addInt(meetingPos.x); + crcForUnit.addInt(meetingPos.y); + + if (consoleDebug) + printf("#7 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + //float lastRotation; + //float targetRotation; + //float rotation; + //float targetRotationZ; + //float targetRotationX; + //float rotationZ; + //float rotationX; + + //const UnitType *preMorph_type; + if (preMorph_type != NULL) { + crcForUnit.addString(preMorph_type->getName(false)); + } + + if (consoleDebug) + printf("#8 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + //const UnitType *type; + if (type != NULL) { + crcForUnit.addString(type->getName(false)); + } + + //const ResourceType *loadType; + if (loadType != NULL) { + crcForUnit.addString(loadType->getName(false)); + } + + //const SkillType *currSkill; + if (currSkill != NULL) { + crcForUnit.addString(currSkill->getName()); + } + + //printf("#9 Unit: %d CRC: %u lastModelIndexForCurrSkillType: %d\n",id,crcForUnit.getSum(),lastModelIndexForCurrSkillType); + //printf("#9a Unit: %d CRC: %u\n",id,crcForUnit.getSum()); + //crcForUnit.addInt(lastModelIndexForCurrSkillType); + + if (consoleDebug) + printf("#9 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + //crcForUnit.addInt(animationRandomCycleCount); + //printf("#9b Unit: %d CRC: %u\n",id,crcForUnit.getSum()); + + crcForUnit.addInt(toBeUndertaken); + + if (consoleDebug) + printf("#9c Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + crcForUnit.addInt(alive); + //bool showUnitParticles; + + if (consoleDebug) + printf("#10 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + //Faction *faction; + //ParticleSystem *fire; + if (fire != NULL) { + crcForUnit.addInt(fire->getActive()); + } + + //TotalUpgrade totalUpgrade; + uint32 crc = totalUpgrade.getCRC().getSum(); + crcForUnit.addBytes(&crc, sizeof(uint32)); + + //Map *map; + //UnitPathInterface *unitPath; + if (unitPath != NULL) { + uint32 crc = unitPath->getCRC().getSum(); + crcForUnit.addBytes(&crc, sizeof(uint32)); + } + //WaypointPath waypointPath; + + if (consoleDebug) + printf("#11 Unit: %d CRC: %u commands.size(): " MG_SIZE_T_SPECIFIER + "\n", id, crcForUnit.getSum(), commands.size()); + + //Commands commands; + if (commands.empty() == false) { + crcForUnit.addInt((int) commands.size()); + for (Commands::const_iterator it = commands.begin(); + it != commands.end(); ++it) { + uint32 crc = (*it)->getCRC().getSum(); + crcForUnit.addBytes(&crc, sizeof(uint32)); + } + } + + //printf("#11 Unit: %d CRC: %u observers.size(): %ld\n",id,crcForUnit.getSum(),observers.size()); + + //Observers observers; + //crcForUnit.addInt64((int64)observers.size()); + + if (consoleDebug) + printf("#11 Unit: %d CRC: %u damageParticleSystems.size(): " + MG_SIZE_T_SPECIFIER "\n", id, crcForUnit.getSum(), + damageParticleSystems.size()); + + //vector unitParticleSystems; + //vector queuedUnitParticleSystemTypes; + + //UnitParticleSystems damageParticleSystems; + crcForUnit.addInt((int) damageParticleSystems.size()); + + if (consoleDebug) + printf("#12 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + //std::map damageParticleSystemsInUse; + + //vector fireParticleSystems; + //vector smokeParticleSystems; + + //CardinalDir modelFacing; + crcForUnit.addInt(modelFacing); + + //std::string lastSynchDataString; + //std::string lastFile; + //int lastLine; + //std::string lastSource; + //int lastRenderFrame; + //bool visible; + + //int retryCurrCommandCount; + + //Vec3f screenPos; + //string currentUnitTitle; + + if (consoleDebug) + printf("#13 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + crcForUnit.addInt(inBailOutAttempt); + + crcForUnit.addInt((int) badHarvestPosList.size()); + //crcForUnit.addInt(lastHarvestResourceTarget.first()); + + if (consoleDebug) + printf("#14 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + //static Game *game; + //bool ignoreCheckCommand; + + //uint32 lastStuckFrame; + crcForUnit.addUInt(lastStuckFrame); + //Vec2i lastStuckPos; + crcForUnit.addInt(lastStuckPos.x); + crcForUnit.addInt(lastStuckPos.y); + + //uint32 lastPathfindFailedFrame; + //Vec2i lastPathfindFailedPos; + //bool usePathfinderExtendedMaxNodes; + //int maxQueuedCommandDisplayCount; + + //UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect; + crcForUnit. + addInt((int) + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + size()); + + if (consoleDebug) + printf("#15 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + //std::vector currentAttackBoostEffects; + + //Mutex *mutexCommands; + + //bool changedActiveCommand; + + //int lastAttackerUnitId; + //int lastAttackedUnitId; + //CauseOfDeathType causeOfDeath; + + //uint32 pathfindFailedConsecutiveFrameCount; + crcForUnit.addString(this-> + currentPathFinderDesiredFinalPos.getString()); + + crcForUnit.addInt(random.getLastNumber()); + if (this->random.getLastCaller() != "") { + crcForUnit.addString(this->random.getLastCaller()); + } + + if (consoleDebug) + printf("#16 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + //int pathFindRefreshCellCount; + + //FowAlphaCellsLookupItem cachedFow; + //Vec2i cachedFowPos; + + crcForUnit.addInt(lastHarvestedResourcePos.x); + crcForUnit.addInt(lastHarvestedResourcePos.y); + + if (consoleDebug) + printf("#17 Unit: %d CRC: %u\n", id, crcForUnit.getSum()); + + if (this->getParticleInfo() != "") { + crcForUnit.addString(this->getParticleInfo()); + } + + crcForUnit.addInt((int) attackParticleSystems.size()); + if (isNetworkCRCEnabled() == true) { + for (unsigned int index = 0; index < attackParticleSystems.size(); + ++index) { + ParticleSystem *ps = attackParticleSystems[index]; + if (ps != NULL && + Renderer::getInstance().validateParticleSystemStillExists(ps, + rsGame) + == true) { + uint32 crc = ps->getCRC().getSum(); + crcForUnit.addBytes(&crc, sizeof(uint32)); + } + } + } + + if (this->networkCRCParticleLogInfo != "") { + crcForUnit.addString(this->networkCRCParticleLogInfo); + } + + return crcForUnit; + } + + } + } //end namespace diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index 0e5840cad..da2846fbd 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -28,1237 +28,1088 @@ //#define LEAK_CHECK_UNITS -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - using Shared::Graphics::ParticleSystem; - using Shared::Graphics::UnitParticleSystem; - using Shared::Graphics::Vec4f; - using Shared::Graphics::Vec2f; - using Shared::Graphics::Vec3f; - using Shared::Graphics::Vec2i; - using Shared::Graphics::Model; - using Shared::PlatformCommon::Chrono; - using Shared::PlatformCommon::ValueCheckerVault; + using Shared::Graphics::ParticleSystem; + using Shared::Graphics::UnitParticleSystem; + using Shared::Graphics::Vec4f; + using Shared::Graphics::Vec2f; + using Shared::Graphics::Vec3f; + using Shared::Graphics::Vec2i; + using Shared::Graphics::Model; + using Shared::PlatformCommon::Chrono; + using Shared::PlatformCommon::ValueCheckerVault; - class Map; -//class Faction; - class Unit; - class Command; - class SkillType; - class ResourceType; - class CommandType; - class SkillType; - class UnitType; - class TotalUpgrade; - class UpgradeType; - class Level; - class MorphCommandType; - class Game; - class Unit; - class GameSettings; - class World; + class Map; + //class Faction; + class Unit; + class Command; + class SkillType; + class ResourceType; + class CommandType; + class SkillType; + class UnitType; + class TotalUpgrade; + class UpgradeType; + class Level; + class MorphCommandType; + class Game; + class Unit; + class GameSettings; + class World; - enum CommandResult - { - crSuccess, - crFailRes, - crFailReqs, - crFailUnitCount, - crFailUndefined, - crSomeFailed - }; + enum CommandResult { + crSuccess, + crFailRes, + crFailReqs, + crFailUnitCount, + crFailUndefined, + crSomeFailed + }; - enum InterestingUnitType - { - iutIdleHarvester, - iutBuiltBuilding, - iutProducer, - iutDamaged, - iutStore - }; + enum InterestingUnitType { + iutIdleHarvester, + iutBuiltBuilding, + iutProducer, + iutDamaged, + iutStore + }; - enum CauseOfDeathType - { - ucodNone, - ucodAttacked, - ucodAttackBoost, - ucodStarvedResource, - ucodStarvedRegeneration - }; + enum CauseOfDeathType { + ucodNone, + ucodAttacked, + ucodAttackBoost, + ucodStarvedResource, + ucodStarvedRegeneration + }; - class UnitBuildInfo - { - public: - UnitBuildInfo () - { - unit = NULL; - //pos; - buildUnit = NULL; - } - const Unit *unit; - CardinalDir facing; - Vec2i pos; - const UnitType *buildUnit; - }; + class UnitBuildInfo { + public: + UnitBuildInfo() { + unit = NULL; + //pos; + buildUnit = NULL; + } + const Unit *unit; + CardinalDir facing; + Vec2i pos; + const UnitType *buildUnit; + }; -// ===================================================== -// class UnitObserver -// ===================================================== + // ===================================================== + // class UnitObserver + // ===================================================== - class UnitObserver - { - public: - enum Event - { - eKill - }; + class UnitObserver { + public: + enum Event { + eKill + }; - public: - virtual ~ UnitObserver () - { - } - virtual void unitEvent (Event event, const Unit * unit) = 0; + public: + virtual ~UnitObserver() { + } + virtual void unitEvent(Event event, const Unit * unit) = 0; - virtual void saveGame (XmlNode * rootNode) const = 0; - }; + virtual void saveGame(XmlNode * rootNode) const = 0; + }; -// ===================================================== -// class UnitReference -// ===================================================== + // ===================================================== + // class UnitReference + // ===================================================== - class UnitReference - { - private: - int id; - Faction *faction; + class UnitReference { + private: + int id; + Faction *faction; - public: - UnitReference (); + public: + UnitReference(); - UnitReference & operator= (const Unit * unit); - Unit *getUnit () const; + UnitReference & operator= (const Unit * unit); + Unit *getUnit() const; - int getUnitId () const - { - return id; - } - Faction *getUnitFaction () const - { - return faction; - } + int getUnitId() const { + return id; + } + Faction *getUnitFaction() const { + return faction; + } - void saveGame (XmlNode * rootNode); - void loadGame (const XmlNode * rootNode, World * world); - }; + void saveGame(XmlNode * rootNode); + void loadGame(const XmlNode * rootNode, World * world); + }; - class UnitPathInterface - { + class UnitPathInterface { - public: - UnitPathInterface () - { - } - virtual ~ UnitPathInterface () - { - } + public: + UnitPathInterface() { + } + virtual ~UnitPathInterface() { + } - virtual bool isBlocked () const = 0; - virtual bool isEmpty () const = 0; - virtual bool isStuck () const = 0; + virtual bool isBlocked() const = 0; + virtual bool isEmpty() const = 0; + virtual bool isStuck() const = 0; - virtual void clear () = 0; - virtual void clearBlockCount () = 0; - virtual void incBlockCount () = 0; - virtual void add (const Vec2i & path) = 0; - //virtual Vec2i pop() = 0; - virtual int getBlockCount () const = 0; - virtual int getQueueCount () const = 0; + virtual void clear() = 0; + virtual void clearBlockCount() = 0; + virtual void incBlockCount() = 0; + virtual void add(const Vec2i & path) = 0; + //virtual Vec2i pop() = 0; + virtual int getBlockCount() const = 0; + virtual int getQueueCount() const = 0; - virtual vector < Vec2i > getQueue () const = 0; + virtual vector < Vec2i > getQueue() const = 0; - virtual std::string toString () const = 0; + virtual std::string toString() const = 0; - virtual void setMap (Map * value) = 0; - virtual Map *getMap () = 0; + virtual void setMap(Map * value) = 0; + virtual Map *getMap() = 0; - virtual void saveGame (XmlNode * rootNode) = 0; - virtual void loadGame (const XmlNode * rootNode) = 0; + virtual void saveGame(XmlNode * rootNode) = 0; + virtual void loadGame(const XmlNode * rootNode) = 0; - virtual void clearCaches () = 0; + virtual void clearCaches() = 0; - virtual Checksum getCRC () = 0; - }; + virtual Checksum getCRC() = 0; + }; - class UnitPathBasic:public UnitPathInterface - { - private: - static const int maxBlockCount; - Map *map; + class UnitPathBasic :public UnitPathInterface { + private: + static const int maxBlockCount; + Map *map; # ifdef LEAK_CHECK_UNITS - static std::map < UnitPathBasic *, bool > mapMemoryList; + static std::map < UnitPathBasic *, bool > mapMemoryList; # endif - private: - int blockCount; - vector < Vec2i > pathQueue; + private: + int blockCount; + vector < Vec2i > pathQueue; - public: - UnitPathBasic (); - virtual ~ UnitPathBasic (); + public: + UnitPathBasic(); + virtual ~UnitPathBasic(); # ifdef LEAK_CHECK_UNITS - static void dumpMemoryList (); + static void dumpMemoryList(); # endif - virtual bool isBlocked () const; - virtual bool isEmpty () const; - virtual bool isStuck () const; + virtual bool isBlocked() const; + virtual bool isEmpty() const; + virtual bool isStuck() const; - virtual void clear (); - virtual void clearBlockCount () - { - blockCount = 0; - } - virtual void incBlockCount (); - virtual void add (const Vec2i & path); - Vec2i pop (bool removeFrontPos = true); - virtual int getBlockCount () const - { - return blockCount; - } - virtual int getQueueCount () const - { - return (int) pathQueue.size (); - } + virtual void clear(); + virtual void clearBlockCount() { + blockCount = 0; + } + virtual void incBlockCount(); + virtual void add(const Vec2i & path); + Vec2i pop(bool removeFrontPos = true); + virtual int getBlockCount() const { + return blockCount; + } + virtual int getQueueCount() const { + return (int) pathQueue.size(); + } - virtual vector < Vec2i > getQueue () const - { - return pathQueue; - } + virtual vector < Vec2i > getQueue() const { + return pathQueue; + } - virtual void setMap (Map * value) - { - map = value; - } - virtual Map *getMap () - { - return map; - } + virtual void setMap(Map * value) { + map = value; + } + virtual Map *getMap() { + return map; + } - virtual std::string toString () const; + virtual std::string toString() const; - virtual void saveGame (XmlNode * rootNode); - virtual void loadGame (const XmlNode * rootNode); - virtual void clearCaches (); + virtual void saveGame(XmlNode * rootNode); + virtual void loadGame(const XmlNode * rootNode); + virtual void clearCaches(); - virtual Checksum getCRC (); - }; + virtual Checksum getCRC(); + }; -// ===================================================== -// class UnitPath -// ===================================================== -/** Holds the next cells of a Unit movement - * @extends std::list - */ - class UnitPath:public list < Vec2i >, public UnitPathInterface - { - private: - static const int maxBlockCount = 10; /**< number of command updates to wait on a blocked path */ + // ===================================================== + // class UnitPath + // ===================================================== + /** Holds the next cells of a Unit movement + * @extends std::list + */ + class UnitPath :public list < Vec2i >, public UnitPathInterface { + private: + static const int maxBlockCount = 10; /**< number of command updates to wait on a blocked path */ - private: - int blockCount; /**< number of command updates this path has been blocked */ - Map *map; + private: + int blockCount; /**< number of command updates this path has been blocked */ + Map *map; - public: - UnitPath ():UnitPathInterface (), blockCount (0), map (NULL) - { - } /**< Construct path object */ + public: + UnitPath() :UnitPathInterface(), blockCount(0), map(NULL) { + } /**< Construct path object */ - virtual bool isBlocked () const - { - return blockCount >= maxBlockCount; - } /**< is this path blocked */ - virtual bool isEmpty () const - { - return list < Vec2i >::empty (); - } /**< is path empty */ - virtual bool isStuck () const - { - return false; - } + virtual bool isBlocked() const { + return blockCount >= maxBlockCount; + } /**< is this path blocked */ + virtual bool isEmpty() const { + return list < Vec2i >::empty(); + } /**< is path empty */ + virtual bool isStuck() const { + return false; + } - int size () const - { - return (int) list < Vec2i >::size (); - } /**< size of path */ - virtual void clear () - { - list < Vec2i >::clear (); - blockCount = 0; - } /**< clear the path */ - virtual void clearBlockCount () - { - blockCount = 0; - } - virtual void incBlockCount () - { - ++blockCount; - } /**< increment block counter */ - virtual void push (Vec2i & pos) - { - push_front (pos); - } /**< push onto front of path */ - bool empty () const - { - return list < Vec2i >::empty (); - } /**< is path empty */ - virtual void add (const Vec2i & pos) - { - push_front (pos); - } /**< push onto front of path */ + int size() const { + return (int) list < Vec2i >::size(); + } /**< size of path */ + virtual void clear() { + list < Vec2i >::clear(); + blockCount = 0; + } /**< clear the path */ + virtual void clearBlockCount() { + blockCount = 0; + } + virtual void incBlockCount() { + ++blockCount; + } /**< increment block counter */ + virtual void push(Vec2i & pos) { + push_front(pos); + } /**< push onto front of path */ + bool empty() const { + return list < Vec2i >::empty(); + } /**< is path empty */ + virtual void add(const Vec2i & pos) { + push_front(pos); + } /**< push onto front of path */ # if 0 - // old style, to work with original PathFinder - Vec2i peek () - { - return back (); - } /**< peek at the next position */ - void pop () - { - this->pop_back (); - } /**< pop the next position off the path */ + // old style, to work with original PathFinder + Vec2i peek() { + return back(); + } /**< peek at the next position */ + void pop() { + this->pop_back(); + } /**< pop the next position off the path */ # else - // new style - Vec2i peek () - { - return front (); - } /**< peek at the next position */ - //virtual Vec2i pop() { Vec2i p= front(); erase(begin()); return p; } /**< pop the next position off the path */ - void pop () - { - erase (begin ()); - } /**< pop the next position off the path */ + // new style + Vec2i peek() { + return front(); + } /**< peek at the next position */ + //virtual Vec2i pop() { Vec2i p= front(); erase(begin()); return p; } /**< pop the next position off the path */ + void pop() { + erase(begin()); + } /**< pop the next position off the path */ # endif - virtual int getBlockCount () const - { - return blockCount; - } - virtual int getQueueCount () const - { - return this->size (); - } + virtual int getBlockCount() const { + return blockCount; + } + virtual int getQueueCount() const { + return this->size(); + } - virtual vector < Vec2i > getQueue () const - { - vector < Vec2i > result; - for (list < Vec2i >::const_iterator iter = this->begin (); - iter != this->end (); ++iter) - { - result.push_back (*iter); - } - return result; - } + virtual vector < Vec2i > getQueue() const { + vector < Vec2i > result; + for (list < Vec2i >::const_iterator iter = this->begin(); + iter != this->end(); ++iter) { + result.push_back(*iter); + } + return result; + } - virtual void setMap (Map * value) - { - map = value; - } - virtual Map *getMap () - { - return map; - } + virtual void setMap(Map * value) { + map = value; + } + virtual Map *getMap() { + return map; + } - virtual std::string toString () const; + virtual std::string toString() const; - virtual void saveGame (XmlNode * rootNode) - { - }; - virtual void loadGame (const XmlNode * rootNode) - { - }; - virtual void clearCaches () - { - }; + virtual void saveGame(XmlNode * rootNode) { + }; + virtual void loadGame(const XmlNode * rootNode) { + }; + virtual void clearCaches() { + }; - virtual Checksum getCRC () - { - return Checksum (); - }; - }; + virtual Checksum getCRC() { + return Checksum(); + }; + }; - class WaypointPath:public list < Vec2i > - { - public: - WaypointPath () - { - } - void push (const Vec2i & pos) - { - push_front (pos); - } - Vec2i peek () const - { - return front (); - } - void pop () - { - erase (begin ()); - } - //void condense(); - }; + class WaypointPath :public list < Vec2i > { + public: + WaypointPath() { + } + void push(const Vec2i & pos) { + push_front(pos); + } + Vec2i peek() const { + return front(); + } + void pop() { + erase(begin()); + } + //void condense(); + }; -// =============================== -// class Unit -// -/// A game unit or building -// =============================== + // =============================== + // class Unit + // + /// A game unit or building + // =============================== - class UnitAttackBoostEffect - { - private: - int unitId; - const Unit *unitPtr; + class UnitAttackBoostEffect { + private: + int unitId; + const Unit *unitPtr; - const Unit *source; + const Unit *source; - void applyLoadedAttackBoostParticles (UnitParticleSystemType * upstPtr, - const XmlNode * node, - Unit * unit); - public: + void applyLoadedAttackBoostParticles(UnitParticleSystemType * upstPtr, + const XmlNode * node, + Unit * unit); + public: - UnitAttackBoostEffect (); - virtual ~ UnitAttackBoostEffect (); + UnitAttackBoostEffect(); + virtual ~UnitAttackBoostEffect(); - const AttackBoost *boost; - //const Unit *source; - const Unit *getSource (); - void setSource (const Unit * unit); - UnitParticleSystem *ups; - UnitParticleSystemType *upst; + const AttackBoost *boost; + //const Unit *source; + const Unit *getSource(); + void setSource(const Unit * unit); + UnitParticleSystem *ups; + UnitParticleSystemType *upst; - virtual void saveGame (XmlNode * rootNode); - virtual void loadGame (const XmlNode * rootNode, Unit * unit, - World * world, bool applyToOriginator); - }; + virtual void saveGame(XmlNode * rootNode); + virtual void loadGame(const XmlNode * rootNode, Unit * unit, + World * world, bool applyToOriginator); + }; - class UnitAttackBoostEffectOriginator - { - public: + class UnitAttackBoostEffectOriginator { + public: - UnitAttackBoostEffectOriginator (); - virtual ~ UnitAttackBoostEffectOriginator (); + UnitAttackBoostEffectOriginator(); + virtual ~UnitAttackBoostEffectOriginator(); - const SkillType *skillType; - std::vector < int >currentAttackBoostUnits; - UnitAttackBoostEffect *currentAppliedEffect; + const SkillType *skillType; + std::vector < int >currentAttackBoostUnits; + UnitAttackBoostEffect *currentAppliedEffect; - virtual void saveGame (XmlNode * rootNode); - virtual void loadGame (const XmlNode * rootNode, Unit * unit, - World * world); - }; + virtual void saveGame(XmlNode * rootNode); + virtual void loadGame(const XmlNode * rootNode, Unit * unit, + World * world); + }; - class Unit:public BaseColorPickEntity, ValueCheckerVault, - public ParticleOwner - { - private: - typedef list < Command * >Commands; - typedef list < UnitObserver * >Observers; - typedef vector < UnitParticleSystem * >UnitParticleSystems; + class Unit :public BaseColorPickEntity, ValueCheckerVault, + public ParticleOwner { + private: + typedef list < Command * >Commands; + typedef list < UnitObserver * >Observers; + typedef vector < UnitParticleSystem * >UnitParticleSystems; # ifdef LEAK_CHECK_UNITS - static std::map < Unit *, bool > mapMemoryList; + static std::map < Unit *, bool > mapMemoryList; # endif - static const float ANIMATION_SPEED_MULTIPLIER; - static const int64 PROGRESS_SPEED_MULTIPLIER; + static const float ANIMATION_SPEED_MULTIPLIER; + static const int64 PROGRESS_SPEED_MULTIPLIER; - public: - static const int speedDivider; - static const int maxDeadCount; - static const int invalidId; + public: + static const int speedDivider; + static const int maxDeadCount; + static const int invalidId; # ifdef LEAK_CHECK_UNITS - static std::map < UnitPathInterface *, int >mapMemoryList2; - static void dumpMemoryList (); + static std::map < UnitPathInterface *, int >mapMemoryList2; + static void dumpMemoryList(); # endif - private: - const int32 id; - int32 hp; - int32 ep; - int32 loadCount; - int32 deadCount; - //float progress; //between 0 and 1 - int64 progress; //between 0 and 1 - int64 lastAnimProgress; //between 0 and 1 - int64 animProgress; //between 0 and 1 - float highlight; - // Progress2 keeps track of update/ upgrade progress of a unit. - int32 progress2; - int32 kills; - int32 enemyKills; - bool morphFieldsBlocked; - int oldTotalSight; - - UnitReference targetRef; - - Field currField; - Field targetField; - const Level *level; - - Vec2i pos; - Vec2i lastPos; - Vec2i targetPos; //absolute target pos - Vec3f targetVec; - Vec2i meetingPos; - - float lastRotation; //in degrees - float targetRotation; - float rotation; - float targetRotationZ; - float targetRotationX; - float rotationZ; - float rotationX; - - const UnitType *preMorph_type; - const UnitType *type; - const ResourceType *loadType; - const SkillType *currSkill; - int32 lastModelIndexForCurrSkillType; - int32 animationRandomCycleCount; - - bool toBeUndertaken; - bool alive; - bool showUnitParticles; - - Faction *faction; - ParticleSystem *fire; - TotalUpgrade totalUpgrade; - Map *map; - - UnitPathInterface *unitPath; - WaypointPath waypointPath; - - Commands commands; - Observers observers; - vector < UnitParticleSystem * >unitParticleSystems; - vector < UnitParticleSystemType * >queuedUnitParticleSystemTypes; - - UnitParticleSystems damageParticleSystems; - std::map < int, UnitParticleSystem * >damageParticleSystemsInUse; - - vector < ParticleSystem * >fireParticleSystems; - vector < UnitParticleSystem * >smokeParticleSystems; - vector < ParticleSystem * >attackParticleSystems; - - CardinalDir modelFacing; - - std::string lastSynchDataString; - std::string lastFile; - int32 lastLine; - std::string lastSource; - int32 lastRenderFrame; - bool visible; - - int retryCurrCommandCount; - - Vec3f screenPos; - string currentUnitTitle; - - bool inBailOutAttempt; - // This buffer stores a list of bad harvest cells, along with the start - // time of when it was detected. Typically this may be due to a unit - // constantly getting blocked from getting to the resource so this - // list may be used to tell areas of the game to ignore those cells for a - // period of time - //std::vector > badHarvestPosList; - std::map < Vec2i, int >badHarvestPosList; - //time_t lastBadHarvestListPurge; - std::pair < Vec2i, int >lastHarvestResourceTarget; - - //std::pair > currentTargetPathTaken; - - static Game *game; - - bool ignoreCheckCommand; - - uint32 lastStuckFrame; - Vec2i lastStuckPos; - - uint32 lastPathfindFailedFrame; - Vec2i lastPathfindFailedPos; - bool usePathfinderExtendedMaxNodes; - int32 maxQueuedCommandDisplayCount; - - UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect; - - std::vector < UnitAttackBoostEffect * >currentAttackBoostEffects; - - Mutex *mutexCommands; - - //static Mutex mutexDeletedUnits; - //static std::map deletedUnits; - - bool changedActiveCommand; - uint32 lastChangedActiveCommandFrame; - uint32 changedActiveCommandFrame; - - int32 lastAttackerUnitId; - int32 lastAttackedUnitId; - CauseOfDeathType causeOfDeath; - - uint32 pathfindFailedConsecutiveFrameCount; - Vec2i currentPathFinderDesiredFinalPos; - - RandomGen random; - int32 pathFindRefreshCellCount; - - FowAlphaCellsLookupItem cachedFow; - Vec2i cachedFowPos; - - ExploredCellsLookupItem cacheExploredCells; - std::pair < Vec2i, int >cacheExploredCellsKey; - - Vec2i lastHarvestedResourcePos; - - string networkCRCLogInfo; - string networkCRCParticleLogInfo; - vector < string > networkCRCDecHpList; - vector < string > networkCRCParticleInfoList; - - public: - Unit (int id, UnitPathInterface * path, const Vec2i & pos, - const UnitType * type, Faction * faction, Map * map, - CardinalDir placeFacing); - virtual ~ Unit (); - - //static bool isUnitDeleted(void *unit); - - static void setGame (Game * value) - { - game = value; - } - - inline int getPathFindRefreshCellCount () const - { - return pathFindRefreshCellCount; - } - - void setCurrentPathFinderDesiredFinalPos (const Vec2i & finalPos) - { - currentPathFinderDesiredFinalPos = finalPos; - } - Vec2i getCurrentPathFinderDesiredFinalPos () const - { - return currentPathFinderDesiredFinalPos; - } - - const UnitAttackBoostEffectOriginator & - getAttackBoostOriginatorEffect () const - { - return currentAttackBoostOriginatorEffect; - } - bool unitHasAttackBoost (const AttackBoost * boost, - const Unit * source); - - inline uint32 getPathfindFailedConsecutiveFrameCount () const - { - return pathfindFailedConsecutiveFrameCount; - } - inline void incrementPathfindFailedConsecutiveFrameCount () - { - pathfindFailedConsecutiveFrameCount++; - } - inline void resetPathfindFailedConsecutiveFrameCount () - { - pathfindFailedConsecutiveFrameCount = 0; - } - - const FowAlphaCellsLookupItem & getCachedFow () const - { - return cachedFow; - } - FowAlphaCellsLookupItem getFogOfWarRadius (bool useCache) const; - void calculateFogOfWarRadius (bool forceRefresh = false); - - //queries - Command *getCurrrentCommandThreadSafe (); - void setIgnoreCheckCommand (bool value) - { - ignoreCheckCommand = value; - } - inline bool getIgnoreCheckCommand () const - { - return ignoreCheckCommand; - } - inline int getId () const - { - return id; - } - inline Field getCurrField () const - { - return currField; - } - inline int getLoadCount () const - { - return loadCount; - } - - //inline int getLastAnimProgress() const {return lastAnimProgress;} - //inline int getAnimProgress() const {return animProgress;} - inline float getLastAnimProgressAsFloat () const - { - return static_cast < - float >(lastAnimProgress) / ANIMATION_SPEED_MULTIPLIER; - } - inline float getAnimProgressAsFloat () const - { - return static_cast < - float >(animProgress) / ANIMATION_SPEED_MULTIPLIER; - } - - inline float getHightlight () const - { - return highlight; - } - inline int getProgress2 () const - { - return progress2; - } - inline int getFactionIndex () const - { - return faction->getIndex (); - } - inline int getTeam () const - { - return faction->getTeam (); - } - inline int getHp () const - { - return hp; - } - inline int getEp () const - { - return ep; - } - int getProductionPercent () const; - float getProgressRatio () const; - float getHpRatio () const; - float getEpRatio () const; - inline bool getToBeUndertaken () const - { - return toBeUndertaken; - } - inline Vec2i getTargetPos () const - { - return targetPos; - } - inline Vec3f getTargetVec () const - { - return targetVec; - } - inline Field getTargetField () const - { - return targetField; - } - inline Vec2i getMeetingPos () const - { - return meetingPos; - } - inline Faction *getFaction () const - { - return faction; - } - inline const ResourceType *getLoadType () const - { - return loadType; - } - - inline const UnitType *getType () const - { - return type; - } - void setType (const UnitType * newType); - inline const UnitType *getPreMorphType () const - { - return preMorph_type; - } - - inline const SkillType *getCurrSkill () const - { - return currSkill; - } - inline const TotalUpgrade *getTotalUpgrade () const - { - return &totalUpgrade; - } - inline float getRotation () const - { - return rotation; - } - float getRotationX () const; - float getRotationZ () const; - ParticleSystem *getFire () const; - inline int getKills () const - { - return kills; - } - inline int getEnemyKills () const - { - return enemyKills; - } - inline const Level *getLevel () const - { - return level; - } - const Level *getNextLevel () const; - string getFullName (bool translatedValue) const; - inline const UnitPathInterface *getPath () const - { - return unitPath; - } - inline UnitPathInterface *getPath () - { - return unitPath; - } - inline WaypointPath *getWaypointPath () - { - return &waypointPath; - } - - inline int getLastAttackerUnitId () const - { - return lastAttackerUnitId; - } - inline void setLastAttackerUnitId (int unitId) - { - lastAttackerUnitId = unitId; - } - - inline int getLastAttackedUnitId () const - { - return lastAttackedUnitId; - } - inline void setLastAttackedUnitId (int unitId) - { - lastAttackedUnitId = unitId; - } - - inline CauseOfDeathType getCauseOfDeath () const - { - return causeOfDeath; - } - inline void setCauseOfDeath (CauseOfDeathType cause) - { - causeOfDeath = cause; - } - - //pos - inline Vec2i getPosNotThreadSafe () const - { - return pos; - } - Vec2i getPos (); - Vec2i getPosWithCellMapSet () const; - inline Vec2i getLastPos () const - { - return lastPos; - } - Vec2i getCenteredPos () const; - Vec2f getFloatCenteredPos () const; - Vec2i getCellPos () const; - - //is - inline bool isHighlighted () const - { - return highlight > 0.f; - } - inline bool isDead () const - { - return !alive; - } - inline bool isAlive () const - { - return alive; - } - bool isOperative () const; - bool isBeingBuilt () const; - bool isBuilt () const; - bool isBuildCommandPending () const; - UnitBuildInfo getBuildCommandPendingInfo () const; - - bool isAnimProgressBound () const; - bool isPutrefacting () const - { - return deadCount != 0; - } - bool isAlly (const Unit * unit) const; - bool isDamaged () const; - bool isInteresting (InterestingUnitType iut) const; - - //set - //void setCurrField(Field currField); - void setCurrSkill (const SkillType * currSkill); - void setCurrSkill (SkillClass sc); - - void setMorphFieldsBlocked (bool value) - { - this->morphFieldsBlocked = value; - } - bool getMorphFieldsBlocked () const - { - return morphFieldsBlocked; - } - - inline void setLastHarvestedResourcePos (Vec2i pos) - { - this->lastHarvestedResourcePos = pos; - } - inline Vec2i getLastHarvestedResourcePos () const - { - return this->lastHarvestedResourcePos; - } - - inline void setLoadCount (int loadCount) - { - this->loadCount = loadCount; - } - inline void setLoadType (const ResourceType * loadType) - { - this->loadType = loadType; - } - // resetProgress2 resets produce and upgrade progress. - inline void resetProgress2 () - { - this->progress2 = 0; - } - void setPos (const Vec2i & pos, bool clearPathFinder = - false, bool threaded = false); - void refreshPos (bool forceRefresh = false); - void setTargetPos (const Vec2i & targetPos, bool threaded = false); - void setTarget (const Unit * unit); - //void setTargetVec(const Vec3f &targetVec); - void setMeetingPos (const Vec2i & meetingPos); - void setVisible (const bool visible); - inline bool getVisible () const - { - return visible; - } - - //render related - //const Model *getCurrentModel(); - Model *getCurrentModelPtr (); - Vec3f getCurrMidHeightVector () const; - Vec3f getCurrVectorForParticlesystems () const; - Vec3f getCurrVectorAsTarget () const; - Vec3f getCurrBurnVector () const; - Vec3f getCurrVectorFlat () const; - Vec3f getVectorFlat (const Vec2i & lastPosValue, - const Vec2i & curPosValue) const; - - //command related - bool anyCommand (bool validateCommandtype = false) const; - inline Command *getCurrCommand () const - { - if (commands.empty () == false) - { - return commands.front (); - } - return NULL; - } - void replaceCurrCommand (Command * cmd); - int getCountOfProducedUnits (const UnitType * ut) const; - unsigned int getCommandSize () const; - std::pair < CommandResult, string > giveCommand (Command * command, bool tryQueue = false); //give a command - CommandResult finishCommand (); //command finished - CommandResult cancelCommand (); //cancel canceled - - //lifecycle - void create (bool startingUnit = false); - void born (const CommandType * ct); - void kill (); - void undertake (); - - //observers - void addObserver (UnitObserver * unitObserver); - //void removeObserver(UnitObserver *unitObserver); - void notifyObservers (UnitObserver::Event event); - - //other - void resetHighlight (); - const CommandType *computeCommandType (const Vec2i & pos, - const Unit * targetUnit = - NULL) const; - string getDesc (bool translatedValue) const; - string getDescExtension (bool translatedValue) const; - bool computeEp (); - //bool computeHp(); - bool repair (); - bool decHp (int i); - int update2 (); - bool update (); - void tick (); - RandomGen *getRandom (bool threadAccessAllowed = false); - - bool applyAttackBoost (const AttackBoost * boost, const Unit * source); - void deapplyAttackBoost (const AttackBoost * boost, - const Unit * source); - - void applyUpgrade (const UpgradeType * upgradeType); - void computeTotalUpgrade (); - void incKills (int team); - bool morph (const MorphCommandType * mct, int frameIndex); - std::pair < CommandResult, - string > checkCommand (Command * command) const; - void applyCommand (Command * command); - - void setModelFacing (CardinalDir value); - inline CardinalDir getModelFacing () const - { - return modelFacing; - } - - bool isMeetingPointSettable () const; - - inline int getLastRenderFrame () const - { - return lastRenderFrame; - } - inline void setLastRenderFrame (int value) - { - lastRenderFrame = value; - } - - inline int getRetryCurrCommandCount () const - { - return retryCurrCommandCount; - } - inline void setRetryCurrCommandCount (int value) - { - retryCurrCommandCount = value; - } - - inline Vec3f getScreenPos () const - { - return screenPos; - } - void setScreenPos (Vec3f value) - { - screenPos = value; - } - - inline string getCurrentUnitTitle () const - { - return currentUnitTitle; - } - void setCurrentUnitTitle (string value) - { - currentUnitTitle = value; - } - - void exploreCells (bool forceRefresh = false); - - inline bool getInBailOutAttempt () const - { - return inBailOutAttempt; - } - inline void setInBailOutAttempt (bool value) - { - inBailOutAttempt = value; - } - - //std::vector > getBadHarvestPosList() const { return badHarvestPosList; } - //void setBadHarvestPosList(std::vector > value) { badHarvestPosList = value; } - void addBadHarvestPos (const Vec2i & value); - //void removeBadHarvestPos(const Vec2i &value); - inline bool isBadHarvestPos (const Vec2i & value, bool checkPeerUnits = - true) const - { - bool result = false; - if (badHarvestPosList.empty () == true) - { - return result; - } - - std::map < Vec2i, int >::const_iterator iter = - badHarvestPosList.find (value); - if (iter != badHarvestPosList.end ()) - { - result = true; - } - else if (checkPeerUnits == true) - { - // Check if any other units of similar type have this position tagged - // as bad? - for (int i = 0; i < this->getFaction ()->getUnitCount (); ++i) - { - Unit *peerUnit = this->getFaction ()->getUnit (i); - if (peerUnit != NULL && peerUnit->getId () != this->getId () && - peerUnit->getType ()->hasCommandClass (ccHarvest) == true && - peerUnit->getType ()->getSize () <= - this->getType ()->getSize ()) - { - if (peerUnit->isBadHarvestPos (value, false) == true) - { - result = true; - break; - } - } - } - } - - return result; - } - void cleanupOldBadHarvestPos (); - - void setLastHarvestResourceTarget (const Vec2i * pos); - inline std::pair < Vec2i, int >getLastHarvestResourceTarget () const - { - return lastHarvestResourceTarget; - } - - //std::pair > getCurrentTargetPathTaken() const { return currentTargetPathTaken; } - //void addCurrentTargetPathTakenCell(const Vec2i &target,const Vec2i &cell); - - void logSynchData (string file, int line, string source = ""); - void logSynchDataThreaded (string file, int line, string source = ""); - - std::string toString (bool crcMode = false) const; - bool needToUpdate (); - float getProgressAsFloat () const; - int64 getUpdateProgress (); - int64 getDiagonalFactor (); - int64 getHeightFactor (int64 speedMultiplier = - PROGRESS_SPEED_MULTIPLIER); - int64 getSpeedDenominator (int64 updateFPS); - bool isChangedActiveCommand () const - { - return changedActiveCommand; - } - - bool isLastStuckFrameWithinCurrentFrameTolerance (bool evalMode); - inline uint32 getLastStuckFrame () const - { - return lastStuckFrame; - } - //inline void setLastStuckFrame(uint32 value) { lastStuckFrame = value; } - void setLastStuckFrameToCurrentFrame (); - - inline Vec2i getLastStuckPos () const - { - return lastStuckPos; - } - inline void setLastStuckPos (Vec2i pos) - { - lastStuckPos = pos; - } - - bool isLastPathfindFailedFrameWithinCurrentFrameTolerance () const; - inline uint32 getLastPathfindFailedFrame () const - { - return lastPathfindFailedFrame; - } - inline void setLastPathfindFailedFrame (uint32 value) - { - lastPathfindFailedFrame = value; - } - void setLastPathfindFailedFrameToCurrentFrame (); - - inline Vec2i getLastPathfindFailedPos () const - { - return lastPathfindFailedPos; - } - inline void setLastPathfindFailedPos (Vec2i pos) - { - lastPathfindFailedPos = pos; - } - - inline bool getUsePathfinderExtendedMaxNodes () const - { - return usePathfinderExtendedMaxNodes; - } - inline void setUsePathfinderExtendedMaxNodes (bool value) - { - usePathfinderExtendedMaxNodes = value; - } - - void updateTimedParticles (); - void setMeshPosInParticleSystem (UnitParticleSystem * ups); - - virtual string getUniquePickName () const; - void saveGame (XmlNode * rootNode); - static Unit *loadGame (const XmlNode * rootNode, - GameSettings * settings, Faction * faction, - World * world); - - void clearCaches (); - bool showTranslatedTechTree () const; - - void addAttackParticleSystem (ParticleSystem * ps); - - Checksum getCRC (); - - virtual void end (ParticleSystem * particleSystem); - virtual void logParticleInfo (string info); - void setNetworkCRCParticleLogInfo (string networkCRCParticleLogInfo) - { - this->networkCRCParticleLogInfo = networkCRCParticleLogInfo; - } - void clearParticleInfo (); - void addNetworkCRCDecHp (string info); - void clearNetworkCRCDecHpList (); - - private: - - void cleanupAllParticlesystems (); - bool isNetworkCRCEnabled (); - string getNetworkCRCDecHpList () const; - string getParticleInfo () const; - - float computeHeight (const Vec2i & pos) const; - void calculateXZRotation (); - void AnimCycleStarts (); - void updateTarget (); - void clearCommands (); - void deleteQueuedCommand (Command * command); - CommandResult undoCommand (Command * command); - void stopDamageParticles (bool force); - void startDamageParticles (); - - uint32 getFrameCount () const; - - void checkCustomizedParticleTriggers (bool force); - void checkCustomizedUnitParticleTriggers (); - void checkCustomizedUnitParticleListTriggers (const - UnitParticleSystemTypes & - unitParticleSystemTypesList, - bool - applySkillChangeParticles); - void queueTimedParticles (const UnitParticleSystemTypes & - unitParticleSystemTypesList); - - bool checkModelStateInfoForNewHpValue (); - void checkUnitLevel (); - - void morphAttackBoosts (Unit * unit); - - int64 getUpdatedProgress (int64 currentProgress, int64 updateFPS, - int64 speed, int64 diagonalFactor, - int64 heightFactor); - - void logSynchDataCommon (string file, int line, string source = - "", bool threadedMode = false); - void updateAttackBoostProgress (const Game * game); - - void setAlive (bool value); - }; - -}} // end namespace + private: + const int32 id; + int32 hp; + int32 ep; + int32 loadCount; + int32 deadCount; + //float progress; //between 0 and 1 + int64 progress; //between 0 and 1 + int64 lastAnimProgress; //between 0 and 1 + int64 animProgress; //between 0 and 1 + float highlight; + // Progress2 keeps track of update/ upgrade progress of a unit. + int32 progress2; + int32 kills; + int32 enemyKills; + bool morphFieldsBlocked; + int oldTotalSight; + + UnitReference targetRef; + + Field currField; + Field targetField; + const Level *level; + + Vec2i pos; + Vec2i lastPos; + Vec2i targetPos; //absolute target pos + Vec3f targetVec; + Vec2i meetingPos; + + float lastRotation; //in degrees + float targetRotation; + float rotation; + float targetRotationZ; + float targetRotationX; + float rotationZ; + float rotationX; + + const UnitType *preMorph_type; + const UnitType *type; + const ResourceType *loadType; + const SkillType *currSkill; + int32 lastModelIndexForCurrSkillType; + int32 animationRandomCycleCount; + + bool toBeUndertaken; + bool alive; + bool showUnitParticles; + + Faction *faction; + ParticleSystem *fire; + TotalUpgrade totalUpgrade; + Map *map; + + UnitPathInterface *unitPath; + WaypointPath waypointPath; + + Commands commands; + Observers observers; + vector < UnitParticleSystem * >unitParticleSystems; + vector < UnitParticleSystemType * >queuedUnitParticleSystemTypes; + + UnitParticleSystems damageParticleSystems; + std::map < int, UnitParticleSystem * >damageParticleSystemsInUse; + + vector < ParticleSystem * >fireParticleSystems; + vector < UnitParticleSystem * >smokeParticleSystems; + vector < ParticleSystem * >attackParticleSystems; + + CardinalDir modelFacing; + + std::string lastSynchDataString; + std::string lastFile; + int32 lastLine; + std::string lastSource; + int32 lastRenderFrame; + bool visible; + + int retryCurrCommandCount; + + Vec3f screenPos; + string currentUnitTitle; + + bool inBailOutAttempt; + // This buffer stores a list of bad harvest cells, along with the start + // time of when it was detected. Typically this may be due to a unit + // constantly getting blocked from getting to the resource so this + // list may be used to tell areas of the game to ignore those cells for a + // period of time + //std::vector > badHarvestPosList; + std::map < Vec2i, int >badHarvestPosList; + //time_t lastBadHarvestListPurge; + std::pair < Vec2i, int >lastHarvestResourceTarget; + + //std::pair > currentTargetPathTaken; + + static Game *game; + + bool ignoreCheckCommand; + + uint32 lastStuckFrame; + Vec2i lastStuckPos; + + uint32 lastPathfindFailedFrame; + Vec2i lastPathfindFailedPos; + bool usePathfinderExtendedMaxNodes; + int32 maxQueuedCommandDisplayCount; + + UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect; + + std::vector < UnitAttackBoostEffect * >currentAttackBoostEffects; + + Mutex *mutexCommands; + + //static Mutex mutexDeletedUnits; + //static std::map deletedUnits; + + bool changedActiveCommand; + uint32 lastChangedActiveCommandFrame; + uint32 changedActiveCommandFrame; + + int32 lastAttackerUnitId; + int32 lastAttackedUnitId; + CauseOfDeathType causeOfDeath; + + uint32 pathfindFailedConsecutiveFrameCount; + Vec2i currentPathFinderDesiredFinalPos; + + RandomGen random; + int32 pathFindRefreshCellCount; + + FowAlphaCellsLookupItem cachedFow; + Vec2i cachedFowPos; + + ExploredCellsLookupItem cacheExploredCells; + std::pair < Vec2i, int >cacheExploredCellsKey; + + Vec2i lastHarvestedResourcePos; + + string networkCRCLogInfo; + string networkCRCParticleLogInfo; + vector < string > networkCRCDecHpList; + vector < string > networkCRCParticleInfoList; + + public: + Unit(int id, UnitPathInterface * path, const Vec2i & pos, + const UnitType * type, Faction * faction, Map * map, + CardinalDir placeFacing); + virtual ~Unit(); + + //static bool isUnitDeleted(void *unit); + + static void setGame(Game * value) { + game = value; + } + + inline int getPathFindRefreshCellCount() const { + return pathFindRefreshCellCount; + } + + void setCurrentPathFinderDesiredFinalPos(const Vec2i & finalPos) { + currentPathFinderDesiredFinalPos = finalPos; + } + Vec2i getCurrentPathFinderDesiredFinalPos() const { + return currentPathFinderDesiredFinalPos; + } + + const UnitAttackBoostEffectOriginator & + getAttackBoostOriginatorEffect() const { + return currentAttackBoostOriginatorEffect; + } + bool unitHasAttackBoost(const AttackBoost * boost, + const Unit * source); + + inline uint32 getPathfindFailedConsecutiveFrameCount() const { + return pathfindFailedConsecutiveFrameCount; + } + inline void incrementPathfindFailedConsecutiveFrameCount() { + pathfindFailedConsecutiveFrameCount++; + } + inline void resetPathfindFailedConsecutiveFrameCount() { + pathfindFailedConsecutiveFrameCount = 0; + } + + const FowAlphaCellsLookupItem & getCachedFow() const { + return cachedFow; + } + FowAlphaCellsLookupItem getFogOfWarRadius(bool useCache) const; + void calculateFogOfWarRadius(bool forceRefresh = false); + + //queries + Command *getCurrrentCommandThreadSafe(); + void setIgnoreCheckCommand(bool value) { + ignoreCheckCommand = value; + } + inline bool getIgnoreCheckCommand() const { + return ignoreCheckCommand; + } + inline int getId() const { + return id; + } + inline Field getCurrField() const { + return currField; + } + inline int getLoadCount() const { + return loadCount; + } + + //inline int getLastAnimProgress() const {return lastAnimProgress;} + //inline int getAnimProgress() const {return animProgress;} + inline float getLastAnimProgressAsFloat() const { + return static_cast < + float>(lastAnimProgress) / ANIMATION_SPEED_MULTIPLIER; + } + inline float getAnimProgressAsFloat() const { + return static_cast < + float>(animProgress) / ANIMATION_SPEED_MULTIPLIER; + } + + inline float getHightlight() const { + return highlight; + } + inline int getProgress2() const { + return progress2; + } + inline int getFactionIndex() const { + return faction->getIndex(); + } + inline int getTeam() const { + return faction->getTeam(); + } + inline int getHp() const { + return hp; + } + inline int getEp() const { + return ep; + } + int getProductionPercent() const; + float getProgressRatio() const; + float getHpRatio() const; + float getEpRatio() const; + inline bool getToBeUndertaken() const { + return toBeUndertaken; + } + inline Vec2i getTargetPos() const { + return targetPos; + } + inline Vec3f getTargetVec() const { + return targetVec; + } + inline Field getTargetField() const { + return targetField; + } + inline Vec2i getMeetingPos() const { + return meetingPos; + } + inline Faction *getFaction() const { + return faction; + } + inline const ResourceType *getLoadType() const { + return loadType; + } + + inline const UnitType *getType() const { + return type; + } + void setType(const UnitType * newType); + inline const UnitType *getPreMorphType() const { + return preMorph_type; + } + + inline const SkillType *getCurrSkill() const { + return currSkill; + } + inline const TotalUpgrade *getTotalUpgrade() const { + return &totalUpgrade; + } + inline float getRotation() const { + return rotation; + } + float getRotationX() const; + float getRotationZ() const; + ParticleSystem *getFire() const; + inline int getKills() const { + return kills; + } + inline int getEnemyKills() const { + return enemyKills; + } + inline const Level *getLevel() const { + return level; + } + const Level *getNextLevel() const; + string getFullName(bool translatedValue) const; + inline const UnitPathInterface *getPath() const { + return unitPath; + } + inline UnitPathInterface *getPath() { + return unitPath; + } + inline WaypointPath *getWaypointPath() { + return &waypointPath; + } + + inline int getLastAttackerUnitId() const { + return lastAttackerUnitId; + } + inline void setLastAttackerUnitId(int unitId) { + lastAttackerUnitId = unitId; + } + + inline int getLastAttackedUnitId() const { + return lastAttackedUnitId; + } + inline void setLastAttackedUnitId(int unitId) { + lastAttackedUnitId = unitId; + } + + inline CauseOfDeathType getCauseOfDeath() const { + return causeOfDeath; + } + inline void setCauseOfDeath(CauseOfDeathType cause) { + causeOfDeath = cause; + } + + //pos + inline Vec2i getPosNotThreadSafe() const { + return pos; + } + Vec2i getPos(); + Vec2i getPosWithCellMapSet() const; + inline Vec2i getLastPos() const { + return lastPos; + } + Vec2i getCenteredPos() const; + Vec2f getFloatCenteredPos() const; + Vec2i getCellPos() const; + + //is + inline bool isHighlighted() const { + return highlight > 0.f; + } + inline bool isDead() const { + return !alive; + } + inline bool isAlive() const { + return alive; + } + bool isOperative() const; + bool isBeingBuilt() const; + bool isBuilt() const; + bool isBuildCommandPending() const; + UnitBuildInfo getBuildCommandPendingInfo() const; + + bool isAnimProgressBound() const; + bool isPutrefacting() const { + return deadCount != 0; + } + bool isAlly(const Unit * unit) const; + bool isDamaged() const; + bool isInteresting(InterestingUnitType iut) const; + + //set + //void setCurrField(Field currField); + void setCurrSkill(const SkillType * currSkill); + void setCurrSkill(SkillClass sc); + + void setMorphFieldsBlocked(bool value) { + this->morphFieldsBlocked = value; + } + bool getMorphFieldsBlocked() const { + return morphFieldsBlocked; + } + + inline void setLastHarvestedResourcePos(Vec2i pos) { + this->lastHarvestedResourcePos = pos; + } + inline Vec2i getLastHarvestedResourcePos() const { + return this->lastHarvestedResourcePos; + } + + inline void setLoadCount(int loadCount) { + this->loadCount = loadCount; + } + inline void setLoadType(const ResourceType * loadType) { + this->loadType = loadType; + } + // resetProgress2 resets produce and upgrade progress. + inline void resetProgress2() { + this->progress2 = 0; + } + void setPos(const Vec2i & pos, bool clearPathFinder = + false, bool threaded = false); + void refreshPos(bool forceRefresh = false); + void setTargetPos(const Vec2i & targetPos, bool threaded = false); + void setTarget(const Unit * unit); + //void setTargetVec(const Vec3f &targetVec); + void setMeetingPos(const Vec2i & meetingPos); + void setVisible(const bool visible); + inline bool getVisible() const { + return visible; + } + + //render related + //const Model *getCurrentModel(); + Model *getCurrentModelPtr(); + Vec3f getCurrMidHeightVector() const; + Vec3f getCurrVectorForParticlesystems() const; + Vec3f getCurrVectorAsTarget() const; + Vec3f getCurrBurnVector() const; + Vec3f getCurrVectorFlat() const; + Vec3f getVectorFlat(const Vec2i & lastPosValue, + const Vec2i & curPosValue) const; + + //command related + bool anyCommand(bool validateCommandtype = false) const; + inline Command *getCurrCommand() const { + if (commands.empty() == false) { + return commands.front(); + } + return NULL; + } + void replaceCurrCommand(Command * cmd); + int getCountOfProducedUnits(const UnitType * ut) const; + unsigned int getCommandSize() const; + std::pair < CommandResult, string > giveCommand(Command * command, bool tryQueue = false); //give a command + CommandResult finishCommand(); //command finished + CommandResult cancelCommand(); //cancel canceled + + //lifecycle + void create(bool startingUnit = false); + void born(const CommandType * ct); + void kill(); + void undertake(); + + //observers + void addObserver(UnitObserver * unitObserver); + //void removeObserver(UnitObserver *unitObserver); + void notifyObservers(UnitObserver::Event event); + + //other + void resetHighlight(); + const CommandType *computeCommandType(const Vec2i & pos, + const Unit * targetUnit = + NULL) const; + string getDesc(bool translatedValue) const; + string getDescExtension(bool translatedValue) const; + bool computeEp(); + //bool computeHp(); + bool repair(); + bool decHp(int i); + int update2(); + bool update(); + void tick(); + RandomGen *getRandom(bool threadAccessAllowed = false); + + bool applyAttackBoost(const AttackBoost * boost, const Unit * source); + void deapplyAttackBoost(const AttackBoost * boost, + const Unit * source); + + void applyUpgrade(const UpgradeType * upgradeType); + void computeTotalUpgrade(); + void incKills(int team); + bool morph(const MorphCommandType * mct, int frameIndex); + std::pair < CommandResult, + string > checkCommand(Command * command) const; + void applyCommand(Command * command); + + void setModelFacing(CardinalDir value); + inline CardinalDir getModelFacing() const { + return modelFacing; + } + + bool isMeetingPointSettable() const; + + inline int getLastRenderFrame() const { + return lastRenderFrame; + } + inline void setLastRenderFrame(int value) { + lastRenderFrame = value; + } + + inline int getRetryCurrCommandCount() const { + return retryCurrCommandCount; + } + inline void setRetryCurrCommandCount(int value) { + retryCurrCommandCount = value; + } + + inline Vec3f getScreenPos() const { + return screenPos; + } + void setScreenPos(Vec3f value) { + screenPos = value; + } + + inline string getCurrentUnitTitle() const { + return currentUnitTitle; + } + void setCurrentUnitTitle(string value) { + currentUnitTitle = value; + } + + void exploreCells(bool forceRefresh = false); + + inline bool getInBailOutAttempt() const { + return inBailOutAttempt; + } + inline void setInBailOutAttempt(bool value) { + inBailOutAttempt = value; + } + + //std::vector > getBadHarvestPosList() const { return badHarvestPosList; } + //void setBadHarvestPosList(std::vector > value) { badHarvestPosList = value; } + void addBadHarvestPos(const Vec2i & value); + //void removeBadHarvestPos(const Vec2i &value); + inline bool isBadHarvestPos(const Vec2i & value, bool checkPeerUnits = + true) const { + bool result = false; + if (badHarvestPosList.empty() == true) { + return result; + } + + std::map < Vec2i, int >::const_iterator iter = + badHarvestPosList.find(value); + if (iter != badHarvestPosList.end()) { + result = true; + } else if (checkPeerUnits == true) { + // Check if any other units of similar type have this position tagged + // as bad? + for (int i = 0; i < this->getFaction()->getUnitCount(); ++i) { + Unit *peerUnit = this->getFaction()->getUnit(i); + if (peerUnit != NULL && peerUnit->getId() != this->getId() && + peerUnit->getType()->hasCommandClass(ccHarvest) == true && + peerUnit->getType()->getSize() <= + this->getType()->getSize()) { + if (peerUnit->isBadHarvestPos(value, false) == true) { + result = true; + break; + } + } + } + } + + return result; + } + void cleanupOldBadHarvestPos(); + + void setLastHarvestResourceTarget(const Vec2i * pos); + inline std::pair < Vec2i, int >getLastHarvestResourceTarget() const { + return lastHarvestResourceTarget; + } + + //std::pair > getCurrentTargetPathTaken() const { return currentTargetPathTaken; } + //void addCurrentTargetPathTakenCell(const Vec2i &target,const Vec2i &cell); + + void logSynchData(string file, int line, string source = ""); + void logSynchDataThreaded(string file, int line, string source = ""); + + std::string toString(bool crcMode = false) const; + bool needToUpdate(); + float getProgressAsFloat() const; + int64 getUpdateProgress(); + int64 getDiagonalFactor(); + int64 getHeightFactor(int64 speedMultiplier = + PROGRESS_SPEED_MULTIPLIER); + int64 getSpeedDenominator(int64 updateFPS); + bool isChangedActiveCommand() const { + return changedActiveCommand; + } + + bool isLastStuckFrameWithinCurrentFrameTolerance(bool evalMode); + inline uint32 getLastStuckFrame() const { + return lastStuckFrame; + } + //inline void setLastStuckFrame(uint32 value) { lastStuckFrame = value; } + void setLastStuckFrameToCurrentFrame(); + + inline Vec2i getLastStuckPos() const { + return lastStuckPos; + } + inline void setLastStuckPos(Vec2i pos) { + lastStuckPos = pos; + } + + bool isLastPathfindFailedFrameWithinCurrentFrameTolerance() const; + inline uint32 getLastPathfindFailedFrame() const { + return lastPathfindFailedFrame; + } + inline void setLastPathfindFailedFrame(uint32 value) { + lastPathfindFailedFrame = value; + } + void setLastPathfindFailedFrameToCurrentFrame(); + + inline Vec2i getLastPathfindFailedPos() const { + return lastPathfindFailedPos; + } + inline void setLastPathfindFailedPos(Vec2i pos) { + lastPathfindFailedPos = pos; + } + + inline bool getUsePathfinderExtendedMaxNodes() const { + return usePathfinderExtendedMaxNodes; + } + inline void setUsePathfinderExtendedMaxNodes(bool value) { + usePathfinderExtendedMaxNodes = value; + } + + void updateTimedParticles(); + void setMeshPosInParticleSystem(UnitParticleSystem * ups); + + virtual string getUniquePickName() const; + void saveGame(XmlNode * rootNode); + static Unit *loadGame(const XmlNode * rootNode, + GameSettings * settings, Faction * faction, + World * world); + + void clearCaches(); + bool showTranslatedTechTree() const; + + void addAttackParticleSystem(ParticleSystem * ps); + + Checksum getCRC(); + + virtual void end(ParticleSystem * particleSystem); + virtual void logParticleInfo(string info); + void setNetworkCRCParticleLogInfo(string networkCRCParticleLogInfo) { + this->networkCRCParticleLogInfo = networkCRCParticleLogInfo; + } + void clearParticleInfo(); + void addNetworkCRCDecHp(string info); + void clearNetworkCRCDecHpList(); + + private: + + void cleanupAllParticlesystems(); + bool isNetworkCRCEnabled(); + string getNetworkCRCDecHpList() const; + string getParticleInfo() const; + + float computeHeight(const Vec2i & pos) const; + void calculateXZRotation(); + void AnimCycleStarts(); + void updateTarget(); + void clearCommands(); + void deleteQueuedCommand(Command * command); + CommandResult undoCommand(Command * command); + void stopDamageParticles(bool force); + void startDamageParticles(); + + uint32 getFrameCount() const; + + void checkCustomizedParticleTriggers(bool force); + void checkCustomizedUnitParticleTriggers(); + void checkCustomizedUnitParticleListTriggers(const + UnitParticleSystemTypes & + unitParticleSystemTypesList, + bool + applySkillChangeParticles); + void queueTimedParticles(const UnitParticleSystemTypes & + unitParticleSystemTypesList); + + bool checkModelStateInfoForNewHpValue(); + void checkUnitLevel(); + + void morphAttackBoosts(Unit * unit); + + int64 getUpdatedProgress(int64 currentProgress, int64 updateFPS, + int64 speed, int64 diagonalFactor, + int64 heightFactor); + + void logSynchDataCommon(string file, int line, string source = + "", bool threadedMode = false); + void updateAttackBoostProgress(const Game * game); + + void setAlive(bool value); + }; + + } +} // end namespace #endif diff --git a/source/glest_game/type_instances/upgrade.cpp b/source/glest_game/type_instances/upgrade.cpp index 090a02876..b9418b08a 100644 --- a/source/glest_game/type_instances/upgrade.cpp +++ b/source/glest_game/type_instances/upgrade.cpp @@ -24,332 +24,293 @@ using namespace std; using namespace Shared::Util; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class Upgrade -// ===================================================== - Upgrade::Upgrade () - { - state = usUpgrading; - this->factionIndex = -1; - this->type = NULL; - } - - Upgrade::Upgrade (const UpgradeType * type, int factionIndex) - { - state = usUpgrading; - this->factionIndex = factionIndex; - this->type = type; - } - -// ============== get ============== - - UpgradeState Upgrade::getState () const - { - return state; - } - - int Upgrade::getFactionIndex () const - { - return factionIndex; - } - - const UpgradeType *Upgrade::getType () const - { - return type; - } - -// ============== set ============== - - void Upgrade::setState (UpgradeState state) - { - this->state = state; - } - - std::string Upgrade::toString ()const - { - std::string result = ""; - - result += - " state = " + intToStr (state) + " factionIndex = " + - intToStr (factionIndex); - if (type != NULL) - { - result += " type = " + type->getReqDesc (false); - } - - return result; - } - - void Upgrade::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode *upgradeNode = rootNode->addChild ("Upgrade"); - - upgradeNode->addAttribute ("state", intToStr (state), - mapTagReplacements); - upgradeNode->addAttribute ("factionIndex", intToStr (factionIndex), - mapTagReplacements); - upgradeNode->addAttribute ("type", type->getName (), - mapTagReplacements); - } - - Upgrade *Upgrade::loadGame (const XmlNode * rootNode, Faction * faction) - { - Upgrade *newUpgrade = new Upgrade (); - - const XmlNode *upgradeNode = rootNode; - - //description = upgrademanagerNode->getAttribute("description")->getValue(); - - newUpgrade->state = - static_cast < UpgradeState > - (upgradeNode->getAttribute ("state")->getIntValue ()); - newUpgrade->factionIndex = - upgradeNode->getAttribute ("factionIndex")->getIntValue (); - string unitTypeName = upgradeNode->getAttribute ("type")->getValue (); - newUpgrade->type = faction->getType ()->getUpgradeType (unitTypeName); - - return newUpgrade; - } - -// ===================================================== -// class UpgradeManager -// ===================================================== - - UpgradeManager::~UpgradeManager () - { - upgradesLookup.clear (); - deleteValues (upgrades.begin (), upgrades.end ()); - } - - void UpgradeManager::startUpgrade (const UpgradeType * upgradeType, - int factionIndex) - { - Upgrade *upgrade = new Upgrade (upgradeType, factionIndex); - upgrades.push_back (upgrade); - upgradesLookup[upgradeType] = (int) upgrades.size () - 1; - } - - void UpgradeManager::cancelUpgrade (const UpgradeType * upgradeType) - { - map < const UpgradeType *, int >::iterator iterFind = - upgradesLookup.find (upgradeType); - if (iterFind != upgradesLookup.end ()) - { - if (iterFind->second >= (int) upgrades.size ()) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Error canceling upgrade, iterFind->second >= upgrades.size() - [%d] : [%d]", - iterFind->second, (int) upgrades.size ()); - throw - megaglest_runtime_error - ("Error canceling upgrade, upgrade not found in upgrade manager"); - } - int eraseIndex = iterFind->second; - upgrades.erase (upgrades.begin () + eraseIndex); - upgradesLookup.erase (upgradeType); - - for (map < const UpgradeType *, int >::iterator iterMap = - upgradesLookup.begin (); iterMap != upgradesLookup.end (); - ++iterMap) - { - if (iterMap->second >= (int) upgrades.size ()) - { - iterMap->second--; - } - if (iterMap->second < 0) - { - upgradesLookup.erase (iterMap->first); - } - } - } - else - { - throw - megaglest_runtime_error - ("Error canceling upgrade, upgrade not found in upgrade manager"); - } - -/* - Upgrades::iterator it; - - for(it=upgrades.begin(); it!=upgrades.end(); it++){ - if((*it)->getType()==upgradeType){ - break; + // ===================================================== + // class Upgrade + // ===================================================== + Upgrade::Upgrade() { + state = usUpgrading; + this->factionIndex = -1; + this->type = NULL; } - } - if(it!=upgrades.end()){ - upgrades.erase(it); - } - else{ - throw megaglest_runtime_error("Error canceling upgrade, upgrade not found in upgrade manager"); - } -*/ - } - - void UpgradeManager::finishUpgrade (const UpgradeType * upgradeType) - { - map < const UpgradeType *, int >::iterator iterFind = - upgradesLookup.find (upgradeType); - if (iterFind != upgradesLookup.end ()) - { - upgrades[iterFind->second]->setState (usUpgraded); - } - else - { - throw - megaglest_runtime_error - ("Error finishing upgrade, upgrade not found in upgrade manager"); - } - - -/* - Upgrades::iterator it; - - for(it=upgrades.begin(); it!=upgrades.end(); it++){ - if((*it)->getType()==upgradeType){ - break; + Upgrade::Upgrade(const UpgradeType * type, int factionIndex) { + state = usUpgrading; + this->factionIndex = factionIndex; + this->type = type; } - } - if(it!=upgrades.end()){ - (*it)->setState(usUpgraded); - } - else{ - throw megaglest_runtime_error("Error finishing upgrade, upgrade not found in upgrade manager"); - } -*/ - } + // ============== get ============== - bool UpgradeManager::isUpgradingOrUpgraded (const UpgradeType * - upgradeType) const - { - if (upgradesLookup.find (upgradeType) != upgradesLookup.end ()) - { - return true; - } - - return false; - -/* - Upgrades::const_iterator it; - - for(it= upgrades.begin(); it!=upgrades.end(); it++){ - if((*it)->getType()==upgradeType){ - return true; + UpgradeState Upgrade::getState() const { + return state; } - } - return false; -*/ - } - - bool UpgradeManager::isUpgraded (const UpgradeType * upgradeType) const - { - map < const UpgradeType *, int >::const_iterator iterFind = - upgradesLookup.find (upgradeType); - if (iterFind != upgradesLookup.end ()) - { - return (upgrades[iterFind->second]->getState () == usUpgraded); - } - return false; - -/* - for(Upgrades::const_iterator it= upgrades.begin(); it!=upgrades.end(); it++){ - if((*it)->getType()==upgradeType && (*it)->getState()==usUpgraded){ - return true; + int Upgrade::getFactionIndex() const { + return factionIndex; } - } - return false; -*/ - } - bool UpgradeManager::isUpgrading (const UpgradeType * upgradeType) const - { - map < const UpgradeType *, int >::const_iterator iterFind = - upgradesLookup.find (upgradeType); - if (iterFind != upgradesLookup.end ()) - { - return (upgrades[iterFind->second]->getState () == usUpgrading); - } - return false; - -/* - for(Upgrades::const_iterator it= upgrades.begin(); it!=upgrades.end(); it++){ - if((*it)->getType()==upgradeType && (*it)->getState()==usUpgrading){ - return true; + const UpgradeType *Upgrade::getType() const { + return type; } + + // ============== set ============== + + void Upgrade::setState(UpgradeState state) { + this->state = state; + } + + std::string Upgrade::toString()const { + std::string result = ""; + + result += + " state = " + intToStr(state) + " factionIndex = " + + intToStr(factionIndex); + if (type != NULL) { + result += " type = " + type->getReqDesc(false); + } + + return result; + } + + void Upgrade::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode *upgradeNode = rootNode->addChild("Upgrade"); + + upgradeNode->addAttribute("state", intToStr(state), + mapTagReplacements); + upgradeNode->addAttribute("factionIndex", intToStr(factionIndex), + mapTagReplacements); + upgradeNode->addAttribute("type", type->getName(), + mapTagReplacements); + } + + Upgrade *Upgrade::loadGame(const XmlNode * rootNode, Faction * faction) { + Upgrade *newUpgrade = new Upgrade(); + + const XmlNode *upgradeNode = rootNode; + + //description = upgrademanagerNode->getAttribute("description")->getValue(); + + newUpgrade->state = + static_cast + (upgradeNode->getAttribute("state")->getIntValue()); + newUpgrade->factionIndex = + upgradeNode->getAttribute("factionIndex")->getIntValue(); + string unitTypeName = upgradeNode->getAttribute("type")->getValue(); + newUpgrade->type = faction->getType()->getUpgradeType(unitTypeName); + + return newUpgrade; + } + + // ===================================================== + // class UpgradeManager + // ===================================================== + + UpgradeManager::~UpgradeManager() { + upgradesLookup.clear(); + deleteValues(upgrades.begin(), upgrades.end()); + } + + void UpgradeManager::startUpgrade(const UpgradeType * upgradeType, + int factionIndex) { + Upgrade *upgrade = new Upgrade(upgradeType, factionIndex); + upgrades.push_back(upgrade); + upgradesLookup[upgradeType] = (int) upgrades.size() - 1; + } + + void UpgradeManager::cancelUpgrade(const UpgradeType * upgradeType) { + map < const UpgradeType *, int >::iterator iterFind = + upgradesLookup.find(upgradeType); + if (iterFind != upgradesLookup.end()) { + if (iterFind->second >= (int) upgrades.size()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Error canceling upgrade, iterFind->second >= upgrades.size() - [%d] : [%d]", + iterFind->second, (int) upgrades.size()); + throw + megaglest_runtime_error + ("Error canceling upgrade, upgrade not found in upgrade manager"); + } + int eraseIndex = iterFind->second; + upgrades.erase(upgrades.begin() + eraseIndex); + upgradesLookup.erase(upgradeType); + + for (map < const UpgradeType *, int >::iterator iterMap = + upgradesLookup.begin(); iterMap != upgradesLookup.end(); + ++iterMap) { + if (iterMap->second >= (int) upgrades.size()) { + iterMap->second--; + } + if (iterMap->second < 0) { + upgradesLookup.erase(iterMap->first); + } + } + } else { + throw + megaglest_runtime_error + ("Error canceling upgrade, upgrade not found in upgrade manager"); + } + + /* + Upgrades::iterator it; + + for(it=upgrades.begin(); it!=upgrades.end(); it++){ + if((*it)->getType()==upgradeType){ + break; + } + } + + if(it!=upgrades.end()){ + upgrades.erase(it); + } + else{ + throw megaglest_runtime_error("Error canceling upgrade, upgrade not found in upgrade manager"); + } + */ + } + + void UpgradeManager::finishUpgrade(const UpgradeType * upgradeType) { + map < const UpgradeType *, int >::iterator iterFind = + upgradesLookup.find(upgradeType); + if (iterFind != upgradesLookup.end()) { + upgrades[iterFind->second]->setState(usUpgraded); + } else { + throw + megaglest_runtime_error + ("Error finishing upgrade, upgrade not found in upgrade manager"); + } + + + /* + Upgrades::iterator it; + + for(it=upgrades.begin(); it!=upgrades.end(); it++){ + if((*it)->getType()==upgradeType){ + break; + } + } + + if(it!=upgrades.end()){ + (*it)->setState(usUpgraded); + } + else{ + throw megaglest_runtime_error("Error finishing upgrade, upgrade not found in upgrade manager"); + } + */ + } + + bool UpgradeManager::isUpgradingOrUpgraded(const UpgradeType * + upgradeType) const { + if (upgradesLookup.find(upgradeType) != upgradesLookup.end()) { + return true; + } + + return false; + + /* + Upgrades::const_iterator it; + + for(it= upgrades.begin(); it!=upgrades.end(); it++){ + if((*it)->getType()==upgradeType){ + return true; + } + } + + return false; + */ + } + + bool UpgradeManager::isUpgraded(const UpgradeType * upgradeType) const { + map < const UpgradeType *, int >::const_iterator iterFind = + upgradesLookup.find(upgradeType); + if (iterFind != upgradesLookup.end()) { + return (upgrades[iterFind->second]->getState() == usUpgraded); + } + return false; + + /* + for(Upgrades::const_iterator it= upgrades.begin(); it!=upgrades.end(); it++){ + if((*it)->getType()==upgradeType && (*it)->getState()==usUpgraded){ + return true; + } + } + return false; + */ + } + + bool UpgradeManager::isUpgrading(const UpgradeType * upgradeType) const { + map < const UpgradeType *, int >::const_iterator iterFind = + upgradesLookup.find(upgradeType); + if (iterFind != upgradesLookup.end()) { + return (upgrades[iterFind->second]->getState() == usUpgrading); + } + return false; + + /* + for(Upgrades::const_iterator it= upgrades.begin(); it!=upgrades.end(); it++){ + if((*it)->getType()==upgradeType && (*it)->getState()==usUpgrading){ + return true; + } + } + return false; + */ + } + + void UpgradeManager::computeTotalUpgrade(const Unit * unit, + TotalUpgrade * + totalUpgrade) const { + totalUpgrade->reset(); + for (Upgrades::const_iterator it = upgrades.begin(); + it != upgrades.end(); ++it) { + if ((*it)->getFactionIndex() == unit->getFactionIndex() + && (*it)->getType()->isAffected(unit->getType()) + && (*it)->getState() == usUpgraded) + totalUpgrade->sum((*it)->getType(), unit); + } + + } + + std::string UpgradeManager::toString() const { + std::string result = + "UpgradeCount: " + intToStr(this->getUpgradeCount()); + for (int idx = 0; idx < (int) upgrades.size(); idx++) { + result += + " index = " + intToStr(idx) + " " + upgrades[idx]->toString(); + } + return result; + } + + void UpgradeManager::saveGame(XmlNode * rootNode) { + //std::map mapTagReplacements; + XmlNode *upgrademanagerNode = rootNode->addChild("UpgradeManager"); + + for (unsigned int i = 0; i < upgrades.size(); ++i) { + upgrades[i]->saveGame(upgrademanagerNode); + } + + // Upgrades upgrades; + // UgradesLookup upgradesLookup; + } + + void UpgradeManager::loadGame(const XmlNode * rootNode, + Faction * faction) { + const XmlNode *upgrademanagerNode = + rootNode->getChild("UpgradeManager"); + + //description = upgrademanagerNode->getAttribute("description")->getValue(); + + vector < XmlNode * >upgradeNodeList = + upgrademanagerNode->getChildList("Upgrade"); + for (unsigned int i = 0; i < upgradeNodeList.size(); ++i) { + XmlNode *node = upgradeNodeList[i]; + Upgrade *newUpgrade = Upgrade::loadGame(node, faction); + upgrades.push_back(newUpgrade); + upgradesLookup[newUpgrade->getType()] = (int) upgrades.size() - 1; + } + } + } - return false; -*/ - } - - void UpgradeManager::computeTotalUpgrade (const Unit * unit, - TotalUpgrade * - totalUpgrade) const - { - totalUpgrade->reset (); - for (Upgrades::const_iterator it = upgrades.begin (); - it != upgrades.end (); ++it) - { - if ((*it)->getFactionIndex () == unit->getFactionIndex () - && (*it)->getType ()->isAffected (unit->getType ()) - && (*it)->getState () == usUpgraded) - totalUpgrade->sum ((*it)->getType (), unit); - } - - } - - std::string UpgradeManager::toString () const - { - std::string result = - "UpgradeCount: " + intToStr (this->getUpgradeCount ()); - for (int idx = 0; idx < (int) upgrades.size (); idx++) - { - result += - " index = " + intToStr (idx) + " " + upgrades[idx]->toString (); - } - return result; - } - - void UpgradeManager::saveGame (XmlNode * rootNode) - { - //std::map mapTagReplacements; - XmlNode *upgrademanagerNode = rootNode->addChild ("UpgradeManager"); - - for (unsigned int i = 0; i < upgrades.size (); ++i) - { - upgrades[i]->saveGame (upgrademanagerNode); - } - -// Upgrades upgrades; -// UgradesLookup upgradesLookup; - } - - void UpgradeManager::loadGame (const XmlNode * rootNode, - Faction * faction) - { - const XmlNode *upgrademanagerNode = - rootNode->getChild ("UpgradeManager"); - - //description = upgrademanagerNode->getAttribute("description")->getValue(); - - vector < XmlNode * >upgradeNodeList = - upgrademanagerNode->getChildList ("Upgrade"); - for (unsigned int i = 0; i < upgradeNodeList.size (); ++i) - { - XmlNode *node = upgradeNodeList[i]; - Upgrade *newUpgrade = Upgrade::loadGame (node, faction); - upgrades.push_back (newUpgrade); - upgradesLookup[newUpgrade->getType ()] = (int) upgrades.size () - 1; - } - } - -}} // end namespace +} // end namespace diff --git a/source/glest_game/type_instances/upgrade.h b/source/glest_game/type_instances/upgrade.h index 903817b30..8ba88c963 100644 --- a/source/glest_game/type_instances/upgrade.h +++ b/source/glest_game/type_instances/upgrade.h @@ -34,188 +34,183 @@ using std::vector; using std::map; using Shared::Xml::XmlNode; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - class Unit; - class UpgradeType; - class Faction; + class Unit; + class UpgradeType; + class Faction; -/** - * Stores the state of the upgrade (whether or not the upgrading process is complete). - */ -// TODO: Don't make this global; move it inside Upgrade - enum UpgradeState - { - usUpgrading, /**< The upgrade is currently in progress. */ - usUpgraded, /**< The upgrade is completed. */ + /** + * Stores the state of the upgrade (whether or not the upgrading process is complete). + */ + // TODO: Don't make this global; move it inside Upgrade + enum UpgradeState { + usUpgrading, /**< The upgrade is currently in progress. */ + usUpgraded, /**< The upgrade is completed. */ - upgradeStateCount // TODO: This should be unnecessary -- there's no need to iterate over this enum - }; + upgradeStateCount // TODO: This should be unnecessary -- there's no need to iterate over this enum + }; - class UpgradeManager; - class TotalUpgrade; + class UpgradeManager; + class TotalUpgrade; -/** - * An instance of an upgrade. Factions will typically have one upgrade of each type. This object - * groups the type, faction, and upgrade state (ie, has the upgrade been obtained yet?). - */ - class Upgrade - { - private: - UpgradeState state; - // TODO: I believe this is unnecessary. As far as I can tell, it's only used for checking - // that the unit we're applying UpgradeManager::computeTotalUpgrade to is in this faction. However, - // I don't see an circumstances when it wouldn't be (since the UpgradeManager already an aggregate - // of a faction and Unit directly gets the UpgradeManager from the faction (so it must have the - // same faction as the upgrades in the UpgradeManager). - int factionIndex; - const UpgradeType *type; + /** + * An instance of an upgrade. Factions will typically have one upgrade of each type. This object + * groups the type, faction, and upgrade state (ie, has the upgrade been obtained yet?). + */ + class Upgrade { + private: + UpgradeState state; + // TODO: I believe this is unnecessary. As far as I can tell, it's only used for checking + // that the unit we're applying UpgradeManager::computeTotalUpgrade to is in this faction. However, + // I don't see an circumstances when it wouldn't be (since the UpgradeManager already an aggregate + // of a faction and Unit directly gets the UpgradeManager from the faction (so it must have the + // same faction as the upgrades in the UpgradeManager). + int factionIndex; + const UpgradeType *type; - friend class UpgradeManager; + friend class UpgradeManager; - Upgrade (); - public: - /** - * Creates an upgrade. The upgrade state will be set to UpgradeState::usUpgrading. - * @param upgradeType The type of the upgrade that this corresponds to. Upgrade types are - * essentially "classes" for upgrades. - * @param factionIndex The index of the faction that the upgrade belongs to. - */ - Upgrade (const UpgradeType * upgradeType, int factionIndex); + Upgrade(); + public: + /** + * Creates an upgrade. The upgrade state will be set to UpgradeState::usUpgrading. + * @param upgradeType The type of the upgrade that this corresponds to. Upgrade types are + * essentially "classes" for upgrades. + * @param factionIndex The index of the faction that the upgrade belongs to. + */ + Upgrade(const UpgradeType * upgradeType, int factionIndex); - private: - UpgradeState getState () const; - int getFactionIndex () const; - const UpgradeType *getType () const; + private: + UpgradeState getState() const; + int getFactionIndex() const; + const UpgradeType *getType() const; - void setState (UpgradeState state); + void setState(UpgradeState state); - /** - * Retrieves a string representation of the upgrade (detailing its state, type, and faction). - */ - std::string toString () const; + /** + * Retrieves a string representation of the upgrade (detailing its state, type, and faction). + */ + std::string toString() const; - /** - * Saves the object state into the given node. - * @param rootNode The UpgradeManager node to save object info to. - */ - void saveGame (XmlNode * rootNode); + /** + * Saves the object state into the given node. + * @param rootNode The UpgradeManager node to save object info to. + */ + void saveGame(XmlNode * rootNode); - /** - * Loads the object state from the given node. - * @param rootNode The UpgradeManager node to retrieve object info from. - * @param faction The faction that the upgrade belongs to. Used to convert the upgrade type from - * the XML string. - */ - static Upgrade *loadGame (const XmlNode * rootNode, Faction * faction); - }; + /** + * Loads the object state from the given node. + * @param rootNode The UpgradeManager node to retrieve object info from. + * @param faction The faction that the upgrade belongs to. Used to convert the upgrade type from + * the XML string. + */ + static Upgrade *loadGame(const XmlNode * rootNode, Faction * faction); + }; -/** - * Manages upgrades by starting, stopping, and finishing upgrades. Each faction has their own - * upgrade manager. - */ - class UpgradeManager - { - private: - typedef vector < Upgrade * >Upgrades; - typedef map < const UpgradeType *, int >UgradesLookup; + /** + * Manages upgrades by starting, stopping, and finishing upgrades. Each faction has their own + * upgrade manager. + */ + class UpgradeManager { + private: + typedef vector < Upgrade * >Upgrades; + typedef map < const UpgradeType *, int >UgradesLookup; - /** - * List of upgrades that the upgrade manager is working with (either in progress or finished). - */ - Upgrades upgrades; + /** + * List of upgrades that the upgrade manager is working with (either in progress or finished). + */ + Upgrades upgrades; - /** - * Maps UpgradeType to the index of the upgrade in UpgradeManager::upgrades. - */ - UgradesLookup upgradesLookup; - public: - ~UpgradeManager (); + /** + * Maps UpgradeType to the index of the upgrade in UpgradeManager::upgrades. + */ + UgradesLookup upgradesLookup; + public: + ~UpgradeManager(); - int getUpgradeCount () const - { - return (int) upgrades.size (); - } + int getUpgradeCount() const { + return (int) upgrades.size(); + } - /** - * Starts an upgrade. - * @param upgradeType The type of the upgrade to start. - * @param factionIndex Passed to the constructor of the Upgrade. - */ - void startUpgrade (const UpgradeType * upgradeType, int factionIndex); + /** + * Starts an upgrade. + * @param upgradeType The type of the upgrade to start. + * @param factionIndex Passed to the constructor of the Upgrade. + */ + void startUpgrade(const UpgradeType * upgradeType, int factionIndex); - /** - * Cancels an upgrade before it is finished. The upgrade is removed from the UpgradeManager. - * @param upgradeType The type of the upgrade to remove. - * @throws megaglest_runtime_error If there is no upgrade of the desired type in the UpgradeManager. - */ - void cancelUpgrade (const UpgradeType * upgradeType); + /** + * Cancels an upgrade before it is finished. The upgrade is removed from the UpgradeManager. + * @param upgradeType The type of the upgrade to remove. + * @throws megaglest_runtime_error If there is no upgrade of the desired type in the UpgradeManager. + */ + void cancelUpgrade(const UpgradeType * upgradeType); - /** - * Sets an Upgrade in the UpgradeManager as finished (ie, the state is UpgradeState::usUpgraded). - * @param upgradeType The type of the upgrade to complete. - * @throws megaglest_runtime_error If there is no upgrade of the desired type in the UpgradeManager. - */ - void finishUpgrade (const UpgradeType * upgradeType); + /** + * Sets an Upgrade in the UpgradeManager as finished (ie, the state is UpgradeState::usUpgraded). + * @param upgradeType The type of the upgrade to complete. + * @throws megaglest_runtime_error If there is no upgrade of the desired type in the UpgradeManager. + */ + void finishUpgrade(const UpgradeType * upgradeType); - /** - * Returns true if an Upgrade of the desired type has state UpgradeState::usUpgraded (ie, is - * finished upgrading). - * @param upgradeType The type of the upgrade in question. - */ - bool isUpgraded (const UpgradeType * upgradeType) const; + /** + * Returns true if an Upgrade of the desired type has state UpgradeState::usUpgraded (ie, is + * finished upgrading). + * @param upgradeType The type of the upgrade in question. + */ + bool isUpgraded(const UpgradeType * upgradeType) const; - /** - * Returns true if an Upgrade of the desired type has state UpgradeState::usUpgrading (ie, is - * currently in progress). - * @param upgradeType The type of the upgrade in question. - */ - bool isUpgrading (const UpgradeType * upgradeType) const; + /** + * Returns true if an Upgrade of the desired type has state UpgradeState::usUpgrading (ie, is + * currently in progress). + * @param upgradeType The type of the upgrade in question. + */ + bool isUpgrading(const UpgradeType * upgradeType) const; - /** - * Returns true if an Upgrade of the desired type exists in the UpgradeManager. - * @param upgradeType The type of the upgrade in question. - */ - bool isUpgradingOrUpgraded (const UpgradeType * upgradeType) const; + /** + * Returns true if an Upgrade of the desired type exists in the UpgradeManager. + * @param upgradeType The type of the upgrade in question. + */ + bool isUpgradingOrUpgraded(const UpgradeType * upgradeType) const; - /** - * [Sums up](@ref TotalUpgrade::sum) the effect of all upgrades for this faction as they apply - * to a particular unit. - * @param unit The unit that the TotalUpgrade applies to. This is necessary because some - * upgrades provide percentage boosts. - * @param totalUpgrade The TotalUpgrade object to modify. Note that it is cleared before values - * are calculated. - */ - void computeTotalUpgrade (const Unit * unit, - TotalUpgrade * totalUpgrade) const; + /** + * [Sums up](@ref TotalUpgrade::sum) the effect of all upgrades for this faction as they apply + * to a particular unit. + * @param unit The unit that the TotalUpgrade applies to. This is necessary because some + * upgrades provide percentage boosts. + * @param totalUpgrade The TotalUpgrade object to modify. Note that it is cleared before values + * are calculated. + */ + void computeTotalUpgrade(const Unit * unit, + TotalUpgrade * totalUpgrade) const; - /** - * Retrieves a string representation of the UpgradeManager. Contains the contents of - * Upgrade::toString for all upgrades in the UpgradeManager. - */ - std::string toString () const; + /** + * Retrieves a string representation of the UpgradeManager. Contains the contents of + * Upgrade::toString for all upgrades in the UpgradeManager. + */ + std::string toString() const; - /** - * Adds a node for the UpgradeManager that contains all the upgrade nodes, saving the object's - * state. - * @param rootNode The faction node to add the UpgradeManager node to. - * @see Upgrade::saveGame - */ - void saveGame (XmlNode * rootNode); + /** + * Adds a node for the UpgradeManager that contains all the upgrade nodes, saving the object's + * state. + * @param rootNode The faction node to add the UpgradeManager node to. + * @see Upgrade::saveGame + */ + void saveGame(XmlNode * rootNode); - /** - * Loads all the upgrades from the UpgradeManager node, effectively reloading the object's - * state. - * @param rootNode The faction node to get the UpgradeManager node from. - * @param faction Only passed to Upgrade::loadGame (which does the actual loading of each - * Upgrade object. - */ - void loadGame (const XmlNode * rootNode, Faction * faction); - }; + /** + * Loads all the upgrades from the UpgradeManager node, effectively reloading the object's + * state. + * @param rootNode The faction node to get the UpgradeManager node from. + * @param faction Only passed to Upgrade::loadGame (which does the actual loading of each + * Upgrade object. + */ + void loadGame(const XmlNode * rootNode, Faction * faction); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/types/command_type.cpp b/source/glest_game/types/command_type.cpp index b2026fa78..5529aaece 100644 --- a/source/glest_game/types/command_type.cpp +++ b/source/glest_game/types/command_type.cpp @@ -29,1580 +29,1441 @@ using namespace Shared::Util; -namespace Glest -{ - namespace Game - { - - -// ===================================================== -// class CommandType -// ===================================================== - -//get - CommandClass CommandType::getClass () const - { - assert (this != NULL); - return commandTypeClass; - } - - void CommandType::load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, - string > > >&loadedFileList, string parentLoader) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - this->id = id; - name = - n->getChild ("name")->getAttribute ("value")->getRestrictedValue (); - - //image - const XmlNode *imageNode = n->getChild ("image"); - image = Renderer::getInstance ().newTexture2D (rsGame); - - string currentPath = dir; - endPathWithSlash (currentPath); - if (image) - { - image->load (imageNode->getAttribute ("path")-> - getRestrictedValue (currentPath)); - } - loadedFileList[imageNode->getAttribute ("path")-> - getRestrictedValue (currentPath)]. - push_back (make_pair - (parentLoader, - imageNode->getAttribute ("path")->getRestrictedValue ())); - - //unit requirements - const XmlNode *unitRequirementsNode = n->getChild ("unit-requirements"); - for (int i = 0; i < (int) unitRequirementsNode->getChildCount (); ++i) - { - const XmlNode *unitNode = unitRequirementsNode->getChild ("unit", i); - string name = unitNode->getAttribute ("name")->getRestrictedValue (); - unitReqs.push_back (ft->getUnitType (name)); - } - - //upgrade requirements - const XmlNode *upgradeRequirementsNode = - n->getChild ("upgrade-requirements"); - for (int i = 0; i < (int) upgradeRequirementsNode->getChildCount (); - ++i) - { - const XmlNode *upgradeReqNode = - upgradeRequirementsNode->getChild ("upgrade", i); - string name = - upgradeReqNode->getAttribute ("name")->getRestrictedValue (); - upgradeReqs.push_back (ft->getUpgradeType (name)); - } - - //fog of war - if (n->hasChild ("fog-of-war-skill") == true) - { - string skillName = - n->getChild ("fog-of-war-skill")->getAttribute ("value")-> - getRestrictedValue (); - fogOfWarSkillType = - static_cast < - const FogOfWarSkillType *>(ut.getSkillType (skillName, scFogOfWar)); - - string skillAttachmentNames = - n->getChild ("fog-of-war-skill")-> - getAttribute ("skill-attachments")->getValue (); - - std::vector < std::string > skillList; - Tokenize (skillAttachmentNames, skillList, ","); - for (unsigned int i = 0; i < skillList.size (); ++i) - { - string skillAttachName = skillList[i]; - fogOfWarSkillAttachments[skillAttachName] = true; - } - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - bool CommandType::hasFogOfWarSkillType (string name) const - { - std::map < string, bool >::const_iterator iterFind = - fogOfWarSkillAttachments.find (name); - bool result = (iterFind != fogOfWarSkillAttachments.end ()); - return result; - } - -// ===================================================== -// class StopCommandType -// ===================================================== - -//varios - StopCommandType::StopCommandType () - { - commandTypeClass = ccStop; - clicks = cOne; - stopSkillType = NULL; - } - - void StopCommandType::update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const - { - unitUpdater->updateStop (unit, frameIndex); - } - - string StopCommandType::getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const - { - string str; - Lang & lang = Lang::getInstance (); - - str = getName (translatedValue) + "\n"; - str += - lang.getString ("ReactionSpeed", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (stopSkillType->getSpeed ()) + "\n"; - if (stopSkillType->getEpCost () != 0) - str += - lang.getString ("EpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (stopSkillType->getEpCost ()) + "\n"; - if (stopSkillType->getHpCost () != 0) - str += - lang.getString ("HpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (stopSkillType->getHpCost ()) + "\n"; - str += stopSkillType->getBoostDesc (translatedValue); - return str; - } - - string StopCommandType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Stop"; - } - Lang & lang = Lang::getInstance (); - return lang.getString ("Stop"); - } - - void StopCommandType::load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - CommandType::load (id, n, dir, tt, ft, ut, loadedFileList, - parentLoader); - - //stop - string skillName = - n->getChild ("stop-skill")->getAttribute ("value")-> - getRestrictedValue (); - stopSkillType = - static_cast < - const StopSkillType *>(ut.getSkillType (skillName, scStop)); - } - - -// ===================================================== -// class MoveCommandType -// ===================================================== - -//varios - MoveCommandType::MoveCommandType () - { - commandTypeClass = ccMove; - clicks = cTwo; - moveSkillType = NULL; - } - - void MoveCommandType::update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const - { - unitUpdater->updateMove (unit, frameIndex); - } - - void MoveCommandType::load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - CommandType::load (id, n, dir, tt, ft, ut, loadedFileList, - parentLoader); - - //move - string skillName = - n->getChild ("move-skill")->getAttribute ("value")-> - getRestrictedValue (); - moveSkillType = - static_cast < - const MoveSkillType *>(ut.getSkillType (skillName, scMove)); - } - - string MoveCommandType::getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const - { - string str; - Lang & lang = Lang::getInstance (); - - str = getName (translatedValue) + "\n"; - str += - lang.getString ("WalkSpeed", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (moveSkillType->getSpeed ()); - if (totalUpgrade->getMoveSpeed (moveSkillType) != 0) - { - str += "+" + intToStr (totalUpgrade->getMoveSpeed (moveSkillType)); - } - str += "\n"; - if (moveSkillType->getEpCost () != 0) - { - str += - lang.getString ("EpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (moveSkillType->getEpCost ()) + "\n"; - } - if (moveSkillType->getHpCost () != 0) - { - str += - lang.getString ("HpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (moveSkillType->getHpCost ()) + "\n"; - } - str += moveSkillType->getBoostDesc (translatedValue); - return str; - } - - string MoveCommandType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Move"; - } - Lang & lang = Lang::getInstance (); - return lang.getString ("Move"); - } - -// ===================================================== -// class AttackCommandType -// ===================================================== - -//varios - AttackCommandType::AttackCommandType () - { - commandTypeClass = ccAttack; - clicks = cTwo; - moveSkillType = NULL; - attackSkillType = NULL; - } - - void AttackCommandType::update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const - { - unitUpdater->updateAttack (unit, frameIndex); - } - - void AttackCommandType::load (int id, const XmlNode * n, - const string & dir, const TechTree * tt, - const FactionType * ft, const UnitType & ut, - std::map < string, vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - CommandType::load (id, n, dir, tt, ft, ut, loadedFileList, - parentLoader); - - //move - string skillName = - n->getChild ("move-skill")->getAttribute ("value")-> - getRestrictedValue (); - moveSkillType = - static_cast < - const MoveSkillType *>(ut.getSkillType (skillName, scMove)); - - //attack - skillName = - n->getChild ("attack-skill")->getAttribute ("value")-> - getRestrictedValue (); - attackSkillType = - static_cast < - const AttackSkillType *>(ut.getSkillType (skillName, scAttack)); - } - - string AttackCommandType::getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const - { - string str; - Lang & lang = Lang::getInstance (); - - str = getName (translatedValue) + "\n"; - if (attackSkillType->getEpCost () != 0) - { - str += - lang.getString ("EpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (attackSkillType->getEpCost ()) + "\n"; - } - if (attackSkillType->getHpCost () != 0) - { - str += - lang.getString ("HpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (attackSkillType->getHpCost ()) + "\n"; - } - - //attack strength - str += - lang.getString ("AttackStrenght", - (translatedValue == true ? "" : "english")) + ": "; - str += - intToStr (attackSkillType->getAttackStrength () - - attackSkillType->getAttackVar ()); - str += "..."; - str += - intToStr (attackSkillType->getAttackStrength () + - attackSkillType->getAttackVar ()); - if (totalUpgrade->getAttackStrength (attackSkillType) != 0) - { - str += - "+" + intToStr (totalUpgrade->getAttackStrength (attackSkillType)); - } - str += - " (" + attackSkillType->getAttackType ()->getName (translatedValue) + - ")"; - str += "\n"; - - //splash radius - if (attackSkillType->getSplashRadius () != 0) - { - str += - lang.getString ("SplashRadius", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (attackSkillType->getSplashRadius ()) + "\n"; - } - - //attack distance - str += - lang.getString ("AttackDistance", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (attackSkillType->getAttackRange ()); - if (totalUpgrade->getAttackRange (attackSkillType) != 0) - { - str += - "+" + intToStr (totalUpgrade->getAttackRange (attackSkillType)); - } - str += "\n"; - - //attack fields - str += lang.getString ("Fields") + ": "; - for (int i = 0; i < fieldCount; i++) - { - Field field = static_cast < Field > (i); - if (attackSkillType->getAttackField (field)) - { - str += SkillType::fieldToStr (field) + " "; - } - } - str += "\n"; - - //movement speed - str += - lang.getString ("WalkSpeed", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (moveSkillType->getSpeed ()); - if (totalUpgrade->getMoveSpeed (moveSkillType) != 0) - { - str += "+" + intToStr (totalUpgrade->getMoveSpeed (moveSkillType)); - } - str += "\n"; - - //attack speed - str += - lang.getString ("AttackSpeed", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (attackSkillType->getSpeed ()) + "\n"; - if (totalUpgrade->getAttackSpeed (attackSkillType) != 0) - { - str += - "+" + intToStr (totalUpgrade->getAttackSpeed (attackSkillType)); - } - str += "\n"; - - str += attackSkillType->getBoostDesc (translatedValue); - return str; - } - - string AttackCommandType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Attack"; - } - Lang & lang = Lang::getInstance (); - return lang.getString ("Attack"); - } - - -// ===================================================== -// class AttackStoppedCommandType -// ===================================================== - -//varios - AttackStoppedCommandType::AttackStoppedCommandType () - { - commandTypeClass = ccAttackStopped; - clicks = cOne; - stopSkillType = NULL; - attackSkillType = NULL; - } - - void AttackStoppedCommandType::update (UnitUpdater * unitUpdater, - Unit * unit, int frameIndex) const - { - unitUpdater->updateAttackStopped (unit, frameIndex); - } - - void AttackStoppedCommandType::load (int id, const XmlNode * n, - const string & dir, - const TechTree * tt, - const FactionType * ft, - const UnitType & ut, - std::map < string, - vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - CommandType::load (id, n, dir, tt, ft, ut, loadedFileList, - parentLoader); - - //stop - string skillName = - n->getChild ("stop-skill")->getAttribute ("value")-> - getRestrictedValue (); - stopSkillType = - static_cast < - const StopSkillType *>(ut.getSkillType (skillName, scStop)); - - //attack - skillName = - n->getChild ("attack-skill")->getAttribute ("value")-> - getRestrictedValue (); - attackSkillType = - static_cast < - const AttackSkillType *>(ut.getSkillType (skillName, scAttack)); - } - - string AttackStoppedCommandType::getDesc (const TotalUpgrade * - totalUpgrade, - bool translatedValue) const - { - Lang & lang = Lang::getInstance (); - string str; - - str = getName (translatedValue) + "\n"; - if (attackSkillType->getEpCost () != 0) - { - str += - lang.getString ("EpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (attackSkillType->getEpCost ()) + "\n"; - } - if (attackSkillType->getHpCost () != 0) - { - str += - lang.getString ("HpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (attackSkillType->getHpCost ()) + "\n"; - } - - //attack strength - str += - lang.getString ("AttackStrenght", - (translatedValue == true ? "" : "english")) + ": "; - str += - intToStr (attackSkillType->getAttackStrength () - - attackSkillType->getAttackVar ()); - str += "..."; - str += - intToStr (attackSkillType->getAttackStrength () + - attackSkillType->getAttackVar ()); - if (totalUpgrade->getAttackStrength (attackSkillType) != 0) - str += - "+" + intToStr (totalUpgrade->getAttackStrength (attackSkillType)); - str += - " (" + attackSkillType->getAttackType ()->getName (translatedValue) + - ")"; - str += "\n"; - - //splash radius - if (attackSkillType->getSplashRadius () != 0) - { - str += - lang.getString ("SplashRadius", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (attackSkillType->getSplashRadius ()) + "\n"; - } - - //attack distance - str += - lang.getString ("AttackDistance", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (attackSkillType->getAttackRange ()); - if (totalUpgrade->getAttackRange (attackSkillType) != 0) - { - str += - "+" + intToStr (totalUpgrade->getAttackRange (attackSkillType) != - 0); - } - str += "\n"; - - //attack fields - str += - lang.getString ("Fields", - (translatedValue == true ? "" : "english")) + ": "; - for (int i = 0; i < fieldCount; i++) - { - Field field = static_cast < Field > (i); - if (attackSkillType->getAttackField (field)) - { - str += SkillType::fieldToStr (field) + " "; - } - } - str += "\n"; - str += attackSkillType->getBoostDesc (translatedValue); - return str; - } - - string AttackStoppedCommandType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "AttackStopped"; - } - Lang & lang = Lang::getInstance (); - return lang.getString ("AttackStopped"); - } - - -// ===================================================== -// class BuildCommandType -// ===================================================== - -//varios - BuildCommandType::BuildCommandType () - { - commandTypeClass = ccBuild; - clicks = cTwo; - moveSkillType = NULL; - buildSkillType = NULL; - } - - BuildCommandType::~BuildCommandType () - { - deleteValues (builtSounds.getSounds ().begin (), - builtSounds.getSounds ().end ()); - deleteValues (startSounds.getSounds ().begin (), - startSounds.getSounds ().end ()); - } - - void BuildCommandType::update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const - { - unitUpdater->updateBuild (unit, frameIndex); - } - - void BuildCommandType::load (int id, const XmlNode * n, - const string & dir, const TechTree * tt, - const FactionType * ft, const UnitType & ut, - std::map < string, vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - CommandType::load (id, n, dir, tt, ft, ut, loadedFileList, - parentLoader); - - //move - string skillName = - n->getChild ("move-skill")->getAttribute ("value")-> - getRestrictedValue (); - moveSkillType = - static_cast < - const MoveSkillType *>(ut.getSkillType (skillName, scMove)); - - //build - skillName = - n->getChild ("build-skill")->getAttribute ("value")-> - getRestrictedValue (); - buildSkillType = - static_cast < - const BuildSkillType *>(ut.getSkillType (skillName, scBuild)); - - //buildings built - const XmlNode *buildingsNode = n->getChild ("buildings"); - for (int i = 0; i < (int) buildingsNode->getChildCount (); ++i) - { - const XmlNode *buildingNode = buildingsNode->getChild ("building", i); - string name = - buildingNode->getAttribute ("name")->getRestrictedValue (); - buildings.push_back (ft->getUnitType (name)); - } - - //start sound - const XmlNode *startSoundNode = n->getChild ("start-sound"); - if (startSoundNode->getAttribute ("enabled")->getBoolValue ()) - { - startSounds.resize ((int) startSoundNode->getChildCount ()); - for (int i = 0; i < (int) startSoundNode->getChildCount (); ++i) - { - const XmlNode *soundFileNode = - startSoundNode->getChild ("sound-file", i); - string currentPath = dir; - endPathWithSlash (currentPath); - string path = - soundFileNode->getAttribute ("path")-> - getRestrictedValue (currentPath, true); - - StaticSound *sound = new StaticSound (); - - sound->load (path); - loadedFileList[path]. - push_back (make_pair - (parentLoader, - soundFileNode->getAttribute ("path")-> - getRestrictedValue ())); - startSounds[i] = sound; - } - } - - //built sound - const XmlNode *builtSoundNode = n->getChild ("built-sound"); - if (builtSoundNode->getAttribute ("enabled")->getBoolValue ()) - { - builtSounds.resize ((int) builtSoundNode->getChildCount ()); - for (int i = 0; i < (int) builtSoundNode->getChildCount (); ++i) - { - const XmlNode *soundFileNode = - builtSoundNode->getChild ("sound-file", i); - string currentPath = dir; - endPathWithSlash (currentPath); - string path = - soundFileNode->getAttribute ("path")-> - getRestrictedValue (currentPath, true); - - StaticSound *sound = new StaticSound (); - - sound->load (path); - loadedFileList[path]. - push_back (make_pair - (parentLoader, - soundFileNode->getAttribute ("path")-> - getRestrictedValue ())); - builtSounds[i] = sound; - } - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - string BuildCommandType::getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const - { - string str; - Lang & lang = Lang::getInstance (); - - str = getName (translatedValue) + "\n"; - str += - lang.getString ("BuildSpeed", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (buildSkillType->getSpeed ()) + "\n"; - if (buildSkillType->getEpCost () != 0) - { - str += - lang.getString ("EpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (buildSkillType->getEpCost ()) + "\n"; - } - if (buildSkillType->getHpCost () != 0) - { - str += - lang.getString ("HpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (buildSkillType->getHpCost ()) + "\n"; - } - str += buildSkillType->getBoostDesc (translatedValue); - return str; - } - - string BuildCommandType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Build"; - } - Lang & lang = Lang::getInstance (); - return lang.getString ("Build"); - } - -// ===================================================== -// class HarvestCommandType -// ===================================================== - -//varios - HarvestCommandType::HarvestCommandType () - { - commandTypeClass = ccHarvest; - clicks = cTwo; - moveSkillType = NULL; - moveLoadedSkillType = NULL; - harvestSkillType = NULL; - stopLoadedSkillType = NULL; - maxLoad = 0; - hitsPerUnit = 0; - } - - void HarvestCommandType::update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const - { - unitUpdater->updateHarvest (unit, frameIndex); - } - - void HarvestCommandType::load (int id, const XmlNode * n, - const string & dir, const TechTree * tt, - const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - CommandType::load (id, n, dir, tt, ft, ut, loadedFileList, - parentLoader); - - //move - string skillName = - n->getChild ("move-skill")->getAttribute ("value")-> - getRestrictedValue (); - moveSkillType = - static_cast < - const MoveSkillType *>(ut.getSkillType (skillName, scMove)); - - //harvest - skillName = - n->getChild ("harvest-skill")->getAttribute ("value")-> - getRestrictedValue (); - harvestSkillType = - static_cast < - const HarvestSkillType *>(ut.getSkillType (skillName, scHarvest)); - - //stop loaded - skillName = - n->getChild ("stop-loaded-skill")->getAttribute ("value")-> - getRestrictedValue (); - stopLoadedSkillType = - static_cast < - const StopSkillType *>(ut.getSkillType (skillName, scStop)); - - //move loaded - skillName = - n->getChild ("move-loaded-skill")->getAttribute ("value")-> - getRestrictedValue (); - moveLoadedSkillType = - static_cast < - const MoveSkillType *>(ut.getSkillType (skillName, scMove)); - - //resources can harvest - const XmlNode *resourcesNode = n->getChild ("harvested-resources"); - for (int i = 0; i < (int) resourcesNode->getChildCount (); ++i) - { - const XmlNode *resourceNode = resourcesNode->getChild ("resource", i); - harvestedResources.push_back (tt-> - getResourceType (resourceNode-> - getAttribute ("name")-> - getRestrictedValue - ())); - } - - maxLoad = - n->getChild ("max-load")->getAttribute ("value")->getIntValue (); - hitsPerUnit = - n->getChild ("hits-per-unit")->getAttribute ("value")->getIntValue (); - } - - string HarvestCommandType::getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const - { - - Lang & lang = Lang::getInstance (); - string str; - - str = getName (translatedValue) + "\n"; - str += - lang.getString ("HarvestSpeed", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (harvestSkillType->getSpeed () / hitsPerUnit) + "\n"; - str += - lang.getString ("MaxLoad", - (translatedValue == - true ? "" : "english")) + ": " + intToStr (maxLoad) + - "\n"; - str += - lang.getString ("LoadedSpeed", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (moveLoadedSkillType->getSpeed ()) + "\n"; - if (harvestSkillType->getEpCost () != 0) - { - str += - lang.getString ("EpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (harvestSkillType->getEpCost ()) + "\n"; - } - if (harvestSkillType->getHpCost () != 0) - { - str += - lang.getString ("HpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (harvestSkillType->getHpCost ()) + "\n"; - } - str += - lang.getString ("Resources", - (translatedValue == true ? "" : "english")) + ":\n"; - for (int i = 0; i < getHarvestedResourceCount (); ++i) - { - str += getHarvestedResource (i)->getName (translatedValue) + "\n"; - } - str += harvestSkillType->getBoostDesc (translatedValue); - return str; - } - - string HarvestCommandType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Harvest"; - } - Lang & lang = Lang::getInstance (); - return lang.getString ("Harvest"); - } - - bool HarvestCommandType::canHarvest (const ResourceType * resourceType) const - { - return find (harvestedResources.begin (), harvestedResources.end (), - resourceType) != harvestedResources.end (); - } - - -// ===================================================== -// class HarvestCommandType -// ===================================================== - -//varios - HarvestEmergencyReturnCommandType::HarvestEmergencyReturnCommandType () - { - commandTypeClass = ccHarvestEmergencyReturn; - clicks = cTwo; - - this->id = -10; - } - - void HarvestEmergencyReturnCommandType::update (UnitUpdater * unitUpdater, - Unit * unit, - int frameIndex) const - { - unitUpdater->updateHarvestEmergencyReturn (unit, frameIndex); - } - - void HarvestEmergencyReturnCommandType::load (int id, const XmlNode * n, - const string & dir, - const TechTree * tt, - const FactionType * ft, - const UnitType & ut, - std::map < string, - vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { -// CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, parentLoader); - } - - string HarvestEmergencyReturnCommandType::getDesc (const TotalUpgrade * - totalUpgrade, - bool translatedValue) - const - { - string str = getName (translatedValue) + "\n"; - return str; - } - - string HarvestEmergencyReturnCommandType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "HarvestEmergencyReturn"; - } - Lang & lang = Lang::getInstance (); - return lang.getString ("Harvest"); - } - -// ===================================================== -// class RepairCommandType -// ===================================================== - -//varios - RepairCommandType::RepairCommandType () - { - commandTypeClass = ccRepair; - clicks = cTwo; - moveSkillType = NULL; - repairSkillType = NULL; - } - - RepairCommandType::~RepairCommandType () - { - } - - void RepairCommandType::update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const - { - unitUpdater->updateRepair (unit, frameIndex); - } - - void RepairCommandType::load (int id, const XmlNode * n, - const string & dir, const TechTree * tt, - const FactionType * ft, const UnitType & ut, - std::map < string, vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - CommandType::load (id, n, dir, tt, ft, ut, loadedFileList, - parentLoader); - - // move skill (no longer required by means unit must already be beside unit to repair) - // for example a hospital - if (n->hasChild ("move-skill") == true) - { - string skillName = - n->getChild ("move-skill")->getAttribute ("value")-> - getRestrictedValue (); - moveSkillType = - static_cast < - const MoveSkillType *>(ut.getSkillType (skillName, scMove)); - } - - //repair - string skillName = - n->getChild ("repair-skill")->getAttribute ("value")-> - getRestrictedValue (); - repairSkillType = - static_cast < - const RepairSkillType *>(ut.getSkillType (skillName, scRepair)); - - //repaired units - const XmlNode *unitsNode = n->getChild ("repaired-units"); - for (int i = 0; i < (int) unitsNode->getChildCount (); ++i) - { - const XmlNode *unitNode = unitsNode->getChild ("unit", i); - repairableUnits.push_back (ft-> - getUnitType (unitNode-> - getAttribute ("name")-> - getRestrictedValue ())); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - string RepairCommandType::getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const - { - Lang & lang = Lang::getInstance (); - string str; - - str = getName (translatedValue) + "\n"; - str += - lang.getString ("RepairSpeed", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (repairSkillType->getSpeed ()) + "\n"; - if (repairSkillType->getEpCost () != 0) - { - str += - lang.getString ("EpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (repairSkillType->getEpCost ()) + "\n"; - } - if (repairSkillType->getHpCost () != 0) - { - str += - lang.getString ("HpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (repairSkillType->getHpCost ()) + "\n"; - } - str += - "\n" + lang.getString ("CanRepair", - (translatedValue == - true ? "" : "english")) + ":\n"; - for (int i = 0; i < (int) repairableUnits.size (); ++i) - { - str += - (static_cast < - const UnitType * - >(repairableUnits[i]))->getName (translatedValue) + "\n"; - } - str += repairSkillType->getBoostDesc (translatedValue); - return str; - } - - string RepairCommandType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Repair"; - } - Lang & lang = Lang::getInstance (); - return lang.getString ("Repair"); - } - -//get - bool RepairCommandType::isRepairableUnitType (const UnitType * unitType) const - { - for (int i = 0; i < (int) repairableUnits.size (); ++i) - { - const UnitType *curUnitType = - static_cast < const UnitType * >(repairableUnits[i]); - //printf("Lookup index = %d Can repair unittype [%s][%p] looking for [%s][%p] lookup found result = %d\n",i,curUnitType->getName().c_str(),curUnitType,unitType->getName().c_str(),unitType,(curUnitType == unitType)); - if (curUnitType == unitType) - { - return true; - } - } - return false; - } - -// ===================================================== -// class ProduceCommandType -// ===================================================== - -//varios - ProduceCommandType::ProduceCommandType () - { - commandTypeClass = ccProduce; - clicks = cOne; - produceSkillType = NULL; - producedUnit = NULL; - } - - void ProduceCommandType::update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const - { - unitUpdater->updateProduce (unit, frameIndex); - } - - void ProduceCommandType::load (int id, const XmlNode * n, - const string & dir, const TechTree * tt, - const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - CommandType::load (id, n, dir, tt, ft, ut, loadedFileList, - parentLoader); - - //produce - string skillName = - n->getChild ("produce-skill")->getAttribute ("value")-> - getRestrictedValue (); - produceSkillType = - static_cast < - const ProduceSkillType *>(ut.getSkillType (skillName, scProduce)); - - string producedUnitName = - n->getChild ("produced-unit")->getAttribute ("name")-> - getRestrictedValue (); - producedUnit = ft->getUnitType (producedUnitName); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - string ProduceCommandType::getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const - { - string str = getName (translatedValue) + "\n"; - Lang & lang = Lang::getInstance (); - - //prod speed - str += - lang.getString ("ProductionSpeed", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (produceSkillType->getSpeed ()); - if (totalUpgrade->getProdSpeed (produceSkillType) != 0) - { - str += "+" + intToStr (totalUpgrade->getProdSpeed (produceSkillType)); - } - str += "\n"; - str += - "" + Lang::getInstance ().getString ("TimeSteps", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (getProducedUnit ()->getProductionTime ()) + "\n"; - int64 speed = - produceSkillType->getSpeed () + - totalUpgrade->getProdSpeed (produceSkillType); - int64 time = getProducedUnit ()->getProductionTime (); - int64 seconds = time * 100 / speed; - str += - "" + Lang::getInstance ().getString ("Time", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (seconds); - str += "\n"; - - //mpcost - if (produceSkillType->getEpCost () != 0) - { - str += - lang.getString ("EpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (produceSkillType->getEpCost ()) + "\n"; - } - if (produceSkillType->getHpCost () != 0) - { - str += - lang.getString ("hpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (produceSkillType->getHpCost ()) + "\n"; - } - str += "\n" + getProducedUnit ()->getReqDesc (translatedValue); - str += produceSkillType->getBoostDesc (translatedValue); - return str; - } - - string ProduceCommandType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Produce"; - } - Lang & lang = Lang::getInstance (); - return lang.getString ("Produce"); - } - - string ProduceCommandType::getReqDesc (bool translatedValue) const - { - return RequirableType::getReqDesc (translatedValue) + "\n" + - getProducedUnit ()->getReqDesc (translatedValue); - } - - const ProducibleType *ProduceCommandType::getProduced () const - { - return producedUnit; - } - -// ===================================================== -// class UpgradeCommandType -// ===================================================== - -//varios - UpgradeCommandType::UpgradeCommandType () - { - commandTypeClass = ccUpgrade; - clicks = cOne; - upgradeSkillType = NULL; - producedUpgrade = NULL; - } - - void UpgradeCommandType::update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const - { - unitUpdater->updateUpgrade (unit, frameIndex); - } - - void UpgradeCommandType::load (int id, const XmlNode * n, - const string & dir, const TechTree * tt, - const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - - CommandType::load (id, n, dir, tt, ft, ut, loadedFileList, - parentLoader); - - //upgrade - string skillName = - n->getChild ("upgrade-skill")->getAttribute ("value")-> - getRestrictedValue (); - upgradeSkillType = - static_cast < - const UpgradeSkillType *>(ut.getSkillType (skillName, scUpgrade)); - - string producedUpgradeName = - n->getChild ("produced-upgrade")->getAttribute ("name")-> - getRestrictedValue (); - producedUpgrade = ft->getUpgradeType (producedUpgradeName); - - } - - string UpgradeCommandType::getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const - { - string str; - Lang & lang = Lang::getInstance (); - - str = getName (translatedValue) + "\n"; - str += - lang.getString ("UpgradeSpeed", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (upgradeSkillType->getSpeed ()); - if (totalUpgrade->getProdSpeed (upgradeSkillType) != 0) - { - str += "+" + intToStr (totalUpgrade->getProdSpeed (upgradeSkillType)); - } - str += "\n"; - str += - "" + Lang::getInstance ().getString ("TimeSteps", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (getProducedUpgrade ()->getProductionTime ()) + "\n"; - int64 speed = - upgradeSkillType->getSpeed () + - totalUpgrade->getProdSpeed (upgradeSkillType); - int64 time = getProducedUpgrade ()->getProductionTime (); - int64 seconds = time * 100 / speed; - str += - "" + Lang::getInstance ().getString ("Time", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (seconds); - str += "\n"; - - if (upgradeSkillType->getEpCost () != 0) - str += - lang.getString ("EpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (upgradeSkillType->getEpCost ()) + "\n"; - if (upgradeSkillType->getHpCost () != 0) - str += - lang.getString ("HpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (upgradeSkillType->getHpCost ()) + "\n"; - str += "\n" + getProducedUpgrade ()->getReqDesc (translatedValue); - str += upgradeSkillType->getBoostDesc (translatedValue); - return str; - } - - string UpgradeCommandType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Upgrade"; - } - Lang & lang = Lang::getInstance (); - return lang.getString ("Upgrade"); - } - - string UpgradeCommandType::getReqDesc (bool translatedValue) const - { - return RequirableType::getReqDesc (translatedValue) + "\n" + - getProducedUpgrade ()->getReqDesc (translatedValue); - } - - const ProducibleType *UpgradeCommandType::getProduced () const - { - return producedUpgrade; - } - -// ===================================================== -// class MorphCommandType -// ===================================================== - -//varios - MorphCommandType::MorphCommandType () - { - commandTypeClass = ccMorph; - clicks = cOne; - morphSkillType = NULL; - morphUnit = NULL; - discount = 0; - ignoreResourceRequirements = false; - } - - void MorphCommandType::update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const - { - unitUpdater->updateMorph (unit, frameIndex); - } - - void MorphCommandType::load (int id, const XmlNode * n, - const string & dir, const TechTree * tt, - const FactionType * ft, const UnitType & ut, - std::map < string, vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - CommandType::load (id, n, dir, tt, ft, ut, loadedFileList, - parentLoader); - - //morph skill - string skillName = - n->getChild ("morph-skill")->getAttribute ("value")-> - getRestrictedValue (); - morphSkillType = - static_cast < - const MorphSkillType *>(ut.getSkillType (skillName, scMorph)); - - //morph unit - string morphUnitName = - n->getChild ("morph-unit")->getAttribute ("name")-> - getRestrictedValue (); - morphUnit = ft->getUnitType (morphUnitName); - - //discount - discount = - n->getChild ("discount")->getAttribute ("value")->getIntValue (); - - ignoreResourceRequirements = false; - if (n->hasChild ("ignore-resource-requirements") == true) - { - ignoreResourceRequirements = - n->getChild ("ignore-resource-requirements")-> - getAttribute ("value")->getBoolValue (); - - //printf("ignoreResourceRequirements = %d\n",ignoreResourceRequirements); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - string MorphCommandType::getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const - { - string str = getName (translatedValue) + "\n"; - Lang & lang = Lang::getInstance (); - - //prod speed - str += - lang.getString ("MorphSpeed", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (morphSkillType->getSpeed ()); - if (totalUpgrade->getProdSpeed (morphSkillType) != 0) - { - str += "+" + intToStr (totalUpgrade->getProdSpeed (morphSkillType)); - } - str += "\n"; - str += - "" + Lang::getInstance ().getString ("TimeSteps", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (getMorphUnit ()->getProductionTime ()) + "\n"; - int64 speed = - morphSkillType->getSpeed () + - totalUpgrade->getProdSpeed (morphSkillType); - int64 time = getMorphUnit ()->getProductionTime (); - int64 seconds = time * 100 / speed; - str += - "" + Lang::getInstance ().getString ("Time", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (seconds); - str += "\n"; - - //mpcost - if (morphSkillType->getEpCost () != 0) - { - str += - lang.getString ("EpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (morphSkillType->getEpCost ()) + "\n"; - } - if (morphSkillType->getHpCost () != 0) - { - str += - lang.getString ("HpCost", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (morphSkillType->getHpCost ()) + "\n"; - } - - //discount - if (discount != 0) - { - str += - lang.getString ("Discount", - (translatedValue == - true ? "" : "english")) + ": " + - intToStr (discount) + "%\n"; - } - - str += - "\n" + getProduced ()->getReqDesc (ignoreResourceRequirements, - translatedValue); - - str += morphSkillType->getBoostDesc (translatedValue); - - return str; - } - - string MorphCommandType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Morph"; - } - Lang & lang = Lang::getInstance (); - return lang.getString ("Morph"); - } - - string MorphCommandType::getReqDesc (bool translatedValue) const - { - return RequirableType::getReqDesc (translatedValue) + "\n" + - getProduced ()->getReqDesc (translatedValue); - } - - const ProducibleType *MorphCommandType::getProduced () const - { - return morphUnit; - } - -// ===================================================== -// class SwitchTeamCommandType -// ===================================================== - -//varios - SwitchTeamCommandType::SwitchTeamCommandType () - { - commandTypeClass = ccSwitchTeam; - clicks = cOne; - } - - void SwitchTeamCommandType::update (UnitUpdater * unitUpdater, - Unit * unit, int frameIndex) const - { - unitUpdater->updateSwitchTeam (unit, frameIndex); - } - - void SwitchTeamCommandType::load (int id, const XmlNode * n, - const string & dir, const TechTree * tt, - const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - CommandType::load (id, n, dir, tt, ft, ut, loadedFileList, - parentLoader); - - //morph skill - //string skillName= n->getChild("morph-skill")->getAttribute("value")->getRestrictedValue(); - //morphSkillType= static_cast(ut.getSkillType(skillName, scMorph)); - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - string SwitchTeamCommandType::getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const - { - string str = getName (translatedValue) + "\n"; - return str; - } - - string SwitchTeamCommandType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "SwitchTeam"; - } - Lang & lang = Lang::getInstance (); - return lang.getString ("SwitchTeam"); - } - -// ===================================================== -// class CommandFactory -// ===================================================== - - CommandTypeFactory::CommandTypeFactory () - { - registerClass < StopCommandType > ("stop"); - registerClass < MoveCommandType > ("move"); - registerClass < AttackCommandType > ("attack"); - registerClass < AttackStoppedCommandType > ("attack_stopped"); - registerClass < BuildCommandType > ("build"); - registerClass < HarvestCommandType > ("harvest"); - registerClass < RepairCommandType > ("repair"); - registerClass < ProduceCommandType > ("produce"); - registerClass < UpgradeCommandType > ("upgrade"); - registerClass < MorphCommandType > ("morph"); - registerClass < SwitchTeamCommandType > ("switch_team"); - registerClass < HarvestEmergencyReturnCommandType > ("harvest_return"); - } - - CommandTypeFactory & CommandTypeFactory::getInstance () - { - static CommandTypeFactory ctf; - return ctf; - } - - } +namespace Glest { + namespace Game { + + + // ===================================================== + // class CommandType + // ===================================================== + + //get + CommandClass CommandType::getClass() const { + assert(this != NULL); + return commandTypeClass; + } + + void CommandType::load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, + string > > >&loadedFileList, string parentLoader) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + this->id = id; + name = + n->getChild("name")->getAttribute("value")->getRestrictedValue(); + + //image + const XmlNode *imageNode = n->getChild("image"); + image = Renderer::getInstance().newTexture2D(rsGame); + + string currentPath = dir; + endPathWithSlash(currentPath); + if (image) { + image->load(imageNode->getAttribute("path")-> + getRestrictedValue(currentPath)); + } + loadedFileList[imageNode->getAttribute("path")-> + getRestrictedValue(currentPath)]. + push_back(make_pair + (parentLoader, + imageNode->getAttribute("path")->getRestrictedValue())); + + //unit requirements + const XmlNode *unitRequirementsNode = n->getChild("unit-requirements"); + for (int i = 0; i < (int) unitRequirementsNode->getChildCount(); ++i) { + const XmlNode *unitNode = unitRequirementsNode->getChild("unit", i); + string name = unitNode->getAttribute("name")->getRestrictedValue(); + unitReqs.push_back(ft->getUnitType(name)); + } + + //upgrade requirements + const XmlNode *upgradeRequirementsNode = + n->getChild("upgrade-requirements"); + for (int i = 0; i < (int) upgradeRequirementsNode->getChildCount(); + ++i) { + const XmlNode *upgradeReqNode = + upgradeRequirementsNode->getChild("upgrade", i); + string name = + upgradeReqNode->getAttribute("name")->getRestrictedValue(); + upgradeReqs.push_back(ft->getUpgradeType(name)); + } + + //fog of war + if (n->hasChild("fog-of-war-skill") == true) { + string skillName = + n->getChild("fog-of-war-skill")->getAttribute("value")-> + getRestrictedValue(); + fogOfWarSkillType = + static_cast < + const FogOfWarSkillType *>(ut.getSkillType(skillName, scFogOfWar)); + + string skillAttachmentNames = + n->getChild("fog-of-war-skill")-> + getAttribute("skill-attachments")->getValue(); + + std::vector < std::string > skillList; + Tokenize(skillAttachmentNames, skillList, ","); + for (unsigned int i = 0; i < skillList.size(); ++i) { + string skillAttachName = skillList[i]; + fogOfWarSkillAttachments[skillAttachName] = true; + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + bool CommandType::hasFogOfWarSkillType(string name) const { + std::map < string, bool >::const_iterator iterFind = + fogOfWarSkillAttachments.find(name); + bool result = (iterFind != fogOfWarSkillAttachments.end()); + return result; + } + + // ===================================================== + // class StopCommandType + // ===================================================== + + //varios + StopCommandType::StopCommandType() { + commandTypeClass = ccStop; + clicks = cOne; + stopSkillType = NULL; + } + + void StopCommandType::update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const { + unitUpdater->updateStop(unit, frameIndex); + } + + string StopCommandType::getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const { + string str; + Lang & lang = Lang::getInstance(); + + str = getName(translatedValue) + "\n"; + str += + lang.getString("ReactionSpeed", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(stopSkillType->getSpeed()) + "\n"; + if (stopSkillType->getEpCost() != 0) + str += + lang.getString("EpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(stopSkillType->getEpCost()) + "\n"; + if (stopSkillType->getHpCost() != 0) + str += + lang.getString("HpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(stopSkillType->getHpCost()) + "\n"; + str += stopSkillType->getBoostDesc(translatedValue); + return str; + } + + string StopCommandType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Stop"; + } + Lang & lang = Lang::getInstance(); + return lang.getString("Stop"); + } + + void StopCommandType::load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, + parentLoader); + + //stop + string skillName = + n->getChild("stop-skill")->getAttribute("value")-> + getRestrictedValue(); + stopSkillType = + static_cast < + const StopSkillType *>(ut.getSkillType(skillName, scStop)); + } + + + // ===================================================== + // class MoveCommandType + // ===================================================== + + //varios + MoveCommandType::MoveCommandType() { + commandTypeClass = ccMove; + clicks = cTwo; + moveSkillType = NULL; + } + + void MoveCommandType::update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const { + unitUpdater->updateMove(unit, frameIndex); + } + + void MoveCommandType::load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, + parentLoader); + + //move + string skillName = + n->getChild("move-skill")->getAttribute("value")-> + getRestrictedValue(); + moveSkillType = + static_cast < + const MoveSkillType *>(ut.getSkillType(skillName, scMove)); + } + + string MoveCommandType::getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const { + string str; + Lang & lang = Lang::getInstance(); + + str = getName(translatedValue) + "\n"; + str += + lang.getString("WalkSpeed", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(moveSkillType->getSpeed()); + if (totalUpgrade->getMoveSpeed(moveSkillType) != 0) { + str += "+" + intToStr(totalUpgrade->getMoveSpeed(moveSkillType)); + } + str += "\n"; + if (moveSkillType->getEpCost() != 0) { + str += + lang.getString("EpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(moveSkillType->getEpCost()) + "\n"; + } + if (moveSkillType->getHpCost() != 0) { + str += + lang.getString("HpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(moveSkillType->getHpCost()) + "\n"; + } + str += moveSkillType->getBoostDesc(translatedValue); + return str; + } + + string MoveCommandType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Move"; + } + Lang & lang = Lang::getInstance(); + return lang.getString("Move"); + } + + // ===================================================== + // class AttackCommandType + // ===================================================== + + //varios + AttackCommandType::AttackCommandType() { + commandTypeClass = ccAttack; + clicks = cTwo; + moveSkillType = NULL; + attackSkillType = NULL; + } + + void AttackCommandType::update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const { + unitUpdater->updateAttack(unit, frameIndex); + } + + void AttackCommandType::load(int id, const XmlNode * n, + const string & dir, const TechTree * tt, + const FactionType * ft, const UnitType & ut, + std::map < string, vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, + parentLoader); + + //move + string skillName = + n->getChild("move-skill")->getAttribute("value")-> + getRestrictedValue(); + moveSkillType = + static_cast < + const MoveSkillType *>(ut.getSkillType(skillName, scMove)); + + //attack + skillName = + n->getChild("attack-skill")->getAttribute("value")-> + getRestrictedValue(); + attackSkillType = + static_cast < + const AttackSkillType *>(ut.getSkillType(skillName, scAttack)); + } + + string AttackCommandType::getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const { + string str; + Lang & lang = Lang::getInstance(); + + str = getName(translatedValue) + "\n"; + if (attackSkillType->getEpCost() != 0) { + str += + lang.getString("EpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(attackSkillType->getEpCost()) + "\n"; + } + if (attackSkillType->getHpCost() != 0) { + str += + lang.getString("HpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(attackSkillType->getHpCost()) + "\n"; + } + + //attack strength + str += + lang.getString("AttackStrenght", + (translatedValue == true ? "" : "english")) + ": "; + str += + intToStr(attackSkillType->getAttackStrength() - + attackSkillType->getAttackVar()); + str += "..."; + str += + intToStr(attackSkillType->getAttackStrength() + + attackSkillType->getAttackVar()); + if (totalUpgrade->getAttackStrength(attackSkillType) != 0) { + str += + "+" + intToStr(totalUpgrade->getAttackStrength(attackSkillType)); + } + str += + " (" + attackSkillType->getAttackType()->getName(translatedValue) + + ")"; + str += "\n"; + + //splash radius + if (attackSkillType->getSplashRadius() != 0) { + str += + lang.getString("SplashRadius", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(attackSkillType->getSplashRadius()) + "\n"; + } + + //attack distance + str += + lang.getString("AttackDistance", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(attackSkillType->getAttackRange()); + if (totalUpgrade->getAttackRange(attackSkillType) != 0) { + str += + "+" + intToStr(totalUpgrade->getAttackRange(attackSkillType)); + } + str += "\n"; + + //attack fields + str += lang.getString("Fields") + ": "; + for (int i = 0; i < fieldCount; i++) { + Field field = static_cast (i); + if (attackSkillType->getAttackField(field)) { + str += SkillType::fieldToStr(field) + " "; + } + } + str += "\n"; + + //movement speed + str += + lang.getString("WalkSpeed", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(moveSkillType->getSpeed()); + if (totalUpgrade->getMoveSpeed(moveSkillType) != 0) { + str += "+" + intToStr(totalUpgrade->getMoveSpeed(moveSkillType)); + } + str += "\n"; + + //attack speed + str += + lang.getString("AttackSpeed", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(attackSkillType->getSpeed()) + "\n"; + if (totalUpgrade->getAttackSpeed(attackSkillType) != 0) { + str += + "+" + intToStr(totalUpgrade->getAttackSpeed(attackSkillType)); + } + str += "\n"; + + str += attackSkillType->getBoostDesc(translatedValue); + return str; + } + + string AttackCommandType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Attack"; + } + Lang & lang = Lang::getInstance(); + return lang.getString("Attack"); + } + + + // ===================================================== + // class AttackStoppedCommandType + // ===================================================== + + //varios + AttackStoppedCommandType::AttackStoppedCommandType() { + commandTypeClass = ccAttackStopped; + clicks = cOne; + stopSkillType = NULL; + attackSkillType = NULL; + } + + void AttackStoppedCommandType::update(UnitUpdater * unitUpdater, + Unit * unit, int frameIndex) const { + unitUpdater->updateAttackStopped(unit, frameIndex); + } + + void AttackStoppedCommandType::load(int id, const XmlNode * n, + const string & dir, + const TechTree * tt, + const FactionType * ft, + const UnitType & ut, + std::map < string, + vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, + parentLoader); + + //stop + string skillName = + n->getChild("stop-skill")->getAttribute("value")-> + getRestrictedValue(); + stopSkillType = + static_cast < + const StopSkillType *>(ut.getSkillType(skillName, scStop)); + + //attack + skillName = + n->getChild("attack-skill")->getAttribute("value")-> + getRestrictedValue(); + attackSkillType = + static_cast < + const AttackSkillType *>(ut.getSkillType(skillName, scAttack)); + } + + string AttackStoppedCommandType::getDesc(const TotalUpgrade * + totalUpgrade, + bool translatedValue) const { + Lang & lang = Lang::getInstance(); + string str; + + str = getName(translatedValue) + "\n"; + if (attackSkillType->getEpCost() != 0) { + str += + lang.getString("EpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(attackSkillType->getEpCost()) + "\n"; + } + if (attackSkillType->getHpCost() != 0) { + str += + lang.getString("HpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(attackSkillType->getHpCost()) + "\n"; + } + + //attack strength + str += + lang.getString("AttackStrenght", + (translatedValue == true ? "" : "english")) + ": "; + str += + intToStr(attackSkillType->getAttackStrength() - + attackSkillType->getAttackVar()); + str += "..."; + str += + intToStr(attackSkillType->getAttackStrength() + + attackSkillType->getAttackVar()); + if (totalUpgrade->getAttackStrength(attackSkillType) != 0) + str += + "+" + intToStr(totalUpgrade->getAttackStrength(attackSkillType)); + str += + " (" + attackSkillType->getAttackType()->getName(translatedValue) + + ")"; + str += "\n"; + + //splash radius + if (attackSkillType->getSplashRadius() != 0) { + str += + lang.getString("SplashRadius", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(attackSkillType->getSplashRadius()) + "\n"; + } + + //attack distance + str += + lang.getString("AttackDistance", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(attackSkillType->getAttackRange()); + if (totalUpgrade->getAttackRange(attackSkillType) != 0) { + str += + "+" + intToStr(totalUpgrade->getAttackRange(attackSkillType) != + 0); + } + str += "\n"; + + //attack fields + str += + lang.getString("Fields", + (translatedValue == true ? "" : "english")) + ": "; + for (int i = 0; i < fieldCount; i++) { + Field field = static_cast (i); + if (attackSkillType->getAttackField(field)) { + str += SkillType::fieldToStr(field) + " "; + } + } + str += "\n"; + str += attackSkillType->getBoostDesc(translatedValue); + return str; + } + + string AttackStoppedCommandType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "AttackStopped"; + } + Lang & lang = Lang::getInstance(); + return lang.getString("AttackStopped"); + } + + + // ===================================================== + // class BuildCommandType + // ===================================================== + + //varios + BuildCommandType::BuildCommandType() { + commandTypeClass = ccBuild; + clicks = cTwo; + moveSkillType = NULL; + buildSkillType = NULL; + } + + BuildCommandType::~BuildCommandType() { + deleteValues(builtSounds.getSounds().begin(), + builtSounds.getSounds().end()); + deleteValues(startSounds.getSounds().begin(), + startSounds.getSounds().end()); + } + + void BuildCommandType::update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const { + unitUpdater->updateBuild(unit, frameIndex); + } + + void BuildCommandType::load(int id, const XmlNode * n, + const string & dir, const TechTree * tt, + const FactionType * ft, const UnitType & ut, + std::map < string, vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, + parentLoader); + + //move + string skillName = + n->getChild("move-skill")->getAttribute("value")-> + getRestrictedValue(); + moveSkillType = + static_cast < + const MoveSkillType *>(ut.getSkillType(skillName, scMove)); + + //build + skillName = + n->getChild("build-skill")->getAttribute("value")-> + getRestrictedValue(); + buildSkillType = + static_cast < + const BuildSkillType *>(ut.getSkillType(skillName, scBuild)); + + //buildings built + const XmlNode *buildingsNode = n->getChild("buildings"); + for (int i = 0; i < (int) buildingsNode->getChildCount(); ++i) { + const XmlNode *buildingNode = buildingsNode->getChild("building", i); + string name = + buildingNode->getAttribute("name")->getRestrictedValue(); + buildings.push_back(ft->getUnitType(name)); + } + + //start sound + const XmlNode *startSoundNode = n->getChild("start-sound"); + if (startSoundNode->getAttribute("enabled")->getBoolValue()) { + startSounds.resize((int) startSoundNode->getChildCount()); + for (int i = 0; i < (int) startSoundNode->getChildCount(); ++i) { + const XmlNode *soundFileNode = + startSoundNode->getChild("sound-file", i); + string currentPath = dir; + endPathWithSlash(currentPath); + string path = + soundFileNode->getAttribute("path")-> + getRestrictedValue(currentPath, true); + + StaticSound *sound = new StaticSound(); + + sound->load(path); + loadedFileList[path]. + push_back(make_pair + (parentLoader, + soundFileNode->getAttribute("path")-> + getRestrictedValue())); + startSounds[i] = sound; + } + } + + //built sound + const XmlNode *builtSoundNode = n->getChild("built-sound"); + if (builtSoundNode->getAttribute("enabled")->getBoolValue()) { + builtSounds.resize((int) builtSoundNode->getChildCount()); + for (int i = 0; i < (int) builtSoundNode->getChildCount(); ++i) { + const XmlNode *soundFileNode = + builtSoundNode->getChild("sound-file", i); + string currentPath = dir; + endPathWithSlash(currentPath); + string path = + soundFileNode->getAttribute("path")-> + getRestrictedValue(currentPath, true); + + StaticSound *sound = new StaticSound(); + + sound->load(path); + loadedFileList[path]. + push_back(make_pair + (parentLoader, + soundFileNode->getAttribute("path")-> + getRestrictedValue())); + builtSounds[i] = sound; + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + string BuildCommandType::getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const { + string str; + Lang & lang = Lang::getInstance(); + + str = getName(translatedValue) + "\n"; + str += + lang.getString("BuildSpeed", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(buildSkillType->getSpeed()) + "\n"; + if (buildSkillType->getEpCost() != 0) { + str += + lang.getString("EpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(buildSkillType->getEpCost()) + "\n"; + } + if (buildSkillType->getHpCost() != 0) { + str += + lang.getString("HpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(buildSkillType->getHpCost()) + "\n"; + } + str += buildSkillType->getBoostDesc(translatedValue); + return str; + } + + string BuildCommandType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Build"; + } + Lang & lang = Lang::getInstance(); + return lang.getString("Build"); + } + + // ===================================================== + // class HarvestCommandType + // ===================================================== + + //varios + HarvestCommandType::HarvestCommandType() { + commandTypeClass = ccHarvest; + clicks = cTwo; + moveSkillType = NULL; + moveLoadedSkillType = NULL; + harvestSkillType = NULL; + stopLoadedSkillType = NULL; + maxLoad = 0; + hitsPerUnit = 0; + } + + void HarvestCommandType::update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const { + unitUpdater->updateHarvest(unit, frameIndex); + } + + void HarvestCommandType::load(int id, const XmlNode * n, + const string & dir, const TechTree * tt, + const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, + parentLoader); + + //move + string skillName = + n->getChild("move-skill")->getAttribute("value")-> + getRestrictedValue(); + moveSkillType = + static_cast < + const MoveSkillType *>(ut.getSkillType(skillName, scMove)); + + //harvest + skillName = + n->getChild("harvest-skill")->getAttribute("value")-> + getRestrictedValue(); + harvestSkillType = + static_cast < + const HarvestSkillType *>(ut.getSkillType(skillName, scHarvest)); + + //stop loaded + skillName = + n->getChild("stop-loaded-skill")->getAttribute("value")-> + getRestrictedValue(); + stopLoadedSkillType = + static_cast < + const StopSkillType *>(ut.getSkillType(skillName, scStop)); + + //move loaded + skillName = + n->getChild("move-loaded-skill")->getAttribute("value")-> + getRestrictedValue(); + moveLoadedSkillType = + static_cast < + const MoveSkillType *>(ut.getSkillType(skillName, scMove)); + + //resources can harvest + const XmlNode *resourcesNode = n->getChild("harvested-resources"); + for (int i = 0; i < (int) resourcesNode->getChildCount(); ++i) { + const XmlNode *resourceNode = resourcesNode->getChild("resource", i); + harvestedResources.push_back(tt-> + getResourceType(resourceNode-> + getAttribute("name")-> + getRestrictedValue + ())); + } + + maxLoad = + n->getChild("max-load")->getAttribute("value")->getIntValue(); + hitsPerUnit = + n->getChild("hits-per-unit")->getAttribute("value")->getIntValue(); + } + + string HarvestCommandType::getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const { + + Lang & lang = Lang::getInstance(); + string str; + + str = getName(translatedValue) + "\n"; + str += + lang.getString("HarvestSpeed", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(harvestSkillType->getSpeed() / hitsPerUnit) + "\n"; + str += + lang.getString("MaxLoad", + (translatedValue == + true ? "" : "english")) + ": " + intToStr(maxLoad) + + "\n"; + str += + lang.getString("LoadedSpeed", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(moveLoadedSkillType->getSpeed()) + "\n"; + if (harvestSkillType->getEpCost() != 0) { + str += + lang.getString("EpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(harvestSkillType->getEpCost()) + "\n"; + } + if (harvestSkillType->getHpCost() != 0) { + str += + lang.getString("HpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(harvestSkillType->getHpCost()) + "\n"; + } + str += + lang.getString("Resources", + (translatedValue == true ? "" : "english")) + ":\n"; + for (int i = 0; i < getHarvestedResourceCount(); ++i) { + str += getHarvestedResource(i)->getName(translatedValue) + "\n"; + } + str += harvestSkillType->getBoostDesc(translatedValue); + return str; + } + + string HarvestCommandType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Harvest"; + } + Lang & lang = Lang::getInstance(); + return lang.getString("Harvest"); + } + + bool HarvestCommandType::canHarvest(const ResourceType * resourceType) const { + return find(harvestedResources.begin(), harvestedResources.end(), + resourceType) != harvestedResources.end(); + } + + + // ===================================================== + // class HarvestCommandType + // ===================================================== + + //varios + HarvestEmergencyReturnCommandType::HarvestEmergencyReturnCommandType() { + commandTypeClass = ccHarvestEmergencyReturn; + clicks = cTwo; + + this->id = -10; + } + + void HarvestEmergencyReturnCommandType::update(UnitUpdater * unitUpdater, + Unit * unit, + int frameIndex) const { + unitUpdater->updateHarvestEmergencyReturn(unit, frameIndex); + } + + void HarvestEmergencyReturnCommandType::load(int id, const XmlNode * n, + const string & dir, + const TechTree * tt, + const FactionType * ft, + const UnitType & ut, + std::map < string, + vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + // CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, parentLoader); + } + + string HarvestEmergencyReturnCommandType::getDesc(const TotalUpgrade * + totalUpgrade, + bool translatedValue) + const { + string str = getName(translatedValue) + "\n"; + return str; + } + + string HarvestEmergencyReturnCommandType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "HarvestEmergencyReturn"; + } + Lang & lang = Lang::getInstance(); + return lang.getString("Harvest"); + } + + // ===================================================== + // class RepairCommandType + // ===================================================== + + //varios + RepairCommandType::RepairCommandType() { + commandTypeClass = ccRepair; + clicks = cTwo; + moveSkillType = NULL; + repairSkillType = NULL; + } + + RepairCommandType::~RepairCommandType() { + } + + void RepairCommandType::update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const { + unitUpdater->updateRepair(unit, frameIndex); + } + + void RepairCommandType::load(int id, const XmlNode * n, + const string & dir, const TechTree * tt, + const FactionType * ft, const UnitType & ut, + std::map < string, vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, + parentLoader); + + // move skill (no longer required by means unit must already be beside unit to repair) + // for example a hospital + if (n->hasChild("move-skill") == true) { + string skillName = + n->getChild("move-skill")->getAttribute("value")-> + getRestrictedValue(); + moveSkillType = + static_cast < + const MoveSkillType *>(ut.getSkillType(skillName, scMove)); + } + + //repair + string skillName = + n->getChild("repair-skill")->getAttribute("value")-> + getRestrictedValue(); + repairSkillType = + static_cast < + const RepairSkillType *>(ut.getSkillType(skillName, scRepair)); + + //repaired units + const XmlNode *unitsNode = n->getChild("repaired-units"); + for (int i = 0; i < (int) unitsNode->getChildCount(); ++i) { + const XmlNode *unitNode = unitsNode->getChild("unit", i); + repairableUnits.push_back(ft-> + getUnitType(unitNode-> + getAttribute("name")-> + getRestrictedValue())); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + string RepairCommandType::getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const { + Lang & lang = Lang::getInstance(); + string str; + + str = getName(translatedValue) + "\n"; + str += + lang.getString("RepairSpeed", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(repairSkillType->getSpeed()) + "\n"; + if (repairSkillType->getEpCost() != 0) { + str += + lang.getString("EpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(repairSkillType->getEpCost()) + "\n"; + } + if (repairSkillType->getHpCost() != 0) { + str += + lang.getString("HpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(repairSkillType->getHpCost()) + "\n"; + } + str += + "\n" + lang.getString("CanRepair", + (translatedValue == + true ? "" : "english")) + ":\n"; + for (int i = 0; i < (int) repairableUnits.size(); ++i) { + str += + (static_cast < + const UnitType * + >(repairableUnits[i]))->getName(translatedValue) + "\n"; + } + str += repairSkillType->getBoostDesc(translatedValue); + return str; + } + + string RepairCommandType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Repair"; + } + Lang & lang = Lang::getInstance(); + return lang.getString("Repair"); + } + + //get + bool RepairCommandType::isRepairableUnitType(const UnitType * unitType) const { + for (int i = 0; i < (int) repairableUnits.size(); ++i) { + const UnitType *curUnitType = + static_cast (repairableUnits[i]); + //printf("Lookup index = %d Can repair unittype [%s][%p] looking for [%s][%p] lookup found result = %d\n",i,curUnitType->getName().c_str(),curUnitType,unitType->getName().c_str(),unitType,(curUnitType == unitType)); + if (curUnitType == unitType) { + return true; + } + } + return false; + } + + // ===================================================== + // class ProduceCommandType + // ===================================================== + + //varios + ProduceCommandType::ProduceCommandType() { + commandTypeClass = ccProduce; + clicks = cOne; + produceSkillType = NULL; + producedUnit = NULL; + } + + void ProduceCommandType::update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const { + unitUpdater->updateProduce(unit, frameIndex); + } + + void ProduceCommandType::load(int id, const XmlNode * n, + const string & dir, const TechTree * tt, + const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, + parentLoader); + + //produce + string skillName = + n->getChild("produce-skill")->getAttribute("value")-> + getRestrictedValue(); + produceSkillType = + static_cast < + const ProduceSkillType *>(ut.getSkillType(skillName, scProduce)); + + string producedUnitName = + n->getChild("produced-unit")->getAttribute("name")-> + getRestrictedValue(); + producedUnit = ft->getUnitType(producedUnitName); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + string ProduceCommandType::getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const { + string str = getName(translatedValue) + "\n"; + Lang & lang = Lang::getInstance(); + + //prod speed + str += + lang.getString("ProductionSpeed", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(produceSkillType->getSpeed()); + if (totalUpgrade->getProdSpeed(produceSkillType) != 0) { + str += "+" + intToStr(totalUpgrade->getProdSpeed(produceSkillType)); + } + str += "\n"; + str += + "" + Lang::getInstance().getString("TimeSteps", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(getProducedUnit()->getProductionTime()) + "\n"; + int64 speed = + produceSkillType->getSpeed() + + totalUpgrade->getProdSpeed(produceSkillType); + int64 time = getProducedUnit()->getProductionTime(); + int64 seconds = time * 100 / speed; + str += + "" + Lang::getInstance().getString("Time", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(seconds); + str += "\n"; + + //mpcost + if (produceSkillType->getEpCost() != 0) { + str += + lang.getString("EpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(produceSkillType->getEpCost()) + "\n"; + } + if (produceSkillType->getHpCost() != 0) { + str += + lang.getString("hpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(produceSkillType->getHpCost()) + "\n"; + } + str += "\n" + getProducedUnit()->getReqDesc(translatedValue); + str += produceSkillType->getBoostDesc(translatedValue); + return str; + } + + string ProduceCommandType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Produce"; + } + Lang & lang = Lang::getInstance(); + return lang.getString("Produce"); + } + + string ProduceCommandType::getReqDesc(bool translatedValue) const { + return RequirableType::getReqDesc(translatedValue) + "\n" + + getProducedUnit()->getReqDesc(translatedValue); + } + + const ProducibleType *ProduceCommandType::getProduced() const { + return producedUnit; + } + + // ===================================================== + // class UpgradeCommandType + // ===================================================== + + //varios + UpgradeCommandType::UpgradeCommandType() { + commandTypeClass = ccUpgrade; + clicks = cOne; + upgradeSkillType = NULL; + producedUpgrade = NULL; + } + + void UpgradeCommandType::update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const { + unitUpdater->updateUpgrade(unit, frameIndex); + } + + void UpgradeCommandType::load(int id, const XmlNode * n, + const string & dir, const TechTree * tt, + const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + + CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, + parentLoader); + + //upgrade + string skillName = + n->getChild("upgrade-skill")->getAttribute("value")-> + getRestrictedValue(); + upgradeSkillType = + static_cast < + const UpgradeSkillType *>(ut.getSkillType(skillName, scUpgrade)); + + string producedUpgradeName = + n->getChild("produced-upgrade")->getAttribute("name")-> + getRestrictedValue(); + producedUpgrade = ft->getUpgradeType(producedUpgradeName); + + } + + string UpgradeCommandType::getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const { + string str; + Lang & lang = Lang::getInstance(); + + str = getName(translatedValue) + "\n"; + str += + lang.getString("UpgradeSpeed", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(upgradeSkillType->getSpeed()); + if (totalUpgrade->getProdSpeed(upgradeSkillType) != 0) { + str += "+" + intToStr(totalUpgrade->getProdSpeed(upgradeSkillType)); + } + str += "\n"; + str += + "" + Lang::getInstance().getString("TimeSteps", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(getProducedUpgrade()->getProductionTime()) + "\n"; + int64 speed = + upgradeSkillType->getSpeed() + + totalUpgrade->getProdSpeed(upgradeSkillType); + int64 time = getProducedUpgrade()->getProductionTime(); + int64 seconds = time * 100 / speed; + str += + "" + Lang::getInstance().getString("Time", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(seconds); + str += "\n"; + + if (upgradeSkillType->getEpCost() != 0) + str += + lang.getString("EpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(upgradeSkillType->getEpCost()) + "\n"; + if (upgradeSkillType->getHpCost() != 0) + str += + lang.getString("HpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(upgradeSkillType->getHpCost()) + "\n"; + str += "\n" + getProducedUpgrade()->getReqDesc(translatedValue); + str += upgradeSkillType->getBoostDesc(translatedValue); + return str; + } + + string UpgradeCommandType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Upgrade"; + } + Lang & lang = Lang::getInstance(); + return lang.getString("Upgrade"); + } + + string UpgradeCommandType::getReqDesc(bool translatedValue) const { + return RequirableType::getReqDesc(translatedValue) + "\n" + + getProducedUpgrade()->getReqDesc(translatedValue); + } + + const ProducibleType *UpgradeCommandType::getProduced() const { + return producedUpgrade; + } + + // ===================================================== + // class MorphCommandType + // ===================================================== + + //varios + MorphCommandType::MorphCommandType() { + commandTypeClass = ccMorph; + clicks = cOne; + morphSkillType = NULL; + morphUnit = NULL; + discount = 0; + ignoreResourceRequirements = false; + } + + void MorphCommandType::update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const { + unitUpdater->updateMorph(unit, frameIndex); + } + + void MorphCommandType::load(int id, const XmlNode * n, + const string & dir, const TechTree * tt, + const FactionType * ft, const UnitType & ut, + std::map < string, vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, + parentLoader); + + //morph skill + string skillName = + n->getChild("morph-skill")->getAttribute("value")-> + getRestrictedValue(); + morphSkillType = + static_cast < + const MorphSkillType *>(ut.getSkillType(skillName, scMorph)); + + //morph unit + string morphUnitName = + n->getChild("morph-unit")->getAttribute("name")-> + getRestrictedValue(); + morphUnit = ft->getUnitType(morphUnitName); + + //discount + discount = + n->getChild("discount")->getAttribute("value")->getIntValue(); + + ignoreResourceRequirements = false; + if (n->hasChild("ignore-resource-requirements") == true) { + ignoreResourceRequirements = + n->getChild("ignore-resource-requirements")-> + getAttribute("value")->getBoolValue(); + + //printf("ignoreResourceRequirements = %d\n",ignoreResourceRequirements); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + string MorphCommandType::getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const { + string str = getName(translatedValue) + "\n"; + Lang & lang = Lang::getInstance(); + + //prod speed + str += + lang.getString("MorphSpeed", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(morphSkillType->getSpeed()); + if (totalUpgrade->getProdSpeed(morphSkillType) != 0) { + str += "+" + intToStr(totalUpgrade->getProdSpeed(morphSkillType)); + } + str += "\n"; + str += + "" + Lang::getInstance().getString("TimeSteps", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(getMorphUnit()->getProductionTime()) + "\n"; + int64 speed = + morphSkillType->getSpeed() + + totalUpgrade->getProdSpeed(morphSkillType); + int64 time = getMorphUnit()->getProductionTime(); + int64 seconds = time * 100 / speed; + str += + "" + Lang::getInstance().getString("Time", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(seconds); + str += "\n"; + + //mpcost + if (morphSkillType->getEpCost() != 0) { + str += + lang.getString("EpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(morphSkillType->getEpCost()) + "\n"; + } + if (morphSkillType->getHpCost() != 0) { + str += + lang.getString("HpCost", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(morphSkillType->getHpCost()) + "\n"; + } + + //discount + if (discount != 0) { + str += + lang.getString("Discount", + (translatedValue == + true ? "" : "english")) + ": " + + intToStr(discount) + "%\n"; + } + + str += + "\n" + getProduced()->getReqDesc(ignoreResourceRequirements, + translatedValue); + + str += morphSkillType->getBoostDesc(translatedValue); + + return str; + } + + string MorphCommandType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Morph"; + } + Lang & lang = Lang::getInstance(); + return lang.getString("Morph"); + } + + string MorphCommandType::getReqDesc(bool translatedValue) const { + return RequirableType::getReqDesc(translatedValue) + "\n" + + getProduced()->getReqDesc(translatedValue); + } + + const ProducibleType *MorphCommandType::getProduced() const { + return morphUnit; + } + + // ===================================================== + // class SwitchTeamCommandType + // ===================================================== + + //varios + SwitchTeamCommandType::SwitchTeamCommandType() { + commandTypeClass = ccSwitchTeam; + clicks = cOne; + } + + void SwitchTeamCommandType::update(UnitUpdater * unitUpdater, + Unit * unit, int frameIndex) const { + unitUpdater->updateSwitchTeam(unit, frameIndex); + } + + void SwitchTeamCommandType::load(int id, const XmlNode * n, + const string & dir, const TechTree * tt, + const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, + parentLoader); + + //morph skill + //string skillName= n->getChild("morph-skill")->getAttribute("value")->getRestrictedValue(); + //morphSkillType= static_cast(ut.getSkillType(skillName, scMorph)); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + string SwitchTeamCommandType::getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const { + string str = getName(translatedValue) + "\n"; + return str; + } + + string SwitchTeamCommandType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "SwitchTeam"; + } + Lang & lang = Lang::getInstance(); + return lang.getString("SwitchTeam"); + } + + // ===================================================== + // class CommandFactory + // ===================================================== + + CommandTypeFactory::CommandTypeFactory() { + registerClass < StopCommandType >("stop"); + registerClass < MoveCommandType >("move"); + registerClass < AttackCommandType >("attack"); + registerClass < AttackStoppedCommandType >("attack_stopped"); + registerClass < BuildCommandType >("build"); + registerClass < HarvestCommandType >("harvest"); + registerClass < RepairCommandType >("repair"); + registerClass < ProduceCommandType >("produce"); + registerClass < UpgradeCommandType >("upgrade"); + registerClass < MorphCommandType >("morph"); + registerClass < SwitchTeamCommandType >("switch_team"); + registerClass < HarvestEmergencyReturnCommandType >("harvest_return"); + } + + CommandTypeFactory & CommandTypeFactory::getInstance() { + static CommandTypeFactory ctf; + return ctf; + } + + } } //end namespace diff --git a/source/glest_game/types/command_type.h b/source/glest_game/types/command_type.h index b5f12e6e5..84d606400 100644 --- a/source/glest_game/types/command_type.h +++ b/source/glest_game/types/command_type.h @@ -26,705 +26,625 @@ # include "sound_container.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { - - using Shared::Util::MultiFactory; - - class UnitUpdater; - class Unit; - class UnitType; - class TechTree; - class FactionType; - - enum CommandClass - { - ccStop, - ccMove, - ccAttack, - ccAttackStopped, - ccBuild, - ccHarvest, - ccRepair, - ccProduce, - ccUpgrade, - ccMorph, - ccSwitchTeam, - ccHarvestEmergencyReturn, - - ccCount, - ccNull - }; - - enum Clicks - { - cOne, - cTwo - }; - - enum Queueability - { - qNever, - qOnRequest, - qOnlyLast, - qAlways - }; - -// ===================================================== -// class CommandType -// -/// A complex action performed by a unit, composed by skills -// ===================================================== - - class CommandType:public RequirableType - { - protected: - Clicks clicks; - int id; - - std::map < string, bool > fogOfWarSkillAttachments; - const FogOfWarSkillType *fogOfWarSkillType; - - public: - static const int invalidId = -1; - CommandClass commandTypeClass; - - public: - CommandType () - { - commandTypeClass = ccNull; - clicks = cOne; - id = -1; - fogOfWarSkillType = NULL; - fogOfWarSkillAttachments.clear (); - } - virtual void update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const = 0; - virtual void load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const = 0; - virtual string toString (bool translatedValue) const = 0; - virtual const ProducibleType *getProduced () const - { - return NULL; - } - virtual Queueability isQueuable () const - { - return qOnRequest; - } - bool isQueuable (bool tryQueue) const - { - Queueability q = isQueuable (); - return (q == qAlways) || ((q == qOnRequest || q == qOnlyLast) - && tryQueue); - } - bool isQueueAppendable () const - { - Queueability q = isQueuable (); - return (q != qNever) && (q != qOnlyLast); - } - //Priority: commands of higher priority will cancel commands of lower priority - virtual int getTypePriority () const - { - return 10; - } - virtual bool usesPathfinder () const = 0; - - //get - CommandClass getClass () const; - Clicks getClicks () const - { - return clicks; - } - int getId () const - { - return id; - } - - const FogOfWarSkillType *getFogOfWarSkillType () const - { - return fogOfWarSkillType; - }; - - bool hasFogOfWarSkillType (string name) const; - }; - -// =============================== -// class StopCommandType -// =============================== - - class StopCommandType:public CommandType - { - private: - const StopSkillType *stopSkillType; - - public: - StopCommandType (); - virtual void update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const; - virtual void load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const; - virtual string toString (bool translatedValue) const; - virtual Queueability isQueuable () const - { - return qNever; - } - virtual int getTypePriority () const - { - return 100000; - } - //get - const StopSkillType *getStopSkillType () const - { - return stopSkillType; - }; - - virtual bool usesPathfinder () const - { - return false; - } - }; - - -// =============================== -// class MoveCommandType -// =============================== - - class MoveCommandType:public CommandType - { - private: - const MoveSkillType *moveSkillType; - - public: - MoveCommandType (); - virtual void update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const; - virtual void load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const; - virtual string toString (bool translatedValue) const; - - //get - const MoveSkillType *getMoveSkillType () const - { - return moveSkillType; - }; - - virtual bool usesPathfinder () const - { - return true; - } - }; - - -// =============================== -// class AttackCommandType -// =============================== - - class AttackCommandType:public CommandType - { - private: - const MoveSkillType *moveSkillType; - const AttackSkillType *attackSkillType; - - public: - AttackCommandType (); - virtual void update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const; - virtual void load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const; - virtual string toString (bool translatedValue) const; - - - //get - const MoveSkillType *getMoveSkillType () const - { - return moveSkillType; - } - const AttackSkillType *getAttackSkillType () const - { - return attackSkillType; - } - - virtual bool usesPathfinder () const - { - return true; - } - }; - -// ======================================= -// class AttackStoppedCommandType -// ======================================= - - class AttackStoppedCommandType:public CommandType - { - private: - const StopSkillType *stopSkillType; - const AttackSkillType *attackSkillType; - - public: - AttackStoppedCommandType (); - virtual void update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const; - virtual void load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const; - virtual string toString (bool translatedValue) const; - - //get - const StopSkillType *getStopSkillType () const - { - return stopSkillType; - } - const AttackSkillType *getAttackSkillType () const - { - return attackSkillType; - } - - virtual bool usesPathfinder () const - { - return false; - } - }; - - -// =============================== -// class BuildCommandType -// =============================== - - class BuildCommandType:public CommandType - { - private: - const MoveSkillType *moveSkillType; - const BuildSkillType *buildSkillType; - vector < const UnitType *>buildings; - SoundContainer startSounds; - SoundContainer builtSounds; - - public: - BuildCommandType (); - ~BuildCommandType (); - virtual void update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const; - virtual void load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const; - virtual string toString (bool translatedValue) const; - - //get - const MoveSkillType *getMoveSkillType () const - { - return moveSkillType; - } - const BuildSkillType *getBuildSkillType () const - { - return buildSkillType; - } - int getBuildingCount () const - { - return (int) buildings.size (); - } - const UnitType *getBuilding (int i) const - { - return buildings[i]; - } - StaticSound *getStartSound () const - { - return startSounds.getRandSound (); - } - StaticSound *getBuiltSound () const - { - return builtSounds.getRandSound (); - } - - virtual bool usesPathfinder () const - { - return true; - } - }; - - -// =============================== -// class HarvestCommandType -// =============================== - - class HarvestCommandType:public CommandType - { - private: - const MoveSkillType *moveSkillType; - const MoveSkillType *moveLoadedSkillType; - const HarvestSkillType *harvestSkillType; - const StopSkillType *stopLoadedSkillType; - vector < const ResourceType *>harvestedResources; - int maxLoad; - int hitsPerUnit; - - public: - HarvestCommandType (); - virtual void update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const; - virtual void load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const; - virtual string toString (bool translatedValue) const; - virtual Queueability isQueuable () const - { - return qOnRequest; - } - - //get - const MoveSkillType *getMoveSkillType () const - { - return moveSkillType; - } - const MoveSkillType *getMoveLoadedSkillType () const - { - return moveLoadedSkillType; - } - const HarvestSkillType *getHarvestSkillType () const - { - return harvestSkillType; - } - const StopSkillType *getStopLoadedSkillType () const - { - return stopLoadedSkillType; - } - int getMaxLoad () const - { - return maxLoad; - } - int getHitsPerUnit () const - { - return hitsPerUnit; - } - int getHarvestedResourceCount () const - { - return (int) harvestedResources.size (); - } - const ResourceType *getHarvestedResource (int i) const - { - return harvestedResources[i]; - } - bool canHarvest (const ResourceType * resourceType) const; - - virtual bool usesPathfinder () const - { - return true; - } - }; - -// =============================== -// class HarvestEmergencyReturnCommandType -// =============================== - - class HarvestEmergencyReturnCommandType:public CommandType - { - private: - - public: - HarvestEmergencyReturnCommandType (); - virtual void update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const; - virtual void load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const; - virtual string toString (bool translatedValue) const; - virtual Queueability isQueuable () const - { - return qOnRequest; - } - - //get - virtual bool usesPathfinder () const - { - return true; - } - }; - - -// =============================== -// class RepairCommandType -// =============================== - - class RepairCommandType:public CommandType - { - private: - const MoveSkillType *moveSkillType; - const RepairSkillType *repairSkillType; - vector < const UnitType *>repairableUnits; - - public: - RepairCommandType (); - ~RepairCommandType (); - virtual void update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const; - virtual void load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const; - virtual string toString (bool translatedValue) const; - - //get - const MoveSkillType *getMoveSkillType () const - { - return moveSkillType; - }; - const RepairSkillType *getRepairSkillType () const - { - return repairSkillType; - }; - bool isRepairableUnitType (const UnitType * unitType) const; - - int getRepairCount () const - { - return (int) repairableUnits.size (); - } - const UnitType *getRepair (int i) const - { - return repairableUnits[i]; - } - - virtual bool usesPathfinder () const - { - return true; - } - }; - - -// =============================== -// class ProduceCommandType -// =============================== - - class ProduceCommandType:public CommandType - { - private: - const ProduceSkillType *produceSkillType; - const UnitType *producedUnit; - - public: - ProduceCommandType (); - virtual void update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const; - virtual void load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const; - virtual string getReqDesc (bool translatedValue) const; - virtual string toString (bool translatedValue) const; - virtual const ProducibleType *getProduced () const; - virtual Queueability isQueuable () const - { - return qAlways; - } - virtual int getTypePriority () const - { - return 15; - } - - //get - const ProduceSkillType *getProduceSkillType () const - { - return produceSkillType; - } - const UnitType *getProducedUnit () const - { - return producedUnit; - } - - virtual bool usesPathfinder () const - { - return false; - } - }; - - -// =============================== -// class UpgradeCommandType -// =============================== - - class UpgradeCommandType:public CommandType - { - private: - const UpgradeSkillType *upgradeSkillType; - const UpgradeType *producedUpgrade; - - public: - UpgradeCommandType (); - virtual void update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const; - virtual void load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const; - virtual string toString (bool translatedValue) const; - virtual string getReqDesc (bool translatedValue) const; - virtual const ProducibleType *getProduced () const; - virtual Queueability isQueuable () const - { - return qAlways; - } - virtual int getTypePriority () const - { - return 15; - } - - //get - const UpgradeSkillType *getUpgradeSkillType () const - { - return upgradeSkillType; - } - const UpgradeType *getProducedUpgrade () const - { - return producedUpgrade; - } - - virtual bool usesPathfinder () const - { - return false; - } - }; - -// =============================== -// class MorphCommandType -// =============================== - - class MorphCommandType:public CommandType - { - private: - const MorphSkillType *morphSkillType; - const UnitType *morphUnit; - int discount; - bool ignoreResourceRequirements; - - public: - MorphCommandType (); - virtual void update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const; - virtual void load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const; - virtual string toString (bool translatedValue) const; - virtual string getReqDesc (bool translatedValue) const; - virtual const ProducibleType *getProduced () const; - Queueability isQueuable () const - { - return qOnlyLast; - } //After morph anything can happen - - //get - const MorphSkillType *getMorphSkillType () const - { - return morphSkillType; - } - const UnitType *getMorphUnit () const - { - return morphUnit; - } - int getDiscount () const - { - return discount; - } - bool getIgnoreResourceRequirements () const - { - return ignoreResourceRequirements; - } - - virtual bool usesPathfinder () const - { - return false; - } - }; - -// =============================== -// class SwitchTeamCommandType -// =============================== - - class SwitchTeamCommandType:public CommandType - { - private: - - - public: - SwitchTeamCommandType (); - virtual void update (UnitUpdater * unitUpdater, Unit * unit, - int frameIndex) const; - virtual void load (int id, const XmlNode * n, const string & dir, - const TechTree * tt, const FactionType * ft, - const UnitType & ut, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string getDesc (const TotalUpgrade * totalUpgrade, - bool translatedValue) const; - virtual string toString (bool translatedValue) const; - - virtual bool usesPathfinder () const - { - return false; - } - }; - -// =============================== -// class CommandFactory -// =============================== - - class CommandTypeFactory:public MultiFactory < CommandType > - { - private: - CommandTypeFactory (); - - public: - static CommandTypeFactory & getInstance (); - }; - -}} //end namespace +namespace Glest { + namespace Game { + + using Shared::Util::MultiFactory; + + class UnitUpdater; + class Unit; + class UnitType; + class TechTree; + class FactionType; + + enum CommandClass { + ccStop, + ccMove, + ccAttack, + ccAttackStopped, + ccBuild, + ccHarvest, + ccRepair, + ccProduce, + ccUpgrade, + ccMorph, + ccSwitchTeam, + ccHarvestEmergencyReturn, + + ccCount, + ccNull + }; + + enum Clicks { + cOne, + cTwo + }; + + enum Queueability { + qNever, + qOnRequest, + qOnlyLast, + qAlways + }; + + // ===================================================== + // class CommandType + // + /// A complex action performed by a unit, composed by skills + // ===================================================== + + class CommandType :public RequirableType { + protected: + Clicks clicks; + int id; + + std::map < string, bool > fogOfWarSkillAttachments; + const FogOfWarSkillType *fogOfWarSkillType; + + public: + static const int invalidId = -1; + CommandClass commandTypeClass; + + public: + CommandType() { + commandTypeClass = ccNull; + clicks = cOne; + id = -1; + fogOfWarSkillType = NULL; + fogOfWarSkillAttachments.clear(); + } + virtual void update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const = 0; + virtual void load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const = 0; + virtual string toString(bool translatedValue) const = 0; + virtual const ProducibleType *getProduced() const { + return NULL; + } + virtual Queueability isQueuable() const { + return qOnRequest; + } + bool isQueuable(bool tryQueue) const { + Queueability q = isQueuable(); + return (q == qAlways) || ((q == qOnRequest || q == qOnlyLast) + && tryQueue); + } + bool isQueueAppendable() const { + Queueability q = isQueuable(); + return (q != qNever) && (q != qOnlyLast); + } + //Priority: commands of higher priority will cancel commands of lower priority + virtual int getTypePriority() const { + return 10; + } + virtual bool usesPathfinder() const = 0; + + //get + CommandClass getClass() const; + Clicks getClicks() const { + return clicks; + } + int getId() const { + return id; + } + + const FogOfWarSkillType *getFogOfWarSkillType() const { + return fogOfWarSkillType; + }; + + bool hasFogOfWarSkillType(string name) const; + }; + + // =============================== + // class StopCommandType + // =============================== + + class StopCommandType :public CommandType { + private: + const StopSkillType *stopSkillType; + + public: + StopCommandType(); + virtual void update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const; + virtual void load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const; + virtual string toString(bool translatedValue) const; + virtual Queueability isQueuable() const { + return qNever; + } + virtual int getTypePriority() const { + return 100000; + } + //get + const StopSkillType *getStopSkillType() const { + return stopSkillType; + }; + + virtual bool usesPathfinder() const { + return false; + } + }; + + + // =============================== + // class MoveCommandType + // =============================== + + class MoveCommandType :public CommandType { + private: + const MoveSkillType *moveSkillType; + + public: + MoveCommandType(); + virtual void update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const; + virtual void load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const; + virtual string toString(bool translatedValue) const; + + //get + const MoveSkillType *getMoveSkillType() const { + return moveSkillType; + }; + + virtual bool usesPathfinder() const { + return true; + } + }; + + + // =============================== + // class AttackCommandType + // =============================== + + class AttackCommandType :public CommandType { + private: + const MoveSkillType *moveSkillType; + const AttackSkillType *attackSkillType; + + public: + AttackCommandType(); + virtual void update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const; + virtual void load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const; + virtual string toString(bool translatedValue) const; + + + //get + const MoveSkillType *getMoveSkillType() const { + return moveSkillType; + } + const AttackSkillType *getAttackSkillType() const { + return attackSkillType; + } + + virtual bool usesPathfinder() const { + return true; + } + }; + + // ======================================= + // class AttackStoppedCommandType + // ======================================= + + class AttackStoppedCommandType :public CommandType { + private: + const StopSkillType *stopSkillType; + const AttackSkillType *attackSkillType; + + public: + AttackStoppedCommandType(); + virtual void update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const; + virtual void load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const; + virtual string toString(bool translatedValue) const; + + //get + const StopSkillType *getStopSkillType() const { + return stopSkillType; + } + const AttackSkillType *getAttackSkillType() const { + return attackSkillType; + } + + virtual bool usesPathfinder() const { + return false; + } + }; + + + // =============================== + // class BuildCommandType + // =============================== + + class BuildCommandType :public CommandType { + private: + const MoveSkillType *moveSkillType; + const BuildSkillType *buildSkillType; + vector < const UnitType *>buildings; + SoundContainer startSounds; + SoundContainer builtSounds; + + public: + BuildCommandType(); + ~BuildCommandType(); + virtual void update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const; + virtual void load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const; + virtual string toString(bool translatedValue) const; + + //get + const MoveSkillType *getMoveSkillType() const { + return moveSkillType; + } + const BuildSkillType *getBuildSkillType() const { + return buildSkillType; + } + int getBuildingCount() const { + return (int) buildings.size(); + } + const UnitType *getBuilding(int i) const { + return buildings[i]; + } + StaticSound *getStartSound() const { + return startSounds.getRandSound(); + } + StaticSound *getBuiltSound() const { + return builtSounds.getRandSound(); + } + + virtual bool usesPathfinder() const { + return true; + } + }; + + + // =============================== + // class HarvestCommandType + // =============================== + + class HarvestCommandType :public CommandType { + private: + const MoveSkillType *moveSkillType; + const MoveSkillType *moveLoadedSkillType; + const HarvestSkillType *harvestSkillType; + const StopSkillType *stopLoadedSkillType; + vector < const ResourceType *>harvestedResources; + int maxLoad; + int hitsPerUnit; + + public: + HarvestCommandType(); + virtual void update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const; + virtual void load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const; + virtual string toString(bool translatedValue) const; + virtual Queueability isQueuable() const { + return qOnRequest; + } + + //get + const MoveSkillType *getMoveSkillType() const { + return moveSkillType; + } + const MoveSkillType *getMoveLoadedSkillType() const { + return moveLoadedSkillType; + } + const HarvestSkillType *getHarvestSkillType() const { + return harvestSkillType; + } + const StopSkillType *getStopLoadedSkillType() const { + return stopLoadedSkillType; + } + int getMaxLoad() const { + return maxLoad; + } + int getHitsPerUnit() const { + return hitsPerUnit; + } + int getHarvestedResourceCount() const { + return (int) harvestedResources.size(); + } + const ResourceType *getHarvestedResource(int i) const { + return harvestedResources[i]; + } + bool canHarvest(const ResourceType * resourceType) const; + + virtual bool usesPathfinder() const { + return true; + } + }; + + // =============================== + // class HarvestEmergencyReturnCommandType + // =============================== + + class HarvestEmergencyReturnCommandType :public CommandType { + private: + + public: + HarvestEmergencyReturnCommandType(); + virtual void update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const; + virtual void load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const; + virtual string toString(bool translatedValue) const; + virtual Queueability isQueuable() const { + return qOnRequest; + } + + //get + virtual bool usesPathfinder() const { + return true; + } + }; + + + // =============================== + // class RepairCommandType + // =============================== + + class RepairCommandType :public CommandType { + private: + const MoveSkillType *moveSkillType; + const RepairSkillType *repairSkillType; + vector < const UnitType *>repairableUnits; + + public: + RepairCommandType(); + ~RepairCommandType(); + virtual void update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const; + virtual void load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const; + virtual string toString(bool translatedValue) const; + + //get + const MoveSkillType *getMoveSkillType() const { + return moveSkillType; + }; + const RepairSkillType *getRepairSkillType() const { + return repairSkillType; + }; + bool isRepairableUnitType(const UnitType * unitType) const; + + int getRepairCount() const { + return (int) repairableUnits.size(); + } + const UnitType *getRepair(int i) const { + return repairableUnits[i]; + } + + virtual bool usesPathfinder() const { + return true; + } + }; + + + // =============================== + // class ProduceCommandType + // =============================== + + class ProduceCommandType :public CommandType { + private: + const ProduceSkillType *produceSkillType; + const UnitType *producedUnit; + + public: + ProduceCommandType(); + virtual void update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const; + virtual void load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const; + virtual string getReqDesc(bool translatedValue) const; + virtual string toString(bool translatedValue) const; + virtual const ProducibleType *getProduced() const; + virtual Queueability isQueuable() const { + return qAlways; + } + virtual int getTypePriority() const { + return 15; + } + + //get + const ProduceSkillType *getProduceSkillType() const { + return produceSkillType; + } + const UnitType *getProducedUnit() const { + return producedUnit; + } + + virtual bool usesPathfinder() const { + return false; + } + }; + + + // =============================== + // class UpgradeCommandType + // =============================== + + class UpgradeCommandType :public CommandType { + private: + const UpgradeSkillType *upgradeSkillType; + const UpgradeType *producedUpgrade; + + public: + UpgradeCommandType(); + virtual void update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const; + virtual void load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const; + virtual string toString(bool translatedValue) const; + virtual string getReqDesc(bool translatedValue) const; + virtual const ProducibleType *getProduced() const; + virtual Queueability isQueuable() const { + return qAlways; + } + virtual int getTypePriority() const { + return 15; + } + + //get + const UpgradeSkillType *getUpgradeSkillType() const { + return upgradeSkillType; + } + const UpgradeType *getProducedUpgrade() const { + return producedUpgrade; + } + + virtual bool usesPathfinder() const { + return false; + } + }; + + // =============================== + // class MorphCommandType + // =============================== + + class MorphCommandType :public CommandType { + private: + const MorphSkillType *morphSkillType; + const UnitType *morphUnit; + int discount; + bool ignoreResourceRequirements; + + public: + MorphCommandType(); + virtual void update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const; + virtual void load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const; + virtual string toString(bool translatedValue) const; + virtual string getReqDesc(bool translatedValue) const; + virtual const ProducibleType *getProduced() const; + Queueability isQueuable() const { + return qOnlyLast; + } //After morph anything can happen + + //get + const MorphSkillType *getMorphSkillType() const { + return morphSkillType; + } + const UnitType *getMorphUnit() const { + return morphUnit; + } + int getDiscount() const { + return discount; + } + bool getIgnoreResourceRequirements() const { + return ignoreResourceRequirements; + } + + virtual bool usesPathfinder() const { + return false; + } + }; + + // =============================== + // class SwitchTeamCommandType + // =============================== + + class SwitchTeamCommandType :public CommandType { + private: + + + public: + SwitchTeamCommandType(); + virtual void update(UnitUpdater * unitUpdater, Unit * unit, + int frameIndex) const; + virtual void load(int id, const XmlNode * n, const string & dir, + const TechTree * tt, const FactionType * ft, + const UnitType & ut, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string getDesc(const TotalUpgrade * totalUpgrade, + bool translatedValue) const; + virtual string toString(bool translatedValue) const; + + virtual bool usesPathfinder() const { + return false; + } + }; + + // =============================== + // class CommandFactory + // =============================== + + class CommandTypeFactory :public MultiFactory < CommandType > { + private: + CommandTypeFactory(); + + public: + static CommandTypeFactory & getInstance(); + }; + + } +} //end namespace #endif diff --git a/source/glest_game/types/damage_multiplier.cpp b/source/glest_game/types/damage_multiplier.cpp index 9fc93be5c..d045bd09d 100644 --- a/source/glest_game/types/damage_multiplier.cpp +++ b/source/glest_game/types/damage_multiplier.cpp @@ -16,117 +16,104 @@ using namespace Shared::Util; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - void AttackType::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode *attackTypeNode = rootNode->addChild ("AttackType"); + void AttackType::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode *attackTypeNode = rootNode->addChild("AttackType"); -// string name; - attackTypeNode->addAttribute ("name", name, mapTagReplacements); -// int id; - attackTypeNode->addAttribute ("id", intToStr (id), mapTagReplacements); - } + // string name; + attackTypeNode->addAttribute("name", name, mapTagReplacements); + // int id; + attackTypeNode->addAttribute("id", intToStr(id), mapTagReplacements); + } - string AttackType::getName (bool translatedValue) const - { - if (translatedValue == false) - return name; + string AttackType::getName(bool translatedValue) const { + if (translatedValue == false) + return name; - Lang & lang = Lang::getInstance (); - return lang.getTechTreeString ("AttackTypeName_" + name, name.c_str ()); - } + Lang & lang = Lang::getInstance(); + return lang.getTechTreeString("AttackTypeName_" + name, name.c_str()); + } - void ArmorType::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode *armorTypeNode = rootNode->addChild ("ArmorType"); + void ArmorType::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode *armorTypeNode = rootNode->addChild("ArmorType"); -// string name; - armorTypeNode->addAttribute ("name", name, mapTagReplacements); -// int id; - armorTypeNode->addAttribute ("id", intToStr (id), mapTagReplacements); - } + // string name; + armorTypeNode->addAttribute("name", name, mapTagReplacements); + // int id; + armorTypeNode->addAttribute("id", intToStr(id), mapTagReplacements); + } - string ArmorType::getName (bool translatedValue) const - { - if (translatedValue == false) - return name; + string ArmorType::getName(bool translatedValue) const { + if (translatedValue == false) + return name; - Lang & lang = Lang::getInstance (); - return lang.getTechTreeString ("ArmorTypeName_" + name, name.c_str ()); - } -// ===================================================== -// class DamageMultiplierTable -// ===================================================== + Lang & lang = Lang::getInstance(); + return lang.getTechTreeString("ArmorTypeName_" + name, name.c_str()); + } + // ===================================================== + // class DamageMultiplierTable + // ===================================================== - DamageMultiplierTable::DamageMultiplierTable () - { - values = NULL; - attackTypeCount = 0; - armorTypeCount = 0; - } + DamageMultiplierTable::DamageMultiplierTable() { + values = NULL; + attackTypeCount = 0; + armorTypeCount = 0; + } - DamageMultiplierTable::~DamageMultiplierTable () - { - delete[]values; - values = NULL; - } + DamageMultiplierTable::~DamageMultiplierTable() { + delete[]values; + values = NULL; + } - void DamageMultiplierTable::init (int attackTypeCount, int armorTypeCount) - { - this->attackTypeCount = attackTypeCount; - this->armorTypeCount = armorTypeCount; + void DamageMultiplierTable::init(int attackTypeCount, int armorTypeCount) { + this->attackTypeCount = attackTypeCount; + this->armorTypeCount = armorTypeCount; - int valueCount = attackTypeCount * armorTypeCount; - values = new double[valueCount]; - for (int i = 0; i < valueCount; ++i) - { - values[i] = 1.f; - } - } + int valueCount = attackTypeCount * armorTypeCount; + values = new double[valueCount]; + for (int i = 0; i < valueCount; ++i) { + values[i] = 1.f; + } + } - double DamageMultiplierTable::getDamageMultiplier (const AttackType * att, - const ArmorType * - art) const - { - return values[attackTypeCount * art->getId () + att->getId ()]; - } + double DamageMultiplierTable::getDamageMultiplier(const AttackType * att, + const ArmorType * + art) const { + return values[attackTypeCount * art->getId() + att->getId()]; + } - void DamageMultiplierTable::setDamageMultiplier (const AttackType * att, - const ArmorType * art, - double value) - { - values[attackTypeCount * art->getId () + att->getId ()] = value; - } + void DamageMultiplierTable::setDamageMultiplier(const AttackType * att, + const ArmorType * art, + double value) { + values[attackTypeCount * art->getId() + att->getId()] = value; + } - void DamageMultiplierTable::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode *damageMultiplierTableNode = - rootNode->addChild ("DamageMultiplierTable"); + void DamageMultiplierTable::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode *damageMultiplierTableNode = + rootNode->addChild("DamageMultiplierTable"); -// float *values; -// int attackTypeCount; -// int armorTypeCount; - damageMultiplierTableNode->addAttribute ("attackTypeCount", - intToStr (attackTypeCount), - mapTagReplacements); - damageMultiplierTableNode->addAttribute ("armorTypeCount", - intToStr (armorTypeCount), - mapTagReplacements); + // float *values; + // int attackTypeCount; + // int armorTypeCount; + damageMultiplierTableNode->addAttribute("attackTypeCount", + intToStr(attackTypeCount), + mapTagReplacements); + damageMultiplierTableNode->addAttribute("armorTypeCount", + intToStr(armorTypeCount), + mapTagReplacements); - int valueCount = attackTypeCount * armorTypeCount; - for (int i = 0; i < valueCount; ++i) - { - XmlNode *valuesNode = damageMultiplierTableNode->addChild ("values"); - valuesNode->addAttribute ("value", doubleToStr (values[i]), - mapTagReplacements); - } - } + int valueCount = attackTypeCount * armorTypeCount; + for (int i = 0; i < valueCount; ++i) { + XmlNode *valuesNode = damageMultiplierTableNode->addChild("values"); + valuesNode->addAttribute("value", doubleToStr(values[i]), + mapTagReplacements); + } + } -}} //end namespaces + } +} //end namespaces diff --git a/source/glest_game/types/damage_multiplier.h b/source/glest_game/types/damage_multiplier.h index 8bfc257dd..b703e126c 100644 --- a/source/glest_game/types/damage_multiplier.h +++ b/source/glest_game/types/damage_multiplier.h @@ -24,104 +24,92 @@ using std::string; using Shared::Xml::XmlNode; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// =============================== -// class AttackType -// =============================== + // =============================== + // class AttackType + // =============================== - class AttackType - { - private: - string name; - int id; + class AttackType { + private: + string name; + int id; - public: - AttackType () - { - id = -1; - } - int getId () const - { - return id; - } - string getName (bool translatedValue = false) const; + public: + AttackType() { + id = -1; + } + int getId() const { + return id; + } + string getName(bool translatedValue = false) const; - void setName (const string & name) - { - this->name = name; - } - void setId (int id) - { - this->id = id; - } + void setName(const string & name) { + this->name = name; + } + void setId(int id) { + this->id = id; + } - void saveGame (XmlNode * rootNode); - }; + void saveGame(XmlNode * rootNode); + }; -// =============================== -// class ArmorType -// =============================== + // =============================== + // class ArmorType + // =============================== - class ArmorType - { - private: - string name; - int id; + class ArmorType { + private: + string name; + int id; - public: - ArmorType () - { - id = -1; - } - int getId () const - { - return id; - } - string getName (bool translatedValue = false) const; + public: + ArmorType() { + id = -1; + } + int getId() const { + return id; + } + string getName(bool translatedValue = false) const; - void setName (const string & name) - { - this->name = name; - } - void setId (int id) - { - this->id = id; - } + void setName(const string & name) { + this->name = name; + } + void setId(int id) { + this->id = id; + } - void saveGame (XmlNode * rootNode); - }; + void saveGame(XmlNode * rootNode); + }; -// ===================================================== -// class DamageMultiplierTable -// -/// Some attack types have bonuses against some -/// armor types and vice-versa -// ===================================================== + // ===================================================== + // class DamageMultiplierTable + // + /// Some attack types have bonuses against some + /// armor types and vice-versa + // ===================================================== - class DamageMultiplierTable - { - private: - double *values; - int attackTypeCount; - int armorTypeCount; + class DamageMultiplierTable { + private: + double *values; + int attackTypeCount; + int armorTypeCount; - public: - DamageMultiplierTable (); - ~DamageMultiplierTable (); + public: + DamageMultiplierTable(); + ~DamageMultiplierTable(); - void init (int attackTypeCount, int armorTypeCount); - double getDamageMultiplier (const AttackType * att, - const ArmorType * art) const; - void setDamageMultiplier (const AttackType * att, const ArmorType * art, - double value); + void init(int attackTypeCount, int armorTypeCount); + double getDamageMultiplier(const AttackType * att, + const ArmorType * art) const; + void setDamageMultiplier(const AttackType * att, const ArmorType * art, + double value); - void saveGame (XmlNode * rootNode); - }; + void saveGame(XmlNode * rootNode); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/types/element_type.cpp b/source/glest_game/types/element_type.cpp index facd89c5e..37a358a0c 100644 --- a/source/glest_game/types/element_type.cpp +++ b/source/glest_game/types/element_type.cpp @@ -25,232 +25,197 @@ using namespace Shared::Util; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class DisplayableType -// ===================================================== + // ===================================================== + // class DisplayableType + // ===================================================== - DisplayableType::DisplayableType () - { - image = NULL; - } + DisplayableType::DisplayableType() { + image = NULL; + } - string DisplayableType::getName (bool translatedValue) const - { - if (translatedValue == false) - return name; + string DisplayableType::getName(bool translatedValue) const { + if (translatedValue == false) + return name; - Lang & lang = Lang::getInstance (); - return lang.getTechTreeString ("CommandName_" + name, name.c_str ()); - } + Lang & lang = Lang::getInstance(); + return lang.getTechTreeString("CommandName_" + name, name.c_str()); + } -//void DisplayableType::saveGame(XmlNode *rootNode) const { -// std::map mapTagReplacements; -// XmlNode *displayableTypeNode = rootNode->addChild("DisplayableType"); -// -// displayableTypeNode->addAttribute("name",name, mapTagReplacements); -//} + //void DisplayableType::saveGame(XmlNode *rootNode) const { + // std::map mapTagReplacements; + // XmlNode *displayableTypeNode = rootNode->addChild("DisplayableType"); + // + // displayableTypeNode->addAttribute("name",name, mapTagReplacements); + //} -// ===================================================== -// class RequirableType -// ===================================================== + // ===================================================== + // class RequirableType + // ===================================================== - string RequirableType::getReqDesc (bool translatedValue) const - { - bool anyReqs = false; + string RequirableType::getReqDesc(bool translatedValue) const { + bool anyReqs = false; - string reqString = ""; - for (int i = 0; i < getUnitReqCount (); ++i) - { - if (getUnitReq (i) == NULL) - { - throw megaglest_runtime_error ("getUnitReq(i) == NULL"); - } - reqString += getUnitReq (i)->getName (translatedValue); - reqString += "\n"; - anyReqs = true; - } + string reqString = ""; + for (int i = 0; i < getUnitReqCount(); ++i) { + if (getUnitReq(i) == NULL) { + throw megaglest_runtime_error("getUnitReq(i) == NULL"); + } + reqString += getUnitReq(i)->getName(translatedValue); + reqString += "\n"; + anyReqs = true; + } - for (int i = 0; i < getUpgradeReqCount (); ++i) - { - if (getUpgradeReq (i) == NULL) - { - throw megaglest_runtime_error ("getUpgradeReq(i) == NULL"); - } + for (int i = 0; i < getUpgradeReqCount(); ++i) { + if (getUpgradeReq(i) == NULL) { + throw megaglest_runtime_error("getUpgradeReq(i) == NULL"); + } - reqString += getUpgradeReq (i)->getName (translatedValue); - reqString += "\n"; - anyReqs = true; - } + reqString += getUpgradeReq(i)->getName(translatedValue); + reqString += "\n"; + anyReqs = true; + } - string str = getName (translatedValue); - if (anyReqs) - { - return str + " " + Lang::getInstance ().getString ("Reqs", - (translatedValue == - true ? "" : - "english")) + - ":\n" + reqString; - } - else - { - return str; - } - } + string str = getName(translatedValue); + if (anyReqs) { + return str + " " + Lang::getInstance().getString("Reqs", + (translatedValue == + true ? "" : + "english")) + + ":\n" + reqString; + } else { + return str; + } + } -//void RequirableType::saveGame(XmlNode *rootNode) const { -// DisplayableType::saveGame(rootNode); -// -// std::map mapTagReplacements; -// XmlNode *requirableTypeNode = rootNode->addChild("RequirableType"); -// -//// UnitReqs unitReqs; //needed units -// for(unsigned int i = 0; i < unitReqs.size(); ++i) { -// const UnitType *ut = unitReqs[i]; -// -// XmlNode *unitReqsNode = requirableTypeNode->addChild("unitReqs"); -// unitReqsNode->addAttribute("name",ut->getName(), mapTagReplacements); -// } -//// UpgradeReqs upgradeReqs; //needed upgrades -// for(unsigned int i = 0; i < upgradeReqs.size(); ++i) { -// const UpgradeType* ut = upgradeReqs[i]; -// -// ut->saveGame(requirableTypeNode); -// } -// -//} + //void RequirableType::saveGame(XmlNode *rootNode) const { + // DisplayableType::saveGame(rootNode); + // + // std::map mapTagReplacements; + // XmlNode *requirableTypeNode = rootNode->addChild("RequirableType"); + // + //// UnitReqs unitReqs; //needed units + // for(unsigned int i = 0; i < unitReqs.size(); ++i) { + // const UnitType *ut = unitReqs[i]; + // + // XmlNode *unitReqsNode = requirableTypeNode->addChild("unitReqs"); + // unitReqsNode->addAttribute("name",ut->getName(), mapTagReplacements); + // } + //// UpgradeReqs upgradeReqs; //needed upgrades + // for(unsigned int i = 0; i < upgradeReqs.size(); ++i) { + // const UpgradeType* ut = upgradeReqs[i]; + // + // ut->saveGame(requirableTypeNode); + // } + // + //} -// ===================================================== -// class ProducibleType -// ===================================================== + // ===================================================== + // class ProducibleType + // ===================================================== - ProducibleType::ProducibleType () - { - cancelImage = NULL; - productionTime = 0; - } + ProducibleType::ProducibleType() { + cancelImage = NULL; + productionTime = 0; + } - ProducibleType::~ProducibleType () - { - } + ProducibleType::~ProducibleType() { + } - const Resource *ProducibleType::getCost (const ResourceType * rt) const - { - for (int i = 0; i < (int) costs.size (); ++i) - { - if (costs[i].getType () == rt) - { - return &costs[i]; - } - } - return NULL; - } + const Resource *ProducibleType::getCost(const ResourceType * rt) const { + for (int i = 0; i < (int) costs.size(); ++i) { + if (costs[i].getType() == rt) { + return &costs[i]; + } + } + return NULL; + } - string ProducibleType::getReqDesc (bool translatedValue) const - { - return getReqDesc (false, translatedValue); - } + string ProducibleType::getReqDesc(bool translatedValue) const { + return getReqDesc(false, translatedValue); + } - string ProducibleType::getResourceReqDesc (bool lineBreaks, - bool translatedValue) const - { - string str = ""; - for (int i = 0; i < getCostCount (); ++i) - { - if (getCost (i)->getAmount () != 0) - { - str += getCost (i)->getType ()->getName (translatedValue); - str += ": " + intToStr (getCost (i)->getAmount ()); - if (lineBreaks == true) - { - str += "\n"; - } - else - { - str += " "; - } - } - } + string ProducibleType::getResourceReqDesc(bool lineBreaks, + bool translatedValue) const { + string str = ""; + for (int i = 0; i < getCostCount(); ++i) { + if (getCost(i)->getAmount() != 0) { + str += getCost(i)->getType()->getName(translatedValue); + str += ": " + intToStr(getCost(i)->getAmount()); + if (lineBreaks == true) { + str += "\n"; + } else { + str += " "; + } + } + } - return str; - } + return str; + } - string ProducibleType::getUnitAndUpgradeReqDesc (bool lineBreaks, - bool translatedValue) - const - { - string str = ""; - for (int i = 0; i < getUnitReqCount (); ++i) - { - str += getUnitReq (i)->getName (translatedValue); - if (lineBreaks == true) - { - str += "\n"; - } - else - { - str += " "; - } - } + string ProducibleType::getUnitAndUpgradeReqDesc(bool lineBreaks, + bool translatedValue) + const { + string str = ""; + for (int i = 0; i < getUnitReqCount(); ++i) { + str += getUnitReq(i)->getName(translatedValue); + if (lineBreaks == true) { + str += "\n"; + } else { + str += " "; + } + } - for (int i = 0; i < getUpgradeReqCount (); ++i) - { - str += getUpgradeReq (i)->getName (translatedValue); - if (lineBreaks == true) - { - str += "\n"; - } - else - { - str += " "; - } - } + for (int i = 0; i < getUpgradeReqCount(); ++i) { + str += getUpgradeReq(i)->getName(translatedValue); + if (lineBreaks == true) { + str += "\n"; + } else { + str += " "; + } + } - return str; - } + return str; + } - string ProducibleType::getReqDesc (bool ignoreResourceRequirements, - bool translatedValue) const - { - string str = - getName (translatedValue) + " " + - Lang::getInstance ().getString ("Reqs", - (translatedValue == - true ? "" : "english")) + ":\n"; - if (ignoreResourceRequirements == false) - { - str += getResourceReqDesc (true, translatedValue); - } + string ProducibleType::getReqDesc(bool ignoreResourceRequirements, + bool translatedValue) const { + string str = + getName(translatedValue) + " " + + Lang::getInstance().getString("Reqs", + (translatedValue == + true ? "" : "english")) + ":\n"; + if (ignoreResourceRequirements == false) { + str += getResourceReqDesc(true, translatedValue); + } - str += getUnitAndUpgradeReqDesc (true, translatedValue); - return str; - } + str += getUnitAndUpgradeReqDesc(true, translatedValue); + return str; + } -//void ProducibleType::saveGame(XmlNode *rootNode) const { -// RequirableType::saveGame(rootNode); -// -// std::map mapTagReplacements; -// XmlNode *producibleTypeNode = rootNode->addChild("ProducibleType"); -// -//// Costs costs; -// for(unsigned int i = 0; i < costs.size(); ++i) { -// const Resource &res = costs[i]; -// res.saveGame(producibleTypeNode); -// } -//// Texture2D *cancelImage; -//// int productionTime; -// producibleTypeNode->addAttribute("productionTime",intToStr(productionTime), mapTagReplacements); -//} + //void ProducibleType::saveGame(XmlNode *rootNode) const { + // RequirableType::saveGame(rootNode); + // + // std::map mapTagReplacements; + // XmlNode *producibleTypeNode = rootNode->addChild("ProducibleType"); + // + //// Costs costs; + // for(unsigned int i = 0; i < costs.size(); ++i) { + // const Resource &res = costs[i]; + // res.saveGame(producibleTypeNode); + // } + //// Texture2D *cancelImage; + //// int productionTime; + // producibleTypeNode->addAttribute("productionTime",intToStr(productionTime), mapTagReplacements); + //} -//void ProducibleType::loadGame(const XmlNode *rootNode) { -// const XmlNode *producibleTypeNode = rootNode->getChild("ProducibleType"); -// -// //int newUnitId = producibleTypeNode->getAttribute("id")->getIntValue(); -//} + //void ProducibleType::loadGame(const XmlNode *rootNode) { + // const XmlNode *producibleTypeNode = rootNode->getChild("ProducibleType"); + // + // //int newUnitId = producibleTypeNode->getAttribute("id")->getIntValue(); + //} - } + } } //end namespace diff --git a/source/glest_game/types/element_type.h b/source/glest_game/types/element_type.h index a3b0d2b65..f0b80b8d0 100644 --- a/source/glest_game/types/element_type.h +++ b/source/glest_game/types/element_type.h @@ -28,142 +28,128 @@ using std::string; using Shared::Graphics::Texture2D; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - class UpgradeType; - class TechTree; - class UnitType; - class UpgradeType; - class DisplayableType; - class ResourceType; + class UpgradeType; + class TechTree; + class UnitType; + class UpgradeType; + class DisplayableType; + class ResourceType; -// ===================================================== -// class DisplayableType -// -/// Base class for anything that has a name and a portrait -// ===================================================== + // ===================================================== + // class DisplayableType + // + /// Base class for anything that has a name and a portrait + // ===================================================== - class DisplayableType - { - protected: - string name; //name - Texture2D *image; //portrait + class DisplayableType { + protected: + string name; //name + Texture2D *image; //portrait - public: - DisplayableType (); - virtual ~ DisplayableType () - { - }; + public: + DisplayableType(); + virtual ~DisplayableType() { + }; - //get - virtual string getName (bool translatedValue = false) const; - virtual const Texture2D *getImage () const - { - return image; - } + //get + virtual string getName(bool translatedValue = false) const; + virtual const Texture2D *getImage() const { + return image; + } - //virtual void saveGame(XmlNode *rootNode) const; - }; + //virtual void saveGame(XmlNode *rootNode) const; + }; -// ===================================================== -// class RequirableType -// -/// Base class for anything that has requirements -// ===================================================== + // ===================================================== + // class RequirableType + // + /// Base class for anything that has requirements + // ===================================================== - class RequirableType:public DisplayableType - { - private: - typedef vector < const UnitType *>UnitReqs; - typedef vector < const UpgradeType *>UpgradeReqs; + class RequirableType :public DisplayableType { + private: + typedef vector < const UnitType *>UnitReqs; + typedef vector < const UpgradeType *>UpgradeReqs; - protected: - UnitReqs unitReqs; //needed units - UpgradeReqs upgradeReqs; //needed upgrades + protected: + UnitReqs unitReqs; //needed units + UpgradeReqs upgradeReqs; //needed upgrades - public: - //get - int getUpgradeReqCount () const - { - return (int) upgradeReqs.size (); - } - int getUnitReqCount () const - { - return (int) unitReqs.size (); - } - const UpgradeType *getUpgradeReq (int i) const - { - return upgradeReqs[i]; - } - const UnitType *getUnitReq (int i) const - { - return unitReqs[i]; - } + public: + //get + int getUpgradeReqCount() const { + return (int) upgradeReqs.size(); + } + int getUnitReqCount() const { + return (int) unitReqs.size(); + } + const UpgradeType *getUpgradeReq(int i) const { + return upgradeReqs[i]; + } + const UnitType *getUnitReq(int i) const { + return unitReqs[i]; + } - //other - virtual string getReqDesc (bool translatedValue) const; + //other + virtual string getReqDesc(bool translatedValue) const; - //virtual void saveGame(XmlNode *rootNode) const; - }; + //virtual void saveGame(XmlNode *rootNode) const; + }; -// ===================================================== -// class ProducibleType -// -/// Base class for anything that can be produced -// ===================================================== + // ===================================================== + // class ProducibleType + // + /// Base class for anything that can be produced + // ===================================================== - class ProducibleType:public RequirableType - { - private: - typedef vector < Resource > Costs; + class ProducibleType :public RequirableType { + private: + typedef vector < Resource > Costs; - protected: - Costs costs; - Texture2D *cancelImage; - int productionTime; + protected: + Costs costs; + Texture2D *cancelImage; + int productionTime; - public: - ProducibleType (); - virtual ~ ProducibleType (); + public: + ProducibleType(); + virtual ~ProducibleType(); - //get - int getCostCount () const - { - return (int) costs.size (); - } - const Resource *getCost (int i) const - { - return &costs[i]; - } - const Resource *getCost (const ResourceType * rt) const; - int getProductionTime () const - { - return productionTime; - } - const Texture2D *getCancelImage () const - { - return cancelImage; - } + //get + int getCostCount() const { + return (int) costs.size(); + } + const Resource *getCost(int i) const { + return &costs[i]; + } + const Resource *getCost(const ResourceType * rt) const; + int getProductionTime() const { + return productionTime; + } + const Texture2D *getCancelImage() const { + return cancelImage; + } - //varios - void checkCostStrings (TechTree * techTree); + //varios + void checkCostStrings(TechTree * techTree); - virtual string getReqDesc (bool translatedValue) const; - string getResourceReqDesc (bool lineBreaks, bool translatedValue) const; - string getUnitAndUpgradeReqDesc (bool lineBreaks, - bool translatedValue) const; - string getReqDesc (bool ignoreResourceRequirements, - bool translatedValue) const; + virtual string getReqDesc(bool translatedValue) const; + string getResourceReqDesc(bool lineBreaks, bool translatedValue) const; + string getUnitAndUpgradeReqDesc(bool lineBreaks, + bool translatedValue) const; + string getReqDesc(bool ignoreResourceRequirements, + bool translatedValue) const; -// virtual void saveGame(XmlNode *rootNode) const; -// void loadGame(const XmlNode *rootNode); - }; + // virtual void saveGame(XmlNode *rootNode) const; + // void loadGame(const XmlNode *rootNode); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/types/faction_type.cpp b/source/glest_game/types/faction_type.cpp index 5e232b5eb..a298543bb 100644 --- a/source/glest_game/types/faction_type.cpp +++ b/source/glest_game/types/faction_type.cpp @@ -25,1565 +25,1350 @@ using namespace Shared::Util; using namespace Shared::Xml; -namespace Glest -{ - namespace Game - { - -// ====================================================== -// Class FactionType -// ====================================================== - - FactionType::FactionType () - { - music = NULL; - personalityType = fpt_Normal; - isLinked = false; - healthbarheight = -100.0f; - healthbarthickness = 0.11f; - healthbarVisible = hbvUndefined; - healthbarBorderTextureEnabled = false; - healthbarBackgroundTextureEnabled = false; - healthbarLineBorder = true; - healthbarTexture = NULL; - healthbarBackgroundTexture = NULL; - flatParticlePositions = false; - } - -//load a faction, given a directory - void FactionType::load (const string & factionName, - const TechTree * techTree, Checksum * checksum, - Checksum * techtreeChecksum, std::map < string, - vector < pair < string, - string > > >&loadedFileList, bool validationMode) - { - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - string techTreePath = techTree->getPath (); - string techTreeName = techTree->getNameUntranslated (); - string currentPath = ""; - - //open xml file - string path = ""; - XmlTree xmlTree; - const XmlNode *factionNode; - - //printf("\n>>> factionname=%s\n",factionName.c_str()); - for (bool realFactionPathFound = false; realFactionPathFound == false;) - { - currentPath = techTreePath + "factions/" + factionName; - endPathWithSlash (currentPath); - - name = lastDir (currentPath); - - // Add special Observer Faction - //Lang &lang= Lang::getInstance(); - if (name == formatString (GameConstants::OBSERVER_SLOTNAME)) - { - personalityType = fpt_Observer; - } - - if (personalityType == fpt_Normal) - { - string tmppath = currentPath + factionName + ".xml"; - std::map < string, string > mapExtraTagReplacementValues; - // mapExtraTagReplacementValues["$COMMONDATAPATH"] = techTreePath + "/commondata/"; - //printf("current $COMMONDATAPATH = %s\n",mapExtraTagReplacementValues["$COMMONDATAPATH"].c_str()); - XmlTree xmlTree; - xmlTree.load (tmppath, - Properties:: - getTagReplacementValues - (&mapExtraTagReplacementValues)); - - - const XmlNode *rootNode = xmlTree.getRootNode (); - - if (rootNode->getName () == "link") - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "Faction [%s] is a linked faction\n", - name.c_str ()); - - isLinked = true; - const XmlNode *techTreeNode = rootNode->getChild ("techtree"); - const string linkedTechTreeName = - techTreeNode->getAttribute ("name")->getRestrictedValue (); - // const XmlNode *factionLinkNode= rootNode->getChild("faction"); - // string linkedFactionName=factionLinkNode->getAttribute("name")->getRestrictedValue(); - string linkedTechTreePath = - techTree->findPath (linkedTechTreeName); - techTreePath = linkedTechTreePath; - endPathWithSlash (techTreePath); - techTreeName = linkedTechTreeName; - - string linkedCurrentPath = - techTreePath + "factions/" + factionName; - endPathWithSlash (linkedCurrentPath); - string linkedTmppath = linkedCurrentPath + factionName + ".xml"; - - //printf("linkedTmppath [%s] linkedCurrentPath [%s]\n",linkedTmppath.c_str(),linkedCurrentPath.c_str()); - - loadedFileList[linkedTmppath]. - push_back (make_pair (linkedCurrentPath, linkedCurrentPath)); - loadedFileList[tmppath]. - push_back (make_pair (currentPath, currentPath)); - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "techTreePath [%s] techTreeName [%s]\n", - techTreePath.c_str (), - techTreeName.c_str ()); - } - else - { - // stop looking for new path, no more links ... - //xmlTree.load(tmppath, Properties::getTagReplacementValues(&mapExtraTagReplacementValues)); - - loadedFileList[tmppath]. - push_back (make_pair (currentPath, currentPath)); - - realFactionPathFound = true; - //printf("techPath found! %s\n",tmppath.c_str()); - - path = tmppath; - } - } - else - { - break; - } - } - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - Lang::getInstance (). - getString ("LogScreenGameLoadingFactionType", "", - true).c_str (), - formatString (this->getName ()).c_str ()); - Logger::getInstance ().add (szBuf, true); - - if (personalityType == fpt_Normal) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "Loading faction [%s] currentPath [%s]\n", - path.c_str (), currentPath.c_str ()); - - checksum->addFile (path); - techtreeChecksum->addFile (path); - - // a1) preload units - //string unitsPath= currentPath + "units/*."; - string unitsPath = currentPath + "units/"; - vector < string > unitFilenames; - //findAll(unitsPath, unitFilenames); - findDirs (unitsPath, unitFilenames, false, false); - - unitTypes.resize (unitFilenames.size ()); - - for (int i = 0; i < (int) unitTypes.size (); ++i) - { - string str = currentPath + "units/" + unitFilenames[i]; - unitTypes[i].preLoad (str); - - SDL_PumpEvents (); - } - - // a2) preload upgrades - //string upgradesPath= currentPath + "upgrades/*."; - string upgradesPath = currentPath + "upgrades/"; - vector < string > upgradeFilenames; - //findAll(upgradesPath, upgradeFilenames, false, false); - findDirs (upgradesPath, upgradeFilenames, false, false); - - upgradeTypes.resize (upgradeFilenames.size ()); - for (int i = 0; i < (int) upgradeTypes.size (); ++i) - { - string str = currentPath + "upgrades/" + upgradeFilenames[i]; - upgradeTypes[i].preLoad (str); - - SDL_PumpEvents (); - } - - // b1) load units - try - { - Logger & logger = Logger::getInstance (); - int progressBaseValue = logger.getProgress (); - for (int i = 0; i < (int) unitTypes.size (); ++i) - { - string str = currentPath + "units/" + unitTypes[i].getName (); - - try - { - unitTypes[i].loaddd (i, str, techTree, techTreePath, this, - checksum, techtreeChecksum, loadedFileList, - validationMode); - logger.setProgress (progressBaseValue + - (int) ((((double) i + - 1.0) / - (double) unitTypes.size ()) * - 100.0 / techTree->getTypeCount ())); - SDL_PumpEvents (); - } - catch (megaglest_runtime_error & ex) - { - if (validationMode == false) - { - throw; - } - else - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, ex.what ()); - } - } - } - } - catch (megaglest_runtime_error & ex) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - ex.what ()); - throw megaglest_runtime_error ("Error loading units: " + - currentPath + "\nMessage: " + - ex.what (), !ex.wantStackTrace ()); - } - catch (const exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - e.what ()); - throw megaglest_runtime_error ("Error loading units: " + - currentPath + "\nMessage: " + - e.what ()); - } - - // b2) load upgrades - try - { - for (int i = 0; i < (int) upgradeTypes.size (); ++i) - { - string str = - currentPath + "upgrades/" + upgradeTypes[i].getName (); - - try - { - upgradeTypes[i].load (str, techTree, this, checksum, - techtreeChecksum, loadedFileList, - validationMode); - } - catch (megaglest_runtime_error & ex) - { - if (validationMode == false) - { - throw; - } - else - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, ex.what ()); - } - } - - SDL_PumpEvents (); - } - } - catch (const exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - e.what ()); - throw megaglest_runtime_error ("Error loading upgrades: " + - currentPath + "\n" + e.what ()); - } - - string tmppath = currentPath + factionName + ".xml"; - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "Loading faction xml [%s]\n", - tmppath.c_str ()); - - std::map < string, string > mapExtraTagReplacementValues; - mapExtraTagReplacementValues["$COMMONDATAPATH"] = - techTreePath + "/commondata/"; - //printf("current $COMMONDATAPATH = %s\n",mapExtraTagReplacementValues["$COMMONDATAPATH"].c_str()); - xmlTree.load (tmppath, - Properties:: - getTagReplacementValues - (&mapExtraTagReplacementValues)); - - - factionNode = xmlTree.getRootNode (); - //read starting resources - //printf("factionNode->getName()=%s",factionNode->getName().c_str()); - const XmlNode *startingResourcesNode = - factionNode->getChild ("starting-resources"); - - startingResources.resize (startingResourcesNode->getChildCount ()); - for (int i = 0; i < (int) startingResources.size (); ++i) - { - const XmlNode *resourceNode = - startingResourcesNode->getChild ("resource", i); - string name = - resourceNode->getAttribute ("name")->getRestrictedValue (); - int amount = resourceNode->getAttribute ("amount")->getIntValue (); - - try - { - startingResources[i].init (techTree->getResourceType (name), - amount); - } - catch (megaglest_runtime_error & ex) - { - if (validationMode == false) - { - throw; - } - else - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\nFor FactionType: %s for StartResource: %s\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, ex.what (), - this->name.c_str (), name.c_str ()); - } - } - - SDL_PumpEvents (); - } - - //read starting units - const XmlNode *startingUnitsNode = - factionNode->getChild ("starting-units"); - for (int i = 0; i < (int) startingUnitsNode->getChildCount (); ++i) - { - const XmlNode *unitNode = startingUnitsNode->getChild ("unit", i); - string name = - unitNode->getAttribute ("name")->getRestrictedValue (); - int amount = unitNode->getAttribute ("amount")->getIntValue (); - startingUnits. - push_back (PairPUnitTypeInt (getUnitType (name), amount)); - - SDL_PumpEvents (); - } - - //read music - const XmlNode *musicNode = factionNode->getChild ("music"); - bool value = musicNode->getAttribute ("value")->getBoolValue (); - if (value) - { - music = new StrSound (); - music->open (musicNode->getAttribute ("path")-> - getRestrictedValue (currentPath)); - loadedFileList[musicNode->getAttribute ("path")-> - getRestrictedValue (currentPath)]. - push_back (make_pair - (path, - musicNode->getAttribute ("path")-> - getRestrictedValue ())); - } - - if (factionNode->hasChild ("flat-particle-positions")) - { - const XmlNode *node = - factionNode->getChild ("flat-particle-positions"); - flatParticlePositions = - node->getAttribute ("value")->getBoolValue (); - } - - //healthbar - if (factionNode->hasChild ("healthbar")) - { - const XmlNode *healthbarNode = factionNode->getChild ("healthbar"); - if (healthbarNode->hasChild ("height")) - { - healthbarheight = - healthbarNode->getChild ("height")->getAttribute ("value")-> - getFloatValue (); - } - if (healthbarNode->hasChild ("thickness")) - { - healthbarthickness = - healthbarNode->getChild ("thickness")->getAttribute ("value")-> - getFloatValue (0.f, 1.f); - } - if (healthbarNode->hasChild ("visible")) - { - string healthbarVisibleString = - healthbarNode->getChild ("visible")->getAttribute ("value")-> - getValue (); - vector < string > v = split (healthbarVisibleString, "|"); - for (int i = 0; i < (int) v.size (); ++i) - { - string current = trim (v[i]); - if (current == "always") - { - healthbarVisible = healthbarVisible | hbvAlways; - } - else if (current == "selected") - { - healthbarVisible = healthbarVisible | hbvSelected; - } - else if (current == "ifNeeded") - { - healthbarVisible = healthbarVisible | hbvIfNeeded; - } - else if (current == "off") - { - healthbarVisible = healthbarVisible | hbvOff; - } - else - { - throw - megaglest_runtime_error - ("Unknown Healthbar Visible Option: " + current, true); - } - } - } - if (healthbarNode->hasChild ("borderTexture")) - { - healthbarBorderTextureEnabled = - healthbarNode->getChild ("borderTexture")-> - getAttribute ("enabled")->getBoolValue (); - if (healthbarBorderTextureEnabled - && healthbarNode->getChild ("borderTexture")-> - hasAttribute ("path")) - { - healthbarTexture = - Renderer::getInstance ().newTexture2D (rsGame); - if (healthbarTexture) - { - healthbarTexture->load (healthbarNode-> - getChild ("borderTexture")-> - getAttribute ("path")-> - getRestrictedValue (currentPath)); - } - loadedFileList[healthbarNode->getChild ("borderTexture")-> - getAttribute ("path")-> - getRestrictedValue (currentPath)]. - push_back (make_pair - (path, - healthbarNode->getChild ("borderTexture")-> - getAttribute ("path")->getRestrictedValue ())); - } - } - if (healthbarNode->hasChild ("backgroundTexture")) - { - healthbarBackgroundTextureEnabled = - healthbarNode->getChild ("backgroundTexture")-> - getAttribute ("enabled")->getBoolValue (); - if (healthbarBackgroundTextureEnabled - && healthbarNode->getChild ("backgroundTexture")-> - hasAttribute ("path")) - { - healthbarBackgroundTexture = - Renderer::getInstance ().newTexture2D (rsGame); - if (healthbarBackgroundTexture) - { - healthbarBackgroundTexture->load (healthbarNode-> - getChild - ("backgroundTexture")-> - getAttribute ("path")-> - getRestrictedValue - (currentPath)); - } - loadedFileList[healthbarNode->getChild ("backgroundTexture")-> - getAttribute ("path")-> - getRestrictedValue (currentPath)]. - push_back (make_pair - (path, - healthbarNode->getChild ("backgroundTexture")-> - getAttribute ("path")->getRestrictedValue ())); - } - } - if (healthbarNode->hasChild ("lineBorder")) - { - healthbarLineBorder = - healthbarNode->getChild ("lineBorder")-> - getAttribute ("enabled")->getBoolValue (); - } - - } - - //read ai behavior - if (factionNode->hasChild ("ai-behavior") == true) - { - const XmlNode *aiNode = factionNode->getChild ("ai-behavior"); - if (aiNode->hasAttribute ("min-static-resource-count") == true) - { - mapAIBehaviorStaticOverrideValues[aibsvcMinStaticResourceCount] = - aiNode->getAttribute ("min-static-resource-count")-> - getIntValue (); - } - - if (aiNode->hasChild ("static-values") == true) - { - const XmlNode *aiNodeUnits = aiNode->getChild ("static-values"); - for (int i = 0; i < (int) aiNodeUnits->getChildCount (); ++i) - { - const XmlNode *unitNode = aiNodeUnits->getChild ("static", i); - AIBehaviorStaticValueCategory type = aibsvcMaxBuildRadius; - if (unitNode->hasAttribute ("type") == true) - { - type = - static_cast < AIBehaviorStaticValueCategory > - (unitNode->getAttribute ("type")->getIntValue ()); - } - else - { - type = - EnumParser < - AIBehaviorStaticValueCategory >::getEnum (unitNode-> - getAttribute - ("type-name")-> - getValue ()); - //printf("Discovered overriden static value for AI, type = %d, value = %d\n",type,value); - } - - int value = unitNode->getAttribute ("value")->getIntValue (); - mapAIBehaviorStaticOverrideValues[type] = value; - //printf("Discovered overriden static value for AI, type = %d, value = %d\n",type,value); - } - } - - if (aiNode->hasChild ("worker-units") == true) - { - const XmlNode *aiNodeUnits = aiNode->getChild ("worker-units"); - for (int i = 0; i < (int) aiNodeUnits->getChildCount (); ++i) - { - const XmlNode *unitNode = aiNodeUnits->getChild ("unit", i); - string name = - unitNode->getAttribute ("name")->getRestrictedValue (); - int minimum = - unitNode->getAttribute ("minimum")->getIntValue (); - - mapAIBehaviorUnitCategories[aibcWorkerUnits]. - push_back (PairPUnitTypeInt (getUnitType (name), minimum)); - } - } - if (aiNode->hasChild ("warrior-units") == true) - { - const XmlNode *aiNodeUnits = aiNode->getChild ("warrior-units"); - for (int i = 0; i < (int) aiNodeUnits->getChildCount (); ++i) - { - const XmlNode *unitNode = aiNodeUnits->getChild ("unit", i); - string name = - unitNode->getAttribute ("name")->getRestrictedValue (); - int minimum = - unitNode->getAttribute ("minimum")->getIntValue (); - - mapAIBehaviorUnitCategories[aibcWarriorUnits]. - push_back (PairPUnitTypeInt (getUnitType (name), minimum)); - } - } - if (aiNode->hasChild ("resource-producer-units") == true) - { - const XmlNode *aiNodeUnits = - aiNode->getChild ("resource-producer-units"); - for (int i = 0; i < (int) aiNodeUnits->getChildCount (); ++i) - { - const XmlNode *unitNode = aiNodeUnits->getChild ("unit", i); - string name = - unitNode->getAttribute ("name")->getRestrictedValue (); - int minimum = - unitNode->getAttribute ("minimum")->getIntValue (); - - mapAIBehaviorUnitCategories[aibcResourceProducerUnits]. - push_back (PairPUnitTypeInt (getUnitType (name), minimum)); - } - } - if (aiNode->hasChild ("building-units") == true) - { - const XmlNode *aiNodeUnits = aiNode->getChild ("building-units"); - for (int i = 0; i < (int) aiNodeUnits->getChildCount (); ++i) - { - const XmlNode *unitNode = aiNodeUnits->getChild ("unit", i); - string name = - unitNode->getAttribute ("name")->getRestrictedValue (); - int minimum = - unitNode->getAttribute ("minimum")->getIntValue (); - - mapAIBehaviorUnitCategories[aibcBuildingUnits]. - push_back (PairPUnitTypeInt (getUnitType (name), minimum)); - } - } - - if (aiNode->hasChild ("upgrades") == true) - { - const XmlNode *aiNodeUpgrades = aiNode->getChild ("upgrades"); - for (int i = 0; i < (int) aiNodeUpgrades->getChildCount (); ++i) - { - const XmlNode *upgradeNode = - aiNodeUpgrades->getChild ("upgrade", i); - string name = - upgradeNode->getAttribute ("name")->getRestrictedValue (); - - vctAIBehaviorUpgrades.push_back (getUpgradeType (name)); - } - } - } - } - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } - - int FactionType:: - getAIBehaviorStaticOverideValue (AIBehaviorStaticValueCategory type) - const - { - int result = INT_MAX; - std::map < AIBehaviorStaticValueCategory, - int >::const_iterator iterFind = - mapAIBehaviorStaticOverrideValues.find (type); - if (iterFind != mapAIBehaviorStaticOverrideValues.end ()) - { - result = iterFind->second; - } - return result; - } - - const std::vector < FactionType::PairPUnitTypeInt > - FactionType::getAIBehaviorUnits (AIBehaviorUnitCategory category) const - { - std::map < AIBehaviorUnitCategory, - std::vector < PairPUnitTypeInt > >::const_iterator iterFind = - mapAIBehaviorUnitCategories.find (category); - if (iterFind != mapAIBehaviorUnitCategories.end ()) - { - return iterFind->second; - } - return std::vector < FactionType::PairPUnitTypeInt > (); - } - - FactionType::~FactionType () - { - delete music; - music = NULL; - } - - std::vector < std::string > FactionType::validateFactionType () - { - std::vector < std::string > results; - - const uint32 MAX_BITRATE_WARNING = 200000; - StrSound *factionMusic = getMusic (); - if (factionMusic != NULL - && factionMusic->getInfo ()->getBitRate () > MAX_BITRATE_WARNING) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Faction [%s] has the music [%s]\nwhich has a bitrate of [%u] which may cause some sound drivers to crash, please use a bitrate of %d or less!", - this->getName ().c_str (), - factionMusic->getFileName ().c_str (), - factionMusic->getInfo ()->getBitRate (), - MAX_BITRATE_WARNING); - results.push_back (szBuf); - } - - for (int i = 0; i < (int) unitTypes.size (); ++i) - { - UnitType & unitType = unitTypes[i]; - - for (int i = 0; - i < (int) unitType.getSelectionSounds ().getSounds ().size (); - ++i) - { - StaticSound *sound = unitType.getSelectionSounds ().getSounds ()[i]; - if (sound != NULL - && sound->getInfo ()->getBitRate () > MAX_BITRATE_WARNING) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has the sound [%s]\nwhich has a bitrate of [%u] which may cause some sound drivers to crash, please use a bitrate of %d or less!", - unitType.getName ().c_str (), this->getName ().c_str (), - sound->getFileName ().c_str (), - sound->getInfo ()->getBitRate (), MAX_BITRATE_WARNING); - results.push_back (szBuf); - } - } - for (int i = 0; - i < (int) unitType.getCommandSounds ().getSounds ().size (); ++i) - { - StaticSound *sound = unitType.getCommandSounds ().getSounds ()[i]; - if (sound != NULL - && sound->getInfo ()->getBitRate () > MAX_BITRATE_WARNING) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has the sound [%s]\nwhich has a bitrate of [%u] which may cause some sound drivers to crash, please use a bitrate of %d or less!", - unitType.getName ().c_str (), this->getName ().c_str (), - sound->getFileName ().c_str (), - sound->getInfo ()->getBitRate (), MAX_BITRATE_WARNING); - results.push_back (szBuf); - } - } - - int morphCommandCount = 0; - for (int j = 0; j < (int) unitType.getCommandTypeCount (); ++j) - { - const CommandType *cmdType = unitType.getCommandType (j); - if (cmdType != NULL) - { - // Check every unit's commands to validate that for every upgrade-requirements - // upgrade we have a unit that can do the upgrade in the faction. - for (int k = 0; k < cmdType->getUpgradeReqCount (); ++k) - { - const UpgradeType *upgradeType = cmdType->getUpgradeReq (k); - - if (upgradeType != NULL) - { - // Now lets find a unit that can produced-upgrade this upgrade - bool foundUpgraderUnit = false; - for (int l = 0; - l < (int) unitTypes.size () - && foundUpgraderUnit == false; ++l) - { - UnitType & unitType2 = unitTypes[l]; - for (int m = 0; - m < unitType2.getCommandTypeCount () - && foundUpgraderUnit == false; ++m) - { - const CommandType *cmdType2 = - unitType2.getCommandType (m); - if (cmdType2 != NULL - && dynamic_cast < - const UpgradeCommandType * >(cmdType2) != NULL) - { - const UpgradeCommandType *uct = - dynamic_cast < const UpgradeCommandType * >(cmdType2); - if (uct != NULL) - { - const UpgradeType *upgradeType2 = - uct->getProducedUpgrade (); - if (upgradeType2 != NULL - && upgradeType2->getName () == - upgradeType->getName ()) - { - foundUpgraderUnit = true; - break; - } - } - } - } - } - - if (foundUpgraderUnit == false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has the command [%s]\nwhich has upgrade requirement [%s] but there are no units able to perform the upgrade!", - unitType.getName ().c_str (), - this->getName ().c_str (), - cmdType->getName ().c_str (), - upgradeType->getName ().c_str ()); - results.push_back (szBuf); - } - } - } - - // Ensure for each build type command that the build units - // exist in this faction - if (cmdType->getClass () == ccBuild) - { - const BuildCommandType *build = - dynamic_cast < const BuildCommandType * >(cmdType); - if (build == NULL) - { - throw megaglest_runtime_error ("build == NULL"); - } - for (int k = 0; k < build->getBuildingCount (); ++k) - { - const UnitType *buildUnit = build->getBuilding (k); - - // Now lets find the unit that we should be able to build - bool foundUnit = false; - for (int l = 0; - l < (int) unitTypes.size () && foundUnit == false; ++l) - { - UnitType & unitType2 = unitTypes[l]; - if (unitType2.getName () == buildUnit->getName ()) - { - foundUnit = true; - - // Now also validate the the unit to be built - // has a be_built_skill - if (buildUnit->hasSkillClass (scBeBuilt) == false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has the command [%s]\nwhich can build the Unit [%s] but the Unit to be built\ndoes not have the skill class [be_built_skill] in this faction!", - unitType.getName ().c_str (), - this->getName ().c_str (), - cmdType->getName ().c_str (), - buildUnit->getName ().c_str ()); - results.push_back (szBuf); - } - - break; - } - } - - if (foundUnit == false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has the command [%s]\nwhich can build the Unit [%s] but the Unit to be built does not exist in this faction!", - unitType.getName ().c_str (), - this->getName ().c_str (), - cmdType->getName ().c_str (), - buildUnit->getName ().c_str ()); - results.push_back (szBuf); - } - } - } - // Ensure for each repair type command that the repair units - // exist in this faction - if (cmdType->getClass () == ccRepair) - { - const RepairCommandType *repair = - dynamic_cast < const RepairCommandType * >(cmdType); - if (repair == NULL) - { - throw megaglest_runtime_error ("repair == NULL"); - } - for (int k = 0; k < repair->getRepairCount (); ++k) - { - const UnitType *repairUnit = repair->getRepair (k); - - // Now lets find the unit that we should be able to repair - bool foundUnit = false; - for (int l = 0; - l < (int) unitTypes.size () && foundUnit == false; ++l) - { - UnitType & unitType2 = unitTypes[l]; - if (unitType2.getName () == repairUnit->getName ()) - { - foundUnit = true; - break; - } - } - - if (foundUnit == false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has the command [%s]\nwhich can repair the Unit [%s] but the Unit to be repaired does not exist in this faction!", - unitType.getName ().c_str (), - this->getName ().c_str (), - cmdType->getName ().c_str (), - repairUnit->getName ().c_str ()); - results.push_back (szBuf); - } - } - } - // Ensure for each morph type command that the morph units - // exist in this faction - if (cmdType->getClass () == ccMorph) - { - const MorphCommandType *morph = - dynamic_cast < const MorphCommandType * >(cmdType); - if (morph != NULL) - { - morphCommandCount++; - const UnitType *morphUnit = morph->getMorphUnit (); - - // Now lets find the unit that we should be able to morph - // to - bool foundUnit = false; - for (int l = 0; - l < (int) unitTypes.size () && foundUnit == false; ++l) - { - UnitType & unitType2 = unitTypes[l]; - if (unitType2.getName () == morphUnit->getName ()) - { - foundUnit = true; - break; - } - } - - if (foundUnit == false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has the command [%s]\nwhich can morph into the Unit [%s] but the Unit to be morphed to does not exist in this faction!", - unitType.getName ().c_str (), - this->getName ().c_str (), - cmdType->getName ().c_str (), - morphUnit->getName ().c_str ()); - results.push_back (szBuf); - } - } - } - } - } - - const int maxMorphsAllowed = 6; - if (morphCommandCount > maxMorphsAllowed) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has more than %d morph commands which is too many to display in the UI!", - unitType.getName ().c_str (), this->getName ().c_str (), - maxMorphsAllowed); - results.push_back (szBuf); - } - - // Check every unit's unit requirements to validate that for every unit-requirements - // we have the units required in the faction. - for (int j = 0; j < unitType.getUnitReqCount (); ++j) - { - const UnitType *unitType2 = unitType.getUnitReq (j); - if (unitType2 != NULL) - { - // Now lets find the required unit - bool foundUnit = false; - for (int l = 0; l < (int) unitTypes.size () && foundUnit == false; - ++l) - { - UnitType & unitType3 = unitTypes[l]; - - if (unitType2->getName () == unitType3.getName ()) - { - foundUnit = true; - break; - } - } - - if (foundUnit == false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has the required Unit [%s]\nbut the required unit does not exist in this faction!", - unitType.getName ().c_str (), - this->getName ().c_str (), - unitType2->getName ().c_str ()); - results.push_back (szBuf); - } - } - } - - // Now check that at least 1 other unit can produce, build or morph this unit - bool foundUnit = false; - for (int l = 0; l < (int) unitTypes.size () && foundUnit == false; - ++l) - { - UnitType & unitType2 = unitTypes[l]; - - for (int j = 0; - j < unitType2.getCommandTypeCount () && foundUnit == false; - ++j) - { - const CommandType *cmdType = unitType2.getCommandType (j); - if (cmdType != NULL) - { - // Check if this is a produce command - if (cmdType->getClass () == ccProduce) - { - const ProduceCommandType *produce = - dynamic_cast < const ProduceCommandType * >(cmdType); - if (produce != NULL) - { - const UnitType *produceUnit = produce->getProducedUnit (); - - if (produceUnit != NULL && - unitType.getId () != unitType2.getId () && - unitType.getName () == produceUnit->getName ()) - { - foundUnit = true; - break; - } - } - } - // Check if this is a build command - if (cmdType->getClass () == ccBuild) - { - const BuildCommandType *build = - dynamic_cast < const BuildCommandType * >(cmdType); - if (build == NULL) - { - throw megaglest_runtime_error ("build == NULL"); - } - for (int k = 0; - k < build->getBuildingCount () && foundUnit == false; - ++k) - { - const UnitType *buildUnit = build->getBuilding (k); - - if (buildUnit != NULL && - unitType.getId () != unitType2.getId () && - unitType.getName () == buildUnit->getName ()) - { - foundUnit = true; - break; - } - } - if (foundUnit == true) - { - break; - } - } - // Check if this is a morph command - if (cmdType->getClass () == ccMorph) - { - const MorphCommandType *morph = - dynamic_cast < const MorphCommandType * >(cmdType); - if (morph == NULL) - { - throw megaglest_runtime_error ("morph == NULL"); - } - const UnitType *morphUnit = morph->getMorphUnit (); - - if (morphUnit != NULL && - unitType.getId () != unitType2.getId () && - unitType.getName () == morphUnit->getName ()) - { - foundUnit = true; - break; - } - } - - // Check if this is an attack command with spawned units on attack - if (cmdType->getClass () == ccAttack) - { - const AttackCommandType *act = - dynamic_cast < const AttackCommandType * >(cmdType); - if (act != NULL && act->getAttackSkillType () != NULL - && act->getAttackSkillType ()->getSpawnUnit () != "" - && act->getAttackSkillType ()->getSpawnUnitCount () > 0) - { - - if (unitType.getId () != unitType2.getId () && - unitType.getName () == - act->getAttackSkillType ()->getSpawnUnit ()) - { - foundUnit = true; - break; - } - } - } - } - } - } - - if (foundUnit == false) - { - //printf("Problem for unit [%s] unitTypes.size() = " MG_SIZE_T_SPECIFIER "\n",unitType.getName().c_str(),unitTypes.size()); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has no other units that can produce, build or morph into it in this faction!", - unitType.getName ().c_str (), this->getName ().c_str ()); - results.push_back (szBuf); - } - - // Ensure that all attack skill types have valid values - if (unitType.hasSkillClass (scAttack) == true) - { - for (int j = 0; j < unitType.getSkillTypeCount (); ++j) - { - const SkillType *st = unitType.getSkillType (j); - if (st != NULL - && dynamic_cast < const AttackSkillType * >(st) != NULL) - { - const AttackSkillType *ast = - dynamic_cast < const AttackSkillType * >(st); - if (ast != NULL && ast->getAttackVar () < 0) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has the skill [%s] with an INVALID attack var value which is < 0 [%d]!", - unitType.getName ().c_str (), - this->getName ().c_str (), ast->getName ().c_str (), - ast->getAttackVar ()); - results.push_back (szBuf); - } - } - } - } - // end - - // Check if the unit has both be_built and harvest skills, this may cause issues - // with the AI - if (unitType.hasSkillClass (scBeBuilt) == true - && unitType.hasSkillClass (scHarvest) == true) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has both a bebuilt and harvest skill which will cause AI problems for CPU players!", - unitType.getName ().c_str (), this->getName ().c_str ()); - results.push_back (szBuf); - } - // end - - // Check if the unit has harvest skills but not move, meaning they cannot - // harvest the resource - if (unitType.hasSkillClass (scHarvest) == true - && unitType.hasSkillClass (scMove) == false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has a harvest skill but no move skill so it cannot harvest!", - unitType.getName ().c_str (), this->getName ().c_str ()); - results.push_back (szBuf); - } - // end - - } - - return results; - } - - std::vector < std::string > - FactionType::validateFactionTypeResourceTypes (vector < ResourceType > - &resourceTypes) - { - std::vector < std::string > results; - - for (int i = 0; i < (int) unitTypes.size (); ++i) - { - UnitType & unitType = unitTypes[i]; - - // Check every unit's required resources to validate that for every resource-requirements - // we have a resource in the faction. - for (int j = 0; j < unitType.getCostCount (); ++j) - { - const Resource *r = unitType.getCost (j); - if (r != NULL && r->getType () != NULL) - { - bool foundResourceType = false; - // Now lets find a matching faction resource type for the unit - for (int k = 0; k < (int) resourceTypes.size (); ++k) - { - ResourceType & rt = resourceTypes[k]; - - if (r->getType ()->getName () == rt.getName ()) - { - foundResourceType = true; - break; - } - } - - if (foundResourceType == false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has the resource req [%s]\nbut there are no such resources in this tech!", - unitType.getName ().c_str (), - this->getName ().c_str (), - r->getType ()->getName ().c_str ()); - results.push_back (szBuf); - } - } - } - - // Check every unit's stored resources to validate that for every resources-stored - // we have a resource in the faction. - for (int j = 0; j < unitType.getStoredResourceCount (); ++j) - { - const Resource *r = unitType.getStoredResource (j); - if (r != NULL && r->getType () != NULL) - { - bool foundResourceType = false; - // Now lets find a matching faction resource type for the unit - for (int k = 0; k < (int) resourceTypes.size (); ++k) - { - ResourceType & rt = resourceTypes[k]; - - if (r->getType ()->getName () == rt.getName ()) - { - foundResourceType = true; - break; - } - } - - if (foundResourceType == false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has the stored resource [%s]\nbut there are no such resources in this tech!", - unitType.getName ().c_str (), - this->getName ().c_str (), - r->getType ()->getName ().c_str ()); - results.push_back (szBuf); - } - } - } - - for (int j = 0; j < unitType.getCommandTypeCount (); ++j) - { - const CommandType *cmdType = unitType.getCommandType (j); - if (cmdType != NULL) - { - // Ensure for each harvest type command that the resource - // exist in this faction - if (cmdType->getClass () == ccHarvest) - { - const HarvestCommandType *harvest = - dynamic_cast < const HarvestCommandType * >(cmdType); - if (harvest == NULL) - { - throw megaglest_runtime_error ("harvest == NULL"); - } - for (int k = 0; k < harvest->getHarvestedResourceCount (); ++k) - { - const ResourceType *harvestResource = - harvest->getHarvestedResource (k); - - bool foundResourceType = false; - // Now lets find a matching faction resource type for the unit - for (int k = 0; k < (int) resourceTypes.size (); ++k) - { - ResourceType & rt = resourceTypes[k]; - - if (harvestResource->getName () == rt.getName ()) - { - foundResourceType = true; - break; - } - } - - if (foundResourceType == false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Unit [%s] in Faction [%s] has the command [%s] which can harvest the resource [%s]\nbut there are no such resources in this tech!", - unitType.getName ().c_str (), - this->getName ().c_str (), - cmdType->getName ().c_str (), - harvestResource->getName ().c_str ()); - results.push_back (szBuf); - } - } - } - } - } - } - - return results; - } - - std::vector < std::string > - FactionType::validateFactionTypeUpgradeTypes () - { - std::vector < std::string > results; - - // For each upgrade type make sure there is at least 1 unit that can produce - // the upgrade - for (int i = 0; i < (int) upgradeTypes.size (); ++i) - { - const UpgradeType & upgradeType = upgradeTypes[i]; - - // First find a unit with a command type to upgrade to this Upgrade type - bool foundUnit = false; - for (int j = 0; j < (int) unitTypes.size () && foundUnit == false; - ++j) - { - UnitType & unitType = unitTypes[j]; - for (int k = 0; - k < unitType.getCommandTypeCount () && foundUnit == false; ++k) - { - const CommandType *cmdType = unitType.getCommandType (k); - if (cmdType != NULL) - { - // Ensure for each build type command that the build units - // exist in this faction - if (cmdType->getClass () == ccUpgrade) - { - const UpgradeCommandType *upgrade = - dynamic_cast < const UpgradeCommandType * >(cmdType); - if (upgrade != NULL) - { - const UpgradeType *upgradeType2 = - upgrade->getProducedUpgrade (); - - if (upgradeType2 != NULL - && upgradeType.getName () == upgradeType2->getName ()) - { - foundUnit = true; - break; - } - } - } - } - } - } - - if (foundUnit == false) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Upgrade Type [%s] in Faction [%s] has no Unit able to produce this upgrade in this faction!", - upgradeType.getName ().c_str (), - this->getName ().c_str ()); - results.push_back (szBuf); - } - } - - return results; - } - -// ==================== get ==================== - - const UnitType *FactionType::getUnitType (const string & name) const - { - for (int i = 0; i < (int) unitTypes.size (); i++) - { - if (unitTypes[i].getName (false) == name) - { - return &unitTypes[i]; - } - } - - printf ("In [%s::%s Line: %d] scanning [%s] size = " MG_SIZE_T_SPECIFIER - "\n", extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, name.c_str (), unitTypes.size ()); - for (int i = 0; i < (int) unitTypes.size (); i++) - { - printf ("In [%s::%s Line: %d] scanning [%s] idx = %d [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, name.c_str (), i, - unitTypes[i].getName (false).c_str ()); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] scanning [%s] size = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - name.c_str (), unitTypes.size ()); - for (int i = 0; i < (int) unitTypes.size (); i++) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] scanning [%s] idx = %d [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - name.c_str (), i, - unitTypes[i].getName (false).c_str ()); - } - - throw megaglest_runtime_error ("Unit type not found: [" + name + - "] in faction type [" + this->name + "]", - true); - } - -//const UnitType *FactionType::getUnitTypeById(int id) const{ -// for(int i=0; i < (int)unitTypes.size();i++){ -// if(unitTypes[i].getId() == id) { -// return &unitTypes[i]; -// } -// } -// -// printf("In [%s::%s Line: %d] scanning [%d] size = " MG_SIZE_T_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,id,unitTypes.size()); -// for(int i=0; i < (int)unitTypes.size();i++){ -// printf("In [%s::%s Line: %d] scanning [%s] idx = %d [%s][%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,name.c_str(),i,unitTypes[i].getName(false).c_str(),unitTypes[i].getId()); -// } -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning [%s] size = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,name.c_str(),unitTypes.size()); -// for(int i=0; i < (int)unitTypes.size();i++){ -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning [%s] idx = %d [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,name.c_str(),i,unitTypes[i].getName(false).c_str()); -// } -// -// throw megaglest_runtime_error("Unit type not found: [" + intToStr(id) + "] in faction type [" + this->name + "]",true); -//} - - const UpgradeType *FactionType::getUpgradeType (const string & name) const - { - for (int i = 0; i < (int) upgradeTypes.size (); i++) - { - if (upgradeTypes[i].getName () == name) - { - return &upgradeTypes[i]; - } - } - - printf ("In [%s::%s Line: %d] scanning [%s] size = " MG_SIZE_T_SPECIFIER - "\n", extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, name.c_str (), unitTypes.size ()); - for (int i = 0; i < (int) upgradeTypes.size (); i++) - { - printf ("In [%s::%s Line: %d] scanning [%s] idx = %d [%s]\n", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, name.c_str (), i, - upgradeTypes[i].getName ().c_str ()); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] scanning [%s] size = %d\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - name.c_str (), unitTypes.size ()); - for (int i = 0; i < (int) upgradeTypes.size (); i++) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d] scanning [%s] idx = %d [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - name.c_str (), i, - upgradeTypes[i].getName ().c_str ()); - } - - throw megaglest_runtime_error ("Upgrade type not found: [" + name + - "] in faction type [" + this->name + "]", - true); - } - - int FactionType::getStartingResourceAmount (const ResourceType * - resourceType) const - { - for (int i = 0; i < (int) startingResources.size (); ++i) - { - if (startingResources[i].getType () == resourceType) - { - return startingResources[i].getAmount (); - } - } - return 0; - } - - void FactionType::deletePixels () - { - for (int i = 0; i < (int) unitTypes.size (); ++i) - { - UnitType & unitType = unitTypes[i]; - Texture2D *texture = unitType.getMeetingPointImage (); - if (texture != NULL) - { - texture->deletePixels (); - } - } - } - - bool FactionType::factionUsesResourceType (const ResourceType * rt) const - { - bool factionUsesResourceType = false; - if (rt != NULL) - { - for (unsigned int j = 0; - factionUsesResourceType == false - && j < (unsigned int) this->getUnitTypeCount (); ++j) - { - const UnitType *ut = this->getUnitType (j); - for (int k = 0; - factionUsesResourceType == false && k < ut->getCostCount (); - ++k) - { - const Resource *costResource = ut->getCost (k); - //printf("#1 factionUsesResourceType, unit [%s] resource [%s] cost [%s]\n",ut->getName().c_str(),rt->getName().c_str(),costResource->getType()->getName().c_str()); - - if (costResource != NULL && costResource->getType () != NULL && - costResource->getType ()->getName () == rt->getName ()) - { - factionUsesResourceType = true; - break; - } - } - if (factionUsesResourceType == false) - { - for (unsigned int k = 0; - factionUsesResourceType == false - && k < (unsigned int) ut->getCommandTypeCount (); ++k) - { - const CommandType *commandType = ut->getCommandType (k); - if (commandType != NULL - && commandType->getClass () == ccHarvest) - { - const HarvestCommandType *hct = - dynamic_cast < const HarvestCommandType * >(commandType); - if (hct != NULL && hct->getHarvestedResourceCount () > 0) - { - for (unsigned int l = 0; - factionUsesResourceType == false - && l < - (unsigned int) hct->getHarvestedResourceCount (); ++l) - { - //printf("#2 factionUsesResourceType, unit [%s] resource [%s] harvest [%s]\n",ut->getName().c_str(),rt->getName().c_str(),hct->getHarvestedResource(l)->getName().c_str()); - - if (hct->getHarvestedResource (l)->getName () == - rt->getName ()) - { - factionUsesResourceType = true; - break; - } - } - } - } - } - } - } - } - return factionUsesResourceType; - } - - std::string FactionType::toString ()const - { - std::string result = "Faction Name: " + name + "\n"; - - result += - "Unit Type List count = " + intToStr (this->getUnitTypeCount ()) + - "\n"; - for (int i = 0; i < (int) unitTypes.size (); i++) - { - result += unitTypes[i].toString () + "\n"; - } - - result += - "Upgrade Type List count = " + - intToStr (this->getUpgradeTypeCount ()) + "\n"; - for (int i = 0; i < (int) upgradeTypes.size (); i++) - { - result += - "index: " + intToStr (i) + " " + - upgradeTypes[i].getReqDesc (false) + "\n"; - } - - return result; - } - - string FactionType::getName (bool translatedValue) const - { - if (translatedValue == false) - return name; - - Lang & lang = Lang::getInstance (); - return lang.getTechTreeString ("FactionName_" + name, name.c_str ()); - } - - - } +namespace Glest { + namespace Game { + + // ====================================================== + // Class FactionType + // ====================================================== + + FactionType::FactionType() { + music = NULL; + personalityType = fpt_Normal; + isLinked = false; + healthbarheight = -100.0f; + healthbarthickness = 0.11f; + healthbarVisible = hbvUndefined; + healthbarBorderTextureEnabled = false; + healthbarBackgroundTextureEnabled = false; + healthbarLineBorder = true; + healthbarTexture = NULL; + healthbarBackgroundTexture = NULL; + flatParticlePositions = false; + } + + //load a faction, given a directory + void FactionType::load(const string & factionName, + const TechTree * techTree, Checksum * checksum, + Checksum * techtreeChecksum, std::map < string, + vector < pair < string, + string > > >&loadedFileList, bool validationMode) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + string techTreePath = techTree->getPath(); + string techTreeName = techTree->getNameUntranslated(); + string currentPath = ""; + + //open xml file + string path = ""; + XmlTree xmlTree; + const XmlNode *factionNode; + + //printf("\n>>> factionname=%s\n",factionName.c_str()); + for (bool realFactionPathFound = false; realFactionPathFound == false;) { + currentPath = techTreePath + "factions/" + factionName; + endPathWithSlash(currentPath); + + name = lastDir(currentPath); + + // Add special Observer Faction + //Lang &lang= Lang::getInstance(); + if (name == formatString(GameConstants::OBSERVER_SLOTNAME)) { + personalityType = fpt_Observer; + } + + if (personalityType == fpt_Normal) { + string tmppath = currentPath + factionName + ".xml"; + std::map < string, string > mapExtraTagReplacementValues; + // mapExtraTagReplacementValues["$COMMONDATAPATH"] = techTreePath + "/commondata/"; + //printf("current $COMMONDATAPATH = %s\n",mapExtraTagReplacementValues["$COMMONDATAPATH"].c_str()); + XmlTree xmlTree; + xmlTree.load(tmppath, + Properties:: + getTagReplacementValues + (&mapExtraTagReplacementValues)); + + + const XmlNode *rootNode = xmlTree.getRootNode(); + + if (rootNode->getName() == "link") { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "Faction [%s] is a linked faction\n", + name.c_str()); + + isLinked = true; + const XmlNode *techTreeNode = rootNode->getChild("techtree"); + const string linkedTechTreeName = + techTreeNode->getAttribute("name")->getRestrictedValue(); + // const XmlNode *factionLinkNode= rootNode->getChild("faction"); + // string linkedFactionName=factionLinkNode->getAttribute("name")->getRestrictedValue(); + string linkedTechTreePath = + techTree->findPath(linkedTechTreeName); + techTreePath = linkedTechTreePath; + endPathWithSlash(techTreePath); + techTreeName = linkedTechTreeName; + + string linkedCurrentPath = + techTreePath + "factions/" + factionName; + endPathWithSlash(linkedCurrentPath); + string linkedTmppath = linkedCurrentPath + factionName + ".xml"; + + //printf("linkedTmppath [%s] linkedCurrentPath [%s]\n",linkedTmppath.c_str(),linkedCurrentPath.c_str()); + + loadedFileList[linkedTmppath]. + push_back(make_pair(linkedCurrentPath, linkedCurrentPath)); + loadedFileList[tmppath]. + push_back(make_pair(currentPath, currentPath)); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "techTreePath [%s] techTreeName [%s]\n", + techTreePath.c_str(), + techTreeName.c_str()); + } else { + // stop looking for new path, no more links ... + //xmlTree.load(tmppath, Properties::getTagReplacementValues(&mapExtraTagReplacementValues)); + + loadedFileList[tmppath]. + push_back(make_pair(currentPath, currentPath)); + + realFactionPathFound = true; + //printf("techPath found! %s\n",tmppath.c_str()); + + path = tmppath; + } + } else { + break; + } + } + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + Lang::getInstance(). + getString("LogScreenGameLoadingFactionType", "", + true).c_str(), + formatString(this->getName()).c_str()); + Logger::getInstance().add(szBuf, true); + + if (personalityType == fpt_Normal) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "Loading faction [%s] currentPath [%s]\n", + path.c_str(), currentPath.c_str()); + + checksum->addFile(path); + techtreeChecksum->addFile(path); + + // a1) preload units + //string unitsPath= currentPath + "units/*."; + string unitsPath = currentPath + "units/"; + vector < string > unitFilenames; + //findAll(unitsPath, unitFilenames); + findDirs(unitsPath, unitFilenames, false, false); + + unitTypes.resize(unitFilenames.size()); + + for (int i = 0; i < (int) unitTypes.size(); ++i) { + string str = currentPath + "units/" + unitFilenames[i]; + unitTypes[i].preLoad(str); + + SDL_PumpEvents(); + } + + // a2) preload upgrades + //string upgradesPath= currentPath + "upgrades/*."; + string upgradesPath = currentPath + "upgrades/"; + vector < string > upgradeFilenames; + //findAll(upgradesPath, upgradeFilenames, false, false); + findDirs(upgradesPath, upgradeFilenames, false, false); + + upgradeTypes.resize(upgradeFilenames.size()); + for (int i = 0; i < (int) upgradeTypes.size(); ++i) { + string str = currentPath + "upgrades/" + upgradeFilenames[i]; + upgradeTypes[i].preLoad(str); + + SDL_PumpEvents(); + } + + // b1) load units + try { + Logger & logger = Logger::getInstance(); + int progressBaseValue = logger.getProgress(); + for (int i = 0; i < (int) unitTypes.size(); ++i) { + string str = currentPath + "units/" + unitTypes[i].getName(); + + try { + unitTypes[i].loaddd(i, str, techTree, techTreePath, this, + checksum, techtreeChecksum, loadedFileList, + validationMode); + logger.setProgress(progressBaseValue + + (int) ((((double) i + + 1.0) / + (double) unitTypes.size()) * + 100.0 / techTree->getTypeCount())); + SDL_PumpEvents(); + } catch (megaglest_runtime_error & ex) { + if (validationMode == false) { + throw; + } else { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, ex.what()); + } + } + } + } catch (megaglest_runtime_error & ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + ex.what()); + throw megaglest_runtime_error("Error loading units: " + + currentPath + "\nMessage: " + + ex.what(), !ex.wantStackTrace()); + } catch (const exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + e.what()); + throw megaglest_runtime_error("Error loading units: " + + currentPath + "\nMessage: " + + e.what()); + } + + // b2) load upgrades + try { + for (int i = 0; i < (int) upgradeTypes.size(); ++i) { + string str = + currentPath + "upgrades/" + upgradeTypes[i].getName(); + + try { + upgradeTypes[i].load(str, techTree, this, checksum, + techtreeChecksum, loadedFileList, + validationMode); + } catch (megaglest_runtime_error & ex) { + if (validationMode == false) { + throw; + } else { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, ex.what()); + } + } + + SDL_PumpEvents(); + } + } catch (const exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + e.what()); + throw megaglest_runtime_error("Error loading upgrades: " + + currentPath + "\n" + e.what()); + } + + string tmppath = currentPath + factionName + ".xml"; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "Loading faction xml [%s]\n", + tmppath.c_str()); + + std::map < string, string > mapExtraTagReplacementValues; + mapExtraTagReplacementValues["$COMMONDATAPATH"] = + techTreePath + "/commondata/"; + //printf("current $COMMONDATAPATH = %s\n",mapExtraTagReplacementValues["$COMMONDATAPATH"].c_str()); + xmlTree.load(tmppath, + Properties:: + getTagReplacementValues + (&mapExtraTagReplacementValues)); + + + factionNode = xmlTree.getRootNode(); + //read starting resources + //printf("factionNode->getName()=%s",factionNode->getName().c_str()); + const XmlNode *startingResourcesNode = + factionNode->getChild("starting-resources"); + + startingResources.resize(startingResourcesNode->getChildCount()); + for (int i = 0; i < (int) startingResources.size(); ++i) { + const XmlNode *resourceNode = + startingResourcesNode->getChild("resource", i); + string name = + resourceNode->getAttribute("name")->getRestrictedValue(); + int amount = resourceNode->getAttribute("amount")->getIntValue(); + + try { + startingResources[i].init(techTree->getResourceType(name), + amount); + } catch (megaglest_runtime_error & ex) { + if (validationMode == false) { + throw; + } else { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\nFor FactionType: %s for StartResource: %s\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, ex.what(), + this->name.c_str(), name.c_str()); + } + } + + SDL_PumpEvents(); + } + + //read starting units + const XmlNode *startingUnitsNode = + factionNode->getChild("starting-units"); + for (int i = 0; i < (int) startingUnitsNode->getChildCount(); ++i) { + const XmlNode *unitNode = startingUnitsNode->getChild("unit", i); + string name = + unitNode->getAttribute("name")->getRestrictedValue(); + int amount = unitNode->getAttribute("amount")->getIntValue(); + startingUnits. + push_back(PairPUnitTypeInt(getUnitType(name), amount)); + + SDL_PumpEvents(); + } + + //read music + const XmlNode *musicNode = factionNode->getChild("music"); + bool value = musicNode->getAttribute("value")->getBoolValue(); + if (value) { + music = new StrSound(); + music->open(musicNode->getAttribute("path")-> + getRestrictedValue(currentPath)); + loadedFileList[musicNode->getAttribute("path")-> + getRestrictedValue(currentPath)]. + push_back(make_pair + (path, + musicNode->getAttribute("path")-> + getRestrictedValue())); + } + + if (factionNode->hasChild("flat-particle-positions")) { + const XmlNode *node = + factionNode->getChild("flat-particle-positions"); + flatParticlePositions = + node->getAttribute("value")->getBoolValue(); + } + + //healthbar + if (factionNode->hasChild("healthbar")) { + const XmlNode *healthbarNode = factionNode->getChild("healthbar"); + if (healthbarNode->hasChild("height")) { + healthbarheight = + healthbarNode->getChild("height")->getAttribute("value")-> + getFloatValue(); + } + if (healthbarNode->hasChild("thickness")) { + healthbarthickness = + healthbarNode->getChild("thickness")->getAttribute("value")-> + getFloatValue(0.f, 1.f); + } + if (healthbarNode->hasChild("visible")) { + string healthbarVisibleString = + healthbarNode->getChild("visible")->getAttribute("value")-> + getValue(); + vector < string > v = split(healthbarVisibleString, "|"); + for (int i = 0; i < (int) v.size(); ++i) { + string current = trim(v[i]); + if (current == "always") { + healthbarVisible = healthbarVisible | hbvAlways; + } else if (current == "selected") { + healthbarVisible = healthbarVisible | hbvSelected; + } else if (current == "ifNeeded") { + healthbarVisible = healthbarVisible | hbvIfNeeded; + } else if (current == "off") { + healthbarVisible = healthbarVisible | hbvOff; + } else { + throw + megaglest_runtime_error + ("Unknown Healthbar Visible Option: " + current, true); + } + } + } + if (healthbarNode->hasChild("borderTexture")) { + healthbarBorderTextureEnabled = + healthbarNode->getChild("borderTexture")-> + getAttribute("enabled")->getBoolValue(); + if (healthbarBorderTextureEnabled + && healthbarNode->getChild("borderTexture")-> + hasAttribute("path")) { + healthbarTexture = + Renderer::getInstance().newTexture2D(rsGame); + if (healthbarTexture) { + healthbarTexture->load(healthbarNode-> + getChild("borderTexture")-> + getAttribute("path")-> + getRestrictedValue(currentPath)); + } + loadedFileList[healthbarNode->getChild("borderTexture")-> + getAttribute("path")-> + getRestrictedValue(currentPath)]. + push_back(make_pair + (path, + healthbarNode->getChild("borderTexture")-> + getAttribute("path")->getRestrictedValue())); + } + } + if (healthbarNode->hasChild("backgroundTexture")) { + healthbarBackgroundTextureEnabled = + healthbarNode->getChild("backgroundTexture")-> + getAttribute("enabled")->getBoolValue(); + if (healthbarBackgroundTextureEnabled + && healthbarNode->getChild("backgroundTexture")-> + hasAttribute("path")) { + healthbarBackgroundTexture = + Renderer::getInstance().newTexture2D(rsGame); + if (healthbarBackgroundTexture) { + healthbarBackgroundTexture->load(healthbarNode-> + getChild + ("backgroundTexture")-> + getAttribute("path")-> + getRestrictedValue + (currentPath)); + } + loadedFileList[healthbarNode->getChild("backgroundTexture")-> + getAttribute("path")-> + getRestrictedValue(currentPath)]. + push_back(make_pair + (path, + healthbarNode->getChild("backgroundTexture")-> + getAttribute("path")->getRestrictedValue())); + } + } + if (healthbarNode->hasChild("lineBorder")) { + healthbarLineBorder = + healthbarNode->getChild("lineBorder")-> + getAttribute("enabled")->getBoolValue(); + } + + } + + //read ai behavior + if (factionNode->hasChild("ai-behavior") == true) { + const XmlNode *aiNode = factionNode->getChild("ai-behavior"); + if (aiNode->hasAttribute("min-static-resource-count") == true) { + mapAIBehaviorStaticOverrideValues[aibsvcMinStaticResourceCount] = + aiNode->getAttribute("min-static-resource-count")-> + getIntValue(); + } + + if (aiNode->hasChild("static-values") == true) { + const XmlNode *aiNodeUnits = aiNode->getChild("static-values"); + for (int i = 0; i < (int) aiNodeUnits->getChildCount(); ++i) { + const XmlNode *unitNode = aiNodeUnits->getChild("static", i); + AIBehaviorStaticValueCategory type = aibsvcMaxBuildRadius; + if (unitNode->hasAttribute("type") == true) { + type = + static_cast + (unitNode->getAttribute("type")->getIntValue()); + } else { + type = + EnumParser < + AIBehaviorStaticValueCategory >::getEnum(unitNode-> + getAttribute + ("type-name")-> + getValue()); + //printf("Discovered overriden static value for AI, type = %d, value = %d\n",type,value); + } + + int value = unitNode->getAttribute("value")->getIntValue(); + mapAIBehaviorStaticOverrideValues[type] = value; + //printf("Discovered overriden static value for AI, type = %d, value = %d\n",type,value); + } + } + + if (aiNode->hasChild("worker-units") == true) { + const XmlNode *aiNodeUnits = aiNode->getChild("worker-units"); + for (int i = 0; i < (int) aiNodeUnits->getChildCount(); ++i) { + const XmlNode *unitNode = aiNodeUnits->getChild("unit", i); + string name = + unitNode->getAttribute("name")->getRestrictedValue(); + int minimum = + unitNode->getAttribute("minimum")->getIntValue(); + + mapAIBehaviorUnitCategories[aibcWorkerUnits]. + push_back(PairPUnitTypeInt(getUnitType(name), minimum)); + } + } + if (aiNode->hasChild("warrior-units") == true) { + const XmlNode *aiNodeUnits = aiNode->getChild("warrior-units"); + for (int i = 0; i < (int) aiNodeUnits->getChildCount(); ++i) { + const XmlNode *unitNode = aiNodeUnits->getChild("unit", i); + string name = + unitNode->getAttribute("name")->getRestrictedValue(); + int minimum = + unitNode->getAttribute("minimum")->getIntValue(); + + mapAIBehaviorUnitCategories[aibcWarriorUnits]. + push_back(PairPUnitTypeInt(getUnitType(name), minimum)); + } + } + if (aiNode->hasChild("resource-producer-units") == true) { + const XmlNode *aiNodeUnits = + aiNode->getChild("resource-producer-units"); + for (int i = 0; i < (int) aiNodeUnits->getChildCount(); ++i) { + const XmlNode *unitNode = aiNodeUnits->getChild("unit", i); + string name = + unitNode->getAttribute("name")->getRestrictedValue(); + int minimum = + unitNode->getAttribute("minimum")->getIntValue(); + + mapAIBehaviorUnitCategories[aibcResourceProducerUnits]. + push_back(PairPUnitTypeInt(getUnitType(name), minimum)); + } + } + if (aiNode->hasChild("building-units") == true) { + const XmlNode *aiNodeUnits = aiNode->getChild("building-units"); + for (int i = 0; i < (int) aiNodeUnits->getChildCount(); ++i) { + const XmlNode *unitNode = aiNodeUnits->getChild("unit", i); + string name = + unitNode->getAttribute("name")->getRestrictedValue(); + int minimum = + unitNode->getAttribute("minimum")->getIntValue(); + + mapAIBehaviorUnitCategories[aibcBuildingUnits]. + push_back(PairPUnitTypeInt(getUnitType(name), minimum)); + } + } + + if (aiNode->hasChild("upgrades") == true) { + const XmlNode *aiNodeUpgrades = aiNode->getChild("upgrades"); + for (int i = 0; i < (int) aiNodeUpgrades->getChildCount(); ++i) { + const XmlNode *upgradeNode = + aiNodeUpgrades->getChild("upgrade", i); + string name = + upgradeNode->getAttribute("name")->getRestrictedValue(); + + vctAIBehaviorUpgrades.push_back(getUpgradeType(name)); + } + } + } + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } + + int FactionType:: + getAIBehaviorStaticOverideValue(AIBehaviorStaticValueCategory type) + const { + int result = INT_MAX; + std::map < AIBehaviorStaticValueCategory, + int >::const_iterator iterFind = + mapAIBehaviorStaticOverrideValues.find(type); + if (iterFind != mapAIBehaviorStaticOverrideValues.end()) { + result = iterFind->second; + } + return result; + } + + const std::vector < FactionType::PairPUnitTypeInt > + FactionType::getAIBehaviorUnits(AIBehaviorUnitCategory category) const { + std::map < AIBehaviorUnitCategory, + std::vector < PairPUnitTypeInt > >::const_iterator iterFind = + mapAIBehaviorUnitCategories.find(category); + if (iterFind != mapAIBehaviorUnitCategories.end()) { + return iterFind->second; + } + return std::vector < FactionType::PairPUnitTypeInt >(); + } + + FactionType::~FactionType() { + delete music; + music = NULL; + } + + std::vector < std::string > FactionType::validateFactionType() { + std::vector < std::string > results; + + const uint32 MAX_BITRATE_WARNING = 200000; + StrSound *factionMusic = getMusic(); + if (factionMusic != NULL + && factionMusic->getInfo()->getBitRate() > MAX_BITRATE_WARNING) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Faction [%s] has the music [%s]\nwhich has a bitrate of [%u] which may cause some sound drivers to crash, please use a bitrate of %d or less!", + this->getName().c_str(), + factionMusic->getFileName().c_str(), + factionMusic->getInfo()->getBitRate(), + MAX_BITRATE_WARNING); + results.push_back(szBuf); + } + + for (int i = 0; i < (int) unitTypes.size(); ++i) { + UnitType & unitType = unitTypes[i]; + + for (int i = 0; + i < (int) unitType.getSelectionSounds().getSounds().size(); + ++i) { + StaticSound *sound = unitType.getSelectionSounds().getSounds()[i]; + if (sound != NULL + && sound->getInfo()->getBitRate() > MAX_BITRATE_WARNING) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has the sound [%s]\nwhich has a bitrate of [%u] which may cause some sound drivers to crash, please use a bitrate of %d or less!", + unitType.getName().c_str(), this->getName().c_str(), + sound->getFileName().c_str(), + sound->getInfo()->getBitRate(), MAX_BITRATE_WARNING); + results.push_back(szBuf); + } + } + for (int i = 0; + i < (int) unitType.getCommandSounds().getSounds().size(); ++i) { + StaticSound *sound = unitType.getCommandSounds().getSounds()[i]; + if (sound != NULL + && sound->getInfo()->getBitRate() > MAX_BITRATE_WARNING) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has the sound [%s]\nwhich has a bitrate of [%u] which may cause some sound drivers to crash, please use a bitrate of %d or less!", + unitType.getName().c_str(), this->getName().c_str(), + sound->getFileName().c_str(), + sound->getInfo()->getBitRate(), MAX_BITRATE_WARNING); + results.push_back(szBuf); + } + } + + int morphCommandCount = 0; + for (int j = 0; j < (int) unitType.getCommandTypeCount(); ++j) { + const CommandType *cmdType = unitType.getCommandType(j); + if (cmdType != NULL) { + // Check every unit's commands to validate that for every upgrade-requirements + // upgrade we have a unit that can do the upgrade in the faction. + for (int k = 0; k < cmdType->getUpgradeReqCount(); ++k) { + const UpgradeType *upgradeType = cmdType->getUpgradeReq(k); + + if (upgradeType != NULL) { + // Now lets find a unit that can produced-upgrade this upgrade + bool foundUpgraderUnit = false; + for (int l = 0; + l < (int) unitTypes.size() + && foundUpgraderUnit == false; ++l) { + UnitType & unitType2 = unitTypes[l]; + for (int m = 0; + m < unitType2.getCommandTypeCount() + && foundUpgraderUnit == false; ++m) { + const CommandType *cmdType2 = + unitType2.getCommandType(m); + if (cmdType2 != NULL + && dynamic_cast < + const UpgradeCommandType *>(cmdType2) != NULL) { + const UpgradeCommandType *uct = + dynamic_cast (cmdType2); + if (uct != NULL) { + const UpgradeType *upgradeType2 = + uct->getProducedUpgrade(); + if (upgradeType2 != NULL + && upgradeType2->getName() == + upgradeType->getName()) { + foundUpgraderUnit = true; + break; + } + } + } + } + } + + if (foundUpgraderUnit == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has the command [%s]\nwhich has upgrade requirement [%s] but there are no units able to perform the upgrade!", + unitType.getName().c_str(), + this->getName().c_str(), + cmdType->getName().c_str(), + upgradeType->getName().c_str()); + results.push_back(szBuf); + } + } + } + + // Ensure for each build type command that the build units + // exist in this faction + if (cmdType->getClass() == ccBuild) { + const BuildCommandType *build = + dynamic_cast (cmdType); + if (build == NULL) { + throw megaglest_runtime_error("build == NULL"); + } + for (int k = 0; k < build->getBuildingCount(); ++k) { + const UnitType *buildUnit = build->getBuilding(k); + + // Now lets find the unit that we should be able to build + bool foundUnit = false; + for (int l = 0; + l < (int) unitTypes.size() && foundUnit == false; ++l) { + UnitType & unitType2 = unitTypes[l]; + if (unitType2.getName() == buildUnit->getName()) { + foundUnit = true; + + // Now also validate the the unit to be built + // has a be_built_skill + if (buildUnit->hasSkillClass(scBeBuilt) == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has the command [%s]\nwhich can build the Unit [%s] but the Unit to be built\ndoes not have the skill class [be_built_skill] in this faction!", + unitType.getName().c_str(), + this->getName().c_str(), + cmdType->getName().c_str(), + buildUnit->getName().c_str()); + results.push_back(szBuf); + } + + break; + } + } + + if (foundUnit == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has the command [%s]\nwhich can build the Unit [%s] but the Unit to be built does not exist in this faction!", + unitType.getName().c_str(), + this->getName().c_str(), + cmdType->getName().c_str(), + buildUnit->getName().c_str()); + results.push_back(szBuf); + } + } + } + // Ensure for each repair type command that the repair units + // exist in this faction + if (cmdType->getClass() == ccRepair) { + const RepairCommandType *repair = + dynamic_cast (cmdType); + if (repair == NULL) { + throw megaglest_runtime_error("repair == NULL"); + } + for (int k = 0; k < repair->getRepairCount(); ++k) { + const UnitType *repairUnit = repair->getRepair(k); + + // Now lets find the unit that we should be able to repair + bool foundUnit = false; + for (int l = 0; + l < (int) unitTypes.size() && foundUnit == false; ++l) { + UnitType & unitType2 = unitTypes[l]; + if (unitType2.getName() == repairUnit->getName()) { + foundUnit = true; + break; + } + } + + if (foundUnit == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has the command [%s]\nwhich can repair the Unit [%s] but the Unit to be repaired does not exist in this faction!", + unitType.getName().c_str(), + this->getName().c_str(), + cmdType->getName().c_str(), + repairUnit->getName().c_str()); + results.push_back(szBuf); + } + } + } + // Ensure for each morph type command that the morph units + // exist in this faction + if (cmdType->getClass() == ccMorph) { + const MorphCommandType *morph = + dynamic_cast (cmdType); + if (morph != NULL) { + morphCommandCount++; + const UnitType *morphUnit = morph->getMorphUnit(); + + // Now lets find the unit that we should be able to morph + // to + bool foundUnit = false; + for (int l = 0; + l < (int) unitTypes.size() && foundUnit == false; ++l) { + UnitType & unitType2 = unitTypes[l]; + if (unitType2.getName() == morphUnit->getName()) { + foundUnit = true; + break; + } + } + + if (foundUnit == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has the command [%s]\nwhich can morph into the Unit [%s] but the Unit to be morphed to does not exist in this faction!", + unitType.getName().c_str(), + this->getName().c_str(), + cmdType->getName().c_str(), + morphUnit->getName().c_str()); + results.push_back(szBuf); + } + } + } + } + } + + const int maxMorphsAllowed = 6; + if (morphCommandCount > maxMorphsAllowed) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has more than %d morph commands which is too many to display in the UI!", + unitType.getName().c_str(), this->getName().c_str(), + maxMorphsAllowed); + results.push_back(szBuf); + } + + // Check every unit's unit requirements to validate that for every unit-requirements + // we have the units required in the faction. + for (int j = 0; j < unitType.getUnitReqCount(); ++j) { + const UnitType *unitType2 = unitType.getUnitReq(j); + if (unitType2 != NULL) { + // Now lets find the required unit + bool foundUnit = false; + for (int l = 0; l < (int) unitTypes.size() && foundUnit == false; + ++l) { + UnitType & unitType3 = unitTypes[l]; + + if (unitType2->getName() == unitType3.getName()) { + foundUnit = true; + break; + } + } + + if (foundUnit == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has the required Unit [%s]\nbut the required unit does not exist in this faction!", + unitType.getName().c_str(), + this->getName().c_str(), + unitType2->getName().c_str()); + results.push_back(szBuf); + } + } + } + + // Now check that at least 1 other unit can produce, build or morph this unit + bool foundUnit = false; + for (int l = 0; l < (int) unitTypes.size() && foundUnit == false; + ++l) { + UnitType & unitType2 = unitTypes[l]; + + for (int j = 0; + j < unitType2.getCommandTypeCount() && foundUnit == false; + ++j) { + const CommandType *cmdType = unitType2.getCommandType(j); + if (cmdType != NULL) { + // Check if this is a produce command + if (cmdType->getClass() == ccProduce) { + const ProduceCommandType *produce = + dynamic_cast (cmdType); + if (produce != NULL) { + const UnitType *produceUnit = produce->getProducedUnit(); + + if (produceUnit != NULL && + unitType.getId() != unitType2.getId() && + unitType.getName() == produceUnit->getName()) { + foundUnit = true; + break; + } + } + } + // Check if this is a build command + if (cmdType->getClass() == ccBuild) { + const BuildCommandType *build = + dynamic_cast (cmdType); + if (build == NULL) { + throw megaglest_runtime_error("build == NULL"); + } + for (int k = 0; + k < build->getBuildingCount() && foundUnit == false; + ++k) { + const UnitType *buildUnit = build->getBuilding(k); + + if (buildUnit != NULL && + unitType.getId() != unitType2.getId() && + unitType.getName() == buildUnit->getName()) { + foundUnit = true; + break; + } + } + if (foundUnit == true) { + break; + } + } + // Check if this is a morph command + if (cmdType->getClass() == ccMorph) { + const MorphCommandType *morph = + dynamic_cast (cmdType); + if (morph == NULL) { + throw megaglest_runtime_error("morph == NULL"); + } + const UnitType *morphUnit = morph->getMorphUnit(); + + if (morphUnit != NULL && + unitType.getId() != unitType2.getId() && + unitType.getName() == morphUnit->getName()) { + foundUnit = true; + break; + } + } + + // Check if this is an attack command with spawned units on attack + if (cmdType->getClass() == ccAttack) { + const AttackCommandType *act = + dynamic_cast (cmdType); + if (act != NULL && act->getAttackSkillType() != NULL + && act->getAttackSkillType()->getSpawnUnit() != "" + && act->getAttackSkillType()->getSpawnUnitCount() > 0) { + + if (unitType.getId() != unitType2.getId() && + unitType.getName() == + act->getAttackSkillType()->getSpawnUnit()) { + foundUnit = true; + break; + } + } + } + } + } + } + + if (foundUnit == false) { + //printf("Problem for unit [%s] unitTypes.size() = " MG_SIZE_T_SPECIFIER "\n",unitType.getName().c_str(),unitTypes.size()); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has no other units that can produce, build or morph into it in this faction!", + unitType.getName().c_str(), this->getName().c_str()); + results.push_back(szBuf); + } + + // Ensure that all attack skill types have valid values + if (unitType.hasSkillClass(scAttack) == true) { + for (int j = 0; j < unitType.getSkillTypeCount(); ++j) { + const SkillType *st = unitType.getSkillType(j); + if (st != NULL + && dynamic_cast (st) != NULL) { + const AttackSkillType *ast = + dynamic_cast (st); + if (ast != NULL && ast->getAttackVar() < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has the skill [%s] with an INVALID attack var value which is < 0 [%d]!", + unitType.getName().c_str(), + this->getName().c_str(), ast->getName().c_str(), + ast->getAttackVar()); + results.push_back(szBuf); + } + } + } + } + // end + + // Check if the unit has both be_built and harvest skills, this may cause issues + // with the AI + if (unitType.hasSkillClass(scBeBuilt) == true + && unitType.hasSkillClass(scHarvest) == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has both a bebuilt and harvest skill which will cause AI problems for CPU players!", + unitType.getName().c_str(), this->getName().c_str()); + results.push_back(szBuf); + } + // end + + // Check if the unit has harvest skills but not move, meaning they cannot + // harvest the resource + if (unitType.hasSkillClass(scHarvest) == true + && unitType.hasSkillClass(scMove) == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has a harvest skill but no move skill so it cannot harvest!", + unitType.getName().c_str(), this->getName().c_str()); + results.push_back(szBuf); + } + // end + + } + + return results; + } + + std::vector < std::string > + FactionType::validateFactionTypeResourceTypes(vector < ResourceType > + &resourceTypes) { + std::vector < std::string > results; + + for (int i = 0; i < (int) unitTypes.size(); ++i) { + UnitType & unitType = unitTypes[i]; + + // Check every unit's required resources to validate that for every resource-requirements + // we have a resource in the faction. + for (int j = 0; j < unitType.getCostCount(); ++j) { + const Resource *r = unitType.getCost(j); + if (r != NULL && r->getType() != NULL) { + bool foundResourceType = false; + // Now lets find a matching faction resource type for the unit + for (int k = 0; k < (int) resourceTypes.size(); ++k) { + ResourceType & rt = resourceTypes[k]; + + if (r->getType()->getName() == rt.getName()) { + foundResourceType = true; + break; + } + } + + if (foundResourceType == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has the resource req [%s]\nbut there are no such resources in this tech!", + unitType.getName().c_str(), + this->getName().c_str(), + r->getType()->getName().c_str()); + results.push_back(szBuf); + } + } + } + + // Check every unit's stored resources to validate that for every resources-stored + // we have a resource in the faction. + for (int j = 0; j < unitType.getStoredResourceCount(); ++j) { + const Resource *r = unitType.getStoredResource(j); + if (r != NULL && r->getType() != NULL) { + bool foundResourceType = false; + // Now lets find a matching faction resource type for the unit + for (int k = 0; k < (int) resourceTypes.size(); ++k) { + ResourceType & rt = resourceTypes[k]; + + if (r->getType()->getName() == rt.getName()) { + foundResourceType = true; + break; + } + } + + if (foundResourceType == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has the stored resource [%s]\nbut there are no such resources in this tech!", + unitType.getName().c_str(), + this->getName().c_str(), + r->getType()->getName().c_str()); + results.push_back(szBuf); + } + } + } + + for (int j = 0; j < unitType.getCommandTypeCount(); ++j) { + const CommandType *cmdType = unitType.getCommandType(j); + if (cmdType != NULL) { + // Ensure for each harvest type command that the resource + // exist in this faction + if (cmdType->getClass() == ccHarvest) { + const HarvestCommandType *harvest = + dynamic_cast (cmdType); + if (harvest == NULL) { + throw megaglest_runtime_error("harvest == NULL"); + } + for (int k = 0; k < harvest->getHarvestedResourceCount(); ++k) { + const ResourceType *harvestResource = + harvest->getHarvestedResource(k); + + bool foundResourceType = false; + // Now lets find a matching faction resource type for the unit + for (int k = 0; k < (int) resourceTypes.size(); ++k) { + ResourceType & rt = resourceTypes[k]; + + if (harvestResource->getName() == rt.getName()) { + foundResourceType = true; + break; + } + } + + if (foundResourceType == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Unit [%s] in Faction [%s] has the command [%s] which can harvest the resource [%s]\nbut there are no such resources in this tech!", + unitType.getName().c_str(), + this->getName().c_str(), + cmdType->getName().c_str(), + harvestResource->getName().c_str()); + results.push_back(szBuf); + } + } + } + } + } + } + + return results; + } + + std::vector < std::string > + FactionType::validateFactionTypeUpgradeTypes() { + std::vector < std::string > results; + + // For each upgrade type make sure there is at least 1 unit that can produce + // the upgrade + for (int i = 0; i < (int) upgradeTypes.size(); ++i) { + const UpgradeType & upgradeType = upgradeTypes[i]; + + // First find a unit with a command type to upgrade to this Upgrade type + bool foundUnit = false; + for (int j = 0; j < (int) unitTypes.size() && foundUnit == false; + ++j) { + UnitType & unitType = unitTypes[j]; + for (int k = 0; + k < unitType.getCommandTypeCount() && foundUnit == false; ++k) { + const CommandType *cmdType = unitType.getCommandType(k); + if (cmdType != NULL) { + // Ensure for each build type command that the build units + // exist in this faction + if (cmdType->getClass() == ccUpgrade) { + const UpgradeCommandType *upgrade = + dynamic_cast (cmdType); + if (upgrade != NULL) { + const UpgradeType *upgradeType2 = + upgrade->getProducedUpgrade(); + + if (upgradeType2 != NULL + && upgradeType.getName() == upgradeType2->getName()) { + foundUnit = true; + break; + } + } + } + } + } + } + + if (foundUnit == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Upgrade Type [%s] in Faction [%s] has no Unit able to produce this upgrade in this faction!", + upgradeType.getName().c_str(), + this->getName().c_str()); + results.push_back(szBuf); + } + } + + return results; + } + + // ==================== get ==================== + + const UnitType *FactionType::getUnitType(const string & name) const { + for (int i = 0; i < (int) unitTypes.size(); i++) { + if (unitTypes[i].getName(false) == name) { + return &unitTypes[i]; + } + } + + printf("In [%s::%s Line: %d] scanning [%s] size = " MG_SIZE_T_SPECIFIER + "\n", extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, name.c_str(), unitTypes.size()); + for (int i = 0; i < (int) unitTypes.size(); i++) { + printf("In [%s::%s Line: %d] scanning [%s] idx = %d [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, name.c_str(), i, + unitTypes[i].getName(false).c_str()); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] scanning [%s] size = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + name.c_str(), unitTypes.size()); + for (int i = 0; i < (int) unitTypes.size(); i++) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] scanning [%s] idx = %d [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + name.c_str(), i, + unitTypes[i].getName(false).c_str()); + } + + throw megaglest_runtime_error("Unit type not found: [" + name + + "] in faction type [" + this->name + "]", + true); + } + + //const UnitType *FactionType::getUnitTypeById(int id) const{ + // for(int i=0; i < (int)unitTypes.size();i++){ + // if(unitTypes[i].getId() == id) { + // return &unitTypes[i]; + // } + // } + // + // printf("In [%s::%s Line: %d] scanning [%d] size = " MG_SIZE_T_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,id,unitTypes.size()); + // for(int i=0; i < (int)unitTypes.size();i++){ + // printf("In [%s::%s Line: %d] scanning [%s] idx = %d [%s][%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,name.c_str(),i,unitTypes[i].getName(false).c_str(),unitTypes[i].getId()); + // } + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning [%s] size = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,name.c_str(),unitTypes.size()); + // for(int i=0; i < (int)unitTypes.size();i++){ + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning [%s] idx = %d [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,name.c_str(),i,unitTypes[i].getName(false).c_str()); + // } + // + // throw megaglest_runtime_error("Unit type not found: [" + intToStr(id) + "] in faction type [" + this->name + "]",true); + //} + + const UpgradeType *FactionType::getUpgradeType(const string & name) const { + for (int i = 0; i < (int) upgradeTypes.size(); i++) { + if (upgradeTypes[i].getName() == name) { + return &upgradeTypes[i]; + } + } + + printf("In [%s::%s Line: %d] scanning [%s] size = " MG_SIZE_T_SPECIFIER + "\n", extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, name.c_str(), unitTypes.size()); + for (int i = 0; i < (int) upgradeTypes.size(); i++) { + printf("In [%s::%s Line: %d] scanning [%s] idx = %d [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, name.c_str(), i, + upgradeTypes[i].getName().c_str()); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] scanning [%s] size = %d\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + name.c_str(), unitTypes.size()); + for (int i = 0; i < (int) upgradeTypes.size(); i++) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d] scanning [%s] idx = %d [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + name.c_str(), i, + upgradeTypes[i].getName().c_str()); + } + + throw megaglest_runtime_error("Upgrade type not found: [" + name + + "] in faction type [" + this->name + "]", + true); + } + + int FactionType::getStartingResourceAmount(const ResourceType * + resourceType) const { + for (int i = 0; i < (int) startingResources.size(); ++i) { + if (startingResources[i].getType() == resourceType) { + return startingResources[i].getAmount(); + } + } + return 0; + } + + void FactionType::deletePixels() { + for (int i = 0; i < (int) unitTypes.size(); ++i) { + UnitType & unitType = unitTypes[i]; + Texture2D *texture = unitType.getMeetingPointImage(); + if (texture != NULL) { + texture->deletePixels(); + } + } + } + + bool FactionType::factionUsesResourceType(const ResourceType * rt) const { + bool factionUsesResourceType = false; + if (rt != NULL) { + for (unsigned int j = 0; + factionUsesResourceType == false + && j < (unsigned int) this->getUnitTypeCount(); ++j) { + const UnitType *ut = this->getUnitType(j); + for (int k = 0; + factionUsesResourceType == false && k < ut->getCostCount(); + ++k) { + const Resource *costResource = ut->getCost(k); + //printf("#1 factionUsesResourceType, unit [%s] resource [%s] cost [%s]\n",ut->getName().c_str(),rt->getName().c_str(),costResource->getType()->getName().c_str()); + + if (costResource != NULL && costResource->getType() != NULL && + costResource->getType()->getName() == rt->getName()) { + factionUsesResourceType = true; + break; + } + } + if (factionUsesResourceType == false) { + for (unsigned int k = 0; + factionUsesResourceType == false + && k < (unsigned int) ut->getCommandTypeCount(); ++k) { + const CommandType *commandType = ut->getCommandType(k); + if (commandType != NULL + && commandType->getClass() == ccHarvest) { + const HarvestCommandType *hct = + dynamic_cast (commandType); + if (hct != NULL && hct->getHarvestedResourceCount() > 0) { + for (unsigned int l = 0; + factionUsesResourceType == false + && l < + (unsigned int) hct->getHarvestedResourceCount(); ++l) { + //printf("#2 factionUsesResourceType, unit [%s] resource [%s] harvest [%s]\n",ut->getName().c_str(),rt->getName().c_str(),hct->getHarvestedResource(l)->getName().c_str()); + + if (hct->getHarvestedResource(l)->getName() == + rt->getName()) { + factionUsesResourceType = true; + break; + } + } + } + } + } + } + } + } + return factionUsesResourceType; + } + + std::string FactionType::toString()const { + std::string result = "Faction Name: " + name + "\n"; + + result += + "Unit Type List count = " + intToStr(this->getUnitTypeCount()) + + "\n"; + for (int i = 0; i < (int) unitTypes.size(); i++) { + result += unitTypes[i].toString() + "\n"; + } + + result += + "Upgrade Type List count = " + + intToStr(this->getUpgradeTypeCount()) + "\n"; + for (int i = 0; i < (int) upgradeTypes.size(); i++) { + result += + "index: " + intToStr(i) + " " + + upgradeTypes[i].getReqDesc(false) + "\n"; + } + + return result; + } + + string FactionType::getName(bool translatedValue) const { + if (translatedValue == false) + return name; + + Lang & lang = Lang::getInstance(); + return lang.getTechTreeString("FactionName_" + name, name.c_str()); + } + + + } } //end namespace diff --git a/source/glest_game/types/faction_type.h b/source/glest_game/types/faction_type.h index 8696a9de2..6dcf17a68 100644 --- a/source/glest_game/types/faction_type.h +++ b/source/glest_game/types/faction_type.h @@ -27,222 +27,196 @@ using Shared::Sound::StrSound; -namespace Glest -{ - namespace Game - { -// ===================================================== -// class FactionType -// -/// Each of the possible factions the user can select -// ===================================================== +namespace Glest { + namespace Game { + // ===================================================== + // class FactionType + // + /// Each of the possible factions the user can select + // ===================================================== - enum AIBehaviorUnitCategory - { - aibcWorkerUnits, - aibcWarriorUnits, - aibcResourceProducerUnits, - aibcBuildingUnits - }; + enum AIBehaviorUnitCategory { + aibcWorkerUnits, + aibcWarriorUnits, + aibcResourceProducerUnits, + aibcBuildingUnits + }; - enum AIBehaviorStaticValueCategory - { - aibsvcMaxBuildRadius, - aibsvcMinMinWarriors, - aibsvcMinMinWarriorsExpandCpuEasy, - aibsvcMinMinWarriorsExpandCpuZeta, - aibsvcMinMinWarriorsExpandCpuUltra, - aibsvcMinMinWarriorsExpandCpuNormal, - aibsvcMaxMinWarriors, - aibsvcMaxExpansions, - aibsvcVillageRadius, - aibsvcMinStaticResourceCount, - aibsvcScoutResourceRange, - aibsvcMinWorkerAttackersHarvesting, - aibsvcMinBuildSpacing - }; - template <> - inline EnumParser < AIBehaviorStaticValueCategory >::EnumParser () - { - enumMap["MaxBuildRadius"] = aibsvcMaxBuildRadius; - enumMap["MinMinWarriors"] = aibsvcMinMinWarriors; - enumMap["MinMinWarriorsExpandCpuEasy"] = - aibsvcMinMinWarriorsExpandCpuEasy; - enumMap["MinMinWarriorsExpandCpuMega"] = - aibsvcMinMinWarriorsExpandCpuZeta; - enumMap["MinMinWarriorsExpandCpuZeta"] = - aibsvcMinMinWarriorsExpandCpuZeta; - enumMap["MinMinWarriorsExpandCpuUltra"] = - aibsvcMinMinWarriorsExpandCpuUltra; - enumMap["MinMinWarriorsExpandCpuNormal"] = - aibsvcMinMinWarriorsExpandCpuNormal; - enumMap["MaxMinWarriors"] = aibsvcMaxMinWarriors; - enumMap["MaxExpansions"] = aibsvcMaxExpansions; - enumMap["VillageRadius"] = aibsvcVillageRadius; - enumMap["MinStaticResourceCount"] = aibsvcMinStaticResourceCount; - enumMap["ScoutResourceRange"] = aibsvcScoutResourceRange; - enumMap["MinWorkerAttackersHarvesting"] = - aibsvcMinWorkerAttackersHarvesting; - enumMap["MinBuildSpacing"] = aibsvcMinBuildSpacing; - } + enum AIBehaviorStaticValueCategory { + aibsvcMaxBuildRadius, + aibsvcMinMinWarriors, + aibsvcMinMinWarriorsExpandCpuEasy, + aibsvcMinMinWarriorsExpandCpuZeta, + aibsvcMinMinWarriorsExpandCpuUltra, + aibsvcMinMinWarriorsExpandCpuNormal, + aibsvcMaxMinWarriors, + aibsvcMaxExpansions, + aibsvcVillageRadius, + aibsvcMinStaticResourceCount, + aibsvcScoutResourceRange, + aibsvcMinWorkerAttackersHarvesting, + aibsvcMinBuildSpacing + }; + template <> + inline EnumParser < AIBehaviorStaticValueCategory >::EnumParser() { + enumMap["MaxBuildRadius"] = aibsvcMaxBuildRadius; + enumMap["MinMinWarriors"] = aibsvcMinMinWarriors; + enumMap["MinMinWarriorsExpandCpuEasy"] = + aibsvcMinMinWarriorsExpandCpuEasy; + enumMap["MinMinWarriorsExpandCpuMega"] = + aibsvcMinMinWarriorsExpandCpuZeta; + enumMap["MinMinWarriorsExpandCpuZeta"] = + aibsvcMinMinWarriorsExpandCpuZeta; + enumMap["MinMinWarriorsExpandCpuUltra"] = + aibsvcMinMinWarriorsExpandCpuUltra; + enumMap["MinMinWarriorsExpandCpuNormal"] = + aibsvcMinMinWarriorsExpandCpuNormal; + enumMap["MaxMinWarriors"] = aibsvcMaxMinWarriors; + enumMap["MaxExpansions"] = aibsvcMaxExpansions; + enumMap["VillageRadius"] = aibsvcVillageRadius; + enumMap["MinStaticResourceCount"] = aibsvcMinStaticResourceCount; + enumMap["ScoutResourceRange"] = aibsvcScoutResourceRange; + enumMap["MinWorkerAttackersHarvesting"] = + aibsvcMinWorkerAttackersHarvesting; + enumMap["MinBuildSpacing"] = aibsvcMinBuildSpacing; + } - class FactionType - { - public: - typedef pair < const UnitType *, int >PairPUnitTypeInt; - typedef vector < UnitType > UnitTypes; - typedef vector < UpgradeType > UpgradeTypes; - typedef vector < PairPUnitTypeInt > StartingUnits; - typedef vector < Resource > Resources; + class FactionType { + public: + typedef pair < const UnitType *, int >PairPUnitTypeInt; + typedef vector < UnitType > UnitTypes; + typedef vector < UpgradeType > UpgradeTypes; + typedef vector < PairPUnitTypeInt > StartingUnits; + typedef vector < Resource > Resources; - private: - string name; - UnitTypes unitTypes; - UpgradeTypes upgradeTypes; - StartingUnits startingUnits; - Resources startingResources; - StrSound *music; - FactionPersonalityType personalityType; + private: + string name; + UnitTypes unitTypes; + UpgradeTypes upgradeTypes; + StartingUnits startingUnits; + Resources startingResources; + StrSound *music; + FactionPersonalityType personalityType; - std::map < AIBehaviorUnitCategory, - std::vector < PairPUnitTypeInt > >mapAIBehaviorUnitCategories; - std::vector < const UpgradeType *>vctAIBehaviorUpgrades; - std::map < AIBehaviorStaticValueCategory, - int >mapAIBehaviorStaticOverrideValues; + std::map < AIBehaviorUnitCategory, + std::vector < PairPUnitTypeInt > >mapAIBehaviorUnitCategories; + std::vector < const UpgradeType *>vctAIBehaviorUpgrades; + std::map < AIBehaviorStaticValueCategory, + int >mapAIBehaviorStaticOverrideValues; - bool isLinked; + bool isLinked; - float healthbarheight; - float healthbarthickness; - int healthbarVisible; - bool healthbarBorderTextureEnabled; - bool healthbarBackgroundTextureEnabled; - bool healthbarLineBorder; - Texture2D *healthbarTexture; - Texture2D *healthbarBackgroundTexture; - bool flatParticlePositions; + float healthbarheight; + float healthbarthickness; + int healthbarVisible; + bool healthbarBorderTextureEnabled; + bool healthbarBackgroundTextureEnabled; + bool healthbarLineBorder; + Texture2D *healthbarTexture; + Texture2D *healthbarBackgroundTexture; + bool flatParticlePositions; - public: - //init - FactionType (); - void load (const string & factionName, const TechTree * techTree, - Checksum * checksum, Checksum * techtreeChecksum, - std::map < string, vector < pair < string, - string > > >&loadedFileList, bool validationMode = false); - virtual ~ FactionType (); + public: + //init + FactionType(); + void load(const string & factionName, const TechTree * techTree, + Checksum * checksum, Checksum * techtreeChecksum, + std::map < string, vector < pair < string, + string > > >&loadedFileList, bool validationMode = false); + virtual ~FactionType(); - const std::vector < FactionType::PairPUnitTypeInt > - getAIBehaviorUnits (AIBehaviorUnitCategory category) const; - const std::vector < const UpgradeType *>getAIBehaviorUpgrades () const - { - return vctAIBehaviorUpgrades; - }; - int getAIBehaviorStaticOverideValue (AIBehaviorStaticValueCategory type) - const; + const std::vector < FactionType::PairPUnitTypeInt > + getAIBehaviorUnits(AIBehaviorUnitCategory category) const; + const std::vector < const UpgradeType *>getAIBehaviorUpgrades() const { + return vctAIBehaviorUpgrades; + }; + int getAIBehaviorStaticOverideValue(AIBehaviorStaticValueCategory type) + const; - //get - bool getIsLinked () const - { - return isLinked; - } - int getUnitTypeCount () const - { - return (int) unitTypes.size (); - } - int getUpgradeTypeCount () const - { - return (int) upgradeTypes.size (); - } - virtual string getName (bool translatedValue = false) const; - const UnitType *getUnitType (int i) const - { - return &unitTypes[i]; - } - const UpgradeType *getUpgradeType (int i) const - { - return &upgradeTypes[i]; - } - StrSound *getMusic () const - { - return music; - } - int getStartingUnitCount () const - { - return (int) startingUnits.size (); - } - const UnitType *getStartingUnit (int i) const - { - return startingUnits[i].first; - } - int getStartingUnitAmount (int i) const - { - return startingUnits[i].second; - } - inline float getHealthbarHeight () const - { - return healthbarheight; - } - inline float getHealthbarThickness () const - { - return healthbarthickness; - } - inline int getHealthbarVisible () const - { - return healthbarVisible; - } - inline bool isHealthbarBorderTextureEnabled () const - { - return healthbarBorderTextureEnabled; - } - inline bool isHealthbarBackgroundTextureEnabled () const - { - return healthbarBackgroundTextureEnabled; - } - inline bool isHealthbarLineBorder () const - { - return healthbarLineBorder; - } - Texture2D *getHealthbarTexture () const - { - return healthbarTexture; - } - Texture2D *getHealthbarBackgroundTexture () const - { - return healthbarBackgroundTexture; - } - bool isFlatParticlePositions () const - { - return flatParticlePositions; - } + //get + bool getIsLinked() const { + return isLinked; + } + int getUnitTypeCount() const { + return (int) unitTypes.size(); + } + int getUpgradeTypeCount() const { + return (int) upgradeTypes.size(); + } + virtual string getName(bool translatedValue = false) const; + const UnitType *getUnitType(int i) const { + return &unitTypes[i]; + } + const UpgradeType *getUpgradeType(int i) const { + return &upgradeTypes[i]; + } + StrSound *getMusic() const { + return music; + } + int getStartingUnitCount() const { + return (int) startingUnits.size(); + } + const UnitType *getStartingUnit(int i) const { + return startingUnits[i].first; + } + int getStartingUnitAmount(int i) const { + return startingUnits[i].second; + } + inline float getHealthbarHeight() const { + return healthbarheight; + } + inline float getHealthbarThickness() const { + return healthbarthickness; + } + inline int getHealthbarVisible() const { + return healthbarVisible; + } + inline bool isHealthbarBorderTextureEnabled() const { + return healthbarBorderTextureEnabled; + } + inline bool isHealthbarBackgroundTextureEnabled() const { + return healthbarBackgroundTextureEnabled; + } + inline bool isHealthbarLineBorder() const { + return healthbarLineBorder; + } + Texture2D *getHealthbarTexture() const { + return healthbarTexture; + } + Texture2D *getHealthbarBackgroundTexture() const { + return healthbarBackgroundTexture; + } + bool isFlatParticlePositions() const { + return flatParticlePositions; + } - const UnitType *getUnitType (const string & name) const; - //const UnitType *getUnitTypeById(int id) const; - const UpgradeType *getUpgradeType (const string & name) const; - int getStartingResourceAmount (const ResourceType * resourceType) const; + const UnitType *getUnitType(const string & name) const; + //const UnitType *getUnitTypeById(int id) const; + const UpgradeType *getUpgradeType(const string & name) const; + int getStartingResourceAmount(const ResourceType * resourceType) const; - FactionPersonalityType getPersonalityType () const - { - return personalityType; - } - void setPersonalityType (FactionPersonalityType value) - { - personalityType = value; - } + FactionPersonalityType getPersonalityType() const { + return personalityType; + } + void setPersonalityType(FactionPersonalityType value) { + personalityType = value; + } - std::string toString () const; - std::vector < std::string > validateFactionType (); - std::vector < std::string > validateFactionTypeResourceTypes (vector < - ResourceType - > - &resourceTypes); - std::vector < std::string > validateFactionTypeUpgradeTypes (); + std::string toString() const; + std::vector < std::string > validateFactionType(); + std::vector < std::string > validateFactionTypeResourceTypes(vector < + ResourceType + > + &resourceTypes); + std::vector < std::string > validateFactionTypeUpgradeTypes(); - void deletePixels (); - bool factionUsesResourceType (const ResourceType * rt) const; + void deletePixels(); + bool factionUsesResourceType(const ResourceType * rt) const; - }; + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/types/object_type.cpp b/source/glest_game/types/object_type.cpp index d34c83d31..c0d195841 100644 --- a/source/glest_game/types/object_type.cpp +++ b/source/glest_game/types/object_type.cpp @@ -14,68 +14,58 @@ #include "renderer.h" #include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class ObjectType -// ===================================================== + // ===================================================== + // class ObjectType + // ===================================================== - void ObjectType::init (int modelCount, int objectClass, bool walkable, - int height) - { -// modeltypes.reserve(modelCount); - this->objectClass = objectClass; - this->walkable = walkable; - this->height = height; - } + void ObjectType::init(int modelCount, int objectClass, bool walkable, + int height) { + // modeltypes.reserve(modelCount); + this->objectClass = objectClass; + this->walkable = walkable; + this->height = height; + } - ObjectType::~ObjectType () - { - while (!(modeltypes.empty ())) - { - delete modeltypes.back (); - modeltypes.pop_back (); - //Logger::getInstance().add("ObjectType", true); - } - } + ObjectType::~ObjectType() { + while (!(modeltypes.empty())) { + delete modeltypes.back(); + modeltypes.pop_back(); + //Logger::getInstance().add("ObjectType", true); + } + } - TilesetModelType *ObjectType::loadModel (const string & path, - std::map < string, - vector < pair < string, - string > > >*loadedFileList, - string parentLoader) - { - Model *model = - Renderer::getInstance ().newModel (rsGame, path, false, - loadedFileList, &parentLoader); - color = Vec3f (0.f); - if (model && model->getMeshCount () > 0 - && model->getMesh (0)->getTexture (0) != NULL) - { - const Pixmap2D *p = - model->getMesh (0)->getTexture (0)->getPixmapConst (); - color = p->getPixel3f (p->getW () / 2, p->getH () / 2); - } - TilesetModelType *modelType = new TilesetModelType (); - modelType->setModel (model); - modeltypes.push_back (modelType); - return modelType; - } + TilesetModelType *ObjectType::loadModel(const string & path, + std::map < string, + vector < pair < string, + string > > >*loadedFileList, + string parentLoader) { + Model *model = + Renderer::getInstance().newModel(rsGame, path, false, + loadedFileList, &parentLoader); + color = Vec3f(0.f); + if (model && model->getMeshCount() > 0 + && model->getMesh(0)->getTexture(0) != NULL) { + const Pixmap2D *p = + model->getMesh(0)->getTexture(0)->getPixmapConst(); + color = p->getPixel3f(p->getW() / 2, p->getH() / 2); + } + TilesetModelType *modelType = new TilesetModelType(); + modelType->setModel(model); + modeltypes.push_back(modelType); + return modelType; + } - void ObjectType::deletePixels () - { - for (int i = 0; i < (int) modeltypes.size (); ++i) - { - TilesetModelType *model = modeltypes[i]; - if (model->getModel () != NULL) - { - model->getModel ()->deletePixels (); - } - } - } + void ObjectType::deletePixels() { + for (int i = 0; i < (int) modeltypes.size(); ++i) { + TilesetModelType *model = modeltypes[i]; + if (model->getModel() != NULL) { + model->getModel()->deletePixels(); + } + } + } - } + } } //end namespace diff --git a/source/glest_game/types/object_type.h b/source/glest_game/types/object_type.h index a3236c127..825694475 100644 --- a/source/glest_game/types/object_type.h +++ b/source/glest_game/types/object_type.h @@ -25,85 +25,75 @@ using std::vector; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - using Shared::Graphics::Model; - using Shared::Graphics::Vec3f; + using Shared::Graphics::Model; + using Shared::Graphics::Vec3f; -// ===================================================== -// class ObjectType -// -/// Each of the possible objects of the map: trees, stones ... -// ===================================================== + // ===================================================== + // class ObjectType + // + /// Each of the possible objects of the map: trees, stones ... + // ===================================================== - typedef vector < ObjectParticleSystemType * >ObjectParticleSystemTypes; - typedef vector < ObjectParticleSystemTypes > ObjectParticleVector; + typedef vector < ObjectParticleSystemType * >ObjectParticleSystemTypes; + typedef vector < ObjectParticleSystemTypes > ObjectParticleVector; - class ObjectType - { - private: - typedef vector < TilesetModelType * >ModelTypes; - private: - static const int tree1 = 0; - static const int tree2 = 1; - static const int choppedTree = 2; + class ObjectType { + private: + typedef vector < TilesetModelType * >ModelTypes; + private: + static const int tree1 = 0; + static const int tree2 = 1; + static const int choppedTree = 2; - private: - ModelTypes modeltypes; - Vec3f color; - int objectClass; - bool walkable; - int height; + private: + ModelTypes modeltypes; + Vec3f color; + int objectClass; + bool walkable; + int height; - public: - ObjectType () - { - objectClass = -1; - walkable = false; - height = 0; - } - ~ObjectType (); - void init (int modelCount, int objectClass, bool walkable, int height); + public: + ObjectType() { + objectClass = -1; + walkable = false; + height = 0; + } + ~ObjectType(); + void init(int modelCount, int objectClass, bool walkable, int height); - TilesetModelType *loadModel (const string & path, std::map < string, - vector < pair < string, - string > > >*loadedFileList = - NULL, string parentLoader = ""); + TilesetModelType *loadModel(const string & path, std::map < string, + vector < pair < string, + string > > >*loadedFileList = + NULL, string parentLoader = ""); - inline TilesetModelType *getTilesetModelType (int i) - { - return modeltypes[i]; - } - inline int getModelCount () const - { - return (int) modeltypes.size (); - } - inline const Vec3f & getColor () const - { - return color; - } - inline int getClass () const - { - return objectClass; - } - inline bool getWalkable () const - { - return walkable; - } - inline int getHeight () const - { - return height; - } - inline bool isATree () const - { - return objectClass == tree1 || objectClass == tree2; - } - void deletePixels (); - }; + inline TilesetModelType *getTilesetModelType(int i) { + return modeltypes[i]; + } + inline int getModelCount() const { + return (int) modeltypes.size(); + } + inline const Vec3f & getColor() const { + return color; + } + inline int getClass() const { + return objectClass; + } + inline bool getWalkable() const { + return walkable; + } + inline int getHeight() const { + return height; + } + inline bool isATree() const { + return objectClass == tree1 || objectClass == tree2; + } + void deletePixels(); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/types/projectile_type.cpp b/source/glest_game/types/projectile_type.cpp index be5c331c4..2ecbc9b46 100644 --- a/source/glest_game/types/projectile_type.cpp +++ b/source/glest_game/types/projectile_type.cpp @@ -17,164 +17,145 @@ using namespace Shared::Util; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - ProjectileType::ProjectileType () - { + ProjectileType::ProjectileType() { - projectileParticleSystemType = NULL; - attackStartTime = 0.0f; + projectileParticleSystemType = NULL; + attackStartTime = 0.0f; - spawnUnit = ""; - spawnUnitcount = 0; - spawnUnitAtTarget = false; + spawnUnit = ""; + spawnUnitcount = 0; + spawnUnitAtTarget = false; - shake = false; - shakeIntensity = 0; - shakeDuration = 0; + shake = false; + shakeIntensity = 0; + shakeDuration = 0; - shakeVisible = true; - shakeInCameraView = true; - shakeCameraDistanceAffected = false; - damagePercentage = 100; - } + shakeVisible = true; + shakeInCameraView = true; + shakeCameraDistanceAffected = false; + damagePercentage = 100; + } - ProjectileType::~ProjectileType () - { - deleteValues (hitSounds.getSounds ().begin (), - hitSounds.getSounds ().end ()); - if (projectileParticleSystemType != NULL) - { - delete projectileParticleSystemType; - projectileParticleSystemType = NULL; - } - } + ProjectileType::~ProjectileType() { + deleteValues(hitSounds.getSounds().begin(), + hitSounds.getSounds().end()); + if (projectileParticleSystemType != NULL) { + delete projectileParticleSystemType; + projectileParticleSystemType = NULL; + } + } - void ProjectileType::load (const XmlNode * projectileNode, - const string & dir, - const string & techtreepath, std::map < string, - vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { + void ProjectileType::load(const XmlNode * projectileNode, + const string & dir, + const string & techtreepath, std::map < string, + vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { - string currentPath = dir; - endPathWithSlash (currentPath); + string currentPath = dir; + endPathWithSlash(currentPath); - if (projectileNode->hasAttribute ("attack-start-time")) - { - attackStartTime = - projectileNode->getAttribute ("attack-start-time")-> - getFloatValue (); - } - else - { - attackStartTime = 0.0f; - } + if (projectileNode->hasAttribute("attack-start-time")) { + attackStartTime = + projectileNode->getAttribute("attack-start-time")-> + getFloatValue(); + } else { + attackStartTime = 0.0f; + } - // damage percentage MUST be set! - damagePercentage = - projectileNode->getAttribute ("damage-percentage")->getIntValue (); + // damage percentage MUST be set! + damagePercentage = + projectileNode->getAttribute("damage-percentage")->getIntValue(); - // projectiles MUST have a particle system. - const XmlNode *particleNode = projectileNode->getChild ("particle"); - string path = - particleNode->getAttribute ("path")->getRestrictedValue (); - ParticleSystemTypeProjectile *projectileParticleSystemType = - new ParticleSystemTypeProjectile (); - projectileParticleSystemType->load (particleNode, dir, - currentPath + path, - &Renderer::getInstance (), - loadedFileList, parentLoader, - techtreepath); - loadedFileList[currentPath + - path].push_back (make_pair (parentLoader, - particleNode-> - getAttribute ("path")-> - getRestrictedValue ())); - setProjectileParticleSystemType (projectileParticleSystemType); + // projectiles MUST have a particle system. + const XmlNode *particleNode = projectileNode->getChild("particle"); + string path = + particleNode->getAttribute("path")->getRestrictedValue(); + ParticleSystemTypeProjectile *projectileParticleSystemType = + new ParticleSystemTypeProjectile(); + projectileParticleSystemType->load(particleNode, dir, + currentPath + path, + &Renderer::getInstance(), + loadedFileList, parentLoader, + techtreepath); + loadedFileList[currentPath + + path].push_back(make_pair(parentLoader, + particleNode-> + getAttribute("path")-> + getRestrictedValue())); + setProjectileParticleSystemType(projectileParticleSystemType); - //spawnattack - if (projectileNode->hasChild ("unit")) - { - spawnUnit = - projectileNode->getChild ("unit")->getAttribute ("value")-> - getValue (); - spawnUnitcount = - projectileNode->getChild ("unit")->getAttribute ("amount")-> - getIntValue (); - if (projectileNode->getChild ("unit")->hasAttribute ("spawnAtTarget")) - { - spawnUnitAtTarget = - projectileNode->getChild ("unit")-> - getAttribute ("spawnAtTarget")->getBoolValue (); - } - else - { - spawnUnitAtTarget = false; - } - } - else - { - spawnUnit = ""; - spawnUnitcount = 0; - spawnUnitAtTarget = false; - } + //spawnattack + if (projectileNode->hasChild("unit")) { + spawnUnit = + projectileNode->getChild("unit")->getAttribute("value")-> + getValue(); + spawnUnitcount = + projectileNode->getChild("unit")->getAttribute("amount")-> + getIntValue(); + if (projectileNode->getChild("unit")->hasAttribute("spawnAtTarget")) { + spawnUnitAtTarget = + projectileNode->getChild("unit")-> + getAttribute("spawnAtTarget")->getBoolValue(); + } else { + spawnUnitAtTarget = false; + } + } else { + spawnUnit = ""; + spawnUnitcount = 0; + spawnUnitAtTarget = false; + } - if (projectileNode->hasChild ("hitshake")) - { - const XmlNode *hitShakeNode = projectileNode->getChild ("hitshake"); - shake = hitShakeNode->getAttribute ("enabled")->getBoolValue (); - if (shake) - { - shakeIntensity = - hitShakeNode->getAttribute ("intensity")->getIntValue (); - shakeDuration = - hitShakeNode->getAttribute ("duration")->getIntValue (); + if (projectileNode->hasChild("hitshake")) { + const XmlNode *hitShakeNode = projectileNode->getChild("hitshake"); + shake = hitShakeNode->getAttribute("enabled")->getBoolValue(); + if (shake) { + shakeIntensity = + hitShakeNode->getAttribute("intensity")->getIntValue(); + shakeDuration = + hitShakeNode->getAttribute("duration")->getIntValue(); - shakeVisible = - hitShakeNode->getAttribute ("visible")->getBoolValue (); - shakeInCameraView = - hitShakeNode->getAttribute ("in-camera-view")->getBoolValue (); - shakeCameraDistanceAffected = - hitShakeNode->getAttribute ("camera-distance-affected")-> - getBoolValue (); - } - } + shakeVisible = + hitShakeNode->getAttribute("visible")->getBoolValue(); + shakeInCameraView = + hitShakeNode->getAttribute("in-camera-view")->getBoolValue(); + shakeCameraDistanceAffected = + hitShakeNode->getAttribute("camera-distance-affected")-> + getBoolValue(); + } + } - if (projectileNode->hasChild ("hitsound")) - { - const XmlNode *soundNode = projectileNode->getChild ("hitsound"); - if (soundNode->getAttribute ("enabled")->getBoolValue ()) - { + if (projectileNode->hasChild("hitsound")) { + const XmlNode *soundNode = projectileNode->getChild("hitsound"); + if (soundNode->getAttribute("enabled")->getBoolValue()) { - hitSounds.resize ((int) soundNode->getChildCount ()); - for (int i = 0; i < (int) soundNode->getChildCount (); ++i) - { - const XmlNode *soundFileNode = - soundNode->getChild ("sound-file", i); - string path = - soundFileNode->getAttribute ("path")-> - getRestrictedValue (currentPath, true); - //printf("\n\n\n\n!@#$ ---> parentLoader [%s] path [%s] nodeValue [%s] i = %d",parentLoader.c_str(),path.c_str(),soundFileNode->getAttribute("path")->getRestrictedValue().c_str(),i); + hitSounds.resize((int) soundNode->getChildCount()); + for (int i = 0; i < (int) soundNode->getChildCount(); ++i) { + const XmlNode *soundFileNode = + soundNode->getChild("sound-file", i); + string path = + soundFileNode->getAttribute("path")-> + getRestrictedValue(currentPath, true); + //printf("\n\n\n\n!@#$ ---> parentLoader [%s] path [%s] nodeValue [%s] i = %d",parentLoader.c_str(),path.c_str(),soundFileNode->getAttribute("path")->getRestrictedValue().c_str(),i); - StaticSound *sound = new StaticSound (); - sound->load (path); - loadedFileList[path]. - push_back (make_pair - (parentLoader, - soundFileNode->getAttribute ("path")-> - getRestrictedValue ())); - hitSounds[i] = sound; - } - } - } - } + StaticSound *sound = new StaticSound(); + sound->load(path); + loadedFileList[path]. + push_back(make_pair + (parentLoader, + soundFileNode->getAttribute("path")-> + getRestrictedValue())); + hitSounds[i] = sound; + } + } + } + } -}} //end namespace + } +} //end namespace diff --git a/source/glest_game/types/projectile_type.h b/source/glest_game/types/projectile_type.h index 0ae172b33..c4b8ee0a2 100644 --- a/source/glest_game/types/projectile_type.h +++ b/source/glest_game/types/projectile_type.h @@ -30,120 +30,100 @@ using std::vector; using std::string; -namespace Glest -{ - namespace Game - { -// ===================================================== -// class ProjectileType -// ===================================================== +namespace Glest { + namespace Game { + // ===================================================== + // class ProjectileType + // ===================================================== - class ProjectileType - { - protected: - ParticleSystemTypeProjectile * projectileParticleSystemType; - SoundContainer hitSounds; - float attackStartTime; + class ProjectileType { + protected: + ParticleSystemTypeProjectile * projectileParticleSystemType; + SoundContainer hitSounds; + float attackStartTime; - string spawnUnit; - int spawnUnitcount; - bool spawnUnitAtTarget; + string spawnUnit; + int spawnUnitcount; + bool spawnUnitAtTarget; - bool shake; - int shakeIntensity; - int shakeDuration; + bool shake; + int shakeIntensity; + int shakeDuration; - bool shakeVisible; - bool shakeInCameraView; - bool shakeCameraDistanceAffected; - int damagePercentage; + bool shakeVisible; + bool shakeInCameraView; + bool shakeCameraDistanceAffected; + int damagePercentage; - public: - ProjectileType (); - virtual ~ ProjectileType (); + public: + ProjectileType(); + virtual ~ProjectileType(); - void load (const XmlNode * projectileNode, const string & dir, - const string & techtreepath, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); + void load(const XmlNode * projectileNode, const string & dir, + const string & techtreepath, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); - //get/set - inline StaticSound *getHitSound () const - { - return hitSounds.getRandSound (); - } - ParticleSystemTypeProjectile *getProjectileParticleSystemType () const - { - return projectileParticleSystemType; - } - float getAttackStartTime () const - { - return attackStartTime; - } - void setAttackStartTime (float value) - { - attackStartTime = value; - } + //get/set + inline StaticSound *getHitSound() const { + return hitSounds.getRandSound(); + } + ParticleSystemTypeProjectile *getProjectileParticleSystemType() const { + return projectileParticleSystemType; + } + float getAttackStartTime() const { + return attackStartTime; + } + void setAttackStartTime(float value) { + attackStartTime = value; + } - string getSpawnUnit () const - { - return spawnUnit; - } - int getSpawnUnitcount () const - { - return spawnUnitcount; - } - bool getSpawnUnitAtTarget () const - { - return spawnUnitAtTarget; - } + string getSpawnUnit() const { + return spawnUnit; + } + int getSpawnUnitcount() const { + return spawnUnitcount; + } + bool getSpawnUnitAtTarget() const { + return spawnUnitAtTarget; + } - bool isShake () const - { - return shake; - } - bool isShakeCameraDistanceAffected () const - { - return shakeCameraDistanceAffected; - } - int getShakeDuration () const - { - return shakeDuration; - } - bool isShakeInCameraView () const - { - return shakeInCameraView; - } - int getShakeIntensity () const - { - return shakeIntensity; - } - bool isShakeVisible () const - { - return shakeVisible; - } - int getDamagePercentage () const - { - return damagePercentage; - } - void setDamagePercentage (int value) - { - damagePercentage = value; - } + bool isShake() const { + return shake; + } + bool isShakeCameraDistanceAffected() const { + return shakeCameraDistanceAffected; + } + int getShakeDuration() const { + return shakeDuration; + } + bool isShakeInCameraView() const { + return shakeInCameraView; + } + int getShakeIntensity() const { + return shakeIntensity; + } + bool isShakeVisible() const { + return shakeVisible; + } + int getDamagePercentage() const { + return damagePercentage; + } + void setDamagePercentage(int value) { + damagePercentage = value; + } - void setProjectileParticleSystemType (ParticleSystemTypeProjectile * - pointer) - { - projectileParticleSystemType = pointer; - } - ParticleSystemTypeProjectile *getProjectileParticleSystemType () - { - return projectileParticleSystemType; - } - }; + void setProjectileParticleSystemType(ParticleSystemTypeProjectile * + pointer) { + projectileParticleSystemType = pointer; + } + ParticleSystemTypeProjectile *getProjectileParticleSystemType() { + return projectileParticleSystemType; + } + }; - } + } } //end namespace #endif diff --git a/source/glest_game/types/resource_type.cpp b/source/glest_game/types/resource_type.cpp index cf58868a1..96e9a4e89 100644 --- a/source/glest_game/types/resource_type.cpp +++ b/source/glest_game/types/resource_type.cpp @@ -24,335 +24,303 @@ using namespace Shared::Util; using namespace Shared::Xml; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class ResourceType -// ===================================================== + // ===================================================== + // class ResourceType + // ===================================================== - ResourceType::ResourceType () - { - resourceClass = rcTech; - tilesetObject = 0; - resourceNumber = 0; - interval = 0; - defResPerPatch = 0; - recoup_cost = false; - model = NULL; - displayInHud = false; - cleanupMemory = true; - } + ResourceType::ResourceType() { + resourceClass = rcTech; + tilesetObject = 0; + resourceNumber = 0; + interval = 0; + defResPerPatch = 0; + recoup_cost = false; + model = NULL; + displayInHud = false; + cleanupMemory = true; + } - ResourceType::~ResourceType () - { - if (cleanupMemory == true) - { - while (particleTypes.empty () == false) - { - delete particleTypes.back (); - particleTypes.pop_back (); - } - } - } + ResourceType::~ResourceType() { + if (cleanupMemory == true) { + while (particleTypes.empty() == false) { + delete particleTypes.back(); + particleTypes.pop_back(); + } + } + } - string ResourceType::getName (bool translatedValue) const - { - if (translatedValue == false) - return name; + string ResourceType::getName(bool translatedValue) const { + if (translatedValue == false) + return name; - Lang & lang = Lang::getInstance (); - return lang.getTechTreeString ("ResourceTypeName_" + name, - name.c_str ()); - } + Lang & lang = Lang::getInstance(); + return lang.getTechTreeString("ResourceTypeName_" + name, + name.c_str()); + } - void ResourceType::load (const string & dir, Checksum * checksum, - Checksum * techtreeChecksum, std::map < string, - vector < pair < string, - string > > >&loadedFileList, string techtreePath) - { + void ResourceType::load(const string & dir, Checksum * checksum, + Checksum * techtreeChecksum, std::map < string, + vector < pair < string, + string > > >&loadedFileList, string techtreePath) { - string path, str; - Renderer & renderer = Renderer::getInstance (); + string path, str; + Renderer & renderer = Renderer::getInstance(); - try - { - recoup_cost = true; + try { + recoup_cost = true; - name = lastDir (dir); + name = lastDir(dir); - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - Lang::getInstance (). - getString ("LogScreenGameLoadingResourceType", "", - true).c_str (), - formatString (getName (true)).c_str ()); - Logger::getInstance ().add (szBuf, true); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + Lang::getInstance(). + getString("LogScreenGameLoadingResourceType", "", + true).c_str(), + formatString(getName(true)).c_str()); + Logger::getInstance().add(szBuf, true); - string currentPath = dir; - endPathWithSlash (currentPath); - path = currentPath + name + ".xml"; - string sourceXMLFile = path; - checksum->addFile (path); - techtreeChecksum->addFile (path); + string currentPath = dir; + endPathWithSlash(currentPath); + path = currentPath + name + ".xml"; + string sourceXMLFile = path; + checksum->addFile(path); + techtreeChecksum->addFile(path); - //tree - XmlTree xmlTree; - std::map < string, string > mapExtraTagReplacementValues; - mapExtraTagReplacementValues["$COMMONDATAPATH"] = - techtreePath + "/commondata/"; - xmlTree.load (path, - Properties:: - getTagReplacementValues - (&mapExtraTagReplacementValues)); - loadedFileList[path].push_back (make_pair (currentPath, currentPath)); + //tree + XmlTree xmlTree; + std::map < string, string > mapExtraTagReplacementValues; + mapExtraTagReplacementValues["$COMMONDATAPATH"] = + techtreePath + "/commondata/"; + xmlTree.load(path, + Properties:: + getTagReplacementValues + (&mapExtraTagReplacementValues)); + loadedFileList[path].push_back(make_pair(currentPath, currentPath)); - const XmlNode *resourceNode = xmlTree.getRootNode (); + const XmlNode *resourceNode = xmlTree.getRootNode(); - //image - const XmlNode *imageNode = resourceNode->getChild ("image"); - image = renderer.newTexture2D (rsGame); - if (image) - { - image->load (imageNode->getAttribute ("path")-> - getRestrictedValue (currentPath)); - } - loadedFileList[imageNode->getAttribute ("path")-> - getRestrictedValue (currentPath)]. - push_back (make_pair - (sourceXMLFile, - imageNode->getAttribute ("path")-> - getRestrictedValue ())); + //image + const XmlNode *imageNode = resourceNode->getChild("image"); + image = renderer.newTexture2D(rsGame); + if (image) { + image->load(imageNode->getAttribute("path")-> + getRestrictedValue(currentPath)); + } + loadedFileList[imageNode->getAttribute("path")-> + getRestrictedValue(currentPath)]. + push_back(make_pair + (sourceXMLFile, + imageNode->getAttribute("path")-> + getRestrictedValue())); - //type - const XmlNode *typeNode = resourceNode->getChild ("type"); - resourceClass = - strToRc (typeNode->getAttribute ("value")->getRestrictedValue ()); + //type + const XmlNode *typeNode = resourceNode->getChild("type"); + resourceClass = + strToRc(typeNode->getAttribute("value")->getRestrictedValue()); - switch (resourceClass) - { - case rcTech: - { - //model - const XmlNode *modelNode = typeNode->getChild ("model"); - string modelPath = - modelNode->getAttribute ("path")-> - getRestrictedValue (currentPath); + switch (resourceClass) { + case rcTech: + { + //model + const XmlNode *modelNode = typeNode->getChild("model"); + string modelPath = + modelNode->getAttribute("path")-> + getRestrictedValue(currentPath); - model = - renderer.newModel (rsGame, modelPath, false, &loadedFileList, - &sourceXMLFile); - loadedFileList[modelPath]. - push_back (make_pair - (sourceXMLFile, - modelNode->getAttribute ("path")-> - getRestrictedValue ())); + model = + renderer.newModel(rsGame, modelPath, false, &loadedFileList, + &sourceXMLFile); + loadedFileList[modelPath]. + push_back(make_pair + (sourceXMLFile, + modelNode->getAttribute("path")-> + getRestrictedValue())); - if (modelNode->hasChild ("particles")) - { - const XmlNode *particleNode = modelNode->getChild ("particles"); - bool particleEnabled = - particleNode->getAttribute ("value")->getBoolValue (); - if (particleEnabled == true) - { - for (int k = 0; k < (int) particleNode->getChildCount (); ++k) - { - const XmlNode *particleFileNode = - particleNode->getChild ("particle-file", k); - string particlePath = - particleFileNode->getAttribute ("path")-> - getRestrictedValue (); + if (modelNode->hasChild("particles")) { + const XmlNode *particleNode = modelNode->getChild("particles"); + bool particleEnabled = + particleNode->getAttribute("value")->getBoolValue(); + if (particleEnabled == true) { + for (int k = 0; k < (int) particleNode->getChildCount(); ++k) { + const XmlNode *particleFileNode = + particleNode->getChild("particle-file", k); + string particlePath = + particleFileNode->getAttribute("path")-> + getRestrictedValue(); - ObjectParticleSystemType *objectParticleSystemType = - new ObjectParticleSystemType (); - objectParticleSystemType->load (particleFileNode, dir, - currentPath + particlePath, - &Renderer::getInstance (), - loadedFileList, - sourceXMLFile, - techtreePath); - loadedFileList[currentPath + - particlePath]. - push_back (make_pair - (sourceXMLFile, - particleFileNode->getAttribute ("path")-> - getRestrictedValue ())); + ObjectParticleSystemType *objectParticleSystemType = + new ObjectParticleSystemType(); + objectParticleSystemType->load(particleFileNode, dir, + currentPath + particlePath, + &Renderer::getInstance(), + loadedFileList, + sourceXMLFile, + techtreePath); + loadedFileList[currentPath + + particlePath]. + push_back(make_pair + (sourceXMLFile, + particleFileNode->getAttribute("path")-> + getRestrictedValue())); - particleTypes.push_back (objectParticleSystemType); - } - } - } + particleTypes.push_back(objectParticleSystemType); + } + } + } - //default resources - const XmlNode *defaultAmountNode = - typeNode->getChild ("default-amount"); - defResPerPatch = - defaultAmountNode->getAttribute ("value")->getIntValue (); + //default resources + const XmlNode *defaultAmountNode = + typeNode->getChild("default-amount"); + defResPerPatch = + defaultAmountNode->getAttribute("value")->getIntValue(); - //resource number - const XmlNode *resourceNumberNode = - typeNode->getChild ("resource-number"); - resourceNumber = - resourceNumberNode->getAttribute ("value")->getIntValue (); - } - break; + //resource number + const XmlNode *resourceNumberNode = + typeNode->getChild("resource-number"); + resourceNumber = + resourceNumberNode->getAttribute("value")->getIntValue(); + } + break; - case rcTileset: - { - //resource number - const XmlNode *defaultAmountNode = - typeNode->getChild ("default-amount"); - defResPerPatch = - defaultAmountNode->getAttribute ("value")->getIntValue (); + case rcTileset: + { + //resource number + const XmlNode *defaultAmountNode = + typeNode->getChild("default-amount"); + defResPerPatch = + defaultAmountNode->getAttribute("value")->getIntValue(); - //resource number - const XmlNode *tilesetObjectNode = - typeNode->getChild ("tileset-object"); - tilesetObject = - tilesetObjectNode->getAttribute ("value")->getIntValue (); - } - break; + //resource number + const XmlNode *tilesetObjectNode = + typeNode->getChild("tileset-object"); + tilesetObject = + tilesetObjectNode->getAttribute("value")->getIntValue(); + } + break; - case rcConsumable: - { - //interval - const XmlNode *intervalNode = typeNode->getChild ("interval"); - interval = intervalNode->getAttribute ("value")->getIntValue (); - } - break; + case rcConsumable: + { + //interval + const XmlNode *intervalNode = typeNode->getChild("interval"); + interval = intervalNode->getAttribute("value")->getIntValue(); + } + break; - case rcStatic: - { - //recoup_cost - if (typeNode->hasChild ("recoup_cost") == true) - { - const XmlNode *recoup_costNode = - typeNode->getChild ("recoup_cost"); - if (recoup_costNode != NULL) - { - recoup_cost = - recoup_costNode->getAttribute ("value")->getBoolValue (); - } - } - } - break; + case rcStatic: + { + //recoup_cost + if (typeNode->hasChild("recoup_cost") == true) { + const XmlNode *recoup_costNode = + typeNode->getChild("recoup_cost"); + if (recoup_costNode != NULL) { + recoup_cost = + recoup_costNode->getAttribute("value")->getBoolValue(); + } + } + } + break; - default: - break; - } + default: + break; + } - //displayInHud - if (resourceNode->hasChild ("display") == true) - { - const XmlNode *displayNode = resourceNode->getChild ("display"); - displayInHud = displayNode->getAttribute ("value")->getBoolValue (); - } - else - { - displayInHud = true; - } - } - catch (megaglest_runtime_error & ex) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - ex.what ()); - throw megaglest_runtime_error ("Error loading resource type: " + - path + "\nMessage: " + ex.what (), - !ex.wantStackTrace ()); - } - catch (const exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - e.what ()); - throw megaglest_runtime_error ("Error loading resource type: " + - path + "\n" + e.what ()); - } - } + //displayInHud + if (resourceNode->hasChild("display") == true) { + const XmlNode *displayNode = resourceNode->getChild("display"); + displayInHud = displayNode->getAttribute("value")->getBoolValue(); + } else { + displayInHud = true; + } + } catch (megaglest_runtime_error & ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + ex.what()); + throw megaglest_runtime_error("Error loading resource type: " + + path + "\nMessage: " + ex.what(), + !ex.wantStackTrace()); + } catch (const exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + e.what()); + throw megaglest_runtime_error("Error loading resource type: " + + path + "\n" + e.what()); + } + } -// ==================== misc ==================== + // ==================== misc ==================== - ResourceClass ResourceType::strToRc (const string & s) - { - if (s == "tech") - { - return rcTech; - } - if (s == "tileset") - { - return rcTileset; - } - if (s == "static") - { - return rcStatic; - } - if (s == "consumable") - { - return rcConsumable; - } - throw - megaglest_runtime_error - ("Error converting from string ro resourceClass, found: " + s); - } + ResourceClass ResourceType::strToRc(const string & s) { + if (s == "tech") { + return rcTech; + } + if (s == "tileset") { + return rcTileset; + } + if (s == "static") { + return rcStatic; + } + if (s == "consumable") { + return rcConsumable; + } + throw + megaglest_runtime_error + ("Error converting from string ro resourceClass, found: " + s); + } - void ResourceType::deletePixels () - { - if (model != NULL) - { - model->deletePixels (); - } - } + void ResourceType::deletePixels() { + if (model != NULL) { + model->deletePixels(); + } + } - void ResourceType::saveGame (XmlNode * rootNode) - { - //DisplayableType::saveGame(rootNode); + void ResourceType::saveGame(XmlNode * rootNode) { + //DisplayableType::saveGame(rootNode); - std::map < string, string > mapTagReplacements; - XmlNode *resourceTypeNode = rootNode->addChild ("ResourceType"); + std::map < string, string > mapTagReplacements; + XmlNode *resourceTypeNode = rootNode->addChild("ResourceType"); - resourceTypeNode->addAttribute ("name", this->getName (), - mapTagReplacements); -// ResourceClass resourceClass; - resourceTypeNode->addAttribute ("resourceClass", - intToStr (resourceClass), - mapTagReplacements); -// int tilesetObject; //used only if class==rcTileset - resourceTypeNode->addAttribute ("tilesetObject", - intToStr (tilesetObject), - mapTagReplacements); -// int resourceNumber; //used only if class==rcTech, resource number in the map - resourceTypeNode->addAttribute ("resourceNumber", - intToStr (resourceNumber), - mapTagReplacements); -// int interval; //used only if class==rcConsumable - resourceTypeNode->addAttribute ("interval", intToStr (interval), - mapTagReplacements); -// int defResPerPatch; //used only if class==rcTileset || class==rcTech - resourceTypeNode->addAttribute ("defResPerPatch", - intToStr (defResPerPatch), - mapTagReplacements); -// bool recoup_cost; - resourceTypeNode->addAttribute ("recoup_cost", intToStr (recoup_cost), - mapTagReplacements); -// -// Model *model; - if (model != NULL) - { - resourceTypeNode->addAttribute ("model", model->getFileName (), - mapTagReplacements); - } -// ObjectParticleSystemTypes particleTypes; - for (unsigned int i = 0; i < particleTypes.size (); ++i) - { - ObjectParticleSystemType *opst = particleTypes[i]; - opst->saveGame (resourceTypeNode); - } - } + resourceTypeNode->addAttribute("name", this->getName(), + mapTagReplacements); + // ResourceClass resourceClass; + resourceTypeNode->addAttribute("resourceClass", + intToStr(resourceClass), + mapTagReplacements); + // int tilesetObject; //used only if class==rcTileset + resourceTypeNode->addAttribute("tilesetObject", + intToStr(tilesetObject), + mapTagReplacements); + // int resourceNumber; //used only if class==rcTech, resource number in the map + resourceTypeNode->addAttribute("resourceNumber", + intToStr(resourceNumber), + mapTagReplacements); + // int interval; //used only if class==rcConsumable + resourceTypeNode->addAttribute("interval", intToStr(interval), + mapTagReplacements); + // int defResPerPatch; //used only if class==rcTileset || class==rcTech + resourceTypeNode->addAttribute("defResPerPatch", + intToStr(defResPerPatch), + mapTagReplacements); + // bool recoup_cost; + resourceTypeNode->addAttribute("recoup_cost", intToStr(recoup_cost), + mapTagReplacements); + // + // Model *model; + if (model != NULL) { + resourceTypeNode->addAttribute("model", model->getFileName(), + mapTagReplacements); + } + // ObjectParticleSystemTypes particleTypes; + for (unsigned int i = 0; i < particleTypes.size(); ++i) { + ObjectParticleSystemType *opst = particleTypes[i]; + opst->saveGame(resourceTypeNode); + } + } -}} //end namespace + } +} //end namespace diff --git a/source/glest_game/types/resource_type.h b/source/glest_game/types/resource_type.h index 6bb3f6dfd..96cbcf13b 100644 --- a/source/glest_game/types/resource_type.h +++ b/source/glest_game/types/resource_type.h @@ -24,107 +24,93 @@ # include "unit_particle_type.h" # include "object_type.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - using Shared::Graphics::Model; - using Shared::Util::Checksum; + using Shared::Graphics::Model; + using Shared::Util::Checksum; - enum ResourceClass - { - rcTech, - rcTileset, - rcStatic, - rcConsumable - }; + enum ResourceClass { + rcTech, + rcTileset, + rcStatic, + rcConsumable + }; -// ===================================================== -// class ResourceType -// -/// A type of resource that can be harvested or not -// ===================================================== + // ===================================================== + // class ResourceType + // + /// A type of resource that can be harvested or not + // ===================================================== - class ResourceType:public DisplayableType - { - private: - ResourceClass resourceClass; - int tilesetObject; //used only if class==rcTileset - int resourceNumber; //used only if class==rcTech, resource number in the map - int interval; //used only if class==rcConsumable - int defResPerPatch; //used only if class==rcTileset || class==rcTech - bool recoup_cost; - bool displayInHud; + class ResourceType :public DisplayableType { + private: + ResourceClass resourceClass; + int tilesetObject; //used only if class==rcTileset + int resourceNumber; //used only if class==rcTech, resource number in the map + int interval; //used only if class==rcConsumable + int defResPerPatch; //used only if class==rcTileset || class==rcTech + bool recoup_cost; + bool displayInHud; - Model *model; - ObjectParticleSystemTypes particleTypes; - bool cleanupMemory; + Model *model; + ObjectParticleSystemTypes particleTypes; + bool cleanupMemory; - public: - ResourceType (); - ~ResourceType (); - void load (const string & dir, Checksum * checksum, - Checksum * techtreeChecksum, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string techtreePath); + public: + ResourceType(); + ~ResourceType(); + void load(const string & dir, Checksum * checksum, + Checksum * techtreeChecksum, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string techtreePath); - virtual string getName (bool translatedValue = false) const; - //get - int getClass () const - { - return resourceClass; - } - int getTilesetObject () const - { - return tilesetObject; - } - int getResourceNumber () const - { - return resourceNumber; - } - int getInterval () const - { - return interval; - } - int getDefResPerPatch () const - { - return defResPerPatch; - } - Model *getModel () const - { - return model; - } - bool getRecoup_cost () const - { - return recoup_cost; - } - bool getDisplayInHud () const - { - return displayInHud; - } + virtual string getName(bool translatedValue = false) const; + //get + int getClass() const { + return resourceClass; + } + int getTilesetObject() const { + return tilesetObject; + } + int getResourceNumber() const { + return resourceNumber; + } + int getInterval() const { + return interval; + } + int getDefResPerPatch() const { + return defResPerPatch; + } + Model *getModel() const { + return model; + } + bool getRecoup_cost() const { + return recoup_cost; + } + bool getDisplayInHud() const { + return displayInHud; + } - bool hasParticles () const - { - return !particleTypes.empty (); - } - const ObjectParticleSystemTypes *getObjectParticleSystemTypes () const - { - return &particleTypes; - } + bool hasParticles() const { + return !particleTypes.empty(); + } + const ObjectParticleSystemTypes *getObjectParticleSystemTypes() const { + return &particleTypes; + } - void setCleanupMemory (bool value) - { - cleanupMemory = value; - } + void setCleanupMemory(bool value) { + cleanupMemory = value; + } - static ResourceClass strToRc (const string & s); - void deletePixels (); + static ResourceClass strToRc(const string & s); + void deletePixels(); - void saveGame (XmlNode * rootNode); - }; + void saveGame(XmlNode * rootNode); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/types/skill_type.cpp b/source/glest_game/types/skill_type.cpp index fc197038f..73e10fe8c 100644 --- a/source/glest_game/types/skill_type.cpp +++ b/source/glest_game/types/skill_type.cpp @@ -28,2056 +28,1776 @@ using namespace Shared::Util; using namespace Shared::Graphics; -namespace Glest -{ - namespace Game - { - - int SkillType::nextAttackBoostId = 0; - - AttackBoost::AttackBoost ():boostUpgrade () - { - enabled = false; - allowMultipleBoosts = false; - radius = 0; - targetType = abtFaction; - unitParticleSystemTypeForSourceUnit = NULL; - unitParticleSystemTypeForAffectedUnit = NULL; - includeSelf = false; - } - - AttackBoost::~AttackBoost () - { - delete unitParticleSystemTypeForSourceUnit; - unitParticleSystemTypeForSourceUnit = NULL; - - delete unitParticleSystemTypeForAffectedUnit; - unitParticleSystemTypeForAffectedUnit = NULL; - } - - bool AttackBoost::isAffected (const Unit * source, const Unit * dest) const - { - bool result = false; - if (enabled == true && - source != NULL && dest != NULL && - (includeSelf == true || source != dest)) - { - bool destUnitMightApply = false; - if (source == dest && includeSelf == true) - { - destUnitMightApply = true; - } - else - { - // All units are affected (including enemies) - if (targetType == abtAll) - { - destUnitMightApply = (boostUnitList.empty () && tags.empty ()) - || isInUnitListOrTags (dest->getType ());; - } - // Only same faction units are affected - else if (targetType == abtFaction) - { - if (source->getFactionIndex () == dest->getFactionIndex ()) - { - destUnitMightApply = (boostUnitList.empty () && tags.empty ()) - || isInUnitListOrTags (dest->getType ()); - } - } - // Only ally units are affected - else if (targetType == abtAlly) - { - if (source->isAlly (dest) == true) - { - destUnitMightApply = (boostUnitList.empty () && tags.empty ()) - || isInUnitListOrTags (dest->getType ()); - } - } - // Only foe units are affected - else if (targetType == abtFoe) - { - if (source->isAlly (dest) == false) - { - destUnitMightApply = (boostUnitList.empty () && tags.empty ()) - || isInUnitListOrTags (dest->getType ()); - } - } - else if (targetType == abtUnitTypes) - { - destUnitMightApply = isInUnitListOrTags (dest->getType ()); - } - } - - if (destUnitMightApply == true) - { - float distance = - source->getCenteredPos ().dist (dest->getCenteredPos ()); - if (distance <= radius) - { - result = true; - } - } - } - - return result; - } - - bool AttackBoost::isInUnitListOrTags (const UnitType * unitType) const - { - // Specify which units are affected - std::set < const UnitType *>::iterator it; - for (it = boostUnitList.begin (); it != boostUnitList.end (); ++it) - { - const UnitType *boostUnit = *it; - if (unitType->getId () == boostUnit->getId ()) - { - return true; - } - } - set < string > unitTags = unitType->getTags (); - set < string > intersect; - set_intersection (tags.begin (), tags.end (), unitTags.begin (), - unitTags.end (), std::inserter (intersect, - intersect.begin ())); - if (!intersect.empty ()) - return true; - - // Otherwise no match - return false; - } - - string AttackBoost::getTagName (string tag, bool translatedValue) const - { - if (translatedValue == false) - return tag; - - Lang & lang = Lang::getInstance (); - return lang.getTechTreeString ("TagName_" + tag, tag.c_str ()); - } - - string AttackBoost::getDesc (bool translatedValue) const - { - Lang & lang = Lang::getInstance (); - string str = ""; - string indent = " "; - if (enabled) - { - if (boostUnitList.empty () == false) - { - str += "\n" + lang.getString ("Effects") + ":\n"; - } - - str += - indent + lang.getString ("effectRadius") + ": " + - intToStr (radius) + "\n"; - if (allowMultipleBoosts == false) - { - string allowIt = lang.getString ("No"); - if (allowMultipleBoosts == true) - allowIt = lang.getString ("False"); - str += - indent + lang.getString ("allowMultiBoost") + ": " + allowIt + - "\n"; - } - str += boostUpgrade.getDesc (translatedValue); - - if (targetType == abtAlly) - { - str += lang.getString ("AffectedUnitsFromTeam") + ":\n"; - } - else if (targetType == abtFoe) - { - str += lang.getString ("AffectedUnitsFromFoe") + ":\n"; - } - else if (targetType == abtFaction) - { - str += lang.getString ("AffectedUnitsFromYourFaction") + ":\n"; - } - else if (targetType == abtUnitTypes) - { - str += lang.getString ("AffectedUnitsFromAll") + ":\n"; - } - else if (targetType == abtAll) - { - str += lang.getString ("AffectedUnitsFromAll") + ":\n"; - } - - if (boostUnitList.empty () && tags.empty ()) - { - str += lang.getString ("All") + "\n"; - } - else - { - // We want the output to be sorted, so convert the set to a vector and sort that - std::vector < const UnitType *>outputUnits (boostUnitList.begin (), - boostUnitList.end ()); - std::sort (outputUnits.begin (), outputUnits.end (), - UnitTypeSorter ()); - - vector < const UnitType *>::iterator unitIter; - for (unitIter = outputUnits.begin (); - unitIter != outputUnits.end (); ++unitIter) - { - const UnitType *unit = *unitIter; - str += indent + unit->getName (translatedValue) + "\n"; - } - - // Do the same for tags - std::vector < string > outputTags (tags.begin (), tags.end ()); - std::sort (outputTags.begin (), outputTags.end ()); - - vector < string >::iterator tagIter; - for (tagIter = outputTags.begin (); tagIter != outputTags.end (); - ++tagIter) - { - string tag = *tagIter; - str += - indent + lang.getString ("TagDesc", - (translatedValue == - true ? "" : "english")) + " " + - getTagName (tag, translatedValue) + "\n"; - } - } - - return str; - } - else - return ""; - } - - void AttackBoost::loadGame (const XmlNode * rootNode, Faction * faction, - const SkillType * skillType) - { - const XmlNode *attackBoostNode = rootNode->getChild ("AttackBoost"); - - enabled = - (attackBoostNode->getAttribute ("enabled")->getIntValue () != 0); - allowMultipleBoosts = - (attackBoostNode->getAttribute ("allowMultipleBoosts")-> - getIntValue () != 0); - radius = attackBoostNode->getAttribute ("radius")->getIntValue (); - targetType = - static_cast < AttackBoostTargetType > - (attackBoostNode->getAttribute ("targetType")->getIntValue ()); - - if (attackBoostNode->hasChild ("UnitType") == true) - { - vector < XmlNode * >attackBoostNodeList = - attackBoostNode->getChildList ("UnitType"); - for (unsigned int i = 0; i < attackBoostNodeList.size (); ++i) - { - XmlNode *node = attackBoostNodeList[i]; - - string unitTypeName = node->getAttribute ("name")->getValue (); - const UnitType *unitType = - faction->getType ()->getUnitType (unitTypeName); - if (unitType != NULL) - { - boostUnitList.insert (unitType); - } - } - } - if (attackBoostNode->hasChild ("tag")) - { - vector < XmlNode * >tagNodeList = - attackBoostNode->getChildList ("tag"); - for (unsigned int i = 0; i < tagNodeList.size (); ++i) - { - XmlNode *node = tagNodeList[i]; - string tagName = node->getAttribute ("name")->getValue (); - tags.insert (tagName); - } - } - //boostUpgrade.loadGame(attackBoostNode,faction); - boostUpgrade = skillType->getAttackBoost ()->boostUpgrade; - - unitParticleSystemTypeForSourceUnit = new UnitParticleSystemType (); - unitParticleSystemTypeForSourceUnit->loadGame (attackBoostNode); - - unitParticleSystemTypeForAffectedUnit = new UnitParticleSystemType (); - unitParticleSystemTypeForAffectedUnit->loadGame (attackBoostNode); - - includeSelf = - (attackBoostNode->getAttribute ("includeSelf")->getIntValue () != 0); - name = attackBoostNode->getAttribute ("name")->getValue (); - } - - void AttackBoost::saveGame (XmlNode * rootNode) const - { - std::map < string, string > mapTagReplacements; - XmlNode *attackBoostNode = rootNode->addChild ("AttackBoost"); - -// bool enabled; - attackBoostNode->addAttribute ("enabled", intToStr (enabled), - mapTagReplacements); -// bool allowMultipleBoosts; - attackBoostNode->addAttribute ("allowMultipleBoosts", - intToStr (allowMultipleBoosts), - mapTagReplacements); -// int radius; - attackBoostNode->addAttribute ("radius", intToStr (radius), - mapTagReplacements); -// AttackBoostTargetType targetType; - attackBoostNode->addAttribute ("targetType", intToStr (targetType), - mapTagReplacements); -// vector boostUnitList; - std::set < const UnitType *>::iterator unitIter; - for (unitIter = boostUnitList.begin (); - unitIter != boostUnitList.end (); ++unitIter) - { - const UnitType *unit = *unitIter; - XmlNode *unitTypeNode = attackBoostNode->addChild ("UnitType"); - unitTypeNode->addAttribute ("name", unit->getName (false), - mapTagReplacements); - } - std::set < string >::iterator tagIter; - for (tagIter = tags.begin (); tagIter != tags.end (); ++tagIter) - { - string tag = *tagIter; - XmlNode *unitTypeNode = attackBoostNode->addChild ("tag"); - unitTypeNode->addAttribute ("name", tag, mapTagReplacements); - } -// UpgradeTypeBase boostUpgrade; - boostUpgrade.saveGame (attackBoostNode); -// UnitParticleSystemType *unitParticleSystemTypeForSourceUnit; - if (unitParticleSystemTypeForSourceUnit != NULL) - { - unitParticleSystemTypeForSourceUnit->saveGame (attackBoostNode); - } -// UnitParticleSystemType *unitParticleSystemTypeForAffectedUnit; - if (unitParticleSystemTypeForAffectedUnit != NULL) - { - unitParticleSystemTypeForAffectedUnit->saveGame (attackBoostNode); - } - -// bool includeSelf; - attackBoostNode->addAttribute ("includeSelf", intToStr (includeSelf), - mapTagReplacements); -// string name; - attackBoostNode->addAttribute ("name", name, mapTagReplacements); - } - -// ===================================================== -// class SkillSound -// ===================================================== - SkillSound::SkillSound () - { - startTime = 0.0f; - } - SkillSound::~SkillSound () - { - deleteValues (soundContainer.getSounds ().begin (), - soundContainer.getSounds ().end ()); - startTime = 0.0f; - //soundContainer - } -// ===================================================== -// class SkillType -// ===================================================== - - SkillType::~SkillType () - { - while (!skillSoundList.empty ()) - { - delete skillSoundList.back (); - skillSoundList.pop_back (); - } - //remove unitParticleSystemTypes - while (!unitParticleSystemTypes.empty ()) - { - delete unitParticleSystemTypes.back (); - unitParticleSystemTypes.pop_back (); - } - } - - const XmlNode *SkillType::findAttackBoostDetails (string attackBoostName, - const XmlNode * - attackBoostsNode, - const XmlNode * - attackBoostNode) - { - const XmlNode *result = attackBoostNode; - - if (attackBoostsNode != NULL && attackBoostName != "") - { - for (int i = 0; i < (int) attackBoostsNode->getChildCount (); ++i) - { - const XmlNode *abn = attackBoostsNode->getChild ("attack-boost", i); - - string sharedName = - abn->getAttribute ("name")->getRestrictedValue (); - if (sharedName == attackBoostName) - { - result = abn; - break; - } - } - - } - - return result; - } - - void SkillType::loadAttackBoost (const XmlNode * attackBoostsNode, - const XmlNode * attackBoostNode, - const FactionType * ft, - string parentLoader, const string & dir, - string currentPath, std::map < string, - vector < pair < string, - string > > >&loadedFileList, - const TechTree * tt) - { - - attackBoost.enabled = true; - if (attackBoostNode->hasAttribute ("name") == true) - { - attackBoost.name = - attackBoostNode->getAttribute ("name")->getRestrictedValue (); - - attackBoostNode = - findAttackBoostDetails (attackBoost.name, attackBoostsNode, - attackBoostNode); - } - else - { - attackBoost.name = - "attack-boost-autoname-" + intToStr (getNextAttackBoostId ()); - } - string targetType = - attackBoostNode->getChild ("target")->getAttribute ("value")-> - getValue (); - - attackBoost.allowMultipleBoosts = false; - if (attackBoostNode->hasChild ("allow-multiple-boosts") == true) - { - attackBoost.allowMultipleBoosts = - attackBoostNode->getChild ("allow-multiple-boosts")-> - getAttribute ("value")->getBoolValue (); - } - - attackBoost.radius = - attackBoostNode->getChild ("radius")->getAttribute ("value")-> - getIntValue (); - - attackBoost.includeSelf = false; - if (attackBoostNode->getChild ("target")-> - hasAttribute ("include-self") == true) - { - attackBoost.includeSelf = - attackBoostNode->getChild ("target")-> - getAttribute ("include-self")->getBoolValue (); - } - - if (targetType == "ally") - { - attackBoost.targetType = abtAlly; - } - else if (targetType == "foe") - { - attackBoost.targetType = abtFoe; - } - else if (targetType == "faction") - { - attackBoost.targetType = abtFaction; - } - else if (targetType == "unit-types") - { - attackBoost.targetType = abtUnitTypes; - } - else if (targetType == "all") - { - attackBoost.targetType = abtAll; - } - else - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "Unsupported target [%s] specified for attack boost for skill [%s] in [%s]", - targetType.c_str (), name.c_str (), parentLoader.c_str ()); - throw megaglest_runtime_error (szBuf, true); - } - - // Load the regular targets - const XmlNode *targetNode = attackBoostNode->getChild ("target"); - vector < XmlNode * >targetNodes = - targetNode->getChildList ("unit-type"); - for (size_t i = 0; i < targetNodes.size (); ++i) - { - string unitName = - targetNodes.at (i)->getAttribute ("name")->getRestrictedValue (); - attackBoost.boostUnitList.insert (ft->getUnitType (unitName)); - } - - // Load tags - vector < XmlNode * >tagNodes = targetNode->getChildList ("tag"); - for (size_t i = 0; i < tagNodes.size (); ++i) - { - string unitName = - tagNodes.at (i)->getAttribute ("name")->getRestrictedValue (); - attackBoost.tags.insert (unitName); - } - - attackBoost.boostUpgrade.load (attackBoostNode, attackBoost.name); - if (attackBoostNode->hasChild ("particles") == true) - { - const XmlNode *particleNode = attackBoostNode->getChild ("particles"); - bool particleEnabled = - particleNode->getAttribute ("value")->getBoolValue (); - if (particleEnabled == true) - { - if (particleNode->hasChild ("originator-particle-file") == true) - { - const XmlNode *particleFileNode = - particleNode->getChild ("originator-particle-file"); - string path = - particleFileNode->getAttribute ("path")->getRestrictedValue (); - attackBoost.unitParticleSystemTypeForSourceUnit = - new UnitParticleSystemType (); - attackBoost.unitParticleSystemTypeForSourceUnit-> - load (particleFileNode, dir, currentPath + path, - &Renderer::getInstance (), loadedFileList, parentLoader, - tt->getPath ()); - loadedFileList[currentPath + - path].push_back (make_pair (parentLoader, - particleFileNode-> - getAttribute ("path")-> - getRestrictedValue - ())); - } - if (particleNode->hasChild ("affected-particle-file") == true) - { - const XmlNode *particleFileNode = - particleNode->getChild ("affected-particle-file"); - string path = - particleFileNode->getAttribute ("path")->getRestrictedValue (); - attackBoost.unitParticleSystemTypeForAffectedUnit = - new UnitParticleSystemType (); - attackBoost.unitParticleSystemTypeForAffectedUnit-> - load (particleFileNode, dir, currentPath + path, - &Renderer::getInstance (), loadedFileList, parentLoader, - tt->getPath ()); - loadedFileList[currentPath + - path].push_back (make_pair (parentLoader, - particleFileNode-> - getAttribute ("path")-> - getRestrictedValue - ())); - } - } - } - } - - void SkillType::load (const XmlNode * sn, - const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader) - { - //name - name = - sn->getChild ("name")->getAttribute ("value")->getRestrictedValue (); - - //ep cost - if (sn->hasChild ("ep-cost") == true) - { - mpCost = - sn->getChild ("ep-cost")->getAttribute ("value")->getIntValue (); - } - else - { - mpCost = 0; - } - - if (sn->hasChild ("hp-cost") == true) - { - hpCost = - sn->getChild ("hp-cost")->getAttribute ("value")->getIntValue (); - } - else - { - hpCost = 0; - } - - //speed - if (sn->hasChild ("speed") == true) - { - speed = - sn->getChild ("speed")->getAttribute ("value")->getIntValue (); - } - else - { - speed = 0; - } - - //anim speed - if (sn->hasChild ("anim-speed") == true) - { - animSpeed = - sn->getChild ("anim-speed")->getAttribute ("value")->getIntValue (); - } - else - { - animSpeed = 0; - } - - //model - string currentPath = dir; - endPathWithSlash (currentPath); - - animationRandomCycleMaxcount = -1; - if (sn->hasChild ("animation-random-cycle-maxcount") == true) - { - const XmlNode *randomCycleCountNode = - sn->getChild ("animation-random-cycle-maxcount"); - animationRandomCycleMaxcount = - randomCycleCountNode->getAttribute ("value")->getIntValue (); - } - - if (sn->hasChild ("animation") == true) - { - //string path= sn->getChild("animation")->getAttribute("path")->getRestrictedValue(currentPath); - vector < XmlNode * >animationList = sn->getChildList ("animation"); - for (unsigned int i = 0; i < animationList.size (); ++i) - { - string path = - animationList[i]->getAttribute ("path")-> - getRestrictedValue (currentPath); - if (fileExists (path) == true) - { - Model *animation = - Renderer::getInstance ().newModel (rsGame, path, false, - &loadedFileList, - &parentLoader); - loadedFileList[path]. - push_back (make_pair - (parentLoader, - animationList[i]->getAttribute ("path")-> - getRestrictedValue ())); - - animations.push_back (animation); - //printf("**FOUND ANIMATION [%s]\n",path.c_str()); - - AnimationAttributes animationAttributeList; - if (animationList[i]->getAttribute ("minHp", false) != NULL - && animationList[i]->getAttribute ("maxHp", false) != NULL) - { - animationAttributeList.fromHp = - animationList[i]->getAttribute ("minHp")->getIntValue (); - animationAttributeList.toHp = - animationList[i]->getAttribute ("maxHp")->getIntValue (); - } - animationAttributes.push_back (animationAttributeList); - } - else - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line %d] ERROR CANNOT LOAD MODEL [%s] for parentLoader [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - path.c_str (), parentLoader.c_str ()); - throw megaglest_runtime_error ("Error: cannot load model [" + - path + "] for skill [" + name + - "] ", true); - } - } - if (animations.empty () == true) - { - throw - megaglest_runtime_error ("Error no animations found for skill [" + - name + "] for parentLoader [" + - parentLoader + "]", true); - } - } - - //particles - if (sn->hasChild ("particles")) - { - const XmlNode *particleNode = sn->getChild ("particles"); - bool particleEnabled = - particleNode->getAttribute ("value")->getBoolValue (); - if (particleEnabled) - { - for (int i = 0; i < (int) particleNode->getChildCount (); ++i) - { - const XmlNode *particleFileNode = - particleNode->getChild ("particle-file", i); - string path = - particleFileNode->getAttribute ("path")->getRestrictedValue (); - UnitParticleSystemType *unitParticleSystemType = - new UnitParticleSystemType (); - unitParticleSystemType->load (particleFileNode, dir, - currentPath + path, - &Renderer::getInstance (), - loadedFileList, parentLoader, - tt->getPath ()); - - if (particleNode->getChild (i)->hasAttribute ("start-time")) - { - //printf("*NOTE particle system type has start-time [%f]\n",particleNode->getAttribute("start-time")->getFloatValue()); - unitParticleSystemType->setStartTime (particleNode-> - getChild (i)-> - getAttribute - ("start-time")-> - getFloatValue ()); - } - else if (particleNode->hasAttribute ("start-time")) - { - //printf("*NOTE particle system type has start-time [%f]\n",particleNode->getAttribute("start-time")->getFloatValue()); - unitParticleSystemType->setStartTime (particleNode-> - getAttribute - ("start-time")-> - getFloatValue ()); - } - - if (particleNode->getChild (i)->hasAttribute ("end-time")) - { - //printf("*NOTE particle system type has start-time [%f]\n",particleNode->getAttribute("start-time")->getFloatValue()); - unitParticleSystemType->setEndTime (particleNode->getChild (i)-> - getAttribute ("end-time")-> - getFloatValue ()); - } - else if (particleNode->hasAttribute ("end-time")) - { - //printf("*NOTE particle system type has end-time [%f]\n",particleNode->getAttribute("end-time")->getFloatValue()); - unitParticleSystemType->setEndTime (particleNode-> - getAttribute ("end-time")-> - getFloatValue ()); - } - - if (particleNode->getChild (i)->hasAttribute ("minHp") - && particleNode->getChild (i)->hasAttribute ("maxHp")) - { - unitParticleSystemType->setMinmaxEnabled (true); - unitParticleSystemType->setMinHp (particleNode->getChild (i)-> - getAttribute ("minHp")-> - getIntValue ()); - unitParticleSystemType->setMaxHp (particleNode->getChild (i)-> - getAttribute ("maxHp")-> - getIntValue ()); - - if (particleNode->getChild (i)->hasAttribute ("ispercentbased")) - { - unitParticleSystemType->setMinmaxIsPercent (particleNode-> - getChild (i)-> - getAttribute - ("ispercentbased")-> - getBoolValue ()); - } - } - - loadedFileList[currentPath + - path].push_back (make_pair (parentLoader, - particleFileNode-> - getAttribute ("path")-> - getRestrictedValue - ())); - unitParticleSystemTypes.push_back (unitParticleSystemType); - } - - //printf("Load skill particles line: %d size: %d\n",__LINE__,(int)unitParticleSystemTypes.size()); - } - } - - //sound - vector < XmlNode * >soundNodeList = sn->getChildList ("sound"); - for (unsigned int i = 0; i < soundNodeList.size (); ++i) - { - const XmlNode *soundNode = soundNodeList[i]; - if (soundNode->getAttribute ("enabled")->getBoolValue ()) - { - float soundStartTime = - soundNode->getAttribute ("start-time")->getFloatValue (); - SkillSound *skillSound = new SkillSound (); - skillSound->setStartTime (soundStartTime); - - skillSound->getSoundContainer ()->resize ((int) soundNode-> - getChildCount ()); - skillSoundList.push_back (skillSound); - for (int i = 0; i < (int) soundNode->getChildCount (); ++i) - { - const XmlNode *soundFileNode = - soundNode->getChild ("sound-file", i); - string path = - soundFileNode->getAttribute ("path")-> - getRestrictedValue (currentPath, true); - - StaticSound *sound = new StaticSound (); - sound->load (path); - loadedFileList[path]. - push_back (make_pair - (parentLoader, - soundFileNode->getAttribute ("path")-> - getRestrictedValue ())); - (*skillSound->getSoundContainer ())[i] = sound; - } - } - } - - - // attack-boost - if (sn->hasChild ("attack-boost") == true) - { - //printf("$$FOUND ATTACK BOOST FOR [%s]\n",parentLoader.c_str()); - const XmlNode *attackBoostNode = sn->getChild ("attack-boost"); - loadAttackBoost (attackBoostsNode, attackBoostNode, ft, parentLoader, - dir, currentPath, loadedFileList, tt); - } - - shake = false; - shakeIntensity = 50; - shakeDuration = 300; - shakeStartTime = 0.0f; - shakeSelfEnabled = false; - shakeSelfVisible = true; - shakeSelfInCameraView = false; - shakeSelfCameraAffected = false; - shakeTeamEnabled = false; - shakeTeamVisible = true; - shakeTeamInCameraView = false; - shakeTeamCameraAffected = false; - shakeEnemyEnabled = false; - shakeEnemyVisible = true; - shakeEnemyInCameraView = false; - shakeEnemyCameraAffected = false; - - if (sn->hasChild ("shake")) - { - XmlNode *shakeNode = sn->getChild ("shake"); - shake = shakeNode->getAttribute ("enabled")->getBoolValue (); - shakeIntensity = - shakeNode->getAttribute ("intensity")->getIntValue (); - shakeDuration = shakeNode->getAttribute ("duration")->getIntValue (); - if (shakeNode->hasAttribute ("start-time")) - { - shakeStartTime = - shakeNode->getAttribute ("start-time")->getFloatValue (); - } - if (shakeNode->hasChild ("self")) - { - shakeSelfEnabled = - shakeNode->getChild ("enemy")->getAttribute ("enabled")-> - getBoolValue (); - shakeSelfVisible = - shakeNode->getChild ("self")->getAttribute ("visible")-> - getBoolValue (); - shakeSelfInCameraView = - shakeNode->getChild ("self")->getAttribute ("in-camera-view")-> - getBoolValue (); - shakeSelfCameraAffected = - shakeNode->getChild ("self")-> - getAttribute ("camera-distance-affected")->getBoolValue (); - } - if (shakeNode->hasChild ("team")) - { - shakeTeamEnabled = - shakeNode->getChild ("enemy")->getAttribute ("enabled")-> - getBoolValue (); - shakeTeamVisible = - shakeNode->getChild ("team")->getAttribute ("visible")-> - getBoolValue (); - shakeTeamInCameraView = - shakeNode->getChild ("team")->getAttribute ("in-camera-view")-> - getBoolValue (); - shakeTeamCameraAffected = - shakeNode->getChild ("team")-> - getAttribute ("camera-distance-affected")->getBoolValue (); - } - if (shakeNode->hasChild ("enemy")) - { - shakeEnemyEnabled = - shakeNode->getChild ("enemy")->getAttribute ("enabled")-> - getBoolValue (); - shakeEnemyVisible = - shakeNode->getChild ("enemy")->getAttribute ("visible")-> - getBoolValue (); - shakeEnemyInCameraView = - shakeNode->getChild ("enemy")->getAttribute ("in-camera-view")-> - getBoolValue (); - shakeEnemyCameraAffected = - shakeNode->getChild ("enemy")-> - getAttribute ("camera-distance-affected")->getBoolValue (); - } - - //visible-for (team, self,all, team-and-visible, self-and-visible, all-and-visible ) - - } - } - - bool SkillType:: - CanCycleNextRandomAnimation (const int *animationRandomCycleCount) const - { - bool result = true; - if (animations.size () > 1) - { - if (animationRandomCycleMaxcount >= 0 && - animationRandomCycleCount != NULL && - *animationRandomCycleCount >= animationRandomCycleMaxcount) - { - result = false; - } - } - return result; - } - - const AnimationAttributes SkillType::getAnimationAttribute (int index) const - { - return animationAttributes[index]; - } - - Model *SkillType::getAnimation (float animProgress, const Unit * unit, - int *lastAnimationIndex, - int *animationRandomCycleCount) const - { - int modelIndex = 0; - //printf("Count [%d] animProgress = [%f] for skill [%s] animationRandomCycleCount = %d\n",animations.size(),animProgress,name.c_str(),*animationRandomCycleCount); - if (animations.size () > 1) - { - //printf("animProgress = [%f] for skill [%s] animationRandomCycleCount = %d\n",animProgress,name.c_str(),*animationRandomCycleCount); - - if (lastAnimationIndex) - { - modelIndex = *lastAnimationIndex; - } - if (modelIndex < 0 || animProgress > 1.0f) - { - bool canCycle = - CanCycleNextRandomAnimation (animationRandomCycleCount); - if (canCycle == true) - { - vector < int >filteredAnimations; - bool foundSpecificAnimation = false; - if (unit != NULL) - { - for (unsigned int i = 0; i < animationAttributes.size (); ++i) - { - const AnimationAttributes & attributes = - animationAttributes[i]; - if (attributes.fromHp != 0 || attributes.toHp != 0) - { - if (unit->getHp () >= attributes.fromHp - && unit->getHp () <= attributes.toHp) - { - //modelIndex = i; - foundSpecificAnimation = true; - filteredAnimations.push_back (i); - //printf("SELECTING Model index = %d [%s] model attributes [%d to %d] for unit [%s - %d] with HP = %d\n",i,animations[modelIndex]->getFileName().c_str(),attributes.fromHp,attributes.toHp,unit->getType()->getName().c_str(),unit->getId(),unit->getHp()); - //break; - } - } - } - // Need to make sure the filtered list does NOT include any - // models with min/max hp - if (foundSpecificAnimation == false) - { - for (unsigned int i = 0; i < animationAttributes.size (); ++i) - { - const AnimationAttributes & attributes = - animationAttributes[i]; - if (attributes.fromHp == 0 && attributes.toHp == 0) - { - //modelIndex = i; - foundSpecificAnimation = true; - filteredAnimations.push_back (i); - //printf("SELECTING Model index = %d [%s] model attributes [%d to %d] for unit [%s - %d] with HP = %d\n",i,animations[modelIndex]->getFileName().c_str(),attributes.fromHp,attributes.toHp,unit->getType()->getName().c_str(),unit->getId(),unit->getHp()); - //break; - } - } - } - } - - if (foundSpecificAnimation == false) - { - //int modelIndex = random.randRange(0,animations.size()-1); - Chrono seed (true); - srand ((unsigned int) seed.getCurTicks () + - (unit != NULL ? unit->getId () : 0)); - - modelIndex = rand () % animations.size (); - - //const AnimationAttributes &attributes = animationAttributes[modelIndex]; - //printf("SELECTING RANDOM Model index = %d [%s] model attributes [%d to %d] for unit [%s - %d] with HP = %d\n",modelIndex,animations[modelIndex]->getFileName().c_str(),attributes.fromHp,attributes.toHp,unit->getType()->getName().c_str(),unit->getId(),unit->getHp()); - } - else - { - Chrono seed (true); - srand ((unsigned int) seed.getCurTicks () + unit->getId ()); - - int filteredModelIndex = rand () % filteredAnimations.size (); - modelIndex = filteredAnimations[filteredModelIndex]; - } - } - } - } - if (lastAnimationIndex) - { - if (*lastAnimationIndex != modelIndex) - { - //printf("Switching model from [%s] to [%s]\n",(*lastAnimationIndex >= 0 ? animations[*lastAnimationIndex]->getFileName().c_str() : "none"),animations[modelIndex]->getFileName().c_str()); - } - *lastAnimationIndex = modelIndex; - } - - //printf("!!RETURN ANIMATION [%d / %d]\n",modelIndex,animations.size()-1); - return animations[modelIndex]; - } - - string SkillType::skillClassToStr (SkillClass skillClass) - { - switch (skillClass) - { - case scStop: - return "Stop"; - case scMove: - return "Move"; - case scAttack: - return "Attack"; - case scHarvest: - return "Harvest"; - case scRepair: - return "Repair"; - case scBuild: - return "Build"; - case scDie: - return "Die"; - case scBeBuilt: - return "Be Built"; - case scProduce: - return "Produce"; - case scUpgrade: - return "Upgrade"; - case scFogOfWar: - return "Fog Of War"; - default: - assert (false); - break; - } - return ""; - } - - string SkillType::fieldToStr (Field field) - { - Lang & lang = Lang::getInstance (); - string fieldName = ""; - switch (field) - { - case fLand: - if (lang.hasString ("FieldLand") == true) - { - fieldName = lang.getString ("FieldLand"); - } - else - { - fieldName = "Land"; - } - //return "Land"; - return lang.getTilesetString ("FieldLandName", fieldName.c_str ()); - - case fAir: - if (lang.hasString ("FieldAir") == true) - { - fieldName = lang.getString ("FieldAir"); - } - else - { - fieldName = "Air"; - } - - //return "Air"; - return lang.getTilesetString ("FieldAirName", fieldName.c_str ()); - default: - assert (false); - break; - } - return ""; - } - - void SkillType::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode *skillTypeNode = rootNode->addChild ("SkillType"); - -// SkillClass skillClass; - skillTypeNode->addAttribute ("skillClass", intToStr (skillClass), - mapTagReplacements); -// string name; - skillTypeNode->addAttribute ("name", name, mapTagReplacements); -// int mpCost; - skillTypeNode->addAttribute ("mpCost", intToStr (mpCost), - mapTagReplacements); -// int hpCost; - skillTypeNode->addAttribute ("hpCost", intToStr (hpCost), - mapTagReplacements); -// int speed; - skillTypeNode->addAttribute ("speed", intToStr (speed), - mapTagReplacements); -// int animSpeed; - skillTypeNode->addAttribute ("animSpeed", intToStr (animSpeed), - mapTagReplacements); -// int animationRandomCycleMaxcount; - skillTypeNode->addAttribute ("animationRandomCycleMaxcount", - intToStr (animationRandomCycleMaxcount), - mapTagReplacements); -// vector animations; -// vector animationAttributes; -// -// SoundContainer sounds; -// float soundStartTime; -// skillTypeNode->addAttribute("soundStartTime",floatToStr(soundStartTime,6), mapTagReplacements); -// RandomGen random; - skillTypeNode->addAttribute ("random", - intToStr (random.getLastNumber ()), - mapTagReplacements); -// AttackBoost attackBoost; - attackBoost.saveGame (skillTypeNode); -// static int nextAttackBoostId; - skillTypeNode->addAttribute ("nextAttackBoostId", - intToStr (nextAttackBoostId), - mapTagReplacements); -// UnitParticleSystemTypes unitParticleSystemTypes; - for (UnitParticleSystemTypes::iterator it = - unitParticleSystemTypes.begin (); - it != unitParticleSystemTypes.end (); ++it) - { - (*it)->saveGame (skillTypeNode); - } - } - -// ===================================================== -// class StopSkillType -// ===================================================== - - StopSkillType::StopSkillType () - { - skillClass = scStop; - } - - string StopSkillType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Stop"; - } - return Lang::getInstance ().getString ("Stop"); - } - -// ===================================================== -// class MoveSkillType -// ===================================================== - - MoveSkillType::MoveSkillType () - { - skillClass = scMove; - } - - string MoveSkillType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Move"; - } - - return Lang::getInstance ().getString ("Move"); - } - - int MoveSkillType::getTotalSpeed (const TotalUpgrade * totalUpgrade) const - { - int result = speed + totalUpgrade->getMoveSpeed (this); - result = max (0, result); - return result; - } - -// ===================================================== -// class AttackSkillType -// ===================================================== - -//varios - AttackSkillType::AttackSkillType () - { - skillClass = scAttack; - attackType = NULL; - projectile = false; - splash = false; - splashRadius = 0; - spawnUnit = ""; - spawnUnitcount = 0; - spawnUnitAtTarget = false; - splashParticleSystemType = NULL; - - for (int i = 0; i < fieldCount; ++i) - { - attackFields[i] = false; - } - - attackStrength = 0; - attackVar = 0; - attackRange = 0; - attackStartTime = 0; - splashDamageAll = false; - } - - AttackSkillType::~AttackSkillType () - { - - deleteValues (projectileTypes.begin (), projectileTypes.end ()); - - delete splashParticleSystemType; - splashParticleSystemType = NULL; - deleteValues (projSounds.getSounds ().begin (), - projSounds.getSounds ().end ()); - projSounds.clearSounds (); - } - - void AttackSkillType::load (const XmlNode * sn, - const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - SkillType::load (sn, attackBoostsNode, dir, tt, ft, loadedFileList, - parentLoader); - - string currentPath = dir; - endPathWithSlash (currentPath); - - //misc - std::vector < string > attackStrengthXMLTags; - attackStrengthXMLTags.push_back ("attack-strenght"); - attackStrengthXMLTags.push_back ("attack-strength"); - attackStrength = - sn->getChildWithAliases (attackStrengthXMLTags)-> - getAttribute ("value")->getIntValue (); - attackVar = - sn->getChild ("attack-var")->getAttribute ("value")->getIntValue (); - - if (attackVar < 0) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The attack skill has an INVALID attack var value which is < 0 [%d] in file [%s]!", - attackVar, dir.c_str ()); - throw megaglest_runtime_error (szBuf, true); - } - - attackRange = - sn->getChild ("attack-range")->getAttribute ("value")->getIntValue (); - string attackTypeName = - sn->getChild ("attack-type")->getAttribute ("value")-> - getRestrictedValue (); - attackType = tt->getAttackType (attackTypeName); - attackStartTime = - sn->getChild ("attack-start-time")->getAttribute ("value")-> - getFloatValue (); - - if (sn->hasChild ("unit")) - { - spawnUnit = - sn->getChild ("unit")->getAttribute ("value")->getValue (); - spawnUnitcount = - sn->getChild ("unit")->getAttribute ("amount")->getIntValue (); - if (sn->getChild ("unit")->hasAttribute ("spawnAtTarget")) - { - spawnUnitAtTarget = - sn->getChild ("unit")->getAttribute ("spawnAtTarget")-> - getBoolValue (); - } - else - { - spawnUnitAtTarget = false; - } - } - else - { - spawnUnit = ""; - spawnUnitcount = 0; - spawnUnitAtTarget = false; - } - //attack fields - const XmlNode *attackFieldsNode = sn->getChild ("attack-fields"); - for (int i = 0; i < (int) attackFieldsNode->getChildCount (); ++i) - { - const XmlNode *fieldNode = attackFieldsNode->getChild ("field", i); - string fieldName = - fieldNode->getAttribute ("value")->getRestrictedValue (); - if (fieldName == "land") - { - attackFields[fLand] = true; - } - else if (fieldName == "air") - { - attackFields[fAir] = true; - } - else - { - throw megaglest_runtime_error ("Not a valid field: " + fieldName + - ": " + dir, true); - } - } - - if (sn->hasChild ("projectile")) - { - //projectile -- backward compatible old behaviour with only one projectile - const XmlNode *projectileNode = sn->getChild ("projectile"); - projectile = projectileNode->getAttribute ("value")->getBoolValue (); - if (projectile) - { - // create new projectile - ProjectileType *projectileType = new ProjectileType (); - //only add this projectile if there is an enabled particlesystem - //projectileTypes.push_back(projectileType); - projectileType->setAttackStartTime (attackStartTime); - projectileType->setDamagePercentage (100); - //proj particle - if (projectileNode->hasChild ("particle")) - { - const XmlNode *particleNode = - projectileNode->getChild ("particle"); - bool particleEnabled = - particleNode->getAttribute ("value")->getBoolValue (); - if (particleEnabled) - { - projectileTypes.push_back (projectileType); - string path = - particleNode->getAttribute ("path")->getRestrictedValue (); - ParticleSystemTypeProjectile *projectileParticleSystemType = - new ParticleSystemTypeProjectile (); - projectileParticleSystemType->load (particleNode, dir, - currentPath + path, - &Renderer::getInstance (), - loadedFileList, - parentLoader, - tt->getPath ()); - loadedFileList[currentPath + - path].push_back (make_pair (parentLoader, - particleNode-> - getAttribute - ("path")-> - getRestrictedValue - ())); - projectileType-> - setProjectileParticleSystemType - (projectileParticleSystemType); - } - else - { - delete projectileType; - } - } - else - { - delete projectileType; - } - //proj sounds - const XmlNode *soundNode = projectileNode->getChild ("sound"); - if (soundNode->getAttribute ("enabled")->getBoolValue ()) - { - - projSounds.resize ((int) soundNode->getChildCount ()); - for (int i = 0; i < (int) soundNode->getChildCount (); ++i) - { - const XmlNode *soundFileNode = - soundNode->getChild ("sound-file", i); - string path = - soundFileNode->getAttribute ("path")-> - getRestrictedValue (currentPath, true); - //printf("\n\n\n\n!@#$ ---> parentLoader [%s] path [%s] nodeValue [%s] i = %d",parentLoader.c_str(),path.c_str(),soundFileNode->getAttribute("path")->getRestrictedValue().c_str(),i); - - StaticSound *sound = new StaticSound (); - sound->load (path); - loadedFileList[path]. - push_back (make_pair - (parentLoader, - soundFileNode->getAttribute ("path")-> - getRestrictedValue ())); - projSounds[i] = sound; - } - } - } - } - else - { - const XmlNode *projectilesNode = sn->getChild ("projectiles"); - vector < XmlNode * >projectilesNodeList = - projectilesNode->getChildList ("projectile"); - int totalDamagePercentage = 0; - for (unsigned int i = 0; i < projectilesNodeList.size (); ++i) - { - const XmlNode *projectileNode = projectilesNodeList[i]; - ProjectileType *projectileType = new ProjectileType (); - projectileType->load (projectileNode, dir, tt->getPath (), - loadedFileList, parentLoader); - totalDamagePercentage += projectileType->getDamagePercentage (); - projectileTypes.push_back (projectileType); - projectile = true; - } - - if (totalDamagePercentage != 100) - { - throw - megaglest_runtime_error - ("Damages percentages of projectiles don't sum up to 100 %", - true); - } - - if (sn->hasChild ("hitsound") == true) - { - //general hit sounds, individual ones can be set in projectiles - const XmlNode *soundNode = sn->getChild ("hitsound"); - if (soundNode->getAttribute ("enabled")->getBoolValue ()) - { - - projSounds.resize ((int) soundNode->getChildCount ()); - for (int i = 0; i < (int) soundNode->getChildCount (); ++i) - { - const XmlNode *soundFileNode = - soundNode->getChild ("sound-file", i); - string path = - soundFileNode->getAttribute ("path")-> - getRestrictedValue (currentPath, true); - //printf("\n\n\n\n!@#$ ---> parentLoader [%s] path [%s] nodeValue [%s] i = %d",parentLoader.c_str(),path.c_str(),soundFileNode->getAttribute("path")->getRestrictedValue().c_str(),i); - - StaticSound *sound = new StaticSound (); - sound->load (path); - loadedFileList[path]. - push_back (make_pair - (parentLoader, - soundFileNode->getAttribute ("path")-> - getRestrictedValue ())); - projSounds[i] = sound; - } - } - } - } - - //splash - const XmlNode *splashNode = sn->getChild ("splash"); - splash = splashNode->getAttribute ("value")->getBoolValue (); - if (splash) - { - splashRadius = - splashNode->getChild ("radius")->getAttribute ("value")-> - getIntValue (); - splashDamageAll = - splashNode->getChild ("damage-all")->getAttribute ("value")-> - getBoolValue (); - - //splash particle - const XmlNode *particleNode = splashNode->getChild ("particle"); - bool particleEnabled = - particleNode->getAttribute ("value")->getBoolValue (); - if (particleEnabled) - { - string path = - particleNode->getAttribute ("path")->getRestrictedValue (); - splashParticleSystemType = new ParticleSystemTypeSplash (); - splashParticleSystemType->load (particleNode, dir, - currentPath + path, - &Renderer::getInstance (), - loadedFileList, parentLoader, - tt->getPath ()); - } - } - } - - int AttackSkillType::getTotalSpeed (const TotalUpgrade * totalUpgrade) const - { - int result = speed + totalUpgrade->getAttackSpeed (this); - result = max (0, result); - return result; - } - -// Get the amount to boost the attack animation speed by (based on attack-speed upgrades) - int AttackSkillType::getAnimSpeedBoost (const TotalUpgrade * totalUpgrade) const - { - // Same calculation as in TotalUpgrade::sum, but bypassing the use of the value - // list (which is for the attack speed, not animation speed) - if (totalUpgrade->getAttackRangeIsMultiplier ()) - { - return animSpeed * (totalUpgrade->getAttackSpeed (NULL) / - (double) 100); - } - else - { - return totalUpgrade->getAttackSpeed (NULL); - } - } - - string AttackSkillType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Attack"; - } - - return Lang::getInstance ().getString ("Attack"); - } - -//get totals - int AttackSkillType::getTotalAttackStrength (const TotalUpgrade * - totalUpgrade) const - { - int result = attackStrength + totalUpgrade->getAttackStrength (this); - result = max (0, result); - return result; - } - - int AttackSkillType::getTotalAttackRange (const TotalUpgrade * - totalUpgrade) const - { - int result = attackRange + totalUpgrade->getAttackRange (this); - result = max (0, result); - return result; - } - - void AttackSkillType::saveGame (XmlNode * rootNode) - { - SkillType::saveGame (rootNode); - std::map < string, string > mapTagReplacements; - XmlNode *attackSkillTypeNode = rootNode->addChild ("AttackSkillType"); - -// int attackStrength; - attackSkillTypeNode->addAttribute ("attackStrength", - intToStr (attackStrength), - mapTagReplacements); -// int attackVar; - attackSkillTypeNode->addAttribute ("attackVar", intToStr (attackVar), - mapTagReplacements); -// int attackRange; - attackSkillTypeNode->addAttribute ("attackRange", - intToStr (attackRange), - mapTagReplacements); -// const AttackType *attackType; - if (attackType != NULL) - { - attackSkillTypeNode->addAttribute ("attackType", - attackType->getName (false), - mapTagReplacements); - } -// bool attackFields[fieldCount]; - for (unsigned int i = 0; i < fieldCount; ++i) - { - XmlNode *attackFieldsNode = - attackSkillTypeNode->addChild ("attackFields"); - attackFieldsNode->addAttribute ("key", intToStr (i), - mapTagReplacements); - attackFieldsNode->addAttribute ("value", intToStr (attackFields[i]), - mapTagReplacements); - } -// float attackStartTime; - attackSkillTypeNode->addAttribute ("attackStartTime", - floatToStr (attackStartTime, 6), - mapTagReplacements); -// string spawnUnit; - attackSkillTypeNode->addAttribute ("spawnUnit", spawnUnit, - mapTagReplacements); -// int spawnUnitcount; - attackSkillTypeNode->addAttribute ("spawnUnitcount", - intToStr (spawnUnitcount), - mapTagReplacements); -// bool spawnUnitAtTarget; - attackSkillTypeNode->addAttribute ("spawnUnitAtTarget", - intToStr (spawnUnitAtTarget), - mapTagReplacements); -// bool projectile; - attackSkillTypeNode->addAttribute ("projectile", intToStr (projectile), - mapTagReplacements); -// ParticleSystemTypeProjectile* projectileParticleSystemType; -// save a skill_type ???? - // if(projectileParticleSystemType != NULL) { -// projectileParticleSystemType->saveGame(attackSkillTypeNode); -// } -// SoundContainer projSounds; -// -// bool splash; - attackSkillTypeNode->addAttribute ("splash", intToStr (splash), - mapTagReplacements); -// int splashRadius; - attackSkillTypeNode->addAttribute ("splashRadius", - intToStr (splashRadius), - mapTagReplacements); -// bool splashDamageAll; - attackSkillTypeNode->addAttribute ("splashDamageAll", - intToStr (splashDamageAll), - mapTagReplacements); -// ParticleSystemTypeSplash* splashParticleSystemType; - if (splashParticleSystemType != NULL) - { - splashParticleSystemType->saveGame (attackSkillTypeNode); - } - } -// ===================================================== -// class BuildSkillType -// ===================================================== - - BuildSkillType::BuildSkillType () - { - skillClass = scBuild; - } - - string BuildSkillType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Build"; - } - - return Lang::getInstance ().getString ("Build"); - } - -// ===================================================== -// class HarvestSkillType -// ===================================================== - - HarvestSkillType::HarvestSkillType () - { - skillClass = scHarvest; - } - - string HarvestSkillType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Harvest"; - } - - return Lang::getInstance ().getString ("Harvest"); - } - -// ===================================================== -// class RepairSkillType -// ===================================================== - - RepairSkillType::RepairSkillType () - { - skillClass = scRepair; - } - - string RepairSkillType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Repair"; - } - - return Lang::getInstance ().getString ("Repair"); - } - -// ===================================================== -// class ProduceSkillType -// ===================================================== - - ProduceSkillType::ProduceSkillType () - { - skillClass = scProduce; - animProgressBound = false; - } - - void ProduceSkillType::load (const XmlNode * sn, - const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - SkillType::load (sn, attackBoostsNode, dir, tt, ft, loadedFileList, - parentLoader); - - if (sn->hasChild ("anim-progress-bound")) - { - animProgressBound = - sn->getChild ("anim-progress-bound")->getAttribute ("value")-> - getBoolValue (); - } - else - { - animProgressBound = false; - } - } - - - string ProduceSkillType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Produce"; - } - - return Lang::getInstance ().getString ("Produce"); - } - - int ProduceSkillType::getTotalSpeed (const TotalUpgrade * totalUpgrade) const - { - int result = speed + totalUpgrade->getProdSpeed (this); - result = max (0, result); - return result; - } - - void ProduceSkillType::saveGame (XmlNode * rootNode) - { - SkillType::saveGame (rootNode); - std::map < string, string > mapTagReplacements; - XmlNode *produceSkillTypeNode = rootNode->addChild ("ProduceSkillType"); - - produceSkillTypeNode->addAttribute ("animProgressBound", - intToStr (animProgressBound), - mapTagReplacements); - } -// ===================================================== -// class UpgradeSkillType -// ===================================================== - - UpgradeSkillType::UpgradeSkillType () - { - skillClass = scUpgrade; - animProgressBound = false; - } - - void UpgradeSkillType::load (const XmlNode * sn, - const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - SkillType::load (sn, attackBoostsNode, dir, tt, ft, loadedFileList, - parentLoader); - - if (sn->hasChild ("anim-progress-bound")) - { - animProgressBound = - sn->getChild ("anim-progress-bound")->getAttribute ("value")-> - getBoolValue (); - } - else - { - animProgressBound = false; - } - } - - string UpgradeSkillType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Upgrade"; - } - - return Lang::getInstance ().getString ("Upgrade"); - } - - int UpgradeSkillType::getTotalSpeed (const TotalUpgrade * totalUpgrade) const - { - int result = speed + totalUpgrade->getProdSpeed (this); - result = max (0, result); - return result; - } - - void UpgradeSkillType::saveGame (XmlNode * rootNode) - { - SkillType::saveGame (rootNode); - std::map < string, string > mapTagReplacements; - XmlNode *upgradeSkillTypeNode = rootNode->addChild ("UpgradeSkillType"); - - upgradeSkillTypeNode->addAttribute ("animProgressBound", - intToStr (animProgressBound), - mapTagReplacements); - } - -// ===================================================== -// class BeBuiltSkillType -// ===================================================== - - BeBuiltSkillType::BeBuiltSkillType () - { - skillClass = scBeBuilt; - animProgressBound = false; - } - - void BeBuiltSkillType::load (const XmlNode * sn, - const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - SkillType::load (sn, attackBoostsNode, dir, tt, ft, loadedFileList, - parentLoader); - - if (sn->hasChild ("anim-progress-bound")) - { - animProgressBound = - sn->getChild ("anim-progress-bound")->getAttribute ("value")-> - getBoolValue (); - } - else if (sn->hasChild ("anim-hp-bound")) - { // deprecated!!!! remove it when you see it after 15th July 2011 - animProgressBound = - sn->getChild ("anim-hp-bound")->getAttribute ("value")-> - getBoolValue (); - } - else - { - animProgressBound = false; - } - } - - - string BeBuiltSkillType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Be built"; - } - - return "Be built"; - } - - void BeBuiltSkillType::saveGame (XmlNode * rootNode) - { - SkillType::saveGame (rootNode); - std::map < string, string > mapTagReplacements; - XmlNode *beBuiltSkillTypeNode = rootNode->addChild ("BeBuiltSkillType"); - - beBuiltSkillTypeNode->addAttribute ("animProgressBound", - intToStr (animProgressBound), - mapTagReplacements); - } - -// ===================================================== -// class MorphSkillType -// ===================================================== - - MorphSkillType::MorphSkillType () - { - skillClass = scMorph; - animProgressBound = false; - } - - void MorphSkillType::load (const XmlNode * sn, - const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - SkillType::load (sn, attackBoostsNode, dir, tt, ft, loadedFileList, - parentLoader); - - if (sn->hasChild ("anim-progress-bound")) - { - animProgressBound = - sn->getChild ("anim-progress-bound")->getAttribute ("value")-> - getBoolValue (); - } - else - { - animProgressBound = false; - } - } - - string MorphSkillType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Morph"; - } - - return "Morph"; - } - - int MorphSkillType::getTotalSpeed (const TotalUpgrade * totalUpgrade) const - { - int result = speed + totalUpgrade->getProdSpeed (this); - result = max (0, result); - return result; - } - - void MorphSkillType::saveGame (XmlNode * rootNode) - { - SkillType::saveGame (rootNode); - std::map < string, string > mapTagReplacements; - XmlNode *morphSkillTypeNode = rootNode->addChild ("MorphSkillType"); - - morphSkillTypeNode->addAttribute ("animProgressBound", - intToStr (animProgressBound), - mapTagReplacements); - } - -// ===================================================== -// class DieSkillType -// ===================================================== - - DieSkillType::DieSkillType () - { - skillClass = scDie; - fade = false; - spawn = false; - spawnStartTime = 0; - spawnUnit = ""; - spawnUnitcount = 0; - spawnUnitHealthPercentMin = 100; - spawnUnitHealthPercentMax = 100; - spawnProbability = 100; - } - - void DieSkillType::load (const XmlNode * sn, - const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, - string > > >&loadedFileList, string parentLoader) - { - SkillType::load (sn, attackBoostsNode, dir, tt, ft, loadedFileList, - parentLoader); - - fade = sn->getChild ("fade")->getAttribute ("value")->getBoolValue (); - if (sn->hasChild ("spawn")) - { - const XmlNode *spawnNode = sn->getChild ("spawn"); - spawn = true; - spawnStartTime = - spawnNode->getAttribute ("start-time")->getFloatValue (); - spawnUnit = - spawnNode->getChild ("unit")->getAttribute ("value")->getValue (); - spawnUnitcount = - spawnNode->hasChild ("amount") ? spawnNode->getChild ("amount")-> - getAttribute ("value")->getIntValue () : 0; - if (spawnNode->hasChild ("health-percent")) - { - spawnUnitHealthPercentMin = - spawnNode->getChild ("health-percent")->getAttribute ("min")-> - getIntValue (); - spawnUnitHealthPercentMax = - spawnNode->getChild ("health-percent")->getAttribute ("max")-> - getIntValue (); - } - spawnProbability = - spawnNode->hasChild ("probability") ? spawnNode-> - getChild ("probability")->getAttribute ("value")-> - getIntValue () : spawnProbability; - } // else keep defaults - } - - string DieSkillType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "Die"; - } - - return "Die"; - } - - void DieSkillType::saveGame (XmlNode * rootNode) - { - SkillType::saveGame (rootNode); - std::map < string, string > mapTagReplacements; - XmlNode *dieSkillTypeNode = rootNode->addChild ("DieSkillType"); - - dieSkillTypeNode->addAttribute ("fade", intToStr (fade), - mapTagReplacements); - // no need to save spawn attributes - } - - StaticSound *DieSkillType::getSound () const - { - if (skillSoundList.size () == 0) - { - return NULL; - } - else - { - return skillSoundList.front ()->getSoundContainer ()->getRandSound (); - } - } - - -// ===================================================== -// class FogOfWarSkillType -// ===================================================== - - FogOfWarSkillType::FogOfWarSkillType () - { - skillClass = scFogOfWar; - - fowEnable = false; - applyToTeam = false; - durationTime = 0; - } - - void FogOfWarSkillType::load (const XmlNode * sn, - const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, - string > > >&loadedFileList, - string parentLoader) - { - SkillType::load (sn, attackBoostsNode, dir, tt, ft, loadedFileList, - parentLoader); - - fowEnable = - sn->getChild ("enable-fog")->getAttribute ("value")->getBoolValue (); - applyToTeam = - sn->getChild ("apply-team")->getAttribute ("value")->getBoolValue (); - durationTime = - sn->getChild ("duration")->getAttribute ("value")->getFloatValue (); - } - - string FogOfWarSkillType::toString (bool translatedValue) const - { - if (translatedValue == false) - { - return "FogOfWar"; - } - - return "FogOfWar"; - } - - void FogOfWarSkillType::saveGame (XmlNode * rootNode) - { - SkillType::saveGame (rootNode); - std::map < string, string > mapTagReplacements; - XmlNode *fogSkillTypeNode = rootNode->addChild ("FogOfWarSkillType"); - - fogSkillTypeNode->addAttribute ("enable-fog", intToStr (fowEnable), - mapTagReplacements); - fogSkillTypeNode->addAttribute ("apply-team", intToStr (applyToTeam), - mapTagReplacements); - fogSkillTypeNode->addAttribute ("duration", - floatToStr (durationTime, 6), - mapTagReplacements); - } - -// ===================================================== -// class SkillTypeFactory -// ===================================================== - - SkillTypeFactory::SkillTypeFactory () - { - registerClass < StopSkillType > ("stop"); - registerClass < MoveSkillType > ("move"); - registerClass < AttackSkillType > ("attack"); - registerClass < BuildSkillType > ("build"); - registerClass < BeBuiltSkillType > ("be_built"); - registerClass < HarvestSkillType > ("harvest"); - registerClass < RepairSkillType > ("repair"); - registerClass < ProduceSkillType > ("produce"); - registerClass < UpgradeSkillType > ("upgrade"); - registerClass < MorphSkillType > ("morph"); - registerClass < DieSkillType > ("die"); - registerClass < FogOfWarSkillType > ("fog_of_war"); - } - - SkillTypeFactory & SkillTypeFactory::getInstance () - { - static SkillTypeFactory ctf; - return ctf; - } - - } +namespace Glest { + namespace Game { + + int SkillType::nextAttackBoostId = 0; + + AttackBoost::AttackBoost() :boostUpgrade() { + enabled = false; + allowMultipleBoosts = false; + radius = 0; + targetType = abtFaction; + unitParticleSystemTypeForSourceUnit = NULL; + unitParticleSystemTypeForAffectedUnit = NULL; + includeSelf = false; + } + + AttackBoost::~AttackBoost() { + delete unitParticleSystemTypeForSourceUnit; + unitParticleSystemTypeForSourceUnit = NULL; + + delete unitParticleSystemTypeForAffectedUnit; + unitParticleSystemTypeForAffectedUnit = NULL; + } + + bool AttackBoost::isAffected(const Unit * source, const Unit * dest) const { + bool result = false; + if (enabled == true && + source != NULL && dest != NULL && + (includeSelf == true || source != dest)) { + bool destUnitMightApply = false; + if (source == dest && includeSelf == true) { + destUnitMightApply = true; + } else { + // All units are affected (including enemies) + if (targetType == abtAll) { + destUnitMightApply = (boostUnitList.empty() && tags.empty()) + || isInUnitListOrTags(dest->getType());; + } + // Only same faction units are affected + else if (targetType == abtFaction) { + if (source->getFactionIndex() == dest->getFactionIndex()) { + destUnitMightApply = (boostUnitList.empty() && tags.empty()) + || isInUnitListOrTags(dest->getType()); + } + } + // Only ally units are affected + else if (targetType == abtAlly) { + if (source->isAlly(dest) == true) { + destUnitMightApply = (boostUnitList.empty() && tags.empty()) + || isInUnitListOrTags(dest->getType()); + } + } + // Only foe units are affected + else if (targetType == abtFoe) { + if (source->isAlly(dest) == false) { + destUnitMightApply = (boostUnitList.empty() && tags.empty()) + || isInUnitListOrTags(dest->getType()); + } + } else if (targetType == abtUnitTypes) { + destUnitMightApply = isInUnitListOrTags(dest->getType()); + } + } + + if (destUnitMightApply == true) { + float distance = + source->getCenteredPos().dist(dest->getCenteredPos()); + if (distance <= radius) { + result = true; + } + } + } + + return result; + } + + bool AttackBoost::isInUnitListOrTags(const UnitType * unitType) const { + // Specify which units are affected + std::set < const UnitType *>::iterator it; + for (it = boostUnitList.begin(); it != boostUnitList.end(); ++it) { + const UnitType *boostUnit = *it; + if (unitType->getId() == boostUnit->getId()) { + return true; + } + } + set < string > unitTags = unitType->getTags(); + set < string > intersect; + set_intersection(tags.begin(), tags.end(), unitTags.begin(), + unitTags.end(), std::inserter(intersect, + intersect.begin())); + if (!intersect.empty()) + return true; + + // Otherwise no match + return false; + } + + string AttackBoost::getTagName(string tag, bool translatedValue) const { + if (translatedValue == false) + return tag; + + Lang & lang = Lang::getInstance(); + return lang.getTechTreeString("TagName_" + tag, tag.c_str()); + } + + string AttackBoost::getDesc(bool translatedValue) const { + Lang & lang = Lang::getInstance(); + string str = ""; + string indent = " "; + if (enabled) { + if (boostUnitList.empty() == false) { + str += "\n" + lang.getString("Effects") + ":\n"; + } + + str += + indent + lang.getString("effectRadius") + ": " + + intToStr(radius) + "\n"; + if (allowMultipleBoosts == false) { + string allowIt = lang.getString("No"); + if (allowMultipleBoosts == true) + allowIt = lang.getString("False"); + str += + indent + lang.getString("allowMultiBoost") + ": " + allowIt + + "\n"; + } + str += boostUpgrade.getDesc(translatedValue); + + if (targetType == abtAlly) { + str += lang.getString("AffectedUnitsFromTeam") + ":\n"; + } else if (targetType == abtFoe) { + str += lang.getString("AffectedUnitsFromFoe") + ":\n"; + } else if (targetType == abtFaction) { + str += lang.getString("AffectedUnitsFromYourFaction") + ":\n"; + } else if (targetType == abtUnitTypes) { + str += lang.getString("AffectedUnitsFromAll") + ":\n"; + } else if (targetType == abtAll) { + str += lang.getString("AffectedUnitsFromAll") + ":\n"; + } + + if (boostUnitList.empty() && tags.empty()) { + str += lang.getString("All") + "\n"; + } else { + // We want the output to be sorted, so convert the set to a vector and sort that + std::vector < const UnitType *>outputUnits(boostUnitList.begin(), + boostUnitList.end()); + std::sort(outputUnits.begin(), outputUnits.end(), + UnitTypeSorter()); + + vector < const UnitType *>::iterator unitIter; + for (unitIter = outputUnits.begin(); + unitIter != outputUnits.end(); ++unitIter) { + const UnitType *unit = *unitIter; + str += indent + unit->getName(translatedValue) + "\n"; + } + + // Do the same for tags + std::vector < string > outputTags(tags.begin(), tags.end()); + std::sort(outputTags.begin(), outputTags.end()); + + vector < string >::iterator tagIter; + for (tagIter = outputTags.begin(); tagIter != outputTags.end(); + ++tagIter) { + string tag = *tagIter; + str += + indent + lang.getString("TagDesc", + (translatedValue == + true ? "" : "english")) + " " + + getTagName(tag, translatedValue) + "\n"; + } + } + + return str; + } else + return ""; + } + + void AttackBoost::loadGame(const XmlNode * rootNode, Faction * faction, + const SkillType * skillType) { + const XmlNode *attackBoostNode = rootNode->getChild("AttackBoost"); + + enabled = + (attackBoostNode->getAttribute("enabled")->getIntValue() != 0); + allowMultipleBoosts = + (attackBoostNode->getAttribute("allowMultipleBoosts")-> + getIntValue() != 0); + radius = attackBoostNode->getAttribute("radius")->getIntValue(); + targetType = + static_cast + (attackBoostNode->getAttribute("targetType")->getIntValue()); + + if (attackBoostNode->hasChild("UnitType") == true) { + vector < XmlNode * >attackBoostNodeList = + attackBoostNode->getChildList("UnitType"); + for (unsigned int i = 0; i < attackBoostNodeList.size(); ++i) { + XmlNode *node = attackBoostNodeList[i]; + + string unitTypeName = node->getAttribute("name")->getValue(); + const UnitType *unitType = + faction->getType()->getUnitType(unitTypeName); + if (unitType != NULL) { + boostUnitList.insert(unitType); + } + } + } + if (attackBoostNode->hasChild("tag")) { + vector < XmlNode * >tagNodeList = + attackBoostNode->getChildList("tag"); + for (unsigned int i = 0; i < tagNodeList.size(); ++i) { + XmlNode *node = tagNodeList[i]; + string tagName = node->getAttribute("name")->getValue(); + tags.insert(tagName); + } + } + //boostUpgrade.loadGame(attackBoostNode,faction); + boostUpgrade = skillType->getAttackBoost()->boostUpgrade; + + unitParticleSystemTypeForSourceUnit = new UnitParticleSystemType(); + unitParticleSystemTypeForSourceUnit->loadGame(attackBoostNode); + + unitParticleSystemTypeForAffectedUnit = new UnitParticleSystemType(); + unitParticleSystemTypeForAffectedUnit->loadGame(attackBoostNode); + + includeSelf = + (attackBoostNode->getAttribute("includeSelf")->getIntValue() != 0); + name = attackBoostNode->getAttribute("name")->getValue(); + } + + void AttackBoost::saveGame(XmlNode * rootNode) const { + std::map < string, string > mapTagReplacements; + XmlNode *attackBoostNode = rootNode->addChild("AttackBoost"); + + // bool enabled; + attackBoostNode->addAttribute("enabled", intToStr(enabled), + mapTagReplacements); + // bool allowMultipleBoosts; + attackBoostNode->addAttribute("allowMultipleBoosts", + intToStr(allowMultipleBoosts), + mapTagReplacements); + // int radius; + attackBoostNode->addAttribute("radius", intToStr(radius), + mapTagReplacements); + // AttackBoostTargetType targetType; + attackBoostNode->addAttribute("targetType", intToStr(targetType), + mapTagReplacements); + // vector boostUnitList; + std::set < const UnitType *>::iterator unitIter; + for (unitIter = boostUnitList.begin(); + unitIter != boostUnitList.end(); ++unitIter) { + const UnitType *unit = *unitIter; + XmlNode *unitTypeNode = attackBoostNode->addChild("UnitType"); + unitTypeNode->addAttribute("name", unit->getName(false), + mapTagReplacements); + } + std::set < string >::iterator tagIter; + for (tagIter = tags.begin(); tagIter != tags.end(); ++tagIter) { + string tag = *tagIter; + XmlNode *unitTypeNode = attackBoostNode->addChild("tag"); + unitTypeNode->addAttribute("name", tag, mapTagReplacements); + } + // UpgradeTypeBase boostUpgrade; + boostUpgrade.saveGame(attackBoostNode); + // UnitParticleSystemType *unitParticleSystemTypeForSourceUnit; + if (unitParticleSystemTypeForSourceUnit != NULL) { + unitParticleSystemTypeForSourceUnit->saveGame(attackBoostNode); + } + // UnitParticleSystemType *unitParticleSystemTypeForAffectedUnit; + if (unitParticleSystemTypeForAffectedUnit != NULL) { + unitParticleSystemTypeForAffectedUnit->saveGame(attackBoostNode); + } + + // bool includeSelf; + attackBoostNode->addAttribute("includeSelf", intToStr(includeSelf), + mapTagReplacements); + // string name; + attackBoostNode->addAttribute("name", name, mapTagReplacements); + } + + // ===================================================== + // class SkillSound + // ===================================================== + SkillSound::SkillSound() { + startTime = 0.0f; + } + SkillSound::~SkillSound() { + deleteValues(soundContainer.getSounds().begin(), + soundContainer.getSounds().end()); + startTime = 0.0f; + //soundContainer + } + // ===================================================== + // class SkillType + // ===================================================== + + SkillType::~SkillType() { + while (!skillSoundList.empty()) { + delete skillSoundList.back(); + skillSoundList.pop_back(); + } + //remove unitParticleSystemTypes + while (!unitParticleSystemTypes.empty()) { + delete unitParticleSystemTypes.back(); + unitParticleSystemTypes.pop_back(); + } + } + + const XmlNode *SkillType::findAttackBoostDetails(string attackBoostName, + const XmlNode * + attackBoostsNode, + const XmlNode * + attackBoostNode) { + const XmlNode *result = attackBoostNode; + + if (attackBoostsNode != NULL && attackBoostName != "") { + for (int i = 0; i < (int) attackBoostsNode->getChildCount(); ++i) { + const XmlNode *abn = attackBoostsNode->getChild("attack-boost", i); + + string sharedName = + abn->getAttribute("name")->getRestrictedValue(); + if (sharedName == attackBoostName) { + result = abn; + break; + } + } + + } + + return result; + } + + void SkillType::loadAttackBoost(const XmlNode * attackBoostsNode, + const XmlNode * attackBoostNode, + const FactionType * ft, + string parentLoader, const string & dir, + string currentPath, std::map < string, + vector < pair < string, + string > > >&loadedFileList, + const TechTree * tt) { + + attackBoost.enabled = true; + if (attackBoostNode->hasAttribute("name") == true) { + attackBoost.name = + attackBoostNode->getAttribute("name")->getRestrictedValue(); + + attackBoostNode = + findAttackBoostDetails(attackBoost.name, attackBoostsNode, + attackBoostNode); + } else { + attackBoost.name = + "attack-boost-autoname-" + intToStr(getNextAttackBoostId()); + } + string targetType = + attackBoostNode->getChild("target")->getAttribute("value")-> + getValue(); + + attackBoost.allowMultipleBoosts = false; + if (attackBoostNode->hasChild("allow-multiple-boosts") == true) { + attackBoost.allowMultipleBoosts = + attackBoostNode->getChild("allow-multiple-boosts")-> + getAttribute("value")->getBoolValue(); + } + + attackBoost.radius = + attackBoostNode->getChild("radius")->getAttribute("value")-> + getIntValue(); + + attackBoost.includeSelf = false; + if (attackBoostNode->getChild("target")-> + hasAttribute("include-self") == true) { + attackBoost.includeSelf = + attackBoostNode->getChild("target")-> + getAttribute("include-self")->getBoolValue(); + } + + if (targetType == "ally") { + attackBoost.targetType = abtAlly; + } else if (targetType == "foe") { + attackBoost.targetType = abtFoe; + } else if (targetType == "faction") { + attackBoost.targetType = abtFaction; + } else if (targetType == "unit-types") { + attackBoost.targetType = abtUnitTypes; + } else if (targetType == "all") { + attackBoost.targetType = abtAll; + } else { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Unsupported target [%s] specified for attack boost for skill [%s] in [%s]", + targetType.c_str(), name.c_str(), parentLoader.c_str()); + throw megaglest_runtime_error(szBuf, true); + } + + // Load the regular targets + const XmlNode *targetNode = attackBoostNode->getChild("target"); + vector < XmlNode * >targetNodes = + targetNode->getChildList("unit-type"); + for (size_t i = 0; i < targetNodes.size(); ++i) { + string unitName = + targetNodes.at(i)->getAttribute("name")->getRestrictedValue(); + attackBoost.boostUnitList.insert(ft->getUnitType(unitName)); + } + + // Load tags + vector < XmlNode * >tagNodes = targetNode->getChildList("tag"); + for (size_t i = 0; i < tagNodes.size(); ++i) { + string unitName = + tagNodes.at(i)->getAttribute("name")->getRestrictedValue(); + attackBoost.tags.insert(unitName); + } + + attackBoost.boostUpgrade.load(attackBoostNode, attackBoost.name); + if (attackBoostNode->hasChild("particles") == true) { + const XmlNode *particleNode = attackBoostNode->getChild("particles"); + bool particleEnabled = + particleNode->getAttribute("value")->getBoolValue(); + if (particleEnabled == true) { + if (particleNode->hasChild("originator-particle-file") == true) { + const XmlNode *particleFileNode = + particleNode->getChild("originator-particle-file"); + string path = + particleFileNode->getAttribute("path")->getRestrictedValue(); + attackBoost.unitParticleSystemTypeForSourceUnit = + new UnitParticleSystemType(); + attackBoost.unitParticleSystemTypeForSourceUnit-> + load(particleFileNode, dir, currentPath + path, + &Renderer::getInstance(), loadedFileList, parentLoader, + tt->getPath()); + loadedFileList[currentPath + + path].push_back(make_pair(parentLoader, + particleFileNode-> + getAttribute("path")-> + getRestrictedValue + ())); + } + if (particleNode->hasChild("affected-particle-file") == true) { + const XmlNode *particleFileNode = + particleNode->getChild("affected-particle-file"); + string path = + particleFileNode->getAttribute("path")->getRestrictedValue(); + attackBoost.unitParticleSystemTypeForAffectedUnit = + new UnitParticleSystemType(); + attackBoost.unitParticleSystemTypeForAffectedUnit-> + load(particleFileNode, dir, currentPath + path, + &Renderer::getInstance(), loadedFileList, parentLoader, + tt->getPath()); + loadedFileList[currentPath + + path].push_back(make_pair(parentLoader, + particleFileNode-> + getAttribute("path")-> + getRestrictedValue + ())); + } + } + } + } + + void SkillType::load(const XmlNode * sn, + const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader) { + //name + name = + sn->getChild("name")->getAttribute("value")->getRestrictedValue(); + + //ep cost + if (sn->hasChild("ep-cost") == true) { + mpCost = + sn->getChild("ep-cost")->getAttribute("value")->getIntValue(); + } else { + mpCost = 0; + } + + if (sn->hasChild("hp-cost") == true) { + hpCost = + sn->getChild("hp-cost")->getAttribute("value")->getIntValue(); + } else { + hpCost = 0; + } + + //speed + if (sn->hasChild("speed") == true) { + speed = + sn->getChild("speed")->getAttribute("value")->getIntValue(); + } else { + speed = 0; + } + + //anim speed + if (sn->hasChild("anim-speed") == true) { + animSpeed = + sn->getChild("anim-speed")->getAttribute("value")->getIntValue(); + } else { + animSpeed = 0; + } + + //model + string currentPath = dir; + endPathWithSlash(currentPath); + + animationRandomCycleMaxcount = -1; + if (sn->hasChild("animation-random-cycle-maxcount") == true) { + const XmlNode *randomCycleCountNode = + sn->getChild("animation-random-cycle-maxcount"); + animationRandomCycleMaxcount = + randomCycleCountNode->getAttribute("value")->getIntValue(); + } + + if (sn->hasChild("animation") == true) { + //string path= sn->getChild("animation")->getAttribute("path")->getRestrictedValue(currentPath); + vector < XmlNode * >animationList = sn->getChildList("animation"); + for (unsigned int i = 0; i < animationList.size(); ++i) { + string path = + animationList[i]->getAttribute("path")-> + getRestrictedValue(currentPath); + if (fileExists(path) == true) { + Model *animation = + Renderer::getInstance().newModel(rsGame, path, false, + &loadedFileList, + &parentLoader); + loadedFileList[path]. + push_back(make_pair + (parentLoader, + animationList[i]->getAttribute("path")-> + getRestrictedValue())); + + animations.push_back(animation); + //printf("**FOUND ANIMATION [%s]\n",path.c_str()); + + AnimationAttributes animationAttributeList; + if (animationList[i]->getAttribute("minHp", false) != NULL + && animationList[i]->getAttribute("maxHp", false) != NULL) { + animationAttributeList.fromHp = + animationList[i]->getAttribute("minHp")->getIntValue(); + animationAttributeList.toHp = + animationList[i]->getAttribute("maxHp")->getIntValue(); + } + animationAttributes.push_back(animationAttributeList); + } else { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line %d] ERROR CANNOT LOAD MODEL [%s] for parentLoader [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + path.c_str(), parentLoader.c_str()); + throw megaglest_runtime_error("Error: cannot load model [" + + path + "] for skill [" + name + + "] ", true); + } + } + if (animations.empty() == true) { + throw + megaglest_runtime_error("Error no animations found for skill [" + + name + "] for parentLoader [" + + parentLoader + "]", true); + } + } + + //particles + if (sn->hasChild("particles")) { + const XmlNode *particleNode = sn->getChild("particles"); + bool particleEnabled = + particleNode->getAttribute("value")->getBoolValue(); + if (particleEnabled) { + for (int i = 0; i < (int) particleNode->getChildCount(); ++i) { + const XmlNode *particleFileNode = + particleNode->getChild("particle-file", i); + string path = + particleFileNode->getAttribute("path")->getRestrictedValue(); + UnitParticleSystemType *unitParticleSystemType = + new UnitParticleSystemType(); + unitParticleSystemType->load(particleFileNode, dir, + currentPath + path, + &Renderer::getInstance(), + loadedFileList, parentLoader, + tt->getPath()); + + if (particleNode->getChild(i)->hasAttribute("start-time")) { + //printf("*NOTE particle system type has start-time [%f]\n",particleNode->getAttribute("start-time")->getFloatValue()); + unitParticleSystemType->setStartTime(particleNode-> + getChild(i)-> + getAttribute + ("start-time")-> + getFloatValue()); + } else if (particleNode->hasAttribute("start-time")) { + //printf("*NOTE particle system type has start-time [%f]\n",particleNode->getAttribute("start-time")->getFloatValue()); + unitParticleSystemType->setStartTime(particleNode-> + getAttribute + ("start-time")-> + getFloatValue()); + } + + if (particleNode->getChild(i)->hasAttribute("end-time")) { + //printf("*NOTE particle system type has start-time [%f]\n",particleNode->getAttribute("start-time")->getFloatValue()); + unitParticleSystemType->setEndTime(particleNode->getChild(i)-> + getAttribute("end-time")-> + getFloatValue()); + } else if (particleNode->hasAttribute("end-time")) { + //printf("*NOTE particle system type has end-time [%f]\n",particleNode->getAttribute("end-time")->getFloatValue()); + unitParticleSystemType->setEndTime(particleNode-> + getAttribute("end-time")-> + getFloatValue()); + } + + if (particleNode->getChild(i)->hasAttribute("minHp") + && particleNode->getChild(i)->hasAttribute("maxHp")) { + unitParticleSystemType->setMinmaxEnabled(true); + unitParticleSystemType->setMinHp(particleNode->getChild(i)-> + getAttribute("minHp")-> + getIntValue()); + unitParticleSystemType->setMaxHp(particleNode->getChild(i)-> + getAttribute("maxHp")-> + getIntValue()); + + if (particleNode->getChild(i)->hasAttribute("ispercentbased")) { + unitParticleSystemType->setMinmaxIsPercent(particleNode-> + getChild(i)-> + getAttribute + ("ispercentbased")-> + getBoolValue()); + } + } + + loadedFileList[currentPath + + path].push_back(make_pair(parentLoader, + particleFileNode-> + getAttribute("path")-> + getRestrictedValue + ())); + unitParticleSystemTypes.push_back(unitParticleSystemType); + } + + //printf("Load skill particles line: %d size: %d\n",__LINE__,(int)unitParticleSystemTypes.size()); + } + } + + //sound + vector < XmlNode * >soundNodeList = sn->getChildList("sound"); + for (unsigned int i = 0; i < soundNodeList.size(); ++i) { + const XmlNode *soundNode = soundNodeList[i]; + if (soundNode->getAttribute("enabled")->getBoolValue()) { + float soundStartTime = + soundNode->getAttribute("start-time")->getFloatValue(); + SkillSound *skillSound = new SkillSound(); + skillSound->setStartTime(soundStartTime); + + skillSound->getSoundContainer()->resize((int) soundNode-> + getChildCount()); + skillSoundList.push_back(skillSound); + for (int i = 0; i < (int) soundNode->getChildCount(); ++i) { + const XmlNode *soundFileNode = + soundNode->getChild("sound-file", i); + string path = + soundFileNode->getAttribute("path")-> + getRestrictedValue(currentPath, true); + + StaticSound *sound = new StaticSound(); + sound->load(path); + loadedFileList[path]. + push_back(make_pair + (parentLoader, + soundFileNode->getAttribute("path")-> + getRestrictedValue())); + (*skillSound->getSoundContainer())[i] = sound; + } + } + } + + + // attack-boost + if (sn->hasChild("attack-boost") == true) { + //printf("$$FOUND ATTACK BOOST FOR [%s]\n",parentLoader.c_str()); + const XmlNode *attackBoostNode = sn->getChild("attack-boost"); + loadAttackBoost(attackBoostsNode, attackBoostNode, ft, parentLoader, + dir, currentPath, loadedFileList, tt); + } + + shake = false; + shakeIntensity = 50; + shakeDuration = 300; + shakeStartTime = 0.0f; + shakeSelfEnabled = false; + shakeSelfVisible = true; + shakeSelfInCameraView = false; + shakeSelfCameraAffected = false; + shakeTeamEnabled = false; + shakeTeamVisible = true; + shakeTeamInCameraView = false; + shakeTeamCameraAffected = false; + shakeEnemyEnabled = false; + shakeEnemyVisible = true; + shakeEnemyInCameraView = false; + shakeEnemyCameraAffected = false; + + if (sn->hasChild("shake")) { + XmlNode *shakeNode = sn->getChild("shake"); + shake = shakeNode->getAttribute("enabled")->getBoolValue(); + shakeIntensity = + shakeNode->getAttribute("intensity")->getIntValue(); + shakeDuration = shakeNode->getAttribute("duration")->getIntValue(); + if (shakeNode->hasAttribute("start-time")) { + shakeStartTime = + shakeNode->getAttribute("start-time")->getFloatValue(); + } + if (shakeNode->hasChild("self")) { + shakeSelfEnabled = + shakeNode->getChild("enemy")->getAttribute("enabled")-> + getBoolValue(); + shakeSelfVisible = + shakeNode->getChild("self")->getAttribute("visible")-> + getBoolValue(); + shakeSelfInCameraView = + shakeNode->getChild("self")->getAttribute("in-camera-view")-> + getBoolValue(); + shakeSelfCameraAffected = + shakeNode->getChild("self")-> + getAttribute("camera-distance-affected")->getBoolValue(); + } + if (shakeNode->hasChild("team")) { + shakeTeamEnabled = + shakeNode->getChild("enemy")->getAttribute("enabled")-> + getBoolValue(); + shakeTeamVisible = + shakeNode->getChild("team")->getAttribute("visible")-> + getBoolValue(); + shakeTeamInCameraView = + shakeNode->getChild("team")->getAttribute("in-camera-view")-> + getBoolValue(); + shakeTeamCameraAffected = + shakeNode->getChild("team")-> + getAttribute("camera-distance-affected")->getBoolValue(); + } + if (shakeNode->hasChild("enemy")) { + shakeEnemyEnabled = + shakeNode->getChild("enemy")->getAttribute("enabled")-> + getBoolValue(); + shakeEnemyVisible = + shakeNode->getChild("enemy")->getAttribute("visible")-> + getBoolValue(); + shakeEnemyInCameraView = + shakeNode->getChild("enemy")->getAttribute("in-camera-view")-> + getBoolValue(); + shakeEnemyCameraAffected = + shakeNode->getChild("enemy")-> + getAttribute("camera-distance-affected")->getBoolValue(); + } + + //visible-for (team, self,all, team-and-visible, self-and-visible, all-and-visible ) + + } + } + + bool SkillType:: + CanCycleNextRandomAnimation(const int *animationRandomCycleCount) const { + bool result = true; + if (animations.size() > 1) { + if (animationRandomCycleMaxcount >= 0 && + animationRandomCycleCount != NULL && + *animationRandomCycleCount >= animationRandomCycleMaxcount) { + result = false; + } + } + return result; + } + + const AnimationAttributes SkillType::getAnimationAttribute(int index) const { + return animationAttributes[index]; + } + + Model *SkillType::getAnimation(float animProgress, const Unit * unit, + int *lastAnimationIndex, + int *animationRandomCycleCount) const { + int modelIndex = 0; + //printf("Count [%d] animProgress = [%f] for skill [%s] animationRandomCycleCount = %d\n",animations.size(),animProgress,name.c_str(),*animationRandomCycleCount); + if (animations.size() > 1) { + //printf("animProgress = [%f] for skill [%s] animationRandomCycleCount = %d\n",animProgress,name.c_str(),*animationRandomCycleCount); + + if (lastAnimationIndex) { + modelIndex = *lastAnimationIndex; + } + if (modelIndex < 0 || animProgress > 1.0f) { + bool canCycle = + CanCycleNextRandomAnimation(animationRandomCycleCount); + if (canCycle == true) { + vector < int >filteredAnimations; + bool foundSpecificAnimation = false; + if (unit != NULL) { + for (unsigned int i = 0; i < animationAttributes.size(); ++i) { + const AnimationAttributes & attributes = + animationAttributes[i]; + if (attributes.fromHp != 0 || attributes.toHp != 0) { + if (unit->getHp() >= attributes.fromHp + && unit->getHp() <= attributes.toHp) { + //modelIndex = i; + foundSpecificAnimation = true; + filteredAnimations.push_back(i); + //printf("SELECTING Model index = %d [%s] model attributes [%d to %d] for unit [%s - %d] with HP = %d\n",i,animations[modelIndex]->getFileName().c_str(),attributes.fromHp,attributes.toHp,unit->getType()->getName().c_str(),unit->getId(),unit->getHp()); + //break; + } + } + } + // Need to make sure the filtered list does NOT include any + // models with min/max hp + if (foundSpecificAnimation == false) { + for (unsigned int i = 0; i < animationAttributes.size(); ++i) { + const AnimationAttributes & attributes = + animationAttributes[i]; + if (attributes.fromHp == 0 && attributes.toHp == 0) { + //modelIndex = i; + foundSpecificAnimation = true; + filteredAnimations.push_back(i); + //printf("SELECTING Model index = %d [%s] model attributes [%d to %d] for unit [%s - %d] with HP = %d\n",i,animations[modelIndex]->getFileName().c_str(),attributes.fromHp,attributes.toHp,unit->getType()->getName().c_str(),unit->getId(),unit->getHp()); + //break; + } + } + } + } + + if (foundSpecificAnimation == false) { + //int modelIndex = random.randRange(0,animations.size()-1); + Chrono seed(true); + srand((unsigned int) seed.getCurTicks() + + (unit != NULL ? unit->getId() : 0)); + + modelIndex = rand() % animations.size(); + + //const AnimationAttributes &attributes = animationAttributes[modelIndex]; + //printf("SELECTING RANDOM Model index = %d [%s] model attributes [%d to %d] for unit [%s - %d] with HP = %d\n",modelIndex,animations[modelIndex]->getFileName().c_str(),attributes.fromHp,attributes.toHp,unit->getType()->getName().c_str(),unit->getId(),unit->getHp()); + } else { + Chrono seed(true); + srand((unsigned int) seed.getCurTicks() + unit->getId()); + + int filteredModelIndex = rand() % filteredAnimations.size(); + modelIndex = filteredAnimations[filteredModelIndex]; + } + } + } + } + if (lastAnimationIndex) { + if (*lastAnimationIndex != modelIndex) { + //printf("Switching model from [%s] to [%s]\n",(*lastAnimationIndex >= 0 ? animations[*lastAnimationIndex]->getFileName().c_str() : "none"),animations[modelIndex]->getFileName().c_str()); + } + *lastAnimationIndex = modelIndex; + } + + //printf("!!RETURN ANIMATION [%d / %d]\n",modelIndex,animations.size()-1); + return animations[modelIndex]; + } + + string SkillType::skillClassToStr(SkillClass skillClass) { + switch (skillClass) { + case scStop: + return "Stop"; + case scMove: + return "Move"; + case scAttack: + return "Attack"; + case scHarvest: + return "Harvest"; + case scRepair: + return "Repair"; + case scBuild: + return "Build"; + case scDie: + return "Die"; + case scBeBuilt: + return "Be Built"; + case scProduce: + return "Produce"; + case scUpgrade: + return "Upgrade"; + case scFogOfWar: + return "Fog Of War"; + default: + assert(false); + break; + } + return ""; + } + + string SkillType::fieldToStr(Field field) { + Lang & lang = Lang::getInstance(); + string fieldName = ""; + switch (field) { + case fLand: + if (lang.hasString("FieldLand") == true) { + fieldName = lang.getString("FieldLand"); + } else { + fieldName = "Land"; + } + //return "Land"; + return lang.getTilesetString("FieldLandName", fieldName.c_str()); + + case fAir: + if (lang.hasString("FieldAir") == true) { + fieldName = lang.getString("FieldAir"); + } else { + fieldName = "Air"; + } + + //return "Air"; + return lang.getTilesetString("FieldAirName", fieldName.c_str()); + default: + assert(false); + break; + } + return ""; + } + + void SkillType::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode *skillTypeNode = rootNode->addChild("SkillType"); + + // SkillClass skillClass; + skillTypeNode->addAttribute("skillClass", intToStr(skillClass), + mapTagReplacements); + // string name; + skillTypeNode->addAttribute("name", name, mapTagReplacements); + // int mpCost; + skillTypeNode->addAttribute("mpCost", intToStr(mpCost), + mapTagReplacements); + // int hpCost; + skillTypeNode->addAttribute("hpCost", intToStr(hpCost), + mapTagReplacements); + // int speed; + skillTypeNode->addAttribute("speed", intToStr(speed), + mapTagReplacements); + // int animSpeed; + skillTypeNode->addAttribute("animSpeed", intToStr(animSpeed), + mapTagReplacements); + // int animationRandomCycleMaxcount; + skillTypeNode->addAttribute("animationRandomCycleMaxcount", + intToStr(animationRandomCycleMaxcount), + mapTagReplacements); + // vector animations; + // vector animationAttributes; + // + // SoundContainer sounds; + // float soundStartTime; + // skillTypeNode->addAttribute("soundStartTime",floatToStr(soundStartTime,6), mapTagReplacements); + // RandomGen random; + skillTypeNode->addAttribute("random", + intToStr(random.getLastNumber()), + mapTagReplacements); + // AttackBoost attackBoost; + attackBoost.saveGame(skillTypeNode); + // static int nextAttackBoostId; + skillTypeNode->addAttribute("nextAttackBoostId", + intToStr(nextAttackBoostId), + mapTagReplacements); + // UnitParticleSystemTypes unitParticleSystemTypes; + for (UnitParticleSystemTypes::iterator it = + unitParticleSystemTypes.begin(); + it != unitParticleSystemTypes.end(); ++it) { + (*it)->saveGame(skillTypeNode); + } + } + + // ===================================================== + // class StopSkillType + // ===================================================== + + StopSkillType::StopSkillType() { + skillClass = scStop; + } + + string StopSkillType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Stop"; + } + return Lang::getInstance().getString("Stop"); + } + + // ===================================================== + // class MoveSkillType + // ===================================================== + + MoveSkillType::MoveSkillType() { + skillClass = scMove; + } + + string MoveSkillType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Move"; + } + + return Lang::getInstance().getString("Move"); + } + + int MoveSkillType::getTotalSpeed(const TotalUpgrade * totalUpgrade) const { + int result = speed + totalUpgrade->getMoveSpeed(this); + result = max(0, result); + return result; + } + + // ===================================================== + // class AttackSkillType + // ===================================================== + + //varios + AttackSkillType::AttackSkillType() { + skillClass = scAttack; + attackType = NULL; + projectile = false; + splash = false; + splashRadius = 0; + spawnUnit = ""; + spawnUnitcount = 0; + spawnUnitAtTarget = false; + splashParticleSystemType = NULL; + + for (int i = 0; i < fieldCount; ++i) { + attackFields[i] = false; + } + + attackStrength = 0; + attackVar = 0; + attackRange = 0; + attackStartTime = 0; + splashDamageAll = false; + } + + AttackSkillType::~AttackSkillType() { + + deleteValues(projectileTypes.begin(), projectileTypes.end()); + + delete splashParticleSystemType; + splashParticleSystemType = NULL; + deleteValues(projSounds.getSounds().begin(), + projSounds.getSounds().end()); + projSounds.clearSounds(); + } + + void AttackSkillType::load(const XmlNode * sn, + const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + SkillType::load(sn, attackBoostsNode, dir, tt, ft, loadedFileList, + parentLoader); + + string currentPath = dir; + endPathWithSlash(currentPath); + + //misc + std::vector < string > attackStrengthXMLTags; + attackStrengthXMLTags.push_back("attack-strenght"); + attackStrengthXMLTags.push_back("attack-strength"); + attackStrength = + sn->getChildWithAliases(attackStrengthXMLTags)-> + getAttribute("value")->getIntValue(); + attackVar = + sn->getChild("attack-var")->getAttribute("value")->getIntValue(); + + if (attackVar < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The attack skill has an INVALID attack var value which is < 0 [%d] in file [%s]!", + attackVar, dir.c_str()); + throw megaglest_runtime_error(szBuf, true); + } + + attackRange = + sn->getChild("attack-range")->getAttribute("value")->getIntValue(); + string attackTypeName = + sn->getChild("attack-type")->getAttribute("value")-> + getRestrictedValue(); + attackType = tt->getAttackType(attackTypeName); + attackStartTime = + sn->getChild("attack-start-time")->getAttribute("value")-> + getFloatValue(); + + if (sn->hasChild("unit")) { + spawnUnit = + sn->getChild("unit")->getAttribute("value")->getValue(); + spawnUnitcount = + sn->getChild("unit")->getAttribute("amount")->getIntValue(); + if (sn->getChild("unit")->hasAttribute("spawnAtTarget")) { + spawnUnitAtTarget = + sn->getChild("unit")->getAttribute("spawnAtTarget")-> + getBoolValue(); + } else { + spawnUnitAtTarget = false; + } + } else { + spawnUnit = ""; + spawnUnitcount = 0; + spawnUnitAtTarget = false; + } + //attack fields + const XmlNode *attackFieldsNode = sn->getChild("attack-fields"); + for (int i = 0; i < (int) attackFieldsNode->getChildCount(); ++i) { + const XmlNode *fieldNode = attackFieldsNode->getChild("field", i); + string fieldName = + fieldNode->getAttribute("value")->getRestrictedValue(); + if (fieldName == "land") { + attackFields[fLand] = true; + } else if (fieldName == "air") { + attackFields[fAir] = true; + } else { + throw megaglest_runtime_error("Not a valid field: " + fieldName + + ": " + dir, true); + } + } + + if (sn->hasChild("projectile")) { + //projectile -- backward compatible old behaviour with only one projectile + const XmlNode *projectileNode = sn->getChild("projectile"); + projectile = projectileNode->getAttribute("value")->getBoolValue(); + if (projectile) { + // create new projectile + ProjectileType *projectileType = new ProjectileType(); + //only add this projectile if there is an enabled particlesystem + //projectileTypes.push_back(projectileType); + projectileType->setAttackStartTime(attackStartTime); + projectileType->setDamagePercentage(100); + //proj particle + if (projectileNode->hasChild("particle")) { + const XmlNode *particleNode = + projectileNode->getChild("particle"); + bool particleEnabled = + particleNode->getAttribute("value")->getBoolValue(); + if (particleEnabled) { + projectileTypes.push_back(projectileType); + string path = + particleNode->getAttribute("path")->getRestrictedValue(); + ParticleSystemTypeProjectile *projectileParticleSystemType = + new ParticleSystemTypeProjectile(); + projectileParticleSystemType->load(particleNode, dir, + currentPath + path, + &Renderer::getInstance(), + loadedFileList, + parentLoader, + tt->getPath()); + loadedFileList[currentPath + + path].push_back(make_pair(parentLoader, + particleNode-> + getAttribute + ("path")-> + getRestrictedValue + ())); + projectileType-> + setProjectileParticleSystemType + (projectileParticleSystemType); + } else { + delete projectileType; + } + } else { + delete projectileType; + } + //proj sounds + const XmlNode *soundNode = projectileNode->getChild("sound"); + if (soundNode->getAttribute("enabled")->getBoolValue()) { + + projSounds.resize((int) soundNode->getChildCount()); + for (int i = 0; i < (int) soundNode->getChildCount(); ++i) { + const XmlNode *soundFileNode = + soundNode->getChild("sound-file", i); + string path = + soundFileNode->getAttribute("path")-> + getRestrictedValue(currentPath, true); + //printf("\n\n\n\n!@#$ ---> parentLoader [%s] path [%s] nodeValue [%s] i = %d",parentLoader.c_str(),path.c_str(),soundFileNode->getAttribute("path")->getRestrictedValue().c_str(),i); + + StaticSound *sound = new StaticSound(); + sound->load(path); + loadedFileList[path]. + push_back(make_pair + (parentLoader, + soundFileNode->getAttribute("path")-> + getRestrictedValue())); + projSounds[i] = sound; + } + } + } + } else { + const XmlNode *projectilesNode = sn->getChild("projectiles"); + vector < XmlNode * >projectilesNodeList = + projectilesNode->getChildList("projectile"); + int totalDamagePercentage = 0; + for (unsigned int i = 0; i < projectilesNodeList.size(); ++i) { + const XmlNode *projectileNode = projectilesNodeList[i]; + ProjectileType *projectileType = new ProjectileType(); + projectileType->load(projectileNode, dir, tt->getPath(), + loadedFileList, parentLoader); + totalDamagePercentage += projectileType->getDamagePercentage(); + projectileTypes.push_back(projectileType); + projectile = true; + } + + if (totalDamagePercentage != 100) { + throw + megaglest_runtime_error + ("Damages percentages of projectiles don't sum up to 100 %", + true); + } + + if (sn->hasChild("hitsound") == true) { + //general hit sounds, individual ones can be set in projectiles + const XmlNode *soundNode = sn->getChild("hitsound"); + if (soundNode->getAttribute("enabled")->getBoolValue()) { + + projSounds.resize((int) soundNode->getChildCount()); + for (int i = 0; i < (int) soundNode->getChildCount(); ++i) { + const XmlNode *soundFileNode = + soundNode->getChild("sound-file", i); + string path = + soundFileNode->getAttribute("path")-> + getRestrictedValue(currentPath, true); + //printf("\n\n\n\n!@#$ ---> parentLoader [%s] path [%s] nodeValue [%s] i = %d",parentLoader.c_str(),path.c_str(),soundFileNode->getAttribute("path")->getRestrictedValue().c_str(),i); + + StaticSound *sound = new StaticSound(); + sound->load(path); + loadedFileList[path]. + push_back(make_pair + (parentLoader, + soundFileNode->getAttribute("path")-> + getRestrictedValue())); + projSounds[i] = sound; + } + } + } + } + + //splash + const XmlNode *splashNode = sn->getChild("splash"); + splash = splashNode->getAttribute("value")->getBoolValue(); + if (splash) { + splashRadius = + splashNode->getChild("radius")->getAttribute("value")-> + getIntValue(); + splashDamageAll = + splashNode->getChild("damage-all")->getAttribute("value")-> + getBoolValue(); + + //splash particle + const XmlNode *particleNode = splashNode->getChild("particle"); + bool particleEnabled = + particleNode->getAttribute("value")->getBoolValue(); + if (particleEnabled) { + string path = + particleNode->getAttribute("path")->getRestrictedValue(); + splashParticleSystemType = new ParticleSystemTypeSplash(); + splashParticleSystemType->load(particleNode, dir, + currentPath + path, + &Renderer::getInstance(), + loadedFileList, parentLoader, + tt->getPath()); + } + } + } + + int AttackSkillType::getTotalSpeed(const TotalUpgrade * totalUpgrade) const { + int result = speed + totalUpgrade->getAttackSpeed(this); + result = max(0, result); + return result; + } + + // Get the amount to boost the attack animation speed by (based on attack-speed upgrades) + int AttackSkillType::getAnimSpeedBoost(const TotalUpgrade * totalUpgrade) const { + // Same calculation as in TotalUpgrade::sum, but bypassing the use of the value + // list (which is for the attack speed, not animation speed) + if (totalUpgrade->getAttackRangeIsMultiplier()) { + return animSpeed * (totalUpgrade->getAttackSpeed(NULL) / + (double) 100); + } else { + return totalUpgrade->getAttackSpeed(NULL); + } + } + + string AttackSkillType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Attack"; + } + + return Lang::getInstance().getString("Attack"); + } + + //get totals + int AttackSkillType::getTotalAttackStrength(const TotalUpgrade * + totalUpgrade) const { + int result = attackStrength + totalUpgrade->getAttackStrength(this); + result = max(0, result); + return result; + } + + int AttackSkillType::getTotalAttackRange(const TotalUpgrade * + totalUpgrade) const { + int result = attackRange + totalUpgrade->getAttackRange(this); + result = max(0, result); + return result; + } + + void AttackSkillType::saveGame(XmlNode * rootNode) { + SkillType::saveGame(rootNode); + std::map < string, string > mapTagReplacements; + XmlNode *attackSkillTypeNode = rootNode->addChild("AttackSkillType"); + + // int attackStrength; + attackSkillTypeNode->addAttribute("attackStrength", + intToStr(attackStrength), + mapTagReplacements); + // int attackVar; + attackSkillTypeNode->addAttribute("attackVar", intToStr(attackVar), + mapTagReplacements); + // int attackRange; + attackSkillTypeNode->addAttribute("attackRange", + intToStr(attackRange), + mapTagReplacements); + // const AttackType *attackType; + if (attackType != NULL) { + attackSkillTypeNode->addAttribute("attackType", + attackType->getName(false), + mapTagReplacements); + } + // bool attackFields[fieldCount]; + for (unsigned int i = 0; i < fieldCount; ++i) { + XmlNode *attackFieldsNode = + attackSkillTypeNode->addChild("attackFields"); + attackFieldsNode->addAttribute("key", intToStr(i), + mapTagReplacements); + attackFieldsNode->addAttribute("value", intToStr(attackFields[i]), + mapTagReplacements); + } + // float attackStartTime; + attackSkillTypeNode->addAttribute("attackStartTime", + floatToStr(attackStartTime, 6), + mapTagReplacements); + // string spawnUnit; + attackSkillTypeNode->addAttribute("spawnUnit", spawnUnit, + mapTagReplacements); + // int spawnUnitcount; + attackSkillTypeNode->addAttribute("spawnUnitcount", + intToStr(spawnUnitcount), + mapTagReplacements); + // bool spawnUnitAtTarget; + attackSkillTypeNode->addAttribute("spawnUnitAtTarget", + intToStr(spawnUnitAtTarget), + mapTagReplacements); + // bool projectile; + attackSkillTypeNode->addAttribute("projectile", intToStr(projectile), + mapTagReplacements); + // ParticleSystemTypeProjectile* projectileParticleSystemType; + // save a skill_type ???? + // if(projectileParticleSystemType != NULL) { + // projectileParticleSystemType->saveGame(attackSkillTypeNode); + // } + // SoundContainer projSounds; + // + // bool splash; + attackSkillTypeNode->addAttribute("splash", intToStr(splash), + mapTagReplacements); + // int splashRadius; + attackSkillTypeNode->addAttribute("splashRadius", + intToStr(splashRadius), + mapTagReplacements); + // bool splashDamageAll; + attackSkillTypeNode->addAttribute("splashDamageAll", + intToStr(splashDamageAll), + mapTagReplacements); + // ParticleSystemTypeSplash* splashParticleSystemType; + if (splashParticleSystemType != NULL) { + splashParticleSystemType->saveGame(attackSkillTypeNode); + } + } + // ===================================================== + // class BuildSkillType + // ===================================================== + + BuildSkillType::BuildSkillType() { + skillClass = scBuild; + } + + string BuildSkillType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Build"; + } + + return Lang::getInstance().getString("Build"); + } + + // ===================================================== + // class HarvestSkillType + // ===================================================== + + HarvestSkillType::HarvestSkillType() { + skillClass = scHarvest; + } + + string HarvestSkillType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Harvest"; + } + + return Lang::getInstance().getString("Harvest"); + } + + // ===================================================== + // class RepairSkillType + // ===================================================== + + RepairSkillType::RepairSkillType() { + skillClass = scRepair; + } + + string RepairSkillType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Repair"; + } + + return Lang::getInstance().getString("Repair"); + } + + // ===================================================== + // class ProduceSkillType + // ===================================================== + + ProduceSkillType::ProduceSkillType() { + skillClass = scProduce; + animProgressBound = false; + } + + void ProduceSkillType::load(const XmlNode * sn, + const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + SkillType::load(sn, attackBoostsNode, dir, tt, ft, loadedFileList, + parentLoader); + + if (sn->hasChild("anim-progress-bound")) { + animProgressBound = + sn->getChild("anim-progress-bound")->getAttribute("value")-> + getBoolValue(); + } else { + animProgressBound = false; + } + } + + + string ProduceSkillType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Produce"; + } + + return Lang::getInstance().getString("Produce"); + } + + int ProduceSkillType::getTotalSpeed(const TotalUpgrade * totalUpgrade) const { + int result = speed + totalUpgrade->getProdSpeed(this); + result = max(0, result); + return result; + } + + void ProduceSkillType::saveGame(XmlNode * rootNode) { + SkillType::saveGame(rootNode); + std::map < string, string > mapTagReplacements; + XmlNode *produceSkillTypeNode = rootNode->addChild("ProduceSkillType"); + + produceSkillTypeNode->addAttribute("animProgressBound", + intToStr(animProgressBound), + mapTagReplacements); + } + // ===================================================== + // class UpgradeSkillType + // ===================================================== + + UpgradeSkillType::UpgradeSkillType() { + skillClass = scUpgrade; + animProgressBound = false; + } + + void UpgradeSkillType::load(const XmlNode * sn, + const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + SkillType::load(sn, attackBoostsNode, dir, tt, ft, loadedFileList, + parentLoader); + + if (sn->hasChild("anim-progress-bound")) { + animProgressBound = + sn->getChild("anim-progress-bound")->getAttribute("value")-> + getBoolValue(); + } else { + animProgressBound = false; + } + } + + string UpgradeSkillType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Upgrade"; + } + + return Lang::getInstance().getString("Upgrade"); + } + + int UpgradeSkillType::getTotalSpeed(const TotalUpgrade * totalUpgrade) const { + int result = speed + totalUpgrade->getProdSpeed(this); + result = max(0, result); + return result; + } + + void UpgradeSkillType::saveGame(XmlNode * rootNode) { + SkillType::saveGame(rootNode); + std::map < string, string > mapTagReplacements; + XmlNode *upgradeSkillTypeNode = rootNode->addChild("UpgradeSkillType"); + + upgradeSkillTypeNode->addAttribute("animProgressBound", + intToStr(animProgressBound), + mapTagReplacements); + } + + // ===================================================== + // class BeBuiltSkillType + // ===================================================== + + BeBuiltSkillType::BeBuiltSkillType() { + skillClass = scBeBuilt; + animProgressBound = false; + } + + void BeBuiltSkillType::load(const XmlNode * sn, + const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + SkillType::load(sn, attackBoostsNode, dir, tt, ft, loadedFileList, + parentLoader); + + if (sn->hasChild("anim-progress-bound")) { + animProgressBound = + sn->getChild("anim-progress-bound")->getAttribute("value")-> + getBoolValue(); + } else if (sn->hasChild("anim-hp-bound")) { // deprecated!!!! remove it when you see it after 15th July 2011 + animProgressBound = + sn->getChild("anim-hp-bound")->getAttribute("value")-> + getBoolValue(); + } else { + animProgressBound = false; + } + } + + + string BeBuiltSkillType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Be built"; + } + + return "Be built"; + } + + void BeBuiltSkillType::saveGame(XmlNode * rootNode) { + SkillType::saveGame(rootNode); + std::map < string, string > mapTagReplacements; + XmlNode *beBuiltSkillTypeNode = rootNode->addChild("BeBuiltSkillType"); + + beBuiltSkillTypeNode->addAttribute("animProgressBound", + intToStr(animProgressBound), + mapTagReplacements); + } + + // ===================================================== + // class MorphSkillType + // ===================================================== + + MorphSkillType::MorphSkillType() { + skillClass = scMorph; + animProgressBound = false; + } + + void MorphSkillType::load(const XmlNode * sn, + const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + SkillType::load(sn, attackBoostsNode, dir, tt, ft, loadedFileList, + parentLoader); + + if (sn->hasChild("anim-progress-bound")) { + animProgressBound = + sn->getChild("anim-progress-bound")->getAttribute("value")-> + getBoolValue(); + } else { + animProgressBound = false; + } + } + + string MorphSkillType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Morph"; + } + + return "Morph"; + } + + int MorphSkillType::getTotalSpeed(const TotalUpgrade * totalUpgrade) const { + int result = speed + totalUpgrade->getProdSpeed(this); + result = max(0, result); + return result; + } + + void MorphSkillType::saveGame(XmlNode * rootNode) { + SkillType::saveGame(rootNode); + std::map < string, string > mapTagReplacements; + XmlNode *morphSkillTypeNode = rootNode->addChild("MorphSkillType"); + + morphSkillTypeNode->addAttribute("animProgressBound", + intToStr(animProgressBound), + mapTagReplacements); + } + + // ===================================================== + // class DieSkillType + // ===================================================== + + DieSkillType::DieSkillType() { + skillClass = scDie; + fade = false; + spawn = false; + spawnStartTime = 0; + spawnUnit = ""; + spawnUnitcount = 0; + spawnUnitHealthPercentMin = 100; + spawnUnitHealthPercentMax = 100; + spawnProbability = 100; + } + + void DieSkillType::load(const XmlNode * sn, + const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, + string > > >&loadedFileList, string parentLoader) { + SkillType::load(sn, attackBoostsNode, dir, tt, ft, loadedFileList, + parentLoader); + + fade = sn->getChild("fade")->getAttribute("value")->getBoolValue(); + if (sn->hasChild("spawn")) { + const XmlNode *spawnNode = sn->getChild("spawn"); + spawn = true; + spawnStartTime = + spawnNode->getAttribute("start-time")->getFloatValue(); + spawnUnit = + spawnNode->getChild("unit")->getAttribute("value")->getValue(); + spawnUnitcount = + spawnNode->hasChild("amount") ? spawnNode->getChild("amount")-> + getAttribute("value")->getIntValue() : 0; + if (spawnNode->hasChild("health-percent")) { + spawnUnitHealthPercentMin = + spawnNode->getChild("health-percent")->getAttribute("min")-> + getIntValue(); + spawnUnitHealthPercentMax = + spawnNode->getChild("health-percent")->getAttribute("max")-> + getIntValue(); + } + spawnProbability = + spawnNode->hasChild("probability") ? spawnNode-> + getChild("probability")->getAttribute("value")-> + getIntValue() : spawnProbability; + } // else keep defaults + } + + string DieSkillType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "Die"; + } + + return "Die"; + } + + void DieSkillType::saveGame(XmlNode * rootNode) { + SkillType::saveGame(rootNode); + std::map < string, string > mapTagReplacements; + XmlNode *dieSkillTypeNode = rootNode->addChild("DieSkillType"); + + dieSkillTypeNode->addAttribute("fade", intToStr(fade), + mapTagReplacements); + // no need to save spawn attributes + } + + StaticSound *DieSkillType::getSound() const { + if (skillSoundList.size() == 0) { + return NULL; + } else { + return skillSoundList.front()->getSoundContainer()->getRandSound(); + } + } + + + // ===================================================== + // class FogOfWarSkillType + // ===================================================== + + FogOfWarSkillType::FogOfWarSkillType() { + skillClass = scFogOfWar; + + fowEnable = false; + applyToTeam = false; + durationTime = 0; + } + + void FogOfWarSkillType::load(const XmlNode * sn, + const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, + string > > >&loadedFileList, + string parentLoader) { + SkillType::load(sn, attackBoostsNode, dir, tt, ft, loadedFileList, + parentLoader); + + fowEnable = + sn->getChild("enable-fog")->getAttribute("value")->getBoolValue(); + applyToTeam = + sn->getChild("apply-team")->getAttribute("value")->getBoolValue(); + durationTime = + sn->getChild("duration")->getAttribute("value")->getFloatValue(); + } + + string FogOfWarSkillType::toString(bool translatedValue) const { + if (translatedValue == false) { + return "FogOfWar"; + } + + return "FogOfWar"; + } + + void FogOfWarSkillType::saveGame(XmlNode * rootNode) { + SkillType::saveGame(rootNode); + std::map < string, string > mapTagReplacements; + XmlNode *fogSkillTypeNode = rootNode->addChild("FogOfWarSkillType"); + + fogSkillTypeNode->addAttribute("enable-fog", intToStr(fowEnable), + mapTagReplacements); + fogSkillTypeNode->addAttribute("apply-team", intToStr(applyToTeam), + mapTagReplacements); + fogSkillTypeNode->addAttribute("duration", + floatToStr(durationTime, 6), + mapTagReplacements); + } + + // ===================================================== + // class SkillTypeFactory + // ===================================================== + + SkillTypeFactory::SkillTypeFactory() { + registerClass < StopSkillType >("stop"); + registerClass < MoveSkillType >("move"); + registerClass < AttackSkillType >("attack"); + registerClass < BuildSkillType >("build"); + registerClass < BeBuiltSkillType >("be_built"); + registerClass < HarvestSkillType >("harvest"); + registerClass < RepairSkillType >("repair"); + registerClass < ProduceSkillType >("produce"); + registerClass < UpgradeSkillType >("upgrade"); + registerClass < MorphSkillType >("morph"); + registerClass < DieSkillType >("die"); + registerClass < FogOfWarSkillType >("fog_of_war"); + } + + SkillTypeFactory & SkillTypeFactory::getInstance() { + static SkillTypeFactory ctf; + return ctf; + } + + } } //end namespace diff --git a/source/glest_game/types/skill_type.h b/source/glest_game/types/skill_type.h index b8659cb35..3a290c485 100644 --- a/source/glest_game/types/skill_type.h +++ b/source/glest_game/types/skill_type.h @@ -37,745 +37,660 @@ using Shared::Xml::XmlNode; using Shared::Graphics::Vec3f; using Shared::Graphics::Model; -namespace Glest -{ - namespace Game - { - - using Shared::Util::MultiFactory; - - class ParticleSystemTypeProjectile; - class ParticleSystemTypeSplash; - class UnitParticleSystemType; - class FactionType; - class TechTree; - class Lang; - class TotalUpgrade; - class Unit; - - - enum Field - { - fLand, - fAir, - - fieldCount - }; - - enum SkillClass - { - scStop, - scMove, - scAttack, - scBuild, - scHarvest, - scRepair, - scBeBuilt, - scProduce, - scUpgrade, - scMorph, - scDie, - scFogOfWar, - - scCount - }; - - typedef list < UnitParticleSystemType * >UnitParticleSystemTypes; - typedef list < ProjectileType * >ProjectileTypes; -// ===================================================== -// class SkillType -// -/// A basic action that an unit can perform -// ===================================================== - - enum AttackBoostTargetType - { - abtAlly, // Only ally units are affected - abtFoe, // Only foe units are affected - abtFaction, // Only same faction units are affected - abtUnitTypes, // Specify which units are affected ( in general same as abtAll ) - abtAll // All units are affected (including enemies) - }; - - class AttackBoost - { - public: - AttackBoost (); - virtual ~ AttackBoost (); - bool enabled; - bool allowMultipleBoosts; - int radius; - AttackBoostTargetType targetType; - std::set < const UnitType *>boostUnitList; - std::set < string > tags; - UpgradeTypeBase boostUpgrade; - - UnitParticleSystemType *unitParticleSystemTypeForSourceUnit; - UnitParticleSystemType *unitParticleSystemTypeForAffectedUnit; - - bool includeSelf; - string name; - - bool isAffected (const Unit * source, const Unit * dest) const; - virtual string getDesc (bool translatedValue) const; - string getTagName (string tag, bool translatedValue = false) const; - - virtual void saveGame (XmlNode * rootNode) const; - virtual void loadGame (const XmlNode * rootNode, Faction * faction, - const SkillType * skillType); - - private: - /** - * Checks if a unit is affected by the attack boost by checking if either the UnitType is in - * the #boostUnitList or shares a tag with #tags. - * @param unitType The unit type to check. - * @return True if the unit *might* be affected by the attack boost (still have to check if it's - * in range), false otherwise. - */ - bool isInUnitListOrTags (const UnitType * unitType) const; - }; - - class AnimationAttributes - { - public: - AnimationAttributes () - { - fromHp = 0; - toHp = 0; - } - - int fromHp; - int toHp; - }; - -// ===================================================== -// class SkillSound -// holds the start time and a SoundContainer -// ===================================================== - - class SkillSound - { - private: - SoundContainer soundContainer; - float startTime; - - public: - SkillSound (); - ~SkillSound (); - - SoundContainer *getSoundContainer () - { - return &soundContainer; - } - float getStartTime () const - { - return startTime; - } - void setStartTime (float value) - { - startTime = value; - } - }; - - typedef list < SkillSound * >SkillSoundList; - - class SkillType - { - - protected: - SkillClass skillClass; - string name; - int mpCost; - int hpCost; - int speed; - int animSpeed; - - bool shake; - int shakeIntensity; - int shakeDuration; - float shakeStartTime; - bool shakeSelfEnabled; - bool shakeSelfVisible; - bool shakeSelfInCameraView; - bool shakeSelfCameraAffected; - bool shakeTeamEnabled; - bool shakeTeamVisible; - bool shakeTeamInCameraView; - bool shakeTeamCameraAffected; - bool shakeEnemyEnabled; - bool shakeEnemyVisible; - bool shakeEnemyInCameraView; - bool shakeEnemyCameraAffected; - - - int animationRandomCycleMaxcount; - vector < Model * >animations; - vector < AnimationAttributes > animationAttributes; - - SkillSoundList skillSoundList; - RandomGen random; - AttackBoost attackBoost; - - static int nextAttackBoostId; - static int getNextAttackBoostId () - { - return ++nextAttackBoostId; - } - - const XmlNode *findAttackBoostDetails (string attackBoostName, - const XmlNode * attackBoostsNode, - const XmlNode * attackBoostNode); - void loadAttackBoost (const XmlNode * attackBoostsNode, - const XmlNode * attackBoostNode, - const FactionType * ft, string parentLoader, - const string & dir, string currentPath, - std::map < string, vector < pair < string, - string > > >&loadedFileList, const TechTree * tt); - - public: - UnitParticleSystemTypes unitParticleSystemTypes; - - public: - //varios - virtual ~ SkillType (); - virtual void load (const XmlNode * sn, const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - - bool CanCycleNextRandomAnimation (const int *animationRandomCycleCount) - const; - - static void resetNextAttackBoostId () - { - nextAttackBoostId = 0; - } - - const AnimationAttributes getAnimationAttribute (int index) const; - int getAnimationCount () const - { - return (int) animations.size (); - } - - //get - const string & getName () const - { - return name; - } - SkillClass getClass () const - { - return skillClass; - } - int getEpCost () const - { - return mpCost; - } - int getHpCost () const - { - return hpCost; - } - int getSpeed () const - { - return speed; - } - int getAnimSpeed () const - { - return animSpeed; - } - Model *getAnimation (float animProgress = 0, const Unit * unit = - NULL, int *lastAnimationIndex = - NULL, int *animationRandomCycleCount = NULL) const; - - float getShakeStartTime () const - { - return shakeStartTime; - } - bool getShake () const - { - return shake; - } - int getShakeIntensity () const - { - return shakeIntensity; - } - int getShakeDuration () const - { - return shakeDuration; - } - - const SkillSoundList *getSkillSoundList () const - { - return &skillSoundList; - } - - bool getShakeSelfEnabled () const - { - return shakeSelfEnabled; - } - bool getShakeSelfVisible () const - { - return shakeSelfVisible; - } - bool getShakeSelfInCameraView () const - { - return shakeSelfInCameraView; - } - bool getShakeSelfCameraAffected () const - { - return shakeSelfCameraAffected; - } - bool getShakeTeamEnabled () const - { - return shakeTeamEnabled; - } - bool getShakeTeamVisible () const - { - return shakeTeamVisible; - } - bool getShakeTeamInCameraView () const - { - return shakeTeamInCameraView; - } - bool getShakeTeamCameraAffected () const - { - return shakeTeamCameraAffected; - } - bool getShakeEnemyEnabled () const - { - return shakeEnemyEnabled; - } - bool getShakeEnemyVisible () const - { - return shakeEnemyVisible; - } - bool getShakeEnemyInCameraView () const - { - return shakeEnemyInCameraView; - } - bool getShakeEnemyCameraAffected () const - { - return shakeEnemyCameraAffected; - } - - - bool isAttackBoostEnabled () const - { - return attackBoost.enabled; - } - const AttackBoost *getAttackBoost () const - { - return &attackBoost; - } - //virtual string getDesc(const TotalUpgrade *totalUpgrade) const= 0; - - //other - virtual string toString (bool translatedValue) const = 0; - virtual int getTotalSpeed (const TotalUpgrade *) const - { - return speed; - } - static string skillClassToStr (SkillClass skillClass); - static string fieldToStr (Field field); - virtual string getBoostDesc (bool translatedValue) const - { - return attackBoost.getDesc (translatedValue); - } - - virtual void saveGame (XmlNode * rootNode); - }; - -// =============================== -// class StopSkillType -// =============================== - - class StopSkillType:public SkillType - { - public: - StopSkillType (); - virtual string toString (bool translatedValue) const; - }; - -// =============================== -// class MoveSkillType -// =============================== - - class MoveSkillType:public SkillType - { - public: - MoveSkillType (); - virtual string toString (bool translatedValue) const; - - virtual int getTotalSpeed (const TotalUpgrade * totalUpgrade) const; - }; - -// =============================== -// class AttackSkillType -// =============================== - - class AttackSkillType:public SkillType - { - public: - ProjectileTypes projectileTypes; - private: - int attackStrength; - int attackVar; - int attackRange; - const AttackType *attackType; - bool attackFields[fieldCount]; - float attackStartTime; - - string spawnUnit; - int spawnUnitcount; - bool spawnUnitAtTarget; - bool projectile; - //ParticleSystemTypeProjectile* projectileParticleSystemType; - SoundContainer projSounds; - - bool splash; - int splashRadius; - bool splashDamageAll; - ParticleSystemTypeSplash *splashParticleSystemType; - - public: - AttackSkillType (); - ~AttackSkillType (); - virtual void load (const XmlNode * sn, const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string toString (bool translatedValue) const; - - //get - inline int getAttackStrength () const - { - return attackStrength; - } - inline int getAttackVar () const - { - return attackVar; - } - inline int getAttackRange () const - { - return attackRange; - } - inline const AttackType *getAttackType () const - { - return attackType; - } - inline bool getAttackField (Field field) const - { - return attackFields[field]; - } - inline float getAttackStartTime () const - { - return attackStartTime; - } - inline string getSpawnUnit () const - { - return spawnUnit; - } - inline int getSpawnUnitCount () const - { - return spawnUnitcount; - } - inline bool getSpawnUnitAtTarget () const - { - return spawnUnitAtTarget; - } - - //get proj - inline bool getProjectile () const - { - return projectile; - } - inline StaticSound *getProjSound () const - { - return projSounds.getRandSound (); - } - - //get splash - inline bool getSplash () const - { - return splash; - } - inline int getSplashRadius () const - { - return splashRadius; - } - inline bool getSplashDamageAll () const - { - return splashDamageAll; - } - inline ParticleSystemTypeSplash *getSplashParticleType () const - { - return splashParticleSystemType; - } - - //misc - int getTotalAttackStrength (const TotalUpgrade * totalUpgrade) const; - int getTotalAttackRange (const TotalUpgrade * totalUpgrade) const; - virtual int getTotalSpeed (const TotalUpgrade * totalUpgrade) const; - virtual int getAnimSpeedBoost (const TotalUpgrade * totalUpgrade) const; - - virtual void saveGame (XmlNode * rootNode); - }; - - -// =============================== -// class BuildSkillType -// =============================== - - class BuildSkillType:public SkillType - { - public: - BuildSkillType (); - virtual string toString (bool translatedValue) const; - }; - -// =============================== -// class HarvestSkillType -// =============================== - - class HarvestSkillType:public SkillType - { - public: - HarvestSkillType (); - virtual string toString (bool translatedValue) const; - }; - -// =============================== -// class RepairSkillType -// =============================== - - class RepairSkillType:public SkillType - { - public: - RepairSkillType (); - virtual string toString (bool translatedValue) const; - }; - -// =============================== -// class ProduceSkillType -// =============================== - - class ProduceSkillType:public SkillType - { - private: - bool animProgressBound; - public: - ProduceSkillType (); - bool getAnimProgressBound () const - { - return animProgressBound; - } - virtual void load (const XmlNode * sn, const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - - virtual string toString (bool translatedValue) const; - - virtual int getTotalSpeed (const TotalUpgrade * totalUpgrade) const; - - virtual void saveGame (XmlNode * rootNode); - }; - -// =============================== -// class UpgradeSkillType -// =============================== - - class UpgradeSkillType:public SkillType - { - private: - bool animProgressBound; - public: - UpgradeSkillType (); - bool getAnimProgressBound () const - { - return animProgressBound; - } - virtual void load (const XmlNode * sn, const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - - virtual string toString (bool translatedValue) const; - - virtual int getTotalSpeed (const TotalUpgrade * totalUpgrade) const; - - virtual void saveGame (XmlNode * rootNode); - }; - - -// =============================== -// class BeBuiltSkillType -// =============================== - - class BeBuiltSkillType:public SkillType - { - private: - bool animProgressBound; - - public: - BeBuiltSkillType (); - bool getAnimProgressBound () const - { - return animProgressBound; - } - - virtual void load (const XmlNode * sn, const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string toString (bool translatedValue) const; - - virtual void saveGame (XmlNode * rootNode); - }; - -// =============================== -// class MorphSkillType -// =============================== - - class MorphSkillType:public SkillType - { - private: - bool animProgressBound; - - public: - MorphSkillType (); - bool getAnimProgressBound () const - { - return animProgressBound; - } - - virtual void load (const XmlNode * sn, const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - - virtual string toString (bool translatedValue) const; - virtual int getTotalSpeed (const TotalUpgrade * totalUpgrade) const; - - virtual void saveGame (XmlNode * rootNode); - }; - -// =============================== -// class DieSkillType -// =============================== - - class DieSkillType:public SkillType - { - private: - bool fade; - bool spawn; - float spawnStartTime; - string spawnUnit; - int spawnUnitcount; - int spawnUnitHealthPercentMin; - int spawnUnitHealthPercentMax; - int spawnProbability; - - public: - DieSkillType (); - - virtual void load (const XmlNode * sn, const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string toString (bool translatedValue) const; - - bool getFade () const - { - return fade; - } - bool getSpawn () const - { - return spawn; - } - inline int getSpawnStartTime () const - { - return spawnStartTime; - } - inline string getSpawnUnit () const - { - return spawnUnit; - } - inline int getSpawnUnitCount () const - { - return spawnUnitcount; - } - inline int getSpawnUnitHealthPercentMin () const - { - return spawnUnitHealthPercentMin; - } - inline int getSpawnUnitHealthPercentMax () const - { - return spawnUnitHealthPercentMax; - } - inline int getSpawnProbability () const - { - return spawnProbability; - } - - virtual void saveGame (XmlNode * rootNode); - StaticSound *getSound () const; - }; - -// =============================== -// class FogOfWarSkillType -// =============================== - - class FogOfWarSkillType:public SkillType - { - private: - bool fowEnable; - bool applyToTeam; - float durationTime; - - public: - FogOfWarSkillType (); - bool getFowEnable () const - { - return fowEnable; - } - bool getApplyToTeam () const - { - return applyToTeam; - } - float getDurationTime () const - { - return durationTime; - } - - virtual void load (const XmlNode * sn, const XmlNode * attackBoostsNode, - const string & dir, const TechTree * tt, - const FactionType * ft, std::map < string, - vector < pair < string, string > > >&loadedFileList, - string parentLoader); - virtual string toString (bool translatedValue) const; - - virtual void saveGame (XmlNode * rootNode); - }; - -// =============================== -// class SkillFactory -// =============================== - - class SkillTypeFactory:public MultiFactory < SkillType > - { - private: - SkillTypeFactory (); - public: - static SkillTypeFactory & getInstance (); - }; - -}} //end namespace +namespace Glest { + namespace Game { + + using Shared::Util::MultiFactory; + + class ParticleSystemTypeProjectile; + class ParticleSystemTypeSplash; + class UnitParticleSystemType; + class FactionType; + class TechTree; + class Lang; + class TotalUpgrade; + class Unit; + + + enum Field { + fLand, + fAir, + + fieldCount + }; + + enum SkillClass { + scStop, + scMove, + scAttack, + scBuild, + scHarvest, + scRepair, + scBeBuilt, + scProduce, + scUpgrade, + scMorph, + scDie, + scFogOfWar, + + scCount + }; + + typedef list < UnitParticleSystemType * >UnitParticleSystemTypes; + typedef list < ProjectileType * >ProjectileTypes; + // ===================================================== + // class SkillType + // + /// A basic action that an unit can perform + // ===================================================== + + enum AttackBoostTargetType { + abtAlly, // Only ally units are affected + abtFoe, // Only foe units are affected + abtFaction, // Only same faction units are affected + abtUnitTypes, // Specify which units are affected ( in general same as abtAll ) + abtAll // All units are affected (including enemies) + }; + + class AttackBoost { + public: + AttackBoost(); + virtual ~AttackBoost(); + bool enabled; + bool allowMultipleBoosts; + int radius; + AttackBoostTargetType targetType; + std::set < const UnitType *>boostUnitList; + std::set < string > tags; + UpgradeTypeBase boostUpgrade; + + UnitParticleSystemType *unitParticleSystemTypeForSourceUnit; + UnitParticleSystemType *unitParticleSystemTypeForAffectedUnit; + + bool includeSelf; + string name; + + bool isAffected(const Unit * source, const Unit * dest) const; + virtual string getDesc(bool translatedValue) const; + string getTagName(string tag, bool translatedValue = false) const; + + virtual void saveGame(XmlNode * rootNode) const; + virtual void loadGame(const XmlNode * rootNode, Faction * faction, + const SkillType * skillType); + + private: + /** + * Checks if a unit is affected by the attack boost by checking if either the UnitType is in + * the #boostUnitList or shares a tag with #tags. + * @param unitType The unit type to check. + * @return True if the unit *might* be affected by the attack boost (still have to check if it's + * in range), false otherwise. + */ + bool isInUnitListOrTags(const UnitType * unitType) const; + }; + + class AnimationAttributes { + public: + AnimationAttributes() { + fromHp = 0; + toHp = 0; + } + + int fromHp; + int toHp; + }; + + // ===================================================== + // class SkillSound + // holds the start time and a SoundContainer + // ===================================================== + + class SkillSound { + private: + SoundContainer soundContainer; + float startTime; + + public: + SkillSound(); + ~SkillSound(); + + SoundContainer *getSoundContainer() { + return &soundContainer; + } + float getStartTime() const { + return startTime; + } + void setStartTime(float value) { + startTime = value; + } + }; + + typedef list < SkillSound * >SkillSoundList; + + class SkillType { + + protected: + SkillClass skillClass; + string name; + int mpCost; + int hpCost; + int speed; + int animSpeed; + + bool shake; + int shakeIntensity; + int shakeDuration; + float shakeStartTime; + bool shakeSelfEnabled; + bool shakeSelfVisible; + bool shakeSelfInCameraView; + bool shakeSelfCameraAffected; + bool shakeTeamEnabled; + bool shakeTeamVisible; + bool shakeTeamInCameraView; + bool shakeTeamCameraAffected; + bool shakeEnemyEnabled; + bool shakeEnemyVisible; + bool shakeEnemyInCameraView; + bool shakeEnemyCameraAffected; + + + int animationRandomCycleMaxcount; + vector < Model * >animations; + vector < AnimationAttributes > animationAttributes; + + SkillSoundList skillSoundList; + RandomGen random; + AttackBoost attackBoost; + + static int nextAttackBoostId; + static int getNextAttackBoostId() { + return ++nextAttackBoostId; + } + + const XmlNode *findAttackBoostDetails(string attackBoostName, + const XmlNode * attackBoostsNode, + const XmlNode * attackBoostNode); + void loadAttackBoost(const XmlNode * attackBoostsNode, + const XmlNode * attackBoostNode, + const FactionType * ft, string parentLoader, + const string & dir, string currentPath, + std::map < string, vector < pair < string, + string > > >&loadedFileList, const TechTree * tt); + + public: + UnitParticleSystemTypes unitParticleSystemTypes; + + public: + //varios + virtual ~SkillType(); + virtual void load(const XmlNode * sn, const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + + bool CanCycleNextRandomAnimation(const int *animationRandomCycleCount) + const; + + static void resetNextAttackBoostId() { + nextAttackBoostId = 0; + } + + const AnimationAttributes getAnimationAttribute(int index) const; + int getAnimationCount() const { + return (int) animations.size(); + } + + //get + const string & getName() const { + return name; + } + SkillClass getClass() const { + return skillClass; + } + int getEpCost() const { + return mpCost; + } + int getHpCost() const { + return hpCost; + } + int getSpeed() const { + return speed; + } + int getAnimSpeed() const { + return animSpeed; + } + Model *getAnimation(float animProgress = 0, const Unit * unit = + NULL, int *lastAnimationIndex = + NULL, int *animationRandomCycleCount = NULL) const; + + float getShakeStartTime() const { + return shakeStartTime; + } + bool getShake() const { + return shake; + } + int getShakeIntensity() const { + return shakeIntensity; + } + int getShakeDuration() const { + return shakeDuration; + } + + const SkillSoundList *getSkillSoundList() const { + return &skillSoundList; + } + + bool getShakeSelfEnabled() const { + return shakeSelfEnabled; + } + bool getShakeSelfVisible() const { + return shakeSelfVisible; + } + bool getShakeSelfInCameraView() const { + return shakeSelfInCameraView; + } + bool getShakeSelfCameraAffected() const { + return shakeSelfCameraAffected; + } + bool getShakeTeamEnabled() const { + return shakeTeamEnabled; + } + bool getShakeTeamVisible() const { + return shakeTeamVisible; + } + bool getShakeTeamInCameraView() const { + return shakeTeamInCameraView; + } + bool getShakeTeamCameraAffected() const { + return shakeTeamCameraAffected; + } + bool getShakeEnemyEnabled() const { + return shakeEnemyEnabled; + } + bool getShakeEnemyVisible() const { + return shakeEnemyVisible; + } + bool getShakeEnemyInCameraView() const { + return shakeEnemyInCameraView; + } + bool getShakeEnemyCameraAffected() const { + return shakeEnemyCameraAffected; + } + + + bool isAttackBoostEnabled() const { + return attackBoost.enabled; + } + const AttackBoost *getAttackBoost() const { + return &attackBoost; + } + //virtual string getDesc(const TotalUpgrade *totalUpgrade) const= 0; + + //other + virtual string toString(bool translatedValue) const = 0; + virtual int getTotalSpeed(const TotalUpgrade *) const { + return speed; + } + static string skillClassToStr(SkillClass skillClass); + static string fieldToStr(Field field); + virtual string getBoostDesc(bool translatedValue) const { + return attackBoost.getDesc(translatedValue); + } + + virtual void saveGame(XmlNode * rootNode); + }; + + // =============================== + // class StopSkillType + // =============================== + + class StopSkillType :public SkillType { + public: + StopSkillType(); + virtual string toString(bool translatedValue) const; + }; + + // =============================== + // class MoveSkillType + // =============================== + + class MoveSkillType :public SkillType { + public: + MoveSkillType(); + virtual string toString(bool translatedValue) const; + + virtual int getTotalSpeed(const TotalUpgrade * totalUpgrade) const; + }; + + // =============================== + // class AttackSkillType + // =============================== + + class AttackSkillType :public SkillType { + public: + ProjectileTypes projectileTypes; + private: + int attackStrength; + int attackVar; + int attackRange; + const AttackType *attackType; + bool attackFields[fieldCount]; + float attackStartTime; + + string spawnUnit; + int spawnUnitcount; + bool spawnUnitAtTarget; + bool projectile; + //ParticleSystemTypeProjectile* projectileParticleSystemType; + SoundContainer projSounds; + + bool splash; + int splashRadius; + bool splashDamageAll; + ParticleSystemTypeSplash *splashParticleSystemType; + + public: + AttackSkillType(); + ~AttackSkillType(); + virtual void load(const XmlNode * sn, const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string toString(bool translatedValue) const; + + //get + inline int getAttackStrength() const { + return attackStrength; + } + inline int getAttackVar() const { + return attackVar; + } + inline int getAttackRange() const { + return attackRange; + } + inline const AttackType *getAttackType() const { + return attackType; + } + inline bool getAttackField(Field field) const { + return attackFields[field]; + } + inline float getAttackStartTime() const { + return attackStartTime; + } + inline string getSpawnUnit() const { + return spawnUnit; + } + inline int getSpawnUnitCount() const { + return spawnUnitcount; + } + inline bool getSpawnUnitAtTarget() const { + return spawnUnitAtTarget; + } + + //get proj + inline bool getProjectile() const { + return projectile; + } + inline StaticSound *getProjSound() const { + return projSounds.getRandSound(); + } + + //get splash + inline bool getSplash() const { + return splash; + } + inline int getSplashRadius() const { + return splashRadius; + } + inline bool getSplashDamageAll() const { + return splashDamageAll; + } + inline ParticleSystemTypeSplash *getSplashParticleType() const { + return splashParticleSystemType; + } + + //misc + int getTotalAttackStrength(const TotalUpgrade * totalUpgrade) const; + int getTotalAttackRange(const TotalUpgrade * totalUpgrade) const; + virtual int getTotalSpeed(const TotalUpgrade * totalUpgrade) const; + virtual int getAnimSpeedBoost(const TotalUpgrade * totalUpgrade) const; + + virtual void saveGame(XmlNode * rootNode); + }; + + + // =============================== + // class BuildSkillType + // =============================== + + class BuildSkillType :public SkillType { + public: + BuildSkillType(); + virtual string toString(bool translatedValue) const; + }; + + // =============================== + // class HarvestSkillType + // =============================== + + class HarvestSkillType :public SkillType { + public: + HarvestSkillType(); + virtual string toString(bool translatedValue) const; + }; + + // =============================== + // class RepairSkillType + // =============================== + + class RepairSkillType :public SkillType { + public: + RepairSkillType(); + virtual string toString(bool translatedValue) const; + }; + + // =============================== + // class ProduceSkillType + // =============================== + + class ProduceSkillType :public SkillType { + private: + bool animProgressBound; + public: + ProduceSkillType(); + bool getAnimProgressBound() const { + return animProgressBound; + } + virtual void load(const XmlNode * sn, const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + + virtual string toString(bool translatedValue) const; + + virtual int getTotalSpeed(const TotalUpgrade * totalUpgrade) const; + + virtual void saveGame(XmlNode * rootNode); + }; + + // =============================== + // class UpgradeSkillType + // =============================== + + class UpgradeSkillType :public SkillType { + private: + bool animProgressBound; + public: + UpgradeSkillType(); + bool getAnimProgressBound() const { + return animProgressBound; + } + virtual void load(const XmlNode * sn, const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + + virtual string toString(bool translatedValue) const; + + virtual int getTotalSpeed(const TotalUpgrade * totalUpgrade) const; + + virtual void saveGame(XmlNode * rootNode); + }; + + + // =============================== + // class BeBuiltSkillType + // =============================== + + class BeBuiltSkillType :public SkillType { + private: + bool animProgressBound; + + public: + BeBuiltSkillType(); + bool getAnimProgressBound() const { + return animProgressBound; + } + + virtual void load(const XmlNode * sn, const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string toString(bool translatedValue) const; + + virtual void saveGame(XmlNode * rootNode); + }; + + // =============================== + // class MorphSkillType + // =============================== + + class MorphSkillType :public SkillType { + private: + bool animProgressBound; + + public: + MorphSkillType(); + bool getAnimProgressBound() const { + return animProgressBound; + } + + virtual void load(const XmlNode * sn, const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + + virtual string toString(bool translatedValue) const; + virtual int getTotalSpeed(const TotalUpgrade * totalUpgrade) const; + + virtual void saveGame(XmlNode * rootNode); + }; + + // =============================== + // class DieSkillType + // =============================== + + class DieSkillType :public SkillType { + private: + bool fade; + bool spawn; + float spawnStartTime; + string spawnUnit; + int spawnUnitcount; + int spawnUnitHealthPercentMin; + int spawnUnitHealthPercentMax; + int spawnProbability; + + public: + DieSkillType(); + + virtual void load(const XmlNode * sn, const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string toString(bool translatedValue) const; + + bool getFade() const { + return fade; + } + bool getSpawn() const { + return spawn; + } + inline int getSpawnStartTime() const { + return spawnStartTime; + } + inline string getSpawnUnit() const { + return spawnUnit; + } + inline int getSpawnUnitCount() const { + return spawnUnitcount; + } + inline int getSpawnUnitHealthPercentMin() const { + return spawnUnitHealthPercentMin; + } + inline int getSpawnUnitHealthPercentMax() const { + return spawnUnitHealthPercentMax; + } + inline int getSpawnProbability() const { + return spawnProbability; + } + + virtual void saveGame(XmlNode * rootNode); + StaticSound *getSound() const; + }; + + // =============================== + // class FogOfWarSkillType + // =============================== + + class FogOfWarSkillType :public SkillType { + private: + bool fowEnable; + bool applyToTeam; + float durationTime; + + public: + FogOfWarSkillType(); + bool getFowEnable() const { + return fowEnable; + } + bool getApplyToTeam() const { + return applyToTeam; + } + float getDurationTime() const { + return durationTime; + } + + virtual void load(const XmlNode * sn, const XmlNode * attackBoostsNode, + const string & dir, const TechTree * tt, + const FactionType * ft, std::map < string, + vector < pair < string, string > > >&loadedFileList, + string parentLoader); + virtual string toString(bool translatedValue) const; + + virtual void saveGame(XmlNode * rootNode); + }; + + // =============================== + // class SkillFactory + // =============================== + + class SkillTypeFactory :public MultiFactory < SkillType > { + private: + SkillTypeFactory(); + public: + static SkillTypeFactory & getInstance(); + }; + + } +} //end namespace #endif diff --git a/source/glest_game/types/tech_tree.cpp b/source/glest_game/types/tech_tree.cpp index 8478ad28a..7d63148cd 100644 --- a/source/glest_game/types/tech_tree.cpp +++ b/source/glest_game/types/tech_tree.cpp @@ -27,755 +27,669 @@ using namespace Shared::Util; using namespace Shared::Xml; -namespace Glest -{ - namespace Game - { - -// ===================================================== -// class TechTree -// ===================================================== - - TechTree::TechTree (const vector < string > pathList) - { - SkillType::resetNextAttackBoostId (); - - name = ""; - treePath = ""; - this->pathList.assign (pathList.begin (), pathList.end ()); - - resourceTypes.clear (); - factionTypes.clear (); - armorTypes.clear (); - attackTypes.clear (); - translatedTechNames.clear (); - translatedTechFactionNames.clear (); - languageUsedForCache = ""; - isValidationModeEnabled = false; - } - - string TechTree::getNameUntranslated () const - { - return name; - } - - string TechTree::getName (bool translatedValue) - { - if (translatedValue == false) - { - return getNameUntranslated (); - } - - bool foundTranslation = false; - Lang & lang = Lang::getInstance (); - if (lang.getTechNameLoaded () != name || - lang.getLanguage () != languageUsedForCache) - { - //printf("Line: %d Tech [%s]\n",__LINE__,name.c_str()); - - foundTranslation = - lang.loadTechTreeStrings (name, - lang.getLanguage () != - languageUsedForCache); - languageUsedForCache = lang.getLanguage (); - translatedTechFactionNames.erase (name); - translatedTechNames.erase (name); - } - - string result = name; - if (foundTranslation == true) - { - result = lang.getTechTreeString ("TechTreeName", name.c_str ()); - } - else - { - result = formatString (result); - } - - - //printf("Line: %d Tech [%s] result [%s]\n",__LINE__,name.c_str(),result.c_str()); - return result; - } - - string TechTree::getTranslatedName (string techName, bool forceLoad, - bool forceTechtreeActiveFile) - { - string result = techName; - - //printf("Line: %d Tech [%s] forceLoad = %d forceTechtreeActiveFile = %d\n",__LINE__,techName.c_str(),forceLoad,forceTechtreeActiveFile); - - Lang & lang = Lang::getInstance (); - if (forceTechtreeActiveFile == false && - translatedTechNames.find (techName) != translatedTechNames.end () && - lang.getLanguage () == languageUsedForCache) - { - result = translatedTechNames[techName]; - } - else - { - name = ""; - string path = findPath (techName); - if (path != "") - { - string currentPath = path; - endPathWithSlash (currentPath); - treePath = currentPath; - name = lastDir (currentPath); - - lang.loadTechTreeStrings (name, - lang.getLanguage () != - languageUsedForCache); - languageUsedForCache = lang.getLanguage (); - - translatedTechFactionNames.erase (techName); - translatedTechNames.erase (techName); - - result = getName (true); - - //printf("techName [%s] name [%s] result [%s]\n",techName.c_str(),name.c_str(),result.c_str()); - translatedTechNames[name] = result; - } - - } - return result; - } - - string TechTree::getTranslatedFactionName (string techName, - string factionName) - { - //printf("Line: %d Tech [%s] name [%s] factionName [%s]\n",__LINE__,techName.c_str(),name.c_str(),factionName.c_str()); - - Lang & lang = Lang::getInstance (); - if (lang.getTechNameLoaded () != techName || - lang.getLanguage () != languageUsedForCache) - { - //printf("Line: %d Tech [%s] name [%s] lang.getTechNameLoaded() [%s] factionName [%s]\n",__LINE__,techName.c_str(),name.c_str(),lang.getTechNameLoaded().c_str(),factionName.c_str()); - - lang.loadTechTreeStrings (techName, - lang.getLanguage () != - languageUsedForCache); - languageUsedForCache = lang.getLanguage (); - - translatedTechFactionNames.erase (techName); - } - - std::map < string, std::map < string, string > >::iterator iterMap = - translatedTechFactionNames.find (techName); - if (iterMap != translatedTechFactionNames.end ()) - { - if (iterMap->second.find (factionName) != iterMap->second.end ()) - { - //printf("Line: %d Tech [%s] factionName [%s]\n",__LINE__,techName.c_str(),factionName.c_str()); - - return iterMap->second.find (factionName)->second; - } - } - - //printf("Line: %d Tech [%s] factionName [%s]\n",__LINE__,techName.c_str(),factionName.c_str()); - - getTranslatedName (techName, false, true); - - string result = - lang.getTechTreeString ("FactionName_" + factionName, - formatString (factionName).c_str ()); - //printf(">>result = %s\n",result.c_str()); - translatedTechFactionNames[techName][factionName] = result; - - //printf("Line: %d Translated faction for Tech [%s] faction [%s] result [%s]\n",__LINE__,techName.c_str(),factionName.c_str(),result.c_str()); - - return result; - } - - Checksum TechTree::loadTech (const string & techName, - set < string > &factions, - Checksum * checksum, std::map < string, - vector < pair < string, - string > > >&loadedFileList, - bool validationMode) - { - name = ""; - isValidationModeEnabled = validationMode; - Checksum techtreeChecksum; - string path = findPath (techName); - if (path != "") - { - //printf(">>> path=%s\n",path.c_str()); - load (path, factions, checksum, &techtreeChecksum, loadedFileList, - validationMode); - } - else - { - printf (">>> techtree [%s] path not found.\n", techName.c_str ()); - } - return techtreeChecksum; - } - - bool TechTree::exists (const string & techName, - const vector < string > &pathTechList) - { - bool techFound = false; - auto_ptr < TechTree > techTree (new TechTree (pathTechList)); - string path = techTree->findPath (techName); - if (path != "") - { - techFound = true; - } - return techFound; - } - - string TechTree::findPath (const string & techName) const - { - return findPath (techName, pathList); - } - string TechTree::findPath (const string & techName, - const vector < string > &pathTechList) - { - for (unsigned int idx = 0; idx < pathTechList.size (); ++idx) - { - string currentPath = (pathTechList)[idx]; - endPathWithSlash (currentPath); - - string path = currentPath + techName; - - //printf(">>> test path=%s\n",path.c_str()); - if (isdir (path.c_str ()) == true) - { - return path; - //break; - } - } - //return "no path found for tech: \""+techname+"\""; - return ""; - } - - - void TechTree::load (const string & dir, set < string > &factions, - Checksum * checksum, Checksum * techtreeChecksum, - std::map < string, vector < pair < string, - string > > >&loadedFileList, bool validationMode) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - string currentPath = dir; - endPathWithSlash (currentPath); - treePath = currentPath; - name = lastDir (currentPath); - - Lang & lang = Lang::getInstance (); - lang.loadTechTreeStrings (name, true); - languageUsedForCache = lang.getLanguage (); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - Lang::getInstance (). - getString ("LogScreenGameLoadingTechtree", "", true).c_str (), - formatString (getName (true)).c_str ()); - Logger::getInstance ().add (szBuf, true); - - vector < string > filenames; - //load resources - string str = currentPath + "resources/*."; - - try - { - findAll (str, filenames); - resourceTypes.resize (filenames.size ()); - - for (int i = 0; i < (int) filenames.size (); ++i) - { - str = currentPath + "resources/" + filenames[i]; - resourceTypes[i].load (str, checksum, &checksumValue, - loadedFileList, treePath); - Window::handleEvent (); - SDL_PumpEvents (); - } - - // Cleanup pixmap memory - for (int i = 0; i < (int) filenames.size (); ++i) - { - resourceTypes[i].deletePixels (); - } - } - catch (megaglest_runtime_error & ex) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - ex.what ()); - throw megaglest_runtime_error ("Error loading Resource Types in: " + - currentPath + "\nMessage: " + - ex.what (), !ex.wantStackTrace () - || isValidationModeEnabled); - } - catch (const exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - e.what ()); - throw megaglest_runtime_error ("Error loading Resource Types in: " + - currentPath + "\nMessage: " + - e.what (), isValidationModeEnabled); - } - - // give CPU time to update other things to avoid apperance of hanging - sleep (0); - Window::handleEvent (); - SDL_PumpEvents (); - - //load tech tree xml info - try - { - XmlTree xmlTree; - string currentPath = dir; - endPathWithSlash (currentPath); - string path = currentPath + lastDir (dir) + ".xml"; - - checksum->addFile (path); - checksumValue.addFile (path); - - std::map < string, string > mapExtraTagReplacementValues; - mapExtraTagReplacementValues["$COMMONDATAPATH"] = - currentPath + "/commondata/"; - xmlTree.load (path, - Properties:: - getTagReplacementValues - (&mapExtraTagReplacementValues)); - loadedFileList[path].push_back (make_pair (currentPath, currentPath)); - - Properties::setTechtreePath (currentPath); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf ("==> Set techtree path to [%s]\n", currentPath.c_str ()); - - const XmlNode *techTreeNode = xmlTree.getRootNode (); - - //attack types - const XmlNode *attackTypesNode = - techTreeNode->getChild ("attack-types"); - attackTypes.resize (attackTypesNode->getChildCount ()); - for (int i = 0; i < (int) attackTypes.size (); ++i) - { - const XmlNode *attackTypeNode = - attackTypesNode->getChild ("attack-type", i); - attackTypes[i].setName (attackTypeNode->getAttribute ("name")-> - getRestrictedValue ()); - attackTypes[i].setId (i); - - Window::handleEvent (); - SDL_PumpEvents (); - } - - // give CPU time to update other things to avoid apperance of hanging - sleep (0); - //SDL_PumpEvents(); - - //armor types - const XmlNode *armorTypesNode = - techTreeNode->getChild ("armor-types"); - armorTypes.resize (armorTypesNode->getChildCount ()); - for (int i = 0; i < (int) armorTypes.size (); ++i) - { - const XmlNode *armorTypeNode = - armorTypesNode->getChild ("armor-type", i); - armorTypes[i].setName (armorTypeNode->getAttribute ("name")-> - getRestrictedValue ()); - armorTypes[i].setId (i); - - Window::handleEvent (); - SDL_PumpEvents (); - } - - //damage multipliers - damageMultiplierTable.init ((int) attackTypes.size (), - (int) armorTypes.size ()); - const XmlNode *damageMultipliersNode = - techTreeNode->getChild ("damage-multipliers"); - for (int i = 0; i < (int) damageMultipliersNode->getChildCount (); - ++i) - { - const XmlNode *damageMultiplierNode = - damageMultipliersNode->getChild ("damage-multiplier", i); - const AttackType *attackType = - getAttackType (damageMultiplierNode->getAttribute ("attack")-> - getRestrictedValue ()); - const ArmorType *armorType = - getArmorType (damageMultiplierNode->getAttribute ("armor")-> - getRestrictedValue ()); - double multiplier = - damageMultiplierNode->getAttribute ("value")->getFloatValue (); - damageMultiplierTable.setDamageMultiplier (attackType, armorType, - multiplier); - - Window::handleEvent (); - SDL_PumpEvents (); - } - } - catch (megaglest_runtime_error & ex) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - ex.what ()); - throw megaglest_runtime_error ("Error loading Tech Tree: " + - currentPath + "\nMessage: " + - ex.what (), !ex.wantStackTrace () - || isValidationModeEnabled); - } - catch (const exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - e.what ()); - throw megaglest_runtime_error ("Error loading Tech Tree: " + - currentPath + "\nMessage: " + - e.what (), isValidationModeEnabled); - } - - // give CPU time to update other things to avoid apperance of hanging - sleep (0); - //SDL_PumpEvents(); - - //load factions - try - { - factionTypes.resize (factions.size ()); - - int i = 0; - for (set < string >::iterator it = factions.begin (); - it != factions.end (); ++it) - { - string factionName = *it; - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, "%s %s [%d / %d] - %s", - Lang::getInstance ().getString ("Loading").c_str (), - Lang::getInstance ().getString ("Faction").c_str (), - i + 1, (int) factions.size (), - formatString (this-> - getTranslatedFactionName (name, - factionName)). - c_str ()); - Logger & logger = Logger::getInstance (); - logger.setState (szBuf); - logger. - setProgress ((int) - ((((double) i) / (double) factions.size ()) * - 100.0)); - - factionTypes[i++].load (factionName, this, checksum, &checksumValue, - loadedFileList, validationMode); - - // give CPU time to update other things to avoid apperance of hanging - sleep (0); - Window::handleEvent (); - SDL_PumpEvents (); - } - } - catch (megaglest_runtime_error & ex) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - ex.what ()); - throw megaglest_runtime_error ("Error loading Faction Types: " + - currentPath + "\nMessage: " + - ex.what (), !ex.wantStackTrace () - || isValidationModeEnabled); - } - catch (const exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - e.what ()); - throw megaglest_runtime_error ("Error loading Faction Types: " + - currentPath + "\nMessage: " + - e.what (), isValidationModeEnabled); - } - - if (techtreeChecksum != NULL) - { - *techtreeChecksum = checksumValue; - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } - - TechTree::~TechTree () - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - Logger::getInstance ().add (Lang::getInstance (). - getString ("LogScreenGameUnLoadingTechtree", - "", true), true); - resourceTypes.clear (); - factionTypes.clear (); - armorTypes.clear (); - attackTypes.clear (); - } - - std::vector < std::string > TechTree::validateFactionTypes () - { - std::vector < std::string > results; - for (int i = 0; i < (int) factionTypes.size (); ++i) - { - std::vector < std::string > factionResults = - factionTypes[i].validateFactionType (); - if (factionResults.empty () == false) - { - results.insert (results.end (), factionResults.begin (), - factionResults.end ()); - } - - factionResults = factionTypes[i].validateFactionTypeUpgradeTypes (); - if (factionResults.empty () == false) - { - results.insert (results.end (), factionResults.begin (), - factionResults.end ()); - } - } - - return results; - } - - std::vector < std::string > TechTree::validateResourceTypes () - { - std::vector < std::string > results; - ResourceTypes resourceTypesNotUsed = resourceTypes; - for (unsigned int i = 0; i < resourceTypesNotUsed.size (); ++i) - { - ResourceType & rt = resourceTypesNotUsed[i]; - rt.setCleanupMemory (false); - } - for (unsigned int i = 0; i < factionTypes.size (); ++i) - { - //printf("Validating [%d / %d] faction [%s]\n",i,(int)factionTypes.size(),factionTypes[i].getName().c_str()); - - std::vector < std::string > factionResults = - factionTypes[i].validateFactionTypeResourceTypes (resourceTypes); - if (factionResults.empty () == false) - { - results.insert (results.end (), factionResults.begin (), - factionResults.end ()); - } - - // Check if the faction uses the resources in this techtree - // Now lets find a matching faction resource type for the unit - for (int j = (int)resourceTypesNotUsed.size () - 1; j >= 0; --j) - { - const ResourceType & rt = resourceTypesNotUsed[j]; - //printf("Validating [%d / %d] resourcetype [%s]\n",j,(int)resourceTypesNotUsed.size(),rt.getName().c_str()); - - if (factionTypes[i].factionUsesResourceType (&rt) == true) - { - //printf("FOUND FACTION CONSUMER FOR RESOURCE - [%d / %d] faction [%s] resource [%d / %d] resourcetype [%s]\n",i,(int)factionTypes.size(),factionTypes[i].getName().c_str(),j,(int)resourceTypesNotUsed.size(),rt.getName().c_str()); - resourceTypesNotUsed.erase (resourceTypesNotUsed.begin () + j); - } - } - } - - if (resourceTypesNotUsed.empty () == false) - { - //printf("FOUND unused resource Types [%d]\n",(int)resourceTypesNotUsed.size()); - - for (unsigned int i = 0; i < resourceTypesNotUsed.size (); ++i) - { - const ResourceType & rt = resourceTypesNotUsed[i]; - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The Resource type [%s] is not used by any units in this techtree!", - rt.getName ().c_str ()); - results.push_back (szBuf); - } - } - return results; - } - -// ==================== get ==================== - - FactionType *TechTree::getTypeByName (const string & name) - { - for (int i = 0; i < (int) factionTypes.size (); ++i) - { - if (factionTypes[i].getName (false) == name) - { - return &factionTypes[i]; - } - } - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - throw megaglest_runtime_error ("Faction not found: " + name, true); - } - - const FactionType *TechTree::getType (const string & name) const - { - for (int i = 0; i < (int) factionTypes.size (); ++i) - { - if (factionTypes[i].getName (false) == name) - { - return &factionTypes[i]; - } - } - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - throw megaglest_runtime_error ("Faction not found: " + name, true); - } - - const ResourceType *TechTree::getTechResourceType (int i) const - { - for (int j = 0; j < getResourceTypeCount (); ++j) - { - const ResourceType *rt = getResourceType (j); - assert (rt != NULL); - if (rt == NULL) - { - throw megaglest_runtime_error ("rt == NULL"); - } - if (rt->getResourceNumber () == i && rt->getClass () == rcTech) - return getResourceType (j); - } - - return getFirstTechResourceType (); - } - - const ResourceType *TechTree::getFirstTechResourceType () const - { - for (int i = 0; i < getResourceTypeCount (); ++i) - { - const ResourceType *rt = getResourceType (i); - assert (rt != NULL); - if (rt->getResourceNumber () == 1 && rt->getClass () == rcTech) - return getResourceType (i); - } - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "The referenced tech tree [%s] is either missing or has no resources defined but at least one resource is required.", - this->name.c_str ()); - throw megaglest_runtime_error (szBuf, true); - } - - const ResourceType *TechTree::getResourceType (const string & name) const - { - - for (int i = 0; i < (int) resourceTypes.size (); ++i) - { - if (resourceTypes[i].getName () == name) - { - return &resourceTypes[i]; - } - } - - throw megaglest_runtime_error ("Resource Type not found: " + name, - true); - } - - const ArmorType *TechTree::getArmorType (const string & name) const - { - for (int i = 0; i < (int) armorTypes.size (); ++i) - { - if (armorTypes[i].getName (false) == name) - { - return &armorTypes[i]; - } - } - - throw megaglest_runtime_error ("Armor Type not found: " + name, true); - } - - const AttackType *TechTree::getAttackType (const string & name) const - { - for (int i = 0; i < (int) attackTypes.size (); ++i) - { - if (attackTypes[i].getName (false) == name) - { - return &attackTypes[i]; - } - } - - throw megaglest_runtime_error ("Attack Type not found: " + name, true); - } - - double TechTree::getDamageMultiplier (const AttackType * att, - const ArmorType * art) const - { - return damageMultiplierTable.getDamageMultiplier (att, art); - } - - void TechTree::saveGame (XmlNode * rootNode) - { - std::map < string, string > mapTagReplacements; - XmlNode *techTreeNode = rootNode->addChild ("TechTree"); - -// string name; - techTreeNode->addAttribute ("name", name, mapTagReplacements); -// //string desc; -// string treePath; - //techTreeNode->addAttribute("treePath",treePath, mapTagReplacements); -// vector pathList; -// for(unsigned int i = 0; i < pathList.size(); ++i) { -// XmlNode *pathListNode = techTreeNode->addChild("pathList"); -// pathListNode->addAttribute("value",pathList[i], mapTagReplacements); -// } -// ResourceTypes resourceTypes; -// for(unsigned int i = 0; i < resourceTypes.size(); ++i) { -// ResourceType &rt = resourceTypes[i]; -// rt.saveGame(techTreeNode); -// } -// FactionTypes factionTypes; -// for(unsigned int i = 0; i < factionTypes.size(); ++i) { -// FactionType &ft = factionTypes[i]; -// ft.saveGame(techTreeNode); -// } - -// ArmorTypes armorTypes; -// for(unsigned int i = 0; i < armorTypes.size(); ++i) { -// ArmorType &at = armorTypes[i]; -// at.saveGame(techTreeNode); -// } - -// AttackTypes attackTypes; -// for(unsigned int i = 0; i < attackTypes.size(); ++i) { -// AttackType &at = attackTypes[i]; -// at.saveGame(techTreeNode); -// } - -// DamageMultiplierTable damageMultiplierTable; -// damageMultiplierTable.saveGame(techTreeNode); - -// Checksum checksumValue; - techTreeNode->addAttribute ("checksumValue", - intToStr (checksumValue.getSum ()), - mapTagReplacements); - } - -}} //end namespace +namespace Glest { + namespace Game { + + // ===================================================== + // class TechTree + // ===================================================== + + TechTree::TechTree(const vector < string > pathList) { + SkillType::resetNextAttackBoostId(); + + name = ""; + treePath = ""; + this->pathList.assign(pathList.begin(), pathList.end()); + + resourceTypes.clear(); + factionTypes.clear(); + armorTypes.clear(); + attackTypes.clear(); + translatedTechNames.clear(); + translatedTechFactionNames.clear(); + languageUsedForCache = ""; + isValidationModeEnabled = false; + } + + string TechTree::getNameUntranslated() const { + return name; + } + + string TechTree::getName(bool translatedValue) { + if (translatedValue == false) { + return getNameUntranslated(); + } + + bool foundTranslation = false; + Lang & lang = Lang::getInstance(); + if (lang.getTechNameLoaded() != name || + lang.getLanguage() != languageUsedForCache) { + //printf("Line: %d Tech [%s]\n",__LINE__,name.c_str()); + + foundTranslation = + lang.loadTechTreeStrings(name, + lang.getLanguage() != + languageUsedForCache); + languageUsedForCache = lang.getLanguage(); + translatedTechFactionNames.erase(name); + translatedTechNames.erase(name); + } + + string result = name; + if (foundTranslation == true) { + result = lang.getTechTreeString("TechTreeName", name.c_str()); + } else { + result = formatString(result); + } + + + //printf("Line: %d Tech [%s] result [%s]\n",__LINE__,name.c_str(),result.c_str()); + return result; + } + + string TechTree::getTranslatedName(string techName, bool forceLoad, + bool forceTechtreeActiveFile) { + string result = techName; + + //printf("Line: %d Tech [%s] forceLoad = %d forceTechtreeActiveFile = %d\n",__LINE__,techName.c_str(),forceLoad,forceTechtreeActiveFile); + + Lang & lang = Lang::getInstance(); + if (forceTechtreeActiveFile == false && + translatedTechNames.find(techName) != translatedTechNames.end() && + lang.getLanguage() == languageUsedForCache) { + result = translatedTechNames[techName]; + } else { + name = ""; + string path = findPath(techName); + if (path != "") { + string currentPath = path; + endPathWithSlash(currentPath); + treePath = currentPath; + name = lastDir(currentPath); + + lang.loadTechTreeStrings(name, + lang.getLanguage() != + languageUsedForCache); + languageUsedForCache = lang.getLanguage(); + + translatedTechFactionNames.erase(techName); + translatedTechNames.erase(techName); + + result = getName(true); + + //printf("techName [%s] name [%s] result [%s]\n",techName.c_str(),name.c_str(),result.c_str()); + translatedTechNames[name] = result; + } + + } + return result; + } + + string TechTree::getTranslatedFactionName(string techName, + string factionName) { + //printf("Line: %d Tech [%s] name [%s] factionName [%s]\n",__LINE__,techName.c_str(),name.c_str(),factionName.c_str()); + + Lang & lang = Lang::getInstance(); + if (lang.getTechNameLoaded() != techName || + lang.getLanguage() != languageUsedForCache) { + //printf("Line: %d Tech [%s] name [%s] lang.getTechNameLoaded() [%s] factionName [%s]\n",__LINE__,techName.c_str(),name.c_str(),lang.getTechNameLoaded().c_str(),factionName.c_str()); + + lang.loadTechTreeStrings(techName, + lang.getLanguage() != + languageUsedForCache); + languageUsedForCache = lang.getLanguage(); + + translatedTechFactionNames.erase(techName); + } + + std::map < string, std::map < string, string > >::iterator iterMap = + translatedTechFactionNames.find(techName); + if (iterMap != translatedTechFactionNames.end()) { + if (iterMap->second.find(factionName) != iterMap->second.end()) { + //printf("Line: %d Tech [%s] factionName [%s]\n",__LINE__,techName.c_str(),factionName.c_str()); + + return iterMap->second.find(factionName)->second; + } + } + + //printf("Line: %d Tech [%s] factionName [%s]\n",__LINE__,techName.c_str(),factionName.c_str()); + + getTranslatedName(techName, false, true); + + string result = + lang.getTechTreeString("FactionName_" + factionName, + formatString(factionName).c_str()); + //printf(">>result = %s\n",result.c_str()); + translatedTechFactionNames[techName][factionName] = result; + + //printf("Line: %d Translated faction for Tech [%s] faction [%s] result [%s]\n",__LINE__,techName.c_str(),factionName.c_str(),result.c_str()); + + return result; + } + + Checksum TechTree::loadTech(const string & techName, + set < string > &factions, + Checksum * checksum, std::map < string, + vector < pair < string, + string > > >&loadedFileList, + bool validationMode) { + name = ""; + isValidationModeEnabled = validationMode; + Checksum techtreeChecksum; + string path = findPath(techName); + if (path != "") { + //printf(">>> path=%s\n",path.c_str()); + load(path, factions, checksum, &techtreeChecksum, loadedFileList, + validationMode); + } else { + printf(">>> techtree [%s] path not found.\n", techName.c_str()); + } + return techtreeChecksum; + } + + bool TechTree::exists(const string & techName, + const vector < string > &pathTechList) { + bool techFound = false; + auto_ptr < TechTree > techTree(new TechTree(pathTechList)); + string path = techTree->findPath(techName); + if (path != "") { + techFound = true; + } + return techFound; + } + + string TechTree::findPath(const string & techName) const { + return findPath(techName, pathList); + } + string TechTree::findPath(const string & techName, + const vector < string > &pathTechList) { + for (unsigned int idx = 0; idx < pathTechList.size(); ++idx) { + string currentPath = (pathTechList)[idx]; + endPathWithSlash(currentPath); + + string path = currentPath + techName; + + //printf(">>> test path=%s\n",path.c_str()); + if (isdir(path.c_str()) == true) { + return path; + //break; + } + } + //return "no path found for tech: \""+techname+"\""; + return ""; + } + + + void TechTree::load(const string & dir, set < string > &factions, + Checksum * checksum, Checksum * techtreeChecksum, + std::map < string, vector < pair < string, + string > > >&loadedFileList, bool validationMode) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + string currentPath = dir; + endPathWithSlash(currentPath); + treePath = currentPath; + name = lastDir(currentPath); + + Lang & lang = Lang::getInstance(); + lang.loadTechTreeStrings(name, true); + languageUsedForCache = lang.getLanguage(); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + Lang::getInstance(). + getString("LogScreenGameLoadingTechtree", "", true).c_str(), + formatString(getName(true)).c_str()); + Logger::getInstance().add(szBuf, true); + + vector < string > filenames; + //load resources + string str = currentPath + "resources/*."; + + try { + findAll(str, filenames); + resourceTypes.resize(filenames.size()); + + for (int i = 0; i < (int) filenames.size(); ++i) { + str = currentPath + "resources/" + filenames[i]; + resourceTypes[i].load(str, checksum, &checksumValue, + loadedFileList, treePath); + Window::handleEvent(); + SDL_PumpEvents(); + } + + // Cleanup pixmap memory + for (int i = 0; i < (int) filenames.size(); ++i) { + resourceTypes[i].deletePixels(); + } + } catch (megaglest_runtime_error & ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + ex.what()); + throw megaglest_runtime_error("Error loading Resource Types in: " + + currentPath + "\nMessage: " + + ex.what(), !ex.wantStackTrace() + || isValidationModeEnabled); + } catch (const exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + e.what()); + throw megaglest_runtime_error("Error loading Resource Types in: " + + currentPath + "\nMessage: " + + e.what(), isValidationModeEnabled); + } + + // give CPU time to update other things to avoid apperance of hanging + sleep(0); + Window::handleEvent(); + SDL_PumpEvents(); + + //load tech tree xml info + try { + XmlTree xmlTree; + string currentPath = dir; + endPathWithSlash(currentPath); + string path = currentPath + lastDir(dir) + ".xml"; + + checksum->addFile(path); + checksumValue.addFile(path); + + std::map < string, string > mapExtraTagReplacementValues; + mapExtraTagReplacementValues["$COMMONDATAPATH"] = + currentPath + "/commondata/"; + xmlTree.load(path, + Properties:: + getTagReplacementValues + (&mapExtraTagReplacementValues)); + loadedFileList[path].push_back(make_pair(currentPath, currentPath)); + + Properties::setTechtreePath(currentPath); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("==> Set techtree path to [%s]\n", currentPath.c_str()); + + const XmlNode *techTreeNode = xmlTree.getRootNode(); + + //attack types + const XmlNode *attackTypesNode = + techTreeNode->getChild("attack-types"); + attackTypes.resize(attackTypesNode->getChildCount()); + for (int i = 0; i < (int) attackTypes.size(); ++i) { + const XmlNode *attackTypeNode = + attackTypesNode->getChild("attack-type", i); + attackTypes[i].setName(attackTypeNode->getAttribute("name")-> + getRestrictedValue()); + attackTypes[i].setId(i); + + Window::handleEvent(); + SDL_PumpEvents(); + } + + // give CPU time to update other things to avoid apperance of hanging + sleep(0); + //SDL_PumpEvents(); + + //armor types + const XmlNode *armorTypesNode = + techTreeNode->getChild("armor-types"); + armorTypes.resize(armorTypesNode->getChildCount()); + for (int i = 0; i < (int) armorTypes.size(); ++i) { + const XmlNode *armorTypeNode = + armorTypesNode->getChild("armor-type", i); + armorTypes[i].setName(armorTypeNode->getAttribute("name")-> + getRestrictedValue()); + armorTypes[i].setId(i); + + Window::handleEvent(); + SDL_PumpEvents(); + } + + //damage multipliers + damageMultiplierTable.init((int) attackTypes.size(), + (int) armorTypes.size()); + const XmlNode *damageMultipliersNode = + techTreeNode->getChild("damage-multipliers"); + for (int i = 0; i < (int) damageMultipliersNode->getChildCount(); + ++i) { + const XmlNode *damageMultiplierNode = + damageMultipliersNode->getChild("damage-multiplier", i); + const AttackType *attackType = + getAttackType(damageMultiplierNode->getAttribute("attack")-> + getRestrictedValue()); + const ArmorType *armorType = + getArmorType(damageMultiplierNode->getAttribute("armor")-> + getRestrictedValue()); + double multiplier = + damageMultiplierNode->getAttribute("value")->getFloatValue(); + damageMultiplierTable.setDamageMultiplier(attackType, armorType, + multiplier); + + Window::handleEvent(); + SDL_PumpEvents(); + } + } catch (megaglest_runtime_error & ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + ex.what()); + throw megaglest_runtime_error("Error loading Tech Tree: " + + currentPath + "\nMessage: " + + ex.what(), !ex.wantStackTrace() + || isValidationModeEnabled); + } catch (const exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + e.what()); + throw megaglest_runtime_error("Error loading Tech Tree: " + + currentPath + "\nMessage: " + + e.what(), isValidationModeEnabled); + } + + // give CPU time to update other things to avoid apperance of hanging + sleep(0); + //SDL_PumpEvents(); + + //load factions + try { + factionTypes.resize(factions.size()); + + int i = 0; + for (set < string >::iterator it = factions.begin(); + it != factions.end(); ++it) { + string factionName = *it; + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "%s %s [%d / %d] - %s", + Lang::getInstance().getString("Loading").c_str(), + Lang::getInstance().getString("Faction").c_str(), + i + 1, (int) factions.size(), + formatString(this-> + getTranslatedFactionName(name, + factionName)). + c_str()); + Logger & logger = Logger::getInstance(); + logger.setState(szBuf); + logger. + setProgress((int) + ((((double) i) / (double) factions.size()) * + 100.0)); + + factionTypes[i++].load(factionName, this, checksum, &checksumValue, + loadedFileList, validationMode); + + // give CPU time to update other things to avoid apperance of hanging + sleep(0); + Window::handleEvent(); + SDL_PumpEvents(); + } + } catch (megaglest_runtime_error & ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + ex.what()); + throw megaglest_runtime_error("Error loading Faction Types: " + + currentPath + "\nMessage: " + + ex.what(), !ex.wantStackTrace() + || isValidationModeEnabled); + } catch (const exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + e.what()); + throw megaglest_runtime_error("Error loading Faction Types: " + + currentPath + "\nMessage: " + + e.what(), isValidationModeEnabled); + } + + if (techtreeChecksum != NULL) { + *techtreeChecksum = checksumValue; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } + + TechTree::~TechTree() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + Logger::getInstance().add(Lang::getInstance(). + getString("LogScreenGameUnLoadingTechtree", + "", true), true); + resourceTypes.clear(); + factionTypes.clear(); + armorTypes.clear(); + attackTypes.clear(); + } + + std::vector < std::string > TechTree::validateFactionTypes() { + std::vector < std::string > results; + for (int i = 0; i < (int) factionTypes.size(); ++i) { + std::vector < std::string > factionResults = + factionTypes[i].validateFactionType(); + if (factionResults.empty() == false) { + results.insert(results.end(), factionResults.begin(), + factionResults.end()); + } + + factionResults = factionTypes[i].validateFactionTypeUpgradeTypes(); + if (factionResults.empty() == false) { + results.insert(results.end(), factionResults.begin(), + factionResults.end()); + } + } + + return results; + } + + std::vector < std::string > TechTree::validateResourceTypes() { + std::vector < std::string > results; + ResourceTypes resourceTypesNotUsed = resourceTypes; + for (unsigned int i = 0; i < resourceTypesNotUsed.size(); ++i) { + ResourceType & rt = resourceTypesNotUsed[i]; + rt.setCleanupMemory(false); + } + for (unsigned int i = 0; i < factionTypes.size(); ++i) { + //printf("Validating [%d / %d] faction [%s]\n",i,(int)factionTypes.size(),factionTypes[i].getName().c_str()); + + std::vector < std::string > factionResults = + factionTypes[i].validateFactionTypeResourceTypes(resourceTypes); + if (factionResults.empty() == false) { + results.insert(results.end(), factionResults.begin(), + factionResults.end()); + } + + // Check if the faction uses the resources in this techtree + // Now lets find a matching faction resource type for the unit + for (int j = (int) resourceTypesNotUsed.size() - 1; j >= 0; --j) { + const ResourceType & rt = resourceTypesNotUsed[j]; + //printf("Validating [%d / %d] resourcetype [%s]\n",j,(int)resourceTypesNotUsed.size(),rt.getName().c_str()); + + if (factionTypes[i].factionUsesResourceType(&rt) == true) { + //printf("FOUND FACTION CONSUMER FOR RESOURCE - [%d / %d] faction [%s] resource [%d / %d] resourcetype [%s]\n",i,(int)factionTypes.size(),factionTypes[i].getName().c_str(),j,(int)resourceTypesNotUsed.size(),rt.getName().c_str()); + resourceTypesNotUsed.erase(resourceTypesNotUsed.begin() + j); + } + } + } + + if (resourceTypesNotUsed.empty() == false) { + //printf("FOUND unused resource Types [%d]\n",(int)resourceTypesNotUsed.size()); + + for (unsigned int i = 0; i < resourceTypesNotUsed.size(); ++i) { + const ResourceType & rt = resourceTypesNotUsed[i]; + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The Resource type [%s] is not used by any units in this techtree!", + rt.getName().c_str()); + results.push_back(szBuf); + } + } + return results; + } + + // ==================== get ==================== + + FactionType *TechTree::getTypeByName(const string & name) { + for (int i = 0; i < (int) factionTypes.size(); ++i) { + if (factionTypes[i].getName(false) == name) { + return &factionTypes[i]; + } + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error("Faction not found: " + name, true); + } + + const FactionType *TechTree::getType(const string & name) const { + for (int i = 0; i < (int) factionTypes.size(); ++i) { + if (factionTypes[i].getName(false) == name) { + return &factionTypes[i]; + } + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error("Faction not found: " + name, true); + } + + const ResourceType *TechTree::getTechResourceType(int i) const { + for (int j = 0; j < getResourceTypeCount(); ++j) { + const ResourceType *rt = getResourceType(j); + assert(rt != NULL); + if (rt == NULL) { + throw megaglest_runtime_error("rt == NULL"); + } + if (rt->getResourceNumber() == i && rt->getClass() == rcTech) + return getResourceType(j); + } + + return getFirstTechResourceType(); + } + + const ResourceType *TechTree::getFirstTechResourceType() const { + for (int i = 0; i < getResourceTypeCount(); ++i) { + const ResourceType *rt = getResourceType(i); + assert(rt != NULL); + if (rt->getResourceNumber() == 1 && rt->getClass() == rcTech) + return getResourceType(i); + } + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "The referenced tech tree [%s] is either missing or has no resources defined but at least one resource is required.", + this->name.c_str()); + throw megaglest_runtime_error(szBuf, true); + } + + const ResourceType *TechTree::getResourceType(const string & name) const { + + for (int i = 0; i < (int) resourceTypes.size(); ++i) { + if (resourceTypes[i].getName() == name) { + return &resourceTypes[i]; + } + } + + throw megaglest_runtime_error("Resource Type not found: " + name, + true); + } + + const ArmorType *TechTree::getArmorType(const string & name) const { + for (int i = 0; i < (int) armorTypes.size(); ++i) { + if (armorTypes[i].getName(false) == name) { + return &armorTypes[i]; + } + } + + throw megaglest_runtime_error("Armor Type not found: " + name, true); + } + + const AttackType *TechTree::getAttackType(const string & name) const { + for (int i = 0; i < (int) attackTypes.size(); ++i) { + if (attackTypes[i].getName(false) == name) { + return &attackTypes[i]; + } + } + + throw megaglest_runtime_error("Attack Type not found: " + name, true); + } + + double TechTree::getDamageMultiplier(const AttackType * att, + const ArmorType * art) const { + return damageMultiplierTable.getDamageMultiplier(att, art); + } + + void TechTree::saveGame(XmlNode * rootNode) { + std::map < string, string > mapTagReplacements; + XmlNode *techTreeNode = rootNode->addChild("TechTree"); + + // string name; + techTreeNode->addAttribute("name", name, mapTagReplacements); + // //string desc; + // string treePath; + //techTreeNode->addAttribute("treePath",treePath, mapTagReplacements); + // vector pathList; + // for(unsigned int i = 0; i < pathList.size(); ++i) { + // XmlNode *pathListNode = techTreeNode->addChild("pathList"); + // pathListNode->addAttribute("value",pathList[i], mapTagReplacements); + // } + // ResourceTypes resourceTypes; + // for(unsigned int i = 0; i < resourceTypes.size(); ++i) { + // ResourceType &rt = resourceTypes[i]; + // rt.saveGame(techTreeNode); + // } + // FactionTypes factionTypes; + // for(unsigned int i = 0; i < factionTypes.size(); ++i) { + // FactionType &ft = factionTypes[i]; + // ft.saveGame(techTreeNode); + // } + + // ArmorTypes armorTypes; + // for(unsigned int i = 0; i < armorTypes.size(); ++i) { + // ArmorType &at = armorTypes[i]; + // at.saveGame(techTreeNode); + // } + + // AttackTypes attackTypes; + // for(unsigned int i = 0; i < attackTypes.size(); ++i) { + // AttackType &at = attackTypes[i]; + // at.saveGame(techTreeNode); + // } + + // DamageMultiplierTable damageMultiplierTable; + // damageMultiplierTable.saveGame(techTreeNode); + + // Checksum checksumValue; + techTreeNode->addAttribute("checksumValue", + intToStr(checksumValue.getSum()), + mapTagReplacements); + } + + } +} //end namespace diff --git a/source/glest_game/types/tech_tree.h b/source/glest_game/types/tech_tree.h index dda7e4464..782e44b25 100644 --- a/source/glest_game/types/tech_tree.h +++ b/source/glest_game/types/tech_tree.h @@ -24,139 +24,126 @@ # include "damage_multiplier.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class TechTree -// -/// A set of factions and resources -// ===================================================== + // ===================================================== + // class TechTree + // + /// A set of factions and resources + // ===================================================== - class TechTree - { - private: - typedef vector < ResourceType > ResourceTypes; - typedef vector < FactionType > FactionTypes; - typedef vector < ArmorType > ArmorTypes; - typedef vector < AttackType > AttackTypes; + class TechTree { + private: + typedef vector < ResourceType > ResourceTypes; + typedef vector < FactionType > FactionTypes; + typedef vector < ArmorType > ArmorTypes; + typedef vector < AttackType > AttackTypes; - private: + private: - string name; - //string desc; - string treePath; - vector < string > pathList; + string name; + //string desc; + string treePath; + vector < string > pathList; - ResourceTypes resourceTypes; - FactionTypes factionTypes; - ArmorTypes armorTypes; - AttackTypes attackTypes; - DamageMultiplierTable damageMultiplierTable; - Checksum checksumValue; + ResourceTypes resourceTypes; + FactionTypes factionTypes; + ArmorTypes armorTypes; + AttackTypes attackTypes; + DamageMultiplierTable damageMultiplierTable; + Checksum checksumValue; - string languageUsedForCache; - std::map < string, string > translatedTechNames; - std::map < string, std::map < string, - string > >translatedTechFactionNames; - bool isValidationModeEnabled; + string languageUsedForCache; + std::map < string, string > translatedTechNames; + std::map < string, std::map < string, + string > >translatedTechFactionNames; + bool isValidationModeEnabled; - public: - Checksum loadTech (const string & techName, - set < string > &factions, Checksum * checksum, - std::map < string, vector < pair < string, - string > > >&loadedFileList, bool validationMode = - false); - void load (const string & dir, set < string > &factions, - Checksum * checksum, Checksum * techtreeChecksum, - std::map < string, vector < pair < string, - string > > >&loadedFileList, bool validationMode = false); - string findPath (const string & techName) const; + public: + Checksum loadTech(const string & techName, + set < string > &factions, Checksum * checksum, + std::map < string, vector < pair < string, + string > > >&loadedFileList, bool validationMode = + false); + void load(const string & dir, set < string > &factions, + Checksum * checksum, Checksum * techtreeChecksum, + std::map < string, vector < pair < string, + string > > >&loadedFileList, bool validationMode = false); + string findPath(const string & techName) const; - static string findPath (const string & techName, - const vector < string > &pathTechList); - static bool exists (const string & techName, - const vector < string > &pathTechList); + static string findPath(const string & techName, + const vector < string > &pathTechList); + static bool exists(const string & techName, + const vector < string > &pathTechList); - explicit TechTree (const vector < string > pathList); - ~TechTree (); - Checksum *getChecksumValue () - { - return &checksumValue; - } + explicit TechTree(const vector < string > pathList); + ~TechTree(); + Checksum *getChecksumValue() { + return &checksumValue; + } - //get - int getResourceTypeCount () const - { - return (int) resourceTypes.size (); - } - int getTypeCount () const - { - return (int) factionTypes.size (); - } - const FactionType *getType (int i) const - { - return &factionTypes[i]; - } - const ResourceType *getResourceType (int i) const - { - return &resourceTypes[i]; - } - string getName (bool translatedValue = false); - string getNameUntranslated () const; + //get + int getResourceTypeCount() const { + return (int) resourceTypes.size(); + } + int getTypeCount() const { + return (int) factionTypes.size(); + } + const FactionType *getType(int i) const { + return &factionTypes[i]; + } + const ResourceType *getResourceType(int i) const { + return &resourceTypes[i]; + } + string getName(bool translatedValue = false); + string getNameUntranslated() const; - string getTranslatedName (string techName, bool forceLoad = - false, bool forceTechtreeActiveFile = false); - string getTranslatedFactionName (string techName, string factionName); + string getTranslatedName(string techName, bool forceLoad = + false, bool forceTechtreeActiveFile = false); + string getTranslatedFactionName(string techName, string factionName); - vector < string > getPathList () const - { - return pathList; - } - //const string &getDesc() const {return desc;} + vector < string > getPathList() const { + return pathList; + } + //const string &getDesc() const {return desc;} - const string getPath () const - { - return treePath; - } + const string getPath() const { + return treePath; + } - const FactionType *getType (const string & name) const; - FactionType *getTypeByName (const string & name); - const ResourceType *getResourceType (const string & name) const; - const ResourceType *getTechResourceType (int i) const; - const ResourceType *getFirstTechResourceType () const; + const FactionType *getType(const string & name) const; + FactionType *getTypeByName(const string & name); + const ResourceType *getResourceType(const string & name) const; + const ResourceType *getTechResourceType(int i) const; + const ResourceType *getFirstTechResourceType() const; - const ArmorType *getArmorType (const string & name) const; - const AttackType *getAttackType (const string & name) const; + const ArmorType *getArmorType(const string & name) const; + const AttackType *getAttackType(const string & name) const; - int getArmorTypeCount () const - { - return (int) armorTypes.size (); - } - const ArmorType *getArmorTypeByIndex (int index) const - { - return &armorTypes[index]; - } - int getAttackTypeCount () const - { - return (int) attackTypes.size (); - } - const AttackType *getAttackTypeByIndex (int index) const - { - return &attackTypes[index]; - } + int getArmorTypeCount() const { + return (int) armorTypes.size(); + } + const ArmorType *getArmorTypeByIndex(int index) const { + return &armorTypes[index]; + } + int getAttackTypeCount() const { + return (int) attackTypes.size(); + } + const AttackType *getAttackTypeByIndex(int index) const { + return &attackTypes[index]; + } - double getDamageMultiplier (const AttackType * att, - const ArmorType * art) const; - std::vector < std::string > validateFactionTypes (); - std::vector < std::string > validateResourceTypes (); + double getDamageMultiplier(const AttackType * att, + const ArmorType * art) const; + std::vector < std::string > validateFactionTypes(); + std::vector < std::string > validateResourceTypes(); - void saveGame (XmlNode * rootNode); + void saveGame(XmlNode * rootNode); - }; + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/types/tileset_model_type.cpp b/source/glest_game/types/tileset_model_type.cpp index 232a30c27..e4697f0f9 100644 --- a/source/glest_game/types/tileset_model_type.cpp +++ b/source/glest_game/types/tileset_model_type.cpp @@ -12,42 +12,37 @@ #include "tileset_model_type.h" #include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { -// ===================================================== -// class TilesetModelType -// ===================================================== + // ===================================================== + // class TilesetModelType + // ===================================================== - TilesetModelType::TilesetModelType () - { - model = NULL; - height = 0; - rotationAllowed = false; - smoothTwoFrameAnim = false; - randomPositionEnabled = false; + TilesetModelType::TilesetModelType() { + model = NULL; + height = 0; + rotationAllowed = false; + smoothTwoFrameAnim = false; + randomPositionEnabled = false; - animSpeed = 0; - } + animSpeed = 0; + } - TilesetModelType::~TilesetModelType () - { - while (!(particleTypes.empty ())) - { - delete particleTypes.back (); - particleTypes.pop_back (); - } - //Logger::getInstance().add("ObjectType", true); - } + TilesetModelType::~TilesetModelType() { + while (!(particleTypes.empty())) { + delete particleTypes.back(); + particleTypes.pop_back(); + } + //Logger::getInstance().add("ObjectType", true); + } - void TilesetModelType::addParticleSystem (ObjectParticleSystemType * - particleSystem) - { - particleTypes.push_back (particleSystem); - } + void TilesetModelType::addParticleSystem(ObjectParticleSystemType * + particleSystem) { + particleTypes.push_back(particleSystem); + } -}} //end namespace + } +} //end namespace diff --git a/source/glest_game/types/tileset_model_type.h b/source/glest_game/types/tileset_model_type.h index 49648c40f..ffe3adca0 100644 --- a/source/glest_game/types/tileset_model_type.h +++ b/source/glest_game/types/tileset_model_type.h @@ -24,107 +24,91 @@ using std::vector; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - using Shared::Graphics::Model; - using Shared::Graphics::Vec3f; + using Shared::Graphics::Model; + using Shared::Graphics::Vec3f; -// ===================================================== -// class ObjectType -// -/// Each of the possible objects of the map: trees, stones ... -// ===================================================== + // ===================================================== + // class ObjectType + // + /// Each of the possible objects of the map: trees, stones ... + // ===================================================== - typedef vector < ObjectParticleSystemType * >ModelParticleSystemTypes; + typedef vector < ObjectParticleSystemType * >ModelParticleSystemTypes; - class TilesetModelType - { - private: - Model * model; - ModelParticleSystemTypes particleTypes; - int height; - bool rotationAllowed; - bool randomPositionEnabled; - bool smoothTwoFrameAnim; + class TilesetModelType { + private: + Model * model; + ModelParticleSystemTypes particleTypes; + int height; + bool rotationAllowed; + bool randomPositionEnabled; + bool smoothTwoFrameAnim; - int animSpeed; + int animSpeed; - public: - TilesetModelType (); - ~TilesetModelType (); + public: + TilesetModelType(); + ~TilesetModelType(); - void addParticleSystem (ObjectParticleSystemType * particleSystem); - inline bool hasParticles () const - { - return particleTypes.empty () == false; - } - inline ModelParticleSystemTypes *getParticleTypes () - { - return &particleTypes; - } + void addParticleSystem(ObjectParticleSystemType * particleSystem); + inline bool hasParticles() const { + return particleTypes.empty() == false; + } + inline ModelParticleSystemTypes *getParticleTypes() { + return &particleTypes; + } - inline Model *getModel () const - { - return model; - } - inline void setModel (Model * model) - { - this->model = model; - } + inline Model *getModel() const { + return model; + } + inline void setModel(Model * model) { + this->model = model; + } - inline int getHeight () const - { - return height; - } - inline void setHeight (int height) - { - this->height = height; - } + inline int getHeight() const { + return height; + } + inline void setHeight(int height) { + this->height = height; + } - inline bool getRotationAllowed () const - { - return rotationAllowed; - } - inline void setRotationAllowed (bool rotationAllowed) - { - this->rotationAllowed = rotationAllowed; - } + inline bool getRotationAllowed() const { + return rotationAllowed; + } + inline void setRotationAllowed(bool rotationAllowed) { + this->rotationAllowed = rotationAllowed; + } - inline bool getRandomPositionEnabled () const - { - return randomPositionEnabled; - } - inline void setRandomPositionEnabled (bool randomPositionEnabled) - { - this->randomPositionEnabled = randomPositionEnabled; - } + inline bool getRandomPositionEnabled() const { + return randomPositionEnabled; + } + inline void setRandomPositionEnabled(bool randomPositionEnabled) { + this->randomPositionEnabled = randomPositionEnabled; + } - inline bool getSmoothTwoFrameAnim () const - { - return smoothTwoFrameAnim; - } - inline void setSmoothTwoFrameAnim (bool smoothTwoFrameAnim) - { - this->smoothTwoFrameAnim = smoothTwoFrameAnim; - } + inline bool getSmoothTwoFrameAnim() const { + return smoothTwoFrameAnim; + } + inline void setSmoothTwoFrameAnim(bool smoothTwoFrameAnim) { + this->smoothTwoFrameAnim = smoothTwoFrameAnim; + } - inline int getAnimSpeed () const - { - return animSpeed; - } - inline void setAnimSpeed (int value) - { - animSpeed = value; - } + inline int getAnimSpeed() const { + return animSpeed; + } + inline void setAnimSpeed(int value) { + animSpeed = value; + } -// inline int getAnimSpeedVariation() const {return animVariation;} -// inline void setAnimSpeedVariation(int value) {animSpeed = valueVariation;} - }; + // inline int getAnimSpeedVariation() const {return animVariation;} + // inline void setAnimSpeedVariation(int value) {animSpeed = valueVariation;} + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/types/unit_type.cpp b/source/glest_game/types/unit_type.cpp index a4f41b194..f13b21210 100644 --- a/source/glest_game/types/unit_type.cpp +++ b/source/glest_game/types/unit_type.cpp @@ -35,1895 +35,1629 @@ using namespace Shared::Xml; using namespace Shared::Graphics; using namespace Shared::Util; -namespace Glest -{ - namespace Game - { - - auto_ptr < CommandType > - UnitType:: - ctHarvestEmergencyReturnCommandType (new - HarvestEmergencyReturnCommandType - ()); -// =============================== -// class Level -// =============================== - - void Level::init (string name, int kills) - { - this->name = name; - this->kills = kills; - } - - string Level::getName (bool translatedValue) const - { - if (translatedValue == false) - return name; - - Lang & lang = Lang::getInstance (); - return lang.getTechTreeString ("LevelName_" + name, name.c_str ()); - } - - void Level::saveGame (XmlNode * rootNode) const - { - std::map < string, string > mapTagReplacements; - XmlNode *levelNode = rootNode->addChild ("Level"); - - levelNode->addAttribute ("name", name, mapTagReplacements); - levelNode->addAttribute ("kills", intToStr (kills), mapTagReplacements); - } - - const Level *Level::loadGame (const XmlNode * rootNode, - const UnitType * ut) - { - const Level *result = NULL; - if (rootNode->hasChild ("Level") == true) - { - const XmlNode *levelNode = rootNode->getChild ("Level"); - - result = ut->getLevel (levelNode->getAttribute ("name")->getValue ()); - } - - return result; - } - -// ===================================================== -// class UnitType -// ===================================================== - -// ===================== PUBLIC ======================== - - const char *UnitType::propertyNames[] = { "burnable", "rotated_climb" }; - -// ==================== creation and loading ==================== - - UnitType::UnitType ():ProducibleType () - { - - countInVictoryConditions = ucvcNotSet; - meetingPointImage = NULL; - lightColor = Vec3f (0.f); - light = false; - healthbarheight = -100.0f; - healthbarthickness = -1.0f; - healthbarVisible = hbvUndefined; - multiSelect = false; - uniformSelect = false; - commandable = true; - armorType = NULL; - rotatedBuildPos = 0; - - field = fLand; - id = 0; - meetingPoint = false; - rotationAllowed = false; - - countUnitDeathInStats = false; - countUnitProductionInStats = false; - countUnitKillInStats = false; - countKillForUnitUpgrade = false; - - - for (int i = 0; i < ccCount; ++i) - { - firstCommandTypeOfClass[i] = NULL; - } - - for (int i = 0; i < scCount; ++i) - { - firstSkillTypeOfClass[i] = NULL; - } - - for (int i = 0; i < pCount; ++i) - { - properties[i] = false; - } - - for (int i = 0; i < fieldCount; ++i) - { - fields[i] = false; - } - - cellMap = NULL; - allowEmptyCellMap = false; - hpRegeneration = 0; - epRegeneration = 0; - maxUnitCount = 0; - maxHp = 0; - startHpValue = 0; - startHpPercentage = 1.0; - startHpType = stValue; - maxEp = 0; - startEpValue = 0; - startEpPercentage = 0; - startEpType = stValue; - armor = 0; - sight = 0; - size = 0; - aiBuildSize = -1; - renderSize = 0; - height = 0; - burnHeight = 0; - targetHeight = 0; - - addItemToVault (&(this->maxHp), this->maxHp); - addItemToVault (&(this->hpRegeneration), this->hpRegeneration); - addItemToVault (&(this->maxEp), this->maxEp); - addItemToVault (&(this->epRegeneration), this->epRegeneration); - addItemToVault (&(this->maxUnitCount), this->maxUnitCount); - addItemToVault (&(this->armor), this->armor); - addItemToVault (&(this->sight), this->sight); - addItemToVault (&(this->size), this->size); - addItemToVault (&(this->height), this->height); - } - - UnitType::~UnitType () - { - deleteValues (commandTypes.begin (), commandTypes.end ()); - commandTypes.clear (); - deleteValues (skillTypes.begin (), skillTypes.end ()); - skillTypes.clear (); - deleteValues (selectionSounds.getSounds ().begin (), - selectionSounds.getSounds ().end ()); - selectionSounds.clearSounds (); - deleteValues (commandSounds.getSounds ().begin (), - commandSounds.getSounds ().end ()); - commandSounds.clearSounds (); - delete[]cellMap; - cellMap = NULL; - //remove damageParticleSystemTypes - while (!damageParticleSystemTypes.empty ()) - { - delete damageParticleSystemTypes.back (); - damageParticleSystemTypes.pop_back (); - } - } - - void UnitType::preLoad (const string & dir) - { - name = lastDir (dir); - } - - void UnitType::loaddd (int id, const string & dir, - const TechTree * techTree, - const string & techTreePath, - const FactionType * factionType, - Checksum * checksum, Checksum * techtreeChecksum, - std::map < string, vector < pair < string, - string > > >&loadedFileList, bool validationMode) - { - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - - string currentPath = dir; - endPathWithSlash (currentPath); - string path = currentPath + name + ".xml"; - string sourceXMLFile = path; - - this->id = id; - - try - { - //Lang &lang= Lang::getInstance(); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - Lang::getInstance (). - getString ("LogScreenGameLoadingUnitType", "", - true).c_str (), - formatString (this->getName (true)).c_str ()); - Logger::getInstance ().add (szBuf, true); - - //file load - checksum->addFile (path); - techtreeChecksum->addFile (path); - - XmlTree xmlTree; - std::map < string, string > mapExtraTagReplacementValues; - mapExtraTagReplacementValues["$COMMONDATAPATH"] = - techTreePath + "/commondata/"; - xmlTree.load (path, - Properties:: - getTagReplacementValues - (&mapExtraTagReplacementValues)); - loadedFileList[path].push_back (make_pair (dir, dir)); - - const XmlNode *unitNode = xmlTree.getRootNode (); - - const XmlNode *parametersNode = unitNode->getChild ("parameters"); - - if (parametersNode->hasChild ("count-in-victory-conditions") == true) - { - bool countUnit = - parametersNode->getChild ("count-in-victory-conditions")-> - getAttribute ("value")->getBoolValue (); - if (countUnit == true) - { - countInVictoryConditions = ucvcTrue; - } - else - { - countInVictoryConditions = ucvcFalse; - } - } - - //size - //checkItemInVault(&(this->size),this->size); - size = - parametersNode->getChild ("size")->getAttribute ("value")-> - getIntValue (); - addItemToVault (&(this->size), this->size); - renderSize = size; - if (parametersNode->hasChild ("render-size")) - { - renderSize = - parametersNode->getChild ("render-size")->getAttribute ("value")-> - getIntValue (); - } - aiBuildSize = size; - if (parametersNode->hasChild ("ai-build-size")) - { - aiBuildSize = - parametersNode->getChild ("ai-build-size")-> - getAttribute ("value")->getIntValue (); - } - - //height - //checkItemInVault(&(this->height),this->height); - height = - parametersNode->getChild ("height")->getAttribute ("value")-> - getIntValue (); - addItemToVault (&(this->height), this->height); - - //targetHeight - if (parametersNode->hasChild ("target-height")) - { - targetHeight = - parametersNode->getChild ("target-height")-> - getAttribute ("value")->getIntValue (); - addItemToVault (&(this->targetHeight), this->targetHeight); - } - else - { - targetHeight = height; - } - //burnHeight - if (parametersNode->hasChild ("target-height")) - { - burnHeight = - parametersNode->getChild ("burn-height")->getAttribute ("value")-> - getIntValue (); - addItemToVault (&(this->burnHeight), this->burnHeight); - } - else - { - burnHeight = height; - } - - - //maxHp - //checkItemInVault(&(this->maxHp),this->maxHp); - maxHp = - parametersNode->getChild ("max-hp")->getAttribute ("value")-> - getIntValue (); - addItemToVault (&(this->maxHp), this->maxHp); - - //hpRegeneration - //checkItemInVault(&(this->hpRegeneration),this->hpRegeneration); - hpRegeneration = - parametersNode->getChild ("max-hp")->getAttribute ("regeneration")-> - getIntValue (); - addItemToVault (&(this->hpRegeneration), this->hpRegeneration); - - //maxEp - //checkItemInVault(&(this->maxEp),this->maxEp); - maxEp = - parametersNode->getChild ("max-ep")->getAttribute ("value")-> - getIntValue (); - addItemToVault (&(this->maxEp), this->maxEp); - - if (maxEp != 0) - { - //epRegeneration - //checkItemInVault(&(this->epRegeneration),this->epRegeneration); - epRegeneration = - parametersNode->getChild ("max-ep")-> - getAttribute ("regeneration")->getIntValue (); - } - addItemToVault (&(this->epRegeneration), this->epRegeneration); - - // Check that we don't use both start-value and start-percentage, as they are mutually - // exclusive - if (parametersNode->getChild ("max-hp")->hasAttribute ("start-value") - && parametersNode->getChild ("max-hp")-> - hasAttribute ("start-percentage")) - { - throw megaglest_runtime_error ("Unit " + name + - " has both start-value and start-percentage for HP", - true); - } - - //startHpValue -- the *absolute* value to use for starting HP - if (parametersNode->getChild ("max-hp")->hasAttribute ("start-value")) - { - //checkItemInVault(&(this->startEp),this->startEp); - startHpValue = - parametersNode->getChild ("max-hp")-> - getAttribute ("start-value")->getIntValue (); - startHpType = stValue; - } - addItemToVault (&(this->startHpValue), this->startHpValue); - - //startHpPercentage -- the *relative* value to use for starting HP - if (parametersNode->getChild ("max-hp")-> - hasAttribute ("start-percentage")) - { - startHpPercentage = - parametersNode->getChild ("max-hp")-> - getAttribute ("start-percentage")->getIntValue (); - startHpType = stPercentage; - } - - // No start value set; use max HP before upgrades - if (!parametersNode->getChild ("max-hp")->hasAttribute ("start-value") - && !parametersNode->getChild ("max-hp")-> - hasAttribute ("start-percentage")) - { - startHpValue = - parametersNode->getChild ("max-hp")->getAttribute ("value")-> - getIntValue (); - startHpType = stValue; - } - addItemToVault (&(this->startHpPercentage), this->startHpPercentage); - - // Check that we don't use both start-value and start-percentage, as they are mutually - // exclusive - if (parametersNode->getChild ("max-ep")->hasAttribute ("start-value") - && parametersNode->getChild ("max-ep")-> - hasAttribute ("start-percentage")) - { - throw megaglest_runtime_error ("Unit " + name + - " has both start-value and start-percentage for EP", - true); - } - - //startEpValue -- the *absolute* value to use for starting EP - if (parametersNode->getChild ("max-ep")->hasAttribute ("start-value")) - { - //checkItemInVault(&(this->startEp),this->startEp); - startEpValue = - parametersNode->getChild ("max-ep")-> - getAttribute ("start-value")->getIntValue (); - startEpType = stValue; - } - addItemToVault (&(this->startEpValue), this->startEpValue); - - //startEpPercentage -- the *relative* value to use for starting EP - if (parametersNode->getChild ("max-ep")-> - hasAttribute ("start-percentage")) - { - startEpPercentage = - parametersNode->getChild ("max-ep")-> - getAttribute ("start-percentage")->getIntValue (); - startEpType = stPercentage; - } - addItemToVault (&(this->startEpPercentage), this->startEpPercentage); - - //maxUnitCount - if (parametersNode->hasChild ("max-unit-count")) - { - //checkItemInVault(&(this->maxUnitCount),this->maxUnitCount); - maxUnitCount = - parametersNode->getChild ("max-unit-count")-> - getAttribute ("value")->getIntValue (); - } - addItemToVault (&(this->maxUnitCount), this->maxUnitCount); - - //armor - //checkItemInVault(&(this->armor),this->armor); - armor = - parametersNode->getChild ("armor")->getAttribute ("value")-> - getIntValue (); - addItemToVault (&(this->armor), this->armor); - - //armor type string - string armorTypeName = - parametersNode->getChild ("armor-type")->getAttribute ("value")-> - getRestrictedValue (); - armorType = techTree->getArmorType (armorTypeName); - - //sight - //checkItemInVault(&(this->sight),this->sight); - sight = - parametersNode->getChild ("sight")->getAttribute ("value")-> - getIntValue (); - addItemToVault (&(this->sight), this->sight); - - //prod time - productionTime = - parametersNode->getChild ("time")->getAttribute ("value")-> - getIntValue (); - - //multi selection - multiSelect = - parametersNode->getChild ("multi-selection")-> - getAttribute ("value")->getBoolValue (); - - //uniform selection - if (parametersNode->hasChild ("uniform-selection")) - { - uniformSelect = - parametersNode->getChild ("uniform-selection")-> - getAttribute ("value")->getBoolValue (); - } - - //commandable - if (parametersNode->hasChild ("commandable")) - { - commandable = - parametersNode->getChild ("commandable")->getAttribute ("value")-> - getBoolValue (); - } - //cellmap - allowEmptyCellMap = false; - const XmlNode *cellMapNode = parametersNode->getChild ("cellmap"); - bool hasCellMap = - cellMapNode->getAttribute ("value")->getBoolValue (); - if (hasCellMap == true) - { - if (cellMapNode->getAttribute ("allowEmpty", false) != NULL) - { - allowEmptyCellMap = - cellMapNode->getAttribute ("allowEmpty")->getBoolValue (); - } - - cellMap = new bool[size * size]; - for (int i = 0; i < size; ++i) - { - const XmlNode *rowNode = cellMapNode->getChild ("row", i); - string row = - rowNode->getAttribute ("value")->getRestrictedValue (); - if ((int) row.size () != size) - { - throw - megaglest_runtime_error - ("Cellmap row has not the same length as unit size", true); - } - for (int j = 0; j < (int) row.size (); ++j) - { - cellMap[i * size + j] = row[j] == '0' ? false : true; - } - } - } - - //levels - const XmlNode *levelsNode = parametersNode->getChild ("levels"); - levels.resize (levelsNode->getChildCount ()); - for (int i = 0; i < (int) levels.size (); ++i) - { - const XmlNode *levelNode = levelsNode->getChild ("level", i); - - levels[i].init (levelNode->getAttribute ("name")-> - getRestrictedValue (), - levelNode->getAttribute ("kills")->getIntValue ()); - } - - //fields - const XmlNode *fieldsNode = parametersNode->getChild ("fields"); - for (int i = 0; i < (int) fieldsNode->getChildCount (); ++i) - { - const XmlNode *fieldNode = fieldsNode->getChild ("field", i); - string fieldName = - fieldNode->getAttribute ("value")->getRestrictedValue (); - if (fieldName == "land") - { - fields[fLand] = true; - } - else if (fieldName == "air") - { - fields[fAir] = true; - } - else - { - throw megaglest_runtime_error ("Not a valid field: " + fieldName + - ": " + path, true); - } - } - - if (fields[fLand]) - { - field = fLand; - } - else if (fields[fAir]) - { - field = fAir; - } - else - { - throw megaglest_runtime_error ("Unit has no field: " + path, true); - } - - //properties - const XmlNode *propertiesNode = - parametersNode->getChild ("properties"); - for (int i = 0; i < (int) propertiesNode->getChildCount (); ++i) - { - const XmlNode *propertyNode = - propertiesNode->getChild ("property", i); - string propertyName = - propertyNode->getAttribute ("value")->getRestrictedValue (); - bool found = false; - for (int i = 0; i < pCount; ++i) - { - if (propertyName == propertyNames[i]) - { - properties[i] = true; - found = true; - break; - } - } - if (!found) - { - throw megaglest_runtime_error ("Unknown property: " + - propertyName, true); - } - } - //damage-particles - if (parametersNode->hasChild ("damage-particles")) - { - const XmlNode *particleNode = - parametersNode->getChild ("damage-particles"); - bool particleEnabled = - particleNode->getAttribute ("value")->getBoolValue (); - - if (particleEnabled) - { - for (int i = 0; i < (int) particleNode->getChildCount (); ++i) - { - const XmlNode *particleFileNode = - particleNode->getChild ("particle-file", i); - string path = - particleFileNode->getAttribute ("path")-> - getRestrictedValue (); - UnitParticleSystemType *unitParticleSystemType = - new UnitParticleSystemType (); - - unitParticleSystemType->load (particleFileNode, dir, - currentPath + path, - &Renderer::getInstance (), - loadedFileList, sourceXMLFile, - techTree->getPath ()); - loadedFileList[currentPath + - path].push_back (make_pair (sourceXMLFile, - particleFileNode-> - getAttribute - ("path")-> - getRestrictedValue - ())); - - if (particleFileNode->getAttribute ("minHp", false) != NULL - && particleFileNode->getAttribute ("maxHp", false) != NULL) - { - unitParticleSystemType->setMinmaxEnabled (true); - unitParticleSystemType->setMinHp (particleFileNode-> - getAttribute ("minHp")-> - getIntValue ()); - unitParticleSystemType->setMaxHp (particleFileNode-> - getAttribute ("maxHp")-> - getIntValue ()); - - if (particleFileNode-> - getAttribute ("ispercentbased", false) != NULL) - { - unitParticleSystemType-> - setMinmaxIsPercent (particleFileNode-> - getAttribute ("ispercentbased")-> - getBoolValue ()); - } - - } - - damageParticleSystemTypes.push_back (unitParticleSystemType); - } - } - } - - //healthbar - if (parametersNode->hasChild ("healthbar")) - { - const XmlNode *healthbarNode = - parametersNode->getChild ("healthbar"); - if (healthbarNode->hasChild ("height")) - { - healthbarheight = - healthbarNode->getChild ("height")->getAttribute ("value")-> - getFloatValue (); - } - if (healthbarNode->hasChild ("thickness")) - { - healthbarthickness = - healthbarNode->getChild ("thickness")->getAttribute ("value")-> - getFloatValue (0.f, 1.f); - } - if (healthbarNode->hasChild ("visible")) - { - string healthbarVisibleString = - healthbarNode->getChild ("visible")->getAttribute ("value")-> - getValue (); - vector < string > v = split (healthbarVisibleString, "|"); - for (int i = 0; i < (int) v.size (); ++i) - { - string current = trim (v[i]); - if (current == "always") - { - healthbarVisible = healthbarVisible | hbvAlways; - } - else if (current == "selected") - { - healthbarVisible = healthbarVisible | hbvSelected; - } - else if (current == "ifNeeded") - { - healthbarVisible = healthbarVisible | hbvIfNeeded; - } - else if (current == "off") - { - healthbarVisible = healthbarVisible | hbvOff; - } - else - { - throw - megaglest_runtime_error - ("Unknown Healthbar Visible Option: " + current, true); - } - } - } - } - - //light - const XmlNode *lightNode = parametersNode->getChild ("light"); - light = lightNode->getAttribute ("enabled")->getBoolValue (); - if (light) - { - lightColor.x = - lightNode->getAttribute ("red")->getFloatValue (0.f, 1.f); - lightColor.y = - lightNode->getAttribute ("green")->getFloatValue (0.f, 1.f); - lightColor.z = - lightNode->getAttribute ("blue")->getFloatValue (0.f, 1.f); - } - - //rotationAllowed - if (parametersNode->hasChild ("rotationAllowed")) - { - const XmlNode *rotationAllowedNode = - parametersNode->getChild ("rotationAllowed"); - rotationAllowed = - rotationAllowedNode->getAttribute ("value")->getBoolValue (); - } - else - { - rotationAllowed = true; - } - - std::map < string, int >sortedItems; - - //unit requirements - bool hasDup = false; - const XmlNode *unitRequirementsNode = - parametersNode->getChild ("unit-requirements"); - for (int i = 0; i < (int) unitRequirementsNode->getChildCount (); ++i) - { - const XmlNode *unitNode = - unitRequirementsNode->getChild ("unit", i); - string name = - unitNode->getAttribute ("name")->getRestrictedValue (); - - if (sortedItems.find (name) != sortedItems.end ()) - { - hasDup = true; - } - - sortedItems[name] = 0; - } - if (hasDup) - { - printf - ("WARNING, unit type [%s] has one or more duplicate unit requirements\n", - this->getName (false).c_str ()); - } - - for (std::map < string, int >::iterator iterMap = - sortedItems.begin (); iterMap != sortedItems.end (); ++iterMap) - { - unitReqs.push_back (factionType->getUnitType (iterMap->first)); - } - sortedItems.clear (); - hasDup = false; - - //upgrade requirements - const XmlNode *upgradeRequirementsNode = - parametersNode->getChild ("upgrade-requirements"); - for (int i = 0; i < (int) upgradeRequirementsNode->getChildCount (); - ++i) - { - const XmlNode *upgradeReqNode = - upgradeRequirementsNode->getChild ("upgrade", i); - string name = - upgradeReqNode->getAttribute ("name")->getRestrictedValue (); - - if (sortedItems.find (name) != sortedItems.end ()) - { - hasDup = true; - } - - sortedItems[name] = 0; - } - - if (hasDup) - { - printf - ("WARNING, unit type [%s] has one or more duplicate upgrade requirements\n", - this->getName (false).c_str ()); - } - - for (std::map < string, int >::iterator iterMap = - sortedItems.begin (); iterMap != sortedItems.end (); ++iterMap) - { - upgradeReqs.push_back (factionType-> - getUpgradeType (iterMap->first)); - } - sortedItems.clear (); - hasDup = false; - - //resource requirements - const XmlNode *resourceRequirementsNode = - parametersNode->getChild ("resource-requirements"); - costs.resize (resourceRequirementsNode->getChildCount ()); - for (int i = 0; i < (int) costs.size (); ++i) - { - const XmlNode *resourceNode = - resourceRequirementsNode->getChild ("resource", i); - string name = - resourceNode->getAttribute ("name")->getRestrictedValue (); - int amount = resourceNode->getAttribute ("amount")->getIntValue (); - - if (sortedItems.find (name) != sortedItems.end ()) - { - hasDup = true; - } - sortedItems[name] = amount; - } - //if(hasDup || sortedItems.size() != costs.size()) printf("Found duplicate resource requirement, costs.size() = %d sortedItems.size() = %d\n",costs.size(),sortedItems.size()); - - if (hasDup) - { - printf - ("WARNING, unit type [%s] has one or more duplicate resource requirements\n", - this->getName (false).c_str ()); - } - - if (sortedItems.size () < costs.size ()) - { - costs.resize (sortedItems.size ()); - } - int index = 0; - for (std::map < string, int >::iterator iterMap = - sortedItems.begin (); iterMap != sortedItems.end (); ++iterMap) - { - try - { - costs[index].init (techTree->getResourceType (iterMap->first), - iterMap->second); - index++; - } - catch (megaglest_runtime_error & ex) - { - if (validationMode == false) - { - throw; - } - else - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\nFor UnitType: %s Cost: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, ex.what (), name.c_str (), - iterMap->second); - } - } - } - sortedItems.clear (); - hasDup = false; - - //resources stored - const XmlNode *resourcesStoredNode = - parametersNode->getChild ("resources-stored"); - storedResources.resize (resourcesStoredNode->getChildCount ()); - for (int i = 0; i < (int) storedResources.size (); ++i) - { - const XmlNode *resourceNode = - resourcesStoredNode->getChild ("resource", i); - string name = - resourceNode->getAttribute ("name")->getRestrictedValue (); - int amount = resourceNode->getAttribute ("amount")->getIntValue (); - - if (sortedItems.find (name) != sortedItems.end ()) - { - hasDup = true; - } - - sortedItems[name] = amount; - } - - if (hasDup) - { - printf - ("WARNING, unit type [%s] has one or more duplicate stored resources\n", - this->getName (false).c_str ()); - } - - if (sortedItems.size () < storedResources.size ()) - { - storedResources.resize (sortedItems.size ()); - } - - index = 0; - for (std::map < string, int >::iterator iterMap = - sortedItems.begin (); iterMap != sortedItems.end (); ++iterMap) - { - try - { - storedResources[index].init (techTree-> - getResourceType (iterMap->first), - iterMap->second); - index++; - } - catch (megaglest_runtime_error & ex) - { - if (validationMode == false) - { - throw; - } - else - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\nFor UnitType: %s Store: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, ex.what (), name.c_str (), - iterMap->second); - } - } - } - sortedItems.clear (); - //hasDup = false; - - // Lootable resources (resources given/lost on death) - if (parametersNode->hasChild ("resources-death")) - { - const XmlNode *deathResourcesNode = - parametersNode->getChild ("resources-death"); - - for (unsigned int i = 0; i < deathResourcesNode->getChildCount (); - ++i) - { - const XmlNode *resourceNode = - deathResourcesNode->getChild ("resource", i); - string name = - resourceNode->getAttribute ("name")->getRestrictedValue (); - - LootableResource resource; - resource.setResourceType (techTree->getResourceType (name)); - - // All attributes are optional, although nothing happens if they aren't used. They can - // be combined freely. Percentages will take affect before absolute values. - if (resourceNode->hasAttribute ("amount-value")) - { - resource.setAmountValue (resourceNode-> - getAttribute ("amount-value")-> - getIntValue ()); - } - else - { - resource.setAmountValue (0); - } - - if (resourceNode->hasAttribute ("amount-faction-percent")) - { - resource.setAmountFactionPercent (resourceNode-> - getAttribute - ("amount-faction-percent")-> - getIntValue ()); - } - else - { - resource.setAmountFactionPercent (0); - } - - if (resourceNode->hasAttribute ("loss-value")) - { - resource.setLossValue (resourceNode-> - getAttribute ("loss-value")-> - getIntValue ()); - } - else - { - resource.setLossValue (0); - } - - if (resourceNode->hasAttribute ("loss-faction-percent")) - { - resource.setLossFactionPercent (resourceNode-> - getAttribute - ("loss-faction-percent")-> - getIntValue ()); - } - else - { - resource.setLossFactionPercent (0); - } - - if (resourceNode->hasAttribute ("allow-negative")) - { - resource.setNegativeAllowed (resourceNode-> - getAttribute ("allow-negative")-> - getBoolValue ()); - } - else - { - resource.setNegativeAllowed (false); - } - - // Figure out if there are duplicate resources. The value stored in the map is arbitrary, - // and exists solely because - if (std:: - find (lootableResources.begin (), lootableResources.end (), - resource) != lootableResources.end ()) - { - printf - ("WARNING, unit type [%s] has one or more duplicate lootable resources\n", - this->getName (false).c_str ()); - } - - lootableResources.push_back (resource); - } - } - - // Tags - if (parametersNode->hasChild ("tags")) - { - const XmlNode *tagsNode = parametersNode->getChild ("tags"); - - for (unsigned int i = 0; i < tagsNode->getChildCount (); ++i) - { - const XmlNode *resourceNode = tagsNode->getChild ("tag", i); - string tag = - resourceNode->getAttribute ("value")->getRestrictedValue (); - tags.insert (tag); - } - } - - //image - const XmlNode *imageNode = parametersNode->getChild ("image"); - image = Renderer::getInstance ().newTexture2D (rsGame); - if (image) - { - image->load (imageNode->getAttribute ("path")-> - getRestrictedValue (currentPath)); - } - loadedFileList[imageNode->getAttribute ("path")-> - getRestrictedValue (currentPath)]. - push_back (make_pair - (sourceXMLFile, - imageNode->getAttribute ("path")-> - getRestrictedValue ())); - - //image cancel - const XmlNode *imageCancelNode = - parametersNode->getChild ("image-cancel"); - cancelImage = Renderer::getInstance ().newTexture2D (rsGame); - if (cancelImage) - { - cancelImage->load (imageCancelNode->getAttribute ("path")-> - getRestrictedValue (currentPath)); - } - loadedFileList[imageCancelNode->getAttribute ("path")-> - getRestrictedValue (currentPath)]. - push_back (make_pair - (sourceXMLFile, - imageCancelNode->getAttribute ("path")-> - getRestrictedValue ())); - - //meeting point - const XmlNode *meetingPointNode = - parametersNode->getChild ("meeting-point"); - meetingPoint = - meetingPointNode->getAttribute ("value")->getBoolValue (); - if (meetingPoint) - { - meetingPointImage = Renderer::getInstance ().newTexture2D (rsGame); - if (meetingPointImage) - { - meetingPointImage->load (meetingPointNode-> - getAttribute ("image-path")-> - getRestrictedValue (currentPath)); - } - loadedFileList[meetingPointNode->getAttribute ("image-path")-> - getRestrictedValue (currentPath)]. - push_back (make_pair - (sourceXMLFile, - meetingPointNode->getAttribute ("image-path")-> - getRestrictedValue ())); - } - - //countUnitDeathInStats - if (parametersNode->hasChild ("count-unit-death-in-stats")) - { - const XmlNode *countUnitDeathInStatsNode = - parametersNode->getChild ("count-unit-death-in-stats"); - countUnitDeathInStats = - countUnitDeathInStatsNode->getAttribute ("value")-> - getBoolValue (); - } - else - { - countUnitDeathInStats = true; - } - //countUnitProductionInStats - if (parametersNode->hasChild ("count-unit-production-in-stats")) - { - const XmlNode *countUnitProductionInStatsNode = - parametersNode->getChild ("count-unit-production-in-stats"); - countUnitProductionInStats = - countUnitProductionInStatsNode->getAttribute ("value")-> - getBoolValue (); - } - else - { - countUnitProductionInStats = true; - } - //countUnitKillInStats - if (parametersNode->hasChild ("count-unit-kill-in-stats")) - { - const XmlNode *countUnitKillInStatsNode = - parametersNode->getChild ("count-unit-kill-in-stats"); - countUnitKillInStats = - countUnitKillInStatsNode->getAttribute ("value")->getBoolValue (); - } - else - { - countUnitKillInStats = true; - } - - //countKillForUnitUpgrade - if (parametersNode->hasChild ("count-kill-for-unit-upgrade")) - { - const XmlNode *countKillForUnitUpgradeNode = - parametersNode->getChild ("count-kill-for-unit-upgrade"); - countKillForUnitUpgrade = - countKillForUnitUpgradeNode->getAttribute ("value")-> - getBoolValue (); - } - else - { - countKillForUnitUpgrade = true; - } - - if (countKillForUnitUpgrade == false) - { - // it makes no sense if we count it in stats but not for upgrades - countUnitKillInStats = false; - } - - //selection sounds - const XmlNode *selectionSoundNode = - parametersNode->getChild ("selection-sounds"); - if (selectionSoundNode->getAttribute ("enabled")->getBoolValue ()) - { - selectionSounds.resize ((int) selectionSoundNode->getChildCount ()); - for (int i = 0; i < (int) selectionSounds.getSounds ().size (); ++i) - { - const XmlNode *soundNode = - selectionSoundNode->getChild ("sound", i); - string path = - soundNode->getAttribute ("path")-> - getRestrictedValue (currentPath); - StaticSound *sound = new StaticSound (); - sound->load (path); - loadedFileList[path]. - push_back (make_pair - (sourceXMLFile, - soundNode->getAttribute ("path")-> - getRestrictedValue ())); - selectionSounds[i] = sound; - } - } - - //command sounds - const XmlNode *commandSoundNode = - parametersNode->getChild ("command-sounds"); - if (commandSoundNode->getAttribute ("enabled")->getBoolValue ()) - { - commandSounds.resize ((int) commandSoundNode->getChildCount ()); - for (int i = 0; i < (int) commandSoundNode->getChildCount (); ++i) - { - const XmlNode *soundNode = - commandSoundNode->getChild ("sound", i); - string path = - soundNode->getAttribute ("path")-> - getRestrictedValue (currentPath); - StaticSound *sound = new StaticSound (); - sound->load (path); - loadedFileList[path]. - push_back (make_pair - (sourceXMLFile, - soundNode->getAttribute ("path")-> - getRestrictedValue ())); - commandSounds[i] = sound; - } - } - - //skills - - const XmlNode *attackBoostsNode = NULL; - if (unitNode->hasChild ("attack-boosts") == true) - { - attackBoostsNode = unitNode->getChild ("attack-boosts"); - } - - const XmlNode *skillsNode = unitNode->getChild ("skills"); - skillTypes.resize (skillsNode->getChildCount ()); - - snprintf (szBuf, 8096, - Lang::getInstance (). - getString ("LogScreenGameLoadingUnitTypeSkills", "", - true).c_str (), - formatString (this->getName (true)).c_str (), - skillTypes.size ()); - Logger::getInstance ().add (szBuf, true); - - for (int i = 0; i < (int) skillTypes.size (); ++i) - { - const XmlNode *sn = skillsNode->getChild ("skill", i); - const XmlNode *typeNode = sn->getChild ("type"); - string classId = - typeNode->getAttribute ("value")->getRestrictedValue (); - SkillType *skillType = - SkillTypeFactory::getInstance ().newInstance (classId); - - skillTypes[i] = NULL; - try - { - skillType->load (sn, attackBoostsNode, dir, techTree, factionType, - loadedFileList, sourceXMLFile); - skillTypes[i] = skillType; - } - catch (megaglest_runtime_error & ex) - { - if (validationMode == false) - { - throw; - } - else - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\nFor UnitType: %s SkillType: %s\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, ex.what (), name.c_str (), - classId.c_str ()); - } - } - } - - //commands - const XmlNode *commandsNode = unitNode->getChild ("commands"); - commandTypes.resize (commandsNode->getChildCount ()); - for (int i = 0; i < (int) commandTypes.size (); ++i) - { - const XmlNode *commandNode = commandsNode->getChild ("command", i); - const XmlNode *typeNode = commandNode->getChild ("type"); - string classId = - typeNode->getAttribute ("value")->getRestrictedValue (); - CommandType *commandType = - CommandTypeFactory::getInstance ().newInstance (classId); - - commandTypes[i] = NULL; - try - { - commandType->load (i, commandNode, dir, techTree, factionType, - *this, loadedFileList, sourceXMLFile); - commandTypes[i] = commandType; - } - catch (megaglest_runtime_error & ex) - { - if (validationMode == false) - { - throw; - } - else - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\nFor UnitType: %s CommandType:%s\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, ex.what (), name.c_str (), - classId.c_str ()); - } - } - } - - computeFirstStOfClass (); - computeFirstCtOfClass (); - - if (getFirstStOfClass (scStop) == NULL) - { - throw - megaglest_runtime_error - ("Every unit must have at least one stop skill: " + path, true); - } - if (getFirstStOfClass (scDie) == NULL) - { - throw - megaglest_runtime_error - ("Every unit must have at least one die skill: " + path, true); - } - - } - //Exception handling (conversions and so on); - catch (megaglest_runtime_error & ex) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - ex.what ()); - throw megaglest_runtime_error ("Error loading UnitType: " + path + - "\nMessage: " + ex.what (), - !ex.wantStackTrace ()); - } - catch (const exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - e.what ()); - throw megaglest_runtime_error ("Error loading UnitType: " + path + - "\nMessage: " + e.what ()); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__); - } - -// ==================== get ==================== - - const Level *UnitType::getLevel (string name) const - { - const Level *result = NULL; - for (unsigned int i = 0; i < levels.size (); ++i) - { - const Level & level = levels[i]; - if (level.getName () == name) - { - result = &level; - break; - } - } - - return result; - } - - const CommandType *UnitType::getFirstCtOfClass (CommandClass commandClass) const - { - if (firstCommandTypeOfClass[commandClass] == NULL) - { - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] commandClass = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,commandClass); - - /* - for(int j=0; jgetClass()== CommandClass(j)){ - return commandTypes[i]; - } - } - } - */ - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - return firstCommandTypeOfClass[commandClass]; - } - - const SkillType *UnitType::getFirstStOfClass (SkillClass skillClass) const - { - if (firstSkillTypeOfClass[skillClass] == NULL) - { - /* - for(int j= 0; jgetClass()== SkillClass(j)){ - return skillTypes[i]; - } - } - } - */ - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - return firstSkillTypeOfClass[skillClass]; - } - - const HarvestCommandType *UnitType:: - getFirstHarvestCommand (const ResourceType * resourceType, - const Faction * faction) const - { - for (int i = 0; i < (int) commandTypes.size (); ++i) - { - if (commandTypes[i]->getClass () == ccHarvest) - { - const HarvestCommandType *hct = - static_cast < const HarvestCommandType * >(commandTypes[i]); - - if (faction->reqsOk (hct) == false) - { - continue; - } - - if (hct->canHarvest (resourceType)) - { - return hct; - } - } - } - return NULL; - } - - const HarvestEmergencyReturnCommandType *UnitType:: - getFirstHarvestEmergencyReturnCommand () const - { - const HarvestEmergencyReturnCommandType *result = - dynamic_cast < - const HarvestEmergencyReturnCommandType * - >(ctHarvestEmergencyReturnCommandType.get ()); - return result; - } - - const AttackCommandType *UnitType::getFirstAttackCommand (Field field) const - { - //printf("$$$ Unit [%s] commandTypes.size() = %d\n",this->getName().c_str(),(int)commandTypes.size()); - - for (int i = 0; i < (int) commandTypes.size (); ++i) - { - if (commandTypes[i] == NULL) - { - throw megaglest_runtime_error ("commandTypes[i] == NULL"); - } - - //printf("$$$ Unit [%s] i = %d, commandTypes[i] [%s]\n",this->getName().c_str(),(int)i, commandTypes[i]->toString().c_str()); - if (commandTypes[i]->getClass () == ccAttack) - { - const AttackCommandType *act = - dynamic_cast < const AttackCommandType * >(commandTypes[i]); - if (act != NULL - && act->getAttackSkillType ()->getAttackField (field)) - { - //printf("## Unit [%s] i = %d, is found\n",this->getName().c_str(),(int)i); - return act; - } - } - } - - return NULL; - } - - const AttackStoppedCommandType *UnitType:: - getFirstAttackStoppedCommand (Field field) const - { - //printf("$$$ Unit [%s] commandTypes.size() = %d\n",this->getName().c_str(),(int)commandTypes.size()); - - for (int i = 0; i < (int) commandTypes.size (); ++i) - { - if (commandTypes[i] == NULL) - { - throw megaglest_runtime_error ("commandTypes[i] == NULL"); - } - - //printf("$$$ Unit [%s] i = %d, commandTypes[i] [%s]\n",this->getName().c_str(),(int)i, commandTypes[i]->toString().c_str()); - if (commandTypes[i]->getClass () == ccAttackStopped) - { - const AttackStoppedCommandType *act = - dynamic_cast < - const AttackStoppedCommandType * >(commandTypes[i]); - if (act != NULL - && act->getAttackSkillType ()->getAttackField (field)) - { - //printf("## Unit [%s] i = %d, is found\n",this->getName().c_str(),(int)i); - return act; - } - } - } - - return NULL; - } - - const RepairCommandType *UnitType::getFirstRepairCommand (const UnitType * - repaired) const - { - for (int i = 0; i < (int) commandTypes.size (); ++i) - { - if (commandTypes[i]->getClass () == ccRepair) - { - const RepairCommandType *rct = - static_cast < const RepairCommandType * >(commandTypes[i]); - if (rct->isRepairableUnitType (repaired)) - { - return rct; - } - } - } - return NULL; - } - - bool UnitType::hasEmptyCellMap () const - { - //checkItemInVault(&(this->size),this->size); - bool result = (size > 0); - for (int i = 0; result == true && i < size; ++i) - { - for (int j = 0; j < size; ++j) - { - if (cellMap[i * size + j] == true) - { - result = false; - break; - } - } - } - - return result; - } - - Vec2i UnitType::getFirstOccupiedCellInCellMap (Vec2i currentPos) const - { - Vec2i cell = currentPos; - //printf("\n\n\n\n^^^^^^^^^^ currentPos [%s] size [%d]\n",currentPos.getString().c_str(),size); - - //checkItemInVault(&(this->size),this->size); - if (hasCellMap () == true) - { - for (int i = 0; i < size; ++i) - { - for (int j = 0; j < size; ++j) - { - if (cellMap[i * size + j] == true) - { - cell.x += i; - cell.y += j; - //printf("\n^^^^^^^^^^ cell [%s] i [%d] j [%d]\n",cell.getString().c_str(),i,j); - return cell; - } - } - } - } - return cell; - } - - bool UnitType::getCellMapCell (int x, int y, CardinalDir facing) const - { - assert (cellMap); - if (cellMap == NULL) - { - throw megaglest_runtime_error ("cellMap == NULL"); - } - - //checkItemInVault(&(this->size),this->size); - int tmp = 0; - switch (facing) - { - case CardinalDir::EAST: - tmp = y; - y = x; - x = size - tmp - 1; - break; - case CardinalDir::SOUTH: - x = size - x - 1; - y = size - y - 1; - break; - case CardinalDir::WEST: - tmp = x; - x = y; - y = size - tmp - 1; - break; - default: - break; - } - return cellMap[y * size + x]; - } - - int UnitType::getStore (const ResourceType * rt) const - { - for (int i = 0; i < (int) storedResources.size (); ++i) - { - if (storedResources[i].getType () == rt) - { - return storedResources[i].getAmount (); - } - } - return 0; - } - - const SkillType *UnitType::getSkillType (const string & skillName, - SkillClass skillClass) const - { - for (int i = 0; i < (int) skillTypes.size (); ++i) - { - if (skillTypes[i]->getName () == skillName) - { - if (skillTypes[i]->getClass () == skillClass) - { - return skillTypes[i]; - } - else - { - throw megaglest_runtime_error ("Skill \"" + skillName + - "\" is not of class \"" + - SkillType:: - skillClassToStr (skillClass)); - } - } - } - throw megaglest_runtime_error ("No skill named \"" + skillName + "\""); - } - -// ==================== totals ==================== - - int UnitType::getTotalMaxHp (const TotalUpgrade * totalUpgrade) const - { - checkItemInVault (&(this->maxHp), this->maxHp); - int result = maxHp + totalUpgrade->getMaxHp (); - result = max (0, result); - return result; - } - - int UnitType::getTotalMaxHpRegeneration (const TotalUpgrade * - totalUpgrade) const - { - checkItemInVault (&(this->hpRegeneration), this->hpRegeneration); - int result = hpRegeneration + totalUpgrade->getMaxHpRegeneration (); - //result = max(0,result); - return result; - } - - int UnitType::getTotalMaxEp (const TotalUpgrade * totalUpgrade) const - { - checkItemInVault (&(this->maxEp), this->maxEp); - int result = maxEp + totalUpgrade->getMaxEp (); - result = max (0, result); - return result; - } - - int UnitType::getTotalMaxEpRegeneration (const TotalUpgrade * - totalUpgrade) const - { - checkItemInVault (&(this->epRegeneration), this->epRegeneration); - int result = epRegeneration + totalUpgrade->getMaxEpRegeneration (); - //result = max(0,result); - return result; - } - - int UnitType::getTotalArmor (const TotalUpgrade * totalUpgrade) const - { - checkItemInVault (&(this->armor), this->armor); - int result = armor + totalUpgrade->getArmor (); - result = max (0, result); - return result; - } - - int UnitType::getTotalSight (const TotalUpgrade * totalUpgrade) const - { - checkItemInVault (&(this->sight), this->sight); - int result = sight + totalUpgrade->getSight (); - result = max (0, result); - return result; - } - -// ==================== has ==================== - - bool UnitType::hasSkillClass (SkillClass skillClass) const - { - return firstSkillTypeOfClass[skillClass] != NULL; - } - - bool UnitType::hasCommandType (const CommandType * commandType) const - { - assert (commandType != NULL); - - const HarvestEmergencyReturnCommandType *result = - dynamic_cast < - const HarvestEmergencyReturnCommandType * - >(ctHarvestEmergencyReturnCommandType.get ()); - if (commandType == result) - { - return true; - } - - for (int i = 0; i < (int) commandTypes.size (); ++i) - { - if (commandTypes[i] == commandType) - { - return true; - } - } - return false; - } - -//bool UnitType::hasSkillType(const SkillType *skillType) const { -// assert(skillType!=NULL); -// for(int i=0; i < (int)skillTypes.size(); ++i) { -// if(skillTypes[i]==skillType) { -// return true; -// } -// } -// return false; -//} - - bool UnitType::isOfClass (UnitClass uc) const - { - switch (uc) - { - case ucWarrior: - return hasSkillClass (scAttack) && !hasSkillClass (scHarvest); - case ucWorker:return hasSkillClass (scBuild) - || hasSkillClass (scRepair) || hasSkillClass (scHarvest); - case ucBuilding:return hasSkillClass (scBeBuilt); - default:assert (false); - break; - } - return false; - } - -// ==================== PRIVATE ==================== - - void UnitType::computeFirstStOfClass () - { - for (int j = 0; j < scCount; ++j) - { - firstSkillTypeOfClass[j] = NULL; - for (int i = 0; i < (int) skillTypes.size (); ++i) - { - if (skillTypes[i] != NULL - && skillTypes[i]->getClass () == SkillClass (j)) - { - firstSkillTypeOfClass[j] = skillTypes[i]; - break; - } - } - } - } - - void UnitType::computeFirstCtOfClass () - { - for (int j = 0; j < ccCount; ++j) - { - firstCommandTypeOfClass[j] = NULL; - for (int i = 0; i < (int) commandTypes.size (); ++i) - { - if (commandTypes[i] != NULL - && commandTypes[i]->getClass () == CommandClass (j)) - { - firstCommandTypeOfClass[j] = commandTypes[i]; - break; - } - } - } - } - - const CommandType *UnitType::findCommandTypeById (int id) const - { - const HarvestEmergencyReturnCommandType *result = - dynamic_cast < - const HarvestEmergencyReturnCommandType * - >(ctHarvestEmergencyReturnCommandType.get ()); - if (result != NULL && id == result->getId ()) - { - return result; - } - - for (int i = 0; i < getCommandTypeCount (); ++i) - { - const CommandType *commandType = getCommandType (i); - if (commandType->getId () == id) - { - return commandType; - } - } - return NULL; - } - - const CommandType *UnitType::getCommandType (int i) const - { - if (i >= (int) commandTypes.size ()) - { - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - "In [%s::%s Line: %d] i >= commandTypes.size(), i = %d, commandTypes.size() = " - MG_SIZE_T_SPECIFIER "", - extractFileFromDirectoryPath (__FILE__).c_str (), - __FUNCTION__, __LINE__, i, commandTypes.size ()); - throw megaglest_runtime_error (szBuf); - } - return commandTypes[i]; - } - - string UnitType::getCommandTypeListDesc () const - { - string desc = "Commands: "; - for (int i = 0; i < getCommandTypeCount (); ++i) - { - const CommandType *commandType = getCommandType (i); - desc += " id = " + intToStr (commandType->getId ()); - +" toString: " + commandType->toString (false); - } - return desc; - - } - - string UnitType::getReqDesc (bool translatedValue) const - { - Lang & lang = Lang::getInstance (); - //string desc = "Limits: "; - string resultTxt = ""; - - checkItemInVault (&(this->maxUnitCount), this->maxUnitCount); - if (getMaxUnitCount () > 0) - { - resultTxt += - "\n" + lang.getString ("MaxUnitCount") + " " + - intToStr (getMaxUnitCount ()); - } - if (resultTxt == "") - return ProducibleType::getReqDesc (translatedValue); - else - return ProducibleType::getReqDesc (translatedValue) + "\n" + - lang.getString ("Limits") + " " + resultTxt; - } - - string UnitType::getName (bool translatedValue) const - { - if (translatedValue == false) - return name; - - Lang & lang = Lang::getInstance (); - return lang.getTechTreeString ("UnitTypeName_" + name, name.c_str ()); - } - - std::string UnitType::toString () const - { - std::string result = "Unit Name: [" + name + "] id = " + intToStr (id); - result += " maxHp = " + intToStr (maxHp); - result += " hpRegeneration = " + intToStr (hpRegeneration); - result += " maxEp = " + intToStr (maxEp); - result += " startEpValue = " + intToStr (startEpValue); - result += " startEpPercentage = " + intToStr (startEpPercentage); - result += " epRegeneration = " + intToStr (epRegeneration); - result += " maxUnitCount = " + intToStr (getMaxUnitCount ()); - - - for (int i = 0; i < fieldCount; i++) - { - result += - " fields index = " + intToStr (i) + " value = " + - intToStr (fields[i]); - } - for (int i = 0; i < pCount; i++) - { - result += - " properties index = " + intToStr (i) + " value = " + - intToStr (properties[i]); - } - - result += " armor = " + intToStr (armor); - - if (armorType != NULL) - { - result += - " armorType Name: [" + armorType->getName (false) + " id = " + - intToStr (armorType->getId ()); - } - - result += " light = " + intToStr (light); - result += " lightColor = " + lightColor.getString (); - result += " multiSelect = " + intToStr (multiSelect); - result += " uniformSelect = " + intToStr (uniformSelect); - result += " commandable = " + intToStr (commandable); - result += " sight = " + intToStr (sight); - result += " size = " + intToStr (size); - result += " height = " + intToStr (height); - result += " rotatedBuildPos = " + floatToStr (rotatedBuildPos, 6); - result += " rotationAllowed = " + intToStr (rotationAllowed); - - if (cellMap != NULL) - { - result += " cellMap: [" + intToStr (size) + "]"; - for (int i = 0; i < size; ++i) - { - for (int j = 0; j < size; ++j) - { - result += - " i = " + intToStr (i) + " j = " + intToStr (j) + " value = " + - intToStr (cellMap[i * size + j]); - } - } - } - - result += " skillTypes: [" + intToStr (skillTypes.size ()) + "]"; - for (int i = 0; i < (int) skillTypes.size (); ++i) - { - result += - " i = " + intToStr (i) + " " + skillTypes[i]->toString (false); - } - - result += " commandTypes: [" + intToStr (commandTypes.size ()) + "]"; - for (int i = 0; i < (int) commandTypes.size (); ++i) - { - result += - " i = " + intToStr (i) + " " + commandTypes[i]->toString (false); - } - - result += - " storedResources: [" + intToStr (storedResources.size ()) + "]"; - for (int i = 0; i < (int) storedResources.size (); ++i) - { - result += - " i = " + intToStr (i) + " " + - storedResources[i].getDescription (false); - } - - result += " levels: [" + intToStr (levels.size ()) + "]"; - for (int i = 0; i < (int) levels.size (); ++i) - { - result += " i = " + intToStr (i) + " " + levels[i].getName (); - } - - result += " meetingPoint = " + intToStr (meetingPoint); - - result += - " countInVictoryConditions = " + intToStr (countInVictoryConditions); - - return result; - } - - } +namespace Glest { + namespace Game { + + auto_ptr < CommandType > + UnitType:: + ctHarvestEmergencyReturnCommandType(new + HarvestEmergencyReturnCommandType + ()); + // =============================== + // class Level + // =============================== + + void Level::init(string name, int kills) { + this->name = name; + this->kills = kills; + } + + string Level::getName(bool translatedValue) const { + if (translatedValue == false) + return name; + + Lang & lang = Lang::getInstance(); + return lang.getTechTreeString("LevelName_" + name, name.c_str()); + } + + void Level::saveGame(XmlNode * rootNode) const { + std::map < string, string > mapTagReplacements; + XmlNode *levelNode = rootNode->addChild("Level"); + + levelNode->addAttribute("name", name, mapTagReplacements); + levelNode->addAttribute("kills", intToStr(kills), mapTagReplacements); + } + + const Level *Level::loadGame(const XmlNode * rootNode, + const UnitType * ut) { + const Level *result = NULL; + if (rootNode->hasChild("Level") == true) { + const XmlNode *levelNode = rootNode->getChild("Level"); + + result = ut->getLevel(levelNode->getAttribute("name")->getValue()); + } + + return result; + } + + // ===================================================== + // class UnitType + // ===================================================== + + // ===================== PUBLIC ======================== + + const char *UnitType::propertyNames[] = { "burnable", "rotated_climb" }; + + // ==================== creation and loading ==================== + + UnitType::UnitType() :ProducibleType() { + + countInVictoryConditions = ucvcNotSet; + meetingPointImage = NULL; + lightColor = Vec3f(0.f); + light = false; + healthbarheight = -100.0f; + healthbarthickness = -1.0f; + healthbarVisible = hbvUndefined; + multiSelect = false; + uniformSelect = false; + commandable = true; + armorType = NULL; + rotatedBuildPos = 0; + + field = fLand; + id = 0; + meetingPoint = false; + rotationAllowed = false; + + countUnitDeathInStats = false; + countUnitProductionInStats = false; + countUnitKillInStats = false; + countKillForUnitUpgrade = false; + + + for (int i = 0; i < ccCount; ++i) { + firstCommandTypeOfClass[i] = NULL; + } + + for (int i = 0; i < scCount; ++i) { + firstSkillTypeOfClass[i] = NULL; + } + + for (int i = 0; i < pCount; ++i) { + properties[i] = false; + } + + for (int i = 0; i < fieldCount; ++i) { + fields[i] = false; + } + + cellMap = NULL; + allowEmptyCellMap = false; + hpRegeneration = 0; + epRegeneration = 0; + maxUnitCount = 0; + maxHp = 0; + startHpValue = 0; + startHpPercentage = 1.0; + startHpType = stValue; + maxEp = 0; + startEpValue = 0; + startEpPercentage = 0; + startEpType = stValue; + armor = 0; + sight = 0; + size = 0; + aiBuildSize = -1; + renderSize = 0; + height = 0; + burnHeight = 0; + targetHeight = 0; + + addItemToVault(&(this->maxHp), this->maxHp); + addItemToVault(&(this->hpRegeneration), this->hpRegeneration); + addItemToVault(&(this->maxEp), this->maxEp); + addItemToVault(&(this->epRegeneration), this->epRegeneration); + addItemToVault(&(this->maxUnitCount), this->maxUnitCount); + addItemToVault(&(this->armor), this->armor); + addItemToVault(&(this->sight), this->sight); + addItemToVault(&(this->size), this->size); + addItemToVault(&(this->height), this->height); + } + + UnitType::~UnitType() { + deleteValues(commandTypes.begin(), commandTypes.end()); + commandTypes.clear(); + deleteValues(skillTypes.begin(), skillTypes.end()); + skillTypes.clear(); + deleteValues(selectionSounds.getSounds().begin(), + selectionSounds.getSounds().end()); + selectionSounds.clearSounds(); + deleteValues(commandSounds.getSounds().begin(), + commandSounds.getSounds().end()); + commandSounds.clearSounds(); + delete[]cellMap; + cellMap = NULL; + //remove damageParticleSystemTypes + while (!damageParticleSystemTypes.empty()) { + delete damageParticleSystemTypes.back(); + damageParticleSystemTypes.pop_back(); + } + } + + void UnitType::preLoad(const string & dir) { + name = lastDir(dir); + } + + void UnitType::loaddd(int id, const string & dir, + const TechTree * techTree, + const string & techTreePath, + const FactionType * factionType, + Checksum * checksum, Checksum * techtreeChecksum, + std::map < string, vector < pair < string, + string > > >&loadedFileList, bool validationMode) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + + string currentPath = dir; + endPathWithSlash(currentPath); + string path = currentPath + name + ".xml"; + string sourceXMLFile = path; + + this->id = id; + + try { + //Lang &lang= Lang::getInstance(); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + Lang::getInstance(). + getString("LogScreenGameLoadingUnitType", "", + true).c_str(), + formatString(this->getName(true)).c_str()); + Logger::getInstance().add(szBuf, true); + + //file load + checksum->addFile(path); + techtreeChecksum->addFile(path); + + XmlTree xmlTree; + std::map < string, string > mapExtraTagReplacementValues; + mapExtraTagReplacementValues["$COMMONDATAPATH"] = + techTreePath + "/commondata/"; + xmlTree.load(path, + Properties:: + getTagReplacementValues + (&mapExtraTagReplacementValues)); + loadedFileList[path].push_back(make_pair(dir, dir)); + + const XmlNode *unitNode = xmlTree.getRootNode(); + + const XmlNode *parametersNode = unitNode->getChild("parameters"); + + if (parametersNode->hasChild("count-in-victory-conditions") == true) { + bool countUnit = + parametersNode->getChild("count-in-victory-conditions")-> + getAttribute("value")->getBoolValue(); + if (countUnit == true) { + countInVictoryConditions = ucvcTrue; + } else { + countInVictoryConditions = ucvcFalse; + } + } + + //size + //checkItemInVault(&(this->size),this->size); + size = + parametersNode->getChild("size")->getAttribute("value")-> + getIntValue(); + addItemToVault(&(this->size), this->size); + renderSize = size; + if (parametersNode->hasChild("render-size")) { + renderSize = + parametersNode->getChild("render-size")->getAttribute("value")-> + getIntValue(); + } + aiBuildSize = size; + if (parametersNode->hasChild("ai-build-size")) { + aiBuildSize = + parametersNode->getChild("ai-build-size")-> + getAttribute("value")->getIntValue(); + } + + //height + //checkItemInVault(&(this->height),this->height); + height = + parametersNode->getChild("height")->getAttribute("value")-> + getIntValue(); + addItemToVault(&(this->height), this->height); + + //targetHeight + if (parametersNode->hasChild("target-height")) { + targetHeight = + parametersNode->getChild("target-height")-> + getAttribute("value")->getIntValue(); + addItemToVault(&(this->targetHeight), this->targetHeight); + } else { + targetHeight = height; + } + //burnHeight + if (parametersNode->hasChild("target-height")) { + burnHeight = + parametersNode->getChild("burn-height")->getAttribute("value")-> + getIntValue(); + addItemToVault(&(this->burnHeight), this->burnHeight); + } else { + burnHeight = height; + } + + + //maxHp + //checkItemInVault(&(this->maxHp),this->maxHp); + maxHp = + parametersNode->getChild("max-hp")->getAttribute("value")-> + getIntValue(); + addItemToVault(&(this->maxHp), this->maxHp); + + //hpRegeneration + //checkItemInVault(&(this->hpRegeneration),this->hpRegeneration); + hpRegeneration = + parametersNode->getChild("max-hp")->getAttribute("regeneration")-> + getIntValue(); + addItemToVault(&(this->hpRegeneration), this->hpRegeneration); + + //maxEp + //checkItemInVault(&(this->maxEp),this->maxEp); + maxEp = + parametersNode->getChild("max-ep")->getAttribute("value")-> + getIntValue(); + addItemToVault(&(this->maxEp), this->maxEp); + + if (maxEp != 0) { + //epRegeneration + //checkItemInVault(&(this->epRegeneration),this->epRegeneration); + epRegeneration = + parametersNode->getChild("max-ep")-> + getAttribute("regeneration")->getIntValue(); + } + addItemToVault(&(this->epRegeneration), this->epRegeneration); + + // Check that we don't use both start-value and start-percentage, as they are mutually + // exclusive + if (parametersNode->getChild("max-hp")->hasAttribute("start-value") + && parametersNode->getChild("max-hp")-> + hasAttribute("start-percentage")) { + throw megaglest_runtime_error("Unit " + name + + " has both start-value and start-percentage for HP", + true); + } + + //startHpValue -- the *absolute* value to use for starting HP + if (parametersNode->getChild("max-hp")->hasAttribute("start-value")) { + //checkItemInVault(&(this->startEp),this->startEp); + startHpValue = + parametersNode->getChild("max-hp")-> + getAttribute("start-value")->getIntValue(); + startHpType = stValue; + } + addItemToVault(&(this->startHpValue), this->startHpValue); + + //startHpPercentage -- the *relative* value to use for starting HP + if (parametersNode->getChild("max-hp")-> + hasAttribute("start-percentage")) { + startHpPercentage = + parametersNode->getChild("max-hp")-> + getAttribute("start-percentage")->getIntValue(); + startHpType = stPercentage; + } + + // No start value set; use max HP before upgrades + if (!parametersNode->getChild("max-hp")->hasAttribute("start-value") + && !parametersNode->getChild("max-hp")-> + hasAttribute("start-percentage")) { + startHpValue = + parametersNode->getChild("max-hp")->getAttribute("value")-> + getIntValue(); + startHpType = stValue; + } + addItemToVault(&(this->startHpPercentage), this->startHpPercentage); + + // Check that we don't use both start-value and start-percentage, as they are mutually + // exclusive + if (parametersNode->getChild("max-ep")->hasAttribute("start-value") + && parametersNode->getChild("max-ep")-> + hasAttribute("start-percentage")) { + throw megaglest_runtime_error("Unit " + name + + " has both start-value and start-percentage for EP", + true); + } + + //startEpValue -- the *absolute* value to use for starting EP + if (parametersNode->getChild("max-ep")->hasAttribute("start-value")) { + //checkItemInVault(&(this->startEp),this->startEp); + startEpValue = + parametersNode->getChild("max-ep")-> + getAttribute("start-value")->getIntValue(); + startEpType = stValue; + } + addItemToVault(&(this->startEpValue), this->startEpValue); + + //startEpPercentage -- the *relative* value to use for starting EP + if (parametersNode->getChild("max-ep")-> + hasAttribute("start-percentage")) { + startEpPercentage = + parametersNode->getChild("max-ep")-> + getAttribute("start-percentage")->getIntValue(); + startEpType = stPercentage; + } + addItemToVault(&(this->startEpPercentage), this->startEpPercentage); + + //maxUnitCount + if (parametersNode->hasChild("max-unit-count")) { + //checkItemInVault(&(this->maxUnitCount),this->maxUnitCount); + maxUnitCount = + parametersNode->getChild("max-unit-count")-> + getAttribute("value")->getIntValue(); + } + addItemToVault(&(this->maxUnitCount), this->maxUnitCount); + + //armor + //checkItemInVault(&(this->armor),this->armor); + armor = + parametersNode->getChild("armor")->getAttribute("value")-> + getIntValue(); + addItemToVault(&(this->armor), this->armor); + + //armor type string + string armorTypeName = + parametersNode->getChild("armor-type")->getAttribute("value")-> + getRestrictedValue(); + armorType = techTree->getArmorType(armorTypeName); + + //sight + //checkItemInVault(&(this->sight),this->sight); + sight = + parametersNode->getChild("sight")->getAttribute("value")-> + getIntValue(); + addItemToVault(&(this->sight), this->sight); + + //prod time + productionTime = + parametersNode->getChild("time")->getAttribute("value")-> + getIntValue(); + + //multi selection + multiSelect = + parametersNode->getChild("multi-selection")-> + getAttribute("value")->getBoolValue(); + + //uniform selection + if (parametersNode->hasChild("uniform-selection")) { + uniformSelect = + parametersNode->getChild("uniform-selection")-> + getAttribute("value")->getBoolValue(); + } + + //commandable + if (parametersNode->hasChild("commandable")) { + commandable = + parametersNode->getChild("commandable")->getAttribute("value")-> + getBoolValue(); + } + //cellmap + allowEmptyCellMap = false; + const XmlNode *cellMapNode = parametersNode->getChild("cellmap"); + bool hasCellMap = + cellMapNode->getAttribute("value")->getBoolValue(); + if (hasCellMap == true) { + if (cellMapNode->getAttribute("allowEmpty", false) != NULL) { + allowEmptyCellMap = + cellMapNode->getAttribute("allowEmpty")->getBoolValue(); + } + + cellMap = new bool[size * size]; + for (int i = 0; i < size; ++i) { + const XmlNode *rowNode = cellMapNode->getChild("row", i); + string row = + rowNode->getAttribute("value")->getRestrictedValue(); + if ((int) row.size() != size) { + throw + megaglest_runtime_error + ("Cellmap row has not the same length as unit size", true); + } + for (int j = 0; j < (int) row.size(); ++j) { + cellMap[i * size + j] = row[j] == '0' ? false : true; + } + } + } + + //levels + const XmlNode *levelsNode = parametersNode->getChild("levels"); + levels.resize(levelsNode->getChildCount()); + for (int i = 0; i < (int) levels.size(); ++i) { + const XmlNode *levelNode = levelsNode->getChild("level", i); + + levels[i].init(levelNode->getAttribute("name")-> + getRestrictedValue(), + levelNode->getAttribute("kills")->getIntValue()); + } + + //fields + const XmlNode *fieldsNode = parametersNode->getChild("fields"); + for (int i = 0; i < (int) fieldsNode->getChildCount(); ++i) { + const XmlNode *fieldNode = fieldsNode->getChild("field", i); + string fieldName = + fieldNode->getAttribute("value")->getRestrictedValue(); + if (fieldName == "land") { + fields[fLand] = true; + } else if (fieldName == "air") { + fields[fAir] = true; + } else { + throw megaglest_runtime_error("Not a valid field: " + fieldName + + ": " + path, true); + } + } + + if (fields[fLand]) { + field = fLand; + } else if (fields[fAir]) { + field = fAir; + } else { + throw megaglest_runtime_error("Unit has no field: " + path, true); + } + + //properties + const XmlNode *propertiesNode = + parametersNode->getChild("properties"); + for (int i = 0; i < (int) propertiesNode->getChildCount(); ++i) { + const XmlNode *propertyNode = + propertiesNode->getChild("property", i); + string propertyName = + propertyNode->getAttribute("value")->getRestrictedValue(); + bool found = false; + for (int i = 0; i < pCount; ++i) { + if (propertyName == propertyNames[i]) { + properties[i] = true; + found = true; + break; + } + } + if (!found) { + throw megaglest_runtime_error("Unknown property: " + + propertyName, true); + } + } + //damage-particles + if (parametersNode->hasChild("damage-particles")) { + const XmlNode *particleNode = + parametersNode->getChild("damage-particles"); + bool particleEnabled = + particleNode->getAttribute("value")->getBoolValue(); + + if (particleEnabled) { + for (int i = 0; i < (int) particleNode->getChildCount(); ++i) { + const XmlNode *particleFileNode = + particleNode->getChild("particle-file", i); + string path = + particleFileNode->getAttribute("path")-> + getRestrictedValue(); + UnitParticleSystemType *unitParticleSystemType = + new UnitParticleSystemType(); + + unitParticleSystemType->load(particleFileNode, dir, + currentPath + path, + &Renderer::getInstance(), + loadedFileList, sourceXMLFile, + techTree->getPath()); + loadedFileList[currentPath + + path].push_back(make_pair(sourceXMLFile, + particleFileNode-> + getAttribute + ("path")-> + getRestrictedValue + ())); + + if (particleFileNode->getAttribute("minHp", false) != NULL + && particleFileNode->getAttribute("maxHp", false) != NULL) { + unitParticleSystemType->setMinmaxEnabled(true); + unitParticleSystemType->setMinHp(particleFileNode-> + getAttribute("minHp")-> + getIntValue()); + unitParticleSystemType->setMaxHp(particleFileNode-> + getAttribute("maxHp")-> + getIntValue()); + + if (particleFileNode-> + getAttribute("ispercentbased", false) != NULL) { + unitParticleSystemType-> + setMinmaxIsPercent(particleFileNode-> + getAttribute("ispercentbased")-> + getBoolValue()); + } + + } + + damageParticleSystemTypes.push_back(unitParticleSystemType); + } + } + } + + //healthbar + if (parametersNode->hasChild("healthbar")) { + const XmlNode *healthbarNode = + parametersNode->getChild("healthbar"); + if (healthbarNode->hasChild("height")) { + healthbarheight = + healthbarNode->getChild("height")->getAttribute("value")-> + getFloatValue(); + } + if (healthbarNode->hasChild("thickness")) { + healthbarthickness = + healthbarNode->getChild("thickness")->getAttribute("value")-> + getFloatValue(0.f, 1.f); + } + if (healthbarNode->hasChild("visible")) { + string healthbarVisibleString = + healthbarNode->getChild("visible")->getAttribute("value")-> + getValue(); + vector < string > v = split(healthbarVisibleString, "|"); + for (int i = 0; i < (int) v.size(); ++i) { + string current = trim(v[i]); + if (current == "always") { + healthbarVisible = healthbarVisible | hbvAlways; + } else if (current == "selected") { + healthbarVisible = healthbarVisible | hbvSelected; + } else if (current == "ifNeeded") { + healthbarVisible = healthbarVisible | hbvIfNeeded; + } else if (current == "off") { + healthbarVisible = healthbarVisible | hbvOff; + } else { + throw + megaglest_runtime_error + ("Unknown Healthbar Visible Option: " + current, true); + } + } + } + } + + //light + const XmlNode *lightNode = parametersNode->getChild("light"); + light = lightNode->getAttribute("enabled")->getBoolValue(); + if (light) { + lightColor.x = + lightNode->getAttribute("red")->getFloatValue(0.f, 1.f); + lightColor.y = + lightNode->getAttribute("green")->getFloatValue(0.f, 1.f); + lightColor.z = + lightNode->getAttribute("blue")->getFloatValue(0.f, 1.f); + } + + //rotationAllowed + if (parametersNode->hasChild("rotationAllowed")) { + const XmlNode *rotationAllowedNode = + parametersNode->getChild("rotationAllowed"); + rotationAllowed = + rotationAllowedNode->getAttribute("value")->getBoolValue(); + } else { + rotationAllowed = true; + } + + std::map < string, int >sortedItems; + + //unit requirements + bool hasDup = false; + const XmlNode *unitRequirementsNode = + parametersNode->getChild("unit-requirements"); + for (int i = 0; i < (int) unitRequirementsNode->getChildCount(); ++i) { + const XmlNode *unitNode = + unitRequirementsNode->getChild("unit", i); + string name = + unitNode->getAttribute("name")->getRestrictedValue(); + + if (sortedItems.find(name) != sortedItems.end()) { + hasDup = true; + } + + sortedItems[name] = 0; + } + if (hasDup) { + printf + ("WARNING, unit type [%s] has one or more duplicate unit requirements\n", + this->getName(false).c_str()); + } + + for (std::map < string, int >::iterator iterMap = + sortedItems.begin(); iterMap != sortedItems.end(); ++iterMap) { + unitReqs.push_back(factionType->getUnitType(iterMap->first)); + } + sortedItems.clear(); + hasDup = false; + + //upgrade requirements + const XmlNode *upgradeRequirementsNode = + parametersNode->getChild("upgrade-requirements"); + for (int i = 0; i < (int) upgradeRequirementsNode->getChildCount(); + ++i) { + const XmlNode *upgradeReqNode = + upgradeRequirementsNode->getChild("upgrade", i); + string name = + upgradeReqNode->getAttribute("name")->getRestrictedValue(); + + if (sortedItems.find(name) != sortedItems.end()) { + hasDup = true; + } + + sortedItems[name] = 0; + } + + if (hasDup) { + printf + ("WARNING, unit type [%s] has one or more duplicate upgrade requirements\n", + this->getName(false).c_str()); + } + + for (std::map < string, int >::iterator iterMap = + sortedItems.begin(); iterMap != sortedItems.end(); ++iterMap) { + upgradeReqs.push_back(factionType-> + getUpgradeType(iterMap->first)); + } + sortedItems.clear(); + hasDup = false; + + //resource requirements + const XmlNode *resourceRequirementsNode = + parametersNode->getChild("resource-requirements"); + costs.resize(resourceRequirementsNode->getChildCount()); + for (int i = 0; i < (int) costs.size(); ++i) { + const XmlNode *resourceNode = + resourceRequirementsNode->getChild("resource", i); + string name = + resourceNode->getAttribute("name")->getRestrictedValue(); + int amount = resourceNode->getAttribute("amount")->getIntValue(); + + if (sortedItems.find(name) != sortedItems.end()) { + hasDup = true; + } + sortedItems[name] = amount; + } + //if(hasDup || sortedItems.size() != costs.size()) printf("Found duplicate resource requirement, costs.size() = %d sortedItems.size() = %d\n",costs.size(),sortedItems.size()); + + if (hasDup) { + printf + ("WARNING, unit type [%s] has one or more duplicate resource requirements\n", + this->getName(false).c_str()); + } + + if (sortedItems.size() < costs.size()) { + costs.resize(sortedItems.size()); + } + int index = 0; + for (std::map < string, int >::iterator iterMap = + sortedItems.begin(); iterMap != sortedItems.end(); ++iterMap) { + try { + costs[index].init(techTree->getResourceType(iterMap->first), + iterMap->second); + index++; + } catch (megaglest_runtime_error & ex) { + if (validationMode == false) { + throw; + } else { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\nFor UnitType: %s Cost: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, ex.what(), name.c_str(), + iterMap->second); + } + } + } + sortedItems.clear(); + hasDup = false; + + //resources stored + const XmlNode *resourcesStoredNode = + parametersNode->getChild("resources-stored"); + storedResources.resize(resourcesStoredNode->getChildCount()); + for (int i = 0; i < (int) storedResources.size(); ++i) { + const XmlNode *resourceNode = + resourcesStoredNode->getChild("resource", i); + string name = + resourceNode->getAttribute("name")->getRestrictedValue(); + int amount = resourceNode->getAttribute("amount")->getIntValue(); + + if (sortedItems.find(name) != sortedItems.end()) { + hasDup = true; + } + + sortedItems[name] = amount; + } + + if (hasDup) { + printf + ("WARNING, unit type [%s] has one or more duplicate stored resources\n", + this->getName(false).c_str()); + } + + if (sortedItems.size() < storedResources.size()) { + storedResources.resize(sortedItems.size()); + } + + index = 0; + for (std::map < string, int >::iterator iterMap = + sortedItems.begin(); iterMap != sortedItems.end(); ++iterMap) { + try { + storedResources[index].init(techTree-> + getResourceType(iterMap->first), + iterMap->second); + index++; + } catch (megaglest_runtime_error & ex) { + if (validationMode == false) { + throw; + } else { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\nFor UnitType: %s Store: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, ex.what(), name.c_str(), + iterMap->second); + } + } + } + sortedItems.clear(); + //hasDup = false; + + // Lootable resources (resources given/lost on death) + if (parametersNode->hasChild("resources-death")) { + const XmlNode *deathResourcesNode = + parametersNode->getChild("resources-death"); + + for (unsigned int i = 0; i < deathResourcesNode->getChildCount(); + ++i) { + const XmlNode *resourceNode = + deathResourcesNode->getChild("resource", i); + string name = + resourceNode->getAttribute("name")->getRestrictedValue(); + + LootableResource resource; + resource.setResourceType(techTree->getResourceType(name)); + + // All attributes are optional, although nothing happens if they aren't used. They can + // be combined freely. Percentages will take affect before absolute values. + if (resourceNode->hasAttribute("amount-value")) { + resource.setAmountValue(resourceNode-> + getAttribute("amount-value")-> + getIntValue()); + } else { + resource.setAmountValue(0); + } + + if (resourceNode->hasAttribute("amount-faction-percent")) { + resource.setAmountFactionPercent(resourceNode-> + getAttribute + ("amount-faction-percent")-> + getIntValue()); + } else { + resource.setAmountFactionPercent(0); + } + + if (resourceNode->hasAttribute("loss-value")) { + resource.setLossValue(resourceNode-> + getAttribute("loss-value")-> + getIntValue()); + } else { + resource.setLossValue(0); + } + + if (resourceNode->hasAttribute("loss-faction-percent")) { + resource.setLossFactionPercent(resourceNode-> + getAttribute + ("loss-faction-percent")-> + getIntValue()); + } else { + resource.setLossFactionPercent(0); + } + + if (resourceNode->hasAttribute("allow-negative")) { + resource.setNegativeAllowed(resourceNode-> + getAttribute("allow-negative")-> + getBoolValue()); + } else { + resource.setNegativeAllowed(false); + } + + // Figure out if there are duplicate resources. The value stored in the map is arbitrary, + // and exists solely because + if (std:: + find(lootableResources.begin(), lootableResources.end(), + resource) != lootableResources.end()) { + printf + ("WARNING, unit type [%s] has one or more duplicate lootable resources\n", + this->getName(false).c_str()); + } + + lootableResources.push_back(resource); + } + } + + // Tags + if (parametersNode->hasChild("tags")) { + const XmlNode *tagsNode = parametersNode->getChild("tags"); + + for (unsigned int i = 0; i < tagsNode->getChildCount(); ++i) { + const XmlNode *resourceNode = tagsNode->getChild("tag", i); + string tag = + resourceNode->getAttribute("value")->getRestrictedValue(); + tags.insert(tag); + } + } + + //image + const XmlNode *imageNode = parametersNode->getChild("image"); + image = Renderer::getInstance().newTexture2D(rsGame); + if (image) { + image->load(imageNode->getAttribute("path")-> + getRestrictedValue(currentPath)); + } + loadedFileList[imageNode->getAttribute("path")-> + getRestrictedValue(currentPath)]. + push_back(make_pair + (sourceXMLFile, + imageNode->getAttribute("path")-> + getRestrictedValue())); + + //image cancel + const XmlNode *imageCancelNode = + parametersNode->getChild("image-cancel"); + cancelImage = Renderer::getInstance().newTexture2D(rsGame); + if (cancelImage) { + cancelImage->load(imageCancelNode->getAttribute("path")-> + getRestrictedValue(currentPath)); + } + loadedFileList[imageCancelNode->getAttribute("path")-> + getRestrictedValue(currentPath)]. + push_back(make_pair + (sourceXMLFile, + imageCancelNode->getAttribute("path")-> + getRestrictedValue())); + + //meeting point + const XmlNode *meetingPointNode = + parametersNode->getChild("meeting-point"); + meetingPoint = + meetingPointNode->getAttribute("value")->getBoolValue(); + if (meetingPoint) { + meetingPointImage = Renderer::getInstance().newTexture2D(rsGame); + if (meetingPointImage) { + meetingPointImage->load(meetingPointNode-> + getAttribute("image-path")-> + getRestrictedValue(currentPath)); + } + loadedFileList[meetingPointNode->getAttribute("image-path")-> + getRestrictedValue(currentPath)]. + push_back(make_pair + (sourceXMLFile, + meetingPointNode->getAttribute("image-path")-> + getRestrictedValue())); + } + + //countUnitDeathInStats + if (parametersNode->hasChild("count-unit-death-in-stats")) { + const XmlNode *countUnitDeathInStatsNode = + parametersNode->getChild("count-unit-death-in-stats"); + countUnitDeathInStats = + countUnitDeathInStatsNode->getAttribute("value")-> + getBoolValue(); + } else { + countUnitDeathInStats = true; + } + //countUnitProductionInStats + if (parametersNode->hasChild("count-unit-production-in-stats")) { + const XmlNode *countUnitProductionInStatsNode = + parametersNode->getChild("count-unit-production-in-stats"); + countUnitProductionInStats = + countUnitProductionInStatsNode->getAttribute("value")-> + getBoolValue(); + } else { + countUnitProductionInStats = true; + } + //countUnitKillInStats + if (parametersNode->hasChild("count-unit-kill-in-stats")) { + const XmlNode *countUnitKillInStatsNode = + parametersNode->getChild("count-unit-kill-in-stats"); + countUnitKillInStats = + countUnitKillInStatsNode->getAttribute("value")->getBoolValue(); + } else { + countUnitKillInStats = true; + } + + //countKillForUnitUpgrade + if (parametersNode->hasChild("count-kill-for-unit-upgrade")) { + const XmlNode *countKillForUnitUpgradeNode = + parametersNode->getChild("count-kill-for-unit-upgrade"); + countKillForUnitUpgrade = + countKillForUnitUpgradeNode->getAttribute("value")-> + getBoolValue(); + } else { + countKillForUnitUpgrade = true; + } + + if (countKillForUnitUpgrade == false) { + // it makes no sense if we count it in stats but not for upgrades + countUnitKillInStats = false; + } + + //selection sounds + const XmlNode *selectionSoundNode = + parametersNode->getChild("selection-sounds"); + if (selectionSoundNode->getAttribute("enabled")->getBoolValue()) { + selectionSounds.resize((int) selectionSoundNode->getChildCount()); + for (int i = 0; i < (int) selectionSounds.getSounds().size(); ++i) { + const XmlNode *soundNode = + selectionSoundNode->getChild("sound", i); + string path = + soundNode->getAttribute("path")-> + getRestrictedValue(currentPath); + StaticSound *sound = new StaticSound(); + sound->load(path); + loadedFileList[path]. + push_back(make_pair + (sourceXMLFile, + soundNode->getAttribute("path")-> + getRestrictedValue())); + selectionSounds[i] = sound; + } + } + + //command sounds + const XmlNode *commandSoundNode = + parametersNode->getChild("command-sounds"); + if (commandSoundNode->getAttribute("enabled")->getBoolValue()) { + commandSounds.resize((int) commandSoundNode->getChildCount()); + for (int i = 0; i < (int) commandSoundNode->getChildCount(); ++i) { + const XmlNode *soundNode = + commandSoundNode->getChild("sound", i); + string path = + soundNode->getAttribute("path")-> + getRestrictedValue(currentPath); + StaticSound *sound = new StaticSound(); + sound->load(path); + loadedFileList[path]. + push_back(make_pair + (sourceXMLFile, + soundNode->getAttribute("path")-> + getRestrictedValue())); + commandSounds[i] = sound; + } + } + + //skills + + const XmlNode *attackBoostsNode = NULL; + if (unitNode->hasChild("attack-boosts") == true) { + attackBoostsNode = unitNode->getChild("attack-boosts"); + } + + const XmlNode *skillsNode = unitNode->getChild("skills"); + skillTypes.resize(skillsNode->getChildCount()); + + snprintf(szBuf, 8096, + Lang::getInstance(). + getString("LogScreenGameLoadingUnitTypeSkills", "", + true).c_str(), + formatString(this->getName(true)).c_str(), + skillTypes.size()); + Logger::getInstance().add(szBuf, true); + + for (int i = 0; i < (int) skillTypes.size(); ++i) { + const XmlNode *sn = skillsNode->getChild("skill", i); + const XmlNode *typeNode = sn->getChild("type"); + string classId = + typeNode->getAttribute("value")->getRestrictedValue(); + SkillType *skillType = + SkillTypeFactory::getInstance().newInstance(classId); + + skillTypes[i] = NULL; + try { + skillType->load(sn, attackBoostsNode, dir, techTree, factionType, + loadedFileList, sourceXMLFile); + skillTypes[i] = skillType; + } catch (megaglest_runtime_error & ex) { + if (validationMode == false) { + throw; + } else { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\nFor UnitType: %s SkillType: %s\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, ex.what(), name.c_str(), + classId.c_str()); + } + } + } + + //commands + const XmlNode *commandsNode = unitNode->getChild("commands"); + commandTypes.resize(commandsNode->getChildCount()); + for (int i = 0; i < (int) commandTypes.size(); ++i) { + const XmlNode *commandNode = commandsNode->getChild("command", i); + const XmlNode *typeNode = commandNode->getChild("type"); + string classId = + typeNode->getAttribute("value")->getRestrictedValue(); + CommandType *commandType = + CommandTypeFactory::getInstance().newInstance(classId); + + commandTypes[i] = NULL; + try { + commandType->load(i, commandNode, dir, techTree, factionType, + *this, loadedFileList, sourceXMLFile); + commandTypes[i] = commandType; + } catch (megaglest_runtime_error & ex) { + if (validationMode == false) { + throw; + } else { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\nFor UnitType: %s CommandType:%s\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, ex.what(), name.c_str(), + classId.c_str()); + } + } + } + + computeFirstStOfClass(); + computeFirstCtOfClass(); + + if (getFirstStOfClass(scStop) == NULL) { + throw + megaglest_runtime_error + ("Every unit must have at least one stop skill: " + path, true); + } + if (getFirstStOfClass(scDie) == NULL) { + throw + megaglest_runtime_error + ("Every unit must have at least one die skill: " + path, true); + } + + } + //Exception handling (conversions and so on); + catch (megaglest_runtime_error & ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + ex.what()); + throw megaglest_runtime_error("Error loading UnitType: " + path + + "\nMessage: " + ex.what(), + !ex.wantStackTrace()); + } catch (const exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + e.what()); + throw megaglest_runtime_error("Error loading UnitType: " + path + + "\nMessage: " + e.what()); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__); + } + + // ==================== get ==================== + + const Level *UnitType::getLevel(string name) const { + const Level *result = NULL; + for (unsigned int i = 0; i < levels.size(); ++i) { + const Level & level = levels[i]; + if (level.getName() == name) { + result = &level; + break; + } + } + + return result; + } + + const CommandType *UnitType::getFirstCtOfClass(CommandClass commandClass) const { + if (firstCommandTypeOfClass[commandClass] == NULL) { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] commandClass = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,commandClass); + + /* + for(int j=0; jgetClass()== CommandClass(j)){ + return commandTypes[i]; + } + } + } + */ + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + } + return firstCommandTypeOfClass[commandClass]; + } + + const SkillType *UnitType::getFirstStOfClass(SkillClass skillClass) const { + if (firstSkillTypeOfClass[skillClass] == NULL) { + /* + for(int j= 0; jgetClass()== SkillClass(j)){ + return skillTypes[i]; + } + } + } + */ + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + } + return firstSkillTypeOfClass[skillClass]; + } + + const HarvestCommandType *UnitType:: + getFirstHarvestCommand(const ResourceType * resourceType, + const Faction * faction) const { + for (int i = 0; i < (int) commandTypes.size(); ++i) { + if (commandTypes[i]->getClass() == ccHarvest) { + const HarvestCommandType *hct = + static_cast (commandTypes[i]); + + if (faction->reqsOk(hct) == false) { + continue; + } + + if (hct->canHarvest(resourceType)) { + return hct; + } + } + } + return NULL; + } + + const HarvestEmergencyReturnCommandType *UnitType:: + getFirstHarvestEmergencyReturnCommand() const { + const HarvestEmergencyReturnCommandType *result = + dynamic_cast < + const HarvestEmergencyReturnCommandType * + >(ctHarvestEmergencyReturnCommandType.get()); + return result; + } + + const AttackCommandType *UnitType::getFirstAttackCommand(Field field) const { + //printf("$$$ Unit [%s] commandTypes.size() = %d\n",this->getName().c_str(),(int)commandTypes.size()); + + for (int i = 0; i < (int) commandTypes.size(); ++i) { + if (commandTypes[i] == NULL) { + throw megaglest_runtime_error("commandTypes[i] == NULL"); + } + + //printf("$$$ Unit [%s] i = %d, commandTypes[i] [%s]\n",this->getName().c_str(),(int)i, commandTypes[i]->toString().c_str()); + if (commandTypes[i]->getClass() == ccAttack) { + const AttackCommandType *act = + dynamic_cast (commandTypes[i]); + if (act != NULL + && act->getAttackSkillType()->getAttackField(field)) { + //printf("## Unit [%s] i = %d, is found\n",this->getName().c_str(),(int)i); + return act; + } + } + } + + return NULL; + } + + const AttackStoppedCommandType *UnitType:: + getFirstAttackStoppedCommand(Field field) const { + //printf("$$$ Unit [%s] commandTypes.size() = %d\n",this->getName().c_str(),(int)commandTypes.size()); + + for (int i = 0; i < (int) commandTypes.size(); ++i) { + if (commandTypes[i] == NULL) { + throw megaglest_runtime_error("commandTypes[i] == NULL"); + } + + //printf("$$$ Unit [%s] i = %d, commandTypes[i] [%s]\n",this->getName().c_str(),(int)i, commandTypes[i]->toString().c_str()); + if (commandTypes[i]->getClass() == ccAttackStopped) { + const AttackStoppedCommandType *act = + dynamic_cast < + const AttackStoppedCommandType *>(commandTypes[i]); + if (act != NULL + && act->getAttackSkillType()->getAttackField(field)) { + //printf("## Unit [%s] i = %d, is found\n",this->getName().c_str(),(int)i); + return act; + } + } + } + + return NULL; + } + + const RepairCommandType *UnitType::getFirstRepairCommand(const UnitType * + repaired) const { + for (int i = 0; i < (int) commandTypes.size(); ++i) { + if (commandTypes[i]->getClass() == ccRepair) { + const RepairCommandType *rct = + static_cast (commandTypes[i]); + if (rct->isRepairableUnitType(repaired)) { + return rct; + } + } + } + return NULL; + } + + bool UnitType::hasEmptyCellMap() const { + //checkItemInVault(&(this->size),this->size); + bool result = (size > 0); + for (int i = 0; result == true && i < size; ++i) { + for (int j = 0; j < size; ++j) { + if (cellMap[i * size + j] == true) { + result = false; + break; + } + } + } + + return result; + } + + Vec2i UnitType::getFirstOccupiedCellInCellMap(Vec2i currentPos) const { + Vec2i cell = currentPos; + //printf("\n\n\n\n^^^^^^^^^^ currentPos [%s] size [%d]\n",currentPos.getString().c_str(),size); + + //checkItemInVault(&(this->size),this->size); + if (hasCellMap() == true) { + for (int i = 0; i < size; ++i) { + for (int j = 0; j < size; ++j) { + if (cellMap[i * size + j] == true) { + cell.x += i; + cell.y += j; + //printf("\n^^^^^^^^^^ cell [%s] i [%d] j [%d]\n",cell.getString().c_str(),i,j); + return cell; + } + } + } + } + return cell; + } + + bool UnitType::getCellMapCell(int x, int y, CardinalDir facing) const { + assert(cellMap); + if (cellMap == NULL) { + throw megaglest_runtime_error("cellMap == NULL"); + } + + //checkItemInVault(&(this->size),this->size); + int tmp = 0; + switch (facing) { + case CardinalDir::EAST: + tmp = y; + y = x; + x = size - tmp - 1; + break; + case CardinalDir::SOUTH: + x = size - x - 1; + y = size - y - 1; + break; + case CardinalDir::WEST: + tmp = x; + x = y; + y = size - tmp - 1; + break; + default: + break; + } + return cellMap[y * size + x]; + } + + int UnitType::getStore(const ResourceType * rt) const { + for (int i = 0; i < (int) storedResources.size(); ++i) { + if (storedResources[i].getType() == rt) { + return storedResources[i].getAmount(); + } + } + return 0; + } + + const SkillType *UnitType::getSkillType(const string & skillName, + SkillClass skillClass) const { + for (int i = 0; i < (int) skillTypes.size(); ++i) { + if (skillTypes[i]->getName() == skillName) { + if (skillTypes[i]->getClass() == skillClass) { + return skillTypes[i]; + } else { + throw megaglest_runtime_error("Skill \"" + skillName + + "\" is not of class \"" + + SkillType:: + skillClassToStr(skillClass)); + } + } + } + throw megaglest_runtime_error("No skill named \"" + skillName + "\""); + } + + // ==================== totals ==================== + + int UnitType::getTotalMaxHp(const TotalUpgrade * totalUpgrade) const { + checkItemInVault(&(this->maxHp), this->maxHp); + int result = maxHp + totalUpgrade->getMaxHp(); + result = max(0, result); + return result; + } + + int UnitType::getTotalMaxHpRegeneration(const TotalUpgrade * + totalUpgrade) const { + checkItemInVault(&(this->hpRegeneration), this->hpRegeneration); + int result = hpRegeneration + totalUpgrade->getMaxHpRegeneration(); + //result = max(0,result); + return result; + } + + int UnitType::getTotalMaxEp(const TotalUpgrade * totalUpgrade) const { + checkItemInVault(&(this->maxEp), this->maxEp); + int result = maxEp + totalUpgrade->getMaxEp(); + result = max(0, result); + return result; + } + + int UnitType::getTotalMaxEpRegeneration(const TotalUpgrade * + totalUpgrade) const { + checkItemInVault(&(this->epRegeneration), this->epRegeneration); + int result = epRegeneration + totalUpgrade->getMaxEpRegeneration(); + //result = max(0,result); + return result; + } + + int UnitType::getTotalArmor(const TotalUpgrade * totalUpgrade) const { + checkItemInVault(&(this->armor), this->armor); + int result = armor + totalUpgrade->getArmor(); + result = max(0, result); + return result; + } + + int UnitType::getTotalSight(const TotalUpgrade * totalUpgrade) const { + checkItemInVault(&(this->sight), this->sight); + int result = sight + totalUpgrade->getSight(); + result = max(0, result); + return result; + } + + // ==================== has ==================== + + bool UnitType::hasSkillClass(SkillClass skillClass) const { + return firstSkillTypeOfClass[skillClass] != NULL; + } + + bool UnitType::hasCommandType(const CommandType * commandType) const { + assert(commandType != NULL); + + const HarvestEmergencyReturnCommandType *result = + dynamic_cast < + const HarvestEmergencyReturnCommandType * + >(ctHarvestEmergencyReturnCommandType.get()); + if (commandType == result) { + return true; + } + + for (int i = 0; i < (int) commandTypes.size(); ++i) { + if (commandTypes[i] == commandType) { + return true; + } + } + return false; + } + + //bool UnitType::hasSkillType(const SkillType *skillType) const { + // assert(skillType!=NULL); + // for(int i=0; i < (int)skillTypes.size(); ++i) { + // if(skillTypes[i]==skillType) { + // return true; + // } + // } + // return false; + //} + + bool UnitType::isOfClass(UnitClass uc) const { + switch (uc) { + case ucWarrior: + return hasSkillClass(scAttack) && !hasSkillClass(scHarvest); + case ucWorker:return hasSkillClass(scBuild) + || hasSkillClass(scRepair) || hasSkillClass(scHarvest); + case ucBuilding:return hasSkillClass(scBeBuilt); + default:assert(false); + break; + } + return false; + } + + // ==================== PRIVATE ==================== + + void UnitType::computeFirstStOfClass() { + for (int j = 0; j < scCount; ++j) { + firstSkillTypeOfClass[j] = NULL; + for (int i = 0; i < (int) skillTypes.size(); ++i) { + if (skillTypes[i] != NULL + && skillTypes[i]->getClass() == SkillClass(j)) { + firstSkillTypeOfClass[j] = skillTypes[i]; + break; + } + } + } + } + + void UnitType::computeFirstCtOfClass() { + for (int j = 0; j < ccCount; ++j) { + firstCommandTypeOfClass[j] = NULL; + for (int i = 0; i < (int) commandTypes.size(); ++i) { + if (commandTypes[i] != NULL + && commandTypes[i]->getClass() == CommandClass(j)) { + firstCommandTypeOfClass[j] = commandTypes[i]; + break; + } + } + } + } + + const CommandType *UnitType::findCommandTypeById(int id) const { + const HarvestEmergencyReturnCommandType *result = + dynamic_cast < + const HarvestEmergencyReturnCommandType * + >(ctHarvestEmergencyReturnCommandType.get()); + if (result != NULL && id == result->getId()) { + return result; + } + + for (int i = 0; i < getCommandTypeCount(); ++i) { + const CommandType *commandType = getCommandType(i); + if (commandType->getId() == id) { + return commandType; + } + } + return NULL; + } + + const CommandType *UnitType::getCommandType(int i) const { + if (i >= (int) commandTypes.size()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s Line: %d] i >= commandTypes.size(), i = %d, commandTypes.size() = " + MG_SIZE_T_SPECIFIER "", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, i, commandTypes.size()); + throw megaglest_runtime_error(szBuf); + } + return commandTypes[i]; + } + + string UnitType::getCommandTypeListDesc() const { + string desc = "Commands: "; + for (int i = 0; i < getCommandTypeCount(); ++i) { + const CommandType *commandType = getCommandType(i); + desc += " id = " + intToStr(commandType->getId()); + +" toString: " + commandType->toString(false); + } + return desc; + + } + + string UnitType::getReqDesc(bool translatedValue) const { + Lang & lang = Lang::getInstance(); + //string desc = "Limits: "; + string resultTxt = ""; + + checkItemInVault(&(this->maxUnitCount), this->maxUnitCount); + if (getMaxUnitCount() > 0) { + resultTxt += + "\n" + lang.getString("MaxUnitCount") + " " + + intToStr(getMaxUnitCount()); + } + if (resultTxt == "") + return ProducibleType::getReqDesc(translatedValue); + else + return ProducibleType::getReqDesc(translatedValue) + "\n" + + lang.getString("Limits") + " " + resultTxt; + } + + string UnitType::getName(bool translatedValue) const { + if (translatedValue == false) + return name; + + Lang & lang = Lang::getInstance(); + return lang.getTechTreeString("UnitTypeName_" + name, name.c_str()); + } + + std::string UnitType::toString() const { + std::string result = "Unit Name: [" + name + "] id = " + intToStr(id); + result += " maxHp = " + intToStr(maxHp); + result += " hpRegeneration = " + intToStr(hpRegeneration); + result += " maxEp = " + intToStr(maxEp); + result += " startEpValue = " + intToStr(startEpValue); + result += " startEpPercentage = " + intToStr(startEpPercentage); + result += " epRegeneration = " + intToStr(epRegeneration); + result += " maxUnitCount = " + intToStr(getMaxUnitCount()); + + + for (int i = 0; i < fieldCount; i++) { + result += + " fields index = " + intToStr(i) + " value = " + + intToStr(fields[i]); + } + for (int i = 0; i < pCount; i++) { + result += + " properties index = " + intToStr(i) + " value = " + + intToStr(properties[i]); + } + + result += " armor = " + intToStr(armor); + + if (armorType != NULL) { + result += + " armorType Name: [" + armorType->getName(false) + " id = " + + intToStr(armorType->getId()); + } + + result += " light = " + intToStr(light); + result += " lightColor = " + lightColor.getString(); + result += " multiSelect = " + intToStr(multiSelect); + result += " uniformSelect = " + intToStr(uniformSelect); + result += " commandable = " + intToStr(commandable); + result += " sight = " + intToStr(sight); + result += " size = " + intToStr(size); + result += " height = " + intToStr(height); + result += " rotatedBuildPos = " + floatToStr(rotatedBuildPos, 6); + result += " rotationAllowed = " + intToStr(rotationAllowed); + + if (cellMap != NULL) { + result += " cellMap: [" + intToStr(size) + "]"; + for (int i = 0; i < size; ++i) { + for (int j = 0; j < size; ++j) { + result += + " i = " + intToStr(i) + " j = " + intToStr(j) + " value = " + + intToStr(cellMap[i * size + j]); + } + } + } + + result += " skillTypes: [" + intToStr(skillTypes.size()) + "]"; + for (int i = 0; i < (int) skillTypes.size(); ++i) { + result += + " i = " + intToStr(i) + " " + skillTypes[i]->toString(false); + } + + result += " commandTypes: [" + intToStr(commandTypes.size()) + "]"; + for (int i = 0; i < (int) commandTypes.size(); ++i) { + result += + " i = " + intToStr(i) + " " + commandTypes[i]->toString(false); + } + + result += + " storedResources: [" + intToStr(storedResources.size()) + "]"; + for (int i = 0; i < (int) storedResources.size(); ++i) { + result += + " i = " + intToStr(i) + " " + + storedResources[i].getDescription(false); + } + + result += " levels: [" + intToStr(levels.size()) + "]"; + for (int i = 0; i < (int) levels.size(); ++i) { + result += " i = " + intToStr(i) + " " + levels[i].getName(); + } + + result += " meetingPoint = " + intToStr(meetingPoint); + + result += + " countInVictoryConditions = " + intToStr(countInVictoryConditions); + + return result; + } + + } } //end namespace diff --git a/source/glest_game/types/unit_type.h b/source/glest_game/types/unit_type.h index 96a39817a..3cb25ba44 100644 --- a/source/glest_game/types/unit_type.h +++ b/source/glest_game/types/unit_type.h @@ -27,595 +27,507 @@ # include "common_scoped_ptr.h" # include "leak_dumper.h" -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - using Shared::Sound::StaticSound; - using Shared::Util::Checksum; - using Shared::PlatformCommon::ValueCheckerVault; + using Shared::Sound::StaticSound; + using Shared::Util::Checksum; + using Shared::PlatformCommon::ValueCheckerVault; - class UpgradeType; - class UnitType; - class UnitParticleSystemType; - class ResourceType; - class TechTree; - class FactionType; - class Faction; + class UpgradeType; + class UnitType; + class UnitParticleSystemType; + class ResourceType; + class TechTree; + class FactionType; + class Faction; -// =============================== -// class Level -// =============================== + // =============================== + // class Level + // =============================== - class Level - { - private: - string name; - int kills; + class Level { + private: + string name; + int kills; - public: - Level () - { - kills = 0; - } - void init (string name, int kills); + public: + Level() { + kills = 0; + } + void init(string name, int kills); - string getName (bool translatedValue = false) const; - int getKills () const - { - return kills; - } + string getName(bool translatedValue = false) const; + int getKills() const { + return kills; + } - void saveGame (XmlNode * rootNode) const; - static const Level *loadGame (const XmlNode * rootNode, - const UnitType * ut); - }; + void saveGame(XmlNode * rootNode) const; + static const Level *loadGame(const XmlNode * rootNode, + const UnitType * ut); + }; -// =============================== -// class LootResource -// -/// Stores information about a lootable resource. Lootable resources are stolen by the attacker on death. -// =============================== + // =============================== + // class LootResource + // + /// Stores information about a lootable resource. Lootable resources are stolen by the attacker on death. + // =============================== - class LootableResource - { - private: - const ResourceType *type; - int amountValue; - int amountFactionPercent; - int lossValue; - int lossFactionPercent; - bool negativeAllowed; + class LootableResource { + private: + const ResourceType *type; + int amountValue; + int amountFactionPercent; + int lossValue; + int lossFactionPercent; + bool negativeAllowed; - public: - LootableResource () - { - type = NULL; - amountValue = 0; - amountFactionPercent = 0; - lossValue = 0; - lossFactionPercent = 0; - negativeAllowed = false; - } + public: + LootableResource() { + type = NULL; + amountValue = 0; + amountFactionPercent = 0; + lossValue = 0; + lossFactionPercent = 0; + negativeAllowed = false; + } - const ResourceType *getResourceType () const - { - return type; - } - void setResourceType (const ResourceType * type) - { - this->type = type; - } + const ResourceType *getResourceType() const { + return type; + } + void setResourceType(const ResourceType * type) { + this->type = type; + } - int getAmountValue () const - { - return amountValue; - } - void setAmountValue (int amountValue) - { - this->amountValue = amountValue; - } + int getAmountValue() const { + return amountValue; + } + void setAmountValue(int amountValue) { + this->amountValue = amountValue; + } - int getAmountFactionPercent () const - { - return amountFactionPercent; - } - void setAmountFactionPercent (int amountPercentage) - { - this->amountFactionPercent = amountPercentage; - } + int getAmountFactionPercent() const { + return amountFactionPercent; + } + void setAmountFactionPercent(int amountPercentage) { + this->amountFactionPercent = amountPercentage; + } - int getLossValue () const - { - return lossValue; - } - void setLossValue (int lossValue) - { - this->lossValue = lossValue; - } + int getLossValue() const { + return lossValue; + } + void setLossValue(int lossValue) { + this->lossValue = lossValue; + } - int getLossFactionPercent () const - { - return lossFactionPercent; - } - void setLossFactionPercent (int lossPercentage) - { - this->lossFactionPercent = lossPercentage; - } + int getLossFactionPercent() const { + return lossFactionPercent; + } + void setLossFactionPercent(int lossPercentage) { + this->lossFactionPercent = lossPercentage; + } - bool isNegativeAllowed () const - { - return negativeAllowed; - } - void setNegativeAllowed (bool negativeAllowed) - { - this->negativeAllowed = negativeAllowed; - } + bool isNegativeAllowed() const { + return negativeAllowed; + } + void setNegativeAllowed(bool negativeAllowed) { + this->negativeAllowed = negativeAllowed; + } - bool operator== (const LootableResource & other) - { - return type == other.getResourceType (); - } - }; + bool operator== (const LootableResource & other) { + return type == other.getResourceType(); + } + }; -// =============================== -// class UnitType -// -/// A unit or building type -// =============================== + // =============================== + // class UnitType + // + /// A unit or building type + // =============================== - enum UnitClass - { - ucWarrior, - ucWorker, - ucBuilding - }; + enum UnitClass { + ucWarrior, + ucWorker, + ucBuilding + }; - typedef vector < UnitParticleSystemType * >DamageParticleSystemTypes; + typedef vector < UnitParticleSystemType * >DamageParticleSystemTypes; - enum HealthbarVisible - { - hbvUndefined = 0, - hbvOff = 1, - hbvAlways = 2, - hbvIfNeeded = 4, - hbvSelected = 8 - }; + enum HealthbarVisible { + hbvUndefined = 0, + hbvOff = 1, + hbvAlways = 2, + hbvIfNeeded = 4, + hbvSelected = 8 + }; - enum UnitCountsInVictoryConditions - { - ucvcNotSet, - ucvcTrue, - ucvcFalse - }; + enum UnitCountsInVictoryConditions { + ucvcNotSet, + ucvcTrue, + ucvcFalse + }; - class UnitType:public ProducibleType, public ValueCheckerVault - { - public: - enum Property - { - pBurnable, - pRotatedClimb, + class UnitType :public ProducibleType, public ValueCheckerVault { + public: + enum Property { + pBurnable, + pRotatedClimb, - pCount - }; + pCount + }; - enum StartType - { - stValue, - stPercentage - }; + enum StartType { + stValue, + stPercentage + }; - static const char *propertyNames[]; - DamageParticleSystemTypes damageParticleSystemTypes; - private: - typedef vector < SkillType * >SkillTypes; - typedef vector < CommandType * >CommandTypes; - typedef vector < Resource > StoredResources; - typedef vector < Level > Levels; - typedef vector < LootableResource > LootableResources; + static const char *propertyNames[]; + DamageParticleSystemTypes damageParticleSystemTypes; + private: + typedef vector < SkillType * >SkillTypes; + typedef vector < CommandType * >CommandTypes; + typedef vector < Resource > StoredResources; + typedef vector < Level > Levels; + typedef vector < LootableResource > LootableResources; - private: - //basic - int id; - int maxHp; - int startHpValue; - int startHpPercentage; - StartType startHpType; - int hpRegeneration; - int maxEp; - int startEpValue; - int startEpPercentage; - StartType startEpType; - int epRegeneration; - int maxUnitCount; + private: + //basic + int id; + int maxHp; + int startHpValue; + int startHpPercentage; + StartType startHpType; + int hpRegeneration; + int maxEp; + int startEpValue; + int startEpPercentage; + StartType startEpType; + int epRegeneration; + int maxUnitCount; - // remove fields, multiple fields are not supported by the engine - bool fields[fieldCount]; //fields: land, sea or air - Field field; + // remove fields, multiple fields are not supported by the engine + bool fields[fieldCount]; //fields: land, sea or air + Field field; - bool properties[pCount]; //properties - int armor; //armor - const ArmorType *armorType; - bool light; - Vec3f lightColor; - float healthbarheight; - float healthbarthickness; - int healthbarVisible; - bool multiSelect; - bool uniformSelect; - bool commandable; - int sight; - int size; //size in cells - int aiBuildSize; - int renderSize; //size to render in cells - int height; - int burnHeight; - int targetHeight; - float rotatedBuildPos; - bool rotationAllowed; + bool properties[pCount]; //properties + int armor; //armor + const ArmorType *armorType; + bool light; + Vec3f lightColor; + float healthbarheight; + float healthbarthickness; + int healthbarVisible; + bool multiSelect; + bool uniformSelect; + bool commandable; + int sight; + int size; //size in cells + int aiBuildSize; + int renderSize; //size to render in cells + int height; + int burnHeight; + int targetHeight; + float rotatedBuildPos; + bool rotationAllowed; - //cellmap - bool *cellMap; - bool allowEmptyCellMap; + //cellmap + bool *cellMap; + bool allowEmptyCellMap; - //sounds - SoundContainer selectionSounds; - SoundContainer commandSounds; + //sounds + SoundContainer selectionSounds; + SoundContainer commandSounds; - //info - SkillTypes skillTypes; - CommandTypes commandTypes; - StoredResources storedResources; - Levels levels; - LootableResources lootableResources; - std::set < string > tags; + //info + SkillTypes skillTypes; + CommandTypes commandTypes; + StoredResources storedResources; + Levels levels; + LootableResources lootableResources; + std::set < string > tags; - //meeting point - bool meetingPoint; - Texture2D *meetingPointImage; + //meeting point + bool meetingPoint; + Texture2D *meetingPointImage; - // for dummy units and units used as shots and so on .... - bool countUnitDeathInStats; - bool countUnitProductionInStats; - bool countUnitKillInStats; - bool countKillForUnitUpgrade; + // for dummy units and units used as shots and so on .... + bool countUnitDeathInStats; + bool countUnitProductionInStats; + bool countUnitKillInStats; + bool countKillForUnitUpgrade; - //OPTIMIZATION: store first command type and skill type of each class - const CommandType *firstCommandTypeOfClass[ccCount]; - const SkillType *firstSkillTypeOfClass[scCount]; + //OPTIMIZATION: store first command type and skill type of each class + const CommandType *firstCommandTypeOfClass[ccCount]; + const SkillType *firstSkillTypeOfClass[scCount]; - UnitCountsInVictoryConditions countInVictoryConditions; + UnitCountsInVictoryConditions countInVictoryConditions; - static auto_ptr < CommandType > ctHarvestEmergencyReturnCommandType; + static auto_ptr < CommandType > ctHarvestEmergencyReturnCommandType; - public: - //creation and loading - UnitType (); - virtual ~ UnitType (); - void preLoad (const string & dir); - void loaddd (int id, const string & dir, const TechTree * techTree, - const string & techTreePath, - const FactionType * factionType, Checksum * checksum, - Checksum * techtreeChecksum, - std::map < string, vector < pair < string, - string > > >&loadedFileList, bool validationMode = false); + public: + //creation and loading + UnitType(); + virtual ~UnitType(); + void preLoad(const string & dir); + void loaddd(int id, const string & dir, const TechTree * techTree, + const string & techTreePath, + const FactionType * factionType, Checksum * checksum, + Checksum * techtreeChecksum, + std::map < string, vector < pair < string, + string > > >&loadedFileList, bool validationMode = false); - virtual string getName (bool translatedValue = false) const; + virtual string getName(bool translatedValue = false) const; - UnitCountsInVictoryConditions getCountInVictoryConditions () const - { - return countInVictoryConditions; - } - //get - inline int getId () const - { - return id; - } - inline int getMaxHp () const - { - return maxHp; - } - inline int getHpRegeneration () const - { - return hpRegeneration; - } - inline int getStartHpValue () const - { - return startHpValue; - } - inline int getStartHpPercentage () const - { - return startHpPercentage; - } - inline StartType getStartHpType () const - { - return startHpType; - } - inline int getMaxEp () const - { - return maxEp; - } - inline int getEpRegeneration () const - { - return epRegeneration; - } - inline int getStartEpValue () const - { - return startEpValue; - } - inline int getStartEpPercentage () const - { - return startEpPercentage; - } - inline StartType getStartEpType () const - { - return startEpType; - } - inline int getMaxUnitCount () const - { - return maxUnitCount; - } - inline bool getField (Field field) const - { - return fields[field]; - } - inline Field getField () const - { - return field; - } - inline bool getProperty (Property property) const - { - return properties[property]; - } - inline int getArmor () const - { - return armor; - } - inline const ArmorType *getArmorType () const - { - return armorType; - } - inline const SkillType *getSkillType (int i) const - { - return skillTypes[i]; - } - const CommandType *getCommandType (int i) const; - inline const Level *getLevel (int i) const - { - return &levels[i]; - } - const Level *getLevel (string name) const; - inline int getSkillTypeCount () const - { - return (int) skillTypes.size (); - } - inline int getCommandTypeCount () const - { - return (int) commandTypes.size (); - } - inline int getLevelCount () const - { - return (int) levels.size (); - } - inline bool getLight () const - { - return light; - } - inline bool getRotationAllowed () const - { - return rotationAllowed; - } - inline Vec3f getLightColor () const - { - return lightColor; - } - inline float getHealthbarHeight () const - { - return healthbarheight; - } - inline float getHealthbarThickness () const - { - return healthbarthickness; - } - inline int getHealthbarVisible () const - { - return healthbarVisible; - } - inline bool getMultiSelect () const - { - return multiSelect; - } - inline bool getUniformSelect () const - { - return uniformSelect; - } - inline bool isCommandable () const - { - return commandable; - } - inline int getSight () const - { - return sight; - } - inline int getSize () const - { - return size; - } - inline int getAiBuildSize () const - { - return aiBuildSize; - } - inline int getRenderSize () const - { - return renderSize; - } - int getHeight () const - { - return height; - } - int getBurnHeight () const - { - return burnHeight; - } - int getTargetHeight () const - { - return targetHeight; - } - int getStoredResourceCount () const - { - return (int) storedResources.size (); - } - inline const Resource *getStoredResource (int i) const - { - return &storedResources[i]; - } - int getLootableResourceCount () const - { - return (int) lootableResources.size (); - } - inline const LootableResource getLootableResource (int i) const - { - return lootableResources.at (i); - } - const set < string > &getTags () const - { - return tags; - } - bool getCellMapCell (int x, int y, CardinalDir facing) const; - inline bool getMeetingPoint () const - { - return meetingPoint; - } - inline bool getCountUnitDeathInStats () const - { - return countUnitDeathInStats; - } - inline bool getCountUnitProductionInStats () const - { - return countUnitProductionInStats; - } - inline bool getCountUnitKillInStats () const - { - return countUnitKillInStats; - } - inline bool getCountKillForUnitUpgrade () const - { - return countKillForUnitUpgrade; - } - inline bool isMobile () const - { - return (firstSkillTypeOfClass[scMove] != NULL); - } - inline Texture2D *getMeetingPointImage () const - { - return meetingPointImage; - } - inline StaticSound *getSelectionSound () const - { - return selectionSounds.getRandSound (); - } - inline StaticSound *getCommandSound () const - { - return commandSounds.getRandSound (); - } + UnitCountsInVictoryConditions getCountInVictoryConditions() const { + return countInVictoryConditions; + } + //get + inline int getId() const { + return id; + } + inline int getMaxHp() const { + return maxHp; + } + inline int getHpRegeneration() const { + return hpRegeneration; + } + inline int getStartHpValue() const { + return startHpValue; + } + inline int getStartHpPercentage() const { + return startHpPercentage; + } + inline StartType getStartHpType() const { + return startHpType; + } + inline int getMaxEp() const { + return maxEp; + } + inline int getEpRegeneration() const { + return epRegeneration; + } + inline int getStartEpValue() const { + return startEpValue; + } + inline int getStartEpPercentage() const { + return startEpPercentage; + } + inline StartType getStartEpType() const { + return startEpType; + } + inline int getMaxUnitCount() const { + return maxUnitCount; + } + inline bool getField(Field field) const { + return fields[field]; + } + inline Field getField() const { + return field; + } + inline bool getProperty(Property property) const { + return properties[property]; + } + inline int getArmor() const { + return armor; + } + inline const ArmorType *getArmorType() const { + return armorType; + } + inline const SkillType *getSkillType(int i) const { + return skillTypes[i]; + } + const CommandType *getCommandType(int i) const; + inline const Level *getLevel(int i) const { + return &levels[i]; + } + const Level *getLevel(string name) const; + inline int getSkillTypeCount() const { + return (int) skillTypes.size(); + } + inline int getCommandTypeCount() const { + return (int) commandTypes.size(); + } + inline int getLevelCount() const { + return (int) levels.size(); + } + inline bool getLight() const { + return light; + } + inline bool getRotationAllowed() const { + return rotationAllowed; + } + inline Vec3f getLightColor() const { + return lightColor; + } + inline float getHealthbarHeight() const { + return healthbarheight; + } + inline float getHealthbarThickness() const { + return healthbarthickness; + } + inline int getHealthbarVisible() const { + return healthbarVisible; + } + inline bool getMultiSelect() const { + return multiSelect; + } + inline bool getUniformSelect() const { + return uniformSelect; + } + inline bool isCommandable() const { + return commandable; + } + inline int getSight() const { + return sight; + } + inline int getSize() const { + return size; + } + inline int getAiBuildSize() const { + return aiBuildSize; + } + inline int getRenderSize() const { + return renderSize; + } + int getHeight() const { + return height; + } + int getBurnHeight() const { + return burnHeight; + } + int getTargetHeight() const { + return targetHeight; + } + int getStoredResourceCount() const { + return (int) storedResources.size(); + } + inline const Resource *getStoredResource(int i) const { + return &storedResources[i]; + } + int getLootableResourceCount() const { + return (int) lootableResources.size(); + } + inline const LootableResource getLootableResource(int i) const { + return lootableResources.at(i); + } + const set < string > &getTags() const { + return tags; + } + bool getCellMapCell(int x, int y, CardinalDir facing) const; + inline bool getMeetingPoint() const { + return meetingPoint; + } + inline bool getCountUnitDeathInStats() const { + return countUnitDeathInStats; + } + inline bool getCountUnitProductionInStats() const { + return countUnitProductionInStats; + } + inline bool getCountUnitKillInStats() const { + return countUnitKillInStats; + } + inline bool getCountKillForUnitUpgrade() const { + return countKillForUnitUpgrade; + } + inline bool isMobile() const { + return (firstSkillTypeOfClass[scMove] != NULL); + } + inline Texture2D *getMeetingPointImage() const { + return meetingPointImage; + } + inline StaticSound *getSelectionSound() const { + return selectionSounds.getRandSound(); + } + inline StaticSound *getCommandSound() const { + return commandSounds.getRandSound(); + } - inline const SoundContainer & getSelectionSounds () const - { - return selectionSounds; - } - inline const SoundContainer & getCommandSounds () const - { - return commandSounds; - } + inline const SoundContainer & getSelectionSounds() const { + return selectionSounds; + } + inline const SoundContainer & getCommandSounds() const { + return commandSounds; + } - int getStore (const ResourceType * rt) const; - const SkillType *getSkillType (const string & skillName, - SkillClass skillClass) const; - const SkillType *getFirstStOfClass (SkillClass skillClass) const; - const CommandType *getFirstCtOfClass (CommandClass commandClass) const; - const HarvestCommandType *getFirstHarvestCommand (const ResourceType * - resourceType, - const Faction * - faction) const; - const HarvestEmergencyReturnCommandType - *getFirstHarvestEmergencyReturnCommand () const; - const AttackCommandType *getFirstAttackCommand (Field field) const; - const AttackStoppedCommandType *getFirstAttackStoppedCommand (Field - field) - const; - const RepairCommandType *getFirstRepairCommand (const UnitType * - repaired) const; + int getStore(const ResourceType * rt) const; + const SkillType *getSkillType(const string & skillName, + SkillClass skillClass) const; + const SkillType *getFirstStOfClass(SkillClass skillClass) const; + const CommandType *getFirstCtOfClass(CommandClass commandClass) const; + const HarvestCommandType *getFirstHarvestCommand(const ResourceType * + resourceType, + const Faction * + faction) const; + const HarvestEmergencyReturnCommandType + *getFirstHarvestEmergencyReturnCommand() const; + const AttackCommandType *getFirstAttackCommand(Field field) const; + const AttackStoppedCommandType *getFirstAttackStoppedCommand(Field + field) + const; + const RepairCommandType *getFirstRepairCommand(const UnitType * + repaired) const; - //get totals - int getTotalMaxHp (const TotalUpgrade * totalUpgrade) const; - int getTotalMaxHpRegeneration (const TotalUpgrade * totalUpgrade) const; - int getTotalMaxEp (const TotalUpgrade * totalUpgrade) const; - int getTotalMaxEpRegeneration (const TotalUpgrade * totalUpgrade) const; - int getTotalArmor (const TotalUpgrade * totalUpgrade) const; - int getTotalSight (const TotalUpgrade * totalUpgrade) const; + //get totals + int getTotalMaxHp(const TotalUpgrade * totalUpgrade) const; + int getTotalMaxHpRegeneration(const TotalUpgrade * totalUpgrade) const; + int getTotalMaxEp(const TotalUpgrade * totalUpgrade) const; + int getTotalMaxEpRegeneration(const TotalUpgrade * totalUpgrade) const; + int getTotalArmor(const TotalUpgrade * totalUpgrade) const; + int getTotalSight(const TotalUpgrade * totalUpgrade) const; - //has - bool hasCommandType (const CommandType * commandType) const; - inline bool hasCommandClass (CommandClass commandClass) const - { - return firstCommandTypeOfClass[commandClass] != NULL; - } - //bool hasSkillType(const SkillType *skillType) const; - bool hasSkillClass (SkillClass skillClass) const; - inline bool hasCellMap () const - { - return cellMap != NULL; - } - inline bool getAllowEmptyCellMap () const - { - return allowEmptyCellMap; - } - bool hasEmptyCellMap () const; - Vec2i getFirstOccupiedCellInCellMap (Vec2i currentPos) const; + //has + bool hasCommandType(const CommandType * commandType) const; + inline bool hasCommandClass(CommandClass commandClass) const { + return firstCommandTypeOfClass[commandClass] != NULL; + } + //bool hasSkillType(const SkillType *skillType) const; + bool hasSkillClass(SkillClass skillClass) const; + inline bool hasCellMap() const { + return cellMap != NULL; + } + inline bool getAllowEmptyCellMap() const { + return allowEmptyCellMap; + } + bool hasEmptyCellMap() const; + Vec2i getFirstOccupiedCellInCellMap(Vec2i currentPos) const; - //is - bool isOfClass (UnitClass uc) const; + //is + bool isOfClass(UnitClass uc) const; - //find - const CommandType *findCommandTypeById (int id) const; - string getCommandTypeListDesc () const; + //find + const CommandType *findCommandTypeById(int id) const; + string getCommandTypeListDesc() const; - inline float getRotatedBuildPos () - { - return rotatedBuildPos; - } - inline void setRotatedBuildPos (float value) - { - rotatedBuildPos = value; - } + inline float getRotatedBuildPos() { + return rotatedBuildPos; + } + inline void setRotatedBuildPos(float value) { + rotatedBuildPos = value; + } - //other - virtual string getReqDesc (bool translatedValue) const; + //other + virtual string getReqDesc(bool translatedValue) const; - std::string toString ()const; + std::string toString()const; - private: - void computeFirstStOfClass (); - void computeFirstCtOfClass (); - }; + private: + void computeFirstStOfClass(); + void computeFirstCtOfClass(); + }; -/** - * Used to sort UnitType. Sorts by *translated* unit name. Sorting is case sensitive and done in - * lexical order. - */ - struct UnitTypeSorter - { - bool operator () (const UnitType * left, const UnitType * right) const - { - return left->getName (true) < right->getName (true); - } - }; + /** + * Used to sort UnitType. Sorts by *translated* unit name. Sorting is case sensitive and done in + * lexical order. + */ + struct UnitTypeSorter { + bool operator () (const UnitType * left, const UnitType * right) const { + return left->getName(true) < right->getName(true); + } + }; - } + } } //end namespace diff --git a/source/glest_game/types/upgrade_type.cpp b/source/glest_game/types/upgrade_type.cpp index 76fdcd6cd..8f1e4d07f 100644 --- a/source/glest_game/types/upgrade_type.cpp +++ b/source/glest_game/types/upgrade_type.cpp @@ -31,2513 +31,2192 @@ using namespace Shared::Util; using namespace Shared::Xml; -namespace Glest -{ - namespace Game - { - -// ===================================================== -// class UpgradeType -// ===================================================== - -// ==================== get ==================== - - const string VALUE_PERCENT_MULTIPLIER_KEY_NAME = - "value-percent-multiplier"; - const string VALUE_REGEN_KEY_NAME = "regeneration"; - - void UpgradeTypeBase::copyDataFrom (UpgradeTypeBase * source) - { - upgradename = source->upgradename; - maxHp = source->maxHp; - maxHpIsMultiplier = source->maxHpIsMultiplier; - maxHpRegeneration = source->maxHpRegeneration; - sight = source->sight; - sightIsMultiplier = source->sightIsMultiplier; - maxEp = source->maxEp; - maxEpIsMultiplier = source->maxEpIsMultiplier; - maxEpRegeneration = source->maxEpRegeneration; - armor = source->armor; - armorIsMultiplier = source->armorIsMultiplier; - attackStrength = source->attackStrength; - attackStrengthIsMultiplier = source->attackStrengthIsMultiplier; - attackStrengthMultiplierValueList = - source->attackStrengthMultiplierValueList; - attackRange = source->attackRange; - attackRangeIsMultiplier = source->attackRangeIsMultiplier; - attackRangeMultiplierValueList = source->attackRangeMultiplierValueList; - moveSpeed = source->moveSpeed; - moveSpeedIsMultiplier = source->moveSpeedIsMultiplier; - moveSpeedIsMultiplierValueList = source->moveSpeedIsMultiplierValueList; - prodSpeed = source->prodSpeed; - prodSpeedIsMultiplier = source->prodSpeedIsMultiplier; - prodSpeedProduceIsMultiplierValueList = - source->prodSpeedProduceIsMultiplierValueList; - prodSpeedUpgradeIsMultiplierValueList = - source->prodSpeedUpgradeIsMultiplierValueList; - prodSpeedMorphIsMultiplierValueList = - source->prodSpeedMorphIsMultiplierValueList; - attackSpeed = source->attackSpeed; - attackSpeedIsMultiplier = source->attackSpeedIsMultiplier; - attackSpeedIsMultiplierValueList = - source->attackSpeedIsMultiplierValueList; - } - - void UpgradeTypeBase::load (const XmlNode * upgradeNode, - string upgradename) - { - this->upgradename = upgradename; - //values - maxHpIsMultiplier = false; - if (upgradeNode->hasChild ("max-hp") == true) - { - maxHp = - upgradeNode->getChild ("max-hp")->getAttribute ("value")-> - getIntValue (); - if (upgradeNode->getChild ("max-hp")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) - { - maxHpIsMultiplier = - upgradeNode->getChild ("max-hp")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue (); - - //printf("Found maxHpIsMultiplier = %d\n",maxHpIsMultiplier); - } - } - else - { - maxHp = 0; - } - maxHpRegeneration = 0; - //maxHpRegenerationIsMultiplier = false; - if (upgradeNode->hasChild ("max-hp") == true) - { - if (upgradeNode->getChild ("max-hp")-> - getAttribute (VALUE_REGEN_KEY_NAME, false) != NULL) - { - maxHpRegeneration = - upgradeNode->getChild ("max-hp")-> - getAttribute (VALUE_REGEN_KEY_NAME)->getIntValue (); - - //printf("Found maxHpIsMultiplier = %d\n",maxHpIsMultiplier); - } - } - - maxEpIsMultiplier = false; - if (upgradeNode->hasChild ("max-ep") == true) - { - maxEp = - upgradeNode->getChild ("max-ep")->getAttribute ("value")-> - getIntValue (); - if (upgradeNode->getChild ("max-ep")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) - { - maxEpIsMultiplier = - upgradeNode->getChild ("max-ep")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue (); - - //printf("Found maxEpIsMultiplier = %d\n",maxEpIsMultiplier); - } - } - else - { - maxEp = 0; - } - maxEpRegeneration = 0; - //maxEpRegenerationIsMultiplier = false; - if (upgradeNode->hasChild ("max-ep") == true) - { - if (upgradeNode->getChild ("max-ep")-> - getAttribute (VALUE_REGEN_KEY_NAME, false) != NULL) - { - maxEpRegeneration = - upgradeNode->getChild ("max-ep")-> - getAttribute (VALUE_REGEN_KEY_NAME)->getIntValue (); - - //printf("Found maxHpIsMultiplier = %d\n",maxHpIsMultiplier); - } - } - - sightIsMultiplier = false; - if (upgradeNode->hasChild ("sight") == true) - { - sight = - upgradeNode->getChild ("sight")->getAttribute ("value")-> - getIntValue (); - if (upgradeNode->getChild ("sight")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) - { - sightIsMultiplier = - upgradeNode->getChild ("sight")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue (); - - //printf("Found sightIsMultiplier = %d\n",sightIsMultiplier); - } - } - else - { - sight = 0; - } - - attackStrengthIsMultiplier = false; - - std::vector < string > attackStrengthXMLTags; - attackStrengthXMLTags.push_back ("attack-strenght"); - attackStrengthXMLTags.push_back ("attack-strength"); - if (upgradeNode->hasChildWithAliases (attackStrengthXMLTags) == true) - { - attackStrength = - upgradeNode->getChildWithAliases (attackStrengthXMLTags)-> - getAttribute ("value")->getIntValue (); - if (upgradeNode->getChildWithAliases (attackStrengthXMLTags)-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) - { - attackStrengthIsMultiplier = - upgradeNode->getChildWithAliases (attackStrengthXMLTags)-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue (); - - //printf("Found attackStrengthIsMultiplier = %d\n",attackStrengthIsMultiplier); - } - } - else - { - attackStrength = 0; - } - - attackRangeIsMultiplier = false; - if (upgradeNode->hasChild ("attack-range") == true) - { - attackRange = - upgradeNode->getChild ("attack-range")->getAttribute ("value")-> - getIntValue (); - if (upgradeNode->getChild ("attack-range")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) - { - attackRangeIsMultiplier = - upgradeNode->getChild ("attack-range")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue (); - - //printf("Found attackRangeIsMultiplier = %d\n",attackRangeIsMultiplier); - } - } - else - { - attackRange = 0; - } - - armorIsMultiplier = false; - if (upgradeNode->hasChild ("armor") == true) - { - armor = - upgradeNode->getChild ("armor")->getAttribute ("value")-> - getIntValue (); - if (upgradeNode->getChild ("armor")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) - { - armorIsMultiplier = - upgradeNode->getChild ("armor")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue (); - - //printf("Found armorIsMultiplier = %d\n",armorIsMultiplier); - } - } - else - { - armor = 0; - } - - moveSpeedIsMultiplier = false; - if (upgradeNode->hasChild ("move-speed") == true) - { - moveSpeed = - upgradeNode->getChild ("move-speed")->getAttribute ("value")-> - getIntValue (); - if (upgradeNode->getChild ("move-speed")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) - { - moveSpeedIsMultiplier = - upgradeNode->getChild ("move-speed")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue (); - - //printf("Found moveSpeedIsMultiplier = %d\n",moveSpeedIsMultiplier); - } - } - else - { - moveSpeed = 0; - } - - prodSpeedIsMultiplier = false; - if (upgradeNode->hasChild ("production-speed") == true) - { - prodSpeed = - upgradeNode->getChild ("production-speed")->getAttribute ("value")-> - getIntValue (); - if (upgradeNode->getChild ("production-speed")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) - { - prodSpeedIsMultiplier = - upgradeNode->getChild ("production-speed")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue (); - - //printf("Found prodSpeedIsMultiplier = %d\n",prodSpeedIsMultiplier); - } - } - else - { - prodSpeed = 0; - } - - attackSpeedIsMultiplier = false; - if (upgradeNode->hasChild ("attack-speed") == true) - { - attackSpeed = - upgradeNode->getChild ("attack-speed")->getAttribute ("value")-> - getIntValue (); - if (upgradeNode->getChild ("attack-speed")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) - { - attackSpeedIsMultiplier = - upgradeNode->getChild ("attack-speed")-> - getAttribute (VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue (); - - //printf("Found prodSpeedIsMultiplier = %d\n",prodSpeedIsMultiplier); - } - } - else - { - attackSpeed = 0; - } - } - - int UpgradeTypeBase::getAttackStrength (const AttackSkillType * st) const - { - if (attackStrengthIsMultiplier == false || st == NULL) - { - return attackStrength; - } - else - { - int result = 0; - if (attackStrengthMultiplierValueList.find (st->getName ()) != - attackStrengthMultiplierValueList.end ()) - { - result = - attackStrengthMultiplierValueList.find (st->getName ())->second; - } - return result; - } - } - int UpgradeTypeBase::getAttackRange (const AttackSkillType * st) const - { - if (attackRangeIsMultiplier == false || st == NULL) - { - return attackRange; - } - else - { - int result = 0; - if (attackRangeMultiplierValueList.find (st->getName ()) != - attackRangeMultiplierValueList.end ()) - { - result = - attackRangeMultiplierValueList.find (st->getName ())->second; - } - return result; - } - } - - int UpgradeTypeBase::getMoveSpeed (const MoveSkillType * st) const - { - if (moveSpeedIsMultiplier == false || st == NULL) - { - //printf("getMoveSpeed moveSpeedIsMultiplier OFF st [%p]\n",st); - return moveSpeed; - } - else - { - int result = 0; - if (moveSpeedIsMultiplierValueList.find (st->getName ()) != - moveSpeedIsMultiplierValueList.end ()) - { - result = - moveSpeedIsMultiplierValueList.find (st->getName ())->second; - } - - //printf("getMoveSpeed moveSpeedIsMultiplier mst->getSpeed() = %d for skill [%s] result = %d\n",st->getSpeed(),st->getName().c_str(),result); - return result; - } - } - - int UpgradeTypeBase::getAttackSpeed (const AttackSkillType * st) const - { - if (attackSpeedIsMultiplier == false || st == NULL) - { - return attackSpeed; - } - else - { - int result = 0; - if (attackSpeedIsMultiplierValueList.find (st->getName ()) != - attackSpeedIsMultiplierValueList.end ()) - { - result = - attackSpeedIsMultiplierValueList.find (st->getName ())->second; - } - - return result; - } - } - - int UpgradeTypeBase::getProdSpeed (const SkillType * st) const - { - if (prodSpeedIsMultiplier == false || st == NULL) - { - return prodSpeed; - } - else - { - int result = 0; - if (dynamic_cast < const ProduceSkillType * >(st) != NULL) - { - if (prodSpeedProduceIsMultiplierValueList.find (st->getName ()) != - prodSpeedProduceIsMultiplierValueList.end ()) - { - result = - prodSpeedProduceIsMultiplierValueList.find (st->getName ())-> - second; - } - } - else if (dynamic_cast < const UpgradeSkillType * >(st) != NULL) - { - if (prodSpeedUpgradeIsMultiplierValueList.find (st->getName ()) != - prodSpeedUpgradeIsMultiplierValueList.end ()) - { - result = - prodSpeedUpgradeIsMultiplierValueList.find (st->getName ())-> - second; - } - } - else if (dynamic_cast < const MorphSkillType * >(st) != NULL) - { - if (prodSpeedMorphIsMultiplierValueList.find (st->getName ()) != - prodSpeedMorphIsMultiplierValueList.end ()) - { - result = - prodSpeedMorphIsMultiplierValueList.find (st->getName ())-> - second; - } - } - else - { - throw - megaglest_runtime_error - ("Unsupported skilltype in getProdSpeed!"); - } - - return result; - } - } - - string UpgradeTypeBase::getDesc (bool translatedValue) const - { - - string str = ""; - string indent = "->"; - Lang & lang = Lang::getInstance (); - - if (getMaxHp () != 0 || getMaxHpRegeneration () != 0) - { - str += - indent + lang.getString ("Hp", - (translatedValue == - true ? "" : "english")) + " +" + - intToStr (maxHp); - if (maxHpIsMultiplier) - { - str += "%"; - } -// if(getMaxHpFromBoosts() != 0) { -// str += " +" + intToStr(getMaxHpFromBoosts()); -// } - if (getMaxHpRegeneration () != 0) - { - str += - " (" + lang.getString ("Regeneration", - (translatedValue == - true ? "" : "english")) + ": +" + - intToStr (maxHpRegeneration); -// if(getMaxHpRegenerationFromBoosts() != 0) { -// str += " +" + intToStr(getMaxHpRegenerationFromBoosts()); -// } - str += ")"; - } - } - - if (getSight () != 0) - { - if (str != "") - { - str += "\n"; - } - str += - indent + lang.getString ("Sight", - (translatedValue == - true ? "" : "english")) + " +" + - intToStr (sight); - if (sightIsMultiplier) - { - str += "%"; - } -// if(getSightFromBoosts() != 0) { -// str += " +" + intToStr(getSightFromBoosts()); -// } - } - - if (getMaxEp () != 0 || getMaxEpRegeneration () != 0) - { - if (str != "") - { - str += "\n"; - } - - str += - indent + lang.getString ("Ep", - (translatedValue == - true ? "" : "english")) + " +" + - intToStr (maxEp); - if (maxEpIsMultiplier) - { - str += "%"; - } -// if(getMaxEpFromBoosts() != 0) { -// str += " +" + intToStr(getMaxEpFromBoosts()); -// } - - if (getMaxEpRegeneration () != 0) - { - str += - " (" + lang.getString ("Regeneration", - (translatedValue == - true ? "" : "english")) + ": +" + - intToStr (maxEpRegeneration); -// if(getMaxEpRegenerationFromBoosts() != 0) { -// str += " +" + intToStr(getMaxEpRegenerationFromBoosts()); -// } - str += ")"; - } - } - - if (getAttackStrength () != 0) - { - if (str != "") - { - str += "\n"; - } - - str += - indent + lang.getString ("AttackStrenght", - (translatedValue == - true ? "" : "english")) + " +" + - intToStr (attackStrength); - if (attackStrengthIsMultiplier) - { - str += "%"; - } -// if(getAttackStrengthFromBoosts(NULL) != 0) { -// str += " +" + intToStr(getAttackStrengthFromBoosts(NULL)); -// } - } - - if (getAttackRange () != 0) - { - if (str != "") - { - str += "\n"; - } - - str += - indent + lang.getString ("AttackDistance", - (translatedValue == - true ? "" : "english")) + " +" + - intToStr (attackRange); - if (attackRangeIsMultiplier) - { - str += "%"; - } -// if(getAttackRangeFromBoosts(NULL) != 0) { -// str += " +" + intToStr(getAttackRangeFromBoosts(NULL)); -// } - } - - if (getArmor () != 0) - { - if (str != "") - { - str += "\n"; - } - - str += - indent + lang.getString ("Armor", - (translatedValue == - true ? "" : "english")) + " +" + - intToStr (armor); - if (armorIsMultiplier) - { - str += "%"; - } -// if(getArmorFromBoosts() != 0) { -// str += " +" + intToStr(getArmorFromBoosts()); -// } - } - - if (getMoveSpeed () != 0) - { - if (str != "") - { - str += "\n"; - } - - str += - indent + lang.getString ("WalkSpeed", - (translatedValue == - true ? "" : "english")) + " +" + - intToStr (moveSpeed); - if (moveSpeedIsMultiplier) - { - str += "%"; - } -// if(getMoveSpeedFromBoosts(NULL) != 0) { -// str += " +" + intToStr(getMoveSpeedFromBoosts(NULL)); -// } - } - - if (getProdSpeed () != 0) - { - if (str != "") - { - str += "\n"; - } - - str += - indent + lang.getString ("ProductionSpeed", - (translatedValue == - true ? "" : "english")) + " +" + - intToStr (prodSpeed); - if (prodSpeedIsMultiplier) - { - str += "%"; - } -// if(getProdSpeedFromBoosts(NULL) != 0) { -// str += " +" + intToStr(getProdSpeedFromBoosts(NULL)); -// } - } - - if (getAttackSpeed () != 0) - { - if (str != "") - { - str += "\n"; - } - - str += - indent + lang.getString ("AttackSpeed", - (translatedValue == - true ? "" : "english")) + " +" + - intToStr (attackSpeed); - if (attackSpeedIsMultiplier) - { - str += "%"; - } -// if(getAttackSpeedFromBoosts(NULL) != 0) { -// str += " +" + intToStr(getAttackSpeedFromBoosts(NULL)); -// } - } - if (str != "") - { - str += "\n"; - } - - return str; - } - -//void UpgradeTypeBase::saveGameBoost(XmlNode *rootNode) const { -// std::map mapTagReplacements; -// XmlNode *upgradeTypeBaseNode = rootNode->addChild("UpgradeTypeBaseBoost"); -// -// upgradeTypeBaseNode->addAttribute("upgradename",upgradename, mapTagReplacements); -// -//// int maxHp; -// upgradeTypeBaseNode->addAttribute("maxHp",intToStr(maxHp), mapTagReplacements); -//// bool maxHpIsMultiplier; -// upgradeTypeBaseNode->addAttribute("maxHpIsMultiplier",intToStr(maxHpIsMultiplier), mapTagReplacements); -//// int maxHpRegeneration; -// upgradeTypeBaseNode->addAttribute("maxHpRegeneration",intToStr(maxHpRegeneration), mapTagReplacements); -//// //bool maxHpRegenerationIsMultiplier; -//// -//// int sight; -// upgradeTypeBaseNode->addAttribute("sight",intToStr(sight), mapTagReplacements); -//// bool sightIsMultiplier; -// upgradeTypeBaseNode->addAttribute("sightIsMultiplier",intToStr(sightIsMultiplier), mapTagReplacements); -//// int maxEp; -// upgradeTypeBaseNode->addAttribute("maxEp",intToStr(maxEp), mapTagReplacements); -//// bool maxEpIsMultiplier; -// upgradeTypeBaseNode->addAttribute("maxEpIsMultiplier",intToStr(maxEpIsMultiplier), mapTagReplacements); -//// int maxEpRegeneration; -// upgradeTypeBaseNode->addAttribute("maxEpRegeneration",intToStr(maxEpRegeneration), mapTagReplacements); -//// //bool maxEpRegenerationIsMultiplier; -//// int armor; -// upgradeTypeBaseNode->addAttribute("armor",intToStr(armor), mapTagReplacements); -//// bool armorIsMultiplier; -// upgradeTypeBaseNode->addAttribute("armorIsMultiplier",intToStr(armorIsMultiplier), mapTagReplacements); -//// int attackStrength; -// upgradeTypeBaseNode->addAttribute("attackStrength",intToStr(attackStrength), mapTagReplacements); -//// bool attackStrengthIsMultiplier; -// upgradeTypeBaseNode->addAttribute("attackStrengthIsMultiplier",intToStr(attackStrengthIsMultiplier), mapTagReplacements); -//// std::map attackStrengthMultiplierValueList; -// for(std::map::const_iterator iterMap = attackStrengthMultiplierValueList.begin(); -// iterMap != attackStrengthMultiplierValueList.end(); ++iterMap) { -// XmlNode *attackStrengthMultiplierValueListNode = upgradeTypeBaseNode->addChild("attackStrengthMultiplierValueList"); -// -// attackStrengthMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); -// attackStrengthMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); -// } -//// int attackRange; -// upgradeTypeBaseNode->addAttribute("attackRange",intToStr(attackRange), mapTagReplacements); -//// bool attackRangeIsMultiplier; -// upgradeTypeBaseNode->addAttribute("attackRangeIsMultiplier",intToStr(attackRangeIsMultiplier), mapTagReplacements); -//// std::map attackRangeMultiplierValueList; -// for(std::map::const_iterator iterMap = attackRangeMultiplierValueList.begin(); -// iterMap != attackRangeMultiplierValueList.end(); ++iterMap) { -// XmlNode *attackRangeMultiplierValueListNode = upgradeTypeBaseNode->addChild("attackRangeMultiplierValueList"); -// -// attackRangeMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); -// attackRangeMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); -// } -// -//// int moveSpeed; -// upgradeTypeBaseNode->addAttribute("moveSpeed",intToStr(moveSpeed), mapTagReplacements); -//// bool moveSpeedIsMultiplier; -// upgradeTypeBaseNode->addAttribute("moveSpeedIsMultiplier",intToStr(moveSpeedIsMultiplier), mapTagReplacements); -//// std::map moveSpeedIsMultiplierValueList; -// for(std::map::const_iterator iterMap = moveSpeedIsMultiplierValueList.begin(); -// iterMap != moveSpeedIsMultiplierValueList.end(); ++iterMap) { -// XmlNode *moveSpeedIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("moveSpeedIsMultiplierValueList"); -// -// moveSpeedIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); -// moveSpeedIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); -// } -// -//// int prodSpeed; -// upgradeTypeBaseNode->addAttribute("prodSpeed",intToStr(prodSpeed), mapTagReplacements); -//// bool prodSpeedIsMultiplier; -// upgradeTypeBaseNode->addAttribute("prodSpeedIsMultiplier",intToStr(prodSpeedIsMultiplier), mapTagReplacements); -//// std::map prodSpeedProduceIsMultiplierValueList; -// for(std::map::const_iterator iterMap = prodSpeedProduceIsMultiplierValueList.begin(); -// iterMap != prodSpeedProduceIsMultiplierValueList.end(); ++iterMap) { -// XmlNode *prodSpeedProduceIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("prodSpeedProduceIsMultiplierValueList"); -// -// prodSpeedProduceIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); -// prodSpeedProduceIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); -// } -// -//// std::map prodSpeedUpgradeIsMultiplierValueList; -// for(std::map::const_iterator iterMap = prodSpeedUpgradeIsMultiplierValueList.begin(); -// iterMap != prodSpeedUpgradeIsMultiplierValueList.end(); ++iterMap) { -// XmlNode *prodSpeedUpgradeIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("prodSpeedUpgradeIsMultiplierValueList"); -// -// prodSpeedUpgradeIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); -// prodSpeedUpgradeIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); -// } -// -//// std::map prodSpeedMorphIsMultiplierValueList; -// for(std::map::const_iterator iterMap = prodSpeedMorphIsMultiplierValueList.begin(); -// iterMap != prodSpeedMorphIsMultiplierValueList.end(); ++iterMap) { -// XmlNode *prodSpeedMorphIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("prodSpeedMorphIsMultiplierValueList"); -// -// prodSpeedMorphIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); -// prodSpeedMorphIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); -// } -//} - - void UpgradeTypeBase::saveGame (XmlNode * rootNode) const - { - std::map < string, string > mapTagReplacements; - XmlNode *upgradeTypeBaseNode = rootNode->addChild ("UpgradeTypeBase"); - - upgradeTypeBaseNode->addAttribute ("upgradename", upgradename, - mapTagReplacements); - -//// int maxHp; -// upgradeTypeBaseNode->addAttribute("maxHp",intToStr(maxHp), mapTagReplacements); -//// bool maxHpIsMultiplier; -// upgradeTypeBaseNode->addAttribute("maxHpIsMultiplier",intToStr(maxHpIsMultiplier), mapTagReplacements); -//// int maxHpRegeneration; -// upgradeTypeBaseNode->addAttribute("maxHpRegeneration",intToStr(maxHpRegeneration), mapTagReplacements); -//// //bool maxHpRegenerationIsMultiplier; -//// -//// int sight; -// upgradeTypeBaseNode->addAttribute("sight",intToStr(sight), mapTagReplacements); -//// bool sightIsMultiplier; -// upgradeTypeBaseNode->addAttribute("sightIsMultiplier",intToStr(sightIsMultiplier), mapTagReplacements); -//// int maxEp; -// upgradeTypeBaseNode->addAttribute("maxEp",intToStr(maxEp), mapTagReplacements); -//// bool maxEpIsMultiplier; -// upgradeTypeBaseNode->addAttribute("maxEpIsMultiplier",intToStr(maxEpIsMultiplier), mapTagReplacements); -//// int maxEpRegeneration; -// upgradeTypeBaseNode->addAttribute("maxEpRegeneration",intToStr(maxEpRegeneration), mapTagReplacements); -//// //bool maxEpRegenerationIsMultiplier; -//// int armor; -// upgradeTypeBaseNode->addAttribute("armor",intToStr(armor), mapTagReplacements); -//// bool armorIsMultiplier; -// upgradeTypeBaseNode->addAttribute("armorIsMultiplier",intToStr(armorIsMultiplier), mapTagReplacements); -//// int attackStrength; -// upgradeTypeBaseNode->addAttribute("attackStrength",intToStr(attackStrength), mapTagReplacements); -//// bool attackStrengthIsMultiplier; -// upgradeTypeBaseNode->addAttribute("attackStrengthIsMultiplier",intToStr(attackStrengthIsMultiplier), mapTagReplacements); -//// std::map attackStrengthMultiplierValueList; -// for(std::map::const_iterator iterMap = attackStrengthMultiplierValueList.begin(); -// iterMap != attackStrengthMultiplierValueList.end(); ++iterMap) { -// XmlNode *attackStrengthMultiplierValueListNode = upgradeTypeBaseNode->addChild("attackStrengthMultiplierValueList"); -// -// attackStrengthMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); -// attackStrengthMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); -// } -//// int attackRange; -// upgradeTypeBaseNode->addAttribute("attackRange",intToStr(attackRange), mapTagReplacements); -//// bool attackRangeIsMultiplier; -// upgradeTypeBaseNode->addAttribute("attackRangeIsMultiplier",intToStr(attackRangeIsMultiplier), mapTagReplacements); -//// std::map attackRangeMultiplierValueList; -// for(std::map::const_iterator iterMap = attackRangeMultiplierValueList.begin(); -// iterMap != attackRangeMultiplierValueList.end(); ++iterMap) { -// XmlNode *attackRangeMultiplierValueListNode = upgradeTypeBaseNode->addChild("attackRangeMultiplierValueList"); -// -// attackRangeMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); -// attackRangeMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); -// } -// -//// int moveSpeed; -// upgradeTypeBaseNode->addAttribute("moveSpeed",intToStr(moveSpeed), mapTagReplacements); -//// bool moveSpeedIsMultiplier; -// upgradeTypeBaseNode->addAttribute("moveSpeedIsMultiplier",intToStr(moveSpeedIsMultiplier), mapTagReplacements); -//// std::map moveSpeedIsMultiplierValueList; -// for(std::map::const_iterator iterMap = moveSpeedIsMultiplierValueList.begin(); -// iterMap != moveSpeedIsMultiplierValueList.end(); ++iterMap) { -// XmlNode *moveSpeedIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("moveSpeedIsMultiplierValueList"); -// -// moveSpeedIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); -// moveSpeedIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); -// } -// -//// int prodSpeed; -// upgradeTypeBaseNode->addAttribute("prodSpeed",intToStr(prodSpeed), mapTagReplacements); -//// bool prodSpeedIsMultiplier; -// upgradeTypeBaseNode->addAttribute("prodSpeedIsMultiplier",intToStr(prodSpeedIsMultiplier), mapTagReplacements); -//// std::map prodSpeedProduceIsMultiplierValueList; -// for(std::map::const_iterator iterMap = prodSpeedProduceIsMultiplierValueList.begin(); -// iterMap != prodSpeedProduceIsMultiplierValueList.end(); ++iterMap) { -// XmlNode *prodSpeedProduceIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("prodSpeedProduceIsMultiplierValueList"); -// -// prodSpeedProduceIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); -// prodSpeedProduceIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); -// } -// -//// std::map prodSpeedUpgradeIsMultiplierValueList; -// for(std::map::const_iterator iterMap = prodSpeedUpgradeIsMultiplierValueList.begin(); -// iterMap != prodSpeedUpgradeIsMultiplierValueList.end(); ++iterMap) { -// XmlNode *prodSpeedUpgradeIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("prodSpeedUpgradeIsMultiplierValueList"); -// -// prodSpeedUpgradeIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); -// prodSpeedUpgradeIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); -// } -// -//// std::map prodSpeedMorphIsMultiplierValueList; -// for(std::map::const_iterator iterMap = prodSpeedMorphIsMultiplierValueList.begin(); -// iterMap != prodSpeedMorphIsMultiplierValueList.end(); ++iterMap) { -// XmlNode *prodSpeedMorphIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("prodSpeedMorphIsMultiplierValueList"); -// -// prodSpeedMorphIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); -// prodSpeedMorphIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); -// } - } - -//void UpgradeTypeBase::loadGameBoost(const XmlNode *rootNode) { -// const XmlNode *upgradeTypeBaseNode = rootNode->getChild("UpgradeTypeBaseBoost"); -// -// //description = upgradeTypeBaseNode->getAttribute("description")->getValue(); -// -// upgradename = upgradeTypeBaseNode->getAttribute("upgradename")->getValue(); -// -// // int maxHp; -// maxHp = upgradeTypeBaseNode->getAttribute("maxHp")->getIntValue(); -// // bool maxHpIsMultiplier; -// maxHpIsMultiplier = (upgradeTypeBaseNode->getAttribute("maxHpIsMultiplier")->getIntValue() != 0); -// // int maxHpRegeneration; -// maxHpRegeneration = upgradeTypeBaseNode->getAttribute("maxHpRegeneration")->getIntValue(); -// // //bool maxHpRegenerationIsMultiplier; -// // -// // int sight; -// sight = upgradeTypeBaseNode->getAttribute("sight")->getIntValue(); -// // bool sightIsMultiplier; -// sightIsMultiplier = (upgradeTypeBaseNode->getAttribute("sightIsMultiplier")->getIntValue() != 0); -// // int maxEp; -// maxEp = upgradeTypeBaseNode->getAttribute("maxEp")->getIntValue(); -// // bool maxEpIsMultiplier; -// maxEpIsMultiplier = (upgradeTypeBaseNode->getAttribute("maxEpIsMultiplier")->getIntValue() != 0); -// // int maxEpRegeneration; -// maxEpRegeneration = upgradeTypeBaseNode->getAttribute("maxEpRegeneration")->getIntValue(); -// // //bool maxEpRegenerationIsMultiplier; -// // int armor; -// armor = upgradeTypeBaseNode->getAttribute("armor")->getIntValue(); -// // bool armorIsMultiplier; -// armorIsMultiplier = (upgradeTypeBaseNode->getAttribute("armorIsMultiplier")->getIntValue() != 0); -// // int attackStrength; -// attackStrength = upgradeTypeBaseNode->getAttribute("attackStrength")->getIntValue(); -// // bool attackStrengthIsMultiplier; -// attackStrengthIsMultiplier = (upgradeTypeBaseNode->getAttribute("attackStrengthIsMultiplier")->getIntValue() != 0); -// // std::map attackStrengthMultiplierValueList; -// vector attackStrengthMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("attackStrengthMultiplierValueList"); -// for(unsigned int i = 0; i < attackStrengthMultiplierValueNodeList.size(); ++i) { -// XmlNode *node = attackStrengthMultiplierValueNodeList[i]; -// -// attackStrengthMultiplierValueList[node->getAttribute("key")->getValue()] = -// node->getAttribute("value")->getIntValue(); -// } -// // int attackRange; -// attackRange = upgradeTypeBaseNode->getAttribute("attackRange")->getIntValue(); -// // bool attackRangeIsMultiplier; -// attackRangeIsMultiplier = (upgradeTypeBaseNode->getAttribute("attackRangeIsMultiplier")->getIntValue() != 0); -// // std::map attackRangeMultiplierValueList; -// vector attackRangeMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("attackRangeMultiplierValueList"); -// for(unsigned int i = 0; i < attackRangeMultiplierValueNodeList.size(); ++i) { -// XmlNode *node = attackRangeMultiplierValueNodeList[i]; -// -// attackRangeMultiplierValueList[node->getAttribute("key")->getValue()] = -// node->getAttribute("value")->getIntValue(); -// } -// -// // int moveSpeed; -// moveSpeed = upgradeTypeBaseNode->getAttribute("moveSpeed")->getIntValue(); -// // bool moveSpeedIsMultiplier; -// moveSpeedIsMultiplier = (upgradeTypeBaseNode->getAttribute("moveSpeedIsMultiplier")->getIntValue() != 0); -// // std::map moveSpeedIsMultiplierValueList; -// vector moveSpeedIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("moveSpeedIsMultiplierValueList"); -// for(unsigned int i = 0; i < moveSpeedIsMultiplierValueNodeList.size(); ++i) { -// XmlNode *node = moveSpeedIsMultiplierValueNodeList[i]; -// -// moveSpeedIsMultiplierValueList[node->getAttribute("key")->getValue()] = -// node->getAttribute("value")->getIntValue(); -// } -// -// // int prodSpeed; -// prodSpeed = upgradeTypeBaseNode->getAttribute("prodSpeed")->getIntValue(); -// // bool prodSpeedIsMultiplier; -// prodSpeedIsMultiplier = (upgradeTypeBaseNode->getAttribute("prodSpeedIsMultiplier")->getIntValue() != 0); -// // std::map prodSpeedProduceIsMultiplierValueList; -// vector prodSpeedProduceIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("prodSpeedProduceIsMultiplierValueList"); -// for(unsigned int i = 0; i < prodSpeedProduceIsMultiplierValueNodeList.size(); ++i) { -// XmlNode *node = prodSpeedProduceIsMultiplierValueNodeList[i]; -// -// prodSpeedProduceIsMultiplierValueList[node->getAttribute("key")->getValue()] = -// node->getAttribute("value")->getIntValue(); -// } -// -// // std::map prodSpeedUpgradeIsMultiplierValueList; -// vector prodSpeedUpgradeIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("prodSpeedUpgradeIsMultiplierValueList"); -// for(unsigned int i = 0; i < prodSpeedUpgradeIsMultiplierValueNodeList.size(); ++i) { -// XmlNode *node = prodSpeedUpgradeIsMultiplierValueNodeList[i]; -// -// prodSpeedUpgradeIsMultiplierValueList[node->getAttribute("key")->getValue()] = -// node->getAttribute("value")->getIntValue(); -// } -// -// // std::map prodSpeedMorphIsMultiplierValueList; -// vector prodSpeedMorphIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("prodSpeedMorphIsMultiplierValueList"); -// for(unsigned int i = 0; i < prodSpeedMorphIsMultiplierValueNodeList.size(); ++i) { -// XmlNode *node = prodSpeedMorphIsMultiplierValueNodeList[i]; -// -// prodSpeedMorphIsMultiplierValueList[node->getAttribute("key")->getValue()] = -// node->getAttribute("value")->getIntValue(); -// } -//} - - const UpgradeType *UpgradeTypeBase::loadGame (const XmlNode * rootNode, - Faction * faction) - { - const XmlNode *upgradeTypeBaseNode = - rootNode->getChild ("UpgradeTypeBase"); - - //description = upgradeTypeBaseNode->getAttribute("description")->getValue(); - - string upgradename = - upgradeTypeBaseNode->getAttribute ("upgradename")->getValue (); - return faction->getType ()->getUpgradeType (upgradename); - // int maxHp; -// maxHp = upgradeTypeBaseNode->getAttribute("maxHp")->getIntValue(); -// // bool maxHpIsMultiplier; -// maxHpIsMultiplier = upgradeTypeBaseNode->getAttribute("maxHpIsMultiplier")->getIntValue(); -// // int maxHpRegeneration; -// maxHpRegeneration = upgradeTypeBaseNode->getAttribute("maxHpRegeneration")->getIntValue(); -// // //bool maxHpRegenerationIsMultiplier; -// // -// // int sight; -// sight = upgradeTypeBaseNode->getAttribute("sight")->getIntValue(); -// // bool sightIsMultiplier; -// sightIsMultiplier = upgradeTypeBaseNode->getAttribute("sightIsMultiplier")->getIntValue(); -// // int maxEp; -// maxEp = upgradeTypeBaseNode->getAttribute("maxEp")->getIntValue(); -// // bool maxEpIsMultiplier; -// maxEpIsMultiplier = upgradeTypeBaseNode->getAttribute("maxEpIsMultiplier")->getIntValue(); -// // int maxEpRegeneration; -// maxEpRegeneration = upgradeTypeBaseNode->getAttribute("maxEpRegeneration")->getIntValue(); -// // //bool maxEpRegenerationIsMultiplier; -// // int armor; -// armor = upgradeTypeBaseNode->getAttribute("armor")->getIntValue(); -// // bool armorIsMultiplier; -// armorIsMultiplier = upgradeTypeBaseNode->getAttribute("armorIsMultiplier")->getIntValue(); -// // int attackStrength; -// attackStrength = upgradeTypeBaseNode->getAttribute("attackStrength")->getIntValue(); -// // bool attackStrengthIsMultiplier; -// attackStrengthIsMultiplier = upgradeTypeBaseNode->getAttribute("attackStrengthIsMultiplier")->getIntValue(); -// // std::map attackStrengthMultiplierValueList; -// vector attackStrengthMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("attackStrengthMultiplierValueList"); -// for(unsigned int i = 0; i < attackStrengthMultiplierValueNodeList.size(); ++i) { -// XmlNode *node = attackStrengthMultiplierValueNodeList[i]; -// -// attackStrengthMultiplierValueList[node->getAttribute("key")->getValue()] = -// node->getAttribute("value")->getIntValue(); -// } -// // int attackRange; -// attackRange = upgradeTypeBaseNode->getAttribute("attackRange")->getIntValue(); -// // bool attackRangeIsMultiplier; -// attackRangeIsMultiplier = upgradeTypeBaseNode->getAttribute("attackRangeIsMultiplier")->getIntValue(); -// // std::map attackRangeMultiplierValueList; -// vector attackRangeMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("attackRangeMultiplierValueList"); -// for(unsigned int i = 0; i < attackRangeMultiplierValueNodeList.size(); ++i) { -// XmlNode *node = attackRangeMultiplierValueNodeList[i]; -// -// attackRangeMultiplierValueList[node->getAttribute("key")->getValue()] = -// node->getAttribute("value")->getIntValue(); -// } -// -// // int moveSpeed; -// moveSpeed = upgradeTypeBaseNode->getAttribute("moveSpeed")->getIntValue(); -// // bool moveSpeedIsMultiplier; -// moveSpeedIsMultiplier = upgradeTypeBaseNode->getAttribute("moveSpeedIsMultiplier")->getIntValue(); -// // std::map moveSpeedIsMultiplierValueList; -// vector moveSpeedIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("moveSpeedIsMultiplierValueList"); -// for(unsigned int i = 0; i < moveSpeedIsMultiplierValueNodeList.size(); ++i) { -// XmlNode *node = moveSpeedIsMultiplierValueNodeList[i]; -// -// moveSpeedIsMultiplierValueList[node->getAttribute("key")->getValue()] = -// node->getAttribute("value")->getIntValue(); -// } -// -// // int prodSpeed; -// prodSpeed = upgradeTypeBaseNode->getAttribute("prodSpeed")->getIntValue(); -// // bool prodSpeedIsMultiplier; -// prodSpeedIsMultiplier = upgradeTypeBaseNode->getAttribute("prodSpeedIsMultiplier")->getIntValue(); -// // std::map prodSpeedProduceIsMultiplierValueList; -// vector prodSpeedProduceIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("prodSpeedProduceIsMultiplierValueList"); -// for(unsigned int i = 0; i < prodSpeedProduceIsMultiplierValueNodeList.size(); ++i) { -// XmlNode *node = prodSpeedProduceIsMultiplierValueNodeList[i]; -// -// prodSpeedProduceIsMultiplierValueList[node->getAttribute("key")->getValue()] = -// node->getAttribute("value")->getIntValue(); -// } -// -// // std::map prodSpeedUpgradeIsMultiplierValueList; -// vector prodSpeedUpgradeIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("prodSpeedUpgradeIsMultiplierValueList"); -// for(unsigned int i = 0; i < prodSpeedUpgradeIsMultiplierValueNodeList.size(); ++i) { -// XmlNode *node = prodSpeedUpgradeIsMultiplierValueNodeList[i]; -// -// prodSpeedUpgradeIsMultiplierValueList[node->getAttribute("key")->getValue()] = -// node->getAttribute("value")->getIntValue(); -// } -// -// // std::map prodSpeedMorphIsMultiplierValueList; -// vector prodSpeedMorphIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("prodSpeedMorphIsMultiplierValueList"); -// for(unsigned int i = 0; i < prodSpeedMorphIsMultiplierValueNodeList.size(); ++i) { -// XmlNode *node = prodSpeedMorphIsMultiplierValueNodeList[i]; -// -// prodSpeedMorphIsMultiplierValueList[node->getAttribute("key")->getValue()] = -// node->getAttribute("value")->getIntValue(); -// } - } - -// ==================== misc ==================== - - string UpgradeType::getName (bool translatedValue) const - { - if (translatedValue == false) - return name; - - Lang & lang = Lang::getInstance (); - return lang.getTechTreeString ("UpgradeTypeName_" + name, - name.c_str ()); - } - - string UpgradeType::getTagName (string tag, bool translatedValue) const - { - if (translatedValue == false) - return tag; - - Lang & lang = Lang::getInstance (); - return lang.getTechTreeString ("TagName_" + tag, tag.c_str ()); - } - - string UpgradeType::getReqDesc (bool translatedValue) const - { - Lang & lang = Lang::getInstance (); - string str = ProducibleType::getReqDesc (translatedValue); - string indent = " "; - if (!effects.empty () || !tags.empty ()) - { - str += - "\n" + lang.getString ("Upgrades", - (translatedValue == - true ? "" : "english")) + "\n"; - } - str += UpgradeTypeBase::getDesc (translatedValue); - if (!effects.empty () || !tags.empty ()) - { - str += - lang.getString ("AffectedUnits", - (translatedValue == true ? "" : "english")) + "\n"; - - // We want the output to be sorted, so convert the set to a vector and sort that - std::vector < const UnitType *>outputUnits (effects.begin (), - effects.end ()); - std::sort (outputUnits.begin (), outputUnits.end (), - UnitTypeSorter ()); - - vector < const UnitType *>::iterator unitIter; - for (unitIter = outputUnits.begin (); unitIter != outputUnits.end (); - ++unitIter) - { - const UnitType *unit = *unitIter; - str += indent + unit->getName (translatedValue) + "\n"; - } - - // Do the same for tags - std::vector < string > outputTags (tags.begin (), tags.end ()); - std::sort (outputTags.begin (), outputTags.end ()); - - vector < string >::iterator tagIter; - for (tagIter = outputTags.begin (); tagIter != outputTags.end (); - ++tagIter) - { - string tag = *tagIter; - str += - indent + lang.getString ("TagDesc", - (translatedValue == - true ? "" : "english")) + " " + - getTagName (tag, translatedValue) + "\n"; - } - } - return str; - } - - void UpgradeType::preLoad (const string & dir) - { - name = lastDir (dir); - } - - void UpgradeType::load (const string & dir, const TechTree * techTree, - const FactionType * factionType, - Checksum * checksum, Checksum * techtreeChecksum, - std::map < string, vector < pair < string, - string > > >&loadedFileList, bool validationMode) - { - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - - char szBuf[8096] = ""; - snprintf (szBuf, 8096, - Lang::getInstance (). - getString ("LogScreenGameLoadingUpgradeType", "", - true).c_str (), - formatString (this->getName (true)).c_str ()); - Logger::getInstance ().add (szBuf, true); - - string currentPath = dir; - endPathWithSlash (currentPath); - string path = currentPath + name + ".xml"; - string sourceXMLFile = path; - - try - { - checksum->addFile (path); - techtreeChecksum->addFile (path); - - XmlTree xmlTree; - std::map < string, string > mapExtraTagReplacementValues; - mapExtraTagReplacementValues["$COMMONDATAPATH"] = - techTree->getPath () + "/commondata/"; - xmlTree.load (path, - Properties:: - getTagReplacementValues - (&mapExtraTagReplacementValues)); - loadedFileList[path].push_back (make_pair (currentPath, currentPath)); - const XmlNode *upgradeNode = xmlTree.getRootNode (); - - //image - image = NULL; // Not used for upgrade types - - //image cancel - cancelImage = NULL; // Not used for upgrade types - - //upgrade time - const XmlNode *upgradeTimeNode = upgradeNode->getChild ("time"); - productionTime = - upgradeTimeNode->getAttribute ("value")->getIntValue (); - - std::map < string, int >sortedItems; - - //unit requirements - bool hasDup = false; - const XmlNode *unitRequirementsNode = - upgradeNode->getChild ("unit-requirements"); - for (int i = 0; i < (int) unitRequirementsNode->getChildCount (); ++i) - { - const XmlNode *unitNode = - unitRequirementsNode->getChild ("unit", i); - string name = - unitNode->getAttribute ("name")->getRestrictedValue (); - - if (sortedItems.find (name) != sortedItems.end ()) - { - hasDup = true; - } - - sortedItems[name] = 0; - } - - if (hasDup) - { - printf - ("WARNING, upgrade type [%s] has one or more duplicate unit requirements\n", - this->getName ().c_str ()); - } - - for (std::map < string, int >::iterator iterMap = - sortedItems.begin (); iterMap != sortedItems.end (); ++iterMap) - { - unitReqs.push_back (factionType->getUnitType (iterMap->first)); - } - sortedItems.clear (); - hasDup = false; - - //upgrade requirements - const XmlNode *upgradeRequirementsNode = - upgradeNode->getChild ("upgrade-requirements"); - for (int i = 0; i < (int) upgradeRequirementsNode->getChildCount (); - ++i) - { - const XmlNode *upgradeReqNode = - upgradeRequirementsNode->getChild ("upgrade", i); - string name = - upgradeReqNode->getAttribute ("name")->getRestrictedValue (); - - if (sortedItems.find (name) != sortedItems.end ()) - { - hasDup = true; - } - - sortedItems[name] = 0; - } - - if (hasDup) - { - printf - ("WARNING, upgrade type [%s] has one or more duplicate upgrade requirements\n", - this->getName ().c_str ()); - } - - for (std::map < string, int >::iterator iterMap = - sortedItems.begin (); iterMap != sortedItems.end (); ++iterMap) - { - upgradeReqs.push_back (factionType-> - getUpgradeType (iterMap->first)); - } - sortedItems.clear (); - hasDup = false; - - //resource requirements - int index = 0; - const XmlNode *resourceRequirementsNode = - upgradeNode->getChild ("resource-requirements"); - - costs.resize (resourceRequirementsNode->getChildCount ()); - for (int i = 0; i < (int) costs.size (); ++i) - { - const XmlNode *resourceNode = - resourceRequirementsNode->getChild ("resource", i); - string name = - resourceNode->getAttribute ("name")->getRestrictedValue (); - int amount = resourceNode->getAttribute ("amount")->getIntValue (); - - if (sortedItems.find (name) != sortedItems.end ()) - { - hasDup = true; - } - - sortedItems[name] = amount; - } - - //if(hasDup || sortedItems.size() != costs.size()) printf("Found duplicate resource requirement, costs.size() = %d sortedItems.size() = %d\n",costs.size(),sortedItems.size()); - - if (hasDup) - { - printf - ("WARNING, upgrade type [%s] has one or more duplicate resource requirements\n", - this->getName ().c_str ()); - } - - if (sortedItems.size () < costs.size ()) - { - costs.resize (sortedItems.size ()); - } - - index = 0; - for (std::map < string, int >::iterator iterMap = - sortedItems.begin (); iterMap != sortedItems.end (); ++iterMap) - { - try - { - costs[index].init (techTree->getResourceType (iterMap->first), - iterMap->second); - index++; - } - catch (megaglest_runtime_error & ex) - { - if (validationMode == false) - { - throw; - } - else - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\nFor UpgradeType: %s Cost: %d\n", - extractFileFromDirectoryPath - (__FILE__).c_str (), __FUNCTION__, - __LINE__, ex.what (), name.c_str (), - iterMap->second); - } - } - - } - sortedItems.clear (); - //hasDup = false; - - //effects -- get list of affected units - const XmlNode *effectsNode = upgradeNode->getChild ("effects"); - vector < XmlNode * >unitNodes = effectsNode->getChildList ("unit"); - for (size_t i = 0; i < unitNodes.size (); ++i) - { - const XmlNode *unitNode = unitNodes.at (i); - string name = - unitNode->getAttribute ("name")->getRestrictedValue (); - - effects.insert (factionType->getUnitType (name)); - } - - //effects -- convert tags into units - vector < XmlNode * >tagNodes = effectsNode->getChildList ("tag"); - for (size_t i = 0; i < tagNodes.size (); ++i) - { - const XmlNode *tagNode = tagNodes.at (i); - string name = tagNode->getAttribute ("name")->getRestrictedValue (); - tags.insert (name); - } - - //values - UpgradeTypeBase::load (upgradeNode, name); - } - catch (megaglest_runtime_error & ex) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - extractFileFromDirectoryPath (__FILE__). - c_str (), __FUNCTION__, __LINE__, - ex.what ()); - throw megaglest_runtime_error ("Error loading UpgradeType: " + - currentPath + "\nMessage: " + - ex.what (), !ex.wantStackTrace ()); - } - catch (const exception & e) - { - SystemFlags::OutputDebug (SystemFlags::debugError, - "In [%s::%s Line: %d] Error [%s]\n", - __FILE__, __FUNCTION__, __LINE__, - e.what ()); - throw megaglest_runtime_error ("Error loading UpgradeType: " + - currentPath + "\n" + e.what ()); - } - - if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). - enabled) - SystemFlags::OutputDebug (SystemFlags::debugSystem, - "In [%s::%s Line: %d]\n", __FILE__, - __FUNCTION__, __LINE__); - } - - bool UpgradeType::isAffected (const UnitType * unitType) const - { - if (std::find (effects.begin (), effects.end (), unitType) != - effects.end ()) - return true; - - const set < string > unitTags = unitType->getTags (); - set < string > intersect; - set_intersection (tags.begin (), tags.end (), unitTags.begin (), - unitTags.end (), std::inserter (intersect, - intersect.begin ())); - if (!intersect.empty ()) - return true; - - return false; - } - -//void UpgradeType::saveGame(XmlNode *rootNode) const { -// UpgradeTypeBase::saveGame(rootNode); -// ProducibleType::saveGame(rootNode); -// -// std::map mapTagReplacements; -// XmlNode *upgradeTypeNode = rootNode->addChild("UpgradeType"); -// -// //upgradeTypeNode->addAttribute("maxHp",intToStr(maxHp), mapTagReplacements); -// //vector effects; -// for(unsigned int i = 0; i < effects.size(); ++i) { -// XmlNode *unitTypeNode = rootNode->addChild("UnitType"); -// -// const UnitType *ut = effects[i]; -// unitTypeNode->addAttribute("name",ut->getName(), mapTagReplacements); -// } -//} -// -//void UpgradeType::loadGame(const XmlNode *rootNode, Faction *faction) { -// //UpgradeTypeBase::loadGame(rootNode); -// //ProducibleType::loadGame(rootNode); -// -// //const XmlNode *upgradeTypeNode = rootNode->getChild("UpgradeType"); -// -// //maxHp = upgradeTypeNode->getAttribute("maxHp")->getIntValue(); -// -//// vector unitTypeNodeList = upgradeTypeNode->getChildList("UnitType"); -//// for(unsigned int i = 0; i < unitTypeNodeList.size(); ++i) { -//// XmlNode *node = unitTypeNodeList[i]; -//// } -//} - -// =============================== -// class TotalUpgrade -// =============================== - - TotalUpgrade::TotalUpgrade () - { - reset (); - } - - void TotalUpgrade::reset () - { - maxHp = 0; - maxHpIsMultiplier = false; - maxHpRegeneration = 0; - - maxEp = 0; - maxEpIsMultiplier = false; - maxEpRegeneration = 0; - - sight = 0; - sightIsMultiplier = false; - - armor = 0; - armorIsMultiplier = false; - - attackStrength = 0; - attackStrengthIsMultiplier = false; - - attackRange = 0; - attackRangeIsMultiplier = false; - - moveSpeed = 0; - moveSpeedIsMultiplier = false; - - prodSpeed = 0; - prodSpeedIsMultiplier = false; - - attackSpeed = 0; - attackSpeedIsMultiplier = false; - - boostUpgradeBase = NULL; - boostUpgradeSourceUnit = -1; - boostUpgradeDestUnit = -1; - } - - void TotalUpgrade::sum (const UpgradeTypeBase * ut, const Unit * unit, - bool boostMode) - { - maxHpIsMultiplier = ut->getMaxHpIsMultiplier (); - sightIsMultiplier = ut->getSightIsMultiplier (); - maxEpIsMultiplier = ut->getMaxEpIsMultiplier (); - armorIsMultiplier = ut->getArmorIsMultiplier (); - attackStrengthIsMultiplier = ut->getAttackStrengthIsMultiplier (); - attackRangeIsMultiplier = ut->getAttackRangeIsMultiplier (); - moveSpeedIsMultiplier = ut->getMoveSpeedIsMultiplier (); - prodSpeedIsMultiplier = ut->getProdSpeedIsMultiplier (); - attackSpeedIsMultiplier = ut->getAttackSpeedIsMultiplier (); - - if (ut->getMaxHpIsMultiplier () == true) - { - //printf("#1 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp()); - int newValue = - ((double) unit->getHp () * - ((double) ut->getMaxHp () / (double) 100)); - if (boostMode) - { - maxHp = newValue; - } - else - { - maxHp += newValue; - } - if (ut->getMaxHpRegeneration () != 0) - { - newValue = - ((double) unit->getType ()->getHpRegeneration () + - ((double) max (maxHp, unit->getHp ()) * - ((double) ut->getMaxHpRegeneration () / (double) 100))); - if (boostMode) - { - maxHpRegeneration = newValue; - } - else - { - maxHpRegeneration += newValue; - } - } - //printf("#1.1 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp()); - } - else - { - //printf("#2 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp()); - int newValue = ut->getMaxHp (); - if (boostMode) - { - maxHp = newValue; - } - else - { - maxHp += newValue; - } - - if (ut->getMaxHpRegeneration () != 0) - { - newValue = ut->getMaxHpRegeneration (); - if (boostMode) - { - maxHpRegeneration = newValue; - } - else - { - maxHpRegeneration += newValue; - } - } - } - - if (ut->getMaxEpIsMultiplier () == true) - { - int newValue = - ((double) unit->getEp () * - ((double) ut->getMaxEp () / (double) 100)); - if (boostMode) - { - maxEp = newValue; - } - else - { - maxEp += newValue; - } - - if (ut->getMaxEpRegeneration () != 0) - { - newValue = - ((double) unit->getType ()->getEpRegeneration () + - ((double) max (maxEp, unit->getEp ()) * - ((double) ut->getMaxEpRegeneration () / (double) 100))); - if (boostMode) - { - maxEpRegeneration = newValue; - } - else - { - maxEpRegeneration += newValue; - } - } - } - else - { - int newValue = ut->getMaxEp (); - if (boostMode) - { - maxEp = newValue; - } - else - { - maxEp += newValue; - } - - if (ut->getMaxEpRegeneration () != 0) - { - newValue = ut->getMaxEpRegeneration (); - if (boostMode) - { - maxEpRegeneration = newValue; - } - else - { - maxEpRegeneration += newValue; - } - } - } - - if (ut->getSightIsMultiplier () == true) - { - int newValue = - ((double) unit->getType ()->getSight () * - ((double) ut->getSight () / (double) 100)); - if (boostMode) - { - sight = newValue; - } - else - { - sight += newValue; - } - } - else - { - int newValue = ut->getSight (); - if (boostMode) - { - sight = newValue; - } - else - { - sight += newValue; - } - } - - if (ut->getArmorIsMultiplier () == true) - { - int newValue = - ((double) unit->getType ()->getArmor () * - ((double) ut->getArmor () / (double) 100)); - if (boostMode) - { - armor = newValue; - } - else - { - armor += newValue; - } - } - else - { - int newValue = ut->getArmor (); - if (boostMode) - { - armor = newValue; - } - else - { - armor += newValue; - } - } - - if (ut->getAttackStrengthIsMultiplier () == true) - { - for (unsigned int i = 0; - i < (unsigned int) unit->getType ()->getSkillTypeCount (); ++i) - { - const SkillType *skillType = unit->getType ()->getSkillType (i); - const AttackSkillType *ast = - dynamic_cast < const AttackSkillType * >(skillType); - if (ast != NULL) - { - int newValue = - ((double) ast->getAttackStrength () * - ((double) ut->getAttackStrength (NULL) / (double) 100)); - if (boostMode) - { - attackStrengthMultiplierValueList[ast->getName ()] = newValue; - } - else - { - attackStrengthMultiplierValueList[ast->getName ()] += newValue; - } - } - } - } - else - { - int newValue = ut->getAttackStrength (NULL); - if (boostMode) - { - attackStrength = newValue; - } - else - { - attackStrength += newValue; - } - } - - if (ut->getAttackRangeIsMultiplier () == true) - { - for (unsigned int i = 0; - i < (unsigned int) unit->getType ()->getSkillTypeCount (); ++i) - { - const SkillType *skillType = unit->getType ()->getSkillType (i); - const AttackSkillType *ast = - dynamic_cast < const AttackSkillType * >(skillType); - if (ast != NULL) - { - int newValue = - ((double) ast->getAttackRange () * - ((double) ut->getAttackRange (NULL) / (double) 100)); - if (boostMode) - { - attackRangeMultiplierValueList[ast->getName ()] = newValue; - } - else - { - attackRangeMultiplierValueList[ast->getName ()] += newValue; - } - } - } - } - else - { - int newValue = ut->getAttackRange (NULL); - if (boostMode) - { - attackRange = newValue; - } - else - { - attackRange += newValue; - } - } - - if (ut->getMoveSpeedIsMultiplier () == true) - { - for (unsigned int i = 0; - i < (unsigned int) unit->getType ()->getSkillTypeCount (); ++i) - { - const SkillType *skillType = unit->getType ()->getSkillType (i); - const MoveSkillType *mst = - dynamic_cast < const MoveSkillType * >(skillType); - if (mst != NULL) - { - int newValue = - ((double) mst->getSpeed () * - ((double) ut->getMoveSpeed (NULL) / (double) 100)); - if (boostMode) - { - moveSpeedIsMultiplierValueList[mst->getName ()] = newValue; - } - else - { - moveSpeedIsMultiplierValueList[mst->getName ()] += newValue; - } - } - } - } - else - { - int newValue = ut->getMoveSpeed (NULL); - if (boostMode) - { - moveSpeed = newValue; - } - else - { - moveSpeed += newValue; - } - } - - if (ut->getProdSpeedIsMultiplier () == true) - { - for (unsigned int i = 0; - i < (unsigned int) unit->getType ()->getSkillTypeCount (); ++i) - { - const SkillType *skillType = unit->getType ()->getSkillType (i); - const ProduceSkillType *pst = - dynamic_cast < const ProduceSkillType * >(skillType); - if (pst != NULL) - { - int newValue = - ((double) pst->getSpeed () * - ((double) ut->getProdSpeed (NULL) / (double) 100)); - if (boostMode) - { - prodSpeedProduceIsMultiplierValueList[pst->getName ()] = - newValue; - } - else - { - prodSpeedProduceIsMultiplierValueList[pst->getName ()] += - newValue; - } - } - const UpgradeSkillType *ust = - dynamic_cast < const UpgradeSkillType * >(skillType); - if (ust != NULL) - { - int newValue = - ((double) ust->getSpeed () * - ((double) ut->getProdSpeed (NULL) / (double) 100)); - if (boostMode) - { - prodSpeedUpgradeIsMultiplierValueList[ust->getName ()] = - newValue; - } - else - { - prodSpeedUpgradeIsMultiplierValueList[ust->getName ()] += - newValue; - } - } - const MorphSkillType *mst = - dynamic_cast < const MorphSkillType * >(skillType); - if (mst != NULL) - { - int newValue = - ((double) mst->getSpeed () * - ((double) ut->getProdSpeed (NULL) / (double) 100)); - if (boostMode) - { - prodSpeedMorphIsMultiplierValueList[mst->getName ()] = newValue; - } - else - { - prodSpeedMorphIsMultiplierValueList[mst->getName ()] += - newValue; - } - } - } - } - else - { - int newValue = ut->getProdSpeed (NULL); - if (boostMode) - { - prodSpeed = newValue; - } - else - { - prodSpeed += newValue; - } - } - - if (ut->getAttackSpeedIsMultiplier () == true) - { - for (unsigned int i = 0; - i < (unsigned int) unit->getType ()->getSkillTypeCount (); ++i) - { - const SkillType *skillType = unit->getType ()->getSkillType (i); - const AttackSkillType *ast = - dynamic_cast < const AttackSkillType * >(skillType); - if (ast != NULL) - { - int newValue = - ((double) ast->getSpeed () * - ((double) ut->getAttackSpeed (NULL) / (double) 100)); - if (boostMode) - { - attackSpeedIsMultiplierValueList[ast->getName ()] = newValue; - } - else - { - attackSpeedIsMultiplierValueList[ast->getName ()] += newValue; - } - } - } - } - else - { - int newValue = ut->getAttackSpeed (NULL); - if (boostMode) - { - attackSpeed = newValue; - } - else - { - attackSpeed += newValue; - } - } - } - - void TotalUpgrade::apply (int sourceUnitId, const UpgradeTypeBase * ut, - const Unit * unit) - { - //sum(ut, unit); - - //printf("====> About to apply boost: %s\nTo unit: %d\n\n",ut->toString().c_str(),unit->getId()); - TotalUpgrade *boostUpgrade = new TotalUpgrade (); - boostUpgrade->copyDataFrom (this); - boostUpgrade->boostUpgradeBase = ut; - boostUpgrade->boostUpgradeSourceUnit = sourceUnitId; - boostUpgrade->boostUpgradeDestUnit = unit->getId (); - - boostUpgrade->sum (ut, unit, true); - boostUpgrades.push_back (boostUpgrade); - } - - void TotalUpgrade::deapply (int sourceUnitId, const UpgradeTypeBase * ut, - int destUnitId) - { - //printf("<****** About to de-apply boost: %s\nTo unit: %d\n\n",ut->toString().c_str(),destUnitId); - - bool removedBoost = false; - for (unsigned int index = 0; index < boostUpgrades.size (); ++index) - { - TotalUpgrade *boost = boostUpgrades[index]; - if (boost->boostUpgradeSourceUnit == sourceUnitId && - boost->boostUpgradeBase->getUpgradeName () == - ut->getUpgradeName () - && boost->boostUpgradeDestUnit == destUnitId) - { - - boostUpgrades.erase (boostUpgrades.begin () + index); - delete boost; - removedBoost = true; - - //printf("de-apply boost FOUND!\n"); - break; - } - } - if (removedBoost == false) - { - printf - ("\n\n!!!!!! de-apply boost NOT FOUND for sourceUnitId = %d, destUnitId = %d\n%s\n\nCurrent Boosts:\n", - sourceUnitId, destUnitId, ut->toString ().c_str ()); - for (unsigned int index = 0; index < boostUpgrades.size (); ++index) - { - TotalUpgrade *boost = boostUpgrades[index]; - printf ("\nBoost #%u\n%s\n", index, boost->toString ().c_str ()); - } - } - } - - int TotalUpgrade::getMaxHp () const - { - return maxHp + getMaxHpFromBoosts (); - } - int TotalUpgrade::getMaxHpFromBoosts () const - { - int result = 0; - for (unsigned int index = 0; index < boostUpgrades.size (); ++index) - { - TotalUpgrade *boost = boostUpgrades[index]; - result += boost->getMaxHp (); - } - return result; - } - int TotalUpgrade::getMaxHpRegeneration () const - { - return maxHpRegeneration + getMaxHpRegenerationFromBoosts (); - } - int TotalUpgrade::getMaxHpRegenerationFromBoosts () const - { - int result = 0; - for (unsigned int index = 0; index < boostUpgrades.size (); ++index) - { - TotalUpgrade *boost = boostUpgrades[index]; - result += boost->getMaxHpRegeneration (); - } - return result; - } - int TotalUpgrade::getSight () const - { - return sight + getSightFromBoosts (); - } - int TotalUpgrade::getSightFromBoosts () const - { - int result = 0; - for (unsigned int index = 0; index < boostUpgrades.size (); ++index) - { - TotalUpgrade *boost = boostUpgrades[index]; - result += boost->getSight (); - } - return result; - } - int TotalUpgrade::getMaxEp () const - { - return maxEp + getMaxEpFromBoosts (); - } - int TotalUpgrade::getMaxEpFromBoosts () const - { - int result = 0; - for (unsigned int index = 0; index < boostUpgrades.size (); ++index) - { - TotalUpgrade *boost = boostUpgrades[index]; - result += boost->getMaxEp (); - } - return result; - } - - int TotalUpgrade::getMaxEpRegeneration () const - { - return maxEpRegeneration + getMaxEpRegenerationFromBoosts (); - } - int TotalUpgrade::getMaxEpRegenerationFromBoosts () const - { - int result = 0; - for (unsigned int index = 0; index < boostUpgrades.size (); ++index) - { - TotalUpgrade *boost = boostUpgrades[index]; - result += boost->getMaxEpRegeneration (); - } - return result; - } - - int TotalUpgrade::getArmor () const - { - return armor + getArmorFromBoosts (); - } - int TotalUpgrade::getArmorFromBoosts () const - { - int result = 0; - for (unsigned int index = 0; index < boostUpgrades.size (); ++index) - { - TotalUpgrade *boost = boostUpgrades[index]; - result += boost->getArmor (); - } - return result; - } - - int TotalUpgrade::getAttackStrength (const AttackSkillType * st) const - { - return UpgradeTypeBase::getAttackStrength (st) + - getAttackStrengthFromBoosts (st); - } - int TotalUpgrade::getAttackStrengthFromBoosts (const AttackSkillType * st) const - { - int result = 0; - for (unsigned int index = 0; index < boostUpgrades.size (); ++index) - { - TotalUpgrade *boost = boostUpgrades[index]; - result += boost->getAttackStrength (st); - } - return result; - } - - int TotalUpgrade::getAttackRange (const AttackSkillType * st) const - { - return UpgradeTypeBase::getAttackRange (st) + - getAttackRangeFromBoosts (st); - } - int TotalUpgrade::getAttackRangeFromBoosts (const AttackSkillType * st) const - { - int result = 0; - for (unsigned int index = 0; index < boostUpgrades.size (); ++index) - { - TotalUpgrade *boost = boostUpgrades[index]; - result += boost->getAttackRange (st); - } - return result; - } - - int TotalUpgrade::getMoveSpeed (const MoveSkillType * st) const - { - return UpgradeTypeBase::getMoveSpeed (st) + getMoveSpeedFromBoosts (st); - } - int TotalUpgrade::getMoveSpeedFromBoosts (const MoveSkillType * st) const - { - int result = 0; - for (unsigned int index = 0; index < boostUpgrades.size (); ++index) - { - TotalUpgrade *boost = boostUpgrades[index]; - result += boost->getMoveSpeed (st); - } - return result; - } - - int TotalUpgrade::getProdSpeed (const SkillType * st) const - { - return UpgradeTypeBase::getProdSpeed (st) + getProdSpeedFromBoosts (st); - } - int TotalUpgrade::getProdSpeedFromBoosts (const SkillType * st) const - { - int result = 0; - for (unsigned int index = 0; index < boostUpgrades.size (); ++index) - { - TotalUpgrade *boost = boostUpgrades[index]; - result += boost->getProdSpeed (st); - } - return result; - } - - int TotalUpgrade::getAttackSpeed (const AttackSkillType * st) const - { - return UpgradeTypeBase::getAttackSpeed (st) + - getAttackSpeedFromBoosts (st); - } - int TotalUpgrade::getAttackSpeedFromBoosts (const AttackSkillType * st) const - { - int result = 0; - for (unsigned int index = 0; index < boostUpgrades.size (); ++index) - { - TotalUpgrade *boost = boostUpgrades[index]; - result += boost->getAttackSpeed (st); - } - return result; - } - - void TotalUpgrade::incLevel (const UnitType * ut) - { - maxHp += ut->getMaxHp () * 50 / 100; - maxEp += ut->getMaxEp () * 50 / 100; - sight += ut->getSight () * 20 / 100; - armor += ut->getArmor () * 50 / 100; - - for (unsigned int index = 0; index < boostUpgrades.size (); ++index) - { - TotalUpgrade *boost = boostUpgrades[index]; - boost->copyDataFrom (this); - } - } - - void TotalUpgrade::saveGame (XmlNode * rootNode) const - { - std::map < string, string > mapTagReplacements; - XmlNode *upgradeTypeBaseNode = rootNode->addChild ("TotalUpgrade"); - -// int maxHp; - upgradeTypeBaseNode->addAttribute ("maxHp", intToStr (maxHp), - mapTagReplacements); -// bool maxHpIsMultiplier; - upgradeTypeBaseNode->addAttribute ("maxHpIsMultiplier", - intToStr (maxHpIsMultiplier), - mapTagReplacements); -// int maxHpRegeneration; - upgradeTypeBaseNode->addAttribute ("maxHpRegeneration", - intToStr (maxHpRegeneration), - mapTagReplacements); -// //bool maxHpRegenerationIsMultiplier; -// -// int sight; - upgradeTypeBaseNode->addAttribute ("sight", intToStr (sight), - mapTagReplacements); -// bool sightIsMultiplier; - upgradeTypeBaseNode->addAttribute ("sightIsMultiplier", - intToStr (sightIsMultiplier), - mapTagReplacements); -// int maxEp; - upgradeTypeBaseNode->addAttribute ("maxEp", intToStr (maxEp), - mapTagReplacements); -// bool maxEpIsMultiplier; - upgradeTypeBaseNode->addAttribute ("maxEpIsMultiplier", - intToStr (maxEpIsMultiplier), - mapTagReplacements); -// int maxEpRegeneration; - upgradeTypeBaseNode->addAttribute ("maxEpRegeneration", - intToStr (maxEpRegeneration), - mapTagReplacements); -// //bool maxEpRegenerationIsMultiplier; -// int armor; - upgradeTypeBaseNode->addAttribute ("armor", intToStr (armor), - mapTagReplacements); -// bool armorIsMultiplier; - upgradeTypeBaseNode->addAttribute ("armorIsMultiplier", - intToStr (armorIsMultiplier), - mapTagReplacements); -// int attackStrength; - upgradeTypeBaseNode->addAttribute ("attackStrength", - intToStr (attackStrength), - mapTagReplacements); -// bool attackStrengthIsMultiplier; - upgradeTypeBaseNode->addAttribute ("attackStrengthIsMultiplier", - intToStr - (attackStrengthIsMultiplier), - mapTagReplacements); -// std::map attackStrengthMultiplierValueList; - for (std::map < string, int >::const_iterator iterMap = - attackStrengthMultiplierValueList.begin (); - iterMap != attackStrengthMultiplierValueList.end (); ++iterMap) - { - XmlNode *attackStrengthMultiplierValueListNode = - upgradeTypeBaseNode->addChild ("attackStrengthMultiplierValueList"); - - attackStrengthMultiplierValueListNode->addAttribute ("key", - iterMap->first, - mapTagReplacements); - attackStrengthMultiplierValueListNode->addAttribute ("value", - intToStr - (iterMap-> - second), - mapTagReplacements); - } -// int attackRange; - upgradeTypeBaseNode->addAttribute ("attackRange", - intToStr (attackRange), - mapTagReplacements); -// bool attackRangeIsMultiplier; - upgradeTypeBaseNode->addAttribute ("attackRangeIsMultiplier", - intToStr (attackRangeIsMultiplier), - mapTagReplacements); -// std::map attackRangeMultiplierValueList; - for (std::map < string, int >::const_iterator iterMap = - attackRangeMultiplierValueList.begin (); - iterMap != attackRangeMultiplierValueList.end (); ++iterMap) - { - XmlNode *attackRangeMultiplierValueListNode = - upgradeTypeBaseNode->addChild ("attackRangeMultiplierValueList"); - - attackRangeMultiplierValueListNode->addAttribute ("key", - iterMap->first, - mapTagReplacements); - attackRangeMultiplierValueListNode->addAttribute ("value", - intToStr (iterMap-> - second), - mapTagReplacements); - } - -// int moveSpeed; - upgradeTypeBaseNode->addAttribute ("moveSpeed", intToStr (moveSpeed), - mapTagReplacements); -// bool moveSpeedIsMultiplier; - upgradeTypeBaseNode->addAttribute ("moveSpeedIsMultiplier", - intToStr (moveSpeedIsMultiplier), - mapTagReplacements); -// std::map moveSpeedIsMultiplierValueList; - for (std::map < string, int >::const_iterator iterMap = - moveSpeedIsMultiplierValueList.begin (); - iterMap != moveSpeedIsMultiplierValueList.end (); ++iterMap) - { - XmlNode *moveSpeedIsMultiplierValueListNode = - upgradeTypeBaseNode->addChild ("moveSpeedIsMultiplierValueList"); - - moveSpeedIsMultiplierValueListNode->addAttribute ("key", - iterMap->first, - mapTagReplacements); - moveSpeedIsMultiplierValueListNode->addAttribute ("value", - intToStr (iterMap-> - second), - mapTagReplacements); - } - -// int prodSpeed; - upgradeTypeBaseNode->addAttribute ("prodSpeed", intToStr (prodSpeed), - mapTagReplacements); -// bool prodSpeedIsMultiplier; - upgradeTypeBaseNode->addAttribute ("prodSpeedIsMultiplier", - intToStr (prodSpeedIsMultiplier), - mapTagReplacements); -// std::map prodSpeedProduceIsMultiplierValueList; - for (std::map < string, int >::const_iterator iterMap = - prodSpeedProduceIsMultiplierValueList.begin (); - iterMap != prodSpeedProduceIsMultiplierValueList.end (); ++iterMap) - { - XmlNode *prodSpeedProduceIsMultiplierValueListNode = - upgradeTypeBaseNode-> - addChild ("prodSpeedProduceIsMultiplierValueList"); - - prodSpeedProduceIsMultiplierValueListNode->addAttribute ("key", - iterMap-> - first, - mapTagReplacements); - prodSpeedProduceIsMultiplierValueListNode->addAttribute ("value", - intToStr - (iterMap-> - second), - mapTagReplacements); - } - -// std::map prodSpeedUpgradeIsMultiplierValueList; - for (std::map < string, int >::const_iterator iterMap = - prodSpeedUpgradeIsMultiplierValueList.begin (); - iterMap != prodSpeedUpgradeIsMultiplierValueList.end (); ++iterMap) - { - XmlNode *prodSpeedUpgradeIsMultiplierValueListNode = - upgradeTypeBaseNode-> - addChild ("prodSpeedUpgradeIsMultiplierValueList"); - - prodSpeedUpgradeIsMultiplierValueListNode->addAttribute ("key", - iterMap-> - first, - mapTagReplacements); - prodSpeedUpgradeIsMultiplierValueListNode->addAttribute ("value", - intToStr - (iterMap-> - second), - mapTagReplacements); - } - -// std::map prodSpeedMorphIsMultiplierValueList; - for (std::map < string, int >::const_iterator iterMap = - prodSpeedMorphIsMultiplierValueList.begin (); - iterMap != prodSpeedMorphIsMultiplierValueList.end (); ++iterMap) - { - XmlNode *prodSpeedMorphIsMultiplierValueListNode = - upgradeTypeBaseNode-> - addChild ("prodSpeedMorphIsMultiplierValueList"); - - prodSpeedMorphIsMultiplierValueListNode->addAttribute ("key", - iterMap->first, - mapTagReplacements); - prodSpeedMorphIsMultiplierValueListNode->addAttribute ("value", - intToStr - (iterMap-> - second), - mapTagReplacements); - } - - upgradeTypeBaseNode->addAttribute ("attackSpeed", - intToStr (attackSpeed), - mapTagReplacements); - upgradeTypeBaseNode->addAttribute ("attackSpeedIsMultiplier", - intToStr (attackSpeedIsMultiplier), - mapTagReplacements); - for (std::map < string, int >::const_iterator iterMap = - attackSpeedIsMultiplierValueList.begin (); - iterMap != attackSpeedIsMultiplierValueList.end (); ++iterMap) - { - XmlNode *attackSpeedIsMultiplierValueListNode = - upgradeTypeBaseNode->addChild ("attackSpeedIsMultiplierValueList"); - - attackSpeedIsMultiplierValueListNode->addAttribute ("key", - iterMap->first, - mapTagReplacements); - attackSpeedIsMultiplierValueListNode->addAttribute ("value", - intToStr - (iterMap->second), - mapTagReplacements); - } - -// for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { -// TotalUpgrade *boost = boostUpgrades[index]; -// XmlNode *attackBoostListNode = upgradeTypeBaseNode->addChild("attackBoostList"); -// attackBoostListNode->addAttribute("unitId",intToStr(boost->boostUpgradeUnit->getId()), mapTagReplacements); -// -// std::map mapTagReplacements; -// if(boost != NULL) { -// boost->saveGameBoost(attackBoostListNode); -// boost->boostUpgradeBase->saveGameBoost(attackBoostListNode); -// } -// } - } - - void TotalUpgrade::loadGame (const XmlNode * rootNode) - { - const XmlNode *upgradeTypeBaseNode = - rootNode->getChild ("TotalUpgrade"); - - //description = upgradeTypeBaseNode->getAttribute("description")->getValue(); - - // int maxHp; - maxHp = upgradeTypeBaseNode->getAttribute ("maxHp")->getIntValue (); - // bool maxHpIsMultiplier; - maxHpIsMultiplier = - upgradeTypeBaseNode->getAttribute ("maxHpIsMultiplier")-> - getIntValue () != 0; - // int maxHpRegeneration; - maxHpRegeneration = - upgradeTypeBaseNode->getAttribute ("maxHpRegeneration")-> - getIntValue (); - // //bool maxHpRegenerationIsMultiplier; - // - // int sight; - sight = upgradeTypeBaseNode->getAttribute ("sight")->getIntValue (); - // bool sightIsMultiplier; - sightIsMultiplier = - upgradeTypeBaseNode->getAttribute ("sightIsMultiplier")-> - getIntValue () != 0; - // int maxEp; - maxEp = upgradeTypeBaseNode->getAttribute ("maxEp")->getIntValue (); - // bool maxEpIsMultiplier; - maxEpIsMultiplier = - upgradeTypeBaseNode->getAttribute ("maxEpIsMultiplier")-> - getIntValue () != 0; - // int maxEpRegeneration; - maxEpRegeneration = - upgradeTypeBaseNode->getAttribute ("maxEpRegeneration")-> - getIntValue (); - // //bool maxEpRegenerationIsMultiplier; - // int armor; - armor = upgradeTypeBaseNode->getAttribute ("armor")->getIntValue (); - // bool armorIsMultiplier; - armorIsMultiplier = - upgradeTypeBaseNode->getAttribute ("armorIsMultiplier")-> - getIntValue () != 0; - // int attackStrength; - attackStrength = - upgradeTypeBaseNode->getAttribute ("attackStrength")->getIntValue (); - // bool attackStrengthIsMultiplier; - attackStrengthIsMultiplier = - upgradeTypeBaseNode->getAttribute ("attackStrengthIsMultiplier")-> - getIntValue () != 0; - // std::map attackStrengthMultiplierValueList; - vector < XmlNode * >attackStrengthMultiplierValueNodeList = - upgradeTypeBaseNode-> - getChildList ("attackStrengthMultiplierValueList"); - for (unsigned int i = 0; - i < attackStrengthMultiplierValueNodeList.size (); ++i) - { - XmlNode *node = attackStrengthMultiplierValueNodeList[i]; - - attackStrengthMultiplierValueList[node->getAttribute ("key")-> - getValue ()] = - node->getAttribute ("value")->getIntValue (); - } - // int attackRange; - attackRange = - upgradeTypeBaseNode->getAttribute ("attackRange")->getIntValue (); - // bool attackRangeIsMultiplier; - attackRangeIsMultiplier = - upgradeTypeBaseNode->getAttribute ("attackRangeIsMultiplier")-> - getIntValue () != 0; - // std::map attackRangeMultiplierValueList; - vector < XmlNode * >attackRangeMultiplierValueNodeList = - upgradeTypeBaseNode->getChildList ("attackRangeMultiplierValueList"); - for (unsigned int i = 0; i < attackRangeMultiplierValueNodeList.size (); - ++i) - { - XmlNode *node = attackRangeMultiplierValueNodeList[i]; - - attackRangeMultiplierValueList[node->getAttribute ("key")-> - getValue ()] = - node->getAttribute ("value")->getIntValue (); - } - - // int moveSpeed; - moveSpeed = - upgradeTypeBaseNode->getAttribute ("moveSpeed")->getIntValue (); - // bool moveSpeedIsMultiplier; - moveSpeedIsMultiplier = - upgradeTypeBaseNode->getAttribute ("moveSpeedIsMultiplier")-> - getIntValue () != 0; - // std::map moveSpeedIsMultiplierValueList; - vector < XmlNode * >moveSpeedIsMultiplierValueNodeList = - upgradeTypeBaseNode->getChildList ("moveSpeedIsMultiplierValueList"); - for (unsigned int i = 0; i < moveSpeedIsMultiplierValueNodeList.size (); - ++i) - { - XmlNode *node = moveSpeedIsMultiplierValueNodeList[i]; - - moveSpeedIsMultiplierValueList[node->getAttribute ("key")-> - getValue ()] = - node->getAttribute ("value")->getIntValue (); - } - - // int prodSpeed; - prodSpeed = - upgradeTypeBaseNode->getAttribute ("prodSpeed")->getIntValue (); - // bool prodSpeedIsMultiplier; - prodSpeedIsMultiplier = - upgradeTypeBaseNode->getAttribute ("prodSpeedIsMultiplier")-> - getIntValue () != 0; - // std::map prodSpeedProduceIsMultiplierValueList; - vector < XmlNode * >prodSpeedProduceIsMultiplierValueNodeList = - upgradeTypeBaseNode-> - getChildList ("prodSpeedProduceIsMultiplierValueList"); - for (unsigned int i = 0; - i < prodSpeedProduceIsMultiplierValueNodeList.size (); ++i) - { - XmlNode *node = prodSpeedProduceIsMultiplierValueNodeList[i]; - - prodSpeedProduceIsMultiplierValueList[node->getAttribute ("key")-> - getValue ()] = - node->getAttribute ("value")->getIntValue (); - } - - // std::map prodSpeedUpgradeIsMultiplierValueList; - vector < XmlNode * >prodSpeedUpgradeIsMultiplierValueNodeList = - upgradeTypeBaseNode-> - getChildList ("prodSpeedUpgradeIsMultiplierValueList"); - for (unsigned int i = 0; - i < prodSpeedUpgradeIsMultiplierValueNodeList.size (); ++i) - { - XmlNode *node = prodSpeedUpgradeIsMultiplierValueNodeList[i]; - - prodSpeedUpgradeIsMultiplierValueList[node->getAttribute ("key")-> - getValue ()] = - node->getAttribute ("value")->getIntValue (); - } - - // std::map prodSpeedMorphIsMultiplierValueList; - vector < XmlNode * >prodSpeedMorphIsMultiplierValueNodeList = - upgradeTypeBaseNode-> - getChildList ("prodSpeedMorphIsMultiplierValueList"); - for (unsigned int i = 0; - i < prodSpeedMorphIsMultiplierValueNodeList.size (); ++i) - { - XmlNode *node = prodSpeedMorphIsMultiplierValueNodeList[i]; - - prodSpeedMorphIsMultiplierValueList[node->getAttribute ("key")-> - getValue ()] = - node->getAttribute ("value")->getIntValue (); - } - - if (upgradeTypeBaseNode->hasAttribute ("attackSpeed")) - { - attackSpeed = - upgradeTypeBaseNode->getAttribute ("attackSpeed")->getIntValue (); - attackSpeedIsMultiplier = - upgradeTypeBaseNode->getAttribute ("attackSpeedIsMultiplier")-> - getIntValue () != 0; - vector < XmlNode * >attackSpeedIsMultiplierValueNodeList = - upgradeTypeBaseNode-> - getChildList ("attackSpeedIsMultiplierValueList"); - for (unsigned int i = 0; - i < attackSpeedIsMultiplierValueNodeList.size (); ++i) - { - XmlNode *node = attackSpeedIsMultiplierValueNodeList[i]; - - attackSpeedIsMultiplierValueList[node->getAttribute ("key")-> - getValue ()] = - node->getAttribute ("value")->getIntValue (); - } - } - -// vector boostNodeList = upgradeTypeBaseNode->getChildList("attackBoostList"); -// for(unsigned int index = 0; index < boostNodeList.size(); ++index) { -// XmlNode *boostNode = boostNodeList[index]; -// -// //for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { -// // TotalUpgrade *boost = boostUpgrades[index]; -// // XmlNode *attackBoostListNode = upgradeTypeBaseNode->addChild("attackBoostList"); -// -//// std::map mapTagReplacements; -//// if(boost != NULL) { -//// boost->saveGame(attackBoostListNode); -//// } -// int unitId = boostNode->getAttribute("unitId")->getIntValue(); -// const Unit *unit = world->findUnitById(unitId); -// -// TotalUpgrade *boostUpgrade = new TotalUpgrade(); -// //boostUpgrade->copyDataFrom(this); -// boostUpgrade->loadGameBoost(boostNode); -// boostUpgrade->loadGameBoost(boostNode); -// -// boostUpgrade->boostUpgradeBase = ut; -// boostUpgrade->boostUpgradeUnit = unit; -// -// //boostUpgrade->sum(ut,unit); -// boostUpgrades.push_back(boostUpgrade); -// -// //boost->saveGameBoost(attackBoostListNode); -// //boost->boostUpgradeBase->saveGameBoost(attackBoostListNode); -// -// //apply(const UpgradeTypeBase *ut, unit); -// } - - } - - -}} //end namespace +namespace Glest { + namespace Game { + + // ===================================================== + // class UpgradeType + // ===================================================== + + // ==================== get ==================== + + const string VALUE_PERCENT_MULTIPLIER_KEY_NAME = + "value-percent-multiplier"; + const string VALUE_REGEN_KEY_NAME = "regeneration"; + + void UpgradeTypeBase::copyDataFrom(UpgradeTypeBase * source) { + upgradename = source->upgradename; + maxHp = source->maxHp; + maxHpIsMultiplier = source->maxHpIsMultiplier; + maxHpRegeneration = source->maxHpRegeneration; + sight = source->sight; + sightIsMultiplier = source->sightIsMultiplier; + maxEp = source->maxEp; + maxEpIsMultiplier = source->maxEpIsMultiplier; + maxEpRegeneration = source->maxEpRegeneration; + armor = source->armor; + armorIsMultiplier = source->armorIsMultiplier; + attackStrength = source->attackStrength; + attackStrengthIsMultiplier = source->attackStrengthIsMultiplier; + attackStrengthMultiplierValueList = + source->attackStrengthMultiplierValueList; + attackRange = source->attackRange; + attackRangeIsMultiplier = source->attackRangeIsMultiplier; + attackRangeMultiplierValueList = source->attackRangeMultiplierValueList; + moveSpeed = source->moveSpeed; + moveSpeedIsMultiplier = source->moveSpeedIsMultiplier; + moveSpeedIsMultiplierValueList = source->moveSpeedIsMultiplierValueList; + prodSpeed = source->prodSpeed; + prodSpeedIsMultiplier = source->prodSpeedIsMultiplier; + prodSpeedProduceIsMultiplierValueList = + source->prodSpeedProduceIsMultiplierValueList; + prodSpeedUpgradeIsMultiplierValueList = + source->prodSpeedUpgradeIsMultiplierValueList; + prodSpeedMorphIsMultiplierValueList = + source->prodSpeedMorphIsMultiplierValueList; + attackSpeed = source->attackSpeed; + attackSpeedIsMultiplier = source->attackSpeedIsMultiplier; + attackSpeedIsMultiplierValueList = + source->attackSpeedIsMultiplierValueList; + } + + void UpgradeTypeBase::load(const XmlNode * upgradeNode, + string upgradename) { + this->upgradename = upgradename; + //values + maxHpIsMultiplier = false; + if (upgradeNode->hasChild("max-hp") == true) { + maxHp = + upgradeNode->getChild("max-hp")->getAttribute("value")-> + getIntValue(); + if (upgradeNode->getChild("max-hp")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) { + maxHpIsMultiplier = + upgradeNode->getChild("max-hp")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue(); + + //printf("Found maxHpIsMultiplier = %d\n",maxHpIsMultiplier); + } + } else { + maxHp = 0; + } + maxHpRegeneration = 0; + //maxHpRegenerationIsMultiplier = false; + if (upgradeNode->hasChild("max-hp") == true) { + if (upgradeNode->getChild("max-hp")-> + getAttribute(VALUE_REGEN_KEY_NAME, false) != NULL) { + maxHpRegeneration = + upgradeNode->getChild("max-hp")-> + getAttribute(VALUE_REGEN_KEY_NAME)->getIntValue(); + + //printf("Found maxHpIsMultiplier = %d\n",maxHpIsMultiplier); + } + } + + maxEpIsMultiplier = false; + if (upgradeNode->hasChild("max-ep") == true) { + maxEp = + upgradeNode->getChild("max-ep")->getAttribute("value")-> + getIntValue(); + if (upgradeNode->getChild("max-ep")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) { + maxEpIsMultiplier = + upgradeNode->getChild("max-ep")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue(); + + //printf("Found maxEpIsMultiplier = %d\n",maxEpIsMultiplier); + } + } else { + maxEp = 0; + } + maxEpRegeneration = 0; + //maxEpRegenerationIsMultiplier = false; + if (upgradeNode->hasChild("max-ep") == true) { + if (upgradeNode->getChild("max-ep")-> + getAttribute(VALUE_REGEN_KEY_NAME, false) != NULL) { + maxEpRegeneration = + upgradeNode->getChild("max-ep")-> + getAttribute(VALUE_REGEN_KEY_NAME)->getIntValue(); + + //printf("Found maxHpIsMultiplier = %d\n",maxHpIsMultiplier); + } + } + + sightIsMultiplier = false; + if (upgradeNode->hasChild("sight") == true) { + sight = + upgradeNode->getChild("sight")->getAttribute("value")-> + getIntValue(); + if (upgradeNode->getChild("sight")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) { + sightIsMultiplier = + upgradeNode->getChild("sight")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue(); + + //printf("Found sightIsMultiplier = %d\n",sightIsMultiplier); + } + } else { + sight = 0; + } + + attackStrengthIsMultiplier = false; + + std::vector < string > attackStrengthXMLTags; + attackStrengthXMLTags.push_back("attack-strenght"); + attackStrengthXMLTags.push_back("attack-strength"); + if (upgradeNode->hasChildWithAliases(attackStrengthXMLTags) == true) { + attackStrength = + upgradeNode->getChildWithAliases(attackStrengthXMLTags)-> + getAttribute("value")->getIntValue(); + if (upgradeNode->getChildWithAliases(attackStrengthXMLTags)-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) { + attackStrengthIsMultiplier = + upgradeNode->getChildWithAliases(attackStrengthXMLTags)-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue(); + + //printf("Found attackStrengthIsMultiplier = %d\n",attackStrengthIsMultiplier); + } + } else { + attackStrength = 0; + } + + attackRangeIsMultiplier = false; + if (upgradeNode->hasChild("attack-range") == true) { + attackRange = + upgradeNode->getChild("attack-range")->getAttribute("value")-> + getIntValue(); + if (upgradeNode->getChild("attack-range")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) { + attackRangeIsMultiplier = + upgradeNode->getChild("attack-range")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue(); + + //printf("Found attackRangeIsMultiplier = %d\n",attackRangeIsMultiplier); + } + } else { + attackRange = 0; + } + + armorIsMultiplier = false; + if (upgradeNode->hasChild("armor") == true) { + armor = + upgradeNode->getChild("armor")->getAttribute("value")-> + getIntValue(); + if (upgradeNode->getChild("armor")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) { + armorIsMultiplier = + upgradeNode->getChild("armor")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue(); + + //printf("Found armorIsMultiplier = %d\n",armorIsMultiplier); + } + } else { + armor = 0; + } + + moveSpeedIsMultiplier = false; + if (upgradeNode->hasChild("move-speed") == true) { + moveSpeed = + upgradeNode->getChild("move-speed")->getAttribute("value")-> + getIntValue(); + if (upgradeNode->getChild("move-speed")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) { + moveSpeedIsMultiplier = + upgradeNode->getChild("move-speed")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue(); + + //printf("Found moveSpeedIsMultiplier = %d\n",moveSpeedIsMultiplier); + } + } else { + moveSpeed = 0; + } + + prodSpeedIsMultiplier = false; + if (upgradeNode->hasChild("production-speed") == true) { + prodSpeed = + upgradeNode->getChild("production-speed")->getAttribute("value")-> + getIntValue(); + if (upgradeNode->getChild("production-speed")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) { + prodSpeedIsMultiplier = + upgradeNode->getChild("production-speed")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue(); + + //printf("Found prodSpeedIsMultiplier = %d\n",prodSpeedIsMultiplier); + } + } else { + prodSpeed = 0; + } + + attackSpeedIsMultiplier = false; + if (upgradeNode->hasChild("attack-speed") == true) { + attackSpeed = + upgradeNode->getChild("attack-speed")->getAttribute("value")-> + getIntValue(); + if (upgradeNode->getChild("attack-speed")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME, false) != NULL) { + attackSpeedIsMultiplier = + upgradeNode->getChild("attack-speed")-> + getAttribute(VALUE_PERCENT_MULTIPLIER_KEY_NAME)->getBoolValue(); + + //printf("Found prodSpeedIsMultiplier = %d\n",prodSpeedIsMultiplier); + } + } else { + attackSpeed = 0; + } + } + + int UpgradeTypeBase::getAttackStrength(const AttackSkillType * st) const { + if (attackStrengthIsMultiplier == false || st == NULL) { + return attackStrength; + } else { + int result = 0; + if (attackStrengthMultiplierValueList.find(st->getName()) != + attackStrengthMultiplierValueList.end()) { + result = + attackStrengthMultiplierValueList.find(st->getName())->second; + } + return result; + } + } + int UpgradeTypeBase::getAttackRange(const AttackSkillType * st) const { + if (attackRangeIsMultiplier == false || st == NULL) { + return attackRange; + } else { + int result = 0; + if (attackRangeMultiplierValueList.find(st->getName()) != + attackRangeMultiplierValueList.end()) { + result = + attackRangeMultiplierValueList.find(st->getName())->second; + } + return result; + } + } + + int UpgradeTypeBase::getMoveSpeed(const MoveSkillType * st) const { + if (moveSpeedIsMultiplier == false || st == NULL) { + //printf("getMoveSpeed moveSpeedIsMultiplier OFF st [%p]\n",st); + return moveSpeed; + } else { + int result = 0; + if (moveSpeedIsMultiplierValueList.find(st->getName()) != + moveSpeedIsMultiplierValueList.end()) { + result = + moveSpeedIsMultiplierValueList.find(st->getName())->second; + } + + //printf("getMoveSpeed moveSpeedIsMultiplier mst->getSpeed() = %d for skill [%s] result = %d\n",st->getSpeed(),st->getName().c_str(),result); + return result; + } + } + + int UpgradeTypeBase::getAttackSpeed(const AttackSkillType * st) const { + if (attackSpeedIsMultiplier == false || st == NULL) { + return attackSpeed; + } else { + int result = 0; + if (attackSpeedIsMultiplierValueList.find(st->getName()) != + attackSpeedIsMultiplierValueList.end()) { + result = + attackSpeedIsMultiplierValueList.find(st->getName())->second; + } + + return result; + } + } + + int UpgradeTypeBase::getProdSpeed(const SkillType * st) const { + if (prodSpeedIsMultiplier == false || st == NULL) { + return prodSpeed; + } else { + int result = 0; + if (dynamic_cast (st) != NULL) { + if (prodSpeedProduceIsMultiplierValueList.find(st->getName()) != + prodSpeedProduceIsMultiplierValueList.end()) { + result = + prodSpeedProduceIsMultiplierValueList.find(st->getName())-> + second; + } + } else if (dynamic_cast (st) != NULL) { + if (prodSpeedUpgradeIsMultiplierValueList.find(st->getName()) != + prodSpeedUpgradeIsMultiplierValueList.end()) { + result = + prodSpeedUpgradeIsMultiplierValueList.find(st->getName())-> + second; + } + } else if (dynamic_cast (st) != NULL) { + if (prodSpeedMorphIsMultiplierValueList.find(st->getName()) != + prodSpeedMorphIsMultiplierValueList.end()) { + result = + prodSpeedMorphIsMultiplierValueList.find(st->getName())-> + second; + } + } else { + throw + megaglest_runtime_error + ("Unsupported skilltype in getProdSpeed!"); + } + + return result; + } + } + + string UpgradeTypeBase::getDesc(bool translatedValue) const { + + string str = ""; + string indent = "->"; + Lang & lang = Lang::getInstance(); + + if (getMaxHp() != 0 || getMaxHpRegeneration() != 0) { + str += + indent + lang.getString("Hp", + (translatedValue == + true ? "" : "english")) + " +" + + intToStr(maxHp); + if (maxHpIsMultiplier) { + str += "%"; + } + // if(getMaxHpFromBoosts() != 0) { + // str += " +" + intToStr(getMaxHpFromBoosts()); + // } + if (getMaxHpRegeneration() != 0) { + str += + " (" + lang.getString("Regeneration", + (translatedValue == + true ? "" : "english")) + ": +" + + intToStr(maxHpRegeneration); + // if(getMaxHpRegenerationFromBoosts() != 0) { + // str += " +" + intToStr(getMaxHpRegenerationFromBoosts()); + // } + str += ")"; + } + } + + if (getSight() != 0) { + if (str != "") { + str += "\n"; + } + str += + indent + lang.getString("Sight", + (translatedValue == + true ? "" : "english")) + " +" + + intToStr(sight); + if (sightIsMultiplier) { + str += "%"; + } + // if(getSightFromBoosts() != 0) { + // str += " +" + intToStr(getSightFromBoosts()); + // } + } + + if (getMaxEp() != 0 || getMaxEpRegeneration() != 0) { + if (str != "") { + str += "\n"; + } + + str += + indent + lang.getString("Ep", + (translatedValue == + true ? "" : "english")) + " +" + + intToStr(maxEp); + if (maxEpIsMultiplier) { + str += "%"; + } + // if(getMaxEpFromBoosts() != 0) { + // str += " +" + intToStr(getMaxEpFromBoosts()); + // } + + if (getMaxEpRegeneration() != 0) { + str += + " (" + lang.getString("Regeneration", + (translatedValue == + true ? "" : "english")) + ": +" + + intToStr(maxEpRegeneration); + // if(getMaxEpRegenerationFromBoosts() != 0) { + // str += " +" + intToStr(getMaxEpRegenerationFromBoosts()); + // } + str += ")"; + } + } + + if (getAttackStrength() != 0) { + if (str != "") { + str += "\n"; + } + + str += + indent + lang.getString("AttackStrenght", + (translatedValue == + true ? "" : "english")) + " +" + + intToStr(attackStrength); + if (attackStrengthIsMultiplier) { + str += "%"; + } + // if(getAttackStrengthFromBoosts(NULL) != 0) { + // str += " +" + intToStr(getAttackStrengthFromBoosts(NULL)); + // } + } + + if (getAttackRange() != 0) { + if (str != "") { + str += "\n"; + } + + str += + indent + lang.getString("AttackDistance", + (translatedValue == + true ? "" : "english")) + " +" + + intToStr(attackRange); + if (attackRangeIsMultiplier) { + str += "%"; + } + // if(getAttackRangeFromBoosts(NULL) != 0) { + // str += " +" + intToStr(getAttackRangeFromBoosts(NULL)); + // } + } + + if (getArmor() != 0) { + if (str != "") { + str += "\n"; + } + + str += + indent + lang.getString("Armor", + (translatedValue == + true ? "" : "english")) + " +" + + intToStr(armor); + if (armorIsMultiplier) { + str += "%"; + } + // if(getArmorFromBoosts() != 0) { + // str += " +" + intToStr(getArmorFromBoosts()); + // } + } + + if (getMoveSpeed() != 0) { + if (str != "") { + str += "\n"; + } + + str += + indent + lang.getString("WalkSpeed", + (translatedValue == + true ? "" : "english")) + " +" + + intToStr(moveSpeed); + if (moveSpeedIsMultiplier) { + str += "%"; + } + // if(getMoveSpeedFromBoosts(NULL) != 0) { + // str += " +" + intToStr(getMoveSpeedFromBoosts(NULL)); + // } + } + + if (getProdSpeed() != 0) { + if (str != "") { + str += "\n"; + } + + str += + indent + lang.getString("ProductionSpeed", + (translatedValue == + true ? "" : "english")) + " +" + + intToStr(prodSpeed); + if (prodSpeedIsMultiplier) { + str += "%"; + } + // if(getProdSpeedFromBoosts(NULL) != 0) { + // str += " +" + intToStr(getProdSpeedFromBoosts(NULL)); + // } + } + + if (getAttackSpeed() != 0) { + if (str != "") { + str += "\n"; + } + + str += + indent + lang.getString("AttackSpeed", + (translatedValue == + true ? "" : "english")) + " +" + + intToStr(attackSpeed); + if (attackSpeedIsMultiplier) { + str += "%"; + } + // if(getAttackSpeedFromBoosts(NULL) != 0) { + // str += " +" + intToStr(getAttackSpeedFromBoosts(NULL)); + // } + } + if (str != "") { + str += "\n"; + } + + return str; + } + + //void UpgradeTypeBase::saveGameBoost(XmlNode *rootNode) const { + // std::map mapTagReplacements; + // XmlNode *upgradeTypeBaseNode = rootNode->addChild("UpgradeTypeBaseBoost"); + // + // upgradeTypeBaseNode->addAttribute("upgradename",upgradename, mapTagReplacements); + // + //// int maxHp; + // upgradeTypeBaseNode->addAttribute("maxHp",intToStr(maxHp), mapTagReplacements); + //// bool maxHpIsMultiplier; + // upgradeTypeBaseNode->addAttribute("maxHpIsMultiplier",intToStr(maxHpIsMultiplier), mapTagReplacements); + //// int maxHpRegeneration; + // upgradeTypeBaseNode->addAttribute("maxHpRegeneration",intToStr(maxHpRegeneration), mapTagReplacements); + //// //bool maxHpRegenerationIsMultiplier; + //// + //// int sight; + // upgradeTypeBaseNode->addAttribute("sight",intToStr(sight), mapTagReplacements); + //// bool sightIsMultiplier; + // upgradeTypeBaseNode->addAttribute("sightIsMultiplier",intToStr(sightIsMultiplier), mapTagReplacements); + //// int maxEp; + // upgradeTypeBaseNode->addAttribute("maxEp",intToStr(maxEp), mapTagReplacements); + //// bool maxEpIsMultiplier; + // upgradeTypeBaseNode->addAttribute("maxEpIsMultiplier",intToStr(maxEpIsMultiplier), mapTagReplacements); + //// int maxEpRegeneration; + // upgradeTypeBaseNode->addAttribute("maxEpRegeneration",intToStr(maxEpRegeneration), mapTagReplacements); + //// //bool maxEpRegenerationIsMultiplier; + //// int armor; + // upgradeTypeBaseNode->addAttribute("armor",intToStr(armor), mapTagReplacements); + //// bool armorIsMultiplier; + // upgradeTypeBaseNode->addAttribute("armorIsMultiplier",intToStr(armorIsMultiplier), mapTagReplacements); + //// int attackStrength; + // upgradeTypeBaseNode->addAttribute("attackStrength",intToStr(attackStrength), mapTagReplacements); + //// bool attackStrengthIsMultiplier; + // upgradeTypeBaseNode->addAttribute("attackStrengthIsMultiplier",intToStr(attackStrengthIsMultiplier), mapTagReplacements); + //// std::map attackStrengthMultiplierValueList; + // for(std::map::const_iterator iterMap = attackStrengthMultiplierValueList.begin(); + // iterMap != attackStrengthMultiplierValueList.end(); ++iterMap) { + // XmlNode *attackStrengthMultiplierValueListNode = upgradeTypeBaseNode->addChild("attackStrengthMultiplierValueList"); + // + // attackStrengthMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + // attackStrengthMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + // } + //// int attackRange; + // upgradeTypeBaseNode->addAttribute("attackRange",intToStr(attackRange), mapTagReplacements); + //// bool attackRangeIsMultiplier; + // upgradeTypeBaseNode->addAttribute("attackRangeIsMultiplier",intToStr(attackRangeIsMultiplier), mapTagReplacements); + //// std::map attackRangeMultiplierValueList; + // for(std::map::const_iterator iterMap = attackRangeMultiplierValueList.begin(); + // iterMap != attackRangeMultiplierValueList.end(); ++iterMap) { + // XmlNode *attackRangeMultiplierValueListNode = upgradeTypeBaseNode->addChild("attackRangeMultiplierValueList"); + // + // attackRangeMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + // attackRangeMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + // } + // + //// int moveSpeed; + // upgradeTypeBaseNode->addAttribute("moveSpeed",intToStr(moveSpeed), mapTagReplacements); + //// bool moveSpeedIsMultiplier; + // upgradeTypeBaseNode->addAttribute("moveSpeedIsMultiplier",intToStr(moveSpeedIsMultiplier), mapTagReplacements); + //// std::map moveSpeedIsMultiplierValueList; + // for(std::map::const_iterator iterMap = moveSpeedIsMultiplierValueList.begin(); + // iterMap != moveSpeedIsMultiplierValueList.end(); ++iterMap) { + // XmlNode *moveSpeedIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("moveSpeedIsMultiplierValueList"); + // + // moveSpeedIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + // moveSpeedIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + // } + // + //// int prodSpeed; + // upgradeTypeBaseNode->addAttribute("prodSpeed",intToStr(prodSpeed), mapTagReplacements); + //// bool prodSpeedIsMultiplier; + // upgradeTypeBaseNode->addAttribute("prodSpeedIsMultiplier",intToStr(prodSpeedIsMultiplier), mapTagReplacements); + //// std::map prodSpeedProduceIsMultiplierValueList; + // for(std::map::const_iterator iterMap = prodSpeedProduceIsMultiplierValueList.begin(); + // iterMap != prodSpeedProduceIsMultiplierValueList.end(); ++iterMap) { + // XmlNode *prodSpeedProduceIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("prodSpeedProduceIsMultiplierValueList"); + // + // prodSpeedProduceIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + // prodSpeedProduceIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + // } + // + //// std::map prodSpeedUpgradeIsMultiplierValueList; + // for(std::map::const_iterator iterMap = prodSpeedUpgradeIsMultiplierValueList.begin(); + // iterMap != prodSpeedUpgradeIsMultiplierValueList.end(); ++iterMap) { + // XmlNode *prodSpeedUpgradeIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("prodSpeedUpgradeIsMultiplierValueList"); + // + // prodSpeedUpgradeIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + // prodSpeedUpgradeIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + // } + // + //// std::map prodSpeedMorphIsMultiplierValueList; + // for(std::map::const_iterator iterMap = prodSpeedMorphIsMultiplierValueList.begin(); + // iterMap != prodSpeedMorphIsMultiplierValueList.end(); ++iterMap) { + // XmlNode *prodSpeedMorphIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("prodSpeedMorphIsMultiplierValueList"); + // + // prodSpeedMorphIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + // prodSpeedMorphIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + // } + //} + + void UpgradeTypeBase::saveGame(XmlNode * rootNode) const { + std::map < string, string > mapTagReplacements; + XmlNode *upgradeTypeBaseNode = rootNode->addChild("UpgradeTypeBase"); + + upgradeTypeBaseNode->addAttribute("upgradename", upgradename, + mapTagReplacements); + + //// int maxHp; + // upgradeTypeBaseNode->addAttribute("maxHp",intToStr(maxHp), mapTagReplacements); + //// bool maxHpIsMultiplier; + // upgradeTypeBaseNode->addAttribute("maxHpIsMultiplier",intToStr(maxHpIsMultiplier), mapTagReplacements); + //// int maxHpRegeneration; + // upgradeTypeBaseNode->addAttribute("maxHpRegeneration",intToStr(maxHpRegeneration), mapTagReplacements); + //// //bool maxHpRegenerationIsMultiplier; + //// + //// int sight; + // upgradeTypeBaseNode->addAttribute("sight",intToStr(sight), mapTagReplacements); + //// bool sightIsMultiplier; + // upgradeTypeBaseNode->addAttribute("sightIsMultiplier",intToStr(sightIsMultiplier), mapTagReplacements); + //// int maxEp; + // upgradeTypeBaseNode->addAttribute("maxEp",intToStr(maxEp), mapTagReplacements); + //// bool maxEpIsMultiplier; + // upgradeTypeBaseNode->addAttribute("maxEpIsMultiplier",intToStr(maxEpIsMultiplier), mapTagReplacements); + //// int maxEpRegeneration; + // upgradeTypeBaseNode->addAttribute("maxEpRegeneration",intToStr(maxEpRegeneration), mapTagReplacements); + //// //bool maxEpRegenerationIsMultiplier; + //// int armor; + // upgradeTypeBaseNode->addAttribute("armor",intToStr(armor), mapTagReplacements); + //// bool armorIsMultiplier; + // upgradeTypeBaseNode->addAttribute("armorIsMultiplier",intToStr(armorIsMultiplier), mapTagReplacements); + //// int attackStrength; + // upgradeTypeBaseNode->addAttribute("attackStrength",intToStr(attackStrength), mapTagReplacements); + //// bool attackStrengthIsMultiplier; + // upgradeTypeBaseNode->addAttribute("attackStrengthIsMultiplier",intToStr(attackStrengthIsMultiplier), mapTagReplacements); + //// std::map attackStrengthMultiplierValueList; + // for(std::map::const_iterator iterMap = attackStrengthMultiplierValueList.begin(); + // iterMap != attackStrengthMultiplierValueList.end(); ++iterMap) { + // XmlNode *attackStrengthMultiplierValueListNode = upgradeTypeBaseNode->addChild("attackStrengthMultiplierValueList"); + // + // attackStrengthMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + // attackStrengthMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + // } + //// int attackRange; + // upgradeTypeBaseNode->addAttribute("attackRange",intToStr(attackRange), mapTagReplacements); + //// bool attackRangeIsMultiplier; + // upgradeTypeBaseNode->addAttribute("attackRangeIsMultiplier",intToStr(attackRangeIsMultiplier), mapTagReplacements); + //// std::map attackRangeMultiplierValueList; + // for(std::map::const_iterator iterMap = attackRangeMultiplierValueList.begin(); + // iterMap != attackRangeMultiplierValueList.end(); ++iterMap) { + // XmlNode *attackRangeMultiplierValueListNode = upgradeTypeBaseNode->addChild("attackRangeMultiplierValueList"); + // + // attackRangeMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + // attackRangeMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + // } + // + //// int moveSpeed; + // upgradeTypeBaseNode->addAttribute("moveSpeed",intToStr(moveSpeed), mapTagReplacements); + //// bool moveSpeedIsMultiplier; + // upgradeTypeBaseNode->addAttribute("moveSpeedIsMultiplier",intToStr(moveSpeedIsMultiplier), mapTagReplacements); + //// std::map moveSpeedIsMultiplierValueList; + // for(std::map::const_iterator iterMap = moveSpeedIsMultiplierValueList.begin(); + // iterMap != moveSpeedIsMultiplierValueList.end(); ++iterMap) { + // XmlNode *moveSpeedIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("moveSpeedIsMultiplierValueList"); + // + // moveSpeedIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + // moveSpeedIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + // } + // + //// int prodSpeed; + // upgradeTypeBaseNode->addAttribute("prodSpeed",intToStr(prodSpeed), mapTagReplacements); + //// bool prodSpeedIsMultiplier; + // upgradeTypeBaseNode->addAttribute("prodSpeedIsMultiplier",intToStr(prodSpeedIsMultiplier), mapTagReplacements); + //// std::map prodSpeedProduceIsMultiplierValueList; + // for(std::map::const_iterator iterMap = prodSpeedProduceIsMultiplierValueList.begin(); + // iterMap != prodSpeedProduceIsMultiplierValueList.end(); ++iterMap) { + // XmlNode *prodSpeedProduceIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("prodSpeedProduceIsMultiplierValueList"); + // + // prodSpeedProduceIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + // prodSpeedProduceIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + // } + // + //// std::map prodSpeedUpgradeIsMultiplierValueList; + // for(std::map::const_iterator iterMap = prodSpeedUpgradeIsMultiplierValueList.begin(); + // iterMap != prodSpeedUpgradeIsMultiplierValueList.end(); ++iterMap) { + // XmlNode *prodSpeedUpgradeIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("prodSpeedUpgradeIsMultiplierValueList"); + // + // prodSpeedUpgradeIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + // prodSpeedUpgradeIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + // } + // + //// std::map prodSpeedMorphIsMultiplierValueList; + // for(std::map::const_iterator iterMap = prodSpeedMorphIsMultiplierValueList.begin(); + // iterMap != prodSpeedMorphIsMultiplierValueList.end(); ++iterMap) { + // XmlNode *prodSpeedMorphIsMultiplierValueListNode = upgradeTypeBaseNode->addChild("prodSpeedMorphIsMultiplierValueList"); + // + // prodSpeedMorphIsMultiplierValueListNode->addAttribute("key",iterMap->first, mapTagReplacements); + // prodSpeedMorphIsMultiplierValueListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + // } + } + + //void UpgradeTypeBase::loadGameBoost(const XmlNode *rootNode) { + // const XmlNode *upgradeTypeBaseNode = rootNode->getChild("UpgradeTypeBaseBoost"); + // + // //description = upgradeTypeBaseNode->getAttribute("description")->getValue(); + // + // upgradename = upgradeTypeBaseNode->getAttribute("upgradename")->getValue(); + // + // // int maxHp; + // maxHp = upgradeTypeBaseNode->getAttribute("maxHp")->getIntValue(); + // // bool maxHpIsMultiplier; + // maxHpIsMultiplier = (upgradeTypeBaseNode->getAttribute("maxHpIsMultiplier")->getIntValue() != 0); + // // int maxHpRegeneration; + // maxHpRegeneration = upgradeTypeBaseNode->getAttribute("maxHpRegeneration")->getIntValue(); + // // //bool maxHpRegenerationIsMultiplier; + // // + // // int sight; + // sight = upgradeTypeBaseNode->getAttribute("sight")->getIntValue(); + // // bool sightIsMultiplier; + // sightIsMultiplier = (upgradeTypeBaseNode->getAttribute("sightIsMultiplier")->getIntValue() != 0); + // // int maxEp; + // maxEp = upgradeTypeBaseNode->getAttribute("maxEp")->getIntValue(); + // // bool maxEpIsMultiplier; + // maxEpIsMultiplier = (upgradeTypeBaseNode->getAttribute("maxEpIsMultiplier")->getIntValue() != 0); + // // int maxEpRegeneration; + // maxEpRegeneration = upgradeTypeBaseNode->getAttribute("maxEpRegeneration")->getIntValue(); + // // //bool maxEpRegenerationIsMultiplier; + // // int armor; + // armor = upgradeTypeBaseNode->getAttribute("armor")->getIntValue(); + // // bool armorIsMultiplier; + // armorIsMultiplier = (upgradeTypeBaseNode->getAttribute("armorIsMultiplier")->getIntValue() != 0); + // // int attackStrength; + // attackStrength = upgradeTypeBaseNode->getAttribute("attackStrength")->getIntValue(); + // // bool attackStrengthIsMultiplier; + // attackStrengthIsMultiplier = (upgradeTypeBaseNode->getAttribute("attackStrengthIsMultiplier")->getIntValue() != 0); + // // std::map attackStrengthMultiplierValueList; + // vector attackStrengthMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("attackStrengthMultiplierValueList"); + // for(unsigned int i = 0; i < attackStrengthMultiplierValueNodeList.size(); ++i) { + // XmlNode *node = attackStrengthMultiplierValueNodeList[i]; + // + // attackStrengthMultiplierValueList[node->getAttribute("key")->getValue()] = + // node->getAttribute("value")->getIntValue(); + // } + // // int attackRange; + // attackRange = upgradeTypeBaseNode->getAttribute("attackRange")->getIntValue(); + // // bool attackRangeIsMultiplier; + // attackRangeIsMultiplier = (upgradeTypeBaseNode->getAttribute("attackRangeIsMultiplier")->getIntValue() != 0); + // // std::map attackRangeMultiplierValueList; + // vector attackRangeMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("attackRangeMultiplierValueList"); + // for(unsigned int i = 0; i < attackRangeMultiplierValueNodeList.size(); ++i) { + // XmlNode *node = attackRangeMultiplierValueNodeList[i]; + // + // attackRangeMultiplierValueList[node->getAttribute("key")->getValue()] = + // node->getAttribute("value")->getIntValue(); + // } + // + // // int moveSpeed; + // moveSpeed = upgradeTypeBaseNode->getAttribute("moveSpeed")->getIntValue(); + // // bool moveSpeedIsMultiplier; + // moveSpeedIsMultiplier = (upgradeTypeBaseNode->getAttribute("moveSpeedIsMultiplier")->getIntValue() != 0); + // // std::map moveSpeedIsMultiplierValueList; + // vector moveSpeedIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("moveSpeedIsMultiplierValueList"); + // for(unsigned int i = 0; i < moveSpeedIsMultiplierValueNodeList.size(); ++i) { + // XmlNode *node = moveSpeedIsMultiplierValueNodeList[i]; + // + // moveSpeedIsMultiplierValueList[node->getAttribute("key")->getValue()] = + // node->getAttribute("value")->getIntValue(); + // } + // + // // int prodSpeed; + // prodSpeed = upgradeTypeBaseNode->getAttribute("prodSpeed")->getIntValue(); + // // bool prodSpeedIsMultiplier; + // prodSpeedIsMultiplier = (upgradeTypeBaseNode->getAttribute("prodSpeedIsMultiplier")->getIntValue() != 0); + // // std::map prodSpeedProduceIsMultiplierValueList; + // vector prodSpeedProduceIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("prodSpeedProduceIsMultiplierValueList"); + // for(unsigned int i = 0; i < prodSpeedProduceIsMultiplierValueNodeList.size(); ++i) { + // XmlNode *node = prodSpeedProduceIsMultiplierValueNodeList[i]; + // + // prodSpeedProduceIsMultiplierValueList[node->getAttribute("key")->getValue()] = + // node->getAttribute("value")->getIntValue(); + // } + // + // // std::map prodSpeedUpgradeIsMultiplierValueList; + // vector prodSpeedUpgradeIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("prodSpeedUpgradeIsMultiplierValueList"); + // for(unsigned int i = 0; i < prodSpeedUpgradeIsMultiplierValueNodeList.size(); ++i) { + // XmlNode *node = prodSpeedUpgradeIsMultiplierValueNodeList[i]; + // + // prodSpeedUpgradeIsMultiplierValueList[node->getAttribute("key")->getValue()] = + // node->getAttribute("value")->getIntValue(); + // } + // + // // std::map prodSpeedMorphIsMultiplierValueList; + // vector prodSpeedMorphIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("prodSpeedMorphIsMultiplierValueList"); + // for(unsigned int i = 0; i < prodSpeedMorphIsMultiplierValueNodeList.size(); ++i) { + // XmlNode *node = prodSpeedMorphIsMultiplierValueNodeList[i]; + // + // prodSpeedMorphIsMultiplierValueList[node->getAttribute("key")->getValue()] = + // node->getAttribute("value")->getIntValue(); + // } + //} + + const UpgradeType *UpgradeTypeBase::loadGame(const XmlNode * rootNode, + Faction * faction) { + const XmlNode *upgradeTypeBaseNode = + rootNode->getChild("UpgradeTypeBase"); + + //description = upgradeTypeBaseNode->getAttribute("description")->getValue(); + + string upgradename = + upgradeTypeBaseNode->getAttribute("upgradename")->getValue(); + return faction->getType()->getUpgradeType(upgradename); + // int maxHp; + // maxHp = upgradeTypeBaseNode->getAttribute("maxHp")->getIntValue(); + // // bool maxHpIsMultiplier; + // maxHpIsMultiplier = upgradeTypeBaseNode->getAttribute("maxHpIsMultiplier")->getIntValue(); + // // int maxHpRegeneration; + // maxHpRegeneration = upgradeTypeBaseNode->getAttribute("maxHpRegeneration")->getIntValue(); + // // //bool maxHpRegenerationIsMultiplier; + // // + // // int sight; + // sight = upgradeTypeBaseNode->getAttribute("sight")->getIntValue(); + // // bool sightIsMultiplier; + // sightIsMultiplier = upgradeTypeBaseNode->getAttribute("sightIsMultiplier")->getIntValue(); + // // int maxEp; + // maxEp = upgradeTypeBaseNode->getAttribute("maxEp")->getIntValue(); + // // bool maxEpIsMultiplier; + // maxEpIsMultiplier = upgradeTypeBaseNode->getAttribute("maxEpIsMultiplier")->getIntValue(); + // // int maxEpRegeneration; + // maxEpRegeneration = upgradeTypeBaseNode->getAttribute("maxEpRegeneration")->getIntValue(); + // // //bool maxEpRegenerationIsMultiplier; + // // int armor; + // armor = upgradeTypeBaseNode->getAttribute("armor")->getIntValue(); + // // bool armorIsMultiplier; + // armorIsMultiplier = upgradeTypeBaseNode->getAttribute("armorIsMultiplier")->getIntValue(); + // // int attackStrength; + // attackStrength = upgradeTypeBaseNode->getAttribute("attackStrength")->getIntValue(); + // // bool attackStrengthIsMultiplier; + // attackStrengthIsMultiplier = upgradeTypeBaseNode->getAttribute("attackStrengthIsMultiplier")->getIntValue(); + // // std::map attackStrengthMultiplierValueList; + // vector attackStrengthMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("attackStrengthMultiplierValueList"); + // for(unsigned int i = 0; i < attackStrengthMultiplierValueNodeList.size(); ++i) { + // XmlNode *node = attackStrengthMultiplierValueNodeList[i]; + // + // attackStrengthMultiplierValueList[node->getAttribute("key")->getValue()] = + // node->getAttribute("value")->getIntValue(); + // } + // // int attackRange; + // attackRange = upgradeTypeBaseNode->getAttribute("attackRange")->getIntValue(); + // // bool attackRangeIsMultiplier; + // attackRangeIsMultiplier = upgradeTypeBaseNode->getAttribute("attackRangeIsMultiplier")->getIntValue(); + // // std::map attackRangeMultiplierValueList; + // vector attackRangeMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("attackRangeMultiplierValueList"); + // for(unsigned int i = 0; i < attackRangeMultiplierValueNodeList.size(); ++i) { + // XmlNode *node = attackRangeMultiplierValueNodeList[i]; + // + // attackRangeMultiplierValueList[node->getAttribute("key")->getValue()] = + // node->getAttribute("value")->getIntValue(); + // } + // + // // int moveSpeed; + // moveSpeed = upgradeTypeBaseNode->getAttribute("moveSpeed")->getIntValue(); + // // bool moveSpeedIsMultiplier; + // moveSpeedIsMultiplier = upgradeTypeBaseNode->getAttribute("moveSpeedIsMultiplier")->getIntValue(); + // // std::map moveSpeedIsMultiplierValueList; + // vector moveSpeedIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("moveSpeedIsMultiplierValueList"); + // for(unsigned int i = 0; i < moveSpeedIsMultiplierValueNodeList.size(); ++i) { + // XmlNode *node = moveSpeedIsMultiplierValueNodeList[i]; + // + // moveSpeedIsMultiplierValueList[node->getAttribute("key")->getValue()] = + // node->getAttribute("value")->getIntValue(); + // } + // + // // int prodSpeed; + // prodSpeed = upgradeTypeBaseNode->getAttribute("prodSpeed")->getIntValue(); + // // bool prodSpeedIsMultiplier; + // prodSpeedIsMultiplier = upgradeTypeBaseNode->getAttribute("prodSpeedIsMultiplier")->getIntValue(); + // // std::map prodSpeedProduceIsMultiplierValueList; + // vector prodSpeedProduceIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("prodSpeedProduceIsMultiplierValueList"); + // for(unsigned int i = 0; i < prodSpeedProduceIsMultiplierValueNodeList.size(); ++i) { + // XmlNode *node = prodSpeedProduceIsMultiplierValueNodeList[i]; + // + // prodSpeedProduceIsMultiplierValueList[node->getAttribute("key")->getValue()] = + // node->getAttribute("value")->getIntValue(); + // } + // + // // std::map prodSpeedUpgradeIsMultiplierValueList; + // vector prodSpeedUpgradeIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("prodSpeedUpgradeIsMultiplierValueList"); + // for(unsigned int i = 0; i < prodSpeedUpgradeIsMultiplierValueNodeList.size(); ++i) { + // XmlNode *node = prodSpeedUpgradeIsMultiplierValueNodeList[i]; + // + // prodSpeedUpgradeIsMultiplierValueList[node->getAttribute("key")->getValue()] = + // node->getAttribute("value")->getIntValue(); + // } + // + // // std::map prodSpeedMorphIsMultiplierValueList; + // vector prodSpeedMorphIsMultiplierValueNodeList = upgradeTypeBaseNode->getChildList("prodSpeedMorphIsMultiplierValueList"); + // for(unsigned int i = 0; i < prodSpeedMorphIsMultiplierValueNodeList.size(); ++i) { + // XmlNode *node = prodSpeedMorphIsMultiplierValueNodeList[i]; + // + // prodSpeedMorphIsMultiplierValueList[node->getAttribute("key")->getValue()] = + // node->getAttribute("value")->getIntValue(); + // } + } + + // ==================== misc ==================== + + string UpgradeType::getName(bool translatedValue) const { + if (translatedValue == false) + return name; + + Lang & lang = Lang::getInstance(); + return lang.getTechTreeString("UpgradeTypeName_" + name, + name.c_str()); + } + + string UpgradeType::getTagName(string tag, bool translatedValue) const { + if (translatedValue == false) + return tag; + + Lang & lang = Lang::getInstance(); + return lang.getTechTreeString("TagName_" + tag, tag.c_str()); + } + + string UpgradeType::getReqDesc(bool translatedValue) const { + Lang & lang = Lang::getInstance(); + string str = ProducibleType::getReqDesc(translatedValue); + string indent = " "; + if (!effects.empty() || !tags.empty()) { + str += + "\n" + lang.getString("Upgrades", + (translatedValue == + true ? "" : "english")) + "\n"; + } + str += UpgradeTypeBase::getDesc(translatedValue); + if (!effects.empty() || !tags.empty()) { + str += + lang.getString("AffectedUnits", + (translatedValue == true ? "" : "english")) + "\n"; + + // We want the output to be sorted, so convert the set to a vector and sort that + std::vector < const UnitType *>outputUnits(effects.begin(), + effects.end()); + std::sort(outputUnits.begin(), outputUnits.end(), + UnitTypeSorter()); + + vector < const UnitType *>::iterator unitIter; + for (unitIter = outputUnits.begin(); unitIter != outputUnits.end(); + ++unitIter) { + const UnitType *unit = *unitIter; + str += indent + unit->getName(translatedValue) + "\n"; + } + + // Do the same for tags + std::vector < string > outputTags(tags.begin(), tags.end()); + std::sort(outputTags.begin(), outputTags.end()); + + vector < string >::iterator tagIter; + for (tagIter = outputTags.begin(); tagIter != outputTags.end(); + ++tagIter) { + string tag = *tagIter; + str += + indent + lang.getString("TagDesc", + (translatedValue == + true ? "" : "english")) + " " + + getTagName(tag, translatedValue) + "\n"; + } + } + return str; + } + + void UpgradeType::preLoad(const string & dir) { + name = lastDir(dir); + } + + void UpgradeType::load(const string & dir, const TechTree * techTree, + const FactionType * factionType, + Checksum * checksum, Checksum * techtreeChecksum, + std::map < string, vector < pair < string, + string > > >&loadedFileList, bool validationMode) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + Lang::getInstance(). + getString("LogScreenGameLoadingUpgradeType", "", + true).c_str(), + formatString(this->getName(true)).c_str()); + Logger::getInstance().add(szBuf, true); + + string currentPath = dir; + endPathWithSlash(currentPath); + string path = currentPath + name + ".xml"; + string sourceXMLFile = path; + + try { + checksum->addFile(path); + techtreeChecksum->addFile(path); + + XmlTree xmlTree; + std::map < string, string > mapExtraTagReplacementValues; + mapExtraTagReplacementValues["$COMMONDATAPATH"] = + techTree->getPath() + "/commondata/"; + xmlTree.load(path, + Properties:: + getTagReplacementValues + (&mapExtraTagReplacementValues)); + loadedFileList[path].push_back(make_pair(currentPath, currentPath)); + const XmlNode *upgradeNode = xmlTree.getRootNode(); + + //image + image = NULL; // Not used for upgrade types + + //image cancel + cancelImage = NULL; // Not used for upgrade types + + //upgrade time + const XmlNode *upgradeTimeNode = upgradeNode->getChild("time"); + productionTime = + upgradeTimeNode->getAttribute("value")->getIntValue(); + + std::map < string, int >sortedItems; + + //unit requirements + bool hasDup = false; + const XmlNode *unitRequirementsNode = + upgradeNode->getChild("unit-requirements"); + for (int i = 0; i < (int) unitRequirementsNode->getChildCount(); ++i) { + const XmlNode *unitNode = + unitRequirementsNode->getChild("unit", i); + string name = + unitNode->getAttribute("name")->getRestrictedValue(); + + if (sortedItems.find(name) != sortedItems.end()) { + hasDup = true; + } + + sortedItems[name] = 0; + } + + if (hasDup) { + printf + ("WARNING, upgrade type [%s] has one or more duplicate unit requirements\n", + this->getName().c_str()); + } + + for (std::map < string, int >::iterator iterMap = + sortedItems.begin(); iterMap != sortedItems.end(); ++iterMap) { + unitReqs.push_back(factionType->getUnitType(iterMap->first)); + } + sortedItems.clear(); + hasDup = false; + + //upgrade requirements + const XmlNode *upgradeRequirementsNode = + upgradeNode->getChild("upgrade-requirements"); + for (int i = 0; i < (int) upgradeRequirementsNode->getChildCount(); + ++i) { + const XmlNode *upgradeReqNode = + upgradeRequirementsNode->getChild("upgrade", i); + string name = + upgradeReqNode->getAttribute("name")->getRestrictedValue(); + + if (sortedItems.find(name) != sortedItems.end()) { + hasDup = true; + } + + sortedItems[name] = 0; + } + + if (hasDup) { + printf + ("WARNING, upgrade type [%s] has one or more duplicate upgrade requirements\n", + this->getName().c_str()); + } + + for (std::map < string, int >::iterator iterMap = + sortedItems.begin(); iterMap != sortedItems.end(); ++iterMap) { + upgradeReqs.push_back(factionType-> + getUpgradeType(iterMap->first)); + } + sortedItems.clear(); + hasDup = false; + + //resource requirements + int index = 0; + const XmlNode *resourceRequirementsNode = + upgradeNode->getChild("resource-requirements"); + + costs.resize(resourceRequirementsNode->getChildCount()); + for (int i = 0; i < (int) costs.size(); ++i) { + const XmlNode *resourceNode = + resourceRequirementsNode->getChild("resource", i); + string name = + resourceNode->getAttribute("name")->getRestrictedValue(); + int amount = resourceNode->getAttribute("amount")->getIntValue(); + + if (sortedItems.find(name) != sortedItems.end()) { + hasDup = true; + } + + sortedItems[name] = amount; + } + + //if(hasDup || sortedItems.size() != costs.size()) printf("Found duplicate resource requirement, costs.size() = %d sortedItems.size() = %d\n",costs.size(),sortedItems.size()); + + if (hasDup) { + printf + ("WARNING, upgrade type [%s] has one or more duplicate resource requirements\n", + this->getName().c_str()); + } + + if (sortedItems.size() < costs.size()) { + costs.resize(sortedItems.size()); + } + + index = 0; + for (std::map < string, int >::iterator iterMap = + sortedItems.begin(); iterMap != sortedItems.end(); ++iterMap) { + try { + costs[index].init(techTree->getResourceType(iterMap->first), + iterMap->second); + index++; + } catch (megaglest_runtime_error & ex) { + if (validationMode == false) { + throw; + } else { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\nFor UpgradeType: %s Cost: %d\n", + extractFileFromDirectoryPath + (__FILE__).c_str(), __FUNCTION__, + __LINE__, ex.what(), name.c_str(), + iterMap->second); + } + } + + } + sortedItems.clear(); + //hasDup = false; + + //effects -- get list of affected units + const XmlNode *effectsNode = upgradeNode->getChild("effects"); + vector < XmlNode * >unitNodes = effectsNode->getChildList("unit"); + for (size_t i = 0; i < unitNodes.size(); ++i) { + const XmlNode *unitNode = unitNodes.at(i); + string name = + unitNode->getAttribute("name")->getRestrictedValue(); + + effects.insert(factionType->getUnitType(name)); + } + + //effects -- convert tags into units + vector < XmlNode * >tagNodes = effectsNode->getChildList("tag"); + for (size_t i = 0; i < tagNodes.size(); ++i) { + const XmlNode *tagNode = tagNodes.at(i); + string name = tagNode->getAttribute("name")->getRestrictedValue(); + tags.insert(name); + } + + //values + UpgradeTypeBase::load(upgradeNode, name); + } catch (megaglest_runtime_error & ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + extractFileFromDirectoryPath(__FILE__). + c_str(), __FUNCTION__, __LINE__, + ex.what()); + throw megaglest_runtime_error("Error loading UpgradeType: " + + currentPath + "\nMessage: " + + ex.what(), !ex.wantStackTrace()); + } catch (const exception & e) { + SystemFlags::OutputDebug(SystemFlags::debugError, + "In [%s::%s Line: %d] Error [%s]\n", + __FILE__, __FUNCTION__, __LINE__, + e.what()); + throw megaglest_runtime_error("Error loading UpgradeType: " + + currentPath + "\n" + e.what()); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", __FILE__, + __FUNCTION__, __LINE__); + } + + bool UpgradeType::isAffected(const UnitType * unitType) const { + if (std::find(effects.begin(), effects.end(), unitType) != + effects.end()) + return true; + + const set < string > unitTags = unitType->getTags(); + set < string > intersect; + set_intersection(tags.begin(), tags.end(), unitTags.begin(), + unitTags.end(), std::inserter(intersect, + intersect.begin())); + if (!intersect.empty()) + return true; + + return false; + } + + //void UpgradeType::saveGame(XmlNode *rootNode) const { + // UpgradeTypeBase::saveGame(rootNode); + // ProducibleType::saveGame(rootNode); + // + // std::map mapTagReplacements; + // XmlNode *upgradeTypeNode = rootNode->addChild("UpgradeType"); + // + // //upgradeTypeNode->addAttribute("maxHp",intToStr(maxHp), mapTagReplacements); + // //vector effects; + // for(unsigned int i = 0; i < effects.size(); ++i) { + // XmlNode *unitTypeNode = rootNode->addChild("UnitType"); + // + // const UnitType *ut = effects[i]; + // unitTypeNode->addAttribute("name",ut->getName(), mapTagReplacements); + // } + //} + // + //void UpgradeType::loadGame(const XmlNode *rootNode, Faction *faction) { + // //UpgradeTypeBase::loadGame(rootNode); + // //ProducibleType::loadGame(rootNode); + // + // //const XmlNode *upgradeTypeNode = rootNode->getChild("UpgradeType"); + // + // //maxHp = upgradeTypeNode->getAttribute("maxHp")->getIntValue(); + // + //// vector unitTypeNodeList = upgradeTypeNode->getChildList("UnitType"); + //// for(unsigned int i = 0; i < unitTypeNodeList.size(); ++i) { + //// XmlNode *node = unitTypeNodeList[i]; + //// } + //} + + // =============================== + // class TotalUpgrade + // =============================== + + TotalUpgrade::TotalUpgrade() { + reset(); + } + + void TotalUpgrade::reset() { + maxHp = 0; + maxHpIsMultiplier = false; + maxHpRegeneration = 0; + + maxEp = 0; + maxEpIsMultiplier = false; + maxEpRegeneration = 0; + + sight = 0; + sightIsMultiplier = false; + + armor = 0; + armorIsMultiplier = false; + + attackStrength = 0; + attackStrengthIsMultiplier = false; + + attackRange = 0; + attackRangeIsMultiplier = false; + + moveSpeed = 0; + moveSpeedIsMultiplier = false; + + prodSpeed = 0; + prodSpeedIsMultiplier = false; + + attackSpeed = 0; + attackSpeedIsMultiplier = false; + + boostUpgradeBase = NULL; + boostUpgradeSourceUnit = -1; + boostUpgradeDestUnit = -1; + } + + void TotalUpgrade::sum(const UpgradeTypeBase * ut, const Unit * unit, + bool boostMode) { + maxHpIsMultiplier = ut->getMaxHpIsMultiplier(); + sightIsMultiplier = ut->getSightIsMultiplier(); + maxEpIsMultiplier = ut->getMaxEpIsMultiplier(); + armorIsMultiplier = ut->getArmorIsMultiplier(); + attackStrengthIsMultiplier = ut->getAttackStrengthIsMultiplier(); + attackRangeIsMultiplier = ut->getAttackRangeIsMultiplier(); + moveSpeedIsMultiplier = ut->getMoveSpeedIsMultiplier(); + prodSpeedIsMultiplier = ut->getProdSpeedIsMultiplier(); + attackSpeedIsMultiplier = ut->getAttackSpeedIsMultiplier(); + + if (ut->getMaxHpIsMultiplier() == true) { + //printf("#1 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp()); + int newValue = + ((double) unit->getHp() * + ((double) ut->getMaxHp() / (double) 100)); + if (boostMode) { + maxHp = newValue; + } else { + maxHp += newValue; + } + if (ut->getMaxHpRegeneration() != 0) { + newValue = + ((double) unit->getType()->getHpRegeneration() + + ((double) max(maxHp, unit->getHp()) * + ((double) ut->getMaxHpRegeneration() / (double) 100))); + if (boostMode) { + maxHpRegeneration = newValue; + } else { + maxHpRegeneration += newValue; + } + } + //printf("#1.1 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp()); + } else { + //printf("#2 Maxhp maxHp = %d, unit->getHp() = %d ut->getMaxHp() = %d\n",maxHp,unit->getHp(),ut->getMaxHp()); + int newValue = ut->getMaxHp(); + if (boostMode) { + maxHp = newValue; + } else { + maxHp += newValue; + } + + if (ut->getMaxHpRegeneration() != 0) { + newValue = ut->getMaxHpRegeneration(); + if (boostMode) { + maxHpRegeneration = newValue; + } else { + maxHpRegeneration += newValue; + } + } + } + + if (ut->getMaxEpIsMultiplier() == true) { + int newValue = + ((double) unit->getEp() * + ((double) ut->getMaxEp() / (double) 100)); + if (boostMode) { + maxEp = newValue; + } else { + maxEp += newValue; + } + + if (ut->getMaxEpRegeneration() != 0) { + newValue = + ((double) unit->getType()->getEpRegeneration() + + ((double) max(maxEp, unit->getEp()) * + ((double) ut->getMaxEpRegeneration() / (double) 100))); + if (boostMode) { + maxEpRegeneration = newValue; + } else { + maxEpRegeneration += newValue; + } + } + } else { + int newValue = ut->getMaxEp(); + if (boostMode) { + maxEp = newValue; + } else { + maxEp += newValue; + } + + if (ut->getMaxEpRegeneration() != 0) { + newValue = ut->getMaxEpRegeneration(); + if (boostMode) { + maxEpRegeneration = newValue; + } else { + maxEpRegeneration += newValue; + } + } + } + + if (ut->getSightIsMultiplier() == true) { + int newValue = + ((double) unit->getType()->getSight() * + ((double) ut->getSight() / (double) 100)); + if (boostMode) { + sight = newValue; + } else { + sight += newValue; + } + } else { + int newValue = ut->getSight(); + if (boostMode) { + sight = newValue; + } else { + sight += newValue; + } + } + + if (ut->getArmorIsMultiplier() == true) { + int newValue = + ((double) unit->getType()->getArmor() * + ((double) ut->getArmor() / (double) 100)); + if (boostMode) { + armor = newValue; + } else { + armor += newValue; + } + } else { + int newValue = ut->getArmor(); + if (boostMode) { + armor = newValue; + } else { + armor += newValue; + } + } + + if (ut->getAttackStrengthIsMultiplier() == true) { + for (unsigned int i = 0; + i < (unsigned int) unit->getType()->getSkillTypeCount(); ++i) { + const SkillType *skillType = unit->getType()->getSkillType(i); + const AttackSkillType *ast = + dynamic_cast (skillType); + if (ast != NULL) { + int newValue = + ((double) ast->getAttackStrength() * + ((double) ut->getAttackStrength(NULL) / (double) 100)); + if (boostMode) { + attackStrengthMultiplierValueList[ast->getName()] = newValue; + } else { + attackStrengthMultiplierValueList[ast->getName()] += newValue; + } + } + } + } else { + int newValue = ut->getAttackStrength(NULL); + if (boostMode) { + attackStrength = newValue; + } else { + attackStrength += newValue; + } + } + + if (ut->getAttackRangeIsMultiplier() == true) { + for (unsigned int i = 0; + i < (unsigned int) unit->getType()->getSkillTypeCount(); ++i) { + const SkillType *skillType = unit->getType()->getSkillType(i); + const AttackSkillType *ast = + dynamic_cast (skillType); + if (ast != NULL) { + int newValue = + ((double) ast->getAttackRange() * + ((double) ut->getAttackRange(NULL) / (double) 100)); + if (boostMode) { + attackRangeMultiplierValueList[ast->getName()] = newValue; + } else { + attackRangeMultiplierValueList[ast->getName()] += newValue; + } + } + } + } else { + int newValue = ut->getAttackRange(NULL); + if (boostMode) { + attackRange = newValue; + } else { + attackRange += newValue; + } + } + + if (ut->getMoveSpeedIsMultiplier() == true) { + for (unsigned int i = 0; + i < (unsigned int) unit->getType()->getSkillTypeCount(); ++i) { + const SkillType *skillType = unit->getType()->getSkillType(i); + const MoveSkillType *mst = + dynamic_cast (skillType); + if (mst != NULL) { + int newValue = + ((double) mst->getSpeed() * + ((double) ut->getMoveSpeed(NULL) / (double) 100)); + if (boostMode) { + moveSpeedIsMultiplierValueList[mst->getName()] = newValue; + } else { + moveSpeedIsMultiplierValueList[mst->getName()] += newValue; + } + } + } + } else { + int newValue = ut->getMoveSpeed(NULL); + if (boostMode) { + moveSpeed = newValue; + } else { + moveSpeed += newValue; + } + } + + if (ut->getProdSpeedIsMultiplier() == true) { + for (unsigned int i = 0; + i < (unsigned int) unit->getType()->getSkillTypeCount(); ++i) { + const SkillType *skillType = unit->getType()->getSkillType(i); + const ProduceSkillType *pst = + dynamic_cast (skillType); + if (pst != NULL) { + int newValue = + ((double) pst->getSpeed() * + ((double) ut->getProdSpeed(NULL) / (double) 100)); + if (boostMode) { + prodSpeedProduceIsMultiplierValueList[pst->getName()] = + newValue; + } else { + prodSpeedProduceIsMultiplierValueList[pst->getName()] += + newValue; + } + } + const UpgradeSkillType *ust = + dynamic_cast (skillType); + if (ust != NULL) { + int newValue = + ((double) ust->getSpeed() * + ((double) ut->getProdSpeed(NULL) / (double) 100)); + if (boostMode) { + prodSpeedUpgradeIsMultiplierValueList[ust->getName()] = + newValue; + } else { + prodSpeedUpgradeIsMultiplierValueList[ust->getName()] += + newValue; + } + } + const MorphSkillType *mst = + dynamic_cast (skillType); + if (mst != NULL) { + int newValue = + ((double) mst->getSpeed() * + ((double) ut->getProdSpeed(NULL) / (double) 100)); + if (boostMode) { + prodSpeedMorphIsMultiplierValueList[mst->getName()] = newValue; + } else { + prodSpeedMorphIsMultiplierValueList[mst->getName()] += + newValue; + } + } + } + } else { + int newValue = ut->getProdSpeed(NULL); + if (boostMode) { + prodSpeed = newValue; + } else { + prodSpeed += newValue; + } + } + + if (ut->getAttackSpeedIsMultiplier() == true) { + for (unsigned int i = 0; + i < (unsigned int) unit->getType()->getSkillTypeCount(); ++i) { + const SkillType *skillType = unit->getType()->getSkillType(i); + const AttackSkillType *ast = + dynamic_cast (skillType); + if (ast != NULL) { + int newValue = + ((double) ast->getSpeed() * + ((double) ut->getAttackSpeed(NULL) / (double) 100)); + if (boostMode) { + attackSpeedIsMultiplierValueList[ast->getName()] = newValue; + } else { + attackSpeedIsMultiplierValueList[ast->getName()] += newValue; + } + } + } + } else { + int newValue = ut->getAttackSpeed(NULL); + if (boostMode) { + attackSpeed = newValue; + } else { + attackSpeed += newValue; + } + } + } + + void TotalUpgrade::apply(int sourceUnitId, const UpgradeTypeBase * ut, + const Unit * unit) { + //sum(ut, unit); + + //printf("====> About to apply boost: %s\nTo unit: %d\n\n",ut->toString().c_str(),unit->getId()); + TotalUpgrade *boostUpgrade = new TotalUpgrade(); + boostUpgrade->copyDataFrom(this); + boostUpgrade->boostUpgradeBase = ut; + boostUpgrade->boostUpgradeSourceUnit = sourceUnitId; + boostUpgrade->boostUpgradeDestUnit = unit->getId(); + + boostUpgrade->sum(ut, unit, true); + boostUpgrades.push_back(boostUpgrade); + } + + void TotalUpgrade::deapply(int sourceUnitId, const UpgradeTypeBase * ut, + int destUnitId) { + //printf("<****** About to de-apply boost: %s\nTo unit: %d\n\n",ut->toString().c_str(),destUnitId); + + bool removedBoost = false; + for (unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + if (boost->boostUpgradeSourceUnit == sourceUnitId && + boost->boostUpgradeBase->getUpgradeName() == + ut->getUpgradeName() + && boost->boostUpgradeDestUnit == destUnitId) { + + boostUpgrades.erase(boostUpgrades.begin() + index); + delete boost; + removedBoost = true; + + //printf("de-apply boost FOUND!\n"); + break; + } + } + if (removedBoost == false) { + printf + ("\n\n!!!!!! de-apply boost NOT FOUND for sourceUnitId = %d, destUnitId = %d\n%s\n\nCurrent Boosts:\n", + sourceUnitId, destUnitId, ut->toString().c_str()); + for (unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + printf("\nBoost #%u\n%s\n", index, boost->toString().c_str()); + } + } + } + + int TotalUpgrade::getMaxHp() const { + return maxHp + getMaxHpFromBoosts(); + } + int TotalUpgrade::getMaxHpFromBoosts() const { + int result = 0; + for (unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getMaxHp(); + } + return result; + } + int TotalUpgrade::getMaxHpRegeneration() const { + return maxHpRegeneration + getMaxHpRegenerationFromBoosts(); + } + int TotalUpgrade::getMaxHpRegenerationFromBoosts() const { + int result = 0; + for (unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getMaxHpRegeneration(); + } + return result; + } + int TotalUpgrade::getSight() const { + return sight + getSightFromBoosts(); + } + int TotalUpgrade::getSightFromBoosts() const { + int result = 0; + for (unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getSight(); + } + return result; + } + int TotalUpgrade::getMaxEp() const { + return maxEp + getMaxEpFromBoosts(); + } + int TotalUpgrade::getMaxEpFromBoosts() const { + int result = 0; + for (unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getMaxEp(); + } + return result; + } + + int TotalUpgrade::getMaxEpRegeneration() const { + return maxEpRegeneration + getMaxEpRegenerationFromBoosts(); + } + int TotalUpgrade::getMaxEpRegenerationFromBoosts() const { + int result = 0; + for (unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getMaxEpRegeneration(); + } + return result; + } + + int TotalUpgrade::getArmor() const { + return armor + getArmorFromBoosts(); + } + int TotalUpgrade::getArmorFromBoosts() const { + int result = 0; + for (unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getArmor(); + } + return result; + } + + int TotalUpgrade::getAttackStrength(const AttackSkillType * st) const { + return UpgradeTypeBase::getAttackStrength(st) + + getAttackStrengthFromBoosts(st); + } + int TotalUpgrade::getAttackStrengthFromBoosts(const AttackSkillType * st) const { + int result = 0; + for (unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getAttackStrength(st); + } + return result; + } + + int TotalUpgrade::getAttackRange(const AttackSkillType * st) const { + return UpgradeTypeBase::getAttackRange(st) + + getAttackRangeFromBoosts(st); + } + int TotalUpgrade::getAttackRangeFromBoosts(const AttackSkillType * st) const { + int result = 0; + for (unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getAttackRange(st); + } + return result; + } + + int TotalUpgrade::getMoveSpeed(const MoveSkillType * st) const { + return UpgradeTypeBase::getMoveSpeed(st) + getMoveSpeedFromBoosts(st); + } + int TotalUpgrade::getMoveSpeedFromBoosts(const MoveSkillType * st) const { + int result = 0; + for (unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getMoveSpeed(st); + } + return result; + } + + int TotalUpgrade::getProdSpeed(const SkillType * st) const { + return UpgradeTypeBase::getProdSpeed(st) + getProdSpeedFromBoosts(st); + } + int TotalUpgrade::getProdSpeedFromBoosts(const SkillType * st) const { + int result = 0; + for (unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getProdSpeed(st); + } + return result; + } + + int TotalUpgrade::getAttackSpeed(const AttackSkillType * st) const { + return UpgradeTypeBase::getAttackSpeed(st) + + getAttackSpeedFromBoosts(st); + } + int TotalUpgrade::getAttackSpeedFromBoosts(const AttackSkillType * st) const { + int result = 0; + for (unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + result += boost->getAttackSpeed(st); + } + return result; + } + + void TotalUpgrade::incLevel(const UnitType * ut) { + maxHp += ut->getMaxHp() * 50 / 100; + maxEp += ut->getMaxEp() * 50 / 100; + sight += ut->getSight() * 20 / 100; + armor += ut->getArmor() * 50 / 100; + + for (unsigned int index = 0; index < boostUpgrades.size(); ++index) { + TotalUpgrade *boost = boostUpgrades[index]; + boost->copyDataFrom(this); + } + } + + void TotalUpgrade::saveGame(XmlNode * rootNode) const { + std::map < string, string > mapTagReplacements; + XmlNode *upgradeTypeBaseNode = rootNode->addChild("TotalUpgrade"); + + // int maxHp; + upgradeTypeBaseNode->addAttribute("maxHp", intToStr(maxHp), + mapTagReplacements); + // bool maxHpIsMultiplier; + upgradeTypeBaseNode->addAttribute("maxHpIsMultiplier", + intToStr(maxHpIsMultiplier), + mapTagReplacements); + // int maxHpRegeneration; + upgradeTypeBaseNode->addAttribute("maxHpRegeneration", + intToStr(maxHpRegeneration), + mapTagReplacements); + // //bool maxHpRegenerationIsMultiplier; + // + // int sight; + upgradeTypeBaseNode->addAttribute("sight", intToStr(sight), + mapTagReplacements); + // bool sightIsMultiplier; + upgradeTypeBaseNode->addAttribute("sightIsMultiplier", + intToStr(sightIsMultiplier), + mapTagReplacements); + // int maxEp; + upgradeTypeBaseNode->addAttribute("maxEp", intToStr(maxEp), + mapTagReplacements); + // bool maxEpIsMultiplier; + upgradeTypeBaseNode->addAttribute("maxEpIsMultiplier", + intToStr(maxEpIsMultiplier), + mapTagReplacements); + // int maxEpRegeneration; + upgradeTypeBaseNode->addAttribute("maxEpRegeneration", + intToStr(maxEpRegeneration), + mapTagReplacements); + // //bool maxEpRegenerationIsMultiplier; + // int armor; + upgradeTypeBaseNode->addAttribute("armor", intToStr(armor), + mapTagReplacements); + // bool armorIsMultiplier; + upgradeTypeBaseNode->addAttribute("armorIsMultiplier", + intToStr(armorIsMultiplier), + mapTagReplacements); + // int attackStrength; + upgradeTypeBaseNode->addAttribute("attackStrength", + intToStr(attackStrength), + mapTagReplacements); + // bool attackStrengthIsMultiplier; + upgradeTypeBaseNode->addAttribute("attackStrengthIsMultiplier", + intToStr + (attackStrengthIsMultiplier), + mapTagReplacements); + // std::map attackStrengthMultiplierValueList; + for (std::map < string, int >::const_iterator iterMap = + attackStrengthMultiplierValueList.begin(); + iterMap != attackStrengthMultiplierValueList.end(); ++iterMap) { + XmlNode *attackStrengthMultiplierValueListNode = + upgradeTypeBaseNode->addChild("attackStrengthMultiplierValueList"); + + attackStrengthMultiplierValueListNode->addAttribute("key", + iterMap->first, + mapTagReplacements); + attackStrengthMultiplierValueListNode->addAttribute("value", + intToStr + (iterMap-> + second), + mapTagReplacements); + } + // int attackRange; + upgradeTypeBaseNode->addAttribute("attackRange", + intToStr(attackRange), + mapTagReplacements); + // bool attackRangeIsMultiplier; + upgradeTypeBaseNode->addAttribute("attackRangeIsMultiplier", + intToStr(attackRangeIsMultiplier), + mapTagReplacements); + // std::map attackRangeMultiplierValueList; + for (std::map < string, int >::const_iterator iterMap = + attackRangeMultiplierValueList.begin(); + iterMap != attackRangeMultiplierValueList.end(); ++iterMap) { + XmlNode *attackRangeMultiplierValueListNode = + upgradeTypeBaseNode->addChild("attackRangeMultiplierValueList"); + + attackRangeMultiplierValueListNode->addAttribute("key", + iterMap->first, + mapTagReplacements); + attackRangeMultiplierValueListNode->addAttribute("value", + intToStr(iterMap-> + second), + mapTagReplacements); + } + + // int moveSpeed; + upgradeTypeBaseNode->addAttribute("moveSpeed", intToStr(moveSpeed), + mapTagReplacements); + // bool moveSpeedIsMultiplier; + upgradeTypeBaseNode->addAttribute("moveSpeedIsMultiplier", + intToStr(moveSpeedIsMultiplier), + mapTagReplacements); + // std::map moveSpeedIsMultiplierValueList; + for (std::map < string, int >::const_iterator iterMap = + moveSpeedIsMultiplierValueList.begin(); + iterMap != moveSpeedIsMultiplierValueList.end(); ++iterMap) { + XmlNode *moveSpeedIsMultiplierValueListNode = + upgradeTypeBaseNode->addChild("moveSpeedIsMultiplierValueList"); + + moveSpeedIsMultiplierValueListNode->addAttribute("key", + iterMap->first, + mapTagReplacements); + moveSpeedIsMultiplierValueListNode->addAttribute("value", + intToStr(iterMap-> + second), + mapTagReplacements); + } + + // int prodSpeed; + upgradeTypeBaseNode->addAttribute("prodSpeed", intToStr(prodSpeed), + mapTagReplacements); + // bool prodSpeedIsMultiplier; + upgradeTypeBaseNode->addAttribute("prodSpeedIsMultiplier", + intToStr(prodSpeedIsMultiplier), + mapTagReplacements); + // std::map prodSpeedProduceIsMultiplierValueList; + for (std::map < string, int >::const_iterator iterMap = + prodSpeedProduceIsMultiplierValueList.begin(); + iterMap != prodSpeedProduceIsMultiplierValueList.end(); ++iterMap) { + XmlNode *prodSpeedProduceIsMultiplierValueListNode = + upgradeTypeBaseNode-> + addChild("prodSpeedProduceIsMultiplierValueList"); + + prodSpeedProduceIsMultiplierValueListNode->addAttribute("key", + iterMap-> + first, + mapTagReplacements); + prodSpeedProduceIsMultiplierValueListNode->addAttribute("value", + intToStr + (iterMap-> + second), + mapTagReplacements); + } + + // std::map prodSpeedUpgradeIsMultiplierValueList; + for (std::map < string, int >::const_iterator iterMap = + prodSpeedUpgradeIsMultiplierValueList.begin(); + iterMap != prodSpeedUpgradeIsMultiplierValueList.end(); ++iterMap) { + XmlNode *prodSpeedUpgradeIsMultiplierValueListNode = + upgradeTypeBaseNode-> + addChild("prodSpeedUpgradeIsMultiplierValueList"); + + prodSpeedUpgradeIsMultiplierValueListNode->addAttribute("key", + iterMap-> + first, + mapTagReplacements); + prodSpeedUpgradeIsMultiplierValueListNode->addAttribute("value", + intToStr + (iterMap-> + second), + mapTagReplacements); + } + + // std::map prodSpeedMorphIsMultiplierValueList; + for (std::map < string, int >::const_iterator iterMap = + prodSpeedMorphIsMultiplierValueList.begin(); + iterMap != prodSpeedMorphIsMultiplierValueList.end(); ++iterMap) { + XmlNode *prodSpeedMorphIsMultiplierValueListNode = + upgradeTypeBaseNode-> + addChild("prodSpeedMorphIsMultiplierValueList"); + + prodSpeedMorphIsMultiplierValueListNode->addAttribute("key", + iterMap->first, + mapTagReplacements); + prodSpeedMorphIsMultiplierValueListNode->addAttribute("value", + intToStr + (iterMap-> + second), + mapTagReplacements); + } + + upgradeTypeBaseNode->addAttribute("attackSpeed", + intToStr(attackSpeed), + mapTagReplacements); + upgradeTypeBaseNode->addAttribute("attackSpeedIsMultiplier", + intToStr(attackSpeedIsMultiplier), + mapTagReplacements); + for (std::map < string, int >::const_iterator iterMap = + attackSpeedIsMultiplierValueList.begin(); + iterMap != attackSpeedIsMultiplierValueList.end(); ++iterMap) { + XmlNode *attackSpeedIsMultiplierValueListNode = + upgradeTypeBaseNode->addChild("attackSpeedIsMultiplierValueList"); + + attackSpeedIsMultiplierValueListNode->addAttribute("key", + iterMap->first, + mapTagReplacements); + attackSpeedIsMultiplierValueListNode->addAttribute("value", + intToStr + (iterMap->second), + mapTagReplacements); + } + + // for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + // TotalUpgrade *boost = boostUpgrades[index]; + // XmlNode *attackBoostListNode = upgradeTypeBaseNode->addChild("attackBoostList"); + // attackBoostListNode->addAttribute("unitId",intToStr(boost->boostUpgradeUnit->getId()), mapTagReplacements); + // + // std::map mapTagReplacements; + // if(boost != NULL) { + // boost->saveGameBoost(attackBoostListNode); + // boost->boostUpgradeBase->saveGameBoost(attackBoostListNode); + // } + // } + } + + void TotalUpgrade::loadGame(const XmlNode * rootNode) { + const XmlNode *upgradeTypeBaseNode = + rootNode->getChild("TotalUpgrade"); + + //description = upgradeTypeBaseNode->getAttribute("description")->getValue(); + + // int maxHp; + maxHp = upgradeTypeBaseNode->getAttribute("maxHp")->getIntValue(); + // bool maxHpIsMultiplier; + maxHpIsMultiplier = + upgradeTypeBaseNode->getAttribute("maxHpIsMultiplier")-> + getIntValue() != 0; + // int maxHpRegeneration; + maxHpRegeneration = + upgradeTypeBaseNode->getAttribute("maxHpRegeneration")-> + getIntValue(); + // //bool maxHpRegenerationIsMultiplier; + // + // int sight; + sight = upgradeTypeBaseNode->getAttribute("sight")->getIntValue(); + // bool sightIsMultiplier; + sightIsMultiplier = + upgradeTypeBaseNode->getAttribute("sightIsMultiplier")-> + getIntValue() != 0; + // int maxEp; + maxEp = upgradeTypeBaseNode->getAttribute("maxEp")->getIntValue(); + // bool maxEpIsMultiplier; + maxEpIsMultiplier = + upgradeTypeBaseNode->getAttribute("maxEpIsMultiplier")-> + getIntValue() != 0; + // int maxEpRegeneration; + maxEpRegeneration = + upgradeTypeBaseNode->getAttribute("maxEpRegeneration")-> + getIntValue(); + // //bool maxEpRegenerationIsMultiplier; + // int armor; + armor = upgradeTypeBaseNode->getAttribute("armor")->getIntValue(); + // bool armorIsMultiplier; + armorIsMultiplier = + upgradeTypeBaseNode->getAttribute("armorIsMultiplier")-> + getIntValue() != 0; + // int attackStrength; + attackStrength = + upgradeTypeBaseNode->getAttribute("attackStrength")->getIntValue(); + // bool attackStrengthIsMultiplier; + attackStrengthIsMultiplier = + upgradeTypeBaseNode->getAttribute("attackStrengthIsMultiplier")-> + getIntValue() != 0; + // std::map attackStrengthMultiplierValueList; + vector < XmlNode * >attackStrengthMultiplierValueNodeList = + upgradeTypeBaseNode-> + getChildList("attackStrengthMultiplierValueList"); + for (unsigned int i = 0; + i < attackStrengthMultiplierValueNodeList.size(); ++i) { + XmlNode *node = attackStrengthMultiplierValueNodeList[i]; + + attackStrengthMultiplierValueList[node->getAttribute("key")-> + getValue()] = + node->getAttribute("value")->getIntValue(); + } + // int attackRange; + attackRange = + upgradeTypeBaseNode->getAttribute("attackRange")->getIntValue(); + // bool attackRangeIsMultiplier; + attackRangeIsMultiplier = + upgradeTypeBaseNode->getAttribute("attackRangeIsMultiplier")-> + getIntValue() != 0; + // std::map attackRangeMultiplierValueList; + vector < XmlNode * >attackRangeMultiplierValueNodeList = + upgradeTypeBaseNode->getChildList("attackRangeMultiplierValueList"); + for (unsigned int i = 0; i < attackRangeMultiplierValueNodeList.size(); + ++i) { + XmlNode *node = attackRangeMultiplierValueNodeList[i]; + + attackRangeMultiplierValueList[node->getAttribute("key")-> + getValue()] = + node->getAttribute("value")->getIntValue(); + } + + // int moveSpeed; + moveSpeed = + upgradeTypeBaseNode->getAttribute("moveSpeed")->getIntValue(); + // bool moveSpeedIsMultiplier; + moveSpeedIsMultiplier = + upgradeTypeBaseNode->getAttribute("moveSpeedIsMultiplier")-> + getIntValue() != 0; + // std::map moveSpeedIsMultiplierValueList; + vector < XmlNode * >moveSpeedIsMultiplierValueNodeList = + upgradeTypeBaseNode->getChildList("moveSpeedIsMultiplierValueList"); + for (unsigned int i = 0; i < moveSpeedIsMultiplierValueNodeList.size(); + ++i) { + XmlNode *node = moveSpeedIsMultiplierValueNodeList[i]; + + moveSpeedIsMultiplierValueList[node->getAttribute("key")-> + getValue()] = + node->getAttribute("value")->getIntValue(); + } + + // int prodSpeed; + prodSpeed = + upgradeTypeBaseNode->getAttribute("prodSpeed")->getIntValue(); + // bool prodSpeedIsMultiplier; + prodSpeedIsMultiplier = + upgradeTypeBaseNode->getAttribute("prodSpeedIsMultiplier")-> + getIntValue() != 0; + // std::map prodSpeedProduceIsMultiplierValueList; + vector < XmlNode * >prodSpeedProduceIsMultiplierValueNodeList = + upgradeTypeBaseNode-> + getChildList("prodSpeedProduceIsMultiplierValueList"); + for (unsigned int i = 0; + i < prodSpeedProduceIsMultiplierValueNodeList.size(); ++i) { + XmlNode *node = prodSpeedProduceIsMultiplierValueNodeList[i]; + + prodSpeedProduceIsMultiplierValueList[node->getAttribute("key")-> + getValue()] = + node->getAttribute("value")->getIntValue(); + } + + // std::map prodSpeedUpgradeIsMultiplierValueList; + vector < XmlNode * >prodSpeedUpgradeIsMultiplierValueNodeList = + upgradeTypeBaseNode-> + getChildList("prodSpeedUpgradeIsMultiplierValueList"); + for (unsigned int i = 0; + i < prodSpeedUpgradeIsMultiplierValueNodeList.size(); ++i) { + XmlNode *node = prodSpeedUpgradeIsMultiplierValueNodeList[i]; + + prodSpeedUpgradeIsMultiplierValueList[node->getAttribute("key")-> + getValue()] = + node->getAttribute("value")->getIntValue(); + } + + // std::map prodSpeedMorphIsMultiplierValueList; + vector < XmlNode * >prodSpeedMorphIsMultiplierValueNodeList = + upgradeTypeBaseNode-> + getChildList("prodSpeedMorphIsMultiplierValueList"); + for (unsigned int i = 0; + i < prodSpeedMorphIsMultiplierValueNodeList.size(); ++i) { + XmlNode *node = prodSpeedMorphIsMultiplierValueNodeList[i]; + + prodSpeedMorphIsMultiplierValueList[node->getAttribute("key")-> + getValue()] = + node->getAttribute("value")->getIntValue(); + } + + if (upgradeTypeBaseNode->hasAttribute("attackSpeed")) { + attackSpeed = + upgradeTypeBaseNode->getAttribute("attackSpeed")->getIntValue(); + attackSpeedIsMultiplier = + upgradeTypeBaseNode->getAttribute("attackSpeedIsMultiplier")-> + getIntValue() != 0; + vector < XmlNode * >attackSpeedIsMultiplierValueNodeList = + upgradeTypeBaseNode-> + getChildList("attackSpeedIsMultiplierValueList"); + for (unsigned int i = 0; + i < attackSpeedIsMultiplierValueNodeList.size(); ++i) { + XmlNode *node = attackSpeedIsMultiplierValueNodeList[i]; + + attackSpeedIsMultiplierValueList[node->getAttribute("key")-> + getValue()] = + node->getAttribute("value")->getIntValue(); + } + } + + // vector boostNodeList = upgradeTypeBaseNode->getChildList("attackBoostList"); + // for(unsigned int index = 0; index < boostNodeList.size(); ++index) { + // XmlNode *boostNode = boostNodeList[index]; + // + // //for(unsigned int index = 0; index < boostUpgrades.size(); ++index) { + // // TotalUpgrade *boost = boostUpgrades[index]; + // // XmlNode *attackBoostListNode = upgradeTypeBaseNode->addChild("attackBoostList"); + // + //// std::map mapTagReplacements; + //// if(boost != NULL) { + //// boost->saveGame(attackBoostListNode); + //// } + // int unitId = boostNode->getAttribute("unitId")->getIntValue(); + // const Unit *unit = world->findUnitById(unitId); + // + // TotalUpgrade *boostUpgrade = new TotalUpgrade(); + // //boostUpgrade->copyDataFrom(this); + // boostUpgrade->loadGameBoost(boostNode); + // boostUpgrade->loadGameBoost(boostNode); + // + // boostUpgrade->boostUpgradeBase = ut; + // boostUpgrade->boostUpgradeUnit = unit; + // + // //boostUpgrade->sum(ut,unit); + // boostUpgrades.push_back(boostUpgrade); + // + // //boost->saveGameBoost(attackBoostListNode); + // //boost->boostUpgradeBase->saveGameBoost(attackBoostListNode); + // + // //apply(const UpgradeTypeBase *ut, unit); + // } + + } + + + } +} //end namespace diff --git a/source/glest_game/types/upgrade_type.h b/source/glest_game/types/upgrade_type.h index 919c29850..6a2e652f3 100644 --- a/source/glest_game/types/upgrade_type.h +++ b/source/glest_game/types/upgrade_type.h @@ -36,545 +36,504 @@ using Shared::Util::Checksum; using namespace Shared::Util; using namespace Shared::Xml; -namespace Glest -{ - namespace Game - { +namespace Glest { + namespace Game { - class TechTree; - class FactionType; - class UnitType; - class Unit; - class SkillType; - class AttackSkillType; - class MoveSkillType; - class ProduceSkillType; - class Faction; + class TechTree; + class FactionType; + class UnitType; + class Unit; + class SkillType; + class AttackSkillType; + class MoveSkillType; + class ProduceSkillType; + class Faction; -/** - * Groups all information used for upgrades. Attack boosts also use this class for modifying stats. - */ - class UpgradeTypeBase - { - protected: - string upgradename; - int maxHp; - bool maxHpIsMultiplier; - int maxHpRegeneration; - //bool maxHpRegenerationIsMultiplier; + /** + * Groups all information used for upgrades. Attack boosts also use this class for modifying stats. + */ + class UpgradeTypeBase { + protected: + string upgradename; + int maxHp; + bool maxHpIsMultiplier; + int maxHpRegeneration; + //bool maxHpRegenerationIsMultiplier; - int sight; - bool sightIsMultiplier; + int sight; + bool sightIsMultiplier; - int maxEp; - bool maxEpIsMultiplier; - int maxEpRegeneration; - //bool maxEpRegenerationIsMultiplier; + int maxEp; + bool maxEpIsMultiplier; + int maxEpRegeneration; + //bool maxEpRegenerationIsMultiplier; - int armor; - bool armorIsMultiplier; + int armor; + bool armorIsMultiplier; - int attackStrength; - bool attackStrengthIsMultiplier; - /** - * List of the values (for each skill type) that the stat was boosted by. This is used so - * that we can restore the original values when the upgrade is removed (eg, an attack - * boost wears off). - */ - std::map < string, int >attackStrengthMultiplierValueList; + int attackStrength; + bool attackStrengthIsMultiplier; + /** + * List of the values (for each skill type) that the stat was boosted by. This is used so + * that we can restore the original values when the upgrade is removed (eg, an attack + * boost wears off). + */ + std::map < string, int >attackStrengthMultiplierValueList; - int attackRange; - bool attackRangeIsMultiplier; - std::map < string, int >attackRangeMultiplierValueList; - /**< @see #attackStrengthMultiplierValueList */ + int attackRange; + bool attackRangeIsMultiplier; + std::map < string, int >attackRangeMultiplierValueList; + /**< @see #attackStrengthMultiplierValueList */ - int moveSpeed; - bool moveSpeedIsMultiplier; - std::map < string, int >moveSpeedIsMultiplierValueList; - /**< @see #attackStrengthMultiplierValueList */ + int moveSpeed; + bool moveSpeedIsMultiplier; + std::map < string, int >moveSpeedIsMultiplierValueList; + /**< @see #attackStrengthMultiplierValueList */ - int prodSpeed; - bool prodSpeedIsMultiplier; - std::map < string, int >prodSpeedProduceIsMultiplierValueList; - /**< @see #attackStrengthMultiplierValueList */ - std::map < string, int >prodSpeedUpgradeIsMultiplierValueList; - /**< @see #attackStrengthMultiplierValueList */ - std::map < string, int >prodSpeedMorphIsMultiplierValueList; - /**< @see #attackStrengthMultiplierValueList */ + int prodSpeed; + bool prodSpeedIsMultiplier; + std::map < string, int >prodSpeedProduceIsMultiplierValueList; + /**< @see #attackStrengthMultiplierValueList */ + std::map < string, int >prodSpeedUpgradeIsMultiplierValueList; + /**< @see #attackStrengthMultiplierValueList */ + std::map < string, int >prodSpeedMorphIsMultiplierValueList; + /**< @see #attackStrengthMultiplierValueList */ - int attackSpeed; - bool attackSpeedIsMultiplier; - std::map < string, int >attackSpeedIsMultiplierValueList; + int attackSpeed; + bool attackSpeedIsMultiplier; + std::map < string, int >attackSpeedIsMultiplierValueList; - protected: + protected: - virtual int getAttackStrength () const - { - return attackStrength; - } - virtual int getAttackRange () const - { - return attackRange; - } - virtual int getMoveSpeed () const - { - return moveSpeed; - } - virtual int getProdSpeed () const - { - return prodSpeed; - } - virtual int getAttackSpeed () const - { - return attackSpeed; - } + virtual int getAttackStrength() const { + return attackStrength; + } + virtual int getAttackRange() const { + return attackRange; + } + virtual int getMoveSpeed() const { + return moveSpeed; + } + virtual int getProdSpeed() const { + return prodSpeed; + } + virtual int getAttackSpeed() const { + return attackSpeed; + } - virtual int getMaxHpFromBoosts () const - { - return 0; - } - virtual int getMaxHpRegenerationFromBoosts () const - { - return 0; - } - virtual int getSightFromBoosts () const - { - return 0; - } - virtual int getMaxEpFromBoosts () const - { - return 0; - } - virtual int getMaxEpRegenerationFromBoosts () const - { - return 0; - } - virtual int getArmorFromBoosts () const - { - return 0; - }; - virtual int getAttackStrengthFromBoosts (const AttackSkillType * st) const - { - return 0; - } - virtual int getAttackRangeFromBoosts (const AttackSkillType * st) const - { - return 0; - } - virtual int getMoveSpeedFromBoosts (const MoveSkillType * st) const - { - return 0; - } - virtual int getProdSpeedFromBoosts (const SkillType * st) const - { - return 0; - } - virtual int getAttackSpeedFromBoosts (const AttackSkillType * st) const - { - return 0; - } + virtual int getMaxHpFromBoosts() const { + return 0; + } + virtual int getMaxHpRegenerationFromBoosts() const { + return 0; + } + virtual int getSightFromBoosts() const { + return 0; + } + virtual int getMaxEpFromBoosts() const { + return 0; + } + virtual int getMaxEpRegenerationFromBoosts() const { + return 0; + } + virtual int getArmorFromBoosts() const { + return 0; + }; + virtual int getAttackStrengthFromBoosts(const AttackSkillType * st) const { + return 0; + } + virtual int getAttackRangeFromBoosts(const AttackSkillType * st) const { + return 0; + } + virtual int getMoveSpeedFromBoosts(const MoveSkillType * st) const { + return 0; + } + virtual int getProdSpeedFromBoosts(const SkillType * st) const { + return 0; + } + virtual int getAttackSpeedFromBoosts(const AttackSkillType * st) const { + return 0; + } - public: - /** - * Creates an UpgradeTypeBase with values such that there are no stat changes. - */ - UpgradeTypeBase () - { - maxHp = 0;; - maxHpIsMultiplier = false; - maxHpRegeneration = 0; - sight = 0; - sightIsMultiplier = false; - maxEp = 0;; - maxEpIsMultiplier = false; - maxEpRegeneration = 0; - armor = 0; - armorIsMultiplier = false; - attackStrength = 0; - attackStrengthIsMultiplier = false; - attackRange = 0; - attackRangeIsMultiplier = false; - moveSpeed = 0; - moveSpeedIsMultiplier = false; - prodSpeed = 0; - prodSpeedIsMultiplier = false; - attackSpeed = 0; - attackSpeedIsMultiplier = false; - } - virtual ~ UpgradeTypeBase () - { - } + public: + /** + * Creates an UpgradeTypeBase with values such that there are no stat changes. + */ + UpgradeTypeBase() { + maxHp = 0;; + maxHpIsMultiplier = false; + maxHpRegeneration = 0; + sight = 0; + sightIsMultiplier = false; + maxEp = 0;; + maxEpIsMultiplier = false; + maxEpRegeneration = 0; + armor = 0; + armorIsMultiplier = false; + attackStrength = 0; + attackStrengthIsMultiplier = false; + attackRange = 0; + attackRangeIsMultiplier = false; + moveSpeed = 0; + moveSpeedIsMultiplier = false; + prodSpeed = 0; + prodSpeedIsMultiplier = false; + attackSpeed = 0; + attackSpeedIsMultiplier = false; + } + virtual ~UpgradeTypeBase() { + } - virtual void copyDataFrom (UpgradeTypeBase * source); + virtual void copyDataFrom(UpgradeTypeBase * source); - virtual string getUpgradeName () const - { - return upgradename; - } - virtual int getMaxHp () const - { - return maxHp; - } - virtual int getMaxHpRegeneration () const - { - return maxHpRegeneration; - } - virtual int getSight () const - { - return sight; - } - virtual int getMaxEp () const - { - return maxEp; - } - virtual int getMaxEpRegeneration () const - { - return maxEpRegeneration; - } - virtual int getArmor () const - { - return armor; - } - virtual int getAttackStrength (const AttackSkillType * st) const; - virtual int getAttackRange (const AttackSkillType * st) const; - virtual int getMoveSpeed (const MoveSkillType * st) const; - virtual int getProdSpeed (const SkillType * st) const; - virtual int getAttackSpeed (const AttackSkillType * st) const; + virtual string getUpgradeName() const { + return upgradename; + } + virtual int getMaxHp() const { + return maxHp; + } + virtual int getMaxHpRegeneration() const { + return maxHpRegeneration; + } + virtual int getSight() const { + return sight; + } + virtual int getMaxEp() const { + return maxEp; + } + virtual int getMaxEpRegeneration() const { + return maxEpRegeneration; + } + virtual int getArmor() const { + return armor; + } + virtual int getAttackStrength(const AttackSkillType * st) const; + virtual int getAttackRange(const AttackSkillType * st) const; + virtual int getMoveSpeed(const MoveSkillType * st) const; + virtual int getProdSpeed(const SkillType * st) const; + virtual int getAttackSpeed(const AttackSkillType * st) const; - virtual bool getAttackStrengthIsMultiplier () const - { - return attackStrengthIsMultiplier; - } - virtual bool getMaxHpIsMultiplier () const - { - return maxHpIsMultiplier; - } - virtual bool getSightIsMultiplier () const - { - return sightIsMultiplier; - } - virtual bool getMaxEpIsMultiplier () const - { - return maxEpIsMultiplier; - } - virtual bool getArmorIsMultiplier () const - { - return armorIsMultiplier; - } - virtual bool getAttackRangeIsMultiplier () const - { - return attackRangeIsMultiplier; - } - virtual bool getMoveSpeedIsMultiplier () const - { - return moveSpeedIsMultiplier; - } - virtual bool getProdSpeedIsMultiplier () const - { - return prodSpeedIsMultiplier; - } - virtual bool getAttackSpeedIsMultiplier () const - { - return attackSpeedIsMultiplier; - } + virtual bool getAttackStrengthIsMultiplier() const { + return attackStrengthIsMultiplier; + } + virtual bool getMaxHpIsMultiplier() const { + return maxHpIsMultiplier; + } + virtual bool getSightIsMultiplier() const { + return sightIsMultiplier; + } + virtual bool getMaxEpIsMultiplier() const { + return maxEpIsMultiplier; + } + virtual bool getArmorIsMultiplier() const { + return armorIsMultiplier; + } + virtual bool getAttackRangeIsMultiplier() const { + return attackRangeIsMultiplier; + } + virtual bool getMoveSpeedIsMultiplier() const { + return moveSpeedIsMultiplier; + } + virtual bool getProdSpeedIsMultiplier() const { + return prodSpeedIsMultiplier; + } + virtual bool getAttackSpeedIsMultiplier() const { + return attackSpeedIsMultiplier; + } - /** - * Loads the upgrade values (stat boosts and whether or not the boosts use a multiplier) from an - * XML node. - * @param upgradeNode Node containing the stat boost elements (`max-hp`, `attack-strength`, etc). - * @param upgradename Unique identifier for the upgrade. - */ + /** + * Loads the upgrade values (stat boosts and whether or not the boosts use a multiplier) from an + * XML node. + * @param upgradeNode Node containing the stat boost elements (`max-hp`, `attack-strength`, etc). + * @param upgradename Unique identifier for the upgrade. + */ - void load (const XmlNode * upgradeNode, string upgradename); + void load(const XmlNode * upgradeNode, string upgradename); - /** - * Creates a string representation of the upgrade. All stat boosts are detailed on their own line - * with their corresponding boosts. - * @param translatedValue If true, the description is translated. Otherwise the description uses - * names as they appear in the XMLs. - */ - virtual string getDesc (bool translatedValue) const; + /** + * Creates a string representation of the upgrade. All stat boosts are detailed on their own line + * with their corresponding boosts. + * @param translatedValue If true, the description is translated. Otherwise the description uses + * names as they appear in the XMLs. + */ + virtual string getDesc(bool translatedValue) const; - /** - * Returns a string representation of this object. Lists all the value that the object stores. - * For debugging purposes, only. - */ - virtual std::string toString () const - { - std::string result = ""; + /** + * Returns a string representation of this object. Lists all the value that the object stores. + * For debugging purposes, only. + */ + virtual std::string toString() const { + std::string result = ""; - result += "upgradename =" + getUpgradeName (); - result += "maxHp = " + intToStr (getMaxHp ()); - result += "maxHpIsMultiplier = " + intToStr (getMaxHpIsMultiplier ()); - result += "maxHpRegeneration = " + intToStr (getMaxHpRegeneration ()); - //result += "maxHpRegenerationIsMultiplier = " + intToStr(maxHpRegenerationIsMultiplier); + result += "upgradename =" + getUpgradeName(); + result += "maxHp = " + intToStr(getMaxHp()); + result += "maxHpIsMultiplier = " + intToStr(getMaxHpIsMultiplier()); + result += "maxHpRegeneration = " + intToStr(getMaxHpRegeneration()); + //result += "maxHpRegenerationIsMultiplier = " + intToStr(maxHpRegenerationIsMultiplier); - result += " sight = " + intToStr (getSight ()); - result += "sightIsMultiplier = " + intToStr (getSightIsMultiplier ()); + result += " sight = " + intToStr(getSight()); + result += "sightIsMultiplier = " + intToStr(getSightIsMultiplier()); - result += " maxEp = " + intToStr (getMaxEp ()); - result += - " maxEpIsMultiplier = " + intToStr (getMaxEpIsMultiplier ()); - result += - " maxEpRegeneration = " + intToStr (getMaxEpRegeneration ()); - //result += "maxEpRegenerationIsMultiplier = " + intToStr(maxEpRegenerationIsMultiplier); + result += " maxEp = " + intToStr(getMaxEp()); + result += + " maxEpIsMultiplier = " + intToStr(getMaxEpIsMultiplier()); + result += + " maxEpRegeneration = " + intToStr(getMaxEpRegeneration()); + //result += "maxEpRegenerationIsMultiplier = " + intToStr(maxEpRegenerationIsMultiplier); - result += " armor = " + intToStr (getArmor ()); - result += - " armorIsMultiplier = " + intToStr (getArmorIsMultiplier ()); - result += " attackStrength = " + intToStr (getAttackStrength ()); - result += - " attackStrengthIsMultiplier = " + - intToStr (getAttackStrengthIsMultiplier ()); - result += " attackRange = " + intToStr (getAttackRange ()); - result += - " attackRangeIsMultiplier = " + - intToStr (getAttackRangeIsMultiplier ()); - result += " moveSpeed = " + intToStr (getMoveSpeed ()); - result += - " moveSpeedIsMultiplier = " + - intToStr (getMoveSpeedIsMultiplier ()); - result += " prodSpeed = " + intToStr (getProdSpeed ()); - result += - " prodSpeedIsMultiplier = " + - intToStr (getProdSpeedIsMultiplier ()); + result += " armor = " + intToStr(getArmor()); + result += + " armorIsMultiplier = " + intToStr(getArmorIsMultiplier()); + result += " attackStrength = " + intToStr(getAttackStrength()); + result += + " attackStrengthIsMultiplier = " + + intToStr(getAttackStrengthIsMultiplier()); + result += " attackRange = " + intToStr(getAttackRange()); + result += + " attackRangeIsMultiplier = " + + intToStr(getAttackRangeIsMultiplier()); + result += " moveSpeed = " + intToStr(getMoveSpeed()); + result += + " moveSpeedIsMultiplier = " + + intToStr(getMoveSpeedIsMultiplier()); + result += " prodSpeed = " + intToStr(getProdSpeed()); + result += + " prodSpeedIsMultiplier = " + + intToStr(getProdSpeedIsMultiplier()); - return result; - } + return result; + } - // TODO: It's not clear if these save game methods are being used, currently. I think - // attack boosts might use the few lines that aren't commented out. - virtual void saveGame (XmlNode * rootNode) const; - //virtual void saveGameBoost(XmlNode *rootNode) const; - static const UpgradeType *loadGame (const XmlNode * rootNode, - Faction * faction); - //void loadGameBoost(const XmlNode *rootNode); + // TODO: It's not clear if these save game methods are being used, currently. I think + // attack boosts might use the few lines that aren't commented out. + virtual void saveGame(XmlNode * rootNode) const; + //virtual void saveGameBoost(XmlNode *rootNode) const; + static const UpgradeType *loadGame(const XmlNode * rootNode, + Faction * faction); + //void loadGameBoost(const XmlNode *rootNode); - /** - * Generates a checksum value for the upgrade. - */ - virtual Checksum getCRC () - { - Checksum crcForUpgradeType; + /** + * Generates a checksum value for the upgrade. + */ + virtual Checksum getCRC() { + Checksum crcForUpgradeType; - crcForUpgradeType.addString (getUpgradeName ()); - crcForUpgradeType.addInt (getMaxHp ()); - crcForUpgradeType.addInt (getMaxHpIsMultiplier ()); - crcForUpgradeType.addInt (getMaxHpRegeneration ()); + crcForUpgradeType.addString(getUpgradeName()); + crcForUpgradeType.addInt(getMaxHp()); + crcForUpgradeType.addInt(getMaxHpIsMultiplier()); + crcForUpgradeType.addInt(getMaxHpRegeneration()); - crcForUpgradeType.addInt (getSight ()); - crcForUpgradeType.addInt (getSightIsMultiplier ()); + crcForUpgradeType.addInt(getSight()); + crcForUpgradeType.addInt(getSightIsMultiplier()); - crcForUpgradeType.addInt (getMaxEp ()); - crcForUpgradeType.addInt (getMaxEpIsMultiplier ()); - crcForUpgradeType.addInt (getMaxEpRegeneration ()); + crcForUpgradeType.addInt(getMaxEp()); + crcForUpgradeType.addInt(getMaxEpIsMultiplier()); + crcForUpgradeType.addInt(getMaxEpRegeneration()); - crcForUpgradeType.addInt (getArmor ()); - crcForUpgradeType.addInt (getArmorIsMultiplier ()); + crcForUpgradeType.addInt(getArmor()); + crcForUpgradeType.addInt(getArmorIsMultiplier()); - crcForUpgradeType.addInt (getAttackStrength ()); - crcForUpgradeType.addInt (getAttackStrengthIsMultiplier ()); - //std::map attackStrengthMultiplierValueList; - crcForUpgradeType.addInt64 ((int64) attackStrengthMultiplierValueList. - size ()); + crcForUpgradeType.addInt(getAttackStrength()); + crcForUpgradeType.addInt(getAttackStrengthIsMultiplier()); + //std::map attackStrengthMultiplierValueList; + crcForUpgradeType.addInt64((int64) attackStrengthMultiplierValueList. + size()); - crcForUpgradeType.addInt (getAttackRange ()); - crcForUpgradeType.addInt (getAttackRangeIsMultiplier ()); - //std::map attackRangeMultiplierValueList; - crcForUpgradeType.addInt64 ((int64) attackRangeMultiplierValueList. - size ()); + crcForUpgradeType.addInt(getAttackRange()); + crcForUpgradeType.addInt(getAttackRangeIsMultiplier()); + //std::map attackRangeMultiplierValueList; + crcForUpgradeType.addInt64((int64) attackRangeMultiplierValueList. + size()); - crcForUpgradeType.addInt (getMoveSpeed ()); - crcForUpgradeType.addInt (getMoveSpeedIsMultiplier ()); - //std::map moveSpeedIsMultiplierValueList; - crcForUpgradeType.addInt64 ((int64) moveSpeedIsMultiplierValueList. - size ()); + crcForUpgradeType.addInt(getMoveSpeed()); + crcForUpgradeType.addInt(getMoveSpeedIsMultiplier()); + //std::map moveSpeedIsMultiplierValueList; + crcForUpgradeType.addInt64((int64) moveSpeedIsMultiplierValueList. + size()); - crcForUpgradeType.addInt (getProdSpeed ()); - crcForUpgradeType.addInt (getProdSpeedIsMultiplier ()); - //std::map prodSpeedProduceIsMultiplierValueList; - crcForUpgradeType. - addInt64 ((int64) prodSpeedProduceIsMultiplierValueList.size ()); - //std::map prodSpeedUpgradeIsMultiplierValueList; - crcForUpgradeType. - addInt64 ((int64) prodSpeedUpgradeIsMultiplierValueList.size ()); - //std::map prodSpeedMorphIsMultiplierValueList; - crcForUpgradeType. - addInt64 ((int64) prodSpeedMorphIsMultiplierValueList.size ()); + crcForUpgradeType.addInt(getProdSpeed()); + crcForUpgradeType.addInt(getProdSpeedIsMultiplier()); + //std::map prodSpeedProduceIsMultiplierValueList; + crcForUpgradeType. + addInt64((int64) prodSpeedProduceIsMultiplierValueList.size()); + //std::map prodSpeedUpgradeIsMultiplierValueList; + crcForUpgradeType. + addInt64((int64) prodSpeedUpgradeIsMultiplierValueList.size()); + //std::map prodSpeedMorphIsMultiplierValueList; + crcForUpgradeType. + addInt64((int64) prodSpeedMorphIsMultiplierValueList.size()); - crcForUpgradeType.addInt (getAttackSpeed ()); - crcForUpgradeType.addInt (getAttackSpeedIsMultiplier ()); + crcForUpgradeType.addInt(getAttackSpeed()); + crcForUpgradeType.addInt(getAttackSpeedIsMultiplier()); - return crcForUpgradeType; - } - }; + return crcForUpgradeType; + } + }; -/** - * Represents the type of upgrade. That is, the single upgrade as it appears in the faction's XML - * files. Each upgrade has a single `UpgradeType`. Contains information about what units are - * affected by the upgrade. - */ - class UpgradeType:public UpgradeTypeBase, public ProducibleType - { - private: - /** - * Set of unit types (the "classes" of units, eg, swordman) that are affected by this upgrade. - */ - std::set < const UnitType *>effects; - std::set < string > tags; + /** + * Represents the type of upgrade. That is, the single upgrade as it appears in the faction's XML + * files. Each upgrade has a single `UpgradeType`. Contains information about what units are + * affected by the upgrade. + */ + class UpgradeType :public UpgradeTypeBase, public ProducibleType { + private: + /** + * Set of unit types (the "classes" of units, eg, swordman) that are affected by this upgrade. + */ + std::set < const UnitType *>effects; + std::set < string > tags; - public: - /** - * Sets the upgrade name to the directory name (the base name of `dir`). - * @param dir Path of the upgrade directory. - */ - void preLoad (const string & dir); + public: + /** + * Sets the upgrade name to the directory name (the base name of `dir`). + * @param dir Path of the upgrade directory. + */ + void preLoad(const string & dir); - /** - * Loads an upgrade from an XML file. - * @param dir Path of the upgrade directory. The file name is determined from this. - * @param techTree The techtree that this upgrade is in. Used to access the common data - * directory and to access resources. - * @param factionType The faction type (a unique type for each faction) that the upgrade belongs - * to. Used for accessing unit types that are in the unit requirements list. - * @param checksum Will have the checksum of the upgrade path added to it (treated the same way - * as the `techtreeChecksum`). - * @param techtreeChecksum Cumulative checksum for the techtree. The path of loaded upgrades - * is added to this checksum. - */ - void load (const string & dir, const TechTree * techTree, - const FactionType * factionType, Checksum * checksum, - Checksum * techtreeChecksum, - std::map < string, vector < pair < string, - string > > >&loadedFileList, bool validationMode = false); + /** + * Loads an upgrade from an XML file. + * @param dir Path of the upgrade directory. The file name is determined from this. + * @param techTree The techtree that this upgrade is in. Used to access the common data + * directory and to access resources. + * @param factionType The faction type (a unique type for each faction) that the upgrade belongs + * to. Used for accessing unit types that are in the unit requirements list. + * @param checksum Will have the checksum of the upgrade path added to it (treated the same way + * as the `techtreeChecksum`). + * @param techtreeChecksum Cumulative checksum for the techtree. The path of loaded upgrades + * is added to this checksum. + */ + void load(const string & dir, const TechTree * techTree, + const FactionType * factionType, Checksum * checksum, + Checksum * techtreeChecksum, + std::map < string, vector < pair < string, + string > > >&loadedFileList, bool validationMode = false); - /** - * Obtains the upgrade name. - * @param translatedValue If true, the name is translated. Otherwise the name is returned as it - * appears in the XMLs. - */ - virtual string getName (bool translatedValue = false) const; - string getTagName (string tag, bool translatedValue = false) const; + /** + * Obtains the upgrade name. + * @param translatedValue If true, the name is translated. Otherwise the name is returned as it + * appears in the XMLs. + */ + virtual string getName(bool translatedValue = false) const; + string getTagName(string tag, bool translatedValue = false) const; - /** - * Determines if a unit is affected by this upgrade. - * @param unitType The UnitType we are checking (to see if they're affected). - * @return True if the unit is affected, false otherwise. - */ - bool isAffected (const UnitType * unitType) const; + /** + * Determines if a unit is affected by this upgrade. + * @param unitType The UnitType we are checking (to see if they're affected). + * @return True if the unit is affected, false otherwise. + */ + bool isAffected(const UnitType * unitType) const; - /** - * Creates a description for this upgrade. Lists the affected units. - */ - virtual string getReqDesc (bool translatedValue) const; + /** + * Creates a description for this upgrade. Lists the affected units. + */ + virtual string getReqDesc(bool translatedValue) const; - //virtual void saveGame(XmlNode *rootNode) const; - //virtual void loadGame(const XmlNode *rootNode); - }; + //virtual void saveGame(XmlNode *rootNode) const; + //virtual void loadGame(const XmlNode *rootNode); + }; -/** - * Keeps track of the cumulative effects of upgrades on units. This allows us to apply multiple - * upgrades to a unit with the effects stacking. - */ - class TotalUpgrade:public UpgradeTypeBase - { + /** + * Keeps track of the cumulative effects of upgrades on units. This allows us to apply multiple + * upgrades to a unit with the effects stacking. + */ + class TotalUpgrade :public UpgradeTypeBase { - private: + private: - // List of boosts - const UpgradeTypeBase *boostUpgradeBase; - int boostUpgradeSourceUnit; - int boostUpgradeDestUnit; - std::vector < TotalUpgrade * >boostUpgrades; + // List of boosts + const UpgradeTypeBase *boostUpgradeBase; + int boostUpgradeSourceUnit; + int boostUpgradeDestUnit; + std::vector < TotalUpgrade * >boostUpgrades; - public: - TotalUpgrade (); - virtual ~ TotalUpgrade () - { - } + public: + TotalUpgrade(); + virtual ~TotalUpgrade() { + } - /** - * Resets all stat boosts (so there's effectively no upgrade). - */ - void reset (); + /** + * Resets all stat boosts (so there's effectively no upgrade). + */ + void reset(); - /** - * Adds an upgrade to this one, stacking the effects. Note that multipliers are stacked - * by multiplying by the original, unboosted amount, and then adding that to the TotalUpgrade. - * @param ut The upgrade to apply. - * @param unit The unit this TotalUpgrade is associated with (since when we use a multiplier, - * the stats raise by an amount relative to the unit's base stats). - */ - void sum (const UpgradeTypeBase * ut, const Unit * unit, - bool boostMode = false); + /** + * Adds an upgrade to this one, stacking the effects. Note that multipliers are stacked + * by multiplying by the original, unboosted amount, and then adding that to the TotalUpgrade. + * @param ut The upgrade to apply. + * @param unit The unit this TotalUpgrade is associated with (since when we use a multiplier, + * the stats raise by an amount relative to the unit's base stats). + */ + void sum(const UpgradeTypeBase * ut, const Unit * unit, + bool boostMode = false); - /** - * Increases the level of the unit. Doing so results in their HP, EP, and armour going up by - * 50% while their sight goes up by 20%. - * @param ut The unit type to get the original stats from (so we can determine just how much - * to increase the stats by on level up). - */ - void incLevel (const UnitType * ut); + /** + * Increases the level of the unit. Doing so results in their HP, EP, and armour going up by + * 50% while their sight goes up by 20%. + * @param ut The unit type to get the original stats from (so we can determine just how much + * to increase the stats by on level up). + */ + void incLevel(const UnitType * ut); - /** - * Applies the upgrade. Just a delegate to TotalUpgrade::sum. - */ - void apply (int sourceUnitId, const UpgradeTypeBase * ut, - const Unit * unit); + /** + * Applies the upgrade. Just a delegate to TotalUpgrade::sum. + */ + void apply(int sourceUnitId, const UpgradeTypeBase * ut, + const Unit * unit); - /** - * Removes the effect of an upgrade to a specific unit. Using this after applying the upgrade - * is an invariant. ie, - * - * totalUpgrade->apply(upgrade, unit); - * totalUpgrade->deapply(upgrade, unit); - * // totalUpgrade is now the same as before the call to apply() - * - * @param ut The upgrade to remove. - * @param unit The unit this TotalUpgrade is associated with (since when we use a multiplier, - * the stats were raise by an amount relative to the unit's base stats). - */ - void deapply (int sourceUnitId, const UpgradeTypeBase * ut, - int destUnitId); + /** + * Removes the effect of an upgrade to a specific unit. Using this after applying the upgrade + * is an invariant. ie, + * + * totalUpgrade->apply(upgrade, unit); + * totalUpgrade->deapply(upgrade, unit); + * // totalUpgrade is now the same as before the call to apply() + * + * @param ut The upgrade to remove. + * @param unit The unit this TotalUpgrade is associated with (since when we use a multiplier, + * the stats were raise by an amount relative to the unit's base stats). + */ + void deapply(int sourceUnitId, const UpgradeTypeBase * ut, + int destUnitId); - virtual int getMaxHp () const; - virtual int getMaxHpRegeneration () const; - virtual int getSight () const; - virtual int getMaxEp () const; - virtual int getMaxEpRegeneration () const; - virtual int getArmor () const; - virtual int getAttackStrength (const AttackSkillType * st) const; - virtual int getAttackRange (const AttackSkillType * st) const; - virtual int getMoveSpeed (const MoveSkillType * st) const; - virtual int getProdSpeed (const SkillType * st) const; - virtual int getAttackSpeed (const AttackSkillType * st) const; + virtual int getMaxHp() const; + virtual int getMaxHpRegeneration() const; + virtual int getSight() const; + virtual int getMaxEp() const; + virtual int getMaxEpRegeneration() const; + virtual int getArmor() const; + virtual int getAttackStrength(const AttackSkillType * st) const; + virtual int getAttackRange(const AttackSkillType * st) const; + virtual int getMoveSpeed(const MoveSkillType * st) const; + virtual int getProdSpeed(const SkillType * st) const; + virtual int getAttackSpeed(const AttackSkillType * st) const; - virtual int getMaxHpFromBoosts () const; - virtual int getMaxHpRegenerationFromBoosts () const; - virtual int getSightFromBoosts () const; - virtual int getMaxEpFromBoosts () const; - virtual int getMaxEpRegenerationFromBoosts () const; - virtual int getArmorFromBoosts () const; - virtual int getAttackStrengthFromBoosts (const AttackSkillType * - st) const; - virtual int getAttackRangeFromBoosts (const AttackSkillType * st) const; - virtual int getMoveSpeedFromBoosts (const MoveSkillType * st) const; - virtual int getProdSpeedFromBoosts (const SkillType * st) const; - virtual int getAttackSpeedFromBoosts (const AttackSkillType * st) const; + virtual int getMaxHpFromBoosts() const; + virtual int getMaxHpRegenerationFromBoosts() const; + virtual int getSightFromBoosts() const; + virtual int getMaxEpFromBoosts() const; + virtual int getMaxEpRegenerationFromBoosts() const; + virtual int getArmorFromBoosts() const; + virtual int getAttackStrengthFromBoosts(const AttackSkillType * + st) const; + virtual int getAttackRangeFromBoosts(const AttackSkillType * st) const; + virtual int getMoveSpeedFromBoosts(const MoveSkillType * st) const; + virtual int getProdSpeedFromBoosts(const SkillType * st) const; + virtual int getAttackSpeedFromBoosts(const AttackSkillType * st) const; - /** - * Creates the XML for the save game file. Essentially just stores everything about its state. - * @rootNode The node of the unit that this TotalUpgrade object belongs to. - */ - void saveGame (XmlNode * rootNode) const; + /** + * Creates the XML for the save game file. Essentially just stores everything about its state. + * @rootNode The node of the unit that this TotalUpgrade object belongs to. + */ + void saveGame(XmlNode * rootNode) const; - /** - * Reloads the object's state from a saved game. - * @rootNode The node of the unit that this TotalUpgrade object belongs to. - */ - void loadGame (const XmlNode * rootNode); - }; + /** + * Reloads the object's state from a saved game. + * @rootNode The node of the unit that this TotalUpgrade object belongs to. + */ + void loadGame(const XmlNode * rootNode); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/world/map.cpp b/source/glest_game/world/map.cpp index 06a45c0a7..742fe14db 100644 --- a/source/glest_game/world/map.cpp +++ b/source/glest_game/world/map.cpp @@ -44,620 +44,614 @@ using namespace Shared::Graphics; using namespace Shared::Util; using namespace Shared::Platform; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class Cell -// ===================================================== + // ===================================================== + // class Cell + // ===================================================== -Cell::Cell() { - //game data - for(int i = 0; i < fieldCount; ++i) { - units[i]= NULL; - unitsWithEmptyCellMap[i]=NULL; - } - height= 0; -} - -// ==================== misc ==================== - -//returns if the cell is free - -//returns if the cell is free - -void Cell::saveGame(XmlNode *rootNode, int index) const { - bool saveCell = false; - //if(saveCell == false) { - for(unsigned int i = 0; i < fieldCount; ++i) { - if(units[i] != NULL) { - saveCell = true; - break; - } - if(unitsWithEmptyCellMap[i] != NULL) { - saveCell = true; - break; + Cell::Cell() { + //game data + for (int i = 0; i < fieldCount; ++i) { + units[i] = NULL; + unitsWithEmptyCellMap[i] = NULL; } + height = 0; } - //} - if(saveCell == true) { - std::map mapTagReplacements; - XmlNode *cellNode = rootNode->addChild("Cell" + intToStr(index)); - cellNode->addAttribute("index",intToStr(index), mapTagReplacements); + // ==================== misc ==================== - // Unit *units[fieldCount]; //units on this cell - for(unsigned int i = 0; i < fieldCount; ++i) { - if(units[i] != NULL) { - XmlNode *unitsNode = cellNode->addChild("units"); - unitsNode->addAttribute("field",intToStr(i), mapTagReplacements); - unitsNode->addAttribute("unitid",intToStr(units[i]->getId()), mapTagReplacements); + //returns if the cell is free + + //returns if the cell is free + + void Cell::saveGame(XmlNode *rootNode, int index) const { + bool saveCell = false; + //if(saveCell == false) { + for (unsigned int i = 0; i < fieldCount; ++i) { + if (units[i] != NULL) { + saveCell = true; + break; + } + if (unitsWithEmptyCellMap[i] != NULL) { + saveCell = true; + break; + } } - } - // Unit *unitsWithEmptyCellMap[fieldCount]; //units with an empty cellmap on this cell - for(unsigned int i = 0; i < fieldCount; ++i) { - if(unitsWithEmptyCellMap[i] != NULL) { - XmlNode *unitsWithEmptyCellMapNode = cellNode->addChild("unitsWithEmptyCellMap"); - unitsWithEmptyCellMapNode->addAttribute("field",intToStr(i), mapTagReplacements); - unitsWithEmptyCellMapNode->addAttribute("unitid",intToStr(unitsWithEmptyCellMap[i]->getId()), mapTagReplacements); + //} + + if (saveCell == true) { + std::map mapTagReplacements; + XmlNode *cellNode = rootNode->addChild("Cell" + intToStr(index)); + cellNode->addAttribute("index", intToStr(index), mapTagReplacements); + + // Unit *units[fieldCount]; //units on this cell + for (unsigned int i = 0; i < fieldCount; ++i) { + if (units[i] != NULL) { + XmlNode *unitsNode = cellNode->addChild("units"); + unitsNode->addAttribute("field", intToStr(i), mapTagReplacements); + unitsNode->addAttribute("unitid", intToStr(units[i]->getId()), mapTagReplacements); + } + } + // Unit *unitsWithEmptyCellMap[fieldCount]; //units with an empty cellmap on this cell + for (unsigned int i = 0; i < fieldCount; ++i) { + if (unitsWithEmptyCellMap[i] != NULL) { + XmlNode *unitsWithEmptyCellMapNode = cellNode->addChild("unitsWithEmptyCellMap"); + unitsWithEmptyCellMapNode->addAttribute("field", intToStr(i), mapTagReplacements); + unitsWithEmptyCellMapNode->addAttribute("unitid", intToStr(unitsWithEmptyCellMap[i]->getId()), mapTagReplacements); + } + } + + // float height; + cellNode->addAttribute("height", floatToStr(getHeight(), 6), mapTagReplacements); } } - // float height; - cellNode->addAttribute("height",floatToStr(getHeight(),6), mapTagReplacements); - } -} + void Cell::loadGame(const XmlNode *rootNode, int index, World *world) { + if (rootNode->hasChild("Cell" + intToStr(index)) == true) { + const XmlNode *cellNode = rootNode->getChild("Cell" + intToStr(index)); -void Cell::loadGame(const XmlNode *rootNode, int index, World *world) { - if(rootNode->hasChild("Cell" + intToStr(index)) == true) { - const XmlNode *cellNode = rootNode->getChild("Cell" + intToStr(index)); - - unsigned int unitCount = (unsigned int)cellNode->getChildCount(); - for(unsigned int i = 0; i < unitCount; ++i) { - if(cellNode->hasChildAtIndex("units",i) == true) { - const XmlNode *unitsNode = cellNode->getChild("units",i); - int field = unitsNode->getAttribute("field")->getIntValue(); - int unitId = unitsNode->getAttribute("unitid")->getIntValue(); - units[field] = world->findUnitById(unitId); - } - if(cellNode->hasChildAtIndex("unitsWithEmptyCellMap",i) == true) { - const XmlNode *unitsNode = cellNode->getChild("unitsWithEmptyCellMap",i); - int field = unitsNode->getAttribute("field")->getIntValue(); - int unitId = unitsNode->getAttribute("unitid")->getIntValue(); - unitsWithEmptyCellMap[field] = world->findUnitById(unitId); + unsigned int unitCount = (unsigned int) cellNode->getChildCount(); + for (unsigned int i = 0; i < unitCount; ++i) { + if (cellNode->hasChildAtIndex("units", i) == true) { + const XmlNode *unitsNode = cellNode->getChild("units", i); + int field = unitsNode->getAttribute("field")->getIntValue(); + int unitId = unitsNode->getAttribute("unitid")->getIntValue(); + units[field] = world->findUnitById(unitId); + } + if (cellNode->hasChildAtIndex("unitsWithEmptyCellMap", i) == true) { + const XmlNode *unitsNode = cellNode->getChild("unitsWithEmptyCellMap", i); + int field = unitsNode->getAttribute("field")->getIntValue(); + int unitId = unitsNode->getAttribute("unitid")->getIntValue(); + unitsWithEmptyCellMap[field] = world->findUnitById(unitId); + } + } } } - } -} -// ===================================================== -// class SurfaceCell -// ===================================================== + // ===================================================== + // class SurfaceCell + // ===================================================== -SurfaceCell::SurfaceCell() { - object= NULL; - vertex= Vec3f(0.f); - normal= Vec3f(0.f, 1.f, 0.f); - surfaceType= -1; - surfaceTexture= NULL; - nearSubmerged = false; - cellChangedFromOriginalMapLoad = false; + SurfaceCell::SurfaceCell() { + object = NULL; + vertex = Vec3f(0.f); + normal = Vec3f(0.f, 1.f, 0.f); + surfaceType = -1; + surfaceTexture = NULL; + nearSubmerged = false; + cellChangedFromOriginalMapLoad = false; - for(int index = 0; index < GameConstants::maxPlayers + GameConstants::specialFactions; ++index) { - setVisible(index,false); - setExplored(index,false); - } -} - -SurfaceCell::~SurfaceCell() { - delete object; - object=NULL; -} - -void SurfaceCell::end(){ - if(object!=NULL){ - object->end(); - } -} - -void SurfaceCell::deleteResource() { - cellChangedFromOriginalMapLoad = true; - - delete object; - object= NULL; -} - -void SurfaceCell::setHeight(float height, bool cellChangedFromOriginalMapLoadValue) { - height = truncateDecimal(height); - vertex.y= height; - if(cellChangedFromOriginalMapLoadValue == true) { - this->cellChangedFromOriginalMapLoad = true; - } -} - -bool SurfaceCell::decAmount(int value) { - cellChangedFromOriginalMapLoad = true; - - return object->getResource()->decAmount(value); -} -void SurfaceCell::setExplored(int teamIndex, bool explored) { - if(teamIndex < 0 || teamIndex >= GameConstants::maxPlayers + GameConstants::specialFactions) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Invalid value for teamIndex [%d]",teamIndex); - printf("%s\n",szBuf); - throw megaglest_runtime_error(szBuf); - } - - this->explored[teamIndex]= explored; - //printf("Setting explored to %d for teamIndex %d\n",explored,teamIndex); -} - -void SurfaceCell::setVisible(int teamIndex, bool visible) { - if(teamIndex < 0 || teamIndex >= GameConstants::maxPlayers + GameConstants::specialFactions) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Invalid value for teamIndex [%d]",teamIndex); - printf("%s\n",szBuf); - throw megaglest_runtime_error(szBuf); - } - - this->visible[teamIndex]= visible; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && - SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In setVisible() teamIndex %d visible %d",teamIndex,visible); - -// if(frameIndex < 0) { -// unit->logSynchData(__FILE__,__LINE__,szBuf); -// } -// else { -// unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); -// } - - if(Thread::isCurrentThreadMainThread()) { - //unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); - SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,szBuf); - } - else { - //unit->logSynchData(__FILE__,__LINE__,szBuf); - printf("%s",szBuf); - } - - } - -} - -string SurfaceCell::isVisibleString() const { - string result = "isVisibleList = "; - for(int index = 0; index < GameConstants::maxPlayers + GameConstants::specialFactions; ++index) { - result += string(visible[index] ? "true" : "false"); - } - return result; -} -string SurfaceCell::isExploredString() const { - string result = "isExploredList = "; - for(int index = 0; index < GameConstants::maxPlayers + GameConstants::specialFactions; ++index) { - result += string(explored[index] ? "true" : "false"); - } - return result; -} - -void SurfaceCell::saveGame(XmlNode *rootNode,int index) const { - bool saveCell = (this->getCellChangedFromOriginalMapLoad() == true); - - if(saveCell == true) { - std::map mapTagReplacements; - XmlNode *surfaceCellNode = rootNode->addChild("SurfaceCell" + intToStr(index)); - surfaceCellNode->addAttribute("index",intToStr(index), mapTagReplacements); - - // //geometry - // Vec3f vertex; - surfaceCellNode->addAttribute("vertex",vertex.getString(), mapTagReplacements); - // Vec3f normal; - //surfaceCellNode->addAttribute("normal",normal.getString(), mapTagReplacements); - // Vec3f color; - //surfaceCellNode->addAttribute("color",color.getString(), mapTagReplacements); - // - // //tex coords - // Vec2f fowTexCoord; //tex coords for TEXTURE1 when multitexturing and fogOfWar - //surfaceCellNode->addAttribute("fowTexCoord",fowTexCoord.getString(), mapTagReplacements); - // Vec2f surfTexCoord; //tex coords for TEXTURE0 - //surfaceCellNode->addAttribute("surfTexCoord",surfTexCoord.getString(), mapTagReplacements); - // //surface - // int surfaceType; - //surfaceCellNode->addAttribute("surfaceType",intToStr(surfaceType), mapTagReplacements); - // const Texture2D *surfaceTexture; - // - // //object & resource - // Object *object; - if(object != NULL) { - object->saveGame(surfaceCellNode); - } - else { - XmlNode *objectNode = surfaceCellNode->addChild("Object"); - objectNode->addAttribute("isDeleted",intToStr(true), mapTagReplacements); - } - // //visibility - // bool visible[GameConstants::maxPlayers + GameConstants::specialFactions]; -// for(unsigned int i = 0; i < GameConstants::maxPlayers; ++i) { -// if(visible[i] == true) { -// XmlNode *visibleNode = surfaceCellNode->addChild("visible"); -// visibleNode->addAttribute("index",intToStr(i), mapTagReplacements); -// visibleNode->addAttribute("value",intToStr(visible[i]), mapTagReplacements); -// } -// } -// // bool explored[GameConstants::maxPlayers + GameConstants::specialFactions]; -// for(unsigned int i = 0; i < GameConstants::maxPlayers; ++i) { -// if(explored[i] == true) { -// XmlNode *exploredNode = surfaceCellNode->addChild("explored"); -// exploredNode->addAttribute("index",intToStr(i), mapTagReplacements); -// exploredNode->addAttribute("value",intToStr(explored[i]), mapTagReplacements); -// } -// } - - // //cache - // bool nearSubmerged; - //surfaceCellNode->addAttribute("nearSubmerged",intToStr(nearSubmerged), mapTagReplacements); - } -} - -void SurfaceCell::loadGame(const XmlNode *rootNode, int index, World *world) { - if(rootNode->hasChild("SurfaceCell" + intToStr(index)) == true) { - const XmlNode *surfaceCellNode = rootNode->getChild("SurfaceCell" + intToStr(index)); - - if(surfaceCellNode->hasAttribute("vertex") == true) { - vertex = Vec3f::strToVec3(surfaceCellNode->getAttribute("vertex")->getValue()); - } - - //int visibleCount = cellNode->getChildCount(); - XmlNode *objectNode = surfaceCellNode->getChild("Object"); - if(objectNode->hasAttribute("isDeleted") == true) { - this->deleteResource(); - } - else { - object->loadGame(surfaceCellNode,world->getTechTree()); - } - - //printf("Loading game, sc index [%d][%d]\n",index,visibleCount); - -// for(unsigned int i = 0; i < visibleCount; ++i) { -// if(cellNode->hasChildAtIndex("visible",i) == true) { -// const XmlNode *visibleNode = cellNode->getChild("visible",i); -// int indexCell = visibleNode->getAttribute("index")->getIntValue(); -// bool value = visibleNode->getAttribute("value")->getIntValue(); -// visible[indexCell] = value; -// -// //printf("Loading game, sc visible index [%d][%d][%d]\n",index,indexCell,value); -// } -// if(cellNode->hasChildAtIndex("explored",i) == true) { -// const XmlNode *exploredNode = cellNode->getChild("explored",i); -// int indexCell = exploredNode->getAttribute("index")->getIntValue(); -// bool value = exploredNode->getAttribute("value")->getIntValue(); -// explored[indexCell] = value; -// -// //printf("Loading game, sc explored cell index [%d] exploredIndex [%d] value [%d]\n",index,indexCell,value); -// } -// } - } -} -// ===================================================== -// class Map -// ===================================================== - -// ===================== PUBLIC ======================== - -const int Map::cellScale= 2; -const int Map::mapScale= 2; - -Map::Map() { - cells= NULL; - surfaceCells= NULL; - startLocations= NULL; - - title=""; - waterLevel=0; - heightFactor=0; - cliffLevel=0; - cameraHeight=0; - w=0; - h=0; - surfaceW=0; - surfaceH=0; - surfaceSize=(surfaceW * surfaceH); - maxPlayers=0; - maxMapHeight=0; -} - -Map::~Map() { - Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingMapCells","",true), true); - - delete [] cells; - cells = NULL; - delete [] surfaceCells; - surfaceCells = NULL; - delete [] startLocations; - startLocations = NULL; -} - -void Map::end(){ - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingMap","",true), true); - //read heightmap - for(int j = 0; j < surfaceH; ++j) { - for(int i = 0; i < surfaceW; ++i) { - getSurfaceCell(i, j)->end(); - } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -Vec2i Map::getStartLocation(int locationIndex) const { - if(locationIndex < hardMaxPlayers) // maxPlayers for a map, not the Game - return startLocations[locationIndex]; - else if (locationIndex < maxPlayers) { - // needed for enhanced observer mode (issue #13) - // observer may be in slot 6 of a 4-player map. Just set the - // startLocation to 0 - return startLocations[0]; - } - else { - char szBuf[8096]=""; - snprintf(szBuf,8096,"locationIndex >= maxPlayers [%d] [%d]",locationIndex, maxPlayers); - printf("%s\n",szBuf); - throw megaglest_runtime_error(szBuf); - assert(locationIndex < GameConstants::maxPlayers); - } -} - -Checksum Map::load(const string &path, TechTree *techTree, Tileset *tileset) { - Checksum mapChecksum; - try{ -#ifdef WIN32 - FILE *f= _wfopen(utf8_decode(path).c_str(), L"rb"); -#else - FILE *f = fopen(path.c_str(), "rb"); -#endif - if(f != NULL) { - mapFile = path; - - mapChecksum.addFile(path); - checksumValue.addFile(path); - //read header - MapFileHeader header; - size_t readBytes = fread(&header, sizeof(MapFileHeader), 1, f); - if(readBytes != 1) { - throw megaglest_runtime_error("Invalid map header detected for file: " + path); + for (int index = 0; index < GameConstants::maxPlayers + GameConstants::specialFactions; ++index) { + setVisible(index, false); + setExplored(index, false); } - fromEndianMapFileHeader(header); + } - if(next2Power(header.width) != header.width){ - throw megaglest_runtime_error("Map width is not a power of 2"); + SurfaceCell::~SurfaceCell() { + delete object; + object = NULL; + } + + void SurfaceCell::end() { + if (object != NULL) { + object->end(); + } + } + + void SurfaceCell::deleteResource() { + cellChangedFromOriginalMapLoad = true; + + delete object; + object = NULL; + } + + void SurfaceCell::setHeight(float height, bool cellChangedFromOriginalMapLoadValue) { + height = truncateDecimal(height); + vertex.y = height; + if (cellChangedFromOriginalMapLoadValue == true) { + this->cellChangedFromOriginalMapLoad = true; + } + } + + bool SurfaceCell::decAmount(int value) { + cellChangedFromOriginalMapLoad = true; + + return object->getResource()->decAmount(value); + } + void SurfaceCell::setExplored(int teamIndex, bool explored) { + if (teamIndex < 0 || teamIndex >= GameConstants::maxPlayers + GameConstants::specialFactions) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Invalid value for teamIndex [%d]", teamIndex); + printf("%s\n", szBuf); + throw megaglest_runtime_error(szBuf); } - if(next2Power(header.height) != header.height){ - throw megaglest_runtime_error("Map height is not a power of 2"); + this->explored[teamIndex] = explored; + //printf("Setting explored to %d for teamIndex %d\n",explored,teamIndex); + } + + void SurfaceCell::setVisible(int teamIndex, bool visible) { + if (teamIndex < 0 || teamIndex >= GameConstants::maxPlayers + GameConstants::specialFactions) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Invalid value for teamIndex [%d]", teamIndex); + printf("%s\n", szBuf); + throw megaglest_runtime_error(szBuf); } - heightFactor= header.heightFactor; - if(heightFactor>100){ - heightFactor=heightFactor/100; - heightFactor = truncateDecimal(heightFactor,6); + this->visible[teamIndex] = visible; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In setVisible() teamIndex %d visible %d", teamIndex, visible); + + // if(frameIndex < 0) { + // unit->logSynchData(__FILE__,__LINE__,szBuf); + // } + // else { + // unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); + // } + + if (Thread::isCurrentThreadMainThread()) { + //unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, szBuf); + } else { + //unit->logSynchData(__FILE__,__LINE__,szBuf); + printf("%s", szBuf); + } + } - waterLevel= static_cast((header.waterLevel-0.01f)/heightFactor); - waterLevel = truncateDecimal(waterLevel,6); - title= header.title; - //maxPlayers= header.maxFactions; - hardMaxPlayers = header.maxFactions; - maxPlayers = GameConstants::maxPlayers; + } - surfaceW= header.width; - surfaceH= header.height; - surfaceSize=(surfaceW * surfaceH); + string SurfaceCell::isVisibleString() const { + string result = "isVisibleList = "; + for (int index = 0; index < GameConstants::maxPlayers + GameConstants::specialFactions; ++index) { + result += string(visible[index] ? "true" : "false"); + } + return result; + } + string SurfaceCell::isExploredString() const { + string result = "isExploredList = "; + for (int index = 0; index < GameConstants::maxPlayers + GameConstants::specialFactions; ++index) { + result += string(explored[index] ? "true" : "false"); + } + return result; + } - w= surfaceW*cellScale; - h= surfaceH*cellScale; + void SurfaceCell::saveGame(XmlNode *rootNode, int index) const { + bool saveCell = (this->getCellChangedFromOriginalMapLoad() == true); + + if (saveCell == true) { + std::map mapTagReplacements; + XmlNode *surfaceCellNode = rootNode->addChild("SurfaceCell" + intToStr(index)); + surfaceCellNode->addAttribute("index", intToStr(index), mapTagReplacements); + + // //geometry + // Vec3f vertex; + surfaceCellNode->addAttribute("vertex", vertex.getString(), mapTagReplacements); + // Vec3f normal; + //surfaceCellNode->addAttribute("normal",normal.getString(), mapTagReplacements); + // Vec3f color; + //surfaceCellNode->addAttribute("color",color.getString(), mapTagReplacements); + // + // //tex coords + // Vec2f fowTexCoord; //tex coords for TEXTURE1 when multitexturing and fogOfWar + //surfaceCellNode->addAttribute("fowTexCoord",fowTexCoord.getString(), mapTagReplacements); + // Vec2f surfTexCoord; //tex coords for TEXTURE0 + //surfaceCellNode->addAttribute("surfTexCoord",surfTexCoord.getString(), mapTagReplacements); + // //surface + // int surfaceType; + //surfaceCellNode->addAttribute("surfaceType",intToStr(surfaceType), mapTagReplacements); + // const Texture2D *surfaceTexture; + // + // //object & resource + // Object *object; + if (object != NULL) { + object->saveGame(surfaceCellNode); + } else { + XmlNode *objectNode = surfaceCellNode->addChild("Object"); + objectNode->addAttribute("isDeleted", intToStr(true), mapTagReplacements); + } + // //visibility + // bool visible[GameConstants::maxPlayers + GameConstants::specialFactions]; + // for(unsigned int i = 0; i < GameConstants::maxPlayers; ++i) { + // if(visible[i] == true) { + // XmlNode *visibleNode = surfaceCellNode->addChild("visible"); + // visibleNode->addAttribute("index",intToStr(i), mapTagReplacements); + // visibleNode->addAttribute("value",intToStr(visible[i]), mapTagReplacements); + // } + // } + // // bool explored[GameConstants::maxPlayers + GameConstants::specialFactions]; + // for(unsigned int i = 0; i < GameConstants::maxPlayers; ++i) { + // if(explored[i] == true) { + // XmlNode *exploredNode = surfaceCellNode->addChild("explored"); + // exploredNode->addAttribute("index",intToStr(i), mapTagReplacements); + // exploredNode->addAttribute("value",intToStr(explored[i]), mapTagReplacements); + // } + // } + + // //cache + // bool nearSubmerged; + //surfaceCellNode->addAttribute("nearSubmerged",intToStr(nearSubmerged), mapTagReplacements); + } + } + + void SurfaceCell::loadGame(const XmlNode *rootNode, int index, World *world) { + if (rootNode->hasChild("SurfaceCell" + intToStr(index)) == true) { + const XmlNode *surfaceCellNode = rootNode->getChild("SurfaceCell" + intToStr(index)); + + if (surfaceCellNode->hasAttribute("vertex") == true) { + vertex = Vec3f::strToVec3(surfaceCellNode->getAttribute("vertex")->getValue()); + } + + //int visibleCount = cellNode->getChildCount(); + XmlNode *objectNode = surfaceCellNode->getChild("Object"); + if (objectNode->hasAttribute("isDeleted") == true) { + this->deleteResource(); + } else { + object->loadGame(surfaceCellNode, world->getTechTree()); + } + + //printf("Loading game, sc index [%d][%d]\n",index,visibleCount); + + // for(unsigned int i = 0; i < visibleCount; ++i) { + // if(cellNode->hasChildAtIndex("visible",i) == true) { + // const XmlNode *visibleNode = cellNode->getChild("visible",i); + // int indexCell = visibleNode->getAttribute("index")->getIntValue(); + // bool value = visibleNode->getAttribute("value")->getIntValue(); + // visible[indexCell] = value; + // + // //printf("Loading game, sc visible index [%d][%d][%d]\n",index,indexCell,value); + // } + // if(cellNode->hasChildAtIndex("explored",i) == true) { + // const XmlNode *exploredNode = cellNode->getChild("explored",i); + // int indexCell = exploredNode->getAttribute("index")->getIntValue(); + // bool value = exploredNode->getAttribute("value")->getIntValue(); + // explored[indexCell] = value; + // + // //printf("Loading game, sc explored cell index [%d] exploredIndex [%d] value [%d]\n",index,indexCell,value); + // } + // } + } + } + // ===================================================== + // class Map + // ===================================================== + + // ===================== PUBLIC ======================== + + const int Map::cellScale = 2; + const int Map::mapScale = 2; + + Map::Map() { + cells = NULL; + surfaceCells = NULL; + startLocations = NULL; + + title = ""; + waterLevel = 0; + heightFactor = 0; cliffLevel = 0; cameraHeight = 0; - if(header.version==1){ - //desc = header.description; - } - else if(header.version==2){ - //desc = header.version2.short_desc; - if(header.version2.cliffLevel > 0 && header.version2.cliffLevel < 5000){ - cliffLevel=static_cast((header.version2.cliffLevel-0.01f)/(heightFactor)); - cliffLevel = truncateDecimal(cliffLevel,6); - } - if(header.version2.cameraHeight > 0 && header.version2.cameraHeight < 5000) { - cameraHeight = header.version2.cameraHeight; - } - } + w = 0; + h = 0; + surfaceW = 0; + surfaceH = 0; + surfaceSize = (surfaceW * surfaceH); + maxPlayers = 0; + maxMapHeight = 0; + } - //start locations - startLocations= new Vec2i[maxPlayers]; - for(int i=0; i < hardMaxPlayers; ++i) { - int x=0, y=0; - readBytes = fread(&x, sizeof(int32), 1, f); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - x = ::Shared::PlatformByteOrder::fromCommonEndian(x); + Map::~Map() { + Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingMapCells", "", true), true); - readBytes = fread(&y, sizeof(int32), 1, f); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - y = ::Shared::PlatformByteOrder::fromCommonEndian(y); - - startLocations[i]= Vec2i(x, y)*cellScale; - } - - //cells - cells= new Cell[getCellArraySize()]; - surfaceCells= new SurfaceCell[getSurfaceCellArraySize()]; + delete[] cells; + cells = NULL; + delete[] surfaceCells; + surfaceCells = NULL; + delete[] startLocations; + startLocations = NULL; + } + void Map::end() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingMap", "", true), true); //read heightmap - for(int j = 0; j < surfaceH; ++j) { - for(int i = 0; i < surfaceW; ++i) { - float32 alt=0; - readBytes = fread(&alt, sizeof(float32), 1, f); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - alt = ::Shared::PlatformByteOrder::fromCommonEndian(alt); - - SurfaceCell *sc= getSurfaceCell(i, j); - sc->setVertex(Vec3f(i*mapScale, alt / heightFactor, j*mapScale)); + for (int j = 0; j < surfaceH; ++j) { + for (int i = 0; i < surfaceW; ++i) { + getSurfaceCell(i, j)->end(); } } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } - //read surfaces - for(int j = 0; j < surfaceH; ++j) { - for(int i = 0; i < surfaceW; ++i) { - int8 surf=0; - readBytes = fread(&surf, sizeof(int8), 1, f); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - surf = ::Shared::PlatformByteOrder::fromCommonEndian(surf); - - getSurfaceCell(i, j)->setSurfaceType(surf-1); - } + Vec2i Map::getStartLocation(int locationIndex) const { + if (locationIndex < hardMaxPlayers) // maxPlayers for a map, not the Game + return startLocations[locationIndex]; + else if (locationIndex < maxPlayers) { + // needed for enhanced observer mode (issue #13) + // observer may be in slot 6 of a 4-player map. Just set the + // startLocation to 0 + return startLocations[0]; + } else { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "locationIndex >= maxPlayers [%d] [%d]", locationIndex, maxPlayers); + printf("%s\n", szBuf); + throw megaglest_runtime_error(szBuf); + assert(locationIndex < GameConstants::maxPlayers); } + } - //read objects and resources - for(int j = 0; j < h; j += cellScale) { - for(int i = 0; i < w; i += cellScale) { + Checksum Map::load(const string &path, TechTree *techTree, Tileset *tileset) { + Checksum mapChecksum; + try { +#ifdef WIN32 + FILE *f = _wfopen(utf8_decode(path).c_str(), L"rb"); +#else + FILE *f = fopen(path.c_str(), "rb"); +#endif + if (f != NULL) { + mapFile = path; - int8 objNumber=0; - readBytes = fread(&objNumber, sizeof(int8), 1, f); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); + mapChecksum.addFile(path); + checksumValue.addFile(path); + //read header + MapFileHeader header; + size_t readBytes = fread(&header, sizeof(MapFileHeader), 1, f); + if (readBytes != 1) { + throw megaglest_runtime_error("Invalid map header detected for file: " + path); } - objNumber = ::Shared::PlatformByteOrder::fromCommonEndian(objNumber); + fromEndianMapFileHeader(header); - SurfaceCell *sc= getSurfaceCell(toSurfCoords(Vec2i(i, j))); - if(objNumber <= 0) { - sc->setObject(NULL); + if (next2Power(header.width) != header.width) { + throw megaglest_runtime_error("Map width is not a power of 2"); } - else if(objNumber <= Tileset::objCount) { - Object *o= new Object(tileset->getObjectType(objNumber-1), sc->getVertex(),Vec2i(i, j)); - sc->setObject(o); - for(int k = 0; k < techTree->getResourceTypeCount(); ++k) { - const ResourceType *rt= techTree->getResourceType(k); - if(rt->getClass() == rcTileset && rt->getTilesetObject() == objNumber){ + + if (next2Power(header.height) != header.height) { + throw megaglest_runtime_error("Map height is not a power of 2"); + } + + heightFactor = header.heightFactor; + if (heightFactor > 100) { + heightFactor = heightFactor / 100; + heightFactor = truncateDecimal(heightFactor, 6); + } + waterLevel = static_cast((header.waterLevel - 0.01f) / heightFactor); + waterLevel = truncateDecimal(waterLevel, 6); + title = header.title; + + //maxPlayers= header.maxFactions; + hardMaxPlayers = header.maxFactions; + maxPlayers = GameConstants::maxPlayers; + + surfaceW = header.width; + surfaceH = header.height; + surfaceSize = (surfaceW * surfaceH); + + w = surfaceW * cellScale; + h = surfaceH * cellScale; + cliffLevel = 0; + cameraHeight = 0; + if (header.version == 1) { + //desc = header.description; + } else if (header.version == 2) { + //desc = header.version2.short_desc; + if (header.version2.cliffLevel > 0 && header.version2.cliffLevel < 5000) { + cliffLevel = static_cast((header.version2.cliffLevel - 0.01f) / (heightFactor)); + cliffLevel = truncateDecimal(cliffLevel, 6); + } + if (header.version2.cameraHeight > 0 && header.version2.cameraHeight < 5000) { + cameraHeight = header.version2.cameraHeight; + } + } + + //start locations + startLocations = new Vec2i[maxPlayers]; + for (int i = 0; i < hardMaxPlayers; ++i) { + int x = 0, y = 0; + readBytes = fread(&x, sizeof(int32), 1, f); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + x = ::Shared::PlatformByteOrder::fromCommonEndian(x); + + readBytes = fread(&y, sizeof(int32), 1, f); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + y = ::Shared::PlatformByteOrder::fromCommonEndian(y); + + startLocations[i] = Vec2i(x, y)*cellScale; + } + + //cells + cells = new Cell[getCellArraySize()]; + surfaceCells = new SurfaceCell[getSurfaceCellArraySize()]; + + //read heightmap + for (int j = 0; j < surfaceH; ++j) { + for (int i = 0; i < surfaceW; ++i) { + float32 alt = 0; + readBytes = fread(&alt, sizeof(float32), 1, f); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + alt = ::Shared::PlatformByteOrder::fromCommonEndian(alt); + + SurfaceCell *sc = getSurfaceCell(i, j); + sc->setVertex(Vec3f(i*mapScale, alt / heightFactor, j*mapScale)); + } + } + + //read surfaces + for (int j = 0; j < surfaceH; ++j) { + for (int i = 0; i < surfaceW; ++i) { + int8 surf = 0; + readBytes = fread(&surf, sizeof(int8), 1, f); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + surf = ::Shared::PlatformByteOrder::fromCommonEndian(surf); + + getSurfaceCell(i, j)->setSurfaceType(surf - 1); + } + } + + //read objects and resources + for (int j = 0; j < h; j += cellScale) { + for (int i = 0; i < w; i += cellScale) { + + int8 objNumber = 0; + readBytes = fread(&objNumber, sizeof(int8), 1, f); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + objNumber = ::Shared::PlatformByteOrder::fromCommonEndian(objNumber); + + SurfaceCell *sc = getSurfaceCell(toSurfCoords(Vec2i(i, j))); + if (objNumber <= 0) { + sc->setObject(NULL); + } else if (objNumber <= Tileset::objCount) { + Object *o = new Object(tileset->getObjectType(objNumber - 1), sc->getVertex(), Vec2i(i, j)); + sc->setObject(o); + for (int k = 0; k < techTree->getResourceTypeCount(); ++k) { + const ResourceType *rt = techTree->getResourceType(k); + if (rt->getClass() == rcTileset && rt->getTilesetObject() == objNumber) { + o->setResource(rt, Vec2i(i, j)); + } + } + } else { + const ResourceType *rt = techTree->getTechResourceType(objNumber - Tileset::objCount); + Object *o = new Object(NULL, sc->getVertex(), Vec2i(i, j)); o->setResource(rt, Vec2i(i, j)); + sc->setObject(o); } } } - else{ - const ResourceType *rt= techTree->getTechResourceType(objNumber - Tileset::objCount) ; - Object *o= new Object(NULL, sc->getVertex(),Vec2i(i, j)); - o->setResource(rt, Vec2i(i, j)); - sc->setObject(o); - } + if (f) fclose(f); + } else { + throw megaglest_runtime_error("Can't open file"); } + } catch (const exception &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, e.what()); + throw megaglest_runtime_error("Error loading map: " + path + "\n" + e.what()); } - if(f) fclose(f); + + return mapChecksum; } - else { - throw megaglest_runtime_error("Can't open file"); + + void Map::init(Tileset *tileset) { + Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingMap", "", true), true); + maxMapHeight = 0.0f; + smoothSurface(tileset); + computeNormals(); + computeInterpolatedHeights(); + computeNearSubmerged(); + computeCellColors(); } - } - catch(const exception &e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what()); - throw megaglest_runtime_error("Error loading map: "+ path+ "\n"+ e.what()); - } - - return mapChecksum; -} - -void Map::init(Tileset *tileset) { - Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingMap","",true), true); - maxMapHeight=0.0f; - smoothSurface(tileset); - computeNormals(); - computeInterpolatedHeights(); - computeNearSubmerged(); - computeCellColors(); -} -// ==================== is ==================== + // ==================== is ==================== -class FindBestPos { -public: - float distanceFromUnitNoAdjustment; - float distanceFromClickNoAdjustment; - Vec2i resourcePosNoAdjustment; -}; + class FindBestPos { + public: + float distanceFromUnitNoAdjustment; + float distanceFromClickNoAdjustment; + Vec2i resourcePosNoAdjustment; + }; -//returns if there is a resource next to a unit, in "resourcePos" is stored the relative position of the resource -bool Map::isResourceNear(int frameIndex,const Vec2i &pos, const ResourceType *rt, Vec2i &resourcePos, - int size, Unit *unit, bool fallbackToPeersHarvestingSameResource, - Vec2i *resourceClickPos) const { + //returns if there is a resource next to a unit, in "resourcePos" is stored the relative position of the resource + bool Map::isResourceNear(int frameIndex, const Vec2i &pos, const ResourceType *rt, Vec2i &resourcePos, + int size, Unit *unit, bool fallbackToPeersHarvestingSameResource, + Vec2i *resourceClickPos) const { - bool resourceNear = false; - float distanceFromUnit=-1; - float distanceFromClick=-1; + bool resourceNear = false; + float distanceFromUnit = -1; + float distanceFromClick = -1; - if(resourceClickPos) { - //printf("+++++++++ unit [%s - %d] pos = [%s] resourceClickPos [%s]\n",unit->getFullName().c_str(),unit->getId(),pos.getString().c_str(),resourceClickPos->getString().c_str()); - } - for(int i = -size; i <= size; ++i) { - for(int j = -size; j <= size; ++j) { - Vec2i resPos = Vec2i(pos.x + i, pos.y + j); - if(resourceClickPos) { - resPos = Vec2i(resourceClickPos->x + i, resourceClickPos->y + j); + if (resourceClickPos) { + //printf("+++++++++ unit [%s - %d] pos = [%s] resourceClickPos [%s]\n",unit->getFullName().c_str(),unit->getId(),pos.getString().c_str(),resourceClickPos->getString().c_str()); } - Vec2i surfCoords = toSurfCoords(resPos); + for (int i = -size; i <= size; ++i) { + for (int j = -size; j <= size; ++j) { + Vec2i resPos = Vec2i(pos.x + i, pos.y + j); + if (resourceClickPos) { + resPos = Vec2i(resourceClickPos->x + i, resourceClickPos->y + j); + } + Vec2i surfCoords = toSurfCoords(resPos); - if(isInside(resPos) && isInsideSurface(surfCoords)) { - Resource *r= getSurfaceCell(surfCoords)->getResource(); - if(r != NULL) { - if(r->getType() == rt) { - if(resourceClickPos) { - //printf("****** unit [%s - %d] resPos = [%s] resourceClickPos->dist(resPos) [%f] distanceFromClick [%f] unit->getCenteredPos().dist(resPos) [%f] distanceFromUnit [%f]\n",unit->getFullName().c_str(),unit->getId(),resPos.getString().c_str(),resourceClickPos->dist(resPos),distanceFromClick,unit->getCenteredPos().dist(resPos),distanceFromUnit); - } - if(resourceClickPos == NULL || - (distanceFromClick < 0 || resourceClickPos->dist(resPos) <= distanceFromClick)) { - if(unit == NULL || - (distanceFromUnit < 0 || unit->getCenteredPos().dist(resPos) <= distanceFromUnit)) { - - bool isResourceNextToUnit = (resourceClickPos == NULL); - for(int i1 = -size; isResourceNextToUnit == false && i1 <= size; ++i1) { - for(int j1 = -size; j1 <= size; ++j1) { - Vec2i resPos1 = Vec2i(pos.x + i1, pos.y + j1); - if(resPos == resPos1) { - isResourceNextToUnit = true; - break; - } - } + if (isInside(resPos) && isInsideSurface(surfCoords)) { + Resource *r = getSurfaceCell(surfCoords)->getResource(); + if (r != NULL) { + if (r->getType() == rt) { + if (resourceClickPos) { + //printf("****** unit [%s - %d] resPos = [%s] resourceClickPos->dist(resPos) [%f] distanceFromClick [%f] unit->getCenteredPos().dist(resPos) [%f] distanceFromUnit [%f]\n",unit->getFullName().c_str(),unit->getId(),resPos.getString().c_str(),resourceClickPos->dist(resPos),distanceFromClick,unit->getCenteredPos().dist(resPos),distanceFromUnit); } - if(isResourceNextToUnit == true) { - if(resourceClickPos != NULL) { - distanceFromClick = resourceClickPos->dist(resPos); - } - if(unit != NULL) { - distanceFromUnit = unit->getCenteredPos().dist(resPos); - } + if (resourceClickPos == NULL || + (distanceFromClick < 0 || resourceClickPos->dist(resPos) <= distanceFromClick)) { + if (unit == NULL || + (distanceFromUnit < 0 || unit->getCenteredPos().dist(resPos) <= distanceFromUnit)) { - resourcePos= pos + Vec2i(i,j); + bool isResourceNextToUnit = (resourceClickPos == NULL); + for (int i1 = -size; isResourceNextToUnit == false && i1 <= size; ++i1) { + for (int j1 = -size; j1 <= size; ++j1) { + Vec2i resPos1 = Vec2i(pos.x + i1, pos.y + j1); + if (resPos == resPos1) { + isResourceNextToUnit = true; + break; + } + } + } + if (isResourceNextToUnit == true) { + if (resourceClickPos != NULL) { + distanceFromClick = resourceClickPos->dist(resPos); + } + if (unit != NULL) { + distanceFromUnit = unit->getCenteredPos().dist(resPos); + } - if(unit == NULL || unit->isBadHarvestPos(resourcePos) == false) { - resourceNear = true; + resourcePos = pos + Vec2i(i, j); - if(resourceClickPos) { - //printf("@@@@@@@@ unit [%s - %d] resPos = [%s] resourceClickPos->dist(resPos) [%f] distanceFromClick [%f] unit->getCenteredPos().dist(resPos) [%f] distanceFromUnit [%f]\n",unit->getFullName().c_str(),unit->getId(),resPos.getString().c_str(),resourceClickPos->dist(resPos),distanceFromClick,unit->getCenteredPos().dist(resPos),distanceFromUnit); + if (unit == NULL || unit->isBadHarvestPos(resourcePos) == false) { + resourceNear = true; + + if (resourceClickPos) { + //printf("@@@@@@@@ unit [%s - %d] resPos = [%s] resourceClickPos->dist(resPos) [%f] distanceFromClick [%f] unit->getCenteredPos().dist(resPos) [%f] distanceFromUnit [%f]\n",unit->getFullName().c_str(),unit->getId(),resPos.getString().c_str(),resourceClickPos->dist(resPos),distanceFromClick,unit->getCenteredPos().dist(resPos),distanceFromUnit); + } + } } } } @@ -666,468 +660,469 @@ bool Map::isResourceNear(int frameIndex,const Vec2i &pos, const ResourceType *rt } } } - } - } - if(resourceNear == false) { - if(fallbackToPeersHarvestingSameResource == true && unit != NULL) { - // Look for another unit that is currently harvesting the same resource - // type right now + if (resourceNear == false) { + if (fallbackToPeersHarvestingSameResource == true && unit != NULL) { + // Look for another unit that is currently harvesting the same resource + // type right now - // Check the faction cache for a known position where we can harvest - // this resource type - Vec2i result = unit->getFaction()->getClosestResourceTypeTargetFromCache(unit, rt,frameIndex); - if(result.x >= 0) { - resourcePos = result; + // Check the faction cache for a known position where we can harvest + // this resource type + Vec2i result = unit->getFaction()->getClosestResourceTypeTargetFromCache(unit, rt, frameIndex); + if (result.x >= 0) { + resourcePos = result; - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[found peer harvest pos] pos [%s] resourcePos [%s] unit->getFaction()->getCacheResourceTargetListSize() [%d]", - pos.getString().c_str(),resourcePos.getString().c_str(),unit->getFaction()->getCacheResourceTargetListSize()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[found peer harvest pos] pos [%s] resourcePos [%s] unit->getFaction()->getCacheResourceTargetListSize() [%d]", + pos.getString().c_str(), resourcePos.getString().c_str(), unit->getFaction()->getCacheResourceTargetListSize()); - if(frameIndex < 0) { - unit->logSynchData(__FILE__,__LINE__,szBuf); - } - else { - unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); - } - } + if (frameIndex < 0) { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } + } - if(unit->getPos().dist(resourcePos) <= size) { - resourceNear = true; + if (unit->getPos().dist(resourcePos) <= size) { + resourceNear = true; - if(resourceClickPos) { - //printf("###### unit [%s - %d]\n",unit->getFullName().c_str(),unit->getId()); + if (resourceClickPos) { + //printf("###### unit [%s - %d]\n",unit->getFullName().c_str(),unit->getId()); + } + } } } } + + if (resourceNear == false && resourceClickPos != NULL) { + std::vector bestPosList; + + //if(resourceClickPos) { + //printf("^^^^^ unit [%s - %d]\n",unit->getFullName().c_str(),unit->getId()); + //} + + for (int i = -1; i <= 1; ++i) { + for (int j = -1; j <= 1; ++j) { + Vec2i resPos = Vec2i(resourceClickPos->x + i, resourceClickPos->y + j); + Vec2i surfCoords = toSurfCoords(resPos); + + if (isInside(resPos) && isInsideSurface(surfCoords)) { + Resource *r = getSurfaceCell(surfCoords)->getResource(); + if (r != NULL) { + if (r->getType() == rt) { + //printf("^^^^^^ unit [%s - %d] resPos = [%s] resourceClickPos->dist(resPos) [%f] distanceFromClick [%f] unit->getCenteredPos().dist(resPos) [%f] distanceFromUnit [%f]\n",unit->getFullName().c_str(),unit->getId(),resPos.getString().c_str(),resourceClickPos->dist(resPos),distanceFromClick,unit->getCenteredPos().dist(resPos),distanceFromUnit); + + if (unit == NULL || + (distanceFromUnit < 0 || unit->getCenteredPos().dist(resPos) <= (distanceFromUnit + 2.0))) { + + if (resourceClickPos->dist(resPos) <= 1.0) { + if (unit != NULL) { + FindBestPos bestPosItem; + + bestPosItem.distanceFromUnitNoAdjustment = unit->getCenteredPos().dist(resPos); + bestPosItem.distanceFromClickNoAdjustment = distanceFromClick = resourceClickPos->dist(resPos); + bestPosItem.resourcePosNoAdjustment = resPos; + + bestPosList.push_back(bestPosItem); + } + } + + //printf("!!!! unit [%s - %d] resPos = [%s] resourceClickPos->dist(resPos) [%f] distanceFromClick [%f] unit->getCenteredPos().dist(resPos) [%f] distanceFromUnit [%f]\n",unit->getFullName().c_str(),unit->getId(),resPos.getString().c_str(),resourceClickPos->dist(resPos),distanceFromClick,unit->getCenteredPos().dist(resPos),distanceFromUnit); + if (distanceFromClick < 0 || resourceClickPos->dist(resPos) <= distanceFromClick) { + //if(resourceClickPos != NULL) { + distanceFromClick = resourceClickPos->dist(resPos); + //} + if (unit != NULL) { + distanceFromUnit = unit->getCenteredPos().dist(resPos); + } + + *resourceClickPos = resPos; + + if (unit == NULL || unit->isBadHarvestPos(*resourceClickPos) == false) { + //resourceNear = true; + + //printf("%%----------- unit [%s - %d] resPos = [%s] resourceClickPos->dist(resPos) [%f] distanceFromClick [%f] unit->getCenteredPos().dist(resPos) [%f] distanceFromUnit [%f]\n",unit->getFullName().c_str(),unit->getId(),resPos.getString().c_str(),resourceClickPos->dist(resPos),distanceFromClick,unit->getCenteredPos().dist(resPos),distanceFromUnit); + } + } + } + } + } + } + } + } + + float bestUnitDist = distanceFromUnit; + for (unsigned int i = 0; i < bestPosList.size(); ++i) { + FindBestPos &bestPosItem = bestPosList[i]; + + if (bestPosItem.distanceFromUnitNoAdjustment < bestUnitDist) { + bestUnitDist = bestPosItem.distanceFromUnitNoAdjustment; + *resourceClickPos = bestPosItem.resourcePosNoAdjustment; + + if (unit == NULL || unit->isBadHarvestPos(*resourceClickPos) == false) { + //printf("%%----------- unit [%s - %d] resourceClickPos [%s] bestUnitDist [%f]\n",unit->getFullName().c_str(),unit->getId(),resourceClickPos->getString().c_str(),bestUnitDist); + } + } + } + } + + return resourceNear; } - } - if(resourceNear == false && resourceClickPos != NULL) { - std::vector bestPosList; + // ==================== free cells ==================== - //if(resourceClickPos) { - //printf("^^^^^ unit [%s - %d]\n",unit->getFullName().c_str(),unit->getId()); + bool Map::isFreeCell(const Vec2i &pos, Field field) const { + return + isInside(pos) && + isInsideSurface(toSurfCoords(pos)) && + getCell(pos)->isFree(field) && + (field == fAir || getSurfaceCell(toSurfCoords(pos))->isFree()) && + (field != fLand || getDeepSubmerged(getCell(pos)) == false); + } + + + bool Map::isFreeCellOrHasUnit(const Vec2i &pos, Field field, const Unit *unit) const { + if (isInside(pos)) { + Cell *c = getCell(pos); + if (c->getUnit(field) == unit && unit != NULL) { + return true; + } else { + return isFreeCell(pos, field); + } + } + return false; + } + + //TT: this is much more complicated compared with the old one above. I think its no more needed + //bool Map::isFreeCellOrHasUnit(const Vec2i &pos, Field field, const Unit *unit) const { + // if(isInside(pos) && isInsideSurface(toSurfCoords(pos))) { + // if(unit->getCurrField() != field) { + // return isFreeCell(pos, field); + // } + // Cell *c= getCell(pos); + // if(c->getUnit(unit->getCurrField()) == unit) { + // if(unit->getCurrField() == fAir) { + // if(field == fAir) { + // return true; + // } + // const SurfaceCell *sc= getSurfaceCell(toSurfCoords(pos)); + // if(sc != NULL) { + // if(getDeepSubmerged(sc) == true) { + // return false; + // } + // else if(field == fLand) { + // if(sc->isFree() == false) { + // return false; + // } + // else if(c->getUnit(field) != NULL) { + // return false; + // } + // } + // } + // } + // return true; + // } + // else{ + // return isFreeCell(pos, field); + // } + // } + // return false; //} - for(int i = -1; i <= 1; ++i) { - for(int j = -1; j <= 1; ++j) { - Vec2i resPos = Vec2i(resourceClickPos->x + i, resourceClickPos->y + j); - Vec2i surfCoords = toSurfCoords(resPos); + bool Map::isAproxFreeCell(const Vec2i &pos, Field field, int teamIndex) const { + if (isInside(pos) && isInsideSurface(toSurfCoords(pos))) { + const SurfaceCell *sc = getSurfaceCell(toSurfCoords(pos)); - if(isInside(resPos) && isInsideSurface(surfCoords)) { - Resource *r= getSurfaceCell(surfCoords)->getResource(); - if(r != NULL) { - if(r->getType() == rt) { - //printf("^^^^^^ unit [%s - %d] resPos = [%s] resourceClickPos->dist(resPos) [%f] distanceFromClick [%f] unit->getCenteredPos().dist(resPos) [%f] distanceFromUnit [%f]\n",unit->getFullName().c_str(),unit->getId(),resPos.getString().c_str(),resourceClickPos->dist(resPos),distanceFromClick,unit->getCenteredPos().dist(resPos),distanceFromUnit); + if (sc->isVisible(teamIndex)) { + return isFreeCell(pos, field); + } else if (sc->isExplored(teamIndex)) { + return field == fLand ? sc->isFree() && !getDeepSubmerged(getCell(pos)) : true; + } else { + return true; + } + } - if(unit == NULL || - (distanceFromUnit < 0 || unit->getCenteredPos().dist(resPos) <= (distanceFromUnit + 2.0))) { + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + return false; + } - if(resourceClickPos->dist(resPos) <= 1.0) { - if(unit != NULL) { - FindBestPos bestPosItem; - - bestPosItem.distanceFromUnitNoAdjustment = unit->getCenteredPos().dist(resPos); - bestPosItem.distanceFromClickNoAdjustment =distanceFromClick = resourceClickPos->dist(resPos); - bestPosItem.resourcePosNoAdjustment = resPos; - - bestPosList.push_back(bestPosItem); - } - } - - //printf("!!!! unit [%s - %d] resPos = [%s] resourceClickPos->dist(resPos) [%f] distanceFromClick [%f] unit->getCenteredPos().dist(resPos) [%f] distanceFromUnit [%f]\n",unit->getFullName().c_str(),unit->getId(),resPos.getString().c_str(),resourceClickPos->dist(resPos),distanceFromClick,unit->getCenteredPos().dist(resPos),distanceFromUnit); - if(distanceFromClick < 0 || resourceClickPos->dist(resPos) <= distanceFromClick) { - //if(resourceClickPos != NULL) { - distanceFromClick = resourceClickPos->dist(resPos); - //} - if(unit != NULL) { - distanceFromUnit = unit->getCenteredPos().dist(resPos); - } - - *resourceClickPos = resPos; - - if(unit == NULL || unit->isBadHarvestPos(*resourceClickPos) == false) { - //resourceNear = true; - - //printf("%%----------- unit [%s - %d] resPos = [%s] resourceClickPos->dist(resPos) [%f] distanceFromClick [%f] unit->getCenteredPos().dist(resPos) [%f] distanceFromUnit [%f]\n",unit->getFullName().c_str(),unit->getId(),resPos.getString().c_str(),resourceClickPos->dist(resPos),distanceFromClick,unit->getCenteredPos().dist(resPos),distanceFromUnit); - } - } - } - } + bool Map::isFreeCells(const Vec2i & pos, int size, Field field) const { + for (int i = pos.x; i < pos.x + size; ++i) { + for (int j = pos.y; j < pos.y + size; ++j) { + Vec2i testPos(i, j); + if (isFreeCell(testPos, field) == false) { + return false; } } } + return true; } - float bestUnitDist = distanceFromUnit; - for(unsigned int i = 0; i < bestPosList.size(); ++i) { - FindBestPos &bestPosItem = bestPosList[i]; - - if(bestPosItem.distanceFromUnitNoAdjustment < bestUnitDist) { - bestUnitDist = bestPosItem.distanceFromUnitNoAdjustment; - *resourceClickPos = bestPosItem.resourcePosNoAdjustment; - - if(unit == NULL || unit->isBadHarvestPos(*resourceClickPos) == false) { - //printf("%%----------- unit [%s - %d] resourceClickPos [%s] bestUnitDist [%f]\n",unit->getFullName().c_str(),unit->getId(),resourceClickPos->getString().c_str(),bestUnitDist); + bool Map::isFreeCellsOrHasUnit(const Vec2i &pos, int size, Field field, + const Unit *unit) const { + for (int i = pos.x; i < pos.x + size; ++i) { + for (int j = pos.y; j < pos.y + size; ++j) { + if (isFreeCellOrHasUnit(Vec2i(i, j), field, unit) == false) { + return false; + } } } - } - } - - return resourceNear; -} - -// ==================== free cells ==================== - -bool Map::isFreeCell(const Vec2i &pos, Field field) const { - return - isInside(pos) && - isInsideSurface(toSurfCoords(pos)) && - getCell(pos)->isFree(field) && - (field==fAir || getSurfaceCell(toSurfCoords(pos))->isFree()) && - (field!=fLand || getDeepSubmerged(getCell(pos)) == false); -} - - -bool Map::isFreeCellOrHasUnit(const Vec2i &pos, Field field, const Unit *unit) const{ - if(isInside(pos)){ - Cell *c= getCell(pos); - if(c->getUnit(field) == unit && unit != NULL) { return true; } - else{ - return isFreeCell(pos, field); - } - } - return false; -} -//TT: this is much more complicated compared with the old one above. I think its no more needed -//bool Map::isFreeCellOrHasUnit(const Vec2i &pos, Field field, const Unit *unit) const { -// if(isInside(pos) && isInsideSurface(toSurfCoords(pos))) { -// if(unit->getCurrField() != field) { -// return isFreeCell(pos, field); -// } -// Cell *c= getCell(pos); -// if(c->getUnit(unit->getCurrField()) == unit) { -// if(unit->getCurrField() == fAir) { -// if(field == fAir) { -// return true; -// } -// const SurfaceCell *sc= getSurfaceCell(toSurfCoords(pos)); -// if(sc != NULL) { -// if(getDeepSubmerged(sc) == true) { -// return false; -// } -// else if(field == fLand) { -// if(sc->isFree() == false) { -// return false; -// } -// else if(c->getUnit(field) != NULL) { -// return false; -// } -// } -// } -// } -// return true; -// } -// else{ -// return isFreeCell(pos, field); -// } -// } -// return false; -//} - -bool Map::isAproxFreeCell(const Vec2i &pos, Field field, int teamIndex) const { - if(isInside(pos) && isInsideSurface(toSurfCoords(pos))) { - const SurfaceCell *sc= getSurfaceCell(toSurfCoords(pos)); - - if(sc->isVisible(teamIndex)) { - return isFreeCell(pos, field); - } - else if(sc->isExplored(teamIndex)) { - return field==fLand? sc->isFree() && !getDeepSubmerged(getCell(pos)): true; - } - else { + bool Map::isAproxFreeCells(const Vec2i &pos, int size, Field field, int teamIndex) const { + for (int i = pos.x; i < pos.x + size; ++i) { + for (int j = pos.y; j < pos.y + size; ++j) { + if (isAproxFreeCell(Vec2i(i, j), field, teamIndex) == false) { + return false; + } + } + } return true; } - } - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; -} + bool Map::canMorph(const Vec2i &pos, const Unit *currentUnit, const UnitType *targetUnitType) const { + Field field = targetUnitType->getField(); + const UnitType *ut = targetUnitType; + CardinalDir facing = currentUnit->getModelFacing(); -bool Map::isFreeCells(const Vec2i & pos, int size, Field field) const { - for(int i=pos.x; igetField(); - const UnitType *ut=targetUnitType; - CardinalDir facing=currentUnit->getModelFacing(); - - if (ut->hasCellMap() && isInside(pos) && isInsideSurface(toSurfCoords(pos))) { - for (int y=0; y < ut->getSize(); ++y) { - for (int x=0; x < ut->getSize(); ++x) { - Vec2i cellPos = pos + Vec2i(x, y); - if(isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) { - if (ut->getCellMapCell(x, y, facing)) { - if (isFreeCellOrHasUnit(cellPos, field, currentUnit) == false) { + if (ut->hasCellMap() && isInside(pos) && isInsideSurface(toSurfCoords(pos))) { + for (int y = 0; y < ut->getSize(); ++y) { + for (int x = 0; x < ut->getSize(); ++x) { + Vec2i cellPos = pos + Vec2i(x, y); + if (isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) { + if (ut->getCellMapCell(x, y, facing)) { + if (isFreeCellOrHasUnit(cellPos, field, currentUnit) == false) { + return false; + } + } + } else { return false; } } } - else { - return false; - } + return true; + } else { + return isFreeCellsOrHasUnit(pos, ut->getSize(), field, currentUnit); } } - return true; - } - else { - return isFreeCellsOrHasUnit(pos, ut->getSize(), field,currentUnit); - } -} -//bool Map::canOccupy(const Vec2i &pos, Field field, const UnitType *ut, CardinalDir facing) { -// if (ut->hasCellMap() && isInside(pos) && isInsideSurface(toSurfCoords(pos))) { -// for (int y=0; y < ut->getSize(); ++y) { -// for (int x=0; x < ut->getSize(); ++x) { -// Vec2i cellPos = pos + Vec2i(x, y); -// if(isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) { -// if (ut->getCellMapCell(x, y, facing)) { -// if (isFreeCell(cellPos, field) == false) { -// return false; -// } -// } -// } -// else { -// return false; -// } -// } -// } -// return true; -// } -// else { -// return isFreeCells(pos, ut->getSize(), field); -// } -//} + //bool Map::canOccupy(const Vec2i &pos, Field field, const UnitType *ut, CardinalDir facing) { + // if (ut->hasCellMap() && isInside(pos) && isInsideSurface(toSurfCoords(pos))) { + // for (int y=0; y < ut->getSize(); ++y) { + // for (int x=0; x < ut->getSize(); ++x) { + // Vec2i cellPos = pos + Vec2i(x, y); + // if(isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) { + // if (ut->getCellMapCell(x, y, facing)) { + // if (isFreeCell(cellPos, field) == false) { + // return false; + // } + // } + // } + // else { + // return false; + // } + // } + // } + // return true; + // } + // else { + // return isFreeCells(pos, ut->getSize(), field); + // } + //} -// ==================== unit placement ==================== + // ==================== unit placement ==================== -//checks if a unit can move from between 2 cells -bool Map::canMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, std::map > > > *lookupCache) const { - int size= unit->getType()->getSize(); - Field field= unit->getCurrField(); + //checks if a unit can move from between 2 cells + bool Map::canMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, std::map > > > *lookupCache) const { + int size = unit->getType()->getSize(); + Field field = unit->getCurrField(); - if(lookupCache != NULL) { - std::map > > >::const_iterator iterFind1 = lookupCache->find(pos1); - if(iterFind1 != lookupCache->end()) { - std::map > >::const_iterator iterFind2 = iterFind1->second.find(pos2); - if(iterFind2 != iterFind1->second.end()) { - std::map >::const_iterator iterFind3 = iterFind2->second.find(size); - if(iterFind3 != iterFind2->second.end()) { - std::map::const_iterator iterFind4 = iterFind3->second.find(field); - if(iterFind4 != iterFind3->second.end()) { - // Found this result in the cache - return iterFind4->second; + if (lookupCache != NULL) { + std::map > > >::const_iterator iterFind1 = lookupCache->find(pos1); + if (iterFind1 != lookupCache->end()) { + std::map > >::const_iterator iterFind2 = iterFind1->second.find(pos2); + if (iterFind2 != iterFind1->second.end()) { + std::map >::const_iterator iterFind3 = iterFind2->second.find(size); + if (iterFind3 != iterFind2->second.end()) { + std::map::const_iterator iterFind4 = iterFind3->second.find(field); + if (iterFind4 != iterFind3->second.end()) { + // Found this result in the cache + return iterFind4->second; + } + } } } } - } - } - for(int i=pos2.x; igetUnit(field) != unit) { - if(isFreeCell(Vec2i(i, j), field) == false) { - if(lookupCache != NULL) { - (*lookupCache)[pos1][pos2][size][field]=false; + for (int i = pos2.x; i < pos2.x + size; ++i) { + for (int j = pos2.y; j < pos2.y + size; ++j) { + if (isInside(i, j) && isInsideSurface(toSurfCoords(Vec2i(i, j)))) { + if (getCell(i, j)->getUnit(field) != unit) { + if (isFreeCell(Vec2i(i, j), field) == false) { + if (lookupCache != NULL) { + (*lookupCache)[pos1][pos2][size][field] = false; + } + + return false; + } + } + } else { + if (lookupCache != NULL) { + (*lookupCache)[pos1][pos2][size][field] = false; } return false; } } } - else { - if(lookupCache != NULL) { - (*lookupCache)[pos1][pos2][size][field]=false; + + bool isBadHarvestPos = false; + //if(unit != NULL) { + Command *command = unit->getCurrCommand(); + if (command != NULL) { + const HarvestCommandType *hct = dynamic_cast(command->getCommandType()); + if (hct != NULL && unit->isBadHarvestPos(pos2) == true) { + isBadHarvestPos = true; + } + } + //} + + if (isBadHarvestPos == true) { + if (lookupCache != NULL) { + (*lookupCache)[pos1][pos2][size][field] = false; } return false; } - } - } - bool isBadHarvestPos = false; - //if(unit != NULL) { - Command *command= unit->getCurrCommand(); - if(command != NULL) { - const HarvestCommandType *hct = dynamic_cast(command->getCommandType()); - if(hct != NULL && unit->isBadHarvestPos(pos2) == true) { - isBadHarvestPos = true; + if (lookupCache != NULL) { + (*lookupCache)[pos1][pos2][size][field] = true; } - } - //} - if(isBadHarvestPos == true) { - if(lookupCache != NULL) { - (*lookupCache)[pos1][pos2][size][field]=false; + return true; } - return false; - } + //checks if a unit can move from between 2 cells using only visible cells (for pathfinding) + bool Map::aproxCanMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, std::map > > > > *lookupCache) const { + if (isInside(pos1) == false || isInsideSurface(toSurfCoords(pos1)) == false || + isInside(pos2) == false || isInsideSurface(toSurfCoords(pos2)) == false) { - if(lookupCache != NULL) { - (*lookupCache)[pos1][pos2][size][field]=true; - } + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + return false; + } - return true; -} + if (unit == NULL) { + throw megaglest_runtime_error("unit == NULL"); + } + int size = unit->getType()->getSize(); + int teamIndex = unit->getTeam(); + Field field = unit->getCurrField(); -//checks if a unit can move from between 2 cells using only visible cells (for pathfinding) -bool Map::aproxCanMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, std::map > > > > *lookupCache) const { - if(isInside(pos1) == false || isInsideSurface(toSurfCoords(pos1)) == false || - isInside(pos2) == false || isInsideSurface(toSurfCoords(pos2)) == false) { - - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; - } - - if(unit == NULL) { - throw megaglest_runtime_error("unit == NULL"); - } - int size= unit->getType()->getSize(); - int teamIndex= unit->getTeam(); - Field field= unit->getCurrField(); - - if(lookupCache != NULL) { - std::map > > > >::const_iterator iterFind1 = lookupCache->find(pos1); - if(iterFind1 != lookupCache->end()) { - std::map > > >::const_iterator iterFind2 = iterFind1->second.find(pos2); - if(iterFind2 != iterFind1->second.end()) { - std::map > >::const_iterator iterFind3 = iterFind2->second.find(teamIndex); - if(iterFind3 != iterFind2->second.end()) { - std::map >::const_iterator iterFind4 = iterFind3->second.find(size); - if(iterFind4 != iterFind3->second.end()) { - std::map::const_iterator iterFind5 = iterFind4->second.find(field); - if(iterFind5 != iterFind4->second.end()) { - // Found this result in the cache - if(iterFind5->second == false) { - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + if (lookupCache != NULL) { + std::map > > > >::const_iterator iterFind1 = lookupCache->find(pos1); + if (iterFind1 != lookupCache->end()) { + std::map > > >::const_iterator iterFind2 = iterFind1->second.find(pos2); + if (iterFind2 != iterFind1->second.end()) { + std::map > >::const_iterator iterFind3 = iterFind2->second.find(teamIndex); + if (iterFind3 != iterFind2->second.end()) { + std::map >::const_iterator iterFind4 = iterFind3->second.find(size); + if (iterFind4 != iterFind3->second.end()) { + std::map::const_iterator iterFind5 = iterFind4->second.find(field); + if (iterFind5 != iterFind4->second.end()) { + // Found this result in the cache + if (iterFind5->second == false) { + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + } + return iterFind5->second; + } } - return iterFind5->second; } } } } - } - } - //single cell units - if(size == 1) { - if(isAproxFreeCell(pos2, field, teamIndex) == false) { - if(lookupCache != NULL) { - (*lookupCache)[pos1][pos2][teamIndex][size][field]=false; - } + //single cell units + if (size == 1) { + if (isAproxFreeCell(pos2, field, teamIndex) == false) { + if (lookupCache != NULL) { + (*lookupCache)[pos1][pos2][teamIndex][size][field] = false; + } - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; - } - if(pos1.x != pos2.x && pos1.y != pos2.y) { - if(isAproxFreeCell(Vec2i(pos1.x, pos2.y), field, teamIndex) == false) { - if(lookupCache != NULL) { - (*lookupCache)[pos1][pos2][teamIndex][size][field]=false; + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + return false; + } + if (pos1.x != pos2.x && pos1.y != pos2.y) { + if (isAproxFreeCell(Vec2i(pos1.x, pos2.y), field, teamIndex) == false) { + if (lookupCache != NULL) { + (*lookupCache)[pos1][pos2][teamIndex][size][field] = false; + } + + //Unit *cellUnit = getCell(Vec2i(pos1.x, pos2.y))->getUnit(field); + //Object * obj = getSurfaceCell(toSurfCoords(Vec2i(pos1.x, pos2.y)))->getObject(); + + //printf("[%s] Line: %d returning false cell [%s] free [%d] cell unitid = %d object class = %d\n",__FUNCTION__,__LINE__,Vec2i(pos1.x, pos2.y).getString().c_str(),this->isFreeCell(Vec2i(pos1.x, pos2.y),field),(cellUnit != NULL ? cellUnit->getId() : -1),(obj != NULL ? obj->getType()->getClass() : -1)); + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + return false; + } + if (isAproxFreeCell(Vec2i(pos2.x, pos1.y), field, teamIndex) == false) { + if (lookupCache != NULL) { + (*lookupCache)[pos1][pos2][teamIndex][size][field] = false; + } + + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + return false; + } } - //Unit *cellUnit = getCell(Vec2i(pos1.x, pos2.y))->getUnit(field); - //Object * obj = getSurfaceCell(toSurfCoords(Vec2i(pos1.x, pos2.y)))->getObject(); + bool isBadHarvestPos = false; + //if(unit != NULL) { + Command *command = unit->getCurrCommand(); + if (command != NULL) { + const HarvestCommandType *hct = dynamic_cast(command->getCommandType()); + if (hct != NULL && unit->isBadHarvestPos(pos2) == true) { + isBadHarvestPos = true; + } + } + //} - //printf("[%s] Line: %d returning false cell [%s] free [%d] cell unitid = %d object class = %d\n",__FUNCTION__,__LINE__,Vec2i(pos1.x, pos2.y).getString().c_str(),this->isFreeCell(Vec2i(pos1.x, pos2.y),field),(cellUnit != NULL ? cellUnit->getId() : -1),(obj != NULL ? obj->getType()->getClass() : -1)); - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; - } - if(isAproxFreeCell(Vec2i(pos2.x, pos1.y), field, teamIndex) == false) { - if(lookupCache != NULL) { - (*lookupCache)[pos1][pos2][teamIndex][size][field]=false; + if (unit == NULL || isBadHarvestPos == true) { + if (lookupCache != NULL) { + (*lookupCache)[pos1][pos2][teamIndex][size][field] = false; + } + + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + return false; } - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; - } - } - - bool isBadHarvestPos = false; - //if(unit != NULL) { - Command *command= unit->getCurrCommand(); - if(command != NULL) { - const HarvestCommandType *hct = dynamic_cast(command->getCommandType()); - if(hct != NULL && unit->isBadHarvestPos(pos2) == true) { - isBadHarvestPos = true; + if (lookupCache != NULL) { + (*lookupCache)[pos1][pos2][teamIndex][size][field] = true; } + + return true; } - //} + //multi cell units + else { + for (int i = pos2.x; i < pos2.x + size; ++i) { + for (int j = pos2.y; j < pos2.y + size; ++j) { - if(unit == NULL || isBadHarvestPos == true) { - if(lookupCache != NULL) { - (*lookupCache)[pos1][pos2][teamIndex][size][field]=false; - } + Vec2i cellPos = Vec2i(i, j); + if (isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) { + if (getCell(cellPos)->getUnit(unit->getCurrField()) != unit) { + if (isAproxFreeCell(cellPos, field, teamIndex) == false) { + if (lookupCache != NULL) { + (*lookupCache)[pos1][pos2][teamIndex][size][field] = false; + } - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; - } + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + return false; + } + } + } else { - if(lookupCache != NULL) { - (*lookupCache)[pos1][pos2][teamIndex][size][field]=true; - } - - return true; - } - //multi cell units - else { - for(int i = pos2.x; i < pos2.x + size; ++i) { - for(int j = pos2.y; j < pos2.y + size; ++j) { - - Vec2i cellPos = Vec2i(i,j); - if(isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) { - if(getCell(cellPos)->getUnit(unit->getCurrField()) != unit) { - if(isAproxFreeCell(cellPos, field, teamIndex) == false) { - if(lookupCache != NULL) { - (*lookupCache)[pos1][pos2][teamIndex][size][field]=false; + if (lookupCache != NULL) { + (*lookupCache)[pos1][pos2][teamIndex][size][field] = false; } //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); @@ -1135,943 +1130,922 @@ bool Map::aproxCanMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, s } } } - else { - if(lookupCache != NULL) { - (*lookupCache)[pos1][pos2][teamIndex][size][field]=false; + bool isBadHarvestPos = false; + Command *command = unit->getCurrCommand(); + if (command != NULL) { + const HarvestCommandType *hct = dynamic_cast(command->getCommandType()); + if (hct != NULL && unit->isBadHarvestPos(pos2) == true) { + isBadHarvestPos = true; + } + } + + if (isBadHarvestPos == true) { + if (lookupCache != NULL) { + (*lookupCache)[pos1][pos2][teamIndex][size][field] = false; } //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); return false; } - } - } - bool isBadHarvestPos = false; - Command *command= unit->getCurrCommand(); - if(command != NULL) { - const HarvestCommandType *hct = dynamic_cast(command->getCommandType()); - if(hct != NULL && unit->isBadHarvestPos(pos2) == true) { - isBadHarvestPos = true; - } - } - - if(isBadHarvestPos == true) { - if(lookupCache != NULL) { - (*lookupCache)[pos1][pos2][teamIndex][size][field]=false; - } - - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; - } - - if(lookupCache != NULL) { - (*lookupCache)[pos1][pos2][teamIndex][size][field]=true; - } - } - return true; -} - - -Vec2i Map::computeRefPos(const Selection *selection) const { - Vec2i total= Vec2i(0); - - if(selection == NULL) { - throw megaglest_runtime_error("selection == NULL"); - } - - for(int i = 0; i < selection->getCount(); ++i) { - if(selection->getUnit(i) == NULL) { - throw megaglest_runtime_error("selection == NULL || selection->getUnit(i) == NULL"); - } - total = total + selection->getUnit(i)->getPosNotThreadSafe(); - } - - return Vec2i(total.x / selection->getCount(), total.y / selection->getCount()); -} - -Vec2i Map::computeDestPos( const Vec2i &refUnitPos, const Vec2i &unitPos, - const Vec2i &commandPos) const { - Vec2i pos; -// no more random needed -// Vec2i posDiff = unitPos - refUnitPos; -// -// if(abs(posDiff.x) >= 3){ -// posDiff.x = posDiff.x % 3; -// } -// -// if(abs(posDiff.y) >= 3){ -// posDiff.y = posDiff.y % 3; -// } - - pos = commandPos; //+ posDiff; - clampPos(pos); - return pos; -} - -//std::pair Map::getUnitDistanceToPos(const Unit *unit,Vec2i pos,const UnitType *ut) { -// if(unit == NULL) { -// throw megaglest_runtime_error("unit == NULL"); -// } -// -// std::pair result(-1,Vec2i(0)); -// //int unitId= unit->getId(); -// Vec2i unitPos= computeDestPos(unit->getPosNotThreadSafe(), unit->getPosNotThreadSafe(), pos); -// -// Vec2i start = pos - Vec2i(1); -// int unitTypeSize = 0; -// if(ut != NULL) { -// unitTypeSize = ut->getSize(); -// } -// Vec2i end = pos + Vec2i(unitTypeSize); -// -// for(int i = start.x; i <= end.x; ++i) { -// for(int j = start.y; j <= end.y; ++j){ -// Vec2i testPos(i,j); -// -// if(ut == NULL || isInUnitTypeCells(ut, pos,testPos) == false) { -// float distance = unitPos.dist(testPos); -// if(result.first < 0 || result.first > distance) { -// result.first = distance; -// result.second = testPos; -// } -// } -// } -// } -// -// return result; -//} - -const Unit * Map::findClosestUnitToPos(const Selection *selection, Vec2i originalBuildPos, - const UnitType *ut) const { - const Unit *closestUnit = NULL; - Vec2i refPos = computeRefPos(selection); - - Vec2i pos = originalBuildPos; - - float bestRange = -1; - - Vec2i start = pos - Vec2i(1); - int unitTypeSize = 0; - if(ut != NULL) { - unitTypeSize = ut->getSize(); - } - Vec2i end = pos + Vec2i(unitTypeSize); - - for(int i = 0; i < selection->getCount(); ++i) { - const Unit *unit = selection->getUnit(i); - //int unitId= unit->getId(); - Vec2i unitBuilderPos= computeDestPos(refPos, unit->getPosNotThreadSafe(), pos); - - for(int i = start.x; i <= end.x; ++i) { - for(int j = start.y; j <= end.y; ++j){ - Vec2i testPos(i,j); - if(isInUnitTypeCells(ut, originalBuildPos,testPos) == false) { - float distance = unitBuilderPos.dist(testPos); - if(bestRange < 0 || bestRange > distance) { - bestRange = distance; - pos = testPos; - closestUnit = unit; - } + if (lookupCache != NULL) { + (*lookupCache)[pos1][pos2][teamIndex][size][field] = true; } } + return true; } - } - return closestUnit; -} -Vec2i Map::findBestBuildApproach(const Unit *unit, Vec2i originalBuildPos,const UnitType *ut) const { - if(unit == NULL) { - throw megaglest_runtime_error("unit == NULL"); - } - if(ut == NULL) { - throw megaglest_runtime_error("ut == NULL"); - } + Vec2i Map::computeRefPos(const Selection *selection) const { + Vec2i total = Vec2i(0); - Vec2i unitBuilderPos = unit->getPosNotThreadSafe(); - Vec2i pos = originalBuildPos; - - float bestRange = -1; - - Vec2i start = pos - Vec2i(unit->getType()->getSize()); - Vec2i end = pos + Vec2i(ut->getSize()); - - for(int i = start.x; i <= end.x; ++i) { - for(int j = start.y; j <= end.y; ++j) { - Vec2i testPos(i,j); - if(isInUnitTypeCells(ut, originalBuildPos,testPos) == false) { - float distance = unitBuilderPos.dist(testPos); - if(bestRange < 0 || bestRange > distance) { - // Check if the cell is occupied by another unit - if(isFreeCellOrHasUnit(testPos, unit->getType()->getField(), unit) == true) { - bestRange = distance; - pos = testPos; - } - } - } - } - } - - return pos; -} - -bool Map::isNextToUnitTypeCells(const UnitType *ut, const Vec2i &pos, - const Vec2i &testPos) const { - bool isInsideDestUnitCells = isInUnitTypeCells(ut, pos,testPos); - if(isInsideDestUnitCells == false) { - //Cell *testCell = getCell(testPos); - for(int i=-1; i <= ut->getSize(); ++i){ - for(int j = -1; j <= ut->getSize(); ++j) { - Vec2i currPos = pos + Vec2i(i, j); - if(isInside(currPos) == true && isInsideSurface(toSurfCoords(currPos)) == true) { - //Cell *unitCell = getCell(currPos); - //if(unitCell == testCell) { - if(isNextTo(testPos,currPos) == true) { - return true; - } - } - } - } - } - - return false; -} - -// is testPos in the cells of unitType where unitType's position is pos -bool Map::isInUnitTypeCells(const UnitType *ut, const Vec2i &pos, - const Vec2i &testPos) const { - assert(ut != NULL); - if(ut == NULL) { - throw megaglest_runtime_error("ut == NULL"); - } - - if(isInside(testPos) && isInsideSurface(toSurfCoords(testPos))) { - Cell *testCell = getCell(testPos); - for(int i=0; i < ut->getSize(); ++i){ - for(int j = 0; j < ut->getSize(); ++j) { - Vec2i currPos = pos + Vec2i(i, j); - if(isInside(currPos) && isInsideSurface(toSurfCoords(currPos))) { - Cell *unitCell = getCell(currPos); - if(unitCell == testCell) { - return true; - } - } - } - } - } - return false; -} - -//put a units into the cells -void Map::putUnitCells(Unit *unit, const Vec2i &pos, bool ignoreSkill, bool threaded) { - assert(unit != NULL); - if(unit == NULL) { - throw megaglest_runtime_error("ut == NULL"); - } - putUnitCellsPrivate(unit, pos, unit->getType(), false, threaded); - - // block space for morphing units - if(ignoreSkill==false && - unit->getCurrSkill() != NULL && - unit->getCurrSkill()->getClass() == scMorph) { - Command *command= unit->getCurrCommand(); - if(command != NULL && command->getCommandType()->commandTypeClass == ccMorph){ - const MorphCommandType *mct= static_cast(command->getCommandType()); - putUnitCellsPrivate(unit, pos, mct->getMorphUnit(),true, threaded); - unit->setMorphFieldsBlocked(true); - } - } -} - -void Map::putUnitCellsPrivate(Unit *unit, const Vec2i &pos, const UnitType *ut, bool isMorph, bool threaded) { - assert(unit != NULL); - if(unit == NULL) { - throw megaglest_runtime_error("ut == NULL"); - } - - bool canPutInCell = true; - Field field=ut->getField(); - for(int i = 0; i < ut->getSize(); ++i) { - for(int j = 0; j < ut->getSize(); ++j) { - Vec2i currPos= pos + Vec2i(i, j); - assert(isInside(currPos)); - if(isInside(currPos) == false) { - throw megaglest_runtime_error("isInside(currPos) == false"); + if (selection == NULL) { + throw megaglest_runtime_error("selection == NULL"); } - if( ut->hasCellMap() == false || ut->getCellMapCell(i, j, unit->getModelFacing())) { - if(getCell(currPos)->getUnit(field) != NULL && - getCell(currPos)->getUnit(field) != unit) { - -// TT: is this ok ? - // If unit tries to move into a cell where another unit resides - // cancel the move command - if(unit->getCurrSkill() != NULL && - unit->getCurrSkill()->getClass() == scMove) { - canPutInCell = false; - //unit->setCurrSkill(scStop); - //unit->finishCommand(); - - //SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] POSSIBLE ERROR [getCell(currPos)->getUnit(unit->getCurrField()) != NULL] currPos [%s] unit [%s] cell unit [%s]\n", - // __FILE__,__FUNCTION__,__LINE__, - // currPos.getString().c_str(), - // unit->toString().c_str(), - // getCell(currPos)->getUnit(unit->getCurrField())->toString().c_str()); - } -//TT: Nonsens? -// else { -// // If the unit trying to move into the cell is not in the moving state -// // it is likely being created or morphed so we will will log the error -// canPutInCell = false; -// // throw megaglest_runtime_error("getCell(currPos)->getUnit(unit->getCurrField()) != NULL"); -// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] ERROR [getCell(currPos)->getUnit(unit->getCurrField()) != NULL] currPos [%s] unit [%s] cell unit [%s]\n", -// __FILE__,__FUNCTION__,__LINE__, -// currPos.getString().c_str(), -// unit->toString().c_str(), -// getCell(currPos)->getUnit(unit->getCurrField())->toString().c_str()); -// } - } - - - if(getCell(currPos)->getUnit(field) == NULL || - getCell(currPos)->getUnit(field) == unit) { - if(isMorph) { - // unit is beeing morphed to another unit with maybe other field. - getCell(currPos)->setUnit(field, unit); - canPutInCell = false; - } - if(canPutInCell == true) { - getCell(currPos)->setUnit(unit->getCurrField(), unit); - } - } - else if(canPutInCell == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Trying to move unit [%d - %s] into occupied cell [%s] and field = %d, unit already in cell [%d - %s] ",unit->getId(),unit->getType()->getName(false).c_str(),pos.getString().c_str(),field,getCell(currPos)->getUnit(field)->getId(),getCell(currPos)->getUnit(field)->getType()->getName(false).c_str()); - throw megaglest_runtime_error(szBuf); + for (int i = 0; i < selection->getCount(); ++i) { + if (selection->getUnit(i) == NULL) { + throw megaglest_runtime_error("selection == NULL || selection->getUnit(i) == NULL"); } + total = total + selection->getUnit(i)->getPosNotThreadSafe(); } - else if(ut->hasCellMap() == true && - ut->getAllowEmptyCellMap() == true && - ut->hasEmptyCellMap() == true) { - getCell(currPos)->setUnitWithEmptyCellMap(unit->getCurrField(), unit); - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] currPos = %s unit = %s\n", - // __FILE__,__FUNCTION__,__LINE__, - // currPos.getString().c_str(), - // unit->toString().c_str()); - } + return Vec2i(total.x / selection->getCount(), total.y / selection->getCount()); } - } - if(canPutInCell == true) { - unit->setPos(pos, false, threaded); - } -} -//removes a unit from cells -void Map::clearUnitCells(Unit *unit, const Vec2i &pos, bool ignoreSkill) { - assert(unit != NULL); - if(unit == NULL) { - throw megaglest_runtime_error("unit == NULL"); - } + Vec2i Map::computeDestPos(const Vec2i &refUnitPos, const Vec2i &unitPos, + const Vec2i &commandPos) const { + Vec2i pos; + // no more random needed + // Vec2i posDiff = unitPos - refUnitPos; + // + // if(abs(posDiff.x) >= 3){ + // posDiff.x = posDiff.x % 3; + // } + // + // if(abs(posDiff.y) >= 3){ + // posDiff.y = posDiff.y % 3; + // } - const UnitType *ut= unit->getType(); - Field currentField=unit->getCurrField(); - - if(ignoreSkill==false && - unit->getCurrSkill() != NULL && - unit->getCurrSkill()->getClass() == scMorph && - unit->getMorphFieldsBlocked() == true) { - Command *command= unit->getCurrCommand(); - const MorphCommandType *mct= static_cast(command->getCommandType()); - if(unit->getType()->getSize()<=mct->getMorphUnit()->getSize()){ - ut=mct->getMorphUnit(); - currentField=ut->getField(); - unit->setMorphFieldsBlocked(false); + pos = commandPos; //+ posDiff; + clampPos(pos); + return pos; } - } + //std::pair Map::getUnitDistanceToPos(const Unit *unit,Vec2i pos,const UnitType *ut) { + // if(unit == NULL) { + // throw megaglest_runtime_error("unit == NULL"); + // } + // + // std::pair result(-1,Vec2i(0)); + // //int unitId= unit->getId(); + // Vec2i unitPos= computeDestPos(unit->getPosNotThreadSafe(), unit->getPosNotThreadSafe(), pos); + // + // Vec2i start = pos - Vec2i(1); + // int unitTypeSize = 0; + // if(ut != NULL) { + // unitTypeSize = ut->getSize(); + // } + // Vec2i end = pos + Vec2i(unitTypeSize); + // + // for(int i = start.x; i <= end.x; ++i) { + // for(int j = start.y; j <= end.y; ++j){ + // Vec2i testPos(i,j); + // + // if(ut == NULL || isInUnitTypeCells(ut, pos,testPos) == false) { + // float distance = unitPos.dist(testPos); + // if(result.first < 0 || result.first > distance) { + // result.first = distance; + // result.second = testPos; + // } + // } + // } + // } + // + // return result; + //} - for(int i=0; igetSize(); ++i){ - for(int j=0; jgetSize(); ++j){ - Vec2i currPos= pos + Vec2i(i, j); - assert(isInside(currPos)); - if(isInside(currPos) == false) { - throw megaglest_runtime_error("isInside(currPos) == false"); + const Unit * Map::findClosestUnitToPos(const Selection *selection, Vec2i originalBuildPos, + const UnitType *ut) const { + const Unit *closestUnit = NULL; + Vec2i refPos = computeRefPos(selection); + + Vec2i pos = originalBuildPos; + + float bestRange = -1; + + Vec2i start = pos - Vec2i(1); + int unitTypeSize = 0; + if (ut != NULL) { + unitTypeSize = ut->getSize(); } + Vec2i end = pos + Vec2i(unitTypeSize); - if(ut->hasCellMap() == false || ut->getCellMapCell(i, j, unit->getModelFacing())) { - // This seems to be a bad assert since you can clear the cell - // for many reasons including a unit dieing. + for (int i = 0; i < selection->getCount(); ++i) { + const Unit *unit = selection->getUnit(i); + //int unitId= unit->getId(); + Vec2i unitBuilderPos = computeDestPos(refPos, unit->getPosNotThreadSafe(), pos); - //assert(getCell(currPos)->getUnit(unit->getCurrField()) == unit || getCell(currPos)->getUnit(unit->getCurrField()) == NULL); - //if(getCell(currPos)->getUnit(unit->getCurrField()) != unit && getCell(currPos)->getUnit(unit->getCurrField()) != NULL) { - // throw megaglest_runtime_error("getCell(currPos)->getUnit(unit->getCurrField()) != unit"); - //SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] ERROR [getCell(currPos)->getUnit(unit->getCurrField()) != unit] currPos [%s] unit [%s] cell unit [%s]\n", - // __FILE__,__FUNCTION__,__LINE__, - // currPos.getString().c_str(), - // unit->toString().c_str(), - // (getCell(currPos)->getUnit(unit->getCurrField()) != NULL ? getCell(currPos)->getUnit(unit->getCurrField())->toString().c_str() : "NULL")); - //} - - // Only clear the cell if its the unit we expect to clear out of it - if(getCell(currPos)->getUnit(currentField) == unit) { - getCell(currPos)->setUnit(currentField, NULL); - } - } - else if(ut->hasCellMap() == true && - ut->getAllowEmptyCellMap() == true && - ut->hasEmptyCellMap() == true) { - getCell(currPos)->setUnitWithEmptyCellMap(currentField, NULL); - - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] currPos = %s unit = %s\n", - // __FILE__,__FUNCTION__,__LINE__, - // currPos.getString().c_str(), - // unit->toString().c_str()); - } - } - } -} - -// ==================== misc ==================== - -//return if unit is next to pos -bool Map::isNextTo(const Vec2i &pos, const Unit *unit) const { - - for(int i=-1; i<=1; ++i) { - for(int j=-1; j<=1; ++j) { - if(isInside(pos.x+i, pos.y+j) && isInsideSurface(toSurfCoords(Vec2i(pos.x+i, pos.y+j)))) { - if(getCell(pos.x+i, pos.y+j)->getUnit(fLand) == unit) { - return true; - } - else if(getCell(pos.x+i, pos.y+j)->getUnitWithEmptyCellMap(fLand) == unit) { - return true; - } - } - } - } - return false; -} - -// Check if a unit is next to another particular unit. -bool Map::isNextTo(const Unit *unit1, const Unit *unit2) const { - Vec2i pos = unit1->getPosNotThreadSafe(); - const UnitType *ut = unit1->getType(); - for (int y=-1; y < ut->getSize()+1; ++y) { - for (int x=-1; x < ut->getSize()+1; ++x) { - Vec2i cellPos = pos + Vec2i(x, y); - if(isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) { - // Check if unit 2 is at that position, on land or air. - if(getCell(cellPos)->getUnit(fLand) == unit2 || getCell(cellPos)->getUnit(fAir) == unit2) { - return true; - } - else if(getCell(cellPos)->getUnitWithEmptyCellMap(fLand) == unit2 || getCell(cellPos)->getUnitWithEmptyCellMap(fAir) == unit2) { - return true; - } - } - } - } - - return false; -} - -//return if unit is next to pos -bool Map::isNextTo(const Vec2i &pos, const Vec2i &nextToPos) const { - - for(int i=-1; i<=1; ++i) { - for(int j=-1; j<=1; ++j) { - if(isInside(pos.x+i, pos.y+j) && isInsideSurface(toSurfCoords(Vec2i(pos.x+i, pos.y+j)))) { - if(getCell(pos.x+i, pos.y+j) == getCell(nextToPos.x,nextToPos.y)) { - return true; - } - } - } - } - return false; -} - -void Map::clampPos(Vec2i &pos) const{ - if(pos.x<0){ - pos.x=0; - } - if(pos.y<0){ - pos.y=0; - } - if(pos.x>=w){ - pos.x=w-1; - } - if(pos.y>=h){ - pos.y=h-1; - } -} - -void Map::prepareTerrain(const Unit *unit) { - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - - flatternTerrain(unit); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - computeNormals(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - computeInterpolatedHeights(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); -} - -// ==================== PRIVATE ==================== - -// ==================== compute ==================== - -void Map::flatternTerrain(const Unit *unit){ - float refHeight= getSurfaceCell(toSurfCoords(unit->getCenteredPos()))->getHeight(); - for(int i=-1; i<=unit->getType()->getSize(); ++i){ - for(int j=-1; j<=unit->getType()->getSize(); ++j){ - Vec2i pos= unit->getPosNotThreadSafe()+Vec2i(i, j); - if(isInside(pos) && isInsideSurface(toSurfCoords(pos))) { - Cell *c= getCell(pos); - SurfaceCell *sc= getSurfaceCell(toSurfCoords(pos)); - //we change height if pos is inside world, if its free or ocupied by the currenty building - if(sc->getObject() == NULL && (c->getUnit(fLand)==NULL || c->getUnit(fLand)==unit)) { - sc->setHeight(refHeight,true); - } - } - } - } -} - -//compute normals -void Map::computeNormals(){ - //compute center normals - for(int i=1; isetNormal( - getSurfaceCell(i, j)->getVertex().normal(getSurfaceCell(i, j-1)->getVertex(), - getSurfaceCell(i+1, j)->getVertex(), - getSurfaceCell(i, j+1)->getVertex(), - getSurfaceCell(i-1, j)->getVertex())); - } - } -} - -void Map::computeInterpolatedHeights(){ - - for(int i=0; isetHeight(getSurfaceCell(toSurfCoords(Vec2i(i, j)))->getHeight()); - } - } - - for(int i=1; isetHeight(getSurfaceCell(i, j)->getHeight()); - } - else if(k!=0 && l==0){ - getCell(i*cellScale+k, j*cellScale)->setHeight(( - getSurfaceCell(i, j)->getHeight()+ - getSurfaceCell(i+1, j)->getHeight())/2.f); - } - else if(l!=0 && k==0){ - getCell(i*cellScale, j*cellScale+l)->setHeight(( - getSurfaceCell(i, j)->getHeight()+ - getSurfaceCell(i, j+1)->getHeight())/2.f); - } - else{ - getCell(i*cellScale+k, j*cellScale+l)->setHeight(( - getSurfaceCell(i, j)->getHeight()+ - getSurfaceCell(i, j+1)->getHeight()+ - getSurfaceCell(i+1, j)->getHeight()+ - getSurfaceCell(i+1, j+1)->getHeight())/4.f); - } - } - } - } - } -} - -void Map::smoothSurface(Tileset *tileset) { - float *oldHeights = new float[getSurfaceCellArraySize()]; - //int arraySize=getSurfaceCellArraySize(); - - for (int i = 0; i < getSurfaceCellArraySize(); ++i) { - oldHeights[i] = surfaceCells[i].getHeight(); - } - - for (int i = 1; i < surfaceW - 1; ++i) { - for (int j = 1; j < surfaceH - 1; ++j) { - float height = 0.f; - float numUsedToSmooth = 0.f; - for (int k = -1; k <= 1; ++k) { - for (int l = -1; l <= 1; ++l) { -#ifdef USE_STREFLOP - if (cliffLevel<=0.1f || cliffLevel > streflop::fabs(static_cast(oldHeights[(j) * surfaceW + (i)] - - oldHeights[(j + k) * surfaceW + (i + l)]))) { -#else - if (cliffLevel<=0.1f || cliffLevel > fabs(oldHeights[(j) * surfaceW + (i)] - - oldHeights[(j + k) * surfaceW + (i + l)])) { -#endif - height += oldHeights[(j + k) * surfaceW + (i + l)]; - numUsedToSmooth++; - } - else { - // we have something which should not be smoothed! - // This is a cliff and must be textured -> set cliff texture - getSurfaceCell(i, j)->setSurfaceType(5); - //set invisible blocking object and replace resource objects - //and non blocking objects with invisible blocker too - Object *formerObject = - getSurfaceCell(i, j)->getObject(); - if (formerObject != NULL) { - if (formerObject->getWalkable() - || formerObject->getResource() != NULL) { - delete formerObject; - formerObject = NULL; + for (int i = start.x; i <= end.x; ++i) { + for (int j = start.y; j <= end.y; ++j) { + Vec2i testPos(i, j); + if (isInUnitTypeCells(ut, originalBuildPos, testPos) == false) { + float distance = unitBuilderPos.dist(testPos); + if (bestRange < 0 || bestRange > distance) { + bestRange = distance; + pos = testPos; + closestUnit = unit; } } - if (formerObject == NULL) { - Object *o = new Object(tileset->getObjectType(9), - getSurfaceCell(i, j)->getVertex(), - Vec2i(i,j)); - getSurfaceCell(i, j)->setObject(o); + } + } + } + + return closestUnit; + } + + Vec2i Map::findBestBuildApproach(const Unit *unit, Vec2i originalBuildPos, const UnitType *ut) const { + if (unit == NULL) { + throw megaglest_runtime_error("unit == NULL"); + } + if (ut == NULL) { + throw megaglest_runtime_error("ut == NULL"); + } + + Vec2i unitBuilderPos = unit->getPosNotThreadSafe(); + Vec2i pos = originalBuildPos; + + float bestRange = -1; + + Vec2i start = pos - Vec2i(unit->getType()->getSize()); + Vec2i end = pos + Vec2i(ut->getSize()); + + for (int i = start.x; i <= end.x; ++i) { + for (int j = start.y; j <= end.y; ++j) { + Vec2i testPos(i, j); + if (isInUnitTypeCells(ut, originalBuildPos, testPos) == false) { + float distance = unitBuilderPos.dist(testPos); + if (bestRange < 0 || bestRange > distance) { + // Check if the cell is occupied by another unit + if (isFreeCellOrHasUnit(testPos, unit->getType()->getField(), unit) == true) { + bestRange = distance; + pos = testPos; + } } } } } - height /= numUsedToSmooth; - if(maxMapHeightsetHeight(height); - Object *object = getSurfaceCell(i, j)->getObject(); - if (object != NULL) { - object->setHeight(height); - } + return pos; } - } - delete[] oldHeights; -} -void Map::computeNearSubmerged(){ - - for(int i=0; igetSize(); ++i) { + for (int j = -1; j <= ut->getSize(); ++j) { + Vec2i currPos = pos + Vec2i(i, j); + if (isInside(currPos) == true && isInsideSurface(toSurfCoords(currPos)) == true) { + //Cell *unitCell = getCell(currPos); + //if(unitCell == testCell) { + if (isNextTo(testPos, currPos) == true) { + return true; + } + } } } } - getSurfaceCell(i, j)->setNearSubmerged(anySubmerged); - } - } -} -void Map::computeCellColors(){ - for(int i=0; igetHeight()*1.5f, 1.f, 1.5f); - sc->setColor(Vec3f(1.0f, 1.0f, 1.0f)/factor); - } - else{ - sc->setColor(Vec3f(1.0f, 1.0f, 1.0f)); - } - } - } -} - -void Map::saveGame(XmlNode *rootNode) const { - std::map mapTagReplacements; - XmlNode *mapNode = rootNode->addChild("Map"); - -// string title; - mapNode->addAttribute("title",title, mapTagReplacements); -// float waterLevel; - mapNode->addAttribute("waterLevel",floatToStr(waterLevel,6), mapTagReplacements); -// float heightFactor; - mapNode->addAttribute("heightFactor",floatToStr(heightFactor,6), mapTagReplacements); -// float cliffLevel; - mapNode->addAttribute("cliffLevel",floatToStr(cliffLevel,6), mapTagReplacements); -// int cameraHeight; - mapNode->addAttribute("cameraHeight",intToStr(cameraHeight), mapTagReplacements); -// int w; - mapNode->addAttribute("w",intToStr(w), mapTagReplacements); -// int h; - mapNode->addAttribute("h",intToStr(h), mapTagReplacements); -// int surfaceW; - mapNode->addAttribute("surfaceW",intToStr(surfaceW), mapTagReplacements); -// int surfaceH; - mapNode->addAttribute("surfaceH",intToStr(surfaceH), mapTagReplacements); -// int maxPlayers; - mapNode->addAttribute("maxPlayers",intToStr(maxPlayers), mapTagReplacements); -// Cell *cells; - //printf("getCellArraySize() = %d\n",getCellArraySize()); -// for(unsigned int i = 0; i < getCellArraySize(); ++i) { -// Cell &cell = cells[i]; -// cell.saveGame(mapNode,i); -// } -// SurfaceCell *surfaceCells; - //printf("getSurfaceCellArraySize() = %d\n",getSurfaceCellArraySize()); - - string exploredList = ""; - string visibleList = ""; - - for(unsigned int i = 0; i < (unsigned int)getSurfaceCellArraySize(); ++i) { - SurfaceCell &surfaceCell = surfaceCells[i]; - - if(exploredList != "") { - exploredList += ","; - } - - for(unsigned int j = 0; j < (unsigned int)GameConstants::maxPlayers; ++j) { - if(j > 0) { - exploredList += "|"; - } - - exploredList += intToStr(surfaceCell.isExplored(j)); - } - - if(visibleList != "") { - visibleList += ","; - } - - for(unsigned int j = 0; j < (unsigned int)GameConstants::maxPlayers; ++j) { - if(j > 0) { - visibleList += "|"; - } - - visibleList += intToStr(surfaceCell.isVisible(j)); - } - - surfaceCell.saveGame(mapNode,i); - - if(i > 0 && i % 100 == 0) { - XmlNode *surfaceCellNode = mapNode->addChild("SurfaceCell"); - surfaceCellNode->addAttribute("batchIndex",intToStr(i), mapTagReplacements); - surfaceCellNode->addAttribute("exploredList",exploredList, mapTagReplacements); - surfaceCellNode->addAttribute("visibleList",visibleList, mapTagReplacements); - - exploredList = ""; - visibleList = ""; - } - } - - if(exploredList != "") { - XmlNode *surfaceCellNode = mapNode->addChild("SurfaceCell"); - surfaceCellNode->addAttribute("batchIndex",intToStr(getSurfaceCellArraySize()), mapTagReplacements); - surfaceCellNode->addAttribute("exploredList",exploredList, mapTagReplacements); - surfaceCellNode->addAttribute("visibleList",visibleList, mapTagReplacements); - } - -// Vec2i *startLocations; - for(unsigned int i = 0; i < (unsigned int)maxPlayers; ++i) { - XmlNode *startLocationsNode = mapNode->addChild("startLocations"); - startLocationsNode->addAttribute("location",startLocations[i].getString(), mapTagReplacements); - } -// Checksum checksumValue; -// mapNode->addAttribute("checksumValue",intToStr(checksumValue.getSum()), mapTagReplacements); -// float maxMapHeight; - mapNode->addAttribute("maxMapHeight",floatToStr(maxMapHeight,6), mapTagReplacements); -// string mapFile; - mapNode->addAttribute("mapFile",mapFile, mapTagReplacements); -} - -void Map::loadGame(const XmlNode *rootNode, World *world) { - const XmlNode *mapNode = rootNode->getChild("Map"); - - //description = gameSettingsNode->getAttribute("description")->getValue(); - -// for(unsigned int i = 0; i < getCellArraySize(); ++i) { -// Cell &cell = cells[i]; -// cell.saveGame(mapNode,i); -// } -// for(unsigned int i = 0; i < getSurfaceCellArraySize(); ++i) { -// SurfaceCell &surfaceCell = surfaceCells[i]; -// surfaceCell.saveGame(mapNode,i); -// } - -// printf("getCellArraySize() = %d\n",getCellArraySize()); -// for(unsigned int i = 0; i < getCellArraySize(); ++i) { -// Cell &cell = cells[i]; -// cell.loadGame(mapNode,i,world); -// } - -// printf("getSurfaceCellArraySize() = %d\n",getSurfaceCellArraySize()); - for(unsigned int i = 0; i < (unsigned int)getSurfaceCellArraySize(); ++i) { - SurfaceCell &surfaceCell = surfaceCells[i]; - surfaceCell.loadGame(mapNode,i,world); - } - - int surfaceCellIndexExplored = 0; - int surfaceCellIndexVisible = 0; - vector surfaceCellNodeList = mapNode->getChildList("SurfaceCell"); - for(unsigned int i = 0; i < surfaceCellNodeList.size(); ++i) { - XmlNode *surfaceCellNode = surfaceCellNodeList[i]; - - //XmlNode *surfaceCellNode = mapNode->getChild("SurfaceCell"); - string exploredList = surfaceCellNode->getAttribute("exploredList")->getValue(); - string visibleList = surfaceCellNode->getAttribute("visibleList")->getValue(); - //int batchIndex = surfaceCellNode->getAttribute("batchIndex")->getIntValue(); - - vector tokensExplored; - Tokenize(exploredList,tokensExplored,","); - - //printf("=====================\nNew batchIndex = %d batchsize = %d\n",batchIndex,tokensExplored.size()); - //for(unsigned int j = 0; j < tokensExplored.size(); ++j) { - //string valueList = tokensExplored[j]; - //printf("valueList [%s]\n",valueList.c_str()); - //} - for(unsigned int j = 0; j < tokensExplored.size(); ++j) { - string valueList = tokensExplored[j]; - - //int surfaceCellIndex = (i * tokensExplored.size()) + j; - //printf("Loading sc = %d batchIndex = %d\n",surfaceCellIndexExplored,batchIndex); - SurfaceCell &surfaceCell = surfaceCells[surfaceCellIndexExplored]; - - vector tokensExploredValue; - Tokenize(valueList,tokensExploredValue,"|"); - -// if(tokensExploredValue.size() != GameConstants::maxPlayers) { -// for(unsigned int k = 0; k < tokensExploredValue.size(); ++k) { -// string value = tokensExploredValue[k]; -// printf("k = %d [%s]\n",k,value.c_str()); -// } -// throw megaglest_runtime_error("tokensExploredValue.size() [" + intToStr(tokensExploredValue.size()) + "] != GameConstants::maxPlayers"); -// } - for(unsigned int k = 0; k < tokensExploredValue.size(); ++k) { - string value = tokensExploredValue[k]; - - surfaceCell.setExplored(k,strToInt(value) != 0); - - //if(surfaceCell.isExplored(k) == true) { - // printf("Setting cell at index: %d for team: %d to: %d [%s]\n",surfaceCellIndexExplored,k,surfaceCell.isExplored(k),value.c_str()); - //} - } - surfaceCellIndexExplored++; - } - - vector tokensVisible; - Tokenize(visibleList,tokensVisible,","); - for(unsigned int j = 0; j < tokensVisible.size(); ++j) { - string valueList = tokensVisible[j]; - - //int surfaceCellIndex = (i * tokensVisible.size()) + j; - SurfaceCell &surfaceCell = surfaceCells[surfaceCellIndexVisible]; - - vector tokensVisibleValue; - Tokenize(valueList,tokensVisibleValue,"|"); - -// if(tokensVisibleValue.size() != GameConstants::maxPlayers) { -// throw megaglest_runtime_error("tokensVisibleValue.size() [" + intToStr(tokensVisibleValue.size()) + "] != GameConstants::maxPlayers"); -// } - - for(unsigned int k = 0; k < tokensVisibleValue.size(); ++k) { - string value = tokensVisibleValue[k]; - - surfaceCell.setVisible(k,strToInt(value) != 0); - } - surfaceCellIndexVisible++; - } - } - - computeNormals(); - computeInterpolatedHeights(); -} - -// ===================================================== -// class PosCircularIterator -// ===================================================== - -PosCircularIterator::PosCircularIterator(const Map *map, const Vec2i ¢er, int radius){ - this->map= map; - this->radius= radius; - this->center= center; - pos= center - Vec2i(radius, radius); - pos.x-= 1; -} - -bool PosCircularIterator::next(){ - - //iterate while dont find a cell that is inside the world - //and at less or equal distance that the radius - do{ - pos.x++; - if(pos.x > center.x+radius){ - pos.x= center.x-radius; - pos.y++; - } - if(pos.y>center.y+radius) return false; - } + } + + // is testPos in the cells of unitType where unitType's position is pos + bool Map::isInUnitTypeCells(const UnitType *ut, const Vec2i &pos, + const Vec2i &testPos) const { + assert(ut != NULL); + if (ut == NULL) { + throw megaglest_runtime_error("ut == NULL"); + } + + if (isInside(testPos) && isInsideSurface(toSurfCoords(testPos))) { + Cell *testCell = getCell(testPos); + for (int i = 0; i < ut->getSize(); ++i) { + for (int j = 0; j < ut->getSize(); ++j) { + Vec2i currPos = pos + Vec2i(i, j); + if (isInside(currPos) && isInsideSurface(toSurfCoords(currPos))) { + Cell *unitCell = getCell(currPos); + if (unitCell == testCell) { + return true; + } + } + } + } + } + return false; + } + + //put a units into the cells + void Map::putUnitCells(Unit *unit, const Vec2i &pos, bool ignoreSkill, bool threaded) { + assert(unit != NULL); + if (unit == NULL) { + throw megaglest_runtime_error("ut == NULL"); + } + putUnitCellsPrivate(unit, pos, unit->getType(), false, threaded); + + // block space for morphing units + if (ignoreSkill == false && + unit->getCurrSkill() != NULL && + unit->getCurrSkill()->getClass() == scMorph) { + Command *command = unit->getCurrCommand(); + if (command != NULL && command->getCommandType()->commandTypeClass == ccMorph) { + const MorphCommandType *mct = static_cast(command->getCommandType()); + putUnitCellsPrivate(unit, pos, mct->getMorphUnit(), true, threaded); + unit->setMorphFieldsBlocked(true); + } + } + } + + void Map::putUnitCellsPrivate(Unit *unit, const Vec2i &pos, const UnitType *ut, bool isMorph, bool threaded) { + assert(unit != NULL); + if (unit == NULL) { + throw megaglest_runtime_error("ut == NULL"); + } + + bool canPutInCell = true; + Field field = ut->getField(); + for (int i = 0; i < ut->getSize(); ++i) { + for (int j = 0; j < ut->getSize(); ++j) { + Vec2i currPos = pos + Vec2i(i, j); + assert(isInside(currPos)); + if (isInside(currPos) == false) { + throw megaglest_runtime_error("isInside(currPos) == false"); + } + + if (ut->hasCellMap() == false || ut->getCellMapCell(i, j, unit->getModelFacing())) { + if (getCell(currPos)->getUnit(field) != NULL && + getCell(currPos)->getUnit(field) != unit) { + + // TT: is this ok ? + // If unit tries to move into a cell where another unit resides + // cancel the move command + if (unit->getCurrSkill() != NULL && + unit->getCurrSkill()->getClass() == scMove) { + canPutInCell = false; + //unit->setCurrSkill(scStop); + //unit->finishCommand(); + + //SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] POSSIBLE ERROR [getCell(currPos)->getUnit(unit->getCurrField()) != NULL] currPos [%s] unit [%s] cell unit [%s]\n", + // __FILE__,__FUNCTION__,__LINE__, + // currPos.getString().c_str(), + // unit->toString().c_str(), + // getCell(currPos)->getUnit(unit->getCurrField())->toString().c_str()); + } + //TT: Nonsens? + // else { + // // If the unit trying to move into the cell is not in the moving state + // // it is likely being created or morphed so we will will log the error + // canPutInCell = false; + // // throw megaglest_runtime_error("getCell(currPos)->getUnit(unit->getCurrField()) != NULL"); + // SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] ERROR [getCell(currPos)->getUnit(unit->getCurrField()) != NULL] currPos [%s] unit [%s] cell unit [%s]\n", + // __FILE__,__FUNCTION__,__LINE__, + // currPos.getString().c_str(), + // unit->toString().c_str(), + // getCell(currPos)->getUnit(unit->getCurrField())->toString().c_str()); + // } + } + + + if (getCell(currPos)->getUnit(field) == NULL || + getCell(currPos)->getUnit(field) == unit) { + if (isMorph) { + // unit is beeing morphed to another unit with maybe other field. + getCell(currPos)->setUnit(field, unit); + canPutInCell = false; + } + if (canPutInCell == true) { + getCell(currPos)->setUnit(unit->getCurrField(), unit); + } + } else if (canPutInCell == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Trying to move unit [%d - %s] into occupied cell [%s] and field = %d, unit already in cell [%d - %s] ", unit->getId(), unit->getType()->getName(false).c_str(), pos.getString().c_str(), field, getCell(currPos)->getUnit(field)->getId(), getCell(currPos)->getUnit(field)->getType()->getName(false).c_str()); + throw megaglest_runtime_error(szBuf); + } + } else if (ut->hasCellMap() == true && + ut->getAllowEmptyCellMap() == true && + ut->hasEmptyCellMap() == true) { + getCell(currPos)->setUnitWithEmptyCellMap(unit->getCurrField(), unit); + + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] currPos = %s unit = %s\n", + // __FILE__,__FUNCTION__,__LINE__, + // currPos.getString().c_str(), + // unit->toString().c_str()); + } + } + } + if (canPutInCell == true) { + unit->setPos(pos, false, threaded); + } + } + + //removes a unit from cells + void Map::clearUnitCells(Unit *unit, const Vec2i &pos, bool ignoreSkill) { + assert(unit != NULL); + if (unit == NULL) { + throw megaglest_runtime_error("unit == NULL"); + } + + const UnitType *ut = unit->getType(); + Field currentField = unit->getCurrField(); + + if (ignoreSkill == false && + unit->getCurrSkill() != NULL && + unit->getCurrSkill()->getClass() == scMorph && + unit->getMorphFieldsBlocked() == true) { + Command *command = unit->getCurrCommand(); + const MorphCommandType *mct = static_cast(command->getCommandType()); + if (unit->getType()->getSize() <= mct->getMorphUnit()->getSize()) { + ut = mct->getMorphUnit(); + currentField = ut->getField(); + unit->setMorphFieldsBlocked(false); + } + } + + + for (int i = 0; i < ut->getSize(); ++i) { + for (int j = 0; j < ut->getSize(); ++j) { + Vec2i currPos = pos + Vec2i(i, j); + assert(isInside(currPos)); + if (isInside(currPos) == false) { + throw megaglest_runtime_error("isInside(currPos) == false"); + } + + if (ut->hasCellMap() == false || ut->getCellMapCell(i, j, unit->getModelFacing())) { + // This seems to be a bad assert since you can clear the cell + // for many reasons including a unit dieing. + + //assert(getCell(currPos)->getUnit(unit->getCurrField()) == unit || getCell(currPos)->getUnit(unit->getCurrField()) == NULL); + //if(getCell(currPos)->getUnit(unit->getCurrField()) != unit && getCell(currPos)->getUnit(unit->getCurrField()) != NULL) { + // throw megaglest_runtime_error("getCell(currPos)->getUnit(unit->getCurrField()) != unit"); + //SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] ERROR [getCell(currPos)->getUnit(unit->getCurrField()) != unit] currPos [%s] unit [%s] cell unit [%s]\n", + // __FILE__,__FUNCTION__,__LINE__, + // currPos.getString().c_str(), + // unit->toString().c_str(), + // (getCell(currPos)->getUnit(unit->getCurrField()) != NULL ? getCell(currPos)->getUnit(unit->getCurrField())->toString().c_str() : "NULL")); + //} + + // Only clear the cell if its the unit we expect to clear out of it + if (getCell(currPos)->getUnit(currentField) == unit) { + getCell(currPos)->setUnit(currentField, NULL); + } + } else if (ut->hasCellMap() == true && + ut->getAllowEmptyCellMap() == true && + ut->hasEmptyCellMap() == true) { + getCell(currPos)->setUnitWithEmptyCellMap(currentField, NULL); + + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] currPos = %s unit = %s\n", + // __FILE__,__FUNCTION__,__LINE__, + // currPos.getString().c_str(), + // unit->toString().c_str()); + } + } + } + } + + // ==================== misc ==================== + + //return if unit is next to pos + bool Map::isNextTo(const Vec2i &pos, const Unit *unit) const { + + for (int i = -1; i <= 1; ++i) { + for (int j = -1; j <= 1; ++j) { + if (isInside(pos.x + i, pos.y + j) && isInsideSurface(toSurfCoords(Vec2i(pos.x + i, pos.y + j)))) { + if (getCell(pos.x + i, pos.y + j)->getUnit(fLand) == unit) { + return true; + } else if (getCell(pos.x + i, pos.y + j)->getUnitWithEmptyCellMap(fLand) == unit) { + return true; + } + } + } + } + return false; + } + + // Check if a unit is next to another particular unit. + bool Map::isNextTo(const Unit *unit1, const Unit *unit2) const { + Vec2i pos = unit1->getPosNotThreadSafe(); + const UnitType *ut = unit1->getType(); + for (int y = -1; y < ut->getSize() + 1; ++y) { + for (int x = -1; x < ut->getSize() + 1; ++x) { + Vec2i cellPos = pos + Vec2i(x, y); + if (isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) { + // Check if unit 2 is at that position, on land or air. + if (getCell(cellPos)->getUnit(fLand) == unit2 || getCell(cellPos)->getUnit(fAir) == unit2) { + return true; + } else if (getCell(cellPos)->getUnitWithEmptyCellMap(fLand) == unit2 || getCell(cellPos)->getUnitWithEmptyCellMap(fAir) == unit2) { + return true; + } + } + } + } + + return false; + } + + //return if unit is next to pos + bool Map::isNextTo(const Vec2i &pos, const Vec2i &nextToPos) const { + + for (int i = -1; i <= 1; ++i) { + for (int j = -1; j <= 1; ++j) { + if (isInside(pos.x + i, pos.y + j) && isInsideSurface(toSurfCoords(Vec2i(pos.x + i, pos.y + j)))) { + if (getCell(pos.x + i, pos.y + j) == getCell(nextToPos.x, nextToPos.y)) { + return true; + } + } + } + } + return false; + } + + void Map::clampPos(Vec2i &pos) const { + if (pos.x < 0) { + pos.x = 0; + } + if (pos.y < 0) { + pos.y = 0; + } + if (pos.x >= w) { + pos.x = w - 1; + } + if (pos.y >= h) { + pos.y = h - 1; + } + } + + void Map::prepareTerrain(const Unit *unit) { + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + + flatternTerrain(unit); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + computeNormals(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + computeInterpolatedHeights(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + } + + // ==================== PRIVATE ==================== + + // ==================== compute ==================== + + void Map::flatternTerrain(const Unit *unit) { + float refHeight = getSurfaceCell(toSurfCoords(unit->getCenteredPos()))->getHeight(); + for (int i = -1; i <= unit->getType()->getSize(); ++i) { + for (int j = -1; j <= unit->getType()->getSize(); ++j) { + Vec2i pos = unit->getPosNotThreadSafe() + Vec2i(i, j); + if (isInside(pos) && isInsideSurface(toSurfCoords(pos))) { + Cell *c = getCell(pos); + SurfaceCell *sc = getSurfaceCell(toSurfCoords(pos)); + //we change height if pos is inside world, if its free or ocupied by the currenty building + if (sc->getObject() == NULL && (c->getUnit(fLand) == NULL || c->getUnit(fLand) == unit)) { + sc->setHeight(refHeight, true); + } + } + } + } + } + + //compute normals + void Map::computeNormals() { + //compute center normals + for (int i = 1; i < surfaceW - 1; ++i) { + for (int j = 1; j < surfaceH - 1; ++j) { + getSurfaceCell(i, j)->setNormal( + getSurfaceCell(i, j)->getVertex().normal(getSurfaceCell(i, j - 1)->getVertex(), + getSurfaceCell(i + 1, j)->getVertex(), + getSurfaceCell(i, j + 1)->getVertex(), + getSurfaceCell(i - 1, j)->getVertex())); + } + } + } + + void Map::computeInterpolatedHeights() { + + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + getCell(i, j)->setHeight(getSurfaceCell(toSurfCoords(Vec2i(i, j)))->getHeight()); + } + } + + for (int i = 1; i < surfaceW - 1; ++i) { + for (int j = 1; j < surfaceH - 1; ++j) { + for (int k = 0; k < cellScale; ++k) { + for (int l = 0; l < cellScale; ++l) { + if (k == 0 && l == 0) { + getCell(i*cellScale, j*cellScale)->setHeight(getSurfaceCell(i, j)->getHeight()); + } else if (k != 0 && l == 0) { + getCell(i*cellScale + k, j*cellScale)->setHeight(( + getSurfaceCell(i, j)->getHeight() + + getSurfaceCell(i + 1, j)->getHeight()) / 2.f); + } else if (l != 0 && k == 0) { + getCell(i*cellScale, j*cellScale + l)->setHeight(( + getSurfaceCell(i, j)->getHeight() + + getSurfaceCell(i, j + 1)->getHeight()) / 2.f); + } else { + getCell(i*cellScale + k, j*cellScale + l)->setHeight(( + getSurfaceCell(i, j)->getHeight() + + getSurfaceCell(i, j + 1)->getHeight() + + getSurfaceCell(i + 1, j)->getHeight() + + getSurfaceCell(i + 1, j + 1)->getHeight()) / 4.f); + } + } + } + } + } + } + + void Map::smoothSurface(Tileset *tileset) { + float *oldHeights = new float[getSurfaceCellArraySize()]; + //int arraySize=getSurfaceCellArraySize(); + + for (int i = 0; i < getSurfaceCellArraySize(); ++i) { + oldHeights[i] = surfaceCells[i].getHeight(); + } + + for (int i = 1; i < surfaceW - 1; ++i) { + for (int j = 1; j < surfaceH - 1; ++j) { + float height = 0.f; + float numUsedToSmooth = 0.f; + for (int k = -1; k <= 1; ++k) { + for (int l = -1; l <= 1; ++l) { #ifdef USE_STREFLOP - while(streflop::floor(static_cast(pos.dist(center))) >= (radius+1) || !map->isInside(pos) || !map->isInsideSurface(map->toSurfCoords(pos)) ); + if (cliffLevel <= 0.1f || cliffLevel > streflop::fabs(static_cast(oldHeights[(j) * surfaceW + (i)] + - oldHeights[(j + k) * surfaceW + (i + l)]))) { #else - while(floor(pos.dist(center)) >= (radius+1) || !map->isInside(pos) || !map->isInsideSurface(map->toSurfCoords(pos)) ); + if (cliffLevel <= 0.1f || cliffLevel > fabs(oldHeights[(j) * surfaceW + (i)] + - oldHeights[(j + k) * surfaceW + (i + l)])) { +#endif + height += oldHeights[(j + k) * surfaceW + (i + l)]; + numUsedToSmooth++; + } else { + // we have something which should not be smoothed! + // This is a cliff and must be textured -> set cliff texture + getSurfaceCell(i, j)->setSurfaceType(5); + //set invisible blocking object and replace resource objects + //and non blocking objects with invisible blocker too + Object *formerObject = + getSurfaceCell(i, j)->getObject(); + if (formerObject != NULL) { + if (formerObject->getWalkable() + || formerObject->getResource() != NULL) { + delete formerObject; + formerObject = NULL; + } + } + if (formerObject == NULL) { + Object *o = new Object(tileset->getObjectType(9), + getSurfaceCell(i, j)->getVertex(), + Vec2i(i, j)); + getSurfaceCell(i, j)->setObject(o); + } + } + } + } + + height /= numUsedToSmooth; + if (maxMapHeight < height) { + maxMapHeight = height; + } + + getSurfaceCell(i, j)->setHeight(height); + Object *object = getSurfaceCell(i, j)->getObject(); + if (object != NULL) { + object->setHeight(height); + } + } + } + delete[] oldHeights; + } + + void Map::computeNearSubmerged() { + + for (int i = 0; i < surfaceW - 1; ++i) { + for (int j = 0; j < surfaceH - 1; ++j) { + bool anySubmerged = false; + for (int k = -1; k <= 2; ++k) { + for (int l = -1; l <= 2; ++l) { + Vec2i pos = Vec2i(i + k, j + l); + if (isInsideSurface(pos) && isInsideSurface(toSurfCoords(pos))) { + if (getSubmerged(getSurfaceCell(pos))) + anySubmerged = true; + } + } + } + getSurfaceCell(i, j)->setNearSubmerged(anySubmerged); + } + } + } + + void Map::computeCellColors() { + for (int i = 0; i < surfaceW; ++i) { + for (int j = 0; j < surfaceH; ++j) { + SurfaceCell *sc = getSurfaceCell(i, j); + if (getDeepSubmerged(sc)) { + float factor = clamp(waterLevel - sc->getHeight()*1.5f, 1.f, 1.5f); + sc->setColor(Vec3f(1.0f, 1.0f, 1.0f) / factor); + } else { + sc->setColor(Vec3f(1.0f, 1.0f, 1.0f)); + } + } + } + } + + void Map::saveGame(XmlNode *rootNode) const { + std::map mapTagReplacements; + XmlNode *mapNode = rootNode->addChild("Map"); + + // string title; + mapNode->addAttribute("title", title, mapTagReplacements); + // float waterLevel; + mapNode->addAttribute("waterLevel", floatToStr(waterLevel, 6), mapTagReplacements); + // float heightFactor; + mapNode->addAttribute("heightFactor", floatToStr(heightFactor, 6), mapTagReplacements); + // float cliffLevel; + mapNode->addAttribute("cliffLevel", floatToStr(cliffLevel, 6), mapTagReplacements); + // int cameraHeight; + mapNode->addAttribute("cameraHeight", intToStr(cameraHeight), mapTagReplacements); + // int w; + mapNode->addAttribute("w", intToStr(w), mapTagReplacements); + // int h; + mapNode->addAttribute("h", intToStr(h), mapTagReplacements); + // int surfaceW; + mapNode->addAttribute("surfaceW", intToStr(surfaceW), mapTagReplacements); + // int surfaceH; + mapNode->addAttribute("surfaceH", intToStr(surfaceH), mapTagReplacements); + // int maxPlayers; + mapNode->addAttribute("maxPlayers", intToStr(maxPlayers), mapTagReplacements); + // Cell *cells; + //printf("getCellArraySize() = %d\n",getCellArraySize()); + // for(unsigned int i = 0; i < getCellArraySize(); ++i) { + // Cell &cell = cells[i]; + // cell.saveGame(mapNode,i); + // } + // SurfaceCell *surfaceCells; + //printf("getSurfaceCellArraySize() = %d\n",getSurfaceCellArraySize()); + + string exploredList = ""; + string visibleList = ""; + + for (unsigned int i = 0; i < (unsigned int) getSurfaceCellArraySize(); ++i) { + SurfaceCell &surfaceCell = surfaceCells[i]; + + if (exploredList != "") { + exploredList += ","; + } + + for (unsigned int j = 0; j < (unsigned int) GameConstants::maxPlayers; ++j) { + if (j > 0) { + exploredList += "|"; + } + + exploredList += intToStr(surfaceCell.isExplored(j)); + } + + if (visibleList != "") { + visibleList += ","; + } + + for (unsigned int j = 0; j < (unsigned int) GameConstants::maxPlayers; ++j) { + if (j > 0) { + visibleList += "|"; + } + + visibleList += intToStr(surfaceCell.isVisible(j)); + } + + surfaceCell.saveGame(mapNode, i); + + if (i > 0 && i % 100 == 0) { + XmlNode *surfaceCellNode = mapNode->addChild("SurfaceCell"); + surfaceCellNode->addAttribute("batchIndex", intToStr(i), mapTagReplacements); + surfaceCellNode->addAttribute("exploredList", exploredList, mapTagReplacements); + surfaceCellNode->addAttribute("visibleList", visibleList, mapTagReplacements); + + exploredList = ""; + visibleList = ""; + } + } + + if (exploredList != "") { + XmlNode *surfaceCellNode = mapNode->addChild("SurfaceCell"); + surfaceCellNode->addAttribute("batchIndex", intToStr(getSurfaceCellArraySize()), mapTagReplacements); + surfaceCellNode->addAttribute("exploredList", exploredList, mapTagReplacements); + surfaceCellNode->addAttribute("visibleList", visibleList, mapTagReplacements); + } + + // Vec2i *startLocations; + for (unsigned int i = 0; i < (unsigned int) maxPlayers; ++i) { + XmlNode *startLocationsNode = mapNode->addChild("startLocations"); + startLocationsNode->addAttribute("location", startLocations[i].getString(), mapTagReplacements); + } + // Checksum checksumValue; + // mapNode->addAttribute("checksumValue",intToStr(checksumValue.getSum()), mapTagReplacements); + // float maxMapHeight; + mapNode->addAttribute("maxMapHeight", floatToStr(maxMapHeight, 6), mapTagReplacements); + // string mapFile; + mapNode->addAttribute("mapFile", mapFile, mapTagReplacements); + } + + void Map::loadGame(const XmlNode *rootNode, World *world) { + const XmlNode *mapNode = rootNode->getChild("Map"); + + //description = gameSettingsNode->getAttribute("description")->getValue(); + + // for(unsigned int i = 0; i < getCellArraySize(); ++i) { + // Cell &cell = cells[i]; + // cell.saveGame(mapNode,i); + // } + // for(unsigned int i = 0; i < getSurfaceCellArraySize(); ++i) { + // SurfaceCell &surfaceCell = surfaceCells[i]; + // surfaceCell.saveGame(mapNode,i); + // } + + // printf("getCellArraySize() = %d\n",getCellArraySize()); + // for(unsigned int i = 0; i < getCellArraySize(); ++i) { + // Cell &cell = cells[i]; + // cell.loadGame(mapNode,i,world); + // } + + // printf("getSurfaceCellArraySize() = %d\n",getSurfaceCellArraySize()); + for (unsigned int i = 0; i < (unsigned int) getSurfaceCellArraySize(); ++i) { + SurfaceCell &surfaceCell = surfaceCells[i]; + surfaceCell.loadGame(mapNode, i, world); + } + + int surfaceCellIndexExplored = 0; + int surfaceCellIndexVisible = 0; + vector surfaceCellNodeList = mapNode->getChildList("SurfaceCell"); + for (unsigned int i = 0; i < surfaceCellNodeList.size(); ++i) { + XmlNode *surfaceCellNode = surfaceCellNodeList[i]; + + //XmlNode *surfaceCellNode = mapNode->getChild("SurfaceCell"); + string exploredList = surfaceCellNode->getAttribute("exploredList")->getValue(); + string visibleList = surfaceCellNode->getAttribute("visibleList")->getValue(); + //int batchIndex = surfaceCellNode->getAttribute("batchIndex")->getIntValue(); + + vector tokensExplored; + Tokenize(exploredList, tokensExplored, ","); + + //printf("=====================\nNew batchIndex = %d batchsize = %d\n",batchIndex,tokensExplored.size()); + //for(unsigned int j = 0; j < tokensExplored.size(); ++j) { + //string valueList = tokensExplored[j]; + //printf("valueList [%s]\n",valueList.c_str()); + //} + for (unsigned int j = 0; j < tokensExplored.size(); ++j) { + string valueList = tokensExplored[j]; + + //int surfaceCellIndex = (i * tokensExplored.size()) + j; + //printf("Loading sc = %d batchIndex = %d\n",surfaceCellIndexExplored,batchIndex); + SurfaceCell &surfaceCell = surfaceCells[surfaceCellIndexExplored]; + + vector tokensExploredValue; + Tokenize(valueList, tokensExploredValue, "|"); + + // if(tokensExploredValue.size() != GameConstants::maxPlayers) { + // for(unsigned int k = 0; k < tokensExploredValue.size(); ++k) { + // string value = tokensExploredValue[k]; + // printf("k = %d [%s]\n",k,value.c_str()); + // } + // throw megaglest_runtime_error("tokensExploredValue.size() [" + intToStr(tokensExploredValue.size()) + "] != GameConstants::maxPlayers"); + // } + for (unsigned int k = 0; k < tokensExploredValue.size(); ++k) { + string value = tokensExploredValue[k]; + + surfaceCell.setExplored(k, strToInt(value) != 0); + + //if(surfaceCell.isExplored(k) == true) { + // printf("Setting cell at index: %d for team: %d to: %d [%s]\n",surfaceCellIndexExplored,k,surfaceCell.isExplored(k),value.c_str()); + //} + } + surfaceCellIndexExplored++; + } + + vector tokensVisible; + Tokenize(visibleList, tokensVisible, ","); + for (unsigned int j = 0; j < tokensVisible.size(); ++j) { + string valueList = tokensVisible[j]; + + //int surfaceCellIndex = (i * tokensVisible.size()) + j; + SurfaceCell &surfaceCell = surfaceCells[surfaceCellIndexVisible]; + + vector tokensVisibleValue; + Tokenize(valueList, tokensVisibleValue, "|"); + + // if(tokensVisibleValue.size() != GameConstants::maxPlayers) { + // throw megaglest_runtime_error("tokensVisibleValue.size() [" + intToStr(tokensVisibleValue.size()) + "] != GameConstants::maxPlayers"); + // } + + for (unsigned int k = 0; k < tokensVisibleValue.size(); ++k) { + string value = tokensVisibleValue[k]; + + surfaceCell.setVisible(k, strToInt(value) != 0); + } + surfaceCellIndexVisible++; + } + } + + computeNormals(); + computeInterpolatedHeights(); + } + + // ===================================================== + // class PosCircularIterator + // ===================================================== + + PosCircularIterator::PosCircularIterator(const Map *map, const Vec2i ¢er, int radius) { + this->map = map; + this->radius = radius; + this->center = center; + pos = center - Vec2i(radius, radius); + pos.x -= 1; + } + + bool PosCircularIterator::next() { + + //iterate while dont find a cell that is inside the world + //and at less or equal distance that the radius + do { + pos.x++; + if (pos.x > center.x + radius) { + pos.x = center.x - radius; + pos.y++; + } + if (pos.y > center.y + radius) + return false; + } +#ifdef USE_STREFLOP + while (streflop::floor(static_cast(pos.dist(center))) >= (radius + 1) || !map->isInside(pos) || !map->isInsideSurface(map->toSurfCoords(pos))); +#else + while (floor(pos.dist(center)) >= (radius + 1) || !map->isInside(pos) || !map->isInsideSurface(map->toSurfCoords(pos))); #endif - return true; -} - -const Vec2i &PosCircularIterator::getPos(){ - return pos; -} - - -// ===================================================== -// class PosQuadIterator -// ===================================================== - -PosQuadIterator::PosQuadIterator(const Map *map,const Quad2i &quad, int step) { - this->map = map; - - this->quad= quad; - this->boundingRect= quad.computeBoundingRect(); - this->step= step; - pos= boundingRect.p[0]; - --pos.x; - pos.x= (pos.x/step)*step; - pos.y= (pos.y/step)*step; - //map->clampPos(pos); -} - -bool PosQuadIterator::next() { - - do { - pos.x += step; - if(pos.x > boundingRect.p[1].x) { - pos.x = (boundingRect.p[0].x / step) * step; - pos.y += step; - } - if(pos.y > boundingRect.p[1].y) { - return false; + return true; } - //printf("pos [%s] boundingRect.p[0] [%s] boundingRect.p[1] [%s]\n",pos.getString().c_str(),boundingRect.p[0].getString().c_str(),boundingRect.p[1].getString().c_str()); - } - while(!quad.isInside(pos)); + const Vec2i &PosCircularIterator::getPos() { + return pos; + } - return true; -} -//void PosQuadIterator::skipX() { -// pos.x+= step; -//} + // ===================================================== + // class PosQuadIterator + // ===================================================== -const Vec2i &PosQuadIterator::getPos(){ - return pos; -} + PosQuadIterator::PosQuadIterator(const Map *map, const Quad2i &quad, int step) { + this->map = map; -}}//end namespace + this->quad = quad; + this->boundingRect = quad.computeBoundingRect(); + this->step = step; + pos = boundingRect.p[0]; + --pos.x; + pos.x = (pos.x / step)*step; + pos.y = (pos.y / step)*step; + //map->clampPos(pos); + } + + bool PosQuadIterator::next() { + + do { + pos.x += step; + if (pos.x > boundingRect.p[1].x) { + pos.x = (boundingRect.p[0].x / step) * step; + pos.y += step; + } + if (pos.y > boundingRect.p[1].y) { + return false; + } + + //printf("pos [%s] boundingRect.p[0] [%s] boundingRect.p[1] [%s]\n",pos.getString().c_str(),boundingRect.p[0].getString().c_str(),boundingRect.p[1].getString().c_str()); + } while (!quad.isInside(pos)); + + return true; + } + + //void PosQuadIterator::skipX() { + // pos.x+= step; + //} + + const Vec2i &PosQuadIterator::getPos() { + return pos; + } + + } + }//end namespace diff --git a/source/glest_game/world/map.h b/source/glest_game/world/map.h index 73e936245..c82ab5f9c 100644 --- a/source/glest_game/world/map.h +++ b/source/glest_game/world/map.h @@ -24,8 +24,8 @@ #define _GLEST_GAME_MAP_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include "vec.h" @@ -42,536 +42,639 @@ #include "leak_dumper.h" -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -using Shared::Graphics::Vec4f; -using Shared::Graphics::Quad2i; -using Shared::Graphics::Rect2i; -using Shared::Graphics::Vec4f; -using Shared::Graphics::Vec2f; -using Shared::Graphics::Vec2i; -using Shared::Graphics::Texture2D; + using Shared::Graphics::Vec4f; + using Shared::Graphics::Quad2i; + using Shared::Graphics::Rect2i; + using Shared::Graphics::Vec4f; + using Shared::Graphics::Vec2f; + using Shared::Graphics::Vec2i; + using Shared::Graphics::Texture2D; -class Tileset; -class Unit; -class Resource; -class TechTree; -class GameSettings; -class World; + class Tileset; + class Unit; + class Resource; + class TechTree; + class GameSettings; + class World; -// ===================================================== -// class Cell -// -/// A map cell that holds info about units present on it -// ===================================================== + // ===================================================== + // class Cell + // + /// A map cell that holds info about units present on it + // ===================================================== -class Cell { -private: - Unit *units[fieldCount]; //units on this cell - Unit *unitsWithEmptyCellMap[fieldCount]; //units with an empty cellmap on this cell - float height; + class Cell { + private: + Unit * units[fieldCount]; //units on this cell + Unit *unitsWithEmptyCellMap[fieldCount]; //units with an empty cellmap on this cell + float height; -private: - Cell(Cell&); - void operator=(Cell&); + private: + Cell(Cell&); + void operator=(Cell&); -public: - Cell(); + public: + Cell(); - //get - inline Unit *getUnit(int field) const { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} return units[field];} - inline Unit *getUnitWithEmptyCellMap(int field) const { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} return unitsWithEmptyCellMap[field];} - inline float getHeight() const {return truncateDecimal(height,6);} - - inline void setUnit(int field, Unit *unit) { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} units[field]= unit;} - inline void setUnitWithEmptyCellMap(int field, Unit *unit) { if(field >= fieldCount) { throw megaglest_runtime_error("Invalid field value" + intToStr(field));} unitsWithEmptyCellMap[field]= unit;} - inline void setHeight(float height) {this->height = truncateDecimal(height,6);} - - inline bool isFree(Field field) const { - Unit *unit = getUnit(field); - bool result = (unit == NULL || unit->isPutrefacting()); - - if(result == false) { - //printf("[%s] Line: %d returning false, unit id = %d [%s]\n",__FUNCTION__,__LINE__,getUnit(field)->getId(),getUnit(field)->getType()->getName().c_str()); - } - - return result; - } - - inline bool isFreeOrMightBeFreeSoon(Vec2i originPos, Vec2i cellPos, Field field) const { - Unit *unit = getUnit(field); - bool result = (unit == NULL || unit->isPutrefacting()); - - if(result == false) { - if(originPos.dist(cellPos) > 5 && unit->getType()->isMobile() == true) { - result = true; + //get + inline Unit *getUnit(int field) const { + if (field >= fieldCount) { + throw megaglest_runtime_error("Invalid field value" + intToStr(field)); + } return units[field]; + } + inline Unit *getUnitWithEmptyCellMap(int field) const { + if (field >= fieldCount) { + throw megaglest_runtime_error("Invalid field value" + intToStr(field)); + } return unitsWithEmptyCellMap[field]; + } + inline float getHeight() const { + return truncateDecimal(height, 6); } - //printf("[%s] Line: %d returning false, unit id = %d [%s]\n",__FUNCTION__,__LINE__,getUnit(field)->getId(),getUnit(field)->getType()->getName().c_str()); - } - - return result; - } - - void saveGame(XmlNode *rootNode,int index) const; - void loadGame(const XmlNode *rootNode, int index, World *world); -}; - -// ===================================================== -// class SurfaceCell -// -// A heightmap cell, each surface cell is composed by more than one Cell -// ===================================================== - -class SurfaceCell { -private: - //geometry - Vec3f vertex; - Vec3f normal; - Vec3f color; - - //tex coords - Vec2f fowTexCoord; //tex coords for TEXTURE1 when multitexturing and fogOfWar - Vec2f surfTexCoord; //tex coords for TEXTURE0 - - //surface - int surfaceType; - const Texture2D *surfaceTexture; - - //object & resource - Object *object; - - //visibility - bool visible[GameConstants::maxPlayers + GameConstants::specialFactions]; - bool explored[GameConstants::maxPlayers + GameConstants::specialFactions]; - - //cache - bool nearSubmerged; - bool cellChangedFromOriginalMapLoad; - -public: - SurfaceCell(); - ~SurfaceCell(); - - void end(); //to kill particles - //get - inline const Vec3f &getVertex() const {return vertex;} - inline float getHeight() const {return vertex.y;} - inline const Vec3f &getColor() const {return color;} - inline const Vec3f &getNormal() const {return normal;} - inline int getSurfaceType() const {return surfaceType;} - inline const Texture2D *getSurfaceTexture() const {return surfaceTexture;} - inline Object *getObject() const {return object;} - inline Resource *getResource() const {return object==NULL? NULL: object->getResource();} - inline const Vec2f &getFowTexCoord() const {return fowTexCoord;} - inline const Vec2f &getSurfTexCoord() const {return surfTexCoord;} - inline bool getNearSubmerged() const {return nearSubmerged;} - - inline bool isVisible(int teamIndex) const {return visible[teamIndex];} - inline bool isExplored(int teamIndex) const {return explored[teamIndex];} - string isVisibleString() const; - string isExploredString() const; - - //set - inline void setVertex(const Vec3f &vertex) {this->vertex= vertex;} - inline void setHeight(float height, bool cellChangedFromOriginalMapLoadValue=false); - inline void setNormal(const Vec3f &normal) {this->normal= normal;} - inline void setColor(const Vec3f &color) {this->color= color;} - inline void setSurfaceType(int surfaceType) {this->surfaceType= surfaceType;} - inline void setSurfaceTexture(const Texture2D *st) {this->surfaceTexture= st;} - inline void setObject(Object *object) {this->object= object;} - inline void setFowTexCoord(const Vec2f &ftc) {this->fowTexCoord= ftc;} - inline void setSurfTexCoord(const Vec2f &stc) {this->surfTexCoord= stc;} - void setExplored(int teamIndex, bool explored); - void setVisible(int teamIndex, bool visible); - inline void setNearSubmerged(bool nearSubmerged) {this->nearSubmerged= nearSubmerged;} - - //misc - void deleteResource(); - bool decAmount(int value); - inline bool isFree() const { - bool result = (object==NULL || object->getWalkable()); - - if(result == false) { - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - } - return result; - } - bool getCellChangedFromOriginalMapLoad() const { return cellChangedFromOriginalMapLoad; } - - void saveGame(XmlNode *rootNode,int index) const; - void loadGame(const XmlNode *rootNode, int index, World *world); -}; - - -// ===================================================== -// class Map -// -/// Represents the game map (and loads it from a gbm file) -// ===================================================== - -class FastAINodeCache { -public: - explicit FastAINodeCache(Unit *unit) { - this->unit = unit; - } - Unit *unit; - std::map > cachedCanMoveSoonList; -}; - -class Map { -public: - static const int cellScale; //number of cells per surfaceCell - static const int mapScale; //horizontal scale of surface - -private: - string title; - float waterLevel; - float heightFactor; - float cliffLevel; - int cameraHeight; - int w; - int h; - int surfaceW; - int surfaceH; - int surfaceSize; - - int hardMaxPlayers; // the max players hard-coded into a map - int maxPlayers; - Cell *cells; - SurfaceCell *surfaceCells; - Vec2i *startLocations; - Checksum checksumValue; - float maxMapHeight; - string mapFile; - -private: - Map(Map&); - void operator=(Map&); - -public: - Map(); - ~Map(); - void end(); //to kill particles - Checksum * getChecksumValue() { return &checksumValue; } - - void init(Tileset *tileset); - Checksum load(const string &path, TechTree *techTree, Tileset *tileset); - - //get - inline Cell *getCell(int x, int y, bool errorOnInvalid=true) const { - int arrayIndex = y * w + x; - if(arrayIndex < 0 || arrayIndex >= getCellArraySize()) { - if(errorOnInvalid == false) { - return NULL; + inline void setUnit(int field, Unit *unit) { + if (field >= fieldCount) { + throw megaglest_runtime_error("Invalid field value" + intToStr(field)); + } units[field] = unit; } - //abort(); - throw megaglest_runtime_error("arrayIndex >= getCellArraySize(), arrayIndex = " + intToStr(arrayIndex) + " w = " + intToStr(w) + " h = " + intToStr(h)); - } - else if(cells == NULL) { - if(errorOnInvalid == false) { - return NULL; + inline void setUnitWithEmptyCellMap(int field, Unit *unit) { + if (field >= fieldCount) { + throw megaglest_runtime_error("Invalid field value" + intToStr(field)); + } unitsWithEmptyCellMap[field] = unit; + } + inline void setHeight(float height) { + this->height = truncateDecimal(height, 6); } - throw megaglest_runtime_error("cells == NULL"); - } + inline bool isFree(Field field) const { + Unit *unit = getUnit(field); + bool result = (unit == NULL || unit->isPutrefacting()); - return &cells[arrayIndex]; - } - inline Cell *getCell(const Vec2i &pos) const { - return getCell(pos.x, pos.y); - } - - inline int getCellArraySize() const { - return (w * h); - } - inline int getSurfaceCellArraySize() const { - //return (surfaceW * surfaceH); - return surfaceSize; - } - inline SurfaceCell *getSurfaceCell(int sx, int sy) const { - int arrayIndex = sy * surfaceW + sx; - if(arrayIndex < 0 || arrayIndex >= getSurfaceCellArraySize()) { - throw megaglest_runtime_error("arrayIndex >= getSurfaceCellArraySize(), arrayIndex = " + intToStr(arrayIndex) + - " surfaceW = " + intToStr(surfaceW) + " surfaceH = " + intToStr(surfaceH) + - " sx: " + intToStr(sx) + " sy: " + intToStr(sy)); - } - else if(surfaceCells == NULL) { - throw megaglest_runtime_error("surfaceCells == NULL"); - } - return &surfaceCells[arrayIndex]; - } - inline SurfaceCell *getSurfaceCell(const Vec2i &sPos) const { - return getSurfaceCell(sPos.x, sPos.y); - } - - inline int getW() const {return w;} - inline int getH() const {return h;} - inline int getSurfaceW() const {return surfaceW;} - inline int getSurfaceH() const {return surfaceH;} - inline int getMaxPlayers() const {return maxPlayers;} - inline float getHeightFactor() const {return truncateDecimal(heightFactor,6);} - inline float getWaterLevel() const {return truncateDecimal(waterLevel,6);} - inline float getCliffLevel() const {return truncateDecimal(cliffLevel,6);} - inline int getCameraHeight() const {return cameraHeight;} - inline float getMaxMapHeight() const {return truncateDecimal(maxMapHeight,6);} - Vec2i getStartLocation(int locationIndex) const; - inline bool getSubmerged(const SurfaceCell *sc) const {return sc->getHeight()getHeight()getHeight()getHeight()=0 && y>=0 && x=0 && sy>=0 && sx > > > > *lookupCache=NULL) const; - bool canMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2,std::map > > > *lookupCache=NULL) const; - void putUnitCells(Unit *unit, const Vec2i &pos,bool ignoreSkill = false, bool threaded = false); - void clearUnitCells(Unit *unit, const Vec2i &pos,bool ignoreSkill = false); - - Vec2i computeRefPos(const Selection *selection) const; - Vec2i computeDestPos( const Vec2i &refUnitPos, const Vec2i &unitPos, - const Vec2i &commandPos) const; - const Unit * findClosestUnitToPos(const Selection *selection, Vec2i originalBuildPos, - const UnitType *ut) const; - bool isInUnitTypeCells(const UnitType *ut, const Vec2i &pos,const Vec2i &testPos) const; - bool isNextToUnitTypeCells(const UnitType *ut, const Vec2i &pos,const Vec2i &testPos) const; - Vec2i findBestBuildApproach(const Unit *unit, Vec2i originalBuildPos,const UnitType *ut) const; - //std::pair getUnitDistanceToPos(const Unit *unit,Vec2i pos,const UnitType *ut); - - //misc - bool isNextTo(const Vec2i &pos, const Unit *unit) const; - bool isNextTo(const Vec2i &pos, const Vec2i &nextToPos) const; - bool isNextTo(const Unit *unit1, const Unit *unit2) const; - void clampPos(Vec2i &pos) const; - - void prepareTerrain(const Unit *unit); - void flatternTerrain(const Unit *unit); - void computeNormals(); - void computeInterpolatedHeights(); - - //static - inline static Vec2i toSurfCoords(const Vec2i &unitPos) {return unitPos / cellScale;} - inline static Vec2i toUnitCoords(const Vec2i &surfPos) {return surfPos * cellScale;} - - inline bool isFreeCellOrMightBeFreeSoon(Vec2i originPos, const Vec2i &pos, Field field) const { - return - isInside(pos) && - isInsideSurface(toSurfCoords(pos)) && - getCell(pos)->isFreeOrMightBeFreeSoon(originPos,pos,field) && - (field==fAir || getSurfaceCell(toSurfCoords(pos))->isFree()) && - (field!=fLand || getDeepSubmerged(getCell(pos)) == false); - } - - inline bool isAproxFreeCellOrMightBeFreeSoon(Vec2i originPos,const Vec2i &pos, Field field, int teamIndex) const { - if(isInside(pos) && isInsideSurface(toSurfCoords(pos))) { - const SurfaceCell *sc= getSurfaceCell(toSurfCoords(pos)); - - if(sc->isVisible(teamIndex)) { - return isFreeCellOrMightBeFreeSoon(originPos, pos, field); - } - else if(sc->isExplored(teamIndex)) { - return field==fLand? sc->isFree() && !getDeepSubmerged(getCell(pos)): true; - } - else { - return true; - } - } - - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - return false; - } - - //checks if a unit can move from between 2 cells using only visible cells (for pathfinding) - inline bool aproxCanMoveSoon(Unit *unit, const Vec2i &pos1, const Vec2i &pos2) const { - if(isInside(pos1) == false || isInsideSurface(toSurfCoords(pos1)) == false || - isInside(pos2) == false || isInsideSurface(toSurfCoords(pos2)) == false) { - - //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && - SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In aproxCanMoveSoon() return false"); - if(Thread::isCurrentThreadMainThread() == false) { - unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); - } - else { - unit->logSynchData(__FILE__,__LINE__,szBuf); - } - } - - return false; - } - - if(unit == NULL) { - throw megaglest_runtime_error("unit == NULL"); - } - - int size= unit->getType()->getSize(); - int teamIndex= unit->getTeam(); - Field field= unit->getCurrField(); - - //single cell units - if(size == 1) { - bool tryPosResult = isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(),pos2, field, teamIndex); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && - SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { - string extraInfo = (string("tryPosResult = ") + (tryPosResult ? string("true") : string("false"))); - const SurfaceCell *sc= getSurfaceCell(toSurfCoords(pos2)); - if(sc->isVisible(teamIndex)) { - bool testCond = isFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(), pos2, field); - extraInfo += (string("isFreeCellOrMightBeFreeSoon = ") + (testCond ? string("true") : string("false"))); - } - else if(sc->isExplored(teamIndex)) { - bool testCond = field==fLand? sc->isFree() && !getDeepSubmerged(getCell(pos2)): true; - extraInfo += (string("field==fLand = ") + (testCond ? string("true") : string("false"))); + if (result == false) { + //printf("[%s] Line: %d returning false, unit id = %d [%s]\n",__FUNCTION__,__LINE__,getUnit(field)->getId(),getUnit(field)->getType()->getName().c_str()); } - char szBuf[8096]=""; - snprintf(szBuf,8096,"In aproxCanMoveSoon() pos2 = %s extraInfo = %s %s %s",pos2.getString().c_str(),extraInfo.c_str(),sc->isVisibleString().c_str(),sc->isExploredString().c_str()); - if(Thread::isCurrentThreadMainThread() == false) { - unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); - } - else { - unit->logSynchData(__FILE__,__LINE__,szBuf); - } + return result; } - if(tryPosResult == false) { - return false; - } - if(pos1.x != pos2.x && pos1.y != pos2.y) { - Vec2i tryPos = Vec2i(pos1.x, pos2.y); - bool tryPosResult = isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(),tryPos, field, teamIndex); + inline bool isFreeOrMightBeFreeSoon(Vec2i originPos, Vec2i cellPos, Field field) const { + Unit *unit = getUnit(field); + bool result = (unit == NULL || unit->isPutrefacting()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && - SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { - string extraInfo = (string("tryPosResult = ") + (tryPosResult ? string("true") : string("false"))); - const SurfaceCell *sc= getSurfaceCell(toSurfCoords(tryPos)); - if(sc->isVisible(teamIndex)) { - bool testCond = isFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(), tryPos, field); - extraInfo += (string("isFreeCellOrMightBeFreeSoon = ") + (testCond ? string("true") : string("false"))); - } - else if(sc->isExplored(teamIndex)) { - bool testCond = field==fLand? sc->isFree() && !getDeepSubmerged(getCell(tryPos)): true; - extraInfo += (string("field==fLand = ") + (testCond ? string("true") : string("false"))); + if (result == false) { + if (originPos.dist(cellPos) > 5 && unit->getType()->isMobile() == true) { + result = true; } - char szBuf[8096]=""; - snprintf(szBuf,8096,"In aproxCanMoveSoon() extraInfo = %s",extraInfo.c_str()); - if(Thread::isCurrentThreadMainThread() == false) { - unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); + //printf("[%s] Line: %d returning false, unit id = %d [%s]\n",__FUNCTION__,__LINE__,getUnit(field)->getId(),getUnit(field)->getType()->getName().c_str()); + } + + return result; + } + + void saveGame(XmlNode *rootNode, int index) const; + void loadGame(const XmlNode *rootNode, int index, World *world); + }; + + // ===================================================== + // class SurfaceCell + // + // A heightmap cell, each surface cell is composed by more than one Cell + // ===================================================== + + class SurfaceCell { + private: + //geometry + Vec3f vertex; + Vec3f normal; + Vec3f color; + + //tex coords + Vec2f fowTexCoord; //tex coords for TEXTURE1 when multitexturing and fogOfWar + Vec2f surfTexCoord; //tex coords for TEXTURE0 + + //surface + int surfaceType; + const Texture2D *surfaceTexture; + + //object & resource + Object *object; + + //visibility + bool visible[GameConstants::maxPlayers + GameConstants::specialFactions]; + bool explored[GameConstants::maxPlayers + GameConstants::specialFactions]; + + //cache + bool nearSubmerged; + bool cellChangedFromOriginalMapLoad; + + public: + SurfaceCell(); + ~SurfaceCell(); + + void end(); //to kill particles + //get + inline const Vec3f &getVertex() const { + return vertex; + } + inline float getHeight() const { + return vertex.y; + } + inline const Vec3f &getColor() const { + return color; + } + inline const Vec3f &getNormal() const { + return normal; + } + inline int getSurfaceType() const { + return surfaceType; + } + inline const Texture2D *getSurfaceTexture() const { + return surfaceTexture; + } + inline Object *getObject() const { + return object; + } + inline Resource *getResource() const { + return object == NULL ? NULL : object->getResource(); + } + inline const Vec2f &getFowTexCoord() const { + return fowTexCoord; + } + inline const Vec2f &getSurfTexCoord() const { + return surfTexCoord; + } + inline bool getNearSubmerged() const { + return nearSubmerged; + } + + inline bool isVisible(int teamIndex) const { + return visible[teamIndex]; + } + inline bool isExplored(int teamIndex) const { + return explored[teamIndex]; + } + string isVisibleString() const; + string isExploredString() const; + + //set + inline void setVertex(const Vec3f &vertex) { + this->vertex = vertex; + } + inline void setHeight(float height, bool cellChangedFromOriginalMapLoadValue = false); + inline void setNormal(const Vec3f &normal) { + this->normal = normal; + } + inline void setColor(const Vec3f &color) { + this->color = color; + } + inline void setSurfaceType(int surfaceType) { + this->surfaceType = surfaceType; + } + inline void setSurfaceTexture(const Texture2D *st) { + this->surfaceTexture = st; + } + inline void setObject(Object *object) { + this->object = object; + } + inline void setFowTexCoord(const Vec2f &ftc) { + this->fowTexCoord = ftc; + } + inline void setSurfTexCoord(const Vec2f &stc) { + this->surfTexCoord = stc; + } + void setExplored(int teamIndex, bool explored); + void setVisible(int teamIndex, bool visible); + inline void setNearSubmerged(bool nearSubmerged) { + this->nearSubmerged = nearSubmerged; + } + + //misc + void deleteResource(); + bool decAmount(int value); + inline bool isFree() const { + bool result = (object == NULL || object->getWalkable()); + + if (result == false) { + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + } + return result; + } + bool getCellChangedFromOriginalMapLoad() const { + return cellChangedFromOriginalMapLoad; + } + + void saveGame(XmlNode *rootNode, int index) const; + void loadGame(const XmlNode *rootNode, int index, World *world); + }; + + + // ===================================================== + // class Map + // + /// Represents the game map (and loads it from a gbm file) + // ===================================================== + + class FastAINodeCache { + public: + explicit FastAINodeCache(Unit *unit) { + this->unit = unit; + } + Unit *unit; + std::map > cachedCanMoveSoonList; + }; + + class Map { + public: + static const int cellScale; //number of cells per surfaceCell + static const int mapScale; //horizontal scale of surface + + private: + string title; + float waterLevel; + float heightFactor; + float cliffLevel; + int cameraHeight; + int w; + int h; + int surfaceW; + int surfaceH; + int surfaceSize; + + int hardMaxPlayers; // the max players hard-coded into a map + int maxPlayers; + Cell *cells; + SurfaceCell *surfaceCells; + Vec2i *startLocations; + Checksum checksumValue; + float maxMapHeight; + string mapFile; + + private: + Map(Map&); + void operator=(Map&); + + public: + Map(); + ~Map(); + void end(); //to kill particles + Checksum * getChecksumValue() { + return &checksumValue; + } + + void init(Tileset *tileset); + Checksum load(const string &path, TechTree *techTree, Tileset *tileset); + + //get + inline Cell *getCell(int x, int y, bool errorOnInvalid = true) const { + int arrayIndex = y * w + x; + if (arrayIndex < 0 || arrayIndex >= getCellArraySize()) { + if (errorOnInvalid == false) { + return NULL; } - else { - unit->logSynchData(__FILE__,__LINE__,szBuf); - } - } - - if(tryPosResult == false) { - return false; - } - - tryPos = Vec2i(pos2.x, pos1.y); - tryPosResult = isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(),tryPos, field, teamIndex); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && - SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { - string extraInfo = (string("tryPosResult = ") + (tryPosResult ? string("true") : string("false"))); - const SurfaceCell *sc= getSurfaceCell(toSurfCoords(tryPos)); - if(sc->isVisible(teamIndex)) { - bool testCond = isFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(), tryPos, field); - extraInfo += (string("isFreeCellOrMightBeFreeSoon = ") + (testCond ? string("true") : string("false"))); - } - else if(sc->isExplored(teamIndex)) { - bool testCond = field==fLand? sc->isFree() && !getDeepSubmerged(getCell(tryPos)): true; - extraInfo += (string("field==fLand = ") + (testCond ? string("true") : string("false"))); - } - - char szBuf[8096]=""; - snprintf(szBuf,8096,"In aproxCanMoveSoon() extraInfo = %s",extraInfo.c_str()); - if(Thread::isCurrentThreadMainThread() == false) { - unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); - } - else { - unit->logSynchData(__FILE__,__LINE__,szBuf); - } - } - - if(tryPosResult == false) { - - return false; - } - } - - bool isBadHarvestPos = false; - Command *command= unit->getCurrCommand(); - if(command != NULL) { - const HarvestCommandType *hct = dynamic_cast(command->getCommandType()); - if(hct != NULL && unit->isBadHarvestPos(pos2) == true) { - isBadHarvestPos = true; - } - } - - if(unit == NULL || isBadHarvestPos == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && - SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In aproxCanMoveSoon() return false"); - if(Thread::isCurrentThreadMainThread() == false) { - unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); - } - else { - unit->logSynchData(__FILE__,__LINE__,szBuf); + //abort(); + throw megaglest_runtime_error("arrayIndex >= getCellArraySize(), arrayIndex = " + intToStr(arrayIndex) + " w = " + intToStr(w) + " h = " + intToStr(h)); + } else if (cells == NULL) { + if (errorOnInvalid == false) { + return NULL; + } + + throw megaglest_runtime_error("cells == NULL"); + } + + return &cells[arrayIndex]; + } + inline Cell *getCell(const Vec2i &pos) const { + return getCell(pos.x, pos.y); + } + + inline int getCellArraySize() const { + return (w * h); + } + inline int getSurfaceCellArraySize() const { + //return (surfaceW * surfaceH); + return surfaceSize; + } + inline SurfaceCell *getSurfaceCell(int sx, int sy) const { + int arrayIndex = sy * surfaceW + sx; + if (arrayIndex < 0 || arrayIndex >= getSurfaceCellArraySize()) { + throw megaglest_runtime_error("arrayIndex >= getSurfaceCellArraySize(), arrayIndex = " + intToStr(arrayIndex) + + " surfaceW = " + intToStr(surfaceW) + " surfaceH = " + intToStr(surfaceH) + + " sx: " + intToStr(sx) + " sy: " + intToStr(sy)); + } else if (surfaceCells == NULL) { + throw megaglest_runtime_error("surfaceCells == NULL"); + } + return &surfaceCells[arrayIndex]; + } + inline SurfaceCell *getSurfaceCell(const Vec2i &sPos) const { + return getSurfaceCell(sPos.x, sPos.y); + } + + inline int getW() const { + return w; + } + inline int getH() const { + return h; + } + inline int getSurfaceW() const { + return surfaceW; + } + inline int getSurfaceH() const { + return surfaceH; + } + inline int getMaxPlayers() const { + return maxPlayers; + } + inline float getHeightFactor() const { + return truncateDecimal(heightFactor, 6); + } + inline float getWaterLevel() const { + return truncateDecimal(waterLevel, 6); + } + inline float getCliffLevel() const { + return truncateDecimal(cliffLevel, 6); + } + inline int getCameraHeight() const { + return cameraHeight; + } + inline float getMaxMapHeight() const { + return truncateDecimal(maxMapHeight, 6); + } + Vec2i getStartLocation(int locationIndex) const; + inline bool getSubmerged(const SurfaceCell *sc) const { + return sc->getHeight() < waterLevel; + } + inline bool getSubmerged(const Cell *c) const { + return c->getHeight() < waterLevel; + } + inline bool getDeepSubmerged(const SurfaceCell *sc) const { + return sc->getHeight() < waterLevel - (1.5f / heightFactor); + } + inline bool getDeepSubmerged(const Cell *c) const { + return c->getHeight() < waterLevel - (1.5f / heightFactor); + } + + //is + inline bool isInside(int x, int y) const { + return x >= 0 && y >= 0 && x < w && y < h; + } + inline bool isInside(const Vec2i &pos) const { + return isInside(pos.x, pos.y); + } + inline bool isInsideSurface(int sx, int sy) const { + return sx >= 0 && sy >= 0 && sx < surfaceW && sy < surfaceH; + } + inline bool isInsideSurface(const Vec2i &sPos) const { + return isInsideSurface(sPos.x, sPos.y); + } + bool isResourceNear(int frameIndex, const Vec2i &pos, const ResourceType *rt, Vec2i &resourcePos, int size, Unit *unit = NULL, bool fallbackToPeersHarvestingSameResource = false, Vec2i *resourceClickPos = NULL) const; + + //free cells + bool isFreeCell(const Vec2i &pos, Field field) const; + bool isFreeCellOrHasUnit(const Vec2i &pos, Field field, const Unit *unit) const; + bool isAproxFreeCell(const Vec2i &pos, Field field, int teamIndex) const; + bool isFreeCells(const Vec2i &pos, int size, Field field) const; + bool isFreeCellsOrHasUnit(const Vec2i &pos, int size, Field field, const Unit *unit) const; + bool isAproxFreeCells(const Vec2i &pos, int size, Field field, int teamIndex) const; + bool canMorph(const Vec2i &pos, const Unit *currentUnit, const UnitType *targetUnitType) const; + //bool canOccupy(const Vec2i &pos, Field field, const UnitType *ut, CardinalDir facing); + + //unit placement + bool aproxCanMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, std::map > > > > *lookupCache = NULL) const; + bool canMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, std::map > > > *lookupCache = NULL) const; + void putUnitCells(Unit *unit, const Vec2i &pos, bool ignoreSkill = false, bool threaded = false); + void clearUnitCells(Unit *unit, const Vec2i &pos, bool ignoreSkill = false); + + Vec2i computeRefPos(const Selection *selection) const; + Vec2i computeDestPos(const Vec2i &refUnitPos, const Vec2i &unitPos, + const Vec2i &commandPos) const; + const Unit * findClosestUnitToPos(const Selection *selection, Vec2i originalBuildPos, + const UnitType *ut) const; + bool isInUnitTypeCells(const UnitType *ut, const Vec2i &pos, const Vec2i &testPos) const; + bool isNextToUnitTypeCells(const UnitType *ut, const Vec2i &pos, const Vec2i &testPos) const; + Vec2i findBestBuildApproach(const Unit *unit, Vec2i originalBuildPos, const UnitType *ut) const; + //std::pair getUnitDistanceToPos(const Unit *unit,Vec2i pos,const UnitType *ut); + + //misc + bool isNextTo(const Vec2i &pos, const Unit *unit) const; + bool isNextTo(const Vec2i &pos, const Vec2i &nextToPos) const; + bool isNextTo(const Unit *unit1, const Unit *unit2) const; + void clampPos(Vec2i &pos) const; + + void prepareTerrain(const Unit *unit); + void flatternTerrain(const Unit *unit); + void computeNormals(); + void computeInterpolatedHeights(); + + //static + inline static Vec2i toSurfCoords(const Vec2i &unitPos) { + return unitPos / cellScale; + } + inline static Vec2i toUnitCoords(const Vec2i &surfPos) { + return surfPos * cellScale; + } + + inline bool isFreeCellOrMightBeFreeSoon(Vec2i originPos, const Vec2i &pos, Field field) const { + return + isInside(pos) && + isInsideSurface(toSurfCoords(pos)) && + getCell(pos)->isFreeOrMightBeFreeSoon(originPos, pos, field) && + (field == fAir || getSurfaceCell(toSurfCoords(pos))->isFree()) && + (field != fLand || getDeepSubmerged(getCell(pos)) == false); + } + + inline bool isAproxFreeCellOrMightBeFreeSoon(Vec2i originPos, const Vec2i &pos, Field field, int teamIndex) const { + if (isInside(pos) && isInsideSurface(toSurfCoords(pos))) { + const SurfaceCell *sc = getSurfaceCell(toSurfCoords(pos)); + + if (sc->isVisible(teamIndex)) { + return isFreeCellOrMightBeFreeSoon(originPos, pos, field); + } else if (sc->isExplored(teamIndex)) { + return field == fLand ? sc->isFree() && !getDeepSubmerged(getCell(pos)) : true; + } else { + return true; } } + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); return false; } - return true; - } - //multi cell units - else { - for(int i = pos2.x; i < pos2.x + size; ++i) { - for(int j = pos2.y; j < pos2.y + size; ++j) { + //checks if a unit can move from between 2 cells using only visible cells (for pathfinding) + inline bool aproxCanMoveSoon(Unit *unit, const Vec2i &pos1, const Vec2i &pos2) const { + if (isInside(pos1) == false || isInsideSurface(toSurfCoords(pos1)) == false || + isInside(pos2) == false || isInsideSurface(toSurfCoords(pos2)) == false) { - Vec2i cellPos = Vec2i(i,j); - if(isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) { - if(getCell(cellPos)->getUnit(unit->getCurrField()) != unit) { - if(isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(),cellPos, field, teamIndex) == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && - SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In aproxCanMoveSoon() return false"); - if(Thread::isCurrentThreadMainThread() == false) { - unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); + //printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In aproxCanMoveSoon() return false"); + if (Thread::isCurrentThreadMainThread() == false) { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + } + + return false; + } + + if (unit == NULL) { + throw megaglest_runtime_error("unit == NULL"); + } + + int size = unit->getType()->getSize(); + int teamIndex = unit->getTeam(); + Field field = unit->getCurrField(); + + //single cell units + if (size == 1) { + bool tryPosResult = isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(), pos2, field, teamIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { + string extraInfo = (string("tryPosResult = ") + (tryPosResult ? string("true") : string("false"))); + const SurfaceCell *sc = getSurfaceCell(toSurfCoords(pos2)); + if (sc->isVisible(teamIndex)) { + bool testCond = isFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(), pos2, field); + extraInfo += (string("isFreeCellOrMightBeFreeSoon = ") + (testCond ? string("true") : string("false"))); + } else if (sc->isExplored(teamIndex)) { + bool testCond = field == fLand ? sc->isFree() && !getDeepSubmerged(getCell(pos2)) : true; + extraInfo += (string("field==fLand = ") + (testCond ? string("true") : string("false"))); + } + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In aproxCanMoveSoon() pos2 = %s extraInfo = %s %s %s", pos2.getString().c_str(), extraInfo.c_str(), sc->isVisibleString().c_str(), sc->isExploredString().c_str()); + if (Thread::isCurrentThreadMainThread() == false) { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + } + + if (tryPosResult == false) { + return false; + } + if (pos1.x != pos2.x && pos1.y != pos2.y) { + Vec2i tryPos = Vec2i(pos1.x, pos2.y); + bool tryPosResult = isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(), tryPos, field, teamIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { + string extraInfo = (string("tryPosResult = ") + (tryPosResult ? string("true") : string("false"))); + const SurfaceCell *sc = getSurfaceCell(toSurfCoords(tryPos)); + if (sc->isVisible(teamIndex)) { + bool testCond = isFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(), tryPos, field); + extraInfo += (string("isFreeCellOrMightBeFreeSoon = ") + (testCond ? string("true") : string("false"))); + } else if (sc->isExplored(teamIndex)) { + bool testCond = field == fLand ? sc->isFree() && !getDeepSubmerged(getCell(tryPos)) : true; + extraInfo += (string("field==fLand = ") + (testCond ? string("true") : string("false"))); + } + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In aproxCanMoveSoon() extraInfo = %s", extraInfo.c_str()); + if (Thread::isCurrentThreadMainThread() == false) { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + } + + if (tryPosResult == false) { + return false; + } + + tryPos = Vec2i(pos2.x, pos1.y); + tryPosResult = isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(), tryPos, field, teamIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { + string extraInfo = (string("tryPosResult = ") + (tryPosResult ? string("true") : string("false"))); + const SurfaceCell *sc = getSurfaceCell(toSurfCoords(tryPos)); + if (sc->isVisible(teamIndex)) { + bool testCond = isFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(), tryPos, field); + extraInfo += (string("isFreeCellOrMightBeFreeSoon = ") + (testCond ? string("true") : string("false"))); + } else if (sc->isExplored(teamIndex)) { + bool testCond = field == fLand ? sc->isFree() && !getDeepSubmerged(getCell(tryPos)) : true; + extraInfo += (string("field==fLand = ") + (testCond ? string("true") : string("false"))); + } + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In aproxCanMoveSoon() extraInfo = %s", extraInfo.c_str()); + if (Thread::isCurrentThreadMainThread() == false) { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + } + + if (tryPosResult == false) { + + return false; + } + } + + bool isBadHarvestPos = false; + Command *command = unit->getCurrCommand(); + if (command != NULL) { + const HarvestCommandType *hct = dynamic_cast(command->getCommandType()); + if (hct != NULL && unit->isBadHarvestPos(pos2) == true) { + isBadHarvestPos = true; + } + } + + if (unit == NULL || isBadHarvestPos == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In aproxCanMoveSoon() return false"); + if (Thread::isCurrentThreadMainThread() == false) { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + } + + return false; + } + + return true; + } + //multi cell units + else { + for (int i = pos2.x; i < pos2.x + size; ++i) { + for (int j = pos2.y; j < pos2.y + size; ++j) { + + Vec2i cellPos = Vec2i(i, j); + if (isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) { + if (getCell(cellPos)->getUnit(unit->getCurrField()) != unit) { + if (isAproxFreeCellOrMightBeFreeSoon(unit->getPosNotThreadSafe(), cellPos, field, teamIndex) == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In aproxCanMoveSoon() return false"); + if (Thread::isCurrentThreadMainThread() == false) { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + } + + return false; } - else { - unit->logSynchData(__FILE__,__LINE__,szBuf); + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In aproxCanMoveSoon() return false"); + if (Thread::isCurrentThreadMainThread() == false) { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); } } @@ -579,103 +682,88 @@ public: } } } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && - SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In aproxCanMoveSoon() return false"); - if(Thread::isCurrentThreadMainThread() == false) { - unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); - } - else { - unit->logSynchData(__FILE__,__LINE__,szBuf); + + bool isBadHarvestPos = false; + Command *command = unit->getCurrCommand(); + if (command != NULL) { + const HarvestCommandType *hct = dynamic_cast(command->getCommandType()); + if (hct != NULL && unit->isBadHarvestPos(pos2) == true) { + isBadHarvestPos = true; + } + } + + if (isBadHarvestPos == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In aproxCanMoveSoon() return false"); + if (Thread::isCurrentThreadMainThread() == false) { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); } } return false; } + } + return true; } - bool isBadHarvestPos = false; - Command *command= unit->getCurrCommand(); - if(command != NULL) { - const HarvestCommandType *hct = dynamic_cast(command->getCommandType()); - if(hct != NULL && unit->isBadHarvestPos(pos2) == true) { - isBadHarvestPos = true; - } + string getMapFile() const { + return mapFile; } - if(isBadHarvestPos == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && - SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In aproxCanMoveSoon() return false"); - if(Thread::isCurrentThreadMainThread() == false) { - unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); - } - else { - unit->logSynchData(__FILE__,__LINE__,szBuf); - } - } + void saveGame(XmlNode *rootNode) const; + void loadGame(const XmlNode *rootNode, World *world); - return false; - } + private: + //compute + void smoothSurface(Tileset *tileset); + void computeNearSubmerged(); + void computeCellColors(); + void putUnitCellsPrivate(Unit *unit, const Vec2i &pos, const UnitType *ut, bool isMorph, bool threaded); + }; + + + // =============================== + // class PosCircularIterator + // =============================== + + class PosCircularIterator { + private: + Vec2i center; + int radius; + const Map *map; + Vec2i pos; + + public: + PosCircularIterator(const Map *map, const Vec2i ¢er, int radius); + bool next(); + const Vec2i &getPos(); + }; + + // =============================== + // class PosQuadIterator + // =============================== + + class PosQuadIterator { + private: + Quad2i quad; + Rect2i boundingRect; + Vec2i pos; + int step; + const Map *map; + + public: + PosQuadIterator(const Map *map, const Quad2i &quad, int step = 1); + bool next(); + //void skipX(); + const Vec2i &getPos(); + }; - } - return true; } - - string getMapFile() const { return mapFile; } - - void saveGame(XmlNode *rootNode) const; - void loadGame(const XmlNode *rootNode,World *world); - -private: - //compute - void smoothSurface(Tileset *tileset); - void computeNearSubmerged(); - void computeCellColors(); - void putUnitCellsPrivate(Unit *unit, const Vec2i &pos, const UnitType *ut, bool isMorph, bool threaded); -}; - - -// =============================== -// class PosCircularIterator -// =============================== - -class PosCircularIterator{ -private: - Vec2i center; - int radius; - const Map *map; - Vec2i pos; - -public: - PosCircularIterator(const Map *map, const Vec2i ¢er, int radius); - bool next(); - const Vec2i &getPos(); -}; - -// =============================== -// class PosQuadIterator -// =============================== - -class PosQuadIterator { -private: - Quad2i quad; - Rect2i boundingRect; - Vec2i pos; - int step; - const Map *map; - -public: - PosQuadIterator(const Map *map,const Quad2i &quad, int step=1); - bool next(); - //void skipX(); - const Vec2i &getPos(); -}; - -} } //end namespace +} //end namespace #endif diff --git a/source/glest_game/world/minimap.cpp b/source/glest_game/world/minimap.cpp index 8cc0e1a9d..f95d17141 100644 --- a/source/glest_game/world/minimap.cpp +++ b/source/glest_game/world/minimap.cpp @@ -23,306 +23,303 @@ using namespace Shared::Graphics; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class Minimap -// ===================================================== + // ===================================================== + // class Minimap + // ===================================================== -const float Minimap::exploredAlpha= 0.5f; + const float Minimap::exploredAlpha = 0.5f; -Minimap::Minimap() { - fowPixmap0= NULL; - fowPixmap1= NULL; - fowPixmap1_default=NULL; - fowPixmap0Copy = NULL; - fowPixmap1Copy = NULL; - fowPixmap1Copy_default = NULL; - fogOfWar= true; - gameSettings= NULL; - tex=NULL; - fowTex=NULL; -} + Minimap::Minimap() { + fowPixmap0 = NULL; + fowPixmap1 = NULL; + fowPixmap1_default = NULL; + fowPixmap0Copy = NULL; + fowPixmap1Copy = NULL; + fowPixmap1Copy_default = NULL; + fogOfWar = true; + gameSettings = NULL; + tex = NULL; + fowTex = NULL; + } -void Minimap::init(int w, int h, const World *world, bool fogOfWar) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - int scaledW= w/Map::cellScale; - int scaledH= h/Map::cellScale; - int potW = next2Power(scaledW); - int potH = next2Power(scaledH); + void Minimap::init(int w, int h, const World *world, bool fogOfWar) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + int scaledW = w / Map::cellScale; + int scaledH = h / Map::cellScale; + int potW = next2Power(scaledW); + int potH = next2Power(scaledH); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scaledW = %d, scaledH = %d, potW = %d, potH = %d\n",__FILE__,__FUNCTION__,__LINE__,scaledW,scaledH,potW,potH); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] scaledW = %d, scaledH = %d, potW = %d, potH = %d\n", __FILE__, __FUNCTION__, __LINE__, scaledW, scaledH, potW, potH); - this->fogOfWar = fogOfWar; - this->gameSettings = world->getGameSettings(); - Renderer &renderer= Renderer::getInstance(); + this->fogOfWar = fogOfWar; + this->gameSettings = world->getGameSettings(); + Renderer &renderer = Renderer::getInstance(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - //fow pixmaps - float f= 0.f; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + //fow pixmaps + float f = 0.f; - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - fowPixmap0 = new Pixmap2D(potW, potH, 1); - fowPixmap0Copy = new Pixmap2D(potW, potH, 1); - fowPixmap1 = new Pixmap2D(potW, potH, 1); - fowPixmap1_default = new Pixmap2D(potW, potH, 1); - fowPixmap1Copy = new Pixmap2D(potW, potH, 1); - fowPixmap1Copy_default = new Pixmap2D(potW, potH, 1); + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + fowPixmap0 = new Pixmap2D(potW, potH, 1); + fowPixmap0Copy = new Pixmap2D(potW, potH, 1); + fowPixmap1 = new Pixmap2D(potW, potH, 1); + fowPixmap1_default = new Pixmap2D(potW, potH, 1); + fowPixmap1Copy = new Pixmap2D(potW, potH, 1); + fowPixmap1Copy_default = new Pixmap2D(potW, potH, 1); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - fowPixmap0->setPixels(&f,1); - if((this->gameSettings->getFlagTypes1() & ft1_show_map_resources) == ft1_show_map_resources) { - f = 0.f; - fowPixmap1->setPixels(&f,1); - f = 0.5f; - for (int y=1; y < scaledH - 1; ++y) { - for (int x=1; x < scaledW - 1; ++x) { - fowPixmap1->setPixel(x, y, &f,1); + fowPixmap0->setPixels(&f, 1); + if ((this->gameSettings->getFlagTypes1() & ft1_show_map_resources) == ft1_show_map_resources) { + f = 0.f; + fowPixmap1->setPixels(&f, 1); + f = 0.5f; + for (int y = 1; y < scaledH - 1; ++y) { + for (int x = 1; x < scaledW - 1; ++x) { + fowPixmap1->setPixel(x, y, &f, 1); + } + } + } else { + fowPixmap1->setPixels(&f, 1); } } - } - else { - fowPixmap1->setPixels(&f,1); - } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - //fow tex - fowTex= renderer.newTexture2D(rsGame); - if(fowTex) { - fowTex->setMipmap(false); - fowTex->setPixmapInit(false); - fowTex->setFormat(Texture::fAlpha); + //fow tex + fowTex = renderer.newTexture2D(rsGame); + if (fowTex) { + fowTex->setMipmap(false); + fowTex->setPixmapInit(false); + fowTex->setFormat(Texture::fAlpha); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scaledW = %d, scaledH = %d, potW = %d, potH = %d\n",__FILE__,__FUNCTION__,__LINE__,scaledW,scaledH,potW,potH); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] scaledW = %d, scaledH = %d, potW = %d, potH = %d\n", __FILE__, __FUNCTION__, __LINE__, scaledW, scaledH, potW, potH); - fowTex->getPixmap()->init(potW, potH, 1); - fowTex->getPixmap()->setPixels(&f,1); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //tex - tex= renderer.newTexture2D(rsGame); - if(tex) { - tex->getPixmap()->init(scaledW, scaledH, 3); - tex->setMipmap(false); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - computeTexture(world); -} - -Minimap::~Minimap() { - Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingMiniMap","",true), true); - delete fowPixmap0; - fowPixmap0=NULL; - delete fowPixmap0Copy; - fowPixmap0Copy = NULL; - delete fowPixmap1; - fowPixmap1=NULL; - delete fowPixmap1_default; - fowPixmap1_default = NULL; - delete fowPixmap1Copy; - fowPixmap1Copy=NULL; - delete fowPixmap1Copy_default; - fowPixmap1Copy_default = NULL; -} - -// ==================== set ==================== - -void Minimap::incFowTextureAlphaSurface(const Vec2i sPos, float alpha, - bool isIncrementalUpdate) { - if(fowPixmap1) { - assert(sPos.x < fowPixmap1->getW() && sPos.y < fowPixmap1->getH()); - - if(fowPixmap1->getPixelf(sPos.x, sPos.y) < alpha){ - fowPixmap1->setPixel(sPos.x, sPos.y, alpha); - } - - if(fowPixmap1Copy != NULL && isIncrementalUpdate == true) { - if(fowPixmap1Copy->getPixelf(sPos.x, sPos.y) < alpha){ - fowPixmap1Copy->setPixel(sPos.x, sPos.y, alpha); + fowTex->getPixmap()->init(potW, potH, 1); + fowTex->getPixmap()->setPixels(&f, 1); } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //tex + tex = renderer.newTexture2D(rsGame); + if (tex) { + tex->getPixmap()->init(scaledW, scaledH, 3); + tex->setMipmap(false); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + computeTexture(world); } - } -} -void Minimap::copyFowTexAlphaSurface() { - if(fowPixmap1_default != NULL && fowPixmap1 != NULL) { - fowPixmap1_default->copy(fowPixmap1); - } - if(fowPixmap1Copy_default != NULL && fowPixmap1Copy != NULL) { - fowPixmap1Copy_default->copy(fowPixmap1Copy); - } -} -void Minimap::restoreFowTexAlphaSurface() { - if(fowPixmap1 != NULL && fowPixmap1_default != NULL) { - fowPixmap1->copy(fowPixmap1_default); - } - if(fowPixmap1Copy != NULL && fowPixmap1Copy_default != NULL) { - fowPixmap1Copy->copy(fowPixmap1Copy_default); - } -} + Minimap::~Minimap() { + Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingMiniMap", "", true), true); + delete fowPixmap0; + fowPixmap0 = NULL; + delete fowPixmap0Copy; + fowPixmap0Copy = NULL; + delete fowPixmap1; + fowPixmap1 = NULL; + delete fowPixmap1_default; + fowPixmap1_default = NULL; + delete fowPixmap1Copy; + fowPixmap1Copy = NULL; + delete fowPixmap1Copy_default; + fowPixmap1Copy_default = NULL; + } -void Minimap::setFogOfWar(bool value) { - fogOfWar = value; - resetFowTex(); -} + // ==================== set ==================== -void Minimap::copyFowTex() { - if(fowPixmap0Copy != NULL && fowPixmap0 != NULL) { - fowPixmap0Copy->copy(fowPixmap0); - } - if(fowPixmap1Copy != NULL && fowPixmap1 != NULL) { - fowPixmap1Copy->copy(fowPixmap1); - } -} -void Minimap::restoreFowTex() { - if(fowPixmap0 != NULL && fowPixmap0Copy != NULL) { - fowPixmap0->copy(fowPixmap0Copy); - } - if(fowPixmap1 != NULL && fowPixmap1Copy != NULL) { - fowPixmap1->copy(fowPixmap1Copy); - } -} + void Minimap::incFowTextureAlphaSurface(const Vec2i sPos, float alpha, + bool isIncrementalUpdate) { + if (fowPixmap1) { + assert(sPos.x < fowPixmap1->getW() && sPos.y < fowPixmap1->getH()); -void Minimap::resetFowTex() { - if(fowTex && fowPixmap0 && fowPixmap1) { - Pixmap2D *tmpPixmap= fowPixmap0; - fowPixmap0= fowPixmap1; - fowPixmap1= tmpPixmap; + if (fowPixmap1->getPixelf(sPos.x, sPos.y) < alpha) { + fowPixmap1->setPixel(sPos.x, sPos.y, alpha); + } - // Could turn off ONLY fog of war by setting below to false - bool overridefogOfWarValue = fogOfWar; - - for(int indexPixelWidth = 0; - indexPixelWidth < fowTex->getPixmap()->getW(); - ++indexPixelWidth){ - for(int indexPixelHeight = 0; - indexPixelHeight < fowTex->getPixmap()->getH(); - ++indexPixelHeight){ - if ((fogOfWar == false && overridefogOfWarValue == false)) { - //(gameSettings->getFlagTypes1() & ft1_show_map_resources) != ft1_show_map_resources) { - //printf("Line: %d\n",__LINE__); - - float p0 = fowPixmap0->getPixelf(indexPixelWidth, indexPixelHeight); - float p1 = fowPixmap1->getPixelf(indexPixelWidth, indexPixelHeight); - if (p0 > p1) { - fowPixmap1->setPixel(indexPixelWidth, indexPixelHeight, p0); - } - else { - fowPixmap1->setPixel(indexPixelWidth, indexPixelHeight, p1); + if (fowPixmap1Copy != NULL && isIncrementalUpdate == true) { + if (fowPixmap1Copy->getPixelf(sPos.x, sPos.y) < alpha) { + fowPixmap1Copy->setPixel(sPos.x, sPos.y, alpha); } } - else if((fogOfWar && overridefogOfWarValue) || - (gameSettings->getFlagTypes1() & ft1_show_map_resources) == ft1_show_map_resources) { - //printf("Line: %d\n",__LINE__); + } + } - float p0= fowPixmap0->getPixelf(indexPixelWidth, indexPixelHeight); - float p1= fowPixmap1->getPixelf(indexPixelWidth, indexPixelHeight); + void Minimap::copyFowTexAlphaSurface() { + if (fowPixmap1_default != NULL && fowPixmap1 != NULL) { + fowPixmap1_default->copy(fowPixmap1); + } + if (fowPixmap1Copy_default != NULL && fowPixmap1Copy != NULL) { + fowPixmap1Copy_default->copy(fowPixmap1Copy); + } + } + void Minimap::restoreFowTexAlphaSurface() { + if (fowPixmap1 != NULL && fowPixmap1_default != NULL) { + fowPixmap1->copy(fowPixmap1_default); + } + if (fowPixmap1Copy != NULL && fowPixmap1Copy_default != NULL) { + fowPixmap1Copy->copy(fowPixmap1Copy_default); + } + } - if(p1 > exploredAlpha) { - fowPixmap1->setPixel(indexPixelWidth, indexPixelHeight, exploredAlpha); - } - if(p0 > p1) { - fowPixmap1->setPixel(indexPixelWidth, indexPixelHeight, p0); + void Minimap::setFogOfWar(bool value) { + fogOfWar = value; + resetFowTex(); + } + + void Minimap::copyFowTex() { + if (fowPixmap0Copy != NULL && fowPixmap0 != NULL) { + fowPixmap0Copy->copy(fowPixmap0); + } + if (fowPixmap1Copy != NULL && fowPixmap1 != NULL) { + fowPixmap1Copy->copy(fowPixmap1); + } + } + void Minimap::restoreFowTex() { + if (fowPixmap0 != NULL && fowPixmap0Copy != NULL) { + fowPixmap0->copy(fowPixmap0Copy); + } + if (fowPixmap1 != NULL && fowPixmap1Copy != NULL) { + fowPixmap1->copy(fowPixmap1Copy); + } + } + + void Minimap::resetFowTex() { + if (fowTex && fowPixmap0 && fowPixmap1) { + Pixmap2D *tmpPixmap = fowPixmap0; + fowPixmap0 = fowPixmap1; + fowPixmap1 = tmpPixmap; + + // Could turn off ONLY fog of war by setting below to false + bool overridefogOfWarValue = fogOfWar; + + for (int indexPixelWidth = 0; + indexPixelWidth < fowTex->getPixmap()->getW(); + ++indexPixelWidth) { + for (int indexPixelHeight = 0; + indexPixelHeight < fowTex->getPixmap()->getH(); + ++indexPixelHeight) { + if ((fogOfWar == false && overridefogOfWarValue == false)) { + //(gameSettings->getFlagTypes1() & ft1_show_map_resources) != ft1_show_map_resources) { + //printf("Line: %d\n",__LINE__); + + float p0 = fowPixmap0->getPixelf(indexPixelWidth, indexPixelHeight); + float p1 = fowPixmap1->getPixelf(indexPixelWidth, indexPixelHeight); + if (p0 > p1) { + fowPixmap1->setPixel(indexPixelWidth, indexPixelHeight, p0); + } else { + fowPixmap1->setPixel(indexPixelWidth, indexPixelHeight, p1); + } + } else if ((fogOfWar && overridefogOfWarValue) || + (gameSettings->getFlagTypes1() & ft1_show_map_resources) == ft1_show_map_resources) { + //printf("Line: %d\n",__LINE__); + + float p0 = fowPixmap0->getPixelf(indexPixelWidth, indexPixelHeight); + float p1 = fowPixmap1->getPixelf(indexPixelWidth, indexPixelHeight); + + if (p1 > exploredAlpha) { + fowPixmap1->setPixel(indexPixelWidth, indexPixelHeight, exploredAlpha); + } + if (p0 > p1) { + fowPixmap1->setPixel(indexPixelWidth, indexPixelHeight, p0); + } + } else { + //printf("Line: %d\n",__LINE__); + fowPixmap1->setPixel(indexPixelWidth, indexPixelHeight, 1.f); + } } } - else { - //printf("Line: %d\n",__LINE__); - fowPixmap1->setPixel(indexPixelWidth, indexPixelHeight, 1.f); - } } } - } -} -void Minimap::updateFowTex(float t) { - if(fowTex && fowPixmap0 && fowPixmap1) { - for(int indexPixelWidth = 0; - indexPixelWidth < fowPixmap0->getW(); - ++indexPixelWidth){ - for(int indexPixelHeight = 0; - indexPixelHeight < fowPixmap0->getH(); - ++indexPixelHeight){ - float p1 = fowPixmap1->getPixelf(indexPixelWidth, indexPixelHeight); - float p2 = fowTex->getPixmap()->getPixelf(indexPixelWidth, indexPixelHeight); - if(p1 != p2) { - float p0 = fowPixmap0->getPixelf(indexPixelWidth, indexPixelHeight); - fowTex->getPixmap()->setPixel(indexPixelWidth, indexPixelHeight, p0+(t*(p1-p0))); - } - } - } - } -} - -// ==================== PRIVATE ==================== - -void Minimap::computeTexture(const World *world) { - - Vec3f color; - const Map *map= world->getMap(); - - if(tex) { - tex->getPixmap()->setPixels(Vec4f(1.f, 1.f, 1.f, 0.1f).ptr(),tex->getPixmap()->getComponents()); - - for(int j=0; jgetPixmap()->getH(); ++j){ - for(int i=0; igetPixmap()->getW(); ++i){ - SurfaceCell *sc= map->getSurfaceCell(i, j); - - if(sc->getObject()==NULL || sc->getObject()->getType()==NULL){ - const Pixmap2D *p= world->getTileset()->getSurfPixmap(sc->getSurfaceType(), 0); - color= p->getPixel3f(p->getW()/2, p->getH()/2); - color= color * static_cast(sc->getVertex().y/6.f); - - if(sc->getVertex().y<= world->getMap()->getWaterLevel()){ - color+= Vec3f(0.5f, 0.5f, 1.0f); + void Minimap::updateFowTex(float t) { + if (fowTex && fowPixmap0 && fowPixmap1) { + for (int indexPixelWidth = 0; + indexPixelWidth < fowPixmap0->getW(); + ++indexPixelWidth) { + for (int indexPixelHeight = 0; + indexPixelHeight < fowPixmap0->getH(); + ++indexPixelHeight) { + float p1 = fowPixmap1->getPixelf(indexPixelWidth, indexPixelHeight); + float p2 = fowTex->getPixmap()->getPixelf(indexPixelWidth, indexPixelHeight); + if (p1 != p2) { + float p0 = fowPixmap0->getPixelf(indexPixelWidth, indexPixelHeight); + fowTex->getPixmap()->setPixel(indexPixelWidth, indexPixelHeight, p0 + (t*(p1 - p0))); + } } - - if(color.x>1.f) color.x=1.f; - if(color.y>1.f) color.y=1.f; - if(color.z>1.f) color.z=1.f; } - else{ - color= sc->getObject()->getType()->getColor(); - } - tex->getPixmap()->setPixel(i, j, color); } } - } -} -void Minimap::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *minimapNode = rootNode->addChild("Minimap"); + // ==================== PRIVATE ==================== - if(fowPixmap1 != NULL) { - for(std::size_t index = 0; index < fowPixmap1->getPixelByteCount(); ++index) { - if(fowPixmap1->getPixels()[index] != 0) { - XmlNode *fowPixmap1Node = minimapNode->addChild("fowPixmap1"); - fowPixmap1Node->addAttribute("index",intToStr(index), mapTagReplacements); - fowPixmap1Node->addAttribute("pixel",intToStr(fowPixmap1->getPixels()[index]), mapTagReplacements); + void Minimap::computeTexture(const World *world) { + + Vec3f color; + const Map *map = world->getMap(); + + if (tex) { + tex->getPixmap()->setPixels(Vec4f(1.f, 1.f, 1.f, 0.1f).ptr(), tex->getPixmap()->getComponents()); + + for (int j = 0; j < tex->getPixmap()->getH(); ++j) { + for (int i = 0; i < tex->getPixmap()->getW(); ++i) { + SurfaceCell *sc = map->getSurfaceCell(i, j); + + if (sc->getObject() == NULL || sc->getObject()->getType() == NULL) { + const Pixmap2D *p = world->getTileset()->getSurfPixmap(sc->getSurfaceType(), 0); + color = p->getPixel3f(p->getW() / 2, p->getH() / 2); + color = color * static_cast(sc->getVertex().y / 6.f); + + if (sc->getVertex().y <= world->getMap()->getWaterLevel()) { + color += Vec3f(0.5f, 0.5f, 1.0f); + } + + if (color.x > 1.f) color.x = 1.f; + if (color.y > 1.f) color.y = 1.f; + if (color.z > 1.f) color.z = 1.f; + } else { + color = sc->getObject()->getType()->getColor(); + } + tex->getPixmap()->setPixel(i, j, color); + } + } } } - } -} -void Minimap::loadGame(const XmlNode *rootNode) { - const XmlNode *minimapNode = rootNode->getChild("Minimap"); + void Minimap::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *minimapNode = rootNode->addChild("Minimap"); - if(minimapNode->hasChild("fowPixmap1") == true) { - vector fowPixmap1NodeList = minimapNode->getChildList("fowPixmap1"); - for(unsigned int i = 0; i < fowPixmap1NodeList.size(); ++i) { - XmlNode *fowPixmap1Node = fowPixmap1NodeList[i]; - - int pixelIndex = fowPixmap1Node->getAttribute("index")->getIntValue(); - fowPixmap1->getPixels()[pixelIndex] = fowPixmap1Node->getAttribute("pixel")->getIntValue(); + if (fowPixmap1 != NULL) { + for (std::size_t index = 0; index < fowPixmap1->getPixelByteCount(); ++index) { + if (fowPixmap1->getPixels()[index] != 0) { + XmlNode *fowPixmap1Node = minimapNode->addChild("fowPixmap1"); + fowPixmap1Node->addAttribute("index", intToStr(index), mapTagReplacements); + fowPixmap1Node->addAttribute("pixel", intToStr(fowPixmap1->getPixels()[index]), mapTagReplacements); + } + } + } } - } -} -}}//end namespace + void Minimap::loadGame(const XmlNode *rootNode) { + const XmlNode *minimapNode = rootNode->getChild("Minimap"); + + if (minimapNode->hasChild("fowPixmap1") == true) { + vector fowPixmap1NodeList = minimapNode->getChildList("fowPixmap1"); + for (unsigned int i = 0; i < fowPixmap1NodeList.size(); ++i) { + XmlNode *fowPixmap1Node = fowPixmap1NodeList[i]; + + int pixelIndex = fowPixmap1Node->getAttribute("index")->getIntValue(); + fowPixmap1->getPixels()[pixelIndex] = fowPixmap1Node->getAttribute("pixel")->getIntValue(); + } + } + } + + } +}//end namespace diff --git a/source/glest_game/world/minimap.h b/source/glest_game/world/minimap.h index 0c8b9e9a1..7c8f2e2f0 100644 --- a/source/glest_game/world/minimap.h +++ b/source/glest_game/world/minimap.h @@ -13,8 +13,8 @@ #define _GLEST_GAME_MINIMAP_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include "pixmap.h" @@ -22,73 +22,79 @@ #include "xml_parser.h" #include "leak_dumper.h" -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -using Shared::Graphics::Vec4f; -using Shared::Graphics::Vec3f; -using Shared::Graphics::Vec2i; -using Shared::Graphics::Pixmap2D; -using Shared::Graphics::Texture2D; -using Shared::Xml::XmlNode; + using Shared::Graphics::Vec4f; + using Shared::Graphics::Vec3f; + using Shared::Graphics::Vec2i; + using Shared::Graphics::Pixmap2D; + using Shared::Graphics::Texture2D; + using Shared::Xml::XmlNode; -class World; -class GameSettings; + class World; + class GameSettings; -enum ExplorationState{ - esNotExplored, - esExplored, - esVisible -}; + enum ExplorationState { + esNotExplored, + esExplored, + esVisible + }; -// ===================================================== -// class Minimap -// -/// State of the in-game minimap -// ===================================================== + // ===================================================== + // class Minimap + // + /// State of the in-game minimap + // ===================================================== -class Minimap{ -private: - Pixmap2D *fowPixmap0; - Pixmap2D *fowPixmap1; - Pixmap2D *fowPixmap1_default; - Pixmap2D *fowPixmap0Copy; - Pixmap2D *fowPixmap1Copy; - Pixmap2D *fowPixmap1Copy_default; + class Minimap { + private: + Pixmap2D * fowPixmap0; + Pixmap2D *fowPixmap1; + Pixmap2D *fowPixmap1_default; + Pixmap2D *fowPixmap0Copy; + Pixmap2D *fowPixmap1Copy; + Pixmap2D *fowPixmap1Copy_default; - Texture2D *tex; - Texture2D *fowTex; //Fog Of War Texture2D - bool fogOfWar; - const GameSettings *gameSettings; + Texture2D *tex; + Texture2D *fowTex; //Fog Of War Texture2D + bool fogOfWar; + const GameSettings *gameSettings; -private: - static const float exploredAlpha; + private: + static const float exploredAlpha; -public: - void init(int x, int y, const World *world, bool fogOfWar); - Minimap(); - ~Minimap(); + public: + void init(int x, int y, const World *world, bool fogOfWar); + Minimap(); + ~Minimap(); - const Texture2D *getFowTexture() const {return fowTex;} - const Texture2D *getTexture() const {return tex;} + const Texture2D *getFowTexture() const { + return fowTex; + } + const Texture2D *getTexture() const { + return tex; + } - void incFowTextureAlphaSurface(const Vec2i sPos, float alpha, bool isIncrementalUpdate=false); - void resetFowTex(); - void updateFowTex(float t); - void setFogOfWar(bool value); + void incFowTextureAlphaSurface(const Vec2i sPos, float alpha, bool isIncrementalUpdate = false); + void resetFowTex(); + void updateFowTex(float t); + void setFogOfWar(bool value); - void copyFowTex(); - void restoreFowTex(); + void copyFowTex(); + void restoreFowTex(); - void copyFowTexAlphaSurface(); - void restoreFowTexAlphaSurface(); + void copyFowTexAlphaSurface(); + void restoreFowTexAlphaSurface(); - void saveGame(XmlNode *rootNode); - void loadGame(const XmlNode *rootNode); + void saveGame(XmlNode *rootNode); + void loadGame(const XmlNode *rootNode); -private: - void computeTexture(const World *world); -}; + private: + void computeTexture(const World *world); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/glest_game/world/scenario.cpp b/source/glest_game/world/scenario.cpp index 9275a2129..9ab2e6307 100644 --- a/source/glest_game/world/scenario.cpp +++ b/source/glest_game/world/scenario.cpp @@ -43,681 +43,679 @@ using namespace Shared::PlatformCommon; using namespace std; namespace Glest { - namespace Game { + namespace Game { -// ===================================================== -// class Scenario -// ===================================================== + // ===================================================== + // class Scenario + // ===================================================== - Scenario::~Scenario() { + Scenario::~Scenario() { - } - Checksum Scenario::load(const string & path) { - //printf("[%s:%s] Line: %d path [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str()); + } + Checksum Scenario::load(const string & path) { + //printf("[%s:%s] Line: %d path [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str()); - Checksum scenarioChecksum; - try { - scenarioChecksum.addFile(path); - checksumValue.addFile(path); + Checksum scenarioChecksum; + try { + scenarioChecksum.addFile(path); + checksumValue.addFile(path); - string name = cutLastExt(lastDir(path)); + string name = cutLastExt(lastDir(path)); - char szBuf[8096] = ""; - snprintf(szBuf, 8096, - Lang::getInstance(). - getString("LogScreenGameLoadingScenario", "", - true).c_str(), formatString(name).c_str()); - Logger::getInstance().add(szBuf, true); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + Lang::getInstance(). + getString("LogScreenGameLoadingScenario", "", + true).c_str(), formatString(name).c_str()); + Logger::getInstance().add(szBuf, true); - bool isTutorial = Scenario::isGameTutorial(path); + bool isTutorial = Scenario::isGameTutorial(path); - //Properties::setTechtreePath(); + //Properties::setTechtreePath(); - //printf("path [%s]\n",path.c_str()); - string scenarioFolder = cutLastFile(formatPath(path)); - endPathWithSlash(scenarioFolder); + //printf("path [%s]\n",path.c_str()); + string scenarioFolder = cutLastFile(formatPath(path)); + endPathWithSlash(scenarioFolder); - if (isTutorial == false) { - Properties::setScenarioPath(scenarioFolder); + if (isTutorial == false) { + Properties::setScenarioPath(scenarioFolder); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf("==> Set scenario path to [%s]\n", - scenarioFolder.c_str()); - } else { - Properties::setTutorialPath(scenarioFolder); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("==> Set scenario path to [%s]\n", + scenarioFolder.c_str()); + } else { + Properties::setTutorialPath(scenarioFolder); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf("==> Set tutorial path to [%s]\n", - scenarioFolder.c_str()); - } + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("==> Set tutorial path to [%s]\n", + scenarioFolder.c_str()); + } - Scenario::loadScenarioInfo(path, &info, isTutorial); + Scenario::loadScenarioInfo(path, &info, isTutorial); - //parse xml - XmlTree xmlTree; - xmlTree.setSkipUpdatePathClimbingParts(true); - xmlTree.load(path, Properties::getTagReplacementValues()); - const XmlNode *scenarioNode = xmlTree.getRootNode(); - const XmlNode *scriptsNode = scenarioNode->getChild("scripts"); + //parse xml + XmlTree xmlTree; + xmlTree.setSkipUpdatePathClimbingParts(true); + xmlTree.load(path, Properties::getTagReplacementValues()); + const XmlNode *scenarioNode = xmlTree.getRootNode(); + const XmlNode *scriptsNode = scenarioNode->getChild("scripts"); - for (int i = 0; i < (int) scriptsNode->getChildCount(); ++i) { - const XmlNode *scriptNode = scriptsNode->getChild(i); + for (int i = 0; i < (int) scriptsNode->getChildCount(); ++i) { + const XmlNode *scriptNode = scriptsNode->getChild(i); - scripts.push_back(Script - (getFunctionName(scriptNode), - scriptNode->getText())); - } - } - //Exception handling (conversions and so on); - catch(const exception & ex) { - char szBuf[8096] = ""; - snprintf(szBuf, 8096, - "In [%s::%s %d]\nError loading scenario [%s]:\n%s\n", - extractFileFromDirectoryPath(__FILE__).c_str(), - __FUNCTION__, __LINE__, path.c_str(), ex.what()); - SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); - if (SystemFlags:: - getSystemSettingType(SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + scripts.push_back(Script + (getFunctionName(scriptNode), + scriptNode->getText())); + } + } + //Exception handling (conversions and so on); + catch (const exception & ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "In [%s::%s %d]\nError loading scenario [%s]:\n%s\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, path.c_str(), ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + if (SystemFlags:: + getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); - throw megaglest_runtime_error(szBuf); - } + throw megaglest_runtime_error(szBuf); + } - return scenarioChecksum; - } + return scenarioChecksum; + } - int Scenario::getScenarioPathIndex(const vector < string > dirList, - const string & scenarioName) { - int iIndex = 0; - for (int idx = 0; idx < (int) dirList.size(); idx++) { - string currentPath = dirList[idx]; - endPathWithSlash(currentPath); - string scenarioFile = - currentPath + scenarioName + "/" + scenarioName + ".xml"; - if (fileExists(scenarioFile) == true) { - iIndex = idx; - break; - } - } + int Scenario::getScenarioPathIndex(const vector < string > dirList, + const string & scenarioName) { + int iIndex = 0; + for (int idx = 0; idx < (int) dirList.size(); idx++) { + string currentPath = dirList[idx]; + endPathWithSlash(currentPath); + string scenarioFile = + currentPath + scenarioName + "/" + scenarioName + ".xml"; + if (fileExists(scenarioFile) == true) { + iIndex = idx; + break; + } + } - return iIndex; - } + return iIndex; + } - string Scenario::getScenarioDir(const vector < string > dir, - const string & scenarioName) { - string scenarioDir = ""; - for (int idx = 0; idx < (int) dir.size(); idx++) { - string currentPath = dir[idx]; - endPathWithSlash(currentPath); - string scenarioFile = - currentPath + scenarioName + "/" + scenarioName + ".xml"; + string Scenario::getScenarioDir(const vector < string > dir, + const string & scenarioName) { + string scenarioDir = ""; + for (int idx = 0; idx < (int) dir.size(); idx++) { + string currentPath = dir[idx]; + endPathWithSlash(currentPath); + string scenarioFile = + currentPath + scenarioName + "/" + scenarioName + ".xml"; - //printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str()); + //printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str()); - if (fileExists(scenarioFile) == true) { - scenarioDir = currentPath + scenarioName + "/"; - break; - } - } + if (fileExists(scenarioFile) == true) { + scenarioDir = currentPath + scenarioName + "/"; + break; + } + } - return scenarioDir; - } + return scenarioDir; + } - string Scenario::getScenarioPath(const vector < string > dirList, - const string & scenarioName, - bool getMatchingRootScenarioPathOnly) - { - string scenarioFile = ""; - for (int idx = 0; idx < (int) dirList.size(); idx++) { - string currentPath = dirList[idx]; - endPathWithSlash(currentPath); - scenarioFile = - currentPath + scenarioName + "/" + scenarioName + ".xml"; - //printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str()); + string Scenario::getScenarioPath(const vector < string > dirList, + const string & scenarioName, + bool getMatchingRootScenarioPathOnly) { + string scenarioFile = ""; + for (int idx = 0; idx < (int) dirList.size(); idx++) { + string currentPath = dirList[idx]; + endPathWithSlash(currentPath); + scenarioFile = + currentPath + scenarioName + "/" + scenarioName + ".xml"; + //printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str()); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf - ("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n", - __FILE__, __FUNCTION__, __LINE__, scenarioName.c_str(), - scenarioFile.c_str()); - //printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n", + __FILE__, __FUNCTION__, __LINE__, scenarioName.c_str(), + scenarioFile.c_str()); + //printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str()); - if (fileExists(scenarioFile) == true) { - //printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str()); + if (fileExists(scenarioFile) == true) { + //printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str()); - if (getMatchingRootScenarioPathOnly == true) { - //printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str()); - scenarioFile = dirList[idx]; - } - break; - } else { - //printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str()); - scenarioFile = ""; - } - } - //printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str()); - return scenarioFile; - } + if (getMatchingRootScenarioPathOnly == true) { + //printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str()); + scenarioFile = dirList[idx]; + } + break; + } else { + //printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str()); + scenarioFile = ""; + } + } + //printf("\n[%s:%s] Line: %d scenarioName [%s] scenarioFile [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioName.c_str(),scenarioFile.c_str()); + return scenarioFile; + } - string Scenario::getScenarioPath(const string & dir, - const string & scenarioName) { - string currentPath = dir; - endPathWithSlash(currentPath); - string scenarioFile = - currentPath + scenarioName + "/" + scenarioName + ".xml"; - return scenarioFile; - } + string Scenario::getScenarioPath(const string & dir, + const string & scenarioName) { + string currentPath = dir; + endPathWithSlash(currentPath); + string scenarioFile = + currentPath + scenarioName + "/" + scenarioName + ".xml"; + return scenarioFile; + } - string Scenario::getFunctionName(const XmlNode * scriptNode) { - string name = scriptNode->getName(); + string Scenario::getFunctionName(const XmlNode * scriptNode) { + string name = scriptNode->getName(); - for (int i = 0; i < (int) scriptNode->getAttributeCount(); ++i) { - name += "_" + scriptNode->getAttribute(i)->getValue(); - } - return name; - } + for (int i = 0; i < (int) scriptNode->getAttributeCount(); ++i) { + name += "_" + scriptNode->getAttribute(i)->getValue(); + } + return name; + } - bool Scenario::isGameTutorial(string path) { - bool isTutorial = false; - Config & config = Config::getInstance(); - vector < string > tutorialPaths = - config.getPathListForType(ptTutorials); - if (tutorialPaths.empty() == false) { - for (unsigned int tutorialIndex = 0; - tutorialIndex < tutorialPaths.size(); ++tutorialIndex) { - const string & tutorialPath = tutorialPaths[tutorialIndex]; - size_t pos = path.find(tutorialPath); - if (pos != path.npos) { - isTutorial = true; - break; - } - } - } + bool Scenario::isGameTutorial(string path) { + bool isTutorial = false; + Config & config = Config::getInstance(); + vector < string > tutorialPaths = + config.getPathListForType(ptTutorials); + if (tutorialPaths.empty() == false) { + for (unsigned int tutorialIndex = 0; + tutorialIndex < tutorialPaths.size(); ++tutorialIndex) { + const string & tutorialPath = tutorialPaths[tutorialIndex]; + size_t pos = path.find(tutorialPath); + if (pos != path.npos) { + isTutorial = true; + break; + } + } + } - return isTutorial; - } + return isTutorial; + } - bool Scenario::loadScenarioInfo(string file, - ScenarioInfo * scenarioInfo, - bool isTutorial) { - if (fileExists (file) == false) - { - // FIXME: A new string will need a new translation; we haven't - // discussed how we'll deal with translations yet. - // - // this particular string is just a placeholder, and will hopefully - // get changed soon, when we can point a user to complete documentation - // on how to obtain a scenario - // -andy5995 2018-02-01 - scenarioInfo->desc = "This scenario will be available soon.\n\n\ + bool Scenario::loadScenarioInfo(string file, + ScenarioInfo * scenarioInfo, + bool isTutorial) { + if (fileExists(file) == false) { + // FIXME: A new string will need a new translation; we haven't + // discussed how we'll deal with translations yet. + // + // this particular string is just a placeholder, and will hopefully + // get changed soon, when we can point a user to complete documentation + // on how to obtain a scenario + // -andy5995 2018-02-01 + scenarioInfo->desc = "This scenario will be available soon.\n\n\ Please contact the ZetaGlest team for more info."; - scenarioInfo->name = file; - return false; - } + scenarioInfo->name = file; + return false; + } - //printf("[%s:%s] Line: %d file [%s]\n",__FILE__,__FUNCTION__,__LINE__,file.c_str()); - if (SystemFlags::VERBOSE_MODE_ENABLED) - printf("In [%s::%s Line: %d] file [%s]\n", - extractFileFromDirectoryPath(__FILE__).c_str(), - __FUNCTION__, __LINE__, file.c_str()); - //printf("In [%s::%s Line: %d] file [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,file.c_str()); + //printf("[%s:%s] Line: %d file [%s]\n",__FILE__,__FUNCTION__,__LINE__,file.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf("In [%s::%s Line: %d] file [%s]\n", + extractFileFromDirectoryPath(__FILE__).c_str(), + __FUNCTION__, __LINE__, file.c_str()); + //printf("In [%s::%s Line: %d] file [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,file.c_str()); - //printf("[%s:%s] Line: %d file [%s]\n",__FILE__,__FUNCTION__,__LINE__,file.c_str()); - Lang & lang = Lang::getInstance(); - string scenarioDir = cutLastFile(formatPath(file)); - string scenarioName = extractLastDirectoryFromPath(scenarioDir); - scenarioDir = cutLastFile(scenarioDir); - //printf("[%s:%s] Line: %d scenarioDir [%s] scenarioName [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioDir.c_str(),scenarioName.c_str()); + //printf("[%s:%s] Line: %d file [%s]\n",__FILE__,__FUNCTION__,__LINE__,file.c_str()); + Lang & lang = Lang::getInstance(); + string scenarioDir = cutLastFile(formatPath(file)); + string scenarioName = extractLastDirectoryFromPath(scenarioDir); + scenarioDir = cutLastFile(scenarioDir); + //printf("[%s:%s] Line: %d scenarioDir [%s] scenarioName [%s]\n",__FILE__,__FUNCTION__,__LINE__,scenarioDir.c_str(),scenarioName.c_str()); - XmlTree xmlTree; - xmlTree.load(file, Properties::getTagReplacementValues()); + XmlTree xmlTree; + xmlTree.load(file, Properties::getTagReplacementValues()); - const XmlNode *scenarioNode = xmlTree.getRootNode(); - if (scenarioNode == NULL) { - char szBuf[8096] = ""; - snprintf(szBuf, 8096, "scenarioNode == NULL for file [%s]\n", - file.c_str()); - throw std::runtime_error(szBuf); - } - const XmlNode *difficultyNode = scenarioNode->getChild("difficulty"); - if (difficultyNode == NULL) { - char szBuf[8096] = ""; - snprintf(szBuf, 8096, "difficultyNode == NULL for file [%s]\n", - file.c_str()); - throw std::runtime_error(szBuf); - } + const XmlNode *scenarioNode = xmlTree.getRootNode(); + if (scenarioNode == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "scenarioNode == NULL for file [%s]\n", + file.c_str()); + throw std::runtime_error(szBuf); + } + const XmlNode *difficultyNode = scenarioNode->getChild("difficulty"); + if (difficultyNode == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "difficultyNode == NULL for file [%s]\n", + file.c_str()); + throw std::runtime_error(szBuf); + } - scenarioInfo->difficulty = - difficultyNode->getAttribute("value")->getIntValue(); - if (scenarioInfo->difficulty < dVeryEasy - || scenarioInfo->difficulty > dInsane) { - char szBuf[8096] = ""; - snprintf(szBuf, 8096, - "Invalid difficulty value specified in scenario: %d must be between %d and %d", - scenarioInfo->difficulty, dVeryEasy, dInsane); - throw std::runtime_error(szBuf); - } + scenarioInfo->difficulty = + difficultyNode->getAttribute("value")->getIntValue(); + if (scenarioInfo->difficulty < dVeryEasy + || scenarioInfo->difficulty > dInsane) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Invalid difficulty value specified in scenario: %d must be between %d and %d", + scenarioInfo->difficulty, dVeryEasy, dInsane); + throw std::runtime_error(szBuf); + } - const XmlNode *playersNode = scenarioNode->getChild("players"); - if (playersNode == NULL) { - char szBuf[8096] = ""; - snprintf(szBuf, 8096, "playersNode == NULL for file [%s]\n", - file.c_str()); - throw std::runtime_error(szBuf); - } + const XmlNode *playersNode = scenarioNode->getChild("players"); + if (playersNode == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "playersNode == NULL for file [%s]\n", + file.c_str()); + throw std::runtime_error(szBuf); + } - for (int i = 0; i < GameConstants::maxPlayers; ++i) { - XmlNode *playerNode = NULL; - //string factionTypeName=""; - ControlType factionControl; + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + XmlNode *playerNode = NULL; + //string factionTypeName=""; + ControlType factionControl; - if (playersNode->hasChildAtIndex("player", i)) { - playerNode = playersNode->getChild("player", i); - if (playerNode == NULL) { - char szBuf[8096] = ""; - snprintf(szBuf, 8096, - "playerNode == NULL for index = %d for file [%s]\n", - i, file.c_str()); - throw std::runtime_error(szBuf); - } + if (playersNode->hasChildAtIndex("player", i)) { + playerNode = playersNode->getChild("player", i); + if (playerNode == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "playerNode == NULL for index = %d for file [%s]\n", + i, file.c_str()); + throw std::runtime_error(szBuf); + } - factionControl = - strToControllerType(playerNode-> - getAttribute("control")->getValue()); + factionControl = + strToControllerType(playerNode-> + getAttribute("control")->getValue()); - if (playerNode->getAttribute("resource_multiplier", false) != - NULL) { - // if a multiplier exists use it - scenarioInfo->resourceMultipliers[i] = - playerNode-> - getAttribute("resource_multiplier")->getFloatValue(); - } else { - // if no multiplier exists use defaults - scenarioInfo->resourceMultipliers[i] = - GameConstants::normalMultiplier; - if (factionControl == ctCpuEasy) { - scenarioInfo->resourceMultipliers[i] = - GameConstants::easyMultiplier; - } - if (factionControl == ctCpuUltra) { - scenarioInfo->resourceMultipliers[i] = - GameConstants::ultraMultiplier; - } else if (factionControl == ctCpuZeta) { - scenarioInfo->resourceMultipliers[i] = - GameConstants::megaMultiplier; - } - } + if (playerNode->getAttribute("resource_multiplier", false) != + NULL) { + // if a multiplier exists use it + scenarioInfo->resourceMultipliers[i] = + playerNode-> + getAttribute("resource_multiplier")->getFloatValue(); + } else { + // if no multiplier exists use defaults + scenarioInfo->resourceMultipliers[i] = + GameConstants::normalMultiplier; + if (factionControl == ctCpuEasy) { + scenarioInfo->resourceMultipliers[i] = + GameConstants::easyMultiplier; + } + if (factionControl == ctCpuUltra) { + scenarioInfo->resourceMultipliers[i] = + GameConstants::ultraMultiplier; + } else if (factionControl == ctCpuZeta) { + scenarioInfo->resourceMultipliers[i] = + GameConstants::megaMultiplier; + } + } - } else { - factionControl = ctClosed; - } + } else { + factionControl = ctClosed; + } - scenarioInfo->factionControls[i] = factionControl; + scenarioInfo->factionControls[i] = factionControl; - if (factionControl != ctClosed) { - int teamIndex = playerNode->getAttribute("team")->getIntValue(); + if (factionControl != ctClosed) { + int teamIndex = playerNode->getAttribute("team")->getIntValue(); - if (teamIndex < 1 - || teamIndex > - GameConstants::maxPlayers + GameConstants::specialFactions) { - char szBuf[8096] = ""; - snprintf(szBuf, 8096, - "Invalid team value specified in scenario: %d must be between %d and %d", - teamIndex, 1, GameConstants::maxPlayers); - throw std::runtime_error(szBuf); - } + if (teamIndex < 1 + || teamIndex > + GameConstants::maxPlayers + GameConstants::specialFactions) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Invalid team value specified in scenario: %d must be between %d and %d", + teamIndex, 1, GameConstants::maxPlayers); + throw std::runtime_error(szBuf); + } - scenarioInfo->teams[i] = teamIndex; - scenarioInfo->factionTypeNames[i] = - playerNode->getAttribute("faction")->getValue(); - } else { - scenarioInfo->teams[i] = 0; - scenarioInfo->factionTypeNames[i] = ""; - } + scenarioInfo->teams[i] = teamIndex; + scenarioInfo->factionTypeNames[i] = + playerNode->getAttribute("faction")->getValue(); + } else { + scenarioInfo->teams[i] = 0; + scenarioInfo->factionTypeNames[i] = ""; + } - if (scenarioNode->getChild("map") == NULL) { - char szBuf[8096] = ""; - snprintf(szBuf, 8096, "map == NULL for file [%s]\n", - file.c_str()); - throw std::runtime_error(szBuf); - } - if (scenarioNode->getChild("tileset") == NULL) { - char szBuf[8096] = ""; - snprintf(szBuf, 8096, "tileset == NULL for file [%s]\n", - file.c_str()); - throw std::runtime_error(szBuf); - } - if (scenarioNode->getChild("tech-tree") == NULL) { - char szBuf[8096] = ""; - snprintf(szBuf, 8096, "tech-tree == NULL for file [%s]\n", - file.c_str()); - throw std::runtime_error(szBuf); - } - if (scenarioNode->getChild("default-units") == NULL) { - char szBuf[8096] = ""; - snprintf(szBuf, 8096, "default-units == NULL for file [%s]\n", - file.c_str()); - throw std::runtime_error(szBuf); - } - if (scenarioNode->getChild("default-resources") == NULL) { - char szBuf[8096] = ""; - snprintf(szBuf, 8096, - "default-resources == NULL for file [%s]\n", - file.c_str()); - throw std::runtime_error(szBuf); - } - if (scenarioNode->getChild("default-victory-conditions") == NULL) { - char szBuf[8096] = ""; - snprintf(szBuf, 8096, - "default-victory-conditions == NULL for file [%s]\n", - file.c_str()); - throw std::runtime_error(szBuf); - } + if (scenarioNode->getChild("map") == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "map == NULL for file [%s]\n", + file.c_str()); + throw std::runtime_error(szBuf); + } + if (scenarioNode->getChild("tileset") == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "tileset == NULL for file [%s]\n", + file.c_str()); + throw std::runtime_error(szBuf); + } + if (scenarioNode->getChild("tech-tree") == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "tech-tree == NULL for file [%s]\n", + file.c_str()); + throw std::runtime_error(szBuf); + } + if (scenarioNode->getChild("default-units") == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "default-units == NULL for file [%s]\n", + file.c_str()); + throw std::runtime_error(szBuf); + } + if (scenarioNode->getChild("default-resources") == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "default-resources == NULL for file [%s]\n", + file.c_str()); + throw std::runtime_error(szBuf); + } + if (scenarioNode->getChild("default-victory-conditions") == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "default-victory-conditions == NULL for file [%s]\n", + file.c_str()); + throw std::runtime_error(szBuf); + } - scenarioInfo->mapName = - scenarioNode->getChild("map")-> - getAttribute("value")->getValue(); - scenarioInfo->tilesetName = - scenarioNode->getChild("tileset")-> - getAttribute("value")->getValue(); - scenarioInfo->techTreeName = - scenarioNode->getChild("tech-tree")-> - getAttribute("value")->getValue(); - scenarioInfo->defaultUnits = - scenarioNode-> - getChild("default-units")->getAttribute("value")-> - getBoolValue(); - scenarioInfo->defaultResources = - scenarioNode-> - getChild("default-resources")->getAttribute("value")-> - getBoolValue(); - scenarioInfo->defaultVictoryConditions = - scenarioNode-> - getChild("default-victory-conditions")->getAttribute("value")-> - getBoolValue(); - } + scenarioInfo->mapName = + scenarioNode->getChild("map")-> + getAttribute("value")->getValue(); + scenarioInfo->tilesetName = + scenarioNode->getChild("tileset")-> + getAttribute("value")->getValue(); + scenarioInfo->techTreeName = + scenarioNode->getChild("tech-tree")-> + getAttribute("value")->getValue(); + scenarioInfo->defaultUnits = + scenarioNode-> + getChild("default-units")->getAttribute("value")-> + getBoolValue(); + scenarioInfo->defaultResources = + scenarioNode-> + getChild("default-resources")->getAttribute("value")-> + getBoolValue(); + scenarioInfo->defaultVictoryConditions = + scenarioNode-> + getChild("default-victory-conditions")->getAttribute("value")-> + getBoolValue(); + } - //add player info - scenarioInfo->desc = lang.getString("PlayerFaction") + ": "; - for (int i = 0; i < GameConstants::maxPlayers; ++i) { - if (scenarioInfo->factionControls[i] == ctHuman) { - scenarioInfo->desc += - formatString(scenarioInfo->factionTypeNames[i]); - break; - } - } + //add player info + scenarioInfo->desc = lang.getString("PlayerFaction") + ": "; + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + if (scenarioInfo->factionControls[i] == ctHuman) { + scenarioInfo->desc += + formatString(scenarioInfo->factionTypeNames[i]); + break; + } + } - //add misc info - string difficultyString = - "Difficulty" + intToStr(scenarioInfo->difficulty); + //add misc info + string difficultyString = + "Difficulty" + intToStr(scenarioInfo->difficulty); - scenarioInfo->desc += "\n"; - scenarioInfo->desc += - lang.getString("Difficulty") + ": " + - lang.getString(difficultyString) + "\n"; - scenarioInfo->desc += - lang.getString("Map") + ": " + - formatString(scenarioInfo->mapName) + "\n"; - scenarioInfo->desc += - lang.getString("Tileset") + ": " + - formatString(scenarioInfo->tilesetName) + "\n"; - scenarioInfo->desc += - lang.getString("TechTree") + ": " + - formatString(scenarioInfo->techTreeName) + "\n"; + scenarioInfo->desc += "\n"; + scenarioInfo->desc += + lang.getString("Difficulty") + ": " + + lang.getString(difficultyString) + "\n"; + scenarioInfo->desc += + lang.getString("Map") + ": " + + formatString(scenarioInfo->mapName) + "\n"; + scenarioInfo->desc += + lang.getString("Tileset") + ": " + + formatString(scenarioInfo->tilesetName) + "\n"; + scenarioInfo->desc += + lang.getString("TechTree") + ": " + + formatString(scenarioInfo->techTreeName) + "\n"; - //look for description and append it - lang.loadScenarioStrings(scenarioDir, scenarioName.c_str(), - isTutorial); - //string tmp_description = lang.getScenarioString("DESCRIPTION"); - string tmp_description = ""; - if (lang.hasScenarioString("DESCRIPTION") == true) { - tmp_description = lang.getScenarioString("DESCRIPTION"); - } - if (tmp_description != "") { - scenarioInfo->desc += - lang.getString("Description") + ": \n" + tmp_description + - "\n"; - } + //look for description and append it + lang.loadScenarioStrings(scenarioDir, scenarioName.c_str(), + isTutorial); + //string tmp_description = lang.getScenarioString("DESCRIPTION"); + string tmp_description = ""; + if (lang.hasScenarioString("DESCRIPTION") == true) { + tmp_description = lang.getScenarioString("DESCRIPTION"); + } + if (tmp_description != "") { + scenarioInfo->desc += + lang.getString("Description") + ": \n" + tmp_description + + "\n"; + } - scenarioInfo->namei18n = ""; - if (lang.hasScenarioString("SCENARIO_NAME") == true) { - scenarioInfo->namei18n = lang.getScenarioString("SCENARIO_NAME"); - //printf("scenarioInfo->namei18n [%s]\n",scenarioInfo->namei18n.c_str()); - } else if (lang.hasScenarioString("TUTORIAL_NAME") == true) { - scenarioInfo->namei18n = lang.getScenarioString("TUTORIAL_NAME"); - //printf("scenarioInfo->namei18n [%s]\n",scenarioInfo->namei18n.c_str()); - } + scenarioInfo->namei18n = ""; + if (lang.hasScenarioString("SCENARIO_NAME") == true) { + scenarioInfo->namei18n = lang.getScenarioString("SCENARIO_NAME"); + //printf("scenarioInfo->namei18n [%s]\n",scenarioInfo->namei18n.c_str()); + } else if (lang.hasScenarioString("TUTORIAL_NAME") == true) { + scenarioInfo->namei18n = lang.getScenarioString("TUTORIAL_NAME"); + //printf("scenarioInfo->namei18n [%s]\n",scenarioInfo->namei18n.c_str()); + } - if (scenarioNode->hasChild("fog-of-war") == true) { - if (scenarioNode->getChild("fog-of-war")-> - getAttribute("value")->getValue() == "explored") { - scenarioInfo->fogOfWar = true; - scenarioInfo->fogOfWar_exploredFlag = true; - } else { - scenarioInfo->fogOfWar = - scenarioNode->getChild("fog-of-war")-> - getAttribute("value")->getBoolValue(); - scenarioInfo->fogOfWar_exploredFlag = false; - } - //printf("\nFOG OF WAR is set to [%d]\n",scenarioInfo->fogOfWar); - } else { - scenarioInfo->fogOfWar = true; - scenarioInfo->fogOfWar_exploredFlag = false; - } + if (scenarioNode->hasChild("fog-of-war") == true) { + if (scenarioNode->getChild("fog-of-war")-> + getAttribute("value")->getValue() == "explored") { + scenarioInfo->fogOfWar = true; + scenarioInfo->fogOfWar_exploredFlag = true; + } else { + scenarioInfo->fogOfWar = + scenarioNode->getChild("fog-of-war")-> + getAttribute("value")->getBoolValue(); + scenarioInfo->fogOfWar_exploredFlag = false; + } + //printf("\nFOG OF WAR is set to [%d]\n",scenarioInfo->fogOfWar); + } else { + scenarioInfo->fogOfWar = true; + scenarioInfo->fogOfWar_exploredFlag = false; + } - if (scenarioNode->hasChild("shared-team-units") == true) { - scenarioInfo->allowTeamUnitSharing = - scenarioNode-> - getChild("shared-team-units")->getAttribute("value")-> - getBoolValue(); - //printf("\nallowTeamUnitSharing is set to [%s]\n",scenarioInfo->allowTeamUnitSharing); - } else { - scenarioInfo->allowTeamUnitSharing = false; - } + if (scenarioNode->hasChild("shared-team-units") == true) { + scenarioInfo->allowTeamUnitSharing = + scenarioNode-> + getChild("shared-team-units")->getAttribute("value")-> + getBoolValue(); + //printf("\nallowTeamUnitSharing is set to [%s]\n",scenarioInfo->allowTeamUnitSharing); + } else { + scenarioInfo->allowTeamUnitSharing = false; + } - if (scenarioNode->hasChild("shared-team-resources") == true) { - scenarioInfo->allowTeamResourceSharing = - scenarioNode-> - getChild("shared-team-resources")->getAttribute("value")-> - getBoolValue(); - //printf("\nallowTeamResourceSharing is set to [%s]\n",scenarioInfo->allowTeamResourceSharing); - } else { - scenarioInfo->allowTeamResourceSharing = false; - } + if (scenarioNode->hasChild("shared-team-resources") == true) { + scenarioInfo->allowTeamResourceSharing = + scenarioNode-> + getChild("shared-team-resources")->getAttribute("value")-> + getBoolValue(); + //printf("\nallowTeamResourceSharing is set to [%s]\n",scenarioInfo->allowTeamResourceSharing); + } else { + scenarioInfo->allowTeamResourceSharing = false; + } - scenarioInfo->file = file; - scenarioInfo->name = extractFileFromDirectoryPath(file); - scenarioInfo->name = cutLastExt(scenarioInfo->name); + scenarioInfo->file = file; + scenarioInfo->name = extractFileFromDirectoryPath(file); + scenarioInfo->name = cutLastExt(scenarioInfo->name); - return true; + return true; - //scenarioLogoTexture = NULL; - //cleanupPreviewTexture(); - //previewLoadDelayTimer=time(NULL); - //needToLoadTextures=true; - } + //scenarioLogoTexture = NULL; + //cleanupPreviewTexture(); + //previewLoadDelayTimer=time(NULL); + //needToLoadTextures=true; + } - ControlType Scenario::strToControllerType(const string & str) { - if (str == "closed") { - return ctClosed; - } else if (str == "cpu-easy") { - return ctCpuEasy; - } else if (str == "cpu") { - return ctCpu; - } else if (str == "cpu-ultra") { - return ctCpuUltra; - } else if (str == "cpu-mega" || str == "cpu-zeta") { - return ctCpuZeta; - } else if (str == "human") { - return ctHuman; - } else if (str == "network") { - return ctNetwork; - } + ControlType Scenario::strToControllerType(const string & str) { + if (str == "closed") { + return ctClosed; + } else if (str == "cpu-easy") { + return ctCpuEasy; + } else if (str == "cpu") { + return ctCpu; + } else if (str == "cpu-ultra") { + return ctCpuUltra; + } else if (str == "cpu-mega" || str == "cpu-zeta") { + return ctCpuZeta; + } else if (str == "human") { + return ctHuman; + } else if (str == "network") { + return ctNetwork; + } - char szBuf[8096] = ""; - snprintf(szBuf, 8096, - "Invalid controller value specified in scenario: [%s] must be one of the following: closed, cpu-easy, cpu, cpu-ultra, cpu-zeta, human", - str.c_str()); - throw std::runtime_error(szBuf); - } + char szBuf[8096] = ""; + snprintf(szBuf, 8096, + "Invalid controller value specified in scenario: [%s] must be one of the following: closed, cpu-easy, cpu, cpu-ultra, cpu-zeta, human", + str.c_str()); + throw std::runtime_error(szBuf); + } - string Scenario::controllerTypeToStr(const ControlType & ct) { - string controlString = ""; + string Scenario::controllerTypeToStr(const ControlType & ct) { + string controlString = ""; - Lang & lang = Lang::getInstance(); - switch (ct) { - case ctCpuEasy: - controlString = lang.getString("CpuEasy"); - break; - case ctCpu: - controlString = lang.getString("Cpu"); - break; - case ctCpuUltra: - controlString = lang.getString("CpuUltra"); - break; - case ctCpuZeta: - controlString = lang.getString("CpuZeta"); - break; - case ctNetwork: - controlString = lang.getString("Network"); - break; - case ctHuman: - controlString = lang.getString("Human"); - break; + Lang & lang = Lang::getInstance(); + switch (ct) { + case ctCpuEasy: + controlString = lang.getString("CpuEasy"); + break; + case ctCpu: + controlString = lang.getString("Cpu"); + break; + case ctCpuUltra: + controlString = lang.getString("CpuUltra"); + break; + case ctCpuZeta: + controlString = lang.getString("CpuZeta"); + break; + case ctNetwork: + controlString = lang.getString("Network"); + break; + case ctHuman: + controlString = lang.getString("Human"); + break; - case ctNetworkCpuEasy: - controlString = lang.getString("NetworkCpuEasy"); - break; - case ctNetworkCpu: - controlString = lang.getString("NetworkCpu"); - break; - case ctNetworkCpuUltra: - controlString = lang.getString("NetworkCpuUltra"); - break; - case ctNetworkCpuZeta: - controlString = lang.getString("NetworkCpuZeta"); - break; + case ctNetworkCpuEasy: + controlString = lang.getString("NetworkCpuEasy"); + break; + case ctNetworkCpu: + controlString = lang.getString("NetworkCpu"); + break; + case ctNetworkCpuUltra: + controlString = lang.getString("NetworkCpuUltra"); + break; + case ctNetworkCpuZeta: + controlString = lang.getString("NetworkCpuZeta"); + break; - default: - printf("Error control = %d\n", ct); - //assert(false); - break; - } + default: + printf("Error control = %d\n", ct); + //assert(false); + break; + } - return controlString; - } + return controlString; + } - void Scenario::loadGameSettings(const vector < string > &dirList, - const ScenarioInfo * scenarioInfo, - GameSettings * gameSettings, - string scenarioDescription) { - int factionCount = 0; - int AIPlayerCount = 0; - Lang & lang = Lang::getInstance(); + void Scenario::loadGameSettings(const vector < string > &dirList, + const ScenarioInfo * scenarioInfo, + GameSettings * gameSettings, + string scenarioDescription) { + int factionCount = 0; + int AIPlayerCount = 0; + Lang & lang = Lang::getInstance(); - if (gameSettings->getGameUUID() == "") { - gameSettings->setGameUUID(getUUIDAsString()); - } + if (gameSettings->getGameUUID() == "") { + gameSettings->setGameUUID(getUUIDAsString()); + } - gameSettings->setDescription(scenarioDescription); - gameSettings->setMap(scenarioInfo->mapName); - gameSettings->setTileset(scenarioInfo->tilesetName); - gameSettings->setTech(scenarioInfo->techTreeName); - gameSettings->setScenario(scenarioInfo->name); - gameSettings->setScenarioDir(Scenario::getScenarioPath - (dirList, scenarioInfo->name)); - gameSettings->setDefaultUnits(scenarioInfo->defaultUnits); - gameSettings->setDefaultResources(scenarioInfo->defaultResources); - gameSettings-> - setDefaultVictoryConditions - (scenarioInfo->defaultVictoryConditions); + gameSettings->setDescription(scenarioDescription); + gameSettings->setMap(scenarioInfo->mapName); + gameSettings->setTileset(scenarioInfo->tilesetName); + gameSettings->setTech(scenarioInfo->techTreeName); + gameSettings->setScenario(scenarioInfo->name); + gameSettings->setScenarioDir(Scenario::getScenarioPath + (dirList, scenarioInfo->name)); + gameSettings->setDefaultUnits(scenarioInfo->defaultUnits); + gameSettings->setDefaultResources(scenarioInfo->defaultResources); + gameSettings-> + setDefaultVictoryConditions + (scenarioInfo->defaultVictoryConditions); - for (int i = 0; i < GameConstants::maxPlayers; ++i) { - ControlType ct = - static_cast < ControlType > (scenarioInfo->factionControls[i]); - if (ct != ctClosed) { - if (ct == ctHuman) { - gameSettings->setThisFactionIndex(factionCount); + for (int i = 0; i < GameConstants::maxPlayers; ++i) { + ControlType ct = + static_cast (scenarioInfo->factionControls[i]); + if (ct != ctClosed) { + if (ct == ctHuman) { + gameSettings->setThisFactionIndex(factionCount); - if (gameSettings->getNetworkPlayerName(factionCount) == "") { - gameSettings->setNetworkPlayerName(factionCount, - Config:: - getInstance().getString - ("NetPlayerName", - Socket::getHostName - ().c_str())); - } - gameSettings->setNetworkPlayerUUID(factionCount, - Config:: - getInstance().getString - ("PlayerId", "")); - gameSettings->setNetworkPlayerPlatform(factionCount, - getPlatformNameString - ()); - } else if (ct == ctNetwork || ct == ctNetworkUnassigned) { - if (gameSettings->getNetworkPlayerName(factionCount) == "") { - gameSettings->setNetworkPlayerName(factionCount, - controllerTypeToStr(ct)); - } - } else { //this is a CPU player - AIPlayerCount++; - if (gameSettings->getNetworkPlayerName(factionCount) == "") { - gameSettings->setNetworkPlayerName(factionCount, - lang.getString("AI") + - intToStr(AIPlayerCount)); - } - } - gameSettings->setFactionControl(factionCount, ct); - gameSettings->setResourceMultiplierIndex(factionCount, - (scenarioInfo->resourceMultipliers - [i] - - 0.5f) / 0.1f); - gameSettings->setTeam(factionCount, scenarioInfo->teams[i] - 1); - gameSettings->setStartLocationIndex(factionCount, i); - gameSettings->setFactionTypeName(factionCount, - scenarioInfo->factionTypeNames - [i]); - factionCount++; - } - } + if (gameSettings->getNetworkPlayerName(factionCount) == "") { + gameSettings->setNetworkPlayerName(factionCount, + Config:: + getInstance().getString + ("NetPlayerName", + Socket::getHostName + ().c_str())); + } + gameSettings->setNetworkPlayerUUID(factionCount, + Config:: + getInstance().getString + ("PlayerId", "")); + gameSettings->setNetworkPlayerPlatform(factionCount, + getPlatformNameString + ()); + } else if (ct == ctNetwork || ct == ctNetworkUnassigned) { + if (gameSettings->getNetworkPlayerName(factionCount) == "") { + gameSettings->setNetworkPlayerName(factionCount, + controllerTypeToStr(ct)); + } + } else { //this is a CPU player + AIPlayerCount++; + if (gameSettings->getNetworkPlayerName(factionCount) == "") { + gameSettings->setNetworkPlayerName(factionCount, + lang.getString("AI") + + intToStr(AIPlayerCount)); + } + } + gameSettings->setFactionControl(factionCount, ct); + gameSettings->setResourceMultiplierIndex(factionCount, + (scenarioInfo->resourceMultipliers + [i] + - 0.5f) / 0.1f); + gameSettings->setTeam(factionCount, scenarioInfo->teams[i] - 1); + gameSettings->setStartLocationIndex(factionCount, i); + gameSettings->setFactionTypeName(factionCount, + scenarioInfo->factionTypeNames + [i]); + factionCount++; + } + } - gameSettings->setFactionCount(factionCount); - gameSettings->setFogOfWar(scenarioInfo->fogOfWar); - uint32 valueFlags1 = gameSettings->getFlagTypes1(); - if (scenarioInfo->fogOfWar == false - || scenarioInfo->fogOfWar_exploredFlag) { - valueFlags1 |= ft1_show_map_resources; - gameSettings->setFlagTypes1(valueFlags1); - } else { - valueFlags1 &= ~ft1_show_map_resources; - gameSettings->setFlagTypes1(valueFlags1); - } + gameSettings->setFactionCount(factionCount); + gameSettings->setFogOfWar(scenarioInfo->fogOfWar); + uint32 valueFlags1 = gameSettings->getFlagTypes1(); + if (scenarioInfo->fogOfWar == false + || scenarioInfo->fogOfWar_exploredFlag) { + valueFlags1 |= ft1_show_map_resources; + gameSettings->setFlagTypes1(valueFlags1); + } else { + valueFlags1 &= ~ft1_show_map_resources; + gameSettings->setFlagTypes1(valueFlags1); + } - if (scenarioInfo->allowTeamUnitSharing == true) { - valueFlags1 |= ft1_allow_shared_team_units; - gameSettings->setFlagTypes1(valueFlags1); - } else { - valueFlags1 &= ~ft1_allow_shared_team_units; - gameSettings->setFlagTypes1(valueFlags1); - } + if (scenarioInfo->allowTeamUnitSharing == true) { + valueFlags1 |= ft1_allow_shared_team_units; + gameSettings->setFlagTypes1(valueFlags1); + } else { + valueFlags1 &= ~ft1_allow_shared_team_units; + gameSettings->setFlagTypes1(valueFlags1); + } - if (scenarioInfo->allowTeamResourceSharing == true) { - valueFlags1 |= ft1_allow_shared_team_resources; - gameSettings->setFlagTypes1(valueFlags1); - } else { - valueFlags1 &= ~ft1_allow_shared_team_resources; - gameSettings->setFlagTypes1(valueFlags1); - } + if (scenarioInfo->allowTeamResourceSharing == true) { + valueFlags1 |= ft1_allow_shared_team_resources; + gameSettings->setFlagTypes1(valueFlags1); + } else { + valueFlags1 &= ~ft1_allow_shared_team_resources; + gameSettings->setFlagTypes1(valueFlags1); + } - gameSettings->setPathFinderType(static_cast < PathFinderType > - (Config:: - getInstance().getInt - ("ScenarioPathFinderType", - intToStr(pfBasic).c_str()))); - } + gameSettings->setPathFinderType(static_cast + (Config:: + getInstance().getInt + ("ScenarioPathFinderType", + intToStr(pfBasic).c_str()))); + } - } + } } //end namespace diff --git a/source/glest_game/world/scenario.h b/source/glest_game/world/scenario.h index 070818917..9aaf3dd4a 100644 --- a/source/glest_game/world/scenario.h +++ b/source/glest_game/world/scenario.h @@ -44,149 +44,150 @@ using Shared::Xml::XmlNode; using namespace Shared::Util; namespace Glest { - namespace Game { + namespace Game { - enum Difficulty { - dVeryEasy, - dEasy, - dMedium, - dHard, - dVeryHard, - dInsane - }; + enum Difficulty { + dVeryEasy, + dEasy, + dMedium, + dHard, + dVeryHard, + dInsane + }; - class ScenarioInfo { + class ScenarioInfo { - public: - ScenarioInfo() { - difficulty = 0; - for (unsigned int i = 0; - i < (unsigned int) GameConstants::maxPlayers; ++i) { - factionControls[i] = ctClosed; - teams[i] = 0; - factionTypeNames[i] = ""; - resourceMultipliers[i] = 0; - } mapName = ""; - tilesetName = ""; - techTreeName = ""; + public: + ScenarioInfo() { + difficulty = 0; + for (unsigned int i = 0; + i < (unsigned int) GameConstants::maxPlayers; ++i) { + factionControls[i] = ctClosed; + teams[i] = 0; + factionTypeNames[i] = ""; + resourceMultipliers[i] = 0; + } mapName = ""; + tilesetName = ""; + techTreeName = ""; - defaultUnits = false; - defaultResources = false; - defaultVictoryConditions = false; + defaultUnits = false; + defaultResources = false; + defaultVictoryConditions = false; - desc = ""; + desc = ""; - fogOfWar = false; - fogOfWar_exploredFlag = false; + fogOfWar = false; + fogOfWar_exploredFlag = false; - allowTeamUnitSharing = false; - allowTeamResourceSharing = false; + allowTeamUnitSharing = false; + allowTeamResourceSharing = false; - file = ""; - name = ""; - namei18n = ""; - } int difficulty; - ControlType factionControls[GameConstants::maxPlayers]; - int teams[GameConstants::maxPlayers]; - string factionTypeNames[GameConstants::maxPlayers]; - float resourceMultipliers[GameConstants::maxPlayers]; + file = ""; + name = ""; + namei18n = ""; + } int difficulty; + ControlType factionControls[GameConstants::maxPlayers]; + int teams[GameConstants::maxPlayers]; + string factionTypeNames[GameConstants::maxPlayers]; + float resourceMultipliers[GameConstants::maxPlayers]; - string mapName; - string tilesetName; - string techTreeName; + string mapName; + string tilesetName; + string techTreeName; - bool defaultUnits; - bool defaultResources; - bool defaultVictoryConditions; + bool defaultUnits; + bool defaultResources; + bool defaultVictoryConditions; - string desc; + string desc; - bool fogOfWar; - bool fogOfWar_exploredFlag; + bool fogOfWar; + bool fogOfWar_exploredFlag; - bool allowTeamUnitSharing; - bool allowTeamResourceSharing; + bool allowTeamUnitSharing; + bool allowTeamResourceSharing; - string file; - string name; - string namei18n; - }; + string file; + string name; + string namei18n; + }; -// ===================================================== -// class Script -// ===================================================== + // ===================================================== + // class Script + // ===================================================== - class Script { - private: - string name; - string code; + class Script { + private: + string name; + string code; - public: - Script(const string & name, const string & code) { - this->name = name; - this->code = code; - } const string & getName() const { - return name; - } - const string & getCode() const { - return code; - } - }; + public: + Script(const string & name, const string & code) { + this->name = name; + this->code = code; + } const string & getName() const { + return name; + } + const string & getCode() const { + return code; + } + }; -// ===================================================== -// class Scenario -// ===================================================== + // ===================================================== + // class Scenario + // ===================================================== - class Scenario { - private: - typedef pair < string, string > NameScriptPair; - typedef vector < Script > Scripts; + class Scenario { + private: + typedef pair < string, string > NameScriptPair; + typedef vector < Script > Scripts; - ScenarioInfo info; - Scripts scripts; - Checksum checksumValue; + ScenarioInfo info; + Scripts scripts; + Checksum checksumValue; - public: - ~Scenario(); - Checksum load(const string & path); - Checksum *getChecksumValue() { - return &checksumValue; - } - int getScriptCount() const { - return (int) scripts.size(); - } const Script *getScript(int i) const { - return &scripts[i]; - } - ScenarioInfo getInfo() const { - return info; - } - static bool isGameTutorial(string path); - static string getScenarioPath(const vector < string > dir, - const string & scenarioName, - bool getMatchingRootScenarioPathOnly = - false); - static string getScenarioPath(const string & dir, - const string & scenarioName); - static int getScenarioPathIndex(const vector < string > dirList, - const string & scenarioName); - static string getScenarioDir(const vector < string > dir, - const string & scenarioName); + public: + ~Scenario(); + Checksum load(const string & path); + Checksum *getChecksumValue() { + return &checksumValue; + } + int getScriptCount() const { + return (int) scripts.size(); + } const Script *getScript(int i) const { + return &scripts[i]; + } + ScenarioInfo getInfo() const { + return info; + } + static bool isGameTutorial(string path); + static string getScenarioPath(const vector < string > dir, + const string & scenarioName, + bool getMatchingRootScenarioPathOnly = + false); + static string getScenarioPath(const string & dir, + const string & scenarioName); + static int getScenarioPathIndex(const vector < string > dirList, + const string & scenarioName); + static string getScenarioDir(const vector < string > dir, + const string & scenarioName); - static bool loadScenarioInfo(string file, - ScenarioInfo * scenarioInfo, - bool isTutorial); - static ControlType strToControllerType(const string & str); - static string controllerTypeToStr(const ControlType & ct); + static bool loadScenarioInfo(string file, + ScenarioInfo * scenarioInfo, + bool isTutorial); + static ControlType strToControllerType(const string & str); + static string controllerTypeToStr(const ControlType & ct); - static void loadGameSettings(const vector < string > &dirList, - const ScenarioInfo * scenarioInfo, - GameSettings * gameSettings, - string scenarioDescription); + static void loadGameSettings(const vector < string > &dirList, + const ScenarioInfo * scenarioInfo, + GameSettings * gameSettings, + string scenarioDescription); - private: - string getFunctionName(const XmlNode * scriptNode); - }; + private: + string getFunctionName(const XmlNode * scriptNode); + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/world/surface_atlas.cpp b/source/glest_game/world/surface_atlas.cpp index f8c66f6ac..af737fe88 100644 --- a/source/glest_game/world/surface_atlas.cpp +++ b/source/glest_game/world/surface_atlas.cpp @@ -23,121 +23,118 @@ using namespace std; using namespace Shared::Util; using namespace Shared::Graphics; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class PixmapInfo -// ===================================================== + // ===================================================== + // class PixmapInfo + // ===================================================== -SurfaceInfo::SurfaceInfo(const Pixmap2D *lu, const Pixmap2D *ru, const Pixmap2D *ld, - const Pixmap2D *rd) { - this->leftDown= ld; - this->leftUp= lu; - this->rightDown= rd; - this->rightUp= ru; - center= NULL; - texture=NULL; + SurfaceInfo::SurfaceInfo(const Pixmap2D *lu, const Pixmap2D *ru, const Pixmap2D *ld, + const Pixmap2D *rd) { + this->leftDown = ld; + this->leftUp = lu; + this->rightDown = rd; + this->rightUp = ru; + center = NULL; + texture = NULL; -} - -SurfaceInfo::SurfaceInfo(const Pixmap2D *center) { - this->leftDown= NULL; - this->leftUp= NULL; - this->rightDown= NULL; - this->rightUp= NULL; - this->center= center; - texture=NULL; -} - -bool SurfaceInfo::operator==(const SurfaceInfo &si) const { - return - this->center == si.getCenter() && - this->leftDown == si.getLeftDown() && - this->leftUp == si.getLeftUp() && - this->rightDown == si.getRightDown() && - this->rightUp == si.getRightUp(); -} - -// =============================== -// class SurfaceAtlas -// =============================== - -SurfaceAtlas::SurfaceAtlas() { - surfaceSize= -1; -} - -void SurfaceAtlas::addSurface(SurfaceInfo *si) { - if(si == NULL) { - throw megaglest_runtime_error("Bad surface info (NULL)"); - } - - //check dimensions - if(si->getCenter() != NULL){ - checkDimensions(si->getCenter()); - } - else{ - checkDimensions(si->getLeftUp()); - checkDimensions(si->getLeftDown()); - checkDimensions(si->getRightUp()); - checkDimensions(si->getRightDown()); - } - - //add info - SurfaceInfos::iterator it = find(surfaceInfos.begin(), surfaceInfos.end(), *si); - if(it == surfaceInfos.end()) { - //add new texture - Texture2D *t= Renderer::getInstance().newTexture2D(rsGame); - if(t) { - //if(t == NULL) { - // throw megaglest_runtime_error("Could not create new texture (NULL)"); - //} - t->setWrapMode(Texture::wmClampToEdge); - t->getPixmap()->init(surfaceSize, surfaceSize, 3); } - - si->setCoord(Vec2f(0.f, 0.f)); - si->setTexture(t); - surfaceInfos.push_back(*si); - - //copy texture to pixmap - if(si->getCenter() != NULL) { - if(t) { - t->getPixmap()->copy(si->getCenter()); + + SurfaceInfo::SurfaceInfo(const Pixmap2D *center) { + this->leftDown = NULL; + this->leftUp = NULL; + this->rightDown = NULL; + this->rightUp = NULL; + this->center = center; + texture = NULL; + } + + bool SurfaceInfo::operator==(const SurfaceInfo &si) const { + return + this->center == si.getCenter() && + this->leftDown == si.getLeftDown() && + this->leftUp == si.getLeftUp() && + this->rightDown == si.getRightDown() && + this->rightUp == si.getRightUp(); + } + + // =============================== + // class SurfaceAtlas + // =============================== + + SurfaceAtlas::SurfaceAtlas() { + surfaceSize = -1; + } + + void SurfaceAtlas::addSurface(SurfaceInfo *si) { + if (si == NULL) { + throw megaglest_runtime_error("Bad surface info (NULL)"); + } + + //check dimensions + if (si->getCenter() != NULL) { + checkDimensions(si->getCenter()); + } else { + checkDimensions(si->getLeftUp()); + checkDimensions(si->getLeftDown()); + checkDimensions(si->getRightUp()); + checkDimensions(si->getRightDown()); + } + + //add info + SurfaceInfos::iterator it = find(surfaceInfos.begin(), surfaceInfos.end(), *si); + if (it == surfaceInfos.end()) { + //add new texture + Texture2D *t = Renderer::getInstance().newTexture2D(rsGame); + if (t) { + //if(t == NULL) { + // throw megaglest_runtime_error("Could not create new texture (NULL)"); + //} + t->setWrapMode(Texture::wmClampToEdge); + t->getPixmap()->init(surfaceSize, surfaceSize, 3); + } + + si->setCoord(Vec2f(0.f, 0.f)); + si->setTexture(t); + surfaceInfos.push_back(*si); + + //copy texture to pixmap + if (si->getCenter() != NULL) { + if (t) { + t->getPixmap()->copy(si->getCenter()); + } + } else { + if (t) { + t->getPixmap()->splat(si->getLeftUp(), si->getRightUp(), si->getLeftDown(), si->getRightDown()); + } + } + } else { + si->setCoord(it->getCoord()); + si->setTexture(it->getTexture()); } } - else { - if(t) { - t->getPixmap()->splat(si->getLeftUp(), si->getRightUp(), si->getLeftDown(), si->getRightDown()); + + float SurfaceAtlas::getCoordStep() const { + return 1.f; + } + + void SurfaceAtlas::checkDimensions(const Pixmap2D *p) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + if (p == NULL) { + throw megaglest_runtime_error("Bad surface texture pixmap (NULL)"); + } else if (surfaceSize == -1) { + surfaceSize = p->getW(); + //printf("Setting surfaceSize = %d for pixmap [%s]\n",surfaceSize,p->getPath().c_str()); + } else if (p->getW() != surfaceSize || p->getH() != surfaceSize) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Bad surface texture dimensions, expected surfaceSize = %d, texture w = %d, h = %d", surfaceSize, p->getW(), p->getH()); + throw megaglest_runtime_error(szBuf); } } - } - else{ - si->setCoord(it->getCoord()); - si->setTexture(it->getTexture()); - } -} -float SurfaceAtlas::getCoordStep() const { - return 1.f; -} - -void SurfaceAtlas::checkDimensions(const Pixmap2D *p) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; } - - if(p == NULL) { - throw megaglest_runtime_error("Bad surface texture pixmap (NULL)"); - } - else if(surfaceSize == -1) { - surfaceSize= p->getW(); - //printf("Setting surfaceSize = %d for pixmap [%s]\n",surfaceSize,p->getPath().c_str()); - } - else if(p->getW() != surfaceSize || p->getH() != surfaceSize) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Bad surface texture dimensions, expected surfaceSize = %d, texture w = %d, h = %d",surfaceSize,p->getW(),p->getH()); - throw megaglest_runtime_error(szBuf); - } -} - -}}//end namespace +}//end namespace diff --git a/source/glest_game/world/surface_atlas.h b/source/glest_game/world/surface_atlas.h index 0250c1a91..6257d5eb3 100644 --- a/source/glest_game/world/surface_atlas.h +++ b/source/glest_game/world/surface_atlas.h @@ -13,8 +13,8 @@ #define _GLEST_GAME_SURFACEATLAS_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -30,63 +30,83 @@ using Shared::Graphics::Texture2D; using Shared::Graphics::Vec2i; using Shared::Graphics::Vec2f; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class SurfaceInfo -// ===================================================== + // ===================================================== + // class SurfaceInfo + // ===================================================== -class SurfaceInfo{ -private: - const Pixmap2D *center; - const Pixmap2D *leftUp; - const Pixmap2D *rightUp; - const Pixmap2D *leftDown; - const Pixmap2D *rightDown; - Vec2f coord; - const Texture2D *texture; + class SurfaceInfo { + private: + const Pixmap2D *center; + const Pixmap2D *leftUp; + const Pixmap2D *rightUp; + const Pixmap2D *leftDown; + const Pixmap2D *rightDown; + Vec2f coord; + const Texture2D *texture; -public: - explicit SurfaceInfo(const Pixmap2D *center); - SurfaceInfo(const Pixmap2D *lu, const Pixmap2D *ru, const Pixmap2D *ld, const Pixmap2D *rd); - bool operator==(const SurfaceInfo &si) const; + public: + explicit SurfaceInfo(const Pixmap2D *center); + SurfaceInfo(const Pixmap2D *lu, const Pixmap2D *ru, const Pixmap2D *ld, const Pixmap2D *rd); + bool operator==(const SurfaceInfo &si) const; - inline const Pixmap2D *getCenter() const {return center;} - inline const Pixmap2D *getLeftUp() const {return leftUp;} - inline const Pixmap2D *getRightUp() const {return rightUp;} - inline const Pixmap2D *getLeftDown() const {return leftDown;} - inline const Pixmap2D *getRightDown() const {return rightDown;} - inline const Vec2f &getCoord() const {return coord;} - inline const Texture2D *getTexture() const {return texture;} + inline const Pixmap2D *getCenter() const { + return center; + } + inline const Pixmap2D *getLeftUp() const { + return leftUp; + } + inline const Pixmap2D *getRightUp() const { + return rightUp; + } + inline const Pixmap2D *getLeftDown() const { + return leftDown; + } + inline const Pixmap2D *getRightDown() const { + return rightDown; + } + inline const Vec2f &getCoord() const { + return coord; + } + inline const Texture2D *getTexture() const { + return texture; + } - inline void setCoord(const Vec2f &coord) {this->coord= coord;} - inline void setTexture(const Texture2D *texture) {this->texture= texture;} -}; + inline void setCoord(const Vec2f &coord) { + this->coord = coord; + } + inline void setTexture(const Texture2D *texture) { + this->texture = texture; + } + }; -// ===================================================== -// class SurfaceAtlas -// -/// Holds all surface textures for a given Tileset -// ===================================================== + // ===================================================== + // class SurfaceAtlas + // + /// Holds all surface textures for a given Tileset + // ===================================================== -class SurfaceAtlas{ -private: - typedef vector SurfaceInfos; + class SurfaceAtlas { + private: + typedef vector SurfaceInfos; -private: - SurfaceInfos surfaceInfos; - int surfaceSize; + private: + SurfaceInfos surfaceInfos; + int surfaceSize; -public: - SurfaceAtlas(); + public: + SurfaceAtlas(); - void addSurface(SurfaceInfo *si); - float getCoordStep() const; + void addSurface(SurfaceInfo *si); + float getCoordStep() const; -private: - void checkDimensions(const Pixmap2D *p); -}; + private: + void checkDimensions(const Pixmap2D *p); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/glest_game/world/tileset.cpp b/source/glest_game/world/tileset.cpp index 5721d3081..be9a628ec 100644 --- a/source/glest_game/world/tileset.cpp +++ b/source/glest_game/world/tileset.cpp @@ -27,543 +27,532 @@ using namespace Shared::Util; using namespace Shared::Xml; using namespace Shared::Graphics; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -const float Tileset::standardAirHeight= 5.0f; -const float Tileset::standardShadowIntensity= 0.2f; -// ===================================================== -// class AmbientSounds -// ===================================================== + const float Tileset::standardAirHeight = 5.0f; + const float Tileset::standardShadowIntensity = 0.2f; + // ===================================================== + // class AmbientSounds + // ===================================================== -void AmbientSounds::load(const string &dir, const XmlNode *xmlNode, - std::map > > &loadedFileList, string parentLoader) { - string path=""; + void AmbientSounds::load(const string &dir, const XmlNode *xmlNode, + std::map > > &loadedFileList, string parentLoader) { + string path = ""; - //day - const XmlNode *dayNode= xmlNode->getChild("day-sound"); - enabledDay= dayNode->getAttribute("enabled")->getBoolValue(); - if(enabledDay) { - string currentPath = dir; - endPathWithSlash(currentPath); + //day + const XmlNode *dayNode = xmlNode->getChild("day-sound"); + enabledDay = dayNode->getAttribute("enabled")->getBoolValue(); + if (enabledDay) { + string currentPath = dir; + endPathWithSlash(currentPath); - path= dayNode->getAttribute("path")->getRestrictedValue(currentPath); - day.open(path); - loadedFileList[path].push_back(make_pair(parentLoader,dayNode->getAttribute("path")->getRestrictedValue())); + path = dayNode->getAttribute("path")->getRestrictedValue(currentPath); + day.open(path); + loadedFileList[path].push_back(make_pair(parentLoader, dayNode->getAttribute("path")->getRestrictedValue())); - alwaysPlayDay= dayNode->getAttribute("play-always")->getBoolValue(); - } - - //night - const XmlNode *nightNode= xmlNode->getChild("night-sound"); - enabledNight= nightNode->getAttribute("enabled")->getBoolValue(); - if(enabledNight) { - string currentPath = dir; - endPathWithSlash(currentPath); - - path= nightNode->getAttribute("path")->getRestrictedValue(currentPath); - night.open(path); - loadedFileList[path].push_back(make_pair(parentLoader,nightNode->getAttribute("path")->getRestrictedValue())); - - alwaysPlayNight= nightNode->getAttribute("play-always")->getBoolValue(); - } - - //rain - const XmlNode *rainNode= xmlNode->getChild("rain-sound"); - enabledRain= rainNode->getAttribute("enabled")->getBoolValue(); - if(enabledRain) { - string currentPath = dir; - endPathWithSlash(currentPath); - - path= rainNode->getAttribute("path")->getRestrictedValue(currentPath); - rain.open(path); - loadedFileList[path].push_back(make_pair(parentLoader,rainNode->getAttribute("path")->getRestrictedValue())); - } - - //snow - const XmlNode *snowNode= xmlNode->getChild("snow-sound"); - enabledSnow= snowNode->getAttribute("enabled")->getBoolValue(); - if(enabledSnow) { - string currentPath = dir; - endPathWithSlash(currentPath); - - path= snowNode->getAttribute("path")->getRestrictedValue(currentPath); - snow.open(path); - loadedFileList[path].push_back(make_pair(parentLoader,snowNode->getAttribute("path")->getRestrictedValue())); - } - - //dayStart - const XmlNode *dayStartNode= xmlNode->getChild("day-start-sound"); - enabledDayStart= dayStartNode->getAttribute("enabled")->getBoolValue(); - if(enabledDayStart) { - string currentPath = dir; - endPathWithSlash(currentPath); - - path= dayStartNode->getAttribute("path")->getRestrictedValue(currentPath); - dayStart.load(path); - loadedFileList[path].push_back(make_pair(parentLoader,dayStartNode->getAttribute("path")->getRestrictedValue())); - } - - //nightStart - const XmlNode *nightStartNode= xmlNode->getChild("night-start-sound"); - enabledNightStart= nightStartNode->getAttribute("enabled")->getBoolValue(); - if(enabledNightStart) { - string currentPath = dir; - endPathWithSlash(currentPath); - - path= nightStartNode->getAttribute("path")->getRestrictedValue(currentPath); - nightStart.load(path); - loadedFileList[path].push_back(make_pair(parentLoader,nightStartNode->getAttribute("path")->getRestrictedValue())); - } -} - -// ===================================================== -// class Tileset -// ===================================================== - -Checksum Tileset::loadTileset(const vector pathList, const string &tilesetName, - Checksum* checksum, std::map > > &loadedFileList) { - Checksum tilesetChecksum; - - bool found = false; - for(int idx = 0; idx < (int)pathList.size(); idx++) { - string currentPath = pathList[idx]; - endPathWithSlash(currentPath); - string path = currentPath + tilesetName; - if(isdir(path.c_str()) == true) { - load(path, checksum, &tilesetChecksum, loadedFileList); - found = true; - break; - } - } - if(found == false) { - throw megaglest_runtime_error("Error could not find tileset [" + tilesetName + "]\n",true); - - } - return tilesetChecksum; -} - - -void Tileset::load(const string &dir, Checksum *checksum, Checksum *tilesetChecksum, - std::map > > &loadedFileList) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - random.init(time(NULL)); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - string name= lastDir(dir); - tileset_name = name; - string currentPath = dir; - endPathWithSlash(currentPath); - string path= currentPath + name + ".xml"; - string sourceXMLFile = path; - - checksum->addFile(path); - tilesetChecksum->addFile(path); - checksumValue.addFile(path); - - try { - char szBuf[8096]=""; - snprintf(szBuf,8096,Lang::getInstance().getString("LogScreenGameLoadingTileset","",true).c_str(),formatString(name).c_str()); - Logger::getInstance().add(szBuf, true); - - Renderer &renderer= Renderer::getInstance(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //printf("About to load tileset [%s]\n",path.c_str()); - //parse xml - XmlTree xmlTree; - xmlTree.load(path,Properties::getTagReplacementValues()); - loadedFileList[path].push_back(make_pair(currentPath,currentPath)); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - const XmlNode *tilesetNode= xmlTree.getRootNode(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //surfaces - const XmlNode *surfacesNode= tilesetNode->getChild("surfaces"); - int partsize= 0; - for(int i=0; i < surfCount; ++i) { - - const XmlNode *surfaceNode; - if(surfacesNode->hasChildAtIndex("surface",i)){ - surfaceNode= surfacesNode->getChild("surface", i); - } - else { - // cliff texture does not exist, use texture 2 instead - surfaceNode= surfacesNode->getChild("surface", 2); + alwaysPlayDay = dayNode->getAttribute("play-always")->getBoolValue(); } - if(surfaceNode->hasAttribute("partsize")){ - partsize=surfaceNode->getAttribute("partsize",true)->getIntValue(); - } - else{ - partsize=0; + //night + const XmlNode *nightNode = xmlNode->getChild("night-sound"); + enabledNight = nightNode->getAttribute("enabled")->getBoolValue(); + if (enabledNight) { + string currentPath = dir; + endPathWithSlash(currentPath); + + path = nightNode->getAttribute("path")->getRestrictedValue(currentPath); + night.open(path); + loadedFileList[path].push_back(make_pair(parentLoader, nightNode->getAttribute("path")->getRestrictedValue())); + + alwaysPlayNight = nightNode->getAttribute("play-always")->getBoolValue(); } - if(partsize==0){ - int childCount= (int)surfaceNode->getChildCount(); - surfPixmaps[i].resize(childCount); - surfProbs[i].resize(childCount); + //rain + const XmlNode *rainNode = xmlNode->getChild("rain-sound"); + enabledRain = rainNode->getAttribute("enabled")->getBoolValue(); + if (enabledRain) { + string currentPath = dir; + endPathWithSlash(currentPath); - for(int j = 0; j < childCount; ++j) { - surfPixmaps[i][j] = NULL; - } - - for(int j = 0; j < childCount; ++j) { - const XmlNode *textureNode= surfaceNode->getChild("texture", j); - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - surfPixmaps[i][j] = new Pixmap2D(); - surfPixmaps[i][j]->init(3); - surfPixmaps[i][j]->load(textureNode->getAttribute("path")->getRestrictedValue(currentPath)); - } - loadedFileList[textureNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(sourceXMLFile,textureNode->getAttribute("path")->getRestrictedValue())); - - surfProbs[i][j]= textureNode->getAttribute("prob")->getFloatValue(); - } + path = rainNode->getAttribute("path")->getRestrictedValue(currentPath); + rain.open(path); + loadedFileList[path].push_back(make_pair(parentLoader, rainNode->getAttribute("path")->getRestrictedValue())); } - else { - // read single big texture and cut it into pieces - const XmlNode *textureNode= surfaceNode->getChild("texture", 0); - // There is no way to figure out parts without loading the texture - // unfortunately we must load it even for headless server - // to get width and height - bool switchOffNonGraphicalModeEnabled = GlobalStaticFlags::getIsNonGraphicalModeEnabled(); - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - GlobalStaticFlags::setIsNonGraphicalModeEnabled(false); - } + //snow + const XmlNode *snowNode = xmlNode->getChild("snow-sound"); + enabledSnow = snowNode->getAttribute("enabled")->getBoolValue(); + if (enabledSnow) { + string currentPath = dir; + endPathWithSlash(currentPath); - string exceptionError = ""; - Pixmap2D *pixmap = NULL; - int width = 0; - int height = 0; + path = snowNode->getAttribute("path")->getRestrictedValue(currentPath); + snow.open(path); + loadedFileList[path].push_back(make_pair(parentLoader, snowNode->getAttribute("path")->getRestrictedValue())); + } - try { - pixmap=new Pixmap2D(); - pixmap->init(3); - pixmap->load(textureNode->getAttribute("path")->getRestrictedValue(currentPath)); - loadedFileList[textureNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(sourceXMLFile,textureNode->getAttribute("path")->getRestrictedValue())); + //dayStart + const XmlNode *dayStartNode = xmlNode->getChild("day-start-sound"); + enabledDayStart = dayStartNode->getAttribute("enabled")->getBoolValue(); + if (enabledDayStart) { + string currentPath = dir; + endPathWithSlash(currentPath); - width = pixmap->getW(); - height = pixmap->getW(); - } - catch(megaglest_runtime_error& ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - throw megaglest_runtime_error("Error loading tileset: "+ path + "\nMessage: " + ex.what(),!ex.wantStackTrace() ); - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); + path = dayStartNode->getAttribute("path")->getRestrictedValue(currentPath); + dayStart.load(path); + loadedFileList[path].push_back(make_pair(parentLoader, dayStartNode->getAttribute("path")->getRestrictedValue())); + } - exceptionError = "Error: " + path + "\n" + ex.what(); - } + //nightStart + const XmlNode *nightStartNode = xmlNode->getChild("night-start-sound"); + enabledNightStart = nightStartNode->getAttribute("enabled")->getBoolValue(); + if (enabledNightStart) { + string currentPath = dir; + endPathWithSlash(currentPath); - if(switchOffNonGraphicalModeEnabled == true) { - GlobalStaticFlags::setIsNonGraphicalModeEnabled(true); - - delete pixmap; - pixmap = NULL; - } - - if(exceptionError != "") { - throw megaglest_runtime_error(exceptionError.c_str()); - } - - if(width != height) { - throw megaglest_runtime_error("width != height"); - } - if(width % 64 != 0) { - throw megaglest_runtime_error("width % 64 != 0"); - } - if(width % partsize != 0) { - throw megaglest_runtime_error("width % partsize != 0"); - } - - int parts=width/partsize; - int numberOfPieces=parts*parts; - partsArray[i]=parts; - surfPixmaps[i].resize(numberOfPieces); - surfProbs[i].resize(numberOfPieces); - int j=0; - for(int x = 0; x < parts; ++x) { - for(int y = 0; y < parts; ++y) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - surfPixmaps[i][j] = new Pixmap2D(); - surfPixmaps[i][j]->init(partsize,partsize,3); - surfPixmaps[i][j]->copyImagePart(x*partsize,y*partsize,pixmap); - } - surfProbs[i][j]=-1; - j++; - } - } + path = nightStartNode->getAttribute("path")->getRestrictedValue(currentPath); + nightStart.load(path); + loadedFileList[path].push_back(make_pair(parentLoader, nightStartNode->getAttribute("path")->getRestrictedValue())); } } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + // ===================================================== + // class Tileset + // ===================================================== - //object models - const XmlNode *objectsNode= tilesetNode->getChild("objects"); - for(int i=0; igetChild("object", i); - int childCount= (int)objectNode->getChildCount(); + Checksum Tileset::loadTileset(const vector pathList, const string &tilesetName, + Checksum* checksum, std::map > > &loadedFileList) { + Checksum tilesetChecksum; - int objectHeight = 0; - bool walkable = objectNode->getAttribute("walkable")->getBoolValue(); - if(walkable == false) { - const XmlAttribute *heightAttribute = objectNode->getAttribute("height",false); - if(heightAttribute != NULL) { - objectHeight = heightAttribute->getIntValue(); - } - } - - objectTypes[i].init(childCount, i, walkable,objectHeight); - for(int j=0; jgetChild("model", j); - const XmlAttribute *pathAttribute= modelNode->getAttribute("path"); - TilesetModelType* tmt=objectTypes[i].loadModel(pathAttribute->getRestrictedValue(currentPath),&loadedFileList, sourceXMLFile); - loadedFileList[pathAttribute->getRestrictedValue(currentPath)].push_back(make_pair(sourceXMLFile,pathAttribute->getRestrictedValue())); - - if(modelNode->hasAttribute("anim-speed") == true) { - int animSpeed= modelNode->getAttribute("anim-speed")->getIntValue(); - tmt->setAnimSpeed(animSpeed); - } - - if(modelNode->hasChild("particles")){ - const XmlNode *particleNode= modelNode->getChild("particles"); - bool particleEnabled= particleNode->getAttribute("value")->getBoolValue(); - if(particleEnabled){ - for(int k=0; k < (int)particleNode->getChildCount(); ++k){ - const XmlNode *particleFileNode= particleNode->getChild("particle-file", k); - string path= particleFileNode->getAttribute("path")->getRestrictedValue(); - ObjectParticleSystemType *objectParticleSystemType= new ObjectParticleSystemType(); - objectParticleSystemType->load(particleFileNode, dir, currentPath + path, - &Renderer::getInstance(), loadedFileList, sourceXMLFile,""); - loadedFileList[currentPath + path].push_back(make_pair(sourceXMLFile,particleFileNode->getAttribute("path")->getRestrictedValue())); - - tmt->addParticleSystem(objectParticleSystemType); - } - } - } - - //rotationAllowed - if(modelNode->hasAttribute("rotationAllowed") == true) { - tmt->setRotationAllowed(modelNode->getAttribute("rotationAllowed")->getBoolValue()); - } - else if(modelNode->hasChild("rotationAllowed")){ - const XmlNode *rotationAllowedNode= modelNode->getChild("rotationAllowed"); - tmt->setRotationAllowed(rotationAllowedNode->getAttribute("value")->getBoolValue()); - } - else{ - tmt->setRotationAllowed(true); - } - //randomPositionEnabled - if(modelNode->hasAttribute("randomPositionEnabled") == true) { - tmt->setRandomPositionEnabled(modelNode->getAttribute("randomPositionEnabled")->getBoolValue()); - } - else{ - tmt->setRandomPositionEnabled(true); - } - - //smoothTwoFrameAnim - if(modelNode->hasAttribute("smoothTwoFrameAnim") == true) { - tmt->setSmoothTwoFrameAnim(modelNode->getAttribute("smoothTwoFrameAnim")->getBoolValue()); - } - else{ - tmt->setSmoothTwoFrameAnim(false); - } - } - } - - // Now free up the pixmap memory - for(int i=0; igetChild("ambient-sounds"), loadedFileList, sourceXMLFile); - - //parameters - const XmlNode *parametersNode= tilesetNode->getChild("parameters"); - - //water - const XmlNode *waterNode= parametersNode->getChild("water"); - waterTex= renderer.newTexture3D(rsGame); - if(waterTex) { - waterTex->setMipmap(false); - waterTex->setWrapMode(Texture::wmRepeat); - } - waterEffects= waterNode->getAttribute("effects")->getBoolValue(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - int waterFrameCount= (int)waterNode->getChildCount(); - if(waterTex) { - waterTex->getPixmap()->init(waterFrameCount, 4); - } - for(int i=0; igetChild("texture", i); - if(waterTex) { - waterTex->getPixmap()->loadSlice(waterFrameNode->getAttribute("path")->getRestrictedValue(currentPath), i); - } - loadedFileList[waterFrameNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(sourceXMLFile,waterFrameNode->getAttribute("path")->getRestrictedValue())); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //fog - const XmlNode *fogNode= parametersNode->getChild("fog"); - fog= fogNode->getAttribute("enabled")->getBoolValue(); - if(fog){ - fogMode= fogNode->getAttribute("mode")->getIntValue(1, 2); - fogDensity= fogNode->getAttribute("density")->getFloatValue(); - fogColor.x= fogNode->getAttribute("color-red")->getFloatValue(0.f, 1.f); - fogColor.y= fogNode->getAttribute("color-green")->getFloatValue(0.f, 1.f); - fogColor.z= fogNode->getAttribute("color-blue")->getFloatValue(0.f, 1.f); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //sun and moon light colors - const XmlNode *sunLightColorNode= parametersNode->getChild("sun-light"); - sunLightColor.x= sunLightColorNode->getAttribute("red")->getFloatValue(); - sunLightColor.y= sunLightColorNode->getAttribute("green")->getFloatValue(); - sunLightColor.z= sunLightColorNode->getAttribute("blue")->getFloatValue(); - - const XmlNode *moonLightColorNode= parametersNode->getChild("moon-light"); - moonLightColor.x= moonLightColorNode->getAttribute("red")->getFloatValue(); - moonLightColor.y= moonLightColorNode->getAttribute("green")->getFloatValue(); - moonLightColor.z= moonLightColorNode->getAttribute("blue")->getFloatValue(); - - if(parametersNode->hasChild("shadow-intensity")) { - const XmlNode *shadowIntenseNode= parametersNode->getChild("shadow-intensity"); - shadowIntensity= shadowIntenseNode->getAttribute("value")->getFloatValue(); - } else { - shadowIntensity=standardShadowIntensity; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //weather - const XmlNode *weatherNode= parametersNode->getChild("weather"); - float sunnyProb= weatherNode->getAttribute("sun")->getFloatValue(0.f, 1.f); - float rainyProb= weatherNode->getAttribute("rain")->getFloatValue(0.f, 1.f) + sunnyProb; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - -#ifdef USE_STREFLOP - float rnd= streflop::fabs(static_cast(random.randRange(-1.f, 1.f))); -#else - float rnd= fabs(random.randRange(-1.f, 1.f)); -#endif - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(rnd < sunnyProb) { - weather= wSunny; - } - else if(rnd < rainyProb) { - weather= wRainy; - } - else { - weather= wSnowy; - } - - //printf("==> Weather is: %d rnd = %f [sun: %f rainyProb: %f]",weather,rnd,sunnyProb,rainyProb); - - //airHeight - if(parametersNode->hasChild("air-height")) { - const XmlNode *node= parametersNode->getChild("air-height"); - airHeight= node->getAttribute("value")->getFloatValue(); - // airHeight should not be lower than default - if( airHeight3*Tileset::standardAirHeight){ - airHeight=3*Tileset::standardAirHeight; - } - } - - - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - } - //Exception handling (conversions and so on); - catch(megaglest_runtime_error& ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - throw megaglest_runtime_error("Error loading tileset: "+ path + "\nMessage: " + ex.what(),!ex.wantStackTrace() ); - } - catch(const exception &e) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what()); - throw megaglest_runtime_error("Error: " + path + "\n" + e.what()); - } - - Lang &lang = Lang::getInstance(); - lang.loadTilesetStrings(name); -} - -Tileset::~Tileset() { - for(int i = 0; i < surfCount; ++i) { - deleteValues(surfPixmaps[i].begin(),surfPixmaps[i].end()); - surfPixmaps[i].clear(); - } - - Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingTileset","",true), true); -} - -const Pixmap2D *Tileset::getSurfPixmap(int type, int var) const{ - int vars= (int)surfPixmaps[type].size(); - return surfPixmaps[type][var % vars]; -} - -void Tileset::addSurfTex(int leftUp, int rightUp, int leftDown, int rightDown, Vec2f &coord, const Texture2D *&texture, int mapX, int mapY) { - //center textures - if(leftUp == rightUp && leftUp == leftDown && leftUp == rightDown) { - //texture variation according to probability - float r= random.randRange(0.f, 1.f); - const Pixmap2D *pixmap = NULL; - - if(surfProbs[leftUp][0] < 0) { - // big textures use coordinates - int parts = partsArray[leftUp]; - pixmap = getSurfPixmap(leftUp, (mapY % parts) * parts + (mapX % parts)); - } - else { - float max= 0.f; - int var= 0; - for(int i=0; i < (int)surfProbs[leftUp].size(); ++i) { - max += surfProbs[leftUp][i]; - if(r <= max) { - var= i; + bool found = false; + for (int idx = 0; idx < (int) pathList.size(); idx++) { + string currentPath = pathList[idx]; + endPathWithSlash(currentPath); + string path = currentPath + tilesetName; + if (isdir(path.c_str()) == true) { + load(path, checksum, &tilesetChecksum, loadedFileList); + found = true; break; } } - pixmap=getSurfPixmap(leftUp, var); + if (found == false) { + throw megaglest_runtime_error("Error could not find tileset [" + tilesetName + "]\n", true); + + } + return tilesetChecksum; } - SurfaceInfo si(pixmap); - surfaceAtlas.addSurface(&si); - coord= si.getCoord(); - // only for 512px printf("coord.x=%f coord.y=%f mapX=%d mapY=%d result=%d\n",coord.x,coord.y,mapX,mapY,(mapY%8)*8+(mapX%8)); - texture= si.getTexture(); - } - //spatted textures - else { - int var= random.randRange(0, transitionVars); - SurfaceInfo si( getSurfPixmap(leftUp, var), - getSurfPixmap(rightUp, var), - getSurfPixmap(leftDown, var), - getSurfPixmap(rightDown, var)); - surfaceAtlas.addSurface(&si); - coord= si.getCoord(); - texture= si.getTexture(); - } -} -}}// end namespace + void Tileset::load(const string &dir, Checksum *checksum, Checksum *tilesetChecksum, + std::map > > &loadedFileList) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + random.init(time(NULL)); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + string name = lastDir(dir); + tileset_name = name; + string currentPath = dir; + endPathWithSlash(currentPath); + string path = currentPath + name + ".xml"; + string sourceXMLFile = path; + + checksum->addFile(path); + tilesetChecksum->addFile(path); + checksumValue.addFile(path); + + try { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, Lang::getInstance().getString("LogScreenGameLoadingTileset", "", true).c_str(), formatString(name).c_str()); + Logger::getInstance().add(szBuf, true); + + Renderer &renderer = Renderer::getInstance(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //printf("About to load tileset [%s]\n",path.c_str()); + //parse xml + XmlTree xmlTree; + xmlTree.load(path, Properties::getTagReplacementValues()); + loadedFileList[path].push_back(make_pair(currentPath, currentPath)); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + const XmlNode *tilesetNode = xmlTree.getRootNode(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //surfaces + const XmlNode *surfacesNode = tilesetNode->getChild("surfaces"); + int partsize = 0; + for (int i = 0; i < surfCount; ++i) { + + const XmlNode *surfaceNode; + if (surfacesNode->hasChildAtIndex("surface", i)) { + surfaceNode = surfacesNode->getChild("surface", i); + } else { + // cliff texture does not exist, use texture 2 instead + surfaceNode = surfacesNode->getChild("surface", 2); + } + + if (surfaceNode->hasAttribute("partsize")) { + partsize = surfaceNode->getAttribute("partsize", true)->getIntValue(); + } else { + partsize = 0; + } + + if (partsize == 0) { + int childCount = (int) surfaceNode->getChildCount(); + surfPixmaps[i].resize(childCount); + surfProbs[i].resize(childCount); + + for (int j = 0; j < childCount; ++j) { + surfPixmaps[i][j] = NULL; + } + + for (int j = 0; j < childCount; ++j) { + const XmlNode *textureNode = surfaceNode->getChild("texture", j); + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + surfPixmaps[i][j] = new Pixmap2D(); + surfPixmaps[i][j]->init(3); + surfPixmaps[i][j]->load(textureNode->getAttribute("path")->getRestrictedValue(currentPath)); + } + loadedFileList[textureNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(sourceXMLFile, textureNode->getAttribute("path")->getRestrictedValue())); + + surfProbs[i][j] = textureNode->getAttribute("prob")->getFloatValue(); + } + } else { + // read single big texture and cut it into pieces + const XmlNode *textureNode = surfaceNode->getChild("texture", 0); + + // There is no way to figure out parts without loading the texture + // unfortunately we must load it even for headless server + // to get width and height + bool switchOffNonGraphicalModeEnabled = GlobalStaticFlags::getIsNonGraphicalModeEnabled(); + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + GlobalStaticFlags::setIsNonGraphicalModeEnabled(false); + } + + string exceptionError = ""; + Pixmap2D *pixmap = NULL; + int width = 0; + int height = 0; + + try { + pixmap = new Pixmap2D(); + pixmap->init(3); + pixmap->load(textureNode->getAttribute("path")->getRestrictedValue(currentPath)); + loadedFileList[textureNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(sourceXMLFile, textureNode->getAttribute("path")->getRestrictedValue())); + + width = pixmap->getW(); + height = pixmap->getW(); + } catch (megaglest_runtime_error& ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + throw megaglest_runtime_error("Error loading tileset: " + path + "\nMessage: " + ex.what(), !ex.wantStackTrace()); + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + + exceptionError = "Error: " + path + "\n" + ex.what(); + } + + if (switchOffNonGraphicalModeEnabled == true) { + GlobalStaticFlags::setIsNonGraphicalModeEnabled(true); + + delete pixmap; + pixmap = NULL; + } + + if (exceptionError != "") { + throw megaglest_runtime_error(exceptionError.c_str()); + } + + if (width != height) { + throw megaglest_runtime_error("width != height"); + } + if (width % 64 != 0) { + throw megaglest_runtime_error("width % 64 != 0"); + } + if (width % partsize != 0) { + throw megaglest_runtime_error("width % partsize != 0"); + } + + int parts = width / partsize; + int numberOfPieces = parts * parts; + partsArray[i] = parts; + surfPixmaps[i].resize(numberOfPieces); + surfProbs[i].resize(numberOfPieces); + int j = 0; + for (int x = 0; x < parts; ++x) { + for (int y = 0; y < parts; ++y) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + surfPixmaps[i][j] = new Pixmap2D(); + surfPixmaps[i][j]->init(partsize, partsize, 3); + surfPixmaps[i][j]->copyImagePart(x*partsize, y*partsize, pixmap); + } + surfProbs[i][j] = -1; + j++; + } + } + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //object models + const XmlNode *objectsNode = tilesetNode->getChild("objects"); + for (int i = 0; i < objCount; ++i) { + const XmlNode *objectNode = objectsNode->getChild("object", i); + int childCount = (int) objectNode->getChildCount(); + + int objectHeight = 0; + bool walkable = objectNode->getAttribute("walkable")->getBoolValue(); + if (walkable == false) { + const XmlAttribute *heightAttribute = objectNode->getAttribute("height", false); + if (heightAttribute != NULL) { + objectHeight = heightAttribute->getIntValue(); + } + } + + objectTypes[i].init(childCount, i, walkable, objectHeight); + for (int j = 0; j < childCount; ++j) { + const XmlNode *modelNode = objectNode->getChild("model", j); + const XmlAttribute *pathAttribute = modelNode->getAttribute("path"); + TilesetModelType* tmt = objectTypes[i].loadModel(pathAttribute->getRestrictedValue(currentPath), &loadedFileList, sourceXMLFile); + loadedFileList[pathAttribute->getRestrictedValue(currentPath)].push_back(make_pair(sourceXMLFile, pathAttribute->getRestrictedValue())); + + if (modelNode->hasAttribute("anim-speed") == true) { + int animSpeed = modelNode->getAttribute("anim-speed")->getIntValue(); + tmt->setAnimSpeed(animSpeed); + } + + if (modelNode->hasChild("particles")) { + const XmlNode *particleNode = modelNode->getChild("particles"); + bool particleEnabled = particleNode->getAttribute("value")->getBoolValue(); + if (particleEnabled) { + for (int k = 0; k < (int) particleNode->getChildCount(); ++k) { + const XmlNode *particleFileNode = particleNode->getChild("particle-file", k); + string path = particleFileNode->getAttribute("path")->getRestrictedValue(); + ObjectParticleSystemType *objectParticleSystemType = new ObjectParticleSystemType(); + objectParticleSystemType->load(particleFileNode, dir, currentPath + path, + &Renderer::getInstance(), loadedFileList, sourceXMLFile, ""); + loadedFileList[currentPath + path].push_back(make_pair(sourceXMLFile, particleFileNode->getAttribute("path")->getRestrictedValue())); + + tmt->addParticleSystem(objectParticleSystemType); + } + } + } + + //rotationAllowed + if (modelNode->hasAttribute("rotationAllowed") == true) { + tmt->setRotationAllowed(modelNode->getAttribute("rotationAllowed")->getBoolValue()); + } else if (modelNode->hasChild("rotationAllowed")) { + const XmlNode *rotationAllowedNode = modelNode->getChild("rotationAllowed"); + tmt->setRotationAllowed(rotationAllowedNode->getAttribute("value")->getBoolValue()); + } else { + tmt->setRotationAllowed(true); + } + //randomPositionEnabled + if (modelNode->hasAttribute("randomPositionEnabled") == true) { + tmt->setRandomPositionEnabled(modelNode->getAttribute("randomPositionEnabled")->getBoolValue()); + } else { + tmt->setRandomPositionEnabled(true); + } + + //smoothTwoFrameAnim + if (modelNode->hasAttribute("smoothTwoFrameAnim") == true) { + tmt->setSmoothTwoFrameAnim(modelNode->getAttribute("smoothTwoFrameAnim")->getBoolValue()); + } else { + tmt->setSmoothTwoFrameAnim(false); + } + } + } + + // Now free up the pixmap memory + for (int i = 0; i < objCount; ++i) { + objectTypes[i].deletePixels(); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //ambient sounds + ambientSounds.load(dir, tilesetNode->getChild("ambient-sounds"), loadedFileList, sourceXMLFile); + + //parameters + const XmlNode *parametersNode = tilesetNode->getChild("parameters"); + + //water + const XmlNode *waterNode = parametersNode->getChild("water"); + waterTex = renderer.newTexture3D(rsGame); + if (waterTex) { + waterTex->setMipmap(false); + waterTex->setWrapMode(Texture::wmRepeat); + } + waterEffects = waterNode->getAttribute("effects")->getBoolValue(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + int waterFrameCount = (int) waterNode->getChildCount(); + if (waterTex) { + waterTex->getPixmap()->init(waterFrameCount, 4); + } + for (int i = 0; i < waterFrameCount; ++i) { + const XmlNode *waterFrameNode = waterNode->getChild("texture", i); + if (waterTex) { + waterTex->getPixmap()->loadSlice(waterFrameNode->getAttribute("path")->getRestrictedValue(currentPath), i); + } + loadedFileList[waterFrameNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(sourceXMLFile, waterFrameNode->getAttribute("path")->getRestrictedValue())); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //fog + const XmlNode *fogNode = parametersNode->getChild("fog"); + fog = fogNode->getAttribute("enabled")->getBoolValue(); + if (fog) { + fogMode = fogNode->getAttribute("mode")->getIntValue(1, 2); + fogDensity = fogNode->getAttribute("density")->getFloatValue(); + fogColor.x = fogNode->getAttribute("color-red")->getFloatValue(0.f, 1.f); + fogColor.y = fogNode->getAttribute("color-green")->getFloatValue(0.f, 1.f); + fogColor.z = fogNode->getAttribute("color-blue")->getFloatValue(0.f, 1.f); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //sun and moon light colors + const XmlNode *sunLightColorNode = parametersNode->getChild("sun-light"); + sunLightColor.x = sunLightColorNode->getAttribute("red")->getFloatValue(); + sunLightColor.y = sunLightColorNode->getAttribute("green")->getFloatValue(); + sunLightColor.z = sunLightColorNode->getAttribute("blue")->getFloatValue(); + + const XmlNode *moonLightColorNode = parametersNode->getChild("moon-light"); + moonLightColor.x = moonLightColorNode->getAttribute("red")->getFloatValue(); + moonLightColor.y = moonLightColorNode->getAttribute("green")->getFloatValue(); + moonLightColor.z = moonLightColorNode->getAttribute("blue")->getFloatValue(); + + if (parametersNode->hasChild("shadow-intensity")) { + const XmlNode *shadowIntenseNode = parametersNode->getChild("shadow-intensity"); + shadowIntensity = shadowIntenseNode->getAttribute("value")->getFloatValue(); + } else { + shadowIntensity = standardShadowIntensity; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //weather + const XmlNode *weatherNode = parametersNode->getChild("weather"); + float sunnyProb = weatherNode->getAttribute("sun")->getFloatValue(0.f, 1.f); + float rainyProb = weatherNode->getAttribute("rain")->getFloatValue(0.f, 1.f) + sunnyProb; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + +#ifdef USE_STREFLOP + float rnd = streflop::fabs(static_cast(random.randRange(-1.f, 1.f))); +#else + float rnd = fabs(random.randRange(-1.f, 1.f)); +#endif + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (rnd < sunnyProb) { + weather = wSunny; + } else if (rnd < rainyProb) { + weather = wRainy; + } else { + weather = wSnowy; + } + + //printf("==> Weather is: %d rnd = %f [sun: %f rainyProb: %f]",weather,rnd,sunnyProb,rainyProb); + + //airHeight + if (parametersNode->hasChild("air-height")) { + const XmlNode *node = parametersNode->getChild("air-height"); + airHeight = node->getAttribute("value")->getFloatValue(); + // airHeight should not be lower than default + if (airHeight < Tileset::standardAirHeight) { + airHeight = standardAirHeight; + } + // airHeight should not be bigger than 3 x default + if (airHeight > 3 * Tileset::standardAirHeight) { + airHeight = 3 * Tileset::standardAirHeight; + } + } + + + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + } + //Exception handling (conversions and so on); + catch (megaglest_runtime_error& ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + throw megaglest_runtime_error("Error loading tileset: " + path + "\nMessage: " + ex.what(), !ex.wantStackTrace()); + } catch (const exception &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, e.what()); + throw megaglest_runtime_error("Error: " + path + "\n" + e.what()); + } + + Lang &lang = Lang::getInstance(); + lang.loadTilesetStrings(name); + } + + Tileset::~Tileset() { + for (int i = 0; i < surfCount; ++i) { + deleteValues(surfPixmaps[i].begin(), surfPixmaps[i].end()); + surfPixmaps[i].clear(); + } + + Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingTileset", "", true), true); + } + + const Pixmap2D *Tileset::getSurfPixmap(int type, int var) const { + int vars = (int) surfPixmaps[type].size(); + return surfPixmaps[type][var % vars]; + } + + void Tileset::addSurfTex(int leftUp, int rightUp, int leftDown, int rightDown, Vec2f &coord, const Texture2D *&texture, int mapX, int mapY) { + //center textures + if (leftUp == rightUp && leftUp == leftDown && leftUp == rightDown) { + //texture variation according to probability + float r = random.randRange(0.f, 1.f); + const Pixmap2D *pixmap = NULL; + + if (surfProbs[leftUp][0] < 0) { + // big textures use coordinates + int parts = partsArray[leftUp]; + pixmap = getSurfPixmap(leftUp, (mapY % parts) * parts + (mapX % parts)); + } else { + float max = 0.f; + int var = 0; + for (int i = 0; i < (int) surfProbs[leftUp].size(); ++i) { + max += surfProbs[leftUp][i]; + if (r <= max) { + var = i; + break; + } + } + pixmap = getSurfPixmap(leftUp, var); + } + SurfaceInfo si(pixmap); + surfaceAtlas.addSurface(&si); + coord = si.getCoord(); + // only for 512px printf("coord.x=%f coord.y=%f mapX=%d mapY=%d result=%d\n",coord.x,coord.y,mapX,mapY,(mapY%8)*8+(mapX%8)); + texture = si.getTexture(); + } + //spatted textures + else { + int var = random.randRange(0, transitionVars); + + SurfaceInfo si(getSurfPixmap(leftUp, var), + getSurfPixmap(rightUp, var), + getSurfPixmap(leftDown, var), + getSurfPixmap(rightDown, var)); + surfaceAtlas.addSurface(&si); + coord = si.getCoord(); + texture = si.getTexture(); + } + } + + } +}// end namespace diff --git a/source/glest_game/world/tileset.h b/source/glest_game/world/tileset.h index c427171c0..1431b8314 100644 --- a/source/glest_game/world/tileset.h +++ b/source/glest_game/world/tileset.h @@ -13,8 +13,8 @@ #define _GLEST_GAME_TILESET_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -27,183 +27,249 @@ #include "checksum.h" #include "leak_dumper.h" -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -using Shared::Xml::XmlNode; -using Shared::Sound::StaticSound; -using Shared::Sound::StrSound; -using Shared::Graphics::Model; -using Shared::Graphics::Vec3f; -using Shared::Graphics::Texture2D; -using Shared::Graphics::Texture3D; -using Shared::Util::RandomGen; -using Shared::Util::Checksum; + using Shared::Xml::XmlNode; + using Shared::Sound::StaticSound; + using Shared::Sound::StrSound; + using Shared::Graphics::Model; + using Shared::Graphics::Vec3f; + using Shared::Graphics::Texture2D; + using Shared::Graphics::Texture3D; + using Shared::Util::RandomGen; + using Shared::Util::Checksum; -using std::map; + using std::map; -enum FogMode{ - fmExp, - fmExp2 -}; + enum FogMode { + fmExp, + fmExp2 + }; -enum Weather{ - wSunny, - wRainy, - wSnowy -}; + enum Weather { + wSunny, + wRainy, + wSnowy + }; -class Renderer; -class SurfaceCell; + class Renderer; + class SurfaceCell; -// ===================================================== -// class AmbientSounds -// ===================================================== + // ===================================================== + // class AmbientSounds + // ===================================================== -class AmbientSounds{ -private: - bool enabledDay; - bool enabledNight; - bool enabledRain; - bool enabledSnow; - bool enabledDayStart; - bool enabledNightStart; - bool alwaysPlayDay; - bool alwaysPlayNight; - StrSound day; - StrSound night; - StrSound rain; - StrSound snow; - StaticSound dayStart; - StaticSound nightStart; + class AmbientSounds { + private: + bool enabledDay; + bool enabledNight; + bool enabledRain; + bool enabledSnow; + bool enabledDayStart; + bool enabledNightStart; + bool alwaysPlayDay; + bool alwaysPlayNight; + StrSound day; + StrSound night; + StrSound rain; + StrSound snow; + StaticSound dayStart; + StaticSound nightStart; + + public: + AmbientSounds() { + enabledDay = false; + enabledNight = false; + enabledRain = false; + enabledSnow = false; + enabledDayStart = false; + enabledNightStart = false; + alwaysPlayDay = false; + alwaysPlayNight = false; + } + + bool isEnabledDay() const { + return enabledDay; + } + bool isEnabledNight() const { + return enabledNight; + } + bool isEnabledRain() const { + return enabledRain; + } + bool isEnabledSnow() const { + return enabledSnow; + } + bool isEnabledDayStart() const { + return enabledDayStart; + } + bool isEnabledNightStart() const { + return enabledNightStart; + } + bool getAlwaysPlayDay() const { + return alwaysPlayDay; + } + bool getAlwaysPlayNight() const { + return alwaysPlayNight; + } + + StrSound *getDay() { + return &day; + } + StrSound *getNight() { + return &night; + } + StrSound *getRain() { + return &rain; + } + StrSound *getSnow() { + return &snow; + } + StaticSound *getDayStart() { + return &dayStart; + } + StaticSound *getNightStart() { + return &nightStart; + } + + void load(const string &dir, const XmlNode *xmlNode, + std::map > > &loadedFileList, string parentLoader); + }; + + // ===================================================== + // class Tileset + // + /// Containt textures, models and parameters for a tileset + // ===================================================== + + class Tileset { + public: + static const int waterTexCount = 1; + static const int surfCount = 6; + static const int objCount = 10; + static const int transitionVars = 2; //number or different transition textures + static const float standardAirHeight; + static const float standardShadowIntensity; + + public: + typedef vector SurfProbs; + typedef vector SurfPixmaps; + + private: + SurfaceAtlas surfaceAtlas; + ObjectType objectTypes[objCount]; + + SurfProbs surfProbs[surfCount]; + SurfPixmaps surfPixmaps[surfCount]; + + int partsArray[surfCount]; + //int partsizes[surfCount]; + + RandomGen random; + Texture3D *waterTex; + bool waterEffects; + bool fog; + int fogMode; + float fogDensity; + Vec3f fogColor; + Vec3f sunLightColor; + Vec3f moonLightColor; + float shadowIntensity; + Weather weather; + float airHeight; + + AmbientSounds ambientSounds; + Checksum checksumValue; + + string tileset_name; + + public: + Tileset() { + waterTex = NULL; + waterEffects = false; + fog = false; + fogMode = 0; + fogDensity = 0.0f; + weather = wSunny; + airHeight = standardAirHeight; + shadowIntensity = standardShadowIntensity; + + for (int index = 0; index < surfCount; ++index) { + partsArray[index] = 0; + } + } + ~Tileset(); + Checksum loadTileset(const vector pathList, const string &tilesetName, + Checksum* checksum, std::map > > &loadedFileList); + void load(const string &dir, Checksum *checksum, Checksum *tilesetChecksum, + std::map > > &loadedFileList); + Checksum * getChecksumValue() { + return &checksumValue; + } + + //get + float getAirHeight()const { + return airHeight; + } + const SurfaceAtlas *getSurfaceAtlas() const { + return &surfaceAtlas; + } + ObjectType *getObjectType(int i) { + return &objectTypes[i]; + } + float getSurfProb(int surf, int var) const { + return surfProbs[surf][var]; + } + Texture3D *getWaterTex() const { + return waterTex; + } + bool getWaterEffects() const { + return waterEffects; + } + bool getFog() const { + return fog; + } + int getFogMode() const { + return fogMode; + } + float getFogDensity() const { + return fogDensity; + } + const Vec3f &getFogColor() const { + return fogColor; + } + const Vec3f &getSunLightColor() const { + return sunLightColor; + } + const Vec3f &getMoonLightColor() const { + return moonLightColor; + } + float getShadowIntense()const { + return shadowIntensity; + } + Weather getWeather() const { + return weather; + } + void setWeather(Weather value) { + weather = value; + } + + //surface textures + const Pixmap2D *getSurfPixmap(int type, int var) const; + void addSurfTex(int leftUp, int rightUp, int leftDown, int rightDown, Vec2f &coord, const Texture2D *&texture, int mapX, int mapY); + + //sounds + AmbientSounds *getAmbientSounds() { + return &ambientSounds; + } + + string getName() const { + return tileset_name; + } + }; -public: - AmbientSounds() { - enabledDay = false; - enabledNight = false; - enabledRain = false; - enabledSnow = false; - enabledDayStart = false; - enabledNightStart = false; - alwaysPlayDay = false; - alwaysPlayNight = false; } - - bool isEnabledDay() const {return enabledDay;} - bool isEnabledNight() const {return enabledNight;} - bool isEnabledRain() const {return enabledRain;} - bool isEnabledSnow() const {return enabledSnow;} - bool isEnabledDayStart() const {return enabledDayStart;} - bool isEnabledNightStart() const {return enabledNightStart;} - bool getAlwaysPlayDay() const {return alwaysPlayDay;} - bool getAlwaysPlayNight() const {return alwaysPlayNight;} - - StrSound *getDay() {return &day;} - StrSound *getNight() {return &night;} - StrSound *getRain() {return &rain;} - StrSound *getSnow() {return &snow;} - StaticSound *getDayStart() {return &dayStart;} - StaticSound *getNightStart() {return &nightStart;} - - void load(const string &dir, const XmlNode *xmlNode, - std::map > > &loadedFileList,string parentLoader); -}; - -// ===================================================== -// class Tileset -// -/// Containt textures, models and parameters for a tileset -// ===================================================== - -class Tileset { -public: - static const int waterTexCount= 1; - static const int surfCount= 6; - static const int objCount= 10; - static const int transitionVars= 2; //number or different transition textures - static const float standardAirHeight; - static const float standardShadowIntensity; - -public: - typedef vector SurfProbs; - typedef vector SurfPixmaps; - -private: - SurfaceAtlas surfaceAtlas; - ObjectType objectTypes[objCount]; - - SurfProbs surfProbs[surfCount]; - SurfPixmaps surfPixmaps[surfCount]; - - int partsArray[surfCount]; - //int partsizes[surfCount]; - - RandomGen random; - Texture3D *waterTex; - bool waterEffects; - bool fog; - int fogMode; - float fogDensity; - Vec3f fogColor; - Vec3f sunLightColor; - Vec3f moonLightColor; - float shadowIntensity; - Weather weather; - float airHeight; - - AmbientSounds ambientSounds; - Checksum checksumValue; - - string tileset_name; - -public: - Tileset() { - waterTex = NULL; - waterEffects = false; - fog = false; - fogMode = 0; - fogDensity = 0.0f; - weather= wSunny; - airHeight= standardAirHeight; - shadowIntensity= standardShadowIntensity; - - for(int index = 0; index < surfCount; ++index) { - partsArray[index] = 0; - } - } - ~Tileset(); - Checksum loadTileset(const vector pathList, const string &tilesetName, - Checksum* checksum, std::map > > &loadedFileList); - void load(const string &dir, Checksum *checksum, Checksum *tilesetChecksum, - std::map > > &loadedFileList); - Checksum * getChecksumValue() { return &checksumValue; } - - //get - float getAirHeight()const {return airHeight;} - const SurfaceAtlas *getSurfaceAtlas() const {return &surfaceAtlas;} - ObjectType *getObjectType(int i) {return &objectTypes[i];} - float getSurfProb(int surf, int var) const {return surfProbs[surf][var];} - Texture3D *getWaterTex() const {return waterTex;} - bool getWaterEffects() const {return waterEffects;} - bool getFog() const {return fog;} - int getFogMode() const {return fogMode;} - float getFogDensity() const {return fogDensity;} - const Vec3f &getFogColor() const {return fogColor;} - const Vec3f &getSunLightColor() const {return sunLightColor;} - const Vec3f &getMoonLightColor() const {return moonLightColor;} - float getShadowIntense()const {return shadowIntensity;} - Weather getWeather() const {return weather;} - void setWeather(Weather value) { weather = value; } - - //surface textures - const Pixmap2D *getSurfPixmap(int type, int var) const; - void addSurfTex(int leftUp, int rightUp, int leftDown, int rightDown, Vec2f &coord, const Texture2D *&texture, int mapX, int mapY); - - //sounds - AmbientSounds *getAmbientSounds() {return &ambientSounds;} - - string getName() const { return tileset_name; } -}; - -}} //end namespace +} //end namespace #endif diff --git a/source/glest_game/world/time_flow.cpp b/source/glest_game/world/time_flow.cpp index 385951489..5e0ef3856 100644 --- a/source/glest_game/world/time_flow.cpp +++ b/source/glest_game/world/time_flow.cpp @@ -20,163 +20,161 @@ using namespace Shared::Util; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class TimeFlow -// ===================================================== + // ===================================================== + // class TimeFlow + // ===================================================== -const float TimeFlow::dusk= 18.f; -const float TimeFlow::dawn= 6.f; + const float TimeFlow::dusk = 18.f; + const float TimeFlow::dawn = 6.f; -TimeFlow::TimeFlow() { - firstTime = false; - tileset = NULL; - time = 0.0f; - lastTime = 0.0f; - timeInc = 0.0f; - //printf("#1a timeInc = %f\n",timeInc); -} - -void TimeFlow::init(Tileset *tileset){ - firstTime= true; - this->tileset= tileset; - time= dawn+1.5f; - lastTime= time; - Config &config= Config::getInstance(); - timeInc= 24.f * (1.f / config.getFloat("DayTime")) / GameConstants::updateFps; - //printf("#1 timeInc = %f\n",timeInc); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] timeInc = %f\n",__FILE__,__FUNCTION__,__LINE__,timeInc); -} - -void TimeFlow::update() { - //printf("START TimeFlow::update() time = %f\n",time); - //update time - time += isDay()? timeInc: timeInc*2; - if(time > 24.f){ - time -= 24.f; - } - - //printf("END TimeFlow::update() time = %f\n",time); - - //sounds - SoundRenderer &soundRenderer= SoundRenderer::getInstance(); - AmbientSounds *ambientSounds= NULL; - if(tileset != NULL) { - ambientSounds = tileset->getAmbientSounds(); - } - - //day - if(lastTime=dawn){ - if(ambientSounds != NULL) { - soundRenderer.stopAmbient(ambientSounds->getNight()); + TimeFlow::TimeFlow() { + firstTime = false; + tileset = NULL; + time = 0.0f; + lastTime = 0.0f; + timeInc = 0.0f; + //printf("#1a timeInc = %f\n",timeInc); } - UnitParticleSystem::isNight=false; - } - UnitParticleSystem::lightColor=computeLightColor(); - if((lastTime=dawn) || firstTime){ - - //day sound - if(ambientSounds != NULL) { - if(ambientSounds->isEnabledDayStart() && !firstTime){ - soundRenderer.playFx(ambientSounds->getDayStart()); + void TimeFlow::init(Tileset *tileset) { + firstTime = true; + this->tileset = tileset; + time = dawn + 1.5f; + lastTime = time; + Config &config = Config::getInstance(); + timeInc = 24.f * (1.f / config.getFloat("DayTime")) / GameConstants::updateFps; + //printf("#1 timeInc = %f\n",timeInc); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d] timeInc = %f\n", __FILE__, __FUNCTION__, __LINE__, timeInc); + } + + void TimeFlow::update() { + //printf("START TimeFlow::update() time = %f\n",time); + //update time + time += isDay() ? timeInc : timeInc * 2; + if (time > 24.f) { + time -= 24.f; } - if(ambientSounds->isEnabledDay()){ - if(ambientSounds->getAlwaysPlayDay() || tileset->getWeather()==wSunny){ - soundRenderer.playAmbient(ambientSounds->getDay()); + + //printf("END TimeFlow::update() time = %f\n",time); + + //sounds + SoundRenderer &soundRenderer = SoundRenderer::getInstance(); + AmbientSounds *ambientSounds = NULL; + if (tileset != NULL) { + ambientSounds = tileset->getAmbientSounds(); + } + + //day + if (lastTime < dawn && time >= dawn) { + if (ambientSounds != NULL) { + soundRenderer.stopAmbient(ambientSounds->getNight()); + } + UnitParticleSystem::isNight = false; + } + UnitParticleSystem::lightColor = computeLightColor(); + + if ((lastTime < dawn && time >= dawn) || firstTime) { + + //day sound + if (ambientSounds != NULL) { + if (ambientSounds->isEnabledDayStart() && !firstTime) { + soundRenderer.playFx(ambientSounds->getDayStart()); + } + if (ambientSounds->isEnabledDay()) { + if (ambientSounds->getAlwaysPlayDay() || tileset->getWeather() == wSunny) { + soundRenderer.playAmbient(ambientSounds->getDay()); + } + } + } + firstTime = false; + } + + //night + if (lastTime < dusk && time >= dusk) { + if (ambientSounds != NULL) { + soundRenderer.stopAmbient(ambientSounds->getDay()); + } + UnitParticleSystem::isNight = true; + } + + if (lastTime < dusk && time >= dusk) { + //night + if (ambientSounds != NULL) { + if (ambientSounds->isEnabledNightStart()) { + soundRenderer.playFx(ambientSounds->getNightStart()); + } + if (ambientSounds->isEnabledNight()) { + if (ambientSounds->getAlwaysPlayNight() || tileset->getWeather() == wSunny) { + soundRenderer.playAmbient(ambientSounds->getNight()); + } + } } } + lastTime = time; } - firstTime= false; - } - //night - if(lastTime=dusk){ - if(ambientSounds != NULL) { - soundRenderer.stopAmbient(ambientSounds->getDay()); - } - UnitParticleSystem::isNight=true; - } + //bool TimeFlow::isAproxTime(float time) const { + // return (this->time>=time) && (this->time=dusk){ - //night - if(ambientSounds != NULL) { - if(ambientSounds->isEnabledNightStart()){ - soundRenderer.playFx(ambientSounds->getNightStart()); - } - if(ambientSounds->isEnabledNight()){ - if(ambientSounds->getAlwaysPlayNight() || tileset->getWeather()==wSunny){ - soundRenderer.playAmbient(ambientSounds->getNight()); + Vec3f TimeFlow::computeLightColor() const { + Vec3f color; + + if (tileset != NULL) { + float time = getTime(); + + const float transition = 2; + const float dayStart = TimeFlow::dawn; + const float dayEnd = TimeFlow::dusk - transition; + const float nightStart = TimeFlow::dusk; + const float nightEnd = TimeFlow::dawn - transition; + + if (time > dayStart && time < dayEnd) { + color = tileset->getSunLightColor(); + } else if (time > nightStart || time < nightEnd) { + color = tileset->getMoonLightColor(); + } else if (time >= dayEnd && time <= nightStart) { + color = tileset->getSunLightColor().lerp((time - dayEnd) / transition, tileset->getMoonLightColor()); + } else if (time >= nightEnd && time <= dayStart) { + color = tileset->getMoonLightColor().lerp((time - nightEnd) / transition, tileset->getSunLightColor()); + } else { + assert(false); + color = tileset->getSunLightColor(); } } + return color; } + + void TimeFlow::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *timeflowNode = rootNode->addChild("TimeFlow"); + + timeflowNode->addAttribute("firstTime", intToStr(firstTime), mapTagReplacements); + // bool firstTime; + // Tileset *tileset; + // float time; + timeflowNode->addAttribute("time", floatToStr(time, 6), mapTagReplacements); + // float lastTime; + timeflowNode->addAttribute("lastTime", floatToStr(lastTime, 6), mapTagReplacements); + // float timeInc; + //printf("#2 timeInc = %f\n",timeInc); + timeflowNode->addAttribute("timeInc", floatToStr(timeInc, 6), mapTagReplacements); + //printf("#3 timeInc = %f\n",timeInc); + } + + void TimeFlow::loadGame(const XmlNode *rootNode) { + const XmlNode *timeflowNode = rootNode->getChild("TimeFlow"); + + firstTime = timeflowNode->getAttribute("firstTime")->getFloatValue() != 0; + time = timeflowNode->getAttribute("time")->getFloatValue(); + lastTime = timeflowNode->getAttribute("lastTime")->getFloatValue(); + timeInc = timeflowNode->getAttribute("timeInc")->getFloatValue(); + //printf("#4 timeInc = %f\n",timeInc); + } + } - lastTime= time; -} - -//bool TimeFlow::isAproxTime(float time) const { -// return (this->time>=time) && (this->timedayStart && timegetSunLightColor(); - } - else if(time>nightStart || timegetMoonLightColor(); - } - else if(time>=dayEnd && time<=nightStart) { - color= tileset->getSunLightColor().lerp((time-dayEnd)/transition, tileset->getMoonLightColor()); - } - else if(time>=nightEnd && time<=dayStart) { - color= tileset->getMoonLightColor().lerp((time-nightEnd)/transition, tileset->getSunLightColor()); - } - else { - assert(false); - color= tileset->getSunLightColor(); - } - } - return color; -} - -void TimeFlow::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *timeflowNode = rootNode->addChild("TimeFlow"); - - timeflowNode->addAttribute("firstTime",intToStr(firstTime), mapTagReplacements); -// bool firstTime; -// Tileset *tileset; -// float time; - timeflowNode->addAttribute("time",floatToStr(time,6), mapTagReplacements); -// float lastTime; - timeflowNode->addAttribute("lastTime",floatToStr(lastTime,6), mapTagReplacements); -// float timeInc; - //printf("#2 timeInc = %f\n",timeInc); - timeflowNode->addAttribute("timeInc",floatToStr(timeInc,6), mapTagReplacements); - //printf("#3 timeInc = %f\n",timeInc); -} - -void TimeFlow::loadGame(const XmlNode *rootNode) { - const XmlNode *timeflowNode = rootNode->getChild("TimeFlow"); - - firstTime = timeflowNode->getAttribute("firstTime")->getFloatValue() != 0; - time = timeflowNode->getAttribute("time")->getFloatValue(); - lastTime = timeflowNode->getAttribute("lastTime")->getFloatValue(); - timeInc = timeflowNode->getAttribute("timeInc")->getFloatValue(); - //printf("#4 timeInc = %f\n",timeInc); -} - -}}//end namespace +}//end namespace diff --git a/source/glest_game/world/time_flow.h b/source/glest_game/world/time_flow.h index 55f8732fb..51dcc7816 100644 --- a/source/glest_game/world/time_flow.h +++ b/source/glest_game/world/time_flow.h @@ -13,59 +13,71 @@ #define _GLEST_GAME_TIMEFLOW_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include "tileset.h" #include "sound.h" #include "leak_dumper.h" -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -using Shared::Sound::StrSound; -using Shared::Sound::StrSound; -using Shared::Sound::StaticSound; + using Shared::Sound::StrSound; + using Shared::Sound::StrSound; + using Shared::Sound::StaticSound; -// ===================================================== -// class TimeFlow -// -/// Raises time related events (day/night cycle) -// ===================================================== + // ===================================================== + // class TimeFlow + // + /// Raises time related events (day/night cycle) + // ===================================================== -class TimeFlow { -public: - static const float dusk; - static const float dawn; + class TimeFlow { + public: + static const float dusk; + static const float dawn; -private: - bool firstTime; - Tileset *tileset; - float time; - float lastTime; - float timeInc; + private: + bool firstTime; + Tileset *tileset; + float time; + float lastTime; + float timeInc; -public: - TimeFlow(); - void init(Tileset *tileset); + public: + TimeFlow(); + void init(Tileset *tileset); - inline float getTime() const {return time;} - inline bool isDay() const {return time>dawn && timedusk-1.f;} - inline float getTimeInc() const {return timeInc;} + inline float getTime() const { + return time; + } + inline bool isDay() const { + return time > dawn && time < dusk; + } + inline bool isNight() const { + return !isDay(); + } + inline bool isTotalNight() const { + return timedusk - 1.f; + } + inline float getTimeInc() const { + return timeInc; + } - Vec3f computeLightColor() const; - void update(); + Vec3f computeLightColor() const; + void update(); - void saveGame(XmlNode *rootNode); - void loadGame(const XmlNode *rootNode); + void saveGame(XmlNode *rootNode); + void loadGame(const XmlNode *rootNode); -private: - //bool isAproxTime(float time) const; -}; + private: + //bool isAproxTime(float time) const; + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/glest_game/world/unit_updater.cpp b/source/glest_game/world/unit_updater.cpp index df4cd2805..cc8026172 100644 --- a/source/glest_game/world/unit_updater.cpp +++ b/source/glest_game/world/unit_updater.cpp @@ -46,3446 +46,3365 @@ using namespace Shared::Graphics; using namespace Shared::Util; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class UnitUpdater -// ===================================================== + // ===================================================== + // class UnitUpdater + // ===================================================== -time_t UnitRangeCellsLookupItem::lastDebug = 0; + time_t UnitRangeCellsLookupItem::lastDebug = 0; -// ===================== PUBLIC ======================== + // ===================== PUBLIC ======================== -UnitUpdater::UnitUpdater() : mutexAttackWarnings(new Mutex(CODE_AT_LINE)), - mutexUnitRangeCellsLookupItemCache(new Mutex(CODE_AT_LINE)) { - this->game= NULL; - this->gui= NULL; - this->gameCamera= NULL; - this->world= NULL; - this->map= NULL; - this->console= NULL; - this->scriptManager= NULL; - this->pathFinder = NULL; - //UnitRangeCellsLookupItemCacheTimerCount = 0; - attackWarnRange=0; -} - -void UnitUpdater::init(Game *game){ - - this->game= game; - this->gui= game->getGuiPtr(); - this->gameCamera= game->getGameCamera(); - this->world= game->getWorld(); - this->map= world->getMap(); - this->console= game->getConsole(); - this->scriptManager= game->getScriptManager(); - this->pathFinder = NULL; - attackWarnRange=Config::getInstance().getFloat("AttackWarnRange","50.0"); - //UnitRangeCellsLookupItemCacheTimerCount = 0; - - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - pathFinder = new PathFinder(); - pathFinder->init(map); - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } -} - -void UnitUpdater::clearUnitPrecache(Unit *unit) { - if(pathFinder != NULL) { - pathFinder->clearUnitPrecache(unit); - } -} - -void UnitUpdater::removeUnitPrecache(Unit *unit) { - if(pathFinder != NULL) { - pathFinder->removeUnitPrecache(unit); - } -} - -UnitUpdater::~UnitUpdater() { - //UnitRangeCellsLookupItemCache.clear(); - - delete pathFinder; - pathFinder = NULL; - - MutexSafeWrapper safeMutex(mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__)); - while(attackWarnings.empty() == false) { - AttackWarningData* awd = attackWarnings.back(); - attackWarnings.pop_back(); - delete awd; - } - - safeMutex.ReleaseLock(); - - delete mutexAttackWarnings; - mutexAttackWarnings = NULL; - - delete mutexUnitRangeCellsLookupItemCache; - mutexUnitRangeCellsLookupItemCache = NULL; -} - -// ==================== progress skills ==================== - -//skill dependent actions -bool UnitUpdater::updateUnit(Unit *unit) { - bool processUnitCommand = false; - - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [START OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - SoundRenderer &soundRenderer= SoundRenderer::getInstance(); - - //play skill sound - const SkillType *currSkill= unit->getCurrSkill(); - - for(SkillSoundList::const_iterator it= currSkill->getSkillSoundList()->begin(); it != currSkill->getSkillSoundList()->end(); ++it) { - float soundStartTime= (*it)->getStartTime(); - if(soundStartTime >= unit->getLastAnimProgressAsFloat() && soundStartTime < unit->getAnimProgressAsFloat()) { - if(map->getSurfaceCell(Map::toSurfCoords(unit->getPos()))->isVisible(world->getThisTeamIndex()) || - (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)) { - soundRenderer.playFx((*it)->getSoundContainer()->getRandSound(), unit->getCurrMidHeightVector(), gameCamera->getPos()); - } + UnitUpdater::UnitUpdater() : mutexAttackWarnings(new Mutex(CODE_AT_LINE)), + mutexUnitRangeCellsLookupItemCache(new Mutex(CODE_AT_LINE)) { + this->game = NULL; + this->gui = NULL; + this->gameCamera = NULL; + this->world = NULL; + this->map = NULL; + this->console = NULL; + this->scriptManager = NULL; + this->pathFinder = NULL; + //UnitRangeCellsLookupItemCacheTimerCount = 0; + attackWarnRange = 0; } - } + void UnitUpdater::init(Game *game) { - if (currSkill->getShake()) { - float shakeStartTime = currSkill->getShakeStartTime(); - if (shakeStartTime >= unit->getLastAnimProgressAsFloat() - && shakeStartTime < unit->getAnimProgressAsFloat()) { - bool visibleAffected=false; - bool cameraViewAffected=false; - bool cameraDistanceAffected=false; - bool enabled=false; - if (game->getWorld()->getThisFactionIndex() == unit->getFactionIndex()) { - visibleAffected=currSkill->getShakeSelfVisible(); - cameraViewAffected=currSkill->getShakeSelfInCameraView(); - cameraDistanceAffected=currSkill->getShakeSelfCameraAffected(); - enabled=currSkill->getShakeSelfEnabled(); - } else if (unit->getTeam() == world->getThisTeamIndex()) { - visibleAffected=currSkill->getShakeTeamVisible(); - cameraViewAffected=currSkill->getShakeTeamInCameraView(); - cameraDistanceAffected=currSkill->getShakeTeamCameraAffected(); - enabled=currSkill->getShakeTeamEnabled(); - } else { - visibleAffected=currSkill->getShakeEnemyVisible(); - cameraViewAffected=currSkill->getShakeEnemyInCameraView(); - cameraDistanceAffected=currSkill->getShakeEnemyCameraAffected(); - enabled=currSkill->getShakeEnemyEnabled(); - } + this->game = game; + this->gui = game->getGuiPtr(); + this->gameCamera = game->getGameCamera(); + this->world = game->getWorld(); + this->map = world->getMap(); + this->console = game->getConsole(); + this->scriptManager = game->getScriptManager(); + this->pathFinder = NULL; + attackWarnRange = Config::getInstance().getFloat("AttackWarnRange", "50.0"); + //UnitRangeCellsLookupItemCacheTimerCount = 0; - bool visibility=(!visibleAffected)||(map->getSurfaceCell(Map::toSurfCoords(unit->getPos()))->isVisible(world->getThisTeamIndex()) || - (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)); - - bool cameraAffected=(!cameraViewAffected) || unit->getVisible(); - - if(visibility && cameraAffected && enabled) { - game->getGameCameraPtr()->shake( currSkill->getShakeDuration(), currSkill->getShakeIntensity(),cameraDistanceAffected,unit->getCurrMidHeightVector()); - } - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after playsound]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - unit->updateTimedParticles(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after playsound]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - - //start attack particle system - if(unit->getCurrSkill()->getClass() == scDie) { - const DieSkillType *dst= static_cast(unit->getCurrSkill()); - - if(dst->getSpawn() == true){ - float spawnStartTime = truncateDecimal(dst->getSpawnStartTime(),6); - float lastAnimProgress = truncateDecimal(unit->getLastAnimProgressAsFloat(),6); - float animProgress = truncateDecimal(unit->getAnimProgressAsFloat(),6); - - bool startSpawnNow = (spawnStartTime >= lastAnimProgress && spawnStartTime < animProgress); - if(startSpawnNow){ - // spawn the units - spawn(unit, dst->getSpawnUnit(), dst->getSpawnUnitCount(), - dst->getSpawnUnitHealthPercentMin(), - dst->getSpawnUnitHealthPercentMax(), - dst->getSpawnProbability()); - } - } - } - - //start attack particle system - if(unit->getCurrSkill()->getClass() == scAttack) { - const AttackSkillType *ast= static_cast(unit->getCurrSkill()); - - float attackStartTime = truncateDecimal(ast->getAttackStartTime(),6); - float lastAnimProgress = truncateDecimal(unit->getLastAnimProgressAsFloat(),6); - float animProgress = truncateDecimal(unit->getAnimProgressAsFloat(),6); - bool startAttackParticleSystemNow = false; - if(ast->projectileTypes.empty() == true ){ - startAttackParticleSystemNow = (attackStartTime >= lastAnimProgress && attackStartTime < animProgress); - } - else {// start projectile attack - for(ProjectileTypes::const_iterator it= ast->projectileTypes.begin(); it != ast->projectileTypes.end(); ++it) { - attackStartTime= (*it)->getAttackStartTime(); - startAttackParticleSystemNow = (attackStartTime >= lastAnimProgress && attackStartTime < animProgress); - if(startAttackParticleSystemNow==true) break; + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + pathFinder = new PathFinder(); + pathFinder->init(map); + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); } } - char szBuf[8096]=""; - snprintf(szBuf,8095,"attackStartTime = %f, lastAnimProgress = %f, animProgress = %f startAttackParticleSystemNow = %d",attackStartTime,lastAnimProgress,animProgress,startAttackParticleSystemNow); - unit->setNetworkCRCParticleLogInfo(szBuf); - - if(startAttackParticleSystemNow == true) { - startAttackParticleSystem(unit,lastAnimProgress,animProgress); + void UnitUpdater::clearUnitPrecache(Unit *unit) { + if (pathFinder != NULL) { + pathFinder->clearUnitPrecache(unit); + } } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after attack particle system]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + void UnitUpdater::removeUnitPrecache(Unit *unit) { + if (pathFinder != NULL) { + pathFinder->removeUnitPrecache(unit); + } + } - bool update = unit->update(); + UnitUpdater::~UnitUpdater() { + //UnitRangeCellsLookupItemCache.clear(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after unit->update()]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + delete pathFinder; + pathFinder = NULL; - //printf("Update Unit [%d - %s] = %d\n",unit->getId(),unit->getType()->getName().c_str(),update); - - //update unit - if(update == true) { - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - processUnitCommand = true; - updateUnitCommand(unit,-1); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after updateUnitCommand()]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - //if unit is out of EP, it stops - if(unit->computeEp() == true) { - bool reQueueHoldPosition = false; - string holdPositionName = ""; - if(unit->getCurrCommand() != NULL && - unit->getCurrCommand()->getCommandType()->getClass() == ccAttackStopped) { - reQueueHoldPosition = true; - holdPositionName = unit->getCurrCommand()->getCommandType()->getName(false); + MutexSafeWrapper safeMutex(mutexAttackWarnings, string(__FILE__) + "_" + intToStr(__LINE__)); + while (attackWarnings.empty() == false) { + AttackWarningData* awd = attackWarnings.back(); + attackWarnings.pop_back(); + delete awd; } - unit->setCurrSkill(scStop); - unit->cancelCommand(); + safeMutex.ReleaseLock(); - if(reQueueHoldPosition == true) { - //Search for a command that can produce the unit - const UnitType *ut = unit->getType(); - for(int i= 0; i < ut->getCommandTypeCount(); ++i) { - const CommandType* ct= ut->getCommandType(i); - if(ct != NULL && ct->getClass() == ccAttackStopped) { - const AttackStoppedCommandType *act= static_cast(ct); - if(act != NULL && act->getName(false) == holdPositionName) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + delete mutexAttackWarnings; + mutexAttackWarnings = NULL; - //printf("Re-Queing hold pos = %d, ep = %d skillep = %d skillname [%s]\n ",unit->getFaction()->reqsOk(act),unit->getEp(),act->getAttackSkillType()->getEpCost(),act->getName().c_str()); - if(unit->getFaction()->reqsOk(act) == true && - unit->getEp() >= act->getStopSkillType()->getEpCost()) { - unit->giveCommand(new Command(act),true); + delete mutexUnitRangeCellsLookupItemCache; + mutexUnitRangeCellsLookupItemCache = NULL; + } + + // ==================== progress skills ==================== + + //skill dependent actions + bool UnitUpdater::updateUnit(Unit *unit) { + bool processUnitCommand = false; + + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld --------------------------- [START OF METHOD] ---------------------------\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + SoundRenderer &soundRenderer = SoundRenderer::getInstance(); + + //play skill sound + const SkillType *currSkill = unit->getCurrSkill(); + + for (SkillSoundList::const_iterator it = currSkill->getSkillSoundList()->begin(); it != currSkill->getSkillSoundList()->end(); ++it) { + float soundStartTime = (*it)->getStartTime(); + if (soundStartTime >= unit->getLastAnimProgressAsFloat() && soundStartTime < unit->getAnimProgressAsFloat()) { + if (map->getSurfaceCell(Map::toSurfCoords(unit->getPos()))->isVisible(world->getThisTeamIndex()) || + (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)) { + soundRenderer.playFx((*it)->getSoundContainer()->getRandSound(), unit->getCurrMidHeightVector(), gameCamera->getPos()); + } + } + } + + + if (currSkill->getShake()) { + float shakeStartTime = currSkill->getShakeStartTime(); + if (shakeStartTime >= unit->getLastAnimProgressAsFloat() + && shakeStartTime < unit->getAnimProgressAsFloat()) { + bool visibleAffected = false; + bool cameraViewAffected = false; + bool cameraDistanceAffected = false; + bool enabled = false; + if (game->getWorld()->getThisFactionIndex() == unit->getFactionIndex()) { + visibleAffected = currSkill->getShakeSelfVisible(); + cameraViewAffected = currSkill->getShakeSelfInCameraView(); + cameraDistanceAffected = currSkill->getShakeSelfCameraAffected(); + enabled = currSkill->getShakeSelfEnabled(); + } else if (unit->getTeam() == world->getThisTeamIndex()) { + visibleAffected = currSkill->getShakeTeamVisible(); + cameraViewAffected = currSkill->getShakeTeamInCameraView(); + cameraDistanceAffected = currSkill->getShakeTeamCameraAffected(); + enabled = currSkill->getShakeTeamEnabled(); + } else { + visibleAffected = currSkill->getShakeEnemyVisible(); + cameraViewAffected = currSkill->getShakeEnemyInCameraView(); + cameraDistanceAffected = currSkill->getShakeEnemyCameraAffected(); + enabled = currSkill->getShakeEnemyEnabled(); + } + + bool visibility = (!visibleAffected) || (map->getSurfaceCell(Map::toSurfCoords(unit->getPos()))->isVisible(world->getThisTeamIndex()) || + (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)); + + bool cameraAffected = (!cameraViewAffected) || unit->getVisible(); + + if (visibility && cameraAffected && enabled) { + game->getGameCameraPtr()->shake(currSkill->getShakeDuration(), currSkill->getShakeIntensity(), cameraDistanceAffected, unit->getCurrMidHeightVector()); + } + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld [after playsound]\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + unit->updateTimedParticles(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld [after playsound]\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + + //start attack particle system + if (unit->getCurrSkill()->getClass() == scDie) { + const DieSkillType *dst = static_cast(unit->getCurrSkill()); + + if (dst->getSpawn() == true) { + float spawnStartTime = truncateDecimal(dst->getSpawnStartTime(), 6); + float lastAnimProgress = truncateDecimal(unit->getLastAnimProgressAsFloat(), 6); + float animProgress = truncateDecimal(unit->getAnimProgressAsFloat(), 6); + + bool startSpawnNow = (spawnStartTime >= lastAnimProgress && spawnStartTime < animProgress); + if (startSpawnNow) { + // spawn the units + spawn(unit, dst->getSpawnUnit(), dst->getSpawnUnitCount(), + dst->getSpawnUnitHealthPercentMin(), + dst->getSpawnUnitHealthPercentMax(), + dst->getSpawnProbability()); + } + } + } + + //start attack particle system + if (unit->getCurrSkill()->getClass() == scAttack) { + const AttackSkillType *ast = static_cast(unit->getCurrSkill()); + + float attackStartTime = truncateDecimal(ast->getAttackStartTime(), 6); + float lastAnimProgress = truncateDecimal(unit->getLastAnimProgressAsFloat(), 6); + float animProgress = truncateDecimal(unit->getAnimProgressAsFloat(), 6); + bool startAttackParticleSystemNow = false; + if (ast->projectileTypes.empty() == true) { + startAttackParticleSystemNow = (attackStartTime >= lastAnimProgress && attackStartTime < animProgress); + } else {// start projectile attack + for (ProjectileTypes::const_iterator it = ast->projectileTypes.begin(); it != ast->projectileTypes.end(); ++it) { + attackStartTime = (*it)->getAttackStartTime(); + startAttackParticleSystemNow = (attackStartTime >= lastAnimProgress && attackStartTime < animProgress); + if (startAttackParticleSystemNow == true) break; + } + } + + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "attackStartTime = %f, lastAnimProgress = %f, animProgress = %f startAttackParticleSystemNow = %d", attackStartTime, lastAnimProgress, animProgress, startAttackParticleSystemNow); + unit->setNetworkCRCParticleLogInfo(szBuf); + + if (startAttackParticleSystemNow == true) { + startAttackParticleSystem(unit, lastAnimProgress, animProgress); + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld [after attack particle system]\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + bool update = unit->update(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld [after unit->update()]\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + //printf("Update Unit [%d - %s] = %d\n",unit->getId(),unit->getType()->getName().c_str(),update); + + //update unit + if (update == true) { + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + processUnitCommand = true; + updateUnitCommand(unit, -1); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld [after updateUnitCommand()]\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + //if unit is out of EP, it stops + if (unit->computeEp() == true) { + bool reQueueHoldPosition = false; + string holdPositionName = ""; + if (unit->getCurrCommand() != NULL && + unit->getCurrCommand()->getCommandType()->getClass() == ccAttackStopped) { + reQueueHoldPosition = true; + holdPositionName = unit->getCurrCommand()->getCommandType()->getName(false); + } + + unit->setCurrSkill(scStop); + unit->cancelCommand(); + + if (reQueueHoldPosition == true) { + //Search for a command that can produce the unit + const UnitType *ut = unit->getType(); + for (int i = 0; i < ut->getCommandTypeCount(); ++i) { + const CommandType* ct = ut->getCommandType(i); + if (ct != NULL && ct->getClass() == ccAttackStopped) { + const AttackStoppedCommandType *act = static_cast(ct); + if (act != NULL && act->getName(false) == holdPositionName) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //printf("Re-Queing hold pos = %d, ep = %d skillep = %d skillname [%s]\n ",unit->getFaction()->reqsOk(act),unit->getEp(),act->getAttackSkillType()->getEpCost(),act->getName().c_str()); + if (unit->getFaction()->reqsOk(act) == true && + unit->getEp() >= act->getStopSkillType()->getEpCost()) { + unit->giveCommand(new Command(act), true); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } } + } + } + } + if (unit->getCurrSkill() != NULL && unit->getCurrSkill()->getClass() != scAttack) { + // !!! Is this causing choppy network play somehow? + //unit->computeHp(); + } else if (unit->getCommandSize() > 0) { + Command *command = unit->getCurrCommand(); + if (command != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; + const AttackCommandType *act = dynamic_cast(command->getCommandType()); + if (act != NULL && act->getAttackSkillType() != NULL + && act->getAttackSkillType()->getSpawnUnit() != "" + && act->getAttackSkillType()->getSpawnUnitCount() > 0) { + spawnAttack(unit, act->getAttackSkillType()->getSpawnUnit(), + act->getAttackSkillType()->getSpawnUnitCount(), 100, + 100, 100, + act->getAttackSkillType()->getSpawnUnitAtTarget()); + } + } + } + + //move unit in cells + if (unit->getCurrSkill()->getClass() == scMove) { + world->moveUnitCells(unit, true); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld [after world->moveUnitCells()]\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + //play water sound + if (map->getCell(unit->getPos())->getHeight() < map->getWaterLevel() && unit->getCurrField() == fLand) { + if (Config::getInstance().getBool("DisableWaterSounds", "false") == false) { + soundRenderer.playFx( + CoreData::getInstance().getWaterSound(), + unit->getCurrMidHeightVector(), + gameCamera->getPos() + ); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld [after soundFx()]\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + } + } + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + //unit death + if (unit->isDead() && unit->getCurrSkill()->getClass() != scDie) { + unit->kill(); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + return processUnitCommand; + } + + void UnitUpdater::spawn(Unit *unit, string spawnUnit, int spawnUnitcount, int healthMin, int healthMax, int probability) { + if (spawnUnit != "" && spawnUnitcount > 0) { + int spawnCount = spawnUnitcount; + for (int y = 0; y < spawnCount; ++y) { + if (probability > 0 && probability < 100 + && unit->getRandom()->randRange(1, 100) <= probability) { + continue; + } + Unit* spawned = this->spawnUnit(unit, spawnUnit); + if (spawned != NULL) { + if (healthMin > 0 && healthMin < 100 && healthMax >= healthMin && healthMax <= 100) { + int damagePercent = 100 - unit->getRandom()->randRange(healthMin, healthMax); + //printf("damagePercent=%d\n",damagePercent); + spawned->decHp((spawned->getHp()*damagePercent) / 100); + } + } + // no stat count !! + //world->getStats()->produce(unit->getFactionIndex(),spawned->getType()->getCountUnitProductionInStats()); + } + } + } + + void UnitUpdater::spawnAttack(Unit *unit, string spawnUnit, int spawnUnitcount, int healthMin, int healthMax, int probability, bool spawnUnitAtTarget, Vec2i targetPos) { + if (spawnUnit != "" && spawnUnitcount > 0) { + + int spawnCount = spawnUnitcount; + for (int y = 0; y < spawnCount; ++y) { + if (probability > 0 && probability < 100 + && unit->getRandom()->randRange(1, 100) <= probability) { + continue; + } + if (targetPos == Vec2i(-10, -10)) { + targetPos = unit->getTargetPos(); + } + Unit* spawned = this->spawnUnit(unit, spawnUnit, spawnUnitAtTarget ? targetPos : unit->getCenteredPos()); + if (spawned != NULL) { + if (healthMin > 0 && healthMin < 100 && healthMax >= healthMin && healthMax <= 100) { + int damagePercent = 100 - unit->getRandom()->randRange(healthMin, healthMax); + //printf("damagePercent=%d\n",damagePercent); + spawned->decHp((spawned->getHp()*damagePercent) / 100); + } + // no stat count !! + // world->getStats()->produce(unit->getFactionIndex(),spawned->getType()->getCountUnitProductionInStats()); + const CommandType *ct = spawned->getType()->getFirstAttackCommand(unit->getTargetField()); + if (ct == NULL) { + ct = spawned->computeCommandType(targetPos, map->getCell(targetPos)->getUnit(unit->getTargetField())); + } + if (ct != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + spawned->giveCommand(new Command(ct, targetPos)); } } } } } - if(unit->getCurrSkill() != NULL && unit->getCurrSkill()->getClass() != scAttack) { - // !!! Is this causing choppy network play somehow? - //unit->computeHp(); - } - else if(unit->getCommandSize() > 0) { - Command *command= unit->getCurrCommand(); - if(command != NULL) { - const AttackCommandType *act= dynamic_cast(command->getCommandType()); - if (act != NULL && act->getAttackSkillType() != NULL - && act->getAttackSkillType()->getSpawnUnit() != "" - && act->getAttackSkillType()->getSpawnUnitCount() > 0) { - spawnAttack(unit, act->getAttackSkillType()->getSpawnUnit(), - act->getAttackSkillType()->getSpawnUnitCount(), 100, - 100, 100, - act->getAttackSkillType()->getSpawnUnitAtTarget()); + + Unit* UnitUpdater::spawnUnit(Unit *unit, string spawnUnit, Vec2i spawnPos) { + const FactionType *ft = unit->getFaction()->getType(); + const UnitType *spawnUnitType = ft->getUnitType(spawnUnit); + Vec2i _spawnPos = spawnPos; + if (_spawnPos == Vec2i(-10, -10)) { + _spawnPos = unit->getCenteredPos(); + } + if (spawnUnitType->getMaxUnitCount() > 0) { + if (spawnUnitType->getMaxUnitCount() <= unit->getFaction()->getCountForMaxUnitCount(spawnUnitType)) { + return NULL; } } - } - //move unit in cells - if(unit->getCurrSkill()->getClass() == scMove) { - world->moveUnitCells(unit, true); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after world->moveUnitCells()]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - //play water sound - if(map->getCell(unit->getPos())->getHeight() < map->getWaterLevel() && unit->getCurrField() == fLand) { - if(Config::getInstance().getBool("DisableWaterSounds","false") == false) { - soundRenderer.playFx( - CoreData::getInstance().getWaterSound(), - unit->getCurrMidHeightVector(), - gameCamera->getPos() - ); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld [after soundFx()]\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } - } - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - //unit death - if(unit->isDead() && unit->getCurrSkill()->getClass() != scDie) { - unit->kill(); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - return processUnitCommand; -} - -void UnitUpdater::spawn(Unit *unit,string spawnUnit,int spawnUnitcount,int healthMin,int healthMax,int probability) { - if(spawnUnit != "" && spawnUnitcount > 0) { - int spawnCount = spawnUnitcount; - for (int y=0; y < spawnCount; ++y) { - if (probability > 0 && probability < 100 - && unit->getRandom()->randRange(1, 100) <= probability) { - continue; - } - Unit* spawned=this->spawnUnit(unit,spawnUnit); - if(spawned!=NULL){ - if(healthMin>0 && healthMin<100 && healthMax>=healthMin && healthMax<=100){ - int damagePercent=100-unit->getRandom()->randRange(healthMin, healthMax); - //printf("damagePercent=%d\n",damagePercent); - spawned->decHp((spawned->getHp()*damagePercent)/100); - } - } - // no stat count !! - //world->getStats()->produce(unit->getFactionIndex(),spawned->getType()->getCountUnitProductionInStats()); - } - } -} - -void UnitUpdater::spawnAttack(Unit *unit,string spawnUnit,int spawnUnitcount,int healthMin,int healthMax,int probability,bool spawnUnitAtTarget,Vec2i targetPos) { - if(spawnUnit != "" && spawnUnitcount > 0) { - - int spawnCount = spawnUnitcount; - for (int y=0; y < spawnCount; ++y) { - if (probability > 0 && probability < 100 - && unit->getRandom()->randRange(1, 100) <= probability) { - continue; - } - if(targetPos==Vec2i(-10,-10)) { - targetPos=unit->getTargetPos(); - } - Unit* spawned=this->spawnUnit(unit,spawnUnit,spawnUnitAtTarget?targetPos:unit->getCenteredPos()); - if(spawned!=NULL){ - if(healthMin>0 && healthMin<100 && healthMax>=healthMin && healthMax<=100){ - int damagePercent=100-unit->getRandom()->randRange(healthMin, healthMax); - //printf("damagePercent=%d\n",damagePercent); - spawned->decHp((spawned->getHp()*damagePercent)/100); - } - // no stat count !! - // world->getStats()->produce(unit->getFactionIndex(),spawned->getType()->getCountUnitProductionInStats()); - const CommandType *ct= spawned->getType()->getFirstAttackCommand(unit->getTargetField()); - if(ct == NULL){ - ct= spawned->computeCommandType(targetPos,map->getCell(targetPos)->getUnit(unit->getTargetField())); - } - if(ct != NULL){ - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - spawned->giveCommand(new Command(ct, targetPos)); - } - } - } - } -} - - -Unit* UnitUpdater::spawnUnit(Unit *unit,string spawnUnit,Vec2i spawnPos) { - const FactionType *ft= unit->getFaction()->getType(); - const UnitType *spawnUnitType = ft->getUnitType(spawnUnit); - Vec2i _spawnPos=spawnPos; - if(_spawnPos==Vec2i(-10,-10)) { - _spawnPos=unit->getCenteredPos(); - } - if(spawnUnitType->getMaxUnitCount() > 0) { - if(spawnUnitType->getMaxUnitCount() <= unit->getFaction()->getCountForMaxUnitCount(spawnUnitType)) { - return NULL; - } - } - - UnitPathInterface *newpath = NULL; - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - newpath = new UnitPathBasic(); - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } - - Unit *spawned= new Unit(world->getNextUnitId(unit->getFaction()), newpath, - Vec2i(0), spawnUnitType, unit->getFaction(), - world->getMap(), CardinalDir(CardinalDir::NORTH)); - - bool placedSpawnUnit=world->placeUnit(_spawnPos, 10, spawned); - - if(!placedSpawnUnit) { - // This will also cleanup newPath - delete spawned; - spawned = NULL; - } - else { - spawned->create(); - spawned->born(NULL); - scriptManager->onUnitCreated(spawned); - } - return spawned; -} - - -// ==================== progress commands ==================== - -//VERY IMPORTANT: compute next state depending on the first order of the list -void UnitUpdater::updateUnitCommand(Unit *unit, int frameIndex) { - try { - bool minorDebugPerformance = false; - Chrono chrono; - if((minorDebugPerformance == true && frameIndex > 0) || SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - - // If the unit has a command, process it. - bool hasCommand = (unit->anyCommand()); - - if((minorDebugPerformance && frameIndex > 0) && chrono.getMillis() >= 1) printf("UnitUpdate [%d - %s] #1-unit threaded updates on frame: %d took [%lld] msecs\n",unit->getId(),unit->getType()->getName(false).c_str(),frameIndex,(long long int)chrono.getMillis()); - - int64 elapsed1 = 0; - if(minorDebugPerformance && frameIndex > 0) elapsed1 = chrono.getMillis(); - - if(hasCommand == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] unit [%s] has command [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString(false).c_str(), unit->getCurrCommand()->toString(false).c_str()); - - bool commandUsesPathFinder = (frameIndex < 0); - if(frameIndex > 0) { - if(unit->getCurrCommand() != NULL && unit->getCurrCommand()->getCommandType() != NULL) { - commandUsesPathFinder = unit->getCurrCommand()->getCommandType()->usesPathfinder(); - - // Clear previous cached unit data - if(commandUsesPathFinder == true) { - clearUnitPrecache(unit); - } - } - } - if(commandUsesPathFinder == true) { - if(unit->getCurrCommand() != NULL && unit->getCurrCommand()->getCommandType() != NULL) { - unit->getCurrCommand()->getCommandType()->update(this, unit, frameIndex); - } - } - - if((minorDebugPerformance && frameIndex > 0) && (chrono.getMillis() - elapsed1) >= 1) { - //CommandClass cc = unit->getCurrCommand()->getCommandType()->commandTypeClass; - printf("UnitUpdate [%d - %s] #2-unit threaded updates on frame: %d commandUsesPathFinder = %d took [%lld] msecs\nCommand: %s\n",unit->getId(),unit->getType()->getName(false).c_str(),frameIndex,commandUsesPathFinder,(long long int)chrono.getMillis() - elapsed1,unit->getCurrCommand()->toString(false).c_str()); - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - if(frameIndex < 0) { - //if no commands stop and add stop command - if(unit->anyCommand() == false && unit->isOperative()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(unit->getType()->hasSkillClass(scStop)) { - unit->setCurrSkill(scStop); - } - if(unit->getType()->hasCommandClass(ccStop)) { - unit->giveCommand(new Command(unit->getType()->getFirstCtOfClass(ccStop))); - } - } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - if((minorDebugPerformance && frameIndex > 0) && chrono.getMillis() >= 1) printf("UnitUpdate [%d - %s] #3-unit threaded updates on frame: %d took [%lld] msecs\n",unit->getId(),unit->getType()->getName(false).c_str(),frameIndex,(long long int)chrono.getMillis()); - - } - catch(const exception &ex) { - //setRunningStatus(false); - - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - throw megaglest_runtime_error(ex.what()); - } - catch(...) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - throw megaglest_runtime_error(szBuf); - } - -} - -// ==================== updateStop ==================== - -void UnitUpdater::updateStop(Unit *unit, int frameIndex) { - try { - // Nothing to do - if(frameIndex >= 0) { - clearUnitPrecache(unit); - return; - } - - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - - Command *command= unit->getCurrCommand(); - if(command == NULL) { - throw megaglest_runtime_error("command == NULL"); - } - const StopCommandType *sct = static_cast(command->getCommandType()); - Unit *sighted=NULL; - - - unit->setCurrSkill(sct->getStopSkillType()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - - //we can attack any unit => attack it - if(unit->getType()->hasSkillClass(scAttack)) { - - int cmdTypeCount = unit->getType()->getCommandTypeCount(); - - for(int i = 0; i < cmdTypeCount; ++i) { - - const CommandType *ct= unit->getType()->getCommandType(i); - - //look for an attack skill - const AttackSkillType *ast= NULL; - if(ct->getClass() == ccAttack) { - ast= static_cast(ct)->getAttackSkillType(); - } - else if(ct->getClass() == ccAttackStopped) { - ast= static_cast(ct)->getAttackSkillType(); - } - - - //use it to attack - if(ast != NULL) { - if(attackableOnSight(unit, &sighted, ast, (frameIndex >= 0))) { - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - unit->giveCommand(new Command(ct, sighted->getPos())); + UnitPathInterface *newpath = NULL; + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + newpath = new UnitPathBasic(); break; - } + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } - //see any unit and cant attack it => run - else if(unit->getType()->hasCommandClass(ccMove)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - if(attackerOnSight(unit, &sighted, (frameIndex >= 0))) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - Vec2i escapePos = unit->getPos() * 2 - sighted->getPos(); - //SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - unit->giveCommand(new Command(unit->getType()->getFirstCtOfClass(ccMove), escapePos)); - } + Unit *spawned = new Unit(world->getNextUnitId(unit->getFaction()), newpath, + Vec2i(0), spawnUnitType, unit->getFaction(), + world->getMap(), CardinalDir(CardinalDir::NORTH)); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } + bool placedSpawnUnit = world->placeUnit(_spawnPos, 10, spawned); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - } - catch(const exception &ex) { - //setRunningStatus(false); - - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - throw megaglest_runtime_error(ex.what()); - } - catch(...) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - throw megaglest_runtime_error(szBuf); - } - -} - -// ==================== updateMove ==================== -void UnitUpdater::updateMove(Unit *unit, int frameIndex) { - try { - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - - Command *command= unit->getCurrCommand(); - if(command == NULL) { - throw megaglest_runtime_error("command == NULL"); - } - const MoveCommandType *mct= static_cast(command->getCommandType()); - - - Vec2i pos= command->getUnit()!=NULL? command->getUnit()->getCenteredPos(): command->getPos(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateMove] pos [%s] unit [%d - %s] cmd [%s]",pos.getString().c_str(),unit->getId(),unit->getFullName(false).c_str(),command->toString(false).c_str()); - unit->logSynchData(__FILE__,__LINE__,szBuf); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - - TravelState tsValue = tsImpossible; - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - tsValue = pathFinder->findPath(unit, pos, NULL, frameIndex); - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - - if(frameIndex < 0) { - switch (tsValue) { - case tsMoving: - unit->setCurrSkill(mct->getMoveSkillType()); - break; - - case tsBlocked: - unit->setCurrSkill(scStop); - if(unit->getPath()->isBlocked()){ - unit->finishCommand(); + if (!placedSpawnUnit) { + // This will also cleanup newPath + delete spawned; + spawned = NULL; + } else { + spawned->create(); + spawned->born(NULL); + scriptManager->onUnitCreated(spawned); } - break; - - default: - unit->finishCommand(); - break; - } - } - - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateMove] tsValue [%d]",tsValue); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - } - catch(const exception &ex) { - //setRunningStatus(false); - - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - throw megaglest_runtime_error(ex.what()); - } - catch(...) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - throw megaglest_runtime_error(szBuf); - } - -} - - -// ==================== updateAttack ==================== - -void UnitUpdater::updateAttack(Unit *unit, int frameIndex) { - try { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateAttack]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - - Command *command= unit->getCurrCommand(); - if(command == NULL) { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateAttack]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); + return spawned; } - return; - } - const AttackCommandType *act= static_cast(command->getCommandType()); - if(act == NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateAttack]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } + // ==================== progress commands ==================== - return; - } - Unit *target= NULL; + //VERY IMPORTANT: compute next state depending on the first order of the list + void UnitUpdater::updateUnitCommand(Unit *unit, int frameIndex) { + try { + bool minorDebugPerformance = false; + Chrono chrono; + if ((minorDebugPerformance == true && frameIndex > 0) || SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + // If the unit has a command, process it. + bool hasCommand = (unit->anyCommand()); - if( (command->getUnit() == NULL || !(command->getUnit()->isAlive()) ) && unit->getCommandSize() > 1) { + if ((minorDebugPerformance && frameIndex > 0) && chrono.getMillis() >= 1) printf("UnitUpdate [%d - %s] #1-unit threaded updates on frame: %d took [%lld] msecs\n", unit->getId(), unit->getType()->getName(false).c_str(), frameIndex, (long long int)chrono.getMillis()); - if(frameIndex < 0) { - unit->finishCommand(); // all queued "ground attacks" are skipped if somthing else is queued after them. + int64 elapsed1 = 0; + if (minorDebugPerformance && frameIndex > 0) elapsed1 = chrono.getMillis(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateAttack]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - } - return; - } + if (hasCommand == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] unit [%s] has command [%s]\n", __FILE__, __FUNCTION__, __LINE__, unit->toString(false).c_str(), unit->getCurrCommand()->toString(false).c_str()); - //if found - //if(frameIndex < 0) { - { - if(attackableOnRange(unit, &target, act->getAttackSkillType(),(frameIndex >= 0))) { - if(frameIndex < 0) { - if(unit->getEp() >= act->getAttackSkillType()->getEpCost()) { - unit->setCurrSkill(act->getAttackSkillType()); - unit->setTarget(target); - } - else { - unit->setCurrSkill(scStop); + bool commandUsesPathFinder = (frameIndex < 0); + if (frameIndex > 0) { + if (unit->getCurrCommand() != NULL && unit->getCurrCommand()->getCommandType() != NULL) { + commandUsesPathFinder = unit->getCurrCommand()->getCommandType()->usesPathfinder(); + + // Clear previous cached unit data + if (commandUsesPathFinder == true) { + clearUnitPrecache(unit); + } + } + } + if (commandUsesPathFinder == true) { + if (unit->getCurrCommand() != NULL && unit->getCurrCommand()->getCommandType() != NULL) { + unit->getCurrCommand()->getCommandType()->update(this, unit, frameIndex); + } + } + + if ((minorDebugPerformance && frameIndex > 0) && (chrono.getMillis() - elapsed1) >= 1) { + //CommandClass cc = unit->getCurrCommand()->getCommandType()->commandTypeClass; + printf("UnitUpdate [%d - %s] #2-unit threaded updates on frame: %d commandUsesPathFinder = %d took [%lld] msecs\nCommand: %s\n", unit->getId(), unit->getType()->getName(false).c_str(), frameIndex, commandUsesPathFinder, (long long int)chrono.getMillis() - elapsed1, unit->getCurrCommand()->toString(false).c_str()); + } } - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateAttack]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + if (frameIndex < 0) { + //if no commands stop and add stop command + if (unit->anyCommand() == false && unit->isOperative()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (unit->getType()->hasSkillClass(scStop)) { + unit->setCurrSkill(scStop); + } + if (unit->getType()->hasCommandClass(ccStop)) { + unit->giveCommand(new Command(unit->getType()->getFirstCtOfClass(ccStop))); + } + } } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + if ((minorDebugPerformance && frameIndex > 0) && chrono.getMillis() >= 1) printf("UnitUpdate [%d - %s] #3-unit threaded updates on frame: %d took [%lld] msecs\n", unit->getId(), unit->getType()->getName(false).c_str(), frameIndex, (long long int)chrono.getMillis()); + + } catch (const exception &ex) { + //setRunningStatus(false); + + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + throw megaglest_runtime_error(ex.what()); + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + } - else { - //compute target pos - Vec2i pos; - if(command->getUnit() != NULL) { - pos= command->getUnit()->getCenteredPos(); - } - else if(attackableOnSight(unit, &target, act->getAttackSkillType(), (frameIndex >= 0))) { - pos= target->getPos(); - } - else { - pos= command->getPos(); + + // ==================== updateStop ==================== + + void UnitUpdater::updateStop(Unit *unit, int frameIndex) { + try { + // Nothing to do + if (frameIndex >= 0) { + clearUnitPrecache(unit); + return; + } + + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + + Command *command = unit->getCurrCommand(); + if (command == NULL) { + throw megaglest_runtime_error("command == NULL"); + } + const StopCommandType *sct = static_cast(command->getCommandType()); + Unit *sighted = NULL; + + + unit->setCurrSkill(sct->getStopSkillType()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + + //we can attack any unit => attack it + if (unit->getType()->hasSkillClass(scAttack)) { + + int cmdTypeCount = unit->getType()->getCommandTypeCount(); + + for (int i = 0; i < cmdTypeCount; ++i) { + + const CommandType *ct = unit->getType()->getCommandType(i); + + //look for an attack skill + const AttackSkillType *ast = NULL; + if (ct->getClass() == ccAttack) { + ast = static_cast(ct)->getAttackSkillType(); + } else if (ct->getClass() == ccAttackStopped) { + ast = static_cast(ct)->getAttackSkillType(); + } + + + //use it to attack + if (ast != NULL) { + if (attackableOnSight(unit, &sighted, ast, (frameIndex >= 0))) { + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + unit->giveCommand(new Command(ct, sighted->getPos())); + break; + } + } + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + } + //see any unit and cant attack it => run + else if (unit->getType()->hasCommandClass(ccMove)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + if (attackerOnSight(unit, &sighted, (frameIndex >= 0))) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + Vec2i escapePos = unit->getPos() * 2 - sighted->getPos(); + //SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + unit->giveCommand(new Command(unit->getType()->getFirstCtOfClass(ccMove), escapePos)); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + } catch (const exception &ex) { + //setRunningStatus(false); + + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + throw megaglest_runtime_error(ex.what()); + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); } - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateAttack] pos [%s] unit->getPos() [%s]",pos.getString().c_str(),unit->getPos().getString().c_str()); - unit->logSynchData(__FILE__,__LINE__,szBuf); - } + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + // ==================== updateMove ==================== + void UnitUpdater::updateMove(Unit *unit, int frameIndex) { + try { + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - TravelState tsValue = tsImpossible; - //if(frameIndex < 0) { - { - //printf("In [%s::%s Line: %d] START pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str()); - //fflush(stdout); - switch(this->game->getGameSettings()->getPathFinderType()) { + Command *command = unit->getCurrCommand(); + if (command == NULL) { + throw megaglest_runtime_error("command == NULL"); + } + const MoveCommandType *mct = static_cast(command->getCommandType()); + + + Vec2i pos = command->getUnit() != NULL ? command->getUnit()->getCenteredPos() : command->getPos(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateMove] pos [%s] unit [%d - %s] cmd [%s]", pos.getString().c_str(), unit->getId(), unit->getFullName(false).c_str(), command->toString(false).c_str()); + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + + TravelState tsValue = tsImpossible; + switch (this->game->getGameSettings()->getPathFinderType()) { case pfBasic: tsValue = pathFinder->findPath(unit, pos, NULL, frameIndex); break; default: throw megaglest_runtime_error("detected unsupported pathfinder type!"); } - //printf("In [%s::%s Line: %d] END pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str()); - //fflush(stdout); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); - if(frameIndex < 0) { - if(command->getUnit() != NULL && !command->getUnit()->isAlive() && unit->getCommandSize() > 1) { - // don't run over to dead body if there is still something to do in the queue - unit->finishCommand(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateAttack]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - } - else { - //if unit arrives destPos order has ended - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0 && - SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"#1 [updateAttack] tsValue = %d",tsValue); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } + if (frameIndex < 0) { switch (tsValue) { case tsMoving: - unit->setCurrSkill(act->getMoveSkillType()); + unit->setCurrSkill(mct->getMoveSkillType()); break; + case tsBlocked: - if(unit->getPath()->isBlocked()) { + unit->setCurrSkill(scStop); + if (unit->getPath()->isBlocked()) { unit->finishCommand(); } break; + default: unit->finishCommand(); break; + } + } + + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateMove] tsValue [%d]", tsValue); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + } catch (const exception &ex) { + //setRunningStatus(false); + + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + throw megaglest_runtime_error(ex.what()); + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + + } + + + // ==================== updateAttack ==================== + + void UnitUpdater::updateAttack(Unit *unit, int frameIndex) { + try { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateAttack]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + + Command *command = unit->getCurrCommand(); + if (command == NULL) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateAttack]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + + return; + } + const AttackCommandType *act = static_cast(command->getCommandType()); + if (act == NULL) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateAttack]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + + return; + } + Unit *target = NULL; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + if ((command->getUnit() == NULL || !(command->getUnit()->isAlive())) && unit->getCommandSize() > 1) { + + if (frameIndex < 0) { + unit->finishCommand(); // all queued "ground attacks" are skipped if somthing else is queued after them. + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateAttack]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); } - /* - case tsMoving: - unit->setCurrSkill(act->getMoveSkillType()); - - { - std::pair beingAttacked = unitBeingAttacked(unit); - if(beingAttacked.first == true) { - Unit *enemy = beingAttacked.second; - const AttackCommandType *act_forenemy = unit->getType()->getFirstAttackCommand(enemy->getCurrField()); - if(act_forenemy != NULL) { - if(unit->getEp() >= act_forenemy->getAttackSkillType()->getEpCost()) { - unit->setCurrSkill(act_forenemy->getAttackSkillType()); - unit->setTarget(enemy); - } - //aiInterface->giveCommand(i, act_forenemy, beingAttacked.second->getPos()); - } - else { - const AttackStoppedCommandType *asct_forenemy = unit->getType()->getFirstAttackStoppedCommand(enemy->getCurrField()); - if(asct_forenemy != NULL) { - //aiInterface->giveCommand(i, asct_forenemy, beingAttacked.second->getCenteredPos()); - if(unit->getEp() >= asct_forenemy->getAttackSkillType()->getEpCost()) { - unit->setCurrSkill(asct_forenemy->getAttackSkillType()); - unit->setTarget(enemy); - } - } - } - } - } - - break; - - case tsBlocked: - if(unit->getPath()->isBlocked()){ - unit->finishCommand(); - } - break; - default: - unit->finishCommand(); } - */ - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0 && - SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"#2 [updateAttack] tsValue = %d",tsValue); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - + return; } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - } - catch(const exception &ex) { - //setRunningStatus(false); - - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Loc [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - throw megaglest_runtime_error(ex.what()); - } - catch(...) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - throw megaglest_runtime_error(szBuf); - } - -} - - -// ==================== updateAttackStopped ==================== - -void UnitUpdater::updateAttackStopped(Unit *unit, int frameIndex) { - try { - - // Nothing to do - if(frameIndex >= 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex >= 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateAttackStopped]"); - unit->logSynchDataThreaded(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - clearUnitPrecache(unit); - return; - } - - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - - Command *command= unit->getCurrCommand(); - if(command == NULL) { - throw megaglest_runtime_error("command == NULL"); - } - - const AttackStoppedCommandType *asct= static_cast(command->getCommandType()); - Unit *enemy=NULL; - - - if(unit->getCommandSize() > 1) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateAttackStopped]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - - unit->finishCommand(); // attackStopped is skipped if somthing else is queued after this. - return; - } - - - float distToUnit=-1; - std::pair result = make_pair(false,(Unit *)NULL); - unitBeingAttacked(result, unit, asct->getAttackSkillType(), &distToUnit); - - - if(result.first == true) { - unit->setCurrSkill(asct->getAttackSkillType()); - unit->setTarget(result.second); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateAttackStopped]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - } - else if(attackableOnRange(unit, &enemy, asct->getAttackSkillType(),(frameIndex >= 0))) { - unit->setCurrSkill(asct->getAttackSkillType()); - unit->setTarget(enemy); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateAttackStopped]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - } - else { - unit->setCurrSkill(asct->getStopSkillType()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateAttackStopped]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - } - catch(const exception &ex) { - //setRunningStatus(false); - - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - throw megaglest_runtime_error(ex.what()); - } - catch(...) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - throw megaglest_runtime_error(szBuf); - } - -} - -void UnitUpdater::unitBeingAttacked(std::pair &result, const Unit *unit, const AttackSkillType *ast, float *currentDistToUnit) { - //std::pair result = make_pair(false,(Unit *)NULL); - - float distToUnit = -1; - if(currentDistToUnit != NULL) { - distToUnit = *currentDistToUnit; - } - if(ast != NULL) { - vector enemies = enemyUnitsOnRange(unit,ast); - for(unsigned j = 0; j < enemies.size(); ++j) { - Unit *enemy = enemies[j]; - - //printf("~~~~~~~~ Unit [%s - %d] enemy # %d found enemy [%s - %d] distToUnit = %f\n",unit->getFullName().c_str(),unit->getId(),j,enemy->getFullName().c_str(),enemy->getId(),unit->getCenteredPos().dist(enemy->getCenteredPos())); - - if(distToUnit < 0 || unit->getCenteredPos().dist(enemy->getCenteredPos()) < distToUnit) { - distToUnit = unit->getCenteredPos().dist(enemy->getCenteredPos()); - if(ast->getAttackRange() >= distToUnit){ - result.first= true; - result.second= enemy; - break; - } - } - } - } - - if(currentDistToUnit != NULL) { - *currentDistToUnit = distToUnit; - } - -// if(result.first == true) { -// printf("~~~~~~~~ Unit [%s - %d] found enemy [%s - %d] distToUnit = %f\n",unit->getFullName().c_str(),unit->getId(),result.second->getFullName().c_str(),result.second->getId(),distToUnit); -// } - //return result; -} - -std::pair UnitUpdater::unitBeingAttacked(const Unit *unit) { - std::pair result = make_pair(false,(Unit *)NULL); - - float distToUnit = -1; - for(unsigned int i = 0; i < (unsigned int)unit->getType()->getSkillTypeCount(); ++i) { - const SkillType *st = unit->getType()->getSkillType(i); - const AttackSkillType *ast = dynamic_cast(st); - unitBeingAttacked(result, unit, ast, &distToUnit); - } - -// if(result.first == true) { -// printf("~~~~~~~~ Unit [%s - %d] found enemy [%s - %d] distToUnit = %f\n",unit->getFullName().c_str(),unit->getId(),result.second->getFullName().c_str(),result.second->getId(),distToUnit); -// } - return result; -} - -// ==================== updateBuild ==================== - -void UnitUpdater::updateBuild(Unit *unit, int frameIndex) { - try { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateBuild]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] unit [%s] will build using command [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString(false).c_str(), unit->getCurrCommand()->toString(false).c_str()); - - Command *command= unit->getCurrCommand(); - if(command == NULL) { - throw megaglest_runtime_error("command == NULL"); - } - - const BuildCommandType *bct= static_cast(command->getCommandType()); - - if(unit->getCurrSkill() != NULL && unit->getCurrSkill()->getClass() != scBuild) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //if not building - const UnitType *ut= command->getUnitType(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - TravelState tsValue = tsImpossible; - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: + //if found + //if(frameIndex < 0) { { - Vec2i buildPos = map->findBestBuildApproach(unit, command->getPos(), ut); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateBuild] unit->getPos() [%s] command->getPos() [%s] buildPos [%s]", - unit->getPos().getString().c_str(),command->getPos().getString().c_str(),buildPos.getString().c_str()); - unit->logSynchData(__FILE__,__LINE__,szBuf); - } - - tsValue = pathFinder->findPath(unit, buildPos, NULL, frameIndex); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateBuild] tsValue: %d",tsValue); - unit->logSynchData(__FILE__,__LINE__,szBuf); - } - - } - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] tsValue = %d\n",__FILE__,__FUNCTION__,__LINE__,tsValue); - - if(frameIndex < 0) { - switch (tsValue) { - case tsMoving: - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] tsMoving\n",__FILE__,__FUNCTION__,__LINE__); - - unit->setCurrSkill(bct->getMoveSkillType()); - break; - - case tsArrived: - { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] tsArrived:\n",__FILE__,__FUNCTION__,__LINE__); - - //if arrived destination - assert(ut); - if(ut == NULL) { - throw megaglest_runtime_error("ut == NULL"); - } - - bool canOccupyCell = false; - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] tsArrived about to call map->isFreeCells() for command->getPos() = %s, ut->getSize() = %d\n",__FILE__,__FUNCTION__,__LINE__,command->getPos().getString().c_str(),ut->getSize()); - canOccupyCell = map->isFreeCells(command->getPos(), ut->getSize(), fLand); - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] canOccupyCell = %d\n",__FILE__,__FUNCTION__,__LINE__,canOccupyCell); - - if (canOccupyCell == true) { - const UnitType *builtUnitType= command->getUnitType(); - CardinalDir facing = command->getFacing(); - - UnitPathInterface *newpath = NULL; - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - newpath = new UnitPathBasic(); - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } - - Vec2i buildPos = command->getPos(); - Unit *builtUnit= new Unit(world->getNextUnitId(unit->getFaction()), newpath, buildPos, builtUnitType, unit->getFaction(), world->getMap(), facing); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - builtUnit->create(); - - if(builtUnitType->hasSkillClass(scBeBuilt) == false) { - throw megaglest_runtime_error("Unit [" + builtUnitType->getName(false) + "] has no be_built skill, producer was [" + intToStr(unit->getId()) + " - " + unit->getType()->getName(false) + "]."); - } - - builtUnit->setCurrSkill(scBeBuilt); - - unit->setCurrSkill(bct->getBuildSkillType()); - unit->setTarget(builtUnit); - - - map->prepareTerrain(builtUnit); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } - - command->setUnit(builtUnit); - - - //play start sound - if(unit->getFactionIndex() == world->getThisFactionIndex() || - (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)) { - SoundRenderer::getInstance().playFx( - bct->getStartSound(), - unit->getCurrMidHeightVector(), - gameCamera->getPos()); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,builtUnit->toString(false).c_str()); - } - else { - //if there are no free cells - unit->cancelCommand(); - unit->setCurrSkill(scStop); - - if(unit->getFactionIndex() == world->getThisFactionIndex()) { - console->addStdMessage("BuildingNoPlace"); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] got BuildingNoPlace\n",__FILE__,__FUNCTION__,__LINE__); - } - } - break; - - case tsBlocked: - if(unit->getPath()->isBlocked()) { - unit->cancelCommand(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] got tsBlocked\n",__FILE__,__FUNCTION__,__LINE__); - } - break; - } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] tsArrived unit = %s\n",__FILE__,__FUNCTION__,__LINE__,unit->toString(false).c_str()); - - if(frameIndex < 0) { - //if building - Unit *builtUnit = map->getCell(unit->getTargetPos())->getUnit(fLand); - if(builtUnit == NULL) { - builtUnit = map->getCell(unit->getTargetPos())->getUnitWithEmptyCellMap(fLand); - } - - if(builtUnit != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] builtUnit = %s\n",__FILE__,__FUNCTION__,__LINE__,builtUnit->toString(false).c_str()); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] builtUnit = [%p]\n",__FILE__,__FUNCTION__,__LINE__,builtUnit); - - //if unit is killed while building then u==NULL; - if(builtUnit != NULL && builtUnit != command->getUnit()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] builtUnit is not the command's unit!\n",__FILE__,__FUNCTION__,__LINE__); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateBuild]"); - unit->logSynchData(__FILE__,__LINE__,szBuf); - } - - unit->setCurrSkill(scStop); - } - else if(builtUnit == NULL || builtUnit->isBuilt()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] builtUnit is NULL or ALREADY built\n",__FILE__,__FUNCTION__,__LINE__); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateBuild]"); - unit->logSynchData(__FILE__,__LINE__,szBuf); - } - - unit->finishCommand(); - unit->setCurrSkill(scStop); - - } - else if(builtUnit == NULL || builtUnit->repair()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateBuild]"); - unit->logSynchData(__FILE__,__LINE__,szBuf); - } - - const CommandType *ct = (command != NULL ? command->getCommandType() : NULL); - //building finished - unit->finishCommand(); - unit->setCurrSkill(scStop); - - builtUnit->born(ct); - scriptManager->onUnitCreated(builtUnit); - if(unit->getFactionIndex() == world->getThisFactionIndex() || - (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)) { - SoundRenderer::getInstance().playFx( - bct->getBuiltSound(), - unit->getCurrMidHeightVector(), - gameCamera->getPos()); - } - } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - } - catch(const exception &ex) { - //setRunningStatus(false); - - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - throw megaglest_runtime_error(ex.what()); - } - catch(...) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - throw megaglest_runtime_error(szBuf); - } - -} - -// ==================== updateHarvest ==================== -void UnitUpdater::updateHarvestEmergencyReturn(Unit *unit, int frameIndex) { - try { - - if(frameIndex >= 0) { - return; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateHarvestEmergencyReturn]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - - //printf("\n#1 updateHarvestEmergencyReturn\n"); - Command *command= unit->getCurrCommand(); - if(command != NULL) { - //printf("\n#2 updateHarvestEmergencyReturn\n"); - - //const HarvestCommandType *hct= dynamic_cast((command != NULL ? command->getCommandType() : NULL)); - //if(hct != NULL) { - { - //printf("\n#3 updateHarvestEmergencyReturn\n"); - - const Vec2i unitTargetPos = command->getPos(); - Cell *cell= map->getCell(unitTargetPos); - if(cell != NULL && cell->getUnit(unit->getCurrField()) != NULL) { - //printf("\n#4 updateHarvestEmergencyReturn\n"); - - Unit *targetUnit = cell->getUnit(unit->getCurrField()); - if(targetUnit != NULL) { - //printf("\n#5 updateHarvestEmergencyReturn\n"); - // Check if we can return whatever resources we have - if(targetUnit->getFactionIndex() == unit->getFactionIndex() && - targetUnit->isOperative() == true && unit->getLoadType() != NULL && - targetUnit->getType() != NULL && targetUnit->getType()->getStore(unit->getLoadType()) > 0) { - //printf("\n#6 updateHarvestEmergencyReturn\n"); - - const HarvestCommandType *previousHarvestCmd = unit->getType()->getFirstHarvestCommand(unit->getLoadType(),unit->getFaction()); - if(previousHarvestCmd != NULL) { - //printf("\n\n#1a return harvested resources\n\n"); - NetworkCommand networkCommand(this->world,nctGiveCommand, unit->getId(), previousHarvestCmd->getId(), unit->getLastHarvestedResourcePos(), - -1, Unit::invalidId, -1, false, cst_None, -1, -1); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - Command* new_command= this->game->getCommander()->buildCommand(&networkCommand); - new_command->setStateType(cst_EmergencyReturnResource); - new_command->setStateValue(1); - std::pair cr= unit->checkCommand(new_command); - if(cr.first == crSuccess) { - //printf("\n\n#1b return harvested resources\n\n"); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - unit->replaceCurrCommand(new_command); - - unit->setCurrSkill(previousHarvestCmd->getStopLoadedSkillType()); // make sure we use the right harvest animation - } - else { - //printf("\n\n#1c return harvested resources\n\n"); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - delete new_command; - + if (attackableOnRange(unit, &target, act->getAttackSkillType(), (frameIndex >= 0))) { + if (frameIndex < 0) { + if (unit->getEp() >= act->getAttackSkillType()->getEpCost()) { + unit->setCurrSkill(act->getAttackSkillType()); + unit->setTarget(target); + } else { unit->setCurrSkill(scStop); - unit->finishCommand(); } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateAttack]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + } else { + //compute target pos + Vec2i pos; + if (command->getUnit() != NULL) { + pos = command->getUnit()->getCenteredPos(); + } else if (attackableOnSight(unit, &target, act->getAttackSkillType(), (frameIndex >= 0))) { + pos = target->getPos(); + } else { + pos = command->getPos(); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateAttack] pos [%s] unit->getPos() [%s]", pos.getString().c_str(), unit->getPos().getString().c_str()); + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + TravelState tsValue = tsImpossible; + //if(frameIndex < 0) { + { + //printf("In [%s::%s Line: %d] START pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str()); + //fflush(stdout); + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + tsValue = pathFinder->findPath(unit, pos, NULL, frameIndex); + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } + //printf("In [%s::%s Line: %d] END pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str()); + //fflush(stdout); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + if (frameIndex < 0) { + if (command->getUnit() != NULL && !command->getUnit()->isAlive() && unit->getCommandSize() > 1) { + // don't run over to dead body if there is still something to do in the queue + unit->finishCommand(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateAttack]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + } else { + //if unit arrives destPos order has ended + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0 && + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "#1 [updateAttack] tsValue = %d", tsValue); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + + switch (tsValue) { + case tsMoving: + unit->setCurrSkill(act->getMoveSkillType()); + break; + case tsBlocked: + if (unit->getPath()->isBlocked()) { + unit->finishCommand(); + } + break; + default: + unit->finishCommand(); + break; + } + /* + case tsMoving: + unit->setCurrSkill(act->getMoveSkillType()); + + { + std::pair beingAttacked = unitBeingAttacked(unit); + if(beingAttacked.first == true) { + Unit *enemy = beingAttacked.second; + const AttackCommandType *act_forenemy = unit->getType()->getFirstAttackCommand(enemy->getCurrField()); + if(act_forenemy != NULL) { + if(unit->getEp() >= act_forenemy->getAttackSkillType()->getEpCost()) { + unit->setCurrSkill(act_forenemy->getAttackSkillType()); + unit->setTarget(enemy); + } + //aiInterface->giveCommand(i, act_forenemy, beingAttacked.second->getPos()); + } + else { + const AttackStoppedCommandType *asct_forenemy = unit->getType()->getFirstAttackStoppedCommand(enemy->getCurrField()); + if(asct_forenemy != NULL) { + //aiInterface->giveCommand(i, asct_forenemy, beingAttacked.second->getCenteredPos()); + if(unit->getEp() >= asct_forenemy->getAttackSkillType()->getEpCost()) { + unit->setCurrSkill(asct_forenemy->getAttackSkillType()); + unit->setTarget(enemy); + } + } + } + } + } + + break; + + case tsBlocked: + if(unit->getPath()->isBlocked()){ + unit->finishCommand(); + } + break; + default: + unit->finishCommand(); + } + */ + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0 && + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "#2 [updateAttack] tsValue = %d", tsValue); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + } catch (const exception &ex) { + //setRunningStatus(false); + + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Loc [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + throw megaglest_runtime_error(ex.what()); + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + + } + + + // ==================== updateAttackStopped ==================== + + void UnitUpdater::updateAttackStopped(Unit *unit, int frameIndex) { + try { + + // Nothing to do + if (frameIndex >= 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex >= 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateAttackStopped]"); + unit->logSynchDataThreaded(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + clearUnitPrecache(unit); + return; + } + + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + + Command *command = unit->getCurrCommand(); + if (command == NULL) { + throw megaglest_runtime_error("command == NULL"); + } + + const AttackStoppedCommandType *asct = static_cast(command->getCommandType()); + Unit *enemy = NULL; + + + if (unit->getCommandSize() > 1) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateAttackStopped]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + + unit->finishCommand(); // attackStopped is skipped if somthing else is queued after this. + return; + } + + + float distToUnit = -1; + std::pair result = make_pair(false, (Unit *) NULL); + unitBeingAttacked(result, unit, asct->getAttackSkillType(), &distToUnit); + + + if (result.first == true) { + unit->setCurrSkill(asct->getAttackSkillType()); + unit->setTarget(result.second); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateAttackStopped]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + } else if (attackableOnRange(unit, &enemy, asct->getAttackSkillType(), (frameIndex >= 0))) { + unit->setCurrSkill(asct->getAttackSkillType()); + unit->setTarget(enemy); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateAttackStopped]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + } else { + unit->setCurrSkill(asct->getStopSkillType()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateAttackStopped]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + } catch (const exception &ex) { + //setRunningStatus(false); + + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + throw megaglest_runtime_error(ex.what()); + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + + } + + void UnitUpdater::unitBeingAttacked(std::pair &result, const Unit *unit, const AttackSkillType *ast, float *currentDistToUnit) { + //std::pair result = make_pair(false,(Unit *)NULL); + + float distToUnit = -1; + if (currentDistToUnit != NULL) { + distToUnit = *currentDistToUnit; + } + if (ast != NULL) { + vector enemies = enemyUnitsOnRange(unit, ast); + for (unsigned j = 0; j < enemies.size(); ++j) { + Unit *enemy = enemies[j]; + + //printf("~~~~~~~~ Unit [%s - %d] enemy # %d found enemy [%s - %d] distToUnit = %f\n",unit->getFullName().c_str(),unit->getId(),j,enemy->getFullName().c_str(),enemy->getId(),unit->getCenteredPos().dist(enemy->getCenteredPos())); + + if (distToUnit < 0 || unit->getCenteredPos().dist(enemy->getCenteredPos()) < distToUnit) { + distToUnit = unit->getCenteredPos().dist(enemy->getCenteredPos()); + if (ast->getAttackRange() >= distToUnit) { + result.first = true; + result.second = enemy; + break; } } } } + + if (currentDistToUnit != NULL) { + *currentDistToUnit = distToUnit; + } + + // if(result.first == true) { + // printf("~~~~~~~~ Unit [%s - %d] found enemy [%s - %d] distToUnit = %f\n",unit->getFullName().c_str(),unit->getId(),result.second->getFullName().c_str(),result.second->getId(),distToUnit); + // } + //return result; } - } - } - catch(const exception &ex) { - //setRunningStatus(false); + std::pair UnitUpdater::unitBeingAttacked(const Unit *unit) { + std::pair result = make_pair(false, (Unit *) NULL); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + float distToUnit = -1; + for (unsigned int i = 0; i < (unsigned int) unit->getType()->getSkillTypeCount(); ++i) { + const SkillType *st = unit->getType()->getSkillType(i); + const AttackSkillType *ast = dynamic_cast(st); + unitBeingAttacked(result, unit, ast, &distToUnit); + } - throw megaglest_runtime_error(ex.what()); - } - catch(...) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - throw megaglest_runtime_error(szBuf); - } + // if(result.first == true) { + // printf("~~~~~~~~ Unit [%s - %d] found enemy [%s - %d] distToUnit = %f\n",unit->getFullName().c_str(),unit->getId(),result.second->getFullName().c_str(),result.second->getId(),distToUnit); + // } + return result; + } -} + // ==================== updateBuild ==================== -void UnitUpdater::updateHarvest(Unit *unit, int frameIndex) { - try { + void UnitUpdater::updateBuild(Unit *unit, int frameIndex) { + try { - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateHarvest]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateBuild]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - Command *command= unit->getCurrCommand(); - if(command == NULL) { - throw megaglest_runtime_error("command == NULL"); - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] unit [%s] will build using command [%s]\n", __FILE__, __FUNCTION__, __LINE__, unit->toString(false).c_str(), unit->getCurrCommand()->toString(false).c_str()); - const HarvestCommandType *hct= dynamic_cast(command->getCommandType()); - if(hct == NULL) { - throw megaglest_runtime_error("hct == NULL"); - } - Vec2i targetPos(-1); + Command *command = unit->getCurrCommand(); + if (command == NULL) { + throw megaglest_runtime_error("command == NULL"); + } - //TravelState tsValue = tsImpossible; - //UnitPathInterface *path= unit->getPath(); + const BuildCommandType *bct = static_cast(command->getCommandType()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - //printf("In UpdateHarvest [%d - %s] unit->getCurrSkill()->getClass() = %d\n",unit->getId(),unit->getType()->getName().c_str(),unit->getCurrSkill()->getClass()); + if (unit->getCurrSkill() != NULL && unit->getCurrSkill()->getClass() != scBuild) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - Resource *harvestResource = NULL; - SurfaceCell *sc = map->getSurfaceCell(Map::toSurfCoords(command->getPos())); - if(sc != NULL) { - harvestResource = sc->getResource(); - } + //if not building + const UnitType *ut = command->getUnitType(); - if(unit->getCurrSkill() != NULL && unit->getCurrSkill()->getClass() != scHarvest) { - bool forceReturnToStore = (command != NULL && - command->getStateType() == cst_EmergencyReturnResource && command->getStateValue() == 1); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); - //if not working - if(unit->getLoadCount() == 0 || - (forceReturnToStore == false && unit->getLoadType() != NULL && - harvestResource != NULL && (unit->getLoadCount() < hct->getMaxLoad()) && - harvestResource->getType() != NULL && unit->getLoadType() == harvestResource->getType())) { - //if not loaded go for resources - SurfaceCell *sc = map->getSurfaceCell(Map::toSurfCoords(command->getPos())); - if(sc != NULL) { - Resource *r = sc->getResource(); - if(r != NULL && hct != NULL && hct->canHarvest(r->getType())) { - //if can harvest dest. pos - bool canHarvestDestPos = false; + TravelState tsValue = tsImpossible; + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + { + Vec2i buildPos = map->findBestBuildApproach(unit, command->getPos(), ut); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - { - const bool newHarvestPath = false; - bool isNearResource = false; - Vec2i clickPos = command->getOriginalPos(); - if(newHarvestPath == true) { - isNearResource = map->isResourceNear(frameIndex,unit->getPos(), r->getType(), targetPos,unit->getType()->getSize(),unit, false,&clickPos); - } - else { - isNearResource = map->isResourceNear(frameIndex,unit->getPos(), r->getType(), targetPos,unit->getType()->getSize(),unit); - } - if(isNearResource == true) { - if((unit->getPos().dist(command->getPos()) < harvestDistance || unit->getPos().dist(targetPos) < harvestDistance) && isNearResource == true) { - canHarvestDestPos = true; - } - } - else if(newHarvestPath == true) { - if(clickPos != command->getOriginalPos()) { - //printf("%%----------- unit [%s - %d] CHANGING RESOURCE POS from [%s] to [%s]\n",unit->getFullName().c_str(),unit->getId(),command->getOriginalPos().getString().c_str(),clickPos.getString().c_str()); - - if(frameIndex < 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateHarvest] clickPos [%s]",clickPos.getString().c_str()); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - - command->setPos(clickPos); - } - } - } - } - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - if (canHarvestDestPos == true ) { - if(frameIndex < 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateHarvest]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateBuild] unit->getPos() [%s] command->getPos() [%s] buildPos [%s]", + unit->getPos().getString().c_str(), command->getPos().getString().c_str(), buildPos.getString().c_str()); + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + + tsValue = pathFinder->findPath(unit, buildPos, NULL, frameIndex); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateBuild] tsValue: %d", tsValue); + unit->logSynchData(__FILE__, __LINE__, szBuf); } - unit->setLastHarvestResourceTarget(NULL); } + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } - canHarvestDestPos = (map->getSurfaceCell(Map::toSurfCoords(targetPos)) != NULL && map->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource() != NULL && map->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource()->getType() != NULL); + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] tsValue = %d\n", __FILE__, __FUNCTION__, __LINE__, tsValue); - if(canHarvestDestPos == true) { - if(frameIndex < 0) { - //if it finds resources it starts harvesting - unit->setCurrSkill(hct->getHarvestSkillType()); - unit->setTargetPos(targetPos); - command->setPos(targetPos); + if (frameIndex < 0) { + switch (tsValue) { + case tsMoving: + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] tsMoving\n", __FILE__, __FUNCTION__, __LINE__); - if(unit->getLoadType() == NULL || harvestResource == NULL || - harvestResource->getType() == NULL || unit->getLoadType() != harvestResource->getType()) { - unit->setLoadCount(0); + unit->setCurrSkill(bct->getMoveSkillType()); + break; + + case tsArrived: + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] tsArrived:\n", __FILE__, __FUNCTION__, __LINE__); + + //if arrived destination + assert(ut); + if (ut == NULL) { + throw megaglest_runtime_error("ut == NULL"); } - unit->getFaction()->addResourceTargetToCache(targetPos); - - switch(this->game->getGameSettings()->getPathFinderType()) { + bool canOccupyCell = false; + switch (this->game->getGameSettings()->getPathFinderType()) { case pfBasic: - unit->setLoadType(r->getType()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] tsArrived about to call map->isFreeCells() for command->getPos() = %s, ut->getSize() = %d\n", __FILE__, __FUNCTION__, __LINE__, command->getPos().getString().c_str(), ut->getSize()); + canOccupyCell = map->isFreeCells(command->getPos(), ut->getSize(), fLand); break; default: throw megaglest_runtime_error("detected unsupported pathfinder type!"); } - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateHarvest] targetPos [%s]",targetPos.getString().c_str()); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] canOccupyCell = %d\n", __FILE__, __FUNCTION__, __LINE__, canOccupyCell); + + if (canOccupyCell == true) { + const UnitType *builtUnitType = command->getUnitType(); + CardinalDir facing = command->getFacing(); + + UnitPathInterface *newpath = NULL; + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + newpath = new UnitPathBasic(); + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } + + Vec2i buildPos = command->getPos(); + Unit *builtUnit = new Unit(world->getNextUnitId(unit->getFaction()), newpath, buildPos, builtUnitType, unit->getFaction(), world->getMap(), facing); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + builtUnit->create(); + + if (builtUnitType->hasSkillClass(scBeBuilt) == false) { + throw megaglest_runtime_error("Unit [" + builtUnitType->getName(false) + "] has no be_built skill, producer was [" + intToStr(unit->getId()) + " - " + unit->getType()->getName(false) + "]."); + } + + builtUnit->setCurrSkill(scBeBuilt); + + unit->setCurrSkill(bct->getBuildSkillType()); + unit->setTarget(builtUnit); + + + map->prepareTerrain(builtUnit); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } + + command->setUnit(builtUnit); + + + //play start sound + if (unit->getFactionIndex() == world->getThisFactionIndex() || + (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)) { + SoundRenderer::getInstance().playFx( + bct->getStartSound(), + unit->getCurrMidHeightVector(), + gameCamera->getPos()); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] unit created for unit [%s]\n", __FILE__, __FUNCTION__, __LINE__, builtUnit->toString(false).c_str()); + } else { + //if there are no free cells + unit->cancelCommand(); + unit->setCurrSkill(scStop); + + if (unit->getFactionIndex() == world->getThisFactionIndex()) { + console->addStdMessage("BuildingNoPlace"); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] got BuildingNoPlace\n", __FILE__, __FUNCTION__, __LINE__); } } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + break; + + case tsBlocked: + if (unit->getPath()->isBlocked()) { + unit->cancelCommand(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] got tsBlocked\n", __FILE__, __FUNCTION__, __LINE__); + } + break; } } - if(canHarvestDestPos == false) { - if(frameIndex < 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateHarvest] targetPos [%s]",targetPos.getString().c_str()); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] tsArrived unit = %s\n", __FILE__, __FUNCTION__, __LINE__, unit->toString(false).c_str()); + + if (frameIndex < 0) { + //if building + Unit *builtUnit = map->getCell(unit->getTargetPos())->getUnit(fLand); + if (builtUnit == NULL) { + builtUnit = map->getCell(unit->getTargetPos())->getUnitWithEmptyCellMap(fLand); + } + + if (builtUnit != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] builtUnit = %s\n", __FILE__, __FUNCTION__, __LINE__, builtUnit->toString(false).c_str()); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] builtUnit = [%p]\n", __FILE__, __FUNCTION__, __LINE__, builtUnit); + + //if unit is killed while building then u==NULL; + if (builtUnit != NULL && builtUnit != command->getUnit()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] builtUnit is not the command's unit!\n", __FILE__, __FUNCTION__, __LINE__); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateBuild]"); + unit->logSynchData(__FILE__, __LINE__, szBuf); } - unit->setLastHarvestResourceTarget(&targetPos); + unit->setCurrSkill(scStop); + } else if (builtUnit == NULL || builtUnit->isBuilt()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] builtUnit is NULL or ALREADY built\n", __FILE__, __FUNCTION__, __LINE__); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateBuild]"); + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + + unit->finishCommand(); + unit->setCurrSkill(scStop); + + } else if (builtUnit == NULL || builtUnit->repair()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateBuild]"); + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + + const CommandType *ct = (command != NULL ? command->getCommandType() : NULL); + //building finished + unit->finishCommand(); + unit->setCurrSkill(scStop); + + builtUnit->born(ct); + scriptManager->onUnitCreated(builtUnit); + if (unit->getFactionIndex() == world->getThisFactionIndex() || + (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)) { + SoundRenderer::getInstance().playFx( + bct->getBuiltSound(), + unit->getCurrMidHeightVector(), + gameCamera->getPos()); + } } + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateHarvest] unit->getPos() [%s] command->getPos() [%s]", - unit->getPos().getString().c_str(),command->getPos().getString().c_str()); - unit->logSynchData(__FILE__,__LINE__,szBuf); - } + } catch (const exception &ex) { + //setRunningStatus(false); - //if not continue walking - bool wasStuck = false; - TravelState tsValue = tsImpossible; - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - tsValue = pathFinder->findPath(unit, command->getPos(), &wasStuck, frameIndex); - if (tsValue == tsMoving && frameIndex < 0) { - unit->setCurrSkill(hct->getMoveSkillType()); + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + throw megaglest_runtime_error(ex.what()); + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + + } + + // ==================== updateHarvest ==================== + void UnitUpdater::updateHarvestEmergencyReturn(Unit *unit, int frameIndex) { + try { + + if (frameIndex >= 0) { + return; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateHarvestEmergencyReturn]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + + //printf("\n#1 updateHarvestEmergencyReturn\n"); + Command *command = unit->getCurrCommand(); + if (command != NULL) { + //printf("\n#2 updateHarvestEmergencyReturn\n"); + + //const HarvestCommandType *hct= dynamic_cast((command != NULL ? command->getCommandType() : NULL)); + //if(hct != NULL) { + { + //printf("\n#3 updateHarvestEmergencyReturn\n"); + + const Vec2i unitTargetPos = command->getPos(); + Cell *cell = map->getCell(unitTargetPos); + if (cell != NULL && cell->getUnit(unit->getCurrField()) != NULL) { + //printf("\n#4 updateHarvestEmergencyReturn\n"); + + Unit *targetUnit = cell->getUnit(unit->getCurrField()); + if (targetUnit != NULL) { + //printf("\n#5 updateHarvestEmergencyReturn\n"); + // Check if we can return whatever resources we have + if (targetUnit->getFactionIndex() == unit->getFactionIndex() && + targetUnit->isOperative() == true && unit->getLoadType() != NULL && + targetUnit->getType() != NULL && targetUnit->getType()->getStore(unit->getLoadType()) > 0) { + //printf("\n#6 updateHarvestEmergencyReturn\n"); + + const HarvestCommandType *previousHarvestCmd = unit->getType()->getFirstHarvestCommand(unit->getLoadType(), unit->getFaction()); + if (previousHarvestCmd != NULL) { + //printf("\n\n#1a return harvested resources\n\n"); + NetworkCommand networkCommand(this->world, nctGiveCommand, unit->getId(), previousHarvestCmd->getId(), unit->getLastHarvestedResourcePos(), + -1, Unit::invalidId, -1, false, cst_None, -1, -1); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + Command* new_command = this->game->getCommander()->buildCommand(&networkCommand); + new_command->setStateType(cst_EmergencyReturnResource); + new_command->setStateValue(1); + std::pair cr = unit->checkCommand(new_command); + if (cr.first == crSuccess) { + //printf("\n\n#1b return harvested resources\n\n"); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + unit->replaceCurrCommand(new_command); + + unit->setCurrSkill(previousHarvestCmd->getStopLoadedSkillType()); // make sure we use the right harvest animation + } else { + //printf("\n\n#1c return harvested resources\n\n"); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + delete new_command; + + unit->setCurrSkill(scStop); + unit->finishCommand(); + } + } } - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } + } + } + } + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + } catch (const exception &ex) { + //setRunningStatus(false); - // If the unit is blocked or Even worse 'stuck' then try to - // find the same resource type elsewhere, but close by - if((wasStuck == true || tsValue == tsBlocked) && unit->isAlive() == true) { - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + throw megaglest_runtime_error(ex.what()); + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + + } + + void UnitUpdater::updateHarvest(Unit *unit, int frameIndex) { + try { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateHarvest]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + + Command *command = unit->getCurrCommand(); + if (command == NULL) { + throw megaglest_runtime_error("command == NULL"); + } + + const HarvestCommandType *hct = dynamic_cast(command->getCommandType()); + if (hct == NULL) { + throw megaglest_runtime_error("hct == NULL"); + } + Vec2i targetPos(-1); + + //TravelState tsValue = tsImpossible; + //UnitPathInterface *path= unit->getPath(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + //printf("In UpdateHarvest [%d - %s] unit->getCurrSkill()->getClass() = %d\n",unit->getId(),unit->getType()->getName().c_str(),unit->getCurrSkill()->getClass()); + + Resource *harvestResource = NULL; + SurfaceCell *sc = map->getSurfaceCell(Map::toSurfCoords(command->getPos())); + if (sc != NULL) { + harvestResource = sc->getResource(); + } + + if (unit->getCurrSkill() != NULL && unit->getCurrSkill()->getClass() != scHarvest) { + bool forceReturnToStore = (command != NULL && + command->getStateType() == cst_EmergencyReturnResource && command->getStateValue() == 1); + + //if not working + if (unit->getLoadCount() == 0 || + (forceReturnToStore == false && unit->getLoadType() != NULL && + harvestResource != NULL && (unit->getLoadCount() < hct->getMaxLoad()) && + harvestResource->getType() != NULL && unit->getLoadType() == harvestResource->getType())) { + //if not loaded go for resources + SurfaceCell *sc = map->getSurfaceCell(Map::toSurfCoords(command->getPos())); + if (sc != NULL) { + Resource *r = sc->getResource(); + if (r != NULL && hct != NULL && hct->canHarvest(r->getType())) { + //if can harvest dest. pos + bool canHarvestDestPos = false; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: { - bool isNearResource = map->isResourceNear(frameIndex,unit->getPos(), r->getType(), targetPos,unit->getType()->getSize(),unit,true); - if(isNearResource == true) { - if((unit->getPos().dist(command->getPos()) < harvestDistance || unit->getPos().dist(targetPos) < harvestDistance) && isNearResource == true) { + const bool newHarvestPath = false; + bool isNearResource = false; + Vec2i clickPos = command->getOriginalPos(); + if (newHarvestPath == true) { + isNearResource = map->isResourceNear(frameIndex, unit->getPos(), r->getType(), targetPos, unit->getType()->getSize(), unit, false, &clickPos); + } else { + isNearResource = map->isResourceNear(frameIndex, unit->getPos(), r->getType(), targetPos, unit->getType()->getSize(), unit); + } + if (isNearResource == true) { + if ((unit->getPos().dist(command->getPos()) < harvestDistance || unit->getPos().dist(targetPos) < harvestDistance) && isNearResource == true) { canHarvestDestPos = true; } + } else if (newHarvestPath == true) { + if (clickPos != command->getOriginalPos()) { + //printf("%%----------- unit [%s - %d] CHANGING RESOURCE POS from [%s] to [%s]\n",unit->getFullName().c_str(),unit->getId(),command->getOriginalPos().getString().c_str(),clickPos.getString().c_str()); + + if (frameIndex < 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateHarvest] clickPos [%s]", clickPos.getString().c_str()); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + + command->setPos(clickPos); + } + } } } break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } - - if (canHarvestDestPos == true) { - if(frameIndex < 0) { - unit->setLastHarvestResourceTarget(NULL); + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); } - canHarvestDestPos = (map->getSurfaceCell(Map::toSurfCoords(targetPos)) != NULL && map->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource() != NULL && map->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource()->getType() != NULL); - if(canHarvestDestPos == true) { - if(frameIndex < 0) { - //if it finds resources it starts harvesting - unit->setCurrSkill(hct->getHarvestSkillType()); - unit->setTargetPos(targetPos); - command->setPos(targetPos); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); - if(unit->getLoadType() == NULL || harvestResource == NULL || - harvestResource->getType() == NULL || unit->getLoadType() != harvestResource->getType()) { - unit->setLoadCount(0); + if (canHarvestDestPos == true) { + if (frameIndex < 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateHarvest]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); } - unit->getFaction()->addResourceTargetToCache(targetPos); - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - unit->setLoadType(r->getType()); - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); + unit->setLastHarvestResourceTarget(NULL); + } + + canHarvestDestPos = (map->getSurfaceCell(Map::toSurfCoords(targetPos)) != NULL && map->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource() != NULL && map->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource()->getType() != NULL); + + if (canHarvestDestPos == true) { + if (frameIndex < 0) { + //if it finds resources it starts harvesting + unit->setCurrSkill(hct->getHarvestSkillType()); + unit->setTargetPos(targetPos); + command->setPos(targetPos); + + if (unit->getLoadType() == NULL || harvestResource == NULL || + harvestResource->getType() == NULL || unit->getLoadType() != harvestResource->getType()) { + unit->setLoadCount(0); + } + + unit->getFaction()->addResourceTargetToCache(targetPos); + + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + unit->setLoadType(r->getType()); + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateHarvest] targetPos [%s]", targetPos.getString().c_str()); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } } + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); } } + if (canHarvestDestPos == false) { + if (frameIndex < 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateHarvest] targetPos [%s]", targetPos.getString().c_str()); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } + unit->setLastHarvestResourceTarget(&targetPos); + } - if(canHarvestDestPos == false) { - if(frameIndex < 0) { - unit->setLastHarvestResourceTarget(&targetPos); - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateHarvest] unit->getPos() [%s] command->getPos() [%s]", + unit->getPos().getString().c_str(), command->getPos().getString().c_str()); + unit->logSynchData(__FILE__, __LINE__, szBuf); + } - if(targetPos.x >= 0) { //if not continue walking - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateHarvest #2] unit->getPos() [%s] command->getPos() [%s] targetPos [%s]", - unit->getPos().getString().c_str(),command->getPos().getString().c_str(),targetPos.getString().c_str()); - unit->logSynchData(__FILE__,__LINE__,szBuf); - } - - wasStuck = false; + bool wasStuck = false; TravelState tsValue = tsImpossible; - switch(this->game->getGameSettings()->getPathFinderType()) { + switch (this->game->getGameSettings()->getPathFinderType()) { case pfBasic: - tsValue = pathFinder->findPath(unit, targetPos, &wasStuck, frameIndex); + tsValue = pathFinder->findPath(unit, command->getPos(), &wasStuck, frameIndex); if (tsValue == tsMoving && frameIndex < 0) { unit->setCurrSkill(hct->getMoveSkillType()); - command->setPos(targetPos); } break; default: throw megaglest_runtime_error("detected unsupported pathfinder type!"); } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + // If the unit is blocked or Even worse 'stuck' then try to + // find the same resource type elsewhere, but close by + if ((wasStuck == true || tsValue == tsBlocked) && unit->isAlive() == true) { + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + { + bool isNearResource = map->isResourceNear(frameIndex, unit->getPos(), r->getType(), targetPos, unit->getType()->getSize(), unit, true); + if (isNearResource == true) { + if ((unit->getPos().dist(command->getPos()) < harvestDistance || unit->getPos().dist(targetPos) < harvestDistance) && isNearResource == true) { + canHarvestDestPos = true; + } + } + } + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } + + if (canHarvestDestPos == true) { + if (frameIndex < 0) { + unit->setLastHarvestResourceTarget(NULL); + } + + canHarvestDestPos = (map->getSurfaceCell(Map::toSurfCoords(targetPos)) != NULL && map->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource() != NULL && map->getSurfaceCell(Map::toSurfCoords(targetPos))->getResource()->getType() != NULL); + if (canHarvestDestPos == true) { + if (frameIndex < 0) { + //if it finds resources it starts harvesting + unit->setCurrSkill(hct->getHarvestSkillType()); + unit->setTargetPos(targetPos); + command->setPos(targetPos); + + if (unit->getLoadType() == NULL || harvestResource == NULL || + harvestResource->getType() == NULL || unit->getLoadType() != harvestResource->getType()) { + unit->setLoadCount(0); + } + unit->getFaction()->addResourceTargetToCache(targetPos); + + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + unit->setLoadType(r->getType()); + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + } + + if (canHarvestDestPos == false) { + if (frameIndex < 0) { + unit->setLastHarvestResourceTarget(&targetPos); + } + + if (targetPos.x >= 0) { + //if not continue walking + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateHarvest #2] unit->getPos() [%s] command->getPos() [%s] targetPos [%s]", + unit->getPos().getString().c_str(), command->getPos().getString().c_str(), targetPos.getString().c_str()); + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + + wasStuck = false; + TravelState tsValue = tsImpossible; + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + tsValue = pathFinder->findPath(unit, targetPos, &wasStuck, frameIndex); + if (tsValue == tsMoving && frameIndex < 0) { + unit->setCurrSkill(hct->getMoveSkillType()); + command->setPos(targetPos); + } + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + if (wasStuck == true && frameIndex < 0) { + //if can't harvest, search for another resource + unit->setCurrSkill(scStop); + if (searchForResource(unit, hct) == false) { + unit->finishCommand(); + } + } + } + } } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - if(wasStuck == true && frameIndex < 0) { + } else { + if (frameIndex < 0) { //if can't harvest, search for another resource unit->setCurrSkill(scStop); - if(searchForResource(unit, hct) == false) { + if (searchForResource(unit, hct) == false) { unit->finishCommand(); } - } - } - } - } - } - else { - if(frameIndex < 0) { - //if can't harvest, search for another resource - unit->setCurrSkill(scStop); - if(searchForResource(unit, hct) == false) { - unit->finishCommand(); - } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - //if loaded, return to store - Unit *store= world->nearestStore(unit->getPos(), unit->getFaction()->getIndex(), unit->getLoadType()); - if(store != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateHarvest #3] unit->getPos() [%s] store->getCenteredPos() [%s]", - unit->getPos().getString().c_str(),store->getCenteredPos().getString().c_str()); - unit->logSynchData(__FILE__,__LINE__,szBuf); - } - - TravelState tsValue = tsImpossible; - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - tsValue = pathFinder->findPath(unit, store->getCenteredPos(), NULL, frameIndex); - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - if(frameIndex < 0) { - switch(tsValue) { - case tsMoving: - { - if (hct->canHarvest(unit->getLoadType()) == false) { - // hct has changed to a different harvest command. - const HarvestCommandType *previousHarvestCmd = unit->getType()->getFirstHarvestCommand(unit->getLoadType(),unit->getFaction()); - if(previousHarvestCmd != NULL) { - //printf("\n\n#1\n\n"); - unit->setCurrSkill(previousHarvestCmd->getMoveLoadedSkillType()); // make sure we use the right harvest animation - } - else { - //printf("\n\n#2\n\n"); - unit->setCurrSkill(hct->getMoveLoadedSkillType()); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); } } - else { - unit->setCurrSkill(hct->getMoveLoadedSkillType()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + //if loaded, return to store + Unit *store = world->nearestStore(unit->getPos(), unit->getFaction()->getIndex(), unit->getLoadType()); + if (store != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateHarvest #3] unit->getPos() [%s] store->getCenteredPos() [%s]", + unit->getPos().getString().c_str(), store->getCenteredPos().getString().c_str()); + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + + TravelState tsValue = tsImpossible; + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + tsValue = pathFinder->findPath(unit, store->getCenteredPos(), NULL, frameIndex); + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + if (frameIndex < 0) { + switch (tsValue) { + case tsMoving: + { + if (hct->canHarvest(unit->getLoadType()) == false) { + // hct has changed to a different harvest command. + const HarvestCommandType *previousHarvestCmd = unit->getType()->getFirstHarvestCommand(unit->getLoadType(), unit->getFaction()); + if (previousHarvestCmd != NULL) { + //printf("\n\n#1\n\n"); + unit->setCurrSkill(previousHarvestCmd->getMoveLoadedSkillType()); // make sure we use the right harvest animation + } else { + //printf("\n\n#2\n\n"); + unit->setCurrSkill(hct->getMoveLoadedSkillType()); + } + } else { + unit->setCurrSkill(hct->getMoveLoadedSkillType()); + } + } + break; + default: + break; + } + + //world->changePosCells(unit,unit->getPos()+unit->getDest()); + if (map->isNextTo(unit, store)) { + //update resources + int resourceAmount = unit->getLoadCount(); + if (unit->getFaction()->getCpuControl()) { + int resourceMultiplierIndex = game->getGameSettings()->getResourceMultiplierIndex(unit->getFaction()->getIndex()); + resourceAmount = (resourceAmount* (resourceMultiplierIndex + 5)) / 10; + } + unit->getFaction()->incResourceAmount(unit->getLoadType(), resourceAmount); + world->getStats()->harvest(unit->getFactionIndex(), resourceAmount); + + scriptManager->onResourceHarvested(); + + //if next to a store unload resources + unit->getPath()->clear(); + unit->setCurrSkill(scStop); + unit->setLoadCount(0); + + command->setPosToOriginalPos(); + } + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + } else { + if (frameIndex < 0) { + unit->finishCommand(); + } } - } - break; - default: - break; } + } else { + if (frameIndex < 0) { + //if working + //unit->setLastHarvestResourceTarget(NULL); - //world->changePosCells(unit,unit->getPos()+unit->getDest()); - if(map->isNextTo(unit, store)) { - //update resources - int resourceAmount= unit->getLoadCount(); - if(unit->getFaction()->getCpuControl()) - { - int resourceMultiplierIndex=game->getGameSettings()->getResourceMultiplierIndex(unit->getFaction()->getIndex()); - resourceAmount=(resourceAmount* (resourceMultiplierIndex +5))/10; - } - unit->getFaction()->incResourceAmount(unit->getLoadType(), resourceAmount); - world->getStats()->harvest(unit->getFactionIndex(), resourceAmount); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); - scriptManager->onResourceHarvested(); + const Vec2i unitTargetPos = unit->getTargetPos(); + SurfaceCell *sc = map->getSurfaceCell(Map::toSurfCoords(unitTargetPos)); + Resource *r = sc->getResource(); - //if next to a store unload resources - unit->getPath()->clear(); - unit->setCurrSkill(scStop); - unit->setLoadCount(0); + if (r != NULL) { + if (hct->canHarvest(r->getType()) == false || + r->getType()->getName() != unit->getLoadType()->getName()) { + // hct has changed to a different harvest command. + if (r->getType()->getName() != unit->getLoadType()->getName()) { + const HarvestCommandType *previousHarvestCmd = unit->getType()->getFirstHarvestCommand(unit->getLoadType(), unit->getFaction()); + if (previousHarvestCmd != NULL) { + //printf("\n\n#1\n\n"); + unit->setCurrSkill(previousHarvestCmd->getStopLoadedSkillType()); // make sure we use the right harvest animation + } else { + //printf("\n\n#2\n\n"); + unit->setCurrSkill(hct->getStopLoadedSkillType()); + } + } else if (hct->canHarvest(r->getType()) == false) { + const HarvestCommandType *previousHarvestCmd = unit->getType()->getFirstHarvestCommand(unit->getLoadType(), unit->getFaction()); + if (previousHarvestCmd != NULL) { + //printf("\n\n#3\n\n"); + unit->setCurrSkill(previousHarvestCmd->getStopLoadedSkillType()); // make sure we use the right harvest animation + } else { + //printf("\n\n#4\n\n"); + unit->setCurrSkill(hct->getStopLoadedSkillType()); + } + } else { + //printf("\n\n#5 [%s] [%s]\n\n",r->getType()->getName().c_str(),unit->getLoadType()->getName().c_str()); + unit->setCurrSkill(hct->getStopLoadedSkillType()); // this is actually the wrong animation + } + unit->getPath()->clear(); - command->setPosToOriginalPos(); - } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } - else { - if(frameIndex < 0) { - unit->finishCommand(); - } - } - } - } - else { - if(frameIndex < 0) { - //if working - //unit->setLastHarvestResourceTarget(NULL); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + } else { + // if there is a resource, continue working, until loaded + unit->update2(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + unit->setLastHarvestedResourcePos(unitTargetPos); - const Vec2i unitTargetPos = unit->getTargetPos(); - SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(unitTargetPos)); - Resource *r= sc->getResource(); + if (unit->getProgress2() >= hct->getHitsPerUnit()) { + if (unit->getLoadCount() < hct->getMaxLoad()) { + unit->resetProgress2(); + unit->setLoadCount(unit->getLoadCount() + 1); - if (r != NULL) { - if (hct->canHarvest(r->getType()) == false || - r->getType()->getName() != unit->getLoadType()->getName()) { - // hct has changed to a different harvest command. - if(r->getType()->getName() != unit->getLoadType()->getName()) { - const HarvestCommandType *previousHarvestCmd = unit->getType()->getFirstHarvestCommand(unit->getLoadType(),unit->getFaction()); - if(previousHarvestCmd != NULL) { - //printf("\n\n#1\n\n"); - unit->setCurrSkill(previousHarvestCmd->getStopLoadedSkillType()); // make sure we use the right harvest animation - } - else { - //printf("\n\n#2\n\n"); + //if resource exausted, then delete it and stop + if (sc->decAmount(1)) { + //const ResourceType *rt = r->getType(); + sc->deleteResource(); + world->removeResourceTargetFromCache(unitTargetPos); + + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } + + //printf("\n\n#6\n\n"); + unit->setCurrSkill(hct->getStopLoadedSkillType()); + } + } + + if (unit->getLoadCount() >= hct->getMaxLoad()) { + //printf("\n\n#7\n\n"); + unit->setCurrSkill(hct->getStopLoadedSkillType()); + unit->getPath()->clear(); + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + } + } else { + //if there is no resource, just stop + //printf("\n\n#8\n\n"); unit->setCurrSkill(hct->getStopLoadedSkillType()); } } - else if(hct->canHarvest(r->getType()) == false) { - const HarvestCommandType *previousHarvestCmd = unit->getType()->getFirstHarvestCommand(unit->getLoadType(),unit->getFaction()); - if(previousHarvestCmd != NULL) { - //printf("\n\n#3\n\n"); - unit->setCurrSkill(previousHarvestCmd->getStopLoadedSkillType()); // make sure we use the right harvest animation - } - else { - //printf("\n\n#4\n\n"); - unit->setCurrSkill(hct->getStopLoadedSkillType()); - } - } - else { - //printf("\n\n#5 [%s] [%s]\n\n",r->getType()->getName().c_str(),unit->getLoadType()->getName().c_str()); - unit->setCurrSkill(hct->getStopLoadedSkillType()); // this is actually the wrong animation - } - unit->getPath()->clear(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); } - else { - // if there is a resource, continue working, until loaded - unit->update2(); - unit->setLastHarvestedResourcePos(unitTargetPos); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); - if (unit->getProgress2() >= hct->getHitsPerUnit()) { - if (unit->getLoadCount() < hct->getMaxLoad()) { - unit->resetProgress2(); - unit->setLoadCount(unit->getLoadCount() + 1); + } catch (const exception &ex) { + //setRunningStatus(false); - //if resource exausted, then delete it and stop - if (sc->decAmount(1)) { - //const ResourceType *rt = r->getType(); - sc->deleteResource(); - world->removeResourceTargetFromCache(unitTargetPos); + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - switch(this->game->getGameSettings()->getPathFinderType()) { + throw megaglest_runtime_error(ex.what()); + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + + } + + void UnitUpdater::SwapActiveCommand(Unit *unitSrc, Unit *unitDest) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (unitSrc->getCommandSize() > 0 && unitDest->getCommandSize() > 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + Command *cmd1 = unitSrc->getCurrCommand(); + Command *cmd2 = unitDest->getCurrCommand(); + unitSrc->replaceCurrCommand(cmd2); + unitDest->replaceCurrCommand(cmd1); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void UnitUpdater::SwapActiveCommandState(Unit *unit, CommandStateType commandStateType, + const CommandType *commandType, + int originalValue, int newValue) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (commandStateType == cst_linkedUnit) { + if (dynamic_cast(commandType) != NULL) { + + for (int i = 0; i < unit->getFaction()->getUnitCount(); ++i) { + Unit *peerUnit = unit->getFaction()->getUnit(i); + if (peerUnit != NULL) { + if (peerUnit->getCommandSize() > 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + Command *peerCommand = peerUnit->getCurrCommand(); + //const BuildCommandType *bct = dynamic_cast(peerCommand->getCommandType()); + //if(bct != NULL) { + if (peerCommand != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //if(command->getPos() == peerCommand->getPos()) { + if (peerCommand->getStateType() == commandStateType && + peerCommand->getStateValue() == originalValue) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + peerCommand->setStateValue(newValue); + } + } + } + } + } + + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + Unit * UnitUpdater::findPeerUnitBuilder(Unit *unit) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + Unit *foundUnitBuilder = NULL; + if (unit->getCommandSize() > 0) { + Command *command = unit->getCurrCommand(); + if (command != NULL) { + const RepairCommandType *rct = dynamic_cast(command->getCommandType()); + if (rct != NULL && command->getStateType() == cst_linkedUnit) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] looking for command->getStateValue() = %d\n", __FILE__, __FUNCTION__, __LINE__, command->getStateValue()); + + Unit *firstLinkedPeerRepairer = NULL; + + for (int i = 0; i < unit->getFaction()->getUnitCount(); ++i) { + Unit *peerUnit = unit->getFaction()->getUnit(i); + if (peerUnit != NULL) { + if (peerUnit->getCommandSize() > 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + Command *peerCommand = peerUnit->getCurrCommand(); + const BuildCommandType *bct = dynamic_cast(peerCommand->getCommandType()); + if (bct != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (command->getStateValue() == peerUnit->getId()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + foundUnitBuilder = peerUnit; + break; + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] **peer NOT building**, peerUnit = [%s]\n", __FILE__, __FUNCTION__, __LINE__, peerUnit->toString(false).c_str()); + + if (firstLinkedPeerRepairer == NULL) { + const RepairCommandType *prct = dynamic_cast(peerCommand->getCommandType()); + if (prct != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (unit->getId() != peerUnit->getId() && command->getStateValue() == peerUnit->getId()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + firstLinkedPeerRepairer = peerUnit; + } + } + } + } + } + } + } + + if (foundUnitBuilder == NULL && firstLinkedPeerRepairer != NULL) { + foundUnitBuilder = firstLinkedPeerRepairer; + } + } + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] returning foundUnitBuilder = [%s]\n", __FILE__, __FUNCTION__, __LINE__, (foundUnitBuilder != NULL ? foundUnitBuilder->toString(false).c_str() : "null")); + + return foundUnitBuilder; + } + + // ==================== updateRepair ==================== + + void UnitUpdater::updateRepair(Unit *unit, int frameIndex) { + try { + + // Nothing to do + if (frameIndex >= 0) { + clearUnitPrecache(unit); + return; + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateRepair]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] unit = %p\n", __FILE__, __FUNCTION__, __LINE__, unit); + + //if(unit != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] unit doing the repair [%s] - %d\n", __FILE__, __FUNCTION__, __LINE__, unit->getFullName(false).c_str(), unit->getId()); + //} + Command *command = unit->getCurrCommand(); + if (command == NULL) { + throw megaglest_runtime_error("command == NULL"); + } + + const RepairCommandType *rct = static_cast(command->getCommandType()); + const CommandType *ct = (command != NULL ? command->getCommandType() : NULL); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] rct = %p\n", __FILE__, __FUNCTION__, __LINE__, rct); + + Unit *repaired = (command != NULL ? map->getCell(command->getPos())->getUnitWithEmptyCellMap(fLand) : NULL); + if (repaired == NULL && command != NULL) { + repaired = map->getCell(command->getPos())->getUnit(fLand); + } + + if (repaired != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] unit to repair [%s] - %d\n", __FILE__, __FUNCTION__, __LINE__, repaired->getFullName(false).c_str(), repaired->getId()); + } + + if (chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + // Check if the 'repaired' unit is actually the peer unit in a multi-build? + Unit *peerUnitBuilder = findPeerUnitBuilder(unit); + + if (peerUnitBuilder != NULL) { + SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] unit peer [%s] - %d\n", __FILE__, __FUNCTION__, __LINE__, peerUnitBuilder->getFullName(false).c_str(), peerUnitBuilder->getId()); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + // Ensure we have the right unit to repair + if (peerUnitBuilder != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] peerUnitBuilder = %p\n", __FILE__, __FUNCTION__, __LINE__, peerUnitBuilder); + + if (peerUnitBuilder->getCurrCommand()->getUnit() != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] peerbuilder's unitid = %d\n", __FILE__, __FUNCTION__, __LINE__, peerUnitBuilder->getCurrCommand()->getUnit()->getId()); + repaired = peerUnitBuilder->getCurrCommand()->getUnit(); + } + } + + bool nextToRepaired = repaired != NULL && map->isNextTo(unit, repaired); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + peerUnitBuilder = NULL; + if (repaired == NULL) { + peerUnitBuilder = findPeerUnitBuilder(unit); + if (peerUnitBuilder != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] peerUnitBuilder = %p\n", __FILE__, __FUNCTION__, __LINE__, peerUnitBuilder); + + if (peerUnitBuilder->getCurrCommand()->getUnit() != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] peerbuilder's unitid = %d\n", __FILE__, __FUNCTION__, __LINE__, peerUnitBuilder->getCurrCommand()->getUnit()->getId()); + repaired = peerUnitBuilder->getCurrCommand()->getUnit(); + nextToRepaired = repaired != NULL && map->isNextTo(unit, repaired); + } else if (peerUnitBuilder->getCurrCommand()->getUnitType() != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + Vec2i buildPos = map->findBestBuildApproach(unit, command->getPos(), peerUnitBuilder->getCurrCommand()->getUnitType()); + + //nextToRepaired= (unit->getPos() == (command->getPos()-Vec2i(1))); + nextToRepaired = (unit->getPos() == buildPos); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] peerUnitBuilder = %p, nextToRepaired = %d\n", __FILE__, __FUNCTION__, __LINE__, peerUnitBuilder, nextToRepaired); + + if (nextToRepaired == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + Command *peerCommand = peerUnitBuilder->getCurrCommand(); + const RepairCommandType *rct = dynamic_cast(peerCommand->getCommandType()); + // If the peer is also scheduled to do a repair we CANNOT swap their commands or + // it will result in a stack overflow as each swaps the others repair command. + // We must convert this unit's repair into a build right now! + if (rct != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + const CommandType *ctbuild = unit->getType()->getFirstCtOfClass(ccBuild); + NetworkCommand networkCommand(this->world, nctGiveCommand, unit->getId(), ctbuild->getId(), command->getPos(), + command->getUnitType()->getId(), -1, CardinalDir(CardinalDir::NORTH), true, command->getStateType(), + command->getStateValue()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + Command* command = this->game->getCommander()->buildCommand(&networkCommand); + std::pair cr = unit->checkCommand(command); + if (cr.first == crSuccess) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + unit->replaceCurrCommand(command); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + delete command; + + unit->setCurrSkill(scStop); + unit->finishCommand(); + } + } else { + CommandStateType commandStateType = unit->getCurrCommand()->getStateType(); + SwapActiveCommand(unit, peerUnitBuilder); + int oldPeerUnitId = peerUnitBuilder->getId(); + int newPeerUnitId = unit->getId(); + SwapActiveCommandState(unit, commandStateType, unit->getCurrCommand()->getCommandType(), oldPeerUnitId, newPeerUnitId); + + // Give the swapped unit a fresh chance to help build in case they + // were or are about to be blocked + peerUnitBuilder->getPath()->clear(); + peerUnitBuilder->setRetryCurrCommandCount(1); + updateUnitCommand(unit, -1); + } + return; + } + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] unit to repair[%s]\n", __FILE__, __FUNCTION__, __LINE__, repaired->getFullName(false).c_str()); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] repaired = %p, nextToRepaired = %d, unit->getCurrSkill()->getClass() = %d\n", __FILE__, __FUNCTION__, __LINE__, repaired, nextToRepaired, unit->getCurrSkill()->getClass()); + + //UnitPathInterface *path= unit->getPath(); + if (unit->getCurrSkill()->getClass() != scRepair || + (nextToRepaired == false && peerUnitBuilder == NULL)) { + + if (command == NULL) { + throw megaglest_runtime_error("command == NULL"); + } + Vec2i repairPos = command->getPos(); + bool startRepairing = (repaired != NULL && rct->isRepairableUnitType(repaired->getType()) && repaired->isDamaged()); + + if (startRepairing == true) { + //printf("STARTING REPAIR, unit [%s - %d] for unit [%s - %d]\n",unit->getType()->getName().c_str(),unit->getId(),repaired->getType()->getName().c_str(),repaired->getId()); + // for(unsigned int i = 0; i < rct->getRepairCount(); ++i) { + // const UnitType *rUnit = rct->getRepair(i); + // printf("Can repair unittype [%s]\n",rUnit->getName().c_str()); + // } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] repairPos = %s, startRepairing = %d\n", __FILE__, __FUNCTION__, __LINE__, repairPos.getString().c_str(), startRepairing); + + if (startRepairing == false && peerUnitBuilder != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + startRepairing = true; + // Since the unit to be built is not yet existing we need to tell the + // other units to move to the build position or else they get in the way + + // No need to adjust repair pos since we already did this above via: Vec2i buildPos = map->findBestBuildApproach(unit->getPos(), command->getPos(), peerUnitBuilder->getCurrCommand()->getUnitType()); + //repairPos = command->getPos()-Vec2i(1); + } + + //if not repairing + if (startRepairing == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (nextToRepaired == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + unit->setTarget(repaired); + unit->setCurrSkill(rct->getRepairSkillType()); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateRepair] unit->getPos() [%s] command->getPos()() [%s] repairPos [%s]", unit->getPos().getString().c_str(), command->getPos().getString().c_str(), repairPos.getString().c_str()); + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + // If the repair command has no move skill and we are not next to + // the unit we cannot repair it + if (rct->getMoveSkillType() == NULL) { + //printf("CANCEL REPAIR NOT NEXT TO REPAIR UNIT\n"); + //Vec2i repairPos = command->getPos(); + //bool startRepairing = (repaired != NULL && rct->isRepairableUnitType(repaired->getType()) && repaired->isDamaged()); + //bool nextToRepaired = repaired != NULL && map->isNextTo(unit, repaired); + + //printf("repairPos [%s] startRepairing = %d nextToRepaired = %d unit->getPos() [%s] repaired->getPos() [%s]\n",repairPos.getString().c_str(),startRepairing,nextToRepaired,unit->getPos().getString().c_str(),repaired->getPos().getString().c_str()); + + console->addStdMessage("InvalidPosition"); + unit->setCurrSkill(scStop); + unit->finishCommand(); + } else { + TravelState ts; + switch (this->game->getGameSettings()->getPathFinderType()) { case pfBasic: + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + ts = pathFinder->findPath(unit, repairPos, NULL, frameIndex); break; default: throw megaglest_runtime_error("detected unsupported pathfinder type!"); } - //printf("\n\n#6\n\n"); - unit->setCurrSkill(hct->getStopLoadedSkillType()); - } - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] ts = %d\n", __FILE__, __FUNCTION__, __LINE__, ts); - if (unit->getLoadCount() >= hct->getMaxLoad()) { - //printf("\n\n#7\n\n"); - unit->setCurrSkill(hct->getStopLoadedSkillType()); - unit->getPath()->clear(); - } - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } - } - else { - //if there is no resource, just stop - //printf("\n\n#8\n\n"); - unit->setCurrSkill(hct->getStopLoadedSkillType()); - } - } - } + switch (ts) { + case tsMoving: + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] tsMoving\n", __FILE__, __FUNCTION__, __LINE__); + unit->setCurrSkill(rct->getMoveSkillType()); + break; + case tsBlocked: + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] tsBlocked\n", __FILE__, __FUNCTION__, __LINE__); + if (unit->getPath()->isBlocked()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] about to call [scStop]\n", __FILE__, __FUNCTION__, __LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - } - catch(const exception &ex) { - //setRunningStatus(false); - - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - throw megaglest_runtime_error(ex.what()); - } - catch(...) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - throw megaglest_runtime_error(szBuf); - } - -} - -void UnitUpdater::SwapActiveCommand(Unit *unitSrc, Unit *unitDest) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(unitSrc->getCommandSize() > 0 && unitDest->getCommandSize() > 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - Command *cmd1 = unitSrc->getCurrCommand(); - Command *cmd2 = unitDest->getCurrCommand(); - unitSrc->replaceCurrCommand(cmd2); - unitDest->replaceCurrCommand(cmd1); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void UnitUpdater::SwapActiveCommandState(Unit *unit, CommandStateType commandStateType, - const CommandType *commandType, - int originalValue,int newValue) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(commandStateType == cst_linkedUnit) { - if(dynamic_cast(commandType) != NULL) { - - for(int i = 0; i < unit->getFaction()->getUnitCount(); ++i) { - Unit *peerUnit = unit->getFaction()->getUnit(i); - if(peerUnit != NULL) { - if(peerUnit->getCommandSize() > 0 ) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - Command *peerCommand = peerUnit->getCurrCommand(); - //const BuildCommandType *bct = dynamic_cast(peerCommand->getCommandType()); - //if(bct != NULL) { - if(peerCommand != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //if(command->getPos() == peerCommand->getPos()) { - if( peerCommand->getStateType() == commandStateType && - peerCommand->getStateValue() == originalValue) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - peerCommand->setStateValue(newValue); - } - } - } - } - } - - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -Unit * UnitUpdater::findPeerUnitBuilder(Unit *unit) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - Unit *foundUnitBuilder = NULL; - if(unit->getCommandSize() > 0 ) { - Command *command = unit->getCurrCommand(); - if(command != NULL) { - const RepairCommandType *rct= dynamic_cast(command->getCommandType()); - if(rct != NULL && command->getStateType() == cst_linkedUnit) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] looking for command->getStateValue() = %d\n",__FILE__,__FUNCTION__,__LINE__,command->getStateValue()); - - Unit *firstLinkedPeerRepairer = NULL; - - for(int i = 0; i < unit->getFaction()->getUnitCount(); ++i) { - Unit *peerUnit = unit->getFaction()->getUnit(i); - if(peerUnit != NULL) { - if(peerUnit->getCommandSize() > 0 ) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - Command *peerCommand = peerUnit->getCurrCommand(); - const BuildCommandType *bct = dynamic_cast(peerCommand->getCommandType()); - if(bct != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(command->getStateValue() == peerUnit->getId()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - foundUnitBuilder = peerUnit; - break; + if (unit->getRetryCurrCommandCount() > 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] will retry command, unit->getRetryCurrCommandCount() = %d\n", __FILE__, __FUNCTION__, __LINE__, unit->getRetryCurrCommandCount()); + unit->setRetryCurrCommandCount(0); + unit->getPath()->clear(); + updateUnitCommand(unit, -1); + } else { + unit->finishCommand(); + } + } + break; + default: + break; } } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] **peer NOT building**, peerUnit = [%s]\n",__FILE__,__FUNCTION__,__LINE__,peerUnit->toString(false).c_str()); - - if(firstLinkedPeerRepairer == NULL) { - const RepairCommandType *prct = dynamic_cast(peerCommand->getCommandType()); - if(prct != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(unit->getId() != peerUnit->getId() && command->getStateValue() == peerUnit->getId()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - firstLinkedPeerRepairer = peerUnit; - } - } - } - } } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] about to call [scStop]\n", __FILE__, __FUNCTION__, __LINE__); + + //console->addStdMessage("InvalidPosition"); + unit->setCurrSkill(scStop); + unit->finishCommand(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); } - } - - if(foundUnitBuilder == NULL && firstLinkedPeerRepairer != NULL) { - foundUnitBuilder = firstLinkedPeerRepairer; - } - } - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] returning foundUnitBuilder = [%s]\n",__FILE__,__FUNCTION__,__LINE__,(foundUnitBuilder != NULL ? foundUnitBuilder->toString(false).c_str() : "null")); - - return foundUnitBuilder; -} - -// ==================== updateRepair ==================== - -void UnitUpdater::updateRepair(Unit *unit, int frameIndex) { - try { - - // Nothing to do - if(frameIndex >= 0) { - clearUnitPrecache(unit); - return; - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateRepair]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] unit = %p\n",__FILE__,__FUNCTION__,__LINE__,unit); - - //if(unit != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] unit doing the repair [%s] - %d\n",__FILE__,__FUNCTION__,__LINE__,unit->getFullName(false).c_str(),unit->getId()); - //} - Command *command= unit->getCurrCommand(); - if(command == NULL) { - throw megaglest_runtime_error("command == NULL"); - } - - const RepairCommandType *rct= static_cast(command->getCommandType()); - const CommandType *ct = (command != NULL ? command->getCommandType() : NULL); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] rct = %p\n",__FILE__,__FUNCTION__,__LINE__,rct); - - Unit *repaired = (command != NULL ? map->getCell(command->getPos())->getUnitWithEmptyCellMap(fLand) : NULL); - if(repaired == NULL && command != NULL) { - repaired = map->getCell(command->getPos())->getUnit(fLand); - } - - if(repaired != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] unit to repair [%s] - %d\n",__FILE__,__FUNCTION__,__LINE__,repaired->getFullName(false).c_str(),repaired->getId()); - } - - if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - // Check if the 'repaired' unit is actually the peer unit in a multi-build? - Unit *peerUnitBuilder = findPeerUnitBuilder(unit); - - if(peerUnitBuilder != NULL) { - SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] unit peer [%s] - %d\n",__FILE__,__FUNCTION__,__LINE__,peerUnitBuilder->getFullName(false).c_str(),peerUnitBuilder->getId()); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - // Ensure we have the right unit to repair - if(peerUnitBuilder != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] peerUnitBuilder = %p\n",__FILE__,__FUNCTION__,__LINE__,peerUnitBuilder); - - if(peerUnitBuilder->getCurrCommand()->getUnit() != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] peerbuilder's unitid = %d\n",__FILE__,__FUNCTION__,__LINE__,peerUnitBuilder->getCurrCommand()->getUnit()->getId()); - repaired = peerUnitBuilder->getCurrCommand()->getUnit(); - } - } - - bool nextToRepaired = repaired != NULL && map->isNextTo(unit, repaired); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - peerUnitBuilder = NULL; - if(repaired == NULL) { - peerUnitBuilder = findPeerUnitBuilder(unit); - if(peerUnitBuilder != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] peerUnitBuilder = %p\n",__FILE__,__FUNCTION__,__LINE__,peerUnitBuilder); - - if(peerUnitBuilder->getCurrCommand()->getUnit() != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] peerbuilder's unitid = %d\n",__FILE__,__FUNCTION__,__LINE__,peerUnitBuilder->getCurrCommand()->getUnit()->getId()); - repaired = peerUnitBuilder->getCurrCommand()->getUnit(); - nextToRepaired = repaired != NULL && map->isNextTo(unit, repaired); - } - else if(peerUnitBuilder->getCurrCommand()->getUnitType() != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - Vec2i buildPos = map->findBestBuildApproach(unit, command->getPos(), peerUnitBuilder->getCurrCommand()->getUnitType()); - - //nextToRepaired= (unit->getPos() == (command->getPos()-Vec2i(1))); - nextToRepaired = (unit->getPos() == buildPos); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] peerUnitBuilder = %p, nextToRepaired = %d\n",__FILE__,__FUNCTION__,__LINE__,peerUnitBuilder,nextToRepaired); - - if(nextToRepaired == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - Command *peerCommand = peerUnitBuilder->getCurrCommand(); - const RepairCommandType *rct = dynamic_cast(peerCommand->getCommandType()); - // If the peer is also scheduled to do a repair we CANNOT swap their commands or - // it will result in a stack overflow as each swaps the others repair command. - // We must convert this unit's repair into a build right now! - if(rct != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - const CommandType *ctbuild = unit->getType()->getFirstCtOfClass(ccBuild); - NetworkCommand networkCommand(this->world,nctGiveCommand, unit->getId(), ctbuild->getId(), command->getPos(), - command->getUnitType()->getId(), -1, CardinalDir(CardinalDir::NORTH), true, command->getStateType(), - command->getStateValue()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - Command* command= this->game->getCommander()->buildCommand(&networkCommand); - std::pair cr= unit->checkCommand(command); - if(cr.first == crSuccess) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - unit->replaceCurrCommand(command); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - delete command; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + bool cancelRepair = false; + //if repairing + if (repaired != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + // Check if we can still repair the unit (may have morphed, etc) + bool canStillRepair = rct->isRepairableUnitType(repaired->getType()); + if (canStillRepair == true) { + unit->setTarget(repaired); + } else { + //printf("CANCELLING CURRENT REPAIR, unit [%s - %d] for unit [%s - %d]\n",unit->getType()->getName().c_str(),unit->getId(),repaired->getType()->getName().c_str(),repaired->getId()); + // for(unsigned int i = 0; i < rct->getRepairCount(); ++i) { + // const UnitType *rUnit = rct->getRepair(i); + // printf("Can repair unittype [%s]\n",rUnit->getName().c_str()); + // } unit->setCurrSkill(scStop); unit->finishCommand(); + cancelRepair = true; } + } else if (peerUnitBuilder != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + unit->setTargetPos(command->getPos()); } - else { - CommandStateType commandStateType = unit->getCurrCommand()->getStateType(); - SwapActiveCommand(unit,peerUnitBuilder); - int oldPeerUnitId = peerUnitBuilder->getId(); - int newPeerUnitId = unit->getId(); - SwapActiveCommandState(unit,commandStateType,unit->getCurrCommand()->getCommandType(),oldPeerUnitId,newPeerUnitId); - // Give the swapped unit a fresh chance to help build in case they - // were or are about to be blocked - peerUnitBuilder->getPath()->clear(); - peerUnitBuilder->setRetryCurrCommandCount(1); - updateUnitCommand(unit,-1); + if (cancelRepair == false && (repaired == NULL || repaired->repair()) && + peerUnitBuilder == NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] about to call [scStop]\n", __FILE__, __FUNCTION__, __LINE__); + + unit->setCurrSkill(scStop); + unit->finishCommand(); + + if (repaired != NULL && repaired->isBuilt() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + repaired->born(ct); + scriptManager->onUnitCreated(repaired); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); } + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + } catch (const exception &ex) { + //setRunningStatus(false); + + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + throw megaglest_runtime_error(ex.what()); + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + + } + + // ==================== updateProduce ==================== + + void UnitUpdater::updateProduce(Unit *unit, int frameIndex) { + try { + + // Nothing to do + if (frameIndex >= 0) { + clearUnitPrecache(unit); return; } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] unit to repair[%s]\n",__FILE__,__FUNCTION__,__LINE__,repaired->getFullName(false).c_str()); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] repaired = %p, nextToRepaired = %d, unit->getCurrSkill()->getClass() = %d\n",__FILE__,__FUNCTION__,__LINE__,repaired,nextToRepaired,unit->getCurrSkill()->getClass()); - - //UnitPathInterface *path= unit->getPath(); - if(unit->getCurrSkill()->getClass() != scRepair || - (nextToRepaired == false && peerUnitBuilder == NULL)) { - - if(command == NULL) { - throw megaglest_runtime_error("command == NULL"); - } - Vec2i repairPos = command->getPos(); - bool startRepairing = (repaired != NULL && rct->isRepairableUnitType(repaired->getType()) && repaired->isDamaged()); - - if(startRepairing == true) { - //printf("STARTING REPAIR, unit [%s - %d] for unit [%s - %d]\n",unit->getType()->getName().c_str(),unit->getId(),repaired->getType()->getName().c_str(),repaired->getId()); -// for(unsigned int i = 0; i < rct->getRepairCount(); ++i) { -// const UnitType *rUnit = rct->getRepair(i); -// printf("Can repair unittype [%s]\n",rUnit->getName().c_str()); -// } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] repairPos = %s, startRepairing = %d\n",__FILE__,__FUNCTION__,__LINE__,repairPos.getString().c_str(),startRepairing); - - if(startRepairing == false && peerUnitBuilder != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - startRepairing = true; - // Since the unit to be built is not yet existing we need to tell the - // other units to move to the build position or else they get in the way - - // No need to adjust repair pos since we already did this above via: Vec2i buildPos = map->findBestBuildApproach(unit->getPos(), command->getPos(), peerUnitBuilder->getCurrCommand()->getUnitType()); - //repairPos = command->getPos()-Vec2i(1); - } - - //if not repairing - if(startRepairing == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(nextToRepaired == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - unit->setTarget(repaired); - unit->setCurrSkill(rct->getRepairSkillType()); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateRepair] unit->getPos() [%s] command->getPos()() [%s] repairPos [%s]",unit->getPos().getString().c_str(),command->getPos().getString().c_str(),repairPos.getString().c_str()); - unit->logSynchData(__FILE__,__LINE__,szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateProduce]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - // If the repair command has no move skill and we are not next to - // the unit we cannot repair it - if(rct->getMoveSkillType() == NULL) { - //printf("CANCEL REPAIR NOT NEXT TO REPAIR UNIT\n"); - //Vec2i repairPos = command->getPos(); - //bool startRepairing = (repaired != NULL && rct->isRepairableUnitType(repaired->getType()) && repaired->isDamaged()); - //bool nextToRepaired = repaired != NULL && map->isNextTo(unit, repaired); - - //printf("repairPos [%s] startRepairing = %d nextToRepaired = %d unit->getPos() [%s] repaired->getPos() [%s]\n",repairPos.getString().c_str(),startRepairing,nextToRepaired,unit->getPos().getString().c_str(),repaired->getPos().getString().c_str()); - - console->addStdMessage("InvalidPosition"); - unit->setCurrSkill(scStop); - unit->finishCommand(); + Command *command = unit->getCurrCommand(); + if (command == NULL) { + throw megaglest_runtime_error("command == NULL"); } - else { - TravelState ts; - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - ts = pathFinder->findPath(unit, repairPos, NULL, frameIndex); - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } + const ProduceCommandType *pct = static_cast(command->getCommandType()); + Unit *produced; - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] ts = %d\n",__FILE__,__FUNCTION__,__LINE__,ts); + if (unit->getCurrSkill()->getClass() != scProduce) { + //if not producing + unit->setCurrSkill(pct->getProduceSkillType()); + } else { + const CommandType *ct = (command != NULL ? command->getCommandType() : NULL); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + unit->update2(); - switch(ts) { - case tsMoving: - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] tsMoving\n",__FILE__,__FUNCTION__,__LINE__); - unit->setCurrSkill(rct->getMoveSkillType()); - break; - case tsBlocked: - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] tsBlocked\n",__FILE__,__FUNCTION__,__LINE__); - if(unit->getPath()->isBlocked()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] about to call [scStop]\n",__FILE__,__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); - if(unit->getRetryCurrCommandCount() > 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] will retry command, unit->getRetryCurrCommandCount() = %d\n",__FILE__,__FUNCTION__,__LINE__,unit->getRetryCurrCommandCount()); - unit->setRetryCurrCommandCount(0); - unit->getPath()->clear(); - updateUnitCommand(unit,-1); + if (unit->getProgress2() > pct->getProduced()->getProductionTime()) { + // finish producing/ upgrading if complete. + unit->finishCommand(); + // Stop the unit that finished producing/ upgrading. + unit->setCurrSkill(scStop); + + UnitPathInterface *newpath = NULL; + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + newpath = new UnitPathBasic(); + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } + + produced = new Unit(world->getNextUnitId(unit->getFaction()), newpath, Vec2i(0), pct->getProducedUnit(), unit->getFaction(), world->getMap(), CardinalDir(CardinalDir::NORTH)); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] about to place unit for unit [%s]\n", __FILE__, __FUNCTION__, __LINE__, produced->toString(false).c_str()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + //place unit creates the unit + if (!world->placeUnit(unit->getCenteredPos(), 10, produced, false, frameIndex < 0)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] COULD NOT PLACE UNIT for unitID [%d]\n", __FILE__, __FUNCTION__, __LINE__, produced->getId()); + delete produced; + } else { + produced->create(); + produced->born(ct); + + world->getStats()->produce(unit->getFactionIndex(), produced->getType()->getCountUnitProductionInStats()); + const CommandType *ct = produced->computeCommandType(unit->getMeetingPos()); + if (ct != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + produced->giveCommand(new Command(ct, unit->getMeetingPos())); } - else { - unit->finishCommand(); + scriptManager->onUnitCreated(produced); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + } + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + } catch (const exception &ex) { + //setRunningStatus(false); + + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + throw megaglest_runtime_error(ex.what()); + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + + } + + + // ==================== updateUpgrade ==================== + + void UnitUpdater::updateUpgrade(Unit *unit, int frameIndex) { + try { + + // Nothing to do + if (frameIndex >= 0) { + clearUnitPrecache(unit); + return; + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateUpgrade]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + + Command *command = unit->getCurrCommand(); + if (command == NULL) { + throw megaglest_runtime_error("command == NULL"); + } + + const UpgradeCommandType *uct = static_cast(command->getCommandType()); + + if (unit->getCurrSkill()->getClass() != scUpgrade) { + //if not producing + unit->setCurrSkill(uct->getUpgradeSkillType()); + } else { + //if producing + unit->update2(); + if (unit->getProgress2() > uct->getProduced()->getProductionTime()) { + unit->finishCommand(); + unit->setCurrSkill(scStop); + unit->getFaction()->finishUpgrade(uct->getProducedUpgrade()); + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + } catch (const exception &ex) { + //setRunningStatus(false); + + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + throw megaglest_runtime_error(ex.what()); + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + + } + + // ==================== updateMorph ==================== + + void UnitUpdater::updateMorph(Unit *unit, int frameIndex) { + try { + + // Nothing to do + if (frameIndex >= 0) { + clearUnitPrecache(unit); + return; + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[updateMorph]"); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, szBuf); + } + + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + + Command *command = unit->getCurrCommand(); + if (command == NULL) { + throw megaglest_runtime_error("command == NULL"); + } + + const MorphCommandType *mct = static_cast(command->getCommandType()); + + if (unit->getCurrSkill()->getClass() != scMorph) { + //if not morphing, check space + if (map->canMorph(unit->getPos(), unit, mct->getMorphUnit())) { + unit->setCurrSkill(mct->getMorphSkillType()); + // block space for morphing units ( block space before and after morph ! ) + map->putUnitCells(unit, unit->getPos(), false, frameIndex < 0); + } else { + if (unit->getFactionIndex() == world->getThisFactionIndex()) { + console->addStdMessage("InvalidPosition"); + } + unit->cancelCommand(); + } + } else { + unit->update2(); + if (unit->getProgress2() > mct->getProduced()->getProductionTime()) { + //int oldSize = 0; + //bool needMapUpdate = false; + + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } + + //finish the command + if (unit->morph(mct, frameIndex)) { + unit->finishCommand(); + if (gui->isSelected(unit)) { + gui->onSelectionChanged(); + } + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } + + scriptManager->onUnitCreated(unit); + } else { + unit->cancelCommand(); + if (unit->getFactionIndex() == world->getThisFactionIndex()) { + console->addStdMessage("InvalidPosition"); } } + unit->setCurrSkill(scStop); + + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis()); + + } catch (const exception &ex) { + //setRunningStatus(false); + + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + throw megaglest_runtime_error(ex.what()); + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + + } + + + // ==================== updateMove ==================== + void UnitUpdater::updateSwitchTeam(Unit *unit, int frameIndex) { + } + + // ==================== updateAttack ==================== + + // ==================== PRIVATE ==================== + + // ==================== attack ==================== + + void UnitUpdater::hit(Unit *attacker) { + hit(attacker, dynamic_cast(attacker->getCurrSkill()), attacker->getTargetPos(), attacker->getTargetField(), 100); + } + + void UnitUpdater::hit(Unit *attacker, const AttackSkillType* ast, const Vec2i &targetPos, Field targetField, int damagePercent) { + //hit attack positions + if (ast != NULL && ast->getSplash()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "Unit hitting [UnitUpdater::hit] hasSplash = %d radius = %d damageall = %d", ast->getSplash(), ast->getSplashRadius(), ast->getSplashDamageAll()); + attacker->addNetworkCRCDecHp(szBuf); + + PosCircularIterator pci(map, targetPos, ast->getSplashRadius()); + while (pci.next()) { + Unit *attacked = map->getCell(pci.getPos())->getUnit(targetField); + if (attacked != NULL) { + if (ast->getSplashDamageAll() || + attacker->isAlly(attacked) == false || + (targetPos.x == pci.getPos().x && targetPos.y == pci.getPos().y)) { + + attacker->setLastAttackedUnitId(attacked->getId()); + scriptManager->onUnitAttacking(attacker); + + float distance = pci.getPos().dist(targetPos); + distance = truncateDecimal(distance, 6); + damage(attacker, ast, attacked, distance, damagePercent); + } + } + } + } else { + Unit *attacked = map->getCell(targetPos)->getUnit(targetField); + + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "Unit hitting [UnitUpdater::hit 2] attacked = %d", (attacked != NULL ? attacked->getId() : -1)); + attacker->addNetworkCRCDecHp(szBuf); + + if (attacked != NULL) { + damage(attacker, ast, attacked, 0.f, damagePercent); + } + } + } + + void UnitUpdater::damage(Unit *attacker, const AttackSkillType* ast, Unit *attacked, float distance, int damagePercent) { + if (attacker == NULL) { + throw megaglest_runtime_error("attacker == NULL"); + } + if (ast == NULL) { + throw megaglest_runtime_error("ast == NULL"); + } + if (attacked == NULL) { + throw megaglest_runtime_error("attacked == NULL"); + } + + //get vars + float damage = ast->getTotalAttackStrength(attacker->getTotalUpgrade()); + int var = ast->getAttackVar(); + int armor = attacked->getType()->getTotalArmor(attacked->getTotalUpgrade()); + float damageMultiplier = world->getTechTree()->getDamageMultiplier(ast->getAttackType(), attacked->getType()->getArmorType()); + damageMultiplier = truncateDecimal(damageMultiplier, 6); + + //compute damage + //damage += random.randRange(-var, var); + damage += attacker->getRandom()->randRange(-var, var, extractFileFromDirectoryPath(__FILE__) + intToStr(__LINE__)); + damage /= distance + 1; + damage -= armor; + damage *= damageMultiplier; + damage = truncateDecimal(damage, 6); + + damage = (damage*damagePercent) / 100; + if (damage < 1) { + damage = 1; + } + int damageVal = static_cast(damage); + + attacked->setLastAttackerUnitId(attacker->getId()); + + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "Unit hitting [UnitUpdater::damage] damageVal = %d", damageVal); + attacker->addNetworkCRCDecHp(szBuf); + + //damage the unit + if (attacked->decHp(damageVal)) { + world->getStats()->kill(attacker->getFactionIndex(), attacked->getFactionIndex(), attacker->getTeam() != attacked->getTeam(), attacked->getType()->getCountUnitDeathInStats(), attacked->getType()->getCountUnitKillInStats()); + if (attacked->getType()->getCountKillForUnitUpgrade() == true) { + attacker->incKills(attacked->getTeam()); + } + + // Perform resource looting iff the attack is from a different faction + if (attacker->getFaction() != attacked->getFaction()) { + int lootableResourceCount = attacked->getType()->getLootableResourceCount(); + for (int i = 0; i < lootableResourceCount; i++) { + LootableResource resource = attacked->getType()->getLootableResource(i); + + // Figure out how much of the resource in question that the attacked unit's faction has + int factionTotalResource = 0; + for (int j = 0; j < attacked->getFaction()->getTechTree()->getResourceTypeCount(); j++) { + if (attacked->getFaction()->getTechTree()->getResourceType(j) == resource.getResourceType()) { + factionTotalResource = attacked->getFaction()->getResource(j)->getAmount(); + break; + } + } + + if (resource.isNegativeAllowed()) { + attacked->getFaction()->incResourceAmount(resource.getResourceType(), -(factionTotalResource * resource.getLossFactionPercent() / 100)); + attacked->getFaction()->incResourceAmount(resource.getResourceType(), -resource.getLossValue()); + attacker->getFaction()->incResourceAmount(resource.getResourceType(), factionTotalResource * resource.getAmountFactionPercent() / 100); + attacker->getFaction()->incResourceAmount(resource.getResourceType(), resource.getAmountValue()); + } + // Can't take more resources than the faction has, otherwise we end up in the negatives + else { + attacked->getFaction()->incResourceAmount(resource.getResourceType(), -(std::min)(factionTotalResource * resource.getLossFactionPercent() / 100, factionTotalResource)); + attacked->getFaction()->incResourceAmount(resource.getResourceType(), -(std::min)(resource.getLossValue(), factionTotalResource)); + attacker->getFaction()->incResourceAmount(resource.getResourceType(), (std::min)(factionTotalResource * resource.getAmountFactionPercent() / 100, factionTotalResource)); + attacker->getFaction()->incResourceAmount(resource.getResourceType(), (std::min)(resource.getAmountValue(), factionTotalResource)); + } + } + } + + switch (this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: break; default: - break; + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } + + attacked->setCauseOfDeath(ucodAttacked); + scriptManager->onUnitDied(attacked); + } + + if (attacked->isAlive() == true) { + scriptManager->onUnitAttacked(attacked); + } + + // !!! Is this causing choppy network play somehow? + //attacker->computeHp(); + } + + void UnitUpdater::startAttackParticleSystem(Unit *unit, float lastAnimProgress, float animProgress) { + Renderer &renderer = Renderer::getInstance(); + + //const AttackSkillType *ast= dynamic_cast(unit->getCurrSkill()); + const AttackSkillType *ast = static_cast(unit->getCurrSkill()); + + if (ast == NULL) { + throw megaglest_runtime_error("Start attack particle ast == NULL!"); + } + + ParticleSystemTypeSplash *pstSplash = ast->getSplashParticleType(); + bool hasProjectile = !ast->projectileTypes.empty(); + Vec3f startPos = unit->getCurrVectorForParticlesystems(); + Vec3f endPos = unit->getTargetVec(); + + //make particle system + const SurfaceCell *sc = map->getSurfaceCell(Map::toSurfCoords(unit->getPos())); + const SurfaceCell *tsc = map->getSurfaceCell(Map::toSurfCoords(unit->getTargetPos())); + bool visible = sc->isVisible(world->getThisTeamIndex()) || tsc->isVisible(world->getThisTeamIndex()); + if (visible == false && world->showWorldForPlayer(world->getThisFactionIndex()) == true) { + visible = true; + } + + //for(ProjectileParticleSystemTypes::const_iterator pit= unit->getCurrSkill()->projectileParticleSystemTypes.begin(); pit != unit->getCurrSkill()->projectileParticleSystemTypes.end(); ++pit) { + for (ProjectileTypes::const_iterator pt = ast->projectileTypes.begin(); pt != ast->projectileTypes.end(); ++pt) { + bool startAttackParticleSystemNow = ((*pt)->getAttackStartTime() >= lastAnimProgress && (*pt)->getAttackStartTime() < animProgress); + if (startAttackParticleSystemNow) { + ProjectileParticleSystem *psProj = (*pt)->getProjectileParticleSystemType()->create(unit); + psProj->setPath(startPos, endPos); + psProj->setObserver(new ParticleDamager(unit, (*pt), this, gameCamera)); + psProj->setVisible(visible); + if (unit->getFaction()->getTexture()) { + psProj->setFactionColor(unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0)); + } + renderer.manageParticleSystem(psProj, rsGame); + unit->addAttackParticleSystem(psProj); + + if (pstSplash != NULL) { + SplashParticleSystem *psSplash = pstSplash->create(unit); + psSplash->setPos(endPos); + psSplash->setVisible(visible); + if (unit->getFaction()->getTexture()) { + psSplash->setFactionColor(unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0)); + } + renderer.manageParticleSystem(psSplash, rsGame); + unit->addAttackParticleSystem(psSplash); + psProj->link(psSplash); } } } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] about to call [scStop]\n",__FILE__,__FUNCTION__,__LINE__); - //console->addStdMessage("InvalidPosition"); - unit->setCurrSkill(scStop); - unit->finishCommand(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - bool cancelRepair = false; - //if repairing - if(repaired != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - // Check if we can still repair the unit (may have morphed, etc) - bool canStillRepair = rct->isRepairableUnitType(repaired->getType()); - if(canStillRepair == true) { - unit->setTarget(repaired); - - } - else { - //printf("CANCELLING CURRENT REPAIR, unit [%s - %d] for unit [%s - %d]\n",unit->getType()->getName().c_str(),unit->getId(),repaired->getType()->getName().c_str(),repaired->getId()); -// for(unsigned int i = 0; i < rct->getRepairCount(); ++i) { -// const UnitType *rUnit = rct->getRepair(i); -// printf("Can repair unittype [%s]\n",rUnit->getName().c_str()); -// } - unit->setCurrSkill(scStop); - unit->finishCommand(); - cancelRepair = true; - } - } - else if(peerUnitBuilder != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - unit->setTargetPos(command->getPos()); - } - - if(cancelRepair == false && (repaired == NULL || repaired->repair()) && - peerUnitBuilder == NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] about to call [scStop]\n",__FILE__,__FUNCTION__,__LINE__); - - unit->setCurrSkill(scStop); - unit->finishCommand(); - - if(repaired != NULL && repaired->isBuilt() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - repaired->born(ct); - scriptManager->onUnitCreated(repaired); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - } - catch(const exception &ex) { - //setRunningStatus(false); - - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - throw megaglest_runtime_error(ex.what()); - } - catch(...) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - throw megaglest_runtime_error(szBuf); - } - -} - -// ==================== updateProduce ==================== - -void UnitUpdater::updateProduce(Unit *unit, int frameIndex) { - try { - - // Nothing to do - if(frameIndex >= 0) { - clearUnitPrecache(unit); - return; - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateProduce]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - - Command *command= unit->getCurrCommand(); - if(command == NULL) { - throw megaglest_runtime_error("command == NULL"); - } - - const ProduceCommandType *pct= static_cast(command->getCommandType()); - Unit *produced; - - if(unit->getCurrSkill()->getClass() != scProduce) { - //if not producing - unit->setCurrSkill(pct->getProduceSkillType()); - } - else { - const CommandType *ct = (command != NULL ? command->getCommandType() : NULL); - - unit->update2(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - if(unit->getProgress2() > pct->getProduced()->getProductionTime()){ - // finish producing/ upgrading if complete. - unit->finishCommand(); - // Stop the unit that finished producing/ upgrading. - unit->setCurrSkill(scStop); - - UnitPathInterface *newpath = NULL; - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - newpath = new UnitPathBasic(); - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } - - produced= new Unit(world->getNextUnitId(unit->getFaction()), newpath, Vec2i(0), pct->getProducedUnit(), unit->getFaction(), world->getMap(), CardinalDir(CardinalDir::NORTH)); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] about to place unit for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,produced->toString(false).c_str()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - //place unit creates the unit - if(!world->placeUnit(unit->getCenteredPos(), 10, produced, false, frameIndex < 0)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] COULD NOT PLACE UNIT for unitID [%d]\n",__FILE__,__FUNCTION__,__LINE__,produced->getId()); - delete produced; - } - else{ - produced->create(); - produced->born(ct); - - world->getStats()->produce(unit->getFactionIndex(),produced->getType()->getCountUnitProductionInStats()); - const CommandType *ct= produced->computeCommandType(unit->getMeetingPos()); - if(ct != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - produced->giveCommand(new Command(ct, unit->getMeetingPos())); - } - scriptManager->onUnitCreated(produced); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - } - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - } - catch(const exception &ex) { - //setRunningStatus(false); - - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - throw megaglest_runtime_error(ex.what()); - } - catch(...) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - throw megaglest_runtime_error(szBuf); - } - -} - - -// ==================== updateUpgrade ==================== - -void UnitUpdater::updateUpgrade(Unit *unit, int frameIndex) { - try { - - // Nothing to do - if(frameIndex >= 0) { - clearUnitPrecache(unit); - return; - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateUpgrade]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - - Command *command= unit->getCurrCommand(); - if(command == NULL) { - throw megaglest_runtime_error("command == NULL"); - } - - const UpgradeCommandType *uct= static_cast(command->getCommandType()); - - if(unit->getCurrSkill()->getClass() != scUpgrade) { - //if not producing - unit->setCurrSkill(uct->getUpgradeSkillType()); - } - else { - //if producing - unit->update2(); - if(unit->getProgress2() > uct->getProduced()->getProductionTime()){ - unit->finishCommand(); - unit->setCurrSkill(scStop); - unit->getFaction()->finishUpgrade(uct->getProducedUpgrade()); - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - } - catch(const exception &ex) { - //setRunningStatus(false); - - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - throw megaglest_runtime_error(ex.what()); - } - catch(...) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - throw megaglest_runtime_error(szBuf); - } - -} - -// ==================== updateMorph ==================== - -void UnitUpdater::updateMorph(Unit *unit, int frameIndex) { - try { - - // Nothing to do - if(frameIndex >= 0) { - clearUnitPrecache(unit); - return; - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateMorph]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); - - Command *command= unit->getCurrCommand(); - if(command == NULL) { - throw megaglest_runtime_error("command == NULL"); - } - - const MorphCommandType *mct= static_cast(command->getCommandType()); - - if(unit->getCurrSkill()->getClass()!=scMorph){ - //if not morphing, check space - if(map->canMorph(unit->getPos(),unit,mct->getMorphUnit())){ - unit->setCurrSkill(mct->getMorphSkillType()); - // block space for morphing units ( block space before and after morph ! ) - map->putUnitCells(unit, unit->getPos(), false, frameIndex < 0); - } - else{ - if(unit->getFactionIndex()==world->getThisFactionIndex()){ - console->addStdMessage("InvalidPosition"); - } - unit->cancelCommand(); - } - } - else{ - unit->update2(); - if(unit->getProgress2() > mct->getProduced()->getProductionTime()){ - //int oldSize = 0; - //bool needMapUpdate = false; - - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } - - //finish the command - if(unit->morph(mct, frameIndex)){ - unit->finishCommand(); - if(gui->isSelected(unit)){ - gui->onSelectionChanged(); - } - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } - - scriptManager->onUnitCreated(unit); - } - else{ - unit->cancelCommand(); - if(unit->getFactionIndex()==world->getThisFactionIndex()){ - console->addStdMessage("InvalidPosition"); - } - } - unit->setCurrSkill(scStop); - - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - - } - catch(const exception &ex) { - //setRunningStatus(false); - - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - throw megaglest_runtime_error(ex.what()); - } - catch(...) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - throw megaglest_runtime_error(szBuf); - } - -} - - -// ==================== updateMove ==================== -void UnitUpdater::updateSwitchTeam(Unit *unit, int frameIndex) { -} - -// ==================== updateAttack ==================== - -// ==================== PRIVATE ==================== - -// ==================== attack ==================== - -void UnitUpdater::hit(Unit *attacker){ - hit(attacker, dynamic_cast(attacker->getCurrSkill()), attacker->getTargetPos(), attacker->getTargetField(),100); -} - -void UnitUpdater::hit(Unit *attacker, const AttackSkillType* ast, const Vec2i &targetPos, Field targetField, int damagePercent){ - //hit attack positions - if(ast != NULL && ast->getSplash()) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"Unit hitting [UnitUpdater::hit] hasSplash = %d radius = %d damageall = %d",ast->getSplash(),ast->getSplashRadius(),ast->getSplashDamageAll()); - attacker->addNetworkCRCDecHp(szBuf); - - PosCircularIterator pci(map, targetPos, ast->getSplashRadius()); - while(pci.next()) { - Unit *attacked= map->getCell(pci.getPos())->getUnit(targetField); - if(attacked != NULL) { - if(ast->getSplashDamageAll() || - attacker->isAlly(attacked) == false || - ( targetPos.x == pci.getPos().x && targetPos.y == pci.getPos().y )) { - - attacker->setLastAttackedUnitId(attacked->getId()); - scriptManager->onUnitAttacking(attacker); - - float distance = pci.getPos().dist(targetPos); - distance = truncateDecimal(distance,6); - damage(attacker, ast, attacked, distance,damagePercent); - } - } - } - } - else { - Unit *attacked= map->getCell(targetPos)->getUnit(targetField); - - char szBuf[8096]=""; - snprintf(szBuf,8095,"Unit hitting [UnitUpdater::hit 2] attacked = %d",(attacked != NULL ? attacked->getId() : -1)); - attacker->addNetworkCRCDecHp(szBuf); - - if(attacked != NULL) { - damage(attacker, ast, attacked, 0.f,damagePercent); - } - } -} - -void UnitUpdater::damage(Unit *attacker, const AttackSkillType* ast, Unit *attacked, float distance, int damagePercent) { - if(attacker == NULL) { - throw megaglest_runtime_error("attacker == NULL"); - } - if(ast == NULL) { - throw megaglest_runtime_error("ast == NULL"); - } - if(attacked == NULL) { - throw megaglest_runtime_error("attacked == NULL"); - } - - //get vars - float damage = ast->getTotalAttackStrength(attacker->getTotalUpgrade()); - int var = ast->getAttackVar(); - int armor = attacked->getType()->getTotalArmor(attacked->getTotalUpgrade()); - float damageMultiplier = world->getTechTree()->getDamageMultiplier(ast->getAttackType(), attacked->getType()->getArmorType()); - damageMultiplier = truncateDecimal(damageMultiplier,6); - - //compute damage - //damage += random.randRange(-var, var); - damage += attacker->getRandom()->randRange(-var, var, extractFileFromDirectoryPath(__FILE__) + intToStr(__LINE__)); - damage /= distance+1; - damage -= armor; - damage *= damageMultiplier; - damage = truncateDecimal(damage,6); - - damage = (damage*damagePercent)/100; - if(damage < 1) { - damage= 1; - } - int damageVal = static_cast(damage); - - attacked->setLastAttackerUnitId(attacker->getId()); - - char szBuf[8096]=""; - snprintf(szBuf,8095,"Unit hitting [UnitUpdater::damage] damageVal = %d",damageVal); - attacker->addNetworkCRCDecHp(szBuf); - - //damage the unit - if(attacked->decHp(damageVal)) { - world->getStats()->kill(attacker->getFactionIndex(), attacked->getFactionIndex(), attacker->getTeam() != attacked->getTeam(),attacked->getType()->getCountUnitDeathInStats(),attacked->getType()->getCountUnitKillInStats()); - if(attacked->getType()->getCountKillForUnitUpgrade() == true){ - attacker->incKills(attacked->getTeam()); - } - - // Perform resource looting iff the attack is from a different faction - if(attacker->getFaction() != attacked->getFaction()) { - int lootableResourceCount = attacked->getType()->getLootableResourceCount(); - for(int i = 0; i < lootableResourceCount; i++) { - LootableResource resource = attacked->getType()->getLootableResource(i); - - // Figure out how much of the resource in question that the attacked unit's faction has - int factionTotalResource = 0; - for(int j = 0; j < attacked->getFaction()->getTechTree()->getResourceTypeCount(); j++) { - if(attacked->getFaction()->getTechTree()->getResourceType(j) == resource.getResourceType()) { - factionTotalResource = attacked->getFaction()->getResource(j)->getAmount(); - break; + // if no projectile, still deal damage.. + if (hasProjectile == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "Unit hitting [startAttackParticleSystem] no proj"); + unit->addNetworkCRCDecHp(szBuf); + hit(unit); + //splash + if (pstSplash != NULL) { + SplashParticleSystem *psSplash = pstSplash->create(unit); + psSplash->setPos(endPos); + psSplash->setVisible(visible); + if (unit->getFaction()->getTexture()) { + psSplash->setFactionColor(unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0)); } - } - - if(resource.isNegativeAllowed()) { - attacked->getFaction()->incResourceAmount(resource.getResourceType(), -(factionTotalResource * resource.getLossFactionPercent() / 100)); - attacked->getFaction()->incResourceAmount(resource.getResourceType(), -resource.getLossValue()); - attacker->getFaction()->incResourceAmount(resource.getResourceType(), factionTotalResource * resource.getAmountFactionPercent() / 100); - attacker->getFaction()->incResourceAmount(resource.getResourceType(), resource.getAmountValue()); - } - // Can't take more resources than the faction has, otherwise we end up in the negatives - else { - attacked->getFaction()->incResourceAmount(resource.getResourceType(), -(std::min)(factionTotalResource * resource.getLossFactionPercent() / 100, factionTotalResource)); - attacked->getFaction()->incResourceAmount(resource.getResourceType(), -(std::min)(resource.getLossValue(), factionTotalResource)); - attacker->getFaction()->incResourceAmount(resource.getResourceType(), (std::min)(factionTotalResource * resource.getAmountFactionPercent() / 100, factionTotalResource)); - attacker->getFaction()->incResourceAmount(resource.getResourceType(), (std::min)(resource.getAmountValue(), factionTotalResource)); + renderer.manageParticleSystem(psSplash, rsGame); + unit->addAttackParticleSystem(psSplash); } } } - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } + // ==================== misc ==================== - attacked->setCauseOfDeath(ucodAttacked); - scriptManager->onUnitDied(attacked); - } + //looks for a resource of type rt, if rt==NULL looks for any + //resource the unit can harvest + bool UnitUpdater::searchForResource(Unit *unit, const HarvestCommandType *hct) { + Vec2i pos = unit->getCurrCommand()->getPos(); - if(attacked->isAlive() == true) { - scriptManager->onUnitAttacked(attacked); - } + for (int radius = 0; radius < maxResSearchRadius; radius++) { + for (int i = pos.x - radius; i <= pos.x + radius; ++i) { + for (int j = pos.y - radius; j <= pos.y + radius; ++j) { + if (map->isInside(i, j)) { + Resource *r = map->getSurfaceCell(Map::toSurfCoords(Vec2i(i, j)))->getResource(); + if (r != NULL) { + if (hct->canHarvest(r->getType())) { + const Vec2i newPos = Vec2i(i, j); + if (unit->isBadHarvestPos(newPos) == false) { + unit->getCurrCommand()->setPos(newPos); - // !!! Is this causing choppy network play somehow? - //attacker->computeHp(); -} - -void UnitUpdater::startAttackParticleSystem(Unit *unit, float lastAnimProgress, float animProgress){ - Renderer &renderer= Renderer::getInstance(); - - //const AttackSkillType *ast= dynamic_cast(unit->getCurrSkill()); - const AttackSkillType *ast= static_cast(unit->getCurrSkill()); - - if(ast == NULL) { - throw megaglest_runtime_error("Start attack particle ast == NULL!"); - } - - ParticleSystemTypeSplash *pstSplash= ast->getSplashParticleType(); - bool hasProjectile = !ast->projectileTypes.empty(); - Vec3f startPos= unit->getCurrVectorForParticlesystems(); - Vec3f endPos= unit->getTargetVec(); - - //make particle system - const SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(unit->getPos())); - const SurfaceCell *tsc= map->getSurfaceCell(Map::toSurfCoords(unit->getTargetPos())); - bool visible= sc->isVisible(world->getThisTeamIndex()) || tsc->isVisible(world->getThisTeamIndex()); - if(visible == false && world->showWorldForPlayer(world->getThisFactionIndex()) == true) { - visible = true; - } - - //for(ProjectileParticleSystemTypes::const_iterator pit= unit->getCurrSkill()->projectileParticleSystemTypes.begin(); pit != unit->getCurrSkill()->projectileParticleSystemTypes.end(); ++pit) { - for(ProjectileTypes::const_iterator pt= ast->projectileTypes.begin(); pt != ast->projectileTypes.end(); ++pt) { - bool startAttackParticleSystemNow = ((*pt)->getAttackStartTime() >= lastAnimProgress && (*pt)->getAttackStartTime() < animProgress); - if(startAttackParticleSystemNow){ - ProjectileParticleSystem *psProj= (*pt)->getProjectileParticleSystemType()->create(unit); - psProj->setPath(startPos, endPos); - psProj->setObserver(new ParticleDamager(unit,(*pt), this, gameCamera)); - psProj->setVisible(visible); - if(unit->getFaction()->getTexture()) { - psProj->setFactionColor(unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); - } - renderer.manageParticleSystem(psProj, rsGame); - unit->addAttackParticleSystem(psProj); - - if(pstSplash!=NULL){ - SplashParticleSystem *psSplash= pstSplash->create(unit); - psSplash->setPos(endPos); - psSplash->setVisible(visible); - if(unit->getFaction()->getTexture()) { - psSplash->setFactionColor(unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); - } - renderer.manageParticleSystem(psSplash, rsGame); - unit->addAttackParticleSystem(psSplash); - psProj->link(psSplash); - } - } - } - - // if no projectile, still deal damage.. - if(hasProjectile == false) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"Unit hitting [startAttackParticleSystem] no proj"); - unit->addNetworkCRCDecHp(szBuf); - hit(unit); - //splash - if(pstSplash != NULL) { - SplashParticleSystem *psSplash= pstSplash->create(unit); - psSplash->setPos(endPos); - psSplash->setVisible(visible); - if(unit->getFaction()->getTexture()) { - psSplash->setFactionColor(unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); - } - renderer.manageParticleSystem(psSplash, rsGame); - unit->addAttackParticleSystem(psSplash); - } - } -} - -// ==================== misc ==================== - -//looks for a resource of type rt, if rt==NULL looks for any -//resource the unit can harvest -bool UnitUpdater::searchForResource(Unit *unit, const HarvestCommandType *hct) { - Vec2i pos= unit->getCurrCommand()->getPos(); - - for(int radius= 0; radius < maxResSearchRadius; radius++) { - for(int i = pos.x - radius; i <= pos.x + radius; ++i) { - for(int j=pos.y - radius; j <= pos.y + radius; ++j) { - if(map->isInside(i, j)) { - Resource *r= map->getSurfaceCell(Map::toSurfCoords(Vec2i(i, j)))->getResource(); - if(r != NULL) { - if(hct->canHarvest(r->getType())) { - const Vec2i newPos = Vec2i(i, j); - if(unit->isBadHarvestPos(newPos) == false) { - unit->getCurrCommand()->setPos(newPos); - - return true; + return true; + } + } } - } - } - } - } - } - } - - return false; -} - -bool UnitUpdater::attackerOnSight(Unit *unit, Unit **rangedPtr, bool evalMode){ - int range = unit->getType()->getTotalSight(unit->getTotalUpgrade()); - return unitOnRange(unit, range, rangedPtr, NULL,evalMode); -} - -bool UnitUpdater::attackableOnSight(Unit *unit, Unit **rangedPtr, const AttackSkillType *ast, bool evalMode) { - int range = unit->getType()->getTotalSight(unit->getTotalUpgrade()); - return unitOnRange(unit, range, rangedPtr, ast, evalMode); -} - -bool UnitUpdater::attackableOnRange(Unit *unit, Unit **rangedPtr, const AttackSkillType *ast,bool evalMode) { - int range= ast->getTotalAttackRange(unit->getTotalUpgrade()); - return unitOnRange(unit, range, rangedPtr, ast, evalMode); -} - -bool UnitUpdater::findCachedCellsEnemies(Vec2i center, int range, int size, vector &enemies, - const AttackSkillType *ast, const Unit *unit, - const Unit *commandTarget) { - bool result = false; - MutexSafeWrapper safeMutex(mutexUnitRangeCellsLookupItemCache,string(__FILE__) + "_" + intToStr(__LINE__)); - std::map > >::iterator iterFind = UnitRangeCellsLookupItemCache.find(center); - - if(iterFind != UnitRangeCellsLookupItemCache.end()) { - std::map >::iterator iterFind3 = iterFind->second.find(size); - if(iterFind3 != iterFind->second.end()) { - std::map::iterator iterFind4 = iterFind3->second.find(range); - if(iterFind4 != iterFind3->second.end()) { - result = true; - - std::vector &cellList = iterFind4->second.rangeCellList; - for(int idx = 0; idx < (int)cellList.size(); ++idx) { - Cell *cell = cellList[idx]; - - findEnemiesForCell(ast,cell,unit,commandTarget,enemies); + } + } } } + + return false; } - } - return result; -} + bool UnitUpdater::attackerOnSight(Unit *unit, Unit **rangedPtr, bool evalMode) { + int range = unit->getType()->getTotalSight(unit->getTotalUpgrade()); + return unitOnRange(unit, range, rangedPtr, NULL, evalMode); + } -void UnitUpdater::findEnemiesForCell(const AttackSkillType *ast, Cell *cell, const Unit *unit, - const Unit *commandTarget,vector &enemies) { - //all fields - for(int k = 0; k < fieldCount; k++) { - Field f= static_cast(k); + bool UnitUpdater::attackableOnSight(Unit *unit, Unit **rangedPtr, const AttackSkillType *ast, bool evalMode) { + int range = unit->getType()->getTotalSight(unit->getTotalUpgrade()); + return unitOnRange(unit, range, rangedPtr, ast, evalMode); + } - //check field - if((ast == NULL || ast->getAttackField(f))) { - Unit *possibleEnemy = cell->getUnit(f); + bool UnitUpdater::attackableOnRange(Unit *unit, Unit **rangedPtr, const AttackSkillType *ast, bool evalMode) { + int range = ast->getTotalAttackRange(unit->getTotalUpgrade()); + return unitOnRange(unit, range, rangedPtr, ast, evalMode); + } - //check enemy - if(possibleEnemy != NULL && possibleEnemy->isAlive()) { - if((unit->isAlly(possibleEnemy) == false && commandTarget == NULL) || - commandTarget == possibleEnemy) { + bool UnitUpdater::findCachedCellsEnemies(Vec2i center, int range, int size, vector &enemies, + const AttackSkillType *ast, const Unit *unit, + const Unit *commandTarget) { + bool result = false; + MutexSafeWrapper safeMutex(mutexUnitRangeCellsLookupItemCache, string(__FILE__) + "_" + intToStr(__LINE__)); + std::map > >::iterator iterFind = UnitRangeCellsLookupItemCache.find(center); - enemies.push_back(possibleEnemy); + if (iterFind != UnitRangeCellsLookupItemCache.end()) { + std::map >::iterator iterFind3 = iterFind->second.find(size); + if (iterFind3 != iterFind->second.end()) { + std::map::iterator iterFind4 = iterFind3->second.find(range); + if (iterFind4 != iterFind3->second.end()) { + result = true; + + std::vector &cellList = iterFind4->second.rangeCellList; + for (int idx = 0; idx < (int) cellList.size(); ++idx) { + Cell *cell = cellList[idx]; + + findEnemiesForCell(ast, cell, unit, commandTarget, enemies); + } + } } } + + return result; } - } -} -void UnitUpdater::findEnemiesForCell(const Vec2i pos, int size, int sightRange, const Faction *faction, vector &enemies, bool attackersOnly) const { - //all fields - for(int k = 0; k < fieldCount; k++) { - Field f= static_cast(k); + void UnitUpdater::findEnemiesForCell(const AttackSkillType *ast, Cell *cell, const Unit *unit, + const Unit *commandTarget, vector &enemies) { + //all fields + for (int k = 0; k < fieldCount; k++) { + Field f = static_cast(k); - for(int i = pos.x - sightRange; i < pos.x + size + sightRange; ++i) { - for(int j = pos.y - sightRange; j < pos.y + size + sightRange; ++j) { - Vec2i testPos(i,j); - if( map->isInside(testPos) && - map->isInsideSurface(map->toSurfCoords(testPos))) { - Cell *cell = map->getCell(testPos); - //check field + //check field + if ((ast == NULL || ast->getAttackField(f))) { Unit *possibleEnemy = cell->getUnit(f); //check enemy - if(possibleEnemy != NULL && possibleEnemy->isAlive()) { - if(faction->getTeam() != possibleEnemy->getTeam()) { - if(attackersOnly == true) { - if(possibleEnemy->getType()->hasCommandClass(ccAttack) || possibleEnemy->getType()->hasCommandClass(ccAttackStopped)) { - enemies.push_back(possibleEnemy); + if (possibleEnemy != NULL && possibleEnemy->isAlive()) { + if ((unit->isAlly(possibleEnemy) == false && commandTarget == NULL) || + commandTarget == possibleEnemy) { + + enemies.push_back(possibleEnemy); + } + } + } + } + } + + void UnitUpdater::findEnemiesForCell(const Vec2i pos, int size, int sightRange, const Faction *faction, vector &enemies, bool attackersOnly) const { + //all fields + for (int k = 0; k < fieldCount; k++) { + Field f = static_cast(k); + + for (int i = pos.x - sightRange; i < pos.x + size + sightRange; ++i) { + for (int j = pos.y - sightRange; j < pos.y + size + sightRange; ++j) { + Vec2i testPos(i, j); + if (map->isInside(testPos) && + map->isInsideSurface(map->toSurfCoords(testPos))) { + Cell *cell = map->getCell(testPos); + //check field + Unit *possibleEnemy = cell->getUnit(f); + + //check enemy + if (possibleEnemy != NULL && possibleEnemy->isAlive()) { + if (faction->getTeam() != possibleEnemy->getTeam()) { + if (attackersOnly == true) { + if (possibleEnemy->getType()->hasCommandClass(ccAttack) || possibleEnemy->getType()->hasCommandClass(ccAttackStopped)) { + enemies.push_back(possibleEnemy); + } + } else { + enemies.push_back(possibleEnemy); + } } } - else { - enemies.push_back(possibleEnemy); + } + } + } + } + } + + //if the unit has any enemy on range + bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr, + const AttackSkillType *ast, bool evalMode) { + bool result = false; + + try { + vector enemies; + enemies.reserve(100); + + //we check command target + const Unit *commandTarget = NULL; + if (unit->anyCommand() && unit->getCurrCommand() != NULL) { + commandTarget = static_cast(unit->getCurrCommand()->getUnit()); + } + if (commandTarget != NULL && commandTarget->isDead()) { + commandTarget = NULL; + } + //aux vars + int size = unit->getType()->getSize(); + Vec2i center = unit->getPos(); + Vec2f floatCenter = unit->getFloatCenteredPos(); + + //bool foundInCache = true; + if (findCachedCellsEnemies(center, range, size, enemies, ast, + unit, commandTarget) == false) { + + //foundInCache = false; + //nearby cells + UnitRangeCellsLookupItem cacheItem; + for (int i = center.x - range; i < center.x + range + size; ++i) { + for (int j = center.y - range; j < center.y + range + size; ++j) { + //cells inside map and in range +#ifdef USE_STREFLOP + if (map->isInside(i, j) && streflop::floor(static_cast(floatCenter.dist(Vec2f((float) i, (float) j)))) <= (range + 1)) { +#else + if (map->isInside(i, j) && floor(floatCenter.dist(Vec2f((float) i, (float) j))) <= (range + 1)) { +#endif + Cell *cell = map->getCell(i, j); + findEnemiesForCell(ast, cell, unit, commandTarget, enemies); + + cacheItem.rangeCellList.push_back(cell); + } + } + } + + + // Ok update our caches with the latest info + if (cacheItem.rangeCellList.empty() == false) { + MutexSafeWrapper safeMutex(mutexUnitRangeCellsLookupItemCache, string(__FILE__) + "_" + intToStr(__LINE__)); + + UnitRangeCellsLookupItemCache[center][size][range] = cacheItem; + } + } + + //attack enemies that can attack first + float distToUnit = -1; + Unit* enemySeen = NULL; + + float distToStandingUnit = -1; + Unit* attackingEnemySeen = NULL; + ControlType controlType = unit->getFaction()->getControlType(); + bool isUltra = controlType == ctCpuUltra || controlType == ctNetworkCpuUltra; + bool isZeta = controlType == ctCpuZeta || controlType == ctNetworkCpuZeta; + + + string randomInfoData = "enemies.size() = " + intToStr(enemies.size()); + + //printf("unit %d has control:%d\n",unit->getId(),controlType); + for (int i = 0; i < (int) enemies.size(); ++i) { + Unit *enemy = enemies[i]; + + + if (enemy != NULL && enemy->isAlive() == true) { + + // Here we default to first enemy if no attackers found + if (enemySeen == NULL) { + *rangedPtr = enemy; + enemySeen = enemy; + result = true; + } + + //randomInfoData += " i = " + intToStr(i) + " alive = true result = " + intToStr(result); + + // Attackers get first priority + if (enemy->getType()->hasSkillClass(scAttack) == true) { + + float currentDist = unit->getCenteredPos().dist(enemy->getCenteredPos()); + + //randomInfoData += " currentDist = " + floatToStr(currentDist); + + // Select closest attacking unit + if (distToUnit < 0 || currentDist < distToUnit) { + distToUnit = currentDist; + *rangedPtr = enemies[i]; + enemySeen = enemies[i]; + result = true; + } + + if (isUltra || isZeta) { + + if (distToStandingUnit < 0 || currentDist < distToStandingUnit) { + if (enemies[i]->getCurrSkill() != NULL && enemies[i]->getCurrSkill()->getClass() == scAttack) { + distToStandingUnit = currentDist; + attackingEnemySeen = enemies[i]; + } + } } } } } - } - } - } -} -//if the unit has any enemy on range -bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr, - const AttackSkillType *ast,bool evalMode) { - bool result=false; + if (evalMode == false && (isUltra || isZeta)) { - try { - vector enemies; - enemies.reserve(100); + unit->getRandom()->addLastCaller(randomInfoData); - //we check command target - const Unit *commandTarget = NULL; - if(unit->anyCommand() && unit->getCurrCommand() != NULL) { - commandTarget = static_cast(unit->getCurrCommand()->getUnit()); - } - if(commandTarget != NULL && commandTarget->isDead()) { - commandTarget = NULL; - } - //aux vars - int size = unit->getType()->getSize(); - Vec2i center = unit->getPos(); - Vec2f floatCenter = unit->getFloatCenteredPos(); - - //bool foundInCache = true; - if(findCachedCellsEnemies(center,range,size,enemies,ast, - unit,commandTarget) == false) { - - //foundInCache = false; - //nearby cells - UnitRangeCellsLookupItem cacheItem; - for(int i = center.x - range; i < center.x + range + size; ++i) { - for(int j = center.y - range; j < center.y + range + size; ++j) { - //cells inside map and in range -#ifdef USE_STREFLOP - if(map->isInside(i, j) && streflop::floor(static_cast(floatCenter.dist(Vec2f((float)i, (float)j)))) <= (range+1)){ -#else - if(map->isInside(i, j) && floor(floatCenter.dist(Vec2f((float)i, (float)j))) <= (range+1)){ -#endif - Cell *cell = map->getCell(i,j); - findEnemiesForCell(ast,cell,unit,commandTarget,enemies); - - cacheItem.rangeCellList.push_back(cell); - } - } - } - - - // Ok update our caches with the latest info - if(cacheItem.rangeCellList.empty() == false) { - MutexSafeWrapper safeMutex(mutexUnitRangeCellsLookupItemCache,string(__FILE__) + "_" + intToStr(__LINE__)); - - UnitRangeCellsLookupItemCache[center][size][range] = cacheItem; - } - } - - //attack enemies that can attack first - float distToUnit= -1; - Unit* enemySeen= NULL; - - float distToStandingUnit= -1; - Unit* attackingEnemySeen= NULL; - ControlType controlType= unit->getFaction()->getControlType(); - bool isUltra= controlType == ctCpuUltra || controlType == ctNetworkCpuUltra; - bool isZeta = controlType == ctCpuZeta || controlType == ctNetworkCpuZeta; - - - string randomInfoData = "enemies.size() = " + intToStr(enemies.size()); - - //printf("unit %d has control:%d\n",unit->getId(),controlType); - for(int i = 0; i< (int)enemies.size(); ++i) { - Unit *enemy = enemies[i]; - - - if(enemy != NULL && enemy->isAlive() == true) { - - // Here we default to first enemy if no attackers found - if(enemySeen == NULL) { - *rangedPtr = enemy; - enemySeen = enemy; - result = true; - } - - //randomInfoData += " i = " + intToStr(i) + " alive = true result = " + intToStr(result); - - // Attackers get first priority - if(enemy->getType()->hasSkillClass(scAttack) == true) { - - float currentDist = unit->getCenteredPos().dist(enemy->getCenteredPos()); - - //randomInfoData += " currentDist = " + floatToStr(currentDist); - - // Select closest attacking unit - if(distToUnit < 0 || currentDist< distToUnit) { - distToUnit = currentDist; - *rangedPtr = enemies[i]; - enemySeen = enemies[i]; - result = true; - } - - if(isUltra || isZeta) { - - if(distToStandingUnit < 0 || currentDist< distToStandingUnit) { - if(enemies[i]->getCurrSkill()!=NULL && enemies[i]->getCurrSkill()->getClass()==scAttack) { - distToStandingUnit = currentDist; - attackingEnemySeen=enemies[i]; - } - } - } - } - } - } - - if(evalMode == false && (isUltra || isZeta)) { - - unit->getRandom()->addLastCaller(randomInfoData); - - if( attackingEnemySeen != NULL && unit->getRandom()->randRange(0,2,extractFileFromDirectoryPath(__FILE__) + intToStr(__LINE__)) != 2 ) { - //if( attackingEnemySeen != NULL) { - *rangedPtr = attackingEnemySeen; - enemySeen = attackingEnemySeen; - //printf("Da hat er wen gefunden:%s\n",enemySeen->getType()->getName(false).c_str()); - } - } - - if(result == true) { - - //const Unit* teamUnit = NULL; - const Unit* enemyUnit = NULL; - bool onlyEnemyUnits = true; - - if(unit->getTeam() == world->getThisTeamIndex()) { - //teamUnit = unit; - enemyUnit = enemySeen; - onlyEnemyUnits = false; - } - else if(enemySeen->getTeam() == world->getThisTeamIndex()) { - //teamUnit = enemySeen; - enemyUnit = unit; - onlyEnemyUnits = false; - } - - if(evalMode == false && onlyEnemyUnits == false && - enemyUnit->getTeam() != world->getThisTeamIndex()) { - - Vec2f enemyFloatCenter = enemyUnit->getFloatCenteredPos(); - // find nearest Attack and cleanup old dates - AttackWarningData *nearest = NULL; - float currentDistance = 0.f; - float nearestDistance = 0.f; - - - MutexSafeWrapper safeMutex(mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__)); - for(int i = (int)attackWarnings.size() - 1; i >= 0; --i) { - if(world->getFrameCount() - attackWarnings[i]->lastFrameCount > 200) { //after 200 frames attack break we warn again - AttackWarningData *toDelete =attackWarnings[i]; - attackWarnings.erase(attackWarnings.begin()+i); - delete toDelete; // old one - } - else { -#ifdef USE_STREFLOP - currentDistance = streflop::floor(static_cast(enemyFloatCenter.dist(attackWarnings[i]->attackPosition))); // no need for streflops here! -#else - currentDistance = floor(enemyFloatCenter.dist(attackWarnings[i]->attackPosition)); // no need for streflops here! -#endif - - if(nearest == NULL) { - nearest = attackWarnings[i]; - nearestDistance = currentDistance; + if (attackingEnemySeen != NULL && unit->getRandom()->randRange(0, 2, extractFileFromDirectoryPath(__FILE__) + intToStr(__LINE__)) != 2) { + //if( attackingEnemySeen != NULL) { + *rangedPtr = attackingEnemySeen; + enemySeen = attackingEnemySeen; + //printf("Da hat er wen gefunden:%s\n",enemySeen->getType()->getName(false).c_str()); } - else { - if(currentDistance < nearestDistance) { - nearest = attackWarnings[i]; - nearestDistance = currentDistance; + } + + if (result == true) { + + //const Unit* teamUnit = NULL; + const Unit* enemyUnit = NULL; + bool onlyEnemyUnits = true; + + if (unit->getTeam() == world->getThisTeamIndex()) { + //teamUnit = unit; + enemyUnit = enemySeen; + onlyEnemyUnits = false; + } else if (enemySeen->getTeam() == world->getThisTeamIndex()) { + //teamUnit = enemySeen; + enemyUnit = unit; + onlyEnemyUnits = false; + } + + if (evalMode == false && onlyEnemyUnits == false && + enemyUnit->getTeam() != world->getThisTeamIndex()) { + + Vec2f enemyFloatCenter = enemyUnit->getFloatCenteredPos(); + // find nearest Attack and cleanup old dates + AttackWarningData *nearest = NULL; + float currentDistance = 0.f; + float nearestDistance = 0.f; + + + MutexSafeWrapper safeMutex(mutexAttackWarnings, string(__FILE__) + "_" + intToStr(__LINE__)); + for (int i = (int) attackWarnings.size() - 1; i >= 0; --i) { + if (world->getFrameCount() - attackWarnings[i]->lastFrameCount > 200) { //after 200 frames attack break we warn again + AttackWarningData *toDelete = attackWarnings[i]; + attackWarnings.erase(attackWarnings.begin() + i); + delete toDelete; // old one + } else { +#ifdef USE_STREFLOP + currentDistance = streflop::floor(static_cast(enemyFloatCenter.dist(attackWarnings[i]->attackPosition))); // no need for streflops here! +#else + currentDistance = floor(enemyFloatCenter.dist(attackWarnings[i]->attackPosition)); // no need for streflops here! +#endif + + if (nearest == NULL) { + nearest = attackWarnings[i]; + nearestDistance = currentDistance; + } else { + if (currentDistance < nearestDistance) { + nearest = attackWarnings[i]; + nearestDistance = currentDistance; + } + } + } + } + + if (nearest != NULL) { + + // does it fit? + if (nearestDistance < attackWarnRange) { + // update entry with current values + nearest->lastFrameCount = world->getFrameCount(); + nearest->attackPosition.x = enemyFloatCenter.x; + nearest->attackPosition.y = enemyFloatCenter.y; + } else { + //Must be a different Attack! + nearest = NULL; //set to null to force a new entry in next step + } + } + // add new attack + if (nearest == NULL) { + // no else! + AttackWarningData* awd = new AttackWarningData(); + awd->lastFrameCount = world->getFrameCount(); + awd->attackPosition.x = enemyFloatCenter.x; + awd->attackPosition.y = enemyFloatCenter.y; + + MutexSafeWrapper safeMutex(mutexAttackWarnings, string(__FILE__) + "_" + intToStr(__LINE__)); + attackWarnings.push_back(awd); + + if (world->getAttackWarningsEnabled() == true) { + static PlaySoundClip snd; + + SoundRenderer::getInstance().playFx(snd.getSound(snd.sfxAttention), true); + world->addAttackEffects(enemyUnit); + } } } } - } - if(nearest != NULL) { + } catch (const exception &ex) { + //setRunningStatus(false); - // does it fit? - if(nearestDistance < attackWarnRange) { - // update entry with current values - nearest->lastFrameCount=world->getFrameCount(); - nearest->attackPosition.x=enemyFloatCenter.x; - nearest->attackPosition.y=enemyFloatCenter.y; - } - else { - //Must be a different Attack! - nearest=NULL; //set to null to force a new entry in next step - } - } - // add new attack - if(nearest == NULL) { - // no else! - AttackWarningData* awd= new AttackWarningData(); - awd->lastFrameCount=world->getFrameCount(); - awd->attackPosition.x=enemyFloatCenter.x; - awd->attackPosition.y=enemyFloatCenter.y; + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - MutexSafeWrapper safeMutex(mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__)); - attackWarnings.push_back(awd); - - if(world->getAttackWarningsEnabled() == true) { - static PlaySoundClip snd; - - SoundRenderer::getInstance().playFx(snd.getSound (snd.sfxAttention),true); - world->addAttackEffects(enemyUnit); - } - } - } - } - - } - catch(const exception &ex) { - //setRunningStatus(false); - - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - throw megaglest_runtime_error(ex.what()); - } - catch(...) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - throw megaglest_runtime_error(szBuf); - } - - return result; -} - - -//if the unit has any enemy on range -vector UnitUpdater::enemyUnitsOnRange(const Unit *unit,const AttackSkillType *ast) { - vector enemies; - enemies.reserve(100); - - try { - - - int range = unit->getType()->getTotalSight(unit->getTotalUpgrade()); - if(ast != NULL) { - - range = ast->getTotalAttackRange(unit->getTotalUpgrade()); - } - //we check command target - const Unit *commandTarget = NULL; -// if(unit->anyCommand()) { -// commandTarget = static_cast(unit->getCurrCommand()->getUnit()); -// } -// if(commandTarget != NULL && commandTarget->isDead()) { -// commandTarget = NULL; -// } - - //aux vars - int size = unit->getType()->getSize(); - Vec2i center = unit->getPosNotThreadSafe(); - Vec2f floatCenter = unit->getFloatCenteredPos(); - - //bool foundInCache = true; - if(findCachedCellsEnemies(center,range,size,enemies,ast, - unit,commandTarget) == false) { - - //foundInCache = false; - //nearby cells - UnitRangeCellsLookupItem cacheItem; - for(int i = center.x - range; i < center.x + range + size; ++i) { - for(int j = center.y - range; j < center.y + range + size; ++j) { - //cells inside map and in range -#ifdef USE_STREFLOP - if(map->isInside(i, j) && streflop::floor(static_cast(floatCenter.dist(Vec2f((float)i, (float)j)))) <= (range+1)){ -#else - if(map->isInside(i, j) && floor(floatCenter.dist(Vec2f((float)i, (float)j))) <= (range+1)){ -#endif - Cell *cell = map->getCell(i,j); - findEnemiesForCell(ast,cell,unit,commandTarget,enemies); - - cacheItem.rangeCellList.push_back(cell); + throw megaglest_runtime_error(ex.what()); + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); } + + return result; } - } - - // Ok update our caches with the latest info - if(cacheItem.rangeCellList.empty() == false) { - MutexSafeWrapper safeMutex(mutexUnitRangeCellsLookupItemCache,string(__FILE__) + "_" + intToStr(__LINE__)); - - UnitRangeCellsLookupItemCache[center][size][range] = cacheItem; - } - } - - } - catch(const exception &ex) { - //setRunningStatus(false); - - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - throw megaglest_runtime_error(ex.what()); - } - catch(...) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - throw megaglest_runtime_error(szBuf); - } - - return enemies; -} -void UnitUpdater::findUnitsForCell(Cell *cell, vector &units) { - //all fields - if(cell != NULL) { - for(int k = 0; k < fieldCount; k++) { - Field f= static_cast(k); + //if the unit has any enemy on range + vector UnitUpdater::enemyUnitsOnRange(const Unit *unit, const AttackSkillType *ast) { + vector enemies; + enemies.reserve(100); - //check field - Unit *cellUnit = cell->getUnit(f); + try { - if(cellUnit != NULL && cellUnit->isAlive()) { - // check if unit already is in list - bool found = false; - //printf("---- search for cellUnit=%d\n",cellUnit->getId()); - for (unsigned int i = 0; i < units.size(); ++i) { - Unit *unitInList = units[i]; - //printf("compare unitInList=%d cellUnit=%d\n",unitInList->getId(),cellUnit->getId()); - if (unitInList->getId() == cellUnit->getId()){ - found=true; - break; + + int range = unit->getType()->getTotalSight(unit->getTotalUpgrade()); + if (ast != NULL) { + + range = ast->getTotalAttackRange(unit->getTotalUpgrade()); + } + //we check command target + const Unit *commandTarget = NULL; + // if(unit->anyCommand()) { + // commandTarget = static_cast(unit->getCurrCommand()->getUnit()); + // } + // if(commandTarget != NULL && commandTarget->isDead()) { + // commandTarget = NULL; + // } + + //aux vars + int size = unit->getType()->getSize(); + Vec2i center = unit->getPosNotThreadSafe(); + Vec2f floatCenter = unit->getFloatCenteredPos(); + + //bool foundInCache = true; + if (findCachedCellsEnemies(center, range, size, enemies, ast, + unit, commandTarget) == false) { + + //foundInCache = false; + //nearby cells + UnitRangeCellsLookupItem cacheItem; + for (int i = center.x - range; i < center.x + range + size; ++i) { + for (int j = center.y - range; j < center.y + range + size; ++j) { + //cells inside map and in range +#ifdef USE_STREFLOP + if (map->isInside(i, j) && streflop::floor(static_cast(floatCenter.dist(Vec2f((float) i, (float) j)))) <= (range + 1)) { +#else + if (map->isInside(i, j) && floor(floatCenter.dist(Vec2f((float) i, (float) j))) <= (range + 1)) { +#endif + Cell *cell = map->getCell(i, j); + findEnemiesForCell(ast, cell, unit, commandTarget, enemies); + + cacheItem.rangeCellList.push_back(cell); + } + } + } + + // Ok update our caches with the latest info + if (cacheItem.rangeCellList.empty() == false) { + MutexSafeWrapper safeMutex(mutexUnitRangeCellsLookupItemCache, string(__FILE__) + "_" + intToStr(__LINE__)); + + UnitRangeCellsLookupItemCache[center][size][range] = cacheItem; + } + } + + } catch (const exception &ex) { + //setRunningStatus(false); + + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + throw megaglest_runtime_error(ex.what()); + } catch (...) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s %d] UNKNOWN error\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, szBuf); + throw megaglest_runtime_error(szBuf); + } + + return enemies; + } + + + void UnitUpdater::findUnitsForCell(Cell *cell, vector &units) { + //all fields + if (cell != NULL) { + for (int k = 0; k < fieldCount; k++) { + Field f = static_cast(k); + + //check field + Unit *cellUnit = cell->getUnit(f); + + if (cellUnit != NULL && cellUnit->isAlive()) { + // check if unit already is in list + bool found = false; + //printf("---- search for cellUnit=%d\n",cellUnit->getId()); + for (unsigned int i = 0; i < units.size(); ++i) { + Unit *unitInList = units[i]; + //printf("compare unitInList=%d cellUnit=%d\n",unitInList->getId(),cellUnit->getId()); + if (unitInList->getId() == cellUnit->getId()) { + found = true; + break; + } + } + if (found == false) { + //printf(">>> adding cellUnit=%d\n",cellUnit->getId()); + units.push_back(cellUnit); + } } } - if(found==false){ - //printf(">>> adding cellUnit=%d\n",cellUnit->getId()); - units.push_back(cellUnit); + } + } + + vector UnitUpdater::findUnitsInRange(const Unit *unit, int radius) { + int range = radius; + vector units; + + //aux vars + int size = unit->getType()->getSize(); + Vec2i center = unit->getPosNotThreadSafe(); + Vec2f floatCenter = unit->getFloatCenteredPos(); + + //nearby cells + //UnitRangeCellsLookupItem cacheItem; + for (int i = center.x - range; i < center.x + range + size; ++i) { + for (int j = center.y - range; j < center.y + range + size; ++j) { + //cells inside map and in range +#ifdef USE_STREFLOP + if (map->isInside(i, j) && streflop::floor(static_cast(floatCenter.dist(Vec2f((float) i, (float) j)))) <= (range + 1)) { +#else + if (map->isInside(i, j) && floor(floatCenter.dist(Vec2f((float) i, (float) j))) <= (range + 1)) { +#endif + Cell *cell = map->getCell(i, j); + findUnitsForCell(cell, units); + } + } + } + + return units; + } + + string UnitUpdater::getUnitRangeCellsLookupItemCacheStats() { + string result = ""; + + int posCount = 0; + int sizeCount = 0; + int rangeCount = 0; + int rangeCountCellCount = 0; + + MutexSafeWrapper safeMutex(mutexUnitRangeCellsLookupItemCache, string(__FILE__) + "_" + intToStr(__LINE__)); + for (std::map > >::iterator iterMap1 = UnitRangeCellsLookupItemCache.begin(); + iterMap1 != UnitRangeCellsLookupItemCache.end(); ++iterMap1) { + posCount++; + + for (std::map >::iterator iterMap2 = iterMap1->second.begin(); + iterMap2 != iterMap1->second.end(); ++iterMap2) { + sizeCount++; + + for (std::map::iterator iterMap3 = iterMap2->second.begin(); + iterMap3 != iterMap2->second.end(); ++iterMap3) { + rangeCount++; + + rangeCountCellCount += (int) iterMap3->second.rangeCellList.size(); + } } } + + uint64 totalBytes = rangeCountCellCount * sizeof(Cell *); + totalBytes /= 1000; + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "pos [%d] size [%d] range [%d][%d] total KB: %s", posCount, sizeCount, rangeCount, rangeCountCellCount, formatNumber(totalBytes).c_str()); + result = szBuf; + return result; } - } -} -vector UnitUpdater::findUnitsInRange(const Unit *unit, int radius) { - int range = radius; - vector units; + void UnitUpdater::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *unitupdaterNode = rootNode->addChild("UnitUpdater"); - //aux vars - int size = unit->getType()->getSize(); - Vec2i center = unit->getPosNotThreadSafe(); - Vec2f floatCenter = unit->getFloatCenteredPos(); + // const GameCamera *gameCamera; + // Gui *gui; + // Map *map; + // World *world; + // Console *console; + // ScriptManager *scriptManager; + // PathFinder *pathFinder; + pathFinder->saveGame(unitupdaterNode); + // Game *game; + // RandomGen random; + //unitupdaterNode->addAttribute("random",intToStr(random.getLastNumber()), mapTagReplacements); + // float attackWarnRange; + unitupdaterNode->addAttribute("attackWarnRange", floatToStr(attackWarnRange, 6), mapTagReplacements); + // AttackWarnings attackWarnings; + // + } - //nearby cells - //UnitRangeCellsLookupItem cacheItem; - for(int i = center.x - range; i < center.x + range + size; ++i) { - for(int j = center.y - range; j < center.y + range + size; ++j) { - //cells inside map and in range -#ifdef USE_STREFLOP - if(map->isInside(i, j) && streflop::floor(static_cast(floatCenter.dist(Vec2f((float)i, (float)j)))) <= (range+1)){ -#else - if(map->isInside(i, j) && floor(floatCenter.dist(Vec2f((float)i, (float)j))) <= (range+1)){ -#endif - Cell *cell = map->getCell(i,j); - findUnitsForCell(cell,units); + void UnitUpdater::clearCaches() { + if (pathFinder != NULL) { + pathFinder->clearCaches(); } } - } - return units; -} + void UnitUpdater::loadGame(const XmlNode *rootNode) { + const XmlNode *unitupdaterNode = rootNode->getChild("UnitUpdater"); -string UnitUpdater::getUnitRangeCellsLookupItemCacheStats() { - string result = ""; + pathFinder->loadGame(unitupdaterNode); + //random.setLastNumber(unitupdaterNode->getAttribute("random")->getIntValue()); + // float attackWarnRange; + attackWarnRange = unitupdaterNode->getAttribute("attackWarnRange")->getFloatValue(); + } + // ===================================================== + // class ParticleDamager + // ===================================================== - int posCount = 0; - int sizeCount = 0; - int rangeCount = 0; - int rangeCountCellCount = 0; + ParticleDamager::ParticleDamager(Unit *attacker, const ProjectileType* projectileType, UnitUpdater *unitUpdater, const GameCamera *gameCamera) { + this->gameCamera = gameCamera; + this->attackerRef = attacker; + this->projectileType = projectileType; + this->ast = static_cast(attacker->getCurrSkill()); + this->targetPos = attacker->getTargetPos(); + this->targetField = attacker->getTargetField(); + this->unitUpdater = unitUpdater; + } - MutexSafeWrapper safeMutex(mutexUnitRangeCellsLookupItemCache,string(__FILE__) + "_" + intToStr(__LINE__)); - for(std::map > >::iterator iterMap1 = UnitRangeCellsLookupItemCache.begin(); - iterMap1 != UnitRangeCellsLookupItemCache.end(); ++iterMap1) { - posCount++; + void ParticleDamager::update(ParticleSystem *particleSystem) { + Unit *attacker = attackerRef.getUnit(); - for(std::map >::iterator iterMap2 = iterMap1->second.begin(); - iterMap2 != iterMap1->second.end(); ++iterMap2) { - sizeCount++; + if (attacker != NULL) { + //string auditBeforeHit = particleSystem->toString(); - for(std::map::iterator iterMap3 = iterMap2->second.begin(); - iterMap3 != iterMap2->second.end(); ++iterMap3) { - rangeCount++; + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "Unit hitting [ParticleDamager::update] [%s] targetField = %d", targetPos.getString().c_str(), targetField); + attacker->addNetworkCRCDecHp(szBuf); - rangeCountCellCount += (int)iterMap3->second.rangeCellList.size(); + unitUpdater->hit(attacker, ast, targetPos, targetField, projectileType->getDamagePercentage()); + + //char szBuf[8096]=""; + //snprintf(szBuf,8095,"ParticleDamager::update attacker particleSystem before: %s\nafter: %s",auditBeforeHit.c_str(),particleSystem->toString().c_str()); + //attacker->setNetworkCRCParticleObserverLogInfo(szBuf); + + //play sound + // Try to use the sound form the projetileType + StaticSound *projSound = projectileType->getHitSound(); + if (projSound == NULL) { + // use the sound from the skill + projSound = ast->getProjSound(); + } + if (particleSystem->getVisible() && projSound != NULL) { + SoundRenderer::getInstance().playFx(projSound, attacker->getCurrMidHeightVector(), gameCamera->getPos()); + } + + //check for spawnattack + if (projectileType->getSpawnUnit() != "" && projectileType->getSpawnUnitcount() > 0) { + unitUpdater->spawnAttack(attacker, projectileType->getSpawnUnit(), 100, + 100, 100, projectileType->getSpawnUnitcount(), + projectileType->getSpawnUnitAtTarget(), targetPos); + } + + // check for shake and shake + if (projectileType->isShake() == true) { + World *world = attacker->getFaction()->getWorld(); + Map* map = world->getMap(); + Game *game = world->getGame(); + + //Unit *attacked= map->getCell(targetPos)->getUnit(targetField); + Vec2i surfaceTargetPos = Map::toSurfCoords(targetPos); + bool visibility = (!projectileType->isShakeVisible()) || (map->getSurfaceCell(surfaceTargetPos)->isVisible(world->getThisTeamIndex()) || + (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)); + + bool isInCameraView = (!projectileType->isShakeInCameraView()) || Renderer::getInstance().posInCellQuadCache(surfaceTargetPos).first; + + if (visibility && isInCameraView) { + game->getGameCameraPtr()->shake(projectileType->getShakeDuration(), projectileType->getShakeIntensity(), projectileType->isShakeCameraDistanceAffected(), map->getSurfaceCell(surfaceTargetPos)->getVertex()); + } + } } - } - } - - uint64 totalBytes = rangeCountCellCount * sizeof(Cell *); - totalBytes /= 1000; - - char szBuf[8096]=""; - snprintf(szBuf,8096,"pos [%d] size [%d] range [%d][%d] total KB: %s",posCount,sizeCount,rangeCount,rangeCountCellCount,formatNumber(totalBytes).c_str()); - result = szBuf; - return result; -} - -void UnitUpdater::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *unitupdaterNode = rootNode->addChild("UnitUpdater"); - -// const GameCamera *gameCamera; -// Gui *gui; -// Map *map; -// World *world; -// Console *console; -// ScriptManager *scriptManager; -// PathFinder *pathFinder; - pathFinder->saveGame(unitupdaterNode); -// Game *game; -// RandomGen random; - //unitupdaterNode->addAttribute("random",intToStr(random.getLastNumber()), mapTagReplacements); -// float attackWarnRange; - unitupdaterNode->addAttribute("attackWarnRange",floatToStr(attackWarnRange,6), mapTagReplacements); -// AttackWarnings attackWarnings; -// -} - -void UnitUpdater::clearCaches() { - if(pathFinder != NULL) { - pathFinder->clearCaches(); - } -} - -void UnitUpdater::loadGame(const XmlNode *rootNode) { - const XmlNode *unitupdaterNode = rootNode->getChild("UnitUpdater"); - - pathFinder->loadGame(unitupdaterNode); - //random.setLastNumber(unitupdaterNode->getAttribute("random")->getIntValue()); -// float attackWarnRange; - attackWarnRange = unitupdaterNode->getAttribute("attackWarnRange")->getFloatValue(); -} -// ===================================================== -// class ParticleDamager -// ===================================================== - -ParticleDamager::ParticleDamager(Unit *attacker,const ProjectileType* projectileType, UnitUpdater *unitUpdater, const GameCamera *gameCamera){ - this->gameCamera= gameCamera; - this->attackerRef= attacker; - this->projectileType= projectileType; - this->ast= static_cast(attacker->getCurrSkill()); - this->targetPos= attacker->getTargetPos(); - this->targetField= attacker->getTargetField(); - this->unitUpdater= unitUpdater; -} - -void ParticleDamager::update(ParticleSystem *particleSystem) { - Unit *attacker= attackerRef.getUnit(); - - if(attacker != NULL) { - //string auditBeforeHit = particleSystem->toString(); - - char szBuf[8096]=""; - snprintf(szBuf,8095,"Unit hitting [ParticleDamager::update] [%s] targetField = %d",targetPos.getString().c_str(),targetField); - attacker->addNetworkCRCDecHp(szBuf); - - unitUpdater->hit(attacker, ast, targetPos, targetField, projectileType->getDamagePercentage()); - - //char szBuf[8096]=""; - //snprintf(szBuf,8095,"ParticleDamager::update attacker particleSystem before: %s\nafter: %s",auditBeforeHit.c_str(),particleSystem->toString().c_str()); - //attacker->setNetworkCRCParticleObserverLogInfo(szBuf); - - //play sound - // Try to use the sound form the projetileType - StaticSound *projSound=projectileType->getHitSound(); - if(projSound == NULL){ - // use the sound from the skill - projSound= ast->getProjSound(); - } - if(particleSystem->getVisible() && projSound != NULL) { - SoundRenderer::getInstance().playFx(projSound, attacker->getCurrMidHeightVector(), gameCamera->getPos()); + particleSystem->setObserver(NULL); + delete this; } - //check for spawnattack - if(projectileType->getSpawnUnit()!="" && projectileType->getSpawnUnitcount()>0 ){ - unitUpdater->spawnAttack(attacker, projectileType->getSpawnUnit(), 100, - 100, 100, projectileType->getSpawnUnitcount(), - projectileType->getSpawnUnitAtTarget(), targetPos); + void ParticleDamager::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *particleDamagerNode = rootNode->addChild("ParticleDamager"); + + // UnitReference attackerRef; + attackerRef.saveGame(particleDamagerNode); + + // const AttackSkillType* ast; + particleDamagerNode->addAttribute("astName", ast->getName(), mapTagReplacements); + particleDamagerNode->addAttribute("astClass", intToStr(ast->getClass()), mapTagReplacements); + // UnitUpdater *unitUpdater; + // const GameCamera *gameCamera; + // Vec2i targetPos; + particleDamagerNode->addAttribute("targetPos", targetPos.getString(), mapTagReplacements); + // Field targetField; + particleDamagerNode->addAttribute("targetField", intToStr(targetField), mapTagReplacements); } - // check for shake and shake - if(projectileType->isShake()==true){ - World *world=attacker->getFaction()->getWorld(); - Map* map=world->getMap(); - Game *game=world->getGame(); + void ParticleDamager::loadGame(const XmlNode *rootNode, void *genericData) { + const XmlNode *particleDamagerNode = rootNode->getChild("ParticleDamager"); - //Unit *attacked= map->getCell(targetPos)->getUnit(targetField); - Vec2i surfaceTargetPos=Map::toSurfCoords(targetPos); - bool visibility=(!projectileType->isShakeVisible())||(map->getSurfaceCell(surfaceTargetPos)->isVisible(world->getThisTeamIndex()) || - (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true)); + std::pair *pairData = (std::pair*)genericData; + //UnitType *ut, Game *game + attackerRef.loadGame(particleDamagerNode, pairData->first->getWorld()); - bool isInCameraView=(!projectileType->isShakeInCameraView()) || Renderer::getInstance().posInCellQuadCache(surfaceTargetPos).first; + //random.setLastNumber(particleSystemNode->getAttribute("random")->getIntValue()); - if(visibility && isInCameraView) { - game->getGameCameraPtr()->shake( projectileType->getShakeDuration(), projectileType->getShakeIntensity(),projectileType->isShakeCameraDistanceAffected(),map->getSurfaceCell(surfaceTargetPos)->getVertex()); - } + // const AttackSkillType* ast; + string astName = particleDamagerNode->getAttribute("astName")->getValue(); + SkillClass astClass = static_cast(particleDamagerNode->getAttribute("astClass")->getIntValue()); + ast = dynamic_cast(pairData->second->getType()->getSkillType(astName, astClass)); + // UnitUpdater *unitUpdater; + unitUpdater = pairData->first->getWorld()->getUnitUpdater(); + // const GameCamera *gameCamera; + gameCamera = pairData->first->getGameCamera(); + // Vec2i targetPos; + targetPos = Vec2i::strToVec2(particleDamagerNode->getAttribute("targetPos")->getValue()); + // Field targetField; + targetField = static_cast(particleDamagerNode->getAttribute("targetField")->getIntValue()); } - } - particleSystem->setObserver(NULL); - delete this; -} -void ParticleDamager::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *particleDamagerNode = rootNode->addChild("ParticleDamager"); - -// UnitReference attackerRef; - attackerRef.saveGame(particleDamagerNode); - -// const AttackSkillType* ast; - particleDamagerNode->addAttribute("astName",ast->getName(), mapTagReplacements); - particleDamagerNode->addAttribute("astClass",intToStr(ast->getClass()), mapTagReplacements); -// UnitUpdater *unitUpdater; -// const GameCamera *gameCamera; -// Vec2i targetPos; - particleDamagerNode->addAttribute("targetPos",targetPos.getString(), mapTagReplacements); -// Field targetField; - particleDamagerNode->addAttribute("targetField",intToStr(targetField), mapTagReplacements); -} - -void ParticleDamager::loadGame(const XmlNode *rootNode, void *genericData) { - const XmlNode *particleDamagerNode = rootNode->getChild("ParticleDamager"); - - std::pair *pairData = (std::pair*)genericData; - //UnitType *ut, Game *game - attackerRef.loadGame(particleDamagerNode,pairData->first->getWorld()); - - //random.setLastNumber(particleSystemNode->getAttribute("random")->getIntValue()); - - // const AttackSkillType* ast; - string astName = particleDamagerNode->getAttribute("astName")->getValue(); - SkillClass astClass = static_cast(particleDamagerNode->getAttribute("astClass")->getIntValue()); - ast = dynamic_cast(pairData->second->getType()->getSkillType(astName,astClass)); - // UnitUpdater *unitUpdater; - unitUpdater = pairData->first->getWorld()->getUnitUpdater(); - // const GameCamera *gameCamera; - gameCamera = pairData->first->getGameCamera(); - // Vec2i targetPos; - targetPos = Vec2i::strToVec2(particleDamagerNode->getAttribute("targetPos")->getValue()); - // Field targetField; - targetField = static_cast(particleDamagerNode->getAttribute("targetField")->getIntValue()); -} - -}}//end namespace + } + }//end namespace diff --git a/source/glest_game/world/unit_updater.h b/source/glest_game/world/unit_updater.h index 2dee6c004..2bf75f118 100644 --- a/source/glest_game/world/unit_updater.h +++ b/source/glest_game/world/unit_updater.h @@ -25,8 +25,8 @@ #define _GLEST_GAME_UNITUPDATER_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include "gui.h" @@ -38,168 +38,172 @@ using Shared::Graphics::ParticleObserver; using Shared::Util::RandomGen; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -class Unit; -class Map; -class ScriptManager; -class PathFinder; + class Unit; + class Map; + class ScriptManager; + class PathFinder; -// ===================================================== -// class UnitUpdater -// -/// Updates all units in the game, even the player -/// controlled units, performs basic actions only -/// such as responding to an attack -// ===================================================== + // ===================================================== + // class UnitUpdater + // + /// Updates all units in the game, even the player + /// controlled units, performs basic actions only + /// such as responding to an attack + // ===================================================== -class ParticleDamager; -class Cell; + class ParticleDamager; + class Cell; -class UnitRangeCellsLookupItem { -public: + class UnitRangeCellsLookupItem { + public: - //int UnitRangeCellsLookupItemCacheTimerCountIndex; - std::vector rangeCellList; + //int UnitRangeCellsLookupItemCacheTimerCountIndex; + std::vector rangeCellList; - static time_t lastDebug; -}; + static time_t lastDebug; + }; -class AttackWarningData { -public: - Vec2f attackPosition; - int lastFrameCount; -}; + class AttackWarningData { + public: + Vec2f attackPosition; + int lastFrameCount; + }; -class UnitUpdater { -private: - friend class ParticleDamager; - typedef vector AttackWarnings; + class UnitUpdater { + private: + friend class ParticleDamager; + typedef vector AttackWarnings; -private: - static const int maxResSearchRadius= 10; - static const int harvestDistance= 5; - static const int ultraResourceFactor= 3; - static const int megaResourceFactor= 4; + private: + static const int maxResSearchRadius = 10; + static const int harvestDistance = 5; + static const int ultraResourceFactor = 3; + static const int megaResourceFactor = 4; -private: - const GameCamera *gameCamera; - Gui *gui; - Map *map; - World *world; - Console *console; - ScriptManager *scriptManager; - PathFinder *pathFinder; - Game *game; - //RandomGen random; - Mutex *mutexAttackWarnings; - float attackWarnRange; - AttackWarnings attackWarnings; + private: + const GameCamera *gameCamera; + Gui *gui; + Map *map; + World *world; + Console *console; + ScriptManager *scriptManager; + PathFinder *pathFinder; + Game *game; + //RandomGen random; + Mutex *mutexAttackWarnings; + float attackWarnRange; + AttackWarnings attackWarnings; - Mutex *mutexUnitRangeCellsLookupItemCache; - std::map > > UnitRangeCellsLookupItemCache; - //std::map ExploredCellsLookupItemCacheTimer; - //int UnitRangeCellsLookupItemCacheTimerCount; + Mutex *mutexUnitRangeCellsLookupItemCache; + std::map > > UnitRangeCellsLookupItemCache; + //std::map ExploredCellsLookupItemCacheTimer; + //int UnitRangeCellsLookupItemCacheTimerCount; - bool findCachedCellsEnemies(Vec2i center, int range, - int size, vector &enemies, - const AttackSkillType *ast, const Unit *unit, - const Unit *commandTarget); - void findEnemiesForCell(const AttackSkillType *ast, Cell *cell, const Unit *unit, - const Unit *commandTarget,vector &enemies); + bool findCachedCellsEnemies(Vec2i center, int range, + int size, vector &enemies, + const AttackSkillType *ast, const Unit *unit, + const Unit *commandTarget); + void findEnemiesForCell(const AttackSkillType *ast, Cell *cell, const Unit *unit, + const Unit *commandTarget, vector &enemies); -public: - UnitUpdater(); - void init(Game *game); - ~UnitUpdater(); + public: + UnitUpdater(); + void init(Game *game); + ~UnitUpdater(); - //update skills - bool updateUnit(Unit *unit); + //update skills + bool updateUnit(Unit *unit); - //update commands - void updateUnitCommand(Unit *unit, int frameIndex); - void updateStop(Unit *unit, int frameIndex); - void updateMove(Unit *unit, int frameIndex); - void updateAttack(Unit *unit, int frameIndex); - void updateAttackStopped(Unit *unit, int frameIndex); - void updateBuild(Unit *unit, int frameIndex); - void updateHarvest(Unit *unit, int frameIndex); - void updateHarvestEmergencyReturn(Unit *unit, int frameIndex); - void updateRepair(Unit *unit, int frameIndex); - void updateProduce(Unit *unit, int frameIndex); - void updateUpgrade(Unit *unit, int frameIndex); - void updateMorph(Unit *unit, int frameIndex); - void updateSwitchTeam(Unit *unit, int frameIndex); + //update commands + void updateUnitCommand(Unit *unit, int frameIndex); + void updateStop(Unit *unit, int frameIndex); + void updateMove(Unit *unit, int frameIndex); + void updateAttack(Unit *unit, int frameIndex); + void updateAttackStopped(Unit *unit, int frameIndex); + void updateBuild(Unit *unit, int frameIndex); + void updateHarvest(Unit *unit, int frameIndex); + void updateHarvestEmergencyReturn(Unit *unit, int frameIndex); + void updateRepair(Unit *unit, int frameIndex); + void updateProduce(Unit *unit, int frameIndex); + void updateUpgrade(Unit *unit, int frameIndex); + void updateMorph(Unit *unit, int frameIndex); + void updateSwitchTeam(Unit *unit, int frameIndex); - void clearUnitPrecache(Unit *unit); - void removeUnitPrecache(Unit *unit); + void clearUnitPrecache(Unit *unit); + void removeUnitPrecache(Unit *unit); - inline unsigned int getAttackWarningCount() const { return (unsigned int)attackWarnings.size(); } - std::pair unitBeingAttacked(const Unit *unit); - void unitBeingAttacked(std::pair &result, const Unit *unit, const AttackSkillType *ast,float *currentDistToUnit=NULL); - vector enemyUnitsOnRange(const Unit *unit,const AttackSkillType *ast); - void findEnemiesForCell(const Vec2i pos, int size, int sightRange, const Faction *faction, vector &enemies, bool attackersOnly) const; + inline unsigned int getAttackWarningCount() const { + return (unsigned int) attackWarnings.size(); + } + std::pair unitBeingAttacked(const Unit *unit); + void unitBeingAttacked(std::pair &result, const Unit *unit, const AttackSkillType *ast, float *currentDistToUnit = NULL); + vector enemyUnitsOnRange(const Unit *unit, const AttackSkillType *ast); + void findEnemiesForCell(const Vec2i pos, int size, int sightRange, const Faction *faction, vector &enemies, bool attackersOnly) const; - vector findUnitsInRange(const Unit *unit, int radius); + vector findUnitsInRange(const Unit *unit, int radius); - string getUnitRangeCellsLookupItemCacheStats(); + string getUnitRangeCellsLookupItemCacheStats(); - void saveGame(XmlNode *rootNode); - void loadGame(const XmlNode *rootNode); + void saveGame(XmlNode *rootNode); + void loadGame(const XmlNode *rootNode); - void clearCaches(); + void clearCaches(); -private: - //attack - void hit(Unit *attacker); - void hit(Unit *attacker, const AttackSkillType* ast, const Vec2i &targetPos, Field targetField, int damagePercent); - void damage(Unit *attacker, const AttackSkillType* ast, Unit *attacked, float distance, int damagePercent); - void startAttackParticleSystem(Unit *unit, float lastAnimProgress, float animProgress); + private: + //attack + void hit(Unit *attacker); + void hit(Unit *attacker, const AttackSkillType* ast, const Vec2i &targetPos, Field targetField, int damagePercent); + void damage(Unit *attacker, const AttackSkillType* ast, Unit *attacked, float distance, int damagePercent); + void startAttackParticleSystem(Unit *unit, float lastAnimProgress, float animProgress); - //misc - bool searchForResource(Unit *unit, const HarvestCommandType *hct); - bool attackerOnSight(Unit *unit, Unit **enemyPtr, bool evalMode=false); - bool attackableOnSight(Unit *unit, Unit **enemyPtr, const AttackSkillType *ast, bool evalMode=false); - bool attackableOnRange(Unit *unit, Unit **enemyPtr, const AttackSkillType *ast, bool evalMode=false); - bool unitOnRange(Unit *unit, int range, Unit **enemyPtr, const AttackSkillType *ast,bool evalMode=false); - void enemiesAtDistance(const Unit *unit, const Unit *priorityUnit, int distance, vector &enemies); + //misc + bool searchForResource(Unit *unit, const HarvestCommandType *hct); + bool attackerOnSight(Unit *unit, Unit **enemyPtr, bool evalMode = false); + bool attackableOnSight(Unit *unit, Unit **enemyPtr, const AttackSkillType *ast, bool evalMode = false); + bool attackableOnRange(Unit *unit, Unit **enemyPtr, const AttackSkillType *ast, bool evalMode = false); + bool unitOnRange(Unit *unit, int range, Unit **enemyPtr, const AttackSkillType *ast, bool evalMode = false); + void enemiesAtDistance(const Unit *unit, const Unit *priorityUnit, int distance, vector &enemies); - void spawn(Unit *unit,string spawnUnit,int spawnUnitcount,int healthMin,int healthMax,int probability); - void spawnAttack(Unit *unit,string spawnUnit,int spawnUnitcount,int healthMin,int healthMax,int probability,bool spawnUnitAtTarget,Vec2i targetPos=Vec2i(-10,-10)); - Unit* spawnUnit(Unit *unit,string spawnUnit,Vec2i targetPos=Vec2i(-10,-10)); + void spawn(Unit *unit, string spawnUnit, int spawnUnitcount, int healthMin, int healthMax, int probability); + void spawnAttack(Unit *unit, string spawnUnit, int spawnUnitcount, int healthMin, int healthMax, int probability, bool spawnUnitAtTarget, Vec2i targetPos = Vec2i(-10, -10)); + Unit* spawnUnit(Unit *unit, string spawnUnit, Vec2i targetPos = Vec2i(-10, -10)); - Unit * findPeerUnitBuilder(Unit *unit); - void SwapActiveCommand(Unit *unitSrc, Unit *unitDest); - void SwapActiveCommandState(Unit *unit, CommandStateType commandStateType, - const CommandType *commandType, - int originalValue,int newValue); - void findUnitsForCell(Cell *cell, vector &units); + Unit * findPeerUnitBuilder(Unit *unit); + void SwapActiveCommand(Unit *unitSrc, Unit *unitDest); + void SwapActiveCommandState(Unit *unit, CommandStateType commandStateType, + const CommandType *commandType, + int originalValue, int newValue); + void findUnitsForCell(Cell *cell, vector &units); -}; + }; -// ===================================================== -// class ParticleDamager -// ===================================================== + // ===================================================== + // class ParticleDamager + // ===================================================== -class ParticleDamager: public ParticleObserver { + class ParticleDamager : public ParticleObserver { -public: - UnitReference attackerRef; - const AttackSkillType* ast; - const ProjectileType* projectileType; - UnitUpdater *unitUpdater; - const GameCamera *gameCamera; - Vec2i targetPos; - Field targetField; + public: + UnitReference attackerRef; + const AttackSkillType* ast; + const ProjectileType* projectileType; + UnitUpdater *unitUpdater; + const GameCamera *gameCamera; + Vec2i targetPos; + Field targetField; -public: - ParticleDamager(Unit *attacker, const ProjectileType *projectileType, UnitUpdater *unitUpdater, const GameCamera *gameCamera); - virtual void update(ParticleSystem *particleSystem); + public: + ParticleDamager(Unit *attacker, const ProjectileType *projectileType, UnitUpdater *unitUpdater, const GameCamera *gameCamera); + virtual void update(ParticleSystem *particleSystem); - virtual void saveGame(XmlNode *rootNode); - virtual void loadGame(const XmlNode *rootNode,void *genericData); -}; + virtual void saveGame(XmlNode *rootNode); + virtual void loadGame(const XmlNode *rootNode, void *genericData); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/glest_game/world/water_effects.cpp b/source/glest_game/world/water_effects.cpp index af6d86071..2d16b468e 100644 --- a/source/glest_game/world/water_effects.cpp +++ b/source/glest_game/world/water_effects.cpp @@ -15,55 +15,57 @@ #include "map.h" #include "leak_dumper.h" -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class WaterSplash -// ===================================================== + // ===================================================== + // class WaterSplash + // ===================================================== -WaterSplash::WaterSplash(const Vec2f &pos, int size){ - this->pos= pos; - this->size=1+(size-1)/2; - anim= 0.f; - enabled= true; + WaterSplash::WaterSplash(const Vec2f &pos, int size) { + this->pos = pos; + this->size = 1 + (size - 1) / 2; + anim = 0.f; + enabled = true; -} - -void WaterSplash::update(float amount){ - if(enabled){ - anim+= amount/size; - if(anim>1.f){ - enabled= false; } - } -} -// =============================== -// class WaterEffects -// =============================== - -WaterEffects::WaterEffects(){ - anim= 0; -} - -void WaterEffects::update(float speed){ - anim+= 0.5f/GameConstants::updateFps; - if(anim>1.f){ - anim= 0; - } - for(int i=0; i < (int)waterSplashes.size(); ++i){ - waterSplashes[i].update(speed/GameConstants::updateFps); - } -} - -void WaterEffects::addWaterSplash(const Vec2f &pos, int size){ - for(int i=0; i < (int)waterSplashes.size(); ++i){ - if(!waterSplashes[i].getEnabled()){ - waterSplashes[i]= WaterSplash(pos,size); - return; + void WaterSplash::update(float amount) { + if (enabled) { + anim += amount / size; + if (anim > 1.f) { + enabled = false; + } + } } - } - waterSplashes.push_back(WaterSplash(pos,size)); -} -}}//end namespace + // =============================== + // class WaterEffects + // =============================== + + WaterEffects::WaterEffects() { + anim = 0; + } + + void WaterEffects::update(float speed) { + anim += 0.5f / GameConstants::updateFps; + if (anim > 1.f) { + anim = 0; + } + for (int i = 0; i < (int) waterSplashes.size(); ++i) { + waterSplashes[i].update(speed / GameConstants::updateFps); + } + } + + void WaterEffects::addWaterSplash(const Vec2f &pos, int size) { + for (int i = 0; i < (int) waterSplashes.size(); ++i) { + if (!waterSplashes[i].getEnabled()) { + waterSplashes[i] = WaterSplash(pos, size); + return; + } + } + waterSplashes.push_back(WaterSplash(pos, size)); + } + + } +}//end namespace diff --git a/source/glest_game/world/water_effects.h b/source/glest_game/world/water_effects.h index 70c703a08..a4a56a2b7 100644 --- a/source/glest_game/world/water_effects.h +++ b/source/glest_game/world/water_effects.h @@ -13,8 +13,8 @@ #define _GLEST_GAME_WATER_EFFECTS_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -25,58 +25,74 @@ using std::vector; using Shared::Graphics::Vec2f; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -class Map; + class Map; -// ===================================================== -// class WaterSplash -// ===================================================== + // ===================================================== + // class WaterSplash + // ===================================================== -class WaterSplash{ -private: - Vec2f pos; - int size; - float anim; - bool enabled; + class WaterSplash { + private: + Vec2f pos; + int size; + float anim; + bool enabled; -public: - WaterSplash(const Vec2f &pos, int size); + public: + WaterSplash(const Vec2f &pos, int size); - void update(float amount); + void update(float amount); - const Vec2f &getPos() const {return pos;} - const int &getSize() const {return size;} - float getAnim() const {return anim;} - bool getEnabled() const {return enabled;} -}; + const Vec2f &getPos() const { + return pos; + } + const int &getSize() const { + return size; + } + float getAnim() const { + return anim; + } + bool getEnabled() const { + return enabled; + } + }; -// =============================== -// class WaterEffects -// -/// List of water splashes -// =============================== + // =============================== + // class WaterEffects + // + /// List of water splashes + // =============================== -class WaterEffects{ -public: - typedef vector WaterSplashes; + class WaterEffects { + public: + typedef vector WaterSplashes; -private: - WaterSplashes waterSplashes; - float anim; - -public: - WaterEffects(); + private: + WaterSplashes waterSplashes; + float anim; - void update(float speed); + public: + WaterEffects(); - float getAmin() const {return anim;} + void update(float speed); - void addWaterSplash(const Vec2f &pos, int size); - int getWaterSplashCount() const {return (int)waterSplashes.size();} - const WaterSplash *getWaterSplash(int i) const {return &waterSplashes[i];} -}; + float getAmin() const { + return anim; + } -}}//end namespace + void addWaterSplash(const Vec2f &pos, int size); + int getWaterSplashCount() const { + return (int) waterSplashes.size(); + } + const WaterSplash *getWaterSplash(int i) const { + return &waterSplashes[i]; + } + }; + + } +}//end namespace #endif diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index 89f2ca0a0..691f56c73 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -42,3095 +42,3048 @@ using namespace Shared::Graphics; using namespace Shared::Util; -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -// ===================================================== -// class World -// ===================================================== + // ===================================================== + // class World + // ===================================================== -// This limit is to keep RAM use under control while offering better performance. -int MaxExploredCellsLookupItemCache = 9500; -//int MaxExploredCellsLookupItemCache = 0; -time_t ExploredCellsLookupItem::lastDebug = 0; + // This limit is to keep RAM use under control while offering better performance. + int MaxExploredCellsLookupItemCache = 9500; + //int MaxExploredCellsLookupItemCache = 0; + time_t ExploredCellsLookupItem::lastDebug = 0; -// ===================== PUBLIC ======================== + // ===================== PUBLIC ======================== -World::World() : mutexFactionNextUnitId(new Mutex(CODE_AT_LINE)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - Config &config= Config::getInstance(); + World::World() : mutexFactionNextUnitId(new Mutex(CODE_AT_LINE)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + Config &config = Config::getInstance(); - unitParticlesEnabled=config.getBool("UnitParticles","true"); + unitParticlesEnabled = config.getBool("UnitParticles", "true"); - animatedTilesetObjectPosListLoaded = false; + animatedTilesetObjectPosListLoaded = false; - ExploredCellsLookupItemCache.clear(); - ExploredCellsLookupItemCacheTimer.clear(); - ExploredCellsLookupItemCacheTimerCount = 0; + ExploredCellsLookupItemCache.clear(); + ExploredCellsLookupItemCacheTimer.clear(); + ExploredCellsLookupItemCacheTimerCount = 0; - nextCommandGroupId = 0; - techTree = NULL; - fogOfWarOverride = false; - fogOfWarSkillTypeValue = -1; - - fogOfWarSmoothing= config.getBool("FogOfWarSmoothing"); - fogOfWarSmoothingFrameSkip= config.getInt("FogOfWarSmoothingFrameSkip"); - - frameCount= 0; - - scriptManager= NULL; - this->game = NULL; - - thisFactionIndex=0; - thisTeamIndex=0; - fogOfWar=false; - originalGameFogOfWar = fogOfWar; - perfTimerEnabled=false; - queuedScenarioName=""; - queuedScenarioKeepFactions=false; - disableAttackEffects = false; - - loadWorldNode = NULL; - cacheFowAlphaTexture = false; - cacheFowAlphaTextureFogOfWarValue = false; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void World::cleanup() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - animatedTilesetObjectPosListLoaded = false; - - ExploredCellsLookupItemCache.clear(); - ExploredCellsLookupItemCacheTimer.clear(); - //FowAlphaCellsLookupItemCache.clear(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - for(int i= 0; i < (int)factions.size(); ++i){ - factions[i]->end(); - } - - masterController.clearSlaves(true); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - for(int i= 0; i < (int)factions.size(); ++i){ - delete factions[i]; - } - factions.clear(); - -#ifdef LEAK_CHECK_UNITS - printf("%s::%s\n",__FILE__,__FUNCTION__); - Unit::dumpMemoryList(); - UnitPathBasic::dumpMemoryList(); -#endif - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - delete techTree; - techTree = NULL; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - for(std::map::iterator iterMap = staticSoundList.begin(); - iterMap != staticSoundList.end(); ++iterMap) { - delete iterMap->second; - } - staticSoundList.clear(); - - for(std::map::iterator iterMap = streamSoundList.begin(); - iterMap != streamSoundList.end(); ++iterMap) { - delete iterMap->second; - } - streamSoundList.clear(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -World::~World() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - cleanup(); - - delete mutexFactionNextUnitId; - mutexFactionNextUnitId = NULL; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void World::endScenario() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingWorld","",true), true); - - animatedTilesetObjectPosListLoaded = false; - - ExploredCellsLookupItemCache.clear(); - ExploredCellsLookupItemCacheTimer.clear(); - - fogOfWarOverride = false; - originalGameFogOfWar = fogOfWar; - fogOfWarSkillTypeValue = -1; - cacheFowAlphaTexture = false; - cacheFowAlphaTextureFogOfWarValue = false; - - map.end(); - - //stats will be deleted by BattleEnd - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void World::end(){ - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingWorld","",true), true); - - animatedTilesetObjectPosListLoaded = false; - - ExploredCellsLookupItemCache.clear(); - ExploredCellsLookupItemCacheTimer.clear(); - - for(int i= 0; i < (int)factions.size(); ++i){ - factions[i]->end(); - } - - masterController.clearSlaves(true); - for(int i= 0; i < (int)factions.size(); ++i){ - delete factions[i]; - } - factions.clear(); - -#ifdef LEAK_CHECK_UNITS - printf("%s::%s\n",__FILE__,__FUNCTION__); - Unit::dumpMemoryList(); - UnitPathBasic::dumpMemoryList(); -#endif - - fogOfWarOverride = false; - originalGameFogOfWar = fogOfWar; - fogOfWarSkillTypeValue = -1; - - map.end(); - cacheFowAlphaTexture = false; - cacheFowAlphaTextureFogOfWarValue = false; - - //stats will be deleted by BattleEnd - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -// ========================== init =============================================== - -void World::addFogOfWarSkillType(const Unit *unit,const FogOfWarSkillType *fowst) { - std::pair fowData; - fowData.first = unit; - fowData.second = fowst; - - mapFogOfWarUnitList[unit->getId()] = fowData; - - if((fowst->getApplyToTeam() == true && unit->getTeam() == this->getThisTeamIndex()) || - (fowst->getApplyToTeam() == false && unit->getFactionIndex() == this->getThisFactionIndex())) { - if((fowst->getFowEnable() == false && fogOfWarSkillTypeValue != 0) || - (fowst->getFowEnable() == true && fogOfWarSkillTypeValue != 1)) { - - //printf("In [%s::%s Line: %d] current = %d new = %d\n",__FILE__,__FUNCTION__,__LINE__,fogOfWar,fowst->getFowEnable()); - setFogOfWar(fowst->getFowEnable()); - } - } -} - -bool World::removeFogOfWarSkillTypeFromList(const Unit *unit) { - bool result = false; - if(mapFogOfWarUnitList.find(unit->getId()) != mapFogOfWarUnitList.end()) { - mapFogOfWarUnitList.erase(unit->getId()); - result = true; - } - return result; -} - -void World::removeFogOfWarSkillType(const Unit *unit) { - bool removedFromList = removeFogOfWarSkillTypeFromList(unit); - if(removedFromList == true) { - if(mapFogOfWarUnitList.empty() == true) { - - //printf("In [%s::%s Line: %d] current = %d new = %d\n",__FILE__,__FUNCTION__,__LINE__,fogOfWar,originalGameFogOfWar); - fogOfWarSkillTypeValue = -1; + nextCommandGroupId = 0; + techTree = NULL; fogOfWarOverride = false; - minimap.restoreFowTex(); + fogOfWarSkillTypeValue = -1; + + fogOfWarSmoothing = config.getBool("FogOfWarSmoothing"); + fogOfWarSmoothingFrameSkip = config.getInt("FogOfWarSmoothingFrameSkip"); + + frameCount = 0; + + scriptManager = NULL; + this->game = NULL; + + thisFactionIndex = 0; + thisTeamIndex = 0; + fogOfWar = false; + originalGameFogOfWar = fogOfWar; + perfTimerEnabled = false; + queuedScenarioName = ""; + queuedScenarioKeepFactions = false; + disableAttackEffects = false; + + loadWorldNode = NULL; + cacheFowAlphaTexture = false; + cacheFowAlphaTextureFogOfWarValue = false; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); } - else { - bool fowEnabled = false; - for(std::map >::const_iterator iterMap = mapFogOfWarUnitList.begin(); - iterMap != mapFogOfWarUnitList.end(); ++iterMap) { - const Unit *unit = iterMap->second.first; - const FogOfWarSkillType *fowst = iterMap->second.second; + void World::cleanup() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + animatedTilesetObjectPosListLoaded = false; + + ExploredCellsLookupItemCache.clear(); + ExploredCellsLookupItemCacheTimer.clear(); + //FowAlphaCellsLookupItemCache.clear(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + for (int i = 0; i < (int) factions.size(); ++i) { + factions[i]->end(); + } + + masterController.clearSlaves(true); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + for (int i = 0; i < (int) factions.size(); ++i) { + delete factions[i]; + } + factions.clear(); + +#ifdef LEAK_CHECK_UNITS + printf("%s::%s\n", __FILE__, __FUNCTION__); + Unit::dumpMemoryList(); + UnitPathBasic::dumpMemoryList(); +#endif + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + delete techTree; + techTree = NULL; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + for (std::map::iterator iterMap = staticSoundList.begin(); + iterMap != staticSoundList.end(); ++iterMap) { + delete iterMap->second; + } + staticSoundList.clear(); + + for (std::map::iterator iterMap = streamSoundList.begin(); + iterMap != streamSoundList.end(); ++iterMap) { + delete iterMap->second; + } + streamSoundList.clear(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + World::~World() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + cleanup(); + + delete mutexFactionNextUnitId; + mutexFactionNextUnitId = NULL; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void World::endScenario() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingWorld", "", true), true); + + animatedTilesetObjectPosListLoaded = false; + + ExploredCellsLookupItemCache.clear(); + ExploredCellsLookupItemCacheTimer.clear(); + + fogOfWarOverride = false; + originalGameFogOfWar = fogOfWar; + fogOfWarSkillTypeValue = -1; + cacheFowAlphaTexture = false; + cacheFowAlphaTextureFogOfWarValue = false; + + map.end(); + + //stats will be deleted by BattleEnd + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void World::end() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameUnLoadingWorld", "", true), true); + + animatedTilesetObjectPosListLoaded = false; + + ExploredCellsLookupItemCache.clear(); + ExploredCellsLookupItemCacheTimer.clear(); + + for (int i = 0; i < (int) factions.size(); ++i) { + factions[i]->end(); + } + + masterController.clearSlaves(true); + for (int i = 0; i < (int) factions.size(); ++i) { + delete factions[i]; + } + factions.clear(); + +#ifdef LEAK_CHECK_UNITS + printf("%s::%s\n", __FILE__, __FUNCTION__); + Unit::dumpMemoryList(); + UnitPathBasic::dumpMemoryList(); +#endif + + fogOfWarOverride = false; + originalGameFogOfWar = fogOfWar; + fogOfWarSkillTypeValue = -1; + + map.end(); + cacheFowAlphaTexture = false; + cacheFowAlphaTextureFogOfWarValue = false; + + //stats will be deleted by BattleEnd + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + // ========================== init =============================================== + + void World::addFogOfWarSkillType(const Unit *unit, const FogOfWarSkillType *fowst) { + std::pair fowData; + fowData.first = unit; + fowData.second = fowst; + + mapFogOfWarUnitList[unit->getId()] = fowData; + + if ((fowst->getApplyToTeam() == true && unit->getTeam() == this->getThisTeamIndex()) || + (fowst->getApplyToTeam() == false && unit->getFactionIndex() == this->getThisFactionIndex())) { + if ((fowst->getFowEnable() == false && fogOfWarSkillTypeValue != 0) || + (fowst->getFowEnable() == true && fogOfWarSkillTypeValue != 1)) { + + //printf("In [%s::%s Line: %d] current = %d new = %d\n",__FILE__,__FUNCTION__,__LINE__,fogOfWar,fowst->getFowEnable()); + setFogOfWar(fowst->getFowEnable()); + } + } + } + + bool World::removeFogOfWarSkillTypeFromList(const Unit *unit) { + bool result = false; + if (mapFogOfWarUnitList.find(unit->getId()) != mapFogOfWarUnitList.end()) { + mapFogOfWarUnitList.erase(unit->getId()); + result = true; + } + return result; + } + + void World::removeFogOfWarSkillType(const Unit *unit) { + bool removedFromList = removeFogOfWarSkillTypeFromList(unit); + if (removedFromList == true) { + if (mapFogOfWarUnitList.empty() == true) { + + //printf("In [%s::%s Line: %d] current = %d new = %d\n",__FILE__,__FUNCTION__,__LINE__,fogOfWar,originalGameFogOfWar); + fogOfWarSkillTypeValue = -1; + fogOfWarOverride = false; + minimap.restoreFowTex(); + } else { + bool fowEnabled = false; + for (std::map >::const_iterator iterMap = mapFogOfWarUnitList.begin(); + iterMap != mapFogOfWarUnitList.end(); ++iterMap) { + + const Unit *unit = iterMap->second.first; + const FogOfWarSkillType *fowst = iterMap->second.second; + + if ((fowst->getApplyToTeam() == true && unit->getTeam() == this->getThisTeamIndex()) || + (fowst->getApplyToTeam() == false && unit->getFactionIndex() == this->getThisFactionIndex())) { + if (fowst->getFowEnable() == true) { + fowEnabled = true; + break; + } + } + } + + if ((fowEnabled == false && fogOfWarSkillTypeValue != 0) || + (fowEnabled == true && fogOfWarSkillTypeValue != 1)) { + //printf("In [%s::%s Line: %d] current = %d new = %d\n",__FILE__,__FUNCTION__,__LINE__,fogOfWar,fowEnabled); + setFogOfWar(fowEnabled); + } + } + } + } + + void World::setFogOfWar(bool value) { + //printf("In [%s::%s Line: %d] current = %d new = %d\n",__FILE__,__FUNCTION__,__LINE__,fogOfWar,value); + + if (fogOfWarOverride == false) { + minimap.copyFowTex(); + } + + if (value == true) { + fogOfWarSkillTypeValue = 1; + } else { + fogOfWarSkillTypeValue = 0; + } + + fogOfWarOverride = true; + } + + void World::clearTileset() { + tileset = Tileset(); + } + + void World::restoreExploredFogOfWarCells() { + for (int i = 0; i < map.getSurfaceW(); ++i) { + for (int j = 0; j < map.getSurfaceH(); ++j) { + for (int k = 0; k < GameConstants::maxPlayers + GameConstants::specialFactions; ++k) { + if (k == thisTeamIndex) { + if (map.getSurfaceCell(i, j)->isExplored(k) == true) { + const Vec2i pos(i, j); + Vec2i surfPos = pos; + //compute max alpha + float maxAlpha = 0.0f; + if (surfPos.x > 1 && surfPos.y > 1 + && surfPos.x < map.getSurfaceW() - 2 + && surfPos.y < map.getSurfaceH() - 2) { + maxAlpha = 1.f; + } else if (surfPos.x > 0 && surfPos.y > 0 + && surfPos.x < map.getSurfaceW() - 1 + && surfPos.y < map.getSurfaceH() - 1) { + maxAlpha = 0.3f; + } + + //compute alpha + float alpha = maxAlpha; + minimap.incFowTextureAlphaSurface(surfPos, alpha); + } + } + } + } + } + } + + void World::init(Game *game, bool createUnits, bool initFactions) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + ExploredCellsLookupItemCache.clear(); + ExploredCellsLookupItemCacheTimer.clear(); + + this->game = game; + scriptManager = game->getScriptManager(); + + GameSettings *gs = game->getGameSettings(); + if (fogOfWarOverride == false) { + fogOfWar = gs->getFogOfWar(); + } + originalGameFogOfWar = fogOfWar; + + if (loadWorldNode != NULL) { + timeFlow.loadGame(loadWorldNode); + } + + if (initFactions == true) { + initFactionTypes(gs); + } + initCells(fogOfWar); //must be done after knowing faction number and dimensions + initMap(); + initSplattedTextures(); + + unitUpdater.init(game); + if (loadWorldNode != NULL) { + unitUpdater.loadGame(loadWorldNode); + } + + //minimap must be init after sum computation + initMinimap(); + + bool gotError = false; + bool skipStackTrace = false; + string sErrBuf = ""; + + try { + if (createUnits) { + initUnits(); + } + } catch (const megaglest_runtime_error &ex) { + gotError = true; + if (ex.wantStackTrace() == true) { + char szErrBuf[8096] = ""; + snprintf(szErrBuf, 8096, "In [%s::%s %d]", __FILE__, __FUNCTION__, __LINE__); + sErrBuf = string(szErrBuf) + string("\nerror [") + string(ex.what()) + string("]\n"); + } else { + skipStackTrace = true; + sErrBuf = ex.what(); + } + SystemFlags::OutputDebug(SystemFlags::debugError, sErrBuf.c_str()); + } catch (const std::exception &ex) { + gotError = true; + char szErrBuf[8096] = ""; + snprintf(szErrBuf, 8096, "In [%s::%s %d]", __FILE__, __FUNCTION__, __LINE__); + sErrBuf = string(szErrBuf) + string("\nerror [") + string(ex.what()) + string("]\n"); + SystemFlags::OutputDebug(SystemFlags::debugError, sErrBuf.c_str()); + } + + if (loadWorldNode != NULL) { + map.loadGame(loadWorldNode, this); + + if (fogOfWar == false) { + for (int i = 0; i < map.getSurfaceW(); ++i) { + for (int j = 0; j < map.getSurfaceH(); ++j) { + + SurfaceCell *sc = map.getSurfaceCell(i, j); + if (sc == NULL) { + throw megaglest_runtime_error("sc == NULL"); + } + + for (int k = 0; k < GameConstants::maxPlayers; k++) { + //sc->setExplored(k, (game->getGameSettings()->getFlagTypes1() & ft1_show_map_resources) == ft1_show_map_resources); + sc->setVisible(k, !fogOfWar); + } + for (int k = GameConstants::maxPlayers; k < GameConstants::maxPlayers + GameConstants::specialFactions; k++) { + sc->setExplored(k, true); + sc->setVisible(k, true); + } + } + } + } else { + restoreExploredFogOfWarCells(); + } + + //minimap.loadGame(loadWorldNode); + } + + //initExplorationState(); ... was only for !fog-of-war, now handled in initCells() + computeFow(); + if (getFrameCount() > 1) { + // this is needed for games that are loaded to "switch the light on". + // otherwise the FowTexture is completely black like in the beginning of a game. + minimap.updateFowTex(1.f); + } + + if (gotError == true) { + throw megaglest_runtime_error(sErrBuf, !skipStackTrace); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + //load tileset + Checksum World::loadTileset(const vector pathList, const string &tilesetName, + Checksum* checksum, std::map > > &loadedFileList) { + Checksum tilsetChecksum; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + tilsetChecksum = tileset.loadTileset(pathList, tilesetName, checksum, loadedFileList); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + timeFlow.init(&tileset); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + return tilsetChecksum; + } + + Checksum World::loadTileset(const string &dir, Checksum *checksum, std::map > > &loadedFileList) { + Checksum tilesetChecksum; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + tileset.load(dir, checksum, &tilesetChecksum, loadedFileList); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + timeFlow.init(&tileset); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + return tilesetChecksum; + } + + //load tech + Checksum World::loadTech(const vector pathList, const string &techName, + set &factions, Checksum *checksum, + std::map > > &loadedFileList, + bool validationMode) { + Checksum techtreeChecksum; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + techTree = new TechTree(pathList); + techtreeChecksum = techTree->loadTech(techName, factions, + checksum, loadedFileList, validationMode); + return techtreeChecksum; + } + + std::vector World::validateFactionTypes() { + return techTree->validateFactionTypes(); + } + + std::vector World::validateResourceTypes() { + return techTree->validateResourceTypes(); + } + + //load map + Checksum World::loadMap(const string &path, Checksum *checksum) { + Checksum mapChecksum; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + checksum->addFile(path); + mapChecksum = map.load(path, techTree, &tileset); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + return mapChecksum; + } + + //load map + Checksum World::loadScenario(const string &path, Checksum *checksum, bool resetCurrentScenario, const XmlNode *rootNode) { + //printf("[%s:%s] Line: %d path [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str()); + + Checksum scenarioChecksum; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + checksum->addFile(path); + + //printf("[%s:%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + + if (resetCurrentScenario == true) { + scenario = Scenario(); + if (scriptManager) scriptManager->init(this, this->getGame()->getGameCameraPtr(), rootNode); + } + + scenarioChecksum = scenario.load(path); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + return scenarioChecksum; + } + + // ==================== misc ==================== + + void World::setQueuedScenario(string scenarioName, bool keepFactions) { + queuedScenarioName = scenarioName; + queuedScenarioKeepFactions = keepFactions; + } + + void World::updateAllTilesetObjects() { + Gui *gui = this->game->getGuiPtr(); + if (gui != NULL) { + Object *selObj = gui->getHighlightedResourceObject(); + if (selObj != NULL) { + selObj->updateHighlight(); + } + } + + if (animatedTilesetObjectPosListLoaded == false) { + animatedTilesetObjectPosListLoaded = true; + animatedTilesetObjectPosList.clear(); + + for (int x = 0; x < map.getSurfaceW(); ++x) { + for (int y = 0; y < map.getSurfaceH(); ++y) { + SurfaceCell *sc = map.getSurfaceCell(x, y); + if (sc != NULL) { + Object *obj = sc->getObject(); + if (obj != NULL && obj->isAnimated() == true) { + //obj->update(); + animatedTilesetObjectPosList.push_back(Vec2i(x, y)); + } + } + } + } + } + if (animatedTilesetObjectPosList.empty() == false) { + for (unsigned int i = 0; i < animatedTilesetObjectPosList.size(); ++i) { + const Vec2i &pos = animatedTilesetObjectPosList[i]; + SurfaceCell *sc = map.getSurfaceCell(pos); + if (sc != NULL) { + Object *obj = sc->getObject(); + if (obj != NULL && obj->isAnimated() == true) { + obj->update(); + } + } + } + } + + // for(int x = 0; x < map.getSurfaceW(); ++x) { + // for(int y = 0; y < map.getSurfaceH(); ++y) { + // SurfaceCell *sc = map.getSurfaceCell(x,y); + // if(sc != NULL) { + // Object *obj = sc->getObject(); + // if(obj != NULL) { + // obj->update(); + // } + // } + // } + // } + } + + void World::updateAllFactionUnits() { + bool showPerfStats = Config::getInstance().getBool("ShowPerfStats", "false"); + Chrono chronoPerf; + if (showPerfStats) chronoPerf.start(); + char perfBuf[8096] = ""; + std::vector perfList; + + if (scriptManager) scriptManager->onTimerTriggerEvent(); + + // Prioritize grouped command units so closest units to target go first + // units + int factionCount = getFactionCount(); + //printf("===== STARTING Frame: %d\n",frameCount); + // Config &config= Config::getInstance(); + // bool sortedUnitsAllowed = config.getBool("AllowGroupedUnitCommands","true"); + // + // int factionCount = getFactionCount(); + // if(sortedUnitsAllowed == true) { + // for(int i = 0; i < factionCount; ++i) { + // Faction *faction = getFaction(i); + // if(faction == NULL) { + // throw megaglest_runtime_error("faction == NULL"); + // } + // + // // Sort units by command groups + // faction->sortUnitsByCommandGroups(); + // } + // } + + // Clear pathfinder list restrictions + for (int i = 0; i < factionCount; ++i) { + Faction *faction = getFaction(i); + faction->clearUnitsPathfinding(); + faction->clearWorldSynchThreadedLogList(); + } + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + Chrono chrono; + chrono.start(); + + const bool newThreadManager = Config::getInstance().getBool("EnableNewThreadManager", "false"); + if (newThreadManager == true) { + masterController.signalSlaves(&frameCount); + bool slavesCompleted = masterController.waitTillSlavesTrigger(20000); + + if (SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 10) printf("In [%s::%s Line: %d] *** Faction thread preprocessing took [%lld] msecs for %d factions for frameCount = %d slavesCompleted = %d.\n", __FILE__, __FUNCTION__, __LINE__, (long long int)chrono.getMillis(), factionCount, frameCount, slavesCompleted); + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + } else { + // Signal the faction threads to do any pre-processing + for (int i = 0; i < factionCount; ++i) { + Faction *faction = getFaction(i); + faction->signalWorkerThread(frameCount); + } + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + Chrono chrono; + chrono.start(); + + const int MAX_FACTION_THREAD_WAIT_MILLISECONDS = 20000; + for (; chrono.getMillis() < MAX_FACTION_THREAD_WAIT_MILLISECONDS;) { + bool workThreadsFinished = true; + for (int i = 0; i < factionCount; ++i) { + Faction *faction = getFaction(i); + if (faction->isWorkerThreadSignalCompleted(frameCount) == false) { + workThreadsFinished = false; + break; + } + } + if (workThreadsFinished == true) { + break; + } + // WARNING... Sleep in here causes the server to lag a bit + //if(chrono.getMillis() % 5 == 0) { + // sleep(0); + //} + } + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 10) printf("In [%s::%s Line: %d] *** Faction thread preprocessing took [%lld] msecs for %d factions for frameCount = %d.\n", __FILE__, __FUNCTION__, __LINE__, (long long int)chrono.getMillis(), factionCount, frameCount); + } + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + //units + Chrono chronoPerfUnit; + int totalUnitsChecked = 0; + int totalUnitsProcessed = 0; + for (int i = 0; i < factionCount; ++i) { + Faction *faction = getFaction(i); + + faction->dumpWorldSynchThreadedLogList(); + faction->clearUnitsPathfinding(); + + std::map mapCommandCount; + std::map mapSkillCount; + int unitCountStuck = 0; + int unitCountUpdated = 0; + + int unitCount = faction->getUnitCount(); + for (int j = 0; j < unitCount; ++j) { + Unit *unit = faction->getUnit(j); + if (unit == NULL) { + throw megaglest_runtime_error("unit == NULL"); + } + + CommandClass unitCommandClass = ccCount; + if (unit->getCurrCommand() != NULL) { + unitCommandClass = unit->getCurrCommand()->getCommandType()->getClass(); + } + + SkillClass unitSkillClass = scCount; + if (unit->getCurrSkill() != NULL) { + unitSkillClass = unit->getCurrSkill()->getClass(); + } + + if (showPerfStats) chronoPerfUnit.start(); + + int unitBlockCount = unit->getPath()->getBlockCount(); + bool isStuck = unit->getPath()->isStuck(); + //bool isStuckWithinTolerance = unit->isLastStuckFrameWithinCurrentFrameTolerance(false); + //uint32 lastStuckFrame = unit->getLastStuckFrame(); + + if (unitUpdater.updateUnit(unit) == true) { + unitCountUpdated++; + + if (unit->getLastStuckFrame() == (unsigned int) frameCount) { + unitCountStuck++; + } + mapCommandCount[unitCommandClass] = mapCommandCount[unitCommandClass] + 1; + mapSkillCount[unitSkillClass] = mapSkillCount[unitSkillClass] + 1; + } + totalUnitsChecked++; + + if (showPerfStats && chronoPerfUnit.getMillis() >= 10) { + //sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER " stuck: %d [%d] for unit:\n%sBEFORE unitBlockCount = %d, AFTER = %d, BEFORE lastStuckFrame = %u, AFTER: %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerfUnit.getMillis(),isStuck,isStuckWithinTolerance,unit->toString().c_str(),unitBlockCount,unit->getPath()->getBlockCount(),lastStuckFrame,unit->getLastStuckFrame()); + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER " stuck: %d for unit:\n%sBEFORE unitBlockCount = %d, AFTER = %d, BEFORE , AFTER: %u\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerfUnit.getMillis(), isStuck, unit->toString().c_str(), unitBlockCount, unit->getPath()->getBlockCount(), unit->getLastStuckFrame()); + perfList.push_back(perfBuf); + } + + } + totalUnitsProcessed += unitCountUpdated; + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER " faction: %d / %d unitCount = %d unitCountUpdated = %d unitCountStuck = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis(), i + 1, factionCount, unitCount, unitCountUpdated, unitCountStuck); + perfList.push_back(perfBuf); + + for (std::map::iterator iterMap = mapCommandCount.begin(); + iterMap != mapCommandCount.end(); ++iterMap) { + + sprintf(perfBuf, "Command class = %d, count = %d\n", iterMap->first, iterMap->second); + perfList.push_back(perfBuf); + } + + for (std::map::iterator iterMap = mapSkillCount.begin(); + iterMap != mapSkillCount.end(); ++iterMap) { + + sprintf(perfBuf, "Skill class = %d, count = %d\n", iterMap->first, iterMap->second); + perfList.push_back(perfBuf); + } + } + } + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER " totalUnitsProcessed = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis(), totalUnitsProcessed); + perfList.push_back(perfBuf); + } + + if (showPerfStats && chronoPerf.getMillis() >= 50) { + for (unsigned int x = 0; x < perfList.size(); ++x) { + printf("%s", perfList[x].c_str()); + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 20) printf("In [%s::%s Line: %d] *** Faction MAIN thread processing took [%lld] msecs for %d factions for frameCount = %d.\n", __FILE__, __FUNCTION__, __LINE__, (long long int)chrono.getMillis(), factionCount, frameCount); + } + + void World::underTakeDeadFactionUnits() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + int factionCount = getFactionCount(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] factionCount = %d\n", __FILE__, __FUNCTION__, __LINE__, factionCount); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + //undertake the dead + for (int i = 0; i < factionCount; ++i) { + Faction *faction = getFaction(i); + int unitCount = faction->getUnitCount(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] i = %d, unitCount = %d\n", __FILE__, __FUNCTION__, __LINE__, i, unitCount); + + for (int j = unitCount - 1; j >= 0; j--) { + Unit *unit = faction->getUnit(j); + + if (unit == NULL) { + throw megaglest_runtime_error("unit == NULL"); + } + + if (unit->getToBeUndertaken() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + unit->undertake(); + delete unit; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + } + + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void World::updateAllFactionConsumableCosts() { + //food costs + int resourceTypeCount = techTree->getResourceTypeCount(); + int factionCount = getFactionCount(); + for (int i = 0; i < resourceTypeCount; ++i) { + const ResourceType *rt = techTree->getResourceType(i); + if (rt != NULL && rt->getClass() == rcConsumable && frameCount % (rt->getInterval() * GameConstants::updateFps) == 0) { + for (int j = 0; j < factionCount; ++j) { + Faction *faction = getFaction(j); + if (faction == NULL) { + throw megaglest_runtime_error("faction == NULL"); + } + + faction->applyCostsOnInterval(rt); + } + } + } + } + + void World::update() { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + bool showPerfStats = Config::getInstance().getBool("ShowPerfStats", "false"); + Chrono chronoPerf; + char perfBuf[8096] = ""; + std::vector perfList; + if (showPerfStats) chronoPerf.start(); + + Chrono chronoGamePerformanceCounts; + + ++frameCount; + + //time + timeFlow.update(); + if (scriptManager) scriptManager->onDayNightTriggerEvent(); + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + //water effects + waterEffects.update(1.0f); + // attack effects + attackEffects.update(0.25f); + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + // objects on the map from tilesets + if (this->game) chronoGamePerformanceCounts.start(); + + updateAllTilesetObjects(); + + if (this->game) this->game->addPerformanceCount("updateAllTilesetObjects", chronoGamePerformanceCounts.getMillis()); + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + //units + if (getFactionCount() > 0) { + if (this->game) chronoGamePerformanceCounts.start(); + + updateAllFactionUnits(); + + if (this->game) this->game->addPerformanceCount("updateAllFactionUnits", chronoGamePerformanceCounts.getMillis()); + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + //undertake the dead + if (this->game) chronoGamePerformanceCounts.start(); + + underTakeDeadFactionUnits(); + + if (this->game) this->game->addPerformanceCount("underTakeDeadFactionUnits", chronoGamePerformanceCounts.getMillis()); + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + //food costs + if (this->game) chronoGamePerformanceCounts.start(); + + updateAllFactionConsumableCosts(); + + if (this->game) this->game->addPerformanceCount("updateAllFactionConsumableCosts", chronoGamePerformanceCounts.getMillis()); + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + //fow smoothing + if (fogOfWarSmoothing && ((frameCount + 1) % (fogOfWarSmoothingFrameSkip + 1)) == 0) { + if (this->game) chronoGamePerformanceCounts.start(); + + float fogFactor = static_cast(frameCount % GameConstants::updateFps) / GameConstants::updateFps; + minimap.updateFowTex(clamp(fogFactor, 0.f, 1.f)); + + if (this->game) this->game->addPerformanceCount("minimap.updateFowTex", chronoGamePerformanceCounts.getMillis()); + } + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + //tick + bool needToTick = canTickWorld(); + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (needToTick == true) { + //printf("=========== World is about to be updated, current frameCount = %d\n",frameCount); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (this->game) chronoGamePerformanceCounts.start(); + + tick(); + + if (this->game) this->game->addPerformanceCount("world->tick", chronoGamePerformanceCounts.getMillis()); + } + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + } + + if (showPerfStats && chronoPerf.getMillis() >= 50) { + for (unsigned int x = 0; x < perfList.size(); ++x) { + printf("%s", perfList[x].c_str()); + } + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + bool World::canTickWorld() const { + //tick + bool needToTick = (frameCount % GameConstants::updateFps == 0); + return needToTick; + } + + void World::tick() { + bool showPerfStats = Config::getInstance().getBool("ShowPerfStats", "false"); + Chrono chronoPerf; + char perfBuf[8096] = ""; + std::vector perfList; + if (showPerfStats) chronoPerf.start(); + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + Chrono chronoGamePerformanceCounts; + if (this->game) chronoGamePerformanceCounts.start(); + + computeFow(); + + if (this->game) this->game->addPerformanceCount("world->computeFow", chronoGamePerformanceCounts.getMillis()); + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER " fogOfWar: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis(), fogOfWar); + perfList.push_back(perfBuf); + } + + if (fogOfWarSmoothing == false) { + if (this->game) chronoGamePerformanceCounts.start(); + + minimap.updateFowTex(1.f); + + if (this->game) this->game->addPerformanceCount("minimap.updateFowTex", chronoGamePerformanceCounts.getMillis()); + } + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + //increase hp + if (this->game) chronoGamePerformanceCounts.start(); + + int factionCount = getFactionCount(); + for (int factionIndex = 0; factionIndex < factionCount; ++factionIndex) { + Faction *faction = getFaction(factionIndex); + int unitCount = faction->getUnitCount(); + + for (int unitIndex = 0; unitIndex < unitCount; ++unitIndex) { + Unit *unit = faction->getUnit(unitIndex); + if (unit == NULL) { + throw megaglest_runtime_error("unit == NULL"); + } + + unit->tick(); + } + } + if (this->game) this->game->addPerformanceCount("world unit->tick()", chronoGamePerformanceCounts.getMillis()); + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + //compute resources balance + if (this->game) chronoGamePerformanceCounts.start(); + + std::map > resourceCostCache; + factionCount = getFactionCount(); + for (int factionIndex = 0; factionIndex < factionCount; ++factionIndex) { + Faction *faction = getFaction(factionIndex); + + //for each resource + for (int resourceTypeIndex = 0; + resourceTypeIndex < techTree->getResourceTypeCount(); ++resourceTypeIndex) { + const ResourceType *rt = techTree->getResourceType(resourceTypeIndex); + + //if consumable + if (rt != NULL && rt->getClass() == rcConsumable) { + + int balance = 0; + for (int unitIndex = 0; + unitIndex < faction->getUnitCount(); ++unitIndex) { + + //if unit operative and has this cost + const Unit *unit = faction->getUnit(unitIndex); + if (unit != NULL && unit->isOperative()) { + + const UnitType *ut = unit->getType(); + const Resource *resource = NULL; + std::map >::iterator iterFind = resourceCostCache.find(ut); + if (iterFind != resourceCostCache.end() && + iterFind->second.find(rt) != iterFind->second.end()) { + + resource = iterFind->second.find(rt)->second; + } else { + resource = ut->getCost(rt); + resourceCostCache[ut][rt] = resource; + } + if (resource != NULL) { + balance -= resource->getAmount(); + } + } + } + faction->setResourceBalance(rt, balance); + } + } + } + if (this->game) this->game->addPerformanceCount("world faction->setResourceBalance()", chronoGamePerformanceCounts.getMillis()); + + if (showPerfStats) { + sprintf(perfBuf, "In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chronoPerf.getMillis()); + perfList.push_back(perfBuf); + } + + if (showPerfStats && chronoPerf.getMillis() >= 50) { + for (unsigned int x = 0; x < perfList.size(); ++x) { + printf("%s", perfList[x].c_str()); + } + } + } + + Unit* World::findUnitById(int id) const { + for (int i = 0; i < getFactionCount(); ++i) { + const Faction* faction = getFaction(i); + Unit* unit = faction->findUnit(id); + if (unit != NULL) { + return unit; + } + } + return NULL; + } + + const UnitType* World::findUnitTypeById(const FactionType* factionType, int id) { + if (factionType == NULL) { + throw megaglest_runtime_error("factionType == NULL"); + } + for (int i = 0; i < factionType->getUnitTypeCount(); ++i) { + const UnitType *unitType = factionType->getUnitType(i); + if (unitType != NULL && unitType->getId() == id) { + return unitType; + } + } + return NULL; + } + + const UnitType * World::findUnitTypeByName(const string factionName, const string unitTypeName) { + const UnitType *unitTypeResult = NULL; + + for (int index = 0; unitTypeResult == NULL && index < getFactionCount(); ++index) { + const Faction *faction = getFaction(index); + if (factionName == "" || factionName == faction->getType()->getName(false)) { + for (int unitIndex = 0; + unitTypeResult == NULL && unitIndex < faction->getType()->getUnitTypeCount(); ++unitIndex) { + + const UnitType *unitType = faction->getType()->getUnitType(unitIndex); + if (unitType != NULL && unitType->getName(false) == unitTypeName) { + unitTypeResult = unitType; + break; + } + } + } + } + return unitTypeResult; + } + + //looks for a place for a unit around a start location, returns true if succeded + bool World::placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spaciated, bool threaded) { + if (unit == NULL) { + throw megaglest_runtime_error("unit == NULL"); + } + + bool freeSpace = false; + int size = unit->getType()->getSize(); + Field currField = unit->getCurrField(); + + for (int r = 1; r < radius; r++) { + for (int i = -r; i < r; ++i) { + for (int j = -r; j < r; ++j) { + Vec2i pos = Vec2i(i, j) + startLoc; + if (spaciated) { + const int spacing = 2; + freeSpace = map.isFreeCells(pos - Vec2i(spacing), size + spacing * 2, currField); + } else { + freeSpace = map.isFreeCells(pos, size, currField); + } + + if (freeSpace) { + unit->setPos(pos, false, threaded); + Vec2i meetingPos = pos - Vec2i(1); + unit->setMeetingPos(meetingPos); + return true; + } + } + } + } + return false; + } + + //clears a unit old position from map and places new position + void World::moveUnitCells(Unit *unit, bool threaded) { + if (unit == NULL) { + throw megaglest_runtime_error("unit == NULL"); + } + + Vec2i newPos = unit->getTargetPos(); + + //newPos must be free or the same pos as current + + // Only change cell placement in map if the new position is different + // from the old one + if (newPos != unit->getPos()) { + map.clearUnitCells(unit, unit->getPos()); + map.putUnitCells(unit, newPos, false, threaded); + } + // Add resources close by to the faction's cache + unit->getFaction()->addCloseResourceTargetToCache(newPos); + + //water splash + if (tileset.getWaterEffects() && unit->getCurrField() == fLand) { + if (map.getSubmerged(map.getCell(unit->getLastPos()))) { + + if (Thread::isCurrentThreadMainThread() == false) { + throw megaglest_runtime_error("#1 Invalid access to World random from outside main thread current id = " + + intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId())); + } + + int unitSize = unit->getType()->getSize(); + for (int i = 0; i < 3; ++i) { + waterEffects.addWaterSplash( + Vec2f(unit->getLastPos().x + (float) unitSize / 2.0f + random.randRange(-0.9f, -0.1f), unit->getLastPos().y + random.randRange(-0.9f, -0.1f) + (float) unitSize / 2.0f), unit->getType()->getSize()); + } + } + } + + if (scriptManager) scriptManager->onCellTriggerEvent(unit); + } + + void World::addAttackEffects(const Unit *unit) { + attackEffects.addWaterSplash( + Vec2f(unit->getPosNotThreadSafe().x, unit->getPosNotThreadSafe().y), 1); + } + + //returns the nearest unit that can store a type of resource given a position and a faction + Unit *World::nearestStore(const Vec2i &pos, int factionIndex, const ResourceType *rt) { + float currDist = infinity; + Unit *currUnit = NULL; + + if (factionIndex >= getFactionCount()) { + throw megaglest_runtime_error("factionIndex >= getFactionCount()"); + } + + for (int i = 0; i < getFaction(factionIndex)->getUnitCount(); ++i) { + Unit *u = getFaction(factionIndex)->getUnit(i); + if (u != NULL) { + float tmpDist = u->getPos().dist(pos); + if (tmpDist < currDist && u->getType() != NULL && u->getType()->getStore(rt) > 0 && u->isOperative()) { + currDist = tmpDist; + currUnit = u; + } + } + } + return currUnit; + } + + bool World::toRenderUnit(const Unit *unit, const Quad2i &visibleQuad) const { + if (unit == NULL) { + throw megaglest_runtime_error("unit == NULL"); + } + + //a unit is rendered if it is in a visible cell or is attacking a unit in a visible cell + return visibleQuad.isInside(unit->getPosNotThreadSafe()) && toRenderUnit(unit); + } + + bool World::toRenderUnit(const Unit *unit) const { + if (unit == NULL) { + throw megaglest_runtime_error("unit == NULL"); + } + + if (showWorldForPlayer(thisFactionIndex) == true) { + return true; + } + + return + (map.getSurfaceCell(Map::toSurfCoords(unit->getCenteredPos()))->isVisible(thisTeamIndex) && + map.getSurfaceCell(Map::toSurfCoords(unit->getCenteredPos()))->isExplored(thisTeamIndex)) || + (unit->getCurrSkill()->getClass() == scAttack && + map.getSurfaceCell(Map::toSurfCoords(unit->getTargetPos()))->isVisible(thisTeamIndex) && + map.getSurfaceCell(Map::toSurfCoords(unit->getTargetPos()))->isExplored(thisTeamIndex)); + } + + bool World::toRenderUnit(const UnitBuildInfo &pendingUnit) const { + if (pendingUnit.unit == NULL) { + throw megaglest_runtime_error("unit == NULL"); + } + + if (showWorldForPlayer(thisFactionIndex) == true) { + return true; + } + if (pendingUnit.unit->getTeam() != thisTeamIndex) { + return false; + } + + return + (map.getSurfaceCell(Map::toSurfCoords(pendingUnit.pos))->isVisible(thisTeamIndex) && + map.getSurfaceCell(Map::toSurfCoords(pendingUnit.pos))->isExplored(thisTeamIndex)); + } + + void World::morphToUnit(int unitId, const string &morphName, bool ignoreRequirements) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d] unit [%d] morphName [%s] forceUpgradesIfRequired = %d\n", __FILE__, __FUNCTION__, __LINE__, unitId, morphName.c_str(), ignoreRequirements); + Unit* unit = findUnitById(unitId); + if (unit != NULL) { + for (int i = 0; i < unit->getType()->getCommandTypeCount(); ++i) { + const CommandType *ct = unit->getType()->getCommandType(i); + const MorphCommandType *mct = dynamic_cast(ct); + if (mct != NULL && mct->getName(false) == morphName) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d] unit [%d] morphName [%s] comparing mct [%s]\n", __FILE__, __FUNCTION__, __LINE__, unitId, morphName.c_str(), mct->getName(false).c_str()); + + std::pair cr(crFailUndefined, ""); + try { + if (unit->getFaction()->reqsOk(mct) == false && ignoreRequirements == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d] unit [%d] morphName [%s] comparing mct [%s] mct->getUpgradeReqCount() = %d\n", __FILE__, __FUNCTION__, __LINE__, unitId, morphName.c_str(), mct->getName(false).c_str(), mct->getUpgradeReqCount()); + unit->setIgnoreCheckCommand(true); + } + + const UnitType* unitType = mct->getMorphUnit(); + cr = this->game->getCommander()->tryGiveCommand(unit, mct, unit->getPos(), unitType, CardinalDir(CardinalDir::NORTH)); + } catch (const exception &ex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + unit->setIgnoreCheckCommand(false); + + throw megaglest_runtime_error(ex.what()); + } + + if (cr.first == crSuccess) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d] unit [%d] morphName [%s] comparing mct [%s] returned = %d\n", __FILE__, __FUNCTION__, __LINE__, unitId, morphName.c_str(), mct->getName(false).c_str(), cr.first); - if((fowst->getApplyToTeam() == true && unit->getTeam() == this->getThisTeamIndex()) || - (fowst->getApplyToTeam() == false && unit->getFactionIndex() == this->getThisFactionIndex())) { - if(fowst->getFowEnable() == true) { - fowEnabled = true; break; } } - } - if((fowEnabled == false && fogOfWarSkillTypeValue != 0) || - (fowEnabled == true && fogOfWarSkillTypeValue != 1)) { - //printf("In [%s::%s Line: %d] current = %d new = %d\n",__FILE__,__FUNCTION__,__LINE__,fogOfWar,fowEnabled); - setFogOfWar(fowEnabled); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); } } - } -} -void World::setFogOfWar(bool value) { - //printf("In [%s::%s Line: %d] current = %d new = %d\n",__FILE__,__FUNCTION__,__LINE__,fogOfWar,value); + void World::createUnit(const string &unitName, int factionIndex, const Vec2i &pos, bool spaciated) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] unitName [%s] factionIndex = %d\n", __FILE__, __FUNCTION__, __LINE__, unitName.c_str(), factionIndex); - if(fogOfWarOverride == false) { - minimap.copyFowTex(); - } + if (factionIndex < (int) factions.size()) { + Faction* faction = factions[factionIndex]; - if(value == true) { - fogOfWarSkillTypeValue = 1; - } - else { - fogOfWarSkillTypeValue = 0; - } + if (faction->getIndex() != factionIndex) { + throw megaglest_runtime_error("faction->getIndex() != factionIndex", true); + } - fogOfWarOverride = true; -} + const FactionType* ft = faction->getType(); + const UnitType* ut = ft->getUnitType(unitName); -void World::clearTileset() { - tileset = Tileset(); -} + UnitPathInterface *newpath = NULL; + switch (game->getGameSettings()->getPathFinderType()) { + case pfBasic: + newpath = new UnitPathBasic(); + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!", true); + } -void World::restoreExploredFogOfWarCells() { - for (int i = 0; i < map.getSurfaceW(); ++i) { - for (int j = 0; j < map.getSurfaceH(); ++j) { - for (int k = 0; k < GameConstants::maxPlayers + GameConstants::specialFactions; ++k) { - if (k == thisTeamIndex) { - if (map.getSurfaceCell(i, j)->isExplored(k) == true) { - const Vec2i pos(i, j); - Vec2i surfPos = pos; - //compute max alpha - float maxAlpha = 0.0f; - if (surfPos.x > 1 && surfPos.y > 1 - && surfPos.x < map.getSurfaceW() - 2 - && surfPos.y < map.getSurfaceH() - 2) { - maxAlpha = 1.f; - } else if (surfPos.x > 0 && surfPos.y > 0 - && surfPos.x < map.getSurfaceW() - 1 - && surfPos.y < map.getSurfaceH() - 1) { - maxAlpha = 0.3f; + Unit* unit = new Unit(getNextUnitId(faction), newpath, pos, ut, faction, &map, CardinalDir(CardinalDir::NORTH)); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] unit created for unit [%s]\n", __FILE__, __FUNCTION__, __LINE__, unit->toString().c_str()); + + if (placeUnit(pos, generationArea, unit, spaciated)) { + unit->create(true); + unit->born(NULL); + if (scriptManager) { + scriptManager->onUnitCreated(unit); + } + if (game->getPaused() == true) { + // new units added in pause mode might change the Fow. ( Scenarios do this ) + computeFow(); + minimap.updateFowTex(1.f); + } + } else { + delete unit; + unit = NULL; + throw megaglest_runtime_error("Unit cant be placed", true); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] unit created for unit [%s]\n", __FILE__, __FUNCTION__, __LINE__, unit->toString().c_str()); + } else { + throw megaglest_runtime_error("Invalid faction index in createUnitAtPosition: " + intToStr(factionIndex), true); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void World::giveResource(const string &resourceName, int factionIndex, int amount) { + if (factionIndex < (int) factions.size()) { + Faction* faction = factions[factionIndex]; + const ResourceType* rt = techTree->getResourceType(resourceName); + faction->incResourceAmount(rt, amount); + } else { + throw megaglest_runtime_error("Invalid faction index in giveResource: " + intToStr(factionIndex), true); + } + } + + int World::getUnitCurrentField(int unitId) { + int field = -1; + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d] unit [%d]\n", __FILE__, __FUNCTION__, __LINE__, unitId); + Unit* unit = findUnitById(unitId); + if (unit != NULL) { + field = unit->getCurrField(); + } + + return field; + } + + bool World::getIsUnitAlive(int unitId) { + bool result = false; + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d] unit [%d]\n", __FILE__, __FUNCTION__, __LINE__, unitId); + Unit* unit = findUnitById(unitId); + if (unit != NULL) { + result = unit->isAlive(); + } + return result; + } + + vector World::getUnitsForFaction(int factionIndex, const string& commandTypeName, int field) { + vector units; + + if (factionIndex < 0 || factionIndex > getFactionCount()) { + throw megaglest_runtime_error("Invalid faction index in getUnitsForFaction: " + intToStr(factionIndex), true); + } + Faction *faction = getFaction(factionIndex); + if (faction != NULL) { + CommandType *commandType = NULL; + if (commandTypeName != "") { + commandType = CommandTypeFactory::getInstance().newInstance(commandTypeName); + } + int unitCount = faction->getUnitCount(); + for (int i = 0; i < unitCount; ++i) { + Unit *unit = faction->getUnit(i); + if (unit != NULL) { + bool addToList = true; + if (commandType != NULL) { + if (commandType->getClass() == ccAttack && field >= 0) { + const AttackCommandType *act = unit->getType()->getFirstAttackCommand(static_cast(field)); + addToList = (act != NULL); + } else if (commandType->getClass() == ccAttackStopped && field >= 0) { + const AttackStoppedCommandType *asct = unit->getType()->getFirstAttackStoppedCommand(static_cast(field)); + addToList = (asct != NULL); + } else { + addToList = unit->getType()->hasCommandClass(commandType->getClass()); + } + } else if (field >= 0) { + addToList = (unit->getCurrField() == static_cast(field)); } - //compute alpha - float alpha = maxAlpha; - minimap.incFowTextureAlphaSurface(surfPos, alpha); + if (addToList == true) { + units.push_back(unit->getId()); + } } } + + delete commandType; + commandType = NULL; + } + return units; + } + + void World::givePositionCommand(int unitId, const string &commandName, const Vec2i &pos) { + Unit* unit = findUnitById(unitId); + if (unit != NULL) { + CommandClass cc; + + if (commandName == "move") { + cc = ccMove; + } else if (commandName == "attack") { + cc = ccAttack; + } else { + throw megaglest_runtime_error("Invalid position command: " + commandName, true); + } + + if (unit->getType()->getFirstCtOfClass(cc) == NULL) { + throw megaglest_runtime_error("Invalid command: [" + commandName + "] for unit: [" + unit->getType()->getName(false) + "] id [" + intToStr(unit->getId()) + "]", true); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] cc = %d Unit [%s]\n", __FILE__, __FUNCTION__, __LINE__, cc, unit->getFullName(false).c_str()); + unit->giveCommand(new Command(unit->getType()->getFirstCtOfClass(cc), pos)); + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } else { + throw megaglest_runtime_error("Invalid unitId index in givePositionCommand: " + intToStr(unitId) + " commandName = " + commandName, true); } } - } -} -void World::init(Game *game, bool createUnits, bool initFactions){ + void World::giveStopCommand(int unitId) { + Unit* unit = findUnitById(unitId); + if (unit != NULL) { + const CommandType *ct = unit->getType()->getFirstCtOfClass(ccStop); + if (ct != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] Unit [%s] will stop\n", __FILE__, __FUNCTION__, __LINE__, unit->getFullName(false).c_str()); + unit->giveCommand(new Command(ct)); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - ExploredCellsLookupItemCache.clear(); - ExploredCellsLookupItemCacheTimer.clear(); - - this->game = game; - scriptManager= game->getScriptManager(); - - GameSettings *gs = game->getGameSettings(); - if(fogOfWarOverride == false) { - fogOfWar = gs->getFogOfWar(); - } - originalGameFogOfWar = fogOfWar; - - if(loadWorldNode != NULL) { - timeFlow.loadGame(loadWorldNode); - } - - if(initFactions == true) { - initFactionTypes(gs); - } - initCells(fogOfWar); //must be done after knowing faction number and dimensions - initMap(); - initSplattedTextures(); - - unitUpdater.init(game); - if(loadWorldNode != NULL) { - unitUpdater.loadGame(loadWorldNode); - } - - //minimap must be init after sum computation - initMinimap(); - - bool gotError = false; - bool skipStackTrace = false; - string sErrBuf = ""; - - try { - if(createUnits) { - initUnits(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } else { + throw megaglest_runtime_error("Invalid ct in giveStopCommand: " + intToStr(unitId), true); + } + } else { + throw megaglest_runtime_error("Invalid unitId index in giveStopCommand: " + intToStr(unitId), true); + } } - } - catch(const megaglest_runtime_error &ex) { - gotError = true; - if(ex.wantStackTrace() == true) { - char szErrBuf[8096]=""; - snprintf(szErrBuf,8096,"In [%s::%s %d]",__FILE__,__FUNCTION__,__LINE__); - sErrBuf = string(szErrBuf) + string("\nerror [") + string(ex.what()) + string("]\n"); + + bool World::selectUnit(int unitId) { + bool result = false; + Unit* unit = findUnitById(unitId); + if (unit != NULL) { + result = game->addUnitToSelection(unit); + } + + return result; } - else { - skipStackTrace = true; - sErrBuf = ex.what(); + + void World::unselectUnit(int unitId) { + Unit* unit = findUnitById(unitId); + if (unit != NULL) { + game->removeUnitFromSelection(unit); + } } - SystemFlags::OutputDebug(SystemFlags::debugError,sErrBuf.c_str()); - } - catch(const std::exception &ex) { - gotError = true; - char szErrBuf[8096]=""; - snprintf(szErrBuf,8096,"In [%s::%s %d]",__FILE__,__FUNCTION__,__LINE__); - sErrBuf = string(szErrBuf) + string("\nerror [") + string(ex.what()) + string("]\n"); - SystemFlags::OutputDebug(SystemFlags::debugError,sErrBuf.c_str()); - } - if(loadWorldNode != NULL) { - map.loadGame(loadWorldNode,this); + void World::addUnitToGroupSelection(int unitId, int groupIndex) { + Unit* unit = findUnitById(unitId); + if (unit != NULL) { + game->addUnitToGroupSelection(unit, groupIndex); + } + } - if(fogOfWar == false) { - for(int i=0; i< map.getSurfaceW(); ++i) { - for(int j=0; j< map.getSurfaceH(); ++j) { + void World::removeUnitFromGroupSelection(int unitId, int groupIndex) { + game->removeUnitFromGroupSelection(unitId, groupIndex); + } - SurfaceCell *sc= map.getSurfaceCell(i, j); - if(sc == NULL) { + void World::recallGroupSelection(int groupIndex) { + game->recallGroupSelection(groupIndex); + } + + void World::setAttackWarningsEnabled(bool enabled) { + this->disableAttackEffects = !enabled; + } + bool World::getAttackWarningsEnabled() { + return (this->disableAttackEffects == false); + } + + void World::giveAttackCommand(int unitId, int unitToAttackId) { + Unit* unit = findUnitById(unitId); + if (unit != NULL) { + Unit* targetUnit = findUnitById(unitToAttackId); + if (targetUnit != NULL) { + const CommandType *ct = unit->getType()->getFirstAttackCommand(targetUnit->getCurrField()); + if (ct != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] Unit [%s] is attacking [%s]\n", __FILE__, __FUNCTION__, __LINE__, unit->getFullName(false).c_str(), targetUnit->getFullName(false).c_str()); + unit->giveCommand(new Command(ct, targetUnit)); + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } else { + throw megaglest_runtime_error("Invalid ct in giveAttackCommand: " + intToStr(unitId) + " unitToAttackId = " + intToStr(unitToAttackId), true); + } + } else { + throw megaglest_runtime_error("Invalid unitToAttackId index in giveAttackCommand: " + intToStr(unitId) + " unitToAttackId = " + intToStr(unitToAttackId), true); + } + } else { + throw megaglest_runtime_error("Invalid unitId index in giveAttackCommand: " + intToStr(unitId) + " unitToAttackId = " + intToStr(unitToAttackId), true); + } + } + + void World::giveProductionCommand(int unitId, const string &producedName) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + Unit *unit = findUnitById(unitId); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + + if (unit != NULL) { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + + const UnitType *ut = unit->getType(); + + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + + //Search for a command that can produce the unit + for (int i = 0; i < ut->getCommandTypeCount(); ++i) { + const CommandType* ct = ut->getCommandType(i); + if (ct != NULL && ct->getClass() == ccProduce) { + const ProduceCommandType *pct = dynamic_cast(ct); + if (pct != NULL && pct->getProducedUnit() != NULL && + pct->getProducedUnit()->getName(false) == producedName) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + unit->giveCommand(new Command(pct)); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } + } + } + } else { + throw megaglest_runtime_error("Invalid unitId index in giveProductionCommand: " + intToStr(unitId) + " producedName = " + producedName, true); + } + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + + void World::giveAttackStoppedCommand(int unitId, const string &itemName, bool ignoreRequirements) { + Unit *unit = findUnitById(unitId); + if (unit != NULL) { + const UnitType *ut = unit->getType(); + + //Search for a command that can produce the unit + for (int i = 0; i < ut->getCommandTypeCount(); ++i) { + const CommandType* ct = ut->getCommandType(i); + if (ct != NULL && ct->getClass() == ccAttackStopped) { + + const AttackStoppedCommandType *act = static_cast(ct); + if (act != NULL && act->getName(false) == itemName) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + try { + if (unit->getFaction()->reqsOk(act) == false && ignoreRequirements == true) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + unit->setIgnoreCheckCommand(true); + } + + unit->giveCommand(new Command(act)); + } catch (const exception &ex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + unit->setIgnoreCheckCommand(false); + + throw megaglest_runtime_error(ex.what()); + } + + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } + } + } + } else { + throw megaglest_runtime_error("Invalid unitId index in giveAttackStoppedCommand: " + intToStr(unitId) + " itemName = " + itemName, true); + } + } + + void World::playStaticSound(const string &playSound) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d] playSound [%s]\n", __FILE__, __FUNCTION__, __LINE__, playSound.c_str()); + + string calculatedFilePath = playSound; + bool changed = Properties::applyTagsToValue(calculatedFilePath); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nPlay static sound changed: %d [%s] [%s]\n\n", changed, playSound.c_str(), calculatedFilePath.c_str()); + + if (staticSoundList.find(calculatedFilePath) == staticSoundList.end()) { + StaticSound *sound = new StaticSound(); + sound->load(calculatedFilePath); + staticSoundList[calculatedFilePath] = sound; + } + StaticSound *playSoundItem = staticSoundList[calculatedFilePath]; + + SoundRenderer &soundRenderer = SoundRenderer::getInstance(); + soundRenderer.playFx(playSoundItem); + } + + void World::playStreamingSound(const string &playSound) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d] playSound [%s]\n", __FILE__, __FUNCTION__, __LINE__, playSound.c_str()); + + string calculatedFilePath = playSound; + bool changed = Properties::applyTagsToValue(calculatedFilePath); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nPlay streaming sound changed: %d [%s] [%s]\n\n", changed, playSound.c_str(), calculatedFilePath.c_str()); + + if (streamSoundList.find(calculatedFilePath) == streamSoundList.end()) { + StrSound *sound = new StrSound(); + sound->open(calculatedFilePath); + sound->setNext(sound); + streamSoundList[calculatedFilePath] = sound; + } + StrSound *playSoundItem = streamSoundList[calculatedFilePath]; + + SoundRenderer &soundRenderer = SoundRenderer::getInstance(); + soundRenderer.playMusic(playSoundItem); + } + + void World::stopStreamingSound(const string &playSound) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d] playSound [%s]\n", __FILE__, __FUNCTION__, __LINE__, playSound.c_str()); + + string calculatedFilePath = playSound; + bool changed = Properties::applyTagsToValue(calculatedFilePath); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nStop streaming sound changed: %d [%s] [%s]\n\n", changed, playSound.c_str(), calculatedFilePath.c_str()); + + if (streamSoundList.find(calculatedFilePath) != streamSoundList.end()) { + StrSound *playSoundItem = streamSoundList[calculatedFilePath]; + SoundRenderer &soundRenderer = SoundRenderer::getInstance(); + soundRenderer.stopMusic(playSoundItem); + } + } + + void World::stopAllSound() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + SoundRenderer &soundRenderer = SoundRenderer::getInstance(); + soundRenderer.stopAllSounds(); + } + + void World::moveToUnit(int unitId, int destUnitId) { + Unit* unit = findUnitById(unitId); + if (unit != NULL) { + CommandClass cc = ccMove; + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] cc = %d Unit [%s]\n", __FILE__, __FUNCTION__, __LINE__, cc, unit->getFullName(false).c_str()); + Unit* destUnit = findUnitById(destUnitId); + if (destUnit != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d] cc = %d Unit [%s] destUnit [%s]\n", __FILE__, __FUNCTION__, __LINE__, cc, unit->getFullName(false).c_str(), destUnit->getFullName(false).c_str()); + unit->giveCommand(new Command(unit->getType()->getFirstCtOfClass(cc), destUnit)); + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + } else { + throw megaglest_runtime_error("Invalid unitId index in followUnit: " + intToStr(unitId), true); + } + } + + void World::clearCaches() { + ExploredCellsLookupItemCache.clear(); + ExploredCellsLookupItemCacheTimer.clear(); + ExploredCellsLookupItemCacheTimerCount = 0; + + unitUpdater.clearCaches(); + } + + void World::togglePauseGame(bool pauseStatus, bool forceAllowPauseStateChange) { + game->setPaused(pauseStatus, forceAllowPauseStateChange, false, false); + // ensures that the Fow is really up to date when the game switches to pause mode. ( mainly for scenarios ) + computeFow(); + minimap.updateFowTex(1.f); + } + + void World::addConsoleText(const string &text) { + game->getConsole()->addStdScenarioMessage(text); + } + void World::addConsoleTextWoLang(const string &text) { + game->getConsole()->addLine(text); + } + + const string World::getSystemMacroValue(const string key) { + std::string result = key; + bool tagApplied = Properties::applyTagsToValue(result); + if (tagApplied == false) { + result = ""; + + if (key == "$SCENARIO_PATH") { + result = extractDirectoryPathFromFile(game->getGameSettings()->getScenarioDir()); + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("system macro key [%s] returning [%s]\n", key.c_str(), result.c_str()); + + return result; + } + + const string World::getPlayerName(int factionIndex) { + return game->getGameSettings()->getNetworkPlayerName(factionIndex); + } + + void World::giveUpgradeCommand(int unitId, const string &upgradeName) { + Unit *unit = findUnitById(unitId); + if (unit != NULL) { + const UnitType *ut = unit->getType(); + + //Search for a command that can produce the unit + for (int i = 0; i < ut->getCommandTypeCount(); ++i) { + const CommandType* ct = ut->getCommandType(i); + if (ct != NULL && ct->getClass() == ccUpgrade) { + const UpgradeCommandType *uct = static_cast(ct); + if (uct != NULL && uct->getProducedUpgrade()->getName() == upgradeName) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + unit->giveCommand(new Command(uct)); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } + } + } + } else { + throw megaglest_runtime_error("Invalid unitId index in giveUpgradeCommand: " + intToStr(unitId) + " upgradeName = " + upgradeName, true); + } + } + + + int World::getResourceAmount(const string &resourceName, int factionIndex) { + if (factionIndex < (int) factions.size()) { + Faction* faction = factions[factionIndex]; + const ResourceType* rt = techTree->getResourceType(resourceName); + return faction->getResource(rt)->getAmount(); + } else { + throw megaglest_runtime_error("Invalid faction index in giveResource: " + intToStr(factionIndex) + " resourceName = " + resourceName, true); + } + } + + Vec2i World::getStartLocation(int factionIndex) { + if (factionIndex < (int) factions.size()) { + Faction* faction = factions[factionIndex]; + return map.getStartLocation(faction->getStartLocationIndex()); + } else { + printf("\n=================================================\n%s\n", game->getGameSettings()->toString().c_str()); + + throw megaglest_runtime_error("Invalid faction index in getStartLocation: " + intToStr(factionIndex) + " : " + intToStr(factions.size()), true); + } + } + + Vec2i World::getUnitPosition(int unitId) { + Unit* unit = findUnitById(unitId); + if (unit == NULL) { + throw megaglest_runtime_error("Can not find unit to get position unitId = " + intToStr(unitId), true); + } + return unit->getPos(); + } + + void World::setUnitPosition(int unitId, Vec2i pos) { + Unit* unit = findUnitById(unitId); + if (unit == NULL) { + throw megaglest_runtime_error("Can not find unit to set position unitId = " + intToStr(unitId), true); + } + unit->setTargetPos(pos); + this->moveUnitCells(unit, false); + } + + void World::addCellMarker(Vec2i pos, int factionIndex, const string ¬e, const string textureFile) { + const Faction *faction = NULL; + if (factionIndex >= 0) { + faction = this->getFaction(factionIndex); + } + + Vec2i surfaceCellPos = map.toSurfCoords(pos); + SurfaceCell *sc = map.getSurfaceCell(surfaceCellPos); + if (sc == NULL) { + throw megaglest_runtime_error("sc == NULL", true); + } + Vec3f vertex = sc->getVertex(); + Vec2i targetPos(vertex.x, vertex.z); + + //printf("pos [%s] scPos [%s][%p] targetPos [%s]\n",pos.getString().c_str(),surfaceCellPos.getString().c_str(),sc,targetPos.getString().c_str()); + + MarkedCell mc(targetPos, faction, note, (faction != NULL ? faction->getStartLocationIndex() : -1)); + game->addCellMarker(surfaceCellPos, mc); + } + + void World::removeCellMarker(Vec2i pos, int factionIndex) { + const Faction *faction = NULL; + if (factionIndex >= 0) { + faction = this->getFaction(factionIndex); + } + + Vec2i surfaceCellPos = map.toSurfCoords(pos); + + game->removeCellMarker(surfaceCellPos, faction); + } + + void World::showMarker(Vec2i pos, int factionIndex, const string ¬e, const string textureFile, int flashCount) { + const Faction *faction = NULL; + if (factionIndex >= 0) { + faction = this->getFaction(factionIndex); + } + + Vec2i surfaceCellPos = map.toSurfCoords(pos); + SurfaceCell *sc = map.getSurfaceCell(surfaceCellPos); + if (sc == NULL) { + throw megaglest_runtime_error("sc == NULL", true); + } + Vec3f vertex = sc->getVertex(); + Vec2i targetPos(vertex.x, vertex.z); + + //printf("pos [%s] scPos [%s][%p] targetPos [%s]\n",pos.getString().c_str(),surfaceCellPos.getString().c_str(),sc,targetPos.getString().c_str()); + + MarkedCell mc(targetPos, faction, note, (faction != NULL ? faction->getStartLocationIndex() : -1)); + if (flashCount > 0) { + mc.setAliveCount(flashCount); + } + game->showMarker(surfaceCellPos, mc); + } + + void World::highlightUnit(int unitId, float radius, float thickness, Vec4f color) { + Unit* unit = findUnitById(unitId); + if (unit == NULL) { + throw megaglest_runtime_error("Can not find unit to set highlight unitId = " + intToStr(unitId), true); + } + game->highlightUnit(unitId, radius, thickness, color); + } + + void World::unhighlightUnit(int unitId) { + Unit* unit = findUnitById(unitId); + if (unit == NULL) { + throw megaglest_runtime_error("Can not find unit to set highlight unitId = " + intToStr(unitId), true); + } + game->unhighlightUnit(unitId); + } + + + int World::getUnitFactionIndex(int unitId) { + Unit* unit = findUnitById(unitId); + if (unit == NULL) { + throw megaglest_runtime_error("Can not find Faction unit to get position unitId = " + intToStr(unitId), true); + } + return unit->getFactionIndex(); + } + const string World::getUnitName(int unitId) { + Unit* unit = findUnitById(unitId); + if (unit == NULL) { + throw megaglest_runtime_error("Can not find Faction unit to get position unitId = " + intToStr(unitId), true); + } + return unit->getFullName(game->showTranslatedTechTree()); + } + + int World::getUnitCount(int factionIndex) { + if (factionIndex < (int) factions.size()) { + Faction* faction = factions[factionIndex]; + int count = 0; + + for (int i = 0; i < faction->getUnitCount(); ++i) { + const Unit* unit = faction->getUnit(i); + if (unit != NULL && unit->isAlive()) { + ++count; + } + } + return count; + } else { + throw megaglest_runtime_error("Invalid faction index in getUnitCount: " + intToStr(factionIndex), true); + } + } + + int World::getUnitCountOfType(int factionIndex, const string &typeName) { + if (factionIndex < (int) factions.size()) { + Faction* faction = factions[factionIndex]; + int count = 0; + + for (int i = 0; i < faction->getUnitCount(); ++i) { + const Unit* unit = faction->getUnit(i); + if (unit != NULL && unit->isAlive() && unit->getType()->getName(false) == typeName) { + ++count; + } + } + return count; + } else { + throw megaglest_runtime_error("Invalid faction index in getUnitCountOfType: " + intToStr(factionIndex), true); + } + } + + // ==================== PRIVATE ==================== + + // ==================== private init ==================== + + //init basic cell state + void World::initCells(bool fogOfWar) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameLoadingStateCells", "", true), true); + for (int i = 0; i < map.getSurfaceW(); ++i) { + for (int j = 0; j < map.getSurfaceH(); ++j) { + + SurfaceCell *sc = map.getSurfaceCell(i, j); + if (sc == NULL) { throw megaglest_runtime_error("sc == NULL"); } + if (sc->getObject() != NULL) { + sc->getObject()->initParticles(); + } + sc->setFowTexCoord(Vec2f( + i / (next2Power(map.getSurfaceW()) - 1.f), + j / (next2Power(map.getSurfaceH()) - 1.f))); for (int k = 0; k < GameConstants::maxPlayers; k++) { - //sc->setExplored(k, (game->getGameSettings()->getFlagTypes1() & ft1_show_map_resources) == ft1_show_map_resources); + sc->setExplored(k, (game->getGameSettings()->getFlagTypes1() & ft1_show_map_resources) == ft1_show_map_resources); sc->setVisible(k, !fogOfWar); } + for (int k = GameConstants::maxPlayers; k < GameConstants::maxPlayers + GameConstants::specialFactions; k++) { sc->setExplored(k, true); sc->setVisible(k, true); } - } - } - } - else { - restoreExploredFogOfWarCells(); - } - //minimap.loadGame(loadWorldNode); - } - - //initExplorationState(); ... was only for !fog-of-war, now handled in initCells() - computeFow(); - if(getFrameCount()>1){ - // this is needed for games that are loaded to "switch the light on". - // otherwise the FowTexture is completely black like in the beginning of a game. - minimap.updateFowTex(1.f); - } - - if(gotError == true) { - throw megaglest_runtime_error(sErrBuf,!skipStackTrace); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -//load tileset -Checksum World::loadTileset(const vector pathList, const string &tilesetName, - Checksum* checksum, std::map > > &loadedFileList) { - Checksum tilsetChecksum; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - tilsetChecksum = tileset.loadTileset(pathList, tilesetName, checksum, loadedFileList); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - timeFlow.init(&tileset); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - return tilsetChecksum; -} - -Checksum World::loadTileset(const string &dir, Checksum *checksum, std::map > > &loadedFileList) { - Checksum tilesetChecksum; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - tileset.load(dir, checksum, &tilesetChecksum, loadedFileList); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - timeFlow.init(&tileset); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - return tilesetChecksum; -} - -//load tech -Checksum World::loadTech(const vector pathList, const string &techName, - set &factions, Checksum *checksum, - std::map > > &loadedFileList, - bool validationMode) { - Checksum techtreeChecksum; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - techTree = new TechTree(pathList); - techtreeChecksum = techTree->loadTech( techName, factions, - checksum,loadedFileList,validationMode); - return techtreeChecksum; -} - -std::vector World::validateFactionTypes() { - return techTree->validateFactionTypes(); -} - -std::vector World::validateResourceTypes() { - return techTree->validateResourceTypes(); -} - -//load map -Checksum World::loadMap(const string &path, Checksum *checksum) { - Checksum mapChecksum; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - checksum->addFile(path); - mapChecksum = map.load(path, techTree, &tileset); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - return mapChecksum; -} - -//load map -Checksum World::loadScenario(const string &path, Checksum *checksum, bool resetCurrentScenario, const XmlNode *rootNode) { - //printf("[%s:%s] Line: %d path [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str()); - - Checksum scenarioChecksum; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - checksum->addFile(path); - - //printf("[%s:%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); - - if(resetCurrentScenario == true) { - scenario = Scenario(); - if(scriptManager) scriptManager->init(this, this->getGame()->getGameCameraPtr(),rootNode); - } - - scenarioChecksum = scenario.load(path); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - return scenarioChecksum; -} - -// ==================== misc ==================== - -void World::setQueuedScenario(string scenarioName,bool keepFactions) { - queuedScenarioName = scenarioName; - queuedScenarioKeepFactions = keepFactions; -} - -void World::updateAllTilesetObjects() { - Gui *gui = this->game->getGuiPtr(); - if(gui != NULL) { - Object *selObj = gui->getHighlightedResourceObject(); - if(selObj != NULL) { - selObj->updateHighlight(); - } - } - - if(animatedTilesetObjectPosListLoaded == false) { - animatedTilesetObjectPosListLoaded = true; - animatedTilesetObjectPosList.clear(); - - for(int x = 0; x < map.getSurfaceW(); ++x) { - for(int y = 0; y < map.getSurfaceH(); ++y) { - SurfaceCell *sc = map.getSurfaceCell(x,y); - if(sc != NULL) { - Object *obj = sc->getObject(); - if(obj != NULL && obj->isAnimated() == true) { - //obj->update(); - animatedTilesetObjectPosList.push_back(Vec2i(x,y)); - } - } - } - } - } - if(animatedTilesetObjectPosList.empty() == false) { - for(unsigned int i = 0; i < animatedTilesetObjectPosList.size(); ++i) { - const Vec2i &pos = animatedTilesetObjectPosList[i]; - SurfaceCell *sc = map.getSurfaceCell(pos); - if(sc != NULL) { - Object *obj = sc->getObject(); - if(obj != NULL && obj->isAnimated() == true) { - obj->update(); - } - } - } - } - -// for(int x = 0; x < map.getSurfaceW(); ++x) { -// for(int y = 0; y < map.getSurfaceH(); ++y) { -// SurfaceCell *sc = map.getSurfaceCell(x,y); -// if(sc != NULL) { -// Object *obj = sc->getObject(); -// if(obj != NULL) { -// obj->update(); -// } -// } -// } -// } -} - -void World::updateAllFactionUnits() { - bool showPerfStats = Config::getInstance().getBool("ShowPerfStats","false"); - Chrono chronoPerf; - if(showPerfStats) chronoPerf.start(); - char perfBuf[8096]=""; - std::vector perfList; - - if(scriptManager) scriptManager->onTimerTriggerEvent(); - - // Prioritize grouped command units so closest units to target go first - // units - int factionCount = getFactionCount(); - //printf("===== STARTING Frame: %d\n",frameCount); -// Config &config= Config::getInstance(); -// bool sortedUnitsAllowed = config.getBool("AllowGroupedUnitCommands","true"); -// -// int factionCount = getFactionCount(); -// if(sortedUnitsAllowed == true) { -// for(int i = 0; i < factionCount; ++i) { -// Faction *faction = getFaction(i); -// if(faction == NULL) { -// throw megaglest_runtime_error("faction == NULL"); -// } -// -// // Sort units by command groups -// faction->sortUnitsByCommandGroups(); -// } -// } - - // Clear pathfinder list restrictions - for(int i = 0; i < factionCount; ++i) { - Faction *faction = getFaction(i); - faction->clearUnitsPathfinding(); - faction->clearWorldSynchThreadedLogList(); - } - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - Chrono chrono; - chrono.start(); - - const bool newThreadManager = Config::getInstance().getBool("EnableNewThreadManager","false"); - if(newThreadManager == true) { - masterController.signalSlaves(&frameCount); - bool slavesCompleted = masterController.waitTillSlavesTrigger(20000); - - if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 10) printf("In [%s::%s Line: %d] *** Faction thread preprocessing took [%lld] msecs for %d factions for frameCount = %d slavesCompleted = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),factionCount,frameCount,slavesCompleted); - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - } - else { - // Signal the faction threads to do any pre-processing - for(int i = 0; i < factionCount; ++i) { - Faction *faction = getFaction(i); - faction->signalWorkerThread(frameCount); - } - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - Chrono chrono; - chrono.start(); - - const int MAX_FACTION_THREAD_WAIT_MILLISECONDS = 20000; - for(;chrono.getMillis() < MAX_FACTION_THREAD_WAIT_MILLISECONDS;) { - bool workThreadsFinished = true; - for(int i = 0; i < factionCount; ++i) { - Faction *faction = getFaction(i); - if(faction->isWorkerThreadSignalCompleted(frameCount) == false) { - workThreadsFinished = false; - break; - } - } - if(workThreadsFinished == true) { - break; - } - // WARNING... Sleep in here causes the server to lag a bit - //if(chrono.getMillis() % 5 == 0) { - // sleep(0); - //} - } - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 10) printf("In [%s::%s Line: %d] *** Faction thread preprocessing took [%lld] msecs for %d factions for frameCount = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),factionCount,frameCount); - } - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - //units - Chrono chronoPerfUnit; - int totalUnitsChecked = 0; - int totalUnitsProcessed = 0; - for(int i = 0; i < factionCount; ++i) { - Faction *faction = getFaction(i); - - faction->dumpWorldSynchThreadedLogList(); - faction->clearUnitsPathfinding(); - - std::map mapCommandCount; - std::map mapSkillCount; - int unitCountStuck = 0; - int unitCountUpdated = 0; - - int unitCount = faction->getUnitCount(); - for(int j = 0; j < unitCount; ++j) { - Unit *unit = faction->getUnit(j); - if(unit == NULL) { - throw megaglest_runtime_error("unit == NULL"); - } - - CommandClass unitCommandClass = ccCount; - if(unit->getCurrCommand() != NULL) { - unitCommandClass = unit->getCurrCommand()->getCommandType()->getClass(); - } - - SkillClass unitSkillClass = scCount; - if(unit->getCurrSkill() != NULL) { - unitSkillClass = unit->getCurrSkill()->getClass(); - } - - if(showPerfStats) chronoPerfUnit.start(); - - int unitBlockCount = unit->getPath()->getBlockCount(); - bool isStuck = unit->getPath()->isStuck(); - //bool isStuckWithinTolerance = unit->isLastStuckFrameWithinCurrentFrameTolerance(false); - //uint32 lastStuckFrame = unit->getLastStuckFrame(); - - if(unitUpdater.updateUnit(unit) == true) { - unitCountUpdated++; - - if(unit->getLastStuckFrame() == (unsigned int)frameCount) { - unitCountStuck++; - } - mapCommandCount[unitCommandClass] = mapCommandCount[unitCommandClass] + 1; - mapSkillCount[unitSkillClass] = mapSkillCount[unitSkillClass] + 1; - } - totalUnitsChecked++; - - if(showPerfStats && chronoPerfUnit.getMillis() >= 10) { - //sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER " stuck: %d [%d] for unit:\n%sBEFORE unitBlockCount = %d, AFTER = %d, BEFORE lastStuckFrame = %u, AFTER: %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerfUnit.getMillis(),isStuck,isStuckWithinTolerance,unit->toString().c_str(),unitBlockCount,unit->getPath()->getBlockCount(),lastStuckFrame,unit->getLastStuckFrame()); - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER " stuck: %d for unit:\n%sBEFORE unitBlockCount = %d, AFTER = %d, BEFORE , AFTER: %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerfUnit.getMillis(),isStuck,unit->toString().c_str(),unitBlockCount,unit->getPath()->getBlockCount(),unit->getLastStuckFrame()); - perfList.push_back(perfBuf); - } - - } - totalUnitsProcessed += unitCountUpdated; - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER " faction: %d / %d unitCount = %d unitCountUpdated = %d unitCountStuck = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis(),i+1,factionCount,unitCount,unitCountUpdated,unitCountStuck); - perfList.push_back(perfBuf); - - for(std::map::iterator iterMap = mapCommandCount.begin(); - iterMap != mapCommandCount.end(); ++iterMap) { - - sprintf(perfBuf,"Command class = %d, count = %d\n",iterMap->first,iterMap->second); - perfList.push_back(perfBuf); - } - - for(std::map::iterator iterMap = mapSkillCount.begin(); - iterMap != mapSkillCount.end(); ++iterMap) { - - sprintf(perfBuf,"Skill class = %d, count = %d\n",iterMap->first,iterMap->second); - perfList.push_back(perfBuf); - } - } - } - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER " totalUnitsProcessed = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis(),totalUnitsProcessed); - perfList.push_back(perfBuf); - } - - if(showPerfStats && chronoPerf.getMillis() >= 50) { - for(unsigned int x = 0; x < perfList.size(); ++x) { - printf("%s",perfList[x].c_str()); - } - } - - if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 20) printf("In [%s::%s Line: %d] *** Faction MAIN thread processing took [%lld] msecs for %d factions for frameCount = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),factionCount,frameCount); -} - -void World::underTakeDeadFactionUnits() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - int factionCount = getFactionCount(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] factionCount = %d\n",__FILE__,__FUNCTION__,__LINE__,factionCount); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //undertake the dead - for(int i = 0; i< factionCount; ++i) { - Faction *faction = getFaction(i); - int unitCount = faction->getUnitCount(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] i = %d, unitCount = %d\n",__FILE__,__FUNCTION__,__LINE__,i,unitCount); - - for(int j= unitCount - 1; j >= 0; j--) { - Unit *unit= faction->getUnit(j); - - if(unit == NULL) { - throw megaglest_runtime_error("unit == NULL"); - } - - if(unit->getToBeUndertaken() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - unit->undertake(); - delete unit; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - } - - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void World::updateAllFactionConsumableCosts() { - //food costs - int resourceTypeCount = techTree->getResourceTypeCount(); - int factionCount = getFactionCount(); - for(int i = 0; i < resourceTypeCount; ++i) { - const ResourceType *rt = techTree->getResourceType(i); - if(rt != NULL && rt->getClass() == rcConsumable && frameCount % (rt->getInterval() * GameConstants::updateFps) == 0) { - for(int j = 0; j < factionCount; ++j) { - Faction *faction = getFaction(j); - if(faction == NULL) { - throw megaglest_runtime_error("faction == NULL"); - } - - faction->applyCostsOnInterval(rt); - } - } - } -} - -void World::update() { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - bool showPerfStats = Config::getInstance().getBool("ShowPerfStats","false"); - Chrono chronoPerf; - char perfBuf[8096]=""; - std::vector perfList; - if(showPerfStats) chronoPerf.start(); - - Chrono chronoGamePerformanceCounts; - - ++frameCount; - - //time - timeFlow.update(); - if(scriptManager) scriptManager->onDayNightTriggerEvent(); - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - //water effects - waterEffects.update(1.0f); - // attack effects - attackEffects.update(0.25f); - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - // objects on the map from tilesets - if(this->game) chronoGamePerformanceCounts.start(); - - updateAllTilesetObjects(); - - if(this->game) this->game->addPerformanceCount("updateAllTilesetObjects",chronoGamePerformanceCounts.getMillis()); - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - //units - if(getFactionCount() > 0) { - if(this->game) chronoGamePerformanceCounts.start(); - - updateAllFactionUnits(); - - if(this->game) this->game->addPerformanceCount("updateAllFactionUnits",chronoGamePerformanceCounts.getMillis()); - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - //undertake the dead - if(this->game) chronoGamePerformanceCounts.start(); - - underTakeDeadFactionUnits(); - - if(this->game) this->game->addPerformanceCount("underTakeDeadFactionUnits",chronoGamePerformanceCounts.getMillis()); - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //food costs - if(this->game) chronoGamePerformanceCounts.start(); - - updateAllFactionConsumableCosts(); - - if(this->game) this->game->addPerformanceCount("updateAllFactionConsumableCosts",chronoGamePerformanceCounts.getMillis()); - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //fow smoothing - if(fogOfWarSmoothing && ((frameCount+1) % (fogOfWarSmoothingFrameSkip+1)) == 0) { - if(this->game) chronoGamePerformanceCounts.start(); - - float fogFactor= static_cast(frameCount % GameConstants::updateFps) / GameConstants::updateFps; - minimap.updateFowTex(clamp(fogFactor, 0.f, 1.f)); - - if(this->game) this->game->addPerformanceCount("minimap.updateFowTex",chronoGamePerformanceCounts.getMillis()); - } - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //tick - bool needToTick = canTickWorld(); - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - if(needToTick == true) { - //printf("=========== World is about to be updated, current frameCount = %d\n",frameCount); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(this->game) chronoGamePerformanceCounts.start(); - - tick(); - - if(this->game) this->game->addPerformanceCount("world->tick",chronoGamePerformanceCounts.getMillis()); - } - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - } - - if(showPerfStats && chronoPerf.getMillis() >= 50) { - for(unsigned int x = 0; x < perfList.size(); ++x) { - printf("%s",perfList[x].c_str()); - } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -bool World::canTickWorld() const { - //tick - bool needToTick = (frameCount % GameConstants::updateFps == 0); - return needToTick; -} - -void World::tick() { - bool showPerfStats = Config::getInstance().getBool("ShowPerfStats","false"); - Chrono chronoPerf; - char perfBuf[8096]=""; - std::vector perfList; - if(showPerfStats) chronoPerf.start(); - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - Chrono chronoGamePerformanceCounts; - if(this->game) chronoGamePerformanceCounts.start(); - - computeFow(); - - if(this->game) this->game->addPerformanceCount("world->computeFow",chronoGamePerformanceCounts.getMillis()); - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER " fogOfWar: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis(),fogOfWar); - perfList.push_back(perfBuf); - } - - if(fogOfWarSmoothing == false) { - if(this->game) chronoGamePerformanceCounts.start(); - - minimap.updateFowTex(1.f); - - if(this->game) this->game->addPerformanceCount("minimap.updateFowTex",chronoGamePerformanceCounts.getMillis()); - } - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - //increase hp - if(this->game) chronoGamePerformanceCounts.start(); - - int factionCount = getFactionCount(); - for(int factionIndex = 0; factionIndex < factionCount; ++factionIndex) { - Faction *faction = getFaction(factionIndex); - int unitCount = faction->getUnitCount(); - - for(int unitIndex = 0; unitIndex < unitCount; ++unitIndex) { - Unit *unit = faction->getUnit(unitIndex); - if(unit == NULL) { - throw megaglest_runtime_error("unit == NULL"); - } - - unit->tick(); - } - } - if(this->game) this->game->addPerformanceCount("world unit->tick()",chronoGamePerformanceCounts.getMillis()); - - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } - - //compute resources balance - if(this->game) chronoGamePerformanceCounts.start(); - - std::map > resourceCostCache; - factionCount = getFactionCount(); - for(int factionIndex = 0; factionIndex < factionCount; ++factionIndex) { - Faction *faction = getFaction(factionIndex); - - //for each resource - for(int resourceTypeIndex = 0; - resourceTypeIndex < techTree->getResourceTypeCount(); ++resourceTypeIndex) { - const ResourceType *rt= techTree->getResourceType(resourceTypeIndex); - - //if consumable - if(rt != NULL && rt->getClass() == rcConsumable) { - - int balance= 0; - for(int unitIndex = 0; - unitIndex < faction->getUnitCount(); ++unitIndex) { - - //if unit operative and has this cost - const Unit *unit = faction->getUnit(unitIndex); - if(unit != NULL && unit->isOperative()) { - - const UnitType *ut = unit->getType(); - const Resource *resource = NULL; - std::map >::iterator iterFind = resourceCostCache.find(ut); - if(iterFind != resourceCostCache.end() && - iterFind->second.find(rt) != iterFind->second.end()) { - - resource = iterFind->second.find(rt)->second; - } - else { - resource = ut->getCost(rt); - resourceCostCache[ut][rt] = resource; - } - if(resource != NULL) { - balance -= resource->getAmount(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In initCells() x = %d y = %d %s %s", i, j, sc->isVisibleString().c_str(), sc->isExploredString().c_str()); + if (Thread::isCurrentThreadMainThread()) { + //unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); + SystemFlags::OutputDebug(SystemFlags::debugWorldSynch, szBuf); } } } - faction->setResourceBalance(rt, balance); } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); } - } - if(this->game) this->game->addPerformanceCount("world faction->setResourceBalance()",chronoGamePerformanceCounts.getMillis()); - if(showPerfStats) { - sprintf(perfBuf,"In [%s::%s] Line: %d took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chronoPerf.getMillis()); - perfList.push_back(perfBuf); - } + //init surface textures + void World::initSplattedTextures() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + for (int i = 0; i < map.getSurfaceW() - 1; ++i) { + for (int j = 0; j < map.getSurfaceH() - 1; ++j) { + Vec2f coord; + const Texture2D *texture = NULL; + SurfaceCell *sc00 = map.getSurfaceCell(i, j); + SurfaceCell *sc10 = map.getSurfaceCell(i + 1, j); + SurfaceCell *sc01 = map.getSurfaceCell(i, j + 1); + SurfaceCell *sc11 = map.getSurfaceCell(i + 1, j + 1); - if(showPerfStats && chronoPerf.getMillis() >= 50) { - for(unsigned int x = 0; x < perfList.size(); ++x) { - printf("%s",perfList[x].c_str()); - } - } -} - -Unit* World::findUnitById(int id) const { - for(int i= 0; ifindUnit(id); - if(unit != NULL) { - return unit; - } - } - return NULL; -} - -const UnitType* World::findUnitTypeById(const FactionType* factionType, int id) { - if(factionType == NULL) { - throw megaglest_runtime_error("factionType == NULL"); - } - for(int i= 0; i < factionType->getUnitTypeCount(); ++i) { - const UnitType *unitType = factionType->getUnitType(i); - if(unitType != NULL && unitType->getId() == id) { - return unitType; - } - } - return NULL; -} - -const UnitType * World::findUnitTypeByName(const string factionName, const string unitTypeName) { - const UnitType *unitTypeResult = NULL; - - for(int index = 0; unitTypeResult == NULL && index < getFactionCount(); ++index) { - const Faction *faction = getFaction(index); - if(factionName == "" || factionName == faction->getType()->getName(false)) { - for(int unitIndex = 0; - unitTypeResult == NULL && unitIndex < faction->getType()->getUnitTypeCount(); ++unitIndex) { - - const UnitType *unitType = faction->getType()->getUnitType(unitIndex); - if(unitType != NULL && unitType->getName(false) == unitTypeName) { - unitTypeResult = unitType; - break; - } - } - } - } - return unitTypeResult; -} - -//looks for a place for a unit around a start location, returns true if succeded -bool World::placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spaciated, bool threaded) { - if(unit == NULL) { - throw megaglest_runtime_error("unit == NULL"); - } - - bool freeSpace=false; - int size= unit->getType()->getSize(); - Field currField= unit->getCurrField(); - - for(int r = 1; r < radius; r++) { - for(int i = -r; i < r; ++i) { - for(int j = -r; j < r; ++j) { - Vec2i pos= Vec2i(i,j) + startLoc; - if(spaciated) { - const int spacing = 2; - freeSpace= map.isFreeCells(pos-Vec2i(spacing), size+spacing*2, currField); - } - else { - freeSpace= map.isFreeCells(pos, size, currField); - } - - if(freeSpace) { - unit->setPos(pos, false, threaded); - Vec2i meetingPos = pos-Vec2i(1); - unit->setMeetingPos(meetingPos); - return true; - } - } - } - } - return false; -} - -//clears a unit old position from map and places new position -void World::moveUnitCells(Unit *unit, bool threaded) { - if(unit == NULL) { - throw megaglest_runtime_error("unit == NULL"); - } - - Vec2i newPos= unit->getTargetPos(); - - //newPos must be free or the same pos as current - - // Only change cell placement in map if the new position is different - // from the old one - if(newPos != unit->getPos()) { - map.clearUnitCells(unit, unit->getPos()); - map.putUnitCells(unit, newPos, false, threaded); - } - // Add resources close by to the faction's cache - unit->getFaction()->addCloseResourceTargetToCache(newPos); - - //water splash - if(tileset.getWaterEffects() && unit->getCurrField() == fLand) { - if(map.getSubmerged(map.getCell(unit->getLastPos()))) { - - if(Thread::isCurrentThreadMainThread() == false) { - throw megaglest_runtime_error("#1 Invalid access to World random from outside main thread current id = " + - intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId())); - } - - int unitSize= unit->getType()->getSize(); - for(int i = 0; i < 3; ++i) { - waterEffects.addWaterSplash( - Vec2f(unit->getLastPos().x+(float)unitSize/2.0f+random.randRange(-0.9f, -0.1f), unit->getLastPos().y+random.randRange(-0.9f, -0.1f)+(float)unitSize/2.0f), unit->getType()->getSize()); - } - } - } - - if(scriptManager) scriptManager->onCellTriggerEvent(unit); -} - -void World::addAttackEffects(const Unit *unit) { - attackEffects.addWaterSplash( - Vec2f(unit->getPosNotThreadSafe().x, unit->getPosNotThreadSafe().y),1); -} - -//returns the nearest unit that can store a type of resource given a position and a faction -Unit *World::nearestStore(const Vec2i &pos, int factionIndex, const ResourceType *rt) { - float currDist = infinity; - Unit *currUnit= NULL; - - if(factionIndex >= getFactionCount()) { - throw megaglest_runtime_error("factionIndex >= getFactionCount()"); - } - - for(int i=0; i < getFaction(factionIndex)->getUnitCount(); ++i) { - Unit *u= getFaction(factionIndex)->getUnit(i); - if(u != NULL) { - float tmpDist= u->getPos().dist(pos); - if(tmpDist < currDist && u->getType() != NULL && u->getType()->getStore(rt) > 0 && u->isOperative()) { - currDist= tmpDist; - currUnit= u; - } - } - } - return currUnit; -} - -bool World::toRenderUnit(const Unit *unit, const Quad2i &visibleQuad) const { - if(unit == NULL) { - throw megaglest_runtime_error("unit == NULL"); - } - - //a unit is rendered if it is in a visible cell or is attacking a unit in a visible cell - return visibleQuad.isInside(unit->getPosNotThreadSafe()) && toRenderUnit(unit); -} - -bool World::toRenderUnit(const Unit *unit) const { - if(unit == NULL) { - throw megaglest_runtime_error("unit == NULL"); - } - - if(showWorldForPlayer(thisFactionIndex) == true) { - return true; - } - - return - (map.getSurfaceCell(Map::toSurfCoords(unit->getCenteredPos()))->isVisible(thisTeamIndex) && - map.getSurfaceCell(Map::toSurfCoords(unit->getCenteredPos()))->isExplored(thisTeamIndex) ) || - (unit->getCurrSkill()->getClass()==scAttack && - map.getSurfaceCell(Map::toSurfCoords(unit->getTargetPos()))->isVisible(thisTeamIndex) && - map.getSurfaceCell(Map::toSurfCoords(unit->getTargetPos()))->isExplored(thisTeamIndex)); -} - -bool World::toRenderUnit(const UnitBuildInfo &pendingUnit) const { - if(pendingUnit.unit == NULL) { - throw megaglest_runtime_error("unit == NULL"); - } - - if(showWorldForPlayer(thisFactionIndex) == true) { - return true; - } - if(pendingUnit.unit->getTeam() != thisTeamIndex) { - return false; - } - - return - (map.getSurfaceCell(Map::toSurfCoords(pendingUnit.pos))->isVisible(thisTeamIndex) && - map.getSurfaceCell(Map::toSurfCoords(pendingUnit.pos))->isExplored(thisTeamIndex) ); -} - -void World::morphToUnit(int unitId,const string &morphName,bool ignoreRequirements) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] unit [%d] morphName [%s] forceUpgradesIfRequired = %d\n",__FILE__,__FUNCTION__,__LINE__,unitId,morphName.c_str(),ignoreRequirements); - Unit* unit= findUnitById(unitId); - if(unit != NULL) { - for(int i = 0; i < unit->getType()->getCommandTypeCount(); ++i) { - const CommandType *ct = unit->getType()->getCommandType(i); - const MorphCommandType *mct = dynamic_cast(ct); - if(mct != NULL && mct->getName(false) == morphName) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] unit [%d] morphName [%s] comparing mct [%s]\n",__FILE__,__FUNCTION__,__LINE__,unitId,morphName.c_str(),mct->getName(false).c_str()); - - std::pair cr(crFailUndefined,""); - try { - if(unit->getFaction()->reqsOk(mct) == false && ignoreRequirements == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] unit [%d] morphName [%s] comparing mct [%s] mct->getUpgradeReqCount() = %d\n",__FILE__,__FUNCTION__,__LINE__,unitId,morphName.c_str(),mct->getName(false).c_str(),mct->getUpgradeReqCount()); - unit->setIgnoreCheckCommand(true); + if (sc00 == NULL) { + throw megaglest_runtime_error("sc00 == NULL"); + } + if (sc10 == NULL) { + throw megaglest_runtime_error("sc10 == NULL"); + } + if (sc01 == NULL) { + throw megaglest_runtime_error("sc01 == NULL"); + } + if (sc11 == NULL) { + throw megaglest_runtime_error("sc11 == NULL"); } - const UnitType* unitType = mct->getMorphUnit(); - cr = this->game->getCommander()->tryGiveCommand(unit, mct,unit->getPos(), unitType,CardinalDir(CardinalDir::NORTH)); - } - catch(const exception &ex) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - unit->setIgnoreCheckCommand(false); - - throw megaglest_runtime_error(ex.what()); - } - - if(cr.first == crSuccess) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] unit [%d] morphName [%s] comparing mct [%s] returned = %d\n",__FILE__,__FUNCTION__,__LINE__,unitId,morphName.c_str(),mct->getName(false).c_str(),cr.first); - - break; - } - } - - - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } -} - -void World::createUnit(const string &unitName, int factionIndex, const Vec2i &pos, bool spaciated) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] unitName [%s] factionIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,unitName.c_str(),factionIndex); - - if(factionIndex < (int)factions.size()) { - Faction* faction= factions[factionIndex]; - - if(faction->getIndex() != factionIndex) { - throw megaglest_runtime_error("faction->getIndex() != factionIndex",true); - } - - const FactionType* ft= faction->getType(); - const UnitType* ut= ft->getUnitType(unitName); - - UnitPathInterface *newpath = NULL; - switch(game->getGameSettings()->getPathFinderType()) { - case pfBasic: - newpath = new UnitPathBasic(); - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!",true); - } - - Unit* unit= new Unit(getNextUnitId(faction), newpath, pos, ut, faction, &map, CardinalDir(CardinalDir::NORTH)); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str()); - - if(placeUnit(pos, generationArea, unit, spaciated)) { - unit->create(true); - unit->born(NULL); - if(scriptManager) { - scriptManager->onUnitCreated(unit); - } - if(game->getPaused()==true){ - // new units added in pause mode might change the Fow. ( Scenarios do this ) - computeFow(); - minimap.updateFowTex(1.f); - } - } - else { - delete unit; - unit = NULL; - throw megaglest_runtime_error("Unit cant be placed",true); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str()); - } - else { - throw megaglest_runtime_error("Invalid faction index in createUnitAtPosition: " + intToStr(factionIndex),true); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void World::giveResource(const string &resourceName, int factionIndex, int amount) { - if(factionIndex < (int)factions.size()) { - Faction* faction= factions[factionIndex]; - const ResourceType* rt= techTree->getResourceType(resourceName); - faction->incResourceAmount(rt, amount); - } - else { - throw megaglest_runtime_error("Invalid faction index in giveResource: " + intToStr(factionIndex),true); - } -} - -int World::getUnitCurrentField(int unitId) { - int field = -1; - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] unit [%d]\n",__FILE__,__FUNCTION__,__LINE__,unitId); - Unit* unit= findUnitById(unitId); - if(unit != NULL) { - field = unit->getCurrField(); - } - - return field; -} - -bool World::getIsUnitAlive(int unitId) { - bool result = false; - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] unit [%d]\n",__FILE__,__FUNCTION__,__LINE__,unitId); - Unit* unit= findUnitById(unitId); - if(unit != NULL) { - result = unit->isAlive(); - } - return result; -} - -vector World::getUnitsForFaction(int factionIndex,const string& commandTypeName, int field) { - vector units; - - if(factionIndex < 0 || factionIndex > getFactionCount()) { - throw megaglest_runtime_error("Invalid faction index in getUnitsForFaction: " + intToStr(factionIndex),true); - } - Faction *faction = getFaction(factionIndex); - if(faction != NULL) { - CommandType *commandType = NULL; - if(commandTypeName != "") { - commandType = CommandTypeFactory::getInstance().newInstance(commandTypeName); - } - int unitCount = faction->getUnitCount(); - for(int i = 0; i < unitCount; ++i) { - Unit *unit = faction->getUnit(i); - if(unit != NULL) { - bool addToList = true; - if(commandType != NULL) { - if(commandType->getClass() == ccAttack && field >= 0) { - const AttackCommandType *act = unit->getType()->getFirstAttackCommand(static_cast(field)); - addToList = (act != NULL); - } - else if(commandType->getClass() == ccAttackStopped && field >= 0) { - const AttackStoppedCommandType *asct = unit->getType()->getFirstAttackStoppedCommand(static_cast(field)); - addToList = (asct != NULL); - } - else { - addToList = unit->getType()->hasCommandClass(commandType->getClass()); - } - } - else if(field >= 0) { - addToList = (unit->getCurrField() == static_cast(field)); - } - - if(addToList == true) { - units.push_back(unit->getId()); + tileset.addSurfTex(sc00->getSurfaceType(), + sc10->getSurfaceType(), + sc01->getSurfaceType(), + sc11->getSurfaceType(), + coord, texture, j, i); + sc00->setSurfTexCoord(coord); + sc00->setSurfaceTexture(texture); } } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); } - delete commandType; - commandType = NULL; - } - return units; -} + //creates each faction looking at each faction name contained in GameSettings + void World::initFactionTypes(GameSettings *gs) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameLoadingFactionTypes", "", true), true); -void World::givePositionCommand(int unitId, const string &commandName, const Vec2i &pos) { - Unit* unit= findUnitById(unitId); - if(unit != NULL) { - CommandClass cc; - - if(commandName=="move") { - cc= ccMove; - } - else if(commandName=="attack") { - cc= ccAttack; - } - else { - throw megaglest_runtime_error("Invalid position command: " + commandName,true); - } - - if(unit->getType()->getFirstCtOfClass(cc) == NULL) { - throw megaglest_runtime_error("Invalid command: [" + commandName + "] for unit: [" + unit->getType()->getName(false) + "] id [" + intToStr(unit->getId()) + "]",true); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] cc = %d Unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,cc,unit->getFullName(false).c_str()); - unit->giveCommand(new Command( unit->getType()->getFirstCtOfClass(cc), pos )); - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - else { - throw megaglest_runtime_error("Invalid unitId index in givePositionCommand: " + intToStr(unitId) + " commandName = " + commandName,true); - } -} - -void World::giveStopCommand(int unitId) { - Unit* unit= findUnitById(unitId); - if(unit != NULL) { - const CommandType *ct = unit->getType()->getFirstCtOfClass(ccStop); - if(ct != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] Unit [%s] will stop\n",__FILE__,__FUNCTION__,__LINE__,unit->getFullName(false).c_str()); - unit->giveCommand(new Command(ct)); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - else { - throw megaglest_runtime_error("Invalid ct in giveStopCommand: " + intToStr(unitId),true); - } - } - else { - throw megaglest_runtime_error("Invalid unitId index in giveStopCommand: " + intToStr(unitId),true); - } -} - -bool World::selectUnit(int unitId) { - bool result = false; - Unit* unit= findUnitById(unitId); - if(unit != NULL) { - result = game->addUnitToSelection(unit); - } - - return result; -} - -void World::unselectUnit(int unitId) { - Unit* unit= findUnitById(unitId); - if(unit != NULL) { - game->removeUnitFromSelection(unit); - } -} - -void World::addUnitToGroupSelection(int unitId,int groupIndex) { - Unit* unit= findUnitById(unitId); - if(unit != NULL) { - game->addUnitToGroupSelection(unit,groupIndex); - } -} - -void World::removeUnitFromGroupSelection(int unitId,int groupIndex) { - game->removeUnitFromGroupSelection(unitId,groupIndex); -} - -void World::recallGroupSelection(int groupIndex) { - game->recallGroupSelection(groupIndex); -} - -void World::setAttackWarningsEnabled(bool enabled) { - this->disableAttackEffects = !enabled; -} -bool World::getAttackWarningsEnabled() { - return (this->disableAttackEffects == false); -} - -void World::giveAttackCommand(int unitId, int unitToAttackId) { - Unit* unit= findUnitById(unitId); - if(unit != NULL) { - Unit* targetUnit = findUnitById(unitToAttackId); - if(targetUnit != NULL) { - const CommandType *ct = unit->getType()->getFirstAttackCommand(targetUnit->getCurrField()); - if(ct != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] Unit [%s] is attacking [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getFullName(false).c_str(),targetUnit->getFullName(false).c_str()); - unit->giveCommand(new Command(ct,targetUnit)); - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if (gs == NULL) { + throw megaglest_runtime_error("gs == NULL"); } - else { - throw megaglest_runtime_error("Invalid ct in giveAttackCommand: " + intToStr(unitId) + " unitToAttackId = " + intToStr(unitToAttackId),true); + + // FIXME: This was commented out while working on issue 13 + // + // + // The check may not be needed or it may need to be re-written + + // if(gs->getFactionCount() > map.getMaxPlayers()) { + // throw megaglest_runtime_error("This map only supports "+intToStr(map.getMaxPlayers())+" players, factionCount is " + intToStr(gs->getFactionCount())); + // } + + //create stats + //printf("World gs->getThisFactionIndex() = %d\n",gs->getThisFactionIndex()); + + if (this->game->isMasterserverMode() == true) { + this->thisFactionIndex = -1; + } else { + this->thisFactionIndex = gs->getThisFactionIndex(); } - } - else { - throw megaglest_runtime_error("Invalid unitToAttackId index in giveAttackCommand: " + intToStr(unitId) + " unitToAttackId = " + intToStr(unitToAttackId),true); - } - } - else { - throw megaglest_runtime_error("Invalid unitId index in giveAttackCommand: " + intToStr(unitId) + " unitToAttackId = " + intToStr(unitToAttackId),true); - } -} -void World::giveProductionCommand(int unitId, const string &producedName) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - Unit *unit= findUnitById(unitId); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + stats.init(gs->getFactionCount(), this->thisFactionIndex, gs->getDescription(), gs->getTech()); - if(unit != NULL) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - const UnitType *ut= unit->getType(); + //create factions + //printf("this->thisFactionIndex = %d\n",this->thisFactionIndex); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + //factions.resize(gs->getFactionCount()); + for (int i = 0; i < gs->getFactionCount(); ++i) { + Faction *newFaction = new Faction(); + factions.push_back(newFaction); + } - //Search for a command that can produce the unit - for(int i= 0; i< ut->getCommandTypeCount(); ++i) { - const CommandType* ct= ut->getCommandType(i); - if(ct != NULL && ct->getClass() == ccProduce) { - const ProduceCommandType *pct= dynamic_cast(ct); - if(pct != NULL && pct->getProducedUnit() != NULL && - pct->getProducedUnit()->getName(false) == producedName) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] factions.size() = %d\n", __FILE__, __FUNCTION__, __LINE__, factions.size()); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - unit->giveCommand(new Command(pct)); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + for (int i = 0; i < (int) factions.size(); ++i) { + FactionType *ft = techTree->getTypeByName(gs->getFactionTypeName(i)); + if (ft == NULL) { + throw megaglest_runtime_error("ft == NULL"); + } + factions[i]->init(ft, gs->getFactionControl(i), techTree, game, i, gs->getTeam(i), + gs->getStartLocationIndex(i), i == thisFactionIndex, + gs->getDefaultResources(), loadWorldNode); - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; + stats.setTeam(i, gs->getTeam(i)); + stats.setFactionTypeName(i, formatString(gs->getFactionTypeName(i))); + stats.setPersonalityType(i, getFaction(i)->getType()->getPersonalityType()); + stats.setControl(i, gs->getFactionControl(i)); + stats.setResourceMultiplier(i, (gs->getResourceMultiplierIndex(i) + 5)*0.1f); + stats.setPlayerName(i, gs->getNetworkPlayerName(i)); + if (getFaction(i)->getTexture()) { + stats.setPlayerColor(i, getFaction(i)->getTexture()->getPixmapConst()->getPixel3f(0, 0)); } } + + if (Config::getInstance().getBool("EnableNewThreadManager", "false") == true) { + std::vector slaveThreadList; + for (unsigned int i = 0; i < factions.size(); ++i) { + Faction *faction = factions[i]; + slaveThreadList.push_back(faction->getWorkerThread()); + } + masterController.setSlaves(slaveThreadList); + } + + if (loadWorldNode != NULL) { + stats.loadGame(loadWorldNode); + random.setLastNumber(loadWorldNode->getAttribute("random")->getIntValue()); + + thisFactionIndex = loadWorldNode->getAttribute("thisFactionIndex")->getIntValue(); + // int thisTeamIndex; + thisTeamIndex = loadWorldNode->getAttribute("thisTeamIndex")->getIntValue(); + // int frameCount; + frameCount = loadWorldNode->getAttribute("frameCount")->getIntValue(); + + //printf("**LOAD World thisFactionIndex = %d\n",thisFactionIndex); + + MutexSafeWrapper safeMutex(mutexFactionNextUnitId, string(__FILE__) + "_" + intToStr(__LINE__)); + // std::map mapFactionNextUnitId; + // for(std::map::iterator iterMap = mapFactionNextUnitId.begin(); + // iterMap != mapFactionNextUnitId.end(); ++iterMap) { + // XmlNode *factionNextUnitIdNode = worldNode->addChild("FactionNextUnitId"); + // + // factionNextUnitIdNode->addAttribute("key",intToStr(iterMap->first), mapTagReplacements); + // factionNextUnitIdNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); + // } + //!!! + vector factionNextUnitIdNodeList = loadWorldNode->getChildList("FactionNextUnitId"); + for (unsigned int i = 0; i < factionNextUnitIdNodeList.size(); ++i) { + XmlNode *factionNextUnitIdNode = factionNextUnitIdNodeList[i]; + + int key = factionNextUnitIdNode->getAttribute("key")->getIntValue(); + int value = factionNextUnitIdNode->getAttribute("value")->getIntValue(); + + mapFactionNextUnitId[key] = value; + } + safeMutex.ReleaseLock(); + // //config + // bool fogOfWarOverride; + fogOfWarOverride = loadWorldNode->getAttribute("fogOfWarOverride")->getIntValue() != 0; + // bool fogOfWar; + fogOfWar = loadWorldNode->getAttribute("fogOfWar")->getIntValue() != 0; + // int fogOfWarSmoothingFrameSkip; + fogOfWarSmoothingFrameSkip = loadWorldNode->getAttribute("fogOfWarSmoothingFrameSkip")->getIntValue(); + // bool fogOfWarSmoothing; + fogOfWarSmoothing = loadWorldNode->getAttribute("fogOfWarSmoothing")->getIntValue() != 0; + // Game *game; + // Chrono chronoPerfTimer; + // bool perfTimerEnabled; + // + // bool unitParticlesEnabled; + unitParticlesEnabled = loadWorldNode->getAttribute("unitParticlesEnabled")->getIntValue() != 0; + // std::map staticSoundList; + // std::map streamSoundList; + // + // uint32 nextCommandGroupId; + nextCommandGroupId = loadWorldNode->getAttribute("nextCommandGroupId")->getIntValue(); + // string queuedScenarioName; + queuedScenarioName = loadWorldNode->getAttribute("queuedScenarioName")->getValue(); + // bool queuedScenarioKeepFactions; + queuedScenarioKeepFactions = loadWorldNode->getAttribute("queuedScenarioKeepFactions")->getIntValue() != 0; + + if (loadWorldNode->hasAttribute("disableAttackEffects") == true) { + disableAttackEffects = loadWorldNode->getAttribute("disableAttackEffects")->getIntValue() != 0; + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (factions.empty() == false) { + if (this->game->isMasterserverMode() == true) { + thisTeamIndex = -1; + } else { + thisTeamIndex = getFaction(thisFactionIndex)->getTeam(); + } + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); } - } - else { - throw megaglest_runtime_error("Invalid unitId index in giveProductionCommand: " + intToStr(unitId) + " producedName = " + producedName,true); - } - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); -} -void World::giveAttackStoppedCommand(int unitId, const string &itemName, bool ignoreRequirements) { - Unit *unit= findUnitById(unitId); - if(unit != NULL) { - const UnitType *ut= unit->getType(); + void World::initMinimap() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - //Search for a command that can produce the unit - for(int i= 0; i < ut->getCommandTypeCount(); ++i) { - const CommandType* ct= ut->getCommandType(i); - if(ct != NULL && ct->getClass() == ccAttackStopped) { + minimap.init(map.getW(), map.getH(), this, game->getGameSettings()->getFogOfWar()); + Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameLoadingMinimapSurface", "", true), true); - const AttackStoppedCommandType *act= static_cast(ct); - if(act != NULL && act->getName(false) == itemName) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + void World::initUnitsForScenario() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameLoadingGenerateGameElements", "", true), true); - try { - if(unit->getFaction()->reqsOk(act) == false && ignoreRequirements == true) { + //put starting units + for (int i = 0; i < getFactionCount(); ++i) { + Faction *f = factions[i]; + const FactionType *ft = f->getType(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - unit->setIgnoreCheckCommand(true); - } + for (int j = 0; j < f->getUnitCount(); ++j) { + Unit *unit = f->getUnit(j); - unit->giveCommand(new Command(act)); - } - catch(const exception &ex) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - unit->setIgnoreCheckCommand(false); + int startLocationIndex = f->getStartLocationIndex(); - throw megaglest_runtime_error(ex.what()); + if (placeUnit(map.getStartLocation(startLocationIndex), generationArea, unit, true)) { + map.putUnitCells(unit, unit->getPos()); + unit->setCurrSkill(scStop); + //unit->create(true); + //unit->born(); + } else { + string unitName = unit->getType()->getName(false); + delete unit; + unit = NULL; + throw megaglest_runtime_error("Unit: " + unitName + " can't be placed, this error is caused because there\nis not enough room to put all units near their start location.\nmake a better/larger map. Faction: #" + intToStr(i) + " name: " + ft->getName(false)); } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; + if (unit->getType()->hasSkillClass(scBeBuilt)) { + map.flatternTerrain(unit); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] unit created for unit [%s]\n", __FILE__, __FUNCTION__, __LINE__, unit->toString().c_str()); } + + // Ensure Starting Resource Amount are adjusted to max store levels + //f->limitResourcesToStore(); } + map.computeNormals(); + map.computeInterpolatedHeights(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); } - } - else { - throw megaglest_runtime_error("Invalid unitId index in giveAttackStoppedCommand: " + intToStr(unitId) + " itemName = " + itemName,true); - } -} -void World::playStaticSound(const string &playSound) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] playSound [%s]\n",__FILE__,__FUNCTION__,__LINE__,playSound.c_str()); - - string calculatedFilePath = playSound; - bool changed = Properties::applyTagsToValue(calculatedFilePath); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nPlay static sound changed: %d [%s] [%s]\n\n",changed, playSound.c_str(),calculatedFilePath.c_str()); - - if(staticSoundList.find(calculatedFilePath) == staticSoundList.end()) { - StaticSound *sound = new StaticSound(); - sound->load(calculatedFilePath); - staticSoundList[calculatedFilePath] = sound; - } - StaticSound *playSoundItem = staticSoundList[calculatedFilePath]; - - SoundRenderer &soundRenderer= SoundRenderer::getInstance(); - soundRenderer.playFx(playSoundItem); -} - -void World::playStreamingSound(const string &playSound) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] playSound [%s]\n",__FILE__,__FUNCTION__,__LINE__,playSound.c_str()); - - string calculatedFilePath = playSound; - bool changed = Properties::applyTagsToValue(calculatedFilePath); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nPlay streaming sound changed: %d [%s] [%s]\n\n",changed, playSound.c_str(),calculatedFilePath.c_str()); - - if(streamSoundList.find(calculatedFilePath) == streamSoundList.end()) { - StrSound *sound = new StrSound(); - sound->open(calculatedFilePath); - sound->setNext(sound); - streamSoundList[calculatedFilePath] = sound; - } - StrSound *playSoundItem = streamSoundList[calculatedFilePath]; - - SoundRenderer &soundRenderer= SoundRenderer::getInstance(); - soundRenderer.playMusic(playSoundItem); -} - -void World::stopStreamingSound(const string &playSound) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] playSound [%s]\n",__FILE__,__FUNCTION__,__LINE__,playSound.c_str()); - - string calculatedFilePath = playSound; - bool changed = Properties::applyTagsToValue(calculatedFilePath); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nStop streaming sound changed: %d [%s] [%s]\n\n",changed, playSound.c_str(),calculatedFilePath.c_str()); - - if(streamSoundList.find(calculatedFilePath) != streamSoundList.end()) { - StrSound *playSoundItem = streamSoundList[calculatedFilePath]; - SoundRenderer &soundRenderer= SoundRenderer::getInstance(); - soundRenderer.stopMusic(playSoundItem); - } -} - -void World::stopAllSound() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - SoundRenderer &soundRenderer= SoundRenderer::getInstance(); - soundRenderer.stopAllSounds(); -} - -void World::moveToUnit(int unitId, int destUnitId) { - Unit* unit= findUnitById(unitId); - if(unit != NULL) { - CommandClass cc= ccMove; - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] cc = %d Unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,cc,unit->getFullName(false).c_str()); - Unit* destUnit = findUnitById(destUnitId); - if(destUnit != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] cc = %d Unit [%s] destUnit [%s]\n",__FILE__,__FUNCTION__,__LINE__,cc,unit->getFullName(false).c_str(),destUnit->getFullName(false).c_str()); - unit->giveCommand(new Command( unit->getType()->getFirstCtOfClass(cc), destUnit)); - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - } - else { - throw megaglest_runtime_error("Invalid unitId index in followUnit: " + intToStr(unitId),true); - } -} - -void World::clearCaches() { - ExploredCellsLookupItemCache.clear(); - ExploredCellsLookupItemCacheTimer.clear(); - ExploredCellsLookupItemCacheTimerCount = 0; - - unitUpdater.clearCaches(); -} - -void World::togglePauseGame(bool pauseStatus,bool forceAllowPauseStateChange) { - game->setPaused(pauseStatus, forceAllowPauseStateChange, false, false); - // ensures that the Fow is really up to date when the game switches to pause mode. ( mainly for scenarios ) - computeFow(); - minimap.updateFowTex(1.f); -} - -void World::addConsoleText(const string &text) { - game->getConsole()->addStdScenarioMessage(text); -} -void World::addConsoleTextWoLang(const string &text) { - game->getConsole()->addLine(text); -} - -const string World::getSystemMacroValue(const string key) { - std::string result = key; - bool tagApplied = Properties::applyTagsToValue(result); - if(tagApplied == false) { - result = ""; - - if(key == "$SCENARIO_PATH") { - result = extractDirectoryPathFromFile(game->getGameSettings()->getScenarioDir()); - } - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("system macro key [%s] returning [%s]\n",key.c_str(),result.c_str()); - - return result; -} - -const string World::getPlayerName(int factionIndex) { - return game->getGameSettings()->getNetworkPlayerName(factionIndex); -} - -void World::giveUpgradeCommand(int unitId, const string &upgradeName) { - Unit *unit= findUnitById(unitId); - if(unit != NULL) { - const UnitType *ut= unit->getType(); - - //Search for a command that can produce the unit - for(int i= 0; i < ut->getCommandTypeCount(); ++i) { - const CommandType* ct= ut->getCommandType(i); - if(ct != NULL && ct->getClass() == ccUpgrade) { - const UpgradeCommandType *uct= static_cast(ct); - if(uct != NULL && uct->getProducedUpgrade()->getName() == upgradeName) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - unit->giveCommand(new Command(uct)); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; - } - } - } - } - else { - throw megaglest_runtime_error("Invalid unitId index in giveUpgradeCommand: " + intToStr(unitId) + " upgradeName = " + upgradeName,true); - } -} - - -int World::getResourceAmount(const string &resourceName, int factionIndex) { - if(factionIndex < (int)factions.size()) { - Faction* faction= factions[factionIndex]; - const ResourceType* rt= techTree->getResourceType(resourceName); - return faction->getResource(rt)->getAmount(); - } - else { - throw megaglest_runtime_error("Invalid faction index in giveResource: " + intToStr(factionIndex) + " resourceName = " + resourceName,true); - } -} - -Vec2i World::getStartLocation(int factionIndex) { - if(factionIndex < (int)factions.size()) { - Faction* faction= factions[factionIndex]; - return map.getStartLocation(faction->getStartLocationIndex()); - } - else { - printf("\n=================================================\n%s\n",game->getGameSettings()->toString().c_str()); - - throw megaglest_runtime_error("Invalid faction index in getStartLocation: " + intToStr(factionIndex) + " : " + intToStr(factions.size()),true); - } -} - -Vec2i World::getUnitPosition(int unitId) { - Unit* unit= findUnitById(unitId); - if(unit == NULL) { - throw megaglest_runtime_error("Can not find unit to get position unitId = " + intToStr(unitId),true); - } - return unit->getPos(); -} - -void World::setUnitPosition(int unitId, Vec2i pos) { - Unit* unit= findUnitById(unitId); - if(unit == NULL) { - throw megaglest_runtime_error("Can not find unit to set position unitId = " + intToStr(unitId),true); - } - unit->setTargetPos(pos); - this->moveUnitCells(unit, false); -} - -void World::addCellMarker(Vec2i pos, int factionIndex, const string ¬e, const string textureFile) { - const Faction *faction = NULL; - if(factionIndex >= 0) { - faction = this->getFaction(factionIndex); - } - - Vec2i surfaceCellPos = map.toSurfCoords(pos); - SurfaceCell *sc = map.getSurfaceCell(surfaceCellPos); - if(sc == NULL) { - throw megaglest_runtime_error("sc == NULL",true); - } - Vec3f vertex = sc->getVertex(); - Vec2i targetPos(vertex.x,vertex.z); - - //printf("pos [%s] scPos [%s][%p] targetPos [%s]\n",pos.getString().c_str(),surfaceCellPos.getString().c_str(),sc,targetPos.getString().c_str()); - - MarkedCell mc(targetPos,faction,note,(faction != NULL ? faction->getStartLocationIndex() : -1)); - game->addCellMarker(surfaceCellPos, mc); -} - -void World::removeCellMarker(Vec2i pos, int factionIndex) { - const Faction *faction = NULL; - if(factionIndex >= 0) { - faction = this->getFaction(factionIndex); - } - - Vec2i surfaceCellPos = map.toSurfCoords(pos); - - game->removeCellMarker(surfaceCellPos, faction); -} - -void World::showMarker(Vec2i pos, int factionIndex, const string ¬e, const string textureFile, int flashCount) { - const Faction *faction = NULL; - if(factionIndex >= 0) { - faction = this->getFaction(factionIndex); - } - - Vec2i surfaceCellPos = map.toSurfCoords(pos); - SurfaceCell *sc = map.getSurfaceCell(surfaceCellPos); - if(sc == NULL) { - throw megaglest_runtime_error("sc == NULL",true); - } - Vec3f vertex = sc->getVertex(); - Vec2i targetPos(vertex.x,vertex.z); - - //printf("pos [%s] scPos [%s][%p] targetPos [%s]\n",pos.getString().c_str(),surfaceCellPos.getString().c_str(),sc,targetPos.getString().c_str()); - - MarkedCell mc(targetPos,faction,note,(faction != NULL ? faction->getStartLocationIndex() : -1)); - if(flashCount > 0) { - mc.setAliveCount(flashCount); - } - game->showMarker(surfaceCellPos, mc); -} - -void World::highlightUnit(int unitId,float radius, float thickness, Vec4f color) { - Unit* unit= findUnitById(unitId); - if(unit == NULL) { - throw megaglest_runtime_error("Can not find unit to set highlight unitId = " + intToStr(unitId),true); - } - game->highlightUnit(unitId,radius, thickness, color); -} - -void World::unhighlightUnit(int unitId) { - Unit* unit= findUnitById(unitId); - if(unit == NULL) { - throw megaglest_runtime_error("Can not find unit to set highlight unitId = " + intToStr(unitId),true); - } - game->unhighlightUnit(unitId); -} - - -int World::getUnitFactionIndex(int unitId) { - Unit* unit= findUnitById(unitId); - if(unit == NULL) { - throw megaglest_runtime_error("Can not find Faction unit to get position unitId = " + intToStr(unitId),true); - } - return unit->getFactionIndex(); -} -const string World::getUnitName(int unitId) { - Unit* unit= findUnitById(unitId); - if(unit == NULL) { - throw megaglest_runtime_error("Can not find Faction unit to get position unitId = " + intToStr(unitId),true); - } - return unit->getFullName(game->showTranslatedTechTree()); -} - -int World::getUnitCount(int factionIndex) { - if(factionIndex < (int)factions.size()) { - Faction* faction= factions[factionIndex]; - int count= 0; - - for(int i= 0; i < faction->getUnitCount(); ++i) { - const Unit* unit= faction->getUnit(i); - if(unit != NULL && unit->isAlive()) { - ++count; - } - } - return count; - } - else { - throw megaglest_runtime_error("Invalid faction index in getUnitCount: " + intToStr(factionIndex),true); - } -} - -int World::getUnitCountOfType(int factionIndex, const string &typeName) { - if(factionIndex < (int)factions.size()) { - Faction* faction= factions[factionIndex]; - int count= 0; - - for(int i= 0; i< faction->getUnitCount(); ++i) { - const Unit* unit= faction->getUnit(i); - if(unit != NULL && unit->isAlive() && unit->getType()->getName(false) == typeName) { - ++count; - } - } - return count; - } - else { - throw megaglest_runtime_error("Invalid faction index in getUnitCountOfType: " + intToStr(factionIndex),true); - } -} - -// ==================== PRIVATE ==================== - -// ==================== private init ==================== - -//init basic cell state -void World::initCells(bool fogOfWar) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameLoadingStateCells","",true), true); - for(int i=0; i< map.getSurfaceW(); ++i) { - for(int j=0; j< map.getSurfaceH(); ++j) { - - SurfaceCell *sc= map.getSurfaceCell(i, j); - if(sc == NULL) { - throw megaglest_runtime_error("sc == NULL"); - } - if(sc->getObject()!=NULL){ - sc->getObject()->initParticles(); - } - sc->setFowTexCoord(Vec2f( - i/(next2Power(map.getSurfaceW())-1.f), - j/(next2Power(map.getSurfaceH())-1.f))); - - for (int k = 0; k < GameConstants::maxPlayers; k++) { - sc->setExplored(k, (game->getGameSettings()->getFlagTypes1() & ft1_show_map_resources) == ft1_show_map_resources); - sc->setVisible(k, !fogOfWar); - } - - for (int k = GameConstants::maxPlayers; k < GameConstants::maxPlayers + GameConstants::specialFactions; k++) { - sc->setExplored(k, true); - sc->setVisible(k, true); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In initCells() x = %d y = %d %s %s",i,j,sc->isVisibleString().c_str(),sc->isExploredString().c_str()); - if(Thread::isCurrentThreadMainThread()) { - //unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); - SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,szBuf); - } - } - } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -//init surface textures -void World::initSplattedTextures() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - for(int i = 0; i < map.getSurfaceW() - 1; ++i) { - for(int j = 0; j < map.getSurfaceH() - 1; ++j) { - Vec2f coord; - const Texture2D *texture=NULL; - SurfaceCell *sc00= map.getSurfaceCell(i, j); - SurfaceCell *sc10= map.getSurfaceCell(i+1, j); - SurfaceCell *sc01= map.getSurfaceCell(i, j+1); - SurfaceCell *sc11= map.getSurfaceCell(i+1, j+1); - - if(sc00 == NULL) { - throw megaglest_runtime_error("sc00 == NULL"); - } - if(sc10 == NULL) { - throw megaglest_runtime_error("sc10 == NULL"); - } - if(sc01 == NULL) { - throw megaglest_runtime_error("sc01 == NULL"); - } - if(sc11 == NULL) { - throw megaglest_runtime_error("sc11 == NULL"); - } - - tileset.addSurfTex( sc00->getSurfaceType(), - sc10->getSurfaceType(), - sc01->getSurfaceType(), - sc11->getSurfaceType(), - coord, texture,j,i); - sc00->setSurfTexCoord(coord); - sc00->setSurfaceTexture(texture); - } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -//creates each faction looking at each faction name contained in GameSettings -void World::initFactionTypes(GameSettings *gs) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameLoadingFactionTypes","",true), true); - - if(gs == NULL) { - throw megaglest_runtime_error("gs == NULL"); - } - - // FIXME: This was commented out while working on issue 13 - // - // - // The check may not be needed or it may need to be re-written - - // if(gs->getFactionCount() > map.getMaxPlayers()) { - // throw megaglest_runtime_error("This map only supports "+intToStr(map.getMaxPlayers())+" players, factionCount is " + intToStr(gs->getFactionCount())); - // } - - //create stats - //printf("World gs->getThisFactionIndex() = %d\n",gs->getThisFactionIndex()); - - if(this->game->isMasterserverMode() == true) { - this->thisFactionIndex = -1; - } - else { - this->thisFactionIndex= gs->getThisFactionIndex(); - } - - stats.init(gs->getFactionCount(), this->thisFactionIndex, gs->getDescription(),gs->getTech()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //create factions - //printf("this->thisFactionIndex = %d\n",this->thisFactionIndex); - - //factions.resize(gs->getFactionCount()); - for(int i= 0; i < gs->getFactionCount(); ++i){ - Faction *newFaction = new Faction(); - factions.push_back(newFaction); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] factions.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,factions.size()); - - for(int i=0; i < (int)factions.size(); ++i) { - FactionType *ft= techTree->getTypeByName(gs->getFactionTypeName(i)); - if(ft == NULL) { - throw megaglest_runtime_error("ft == NULL"); - } - factions[i]->init(ft, gs->getFactionControl(i), techTree, game, i, gs->getTeam(i), - gs->getStartLocationIndex(i), i==thisFactionIndex, - gs->getDefaultResources(),loadWorldNode); - - stats.setTeam(i, gs->getTeam(i)); - stats.setFactionTypeName(i, formatString(gs->getFactionTypeName(i))); - stats.setPersonalityType(i, getFaction(i)->getType()->getPersonalityType()); - stats.setControl(i, gs->getFactionControl(i)); - stats.setResourceMultiplier(i,(gs->getResourceMultiplierIndex(i)+5)*0.1f); - stats.setPlayerName(i,gs->getNetworkPlayerName(i)); - if(getFaction(i)->getTexture()) { - stats.setPlayerColor(i,getFaction(i)->getTexture()->getPixmapConst()->getPixel3f(0, 0)); - } - } - - if(Config::getInstance().getBool("EnableNewThreadManager","false") == true) { - std::vector slaveThreadList; - for(unsigned int i = 0; i < factions.size(); ++i) { - Faction *faction = factions[i]; - slaveThreadList.push_back(faction->getWorkerThread()); - } - masterController.setSlaves(slaveThreadList); - } - - if(loadWorldNode != NULL) { - stats.loadGame(loadWorldNode); - random.setLastNumber(loadWorldNode->getAttribute("random")->getIntValue()); - - thisFactionIndex = loadWorldNode->getAttribute("thisFactionIndex")->getIntValue(); - // int thisTeamIndex; - thisTeamIndex = loadWorldNode->getAttribute("thisTeamIndex")->getIntValue(); - // int frameCount; - frameCount = loadWorldNode->getAttribute("frameCount")->getIntValue(); - - //printf("**LOAD World thisFactionIndex = %d\n",thisFactionIndex); - - MutexSafeWrapper safeMutex(mutexFactionNextUnitId,string(__FILE__) + "_" + intToStr(__LINE__)); - // std::map mapFactionNextUnitId; -// for(std::map::iterator iterMap = mapFactionNextUnitId.begin(); -// iterMap != mapFactionNextUnitId.end(); ++iterMap) { -// XmlNode *factionNextUnitIdNode = worldNode->addChild("FactionNextUnitId"); -// -// factionNextUnitIdNode->addAttribute("key",intToStr(iterMap->first), mapTagReplacements); -// factionNextUnitIdNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); -// } - //!!! - vector factionNextUnitIdNodeList = loadWorldNode->getChildList("FactionNextUnitId"); - for(unsigned int i = 0; i < factionNextUnitIdNodeList.size(); ++i) { - XmlNode *factionNextUnitIdNode = factionNextUnitIdNodeList[i]; - - int key = factionNextUnitIdNode->getAttribute("key")->getIntValue(); - int value = factionNextUnitIdNode->getAttribute("value")->getIntValue(); - - mapFactionNextUnitId[key] = value; - } - safeMutex.ReleaseLock(); - // //config - // bool fogOfWarOverride; - fogOfWarOverride = loadWorldNode->getAttribute("fogOfWarOverride")->getIntValue() != 0; - // bool fogOfWar; - fogOfWar = loadWorldNode->getAttribute("fogOfWar")->getIntValue() != 0; - // int fogOfWarSmoothingFrameSkip; - fogOfWarSmoothingFrameSkip = loadWorldNode->getAttribute("fogOfWarSmoothingFrameSkip")->getIntValue(); - // bool fogOfWarSmoothing; - fogOfWarSmoothing = loadWorldNode->getAttribute("fogOfWarSmoothing")->getIntValue() != 0; - // Game *game; - // Chrono chronoPerfTimer; - // bool perfTimerEnabled; - // - // bool unitParticlesEnabled; - unitParticlesEnabled = loadWorldNode->getAttribute("unitParticlesEnabled")->getIntValue() != 0; - // std::map staticSoundList; - // std::map streamSoundList; - // - // uint32 nextCommandGroupId; - nextCommandGroupId = loadWorldNode->getAttribute("nextCommandGroupId")->getIntValue(); - // string queuedScenarioName; - queuedScenarioName = loadWorldNode->getAttribute("queuedScenarioName")->getValue(); - // bool queuedScenarioKeepFactions; - queuedScenarioKeepFactions = loadWorldNode->getAttribute("queuedScenarioKeepFactions")->getIntValue() != 0; - - if(loadWorldNode->hasAttribute("disableAttackEffects") == true) { - disableAttackEffects = loadWorldNode->getAttribute("disableAttackEffects")->getIntValue() != 0; - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(factions.empty() == false) { - if(this->game->isMasterserverMode() == true) { - thisTeamIndex = -1; - } - else { - thisTeamIndex = getFaction(thisFactionIndex)->getTeam(); - } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void World::initMinimap() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - minimap.init(map.getW(), map.getH(), this, game->getGameSettings()->getFogOfWar()); - Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameLoadingMinimapSurface","",true), true); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void World::initUnitsForScenario() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameLoadingGenerateGameElements","",true), true); - - //put starting units - for(int i = 0; i < getFactionCount(); ++i) { - Faction *f= factions[i]; - const FactionType *ft= f->getType(); - - for(int j = 0; j < f->getUnitCount(); ++j) { - Unit *unit = f->getUnit(j); - - int startLocationIndex= f->getStartLocationIndex(); - - if(placeUnit(map.getStartLocation(startLocationIndex), generationArea, unit, true)) { - map.putUnitCells(unit, unit->getPos()); - unit->setCurrSkill(scStop); - //unit->create(true); - //unit->born(); - } - else { + void World::placeUnitAtLocation(const Vec2i &location, int radius, Unit *unit, bool spaciated) { + if (placeUnit(location, generationArea, unit, spaciated)) { + unit->create(true); + unit->born(NULL); + } else { string unitName = unit->getType()->getName(false); + string unitFactionName = unit->getFaction()->getType()->getName(false); + int unitFactionIndex = unit->getFactionIndex(); + delete unit; unit = NULL; - throw megaglest_runtime_error("Unit: " + unitName + " can't be placed, this error is caused because there\nis not enough room to put all units near their start location.\nmake a better/larger map. Faction: #" + intToStr(i) + " name: " + ft->getName(false)); - } + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Unit: [%s] can't be placed, this error is caused because there\nis not enough room to put all units near their start location.\nmake a better/larger map. Faction: #%d name: [%s]", + unitName.c_str(), unitFactionIndex, unitFactionName.c_str()); + throw megaglest_runtime_error(szBuf, false); + } if (unit->getType()->hasSkillClass(scBeBuilt)) { map.flatternTerrain(unit); } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] unit created for unit [%s]\n", __FILE__, __FUNCTION__, __LINE__, unit->toString().c_str()); + } - // Ensure Starting Resource Amount are adjusted to max store levels - //f->limitResourcesToStore(); - } - map.computeNormals(); - map.computeInterpolatedHeights(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} + //place units randomly aroud start location + void World::initUnits() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameLoadingGenerateGameElements", "", true), true); -void World::placeUnitAtLocation(const Vec2i &location, int radius, Unit *unit, bool spaciated) { - if(placeUnit(location, generationArea, unit, spaciated)) { - unit->create(true); - unit->born(NULL); - } - else { - string unitName = unit->getType()->getName(false); - string unitFactionName = unit->getFaction()->getType()->getName(false); - int unitFactionIndex = unit->getFactionIndex(); + bool gotError = false; + bool skipStackTrace = false; + string sErrBuf = ""; + try { + //put starting units + if (loadWorldNode == NULL) { + for (int i = 0; i < getFactionCount(); ++i) { + Faction *f = factions[i]; + const FactionType *ft = f->getType(); + for (int j = 0; j < ft->getStartingUnitCount(); ++j) { + const UnitType *ut = ft->getStartingUnit(j); + int initNumber = ft->getStartingUnitAmount(j); - delete unit; - unit = NULL; + for (int l = 0; l < initNumber; l++) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Unit: [%s] can't be placed, this error is caused because there\nis not enough room to put all units near their start location.\nmake a better/larger map. Faction: #%d name: [%s]", - unitName.c_str(),unitFactionIndex,unitFactionName.c_str()); - throw megaglest_runtime_error(szBuf,false); - } - if (unit->getType()->hasSkillClass(scBeBuilt)) { - map.flatternTerrain(unit); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str()); + UnitPathInterface *newpath = NULL; + switch (game->getGameSettings()->getPathFinderType()) { + case pfBasic: + newpath = new UnitPathBasic(); + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } -} + Unit *unit = new Unit(getNextUnitId(f), newpath, Vec2i(0), ut, f, &map, CardinalDir(CardinalDir::NORTH)); + int startLocationIndex = f->getStartLocationIndex(); + placeUnitAtLocation(map.getStartLocation(startLocationIndex), generationArea, unit, true); + } + } + } + // the following is done here in an extra loop and not in the loop above, because shared resources games + // need to load all factions first, before calculating limitResourcesToStore() + for (int i = 0; i < getFactionCount(); ++i) { + Faction *f = factions[i]; + // Ensure Starting Resource Amount are adjusted to max store levels + f->limitResourcesToStore(); + } + } else { + //printf("Load game setting unit pos\n"); + refreshAllUnitExplorations(); + } + } catch (const megaglest_runtime_error &ex) { + gotError = true; + if (ex.wantStackTrace() == true) { + char szErrBuf[8096] = ""; + snprintf(szErrBuf, 8096, "In [%s::%s %d]", __FILE__, __FUNCTION__, __LINE__); + sErrBuf = string(szErrBuf) + string("\nerror [") + string(ex.what()) + string("]\n"); + } else { + skipStackTrace = true; + sErrBuf = ex.what(); + } + SystemFlags::OutputDebug(SystemFlags::debugError, sErrBuf.c_str()); + } catch (const std::exception &ex) { + gotError = true; + char szErrBuf[8096] = ""; + snprintf(szErrBuf, 8096, "In [%s::%s %d]", __FILE__, __FUNCTION__, __LINE__); + sErrBuf = string(szErrBuf) + string("\nerror [") + string(ex.what()) + string("]\n"); + SystemFlags::OutputDebug(SystemFlags::debugError, sErrBuf.c_str()); + } -//place units randomly aroud start location -void World::initUnits() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - Logger::getInstance().add(Lang::getInstance().getString("LogScreenGameLoadingGenerateGameElements","",true), true); + map.computeNormals(); + map.computeInterpolatedHeights(); - bool gotError = false; - bool skipStackTrace = false; - string sErrBuf=""; - try { - //put starting units - if(loadWorldNode == NULL) { - for(int i = 0; i < getFactionCount(); ++i) { - Faction *f= factions[i]; - const FactionType *ft= f->getType(); - for(int j = 0; j < ft->getStartingUnitCount(); ++j) { - const UnitType *ut= ft->getStartingUnit(j); - int initNumber= ft->getStartingUnitAmount(j); + if (gotError == true) { + throw megaglest_runtime_error(sErrBuf, !skipStackTrace); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } - for(int l = 0; l < initNumber; l++) { + void World::refreshAllUnitExplorations() { + for (unsigned int i = 0; i < (unsigned int) getFactionCount(); ++i) { + Faction *faction = factions[i]; - UnitPathInterface *newpath = NULL; - switch(game->getGameSettings()->getPathFinderType()) { - case pfBasic: - newpath = new UnitPathBasic(); - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); + for (unsigned int j = 0; j < (unsigned int) faction->getUnitCount(); ++j) { + Unit *unit = faction->getUnit(j); + unit->refreshPos(); + } + } + } + + void World::initMap() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + map.init(&tileset); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void World::exploreCells(int teamIndex, ExploredCellsLookupItem &exploredCellsCache) { + std::vector &cellList = exploredCellsCache.exploredCellList; + for (int idx2 = 0; idx2 < (int) cellList.size(); ++idx2) { + SurfaceCell* sc = cellList[idx2]; + sc->setExplored(teamIndex, true); + } + cellList = exploredCellsCache.visibleCellList; + for (int idx2 = 0; idx2 < (int) cellList.size(); ++idx2) { + SurfaceCell* sc = cellList[idx2]; + sc->setVisible(teamIndex, true); + } + } + + // ==================== exploration ==================== + + ExploredCellsLookupItem World::exploreCells(const Vec2i &newPos, int sightRange, int teamIndex, Unit *unit) { + // cache lookup of previously calculated cells + sight range + if (MaxExploredCellsLookupItemCache > 0) { + if (difftime(time(NULL), ExploredCellsLookupItem::lastDebug) >= 10) { + ExploredCellsLookupItem::lastDebug = time(NULL); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] ExploredCellsLookupItemCache.size() = %d\n", __FILE__, __FUNCTION__, __LINE__, ExploredCellsLookupItemCache.size()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] ExploredCellsLookupItemCache.size() = %d\n", __FILE__, __FUNCTION__, __LINE__, ExploredCellsLookupItemCache.size()); + } + + // Ok we limit the cache size due to possible RAM constraints when + // the threshold is met + bool MaxExploredCellsLookupItemCacheTriggered = false; + if ((int) ExploredCellsLookupItemCache.size() >= MaxExploredCellsLookupItemCache) { + MaxExploredCellsLookupItemCacheTriggered = true; + // Snag the oldest entry in the list + std::map::reverse_iterator purgeItem = ExploredCellsLookupItemCacheTimer.rbegin(); + + ExploredCellsLookupItemCache[purgeItem->second.pos].erase(purgeItem->second.sightRange); + + if (ExploredCellsLookupItemCache[purgeItem->second.pos].empty() == true) { + ExploredCellsLookupItemCache.erase(purgeItem->second.pos); + } + + ExploredCellsLookupItemCacheTimer.erase(purgeItem->first); + } + + // Check the cache for the pos, sightrange and use from + // cache if already found + std::map >::iterator iterFind = ExploredCellsLookupItemCache.find(newPos); + if (iterFind != ExploredCellsLookupItemCache.end()) { + + std::map::iterator iterFind2 = iterFind->second.find(sightRange); + if (iterFind2 != iterFind->second.end()) { + + ExploredCellsLookupItem &exploredCellsCache = iterFind2->second; + exploreCells(teamIndex, exploredCellsCache); + + // Only start worrying about updating the cache timer if we + // have hit the threshold + if (MaxExploredCellsLookupItemCacheTriggered == true) { + // Remove the old timer entry since the search key id is stale + ExploredCellsLookupItemCacheTimer.erase(exploredCellsCache.ExploredCellsLookupItemCacheTimerCountIndex); + exploredCellsCache.ExploredCellsLookupItemCacheTimerCountIndex = ExploredCellsLookupItemCacheTimerCount++; + + ExploredCellsLookupKey lookupKey; + lookupKey.pos = newPos; + lookupKey.sightRange = sightRange; + lookupKey.teamIndex = teamIndex; + + // Add a new search key since we just used this exploredCellsCache + ExploredCellsLookupItemCacheTimer[exploredCellsCache.ExploredCellsLookupItemCacheTimerCountIndex] = lookupKey; } - Unit *unit= new Unit(getNextUnitId(f), newpath, Vec2i(0), ut, f, &map, CardinalDir(CardinalDir::NORTH)); - int startLocationIndex= f->getStartLocationIndex(); - placeUnitAtLocation(map.getStartLocation(startLocationIndex), generationArea, unit, true); + return exploredCellsCache; } } } - // the following is done here in an extra loop and not in the loop above, because shared resources games - // need to load all factions first, before calculating limitResourcesToStore() - for(int i = 0; i < getFactionCount(); ++i) { - Faction *f= factions[i]; - // Ensure Starting Resource Amount are adjusted to max store levels - f->limitResourcesToStore(); - } - } - else { - //printf("Load game setting unit pos\n"); - refreshAllUnitExplorations(); - } - } - catch(const megaglest_runtime_error &ex) { - gotError = true; - if(ex.wantStackTrace() == true) { - char szErrBuf[8096]=""; - snprintf(szErrBuf,8096,"In [%s::%s %d]",__FILE__,__FUNCTION__,__LINE__); - sErrBuf = string(szErrBuf) + string("\nerror [") + string(ex.what()) + string("]\n"); - } - else { - skipStackTrace = true; - sErrBuf = ex.what(); - } - SystemFlags::OutputDebug(SystemFlags::debugError,sErrBuf.c_str()); - } - catch(const std::exception &ex) { - gotError = true; - char szErrBuf[8096]=""; - snprintf(szErrBuf,8096,"In [%s::%s %d]",__FILE__,__FUNCTION__,__LINE__); - sErrBuf = string(szErrBuf) + string("\nerror [") + string(ex.what()) + string("]\n"); - SystemFlags::OutputDebug(SystemFlags::debugError,sErrBuf.c_str()); - } - map.computeNormals(); - map.computeInterpolatedHeights(); + Vec2i newSurfPos = Map::toSurfCoords(newPos); + int surfSightRange = sightRange / Map::cellScale + 1; - if(gotError == true) { - throw megaglest_runtime_error(sErrBuf,!skipStackTrace); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} + // Explore, this code is quite expensive when we have lots of units + ExploredCellsLookupItem exploredCellsCache; + exploredCellsCache.exploredCellList.reserve(surfSightRange + indirectSightRange * 4); + exploredCellsCache.visibleCellList.reserve(surfSightRange + indirectSightRange * 4); -void World::refreshAllUnitExplorations() { - for(unsigned int i = 0; i < (unsigned int)getFactionCount(); ++i) { - Faction *faction = factions[i]; + //int loopCount = 0; + for (int i = -surfSightRange - indirectSightRange - 1; i <= surfSightRange + indirectSightRange + 1; ++i) { + for (int j = -surfSightRange - indirectSightRange - 1; j <= surfSightRange + indirectSightRange + 1; ++j) { + //loopCount++; + Vec2i currRelPos = Vec2i(i, j); + Vec2i currPos = newSurfPos + currRelPos; + if (map.isInsideSurface(currPos) == true) { + SurfaceCell *sc = map.getSurfaceCell(currPos); + if (sc == NULL) { + throw megaglest_runtime_error("sc == NULL"); + } - for(unsigned int j = 0; j < (unsigned int)faction->getUnitCount(); ++j) { - Unit *unit = faction->getUnit(j); - unit->refreshPos(); - } - } -} + //explore + float posLength = currRelPos.length(); + bool updateExplored = (posLength < surfSightRange + indirectSightRange + 1); + bool updateVisible = (posLength < surfSightRange); -void World::initMap() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - map.init(&tileset); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} + if (SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In exploreCells() currRelPos = %s currPos = %s posLength = %f updateExplored = %d updateVisible = %d sightRange = %d teamIndex = %d", + currRelPos.getString().c_str(), currPos.getString().c_str(), posLength, updateExplored, updateVisible, sightRange, teamIndex); + if (Thread::isCurrentThreadMainThread() == false) { + unit->logSynchDataThreaded(__FILE__, __LINE__, szBuf); + } else { + unit->logSynchData(__FILE__, __LINE__, szBuf); + } + } -void World::exploreCells(int teamIndex, ExploredCellsLookupItem &exploredCellsCache) { - std::vector &cellList = exploredCellsCache.exploredCellList; - for (int idx2 = 0; idx2 < (int)cellList.size(); ++idx2) { - SurfaceCell* sc = cellList[idx2]; - sc->setExplored(teamIndex, true); - } - cellList = exploredCellsCache.visibleCellList; - for (int idx2 = 0; idx2 < (int)cellList.size(); ++idx2) { - SurfaceCell* sc = cellList[idx2]; - sc->setVisible(teamIndex, true); - } -} - -// ==================== exploration ==================== - -ExploredCellsLookupItem World::exploreCells(const Vec2i &newPos, int sightRange, int teamIndex, Unit *unit) { - // cache lookup of previously calculated cells + sight range - if(MaxExploredCellsLookupItemCache > 0) { - if(difftime(time(NULL),ExploredCellsLookupItem::lastDebug) >= 10) { - ExploredCellsLookupItem::lastDebug = time(NULL); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] ExploredCellsLookupItemCache.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,ExploredCellsLookupItemCache.size()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] ExploredCellsLookupItemCache.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,ExploredCellsLookupItemCache.size()); - } - - // Ok we limit the cache size due to possible RAM constraints when - // the threshold is met - bool MaxExploredCellsLookupItemCacheTriggered = false; - if((int)ExploredCellsLookupItemCache.size() >= MaxExploredCellsLookupItemCache) { - MaxExploredCellsLookupItemCacheTriggered = true; - // Snag the oldest entry in the list - std::map::reverse_iterator purgeItem = ExploredCellsLookupItemCacheTimer.rbegin(); - - ExploredCellsLookupItemCache[purgeItem->second.pos].erase(purgeItem->second.sightRange); - - if(ExploredCellsLookupItemCache[purgeItem->second.pos].empty() == true) { - ExploredCellsLookupItemCache.erase(purgeItem->second.pos); + if (updateExplored) { + sc->setExplored(teamIndex, true); + exploredCellsCache.exploredCellList.push_back(sc); + } + //visible + if (updateVisible) { + sc->setVisible(teamIndex, true); + exploredCellsCache.visibleCellList.push_back(sc); + } + } + } } - ExploredCellsLookupItemCacheTimer.erase(purgeItem->first); - } - - // Check the cache for the pos, sightrange and use from - // cache if already found - std::map >::iterator iterFind = ExploredCellsLookupItemCache.find(newPos); - if(iterFind != ExploredCellsLookupItemCache.end()) { - - std::map::iterator iterFind2 = iterFind->second.find(sightRange); - if(iterFind2 != iterFind->second.end()) { - - ExploredCellsLookupItem &exploredCellsCache = iterFind2->second; - exploreCells(teamIndex, exploredCellsCache); - - // Only start worrying about updating the cache timer if we - // have hit the threshold - if(MaxExploredCellsLookupItemCacheTriggered == true) { - // Remove the old timer entry since the search key id is stale - ExploredCellsLookupItemCacheTimer.erase(exploredCellsCache.ExploredCellsLookupItemCacheTimerCountIndex); + // Ok update our caches with the latest info for this position, sight and team + if (MaxExploredCellsLookupItemCache > 0) { + if (exploredCellsCache.exploredCellList.empty() == false || exploredCellsCache.visibleCellList.empty() == false) { exploredCellsCache.ExploredCellsLookupItemCacheTimerCountIndex = ExploredCellsLookupItemCacheTimerCount++; + ExploredCellsLookupItemCache[newPos][sightRange] = exploredCellsCache; ExploredCellsLookupKey lookupKey; lookupKey.pos = newPos; lookupKey.sightRange = sightRange; lookupKey.teamIndex = teamIndex; - - // Add a new search key since we just used this exploredCellsCache ExploredCellsLookupItemCacheTimer[exploredCellsCache.ExploredCellsLookupItemCacheTimerCountIndex] = lookupKey; } - - return exploredCellsCache; } + return exploredCellsCache; } - } - Vec2i newSurfPos= Map::toSurfCoords(newPos); - int surfSightRange= sightRange / Map::cellScale+1; + bool World::showWorldForPlayer(int factionIndex, bool excludeFogOfWarCheck) const { + bool ret = false; + if (factionIndex >= 0) { + if (excludeFogOfWarCheck == false && + fogOfWarSkillTypeValue == 0 && fogOfWarOverride == true) { + ret = true; + } else if (factionIndex == thisFactionIndex && game != NULL) { - // Explore, this code is quite expensive when we have lots of units - ExploredCellsLookupItem exploredCellsCache; - exploredCellsCache.exploredCellList.reserve(surfSightRange + indirectSightRange * 4); - exploredCellsCache.visibleCellList.reserve(surfSightRange + indirectSightRange * 4); + //printf("Show FOW thisTeamIndex = %d (%d) game->getGameOver() = %d game->getGameSettings()->isNetworkGame() = %d game->getGameSettings()->getEnableObserverModeAtEndGame() = %d thisFactionIndex = %d Is Winning Faction = %d\n", + // thisTeamIndex,(GameConstants::maxPlayers -1 + fpt_Observer),game->getGameOver(), + // game->getGameSettings()->isNetworkGame(),game->getGameSettings()->getEnableObserverModeAtEndGame(), + // thisFactionIndex,getStats()->getVictory(thisFactionIndex)); - //int loopCount = 0; - for(int i = -surfSightRange - indirectSightRange -1; i <= surfSightRange + indirectSightRange +1; ++i) { - for(int j = -surfSightRange - indirectSightRange -1; j <= surfSightRange + indirectSightRange +1; ++j) { - //loopCount++; - Vec2i currRelPos= Vec2i(i, j); - Vec2i currPos= newSurfPos + currRelPos; - if(map.isInsideSurface(currPos) == true){ - SurfaceCell *sc= map.getSurfaceCell(currPos); - if(sc == NULL) { - throw megaglest_runtime_error("sc == NULL"); - } - - //explore - float posLength = currRelPos.length(); - bool updateExplored = (posLength < surfSightRange + indirectSightRange + 1); - bool updateVisible = (posLength < surfSightRange); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && - SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In exploreCells() currRelPos = %s currPos = %s posLength = %f updateExplored = %d updateVisible = %d sightRange = %d teamIndex = %d", - currRelPos.getString().c_str(), currPos.getString().c_str(),posLength,updateExplored, updateVisible, sightRange, teamIndex); - if(Thread::isCurrentThreadMainThread() == false) { - unit->logSynchDataThreaded(__FILE__,__LINE__,szBuf); + // Player is an Observer + if (thisTeamIndex == GameConstants::maxPlayers - 1 + fpt_Observer) { + ret = true; } - else { - unit->logSynchData(__FILE__,__LINE__,szBuf); + // Game over and not a network game + else if (game->getGameOver() == true && + game->getGameSettings()->isNetworkGame() == false) { + ret = true; } - } + // Game is over but playing a Network game so check if we can + // turn off fog of war? + else if (game->getGameOver() == true && + game->getGameSettings()->isNetworkGame() == true && + game->getGameSettings()->getEnableObserverModeAtEndGame() == true) { + ret = true; - if(updateExplored) { - sc->setExplored(teamIndex, true); - exploredCellsCache.exploredCellList.push_back(sc); - } - //visible - if(updateVisible) { - sc->setVisible(teamIndex, true); - exploredCellsCache.visibleCellList.push_back(sc); - } - } - } - } + // If the faction is NOT on the winning team, don't let them see the map + // until all mobile units are dead + if (getStats()->getVictory(factionIndex) == false) { + // If the player has at least 1 Unit alive that is mobile (can move) + // then we cannot turn off fog of war - // Ok update our caches with the latest info for this position, sight and team - if(MaxExploredCellsLookupItemCache > 0) { - if(exploredCellsCache.exploredCellList.empty() == false || exploredCellsCache.visibleCellList.empty() == false) { - exploredCellsCache.ExploredCellsLookupItemCacheTimerCountIndex = ExploredCellsLookupItemCacheTimerCount++; - ExploredCellsLookupItemCache[newPos][sightRange] = exploredCellsCache; - - ExploredCellsLookupKey lookupKey; - lookupKey.pos = newPos; - lookupKey.sightRange = sightRange; - lookupKey.teamIndex = teamIndex; - ExploredCellsLookupItemCacheTimer[exploredCellsCache.ExploredCellsLookupItemCacheTimerCountIndex] = lookupKey; - } - } - return exploredCellsCache; -} - -bool World::showWorldForPlayer(int factionIndex, bool excludeFogOfWarCheck) const { - bool ret = false; - if(factionIndex >= 0) { - if(excludeFogOfWarCheck == false && - fogOfWarSkillTypeValue == 0 && fogOfWarOverride == true) { - ret = true; - } - else if(factionIndex == thisFactionIndex && game != NULL) { - - //printf("Show FOW thisTeamIndex = %d (%d) game->getGameOver() = %d game->getGameSettings()->isNetworkGame() = %d game->getGameSettings()->getEnableObserverModeAtEndGame() = %d thisFactionIndex = %d Is Winning Faction = %d\n", - // thisTeamIndex,(GameConstants::maxPlayers -1 + fpt_Observer),game->getGameOver(), - // game->getGameSettings()->isNetworkGame(),game->getGameSettings()->getEnableObserverModeAtEndGame(), - // thisFactionIndex,getStats()->getVictory(thisFactionIndex)); - - // Player is an Observer - if(thisTeamIndex == GameConstants::maxPlayers -1 + fpt_Observer) { - ret = true; - } - // Game over and not a network game - else if(game->getGameOver() == true && - game->getGameSettings()->isNetworkGame() == false) { - ret = true; - } - // Game is over but playing a Network game so check if we can - // turn off fog of war? - else if(game->getGameOver() == true && - game->getGameSettings()->isNetworkGame() == true && - game->getGameSettings()->getEnableObserverModeAtEndGame() == true) { - ret = true; - - // If the faction is NOT on the winning team, don't let them see the map - // until all mobile units are dead - if(getStats()->getVictory(factionIndex) == false) { - // If the player has at least 1 Unit alive that is mobile (can move) - // then we cannot turn off fog of war - - const Faction *faction = getFaction(factionIndex); - // for(int i = 0; i < faction->getUnitCount(); ++i) { - // Unit *unit = getFaction(factionIndex)->getUnit(i); - // if(unit != NULL && unit->isAlive() && unit->getType()->isMobile() == true) { - // ret = false; - // break; - // } - // } - if(faction->hasAliveUnits(true,false) == true) { - ret = false; - } - } - } - } - } - //printf("showWorldForPlayer for %d is: %d\n",factionIndex,ret); - return ret; -} - -//computes the fog of war texture, contained in the minimap -void World::computeFow() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] Line: %d in frame: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,getFrameCount()); - - Chrono chronoGamePerformanceCounts; - if(this->game) chronoGamePerformanceCounts.start(); - - minimap.resetFowTex(); - - if(this->game) this->game->addPerformanceCount("world minimap.resetFowTex",chronoGamePerformanceCounts.getMillis()); - - // reset cells - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] Line: %d in frame: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,getFrameCount()); - - if(this->game) chronoGamePerformanceCounts.start(); - - // Once we have calculated fog of war texture alpha, they are cached so we - // restore the default texture in one shot for speed - if(fogOfWar && cacheFowAlphaTexture == true) { - if(cacheFowAlphaTextureFogOfWarValue != fogOfWar) { - cacheFowAlphaTexture = false; - } - else { - minimap.restoreFowTexAlphaSurface(); - } - } - int resetFowAlphaFactionCount = 0; - - for(int factionIndex = 0; factionIndex < GameConstants::maxPlayers + GameConstants::specialFactions; ++factionIndex) { - if(factionIndex >= getFactionCount()) { - continue; - } - Faction *faction = getFaction(factionIndex); -// for(int indexTeamFaction = 0; -// indexTeamFaction < GameConstants::maxPlayers + GameConstants::specialFactions; -// ++indexTeamFaction) { - - // If fog of war enabled set cell visible to false and later set those close to units to true - if(fogOfWar) { - for(int indexSurfaceW = 0; indexSurfaceW < map.getSurfaceW(); ++indexSurfaceW) { - for(int indexSurfaceH = 0; indexSurfaceH < map.getSurfaceH(); ++indexSurfaceH) { - // set all cells to not visible - map.getSurfaceCell(indexSurfaceW, indexSurfaceH)->setVisible(faction->getTeam(), false); - } - } - } - - // Remove fog of war for factions NOT on my team which i can see - if(!fogOfWar || (faction->getTeam() != thisTeamIndex)) { - bool showWorldForFaction = showWorldForPlayer(factionIndex); - //printf("showWorldForFaction indexFaction = %d thisTeamIndex = %d showWorldForFaction = %d\n",indexFaction,thisTeamIndex,showWorldForFaction); - if(showWorldForFaction == true) { - resetFowAlphaFactionCount++; - } - for(int indexSurfaceW = 0; indexSurfaceW < map.getSurfaceW(); ++indexSurfaceW) { - for(int indexSurfaceH = 0; indexSurfaceH < map.getSurfaceH(); ++indexSurfaceH) { - // reset fog of ware texture alpha values - if(!fogOfWar || (cacheFowAlphaTexture == false && - showWorldForFaction == true && - resetFowAlphaFactionCount <= 1)) { - const Vec2i surfPos(indexSurfaceW,indexSurfaceH); - - //compute max alpha - float maxAlpha= 0.0f; - if(surfPos.x > 1 && surfPos.y > 1 && - surfPos.x < map.getSurfaceW() - 2 && - surfPos.y < map.getSurfaceH() - 2) { - maxAlpha= 1.f; - } - else if(surfPos.x > 0 && surfPos.y > 0 && - surfPos.x < map.getSurfaceW() - 1 && - surfPos.y < map.getSurfaceH() - 1){ - maxAlpha= 0.3f; - } - - // compute alpha - float alpha = maxAlpha; - minimap.incFowTextureAlphaSurface(surfPos, alpha); - } - } - } - } - // Remove fog of war for factions on my team - else if(fogOfWar && (faction->getTeam() == thisTeamIndex)) { - bool showWorldForFaction = showWorldForPlayer(factionIndex); - //printf("#2 showWorldForFaction thisFactionIndex = %d thisTeamIndex = %d showWorldForFaction = %d\n",thisFactionIndex,thisTeamIndex,showWorldForFaction); - if(showWorldForFaction == true) { - for(int indexSurfaceW = 0; indexSurfaceW < map.getSurfaceW(); ++indexSurfaceW) { - for(int indexSurfaceH = 0; indexSurfaceH < map.getSurfaceH(); ++indexSurfaceH) { - // reset fog of ware texture alpha values - if(!fogOfWar || (cacheFowAlphaTexture == false && - showWorldForFaction == true)) { - const Vec2i surfPos(indexSurfaceW,indexSurfaceH); - - //compute max alpha - float maxAlpha= 0.0f; - if(surfPos.x > 1 && surfPos.y > 1 && - surfPos.x < map.getSurfaceW() - 2 && - surfPos.y < map.getSurfaceH() - 2) { - maxAlpha= 1.f; + const Faction *faction = getFaction(factionIndex); + // for(int i = 0; i < faction->getUnitCount(); ++i) { + // Unit *unit = getFaction(factionIndex)->getUnit(i); + // if(unit != NULL && unit->isAlive() && unit->getType()->isMobile() == true) { + // ret = false; + // break; + // } + // } + if (faction->hasAliveUnits(true, false) == true) { + ret = false; } - else if(surfPos.x > 0 && surfPos.y > 0 && + } + } + } + } + //printf("showWorldForPlayer for %d is: %d\n",factionIndex,ret); + return ret; + } + + //computes the fog of war texture, contained in the minimap + void World::computeFow() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] Line: %d in frame: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, getFrameCount()); + + Chrono chronoGamePerformanceCounts; + if (this->game) chronoGamePerformanceCounts.start(); + + minimap.resetFowTex(); + + if (this->game) this->game->addPerformanceCount("world minimap.resetFowTex", chronoGamePerformanceCounts.getMillis()); + + // reset cells + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] Line: %d in frame: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, getFrameCount()); + + if (this->game) chronoGamePerformanceCounts.start(); + + // Once we have calculated fog of war texture alpha, they are cached so we + // restore the default texture in one shot for speed + if (fogOfWar && cacheFowAlphaTexture == true) { + if (cacheFowAlphaTextureFogOfWarValue != fogOfWar) { + cacheFowAlphaTexture = false; + } else { + minimap.restoreFowTexAlphaSurface(); + } + } + int resetFowAlphaFactionCount = 0; + + for (int factionIndex = 0; factionIndex < GameConstants::maxPlayers + GameConstants::specialFactions; ++factionIndex) { + if (factionIndex >= getFactionCount()) { + continue; + } + Faction *faction = getFaction(factionIndex); + // for(int indexTeamFaction = 0; + // indexTeamFaction < GameConstants::maxPlayers + GameConstants::specialFactions; + // ++indexTeamFaction) { + + // If fog of war enabled set cell visible to false and later set those close to units to true + if (fogOfWar) { + for (int indexSurfaceW = 0; indexSurfaceW < map.getSurfaceW(); ++indexSurfaceW) { + for (int indexSurfaceH = 0; indexSurfaceH < map.getSurfaceH(); ++indexSurfaceH) { + // set all cells to not visible + map.getSurfaceCell(indexSurfaceW, indexSurfaceH)->setVisible(faction->getTeam(), false); + } + } + } + + // Remove fog of war for factions NOT on my team which i can see + if (!fogOfWar || (faction->getTeam() != thisTeamIndex)) { + bool showWorldForFaction = showWorldForPlayer(factionIndex); + //printf("showWorldForFaction indexFaction = %d thisTeamIndex = %d showWorldForFaction = %d\n",indexFaction,thisTeamIndex,showWorldForFaction); + if (showWorldForFaction == true) { + resetFowAlphaFactionCount++; + } + for (int indexSurfaceW = 0; indexSurfaceW < map.getSurfaceW(); ++indexSurfaceW) { + for (int indexSurfaceH = 0; indexSurfaceH < map.getSurfaceH(); ++indexSurfaceH) { + // reset fog of ware texture alpha values + if (!fogOfWar || (cacheFowAlphaTexture == false && + showWorldForFaction == true && + resetFowAlphaFactionCount <= 1)) { + const Vec2i surfPos(indexSurfaceW, indexSurfaceH); + + //compute max alpha + float maxAlpha = 0.0f; + if (surfPos.x > 1 && surfPos.y > 1 && + surfPos.x < map.getSurfaceW() - 2 && + surfPos.y < map.getSurfaceH() - 2) { + maxAlpha = 1.f; + } else if (surfPos.x > 0 && surfPos.y > 0 && surfPos.x < map.getSurfaceW() - 1 && - surfPos.y < map.getSurfaceH() - 1){ - maxAlpha= 0.3f; - } + surfPos.y < map.getSurfaceH() - 1) { + maxAlpha = 0.3f; + } - // compute alpha - float alpha = maxAlpha; - minimap.incFowTextureAlphaSurface(surfPos, alpha); + // compute alpha + float alpha = maxAlpha; + minimap.incFowTextureAlphaSurface(surfPos, alpha); + } + } + } + } + // Remove fog of war for factions on my team + else if (fogOfWar && (faction->getTeam() == thisTeamIndex)) { + bool showWorldForFaction = showWorldForPlayer(factionIndex); + //printf("#2 showWorldForFaction thisFactionIndex = %d thisTeamIndex = %d showWorldForFaction = %d\n",thisFactionIndex,thisTeamIndex,showWorldForFaction); + if (showWorldForFaction == true) { + for (int indexSurfaceW = 0; indexSurfaceW < map.getSurfaceW(); ++indexSurfaceW) { + for (int indexSurfaceH = 0; indexSurfaceH < map.getSurfaceH(); ++indexSurfaceH) { + // reset fog of ware texture alpha values + if (!fogOfWar || (cacheFowAlphaTexture == false && + showWorldForFaction == true)) { + const Vec2i surfPos(indexSurfaceW, indexSurfaceH); + + //compute max alpha + float maxAlpha = 0.0f; + if (surfPos.x > 1 && surfPos.y > 1 && + surfPos.x < map.getSurfaceW() - 2 && + surfPos.y < map.getSurfaceH() - 2) { + maxAlpha = 1.f; + } else if (surfPos.x > 0 && surfPos.y > 0 && + surfPos.x < map.getSurfaceW() - 1 && + surfPos.y < map.getSurfaceH() - 1) { + maxAlpha = 0.3f; + } + + // compute alpha + float alpha = maxAlpha; + minimap.incFowTextureAlphaSurface(surfPos, alpha); + } + } + } + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] Line: %d in frame: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, getFrameCount()); + } + + // Once we have calculated fog of war texture alpha, will we cache it so that we + // can restore it later + if (fogOfWar && cacheFowAlphaTexture == false && resetFowAlphaFactionCount > 0) { + cacheFowAlphaTexture = true; + cacheFowAlphaTextureFogOfWarValue = fogOfWar; + minimap.copyFowTexAlphaSurface(); + } + + if (this->game) this->game->addPerformanceCount("world reset cells", chronoGamePerformanceCounts.getMillis()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] Line: %d in frame: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, getFrameCount()); + + //compute cells + if (this->game) chronoGamePerformanceCounts.start(); + + for (int factionIndex = 0; factionIndex < getFactionCount(); ++factionIndex) { + Faction *faction = getFaction(factionIndex); + bool cellVisibleForFaction = showWorldForPlayer(thisFactionIndex); + //printf("computeFow thisFactionIndex = %d factionIndex = %d thisTeamIndex = %d faction->getTeam() = %d cellVisibleForFaction = %d\n",thisFactionIndex,factionIndex,thisTeamIndex,faction->getTeam(),cellVisibleForFaction); + + int unitCount = faction->getUnitCount(); + for (int unitIndex = 0; unitIndex < unitCount; ++unitIndex) { + Unit *unit = faction->getUnit(unitIndex); + // exploration + unit->exploreCells(); + + // fire particle visible + ParticleSystem *fire = unit->getFire(); + if (fire != NULL) { + bool cellVisible = cellVisibleForFaction; + if (cellVisible == false) { + Vec2i sCoords = Map::toSurfCoords(unit->getPos()); + SurfaceCell *sc = map.getSurfaceCell(sCoords); + if (sc != NULL) { + cellVisible = sc->isVisible(thisTeamIndex); + } + } + + fire->setActive(cellVisible); + } + + // compute fog of war render texture + if (fogOfWar == true && + faction->getTeam() == thisTeamIndex && + unit->isOperative() == true) { + + //printf("computeFow unit->isOperative() == true\n"); + + const FowAlphaCellsLookupItem &cellList = unit->getCachedFow(); + for (std::map::const_iterator iterMap = cellList.surfPosAlphaList.begin(); + iterMap != cellList.surfPosAlphaList.end(); ++iterMap) { + const Vec2i &surfPos = iterMap->first; + const float &alpha = iterMap->second; + + minimap.incFowTextureAlphaSurface(surfPos, alpha, true); } } } } + + if (this->game) this->game->addPerformanceCount("world compute cells", chronoGamePerformanceCounts.getMillis()); } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] Line: %d in frame: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,getFrameCount()); - } + GameSettings * World::getGameSettingsPtr() { + return (game != NULL ? game->getGameSettings() : NULL); + } - // Once we have calculated fog of war texture alpha, will we cache it so that we - // can restore it later - if(fogOfWar && cacheFowAlphaTexture == false && resetFowAlphaFactionCount > 0) { - cacheFowAlphaTexture = true; - cacheFowAlphaTextureFogOfWarValue = fogOfWar; - minimap.copyFowTexAlphaSurface(); - } + const GameSettings * World::getGameSettings() const { + return (game != NULL ? game->getReadOnlyGameSettings() : NULL); + } - if(this->game) this->game->addPerformanceCount("world reset cells",chronoGamePerformanceCounts.getMillis()); + // WARNING! This id is critical! Make sure it fits inside the network packet + // (currently cannot be larger than 2,147,483,647) + // Make sure each faction has their own unique section of id #'s for proper + // multi-platform play + // Calculates the unit unit ID for each faction + // + int World::getNextUnitId(Faction *faction) { + MutexSafeWrapper safeMutex(mutexFactionNextUnitId, string(__FILE__) + "_" + intToStr(__LINE__)); + if (mapFactionNextUnitId.find(faction->getIndex()) == mapFactionNextUnitId.end()) { + mapFactionNextUnitId[faction->getIndex()] = faction->getIndex() * 100000; + } + return mapFactionNextUnitId[faction->getIndex()]++; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] Line: %d in frame: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,getFrameCount()); + // Get a unique commandid when sending commands to a group of units + int World::getNextCommandGroupId() { + return ++nextCommandGroupId; + } - //compute cells - if(this->game) chronoGamePerformanceCounts.start(); + void World::playStaticVideo(const string &playVideo) { + string calculatedFilePath = playVideo; + bool changed = Properties::applyTagsToValue(calculatedFilePath); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nPlay static video changed: %d [%s] [%s]\n\n", changed, playVideo.c_str(), calculatedFilePath.c_str()); - for(int factionIndex = 0; factionIndex < getFactionCount(); ++factionIndex) { - Faction *faction = getFaction(factionIndex); - bool cellVisibleForFaction = showWorldForPlayer(thisFactionIndex); - //printf("computeFow thisFactionIndex = %d factionIndex = %d thisTeamIndex = %d faction->getTeam() = %d cellVisibleForFaction = %d\n",thisFactionIndex,factionIndex,thisTeamIndex,faction->getTeam(),cellVisibleForFaction); + this->game->playStaticVideo(calculatedFilePath); + } - int unitCount = faction->getUnitCount(); - for(int unitIndex = 0; unitIndex < unitCount; ++unitIndex) { - Unit *unit= faction->getUnit(unitIndex); - // exploration - unit->exploreCells(); + void World::playStreamingVideo(const string &playVideo) { + string calculatedFilePath = playVideo; + bool changed = Properties::applyTagsToValue(calculatedFilePath); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nPlay streaming video changed: %d [%s] [%s]\n\n", changed, playVideo.c_str(), calculatedFilePath.c_str()); - // fire particle visible - ParticleSystem *fire = unit->getFire(); - if(fire != NULL) { - bool cellVisible = cellVisibleForFaction; - if(cellVisible == false) { - Vec2i sCoords = Map::toSurfCoords(unit->getPos()); - SurfaceCell *sc = map.getSurfaceCell(sCoords); - if(sc != NULL) { - cellVisible = sc->isVisible(thisTeamIndex); + this->game->playStreamingVideo(calculatedFilePath); + } + + void World::stopStreamingVideo(const string &playVideo) { + string calculatedFilePath = playVideo; + bool changed = Properties::applyTagsToValue(calculatedFilePath); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nStop streaming video changed: %d [%s] [%s]\n\n", changed, playVideo.c_str(), calculatedFilePath.c_str()); + + this->game->stopStreamingVideo(calculatedFilePath); + } + + void World::stopAllVideo() { + this->game->stopAllVideo(); + } + + void World::initTeamResource(const ResourceType *rt, int teamIndex, int value) { + std::string resourceTypeName = rt->getName(false); + TeamResources[teamIndex][resourceTypeName].init(rt, value); + } + + const Resource *World::getResourceForTeam(const ResourceType *rt, int teamIndex) { + if (rt == NULL) { + return NULL; + } + + std::map &resourceList = TeamResources[teamIndex]; + std::string resourceTypeName = rt->getName(false); + resourceList[resourceTypeName].init(rt, 0); + Resource &teamResource = resourceList[resourceTypeName]; + + for (int index = 0; index < (int) factions.size(); ++index) { + + Faction *faction = factions[index]; + if (faction != NULL && faction->getTeam() == teamIndex) { + const Resource *factionResource = faction->getResource(rt, true); + if (factionResource != NULL && factionResource->getType() != NULL) { + + int teamResourceAmount = teamResource.getAmount(); + int teamResourceBalance = teamResource.getBalance(); + + teamResource.setAmount(teamResourceAmount + factionResource->getAmount()); + teamResource.setBalance(teamResourceBalance + factionResource->getBalance()); } } - - fire->setActive(cellVisible); } - // compute fog of war render texture - if(fogOfWar == true && - faction->getTeam() == thisTeamIndex && - unit->isOperative() == true) { + return &teamResource; + } - //printf("computeFow unit->isOperative() == true\n"); + int World::getStoreAmountForTeam(const ResourceType *rt, int teamIndex) const { - const FowAlphaCellsLookupItem &cellList = unit->getCachedFow(); - for(std::map::const_iterator iterMap = cellList.surfPosAlphaList.begin(); - iterMap != cellList.surfPosAlphaList.end(); ++iterMap) { - const Vec2i &surfPos = iterMap->first; - const float &alpha = iterMap->second; + int teamStoreAmount = 0; + for (int index = 0; index < (int) factions.size(); ++index) { - minimap.incFowTextureAlphaSurface(surfPos, alpha, true); + Faction *faction = factions[index]; + if (faction != NULL && faction->getTeam() == teamIndex) { + + teamStoreAmount += faction->getStoreAmount(rt, true); } } + + return teamStoreAmount; } - } - if(this->game) this->game->addPerformanceCount("world compute cells",chronoGamePerformanceCounts.getMillis()); -} + bool World::showResourceTypeForTeam(const ResourceType *rt, int teamIndex) const { + //if any unit produces the resource + bool showResource = false; + for (int index = 0; showResource == false && index < (int) factions.size(); ++index) { + const Faction *teamFaction = factions[index]; + if (teamFaction != NULL && teamFaction->getTeam() == teamIndex) { -GameSettings * World::getGameSettingsPtr() { - return (game != NULL ? game->getGameSettings() : NULL); -} - -const GameSettings * World::getGameSettings() const { - return (game != NULL ? game->getReadOnlyGameSettings() : NULL); -} - -// WARNING! This id is critical! Make sure it fits inside the network packet -// (currently cannot be larger than 2,147,483,647) -// Make sure each faction has their own unique section of id #'s for proper -// multi-platform play -// Calculates the unit unit ID for each faction -// -int World::getNextUnitId(Faction *faction) { - MutexSafeWrapper safeMutex(mutexFactionNextUnitId,string(__FILE__) + "_" + intToStr(__LINE__)); - if(mapFactionNextUnitId.find(faction->getIndex()) == mapFactionNextUnitId.end()) { - mapFactionNextUnitId[faction->getIndex()] = faction->getIndex() * 100000; - } - return mapFactionNextUnitId[faction->getIndex()]++; -} - -// Get a unique commandid when sending commands to a group of units -int World::getNextCommandGroupId() { - return ++nextCommandGroupId; -} - -void World::playStaticVideo(const string &playVideo) { - string calculatedFilePath = playVideo; - bool changed = Properties::applyTagsToValue(calculatedFilePath); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nPlay static video changed: %d [%s] [%s]\n\n",changed, playVideo.c_str(),calculatedFilePath.c_str()); - - this->game->playStaticVideo(calculatedFilePath); -} - -void World::playStreamingVideo(const string &playVideo) { - string calculatedFilePath = playVideo; - bool changed = Properties::applyTagsToValue(calculatedFilePath); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nPlay streaming video changed: %d [%s] [%s]\n\n",changed, playVideo.c_str(),calculatedFilePath.c_str()); - - this->game->playStreamingVideo(calculatedFilePath); -} - -void World::stopStreamingVideo(const string &playVideo) { - string calculatedFilePath = playVideo; - bool changed = Properties::applyTagsToValue(calculatedFilePath); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nStop streaming video changed: %d [%s] [%s]\n\n",changed, playVideo.c_str(),calculatedFilePath.c_str()); - - this->game->stopStreamingVideo(calculatedFilePath); -} - -void World::stopAllVideo() { - this->game->stopAllVideo(); -} - -void World::initTeamResource(const ResourceType *rt,int teamIndex, int value) { - std::string resourceTypeName = rt->getName(false); - TeamResources[teamIndex][resourceTypeName].init(rt,value); -} - -const Resource *World::getResourceForTeam(const ResourceType *rt, int teamIndex) { - if(rt == NULL) { - return NULL; - } - - std::map &resourceList = TeamResources[teamIndex]; - std::string resourceTypeName = rt->getName(false); - resourceList[resourceTypeName].init(rt,0); - Resource &teamResource = resourceList[resourceTypeName]; - - for(int index = 0; index < (int)factions.size(); ++index) { - - Faction *faction = factions[index]; - if(faction != NULL && faction->getTeam() == teamIndex) { - const Resource *factionResource = faction->getResource(rt,true); - if(factionResource != NULL && factionResource->getType() != NULL) { - - int teamResourceAmount = teamResource.getAmount(); - int teamResourceBalance = teamResource.getBalance(); - - teamResource.setAmount(teamResourceAmount + factionResource->getAmount()); - teamResource.setBalance(teamResourceBalance + factionResource->getBalance()); + if (teamFaction->hasUnitTypeWithResourceCostInCache(rt) == true) { + showResource = true; + } + } } + return showResource; } - } - - return &teamResource; -} - -int World::getStoreAmountForTeam(const ResourceType *rt, int teamIndex) const { - - int teamStoreAmount = 0; - for(int index = 0; index < (int)factions.size(); ++index) { - - Faction *faction = factions[index]; - if(faction != NULL && faction->getTeam() == teamIndex) { - - teamStoreAmount += faction->getStoreAmount(rt,true); - } - } - - return teamStoreAmount; -} - -bool World::showResourceTypeForTeam(const ResourceType *rt, int teamIndex) const { - //if any unit produces the resource - bool showResource = false; - for(int index = 0; showResource == false && index < (int)factions.size(); ++index) { - const Faction *teamFaction = factions[index]; - if(teamFaction != NULL && teamFaction->getTeam() == teamIndex) { - - if(teamFaction->hasUnitTypeWithResourceCostInCache(rt) == true) { - showResource = true; - } - } - } - return showResource; -} -bool World::showResourceTypeForFaction(const ResourceType *rt, const Faction *faction) const { - //if any unit produces the resource - bool showResource = false; - for(int factionUnitTypeIndex = 0; - factionUnitTypeIndex < faction->getType()->getUnitTypeCount(); + bool World::showResourceTypeForFaction(const ResourceType *rt, const Faction *faction) const { + //if any unit produces the resource + bool showResource = false; + for (int factionUnitTypeIndex = 0; + factionUnitTypeIndex < faction->getType()->getUnitTypeCount(); ++factionUnitTypeIndex) { - const UnitType *ut = faction->getType()->getUnitType(factionUnitTypeIndex); - if(ut->getCost(rt) != NULL) { - showResource = true; - break; - } - } - return showResource; -} - -void World::removeResourceTargetFromCache(const Vec2i &pos) { - for(int i= 0; i < (int)factions.size(); ++i) { - factions[i]->removeResourceTargetFromCache(pos); - } -} - -string World::getExploredCellsLookupItemCacheStats() { - string result = ""; - - int posCount = 0; - int sightCount = 0; - int exploredCellCount = 0; - int visibleCellCount = 0; - - for(std::map >::iterator iterMap1 = ExploredCellsLookupItemCache.begin(); - iterMap1 != ExploredCellsLookupItemCache.end(); ++iterMap1) { - posCount++; - - for(std::map::iterator iterMap2 = iterMap1->second.begin(); - iterMap2 != iterMap1->second.end(); ++iterMap2) { - sightCount++; - - exploredCellCount += (int)iterMap2->second.exploredCellList.size(); - visibleCellCount += (int)iterMap2->second.visibleCellList.size(); - } - } - - uint64 totalBytes = exploredCellCount * sizeof(SurfaceCell *); - totalBytes += visibleCellCount * sizeof(SurfaceCell *); - - totalBytes /= 1000; - - char szBuf[8096]=""; - snprintf(szBuf,8096,"pos [%d] sight [%d] [%d][%d] total KB: %s",posCount,sightCount,exploredCellCount,visibleCellCount,formatNumber(totalBytes).c_str()); - result = szBuf; - return result; -} - -string World::getFowAlphaCellsLookupItemCacheStats() { - string result = ""; - - int surfPosAlphaCount = 0; - - for(int factionIndex = 0; factionIndex < getFactionCount(); ++factionIndex) { - Faction *faction= getFaction(factionIndex); - if(faction->getTeam() == thisTeamIndex) { - for(int unitIndex = 0; unitIndex < faction->getUnitCount(); ++unitIndex) { - const Unit *unit= faction->getUnit(unitIndex); - const FowAlphaCellsLookupItem &cache = unit->getCachedFow(); - - surfPosAlphaCount += (int)cache.surfPosAlphaList.size(); - } - } - } - uint64 totalBytes = surfPosAlphaCount * sizeof(Vec2i); - totalBytes += surfPosAlphaCount * sizeof(float); - - totalBytes /= 1000; - - char szBuf[8096]=""; - snprintf(szBuf,8096,"surface count [%d] total KB: %s",surfPosAlphaCount,formatNumber(totalBytes).c_str()); - result = szBuf; - return result; -} - -string World::getAllFactionsCacheStats() { - string result = ""; - - uint64 totalBytes = 0; - uint64 totalCache1Size = 0; - uint64 totalCache2Size = 0; - uint64 totalCache3Size = 0; - uint64 totalCache4Size = 0; - uint64 totalCache5Size = 0; - for(int i = 0; i < getFactionCount(); ++i) { - uint64 cache1Size = 0; - uint64 cache2Size = 0; - uint64 cache3Size = 0; - uint64 cache4Size = 0; - uint64 cache5Size = 0; - - totalBytes += getFaction(i)->getCacheKBytes(&cache1Size,&cache2Size,&cache3Size,&cache4Size,&cache5Size); - totalCache1Size += cache1Size; - totalCache2Size += cache2Size; - totalCache3Size += cache3Size; - totalCache4Size += cache4Size; - totalCache5Size += cache5Size; - } - - char szBuf[8096]=""; - snprintf(szBuf,8096,"Cache1 [%llu] Cache2 [%llu] Cache3 [%llu] Cache4 [%llu] Cache5 [%llu] total KB: %s", - (long long unsigned)totalCache1Size,(long long unsigned)totalCache2Size,(long long unsigned)totalCache3Size, - (long long unsigned)totalCache4Size,(long long unsigned)totalCache5Size,formatNumber(totalBytes).c_str()); - result = szBuf; - return result; -} - -bool World::factionLostGame(int factionIndex) { - if(this->game != NULL) { - return this->game->factionLostGame(factionIndex); - } - return false; -} - -std::string World::DumpWorldToLog(bool consoleBasicInfoOnly) const { - - string debugWorldLogFile = Config::getInstance().getString("DebugWorldLogFile","debugWorld.log"); - if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { - debugWorldLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugWorldLogFile; - } - else { - string userData = Config::getInstance().getString("UserData_Root",""); - if(userData != "") { - endPathWithSlash(userData); - } - debugWorldLogFile = userData + debugWorldLogFile; - } - - if(consoleBasicInfoOnly == true) { - std::cout << "World debug information:" << std::endl; - std::cout << "========================" << std::endl; - - //factions (and their related info) - for(int i = 0; i < getFactionCount(); ++i) { - std::cout << "Faction detail for index: " << i << std::endl; - std::cout << "--------------------------" << std::endl; - - std::cout << "FactionName = " << getFaction(i)->getType()->getName(false) << std::endl; - std::cout << "FactionIndex = " << intToStr(getFaction(i)->getIndex()) << std::endl; - std::cout << "teamIndex = " << intToStr(getFaction(i)->getTeam()) << std::endl; - std::cout << "startLocationIndex = " << intToStr(getFaction(i)->getStartLocationIndex()) << std::endl; - std::cout << "thisFaction = " << intToStr(getFaction(i)->getThisFaction()) << std::endl; - std::cout << "control = " << intToStr(getFaction(i)->getControlType()) << std::endl; - } - } - else { - -#if defined(WIN32) && !defined(__MINGW32__) - FILE *fp = _wfopen(utf8_decode(debugWorldLogFile).c_str(), L"w"); - std::ofstream logFile(fp); -#else - std::ofstream logFile; - logFile.open(debugWorldLogFile.c_str(), ios_base::out | ios_base::trunc); -#endif - logFile << "World debug information:" << std::endl; - logFile << "========================" << std::endl; - - //factions (and their related info) - for(int i = 0; i < getFactionCount(); ++i) { - logFile << "Faction detail for index: " << i << std::endl; - logFile << "--------------------------" << std::endl; - logFile << getFaction(i)->toString() << std::endl; - } - - //undertake the dead - logFile << "Undertake stats:" << std::endl; - for(int i = 0; i < getFactionCount(); ++i){ - logFile << "Faction: " << getFaction(i)->getType()->getName(false) << std::endl; - int unitCount = getFaction(i)->getUnitCount(); - for(int j= unitCount - 1; j >= 0; j--){ - Unit *unit= getFaction(i)->getUnit(j); - if(unit->getToBeUndertaken()) { - logFile << "Undertake unit index = " << j << unit->getFullName(false) << std::endl; + const UnitType *ut = faction->getType()->getUnitType(factionUnitTypeIndex); + if (ut->getCost(rt) != NULL) { + showResource = true; + break; } } + return showResource; } - logFile.close(); + void World::removeResourceTargetFromCache(const Vec2i &pos) { + for (int i = 0; i < (int) factions.size(); ++i) { + factions[i]->removeResourceTargetFromCache(pos); + } + } + + string World::getExploredCellsLookupItemCacheStats() { + string result = ""; + + int posCount = 0; + int sightCount = 0; + int exploredCellCount = 0; + int visibleCellCount = 0; + + for (std::map >::iterator iterMap1 = ExploredCellsLookupItemCache.begin(); + iterMap1 != ExploredCellsLookupItemCache.end(); ++iterMap1) { + posCount++; + + for (std::map::iterator iterMap2 = iterMap1->second.begin(); + iterMap2 != iterMap1->second.end(); ++iterMap2) { + sightCount++; + + exploredCellCount += (int) iterMap2->second.exploredCellList.size(); + visibleCellCount += (int) iterMap2->second.visibleCellList.size(); + } + } + + uint64 totalBytes = exploredCellCount * sizeof(SurfaceCell *); + totalBytes += visibleCellCount * sizeof(SurfaceCell *); + + totalBytes /= 1000; + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "pos [%d] sight [%d] [%d][%d] total KB: %s", posCount, sightCount, exploredCellCount, visibleCellCount, formatNumber(totalBytes).c_str()); + result = szBuf; + return result; + } + + string World::getFowAlphaCellsLookupItemCacheStats() { + string result = ""; + + int surfPosAlphaCount = 0; + + for (int factionIndex = 0; factionIndex < getFactionCount(); ++factionIndex) { + Faction *faction = getFaction(factionIndex); + if (faction->getTeam() == thisTeamIndex) { + for (int unitIndex = 0; unitIndex < faction->getUnitCount(); ++unitIndex) { + const Unit *unit = faction->getUnit(unitIndex); + const FowAlphaCellsLookupItem &cache = unit->getCachedFow(); + + surfPosAlphaCount += (int) cache.surfPosAlphaList.size(); + } + } + } + uint64 totalBytes = surfPosAlphaCount * sizeof(Vec2i); + totalBytes += surfPosAlphaCount * sizeof(float); + + totalBytes /= 1000; + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "surface count [%d] total KB: %s", surfPosAlphaCount, formatNumber(totalBytes).c_str()); + result = szBuf; + return result; + } + + string World::getAllFactionsCacheStats() { + string result = ""; + + uint64 totalBytes = 0; + uint64 totalCache1Size = 0; + uint64 totalCache2Size = 0; + uint64 totalCache3Size = 0; + uint64 totalCache4Size = 0; + uint64 totalCache5Size = 0; + for (int i = 0; i < getFactionCount(); ++i) { + uint64 cache1Size = 0; + uint64 cache2Size = 0; + uint64 cache3Size = 0; + uint64 cache4Size = 0; + uint64 cache5Size = 0; + + totalBytes += getFaction(i)->getCacheKBytes(&cache1Size, &cache2Size, &cache3Size, &cache4Size, &cache5Size); + totalCache1Size += cache1Size; + totalCache2Size += cache2Size; + totalCache3Size += cache3Size; + totalCache4Size += cache4Size; + totalCache5Size += cache5Size; + } + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Cache1 [%llu] Cache2 [%llu] Cache3 [%llu] Cache4 [%llu] Cache5 [%llu] total KB: %s", + (long long unsigned)totalCache1Size, (long long unsigned)totalCache2Size, (long long unsigned)totalCache3Size, + (long long unsigned)totalCache4Size, (long long unsigned)totalCache5Size, formatNumber(totalBytes).c_str()); + result = szBuf; + return result; + } + + bool World::factionLostGame(int factionIndex) { + if (this->game != NULL) { + return this->game->factionLostGame(factionIndex); + } + return false; + } + + std::string World::DumpWorldToLog(bool consoleBasicInfoOnly) const { + + string debugWorldLogFile = Config::getInstance().getString("DebugWorldLogFile", "debugWorld.log"); + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { + debugWorldLogFile = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + debugWorldLogFile; + } else { + string userData = Config::getInstance().getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + debugWorldLogFile = userData + debugWorldLogFile; + } + + if (consoleBasicInfoOnly == true) { + std::cout << "World debug information:" << std::endl; + std::cout << "========================" << std::endl; + + //factions (and their related info) + for (int i = 0; i < getFactionCount(); ++i) { + std::cout << "Faction detail for index: " << i << std::endl; + std::cout << "--------------------------" << std::endl; + + std::cout << "FactionName = " << getFaction(i)->getType()->getName(false) << std::endl; + std::cout << "FactionIndex = " << intToStr(getFaction(i)->getIndex()) << std::endl; + std::cout << "teamIndex = " << intToStr(getFaction(i)->getTeam()) << std::endl; + std::cout << "startLocationIndex = " << intToStr(getFaction(i)->getStartLocationIndex()) << std::endl; + std::cout << "thisFaction = " << intToStr(getFaction(i)->getThisFaction()) << std::endl; + std::cout << "control = " << intToStr(getFaction(i)->getControlType()) << std::endl; + } + } else { + #if defined(WIN32) && !defined(__MINGW32__) - if(fp) { - fclose(fp); - } + FILE *fp = _wfopen(utf8_decode(debugWorldLogFile).c_str(), L"w"); + std::ofstream logFile(fp); +#else + std::ofstream logFile; + logFile.open(debugWorldLogFile.c_str(), ios_base::out | ios_base::trunc); #endif + logFile << "World debug information:" << std::endl; + logFile << "========================" << std::endl; + + //factions (and their related info) + for (int i = 0; i < getFactionCount(); ++i) { + logFile << "Faction detail for index: " << i << std::endl; + logFile << "--------------------------" << std::endl; + logFile << getFaction(i)->toString() << std::endl; + } + + //undertake the dead + logFile << "Undertake stats:" << std::endl; + for (int i = 0; i < getFactionCount(); ++i) { + logFile << "Faction: " << getFaction(i)->getType()->getName(false) << std::endl; + int unitCount = getFaction(i)->getUnitCount(); + for (int j = unitCount - 1; j >= 0; j--) { + Unit *unit = getFaction(i)->getUnit(j); + if (unit->getToBeUndertaken()) { + logFile << "Undertake unit index = " << j << unit->getFullName(false) << std::endl; + } + } + } + + logFile.close(); +#if defined(WIN32) && !defined(__MINGW32__) + if (fp) { + fclose(fp); + } +#endif + } + + //printf("Check savegame\n"); + if (this->game != NULL) { + //printf("Saving...\n"); + this->game->saveGame(GameConstants::saveGameFileDefault); + } + + return debugWorldLogFile; + } + + void World::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *worldNode = rootNode->addChild("World"); + + // Map map; + map.saveGame(worldNode); + // Tileset tileset; + worldNode->addAttribute("tileset", tileset.getName(), mapTagReplacements); + // //TechTree techTree; + // TechTree *techTree; + if (techTree != NULL) { + techTree->saveGame(worldNode); + } + worldNode->addAttribute("techTree", (techTree != NULL ? techTree->getName() : ""), mapTagReplacements); + // TimeFlow timeFlow; + timeFlow.saveGame(worldNode); + // Scenario scenario; + // + // UnitUpdater unitUpdater; + unitUpdater.saveGame(worldNode); + // WaterEffects waterEffects; + // WaterEffects attackEffects; // onMiniMap + // Minimap minimap; + minimap.saveGame(worldNode); + // Stats stats; //BattleEnd will delete this object + stats.saveGame(worldNode); + // + // Factions factions; + for (unsigned int i = 0; i < factions.size(); ++i) { + factions[i]->saveGame(worldNode); + } + // RandomGen random; + worldNode->addAttribute("random", intToStr(random.getLastNumber()), mapTagReplacements); + // ScriptManager* scriptManager; + // + // int thisFactionIndex; + worldNode->addAttribute("thisFactionIndex", intToStr(thisFactionIndex), mapTagReplacements); + // int thisTeamIndex; + worldNode->addAttribute("thisTeamIndex", intToStr(thisTeamIndex), mapTagReplacements); + // int frameCount; + worldNode->addAttribute("frameCount", intToStr(frameCount), mapTagReplacements); + // //int nextUnitId; + // Mutex mutexFactionNextUnitId; + MutexSafeWrapper safeMutex(mutexFactionNextUnitId, string(__FILE__) + "_" + intToStr(__LINE__)); + // std::map mapFactionNextUnitId; + for (std::map::iterator iterMap = mapFactionNextUnitId.begin(); + iterMap != mapFactionNextUnitId.end(); ++iterMap) { + XmlNode *factionNextUnitIdNode = worldNode->addChild("FactionNextUnitId"); + + factionNextUnitIdNode->addAttribute("key", intToStr(iterMap->first), mapTagReplacements); + factionNextUnitIdNode->addAttribute("value", intToStr(iterMap->second), mapTagReplacements); + } + safeMutex.ReleaseLock(); + // //config + // bool fogOfWarOverride; + worldNode->addAttribute("fogOfWarOverride", intToStr(fogOfWarOverride), mapTagReplacements); + // bool fogOfWar; + worldNode->addAttribute("fogOfWar", intToStr(fogOfWar), mapTagReplacements); + // int fogOfWarSmoothingFrameSkip; + worldNode->addAttribute("fogOfWarSmoothingFrameSkip", intToStr(fogOfWarSmoothingFrameSkip), mapTagReplacements); + // bool fogOfWarSmoothing; + worldNode->addAttribute("fogOfWarSmoothing", intToStr(fogOfWarSmoothing), mapTagReplacements); + // Game *game; + // Chrono chronoPerfTimer; + // bool perfTimerEnabled; + // + // bool unitParticlesEnabled; + worldNode->addAttribute("unitParticlesEnabled", intToStr(unitParticlesEnabled), mapTagReplacements); + // std::map staticSoundList; + // std::map streamSoundList; + // + // uint32 nextCommandGroupId; + worldNode->addAttribute("nextCommandGroupId", intToStr(nextCommandGroupId), mapTagReplacements); + // string queuedScenarioName; + worldNode->addAttribute("queuedScenarioName", queuedScenarioName, mapTagReplacements); + // bool queuedScenarioKeepFactions; + worldNode->addAttribute("queuedScenarioKeepFactions", intToStr(queuedScenarioKeepFactions), mapTagReplacements); + + worldNode->addAttribute("disableAttackEffects", intToStr(disableAttackEffects), mapTagReplacements); + } + + void World::loadGame(const XmlNode *rootNode) { + loadWorldNode = rootNode; + } + } - - //printf("Check savegame\n"); - if(this->game != NULL) { - //printf("Saving...\n"); - this->game->saveGame(GameConstants::saveGameFileDefault); - } - - return debugWorldLogFile; -} - -void World::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *worldNode = rootNode->addChild("World"); - -// Map map; - map.saveGame(worldNode); -// Tileset tileset; - worldNode->addAttribute("tileset",tileset.getName(), mapTagReplacements); -// //TechTree techTree; -// TechTree *techTree; - if(techTree != NULL) { - techTree->saveGame(worldNode); - } - worldNode->addAttribute("techTree",(techTree != NULL ? techTree->getName() : ""), mapTagReplacements); -// TimeFlow timeFlow; - timeFlow.saveGame(worldNode); -// Scenario scenario; -// -// UnitUpdater unitUpdater; - unitUpdater.saveGame(worldNode); -// WaterEffects waterEffects; -// WaterEffects attackEffects; // onMiniMap -// Minimap minimap; - minimap.saveGame(worldNode); -// Stats stats; //BattleEnd will delete this object - stats.saveGame(worldNode); -// -// Factions factions; - for(unsigned int i = 0; i < factions.size(); ++i) { - factions[i]->saveGame(worldNode); - } -// RandomGen random; - worldNode->addAttribute("random",intToStr(random.getLastNumber()), mapTagReplacements); -// ScriptManager* scriptManager; -// -// int thisFactionIndex; - worldNode->addAttribute("thisFactionIndex",intToStr(thisFactionIndex), mapTagReplacements); -// int thisTeamIndex; - worldNode->addAttribute("thisTeamIndex",intToStr(thisTeamIndex), mapTagReplacements); -// int frameCount; - worldNode->addAttribute("frameCount",intToStr(frameCount), mapTagReplacements); -// //int nextUnitId; -// Mutex mutexFactionNextUnitId; - MutexSafeWrapper safeMutex(mutexFactionNextUnitId,string(__FILE__) + "_" + intToStr(__LINE__)); -// std::map mapFactionNextUnitId; - for(std::map::iterator iterMap = mapFactionNextUnitId.begin(); - iterMap != mapFactionNextUnitId.end(); ++iterMap) { - XmlNode *factionNextUnitIdNode = worldNode->addChild("FactionNextUnitId"); - - factionNextUnitIdNode->addAttribute("key",intToStr(iterMap->first), mapTagReplacements); - factionNextUnitIdNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); - } - safeMutex.ReleaseLock(); -// //config -// bool fogOfWarOverride; - worldNode->addAttribute("fogOfWarOverride",intToStr(fogOfWarOverride), mapTagReplacements); -// bool fogOfWar; - worldNode->addAttribute("fogOfWar",intToStr(fogOfWar), mapTagReplacements); -// int fogOfWarSmoothingFrameSkip; - worldNode->addAttribute("fogOfWarSmoothingFrameSkip",intToStr(fogOfWarSmoothingFrameSkip), mapTagReplacements); -// bool fogOfWarSmoothing; - worldNode->addAttribute("fogOfWarSmoothing",intToStr(fogOfWarSmoothing), mapTagReplacements); -// Game *game; -// Chrono chronoPerfTimer; -// bool perfTimerEnabled; -// -// bool unitParticlesEnabled; - worldNode->addAttribute("unitParticlesEnabled",intToStr(unitParticlesEnabled), mapTagReplacements); -// std::map staticSoundList; -// std::map streamSoundList; -// -// uint32 nextCommandGroupId; - worldNode->addAttribute("nextCommandGroupId",intToStr(nextCommandGroupId), mapTagReplacements); -// string queuedScenarioName; - worldNode->addAttribute("queuedScenarioName",queuedScenarioName, mapTagReplacements); -// bool queuedScenarioKeepFactions; - worldNode->addAttribute("queuedScenarioKeepFactions",intToStr(queuedScenarioKeepFactions), mapTagReplacements); - - worldNode->addAttribute("disableAttackEffects",intToStr(disableAttackEffects), mapTagReplacements); -} - -void World::loadGame(const XmlNode *rootNode) { - loadWorldNode = rootNode; -} - -}}//end namespace +}//end namespace diff --git a/source/glest_game/world/world.h b/source/glest_game/world/world.h index 62b45659f..07a5aa596 100644 --- a/source/glest_game/world/world.h +++ b/source/glest_game/world/world.h @@ -24,8 +24,8 @@ #define _GLEST_GAME_WORLD_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include "vec.h" @@ -48,320 +48,382 @@ #include "game_constants.h" #include "leak_dumper.h" -namespace Glest{ namespace Game{ +namespace Glest { + namespace Game { -using Shared::Graphics::Quad2i; -using Shared::Graphics::Rect2i; -using Shared::Util::RandomGen; + using Shared::Graphics::Quad2i; + using Shared::Graphics::Rect2i; + using Shared::Util::RandomGen; -class Faction; -class Unit; -class Config; -class Game; -class GameSettings; -class ScriptManager; + class Faction; + class Unit; + class Config; + class Game; + class GameSettings; + class ScriptManager; -namespace Shared{ namespace Sound{ -class StaticSound; -class StrSound; -}}; + namespace Shared { + namespace Sound { + class StaticSound; + class StrSound; + } + }; -// ===================================================== -// class World -// -/// The game world: Map + Tileset + TechTree -// ===================================================== + // ===================================================== + // class World + // + /// The game world: Map + Tileset + TechTree + // ===================================================== -class ExploredCellsLookupKey { -public: + class ExploredCellsLookupKey { + public: - Vec2i pos; - int sightRange; - int teamIndex; -}; + Vec2i pos; + int sightRange; + int teamIndex; + }; -class World { -private: - typedef vector Factions; + class World { + private: + typedef vector Factions; - std::map > ExploredCellsLookupItemCache; - std::map ExploredCellsLookupItemCacheTimer; - int ExploredCellsLookupItemCacheTimerCount; + std::map > ExploredCellsLookupItemCache; + std::map ExploredCellsLookupItemCacheTimer; + int ExploredCellsLookupItemCacheTimerCount; -public: - static const int generationArea= 100; - static const int indirectSightRange= 5; + public: + static const int generationArea = 100; + static const int indirectSightRange = 5; -private: + private: - Map map; - Tileset tileset; - TechTree *techTree; - TimeFlow timeFlow; - Scenario scenario; + Map map; + Tileset tileset; + TechTree *techTree; + TimeFlow timeFlow; + Scenario scenario; - UnitUpdater unitUpdater; - WaterEffects waterEffects; - WaterEffects attackEffects; // onMiniMap - Minimap minimap; - Stats stats; //BattleEnd will delete this object + UnitUpdater unitUpdater; + WaterEffects waterEffects; + WaterEffects attackEffects; // onMiniMap + Minimap minimap; + Stats stats; //BattleEnd will delete this object - Factions factions; + Factions factions; - RandomGen random; + RandomGen random; - ScriptManager* scriptManager; + ScriptManager* scriptManager; - int thisFactionIndex; - int thisTeamIndex; - int frameCount; - Mutex *mutexFactionNextUnitId; - std::map mapFactionNextUnitId; + int thisFactionIndex; + int thisTeamIndex; + int frameCount; + Mutex *mutexFactionNextUnitId; + std::map mapFactionNextUnitId; - //config - bool fogOfWarOverride; - bool fogOfWar; - int fogOfWarSmoothingFrameSkip; - bool fogOfWarSmoothing; - int fogOfWarSkillTypeValue; + //config + bool fogOfWarOverride; + bool fogOfWar; + int fogOfWarSmoothingFrameSkip; + bool fogOfWarSmoothing; + int fogOfWarSkillTypeValue; - Game *game; - Chrono chronoPerfTimer; - bool perfTimerEnabled; + Game *game; + Chrono chronoPerfTimer; + bool perfTimerEnabled; - bool unitParticlesEnabled; - std::map staticSoundList; - std::map streamSoundList; + bool unitParticlesEnabled; + std::map staticSoundList; + std::map streamSoundList; - uint32 nextCommandGroupId; + uint32 nextCommandGroupId; - string queuedScenarioName; - bool queuedScenarioKeepFactions; + string queuedScenarioName; + bool queuedScenarioKeepFactions; - bool disableAttackEffects; + bool disableAttackEffects; - const XmlNode *loadWorldNode; + const XmlNode *loadWorldNode; - MasterSlaveThreadController masterController; + MasterSlaveThreadController masterController; - bool originalGameFogOfWar; - std::map > mapFogOfWarUnitList; + bool originalGameFogOfWar; + std::map > mapFogOfWarUnitList; - bool animatedTilesetObjectPosListLoaded; - std::vector animatedTilesetObjectPosList; + bool animatedTilesetObjectPosListLoaded; + std::vector animatedTilesetObjectPosList; - bool cacheFowAlphaTexture; - bool cacheFowAlphaTextureFogOfWarValue; + bool cacheFowAlphaTexture; + bool cacheFowAlphaTextureFogOfWarValue; - std::map > TeamResources; + std::map > TeamResources; -public: - World(); - ~World(); -// World & World(World &obj) { -// throw runtime_error("class World is NOT safe to assign!"); -// } - void cleanup(); - void end(); //to die before selection does - void endScenario(); //to die before selection does + public: + World(); + ~World(); + // World & World(World &obj) { + // throw runtime_error("class World is NOT safe to assign!"); + // } + void cleanup(); + void end(); //to die before selection does + void endScenario(); //to die before selection does - void addFogOfWarSkillType(const Unit *unit,const FogOfWarSkillType *fowst); - void removeFogOfWarSkillType(const Unit *unit); - bool removeFogOfWarSkillTypeFromList(const Unit *unit); + void addFogOfWarSkillType(const Unit *unit, const FogOfWarSkillType *fowst); + void removeFogOfWarSkillType(const Unit *unit); + bool removeFogOfWarSkillTypeFromList(const Unit *unit); - //get - inline int getMaxPlayers() const {return map.getMaxPlayers();} - inline int getThisFactionIndex() const {return thisFactionIndex;} + //get + inline int getMaxPlayers() const { + return map.getMaxPlayers(); + } + inline int getThisFactionIndex() const { + return thisFactionIndex; + } - inline int getThisTeamIndex() const {return thisTeamIndex;} - inline void setThisTeamIndex(int team) { thisTeamIndex=team;} + inline int getThisTeamIndex() const { + return thisTeamIndex; + } + inline void setThisTeamIndex(int team) { + thisTeamIndex = team; + } - inline const Faction *getThisFaction() const {return (thisFactionIndex >= 0 ? factions[thisFactionIndex] : NULL);} - inline Faction *getThisFactionPtr() {return (thisFactionIndex >= 0 ? factions[thisFactionIndex] : NULL);} + inline const Faction *getThisFaction() const { + return (thisFactionIndex >= 0 ? factions[thisFactionIndex] : NULL); + } + inline Faction *getThisFactionPtr() { + return (thisFactionIndex >= 0 ? factions[thisFactionIndex] : NULL); + } - inline int getFactionCount() const {return (int)factions.size();} - inline const Map *getMap() const {return ↦} - inline Map *getMapPtr() {return ↦} + inline int getFactionCount() const { + return (int) factions.size(); + } + inline const Map *getMap() const { + return ↦ + } + inline Map *getMapPtr() { + return ↦ + } - inline const Tileset *getTileset() const {return &tileset;} - inline const TechTree *getTechTree() const {return techTree;} - inline const Scenario *getScenario() const {return &scenario;} - inline const TimeFlow *getTimeFlow() const {return &timeFlow;} - inline Tileset *getTileset() {return &tileset;} - inline Map *getMap() {return ↦} - inline const Faction *getFaction(int i) const {return factions[i];} - inline Faction *getFaction(int i) {return factions[i];} - inline const Minimap *getMinimap() const {return &minimap;} - inline Minimap *getMiniMapObject() {return &minimap;} + inline const Tileset *getTileset() const { + return &tileset; + } + inline const TechTree *getTechTree() const { + return techTree; + } + inline const Scenario *getScenario() const { + return &scenario; + } + inline const TimeFlow *getTimeFlow() const { + return &timeFlow; + } + inline Tileset *getTileset() { + return &tileset; + } + inline Map *getMap() { + return ↦ + } + inline const Faction *getFaction(int i) const { + return factions[i]; + } + inline Faction *getFaction(int i) { + return factions[i]; + } + inline const Minimap *getMinimap() const { + return &minimap; + } + inline Minimap *getMiniMapObject() { + return &minimap; + } - inline const Stats *getStats() const {return &stats;}; - inline Stats *getStats() {return &stats;}; + inline const Stats *getStats() const { + return &stats; + }; + inline Stats *getStats() { + return &stats; + }; - inline const WaterEffects *getWaterEffects() const {return &waterEffects;} - inline const WaterEffects *getAttackEffects() const {return &attackEffects;} - int getNextUnitId(Faction *faction); - int getNextCommandGroupId(); - inline int getFrameCount() const {return frameCount;} + inline const WaterEffects *getWaterEffects() const { + return &waterEffects; + } + inline const WaterEffects *getAttackEffects() const { + return &attackEffects; + } + int getNextUnitId(Faction *faction); + int getNextCommandGroupId(); + inline int getFrameCount() const { + return frameCount; + } - //init & load - void init(Game *game, bool createUnits, bool initFactions=true); - Checksum loadTileset(const vector pathList, const string &tilesetName, - Checksum* checksum, std::map > > &loadedFileList); - Checksum loadTileset(const string &dir, Checksum* checksum, - std::map > > &loadedFileList); - void clearTileset(); - Checksum loadTech(const vector pathList, const string &techName, - set &factions, Checksum* checksum, - std::map > > &loadedFileList, - bool validationMode=false); - Checksum loadMap(const string &path, Checksum* checksum); - Checksum loadScenario(const string &path, Checksum* checksum,bool resetCurrentScenario=false,const XmlNode *rootNode=NULL); - void setQueuedScenario(string scenarioName,bool keepFactions); - inline string getQueuedScenario() const { return queuedScenarioName; } - inline bool getQueuedScenarioKeepFactions() const { return queuedScenarioKeepFactions; } - void initUnitsForScenario(); + //init & load + void init(Game *game, bool createUnits, bool initFactions = true); + Checksum loadTileset(const vector pathList, const string &tilesetName, + Checksum* checksum, std::map > > &loadedFileList); + Checksum loadTileset(const string &dir, Checksum* checksum, + std::map > > &loadedFileList); + void clearTileset(); + Checksum loadTech(const vector pathList, const string &techName, + set &factions, Checksum* checksum, + std::map > > &loadedFileList, + bool validationMode = false); + Checksum loadMap(const string &path, Checksum* checksum); + Checksum loadScenario(const string &path, Checksum* checksum, bool resetCurrentScenario = false, const XmlNode *rootNode = NULL); + void setQueuedScenario(string scenarioName, bool keepFactions); + inline string getQueuedScenario() const { + return queuedScenarioName; + } + inline bool getQueuedScenarioKeepFactions() const { + return queuedScenarioKeepFactions; + } + void initUnitsForScenario(); - //misc - void update(); - Unit* findUnitById(int id) const; - const UnitType* findUnitTypeById(const FactionType* factionType, int id); - const UnitType *findUnitTypeByName(const string factionName, const string unitTypeName); - bool placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spaciated= false, bool threaded=false); - void moveUnitCells(Unit *unit, bool threaded); + //misc + void update(); + Unit* findUnitById(int id) const; + const UnitType* findUnitTypeById(const FactionType* factionType, int id); + const UnitType *findUnitTypeByName(const string factionName, const string unitTypeName); + bool placeUnit(const Vec2i &startLoc, int radius, Unit *unit, bool spaciated = false, bool threaded = false); + void moveUnitCells(Unit *unit, bool threaded); - bool toRenderUnit(const Unit *unit, const Quad2i &visibleQuad) const; - bool toRenderUnit(const Unit *unit) const; - bool toRenderUnit(const UnitBuildInfo &pendingUnit) const; + bool toRenderUnit(const Unit *unit, const Quad2i &visibleQuad) const; + bool toRenderUnit(const Unit *unit) const; + bool toRenderUnit(const UnitBuildInfo &pendingUnit) const; - Unit *nearestStore(const Vec2i &pos, int factionIndex, const ResourceType *rt); - void addAttackEffects(const Unit *unit); + Unit *nearestStore(const Vec2i &pos, int factionIndex, const ResourceType *rt); + void addAttackEffects(const Unit *unit); - //scripting interface - void morphToUnit(int unitId,const string &morphName,bool ignoreRequirements); - void createUnit(const string &unitName, int factionIndex, const Vec2i &pos,bool spaciated = true); - void givePositionCommand(int unitId, const string &commandName, const Vec2i &pos); - vector getUnitsForFaction(int factionIndex,const string& commandTypeName,int field); - int getUnitCurrentField(int unitId); - bool getIsUnitAlive(int unitId); - void giveAttackCommand(int unitId, int unitToAttackId); - void giveProductionCommand(int unitId, const string &producedName); - void giveUpgradeCommand(int unitId, const string &upgradeName); - void giveAttackStoppedCommand(int unitId, const string &itemName,bool ignoreRequirements); - void playStaticSound(const string &playSound); - void playStreamingSound(const string &playSound); - void stopStreamingSound(const string &playSound); - void stopAllSound(); - void moveToUnit(int unitId, int destUnitId); - void togglePauseGame(bool pauseStatus, bool forceAllowPauseStateChange); - void addConsoleText(const string &text); - void addConsoleTextWoLang(const string &text); + //scripting interface + void morphToUnit(int unitId, const string &morphName, bool ignoreRequirements); + void createUnit(const string &unitName, int factionIndex, const Vec2i &pos, bool spaciated = true); + void givePositionCommand(int unitId, const string &commandName, const Vec2i &pos); + vector getUnitsForFaction(int factionIndex, const string& commandTypeName, int field); + int getUnitCurrentField(int unitId); + bool getIsUnitAlive(int unitId); + void giveAttackCommand(int unitId, int unitToAttackId); + void giveProductionCommand(int unitId, const string &producedName); + void giveUpgradeCommand(int unitId, const string &upgradeName); + void giveAttackStoppedCommand(int unitId, const string &itemName, bool ignoreRequirements); + void playStaticSound(const string &playSound); + void playStreamingSound(const string &playSound); + void stopStreamingSound(const string &playSound); + void stopAllSound(); + void moveToUnit(int unitId, int destUnitId); + void togglePauseGame(bool pauseStatus, bool forceAllowPauseStateChange); + void addConsoleText(const string &text); + void addConsoleTextWoLang(const string &text); - void giveResource(const string &resourceName, int factionIndex, int amount); - int getResourceAmount(const string &resourceName, int factionIndex); - Vec2i getStartLocation(int factionIndex); - Vec2i getUnitPosition(int unitId); - void setUnitPosition(int unitId, Vec2i pos); + void giveResource(const string &resourceName, int factionIndex, int amount); + int getResourceAmount(const string &resourceName, int factionIndex); + Vec2i getStartLocation(int factionIndex); + Vec2i getUnitPosition(int unitId); + void setUnitPosition(int unitId, Vec2i pos); - void addCellMarker(Vec2i pos, int factionIndex, const string ¬e, const string textureFile); - void removeCellMarker(Vec2i pos, int factionIndex); - void showMarker(Vec2i pos, int factionIndex, const string ¬e, const string textureFile,int flashCount); + void addCellMarker(Vec2i pos, int factionIndex, const string ¬e, const string textureFile); + void removeCellMarker(Vec2i pos, int factionIndex); + void showMarker(Vec2i pos, int factionIndex, const string ¬e, const string textureFile, int flashCount); - int getUnitFactionIndex(int unitId); - const string getUnitName(int unitId); - int getUnitCount(int factionIndex); - int getUnitCountOfType(int factionIndex, const string &typeName); + int getUnitFactionIndex(int unitId); + const string getUnitName(int unitId); + int getUnitCount(int factionIndex); + int getUnitCountOfType(int factionIndex, const string &typeName); - const string getSystemMacroValue(const string key); - const string getPlayerName(int factionIndex); + const string getSystemMacroValue(const string key); + const string getPlayerName(int factionIndex); - void highlightUnit(int unitId,float radius, float thickness, Vec4f color); - void unhighlightUnit(int unitId); + void highlightUnit(int unitId, float radius, float thickness, Vec4f color); + void unhighlightUnit(int unitId); - void giveStopCommand(int unitId); + void giveStopCommand(int unitId); - bool selectUnit(int unitId); - void unselectUnit(int unitId); - void addUnitToGroupSelection(int unitId,int groupIndex); - void removeUnitFromGroupSelection(int unitId,int groupIndex); - void recallGroupSelection(int groupIndex); - void setAttackWarningsEnabled(bool enabled); - bool getAttackWarningsEnabled(); + bool selectUnit(int unitId); + void unselectUnit(int unitId); + void addUnitToGroupSelection(int unitId, int groupIndex); + void removeUnitFromGroupSelection(int unitId, int groupIndex); + void recallGroupSelection(int groupIndex); + void setAttackWarningsEnabled(bool enabled); + bool getAttackWarningsEnabled(); - inline Game * getGame() { return game; } - const GameSettings * getGameSettings() const; + inline Game * getGame() { + return game; + } + const GameSettings * getGameSettings() const; - GameSettings * getGameSettingsPtr(); + GameSettings * getGameSettingsPtr(); - std::vector validateFactionTypes(); - std::vector validateResourceTypes(); + std::vector validateFactionTypes(); + std::vector validateResourceTypes(); - void setFogOfWar(bool value); - bool getFogOfWar() const { return fogOfWar; } + void setFogOfWar(bool value); + bool getFogOfWar() const { + return fogOfWar; + } - std::string DumpWorldToLog(bool consoleBasicInfoOnly = false) const; + std::string DumpWorldToLog(bool consoleBasicInfoOnly = false) const; + + inline int getUpdateFps(int factionIndex) const { + int result = GameConstants::updateFps; + return result; + } + bool canTickWorld() const; + + ExploredCellsLookupItem exploreCells(const Vec2i &newPos, int sightRange, int teamIndex, Unit *unit); + void exploreCells(int teamIndex, ExploredCellsLookupItem &exploredCellsCache); + bool showWorldForPlayer(int factionIndex, bool excludeFogOfWarCheck = false) const; + + inline UnitUpdater * getUnitUpdater() { + return &unitUpdater; + } + + void playStaticVideo(const string &playVideo); + void playStreamingVideo(const string &playVideo); + void stopStreamingVideo(const string &playVideo); + void stopAllVideo(); + + void removeResourceTargetFromCache(const Vec2i &pos); + + string getExploredCellsLookupItemCacheStats(); + string getFowAlphaCellsLookupItemCacheStats(); + string getAllFactionsCacheStats(); + + void placeUnitAtLocation(const Vec2i &location, int radius, Unit *unit, bool spaciated); + void saveGame(XmlNode *rootNode); + void loadGame(const XmlNode *rootNode); + + void clearCaches(); + void refreshAllUnitExplorations(); + + bool factionLostGame(int factionIndex); + + void initTeamResource(const ResourceType *rt, int teamIndex, int value); + const Resource * getResourceForTeam(const ResourceType *rt, int teamIndex); + int getStoreAmountForTeam(const ResourceType *rt, int teamIndex) const; + bool showResourceTypeForFaction(const ResourceType *rt, const Faction *faction) const; + bool showResourceTypeForTeam(const ResourceType *rt, int teamIndex) const; + + + private: + + void initCells(bool fogOfWar); + void initSplattedTextures(); + void initFactionTypes(GameSettings *gs); + void initMinimap(); + void initUnits(); + void initMap(); + + //misc + void tick(); + void computeFow(); + + void updateAllTilesetObjects(); + void updateAllFactionUnits(); + void underTakeDeadFactionUnits(); + void updateAllFactionConsumableCosts(); + void restoreExploredFogOfWarCells(); + + }; - inline int getUpdateFps(int factionIndex) const { - int result = GameConstants::updateFps; - return result; } - bool canTickWorld() const; - - ExploredCellsLookupItem exploreCells(const Vec2i &newPos, int sightRange, int teamIndex, Unit *unit); - void exploreCells(int teamIndex,ExploredCellsLookupItem &exploredCellsCache); - bool showWorldForPlayer(int factionIndex, bool excludeFogOfWarCheck=false) const; - - inline UnitUpdater * getUnitUpdater() { return &unitUpdater; } - - void playStaticVideo(const string &playVideo); - void playStreamingVideo(const string &playVideo); - void stopStreamingVideo(const string &playVideo); - void stopAllVideo(); - - void removeResourceTargetFromCache(const Vec2i &pos); - - string getExploredCellsLookupItemCacheStats(); - string getFowAlphaCellsLookupItemCacheStats(); - string getAllFactionsCacheStats(); - - void placeUnitAtLocation(const Vec2i &location, int radius, Unit *unit, bool spaciated); - void saveGame(XmlNode *rootNode); - void loadGame(const XmlNode *rootNode); - - void clearCaches(); - void refreshAllUnitExplorations(); - - bool factionLostGame(int factionIndex); - - void initTeamResource(const ResourceType *rt,int teamIndex, int value); - const Resource * getResourceForTeam(const ResourceType *rt, int teamIndex); - int getStoreAmountForTeam(const ResourceType *rt, int teamIndex) const; - bool showResourceTypeForFaction(const ResourceType *rt, const Faction *faction) const; - bool showResourceTypeForTeam(const ResourceType *rt, int teamIndex) const; - - -private: - - void initCells(bool fogOfWar); - void initSplattedTextures(); - void initFactionTypes(GameSettings *gs); - void initMinimap(); - void initUnits(); - void initMap(); - - //misc - void tick(); - void computeFow(); - - void updateAllTilesetObjects(); - void updateAllFactionUnits(); - void underTakeDeadFactionUnits(); - void updateAllFactionConsumableCosts(); - void restoreExploredFogOfWarCells(); - -}; - -}}//end namespace +}//end namespace #endif diff --git a/source/glest_map_editor/main.cpp b/source/glest_map_editor/main.cpp index 3f88c5fa5..eb9b7ca3a 100644 --- a/source/glest_map_editor/main.cpp +++ b/source/glest_map_editor/main.cpp @@ -40,45 +40,47 @@ using namespace Shared::PlatformCommon; using namespace Glest::Game; using namespace std; -namespace Glest { namespace Game { -string getGameReadWritePath(const string &lookupKey) { - string path = ""; - if(path == "" && getenv("GLESTHOME") != NULL) { - path = getenv("GLESTHOME"); - if(path != "" && EndsWith(path, "/") == false && EndsWith(path, "\\") == false) { - path += "/"; - } +namespace Glest { + namespace Game { + string getGameReadWritePath(const string &lookupKey) { + string path = ""; + if (path == "" && getenv("GLESTHOME") != NULL) { + path = getenv("GLESTHOME"); + if (path != "" && EndsWith(path, "/") == false && EndsWith(path, "\\") == false) { + path += "/"; + } - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path to be used for read/write files [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str()); - } + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path to be used for read/write files [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str()); + } - return path; + return path; + } + } } -}} namespace MapEditor { -const string mapeditorVersionString = "v0.8.01"; -const string MainWindow::winHeader = "ZetaGlest Map Editor " + mapeditorVersionString; + const string mapeditorVersionString = "v0.8.01"; + const string MainWindow::winHeader = "ZetaGlest Map Editor " + mapeditorVersionString; -// =============================================== -// class Global functions -// =============================================== + // =============================================== + // class Global functions + // =============================================== -wxString ToUnicode(const char* str) { - return wxString(str, wxConvUTF8); -} + wxString ToUnicode(const char* str) { + return wxString(str, wxConvUTF8); + } -wxString ToUnicode(const string& str) { - return wxString(str.c_str(), wxConvUTF8); -} + wxString ToUnicode(const string& str) { + return wxString(str.c_str(), wxConvUTF8); + } -// =============================================== -// class MainWindow -// =============================================== + // =============================================== + // class MainWindow + // =============================================== -MainWindow::MainWindow(string appPath) - : wxFrame(NULL, -1, ToUnicode(winHeader), wxPoint(0,0), wxSize(1024, 768)) + MainWindow::MainWindow(string appPath) + : wxFrame(NULL, -1, ToUnicode(winHeader), wxPoint(0, 0), wxSize(1024, 768)) , glCanvas(NULL) , program(NULL) , lastX(0) @@ -96,1115 +98,1104 @@ MainWindow::MainWindow(string appPath) , startLocation(1) , enabledGroup(ctHeight) , fileModified(false) - , boxsizer(NULL) - ,startupSettingsInited(false) { + , boxsizer(NULL) + , startupSettingsInited(false) { - menuFile=NULL; - menuEdit=NULL; - menuEditMirror=NULL; - menuView=NULL; - menuBrush=NULL; - menuBrushHeight=NULL; - menuBrushGradient=NULL; - menuBrushSurface=NULL; - menuBrushObject=NULL; - menuBrushResource=NULL; - menuBrushStartLocation=NULL; - menuRadius=NULL; - fileDialog=NULL; - resourceUnderMouse=0; - objectUnderMouse=0; + menuFile = NULL; + menuEdit = NULL; + menuEditMirror = NULL; + menuView = NULL; + menuBrush = NULL; + menuBrushHeight = NULL; + menuBrushGradient = NULL; + menuBrushSurface = NULL; + menuBrushObject = NULL; + menuBrushResource = NULL; + menuBrushStartLocation = NULL; + menuRadius = NULL; + fileDialog = NULL; + resourceUnderMouse = 0; + objectUnderMouse = 0; - // default values for random height calculation that turned out to be quite useful - randomWithReset=true; - randomMinimumHeight=-300; - randomMaximumHeight=400; - randomChanceDivider=30; - randomRecursions=3; + // default values for random height calculation that turned out to be quite useful + randomWithReset = true; + randomMinimumHeight = -300; + randomMaximumHeight = 400; + randomChanceDivider = 30; + randomRecursions = 3; - this->appPath = appPath; - Properties::setApplicationPath(executable_path(appPath)); + this->appPath = appPath; + Properties::setApplicationPath(executable_path(appPath)); - this->panel = new wxPanel(this, wxID_ANY); -} + this->panel = new wxPanel(this, wxID_ANY); + } -void MainWindow::onToolPlayer(wxCommandEvent& event){ - PopupMenu(menuBrushStartLocation); -} + void MainWindow::onToolPlayer(wxCommandEvent& event) { + PopupMenu(menuBrushStartLocation); + } -void MainToolBar::onMouseMove(wxMouseEvent &event) { + void MainToolBar::onMouseMove(wxMouseEvent &event) { #ifdef WIN32 - if(this->GetParent() != NULL && this->GetParent()->GetParent() != NULL) { - MainWindow *mainWindow = dynamic_cast(this->GetParent()->GetParent()); - if(mainWindow != NULL) { - mainWindow->refreshMapRender(); + if (this->GetParent() != NULL && this->GetParent()->GetParent() != NULL) { + MainWindow *mainWindow = dynamic_cast(this->GetParent()->GetParent()); + if (mainWindow != NULL) { + mainWindow->refreshMapRender(); + } } - } #endif - event.Skip(); -} - -BEGIN_EVENT_TABLE(MainToolBar, wxToolBar) - - EVT_MOTION(MainToolBar::onMouseMove) - -END_EVENT_TABLE() - -void MainWindow::init(string fname) { - - //menus - menuBar = new wxMenuBar(); - - //file - menuFile = new wxMenu(); - menuFile->Append(wxID_NEW); - menuFile->Append(wxID_OPEN); - menuFile->AppendSeparator(); - menuFile->Append(wxID_SAVE); - menuFile->Append(wxID_SAVEAS); - menuFile->AppendSeparator(); - menuFile->Append(wxID_EXIT); - menuBar->Append(menuFile, wxT("&File")); - - //edit - menuEdit = new wxMenu(); - menuEdit->Append(miEditUndo, wxT("&Undo\tCTRL+Z")); - menuEdit->Append(miEditRedo, wxT("&Redo\tCTRL+Y")); - menuEdit->AppendSeparator(); -// menuEdit->Append(miEditReset, wxT("Rese&t...")); - menuEdit->Append(miEditResetPlayers, wxT("Reset &Players...")); - menuEdit->Append(miEditResize, wxT("Re&size...")); - menuEdit->Append(miEditFlipDiagonal, wxT("Flip &Diagonal")); - menuEdit->Append(miEditFlipX, wxT("Flip &X")); - menuEdit->Append(miEditFlipY, wxT("Flip &Y")); - - // Mirror submenu------------------------------------------- - menuEditMirror = new wxMenu(); - menuEditMirror->Append(miEditMirrorX, wxT("Copy &Left to Right")); - menuEditMirror->Append(miEditMirrorY, wxT("Copy &Top to Bottom")); - menuEditMirror->Append(miEditMirrorXY, wxT("Copy &BottomLeft to TopRight")); - menuEditMirror->AppendSeparator(); - menuEditMirror->Append(miEditRotatecopyX, wxT("&Rotate Left to Right")); - menuEditMirror->Append(miEditRotatecopyY, wxT("Rotate T&op to Bottom")); - menuEditMirror->Append(miEditRotatecopyXY, wxT("Rotate Botto&mLeft to TopRight")); - menuEditMirror->Append(miEditRotatecopyCorner, wxT("Rotate TopLeft &corner to TopRight")); - menuEdit->Append(miEditMirror, wxT("&Mirror"), menuEditMirror); - // --------------------------------------------------------- - - menuEdit->Append(miEditRandomizeHeights, wxT("Randomize &Heights")); - menuEdit->Append(miEditRandomize, wxT("Randomi&ze Players")); - menuEdit->Append(miEditSwitchSurfaces, wxT("Switch Sur&faces...")); - menuEdit->Append(miEditInfo, wxT("&Info...")); - menuEdit->Append(miEditAdvanced, wxT("&Advanced...")); - menuBar->Append(menuEdit, wxT("&Edit")); - - //view - menuView = new wxMenu(); - menuView->Append(miViewResetZoomAndPos, wxT("&Reset zoom and pos")); - menuView->AppendCheckItem(miViewGrid, wxT("&Grid")); - menuView->AppendCheckItem(miViewHeightMap, wxT("H&eightMap")); - menuView->AppendCheckItem(miHideWater, wxT("Hide&Water")); - menuView->AppendSeparator(); - menuView->Append(miViewHelp, wxT("&Help...")); - menuView->Append(miViewAbout, wxT("&About...")); - menuBar->Append(menuView, wxT("&View")); - - //brush - // menuBrush = new wxMenu(); - - //surface - menuBrushSurface = new wxMenu(); - menuBrushSurface->AppendCheckItem(miBrushSurface + 1, wxT("&Grass")); - menuBrushSurface->AppendCheckItem(miBrushSurface + 2, wxT("S&econdary grass")); - menuBrushSurface->AppendCheckItem(miBrushSurface + 3, wxT("&Road")); - menuBrushSurface->AppendCheckItem(miBrushSurface + 4, wxT("&Stone")); - menuBrushSurface->AppendCheckItem(miBrushSurface + 5, wxT("Gr&ound")); - menuBar->Append(menuBrushSurface, wxT("&Surface")); - - //resources - menuBrushResource = new wxMenu(); - //menuBrushResource->AppendCheckItem(miBrushResource + 1, wxT("&0 - None")); - menuBrushResource->AppendCheckItem(miBrushResource+2, wxT("&Gold (unwalkable)")); - menuBrushResource->AppendCheckItem(miBrushResource+3, wxT("&Stone (unwalkable)")); - menuBrushResource->AppendCheckItem(miBrushResource+4, wxT("&3 - custom")); - menuBrushResource->AppendCheckItem(miBrushResource+5, wxT("&4 - custom")); - menuBrushResource->AppendCheckItem(miBrushResource+6, wxT("&5 - custom")); - menuBar->Append(menuBrushResource, wxT("&Resource")); - - //objects - menuBrushObject = new wxMenu(); - menuBrushObject->AppendCheckItem(miBrushObject+1, wxT("&None (erase)\tALT+0")); - menuBrushObject->AppendSeparator(); - menuBrushObject->AppendCheckItem(miBrushObject+2, wxT("&Tree (harvestable)")); - menuBrushObject->AppendCheckItem(miBrushObject+3, wxT("&Dead tree/Cactuses/Thornbush")); - menuBrushObject->AppendCheckItem(miBrushObject+4, wxT("&Stone")); - menuBrushObject->AppendCheckItem(miBrushObject+5, wxT("&Bush/Grass/Fern (walkable)")); - menuBrushObject->AppendCheckItem(miBrushObject+6, wxT("&Water object/Reed/Papyrus (walkable)")); - menuBrushObject->AppendCheckItem(miBrushObject+7, wxT("Big tree/&Old palm")); - menuBrushObject->AppendCheckItem(miBrushObject+8, wxT("&Hanged/Impaled ")); - menuBrushObject->AppendCheckItem(miBrushObject+9, wxT("St&atues")); - menuBrushObject->AppendCheckItem(miBrushObject+10, wxT("&Mountain")); - menuBrushObject->AppendCheckItem(miBrushObject+11, wxT("&Invisible blocking object")); - menuBar->Append(menuBrushObject, wxT("&Object")); - - // ZombiePirate height brush - menuBrushGradient = new wxMenu(); - for (int i = 0; i < heightCount; ++i) { - menuBrushGradient->AppendCheckItem(miBrushGradient + i + 1, ToUnicode((i>4?"&":"") +intToStr(i - heightCount / 2))); + event.Skip(); } - menuBar->Append(menuBrushGradient, wxT("&Gradient")); - // Glest height brush - menuBrushHeight = new wxMenu(); - for (int i = 0; i < heightCount; ++i) { - menuBrushHeight->AppendCheckItem(miBrushHeight + i + 1, ToUnicode((i>4?"&":"") +intToStr(i - heightCount / 2))); - } - menuBrushHeight->Check(miBrushHeight + (heightCount + 1) / 2, true); - menuBar->Append(menuBrushHeight, wxT("&Height")); + BEGIN_EVENT_TABLE(MainToolBar, wxToolBar) - enabledGroup = ctHeight; + EVT_MOTION(MainToolBar::onMouseMove) - //radius - menuRadius = new wxMenu(); - for (int i = 1; i <= radiusCount; ++i) { - menuRadius->AppendCheckItem(miRadius + i, ToUnicode("&" + intToStr(i) + " (diameter "+intToStr(i*2-1)+ ")"+ "\tALT+" + intToStr(i))); - } - menuRadius->Check(miRadius + 1, true); - menuBar->Append(menuRadius, wxT("R&adius")); + END_EVENT_TABLE() - //players - menuBrushStartLocation = new wxMenu(); - wxMenuItem *pmi1 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 1, wxT("Player &1 Red")); - pmi1->SetBitmap(wxBitmap(brush_players_red)); - menuBrushStartLocation->Append(pmi1); - wxMenuItem *pmi2 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 2, wxT("Player &2 Blue")); - pmi2->SetBitmap(wxBitmap(brush_players_blue)); - menuBrushStartLocation->Append(pmi2); - wxMenuItem *pmi3 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 3, wxT("Player &3 Green")); - pmi3->SetBitmap(wxBitmap(brush_players_green)); - menuBrushStartLocation->Append(pmi3); - wxMenuItem *pmi4 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 4, wxT("Player &4 Yellow")); - pmi4->SetBitmap(wxBitmap(brush_players_yellow)); - menuBrushStartLocation->Append(pmi4); - wxMenuItem *pmi5 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 5, wxT("Player &5 White")); - pmi5->SetBitmap(wxBitmap(brush_players_white)); - menuBrushStartLocation->Append(pmi5); - wxMenuItem *pmi6 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 6, wxT("Player &6 Cyan")); - pmi6->SetBitmap(wxBitmap(brush_players_cyan)); - menuBrushStartLocation->Append(pmi6); - wxMenuItem *pmi7 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 7, wxT("Player &7 Orange")); - pmi7->SetBitmap(wxBitmap(brush_players_orange)); - menuBrushStartLocation->Append(pmi7); - wxMenuItem *pmi8 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 8, wxT("Player &8 Pink")); // = Light Magenta :-) - pmi8->SetBitmap(wxBitmap(brush_players_pink)); - menuBrushStartLocation->Append(pmi8); - menuBar->Append(menuBrushStartLocation, wxT("&Player")); - //menuBar->Append(menuBrush, wxT("&Brush")); + void MainWindow::init(string fname) { + + //menus + menuBar = new wxMenuBar(); + + //file + menuFile = new wxMenu(); + menuFile->Append(wxID_NEW); + menuFile->Append(wxID_OPEN); + menuFile->AppendSeparator(); + menuFile->Append(wxID_SAVE); + menuFile->Append(wxID_SAVEAS); + menuFile->AppendSeparator(); + menuFile->Append(wxID_EXIT); + menuBar->Append(menuFile, wxT("&File")); + + //edit + menuEdit = new wxMenu(); + menuEdit->Append(miEditUndo, wxT("&Undo\tCTRL+Z")); + menuEdit->Append(miEditRedo, wxT("&Redo\tCTRL+Y")); + menuEdit->AppendSeparator(); + // menuEdit->Append(miEditReset, wxT("Rese&t...")); + menuEdit->Append(miEditResetPlayers, wxT("Reset &Players...")); + menuEdit->Append(miEditResize, wxT("Re&size...")); + menuEdit->Append(miEditFlipDiagonal, wxT("Flip &Diagonal")); + menuEdit->Append(miEditFlipX, wxT("Flip &X")); + menuEdit->Append(miEditFlipY, wxT("Flip &Y")); + + // Mirror submenu------------------------------------------- + menuEditMirror = new wxMenu(); + menuEditMirror->Append(miEditMirrorX, wxT("Copy &Left to Right")); + menuEditMirror->Append(miEditMirrorY, wxT("Copy &Top to Bottom")); + menuEditMirror->Append(miEditMirrorXY, wxT("Copy &BottomLeft to TopRight")); + menuEditMirror->AppendSeparator(); + menuEditMirror->Append(miEditRotatecopyX, wxT("&Rotate Left to Right")); + menuEditMirror->Append(miEditRotatecopyY, wxT("Rotate T&op to Bottom")); + menuEditMirror->Append(miEditRotatecopyXY, wxT("Rotate Botto&mLeft to TopRight")); + menuEditMirror->Append(miEditRotatecopyCorner, wxT("Rotate TopLeft &corner to TopRight")); + menuEdit->Append(miEditMirror, wxT("&Mirror"), menuEditMirror); + // --------------------------------------------------------- + + menuEdit->Append(miEditRandomizeHeights, wxT("Randomize &Heights")); + menuEdit->Append(miEditRandomize, wxT("Randomi&ze Players")); + menuEdit->Append(miEditSwitchSurfaces, wxT("Switch Sur&faces...")); + menuEdit->Append(miEditInfo, wxT("&Info...")); + menuEdit->Append(miEditAdvanced, wxT("&Advanced...")); + menuBar->Append(menuEdit, wxT("&Edit")); + + //view + menuView = new wxMenu(); + menuView->Append(miViewResetZoomAndPos, wxT("&Reset zoom and pos")); + menuView->AppendCheckItem(miViewGrid, wxT("&Grid")); + menuView->AppendCheckItem(miViewHeightMap, wxT("H&eightMap")); + menuView->AppendCheckItem(miHideWater, wxT("Hide&Water")); + menuView->AppendSeparator(); + menuView->Append(miViewHelp, wxT("&Help...")); + menuView->Append(miViewAbout, wxT("&About...")); + menuBar->Append(menuView, wxT("&View")); + + //brush + // menuBrush = new wxMenu(); + + //surface + menuBrushSurface = new wxMenu(); + menuBrushSurface->AppendCheckItem(miBrushSurface + 1, wxT("&Grass")); + menuBrushSurface->AppendCheckItem(miBrushSurface + 2, wxT("S&econdary grass")); + menuBrushSurface->AppendCheckItem(miBrushSurface + 3, wxT("&Road")); + menuBrushSurface->AppendCheckItem(miBrushSurface + 4, wxT("&Stone")); + menuBrushSurface->AppendCheckItem(miBrushSurface + 5, wxT("Gr&ound")); + menuBar->Append(menuBrushSurface, wxT("&Surface")); + + //resources + menuBrushResource = new wxMenu(); + //menuBrushResource->AppendCheckItem(miBrushResource + 1, wxT("&0 - None")); + menuBrushResource->AppendCheckItem(miBrushResource + 2, wxT("&Gold (unwalkable)")); + menuBrushResource->AppendCheckItem(miBrushResource + 3, wxT("&Stone (unwalkable)")); + menuBrushResource->AppendCheckItem(miBrushResource + 4, wxT("&3 - custom")); + menuBrushResource->AppendCheckItem(miBrushResource + 5, wxT("&4 - custom")); + menuBrushResource->AppendCheckItem(miBrushResource + 6, wxT("&5 - custom")); + menuBar->Append(menuBrushResource, wxT("&Resource")); + + //objects + menuBrushObject = new wxMenu(); + menuBrushObject->AppendCheckItem(miBrushObject + 1, wxT("&None (erase)\tALT+0")); + menuBrushObject->AppendSeparator(); + menuBrushObject->AppendCheckItem(miBrushObject + 2, wxT("&Tree (harvestable)")); + menuBrushObject->AppendCheckItem(miBrushObject + 3, wxT("&Dead tree/Cactuses/Thornbush")); + menuBrushObject->AppendCheckItem(miBrushObject + 4, wxT("&Stone")); + menuBrushObject->AppendCheckItem(miBrushObject + 5, wxT("&Bush/Grass/Fern (walkable)")); + menuBrushObject->AppendCheckItem(miBrushObject + 6, wxT("&Water object/Reed/Papyrus (walkable)")); + menuBrushObject->AppendCheckItem(miBrushObject + 7, wxT("Big tree/&Old palm")); + menuBrushObject->AppendCheckItem(miBrushObject + 8, wxT("&Hanged/Impaled ")); + menuBrushObject->AppendCheckItem(miBrushObject + 9, wxT("St&atues")); + menuBrushObject->AppendCheckItem(miBrushObject + 10, wxT("&Mountain")); + menuBrushObject->AppendCheckItem(miBrushObject + 11, wxT("&Invisible blocking object")); + menuBar->Append(menuBrushObject, wxT("&Object")); + + // ZombiePirate height brush + menuBrushGradient = new wxMenu(); + for (int i = 0; i < heightCount; ++i) { + menuBrushGradient->AppendCheckItem(miBrushGradient + i + 1, ToUnicode((i > 4 ? "&" : "") + intToStr(i - heightCount / 2))); + } + menuBar->Append(menuBrushGradient, wxT("&Gradient")); + + // Glest height brush + menuBrushHeight = new wxMenu(); + for (int i = 0; i < heightCount; ++i) { + menuBrushHeight->AppendCheckItem(miBrushHeight + i + 1, ToUnicode((i > 4 ? "&" : "") + intToStr(i - heightCount / 2))); + } + menuBrushHeight->Check(miBrushHeight + (heightCount + 1) / 2, true); + menuBar->Append(menuBrushHeight, wxT("&Height")); + + enabledGroup = ctHeight; + + //radius + menuRadius = new wxMenu(); + for (int i = 1; i <= radiusCount; ++i) { + menuRadius->AppendCheckItem(miRadius + i, ToUnicode("&" + intToStr(i) + " (diameter " + intToStr(i * 2 - 1) + ")" + "\tALT+" + intToStr(i))); + } + menuRadius->Check(miRadius + 1, true); + menuBar->Append(menuRadius, wxT("R&adius")); + + //players + menuBrushStartLocation = new wxMenu(); + wxMenuItem *pmi1 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 1, wxT("Player &1 Red")); + pmi1->SetBitmap(wxBitmap(brush_players_red)); + menuBrushStartLocation->Append(pmi1); + wxMenuItem *pmi2 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 2, wxT("Player &2 Blue")); + pmi2->SetBitmap(wxBitmap(brush_players_blue)); + menuBrushStartLocation->Append(pmi2); + wxMenuItem *pmi3 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 3, wxT("Player &3 Green")); + pmi3->SetBitmap(wxBitmap(brush_players_green)); + menuBrushStartLocation->Append(pmi3); + wxMenuItem *pmi4 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 4, wxT("Player &4 Yellow")); + pmi4->SetBitmap(wxBitmap(brush_players_yellow)); + menuBrushStartLocation->Append(pmi4); + wxMenuItem *pmi5 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 5, wxT("Player &5 White")); + pmi5->SetBitmap(wxBitmap(brush_players_white)); + menuBrushStartLocation->Append(pmi5); + wxMenuItem *pmi6 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 6, wxT("Player &6 Cyan")); + pmi6->SetBitmap(wxBitmap(brush_players_cyan)); + menuBrushStartLocation->Append(pmi6); + wxMenuItem *pmi7 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 7, wxT("Player &7 Orange")); + pmi7->SetBitmap(wxBitmap(brush_players_orange)); + menuBrushStartLocation->Append(pmi7); + wxMenuItem *pmi8 = new wxMenuItem(menuBrushStartLocation, miBrushStartLocation + 8, wxT("Player &8 Pink")); // = Light Magenta :-) + pmi8->SetBitmap(wxBitmap(brush_players_pink)); + menuBrushStartLocation->Append(pmi8); + menuBar->Append(menuBrushStartLocation, wxT("&Player")); + //menuBar->Append(menuBrush, wxT("&Brush")); - SetMenuBar(menuBar); + SetMenuBar(menuBar); - fileName = "New (unsaved) map"; - int status_widths[siCOUNT] = { - 10, // empty - -25, // File name - -6, // File type - -20, // Current Object - -14, // Brush Type - -20, // Brush 'Value' - -10, // Brush Radius - -25, // Position - }; - CreateStatusBar(siCOUNT); - GetStatusBar()->SetStatusWidths(siCOUNT, status_widths); + fileName = "New (unsaved) map"; + int status_widths[siCOUNT] = { + 10, // empty + -25, // File name + -6, // File type + -20, // Current Object + -14, // Brush Type + -20, // Brush 'Value' + -10, // Brush Radius + -25, // Position + }; + CreateStatusBar(siCOUNT); + GetStatusBar()->SetStatusWidths(siCOUNT, status_widths); - SetStatusText(wxT("File: ") + ToUnicode(fileName), siFILE_NAME); - SetStatusText(wxT(".mgm"), siFILE_TYPE); - SetStatusText(wxT("Object: None (Erase)"), siCURR_OBJECT); - SetStatusText(wxT("Brush: Height"), siBRUSH_TYPE); - SetStatusText(wxT("Value: 0"), siBRUSH_VALUE); - SetStatusText(wxT("Radius: 1"), siBRUSH_RADIUS); - SetStatusText(wxT("Pos (Ingame): 0"), siPOS_VALUE); + SetStatusText(wxT("File: ") + ToUnicode(fileName), siFILE_NAME); + SetStatusText(wxT(".mgm"), siFILE_TYPE); + SetStatusText(wxT("Object: None (Erase)"), siCURR_OBJECT); + SetStatusText(wxT("Brush: Height"), siBRUSH_TYPE); + SetStatusText(wxT("Value: 0"), siBRUSH_VALUE); + SetStatusText(wxT("Radius: 1"), siBRUSH_RADIUS); + SetStatusText(wxT("Pos (Ingame): 0"), siPOS_VALUE); - wxToolBar *toolbar = new MainToolBar(this->panel, wxID_ANY); - toolbar->AddTool(miEditUndo, _("undo"), wxBitmap(edit_undo), _("Undo")); - toolbar->AddTool(miEditRedo, _("redo"), wxBitmap(edit_redo), _("Redo")); - toolbar->AddTool(miEditRandomizeHeights, _("randomizeHeights"), wxBitmap(edit_randomize_heights), _("Randomize Heights")); -// toolbar->AddTool(miEditRandomize, _("randomize"), wxBitmap(edit_randomize), _("Randomize")); - toolbar->AddTool(miEditSwitchSurfaces, _("switch"), wxBitmap(edit_switch_surfaces), _("Switch Surfaces")); - toolbar->AddSeparator(); - toolbar->AddTool(miBrushSurface + 1, _("brush_grass1"), wxBitmap(brush_surface_grass1), _("Grass")); - toolbar->AddTool(miBrushSurface + 2, _("brush_grass2"), wxBitmap(brush_surface_grass2), _("Secondary grass")); - toolbar->AddTool(miBrushSurface + 3, _("brush_road"), wxBitmap(brush_surface_road), _("Road")); - toolbar->AddTool(miBrushSurface + 4, _("brush_stone"), wxBitmap(brush_surface_stone), _("Stone")); - toolbar->AddTool(miBrushSurface + 5, _("brush_custom"), wxBitmap(brush_surface_custom), _("Ground")); - toolbar->AddSeparator(); - toolbar->AddTool(miBrushResource + 2, _("resource1"), wxBitmap(brush_resource_1_gold), _("gold (unwalkable)")); - toolbar->AddTool(miBrushResource + 3, _("resource2"), wxBitmap(brush_resource_2_stone), _("stone (unwalkable)")); - toolbar->AddTool(miBrushResource + 4, _("resource3"), wxBitmap(brush_resource_3), _("custom3")); - toolbar->AddTool(miBrushResource + 5, _("resource4"), wxBitmap(brush_resource_4), _("custom4")); - toolbar->AddTool(miBrushResource + 6, _("resource5"), wxBitmap(brush_resource_5), _("custom5")); - toolbar->AddSeparator(); - toolbar->AddTool(miBrushObject + 1, _("brush_none"), wxBitmap(brush_none), _("None (erase)")); - toolbar->AddTool(miBrushObject + 2, _("brush_tree"), wxBitmap(brush_object_tree), _("Tree (unwalkable/harvestable)")); - toolbar->AddTool(miBrushObject + 3, _("brush_dead_tree"), wxBitmap(brush_object_dead_tree), _("Dead tree/Cactuses/Thornbush (unwalkable)")); - toolbar->AddTool(miBrushObject + 4, _("brush_stone"), wxBitmap(brush_object_stone), _("Stone (unwalkable/not harvestable)")); - toolbar->AddTool(miBrushObject + 5, _("brush_bush"), wxBitmap(brush_object_bush), _("Bush/Grass/Fern (walkable)")); - toolbar->AddTool(miBrushObject + 6, _("brush_water"), wxBitmap(brush_object_water_object), _("Water object/Reed/Papyrus (walkable)")); - toolbar->AddTool(miBrushObject + 7, _("brush_c1_bigtree"), wxBitmap(brush_object_c1_bigtree), _("Big tree/Old palm (unwalkable/not harvestable)")); - toolbar->AddTool(miBrushObject + 8, _("brush_c2_hanged"), wxBitmap(brush_object_c2_hanged), _("Hanged/Impaled (unwalkable)")); - toolbar->AddTool(miBrushObject + 9, _("brush_c3_statue"), wxBitmap(brush_object_c3_statue), _("Statues (unwalkable)")); - toolbar->AddTool(miBrushObject +10, _("brush_c4_bigrock"), wxBitmap(brush_object_c4_bigrock), _("Mountain (unwalkable)")); - toolbar->AddTool(miBrushObject +11, _("brush_c5_blocking"), wxBitmap(brush_object_c5_blocking), _("Invisible blocking object (unwalkable)")); - toolbar->AddSeparator(); - toolbar->AddTool(toolPlayer, _("brush_player"), wxBitmap(brush_players_player), _("Player start position")); - toolbar->Realize(); + wxToolBar *toolbar = new MainToolBar(this->panel, wxID_ANY); + toolbar->AddTool(miEditUndo, _("undo"), wxBitmap(edit_undo), _("Undo")); + toolbar->AddTool(miEditRedo, _("redo"), wxBitmap(edit_redo), _("Redo")); + toolbar->AddTool(miEditRandomizeHeights, _("randomizeHeights"), wxBitmap(edit_randomize_heights), _("Randomize Heights")); + // toolbar->AddTool(miEditRandomize, _("randomize"), wxBitmap(edit_randomize), _("Randomize")); + toolbar->AddTool(miEditSwitchSurfaces, _("switch"), wxBitmap(edit_switch_surfaces), _("Switch Surfaces")); + toolbar->AddSeparator(); + toolbar->AddTool(miBrushSurface + 1, _("brush_grass1"), wxBitmap(brush_surface_grass1), _("Grass")); + toolbar->AddTool(miBrushSurface + 2, _("brush_grass2"), wxBitmap(brush_surface_grass2), _("Secondary grass")); + toolbar->AddTool(miBrushSurface + 3, _("brush_road"), wxBitmap(brush_surface_road), _("Road")); + toolbar->AddTool(miBrushSurface + 4, _("brush_stone"), wxBitmap(brush_surface_stone), _("Stone")); + toolbar->AddTool(miBrushSurface + 5, _("brush_custom"), wxBitmap(brush_surface_custom), _("Ground")); + toolbar->AddSeparator(); + toolbar->AddTool(miBrushResource + 2, _("resource1"), wxBitmap(brush_resource_1_gold), _("gold (unwalkable)")); + toolbar->AddTool(miBrushResource + 3, _("resource2"), wxBitmap(brush_resource_2_stone), _("stone (unwalkable)")); + toolbar->AddTool(miBrushResource + 4, _("resource3"), wxBitmap(brush_resource_3), _("custom3")); + toolbar->AddTool(miBrushResource + 5, _("resource4"), wxBitmap(brush_resource_4), _("custom4")); + toolbar->AddTool(miBrushResource + 6, _("resource5"), wxBitmap(brush_resource_5), _("custom5")); + toolbar->AddSeparator(); + toolbar->AddTool(miBrushObject + 1, _("brush_none"), wxBitmap(brush_none), _("None (erase)")); + toolbar->AddTool(miBrushObject + 2, _("brush_tree"), wxBitmap(brush_object_tree), _("Tree (unwalkable/harvestable)")); + toolbar->AddTool(miBrushObject + 3, _("brush_dead_tree"), wxBitmap(brush_object_dead_tree), _("Dead tree/Cactuses/Thornbush (unwalkable)")); + toolbar->AddTool(miBrushObject + 4, _("brush_stone"), wxBitmap(brush_object_stone), _("Stone (unwalkable/not harvestable)")); + toolbar->AddTool(miBrushObject + 5, _("brush_bush"), wxBitmap(brush_object_bush), _("Bush/Grass/Fern (walkable)")); + toolbar->AddTool(miBrushObject + 6, _("brush_water"), wxBitmap(brush_object_water_object), _("Water object/Reed/Papyrus (walkable)")); + toolbar->AddTool(miBrushObject + 7, _("brush_c1_bigtree"), wxBitmap(brush_object_c1_bigtree), _("Big tree/Old palm (unwalkable/not harvestable)")); + toolbar->AddTool(miBrushObject + 8, _("brush_c2_hanged"), wxBitmap(brush_object_c2_hanged), _("Hanged/Impaled (unwalkable)")); + toolbar->AddTool(miBrushObject + 9, _("brush_c3_statue"), wxBitmap(brush_object_c3_statue), _("Statues (unwalkable)")); + toolbar->AddTool(miBrushObject + 10, _("brush_c4_bigrock"), wxBitmap(brush_object_c4_bigrock), _("Mountain (unwalkable)")); + toolbar->AddTool(miBrushObject + 11, _("brush_c5_blocking"), wxBitmap(brush_object_c5_blocking), _("Invisible blocking object (unwalkable)")); + toolbar->AddSeparator(); + toolbar->AddTool(toolPlayer, _("brush_player"), wxBitmap(brush_players_player), _("Player start position")); + toolbar->Realize(); - wxToolBar *toolbar2 = new MainToolBar(this->panel, wxID_ANY); - toolbar2->AddTool(miBrushGradient + 1, _("brush_gradient_n5"), wxBitmap(brush_gradient_n5)); - toolbar2->AddTool(miBrushGradient + 2, _("brush_gradient_n4"), wxBitmap(brush_gradient_n4)); - toolbar2->AddTool(miBrushGradient + 3, _("brush_gradient_n3"), wxBitmap(brush_gradient_n3)); - toolbar2->AddTool(miBrushGradient + 4, _("brush_gradient_n2"), wxBitmap(brush_gradient_n2)); - toolbar2->AddTool(miBrushGradient + 5, _("brush_gradient_n1"), wxBitmap(brush_gradient_n1)); - toolbar2->AddTool(miBrushGradient + 6, _("brush_gradient_0"), wxBitmap(brush_gradient_0)); - toolbar2->AddTool(miBrushGradient + 7, _("brush_gradient_p1"), wxBitmap(brush_gradient_p1)); - toolbar2->AddTool(miBrushGradient + 8, _("brush_gradient_p2"), wxBitmap(brush_gradient_p2)); - toolbar2->AddTool(miBrushGradient + 9, _("brush_gradient_p3"), wxBitmap(brush_gradient_p3)); - toolbar2->AddTool(miBrushGradient +10, _("brush_gradient_p4"), wxBitmap(brush_gradient_p4)); - toolbar2->AddTool(miBrushGradient +11, _("brush_gradient_p5"), wxBitmap(brush_gradient_p5)); - toolbar2->AddSeparator(); - toolbar2->AddTool(miBrushHeight + 1, _("brush_height_n5"), wxBitmap(brush_height_n5)); - toolbar2->AddTool(miBrushHeight + 2, _("brush_height_n4"), wxBitmap(brush_height_n4)); - toolbar2->AddTool(miBrushHeight + 3, _("brush_height_n3"), wxBitmap(brush_height_n3)); - toolbar2->AddTool(miBrushHeight + 4, _("brush_height_n2"), wxBitmap(brush_height_n2)); - toolbar2->AddTool(miBrushHeight + 5, _("brush_height_n1"), wxBitmap(brush_height_n1)); - toolbar2->AddTool(miBrushHeight + 6, _("brush_height_0"), wxBitmap(brush_height_0)); - toolbar2->AddTool(miBrushHeight + 7, _("brush_height_p1"), wxBitmap(brush_height_p1)); - toolbar2->AddTool(miBrushHeight + 8, _("brush_height_p2"), wxBitmap(brush_height_p2)); - toolbar2->AddTool(miBrushHeight + 9, _("brush_height_p3"), wxBitmap(brush_height_p3)); - toolbar2->AddTool(miBrushHeight +10, _("brush_height_p4"), wxBitmap(brush_height_p4)); - toolbar2->AddTool(miBrushHeight +11, _("brush_height_p5"), wxBitmap(brush_height_p5)); - toolbar2->AddSeparator(); - toolbar2->AddTool(miRadius + 1, _("radius1"), wxBitmap(radius_1), _("1 (1x1)")); - toolbar2->AddTool(miRadius + 2, _("radius2"), wxBitmap(radius_2), _("2 (3x3)")); - toolbar2->AddTool(miRadius + 3, _("radius3"), wxBitmap(radius_3), _("3 (5x5)")); - toolbar2->AddTool(miRadius + 4, _("radius4"), wxBitmap(radius_4), _("4 (7x7)")); - toolbar2->AddTool(miRadius + 5, _("radius5"), wxBitmap(radius_5), _("5 (9x9)")); - toolbar2->AddTool(miRadius + 6, _("radius6"), wxBitmap(radius_6), _("6 (11x11)")); - toolbar2->AddTool(miRadius + 7, _("radius7"), wxBitmap(radius_7), _("7 (13x13)")); - toolbar2->AddTool(miRadius + 8, _("radius8"), wxBitmap(radius_8), _("8 (15x15)")); - toolbar2->AddTool(miRadius + 9, _("radius9"), wxBitmap(radius_9), _("9 (17x17)")); - toolbar2->Realize(); + wxToolBar *toolbar2 = new MainToolBar(this->panel, wxID_ANY); + toolbar2->AddTool(miBrushGradient + 1, _("brush_gradient_n5"), wxBitmap(brush_gradient_n5)); + toolbar2->AddTool(miBrushGradient + 2, _("brush_gradient_n4"), wxBitmap(brush_gradient_n4)); + toolbar2->AddTool(miBrushGradient + 3, _("brush_gradient_n3"), wxBitmap(brush_gradient_n3)); + toolbar2->AddTool(miBrushGradient + 4, _("brush_gradient_n2"), wxBitmap(brush_gradient_n2)); + toolbar2->AddTool(miBrushGradient + 5, _("brush_gradient_n1"), wxBitmap(brush_gradient_n1)); + toolbar2->AddTool(miBrushGradient + 6, _("brush_gradient_0"), wxBitmap(brush_gradient_0)); + toolbar2->AddTool(miBrushGradient + 7, _("brush_gradient_p1"), wxBitmap(brush_gradient_p1)); + toolbar2->AddTool(miBrushGradient + 8, _("brush_gradient_p2"), wxBitmap(brush_gradient_p2)); + toolbar2->AddTool(miBrushGradient + 9, _("brush_gradient_p3"), wxBitmap(brush_gradient_p3)); + toolbar2->AddTool(miBrushGradient + 10, _("brush_gradient_p4"), wxBitmap(brush_gradient_p4)); + toolbar2->AddTool(miBrushGradient + 11, _("brush_gradient_p5"), wxBitmap(brush_gradient_p5)); + toolbar2->AddSeparator(); + toolbar2->AddTool(miBrushHeight + 1, _("brush_height_n5"), wxBitmap(brush_height_n5)); + toolbar2->AddTool(miBrushHeight + 2, _("brush_height_n4"), wxBitmap(brush_height_n4)); + toolbar2->AddTool(miBrushHeight + 3, _("brush_height_n3"), wxBitmap(brush_height_n3)); + toolbar2->AddTool(miBrushHeight + 4, _("brush_height_n2"), wxBitmap(brush_height_n2)); + toolbar2->AddTool(miBrushHeight + 5, _("brush_height_n1"), wxBitmap(brush_height_n1)); + toolbar2->AddTool(miBrushHeight + 6, _("brush_height_0"), wxBitmap(brush_height_0)); + toolbar2->AddTool(miBrushHeight + 7, _("brush_height_p1"), wxBitmap(brush_height_p1)); + toolbar2->AddTool(miBrushHeight + 8, _("brush_height_p2"), wxBitmap(brush_height_p2)); + toolbar2->AddTool(miBrushHeight + 9, _("brush_height_p3"), wxBitmap(brush_height_p3)); + toolbar2->AddTool(miBrushHeight + 10, _("brush_height_p4"), wxBitmap(brush_height_p4)); + toolbar2->AddTool(miBrushHeight + 11, _("brush_height_p5"), wxBitmap(brush_height_p5)); + toolbar2->AddSeparator(); + toolbar2->AddTool(miRadius + 1, _("radius1"), wxBitmap(radius_1), _("1 (1x1)")); + toolbar2->AddTool(miRadius + 2, _("radius2"), wxBitmap(radius_2), _("2 (3x3)")); + toolbar2->AddTool(miRadius + 3, _("radius3"), wxBitmap(radius_3), _("3 (5x5)")); + toolbar2->AddTool(miRadius + 4, _("radius4"), wxBitmap(radius_4), _("4 (7x7)")); + toolbar2->AddTool(miRadius + 5, _("radius5"), wxBitmap(radius_5), _("5 (9x9)")); + toolbar2->AddTool(miRadius + 6, _("radius6"), wxBitmap(radius_6), _("6 (11x11)")); + toolbar2->AddTool(miRadius + 7, _("radius7"), wxBitmap(radius_7), _("7 (13x13)")); + toolbar2->AddTool(miRadius + 8, _("radius8"), wxBitmap(radius_8), _("8 (15x15)")); + toolbar2->AddTool(miRadius + 9, _("radius9"), wxBitmap(radius_9), _("9 (17x17)")); + toolbar2->Realize(); - Config &config = Config::getInstance(); + Config &config = Config::getInstance(); - string userData = config.getString("UserData_Root",""); - if(userData != "") { - endPathWithSlash(userData); - } + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } - //std::cout << "A" << std::endl; - wxInitAllImageHandlers(); + //std::cout << "A" << std::endl; + wxInitAllImageHandlers(); #ifdef WIN32 - //std::cout << "B" << std::endl; -// #if defined(__MINGW32__) + //std::cout << "B" << std::endl; + // #if defined(__MINGW32__) wxIcon icon(ToUnicode("IDI_ICON1")); -// #else -// wxIcon icon("IDI_ICON1"); -// #endif + // #else + // wxIcon icon("IDI_ICON1"); + // #endif #else - //std::cout << "B" << std::endl; - wxIcon icon; - string iniFilePath = extractDirectoryPathFromFile(config.getFileName(false)); - string icon_file = iniFilePath + "editor.ico"; - std::ifstream testFile(icon_file.c_str()); - if(testFile.good()) { - testFile.close(); - icon.LoadFile(ToUnicode(icon_file.c_str()),wxBITMAP_TYPE_ICO); - } -#endif - //std::cout << "C" << std::endl; - SetIcon(icon); - fileDialog = new wxFileDialog(this); - string defaultPath = userData + "maps/"; - fileDialog->SetDirectory(ToUnicode(defaultPath)); - - //printf("Default Path [%s]\n",defaultPath.c_str()); - - lastPaintEvent.start(); - - boxsizer = new wxBoxSizer(wxVERTICAL); - boxsizer->Add(toolbar, 0, wxEXPAND); - boxsizer->Add(toolbar2, 0, wxEXPAND); - //boxsizer->Add(glCanvas, 1, wxEXPAND); - - this->panel->SetSizer(boxsizer); - //this->Layout(); - - //program = new Program(glCanvas->GetClientSize().x, glCanvas->GetClientSize().y); - - fileName = "New (unsaved) Map"; - - //printf("Does file exist, fname [%s]\n",fname.c_str()); - - if (fname.empty() == false && fileExists(fname)) { - //printf("YES file exist, fname [%s]\n",fname.c_str()); - - //program->loadMap(fname); - currentFile = fname; - fileName = cutLastExt(extractFileFromDirectoryPath(fname.c_str())); - fileDialog->SetPath(ToUnicode(fname)); - } - SetTitle(ToUnicode(currentFile + " - " + winHeader)); - //setDirty(false); - //setExtension(); - - initGlCanvas(); - #if wxCHECK_VERSION(2, 9, 3) - //glCanvas->setCurrentGLContext(); - //printf("setcurrent #1\n"); - #elif wxCHECK_VERSION(2, 9, 1) - - #else - if(glCanvas) glCanvas->SetCurrent(); - //printf("setcurrent #2\n"); - #endif - - if(startupSettingsInited == false) { - startupSettingsInited = true; - setupStartupSettings(); - } -} - -void MainWindow::onClose(wxCloseEvent &event) { - if(program != NULL && program->getMap()->getHasChanged() == true) { - if( wxMessageDialog(NULL, ToUnicode("Do you want to save the current map?"), - ToUnicode("Question"), wxYES_NO | wxYES_DEFAULT).ShowModal() == wxID_YES) { - wxCommandEvent ev; - MainWindow::onMenuFileSave(ev); + //std::cout << "B" << std::endl; + wxIcon icon; + string iniFilePath = extractDirectoryPathFromFile(config.getFileName(false)); + string icon_file = iniFilePath + "editor.ico"; + std::ifstream testFile(icon_file.c_str()); + if (testFile.good()) { + testFile.close(); + icon.LoadFile(ToUnicode(icon_file.c_str()), wxBITMAP_TYPE_ICO); } - } - delete program; - program = NULL; +#endif + //std::cout << "C" << std::endl; + SetIcon(icon); + fileDialog = new wxFileDialog(this); + string defaultPath = userData + "maps/"; + fileDialog->SetDirectory(ToUnicode(defaultPath)); - //delete glCanvas; - if(glCanvas) glCanvas->Destroy(); - glCanvas = NULL; + //printf("Default Path [%s]\n",defaultPath.c_str()); - this->Destroy(); -} + lastPaintEvent.start(); -void MainWindow::initGlCanvas(){ - if(glCanvas == NULL) { - int args[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_MIN_ALPHA, 8 }; - glCanvas = new GlCanvas(this, this->panel, args); - - boxsizer->Add(glCanvas, 1, wxEXPAND); - } -} - -void MainWindow::setupStartupSettings() { - - //gl canvas - if(glCanvas == NULL) { - initGlCanvas(); - - boxsizer->Add(glCanvas, 1, wxEXPAND); + boxsizer = new wxBoxSizer(wxVERTICAL); + boxsizer->Add(toolbar, 0, wxEXPAND); + boxsizer->Add(toolbar2, 0, wxEXPAND); + //boxsizer->Add(glCanvas, 1, wxEXPAND); this->panel->SetSizer(boxsizer); - this->Layout(); - } - glCanvas->setCurrentGLContext(); - glCanvas->SetFocus(); + //this->Layout(); - string playerName = Config::getInstance().getString("NetPlayerName",""); - program = new Program(glCanvas->GetClientSize().x, glCanvas->GetClientSize().y, playerName); - fileName = "New (unsaved) Map"; + //program = new Program(glCanvas->GetClientSize().x, glCanvas->GetClientSize().y); - //printf("#0 file load [%s]\n",currentFile.c_str()); + fileName = "New (unsaved) Map"; - if (!currentFile.empty() && fileExists(currentFile)) { - //printf("#0 exists file load [%s]\n",currentFile.c_str()); + //printf("Does file exist, fname [%s]\n",fname.c_str()); - program->loadMap(currentFile); - //currentFile = fname; - fileName = cutLastExt(extractFileFromDirectoryPath(currentFile.c_str())); - fileDialog->SetPath(ToUnicode(currentFile)); - } - SetTitle(ToUnicode(currentFile + " - " + winHeader)); - setDirty(false); - setExtension(); -} + if (fname.empty() == false && fileExists(fname)) { + //printf("YES file exist, fname [%s]\n",fname.c_str()); -MainWindow::~MainWindow() { - delete fileDialog; - fileDialog = NULL; - - delete program; - program = NULL; - - delete glCanvas; - glCanvas = NULL; -} - -void MainWindow::setDirty(bool val) { - wxPaintEvent ev; - onPaint(ev); - if (fileModified && val) { - return; - } - fileModified = val; - if (fileModified) { - SetStatusText(wxT("File: ") + ToUnicode(fileName) + wxT("*"), siFILE_NAME); - } else { - SetStatusText(wxT("File: ") + ToUnicode(fileName), siFILE_NAME); - } -} - -void MainWindow::setExtension() { - if (currentFile.empty() || program == NULL) { - return; - } - - string extnsn = ext(currentFile); - - //printf("#A currentFile [%s] extnsn [%s]\n",currentFile.c_str(),extnsn.c_str()); - - if (extnsn == "gbm" || extnsn == "mgm") { - currentFile = cutLastExt(currentFile); - } - SetStatusText(wxT(".mgm"), siFILE_TYPE); - currentFile += ".mgm"; -} - -void MainWindow::onMouseDown(wxMouseEvent &event, int x, int y) { - if (event.LeftIsDown() && program != NULL) { - program->setUndoPoint(enabledGroup); - program->setRefAlt(x, y); - change(x, y); - if (!isDirty()) { - setDirty(true); + //program->loadMap(fname); + currentFile = fname; + fileName = cutLastExt(extractFileFromDirectoryPath(fname.c_str())); + fileDialog->SetPath(ToUnicode(fname)); } + SetTitle(ToUnicode(currentFile + " - " + winHeader)); + //setDirty(false); + //setExtension(); + + initGlCanvas(); +#if wxCHECK_VERSION(2, 9, 3) + //glCanvas->setCurrentGLContext(); + //printf("setcurrent #1\n"); +#elif wxCHECK_VERSION(2, 9, 1) + +#else + if (glCanvas) glCanvas->SetCurrent(); + //printf("setcurrent #2\n"); +#endif + + if (startupSettingsInited == false) { + startupSettingsInited = true; + setupStartupSettings(); + } + } + + void MainWindow::onClose(wxCloseEvent &event) { + if (program != NULL && program->getMap()->getHasChanged() == true) { + if (wxMessageDialog(NULL, ToUnicode("Do you want to save the current map?"), + ToUnicode("Question"), wxYES_NO | wxYES_DEFAULT).ShowModal() == wxID_YES) { + wxCommandEvent ev; + MainWindow::onMenuFileSave(ev); + } + } + delete program; + program = NULL; + + //delete glCanvas; + if (glCanvas) glCanvas->Destroy(); + glCanvas = NULL; + + this->Destroy(); + } + + void MainWindow::initGlCanvas() { + if (glCanvas == NULL) { + int args[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_MIN_ALPHA, 8 }; + glCanvas = new GlCanvas(this, this->panel, args); + + boxsizer->Add(glCanvas, 1, wxEXPAND); + } + } + + void MainWindow::setupStartupSettings() { + + //gl canvas + if (glCanvas == NULL) { + initGlCanvas(); + + boxsizer->Add(glCanvas, 1, wxEXPAND); + + this->panel->SetSizer(boxsizer); + this->Layout(); + } + glCanvas->setCurrentGLContext(); + glCanvas->SetFocus(); + + string playerName = Config::getInstance().getString("NetPlayerName", ""); + program = new Program(glCanvas->GetClientSize().x, glCanvas->GetClientSize().y, playerName); + fileName = "New (unsaved) Map"; + + //printf("#0 file load [%s]\n",currentFile.c_str()); + + if (!currentFile.empty() && fileExists(currentFile)) { + //printf("#0 exists file load [%s]\n",currentFile.c_str()); + + program->loadMap(currentFile); + //currentFile = fname; + fileName = cutLastExt(extractFileFromDirectoryPath(currentFile.c_str())); + fileDialog->SetPath(ToUnicode(currentFile)); + } + SetTitle(ToUnicode(currentFile + " - " + winHeader)); + setDirty(false); + setExtension(); + } + + MainWindow::~MainWindow() { + delete fileDialog; + fileDialog = NULL; + + delete program; + program = NULL; + + delete glCanvas; + glCanvas = NULL; + } + + void MainWindow::setDirty(bool val) { wxPaintEvent ev; onPaint(ev); - } - event.Skip(); -} - -// for the mousewheel -void MainWindow::onMouseWheelDown(wxMouseEvent &event) { - if(program == NULL) { - return; - } - wxPaintEvent ev; - program->incCellSize(1); - onPaint(ev); -} - -void MainWindow::onMouseWheelUp(wxMouseEvent &event) { - if(program == NULL) { - return; - } - wxPaintEvent ev; - program->incCellSize(-1); - onPaint(ev); -} - -void MainWindow::onMouseMove(wxMouseEvent &event, int x, int y) { - if(program == NULL) { - return; - } - bool repaint = false; - if (event.LeftIsDown()) { - change(x, y); - repaint = true; - } else if (event.MiddleIsDown()) { - int dif = (y - lastY); - if (dif != 0) { - program->incCellSize(dif / abs(dif)); - repaint = true; + if (fileModified && val) { + return; } - } else if (event.RightIsDown()) { - program->setOfset(x - lastX, y - lastY); - repaint = true; - } else { - int currResource = program->getResource(x, y); - if (currResource > 0) { - SetStatusText(wxT("Resource: ") + ToUnicode(resource_descs[currResource]), siCURR_OBJECT); - resourceUnderMouse = currResource; - objectUnderMouse = 0; + fileModified = val; + if (fileModified) { + SetStatusText(wxT("File: ") + ToUnicode(fileName) + wxT("*"), siFILE_NAME); } else { - int currObject = program->getObject(x, y); - SetStatusText(wxT("Object: ") + ToUnicode(object_descs[currObject]), siCURR_OBJECT); - resourceUnderMouse = 0; - objectUnderMouse = currObject; + SetStatusText(wxT("File: ") + ToUnicode(fileName), siFILE_NAME); + } + } + + void MainWindow::setExtension() { + if (currentFile.empty() || program == NULL) { + return; } - SetStatusText(wxT("Pos (Ingame): ") - + ToUnicode(intToStr(program->getCellX(x)) - + "," - + intToStr(program->getCellY(y)) - + " (" - + intToStr(2*(program->getCellX(x))) - + "," - + intToStr(2*(program->getCellY(y))) - + ")"), siPOS_VALUE); -//#ifdef WIN32 - //repaint = true; -//#endif - } - lastX = x; - lastY = y; + string extnsn = ext(currentFile); - if (repaint) { + //printf("#A currentFile [%s] extnsn [%s]\n",currentFile.c_str(),extnsn.c_str()); + + if (extnsn == "gbm" || extnsn == "mgm") { + currentFile = cutLastExt(currentFile); + } + SetStatusText(wxT(".mgm"), siFILE_TYPE); + currentFile += ".mgm"; + } + + void MainWindow::onMouseDown(wxMouseEvent &event, int x, int y) { + if (event.LeftIsDown() && program != NULL) { + program->setUndoPoint(enabledGroup); + program->setRefAlt(x, y); + change(x, y); + if (!isDirty()) { + setDirty(true); + } + wxPaintEvent ev; + onPaint(ev); + } + event.Skip(); + } + + // for the mousewheel + void MainWindow::onMouseWheelDown(wxMouseEvent &event) { + if (program == NULL) { + return; + } wxPaintEvent ev; + program->incCellSize(1); onPaint(ev); } - event.Skip(); -} -void MainWindow::onPaint(wxPaintEvent &event) { - //printf("onPaint map\n"); + void MainWindow::onMouseWheelUp(wxMouseEvent &event) { + if (program == NULL) { + return; + } + wxPaintEvent ev; + program->incCellSize(-1); + onPaint(ev); + } - if(!IsShown()) { - //printf("onPaint skip map\n"); + void MainWindow::onMouseMove(wxMouseEvent &event, int x, int y) { + if (program == NULL) { + return; + } + bool repaint = false; + if (event.LeftIsDown()) { + change(x, y); + repaint = true; + } else if (event.MiddleIsDown()) { + int dif = (y - lastY); + if (dif != 0) { + program->incCellSize(dif / abs(dif)); + repaint = true; + } + } else if (event.RightIsDown()) { + program->setOfset(x - lastX, y - lastY); + repaint = true; + } else { + int currResource = program->getResource(x, y); + if (currResource > 0) { + SetStatusText(wxT("Resource: ") + ToUnicode(resource_descs[currResource]), siCURR_OBJECT); + resourceUnderMouse = currResource; + objectUnderMouse = 0; + } else { + int currObject = program->getObject(x, y); + SetStatusText(wxT("Object: ") + ToUnicode(object_descs[currObject]), siCURR_OBJECT); + resourceUnderMouse = 0; + objectUnderMouse = currObject; + } + SetStatusText(wxT("Pos (Ingame): ") + + ToUnicode(intToStr(program->getCellX(x)) + + "," + + intToStr(program->getCellY(y)) + + " (" + + intToStr(2 * (program->getCellX(x))) + + "," + + intToStr(2 * (program->getCellY(y))) + + ")"), siPOS_VALUE); + //#ifdef WIN32 + //repaint = true; + //#endif + } + lastX = x; + lastY = y; + + if (repaint) { + wxPaintEvent ev; + onPaint(ev); + } event.Skip(); - return; } -//#if wxCHECK_VERSION(2, 9, 3) + void MainWindow::onPaint(wxPaintEvent &event) { + //printf("onPaint map\n"); -//#elif wxCHECK_VERSION(2, 9, 1) -// glCanvas->setCurrentGLContext(); -//#endif + if (!IsShown()) { + //printf("onPaint skip map\n"); - //static bool contextSet = false; - //if(contextSet == false) { - // contextSet = true; - glCanvas->setCurrentGLContext(); - //} + event.Skip(); + return; + } - //printf("lastPaintEvent.getMillis() map\n"); - if(lastPaintEvent.getMillis() < 30) { - sleep(1); + //#if wxCHECK_VERSION(2, 9, 3) + + //#elif wxCHECK_VERSION(2, 9, 1) + // glCanvas->setCurrentGLContext(); + //#endif + + //static bool contextSet = false; + //if(contextSet == false) { + // contextSet = true; + glCanvas->setCurrentGLContext(); + //} + + //printf("lastPaintEvent.getMillis() map\n"); + if (lastPaintEvent.getMillis() < 30) { + sleep(1); + event.Skip(); + return; + } + + //printf("wxPaintDC dc map\n"); + wxPaintDC dc(this); // "In a paint event handler must always create a wxPaintDC object even if you do not use it. (?) + // Otherwise, under MS Windows, refreshing for this and other windows will go wrong" + // http://docs.wxwidgets.org/2.6/wx_wxpaintevent.html + + lastPaintEvent.start(); + + if (panel) panel->Refresh(false); + if (menuBar) menuBar->Refresh(false); + + refreshMapRender(); event.Skip(); - return; } - //printf("wxPaintDC dc map\n"); - wxPaintDC dc(this); // "In a paint event handler must always create a wxPaintDC object even if you do not use it. (?) - // Otherwise, under MS Windows, refreshing for this and other windows will go wrong" - // http://docs.wxwidgets.org/2.6/wx_wxpaintevent.html + void MainWindow::refreshMapRender() { + //printf("refreshMapRender map\n"); - lastPaintEvent.start(); - - if(panel) panel->Refresh(false); - if(menuBar) menuBar->Refresh(false); - - refreshMapRender(); - event.Skip(); -} - -void MainWindow::refreshMapRender() { - //printf("refreshMapRender map\n"); - - if(program && glCanvas) { - program->renderMap(glCanvas->GetClientSize().x, glCanvas->GetClientSize().y); - glCanvas->SwapBuffers(); - } -} - -void MainWindow::onMenuFileLoad(wxCommandEvent &event) { - if(program == NULL) { - return; + if (program && glCanvas) { + program->renderMap(glCanvas->GetClientSize().x, glCanvas->GetClientSize().y); + glCanvas->SwapBuffers(); + } } - try { - fileDialog->SetMessage(wxT("Select Glestmap to load")); - fileDialog->SetWildcard(wxT("Glest&Mega Map (*.gbm *.mgm)|*.gbm;*.mgm|Glest Map (*.gbm)|*.gbm|Mega Map (*.mgm)|*.mgm")); - if (fileDialog->ShowModal() == wxID_OK) { + void MainWindow::onMenuFileLoad(wxCommandEvent &event) { + if (program == NULL) { + return; + } + + try { + fileDialog->SetMessage(wxT("Select Glestmap to load")); + fileDialog->SetWildcard(wxT("Glest&Mega Map (*.gbm *.mgm)|*.gbm;*.mgm|Glest Map (*.gbm)|*.gbm|Mega Map (*.mgm)|*.mgm")); + if (fileDialog->ShowModal() == wxID_OK) { #ifdef WIN32 - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(fileDialog->GetPath())); + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(fileDialog->GetPath())); + currentFile = tmp_buf; + + auto_ptr wstr(Ansi2WideString(currentFile.c_str())); + currentFile = utf8_encode(wstr.get()); +#elif wxCHECK_VERSION(2, 9, 1) + currentFile = fileDialog->GetPath().ToStdString(); +#else + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(fileDialog->GetPath()); + currentFile = tmp_buf; +#endif + + //printf("#1 file load [%s]\n",currentFile.c_str()); + + program->loadMap(currentFile); + fileName = cutLastExt(extractFileFromDirectoryPath(currentFile.c_str())); + setDirty(false); + setExtension(); + SetTitle(ToUnicode(winHeader + "; " + currentFile)); + } + } catch (const string &e) { + MsgDialog(this, ToUnicode(e), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); + } catch (const exception &e) { + MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); + } + + } + + void MainWindow::onMenuFileSave(wxCommandEvent &event) { + if (program == NULL) { + return; + } + + if (currentFile.empty()) { + wxCommandEvent ev; + onMenuFileSaveAs(ev); + } else { + setExtension(); + + //printf("#1 save load [%s]\n",currentFile.c_str()); + + program->saveMap(currentFile); + setDirty(false); + } + } + + void MainWindow::onMenuFileSaveAs(wxCommandEvent &event) { + if (program == NULL) { + return; + } + +#if wxCHECK_VERSION(2, 9, 1) + wxFileDialog fd(this, wxT("Select file"), wxT(""), wxT(""), wxT("*.mgm|*.gbm"), wxFD_SAVE); +#else + wxFileDialog fd(this, wxT("Select file"), wxT(""), wxT(""), wxT("*.mgm|*.gbm"), wxSAVE); +#endif + + if (fileDialog->GetPath() != ToUnicode("")) { + fd.SetPath(fileDialog->GetPath()); + } else { + Config &config = Config::getInstance(); + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + string defaultPath = userData + "maps/"; + fd.SetDirectory(ToUnicode(defaultPath)); + } + + fd.SetWildcard(wxT("ZetaGlest Map (*.mgm)|*.mgm|Glest Map (*.gbm)|*.gbm")); + if (fd.ShowModal() == wxID_OK) { +#ifdef WIN32 + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(fd.GetPath())); currentFile = tmp_buf; auto_ptr wstr(Ansi2WideString(currentFile.c_str())); currentFile = utf8_encode(wstr.get()); #elif wxCHECK_VERSION(2, 9, 1) - currentFile = fileDialog->GetPath().ToStdString(); + currentFile = fd.GetPath().ToStdString(); #else - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(fileDialog->GetPath()); + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(fd.GetPath()); currentFile = tmp_buf; #endif - //printf("#1 file load [%s]\n",currentFile.c_str()); + fileDialog->SetPath(fd.GetPath()); + setExtension(); - program->loadMap(currentFile); + //printf("#2 file save [%s]\n",currentFile.c_str()); + + program->saveMap(currentFile); fileName = cutLastExt(extractFileFromDirectoryPath(currentFile.c_str())); setDirty(false); - setExtension(); - SetTitle(ToUnicode(winHeader + "; " + currentFile)); + } + SetTitle(ToUnicode(winHeader + "; " + currentFile)); + } + + void MainWindow::onMenuFileExit(wxCommandEvent &event) { + Close(); + } + + void MainWindow::onMenuEditUndo(wxCommandEvent &event) { + if (program == NULL) { + return; + } + + // std::cout << "Undo Pressed" << std::endl; + if (program->undo()) { + wxPaintEvent e; + onPaint(e); + setDirty(); } } - catch (const string &e) { - MsgDialog(this, ToUnicode(e), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); - } - catch (const exception &e) { - MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); - } -} - -void MainWindow::onMenuFileSave(wxCommandEvent &event) { - if(program == NULL) { - return; - } - - if (currentFile.empty()) { - wxCommandEvent ev; - onMenuFileSaveAs(ev); - } - else { - setExtension(); - - //printf("#1 save load [%s]\n",currentFile.c_str()); - - program->saveMap(currentFile); - setDirty(false); - } -} - -void MainWindow::onMenuFileSaveAs(wxCommandEvent &event) { - if(program == NULL) { - return; - } - -#if wxCHECK_VERSION(2, 9, 1) - wxFileDialog fd(this, wxT("Select file"), wxT(""), wxT(""), wxT("*.mgm|*.gbm"), wxFD_SAVE); -#else - wxFileDialog fd(this, wxT("Select file"), wxT(""), wxT(""), wxT("*.mgm|*.gbm"), wxSAVE); -#endif - - if(fileDialog->GetPath() != ToUnicode("")) { - fd.SetPath(fileDialog->GetPath()); - } - else { - Config &config = Config::getInstance(); - string userData = config.getString("UserData_Root",""); - if(userData != "") { - endPathWithSlash(userData); + void MainWindow::onMenuEditRedo(wxCommandEvent &event) { + if (program == NULL) { + return; + } + + if (program->redo()) { + wxPaintEvent e; + onPaint(e); + setDirty(); } - string defaultPath = userData + "maps/"; - fd.SetDirectory(ToUnicode(defaultPath)); } - fd.SetWildcard(wxT("ZetaGlest Map (*.mgm)|*.mgm|Glest Map (*.gbm)|*.gbm")); - if (fd.ShowModal() == wxID_OK) { -#ifdef WIN32 - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(fd.GetPath())); - currentFile = tmp_buf; - - auto_ptr wstr(Ansi2WideString(currentFile.c_str())); - currentFile = utf8_encode(wstr.get()); -#elif wxCHECK_VERSION(2, 9, 1) - currentFile = fd.GetPath().ToStdString(); -#else - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(fd.GetPath()); - currentFile = tmp_buf; -#endif - - fileDialog->SetPath(fd.GetPath()); - setExtension(); - - //printf("#2 file save [%s]\n",currentFile.c_str()); - - program->saveMap(currentFile); - fileName = cutLastExt(extractFileFromDirectoryPath(currentFile.c_str())); - setDirty(false); - } - SetTitle(ToUnicode(winHeader + "; " + currentFile)); -} - -void MainWindow::onMenuFileExit(wxCommandEvent &event) { - Close(); -} - -void MainWindow::onMenuEditUndo(wxCommandEvent &event) { - if(program == NULL) { - return; - } - - // std::cout << "Undo Pressed" << std::endl; - if (program->undo()) { - wxPaintEvent e; - onPaint(e); - setDirty(); - } -} - -void MainWindow::onMenuEditRedo(wxCommandEvent &event) { - if(program == NULL) { - return; - } - - if (program->redo()) { - wxPaintEvent e; - onPaint(e); - setDirty(); - } -} - -void MainWindow::onMenuEditReset(wxCommandEvent &event) { - if(program == NULL) { - return; - } - - program->setUndoPoint(ctAll); - SimpleDialog simpleDialog; - simpleDialog.addValue("Width", "128","(must be 16,32,64,128,256,512...)"); // must be an exponent of two - simpleDialog.addValue("Height", "128","(must be 16,32,64,128,256,512...)"); - simpleDialog.addValue("Surface", "1","(Default surface material)"); - simpleDialog.addValue("Altitude", "10","(Default surface height)"); - simpleDialog.addValue("Number of players", "8"); - if (!simpleDialog.show()) return; - - try { - program->reset( - strToInt(simpleDialog.getValue("Width")), - strToInt(simpleDialog.getValue("Height")), - strToInt(simpleDialog.getValue("Altitude")), - strToInt(simpleDialog.getValue("Surface"))); - program->resetFactions(strToInt(simpleDialog.getValue("Number of players"))); - } - catch (const exception &e) { - MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); - } - currentFile = ""; - fileName = "New (unsaved) map"; - - wxPaintEvent ev; - onPaint(ev); -} - -void MainWindow::onMenuEditResetPlayers(wxCommandEvent &event) { - if(program == NULL) { - return; - } - - SimpleDialog simpleDialog; - simpleDialog.addValue("Number of players", intToStr(program->getMap()->getMaxFactions())); - if (!simpleDialog.show("Reset players")) return; - - try { - program->resetFactions(strToInt(simpleDialog.getValue("Number of players"))); - } - catch (const exception &e) { - MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); - } - setDirty(); - setExtension(); -} - - -void MainWindow::onMenuEditFlipDiagonal(wxCommandEvent &event) { - if(program == NULL) { - return; - } - program->setUndoPoint(ctAll); - program->flipDiagonal(); - setDirty(); -} - -void MainWindow::onMenuEditResize(wxCommandEvent &event) { - if(program == NULL) { - return; - } - - SimpleDialog simpleDialog; - simpleDialog.addValue("Width", intToStr(program->getMap()->getW()),"(must be 16,32,64,128,256,512...)"); - simpleDialog.addValue("Height", intToStr(program->getMap()->getH()),"(must be 16,32,64,128,256,512...)"); - simpleDialog.addValue("Surface", "1","(surface material for new area around map)"); - simpleDialog.addValue("Altitude", "10","(surface height for new area around map)"); - if (!simpleDialog.show("Resize - expand around, shrink to topleft")) return; - - try { - program->resize( - strToInt(simpleDialog.getValue("Width")), - strToInt(simpleDialog.getValue("Height")), - strToInt(simpleDialog.getValue("Altitude")), - strToInt(simpleDialog.getValue("Surface"))); - } - catch (const exception &e) { - MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); - } - setDirty(); -} - -void MainWindow::onMenuEditFlipX(wxCommandEvent &event) { - if(program == NULL) { - return; - } - - program->setUndoPoint(ctAll); - program->flipX(); - setDirty(); -} - -void MainWindow::onMenuEditFlipY(wxCommandEvent &event) { - if(program == NULL) { - return; - } - - program->setUndoPoint(ctAll); - program->flipY(); - setDirty(); -} - -void MainWindow::onMenuEditMirrorX(wxCommandEvent &event) { // copy left to right - if(program == NULL) { - return; - } - - program->setUndoPoint(ctAll); - program->mirrorX(); - setDirty(); -} - -void MainWindow::onMenuEditMirrorY(wxCommandEvent &event) { // copy top to bottom - if(program == NULL) { - return; - } - - program->setUndoPoint(ctAll); - program->mirrorY(); - setDirty(); -} - -void MainWindow::onMenuEditMirrorXY(wxCommandEvent &event) { // copy bottomleft tp topright - if(program == NULL) { - return; - } - - program->setUndoPoint(ctAll); - program->mirrorXY(); - setDirty(); -} - -void MainWindow::onMenuEditRotatecopyX(wxCommandEvent &event) { // copy left to right, rotated - if(program == NULL) { - return; - } - - program->setUndoPoint(ctAll); - program->rotatecopyX(); - setDirty(); -} - -void MainWindow::onMenuEditRotatecopyY(wxCommandEvent &event) { // copy top to bottom, rotated - if(program == NULL) { - return; - } - - program->setUndoPoint(ctAll); - program->rotatecopyY(); - setDirty(); -} - -void MainWindow::onMenuEditRotatecopyXY(wxCommandEvent &event) { // copy bottomleft to topright, rotated - if(program == NULL) { - return; - } - - program->setUndoPoint(ctAll); - program->rotatecopyXY(); - setDirty(); -} - -void MainWindow::onMenuEditRotatecopyCorner(wxCommandEvent &event) { // copy top left 1/4 to top right 1/4, rotated - if(program == NULL) { - return; - } - - program->setUndoPoint(ctAll); - program->rotatecopyCorner(); - setDirty(); -} - - -void MainWindow::onMenuEditRandomizeHeights(wxCommandEvent &event) { - if(program == NULL) { - return; - } - while(true){ + void MainWindow::onMenuEditReset(wxCommandEvent &event) { + if (program == NULL) { + return; + } + program->setUndoPoint(ctAll); SimpleDialog simpleDialog; - simpleDialog.addValue("Initial Reset", boolToStr(randomWithReset),"(1 = true, 0 = false) If set to '0' no height reset is done before calculating"); - simpleDialog.addValue("Min Height", intToStr(randomMinimumHeight),"Lowest random height. example: -300 or below if you want water , 0 if you don't want water."); - simpleDialog.addValue("Max Height", intToStr(randomMaximumHeight),"Max random height. A good value is 400"); - simpleDialog.addValue("Chance Divider", intToStr(randomChanceDivider),"Defines how often you get a hill or hole default is 30. Bigger number, less hills/holes."); - simpleDialog.addValue("Smooth Recursions", intToStr(randomRecursions),"Number of recursions cycles to smooth the hills and holes. 0 1) { - randomWithReset = true; - } - else { - randomWithReset = strToBool(simpleDialog.getValue("Initial Reset")); - } - randomMinimumHeight=strToInt(simpleDialog.getValue("Min Height")); - randomMaximumHeight=strToInt(simpleDialog.getValue("Max Height")); - randomChanceDivider=strToInt(simpleDialog.getValue("Chance Divider")); - randomRecursions=strToInt(simpleDialog.getValue("Smooth Recursions")); - - // set insane inputs to something that does not crash - if(randomMinimumHeight>=randomMaximumHeight) randomMinimumHeight=randomMaximumHeight-1; - if(randomChanceDivider<1) randomChanceDivider=1; - - // set randomRecursions to something useful - if(randomRecursions<0) randomRecursions=0; - if(randomRecursions>50) randomRecursions=50; - - program->setUndoPoint(ctAll); - program->randomizeMapHeights(randomWithReset, randomMinimumHeight, randomMaximumHeight, - randomChanceDivider, randomRecursions); + program->reset( + strToInt(simpleDialog.getValue("Width")), + strToInt(simpleDialog.getValue("Height")), + strToInt(simpleDialog.getValue("Altitude")), + strToInt(simpleDialog.getValue("Surface"))); + program->resetFactions(strToInt(simpleDialog.getValue("Number of players"))); + } catch (const exception &e) { + MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); } - catch (const exception &e) { + currentFile = ""; + fileName = "New (unsaved) map"; + + wxPaintEvent ev; + onPaint(ev); + } + + void MainWindow::onMenuEditResetPlayers(wxCommandEvent &event) { + if (program == NULL) { + return; + } + + SimpleDialog simpleDialog; + simpleDialog.addValue("Number of players", intToStr(program->getMap()->getMaxFactions())); + if (!simpleDialog.show("Reset players")) return; + + try { + program->resetFactions(strToInt(simpleDialog.getValue("Number of players"))); + } catch (const exception &e) { + MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); + } + setDirty(); + setExtension(); + } + + + void MainWindow::onMenuEditFlipDiagonal(wxCommandEvent &event) { + if (program == NULL) { + return; + } + program->setUndoPoint(ctAll); + program->flipDiagonal(); + setDirty(); + } + + void MainWindow::onMenuEditResize(wxCommandEvent &event) { + if (program == NULL) { + return; + } + + SimpleDialog simpleDialog; + simpleDialog.addValue("Width", intToStr(program->getMap()->getW()), "(must be 16,32,64,128,256,512...)"); + simpleDialog.addValue("Height", intToStr(program->getMap()->getH()), "(must be 16,32,64,128,256,512...)"); + simpleDialog.addValue("Surface", "1", "(surface material for new area around map)"); + simpleDialog.addValue("Altitude", "10", "(surface height for new area around map)"); + if (!simpleDialog.show("Resize - expand around, shrink to topleft")) return; + + try { + program->resize( + strToInt(simpleDialog.getValue("Width")), + strToInt(simpleDialog.getValue("Height")), + strToInt(simpleDialog.getValue("Altitude")), + strToInt(simpleDialog.getValue("Surface"))); + } catch (const exception &e) { MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); } setDirty(); } -} -void MainWindow::onMenuEditRandomize(wxCommandEvent &event) { - if(program == NULL) { - return; - } - - program->setUndoPoint(ctAll); - program->randomizeFactions(); - setDirty(); -} - -void MainWindow::onMenuEditSwitchSurfaces(wxCommandEvent &event) { - if(program == NULL) { - return; - } - - SimpleDialog simpleDialog; - simpleDialog.addValue("Surface1", "1","replace this surface with..."); - simpleDialog.addValue("Surface2", "2","...this and vice versa"); - if (!simpleDialog.show("Switch surfaces")) return; - - try { - program->setUndoPoint(ctSurface); - program->switchMapSurfaces( - strToInt(simpleDialog.getValue("Surface1")), - strToInt(simpleDialog.getValue("Surface2"))); - } - catch (const exception &e) { - MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); - } - setDirty(); -} - -void MainWindow::onMenuEditInfo(wxCommandEvent &event) { - if(program == NULL) { - return; - } - - SimpleDialog simpleDialog; - simpleDialog.addValue("Title", program->getMap()->getTitle()); - simpleDialog.addValue("Description", program->getMap()->getDesc()); - simpleDialog.addValue("Author", program->getMap()->getAuthor()); - if (!simpleDialog.show("Info",true)) return; - - bool ischanged = program->setMapTitle(simpleDialog.getValue("Title")); - ischanged = (program->setMapDesc(simpleDialog.getValue("Description")) || ischanged); - ischanged = (program->setMapAuthor(simpleDialog.getValue("Author")) || ischanged); - if (ischanged) - if (!isDirty()) { - setDirty(true); + void MainWindow::onMenuEditFlipX(wxCommandEvent &event) { + if (program == NULL) { + return; } -} - -void MainWindow::onMenuEditAdvanced(wxCommandEvent &event) { - if(program == NULL) { - return; + program->setUndoPoint(ctAll); + program->flipX(); + setDirty(); } - SimpleDialog simpleDialog; - simpleDialog.addValue("Height Factor", intToStr(program->getMap()->getHeightFactor()),"lower means more hill effect. Numbers above 100 are handled like this:\nx=x/100 ,so a 150 will mean 1.5 in the game."); - simpleDialog.addValue("Water Level", intToStr(program->getMap()->getWaterLevel()),"water is visible below this, and walkable until 1.5 less"); - simpleDialog.addValue("Cliff Level", intToStr(program->getMap()->getCliffLevel()),"neighboring fields with at least this heights difference are cliffs"); - simpleDialog.addValue("Camera Height", intToStr(program->getMap()->getCameraHeight()),"you can give a camera height here default is 0 ;ignored if <20"); - if (!simpleDialog.show("Advanced")) return; + void MainWindow::onMenuEditFlipY(wxCommandEvent &event) { + if (program == NULL) { + return; + } - try { - program->setMapAdvanced( - strToInt(simpleDialog.getValue("Height Factor")), - strToInt(simpleDialog.getValue("Water Level")), - strToInt(simpleDialog.getValue("Cliff Level")), - strToInt(simpleDialog.getValue("Camera Height"))); - } - catch (const exception &e) { - MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); - } - setDirty(); -} - -void MainWindow::onMenuViewResetZoomAndPos(wxCommandEvent &event) { - if(program == NULL) { - return; + program->setUndoPoint(ctAll); + program->flipY(); + setDirty(); } - program->resetOfset(); - wxPaintEvent e; - onPaint(e); -} + void MainWindow::onMenuEditMirrorX(wxCommandEvent &event) { // copy left to right + if (program == NULL) { + return; + } -void MainWindow::onMenuViewGrid(wxCommandEvent &event) { - if(program == NULL) { - return; + program->setUndoPoint(ctAll); + program->mirrorX(); + setDirty(); } - menuView->Check(miViewGrid, program->setGridOnOff()); // miViewGrid event.GetId() - wxPaintEvent e; - onPaint(e); -} + void MainWindow::onMenuEditMirrorY(wxCommandEvent &event) { // copy top to bottom + if (program == NULL) { + return; + } - -void MainWindow::onMenuViewHeightMap(wxCommandEvent &event) { - if(program == NULL) { - return; + program->setUndoPoint(ctAll); + program->mirrorY(); + setDirty(); } - menuView->Check(miViewHeightMap, program->setHeightMapOnOff()); // miViewGrid event.GetId() - wxPaintEvent e; - onPaint(e); -} -void MainWindow::onMenuHideWater(wxCommandEvent &event) { - if(program == NULL) { - return; + void MainWindow::onMenuEditMirrorXY(wxCommandEvent &event) { // copy bottomleft tp topright + if (program == NULL) { + return; + } + + program->setUndoPoint(ctAll); + program->mirrorXY(); + setDirty(); } - menuView->Check(miHideWater, program->setHideWaterOnOff()); // miViewGrid event.GetId() - wxPaintEvent e; - onPaint(e); -} -void MainWindow::onMenuViewAbout(wxCommandEvent &event) { - MsgDialog( - this, - wxT("\n ZetaGlest Map Editor\n Copyright 2004-2010 The Glest Team\n Copyright 2010-2018 The MegaGlest Team \n"), - wxT("About")).ShowModal(); -} + void MainWindow::onMenuEditRotatecopyX(wxCommandEvent &event) { // copy left to right, rotated + if (program == NULL) { + return; + } -void MainWindow::onMenuViewHelp(wxCommandEvent &event) { - MsgDialog(this, - wxT("Draw with left mouse\nMove viewport with right mouse drag\nZoom with center mouse drag, or mousewheel\n\n\ + program->setUndoPoint(ctAll); + program->rotatecopyX(); + setDirty(); + } + + void MainWindow::onMenuEditRotatecopyY(wxCommandEvent &event) { // copy top to bottom, rotated + if (program == NULL) { + return; + } + + program->setUndoPoint(ctAll); + program->rotatecopyY(); + setDirty(); + } + + void MainWindow::onMenuEditRotatecopyXY(wxCommandEvent &event) { // copy bottomleft to topright, rotated + if (program == NULL) { + return; + } + + program->setUndoPoint(ctAll); + program->rotatecopyXY(); + setDirty(); + } + + void MainWindow::onMenuEditRotatecopyCorner(wxCommandEvent &event) { // copy top left 1/4 to top right 1/4, rotated + if (program == NULL) { + return; + } + + program->setUndoPoint(ctAll); + program->rotatecopyCorner(); + setDirty(); + } + + + void MainWindow::onMenuEditRandomizeHeights(wxCommandEvent &event) { + if (program == NULL) { + return; + } + while (true) { + + SimpleDialog simpleDialog; + simpleDialog.addValue("Initial Reset", boolToStr(randomWithReset), "(1 = true, 0 = false) If set to '0' no height reset is done before calculating"); + simpleDialog.addValue("Min Height", intToStr(randomMinimumHeight), "Lowest random height. example: -300 or below if you want water , 0 if you don't want water."); + simpleDialog.addValue("Max Height", intToStr(randomMaximumHeight), "Max random height. A good value is 400"); + simpleDialog.addValue("Chance Divider", intToStr(randomChanceDivider), "Defines how often you get a hill or hole default is 30. Bigger number, less hills/holes."); + simpleDialog.addValue("Smooth Recursions", intToStr(randomRecursions), "Number of recursions cycles to smooth the hills and holes. 0 1) { + randomWithReset = true; + } else { + randomWithReset = strToBool(simpleDialog.getValue("Initial Reset")); + } + randomMinimumHeight = strToInt(simpleDialog.getValue("Min Height")); + randomMaximumHeight = strToInt(simpleDialog.getValue("Max Height")); + randomChanceDivider = strToInt(simpleDialog.getValue("Chance Divider")); + randomRecursions = strToInt(simpleDialog.getValue("Smooth Recursions")); + + // set insane inputs to something that does not crash + if (randomMinimumHeight >= randomMaximumHeight) randomMinimumHeight = randomMaximumHeight - 1; + if (randomChanceDivider < 1) randomChanceDivider = 1; + + // set randomRecursions to something useful + if (randomRecursions < 0) randomRecursions = 0; + if (randomRecursions > 50) randomRecursions = 50; + + program->setUndoPoint(ctAll); + program->randomizeMapHeights(randomWithReset, randomMinimumHeight, randomMaximumHeight, + randomChanceDivider, randomRecursions); + } catch (const exception &e) { + MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); + } + setDirty(); + } + } + + void MainWindow::onMenuEditRandomize(wxCommandEvent &event) { + if (program == NULL) { + return; + } + + program->setUndoPoint(ctAll); + program->randomizeFactions(); + setDirty(); + } + + void MainWindow::onMenuEditSwitchSurfaces(wxCommandEvent &event) { + if (program == NULL) { + return; + } + + SimpleDialog simpleDialog; + simpleDialog.addValue("Surface1", "1", "replace this surface with..."); + simpleDialog.addValue("Surface2", "2", "...this and vice versa"); + if (!simpleDialog.show("Switch surfaces")) return; + + try { + program->setUndoPoint(ctSurface); + program->switchMapSurfaces( + strToInt(simpleDialog.getValue("Surface1")), + strToInt(simpleDialog.getValue("Surface2"))); + } catch (const exception &e) { + MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); + } + setDirty(); + } + + void MainWindow::onMenuEditInfo(wxCommandEvent &event) { + if (program == NULL) { + return; + } + + SimpleDialog simpleDialog; + simpleDialog.addValue("Title", program->getMap()->getTitle()); + simpleDialog.addValue("Description", program->getMap()->getDesc()); + simpleDialog.addValue("Author", program->getMap()->getAuthor()); + if (!simpleDialog.show("Info", true)) return; + + bool ischanged = program->setMapTitle(simpleDialog.getValue("Title")); + ischanged = (program->setMapDesc(simpleDialog.getValue("Description")) || ischanged); + ischanged = (program->setMapAuthor(simpleDialog.getValue("Author")) || ischanged); + if (ischanged) + if (!isDirty()) { + setDirty(true); + } + + } + + void MainWindow::onMenuEditAdvanced(wxCommandEvent &event) { + if (program == NULL) { + return; + } + + SimpleDialog simpleDialog; + simpleDialog.addValue("Height Factor", intToStr(program->getMap()->getHeightFactor()), "lower means more hill effect. Numbers above 100 are handled like this:\nx=x/100 ,so a 150 will mean 1.5 in the game."); + simpleDialog.addValue("Water Level", intToStr(program->getMap()->getWaterLevel()), "water is visible below this, and walkable until 1.5 less"); + simpleDialog.addValue("Cliff Level", intToStr(program->getMap()->getCliffLevel()), "neighboring fields with at least this heights difference are cliffs"); + simpleDialog.addValue("Camera Height", intToStr(program->getMap()->getCameraHeight()), "you can give a camera height here default is 0 ;ignored if <20"); + if (!simpleDialog.show("Advanced")) return; + + try { + program->setMapAdvanced( + strToInt(simpleDialog.getValue("Height Factor")), + strToInt(simpleDialog.getValue("Water Level")), + strToInt(simpleDialog.getValue("Cliff Level")), + strToInt(simpleDialog.getValue("Camera Height"))); + } catch (const exception &e) { + MsgDialog(this, ToUnicode(e.what()), wxT("Exception"), wxOK | wxICON_ERROR).ShowModal(); + } + setDirty(); + } + + void MainWindow::onMenuViewResetZoomAndPos(wxCommandEvent &event) { + if (program == NULL) { + return; + } + + program->resetOfset(); + wxPaintEvent e; + onPaint(e); + } + + void MainWindow::onMenuViewGrid(wxCommandEvent &event) { + if (program == NULL) { + return; + } + + menuView->Check(miViewGrid, program->setGridOnOff()); // miViewGrid event.GetId() + wxPaintEvent e; + onPaint(e); + } + + + void MainWindow::onMenuViewHeightMap(wxCommandEvent &event) { + if (program == NULL) { + return; + } + + menuView->Check(miViewHeightMap, program->setHeightMapOnOff()); // miViewGrid event.GetId() + wxPaintEvent e; + onPaint(e); + } + void MainWindow::onMenuHideWater(wxCommandEvent &event) { + if (program == NULL) { + return; + } + + menuView->Check(miHideWater, program->setHideWaterOnOff()); // miViewGrid event.GetId() + wxPaintEvent e; + onPaint(e); + } + void MainWindow::onMenuViewAbout(wxCommandEvent &event) { + MsgDialog( + this, + wxT("\n ZetaGlest Map Editor\n Copyright 2004-2010 The Glest Team\n Copyright 2010-2018 The MegaGlest Team \n"), + wxT("About")).ShowModal(); + } + + void MainWindow::onMenuViewHelp(wxCommandEvent &event) { + MsgDialog(this, + wxT("Draw with left mouse\nMove viewport with right mouse drag\nZoom with center mouse drag, or mousewheel\n\n\ You can change brush in the same category with key 1-9\n\ and change category with their first letter (keys S, R, O, G, H)\n\ Press Space to set brush to the resource or object under the mouse cursor\n\ @@ -1213,583 +1204,581 @@ Height tool (blue) builds with integer height steps 0-20, \nwhile Gradient tool Units can go over water as long as it is less than 1.5 deep\n\n\ A good idea is to put some stone, gold and tree near starting position\n\ Starting position needs an open area for the tower and the starting units\n"), - wxT("Help")).ShowModal(); +wxT("Help")).ShowModal(); /* 5 away and 10x10 empty area? */ -} - -void MainWindow::onMenuBrushHeight(wxCommandEvent &e) { - uncheckBrush(); - menuBrushHeight->Check(e.GetId(), true); - height = e.GetId() - miBrushHeight - heightCount / 2 - 1; - enabledGroup = ctHeight; - currentBrush = btHeight; - SetStatusText(wxT("Brush: Height"), siBRUSH_TYPE); - SetStatusText(wxT("Value: ") + ToUnicode(intToStr(height)), siBRUSH_VALUE); -} - -void MainWindow::onMenuBrushGradient(wxCommandEvent &e) { - uncheckBrush(); - menuBrushGradient->Check(e.GetId(), true); - height = e.GetId() - miBrushGradient - heightCount / 2 - 1; - enabledGroup = ctGradient; - currentBrush = btGradient; - SetStatusText(wxT("Brush: Gradient"), siBRUSH_TYPE); - SetStatusText(wxT("Value: ") + ToUnicode(intToStr(height)), siBRUSH_VALUE); -} - - -void MainWindow::onMenuBrushSurface(wxCommandEvent &e) { - uncheckBrush(); - menuBrushSurface->Check(e.GetId(), true); - surface = e.GetId() - miBrushSurface; - enabledGroup = ctSurface; - currentBrush = btSurface; - SetStatusText(wxT("Brush: Surface"), siBRUSH_TYPE); - SetStatusText( - wxT("Value: ") + ToUnicode(intToStr(surface)) + wxT(" ") - + ToUnicode(surface_descs[surface - 1]), siBRUSH_VALUE); -} - -void MainWindow::onMenuBrushObject(wxCommandEvent &e) { - uncheckBrush(); - menuBrushObject->Check(e.GetId(), true); - object = e.GetId() - miBrushObject - 1; - enabledGroup = ctObject; - currentBrush = btObject; - SetStatusText(wxT("Brush: Object"), siBRUSH_TYPE); - SetStatusText( - wxT("Value: ") + ToUnicode(intToStr(object)) + wxT(" ") - + ToUnicode(object_descs[object]), siBRUSH_VALUE); -} - -void MainWindow::onMenuBrushResource(wxCommandEvent &e) { - uncheckBrush(); - menuBrushResource->Check(e.GetId(), true); - resource = e.GetId() - miBrushResource - 1; - enabledGroup = ctResource; - currentBrush = btResource; - SetStatusText(wxT("Brush: Resource"), siBRUSH_TYPE); - SetStatusText( - wxT("Value: ") + ToUnicode(intToStr(resource)) + wxT(" ") - + ToUnicode(resource_descs[resource]), siBRUSH_VALUE); -} - -void MainWindow::onMenuBrushStartLocation(wxCommandEvent &e) { - uncheckBrush(); - menuBrushStartLocation->Check(e.GetId(), true); - startLocation = e.GetId() - miBrushStartLocation; - enabledGroup = ctLocation; - currentBrush = btStartLocation; - SetStatusText(wxT("Brush: Start Locations"), siBRUSH_TYPE); - SetStatusText(wxT("Value: ") + ToUnicode(intToStr(startLocation)), siBRUSH_VALUE); -} - -void MainWindow::onMenuRadius(wxCommandEvent &e) { - uncheckRadius(); - menuRadius->Check(e.GetId(), true); - radius = e.GetId() - miRadius; - SetStatusText(wxT("Radius: ") + ToUnicode(intToStr(radius)), siBRUSH_RADIUS); -} - -void MainWindow::change(int x, int y) { - if(program == NULL) { - return; } - switch (enabledGroup) { - case ctHeight: - program->glestChangeMapHeight(x, y, height, radius); - break; - case ctSurface: - program->changeMapSurface(x, y, surface, radius); - break; - case ctObject: - program->changeMapObject(x, y, object, radius); - break; - case ctResource: - program->changeMapResource(x, y, resource, radius); - break; - case ctLocation: - program->changeStartLocation(x, y, startLocation - 1); - break; - case ctGradient: - program->pirateChangeMapHeight(x, y, height, radius); - break; - } -} - -void MainWindow::uncheckBrush() { - for (int i = 0; i < heightCount; ++i) { - menuBrushHeight->Check(miBrushHeight + i + 1, false); - } - for (int i = 0; i < heightCount; ++i) { - menuBrushGradient->Check(miBrushGradient + i + 1, false); - } - for (int i = 0; i < surfaceCount; ++i) { - menuBrushSurface->Check(miBrushSurface + i + 1, false); - } - for (int i = 0; i < objectCount; ++i) { - menuBrushObject->Check(miBrushObject + i + 1, false); - } - for (int i = 0; i < resourceCount; ++i) { - menuBrushResource->Check(miBrushResource + i + 1, false); - } - for (int i = 0; i < startLocationCount; ++i) { - menuBrushStartLocation->Check(miBrushStartLocation + i + 1, false); - } -} - -void MainWindow::uncheckRadius() { - for (int i = 1; i <= radiusCount; ++i) { - menuRadius->Check(miRadius + i, false); - } -} - - void MainWindow::onKeyDown(wxKeyEvent &e) { - if(program == NULL) { - return; + void MainWindow::onMenuBrushHeight(wxCommandEvent &e) { + uncheckBrush(); + menuBrushHeight->Check(e.GetId(), true); + height = e.GetId() - miBrushHeight - heightCount / 2 - 1; + enabledGroup = ctHeight; + currentBrush = btHeight; + SetStatusText(wxT("Brush: Height"), siBRUSH_TYPE); + SetStatusText(wxT("Value: ") + ToUnicode(intToStr(height)), siBRUSH_VALUE); } - if(e.GetModifiers() == wxMOD_CONTROL || e.GetModifiers() == wxMOD_ALT){ - e.Skip(); + void MainWindow::onMenuBrushGradient(wxCommandEvent &e) { + uncheckBrush(); + menuBrushGradient->Check(e.GetId(), true); + height = e.GetId() - miBrushGradient - heightCount / 2 - 1; + enabledGroup = ctGradient; + currentBrush = btGradient; + SetStatusText(wxT("Brush: Gradient"), siBRUSH_TYPE); + SetStatusText(wxT("Value: ") + ToUnicode(intToStr(height)), siBRUSH_VALUE); } - // WARNING: don't add any Ctrl or ALt key shortcuts below those are reserved for internal menu use. - if (currentBrush == btSurface) { // surface texture - if (e.GetKeyCode() >= '1' && e.GetKeyCode() <= '5') { - surface = e.GetKeyCode() - 48; // '1'-'5' == 1-5 - wxCommandEvent evt(wxEVT_NULL, miBrushSurface + surface); - onMenuBrushSurface(evt); - return; - } - } - if (currentBrush == btObject) { - bool valid = true; - if (e.GetKeyCode() >= '1' && e.GetKeyCode() <= '9') { - object = e.GetKeyCode() - 48; // '1'-'9' == 1-9 - } else if (e.GetKeyCode() == '0') { // '0' == 10 - object = 10; - } else if (e.GetKeyCode() == '-') { // '-' == 0 - object = 0; - } else { - valid = false; - } - if (valid) { - wxCommandEvent evt(wxEVT_NULL, miBrushObject + object + 1); - onMenuBrushObject(evt); - return; - } - } - if (currentBrush == btResource) { - if (e.GetKeyCode() >= '0' && e.GetKeyCode() <= '5') { - resource = e.GetKeyCode() - 48; // '0'-'5' == 0-5 - wxCommandEvent evt(wxEVT_NULL, miBrushResource + resource + 1); - onMenuBrushResource(evt); - return; - } - } - if (currentBrush == btStartLocation) { - if (e.GetKeyCode() >= '1' && e.GetKeyCode() <= '8') { - startLocation = e.GetKeyCode() - 48; // '1'-'8' == 0-7 - wxCommandEvent evt(wxEVT_NULL, miBrushStartLocation + startLocation); - onMenuBrushStartLocation(evt); - return; - } - } - if (e.GetKeyCode() == 'H') { - wxCommandEvent evt(wxEVT_NULL, miBrushHeight + height + heightCount / 2 + 1); - onMenuBrushHeight(evt); - } else if (e.GetKeyCode() == ' ') { - if (resourceUnderMouse != 0) { - wxCommandEvent evt(wxEVT_NULL, miBrushResource + resourceUnderMouse + 1); - onMenuBrushResource(evt); - } else { - wxCommandEvent evt(wxEVT_NULL, miBrushObject + objectUnderMouse + 1); - onMenuBrushObject(evt); + + void MainWindow::onMenuBrushSurface(wxCommandEvent &e) { + uncheckBrush(); + menuBrushSurface->Check(e.GetId(), true); + surface = e.GetId() - miBrushSurface; + enabledGroup = ctSurface; + currentBrush = btSurface; + SetStatusText(wxT("Brush: Surface"), siBRUSH_TYPE); + SetStatusText( + wxT("Value: ") + ToUnicode(intToStr(surface)) + wxT(" ") + + ToUnicode(surface_descs[surface - 1]), siBRUSH_VALUE); + } + + void MainWindow::onMenuBrushObject(wxCommandEvent &e) { + uncheckBrush(); + menuBrushObject->Check(e.GetId(), true); + object = e.GetId() - miBrushObject - 1; + enabledGroup = ctObject; + currentBrush = btObject; + SetStatusText(wxT("Brush: Object"), siBRUSH_TYPE); + SetStatusText( + wxT("Value: ") + ToUnicode(intToStr(object)) + wxT(" ") + + ToUnicode(object_descs[object]), siBRUSH_VALUE); + } + + void MainWindow::onMenuBrushResource(wxCommandEvent &e) { + uncheckBrush(); + menuBrushResource->Check(e.GetId(), true); + resource = e.GetId() - miBrushResource - 1; + enabledGroup = ctResource; + currentBrush = btResource; + SetStatusText(wxT("Brush: Resource"), siBRUSH_TYPE); + SetStatusText( + wxT("Value: ") + ToUnicode(intToStr(resource)) + wxT(" ") + + ToUnicode(resource_descs[resource]), siBRUSH_VALUE); + } + + void MainWindow::onMenuBrushStartLocation(wxCommandEvent &e) { + uncheckBrush(); + menuBrushStartLocation->Check(e.GetId(), true); + startLocation = e.GetId() - miBrushStartLocation; + enabledGroup = ctLocation; + currentBrush = btStartLocation; + SetStatusText(wxT("Brush: Start Locations"), siBRUSH_TYPE); + SetStatusText(wxT("Value: ") + ToUnicode(intToStr(startLocation)), siBRUSH_VALUE); + } + + void MainWindow::onMenuRadius(wxCommandEvent &e) { + uncheckRadius(); + menuRadius->Check(e.GetId(), true); + radius = e.GetId() - miRadius; + SetStatusText(wxT("Radius: ") + ToUnicode(intToStr(radius)), siBRUSH_RADIUS); + } + + void MainWindow::change(int x, int y) { + if (program == NULL) { + return; + } + + switch (enabledGroup) { + case ctHeight: + program->glestChangeMapHeight(x, y, height, radius); + break; + case ctSurface: + program->changeMapSurface(x, y, surface, radius); + break; + case ctObject: + program->changeMapObject(x, y, object, radius); + break; + case ctResource: + program->changeMapResource(x, y, resource, radius); + break; + case ctLocation: + program->changeStartLocation(x, y, startLocation - 1); + break; + case ctGradient: + program->pirateChangeMapHeight(x, y, height, radius); + break; } - } else if (e.GetKeyCode() == 'G') { - wxCommandEvent evt(wxEVT_NULL, miBrushGradient + height + heightCount / 2 + 1); - onMenuBrushGradient(evt); - } else if (e.GetKeyCode() == 'S') { - wxCommandEvent evt(wxEVT_NULL, miBrushSurface + surface); - onMenuBrushSurface(evt); - } else if (e.GetKeyCode() == 'O') { - wxCommandEvent evt(wxEVT_NULL, miBrushObject + object + 1); - onMenuBrushObject(evt); - } else if (e.GetKeyCode() == 'R') { - wxCommandEvent evt(wxEVT_NULL, miBrushResource + resource + 1); - onMenuBrushResource(evt); - } else if (e.GetKeyCode() == 'L') { - wxCommandEvent evt(wxEVT_NULL, miBrushStartLocation + startLocation + 1); - onMenuBrushStartLocation(evt); - } else if (e.GetKeyCode() == WXK_LEFT && e.GetModifiers() == wxMOD_SHIFT) { // shift-left/right/up/down to shift the map one square - program->setUndoPoint(ctAll); - program->shiftLeft(); - setDirty(); - } else if (e.GetKeyCode() == WXK_RIGHT && e.GetModifiers() == wxMOD_SHIFT) { - program->setUndoPoint(ctAll); - program->shiftRight(); - setDirty(); - } else if (e.GetKeyCode() == WXK_UP && e.GetModifiers() == wxMOD_SHIFT) { - program->setUndoPoint(ctAll); - program->shiftUp(); - setDirty(); - } else if (e.GetKeyCode() == WXK_DOWN && e.GetModifiers() == wxMOD_SHIFT) { - program->setUndoPoint(ctAll); - program->shiftDown(); - setDirty(); - } else { - e.Skip(); } -} -BEGIN_EVENT_TABLE(MainWindow, wxFrame) + void MainWindow::uncheckBrush() { + for (int i = 0; i < heightCount; ++i) { + menuBrushHeight->Check(miBrushHeight + i + 1, false); + } + for (int i = 0; i < heightCount; ++i) { + menuBrushGradient->Check(miBrushGradient + i + 1, false); + } + for (int i = 0; i < surfaceCount; ++i) { + menuBrushSurface->Check(miBrushSurface + i + 1, false); + } + for (int i = 0; i < objectCount; ++i) { + menuBrushObject->Check(miBrushObject + i + 1, false); + } + for (int i = 0; i < resourceCount; ++i) { + menuBrushResource->Check(miBrushResource + i + 1, false); + } + for (int i = 0; i < startLocationCount; ++i) { + menuBrushStartLocation->Check(miBrushStartLocation + i + 1, false); + } + } - EVT_CLOSE(MainWindow::onClose) + void MainWindow::uncheckRadius() { + for (int i = 1; i <= radiusCount; ++i) { + menuRadius->Check(miRadius + i, false); + } + } - // these are 'handled' by GlCanvas and funneled to these handlers. See BEGIN_EVENT_TABLE(GlCanvas, wxGLCanvas) below. - //EVT_LEFT_DOWN(MainWindow::onMouseDown) - //EVT_MOTION(MainWindow::onMouseMove) - //EVT_KEY_DOWN(MainWindow::onKeyDown) + void MainWindow::onKeyDown(wxKeyEvent &e) { + if (program == NULL) { + return; + } - EVT_MENU(wxID_NEW, MainWindow::onMenuEditReset) - EVT_MENU(wxID_OPEN, MainWindow::onMenuFileLoad) - EVT_MENU(wxID_SAVE, MainWindow::onMenuFileSave) - EVT_MENU(wxID_SAVEAS, MainWindow::onMenuFileSaveAs) - EVT_MENU(wxID_EXIT, MainWindow::onMenuFileExit) + if (e.GetModifiers() == wxMOD_CONTROL || e.GetModifiers() == wxMOD_ALT) { + e.Skip(); + } + // WARNING: don't add any Ctrl or ALt key shortcuts below those are reserved for internal menu use. - EVT_MENU(miEditUndo, MainWindow::onMenuEditUndo) - EVT_MENU(miEditRedo, MainWindow::onMenuEditRedo) - EVT_MENU(miEditResetPlayers, MainWindow::onMenuEditResetPlayers) - EVT_MENU(miEditResize, MainWindow::onMenuEditResize) - EVT_MENU(miEditFlipDiagonal, MainWindow::onMenuEditFlipDiagonal) - EVT_MENU(miEditFlipX, MainWindow::onMenuEditFlipX) - EVT_MENU(miEditFlipY, MainWindow::onMenuEditFlipY) + if (currentBrush == btSurface) { // surface texture + if (e.GetKeyCode() >= '1' && e.GetKeyCode() <= '5') { + surface = e.GetKeyCode() - 48; // '1'-'5' == 1-5 + wxCommandEvent evt(wxEVT_NULL, miBrushSurface + surface); + onMenuBrushSurface(evt); + return; + } + } + if (currentBrush == btObject) { + bool valid = true; + if (e.GetKeyCode() >= '1' && e.GetKeyCode() <= '9') { + object = e.GetKeyCode() - 48; // '1'-'9' == 1-9 + } else if (e.GetKeyCode() == '0') { // '0' == 10 + object = 10; + } else if (e.GetKeyCode() == '-') { // '-' == 0 + object = 0; + } else { + valid = false; + } + if (valid) { + wxCommandEvent evt(wxEVT_NULL, miBrushObject + object + 1); + onMenuBrushObject(evt); + return; + } + } + if (currentBrush == btResource) { + if (e.GetKeyCode() >= '0' && e.GetKeyCode() <= '5') { + resource = e.GetKeyCode() - 48; // '0'-'5' == 0-5 + wxCommandEvent evt(wxEVT_NULL, miBrushResource + resource + 1); + onMenuBrushResource(evt); + return; + } + } + if (currentBrush == btStartLocation) { + if (e.GetKeyCode() >= '1' && e.GetKeyCode() <= '8') { + startLocation = e.GetKeyCode() - 48; // '1'-'8' == 0-7 + wxCommandEvent evt(wxEVT_NULL, miBrushStartLocation + startLocation); + onMenuBrushStartLocation(evt); + return; + } + } + if (e.GetKeyCode() == 'H') { + wxCommandEvent evt(wxEVT_NULL, miBrushHeight + height + heightCount / 2 + 1); + onMenuBrushHeight(evt); + } else if (e.GetKeyCode() == ' ') { + if (resourceUnderMouse != 0) { + wxCommandEvent evt(wxEVT_NULL, miBrushResource + resourceUnderMouse + 1); + onMenuBrushResource(evt); + } else { + wxCommandEvent evt(wxEVT_NULL, miBrushObject + objectUnderMouse + 1); + onMenuBrushObject(evt); + } + } else if (e.GetKeyCode() == 'G') { + wxCommandEvent evt(wxEVT_NULL, miBrushGradient + height + heightCount / 2 + 1); + onMenuBrushGradient(evt); + } else if (e.GetKeyCode() == 'S') { + wxCommandEvent evt(wxEVT_NULL, miBrushSurface + surface); + onMenuBrushSurface(evt); + } else if (e.GetKeyCode() == 'O') { + wxCommandEvent evt(wxEVT_NULL, miBrushObject + object + 1); + onMenuBrushObject(evt); + } else if (e.GetKeyCode() == 'R') { + wxCommandEvent evt(wxEVT_NULL, miBrushResource + resource + 1); + onMenuBrushResource(evt); + } else if (e.GetKeyCode() == 'L') { + wxCommandEvent evt(wxEVT_NULL, miBrushStartLocation + startLocation + 1); + onMenuBrushStartLocation(evt); + } else if (e.GetKeyCode() == WXK_LEFT && e.GetModifiers() == wxMOD_SHIFT) { // shift-left/right/up/down to shift the map one square + program->setUndoPoint(ctAll); + program->shiftLeft(); + setDirty(); + } else if (e.GetKeyCode() == WXK_RIGHT && e.GetModifiers() == wxMOD_SHIFT) { + program->setUndoPoint(ctAll); + program->shiftRight(); + setDirty(); + } else if (e.GetKeyCode() == WXK_UP && e.GetModifiers() == wxMOD_SHIFT) { + program->setUndoPoint(ctAll); + program->shiftUp(); + setDirty(); + } else if (e.GetKeyCode() == WXK_DOWN && e.GetModifiers() == wxMOD_SHIFT) { + program->setUndoPoint(ctAll); + program->shiftDown(); + setDirty(); + } else { + e.Skip(); + } + } - EVT_MENU(miEditMirrorX, MainWindow::onMenuEditMirrorX) - EVT_MENU(miEditMirrorY, MainWindow::onMenuEditMirrorY) - EVT_MENU(miEditMirrorXY, MainWindow::onMenuEditMirrorXY) - EVT_MENU(miEditRotatecopyX, MainWindow::onMenuEditRotatecopyX) - EVT_MENU(miEditRotatecopyY, MainWindow::onMenuEditRotatecopyY) - EVT_MENU(miEditRotatecopyXY, MainWindow::onMenuEditRotatecopyXY) - EVT_MENU(miEditRotatecopyCorner, MainWindow::onMenuEditRotatecopyCorner) + BEGIN_EVENT_TABLE(MainWindow, wxFrame) - EVT_MENU(miEditRandomizeHeights, MainWindow::onMenuEditRandomizeHeights) - EVT_MENU(miEditRandomize, MainWindow::onMenuEditRandomize) - EVT_MENU(miEditSwitchSurfaces, MainWindow::onMenuEditSwitchSurfaces) - EVT_MENU(miEditInfo, MainWindow::onMenuEditInfo) - EVT_MENU(miEditAdvanced, MainWindow::onMenuEditAdvanced) + EVT_CLOSE(MainWindow::onClose) - EVT_MENU(miViewResetZoomAndPos, MainWindow::onMenuViewResetZoomAndPos) - EVT_MENU(miViewGrid, MainWindow::onMenuViewGrid) - EVT_MENU(miViewHeightMap, MainWindow::onMenuViewHeightMap) - EVT_MENU(miHideWater, MainWindow::onMenuHideWater) - EVT_MENU(miViewAbout, MainWindow::onMenuViewAbout) - EVT_MENU(miViewHelp, MainWindow::onMenuViewHelp) + // these are 'handled' by GlCanvas and funneled to these handlers. See BEGIN_EVENT_TABLE(GlCanvas, wxGLCanvas) below. + //EVT_LEFT_DOWN(MainWindow::onMouseDown) + //EVT_MOTION(MainWindow::onMouseMove) + //EVT_KEY_DOWN(MainWindow::onKeyDown) - EVT_MENU_RANGE(miBrushHeight + 1, miBrushHeight + heightCount, MainWindow::onMenuBrushHeight) - EVT_MENU_RANGE(miBrushGradient + 1, miBrushGradient + heightCount, MainWindow::onMenuBrushGradient) - EVT_MENU_RANGE(miBrushSurface + 1, miBrushSurface + surfaceCount, MainWindow::onMenuBrushSurface) - EVT_MENU_RANGE(miBrushObject + 1, miBrushObject + objectCount, MainWindow::onMenuBrushObject) - EVT_MENU_RANGE(miBrushResource + 1, miBrushResource + resourceCount, MainWindow::onMenuBrushResource) - EVT_MENU_RANGE(miBrushStartLocation + 1, miBrushStartLocation + startLocationCount, MainWindow::onMenuBrushStartLocation) - EVT_MENU_RANGE(miRadius, miRadius + radiusCount, MainWindow::onMenuRadius) + EVT_MENU(wxID_NEW, MainWindow::onMenuEditReset) + EVT_MENU(wxID_OPEN, MainWindow::onMenuFileLoad) + EVT_MENU(wxID_SAVE, MainWindow::onMenuFileSave) + EVT_MENU(wxID_SAVEAS, MainWindow::onMenuFileSaveAs) + EVT_MENU(wxID_EXIT, MainWindow::onMenuFileExit) - EVT_PAINT(MainWindow::onPaint) + EVT_MENU(miEditUndo, MainWindow::onMenuEditUndo) + EVT_MENU(miEditRedo, MainWindow::onMenuEditRedo) + EVT_MENU(miEditResetPlayers, MainWindow::onMenuEditResetPlayers) + EVT_MENU(miEditResize, MainWindow::onMenuEditResize) + EVT_MENU(miEditFlipDiagonal, MainWindow::onMenuEditFlipDiagonal) + EVT_MENU(miEditFlipX, MainWindow::onMenuEditFlipX) + EVT_MENU(miEditFlipY, MainWindow::onMenuEditFlipY) - EVT_TOOL(toolPlayer, MainWindow::onToolPlayer) -END_EVENT_TABLE() + EVT_MENU(miEditMirrorX, MainWindow::onMenuEditMirrorX) + EVT_MENU(miEditMirrorY, MainWindow::onMenuEditMirrorY) + EVT_MENU(miEditMirrorXY, MainWindow::onMenuEditMirrorXY) + EVT_MENU(miEditRotatecopyX, MainWindow::onMenuEditRotatecopyX) + EVT_MENU(miEditRotatecopyY, MainWindow::onMenuEditRotatecopyY) + EVT_MENU(miEditRotatecopyXY, MainWindow::onMenuEditRotatecopyXY) + EVT_MENU(miEditRotatecopyCorner, MainWindow::onMenuEditRotatecopyCorner) -// ===================================================== -// class GlCanvas -// ===================================================== + EVT_MENU(miEditRandomizeHeights, MainWindow::onMenuEditRandomizeHeights) + EVT_MENU(miEditRandomize, MainWindow::onMenuEditRandomize) + EVT_MENU(miEditSwitchSurfaces, MainWindow::onMenuEditSwitchSurfaces) + EVT_MENU(miEditInfo, MainWindow::onMenuEditInfo) + EVT_MENU(miEditAdvanced, MainWindow::onMenuEditAdvanced) -GlCanvas::GlCanvas(MainWindow *mainWindow, wxWindow *parent, int *args) + EVT_MENU(miViewResetZoomAndPos, MainWindow::onMenuViewResetZoomAndPos) + EVT_MENU(miViewGrid, MainWindow::onMenuViewGrid) + EVT_MENU(miViewHeightMap, MainWindow::onMenuViewHeightMap) + EVT_MENU(miHideWater, MainWindow::onMenuHideWater) + EVT_MENU(miViewAbout, MainWindow::onMenuViewAbout) + EVT_MENU(miViewHelp, MainWindow::onMenuViewHelp) + + EVT_MENU_RANGE(miBrushHeight + 1, miBrushHeight + heightCount, MainWindow::onMenuBrushHeight) + EVT_MENU_RANGE(miBrushGradient + 1, miBrushGradient + heightCount, MainWindow::onMenuBrushGradient) + EVT_MENU_RANGE(miBrushSurface + 1, miBrushSurface + surfaceCount, MainWindow::onMenuBrushSurface) + EVT_MENU_RANGE(miBrushObject + 1, miBrushObject + objectCount, MainWindow::onMenuBrushObject) + EVT_MENU_RANGE(miBrushResource + 1, miBrushResource + resourceCount, MainWindow::onMenuBrushResource) + EVT_MENU_RANGE(miBrushStartLocation + 1, miBrushStartLocation + startLocationCount, MainWindow::onMenuBrushStartLocation) + EVT_MENU_RANGE(miRadius, miRadius + radiusCount, MainWindow::onMenuRadius) + + EVT_PAINT(MainWindow::onPaint) + + EVT_TOOL(toolPlayer, MainWindow::onToolPlayer) + END_EVENT_TABLE() + + // ===================================================== + // class GlCanvas + // ===================================================== + + GlCanvas::GlCanvas(MainWindow *mainWindow, wxWindow *parent, int *args) #if wxCHECK_VERSION(2, 9, 1) : wxGLCanvas(parent, -1, args, wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas")) { - this->context = new wxGLContext(this); + this->context = new wxGLContext(this); #else : wxGLCanvas(parent, -1, wxDefaultPosition, wxDefaultSize, 0, wxT("GLCanvas"), args) { - this->context = NULL; + this->context = NULL; #endif - this->mainWindow = mainWindow; -} + this->mainWindow = mainWindow; + } -GlCanvas::~GlCanvas() { - delete this->context; - this->context = NULL; -} + GlCanvas::~GlCanvas() { + delete this->context; + this->context = NULL; + } -void GlCanvas::setCurrentGLContext() { + void GlCanvas::setCurrentGLContext() { #ifndef __APPLE__ #if wxCHECK_VERSION(2, 9, 1) - if(this->context == NULL) { - this->context = new wxGLContext(this); - } -#endif - - if(this->context) { - this->SetCurrent(*this->context); - } -#else - this->SetCurrent(); -#endif -} - -void translateCoords(wxWindow *wnd, int &x, int &y) { -/* -#ifdef WIN32 - int cx, cy; - wnd->GetPosition(&cx, &cy); - x += cx; - y += cy; -#endif - */ -} - -// for the mousewheel -void GlCanvas::onMouseWheel(wxMouseEvent &event) { - if(event.GetWheelRotation()>0) mainWindow->onMouseWheelDown(event); - else mainWindow->onMouseWheelUp(event); -} - -void GlCanvas::onMouseDown(wxMouseEvent &event) { - int x, y; - event.GetPosition(&x, &y); - translateCoords(this, x, y); - mainWindow->onMouseDown(event, x, y); -} - -void GlCanvas::onMouseMove(wxMouseEvent &event) { - int x, y; - event.GetPosition(&x, &y); - translateCoords(this, x, y); - mainWindow->onMouseMove(event, x, y); -} - -void GlCanvas::onKeyDown(wxKeyEvent &event) { - int x, y; - event.GetPosition(&x, &y); - translateCoords(this, x, y); - mainWindow->onKeyDown(event); -} - -void GlCanvas::onPaint(wxPaintEvent &event) { -// wxPaintDC dc(this); //N "In a paint event handler must always create a wxPaintDC object even if you do not use it. (?) -// mainWindow->program->renderMap(GetClientSize().x, GetClientSize().y); -// SwapBuffers(); -// event.Skip(); - //printf("gl onPaint skip map\n"); - mainWindow->onPaint(event); -} - -BEGIN_EVENT_TABLE(GlCanvas, wxGLCanvas) - EVT_KEY_DOWN(GlCanvas::onKeyDown) - EVT_MOUSEWHEEL(GlCanvas::onMouseWheel) - EVT_LEFT_DOWN(GlCanvas::onMouseDown) - EVT_MOTION(GlCanvas::onMouseMove) - EVT_PAINT(GlCanvas::onPaint) // Because the drawing area needs to be repainted too. -END_EVENT_TABLE() - -// =============================================== -// class SimpleDialog -// =============================================== - -void SimpleDialog::addValue(const string &key, const string &value, const string &help) { - values.push_back(pair(key, value+"|"+help)); // I guess I need map<,> instead but I don't know how to do it -} - -string SimpleDialog::getValue(const string &key) { - for (unsigned int i = 0; i < values.size(); ++i) { - if (values[i].first == key) { - return values[i].second; + if (this->context == NULL) { + this->context = new wxGLContext(this); } - } - return ""; -} +#endif -bool SimpleDialog::show(const string &title, bool wide) { - Create(NULL, -1, ToUnicode(title)); - wxSizer *sizer2 = new wxBoxSizer(wxVERTICAL); - wxSizer *sizer = new wxFlexGridSizer(3); - - vector texts; - for (Values::iterator it = values.begin(); it != values.end(); ++it) { - size_t helptextpos = it->second.find_first_of('|'); - sizer->Add(new wxStaticText(this, -1, ToUnicode(it->first)), 0, wxALL, 5); - wxTextCtrl *text = new wxTextCtrl(this, -1, ToUnicode(it->second.substr(0,helptextpos))); - if(wide) text->SetMinSize( wxSize((text->GetSize().GetWidth())*4, text->GetSize().GetHeight())); // 4 time as wide as default - sizer->Add(text, 0, wxALL, 5); - texts.push_back(text); - sizer->Add(new wxStaticText(this, -1, ToUnicode(it->second.substr(helptextpos+1))), 0, wxALL, 5); - } - sizer2->Add(sizer); - sizer2->Add(CreateButtonSizer(wxOK|wxCANCEL),0,wxALIGN_RIGHT); // enable Cancel button - SetSizerAndFit(sizer2); - - ShowModal(); - if(m_returnCode==wxID_CANCEL) return false; // don't change values if canceled - - for (unsigned int i = 0; i < texts.size(); ++i) { -#ifdef WIN32 - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(texts[i]->GetValue())); - values[i].second = tmp_buf; + if (this->context) { + this->SetCurrent(*this->context); + } #else - values[i].second = texts[i]->GetValue().ToAscii(); + this->SetCurrent(); #endif } - return true; -} + void translateCoords(wxWindow *wnd, int &x, int &y) { + /* + #ifdef WIN32 + int cx, cy; + wnd->GetPosition(&cx, &cy); + x += cx; + y += cy; + #endif + */ + } -// =============================================== -// class App -// =============================================== + // for the mousewheel + void GlCanvas::onMouseWheel(wxMouseEvent &event) { + if (event.GetWheelRotation() > 0) mainWindow->onMouseWheelDown(event); + else mainWindow->onMouseWheelUp(event); + } -bool App::OnInit() { - SystemFlags::VERBOSE_MODE_ENABLED = false; - SystemFlags::ENABLE_THREADED_LOGGING = false; + void GlCanvas::onMouseDown(wxMouseEvent &event) { + int x, y; + event.GetPosition(&x, &y); + translateCoords(this, x, y); + mainWindow->onMouseDown(event, x, y); + } - string fileparam; - if(argc==2){ - if(argv[1][0]=='-') { // any flag gives help and exits program. - std::cout << std::endl << "ZetaGlest map editor " << mapeditorVersionString << " [Using " << (const char *)wxConvCurrent->cWX2MB(wxVERSION_STRING) << "]" << std::endl << std::endl; - //std::cout << "\nglest_map_editor [MGM FILE]" << std::endl << std::endl; - std::cout << "Creates or edits zetaglest/glest maps. [.mgm/.gbm]" << std::endl << std::endl; - std::cout << "Draw with left mouse button." << std::endl; - std::cout << "Move map with right mouse button." << std::endl; - std::cout << "Zoom with middle mouse button or mousewheel." << std::endl; + void GlCanvas::onMouseMove(wxMouseEvent &event) { + int x, y; + event.GetPosition(&x, &y); + translateCoords(this, x, y); + mainWindow->onMouseMove(event, x, y); + } -// std::cout << " ~ more helps should be written here ~" << std::endl; - std::cout << std::endl; - exit (0); + void GlCanvas::onKeyDown(wxKeyEvent &event) { + int x, y; + event.GetPosition(&x, &y); + translateCoords(this, x, y); + mainWindow->onKeyDown(event); + } + + void GlCanvas::onPaint(wxPaintEvent &event) { + // wxPaintDC dc(this); //N "In a paint event handler must always create a wxPaintDC object even if you do not use it. (?) + // mainWindow->program->renderMap(GetClientSize().x, GetClientSize().y); + // SwapBuffers(); + // event.Skip(); + //printf("gl onPaint skip map\n"); + mainWindow->onPaint(event); + } + + BEGIN_EVENT_TABLE(GlCanvas, wxGLCanvas) + EVT_KEY_DOWN(GlCanvas::onKeyDown) + EVT_MOUSEWHEEL(GlCanvas::onMouseWheel) + EVT_LEFT_DOWN(GlCanvas::onMouseDown) + EVT_MOTION(GlCanvas::onMouseMove) + EVT_PAINT(GlCanvas::onPaint) // Because the drawing area needs to be repainted too. + END_EVENT_TABLE() + + // =============================================== + // class SimpleDialog + // =============================================== + + void SimpleDialog::addValue(const string &key, const string &value, const string &help) { + values.push_back(pair(key, value + "|" + help)); // I guess I need map<,> instead but I don't know how to do it + } + + string SimpleDialog::getValue(const string &key) { + for (unsigned int i = 0; i < values.size(); ++i) { + if (values[i].first == key) { + return values[i].second; + } } -//#if defined(__MINGW32__) + return ""; + } + + bool SimpleDialog::show(const string &title, bool wide) { + Create(NULL, -1, ToUnicode(title)); + wxSizer *sizer2 = new wxBoxSizer(wxVERTICAL); + wxSizer *sizer = new wxFlexGridSizer(3); + + vector texts; + for (Values::iterator it = values.begin(); it != values.end(); ++it) { + size_t helptextpos = it->second.find_first_of('|'); + sizer->Add(new wxStaticText(this, -1, ToUnicode(it->first)), 0, wxALL, 5); + wxTextCtrl *text = new wxTextCtrl(this, -1, ToUnicode(it->second.substr(0, helptextpos))); + if (wide) text->SetMinSize(wxSize((text->GetSize().GetWidth()) * 4, text->GetSize().GetHeight())); // 4 time as wide as default + sizer->Add(text, 0, wxALL, 5); + texts.push_back(text); + sizer->Add(new wxStaticText(this, -1, ToUnicode(it->second.substr(helptextpos + 1))), 0, wxALL, 5); + } + sizer2->Add(sizer); + sizer2->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxALIGN_RIGHT); // enable Cancel button + SetSizerAndFit(sizer2); + + ShowModal(); + if (m_returnCode == wxID_CANCEL) return false; // don't change values if canceled + + for (unsigned int i = 0; i < texts.size(); ++i) { +#ifdef WIN32 + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(texts[i]->GetValue())); + values[i].second = tmp_buf; +#else + values[i].second = texts[i]->GetValue().ToAscii(); +#endif + } + return true; + } + + + // =============================================== + // class App + // =============================================== + + bool App::OnInit() { + SystemFlags::VERBOSE_MODE_ENABLED = false; + SystemFlags::ENABLE_THREADED_LOGGING = false; + + string fileparam; + if (argc == 2) { + if (argv[1][0] == '-') { // any flag gives help and exits program. + std::cout << std::endl << "ZetaGlest map editor " << mapeditorVersionString << " [Using " << (const char *) wxConvCurrent->cWX2MB(wxVERSION_STRING) << "]" << std::endl << std::endl; + //std::cout << "\nglest_map_editor [MGM FILE]" << std::endl << std::endl; + std::cout << "Creates or edits zetaglest/glest maps. [.mgm/.gbm]" << std::endl << std::endl; + std::cout << "Draw with left mouse button." << std::endl; + std::cout << "Move map with right mouse button." << std::endl; + std::cout << "Zoom with middle mouse button or mousewheel." << std::endl; + + // std::cout << " ~ more helps should be written here ~" << std::endl; + std::cout << std::endl; + exit(0); + } + //#if defined(__MINGW32__) #if wxCHECK_VERSION(2, 9, 1) - fileparam = argv[1].ToStdString(); + fileparam = argv[1].ToStdString(); #else - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(argv[1]); - fileparam = tmp_buf; + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(argv[1]); + fileparam = tmp_buf; #endif #ifdef WIN32 - auto_ptr wstr(Ansi2WideString(fileparam.c_str())); - fileparam = utf8_encode(wstr.get()); + auto_ptr wstr(Ansi2WideString(fileparam.c_str())); + fileparam = utf8_encode(wstr.get()); #endif -//#else -// fileparam = wxFNCONV(argv[1]); -//#endif - } + //#else + // fileparam = wxFNCONV(argv[1]); + //#endif + } #if defined(wxMAJOR_VERSION) && defined(wxMINOR_VERSION) && defined(wxRELEASE_NUMBER) && defined(wxSUBRELEASE_NUMBER) - printf("Using wxWidgets version [%d.%d.%d.%d]\n",wxMAJOR_VERSION,wxMINOR_VERSION,wxRELEASE_NUMBER,wxSUBRELEASE_NUMBER); + printf("Using wxWidgets version [%d.%d.%d.%d]\n", wxMAJOR_VERSION, wxMINOR_VERSION, wxRELEASE_NUMBER, wxSUBRELEASE_NUMBER); #endif - wxString exe_path = wxStandardPaths::Get().GetExecutablePath(); - //wxString path_separator = wxFileName::GetPathSeparator(); - //exe_path = exe_path.BeforeLast(path_separator[0]); - //exe_path += path_separator; + wxString exe_path = wxStandardPaths::Get().GetExecutablePath(); + //wxString path_separator = wxFileName::GetPathSeparator(); + //exe_path = exe_path.BeforeLast(path_separator[0]); + //exe_path += path_separator; - string appPath; -//#if defined(__MINGW32__) + string appPath; + //#if defined(__MINGW32__) #ifdef WIN32 - const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(exe_path)); - appPath = tmp_buf; + const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(exe_path)); + appPath = tmp_buf; - auto_ptr wstr(Ansi2WideString(appPath.c_str())); - appPath = utf8_encode(wstr.get()); + auto_ptr wstr(Ansi2WideString(appPath.c_str())); + appPath = utf8_encode(wstr.get()); #elif wxCHECK_VERSION(2, 9, 1) - appPath = exe_path.ToStdString(); + appPath = exe_path.ToStdString(); #else - appPath = wxFNCONV(exe_path); + appPath = wxFNCONV(exe_path); #endif -//#else -// const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(exe_path)); -// appPath = tmp_buf; -//#endif + //#else + // const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(wxFNCONV(exe_path)); + // appPath = tmp_buf; + //#endif - mainWindow = new MainWindow(appPath); - mainWindow->Show(); - mainWindow->init(fileparam); - mainWindow->Update(); + mainWindow = new MainWindow(appPath); + mainWindow->Show(); + mainWindow->init(fileparam); + mainWindow->Update(); #ifdef WIN32 - wxPoint pos = mainWindow->GetScreenPosition(); - wxSize size = mainWindow->GetSize(); + wxPoint pos = mainWindow->GetScreenPosition(); + wxSize size = mainWindow->GetSize(); - mainWindow->SetSize(pos.x, pos.y, 1, 1, wxSIZE_FORCE); - //mainWindow->Update(); + mainWindow->SetSize(pos.x, pos.y, 1, 1, wxSIZE_FORCE); + //mainWindow->Update(); - mainWindow->SetSize(pos.x, pos.y, size.x-1, size.y, wxSIZE_FORCE); - mainWindow->Update(); + mainWindow->SetSize(pos.x, pos.y, size.x - 1, size.y, wxSIZE_FORCE); + mainWindow->Update(); #endif - return true; -} - -int App::MainLoop() { - try { - //throw megaglest_runtime_error("test"); - return wxApp::MainLoop(); + return true; } - catch (const exception &e) { - MsgDialog(NULL, ToUnicode(e.what()), wxT("Exception")).ShowModal(); + + int App::MainLoop() { + try { + //throw megaglest_runtime_error("test"); + return wxApp::MainLoop(); + } catch (const exception &e) { + MsgDialog(NULL, ToUnicode(e.what()), wxT("Exception")).ShowModal(); + } + return 0; } - return 0; -} -int App::OnExit() { - SystemFlags::Close(); - SystemFlags::SHUTDOWN_PROGRAM_MODE=true; + int App::OnExit() { + SystemFlags::Close(); + SystemFlags::SHUTDOWN_PROGRAM_MODE = true; - return 0; -} - -MsgDialog::MsgDialog(wxWindow *parent, - const wxString& message, - const wxString& caption, - long style, - const wxPoint& pos) { - - m_sizerText = NULL; - if ( !wxDialog::Create(parent, wxID_ANY, caption, - pos, wxDefaultSize, - style) ) { - return; + return 0; } - m_sizerText = new wxBoxSizer(wxVERTICAL); - wxStaticText *label = new wxStaticText(this, wxID_ANY, message); - wxFont font(*wxNORMAL_FONT); - font.SetPointSize(font.GetPointSize()); - font.SetWeight(wxFONTWEIGHT_NORMAL); - label->SetFont(font); - m_sizerText->Add(label, wxSizerFlags().Centre().Border()); + MsgDialog::MsgDialog(wxWindow *parent, + const wxString& message, + const wxString& caption, + long style, + const wxPoint& pos) { - wxSizer *sizerIconAndText = new wxBoxSizer(wxHORIZONTAL); - sizerIconAndText->Add(m_sizerText, wxSizerFlags(1).Expand()); + m_sizerText = NULL; + if (!wxDialog::Create(parent, wxID_ANY, caption, + pos, wxDefaultSize, + style)) { + return; + } + m_sizerText = new wxBoxSizer(wxVERTICAL); + wxStaticText *label = new wxStaticText(this, wxID_ANY, message); + wxFont font(*wxNORMAL_FONT); + font.SetPointSize(font.GetPointSize()); + font.SetWeight(wxFONTWEIGHT_NORMAL); + label->SetFont(font); - wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL); - sizerTop->Add(sizerIconAndText, wxSizerFlags(1).Expand().Border()); + m_sizerText->Add(label, wxSizerFlags().Centre().Border()); - wxSizer *sizerBtns = CreateButtonSizer(wxOK); - if ( sizerBtns ) - { - sizerTop->Add(sizerBtns, wxSizerFlags().Expand().Border()); - } + wxSizer *sizerIconAndText = new wxBoxSizer(wxHORIZONTAL); + sizerIconAndText->Add(m_sizerText, wxSizerFlags(1).Expand()); - SetSizerAndFit(sizerTop); - CentreOnScreen(); -} -MsgDialog::~MsgDialog() { + wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL); + sizerTop->Add(sizerIconAndText, wxSizerFlags(1).Expand().Border()); -} + wxSizer *sizerBtns = CreateButtonSizer(wxOK); + if (sizerBtns) { + sizerTop->Add(sizerBtns, wxSizerFlags().Expand().Border()); + } -}// end namespace + SetSizerAndFit(sizerTop); + CentreOnScreen(); + } + MsgDialog::~MsgDialog() { + + } + + }// end namespace IMPLEMENT_APP(MapEditor::App) diff --git a/source/glest_map_editor/main.h b/source/glest_map_editor/main.h index 639900c1f..1ac63bcbd 100644 --- a/source/glest_map_editor/main.h +++ b/source/glest_map_editor/main.h @@ -13,8 +13,8 @@ #define _MAPEDITOR_MAIN_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include @@ -34,344 +34,348 @@ using namespace Shared::PlatformCommon; namespace MapEditor { -class GlCanvas; + class GlCanvas; -enum BrushType { - btHeight, - btGradient, - btSurface, - btObject, - btResource, - btStartLocation -}; - -enum StatusItems { - siNULL_ENTRY, - siFILE_NAME, - siFILE_TYPE, - siCURR_OBJECT, - siBRUSH_TYPE, - siBRUSH_VALUE, - siBRUSH_RADIUS, - siPOS_VALUE, - siCOUNT -}; - -const char *object_descs[] = { - "None (Erase)", - "Tree", - "Dead tree", - "Stone (non harvest)", - "Bush", - "Water object", - "Big tree", - "Hanged/Impaled", - "Statues", - "Mountain", - "Invisible blocking" -}; - -const char *resource_descs[] = { - "None (Erase)", "Gold", "Stone", "Custom 4", "Custom 5", "Custom 6" -}; - - -const char *surface_descs[] = { - "Grass", "Sec. grass", "Road", "Stone", "Ground" -}; - - -class MainToolBar : public wxToolBar { -private: - DECLARE_EVENT_TABLE() - -public: - - MainToolBar(wxWindow *parent, - wxWindowID id) : wxToolBar(parent,id) {} - - void onMouseMove(wxMouseEvent &event); -}; - -// ===================================================== -// class MainWindow -// ===================================================== - -class MainWindow: public wxFrame { -private: - DECLARE_EVENT_TABLE() - -private: - static const string versionString; - static const string winHeader; - static const int heightCount = 11; - static const int surfaceCount = 5; - static const int objectCount = 11; - static const int resourceCount = 6; - static const int startLocationCount = 8; - static const int radiusCount = 9; - -private: - enum MenuId { - miFileLoad, - miFileSave, - miFileSaveAs, - miFileExit, - - miEditUndo, - miEditRedo, - miEditReset, - miEditResetPlayers, - miEditResize, - miEditFlipDiagonal, - miEditFlipX, - miEditFlipY, - - miEditMirrorX, - miEditMirrorY, - miEditMirrorXY, - miEditRotatecopyX, - miEditRotatecopyY, - miEditRotatecopyXY, - miEditRotatecopyCorner, - miEditMirror, - - miEditRandomizeHeights, - miEditRandomize, - miEditSwitchSurfaces, - miEditInfo, - miEditAdvanced, - - miViewResetZoomAndPos, - miViewGrid, - miViewHeightMap, - miHideWater, - miViewAbout, - miViewHelp, - - toolPlayer, - - miBrushHeight, - miBrushGradient = miBrushHeight + heightCount + 1, - miBrushSurface = miBrushGradient + heightCount + 1, - miBrushObject = miBrushSurface + surfaceCount + 1, - miBrushResource = miBrushObject + objectCount + 1, - miBrushStartLocation = miBrushResource + resourceCount + 1, - - miRadius = miBrushStartLocation + startLocationCount + 1 + enum BrushType { + btHeight, + btGradient, + btSurface, + btObject, + btResource, + btStartLocation }; -private: - GlCanvas *glCanvas; - Program *program; - int lastX, lastY; + enum StatusItems { + siNULL_ENTRY, + siFILE_NAME, + siFILE_TYPE, + siCURR_OBJECT, + siBRUSH_TYPE, + siBRUSH_VALUE, + siBRUSH_RADIUS, + siPOS_VALUE, + siCOUNT + }; - wxPanel *panel; + const char *object_descs[] = { + "None (Erase)", + "Tree", + "Dead tree", + "Stone (non harvest)", + "Bush", + "Water object", + "Big tree", + "Hanged/Impaled", + "Statues", + "Mountain", + "Invisible blocking" + }; - wxMenuBar *menuBar; - wxMenu *menuFile; - wxMenu *menuEdit; - wxMenu *menuEditMirror; - wxMenu *menuView; - wxMenu *menuBrush; - wxMenu *menuBrushHeight; - wxMenu *menuBrushGradient; + const char *resource_descs[] = { + "None (Erase)", "Gold", "Stone", "Custom 4", "Custom 5", "Custom 6" + }; - wxMenu *menuBrushSurface; - wxMenu *menuBrushObject; - wxMenu *menuBrushResource; - wxMenu *menuBrushStartLocation; - wxMenu *menuRadius; - wxFileDialog *fileDialog; + const char *surface_descs[] = { + "Grass", "Sec. grass", "Road", "Stone", "Ground" + }; - string currentFile; - BrushType currentBrush; - int height; - int surface; - int radius; - int object; - int resource; - int startLocation; - int resourceUnderMouse; - int objectUnderMouse; + class MainToolBar : public wxToolBar { + private: + DECLARE_EVENT_TABLE() - bool randomWithReset; - int randomMinimumHeight; - int randomMaximumHeight; - int randomChanceDivider; - int randomRecursions; + public: - ChangeType enabledGroup; + MainToolBar(wxWindow *parent, + wxWindowID id) : wxToolBar(parent, id) { + } - string fileName; - bool fileModified; - Chrono lastPaintEvent; + void onMouseMove(wxMouseEvent &event); + }; - wxBoxSizer *boxsizer; + // ===================================================== + // class MainWindow + // ===================================================== - bool startupSettingsInited; - string appPath; + class MainWindow : public wxFrame { + private: + DECLARE_EVENT_TABLE() -public: - explicit MainWindow(string appPath); - ~MainWindow(); + private: + static const string versionString; + static const string winHeader; + static const int heightCount = 11; + static const int surfaceCount = 5; + static const int objectCount = 11; + static const int resourceCount = 6; + static const int startLocationCount = 8; + static const int radiusCount = 9; - void refreshMapRender(); - void init(string fname); + private: + enum MenuId { + miFileLoad, + miFileSave, + miFileSaveAs, + miFileExit, - void onClose(wxCloseEvent &event); + miEditUndo, + miEditRedo, + miEditReset, + miEditResetPlayers, + miEditResize, + miEditFlipDiagonal, + miEditFlipX, + miEditFlipY, - void onMouseDown(wxMouseEvent &event, int x, int y); - void onMouseMove(wxMouseEvent &event, int x, int y); - void onMouseWheelDown(wxMouseEvent &event); - void onMouseWheelUp(wxMouseEvent &event); + miEditMirrorX, + miEditMirrorY, + miEditMirrorXY, + miEditRotatecopyX, + miEditRotatecopyY, + miEditRotatecopyXY, + miEditRotatecopyCorner, + miEditMirror, - void onPaint(wxPaintEvent &event); - void onKeyDown(wxKeyEvent &e); + miEditRandomizeHeights, + miEditRandomize, + miEditSwitchSurfaces, + miEditInfo, + miEditAdvanced, - void onMenuFileLoad(wxCommandEvent &event); - void onMenuFileSave(wxCommandEvent &event); - void onMenuFileSaveAs(wxCommandEvent &event); - void onMenuFileExit(wxCommandEvent &event); + miViewResetZoomAndPos, + miViewGrid, + miViewHeightMap, + miHideWater, + miViewAbout, + miViewHelp, - void onMenuEditUndo(wxCommandEvent &event); - void onMenuEditRedo(wxCommandEvent &event); - void onMenuEditReset(wxCommandEvent &event); - void onMenuEditResetPlayers(wxCommandEvent &event); - void onMenuEditResize(wxCommandEvent &event); - void onMenuEditFlipDiagonal(wxCommandEvent &event); - void onMenuEditFlipX(wxCommandEvent &event); - void onMenuEditFlipY(wxCommandEvent &event); + toolPlayer, - void onMenuEditMirrorX(wxCommandEvent &event); // copy left to right - void onMenuEditMirrorY(wxCommandEvent &event); // copy top to bottom - void onMenuEditMirrorXY(wxCommandEvent &event); // copy bottomleft to topright - void onMenuEditRotatecopyX(wxCommandEvent &event); // copy left to right, rotated - void onMenuEditRotatecopyY(wxCommandEvent &event); // copy top to bottom, rotated - void onMenuEditRotatecopyXY(wxCommandEvent &event); // copy bottomleft to topright, rotated - void onMenuEditRotatecopyCorner(wxCommandEvent &event); // copy top left 1/4 to top right 1/4, rotated + miBrushHeight, + miBrushGradient = miBrushHeight + heightCount + 1, + miBrushSurface = miBrushGradient + heightCount + 1, + miBrushObject = miBrushSurface + surfaceCount + 1, + miBrushResource = miBrushObject + objectCount + 1, + miBrushStartLocation = miBrushResource + resourceCount + 1, - void onMenuEditRandomizeHeights(wxCommandEvent &event); - void onMenuEditRandomize(wxCommandEvent &event); - void onMenuEditSwitchSurfaces(wxCommandEvent &event); - void onMenuEditInfo(wxCommandEvent &event); - void onMenuEditAdvanced(wxCommandEvent &event); + miRadius = miBrushStartLocation + startLocationCount + 1 + }; - void onMenuViewResetZoomAndPos(wxCommandEvent &event); - void onMenuViewGrid(wxCommandEvent &event); - void onMenuViewHeightMap(wxCommandEvent &event); - void onMenuHideWater(wxCommandEvent &event); - void onMenuViewAbout(wxCommandEvent &event); - void onMenuViewHelp(wxCommandEvent &event); + private: + GlCanvas *glCanvas; + Program *program; + int lastX, lastY; - void onMenuBrushHeight(wxCommandEvent &event); - void onMenuBrushGradient(wxCommandEvent &event); - void onMenuBrushSurface(wxCommandEvent &event); - void onMenuBrushObject(wxCommandEvent &event); - void onMenuBrushResource(wxCommandEvent &event); - void onMenuBrushStartLocation(wxCommandEvent &event); - void onMenuRadius(wxCommandEvent &event); + wxPanel *panel; - void onToolPlayer(wxCommandEvent &event); + wxMenuBar *menuBar; + wxMenu *menuFile; + wxMenu *menuEdit; + wxMenu *menuEditMirror; + wxMenu *menuView; + wxMenu *menuBrush; + wxMenu *menuBrushHeight; + wxMenu *menuBrushGradient; - void change(int x, int y); + wxMenu *menuBrushSurface; + wxMenu *menuBrushObject; + wxMenu *menuBrushResource; + wxMenu *menuBrushStartLocation; + wxMenu *menuRadius; - void uncheckBrush(); - void uncheckRadius(); + wxFileDialog *fileDialog; -private: + string currentFile; - bool isDirty() const { return fileModified; } - void setDirty(bool val=true); - void setExtension(); - void setupStartupSettings(); - void initGlCanvas(); -}; + BrushType currentBrush; + int height; + int surface; + int radius; + int object; + int resource; + int startLocation; + int resourceUnderMouse; + int objectUnderMouse; -// ===================================================== -// class GlCanvas -// ===================================================== + bool randomWithReset; + int randomMinimumHeight; + int randomMaximumHeight; + int randomChanceDivider; + int randomRecursions; -class GlCanvas: public wxGLCanvas { -private: - DECLARE_EVENT_TABLE() + ChangeType enabledGroup; -public: - GlCanvas(MainWindow *mainWindow, wxWindow *parent, int *args); - ~GlCanvas(); + string fileName; + bool fileModified; + Chrono lastPaintEvent; - void onMouseDown(wxMouseEvent &event); - void onMouseMove(wxMouseEvent &event); - void onMouseWheel(wxMouseEvent &event); - void onKeyDown(wxKeyEvent &event); - void onPaint(wxPaintEvent &event); + wxBoxSizer *boxsizer; - void setCurrentGLContext(); -private: - MainWindow *mainWindow; - wxGLContext *context; -}; + bool startupSettingsInited; + string appPath; -// ===================================================== -// class SimpleDialog -// ===================================================== + public: + explicit MainWindow(string appPath); + ~MainWindow(); -class SimpleDialog: public wxDialog { -private: - typedef vector > Values; + void refreshMapRender(); + void init(string fname); -private: - Values values; + void onClose(wxCloseEvent &event); -public: - void addValue(const string &key, const string &value, const string &help=""); - string getValue(const string &key); + void onMouseDown(wxMouseEvent &event, int x, int y); + void onMouseMove(wxMouseEvent &event, int x, int y); + void onMouseWheelDown(wxMouseEvent &event); + void onMouseWheelUp(wxMouseEvent &event); - bool show(const string &title="Edit values", bool wide=false); -}; + void onPaint(wxPaintEvent &event); + void onKeyDown(wxKeyEvent &e); -// ===================================================== -// class SimpleDialog -// ===================================================== + void onMenuFileLoad(wxCommandEvent &event); + void onMenuFileSave(wxCommandEvent &event); + void onMenuFileSaveAs(wxCommandEvent &event); + void onMenuFileExit(wxCommandEvent &event); -class MsgDialog: public wxDialog { + void onMenuEditUndo(wxCommandEvent &event); + void onMenuEditRedo(wxCommandEvent &event); + void onMenuEditReset(wxCommandEvent &event); + void onMenuEditResetPlayers(wxCommandEvent &event); + void onMenuEditResize(wxCommandEvent &event); + void onMenuEditFlipDiagonal(wxCommandEvent &event); + void onMenuEditFlipX(wxCommandEvent &event); + void onMenuEditFlipY(wxCommandEvent &event); -private: + void onMenuEditMirrorX(wxCommandEvent &event); // copy left to right + void onMenuEditMirrorY(wxCommandEvent &event); // copy top to bottom + void onMenuEditMirrorXY(wxCommandEvent &event); // copy bottomleft to topright + void onMenuEditRotatecopyX(wxCommandEvent &event); // copy left to right, rotated + void onMenuEditRotatecopyY(wxCommandEvent &event); // copy top to bottom, rotated + void onMenuEditRotatecopyXY(wxCommandEvent &event); // copy bottomleft to topright, rotated + void onMenuEditRotatecopyCorner(wxCommandEvent &event); // copy top left 1/4 to top right 1/4, rotated - wxSizer *m_sizerText; + void onMenuEditRandomizeHeights(wxCommandEvent &event); + void onMenuEditRandomize(wxCommandEvent &event); + void onMenuEditSwitchSurfaces(wxCommandEvent &event); + void onMenuEditInfo(wxCommandEvent &event); + void onMenuEditAdvanced(wxCommandEvent &event); -public: - MsgDialog(wxWindow *parent, - const wxString& message, - const wxString& caption, - long style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxOK | wxCENTRE, - const wxPoint& pos = wxDefaultPosition); - virtual ~MsgDialog(); -}; + void onMenuViewResetZoomAndPos(wxCommandEvent &event); + void onMenuViewGrid(wxCommandEvent &event); + void onMenuViewHeightMap(wxCommandEvent &event); + void onMenuHideWater(wxCommandEvent &event); + void onMenuViewAbout(wxCommandEvent &event); + void onMenuViewHelp(wxCommandEvent &event); -// ===================================================== -// class App -// ===================================================== + void onMenuBrushHeight(wxCommandEvent &event); + void onMenuBrushGradient(wxCommandEvent &event); + void onMenuBrushSurface(wxCommandEvent &event); + void onMenuBrushObject(wxCommandEvent &event); + void onMenuBrushResource(wxCommandEvent &event); + void onMenuBrushStartLocation(wxCommandEvent &event); + void onMenuRadius(wxCommandEvent &event); -// ===================================================== -// class App -// ===================================================== + void onToolPlayer(wxCommandEvent &event); -class App: public wxApp { -private: - MainWindow *mainWindow; + void change(int x, int y); -public: - App() : wxApp() { - mainWindow = NULL; - } - virtual ~App() {} - virtual bool OnInit(); - virtual int MainLoop(); - virtual int OnExit(); -}; + void uncheckBrush(); + void uncheckRadius(); + + private: + + bool isDirty() const { + return fileModified; + } + void setDirty(bool val = true); + void setExtension(); + void setupStartupSettings(); + void initGlCanvas(); + }; + + // ===================================================== + // class GlCanvas + // ===================================================== + + class GlCanvas : public wxGLCanvas { + private: + DECLARE_EVENT_TABLE() + + public: + GlCanvas(MainWindow *mainWindow, wxWindow *parent, int *args); + ~GlCanvas(); + + void onMouseDown(wxMouseEvent &event); + void onMouseMove(wxMouseEvent &event); + void onMouseWheel(wxMouseEvent &event); + void onKeyDown(wxKeyEvent &event); + void onPaint(wxPaintEvent &event); + + void setCurrentGLContext(); + private: + MainWindow *mainWindow; + wxGLContext *context; + }; + + // ===================================================== + // class SimpleDialog + // ===================================================== + + class SimpleDialog : public wxDialog { + private: + typedef vector > Values; + + private: + Values values; + + public: + void addValue(const string &key, const string &value, const string &help = ""); + string getValue(const string &key); + + bool show(const string &title = "Edit values", bool wide = false); + }; + + // ===================================================== + // class SimpleDialog + // ===================================================== + + class MsgDialog : public wxDialog { + + private: + + wxSizer *m_sizerText; + + public: + MsgDialog(wxWindow *parent, + const wxString& message, + const wxString& caption, + long style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxOK | wxCENTRE, + const wxPoint& pos = wxDefaultPosition); + virtual ~MsgDialog(); + }; + + // ===================================================== + // class App + // ===================================================== + + // ===================================================== + // class App + // ===================================================== + + class App : public wxApp { + private: + MainWindow *mainWindow; + + public: + App() : wxApp() { + mainWindow = NULL; + } + virtual ~App() { + } + virtual bool OnInit(); + virtual int MainLoop(); + virtual int OnExit(); + }; }// end namespace diff --git a/source/glest_map_editor/program.cpp b/source/glest_map_editor/program.cpp index 68cc63dc4..12d7a6784 100644 --- a/source/glest_map_editor/program.cpp +++ b/source/glest_map_editor/program.cpp @@ -19,660 +19,655 @@ using namespace Shared::Util; namespace MapEditor { -//////////////////////////// -// class UndoPoint -//////////////////////////// -int UndoPoint::w = 0; -int UndoPoint::h = 0; + //////////////////////////// + // class UndoPoint + //////////////////////////// + int UndoPoint::w = 0; + int UndoPoint::h = 0; -UndoPoint::UndoPoint() + UndoPoint::UndoPoint() : change(ctNone) , surface(0) , object(0) , resource(0) , height(0) { - w = Program::map->getW(); - h = Program::map->getH(); -} -/* -UndoPoint::UndoPoint(ChangeType change) { - w = Program::map->getW(); - h = Program::map->getH(); - - init(change); -}*/ - -void UndoPoint::init(ChangeType change) { - this->change = change; - switch (change) { - // Back up everything - case ctAll: - // Back up heights - case ctHeight: - case ctGradient: - // Build an array of heights from the map - //std::cout << "Building an array of heights to use for our UndoPoint" << std::endl; - height = new float[w * h]; - for (int i = 0; i < w; ++i) { - for (int j = 0; j < h; ++j) { - height[j * w + i] = Program::map->getHeight(i, j); - } - } - //std::cout << "Built the array" << std::endl; - if (change != ctAll) break; - // Back up surfaces - case ctSurface: - surface = new int[w * h]; - for (int i = 0; i < w; ++i) { - for (int j = 0; j < h; ++j) { - surface[j * w + i] = Program::map->getSurface(i, j); - } - } - if (change != ctAll) break; - // Back up both objects and resources if either changes - case ctObject: - case ctResource: - object = new int[w * h]; - for (int i = 0; i < w; ++i) { - for (int j = 0; j < h; ++j) { - object[j * w + i] = Program::map->getObject(i, j); - } - } - resource = new int[w * h]; - for (int i = 0; i < w; ++i) { - for (int j = 0; j < h; ++j) { - resource[j * w + i] = Program::map->getResource(i, j); - } - } - break; + w = Program::map->getW(); + h = Program::map->getH(); } -} + /* + UndoPoint::UndoPoint(ChangeType change) { + w = Program::map->getW(); + h = Program::map->getH(); -UndoPoint::~UndoPoint() { - delete [] height; - delete [] resource; - delete [] object; - delete [] surface; -} + init(change); + }*/ -void UndoPoint::revert() { - //std::cout << "attempting to revert last changes to " << undoID << std::endl; - switch (change) { - // Revert Everything - case ctAll: - // Revert Heights - case ctHeight: - case ctGradient: - // Restore the array of heights to the map - //std::cout << "attempting to restore the height array" << std::endl; - for (int i = 0; i < w; i++) { + void UndoPoint::init(ChangeType change) { + this->change = change; + switch (change) { + // Back up everything + case ctAll: + // Back up heights + case ctHeight: + case ctGradient: + // Build an array of heights from the map + //std::cout << "Building an array of heights to use for our UndoPoint" << std::endl; + height = new float[w * h]; + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + height[j * w + i] = Program::map->getHeight(i, j); + } + } + //std::cout << "Built the array" << std::endl; + if (change != ctAll) break; + // Back up surfaces + case ctSurface: + surface = new int[w * h]; + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + surface[j * w + i] = Program::map->getSurface(i, j); + } + } + if (change != ctAll) break; + // Back up both objects and resources if either changes + case ctObject: + case ctResource: + object = new int[w * h]; + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + object[j * w + i] = Program::map->getObject(i, j); + } + } + resource = new int[w * h]; + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + resource[j * w + i] = Program::map->getResource(i, j); + } + } + break; + } + } + + UndoPoint::~UndoPoint() { + delete[] height; + delete[] resource; + delete[] object; + delete[] surface; + } + + void UndoPoint::revert() { + //std::cout << "attempting to revert last changes to " << undoID << std::endl; + switch (change) { + // Revert Everything + case ctAll: + // Revert Heights + case ctHeight: + case ctGradient: + // Restore the array of heights to the map + //std::cout << "attempting to restore the height array" << std::endl; + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + Program::map->setHeight(i, j, height[j * w + i]); + } + } + if (change != ctAll) break; + // Revert surfaces + case ctSurface: + //std::cout << "attempting to restore the surface array" << std::endl; + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + Program::map->setSurface(i, j, static_cast(surface[j * w + i])); + } + } + if (change != ctAll) break; + // Revert objects and resources + case ctObject: + case ctResource: + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + Program::map->setObject(i, j, object[j * w + i]); + } + } + for (int i = 0; i < w; i++) { + for (int j = 0; j < h; j++) { + Program::map->setResource(i, j, resource[j * w + i]); + } + } + break; + } + //std::cout << "reverted changes (we hope)" << std::endl; + } + + // =============================================== + // class Program + // =============================================== + + MapPreview *Program::map = NULL; + + Program::Program(int w, int h, string playerName) { + cellSize = 5; + grid = false; + heightmap = false; + hideWater = false; + ofsetX = 0; + ofsetY = 0; + + map = new MapPreview(); + resetFactions(8); + renderer.initMapSurface(w, h); + map->setAuthor(playerName); + } + + void Program::init() { + undoStack = ChangeStack(); + redoStack = ChangeStack(); + cellSize = 5; + grid = false; + heightmap = false; + hideWater = false; + ofsetX = 0; + ofsetY = 0; + map = NULL; + } + + Program::~Program() { + delete map; + map = NULL; + } + + int Program::getObject(int x, int y) { + int i = (x - ofsetX) / cellSize; + int j = (y + ofsetY) / cellSize; + if (map && map->inside(i, j)) { + return map->getObject(i, j); + } else { + return 0; + } + } + + int Program::getCellX(int x) { + return (x - ofsetX) / cellSize; + } + + int Program::getCellY(int y) { + return (y + ofsetY) / cellSize; + } + + int Program::getResource(int x, int y) { + int i = (x - ofsetX) / cellSize; + int j = (y + ofsetY) / cellSize; + if (map && map->inside(i, j)) { + return map->getResource(i, j); + } else { + return 0; + } + } + + void Program::glestChangeMapHeight(int x, int y, int Height, int radius) { + if (map) map->glestChangeHeight((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, Height, radius); + } + + void Program::pirateChangeMapHeight(int x, int y, int Height, int radius) { + if (map) map->pirateChangeHeight((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, Height, radius); + } + + void Program::changeMapSurface(int x, int y, int surface, int radius) { + if (map) map->changeSurface((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, static_cast(surface), radius); + } + + void Program::changeMapObject(int x, int y, int object, int radius) { + if (map) map->changeObject((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, object, radius); + } + + void Program::changeMapResource(int x, int y, int resource, int radius) { + if (map) map->changeResource((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, resource, radius); + } + + void Program::changeStartLocation(int x, int y, int player) { + if (map) map->changeStartLocation((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, player); + } + + void Program::setUndoPoint(ChangeType change) { + if (change == ctLocation) return; + + undoStack.push(UndoPoint()); + undoStack.top().init(change); + + redoStack.clear(); + } + + bool Program::undo() { + if (undoStack.empty()) { + return false; + } + // push current state onto redo stack + redoStack.push(UndoPoint()); + redoStack.top().init(undoStack.top().getChange()); + + undoStack.top().revert(); + undoStack.pop(); + return true; + } + + bool Program::redo() { + if (redoStack.empty()) { + return false; + } + // push current state onto undo stack + undoStack.push(UndoPoint()); + undoStack.top().init(redoStack.top().getChange()); + + redoStack.top().revert(); + redoStack.pop(); + return true; + } + + void Program::renderMap(int w, int h) { + //printf("Rendering map\n"); + if (map) renderer.renderMap(map, ofsetX, ofsetY, w, h, cellSize, grid, heightmap, hideWater); + } + + void Program::setRefAlt(int x, int y) { + if (map) map->setRefAlt((x - ofsetX) / cellSize, (y + ofsetY) / cellSize); + } + + void Program::flipX() { + if (map) map->flipX(); + } + + void Program::flipY() { + if (map) map->flipY(); + } + + void Program::mirrorX() { // copy left to right + if (map) { + int w = map->getW(); + int h = map->getH(); + for (int i = 0; i < w / 2; i++) { for (int j = 0; j < h; j++) { - Program::map->setHeight(i, j, height[j * w + i]); + map->copyXY(w - i - 1, j, i, j); } } - if (change != ctAll) break; - // Revert surfaces - case ctSurface: - //std::cout << "attempting to restore the surface array" << std::endl; + + // move players + for (int i = 0; i < map->getMaxFactions(); ++i) // first remove players from target corner + if (map->getStartLocationX(i) >= w / 2) map->changeStartLocation(0, 0, i); + for (int i = 0; i < map->getMaxFactions(); ++i) { + if ((map->getStartLocationX(i) < w / 2) && (map->getStartLocationX(i) != 0 || map->getStartLocationY(i) != 0)) // any startpositions to copy? + for (int ii = 0; ii < map->getMaxFactions(); ++ii) + if (map->getStartLocationX(ii) == 0 && map->getStartLocationY(ii) == 0) { // first free one + map->changeStartLocation(w - map->getStartLocationX(i) - 1, map->getStartLocationY(i), ii); + break; + } + } + } + } + + void Program::mirrorY() { // copy top to bottom + if (map) { + int w = map->getW(); + int h = map->getH(); for (int i = 0; i < w; i++) { - for (int j = 0; j < h; j++) { - Program::map->setSurface(i, j, static_cast(surface[j * w + i])); + for (int j = 0; j < h / 2; j++) { + map->copyXY(i, h - j - 1, i, j); } } - if (change != ctAll) break; - // Revert objects and resources - case ctObject: - case ctResource: + + // move players + for (int i = 0; i < map->getMaxFactions(); ++i) // first remove players from target corner + if (map->getStartLocationY(i) >= h / 2) map->changeStartLocation(0, 0, i); + for (int i = 0; i < map->getMaxFactions(); ++i) { + if ((map->getStartLocationY(i) < h / 2) && (map->getStartLocationX(i) != 0 || map->getStartLocationY(i) != 0)) // any startpositions to copy? + for (int ii = 0; ii < map->getMaxFactions(); ++ii) + if (map->getStartLocationX(ii) == 0 && map->getStartLocationY(ii) == 0) { // first free one + map->changeStartLocation(map->getStartLocationX(i), h - map->getStartLocationY(i) - 1, ii); + break; + } + } + } + } + + void Program::mirrorXY() { // copy leftbottom to topright, can handle non-sqaure maps + if (map) { + int w = map->getW(); + int h = map->getH(); + if (h == w) { + for (int i = 0; i < w - 1; i++) { + for (int j = i + 1; j < h; j++) { + map->copyXY(j, i, i, j); + } + } + } + // Non-sqaure maps: + else if (h < w) { // copy horizontal strips + int s = w / h; // 2 if twice as wide as heigh + for (int i = 0; i < w / s - 1; i++) { + for (int j = i + 1; j < h; j++) { + for (int p = 0; p < s; p++) map->copyXY(j*s + p, i, i*s + p, j); + } + } + } else { // copy vertical strips + int s = h / w; // 2 if twice as heigh as wide + for (int i = 0; i < w - 1; i++) { + for (int j = i + 1; j < h / s; j++) { + for (int p = 0; p < s; p++) map->copyXY(j, i*s + p, i, j*s + p); + } + } + } + + // move players + for (int i = 0; i < map->getMaxFactions(); ++i) // first remove players from target corner + if (map->getStartLocationX(i) > map->getStartLocationY(i)) map->changeStartLocation(0, 0, i); + for (int i = 0; i < map->getMaxFactions(); ++i) { + if (map->getStartLocationX(i) < map->getStartLocationY(i)) // any startpositions to copy? + for (int ii = 0; ii < map->getMaxFactions(); ++ii) + if (map->getStartLocationX(ii) == 0 && map->getStartLocationY(ii) == 0) { // first free one + map->changeStartLocation(map->getStartLocationY(i)*w / h, map->getStartLocationX(i)*h / w, ii); + break; + } + } + } + } + + void Program::rotatecopyX() { + if (map) { + int w = map->getW(); + int h = map->getH(); + for (int i = 0; i < w / 2; i++) { + for (int j = 0; j < h; j++) { + map->copyXY(w - i - 1, h - j - 1, i, j); + } + } + + // move players + for (int i = 0; i < map->getMaxFactions(); ++i) // first remove players from target corner + if (map->getStartLocationX(i) >= w / 2) map->changeStartLocation(0, 0, i); + for (int i = 0; i < map->getMaxFactions(); ++i) { + if ((map->getStartLocationX(i) < w / 2) && (map->getStartLocationX(i) != 0 || map->getStartLocationY(i) != 0)) // any startpositions to copy? + for (int ii = 0; ii < map->getMaxFactions(); ++ii) + if (map->getStartLocationX(ii) == 0 && map->getStartLocationY(ii) == 0) { // first free one + map->changeStartLocation(w - map->getStartLocationX(i) - 1, h - map->getStartLocationY(i) - 1, ii); + break; + } + } + } + } + + void Program::rotatecopyY() { + if (map) { + int w = map->getW(); + int h = map->getH(); for (int i = 0; i < w; i++) { - for (int j = 0; j < h; j++) { - Program::map->setObject(i, j, object[j * w + i]); + for (int j = 0; j < h / 2; j++) { + map->copyXY(w - i - 1, h - j - 1, i, j); } } - for (int i = 0; i < w; i++) { - for (int j = 0; j < h; j++) { - Program::map->setResource(i, j, resource[j * w + i]); + + // move players + for (int i = 0; i < map->getMaxFactions(); ++i) // first remove players from target corner + if (map->getStartLocationY(i) >= h / 2) map->changeStartLocation(0, 0, i); + for (int i = 0; i < map->getMaxFactions(); ++i) { + if ((map->getStartLocationY(i) < h / 2) && (map->getStartLocationX(i) != 0 || map->getStartLocationY(i) != 0)) // any startpositions to copy? + for (int ii = 0; ii < map->getMaxFactions(); ++ii) + if (map->getStartLocationX(ii) == 0 && map->getStartLocationY(ii) == 0) { // first free one + map->changeStartLocation(w - map->getStartLocationX(i) - 1, h - map->getStartLocationY(i) - 1, ii); + break; + } + } + } + } + + void Program::rotatecopyXY() { + if (map) { + int w = map->getW(); + int h = map->getH(); + int sw = w / h; if (sw < 1) sw = 1; // x-squares per y + int sh = h / w; if (sh < 1) sh = 1; // y-squares per x + if (sh == 1) + for (int j = 0; j < h - 1; j++) { // row by row! + for (int i = j*sw; i < w; i++) { + map->copyXY(i, j, w - i - 1, h - j - 1); + } + } else + for (int i = 0; i < w; i++) { // column for colum! + for (int j = h - 1 - i*sh; j >= 0; j--) { + map->copyXY(w - i - 1, j, i, h - j - 1); + } + } + + // move players + for (int i = 0; i < map->getMaxFactions(); ++i) // first remove players from target corner + if (map->getStartLocationX(i) > map->getStartLocationY(i)) map->changeStartLocation(0, 0, i); + for (int i = 0; i < map->getMaxFactions(); ++i) { + if (map->getStartLocationX(i) < map->getStartLocationY(i)) // any startpositions to copy? + for (int ii = 0; ii < map->getMaxFactions(); ++ii) + if (map->getStartLocationX(ii) == 0 && map->getStartLocationY(ii) == 0) { // first free one + map->changeStartLocation(w - map->getStartLocationX(i) - 1, h - map->getStartLocationY(i) - 1, ii); + break; + } + } + } + } + + void Program::rotatecopyCorner() { // rotate top left 1/4 to top right 1/4 + if (map) { + int w = map->getW(); + int h = map->getH(); + if (h == w) { + for (int i = 0; i < w / 2; i++) { + for (int j = 0; j < h / 2; j++) { + map->copyXY(w - j - 1, i, i, j); + } } } - break; + // Non-sqaure maps: + else if (h < w) { // copy horizontal strips + int s = w / h; // 2 if twice as wide as heigh + for (int i = 0; i < w / s / 2; i++) { + for (int j = 0; j < h / 2; j++) { + for (int p = 0; p < s; p++) map->copyXY(w - j*s - 1 - p, i, i*s + p, j); + } + } + } else { // copy vertical strips + int s = h / w; // 2 if twice as heigh as wide + for (int i = 0; i < w / 2; i++) { + for (int j = 0; j < h / s / 2; j++) { + for (int p = 0; p < s; p++) map->copyXY(w - j - 1, i*s + p, i, j*s + p); + } + } + } + + // move players + for (int i = 0; i < map->getMaxFactions(); ++i) // first remove players from target corner + if (map->getStartLocationX(i) >= w / 2 && map->getStartLocationY(i) < h / 2) map->changeStartLocation(0, 0, i); + for (int i = 0; i < map->getMaxFactions(); ++i) { + if ((map->getStartLocationX(i) < w / 2 && map->getStartLocationY(i) < h / 2) && (map->getStartLocationX(i) != 0 || map->getStartLocationY(i) != 0)) // any startpositions to copy? + for (int ii = 0; ii < map->getMaxFactions(); ++ii) + if (map->getStartLocationX(ii) == 0 && map->getStartLocationY(ii) == 0) { // first free one + map->changeStartLocation(w - map->getStartLocationY(i)*w / h - 1, map->getStartLocationX(i)*h / w, ii); + break; + } + } + } } - //std::cout << "reverted changes (we hope)" << std::endl; -} -// =============================================== -// class Program -// =============================================== -MapPreview *Program::map = NULL; - -Program::Program(int w, int h, string playerName) { - cellSize = 5; - grid=false; - heightmap=false; - hideWater=false; - ofsetX = 0; - ofsetY = 0; - - map = new MapPreview(); - resetFactions(8); - renderer.initMapSurface(w, h); - map->setAuthor(playerName); -} - -void Program::init() { - undoStack = ChangeStack(); - redoStack = ChangeStack(); - cellSize = 5; - grid=false; - heightmap=false; - hideWater=false; - ofsetX = 0; - ofsetY = 0; - map = NULL; -} - -Program::~Program() { - delete map; - map = NULL; -} - -int Program::getObject(int x, int y) { - int i=(x - ofsetX) / cellSize; - int j= (y + ofsetY) / cellSize; - if (map && map->inside(i, j)) { - return map->getObject(i,j); + void Program::shiftLeft() { + if (map) { + int w = map->getW() - 1; + int h = map->getH(); + for (int i = 0; i < w; i++) + for (int j = 0; j < h; j++) + map->copyXY(i, j, i + 1, j); + for (int i = 0; i < map->getMaxFactions(); ++i) // move players + map->changeStartLocation(map->getStartLocationX(i) - 1, map->getStartLocationY(i), i); // it allready check limits + } } - else { - return 0; + + void Program::flipDiagonal() { + if (map) { + int w = map->getW(); + int h = map->getH(); + for (int i = 0; i < w; i++) + for (int j = i; j < h; j++) { + map->swapXY(i, j, j, i); + } + for (int i = 0; i < map->getMaxFactions(); ++i) // move players + if (map->getStartLocationX(i) != 0 || map->getStartLocationY(i) != 0) // don't move the unset ones + map->changeStartLocation(map->getStartLocationY(i), map->getStartLocationX(i), i); // it allready check limits + } } -} -int Program::getCellX(int x) { - return (x - ofsetX) / cellSize; -} -int Program::getCellY(int y) { - return (y + ofsetY) / cellSize; -} - -int Program::getResource(int x, int y) { - int i=(x - ofsetX) / cellSize; - int j= (y + ofsetY) / cellSize; - if (map && map->inside(i, j)) { - return map->getResource(i,j); + void Program::shiftRight() { + if (map) { + int w = map->getW() - 1; + int h = map->getH(); + for (int i = w; i > 0; i--) + for (int j = 0; j < h; j++) + map->copyXY(i, j, i - 1, j); + for (int i = 0; i < map->getMaxFactions(); ++i) // move players + if (map->getStartLocationX(i) != 0 || map->getStartLocationY(i) != 0) // don't move the unset ones + map->changeStartLocation(map->getStartLocationX(i) + 1, map->getStartLocationY(i), i); // it allready check limits + } } - else { - return 0; + void Program::shiftUp() { + if (map) { + int w = map->getW(); + int h = map->getH() - 1; + for (int i = 0; i < w; i++) + for (int j = 0; j < h; j++) + map->copyXY(i, j, i, j + 1); + for (int i = 0; i < map->getMaxFactions(); ++i) // move players + map->changeStartLocation(map->getStartLocationX(i), map->getStartLocationY(i) - 1, i); // it allready check limits + } + } + void Program::shiftDown() { + if (map) { + int w = map->getW(); + int h = map->getH() - 1; + for (int i = 0; i < w; i++) + for (int j = h; j > 0; j--) + map->copyXY(i, j, i, j - 1); + for (int i = 0; i < map->getMaxFactions(); ++i) // move players + if (map->getStartLocationX(i) != 0 || map->getStartLocationY(i) != 0) // don't move the unset ones + map->changeStartLocation(map->getStartLocationX(i), map->getStartLocationY(i) + 1, i); // it allready check limits + } } -} -void Program::glestChangeMapHeight(int x, int y, int Height, int radius) { - if(map) map->glestChangeHeight((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, Height, radius); -} -void Program::pirateChangeMapHeight(int x, int y, int Height, int radius) { - if(map) map->pirateChangeHeight((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, Height, radius); -} + void Program::randomizeMapHeights(bool withReset, int minimumHeight, int maximumHeight, int chanceDivider, int smoothRecursions) { + if (map) map->randomizeHeights(withReset, minimumHeight, maximumHeight, chanceDivider, smoothRecursions); + } -void Program::changeMapSurface(int x, int y, int surface, int radius) { - if(map) map->changeSurface((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, static_cast(surface), radius); -} + void Program::randomizeFactions() { + if (map) map->randomizeFactions(); + } -void Program::changeMapObject(int x, int y, int object, int radius) { - if(map) map->changeObject((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, object, radius); -} + void Program::switchMapSurfaces(int surf1, int surf2) { + if (map) map->switchSurfaces(static_cast(surf1), static_cast(surf2)); + } -void Program::changeMapResource(int x, int y, int resource, int radius) { - if(map) map->changeResource((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, resource, radius); -} + void Program::reset(int w, int h, int alt, int surf) { + undoStack.clear(); + redoStack.clear(); + if (map) map->reset(w, h, (float) alt, static_cast(surf)); + } -void Program::changeStartLocation(int x, int y, int player) { - if(map) map->changeStartLocation((x - ofsetX) / cellSize, (y + ofsetY) / cellSize, player); -} + void Program::resize(int w, int h, int alt, int surf) { + if (map) map->resize(w, h, (float) alt, static_cast(surf)); + } -void Program::setUndoPoint(ChangeType change) { - if (change == ctLocation) return; + void Program::resetFactions(int maxFactions) { + if (map) map->resetFactions(maxFactions); + randomizeFactions(); + } - undoStack.push(UndoPoint()); - undoStack.top().init(change); - - redoStack.clear(); -} - -bool Program::undo() { - if (undoStack.empty()) { + bool Program::setMapTitle(const string &title) { + if (map) { + if (map->getTitle() != title) { + map->setTitle(title); + return true; + } + } return false; } - // push current state onto redo stack - redoStack.push(UndoPoint()); - redoStack.top().init(undoStack.top().getChange()); - undoStack.top().revert(); - undoStack.pop(); - return true; -} - -bool Program::redo() { - if (redoStack.empty()) { + bool Program::setMapDesc(const string &desc) { + if (map) { + if (map->getDesc() != desc) { + map->setDesc(desc); + return true; + } + } return false; } - // push current state onto undo stack - undoStack.push(UndoPoint()); - undoStack.top().init(redoStack.top().getChange()); - redoStack.top().revert(); - redoStack.pop(); - return true; -} - -void Program::renderMap(int w, int h) { - //printf("Rendering map\n"); - if(map) renderer.renderMap(map, ofsetX, ofsetY, w, h, cellSize, grid,heightmap,hideWater); -} - -void Program::setRefAlt(int x, int y) { - if(map) map->setRefAlt((x - ofsetX) / cellSize, (y + ofsetY) / cellSize); -} - -void Program::flipX() { - if(map) map->flipX(); -} - -void Program::flipY() { - if(map) map->flipY(); -} - -void Program::mirrorX() { // copy left to right - if(map) { - int w=map->getW(); - int h=map->getH(); - for (int i = 0; i < w/2; i++) { - for (int j = 0; j < h; j++) { - map->copyXY(w-i-1,j , i,j); + bool Program::setMapAuthor(const string &author) { + if (map) { + if (map->getAuthor() != author) { + map->setAuthor(author); + return true; } } - - // move players - for (int i = 0; i < map->getMaxFactions(); ++i) // first remove players from target corner - if (map->getStartLocationX(i) >= w/2) map->changeStartLocation(0,0,i); - for (int i = 0; i < map->getMaxFactions(); ++i) { - if((map->getStartLocationX(i) < w/2) && (map->getStartLocationX(i)!=0 || map->getStartLocationY(i)!=0)) // any startpositions to copy? - for (int ii = 0; ii < map->getMaxFactions(); ++ii) - if(map->getStartLocationX(ii)==0 && map->getStartLocationY(ii)==0) { // first free one - map->changeStartLocation(w-map->getStartLocationX(i)-1, map->getStartLocationY(i), ii); - break; - } - } + return false; } -} -void Program::mirrorY() { // copy top to bottom - if(map) { - int w=map->getW(); - int h=map->getH(); - for (int i = 0; i < w; i++) { - for (int j = 0; j < h/2; j++) { - map->copyXY(i,h-j-1 , i,j); + void Program::setOfset(int x, int y) { + ofsetX += x; + ofsetY -= y; + } + + void Program::incCellSize(int i) { + if (map) { + int minInc = 2 - cellSize; + + if (i < minInc) { + i = minInc; } - } - - // move players - for (int i = 0; i < map->getMaxFactions(); ++i) // first remove players from target corner - if (map->getStartLocationY(i) >= h/2) map->changeStartLocation(0,0,i); - for (int i = 0; i < map->getMaxFactions(); ++i) { - if((map->getStartLocationY(i) < h/2) && (map->getStartLocationX(i)!=0 || map->getStartLocationY(i)!=0)) // any startpositions to copy? - for (int ii = 0; ii < map->getMaxFactions(); ++ii) - if(map->getStartLocationX(ii)==0 && map->getStartLocationY(ii)==0) { // first free one - map->changeStartLocation(map->getStartLocationX(i), h-map->getStartLocationY(i)-1, ii); - break; - } + cellSize += i; + ofsetX -= (map->getW() * i) / 2; + ofsetY += (map->getH() * i) / 2; } } -} -void Program::mirrorXY() { // copy leftbottom to topright, can handle non-sqaure maps - if(map) { - int w=map->getW(); - int h=map->getH(); - if (h==w) { - for (int i = 0; i < w-1; i++) { - for (int j = i+1; j < h; j++) { - map->copyXY(j,i , i,j); - } - } - } - // Non-sqaure maps: - else if (h < w) { // copy horizontal strips - int s=w/h; // 2 if twice as wide as heigh - for (int i = 0; i < w/s-1; i++) { - for (int j = i+1; j < h; j++) { - for (int p = 0; p < s; p++) map->copyXY(j*s+p,i , i*s+p,j); - } - } - } - else { // copy vertical strips - int s=h/w; // 2 if twice as heigh as wide - for (int i = 0; i < w-1; i++) { - for (int j = i+1; j < h/s; j++) { - for (int p = 0; p < s; p++) map->copyXY(j,i*s+p , i,j*s+p); - } - } - } - - // move players - for (int i = 0; i < map->getMaxFactions(); ++i) // first remove players from target corner - if (map->getStartLocationX(i) > map->getStartLocationY(i)) map->changeStartLocation(0,0,i); - for (int i = 0; i < map->getMaxFactions(); ++i) { - if(map->getStartLocationX(i) < map->getStartLocationY(i)) // any startpositions to copy? - for (int ii = 0; ii < map->getMaxFactions(); ++ii) - if(map->getStartLocationX(ii)==0 && map->getStartLocationY(ii) == 0) { // first free one - map->changeStartLocation(map->getStartLocationY(i)*w/h, map->getStartLocationX(i)*h/w, ii); - break; - } - } + void Program::resetOfset() { + ofsetX = 0; + ofsetY = 0; + cellSize = 5; } -} -void Program::rotatecopyX() { - if(map) { - int w=map->getW(); - int h=map->getH(); - for (int i = 0; i < w/2; i++) { - for (int j = 0; j < h; j++) { - map->copyXY(w-i-1,h-j-1 , i,j); - } - } - - // move players - for (int i = 0; i < map->getMaxFactions(); ++i) // first remove players from target corner - if (map->getStartLocationX(i) >= w/2) map->changeStartLocation(0,0,i); - for (int i = 0; i < map->getMaxFactions(); ++i) { - if((map->getStartLocationX(i) < w/2) && (map->getStartLocationX(i)!=0 || map->getStartLocationY(i)!=0)) // any startpositions to copy? - for (int ii = 0; ii < map->getMaxFactions(); ++ii) - if(map->getStartLocationX(ii)==0 && map->getStartLocationY(ii)==0) { // first free one - map->changeStartLocation(w-map->getStartLocationX(i)-1, h-map->getStartLocationY(i)-1, ii); - break; - } - } + bool Program::setGridOnOff() { + grid = !grid; + return grid; } -} - -void Program::rotatecopyY() { - if(map) { - int w=map->getW(); - int h=map->getH(); - for (int i = 0; i < w; i++) { - for (int j = 0; j < h/2; j++) { - map->copyXY(w-i-1,h-j-1 , i,j); - } - } - - // move players - for (int i = 0; i < map->getMaxFactions(); ++i) // first remove players from target corner - if (map->getStartLocationY(i) >= h/2) map->changeStartLocation(0,0,i); - for (int i = 0; i < map->getMaxFactions(); ++i) { - if((map->getStartLocationY(i) < h/2) && (map->getStartLocationX(i)!=0 || map->getStartLocationY(i)!=0)) // any startpositions to copy? - for (int ii = 0; ii < map->getMaxFactions(); ++ii) - if(map->getStartLocationX(ii)==0 && map->getStartLocationY(ii)==0) { // first free one - map->changeStartLocation(w-map->getStartLocationX(i)-1, h-map->getStartLocationY(i)-1, ii); - break; - } - } + bool Program::setHeightMapOnOff() { + heightmap = !heightmap; + return heightmap; } -} - -void Program::rotatecopyXY() { - if(map) { - int w=map->getW(); - int h=map->getH(); - int sw=w/h; if(sw<1) sw=1; // x-squares per y - int sh=h/w; if(sh<1) sh=1; // y-squares per x - if (sh==1) - for (int j = 0; j < h-1; j++) { // row by row! - for (int i = j*sw; i < w; i++) { - map->copyXY(i,j , w-i-1,h-j-1); - } - } - else - for (int i = 0; i = 0; j--) { - map->copyXY(w-i-1,j , i,h-j-1); - } - } - - // move players - for (int i = 0; i < map->getMaxFactions(); ++i) // first remove players from target corner - if (map->getStartLocationX(i) > map->getStartLocationY(i)) map->changeStartLocation(0,0,i); - for (int i = 0; i < map->getMaxFactions(); ++i) { - if(map->getStartLocationX(i) < map->getStartLocationY(i)) // any startpositions to copy? - for (int ii = 0; ii < map->getMaxFactions(); ++ii) - if(map->getStartLocationX(ii)==0 && map->getStartLocationY(ii) == 0) { // first free one - map->changeStartLocation(w-map->getStartLocationX(i)-1, h-map->getStartLocationY(i)-1, ii); - break; - } - } + bool Program::setHideWaterOnOff() { + hideWater = !hideWater; + return hideWater; } -} -void Program::rotatecopyCorner() { // rotate top left 1/4 to top right 1/4 - if(map) { - int w=map->getW(); - int h=map->getH(); - if (h==w) { - for (int i = 0; i < w/2; i++) { - for (int j = 0; j < h/2; j++) { - map->copyXY(w-j-1,i , i,j); - } - } - } - // Non-sqaure maps: - else if (h < w) { // copy horizontal strips - int s=w/h; // 2 if twice as wide as heigh - for (int i = 0; i < w/s/2; i++) { - for (int j = 0; j < h/2; j++) { - for (int p = 0; p < s; p++) map->copyXY(w-j*s-1-p,i , i*s+p,j); - } - } - } - else { // copy vertical strips - int s=h/w; // 2 if twice as heigh as wide - for (int i = 0; i < w/2; i++) { - for (int j = 0; j < h/s/2; j++) { - for (int p = 0; p < s; p++) map->copyXY(w-j-1,i*s+p , i,j*s+p); - } - } - } - - // move players - for (int i = 0; i < map->getMaxFactions(); ++i) // first remove players from target corner - if (map->getStartLocationX(i) >= w/2 && map->getStartLocationY(i) < h/2) map->changeStartLocation(0,0,i); - for (int i = 0; i < map->getMaxFactions(); ++i) { - if((map->getStartLocationX(i) < w/2 && map->getStartLocationY(i) < h/2) && (map->getStartLocationX(i)!=0 || map->getStartLocationY(i)!=0)) // any startpositions to copy? - for (int ii = 0; ii < map->getMaxFactions(); ++ii) - if(map->getStartLocationX(ii)==0 && map->getStartLocationY(ii)==0) { // first free one - map->changeStartLocation(w-map->getStartLocationY(i)*w/h-1, map->getStartLocationX(i)*h/w, ii); - break; - } - } + void Program::setMapAdvanced(int altFactor, int waterLevel, int cliffLevel, int cameraHeight) { + if (map) map->setAdvanced(altFactor, waterLevel, cliffLevel, cameraHeight); } -} + void Program::loadMap(const string &path) { + undoStack.clear(); + redoStack.clear(); -void Program::shiftLeft() { - if(map) { - int w=map->getW()-1; - int h=map->getH(); - for (int i=0; icopyXY(i,j , i+1,j); - for (int i = 0; i < map->getMaxFactions(); ++i) // move players - map->changeStartLocation(map->getStartLocationX(i)-1, map->getStartLocationY(i), i); // it allready check limits - } -} - -void Program::flipDiagonal() { - if(map) { - int w=map->getW(); - int h=map->getH(); - for (int i=0; iswapXY(i,j , j,i); - } - for (int i = 0; i < map->getMaxFactions(); ++i) // move players - if (map->getStartLocationX(i) != 0 || map->getStartLocationY(i) != 0) // don't move the unset ones - map->changeStartLocation(map->getStartLocationY(i), map->getStartLocationX(i), i); // it allready check limits - } -} - - -void Program::shiftRight() { - if(map) { - int w=map->getW()-1; - int h=map->getH(); - for (int i=w; i>0; i--) - for (int j=0; jcopyXY(i,j , i-1,j); - for (int i = 0; i < map->getMaxFactions(); ++i) // move players - if (map->getStartLocationX(i) != 0 || map->getStartLocationY(i) != 0) // don't move the unset ones - map->changeStartLocation(map->getStartLocationX(i)+1, map->getStartLocationY(i), i); // it allready check limits - } -} -void Program::shiftUp() { - if(map) { - int w=map->getW(); - int h=map->getH()-1; - for (int i=0; icopyXY(i,j , i,j+1); - for (int i = 0; i < map->getMaxFactions(); ++i) // move players - map->changeStartLocation(map->getStartLocationX(i), map->getStartLocationY(i)-1, i); // it allready check limits - } -} -void Program::shiftDown() { - if(map) { - int w=map->getW(); - int h=map->getH()-1; - for (int i=0; i0; j--) - map->copyXY(i,j , i,j-1); - for (int i = 0; i < map->getMaxFactions(); ++i) // move players - if (map->getStartLocationX(i) != 0 || map->getStartLocationY(i) != 0) // don't move the unset ones - map->changeStartLocation(map->getStartLocationX(i), map->getStartLocationY(i)+1, i); // it allready check limits - } -} - - -void Program::randomizeMapHeights(bool withReset,int minimumHeight, int maximumHeight, int chanceDivider, int smoothRecursions) { - if(map) map->randomizeHeights(withReset, minimumHeight, maximumHeight, chanceDivider, smoothRecursions); -} - -void Program::randomizeFactions() { - if(map) map->randomizeFactions(); -} - -void Program::switchMapSurfaces(int surf1, int surf2) { - if(map) map->switchSurfaces(static_cast(surf1), static_cast(surf2)); -} - -void Program::reset(int w, int h, int alt, int surf) { - undoStack.clear(); - redoStack.clear(); - if(map) map->reset(w, h, (float) alt, static_cast(surf)); -} - -void Program::resize(int w, int h, int alt, int surf) { - if(map) map->resize(w, h, (float) alt, static_cast(surf)); -} - -void Program::resetFactions(int maxFactions) { - if(map) map->resetFactions(maxFactions); - randomizeFactions(); -} - -bool Program::setMapTitle(const string &title) { - if(map) { - if (map->getTitle() != title) { - map->setTitle(title); - return true; - } - } - return false; -} - -bool Program::setMapDesc(const string &desc) { - if(map) { - if (map->getDesc() != desc) { - map->setDesc(desc); - return true; - } - } - return false; -} - -bool Program::setMapAuthor(const string &author) { - if(map) { - if (map->getAuthor() != author) { - map->setAuthor(author); - return true; - } - } - return false; -} - -void Program::setOfset(int x, int y) { - ofsetX += x; - ofsetY -= y; -} - -void Program::incCellSize(int i) { - if(map) { - int minInc = 2 - cellSize; - - if (i < minInc) { - i = minInc; - } - cellSize += i; - ofsetX -= (map->getW() * i) / 2; - ofsetY += (map->getH() * i) / 2; - } -} - -void Program::resetOfset() { - ofsetX = 0; - ofsetY = 0; - cellSize = 5; -} - -bool Program::setGridOnOff() { - grid=!grid; - return grid; -} -bool Program::setHeightMapOnOff() { - heightmap=!heightmap; - return heightmap; -} -bool Program::setHideWaterOnOff() { - hideWater=!hideWater; - return hideWater; -} - -void Program::setMapAdvanced(int altFactor, int waterLevel, int cliffLevel , int cameraHeight) { - if(map) map->setAdvanced(altFactor, waterLevel, cliffLevel, cameraHeight); -} - -void Program::loadMap(const string &path) { - undoStack.clear(); - redoStack.clear(); - - std::string encodedPath = path; - map->loadFromFile(encodedPath); -} - -void Program::saveMap(const string &path) { - if(map) { std::string encodedPath = path; - - map->saveToFile(encodedPath); + map->loadFromFile(encodedPath); + } + + void Program::saveMap(const string &path) { + if (map) { + std::string encodedPath = path; + + map->saveToFile(encodedPath); + } } -} }// end namespace diff --git a/source/glest_map_editor/program.h b/source/glest_map_editor/program.h index f332b4199..d2fd6abb4 100644 --- a/source/glest_map_editor/program.h +++ b/source/glest_map_editor/program.h @@ -25,26 +25,26 @@ using namespace Shared::Graphics; namespace MapEditor { -class MainWindow; + class MainWindow; -enum ChangeType { - ctNone = -1, - ctHeight, - ctSurface, - ctObject, - ctResource, - ctLocation, - ctGradient, - ctAll -}; + enum ChangeType { + ctNone = -1, + ctHeight, + ctSurface, + ctObject, + ctResource, + ctLocation, + ctGradient, + ctAll + }; -// ============================================= -// class Undo Point -// A linked list class that is more of an extension / modification on -// the already existing Cell struct in map.h -// Provides the ability to only specify a certain property of the map to change -// ============================================= -class UndoPoint { + // ============================================= + // class Undo Point + // A linked list class that is more of an extension / modification on + // the already existing Cell struct in map.h + // Provides the ability to only specify a certain property of the map to change + // ============================================= + class UndoPoint { private: // Only keep a certain number of undo points in memory otherwise // Big projects could hog a lot of memory @@ -69,115 +69,122 @@ class UndoPoint { void init(ChangeType change); void revert(); - inline ChangeType getChange() const { return change; } -}; - -class ChangeStack : public std::stack { -public: - static const unsigned int maxSize = 100; - - ChangeStack() : std::stack() { } - void clear() { c.clear(); } - - void push(UndoPoint p) { - if (c.size() >= maxSize) { - c.pop_front(); + inline ChangeType getChange() const { + return change; } - stack::push(p); - } -}; + }; -// =============================================== -// class Program -// =============================================== + class ChangeStack : public std::stack { + public: + static const unsigned int maxSize = 100; -class Program { -private: - //Renderer renderer; - BaseRenderer renderer; - int ofsetX, ofsetY; - int cellSize; - bool grid; // show grid option - bool heightmap; - bool hideWater; - //static Map *map; - static MapPreview *map; - friend class UndoPoint; - ChangeStack undoStack, redoStack; + ChangeStack() : std::stack() { + } + void clear() { + c.clear(); + } - void init(); -public: - Program(int w, int h, string playerName); - ~Program(); + void push(UndoPoint p) { + if (c.size() >= maxSize) { + c.pop_front(); + } + stack::push(p); + } + }; - Program(const Program& obj) { - init(); - throw runtime_error("class Program is NOT safe to copy!"); - } - Program & operator=(const Program& obj) { - init(); - throw runtime_error("class Program is NOT safe to assign!"); - } + // =============================================== + // class Program + // =============================================== - //map cell change - void glestChangeMapHeight(int x, int y, int Height, int radius); - void pirateChangeMapHeight(int x, int y, int Height, int radius); - void changeMapSurface(int x, int y, int surface, int radius); - void changeMapObject(int x, int y, int object, int radius); - void changeMapResource(int x, int y, int resource, int radius); - void changeStartLocation(int x, int y, int player); + class Program { + private: + //Renderer renderer; + BaseRenderer renderer; + int ofsetX, ofsetY; + int cellSize; + bool grid; // show grid option + bool heightmap; + bool hideWater; + //static Map *map; + static MapPreview *map; + friend class UndoPoint; + ChangeStack undoStack, redoStack; - void setUndoPoint(ChangeType change); - bool undo(); - bool redo(); + void init(); + public: + Program(int w, int h, string playerName); + ~Program(); - //map ops - void reset(int w, int h, int alt, int surf); - void resize(int w, int h, int alt, int surf); - void resetFactions(int maxFactions); - void setRefAlt(int x, int y); - void flipX(); - void flipY(); - void mirrorX(); - void mirrorY(); - void mirrorXY(); - void rotatecopyX(); - void rotatecopyY(); - void rotatecopyXY(); - void rotatecopyCorner(); - void flipDiagonal(); - void shiftLeft(); - void shiftRight(); - void shiftUp(); - void shiftDown(); + Program(const Program& obj) { + init(); + throw runtime_error("class Program is NOT safe to copy!"); + } + Program & operator=(const Program& obj) { + init(); + throw runtime_error("class Program is NOT safe to assign!"); + } - void randomizeMapHeights(bool withReset, int minimumHeight, int maximumHeight, int chanceDivider, int smoothRecursions);; - void randomizeFactions(); - void switchMapSurfaces(int surf1, int surf2); - void loadMap(const string &path); - void saveMap(const string &path); + //map cell change + void glestChangeMapHeight(int x, int y, int Height, int radius); + void pirateChangeMapHeight(int x, int y, int Height, int radius); + void changeMapSurface(int x, int y, int surface, int radius); + void changeMapObject(int x, int y, int object, int radius); + void changeMapResource(int x, int y, int resource, int radius); + void changeStartLocation(int x, int y, int player); - //map misc - bool setMapTitle(const string &title); - bool setMapDesc(const string &desc); - bool setMapAuthor(const string &author); - void setMapAdvanced(int altFactor, int waterLevel, int minimumCliffHeight, int cameraHeight); + void setUndoPoint(ChangeType change); + bool undo(); + bool redo(); - //misc - void renderMap(int w, int h); - void setOfset(int x, int y); - void incCellSize(int i); - void resetOfset(); - bool setGridOnOff(); - bool setHeightMapOnOff(); - bool setHideWaterOnOff(); + //map ops + void reset(int w, int h, int alt, int surf); + void resize(int w, int h, int alt, int surf); + void resetFactions(int maxFactions); + void setRefAlt(int x, int y); + void flipX(); + void flipY(); + void mirrorX(); + void mirrorY(); + void mirrorXY(); + void rotatecopyX(); + void rotatecopyY(); + void rotatecopyXY(); + void rotatecopyCorner(); + void flipDiagonal(); + void shiftLeft(); + void shiftRight(); + void shiftUp(); + void shiftDown(); - int getObject(int x, int y); - int getResource(int x, int y); - int getCellX(int x); - int getCellY(int y); - static const MapPreview *getMap() {return map;} -}; + void randomizeMapHeights(bool withReset, int minimumHeight, int maximumHeight, int chanceDivider, int smoothRecursions);; + void randomizeFactions(); + void switchMapSurfaces(int surf1, int surf2); + void loadMap(const string &path); + void saveMap(const string &path); + + //map misc + bool setMapTitle(const string &title); + bool setMapDesc(const string &desc); + bool setMapAuthor(const string &author); + void setMapAdvanced(int altFactor, int waterLevel, int minimumCliffHeight, int cameraHeight); + + //misc + void renderMap(int w, int h); + void setOfset(int x, int y); + void incCellSize(int i); + void resetOfset(); + bool setGridOnOff(); + bool setHeightMapOnOff(); + bool setHideWaterOnOff(); + + int getObject(int x, int y); + int getResource(int x, int y); + int getCellX(int x); + int getCellY(int y); + static const MapPreview *getMap() { + return map; + } + }; }// end namespace diff --git a/source/shared_lib/include/compression/compression_utils.h b/source/shared_lib/include/compression/compression_utils.h index 707a46a7d..68586f7f4 100644 --- a/source/shared_lib/include/compression/compression_utils.h +++ b/source/shared_lib/include/compression/compression_utils.h @@ -16,13 +16,15 @@ using std::string; -namespace Shared{ namespace CompressionUtil{ +namespace Shared { + namespace CompressionUtil { -bool compressFileToZIPFile(string inFile, string outFile, int compressionLevel=5); -bool extractFileFromZIPFile(string inFile, string outFile); -std::pair compressMemoryToMemory(unsigned char *input, unsigned long input_len, int compressionLevel=5); -std::pair extractMemoryToMemory(unsigned char *input, unsigned long input_len, unsigned long max_output_len); + bool compressFileToZIPFile(string inFile, string outFile, int compressionLevel = 5); + bool extractFileFromZIPFile(string inFile, string outFile); + std::pair compressMemoryToMemory(unsigned char *input, unsigned long input_len, int compressionLevel = 5); + std::pair extractMemoryToMemory(unsigned char *input, unsigned long input_len, unsigned long max_output_len); -}}; + } +}; #endif diff --git a/source/shared_lib/include/feathery_ftp/ftp.h b/source/shared_lib/include/feathery_ftp/ftp.h index 6d26d33dd..c8bc3eaad 100644 --- a/source/shared_lib/include/feathery_ftp/ftp.h +++ b/source/shared_lib/include/feathery_ftp/ftp.h @@ -26,12 +26,11 @@ #define FTP_H_ -/** - * @brief specifies the type of operation that is in progress - */ -typedef enum -{ - OP_NOP = 0, ///< no operation + /** + * @brief specifies the type of operation that is in progress + */ +typedef enum { + OP_NOP = 0, ///< no operation OP_RETR = 1, ///< RETR command OP_STOR = 2, ///< STOR command OP_LIST = 3 ///< LIST command @@ -41,8 +40,7 @@ typedef enum * @brief infos about a file/directory transmittion * @see ftpExecTransmission */ -typedef struct -{ +typedef struct { operation_E op; ///< active transmission void* fsHandle; ///< file or directory handle of current transmission socket_t dataSocket; ///< data socket of current transmission @@ -53,8 +51,7 @@ typedef struct /** * @brief Data of a ftp session */ -typedef struct -{ +typedef struct { int open; ///< TRUE, if the session is open int authenticated; ///< TRUE, if user is authenticated via USER and PASS commands int userId; ///< id of the dedicated user account, is 0 until execution of USER command @@ -79,18 +76,16 @@ typedef struct /** * @brief format in which a message is to be displayed */ -typedef enum -{ - MSG_NORMAL = 0, ///< normal message, no translation - MSG_QUOTE = 1, ///< message will be displayed between doublequotes +typedef enum { + MSG_NORMAL = 0, ///< normal message, no translation + MSG_QUOTE = 1, ///< message will be displayed between doublequotes MSG_MULTILINE = 2 ///< message contains multiple lines }msgmode_E; /** * @brief time-structure */ -typedef struct -{ +typedef struct { uint16_t year; ///< year 0000-9999 uint8_t month; ///< month 1 - 12 uint8_t day; ///< day 1 - 31 @@ -103,10 +98,9 @@ typedef struct /** * @brief type of a file */ -typedef enum -{ +typedef enum { TYPE_FILE = 1, ///< regular file - TYPE_DIR = 2, ///< directory + TYPE_DIR = 2, ///< directory TYPE_LINK = 4 ///< hard link }ftpFileType_E; @@ -114,8 +108,7 @@ typedef enum /** * @brief infos about a file or directory similar to stat */ -typedef struct -{ +typedef struct { ftpFileType_E type; ///< filetype uint16_t mode; ///< access rights (currently unused) ftpTime_S cTime; ///< creation time (currently unused) @@ -171,7 +164,7 @@ extern int ftpStat(const char* path, ftpPathInfo_S *info); # define ftpRemoveFile remove #else extern void* ftpOpenFile(const char *filename, const char *mode); -extern int ftpCloseFile(void *stream ); +extern int ftpCloseFile(void *stream); extern int ftpReadFile(void *buffer, size_t size, size_t count, void *stream); extern int ftpWriteFile(const void *buffer, size_t size, size_t count, void *stream); extern int ftpRemoveFile(const char* path); diff --git a/source/shared_lib/include/feathery_ftp/ftpConfig.h b/source/shared_lib/include/feathery_ftp/ftpConfig.h index ce0d3d9e1..beade3db7 100644 --- a/source/shared_lib/include/feathery_ftp/ftpConfig.h +++ b/source/shared_lib/include/feathery_ftp/ftpConfig.h @@ -22,65 +22,65 @@ #ifndef FTPCONFIG_H_ #define FTPCONFIG_H_ -/** - * @brief max. possible simultaneous FTP client connections - */ + /** + * @brief max. possible simultaneous FTP client connections + */ #define MAX_CONNECTIONS 20 -/** - * @brief max. possible user accounts - */ + /** + * @brief max. possible user accounts + */ #define MAX_USERS 10 -/** - * @brief max. length of a user account name - */ + /** + * @brief max. length of a user account name + */ #define MAXLEN_USERNAME 40 -/** - * @brief max. length of a user account password - */ + /** + * @brief max. length of a user account password + */ #define MAXLEN_PASSWORD 40 -/** - * @brief session timeout in seconds - */ + /** + * @brief session timeout in seconds + */ #define SESSION_TIMEOUT 600 -/** - * @brief maximum length of a complete directory path - */ + /** + * @brief maximum length of a complete directory path + */ #define MAX_PATH_LEN 1024 -/** - * @brief Size of the scratch buffer - * - * The scratch buffer is used for - * send / receive of files and directory listings - */ + /** + * @brief Size of the scratch buffer + * + * The scratch buffer is used for + * send / receive of files and directory listings + */ #define LEN_SCRATCHBUF 1024 -/** - * @brief Size of the receive buffer for ftp commands - * - * Buffer must be big enough to hold a complete ftp command. - * command (4) + space (1) + path (MAX_PATH_LEN) + quotes (2) + CRLF (2) + end of string (1) - */ + /** + * @brief Size of the receive buffer for ftp commands + * + * Buffer must be big enough to hold a complete ftp command. + * command (4) + space (1) + path (MAX_PATH_LEN) + quotes (2) + CRLF (2) + end of string (1) + */ #define LEN_RXBUF (MAX_PATH_LEN + 10) -/** - * @brief activates ftp extentions according to RFC 3659 - */ + /** + * @brief activates ftp extentions according to RFC 3659 + */ #define RFC3659 1 -/** - * @brief set to 1 to activate debug messages on stdout - */ -//#define DBG_LOG 1 + /** + * @brief set to 1 to activate debug messages on stdout + */ + //#define DBG_LOG 1 -/** - * @brief set to 1 if target-plattform supports ANSI-C file-IO functions - */ + /** + * @brief set to 1 if target-plattform supports ANSI-C file-IO functions + */ #define ANSI_FILE_IO 1 #endif /* FTPCONFIG_H_ */ diff --git a/source/shared_lib/include/feathery_ftp/ftpIfc.h b/source/shared_lib/include/feathery_ftp/ftpIfc.h index fd9dce47c..a3d863867 100644 --- a/source/shared_lib/include/feathery_ftp/ftpIfc.h +++ b/source/shared_lib/include/feathery_ftp/ftpIfc.h @@ -38,16 +38,16 @@ extern "C" { #endif -void ftpInit(ftpFindExternalFTPServerIpType cb1, ftpAddUPNPPortForwardType cb2, - ftpRemoveUPNPPortForwardType cb3, ftpIsValidClientType cb4, - ftpIsClientAllowedToGetFileType cb5); -int ftpCreateAccount(const char* name, const char* passw, const char* root, int accRights); -int ftpDeleteAccount(const char* name); -int ftpStart(int portNumber); -int ftpShutdown(void); -int ftpExecute(void); -int ftpState(void); -void ftpSignalShutdown(void); + void ftpInit(ftpFindExternalFTPServerIpType cb1, ftpAddUPNPPortForwardType cb2, + ftpRemoveUPNPPortForwardType cb3, ftpIsValidClientType cb4, + ftpIsClientAllowedToGetFileType cb5); + int ftpCreateAccount(const char* name, const char* passw, const char* root, int accRights); + int ftpDeleteAccount(const char* name); + int ftpStart(int portNumber); + int ftpShutdown(void); + int ftpExecute(void); + int ftpState(void); + void ftpSignalShutdown(void); #ifdef __cplusplus } diff --git a/source/shared_lib/include/feathery_ftp/ftpTypes.h b/source/shared_lib/include/feathery_ftp/ftpTypes.h index 893102289..cf7849f72 100644 --- a/source/shared_lib/include/feathery_ftp/ftpTypes.h +++ b/source/shared_lib/include/feathery_ftp/ftpTypes.h @@ -25,7 +25,7 @@ #define FTPTYPES_H_ -// if the compiler is c99 complient, we don't need to define our own types + // if the compiler is c99 complient, we don't need to define our own types #if __STDC_VERSION__ == 199901L || (defined(WIN32) && defined(_MSC_VER) && _MSC_VER >= 1600) # include #else @@ -48,9 +48,9 @@ typedef uint16_t port_t; */ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -/** - * @brief defines functions/variables local to a module - */ + /** + * @brief defines functions/variables local to a module + */ #define LOCAL static #ifndef FALSE @@ -69,19 +69,19 @@ typedef uint16_t port_t; extern "C" { #endif -int VERBOSE_MODE_ENABLED; + int VERBOSE_MODE_ENABLED; -typedef ip_t (*ftpFindExternalFTPServerIpType)(ip_t clientIp); -typedef void (*ftpAddUPNPPortForwardType)(int internalPort, int externalPort); -typedef void (*ftpRemoveUPNPPortForwardType)(int internalPort, int externalPort); -typedef int (*ftpIsValidClientType)(ip_t clientIp); -typedef int (*ftpIsClientAllowedToGetFileType)(ip_t clientIp, const char *username, const char *filename); + typedef ip_t(*ftpFindExternalFTPServerIpType)(ip_t clientIp); + typedef void(*ftpAddUPNPPortForwardType)(int internalPort, int externalPort); + typedef void(*ftpRemoveUPNPPortForwardType)(int internalPort, int externalPort); + typedef int(*ftpIsValidClientType)(ip_t clientIp); + typedef int(*ftpIsClientAllowedToGetFileType)(ip_t clientIp, const char *username, const char *filename); -ftpFindExternalFTPServerIpType ftpFindExternalFTPServerIp; -ftpAddUPNPPortForwardType ftpAddUPNPPortForward; -ftpRemoveUPNPPortForwardType ftpRemoveUPNPPortForward; -ftpIsValidClientType ftpIsValidClient; -ftpIsClientAllowedToGetFileType ftpIsClientAllowedToGetFile; + ftpFindExternalFTPServerIpType ftpFindExternalFTPServerIp; + ftpAddUPNPPortForwardType ftpAddUPNPPortForward; + ftpRemoveUPNPPortForwardType ftpRemoveUPNPPortForward; + ftpIsValidClientType ftpIsValidClient; + ftpIsClientAllowedToGetFileType ftpIsClientAllowedToGetFile; #ifdef __cplusplus } diff --git a/source/shared_lib/include/graphics/BMPReader.h b/source/shared_lib/include/graphics/BMPReader.h index c02135f28..8ef4e38ea 100644 --- a/source/shared_lib/include/graphics/BMPReader.h +++ b/source/shared_lib/include/graphics/BMPReader.h @@ -20,16 +20,18 @@ #include "pixmap.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -class BMPReader: FileReader { -public: - BMPReader(); + class BMPReader : FileReader { + public: + BMPReader(); - Pixmap2D* read(ifstream& in, const string& path, Pixmap2D* ret) const; -}; + Pixmap2D* read(ifstream& in, const string& path, Pixmap2D* ret) const; + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/shared_lib/include/graphics/FileReader.h b/source/shared_lib/include/graphics/FileReader.h index d2cd208f0..90608fb0c 100644 --- a/source/shared_lib/include/graphics/FileReader.h +++ b/source/shared_lib/include/graphics/FileReader.h @@ -32,131 +32,308 @@ using Shared::PlatformCommon::extractExtension; #define AS_STRING(...) #__VA_ARGS__ -namespace Shared{ +namespace Shared { -// ===================================================== -// class FileReader -// ===================================================== + // ===================================================== + // class FileReader + // ===================================================== -template -class FileReader { -public: - //string const * extensions; - std::vector extensions; + template + class FileReader { + public: + //string const * extensions; + std::vector extensions; - /**Creates a filereader being able to possibly load files - * from the specified extension - **/ - //FileReader(string const * extensions); - FileReader(std::vector extensions); + /**Creates a filereader being able to possibly load files + * from the specified extension + **/ + //FileReader(string const * extensions); + FileReader(std::vector extensions); - /**Creates a low-priority filereader - **/ - FileReader(); + /**Creates a low-priority filereader + **/ + FileReader(); -public: - /*Return the - existing and initialized - fileReadersMap - */ - static map const * >* >& getFileReadersMap() { - static map const * >* > fileReaderByExtension; - return fileReaderByExtension; - } + public: + /*Return the - existing and initialized - fileReadersMap + */ + static map const * >* >& getFileReadersMap() { + static map const * >* > fileReaderByExtension; + return fileReaderByExtension; + } - static vector const * >& getFileReaders() { - static vector const*> fileReaders; - return fileReaders; + static vector const * >& getFileReaders() { + static vector const*> fileReaders; + return fileReaders; + }; + + static vector const * >& getLowPriorityFileReaders() { + static vector const*> lowPriorityFileReaders; + return lowPriorityFileReaders; + }; + + + public: + + /**Tries to read a file + * This method tries to read the file with the specified filepath. + * If it fails, either null is returned or an exception + * is thrown*/ + static T* readPath(const string& filepath); + + /**Tries to read a file from an object + * This method tries to read the file with the specified filepath. + * If it fails, either null is returned or an exception + * is thrown*/ + static T* readPath(const string& filepath, T* object); + + /**Gives a quick estimation of whether the specified file + * can be read or not depending on the filename*/ + virtual bool canRead(const string& filepath) const; + + /**Gives a better estimation of whether the specified file + * can be read or not depending on the file content*/ + virtual bool canRead(ifstream& file) const; + + virtual void cleanupExtensions(); + + /**Reads a file + * This method tries to read the file with the specified filepath + * If it fails, either null is returned or an exception + * is thrown + */ + virtual T* read(const string& filepath) const; + + /**Reads a file to an object + * This method tries to read the file with the specified filepath + * If it fails, either null is returned or an exception + * is thrown + */ + virtual T* read(const string& filepath, T* object) const; + + /**Reads a file + * This method tries to read the specified file + * If it failes, either null is returned or an exception + * Default implementation generates an object using T() + * is thrown + */ + virtual T* read(ifstream& file, const string& path) const { + T* obj = new T(); + T* ret = read(file, path, obj); + if (obj != ret) { + delete obj; + } + return ret; + } + + + /**Reads a file onto the specified object + * This method tries to read the specified file + * If it failes, either null is returned or an exception + * is thrown + */ + virtual T* read(ifstream& file, const string& path, T* former) const = 0; + + virtual ~FileReader() { + cleanupExtensions(); + }; //Well ... these objects aren't supposed to be destroyed }; - static vector const * >& getLowPriorityFileReaders() { - static vector const*> lowPriorityFileReaders; - return lowPriorityFileReaders; - }; + template + static inline T* readFromFileReaders(vector const *>* readers, const string& filepath) { + //try to assign file +#if defined(WIN32) && !defined(__MINGW32__) + FILE *fp = _wfopen(utf8_decode(filepath).c_str(), L"rb"); + ifstream file(fp); +#else + ifstream file(filepath.c_str(), ios::in | ios::binary); +#endif + if (!file.is_open()) { + throw megaglest_runtime_error("[#1] Could not open file " + filepath); + } + for (typename vector const *>::const_iterator i = readers->begin(); i != readers->end(); ++i) { + T* ret = NULL; + file.seekg(0, ios::beg); //Set position to first + try { + FileReader const * reader = *i; + ret = reader->read(file, filepath); //It is guaranteed that at least the filepath matches ... + } +#if defined(WIN32) + catch (megaglest_runtime_error) { +#else + catch (megaglest_runtime_error &ex) { +#endif + throw; + } catch (...) { + continue; + } + if (ret != NULL) { + file.close(); +#if defined(WIN32) && !defined(__MINGW32__) + if (fp) fclose(fp); +#endif + return ret; + } + } + file.close(); +#if defined(WIN32) && !defined(__MINGW32__) + if (fp) fclose(fp); +#endif + return NULL; + } -public: + template + static inline T* readFromFileReaders(vector const *>* readers, const string& filepath, T* object) { + //try to assign file +#if defined(WIN32) && !defined(__MINGW32__) + wstring wstr = utf8_decode(filepath); + FILE *fp = _wfopen(wstr.c_str(), L"rb"); + int fileErrno = errno; + ifstream file(fp); +#else + ifstream file(filepath.c_str(), ios::in | ios::binary); +#endif + if (!file.is_open()) { +#if defined(WIN32) && !defined(__MINGW32__) + DWORD error = GetLastError(); + throw megaglest_runtime_error("[#2] Could not open file, result: " + intToStr(error) + " - " + intToStr(fileErrno) + " [" + filepath + "]"); +#else + throw megaglest_runtime_error("[#2] Could not open file [" + filepath + "]"); +#endif + } + for (typename vector const *>::const_iterator i = readers->begin(); i != readers->end(); ++i) { + T* ret = NULL; + file.seekg(0, ios::beg); //Set position to first + try { + FileReader const * reader = *i; + ret = reader->read(file, filepath, object); //It is guaranteed that at least the filepath matches ... + } +#if defined(WIN32) + catch (megaglest_runtime_error) { +#else + catch (megaglest_runtime_error &ex) { +#endif + throw; + } catch (...) { + continue; + } + if (ret != NULL) { + file.close(); +#if defined(WIN32) && !defined(__MINGW32__) + if (fp) fclose(fp); +#endif + return ret; + } + } + file.close(); +#if defined(WIN32) && !defined(__MINGW32__) + if (fp) fclose(fp); +#endif + return NULL; + } /**Tries to read a file * This method tries to read the file with the specified filepath. * If it fails, either null is returned or an exception - * is thrown*/ - static T* readPath(const string& filepath); + * is thrown*/ + template + T* FileReader::readPath(const string& filepath) { + const string& extension = extractExtension(filepath); + vector const * >* possibleReaders = (getFileReadersMap())[extension]; + if (possibleReaders != NULL) { + //Search in these possible readers + T* ret = readFromFileReaders(possibleReaders, filepath); + if (ret != NULL) { + return ret; + } + } + T* ret = readFromFileReaders(&(getFileReaders()), filepath); //Try all other + if (ret == NULL) { + std::cerr << "ERROR #1 - Could not parse filepath: " << filepath << std::endl; + throw megaglest_runtime_error(string("Could not parse ") + filepath + " as object of type " + typeid(T).name()); + } + return ret; + } - /**Tries to read a file from an object + /**Tries to read a file * This method tries to read the file with the specified filepath. * If it fails, either null is returned or an exception - * is thrown*/ - static T* readPath(const string& filepath, T* object); + * is thrown*/ + template + T* FileReader::readPath(const string& filepath, T* object) { + const string& extension = extractExtension(filepath); + vector const * >* possibleReaders = (getFileReadersMap())[extension]; + if (possibleReaders != NULL) { + //Search in these possible readers + T* ret = readFromFileReaders(possibleReaders, filepath, object); + if (ret != NULL) { + return ret; + } + } + T* ret = readFromFileReaders(&(getFileReaders()), filepath, object); //Try all other + if (ret == NULL) { + std::cerr << "ERROR #2 - Could not parse filepath: " << filepath << std::endl; + ret = readFromFileReaders(&(getLowPriorityFileReaders()), filepath); //Try to get dummy file + if (ret == NULL) { + throw megaglest_runtime_error(string("Could not parse ") + filepath + " as object of type " + typeid(T).name()); + } + } + return ret; + } + + template + FileReader::FileReader(std::vector extensions) : extensions(extensions) { + getFileReaders().push_back(this); + std::vector nextExtension = extensions; + for (unsigned int i = 0; i < nextExtension.size(); ++i) { + vector const* >* curPossibleReaders = (getFileReadersMap())[nextExtension[i]]; + if (curPossibleReaders == NULL) { + (getFileReadersMap())[nextExtension[i]] = (curPossibleReaders = new vector const *>()); + } + curPossibleReaders->push_back(this); + } + } + + template + void FileReader::cleanupExtensions() { + std::vector nextExtension = extensions; + for (unsigned int i = 0; i < nextExtension.size(); ++i) { + vector const* >* curPossibleReaders = (getFileReadersMap())[nextExtension[i]]; + if (curPossibleReaders != NULL) { + delete curPossibleReaders; + (getFileReadersMap())[nextExtension[i]] = NULL; + } + } + } /**Gives a quick estimation of whether the specified file - * can be read or not depending on the filename*/ - virtual bool canRead(const string& filepath) const; + * can be read or not depending on the filename*/ + template + bool FileReader::canRead(const string& filepath) const { + const string& realExtension = extractExtension(filepath); + //const string* haveExtension = extensions; + std::vector haveExtension = extensions; + //while (*haveExtension != "") { + for (unsigned int i = 0; i < haveExtension.size(); ++i) { + //if (realExtension == *haveExtension) { + if (realExtension == haveExtension[i]) { + return true; + } + //++haveExtension; + } + return false; + } /**Gives a better estimation of whether the specified file * can be read or not depending on the file content*/ - virtual bool canRead(ifstream& file) const; - - virtual void cleanupExtensions(); - - /**Reads a file - * This method tries to read the file with the specified filepath - * If it fails, either null is returned or an exception - * is thrown - */ - virtual T* read(const string& filepath) const; - - /**Reads a file to an object - * This method tries to read the file with the specified filepath - * If it fails, either null is returned or an exception - * is thrown - */ - virtual T* read(const string& filepath, T* object) const; - - /**Reads a file - * This method tries to read the specified file - * If it failes, either null is returned or an exception - * Default implementation generates an object using T() - * is thrown - */ - virtual T* read(ifstream& file, const string& path) const { - T* obj = new T(); - T* ret = read(file,path,obj); - if (obj != ret) { - delete obj; - } - return ret; - } - - - /**Reads a file onto the specified object - * This method tries to read the specified file - * If it failes, either null is returned or an exception - * is thrown - */ - virtual T* read(ifstream& file, const string& path, T* former) const = 0; - - virtual ~FileReader() { - cleanupExtensions(); - }; //Well ... these objects aren't supposed to be destroyed -}; - -template -static inline T* readFromFileReaders(vector const *>* readers, const string& filepath) { - //try to assign file -#if defined(WIN32) && !defined(__MINGW32__) - FILE *fp = _wfopen(utf8_decode(filepath).c_str(), L"rb"); - ifstream file(fp); -#else - ifstream file(filepath.c_str(), ios::in | ios::binary); -#endif - if (!file.is_open()) { - throw megaglest_runtime_error("[#1] Could not open file " + filepath); - } - for (typename vector const *>::const_iterator i = readers->begin(); i != readers->end(); ++i) { - T* ret = NULL; - file.seekg(0, ios::beg); //Set position to first + template + bool FileReader::canRead(ifstream& file) const { try { - FileReader const * reader = *i; - ret = reader->read(file, filepath); //It is guaranteed that at least the filepath matches ... + T* wouldRead = read(file, "unknown file"); + bool ret = (wouldRead != NULL); + delete wouldRead; + return ret; } #if defined(WIN32) catch (megaglest_runtime_error) { @@ -164,242 +341,62 @@ static inline T* readFromFileReaders(vector const *>* readers, con catch (megaglest_runtime_error &ex) { #endif throw; + } catch (...) { + return false; } - catch (...) { - continue; } - if (ret != NULL) { - file.close(); -#if defined(WIN32) && !defined(__MINGW32__) - if(fp) fclose(fp); -#endif - return ret; - } - } - file.close(); -#if defined(WIN32) && !defined(__MINGW32__) - if(fp) fclose(fp); -#endif - return NULL; -} - -template -static inline T* readFromFileReaders(vector const *>* readers, const string& filepath, T* object) { - //try to assign file + /**Reads a file + * This method tries to read the file with the specified filepath + * If it fails, either null is returned or an exception + * is thrown + */ + template + T* FileReader::read(const string& filepath) const { #if defined(WIN32) && !defined(__MINGW32__) - wstring wstr = utf8_decode(filepath); - FILE *fp = _wfopen(wstr.c_str(), L"rb"); - int fileErrno = errno; - ifstream file(fp); + FILE *fp = _wfopen(utf8_decode(filepath).c_str(), L"rb"); + ifstream file(fp); #else - ifstream file(filepath.c_str(), ios::in | ios::binary); + ifstream file(filepath.c_str(), ios::in | ios::binary); #endif - if (!file.is_open()) { + if (!file.is_open()) { + throw megaglest_runtime_error("[#3] Could not open file " + filepath); + } + T* ret = read(file, filepath); + file.close(); #if defined(WIN32) && !defined(__MINGW32__) - DWORD error = GetLastError(); - throw megaglest_runtime_error("[#2] Could not open file, result: " + intToStr(error) + " - " + intToStr(fileErrno) + " [" + filepath + "]"); -#else - throw megaglest_runtime_error("[#2] Could not open file [" + filepath + "]"); + if (fp) fclose(fp); #endif - } - for (typename vector const *>::const_iterator i = readers->begin(); i != readers->end(); ++i) { - T* ret = NULL; - file.seekg(0, ios::beg); //Set position to first - try { - FileReader const * reader = *i; - ret = reader->read(file, filepath, object); //It is guaranteed that at least the filepath matches ... - } -#if defined(WIN32) - catch (megaglest_runtime_error) { -#else - catch (megaglest_runtime_error &ex) { -#endif - throw; - } - catch (...) { - continue; - } - if (ret != NULL) { - file.close(); -#if defined(WIN32) && !defined(__MINGW32__) - if(fp) fclose(fp); -#endif - return ret; - } - } - file.close(); -#if defined(WIN32) && !defined(__MINGW32__) - if(fp) fclose(fp); -#endif - return NULL; -} -/**Tries to read a file - * This method tries to read the file with the specified filepath. - * If it fails, either null is returned or an exception - * is thrown*/ -template -T* FileReader::readPath(const string& filepath) { - const string& extension = extractExtension(filepath); - vector const * >* possibleReaders = (getFileReadersMap())[extension]; - if (possibleReaders != NULL) { - //Search in these possible readers - T* ret = readFromFileReaders(possibleReaders, filepath); - if (ret != NULL) { - return ret; - } - } - T* ret = readFromFileReaders(&(getFileReaders()), filepath); //Try all other - if (ret == NULL) { - std::cerr << "ERROR #1 - Could not parse filepath: " << filepath << std::endl; - throw megaglest_runtime_error(string("Could not parse ") + filepath + " as object of type " + typeid(T).name()); - } - return ret; -} - -/**Tries to read a file - * This method tries to read the file with the specified filepath. - * If it fails, either null is returned or an exception - * is thrown*/ -template -T* FileReader::readPath(const string& filepath, T* object) { - const string& extension = extractExtension(filepath); - vector const * >* possibleReaders = (getFileReadersMap())[extension]; - if (possibleReaders != NULL) { - //Search in these possible readers - T* ret = readFromFileReaders(possibleReaders, filepath, object); - if (ret != NULL) { - return ret; - } - } - T* ret = readFromFileReaders(&(getFileReaders()), filepath, object); //Try all other - if (ret == NULL) { - std::cerr << "ERROR #2 - Could not parse filepath: " << filepath << std::endl; - ret = readFromFileReaders(&(getLowPriorityFileReaders()), filepath); //Try to get dummy file - if (ret == NULL) { - throw megaglest_runtime_error(string("Could not parse ") + filepath + " as object of type " + typeid(T).name()); - } - } - return ret; -} - -template -FileReader::FileReader(std::vector extensions): extensions(extensions) { - getFileReaders().push_back(this); - std::vector nextExtension = extensions; - for(unsigned int i = 0; i < nextExtension.size(); ++i) { - vector const* >* curPossibleReaders = (getFileReadersMap())[nextExtension[i]]; - if (curPossibleReaders == NULL) { - (getFileReadersMap())[nextExtension[i]] = (curPossibleReaders = new vector const *>()); - } - curPossibleReaders->push_back(this); - } -} - -template -void FileReader::cleanupExtensions() { - std::vector nextExtension = extensions; - for(unsigned int i = 0; i < nextExtension.size(); ++i) { - vector const* >* curPossibleReaders = (getFileReadersMap())[nextExtension[i]]; - if (curPossibleReaders != NULL) { - delete curPossibleReaders; - (getFileReadersMap())[nextExtension[i]] = NULL; - } - } -} - -/**Gives a quick estimation of whether the specified file - * can be read or not depending on the filename*/ -template -bool FileReader::canRead(const string& filepath) const { - const string& realExtension = extractExtension(filepath); - //const string* haveExtension = extensions; - std::vector haveExtension = extensions; - //while (*haveExtension != "") { - for(unsigned int i = 0; i < haveExtension.size(); ++i) { - //if (realExtension == *haveExtension) { - if (realExtension == haveExtension[i]) { - return true; - } - //++haveExtension; - } - return false; -} - -/**Gives a better estimation of whether the specified file - * can be read or not depending on the file content*/ -template -bool FileReader::canRead(ifstream& file) const { - try { - T* wouldRead = read(file,"unknown file"); - bool ret = (wouldRead != NULL); - delete wouldRead; return ret; } -#if defined(WIN32) - catch (megaglest_runtime_error) { + + /**Reads a file + * This method tries to read the file with the specified filepath + * If it fails, either null is returned or an exception + * is thrown + */ + template + T* FileReader::read(const string& filepath, T* object) const { +#if defined(WIN32) && !defined(__MINGW32__) + FILE *fp = _wfopen(utf8_decode(filepath).c_str(), L"rb"); + ifstream file(fp); #else - catch (megaglest_runtime_error &ex) { + ifstream file(filepath.c_str(), ios::in | ios::binary); #endif - throw; - } - catch (...) { - return false; - } -} - -/**Reads a file - * This method tries to read the file with the specified filepath - * If it fails, either null is returned or an exception - * is thrown - */ -template -T* FileReader::read(const string& filepath) const { + if (!file.is_open()) { + throw megaglest_runtime_error("[#4] Could not open file " + filepath); + } + T* ret = read(file, filepath, object); + file.close(); #if defined(WIN32) && !defined(__MINGW32__) - FILE *fp = _wfopen(utf8_decode(filepath).c_str(), L"rb"); - ifstream file(fp); -#else - ifstream file(filepath.c_str(), ios::in | ios::binary); + if (fp) fclose(fp); #endif - if (!file.is_open()) { - throw megaglest_runtime_error("[#3] Could not open file " + filepath); + + return ret; } - T* ret = read(file,filepath); - file.close(); -#if defined(WIN32) && !defined(__MINGW32__) - if(fp) fclose(fp); -#endif - - return ret; -} - -/**Reads a file - * This method tries to read the file with the specified filepath - * If it fails, either null is returned or an exception - * is thrown - */ -template -T* FileReader::read(const string& filepath, T* object) const { -#if defined(WIN32) && !defined(__MINGW32__) - FILE *fp = _wfopen(utf8_decode(filepath).c_str(), L"rb"); - ifstream file(fp); -#else - ifstream file(filepath.c_str(), ios::in | ios::binary); -#endif - if (!file.is_open()) { - throw megaglest_runtime_error("[#4] Could not open file " + filepath); - } - T* ret = read(file,filepath,object); - file.close(); -#if defined(WIN32) && !defined(__MINGW32__) - if(fp) fclose(fp); -#endif - - return ret; -} -} //end namespace + } //end namespace #endif diff --git a/source/shared_lib/include/graphics/ImageReaders.h b/source/shared_lib/include/graphics/ImageReaders.h index 60a843058..d07316320 100644 --- a/source/shared_lib/include/graphics/ImageReaders.h +++ b/source/shared_lib/include/graphics/ImageReaders.h @@ -20,25 +20,27 @@ #include "leak_dumper.h" //Initialize some objects -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// namespace ImageRegisterer -// ===================================================== + // ===================================================== + // namespace ImageRegisterer + // ===================================================== -namespace ImageRegisterer { + namespace ImageRegisterer { - //This function registers all image-readers, but only once (any further call is unnecessary) - bool registerImageReaders(); + //This function registers all image-readers, but only once (any further call is unnecessary) + bool registerImageReaders(); - //Since you can't call void methods here, I have used a method doing nothing except initializing the image Readers + //Since you can't call void methods here, I have used a method doing nothing except initializing the image Readers #ifdef WIN32 - static bool readersRegistered = registerImageReaders(); //should always return true, this should guarantee that the readers are registered <--> ImageReaders is included anywhere + static bool readersRegistered = registerImageReaders(); //should always return true, this should guarantee that the readers are registered <--> ImageReaders is included anywhere #else - static bool readersRegistered __attribute__((unused)) = registerImageReaders(); //should always return true, this should guarantee that the readers are registered <--> ImageReaders is included anywhere + static bool readersRegistered __attribute__((unused)) = registerImageReaders(); //should always return true, this should guarantee that the readers are registered <--> ImageReaders is included anywhere #endif -} + } -}} //end namespace + } +} //end namespace #endif diff --git a/source/shared_lib/include/graphics/JPGReader.h b/source/shared_lib/include/graphics/JPGReader.h index 1e74cbde6..7fcc16198 100644 --- a/source/shared_lib/include/graphics/JPGReader.h +++ b/source/shared_lib/include/graphics/JPGReader.h @@ -20,16 +20,18 @@ #include "pixmap.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -class JPGReader: FileReader { -public: - JPGReader(); + class JPGReader : FileReader { + public: + JPGReader(); - Pixmap2D* read(ifstream& in, const string& path, Pixmap2D* ret) const; -}; + Pixmap2D* read(ifstream& in, const string& path, Pixmap2D* ret) const; + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/shared_lib/include/graphics/PNGReader.h b/source/shared_lib/include/graphics/PNGReader.h index c3987d3bf..1c66fcb5f 100644 --- a/source/shared_lib/include/graphics/PNGReader.h +++ b/source/shared_lib/include/graphics/PNGReader.h @@ -20,23 +20,25 @@ #include "pixmap.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -class PNGReader: FileReader { -public: - PNGReader(); + class PNGReader : FileReader { + public: + PNGReader(); - Pixmap2D* read(ifstream& in, const string& path, Pixmap2D* ret) const; -}; + Pixmap2D* read(ifstream& in, const string& path, Pixmap2D* ret) const; + }; -class PNGReader3D: FileReader { -public: - PNGReader3D(); + class PNGReader3D : FileReader { + public: + PNGReader3D(); - Pixmap3D* read(ifstream& in, const string& path, Pixmap3D* ret) const; -}; + Pixmap3D* read(ifstream& in, const string& path, Pixmap3D* ret) const; + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/shared_lib/include/graphics/TGAReader.h b/source/shared_lib/include/graphics/TGAReader.h index c45bbd12c..c02fe6de8 100644 --- a/source/shared_lib/include/graphics/TGAReader.h +++ b/source/shared_lib/include/graphics/TGAReader.h @@ -20,22 +20,24 @@ #include "pixmap.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -class TGAReader: FileReader { -public: - TGAReader(); + class TGAReader : FileReader { + public: + TGAReader(); - Pixmap2D* read(ifstream& in, const string& path, Pixmap2D* ret) const; -}; + Pixmap2D* read(ifstream& in, const string& path, Pixmap2D* ret) const; + }; -class TGAReader3D: FileReader { -public: - TGAReader3D(); + class TGAReader3D : FileReader { + public: + TGAReader3D(); - Pixmap3D* read(ifstream& in, const string& path, Pixmap3D* ret) const; -}; + Pixmap3D* read(ifstream& in, const string& path, Pixmap3D* ret) const; + }; -}} //end namespace + } +} //end namespace #endif diff --git a/source/shared_lib/include/graphics/buffer.h b/source/shared_lib/include/graphics/buffer.h index ee8407858..341a6e74e 100644 --- a/source/shared_lib/include/graphics/buffer.h +++ b/source/shared_lib/include/graphics/buffer.h @@ -13,57 +13,61 @@ using std::string; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class VertexBuffer -// ===================================================== + // ===================================================== + // class VertexBuffer + // ===================================================== -class VertexBuffer{ -private: - static const int texCoordCount = 8; - static const int attribCount = 8; + class VertexBuffer { + private: + static const int texCoordCount = 8; + static const int attribCount = 8; -private: - void *positionPointer; - void *normalPointer; + private: + void *positionPointer; + void *normalPointer; - void *texCoordPointers[texCoordCount]; - int texCoordCoordCounts[texCoordCount]; + void *texCoordPointers[texCoordCount]; + int texCoordCoordCounts[texCoordCount]; - void *attribPointers[attribCount]; - int attribCoordCounts[attribCount]; - string attribNames[attribCount]; + void *attribPointers[attribCount]; + int attribCoordCounts[attribCount]; + string attribNames[attribCount]; -public: - VertexBuffer(); - virtual ~VertexBuffer(){}; + public: + VertexBuffer(); + virtual ~VertexBuffer() { + }; - virtual void init(int size)= 0; + virtual void init(int size) = 0; - void setPositionPointer(void *pointer); - void setNormalPointer(void *pointer); - void setTexCoordPointer(void *pointer, int texCoordIndex, int coordCount); - void setAttribPointer(void *pointer, int attribIndex, int coordCount, const string &name); -}; + void setPositionPointer(void *pointer); + void setNormalPointer(void *pointer); + void setTexCoordPointer(void *pointer, int texCoordIndex, int coordCount); + void setAttribPointer(void *pointer, int attribIndex, int coordCount, const string &name); + }; -// ===================================================== -// class IndexBuffer -// ===================================================== + // ===================================================== + // class IndexBuffer + // ===================================================== -class IndexBuffer{ -private: - void *indexPointer; + class IndexBuffer { + private: + void *indexPointer; -public: - IndexBuffer(); - virtual ~IndexBuffer(){} + public: + IndexBuffer(); + virtual ~IndexBuffer() { + } - virtual void init(int size)= 0; + virtual void init(int size) = 0; - void setIndexPointer(void *pointer); -}; + void setIndexPointer(void *pointer); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/camera.h b/source/shared_lib/include/graphics/camera.h index a0483100c..7b7cd46fb 100644 --- a/source/shared_lib/include/graphics/camera.h +++ b/source/shared_lib/include/graphics/camera.h @@ -16,37 +16,51 @@ #include "quaternion.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class Camera -// ===================================================== + // ===================================================== + // class Camera + // ===================================================== -class Camera{ -private: - Quaternion orientation; - Vec3f position; -public: - Camera(); + class Camera { + private: + Quaternion orientation; + Vec3f position; + public: + Camera(); - Vec3f getPosition() const {return position;} - Quaternion getOrientation() const {return orientation;} + Vec3f getPosition() const { + return position; + } + Quaternion getOrientation() const { + return orientation; + } - const Vec3f & getConstPosition() const {return position;} - const Quaternion & getConstOrientation() const {return orientation;} + const Vec3f & getConstPosition() const { + return position; + } + const Quaternion & getConstOrientation() const { + return orientation; + } - void setPosition(const Vec3f &position) {this->position= position;} - void setOrientation(const Quaternion &orientation) {this->orientation= orientation;} + void setPosition(const Vec3f &position) { + this->position = position; + } + void setOrientation(const Quaternion &orientation) { + this->orientation = orientation; + } - void moveLocalX(float amount); - void moveLocalY(float amount); - void moveLocalZ(float amount); + void moveLocalX(float amount); + void moveLocalY(float amount); + void moveLocalZ(float amount); - void addYaw(float amount); - void addPitch(float amount); - void addRoll(float amount); -}; + void addYaw(float amount); + void addPitch(float amount); + void addRoll(float amount); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/context.h b/source/shared_lib/include/graphics/context.h index 42764130a..c9206b76f 100644 --- a/source/shared_lib/include/graphics/context.h +++ b/source/shared_lib/include/graphics/context.h @@ -15,50 +15,77 @@ #include "data_types.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -using Platform::uint32; -using Platform::int8; + using Platform::uint32; + using Platform::int8; -// ===================================================== -// class Context -// ===================================================== + // ===================================================== + // class Context + // ===================================================== -class Context{ -protected: - uint32 colorBits; - uint32 depthBits; - uint32 stencilBits; - int8 hardware_acceleration; - int8 fullscreen_anti_aliasing; - float gammaValue; + class Context { + protected: + uint32 colorBits; + uint32 depthBits; + uint32 stencilBits; + int8 hardware_acceleration; + int8 fullscreen_anti_aliasing; + float gammaValue; -public: - Context(); - virtual ~Context(){} + public: + Context(); + virtual ~Context() { + } - uint32 getColorBits() const {return colorBits;} - uint32 getDepthBits() const {return depthBits;} - uint32 getStencilBits() const {return stencilBits;} - int8 getHardware_acceleration() const { return hardware_acceleration; } - int8 getFullscreen_anti_aliasing() const { return fullscreen_anti_aliasing; } - float getGammaValue() const { return gammaValue; } + uint32 getColorBits() const { + return colorBits; + } + uint32 getDepthBits() const { + return depthBits; + } + uint32 getStencilBits() const { + return stencilBits; + } + int8 getHardware_acceleration() const { + return hardware_acceleration; + } + int8 getFullscreen_anti_aliasing() const { + return fullscreen_anti_aliasing; + } + float getGammaValue() const { + return gammaValue; + } - void setColorBits(uint32 colorBits) {this->colorBits= colorBits;} - void setDepthBits(uint32 depthBits) {this->depthBits= depthBits;} - void setStencilBits(uint32 stencilBits) {this->stencilBits= stencilBits;} - void setHardware_acceleration(int8 value) { hardware_acceleration = value; } - void setFullscreen_anti_aliasing(int8 value) { fullscreen_anti_aliasing = value; } - void setGammaValue(float value) { gammaValue = value; } + void setColorBits(uint32 colorBits) { + this->colorBits = colorBits; + } + void setDepthBits(uint32 depthBits) { + this->depthBits = depthBits; + } + void setStencilBits(uint32 stencilBits) { + this->stencilBits = stencilBits; + } + void setHardware_acceleration(int8 value) { + hardware_acceleration = value; + } + void setFullscreen_anti_aliasing(int8 value) { + fullscreen_anti_aliasing = value; + } + void setGammaValue(float value) { + gammaValue = value; + } - virtual void init()= 0; - virtual void end()= 0; - virtual void reset()= 0; + virtual void init() = 0; + virtual void end() = 0; + virtual void reset() = 0; - virtual void makeCurrent()= 0; - virtual void swapBuffers()= 0; -}; + virtual void makeCurrent() = 0; + virtual void swapBuffers() = 0; + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/font.h b/source/shared_lib/include/graphics/font.h index c76a9896f..f60215227 100644 --- a/source/shared_lib/include/graphics/font.h +++ b/source/shared_lib/include/graphics/font.h @@ -21,142 +21,163 @@ using std::string; //class Text; -namespace Shared { namespace Graphics { +namespace Shared { + namespace Graphics { -// ===================================================== -// class FontMetrics -// ===================================================== + // ===================================================== + // class FontMetrics + // ===================================================== -class FontMetrics { + class FontMetrics { -private: - float *widths; - float height; + private: + float *widths; + float height; - //float yOffsetFactor; - Text *textHandler; + //float yOffsetFactor; + Text *textHandler; -public: - //static float DEFAULT_Y_OFFSET_FACTOR; + public: + //static float DEFAULT_Y_OFFSET_FACTOR; - FontMetrics(Text *textHandler=NULL); - ~FontMetrics(); + FontMetrics(Text *textHandler = NULL); + ~FontMetrics(); - //void setYOffsetFactor(float yOffsetFactor); - //float getYOffsetFactor() const; + //void setYOffsetFactor(float yOffsetFactor); + //float getYOffsetFactor() const; - void setTextHandler(Text *textHandler); - Text * getTextHandler(); + void setTextHandler(Text *textHandler); + Text * getTextHandler(); - void setWidth(int i, float width) {this->widths[i] = width;} - void setHeight(float height) {this->height= height;} + void setWidth(int i, float width) { + this->widths[i] = width; + } + void setHeight(float height) { + this->height = height; + } - float getTextWidth(const string &str); - float getHeight(const string &str) const; + float getTextWidth(const string &str); + float getHeight(const string &str) const; - string wordWrapText(string text, int maxWidth); + string wordWrapText(string text, int maxWidth); -}; + }; -// ===================================================== -// class Font -// ===================================================== + // ===================================================== + // class Font + // ===================================================== -class Font { -public: - static int charCount; - static std::string fontTypeName; - static bool fontIsMultibyte; - static bool forceLegacyFonts; - static bool fontIsRightToLeft; - static bool fontSupportMixedRightToLeft; - static float scaleFontValue; - static float scaleFontValueCenterHFactor; - static int baseSize; - static int faceResolution; - static string langHeightText; - -public: - enum Width { - wNormal= 400, - wBold= 700 - }; + class Font { + public: + static int charCount; + static std::string fontTypeName; + static bool fontIsMultibyte; + static bool forceLegacyFonts; + static bool fontIsRightToLeft; + static bool fontSupportMixedRightToLeft; + static float scaleFontValue; + static float scaleFontValueCenterHFactor; + static int baseSize; + static int faceResolution; + static string langHeightText; -protected: - string type; - int width; - bool inited; - int size; - FontMetrics metrics; - - Text *textHandler; - string fontUniqueId; + public: + enum Width { + wNormal = 400, + wBold = 700 + }; -public: - //constructor & destructor - Font(FontTextHandlerType type); - virtual ~Font(); - virtual void init()=0; - virtual void end()=0; + protected: + string type; + int width; + bool inited; + int size; + FontMetrics metrics; - void setFontUniqueId(string id) { fontUniqueId = id; } - string getFontUniqueId() { return fontUniqueId; } - - //get - int getWidth() const; - FontMetrics *getMetrics() {return &metrics;} - Text * getTextHandler() {return textHandler;} - string getType() const; + Text *textHandler; + string fontUniqueId; - //set - void setType(string typeX11, string typeGeneric, string typeGenericFamily); - void setWidth(int width); + public: + //constructor & destructor + Font(FontTextHandlerType type); + virtual ~Font(); + virtual void init() = 0; + virtual void end() = 0; - int getSize() const; - void setSize(int size); + void setFontUniqueId(string id) { + fontUniqueId = id; + } + string getFontUniqueId() { + return fontUniqueId; + } - static void bidi_cvt(string &str_); + //get + int getWidth() const; + FontMetrics *getMetrics() { + return &metrics; + } + Text * getTextHandler() { + return textHandler; + } + string getType() const; - static void resetToDefaults(); -}; + //set + void setType(string typeX11, string typeGeneric, string typeGenericFamily); + void setWidth(int width); -// ===================================================== -// class Font2D -// ===================================================== + int getSize() const; + void setSize(int size); -class Font2D: public Font { + static void bidi_cvt(string &str_); -public: - Font2D(FontTextHandlerType type=ftht_2D); - virtual ~Font2D() {}; -}; + static void resetToDefaults(); + }; -// ===================================================== -// class Font3D -// ===================================================== + // ===================================================== + // class Font2D + // ===================================================== -class Font3D: public Font { -protected: - float depth; + class Font2D : public Font { -public: - Font3D(FontTextHandlerType type=ftht_3D); - virtual ~Font3D() {}; - - float getDepth() const {return depth;} - void setDepth(float depth) {this->depth= depth;} -}; + public: + Font2D(FontTextHandlerType type = ftht_2D); + virtual ~Font2D() { + }; + }; -Font3D *ConvertFont2DTo3D(Font2D *font); + // ===================================================== + // class Font3D + // ===================================================== -const char* findFont(const char *firstFontToTry=NULL,const char *firstFontFamilyToTry=NULL); + class Font3D : public Font { + protected: + float depth; -class FontChangedCallbackInterface { -public: - virtual void FontChangedCallback(std::string fontUniqueId, Font *font) = 0; - virtual ~FontChangedCallbackInterface() {}; -}; + public: + Font3D(FontTextHandlerType type = ftht_3D); + virtual ~Font3D() { + }; -}}//end namespace + float getDepth() const { + return depth; + } + void setDepth(float depth) { + this->depth = depth; + } + }; + + Font3D *ConvertFont2DTo3D(Font2D *font); + + const char* findFont(const char *firstFontToTry = NULL, const char *firstFontFamilyToTry = NULL); + + class FontChangedCallbackInterface { + public: + virtual void FontChangedCallback(std::string fontUniqueId, Font *font) = 0; + virtual ~FontChangedCallbackInterface() { + }; + }; + + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/font_manager.h b/source/shared_lib/include/graphics/font_manager.h index 34b957db8..1416b9636 100644 --- a/source/shared_lib/include/graphics/font_manager.h +++ b/source/shared_lib/include/graphics/font_manager.h @@ -18,34 +18,36 @@ using namespace std; -namespace Shared { namespace Graphics { +namespace Shared { + namespace Graphics { -// ===================================================== -// class FontManager -// -/// Creates, Intializes, Finalizes, and Deletes fonts -// ===================================================== + // ===================================================== + // class FontManager + // + /// Creates, Intializes, Finalizes, and Deletes fonts + // ===================================================== -class FontManager { -protected: - typedef vector FontContainer; + class FontManager { + protected: + typedef vector FontContainer; -protected: - FontContainer fonts; + protected: + FontContainer fonts; -public: - FontManager(); - virtual ~FontManager(); + public: + FontManager(); + virtual ~FontManager(); - Font2D *newFont2D(); - Font3D *newFont3D(); + Font2D *newFont2D(); + Font3D *newFont3D(); - void endFont(Font *font,bool mustExistInList=false); + void endFont(Font *font, bool mustExistInList = false); - void init(); - void end(); -}; + void init(); + void end(); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/font_text.h b/source/shared_lib/include/graphics/font_text.h index 8504a9f58..c79cf3607 100644 --- a/source/shared_lib/include/graphics/font_text.h +++ b/source/shared_lib/include/graphics/font_text.h @@ -24,9 +24,8 @@ enum FontTextHandlerType { /** * Base class upon which all text rendering calls are made. */ -//==================================================================== -class Text -{ + //==================================================================== +class Text { protected: FontTextHandlerType type; public: diff --git a/source/shared_lib/include/graphics/gl/base_renderer.h b/source/shared_lib/include/graphics/gl/base_renderer.h index 0367f2f1c..a67372070 100644 --- a/source/shared_lib/include/graphics/gl/base_renderer.h +++ b/source/shared_lib/include/graphics/gl/base_renderer.h @@ -15,21 +15,25 @@ #include "graphics_interface.h" #include "leak_dumper.h" -namespace Shared { namespace Graphics { +namespace Shared { + namespace Graphics { -// =============================================== -// class BaseRenderer -// =============================================== + // =============================================== + // class BaseRenderer + // =============================================== -class BaseRenderer : public RendererMapInterface { -public: - BaseRenderer() { } - virtual ~BaseRenderer() { } + class BaseRenderer : public RendererMapInterface { + public: + BaseRenderer() { + } + virtual ~BaseRenderer() { + } - virtual void initMapSurface(int clientW, int clientH); - virtual void renderMap(MapPreview *map, int x, int y, int clientW, int clientH, int cellSize, bool grid=false, bool heightMap=false, bool hideWater=false); -}; + virtual void initMapSurface(int clientW, int clientH); + virtual void renderMap(MapPreview *map, int x, int y, int clientW, int clientH, int cellSize, bool grid = false, bool heightMap = false, bool hideWater = false); + }; -}} // end namespace + } +} // end namespace #endif diff --git a/source/shared_lib/include/graphics/gl/context_gl.h b/source/shared_lib/include/graphics/gl/context_gl.h index a2c888cce..a9fbe6580 100644 --- a/source/shared_lib/include/graphics/gl/context_gl.h +++ b/source/shared_lib/include/graphics/gl/context_gl.h @@ -16,33 +16,42 @@ #include "gl_wrap.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ namespace Gl{ +namespace Shared { + namespace Graphics { + namespace Gl { -using Platform::PlatformContextGl; + using Platform::PlatformContextGl; -// ===================================================== -// class ContextGl -// ===================================================== + // ===================================================== + // class ContextGl + // ===================================================== -class ContextGl: public Context { -protected: - PlatformContextGl pcgl; + class ContextGl : public Context { + protected: + PlatformContextGl pcgl; -public: - ContextGl(); - virtual ~ContextGl(); + public: + ContextGl(); + virtual ~ContextGl(); - virtual void init(); - virtual void end(); - virtual void reset(){}; + virtual void init(); + virtual void end(); + virtual void reset() { + }; - virtual void makeCurrent(); - virtual void swapBuffers(); + virtual void makeCurrent(); + virtual void swapBuffers(); - const PlatformContextGl *getPlatformContextGl() const {return &pcgl;} - PlatformContextGl *getPlatformContextGlPtr() {return &pcgl;} -}; + const PlatformContextGl *getPlatformContextGl() const { + return &pcgl; + } + PlatformContextGl *getPlatformContextGlPtr() { + return &pcgl; + } + }; -}}}//end namespace + } + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/gl/font_gl.h b/source/shared_lib/include/graphics/gl/font_gl.h index 6fa889408..35c357795 100644 --- a/source/shared_lib/include/graphics/gl/font_gl.h +++ b/source/shared_lib/include/graphics/gl/font_gl.h @@ -19,52 +19,62 @@ using namespace std; -namespace Shared { namespace Graphics { namespace Gl { +namespace Shared { + namespace Graphics { + namespace Gl { -// ===================================================== -// class FontGl -// ===================================================== + // ===================================================== + // class FontGl + // ===================================================== -class FontGl { -protected: + class FontGl { + protected: - GLuint handle; - static string default_fonttype; + GLuint handle; + static string default_fonttype; -public: + public: - GLuint getHandle() const {return handle;} + GLuint getHandle() const { + return handle; + } - static string getDefault_fontType() {return default_fonttype;} - static void setDefault_fontType(string value) {default_fonttype = value;} -}; + static string getDefault_fontType() { + return default_fonttype; + } + static void setDefault_fontType(string value) { + default_fonttype = value; + } + }; -// ===================================================== -// class Font2DGl -// -/// OpenGL bitmap font -// ===================================================== + // ===================================================== + // class Font2DGl + // + /// OpenGL bitmap font + // ===================================================== -class Font2DGl: public Font2D, public FontGl { -public: + class Font2DGl : public Font2D, public FontGl { + public: - virtual void init(); - virtual void end(); -}; + virtual void init(); + virtual void end(); + }; -// ===================================================== -// class Font3DGl -// -/// OpenGL outline font -// ===================================================== + // ===================================================== + // class Font3DGl + // + /// OpenGL outline font + // ===================================================== -class Font3DGl: public Font3D, public FontGl { -public: + class Font3DGl : public Font3D, public FontGl { + public: - virtual void init(); - virtual void end(); -}; + virtual void init(); + virtual void end(); + }; -}}}//end namespace + } + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/gl/font_textFTGL.h b/source/shared_lib/include/graphics/gl/font_textFTGL.h index 99a265d16..72266dcfd 100644 --- a/source/shared_lib/include/graphics/gl/font_textFTGL.h +++ b/source/shared_lib/include/graphics/gl/font_textFTGL.h @@ -18,42 +18,45 @@ #include "font_text.h" -namespace Shared { namespace Graphics { namespace Gl { +namespace Shared { + namespace Graphics { + namespace Gl { -/** - * Use FTGL for rendering text in OpenGL - */ -//==================================================================== -class TextFTGL : public Text -{ -public: + /** + * Use FTGL for rendering text in OpenGL + */ + //==================================================================== + class TextFTGL : public Text { + public: - static string langHeightText; - static int faceResolution; + static string langHeightText; + static int faceResolution; - TextFTGL(FontTextHandlerType type); - virtual ~TextFTGL(); - virtual void init(string fontName, string fontFamilyName, int fontSize); + TextFTGL(FontTextHandlerType type); + virtual ~TextFTGL(); + virtual void init(string fontName, string fontFamilyName, int fontSize); - virtual void SetFaceSize(int); - virtual int GetFaceSize(); + virtual void SetFaceSize(int); + virtual int GetFaceSize(); - virtual void Render(const char*, const int = -1); - virtual float Advance(const char*, const int = -1); - virtual float LineHeight(const char*, const int = -1); + virtual void Render(const char*, const int = -1); + virtual float Advance(const char*, const int = -1); + virtual float LineHeight(const char*, const int = -1); - virtual void Render(const wchar_t*, const int = -1); - virtual float Advance(const wchar_t*, const int = -1); - virtual float LineHeight(const wchar_t* = L" ", const int = -1); + virtual void Render(const wchar_t*, const int = -1); + virtual float Advance(const wchar_t*, const int = -1); + virtual float LineHeight(const wchar_t* = L" ", const int = -1); -private: - FTFont *ftFont; - const char* fontFile; + private: + FTFont *ftFont; + const char* fontFile; - void cleanupFont(); -}; + void cleanupFont(); + }; -}}}//end namespace + } + } +}//end namespace #endif // USE_FTGL diff --git a/source/shared_lib/include/graphics/gl/graphics_factory_basic_gl.h b/source/shared_lib/include/graphics/gl/graphics_factory_basic_gl.h index 2cc5320e4..657ab024d 100644 --- a/source/shared_lib/include/graphics/gl/graphics_factory_basic_gl.h +++ b/source/shared_lib/include/graphics/gl/graphics_factory_basic_gl.h @@ -21,24 +21,44 @@ #include "font_gl.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ namespace Gl{ +namespace Shared { + namespace Graphics { + namespace Gl { -// ===================================================== -// class GraphicsFactoryBasicGl -// ===================================================== + // ===================================================== + // class GraphicsFactoryBasicGl + // ===================================================== -class GraphicsFactoryBasicGl: public GraphicsFactory{ -public: - virtual TextRenderer2D *newTextRenderer2D() {return new TextRenderer2DGl();} - virtual TextRenderer3D *newTextRenderer3D() {return new TextRenderer3DGl();} - virtual ModelRenderer *newModelRenderer() {return new ModelRendererGl();} - virtual Context *newContext() {return new ContextGl();} - virtual Model *newModel(const string &path,TextureManager* textureManager,bool deletePixMapAfterLoad,std::map > > *loadedFileList, string *sourceLoader) { return new ModelGl(path,textureManager,deletePixMapAfterLoad,loadedFileList,sourceLoader); } - virtual Texture2D *newTexture2D() {return new Texture2DGl();} - virtual Font2D *newFont2D() {return new Font2DGl();} - virtual Font3D *newFont3D() {return new Font3DGl();} -}; + class GraphicsFactoryBasicGl : public GraphicsFactory { + public: + virtual TextRenderer2D *newTextRenderer2D() { + return new TextRenderer2DGl(); + } + virtual TextRenderer3D *newTextRenderer3D() { + return new TextRenderer3DGl(); + } + virtual ModelRenderer *newModelRenderer() { + return new ModelRendererGl(); + } + virtual Context *newContext() { + return new ContextGl(); + } + virtual Model *newModel(const string &path, TextureManager* textureManager, bool deletePixMapAfterLoad, std::map > > *loadedFileList, string *sourceLoader) { + return new ModelGl(path, textureManager, deletePixMapAfterLoad, loadedFileList, sourceLoader); + } + virtual Texture2D *newTexture2D() { + return new Texture2DGl(); + } + virtual Font2D *newFont2D() { + return new Font2DGl(); + } + virtual Font3D *newFont3D() { + return new Font3DGl(); + } + }; -}}}//end namespace + } + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/gl/graphics_factory_gl.h b/source/shared_lib/include/graphics/gl/graphics_factory_gl.h index 9a3cbba7f..78dcb7585 100644 --- a/source/shared_lib/include/graphics/gl/graphics_factory_gl.h +++ b/source/shared_lib/include/graphics/gl/graphics_factory_gl.h @@ -26,41 +26,77 @@ #include "font_gl.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ namespace Gl{ +namespace Shared { + namespace Graphics { + namespace Gl { -// ===================================================== -// class GraphicsFactoryGl -// ===================================================== + // ===================================================== + // class GraphicsFactoryGl + // ===================================================== -class GraphicsFactoryGl: public GraphicsFactory{ -public: - //context - virtual Context *newContext() {return new ContextGl();} + class GraphicsFactoryGl : public GraphicsFactory { + public: + //context + virtual Context *newContext() { + return new ContextGl(); + } - //textures - virtual TextureManager *newTextureManager() {return new TextureManager();} - virtual Texture1D *newTexture1D() {return new Texture1DGl();} - virtual Texture2D *newTexture2D() {return new Texture2DGl();} - virtual Texture3D *newTexture3D() {return new Texture3DGl();} - virtual TextureCube *newTextureCube() {return new TextureCubeGl();} - - //models - virtual ModelManager *newModelManager() {return new ModelManager();} - virtual ModelRenderer *newModelRenderer() {return new ModelRendererGl();} - virtual Model *newModel(const string &path,TextureManager* textureManager,bool deletePixMapAfterLoad,std::map > > *loadedFileList, string *sourceLoader) { return new ModelGl(path,textureManager,deletePixMapAfterLoad,loadedFileList,sourceLoader); } + //textures + virtual TextureManager *newTextureManager() { + return new TextureManager(); + } + virtual Texture1D *newTexture1D() { + return new Texture1DGl(); + } + virtual Texture2D *newTexture2D() { + return new Texture2DGl(); + } + virtual Texture3D *newTexture3D() { + return new Texture3DGl(); + } + virtual TextureCube *newTextureCube() { + return new TextureCubeGl(); + } - //text - virtual FontManager *newFontManager() {return new FontManager();} - virtual TextRenderer2D *newTextRenderer2D() {return new TextRenderer2DGl();} - virtual TextRenderer3D *newTextRenderer3D() {return new TextRenderer3DGl();} - virtual Font2D *newFont2D() {return new Font2DGl();} - virtual Font3D *newFont3D() {return new Font3DGl();} + //models + virtual ModelManager *newModelManager() { + return new ModelManager(); + } + virtual ModelRenderer *newModelRenderer() { + return new ModelRendererGl(); + } + virtual Model *newModel(const string &path, TextureManager* textureManager, bool deletePixMapAfterLoad, std::map > > *loadedFileList, string *sourceLoader) { + return new ModelGl(path, textureManager, deletePixMapAfterLoad, loadedFileList, sourceLoader); + } - //particles - virtual ParticleManager *newParticleManager() {return new ParticleManager();} - virtual ParticleRenderer *newParticleRenderer() {return new ParticleRendererGl();} -}; + //text + virtual FontManager *newFontManager() { + return new FontManager(); + } + virtual TextRenderer2D *newTextRenderer2D() { + return new TextRenderer2DGl(); + } + virtual TextRenderer3D *newTextRenderer3D() { + return new TextRenderer3DGl(); + } + virtual Font2D *newFont2D() { + return new Font2DGl(); + } + virtual Font3D *newFont3D() { + return new Font3DGl(); + } -}}}//end namespace + //particles + virtual ParticleManager *newParticleManager() { + return new ParticleManager(); + } + virtual ParticleRenderer *newParticleRenderer() { + return new ParticleRendererGl(); + } + }; + + } + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/gl/model_gl.h b/source/shared_lib/include/graphics/gl/model_gl.h index 61534cc36..e04c88f71 100644 --- a/source/shared_lib/include/graphics/gl/model_gl.h +++ b/source/shared_lib/include/graphics/gl/model_gl.h @@ -15,21 +15,27 @@ #include "model.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ namespace Gl{ +namespace Shared { + namespace Graphics { + namespace Gl { -// ===================================================== -// class ModelGl -// ===================================================== + // ===================================================== + // class ModelGl + // ===================================================== -class ModelGl: public Model{ - friend class GraphicsFactoryGl; -protected: - ModelGl(const string &path,TextureManager* textureManager,bool deletePixMapAfterLoad,std::map > > *loadedFileList, string *sourceLoader); -public: - virtual void init(){} - virtual void end(){} -}; + class ModelGl : public Model { + friend class GraphicsFactoryGl; + protected: + ModelGl(const string &path, TextureManager* textureManager, bool deletePixMapAfterLoad, std::map > > *loadedFileList, string *sourceLoader); + public: + virtual void init() { + } + virtual void end() { + } + }; -}}}//end namespace + } + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/gl/model_renderer_gl.h b/source/shared_lib/include/graphics/gl/model_renderer_gl.h index 80c85a4ca..30ce31806 100644 --- a/source/shared_lib/include/graphics/gl/model_renderer_gl.h +++ b/source/shared_lib/include/graphics/gl/model_renderer_gl.h @@ -17,35 +17,43 @@ #include "opengl.h" #include "leak_dumper.h" -namespace Shared { namespace Graphics { namespace Gl { +namespace Shared { + namespace Graphics { + namespace Gl { -// ===================================================== -// class ModelRendererGl -// ===================================================== + // ===================================================== + // class ModelRendererGl + // ===================================================== -class ModelRendererGl: public ModelRenderer { -private: - bool rendering; - bool duplicateTexCoords; - int secondaryTexCoordUnit; - GLuint lastTexture; + class ModelRendererGl : public ModelRenderer { + private: + bool rendering; + bool duplicateTexCoords; + int secondaryTexCoordUnit; + GLuint lastTexture; -public: - ModelRendererGl(); - virtual void begin(bool renderNormals, bool renderTextures, bool renderColors, bool colorPickingMode, MeshCallback *meshCallback); - virtual void end(); - virtual void render(Model *model,int renderMode=rmNormal); - virtual void renderNormalsOnly(Model *model); + public: + ModelRendererGl(); + virtual void begin(bool renderNormals, bool renderTextures, bool renderColors, bool colorPickingMode, MeshCallback *meshCallback); + virtual void end(); + virtual void render(Model *model, int renderMode = rmNormal); + virtual void renderNormalsOnly(Model *model); - void setDuplicateTexCoords(bool duplicateTexCoords) {this->duplicateTexCoords= duplicateTexCoords;} - void setSecondaryTexCoordUnit(int secondaryTexCoordUnit) {this->secondaryTexCoordUnit= secondaryTexCoordUnit;} + void setDuplicateTexCoords(bool duplicateTexCoords) { + this->duplicateTexCoords = duplicateTexCoords; + } + void setSecondaryTexCoordUnit(int secondaryTexCoordUnit) { + this->secondaryTexCoordUnit = secondaryTexCoordUnit; + } -private: - - void renderMesh(Mesh *mesh,int renderMode=rmNormal); - void renderMeshNormals(Mesh *mesh); -}; + private: -}}}//end namespace + void renderMesh(Mesh *mesh, int renderMode = rmNormal); + void renderMeshNormals(Mesh *mesh); + }; + + } + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/gl/opengl.h b/source/shared_lib/include/graphics/gl/opengl.h index 5ae75cb16..ca4239bd4 100644 --- a/source/shared_lib/include/graphics/gl/opengl.h +++ b/source/shared_lib/include/graphics/gl/opengl.h @@ -24,51 +24,53 @@ using std::runtime_error; using std::string; -namespace Shared{ namespace Graphics{ namespace Gl{ +namespace Shared { + namespace Graphics { + namespace Gl { -using Util::intToStr; + using Util::intToStr; -// ===================================================== -// Globals -// ===================================================== + // ===================================================== + // Globals + // ===================================================== -bool getVBOSupported(); -void setVBOSupported(bool value); + bool getVBOSupported(); + void setVBOSupported(bool value); -//void overrideGlExtensionSupport(const char *extensionName,bool value); -bool isGlExtensionSupported(const char *extensionName); -//bool isGlVersionSupported(int major, int minor, int release); -const char *getGlVersion(); -const char *getGlRenderer(); -const char *getGlVendor(); -const char *getGlExtensions(); -const char *getGlPlatformExtensions(); -int getGlMaxLights(); -int getGlMaxTextureSize(); -int getGlMaxTextureUnits(); -int getGlModelviewMatrixStackDepth(); -int getGlProjectionMatrixStackDepth(); -//void checkGlExtension(const char *extensionName); + //void overrideGlExtensionSupport(const char *extensionName,bool value); + bool isGlExtensionSupported(const char *extensionName); + //bool isGlVersionSupported(int major, int minor, int release); + const char *getGlVersion(); + const char *getGlRenderer(); + const char *getGlVendor(); + const char *getGlExtensions(); + const char *getGlPlatformExtensions(); + int getGlMaxLights(); + int getGlMaxTextureSize(); + int getGlMaxTextureUnits(); + int getGlModelviewMatrixStackDepth(); + int getGlProjectionMatrixStackDepth(); + //void checkGlExtension(const char *extensionName); -void inline _assertGl(const char *file, int line, GLenum *forceErrorNumber = NULL) { - GLenum error = (forceErrorNumber != NULL ? *forceErrorNumber : glGetError()); - if(error != GL_NO_ERROR) { + void inline _assertGl(const char *file, int line, GLenum *forceErrorNumber = NULL) { + GLenum error = (forceErrorNumber != NULL ? *forceErrorNumber : glGetError()); + if (error != GL_NO_ERROR) { #ifdef _DEBUG - if(error == GL_INVALID_ENUM) { - return; - } + if (error == GL_INVALID_ENUM) { + return; + } #endif - //if(error != GL_INVALID_ENUM) { - const char *errorString= reinterpret_cast(gluErrorString(error)); - char szBuf[8096]=""; - snprintf(szBuf,8096,"OpenGL error #%d [0x%X] : [%s] at file: [%s], line: %d",error,error,errorString,file,line); - //throw megaglest_runtime_error("OpenGL error #" + intToStr(error) + " : " + string(errorString) + " at file: " + string(file) + ", line " + intToStr(line)); - throw megaglest_runtime_error(szBuf); - //} - } + //if(error != GL_INVALID_ENUM) { + const char *errorString = reinterpret_cast(gluErrorString(error)); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "OpenGL error #%d [0x%X] : [%s] at file: [%s], line: %d", error, error, errorString, file, line); + //throw megaglest_runtime_error("OpenGL error #" + intToStr(error) + " : " + string(errorString) + " at file: " + string(file) + ", line " + intToStr(line)); + throw megaglest_runtime_error(szBuf); + //} + } -} + } #ifdef NDEBUG @@ -79,9 +81,11 @@ void inline _assertGl(const char *file, int line, GLenum *forceErrorNumber = NUL #define assertGl() _assertGl(__FILE__, __LINE__); #define assertGlWithErrorNumber(forceErrorNumber) _assertGl(__FILE__, __LINE__, &forceErrorNumber); - -#endif - -}}}//end namespace + +#endif + + } + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/gl/particle_renderer_gl.h b/source/shared_lib/include/graphics/gl/particle_renderer_gl.h index d49953de1..7168157bb 100644 --- a/source/shared_lib/include/graphics/gl/particle_renderer_gl.h +++ b/source/shared_lib/include/graphics/gl/particle_renderer_gl.h @@ -15,37 +15,41 @@ #include "particle_renderer.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ namespace Gl{ +namespace Shared { + namespace Graphics { + namespace Gl { -// ===================================================== -// class ParticleRendererGl -// ===================================================== + // ===================================================== + // class ParticleRendererGl + // ===================================================== -class ParticleRendererGl: public ParticleRenderer{ -public: - static const int bufferSize = 1024; + class ParticleRendererGl : public ParticleRenderer { + public: + static const int bufferSize = 1024; -private: - bool rendering; - Vec3f vertexBuffer[bufferSize]; - Vec2f texCoordBuffer[bufferSize]; - Vec4f colorBuffer[bufferSize]; + private: + bool rendering; + Vec3f vertexBuffer[bufferSize]; + Vec2f texCoordBuffer[bufferSize]; + Vec4f colorBuffer[bufferSize]; -public: - //particles - ParticleRendererGl(); - virtual void renderManager(ParticleManager *pm, ModelRenderer *mr); - virtual void renderSystem(ParticleSystem *ps); - virtual void renderSystemLine(ParticleSystem *ps); - virtual void renderSystemLineAlpha(ParticleSystem *ps); - virtual void renderModel(GameParticleSystem *ps, ModelRenderer *mr); - -protected: - void renderBufferQuads(int quadCount); - void renderBufferLines(int lineCount); - void setBlendMode(ParticleSystem::BlendMode blendMode); -}; + public: + //particles + ParticleRendererGl(); + virtual void renderManager(ParticleManager *pm, ModelRenderer *mr); + virtual void renderSystem(ParticleSystem *ps); + virtual void renderSystemLine(ParticleSystem *ps); + virtual void renderSystemLineAlpha(ParticleSystem *ps); + virtual void renderModel(GameParticleSystem *ps, ModelRenderer *mr); -}}}//end namespace + protected: + void renderBufferQuads(int quadCount); + void renderBufferLines(int lineCount); + void setBlendMode(ParticleSystem::BlendMode blendMode); + }; + + } + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/gl/shader_gl.h b/source/shared_lib/include/graphics/gl/shader_gl.h index 2971e1259..09fbe8faa 100644 --- a/source/shared_lib/include/graphics/gl/shader_gl.h +++ b/source/shared_lib/include/graphics/gl/shader_gl.h @@ -22,90 +22,100 @@ using std::vector; using std::string; using std::pair; -namespace Shared{ namespace Graphics{ namespace Gl{ +namespace Shared { + namespace Graphics { + namespace Gl { -// ===================================================== -// class ShaderProgramGl -// ===================================================== + // ===================================================== + // class ShaderProgramGl + // ===================================================== -class ShaderProgramGl: public ShaderProgram{ -private: - typedef pair AttributePair; - typedef vector Attributes; + class ShaderProgramGl : public ShaderProgram { + private: + typedef pair AttributePair; + typedef vector Attributes; -private: - Attributes attributes; - GLhandleARB handle; - VertexShader *vertexShader; - FragmentShader *fragmentShader; - bool inited; + private: + Attributes attributes; + GLhandleARB handle; + VertexShader *vertexShader; + FragmentShader *fragmentShader; + bool inited; -public: - ShaderProgramGl(); + public: + ShaderProgramGl(); - GLhandleARB getHandle() const {return handle;} + GLhandleARB getHandle() const { + return handle; + } - virtual void init(); - virtual void end(); + virtual void init(); + virtual void end(); - virtual void attach(VertexShader *vertexShader, FragmentShader *fragmentShader); - virtual bool link(string &messages); - virtual void activate(); - virtual void deactivate(); + virtual void attach(VertexShader *vertexShader, FragmentShader *fragmentShader); + virtual bool link(string &messages); + virtual void activate(); + virtual void deactivate(); - virtual void setUniform(const string &name, int value); - virtual void setUniform(const string &name, float value); - virtual void setUniform(const string &name, const Vec2f &value); - virtual void setUniform(const string &name, const Vec3f &value); - virtual void setUniform(const string &name, const Vec4f &value); - virtual void setUniform(const string &name, const Matrix3f &value); - virtual void setUniform(const string &name, const Matrix4f &value); + virtual void setUniform(const string &name, int value); + virtual void setUniform(const string &name, float value); + virtual void setUniform(const string &name, const Vec2f &value); + virtual void setUniform(const string &name, const Vec3f &value); + virtual void setUniform(const string &name, const Vec4f &value); + virtual void setUniform(const string &name, const Matrix3f &value); + virtual void setUniform(const string &name, const Matrix4f &value); - void bindAttribute(const string &name, int index); + void bindAttribute(const string &name, int index); -private: - GLint getLocation(const string &name); -}; + private: + GLint getLocation(const string &name); + }; -// ===================================================== -// class ShaderGl -// ===================================================== + // ===================================================== + // class ShaderGl + // ===================================================== -class ShaderGl: virtual public Shader{ -protected: - GLhandleARB handle; - ShaderSource source; - bool inited; + class ShaderGl : virtual public Shader { + protected: + GLhandleARB handle; + ShaderSource source; + bool inited; -public: - ShaderGl(); - - const ShaderSource *getSource() const {return &source;} - GLhandleARB getHandle() const {return handle;} + public: + ShaderGl(); - virtual void load(const string &path); - virtual bool compile(string &messages); - virtual void end(); -}; + const ShaderSource *getSource() const { + return &source; + } + GLhandleARB getHandle() const { + return handle; + } -// ===================================================== -// class VertexShaderGl -// ===================================================== + virtual void load(const string &path); + virtual bool compile(string &messages); + virtual void end(); + }; -class VertexShaderGl: public VertexShader, public ShaderGl{ -public: - virtual void init(); -}; + // ===================================================== + // class VertexShaderGl + // ===================================================== -// ===================================================== -// class FragmentShaderGl -// ===================================================== + class VertexShaderGl : public VertexShader, public ShaderGl { + public: + virtual void init(); + }; -class FragmentShaderGl: public FragmentShader, public ShaderGl{ -public: - virtual void init(); -}; + // ===================================================== + // class FragmentShaderGl + // ===================================================== -}}}//end namespace + class FragmentShaderGl : public FragmentShader, public ShaderGl { + public: + virtual void init(); + }; + + } + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/gl/text_renderer_gl.h b/source/shared_lib/include/graphics/gl/text_renderer_gl.h index f17744a71..e8351bda5 100644 --- a/source/shared_lib/include/graphics/gl/text_renderer_gl.h +++ b/source/shared_lib/include/graphics/gl/text_renderer_gl.h @@ -15,100 +15,103 @@ #include "text_renderer.h" #include "leak_dumper.h" -namespace Shared { namespace Graphics { namespace Gl { +namespace Shared { + namespace Graphics { + namespace Gl { -class Font2DGl; -class Font3DGl; -class TextRenderer2DGl; -class TextRenderer3DGl; + class Font2DGl; + class Font3DGl; + class TextRenderer2DGl; + class TextRenderer3DGl; -// ===================================================== -// class TextRenderer2DGl -// ===================================================== + // ===================================================== + // class TextRenderer2DGl + // ===================================================== -class TextRenderer2DGl: public TextRenderer2D { -private: - Font2DGl *font; - bool rendering; + class TextRenderer2DGl : public TextRenderer2D { + private: + Font2DGl *font; + bool rendering; - //Font3DGl *font3D; - //TextRenderer3DGl *tester; + //Font3DGl *font3D; + //TextRenderer3DGl *tester; -public: - TextRenderer2DGl(); - virtual ~TextRenderer2DGl(); + public: + TextRenderer2DGl(); + virtual ~TextRenderer2DGl(); - virtual void begin(Font2D *font); - virtual void render(const string &text, float x, float y, bool centered=false, Vec3f *color=NULL); - virtual void end(); -}; + virtual void begin(Font2D *font); + virtual void render(const string &text, float x, float y, bool centered = false, Vec3f *color = NULL); + virtual void end(); + }; -// ===================================================== -// class TextRenderer3DGl -// ===================================================== + // ===================================================== + // class TextRenderer3DGl + // ===================================================== -class TextRenderer3DGl: public TextRenderer3D { -private: - Font3DGl *font; - bool rendering; - int currentFTGLErrorCount; + class TextRenderer3DGl : public TextRenderer3D { + private: + Font3DGl *font; + bool rendering; + int currentFTGLErrorCount; - void internalRender(const string &text, float x, float y, bool centered, Vec3f *color); - void specialFTGLErrorCheckWorkaround(string text); + void internalRender(const string &text, float x, float y, bool centered, Vec3f *color); + void specialFTGLErrorCheckWorkaround(string text); -public: - TextRenderer3DGl(); - virtual ~TextRenderer3DGl(); + public: + TextRenderer3DGl(); + virtual ~TextRenderer3DGl(); - virtual void begin(Font3D *font); - virtual void render(const string &text, float x, float y, bool centered=false, Vec3f *color=NULL); - virtual void end(); -}; + virtual void begin(Font3D *font); + virtual void render(const string &text, float x, float y, bool centered = false, Vec3f *color = NULL); + virtual void end(); + }; -class TextRendererSafeWrapper { -protected: - TextRenderer *renderer; - Font *font; - bool mustEnd; + class TextRendererSafeWrapper { + protected: + TextRenderer *renderer; + Font *font; + bool mustEnd; -public: + public: - TextRendererSafeWrapper(TextRenderer *renderer,Font *font) { - mustEnd = false; - this->renderer = renderer; - this->font = font; - begin(); - } - ~TextRendererSafeWrapper() { - end(); - } - - void begin() { - if(this->renderer != NULL) { - TextRenderer2DGl *txtrender2d = dynamic_cast(renderer); - if(txtrender2d != NULL) { - txtrender2d->begin(dynamic_cast(this->font)); - mustEnd = true; - } - else { - TextRenderer3DGl *txtrender3d = dynamic_cast(renderer); - if(txtrender3d != NULL) { - mustEnd = true; - txtrender3d->begin(dynamic_cast(this->font)); + TextRendererSafeWrapper(TextRenderer *renderer, Font *font) { + mustEnd = false; + this->renderer = renderer; + this->font = font; + begin(); + } + ~TextRendererSafeWrapper() { + end(); } - } - } - } - void end() { - if(this->renderer != NULL && mustEnd == true) { - this->renderer->end(); - mustEnd = false; - } - } -}; -}}}//end namespace + void begin() { + if (this->renderer != NULL) { + TextRenderer2DGl *txtrender2d = dynamic_cast(renderer); + if (txtrender2d != NULL) { + txtrender2d->begin(dynamic_cast(this->font)); + mustEnd = true; + } else { + TextRenderer3DGl *txtrender3d = dynamic_cast(renderer); + if (txtrender3d != NULL) { + mustEnd = true; + txtrender3d->begin(dynamic_cast(this->font)); + } + } + } + } + void end() { + if (this->renderer != NULL && mustEnd == true) { + this->renderer->end(); + mustEnd = false; + } + } + }; + + } + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/gl/texture_gl.h b/source/shared_lib/include/graphics/gl/texture_gl.h index 5f6386daa..b739620b2 100644 --- a/source/shared_lib/include/graphics/gl/texture_gl.h +++ b/source/shared_lib/include/graphics/gl/texture_gl.h @@ -16,116 +16,146 @@ #include "opengl.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ namespace Gl{ +namespace Shared { + namespace Graphics { + namespace Gl { -// ===================================================== -// class TextureGl -// ===================================================== + // ===================================================== + // class TextureGl + // ===================================================== -class TextureGl { -protected: - GLuint handle; - GLuint renderBufferId; - GLuint frameBufferId; + class TextureGl { + protected: + GLuint handle; + GLuint renderBufferId; + GLuint frameBufferId; - static bool enableATIHacks; + static bool enableATIHacks; - void initRenderBuffer(); - void initFrameBuffer(); - void attachRenderBuffer(); + void initRenderBuffer(); + void initFrameBuffer(); + void attachRenderBuffer(); -public: - TextureGl(); - virtual ~TextureGl(); + public: + TextureGl(); + virtual ~TextureGl(); - static void setEnableATIHacks(bool value) { enableATIHacks = value; } - static bool getEnableATIHacks() { return enableATIHacks; } + static void setEnableATIHacks(bool value) { + enableATIHacks = value; + } + static bool getEnableATIHacks() { + return enableATIHacks; + } - GLuint getHandle() const {return handle;} - GLuint getRenderBufferHandle() const {return renderBufferId;} - GLuint getFrameBufferHandle() const {return frameBufferId;} + GLuint getHandle() const { + return handle; + } + GLuint getRenderBufferHandle() const { + return renderBufferId; + } + GLuint getFrameBufferHandle() const { + return frameBufferId; + } - bool supports_FBO_RBO(); - void setup_FBO_RBO(); - void attachFrameBufferToTexture(); - void dettachFrameBufferFromTexture(); - void dettachRenderBufferFromTexture(); - bool checkFrameBufferStatus(); - void teardown_FBO_RBO(); + bool supports_FBO_RBO(); + void setup_FBO_RBO(); + void attachFrameBufferToTexture(); + void dettachFrameBufferFromTexture(); + void dettachRenderBufferFromTexture(); + bool checkFrameBufferStatus(); + void teardown_FBO_RBO(); - virtual int getTextureWidth() const = 0; - virtual int getTextureHeight() const = 0; + virtual int getTextureWidth() const = 0; + virtual int getTextureHeight() const = 0; - void OutputTextureDebugInfo(Texture::Format format, int components, const string path,std::size_t rawSize,GLenum texType); -}; + void OutputTextureDebugInfo(Texture::Format format, int components, const string path, std::size_t rawSize, GLenum texType); + }; -// ===================================================== -// class Texture1DGl -// ===================================================== + // ===================================================== + // class Texture1DGl + // ===================================================== -class Texture1DGl: public Texture1D, public TextureGl { -public: - Texture1DGl(); - virtual ~Texture1DGl(); + class Texture1DGl : public Texture1D, public TextureGl { + public: + Texture1DGl(); + virtual ~Texture1DGl(); - virtual void init(Filter filter, int maxAnisotropy= 1); - virtual void end(bool deletePixelBuffer=true); + virtual void init(Filter filter, int maxAnisotropy = 1); + virtual void end(bool deletePixelBuffer = true); - virtual int getTextureWidth() const { return Texture1D::getTextureWidth();} - virtual int getTextureHeight() const { return Texture1D::getTextureHeight();} -}; + virtual int getTextureWidth() const { + return Texture1D::getTextureWidth(); + } + virtual int getTextureHeight() const { + return Texture1D::getTextureHeight(); + } + }; -// ===================================================== -// class Texture2DGl -// ===================================================== + // ===================================================== + // class Texture2DGl + // ===================================================== -class Texture2DGl: public Texture2D, public TextureGl{ -public: - Texture2DGl(); - virtual ~Texture2DGl(); + class Texture2DGl : public Texture2D, public TextureGl { + public: + Texture2DGl(); + virtual ~Texture2DGl(); - virtual void init(Filter filter, int maxAnisotropy= 1); - virtual void end(bool deletePixelBuffer=true); + virtual void init(Filter filter, int maxAnisotropy = 1); + virtual void end(bool deletePixelBuffer = true); - virtual int getTextureWidth() const { return Texture2D::getTextureWidth();} - virtual int getTextureHeight() const { return Texture2D::getTextureHeight();} -}; + virtual int getTextureWidth() const { + return Texture2D::getTextureWidth(); + } + virtual int getTextureHeight() const { + return Texture2D::getTextureHeight(); + } + }; -// ===================================================== -// class Texture3DGl -// ===================================================== + // ===================================================== + // class Texture3DGl + // ===================================================== -class Texture3DGl: public Texture3D, public TextureGl{ -public: + class Texture3DGl : public Texture3D, public TextureGl { + public: - Texture3DGl(); - virtual ~Texture3DGl(); + Texture3DGl(); + virtual ~Texture3DGl(); - virtual void init(Filter filter, int maxAnisotropy= 1); - virtual void end(bool deletePixelBuffer=true); + virtual void init(Filter filter, int maxAnisotropy = 1); + virtual void end(bool deletePixelBuffer = true); - virtual int getTextureWidth() const { return Texture3D::getTextureWidth();} - virtual int getTextureHeight() const { return Texture3D::getTextureHeight();} -}; + virtual int getTextureWidth() const { + return Texture3D::getTextureWidth(); + } + virtual int getTextureHeight() const { + return Texture3D::getTextureHeight(); + } + }; -// ===================================================== -// class TextureCubeGl -// ===================================================== + // ===================================================== + // class TextureCubeGl + // ===================================================== -class TextureCubeGl: public TextureCube, public TextureGl{ -public: + class TextureCubeGl : public TextureCube, public TextureGl { + public: - TextureCubeGl(); - virtual ~TextureCubeGl(); + TextureCubeGl(); + virtual ~TextureCubeGl(); - virtual void init(Filter filter, int maxAnisotropy= 1); - virtual void end(bool deletePixelBuffer=true); + virtual void init(Filter filter, int maxAnisotropy = 1); + virtual void end(bool deletePixelBuffer = true); - virtual int getTextureWidth() const { return TextureCube::getTextureWidth();} - virtual int getTextureHeight() const { return TextureCube::getTextureHeight();} + virtual int getTextureWidth() const { + return TextureCube::getTextureWidth(); + } + virtual int getTextureHeight() const { + return TextureCube::getTextureHeight(); + } -}; + }; -}}}//end namespace + } + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/graphics_factory.h b/source/shared_lib/include/graphics/graphics_factory.h index 6716c9e33..655eb0eca 100644 --- a/source/shared_lib/include/graphics/graphics_factory.h +++ b/source/shared_lib/include/graphics/graphics_factory.h @@ -20,75 +20,118 @@ using std::string; #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -class Context; + class Context; -class TextureManager; -class Texture1D; -class Texture2D; -class Texture3D; -class TextureCube; - -class ModelManager; -class ModelRenderer; -class Model; + class TextureManager; + class Texture1D; + class Texture2D; + class Texture3D; + class TextureCube; -class FontManager; -class TextRenderer2D; -class TextRenderer3D; -class Font2D; -class Font3D; + class ModelManager; + class ModelRenderer; + class Model; -class ParticleManager; -class ParticleRenderer; - -class ShaderManager; -class ShaderProgram; -class VertexShader; -class FragmentShader; + class FontManager; + class TextRenderer2D; + class TextRenderer3D; + class Font2D; + class Font3D; -// ===================================================== -// class GraphicsFactory -// ===================================================== + class ParticleManager; + class ParticleRenderer; -class GraphicsFactory{ -public: - virtual ~GraphicsFactory(){} + class ShaderManager; + class ShaderProgram; + class VertexShader; + class FragmentShader; - //context - virtual Context *newContext() {return NULL;} + // ===================================================== + // class GraphicsFactory + // ===================================================== - //textures - virtual TextureManager *newTextureManager() {return NULL;} - virtual Texture1D *newTexture1D() {return NULL;} - virtual Texture2D *newTexture2D() {return NULL;} - virtual Texture3D *newTexture3D() {return NULL;} - virtual TextureCube *newTextureCube() {return NULL;} - - //models - virtual ModelManager *newModelManager() {return NULL;} - virtual ModelRenderer *newModelRenderer() {return NULL;} - virtual Model *newModel(const string &path,TextureManager* textureManager,bool deletePixMapAfterLoad,std::map > > *loadedFileList, string *sourceLoader) {return NULL;} + class GraphicsFactory { + public: + virtual ~GraphicsFactory() { + } - //text - virtual FontManager *newFontManager() {return NULL;} - virtual TextRenderer2D *newTextRenderer2D() {return NULL;} - virtual TextRenderer3D *newTextRenderer3D() {return NULL;} - virtual Font2D *newFont2D() {return NULL;} - virtual Font3D *newFont3D() {return NULL;} + //context + virtual Context *newContext() { + return NULL; + } - //particles - virtual ParticleManager *newParticleManager() {return NULL;} - virtual ParticleRenderer *newParticleRenderer() {return NULL;} - - //shaders - virtual ShaderManager *newShaderManager() {return NULL;} - virtual ShaderProgram *newShaderProgram() {return NULL;} - virtual VertexShader *newVertexShader() {return NULL;} - virtual FragmentShader *newFragmentShader() {return NULL;} -}; + //textures + virtual TextureManager *newTextureManager() { + return NULL; + } + virtual Texture1D *newTexture1D() { + return NULL; + } + virtual Texture2D *newTexture2D() { + return NULL; + } + virtual Texture3D *newTexture3D() { + return NULL; + } + virtual TextureCube *newTextureCube() { + return NULL; + } -}}//end namespace + //models + virtual ModelManager *newModelManager() { + return NULL; + } + virtual ModelRenderer *newModelRenderer() { + return NULL; + } + virtual Model *newModel(const string &path, TextureManager* textureManager, bool deletePixMapAfterLoad, std::map > > *loadedFileList, string *sourceLoader) { + return NULL; + } + + //text + virtual FontManager *newFontManager() { + return NULL; + } + virtual TextRenderer2D *newTextRenderer2D() { + return NULL; + } + virtual TextRenderer3D *newTextRenderer3D() { + return NULL; + } + virtual Font2D *newFont2D() { + return NULL; + } + virtual Font3D *newFont3D() { + return NULL; + } + + //particles + virtual ParticleManager *newParticleManager() { + return NULL; + } + virtual ParticleRenderer *newParticleRenderer() { + return NULL; + } + + //shaders + virtual ShaderManager *newShaderManager() { + return NULL; + } + virtual ShaderProgram *newShaderProgram() { + return NULL; + } + virtual VertexShader *newVertexShader() { + return NULL; + } + virtual FragmentShader *newFragmentShader() { + return NULL; + } + }; + + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/graphics_interface.h b/source/shared_lib/include/graphics/graphics_interface.h index 7423b2749..88517fc35 100644 --- a/source/shared_lib/include/graphics/graphics_interface.h +++ b/source/shared_lib/include/graphics/graphics_interface.h @@ -17,67 +17,75 @@ using namespace Shared::Map; -namespace Shared { namespace Graphics { +namespace Shared { + namespace Graphics { -class GraphicsFactory; -class Context; -class Texture2D; -class Model; + class GraphicsFactory; + class Context; + class Texture2D; + class Model; -enum ResourceScope { - rsGlobal, - rsMenu, - rsGame, + enum ResourceScope { + rsGlobal, + rsMenu, + rsGame, - rsCount -}; + rsCount + }; -class RendererInterface { -public: - virtual Texture2D *newTexture2D(ResourceScope rs) = 0; - virtual Model *newModel(ResourceScope rs,const string &path,bool deletePixMapAfterLoad=false,std::map > > *loadedFileList=NULL, string *sourceLoader=NULL) = 0; + class RendererInterface { + public: + virtual Texture2D *newTexture2D(ResourceScope rs) = 0; + virtual Model *newModel(ResourceScope rs, const string &path, bool deletePixMapAfterLoad = false, std::map > > *loadedFileList = NULL, string *sourceLoader = NULL) = 0; - virtual ~RendererInterface() {} -}; + virtual ~RendererInterface() { + } + }; -class RendererMapInterface { -public: - virtual void initMapSurface(int clientW, int clientH) = 0; - virtual void renderMap(MapPreview *map, int x, int y, int clientW, int clientH, int cellSize, bool grid, bool heightMap, bool hideWater) = 0; + class RendererMapInterface { + public: + virtual void initMapSurface(int clientW, int clientH) = 0; + virtual void renderMap(MapPreview *map, int x, int y, int clientW, int clientH, int cellSize, bool grid, bool heightMap, bool hideWater) = 0; - virtual ~RendererMapInterface() {} -}; + virtual ~RendererMapInterface() { + } + }; -// ===================================================== -// class GraphicsInterface -// -/// Interface for the graphic engine -// ===================================================== + // ===================================================== + // class GraphicsInterface + // + /// Interface for the graphic engine + // ===================================================== -class GraphicsInterface { -private: - GraphicsFactory *graphicsFactory; - Context *currentContext; + class GraphicsInterface { + private: + GraphicsFactory *graphicsFactory; + Context *currentContext; -private: - friend class TextureManager; - friend class FontManager; + private: + friend class TextureManager; + friend class FontManager; -private: - GraphicsInterface(); - GraphicsInterface(GraphicsInterface &); - void operator=(GraphicsInterface &); + private: + GraphicsInterface(); + GraphicsInterface(GraphicsInterface &); + void operator=(GraphicsInterface &); -public: - static GraphicsInterface &getInstance(); + public: + static GraphicsInterface &getInstance(); - void setFactory(GraphicsFactory *graphicsFactory); - void setCurrentContext(Context *context); + void setFactory(GraphicsFactory *graphicsFactory); + void setCurrentContext(Context *context); - Context *getCurrentContext() const {return currentContext;} - GraphicsFactory *getFactory() const {return graphicsFactory;} -}; + Context *getCurrentContext() const { + return currentContext; + } + GraphicsFactory *getFactory() const { + return graphicsFactory; + } + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/interpolation.h b/source/shared_lib/include/graphics/interpolation.h index baeefb2bf..5543dc8c2 100644 --- a/source/shared_lib/include/graphics/interpolation.h +++ b/source/shared_lib/include/graphics/interpolation.h @@ -17,39 +17,47 @@ #include #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class InterpolationData -// ===================================================== + // ===================================================== + // class InterpolationData + // ===================================================== -class InterpolationData{ -private: - const Mesh *mesh; + class InterpolationData { + private: + const Mesh *mesh; - Vec3f *vertices; - Vec3f *normals; + Vec3f *vertices; + Vec3f *normals; - int raw_frame_ofs; + int raw_frame_ofs; - static bool enableInterpolation; - - void update(const Vec3f* src, Vec3f* &dest, float t, bool cycle); + static bool enableInterpolation; -public: - InterpolationData(const Mesh *mesh); - ~InterpolationData(); + void update(const Vec3f* src, Vec3f* &dest, float t, bool cycle); - static void setEnableInterpolation(bool enabled) { enableInterpolation = enabled; } + public: + InterpolationData(const Mesh *mesh); + ~InterpolationData(); - const Vec3f *getVertices() const {return !vertices || !enableInterpolation? mesh->getVertices()+raw_frame_ofs: vertices;} - const Vec3f *getNormals() const {return !normals || !enableInterpolation? mesh->getNormals()+raw_frame_ofs: normals;} - - void update(float t, bool cycle); - void updateVertices(float t, bool cycle); - void updateNormals(float t, bool cycle); -}; + static void setEnableInterpolation(bool enabled) { + enableInterpolation = enabled; + } -}}//end namespace + const Vec3f *getVertices() const { + return !vertices || !enableInterpolation ? mesh->getVertices() + raw_frame_ofs : vertices; + } + const Vec3f *getNormals() const { + return !normals || !enableInterpolation ? mesh->getNormals() + raw_frame_ofs : normals; + } + + void update(float t, bool cycle); + void updateVertices(float t, bool cycle); + void updateNormals(float t, bool cycle); + }; + + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/math_util.h b/source/shared_lib/include/graphics/math_util.h index 18ab3dba9..c02fa32be 100644 --- a/source/shared_lib/include/graphics/math_util.h +++ b/source/shared_lib/include/graphics/math_util.h @@ -20,299 +20,301 @@ using namespace std; using namespace Shared::Platform; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -const float pi= 3.1415926f; -const float sqrt2= 1.41421356f; -const float zero= 1e-6f; -const float infinity= 1e6f; + const float pi = 3.1415926f; + const float sqrt2 = 1.41421356f; + const float zero = 1e-6f; + const float infinity = 1e6f; -// ===================================================== -// class Rect -// ===================================================== + // ===================================================== + // class Rect + // ===================================================== -// 0 +-+ -// | | -// +-+ 1 + // 0 +-+ + // | | + // +-+ 1 -template -class Rect2{ -public: - Vec2 p[2]; -public: - Rect2(){ - }; + template + class Rect2 { + public: + Vec2 p[2]; + public: + Rect2() { + }; - Rect2(const Vec2 &p0, const Vec2 &p1){ - this->p[0]= p0; - this->p[1]= p1; - } - - Rect2(T p0x, T p0y, T p1x, T p1y){ - p[0].x= p0x; - p[0].y= p0y; - p[1].x= p1x; - p[1].y= p1y; - } - - Rect2 operator*(T scalar){ - return Rect2( - p[0]*scalar, - p[1]*scalar); - } - - Rect2 operator/(T scalar){ - return Rect2( - p[0]/scalar, - p[1]/scalar); - } - - bool isInside(const Vec2 &p) const{ - return - p.x>=this->p[0].x && - p.y>=this->p[0].y && - p.xp[1].x && - p.yp[1].y; - } - - void clamp(T minX, T minY,T maxX, T maxY){ - for(int i=0; i<2; ++i){ - if(p[i].x &p0, const Vec2 &p1) { + this->p[0] = p0; + this->p[1] = p1; } - if(p[i].ymaxX){ - p[i].x= maxX; + + Rect2 operator*(T scalar) { + return Rect2( + p[0] * scalar, + p[1] * scalar); } - if(p[i].y>maxY){ - p[i].y= maxY; + + Rect2 operator/(T scalar) { + return Rect2( + p[0] / scalar, + p[1] / scalar); } - } - } - std::string getString() const { - std::ostringstream streamOut; - streamOut << "#1: " << this->p[0].getString(); - streamOut << "#2: " << this->p[1].getString(); - std::string result = streamOut.str(); - streamOut.str(std::string()); - return result; - } + bool isInside(const Vec2 &p) const { + return + p.x >= this->p[0].x && + p.y >= this->p[0].y && + p.x < this->p[1].x && + p.y < this->p[1].y; + } -}; + void clamp(T minX, T minY, T maxX, T maxY) { + for (int i = 0; i < 2; ++i) { + if (p[i].x < minX) { + p[i].x = minX; + } + if (p[i].y < minY) { + p[i].y = minY; + } + if (p[i].x > maxX) { + p[i].x = maxX; + } + if (p[i].y > maxY) { + p[i].y = maxY; + } + } + } -typedef Rect2 Rect2i; -typedef Rect2 Rect2c; -typedef Rect2 Rect2f; -typedef Rect2 Rect2d; + std::string getString() const { + std::ostringstream streamOut; + streamOut << "#1: " << this->p[0].getString(); + streamOut << "#2: " << this->p[1].getString(); + std::string result = streamOut.str(); + streamOut.str(std::string()); + return result; + } -// ===================================================== -// class Quad -// ===================================================== + }; -// 0 +-+ 2 -// | | -// 1 +-+ 3 + typedef Rect2 Rect2i; + typedef Rect2 Rect2c; + typedef Rect2 Rect2f; + typedef Rect2 Rect2d; -template -class Quad2{ -public: - Vec2 p[4]; -public: - Quad2(){ - }; + // ===================================================== + // class Quad + // ===================================================== - Quad2(const Vec2 &p0, const Vec2 &p1, const Vec2 &p2, const Vec2 &p3){ - this->p[0]= p0; - this->p[1]= p1; - this->p[2]= p2; - this->p[3]= p3; - } + // 0 +-+ 2 + // | | + // 1 +-+ 3 - explicit Quad2(const Rect2 &rect){ - this->p[0]= rect.p[0]; - this->p[1]= Vec2(rect.p[0].x, rect.p[1].y); - this->p[2]= rect.p[1]; - this->p[3]= Vec2(rect.p[1].x, rect.p[0].y); - } + template + class Quad2 { + public: + Vec2 p[4]; + public: + Quad2() { + }; - Quad2 operator*(T scalar){ - return Quad2( - p[0]*scalar, - p[1]*scalar, - p[2]*scalar, - p[3]*scalar); - } + Quad2(const Vec2 &p0, const Vec2 &p1, const Vec2 &p2, const Vec2 &p3) { + this->p[0] = p0; + this->p[1] = p1; + this->p[2] = p2; + this->p[3] = p3; + } - Quad2 operator/(T scalar){ - return Quad2( - p[0]/scalar, - p[1]/scalar, - p[2]/scalar, - p[3]/scalar); - } + explicit Quad2(const Rect2 &rect) { + this->p[0] = rect.p[0]; + this->p[1] = Vec2(rect.p[0].x, rect.p[1].y); + this->p[2] = rect.p[1]; + this->p[3] = Vec2(rect.p[1].x, rect.p[0].y); + } - bool operator <(const Quad2 &v) const { - if(p[0] < v.p[0]) { - return true; - } - if(p[1] < v.p[1]) { - return true; - } - if(p[2] < v.p[2]) { - return true; - } - if(p[3] < v.p[3]) { - return true; - } - return false; - } + Quad2 operator*(T scalar) { + return Quad2( + p[0] * scalar, + p[1] * scalar, + p[2] * scalar, + p[3] * scalar); + } - bool operator !=(const Quad2 &v) const { - if(p[0] != v.p[0]) { - return true; - } - if(p[1] != v.p[1]) { - return true; - } - if(p[2] != v.p[2]) { - return true; - } - if(p[3] != v.p[3]) { - return true; - } - return false; - } + Quad2 operator/(T scalar) { + return Quad2( + p[0] / scalar, + p[1] / scalar, + p[2] / scalar, + p[3] / scalar); + } - Rect2 computeBoundingRect() const{ - return Rect2i( + bool operator <(const Quad2 &v) const { + if (p[0] < v.p[0]) { + return true; + } + if (p[1] < v.p[1]) { + return true; + } + if (p[2] < v.p[2]) { + return true; + } + if (p[3] < v.p[3]) { + return true; + } + return false; + } + + bool operator !=(const Quad2 &v) const { + if (p[0] != v.p[0]) { + return true; + } + if (p[1] != v.p[1]) { + return true; + } + if (p[2] != v.p[2]) { + return true; + } + if (p[3] != v.p[3]) { + return true; + } + return false; + } + + Rect2 computeBoundingRect() const { + return Rect2i( #ifdef WIN32 - min(p[0].x, p[1].x), - min(p[0].y, p[2].y), - max(p[2].x, p[3].x), - max(p[1].y, p[3].y)); + min(p[0].x, p[1].x), + min(p[0].y, p[2].y), + max(p[2].x, p[3].x), + max(p[1].y, p[3].y)); #else - std::min(p[0].x, p[1].x), - std::min(p[0].y, p[2].y), - std::max(p[2].x, p[3].x), - std::max(p[1].y, p[3].y)); + std::min(p[0].x, p[1].x), + std::min(p[0].y, p[2].y), + std::max(p[2].x, p[3].x), + std::max(p[1].y, p[3].y)); #endif - } - - bool isInside(const Vec2 &pt) const{ - - if(!computeBoundingRect().isInside(pt)) - return false; - - bool left[4]; - - left[0]= (pt.y - p[0].y)*(p[1].x - p[0].x) - (pt.x - p[0].x)*(p[1].y - p[0].y) < 0; - left[1]= (pt.y - p[1].y)*(p[3].x - p[1].x) - (pt.x - p[1].x)*(p[3].y - p[1].y) < 0; - left[2]= (pt.y - p[3].y)*(p[2].x - p[3].x) - (pt.x - p[3].x)*(p[2].y - p[3].y) < 0; - left[3]= (pt.y - p[2].y)*(p[0].x - p[2].x) - (pt.x - p[2].x)*(p[0].y - p[2].y) < 0; - - return left[0] && left[1] && left[2] && left[3]; - } - - void clamp(T minX, T minY, T maxX, T maxY){ - for(int i=0; i<4; ++i){ - if(p[i].x &pt) const { + + if (!computeBoundingRect().isInside(pt)) + return false; + + bool left[4]; + + left[0] = (pt.y - p[0].y)*(p[1].x - p[0].x) - (pt.x - p[0].x)*(p[1].y - p[0].y) < 0; + left[1] = (pt.y - p[1].y)*(p[3].x - p[1].x) - (pt.x - p[1].x)*(p[3].y - p[1].y) < 0; + left[2] = (pt.y - p[3].y)*(p[2].x - p[3].x) - (pt.x - p[3].x)*(p[2].y - p[3].y) < 0; + left[3] = (pt.y - p[2].y)*(p[0].x - p[2].x) - (pt.x - p[2].x)*(p[0].y - p[2].y) < 0; + + return left[0] && left[1] && left[2] && left[3]; } - if(p[i].x>maxX){ - p[i].x= maxX; + + void clamp(T minX, T minY, T maxX, T maxY) { + for (int i = 0; i < 4; ++i) { + if (p[i].x < minX) { + p[i].x = minX; + } + if (p[i].y < minY) { + p[i].y = minY; + } + if (p[i].x > maxX) { + p[i].x = maxX; + } + if (p[i].y > maxY) { + p[i].y = maxY; + } + } } - if(p[i].y>maxY){ - p[i].y= maxY; + + float area() { + Vec2i v0 = p[3] - p[0]; + Vec2i v1 = p[1] - p[2]; + + return 0.5f * ((v0.x * v1.y) - (v0.y * v1.x)); } + + std::string getString() const { + std::ostringstream streamOut; + streamOut << "#1: " << this->p[0].getString(); + streamOut << "#2: " << this->p[1].getString(); + streamOut << "#3: " << this->p[2].getString(); + streamOut << "#4: " << this->p[3].getString(); + std::string result = streamOut.str(); + streamOut.str(std::string()); + return result; + } + + }; + + typedef Quad2 Quad2i; + typedef Quad2 Quad2c; + typedef Quad2 Quad2f; + typedef Quad2 Quad2d; + + // ===================================================== + // Misc + // ===================================================== + + inline int next2Power(int n) { + int i; + for (i = 1; i < n; i *= 2); + return i; } + + template + inline T degToRad(T deg) { + return (deg * 2 * pi) / 360; + } + + template + inline T radToDeg(T rad) { + return (rad * 360) / (2 * pi); + } + + // ==================================================================================================================== + // ==================================================================================================================== + // Inline implementation + // ==================================================================================================================== + // ==================================================================================================================== + //#if _xs_BigEndian_ + // #define _xs_iexp_ 0 + // #define _xs_iman_ 1 + //#else + // #define _xs_iexp_ 1 //intel is little endian + // #define _xs_iman_ 0 + //#endif //BigEndian_ + // + ////#define finline __forceinline + //#define finline inline + // + //#ifndef _xs_DEFAULT_CONVERSION + //#define _xs_DEFAULT_CONVERSION 0 + //#endif + // + ////typedef long int32; + //typedef double real64; + //const real64 _xs_doublemagic = real64 (6755399441055744.0); //2^52 * 1.5, uses limited precisicion to floor + // + //finline int32 xs_CRoundToInt(real64 val, real64 dmr = _xs_doublemagic) { + //#if _xs_DEFAULT_CONVERSION==0 + // val = val + dmr; + // return ((int32*)&val)[_xs_iman_]; + // //return 0; + //#else + // return int32(floor(val+.5)); + //#endif + //} + + } - - float area() { - Vec2i v0= p[3]-p[0]; - Vec2i v1= p[1]-p[2]; - - return 0.5f * ((v0.x * v1.y) - (v0.y * v1.x)); - } - - std::string getString() const { - std::ostringstream streamOut; - streamOut << "#1: " << this->p[0].getString(); - streamOut << "#2: " << this->p[1].getString(); - streamOut << "#3: " << this->p[2].getString(); - streamOut << "#4: " << this->p[3].getString(); - std::string result = streamOut.str(); - streamOut.str(std::string()); - return result; - } - -}; - -typedef Quad2 Quad2i; -typedef Quad2 Quad2c; -typedef Quad2 Quad2f; -typedef Quad2 Quad2d; - -// ===================================================== -// Misc -// ===================================================== - -inline int next2Power(int n){ - int i; - for (i=1; i -inline T degToRad(T deg){ - return (deg*2*pi)/360; -} - -template -inline T radToDeg(T rad){ - return (rad*360)/(2*pi); -} - -// ==================================================================================================================== -// ==================================================================================================================== -// Inline implementation -// ==================================================================================================================== -// ==================================================================================================================== -//#if _xs_BigEndian_ -// #define _xs_iexp_ 0 -// #define _xs_iman_ 1 -//#else -// #define _xs_iexp_ 1 //intel is little endian -// #define _xs_iman_ 0 -//#endif //BigEndian_ -// -////#define finline __forceinline -//#define finline inline -// -//#ifndef _xs_DEFAULT_CONVERSION -//#define _xs_DEFAULT_CONVERSION 0 -//#endif -// -////typedef long int32; -//typedef double real64; -//const real64 _xs_doublemagic = real64 (6755399441055744.0); //2^52 * 1.5, uses limited precisicion to floor -// -//finline int32 xs_CRoundToInt(real64 val, real64 dmr = _xs_doublemagic) { -//#if _xs_DEFAULT_CONVERSION==0 -// val = val + dmr; -// return ((int32*)&val)[_xs_iman_]; -// //return 0; -//#else -// return int32(floor(val+.5)); -//#endif -//} - - -}}//end namespace +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/matrix.h b/source/shared_lib/include/graphics/matrix.h index c055f80fa..ad94b6dda 100644 --- a/source/shared_lib/include/graphics/matrix.h +++ b/source/shared_lib/include/graphics/matrix.h @@ -15,147 +15,151 @@ #include "vec.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class Matrix3 -// ===================================================== + // ===================================================== + // class Matrix3 + // ===================================================== -template -class Matrix3{ -private: - T data[9]; -public: - Matrix3(){}; + template + class Matrix3 { + private: + T data[9]; + public: + Matrix3() { + }; - Matrix3(T *p){ - for(int i=0; i<9; ++i){ - data[i]= p[i]; - } - } - - T *ptr(){ - return data; - } - - const T *ptr() const{ - return data; - } - - T &operator[](int i){ - return data[i]; - } - - T &operator()(int i, int j){ - return data[i*3+j]; - } - - Vec3 operator * (const Vec3 &v) const{ - Vec3 rv; - - return Vec3f( - data[0]*v.x + data[1]*v.y + data[2]*v.z, - data[3]*v.x + data[4]*v.y + data[5]*v.z, - data[6]*v.x + data[7]*v.y + data[8]*v.z); - } - - Matrix3 operator * (const Matrix3 &m) const{ - Matrix3 rm; - - for(int i=0; i<3; ++i){ - for(int j=0; j<3; ++j){ - T acum= 0.0f; - for(int k=0; k<3; ++k){ - acum+= data[i*3+k]*m[k*3+j]; + Matrix3(T *p) { + for (int i = 0; i < 9; ++i) { + data[i] = p[i]; } - rm[i*3+j]= acum; } - } - return rm; - } - void traspose(){ - for(int i=0; i<3; ++i){ - for(int j=0; j<3; ++j){ - T tmp= data[j*3+i]; - data[j*3+i]= data[i*3+j]; - data[i*3+j]= tmp; + T *ptr() { + return data; } - } - } -}; -typedef Matrix3 Matrix3f; -typedef Matrix3 Matrix3d; + const T *ptr() const { + return data; + } -// ===================================================== -// class Matrix4 -// ===================================================== + T &operator[](int i) { + return data[i]; + } -template -class Matrix4{ -private: - T data[16]; -public: - Matrix4(){}; + T &operator()(int i, int j) { + return data[i * 3 + j]; + } - Matrix4(T *p){ - for(int i=0; i<16; ++i){ - data[i]= p[i]; - } - } + Vec3 operator * (const Vec3 &v) const { + Vec3 rv; - T *ptr(){ - return data; - } + return Vec3f( + data[0] * v.x + data[1] * v.y + data[2] * v.z, + data[3] * v.x + data[4] * v.y + data[5] * v.z, + data[6] * v.x + data[7] * v.y + data[8] * v.z); + } - const T *ptr() const{ - return data; - } + Matrix3 operator * (const Matrix3 &m) const { + Matrix3 rm; - T &operator[](int i){ - return data[i]; - } - - const T &operator[](int i) const{ - return data[i]; - } - - T &operator()(int i, int j){ - return data[i*4+j]; - } - - Vec4 operator * (const Vec4 &v) const{ - Vec4 rv; - - return Vec4f( - data[0]*v.x + data[1]*v.y + data[2]*v.z + data[3]*v.w, - data[4]*v.x + data[5]*v.y + data[6]*v.z + data[7]*v.w, - data[8]*v.x + data[9]*v.y + data[10]*v.z + data[11]*v.w, - data[12]*v.x + data[13]*v.y + data[14]*v.z + data[15]*v.w); - } - - Matrix4 operator * (const Matrix4 &m) const{ - Matrix4 rm; - - for(int i=0; i<4; ++i){ - for(int j=0; j<4; ++j){ - T acum= 0.0f; - for(int k=0; k<4; ++k){ - acum+= data[i*4+k]*m[k*4+j]; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + T acum = 0.0f; + for (int k = 0; k < 3; ++k) { + acum += data[i * 3 + k] * m[k * 3 + j]; + } + rm[i * 3 + j] = acum; + } } - rm[i*4+j]= acum; + return rm; } - } - return rm; + + void traspose() { + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + T tmp = data[j * 3 + i]; + data[j * 3 + i] = data[i * 3 + j]; + data[i * 3 + j] = tmp; + } + } + } + }; + + typedef Matrix3 Matrix3f; + typedef Matrix3 Matrix3d; + + // ===================================================== + // class Matrix4 + // ===================================================== + + template + class Matrix4 { + private: + T data[16]; + public: + Matrix4() { + }; + + Matrix4(T *p) { + for (int i = 0; i < 16; ++i) { + data[i] = p[i]; + } + } + + T *ptr() { + return data; + } + + const T *ptr() const { + return data; + } + + T &operator[](int i) { + return data[i]; + } + + const T &operator[](int i) const { + return data[i]; + } + + T &operator()(int i, int j) { + return data[i * 4 + j]; + } + + Vec4 operator * (const Vec4 &v) const { + Vec4 rv; + + return Vec4f( + data[0] * v.x + data[1] * v.y + data[2] * v.z + data[3] * v.w, + data[4] * v.x + data[5] * v.y + data[6] * v.z + data[7] * v.w, + data[8] * v.x + data[9] * v.y + data[10] * v.z + data[11] * v.w, + data[12] * v.x + data[13] * v.y + data[14] * v.z + data[15] * v.w); + } + + Matrix4 operator * (const Matrix4 &m) const { + Matrix4 rm; + + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + T acum = 0.0f; + for (int k = 0; k < 4; ++k) { + acum += data[i * 4 + k] * m[k * 4 + j]; + } + rm[i * 4 + j] = acum; + } + } + return rm; + } + + }; + + typedef Matrix4 Matrix4f; + typedef Matrix4 Matrix4d; + + } - -}; - -typedef Matrix4 Matrix4f; -typedef Matrix4 Matrix4d; - - -}} //enmd namespace +} //enmd namespace #endif diff --git a/source/shared_lib/include/graphics/model.h b/source/shared_lib/include/graphics/model.h index eee2ff3ac..7093ebaa8 100644 --- a/source/shared_lib/include/graphics/model.h +++ b/source/shared_lib/include/graphics/model.h @@ -28,304 +28,378 @@ using std::string; using std::map; using std::pair; -namespace Shared { namespace Graphics { - -class Model; -class Mesh; -class ShadowVolumeData; -class InterpolationData; -class TextureManager; - -// ===================================================== -// class Mesh -// -// Part of a 3D model -// ===================================================== - -class Mesh { -private: - //mesh data - Texture2D *textures[meshTextureCount]; - bool texturesOwned[meshTextureCount]; - string texturePaths[meshTextureCount]; - - string name; - //vertex data counts - uint32 frameCount; - uint32 vertexCount; - uint32 indexCount; - uint32 texCoordFrameCount; - - //vertex data - Vec3f *vertices; - Vec3f *normals; - Vec2f *texCoords; - Vec3f *tangents; - uint32 *indices; - - //material data - Vec3f diffuseColor; - Vec3f specularColor; - float specularPower; - float opacity; - - //properties - bool twoSided; - bool customColor; - bool noSelect; - bool glow; - - uint32 textureFlags; - - InterpolationData *interpolationData; - TextureManager *textureManager; - - // Vertex Buffer Object Names - bool hasBuiltVBOs; - uint32 m_nVBOVertices; // Vertex VBO Name - uint32 m_nVBOTexCoords; // Texture Coordinate VBO Name - uint32 m_nVBONormals; // Normal VBO Name - uint32 m_nVBOIndexes; // Indexes VBO Name - -public: - //init & end - Mesh(); - ~Mesh(); - void init(); - void end(); - - void copyInto(Mesh *dest, bool ignoreInterpolationData, bool destinationOwnsTextures); - - //maps - const Texture2D *getTexture(int i) const {return textures[i];} - - //counts - uint32 getFrameCount() const {return frameCount;} - uint32 getVertexCount() const {return vertexCount;} - uint32 getIndexCount() const {return indexCount;} - uint32 getTriangleCount() const; - - uint32 getVBOVertices() const { return m_nVBOVertices;} - uint32 getVBOTexCoords() const { return m_nVBOTexCoords;} - uint32 getVBONormals() const { return m_nVBONormals;} - uint32 getVBOIndexes() const { return m_nVBOIndexes;} - bool hasBuiltVBOEntities() const { return hasBuiltVBOs;} - void BuildVBOs(); - void ReleaseVBOs(); - - //data - const Vec3f *getVertices() const {return vertices;} - const Vec3f *getNormals() const {return normals;} - const Vec2f *getTexCoords() const {return texCoords;} - const Vec3f *getTangents() const {return tangents;} - const uint32 *getIndices() const {return indices;} - - void setVertices(Vec3f *data, uint32 count); - void setNormals(Vec3f *data, uint32 count); - void setTexCoords(Vec2f *data, uint32 count); - void setIndices(uint32 *data, uint32 count); - - //material - const Vec3f &getDiffuseColor() const {return diffuseColor;} - const Vec3f &getSpecularColor() const {return specularColor;} - float getSpecularPower() const {return specularPower;} - float getOpacity() const {return opacity;} - - //properties - bool getTwoSided() const {return twoSided;} - bool getCustomTexture() const {return customColor;} - bool getNoSelect() const {return noSelect;} - bool getGlow() const {return glow;} - string getName() const {return name;} - - uint32 getTextureFlags() const { return textureFlags; } - - //external data - const InterpolationData *getInterpolationData() const {return interpolationData;} - - //interpolation - void buildInterpolationData(); - void cleanupInterpolationData(); - - void updateInterpolationData(float t, bool cycle); - void updateInterpolationVertices(float t, bool cycle); - - Texture2D *loadMeshTexture(int meshIndex, int textureIndex, TextureManager *textureManager, string textureFile, - int textureChannelCount, bool &textureOwned, - bool deletePixMapAfterLoad, std::map > > *loadedFileList=NULL, - string sourceLoader="",string modelFile=""); - - //load - void loadV2(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager, - bool deletePixMapAfterLoad,std::map > > *loadedFileList=NULL,string sourceLoader="",string modelFile=""); - void loadV3(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager, - bool deletePixMapAfterLoad,std::map > > *loadedFileList=NULL,string sourceLoader="",string modelFile=""); - void load(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager,bool deletePixMapAfterLoad,std::map > > *loadedFileList=NULL,string sourceLoader="",string modelFile=""); - void save(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager, - string convertTextureToFormat, std::map &textureDeleteList, - bool keepsmallest,string modelFile); - - void deletePixels(); - - void toEndian(); - void fromEndian(); - -private: - string findAlternateTexture(vector conversionList, string textureFile); - void computeTangents(); - -}; - -// ===================================================== -// class Model -// -// 3D Model, than can be loaded from a g3d file -// ===================================================== - -class Model { -private: - TextureManager *textureManager; - -private: - uint8 fileVersion; - uint32 meshCount; - Mesh *meshes; - - float lastTData; - bool lastCycleData; - float lastTVertex; - bool lastCycleVertex; - - string fileName; - string sourceLoader; - - //static bool masterserverMode; - -public: - //constructor & destructor - Model(); - virtual ~Model(); - virtual void init()= 0; - virtual void end()= 0; - - //static void setMasterserverMode(bool value) { masterserverMode=value; } +namespace Shared { + namespace Graphics { + + class Model; + class Mesh; + class ShadowVolumeData; + class InterpolationData; + class TextureManager; + + // ===================================================== + // class Mesh + // + // Part of a 3D model + // ===================================================== + + class Mesh { + private: + //mesh data + Texture2D *textures[meshTextureCount]; + bool texturesOwned[meshTextureCount]; + string texturePaths[meshTextureCount]; + + string name; + //vertex data counts + uint32 frameCount; + uint32 vertexCount; + uint32 indexCount; + uint32 texCoordFrameCount; + + //vertex data + Vec3f *vertices; + Vec3f *normals; + Vec2f *texCoords; + Vec3f *tangents; + uint32 *indices; + + //material data + Vec3f diffuseColor; + Vec3f specularColor; + float specularPower; + float opacity; + + //properties + bool twoSided; + bool customColor; + bool noSelect; + bool glow; + + uint32 textureFlags; + + InterpolationData *interpolationData; + TextureManager *textureManager; + + // Vertex Buffer Object Names + bool hasBuiltVBOs; + uint32 m_nVBOVertices; // Vertex VBO Name + uint32 m_nVBOTexCoords; // Texture Coordinate VBO Name + uint32 m_nVBONormals; // Normal VBO Name + uint32 m_nVBOIndexes; // Indexes VBO Name + + public: + //init & end + Mesh(); + ~Mesh(); + void init(); + void end(); + + void copyInto(Mesh *dest, bool ignoreInterpolationData, bool destinationOwnsTextures); + + //maps + const Texture2D *getTexture(int i) const { + return textures[i]; + } + + //counts + uint32 getFrameCount() const { + return frameCount; + } + uint32 getVertexCount() const { + return vertexCount; + } + uint32 getIndexCount() const { + return indexCount; + } + uint32 getTriangleCount() const; + + uint32 getVBOVertices() const { + return m_nVBOVertices; + } + uint32 getVBOTexCoords() const { + return m_nVBOTexCoords; + } + uint32 getVBONormals() const { + return m_nVBONormals; + } + uint32 getVBOIndexes() const { + return m_nVBOIndexes; + } + bool hasBuiltVBOEntities() const { + return hasBuiltVBOs; + } + void BuildVBOs(); + void ReleaseVBOs(); + + //data + const Vec3f *getVertices() const { + return vertices; + } + const Vec3f *getNormals() const { + return normals; + } + const Vec2f *getTexCoords() const { + return texCoords; + } + const Vec3f *getTangents() const { + return tangents; + } + const uint32 *getIndices() const { + return indices; + } + + void setVertices(Vec3f *data, uint32 count); + void setNormals(Vec3f *data, uint32 count); + void setTexCoords(Vec2f *data, uint32 count); + void setIndices(uint32 *data, uint32 count); + + //material + const Vec3f &getDiffuseColor() const { + return diffuseColor; + } + const Vec3f &getSpecularColor() const { + return specularColor; + } + float getSpecularPower() const { + return specularPower; + } + float getOpacity() const { + return opacity; + } + + //properties + bool getTwoSided() const { + return twoSided; + } + bool getCustomTexture() const { + return customColor; + } + bool getNoSelect() const { + return noSelect; + } + bool getGlow() const { + return glow; + } + string getName() const { + return name; + } + + uint32 getTextureFlags() const { + return textureFlags; + } + + //external data + const InterpolationData *getInterpolationData() const { + return interpolationData; + } + + //interpolation + void buildInterpolationData(); + void cleanupInterpolationData(); + + void updateInterpolationData(float t, bool cycle); + void updateInterpolationVertices(float t, bool cycle); + + Texture2D *loadMeshTexture(int meshIndex, int textureIndex, TextureManager *textureManager, string textureFile, + int textureChannelCount, bool &textureOwned, + bool deletePixMapAfterLoad, std::map > > *loadedFileList = NULL, + string sourceLoader = "", string modelFile = ""); + + //load + void loadV2(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager, + bool deletePixMapAfterLoad, std::map > > *loadedFileList = NULL, string sourceLoader = "", string modelFile = ""); + void loadV3(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager, + bool deletePixMapAfterLoad, std::map > > *loadedFileList = NULL, string sourceLoader = "", string modelFile = ""); + void load(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager, bool deletePixMapAfterLoad, std::map > > *loadedFileList = NULL, string sourceLoader = "", string modelFile = ""); + void save(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager, + string convertTextureToFormat, std::map &textureDeleteList, + bool keepsmallest, string modelFile); + + void deletePixels(); + + void toEndian(); + void fromEndian(); + + private: + string findAlternateTexture(vector conversionList, string textureFile); + void computeTangents(); + + }; + + // ===================================================== + // class Model + // + // 3D Model, than can be loaded from a g3d file + // ===================================================== + + class Model { + private: + TextureManager *textureManager; + + private: + uint8 fileVersion; + uint32 meshCount; + Mesh *meshes; + + float lastTData; + bool lastCycleData; + float lastTVertex; + bool lastCycleVertex; + + string fileName; + string sourceLoader; + + //static bool masterserverMode; + + public: + //constructor & destructor + Model(); + virtual ~Model(); + virtual void init() = 0; + virtual void end() = 0; + + //static void setMasterserverMode(bool value) { masterserverMode=value; } + + //data + void updateInterpolationData(float t, bool cycle); + void updateInterpolationVertices(float t, bool cycle); + void buildShadowVolumeData() const; + + //get + uint8 getFileVersion() const { + return fileVersion; + } + uint32 getMeshCount() const { + return meshCount; + } + const Mesh *getMesh(int i) const { + return &meshes[i]; + } + Mesh *getMeshPtr(int i) const { + return &meshes[i]; + } + + uint32 getTriangleCount() const; + uint32 getVertexCount() const; + + //io + void save(const string &path, string convertTextureToFormat, bool keepsmallest); + void saveG3d(const string &path, string convertTextureToFormat, bool keepsmallest); + + void setTextureManager(TextureManager *textureManager) { + this->textureManager = textureManager; + } + void deletePixels(); + + string getFileName() const { + return fileName; + } + + void toEndian(); + void fromEndian(); + + protected: + void load(const string &path, bool deletePixMapAfterLoad = false, std::map > > *loadedFileList = NULL, string *sourceLoader = NULL); + void loadG3d(const string &path, bool deletePixMapAfterLoad = false, std::map > > *loadedFileList = NULL, string sourceLoader = ""); + + + private: + void buildInterpolationData() const; + void autoJoinMeshFrames(); + }; + + class PixelBufferWrapper { + public: + PixelBufferWrapper(int pboCount, int bufferSize); + ~PixelBufferWrapper(); - //data - void updateInterpolationData(float t, bool cycle); - void updateInterpolationVertices(float t, bool cycle); - void buildShadowVolumeData() const; + Pixmap2D *getPixelBufferFor(int x, int y, int w, int h, int colorComponents); + static void begin(); + static void end(); + static bool getIsPBOEnable() { + return isPBOEnabled; + } - //get - uint8 getFileVersion() const {return fileVersion;} - uint32 getMeshCount() const {return meshCount;} - const Mesh *getMesh(int i) const {return &meshes[i];} - Mesh *getMeshPtr(int i) const {return &meshes[i];} + private: + static bool isPBOEnabled; + static int index; + static vector pboIds; + int bufferSize; - uint32 getTriangleCount() const; - uint32 getVertexCount() const; + void cleanup(); + void addBuffersToPixelBuf(int pboCount); + }; - //io - void save(const string &path, string convertTextureToFormat,bool keepsmallest); - void saveG3d(const string &path, string convertTextureToFormat,bool keepsmallest); + class BaseColorPickEntity { - void setTextureManager(TextureManager *textureManager) {this->textureManager= textureManager;} - void deletePixels(); + public: + BaseColorPickEntity(); + virtual ~BaseColorPickEntity() { + recycleUniqueColor(); + } - string getFileName() const { return fileName; } + //static const int COLOR_COMPONENTS = 3; + static const int COLOR_COMPONENTS = 4; + static void init(int bufferSize); + static void beginPicking(); + static void endPicking(); + static vector getPickedList(int x, int y, int w, int h, const vector &rendererModels); - void toEndian(); - void fromEndian(); + void setUniquePickingColor() const; + bool isUniquePickingColor(unsigned char *pixel) const; -protected: - void load(const string &path,bool deletePixMapAfterLoad=false,std::map > > *loadedFileList=NULL, string *sourceLoader=NULL); - void loadG3d(const string &path,bool deletePixMapAfterLoad=false,std::map > > *loadedFileList=NULL, string sourceLoader=""); + string getColorDescription() const; + virtual string getUniquePickName() const = 0; - -private: - void buildInterpolationData() const; - void autoJoinMeshFrames(); -}; + static void resetUniqueColors(); + + static void setUsingLoopMethod(bool value) { + using_loop_method = value; + } -class PixelBufferWrapper { -public: - PixelBufferWrapper(int pboCount,int bufferSize); - ~PixelBufferWrapper(); + static void setTrackColorUse(bool value) { + trackColorUse = value; + } + unsigned char * getUniqueColorID() { + return &uniqueColorID[0]; + } + bool get_next_assign_color(unsigned char *assign_to); - Pixmap2D *getPixelBufferFor(int x,int y,int w,int h, int colorComponents); - static void begin(); - static void end(); - static bool getIsPBOEnable() { return isPBOEnabled; } + static int getUsedColorIDListSize() { + return (int) usedColorIDList.size(); + } -private: - static bool isPBOEnabled; - static int index; - static vector pboIds; - int bufferSize; + static void cleanupPBO(); - void cleanup(); - void addBuffersToPixelBuf(int pboCount); -}; + private: -class BaseColorPickEntity { + static int bufferSizeRequired; + unsigned char uniqueColorID[COLOR_COMPONENTS]; -public: - BaseColorPickEntity(); - virtual ~BaseColorPickEntity() { - recycleUniqueColor(); - } + static unsigned char nextColorID[COLOR_COMPONENTS]; + static unsigned int nextColorRGB; + static const unsigned int k, p; - //static const int COLOR_COMPONENTS = 3; - static const int COLOR_COMPONENTS = 4; - static void init(int bufferSize); - static void beginPicking(); - static void endPicking(); - static vector getPickedList(int x,int y,int w,int h, const vector &rendererModels); + static bool using_loop_method; - void setUniquePickingColor() const; - bool isUniquePickingColor(unsigned char *pixel) const; + static bool trackColorUse; + static map usedColorIDList; - string getColorDescription() const; - virtual string getUniquePickName() const = 0; + static vector > nextColorIDReuseList; - static void resetUniqueColors(); + static auto_ptr pbo; + //static auto_ptr cachedPixels; - static void setUsingLoopMethod(bool value) { using_loop_method = value; } + void assign_color(); - static void setTrackColorUse(bool value) { trackColorUse = value; } - unsigned char * getUniqueColorID() { return &uniqueColorID[0]; } - bool get_next_assign_color(unsigned char *assign_to); + void assign_color_using_prime(unsigned char *assign_to); + void assign_color_using_loop(unsigned char *assign_to); - static int getUsedColorIDListSize() { return (int)usedColorIDList.size(); } + void recycleUniqueColor(); + }; - static void cleanupPBO(); - -private: - - static int bufferSizeRequired; - unsigned char uniqueColorID[COLOR_COMPONENTS]; - - static unsigned char nextColorID[COLOR_COMPONENTS]; - static unsigned int nextColorRGB; - static const unsigned int k, p; - - static bool using_loop_method; - - static bool trackColorUse; - static map usedColorIDList; - - static vector > nextColorIDReuseList; - - static auto_ptr pbo; - //static auto_ptr cachedPixels; - - void assign_color(); - - void assign_color_using_prime(unsigned char *assign_to); - void assign_color_using_loop(unsigned char *assign_to); - - void recycleUniqueColor(); -}; - -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/model_header.h b/source/shared_lib/include/graphics/model_header.h index efe277a1b..c18323ad3 100644 --- a/source/shared_lib/include/graphics/model_header.h +++ b/source/shared_lib/include/graphics/model_header.h @@ -20,102 +20,104 @@ using Shared::Platform::uint16; using Shared::Platform::uint32; using Shared::Platform::float32; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { #pragma pack(push, 1) -struct FileHeader{ - uint8 id[3]; - uint8 version; -}; + struct FileHeader { + uint8 id[3]; + uint8 version; + }; -//version 4 + //version 4 -struct ModelHeader{ - uint16 meshCount; - uint8 type; -}; + struct ModelHeader { + uint16 meshCount; + uint8 type; + }; -enum ModelType{ - mtMorphMesh -}; + enum ModelType { + mtMorphMesh + }; -enum MeshPropertyFlag{ - mpfCustomColor= 1, - mpfTwoSided= 2, - mpfNoSelect= 4, - mpfGlow= 8 -}; + enum MeshPropertyFlag { + mpfCustomColor = 1, + mpfTwoSided = 2, + mpfNoSelect = 4, + mpfGlow = 8 + }; -enum MeshTexture{ - mtDiffuse, - mtSpecular, - mtNormal, - mtReflection, - mtColorMask, + enum MeshTexture { + mtDiffuse, + mtSpecular, + mtNormal, + mtReflection, + mtColorMask, - meshTextureCount -}; + meshTextureCount + }; -const int meshTextureChannelCount[]= {-1, 1, 3, 1, 1}; + const int meshTextureChannelCount[] = { -1, 1, 3, 1, 1 }; -const uint32 meshNameSize= 64; -const uint32 mapPathSize= 64; + const uint32 meshNameSize = 64; + const uint32 mapPathSize = 64; -struct MeshHeader{ - uint8 name[meshNameSize]; - uint32 frameCount; - uint32 vertexCount; - uint32 indexCount; - float32 diffuseColor[3]; - float32 specularColor[3]; - float32 specularPower; - float32 opacity; - uint32 properties; - uint32 textures; -}; + struct MeshHeader { + uint8 name[meshNameSize]; + uint32 frameCount; + uint32 vertexCount; + uint32 indexCount; + float32 diffuseColor[3]; + float32 specularColor[3]; + float32 specularPower; + float32 opacity; + uint32 properties; + uint32 textures; + }; #pragma pack(pop) -//version 3 + //version 3 -//front faces are clockwise faces -struct ModelHeaderV3{ - uint32 meshCount; -}; + //front faces are clockwise faces + struct ModelHeaderV3 { + uint32 meshCount; + }; -enum MeshPropertyV3{ - mp3NoTexture= 1, - mp3TwoSided= 2, - mp3CustomColor= 4 -}; + enum MeshPropertyV3 { + mp3NoTexture = 1, + mp3TwoSided = 2, + mp3CustomColor = 4 + }; -struct MeshHeaderV3{ - uint32 vertexFrameCount; - uint32 normalFrameCount; - uint32 texCoordFrameCount; - uint32 colorFrameCount; - uint32 pointCount; - uint32 indexCount; - uint32 properties; - uint8 texName[64]; -}; + struct MeshHeaderV3 { + uint32 vertexFrameCount; + uint32 normalFrameCount; + uint32 texCoordFrameCount; + uint32 colorFrameCount; + uint32 pointCount; + uint32 indexCount; + uint32 properties; + uint8 texName[64]; + }; -//version 2 + //version 2 -struct MeshHeaderV2{ - uint32 vertexFrameCount; - uint32 normalFrameCount; - uint32 texCoordFrameCount; - uint32 colorFrameCount; - uint32 pointCount; - uint32 indexCount; - uint8 hasTexture; - uint8 primitive; - uint8 cullFace; - uint8 texName[64]; -}; + struct MeshHeaderV2 { + uint32 vertexFrameCount; + uint32 normalFrameCount; + uint32 texCoordFrameCount; + uint32 colorFrameCount; + uint32 pointCount; + uint32 indexCount; + uint8 hasTexture; + uint8 primitive; + uint8 cullFace; + uint8 texName[64]; + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/model_manager.h b/source/shared_lib/include/graphics/model_manager.h index 0f1198724..29d678af3 100644 --- a/source/shared_lib/include/graphics/model_manager.h +++ b/source/shared_lib/include/graphics/model_manager.h @@ -18,36 +18,40 @@ using namespace std; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -class TextureManager; + class TextureManager; -// ===================================================== -// class ModelManager -// ===================================================== + // ===================================================== + // class ModelManager + // ===================================================== -class ModelManager{ -protected: - typedef vector ModelContainer; + class ModelManager { + protected: + typedef vector ModelContainer; -protected: - ModelContainer models; - TextureManager *textureManager; + protected: + ModelContainer models; + TextureManager *textureManager; -public: - ModelManager(); - virtual ~ModelManager(); + public: + ModelManager(); + virtual ~ModelManager(); - Model *newModel(const string &path,bool deletePixMapAfterLoad,std::map > > *loadedFileList, string *sourceLoader); + Model *newModel(const string &path, bool deletePixMapAfterLoad, std::map > > *loadedFileList, string *sourceLoader); - void init(); - void end(); - void endModel(Model *model,bool mustExistInList=false); - void endLastModel(bool mustExistInList=false); + void init(); + void end(); + void endModel(Model *model, bool mustExistInList = false); + void endLastModel(bool mustExistInList = false); - void setTextureManager(TextureManager *textureManager) {this->textureManager= textureManager;} -}; + void setTextureManager(TextureManager *textureManager) { + this->textureManager = textureManager; + } + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/model_renderer.h b/source/shared_lib/include/graphics/model_renderer.h index 58e7aade2..4b6b9d3f6 100644 --- a/source/shared_lib/include/graphics/model_renderer.h +++ b/source/shared_lib/include/graphics/model_renderer.h @@ -16,60 +16,64 @@ #include "model.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -enum RenderMode{ - rmNormal, - rmSelection, + enum RenderMode { + rmNormal, + rmSelection, - renderModeCount -}; + renderModeCount + }; -class Texture; + class Texture; -// ===================================================== -// class MeshCallback -// -/// This gets called before rendering mesh -// ===================================================== + // ===================================================== + // class MeshCallback + // + /// This gets called before rendering mesh + // ===================================================== -class MeshCallback{ -public: - virtual ~MeshCallback(){}; - virtual void execute(const Mesh *mesh)= 0; -}; + class MeshCallback { + public: + virtual ~MeshCallback() { + }; + virtual void execute(const Mesh *mesh) = 0; + }; -// ===================================================== -// class ModelRenderer -// ===================================================== + // ===================================================== + // class ModelRenderer + // ===================================================== -class ModelRenderer{ -protected: - bool renderNormals; - bool renderTextures; - bool renderColors; - bool colorPickingMode; - MeshCallback *meshCallback; + class ModelRenderer { + protected: + bool renderNormals; + bool renderTextures; + bool renderColors; + bool colorPickingMode; + MeshCallback *meshCallback; -public: - ModelRenderer() { - renderNormals = false; - renderTextures = false; - renderColors = false; - colorPickingMode = false; + public: + ModelRenderer() { + renderNormals = false; + renderTextures = false; + renderColors = false; + colorPickingMode = false; + + meshCallback = NULL; + } + + virtual ~ModelRenderer() { + }; + + virtual void begin(bool renderNormals, bool renderTextures, bool renderColors, bool colorPickingMode, MeshCallback *meshCallback = NULL) = 0; + virtual void end() = 0; + virtual void render(Model *model, int renderMode = rmNormal) = 0; + virtual void renderNormalsOnly(Model *model) = 0; + }; - meshCallback= NULL; } - - virtual ~ModelRenderer(){}; - - virtual void begin(bool renderNormals, bool renderTextures, bool renderColors, bool colorPickingMode, MeshCallback *meshCallback= NULL)=0; - virtual void end()=0; - virtual void render(Model *model,int renderMode=rmNormal)=0; - virtual void renderNormalsOnly(Model *model)=0; -}; - -}}//end namespace +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/particle.h b/source/shared_lib/include/graphics/particle.h index 1b1b0c102..c530ac0eb 100644 --- a/source/shared_lib/include/graphics/particle.h +++ b/source/shared_lib/include/graphics/particle.h @@ -26,649 +26,806 @@ using std::list; using Shared::Util::RandomGen; using Shared::Xml::XmlNode; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -class ParticleSystem; -class FireParticleSystem; -class UnitParticleSystem; -class RainParticleSystem; -class SnowParticleSystem; -class ProjectileParticleSystem; -class SplashParticleSystem; -class ParticleRenderer; -class ModelRenderer; -class Model; + class ParticleSystem; + class FireParticleSystem; + class UnitParticleSystem; + class RainParticleSystem; + class SnowParticleSystem; + class ProjectileParticleSystem; + class SplashParticleSystem; + class ParticleRenderer; + class ModelRenderer; + class Model; -// ===================================================== -// class Particle -// ===================================================== + // ===================================================== + // class Particle + // ===================================================== -class Particle { -public: - //attributes - Vec3f pos; - Vec3f lastPos; - Vec3f speed; - float speedUpRelative; - Vec3f speedUpConstant; - Vec3f accel; - Vec4f color; - float size; - int energy; + class Particle { + public: + //attributes + Vec3f pos; + Vec3f lastPos; + Vec3f speed; + float speedUpRelative; + Vec3f speedUpConstant; + Vec3f accel; + Vec4f color; + float size; + int energy; + + public: + Particle() { + speedUpRelative = 0; + size = 0; + energy = 0; + } + //get + Vec3f getPos() const { + return pos; + } + Vec3f getLastPos() const { + return lastPos; + } + Vec3f getSpeed() const { + return speed; + } + Vec3f getAccel() const { + return accel; + } + Vec4f getColor() const { + return color; + } + float getSize() const { + return size; + } + int getEnergy() const { + return energy; + } + + void saveGame(XmlNode *rootNode); + void loadGame(const XmlNode *rootNode); + }; + + // ===================================================== + // class ParticleObserver + // ===================================================== + + class ParticleObserver { + public: + virtual ~ParticleObserver() { + }; + virtual void update(ParticleSystem *particleSystem) = 0; + virtual void saveGame(XmlNode *rootNode) = 0; + virtual void loadGame(const XmlNode *rootNode, void *genericData) = 0; + }; + + class ParticleOwner { + public: + virtual ~ParticleOwner() { + } + virtual void end(ParticleSystem *particleSystem) = 0; + virtual void logParticleInfo(string info) = 0; + }; + + + class ParticleSystemTypeInterface { + public: + + ParticleSystemTypeInterface() { + }; + virtual ~ParticleSystemTypeInterface() { + }; + + virtual bool getMinmaxEnabled() const = 0; + virtual int getMinHp() const = 0; + virtual int getMaxHp() const = 0; + virtual bool getMinmaxIsPercent() const = 0; + + }; + + // ===================================================== + // class ParticleSystem + // ===================================================== + + class ParticleSystem { + + public: + + enum State { + sPause, // No updates + sPlay, + sFade // No new particles + }; + + enum BlendMode { + bmOne, + bmOneMinusAlpha + }; + + enum ParticleSystemType { + pst_All, + pst_FireParticleSystem, + pst_UnitParticleSystem, + pst_RainParticleSystem, + pst_SnowParticleSystem, + pst_ProjectileParticleSystem, + pst_SplashParticleSystem, + }; + + protected: + + std::vector particles; + RandomGen random; + + BlendMode blendMode; + State state; + bool active; + bool visible; + int aliveParticleCount; + int particleCount; + + string textureFileLoadDeferred; + int textureFileLoadDeferredSystemId; + Texture::Format textureFileLoadDeferredFormat; + int textureFileLoadDeferredComponents; + + Texture *texture; + Vec3f pos; + Vec4f color; + Vec4f colorNoEnergy; + float emissionRate; + float emissionState; + int maxParticleEnergy; + int varParticleEnergy; + float particleSize; + float speed; + float speedUpRelative; + float speedUpConstant; + Vec3f factionColor; + bool teamcolorNoEnergy; + bool teamcolorEnergy; + int alternations; + int particleSystemStartDelay; + ParticleObserver *particleObserver; + ParticleOwner *particleOwner; + + public: + //conmstructor and destructor + ParticleSystem(int particleCount); + virtual ~ParticleSystem(); + virtual ParticleSystemType getParticleSystemType() const = 0; + + //public + virtual void update(); + virtual void render(ParticleRenderer *pr, ModelRenderer *mr); + + //get + State getState() const { + return state; + } + BlendMode getBlendMode() const { + return blendMode; + } + Texture *getTexture() const { + return texture; + } + Vec3f getPos() const { + return pos; + } + Particle *getParticle(int i) { + return &particles[i]; + } + const Particle *getParticle(int i) const { + return &particles[i]; + } + int getAliveParticleCount() const { + return aliveParticleCount; + } + bool getActive() const { + return active; + } + virtual bool getVisible() const { + return visible; + } + + virtual string getTextureFileLoadDeferred(); + virtual int getTextureFileLoadDeferredSystemId(); + virtual Texture::Format getTextureFileLoadDeferredFormat(); + virtual int getTextureFileLoadDeferredComponents(); + + //set + virtual void setState(State state); + void setTexture(Texture *texture); + virtual void setPos(Vec3f pos); + void setColor(Vec4f color); + void setColorNoEnergy(Vec4f color); + void setEmissionRate(float emissionRate); + void setMaxParticleEnergy(int maxParticleEnergy); + void setVarParticleEnergy(int varParticleEnergy); + void setParticleSize(float particleSize); + void setSpeed(float speed); + void setSpeedUpRelative(float speedUpRelative); + void setSpeedUpConstant(float speedUpConstant); + virtual void setActive(bool active); + void setObserver(ParticleObserver *particleObserver); + virtual void setVisible(bool visible); + void setBlendMode(BlendMode blendMode) { + this->blendMode = blendMode; + } + void setTeamcolorNoEnergy(bool teamcolorNoEnergy) { + this->teamcolorNoEnergy = teamcolorNoEnergy; + } + void setTeamcolorEnergy(bool teamcolorEnergy) { + this->teamcolorEnergy = teamcolorEnergy; + } + void setAlternations(int alternations) { + this->alternations = alternations; + } + void setParticleSystemStartDelay(int delay) { + this->particleSystemStartDelay = delay; + } + virtual void setFactionColor(Vec3f factionColor); + + static BlendMode strToBlendMode(const string &str); + //misc + virtual void fade(); + int isEmpty() const; + + virtual void setParticleOwner(ParticleOwner *particleOwner) { + this->particleOwner = particleOwner; + } + virtual ParticleOwner * getParticleOwner() { + return this->particleOwner; + } + virtual void callParticleOwnerEnd(ParticleSystem *particleSystem); + + //children + virtual int getChildCount() { + return 0; + } + virtual ParticleSystem* getChild(int i); + + virtual string toString() const; + + virtual void saveGame(XmlNode *rootNode); + virtual void loadGame(const XmlNode *rootNode); + + virtual Checksum getCRC(); + + protected: + //protected + Particle *createParticle(); + void killParticle(Particle *p); + + //virtual protected + virtual void initParticle(Particle *p, int particleIndex); + virtual void updateParticle(Particle *p); + virtual bool deathTest(Particle *p); + }; + + // ===================================================== + // class FireParticleSystem + // ===================================================== + + class FireParticleSystem : public ParticleSystem { + private: + float radius; + Vec3f windSpeed; + + public: + FireParticleSystem(int particleCount = 2000); + + virtual ParticleSystemType getParticleSystemType() const { + return pst_FireParticleSystem; + } + + //virtual + virtual void initParticle(Particle *p, int particleIndex); + virtual void updateParticle(Particle *p); + + //set params + void setRadius(float radius); + void setWind(float windAngle, float windSpeed); + + virtual void saveGame(XmlNode *rootNode); + virtual void loadGame(const XmlNode *rootNode); + + virtual string toString() const; + + virtual Checksum getCRC(); + }; + + // ===================================================== + // class GameParticleSystem + /// base-class for unit and attack systems + // ===================================================== + + class UnitParticleSystem; + + class GameParticleSystem : public ParticleSystem { + public: + enum Primitive { + pQuad, + pLine, + pLineAlpha + }; + static Primitive strToPrimitive(const string &str); + virtual ~GameParticleSystem(); + int getChildCount(); + ParticleSystem* getChild(int i); + void addChild(UnitParticleSystem* child); + void removeChild(UnitParticleSystem* child); + void setPos(Vec3f pos); + void setOffset(Vec3f offset); + void setModel(Model *model) { + this->model = model; + } + virtual void render(ParticleRenderer *pr, ModelRenderer *mr); + float getTween() { + return tween; + } // 0.0 -> 1.0 for animation of model + Model *getModel() const { + return model; + } + virtual string getModelFileLoadDeferred(); + + void setPrimitive(Primitive primitive) { + this->primitive = primitive; + } + Vec3f getDirection() const { + return direction; + } + void setModelCycle(float modelCycle) { + this->modelCycle = modelCycle; + } + + virtual void saveGame(XmlNode *rootNode); + virtual void loadGame(const XmlNode *rootNode); + + virtual string toString() const; + + virtual Checksum getCRC(); + + protected: + typedef std::vector Children; + Children children; + Primitive primitive; + + string modelFileLoadDeferred; + Model *model; + float modelCycle; + Vec3f offset; + Vec3f direction; + float tween; + + GameParticleSystem(int particleCount); + void positionChildren(); + void setTween(float relative, float absolute); + }; + + // ===================================================== + // class UnitParticleSystem + // ===================================================== + + class UnitParticleSystem : public GameParticleSystem { + public: + static bool isNight; + static Vec3f lightColor; + private: + float radius; + float minRadius; + Vec3f windSpeed; + Vec3f cRotation; + Vec3f fixedAddition; + Vec3f oldPosition; + bool energyUp; + float startTime; + float endTime; + + ParticleSystemTypeInterface *particleSystemType; + + public: + enum Shape { + sLinear, // generated in a sphere, flying in direction + sSpherical, // generated in a sphere, flying away from center + sConical, // generated in a cone at angle from direction + }; + + bool relative; + bool relativeDirection; + bool fixed; + Shape shape; + float angle; + float sizeNoEnergy; + float gravity; + float rotation; + const Model *unitModel; + Vec3f meshPos; + string meshName; + bool isVisibleAtNight; + bool isVisibleAtDay; + bool isDaylightAffected; + bool radiusBasedStartenergy; + int staticParticleCount; + int delay; + int lifetime; + float emissionRateFade; + GameParticleSystem* parent; + + public: + UnitParticleSystem(int particleCount = 2000); + ~UnitParticleSystem(); + + virtual ParticleSystemType getParticleSystemType() const { + return pst_UnitParticleSystem; + } + + ParticleSystemTypeInterface * getParticleType() const { + return particleSystemType; + } + void setParticleType(ParticleSystemTypeInterface *type) { + particleSystemType = type; + } + + //virtual + virtual void initParticle(Particle *p, int particleIndex); + virtual void updateParticle(Particle *p); + virtual void update(); + virtual bool getVisible() const; + virtual void fade(); + virtual void render(ParticleRenderer *pr, ModelRenderer *mr); + + virtual void setStartTime(float startTime) { + this->startTime = startTime; + } + virtual float getStartTime() const { + return this->startTime; + } + virtual void setEndTime(float endTime) { + this->endTime = endTime; + } + virtual float getEndTime() const { + return this->endTime; + } + + //set params + void setRadius(float radius) { + this->radius = radius; + } + void setMinRadius(float minRadius) { + this->minRadius = minRadius; + } + void setEmissionRateFade(float emissionRateFade) { + this->emissionRateFade = emissionRateFade; + } + + void setWind(float windAngle, float windSpeed); + + void setDirection(Vec3f direction) { + this->direction = direction; + } + void setSizeNoEnergy(float sizeNoEnergy) { + this->sizeNoEnergy = sizeNoEnergy; + } + void setGravity(float gravity) { + this->gravity = gravity; + } + void setRotation(float rotation); + void setMeshPos(Vec3f meshPos) { + this->meshPos = meshPos; + } + string getMeshName() { + return meshName; + } + void setMeshName(string meshName) { + this->meshName = meshName; + } + void setRelative(bool relative) { + this->relative = relative; + } + void setRelativeDirection(bool relativeDirection) { + this->relativeDirection = relativeDirection; + } + void setFixed(bool fixed) { + this->fixed = fixed; + } + void setPrimitive(Primitive primitive) { + this->primitive = primitive; + } + void setStaticParticleCount(int staticParticleCount) { + this->staticParticleCount = staticParticleCount; + } + void setIsVisibleAtNight(bool value) { + this->isVisibleAtNight = value; + } + void setIsDaylightAffected(bool value) { + this->isDaylightAffected = value; + } + void setIsVisibleAtDay(bool value) { + this->isVisibleAtDay = value; + } + void setRadiusBasedStartenergy(bool value) { + this->radiusBasedStartenergy = value; + } + void setShape(Shape shape) { + this->shape = shape; + } + void setAngle(float angle) { + this->angle = angle; + } + void setDelay(int delay) { + this->delay = delay; + } + void setLifetime(int lifetime) { + this->lifetime = lifetime; + } + void setParent(GameParticleSystem* parent) { + this->parent = parent; + } + GameParticleSystem* getParent() const { + return parent; + } + void setParentDirection(Vec3f parentDirection); + + static Shape strToShape(const string& str); + + virtual void saveGame(XmlNode *rootNode); + virtual void loadGame(const XmlNode *rootNode); + + virtual string toString() const; + + virtual Checksum getCRC(); + }; + + // ===================================================== + // class RainParticleSystem + // ===================================================== + + class RainParticleSystem : public ParticleSystem { + private: + Vec3f windSpeed; + float radius; + + public: + RainParticleSystem(int particleCount = 4000); + + virtual ParticleSystemType getParticleSystemType() const { + return pst_RainParticleSystem; + } + + virtual void render(ParticleRenderer *pr, ModelRenderer *mr); + + virtual void initParticle(Particle *p, int particleIndex); + virtual bool deathTest(Particle *p); + + void setRadius(float radius); + void setWind(float windAngle, float windSpeed); + + virtual string toString() const; + + virtual Checksum getCRC(); + }; + + // ===================================================== + // class SnowParticleSystem + // ===================================================== + + class SnowParticleSystem : public ParticleSystem { + private: + Vec3f windSpeed; + float radius; + + public: + SnowParticleSystem(int particleCount = 4000); + + virtual ParticleSystemType getParticleSystemType() const { + return pst_SnowParticleSystem; + } + + virtual void initParticle(Particle *p, int particleIndex); + virtual bool deathTest(Particle *p); + + void setRadius(float radius); + void setWind(float windAngle, float windSpeed); + + virtual string toString() const; + + virtual Checksum getCRC(); + }; + + // =========================================================================== + // AttackParticleSystem + // + /// Base class for Projectiles and Splashes + // =========================================================================== + + class AttackParticleSystem : public GameParticleSystem { + + protected: + float sizeNoEnergy; + float gravity; + public: + AttackParticleSystem(int particleCount); + + virtual ParticleSystemType getParticleSystemType() const { + return pst_ProjectileParticleSystem; + } + + void setSizeNoEnergy(float sizeNoEnergy) { + this->sizeNoEnergy = sizeNoEnergy; + } + void setGravity(float gravity) { + this->gravity = gravity; + } + + virtual void initParticleSystem() { + } // opportunity to do any initialization when the system has been created and all settings set + + virtual void saveGame(XmlNode *rootNode); + virtual void loadGame(const XmlNode *rootNode); + + virtual string toString() const; + + virtual Checksum getCRC(); + }; + + // ===================================================== + // class ProjectileParticleSystem + // ===================================================== + + class ProjectileParticleSystem : public AttackParticleSystem { + public: + friend class SplashParticleSystem; + + enum Trajectory { + tLinear, + tParabolic, + tSpiral + }; + + private: + SplashParticleSystem *nextParticleSystem; + + Vec3f lastPos; + Vec3f startPos; + Vec3f endPos; + Vec3f flatPos; + + Vec3f xVector; + Vec3f yVector; + Vec3f zVector; + + Trajectory trajectory; + float trajectorySpeed; + + //parabolic + float trajectoryScale; + float trajectoryFrequency; + + float arriveDestinationDistance; + void rotateChildren(); + + public: + ProjectileParticleSystem(int particleCount = 1000); + virtual ~ProjectileParticleSystem(); + + virtual ParticleSystemType getParticleSystemType() const { + return pst_SplashParticleSystem; + } + + void link(SplashParticleSystem *particleSystem); + + virtual void update(); + virtual void initParticle(Particle *p, int particleIndex); + virtual void updateParticle(Particle *p); + + void setTrajectory(Trajectory trajectory) { + this->trajectory = trajectory; + } + void setTrajectorySpeed(float trajectorySpeed) { + this->trajectorySpeed = trajectorySpeed; + } + void setTrajectoryScale(float trajectoryScale) { + this->trajectoryScale = trajectoryScale; + } + void setTrajectoryFrequency(float trajectoryFrequency) { + this->trajectoryFrequency = trajectoryFrequency; + } + + void setPath(Vec3f startPos, Vec3f endPos); + + static Trajectory strToTrajectory(const string &str); + + virtual void saveGame(XmlNode *rootNode); + virtual void loadGame(const XmlNode *rootNode); + + virtual string toString() const; + + virtual Checksum getCRC(); + }; + + // ===================================================== + // class SplashParticleSystem + // ===================================================== + + class SplashParticleSystem : public AttackParticleSystem { + public: + friend class ProjectileParticleSystem; + + private: + ProjectileParticleSystem *prevParticleSystem; + + float emissionRateFade; + float verticalSpreadA; + float verticalSpreadB; + float horizontalSpreadA; + float horizontalSpreadB; + + float startEmissionRate; + + public: + SplashParticleSystem(int particleCount = 1000); + virtual ~SplashParticleSystem(); + + virtual void update(); + virtual void initParticle(Particle *p, int particleIndex); + virtual void updateParticle(Particle *p); + + virtual void initParticleSystem(); + + void setEmissionRateFade(float emissionRateFade) { + this->emissionRateFade = emissionRateFade; + } + void setVerticalSpreadA(float verticalSpreadA) { + this->verticalSpreadA = verticalSpreadA; + } + void setVerticalSpreadB(float verticalSpreadB) { + this->verticalSpreadB = verticalSpreadB; + } + void setHorizontalSpreadA(float horizontalSpreadA) { + this->horizontalSpreadA = horizontalSpreadA; + } + void setHorizontalSpreadB(float horizontalSpreadB) { + this->horizontalSpreadB = horizontalSpreadB; + } + + virtual void saveGame(XmlNode *rootNode); + virtual void loadGame(const XmlNode *rootNode); + + virtual string toString() const; + + virtual Checksum getCRC(); + }; + + // ===================================================== + // class ParticleManager + // ===================================================== + + class ParticleManager { + private: + vector particleSystems; + + public: + ParticleManager(); + ~ParticleManager(); + void update(int renderFps = -1); + void render(ParticleRenderer *pr, ModelRenderer *mr) const; + void manage(ParticleSystem *ps); + void end(); + void cleanupParticleSystems(ParticleSystem *ps); + void cleanupParticleSystems(vector &particleSystems); + void cleanupUnitParticleSystems(vector &particleSystems); + int findParticleSystems(ParticleSystem *psFind, const vector &particleSystems) const; + bool validateParticleSystemStillExists(ParticleSystem * particleSystem) const; + void removeParticleSystemsForParticleOwner(ParticleOwner * particleOwner); + bool hasActiveParticleSystem(ParticleSystem::ParticleSystemType type) const; + }; -public: - Particle() { - speedUpRelative = 0; - size = 0; - energy = 0; } - //get - Vec3f getPos() const {return pos;} - Vec3f getLastPos() const {return lastPos;} - Vec3f getSpeed() const {return speed;} - Vec3f getAccel() const {return accel;} - Vec4f getColor() const {return color;} - float getSize() const {return size;} - int getEnergy() const {return energy;} - - void saveGame(XmlNode *rootNode); - void loadGame(const XmlNode *rootNode); -}; - -// ===================================================== -// class ParticleObserver -// ===================================================== - -class ParticleObserver { -public: - virtual ~ParticleObserver(){}; - virtual void update(ParticleSystem *particleSystem)= 0; - virtual void saveGame(XmlNode *rootNode) = 0; - virtual void loadGame(const XmlNode *rootNode, void *genericData) = 0; -}; - -class ParticleOwner { -public: - virtual ~ParticleOwner() {} - virtual void end(ParticleSystem *particleSystem)= 0; - virtual void logParticleInfo(string info)= 0; -}; - - -class ParticleSystemTypeInterface { -public: - - ParticleSystemTypeInterface() {}; - virtual ~ParticleSystemTypeInterface() {}; - - virtual bool getMinmaxEnabled() const = 0; - virtual int getMinHp() const = 0; - virtual int getMaxHp() const = 0; - virtual bool getMinmaxIsPercent() const = 0; - -}; - -// ===================================================== -// class ParticleSystem -// ===================================================== - -class ParticleSystem { - -public: - -enum State { - sPause, // No updates - sPlay, - sFade // No new particles -}; - -enum BlendMode { - bmOne, - bmOneMinusAlpha -}; - -enum ParticleSystemType { - pst_All, - pst_FireParticleSystem, - pst_UnitParticleSystem, - pst_RainParticleSystem, - pst_SnowParticleSystem, - pst_ProjectileParticleSystem, - pst_SplashParticleSystem, -}; - -protected: - - std::vector particles; - RandomGen random; - - BlendMode blendMode; - State state; - bool active; - bool visible; - int aliveParticleCount; - int particleCount; - - string textureFileLoadDeferred; - int textureFileLoadDeferredSystemId; - Texture::Format textureFileLoadDeferredFormat; - int textureFileLoadDeferredComponents; - - Texture *texture; - Vec3f pos; - Vec4f color; - Vec4f colorNoEnergy; - float emissionRate; - float emissionState; - int maxParticleEnergy; - int varParticleEnergy; - float particleSize; - float speed; - float speedUpRelative; - float speedUpConstant; - Vec3f factionColor; - bool teamcolorNoEnergy; - bool teamcolorEnergy; - int alternations; - int particleSystemStartDelay; - ParticleObserver *particleObserver; - ParticleOwner *particleOwner; - -public: - //conmstructor and destructor - ParticleSystem(int particleCount); - virtual ~ParticleSystem(); - virtual ParticleSystemType getParticleSystemType() const = 0; - - //public - virtual void update(); - virtual void render(ParticleRenderer *pr, ModelRenderer *mr); - - //get - State getState() const {return state;} - BlendMode getBlendMode() const {return blendMode;} - Texture *getTexture() const {return texture;} - Vec3f getPos() const {return pos;} - Particle *getParticle(int i) {return &particles[i];} - const Particle *getParticle(int i) const {return &particles[i];} - int getAliveParticleCount() const {return aliveParticleCount;} - bool getActive() const {return active;} - virtual bool getVisible() const {return visible;} - - virtual string getTextureFileLoadDeferred(); - virtual int getTextureFileLoadDeferredSystemId(); - virtual Texture::Format getTextureFileLoadDeferredFormat(); - virtual int getTextureFileLoadDeferredComponents(); - - //set - virtual void setState(State state); - void setTexture(Texture *texture); - virtual void setPos(Vec3f pos); - void setColor(Vec4f color); - void setColorNoEnergy(Vec4f color); - void setEmissionRate(float emissionRate); - void setMaxParticleEnergy(int maxParticleEnergy); - void setVarParticleEnergy(int varParticleEnergy); - void setParticleSize(float particleSize); - void setSpeed(float speed); - void setSpeedUpRelative(float speedUpRelative); - void setSpeedUpConstant(float speedUpConstant); - virtual void setActive(bool active); - void setObserver(ParticleObserver *particleObserver); - virtual void setVisible(bool visible); - void setBlendMode(BlendMode blendMode) {this->blendMode= blendMode;} - void setTeamcolorNoEnergy(bool teamcolorNoEnergy) {this->teamcolorNoEnergy= teamcolorNoEnergy;} - void setTeamcolorEnergy(bool teamcolorEnergy) {this->teamcolorEnergy= teamcolorEnergy;} - void setAlternations(int alternations) {this->alternations= alternations;} - void setParticleSystemStartDelay(int delay) {this->particleSystemStartDelay= delay;} - virtual void setFactionColor(Vec3f factionColor); - - static BlendMode strToBlendMode(const string &str); - //misc - virtual void fade(); - int isEmpty() const; - - virtual void setParticleOwner(ParticleOwner *particleOwner) { this->particleOwner = particleOwner;} - virtual ParticleOwner * getParticleOwner() { return this->particleOwner;} - virtual void callParticleOwnerEnd(ParticleSystem *particleSystem); - - //children - virtual int getChildCount() { return 0; } - virtual ParticleSystem* getChild(int i); - - virtual string toString() const; - - virtual void saveGame(XmlNode *rootNode); - virtual void loadGame(const XmlNode *rootNode); - - virtual Checksum getCRC(); - -protected: - //protected - Particle *createParticle(); - void killParticle(Particle *p); - - //virtual protected - virtual void initParticle(Particle *p, int particleIndex); - virtual void updateParticle(Particle *p); - virtual bool deathTest(Particle *p); -}; - -// ===================================================== -// class FireParticleSystem -// ===================================================== - -class FireParticleSystem: public ParticleSystem{ -private: - float radius; - Vec3f windSpeed; - -public: - FireParticleSystem(int particleCount= 2000); - - virtual ParticleSystemType getParticleSystemType() const { return pst_FireParticleSystem;} - - //virtual - virtual void initParticle(Particle *p, int particleIndex); - virtual void updateParticle(Particle *p); - - //set params - void setRadius(float radius); - void setWind(float windAngle, float windSpeed); - - virtual void saveGame(XmlNode *rootNode); - virtual void loadGame(const XmlNode *rootNode); - - virtual string toString() const; - - virtual Checksum getCRC(); -}; - -// ===================================================== -// class GameParticleSystem -/// base-class for unit and attack systems -// ===================================================== - -class UnitParticleSystem; - -class GameParticleSystem: public ParticleSystem{ -public: - enum Primitive{ - pQuad, - pLine, - pLineAlpha - }; - static Primitive strToPrimitive(const string &str); - virtual ~GameParticleSystem(); - int getChildCount(); - ParticleSystem* getChild(int i); - void addChild(UnitParticleSystem* child); - void removeChild(UnitParticleSystem* child); - void setPos(Vec3f pos); - void setOffset(Vec3f offset); - void setModel(Model *model) {this->model= model;} - virtual void render(ParticleRenderer *pr, ModelRenderer *mr); - float getTween() { return tween; } // 0.0 -> 1.0 for animation of model - Model *getModel() const {return model;} - virtual string getModelFileLoadDeferred(); - - void setPrimitive(Primitive primitive) {this->primitive= primitive;} - Vec3f getDirection() const {return direction;} - void setModelCycle(float modelCycle) {this->modelCycle= modelCycle;} - - virtual void saveGame(XmlNode *rootNode); - virtual void loadGame(const XmlNode *rootNode); - - virtual string toString() const; - - virtual Checksum getCRC(); - -protected: - typedef std::vector Children; - Children children; - Primitive primitive; - - string modelFileLoadDeferred; - Model *model; - float modelCycle; - Vec3f offset; - Vec3f direction; - float tween; - - GameParticleSystem(int particleCount); - void positionChildren(); - void setTween(float relative,float absolute); -}; - -// ===================================================== -// class UnitParticleSystem -// ===================================================== - -class UnitParticleSystem: public GameParticleSystem{ -public: - static bool isNight; - static Vec3f lightColor; -private: - float radius; - float minRadius; - Vec3f windSpeed; - Vec3f cRotation; - Vec3f fixedAddition; - Vec3f oldPosition; - bool energyUp; - float startTime; - float endTime; - - ParticleSystemTypeInterface *particleSystemType; - -public: - enum Shape{ - sLinear, // generated in a sphere, flying in direction - sSpherical, // generated in a sphere, flying away from center - sConical, // generated in a cone at angle from direction - }; - - bool relative; - bool relativeDirection; - bool fixed; - Shape shape; - float angle; - float sizeNoEnergy; - float gravity; - float rotation; - const Model *unitModel; - Vec3f meshPos; - string meshName; - bool isVisibleAtNight; - bool isVisibleAtDay; - bool isDaylightAffected; - bool radiusBasedStartenergy; - int staticParticleCount; - int delay; - int lifetime; - float emissionRateFade; - GameParticleSystem* parent; - -public: - UnitParticleSystem(int particleCount= 2000); - ~UnitParticleSystem(); - - virtual ParticleSystemType getParticleSystemType() const { return pst_UnitParticleSystem;} - - ParticleSystemTypeInterface * getParticleType() const { - return particleSystemType; - } - void setParticleType(ParticleSystemTypeInterface *type) { - particleSystemType = type; - } - - //virtual - virtual void initParticle(Particle *p, int particleIndex); - virtual void updateParticle(Particle *p); - virtual void update(); - virtual bool getVisible() const; - virtual void fade(); - virtual void render(ParticleRenderer *pr, ModelRenderer *mr); - - virtual void setStartTime(float startTime) { this->startTime = startTime; } - virtual float getStartTime() const { return this->startTime; } - virtual void setEndTime(float endTime) { this->endTime = endTime; } - virtual float getEndTime() const { return this->endTime; } - - //set params - void setRadius(float radius) {this->radius= radius;} - void setMinRadius(float minRadius) {this->minRadius= minRadius;} - void setEmissionRateFade(float emissionRateFade) {this->emissionRateFade= emissionRateFade;} - - void setWind(float windAngle, float windSpeed); - - void setDirection(Vec3f direction) {this->direction= direction;} - void setSizeNoEnergy(float sizeNoEnergy) {this->sizeNoEnergy= sizeNoEnergy;} - void setGravity(float gravity) {this->gravity= gravity;} - void setRotation(float rotation); - void setMeshPos(Vec3f meshPos) {this->meshPos=meshPos;} - string getMeshName() {return meshName;} - void setMeshName(string meshName) {this->meshName= meshName;} - void setRelative(bool relative) {this->relative= relative;} - void setRelativeDirection(bool relativeDirection) {this->relativeDirection= relativeDirection;} - void setFixed(bool fixed) {this->fixed= fixed;} - void setPrimitive(Primitive primitive) {this->primitive= primitive;} - void setStaticParticleCount(int staticParticleCount){this->staticParticleCount= staticParticleCount;} - void setIsVisibleAtNight(bool value) {this->isVisibleAtNight= value;} - void setIsDaylightAffected(bool value) {this->isDaylightAffected= value;} - void setIsVisibleAtDay(bool value) {this->isVisibleAtDay= value;} - void setRadiusBasedStartenergy(bool value) {this->radiusBasedStartenergy= value;} - void setShape(Shape shape) {this->shape= shape;} - void setAngle(float angle) {this->angle= angle;} - void setDelay(int delay) {this->delay= delay;} - void setLifetime(int lifetime) {this->lifetime= lifetime;} - void setParent(GameParticleSystem* parent) {this->parent= parent;} - GameParticleSystem* getParent() const {return parent;} - void setParentDirection(Vec3f parentDirection); - - static Shape strToShape(const string& str); - - virtual void saveGame(XmlNode *rootNode); - virtual void loadGame(const XmlNode *rootNode); - - virtual string toString() const; - - virtual Checksum getCRC(); -}; - -// ===================================================== -// class RainParticleSystem -// ===================================================== - -class RainParticleSystem: public ParticleSystem{ -private: - Vec3f windSpeed; - float radius; - -public: - RainParticleSystem(int particleCount= 4000); - - virtual ParticleSystemType getParticleSystemType() const { return pst_RainParticleSystem;} - - virtual void render(ParticleRenderer *pr, ModelRenderer *mr); - - virtual void initParticle(Particle *p, int particleIndex); - virtual bool deathTest(Particle *p); - - void setRadius(float radius); - void setWind(float windAngle, float windSpeed); - - virtual string toString() const; - - virtual Checksum getCRC(); -}; - -// ===================================================== -// class SnowParticleSystem -// ===================================================== - -class SnowParticleSystem: public ParticleSystem{ -private: - Vec3f windSpeed; - float radius; - -public: - SnowParticleSystem(int particleCount= 4000); - - virtual ParticleSystemType getParticleSystemType() const { return pst_SnowParticleSystem;} - - virtual void initParticle(Particle *p, int particleIndex); - virtual bool deathTest(Particle *p); - - void setRadius(float radius); - void setWind(float windAngle, float windSpeed); - - virtual string toString() const; - - virtual Checksum getCRC(); -}; - -// =========================================================================== -// AttackParticleSystem -// -/// Base class for Projectiles and Splashes -// =========================================================================== - -class AttackParticleSystem: public GameParticleSystem { - -protected: - float sizeNoEnergy; - float gravity; -public: - AttackParticleSystem(int particleCount); - - virtual ParticleSystemType getParticleSystemType() const { return pst_ProjectileParticleSystem;} - - void setSizeNoEnergy(float sizeNoEnergy) {this->sizeNoEnergy= sizeNoEnergy;} - void setGravity(float gravity) {this->gravity= gravity;} - - virtual void initParticleSystem() {} // opportunity to do any initialization when the system has been created and all settings set - - virtual void saveGame(XmlNode *rootNode); - virtual void loadGame(const XmlNode *rootNode); - - virtual string toString() const; - - virtual Checksum getCRC(); -}; - -// ===================================================== -// class ProjectileParticleSystem -// ===================================================== - -class ProjectileParticleSystem: public AttackParticleSystem{ -public: - friend class SplashParticleSystem; - - enum Trajectory{ - tLinear, - tParabolic, - tSpiral - }; - -private: - SplashParticleSystem *nextParticleSystem; - - Vec3f lastPos; - Vec3f startPos; - Vec3f endPos; - Vec3f flatPos; - - Vec3f xVector; - Vec3f yVector; - Vec3f zVector; - - Trajectory trajectory; - float trajectorySpeed; - - //parabolic - float trajectoryScale; - float trajectoryFrequency; - - float arriveDestinationDistance; - void rotateChildren(); - -public: - ProjectileParticleSystem(int particleCount= 1000); - virtual ~ProjectileParticleSystem(); - - virtual ParticleSystemType getParticleSystemType() const { return pst_SplashParticleSystem;} - - void link(SplashParticleSystem *particleSystem); - - virtual void update(); - virtual void initParticle(Particle *p, int particleIndex); - virtual void updateParticle(Particle *p); - - void setTrajectory(Trajectory trajectory) {this->trajectory= trajectory;} - void setTrajectorySpeed(float trajectorySpeed) {this->trajectorySpeed= trajectorySpeed;} - void setTrajectoryScale(float trajectoryScale) {this->trajectoryScale= trajectoryScale;} - void setTrajectoryFrequency(float trajectoryFrequency) {this->trajectoryFrequency= trajectoryFrequency;} - - void setPath(Vec3f startPos, Vec3f endPos); - - static Trajectory strToTrajectory(const string &str); - - virtual void saveGame(XmlNode *rootNode); - virtual void loadGame(const XmlNode *rootNode); - - virtual string toString() const; - - virtual Checksum getCRC(); -}; - -// ===================================================== -// class SplashParticleSystem -// ===================================================== - -class SplashParticleSystem: public AttackParticleSystem{ -public: - friend class ProjectileParticleSystem; - -private: - ProjectileParticleSystem *prevParticleSystem; - - float emissionRateFade; - float verticalSpreadA; - float verticalSpreadB; - float horizontalSpreadA; - float horizontalSpreadB; - - float startEmissionRate; - -public: - SplashParticleSystem(int particleCount= 1000); - virtual ~SplashParticleSystem(); - - virtual void update(); - virtual void initParticle(Particle *p, int particleIndex); - virtual void updateParticle(Particle *p); - - virtual void initParticleSystem(); - - void setEmissionRateFade(float emissionRateFade) {this->emissionRateFade= emissionRateFade;} - void setVerticalSpreadA(float verticalSpreadA) {this->verticalSpreadA= verticalSpreadA;} - void setVerticalSpreadB(float verticalSpreadB) {this->verticalSpreadB= verticalSpreadB;} - void setHorizontalSpreadA(float horizontalSpreadA) {this->horizontalSpreadA= horizontalSpreadA;} - void setHorizontalSpreadB(float horizontalSpreadB) {this->horizontalSpreadB= horizontalSpreadB;} - - virtual void saveGame(XmlNode *rootNode); - virtual void loadGame(const XmlNode *rootNode); - - virtual string toString() const; - - virtual Checksum getCRC(); -}; - -// ===================================================== -// class ParticleManager -// ===================================================== - -class ParticleManager { -private: - vector particleSystems; - -public: - ParticleManager(); - ~ParticleManager(); - void update(int renderFps=-1); - void render(ParticleRenderer *pr, ModelRenderer *mr) const; - void manage(ParticleSystem *ps); - void end(); - void cleanupParticleSystems(ParticleSystem *ps); - void cleanupParticleSystems(vector &particleSystems); - void cleanupUnitParticleSystems(vector &particleSystems); - int findParticleSystems(ParticleSystem *psFind, const vector &particleSystems) const; - bool validateParticleSystemStillExists(ParticleSystem * particleSystem) const; - void removeParticleSystemsForParticleOwner(ParticleOwner * particleOwner); - bool hasActiveParticleSystem(ParticleSystem::ParticleSystemType type) const; -}; - -}}//end namespace +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/particle_renderer.h b/source/shared_lib/include/graphics/particle_renderer.h index 52f81c880..3ee4dd44d 100644 --- a/source/shared_lib/include/graphics/particle_renderer.h +++ b/source/shared_lib/include/graphics/particle_renderer.h @@ -15,25 +15,28 @@ #include "particle.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -class ModelRenderer; + class ModelRenderer; -// ===================================================== -// class ParticleRenderer -// ===================================================== + // ===================================================== + // class ParticleRenderer + // ===================================================== -class ParticleRenderer{ -public: - //particles - virtual ~ParticleRenderer(){}; - virtual void renderManager(ParticleManager *pm, ModelRenderer *mr)=0; - virtual void renderSystem(ParticleSystem *ps)=0; - virtual void renderSystemLine(ParticleSystem *ps)=0; - virtual void renderSystemLineAlpha(ParticleSystem *ps)=0; - virtual void renderModel(GameParticleSystem *ps, ModelRenderer *mr)=0; -}; + class ParticleRenderer { + public: + //particles + virtual ~ParticleRenderer() { + }; + virtual void renderManager(ParticleManager *pm, ModelRenderer *mr) = 0; + virtual void renderSystem(ParticleSystem *ps) = 0; + virtual void renderSystemLine(ParticleSystem *ps) = 0; + virtual void renderSystemLineAlpha(ParticleSystem *ps) = 0; + virtual void renderModel(GameParticleSystem *ps, ModelRenderer *mr) = 0; + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/pixmap.h b/source/shared_lib/include/graphics/pixmap.h index a0c162954..70ff5417a 100644 --- a/source/shared_lib/include/graphics/pixmap.h +++ b/source/shared_lib/include/graphics/pixmap.h @@ -29,367 +29,420 @@ using Shared::Platform::uint32; using Shared::Platform::float32; using Shared::Util::Checksum; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -/** - * @brief Next power of 2 - * @param x The number to be rounded - * @return the rounded number - * - * Rounds an unsigned integer up to the - * next power of 2; i.e. 2, 4, 8, 16, etc. - */ -static inline unsigned int next_power_of_2(unsigned int x) -{ - x--; - x |= (x >> 1); - x |= (x >> 2); - x |= (x >> 4); - x |= (x >> 8); - x |= (x >> 16); - return ++x; -} + /** + * @brief Next power of 2 + * @param x The number to be rounded + * @return the rounded number + * + * Rounds an unsigned integer up to the + * next power of 2; i.e. 2, 4, 8, 16, etc. + */ + static inline unsigned int next_power_of_2(unsigned int x) { + x--; + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return ++x; + } -/** - * @brief Count bits set - * @param w Number in which to count bits - * @return The number of bits set - * - * Counts the number of bits in an unsigned int - * that are set to 1. So, for example, in the - * number 5, hich is 101 in binary, there are - * two bits set to 1. - */ -static inline unsigned int count_bits_set(unsigned int w) -{ - /* - * This is faster, and runs in parallel - */ - const int S[] = {1, 2, 4, 8, 16}; - const int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF}; - int c = w; - c = ((c >> S[0]) & B[0]) + (c & B[0]); - c = ((c >> S[1]) & B[1]) + (c & B[1]); - c = ((c >> S[2]) & B[2]) + (c & B[2]); - c = ((c >> S[3]) & B[3]) + (c & B[3]); - c = ((c >> S[4]) & B[4]) + (c & B[4]); - return c; -} + /** + * @brief Count bits set + * @param w Number in which to count bits + * @return The number of bits set + * + * Counts the number of bits in an unsigned int + * that are set to 1. So, for example, in the + * number 5, hich is 101 in binary, there are + * two bits set to 1. + */ + static inline unsigned int count_bits_set(unsigned int w) { + /* + * This is faster, and runs in parallel + */ + const int S[] = { 1, 2, 4, 8, 16 }; + const int B[] = { 0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF }; + int c = w; + c = ((c >> S[0]) & B[0]) + (c & B[0]); + c = ((c >> S[1]) & B[1]) + (c & B[1]); + c = ((c >> S[2]) & B[2]) + (c & B[2]); + c = ((c >> S[3]) & B[3]) + (c & B[3]); + c = ((c >> S[4]) & B[4]) + (c & B[4]); + return c; + } -// ===================================================== -// class PixmapIo -// ===================================================== + // ===================================================== + // class PixmapIo + // ===================================================== -class PixmapIo { -protected: - int w; - int h; - int components; + class PixmapIo { + protected: + int w; + int h; + int components; -public: - virtual ~PixmapIo(){} + public: + virtual ~PixmapIo() { + } - int getW() const {return w;} - int getH() const {return h;} - int getComponents() const {return components;} + int getW() const { + return w; + } + int getH() const { + return h; + } + int getComponents() const { + return components; + } - virtual void openRead(const string &path)= 0; - virtual void read(uint8 *pixels)= 0; - virtual void read(uint8 *pixels, int components)= 0; + virtual void openRead(const string &path) = 0; + virtual void read(uint8 *pixels) = 0; + virtual void read(uint8 *pixels, int components) = 0; - virtual void openWrite(const string &path, int w, int h, int components)= 0; - virtual void write(uint8 *pixels)= 0; -}; + virtual void openWrite(const string &path, int w, int h, int components) = 0; + virtual void write(uint8 *pixels) = 0; + }; -// ===================================================== -// class PixmapIoTga -// ===================================================== + // ===================================================== + // class PixmapIoTga + // ===================================================== -class PixmapIoTga: public PixmapIo { -private: - FILE *file; + class PixmapIoTga : public PixmapIo { + private: + FILE *file; -public: - PixmapIoTga(); - virtual ~PixmapIoTga(); + public: + PixmapIoTga(); + virtual ~PixmapIoTga(); - virtual void openRead(const string &path); - virtual void read(uint8 *pixels); - virtual void read(uint8 *pixels, int components); + virtual void openRead(const string &path); + virtual void read(uint8 *pixels); + virtual void read(uint8 *pixels, int components); - virtual void openWrite(const string &path, int w, int h, int components); - virtual void write(uint8 *pixels); -}; + virtual void openWrite(const string &path, int w, int h, int components); + virtual void write(uint8 *pixels); + }; -// ===================================================== -// class PixmapIoBmp -// ===================================================== + // ===================================================== + // class PixmapIoBmp + // ===================================================== -class PixmapIoBmp: public PixmapIo { -private: - FILE *file; + class PixmapIoBmp : public PixmapIo { + private: + FILE *file; -public: - PixmapIoBmp(); - virtual ~PixmapIoBmp(); - - virtual void openRead(const string &path); - virtual void read(uint8 *pixels); - virtual void read(uint8 *pixels, int components); + public: + PixmapIoBmp(); + virtual ~PixmapIoBmp(); - virtual void openWrite(const string &path, int w, int h, int components); - virtual void write(uint8 *pixels); -}; + virtual void openRead(const string &path); + virtual void read(uint8 *pixels); + virtual void read(uint8 *pixels, int components); -// ===================================================== -// class PixmapIoBmp -// ===================================================== + virtual void openWrite(const string &path, int w, int h, int components); + virtual void write(uint8 *pixels); + }; -class PixmapIoPng: public PixmapIo { -private: - FILE *file; - string path; + // ===================================================== + // class PixmapIoBmp + // ===================================================== -public: - PixmapIoPng(); - virtual ~PixmapIoPng(); + class PixmapIoPng : public PixmapIo { + private: + FILE *file; + string path; - virtual void openRead(const string &path); - virtual void read(uint8 *pixels); - virtual void read(uint8 *pixels, int components); + public: + PixmapIoPng(); + virtual ~PixmapIoPng(); - virtual void openWrite(const string &path, int w, int h, int components); - virtual void write(uint8 *pixels); -}; + virtual void openRead(const string &path); + virtual void read(uint8 *pixels); + virtual void read(uint8 *pixels, int components); -class PixmapIoJpg: public PixmapIo { -private: - FILE *file; - string path; + virtual void openWrite(const string &path, int w, int h, int components); + virtual void write(uint8 *pixels); + }; -public: - PixmapIoJpg(); - virtual ~PixmapIoJpg(); + class PixmapIoJpg : public PixmapIo { + private: + FILE *file; + string path; - virtual void openRead(const string &path); - virtual void read(uint8 *pixels); - virtual void read(uint8 *pixels, int components); + public: + PixmapIoJpg(); + virtual ~PixmapIoJpg(); - virtual void openWrite(const string &path, int w, int h, int components); - virtual void write(uint8 *pixels); -}; + virtual void openRead(const string &path); + virtual void read(uint8 *pixels); + virtual void read(uint8 *pixels, int components); -// ===================================================== -// class Pixmap1D -// ===================================================== + virtual void openWrite(const string &path, int w, int h, int components); + virtual void write(uint8 *pixels); + }; -class Pixmap1D { -protected: - int w; - int components; - uint8 *pixels; - string path; - Checksum crc; + // ===================================================== + // class Pixmap1D + // ===================================================== -public: - //constructor & destructor - Pixmap1D(); - Pixmap1D(int components); - Pixmap1D(int w, int components); - void init(int components); - void init(int w, int components); - ~Pixmap1D(); - - //load & save - void load(const string &path); - void loadTga(const string &path); - void loadBmp(const string &path); + class Pixmap1D { + protected: + int w; + int components; + uint8 *pixels; + string path; + Checksum crc; - //get - int getW() const {return w;} - int getComponents() const {return components;} - uint8 *getPixels() const {return pixels;} - void deletePixels(); - string getPath() const { return path;} - std::size_t getPixelByteCount() const; + public: + //constructor & destructor + Pixmap1D(); + Pixmap1D(int components); + Pixmap1D(int w, int components); + void init(int components); + void init(int w, int components); + ~Pixmap1D(); - Checksum * getCRC() { return &crc; } -}; + //load & save + void load(const string &path); + void loadTga(const string &path); + void loadBmp(const string &path); -// ===================================================== -// class Pixmap2D -// ===================================================== + //get + int getW() const { + return w; + } + int getComponents() const { + return components; + } + uint8 *getPixels() const { + return pixels; + } + void deletePixels(); + string getPath() const { + return path; + } + std::size_t getPixelByteCount() const; -class Pixmap2D { -protected: - int h; - int w; - int components; - uint8 *pixels; - string path; - Checksum crc; + Checksum * getCRC() { + return &crc; + } + }; -public: - //constructor & destructor - Pixmap2D(); - Pixmap2D(int components); - Pixmap2D(int w, int h, int components); - void init(int components); - void init(int w, int h, int components); - ~Pixmap2D(); - - void Scale(int format, int newW, int newH); + // ===================================================== + // class Pixmap2D + // ===================================================== - //load & save - static Pixmap2D* loadPath(const string& path); - void load(const string &path); - /*void loadTga(const string &path); - void loadBmp(const string &path);*/ - void save(const string &path); - void saveBmp(const string &path); - void saveTga(const string &path); - void savePng(const string &path); - void saveJpg(const string &path); + class Pixmap2D { + protected: + int h; + int w; + int components; + uint8 *pixels; + string path; + Checksum crc; - //get - int getW() const {return w;} - int getH() const {return h;} - int getComponents() const {return components;} - uint8 *getPixels() const {return pixels;} - void deletePixels(); - - //get data - void getPixel(int x, int y, uint8 *value) const; - void getPixel(int x, int y, float32 *value) const; - void getComponent(int x, int y, int component, uint8 &value) const; - void getComponent(int x, int y, int component, float32 &value) const; + public: + //constructor & destructor + Pixmap2D(); + Pixmap2D(int components); + Pixmap2D(int w, int h, int components); + void init(int components); + void init(int w, int h, int components); + ~Pixmap2D(); - //vector get - Vec4f getPixel4f(int x, int y) const; - Vec3f getPixel3f(int x, int y) const; - float getPixelf(int x, int y) const; - float getComponentf(int x, int y, int component) const; + void Scale(int format, int newW, int newH); - //set data - void setPixel(int x, int y, const uint8 *value, int arraySize); - void setPixel(int x, int y, const float32 *value, int arraySize); - void setComponent(int x, int y, int component, uint8 value); - void setComponent(int x, int y, int component, float32 value); + //load & save + static Pixmap2D* loadPath(const string& path); + void load(const string &path); + /*void loadTga(const string &path); + void loadBmp(const string &path);*/ + void save(const string &path); + void saveBmp(const string &path); + void saveTga(const string &path); + void savePng(const string &path); + void saveJpg(const string &path); - //vector set - void setPixel(int x, int y, const Vec3f &p); - void setPixel(int x, int y, const Vec4f &p); - void setPixel(int x, int y, float p); - - //mass set - void setPixels(const uint8 *value, int arraySize); - void setPixels(const float32 *value, int arraySize); - void setComponents(int component, uint8 value); - void setComponents(int component, float32 value); + //get + int getW() const { + return w; + } + int getH() const { + return h; + } + int getComponents() const { + return components; + } + uint8 *getPixels() const { + return pixels; + } + void deletePixels(); - //operations - void splat(const Pixmap2D *leftUp, const Pixmap2D *rightUp, const Pixmap2D *leftDown, const Pixmap2D *rightDown); - void lerp(float t, const Pixmap2D *pixmap1, const Pixmap2D *pixmap2); - void copy(const Pixmap2D *sourcePixmap); - void subCopy(int x, int y, const Pixmap2D *sourcePixmap); - void copyImagePart(int x, int y, const Pixmap2D *sourcePixmap); - string getPath() const { return path;} - std::size_t getPixelByteCount() const; + //get data + void getPixel(int x, int y, uint8 *value) const; + void getPixel(int x, int y, float32 *value) const; + void getComponent(int x, int y, int component, uint8 &value) const; + void getComponent(int x, int y, int component, float32 &value) const; - Checksum * getCRC() { return &crc; } + //vector get + Vec4f getPixel4f(int x, int y) const; + Vec3f getPixel3f(int x, int y) const; + float getPixelf(int x, int y) const; + float getComponentf(int x, int y, int component) const; -private: - bool doDimensionsAgree(const Pixmap2D *pixmap); -}; + //set data + void setPixel(int x, int y, const uint8 *value, int arraySize); + void setPixel(int x, int y, const float32 *value, int arraySize); + void setComponent(int x, int y, int component, uint8 value); + void setComponent(int x, int y, int component, float32 value); -// ===================================================== -// class Pixmap3D -// ===================================================== + //vector set + void setPixel(int x, int y, const Vec3f &p); + void setPixel(int x, int y, const Vec4f &p); + void setPixel(int x, int y, float p); -class Pixmap3D { -protected: - int h; - int w; - int d; - int components; - int slice; - uint8 *pixels; - string path; - Checksum crc; + //mass set + void setPixels(const uint8 *value, int arraySize); + void setPixels(const float32 *value, int arraySize); + void setComponents(int component, uint8 value); + void setComponents(int component, float32 value); -public: - //constructor & destructor - Pixmap3D(); - Pixmap3D(int w, int h, int d, int components); - Pixmap3D(int d, int components); - void init(int w, int h, int d, int components); - void init(int d, int components); - void init(int components); - ~Pixmap3D(); - - //load & save - void loadSlice(const string &path, int slice); - void loadSliceBmp(const string &path, int slice); - void loadSliceTga(const string &path, int slice); - void loadSlicePng(const string &path, int slice); - - //get - int getSlice() const { return slice; } - int getW() const {return w;} - int getH() const {return h;} - int getD() const {return d;} - int getComponents() const {return components;} - uint8 *getPixels() const {return pixels;} - void deletePixels(); - string getPath() const { return path;} - std::size_t getPixelByteCount() const; + //operations + void splat(const Pixmap2D *leftUp, const Pixmap2D *rightUp, const Pixmap2D *leftDown, const Pixmap2D *rightDown); + void lerp(float t, const Pixmap2D *pixmap1, const Pixmap2D *pixmap2); + void copy(const Pixmap2D *sourcePixmap); + void subCopy(int x, int y, const Pixmap2D *sourcePixmap); + void copyImagePart(int x, int y, const Pixmap2D *sourcePixmap); + string getPath() const { + return path; + } + std::size_t getPixelByteCount() const; - Checksum * getCRC() { return &crc; } -}; + Checksum * getCRC() { + return &crc; + } -// ===================================================== -// class PixmapCube -// ===================================================== + private: + bool doDimensionsAgree(const Pixmap2D *pixmap); + }; -class PixmapCube { -public: - enum Face{ - fPositiveX, - fNegativeX, - fPositiveY, - fNegativeY, - fPositiveZ, - fNegativeZ - }; + // ===================================================== + // class Pixmap3D + // ===================================================== -protected: - Pixmap2D faces[6]; - string path[6]; - Checksum crc; + class Pixmap3D { + protected: + int h; + int w; + int d; + int components; + int slice; + uint8 *pixels; + string path; + Checksum crc; -public: - PixmapCube(); - ~PixmapCube(); + public: + //constructor & destructor + Pixmap3D(); + Pixmap3D(int w, int h, int d, int components); + Pixmap3D(int d, int components); + void init(int w, int h, int d, int components); + void init(int d, int components); + void init(int components); + ~Pixmap3D(); - //init - void init(int w, int h, int components); - void init(int components); + //load & save + void loadSlice(const string &path, int slice); + void loadSliceBmp(const string &path, int slice); + void loadSliceTga(const string &path, int slice); + void loadSlicePng(const string &path, int slice); - //load & save - void loadFace(const string &path, int face); - /*void loadFaceBmp(const string &path, int face); - void loadFaceTga(const string &path, int face);*/ - - //get - Pixmap2D *getFace(int face) {return &faces[face];} - const Pixmap2D *getFace(int face) const {return &faces[face];} - void deletePixels(); - string getPath(int face) const { return path[face];} - std::size_t getPixelByteCount() const; + //get + int getSlice() const { + return slice; + } + int getW() const { + return w; + } + int getH() const { + return h; + } + int getD() const { + return d; + } + int getComponents() const { + return components; + } + uint8 *getPixels() const { + return pixels; + } + void deletePixels(); + string getPath() const { + return path; + } + std::size_t getPixelByteCount() const; - Checksum * getCRC() { return &crc; } -}; + Checksum * getCRC() { + return &crc; + } + }; -}}//end namespace + // ===================================================== + // class PixmapCube + // ===================================================== + + class PixmapCube { + public: + enum Face { + fPositiveX, + fNegativeX, + fPositiveY, + fNegativeY, + fPositiveZ, + fNegativeZ + }; + + protected: + Pixmap2D faces[6]; + string path[6]; + Checksum crc; + + public: + PixmapCube(); + ~PixmapCube(); + + //init + void init(int w, int h, int components); + void init(int components); + + //load & save + void loadFace(const string &path, int face); + /*void loadFaceBmp(const string &path, int face); + void loadFaceTga(const string &path, int face);*/ + + //get + Pixmap2D *getFace(int face) { + return &faces[face]; + } + const Pixmap2D *getFace(int face) const { + return &faces[face]; + } + void deletePixels(); + string getPath(int face) const { + return path[face]; + } + std::size_t getPixelByteCount() const; + + Checksum * getCRC() { + return &crc; + } + }; + + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/quaternion.h b/source/shared_lib/include/graphics/quaternion.h index 2e8c61839..6d70c569a 100644 --- a/source/shared_lib/include/graphics/quaternion.h +++ b/source/shared_lib/include/graphics/quaternion.h @@ -20,85 +20,87 @@ using namespace std; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class AxisAngle -// ===================================================== + // ===================================================== + // class AxisAngle + // ===================================================== -class AxisAngle{ -public: - Vec3f axis; - float angle; + class AxisAngle { + public: + Vec3f axis; + float angle; + + AxisAngle() { + angle = 0.0f; + } + AxisAngle(const Vec3f &axis, float angle); + }; + + // ===================================================== + // class EulerAngles + // ===================================================== + + class EulerAngles { + public: + float x, y, z; + + EulerAngles() { + x = 0.0f; + y = 0.0f; + z = 0.0f; + } + EulerAngles(float x, float y, float z); + }; + + // ===================================================== + // class Quaternion + // ===================================================== + + class Quaternion { + private: + float w; + Vec3f v; + + public: + Quaternion(); + Quaternion(float w, const Vec3f &v); + Quaternion(const EulerAngles &eulerAngles); + //Quaternion(const AxisAngle &axisAngle); + + //initializers + void setMultIdentity(); + void setAddIdentity(); + void setAxisAngle(const AxisAngle &axisAngle); + void setEuler(const EulerAngles &eulerAngles); + + //unary operators + //float length(); + Quaternion conjugate(); + //void normalize(); + + //binary operators + Quaternion operator + (const Quaternion &q) const; + Quaternion operator * (const Quaternion &q) const; + void operator += (const Quaternion &q); + void operator *= (const Quaternion &q); + + //ternary operators + Quaternion lerp(float t, const Quaternion &q) const; + + //conversions + Matrix3f toMatrix3() const; + Matrix4f toMatrix4() const; + //AxisAngle toAxisAngle() const; + + //local axis + Vec3f getLocalXAxis() const; + Vec3f getLocalYAxis() const; + Vec3f getLocalZAxis() const; + }; - AxisAngle() { - angle = 0.0f; } - AxisAngle(const Vec3f &axis, float angle); -}; - -// ===================================================== -// class EulerAngles -// ===================================================== - -class EulerAngles{ -public: - float x, y, z; - - EulerAngles() { - x = 0.0f; - y = 0.0f; - z = 0.0f; - } - EulerAngles(float x, float y, float z); -}; - -// ===================================================== -// class Quaternion -// ===================================================== - -class Quaternion{ -private: - float w; - Vec3f v; - -public: - Quaternion(); - Quaternion(float w, const Vec3f &v); - Quaternion(const EulerAngles &eulerAngles); - //Quaternion(const AxisAngle &axisAngle); - - //initializers - void setMultIdentity(); - void setAddIdentity(); - void setAxisAngle(const AxisAngle &axisAngle); - void setEuler(const EulerAngles &eulerAngles); - - //unary operators - //float length(); - Quaternion conjugate(); - //void normalize(); - - //binary operators - Quaternion operator + (const Quaternion &q) const; - Quaternion operator * (const Quaternion &q) const; - void operator += (const Quaternion &q); - void operator *= (const Quaternion &q); - - //ternary operators - Quaternion lerp(float t, const Quaternion &q) const; - - //conversions - Matrix3f toMatrix3() const; - Matrix4f toMatrix4() const; - //AxisAngle toAxisAngle() const; - - //local axis - Vec3f getLocalXAxis() const; - Vec3f getLocalYAxis() const; - Vec3f getLocalZAxis() const; -}; - -}}//end namespace +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/shader.h b/source/shared_lib/include/graphics/shader.h index 0ec8866c6..b2995422c 100644 --- a/source/shared_lib/include/graphics/shader.h +++ b/source/shared_lib/include/graphics/shader.h @@ -17,71 +17,79 @@ #include "texture.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class ShaderProgram -// ===================================================== + // ===================================================== + // class ShaderProgram + // ===================================================== -class VertexShader; -class FragmentShader; + class VertexShader; + class FragmentShader; -class ShaderProgram{ -public: - virtual ~ShaderProgram(){} - virtual void init()= 0; - virtual void end()= 0; + class ShaderProgram { + public: + virtual ~ShaderProgram() { + } + virtual void init() = 0; + virtual void end() = 0; - virtual void attach(VertexShader *vs, FragmentShader *fs)= 0; - virtual bool link(string &messages)= 0; - virtual void activate()= 0; - virtual void deactivate()= 0; + virtual void attach(VertexShader *vs, FragmentShader *fs) = 0; + virtual bool link(string &messages) = 0; + virtual void activate() = 0; + virtual void deactivate() = 0; - virtual void setUniform(const string &name, int value)= 0; - virtual void setUniform(const string &name, float value)= 0; - virtual void setUniform(const string &name, const Vec2f &value)= 0; - virtual void setUniform(const string &name, const Vec3f &value)= 0; - virtual void setUniform(const string &name, const Vec4f &value)= 0; - virtual void setUniform(const string &name, const Matrix3f &value)= 0; - virtual void setUniform(const string &name, const Matrix4f &value)= 0; -}; + virtual void setUniform(const string &name, int value) = 0; + virtual void setUniform(const string &name, float value) = 0; + virtual void setUniform(const string &name, const Vec2f &value) = 0; + virtual void setUniform(const string &name, const Vec3f &value) = 0; + virtual void setUniform(const string &name, const Vec4f &value) = 0; + virtual void setUniform(const string &name, const Matrix3f &value) = 0; + virtual void setUniform(const string &name, const Matrix4f &value) = 0; + }; -// ===================================================== -// class Shader -// ===================================================== + // ===================================================== + // class Shader + // ===================================================== -class Shader{ -public: - virtual ~Shader(){} - virtual void init()= 0; - virtual void end()= 0; + class Shader { + public: + virtual ~Shader() { + } + virtual void init() = 0; + virtual void end() = 0; - virtual void load(const string &path)= 0; - virtual bool compile(string &messages)= 0; -}; + virtual void load(const string &path) = 0; + virtual bool compile(string &messages) = 0; + }; -class VertexShader: virtual public Shader{ -}; + class VertexShader : virtual public Shader { + }; -class FragmentShader: virtual public Shader{ -}; + class FragmentShader : virtual public Shader { + }; -// ===================================================== -// class ShaderSource -// ===================================================== + // ===================================================== + // class ShaderSource + // ===================================================== -class ShaderSource{ -private: - string pathInfo; - string code; + class ShaderSource { + private: + string pathInfo; + string code; -public: - const string &getPathInfo() const {return pathInfo;} - const string &getCode() const {return code;} + public: + const string &getPathInfo() const { + return pathInfo; + } + const string &getCode() const { + return code; + } - void load(const string &path); -}; + void load(const string &path); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/shader_manager.h b/source/shared_lib/include/graphics/shader_manager.h index d6b070f8a..f804f9dca 100644 --- a/source/shared_lib/include/graphics/shader_manager.h +++ b/source/shared_lib/include/graphics/shader_manager.h @@ -18,36 +18,40 @@ using namespace std; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class ShaderManager -// ===================================================== + // ===================================================== + // class ShaderManager + // ===================================================== -class ShaderManager{ -protected: - typedef vector ShaderProgramContainer; - typedef vector ShaderContainer; + class ShaderManager { + protected: + typedef vector ShaderProgramContainer; + typedef vector ShaderContainer; -protected: - ShaderProgramContainer shaderPrograms; - ShaderContainer shaders; - string logString; + protected: + ShaderProgramContainer shaderPrograms; + ShaderContainer shaders; + string logString; -public: - ShaderManager(); - virtual ~ShaderManager(); + public: + ShaderManager(); + virtual ~ShaderManager(); - ShaderProgram *newShaderProgram(); - VertexShader *newVertexShader(); - FragmentShader *newFragmentShader(); + ShaderProgram *newShaderProgram(); + VertexShader *newVertexShader(); + FragmentShader *newFragmentShader(); - void init(); - void end(); + void init(); + void end(); - const string &getLogString() const {return logString;} -}; + const string &getLogString() const { + return logString; + } + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/text_renderer.h b/source/shared_lib/include/graphics/text_renderer.h index 683d0fcaf..2ccf17a06 100644 --- a/source/shared_lib/include/graphics/text_renderer.h +++ b/source/shared_lib/include/graphics/text_renderer.h @@ -19,42 +19,47 @@ using std::string; -namespace Shared { namespace Graphics { +namespace Shared { + namespace Graphics { -// ===================================================== -// class TextRenderer2D -// ===================================================== + // ===================================================== + // class TextRenderer2D + // ===================================================== -class TextRenderer { -public: - virtual void render(const string &text, float x, float y, bool centered=false, Vec3f *color=NULL) = 0; - virtual void end()= 0; + class TextRenderer { + public: + virtual void render(const string &text, float x, float y, bool centered = false, Vec3f *color = NULL) = 0; + virtual void end() = 0; - virtual ~TextRenderer() {} -}; + virtual ~TextRenderer() { + } + }; -class TextRenderer2D : public TextRenderer { -public: - virtual ~TextRenderer2D(){}; + class TextRenderer2D : public TextRenderer { + public: + virtual ~TextRenderer2D() { + }; - virtual void begin(Font2D *font)= 0; - //virtual void render(const string &text, int x, int y, bool centered= false,Vec3f *color=NULL)= 0; - //virtual void end()= 0; -}; + virtual void begin(Font2D *font) = 0; + //virtual void render(const string &text, int x, int y, bool centered= false,Vec3f *color=NULL)= 0; + //virtual void end()= 0; + }; -// ===================================================== -// class TextRenderer3D -// ===================================================== + // ===================================================== + // class TextRenderer3D + // ===================================================== -class TextRenderer3D : public TextRenderer { -public: - virtual ~TextRenderer3D(){}; + class TextRenderer3D : public TextRenderer { + public: + virtual ~TextRenderer3D() { + }; - virtual void begin(Font3D *font)= 0; - //virtual void render(const string &text, float x, float y, bool centered= false,Vec3f *color=NULL)= 0; - //virtual void end()= 0; -}; + virtual void begin(Font3D *font) = 0; + //virtual void render(const string &text, float x, float y, bool centered= false,Vec3f *color=NULL)= 0; + //virtual void end()= 0; + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/texture.h b/source/shared_lib/include/graphics/texture.h index 93a40feb8..a9791d73b 100644 --- a/source/shared_lib/include/graphics/texture.h +++ b/source/shared_lib/include/graphics/texture.h @@ -22,178 +22,257 @@ using Shared::Platform::uint8; struct SDL_Surface; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -class TextureParams; + class TextureParams; -// ===================================================== -// class Texture -// ===================================================== + // ===================================================== + // class Texture + // ===================================================== -class Texture { -public: - static const int defaultSize; - static const int defaultComponents; - static bool useTextureCompression; + class Texture { + public: + static const int defaultSize; + static const int defaultComponents; + static bool useTextureCompression; - enum WrapMode{ - wmRepeat, - wmClamp, - wmClampToEdge - }; + enum WrapMode { + wmRepeat, + wmClamp, + wmClampToEdge + }; - enum Filter{ - fBilinear, - fTrilinear - }; + enum Filter { + fBilinear, + fTrilinear + }; - enum Format{ - fAuto, - fAlpha, - fLuminance, - fRgb, - fRgba - }; + enum Format { + fAuto, + fAlpha, + fLuminance, + fRgb, + fRgba + }; -protected: - string path; - bool mipmap; - WrapMode wrapMode; - bool pixmapInit; - Format format; + protected: + string path; + bool mipmap; + WrapMode wrapMode; + bool pixmapInit; + Format format; - bool inited; - bool forceCompressionDisabled; - int textureSystemId; + bool inited; + bool forceCompressionDisabled; + int textureSystemId; -public: - Texture(); - virtual ~Texture(){}; - - bool getMipmap() const {return mipmap;} - WrapMode getWrapMode() const {return wrapMode;} - bool getPixmapInit() const {return pixmapInit;} - Format getFormat() const {return format;} - bool getInited() const {return inited;} + public: + Texture(); + virtual ~Texture() { + }; - int getTextureSystemId() const { return textureSystemId; } - void setTextureSystemId(int id) { textureSystemId = id; } + bool getMipmap() const { + return mipmap; + } + WrapMode getWrapMode() const { + return wrapMode; + } + bool getPixmapInit() const { + return pixmapInit; + } + Format getFormat() const { + return format; + } + bool getInited() const { + return inited; + } - void setMipmap(bool mipmap) {this->mipmap= mipmap;} - void setWrapMode(WrapMode wrapMode) {this->wrapMode= wrapMode;} - void setPixmapInit(bool pixmapInit) {this->pixmapInit= pixmapInit;} - void setFormat(Format format) {this->format= format;} + int getTextureSystemId() const { + return textureSystemId; + } + void setTextureSystemId(int id) { + textureSystemId = id; + } - virtual void init(Filter filter= fBilinear, int maxAnisotropy= 1)=0; - virtual void end(bool deletePixelBuffer=true)=0; - virtual string getPath() const = 0; - virtual void deletePixels() = 0; - virtual std::size_t getPixelByteCount() const = 0; + void setMipmap(bool mipmap) { + this->mipmap = mipmap; + } + void setWrapMode(WrapMode wrapMode) { + this->wrapMode = wrapMode; + } + void setPixmapInit(bool pixmapInit) { + this->pixmapInit = pixmapInit; + } + void setFormat(Format format) { + this->format = format; + } - virtual void reseInitState() { inited = false; } + virtual void init(Filter filter = fBilinear, int maxAnisotropy = 1) = 0; + virtual void end(bool deletePixelBuffer = true) = 0; + virtual string getPath() const = 0; + virtual void deletePixels() = 0; + virtual std::size_t getPixelByteCount() const = 0; - virtual void setForceCompressionDisabled(bool value) { forceCompressionDisabled = value;} - virtual bool getForceCompressionDisabled() const {return forceCompressionDisabled;} + virtual void reseInitState() { + inited = false; + } - virtual uint32 getCRC() = 0; + virtual void setForceCompressionDisabled(bool value) { + forceCompressionDisabled = value; + } + virtual bool getForceCompressionDisabled() const { + return forceCompressionDisabled; + } -}; + virtual uint32 getCRC() = 0; -// ===================================================== -// class Texture1D -// ===================================================== + }; -class Texture1D: public Texture { -protected: - Pixmap1D pixmap; + // ===================================================== + // class Texture1D + // ===================================================== -public: - void load(const string &path); + class Texture1D : public Texture { + protected: + Pixmap1D pixmap; - Pixmap1D *getPixmap() {return &pixmap;} - const Pixmap1D *getPixmap() const {return &pixmap;} - virtual string getPath() const; - virtual void deletePixels(); - virtual std::size_t getPixelByteCount() const {return pixmap.getPixelByteCount();} + public: + void load(const string &path); - virtual int getTextureWidth() const {return pixmap.getW();} - virtual int getTextureHeight() const {return -1;} + Pixmap1D *getPixmap() { + return &pixmap; + } + const Pixmap1D *getPixmap() const { + return &pixmap; + } + virtual string getPath() const; + virtual void deletePixels(); + virtual std::size_t getPixelByteCount() const { + return pixmap.getPixelByteCount(); + } - virtual uint32 getCRC() { return pixmap.getCRC()->getSum(); } -}; + virtual int getTextureWidth() const { + return pixmap.getW(); + } + virtual int getTextureHeight() const { + return -1; + } -// ===================================================== -// class Texture2D -// ===================================================== + virtual uint32 getCRC() { + return pixmap.getCRC()->getSum(); + } + }; -class Texture2D: public Texture { -protected: - Pixmap2D pixmap; + // ===================================================== + // class Texture2D + // ===================================================== -public: - void load(const string &path); + class Texture2D : public Texture { + protected: + Pixmap2D pixmap; - Pixmap2D *getPixmap() {return &pixmap;} - const Pixmap2D *getPixmapConst() const {return &pixmap;} - virtual string getPath() const; - virtual void deletePixels(); - virtual std::size_t getPixelByteCount() const {return pixmap.getPixelByteCount();} + public: + void load(const string &path); - virtual int getTextureWidth() const {return pixmap.getW();} - virtual int getTextureHeight() const {return pixmap.getH();} + Pixmap2D *getPixmap() { + return &pixmap; + } + const Pixmap2D *getPixmapConst() const { + return &pixmap; + } + virtual string getPath() const; + virtual void deletePixels(); + virtual std::size_t getPixelByteCount() const { + return pixmap.getPixelByteCount(); + } - virtual uint32 getCRC() { return pixmap.getCRC()->getSum(); } + virtual int getTextureWidth() const { + return pixmap.getW(); + } + virtual int getTextureHeight() const { + return pixmap.getH(); + } - std::pair CreateSDLSurface(bool newPixelData) const; -}; + virtual uint32 getCRC() { + return pixmap.getCRC()->getSum(); + } -// ===================================================== -// class Texture3D -// ===================================================== + std::pair CreateSDLSurface(bool newPixelData) const; + }; -class Texture3D: public Texture { -protected: - Pixmap3D pixmap; + // ===================================================== + // class Texture3D + // ===================================================== -public: - void loadSlice(const string &path, int slice); + class Texture3D : public Texture { + protected: + Pixmap3D pixmap; - Pixmap3D *getPixmap() {return &pixmap;} - const Pixmap3D *getPixmap() const {return &pixmap;} - virtual string getPath() const; - virtual void deletePixels(); - virtual std::size_t getPixelByteCount() const {return pixmap.getPixelByteCount();} + public: + void loadSlice(const string &path, int slice); - virtual int getTextureWidth() const {return pixmap.getW();} - virtual int getTextureHeight() const {return pixmap.getH();} + Pixmap3D *getPixmap() { + return &pixmap; + } + const Pixmap3D *getPixmap() const { + return &pixmap; + } + virtual string getPath() const; + virtual void deletePixels(); + virtual std::size_t getPixelByteCount() const { + return pixmap.getPixelByteCount(); + } - virtual uint32 getCRC() { return pixmap.getCRC()->getSum(); } -}; + virtual int getTextureWidth() const { + return pixmap.getW(); + } + virtual int getTextureHeight() const { + return pixmap.getH(); + } -// ===================================================== -// class TextureCube -// ===================================================== + virtual uint32 getCRC() { + return pixmap.getCRC()->getSum(); + } + }; -class TextureCube: public Texture{ -protected: - PixmapCube pixmap; + // ===================================================== + // class TextureCube + // ===================================================== -public: - void loadFace(const string &path, int face); + class TextureCube : public Texture { + protected: + PixmapCube pixmap; - PixmapCube *getPixmap() {return &pixmap;} - const PixmapCube *getPixmap() const {return &pixmap;} - virtual string getPath() const; - virtual void deletePixels(); - virtual std::size_t getPixelByteCount() const {return pixmap.getPixelByteCount();} + public: + void loadFace(const string &path, int face); - virtual int getTextureWidth() const {return -1;} - virtual int getTextureHeight() const {return -1;} + PixmapCube *getPixmap() { + return &pixmap; + } + const PixmapCube *getPixmap() const { + return &pixmap; + } + virtual string getPath() const; + virtual void deletePixels(); + virtual std::size_t getPixelByteCount() const { + return pixmap.getPixelByteCount(); + } - virtual uint32 getCRC() { return pixmap.getCRC()->getSum(); } -}; + virtual int getTextureWidth() const { + return -1; + } + virtual int getTextureHeight() const { + return -1; + } -}}//end namespace + virtual uint32 getCRC() { + return pixmap.getCRC()->getSum(); + } + }; + + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/texture_manager.h b/source/shared_lib/include/graphics/texture_manager.h index ae956c197..fd6e53bfc 100644 --- a/source/shared_lib/include/graphics/texture_manager.h +++ b/source/shared_lib/include/graphics/texture_manager.h @@ -18,48 +18,56 @@ using std::vector; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class TextureManager -// ===================================================== -typedef vector TextureContainer; + // ===================================================== + // class TextureManager + // ===================================================== + typedef vector TextureContainer; -//manages textures, creation on request and deletion on destruction -class TextureManager{ - -protected: - TextureContainer textures; - - Texture::Filter textureFilter; - int maxAnisotropy; + //manages textures, creation on request and deletion on destruction + class TextureManager { -public: - TextureManager(); - ~TextureManager(); - void init(bool forceInit=false); - void end(); + protected: + TextureContainer textures; - void setFilter(Texture::Filter textureFilter); - void setMaxAnisotropy(int maxAnisotropy); - void initTexture(Texture *texture); - void endTexture(Texture *texture,bool mustExistInList=false); - void endLastTexture(bool mustExistInList=false); - void reinitTextures(); + Texture::Filter textureFilter; + int maxAnisotropy; - Texture::Filter getTextureFilter() const {return textureFilter;} - int getMaxAnisotropy() const {return maxAnisotropy;} + public: + TextureManager(); + ~TextureManager(); + void init(bool forceInit = false); + void end(); - Texture *getTexture(const string &path); - Texture1D *newTexture1D(); - Texture2D *newTexture2D(); - Texture3D *newTexture3D(); - TextureCube *newTextureCube(); + void setFilter(Texture::Filter textureFilter); + void setMaxAnisotropy(int maxAnisotropy); + void initTexture(Texture *texture); + void endTexture(Texture *texture, bool mustExistInList = false); + void endLastTexture(bool mustExistInList = false); + void reinitTextures(); - const TextureContainer &getTextures() const {return textures;} -}; + Texture::Filter getTextureFilter() const { + return textureFilter; + } + int getMaxAnisotropy() const { + return maxAnisotropy; + } + + Texture *getTexture(const string &path); + Texture1D *newTexture1D(); + Texture2D *newTexture2D(); + Texture3D *newTexture3D(); + TextureCube *newTextureCube(); + + const TextureContainer &getTextures() const { + return textures; + } + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/graphics/vec.h b/source/shared_lib/include/graphics/vec.h index 176a613e0..478816e05 100644 --- a/source/shared_lib/include/graphics/vec.h +++ b/source/shared_lib/include/graphics/vec.h @@ -31,831 +31,826 @@ using namespace std; using namespace Shared::Platform; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -template -inline T truncateDecimal(const T &value, int precision=6) { - T precNum = 0; - if(precision == 0) { - precNum = 1; - } - else if(precision == 1) { - precNum = 10; - } - else if(precision == 2) { - precNum = 100; - } - else if(precision == 3) { - precNum = 1000; - } - else if(precision == 4) { - precNum = 10000; - } - else if(precision == 5) { - precNum = 100000; - } - else if(precision == 6) { - precNum = 1000000; - } - else { - precNum = std::pow((T)10,(T)precision); - } + template + inline T truncateDecimal(const T &value, int precision = 6) { + T precNum = 0; + if (precision == 0) { + precNum = 1; + } else if (precision == 1) { + precNum = 10; + } else if (precision == 2) { + precNum = 100; + } else if (precision == 3) { + precNum = 1000; + } else if (precision == 4) { + precNum = 10000; + } else if (precision == 5) { + precNum = 100000; + } else if (precision == 6) { + precNum = 1000000; + } else { + precNum = std::pow((T) 10, (T) precision); + } - // See if we can avoid using an int64 for speed -// To avoid stupid VC++ compiler error: illegal token on right side of '::' -//#ifdef WIN32 -//#undef max -//#endif -// static int MAX_INT_VALUE = numeric_limits::max(); -// if((T)value * (T)precNum <= MAX_INT_VALUE) { -// int resultInt = (int)((T)value * (T)precNum); -// T result = (T)resultInt / precNum; -// //printf("=======================\nvalue = %.10f\nresultInt: %d\nprecision: %d\nbecame: %.10f\n----------\n",value,resultInt,precision,result); -// return result; -// } + // See if we can avoid using an int64 for speed + // To avoid stupid VC++ compiler error: illegal token on right side of '::' + //#ifdef WIN32 + //#undef max + //#endif + // static int MAX_INT_VALUE = numeric_limits::max(); + // if((T)value * (T)precNum <= MAX_INT_VALUE) { + // int resultInt = (int)((T)value * (T)precNum); + // T result = (T)resultInt / precNum; + // //printf("=======================\nvalue = %.10f\nresultInt: %d\nprecision: %d\nbecame: %.10f\n----------\n",value,resultInt,precision,result); + // return result; + // } - // Must use an int64 since the result is large - int64 resultInt = (int64)((T)value * (T)precNum); - T result = (T)((long double)resultInt / precNum); - return result; -} - -inline std::vector TokenizeString(const std::string str,const std::string delimiters) { - std::vector tokens; - // Assume textLine contains the line of text to parse. - std::string textLine = str; - - std::size_t pos = 0; - while( true ) { - std::size_t nextPos = textLine.find( delimiters, pos ); - if( nextPos == textLine.npos ) { - tokens.push_back(textLine.substr(pos, textLine.length( ))); - break; + // Must use an int64 since the result is large + int64 resultInt = (int64) ((T) value * (T) precNum); + T result = (T) ((long double) resultInt / precNum); + return result; } - tokens.push_back( std::string( textLine.substr( pos, nextPos - pos ) ) ); - pos = nextPos + 1; - } - return tokens; -} + inline std::vector TokenizeString(const std::string str, const std::string delimiters) { + std::vector tokens; + // Assume textLine contains the line of text to parse. + std::string textLine = str; -template -inline T strToType(const std::string &s) { - char *endChar=NULL; + std::size_t pos = 0; + while (true) { + std::size_t nextPos = textLine.find(delimiters, pos); + if (nextPos == textLine.npos) { + tokens.push_back(textLine.substr(pos, textLine.length())); + break; + } + tokens.push_back(std::string(textLine.substr(pos, nextPos - pos))); + pos = nextPos + 1; + } - setlocale(LC_NUMERIC, "C"); - T value= static_cast(strtod(s.c_str(), &endChar)); - - if(*endChar!='\0'){ - throw std::runtime_error("Error converting from string to type, found: [" + s + "]"); - } - - return value; -} - - -template class Vec2; -template class Vec3; -template class Vec4; - -template -void toEndianVecArray(T *vec, size_t size) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - for(size_t i = 0; i < size; ++i) { - vec[i].toEndian(); + return tokens; } - } -} -template -void fromEndianVecArray(T *vec, size_t size) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - for(size_t i = 0; i < size; ++i) { - vec[i].fromEndian(); + + template + inline T strToType(const std::string &s) { + char *endChar = NULL; + + setlocale(LC_NUMERIC, "C"); + T value = static_cast(strtod(s.c_str(), &endChar)); + + if (*endChar != '\0') { + throw std::runtime_error("Error converting from string to type, found: [" + s + "]"); + } + + return value; } - } -} -// ===================================================== -// class Vec2 -// ===================================================== -template -class Vec2{ -public: - T x; - T y; + template class Vec2; + template class Vec3; + template class Vec4; -public: - Vec2(){ - x = 0; - y = 0; - }; + template + void toEndianVecArray(T *vec, size_t size) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + for (size_t i = 0; i < size; ++i) { + vec[i].toEndian(); + } + } + } + template + void fromEndianVecArray(T *vec, size_t size) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + for (size_t i = 0; i < size; ++i) { + vec[i].fromEndian(); + } + } + } - explicit Vec2(T *p){ - this->x= p[0]; - this->y= p[1]; - } + // ===================================================== + // class Vec2 + // ===================================================== - explicit Vec2(T xy){ - this->x= xy; - this->y= xy; - } + template + class Vec2 { + public: + T x; + T y; - template - explicit Vec2(const Vec2 &v){ - this->x= v.x; - this->y= v.y; - } - template - explicit Vec2(Vec2 &v){ - this->x= v.x; - this->y= v.y; - } + public: + Vec2() { + x = 0; + y = 0; + }; - Vec2(T x, T y){ - this->x= x; - this->y= y; - } + explicit Vec2(T *p) { + this->x = p[0]; + this->y = p[1]; + } - //template - //size_t operator()(const Vec2 &v) const { - // return hash()(v.x) ^ hash()(v.y); - //} - //template - //bool operator()(const Vec2 &a, const Vec2 &b) const { - // return a == b; - //} + explicit Vec2(T xy) { + this->x = xy; + this->y = xy; + } - inline T *ptr(){ - return reinterpret_cast(this); - } + template + explicit Vec2(const Vec2 &v) { + this->x = v.x; + this->y = v.y; + } + template + explicit Vec2(Vec2 &v) { + this->x = v.x; + this->y = v.y; + } - inline const T *ptr() const { - return reinterpret_cast(this); - } + Vec2(T x, T y) { + this->x = x; + this->y = y; + } - inline Vec2 & operator=(const Vec2 &v) { - this->x= v.x; - this->y= v.y; - return *this; - } + //template + //size_t operator()(const Vec2 &v) const { + // return hash()(v.x) ^ hash()(v.y); + //} + //template + //bool operator()(const Vec2 &a, const Vec2 &b) const { + // return a == b; + //} - inline bool operator ==(const Vec2 &v) const{ - return x==v.x && y==v.y; - } + inline T *ptr() { + return reinterpret_cast(this); + } - inline bool operator !=(const Vec2 &v) const{ - return x!=v.x || y!=v.y; - } + inline const T *ptr() const { + return reinterpret_cast(this); + } - inline Vec2 operator +(const Vec2 &v) const{ - return Vec2(x+v.x, y+v.y); - } + inline Vec2 & operator=(const Vec2 &v) { + this->x = v.x; + this->y = v.y; + return *this; + } - inline Vec2 operator -(const Vec2 &v) const{ - return Vec2(x-v.x, y-v.y); - } + inline bool operator ==(const Vec2 &v) const { + return x == v.x && y == v.y; + } - inline Vec2 operator -() const{ - return Vec2(-x, -y); - } + inline bool operator !=(const Vec2 &v) const { + return x != v.x || y != v.y; + } - inline Vec2 operator *(const Vec2 &v) const{ - return Vec2(x*v.x, y*v.y); - } + inline Vec2 operator +(const Vec2 &v) const { + return Vec2(x + v.x, y + v.y); + } - inline Vec2 operator *(T s) const{ - return Vec2(x*s, y*s); - } + inline Vec2 operator -(const Vec2 &v) const { + return Vec2(x - v.x, y - v.y); + } - inline Vec2 operator /(const Vec2 &v) const{ - return Vec2(x/v.x, y/v.y); - } + inline Vec2 operator -() const { + return Vec2(-x, -y); + } - inline Vec2 operator /(T s) const{ - return Vec2(x/s, y/s); - } + inline Vec2 operator *(const Vec2 &v) const { + return Vec2(x*v.x, y*v.y); + } - inline Vec2 operator +=(const Vec2 &v){ - x+=v.x; - y+=v.y; - return *this; - } + inline Vec2 operator *(T s) const { + return Vec2(x*s, y*s); + } - inline Vec2 operator -=(const Vec2 &v){ - x-=v.x; - y-=v.y; - return *this; - } + inline Vec2 operator /(const Vec2 &v) const { + return Vec2(x / v.x, y / v.y); + } - inline Vec2 lerp(T t, const Vec2 &v) const{ - return *this + (v - *this)*t; - } + inline Vec2 operator /(T s) const { + return Vec2(x / s, y / s); + } - inline T dot(const Vec2 &v) const{ - return x*v.x+y*v.y; - } + inline Vec2 operator +=(const Vec2 &v) { + x += v.x; + y += v.y; + return *this; + } - inline float dist(const Vec2 &v) const{ - float distance = Vec2(v-*this).length(); - return distance; - } + inline Vec2 operator -=(const Vec2 &v) { + x -= v.x; + y -= v.y; + return *this; + } - // strict week ordering, so Vec2 can be used as key for set<> or map<> - inline bool operator<(const Vec2 &v) const { - return x < v.x || (x == v.x && y < v.y); - } + inline Vec2 lerp(T t, const Vec2 &v) const { + return *this + (v - *this)*t; + } - inline float length() const { + inline T dot(const Vec2 &v) const { + return x*v.x + y*v.y; + } + + inline float dist(const Vec2 &v) const { + float distance = Vec2(v - *this).length(); + return distance; + } + + // strict week ordering, so Vec2 can be used as key for set<> or map<> + inline bool operator<(const Vec2 &v) const { + return x < v.x || (x == v.x && y < v.y); + } + + inline float length() const { #ifdef USE_STREFLOP - float len = static_cast(streflop::sqrt(static_cast(x*x + y*y))); + float len = static_cast(streflop::sqrt(static_cast(x*x + y*y))); #else - float len = static_cast(std::sqrt(static_cast(x*x + y*y))); - len = truncateDecimal(len,6); + float len = static_cast(std::sqrt(static_cast(x*x + y*y))); + len = truncateDecimal(len, 6); #endif - return len; - } - - inline void normalize(){ - T m= length(); - x/= m; - y/= m; - } - - inline Vec2 rotate(float rad) { - float c = std::cos(rad), - s = std::sin(rad); - - return Vec2(x*c-y*s,x*s+y*c); - } - - inline Vec2 rotateAround(float rad,const Vec2& pt) { - return pt+(*this-pt).rotate(rad); - } - - inline std::string getString() const { - std::ostringstream streamOut; - streamOut << "x [" << x; - streamOut << "] y [" << y << "]"; - std::string result = streamOut.str(); - streamOut.str(std::string()); - return result; - } - // meetingPos="x [32] y [120]" - static inline Vec2 strToVec2(std::string value) { - Vec2 result; - - std::vector tokens = TokenizeString(value,"["); - //for(unsigned int i = 0; i < tokens.size(); ++i) { - //printf("#1 Vec2T i = %d [%s]\n",i,tokens[i].c_str()); - //} - if(tokens.size() == 3) { - std::vector tokens2 = TokenizeString(tokens[1],"]"); - //for(unsigned int i = 0; i < tokens2.size(); ++i) { - //printf("#2 Vec2T i = %d [%s]\n",i,tokens2[i].c_str()); - //} - std::vector tokens3 = TokenizeString(tokens[2],"]"); - //for(unsigned int i = 0; i < tokens3.size(); ++i) { - //printf("#3 Vec2T i = %d [%s]\n",i,tokens3[i].c_str()); - //} - - if(tokens2.size() == 2 && tokens3.size() == 2) { - result.x = (T)strToType(tokens2[0]); - result.y = (T)strToType(tokens3[0]); - - //printf("#3 Vec2T [%s]\n",result.getString().c_str()); + return len; } + + inline void normalize() { + T m = length(); + x /= m; + y /= m; + } + + inline Vec2 rotate(float rad) { + float c = std::cos(rad), + s = std::sin(rad); + + return Vec2(x*c - y*s, x*s + y*c); + } + + inline Vec2 rotateAround(float rad, const Vec2& pt) { + return pt + (*this - pt).rotate(rad); + } + + inline std::string getString() const { + std::ostringstream streamOut; + streamOut << "x [" << x; + streamOut << "] y [" << y << "]"; + std::string result = streamOut.str(); + streamOut.str(std::string()); + return result; + } + // meetingPos="x [32] y [120]" + static inline Vec2 strToVec2(std::string value) { + Vec2 result; + + std::vector tokens = TokenizeString(value, "["); + //for(unsigned int i = 0; i < tokens.size(); ++i) { + //printf("#1 Vec2T i = %d [%s]\n",i,tokens[i].c_str()); + //} + if (tokens.size() == 3) { + std::vector tokens2 = TokenizeString(tokens[1], "]"); + //for(unsigned int i = 0; i < tokens2.size(); ++i) { + //printf("#2 Vec2T i = %d [%s]\n",i,tokens2[i].c_str()); + //} + std::vector tokens3 = TokenizeString(tokens[2], "]"); + //for(unsigned int i = 0; i < tokens3.size(); ++i) { + //printf("#3 Vec2T i = %d [%s]\n",i,tokens3[i].c_str()); + //} + + if (tokens2.size() == 2 && tokens3.size() == 2) { + result.x = (T) strToType(tokens2[0]); + result.y = (T) strToType(tokens3[0]); + + //printf("#3 Vec2T [%s]\n",result.getString().c_str()); + } + } + + + return result; + } + + void toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + this->x = Shared::PlatformByteOrder::toCommonEndian(this->x); + this->y = Shared::PlatformByteOrder::toCommonEndian(this->y); + } + } + void fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + this->x = Shared::PlatformByteOrder::fromCommonEndian(this->x); + this->y = Shared::PlatformByteOrder::fromCommonEndian(this->y); + } + } + + }; + + template + inline std::ostream& operator<<(std::ostream &stream, const Vec2 &vec) { + return stream << "(" << vec.x << ", " << vec.y << ")"; } - return result; - } + typedef Vec2 Vec2i; + typedef Vec2 Vec2b; + typedef Vec2 Vec2c; + typedef Vec2 Vec2f; + typedef Vec2 Vec2d; - void toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - this->x = Shared::PlatformByteOrder::toCommonEndian(this->x); - this->y = Shared::PlatformByteOrder::toCommonEndian(this->y); - } - } - void fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - this->x = Shared::PlatformByteOrder::fromCommonEndian(this->x); - this->y = Shared::PlatformByteOrder::fromCommonEndian(this->y); - } - } + // ===================================================== + // class Vec3 + // ===================================================== -}; + template + class Vec3 { + public: + T x; + T y; + T z; -template -inline std::ostream& operator<<(std::ostream &stream, const Vec2 &vec) { - return stream << "(" << vec.x << ", " << vec.y << ")"; -} + public: + Vec3() { + x = 0; + y = 0; + z = 0; + }; + explicit Vec3(T *p) { + this->x = p[0]; + this->y = p[1]; + this->z = p[2]; + } -typedef Vec2 Vec2i; -typedef Vec2 Vec2b; -typedef Vec2 Vec2c; -typedef Vec2 Vec2f; -typedef Vec2 Vec2d; + explicit Vec3(T xyz) { + this->x = xyz; + this->y = xyz; + this->z = xyz; + } -// ===================================================== -// class Vec3 -// ===================================================== + template + explicit Vec3(const Vec3 &v) { + this->x = v.x; + this->y = v.y; + this->z = v.z; + } -template -class Vec3 { -public: - T x; - T y; - T z; + template + explicit Vec3(Vec3 &v) { + this->x = v.x; + this->y = v.y; + this->z = v.z; + } -public: - Vec3() { - x = 0; - y = 0; - z = 0; - }; + Vec3(T x, T y, T z) { + this->x = x; + this->y = y; + this->z = z; + } - explicit Vec3(T *p){ - this->x= p[0]; - this->y= p[1]; - this->z= p[2]; - } + explicit Vec3(Vec4 v) { + this->x = v.x; + this->y = v.y; + this->z = v.z; + } - explicit Vec3(T xyz){ - this->x= xyz; - this->y= xyz; - this->z= xyz; - } + inline T *ptr() { + return reinterpret_cast(this); + } - template - explicit Vec3(const Vec3 &v){ - this->x= v.x; - this->y= v.y; - this->z= v.z; - } + inline const T *ptr() const { + return reinterpret_cast(this); + } - template - explicit Vec3(Vec3 &v){ - this->x= v.x; - this->y= v.y; - this->z= v.z; - } + inline Vec3 & operator=(const Vec3 &v) { + this->x = v.x; + this->y = v.y; + this->z = v.z; + return *this; + } - Vec3(T x, T y, T z){ - this->x= x; - this->y= y; - this->z= z; - } + inline bool operator ==(const Vec3 &v) const { + return x == v.x && y == v.y && z == v.z; + } - explicit Vec3(Vec4 v){ - this->x= v.x; - this->y= v.y; - this->z= v.z; - } + inline bool operator !=(const Vec3 &v) const { + return x != v.x || y != v.y || z != v.z; + } - inline T *ptr(){ - return reinterpret_cast(this); - } + inline Vec3 operator +(const Vec3 &v) const { + return Vec3(x + v.x, y + v.y, z + v.z); + } - inline const T *ptr() const{ - return reinterpret_cast(this); - } + inline Vec3 operator -(const Vec3 &v) const { + return Vec3(x - v.x, y - v.y, z - v.z); + } - inline Vec3 & operator=(const Vec3 &v) { - this->x= v.x; - this->y= v.y; - this->z= v.z; - return *this; - } + inline Vec3 operator -() const { + return Vec3(-x, -y, -z); + } - inline bool operator ==(const Vec3 &v) const{ - return x==v.x && y==v.y && z==v.z; - } + inline Vec3 operator *(const Vec3 &v) const { + return Vec3(x*v.x, y*v.y, z*v.z); + } - inline bool operator !=(const Vec3 &v) const{ - return x!=v.x || y!=v.y || z!=v.z; - } + inline Vec3 operator *(T s) const { + return Vec3(x*s, y*s, z*s); + } - inline Vec3 operator +(const Vec3 &v) const{ - return Vec3(x+v.x, y+v.y, z+v.z); - } + inline Vec3 operator /(const Vec3 &v) const { + return Vec3(x / v.x, y / v.y, z / v.z); + } - inline Vec3 operator -(const Vec3 &v) const{ - return Vec3(x-v.x, y-v.y, z-v.z); - } + inline Vec3 operator /(T s) const { + return Vec3(x / s, y / s, z / s); + } - inline Vec3 operator -() const{ - return Vec3(-x, -y, -z); - } + inline Vec3 operator +=(const Vec3 &v) { + x += v.x; + y += v.y; + z += v.z; + return *this; + } - inline Vec3 operator *(const Vec3 &v) const{ - return Vec3(x*v.x, y*v.y, z*v.z); - } + inline Vec3 operator -=(const Vec3 &v) { + x -= v.x; + y -= v.y; + z -= v.z; + return *this; + } - inline Vec3 operator *(T s) const{ - return Vec3(x*s, y*s, z*s); - } + inline bool operator <(const Vec3 &v) const { + return x < v.x || (x == v.x && y < v.y) || (x == v.x && y == v.y && z < v.z); + } - inline Vec3 operator /(const Vec3 &v) const{ - return Vec3(x/v.x, y/v.y, z/v.z); - } + inline Vec3 lerp(T t, const Vec3 &v) const { + return *this + (v - *this) * t; + } - inline Vec3 operator /(T s) const{ - return Vec3(x/s, y/s, z/s); - } + inline T dot(const Vec3 &v) const { + return x*v.x + y*v.y + z*v.z; + } - inline Vec3 operator +=(const Vec3 &v){ - x+=v.x; - y+=v.y; - z+=v.z; - return *this; - } + inline float dist(const Vec3 &v) const { + float distance = Vec3(v - *this).length(); + return distance; + } - inline Vec3 operator -=(const Vec3 &v){ - x-=v.x; - y-=v.y; - z-=v.z; - return *this; - } - - inline bool operator <(const Vec3 &v) const { - return x < v.x || (x == v.x && y < v.y) || (x == v.x && y == v.y && z < v.z); - } - - inline Vec3 lerp(T t, const Vec3 &v) const{ - return *this + (v - *this) * t; - } - - inline T dot(const Vec3 &v) const{ - return x*v.x + y*v.y + z*v.z; - } - - inline float dist(const Vec3 &v) const { - float distance = Vec3(v-*this).length(); - return distance; - } - - inline float length() const { + inline float length() const { #ifdef USE_STREFLOP - float len = static_cast(streflop::sqrt(static_cast(x*x + y*y + z*z))); + float len = static_cast(streflop::sqrt(static_cast(x*x + y*y + z*z))); #else - float len = static_cast(std::sqrt(x*x + y*y + z*z)); - len = truncateDecimal(len,6); + float len = static_cast(std::sqrt(x*x + y*y + z*z)); + len = truncateDecimal(len, 6); #endif - return len; - } - - inline void normalize() { - T m= length(); - x/= m; - y/= m; - z/= m; - } - - inline Vec3 getNormalized() const { - T m= length(); - return Vec3(x/m, y/m, z/m); - } - - inline Vec3 cross(const Vec3 &v) const{ - return Vec3( - this->y*v.z-this->z*v.y, - this->z*v.x-this->x*v.z, - this->x*v.y-this->y*v.x); - } - - inline Vec3 normal(const Vec3 &p1, const Vec3 &p2) const{ - Vec3 rv; - rv= (p2-*this).cross(p1-*this); - rv.normalize(); - return rv; - } - - inline Vec3 normal(const Vec3 &p1, const Vec3 &p2, const Vec3 &p3, const Vec3 &p4) const{ - Vec3 rv; - - rv= this->normal(p1, p2); - rv= rv + this->normal(p2, p3); - rv= rv + this->normal(p3, p4); - rv= rv + this->normal(p4, p1); - rv.normalize(); - return rv; - } - - inline std::string getString() const { - std::ostringstream streamOut; - streamOut << "x [" << x; - streamOut << "] y [" << y; - streamOut << "] z [" << z << "]"; - std::string result = streamOut.str(); - streamOut.str(std::string()); - return result; - } - - // playerColor="x [1] y [0] z [0]" - static inline Vec3 strToVec3(std::string value) { - Vec3 result; - - std::vector tokens = TokenizeString(value,"["); - //for(unsigned int i = 0; i < tokens.size(); ++i) { - //printf("#1 Vec2T i = %d [%s]\n",i,tokens[i].c_str()); - //} - if(tokens.size() == 4) { - std::vector tokens2 = TokenizeString(tokens[1],"]"); - //for(unsigned int i = 0; i < tokens2.size(); ++i) { - //printf("#2 Vec2T i = %d [%s]\n",i,tokens2[i].c_str()); - //} - std::vector tokens3 = TokenizeString(tokens[2],"]"); - //for(unsigned int i = 0; i < tokens3.size(); ++i) { - //printf("#3 Vec2T i = %d [%s]\n",i,tokens3[i].c_str()); - //} - - std::vector tokens4 = TokenizeString(tokens[3],"]"); - //for(unsigned int i = 0; i < tokens3.size(); ++i) { - //printf("#3 Vec2T i = %d [%s]\n",i,tokens3[i].c_str()); - //} - - if(tokens2.size() == 2 && tokens3.size() == 2 && tokens4.size() == 2) { - result.x = (T)strToType(tokens2[0]); - result.y = (T)strToType(tokens3[0]); - result.z = (T)strToType(tokens4[0]); - - //printf("#3 Vec2T [%s]\n",result.getString().c_str()); + return len; } - } - - return result; - } - - void toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - this->x = Shared::PlatformByteOrder::toCommonEndian(this->x); - this->y = Shared::PlatformByteOrder::toCommonEndian(this->y); - this->z = Shared::PlatformByteOrder::toCommonEndian(this->z); - } - } - void fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - this->x = Shared::PlatformByteOrder::fromCommonEndian(this->x); - this->y = Shared::PlatformByteOrder::fromCommonEndian(this->y); - this->z = Shared::PlatformByteOrder::fromCommonEndian(this->z); - } - } - -}; - -typedef Vec3 Vec3i; -typedef Vec3 Vec3b; -typedef Vec3 Vec3c; -typedef Vec3 Vec3f; -typedef Vec3 Vec3d; - -// ===================================================== -// class Vec4 -// ===================================================== - -template -class Vec4 { -public: - T x; - T y; - T z; - T w; -public: - Vec4() { - x = 0; - y = 0; - z = 0; - w = 0; - }; - - explicit Vec4(const T *p){ - this->x= p[0]; - this->y= p[1]; - this->z= p[2]; - this->w= p[3]; - } - - explicit Vec4(T *p){ - this->x= p[0]; - this->y= p[1]; - this->z= p[2]; - this->w= p[3]; - } - - explicit Vec4(T xyzw){ - this->x= xyzw; - this->y= xyzw; - this->z= xyzw; - this->w= xyzw; - } - - template - explicit Vec4(const Vec4 &v){ - this->x= v.x; - this->y= v.y; - this->z= v.z; - this->w= v.w; - } - - template - explicit Vec4(Vec4 &v){ - this->x= v.x; - this->y= v.y; - this->z= v.z; - this->w= v.w; - } - - Vec4(T x, T y, T z, T w){ - this->x= x; - this->y= y; - this->z= z; - this->w= w; - } - - Vec4(Vec3 v, T w){ - this->x= v.x; - this->y= v.y; - this->z= v.z; - this->w= w; - } - - explicit Vec4(Vec3 v){ - this->x= v.x; - this->y= v.y; - this->z= v.z; - this->w= 1; - } - - inline T *ptr(){ - return reinterpret_cast(this); - } - - inline const T *ptr() const{ - return reinterpret_cast(this); - } - - inline Vec4 & operator=(const Vec4 &v) { - this->x= v.x; - this->y= v.y; - this->z= v.z; - this->w= v.w; - return *this; - } - - inline bool operator ==(const Vec4 &v) const{ - return x==v.x && y==v.y && z==v.z && w==v.w; - } - - inline bool operator !=(const Vec4 &v) const{ - return x!=v.x || y!=v.y || z!=v.z || w!=v.w; - } - - inline Vec4 operator +(const Vec4 &v) const{ - return Vec4(x+v.x, y+v.y, z+v.z, w+v.w); - } - - inline Vec4 operator -(const Vec4 &v) const{ - return Vec4(x-v.x, y-v.y, z-v.z, w-v.w); - } - - inline Vec4 operator -() const{ - return Vec4(-x, -y, -z, -w); - } - - inline Vec4 operator *(const Vec4 &v) const{ - return Vec4(x*v.x, y*v.y, z*v.z, w*v.w); - } - - inline Vec4 operator *(T s) const{ - return Vec4(x*s, y*s, z*s, w*s); - } - - inline Vec4 operator /(const Vec4 &v) const{ - return Vec4(x/v.x, y/v.y, z/v.z, w/v.w); - } - - inline Vec4 operator /(T s) const{ - return Vec4(x/s, y/s, z/s, w/s); - } - - inline Vec4 operator +=(const Vec4 &v){ - x+=v.x; - y+=v.y; - z+=v.z; - w+=w.z; - return *this; - } - - inline Vec4 operator -=(const Vec4 &v){ - x-=v.x; - y-=v.y; - z-=v.z; - w-=w.z; - return *this; - } - inline bool operator <(const Vec4 &v) const { - return x < v.x || (x == v.x && y < v.y) || - (x == v.x && y == v.y && z < v.z) || - (x == v.x && y == v.y && z == v.z && w < v.w); - } - - inline Vec4 lerp(T t, const Vec4 &v) const{ - return *this + (v - *this) *t; - } - - inline T dot(const Vec4 &v) const{ - return x*v.x + y*v.y + z*v.z + w*v.w; - } - - inline std::string getString() const { - std::ostringstream streamOut; - streamOut << "x [" << x; - streamOut << "] y [" << y; - streamOut << "] z [" << z; - streamOut << "] w [" << w << "]"; - std::string result = streamOut.str(); - streamOut.str(std::string()); - return result; - } - - // playerColor="x [1] y [0] z [0] w [0]" - static inline Vec4 strToVec4(std::string value) { - Vec4 result; - - std::vector tokens = TokenizeString(value,"["); - //for(unsigned int i = 0; i < tokens.size(); ++i) { - //printf("#1 Vec2T i = %d [%s]\n",i,tokens[i].c_str()); - //} - if(tokens.size() == 5) { - std::vector tokens2 = TokenizeString(tokens[1],"]"); - //for(unsigned int i = 0; i < tokens2.size(); ++i) { - //printf("#2 Vec2T i = %d [%s]\n",i,tokens2[i].c_str()); - //} - std::vector tokens3 = TokenizeString(tokens[2],"]"); - //for(unsigned int i = 0; i < tokens3.size(); ++i) { - //printf("#3 Vec2T i = %d [%s]\n",i,tokens3[i].c_str()); - //} - - std::vector tokens4 = TokenizeString(tokens[3],"]"); - //for(unsigned int i = 0; i < tokens3.size(); ++i) { - //printf("#3 Vec2T i = %d [%s]\n",i,tokens3[i].c_str()); - //} - - std::vector tokens5 = TokenizeString(tokens[4],"]"); - //for(unsigned int i = 0; i < tokens3.size(); ++i) { - //printf("#3 Vec2T i = %d [%s]\n",i,tokens3[i].c_str()); - //} - - if(tokens2.size() == 2 && tokens3.size() == 2 && - tokens4.size() == 2 && tokens5.size() == 2) { - result.x = (T)strToType(tokens2[0]); - result.y = (T)strToType(tokens3[0]); - result.z = (T)strToType(tokens4[0]); - result.w = (T)strToType(tokens5[0]); - - //printf("#3 Vec2T [%s]\n",result.getString().c_str()); + inline void normalize() { + T m = length(); + x /= m; + y /= m; + z /= m; } - } - return result; + inline Vec3 getNormalized() const { + T m = length(); + return Vec3(x / m, y / m, z / m); + } + + inline Vec3 cross(const Vec3 &v) const { + return Vec3( + this->y*v.z - this->z*v.y, + this->z*v.x - this->x*v.z, + this->x*v.y - this->y*v.x); + } + + inline Vec3 normal(const Vec3 &p1, const Vec3 &p2) const { + Vec3 rv; + rv = (p2 - *this).cross(p1 - *this); + rv.normalize(); + return rv; + } + + inline Vec3 normal(const Vec3 &p1, const Vec3 &p2, const Vec3 &p3, const Vec3 &p4) const { + Vec3 rv; + + rv = this->normal(p1, p2); + rv = rv + this->normal(p2, p3); + rv = rv + this->normal(p3, p4); + rv = rv + this->normal(p4, p1); + rv.normalize(); + return rv; + } + + inline std::string getString() const { + std::ostringstream streamOut; + streamOut << "x [" << x; + streamOut << "] y [" << y; + streamOut << "] z [" << z << "]"; + std::string result = streamOut.str(); + streamOut.str(std::string()); + return result; + } + + // playerColor="x [1] y [0] z [0]" + static inline Vec3 strToVec3(std::string value) { + Vec3 result; + + std::vector tokens = TokenizeString(value, "["); + //for(unsigned int i = 0; i < tokens.size(); ++i) { + //printf("#1 Vec2T i = %d [%s]\n",i,tokens[i].c_str()); + //} + if (tokens.size() == 4) { + std::vector tokens2 = TokenizeString(tokens[1], "]"); + //for(unsigned int i = 0; i < tokens2.size(); ++i) { + //printf("#2 Vec2T i = %d [%s]\n",i,tokens2[i].c_str()); + //} + std::vector tokens3 = TokenizeString(tokens[2], "]"); + //for(unsigned int i = 0; i < tokens3.size(); ++i) { + //printf("#3 Vec2T i = %d [%s]\n",i,tokens3[i].c_str()); + //} + + std::vector tokens4 = TokenizeString(tokens[3], "]"); + //for(unsigned int i = 0; i < tokens3.size(); ++i) { + //printf("#3 Vec2T i = %d [%s]\n",i,tokens3[i].c_str()); + //} + + if (tokens2.size() == 2 && tokens3.size() == 2 && tokens4.size() == 2) { + result.x = (T) strToType(tokens2[0]); + result.y = (T) strToType(tokens3[0]); + result.z = (T) strToType(tokens4[0]); + + //printf("#3 Vec2T [%s]\n",result.getString().c_str()); + } + } + + + return result; + } + + void toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + this->x = Shared::PlatformByteOrder::toCommonEndian(this->x); + this->y = Shared::PlatformByteOrder::toCommonEndian(this->y); + this->z = Shared::PlatformByteOrder::toCommonEndian(this->z); + } + } + void fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + this->x = Shared::PlatformByteOrder::fromCommonEndian(this->x); + this->y = Shared::PlatformByteOrder::fromCommonEndian(this->y); + this->z = Shared::PlatformByteOrder::fromCommonEndian(this->z); + } + } + + }; + + typedef Vec3 Vec3i; + typedef Vec3 Vec3b; + typedef Vec3 Vec3c; + typedef Vec3 Vec3f; + typedef Vec3 Vec3d; + + // ===================================================== + // class Vec4 + // ===================================================== + + template + class Vec4 { + public: + T x; + T y; + T z; + T w; + public: + Vec4() { + x = 0; + y = 0; + z = 0; + w = 0; + }; + + explicit Vec4(const T *p) { + this->x = p[0]; + this->y = p[1]; + this->z = p[2]; + this->w = p[3]; + } + + explicit Vec4(T *p) { + this->x = p[0]; + this->y = p[1]; + this->z = p[2]; + this->w = p[3]; + } + + explicit Vec4(T xyzw) { + this->x = xyzw; + this->y = xyzw; + this->z = xyzw; + this->w = xyzw; + } + + template + explicit Vec4(const Vec4 &v) { + this->x = v.x; + this->y = v.y; + this->z = v.z; + this->w = v.w; + } + + template + explicit Vec4(Vec4 &v) { + this->x = v.x; + this->y = v.y; + this->z = v.z; + this->w = v.w; + } + + Vec4(T x, T y, T z, T w) { + this->x = x; + this->y = y; + this->z = z; + this->w = w; + } + + Vec4(Vec3 v, T w) { + this->x = v.x; + this->y = v.y; + this->z = v.z; + this->w = w; + } + + explicit Vec4(Vec3 v) { + this->x = v.x; + this->y = v.y; + this->z = v.z; + this->w = 1; + } + + inline T *ptr() { + return reinterpret_cast(this); + } + + inline const T *ptr() const { + return reinterpret_cast(this); + } + + inline Vec4 & operator=(const Vec4 &v) { + this->x = v.x; + this->y = v.y; + this->z = v.z; + this->w = v.w; + return *this; + } + + inline bool operator ==(const Vec4 &v) const { + return x == v.x && y == v.y && z == v.z && w == v.w; + } + + inline bool operator !=(const Vec4 &v) const { + return x != v.x || y != v.y || z != v.z || w != v.w; + } + + inline Vec4 operator +(const Vec4 &v) const { + return Vec4(x + v.x, y + v.y, z + v.z, w + v.w); + } + + inline Vec4 operator -(const Vec4 &v) const { + return Vec4(x - v.x, y - v.y, z - v.z, w - v.w); + } + + inline Vec4 operator -() const { + return Vec4(-x, -y, -z, -w); + } + + inline Vec4 operator *(const Vec4 &v) const { + return Vec4(x*v.x, y*v.y, z*v.z, w*v.w); + } + + inline Vec4 operator *(T s) const { + return Vec4(x*s, y*s, z*s, w*s); + } + + inline Vec4 operator /(const Vec4 &v) const { + return Vec4(x / v.x, y / v.y, z / v.z, w / v.w); + } + + inline Vec4 operator /(T s) const { + return Vec4(x / s, y / s, z / s, w / s); + } + + inline Vec4 operator +=(const Vec4 &v) { + x += v.x; + y += v.y; + z += v.z; + w += w.z; + return *this; + } + + inline Vec4 operator -=(const Vec4 &v) { + x -= v.x; + y -= v.y; + z -= v.z; + w -= w.z; + return *this; + } + inline bool operator <(const Vec4 &v) const { + return x < v.x || (x == v.x && y < v.y) || + (x == v.x && y == v.y && z < v.z) || + (x == v.x && y == v.y && z == v.z && w < v.w); + } + + inline Vec4 lerp(T t, const Vec4 &v) const { + return *this + (v - *this) *t; + } + + inline T dot(const Vec4 &v) const { + return x*v.x + y*v.y + z*v.z + w*v.w; + } + + inline std::string getString() const { + std::ostringstream streamOut; + streamOut << "x [" << x; + streamOut << "] y [" << y; + streamOut << "] z [" << z; + streamOut << "] w [" << w << "]"; + std::string result = streamOut.str(); + streamOut.str(std::string()); + return result; + } + + // playerColor="x [1] y [0] z [0] w [0]" + static inline Vec4 strToVec4(std::string value) { + Vec4 result; + + std::vector tokens = TokenizeString(value, "["); + //for(unsigned int i = 0; i < tokens.size(); ++i) { + //printf("#1 Vec2T i = %d [%s]\n",i,tokens[i].c_str()); + //} + if (tokens.size() == 5) { + std::vector tokens2 = TokenizeString(tokens[1], "]"); + //for(unsigned int i = 0; i < tokens2.size(); ++i) { + //printf("#2 Vec2T i = %d [%s]\n",i,tokens2[i].c_str()); + //} + std::vector tokens3 = TokenizeString(tokens[2], "]"); + //for(unsigned int i = 0; i < tokens3.size(); ++i) { + //printf("#3 Vec2T i = %d [%s]\n",i,tokens3[i].c_str()); + //} + + std::vector tokens4 = TokenizeString(tokens[3], "]"); + //for(unsigned int i = 0; i < tokens3.size(); ++i) { + //printf("#3 Vec2T i = %d [%s]\n",i,tokens3[i].c_str()); + //} + + std::vector tokens5 = TokenizeString(tokens[4], "]"); + //for(unsigned int i = 0; i < tokens3.size(); ++i) { + //printf("#3 Vec2T i = %d [%s]\n",i,tokens3[i].c_str()); + //} + + if (tokens2.size() == 2 && tokens3.size() == 2 && + tokens4.size() == 2 && tokens5.size() == 2) { + result.x = (T) strToType(tokens2[0]); + result.y = (T) strToType(tokens3[0]); + result.z = (T) strToType(tokens4[0]); + result.w = (T) strToType(tokens5[0]); + + //printf("#3 Vec2T [%s]\n",result.getString().c_str()); + } + } + + return result; + } + + void toEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + this->x = Shared::PlatformByteOrder::toCommonEndian(this->x); + this->y = Shared::PlatformByteOrder::toCommonEndian(this->y); + this->z = Shared::PlatformByteOrder::toCommonEndian(this->z); + this->w = Shared::PlatformByteOrder::toCommonEndian(this->w); + } + } + void fromEndian() { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + this->x = Shared::PlatformByteOrder::fromCommonEndian(this->x); + this->y = Shared::PlatformByteOrder::fromCommonEndian(this->y); + this->z = Shared::PlatformByteOrder::fromCommonEndian(this->z); + this->w = Shared::PlatformByteOrder::fromCommonEndian(this->w); + } + } + + }; + + typedef Vec4 Vec4i; + typedef Vec4 Vec4b; + typedef Vec4 Vec4c; + typedef Vec4 Vec4f; + typedef Vec4 Vec4d; + } - - void toEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - this->x = Shared::PlatformByteOrder::toCommonEndian(this->x); - this->y = Shared::PlatformByteOrder::toCommonEndian(this->y); - this->z = Shared::PlatformByteOrder::toCommonEndian(this->z); - this->w = Shared::PlatformByteOrder::toCommonEndian(this->w); - } - } - void fromEndian() { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - this->x = Shared::PlatformByteOrder::fromCommonEndian(this->x); - this->y = Shared::PlatformByteOrder::fromCommonEndian(this->y); - this->z = Shared::PlatformByteOrder::fromCommonEndian(this->z); - this->w = Shared::PlatformByteOrder::fromCommonEndian(this->w); - } - } - -}; - -typedef Vec4 Vec4i; -typedef Vec4 Vec4b; -typedef Vec4 Vec4c; -typedef Vec4 Vec4f; -typedef Vec4 Vec4d; - -}} //enmd namespace +} //enmd namespace #endif diff --git a/source/shared_lib/include/graphics/video_player.h b/source/shared_lib/include/graphics/video_player.h index 7387934d4..95cacf43e 100644 --- a/source/shared_lib/include/graphics/video_player.h +++ b/source/shared_lib/include/graphics/video_player.h @@ -18,70 +18,79 @@ class ctx; using namespace std; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -class VideoLoadingCallbackInterface { -public: - virtual ~VideoLoadingCallbackInterface() {} - /** a value from 1 to 100 representing % done */ - virtual void renderVideoLoading(int progressPercent) = 0; -}; + class VideoLoadingCallbackInterface { + public: + virtual ~VideoLoadingCallbackInterface() { + } + /** a value from 1 to 100 representing % done */ + virtual void renderVideoLoading(int progressPercent) = 0; + }; -class VideoPlayer { -protected: + class VideoPlayer { + protected: - string filename; - string filenameFallback; - SDL_Window *window; - int x; - int y; - int width; - int height; - int colorBits; + string filename; + string filenameFallback; + SDL_Window *window; + int x; + int y; + int width; + int height; + int colorBits; - bool successLoadingLib; - string pluginsPath; - bool verboseEnabled; + bool successLoadingLib; + string pluginsPath; + bool verboseEnabled; - bool stop; - bool finished; - bool loop; + bool stop; + bool finished; + bool loop; - VideoLoadingCallbackInterface *loadingCB; - ctx *ctxPtr; + VideoLoadingCallbackInterface *loadingCB; + ctx *ctxPtr; - static bool disabled; - void init(); + static bool disabled; + void init(); - void cleanupPlayer(); - bool initPlayer(string mediaURL); + void cleanupPlayer(); + bool initPlayer(string mediaURL); -public: - VideoPlayer(VideoLoadingCallbackInterface *loadingCB, - string filename, - string filenameFallback, - SDL_Window *window, int x, int y, - int width, int height, int colorBits, - bool loop, string pluginsPath,bool verboseEnabled=false); - virtual ~VideoPlayer(); + public: + VideoPlayer(VideoLoadingCallbackInterface *loadingCB, + string filename, + string filenameFallback, + SDL_Window *window, int x, int y, + int width, int height, int colorBits, + bool loop, string pluginsPath, bool verboseEnabled = false); + virtual ~VideoPlayer(); - static void setDisabled(bool value) { disabled = value; } - static bool getDisabled() { return disabled; } + static void setDisabled(bool value) { + disabled = value; + } + static bool getDisabled() { + return disabled; + } - void PlayVideo(); - void StopVideo() { stop = true; } + void PlayVideo(); + void StopVideo() { + stop = true; + } - bool initPlayer(); - void closePlayer(); + bool initPlayer(); + void closePlayer(); - bool playFrame(bool swapBuffers = true); - bool isPlaying() const; + bool playFrame(bool swapBuffers = true); + bool isPlaying() const; - static bool hasBackEndVideoPlayer(); + static bool hasBackEndVideoPlayer(); - void RestartVideo(); -}; + void RestartVideo(); + }; -}} + } +} #endif /* VIDEO_PLAYER_H_ */ diff --git a/source/shared_lib/include/lua/lua_script.h b/source/shared_lib/include/lua/lua_script.h index eabfda493..35a504b76 100644 --- a/source/shared_lib/include/lua/lua_script.h +++ b/source/shared_lib/include/lua/lua_script.h @@ -28,94 +28,104 @@ using Shared::Graphics::Vec4f; using Shared::Xml::XmlNode; -namespace Shared { namespace Lua { +namespace Shared { + namespace Lua { -typedef lua_State LuaHandle; -typedef int(*LuaFunction)(LuaHandle*); + typedef lua_State LuaHandle; + typedef int(*LuaFunction)(LuaHandle*); -// ===================================================== -// class LuaScript -// ===================================================== + // ===================================================== + // class LuaScript + // ===================================================== -class LuaScript { -private: - LuaHandle *luaState; - int argumentCount; - string currentLuaFunction; - bool currentLuaFunctionIsValid; - string sandboxWrapperFunctionName; - string sandboxCode; + class LuaScript { + private: + LuaHandle *luaState; + int argumentCount; + string currentLuaFunction; + bool currentLuaFunctionIsValid; + string sandboxWrapperFunctionName; + string sandboxCode; - static bool disableSandbox; - static bool debugModeEnabled; + static bool disableSandbox; + static bool debugModeEnabled; - void DumpGlobals(); + void DumpGlobals(); -public: - LuaScript(); - ~LuaScript(); + public: + LuaScript(); + ~LuaScript(); - static void setDebugModeEnabled(bool value) { debugModeEnabled = value; } - static bool getDebugModeEnabled() { return debugModeEnabled; } + static void setDebugModeEnabled(bool value) { + debugModeEnabled = value; + } + static bool getDebugModeEnabled() { + return debugModeEnabled; + } - static void setDisableSandbox(bool value) { disableSandbox = value; } + static void setDisableSandbox(bool value) { + disableSandbox = value; + } - void loadCode(string code, string name); + void loadCode(string code, string name); - void beginCall(string functionName); - void endCall(); + void beginCall(string functionName); + void endCall(); - int runCode(const string code); - void setSandboxWrapperFunctionName(string name); - void setSandboxCode(string code); + int runCode(const string code); + void setSandboxWrapperFunctionName(string name); + void setSandboxCode(string code); - void registerFunction(LuaFunction luaFunction, string functionName); + void registerFunction(LuaFunction luaFunction, string functionName); - void saveGame(XmlNode *rootNode); - void loadGame(const XmlNode *rootNode); + void saveGame(XmlNode *rootNode); + void loadGame(const XmlNode *rootNode); -private: - string errorToString(int errorCode); -}; + private: + string errorToString(int errorCode); + }; -// ===================================================== -// class LuaArguments -// ===================================================== + // ===================================================== + // class LuaArguments + // ===================================================== -class LuaArguments { -private: - lua_State *luaState; - int returnCount; + class LuaArguments { + private: + lua_State *luaState; + int returnCount; -public: - LuaArguments(lua_State *luaState); + public: + LuaArguments(lua_State *luaState); - int getInt(int argumentIndex) const; - string getString(int argumentIndex) const; - void * getGenericData(int argumentIndex) const; - Vec2i getVec2i(int argumentIndex) const; - Vec4i getVec4i(int argumentIndex) const; + int getInt(int argumentIndex) const; + string getString(int argumentIndex) const; + void * getGenericData(int argumentIndex) const; + Vec2i getVec2i(int argumentIndex) const; + Vec4i getVec4i(int argumentIndex) const; - float getFloat(int argumentIndex) const; - Vec2f getVec2f(int argumentIndex) const; - Vec3f getVec3f(int argumentIndex) const; - Vec4f getVec4f(int argumentIndex) const; + float getFloat(int argumentIndex) const; + Vec2f getVec2f(int argumentIndex) const; + Vec3f getVec3f(int argumentIndex) const; + Vec4f getVec4f(int argumentIndex) const; - int getReturnCount() const {return returnCount;} + int getReturnCount() const { + return returnCount; + } - void returnInt(int value); - void returnFloat(float value); - void returnString(const string &value); - void returnVec2i(const Vec2i &value); - void returnVec4i(const Vec4i &value); - void returnVectorInt(const vector &value); + void returnInt(int value); + void returnFloat(float value); + void returnString(const string &value); + void returnVec2i(const Vec2i &value); + void returnVec4i(const Vec4i &value); + void returnVectorInt(const vector &value); -private: + private: - void throwLuaError(const string &message) const; - string getStackText() const; -}; + void throwLuaError(const string &message) const; + string getStackText() const; + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/map/map_preview.h b/source/shared_lib/include/map/map_preview.h index 0237c8a7c..6aa128580 100644 --- a/source/shared_lib/include/map/map_preview.h +++ b/source/shared_lib/include/map/map_preview.h @@ -25,212 +25,242 @@ using Shared::Platform::float32; using Shared::Util::RandomGen; using Shared::Graphics::Vec2i; -namespace Shared { namespace Map { +namespace Shared { + namespace Map { -enum MapSurfaceType { - st_Grass = 1, - st_Secondary_Grass, - st_Road, - st_Stone, - st_Ground + enum MapSurfaceType { + st_Grass = 1, + st_Secondary_Grass, + st_Road, + st_Stone, + st_Ground -}; + }; -static const int MAX_TITLE_LENGTH = 128; -static const int MAX_AUTHOR_LENGTH = 128; -static const int MAX_DESCRIPTION_LENGTH = 256; -static const int MAX_DESCRIPTION_LENGTH_VERSION2 = 128; + static const int MAX_TITLE_LENGTH = 128; + static const int MAX_AUTHOR_LENGTH = 128; + static const int MAX_DESCRIPTION_LENGTH = 256; + static const int MAX_DESCRIPTION_LENGTH_VERSION2 = 128; -static const int MIN_MAP_CELL_DIMENSION = 16; -static const int MAX_MAP_CELL_DIMENSION = 1024; + static const int MIN_MAP_CELL_DIMENSION = 16; + static const int MAX_MAP_CELL_DIMENSION = 1024; -static const int MIN_MAP_CELL_HEIGHT = 0; -static const int MAX_MAP_CELL_HEIGHT = 20; -static const int DEFAULT_MAP_CELL_HEIGHT = 10; + static const int MIN_MAP_CELL_HEIGHT = 0; + static const int MAX_MAP_CELL_HEIGHT = 20; + static const int DEFAULT_MAP_CELL_HEIGHT = 10; -static const int MIN_MAP_FACTIONCOUNT = 1; -static const int MAX_MAP_FACTIONCOUNT = 8; -static const int DEFAULT_MAP_FACTIONCOUNT = 8; + static const int MIN_MAP_FACTIONCOUNT = 1; + static const int MAX_MAP_FACTIONCOUNT = 8; + static const int DEFAULT_MAP_FACTIONCOUNT = 8; -static const int DEFAULT_MAP_CELL_WIDTH = 128; -static const int DEFAULT_MAP_CELL_LENGTH = 128; + static const int DEFAULT_MAP_CELL_WIDTH = 128; + static const int DEFAULT_MAP_CELL_LENGTH = 128; -static const MapSurfaceType DEFAULT_MAP_CELL_SURFACE_TYPE = st_Grass; + static const MapSurfaceType DEFAULT_MAP_CELL_SURFACE_TYPE = st_Grass; -static const int DEFAULT_MAP_CELL_HEIGHT_FACTOR = 3; -static const int DEFAULT_MAP_WATER_DEPTH = 4; -static const int DEFAULT_CLIFF_HEIGHT = 0; + static const int DEFAULT_MAP_CELL_HEIGHT_FACTOR = 3; + static const int DEFAULT_MAP_WATER_DEPTH = 4; + static const int DEFAULT_CLIFF_HEIGHT = 0; -enum MapVersionType { - mapver_1 = 1, - mapver_2, + enum MapVersionType { + mapver_1 = 1, + mapver_2, - mapver_MAX -}; + mapver_MAX + }; -static const int MAP_FORMAT_VERSION = mapver_MAX - 1; + static const int MAP_FORMAT_VERSION = mapver_MAX - 1; -struct MapFileHeader { - int32 version; - int32 maxFactions; - int32 width; - int32 height; - int32 heightFactor; - int32 waterLevel; - int8 title[MAX_TITLE_LENGTH]; - int8 author[MAX_AUTHOR_LENGTH]; - union { - int8 description[MAX_DESCRIPTION_LENGTH]; - struct { - int8 short_desc[MAX_DESCRIPTION_LENGTH_VERSION2]; - int32 magic; // 0x01020304 for meta - int32 cliffLevel; - int32 cameraHeight; - int8 meta[116]; - } version2; - }; -}; + struct MapFileHeader { + int32 version; + int32 maxFactions; + int32 width; + int32 height; + int32 heightFactor; + int32 waterLevel; + int8 title[MAX_TITLE_LENGTH]; + int8 author[MAX_AUTHOR_LENGTH]; + union { + int8 description[MAX_DESCRIPTION_LENGTH]; + struct { + int8 short_desc[MAX_DESCRIPTION_LENGTH_VERSION2]; + int32 magic; // 0x01020304 for meta + int32 cliffLevel; + int32 cameraHeight; + int8 meta[116]; + } version2; + }; + }; -void toEndianMapFileHeader(MapFileHeader &header); -void fromEndianMapFileHeader(MapFileHeader &header); + void toEndianMapFileHeader(MapFileHeader &header); + void fromEndianMapFileHeader(MapFileHeader &header); -class MapInfo { -public: + class MapInfo { + public: - Vec2i size; - int players; - int hardMaxPlayers; - string desc; + Vec2i size; + int players; + int hardMaxPlayers; + string desc; + + MapInfo() { + size = Vec2i(0, 0); + players = 0; + hardMaxPlayers = 0; + desc = ""; + } + }; + + // =============================================== + // class Map + // =============================================== + + class MapPreview { + public: + static const int maxHeight = 20; + static const int minHeight = 0; + + private: + struct Cell { + int surface; + int object; + int resource; + float height; + }; + + struct StartLocation { + int x; + int y; + }; + + RandomGen random; + string title; + string author; + string desc; + string recScn; + int type; + int h; + int w; + int heightFactor; + int waterLevel; + int cliffLevel; + int cameraHeight; + //Cell **cells; + std::vector > cells; + + int maxFactions; + //StartLocation *startLocations; + std::vector startLocations; + int refAlt; + + bool fileLoaded; + string mapFileLoaded; + bool hasChanged; + + public: + MapPreview(); + ~MapPreview(); + + bool getHasChanged() const { + return hasChanged; + } + void setHasChanged(bool value) { + hasChanged = value; + } + + float getHeight(int x, int y) const; + bool isCliff(int x, int y); + MapSurfaceType getSurface(int x, int y) const; + int getObject(int x, int y) const; + int getResource(int x, int y) const; + int getStartLocationX(int index) const; + int getStartLocationY(int index) const; + int getHeightFactor() const { + return heightFactor; + } + int getWaterLevel() const { + return waterLevel; + } + int getCliffLevel() const { + return cliffLevel; + } + int getCameraHeight() const { + return cameraHeight; + } + + bool inside(int x, int y); + + void setRefAlt(int x, int y); + void setAdvanced(int heightFactor, int waterLevel, int cliffLevel, int cameraHeight); + void setTitle(const string &title); + void setDesc(const string &desc); + void setAuthor(const string &author); + + int getH() const { + return h; + } + int getW() const { + return w; + } + int getMaxFactions() const { + return maxFactions; + } + string getTitle() const { + return title; + } + string getDesc() const { + return desc; + } + string getAuthor() const { + return author; + } + + void glestChangeHeight(int x, int y, int height, int radius); + void pirateChangeHeight(int x, int y, int height, int radius); + void changeSurface(int x, int y, MapSurfaceType surface, int radius); + void changeObject(int x, int y, int object, int radius); + void changeResource(int x, int y, int resource, int radius); + void changeStartLocation(int x, int y, int player); + + void setHeight(int x, int y, float height); + void setSurface(int x, int y, MapSurfaceType surface); + void setObject(int x, int y, int object); + void setResource(int x, int y, int resource); + + void flipX(); + void flipY(); + void copyXY(int x, int y, int sx, int sy); // destination x,y = source sx,sy + void swapXY(int x, int y, int sx, int sy); + void reset(int w, int h, float alt, MapSurfaceType surf); + void resize(int w, int h, float alt, MapSurfaceType surf); + void resetFactions(int maxFactions); + void randomizeHeights(bool withReset, int minimumHeight, int maximumHeight, int chanceDevider, int smoothRecursions); + void randomizeFactions(); + void smoothSurface(bool limitHeights); + void switchSurfaces(MapSurfaceType surf1, MapSurfaceType surf2); + + void loadFromFile(const string &path); + void saveToFile(const string &path); + + void resetHeights(int height); + void realRandomize(int minimumHeight, int maximumHeight, int chanceDivider, int smoothRecursions); + void applyNewHeight(float newHeight, int x, int y, int strenght); + + bool hasFileLoaded() const { + return fileLoaded; + } + string getMapFileLoaded() const { + return mapFileLoaded; + } + + static bool loadMapInfo(string file, MapInfo *mapInfo, string i18nMaxMapPlayersTitle, string i18nMapSizeTitle, bool errorOnInvalidMap = true); + static string getMapPath(const vector &pathList, const string &mapName, string scenarioDir = "", bool errorOnNotFound = true); + static vector findAllValidMaps(const vector &pathList, + string scenarioDir, bool getUserDataOnly = false, bool cutExtension = true, + vector *invalidMapList = NULL); + }; - MapInfo() { - size = Vec2i(0,0); - players = 0; - hardMaxPlayers = 0; - desc = ""; } -}; - -// =============================================== -// class Map -// =============================================== - -class MapPreview { -public: - static const int maxHeight = 20; - static const int minHeight = 0; - -private: - struct Cell { - int surface; - int object; - int resource; - float height; - }; - - struct StartLocation { - int x; - int y; - }; - - RandomGen random; - string title; - string author; - string desc; - string recScn; - int type; - int h; - int w; - int heightFactor; - int waterLevel; - int cliffLevel; - int cameraHeight; - //Cell **cells; - std::vector > cells; - - int maxFactions; - //StartLocation *startLocations; - std::vector startLocations; - int refAlt; - - bool fileLoaded; - string mapFileLoaded; - bool hasChanged; - -public: - MapPreview(); - ~MapPreview(); - - bool getHasChanged() const { return hasChanged; } - void setHasChanged(bool value) { hasChanged = value; } - - float getHeight(int x, int y) const; - bool isCliff(int x,int y); - MapSurfaceType getSurface(int x, int y) const; - int getObject(int x, int y) const; - int getResource(int x, int y) const; - int getStartLocationX(int index) const; - int getStartLocationY(int index) const; - int getHeightFactor() const{return heightFactor;} - int getWaterLevel() const{return waterLevel;} - int getCliffLevel() const{return cliffLevel;} - int getCameraHeight() const{return cameraHeight;} - - bool inside(int x, int y); - - void setRefAlt(int x, int y); - void setAdvanced(int heightFactor, int waterLevel, int cliffLevel, int cameraHeight); - void setTitle(const string &title); - void setDesc(const string &desc); - void setAuthor(const string &author); - - int getH() const {return h;} - int getW() const {return w;} - int getMaxFactions() const {return maxFactions;} - string getTitle() const {return title;} - string getDesc() const {return desc;} - string getAuthor() const {return author;} - - void glestChangeHeight(int x, int y, int height, int radius); - void pirateChangeHeight(int x, int y, int height, int radius); - void changeSurface(int x, int y, MapSurfaceType surface, int radius); - void changeObject(int x, int y, int object, int radius); - void changeResource(int x, int y, int resource, int radius); - void changeStartLocation(int x, int y, int player); - - void setHeight(int x, int y, float height); - void setSurface(int x, int y, MapSurfaceType surface); - void setObject(int x, int y, int object); - void setResource(int x, int y, int resource); - - void flipX(); - void flipY(); - void copyXY(int x, int y, int sx, int sy); // destination x,y = source sx,sy - void swapXY(int x, int y, int sx, int sy); - void reset(int w, int h, float alt, MapSurfaceType surf); - void resize(int w, int h, float alt, MapSurfaceType surf); - void resetFactions(int maxFactions); - void randomizeHeights(bool withReset,int minimumHeight, int maximumHeight, int chanceDevider, int smoothRecursions); - void randomizeFactions(); - void smoothSurface(bool limitHeights); - void switchSurfaces(MapSurfaceType surf1, MapSurfaceType surf2); - - void loadFromFile(const string &path); - void saveToFile(const string &path); - - void resetHeights(int height); - void realRandomize(int minimumHeight, int maximumHeight, int chanceDivider, int smoothRecursions); - void applyNewHeight(float newHeight, int x, int y, int strenght); - - bool hasFileLoaded() const {return fileLoaded;} - string getMapFileLoaded() const { return mapFileLoaded; } - - static bool loadMapInfo(string file, MapInfo *mapInfo, string i18nMaxMapPlayersTitle,string i18nMapSizeTitle,bool errorOnInvalidMap=true); - static string getMapPath(const vector &pathList, const string &mapName, string scenarioDir="", bool errorOnNotFound=true); - static vector findAllValidMaps(const vector &pathList, - string scenarioDir, bool getUserDataOnly=false, bool cutExtension=true, - vector *invalidMapList=NULL); -}; - -}}// end namespace +}// end namespace #endif diff --git a/source/shared_lib/include/platform/common/base_thread.h b/source/shared_lib/include/platform/common/base_thread.h index 9ec620ff7..9cd0bf346 100644 --- a/source/shared_lib/include/platform/common/base_thread.h +++ b/source/shared_lib/include/platform/common/base_thread.h @@ -20,147 +20,152 @@ using namespace Shared::Platform; using namespace std; -namespace Shared { namespace PlatformCommon { +namespace Shared { + namespace PlatformCommon { -// ===================================================== -// class BaseThread -// ===================================================== + // ===================================================== + // class BaseThread + // ===================================================== -class BaseThread : public Thread -{ -protected: - Mutex *mutexRunning; - Mutex *mutexQuit; - Mutex *mutexBeginExecution; - Mutex *mutexDeleteSelfOnExecutionDone; + class BaseThread : public Thread { + protected: + Mutex *mutexRunning; + Mutex *mutexQuit; + Mutex *mutexBeginExecution; + Mutex *mutexDeleteSelfOnExecutionDone; - Mutex *mutexThreadObjectAccessor; + Mutex *mutexThreadObjectAccessor; - bool threadOwnerValid; - Mutex *mutexThreadOwnerValid; + bool threadOwnerValid; + Mutex *mutexThreadOwnerValid; - Mutex *mutexExecutingTask; - bool executingTask; + Mutex *mutexExecutingTask; + bool executingTask; - void *ptr; - static Mutex mutexMasterThreadList; - static std::map masterThreadList; + void *ptr; + static Mutex mutexMasterThreadList; + static std::map masterThreadList; - bool quit; - bool running; - string uniqueID; - bool hasBeginExecution; - bool deleteSelfOnExecutionDone; + bool quit; + bool running; + string uniqueID; + bool hasBeginExecution; + bool deleteSelfOnExecutionDone; - Mutex *mutexStarted; - bool started; + Mutex *mutexStarted; + bool started; - virtual void setQuitStatus(bool value); - void deleteSelfIfRequired(); + virtual void setQuitStatus(bool value); + void deleteSelfIfRequired(); - void *genericData; + void *genericData; -public: - BaseThread(); - virtual ~BaseThread(); - virtual void execute()=0; + public: + BaseThread(); + virtual ~BaseThread(); + virtual void execute() = 0; - virtual void signalQuit(); - virtual bool getQuitStatus(); - virtual bool getRunningStatus(); + virtual void signalQuit(); + virtual bool getQuitStatus(); + virtual bool getRunningStatus(); - virtual bool getStarted(); - virtual void setStarted(bool value); + virtual bool getStarted(); + virtual void setStarted(bool value); - virtual bool getHasBeginExecution(); - virtual void setHasBeginExecution(bool value); + virtual bool getHasBeginExecution(); + virtual void setHasBeginExecution(bool value); - static bool shutdownAndWait(BaseThread *ppThread); - virtual bool shutdownAndWait(); - virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false); + static bool shutdownAndWait(BaseThread *ppThread); + virtual bool shutdownAndWait(); + virtual bool canShutdown(bool deleteSelfIfShutdownDelayed = false); - virtual bool getDeleteSelfOnExecutionDone(); - virtual void setDeleteSelfOnExecutionDone(bool value); + virtual bool getDeleteSelfOnExecutionDone(); + virtual void setDeleteSelfOnExecutionDone(bool value); - void setUniqueID(string value) { uniqueID = value; } - string getUniqueID() { return uniqueID; } + void setUniqueID(string value) { + uniqueID = value; + } + string getUniqueID() { + return uniqueID; + } - virtual void setRunningStatus(bool value); + virtual void setRunningStatus(bool value); - void setExecutingTask(bool value); - bool getExecutingTask(); + void setExecutingTask(bool value); + bool getExecutingTask(); - void setThreadOwnerValid(bool value); - bool getThreadOwnerValid(); - Mutex * getMutexThreadOwnerValid(); + void setThreadOwnerValid(bool value); + bool getThreadOwnerValid(); + Mutex * getMutexThreadOwnerValid(); + + Mutex * getMutexThreadObjectAccessor(); + + template + T * getGenericData() { + return genericData; + } + template + void setGenericData(T *value) { + genericData = value; + } + + static bool isThreadDeleted(void *ptr); + }; + + class RunningStatusSafeWrapper { + protected: + BaseThread *thread; + public: + + RunningStatusSafeWrapper(BaseThread *thread) { + this->thread = thread; + Enable(); + } + ~RunningStatusSafeWrapper() { + Disable(); + } + + void Enable() { + if (this->thread != NULL) { + this->thread->setRunningStatus(true); + } + } + void Disable() { + if (this->thread != NULL) { + this->thread->setRunningStatus(false); + } + } + }; + + class ExecutingTaskSafeWrapper { + protected: + BaseThread *thread; + public: + + ExecutingTaskSafeWrapper(BaseThread *thread) { + this->thread = thread; + Enable(); + } + ~ExecutingTaskSafeWrapper() { + Disable(); + } + + void Enable() { + if (this->thread != NULL) { + this->thread->setExecutingTask(true); + } + } + void Disable() { + if (this->thread != NULL) { + this->thread->setExecutingTask(false); + } + } + }; - Mutex * getMutexThreadObjectAccessor(); - template - T * getGenericData() { - return genericData; } - template - void setGenericData(T *value) { - genericData = value; - } - - static bool isThreadDeleted(void *ptr); -}; - -class RunningStatusSafeWrapper { -protected: - BaseThread *thread; -public: - - RunningStatusSafeWrapper(BaseThread *thread) { - this->thread = thread; - Enable(); - } - ~RunningStatusSafeWrapper() { - Disable(); - } - - void Enable() { - if(this->thread != NULL) { - this->thread->setRunningStatus(true); - } - } - void Disable() { - if(this->thread != NULL) { - this->thread->setRunningStatus(false); - } - } -}; - -class ExecutingTaskSafeWrapper { -protected: - BaseThread *thread; -public: - - ExecutingTaskSafeWrapper(BaseThread *thread) { - this->thread = thread; - Enable(); - } - ~ExecutingTaskSafeWrapper() { - Disable(); - } - - void Enable() { - if(this->thread != NULL) { - this->thread->setExecutingTask(true); - } - } - void Disable() { - if(this->thread != NULL) { - this->thread->setExecutingTask(false); - } - } -}; - - -}}//end namespace +}//end namespace #endif diff --git a/source/shared_lib/include/platform/common/byte_order.h b/source/shared_lib/include/platform/common/byte_order.h index 2451e5bf3..f3a6d1da8 100644 --- a/source/shared_lib/include/platform/common/byte_order.h +++ b/source/shared_lib/include/platform/common/byte_order.h @@ -15,65 +15,67 @@ #include #include "leak_dumper.h" -namespace Shared{ namespace PlatformByteOrder { +namespace Shared { + namespace PlatformByteOrder { -template T EndianReverse(T t) { -// unsigned char uc[sizeof t]; -// memcpy(uc, &t, sizeof t); -// -// for (unsigned char *b = uc, *e = uc + sizeof(T) - 1; b < e; ++b, --e) { -// std::swap(*b, *e); -// } -// memcpy(&t, uc, sizeof t); -// return t; + template T EndianReverse(T t) { + // unsigned char uc[sizeof t]; + // memcpy(uc, &t, sizeof t); + // + // for (unsigned char *b = uc, *e = uc + sizeof(T) - 1; b < e; ++b, --e) { + // std::swap(*b, *e); + // } + // memcpy(&t, uc, sizeof t); + // return t; - char& raw = reinterpret_cast(t); - std::reverse(&raw, &raw + sizeof(T)); - return t; -} - -inline static bool isBigEndian() { - short n = 0x1; - return (*(char*)(&n) == 0x0); -} - - -template T toCommonEndian(T t) { - static bool bigEndianSystem = isBigEndian(); - if(bigEndianSystem == true) { - t = EndianReverse(t); - } - return t; -} - -template T fromCommonEndian(T t) { - static bool bigEndianSystem = isBigEndian(); - if(bigEndianSystem == true) { - t = EndianReverse(t); - } - return t; -} - -template -void toEndianTypeArray(T *data, size_t size) { - static bool bigEndianSystem = isBigEndian(); - if(bigEndianSystem == true) { - for(size_t i = 0; i < size; ++i) { - data[i] = toCommonEndian(data[i]); + char& raw = reinterpret_cast(t); + std::reverse(&raw, &raw + sizeof(T)); + return t; } - } -} -template -void fromEndianTypeArray(T *data, size_t size) { - static bool bigEndianSystem = isBigEndian(); - if(bigEndianSystem == true) { - for(size_t i = 0; i < size; ++i) { - data[i] = fromCommonEndian(data[i]); + inline static bool isBigEndian() { + short n = 0x1; + return (*(char*) (&n) == 0x0); } + + + template T toCommonEndian(T t) { + static bool bigEndianSystem = isBigEndian(); + if (bigEndianSystem == true) { + t = EndianReverse(t); + } + return t; + } + + template T fromCommonEndian(T t) { + static bool bigEndianSystem = isBigEndian(); + if (bigEndianSystem == true) { + t = EndianReverse(t); + } + return t; + } + + template + void toEndianTypeArray(T *data, size_t size) { + static bool bigEndianSystem = isBigEndian(); + if (bigEndianSystem == true) { + for (size_t i = 0; i < size; ++i) { + data[i] = toCommonEndian(data[i]); + } + } + } + + template + void fromEndianTypeArray(T *data, size_t size) { + static bool bigEndianSystem = isBigEndian(); + if (bigEndianSystem == true) { + for (size_t i = 0; i < size; ++i) { + data[i] = fromCommonEndian(data[i]); + } + } + } + } } -}} - #endif diff --git a/source/shared_lib/include/platform/common/cache_manager.h b/source/shared_lib/include/platform/common/cache_manager.h index 9acc56cc0..04b84e331 100644 --- a/source/shared_lib/include/platform/common/cache_manager.h +++ b/source/shared_lib/include/platform/common/cache_manager.h @@ -23,116 +23,116 @@ using namespace std; using namespace Shared::Platform; -namespace Shared { namespace PlatformCommon { +namespace Shared { + namespace PlatformCommon { -// ===================================================== -// class BaseThread -// ===================================================== + // ===================================================== + // class BaseThread + // ===================================================== -class CacheManager -{ -public: + class CacheManager { + public: -static const char *getFolderTreeContentsCheckSumRecursivelyCacheLookupKey1; -static const char *getFolderTreeContentsCheckSumRecursivelyCacheLookupKey2; -static const char *getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey1; -static const char *getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey2; + static const char *getFolderTreeContentsCheckSumRecursivelyCacheLookupKey1; + static const char *getFolderTreeContentsCheckSumRecursivelyCacheLookupKey2; + static const char *getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey1; + static const char *getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey2; -protected: - static std::map itemCacheMutexList; - static Mutex mutexMap; - typedef enum { - cacheItemGet, - cacheItemSet - } CacheAccessorType; + protected: + static std::map itemCacheMutexList; + static Mutex mutexMap; + typedef enum { + cacheItemGet, + cacheItemSet + } CacheAccessorType; - static Mutex & manageCachedItemMutex(string cacheKey) { - if(itemCacheMutexList.find(cacheKey) == itemCacheMutexList.end()) { - MutexSafeWrapper safeMutex(&mutexMap); - if(itemCacheMutexList.find(cacheKey) == itemCacheMutexList.end()) { - itemCacheMutexList[cacheKey] = new Mutex(CODE_AT_LINE); - } - safeMutex.ReleaseLock(); - } - Mutex *mutex = itemCacheMutexList[cacheKey]; - return *mutex; - } - - template - static T & manageCachedItem(string cacheKey, T *value,CacheAccessorType accessor) { - // Here is the actual type-safe instantiation - static std::map itemCache; - if(accessor == cacheItemSet) { - if(value == NULL) { - try { - Mutex &mutexCache = manageCachedItemMutex(cacheKey); - MutexSafeWrapper safeMutex(&mutexCache); - if(itemCache.find(cacheKey) != itemCache.end()) { - itemCache.erase(cacheKey); + static Mutex & manageCachedItemMutex(string cacheKey) { + if (itemCacheMutexList.find(cacheKey) == itemCacheMutexList.end()) { + MutexSafeWrapper safeMutex(&mutexMap); + if (itemCacheMutexList.find(cacheKey) == itemCacheMutexList.end()) { + itemCacheMutexList[cacheKey] = new Mutex(CODE_AT_LINE); } safeMutex.ReleaseLock(); } - catch(const std::exception &ex) { - throw megaglest_runtime_error(ex.what()); - } - + Mutex *mutex = itemCacheMutexList[cacheKey]; + return *mutex; } - if(value != NULL) { - try { - Mutex &mutexCache = manageCachedItemMutex(cacheKey); - MutexSafeWrapper safeMutex(&mutexCache); - itemCache[cacheKey] = *value; - safeMutex.ReleaseLock(); - } - catch(const std::exception &ex) { - throw megaglest_runtime_error(ex.what()); + + template + static T & manageCachedItem(string cacheKey, T *value, CacheAccessorType accessor) { + // Here is the actual type-safe instantiation + static std::map itemCache; + if (accessor == cacheItemSet) { + if (value == NULL) { + try { + Mutex &mutexCache = manageCachedItemMutex(cacheKey); + MutexSafeWrapper safeMutex(&mutexCache); + if (itemCache.find(cacheKey) != itemCache.end()) { + itemCache.erase(cacheKey); + } + safeMutex.ReleaseLock(); + } catch (const std::exception &ex) { + throw megaglest_runtime_error(ex.what()); + } + + } + if (value != NULL) { + try { + Mutex &mutexCache = manageCachedItemMutex(cacheKey); + MutexSafeWrapper safeMutex(&mutexCache); + itemCache[cacheKey] = *value; + safeMutex.ReleaseLock(); + } catch (const std::exception &ex) { + throw megaglest_runtime_error(ex.what()); + } + } } + // If this is the first access we return a default object of the type + Mutex &mutexCache = manageCachedItemMutex(cacheKey); + MutexSafeWrapper safeMutex(&mutexCache); + + return itemCache[cacheKey]; } - } - // If this is the first access we return a default object of the type - Mutex &mutexCache = manageCachedItemMutex(cacheKey); - MutexSafeWrapper safeMutex(&mutexCache); - return itemCache[cacheKey]; - } + public: -public: + CacheManager() { + } + static void cleanupMutexes() { + MutexSafeWrapper safeMutex(&mutexMap); + for (std::map::iterator iterMap = itemCacheMutexList.begin(); + iterMap != itemCacheMutexList.end(); iterMap++) { + delete iterMap->second; + iterMap->second = NULL; + } + itemCacheMutexList.clear(); + safeMutex.ReleaseLock(); + } + ~CacheManager() { + CacheManager::cleanupMutexes(); + } - CacheManager() { } - static void cleanupMutexes() { - MutexSafeWrapper safeMutex(&mutexMap); - for(std::map::iterator iterMap = itemCacheMutexList.begin(); - iterMap != itemCacheMutexList.end(); iterMap++) { - delete iterMap->second; - iterMap->second = NULL; - } - itemCacheMutexList.clear(); - safeMutex.ReleaseLock(); - } - ~CacheManager() { - CacheManager::cleanupMutexes(); - } + template + static void setCachedItem(string cacheKey, const T value) { + manageCachedItem(cacheKey, value, cacheItemSet); + } + template + static T & getCachedItem(string cacheKey) { + return manageCachedItem(cacheKey, NULL, cacheItemGet); + } + template + static void clearCachedItem(string cacheKey) { + return manageCachedItem(cacheKey, NULL, cacheItemSet); + } - template - static void setCachedItem(string cacheKey, const T value) { - manageCachedItem(cacheKey,value,cacheItemSet); - } - template - static T & getCachedItem(string cacheKey) { - return manageCachedItem(cacheKey,NULL,cacheItemGet); - } - template - static void clearCachedItem(string cacheKey) { - return manageCachedItem(cacheKey,NULL,cacheItemSet); - } + template + static Mutex & getMutexForItem(string cacheKey) { + return manageCachedItemMutex(cacheKey); + } + }; - template - static Mutex & getMutexForItem(string cacheKey) { - return manageCachedItemMutex(cacheKey); } -}; - -}}//end namespace +}//end namespace #endif diff --git a/source/shared_lib/include/platform/common/common_scoped_ptr.h b/source/shared_lib/include/platform/common/common_scoped_ptr.h index dcdc4bb55..ad18eabc2 100644 --- a/source/shared_lib/include/platform/common/common_scoped_ptr.h +++ b/source/shared_lib/include/platform/common/common_scoped_ptr.h @@ -25,7 +25,7 @@ #if defined(WIN32) #define auto_ptr unique_ptr #else - #define auto_ptr std::unique_ptr +#define auto_ptr std::unique_ptr #endif #endif diff --git a/source/shared_lib/include/platform/common/platform_common.h b/source/shared_lib/include/platform/common/platform_common.h index ec4637c2f..585c4fcec 100644 --- a/source/shared_lib/include/platform/common/platform_common.h +++ b/source/shared_lib/include/platform/common/platform_common.h @@ -40,295 +40,297 @@ using std::exception; using Shared::Platform::int64; using Shared::Util::Checksum; -namespace Shared { namespace PlatformCommon { +namespace Shared { + namespace PlatformCommon { #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #define CODE_AT_LINE __FILE__ ":" TOSTRING(__LINE__) #define CODE_AT_LINE_X(x) __FILE__ ":" TOSTRING(__LINE__) ":" TOSTRING(x) -static const int IGNORE_CMD_RESULT_VALUE = -999999; + static const int IGNORE_CMD_RESULT_VALUE = -999999; -// keycode constants (unfortunately designed after DirectInput and therefore not -// very specific) -// They also have to fit into a char. The positive numbers seem to be equal -// to ascii, for the rest we have to find sensefull mappings from SDL (which is -// alot more fine grained like left/right control instead of just control...) -const char vkAdd = -1; -const char vkSubtract = -2; -const char vkAlt = -3; -const char vkControl = -4; -const char vkShift = -5; -const char vkEscape = -6; -const char vkUp = -7; -const char vkLeft = -8; -const char vkRight = -9; -const char vkDown = -10; -const char vkReturn = -11; -const char vkBack = -12; -const char vkTab = -13; -const char vkF1 = -14; -const char vkF2 = -15; -const char vkF3 = -16; -const char vkF4 = -17; -const char vkF5 = -18; -const char vkF6 = -19; -const char vkF7 = -20; -const char vkF8 = -21; -const char vkF9 = -22; -const char vkF10 = -23; -const char vkF11 = -24; -const char vkF12 = -25; -const char vkDelete = -26; -const char vkPrint = -27; -const char vkPause = -29; + // keycode constants (unfortunately designed after DirectInput and therefore not + // very specific) + // They also have to fit into a char. The positive numbers seem to be equal + // to ascii, for the rest we have to find sensefull mappings from SDL (which is + // alot more fine grained like left/right control instead of just control...) + const char vkAdd = -1; + const char vkSubtract = -2; + const char vkAlt = -3; + const char vkControl = -4; + const char vkShift = -5; + const char vkEscape = -6; + const char vkUp = -7; + const char vkLeft = -8; + const char vkRight = -9; + const char vkDown = -10; + const char vkReturn = -11; + const char vkBack = -12; + const char vkTab = -13; + const char vkF1 = -14; + const char vkF2 = -15; + const char vkF3 = -16; + const char vkF4 = -17; + const char vkF5 = -18; + const char vkF6 = -19; + const char vkF7 = -20; + const char vkF8 = -21; + const char vkF9 = -22; + const char vkF10 = -23; + const char vkF11 = -24; + const char vkF12 = -25; + const char vkDelete = -26; + const char vkPrint = -27; + const char vkPause = -29; -class ShellCommandOutputCallbackInterface { -public: - virtual ~ShellCommandOutputCallbackInterface() {} + class ShellCommandOutputCallbackInterface { + public: + virtual ~ShellCommandOutputCallbackInterface() { + } - virtual void * getShellCommandOutput_UserData(string cmd) = 0; - virtual void ShellCommandOutput_CallbackEvent(string cmd,char *output,void *userdata) = 0; -}; + virtual void * getShellCommandOutput_UserData(string cmd) = 0; + virtual void ShellCommandOutput_CallbackEvent(string cmd, char *output, void *userdata) = 0; + }; -//typedef std::chrono::time_point system_time_point; -tm threadsafe_localtime(const time_t &time); -// extracting std::time_t from std:chrono for "now" -time_t systemtime_now(); + //typedef std::chrono::time_point system_time_point; + tm threadsafe_localtime(const time_t &time); + // extracting std::time_t from std:chrono for "now" + time_t systemtime_now(); -// ===================================================== -// class PerformanceTimer -// ===================================================== + // ===================================================== + // class PerformanceTimer + // ===================================================== -class PerformanceTimer { -private: - Uint32 lastTicks; - Uint32 updateTicks; + class PerformanceTimer { + private: + Uint32 lastTicks; + Uint32 updateTicks; - int times; // number of consecutive times - int maxTimes; // maximum number consecutive times + int times; // number of consecutive times + int maxTimes; // maximum number consecutive times -public: - void init(float fps, int maxTimes= -1); + public: + void init(float fps, int maxTimes = -1); - bool isTime(); - void reset(); -}; + bool isTime(); + void reset(); + }; -// ===================================================== -// class Chrono -// ===================================================== + // ===================================================== + // class Chrono + // ===================================================== -class Chrono { -private: - Uint32 startCount; - Uint32 accumCount; - Uint32 freq; - bool stopped; + class Chrono { + private: + Uint32 startCount; + Uint32 accumCount; + Uint32 freq; + bool stopped; - Uint32 lastStartCount; - Uint32 lastTickCount; - int64 lastResult; - int64 lastMultiplier; - bool lastStopped; + Uint32 lastStartCount; + Uint32 lastTickCount; + int64 lastResult; + int64 lastMultiplier; + bool lastStopped; -public: - Chrono(bool autoStart=false); - void start(); - void stop(); - void reset(); - int64 getMicros(); - int64 getMillis(); - int64 getSeconds(); + public: + Chrono(bool autoStart = false); + void start(); + void stop(); + void reset(); + int64 getMicros(); + int64 getMillis(); + int64 getSeconds(); - bool isStarted() const; - static int64 getCurTicks(); - static int64 getCurMillis(); + bool isStarted() const; + static int64 getCurTicks(); + static int64 getCurMillis(); -private: - int64 queryCounter(int64 multiplier); -}; + private: + int64 queryCounter(int64 multiplier); + }; -// ===================================================== -// class ModeInfo -// ===================================================== -class ModeInfo { -public: - int width; - int height; - int depth; + // ===================================================== + // class ModeInfo + // ===================================================== + class ModeInfo { + public: + int width; + int height; + int depth; - ModeInfo(int width, int height, int depth); + ModeInfo(int width, int height, int depth); - bool operator< (const ModeInfo &j) const { - if(this->width < j.width) { - return true; - } - else if(this->width == j.width && this->height < j.height) { - return true; - } - else if(this->width == j.width && - this->height == j.height && - this->depth < j.depth) { - return true; + bool operator< (const ModeInfo &j) const { + if (this->width < j.width) { + return true; + } else if (this->width == j.width && this->height < j.height) { + return true; + } else if (this->width == j.width && + this->height == j.height && + this->depth < j.depth) { + return true; + } + + return false; + } + string getString() const; + }; + + // ===================================================== + // Misc + // ===================================================== + void Tokenize(const string& str, vector& tokens, const string& delimiters = " "); + bool isdir(const char *path); + bool fileExists(const string &path); + inline bool folderExists(const string &path) { + return isdir(path.c_str()); } - return false; - } - string getString() const; -}; + void findDirs(const string &path, vector &results, bool errorOnNotFound, bool keepDuplicates); + void findDirs(const vector &paths, vector &results, bool errorOnNotFound = false, bool keepDuplicates = false); + void findAll(const vector &paths, const string &fileFilter, vector &results, bool cutExtension = false, bool errorOnNotFound = true, bool keepDuplicates = false); + void findAll(const string &path, vector &results, bool cutExtension = false, bool errorOnNotFound = true); + vector getFolderTreeContentsListRecursively(const string &path, const string &filterFileExt, bool includeFolders = false, vector *recursiveMap = NULL); -// ===================================================== -// Misc -// ===================================================== -void Tokenize(const string& str,vector& tokens,const string& delimiters = " "); -bool isdir(const char *path); -bool fileExists(const string &path); -inline bool folderExists(const string &path) { return isdir(path.c_str()); } + //string getGameVersion(); + //string getGameGITVersion(); + void setGameVersion(const string &version); + void setGameGITVersion(const string &git); -void findDirs(const string &path, vector &results, bool errorOnNotFound,bool keepDuplicates); -void findDirs(const vector &paths, vector &results, bool errorOnNotFound=false,bool keepDuplicates=false); -void findAll(const vector &paths, const string &fileFilter, vector &results, bool cutExtension=false, bool errorOnNotFound=true,bool keepDuplicates=false); -void findAll(const string &path, vector &results, bool cutExtension=false, bool errorOnNotFound=true); -vector getFolderTreeContentsListRecursively(const string &path, const string &filterFileExt, bool includeFolders=false, vector *recursiveMap=NULL); + string getCRCCacheFilePath(); + void setCRCCacheFilePath(const string &path); -//string getGameVersion(); -//string getGameGITVersion(); -void setGameVersion(const string &version); -void setGameGITVersion(const string &git); + std::pair getFolderTreeContentsCheckSumCacheKey(vector paths, const string &pathSearchString, const string &filterFileExt); + void clearFolderTreeContentsCheckSum(vector paths, const string &pathSearchString, const string &filterFileExt); + uint32 getFolderTreeContentsCheckSumRecursively(vector paths, string pathSearchString, const string &filterFileExt, Checksum *recursiveChecksum, bool forceNoCache = false); + time_t getFolderTreeContentsCheckSumRecursivelyLastGenerated(const vector &paths, string pathSearchString, const string &filterFileExt); -string getCRCCacheFilePath(); -void setCRCCacheFilePath(const string &path); + std::pair getFolderTreeContentsCheckSumCacheKey(const string &path, const string &filterFileExt); + void clearFolderTreeContentsCheckSum(const string &path, const string &filterFileExt); + uint32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum, bool forceNoCache = false); -std::pair getFolderTreeContentsCheckSumCacheKey(vector paths, const string &pathSearchString, const string &filterFileExt); -void clearFolderTreeContentsCheckSum(vector paths, const string &pathSearchString, const string &filterFileExt); -uint32 getFolderTreeContentsCheckSumRecursively(vector paths, string pathSearchString, const string &filterFileExt, Checksum *recursiveChecksum,bool forceNoCache=false); -time_t getFolderTreeContentsCheckSumRecursivelyLastGenerated(const vector &paths, string pathSearchString, const string &filterFileExt); + std::pair getFolderTreeContentsCheckSumListCacheKey(vector paths, const string &pathSearchString, const string &filterFileExt); + void clearFolderTreeContentsCheckSumList(vector paths, const string &pathSearchString, const string &filterFileExt); + vector > getFolderTreeContentsCheckSumListRecursively(vector paths, const string &pathSearchString, const string &filterFileExt, vector > *recursiveMap); -std::pair getFolderTreeContentsCheckSumCacheKey(const string &path, const string &filterFileExt); -void clearFolderTreeContentsCheckSum(const string &path, const string &filterFileExt); -uint32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum,bool forceNoCache=false); + std::pair getFolderTreeContentsCheckSumListCacheKey(const string &path, const string &filterFileExt); + void clearFolderTreeContentsCheckSumList(const string &path, const string &filterFileExt); + vector > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector > *recursiveMap); -std::pair getFolderTreeContentsCheckSumListCacheKey(vector paths, const string &pathSearchString, const string &filterFileExt); -void clearFolderTreeContentsCheckSumList(vector paths, const string &pathSearchString, const string &filterFileExt); -vector > getFolderTreeContentsCheckSumListRecursively(vector paths, const string &pathSearchString, const string &filterFileExt, vector > *recursiveMap); + void createDirectoryPaths(string Path); + string extractFileFromDirectoryPath(string filename); + string extractDirectoryPathFromFile(string filename); + string extractLastDirectoryFromPath(string Path); + string extractExtension(const string& filename); -std::pair getFolderTreeContentsCheckSumListCacheKey(const string &path, const string &filterFileExt); -void clearFolderTreeContentsCheckSumList(const string &path, const string &filterFileExt); -vector > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector > *recursiveMap); + void getFullscreenVideoModes(vector *modeinfos, bool isFullscreen); + void getFullscreenVideoInfo(int &colorBits, int &screenWidth, int &screenHeight, bool isFullscreen); + void changeVideoModeFullScreen(bool value); + void restoreVideoMode(SDL_Window *sdlWindow, bool exitingApp = false); -void createDirectoryPaths(string Path); -string extractFileFromDirectoryPath(string filename); -string extractDirectoryPathFromFile(string filename); -string extractLastDirectoryFromPath(string Path); -string extractExtension(const string& filename); + bool StartsWith(const std::string &str, const std::string &key); + bool EndsWith(const string &str, const string& key); -void getFullscreenVideoModes(vector *modeinfos,bool isFullscreen); -void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight,bool isFullscreen); -void changeVideoModeFullScreen(bool value); -void restoreVideoMode(SDL_Window *sdlWindow,bool exitingApp=false); + void endPathWithSlash(string &path, bool requireOSSlash = false); + void trimPathWithStartingSlash(string &path); + void updatePathClimbingParts(string &path, bool processPreviousDirTokenCheck = true); + string formatPath(string path); -bool StartsWith(const std::string &str, const std::string &key); -bool EndsWith(const string &str, const string& key); + string replaceAllHTMLEntities(string& context); + string replaceAll(string& context, const string& from, const string& to); + vector replaceAllBetweenTokens(vector& context, const string &startToken, const string &endToken, const string &newText, bool removeTokens = true); + string replaceAllBetweenTokens(string& context, const string &startToken, const string &endToken, const string &newText, bool removeTokens = true); + bool removeFile(string file); + bool renameFile(string oldFile, string newFile); + void removeFolder(const string &path); + off_t getFileSize(string filename); + bool searchAndReplaceTextInFile(string fileName, string findText, string replaceText, bool simulateOnly); + void copyFileTo(string fromFileName, string toFileName); -void endPathWithSlash(string &path, bool requireOSSlash=false); -void trimPathWithStartingSlash(string &path); -void updatePathClimbingParts(string &path,bool processPreviousDirTokenCheck=true); -string formatPath(string path); + //int getScreenW(); + //int getScreenH(); -string replaceAllHTMLEntities(string& context); -string replaceAll(string& context, const string& from, const string& to); -vector replaceAllBetweenTokens(vector& context, const string &startToken, const string &endToken, const string &newText, bool removeTokens=true); -string replaceAllBetweenTokens(string& context, const string &startToken, const string &endToken, const string &newText, bool removeTokens=true); -bool removeFile(string file); -bool renameFile(string oldFile, string newFile); -void removeFolder(const string &path); -off_t getFileSize(string filename); -bool searchAndReplaceTextInFile(string fileName, string findText, string replaceText, bool simulateOnly); -void copyFileTo(string fromFileName, string toFileName); + void sleep(int millis); -//int getScreenW(); -//int getScreenH(); + bool isCursorShowing(); + void showCursor(bool b); + bool isKeyDown(int virtualKey); + //bool isKeyDown(SDLKey key); + string getCommandLine(); -void sleep(int millis); - -bool isCursorShowing(); -void showCursor(bool b); -bool isKeyDown(int virtualKey); -//bool isKeyDown(SDLKey key); -string getCommandLine(); - -string getUserHome(); + string getUserHome(); #define SPACES " " -inline string trim_at_delim (const string & s, const string &t) { - string d (s); - string::size_type i(d.find(t)); - //printf("Searching for [%s] in [%s] got " MG_SIZE_T_SPECIFIER "\n",t.c_str(),d.c_str(),i); + inline string trim_at_delim(const string & s, const string &t) { + string d(s); + string::size_type i(d.find(t)); + //printf("Searching for [%s] in [%s] got " MG_SIZE_T_SPECIFIER "\n",t.c_str(),d.c_str(),i); - if (i == string::npos) { - return d; - } - else { - d = d.erase (i) ; - //printf("returning [%s]\n",d.c_str()); - return d; - } -} + if (i == string::npos) { + return d; + } else { + d = d.erase(i); + //printf("returning [%s]\n",d.c_str()); + return d; + } + } -inline string trim_right (const string & s, const string & t = SPACES) { - string d (s); - string::size_type i (d.find_last_not_of (t)); - if (i == string::npos) - return ""; - else - return d.erase (d.find_last_not_of (t) + 1) ; -} // end of trim_right + inline string trim_right(const string & s, const string & t = SPACES) { + string d(s); + string::size_type i(d.find_last_not_of(t)); + if (i == string::npos) + return ""; + else + return d.erase(d.find_last_not_of(t) + 1); + } // end of trim_right -inline string trim_left (const string & s, const string & t = SPACES) { - string d (s); - return d.erase (0, s.find_first_not_of (t)) ; -} // end of trim_left + inline string trim_left(const string & s, const string & t = SPACES) { + string d(s); + return d.erase(0, s.find_first_not_of(t)); + } // end of trim_left -inline string trim (const string & s, const string & t = SPACES) { - string d (s); - return trim_left (trim_right (d, t), t) ; -} // end of trim + inline string trim(const string & s, const string & t = SPACES) { + string d(s); + return trim_left(trim_right(d, t), t); + } // end of trim -string getFullFileArchiveExtractCommand(const string &fileArchiveExtractCommand, - string fileArchiveExtractCommandParameters, const string &outputpath, const string &archivename); -string getFullFileArchiveCompressCommand(const string &fileArchiveCompressCommand, - string fileArchiveCompressCommandParameters, const string &archivename, const string &archivefiles); + string getFullFileArchiveExtractCommand(const string &fileArchiveExtractCommand, + string fileArchiveExtractCommandParameters, const string &outputpath, const string &archivename); + string getFullFileArchiveCompressCommand(const string &fileArchiveCompressCommand, + string fileArchiveCompressCommandParameters, const string &archivename, const string &archivefiles); -bool executeShellCommand(string cmd,int expectedResult=IGNORE_CMD_RESULT_VALUE,ShellCommandOutputCallbackInterface *cb=NULL); -string executable_path(const string &exeName,bool includeExeNameInPath=false); + bool executeShellCommand(string cmd, int expectedResult = IGNORE_CMD_RESULT_VALUE, ShellCommandOutputCallbackInterface *cb = NULL); + string executable_path(const string &exeName, bool includeExeNameInPath = false); -void saveDataToFile(string filename, const string &data); + void saveDataToFile(string filename, const string &data); -bool valid_utf8_file(const char* file_name); + bool valid_utf8_file(const char* file_name); -//string getFileTextContents(string path); + //string getFileTextContents(string path); -string safeCharPtrCopy(const char *ptr, int maxLength=-1); + string safeCharPtrCopy(const char *ptr, int maxLength = -1); -class ValueCheckerVault { + class ValueCheckerVault { -protected: - std::map vaultList; + protected: + std::map vaultList; - void addItemToVault(const void *ptr,int value); - void checkItemInVault(const void *ptr,int value) const; + void addItemToVault(const void *ptr, int value); + void checkItemInVault(const void *ptr, int value) const; + + public: + + ValueCheckerVault() { + vaultList.clear(); + } + }; -public: - ValueCheckerVault() { - vaultList.clear(); } -}; - - -}}//end namespace +}//end namespace #endif diff --git a/source/shared_lib/include/platform/common/simple_threads.h b/source/shared_lib/include/platform/common/simple_threads.h index 3b2fd49a8..ac59fbf63 100644 --- a/source/shared_lib/include/platform/common/simple_threads.h +++ b/source/shared_lib/include/platform/common/simple_threads.h @@ -22,153 +22,166 @@ using namespace std; using namespace Shared::Util; using namespace Shared::Graphics; -namespace Shared { namespace PlatformCommon { +namespace Shared { + namespace PlatformCommon { -// -// This interface describes the methods a callback object must implement -// -class FileCRCPreCacheThreadCallbackInterface { -public: - virtual vector processTech(string techName) = 0; - virtual ~FileCRCPreCacheThreadCallbackInterface() {} -}; + // + // This interface describes the methods a callback object must implement + // + class FileCRCPreCacheThreadCallbackInterface { + public: + virtual vector processTech(string techName) = 0; + virtual ~FileCRCPreCacheThreadCallbackInterface() { + } + }; -// ===================================================== -// class FileCRCPreCacheThread -// ===================================================== + // ===================================================== + // class FileCRCPreCacheThread + // ===================================================== -class FileCRCPreCacheThread : public BaseThread -{ -protected: - vector techDataPaths; - vector workerThreadTechPaths; - FileCRCPreCacheThreadCallbackInterface *processTechCB; + class FileCRCPreCacheThread : public BaseThread { + protected: + vector techDataPaths; + vector workerThreadTechPaths; + FileCRCPreCacheThreadCallbackInterface *processTechCB; - static string preCacheThreadCacheLookupKey; - Mutex *mutexPauseForGame; - bool pauseForGame; - std::vector preCacheWorkerThreadList; + static string preCacheThreadCacheLookupKey; + Mutex *mutexPauseForGame; + bool pauseForGame; + std::vector preCacheWorkerThreadList; -public: - FileCRCPreCacheThread(); - FileCRCPreCacheThread(vector techDataPaths,vector workerThreadTechPaths,FileCRCPreCacheThreadCallbackInterface *processTechCB); - virtual ~FileCRCPreCacheThread(); + public: + FileCRCPreCacheThread(); + FileCRCPreCacheThread(vector techDataPaths, vector workerThreadTechPaths, FileCRCPreCacheThreadCallbackInterface *processTechCB); + virtual ~FileCRCPreCacheThread(); - static void setPreCacheThreadCacheLookupKey(string value) { preCacheThreadCacheLookupKey = value; } + static void setPreCacheThreadCacheLookupKey(string value) { + preCacheThreadCacheLookupKey = value; + } - virtual void execute(); - void setTechDataPaths(vector value) { this->techDataPaths = value; } - void setWorkerThreadTechPaths(vector value) { this->workerThreadTechPaths = value; } - void setFileCRCPreCacheThreadCallbackInterface(FileCRCPreCacheThreadCallbackInterface *value) { processTechCB = value; } + virtual void execute(); + void setTechDataPaths(vector value) { + this->techDataPaths = value; + } + void setWorkerThreadTechPaths(vector value) { + this->workerThreadTechPaths = value; + } + void setFileCRCPreCacheThreadCallbackInterface(FileCRCPreCacheThreadCallbackInterface *value) { + processTechCB = value; + } - virtual bool canShutdown(bool deleteSelfIfShutdownDelayed); + virtual bool canShutdown(bool deleteSelfIfShutdownDelayed); - void setPauseForGame(bool pauseForGame); - bool getPauseForGame(); -}; + void setPauseForGame(bool pauseForGame); + bool getPauseForGame(); + }; -// ===================================================== -// class SimpleTaskThread -// ===================================================== -typedef void taskFunctionCallback(BaseThread *callingThread); -// -// This interface describes the methods a callback object must implement -// -class SimpleTaskCallbackInterface { -public: - virtual void simpleTask(BaseThread *callingThread,void *userdata) = 0; + // ===================================================== + // class SimpleTaskThread + // ===================================================== + typedef void taskFunctionCallback(BaseThread *callingThread); + // + // This interface describes the methods a callback object must implement + // + class SimpleTaskCallbackInterface { + public: + virtual void simpleTask(BaseThread *callingThread, void *userdata) = 0; - virtual void setupTask(BaseThread *callingThread,void *userdata) { } - virtual void shutdownTask(BaseThread *callingThread,void *userdata) { } + virtual void setupTask(BaseThread *callingThread, void *userdata) { + } + virtual void shutdownTask(BaseThread *callingThread, void *userdata) { + } - virtual ~SimpleTaskCallbackInterface() {} -}; + virtual ~SimpleTaskCallbackInterface() { + } + }; -class SimpleTaskThread : public BaseThread -{ -protected: + class SimpleTaskThread : public BaseThread { + protected: - Mutex *mutexSimpleTaskInterfaceValid; - bool simpleTaskInterfaceValid; - SimpleTaskCallbackInterface *simpleTaskInterface; - unsigned int executionCount; - unsigned int millisecsBetweenExecutions; + Mutex *mutexSimpleTaskInterfaceValid; + bool simpleTaskInterfaceValid; + SimpleTaskCallbackInterface *simpleTaskInterface; + unsigned int executionCount; + unsigned int millisecsBetweenExecutions; - Mutex *mutexTaskSignaller; - bool taskSignalled; - bool needTaskSignal; + Mutex *mutexTaskSignaller; + bool taskSignalled; + bool needTaskSignal; - Mutex *mutexLastExecuteTimestamp; - time_t lastExecuteTimestamp; + Mutex *mutexLastExecuteTimestamp; + time_t lastExecuteTimestamp; - taskFunctionCallback *overrideShutdownTask; - void *userdata; - bool wantSetupAndShutdown; + taskFunctionCallback *overrideShutdownTask; + void *userdata; + bool wantSetupAndShutdown; -public: - SimpleTaskThread(SimpleTaskCallbackInterface *simpleTaskInterface, - unsigned int executionCount=0, - unsigned int millisecsBetweenExecutions=0, - bool needTaskSignal = false, - void *userdata=NULL, - bool wantSetupAndShutdown=true); - virtual ~SimpleTaskThread(); + public: + SimpleTaskThread(SimpleTaskCallbackInterface *simpleTaskInterface, + unsigned int executionCount = 0, + unsigned int millisecsBetweenExecutions = 0, + bool needTaskSignal = false, + void *userdata = NULL, + bool wantSetupAndShutdown = true); + virtual ~SimpleTaskThread(); + + virtual void * getUserdata() { + return userdata; + } + virtual int getUserdataAsInt() { + int value = 0; + if (userdata) { + value = *((int*) &userdata); + } + return value; + } + virtual void execute(); + virtual bool canShutdown(bool deleteSelfIfShutdownDelayed = false); + + void setTaskSignalled(bool value); + bool getTaskSignalled(); + + bool isThreadExecutionLagging(); + + void cleanup(); + + void setOverrideShutdownTask(taskFunctionCallback *ptr); + + bool getSimpleTaskInterfaceValid(); + void setSimpleTaskInterfaceValid(bool value); + }; + + // ===================================================== + // class LogFileThread + // ===================================================== + + class LogFileEntry { + public: + SystemFlags::DebugType type; + string entry; + time_t entryDateTime; + }; + + class LogFileThread : public BaseThread { + protected: + + Mutex *mutexLogList; + vector logList; + time_t lastSaveToDisk; + + void saveToDisk(bool forceSaveAll, bool logListAlreadyLocked); + bool checkSaveCurrentLogBufferToDisk(); + + public: + LogFileThread(); + virtual ~LogFileThread(); + virtual void execute(); + void addLogEntry(SystemFlags::DebugType type, string logEntry); + std::size_t getLogEntryBufferCount(); + virtual bool canShutdown(bool deleteSelfIfShutdownDelayed = false); + }; - virtual void * getUserdata() { return userdata; } - virtual int getUserdataAsInt() { - int value = 0; - if(userdata) { - value = *((int*)&userdata); - } - return value; } - virtual void execute(); - virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false); - - void setTaskSignalled(bool value); - bool getTaskSignalled(); - - bool isThreadExecutionLagging(); - - void cleanup(); - - void setOverrideShutdownTask(taskFunctionCallback *ptr); - - bool getSimpleTaskInterfaceValid(); - void setSimpleTaskInterfaceValid(bool value); -}; - -// ===================================================== -// class LogFileThread -// ===================================================== - -class LogFileEntry { -public: - SystemFlags::DebugType type; - string entry; - time_t entryDateTime; -}; - -class LogFileThread : public BaseThread -{ -protected: - - Mutex *mutexLogList; - vector logList; - time_t lastSaveToDisk; - - void saveToDisk(bool forceSaveAll,bool logListAlreadyLocked); - bool checkSaveCurrentLogBufferToDisk(); - -public: - LogFileThread(); - virtual ~LogFileThread(); - virtual void execute(); - void addLogEntry(SystemFlags::DebugType type, string logEntry); - std::size_t getLogEntryBufferCount(); - virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false); -}; - -}}//end namespace +}//end namespace #endif diff --git a/source/shared_lib/include/platform/common/streflop_cond.h b/source/shared_lib/include/platform/common/streflop_cond.h index 1ec17a788..0391a4fc1 100644 --- a/source/shared_lib/include/platform/common/streflop_cond.h +++ b/source/shared_lib/include/platform/common/streflop_cond.h @@ -49,7 +49,7 @@ namespace math { using std::exp; using std::frexp; using std::ldexp; -// the following are C99 functions -> not supported by VS C + // the following are C99 functions -> not supported by VS C #if !defined(_MSC_VER) || _MSC_VER < 1500 using std::isnan; using std::isinf; diff --git a/source/shared_lib/include/platform/miniupnpc/bsdqueue.h b/source/shared_lib/include/platform/miniupnpc/bsdqueue.h index c6afe1f7c..8edf9d0f7 100644 --- a/source/shared_lib/include/platform/miniupnpc/bsdqueue.h +++ b/source/shared_lib/include/platform/miniupnpc/bsdqueue.h @@ -35,52 +35,52 @@ #ifndef _SYS_QUEUE_H_ #define _SYS_QUEUE_H_ -/* - * This file defines five types of data structures: singly-linked lists, - * lists, simple queues, tail queues, and circular queues. - * - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A simple queue is headed by a pair of pointers, one the head of the - * list and the other to the tail of the list. The elements are singly - * linked to save space, so elements can only be removed from the - * head of the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the - * list. A simple queue may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * A circle queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the list. - * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. - * - * For details on the use of these macros, see the queue(3) manual page. - */ + /* + * This file defines five types of data structures: singly-linked lists, + * lists, simple queues, tail queues, and circular queues. + * + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A simple queue is headed by a pair of pointers, one the head of the + * list and the other to the tail of the list. The elements are singly + * linked to save space, so elements can only be removed from the + * head of the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the + * list. A simple queue may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * A circle queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the list. + * A circle queue may be traversed in either direction, but has a more + * complex end of list detection. + * + * For details on the use of these macros, see the queue(3) manual page. + */ #ifdef QUEUE_MACRO_DEBUG #define _Q_INVALIDATE(a) (a) = ((void *)-1) @@ -88,9 +88,9 @@ #define _Q_INVALIDATE(a) #endif -/* - * Singly-linked List definitions. - */ + /* + * Singly-linked List definitions. + */ #define SLIST_HEAD(name, type) \ struct name { \ struct type *slh_first; /* first element */ \ @@ -108,9 +108,9 @@ struct { \ struct type *sle_next; /* next element */ \ } -/* - * Singly-linked List access methods. - */ + /* + * Singly-linked List access methods. + */ #define SLIST_FIRST(head) ((head)->slh_first) #define SLIST_END(head) NULL #define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) @@ -126,9 +126,9 @@ struct { \ ((var) = *(varp)) != SLIST_END(head); \ (varp) = &SLIST_NEXT((var), field)) -/* - * Singly-linked List functions. - */ + /* + * Singly-linked List functions. + */ #define SLIST_INIT(head) { \ SLIST_FIRST(head) = SLIST_END(head); \ } @@ -165,9 +165,9 @@ struct { \ } \ } while (0) -/* - * List definitions. - */ + /* + * List definitions. + */ #define LIST_HEAD(name, type) \ struct name { \ struct type *lh_first; /* first element */ \ @@ -182,9 +182,9 @@ struct { \ struct type **le_prev; /* address of previous next element */ \ } -/* - * List access methods - */ + /* + * List access methods + */ #define LIST_FIRST(head) ((head)->lh_first) #define LIST_END(head) NULL #define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) @@ -195,9 +195,9 @@ struct { \ (var)!= LIST_END(head); \ (var) = LIST_NEXT(var, field)) -/* - * List functions. - */ + /* + * List functions. + */ #define LIST_INIT(head) do { \ LIST_FIRST(head) = LIST_END(head); \ } while (0) @@ -243,9 +243,9 @@ struct { \ _Q_INVALIDATE((elm)->field.le_next); \ } while (0) -/* - * Simple queue definitions. - */ + /* + * Simple queue definitions. + */ #define SIMPLEQ_HEAD(name, type) \ struct name { \ struct type *sqh_first; /* first element */ \ @@ -260,9 +260,9 @@ struct { \ struct type *sqe_next; /* next element */ \ } -/* - * Simple queue access methods. - */ + /* + * Simple queue access methods. + */ #define SIMPLEQ_FIRST(head) ((head)->sqh_first) #define SIMPLEQ_END(head) NULL #define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) @@ -273,9 +273,9 @@ struct { \ (var) != SIMPLEQ_END(head); \ (var) = SIMPLEQ_NEXT(var, field)) -/* - * Simple queue functions. - */ + /* + * Simple queue functions. + */ #define SIMPLEQ_INIT(head) do { \ (head)->sqh_first = NULL; \ (head)->sqh_last = &(head)->sqh_first; \ @@ -304,9 +304,9 @@ struct { \ (head)->sqh_last = &(head)->sqh_first; \ } while (0) -/* - * Tail queue definitions. - */ + /* + * Tail queue definitions. + */ #define TAILQ_HEAD(name, type) \ struct name { \ struct type *tqh_first; /* first element */ \ @@ -322,15 +322,15 @@ struct { \ struct type **tqe_prev; /* address of previous next element */ \ } -/* - * tail queue access methods - */ + /* + * tail queue access methods + */ #define TAILQ_FIRST(head) ((head)->tqh_first) #define TAILQ_END(head) NULL #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) #define TAILQ_LAST(head, headname) \ (*(((struct headname *)((head)->tqh_last))->tqh_last)) -/* XXX */ + /* XXX */ #define TAILQ_PREV(elm, headname, field) \ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) #define TAILQ_EMPTY(head) \ @@ -411,9 +411,9 @@ struct { \ _Q_INVALIDATE((elm)->field.tqe_next); \ } while (0) -/* - * Circular queue definitions. - */ + /* + * Circular queue definitions. + */ #define CIRCLEQ_HEAD(name, type) \ struct name { \ struct type *cqh_first; /* first element */ \ @@ -429,9 +429,9 @@ struct { \ struct type *cqe_prev; /* previous element */ \ } -/* - * Circular queue access methods - */ + /* + * Circular queue access methods + */ #define CIRCLEQ_FIRST(head) ((head)->cqh_first) #define CIRCLEQ_LAST(head) ((head)->cqh_last) #define CIRCLEQ_END(head) ((void *)(head)) @@ -450,9 +450,9 @@ struct { \ (var) != CIRCLEQ_END(head); \ (var) = CIRCLEQ_PREV(var, field)) -/* - * Circular queue functions. - */ + /* + * Circular queue functions. + */ #define CIRCLEQ_INIT(head) do { \ (head)->cqh_first = CIRCLEQ_END(head); \ (head)->cqh_last = CIRCLEQ_END(head); \ diff --git a/source/shared_lib/include/platform/miniupnpc/codelength.h b/source/shared_lib/include/platform/miniupnpc/codelength.h index f5f8e30f9..21ceb019e 100644 --- a/source/shared_lib/include/platform/miniupnpc/codelength.h +++ b/source/shared_lib/include/platform/miniupnpc/codelength.h @@ -7,20 +7,20 @@ #ifndef CODELENGTH_H_INCLUDED #define CODELENGTH_H_INCLUDED -/* Encode length by using 7bit per Byte : - * Most significant bit of each byte specifies that the - * following byte is part of the code */ + /* Encode length by using 7bit per Byte : + * Most significant bit of each byte specifies that the + * following byte is part of the code */ -/* n : unsigned - * p : unsigned char * - */ + /* n : unsigned + * p : unsigned char * + */ #define DECODELENGTH(n, p) n = 0; \ do { n = (n << 7) | (*p & 0x7f); } \ while((*(p++)&0x80) && (n<(1<<25))); -/* n : unsigned - * READ : function/macro to read one byte (unsigned char) - */ + /* n : unsigned + * READ : function/macro to read one byte (unsigned char) + */ #define DECODELENGTH_READ(n, READ) \ n = 0; \ do { \ @@ -30,10 +30,10 @@ if(!(c&0x80)) break; \ } while(n<(1<<25)); -/* n : unsigned - * p : unsigned char * - * p_limit : unsigned char * - */ + /* n : unsigned + * p : unsigned char * + * p_limit : unsigned char * + */ #define DECODELENGTH_CHECKLIMIT(n, p, p_limit) \ n = 0; \ do { \ @@ -42,9 +42,9 @@ } while((*((p)++)&0x80) && (n<(1<<25))); -/* n : unsigned - * p : unsigned char * - */ + /* n : unsigned + * p : unsigned char * + */ #define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \ if(n>=2097152) *(p++) = (n >> 21) | 0x80; \ if(n>=16384) *(p++) = (n >> 14) | 0x80; \ diff --git a/source/shared_lib/include/platform/miniupnpc/connecthostport.h b/source/shared_lib/include/platform/miniupnpc/connecthostport.h index 56941d6fa..041a68025 100644 --- a/source/shared_lib/include/platform/miniupnpc/connecthostport.h +++ b/source/shared_lib/include/platform/miniupnpc/connecthostport.h @@ -8,11 +8,11 @@ #ifndef CONNECTHOSTPORT_H_INCLUDED #define CONNECTHOSTPORT_H_INCLUDED -/* connecthostport() - * return a socket connected (TCP) to the host and port - * or -1 in case of error */ + /* connecthostport() + * return a socket connected (TCP) to the host and port + * or -1 in case of error */ int connecthostport(const char * host, unsigned short port, - unsigned int scope_id); + unsigned int scope_id); #endif diff --git a/source/shared_lib/include/platform/miniupnpc/declspec.h b/source/shared_lib/include/platform/miniupnpc/declspec.h index 2638faa61..df70e3ece 100644 --- a/source/shared_lib/include/platform/miniupnpc/declspec.h +++ b/source/shared_lib/include/platform/miniupnpc/declspec.h @@ -2,13 +2,13 @@ #define __DECLSPEC_H__ #if defined(_WIN32) && !defined(STATICLIB) - #ifdef MINIUPNP_EXPORTS - #define LIBSPEC __declspec(dllexport) - #else - #define LIBSPEC __declspec(dllimport) - #endif +#ifdef MINIUPNP_EXPORTS +#define LIBSPEC __declspec(dllexport) #else - #define LIBSPEC +#define LIBSPEC __declspec(dllimport) +#endif +#else +#define LIBSPEC #endif #endif diff --git a/source/shared_lib/include/platform/miniupnpc/igd_desc_parse.h b/source/shared_lib/include/platform/miniupnpc/igd_desc_parse.h index 0de546b69..e44e660b2 100644 --- a/source/shared_lib/include/platform/miniupnpc/igd_desc_parse.h +++ b/source/shared_lib/include/platform/miniupnpc/igd_desc_parse.h @@ -9,8 +9,8 @@ #ifndef IGD_DESC_PARSE_H_INCLUDED #define IGD_DESC_PARSE_H_INCLUDED -/* Structure to store the result of the parsing of UPnP - * descriptions of Internet Gateway Devices */ + /* Structure to store the result of the parsing of UPnP + * descriptions of Internet Gateway Devices */ #define MINIUPNPC_URL_MAXSIZE (128) struct IGDdatas_service { char controlurl[MINIUPNPC_URL_MAXSIZE]; diff --git a/source/shared_lib/include/platform/miniupnpc/minisoap.h b/source/shared_lib/include/platform/miniupnpc/minisoap.h index 14c859d1e..3190a8da4 100644 --- a/source/shared_lib/include/platform/miniupnpc/minisoap.h +++ b/source/shared_lib/include/platform/miniupnpc/minisoap.h @@ -7,9 +7,9 @@ #ifndef MINISOAP_H_INCLUDED #define MINISOAP_H_INCLUDED -/*int httpWrite(int, const char *, int, const char *);*/ + /*int httpWrite(int, const char *, int, const char *);*/ int soapPostSubmit(int, const char *, const char *, unsigned short, - const char *, const char *, const char *); + const char *, const char *, const char *); #endif diff --git a/source/shared_lib/include/platform/miniupnpc/minissdpc.h b/source/shared_lib/include/platform/miniupnpc/minissdpc.h index a5c622b28..ff87a3aff 100644 --- a/source/shared_lib/include/platform/miniupnpc/minissdpc.h +++ b/source/shared_lib/include/platform/miniupnpc/minissdpc.h @@ -11,7 +11,7 @@ #include "miniupnpc_declspec.h" #include "upnpdev.h" -/* error codes : */ + /* error codes : */ #define MINISSDPC_SUCCESS (0) #define MINISSDPC_UNKNOWN_ERROR (-1) #define MINISSDPC_SOCKET_ERROR (-101) @@ -25,30 +25,30 @@ extern "C" { #if !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) -MINIUPNP_LIBSPEC struct UPNPDev * -getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error); + MINIUPNP_LIBSPEC struct UPNPDev * + getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error); -MINIUPNP_LIBSPEC int -connectToMiniSSDPD(const char * socketpath); + MINIUPNP_LIBSPEC int + connectToMiniSSDPD(const char * socketpath); -MINIUPNP_LIBSPEC int -disconnectFromMiniSSDPD(int fd); + MINIUPNP_LIBSPEC int + disconnectFromMiniSSDPD(int fd); -MINIUPNP_LIBSPEC int -requestDevicesFromMiniSSDPD(int fd, const char * devtype); + MINIUPNP_LIBSPEC int + requestDevicesFromMiniSSDPD(int fd, const char * devtype); -MINIUPNP_LIBSPEC struct UPNPDev * -receiveDevicesFromMiniSSDPD(int fd, int * error); + MINIUPNP_LIBSPEC struct UPNPDev * + receiveDevicesFromMiniSSDPD(int fd, int * error); #endif /* !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) */ -MINIUPNP_LIBSPEC struct UPNPDev * -ssdpDiscoverDevices(const char * const deviceTypes[], - int delay, const char * multicastif, - int localport, - int ipv6, unsigned char ttl, - int * error, - int searchalltypes); + MINIUPNP_LIBSPEC struct UPNPDev * + ssdpDiscoverDevices(const char * const deviceTypes[], + int delay, const char * multicastif, + int localport, + int ipv6, unsigned char ttl, + int * error, + int searchalltypes); #ifdef __cplusplus } diff --git a/source/shared_lib/include/platform/miniupnpc/miniupnpc.h b/source/shared_lib/include/platform/miniupnpc/miniupnpc.h index f54d2967f..a3247358f 100644 --- a/source/shared_lib/include/platform/miniupnpc/miniupnpc.h +++ b/source/shared_lib/include/platform/miniupnpc/miniupnpc.h @@ -12,7 +12,7 @@ #include "igd_desc_parse.h" #include "upnpdev.h" -/* error codes : */ + /* error codes : */ #define UPNPDISCOVER_SUCCESS (0) #define UPNPDISCOVER_UNKNOWN_ERROR (-1) #define UPNPDISCOVER_SOCKET_ERROR (-101) @@ -32,116 +32,118 @@ extern "C" { #endif -/* Structures definitions : */ -struct UPNParg { const char * elt; const char * val; }; + /* Structures definitions : */ + struct UPNParg { + const char * elt; const char * val; + }; -char * -simpleUPnPcommand(int, const char *, const char *, - const char *, struct UPNParg *, - int *); + char * + simpleUPnPcommand(int, const char *, const char *, + const char *, struct UPNParg *, + int *); -/* upnpDiscover() - * discover UPnP devices on the network. - * The discovered devices are returned as a chained list. - * It is up to the caller to free the list with freeUPNPDevlist(). - * delay (in millisecond) is the maximum time for waiting any device - * response. - * If available, device list will be obtained from MiniSSDPd. - * Default path for minissdpd socket will be used if minissdpdsock argument - * is NULL. - * If multicastif is not NULL, it will be used instead of the default - * multicast interface for sending SSDP discover packets. - * If localport is set to UPNP_LOCAL_PORT_SAME(1) SSDP packets will be sent - * from the source port 1900 (same as destination port), if set to - * UPNP_LOCAL_PORT_ANY(0) system assign a source port, any other value will - * be attempted as the source port. - * "searchalltypes" parameter is useful when searching several types, - * if 0, the discovery will stop with the first type returning results. - * TTL should default to 2. */ -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscover(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error); + /* upnpDiscover() + * discover UPnP devices on the network. + * The discovered devices are returned as a chained list. + * It is up to the caller to free the list with freeUPNPDevlist(). + * delay (in millisecond) is the maximum time for waiting any device + * response. + * If available, device list will be obtained from MiniSSDPd. + * Default path for minissdpd socket will be used if minissdpdsock argument + * is NULL. + * If multicastif is not NULL, it will be used instead of the default + * multicast interface for sending SSDP discover packets. + * If localport is set to UPNP_LOCAL_PORT_SAME(1) SSDP packets will be sent + * from the source port 1900 (same as destination port), if set to + * UPNP_LOCAL_PORT_ANY(0) system assign a source port, any other value will + * be attempted as the source port. + * "searchalltypes" parameter is useful when searching several types, + * if 0, the discovery will stop with the first type returning results. + * TTL should default to 2. */ + MINIUPNP_LIBSPEC struct UPNPDev * + upnpDiscover(int delay, const char * multicastif, + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error); -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverAll(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error); + MINIUPNP_LIBSPEC struct UPNPDev * + upnpDiscoverAll(int delay, const char * multicastif, + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error); -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverDevice(const char * device, int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error); + MINIUPNP_LIBSPEC struct UPNPDev * + upnpDiscoverDevice(const char * device, int delay, const char * multicastif, + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error); -MINIUPNP_LIBSPEC struct UPNPDev * -upnpDiscoverDevices(const char * const deviceTypes[], - int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error, - int searchalltypes); + MINIUPNP_LIBSPEC struct UPNPDev * + upnpDiscoverDevices(const char * const deviceTypes[], + int delay, const char * multicastif, + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error, + int searchalltypes); -/* parserootdesc() : - * parse root XML description of a UPnP device and fill the IGDdatas - * structure. */ -MINIUPNP_LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *); + /* parserootdesc() : + * parse root XML description of a UPnP device and fill the IGDdatas + * structure. */ + MINIUPNP_LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *); -/* structure used to get fast access to urls - * controlURL: controlURL of the WANIPConnection - * ipcondescURL: url of the description of the WANIPConnection - * controlURL_CIF: controlURL of the WANCommonInterfaceConfig - * controlURL_6FC: controlURL of the WANIPv6FirewallControl - */ -struct UPNPUrls { - char * controlURL; - char * ipcondescURL; - char * controlURL_CIF; - char * controlURL_6FC; - char * rootdescURL; -}; + /* structure used to get fast access to urls + * controlURL: controlURL of the WANIPConnection + * ipcondescURL: url of the description of the WANIPConnection + * controlURL_CIF: controlURL of the WANCommonInterfaceConfig + * controlURL_6FC: controlURL of the WANIPv6FirewallControl + */ + struct UPNPUrls { + char * controlURL; + char * ipcondescURL; + char * controlURL_CIF; + char * controlURL_6FC; + char * rootdescURL; + }; -/* UPNP_GetValidIGD() : - * return values : - * 0 = NO IGD found - * 1 = A valid connected IGD has been found - * 2 = A valid IGD has been found but it reported as - * not connected - * 3 = an UPnP device has been found but was not recognized as an IGD - * - * In any non zero return case, the urls and data structures - * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to - * free allocated memory. - */ -MINIUPNP_LIBSPEC int -UPNP_GetValidIGD(struct UPNPDev * devlist, - struct UPNPUrls * urls, - struct IGDdatas * data, - char * lanaddr, int lanaddrlen); + /* UPNP_GetValidIGD() : + * return values : + * 0 = NO IGD found + * 1 = A valid connected IGD has been found + * 2 = A valid IGD has been found but it reported as + * not connected + * 3 = an UPnP device has been found but was not recognized as an IGD + * + * In any non zero return case, the urls and data structures + * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to + * free allocated memory. + */ + MINIUPNP_LIBSPEC int + UPNP_GetValidIGD(struct UPNPDev * devlist, + struct UPNPUrls * urls, + struct IGDdatas * data, + char * lanaddr, int lanaddrlen); -/* UPNP_GetIGDFromUrl() - * Used when skipping the discovery process. - * When succeding, urls, data, and lanaddr arguments are set. - * return value : - * 0 - Not ok - * 1 - OK */ -MINIUPNP_LIBSPEC int -UPNP_GetIGDFromUrl(const char * rootdescurl, - struct UPNPUrls * urls, - struct IGDdatas * data, - char * lanaddr, int lanaddrlen); + /* UPNP_GetIGDFromUrl() + * Used when skipping the discovery process. + * When succeding, urls, data, and lanaddr arguments are set. + * return value : + * 0 - Not ok + * 1 - OK */ + MINIUPNP_LIBSPEC int + UPNP_GetIGDFromUrl(const char * rootdescurl, + struct UPNPUrls * urls, + struct IGDdatas * data, + char * lanaddr, int lanaddrlen); -MINIUPNP_LIBSPEC void -GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, - const char *, unsigned int); + MINIUPNP_LIBSPEC void + GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, + const char *, unsigned int); -MINIUPNP_LIBSPEC void -FreeUPNPUrls(struct UPNPUrls *); + MINIUPNP_LIBSPEC void + FreeUPNPUrls(struct UPNPUrls *); -/* return 0 or 1 */ -MINIUPNP_LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *); + /* return 0 or 1 */ + MINIUPNP_LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *); #ifdef __cplusplus diff --git a/source/shared_lib/include/platform/miniupnpc/miniupnpc_declspec.h b/source/shared_lib/include/platform/miniupnpc/miniupnpc_declspec.h index 40adb922e..5dcb45762 100644 --- a/source/shared_lib/include/platform/miniupnpc/miniupnpc_declspec.h +++ b/source/shared_lib/include/platform/miniupnpc/miniupnpc_declspec.h @@ -2,19 +2,19 @@ #define MINIUPNPC_DECLSPEC_H_INCLUDED #if defined(_WIN32) && !defined(MINIUPNP_STATICLIB) - /* for windows dll */ - #ifdef MINIUPNP_EXPORTS - #define MINIUPNP_LIBSPEC __declspec(dllexport) - #else - #define MINIUPNP_LIBSPEC __declspec(dllimport) - #endif +/* for windows dll */ +#ifdef MINIUPNP_EXPORTS +#define MINIUPNP_LIBSPEC __declspec(dllexport) #else - #if defined(__GNUC__) && __GNUC__ >= 4 - /* fix dynlib for OS X 10.9.2 and Apple LLVM version 5.0 */ - #define MINIUPNP_LIBSPEC __attribute__ ((visibility ("default"))) - #else - #define MINIUPNP_LIBSPEC - #endif +#define MINIUPNP_LIBSPEC __declspec(dllimport) +#endif +#else +#if defined(__GNUC__) && __GNUC__ >= 4 +/* fix dynlib for OS X 10.9.2 and Apple LLVM version 5.0 */ +#define MINIUPNP_LIBSPEC __attribute__ ((visibility ("default"))) +#else +#define MINIUPNP_LIBSPEC +#endif #endif #endif /* MINIUPNPC_DECLSPEC_H_INCLUDED */ diff --git a/source/shared_lib/include/platform/miniupnpc/miniupnpcstrings.h b/source/shared_lib/include/platform/miniupnpc/miniupnpcstrings.h index 3ba0176e8..d981addac 100644 --- a/source/shared_lib/include/platform/miniupnpc/miniupnpcstrings.h +++ b/source/shared_lib/include/platform/miniupnpc/miniupnpcstrings.h @@ -8,7 +8,7 @@ #ifndef __MINIUPNPCSTRINGS_H__ #define __MINIUPNPCSTRINGS_H__ -//#include "lib/framework/wzglobal.h" + //#include "lib/framework/wzglobal.h" #if defined(WIN32) #define OS_STRING "Windows" diff --git a/source/shared_lib/include/platform/miniupnpc/miniwget.h b/source/shared_lib/include/platform/miniupnpc/miniwget.h index d6db71a85..a5569a1b4 100644 --- a/source/shared_lib/include/platform/miniupnpc/miniwget.h +++ b/source/shared_lib/include/platform/miniupnpc/miniwget.h @@ -14,13 +14,13 @@ extern "C" { #endif -MINIUPNP_LIBSPEC void * getHTTPResponse(int s, int * size); + MINIUPNP_LIBSPEC void * getHTTPResponse(int s, int * size); -MINIUPNP_LIBSPEC void * miniwget(const char *, int *, unsigned int); + MINIUPNP_LIBSPEC void * miniwget(const char *, int *, unsigned int); -MINIUPNP_LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int); + MINIUPNP_LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int); -int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *); + int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *); #ifdef __cplusplus } diff --git a/source/shared_lib/include/platform/miniupnpc/minixml.h b/source/shared_lib/include/platform/miniupnpc/minixml.h index 9f43aa48c..b74a64956 100644 --- a/source/shared_lib/include/platform/miniupnpc/minixml.h +++ b/source/shared_lib/include/platform/miniupnpc/minixml.h @@ -12,18 +12,18 @@ #define MINIXML_H_INCLUDED #define IS_WHITE_SPACE(c) ((c==' ') || (c=='\t') || (c=='\r') || (c=='\n')) -/* if a callback function pointer is set to NULL, - * the function is not called */ + /* if a callback function pointer is set to NULL, + * the function is not called */ struct xmlparser { const char *xmlstart; const char *xmlend; const char *xml; /* pointer to current character */ int xmlsize; void * data; - void (*starteltfunc) (void *, const char *, int); - void (*endeltfunc) (void *, const char *, int); - void (*datafunc) (void *, const char *, int); - void (*attfunc) (void *, const char *, int, const char *, int); + void(*starteltfunc) (void *, const char *, int); + void(*endeltfunc) (void *, const char *, int); + void(*datafunc) (void *, const char *, int); + void(*attfunc) (void *, const char *, int, const char *, int); }; /* parsexml() diff --git a/source/shared_lib/include/platform/miniupnpc/portlistingparse.h b/source/shared_lib/include/platform/miniupnpc/portlistingparse.h index 661ad1faa..a9785e8f1 100644 --- a/source/shared_lib/include/platform/miniupnpc/portlistingparse.h +++ b/source/shared_lib/include/platform/miniupnpc/portlistingparse.h @@ -8,55 +8,57 @@ #define PORTLISTINGPARSE_H_INCLUDED #include "miniupnpc_declspec.h" -/* for the definition of UNSIGNED_INTEGER */ + /* for the definition of UNSIGNED_INTEGER */ #include "miniupnpctypes.h" #ifdef __cplusplus extern "C" { #endif -/* sample of PortMappingEntry : - - 202.233.2.1 - 2345 - TCP - 2345 - 192.168.1.137 - 1 - dooom - 345 - - */ -typedef enum { PortMappingEltNone, - PortMappingEntry, NewRemoteHost, - NewExternalPort, NewProtocol, - NewInternalPort, NewInternalClient, - NewEnabled, NewDescription, - NewLeaseTime } portMappingElt; + /* sample of PortMappingEntry : + + 202.233.2.1 + 2345 + TCP + 2345 + 192.168.1.137 + 1 + dooom + 345 + + */ + typedef enum { + PortMappingEltNone, + PortMappingEntry, NewRemoteHost, + NewExternalPort, NewProtocol, + NewInternalPort, NewInternalClient, + NewEnabled, NewDescription, + NewLeaseTime + } portMappingElt; -struct PortMapping { - struct PortMapping * l_next; /* list next element */ - UNSIGNED_INTEGER leaseTime; - unsigned short externalPort; - unsigned short internalPort; - char remoteHost[64]; - char internalClient[64]; - char description[64]; - char protocol[4]; - unsigned char enabled; -}; + struct PortMapping { + struct PortMapping * l_next; /* list next element */ + UNSIGNED_INTEGER leaseTime; + unsigned short externalPort; + unsigned short internalPort; + char remoteHost[64]; + char internalClient[64]; + char description[64]; + char protocol[4]; + unsigned char enabled; + }; -struct PortMappingParserData { - struct PortMapping * l_head; /* list head */ - portMappingElt curelt; -}; + struct PortMappingParserData { + struct PortMapping * l_head; /* list head */ + portMappingElt curelt; + }; -MINIUPNP_LIBSPEC void -ParsePortListing(const char * buffer, int bufsize, - struct PortMappingParserData * pdata); + MINIUPNP_LIBSPEC void + ParsePortListing(const char * buffer, int bufsize, + struct PortMappingParserData * pdata); -MINIUPNP_LIBSPEC void -FreePortListing(struct PortMappingParserData * pdata); + MINIUPNP_LIBSPEC void + FreePortListing(struct PortMappingParserData * pdata); #ifdef __cplusplus } diff --git a/source/shared_lib/include/platform/miniupnpc/receivedata.h b/source/shared_lib/include/platform/miniupnpc/receivedata.h index 0520a11d3..1dee49383 100644 --- a/source/shared_lib/include/platform/miniupnpc/receivedata.h +++ b/source/shared_lib/include/platform/miniupnpc/receivedata.h @@ -8,12 +8,12 @@ #ifndef RECEIVEDATA_H_INCLUDED #define RECEIVEDATA_H_INCLUDED -/* Reads data from the specified socket. - * Returns the number of bytes read if successful, zero if no bytes were - * read or if we timed out. Returns negative if there was an error. */ + /* Reads data from the specified socket. + * Returns the number of bytes read if successful, zero if no bytes were + * read or if we timed out. Returns negative if there was an error. */ int receivedata(int socket, - char * data, int length, - int timeout, unsigned int * scope_id); + char * data, int length, + int timeout, unsigned int * scope_id); #endif diff --git a/source/shared_lib/include/platform/miniupnpc/upnpcommands.h b/source/shared_lib/include/platform/miniupnpc/upnpcommands.h index 22eda5e39..c4aa0ccf4 100644 --- a/source/shared_lib/include/platform/miniupnpc/upnpcommands.h +++ b/source/shared_lib/include/platform/miniupnpc/upnpcommands.h @@ -12,7 +12,7 @@ #include "miniupnpc_declspec.h" #include "miniupnpctypes.h" -/* MiniUPnPc return codes : */ + /* MiniUPnPc return codes : */ #define UPNPCOMMAND_SUCCESS (0) #define UPNPCOMMAND_UNKNOWN_ERROR (-1) #define UPNPCOMMAND_INVALID_ARGS (-2) @@ -24,321 +24,321 @@ extern "C" { #endif -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalBytesSent(const char * controlURL, - const char * servicetype); + MINIUPNP_LIBSPEC UNSIGNED_INTEGER + UPNP_GetTotalBytesSent(const char * controlURL, + const char * servicetype); -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalBytesReceived(const char * controlURL, - const char * servicetype); + MINIUPNP_LIBSPEC UNSIGNED_INTEGER + UPNP_GetTotalBytesReceived(const char * controlURL, + const char * servicetype); -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalPacketsSent(const char * controlURL, - const char * servicetype); + MINIUPNP_LIBSPEC UNSIGNED_INTEGER + UPNP_GetTotalPacketsSent(const char * controlURL, + const char * servicetype); -MINIUPNP_LIBSPEC UNSIGNED_INTEGER -UPNP_GetTotalPacketsReceived(const char * controlURL, - const char * servicetype); + MINIUPNP_LIBSPEC UNSIGNED_INTEGER + UPNP_GetTotalPacketsReceived(const char * controlURL, + const char * servicetype); -/* UPNP_GetStatusInfo() - * status and lastconnerror are 64 byte buffers - * Return values : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error code */ -MINIUPNP_LIBSPEC int -UPNP_GetStatusInfo(const char * controlURL, - const char * servicetype, - char * status, - unsigned int * uptime, - char * lastconnerror); + /* UPNP_GetStatusInfo() + * status and lastconnerror are 64 byte buffers + * Return values : + * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR + * or a UPnP Error code */ + MINIUPNP_LIBSPEC int + UPNP_GetStatusInfo(const char * controlURL, + const char * servicetype, + char * status, + unsigned int * uptime, + char * lastconnerror); -/* UPNP_GetConnectionTypeInfo() - * argument connectionType is a 64 character buffer - * Return Values : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error code */ -MINIUPNP_LIBSPEC int -UPNP_GetConnectionTypeInfo(const char * controlURL, - const char * servicetype, - char * connectionType); + /* UPNP_GetConnectionTypeInfo() + * argument connectionType is a 64 character buffer + * Return Values : + * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR + * or a UPnP Error code */ + MINIUPNP_LIBSPEC int + UPNP_GetConnectionTypeInfo(const char * controlURL, + const char * servicetype, + char * connectionType); -/* UPNP_GetExternalIPAddress() call the corresponding UPNP method. - * if the third arg is not null the value is copied to it. - * at least 16 bytes must be available - * - * Return values : - * 0 : SUCCESS - * NON ZERO : ERROR Either an UPnP error code or an unknown error. - * - * possible UPnP Errors : - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. */ -MINIUPNP_LIBSPEC int -UPNP_GetExternalIPAddress(const char * controlURL, - const char * servicetype, - char * extIpAdd); + /* UPNP_GetExternalIPAddress() call the corresponding UPNP method. + * if the third arg is not null the value is copied to it. + * at least 16 bytes must be available + * + * Return values : + * 0 : SUCCESS + * NON ZERO : ERROR Either an UPnP error code or an unknown error. + * + * possible UPnP Errors : + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 501 Action Failed - See UPnP Device Architecture section on Control. */ + MINIUPNP_LIBSPEC int + UPNP_GetExternalIPAddress(const char * controlURL, + const char * servicetype, + char * extIpAdd); -/* UPNP_GetLinkLayerMaxBitRates() - * call WANCommonInterfaceConfig:1#GetCommonLinkProperties - * - * return values : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error Code. */ -MINIUPNP_LIBSPEC int -UPNP_GetLinkLayerMaxBitRates(const char* controlURL, - const char* servicetype, - unsigned int * bitrateDown, - unsigned int * bitrateUp); + /* UPNP_GetLinkLayerMaxBitRates() + * call WANCommonInterfaceConfig:1#GetCommonLinkProperties + * + * return values : + * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR + * or a UPnP Error Code. */ + MINIUPNP_LIBSPEC int + UPNP_GetLinkLayerMaxBitRates(const char* controlURL, + const char* servicetype, + unsigned int * bitrateDown, + unsigned int * bitrateUp); -/* UPNP_AddPortMapping() - * if desc is NULL, it will be defaulted to "libminiupnpc" - * remoteHost is usually NULL because IGD don't support it. - * - * Return values : - * 0 : SUCCESS - * NON ZERO : ERROR. Either an UPnP error code or an unknown error. - * - * List of possible UPnP errors for AddPortMapping : - * errorCode errorDescription (short) - Description (long) - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. - * 606 Action not authorized - The action requested REQUIRES authorization and - * the sender was not authorized. - * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be - * wild-carded - * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded - * 718 ConflictInMappingEntry - The port mapping entry specified conflicts - * with a mapping assigned previously to another client - * 724 SamePortValuesRequired - Internal and External port values - * must be the same - * 725 OnlyPermanentLeasesSupported - The NAT implementation only supports - * permanent lease times on port mappings - * 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard - * and cannot be a specific IP address or DNS name - * 727 ExternalPortOnlySupportsWildcard - ExternalPort must be a wildcard and - * cannot be a specific port value - * 728 NoPortMapsAvailable - There are not enough free ports available to - * complete port mapping. - * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed - * due to conflict with other mechanisms. - * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded - */ -MINIUPNP_LIBSPEC int -UPNP_AddPortMapping(const char * controlURL, const char * servicetype, - const char * extPort, - const char * inPort, - const char * inClient, - const char * desc, - const char * proto, - const char * remoteHost, - const char * leaseDuration); + /* UPNP_AddPortMapping() + * if desc is NULL, it will be defaulted to "libminiupnpc" + * remoteHost is usually NULL because IGD don't support it. + * + * Return values : + * 0 : SUCCESS + * NON ZERO : ERROR. Either an UPnP error code or an unknown error. + * + * List of possible UPnP errors for AddPortMapping : + * errorCode errorDescription (short) - Description (long) + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 501 Action Failed - See UPnP Device Architecture section on Control. + * 606 Action not authorized - The action requested REQUIRES authorization and + * the sender was not authorized. + * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be + * wild-carded + * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded + * 718 ConflictInMappingEntry - The port mapping entry specified conflicts + * with a mapping assigned previously to another client + * 724 SamePortValuesRequired - Internal and External port values + * must be the same + * 725 OnlyPermanentLeasesSupported - The NAT implementation only supports + * permanent lease times on port mappings + * 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard + * and cannot be a specific IP address or DNS name + * 727 ExternalPortOnlySupportsWildcard - ExternalPort must be a wildcard and + * cannot be a specific port value + * 728 NoPortMapsAvailable - There are not enough free ports available to + * complete port mapping. + * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed + * due to conflict with other mechanisms. + * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded + */ + MINIUPNP_LIBSPEC int + UPNP_AddPortMapping(const char * controlURL, const char * servicetype, + const char * extPort, + const char * inPort, + const char * inClient, + const char * desc, + const char * proto, + const char * remoteHost, + const char * leaseDuration); -/* UPNP_AddAnyPortMapping() - * if desc is NULL, it will be defaulted to "libminiupnpc" - * remoteHost is usually NULL because IGD don't support it. - * - * Return values : - * 0 : SUCCESS - * NON ZERO : ERROR. Either an UPnP error code or an unknown error. - * - * List of possible UPnP errors for AddPortMapping : - * errorCode errorDescription (short) - Description (long) - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. - * 606 Action not authorized - The action requested REQUIRES authorization and - * the sender was not authorized. - * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be - * wild-carded - * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded - * 728 NoPortMapsAvailable - There are not enough free ports available to - * complete port mapping. - * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed - * due to conflict with other mechanisms. - * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded - */ -MINIUPNP_LIBSPEC int -UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype, - const char * extPort, - const char * inPort, - const char * inClient, - const char * desc, - const char * proto, - const char * remoteHost, - const char * leaseDuration, - char * reservedPort); + /* UPNP_AddAnyPortMapping() + * if desc is NULL, it will be defaulted to "libminiupnpc" + * remoteHost is usually NULL because IGD don't support it. + * + * Return values : + * 0 : SUCCESS + * NON ZERO : ERROR. Either an UPnP error code or an unknown error. + * + * List of possible UPnP errors for AddPortMapping : + * errorCode errorDescription (short) - Description (long) + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 501 Action Failed - See UPnP Device Architecture section on Control. + * 606 Action not authorized - The action requested REQUIRES authorization and + * the sender was not authorized. + * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be + * wild-carded + * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded + * 728 NoPortMapsAvailable - There are not enough free ports available to + * complete port mapping. + * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed + * due to conflict with other mechanisms. + * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded + */ + MINIUPNP_LIBSPEC int + UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype, + const char * extPort, + const char * inPort, + const char * inClient, + const char * desc, + const char * proto, + const char * remoteHost, + const char * leaseDuration, + char * reservedPort); -/* UPNP_DeletePortMapping() - * Use same argument values as what was used for AddPortMapping(). - * remoteHost is usually NULL because IGD don't support it. - * Return Values : - * 0 : SUCCESS - * NON ZERO : error. Either an UPnP error code or an undefined error. - * - * List of possible UPnP errors for DeletePortMapping : - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 606 Action not authorized - The action requested REQUIRES authorization - * and the sender was not authorized. - * 714 NoSuchEntryInArray - The specified value does not exist in the array */ -MINIUPNP_LIBSPEC int -UPNP_DeletePortMapping(const char * controlURL, const char * servicetype, - const char * extPort, const char * proto, - const char * remoteHost); + /* UPNP_DeletePortMapping() + * Use same argument values as what was used for AddPortMapping(). + * remoteHost is usually NULL because IGD don't support it. + * Return Values : + * 0 : SUCCESS + * NON ZERO : error. Either an UPnP error code or an undefined error. + * + * List of possible UPnP errors for DeletePortMapping : + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 606 Action not authorized - The action requested REQUIRES authorization + * and the sender was not authorized. + * 714 NoSuchEntryInArray - The specified value does not exist in the array */ + MINIUPNP_LIBSPEC int + UPNP_DeletePortMapping(const char * controlURL, const char * servicetype, + const char * extPort, const char * proto, + const char * remoteHost); -/* UPNP_DeletePortRangeMapping() - * Use same argument values as what was used for AddPortMapping(). - * remoteHost is usually NULL because IGD don't support it. - * Return Values : - * 0 : SUCCESS - * NON ZERO : error. Either an UPnP error code or an undefined error. - * - * List of possible UPnP errors for DeletePortMapping : - * 606 Action not authorized - The action requested REQUIRES authorization - * and the sender was not authorized. - * 730 PortMappingNotFound - This error message is returned if no port - * mapping is found in the specified range. - * 733 InconsistentParameters - NewStartPort and NewEndPort values are not consistent. */ -MINIUPNP_LIBSPEC int -UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype, - const char * extPortStart, const char * extPortEnd, - const char * proto, - const char * manage); + /* UPNP_DeletePortRangeMapping() + * Use same argument values as what was used for AddPortMapping(). + * remoteHost is usually NULL because IGD don't support it. + * Return Values : + * 0 : SUCCESS + * NON ZERO : error. Either an UPnP error code or an undefined error. + * + * List of possible UPnP errors for DeletePortMapping : + * 606 Action not authorized - The action requested REQUIRES authorization + * and the sender was not authorized. + * 730 PortMappingNotFound - This error message is returned if no port + * mapping is found in the specified range. + * 733 InconsistentParameters - NewStartPort and NewEndPort values are not consistent. */ + MINIUPNP_LIBSPEC int + UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype, + const char * extPortStart, const char * extPortEnd, + const char * proto, + const char * manage); -/* UPNP_GetPortMappingNumberOfEntries() - * not supported by all routers */ -MINIUPNP_LIBSPEC int -UPNP_GetPortMappingNumberOfEntries(const char* controlURL, - const char* servicetype, - unsigned int * num); + /* UPNP_GetPortMappingNumberOfEntries() + * not supported by all routers */ + MINIUPNP_LIBSPEC int + UPNP_GetPortMappingNumberOfEntries(const char* controlURL, + const char* servicetype, + unsigned int * num); -/* UPNP_GetSpecificPortMappingEntry() - * retrieves an existing port mapping - * params : - * in extPort - * in proto - * in remoteHost - * out intClient (16 bytes) - * out intPort (6 bytes) - * out desc (80 bytes) - * out enabled (4 bytes) - * out leaseDuration (16 bytes) - * - * return value : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error Code. - * - * List of possible UPnP errors for _GetSpecificPortMappingEntry : - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 501 Action Failed - See UPnP Device Architecture section on Control. - * 606 Action not authorized - The action requested REQUIRES authorization - * and the sender was not authorized. - * 714 NoSuchEntryInArray - The specified value does not exist in the array. - */ -MINIUPNP_LIBSPEC int -UPNP_GetSpecificPortMappingEntry(const char * controlURL, - const char * servicetype, - const char * extPort, - const char * proto, - const char * remoteHost, - char * intClient, - char * intPort, - char * desc, - char * enabled, - char * leaseDuration); + /* UPNP_GetSpecificPortMappingEntry() + * retrieves an existing port mapping + * params : + * in extPort + * in proto + * in remoteHost + * out intClient (16 bytes) + * out intPort (6 bytes) + * out desc (80 bytes) + * out enabled (4 bytes) + * out leaseDuration (16 bytes) + * + * return value : + * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR + * or a UPnP Error Code. + * + * List of possible UPnP errors for _GetSpecificPortMappingEntry : + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 501 Action Failed - See UPnP Device Architecture section on Control. + * 606 Action not authorized - The action requested REQUIRES authorization + * and the sender was not authorized. + * 714 NoSuchEntryInArray - The specified value does not exist in the array. + */ + MINIUPNP_LIBSPEC int + UPNP_GetSpecificPortMappingEntry(const char * controlURL, + const char * servicetype, + const char * extPort, + const char * proto, + const char * remoteHost, + char * intClient, + char * intPort, + char * desc, + char * enabled, + char * leaseDuration); -/* UPNP_GetGenericPortMappingEntry() - * params : - * in index - * out extPort (6 bytes) - * out intClient (16 bytes) - * out intPort (6 bytes) - * out protocol (4 bytes) - * out desc (80 bytes) - * out enabled (4 bytes) - * out rHost (64 bytes) - * out duration (16 bytes) - * - * return value : - * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR - * or a UPnP Error Code. - * - * Possible UPNP Error codes : - * 402 Invalid Args - See UPnP Device Architecture section on Control. - * 606 Action not authorized - The action requested REQUIRES authorization - * and the sender was not authorized. - * 713 SpecifiedArrayIndexInvalid - The specified array index is out of bounds - */ -MINIUPNP_LIBSPEC int -UPNP_GetGenericPortMappingEntry(const char * controlURL, - const char * servicetype, - const char * index, - char * extPort, - char * intClient, - char * intPort, - char * protocol, - char * desc, - char * enabled, - char * rHost, - char * duration); + /* UPNP_GetGenericPortMappingEntry() + * params : + * in index + * out extPort (6 bytes) + * out intClient (16 bytes) + * out intPort (6 bytes) + * out protocol (4 bytes) + * out desc (80 bytes) + * out enabled (4 bytes) + * out rHost (64 bytes) + * out duration (16 bytes) + * + * return value : + * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR + * or a UPnP Error Code. + * + * Possible UPNP Error codes : + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 606 Action not authorized - The action requested REQUIRES authorization + * and the sender was not authorized. + * 713 SpecifiedArrayIndexInvalid - The specified array index is out of bounds + */ + MINIUPNP_LIBSPEC int + UPNP_GetGenericPortMappingEntry(const char * controlURL, + const char * servicetype, + const char * index, + char * extPort, + char * intClient, + char * intPort, + char * protocol, + char * desc, + char * enabled, + char * rHost, + char * duration); -/* UPNP_GetListOfPortMappings() Available in IGD v2 - * - * - * Possible UPNP Error codes : - * 606 Action not Authorized - * 730 PortMappingNotFound - no port mapping is found in the specified range. - * 733 InconsistantParameters - NewStartPort and NewEndPort values are not - * consistent. - */ -MINIUPNP_LIBSPEC int -UPNP_GetListOfPortMappings(const char * controlURL, - const char * servicetype, - const char * startPort, - const char * endPort, - const char * protocol, - const char * numberOfPorts, - struct PortMappingParserData * data); + /* UPNP_GetListOfPortMappings() Available in IGD v2 + * + * + * Possible UPNP Error codes : + * 606 Action not Authorized + * 730 PortMappingNotFound - no port mapping is found in the specified range. + * 733 InconsistantParameters - NewStartPort and NewEndPort values are not + * consistent. + */ + MINIUPNP_LIBSPEC int + UPNP_GetListOfPortMappings(const char * controlURL, + const char * servicetype, + const char * startPort, + const char * endPort, + const char * protocol, + const char * numberOfPorts, + struct PortMappingParserData * data); -/* IGD:2, functions for service WANIPv6FirewallControl:1 */ -MINIUPNP_LIBSPEC int -UPNP_GetFirewallStatus(const char * controlURL, - const char * servicetype, - int * firewallEnabled, - int * inboundPinholeAllowed); + /* IGD:2, functions for service WANIPv6FirewallControl:1 */ + MINIUPNP_LIBSPEC int + UPNP_GetFirewallStatus(const char * controlURL, + const char * servicetype, + int * firewallEnabled, + int * inboundPinholeAllowed); -MINIUPNP_LIBSPEC int -UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype, - const char * remoteHost, - const char * remotePort, - const char * intClient, - const char * intPort, - const char * proto, - int * opTimeout); + MINIUPNP_LIBSPEC int + UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype, + const char * remoteHost, + const char * remotePort, + const char * intClient, + const char * intPort, + const char * proto, + int * opTimeout); -MINIUPNP_LIBSPEC int -UPNP_AddPinhole(const char * controlURL, const char * servicetype, - const char * remoteHost, - const char * remotePort, - const char * intClient, - const char * intPort, - const char * proto, - const char * leaseTime, - char * uniqueID); + MINIUPNP_LIBSPEC int + UPNP_AddPinhole(const char * controlURL, const char * servicetype, + const char * remoteHost, + const char * remotePort, + const char * intClient, + const char * intPort, + const char * proto, + const char * leaseTime, + char * uniqueID); -MINIUPNP_LIBSPEC int -UPNP_UpdatePinhole(const char * controlURL, const char * servicetype, - const char * uniqueID, - const char * leaseTime); + MINIUPNP_LIBSPEC int + UPNP_UpdatePinhole(const char * controlURL, const char * servicetype, + const char * uniqueID, + const char * leaseTime); -MINIUPNP_LIBSPEC int -UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID); + MINIUPNP_LIBSPEC int + UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID); -MINIUPNP_LIBSPEC int -UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, - const char * uniqueID, int * isWorking); + MINIUPNP_LIBSPEC int + UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, + const char * uniqueID, int * isWorking); -MINIUPNP_LIBSPEC int -UPNP_GetPinholePackets(const char * controlURL, const char * servicetype, - const char * uniqueID, int * packets); + MINIUPNP_LIBSPEC int + UPNP_GetPinholePackets(const char * controlURL, const char * servicetype, + const char * uniqueID, int * packets); #ifdef __cplusplus } diff --git a/source/shared_lib/include/platform/miniupnpc/upnpdev.h b/source/shared_lib/include/platform/miniupnpc/upnpdev.h index f49fbe17c..d939e1853 100644 --- a/source/shared_lib/include/platform/miniupnpc/upnpdev.h +++ b/source/shared_lib/include/platform/miniupnpc/upnpdev.h @@ -14,18 +14,18 @@ extern "C" { #endif -struct UPNPDev { - struct UPNPDev * pNext; - char * descURL; - char * st; - unsigned int scope_id; - char * usn; - char buffer[3]; -}; + struct UPNPDev { + struct UPNPDev * pNext; + char * descURL; + char * st; + unsigned int scope_id; + char * usn; + char buffer[3]; + }; -/* freeUPNPDevlist() - * free list returned by upnpDiscover() */ -MINIUPNP_LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist); + /* freeUPNPDevlist() + * free list returned by upnpDiscover() */ + MINIUPNP_LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist); #ifdef __cplusplus diff --git a/source/shared_lib/include/platform/miniupnpc/upnperrors.h b/source/shared_lib/include/platform/miniupnpc/upnperrors.h index 3115aee5b..c8a1e8353 100644 --- a/source/shared_lib/include/platform/miniupnpc/upnperrors.h +++ b/source/shared_lib/include/platform/miniupnpc/upnperrors.h @@ -14,10 +14,10 @@ extern "C" { #endif -/* strupnperror() - * Return a string description of the UPnP error code - * or NULL for undefinded errors */ -MINIUPNP_LIBSPEC const char * strupnperror(int err); + /* strupnperror() + * Return a string description of the UPnP error code + * or NULL for undefinded errors */ + MINIUPNP_LIBSPEC const char * strupnperror(int err); #ifdef __cplusplus } diff --git a/source/shared_lib/include/platform/miniupnpc/upnpreplyparse.h b/source/shared_lib/include/platform/miniupnpc/upnpreplyparse.h index 6badd15b2..c64607c1a 100644 --- a/source/shared_lib/include/platform/miniupnpc/upnpreplyparse.h +++ b/source/shared_lib/include/platform/miniupnpc/upnpreplyparse.h @@ -12,47 +12,47 @@ extern "C" { #endif -struct NameValue { - struct NameValue * l_next; - char name[64]; - char value[128]; -}; + struct NameValue { + struct NameValue * l_next; + char name[64]; + char value[128]; + }; -struct NameValueParserData { - struct NameValue * l_head; - char curelt[64]; - char * portListing; - int portListingLength; - int topelt; - const char * cdata; - int cdatalen; -}; + struct NameValueParserData { + struct NameValue * l_head; + char curelt[64]; + char * portListing; + int portListingLength; + int topelt; + const char * cdata; + int cdatalen; + }; -/* ParseNameValue() */ -void -ParseNameValue(const char * buffer, int bufsize, - struct NameValueParserData * data); + /* ParseNameValue() */ + void + ParseNameValue(const char * buffer, int bufsize, + struct NameValueParserData * data); -/* ClearNameValueList() */ -void -ClearNameValueList(struct NameValueParserData * pdata); + /* ClearNameValueList() */ + void + ClearNameValueList(struct NameValueParserData * pdata); -/* GetValueFromNameValueList() */ -char * -GetValueFromNameValueList(struct NameValueParserData * pdata, - const char * Name); + /* GetValueFromNameValueList() */ + char * + GetValueFromNameValueList(struct NameValueParserData * pdata, + const char * Name); #if 0 -/* GetValueFromNameValueListIgnoreNS() */ -char * -GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata, - const char * Name); + /* GetValueFromNameValueListIgnoreNS() */ + char * + GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata, + const char * Name); #endif -/* DisplayNameValueList() */ + /* DisplayNameValueList() */ #ifdef DEBUG -void -DisplayNameValueList(char * buffer, int bufsize); + void + DisplayNameValueList(char * buffer, int bufsize); #endif #ifdef __cplusplus diff --git a/source/shared_lib/include/platform/posix/ircclient.h b/source/shared_lib/include/platform/posix/ircclient.h index 3ae99be54..a3801c748 100644 --- a/source/shared_lib/include/platform/posix/ircclient.h +++ b/source/shared_lib/include/platform/posix/ircclient.h @@ -13,8 +13,8 @@ #define _SHARED_PLATFORMCOMMON_IRCTHREAD_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include "base_thread.h" @@ -30,116 +30,154 @@ typedef struct irc_session_s irc_session_t; using namespace std; -namespace Shared { namespace PlatformCommon { +namespace Shared { + namespace PlatformCommon { -// ===================================================== -// class IRCThreadThread -// ===================================================== + // ===================================================== + // class IRCThreadThread + // ===================================================== -enum IRCEventType { - IRC_evt_chatText = 0, - IRC_evt_exitThread = 1 -}; + enum IRCEventType { + IRC_evt_chatText = 0, + IRC_evt_exitThread = 1 + }; -void normalizeNick(char *nick); + void normalizeNick(char *nick); -class IRCCallbackInterface { -public: - virtual void IRC_CallbackEvent(IRCEventType evt, const char* origin, const char **params, unsigned int count) = 0; + class IRCCallbackInterface { + public: + virtual void IRC_CallbackEvent(IRCEventType evt, const char* origin, const char **params, unsigned int count) = 0; - virtual ~IRCCallbackInterface() {} -}; + virtual ~IRCCallbackInterface() { + } + }; -class IRCThread : public BaseThread -{ -public: - static bool debugEnabled; -protected: - static const char *globalCacheContainerName; + class IRCThread : public BaseThread { + public: + static bool debugEnabled; + protected: + static const char *globalCacheContainerName; - std::vector argv; + std::vector argv; - Mutex mutexIRCSession; - irc_session_t *ircSession; + Mutex mutexIRCSession; + irc_session_t *ircSession; - string execute_cmd_onconnect; - //string password; - string username; - string channel; - string nick; + string execute_cmd_onconnect; + //string password; + string username; + string channel; + string nick; - string playerName; - string glestVersionString; + string playerName; + string glestVersionString; - bool hasJoinedChannel; + bool hasJoinedChannel; - Mutex mutexEventDataDone; - bool eventDataDone; + Mutex mutexEventDataDone; + bool eventDataDone; - Mutex mutexNickList; - time_t lastNickListUpdate; - std::vector eventData; + Mutex mutexNickList; + time_t lastNickListUpdate; + std::vector eventData; - Mutex mutexIRCCB; - IRCCallbackInterface *callbackObj; + Mutex mutexIRCCB; + IRCCallbackInterface *callbackObj; - bool wantToLeaveChannel; + bool wantToLeaveChannel; - int irc_run_session(irc_session_t * session); + int irc_run_session(irc_session_t * session); -public: + public: - IRCThread(const std::vector &argv,IRCCallbackInterface *callbackObj); - virtual ~IRCThread(); - virtual void execute(); - virtual void signalQuit(); - virtual bool shutdownAndWait(); + IRCThread(const std::vector &argv, IRCCallbackInterface *callbackObj); + virtual ~IRCThread(); + virtual void execute(); + virtual void signalQuit(); + virtual bool shutdownAndWait(); - static void setGlobalCacheContainerName(const char *name) { globalCacheContainerName = name; } + static void setGlobalCacheContainerName(const char *name) { + globalCacheContainerName = name; + } - void setPlayerName(string value) { playerName = value; } - void setGlestVersionString(string value) { glestVersionString = value; } - string getPlayerName() const { return playerName; } + void setPlayerName(string value) { + playerName = value; + } + void setGlestVersionString(string value) { + glestVersionString = value; + } + string getPlayerName() const { + return playerName; + } - bool getWantToLeaveChannel() const { return wantToLeaveChannel; } + bool getWantToLeaveChannel() const { + return wantToLeaveChannel; + } - void SendIRCCmdMessage(string target, string msg); - std::vector getNickList(); - bool isConnected(bool mutexLockRequired=true); + void SendIRCCmdMessage(string target, string msg); + std::vector getNickList(); + bool isConnected(bool mutexLockRequired = true); - std::vector GetIRCConnectedNickList(string target, bool waitForCompletion); + std::vector GetIRCConnectedNickList(string target, bool waitForCompletion); - bool getEventDataDone(); - void setEventDataDone(bool value); + bool getEventDataDone(); + void setEventDataDone(bool value); - bool getHasJoinedChannel() const { return hasJoinedChannel; } - void setHasJoinedChannel(bool value) { hasJoinedChannel=value; } + bool getHasJoinedChannel() const { + return hasJoinedChannel; + } + void setHasJoinedChannel(bool value) { + hasJoinedChannel = value; + } - time_t getLastNickListUpdate() const { return lastNickListUpdate; } - void setLastNickListUpdate(time_t value) { lastNickListUpdate = value;} + time_t getLastNickListUpdate() const { + return lastNickListUpdate; + } + void setLastNickListUpdate(time_t value) { + lastNickListUpdate = value; + } - string getChannel() const { return channel;} - string getNick() const { return nick;} + string getChannel() const { + return channel; + } + string getNick() const { + return nick; + } - string getExecute_cmd_onconnect() const { return execute_cmd_onconnect; } - void setExecute_cmd_onconnect(string value) { execute_cmd_onconnect = value; } + string getExecute_cmd_onconnect() const { + return execute_cmd_onconnect; + } + void setExecute_cmd_onconnect(string value) { + execute_cmd_onconnect = value; + } - std::vector getArgs() const { return argv;} + std::vector getArgs() const { + return argv; + } - Mutex * getMutexNickList() { return &mutexNickList; } - std::vector & getCachedNickList() { return eventData; } - void setCachedNickList(std::vector &list) { eventData = list; } + Mutex * getMutexNickList() { + return &mutexNickList; + } + std::vector & getCachedNickList() { + return eventData; + } + void setCachedNickList(std::vector &list) { + eventData = list; + } - Mutex * getMutexIRCCB() { return &mutexIRCCB; } - IRCCallbackInterface * getCallbackObj(bool lockObj=true); - void setCallbackObj(IRCCallbackInterface *cb); + Mutex * getMutexIRCCB() { + return &mutexIRCCB; + } + IRCCallbackInterface * getCallbackObj(bool lockObj = true); + void setCallbackObj(IRCCallbackInterface *cb); - void joinChannel(); - void leaveChannel(); - void connectToHost(); - void disconnect(); -}; + void joinChannel(); + void leaveChannel(); + void connectToHost(); + void disconnect(); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/platform/posix/miniftpclient.h b/source/shared_lib/include/platform/posix/miniftpclient.h index 2cd92ebd0..9e0855ac1 100644 --- a/source/shared_lib/include/platform/posix/miniftpclient.h +++ b/source/shared_lib/include/platform/posix/miniftpclient.h @@ -20,143 +20,147 @@ using namespace std; -namespace Shared { namespace PlatformCommon { +namespace Shared { + namespace PlatformCommon { -// ===================================================== -// class FTPClientThread -// ===================================================== + // ===================================================== + // class FTPClientThread + // ===================================================== -enum FTP_Client_ResultType { - ftp_crt_SUCCESS = 0, - ftp_crt_PARTIALFAIL = 1, - ftp_crt_FAIL = 2, - ftp_crt_ABORTED = 3, - ftp_crt_HOST_NOT_ACCEPTING = 4 -}; + enum FTP_Client_ResultType { + ftp_crt_SUCCESS = 0, + ftp_crt_PARTIALFAIL = 1, + ftp_crt_FAIL = 2, + ftp_crt_ABORTED = 3, + ftp_crt_HOST_NOT_ACCEPTING = 4 + }; -enum FTP_Client_CallbackType { - ftp_cct_Map = 0, - ftp_cct_Tileset = 1, - ftp_cct_Techtree = 2, - ftp_cct_Scenario = 3, - ftp_cct_File = 4, - ftp_cct_TempFile = 5, - ftp_cct_DownloadProgress = 6, - ftp_cct_ExtractProgress = 7 -}; + enum FTP_Client_CallbackType { + ftp_cct_Map = 0, + ftp_cct_Tileset = 1, + ftp_cct_Techtree = 2, + ftp_cct_Scenario = 3, + ftp_cct_File = 4, + ftp_cct_TempFile = 5, + ftp_cct_DownloadProgress = 6, + ftp_cct_ExtractProgress = 7 + }; -class FTPClientCallbackInterface { -public: - virtual ~FTPClientCallbackInterface() {} - struct FtpProgressStats { - double download_total; - double download_now; - double upload_total; - double upload_now; - string currentFilename; - FTP_Client_CallbackType downloadType; - }; + class FTPClientCallbackInterface { + public: + virtual ~FTPClientCallbackInterface() { + } + struct FtpProgressStats { + double download_total; + double download_now; + double upload_total; + double upload_now; + string currentFilename; + FTP_Client_CallbackType downloadType; + }; - virtual void FTPClient_CallbackEvent(string itemName, - FTP_Client_CallbackType type, - pair result, - void *userdata) = 0; -}; + virtual void FTPClient_CallbackEvent(string itemName, + FTP_Client_CallbackType type, + pair result, + void *userdata) = 0; + }; -class FTPClientThread : public BaseThread, public ShellCommandOutputCallbackInterface -{ -protected: - int portNumber; - string serverUrl; - FTPClientCallbackInterface *pCBObject; - std::pair mapsPath; - std::pair tilesetsPath; - std::pair techtreesPath; - std::pair scenariosPath; - string tempFilesPath; + class FTPClientThread : public BaseThread, public ShellCommandOutputCallbackInterface { + protected: + int portNumber; + string serverUrl; + FTPClientCallbackInterface *pCBObject; + std::pair mapsPath; + std::pair tilesetsPath; + std::pair techtreesPath; + std::pair scenariosPath; + string tempFilesPath; - Mutex mutexMapFileList; - vector > mapFileList; + Mutex mutexMapFileList; + vector > mapFileList; - Mutex mutexTilesetList; - vector > tilesetList; + Mutex mutexTilesetList; + vector > tilesetList; - Mutex mutexTechtreeList; - vector > techtreeList; + Mutex mutexTechtreeList; + vector > techtreeList; - Mutex mutexScenarioList; - vector > scenarioList; + Mutex mutexScenarioList; + vector > scenarioList; - Mutex mutexFileList; - vector > fileList; + Mutex mutexFileList; + vector > fileList; - Mutex mutexTempFileList; - vector > tempFileList; + Mutex mutexTempFileList; + vector > tempFileList; - void getMapFromServer(pair mapFilename); - pair getMapFromServer(pair mapFileName, string ftpUser, string ftpUserPassword); + void getMapFromServer(pair mapFilename); + pair getMapFromServer(pair mapFileName, string ftpUser, string ftpUserPassword); - void getTilesetFromServer(pair tileSetName); - pair getTilesetFromServer(pair tileSetName, string tileSetNameSubfolder, string ftpUser, string ftpUserPassword, bool findArchive); + void getTilesetFromServer(pair tileSetName); + pair getTilesetFromServer(pair tileSetName, string tileSetNameSubfolder, string ftpUser, string ftpUserPassword, bool findArchive); - void getTechtreeFromServer(pair techtreeName); - pair getTechtreeFromServer(pair techtreeName, string ftpUser, string ftpUserPassword); + void getTechtreeFromServer(pair techtreeName); + pair getTechtreeFromServer(pair techtreeName, string ftpUser, string ftpUserPassword); - void getScenarioFromServer(pair fileName); - pair getScenarioInternalFromServer(pair fileName); + void getScenarioFromServer(pair fileName); + pair getScenarioInternalFromServer(pair fileName); - void getFileFromServer(pair fileName); - pair getFileInternalFromServer(pair fileName); + void getFileFromServer(pair fileName); + pair getFileInternalFromServer(pair fileName); - void getTempFileFromServer(pair fileName); - pair getTempFileInternalFromServer(pair fileName); + void getTempFileFromServer(pair fileName); + pair getTempFileInternalFromServer(pair fileName); - Mutex mutexProgressMutex; + Mutex mutexProgressMutex; - string fileArchiveExtension; - string fileArchiveExtractCommand; - string fileArchiveExtractCommandParameters; - int fileArchiveExtractCommandSuccessResult; + string fileArchiveExtension; + string fileArchiveExtractCommand; + string fileArchiveExtractCommandParameters; + int fileArchiveExtractCommandSuccessResult; - pair getFileFromServer(FTP_Client_CallbackType downloadType, - pair fileNameTitle, - string remotePath, string destFileSaveAs, string ftpUser, - string ftpUserPassword, vector *wantDirListOnly=NULL); + pair getFileFromServer(FTP_Client_CallbackType downloadType, + pair fileNameTitle, + string remotePath, string destFileSaveAs, string ftpUser, + string ftpUserPassword, vector *wantDirListOnly = NULL); - string shellCommandCallbackUserData; - virtual void * getShellCommandOutput_UserData(string cmd); - virtual void ShellCommandOutput_CallbackEvent(string cmd,char *output,void *userdata); + string shellCommandCallbackUserData; + virtual void * getShellCommandOutput_UserData(string cmd); + virtual void ShellCommandOutput_CallbackEvent(string cmd, char *output, void *userdata); -public: + public: - FTPClientThread(int portNumber,string serverUrl, - std::pair mapsPath, - std::pair tilesetsPath, - std::pair techtreesPath, - std::pair scenariosPath, - FTPClientCallbackInterface *pCBObject, - string fileArchiveExtension, - string fileArchiveExtractCommand, - string fileArchiveExtractCommandParameters, - int fileArchiveExtractCommandSuccessResult, - string tempFilesPath); - virtual void execute(); - virtual void signalQuit(); - virtual bool shutdownAndWait(); + FTPClientThread(int portNumber, string serverUrl, + std::pair mapsPath, + std::pair tilesetsPath, + std::pair techtreesPath, + std::pair scenariosPath, + FTPClientCallbackInterface *pCBObject, + string fileArchiveExtension, + string fileArchiveExtractCommand, + string fileArchiveExtractCommandParameters, + int fileArchiveExtractCommandSuccessResult, + string tempFilesPath); + virtual void execute(); + virtual void signalQuit(); + virtual bool shutdownAndWait(); - void addMapToRequests(string mapFilename,string URL=""); - void addTilesetToRequests(string tileSetName,string URL=""); - void addTechtreeToRequests(string techtreeName,string URL=""); - void addScenarioToRequests(string fileName,string URL=""); - void addFileToRequests(string fileName,string URL=""); - void addTempFileToRequests(string fileName,string URL=""); + void addMapToRequests(string mapFilename, string URL = ""); + void addTilesetToRequests(string tileSetName, string URL = ""); + void addTechtreeToRequests(string techtreeName, string URL = ""); + void addScenarioToRequests(string fileName, string URL = ""); + void addFileToRequests(string fileName, string URL = ""); + void addTempFileToRequests(string fileName, string URL = ""); - FTPClientCallbackInterface * getCallBackObject(); - void setCallBackObject(FTPClientCallbackInterface *value); + FTPClientCallbackInterface * getCallBackObject(); + void setCallBackObject(FTPClientCallbackInterface *value); - Mutex * getProgressMutex() { return &mutexProgressMutex; } -}; + Mutex * getProgressMutex() { + return &mutexProgressMutex; + } + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/platform/posix/miniftpserver.h b/source/shared_lib/include/platform/posix/miniftpserver.h index 6af84148a..22467b925 100644 --- a/source/shared_lib/include/platform/posix/miniftpserver.h +++ b/source/shared_lib/include/platform/posix/miniftpserver.h @@ -13,8 +13,8 @@ #define _SHARED_PLATFORMCOMMON_MINIFTPSERVERTHREAD_H_ #ifdef WIN32 - #include - #include +#include +#include #endif #include "base_thread.h" @@ -27,47 +27,50 @@ using namespace std; -namespace Shared { namespace PlatformCommon { +namespace Shared { + namespace PlatformCommon { -// ===================================================== -// class FTPServerThread -// ===================================================== + // ===================================================== + // class FTPServerThread + // ===================================================== -class FTPServerThread : public BaseThread -{ -protected: - std::pair mapsPath; - std::pair tilesetsPath; - std::pair techtreesPath; - string tempFilesPath; + class FTPServerThread : public BaseThread { + protected: + std::pair mapsPath; + std::pair tilesetsPath; + std::pair techtreesPath; + string tempFilesPath; - int portNumber; - int maxPlayers; - static FTPClientValidationInterface *ftpValidationIntf; + int portNumber; + int maxPlayers; + static FTPClientValidationInterface *ftpValidationIntf; - bool internetEnabled; - bool allowInternetTilesetFileTransfers; - bool allowInternetTechtreeFileTransfers; + bool internetEnabled; + bool allowInternetTilesetFileTransfers; + bool allowInternetTechtreeFileTransfers; -public: + public: - FTPServerThread(std::pair mapsPath, - std::pair tilesetsPath, std::pair techtreesPath, - bool internetEnabledFlag, - bool allowInternetTilesetFileTransfers, bool allowInternetTechtreeFileTransfers, - int portNumber,int maxPlayers, FTPClientValidationInterface *ftpValidationIntf, - string tempFilesPath); - ~FTPServerThread(); - virtual void execute(); - virtual void signalQuit(); - virtual bool shutdownAndWait(); + FTPServerThread(std::pair mapsPath, + std::pair tilesetsPath, std::pair techtreesPath, + bool internetEnabledFlag, + bool allowInternetTilesetFileTransfers, bool allowInternetTechtreeFileTransfers, + int portNumber, int maxPlayers, FTPClientValidationInterface *ftpValidationIntf, + string tempFilesPath); + ~FTPServerThread(); + virtual void execute(); + virtual void signalQuit(); + virtual bool shutdownAndWait(); - void setInternetEnabled(bool value, bool forceChange=false); - static void addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp); - static FTPClientValidationInterface * getFtpValidationIntf() { return ftpValidationIntf; } + void setInternetEnabled(bool value, bool forceChange = false); + static void addClientToServerIPAddress(uint32 clientIp, uint32 ServerIp); + static FTPClientValidationInterface * getFtpValidationIntf() { + return ftpValidationIntf; + } -}; + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/platform/posix/socket.h b/source/shared_lib/include/platform/posix/socket.h index d923b2199..6080b9479 100644 --- a/source/shared_lib/include/platform/posix/socket.h +++ b/source/shared_lib/include/platform/posix/socket.h @@ -13,28 +13,28 @@ #define _SHARED_PLATFORM_SOCKET_H_ #ifdef WIN32 - #ifdef __MINGW32__ - #include - #else - #include - #include - #endif - - typedef SOCKET PLATFORM_SOCKET; - #if defined(_WIN64) - #define PLATFORM_SOCKET_FORMAT_TYPE MG_I64U_SPECIFIER - #else - #define PLATFORM_SOCKET_FORMAT_TYPE "%d" - #endif +#ifdef __MINGW32__ +#include #else - #include - #include - #include - #include - #include +#include +#include +#endif - typedef int PLATFORM_SOCKET; - #define PLATFORM_SOCKET_FORMAT_TYPE "%d" +typedef SOCKET PLATFORM_SOCKET; +#if defined(_WIN64) +#define PLATFORM_SOCKET_FORMAT_TYPE MG_I64U_SPECIFIER +#else +#define PLATFORM_SOCKET_FORMAT_TYPE "%d" +#endif +#else +#include +#include +#include +#include +#include + +typedef int PLATFORM_SOCKET; +#define PLATFORM_SOCKET_FORMAT_TYPE "%d" #endif #include @@ -53,312 +53,345 @@ using std::string; using namespace Shared::PlatformCommon; -namespace Shared { namespace Platform { +namespace Shared { + namespace Platform { #ifdef WIN32 - #define PLATFORM_SOCKET_TRY_AGAIN WSAEWOULDBLOCK - #define PLATFORM_SOCKET_INPROGRESS WSAEINPROGRESS - #define PLATFORM_SOCKET_INTERRUPTED WSAEWOULDBLOCK +#define PLATFORM_SOCKET_TRY_AGAIN WSAEWOULDBLOCK +#define PLATFORM_SOCKET_INPROGRESS WSAEINPROGRESS +#define PLATFORM_SOCKET_INTERRUPTED WSAEWOULDBLOCK #else - #define PLATFORM_SOCKET_TRY_AGAIN EAGAIN - #define PLATFORM_SOCKET_INPROGRESS EINPROGRESS - #define PLATFORM_SOCKET_INTERRUPTED EINTR +#define PLATFORM_SOCKET_TRY_AGAIN EAGAIN +#define PLATFORM_SOCKET_INPROGRESS EINPROGRESS +#define PLATFORM_SOCKET_INTERRUPTED EINTR #endif -// The callback Interface used by the UPNP discovery process -class FTPClientValidationInterface { -public: - virtual int isValidClientType(uint32 clientIp) = 0; - virtual int isClientAllowedToGetFile(uint32 clientIp, const char *username, const char *filename) = 0; + // The callback Interface used by the UPNP discovery process + class FTPClientValidationInterface { + public: + virtual int isValidClientType(uint32 clientIp) = 0; + virtual int isClientAllowedToGetFile(uint32 clientIp, const char *username, const char *filename) = 0; - virtual ~FTPClientValidationInterface() {} -}; + virtual ~FTPClientValidationInterface() { + } + }; -// The callback Interface used by the UPNP discovery process -class UPNPInitInterface { -public: - virtual void UPNPInitStatus(bool result) = 0; + // The callback Interface used by the UPNP discovery process + class UPNPInitInterface { + public: + virtual void UPNPInitStatus(bool result) = 0; - virtual ~UPNPInitInterface() {} -}; + virtual ~UPNPInitInterface() { + } + }; -// -// This interface describes the methods a callback object must implement -// when signaled with detected servers -// -class DiscoveredServersInterface { -public: - virtual void DiscoveredServers(std::vector serverList) = 0; - virtual ~DiscoveredServersInterface() {} -}; + // + // This interface describes the methods a callback object must implement + // when signaled with detected servers + // + class DiscoveredServersInterface { + public: + virtual void DiscoveredServers(std::vector serverList) = 0; + virtual ~DiscoveredServersInterface() { + } + }; -// ===================================================== -// class IP -// ===================================================== -class Ip { -private: - unsigned char bytes[4]; + // ===================================================== + // class IP + // ===================================================== + class Ip { + private: + unsigned char bytes[4]; -public: - Ip(); - Ip(unsigned char byte0, unsigned char byte1, unsigned char byte2, unsigned char byte3); - Ip(const string& ipString); - static void Inet_NtoA(uint32 addr, char * ipbuf); + public: + Ip(); + Ip(unsigned char byte0, unsigned char byte1, unsigned char byte2, unsigned char byte3); + Ip(const string& ipString); + static void Inet_NtoA(uint32 addr, char * ipbuf); - unsigned char getByte(int byteIndex) {return bytes[byteIndex];} - string getString() const; -}; + unsigned char getByte(int byteIndex) { + return bytes[byteIndex]; + } + string getString() const; + }; -// ===================================================== -// class Socket -// ===================================================== + // ===================================================== + // class Socket + // ===================================================== #ifdef WIN32 -class SocketManager{ -public: - SocketManager(); - ~SocketManager(); -}; + class SocketManager { + public: + SocketManager(); + ~SocketManager(); + }; #endif -class Socket { + class Socket { -protected: -//#ifdef WIN32 - //static SocketManager wsaManager; -//#endif - PLATFORM_SOCKET sock; - time_t lastDebugEvent; - static int broadcast_portno; - std::string ipAddress; - std::string connectedIpAddress; + protected: + //#ifdef WIN32 + //static SocketManager wsaManager; + //#endif + PLATFORM_SOCKET sock; + time_t lastDebugEvent; + static int broadcast_portno; + std::string ipAddress; + std::string connectedIpAddress; - //SimpleTaskThread *pingThread; - std::map pingCache; - time_t lastThreadedPing; - //Mutex pingThreadAccessor; + //SimpleTaskThread *pingThread; + std::map pingCache; + time_t lastThreadedPing; + //Mutex pingThreadAccessor; - Mutex *dataSynchAccessorRead; - Mutex *dataSynchAccessorWrite; + Mutex *dataSynchAccessorRead; + Mutex *dataSynchAccessorWrite; - Mutex *inSocketDestructorSynchAccessor; - bool inSocketDestructor; + Mutex *inSocketDestructorSynchAccessor; + bool inSocketDestructor; - bool isSocketBlocking; - time_t lastSocketError; + bool isSocketBlocking; + time_t lastSocketError; - static string host_name; - static std::vector intfTypes; + static string host_name; + static std::vector intfTypes; -public: - Socket(PLATFORM_SOCKET sock); - Socket(); - virtual ~Socket(); + public: + Socket(PLATFORM_SOCKET sock); + Socket(); + virtual ~Socket(); - static int getLastSocketError(); - static const char * getLastSocketErrorText(int *errNumber=NULL); - static string getLastSocketErrorFormattedText(int *errNumber=NULL); + static int getLastSocketError(); + static const char * getLastSocketErrorText(int *errNumber = NULL); + static string getLastSocketErrorFormattedText(int *errNumber = NULL); - static void setIntfTypes(std::vector intfTypes) { Socket::intfTypes = intfTypes; } - static bool disableNagle; - static int DEFAULT_SOCKET_SENDBUF_SIZE; - static int DEFAULT_SOCKET_RECVBUF_SIZE; + static void setIntfTypes(std::vector intfTypes) { + Socket::intfTypes = intfTypes; + } + static bool disableNagle; + static int DEFAULT_SOCKET_SENDBUF_SIZE; + static int DEFAULT_SOCKET_RECVBUF_SIZE; - static int getBroadCastPort() { return broadcast_portno; } - static void setBroadCastPort(int value) { broadcast_portno = value; } - static std::vector getLocalIPAddressList(); + static int getBroadCastPort() { + return broadcast_portno; + } + static void setBroadCastPort(int value) { + broadcast_portno = value; + } + static std::vector getLocalIPAddressList(); - // Int lookup is socket fd while bool result is whether or not that socket was signalled for reading - static bool hasDataToRead(std::map &socketTriggeredList); - static bool hasDataToRead(PLATFORM_SOCKET socket); - bool hasDataToRead(); + // Int lookup is socket fd while bool result is whether or not that socket was signalled for reading + static bool hasDataToRead(std::map &socketTriggeredList); + static bool hasDataToRead(PLATFORM_SOCKET socket); + bool hasDataToRead(); - static bool hasDataToReadWithWait(PLATFORM_SOCKET socket,int waitMicroseconds); - bool hasDataToReadWithWait(int waitMicroseconds); + static bool hasDataToReadWithWait(PLATFORM_SOCKET socket, int waitMicroseconds); + bool hasDataToReadWithWait(int waitMicroseconds); - virtual void disconnectSocket(); + virtual void disconnectSocket(); - PLATFORM_SOCKET getSocketId() const { return sock; } + PLATFORM_SOCKET getSocketId() const { + return sock; + } - int getDataToRead(bool wantImmediateReply=false); - int send(const void *data, int dataSize); - int receive(void *data, int dataSize, bool tryReceiveUntilDataSizeMet); - int peek(void *data, int dataSize, bool mustGetData=true,int *pLastSocketError=NULL); + int getDataToRead(bool wantImmediateReply = false); + int send(const void *data, int dataSize); + int receive(void *data, int dataSize, bool tryReceiveUntilDataSizeMet); + int peek(void *data, int dataSize, bool mustGetData = true, int *pLastSocketError = NULL); - void setBlock(bool block); - static void setBlock(bool block, PLATFORM_SOCKET socket); - bool getBlock(); + void setBlock(bool block); + static void setBlock(bool block, PLATFORM_SOCKET socket); + bool getBlock(); - bool isReadable(bool lockMutex=false); - bool isWritable(struct timeval *timeVal=NULL,bool lockMutex=false); - bool isConnected(); + bool isReadable(bool lockMutex = false); + bool isWritable(struct timeval *timeVal = NULL, bool lockMutex = false); + bool isConnected(); - static string getHostName(); - static string getIp(); - bool isSocketValid() const; - static bool isSocketValid(const PLATFORM_SOCKET *validateSocket); + static string getHostName(); + static string getIp(); + bool isSocketValid() const; + static bool isSocketValid(const PLATFORM_SOCKET *validateSocket); - static double getAveragePingMS(std::string host, int pingCount=5); - float getThreadedPingMS(std::string host); + static double getAveragePingMS(std::string host, int pingCount = 5); + float getThreadedPingMS(std::string host); - virtual std::string getIpAddress(); - virtual void setIpAddress(std::string value) { ipAddress = value; } + virtual std::string getIpAddress(); + virtual void setIpAddress(std::string value) { + ipAddress = value; + } - uint32 getConnectedIPAddress(string IP=""); + uint32 getConnectedIPAddress(string IP = ""); -protected: - static void throwException(string str); - static void getLocalIPAddressListForPlatform(std::vector &ipList); -}; + protected: + static void throwException(string str); + static void getLocalIPAddressListForPlatform(std::vector &ipList); + }; -class SafeSocketBlockToggleWrapper { -protected: - Socket *socket; - bool originallyBlocked; - bool newBlocked; -public: - SafeSocketBlockToggleWrapper(Socket *socket, bool toggle); - ~SafeSocketBlockToggleWrapper(); - void Restore(); -}; + class SafeSocketBlockToggleWrapper { + protected: + Socket *socket; + bool originallyBlocked; + bool newBlocked; + public: + SafeSocketBlockToggleWrapper(Socket *socket, bool toggle); + ~SafeSocketBlockToggleWrapper(); + void Restore(); + }; -class BroadCastClientSocketThread : public BaseThread -{ -private: - DiscoveredServersInterface *discoveredServersCB; + class BroadCastClientSocketThread : public BaseThread { + private: + DiscoveredServersInterface *discoveredServersCB; -public: - BroadCastClientSocketThread(DiscoveredServersInterface *cb); - virtual void execute(); -}; + public: + BroadCastClientSocketThread(DiscoveredServersInterface *cb); + virtual void execute(); + }; -// ===================================================== -// class ClientSocket -// ===================================================== -class ClientSocket: public Socket { -public: - ClientSocket(); - virtual ~ClientSocket(); + // ===================================================== + // class ClientSocket + // ===================================================== + class ClientSocket : public Socket { + public: + ClientSocket(); + virtual ~ClientSocket(); - void connect(const Ip &ip, int port); - static void discoverServers(DiscoveredServersInterface *cb); + void connect(const Ip &ip, int port); + static void discoverServers(DiscoveredServersInterface *cb); - static void stopBroadCastClientThread(); + static void stopBroadCastClientThread(); -protected: + protected: - static BroadCastClientSocketThread *broadCastClientThread; - static void startBroadCastClientThread(DiscoveredServersInterface *cb); -}; + static BroadCastClientSocketThread *broadCastClientThread; + static void startBroadCastClientThread(DiscoveredServersInterface *cb); + }; -class BroadCastSocketThread : public BaseThread -{ -private: - Mutex *mutexPauseBroadcast; - bool pauseBroadcast; - int boundPort; + class BroadCastSocketThread : public BaseThread { + private: + Mutex *mutexPauseBroadcast; + bool pauseBroadcast; + int boundPort; -public: - BroadCastSocketThread(int boundPort); - virtual ~BroadCastSocketThread(); - virtual void execute(); - virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false); + public: + BroadCastSocketThread(int boundPort); + virtual ~BroadCastSocketThread(); + virtual void execute(); + virtual bool canShutdown(bool deleteSelfIfShutdownDelayed = false); - bool getPauseBroadcast(); - void setPauseBroadcast(bool value); -}; + bool getPauseBroadcast(); + void setPauseBroadcast(bool value); + }; -// ===================================================== -// class ServerSocket -// ===================================================== -class ServerSocket: public Socket, public UPNPInitInterface { -protected: + // ===================================================== + // class ServerSocket + // ===================================================== + class ServerSocket : public Socket, public UPNPInitInterface { + protected: - bool portBound; - int boundPort; - string bindSpecificAddress; + bool portBound; + int boundPort; + string bindSpecificAddress; - static int externalPort; - static int ftpServerPort; + static int externalPort; + static int ftpServerPort; - static int maxPlayerCount; + static int maxPlayerCount; - virtual void UPNPInitStatus(bool result); - BroadCastSocketThread *broadCastThread; - void startBroadCastThread(); - void resumeBroadcast(); - bool isBroadCastThreadRunning(); - vector blockIPList; + virtual void UPNPInitStatus(bool result); + BroadCastSocketThread *broadCastThread; + void startBroadCastThread(); + void resumeBroadcast(); + bool isBroadCastThreadRunning(); + vector blockIPList; - bool basicMode; + bool basicMode; -public: - ServerSocket(bool basicMode = false); - virtual ~ServerSocket(); - void bind(int port); - void listen(int connectionQueueSize= SOMAXCONN); - Socket *accept(bool errorOnFail=true); - void stopBroadCastThread(); - void pauseBroadcast(); + public: + ServerSocket(bool basicMode = false); + virtual ~ServerSocket(); + void bind(int port); + void listen(int connectionQueueSize = SOMAXCONN); + Socket *accept(bool errorOnFail = true); + void stopBroadCastThread(); + void pauseBroadcast(); - void addIPAddressToBlockedList(string value); - bool isIPAddressBlocked(string value) const; - void removeBlockedIPAddress(string value); - void clearBlockedIPAddress(); - bool hasBlockedIPAddresses() const; + void addIPAddressToBlockedList(string value); + bool isIPAddressBlocked(string value) const; + void removeBlockedIPAddress(string value); + void clearBlockedIPAddress(); + bool hasBlockedIPAddresses() const; - void setBindPort(int port) { boundPort = port; } - int getBindPort() const { return boundPort; } - bool isPortBound() const { return portBound; } + void setBindPort(int port) { + boundPort = port; + } + int getBindPort() const { + return boundPort; + } + bool isPortBound() const { + return portBound; + } - void setBindSpecificAddress(string value) { bindSpecificAddress = value;} + void setBindSpecificAddress(string value) { + bindSpecificAddress = value; + } - static void setExternalPort(int port) { externalPort = port; } - static int getExternalPort() { return externalPort; } + static void setExternalPort(int port) { + externalPort = port; + } + static int getExternalPort() { + return externalPort; + } - static void setFTPServerPort(int port) { ftpServerPort = port; } - static int getFTPServerPort() { return ftpServerPort; } + static void setFTPServerPort(int port) { + ftpServerPort = port; + } + static int getFTPServerPort() { + return ftpServerPort; + } - virtual void disconnectSocket(); + virtual void disconnectSocket(); - void NETdiscoverUPnPDevices(); + void NETdiscoverUPnPDevices(); - static void setMaxPlayerCount(int value) { maxPlayerCount=value; } + static void setMaxPlayerCount(int value) { + maxPlayerCount = value; + } - static Mutex mutexUpnpdiscoverThread; - static SDL_Thread *upnpdiscoverThread; - static bool cancelUpnpdiscoverThread; -}; + static Mutex mutexUpnpdiscoverThread; + static SDL_Thread *upnpdiscoverThread; + static bool cancelUpnpdiscoverThread; + }; -// ===================================================== -// class UPNP_Tools -// ===================================================== -class UPNP_Tools { + // ===================================================== + // class UPNP_Tools + // ===================================================== + class UPNP_Tools { -public: + public: - static bool isUPNP; - static bool enabledUPNP; - static Mutex mutexUPNP; + static bool isUPNP; + static bool enabledUPNP; + static Mutex mutexUPNP; - static int upnp_init(void *param); + static int upnp_init(void *param); - static bool upnp_add_redirect(int ports[2],bool mutexLock=true); - static void upnp_rem_redirect(int ext_port); + static bool upnp_add_redirect(int ports[2], bool mutexLock = true); + static void upnp_rem_redirect(int ext_port); - static void NETaddRedirects(std::vector UPNPPortForwardList, bool mutexLock=true); - static void NETremRedirects(int ext_port); + static void NETaddRedirects(std::vector UPNPPortForwardList, bool mutexLock = true); + static void NETremRedirects(int ext_port); - static void AddUPNPPortForward(int internalPort, int externalPort); - static void RemoveUPNPPortForward(int internalPort, int externalPort); -}; + static void AddUPNPPortForward(int internalPort, int externalPort); + static void RemoveUPNPPortForward(int internalPort, int externalPort); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/platform/sdl/gl_wrap.h b/source/shared_lib/include/platform/sdl/gl_wrap.h index 0bcfd4126..9e7fabe3a 100644 --- a/source/shared_lib/include/platform/sdl/gl_wrap.h +++ b/source/shared_lib/include/platform/sdl/gl_wrap.h @@ -36,61 +36,67 @@ using std::string; using Shared::Graphics::FontMetrics; -namespace Shared{ namespace Platform{ +namespace Shared { + namespace Platform { -// ===================================================== -// class PlatformContextGl -// ===================================================== + // ===================================================== + // class PlatformContextGl + // ===================================================== -class PlatformContextGl { -protected: - SDL_Surface *icon; - SDL_Window *window; - SDL_GLContext glcontext; + class PlatformContextGl { + protected: + SDL_Surface *icon; + SDL_Window *window; + SDL_GLContext glcontext; -public: - // Example values: - // DEFAULT_CHARSET (English) = 1 - // GB2312_CHARSET (Chinese) = 134 - #ifdef WIN32 - static DWORD charSet; - #else - static int charSet; - #endif + public: + // Example values: + // DEFAULT_CHARSET (English) = 1 + // GB2312_CHARSET (Chinese) = 134 +#ifdef WIN32 + static DWORD charSet; +#else + static int charSet; +#endif -public: - PlatformContextGl(); - virtual ~PlatformContextGl(); + public: + PlatformContextGl(); + virtual ~PlatformContextGl(); - virtual void init(int colorBits, int depthBits, int stencilBits, - bool hardware_acceleration, bool fullscreen_anti_aliasing, - float gammaValue); - virtual void end(); + virtual void init(int colorBits, int depthBits, int stencilBits, + bool hardware_acceleration, bool fullscreen_anti_aliasing, + float gammaValue); + virtual void end(); - virtual void makeCurrent(); - virtual void swapBuffers(); + virtual void makeCurrent(); + virtual void swapBuffers(); - SDL_Window * getScreenWindow() { return window; } - SDL_Surface * getScreenSurface(); + SDL_Window * getScreenWindow() { + return window; + } + SDL_Surface * getScreenSurface(); - DeviceContextHandle getHandle() const { return 0; } -}; + DeviceContextHandle getHandle() const { + return 0; + } + }; -// ===================================================== -// Global Fcs -// ===================================================== + // ===================================================== + // Global Fcs + // ===================================================== #if defined(__APPLE__) -void createGlFontBitmaps(uint32 &base, const string &type, int size, int width, int charCount, FontMetrics &metrics); -void createGlFontOutlines(uint32 &base, const string &type, int width, float depth, int charCount, FontMetrics &metrics); + void createGlFontBitmaps(uint32 &base, const string &type, int size, int width, int charCount, FontMetrics &metrics); + void createGlFontOutlines(uint32 &base, const string &type, int width, float depth, int charCount, FontMetrics &metrics); #else -void createGlFontBitmaps(uint32 &base, const string &type, int size, int width, int charCount, FontMetrics &metrics); -void createGlFontOutlines(uint32 &base, const string &type, int width, float depth, int charCount, FontMetrics &metrics); + void createGlFontBitmaps(uint32 &base, const string &type, int size, int width, int charCount, FontMetrics &metrics); + void createGlFontOutlines(uint32 &base, const string &type, int width, float depth, int charCount, FontMetrics &metrics); #endif -const char *getPlatformExtensions(const PlatformContextGl *pcgl); -void* getGlProcAddress(const char *procName); + const char *getPlatformExtensions(const PlatformContextGl *pcgl); + void* getGlProcAddress(const char *procName); -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/platform/sdl/platform_main.h b/source/shared_lib/include/platform/sdl/platform_main.h index 5125bdb0d..483b94696 100644 --- a/source/shared_lib/include/platform/sdl/platform_main.h +++ b/source/shared_lib/include/platform/sdl/platform_main.h @@ -17,9 +17,9 @@ #include "leak_dumper.h" #ifndef WIN32 - #define stricmp strcasecmp - #define strnicmp strncasecmp - #define _strnicmp strncasecmp +#define stricmp strcasecmp +#define strnicmp strncasecmp +#define _strnicmp strncasecmp #endif const char *GAME_ARGS[] = { @@ -197,22 +197,22 @@ enum GAME_ARG_TYPE { void printParameterHelp(const char *argv0, bool foundInvalidArgs) { // MAX WIDTH FOR MAN PAGE // "================================================================================" - if(foundInvalidArgs == true) { - printf("\n"); + if (foundInvalidArgs == true) { + printf("\n"); } - printf("\n%s, usage",extractFileFromDirectoryPath(argv0).c_str()); + printf("\n%s, usage", extractFileFromDirectoryPath(argv0).c_str()); printf("\n\nCommandline Parameter: Description:"); printf("\n\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); - printf("\n\n%s \t\tDisplays this help text.",GAME_ARGS[GAME_ARG_HELP]); + printf("\n\n%s \t\tDisplays this help text.", GAME_ARGS[GAME_ARG_HELP]); - printf("\n\n%s \tAutomatically starts a game with the last game",GAME_ARGS[GAME_ARG_AUTOSTART_LASTGAME]); + printf("\n\n%s \tAutomatically starts a game with the last game", GAME_ARGS[GAME_ARG_AUTOSTART_LASTGAME]); printf("\n\n \tsettings you played."); - printf("\n\n%s=x \tLoads the last saved game.",GAME_ARGS[GAME_ARG_AUTOSTART_LAST_SAVED_GAME]); + printf("\n\n%s=x \tLoads the last saved game.", GAME_ARGS[GAME_ARG_AUTOSTART_LAST_SAVED_GAME]); printf("\n\n \tWhere x is an optional name of the saved game file to load."); printf("\n\n \tIf x is not specified we load the last game that was saved."); - printf("\n\n%s=x,y,z \tRun in auto test mode.",GAME_ARGS[GAME_ARG_AUTO_TEST]); + printf("\n\n%s=x,y,z \tRun in auto test mode.", GAME_ARGS[GAME_ARG_AUTO_TEST]); printf("\n\n \tWhere x is an optional maximum # seconds to play."); printf("\n\n \tIf x is not specified the default is 1200 seconds (20 minutes)."); printf("\n\n \tWhere y is an optional game settings file to play."); @@ -222,18 +222,18 @@ void printParameterHelp(const char *argv0, bool foundInvalidArgs) { printf("\n\n \tafter the game is finished or the time runs out. If z is"); printf("\n\n \tnot specified (or is empty) then auto test continues to cycle."); - printf("\n\n%s=x:y \t\tAuto connect to host server at IP or hostname x using",GAME_ARGS[GAME_ARG_CONNECT]); - printf("\n\n \t port y. Shortcut version of using %s and %s.",GAME_ARGS[GAME_ARG_CLIENT],GAME_ARGS[GAME_ARG_USE_PORTS]); + printf("\n\n%s=x:y \t\tAuto connect to host server at IP or hostname x using", GAME_ARGS[GAME_ARG_CONNECT]); + printf("\n\n \t port y. Shortcut version of using %s and %s.", GAME_ARGS[GAME_ARG_CLIENT], GAME_ARGS[GAME_ARG_USE_PORTS]); printf("\n\n \t*NOTE: to automatically connect to the first LAN host you may"); - printf("\n\n \t use: %s=auto-connect",GAME_ARGS[GAME_ARG_CONNECT]); + printf("\n\n \t use: %s=auto-connect", GAME_ARGS[GAME_ARG_CONNECT]); - printf("\n\n%s=x \tAuto connect to host server at IP or hostname x.",GAME_ARGS[GAME_ARG_CLIENT]); + printf("\n\n%s=x \tAuto connect to host server at IP or hostname x.", GAME_ARGS[GAME_ARG_CLIENT]); printf("\n\n \t*NOTE: to automatically connect to the first LAN host you may"); - printf("\n\n \t use: %s=auto-connect",GAME_ARGS[GAME_ARG_CLIENT]); + printf("\n\n \t use: %s=auto-connect", GAME_ARGS[GAME_ARG_CLIENT]); - printf("\n\n%s \t\tAuto create a host server.",GAME_ARGS[GAME_ARG_SERVER]); + printf("\n\n%s \t\tAuto create a host server.", GAME_ARGS[GAME_ARG_SERVER]); - printf("\n\n%s=x,x ",GAME_ARGS[GAME_ARG_MASTERSERVER_MODE]); + printf("\n\n%s=x,x ", GAME_ARGS[GAME_ARG_MASTERSERVER_MODE]); printf("\n\n \tRun as a headless server."); printf("\n\n \tWhere x is an optional comma delimited command list of one or"); printf("\n\n \t more of the following: "); @@ -244,10 +244,10 @@ void printParameterHelp(const char *argv0, bool foundInvalidArgs) { printf("\n\n \t'lan' - which does not broadcast the hosting server to the"); printf("\n\n \t masterserver (for local LAN games)."); - printf("\n\n%s ",GAME_ARGS[GAME_ARG_MASTERSERVER_STATUS]); + printf("\n\n%s ", GAME_ARGS[GAME_ARG_MASTERSERVER_STATUS]); printf("\n\n \tCheck the current status of a headless server."); - printf("\n\n%s=x,y,z \tForce hosted games to listen internally on port",GAME_ARGS[GAME_ARG_USE_PORTS]); + printf("\n\n%s=x,y,z \tForce hosted games to listen internally on port", GAME_ARGS[GAME_ARG_USE_PORTS]); printf("\n\n \t x, externally on port y and for game status on port z."); printf("\n\n \tWhere x is the internal port # on the local machine to"); printf("\n\n \t listen for connects."); @@ -258,23 +258,23 @@ void printParameterHelp(const char *argv0, bool foundInvalidArgs) { printf("\n\n \t*NOTE: If enabled the FTP Server port #'s will be set"); printf("\n\n \t to x+1 to x+9."); - printf("\n\n%s=x \tSet server title.",GAME_ARGS[GAME_ARG_SERVER_TITLE]); + printf("\n\n%s=x \tSet server title.", GAME_ARGS[GAME_ARG_SERVER_TITLE]); - printf("\n\n%s=x \tAuto load a scenario by scenario name.",GAME_ARGS[GAME_ARG_LOADSCENARIO]); - printf("\n\n%s=x \t\tAuto load a mod by mod pathname.",GAME_ARGS[GAME_ARG_MOD]); + printf("\n\n%s=x \tAuto load a scenario by scenario name.", GAME_ARGS[GAME_ARG_LOADSCENARIO]); + printf("\n\n%s=x \t\tAuto load a mod by mod pathname.", GAME_ARGS[GAME_ARG_MOD]); // "================================================================================" - printf("\n\n%s=Map,Tileset ",GAME_ARGS[GAME_ARG_PREVIEW_MAP]); + printf("\n\n%s=Map,Tileset ", GAME_ARGS[GAME_ARG_PREVIEW_MAP]); printf("\n\n \tAuto Preview a map by map name. (tileset is optional)"); - printf("\n\n%s \t\tDisplays the version string of this program.",GAME_ARGS[GAME_ARG_VERSION]); - printf("\n\n%s \t\tDisplays your video driver's OpenGL info.",GAME_ARGS[GAME_ARG_OPENGL_INFO]); - printf("\n\n%s \t\tDisplays your SDL version information.",GAME_ARGS[GAME_ARG_SDL_INFO]); - printf("\n\n%s \t\tDisplays your LUA version information.",GAME_ARGS[GAME_ARG_LUA_INFO]); - printf("\n\n%s \t\tDisplays LUA debug information.",GAME_ARGS[GAME_ARG_LUA_DEBUG]); - printf("\n\n%s \t\tDisplays your CURL version information.",GAME_ARGS[GAME_ARG_CURL_INFO]); - printf("\n\n%s \t\tDisplays your XERCES version information.",GAME_ARGS[GAME_ARG_XERCES_INFO]); + printf("\n\n%s \t\tDisplays the version string of this program.", GAME_ARGS[GAME_ARG_VERSION]); + printf("\n\n%s \t\tDisplays your video driver's OpenGL info.", GAME_ARGS[GAME_ARG_OPENGL_INFO]); + printf("\n\n%s \t\tDisplays your SDL version information.", GAME_ARGS[GAME_ARG_SDL_INFO]); + printf("\n\n%s \t\tDisplays your LUA version information.", GAME_ARGS[GAME_ARG_LUA_INFO]); + printf("\n\n%s \t\tDisplays LUA debug information.", GAME_ARGS[GAME_ARG_LUA_DEBUG]); + printf("\n\n%s \t\tDisplays your CURL version information.", GAME_ARGS[GAME_ARG_CURL_INFO]); + printf("\n\n%s \t\tDisplays your XERCES version information.", GAME_ARGS[GAME_ARG_XERCES_INFO]); - printf("\n\n%s=x=purgeunused=purgeduplicates=gitdelete=hideduplicates ",GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]); + printf("\n\n%s=x=purgeunused=purgeduplicates=gitdelete=hideduplicates ", GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]); printf("\n\n \tDisplay a report detailing any known problems related to"); printf("\n\n \t your selected techtrees game data."); printf("\n\n \tWhere x is a comma-delimited list of techtrees to validate."); @@ -291,9 +291,9 @@ void printParameterHelp(const char *argv0, bool foundInvalidArgs) { printf("\n\n \t*NOTE: This only applies when files are purged due to the"); printf("\n\n \t above flags being set."); printf("\n\n \texample:"); - printf("\n\n \t%s %s=megapack,vbros_pack_5",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]); + printf("\n\n \t%s %s=megapack,vbros_pack_5", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]); - printf("\n\n%s=x=purgeunused=purgeduplicates=hideduplicates ",GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]); + printf("\n\n%s=x=purgeunused=purgeduplicates=hideduplicates ", GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]); printf("\n\n \tDisplay a report detailing any known problems related to"); printf("\n\n \t your selected factions game data."); printf("\n\n \tWhere x is a comma-delimited list of factions to validate."); @@ -305,72 +305,72 @@ void printParameterHelp(const char *argv0, bool foundInvalidArgs) { printf("\n\n \tWhere 'hideduplicates' is an optional parameter telling the"); printf("\n\n \t validation to NOT SHOW duplicate files in the techtree."); printf("\n\n \t*NOTE: leaving the list empty is the same as running:"); - printf("\n\n \t %s",GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]); - printf("\n\n \texample: %s %s=tech,egypt",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]); + printf("\n\n \t %s", GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]); + printf("\n\n \texample: %s %s=tech,egypt", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]); - printf("\n\n%s=x=purgeunused=gitdelete ",GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]); + printf("\n\n%s=x=purgeunused=gitdelete ", GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]); printf("\n\n \tDisplay a report detailing any known problems related to"); printf("\n\n \t your selected scenario game data."); printf("\n\n \tWhere x is a single scenario to validate."); printf("\n\n \tWhere 'purgeunused' is an optional parameter telling the"); printf("\n\n \t validation to delete extra files in the scenario that"); printf("\n\n \t are not used."); - printf("\n\n \texample: %s %s=stranded",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]); + printf("\n\n \texample: %s %s=stranded", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]); - printf("\n\n%s=x=purgeunused=gitdelete ",GAME_ARGS[GAME_ARG_VALIDATE_TILESET]); + printf("\n\n%s=x=purgeunused=gitdelete ", GAME_ARGS[GAME_ARG_VALIDATE_TILESET]); printf("\n\n \tDisplay a report detailing any known problems related to"); printf("\n\n \t your selected tileset game data."); printf("\n\n \tWhere x is a single tileset to validate."); printf("\n\n \tWhere 'purgeunused' is an optional parameter telling the"); printf("\n\n \t validation to delete extra files in the tileset that"); printf("\n\n \t are not used."); - printf("\n\n \texample: %s %s=desert2",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_VALIDATE_TILESET]); + printf("\n\n \texample: %s %s=desert2", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_VALIDATE_TILESET]); - printf("\n\n%s=x ",GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]); + printf("\n\n%s=x ", GAME_ARGS[GAME_ARG_TRANSLATE_TECHTREES]); printf("\n\n \tProduces a default lng file for the specified techtree to"); printf("\n\n \t prepare for translation into other languages."); printf("\n\n \tWhere x is a techtree name."); - printf("\n\n%s=x \t\tDisplay a list of game content: maps.",GAME_ARGS[GAME_ARG_LIST_MAPS]); + printf("\n\n%s=x \t\tDisplay a list of game content: maps.", GAME_ARGS[GAME_ARG_LIST_MAPS]); printf("\n\n \tWhere x is an optional name filter."); - printf("\n\n \texample: %s %s=island*",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_LIST_MAPS]); + printf("\n\n \texample: %s %s=island*", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_LIST_MAPS]); - printf("\n\n%s=showfactions ",GAME_ARGS[GAME_ARG_LIST_TECHTRESS]); + printf("\n\n%s=showfactions ", GAME_ARGS[GAME_ARG_LIST_TECHTRESS]); printf("\n\n \tDisplay a list of game content: techtrees."); printf("\n\n \tWhere 'showfactions' is an optional parameter to display"); printf("\n\n \t factions in each techtree."); - printf("\n\n \texample: %s %s=showfactions",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_LIST_TECHTRESS]); + printf("\n\n \texample: %s %s=showfactions", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_LIST_TECHTRESS]); - printf("\n\n%s=x \tDisplay a list of game content: scenarios.",GAME_ARGS[GAME_ARG_LIST_SCENARIOS]); + printf("\n\n%s=x \tDisplay a list of game content: scenarios.", GAME_ARGS[GAME_ARG_LIST_SCENARIOS]); printf("\n\n \tWhere x is an optional name filter."); - printf("\n\n \texample: %s %s=beginner*",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_LIST_SCENARIOS]); + printf("\n\n \texample: %s %s=beginner*", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_LIST_SCENARIOS]); - printf("\n\n%s=x \tDisplay a list of game content: tilesets.",GAME_ARGS[GAME_ARG_LIST_TILESETS]); + printf("\n\n%s=x \tDisplay a list of game content: tilesets.", GAME_ARGS[GAME_ARG_LIST_TILESETS]); printf("\n\n \tWhere x is an optional name filter."); - printf("\n\n \texample: %s %s=f*",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_LIST_TILESETS]); + printf("\n\n \texample: %s %s=f*", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_LIST_TILESETS]); - printf("\n\n%s=x \tDisplay a list of game content: tutorials.",GAME_ARGS[GAME_ARG_LIST_TUTORIALS]); + printf("\n\n%s=x \tDisplay a list of game content: tutorials.", GAME_ARGS[GAME_ARG_LIST_TUTORIALS]); printf("\n\n \tWhere x is an optional name filter."); - printf("\n\n \texample: %s %s=*",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_LIST_TUTORIALS]); + printf("\n\n \texample: %s %s=*", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_LIST_TUTORIALS]); // "================================================================================" - printf("\n\n%s=x \t\tSets the game data path to x.",GAME_ARGS[GAME_ARG_DATA_PATH]); + printf("\n\n%s=x \t\tSets the game data path to x.", GAME_ARGS[GAME_ARG_DATA_PATH]); printf("\n\n \texample:"); - printf("\n\n \t%s %s=/usr/local/game_data/",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_DATA_PATH]); - printf("\n\n%s=x \t\tSets the game ini path to x.",GAME_ARGS[GAME_ARG_INI_PATH]); - printf("\n\n \texample: %s %s=~/game_config/",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_INI_PATH]); - printf("\n\n%s=x \t\tSets the game logs path to x.",GAME_ARGS[GAME_ARG_LOG_PATH]); - printf("\n\n \texample: %s %s=~/game_logs/",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_LOG_PATH]); - printf("\n\n%s=x \t\tSets the game fonts path to x.",GAME_ARGS[GAME_ARG_FONT_PATH]); - printf("\n\n \texample: %s %s=~/myfonts/",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_FONT_PATH]); + printf("\n\n \t%s %s=/usr/local/game_data/", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_DATA_PATH]); + printf("\n\n%s=x \t\tSets the game ini path to x.", GAME_ARGS[GAME_ARG_INI_PATH]); + printf("\n\n \texample: %s %s=~/game_config/", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_INI_PATH]); + printf("\n\n%s=x \t\tSets the game logs path to x.", GAME_ARGS[GAME_ARG_LOG_PATH]); + printf("\n\n \texample: %s %s=~/game_logs/", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_LOG_PATH]); + printf("\n\n%s=x \t\tSets the game fonts path to x.", GAME_ARGS[GAME_ARG_FONT_PATH]); + printf("\n\n \texample: %s %s=~/myfonts/", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_FONT_PATH]); - printf("\n\n%s=x \tDisplay merged ini settings information.",GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]); + printf("\n\n%s=x \tDisplay merged ini settings information.", GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]); printf("\n\n \tWhere x is an optional property name to filter (default"); printf("\n\n \t shows all)."); printf("\n\n \texample:"); - printf("\n\n \t%s %s=DebugMode",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]); + printf("\n\n \t%s %s=DebugMode", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]); - printf("\n\n%s=x=textureformat=keepsmallest ",GAME_ARGS[GAME_ARG_CONVERT_MODELS]); + printf("\n\n%s=x=textureformat=keepsmallest ", GAME_ARGS[GAME_ARG_CONVERT_MODELS]); printf("\n\n \tConvert a model file or folder to the current g3d version"); printf("\n\n \t format."); printf("\n\n \tWhere x is a filename or folder containing the g3d model(s)."); @@ -380,116 +380,116 @@ void printParameterHelp(const char *argv0, bool foundInvalidArgs) { printf("\n\n \t the original texture if its filesize is smaller than the"); printf("\n\n \t converted format."); printf("\n\n \texample:"); - printf("\n\n \t%s %s=techs/megapack/factions/tech/",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_CONVERT_MODELS]); + printf("\n\n \t%s %s=techs/megapack/factions/tech/", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_CONVERT_MODELS]); printf("\n\n \tunits/castle/models/castle.g3d=png=keepsmallest"); - printf("\n\n%s=x \tForce the language to be the language specified",GAME_ARGS[GAME_ARG_USE_LANGUAGE]); + printf("\n\n%s=x \tForce the language to be the language specified", GAME_ARGS[GAME_ARG_USE_LANGUAGE]); printf("\n\n \t by x. Where x is a language filename or ISO639-1 code."); - printf("\n\n \texample: %s %s=english",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_USE_LANGUAGE]); - printf("\n\n \texample: %s %s=en",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_USE_LANGUAGE]); + printf("\n\n \texample: %s %s=english", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_USE_LANGUAGE]); + printf("\n\n \texample: %s %s=en", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_USE_LANGUAGE]); - printf("\n\n%s=x \tShow the calculated CRC for the map named x.",GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]); + printf("\n\n%s=x \tShow the calculated CRC for the map named x.", GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]); printf("\n\n \tWhere x is a map name."); - printf("\n\n \texample: %s %s=four_rivers",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]); + printf("\n\n \texample: %s %s=four_rivers", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_SHOW_MAP_CRC]); - printf("\n\n%s=x \tShow the calculated CRC for the tileset named x.",GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]); + printf("\n\n%s=x \tShow the calculated CRC for the tileset named x.", GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]); printf("\n\n \tWhere x is a tileset name."); - printf("\n\n \texample: %s %s=forest",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]); + printf("\n\n \texample: %s %s=forest", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_SHOW_TILESET_CRC]); - printf("\n\n%s=x \tShow the calculated CRC for the techtree named x.",GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]); + printf("\n\n%s=x \tShow the calculated CRC for the techtree named x.", GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]); printf("\n\n \tWhere x is a techtree name."); - printf("\n\n \texample: %s %s=megapack",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]); + printf("\n\n \texample: %s %s=megapack", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_SHOW_TECHTREE_CRC]); - printf("\n\n%s=x \tShow the calculated CRC for the scenario named x.",GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]); + printf("\n\n%s=x \tShow the calculated CRC for the scenario named x.", GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]); printf("\n\n \tWhere x is a scenario name."); - printf("\n\n \texample: %s %s=storming",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]); + printf("\n\n \texample: %s %s=storming", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_SHOW_SCENARIO_CRC]); // "================================================================================" - printf("\n\n%s=x=y \tShow the calculated CRC for files in the path",GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]); + printf("\n\n%s=x=y \tShow the calculated CRC for files in the path", GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]); printf("\n\n \t located in x using file filter y."); printf("\n\n \tWhere x is a path name and y is file(s) filter."); - printf("\n\n \texample: %s %s=techs/=megapack.7z",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]); + printf("\n\n \texample: %s %s=techs/=megapack.7z", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_SHOW_PATH_CRC]); - printf("\n\n%s \tDisables stack backtrace on errors.",GAME_ARGS[GAME_ARG_DISABLE_BACKTRACE]); + printf("\n\n%s \tDisables stack backtrace on errors.", GAME_ARGS[GAME_ARG_DISABLE_BACKTRACE]); - printf("\n\n%s ",GAME_ARGS[GAME_ARG_DISABLE_SIGSEGV_HANDLER]); + printf("\n\n%s ", GAME_ARGS[GAME_ARG_DISABLE_SIGSEGV_HANDLER]); printf("\n\n \tDisables the sigsegv error handler."); - printf("\n\n%s \t\tDisables trying to use Vertex Buffer Objects.",GAME_ARGS[GAME_ARG_DISABLE_VBO]); - printf("\n\n%s ",GAME_ARGS[GAME_ARG_DISABLE_VERTEX_INTERPOLATION]); + printf("\n\n%s \t\tDisables trying to use Vertex Buffer Objects.", GAME_ARGS[GAME_ARG_DISABLE_VBO]); + printf("\n\n%s ", GAME_ARGS[GAME_ARG_DISABLE_VERTEX_INTERPOLATION]); printf("\n\n \tDisables interpolating animations to make them smoother."); - printf("\n\n%s \tDisables the sound system.",GAME_ARGS[GAME_ARG_DISABLE_SOUND]); + printf("\n\n%s \tDisables the sound system.", GAME_ARGS[GAME_ARG_DISABLE_SOUND]); - printf("\n\n%s \tEnables using the legacy font system.",GAME_ARGS[GAME_ARG_ENABLE_LEGACYFONTS]); + printf("\n\n%s \tEnables using the legacy font system.", GAME_ARGS[GAME_ARG_ENABLE_LEGACYFONTS]); // "================================================================================" - printf("\n\n%s=x \tOverride the video resolution.",GAME_ARGS[GAME_ARG_USE_RESOLUTION]); + printf("\n\n%s=x \tOverride the video resolution.", GAME_ARGS[GAME_ARG_USE_RESOLUTION]); printf("\n\n \tWhere x is a string with the following format: 'width x height'."); - printf("\n\n \texample: %s %s=1024x768",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_USE_RESOLUTION]); + printf("\n\n \texample: %s %s=1024x768", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_USE_RESOLUTION]); - printf("\n\n%s=x \t\tOverride the video colorbits.",GAME_ARGS[GAME_ARG_USE_COLORBITS]); + printf("\n\n%s=x \t\tOverride the video colorbits.", GAME_ARGS[GAME_ARG_USE_COLORBITS]); printf("\n\n \tWhere x is a valid colorbits value supported by your video"); printf("\n\n \t driver."); - printf("\n\n \texample: %s %s=32",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_USE_COLORBITS]); + printf("\n\n \texample: %s %s=32", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_USE_COLORBITS]); - printf("\n\n%s=x \t\tOverride the video depthbits.",GAME_ARGS[GAME_ARG_USE_DEPTHBITS]); + printf("\n\n%s=x \t\tOverride the video depthbits.", GAME_ARGS[GAME_ARG_USE_DEPTHBITS]); printf("\n\n \tWhere x is a valid depthbits value supported by your video"); printf("\n\n \t driver."); - printf("\n\n \texample: %s %s=24",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_USE_DEPTHBITS]); + printf("\n\n \texample: %s %s=24", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_USE_DEPTHBITS]); - printf("\n\n%s=x \tOverride the video fullscreen mode.",GAME_ARGS[GAME_ARG_USE_FULLSCREEN]); + printf("\n\n%s=x \tOverride the video fullscreen mode.", GAME_ARGS[GAME_ARG_USE_FULLSCREEN]); printf("\n\n \tWhere x either true or false."); - printf("\n\n \texample: %s %s=true",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_USE_FULLSCREEN]); + printf("\n\n \texample: %s %s=true", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_USE_FULLSCREEN]); - printf("\n\n%s=x \t\tOverride the video gamma (contrast) value.",GAME_ARGS[GAME_ARG_SET_GAMMA]); + printf("\n\n%s=x \t\tOverride the video gamma (contrast) value.", GAME_ARGS[GAME_ARG_SET_GAMMA]); printf("\n\n \tWhere x is a floating point value."); - printf("\n\n \texample: %s %s=1.5",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_SET_GAMMA]); + printf("\n\n \texample: %s %s=1.5", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_SET_GAMMA]); - printf("\n\n%s=x \t\tOverride the font to use.",GAME_ARGS[GAME_ARG_USE_FONT]); + printf("\n\n%s=x \t\tOverride the font to use.", GAME_ARGS[GAME_ARG_USE_FONT]); printf("\n\n \tWhere x is the path and name of a font file supported by"); printf("\n\n \t freetype2."); printf("\n\n \texample:"); - printf("\n\n \t%s %s=$APPLICATIONDATAPATH/data/core/fonts/Vera.ttf",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_USE_FONT]); + printf("\n\n \t%s %s=$APPLICATIONDATAPATH/data/core/fonts/Vera.ttf", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_USE_FONT]); - printf("\n\n%s=x \tOverride the font base size.",GAME_ARGS[GAME_ARG_FONT_BASESIZE]); + printf("\n\n%s=x \tOverride the font base size.", GAME_ARGS[GAME_ARG_FONT_BASESIZE]); printf("\n\n \tWhere x is the numeric base font size to use."); - printf("\n\n \texample: %s %s=5",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_FONT_BASESIZE]); + printf("\n\n \texample: %s %s=5", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_FONT_BASESIZE]); - printf("\n\n%s \tDisables video playback.",GAME_ARGS[GAME_ARG_DISABLE_VIDEOS]); + printf("\n\n%s \tDisables video playback.", GAME_ARGS[GAME_ARG_DISABLE_VIDEOS]); - printf("\n\n%s ",GAME_ARGS[GAME_ARG_DISABLE_OPENGL_CAPS_CHECK]); + printf("\n\n%s ", GAME_ARGS[GAME_ARG_DISABLE_OPENGL_CAPS_CHECK]); printf("\n\n \tDisables opengl capability checks (for corrupt or flaky video"); printf("\n\n \t drivers)."); - printf("\n\n%s=x=y ",GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]); + printf("\n\n%s=x=y ", GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]); printf("\n\n \tCompress selected game data into archives for network sharing."); printf("\n\n \tWhere x is one of the following data items to compress:"); printf("\n\n \t techtrees, tilesets or all."); printf("\n\n \tWhere y = include_main to include main (non mod) data."); - printf("\n\n \texample: %s %s=all",extractFileFromDirectoryPath(argv0).c_str(),GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]); + printf("\n\n \texample: %s %s=all", extractFileFromDirectoryPath(argv0).c_str(), GAME_ARGS[GAME_ARG_CREATE_DATA_ARCHIVES]); - printf("\n\n%s=x=y ",GAME_ARGS[GAME_ARG_STEAM]); + printf("\n\n%s=x=y ", GAME_ARGS[GAME_ARG_STEAM]); printf("\n\n \tRun with Steam Client Integration."); - printf("\n\n%s \t\tDisplays verbose information in the console.",GAME_ARGS[GAME_ARG_VERBOSE_MODE]); + printf("\n\n%s \t\tDisplays verbose information in the console.", GAME_ARGS[GAME_ARG_VERBOSE_MODE]); printf("\n\n"); } -bool hasCommandArgument(int argc, char** argv,const string argName, int *foundIndex=NULL, int startLookupIndex=1,bool useArgParamLen=false) { +bool hasCommandArgument(int argc, char** argv, const string argName, int *foundIndex = NULL, int startLookupIndex = 1, bool useArgParamLen = false) { bool result = false; - if(foundIndex != NULL) { + if (foundIndex != NULL) { *foundIndex = -1; } - int compareLen = (int)strlen(argName.c_str()); + int compareLen = (int) strlen(argName.c_str()); - for(int idx = startLookupIndex; idx < argc; idx++) { - if(useArgParamLen == true) { - compareLen = (int)strlen(argv[idx]); + for (int idx = startLookupIndex; idx < argc; idx++) { + if (useArgParamLen == true) { + compareLen = (int) strlen(argv[idx]); } - if(_strnicmp(argName.c_str(),argv[idx],compareLen) == 0) { + if (_strnicmp(argName.c_str(), argv[idx], compareLen) == 0) { result = true; - if(foundIndex != NULL) { + if (foundIndex != NULL) { *foundIndex = idx; } @@ -500,87 +500,87 @@ bool hasCommandArgument(int argc, char** argv,const string argName, int *foundIn } int mainSetup(int argc, char **argv) { - bool haveSpecialOutputCommandLineOption = false; + bool haveSpecialOutputCommandLineOption = false; - const int knownArgCount = sizeof(GAME_ARGS) / sizeof(GAME_ARGS[0]); - if(knownArgCount != GAME_ARG_END) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Internal arg count mismatch knownArgCount = %d, GAME_ARG_END = %d",knownArgCount,GAME_ARG_END); - throw megaglest_runtime_error(szBuf); - } + const int knownArgCount = sizeof(GAME_ARGS) / sizeof(GAME_ARGS[0]); + if (knownArgCount != GAME_ARG_END) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Internal arg count mismatch knownArgCount = %d, GAME_ARG_END = %d", knownArgCount, GAME_ARG_END); + throw megaglest_runtime_error(szBuf); + } - SystemFlags::VERBOSE_MODE_ENABLED = false; - if(hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERBOSE_MODE]) == true) { - SystemFlags::VERBOSE_MODE_ENABLED = true; - } + SystemFlags::VERBOSE_MODE_ENABLED = false; + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_VERBOSE_MODE]) == true) { + SystemFlags::VERBOSE_MODE_ENABLED = true; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_DISABLE_STREFLOP_CAPS_CHECK])) == false) { -// Ensure at runtime that the client has SSE + if (hasCommandArgument(argc, argv, string(GAME_ARGS[GAME_ARG_DISABLE_STREFLOP_CAPS_CHECK])) == false) { + // Ensure at runtime that the client has SSE #if defined(STREFLOP_SSE) #if defined(WIN32) - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] About to validate SSE support\n",__FILE__,__FUNCTION__,__LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] About to validate SSE support\n", __FILE__, __FUNCTION__, __LINE__); - int has_x64 = false; - int has_MMX = false; - int has_SSE = false; - int has_SSE2 = false; - int has_SSE3 = false; - int has_SSSE3 = false; - int has_SSE41 = false; - int has_SSE42 = false; - int has_SSE4a = false; - int has_AVX = false; - int has_XOP = false; - int has_FMA3 = false; - int has_FMA4 = false; + int has_x64 = false; + int has_MMX = false; + int has_SSE = false; + int has_SSE2 = false; + int has_SSE3 = false; + int has_SSSE3 = false; + int has_SSE41 = false; + int has_SSE42 = false; + int has_SSE4a = false; + int has_AVX = false; + int has_XOP = false; + int has_FMA3 = false; + int has_FMA4 = false; - int info[4]; - __cpuid(info, 0); - int nIds = info[0]; + int info[4]; + __cpuid(info, 0); + int nIds = info[0]; - __cpuid(info, 0x80000000); - int nExIds = info[0]; + __cpuid(info, 0x80000000); + int nExIds = info[0]; - // Detect Instruction Set - if (nIds >= 1){ - __cpuid(info,0x00000001); - has_MMX = (info[3] & ((int)1 << 23)) != 0; - has_SSE = (info[3] & ((int)1 << 25)) != 0; - has_SSE2 = (info[3] & ((int)1 << 26)) != 0; - has_SSE3 = (info[2] & ((int)1 << 0)) != 0; + // Detect Instruction Set + if (nIds >= 1) { + __cpuid(info, 0x00000001); + has_MMX = (info[3] & ((int) 1 << 23)) != 0; + has_SSE = (info[3] & ((int) 1 << 25)) != 0; + has_SSE2 = (info[3] & ((int) 1 << 26)) != 0; + has_SSE3 = (info[2] & ((int) 1 << 0)) != 0; - has_SSSE3 = (info[2] & ((int)1 << 9)) != 0; - has_SSE41 = (info[2] & ((int)1 << 19)) != 0; - has_SSE42 = (info[2] & ((int)1 << 20)) != 0; + has_SSSE3 = (info[2] & ((int) 1 << 9)) != 0; + has_SSE41 = (info[2] & ((int) 1 << 19)) != 0; + has_SSE42 = (info[2] & ((int) 1 << 20)) != 0; - has_AVX = (info[2] & ((int)1 << 28)) != 0; - has_FMA3 = (info[2] & ((int)1 << 12)) != 0; - } + has_AVX = (info[2] & ((int) 1 << 28)) != 0; + has_FMA3 = (info[2] & ((int) 1 << 12)) != 0; + } - if (nExIds >= 0x80000001){ - __cpuid(info,0x80000001); - has_x64 = (info[3] & ((int)1 << 29)) != 0; - has_SSE4a = (info[2] & ((int)1 << 6)) != 0; - has_FMA4 = (info[2] & ((int)1 << 16)) != 0; - has_XOP = (info[2] & ((int)1 << 11)) != 0; - } + if (nExIds >= 0x80000001) { + __cpuid(info, 0x80000001); + has_x64 = (info[3] & ((int) 1 << 29)) != 0; + has_SSE4a = (info[2] & ((int) 1 << 6)) != 0; + has_FMA4 = (info[2] & ((int) 1 << 16)) != 0; + has_XOP = (info[2] & ((int) 1 << 11)) != 0; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] sse check got [%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d]\n",__FILE__,__FUNCTION__,__LINE__,has_x64,has_MMX,has_SSE,has_SSE2,has_SSE3,has_SSSE3,has_SSE41,has_SSE42,has_SSE4a,has_AVX,has_XOP,has_FMA3,has_FMA4); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] sse check got [%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d]\n", __FILE__, __FUNCTION__, __LINE__, has_x64, has_MMX, has_SSE, has_SSE2, has_SSE3, has_SSSE3, has_SSE41, has_SSE42, has_SSE4a, has_AVX, has_XOP, has_FMA3, has_FMA4); - if( has_SSE == false && has_SSE2 == false && has_SSE3 == false && - has_SSSE3 == false && has_SSE41 == false && has_SSE42 == false && - has_SSE4a == false) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error detected, your CPU does not seem to support SSE: [%d]\n",has_SSE); - throw megaglest_runtime_error(szBuf); - } + if (has_SSE == false && has_SSE2 == false && has_SSE3 == false && + has_SSSE3 == false && has_SSE41 == false && has_SSE42 == false && + has_SSE4a == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error detected, your CPU does not seem to support SSE: [%d]\n", has_SSE); + throw megaglest_runtime_error(szBuf); + } #elif defined (__GNUC__) && !defined(__APPLE__) - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] About to validate SSE support\n",__FILE__,__FUNCTION__,__LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] About to validate SSE support\n", __FILE__, __FUNCTION__, __LINE__); #define CHECK_BIT(var,pos) ((var) & (1<<(pos))) @@ -588,80 +588,79 @@ int mainSetup(int argc, char **argv) { __asm__ __volatile__ ("cpuid":\ "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func)); - int ax=0,bx=0,cx=0,dx=0; - cpuid(0x0000001,ax,bx,cx,dx) + int ax = 0, bx = 0, cx = 0, dx = 0; + cpuid(0x0000001, ax, bx, cx, dx) - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] sse check got [%d,%d,%d,%d]\n",__FILE__,__FUNCTION__,__LINE__,ax,bx,cx,dx); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] sse check got [%d,%d,%d,%d]\n", __FILE__, __FUNCTION__, __LINE__, ax, bx, cx, dx); - // Check SSE, SSE2 and SSE3 support (if all 3 fail throw exception) - if( !CHECK_BIT(dx,25) && !CHECK_BIT(dx,26) && !CHECK_BIT(cx,0) ) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error detected, your CPU does not seem to support SSE: [%d]\n",CHECK_BIT(dx,25)); - throw megaglest_runtime_error(szBuf); - } + // Check SSE, SSE2 and SSE3 support (if all 3 fail throw exception) + if (!CHECK_BIT(dx, 25) && !CHECK_BIT(dx, 26) && !CHECK_BIT(cx, 0)) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error detected, your CPU does not seem to support SSE: [%d]\n", CHECK_BIT(dx, 25)); + throw megaglest_runtime_error(szBuf); + } #endif #endif } - if( hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_OPENGL_INFO]) == true || - hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SDL_INFO]) == true || - hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LUA_INFO]) == true || - hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_CURL_INFO]) == true || - hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_XERCES_INFO]) == true || - hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VERSION]) == true || - hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true || - hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == true || - hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == true || - hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == true || - hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true || - hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_MAPS]) == true || - hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true || - hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true || - hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true || - hasCommandArgument(argc, argv,GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true) { + if (hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_OPENGL_INFO]) == true || + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_SDL_INFO]) == true || + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_LUA_INFO]) == true || + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_CURL_INFO]) == true || + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_XERCES_INFO]) == true || + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_VERSION]) == true || + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS]) == true || + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_VALIDATE_TECHTREES]) == true || + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_VALIDATE_FACTIONS]) == true || + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_VALIDATE_SCENARIO]) == true || + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_VALIDATE_TILESET]) == true || + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_LIST_MAPS]) == true || + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_LIST_TECHTRESS]) == true || + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_LIST_SCENARIOS]) == true || + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_LIST_TILESETS]) == true || + hasCommandArgument(argc, argv, GAME_ARGS[GAME_ARG_LIST_TUTORIALS]) == true) { haveSpecialOutputCommandLineOption = true; } - if( haveSpecialOutputCommandLineOption == false) { + if (haveSpecialOutputCommandLineOption == false) { #ifdef USE_STREFLOP #define STREFLOP_NO_DENORMALS - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - streflop_init(); + streflop_init(); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); #endif } - if(hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_HELP])) == true || - hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_VERSION])) == true || - hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS])) == true || - hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true || - hasCommandArgument(argc, argv,string(GAME_ARGS[GAME_ARG_MASTERSERVER_STATUS]))) { - // Use this for masterserver mode for timers like Chrono - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if (hasCommandArgument(argc, argv, string(GAME_ARGS[GAME_ARG_HELP])) == true || + hasCommandArgument(argc, argv, string(GAME_ARGS[GAME_ARG_VERSION])) == true || + hasCommandArgument(argc, argv, string(GAME_ARGS[GAME_ARG_SHOW_INI_SETTINGS])) == true || + hasCommandArgument(argc, argv, string(GAME_ARGS[GAME_ARG_MASTERSERVER_MODE])) == true || + hasCommandArgument(argc, argv, string(GAME_ARGS[GAME_ARG_MASTERSERVER_STATUS]))) { + // Use this for masterserver mode for timers like Chrono + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - if(SDL_Init(SDL_INIT_TIMER) < 0) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - std::cerr << "Couldn't initialize SDL: " << SDL_GetError() << "\n"; - return 3; - } - } - else { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(SDL_Init(SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | \ - SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS) < 0) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if (SDL_Init(SDL_INIT_TIMER) < 0) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); std::cerr << "Couldn't initialize SDL: " << SDL_GetError() << "\n"; return 3; - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - //SDL_EnableUNICODE(1); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); + } + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | \ + SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS) < 0) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + std::cerr << "Couldn't initialize SDL: " << SDL_GetError() << "\n"; + return 3; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + //SDL_EnableUNICODE(1); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); return 0; } diff --git a/source/shared_lib/include/platform/sdl/sdl_private.h b/source/shared_lib/include/platform/sdl/sdl_private.h index e5c509257..f1bb21b01 100644 --- a/source/shared_lib/include/platform/sdl/sdl_private.h +++ b/source/shared_lib/include/platform/sdl/sdl_private.h @@ -16,13 +16,17 @@ #include "leak_dumper.h" -namespace Shared{ namespace PlatformCommon { namespace Private { +namespace Shared { + namespace PlatformCommon { + namespace Private { -extern bool shouldBeFullscreen; -extern int ScreenWidth; -extern int ScreenHeight; + extern bool shouldBeFullscreen; + extern int ScreenWidth; + extern int ScreenHeight; -}}} + } + } +} #endif diff --git a/source/shared_lib/include/platform/sdl/thread.h b/source/shared_lib/include/platform/sdl/thread.h index be3d8ab68..9e356eb65 100644 --- a/source/shared_lib/include/platform/sdl/thread.h +++ b/source/shared_lib/include/platform/sdl/thread.h @@ -38,503 +38,519 @@ using namespace std; using namespace Shared::PlatformCommon; #endif -namespace Shared { namespace PlatformCommon { -class Chrono; -}}; - -namespace Shared { namespace Platform { - -class Mutex; -//class uint32; - -enum ThreadState { - thrsNew, - thrsStarting, - thrsExecuteStart, - thrsExecuting, - thrsExecuted, - thrsExecuteAutoClean, - thrsExecuteComplete - +namespace Shared { + namespace PlatformCommon { + class Chrono; + } }; -class Thread { -public: - enum Priority { - pIdle = 0, - pLow = 1, - pNormal = 2, - pHigh = 3, - pRealTime = 4 - }; +namespace Shared { + namespace Platform { -private: - SDL_Thread* thread; - //std::auto_ptr mutexthreadAccessor; - Mutex *mutexthreadAccessor; - ThreadState currentState; - bool threadObjectValid(); + class Mutex; + //class uint32; - bool deleteAfterExecute; - static Mutex mutexthreadList; - static vector threadList; - static bool enableVerboseMode; - static unsigned long mainThreadId; + enum ThreadState { + thrsNew, + thrsStarting, + thrsExecuteStart, + thrsExecuting, + thrsExecuted, + thrsExecuteAutoClean, + thrsExecuteComplete -protected: - void addThreadToList(); - void removeThreadFromList(); - void queueAutoCleanThread(); - bool isThreadExecuteCompleteStatus(); + }; -public: - Thread(); - virtual ~Thread(); + class Thread { + public: + enum Priority { + pIdle = 0, + pLow = 1, + pNormal = 2, + pHigh = 3, + pRealTime = 4 + }; - static unsigned long getCurrentThreadId(); - static unsigned long getMainThreadId() { return mainThreadId; } - static void setMainThreadId(); - static bool isCurrentThreadMainThread(); + private: + SDL_Thread* thread; + //std::auto_ptr mutexthreadAccessor; + Mutex *mutexthreadAccessor; + ThreadState currentState; + bool threadObjectValid(); - static void setEnableVerboseMode(bool value) { enableVerboseMode = value; } - static bool getEnableVerboseMode() { return enableVerboseMode; } + bool deleteAfterExecute; + static Mutex mutexthreadList; + static vector threadList; + static bool enableVerboseMode; + static unsigned long mainThreadId; - static std::vector getThreadList(); - static void shutdownThreads(); + protected: + void addThreadToList(); + void removeThreadFromList(); + void queueAutoCleanThread(); + bool isThreadExecuteCompleteStatus(); - void setDeleteAfterExecute(bool value) { deleteAfterExecute = value; } - bool getDeleteAfterExecute() const { return deleteAfterExecute; } + public: + Thread(); + virtual ~Thread(); - void start(); - virtual void execute()=0; - void setPriority(Thread::Priority threadPriority); - void suspend(); - void resume(); - void kill(); + static unsigned long getCurrentThreadId(); + static unsigned long getMainThreadId() { + return mainThreadId; + } + static void setMainThreadId(); + static bool isCurrentThreadMainThread(); -private: - static int beginExecution(void *param); -}; - -// ===================================================== -// class Mutex -// ===================================================== - -class Mutex { -private: - - SDL_mutex* mutex; - int refCount; - string ownerId; - string deleteownerId; - - SDL_mutex* mutexAccessor; - string lastownerId; - - int maxRefCount; - Shared::PlatformCommon::Chrono *chronoPerf; - - bool isStaticMutexListMutex; - static auto_ptr mutexMutexList; - static vector mutexList; - -public: - Mutex(string ownerId=""); - ~Mutex(); - inline void setOwnerId(string ownerId) { - if(this->ownerId != ownerId) { - this->ownerId = ownerId; - } - } - inline void p() { - SDL_LockMutex(mutex); - refCount++; - } - // Returns return 0, SDL_MUTEX_TIMEDOUT, or -1 on error; - // call SDL_GetError() for more information. - inline int TryLock(int millisecondsToWait=0) { - int result = SDL_TryLockMutex(mutex); - if(result == 0) { - refCount++; - } - return result; - } - inline void v() { - refCount--; - SDL_UnlockMutex(mutex); - } - inline int getRefCount() const { return refCount; } - - inline SDL_mutex* getMutex() { return mutex; } -}; - -class MutexSafeWrapper { -protected: - Mutex *mutex; - string ownerId; -#ifdef DEBUG_PERFORMANCE_MUTEXES - Chrono chrono; -#endif - -public: - - MutexSafeWrapper(Mutex *mutex,string ownerId="") { - this->mutex = mutex; - if(this->ownerId != ownerId) { - this->ownerId = ownerId; - } - Lock(); - } - ~MutexSafeWrapper() { - ReleaseLock(); - } - - inline void setMutex(Mutex *mutex,string ownerId="") { - this->mutex = mutex; - if(this->ownerId != ownerId) { - this->ownerId = ownerId; - } - Lock(); - } - inline int setMutexAndTryLock(Mutex *mutex,string ownerId="") { - this->mutex = mutex; - if(this->ownerId != ownerId) { - this->ownerId = ownerId; - } - return this->mutex->TryLock(); - } - - inline bool isValidMutex() const { - return(this->mutex != NULL); - } - - inline void Lock() { - if(this->mutex != NULL) { - #ifdef DEBUG_MUTEXES - if(this->ownerId != "") { - printf("Locking Mutex [%s] refCount: %d\n",this->ownerId.c_str(),this->mutex->getRefCount()); - } - #endif - -#ifdef DEBUG_PERFORMANCE_MUTEXES - chrono.start(); -#endif - - this->mutex->p(); - if(this->mutex != NULL) { - this->mutex->setOwnerId(ownerId); + static void setEnableVerboseMode(bool value) { + enableVerboseMode = value; + } + static bool getEnableVerboseMode() { + return enableVerboseMode; } -#ifdef DEBUG_PERFORMANCE_MUTEXES - if(chrono.getMillis() > 5) printf("In [%s::%s Line: %d] MUTEX LOCK took msecs: %lld, this->mutex->getRefCount() = %d ownerId [%s]\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),this->mutex->getRefCount(),ownerId.c_str()); - chrono.start(); -#endif + static std::vector getThreadList(); + static void shutdownThreads(); - #ifdef DEBUG_MUTEXES - if(this->ownerId != "") { - printf("Locked Mutex [%s] refCount: %d\n",this->ownerId.c_str(),this->mutex->getRefCount()); - } - #endif - } - } - - inline int TryLock(int millisecondsToWait=0) { - if(this->mutex != NULL) { - #ifdef DEBUG_MUTEXES - if(this->ownerId != "") { - printf("TryLocking Mutex [%s] refCount: %d\n",this->ownerId.c_str(),this->mutex->getRefCount()); - } - #endif - -#ifdef DEBUG_PERFORMANCE_MUTEXES - chrono.start(); -#endif - - int result = this->mutex->TryLock(millisecondsToWait); - if(result == 0 && this->mutex != NULL) { - this->mutex->setOwnerId(ownerId); + void setDeleteAfterExecute(bool value) { + deleteAfterExecute = value; + } + bool getDeleteAfterExecute() const { + return deleteAfterExecute; } -#ifdef DEBUG_PERFORMANCE_MUTEXES - if(chrono.getMillis() > 5) printf("In [%s::%s Line: %d] MUTEX LOCK took msecs: %lld, this->mutex->getRefCount() = %d ownerId [%s]\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),this->mutex->getRefCount(),ownerId.c_str()); - chrono.start(); -#endif + void start(); + virtual void execute() = 0; + void setPriority(Thread::Priority threadPriority); + void suspend(); + void resume(); + void kill(); - #ifdef DEBUG_MUTEXES - if(this->ownerId != "") { - printf("Locked Mutex [%s] refCount: %d\n",this->ownerId.c_str(),this->mutex->getRefCount()); - } - #endif + private: + static int beginExecution(void *param); + }; - return result; - } - return 0; - } + // ===================================================== + // class Mutex + // ===================================================== - inline void ReleaseLock(bool keepMutex=false,bool deleteMutexOnRelease=false) { - if(this->mutex != NULL) { - #ifdef DEBUG_MUTEXES - if(this->ownerId != "") { - printf("UnLocking Mutex [%s] refCount: %d\n",this->ownerId.c_str(),this->mutex->getRefCount()); - } - #endif + class Mutex { + private: - this->mutex->v(); + SDL_mutex* mutex; + int refCount; + string ownerId; + string deleteownerId; -#ifdef DEBUG_PERFORMANCE_MUTEXES - if(chrono.getMillis() > 100) printf("In [%s::%s Line: %d] MUTEX UNLOCKED and held locked for msecs: %lld, this->mutex->getRefCount() = %d ownerId [%s]\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),this->mutex->getRefCount(),ownerId.c_str()); -#endif + SDL_mutex* mutexAccessor; + string lastownerId; - #ifdef DEBUG_MUTEXES - if(this->ownerId != "") { - printf("UnLocked Mutex [%s] refCount: %d\n",this->ownerId.c_str(),this->mutex->getRefCount()); - } - #endif + int maxRefCount; + Shared::PlatformCommon::Chrono *chronoPerf; - if(deleteMutexOnRelease == true) { - delete this->mutex; - this->mutex = NULL; + bool isStaticMutexListMutex; + static auto_ptr mutexMutexList; + static vector mutexList; + + public: + Mutex(string ownerId = ""); + ~Mutex(); + inline void setOwnerId(string ownerId) { + if (this->ownerId != ownerId) { + this->ownerId = ownerId; + } + } + inline void p() { + SDL_LockMutex(mutex); + refCount++; + } + // Returns return 0, SDL_MUTEX_TIMEDOUT, or -1 on error; + // call SDL_GetError() for more information. + inline int TryLock(int millisecondsToWait = 0) { + int result = SDL_TryLockMutex(mutex); + if (result == 0) { + refCount++; + } + return result; + } + inline void v() { + refCount--; + SDL_UnlockMutex(mutex); + } + inline int getRefCount() const { + return refCount; } - if(keepMutex == false) { - this->mutex = NULL; + inline SDL_mutex* getMutex() { + return mutex; } - } - } -}; - -// ===================================================== -// class Semaphore -// ===================================================== - -class Semaphore { -private: - SDL_sem* semaphore; - -public: - Semaphore(Uint32 initialValue = 0); - ~Semaphore(); - void signal(); - int waitTillSignalled(int waitMilliseconds=-1); - bool tryDecrement(); - - uint32 getSemValue(); - void resetSemValue(Uint32 initialValue); -}; - - -class ReadWriteMutex -{ -public: - ReadWriteMutex(int maxReaders = 32); - - void LockRead(); - void UnLockRead(); - - void LockWrite(); - void UnLockWrite(); - - int maxReaders(); - void setOwnerId(string ownerId) { - if(this->ownerId != ownerId) { - this->ownerId = ownerId; - } - } - -private: - Semaphore semaphore; - Mutex mutex; - int maxReadersCount; - - string ownerId; -}; - - -class ReadWriteMutexSafeWrapper { -protected: - ReadWriteMutex *mutex; - string ownerId; - bool isReadLock; + }; + class MutexSafeWrapper { + protected: + Mutex *mutex; + string ownerId; #ifdef DEBUG_PERFORMANCE_MUTEXES - Chrono chrono; + Chrono chrono; #endif -public: + public: - ReadWriteMutexSafeWrapper(ReadWriteMutex *mutex,bool isReadLock=true, string ownerId="") { - this->mutex = mutex; - if(this->isReadLock != isReadLock) { - this->isReadLock = isReadLock; - } - if(this->ownerId != ownerId) { - this->ownerId = ownerId; - } - Lock(); - } - ~ReadWriteMutexSafeWrapper() { - ReleaseLock(); - } - - void setReadWriteMutex(ReadWriteMutex *mutex,bool isReadLock=true,string ownerId="") { - this->mutex = mutex; - if(this->isReadLock != isReadLock) { - this->isReadLock = isReadLock; - } - if(this->ownerId != ownerId) { - this->ownerId = ownerId; - } - Lock(); - } - bool isValidReadWriteMutex() const { - return(this->mutex != NULL); - } - - void Lock() { - if(this->mutex != NULL) { - #ifdef DEBUG_MUTEXES - if(this->ownerId != "") { - printf("Locking Mutex [%s] refCount: %d\n",this->ownerId.c_str(),this->mutex->getRefCount()); - } - #endif - -#ifdef DEBUG_PERFORMANCE_MUTEXES - chrono.start(); -#endif - - if(this->isReadLock == true) { - this->mutex->LockRead(); - } - else { - this->mutex->LockWrite(); - } - -#ifdef DEBUG_PERFORMANCE_MUTEXES - if(chrono.getMillis() > 5) printf("In [%s::%s Line: %d] MUTEX LOCK took msecs: %lld, this->mutex->getRefCount() = %d ownerId [%s]\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),this->mutex->getRefCount(),ownerId.c_str()); - chrono.start(); -#endif - - #ifdef DEBUG_MUTEXES - if(this->ownerId != "") { - printf("Locked Mutex [%s] refCount: %d\n",this->ownerId.c_str(),this->mutex->getRefCount()); - } - #endif - } - } - void ReleaseLock(bool keepMutex=false) { - if(this->mutex != NULL) { - #ifdef DEBUG_MUTEXES - if(this->ownerId != "") { - printf("UnLocking Mutex [%s] refCount: %d\n",this->ownerId.c_str(),this->mutex->getRefCount()); - } - #endif - - if(this->isReadLock == true) { - this->mutex->UnLockRead(); - } - else { - this->mutex->UnLockWrite(); - } - -#ifdef DEBUG_PERFORMANCE_MUTEXES - if(chrono.getMillis() > 100) printf("In [%s::%s Line: %d] MUTEX UNLOCKED and held locked for msecs: %lld, this->mutex->getRefCount() = %d ownerId [%s]\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),this->mutex->getRefCount(),ownerId.c_str()); -#endif - - #ifdef DEBUG_MUTEXES - if(this->ownerId != "") { - printf("UnLocked Mutex [%s] refCount: %d\n",this->ownerId.c_str(),this->mutex->getRefCount()); - } - #endif - - if(keepMutex == false) { - this->mutex = NULL; + MutexSafeWrapper(Mutex *mutex, string ownerId = "") { + this->mutex = mutex; + if (this->ownerId != ownerId) { + this->ownerId = ownerId; + } + Lock(); } - } + ~MutexSafeWrapper() { + ReleaseLock(); + } + + inline void setMutex(Mutex *mutex, string ownerId = "") { + this->mutex = mutex; + if (this->ownerId != ownerId) { + this->ownerId = ownerId; + } + Lock(); + } + inline int setMutexAndTryLock(Mutex *mutex, string ownerId = "") { + this->mutex = mutex; + if (this->ownerId != ownerId) { + this->ownerId = ownerId; + } + return this->mutex->TryLock(); + } + + inline bool isValidMutex() const { + return(this->mutex != NULL); + } + + inline void Lock() { + if (this->mutex != NULL) { +#ifdef DEBUG_MUTEXES + if (this->ownerId != "") { + printf("Locking Mutex [%s] refCount: %d\n", this->ownerId.c_str(), this->mutex->getRefCount()); + } +#endif + +#ifdef DEBUG_PERFORMANCE_MUTEXES + chrono.start(); +#endif + + this->mutex->p(); + if (this->mutex != NULL) { + this->mutex->setOwnerId(ownerId); + } + +#ifdef DEBUG_PERFORMANCE_MUTEXES + if (chrono.getMillis() > 5) printf("In [%s::%s Line: %d] MUTEX LOCK took msecs: %lld, this->mutex->getRefCount() = %d ownerId [%s]\n", __FILE__, __FUNCTION__, __LINE__, (long long int)chrono.getMillis(), this->mutex->getRefCount(), ownerId.c_str()); + chrono.start(); +#endif + +#ifdef DEBUG_MUTEXES + if (this->ownerId != "") { + printf("Locked Mutex [%s] refCount: %d\n", this->ownerId.c_str(), this->mutex->getRefCount()); + } +#endif + } + } + + inline int TryLock(int millisecondsToWait = 0) { + if (this->mutex != NULL) { +#ifdef DEBUG_MUTEXES + if (this->ownerId != "") { + printf("TryLocking Mutex [%s] refCount: %d\n", this->ownerId.c_str(), this->mutex->getRefCount()); + } +#endif + +#ifdef DEBUG_PERFORMANCE_MUTEXES + chrono.start(); +#endif + + int result = this->mutex->TryLock(millisecondsToWait); + if (result == 0 && this->mutex != NULL) { + this->mutex->setOwnerId(ownerId); + } + +#ifdef DEBUG_PERFORMANCE_MUTEXES + if (chrono.getMillis() > 5) printf("In [%s::%s Line: %d] MUTEX LOCK took msecs: %lld, this->mutex->getRefCount() = %d ownerId [%s]\n", __FILE__, __FUNCTION__, __LINE__, (long long int)chrono.getMillis(), this->mutex->getRefCount(), ownerId.c_str()); + chrono.start(); +#endif + +#ifdef DEBUG_MUTEXES + if (this->ownerId != "") { + printf("Locked Mutex [%s] refCount: %d\n", this->ownerId.c_str(), this->mutex->getRefCount()); + } +#endif + + return result; + } + return 0; + } + + inline void ReleaseLock(bool keepMutex = false, bool deleteMutexOnRelease = false) { + if (this->mutex != NULL) { +#ifdef DEBUG_MUTEXES + if (this->ownerId != "") { + printf("UnLocking Mutex [%s] refCount: %d\n", this->ownerId.c_str(), this->mutex->getRefCount()); + } +#endif + + this->mutex->v(); + +#ifdef DEBUG_PERFORMANCE_MUTEXES + if (chrono.getMillis() > 100) printf("In [%s::%s Line: %d] MUTEX UNLOCKED and held locked for msecs: %lld, this->mutex->getRefCount() = %d ownerId [%s]\n", __FILE__, __FUNCTION__, __LINE__, (long long int)chrono.getMillis(), this->mutex->getRefCount(), ownerId.c_str()); +#endif + +#ifdef DEBUG_MUTEXES + if (this->ownerId != "") { + printf("UnLocked Mutex [%s] refCount: %d\n", this->ownerId.c_str(), this->mutex->getRefCount()); + } +#endif + + if (deleteMutexOnRelease == true) { + delete this->mutex; + this->mutex = NULL; + } + + if (keepMutex == false) { + this->mutex = NULL; + } + } + } + }; + + // ===================================================== + // class Semaphore + // ===================================================== + + class Semaphore { + private: + SDL_sem* semaphore; + + public: + Semaphore(Uint32 initialValue = 0); + ~Semaphore(); + void signal(); + int waitTillSignalled(int waitMilliseconds = -1); + bool tryDecrement(); + + uint32 getSemValue(); + void resetSemValue(Uint32 initialValue); + }; + + + class ReadWriteMutex { + public: + ReadWriteMutex(int maxReaders = 32); + + void LockRead(); + void UnLockRead(); + + void LockWrite(); + void UnLockWrite(); + + int maxReaders(); + void setOwnerId(string ownerId) { + if (this->ownerId != ownerId) { + this->ownerId = ownerId; + } + } + + private: + Semaphore semaphore; + Mutex mutex; + int maxReadersCount; + + string ownerId; + }; + + + class ReadWriteMutexSafeWrapper { + protected: + ReadWriteMutex *mutex; + string ownerId; + bool isReadLock; + +#ifdef DEBUG_PERFORMANCE_MUTEXES + Chrono chrono; +#endif + + public: + + ReadWriteMutexSafeWrapper(ReadWriteMutex *mutex, bool isReadLock = true, string ownerId = "") { + this->mutex = mutex; + if (this->isReadLock != isReadLock) { + this->isReadLock = isReadLock; + } + if (this->ownerId != ownerId) { + this->ownerId = ownerId; + } + Lock(); + } + ~ReadWriteMutexSafeWrapper() { + ReleaseLock(); + } + + void setReadWriteMutex(ReadWriteMutex *mutex, bool isReadLock = true, string ownerId = "") { + this->mutex = mutex; + if (this->isReadLock != isReadLock) { + this->isReadLock = isReadLock; + } + if (this->ownerId != ownerId) { + this->ownerId = ownerId; + } + Lock(); + } + bool isValidReadWriteMutex() const { + return(this->mutex != NULL); + } + + void Lock() { + if (this->mutex != NULL) { +#ifdef DEBUG_MUTEXES + if (this->ownerId != "") { + printf("Locking Mutex [%s] refCount: %d\n", this->ownerId.c_str(), this->mutex->getRefCount()); + } +#endif + +#ifdef DEBUG_PERFORMANCE_MUTEXES + chrono.start(); +#endif + + if (this->isReadLock == true) { + this->mutex->LockRead(); + } else { + this->mutex->LockWrite(); + } + +#ifdef DEBUG_PERFORMANCE_MUTEXES + if (chrono.getMillis() > 5) printf("In [%s::%s Line: %d] MUTEX LOCK took msecs: %lld, this->mutex->getRefCount() = %d ownerId [%s]\n", __FILE__, __FUNCTION__, __LINE__, (long long int)chrono.getMillis(), this->mutex->getRefCount(), ownerId.c_str()); + chrono.start(); +#endif + +#ifdef DEBUG_MUTEXES + if (this->ownerId != "") { + printf("Locked Mutex [%s] refCount: %d\n", this->ownerId.c_str(), this->mutex->getRefCount()); + } +#endif + } + } + void ReleaseLock(bool keepMutex = false) { + if (this->mutex != NULL) { +#ifdef DEBUG_MUTEXES + if (this->ownerId != "") { + printf("UnLocking Mutex [%s] refCount: %d\n", this->ownerId.c_str(), this->mutex->getRefCount()); + } +#endif + + if (this->isReadLock == true) { + this->mutex->UnLockRead(); + } else { + this->mutex->UnLockWrite(); + } + +#ifdef DEBUG_PERFORMANCE_MUTEXES + if (chrono.getMillis() > 100) printf("In [%s::%s Line: %d] MUTEX UNLOCKED and held locked for msecs: %lld, this->mutex->getRefCount() = %d ownerId [%s]\n", __FILE__, __FUNCTION__, __LINE__, (long long int)chrono.getMillis(), this->mutex->getRefCount(), ownerId.c_str()); +#endif + +#ifdef DEBUG_MUTEXES + if (this->ownerId != "") { + printf("UnLocked Mutex [%s] refCount: %d\n", this->ownerId.c_str(), this->mutex->getRefCount()); + } +#endif + + if (keepMutex == false) { + this->mutex = NULL; + } + } + } + }; + + const bool debugMasterSlaveThreadController = false; + // ===================================================== + // class Trigger + // ===================================================== + + class Trigger { + private: + SDL_cond* trigger; + Mutex *mutex; + + public: + Trigger(Mutex *mutex); + ~Trigger(); + void signal(bool allThreads = false); + int waitTillSignalled(Mutex *mutex, int waitMilliseconds = -1); + }; + + class MasterSlaveThreadController; + + class SlaveThreadControllerInterface { + public: + virtual void setMasterController(MasterSlaveThreadController *master) = 0; + virtual void signalSlave(void *userdata) = 0; + virtual ~SlaveThreadControllerInterface() { + } + }; + + class MasterSlaveThreadController { + private: + static const int triggerBaseCount = 1; + + Mutex *mutex; + Semaphore *slaveTriggerSem; + int slaveTriggerCounter; + + std::vector slaveThreadList; + + void init(std::vector &newSlaveThreadList); + public: + + MasterSlaveThreadController(); + MasterSlaveThreadController(std::vector &slaveThreadList); + ~MasterSlaveThreadController(); + + void setSlaves(std::vector &slaveThreadList); + void clearSlaves(bool clearListOnly = false); + + void signalSlaves(void *userdata); + void triggerMaster(int waitMilliseconds = -1); + bool waitTillSlavesTrigger(int waitMilliseconds = -1); + + }; + + class MasterSlaveThreadControllerSafeWrapper { + protected: + MasterSlaveThreadController *master; + string ownerId; + int waitMilliseconds; + + public: + + MasterSlaveThreadControllerSafeWrapper(MasterSlaveThreadController *master, int waitMilliseconds = -1, string ownerId = "") { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + this->master = master; + this->waitMilliseconds = waitMilliseconds; + this->ownerId = ownerId; + + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + ~MasterSlaveThreadControllerSafeWrapper() { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (master != NULL) { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + master->triggerMaster(this->waitMilliseconds); + } + + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + }; + } -}; - -const bool debugMasterSlaveThreadController = false; -// ===================================================== -// class Trigger -// ===================================================== - -class Trigger { -private: - SDL_cond* trigger; - Mutex *mutex; - -public: - Trigger(Mutex *mutex); - ~Trigger(); - void signal(bool allThreads=false); - int waitTillSignalled(Mutex *mutex, int waitMilliseconds=-1); -}; - -class MasterSlaveThreadController; - -class SlaveThreadControllerInterface { -public: - virtual void setMasterController(MasterSlaveThreadController *master) = 0; - virtual void signalSlave(void *userdata) = 0; - virtual ~SlaveThreadControllerInterface() {} -}; - -class MasterSlaveThreadController { -private: - static const int triggerBaseCount = 1; - - Mutex *mutex; - Semaphore *slaveTriggerSem; - int slaveTriggerCounter; - - std::vector slaveThreadList; - - void init(std::vector &newSlaveThreadList); -public: - - MasterSlaveThreadController(); - MasterSlaveThreadController(std::vector &slaveThreadList); - ~MasterSlaveThreadController(); - - void setSlaves(std::vector &slaveThreadList); - void clearSlaves(bool clearListOnly=false); - - void signalSlaves(void *userdata); - void triggerMaster(int waitMilliseconds=-1); - bool waitTillSlavesTrigger(int waitMilliseconds=-1); - -}; - -class MasterSlaveThreadControllerSafeWrapper { -protected: - MasterSlaveThreadController *master; - string ownerId; - int waitMilliseconds; - -public: - - MasterSlaveThreadControllerSafeWrapper(MasterSlaveThreadController *master, int waitMilliseconds=-1, string ownerId="") { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - this->master = master; - this->waitMilliseconds = waitMilliseconds; - this->ownerId = ownerId; - - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - ~MasterSlaveThreadControllerSafeWrapper() { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(master != NULL) { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - master->triggerMaster(this->waitMilliseconds); - } - - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } -}; - -}}//end namespace +}//end namespace #endif diff --git a/source/shared_lib/include/platform/sdl/window.h b/source/shared_lib/include/platform/sdl/window.h index 0945616d6..5d4bad2df 100644 --- a/source/shared_lib/include/platform/sdl/window.h +++ b/source/shared_lib/include/platform/sdl/window.h @@ -33,217 +33,290 @@ typedef SDL_Keysym SDL_keysym; #endif -namespace Shared{ namespace Platform{ +namespace Shared { + namespace Platform { -class Timer; -//class PlatformContextGl; + class Timer; + //class PlatformContextGl; -enum MouseButton { - mbUnknown, - mbLeft, - mbCenter, - mbRight, - mbButtonX1, - mbButtonX2, + enum MouseButton { + mbUnknown, + mbLeft, + mbCenter, + mbRight, + mbButtonX1, + mbButtonX2, - mbCount -}; + mbCount + }; -enum SizeState{ - ssMaximized, - ssMinimized, - ssRestored -}; + enum SizeState { + ssMaximized, + ssMinimized, + ssRestored + }; -class MouseState { -private: - bool states[mbCount]; + class MouseState { + private: + bool states[mbCount]; -public: - MouseState() { - clear(); + public: + MouseState() { + clear(); + } + //MouseState(const MouseState &); + //MouseState &operator=(const MouseState &); + void clear() { + memset(this, 0, sizeof(MouseState)); + } + + bool get(MouseButton b) const { + if (b > 0 && b < mbCount) { + return states[b]; + } + return false; + } + + void set(MouseButton b, bool state) { + if (b > 0 && b < mbCount) { + states[b] = state; + } + } + }; + + enum WindowStyle { + wsFullscreen, + wsWindowedFixed, + wsWindowedResizable + }; + + // ===================================================== + // class Window + // ===================================================== + + class Window { + private: + static SDL_Window *sdlWindow; + Uint32 lastMouseDown[mbCount]; + int lastMouseX[mbCount]; + int lastMouseY[mbCount]; + + static int64 lastMouseEvent; /** for use in mouse hover calculations */ + static MouseState mouseState; + static Vec2i mousePos; + static bool isKeyPressedDown; + static bool isFullScreen; + static SDL_keysym keystate; + static bool tryVSynch; + static int64 lastToggle; + + static void setLastToggle(int64 lastToggle) { + Window::lastToggle = lastToggle; + } + static int64 getLastToggle() { + return Window::lastToggle; + } + + static void setLastMouseEvent(int64 lastMouseEvent) { + Window::lastMouseEvent = lastMouseEvent; + } + static int64 getLastMouseEvent() { + return Window::lastMouseEvent; + } + + static const MouseState &getMouseState() { + return Window::mouseState; + } + static void setMouseState(MouseButton b, bool state) { + Window::mouseState.set(b, state); + } + + static const Vec2i &getMousePos() { + return Window::mousePos; + } + static void setMousePos(const Vec2i &mousePos) { + Window::mousePos = mousePos; + } + + static void setKeystate(SDL_keysym state) { + keystate = state; + } + + //static bool masterserverMode; + static map mapAllowedKeys; + + protected: + //int w, h; + static bool isActive; + static bool allowAltEnterFullscreenToggle; + static int lastShowMouseState; + + public: + static SDL_Window *getSDLWindow(); + static bool handleEvent(); + static void revertMousePos(); + static Vec2i getOldMousePos(); + static bool isKeyDown() { + return isKeyPressedDown; + } + static void setupGraphicsScreen(int depthBits = -1, int stencilBits = -1, bool hardware_acceleration = false, bool fullscreen_anti_aliasing = false); + static const bool getIsFullScreen() { + return isFullScreen; + } + static void setIsFullScreen(bool value) { + isFullScreen = value; + } + //static SDL_keysym getKeystate() { return keystate; } + static bool isKeyStateModPressed(int mod); + static wchar_t extractLastKeyPressed(); + + Window(); + Window(SDL_Window *sdlWindow); + virtual ~Window(); + + static void addAllowedKeys(string keyList); + static void clearAllowedKeys(); + static bool isAllowedKey(wchar_t key); + + virtual int getScreenWidth() = 0; + virtual int getScreenHeight() = 0; + + virtual bool ChangeVideoMode(bool preserveContext, int resWidth, int resHeight, + bool fullscreenWindow, int colorBits, int depthBits, int stencilBits, + bool hardware_acceleration, bool fullscreen_anti_aliasing, + float gammaValue) = 0; + //static void setMasterserverMode(bool value) { Window::masterserverMode = value;} + //static bool getMasterserverMode() { return Window::masterserverMode;} + + static bool getTryVSynch() { + return tryVSynch; + } + static void setTryVSynch(bool value) { + tryVSynch = value; + } + + WindowHandle getHandle() { + return 0; + } + string getText(); + int getX() { + return 0; + } + int getY() { + return 0; + } + int getW() { + return getScreenWidth(); + } + int getH() { + return getScreenHeight(); + } + + //component state + int getClientW() { + return getW(); + } + int getClientH() { + return getH(); + } + float getAspect(); + + //object state + void setText(string text); + void setStyle(WindowStyle windowStyle); + void setSize(int w, int h); + void setPos(int x, int y); + void setEnabled(bool enabled); + void setVisible(bool visible); + + //misc + void create(); + void destroy(); + void minimize(); + + static void setAllowAltEnterFullscreenToggle(bool value) { + allowAltEnterFullscreenToggle = value; + } + static bool getAllowAltEnterFullscreenToggle() { + return allowAltEnterFullscreenToggle; + } + + static char getRawKey(SDL_keysym keysym); + + protected: + + void setSDLWindow(SDL_Window *window); + + virtual void eventCreate() { + } + virtual void eventMouseDown(int x, int y, MouseButton mouseButton) { + } + virtual void eventMouseUp(int x, int y, MouseButton mouseButton) { + } + virtual void eventMouseMove(int x, int y, const MouseState* mouseState) { + } + virtual void eventMouseDoubleClick(int x, int y, MouseButton mouseButton) { + } + virtual void eventMouseWheel(int x, int y, int zDelta) { + } + virtual void eventKeyDown(SDL_KeyboardEvent key) { + } + virtual void eventKeyUp(SDL_KeyboardEvent key) { + } + virtual void eventKeyPress(SDL_KeyboardEvent c) { + } + virtual bool eventTextInput(std::string text) { + return false; + } + virtual bool eventSdlKeyDown(SDL_KeyboardEvent key) { + return false; + } + virtual void eventResize() { + }; + virtual void eventPaint() { + } + virtual void eventTimer(int timerId) { + } + virtual void eventActivate(bool activated) { + }; + virtual void eventResize(SizeState sizeState) { + }; + virtual void eventMenu(int menuId) { + } + virtual void eventClose() { + }; + virtual void eventDestroy() { + }; + virtual void eventToggleFullScreen(bool isFullscreen) { + }; + virtual void eventWindowEvent(SDL_WindowEvent event) { + } + + private: + /// needed to detect double clicks + void handleMouseDown(SDL_Event event); + void handleMouseWheel(SDL_Event event); + + static MouseButton getMouseButton(int sdlButton); + //static char getKey(SDL_keysym keysym, bool skipSpecialKeys=false); + //static char getNormalKey(SDL_keysym keysym,bool skipSpecialKeys=false); + static void toggleFullscreen(); + + static wchar_t convertStringtoSDLKey(const string &value); + }; + + bool isKeyPressed(SDL_Keycode compareKey, SDL_KeyboardEvent input, vector modifiersToCheck); + bool isKeyPressed(SDL_Keycode compareKey, SDL_KeyboardEvent input, bool modifiersAllowed = true); + + SDL_Keycode extractKeyPressed(SDL_KeyboardEvent input); + //bool isAllowedInputTextKey(SDL_Keycode key); + + //wchar_t extractKeyPressedUnicode(SDL_KeyboardEvent input); + vector extractKeyPressedUnicodeLength(string text); + bool isAllowedInputTextKey(wchar_t &key); + } - //MouseState(const MouseState &); - //MouseState &operator=(const MouseState &); - void clear() { memset(this, 0, sizeof(MouseState)); } - - bool get(MouseButton b) const { - if(b > 0 && b < mbCount) { - return states[b]; - } - return false; - } - - void set(MouseButton b, bool state) { - if(b > 0 && b < mbCount) { - states[b] = state; - } - } -}; - -enum WindowStyle{ - wsFullscreen, - wsWindowedFixed, - wsWindowedResizable -}; - -// ===================================================== -// class Window -// ===================================================== - -class Window { -private: - static SDL_Window *sdlWindow; - Uint32 lastMouseDown[mbCount]; - int lastMouseX[mbCount]; - int lastMouseY[mbCount]; - - static int64 lastMouseEvent; /** for use in mouse hover calculations */ - static MouseState mouseState; - static Vec2i mousePos; - static bool isKeyPressedDown; - static bool isFullScreen; - static SDL_keysym keystate; - static bool tryVSynch; - static int64 lastToggle ; - - static void setLastToggle(int64 lastToggle) {Window::lastToggle = lastToggle;} - static int64 getLastToggle() {return Window::lastToggle;} - - static void setLastMouseEvent(int64 lastMouseEvent) {Window::lastMouseEvent = lastMouseEvent;} - static int64 getLastMouseEvent() {return Window::lastMouseEvent;} - - static const MouseState &getMouseState() {return Window::mouseState;} - static void setMouseState(MouseButton b, bool state) {Window::mouseState.set(b, state);} - - static const Vec2i &getMousePos() {return Window::mousePos;} - static void setMousePos(const Vec2i &mousePos) {Window::mousePos = mousePos;} - - static void setKeystate(SDL_keysym state) { keystate = state; } - - //static bool masterserverMode; - static map mapAllowedKeys; - -protected: - //int w, h; - static bool isActive; - static bool allowAltEnterFullscreenToggle; - static int lastShowMouseState; - -public: - static SDL_Window *getSDLWindow(); - static bool handleEvent(); - static void revertMousePos(); - static Vec2i getOldMousePos(); - static bool isKeyDown() { return isKeyPressedDown; } - static void setupGraphicsScreen(int depthBits=-1, int stencilBits=-1, bool hardware_acceleration=false, bool fullscreen_anti_aliasing=false); - static const bool getIsFullScreen() { return isFullScreen; } - static void setIsFullScreen(bool value) { isFullScreen = value; } - //static SDL_keysym getKeystate() { return keystate; } - static bool isKeyStateModPressed(int mod); - static wchar_t extractLastKeyPressed(); - - Window(); - Window(SDL_Window *sdlWindow); - virtual ~Window(); - - static void addAllowedKeys(string keyList); - static void clearAllowedKeys(); - static bool isAllowedKey(wchar_t key); - - virtual int getScreenWidth() = 0; - virtual int getScreenHeight() = 0; - - virtual bool ChangeVideoMode(bool preserveContext,int resWidth, int resHeight, - bool fullscreenWindow, int colorBits, int depthBits, int stencilBits, - bool hardware_acceleration, bool fullscreen_anti_aliasing, - float gammaValue) = 0; - //static void setMasterserverMode(bool value) { Window::masterserverMode = value;} - //static bool getMasterserverMode() { return Window::masterserverMode;} - - static bool getTryVSynch() { return tryVSynch; } - static void setTryVSynch(bool value) { tryVSynch = value; } - - WindowHandle getHandle() {return 0;} - string getText(); - int getX() { return 0; } - int getY() { return 0; } - int getW() { return getScreenWidth(); } - int getH() { return getScreenHeight(); } - - //component state - int getClientW() { return getW(); } - int getClientH() { return getH(); } - float getAspect(); - - //object state - void setText(string text); - void setStyle(WindowStyle windowStyle); - void setSize(int w, int h); - void setPos(int x, int y); - void setEnabled(bool enabled); - void setVisible(bool visible); - - //misc - void create(); - void destroy(); - void minimize(); - - static void setAllowAltEnterFullscreenToggle(bool value) { allowAltEnterFullscreenToggle = value; } - static bool getAllowAltEnterFullscreenToggle() { return allowAltEnterFullscreenToggle; } - - static char getRawKey(SDL_keysym keysym); - -protected: - - void setSDLWindow(SDL_Window *window); - - virtual void eventCreate(){} - virtual void eventMouseDown(int x, int y, MouseButton mouseButton){} - virtual void eventMouseUp(int x, int y, MouseButton mouseButton){} - virtual void eventMouseMove(int x, int y, const MouseState* mouseState){} - virtual void eventMouseDoubleClick(int x, int y, MouseButton mouseButton){} - virtual void eventMouseWheel(int x, int y, int zDelta) {} - virtual void eventKeyDown(SDL_KeyboardEvent key) {} - virtual void eventKeyUp(SDL_KeyboardEvent key) {} - virtual void eventKeyPress(SDL_KeyboardEvent c) {} - virtual bool eventTextInput(std::string text) { return false; } - virtual bool eventSdlKeyDown(SDL_KeyboardEvent key) { return false; } - virtual void eventResize() {}; - virtual void eventPaint() {} - virtual void eventTimer(int timerId) {} - virtual void eventActivate(bool activated) {}; - virtual void eventResize(SizeState sizeState) {}; - virtual void eventMenu(int menuId) {} - virtual void eventClose() {}; - virtual void eventDestroy() {}; - virtual void eventToggleFullScreen(bool isFullscreen) {}; - virtual void eventWindowEvent(SDL_WindowEvent event) {} - -private: - /// needed to detect double clicks - void handleMouseDown(SDL_Event event); - void handleMouseWheel(SDL_Event event); - - static MouseButton getMouseButton(int sdlButton); - //static char getKey(SDL_keysym keysym, bool skipSpecialKeys=false); - //static char getNormalKey(SDL_keysym keysym,bool skipSpecialKeys=false); - static void toggleFullscreen(); - - static wchar_t convertStringtoSDLKey(const string &value); -}; - -bool isKeyPressed(SDL_Keycode compareKey, SDL_KeyboardEvent input, vector modifiersToCheck); -bool isKeyPressed(SDL_Keycode compareKey, SDL_KeyboardEvent input, bool modifiersAllowed=true); - -SDL_Keycode extractKeyPressed(SDL_KeyboardEvent input); -//bool isAllowedInputTextKey(SDL_Keycode key); - -//wchar_t extractKeyPressedUnicode(SDL_KeyboardEvent input); -vector extractKeyPressedUnicodeLength(string text); -bool isAllowedInputTextKey(wchar_t &key); - -}}//end namespace +}//end namespace #endif diff --git a/source/shared_lib/include/platform/sdl/window_gl.h b/source/shared_lib/include/platform/sdl/window_gl.h index 260408ec8..84cf25c7f 100644 --- a/source/shared_lib/include/platform/sdl/window_gl.h +++ b/source/shared_lib/include/platform/sdl/window_gl.h @@ -18,45 +18,51 @@ using Shared::Graphics::Gl::ContextGl; -namespace Shared{ namespace Platform{ +namespace Shared { + namespace Platform { -// ===================================================== -// class WindowGl -// ===================================================== + // ===================================================== + // class WindowGl + // ===================================================== -class WindowGl: public Window { -private: - ContextGl context; + class WindowGl : public Window { + private: + ContextGl context; - static void setGamma(SDL_Window *window,float gammaValue); -public: - WindowGl(); - WindowGl(SDL_Window *sdlWindow); - virtual ~WindowGl(); + static void setGamma(SDL_Window *window, float gammaValue); + public: + WindowGl(); + WindowGl(SDL_Window *sdlWindow); + virtual ~WindowGl(); - void initGl(int colorBits, int depthBits, int stencilBits, - bool hardware_acceleration, bool fullscreen_anti_aliasing, - float gammaValue); - void makeCurrentGl(); - void swapBuffersGl(); - void setGamma(float gammaValue); + void initGl(int colorBits, int depthBits, int stencilBits, + bool hardware_acceleration, bool fullscreen_anti_aliasing, + float gammaValue); + void makeCurrentGl(); + void swapBuffersGl(); + void setGamma(float gammaValue); - SDL_Window * getScreenWindow(); - SDL_Surface * getScreenSurface(); - virtual int getScreenWidth(); - virtual int getScreenHeight(); - virtual int getDesiredScreenWidth() { return getScreenWidth(); } - virtual int getDesiredScreenHeight() { return getScreenHeight(); } + SDL_Window * getScreenWindow(); + SDL_Surface * getScreenSurface(); + virtual int getScreenWidth(); + virtual int getScreenHeight(); + virtual int getDesiredScreenWidth() { + return getScreenWidth(); + } + virtual int getDesiredScreenHeight() { + return getScreenHeight(); + } - virtual bool ChangeVideoMode(bool preserveContext, int resWidth, int resHeight, - bool fullscreenWindow, int colorBits, int depthBits, int stencilBits, - bool hardware_acceleration, bool fullscreen_anti_aliasing, - float gammaValue); + virtual bool ChangeVideoMode(bool preserveContext, int resWidth, int resHeight, + bool fullscreenWindow, int colorBits, int depthBits, int stencilBits, + bool hardware_acceleration, bool fullscreen_anti_aliasing, + float gammaValue); -protected: - virtual void eventToggleFullScreen(bool isFullscreen); -}; + protected: + virtual void eventToggleFullScreen(bool isFullscreen); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/platform/win32/glob.h b/source/shared_lib/include/platform/win32/glob.h index 2f9309ac4..1ef3324af 100644 --- a/source/shared_lib/include/platform/win32/glob.h +++ b/source/shared_lib/include/platform/win32/glob.h @@ -39,29 +39,29 @@ * ////////////////////////////////////////////////////////////////////// */ -/** \file glob.h - * - * Contains the declarations for the glob() API. - */ + /** \file glob.h + * + * Contains the declarations for the glob() API. + */ #ifndef SYNSOFT_UNIXEM_INCL_H_GLOB #define SYNSOFT_UNIXEM_INCL_H_GLOB #include "leak_dumper.h" -/* ////////////////////////////////////////////////////////////////////// */ + /* ////////////////////////////////////////////////////////////////////// */ -/** \weakgroup unixem Synesis Software UNIX Emulation for Win32 - * \brief The UNIX emulation library - */ + /** \weakgroup unixem Synesis Software UNIX Emulation for Win32 + * \brief The UNIX emulation library + */ -/** \weakgroup unixem_glob glob() API - * \ingroup UNIXem unixem - * \brief This API provides facilities for enumerating the file-system contents - * @{ - */ + /** \weakgroup unixem_glob glob() API + * \ingroup UNIXem unixem + * \brief This API provides facilities for enumerating the file-system contents + * @{ + */ -/* ////////////////////////////////////////////////////////////////////// */ + /* ////////////////////////////////////////////////////////////////////// */ #ifndef _WIN32 # error This file is only currently defined for compilation on Win32 systems @@ -71,7 +71,7 @@ * Constants and definitions */ -/* Error codes */ + /* Error codes */ #define GLOB_NOSPACE (1) /*!< \brief (Error result code:) An attempt to allocate memory failed, or if errno was 0 GLOB_LIMIT was specified in the flags and ARG_MAX patterns were matched. */ #define GLOB_ABORTED (2) /*!< \brief (Error result code:) The scan was stopped because an error was encountered and either GLOB_ERR was set or (*errfunc)() returned non-zero. */ #define GLOB_NOMATCH (3) /*!< \brief (Error result code:) The pattern does not match any existing pathname, and GLOB_NOCHECK was not set int flags. */ @@ -103,17 +103,16 @@ * Typedefs */ -/** \brief Result structure for glob() - * - * This structure is used by glob() to return the results of the search. - */ -typedef struct -{ - int gl_pathc; /*!< count of total paths so far */ - int gl_matchc; /*!< count of paths matching pattern */ - int gl_offs; /*!< reserved at beginning of gl_pathv */ - int gl_flags; /*!< returned flags */ - char **gl_pathv; /*!< list of paths matching pattern */ + /** \brief Result structure for glob() + * + * This structure is used by glob() to return the results of the search. + */ +typedef struct { + int gl_pathc; /*!< count of total paths so far */ + int gl_matchc; /*!< count of paths matching pattern */ + int gl_offs; /*!< reserved at beginning of gl_pathv */ + int gl_flags; /*!< returned flags */ + char **gl_pathv; /*!< list of paths matching pattern */ } glob_t; /* ///////////////////////////////////////////////////////////////////////// @@ -124,34 +123,34 @@ typedef struct extern "C" { #endif /* __cplusplus */ -/** \brief Generates pathnames matching a pattern - * - * This function is a pathname generator that implements the rules for - * file name pattern matching used by the UNIX shell. - * - * \param pattern The pattern controlling the search - * \param flags A combination of the GLOB_* flags - * \param errfunc A function that is called each time part of the search processing fails - * \param pglob Pointer to a glob_t structure to receive the search results - * \return 0 on success, otherwise one of the GLOB_* error codes - */ -int glob( char const *pattern - , int flags + /** \brief Generates pathnames matching a pattern + * + * This function is a pathname generator that implements the rules for + * file name pattern matching used by the UNIX shell. + * + * \param pattern The pattern controlling the search + * \param flags A combination of the GLOB_* flags + * \param errfunc A function that is called each time part of the search processing fails + * \param pglob Pointer to a glob_t structure to receive the search results + * \return 0 on success, otherwise one of the GLOB_* error codes + */ + int glob(char const *pattern + , int flags #if defined(__COMO__) - , int (*errfunc)(char const *, int) + , int(*errfunc)(char const *, int) #else /* ? compiler */ - , const int (*errfunc)(char const *, int) + , const int(*errfunc)(char const *, int) #endif /* compiler */ - , glob_t *pglob); + , glob_t *pglob); -/** \brief Frees the results of a call to glob - * - * This function releases any memory allocated in a call to glob. It must - * always be called for a successful call to glob. - * - * \param pglob Pointer to a glob_t structure to receive the search results - */ -void globfree(glob_t *pglob); + /** \brief Frees the results of a call to glob + * + * This function releases any memory allocated in a call to glob. It must + * always be called for a successful call to glob. + * + * \param pglob Pointer to a glob_t structure to receive the search results + */ + void globfree(glob_t *pglob); #ifdef __cplusplus } diff --git a/source/shared_lib/include/platform/win32/platform_definitions.h b/source/shared_lib/include/platform/win32/platform_definitions.h index 79a888071..cb4e39676 100644 --- a/source/shared_lib/include/platform/win32/platform_definitions.h +++ b/source/shared_lib/include/platform/win32/platform_definitions.h @@ -14,10 +14,12 @@ #include "leak_dumper.h" -namespace Shared{ namespace Platform{ +namespace Shared { + namespace Platform { -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/sound/sound.h b/source/shared_lib/include/sound/sound.h index 0d344d3b5..e3e140b91 100644 --- a/source/shared_lib/include/sound/sound.h +++ b/source/shared_lib/include/sound/sound.h @@ -19,102 +19,140 @@ using namespace std; using namespace Shared::Platform; -namespace Shared{ namespace Sound{ +namespace Shared { + namespace Sound { -// ===================================================== -// class SoundInfo -// ===================================================== + // ===================================================== + // class SoundInfo + // ===================================================== -class SoundInfo{ -private: - uint32 channels; - uint32 samplesPerSecond; - uint32 bitsPerSample; - uint32 size; - uint32 bitRate; + class SoundInfo { + private: + uint32 channels; + uint32 samplesPerSecond; + uint32 bitsPerSample; + uint32 size; + uint32 bitRate; -public: - SoundInfo(); - virtual ~SoundInfo(){}; + public: + SoundInfo(); + virtual ~SoundInfo() { + }; - uint32 getChannels() const {return channels;} - uint32 getSamplesPerSecond() const {return samplesPerSecond;} - uint32 getBitsPerSample() const {return bitsPerSample;} - uint32 getSize() const {return size;} - uint32 getBitRate() const {return bitRate;} + uint32 getChannels() const { + return channels; + } + uint32 getSamplesPerSecond() const { + return samplesPerSecond; + } + uint32 getBitsPerSample() const { + return bitsPerSample; + } + uint32 getSize() const { + return size; + } + uint32 getBitRate() const { + return bitRate; + } - void setChannels(uint32 channels) {this->channels= channels;} - void setsamplesPerSecond(uint32 samplesPerSecond) {this->samplesPerSecond= samplesPerSecond;} - void setBitsPerSample(uint32 bitsPerSample) {this->bitsPerSample= bitsPerSample;} - void setSize(uint32 size) {this->size= size;} - void setBitRate(uint32 value) {this->bitRate = value;} -}; + void setChannels(uint32 channels) { + this->channels = channels; + } + void setsamplesPerSecond(uint32 samplesPerSecond) { + this->samplesPerSecond = samplesPerSecond; + } + void setBitsPerSample(uint32 bitsPerSample) { + this->bitsPerSample = bitsPerSample; + } + void setSize(uint32 size) { + this->size = size; + } + void setBitRate(uint32 value) { + this->bitRate = value; + } + }; -// ===================================================== -// class Sound -// ===================================================== + // ===================================================== + // class Sound + // ===================================================== -class Sound { -protected: - SoundFileLoader *soundFileLoader; - SoundInfo info; - float volume; - string fileName; - - //static bool masterserverMode; + class Sound { + protected: + SoundFileLoader *soundFileLoader; + SoundInfo info; + float volume; + string fileName; -public: - Sound(); - virtual ~Sound(){}; + //static bool masterserverMode; - //static void setMasterserverMode(bool value) { masterserverMode=value; } + public: + Sound(); + virtual ~Sound() { + }; - const SoundInfo *getInfo() const {return &info;} - float getVolume() const {return volume;} - - void setVolume(float volume) {this->volume= volume;} - string getFileName() {return fileName; } -}; + //static void setMasterserverMode(bool value) { masterserverMode=value; } -// ===================================================== -// class StaticSound -// ===================================================== + const SoundInfo *getInfo() const { + return &info; + } + float getVolume() const { + return volume; + } -class StaticSound: public Sound{ -private: - int8 * samples; + void setVolume(float volume) { + this->volume = volume; + } + string getFileName() { + return fileName; + } + }; -public: - StaticSound(); - virtual ~StaticSound(); + // ===================================================== + // class StaticSound + // ===================================================== - int8 *getSamples() const {return samples;} - - void load(const string &path); - void close(); -}; + class StaticSound : public Sound { + private: + int8 * samples; -// ===================================================== -// class StrSound -// ===================================================== + public: + StaticSound(); + virtual ~StaticSound(); -class StrSound: public Sound{ -private: - StrSound *next; + int8 *getSamples() const { + return samples; + } -public: - StrSound(); - virtual ~StrSound(); + void load(const string &path); + void close(); + }; - StrSound *getNext() const {return next;} - void setNext(StrSound *next) {this->next= next;} + // ===================================================== + // class StrSound + // ===================================================== - void open(const string &path); - uint32 read(int8 *samples, uint32 size); - void close(); - void restart(); -}; + class StrSound : public Sound { + private: + StrSound *next; -}}//end namespace + public: + StrSound(); + virtual ~StrSound(); + + StrSound *getNext() const { + return next; + } + void setNext(StrSound *next) { + this->next = next; + } + + void open(const string &path); + uint32 read(int8 *samples, uint32 size); + void close(); + void restart(); + }; + + } +}//end namespace #endif diff --git a/source/shared_lib/include/sound/sound_factory.h b/source/shared_lib/include/sound/sound_factory.h index e5e1eaca8..ba7506877 100644 --- a/source/shared_lib/include/sound/sound_factory.h +++ b/source/shared_lib/include/sound/sound_factory.h @@ -15,18 +15,23 @@ #include "sound_player.h" #include "leak_dumper.h" -namespace Shared{ namespace Sound{ +namespace Shared { + namespace Sound { -// ===================================================== -// class SoundFactory -// ===================================================== + // ===================================================== + // class SoundFactory + // ===================================================== -class SoundFactory{ -public: - virtual ~SoundFactory(){} - virtual SoundPlayer *newSoundPlayer() {return NULL;} -}; + class SoundFactory { + public: + virtual ~SoundFactory() { + } + virtual SoundPlayer *newSoundPlayer() { + return NULL; + } + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/sound/sound_factory_none.h b/source/shared_lib/include/sound/sound_factory_none.h index d13b4fb04..2793a643b 100644 --- a/source/shared_lib/include/sound/sound_factory_none.h +++ b/source/shared_lib/include/sound/sound_factory_none.h @@ -12,17 +12,21 @@ #include "sound_factory.h" #include "leak_dumper.h" -namespace Shared{ namespace Sound{ +namespace Shared { + namespace Sound { -// =============================== -// class SoundFactoryOpenAL -// =============================== + // =============================== + // class SoundFactoryOpenAL + // =============================== -class SoundFactoryNone : public SoundFactory{ -public: - virtual SoundPlayer* newSoundPlayer() {return NULL;} -}; + class SoundFactoryNone : public SoundFactory { + public: + virtual SoundPlayer* newSoundPlayer() { + return NULL; + } + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/sound/sound_file_loader.h b/source/shared_lib/include/sound/sound_file_loader.h index 6d946a737..c5e2d91f9 100644 --- a/source/shared_lib/include/sound/sound_file_loader.h +++ b/source/shared_lib/include/sound/sound_file_loader.h @@ -23,87 +23,94 @@ struct OggVorbis_File; using std::string; using std::ifstream; -namespace Shared{ namespace Sound{ +namespace Shared { + namespace Sound { -using Platform::uint32; -using Platform::int8; -using Util::MultiFactory; + using Platform::uint32; + using Platform::int8; + using Util::MultiFactory; -class SoundInfo; + class SoundInfo; -// ===================================================== -// class SoundFileLoader -// -/// Interface that all SoundFileLoaders will implement -// ===================================================== + // ===================================================== + // class SoundFileLoader + // + /// Interface that all SoundFileLoaders will implement + // ===================================================== -class SoundFileLoader{ -public: - virtual ~SoundFileLoader(){} + class SoundFileLoader { + public: + virtual ~SoundFileLoader() { + } - virtual void open(const string &path, SoundInfo *soundInfo)= 0; - virtual uint32 read(int8 *samples, uint32 size)= 0; - virtual void close()= 0; - virtual void restart()= 0; - virtual string getFileName() = 0; -}; + virtual void open(const string &path, SoundInfo *soundInfo) = 0; + virtual uint32 read(int8 *samples, uint32 size) = 0; + virtual void close() = 0; + virtual void restart() = 0; + virtual string getFileName() = 0; + }; -// ===================================================== -// class WavSoundFileLoader -// -/// Wave file loader -// ===================================================== + // ===================================================== + // class WavSoundFileLoader + // + /// Wave file loader + // ===================================================== -class WavSoundFileLoader: public SoundFileLoader{ -private: - static const int maxDataRetryCount= 10; - string fileName; -private: - uint32 dataOffset; - uint32 dataSize; - uint32 bytesPerSecond; - ifstream f; + class WavSoundFileLoader : public SoundFileLoader { + private: + static const int maxDataRetryCount = 10; + string fileName; + private: + uint32 dataOffset; + uint32 dataSize; + uint32 bytesPerSecond; + ifstream f; -public: - virtual void open(const string &path, SoundInfo *soundInfo); - virtual uint32 read(int8 *samples, uint32 size); - virtual void close(); - virtual void restart(); - virtual string getFileName() { return fileName; } -}; + public: + virtual void open(const string &path, SoundInfo *soundInfo); + virtual uint32 read(int8 *samples, uint32 size); + virtual void close(); + virtual void restart(); + virtual string getFileName() { + return fileName; + } + }; -// ===================================================== -// class OggSoundFileLoader -// -/// OGG sound file loader, uses ogg-vorbis library -// ===================================================== + // ===================================================== + // class OggSoundFileLoader + // + /// OGG sound file loader, uses ogg-vorbis library + // ===================================================== -class OggSoundFileLoader: public SoundFileLoader{ -private: - OggVorbis_File *vf; - FILE *f; - string fileName; + class OggSoundFileLoader : public SoundFileLoader { + private: + OggVorbis_File *vf; + FILE *f; + string fileName; -public: - OggSoundFileLoader(); - virtual void open(const string &path, SoundInfo *soundInfo); - virtual uint32 read(int8 *samples, uint32 size); - virtual void close(); - virtual void restart(); - virtual string getFileName() { return fileName; } -}; + public: + OggSoundFileLoader(); + virtual void open(const string &path, SoundInfo *soundInfo); + virtual uint32 read(int8 *samples, uint32 size); + virtual void close(); + virtual void restart(); + virtual string getFileName() { + return fileName; + } + }; -// ===================================================== -// class SoundFileLoaderFactory -// ===================================================== + // ===================================================== + // class SoundFileLoaderFactory + // ===================================================== -class SoundFileLoaderFactory: public MultiFactory{ -private: - SoundFileLoaderFactory(); -public: - static SoundFileLoaderFactory * getInstance(); -}; + class SoundFileLoaderFactory : public MultiFactory { + private: + SoundFileLoaderFactory(); + public: + static SoundFileLoaderFactory * getInstance(); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/sound/sound_interface.h b/source/shared_lib/include/sound/sound_interface.h index 33eecafb7..eaadfdabf 100644 --- a/source/shared_lib/include/sound/sound_interface.h +++ b/source/shared_lib/include/sound/sound_interface.h @@ -15,31 +15,33 @@ #include "sound_factory.h" #include "leak_dumper.h" -namespace Shared{ namespace Sound{ +namespace Shared { + namespace Sound { -// ===================================================== -// class SoundInterface -// ===================================================== + // ===================================================== + // class SoundInterface + // ===================================================== -class SoundInterface{ -private: - SoundFactory *soundFactory; + class SoundInterface { + private: + SoundFactory *soundFactory; + + private: + SoundInterface() { + soundFactory = 0; + } + SoundInterface(SoundInterface &); + void operator=(SoundInterface &); + + public: + static SoundInterface &getInstance(); + + void setFactory(SoundFactory *soundFactory); + + SoundPlayer *newSoundPlayer(); + }; -private: - SoundInterface() { - soundFactory = 0; } - SoundInterface(SoundInterface &); - void operator=(SoundInterface &); - -public: - static SoundInterface &getInstance(); - - void setFactory(SoundFactory *soundFactory); - - SoundPlayer *newSoundPlayer(); -}; - -}}//end namespace +}//end namespace #endif diff --git a/source/shared_lib/include/sound/sound_player.h b/source/shared_lib/include/sound/sound_player.h index 66f3e739e..d662ddeb2 100644 --- a/source/shared_lib/include/sound/sound_player.h +++ b/source/shared_lib/include/sound/sound_player.h @@ -18,47 +18,50 @@ using Shared::Platform::uint32; -namespace Shared{ namespace Sound{ +namespace Shared { + namespace Sound { -// ===================================================== -// class SoundPlayerParams -// ===================================================== + // ===================================================== + // class SoundPlayerParams + // ===================================================== -class SoundPlayerParams{ -public: - uint32 strBufferSize; - uint32 strBufferCount; - uint32 staticBufferCount; + class SoundPlayerParams { + public: + uint32 strBufferSize; + uint32 strBufferCount; + uint32 staticBufferCount; - SoundPlayerParams(); -}; + SoundPlayerParams(); + }; -// ===================================================== -// class SoundPlayer -// -// Interface that every SoundPlayer will implement -// ===================================================== + // ===================================================== + // class SoundPlayer + // + // Interface that every SoundPlayer will implement + // ===================================================== -class SoundPlayer{ -protected: + class SoundPlayer { + protected: - bool initOk; + bool initOk; -public: - virtual ~SoundPlayer() - { - initOk = false; - }; - virtual bool init(const SoundPlayerParams *params)= 0; - virtual void end()= 0; - virtual void play(StaticSound *staticSound, bool force=false)= 0; - virtual void play(StrSound *strSound, int64 fadeOn=0)= 0; //delay and fade in miliseconds - virtual void stop(StrSound *strSound, int64 fadeOff=0)= 0; - virtual void stopAllSounds(int64 fadeOff=0)= 0; - virtual void updateStreams()= 0; - virtual bool wasInitOk() const { return initOk; } -}; + public: + virtual ~SoundPlayer() { + initOk = false; + }; + virtual bool init(const SoundPlayerParams *params) = 0; + virtual void end() = 0; + virtual void play(StaticSound *staticSound, bool force = false) = 0; + virtual void play(StrSound *strSound, int64 fadeOn = 0) = 0; //delay and fade in miliseconds + virtual void stop(StrSound *strSound, int64 fadeOff = 0) = 0; + virtual void stopAllSounds(int64 fadeOff = 0) = 0; + virtual void updateStreams() = 0; + virtual bool wasInitOk() const { + return initOk; + } + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/streflop/FPUCheck.h b/source/shared_lib/include/streflop/FPUCheck.h index f416f9b1f..61d9b6801 100644 --- a/source/shared_lib/include/streflop/FPUCheck.h +++ b/source/shared_lib/include/streflop/FPUCheck.h @@ -13,7 +13,7 @@ #ifndef FPUCHECK_H #define FPUCHECK_H -//#include "LogOutput.h" + //#include "LogOutput.h" #include "util.h" #include "../../include/platform/common/streflop_cond.h" @@ -25,16 +25,16 @@ e.g. `assert(good_fpu_control_registers());' For reference, the layout of the MXCSR register: - FZ:RC:RC:PM:UM:OM:ZM:DM:IM:Rsvd:PE:UE:OE:ZE:DE:IE - 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + FZ:RC:RC:PM:UM:OM:ZM:DM:IM:Rsvd:PE:UE:OE:ZE:DE:IE + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 Spring1: 0 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 = 0x1D00 = 7424 Spring2: 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 = 0x1F80 = 8064 Default: 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 = 0x1F80 = 8064 MaskRsvd:1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 = 0xFF80 And the layout of the 387 FPU control word register: - Rsvd:Rsvd:Rsvd:X:RC:RC:PC:PC:Rsvd:Rsvd:PM:UM:OM:ZM:DM:IM - 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + Rsvd:Rsvd:Rsvd:X:RC:RC:PC:PC:Rsvd:Rsvd:PM:UM:OM:ZM:DM:IM + 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 Spring1: 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 = 0x003A = 58 Spring2: 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 = 0x003F = 63 Default: 0 0 0 0 0 0 1 1 0 0 1 1 1 1 1 1 = 0x033F = 831 @@ -66,12 +66,11 @@ MaskRsvd: 0 0 0 1 1 1 1 1 0 0 1 1 1 1 1 1 = 0x1F3F Source: Intel Architecture Software Development Manual, Volume 1, Basic Architecture */ -static inline void good_fpu_control_registers(const char* text, const char *file=NULL, const char *classname=NULL, const int line=-1) -{ +static inline void good_fpu_control_registers(const char* text, const char *file = NULL, const char *classname = NULL, const int line = -1) { const char *outText = text; - char szBuf[256]=""; - if(outText == NULL) { - sprintf(szBuf,"In [%s::%s Line: %d]",file=NULL, classname, line); + char szBuf[256] = ""; + if (outText == NULL) { + sprintf(szBuf, "In [%s::%s Line: %d]", file = NULL, classname, line); outText = &szBuf[0]; } // We are paranoid. @@ -80,38 +79,38 @@ static inline void good_fpu_control_registers(const char* text, const char *file fenv_t fenv; fegetenv(&fenv); - #if defined(__SUPPORT_SNAN__) && !defined(USE_GML) // -fsignaling-nans +#if defined(__SUPPORT_SNAN__) && !defined(USE_GML) // -fsignaling-nans bool ret = ((fenv.sse_mode & 0xFF80) == (0x1937 & 0xFF80) || (fenv.sse_mode & 0xFF80) == (0x1925 & 0xFF80)) && - ((fenv.x87_mode & 0x1F3F) == (0x0072 & 0x1F3F) || (fenv.x87_mode & 0x1F3F) == 0x003F); - #else + ((fenv.x87_mode & 0x1F3F) == (0x0072 & 0x1F3F) || (fenv.x87_mode & 0x1F3F) == 0x003F); +#else bool ret = ((fenv.sse_mode & 0xFF80) == 0x1D00 || (fenv.sse_mode & 0xFF80) == 0x1F80) && - ((fenv.x87_mode & 0x1F3F) == 0x003A || (fenv.x87_mode & 0x1F3F) == 0x003F); - #endif + ((fenv.x87_mode & 0x1F3F) == 0x003A || (fenv.x87_mode & 0x1F3F) == 0x003F); +#endif if (!ret) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"Sync warning: MXCSR 0x%04X instead of 0x1D00 or 0x1F80 (\"%s\")", fenv.sse_mode, outText); - SystemFlags::OutputDebug(SystemFlags::debugSystem,"Sync warning: FPUCW 0x%04X instead of 0x003A or 0x003F (\"%s\")", fenv.x87_mode, outText); + SystemFlags::OutputDebug(SystemFlags::debugSystem, "Sync warning: MXCSR 0x%04X instead of 0x1D00 or 0x1F80 (\"%s\")", fenv.sse_mode, outText); + SystemFlags::OutputDebug(SystemFlags::debugSystem, "Sync warning: FPUCW 0x%04X instead of 0x003A or 0x003F (\"%s\")", fenv.x87_mode, outText); // Set single precision floating point math. streflop_init(); - #if defined(__SUPPORT_SNAN__) && !defined(USE_GML) +#if defined(__SUPPORT_SNAN__) && !defined(USE_GML) feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); - #endif +#endif } #elif defined(STREFLOP_X87) fenv_t fenv; fegetenv(&fenv); - #if defined(__SUPPORT_SNAN__) && !defined(USE_GML) +#if defined(__SUPPORT_SNAN__) && !defined(USE_GML) bool ret = (fenv & 0x1F3F) == 0x0072 || (fenv & 0x1F3F) == 0x003F; - #else +#else bool ret = (fenv & 0x1F3F) == 0x003A || (fenv & 0x1F3F) == 0x003F; - #endif +#endif if (!ret) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"Sync warning: FPUCW 0x%04X instead of 0x003A or 0x003F (\"%s\")", fenv, outText); + SystemFlags::OutputDebug(SystemFlags::debugSystem, "Sync warning: FPUCW 0x%04X instead of 0x003A or 0x003F (\"%s\")", fenv, outText); // Set single precision floating point math. streflop_init(); - #if defined(__SUPPORT_SNAN__) && !defined(USE_GML) +#if defined(__SUPPORT_SNAN__) && !defined(USE_GML) feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); - #endif +#endif } #endif } diff --git a/source/shared_lib/include/streflop/FPUSettings.h b/source/shared_lib/include/streflop/FPUSettings.h index 345a0374c..c69878d28 100644 --- a/source/shared_lib/include/streflop/FPUSettings.h +++ b/source/shared_lib/include/streflop/FPUSettings.h @@ -1,13 +1,13 @@ /* - streflop: STandalone REproducible FLOating-Point - Copyright 2006 Nicolas Brodu - 2012 Mark Vejvoda - Code released according to the GNU Lesser General Public License + streflop: STandalone REproducible FLOating-Point + Copyright 2006 Nicolas Brodu + 2012 Mark Vejvoda + Code released according to the GNU Lesser General Public License - Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. - Uses SoftFloat too. + Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. + Uses SoftFloat too. - Please read the history and copyright information in the documentation provided with the source code + Please read the history and copyright information in the documentation provided with the source code */ /* @@ -53,13 +53,13 @@ namespace streflop { -// We do not use libm, so let's copy a few flags and C99 functions -// Give warning in case these flags would be defined already, this is indication -// of potential confusion! + // We do not use libm, so let's copy a few flags and C99 functions + // Give warning in case these flags would be defined already, this is indication + // of potential confusion! #if defined(FE_INVALID) || defined(FE_DENORMAL) || defined(FE_DIVBYZERO) || defined(FE_OVERFLOW) || defined(FE_UNDERFLOW) || defined(FE_INEXACT) || defined(FE_DOWNWARD) || defined(FE_TONEAREST) || defined(FE_TOWARDZERO) || defined(FE_UPWARD) -#warning STREFLOP: FE_XXX flags were already defined and will be redefined! Check you do not use the system libm. + #warning STREFLOP : FE_XXX flags were already defined and will be redefined!Check you do not use the system libm. #undef FE_INVALID #undef FE_DENORMAL #undef FE_DIVBYZERO @@ -75,74 +75,74 @@ namespace streflop { #endif // defined(FE_INVALID) || ... -// Flags for FPU exceptions -enum FPU_Exceptions { + // Flags for FPU exceptions + enum FPU_Exceptions { - // Invalid operation. If not signaling, gives NaN instead - FE_INVALID = 0x0001, - #define FE_INVALID FE_INVALID + // Invalid operation. If not signaling, gives NaN instead + FE_INVALID = 0x0001, +#define FE_INVALID FE_INVALID - // Extension: for x86 and SSE - // Denormal operand. If not signaling, use denormal arithmetic as usual - FE_DENORMAL = 0x0002, - #define FE_DENORMAL FE_DENORMAL + // Extension: for x86 and SSE + // Denormal operand. If not signaling, use denormal arithmetic as usual + FE_DENORMAL = 0x0002, +#define FE_DENORMAL FE_DENORMAL - // Division by zero. If not signaling, uses +/- infinity - FE_DIVBYZERO = 0x0004, - #define FE_DIVBYZERO FE_DIVBYZERO + // Division by zero. If not signaling, uses +/- infinity + FE_DIVBYZERO = 0x0004, +#define FE_DIVBYZERO FE_DIVBYZERO - // Overflow. If not signaling, round to nearest (including infinity) according to rounding mode - FE_OVERFLOW = 0x0008, - #define FE_OVERFLOW FE_OVERFLOW + // Overflow. If not signaling, round to nearest (including infinity) according to rounding mode + FE_OVERFLOW = 0x0008, +#define FE_OVERFLOW FE_OVERFLOW - // Underflow. If not signaling, use 0 instead - FE_UNDERFLOW = 0x0010, - #define FE_UNDERFLOW FE_UNDERFLOW + // Underflow. If not signaling, use 0 instead + FE_UNDERFLOW = 0x0010, +#define FE_UNDERFLOW FE_UNDERFLOW - // Rounding was not exact (ex: sqrt(2) is never exact) or when overflow causes rounding - FE_INEXACT = 0x0020, - #define FE_INEXACT FE_INEXACT + // Rounding was not exact (ex: sqrt(2) is never exact) or when overflow causes rounding + FE_INEXACT = 0x0020, +#define FE_INEXACT FE_INEXACT - // Combination of all the above - FE_ALL_EXCEPT = 0x003F - #define FE_ALL_EXCEPT FE_ALL_EXCEPT -}; + // Combination of all the above + FE_ALL_EXCEPT = 0x003F +#define FE_ALL_EXCEPT FE_ALL_EXCEPT + }; -// Flags for FPU rounding modes -enum FPU_RoundMode { - FE_TONEAREST = 0x0000, - #define FE_TONEAREST FE_TONEAREST + // Flags for FPU rounding modes + enum FPU_RoundMode { + FE_TONEAREST = 0x0000, +#define FE_TONEAREST FE_TONEAREST - FE_DOWNWARD = 0x0400, - #define FE_DOWNWARD FE_DOWNWARD + FE_DOWNWARD = 0x0400, +#define FE_DOWNWARD FE_DOWNWARD - FE_UPWARD = 0x0800, - #define FE_UPWARD FE_UPWARD + FE_UPWARD = 0x0800, +#define FE_UPWARD FE_UPWARD - FE_TOWARDZERO = 0x0C00 - #define FE_TOWARDZERO FE_TOWARDZERO -}; + FE_TOWARDZERO = 0x0C00 +#define FE_TOWARDZERO FE_TOWARDZERO + }; -/* Note: SSE control word, bits 0..15 -0->5: Run-time status flags -6: DAZ (denormals are zero, i.e. don't use denormals if bit is 1) -7->12: Exception flags, same meaning as for the x87 ones -13,14: Rounding flags, same meaning as for the x87 ones -15: Flush to zero (FTZ) for automatic handling of underflow (default is NO) -*/ + /* Note: SSE control word, bits 0..15 + 0->5: Run-time status flags + 6: DAZ (denormals are zero, i.e. don't use denormals if bit is 1) + 7->12: Exception flags, same meaning as for the x87 ones + 13,14: Rounding flags, same meaning as for the x87 ones + 15: Flush to zero (FTZ) for automatic handling of underflow (default is NO) + */ -// plan for portability + // plan for portability #if defined(_MSC_VER) #if _WIN64 // No fldcw intrinsics on Windows x64, punt to external asm // Seems like using unsigned is better on windows x64: http://www.virtualdub.org/blog/pivot/entry.php?id=340 -extern "C" { void streflop_winx64_fldcw(unsigned short mode); } -extern "C" { unsigned short streflop_winx64_fstcw(); } -extern "C" { void streflop_winx64_fclex(void); } -extern "C" { void streflop_winx64_stmxcsr(unsigned int mode); } -extern "C" { void streflop_winx64_ldmxcsr(unsigned int mode); } + extern "C" { void streflop_winx64_fldcw(unsigned short mode); } + extern "C" { unsigned short streflop_winx64_fstcw(); } + extern "C" { void streflop_winx64_fclex(void); } + extern "C" { void streflop_winx64_stmxcsr(unsigned int mode); } + extern "C" { void streflop_winx64_ldmxcsr(unsigned int mode); } #define STREFLOP_FSTCW(cw) do { short tmp = 0; tmp = streflop_winx64_fstcw(); (cw) = tmp; } while (0) #define STREFLOP_FLDCW(cw) do { short tmp = (cw); streflop_winx64_fldcw(tmp); } while (0) @@ -172,381 +172,382 @@ extern "C" { void streflop_winx64_ldmxcsr(unsigned int mode); } #if defined(STREFLOP_X87) /// Raise exception for these flags -inline int feraiseexcept(FPU_Exceptions excepts) { - unsigned short fpu_mode; - STREFLOP_FSTCW(fpu_mode); - fpu_mode &= ~( excepts ); // generate error for selection - STREFLOP_FLDCW(fpu_mode); - return 0; -} + inline int feraiseexcept(FPU_Exceptions excepts) { + unsigned short fpu_mode; + STREFLOP_FSTCW(fpu_mode); + fpu_mode &= ~(excepts); // generate error for selection + STREFLOP_FLDCW(fpu_mode); + return 0; + } -/// Clear exceptions for these flags -inline int feclearexcept(int excepts) { - unsigned short fpu_mode; - STREFLOP_FSTCW(fpu_mode); - fpu_mode |= excepts; - STREFLOP_FLDCW(fpu_mode); - return 0; -} + /// Clear exceptions for these flags + inline int feclearexcept(int excepts) { + unsigned short fpu_mode; + STREFLOP_FSTCW(fpu_mode); + fpu_mode |= excepts; + STREFLOP_FLDCW(fpu_mode); + return 0; + } -/// Get current rounding mode -inline int fegetround() { - unsigned short fpu_mode; - STREFLOP_FSTCW(fpu_mode); - return fpu_mode & 0x0C00; -} + /// Get current rounding mode + inline int fegetround() { + unsigned short fpu_mode; + STREFLOP_FSTCW(fpu_mode); + return fpu_mode & 0x0C00; + } -/// Set a new rounding mode -inline int fesetround(FPU_RoundMode roundMode) { - unsigned short fpu_mode; - STREFLOP_FSTCW(fpu_mode); - fpu_mode &= 0xF3FF; // clear current mode - fpu_mode |= roundMode; // sets new mode - STREFLOP_FLDCW(fpu_mode); - return 0; -} + /// Set a new rounding mode + inline int fesetround(FPU_RoundMode roundMode) { + unsigned short fpu_mode; + STREFLOP_FSTCW(fpu_mode); + fpu_mode &= 0xF3FF; // clear current mode + fpu_mode |= roundMode; // sets new mode + STREFLOP_FLDCW(fpu_mode); + return 0; + } -typedef short int fenv_t; + typedef short int fenv_t; -/// Default env. Defined in Math.cpp to be 0, and initalized on first use to the permanent holder -extern fenv_t FE_DFL_ENV; + /// Default env. Defined in Math.cpp to be 0, and initalized on first use to the permanent holder + extern fenv_t FE_DFL_ENV; -/// Get FP env into the given structure -inline int fegetenv(fenv_t *envp) { - // check that default env exists, otherwise save it now - if (!FE_DFL_ENV) STREFLOP_FSTCW(FE_DFL_ENV); - // Now store env into argument - STREFLOP_FSTCW(*envp); - return 0; -} + /// Get FP env into the given structure + inline int fegetenv(fenv_t *envp) { + // check that default env exists, otherwise save it now + if (!FE_DFL_ENV) STREFLOP_FSTCW(FE_DFL_ENV); + // Now store env into argument + STREFLOP_FSTCW(*envp); + return 0; + } -/// Sets FP env from the given structure -inline int fesetenv(const fenv_t *envp) { - // check that default env exists, otherwise save it now - if (!FE_DFL_ENV) STREFLOP_FSTCW(FE_DFL_ENV); - // Now overwrite current env by argument - STREFLOP_FLDCW(*envp); - return 0; -} + /// Sets FP env from the given structure + inline int fesetenv(const fenv_t *envp) { + // check that default env exists, otherwise save it now + if (!FE_DFL_ENV) STREFLOP_FSTCW(FE_DFL_ENV); + // Now overwrite current env by argument + STREFLOP_FLDCW(*envp); + return 0; + } -/// get env and clear exceptions -inline int feholdexcept(fenv_t *envp) { - fegetenv(envp); - feclearexcept(FE_ALL_EXCEPT); - return 0; -} + /// get env and clear exceptions + inline int feholdexcept(fenv_t *envp) { + fegetenv(envp); + feclearexcept(FE_ALL_EXCEPT); + return 0; + } -template inline void streflop_init() { - struct X {}; - X Unknown_numeric_type; - // unknown types do not compile - T error = Unknown_numeric_type; -} + template inline void streflop_init() { + struct X { + }; + X Unknown_numeric_type; + // unknown types do not compile + T error = Unknown_numeric_type; + } -/// Initialize the FPU for the different types -/// this may also be called to switch between code sections using -/// different precisions -template<> inline void streflop_init() { - unsigned short fpu_mode; - STREFLOP_FSTCW(fpu_mode); - fpu_mode &= 0xFCFF; // 32 bits internal operations - STREFLOP_FLDCW(fpu_mode); + /// Initialize the FPU for the different types + /// this may also be called to switch between code sections using + /// different precisions + template<> inline void streflop_init() { + unsigned short fpu_mode; + STREFLOP_FSTCW(fpu_mode); + fpu_mode &= 0xFCFF; // 32 bits internal operations + STREFLOP_FLDCW(fpu_mode); - // Enable signaling nans if compiled with this option. + // Enable signaling nans if compiled with this option. #if defined(__SUPPORT_SNAN__) && !defined(USE_GML) - feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); + feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); #endif -} + } -template<> inline void streflop_init() { - unsigned short fpu_mode; - STREFLOP_FSTCW(fpu_mode); - fpu_mode &= 0xFCFF; - fpu_mode |= 0x0200; // 64 bits internal operations - STREFLOP_FLDCW(fpu_mode); + template<> inline void streflop_init() { + unsigned short fpu_mode; + STREFLOP_FSTCW(fpu_mode); + fpu_mode &= 0xFCFF; + fpu_mode |= 0x0200; // 64 bits internal operations + STREFLOP_FLDCW(fpu_mode); #if defined(__SUPPORT_SNAN__) && !defined(USE_GML) - feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); + feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); #endif -} + } #if defined(Extended) -template<> inline void streflop_init() { - unsigned short fpu_mode; - STREFLOP_FSTCW(fpu_mode); - fpu_mode &= 0xFCFF; - fpu_mode |= 0x0300; // 80 bits internal operations - STREFLOP_FLDCW(fpu_mode); + template<> inline void streflop_init() { + unsigned short fpu_mode; + STREFLOP_FSTCW(fpu_mode); + fpu_mode &= 0xFCFF; + fpu_mode |= 0x0300; // 80 bits internal operations + STREFLOP_FLDCW(fpu_mode); #if defined(__SUPPORT_SNAN__) && !defined(USE_GML) - feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); + feraiseexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); #endif -} + } #endif // defined(Extended) #elif defined(STREFLOP_SSE) /// Raise exception for these flags -inline int feraiseexcept(FPU_Exceptions excepts) { - // Just in case the compiler would store a value on the st(x) registers - unsigned short x87_mode; - STREFLOP_FSTCW(x87_mode); - x87_mode &= ~( excepts ); // generate error for selection - STREFLOP_FLDCW(x87_mode); + inline int feraiseexcept(FPU_Exceptions excepts) { + // Just in case the compiler would store a value on the st(x) registers + unsigned short x87_mode; + STREFLOP_FSTCW(x87_mode); + x87_mode &= ~(excepts); // generate error for selection + STREFLOP_FLDCW(x87_mode); - int sse_mode; - STREFLOP_STMXCSR(sse_mode); - sse_mode &= ~( excepts << 7 ); // generate error for selection - STREFLOP_LDMXCSR(sse_mode); + int sse_mode; + STREFLOP_STMXCSR(sse_mode); + sse_mode &= ~(excepts << 7); // generate error for selection + STREFLOP_LDMXCSR(sse_mode); - return 0; -} + return 0; + } -/// Clear exceptions for these flags -inline int feclearexcept(int excepts) { - // Just in case the compiler would store a value on the st(x) registers - unsigned short x87_mode; - STREFLOP_FSTCW(x87_mode); - x87_mode |= excepts; - STREFLOP_FLDCW(x87_mode); + /// Clear exceptions for these flags + inline int feclearexcept(int excepts) { + // Just in case the compiler would store a value on the st(x) registers + unsigned short x87_mode; + STREFLOP_FSTCW(x87_mode); + x87_mode |= excepts; + STREFLOP_FLDCW(x87_mode); - int sse_mode; - STREFLOP_STMXCSR(sse_mode); - sse_mode |= excepts << 7; - STREFLOP_LDMXCSR(sse_mode); + int sse_mode; + STREFLOP_STMXCSR(sse_mode); + sse_mode |= excepts << 7; + STREFLOP_LDMXCSR(sse_mode); - return 0; -} + return 0; + } -/// Get current rounding mode -inline int fegetround() { - int sse_mode; - STREFLOP_STMXCSR(sse_mode); - return (sse_mode>>3) & 0x00000C00; -} + /// Get current rounding mode + inline int fegetround() { + int sse_mode; + STREFLOP_STMXCSR(sse_mode); + return (sse_mode >> 3) & 0x00000C00; + } -/// Set a new rounding mode -inline int fesetround(FPU_RoundMode roundMode) { - int sse_mode; - STREFLOP_STMXCSR(sse_mode); - sse_mode &= 0xFFFF9FFF; // clear current mode - sse_mode |= roundMode<<3; // sets new mode - STREFLOP_LDMXCSR(sse_mode); - return 0; -} + /// Set a new rounding mode + inline int fesetround(FPU_RoundMode roundMode) { + int sse_mode; + STREFLOP_STMXCSR(sse_mode); + sse_mode &= 0xFFFF9FFF; // clear current mode + sse_mode |= roundMode << 3; // sets new mode + STREFLOP_LDMXCSR(sse_mode); + return 0; + } -/// stores both x87 and SSE words -struct fenv_t { - int sse_mode; - short int x87_mode; -}; + /// stores both x87 and SSE words + struct fenv_t { + int sse_mode; + short int x87_mode; + }; -/// Default env. Defined in Math.cpp, structs are initialized to 0 -extern fenv_t FE_DFL_ENV; + /// Default env. Defined in Math.cpp, structs are initialized to 0 + extern fenv_t FE_DFL_ENV; -/// Get FP env into the given structure -inline int fegetenv(fenv_t *envp) { - // check that default env exists, otherwise save it now - if (!FE_DFL_ENV.x87_mode) STREFLOP_FSTCW(FE_DFL_ENV.x87_mode); - // Now store env into argument - STREFLOP_FSTCW(envp->x87_mode); + /// Get FP env into the given structure + inline int fegetenv(fenv_t *envp) { + // check that default env exists, otherwise save it now + if (!FE_DFL_ENV.x87_mode) STREFLOP_FSTCW(FE_DFL_ENV.x87_mode); + // Now store env into argument + STREFLOP_FSTCW(envp->x87_mode); - // For SSE - if (!FE_DFL_ENV.sse_mode) STREFLOP_STMXCSR(FE_DFL_ENV.sse_mode); - // Now store env into argument - STREFLOP_STMXCSR(envp->sse_mode); - return 0; -} + // For SSE + if (!FE_DFL_ENV.sse_mode) STREFLOP_STMXCSR(FE_DFL_ENV.sse_mode); + // Now store env into argument + STREFLOP_STMXCSR(envp->sse_mode); + return 0; + } -/// Sets FP env from the given structure -inline int fesetenv(const fenv_t *envp) { - // check that default env exists, otherwise save it now - if (!FE_DFL_ENV.x87_mode) STREFLOP_FSTCW(FE_DFL_ENV.x87_mode); - // Now overwrite current env by argument - STREFLOP_FLDCW(envp->x87_mode); + /// Sets FP env from the given structure + inline int fesetenv(const fenv_t *envp) { + // check that default env exists, otherwise save it now + if (!FE_DFL_ENV.x87_mode) STREFLOP_FSTCW(FE_DFL_ENV.x87_mode); + // Now overwrite current env by argument + STREFLOP_FLDCW(envp->x87_mode); - // For SSE - if (!FE_DFL_ENV.sse_mode) STREFLOP_STMXCSR(FE_DFL_ENV.sse_mode); - // Now overwrite current env by argument - STREFLOP_LDMXCSR(envp->sse_mode); - return 0; -} + // For SSE + if (!FE_DFL_ENV.sse_mode) STREFLOP_STMXCSR(FE_DFL_ENV.sse_mode); + // Now overwrite current env by argument + STREFLOP_LDMXCSR(envp->sse_mode); + return 0; + } -/// get env and clear exceptions -inline int feholdexcept(fenv_t *envp) { - fegetenv(envp); - feclearexcept(FE_ALL_EXCEPT); - return 0; -} + /// get env and clear exceptions + inline int feholdexcept(fenv_t *envp) { + fegetenv(envp); + feclearexcept(FE_ALL_EXCEPT); + return 0; + } -template inline void streflop_init() { - // Do nothing by default, or for unknown types -} + template inline void streflop_init() { + // Do nothing by default, or for unknown types + } -/// Initialize the FPU for the different types -/// this may also be called to switch between code sections using -/// different precisions -template<> inline void streflop_init() { - // Just in case the compiler would store a value on the st(x) registers - unsigned short x87_mode; - STREFLOP_FSTCW(x87_mode); - x87_mode &= 0xFCFF; // 32 bits internal operations - STREFLOP_FLDCW(x87_mode); + /// Initialize the FPU for the different types + /// this may also be called to switch between code sections using + /// different precisions + template<> inline void streflop_init() { + // Just in case the compiler would store a value on the st(x) registers + unsigned short x87_mode; + STREFLOP_FSTCW(x87_mode); + x87_mode &= 0xFCFF; // 32 bits internal operations + STREFLOP_FLDCW(x87_mode); - int sse_mode; - STREFLOP_STMXCSR(sse_mode); + int sse_mode; + STREFLOP_STMXCSR(sse_mode); #if defined(STREFLOP_NO_DENORMALS) - sse_mode |= 0x8040; // set DAZ and FTZ + sse_mode |= 0x8040; // set DAZ and FTZ #else - sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ + sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ #endif - STREFLOP_LDMXCSR(sse_mode); -} + STREFLOP_LDMXCSR(sse_mode); + } -template<> inline void streflop_init() { - // Just in case the compiler would store a value on the st(x) registers - unsigned short x87_mode; - STREFLOP_FSTCW(x87_mode); - x87_mode &= 0xFCFF; - x87_mode |= 0x0200; // 64 bits internal operations - STREFLOP_FLDCW(x87_mode); + template<> inline void streflop_init() { + // Just in case the compiler would store a value on the st(x) registers + unsigned short x87_mode; + STREFLOP_FSTCW(x87_mode); + x87_mode &= 0xFCFF; + x87_mode |= 0x0200; // 64 bits internal operations + STREFLOP_FLDCW(x87_mode); - int sse_mode; - STREFLOP_STMXCSR(sse_mode); + int sse_mode; + STREFLOP_STMXCSR(sse_mode); #if defined(STREFLOP_NO_DENORMALS) - sse_mode |= 0x8040; // set DAZ and FTZ + sse_mode |= 0x8040; // set DAZ and FTZ #else - sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ + sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ #endif - STREFLOP_LDMXCSR(sse_mode); -} + STREFLOP_LDMXCSR(sse_mode); + } #if defined(Extended) -template<> inline void streflop_init() { - // Just in case the compiler would store a value on the st(x) registers - unsigned short x87_mode; - STREFLOP_FSTCW(x87_mode); - x87_mode &= 0xFCFF; - x87_mode |= 0x0300; // 80 bits internal operations - STREFLOP_FLDCW(x87_mode); + template<> inline void streflop_init() { + // Just in case the compiler would store a value on the st(x) registers + unsigned short x87_mode; + STREFLOP_FSTCW(x87_mode); + x87_mode &= 0xFCFF; + x87_mode |= 0x0300; // 80 bits internal operations + STREFLOP_FLDCW(x87_mode); - int sse_mode; - STREFLOP_STMXCSR(sse_mode); + int sse_mode; + STREFLOP_STMXCSR(sse_mode); #if defined(STREFLOP_NO_DENORMALS) - sse_mode |= 0x8040; // set DAZ and FTZ + sse_mode |= 0x8040; // set DAZ and FTZ #else - sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ + sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ #endif - STREFLOP_LDMXCSR(sse_mode); -} + STREFLOP_LDMXCSR(sse_mode); + } #endif // defined(Extended) #elif defined(STREFLOP_SOFT) /// Raise exception for these flags -inline int feraiseexcept(FPU_Exceptions excepts) { - // Use positive logic - SoftFloat::float_exception_realtraps |= excepts; - return 0; -} + inline int feraiseexcept(FPU_Exceptions excepts) { + // Use positive logic + SoftFloat::float_exception_realtraps |= excepts; + return 0; + } -/// Clear exceptions for these flags -inline int feclearexcept(int excepts) { - // Use positive logic - SoftFloat::float_exception_realtraps &= ~( excepts ); - return 0; -} + /// Clear exceptions for these flags + inline int feclearexcept(int excepts) { + // Use positive logic + SoftFloat::float_exception_realtraps &= ~(excepts); + return 0; + } -/// Get current rounding mode -inline int fegetround() { - // see softfloat.h for the definition - switch (SoftFloat::float_rounding_mode) { - case SoftFloat::float_round_down: return FE_DOWNWARD; - case SoftFloat::float_round_up: return FE_UPWARD; - case SoftFloat::float_round_to_zero: return FE_TOWARDZERO; - default:; // is also initial mode - } - // case SoftFloat::float_round_nearest_even: - return FE_TONEAREST; -} + /// Get current rounding mode + inline int fegetround() { + // see softfloat.h for the definition + switch (SoftFloat::float_rounding_mode) { + case SoftFloat::float_round_down: return FE_DOWNWARD; + case SoftFloat::float_round_up: return FE_UPWARD; + case SoftFloat::float_round_to_zero: return FE_TOWARDZERO; + default:; // is also initial mode + } + // case SoftFloat::float_round_nearest_even: + return FE_TONEAREST; + } -/// Set a new rounding mode -inline int fesetround(FPU_RoundMode roundMode) { - // see softfloat.h for the definition - switch (roundMode) { - case FE_DOWNWARD: SoftFloat::float_rounding_mode = SoftFloat::float_round_down; return 0; - case FE_UPWARD: SoftFloat::float_rounding_mode = SoftFloat::float_round_up; return 0; - case FE_TOWARDZERO: SoftFloat::float_rounding_mode = SoftFloat::float_round_to_zero; return 0; - case FE_TONEAREST: SoftFloat::float_rounding_mode = SoftFloat::float_round_nearest_even; return 0; - } - // Error, invalid mode - return 1; -} + /// Set a new rounding mode + inline int fesetround(FPU_RoundMode roundMode) { + // see softfloat.h for the definition + switch (roundMode) { + case FE_DOWNWARD: SoftFloat::float_rounding_mode = SoftFloat::float_round_down; return 0; + case FE_UPWARD: SoftFloat::float_rounding_mode = SoftFloat::float_round_up; return 0; + case FE_TOWARDZERO: SoftFloat::float_rounding_mode = SoftFloat::float_round_to_zero; return 0; + case FE_TONEAREST: SoftFloat::float_rounding_mode = SoftFloat::float_round_nearest_even; return 0; + } + // Error, invalid mode + return 1; + } -/// SoftFloat environment comprises non-volatile state variables -struct fenv_t { - char tininess; - char rounding_mode; - int exception_realtraps; -}; + /// SoftFloat environment comprises non-volatile state variables + struct fenv_t { + char tininess; + char rounding_mode; + int exception_realtraps; + }; -/// Default env. Defined in Math.cpp, initialized to some invalid value for detection -extern fenv_t FE_DFL_ENV; + /// Default env. Defined in Math.cpp, initialized to some invalid value for detection + extern fenv_t FE_DFL_ENV; -/// Get FP env into the given structure -inline int fegetenv(fenv_t *envp) { - // check that default env exists, otherwise save it now - if (FE_DFL_ENV.tininess==42) { - // First use: save default environment now - FE_DFL_ENV.tininess = SoftFloat::float_detect_tininess; - FE_DFL_ENV.rounding_mode = SoftFloat::float_rounding_mode; - FE_DFL_ENV.exception_realtraps = SoftFloat::float_exception_realtraps; - } - // Now get the current env in the given argument - envp->tininess = SoftFloat::float_detect_tininess; - envp->rounding_mode = SoftFloat::float_rounding_mode; - envp->exception_realtraps = SoftFloat::float_exception_realtraps; - return 0; -} + /// Get FP env into the given structure + inline int fegetenv(fenv_t *envp) { + // check that default env exists, otherwise save it now + if (FE_DFL_ENV.tininess == 42) { + // First use: save default environment now + FE_DFL_ENV.tininess = SoftFloat::float_detect_tininess; + FE_DFL_ENV.rounding_mode = SoftFloat::float_rounding_mode; + FE_DFL_ENV.exception_realtraps = SoftFloat::float_exception_realtraps; + } + // Now get the current env in the given argument + envp->tininess = SoftFloat::float_detect_tininess; + envp->rounding_mode = SoftFloat::float_rounding_mode; + envp->exception_realtraps = SoftFloat::float_exception_realtraps; + return 0; + } -/// Sets FP env from the given structure -inline int fesetenv(const fenv_t *envp) { - // check that default env exists, otherwise save it now - if (FE_DFL_ENV.tininess==42) { - // First use: save default environment now - FE_DFL_ENV.tininess = SoftFloat::float_detect_tininess; - FE_DFL_ENV.rounding_mode = SoftFloat::float_rounding_mode; - FE_DFL_ENV.exception_realtraps = SoftFloat::float_exception_realtraps; - } - // Now get the current env in the given argument - SoftFloat::float_detect_tininess = envp->tininess; - SoftFloat::float_rounding_mode = envp->rounding_mode; - SoftFloat::float_exception_realtraps = envp->exception_realtraps; - return 0; -} + /// Sets FP env from the given structure + inline int fesetenv(const fenv_t *envp) { + // check that default env exists, otherwise save it now + if (FE_DFL_ENV.tininess == 42) { + // First use: save default environment now + FE_DFL_ENV.tininess = SoftFloat::float_detect_tininess; + FE_DFL_ENV.rounding_mode = SoftFloat::float_rounding_mode; + FE_DFL_ENV.exception_realtraps = SoftFloat::float_exception_realtraps; + } + // Now get the current env in the given argument + SoftFloat::float_detect_tininess = envp->tininess; + SoftFloat::float_rounding_mode = envp->rounding_mode; + SoftFloat::float_exception_realtraps = envp->exception_realtraps; + return 0; + } -/// get env and clear exceptions -inline int feholdexcept(fenv_t *envp) { - fegetenv(envp); - feclearexcept(FE_ALL_EXCEPT); - return 0; -} + /// get env and clear exceptions + inline int feholdexcept(fenv_t *envp) { + fegetenv(envp); + feclearexcept(FE_ALL_EXCEPT); + return 0; + } -template inline void streflop_init() { - // Do nothing by default, or for unknown types -} + template inline void streflop_init() { + // Do nothing by default, or for unknown types + } -/// Initialize the FPU for the different types -/// this may also be called to switch between code sections using -/// different precisions -template<> inline void streflop_init() { -} -template<> inline void streflop_init() { -} -template<> inline void streflop_init() { -} + /// Initialize the FPU for the different types + /// this may also be called to switch between code sections using + /// different precisions + template<> inline void streflop_init() { + } + template<> inline void streflop_init() { + } + template<> inline void streflop_init() { + } #else // defined(STREFLOP_X87) #error STREFLOP: Invalid combination or unknown FPU type. diff --git a/source/shared_lib/include/streflop/IntegerTypes.h b/source/shared_lib/include/streflop/IntegerTypes.h index 17c1251f6..8063b5bb5 100644 --- a/source/shared_lib/include/streflop/IntegerTypes.h +++ b/source/shared_lib/include/streflop/IntegerTypes.h @@ -1,13 +1,13 @@ /* - streflop: STandalone REproducible FLOating-Point - Copyright 2006 Nicolas Brodu - 2012 Mark Vejvoda - Code released according to the GNU Lesser General Public License + streflop: STandalone REproducible FLOating-Point + Copyright 2006 Nicolas Brodu + 2012 Mark Vejvoda + Code released according to the GNU Lesser General Public License - Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. - Uses SoftFloat too. + Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. + Uses SoftFloat too. - Please read the history and copyright information in the documentation provided with the source code + Please read the history and copyright information in the documentation provided with the source code */ #ifndef STREFLOP_INTEGER_TYPES_H @@ -27,113 +27,113 @@ // Avoid conflict with system types, if any namespace streflop { -// Template meta-programming: this is the "program" which variables are types and constants are int template arguments -// Algorithm: provide an expected size, and recursively increase the integer types till the size match -template struct SizedTypeMaker { -}; + // Template meta-programming: this is the "program" which variables are types and constants are int template arguments + // Algorithm: provide an expected size, and recursively increase the integer types till the size match + template struct SizedTypeMaker { + }; -// start by long long to provide the recursion terminal condition + // start by long long to provide the recursion terminal condition -// false : the expected_size does not exist: do not define a type, there will be a compilation error -template struct SizedTypeMaker { - // Error: Integer type with expected size does not exist -}; + // false : the expected_size does not exist: do not define a type, there will be a compilation error + template struct SizedTypeMaker { + // Error: Integer type with expected size does not exist + }; -// true: end recursion by defining the correct type to be long long -template struct SizedTypeMaker { - typedef long long final_type; -}; + // true: end recursion by defining the correct type to be long long + template struct SizedTypeMaker { + typedef long long final_type; + }; -// false : recurse by increasing the integer type till it reaches the expected size -template struct SizedTypeMaker { - typedef typename SizedTypeMaker::final_type final_type; -}; + // false : recurse by increasing the integer type till it reaches the expected size + template struct SizedTypeMaker { + typedef typename SizedTypeMaker::final_type final_type; + }; -// true: end recursion by defining the correct type to be long -template struct SizedTypeMaker { - typedef long final_type; -}; + // true: end recursion by defining the correct type to be long + template struct SizedTypeMaker { + typedef long final_type; + }; -// false : recurse by increasing the integer type till it reaches the expected size -template struct SizedTypeMaker { - typedef typename SizedTypeMaker::final_type final_type; -}; + // false : recurse by increasing the integer type till it reaches the expected size + template struct SizedTypeMaker { + typedef typename SizedTypeMaker::final_type final_type; + }; -// true: end recursion by defining the correct type to be int -template struct SizedTypeMaker { - typedef int final_type; -}; + // true: end recursion by defining the correct type to be int + template struct SizedTypeMaker { + typedef int final_type; + }; -// false : recurse by increasing the integer type till it reaches the expected size -template struct SizedTypeMaker { - typedef typename SizedTypeMaker::final_type final_type; -}; + // false : recurse by increasing the integer type till it reaches the expected size + template struct SizedTypeMaker { + typedef typename SizedTypeMaker::final_type final_type; + }; -// true: end recursion by defining the correct type to be short -template struct SizedTypeMaker { - typedef short final_type; -}; + // true: end recursion by defining the correct type to be short + template struct SizedTypeMaker { + typedef short final_type; + }; -// Do it again for unsigned types + // Do it again for unsigned types -// false : the expected_size does not exist: do not define a type, there will be a compilation error -template struct SizedTypeMaker { - // Error: Integer type with expected size does not exist -}; + // false : the expected_size does not exist: do not define a type, there will be a compilation error + template struct SizedTypeMaker { + // Error: Integer type with expected size does not exist + }; -// true: end recursion by defining the correct type to be long long -template struct SizedTypeMaker { - typedef unsigned long long final_type; -}; + // true: end recursion by defining the correct type to be long long + template struct SizedTypeMaker { + typedef unsigned long long final_type; + }; -// false : recurse by increasing the integer type till it reaches the expected size -template struct SizedTypeMaker { - typedef typename SizedTypeMaker::final_type final_type; -}; + // false : recurse by increasing the integer type till it reaches the expected size + template struct SizedTypeMaker { + typedef typename SizedTypeMaker::final_type final_type; + }; -// true: end recursion by defining the correct type to be long -template struct SizedTypeMaker { - typedef unsigned long final_type; -}; + // true: end recursion by defining the correct type to be long + template struct SizedTypeMaker { + typedef unsigned long final_type; + }; -// false : recurse by increasing the integer type till it reaches the expected size -template struct SizedTypeMaker { - typedef typename SizedTypeMaker::final_type final_type; -}; + // false : recurse by increasing the integer type till it reaches the expected size + template struct SizedTypeMaker { + typedef typename SizedTypeMaker::final_type final_type; + }; -// true: end recursion by defining the correct type to be int -template struct SizedTypeMaker { - typedef unsigned int final_type; -}; + // true: end recursion by defining the correct type to be int + template struct SizedTypeMaker { + typedef unsigned int final_type; + }; -// false : recurse by increasing the integer type till it reaches the expected size -template struct SizedTypeMaker { - typedef typename SizedTypeMaker::final_type final_type; -}; + // false : recurse by increasing the integer type till it reaches the expected size + template struct SizedTypeMaker { + typedef typename SizedTypeMaker::final_type final_type; + }; -// true: end recursion by defining the correct type to be short -template struct SizedTypeMaker { - typedef unsigned short final_type; -}; + // true: end recursion by defining the correct type to be short + template struct SizedTypeMaker { + typedef unsigned short final_type; + }; -// Utility to get an int type with the selected size IN BITS -template struct SizedInteger { - typedef typename SizedTypeMaker::final_type Type; -}; -template struct SizedUnsignedInteger { - typedef typename SizedTypeMaker::final_type Type; -}; + // Utility to get an int type with the selected size IN BITS + template struct SizedInteger { + typedef typename SizedTypeMaker::final_type Type; + }; + template struct SizedUnsignedInteger { + typedef typename SizedTypeMaker::final_type Type; + }; -// Specialize for size = STREFLOP_INTEGER_TYPES_CHAR_BITS + // Specialize for size = STREFLOP_INTEGER_TYPES_CHAR_BITS -template<> struct SizedInteger { - typedef char Type; -}; + template<> struct SizedInteger { + typedef char Type; + }; -template<> struct SizedUnsignedInteger { - typedef unsigned char Type; -}; + template<> struct SizedUnsignedInteger { + typedef unsigned char Type; + }; } diff --git a/source/shared_lib/include/streflop/Random.h b/source/shared_lib/include/streflop/Random.h index 2467e8849..0f266cbc6 100644 --- a/source/shared_lib/include/streflop/Random.h +++ b/source/shared_lib/include/streflop/Random.h @@ -1,14 +1,14 @@ /* - streflop: STandalone REproducible FLOating-Point - Copyright 2006 Nicolas Brodu - 2010 Mark Vejvoda + streflop: STandalone REproducible FLOating-Point + Copyright 2006 Nicolas Brodu + 2010 Mark Vejvoda - Code released according to the GNU Lesser General Public License + Code released according to the GNU Lesser General Public License - Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. - Uses SoftFloat too. + Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. + Uses SoftFloat too. - Please read the history and copyright information in the documentation provided with the source code + Please read the history and copyright information in the documentation provided with the source code */ #ifndef RANDOM_H @@ -19,107 +19,115 @@ namespace streflop { -/** Random state holder object - Declare one of this per thread, and use it as context to the random functions - Object is properly set by the RandomInit functions - This allows it to remain POD type -*/ -struct RandomState { + /** Random state holder object + Declare one of this per thread, and use it as context to the random functions + Object is properly set by the RandomInit functions + This allows it to remain POD type + */ + struct RandomState { #if !defined(STREFLOP_RANDOM_GEN_SIZE) #define STREFLOP_RANDOM_GEN_SIZE 32 #endif - // state vector - SizedUnsignedInteger::Type mt[19968/STREFLOP_RANDOM_GEN_SIZE]; - int mti; - // random seed that was used for initialization - SizedUnsignedInteger<32>::Type seed; -} + // state vector + SizedUnsignedInteger::Type mt[19968 / STREFLOP_RANDOM_GEN_SIZE]; + int mti; + // random seed that was used for initialization + SizedUnsignedInteger<32>::Type seed; + } #ifdef __GNUC__ -__attribute__ ((aligned (64))) // align state vector on cache line size + __attribute__((aligned(64))) // align state vector on cache line size #endif -; + ; -/// Default random state holder -extern RandomState DefaultRandomState; + /// Default random state holder + extern RandomState DefaultRandomState; -/** Initialize the random number generator with the given seed. + /** Initialize the random number generator with the given seed. - By default, the seed is taken from system time and printed out - so the experiment is reproducible by inputing the same seed again. + By default, the seed is taken from system time and printed out + so the experiment is reproducible by inputing the same seed again. - You can set here a previous seed to reproduce it. + You can set here a previous seed to reproduce it. - This interface allows independance from the actual RNG used, - and/or system functions. + This interface allows independance from the actual RNG used, + and/or system functions. - The RNG used is the Mersenne twister implementation by the - original authors Takuji Nishimura and Makoto Matsumoto. + The RNG used is the Mersenne twister implementation by the + original authors Takuji Nishimura and Makoto Matsumoto. - See also Random.cpp for more information. -*/ -SizedUnsignedInteger<32>::Type RandomInit(RandomState& state = DefaultRandomState); -SizedUnsignedInteger<32>::Type RandomInit(SizedUnsignedInteger<32>::Type seed, RandomState& state = DefaultRandomState); + See also Random.cpp for more information. + */ + SizedUnsignedInteger<32>::Type RandomInit(RandomState& state = DefaultRandomState); + SizedUnsignedInteger<32>::Type RandomInit(SizedUnsignedInteger<32>::Type seed, RandomState& state = DefaultRandomState); -/// Returns the random seed that was used for the initialization -/// Defaults to 0 if the RNG is not yet initialized -SizedUnsignedInteger<32>::Type RandomSeed(RandomState& state = DefaultRandomState); + /// Returns the random seed that was used for the initialization + /// Defaults to 0 if the RNG is not yet initialized + SizedUnsignedInteger<32>::Type RandomSeed(RandomState& state = DefaultRandomState); -/** Returns a random number from a uniform distribution. + /** Returns a random number from a uniform distribution. - All integer types are supported, as well as Simple, Double, and Extended + All integer types are supported, as well as Simple, Double, and Extended - The Random(min, max) template takes as argument: - - bool: whether or not including the min bound - - bool: whether or not including the max bound - - type: to generate a number from that type, and decide on min/max bounds - Example: Double x = Random(7.0, 18.0) - This will return a Double number between 7.0 (included) and 18.0 (excluded) - This works for both float and integer types. + The Random(min, max) template takes as argument: + - bool: whether or not including the min bound + - bool: whether or not including the max bound + - type: to generate a number from that type, and decide on min/max bounds + Example: Double x = Random(7.0, 18.0) + This will return a Double number between 7.0 (included) and 18.0 (excluded) + This works for both float and integer types. - Aliases are named like RandomXY with X,Y = E,I for bounds Excluded,Included. - Example: RandomEI(min,max) will return a number between min (excluded) and max (included). + Aliases are named like RandomXY with X,Y = E,I for bounds Excluded,Included. + Example: RandomEI(min,max) will return a number between min (excluded) and max (included). - The Random() template returns a number of the given type chosen uniformly between - all representable numbers of that type. - - For integer types, this means what you expect: any int, char, whatever on the whole range - - For float types, just recall that there are as many representable floats in each range - 2^x - 2^(x+1), this is what floating-point means + The Random() template returns a number of the given type chosen uniformly between + all representable numbers of that type. + - For integer types, this means what you expect: any int, char, whatever on the whole range + - For float types, just recall that there are as many representable floats in each range + 2^x - 2^(x+1), this is what floating-point means - Notes: - - If min > max then the result is undefined. - - If you ask for an empty interval (like RandomEE with min==max) then the result is undefined. - - If a NaN value is passed to the float functions, NaN is returned. - - By order of performance, for float types, IE is fastest, then EI, then EE, then II. For integer - types, it happens that the order is II, IE and EI ex-aequo, and EE, but the difference is much - less pronounced than for the float types. Use IE preferably for floats, II for ints. + Notes: + - If min > max then the result is undefined. + - If you ask for an empty interval (like RandomEE with min==max) then the result is undefined. + - If a NaN value is passed to the float functions, NaN is returned. + - By order of performance, for float types, IE is fastest, then EI, then EE, then II. For integer + types, it happens that the order is II, IE and EI ex-aequo, and EE, but the difference is much + less pronounced than for the float types. Use IE preferably for floats, II for ints. - The floating-point functions always compute a random number with the maximum digits of precision, - taking care of bounds. That is, it uses the 1-2 interval as this is a power-of-two bounded interval, - so each representable number in that interval (matching a distinct bit pattern) is given exactly - the same weight. This is really a truly uniform distribution, unlike the 0-1 range (see note below). - That 1-2 interval is then converted to the min-max range, hopefully resulting in the loss of as - few random bits as possible. See also the additional functions below for better performance. + The floating-point functions always compute a random number with the maximum digits of precision, + taking care of bounds. That is, it uses the 1-2 interval as this is a power-of-two bounded interval, + so each representable number in that interval (matching a distinct bit pattern) is given exactly + the same weight. This is really a truly uniform distribution, unlike the 0-1 range (see note below). + That 1-2 interval is then converted to the min-max range, hopefully resulting in the loss of as + few random bits as possible. See also the additional functions below for better performance. - Note: Getting numbers in the 0-1 interval may be tricky. Half the 2^X exponents are in that range as - well as denormal numbers. This could result in an horrible loss of bits when scaling from one exponent - to another. Fortunately, the numbers in 1-2 are generated with maximum precision, and then subtracting 1.0 - to get a number in 0-1 keeps that precision because all the numbers obtained this way are still perfectly - representable. Moreover, the minimum exponent reached this way is still far above the denormals range. + Note: Getting numbers in the 0-1 interval may be tricky. Half the 2^X exponents are in that range as + well as denormal numbers. This could result in an horrible loss of bits when scaling from one exponent + to another. Fortunately, the numbers in 1-2 are generated with maximum precision, and then subtracting 1.0 + to get a number in 0-1 keeps that precision because all the numbers obtained this way are still perfectly + representable. Moreover, the minimum exponent reached this way is still far above the denormals range. - Note3: The random number generator MUST be initialized for this function to work correctly. + Note3: The random number generator MUST be initialized for this function to work correctly. - Note4: These functions are thread-safe if you use one RandomState object per thread (or if you - synchronize the access to a shared state object, of course). -*/ + Note4: These functions are thread-safe if you use one RandomState object per thread (or if you + synchronize the access to a shared state object, of course). + */ -template a_type Random(a_type min, a_type max, RandomState& state = DefaultRandomState); -// function that returns a random number on the whole possible range -template a_type Random(RandomState& state = DefaultRandomState); -// Alias that can be useful too -template inline a_type RandomIE(a_type min, a_type max, RandomState& state = DefaultRandomState) {return Random(min, max, state);} -template inline a_type RandomEI(a_type min, a_type max, RandomState& state = DefaultRandomState) {return Random(min, max, state);} -template inline a_type RandomEE(a_type min, a_type max, RandomState& state = DefaultRandomState) {return Random(min, max, state);} -template inline a_type RandomII(a_type min, a_type max, RandomState& state = DefaultRandomState) {return Random(min, max, state);} + template a_type Random(a_type min, a_type max, RandomState& state = DefaultRandomState); + // function that returns a random number on the whole possible range + template a_type Random(RandomState& state = DefaultRandomState); + // Alias that can be useful too + template inline a_type RandomIE(a_type min, a_type max, RandomState& state = DefaultRandomState) { + return Random(min, max, state); + } + template inline a_type RandomEI(a_type min, a_type max, RandomState& state = DefaultRandomState) { + return Random(min, max, state); + } + template inline a_type RandomEE(a_type min, a_type max, RandomState& state = DefaultRandomState) { + return Random(min, max, state); + } + template inline a_type RandomII(a_type min, a_type max, RandomState& state = DefaultRandomState) { + return Random(min, max, state); + } #define STREFLOP_RANDOM_MAKE_REAL(a_type) \ template<> a_type Random(RandomState& state); \ template<> a_type Random(a_type min, a_type max, RandomState& state); \ @@ -127,46 +135,62 @@ template<> a_type Random(a_type min, a_type max, RandomStat template<> a_type Random(a_type min, a_type max, RandomState& state); \ template<> a_type Random(a_type min, a_type max, RandomState& state); -STREFLOP_RANDOM_MAKE_REAL(char) -STREFLOP_RANDOM_MAKE_REAL(unsigned char) -STREFLOP_RANDOM_MAKE_REAL(short) -STREFLOP_RANDOM_MAKE_REAL(unsigned short) -STREFLOP_RANDOM_MAKE_REAL(int) -STREFLOP_RANDOM_MAKE_REAL(unsigned int) -STREFLOP_RANDOM_MAKE_REAL(long) -STREFLOP_RANDOM_MAKE_REAL(unsigned long) -STREFLOP_RANDOM_MAKE_REAL(long long) -STREFLOP_RANDOM_MAKE_REAL(unsigned long long) + STREFLOP_RANDOM_MAKE_REAL(char) + STREFLOP_RANDOM_MAKE_REAL(unsigned char) + STREFLOP_RANDOM_MAKE_REAL(short) + STREFLOP_RANDOM_MAKE_REAL(unsigned short) + STREFLOP_RANDOM_MAKE_REAL(int) + STREFLOP_RANDOM_MAKE_REAL(unsigned int) + STREFLOP_RANDOM_MAKE_REAL(long) + STREFLOP_RANDOM_MAKE_REAL(unsigned long) + STREFLOP_RANDOM_MAKE_REAL(long long) + STREFLOP_RANDOM_MAKE_REAL(unsigned long long) -/** Additional and faster functions for real numbers - These return a number in the 1..2 range, the base for all the other random functions -*/ -template a_type Random12(RandomState& state = DefaultRandomState); -// Alias that can be useful too -template inline a_type Random12IE(RandomState& state = DefaultRandomState) {return Random12(state);} -template inline a_type Random12EI(RandomState& state = DefaultRandomState) {return Random12(state);} -template inline a_type Random12EE(RandomState& state = DefaultRandomState) {return Random12(state);} -template inline a_type Random12II(RandomState& state = DefaultRandomState) {return Random12(state);} + /** Additional and faster functions for real numbers + These return a number in the 1..2 range, the base for all the other random functions + */ + template a_type Random12(RandomState& state = DefaultRandomState); + // Alias that can be useful too + template inline a_type Random12IE(RandomState& state = DefaultRandomState) { + return Random12(state); + } + template inline a_type Random12EI(RandomState& state = DefaultRandomState) { + return Random12(state); + } + template inline a_type Random12EE(RandomState& state = DefaultRandomState) { + return Random12(state); + } + template inline a_type Random12II(RandomState& state = DefaultRandomState) { + return Random12(state); + } -/** Additional and faster functions for real numbers + /** Additional and faster functions for real numbers - These return a number in the 0..1 range by subtracting one to the 1..2 function - This avoids a multiplication for the min...max scaling + These return a number in the 0..1 range by subtracting one to the 1..2 function + This avoids a multiplication for the min...max scaling - Provided for convenience only, use the 1..2 range as the base random function -*/ -template inline a_type Random01(RandomState& state = DefaultRandomState) { - return Random12(state) - a_type(1.0); -} -// Alias that can be useful too -template inline a_type Random01IE(RandomState& state = DefaultRandomState) {return Random01(state);} -template inline a_type Random01EI(RandomState& state = DefaultRandomState) {return Random01(state);} -template inline a_type Random01EE(RandomState& state = DefaultRandomState) {return Random01(state);} -template inline a_type Random01II(RandomState& state = DefaultRandomState) {return Random01(state);} + Provided for convenience only, use the 1..2 range as the base random function + */ + template inline a_type Random01(RandomState& state = DefaultRandomState) { + return Random12(state) - a_type(1.0); + } + // Alias that can be useful too + template inline a_type Random01IE(RandomState& state = DefaultRandomState) { + return Random01(state); + } + template inline a_type Random01EI(RandomState& state = DefaultRandomState) { + return Random01(state); + } + template inline a_type Random01EE(RandomState& state = DefaultRandomState) { + return Random01(state); + } + template inline a_type Random01II(RandomState& state = DefaultRandomState) { + return Random01(state); + } -/// Define all 12 and 01 functions only for real types -/// use the 12 function to generate the other + /// Define all 12 and 01 functions only for real types + /// use the 12 function to generate the other #define STREFLOP_RANDOM_MAKE_REAL_FLOAT_TYPES(a_type) \ template<> a_type Random12(RandomState& state); \ @@ -192,53 +216,53 @@ template<> inline a_type Random(a_type min, a_type max, Ra } -STREFLOP_RANDOM_MAKE_REAL_FLOAT_TYPES(Simple) -STREFLOP_RANDOM_MAKE_REAL_FLOAT_TYPES(Double) + STREFLOP_RANDOM_MAKE_REAL_FLOAT_TYPES(Simple) + STREFLOP_RANDOM_MAKE_REAL_FLOAT_TYPES(Double) #if defined(Extended) -STREFLOP_RANDOM_MAKE_REAL_FLOAT_TYPES(Extended) + STREFLOP_RANDOM_MAKE_REAL_FLOAT_TYPES(Extended) #endif -/** - Utility to get a number from a Normal distribution - The no argument version returns a distribution with mean 0, variance 1. - The 2 argument version takes the desired mean standard deviation. - Both are only defined over the floating-point types + /** + Utility to get a number from a Normal distribution + The no argument version returns a distribution with mean 0, variance 1. + The 2 argument version takes the desired mean standard deviation. + Both are only defined over the floating-point types - This uses the common polar-coordinate method to transform between uniform and normal - Step 1: generate a pair of numbers in the -1,1 x -1,1 square - Step 2: loop over to step 1 until it is also in the unit circle - Step 3: Convert using the property property (U1, U2) = (X,Y) * sqrt( -2 * log(D) / D) - with D = X*X+Y*Y the squared distance and log(D) the natural logarithm function - Step 4: Choose U1 or U2, they are independent (keep the other for the next call) - Step 5 (optional): Scale and translate U to a given mean, std_dev + This uses the common polar-coordinate method to transform between uniform and normal + Step 1: generate a pair of numbers in the -1,1 x -1,1 square + Step 2: loop over to step 1 until it is also in the unit circle + Step 3: Convert using the property property (U1, U2) = (X,Y) * sqrt( -2 * log(D) / D) + with D = X*X+Y*Y the squared distance and log(D) the natural logarithm function + Step 4: Choose U1 or U2, they are independent (keep the other for the next call) + Step 5 (optional): Scale and translate U to a given mean, std_dev - There may be better numerical methods, but I'm too lazy to implement them. - Any suggestion/contribution is welcome! + There may be better numerical methods, but I'm too lazy to implement them. + Any suggestion/contribution is welcome! - In particular, it seems quite horrendous to do computations close to the 0, in the 0-1 range, - where there may be denormals and the lot, to scale and translate later on. It would be better - to compute everything in another float interval (ex: 2 to 4 centered on 3 for the same square - has a uniform representable range of floats), and only then convert to the given mean/std_dev - at the last moment. + In particular, it seems quite horrendous to do computations close to the 0, in the 0-1 range, + where there may be denormals and the lot, to scale and translate later on. It would be better + to compute everything in another float interval (ex: 2 to 4 centered on 3 for the same square + has a uniform representable range of floats), and only then convert to the given mean/std_dev + at the last moment. - Note: An optional argument "secondary" may be specified, and in that case, a second number - indepedent from the first will be returned at negligible cost (in other words, by default, half the values - are thrown away) -*/ -template a_type NRandom(a_type mean, a_type std_dev, a_type *secondary = 0, RandomState& state = DefaultRandomState); -template<> Simple NRandom(Simple mean, Simple std_dev, Simple *secondary, RandomState& state); -template<> Double NRandom(Double mean, Double std_dev, Double *secondary, RandomState& state); + Note: An optional argument "secondary" may be specified, and in that case, a second number + indepedent from the first will be returned at negligible cost (in other words, by default, half the values + are thrown away) + */ + template a_type NRandom(a_type mean, a_type std_dev, a_type *secondary = 0, RandomState& state = DefaultRandomState); + template<> Simple NRandom(Simple mean, Simple std_dev, Simple *secondary, RandomState& state); + template<> Double NRandom(Double mean, Double std_dev, Double *secondary, RandomState& state); #if defined(Extended) -template<> Extended NRandom(Extended mean, Extended std_dev, Extended *secondary, RandomState& state); + template<> Extended NRandom(Extended mean, Extended std_dev, Extended *secondary, RandomState& state); #endif -/// Simplified versions -template a_type NRandom(a_type *secondary = 0, RandomState& state = DefaultRandomState); -template<> Simple NRandom(Simple *secondary, RandomState& state); -template<> Double NRandom(Double *secondary, RandomState& state); + /// Simplified versions + template a_type NRandom(a_type *secondary = 0, RandomState& state = DefaultRandomState); + template<> Simple NRandom(Simple *secondary, RandomState& state); + template<> Double NRandom(Double *secondary, RandomState& state); #if defined(Extended) -template<> Extended NRandom(Extended *secondary, RandomState& state); + template<> Extended NRandom(Extended *secondary, RandomState& state); #endif } diff --git a/source/shared_lib/include/streflop/SMath.h b/source/shared_lib/include/streflop/SMath.h index e6f136084..549caa231 100644 --- a/source/shared_lib/include/streflop/SMath.h +++ b/source/shared_lib/include/streflop/SMath.h @@ -1,7 +1,7 @@ /* streflop: STandalone REproducible FLOating-Point - Copyright 2006 Nicolas Brodu - 2010 Mark Vejvoda + Copyright 2006 Nicolas Brodu + 2010 Mark Vejvoda Code released according to the GNU Lesser General Public License @@ -23,10 +23,10 @@ // Names from the libm conversion namespace streflop_libm { -using streflop::Simple; -using streflop::Double; + using streflop::Simple; + using streflop::Double; #ifdef Extended -using streflop::Extended; + using streflop::Extended; #endif extern Simple __ieee754_sqrtf(Simple x); @@ -203,94 +203,211 @@ using streflop::Extended; // Wrappers in our own namespace namespace streflop { -// Stolen from math.h. All floating-point numbers can be put in one of these categories. -enum -{ - STREFLOP_FP_NAN = 0, - STREFLOP_FP_INFINITE = 1, - STREFLOP_FP_ZERO = 2, - STREFLOP_FP_SUBNORMAL = 3, - STREFLOP_FP_NORMAL = 4 -}; + // Stolen from math.h. All floating-point numbers can be put in one of these categories. + enum { + STREFLOP_FP_NAN = 0, + STREFLOP_FP_INFINITE = 1, + STREFLOP_FP_ZERO = 2, + STREFLOP_FP_SUBNORMAL = 3, + STREFLOP_FP_NORMAL = 4 + }; -// Simple and double are present in all configurations + // Simple and double are present in all configurations - inline Simple sqrt(Simple x) {return streflop_libm::__ieee754_sqrtf(x);} - inline Simple cbrt(Simple x) {return streflop_libm::__cbrtf(x);} - inline Simple hypot(Simple x, Simple y) {return streflop_libm::__ieee754_hypotf(x,y);} + inline Simple sqrt(Simple x) { + return streflop_libm::__ieee754_sqrtf(x); + } + inline Simple cbrt(Simple x) { + return streflop_libm::__cbrtf(x); + } + inline Simple hypot(Simple x, Simple y) { + return streflop_libm::__ieee754_hypotf(x, y); + } - inline Simple exp(Simple x) {return streflop_libm::__ieee754_expf(x);} - inline Simple log(Simple x) {return streflop_libm::__ieee754_logf(x);} - inline Simple log2(Simple x) {return streflop_libm::__ieee754_log2f(x);} - inline Simple exp2(Simple x) {return streflop_libm::__ieee754_exp2f(x);} - inline Simple log10(Simple x) {return streflop_libm::__ieee754_log10f(x);} - inline Simple pow(Simple x, Simple y) {return streflop_libm::__ieee754_powf(x,y);} + inline Simple exp(Simple x) { + return streflop_libm::__ieee754_expf(x); + } + inline Simple log(Simple x) { + return streflop_libm::__ieee754_logf(x); + } + inline Simple log2(Simple x) { + return streflop_libm::__ieee754_log2f(x); + } + inline Simple exp2(Simple x) { + return streflop_libm::__ieee754_exp2f(x); + } + inline Simple log10(Simple x) { + return streflop_libm::__ieee754_log10f(x); + } + inline Simple pow(Simple x, Simple y) { + return streflop_libm::__ieee754_powf(x, y); + } - inline Simple sin(Simple x) {return streflop_libm::__sinf(x);} - inline Simple cos(Simple x) {return streflop_libm::__cosf(x);} - inline Simple tan(Simple x) {return streflop_libm::__tanf(x);} - inline Simple acos(Simple x) {return streflop_libm::__ieee754_acosf(x);} - inline Simple asin(Simple x) {return streflop_libm::__ieee754_asinf(x);} - inline Simple atan(Simple x) {return streflop_libm::__atanf(x);} - inline Simple atan2(Simple x, Simple y) {return streflop_libm::__ieee754_atan2f(x,y);} + inline Simple sin(Simple x) { + return streflop_libm::__sinf(x); + } + inline Simple cos(Simple x) { + return streflop_libm::__cosf(x); + } + inline Simple tan(Simple x) { + return streflop_libm::__tanf(x); + } + inline Simple acos(Simple x) { + return streflop_libm::__ieee754_acosf(x); + } + inline Simple asin(Simple x) { + return streflop_libm::__ieee754_asinf(x); + } + inline Simple atan(Simple x) { + return streflop_libm::__atanf(x); + } + inline Simple atan2(Simple x, Simple y) { + return streflop_libm::__ieee754_atan2f(x, y); + } - inline Simple cosh(Simple x) {return streflop_libm::__ieee754_coshf(x);} - inline Simple sinh(Simple x) {return streflop_libm::__ieee754_sinhf(x);} - inline Simple tanh(Simple x) {return streflop_libm::__tanhf(x);} - inline Simple acosh(Simple x) {return streflop_libm::__ieee754_acoshf(x);} - inline Simple asinh(Simple x) {return streflop_libm::__asinhf(x);} - inline Simple atanh(Simple x) {return streflop_libm::__ieee754_atanhf(x);} + inline Simple cosh(Simple x) { + return streflop_libm::__ieee754_coshf(x); + } + inline Simple sinh(Simple x) { + return streflop_libm::__ieee754_sinhf(x); + } + inline Simple tanh(Simple x) { + return streflop_libm::__tanhf(x); + } + inline Simple acosh(Simple x) { + return streflop_libm::__ieee754_acoshf(x); + } + inline Simple asinh(Simple x) { + return streflop_libm::__asinhf(x); + } + inline Simple atanh(Simple x) { + return streflop_libm::__ieee754_atanhf(x); + } - inline Simple fabs(Simple x) {return streflop_libm::__fabsf(x);} - inline Simple floor(Simple x) {return streflop_libm::__floorf(x);} - inline Simple ceil(Simple x) {return streflop_libm::__ceilf(x);} - inline Simple trunc(Simple x) {return streflop_libm::__truncf(x);} - inline Simple fmod(Simple x, Simple y) {return streflop_libm::__ieee754_fmodf(x,y);} - inline Simple remainder(Simple x, Simple y) {return streflop_libm::__ieee754_remainderf(x,y);} - inline Simple remquo(Simple x, Simple y, int *quo) {return streflop_libm::__remquof(x,y,quo);} - inline Simple rint(Simple x) {return streflop_libm::__rintf(x);} - inline long int lrint(Simple x) {return streflop_libm::__lrintf(x);} - inline long long int llrint(Simple x) {return streflop_libm::__llrintf(x);} - inline Simple round(Simple x) {return streflop_libm::__roundf(x);} - inline long int lround(Simple x) {return streflop_libm::__lroundf(x);} - inline long long int llround(Simple x) {return streflop_libm::__llroundf(x);} - inline Simple nearbyint(Simple x) {return streflop_libm::__nearbyintf(x);} + inline Simple fabs(Simple x) { + return streflop_libm::__fabsf(x); + } + inline Simple floor(Simple x) { + return streflop_libm::__floorf(x); + } + inline Simple ceil(Simple x) { + return streflop_libm::__ceilf(x); + } + inline Simple trunc(Simple x) { + return streflop_libm::__truncf(x); + } + inline Simple fmod(Simple x, Simple y) { + return streflop_libm::__ieee754_fmodf(x, y); + } + inline Simple remainder(Simple x, Simple y) { + return streflop_libm::__ieee754_remainderf(x, y); + } + inline Simple remquo(Simple x, Simple y, int *quo) { + return streflop_libm::__remquof(x, y, quo); + } + inline Simple rint(Simple x) { + return streflop_libm::__rintf(x); + } + inline long int lrint(Simple x) { + return streflop_libm::__lrintf(x); + } + inline long long int llrint(Simple x) { + return streflop_libm::__llrintf(x); + } + inline Simple round(Simple x) { + return streflop_libm::__roundf(x); + } + inline long int lround(Simple x) { + return streflop_libm::__lroundf(x); + } + inline long long int llround(Simple x) { + return streflop_libm::__llroundf(x); + } + inline Simple nearbyint(Simple x) { + return streflop_libm::__nearbyintf(x); + } - inline Simple frexp(Simple x, int *exp) {return streflop_libm::__frexpf(x,exp);} - inline Simple ldexp(Simple value, int exp) {return streflop_libm::__ldexpf(value,exp);} - inline Simple logb(Simple x) {return streflop_libm::__logbf(x);} - inline int ilogb(Simple x) {return streflop_libm::__ilogbf(x);} - inline Simple copysign(Simple x) {return streflop_libm::__copysignf(x);} + inline Simple frexp(Simple x, int *exp) { + return streflop_libm::__frexpf(x, exp); + } + inline Simple ldexp(Simple value, int exp) { + return streflop_libm::__ldexpf(value, exp); + } + inline Simple logb(Simple x) { + return streflop_libm::__logbf(x); + } + inline int ilogb(Simple x) { + return streflop_libm::__ilogbf(x); + } + inline Simple copysign(Simple x) { + return streflop_libm::__copysignf(x); + } #undef signbit - inline int signbit (Simple x) {return streflop_libm::__signbitf(x);} - inline Simple nextafter(Simple x, Simple y) {return streflop_libm::__nextafterf(x,y);} + inline int signbit(Simple x) { + return streflop_libm::__signbitf(x); + } + inline Simple nextafter(Simple x, Simple y) { + return streflop_libm::__nextafterf(x, y); + } - inline Simple expm1(Simple x) {return streflop_libm::__expm1f(x);} - inline Simple log1p(Simple x) {return streflop_libm::__log1pf(x);} - inline Simple erf(Simple x) {return streflop_libm::__erff(x);} - inline Simple j0(Simple x) {return streflop_libm::__ieee754_j0f(x);} - inline Simple j1(Simple x) {return streflop_libm::__ieee754_j1f(x);} - inline Simple jn(int n, Simple x) {return streflop_libm::__ieee754_jnf(n,x);} - inline Simple y0(Simple x) {return streflop_libm::__ieee754_y0f(x);} - inline Simple y1(Simple x) {return streflop_libm::__ieee754_y1f(x);} - inline Simple yn(int n, Simple x) {return streflop_libm::__ieee754_ynf(n,x);} - inline Simple scalbn(Simple x, int n) {return streflop_libm::__scalbnf(x,n);} - inline Simple scalbln(Simple x, long int n) {return streflop_libm::__scalblnf(x,n);} + inline Simple expm1(Simple x) { + return streflop_libm::__expm1f(x); + } + inline Simple log1p(Simple x) { + return streflop_libm::__log1pf(x); + } + inline Simple erf(Simple x) { + return streflop_libm::__erff(x); + } + inline Simple j0(Simple x) { + return streflop_libm::__ieee754_j0f(x); + } + inline Simple j1(Simple x) { + return streflop_libm::__ieee754_j1f(x); + } + inline Simple jn(int n, Simple x) { + return streflop_libm::__ieee754_jnf(n, x); + } + inline Simple y0(Simple x) { + return streflop_libm::__ieee754_y0f(x); + } + inline Simple y1(Simple x) { + return streflop_libm::__ieee754_y1f(x); + } + inline Simple yn(int n, Simple x) { + return streflop_libm::__ieee754_ynf(n, x); + } + inline Simple scalbn(Simple x, int n) { + return streflop_libm::__scalbnf(x, n); + } + inline Simple scalbln(Simple x, long int n) { + return streflop_libm::__scalblnf(x, n); + } #undef fpclassify - inline int fpclassify(Simple x) {return streflop_libm::__fpclassifyf(x);} + inline int fpclassify(Simple x) { + return streflop_libm::__fpclassifyf(x); + } #undef isnan - inline int isnan(Simple x) {return streflop_libm::__isnanf(x);} + inline int isnan(Simple x) { + return streflop_libm::__isnanf(x); + } #undef isinf - inline int isinf(Simple x) {return streflop_libm::__isinff(x);} + inline int isinf(Simple x) { + return streflop_libm::__isinff(x); + } #undef isfinite - inline int isfinite(Simple x) {return !(isnan(x) || isinf(x));} + inline int isfinite(Simple x) { + return !(isnan(x) || isinf(x)); + } // Stolen from math.h and inlined instead of macroized. // Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ #undef isnormal - inline int isnormal(Simple x) {return fpclassify(x) == STREFLOP_FP_NORMAL;} + inline int isnormal(Simple x) { + return fpclassify(x) == STREFLOP_FP_NORMAL; + } // Constants user may set extern const Simple SimplePositiveInfinity; @@ -315,184 +432,432 @@ enum #undef isgreater #endif // defined isgreater inline bool isgreater(Simple x, Simple y) { - return (!isunordered(x,y)) && (x > y); + return (!isunordered(x, y)) && (x > y); } #if defined isgreaterequal #undef isgreaterequal #endif // defined isgreaterequal inline bool isgreaterequal(Simple x, Simple y) { - return (!isunordered(x,y)) && (x >= y); + return (!isunordered(x, y)) && (x >= y); } #if defined isless #undef isless #endif // defined isless inline bool isless(Simple x, Simple y) { - return (!isunordered(x,y)) && (x < y); + return (!isunordered(x, y)) && (x < y); } #if defined islessequal #undef islessequal #endif // defined islessequal inline bool islessequal(Simple x, Simple y) { - return (!isunordered(x,y)) && (x <= y); + return (!isunordered(x, y)) && (x <= y); } #if defined islessgreater #undef islessgreater #endif // defined islessgreater inline bool islessgreater(Simple x, Simple y) { - return (!isunordered(x,y)) && ((x < y) || (x > y)); + return (!isunordered(x, y)) && ((x < y) || (x > y)); } -// Add xxxf alias to ease porting existing code to streflop -// Additionally, using xxxf(number) avoids potential confusion + // Add xxxf alias to ease porting existing code to streflop + // Additionally, using xxxf(number) avoids potential confusion - inline Simple sqrtf(Simple x) {return sqrt(x);} - inline Simple cbrtf(Simple x) {return cbrt(x);} - inline Simple hypotf(Simple x, Simple y) {return hypot(x, y);} + inline Simple sqrtf(Simple x) { + return sqrt(x); + } + inline Simple cbrtf(Simple x) { + return cbrt(x); + } + inline Simple hypotf(Simple x, Simple y) { + return hypot(x, y); + } - inline Simple expf(Simple x) {return exp(x);} - inline Simple logf(Simple x) {return log(x);} - inline Simple log2f(Simple x) {return log2(x);} - inline Simple exp2f(Simple x) {return exp2(x);} - inline Simple log10f(Simple x) {return log10(x);} - inline Simple powf(Simple x, Simple y) {return pow(x, y);} + inline Simple expf(Simple x) { + return exp(x); + } + inline Simple logf(Simple x) { + return log(x); + } + inline Simple log2f(Simple x) { + return log2(x); + } + inline Simple exp2f(Simple x) { + return exp2(x); + } + inline Simple log10f(Simple x) { + return log10(x); + } + inline Simple powf(Simple x, Simple y) { + return pow(x, y); + } - inline Simple sinf(Simple x) {return sin(x);} - inline Simple cosf(Simple x) {return cos(x);} - inline Simple tanf(Simple x) {return tan(x);} - inline Simple acosf(Simple x) {return acos(x);} - inline Simple asinf(Simple x) {return asin(x);} - inline Simple atanf(Simple x) {return atan(x);} - inline Simple atan2f(Simple x, Simple y) {return atan2(x, y);} + inline Simple sinf(Simple x) { + return sin(x); + } + inline Simple cosf(Simple x) { + return cos(x); + } + inline Simple tanf(Simple x) { + return tan(x); + } + inline Simple acosf(Simple x) { + return acos(x); + } + inline Simple asinf(Simple x) { + return asin(x); + } + inline Simple atanf(Simple x) { + return atan(x); + } + inline Simple atan2f(Simple x, Simple y) { + return atan2(x, y); + } - inline Simple coshf(Simple x) {return cosh(x);} - inline Simple sinhf(Simple x) {return sinh(x);} - inline Simple tanhf(Simple x) {return tanh(x);} - inline Simple acoshf(Simple x) {return acosh(x);} - inline Simple asinhf(Simple x) {return asinh(x);} - inline Simple atanhf(Simple x) {return atanh(x);} + inline Simple coshf(Simple x) { + return cosh(x); + } + inline Simple sinhf(Simple x) { + return sinh(x); + } + inline Simple tanhf(Simple x) { + return tanh(x); + } + inline Simple acoshf(Simple x) { + return acosh(x); + } + inline Simple asinhf(Simple x) { + return asinh(x); + } + inline Simple atanhf(Simple x) { + return atanh(x); + } - inline Simple fabsf(Simple x) {return fabs(x);} - inline Simple floorf(Simple x) {return floor(x);} - inline Simple ceilf(Simple x) {return ceil(x);} - inline Simple truncf(Simple x) {return trunc(x);} - inline Simple fmodf(Simple x, Simple y) {return fmod(x,y);} - inline Simple remainderf(Simple x, Simple y) {return remainder(x,y);} - inline Simple remquof(Simple x, Simple y, int *quo) {return remquo(x, y, quo);} - inline Simple rintf(Simple x) {return rint(x);} - inline long int lrintf(Simple x) {return lrint(x);} - inline long long int llrintf(Simple x) {return llrint(x);} - inline Simple roundf(Simple x) {return round(x);} - inline long int lroundf(Simple x) {return lround(x);} - inline long long int llroundf(Simple x) {return llround(x);} - inline Simple nearbyintf(Simple x) {return nearbyint(x);} + inline Simple fabsf(Simple x) { + return fabs(x); + } + inline Simple floorf(Simple x) { + return floor(x); + } + inline Simple ceilf(Simple x) { + return ceil(x); + } + inline Simple truncf(Simple x) { + return trunc(x); + } + inline Simple fmodf(Simple x, Simple y) { + return fmod(x, y); + } + inline Simple remainderf(Simple x, Simple y) { + return remainder(x, y); + } + inline Simple remquof(Simple x, Simple y, int *quo) { + return remquo(x, y, quo); + } + inline Simple rintf(Simple x) { + return rint(x); + } + inline long int lrintf(Simple x) { + return lrint(x); + } + inline long long int llrintf(Simple x) { + return llrint(x); + } + inline Simple roundf(Simple x) { + return round(x); + } + inline long int lroundf(Simple x) { + return lround(x); + } + inline long long int llroundf(Simple x) { + return llround(x); + } + inline Simple nearbyintf(Simple x) { + return nearbyint(x); + } - inline Simple frexpf(Simple x, int *exp) {return frexp(x, exp);} - inline Simple ldexpf(Simple value, int exp) {return ldexp(value,exp);} - inline Simple logbf(Simple x) {return logb(x);} - inline int ilogbf(Simple x) {return ilogb(x);} - inline Simple copysignf(Simple x) {return copysign(x);} - inline int signbitf(Simple x) {return signbit(x);} - inline Simple nextafterf(Simple x, Simple y) {return nextafter(x, y);} + inline Simple frexpf(Simple x, int *exp) { + return frexp(x, exp); + } + inline Simple ldexpf(Simple value, int exp) { + return ldexp(value, exp); + } + inline Simple logbf(Simple x) { + return logb(x); + } + inline int ilogbf(Simple x) { + return ilogb(x); + } + inline Simple copysignf(Simple x) { + return copysign(x); + } + inline int signbitf(Simple x) { + return signbit(x); + } + inline Simple nextafterf(Simple x, Simple y) { + return nextafter(x, y); + } - inline Simple expm1f(Simple x) {return expm1(x);} - inline Simple log1pf(Simple x) {return log1p(x);} - inline Simple erff(Simple x) {return erf(x);} - inline Simple j0f(Simple x) {return j0(x);} - inline Simple j1f(Simple x) {return j1(x);} - inline Simple jnf(int n, Simple x) {return jn(n, x);} - inline Simple y0f(Simple x) {return y0(x);} - inline Simple y1f(Simple x) {return y1(x);} - inline Simple ynf(int n, Simple x) {return yn(n, x);} - inline Simple scalbnf(Simple x, int n) {return scalbn(x, n);} - inline Simple scalblnf(Simple x, long int n) {return scalbln(x, n);} + inline Simple expm1f(Simple x) { + return expm1(x); + } + inline Simple log1pf(Simple x) { + return log1p(x); + } + inline Simple erff(Simple x) { + return erf(x); + } + inline Simple j0f(Simple x) { + return j0(x); + } + inline Simple j1f(Simple x) { + return j1(x); + } + inline Simple jnf(int n, Simple x) { + return jn(n, x); + } + inline Simple y0f(Simple x) { + return y0(x); + } + inline Simple y1f(Simple x) { + return y1(x); + } + inline Simple ynf(int n, Simple x) { + return yn(n, x); + } + inline Simple scalbnf(Simple x, int n) { + return scalbn(x, n); + } + inline Simple scalblnf(Simple x, long int n) { + return scalbln(x, n); + } - inline int fpclassifyf(Simple x) {return fpclassify(x);} - inline int isnanf(Simple x) {return isnan(x);} - inline int isinff(Simple x) {return isinf(x);} - inline int isfinitef(Simple x) {return isfinite(x);} - inline int isnormalf(Simple x) {return isnormal(x);} + inline int fpclassifyf(Simple x) { + return fpclassify(x); + } + inline int isnanf(Simple x) { + return isnan(x); + } + inline int isinff(Simple x) { + return isinf(x); + } + inline int isfinitef(Simple x) { + return isfinite(x); + } + inline int isnormalf(Simple x) { + return isnormal(x); + } - inline bool isunorderedf(Simple x, Simple y) {return isunordered(x, y);} - inline bool isgreaterf(Simple x, Simple y) {return isgreater(x, y);} - inline bool isgreaterequalf(Simple x, Simple y) {return isgreaterequalf(x, y);} - inline bool islessf(Simple x, Simple y) {return isless(x, y);} - inline bool islessequalf(Simple x, Simple y) {return islessequal(x, y);} - inline bool islessgreaterf(Simple x, Simple y) {return islessgreater(x, y);} + inline bool isunorderedf(Simple x, Simple y) { + return isunordered(x, y); + } + inline bool isgreaterf(Simple x, Simple y) { + return isgreater(x, y); + } + inline bool isgreaterequalf(Simple x, Simple y) { + return isgreaterequalf(x, y); + } + inline bool islessf(Simple x, Simple y) { + return isless(x, y); + } + inline bool islessequalf(Simple x, Simple y) { + return islessequal(x, y); + } + inline bool islessgreaterf(Simple x, Simple y) { + return islessgreater(x, y); + } -// Declare Double functions -// Simple and double are present in all configurations + // Declare Double functions + // Simple and double are present in all configurations - inline Double sqrt(Double x) {return streflop_libm::__ieee754_sqrt(x);} - inline Double cbrt(Double x) {return streflop_libm::__cbrt(x);} - inline Double hypot(Double x, Double y) {return streflop_libm::__ieee754_hypot(x,y);} + inline Double sqrt(Double x) { + return streflop_libm::__ieee754_sqrt(x); + } + inline Double cbrt(Double x) { + return streflop_libm::__cbrt(x); + } + inline Double hypot(Double x, Double y) { + return streflop_libm::__ieee754_hypot(x, y); + } - inline Double exp(Double x) {return streflop_libm::__ieee754_exp(x);} - inline Double log(Double x) {return streflop_libm::__ieee754_log(x);} - inline Double log2(Double x) {return streflop_libm::__ieee754_log2(x);} - inline Double exp2(Double x) {return streflop_libm::__ieee754_exp2(x);} - inline Double log10(Double x) {return streflop_libm::__ieee754_log10(x);} - inline Double pow(Double x, Double y) {return streflop_libm::__ieee754_pow(x,y);} + inline Double exp(Double x) { + return streflop_libm::__ieee754_exp(x); + } + inline Double log(Double x) { + return streflop_libm::__ieee754_log(x); + } + inline Double log2(Double x) { + return streflop_libm::__ieee754_log2(x); + } + inline Double exp2(Double x) { + return streflop_libm::__ieee754_exp2(x); + } + inline Double log10(Double x) { + return streflop_libm::__ieee754_log10(x); + } + inline Double pow(Double x, Double y) { + return streflop_libm::__ieee754_pow(x, y); + } - inline Double sin(Double x) {return streflop_libm::__sin(x);} - inline Double cos(Double x) {return streflop_libm::__cos(x);} - inline Double tan(Double x) {return streflop_libm::tan(x);} - inline Double acos(Double x) {return streflop_libm::__ieee754_acos(x);} - inline Double asin(Double x) {return streflop_libm::__ieee754_asin(x);} - inline Double atan(Double x) {return streflop_libm::atan(x);} - inline Double atan2(Double x, Double y) {return streflop_libm::__ieee754_atan2(x,y);} + inline Double sin(Double x) { + return streflop_libm::__sin(x); + } + inline Double cos(Double x) { + return streflop_libm::__cos(x); + } + inline Double tan(Double x) { + return streflop_libm::tan(x); + } + inline Double acos(Double x) { + return streflop_libm::__ieee754_acos(x); + } + inline Double asin(Double x) { + return streflop_libm::__ieee754_asin(x); + } + inline Double atan(Double x) { + return streflop_libm::atan(x); + } + inline Double atan2(Double x, Double y) { + return streflop_libm::__ieee754_atan2(x, y); + } - inline Double cosh(Double x) {return streflop_libm::__ieee754_cosh(x);} - inline Double sinh(Double x) {return streflop_libm::__ieee754_sinh(x);} - inline Double tanh(Double x) {return streflop_libm::__tanh(x);} - inline Double acosh(Double x) {return streflop_libm::__ieee754_acosh(x);} - inline Double asinh(Double x) {return streflop_libm::__asinh(x);} - inline Double atanh(Double x) {return streflop_libm::__ieee754_atanh(x);} + inline Double cosh(Double x) { + return streflop_libm::__ieee754_cosh(x); + } + inline Double sinh(Double x) { + return streflop_libm::__ieee754_sinh(x); + } + inline Double tanh(Double x) { + return streflop_libm::__tanh(x); + } + inline Double acosh(Double x) { + return streflop_libm::__ieee754_acosh(x); + } + inline Double asinh(Double x) { + return streflop_libm::__asinh(x); + } + inline Double atanh(Double x) { + return streflop_libm::__ieee754_atanh(x); + } - inline Double fabs(Double x) {return streflop_libm::__fabs(x);} - inline Double floor(Double x) {return streflop_libm::__floor(x);} - inline Double ceil(Double x) {return streflop_libm::__ceil(x);} - inline Double trunc(Double x) {return streflop_libm::__trunc(x);} - inline Double fmod(Double x, Double y) {return streflop_libm::__ieee754_fmod(x,y);} - inline Double remainder(Double x, Double y) {return streflop_libm::__ieee754_remainder(x,y);} - inline Double remquo(Double x, Double y, int *quo) {return streflop_libm::__remquo(x,y,quo);} - inline Double rint(Double x) {return streflop_libm::__rint(x);} - inline long int lrint(Double x) {return streflop_libm::__lrint(x);} - inline long long int llrint(Double x) {return streflop_libm::__llrint(x);} - inline Double round(Double x) {return streflop_libm::__round(x);} - inline long int lround(Double x) {return streflop_libm::__lround(x);} - inline long long int llround(Double x) {return streflop_libm::__llround(x);} - inline Double nearbyint(Double x) {return streflop_libm::__nearbyint(x);} + inline Double fabs(Double x) { + return streflop_libm::__fabs(x); + } + inline Double floor(Double x) { + return streflop_libm::__floor(x); + } + inline Double ceil(Double x) { + return streflop_libm::__ceil(x); + } + inline Double trunc(Double x) { + return streflop_libm::__trunc(x); + } + inline Double fmod(Double x, Double y) { + return streflop_libm::__ieee754_fmod(x, y); + } + inline Double remainder(Double x, Double y) { + return streflop_libm::__ieee754_remainder(x, y); + } + inline Double remquo(Double x, Double y, int *quo) { + return streflop_libm::__remquo(x, y, quo); + } + inline Double rint(Double x) { + return streflop_libm::__rint(x); + } + inline long int lrint(Double x) { + return streflop_libm::__lrint(x); + } + inline long long int llrint(Double x) { + return streflop_libm::__llrint(x); + } + inline Double round(Double x) { + return streflop_libm::__round(x); + } + inline long int lround(Double x) { + return streflop_libm::__lround(x); + } + inline long long int llround(Double x) { + return streflop_libm::__llround(x); + } + inline Double nearbyint(Double x) { + return streflop_libm::__nearbyint(x); + } - inline Double frexp(Double x, int *exp) {return streflop_libm::__frexp(x, exp);} - inline Double ldexp(Double value, int exp) {return streflop_libm::__ldexp(value,exp);} - inline Double logb(Double x) {return streflop_libm::__logb(x);} - inline int ilogb(Double x) {return streflop_libm::__ilogb(x);} - inline Double copysign(Double x) {return streflop_libm::__copysign(x);} - inline int signbit(Double x) {return streflop_libm::__signbit(x);} - inline Double nextafter(Double x, Double y) {return streflop_libm::__nextafter(x,y);} + inline Double frexp(Double x, int *exp) { + return streflop_libm::__frexp(x, exp); + } + inline Double ldexp(Double value, int exp) { + return streflop_libm::__ldexp(value, exp); + } + inline Double logb(Double x) { + return streflop_libm::__logb(x); + } + inline int ilogb(Double x) { + return streflop_libm::__ilogb(x); + } + inline Double copysign(Double x) { + return streflop_libm::__copysign(x); + } + inline int signbit(Double x) { + return streflop_libm::__signbit(x); + } + inline Double nextafter(Double x, Double y) { + return streflop_libm::__nextafter(x, y); + } - inline Double expm1(Double x) {return streflop_libm::__expm1(x);} - inline Double log1p(Double x) {return streflop_libm::__log1p(x);} - inline Double erf(Double x) {return streflop_libm::__erf(x);} - inline Double j0(Double x) {return streflop_libm::__ieee754_j0(x);} - inline Double j1(Double x) {return streflop_libm::__ieee754_j1(x);} - inline Double jn(int n, Double x) {return streflop_libm::__ieee754_jn(n,x);} - inline Double y0(Double x) {return streflop_libm::__ieee754_y0(x);} - inline Double y1(Double x) {return streflop_libm::__ieee754_y1(x);} - inline Double yn(int n, Double x) {return streflop_libm::__ieee754_yn(n,x);} - inline Double scalbn(Double x, int n) {return streflop_libm::__scalbn(x,n);} - inline Double scalbln(Double x, long int n) {return streflop_libm::__scalbln(x,n);} + inline Double expm1(Double x) { + return streflop_libm::__expm1(x); + } + inline Double log1p(Double x) { + return streflop_libm::__log1p(x); + } + inline Double erf(Double x) { + return streflop_libm::__erf(x); + } + inline Double j0(Double x) { + return streflop_libm::__ieee754_j0(x); + } + inline Double j1(Double x) { + return streflop_libm::__ieee754_j1(x); + } + inline Double jn(int n, Double x) { + return streflop_libm::__ieee754_jn(n, x); + } + inline Double y0(Double x) { + return streflop_libm::__ieee754_y0(x); + } + inline Double y1(Double x) { + return streflop_libm::__ieee754_y1(x); + } + inline Double yn(int n, Double x) { + return streflop_libm::__ieee754_yn(n, x); + } + inline Double scalbn(Double x, int n) { + return streflop_libm::__scalbn(x, n); + } + inline Double scalbln(Double x, long int n) { + return streflop_libm::__scalbln(x, n); + } - inline int fpclassify(Double x) {return streflop_libm::__fpclassify(x);} - inline int isnan(Double x) {return streflop_libm::__isnanl(x);} - inline int isinf(Double x) {return streflop_libm::__isinf(x);} - inline int isfinite(Double x) {return !(isnan(x) || isinf(x));} + inline int fpclassify(Double x) { + return streflop_libm::__fpclassify(x); + } + inline int isnan(Double x) { + return streflop_libm::__isnanl(x); + } + inline int isinf(Double x) { + return streflop_libm::__isinf(x); + } + inline int isfinite(Double x) { + return !(isnan(x) || isinf(x)); + } // Stolen from math.h and inlined instead of macroized. // Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ - inline int isnormal(Double x) {return fpclassify(x) == STREFLOP_FP_NORMAL;} + inline int isnormal(Double x) { + return fpclassify(x) == STREFLOP_FP_NORMAL; + } // Constants user may set extern const Double DoublePositiveInfinity; @@ -508,102 +873,220 @@ enum Defined as inlined for each type, thanks to C++ overloading */ inline bool isunordered(Double x, Double y) { - return (fpclassify(x) == STREFLOP_FP_NAN) || (fpclassify (y) == STREFLOP_FP_NAN); + return (fpclassify(x) == STREFLOP_FP_NAN) || (fpclassify(y) == STREFLOP_FP_NAN); } inline bool isgreater(Double x, Double y) { - return (!isunordered(x,y)) && (x > y); + return (!isunordered(x, y)) && (x > y); } inline bool isgreaterequal(Double x, Double y) { - return (!isunordered(x,y)) && (x >= y); + return (!isunordered(x, y)) && (x >= y); } inline bool isless(Double x, Double y) { - return (!isunordered(x,y)) && (x < y); + return (!isunordered(x, y)) && (x < y); } inline bool islessequal(Double x, Double y) { - return (!isunordered(x,y)) && (x <= y); + return (!isunordered(x, y)) && (x <= y); } inline bool islessgreater(Double x, Double y) { - return (!isunordered(x,y)) && ((x < y) || (x > y)); + return (!isunordered(x, y)) && ((x < y) || (x > y)); } -// Extended are not always available + // Extended are not always available #ifdef Extended - inline Extended cbrt(Extended x) {return streflop_libm::__cbrtl(x);} - inline Extended hypot(Extended x, Extended y) {return streflop_libm::__ieee754_hypotl(x,y);} + inline Extended cbrt(Extended x) { + return streflop_libm::__cbrtl(x); + } + inline Extended hypot(Extended x, Extended y) { + return streflop_libm::__ieee754_hypotl(x, y); + } -// Missing from libm: temporarily switch to Double and execute the Double version, -// then switch back to Extended and return the result - inline Extended sqrt(Extended x) {streflop_init(); Double res = sqrt(Double(x)); streflop_init(); return Extended(res);} + // Missing from libm: temporarily switch to Double and execute the Double version, + // then switch back to Extended and return the result + inline Extended sqrt(Extended x) { + streflop_init(); Double res = sqrt(Double(x)); streflop_init(); return Extended(res); + } - inline Extended exp(Extended x) {streflop_init(); Double res = exp(Double(x)); streflop_init(); return Extended(res);} - inline Extended log(Extended x) {streflop_init(); Double res = log(Double(x)); streflop_init(); return Extended(res);} - inline Extended log2(Extended x) {streflop_init(); Double res = log2(Double(x)); streflop_init(); return Extended(res);} - inline Extended exp2(Extended x) {streflop_init(); Double res = exp2(Double(x)); streflop_init(); return Extended(res);} - inline Extended log10(Extended x) {streflop_init(); Double res = log10(Double(x)); streflop_init(); return Extended(res);} - inline Extended pow(Extended x, Extended y) {streflop_init(); Double res = pow(Double(x), Double(y)); streflop_init(); return Extended(res);} - inline Extended sin(Extended x) {streflop_init(); Double res = sin(Double(x)); streflop_init(); return Extended(res);} - inline Extended cos(Extended x) {streflop_init(); Double res = cos(Double(x)); streflop_init(); return Extended(res);} - inline Extended tan(Extended x) {streflop_init(); Double res = tan(Double(x)); streflop_init(); return Extended(res);} - inline Extended acos(Extended x) {streflop_init(); Double res = acos(Double(x)); streflop_init(); return Extended(res);} - inline Extended asin(Extended x) {streflop_init(); Double res = asin(Double(x)); streflop_init(); return Extended(res);} - inline Extended atan(Extended x) {streflop_init(); Double res = atan(Double(x)); streflop_init(); return Extended(res);} - inline Extended atan2(Extended x, Extended y) {streflop_init(); Double res = atan2(Double(x), Double(y)); streflop_init(); return Extended(res);} + inline Extended exp(Extended x) { + streflop_init(); Double res = exp(Double(x)); streflop_init(); return Extended(res); + } + inline Extended log(Extended x) { + streflop_init(); Double res = log(Double(x)); streflop_init(); return Extended(res); + } + inline Extended log2(Extended x) { + streflop_init(); Double res = log2(Double(x)); streflop_init(); return Extended(res); + } + inline Extended exp2(Extended x) { + streflop_init(); Double res = exp2(Double(x)); streflop_init(); return Extended(res); + } + inline Extended log10(Extended x) { + streflop_init(); Double res = log10(Double(x)); streflop_init(); return Extended(res); + } + inline Extended pow(Extended x, Extended y) { + streflop_init(); Double res = pow(Double(x), Double(y)); streflop_init(); return Extended(res); + } + inline Extended sin(Extended x) { + streflop_init(); Double res = sin(Double(x)); streflop_init(); return Extended(res); + } + inline Extended cos(Extended x) { + streflop_init(); Double res = cos(Double(x)); streflop_init(); return Extended(res); + } + inline Extended tan(Extended x) { + streflop_init(); Double res = tan(Double(x)); streflop_init(); return Extended(res); + } + inline Extended acos(Extended x) { + streflop_init(); Double res = acos(Double(x)); streflop_init(); return Extended(res); + } + inline Extended asin(Extended x) { + streflop_init(); Double res = asin(Double(x)); streflop_init(); return Extended(res); + } + inline Extended atan(Extended x) { + streflop_init(); Double res = atan(Double(x)); streflop_init(); return Extended(res); + } + inline Extended atan2(Extended x, Extended y) { + streflop_init(); Double res = atan2(Double(x), Double(y)); streflop_init(); return Extended(res); + } - inline Extended cosh(Extended x) {streflop_init(); Double res = cosh(Double(x)); streflop_init(); return Extended(res);} - inline Extended sinh(Extended x) {streflop_init(); Double res = sinh(Double(x)); streflop_init(); return Extended(res);} - inline Extended tanh(Extended x) {streflop_init(); Double res = tanh(Double(x)); streflop_init(); return Extended(res);} - inline Extended acosh(Extended x) {streflop_init(); Double res = acosh(Double(x)); streflop_init(); return Extended(res);} - inline Extended asinh(Extended x) {streflop_init(); Double res = asinh(Double(x)); streflop_init(); return Extended(res);} - inline Extended atanh(Extended x) {streflop_init(); Double res = atanh(Double(x)); streflop_init(); return Extended(res);} + inline Extended cosh(Extended x) { + streflop_init(); Double res = cosh(Double(x)); streflop_init(); return Extended(res); + } + inline Extended sinh(Extended x) { + streflop_init(); Double res = sinh(Double(x)); streflop_init(); return Extended(res); + } + inline Extended tanh(Extended x) { + streflop_init(); Double res = tanh(Double(x)); streflop_init(); return Extended(res); + } + inline Extended acosh(Extended x) { + streflop_init(); Double res = acosh(Double(x)); streflop_init(); return Extended(res); + } + inline Extended asinh(Extended x) { + streflop_init(); Double res = asinh(Double(x)); streflop_init(); return Extended(res); + } + inline Extended atanh(Extended x) { + streflop_init(); Double res = atanh(Double(x)); streflop_init(); return Extended(res); + } - inline Extended expm1(Extended x) {streflop_init(); Double res = expm1(Double(x)); streflop_init(); return Extended(res);} - inline Extended log1p(Extended x) {streflop_init(); Double res = log1p(Double(x)); streflop_init(); return Extended(res);} - inline Extended erf(Extended x) {streflop_init(); Double res = erf(Double(x)); streflop_init(); return Extended(res);} - inline Extended j0(Extended x) {streflop_init(); Double res = j0(Double(x)); streflop_init(); return Extended(res);} - inline Extended j1(Extended x) {streflop_init(); Double res = j1(Double(x)); streflop_init(); return Extended(res);} - inline Extended jn(int n, Extended x) {streflop_init(); Double res = jn(n,Double(x)); streflop_init(); return Extended(res);} - inline Extended y0(Extended x) {streflop_init(); Double res = y0(Double(x)); streflop_init(); return Extended(res);} - inline Extended y1(Extended x) {streflop_init(); Double res = y1(Double(x)); streflop_init(); return Extended(res);} - inline Extended yn(int n, Extended x) {streflop_init(); Double res = yn(n,Double(x)); streflop_init(); return Extended(res);} - inline Extended scalbn(Extended x, int n) {streflop_init(); Double res = scalbn(Double(x),n); streflop_init(); return Extended(res);} - inline Extended scalbln(Extended x, long int n) {streflop_init(); Double res = scalbln(Double(x),n); streflop_init(); return Extended(res);} + inline Extended expm1(Extended x) { + streflop_init(); Double res = expm1(Double(x)); streflop_init(); return Extended(res); + } + inline Extended log1p(Extended x) { + streflop_init(); Double res = log1p(Double(x)); streflop_init(); return Extended(res); + } + inline Extended erf(Extended x) { + streflop_init(); Double res = erf(Double(x)); streflop_init(); return Extended(res); + } + inline Extended j0(Extended x) { + streflop_init(); Double res = j0(Double(x)); streflop_init(); return Extended(res); + } + inline Extended j1(Extended x) { + streflop_init(); Double res = j1(Double(x)); streflop_init(); return Extended(res); + } + inline Extended jn(int n, Extended x) { + streflop_init(); Double res = jn(n, Double(x)); streflop_init(); return Extended(res); + } + inline Extended y0(Extended x) { + streflop_init(); Double res = y0(Double(x)); streflop_init(); return Extended(res); + } + inline Extended y1(Extended x) { + streflop_init(); Double res = y1(Double(x)); streflop_init(); return Extended(res); + } + inline Extended yn(int n, Extended x) { + streflop_init(); Double res = yn(n, Double(x)); streflop_init(); return Extended(res); + } + inline Extended scalbn(Extended x, int n) { + streflop_init(); Double res = scalbn(Double(x), n); streflop_init(); return Extended(res); + } + inline Extended scalbln(Extended x, long int n) { + streflop_init(); Double res = scalbln(Double(x), n); streflop_init(); return Extended(res); + } - inline Extended fabs(Extended x) {return streflop_libm::__fabsl(x);} - inline Extended floor(Extended x) {return streflop_libm::__floorl(x);} - inline Extended ceil(Extended x) {return streflop_libm::__ceill(x);} - inline Extended trunc(Extended x) {return streflop_libm::__truncl(x);} - inline Extended fmod(Extended x, Extended y) {return streflop_libm::__ieee754_fmodl(x,y);} - inline Extended remainder(Extended x, Extended y) {return streflop_libm::__ieee754_remainderl(x,y);} - inline Extended remquo(Extended x, Extended y, int *quo) {return streflop_libm::__remquol(x,y,quo);} - inline Extended rint(Extended x) {return streflop_libm::__rintl(x);} - inline long int lrint(Extended x) {return streflop_libm::__lrintl(x);} - inline long long int llrint(Extended x) {return streflop_libm::__llrintl(x);} - inline Extended round(Extended x) {return streflop_libm::__roundl(x);} - inline long int lround(Extended x) {return streflop_libm::__lroundl(x);} - inline long long int llround(Extended x) {return streflop_libm::__llroundl(x);} - inline Extended nearbyint(Extended x) {return streflop_libm::__nearbyintl(x);} + inline Extended fabs(Extended x) { + return streflop_libm::__fabsl(x); + } + inline Extended floor(Extended x) { + return streflop_libm::__floorl(x); + } + inline Extended ceil(Extended x) { + return streflop_libm::__ceill(x); + } + inline Extended trunc(Extended x) { + return streflop_libm::__truncl(x); + } + inline Extended fmod(Extended x, Extended y) { + return streflop_libm::__ieee754_fmodl(x, y); + } + inline Extended remainder(Extended x, Extended y) { + return streflop_libm::__ieee754_remainderl(x, y); + } + inline Extended remquo(Extended x, Extended y, int *quo) { + return streflop_libm::__remquol(x, y, quo); + } + inline Extended rint(Extended x) { + return streflop_libm::__rintl(x); + } + inline long int lrint(Extended x) { + return streflop_libm::__lrintl(x); + } + inline long long int llrint(Extended x) { + return streflop_libm::__llrintl(x); + } + inline Extended round(Extended x) { + return streflop_libm::__roundl(x); + } + inline long int lround(Extended x) { + return streflop_libm::__lroundl(x); + } + inline long long int llround(Extended x) { + return streflop_libm::__llroundl(x); + } + inline Extended nearbyint(Extended x) { + return streflop_libm::__nearbyintl(x); + } - inline Extended frexp(Extended x, int *exp) {return streflop_libm::__frexpl(x,exp);} - inline Extended ldexp(Extended value, int exp) {return streflop_libm::__ldexpl(value,exp);} - inline Extended logb(Extended x) {return streflop_libm::__logbl(x);} - inline int ilogb(Extended x) {return streflop_libm::__ilogbl(x);} - inline Extended copysign(Extended x) {return streflop_libm::__copysignl(x);} - inline int signbit (Extended x) {return streflop_libm::__signbitl(x);} - inline Extended nextafter(Extended x, Extended y) {return streflop_libm::__nextafterl(x,y);} + inline Extended frexp(Extended x, int *exp) { + return streflop_libm::__frexpl(x, exp); + } + inline Extended ldexp(Extended value, int exp) { + return streflop_libm::__ldexpl(value, exp); + } + inline Extended logb(Extended x) { + return streflop_libm::__logbl(x); + } + inline int ilogb(Extended x) { + return streflop_libm::__ilogbl(x); + } + inline Extended copysign(Extended x) { + return streflop_libm::__copysignl(x); + } + inline int signbit(Extended x) { + return streflop_libm::__signbitl(x); + } + inline Extended nextafter(Extended x, Extended y) { + return streflop_libm::__nextafterl(x, y); + } - inline int fpclassify(Extended x) {return streflop_libm::__fpclassifyl(x);} - inline int isnan(Extended x) {return streflop_libm::__isnanl(x);} - inline int isinf(Extended x) {return streflop_libm::__isinfl(x);} - inline int isfinite(Extended x) {return !(isnan(x) || isinf(x));} + inline int fpclassify(Extended x) { + return streflop_libm::__fpclassifyl(x); + } + inline int isnan(Extended x) { + return streflop_libm::__isnanl(x); + } + inline int isinf(Extended x) { + return streflop_libm::__isinfl(x); + } + inline int isfinite(Extended x) { + return !(isnan(x) || isinf(x)); + } // Stolen from math.h and inlined instead of macroized. // Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ - inline int isnormal(Extended x) {return fpclassify(x) == STREFLOP_FP_NORMAL;} + inline int isnormal(Extended x) { + return fpclassify(x) == STREFLOP_FP_NORMAL; + } // Constants user may set extern const Extended ExtendedPositiveInfinity; @@ -619,101 +1102,231 @@ enum Defined as inlined for each type, thanks to C++ overloading */ inline bool isunordered(Extended x, Extended y) { - return (fpclassify(x) == STREFLOP_FP_NAN) || (fpclassify (y) == STREFLOP_FP_NAN); + return (fpclassify(x) == STREFLOP_FP_NAN) || (fpclassify(y) == STREFLOP_FP_NAN); } inline bool isgreater(Extended x, Extended y) { - return (!isunordered(x,y)) && (x > y); + return (!isunordered(x, y)) && (x > y); } inline bool isgreaterequal(Extended x, Extended y) { - return (!isunordered(x,y)) && (x >= y); + return (!isunordered(x, y)) && (x >= y); } inline bool isless(Extended x, Extended y) { - return (!isunordered(x,y)) && (x < y); + return (!isunordered(x, y)) && (x < y); } inline bool islessequal(Extended x, Extended y) { - return (!isunordered(x,y)) && (x <= y); + return (!isunordered(x, y)) && (x <= y); } inline bool islessgreater(Extended x, Extended y) { - return (!isunordered(x,y)) && ((x < y) || (x > y)); + return (!isunordered(x, y)) && ((x < y) || (x > y)); } -// Add xxxl alias to ease porting existing code to streflop -// Additionally, using xxxl(number) avoids potential confusion + // Add xxxl alias to ease porting existing code to streflop + // Additionally, using xxxl(number) avoids potential confusion - inline Extended sqrtl(Extended x) {return sqrt(x);} - inline Extended cbrtl(Extended x) {return cbrt(x);} - inline Extended hypotl(Extended x, Extended y) {return hypot(x, y);} + inline Extended sqrtl(Extended x) { + return sqrt(x); + } + inline Extended cbrtl(Extended x) { + return cbrt(x); + } + inline Extended hypotl(Extended x, Extended y) { + return hypot(x, y); + } - inline Extended expl(Extended x) {return exp(x);} - inline Extended logl(Extended x) {return log(x);} - inline Extended log2l(Extended x) {return log2(x);} - inline Extended exp2l(Extended x) {return exp2(x);} - inline Extended log10l(Extended x) {return log10(x);} - inline Extended powl(Extended x, Extended y) {return pow(x, y);} + inline Extended expl(Extended x) { + return exp(x); + } + inline Extended logl(Extended x) { + return log(x); + } + inline Extended log2l(Extended x) { + return log2(x); + } + inline Extended exp2l(Extended x) { + return exp2(x); + } + inline Extended log10l(Extended x) { + return log10(x); + } + inline Extended powl(Extended x, Extended y) { + return pow(x, y); + } - inline Extended sinl(Extended x) {return sin(x);} - inline Extended cosl(Extended x) {return cos(x);} - inline Extended tanl(Extended x) {return tan(x);} - inline Extended acosl(Extended x) {return acos(x);} - inline Extended asinl(Extended x) {return asin(x);} - inline Extended atanl(Extended x) {return atan(x);} - inline Extended atan2l(Extended x, Extended y) {return atan2(x, y);} + inline Extended sinl(Extended x) { + return sin(x); + } + inline Extended cosl(Extended x) { + return cos(x); + } + inline Extended tanl(Extended x) { + return tan(x); + } + inline Extended acosl(Extended x) { + return acos(x); + } + inline Extended asinl(Extended x) { + return asin(x); + } + inline Extended atanl(Extended x) { + return atan(x); + } + inline Extended atan2l(Extended x, Extended y) { + return atan2(x, y); + } - inline Extended coshl(Extended x) {return cosh(x);} - inline Extended sinhl(Extended x) {return sinh(x);} - inline Extended tanhl(Extended x) {return tanh(x);} - inline Extended acoshl(Extended x) {return acosh(x);} - inline Extended asinhl(Extended x) {return asinh(x);} - inline Extended atanhl(Extended x) {return atanh(x);} + inline Extended coshl(Extended x) { + return cosh(x); + } + inline Extended sinhl(Extended x) { + return sinh(x); + } + inline Extended tanhl(Extended x) { + return tanh(x); + } + inline Extended acoshl(Extended x) { + return acosh(x); + } + inline Extended asinhl(Extended x) { + return asinh(x); + } + inline Extended atanhl(Extended x) { + return atanh(x); + } - inline Extended fabsl(Extended x) {return fabs(x);} - inline Extended floorl(Extended x) {return floor(x);} - inline Extended ceill(Extended x) {return ceil(x);} - inline Extended truncl(Extended x) {return trunc(x);} - inline Extended fmodl(Extended x, Extended y) {return fmod(x,y);} - inline Extended remainderl(Extended x, Extended y) {return remainder(x,y);} - inline Extended remquol(Extended x, Extended y, int *quo) {return remquo(x, y, quo);} - inline Extended rintl(Extended x) {return rint(x);} - inline long int lrintl(Extended x) {return lrint(x);} - inline long long int llrintl(Extended x) {return llrint(x);} - inline Extended roundl(Extended x) {return round(x);} - inline long int lroundl(Extended x) {return lround(x);} - inline long long int llroundl(Extended x) {return llround(x);} - inline Extended nearbyintl(Extended x) {return nearbyint(x);} + inline Extended fabsl(Extended x) { + return fabs(x); + } + inline Extended floorl(Extended x) { + return floor(x); + } + inline Extended ceill(Extended x) { + return ceil(x); + } + inline Extended truncl(Extended x) { + return trunc(x); + } + inline Extended fmodl(Extended x, Extended y) { + return fmod(x, y); + } + inline Extended remainderl(Extended x, Extended y) { + return remainder(x, y); + } + inline Extended remquol(Extended x, Extended y, int *quo) { + return remquo(x, y, quo); + } + inline Extended rintl(Extended x) { + return rint(x); + } + inline long int lrintl(Extended x) { + return lrint(x); + } + inline long long int llrintl(Extended x) { + return llrint(x); + } + inline Extended roundl(Extended x) { + return round(x); + } + inline long int lroundl(Extended x) { + return lround(x); + } + inline long long int llroundl(Extended x) { + return llround(x); + } + inline Extended nearbyintl(Extended x) { + return nearbyint(x); + } - inline Extended frexpl(Extended x, int *exp) {return frexp(x, exp);} - inline Extended ldexpl(Extended value, int exp) {return ldexp(value,exp);} - inline Extended logbl(Extended x) {return logb(x);} - inline int ilogbl(Extended x) {return ilogb(x);} - inline Extended copysignl(Extended x) {return copysign(x);} - inline int signbitl(Extended x) {return signbit(x);} - inline Extended nextafterl(Extended x, Extended y) {return nextafter(x, y);} + inline Extended frexpl(Extended x, int *exp) { + return frexp(x, exp); + } + inline Extended ldexpl(Extended value, int exp) { + return ldexp(value, exp); + } + inline Extended logbl(Extended x) { + return logb(x); + } + inline int ilogbl(Extended x) { + return ilogb(x); + } + inline Extended copysignl(Extended x) { + return copysign(x); + } + inline int signbitl(Extended x) { + return signbit(x); + } + inline Extended nextafterl(Extended x, Extended y) { + return nextafter(x, y); + } - inline Extended expm1l(Extended x) {return expm1(x);} - inline Extended log1pl(Extended x) {return log1p(x);} - inline Extended erfl(Extended x) {return erf(x);} - inline Extended j0l(Extended x) {return j0(x);} - inline Extended j1l(Extended x) {return j1(x);} - inline Extended jnl(int n, Extended x) {return jn(n, x);} - inline Extended y0l(Extended x) {return y0(x);} - inline Extended y1l(Extended x) {return y1(x);} - inline Extended ynl(int n, Extended x) {return yn(n, x);} - inline Extended scalbnl(Extended x, int n) {return scalbn(x, n);} - inline Extended scalblnl(Extended x, long int n) {return scalbln(x, n);} + inline Extended expm1l(Extended x) { + return expm1(x); + } + inline Extended log1pl(Extended x) { + return log1p(x); + } + inline Extended erfl(Extended x) { + return erf(x); + } + inline Extended j0l(Extended x) { + return j0(x); + } + inline Extended j1l(Extended x) { + return j1(x); + } + inline Extended jnl(int n, Extended x) { + return jn(n, x); + } + inline Extended y0l(Extended x) { + return y0(x); + } + inline Extended y1l(Extended x) { + return y1(x); + } + inline Extended ynl(int n, Extended x) { + return yn(n, x); + } + inline Extended scalbnl(Extended x, int n) { + return scalbn(x, n); + } + inline Extended scalblnl(Extended x, long int n) { + return scalbln(x, n); + } - inline int fpclassifyl(Extended x) {return fpclassify(x);} - inline int isnanl(Extended x) {return isnan(x);} - inline int isinfl(Extended x) {return isinf(x);} - inline int isfinitel(Extended x) {return isfinite(x);} - inline int isnormall(Extended x) {return isnormal(x);} + inline int fpclassifyl(Extended x) { + return fpclassify(x); + } + inline int isnanl(Extended x) { + return isnan(x); + } + inline int isinfl(Extended x) { + return isinf(x); + } + inline int isfinitel(Extended x) { + return isfinite(x); + } + inline int isnormall(Extended x) { + return isnormal(x); + } - inline bool isunorderedl(Extended x, Extended y) {return isunordered(x, y);} - inline bool isgreaterl(Extended x, Extended y) {return isgreater(x, y);} - inline bool isgreaterequall(Extended x, Extended y) {return isgreaterequall(x, y);} - inline bool islessl(Extended x, Extended y) {return isless(x, y);} - inline bool islessequall(Extended x, Extended y) {return islessequal(x, y);} - inline bool islessgreaterl(Extended x, Extended y) {return islessgreater(x, y);} + inline bool isunorderedl(Extended x, Extended y) { + return isunordered(x, y); + } + inline bool isgreaterl(Extended x, Extended y) { + return isgreater(x, y); + } + inline bool isgreaterequall(Extended x, Extended y) { + return isgreaterequall(x, y); + } + inline bool islessl(Extended x, Extended y) { + return isless(x, y); + } + inline bool islessequall(Extended x, Extended y) { + return islessequal(x, y); + } + inline bool islessgreaterl(Extended x, Extended y) { + return islessgreater(x, y); + } #endif // Extended diff --git a/source/shared_lib/include/streflop/SoftFloatWrapper.h b/source/shared_lib/include/streflop/SoftFloatWrapper.h index 3f2e82196..1a6a16fe4 100644 --- a/source/shared_lib/include/streflop/SoftFloatWrapper.h +++ b/source/shared_lib/include/streflop/SoftFloatWrapper.h @@ -1,14 +1,14 @@ /* - streflop: STandalone REproducible FLOating-Point - Copyright 2006 Nicolas Brodu - 2010 Mark Vejvoda + streflop: STandalone REproducible FLOating-Point + Copyright 2006 Nicolas Brodu + 2010 Mark Vejvoda - Code released according to the GNU Lesser General Public License + Code released according to the GNU Lesser General Public License - Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. - Uses SoftFloat too. + Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. + Uses SoftFloat too. - Please read the history and copyright information in the documentation provided with the source code + Please read the history and copyright information in the documentation provided with the source code */ #ifdef STREFLOP_SOFT @@ -28,41 +28,49 @@ #include "IntegerTypes.h" namespace streflop { -// Generic define -template struct SoftFloatWrapper { + // Generic define + template struct SoftFloatWrapper { - char holder[(Nbits/STREFLOP_INTEGER_TYPES_CHAR_BITS)]; - template inline T& value() {return *reinterpret_cast(&holder);} - template inline const T& value() const {return *reinterpret_cast(&holder);} + char holder[(Nbits / STREFLOP_INTEGER_TYPES_CHAR_BITS)]; + template inline T& value() { + return *reinterpret_cast(&holder); + } + template inline const T& value() const { + return *reinterpret_cast(&holder); + } - /// Use dummy bool argument for construction from an already initialized holder - template inline SoftFloatWrapper(T init_value, bool) {value() = init_value;} + /// Use dummy bool argument for construction from an already initialized holder + template inline SoftFloatWrapper(T init_value, bool) { + value() = init_value; + } - /// Uninitialized object - inline SoftFloatWrapper() {} + /// Uninitialized object + inline SoftFloatWrapper() { + } - /// Conversion between different types. Also unfortunately includes otherwise perfectly fine copy constructor - SoftFloatWrapper(const SoftFloatWrapper<32>& f); - SoftFloatWrapper& operator=(const SoftFloatWrapper<32>& f); - SoftFloatWrapper(const SoftFloatWrapper<64>& f); - SoftFloatWrapper& operator=(const SoftFloatWrapper<64>& f); - SoftFloatWrapper(const SoftFloatWrapper<96>& f); - SoftFloatWrapper& operator=(const SoftFloatWrapper<96>& f); + /// Conversion between different types. Also unfortunately includes otherwise perfectly fine copy constructor + SoftFloatWrapper(const SoftFloatWrapper<32>& f); + SoftFloatWrapper& operator=(const SoftFloatWrapper<32>& f); + SoftFloatWrapper(const SoftFloatWrapper<64>& f); + SoftFloatWrapper& operator=(const SoftFloatWrapper<64>& f); + SoftFloatWrapper(const SoftFloatWrapper<96>& f); + SoftFloatWrapper& operator=(const SoftFloatWrapper<96>& f); - /// Destructor - inline ~SoftFloatWrapper() {} + /// Destructor + inline ~SoftFloatWrapper() { + } - /// Now the real fun, arithmetic operator overloading - SoftFloatWrapper& operator+=(const SoftFloatWrapper& f); - SoftFloatWrapper& operator-=(const SoftFloatWrapper& f); - SoftFloatWrapper& operator*=(const SoftFloatWrapper& f); - SoftFloatWrapper& operator/=(const SoftFloatWrapper& f); - bool operator==(const SoftFloatWrapper& f) const; - bool operator!=(const SoftFloatWrapper& f) const; - bool operator<(const SoftFloatWrapper& f) const; - bool operator<=(const SoftFloatWrapper& f) const; - bool operator>(const SoftFloatWrapper& f) const; - bool operator>=(const SoftFloatWrapper& f) const; + /// Now the real fun, arithmetic operator overloading + SoftFloatWrapper& operator+=(const SoftFloatWrapper& f); + SoftFloatWrapper& operator-=(const SoftFloatWrapper& f); + SoftFloatWrapper& operator*=(const SoftFloatWrapper& f); + SoftFloatWrapper& operator/=(const SoftFloatWrapper& f); + bool operator==(const SoftFloatWrapper& f) const; + bool operator!=(const SoftFloatWrapper& f) const; + bool operator<(const SoftFloatWrapper& f) const; + bool operator<=(const SoftFloatWrapper& f) const; + bool operator>(const SoftFloatWrapper& f) const; + bool operator>=(const SoftFloatWrapper& f) const; #define STREFLOP_SOFT_WRAPPER_NATIVE_OPS(native_type) \ SoftFloatWrapper(const native_type f); \ @@ -79,21 +87,21 @@ template struct SoftFloatWrapper { bool operator>(const native_type f) const; \ bool operator>=(const native_type f) const; -STREFLOP_SOFT_WRAPPER_NATIVE_OPS(float) -STREFLOP_SOFT_WRAPPER_NATIVE_OPS(double) -STREFLOP_SOFT_WRAPPER_NATIVE_OPS(long double) -STREFLOP_SOFT_WRAPPER_NATIVE_OPS(char) -STREFLOP_SOFT_WRAPPER_NATIVE_OPS(unsigned char) -STREFLOP_SOFT_WRAPPER_NATIVE_OPS(short) -STREFLOP_SOFT_WRAPPER_NATIVE_OPS(unsigned short) -STREFLOP_SOFT_WRAPPER_NATIVE_OPS(int) -STREFLOP_SOFT_WRAPPER_NATIVE_OPS(unsigned int) -STREFLOP_SOFT_WRAPPER_NATIVE_OPS(long) -STREFLOP_SOFT_WRAPPER_NATIVE_OPS(unsigned long) -STREFLOP_SOFT_WRAPPER_NATIVE_OPS(long long) -STREFLOP_SOFT_WRAPPER_NATIVE_OPS(unsigned long long) + STREFLOP_SOFT_WRAPPER_NATIVE_OPS(float) + STREFLOP_SOFT_WRAPPER_NATIVE_OPS(double) + STREFLOP_SOFT_WRAPPER_NATIVE_OPS(long double) + STREFLOP_SOFT_WRAPPER_NATIVE_OPS(char) + STREFLOP_SOFT_WRAPPER_NATIVE_OPS(unsigned char) + STREFLOP_SOFT_WRAPPER_NATIVE_OPS(short) + STREFLOP_SOFT_WRAPPER_NATIVE_OPS(unsigned short) + STREFLOP_SOFT_WRAPPER_NATIVE_OPS(int) + STREFLOP_SOFT_WRAPPER_NATIVE_OPS(unsigned int) + STREFLOP_SOFT_WRAPPER_NATIVE_OPS(long) + STREFLOP_SOFT_WRAPPER_NATIVE_OPS(unsigned long) + STREFLOP_SOFT_WRAPPER_NATIVE_OPS(long long) + STREFLOP_SOFT_WRAPPER_NATIVE_OPS(unsigned long long) -}; + }; #define STREFLOP_SOFT_WRAPPER_MAKE_REAL_CLASS_OPS(N) \ template<> bool SoftFloatWrapper::operator<(const SoftFloatWrapper& f) const; \ @@ -107,13 +115,13 @@ template<> bool SoftFloatWrapper::operator<(const SoftFloatWrapper& f) con template<> bool SoftFloatWrapper::operator<=(const SoftFloatWrapper& f) const; \ template<> bool SoftFloatWrapper::operator>(const SoftFloatWrapper& f) const; \ template<> bool SoftFloatWrapper::operator>=(const SoftFloatWrapper& f) const; -STREFLOP_SOFT_WRAPPER_MAKE_REAL_CLASS_OPS(32) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_CLASS_OPS(64) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_CLASS_OPS(96) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_CLASS_OPS(32) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_CLASS_OPS(64) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_CLASS_OPS(96) -// Making real the conversion N->M -// Have to include default constructors for template overloading reasons + // Making real the conversion N->M + // Have to include default constructors for template overloading reasons #define STREFLOP_SOFT_WRAPPER_MAKE_REAL_NM_CONVERSION(Nbits) \ template<> SoftFloatWrapper::SoftFloatWrapper(const SoftFloatWrapper<32>& f); \ template<> SoftFloatWrapper& SoftFloatWrapper::operator=(const SoftFloatWrapper<32>& f); \ @@ -121,9 +129,9 @@ template<> SoftFloatWrapper::SoftFloatWrapper(const SoftFloatWrapper<64>& template<> SoftFloatWrapper& SoftFloatWrapper::operator=(const SoftFloatWrapper<64>& f); \ template<> SoftFloatWrapper::SoftFloatWrapper(const SoftFloatWrapper<96>& f); \ template<> SoftFloatWrapper& SoftFloatWrapper::operator=(const SoftFloatWrapper<96>& f); -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NM_CONVERSION(32) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NM_CONVERSION(64) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NM_CONVERSION(96) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NM_CONVERSION(32) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NM_CONVERSION(64) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NM_CONVERSION(96) #define STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(N,native_type) \ @@ -141,64 +149,64 @@ template<> bool SoftFloatWrapper::operator<=(const native_type f) const; \ template<> bool SoftFloatWrapper::operator>(const native_type f) const; \ template<> bool SoftFloatWrapper::operator>=(const native_type f) const; -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32,float) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32,double) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32,long double) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32,char) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32,unsigned char) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32,short) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32,unsigned short) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32,int) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32,unsigned int) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32,long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32,unsigned long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32,long long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32,unsigned long long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64,float) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64,double) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64,long double) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64,char) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64,unsigned char) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64,short) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64,unsigned short) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64,int) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64,unsigned int) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64,long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64,unsigned long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64,long long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64,unsigned long long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96,float) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96,double) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96,long double) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96,char) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96,unsigned char) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96,short) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96,unsigned short) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96,int) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96,unsigned int) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96,long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96,unsigned long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96,long long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96,unsigned long long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32, float) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32, double) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32, long double) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32, char) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32, unsigned char) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32, short) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32, unsigned short) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32, int) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32, unsigned int) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32, long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32, unsigned long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32, long long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(32, unsigned long long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64, float) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64, double) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64, long double) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64, char) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64, unsigned char) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64, short) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64, unsigned short) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64, int) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64, unsigned int) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64, long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64, unsigned long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64, long long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(64, unsigned long long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96, float) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96, double) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96, long double) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96, char) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96, unsigned char) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96, short) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96, unsigned short) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96, int) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96, unsigned int) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96, long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96, unsigned long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96, long long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_NATIVE_OPS(96, unsigned long long) -// Generic versions are fine here, specializations in the cpp + // Generic versions are fine here, specializations in the cpp -/// binary operators -template SoftFloatWrapper operator+(const SoftFloatWrapper& f1, const SoftFloatWrapper& f2); -template SoftFloatWrapper operator-(const SoftFloatWrapper& f1, const SoftFloatWrapper& f2); -template SoftFloatWrapper operator*(const SoftFloatWrapper& f1, const SoftFloatWrapper& f2); -template SoftFloatWrapper operator/(const SoftFloatWrapper& f1, const SoftFloatWrapper& f2); + /// binary operators + template SoftFloatWrapper operator+(const SoftFloatWrapper& f1, const SoftFloatWrapper& f2); + template SoftFloatWrapper operator-(const SoftFloatWrapper& f1, const SoftFloatWrapper& f2); + template SoftFloatWrapper operator*(const SoftFloatWrapper& f1, const SoftFloatWrapper& f2); + template SoftFloatWrapper operator/(const SoftFloatWrapper& f1, const SoftFloatWrapper& f2); #define STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_CLASS_OPS(N) \ template<> SoftFloatWrapper operator+(const SoftFloatWrapper& f1, const SoftFloatWrapper& f2); \ template<> SoftFloatWrapper operator-(const SoftFloatWrapper& f1, const SoftFloatWrapper& f2); \ template<> SoftFloatWrapper operator*(const SoftFloatWrapper& f1, const SoftFloatWrapper& f2); \ template<> SoftFloatWrapper operator/(const SoftFloatWrapper& f1, const SoftFloatWrapper& f2); -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_CLASS_OPS(32) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_CLASS_OPS(64) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_CLASS_OPS(96) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_CLASS_OPS(32) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_CLASS_OPS(64) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_CLASS_OPS(96) #define STREFLOP_SOFT_WRAPPER_BINARY_OPS(native_type) \ template SoftFloatWrapper operator+(const SoftFloatWrapper& f1, const native_type f2); \ @@ -216,19 +224,19 @@ template bool operator<=(const native_type value, const SoftFloatWrapper< template bool operator>(const native_type value, const SoftFloatWrapper& f); \ template bool operator>=(const native_type value, const SoftFloatWrapper& f); -STREFLOP_SOFT_WRAPPER_BINARY_OPS(float) -STREFLOP_SOFT_WRAPPER_BINARY_OPS(double) -STREFLOP_SOFT_WRAPPER_BINARY_OPS(long double) -STREFLOP_SOFT_WRAPPER_BINARY_OPS(char) -STREFLOP_SOFT_WRAPPER_BINARY_OPS(unsigned char) -STREFLOP_SOFT_WRAPPER_BINARY_OPS(short) -STREFLOP_SOFT_WRAPPER_BINARY_OPS(unsigned short) -STREFLOP_SOFT_WRAPPER_BINARY_OPS(int) -STREFLOP_SOFT_WRAPPER_BINARY_OPS(unsigned int) -STREFLOP_SOFT_WRAPPER_BINARY_OPS(long) -STREFLOP_SOFT_WRAPPER_BINARY_OPS(unsigned long) -STREFLOP_SOFT_WRAPPER_BINARY_OPS(long long) -STREFLOP_SOFT_WRAPPER_BINARY_OPS(unsigned long long) + STREFLOP_SOFT_WRAPPER_BINARY_OPS(float) + STREFLOP_SOFT_WRAPPER_BINARY_OPS(double) + STREFLOP_SOFT_WRAPPER_BINARY_OPS(long double) + STREFLOP_SOFT_WRAPPER_BINARY_OPS(char) + STREFLOP_SOFT_WRAPPER_BINARY_OPS(unsigned char) + STREFLOP_SOFT_WRAPPER_BINARY_OPS(short) + STREFLOP_SOFT_WRAPPER_BINARY_OPS(unsigned short) + STREFLOP_SOFT_WRAPPER_BINARY_OPS(int) + STREFLOP_SOFT_WRAPPER_BINARY_OPS(unsigned int) + STREFLOP_SOFT_WRAPPER_BINARY_OPS(long) + STREFLOP_SOFT_WRAPPER_BINARY_OPS(unsigned long) + STREFLOP_SOFT_WRAPPER_BINARY_OPS(long long) + STREFLOP_SOFT_WRAPPER_BINARY_OPS(unsigned long long) #define STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(N,native_type) \ @@ -246,56 +254,56 @@ template<> bool operator<(const native_type value, const SoftFloatWrapper& f) template<> bool operator<=(const native_type value, const SoftFloatWrapper& f); \ template<> bool operator>(const native_type value, const SoftFloatWrapper& f); \ template<> bool operator>=(const native_type value, const SoftFloatWrapper& f); -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32,float) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32,double) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32,long double) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32,char) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32,unsigned char) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32,short) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32,unsigned short) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32,int) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32,unsigned int) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32,long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32,unsigned long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32,long long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32,unsigned long long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64,float) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64,double) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64,long double) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64,char) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64,unsigned char) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64,short) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64,unsigned short) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64,int) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64,unsigned int) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64,long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64,unsigned long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64,long long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64,unsigned long long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96,float) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96,double) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96,long double) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96,char) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96,unsigned char) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96,short) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96,unsigned short) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96,int) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96,unsigned int) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96,long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96,unsigned long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96,long long) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96,unsigned long long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32, float) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32, double) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32, long double) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32, char) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32, unsigned char) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32, short) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32, unsigned short) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32, int) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32, unsigned int) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32, long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32, unsigned long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32, long long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(32, unsigned long long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64, float) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64, double) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64, long double) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64, char) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64, unsigned char) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64, short) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64, unsigned short) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64, int) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64, unsigned int) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64, long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64, unsigned long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64, long long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(64, unsigned long long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96, float) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96, double) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96, long double) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96, char) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96, unsigned char) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96, short) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96, unsigned short) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96, int) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96, unsigned int) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96, long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96, unsigned long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96, long long) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_BINARY_OPS(96, unsigned long long) -/// Unary operators -template SoftFloatWrapper operator-(const SoftFloatWrapper& f); -template SoftFloatWrapper operator+(const SoftFloatWrapper& f); + /// Unary operators + template SoftFloatWrapper operator-(const SoftFloatWrapper& f); + template SoftFloatWrapper operator+(const SoftFloatWrapper& f); #define STREFLOP_SOFT_WRAPPER_MAKE_REAL_UNARY_CLASS_OPS(N) \ template<> SoftFloatWrapper operator-(const SoftFloatWrapper& f); \ template<> SoftFloatWrapper operator+(const SoftFloatWrapper& f); -STREFLOP_SOFT_WRAPPER_MAKE_REAL_UNARY_CLASS_OPS(32) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_UNARY_CLASS_OPS(64) -STREFLOP_SOFT_WRAPPER_MAKE_REAL_UNARY_CLASS_OPS(96) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_UNARY_CLASS_OPS(32) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_UNARY_CLASS_OPS(64) + STREFLOP_SOFT_WRAPPER_MAKE_REAL_UNARY_CLASS_OPS(96) #endif diff --git a/source/shared_lib/include/streflop/System.h b/source/shared_lib/include/streflop/System.h index d204c132e..8feecbc22 100644 --- a/source/shared_lib/include/streflop/System.h +++ b/source/shared_lib/include/streflop/System.h @@ -1,13 +1,13 @@ /* - streflop: STandalone REproducible FLOating-Point - Copyright 2006 Nicolas Brodu + streflop: STandalone REproducible FLOating-Point + Copyright 2006 Nicolas Brodu 2012 Mark Vejvoda - Code released according to the GNU Lesser General Public License + Code released according to the GNU Lesser General Public License - Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. - Uses SoftFloat too. + Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. + Uses SoftFloat too. - Please read the history and copyright information in the documentation provided with the source code + Please read the history and copyright information in the documentation provided with the source code */ @@ -65,18 +65,18 @@ // Avoid conflict with system types, if any namespace streflop { -// Use the assumption above for char -typedef char int8_t; -typedef unsigned char uint8_t; + // Use the assumption above for char + typedef char int8_t; + typedef unsigned char uint8_t; -// Now "run" the meta-program to define the types -// Entry point is (unsigned) short, then all types above are tried till the size match -typedef SizedInteger<16>::Type int16_t; -typedef SizedUnsignedInteger<16>::Type uint16_t; -typedef SizedInteger<32>::Type int32_t; -typedef SizedUnsignedInteger<32>::Type uint32_t; -typedef SizedInteger<64>::Type int64_t; -typedef SizedUnsignedInteger<64>::Type uint64_t; + // Now "run" the meta-program to define the types + // Entry point is (unsigned) short, then all types above are tried till the size match + typedef SizedInteger<16>::Type int16_t; + typedef SizedUnsignedInteger<16>::Type uint16_t; + typedef SizedInteger<32>::Type int32_t; + typedef SizedUnsignedInteger<32>::Type uint32_t; + typedef SizedInteger<64>::Type int64_t; + typedef SizedUnsignedInteger<64>::Type uint64_t; } diff --git a/source/shared_lib/include/streflop/X87DenormalSquasher.h b/source/shared_lib/include/streflop/X87DenormalSquasher.h index bbfa2f630..d54e0a0d4 100644 --- a/source/shared_lib/include/streflop/X87DenormalSquasher.h +++ b/source/shared_lib/include/streflop/X87DenormalSquasher.h @@ -1,13 +1,13 @@ /* - streflop: STandalone REproducible FLOating-Point - Copyright 2006 Nicolas Brodu - 2012 Mark Vejvoda - Code released according to the GNU Lesser General Public License + streflop: STandalone REproducible FLOating-Point + Copyright 2006 Nicolas Brodu + 2012 Mark Vejvoda + Code released according to the GNU Lesser General Public License - Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. - Uses SoftFloat too. + Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. + Uses SoftFloat too. - Please read the history and copyright information in the documentation provided with the source code + Please read the history and copyright information in the documentation provided with the source code */ #ifndef X87DenormalSquasher_H @@ -16,10 +16,11 @@ /// This file should be included from within a streflop namespace template inline void X87DenormalSquashFunction(ValueType& value) { - struct X {}; - X Unknown_numeric_type; - // unknown types do not compile - value = Unknown_numeric_type; + struct X { + }; + X Unknown_numeric_type; + // unknown types do not compile + value = Unknown_numeric_type; } // Use cmov instruction to avoid branching? @@ -27,15 +28,15 @@ template inline void X87DenormalSquashFunction(ValueType& va // Con: cmov forces an unconditional writeback to the mem just after read, which may be worse than the branch template<> inline void X87DenormalSquashFunction(float& value) { - if ((reinterpret_cast(&value)[0] & 0x7F800000) == 0) value = 0.0f; + if ((reinterpret_cast(&value)[0] & 0x7F800000) == 0) value = 0.0f; } template<> inline void X87DenormalSquashFunction(double& value) { - if ((reinterpret_cast(&value)[1] & 0x7FF00000) == 0) value = 0.0; + if ((reinterpret_cast(&value)[1] & 0x7FF00000) == 0) value = 0.0; } template<> inline void X87DenormalSquashFunction(long double& value) { - if ((reinterpret_cast(&value)[4] & 0x7FFF) == 0) value = 0.0L; + if ((reinterpret_cast(&value)[4] & 0x7FFF) == 0) value = 0.0L; } /// Wrapper class for the denormal squashing of X87 @@ -46,34 +47,68 @@ template<> inline void X87DenormalSquashFunction(long double& value template struct X87DenormalSquasher { -// Define value - ValueType value; + // Define value + ValueType value; - /// Uninitialized object - inline X87DenormalSquasher() {} + /// Uninitialized object + inline X87DenormalSquasher() { + } - /// Copy and conversion from other precisions - inline X87DenormalSquasher(const X87DenormalSquasher& f) : value(f.value) {X87DenormalSquashFunction(value);} - inline X87DenormalSquasher(const X87DenormalSquasher& f) : value(f.value) {X87DenormalSquashFunction(value);} - inline X87DenormalSquasher(const X87DenormalSquasher& f) : value(f.value) {X87DenormalSquashFunction(value);} - inline X87DenormalSquasher& operator=(const X87DenormalSquasher& f) {value = f.value; X87DenormalSquashFunction(value); return *this;} // self-ref OK - inline X87DenormalSquasher& operator=(const X87DenormalSquasher& f) {value = f.value; X87DenormalSquashFunction(value); return *this;} // self-ref OK - inline X87DenormalSquasher& operator=(const X87DenormalSquasher& f) {value = f.value; X87DenormalSquashFunction(value); return *this;} // self-ref OK + /// Copy and conversion from other precisions + inline X87DenormalSquasher(const X87DenormalSquasher& f) : value(f.value) { + X87DenormalSquashFunction(value); + } + inline X87DenormalSquasher(const X87DenormalSquasher& f) : value(f.value) { + X87DenormalSquashFunction(value); + } + inline X87DenormalSquasher(const X87DenormalSquasher& f) : value(f.value) { + X87DenormalSquashFunction(value); + } + inline X87DenormalSquasher& operator=(const X87DenormalSquasher& f) { + value = f.value; X87DenormalSquashFunction(value); return *this; + } // self-ref OK + inline X87DenormalSquasher& operator=(const X87DenormalSquasher& f) { + value = f.value; X87DenormalSquashFunction(value); return *this; + } // self-ref OK + inline X87DenormalSquasher& operator=(const X87DenormalSquasher& f) { + value = f.value; X87DenormalSquashFunction(value); return *this; + } // self-ref OK - /// Destructor - inline ~X87DenormalSquasher() {} +/// Destructor + inline ~X87DenormalSquasher() { + } - /// Now the real fun, arithmetic operator overloading - inline X87DenormalSquasher& operator+=(const X87DenormalSquasher& f) {value += f.value; X87DenormalSquashFunction(value); return *this;} - inline X87DenormalSquasher& operator-=(const X87DenormalSquasher& f) {value -= f.value; X87DenormalSquashFunction(value); return *this;} - inline X87DenormalSquasher& operator*=(const X87DenormalSquasher& f) {value *= f.value; X87DenormalSquashFunction(value); return *this;} - inline X87DenormalSquasher& operator/=(const X87DenormalSquasher& f) {value /= f.value; X87DenormalSquashFunction(value); return *this;} - inline bool operator==(const X87DenormalSquasher& f) const {return value == f.value;} - inline bool operator!=(const X87DenormalSquasher& f) const {return value != f.value;} - inline bool operator<(const X87DenormalSquasher& f) const {return value < f.value;} - inline bool operator<=(const X87DenormalSquasher& f) const {return value <= f.value;} - inline bool operator>(const X87DenormalSquasher& f) const {return value > f.value;} - inline bool operator>=(const X87DenormalSquasher& f) const {return value >= f.value;} + /// Now the real fun, arithmetic operator overloading + inline X87DenormalSquasher& operator+=(const X87DenormalSquasher& f) { + value += f.value; X87DenormalSquashFunction(value); return *this; + } + inline X87DenormalSquasher& operator-=(const X87DenormalSquasher& f) { + value -= f.value; X87DenormalSquashFunction(value); return *this; + } + inline X87DenormalSquasher& operator*=(const X87DenormalSquasher& f) { + value *= f.value; X87DenormalSquashFunction(value); return *this; + } + inline X87DenormalSquasher& operator/=(const X87DenormalSquasher& f) { + value /= f.value; X87DenormalSquashFunction(value); return *this; + } + inline bool operator==(const X87DenormalSquasher& f) const { + return value == f.value; + } + inline bool operator!=(const X87DenormalSquasher& f) const { + return value != f.value; + } + inline bool operator<(const X87DenormalSquasher& f) const { + return value < f.value; + } + inline bool operator<=(const X87DenormalSquasher& f) const { + return value <= f.value; + } + inline bool operator>(const X87DenormalSquasher& f) const { + return value > f.value; + } + inline bool operator>=(const X87DenormalSquasher& f) const { + return value >= f.value; + } #define STREFLOP_X87DENORMAL_NATIVE_FLOAT_OPS(native_type) \ inline X87DenormalSquasher(const native_type f) {value = f; X87DenormalSquashFunction(value);} \ @@ -105,28 +140,36 @@ template struct X87DenormalSquasher { inline bool operator>(const native_type f) const {return value > f;} \ inline bool operator>=(const native_type f) const {return value >= f;} -STREFLOP_X87DENORMAL_NATIVE_FLOAT_OPS(float) -STREFLOP_X87DENORMAL_NATIVE_FLOAT_OPS(double) -STREFLOP_X87DENORMAL_NATIVE_FLOAT_OPS(long double) + STREFLOP_X87DENORMAL_NATIVE_FLOAT_OPS(float) + STREFLOP_X87DENORMAL_NATIVE_FLOAT_OPS(double) + STREFLOP_X87DENORMAL_NATIVE_FLOAT_OPS(long double) -STREFLOP_X87DENORMAL_NATIVE_INT_OPS(char) -STREFLOP_X87DENORMAL_NATIVE_INT_OPS(unsigned char) -STREFLOP_X87DENORMAL_NATIVE_INT_OPS(short) -STREFLOP_X87DENORMAL_NATIVE_INT_OPS(unsigned short) -STREFLOP_X87DENORMAL_NATIVE_INT_OPS(int) -STREFLOP_X87DENORMAL_NATIVE_INT_OPS(unsigned int) -STREFLOP_X87DENORMAL_NATIVE_INT_OPS(long) -STREFLOP_X87DENORMAL_NATIVE_INT_OPS(unsigned long) -STREFLOP_X87DENORMAL_NATIVE_INT_OPS(long long) -STREFLOP_X87DENORMAL_NATIVE_INT_OPS(unsigned long long) + STREFLOP_X87DENORMAL_NATIVE_INT_OPS(char) + STREFLOP_X87DENORMAL_NATIVE_INT_OPS(unsigned char) + STREFLOP_X87DENORMAL_NATIVE_INT_OPS(short) + STREFLOP_X87DENORMAL_NATIVE_INT_OPS(unsigned short) + STREFLOP_X87DENORMAL_NATIVE_INT_OPS(int) + STREFLOP_X87DENORMAL_NATIVE_INT_OPS(unsigned int) + STREFLOP_X87DENORMAL_NATIVE_INT_OPS(long) + STREFLOP_X87DENORMAL_NATIVE_INT_OPS(unsigned long) + STREFLOP_X87DENORMAL_NATIVE_INT_OPS(long long) + STREFLOP_X87DENORMAL_NATIVE_INT_OPS(unsigned long long) }; /// binary operators -template inline X87DenormalSquasher operator+(const X87DenormalSquasher& f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1.value + f2.value);} -template inline X87DenormalSquasher operator-(const X87DenormalSquasher& f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1.value - f2.value);} -template inline X87DenormalSquasher operator*(const X87DenormalSquasher& f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1.value * f2.value);} -template inline X87DenormalSquasher operator/(const X87DenormalSquasher& f1, const X87DenormalSquasher& f2) {return X87DenormalSquasher(f1.value / f2.value);} +template inline X87DenormalSquasher operator+(const X87DenormalSquasher& f1, const X87DenormalSquasher& f2) { + return X87DenormalSquasher(f1.value + f2.value); +} +template inline X87DenormalSquasher operator-(const X87DenormalSquasher& f1, const X87DenormalSquasher& f2) { + return X87DenormalSquasher(f1.value - f2.value); +} +template inline X87DenormalSquasher operator*(const X87DenormalSquasher& f1, const X87DenormalSquasher& f2) { + return X87DenormalSquasher(f1.value * f2.value); +} +template inline X87DenormalSquasher operator/(const X87DenormalSquasher& f1, const X87DenormalSquasher& f2) { + return X87DenormalSquasher(f1.value / f2.value); +} #define STREFLOP_X87DENORMAL_FLOAT_BINARY(native_type) \ template inline X87DenormalSquasher operator+(const X87DenormalSquasher& f1, const native_type f2) {return f1 + X87DenormalSquasher(f2);} \ @@ -176,8 +219,12 @@ STREFLOP_X87DENORMAL_INT_BINARY(long long) STREFLOP_X87DENORMAL_INT_BINARY(unsigned long long) /// Unary operators -template inline X87DenormalSquasher operator-(const X87DenormalSquasher& f) {return X87DenormalSquasher(-f.value);} -template inline X87DenormalSquasher operator+(const X87DenormalSquasher& f) {return X87DenormalSquasher(+f.value);} +template inline X87DenormalSquasher operator-(const X87DenormalSquasher& f) { + return X87DenormalSquasher(-f.value); +} +template inline X87DenormalSquasher operator+(const X87DenormalSquasher& f) { + return X87DenormalSquasher(+f.value); +} /* /// Stream operators for output @@ -185,12 +232,12 @@ template inline X87DenormalSquasher operator+(con /// this function may not be reliable (they may depend on system rounding mode, etc.) /// Still useful for debug output and to report results with a few significant digits template inline std::ostream& operator<<(std::ostream& out, const X87DenormalSquasher& f) { - out << f.value; - return out; + out << f.value; + return out; } template inline std::istream& operator>>(std::istream& in, X87DenormalSquasher& f) { - in >> f.value; - return in; + in >> f.value; + return in; } */ diff --git a/source/shared_lib/include/streflop/streflop.h b/source/shared_lib/include/streflop/streflop.h index 35791b756..4164dbb31 100644 --- a/source/shared_lib/include/streflop/streflop.h +++ b/source/shared_lib/include/streflop/streflop.h @@ -1,14 +1,14 @@ /* - streflop: STandalone REproducible FLOating-Point - Copyright 2006 Nicolas Brodu - 2010 Mark Vejvoda + streflop: STandalone REproducible FLOating-Point + Copyright 2006 Nicolas Brodu + 2010 Mark Vejvoda - Code released according to the GNU Lesser General Public License + Code released according to the GNU Lesser General Public License - Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. - Uses SoftFloat too. + Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, and IBM MP lib. + Uses SoftFloat too. - Please read the history and copyright information in the documentation provided with the source code + Please read the history and copyright information in the documentation provided with the source code */ #ifndef STREFLOP_H @@ -28,39 +28,39 @@ // First, define the numerical types namespace streflop { -// Handle the 6 cells of the configuration array. See README.txt + // Handle the 6 cells of the configuration array. See README.txt #if defined(STREFLOP_SSE) - // SSE always uses native types, denormals are handled by FPU flags - typedef float Simple; - typedef double Double; - #undef Extended + // SSE always uses native types, denormals are handled by FPU flags + typedef float Simple; + typedef double Double; +#undef Extended #elif defined(STREFLOP_X87) - // X87 uses a wrapper for no denormals case + // X87 uses a wrapper for no denormals case #if defined(STREFLOP_NO_DENORMALS) #include "X87DenormalSquasher.h" - typedef X87DenormalSquasher Simple; - typedef X87DenormalSquasher Double; - typedef X87DenormalSquasher Extended; - #define Extended Extended + typedef X87DenormalSquasher Simple; + typedef X87DenormalSquasher Double; + typedef X87DenormalSquasher Extended; +#define Extended Extended #else - // Use FPU flags for x87 with denormals - typedef float Simple; - typedef double Double; - typedef long double Extended; - #define Extended Extended + // Use FPU flags for x87 with denormals + typedef float Simple; + typedef double Double; + typedef long double Extended; +#define Extended Extended #endif #elif defined(STREFLOP_SOFT) && !defined(STREFLOP_NO_DENORMALS) - // Use SoftFloat wrapper + // Use SoftFloat wrapper #include "SoftFloatWrapper.h" - typedef SoftFloatWrapper<32> Simple; - typedef SoftFloatWrapper<64> Double; - typedef SoftFloatWrapper<96> Extended; - #define Extended Extended + typedef SoftFloatWrapper<32> Simple; + typedef SoftFloatWrapper<64> Double; + typedef SoftFloatWrapper<96> Extended; +#define Extended Extended #else @@ -71,21 +71,21 @@ namespace streflop { } #if defined(STREFLOP_SSE) && defined(_MSC_VER) - // MSVC will not compile without the long double variants defined, so we either have to declare Extended: - // typedef long double Extended; - // #define Extended Extended - // or write some wrapper macros: - #define atan2l(a, b) atan2((double)a, (double)b) - #define cosl(a) cos((double)a) - #define expl(a) exp((double)a) - #define ldexpl(a, b) ldexp((double)a, (double)b) - #define logl(a) log((double)a) - #define powl(a,b) pow((double)a, (double)b) - #define sinl(a) sin((double)a) - #define sqrtl(a) sqrt((double)a) - #define tanl(a) tan((double)a) - #define frexpl(a, b) frexp((double)a, b) - // The wrappers are possibly the better choice for sync reasons. +// MSVC will not compile without the long double variants defined, so we either have to declare Extended: +// typedef long double Extended; +// #define Extended Extended +// or write some wrapper macros: +#define atan2l(a, b) atan2((double)a, (double)b) +#define cosl(a) cos((double)a) +#define expl(a) exp((double)a) +#define ldexpl(a, b) ldexp((double)a, (double)b) +#define logl(a) log((double)a) +#define powl(a,b) pow((double)a, (double)b) +#define sinl(a) sin((double)a) +#define sqrtl(a) sqrt((double)a) +#define tanl(a) tan((double)a) +#define frexpl(a, b) frexp((double)a, b) +// The wrappers are possibly the better choice for sync reasons. #endif // Include the FPU settings file, so the user can initialize the library diff --git a/source/shared_lib/include/streflop/streflopC.h b/source/shared_lib/include/streflop/streflopC.h index 0af9edd22..c6904dc00 100644 --- a/source/shared_lib/include/streflop/streflopC.h +++ b/source/shared_lib/include/streflop/streflopC.h @@ -11,15 +11,15 @@ extern "C" { #endif -/// Initializes the FPU to single precision -void streflop_init_Simple(); + /// Initializes the FPU to single precision + void streflop_init_Simple(); -/// Initializes the FPU to double precision -void streflop_init_Double(); + /// Initializes the FPU to double precision + void streflop_init_Double(); #if defined(Extended) -/// Initializes the FPU to extended precision -void streflop_init_Extended(); + /// Initializes the FPU to extended precision + void streflop_init_Extended(); #endif // defined(Extended) #ifdef __cplusplus diff --git a/source/shared_lib/include/util/checksum.h b/source/shared_lib/include/util/checksum.h index e3d1ef9ec..a61a437de 100644 --- a/source/shared_lib/include/util/checksum.h +++ b/source/shared_lib/include/util/checksum.h @@ -21,46 +21,48 @@ using std::string; using namespace Shared::Platform; -namespace Shared{ namespace Util{ +namespace Shared { + namespace Util { -// ===================================================== -// class Checksum -// ===================================================== + // ===================================================== + // class Checksum + // ===================================================== -class Checksum { -private: - uint32 sum; - int32 r; - int32 c1; - int32 c2; - std::map fileList; + class Checksum { + private: + uint32 sum; + int32 r; + int32 c1; + int32 c2; + std::map fileList; - static Mutex fileListCacheSynchAccessor; - static std::map fileListCache; + static Mutex fileListCacheSynchAccessor; + static std::map fileListCache; - void addSum(uint32 value); - bool addFileToSum(const string &path); + void addSum(uint32 value); + bool addFileToSum(const string &path); -public: - Checksum(); + public: + Checksum(); - uint32 getSum(); - uint32 getFinalFileListSum(); - uint32 getFileCount(); + uint32 getSum(); + uint32 getFinalFileListSum(); + uint32 getFileCount(); - //uint32 addByte(int8 value); - uint32 addByte(const char value); - uint32 addBytes(const void *_data, size_t _size); - void addString(const string &value); - uint32 addInt(const int32 &value); - uint32 addUInt(const uint32 &value); - uint32 addInt64(const int64 &value); - void addFile(const string &path); + //uint32 addByte(int8 value); + uint32 addByte(const char value); + uint32 addBytes(const void *_data, size_t _size); + void addString(const string &value); + uint32 addInt(const int32 &value); + uint32 addUInt(const uint32 &value); + uint32 addInt64(const int64 &value); + void addFile(const string &path); - static void removeFileFromCache(const string file); - static void clearFileCache(); -}; + static void removeFileFromCache(const string file); + static void clearFileCache(); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/util/conversion.h b/source/shared_lib/include/util/conversion.h index deeab9d4d..9df50469d 100644 --- a/source/shared_lib/include/util/conversion.h +++ b/source/shared_lib/include/util/conversion.h @@ -20,32 +20,34 @@ using std::string; using namespace Shared::Platform; -namespace Shared { namespace Util { +namespace Shared { + namespace Util { -bool strToBool(const string &s); -int strToInt(const string &s); -uint32 strToUInt(const string &s); -float strToFloat(const string &s); + bool strToBool(const string &s); + int strToInt(const string &s); + uint32 strToUInt(const string &s); + float strToFloat(const string &s); -bool strToBool(const string &s, bool *b); -bool strToInt(const string &s, int *i); -bool strToUInt(const string &s, uint32 *i); -bool strToFloat(const string &s, float *f); + bool strToBool(const string &s, bool *b); + bool strToInt(const string &s, int *i); + bool strToUInt(const string &s, uint32 *i); + bool strToFloat(const string &s, float *f); -string boolToStr(bool b); -string uIntToStr(const uint64 value); -string intToStr(const int64 value); -string intToHex(int i); -string floatToStr(float f,int precsion=2); -string doubleToStr(double f,int precsion=2); + string boolToStr(bool b); + string uIntToStr(const uint64 value); + string intToStr(const int64 value); + string intToHex(int i); + string floatToStr(float f, int precsion = 2); + string doubleToStr(double f, int precsion = 2); -bool IsNumeric(const char *p, bool allowNegative=true); + bool IsNumeric(const char *p, bool allowNegative = true); -string formatNumber(uint64 f); + string formatNumber(uint64 f); -double getTimeDuationMinutes(int frames, int updateFps); -string getTimeDuationString(int frames, int updateFps); + double getTimeDuationMinutes(int frames, int updateFps); + string getTimeDuationString(int frames, int updateFps); -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/util/factory.h b/source/shared_lib/include/util/factory.h index 0066fe110..f786f7442 100644 --- a/source/shared_lib/include/util/factory.h +++ b/source/shared_lib/include/util/factory.h @@ -23,67 +23,72 @@ using std::string; using std::pair; using std::runtime_error; -namespace Shared{ namespace Util{ +namespace Shared { + namespace Util { -// ===================================================== -// class SingleFactoryBase -// ===================================================== + // ===================================================== + // class SingleFactoryBase + // ===================================================== -class SingleFactoryBase{ -public: - virtual ~SingleFactoryBase(){} - virtual void *newInstance()= 0; -}; + class SingleFactoryBase { + public: + virtual ~SingleFactoryBase() { + } + virtual void *newInstance() = 0; + }; -// ===================================================== -// class SingleFactory -// ===================================================== + // ===================================================== + // class SingleFactory + // ===================================================== -template -class SingleFactory: public SingleFactoryBase{ -public: - virtual void *newInstance() {return new T();} -}; + template + class SingleFactory : public SingleFactoryBase { + public: + virtual void *newInstance() { + return new T(); + } + }; -// ===================================================== -// class MultiFactory -// ===================================================== + // ===================================================== + // class MultiFactory + // ===================================================== -template -class MultiFactory{ -private: - typedef map Factories; - typedef pair FactoryPair; + template + class MultiFactory { + private: + typedef map Factories; + typedef pair FactoryPair; -private: - Factories factories; + private: + Factories factories; + + public: + virtual ~MultiFactory() { + for (Factories::iterator it = factories.begin(); it != factories.end(); ++it) { + delete it->second; + } + factories.clear(); + } + + template + void registerClass(string classId) { + factories.insert(FactoryPair(classId, new SingleFactory())); + } + + T *newInstance(string classId) { + Factories::iterator it = factories.find(classId); + if (it == factories.end()) { + throw megaglest_runtime_error("Unknown class identifier: " + classId); + } + return static_cast(it->second->newInstance()); + } + + bool isClassId(string classId) { + return factories.find(classId) != factories.end(); + } + }; -public: - virtual ~MultiFactory(){ - for(Factories::iterator it= factories.begin(); it!=factories.end(); ++it){ - delete it->second; - } - factories.clear(); } - - template - void registerClass(string classId){ - factories.insert(FactoryPair(classId, new SingleFactory())); - } - - T *newInstance(string classId){ - Factories::iterator it= factories.find(classId); - if(it == factories.end()){ - throw megaglest_runtime_error("Unknown class identifier: " + classId); - } - return static_cast(it->second->newInstance()); - } - - bool isClassId(string classId){ - return factories.find(classId)!=factories.end(); - } -}; - -}}//end namespace +}//end namespace #endif diff --git a/source/shared_lib/include/util/gen_uuid.h b/source/shared_lib/include/util/gen_uuid.h index eec9b5b6b..0724617dd 100644 --- a/source/shared_lib/include/util/gen_uuid.h +++ b/source/shared_lib/include/util/gen_uuid.h @@ -11,73 +11,74 @@ /* what follows is a somewhat stripped-down version of the sample implementation of UUID generation from RFC 4122. */ -/* -** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. -** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & -** Digital Equipment Corporation, Maynard, Mass. -** Copyright (c) 1998 Microsoft. -** To anyone who acknowledges that this file is provided "AS IS" -** without any express or implied warranty: permission to use, copy, -** modify, and distribute this file for any purpose is hereby -** granted without fee, provided that the above copyright notices and -** this notice appears in all source code copies, and that none of -** the names of Open Software Foundation, Inc., Hewlett-Packard -** Company, Microsoft, or Digital Equipment Corporation be used in -** advertising or publicity pertaining to distribution of the software -** without specific, written prior permission. Neither Open Software -** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital -** Equipment Corporation makes any representations about the -** suitability of this software for any purpose. -*/ + /* + ** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. + ** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & + ** Digital Equipment Corporation, Maynard, Mass. + ** Copyright (c) 1998 Microsoft. + ** To anyone who acknowledges that this file is provided "AS IS" + ** without any express or implied warranty: permission to use, copy, + ** modify, and distribute this file for any purpose is hereby + ** granted without fee, provided that the above copyright notices and + ** this notice appears in all source code copies, and that none of + ** the names of Open Software Foundation, Inc., Hewlett-Packard + ** Company, Microsoft, or Digital Equipment Corporation be used in + ** advertising or publicity pertaining to distribution of the software + ** without specific, written prior permission. Neither Open Software + ** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital + ** Equipment Corporation makes any representations about the + ** suitability of this software for any purpose. + */ #ifndef _SHARED_PLATFORM_UUID_H_ #define _SHARED_PLATFORM_UUID_H_ -//#ifdef HAVE_CONFIG_H -//#include "config.h" -//#endif + //#ifdef HAVE_CONFIG_H + //#include "config.h" + //#endif #include #include #include -namespace Shared { namespace Util { +namespace Shared { + namespace Util { -//#if defined(HAVE_INTTYPES_H) -//#include -//#endif + //#if defined(HAVE_INTTYPES_H) + //#include + //#endif -/* set the following to the number of 100ns ticks of the actual - resolution of your system's clock */ + /* set the following to the number of 100ns ticks of the actual + resolution of your system's clock */ #define UUIDS_PER_TICK 1024 -//#ifdef WIN32 -//#include -//#include "missing\stdint.h" -//#define snprintf _snprintf -//#else -// -//#if HAVE_SYS_TYPES_H -//#include -//#else -//# if HAVE_STDINT_H -//# include -//# endif -//#endif -// -//#if HAVE_SYS_TIME_H -//#include -//#endif -// -//#if HAVE_SYS_SYSINFO_H -//#include -//#endif -// -//#endif + //#ifdef WIN32 + //#include + //#include "missing\stdint.h" + //#define snprintf _snprintf + //#else + // + //#if HAVE_SYS_TYPES_H + //#include + //#else + //# if HAVE_STDINT_H + //# include + //# endif + //#endif + // + //#if HAVE_SYS_TIME_H + //#include + //#endif + // + //#if HAVE_SYS_SYSINFO_H + //#include + //#endif + // + //#endif -/* system dependent call to get the current system time. Returned as - 100ns ticks since UUID epoch, but resolution may be less than - 100ns. */ + /* system dependent call to get the current system time. Returned as + 100ns ticks since UUID epoch, but resolution may be less than + 100ns. */ #ifdef WIN32 #define I64(C) C @@ -85,278 +86,280 @@ namespace Shared { namespace Util { #define I64(C) C##LL #endif -typedef uint64_t uuid_time_t; + typedef uint64_t uuid_time_t; -typedef struct { - char nodeID[6]; -} uuid_node_t; + typedef struct { + char nodeID[6]; + } uuid_node_t; #undef uuid_t -typedef struct { - uint32_t time_low; - uint16_t time_mid; - uint16_t time_hi_and_version; - uint8_t clock_seq_hi_and_reserved; - uint8_t clock_seq_low; - uint8_t node[6]; -} uuid_t; + typedef struct { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint8_t clock_seq_hi_and_reserved; + uint8_t clock_seq_low; + uint8_t node[6]; + } uuid_t; -/* some forward declarations. kind of wimpy to do that but heck, we - are all friends here right? raj 20081024 */ -inline static uint16_t true_random(void); + /* some forward declarations. kind of wimpy to do that but heck, we + are all friends here right? raj 20081024 */ + inline static uint16_t true_random(void); #ifdef WIN32 -inline static void get_system_time(uuid_time_t *uuid_time) { - ULARGE_INTEGER time; + inline static void get_system_time(uuid_time_t *uuid_time) { + ULARGE_INTEGER time; - /* NT keeps time in FILETIME format which is 100ns ticks since - Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582. - The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec) - + 18 years and 5 leap days. */ - GetSystemTimeAsFileTime((FILETIME *)&time); - time.QuadPart += + /* NT keeps time in FILETIME format which is 100ns ticks since + Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582. + The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec) + + 18 years and 5 leap days. */ + GetSystemTimeAsFileTime((FILETIME *) &time); + time.QuadPart += - (unsigned __int64) (1000*1000*10) // seconds - * (unsigned __int64) (60 * 60 * 24) // days - * (unsigned __int64) (17+30+31+365*18+5); // # of days - *uuid_time = time.QuadPart; -} + (unsigned __int64) (1000 * 1000 * 10) // seconds + * (unsigned __int64) (60 * 60 * 24) // days + * (unsigned __int64) (17 + 30 + 31 + 365 * 18 + 5); // # of days + *uuid_time = time.QuadPart; + } -/* Sample code, not for use in production; see RFC 1750 */ -inline static void get_random_info(char seed[16]) { - uint16_t myrand; - int i; + /* Sample code, not for use in production; see RFC 1750 */ + inline static void get_random_info(char seed[16]) { + uint16_t myrand; + int i; - i = 0; - do { - myrand = true_random(); - seed[i++] = myrand & 0xff; - seed[i++] = myrand >> 8; - } while (i < 14); -} + i = 0; + do { + myrand = true_random(); + seed[i++] = myrand & 0xff; + seed[i++] = myrand >> 8; + } while (i < 14); + } #else -inline static void get_system_time(uuid_time_t *uuid_time) { - struct timeval tp; - gettimeofday(&tp, (struct timezone *)0); + inline static void get_system_time(uuid_time_t *uuid_time) { + struct timeval tp; + gettimeofday(&tp, (struct timezone *)0); - /* Offset between UUID formatted times and Unix formatted times. - UUID UTC base time is October 15, 1582. - Unix base time is January 1, 1970.*/ - *uuid_time = ((uint64_t)tp.tv_sec * 10000000) - + ((uint64_t)tp.tv_usec * 10) - + I64(0x01B21DD213814000); -} + /* Offset between UUID formatted times and Unix formatted times. + UUID UTC base time is October 15, 1582. + Unix base time is January 1, 1970.*/ + *uuid_time = ((uint64_t) tp.tv_sec * 10000000) + + ((uint64_t) tp.tv_usec * 10) + + I64(0x01B21DD213814000); + } -/* Sample code, not for use in production; see RFC 1750 */ -inline static void get_random_info(char seed[16]) { - FILE *fp; - uint16_t myrand; - int i; + /* Sample code, not for use in production; see RFC 1750 */ + inline static void get_random_info(char seed[16]) { + FILE *fp; + uint16_t myrand; + int i; - /* we aren't all that picky, and we would rather not block so we - will use urandom */ - fp = fopen("/dev/urandom","rb"); + /* we aren't all that picky, and we would rather not block so we + will use urandom */ + fp = fopen("/dev/urandom", "rb"); - if (NULL != fp) { - size_t bytes = fread(seed,sizeof(char),16,fp); - if(bytes <= 0) { } - fclose(fp); - return; - } + if (NULL != fp) { + size_t bytes = fread(seed, sizeof(char), 16, fp); + if (bytes <= 0) { + } + fclose(fp); + return; + } - /* ok, now what? */ + /* ok, now what? */ - i = 0; - do { - myrand = true_random(); - seed[i++] = myrand & 0xff; - seed[i++] = myrand >> 8; - } while (i < 14); -} + i = 0; + do { + myrand = true_random(); + seed[i++] = myrand & 0xff; + seed[i++] = myrand >> 8; + } while (i < 14); + } #endif -/* true_random -- generate a crypto-quality random number. -**This sample doesn't do that.** */ -inline static uint16_t true_random(void) { - static int inited = 0; - uuid_time_t time_now; + /* true_random -- generate a crypto-quality random number. + **This sample doesn't do that.** */ + inline static uint16_t true_random(void) { + static int inited = 0; + uuid_time_t time_now; - if (!inited) { - get_system_time(&time_now); - time_now = time_now / UUIDS_PER_TICK; - srand((unsigned int) (((time_now >> 32) ^ time_now) & 0xffffffff)); - inited = 1; - } + if (!inited) { + get_system_time(&time_now); + time_now = time_now / UUIDS_PER_TICK; + srand((unsigned int) (((time_now >> 32) ^ time_now) & 0xffffffff)); + inited = 1; + } - return (uint16_t)rand(); -} + return (uint16_t) rand(); + } -/* puid -- print a UUID */ -inline void puid(uuid_t u) { - int i; + /* puid -- print a UUID */ + inline void puid(uuid_t u) { + int i; - printf("%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", u.time_low, u.time_mid, - u.time_hi_and_version, u.clock_seq_hi_and_reserved, - u.clock_seq_low); - for (i = 0; i < 6; i++) - printf("%2.2x", u.node[i]); - printf("\n"); -} + printf("%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", u.time_low, u.time_mid, + u.time_hi_and_version, u.clock_seq_hi_and_reserved, + u.clock_seq_low); + for (i = 0; i < 6; i++) + printf("%2.2x", u.node[i]); + printf("\n"); + } -/* snpuid -- print a UUID in the supplied buffer */ -inline void snpuid(char *str, size_t size, uuid_t u) { - int i; - char *tmp = str; + /* snpuid -- print a UUID in the supplied buffer */ + inline void snpuid(char *str, size_t size, uuid_t u) { + int i; + char *tmp = str; - if (size < 38) { - snprintf(tmp,size,"%s","uuid string too small"); - return; - } + if (size < 38) { + snprintf(tmp, size, "%s", "uuid string too small"); + return; + } - /* perhaps this is a trifle optimistic but what the heck */ - sprintf(tmp, - "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", - u.time_low, - u.time_mid, - u.time_hi_and_version, - u.clock_seq_hi_and_reserved, - u.clock_seq_low); - tmp += 24; - for (i = 0; i < 6; i++) { - sprintf(tmp,"%2.2x", u.node[i]); - tmp += 2; - } - *tmp = 0; -} + /* perhaps this is a trifle optimistic but what the heck */ + sprintf(tmp, + "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", + u.time_low, + u.time_mid, + u.time_hi_and_version, + u.clock_seq_hi_and_reserved, + u.clock_seq_low); + tmp += 24; + for (i = 0; i < 6; i++) { + sprintf(tmp, "%2.2x", u.node[i]); + tmp += 2; + } + *tmp = 0; + } -/* get-current_time -- get time as 60-bit 100ns ticks since UUID epoch. - Compensate for the fact that real clock resolution is - less than 100ns. */ -inline static void get_current_time(uuid_time_t *timestamp) { - static int inited = 0; - static uuid_time_t time_last; - static uint16_t uuids_this_tick; - uuid_time_t time_now; + /* get-current_time -- get time as 60-bit 100ns ticks since UUID epoch. + Compensate for the fact that real clock resolution is + less than 100ns. */ + inline static void get_current_time(uuid_time_t *timestamp) { + static int inited = 0; + static uuid_time_t time_last; + static uint16_t uuids_this_tick; + uuid_time_t time_now; - if (!inited) { - get_system_time(&time_now); - uuids_this_tick = UUIDS_PER_TICK; - inited = 1; - } + if (!inited) { + get_system_time(&time_now); + uuids_this_tick = UUIDS_PER_TICK; + inited = 1; + } - for ( ; ; ) { - get_system_time(&time_now); + for (; ; ) { + get_system_time(&time_now); - /* if clock reading changed since last UUID generated, */ - if (time_last != time_now) { - /* reset count of uuids gen'd with this clock reading */ - uuids_this_tick = 0; - time_last = time_now; - break; - } - if (uuids_this_tick < UUIDS_PER_TICK) { - uuids_this_tick++; - break; - } - /* going too fast for our clock; spin */ - } - /* add the count of uuids to low order bits of the clock reading */ - *timestamp = time_now + uuids_this_tick; -} + /* if clock reading changed since last UUID generated, */ + if (time_last != time_now) { + /* reset count of uuids gen'd with this clock reading */ + uuids_this_tick = 0; + time_last = time_now; + break; + } + if (uuids_this_tick < UUIDS_PER_TICK) { + uuids_this_tick++; + break; + } + /* going too fast for our clock; spin */ + } + /* add the count of uuids to low order bits of the clock reading */ + *timestamp = time_now + uuids_this_tick; + } -/* system dependent call to get IEEE node ID. - This sample implementation generates a random node ID. */ -/* netperf mod - don't bother trying to read or write the nodeid */ -inline static void get_ieee_node_identifier(uuid_node_t *node) { - static int inited = 0; - static uuid_node_t saved_node; - char seed[16]; + /* system dependent call to get IEEE node ID. + This sample implementation generates a random node ID. */ + /* netperf mod - don't bother trying to read or write the nodeid */ + inline static void get_ieee_node_identifier(uuid_node_t *node) { + static int inited = 0; + static uuid_node_t saved_node; + char seed[16]; - if (!inited) { - get_random_info(seed); - seed[0] |= 0x01; - memcpy(&saved_node, seed, sizeof saved_node); - } - inited = 1; + if (!inited) { + get_random_info(seed); + seed[0] |= 0x01; + memcpy(&saved_node, seed, sizeof saved_node); + } + inited = 1; - *node = saved_node; -} + *node = saved_node; + } -/* format_uuid_v1 -- make a UUID from the timestamp, clockseq, - and node ID */ -inline static void format_uuid_v1(uuid_t* uuid, uint16_t clock_seq, - uuid_time_t timestamp, uuid_node_t node) { - /* Construct a version 1 uuid with the information we've gathered - plus a few constants. */ - uuid->time_low = (unsigned long)(timestamp & 0xFFFFFFFF); - uuid->time_mid = (unsigned short)((timestamp >> 32) & 0xFFFF); - uuid->time_hi_and_version = - (unsigned short)((timestamp >> 48) & 0x0FFF); - uuid->time_hi_and_version |= (1 << 12); - uuid->clock_seq_low = clock_seq & 0xFF; - uuid->clock_seq_hi_and_reserved = (clock_seq & 0x3F00) >> 8; - uuid->clock_seq_hi_and_reserved |= 0x80; - memcpy(&uuid->node, &node, sizeof uuid->node); -} + /* format_uuid_v1 -- make a UUID from the timestamp, clockseq, + and node ID */ + inline static void format_uuid_v1(uuid_t* uuid, uint16_t clock_seq, + uuid_time_t timestamp, uuid_node_t node) { + /* Construct a version 1 uuid with the information we've gathered + plus a few constants. */ + uuid->time_low = (unsigned long) (timestamp & 0xFFFFFFFF); + uuid->time_mid = (unsigned short) ((timestamp >> 32) & 0xFFFF); + uuid->time_hi_and_version = + (unsigned short) ((timestamp >> 48) & 0x0FFF); + uuid->time_hi_and_version |= (1 << 12); + uuid->clock_seq_low = clock_seq & 0xFF; + uuid->clock_seq_hi_and_reserved = (clock_seq & 0x3F00) >> 8; + uuid->clock_seq_hi_and_reserved |= 0x80; + memcpy(&uuid->node, &node, sizeof uuid->node); + } -/* uuid_create -- generator a UUID */ -inline int uuid_create(uuid_t *uuid) { - uuid_time_t timestamp; - uint16_t clockseq; - uuid_node_t node; + /* uuid_create -- generator a UUID */ + inline int uuid_create(uuid_t *uuid) { + uuid_time_t timestamp; + uint16_t clockseq; + uuid_node_t node; - /* get time, node ID, saved state from non-volatile storage */ - get_current_time(×tamp); - get_ieee_node_identifier(&node); + /* get time, node ID, saved state from non-volatile storage */ + get_current_time(×tamp); + get_ieee_node_identifier(&node); - /* for us clockseq is always to be random as we have no state */ - clockseq = true_random(); + /* for us clockseq is always to be random as we have no state */ + clockseq = true_random(); - /* stuff fields into the UUID */ - format_uuid_v1(uuid, clockseq, timestamp, node); - return 1; -} + /* stuff fields into the UUID */ + format_uuid_v1(uuid, clockseq, timestamp, node); + return 1; + } -inline void get_uuid_string(char *uuid_str, size_t size) { - uuid_t u; + inline void get_uuid_string(char *uuid_str, size_t size) { + uuid_t u; - uuid_create(&u); - snpuid(uuid_str,size,u); + uuid_create(&u); + snpuid(uuid_str, size, u); - return; -} + return; + } -inline string getUUIDAsString() { - char uuid_str[38]; - get_uuid_string(uuid_str,sizeof(uuid_str)); - return uuid_str; -} + inline string getUUIDAsString() { + char uuid_str[38]; + get_uuid_string(uuid_str, sizeof(uuid_str)); + return uuid_str; + } -//#ifdef NETPERF_STANDALONE_DEBUG -// -//int -//main(int argc, char *argv[]) -//{ -// uuid_t u; -// char uuid_str[38]; -//#if 0 -// uuid_create(&u); -// printf("uuid_create(): "); puid(u); -// snpuid(uuid_str,sizeof(uuid_str),u); -// printf("\nas a string %s\n",uuid_str); -//#endif -// get_uuid_string(uuid_str,sizeof(uuid_str)); -// printf("uuid_str is %s\n",uuid_str); -// return 0; -//} -// -//#endif + //#ifdef NETPERF_STANDALONE_DEBUG + // + //int + //main(int argc, char *argv[]) + //{ + // uuid_t u; + // char uuid_str[38]; + //#if 0 + // uuid_create(&u); + // printf("uuid_create(): "); puid(u); + // snpuid(uuid_str,sizeof(uuid_str),u); + // printf("\nas a string %s\n",uuid_str); + //#endif + // get_uuid_string(uuid_str,sizeof(uuid_str)); + // printf("uuid_str is %s\n",uuid_str); + // return 0; + //} + // + //#endif -}}; + } +}; #endif diff --git a/source/shared_lib/include/util/leak_dumper.h b/source/shared_lib/include/util/leak_dumper.h index babdb6a2f..8c9a3744e 100644 --- a/source/shared_lib/include/util/leak_dumper.h +++ b/source/shared_lib/include/util/leak_dumper.h @@ -49,7 +49,7 @@ using namespace std; //occurred in a file where this header is included will have //file and line number -static bool want_full_leak_stacktrace = false; +static bool want_full_leak_stacktrace = false; static bool want_full_leak_stacktrace_line_numbers = false; struct AllocInfo { @@ -80,104 +80,102 @@ public: : ptr(ptr), file(file), line(line), bytes(bytes), array(array), freetouse(false), inuse(true), stack(stacktrace) { } -//#if defined(__GNUC__) && !defined(__FreeBSD__) && !defined(BSD) + //#if defined(__GNUC__) && !defined(__FreeBSD__) && !defined(BSD) #if defined(HAS_GCC_BACKTRACE) inline static int getFileAndLine(char *function, void *address, char *file, size_t flen) { - int line=-1; - if(want_full_leak_stacktrace_line_numbers == true && AllocInfo::get_application_binary() != "") { - const int maxbufSize = 8094; - char buf[maxbufSize+1]=""; - //char *p=NULL; + int line = -1; + if (want_full_leak_stacktrace_line_numbers == true && AllocInfo::get_application_binary() != "") { + const int maxbufSize = 8094; + char buf[maxbufSize + 1] = ""; + //char *p=NULL; - // prepare command to be executed - // our program need to be passed after the -e parameter - //sprintf (buf, "/usr/bin/addr2line -C -e ./a.out -f -i %lx", addr); - snprintf(buf, 8096,"addr2line -C -e %s -f -i %p",AllocInfo::get_application_binary().c_str(),address); + // prepare command to be executed + // our program need to be passed after the -e parameter + //sprintf (buf, "/usr/bin/addr2line -C -e ./a.out -f -i %lx", addr); + snprintf(buf, 8096, "addr2line -C -e %s -f -i %p", AllocInfo::get_application_binary().c_str(), address); - FILE* f = popen (buf, "r"); - if (f == NULL) { - perror (buf); - return 0; - } + FILE* f = popen(buf, "r"); + if (f == NULL) { + perror(buf); + return 0; + } - if(function != NULL && function[0] != '\0') { - line = 0; - for(;function != NULL && function[0] != '\0';) { - // get function name - char *ret = fgets (buf, maxbufSize, f); - if(ret == NULL) { - pclose(f); - return line; - } - //printf("Looking for [%s] Found [%s]\n",function,ret); - if(strstr(ret,function) != NULL) { - break; - } - - // get file and line - ret = fgets (buf, maxbufSize, f); - if(ret == NULL) { - pclose(f); - return line; - } - - if(strlen(buf) > 0 && buf[0] != '?') { - //int l; - char *p = buf; - - // file name is until ':' - while(*p != 0 && *p != ':') { - p++; - } - - *p++ = 0; - // after file name follows line number - strcpy (file , buf); - sscanf (p,"%d", &line); - } - else { - strcpy (file,"unknown"); - line = 0; - } + if (function != NULL && function[0] != '\0') { + line = 0; + for (; function != NULL && function[0] != '\0';) { + // get function name + char *ret = fgets(buf, maxbufSize, f); + if (ret == NULL) { + pclose(f); + return line; } - } - - // get file and line - char *ret = fgets (buf, maxbufSize, f); - if(ret == NULL) { - pclose(f); - return line; - } - - if(strlen(buf) > 0 && buf[0] != '?') { - //int l; - char *p = buf; - - // file name is until ':' - while(*p != 0 && *p != ':') { - p++; + //printf("Looking for [%s] Found [%s]\n",function,ret); + if (strstr(ret, function) != NULL) { + break; } - *p++ = 0; - // after file name follows line number - strcpy (file , buf); - sscanf (p,"%d", &line); - } - else { - strcpy (file,"unknown"); - line = 0; + // get file and line + ret = fgets(buf, maxbufSize, f); + if (ret == NULL) { + pclose(f); + return line; + } + + if (strlen(buf) > 0 && buf[0] != '?') { + //int l; + char *p = buf; + + // file name is until ':' + while (*p != 0 && *p != ':') { + p++; + } + + *p++ = 0; + // after file name follows line number + strcpy(file, buf); + sscanf(p, "%d", &line); + } else { + strcpy(file, "unknown"); + line = 0; + } } + } + + // get file and line + char *ret = fgets(buf, maxbufSize, f); + if (ret == NULL) { pclose(f); - } - return line; + return line; + } + + if (strlen(buf) > 0 && buf[0] != '?') { + //int l; + char *p = buf; + + // file name is until ':' + while (*p != 0 && *p != ':') { + p++; + } + + *p++ = 0; + // after file name follows line number + strcpy(file, buf); + sscanf(p, "%d", &line); + } else { + strcpy(file, "unknown"); + line = 0; + } + pclose(f); + } + return line; } #endif inline static string getStackTrace() { -//#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD) + //#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(__FreeBSD__) && !defined(BSD) #if defined(HAS_GCC_BACKTRACE) - if(want_full_leak_stacktrace == true) { - string errMsg = "\nStack Trace:\n"; + if (want_full_leak_stacktrace == true) { + string errMsg = "\nStack Trace:\n"; //errMsg += "To find line #'s use:\n"; //errMsg += "readelf --debug-dump=decodedline %s | egrep 0xaddress-of-stack\n"; @@ -191,9 +189,9 @@ public: //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(stack_depth > 0) { - char szBuf[8096]=""; - for(size_t i = 1; i < stack_depth; i++) { + if (stack_depth > 0) { + char szBuf[8096] = ""; + for (size_t i = 1; i < stack_depth; i++) { void *lineAddress = stack_addrs[i]; //getStackAddress(stackIndex); size_t sz = 8096; // just a guess, template names will go much wider @@ -207,8 +205,7 @@ public: for (char *j = stack_strings[i]; *j; ++j) { if (*j == '(') { begin = j; - } - else if (*j == '+') { + } else if (*j == '+') { end = j; } } @@ -222,31 +219,29 @@ public: if (ret) { // return value may be a realloc() of the input function = ret; - } - else { + } else { // demangling failed, just pretend it's a C function with no args strncpy(function, begin, sz); strncat(function, "()", sz); - function[sz-1] = '\0'; + function[sz - 1] = '\0'; } //fprintf(out, " %s:%s\n", stack.strings[i], function); - snprintf(szBuf,8096,"%s:%s address [%p]",stack_strings[i],function,lineAddress); - } - else { + snprintf(szBuf, 8096, "%s:%s address [%p]", stack_strings[i], function, lineAddress); + } else { // didn't find the mangled name, just print the whole line //fprintf(out, " %s\n", stack.strings[i]); - snprintf(szBuf,8096,"%s address [%p]",stack_strings[i],lineAddress); + snprintf(szBuf, 8096, "%s address [%p]", stack_strings[i], lineAddress); } errMsg += string(szBuf); - if(want_full_leak_stacktrace_line_numbers == true && AllocInfo::get_application_binary() != "") { - char file[8096]=""; + if (want_full_leak_stacktrace_line_numbers == true && AllocInfo::get_application_binary() != "") { + char file[8096] = ""; int line = getFileAndLine(function, lineAddress, file, 8096); - if(line >= 0) { - char lineBuf[1024]=""; - snprintf(lineBuf,1024,"%d",line); + if (line >= 0) { + char lineBuf[1024] = ""; + snprintf(lineBuf, 1024, "%d", line); errMsg += " line: " + string(lineBuf); } } @@ -259,14 +254,13 @@ public: //printf("%s",errMsg.c_str()); return errMsg; - } - else { - static string empty = ""; - return empty; - } + } else { + static string empty = ""; + return empty; + } #else - static string empty = ""; - return empty; + static string empty = ""; + return empty; #endif } }; @@ -277,7 +271,7 @@ public: class AllocRegistry { private: - static const size_t maxAllocs= 100000; + static const size_t maxAllocs = 100000; Mutex *mutex; private: @@ -308,13 +302,13 @@ public: } inline void reset() { - allocCount= 0; - allocBytes= 0; - nonMonitoredCount= 0; - nonMonitoredBytes= 0; + allocCount = 0; + allocBytes = 0; + nonMonitoredCount = 0; + nonMonitoredBytes = 0; nextFreeIndex = 0; - for(int i = 0; i < maxAllocs; ++i) { + for (int i = 0; i < maxAllocs; ++i) { allocs[i].freetouse = true; allocs[i].inuse = false; } @@ -326,14 +320,14 @@ public: MutexSafeWrapper safeMutexMasterList(mutex); //printf("ALLOCATE.\tfile: %s, line: %d, bytes: " MG_SIZE_T_SPECIFIER ", array: %d inuse: %d\n", info.file, info.line, info.bytes, info.array, info.inuse); - if(info.line > 0) { + if (info.line > 0) { ++allocCount; allocBytes += info.bytes; } - for(int i = (nextFreeIndex >= 0 ? nextFreeIndex : 0); i < maxAllocs; ++i) { - if(allocs[i].freetouse == true && allocs[i].inuse == false) { - allocs[i]= info; - nextFreeIndex=-1; + for (int i = (nextFreeIndex >= 0 ? nextFreeIndex : 0); i < maxAllocs; ++i) { + if (allocs[i].freetouse == true && allocs[i].inuse == false) { + allocs[i] = info; + nextFreeIndex = -1; return; } @@ -342,26 +336,26 @@ public: printf("ALLOCATE NOT MONITORED.\tfile: %s, line: %d, ptr [%p], bytes: " MG_SIZE_T_SPECIFIER ", array: %d inuse: %d, \n%s\n", info.file, info.line, info.ptr, info.bytes, info.array, info.inuse, info.stack.c_str()); ++nonMonitoredCount; - nonMonitoredBytes+= info.bytes; + nonMonitoredBytes += info.bytes; } - inline void deallocate(void* ptr, bool array,const char* file, int line) { + inline void deallocate(void* ptr, bool array, const char* file, int line) { //if(line == 0) return; MutexSafeWrapper safeMutexMasterList(mutex); - for(int i=0; i < maxAllocs; ++i) { - if(allocs[i].freetouse == false && allocs[i].inuse == true && - allocs[i].ptr == ptr && allocs[i].array == array) { - allocs[i].freetouse= true; + for (int i = 0; i < maxAllocs; ++i) { + if (allocs[i].freetouse == false && allocs[i].inuse == true && + allocs[i].ptr == ptr && allocs[i].array == array) { + allocs[i].freetouse = true; allocs[i].inuse = false; - nextFreeIndex=i; + nextFreeIndex = i; return; } } - if(line > 0) printf("WARNING, possible error on pointer delete for ptr [%p] array = %d, file [%s] line: %d\n%s\n",ptr,array,file, line,AllocInfo::getStackTrace().c_str()); + if (line > 0) printf("WARNING, possible error on pointer delete for ptr [%p] array = %d, file [%s] line: %d\n%s\n", ptr, array, file, line, AllocInfo::getStackTrace().c_str()); } void dump(const char *path); @@ -370,7 +364,7 @@ public: //if an allocation ocurrs in a file where "leaks_dumper.h" is not included //this operator new is called and file and line will be unknown inline void * operator new (size_t bytes) { - void *ptr= malloc(bytes); + void *ptr = malloc(bytes); AllocRegistry::getInstance().allocate(AllocInfo(ptr, "unknown", 0, "", bytes, false)); return ptr; } @@ -381,7 +375,7 @@ inline void operator delete(void *ptr) { } inline void * operator new[](size_t bytes) { - void *ptr= malloc(bytes); + void *ptr = malloc(bytes); AllocRegistry::getInstance().allocate(AllocInfo(ptr, "unknown", 0, "", bytes, true)); return ptr; } @@ -394,7 +388,7 @@ inline void operator delete [](void *ptr) { //if an allocation ocurrs in a file where "leaks_dumper.h" is included //this operator new is called and file and line will be known inline void * operator new (size_t bytes, const char* file, int line, string stack) { - void *ptr= malloc(bytes); + void *ptr = malloc(bytes); AllocRegistry::getInstance().allocate(AllocInfo(ptr, file, line, stack, bytes, false)); return ptr; } @@ -404,8 +398,8 @@ inline void operator delete(void *ptr, const char* file, int line) { free(ptr); } -inline void * operator new[](size_t bytes, const char* file, int line,string stack) { - void *ptr= malloc(bytes); +inline void * operator new[](size_t bytes, const char* file, int line, string stack) { + void *ptr = malloc(bytes); AllocRegistry::getInstance().allocate(AllocInfo(ptr, file, line, stack, bytes, true)); return ptr; } diff --git a/source/shared_lib/include/util/profiler.h b/source/shared_lib/include/util/profiler.h index de0820a35..ca0170d8d 100644 --- a/source/shared_lib/include/util/profiler.h +++ b/source/shared_lib/include/util/profiler.h @@ -26,76 +26,90 @@ using std::string; using Shared::PlatformCommon::Chrono; -namespace Shared{ namespace Util{ +namespace Shared { + namespace Util { #ifdef SL_PROFILE -// ===================================================== -// class Section -// ===================================================== + // ===================================================== + // class Section + // ===================================================== -class Section{ -public: - typedef list SectionContainer; -private: - string name; - Chrono chrono; - int64 milisElapsed; - Section *parent; - SectionContainer children; + class Section { + public: + typedef list SectionContainer; + private: + string name; + Chrono chrono; + int64 milisElapsed; + Section *parent; + SectionContainer children; -public: - Section(const string &name); + public: + Section(const string &name); - Section *getParent() {return parent;} - const string &getName() const {return name;} + Section *getParent() { + return parent; + } + const string &getName() const { + return name; + } - void setParent(Section *parent) {this->parent= parent;} + void setParent(Section *parent) { + this->parent = parent; + } - void start() {chrono.start();} - void stop() {milisElapsed+=chrono.getMillis();} + void start() { + chrono.start(); + } + void stop() { + milisElapsed += chrono.getMillis(); + } - void addChild(Section *child) {children.push_back(child);} - Section *getChild(const string &name); + void addChild(Section *child) { + children.push_back(child); + } + Section *getChild(const string &name); - void print(FILE *outSream, int tabLevel=0); -}; + void print(FILE *outSream, int tabLevel = 0); + }; -// ===================================================== -// class Profiler -// ===================================================== + // ===================================================== + // class Profiler + // ===================================================== -class Profiler{ -private: - Section *rootSection; - Section *currSection; -private: - Profiler(); -public: - ~Profiler(); - static Profiler &getInstance(); - void sectionBegin(const string &name); - void sectionEnd(const string &name); -}; + class Profiler { + private: + Section * rootSection; + Section *currSection; + private: + Profiler(); + public: + ~Profiler(); + static Profiler &getInstance(); + void sectionBegin(const string &name); + void sectionEnd(const string &name); + }; #endif //SL_PROFILE -// ===================================================== -// class funtions -// ===================================================== + // ===================================================== + // class funtions + // ===================================================== -inline void profileBegin(const string §ionName){ + inline void profileBegin(const string §ionName) { #ifdef SL_PROFILE - Profiler::getInstance().sectionBegin(sectionName); + Profiler::getInstance().sectionBegin(sectionName); #endif -} + } -inline void profileEnd(const string §ionName){ + inline void profileEnd(const string §ionName) { #ifdef SL_PROFILE - Profiler::getInstance().sectionEnd(sectionName); + Profiler::getInstance().sectionEnd(sectionName); #endif -} + } -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/util/properties.h b/source/shared_lib/include/util/properties.h index 038facfee..badff4c21 100644 --- a/source/shared_lib/include/util/properties.h +++ b/source/shared_lib/include/util/properties.h @@ -22,99 +22,127 @@ using std::vector; using std::string; using std::pair; -namespace Shared{ namespace Util{ +namespace Shared { + namespace Util { -// ===================================================== -// class Properties -// -/// ini-like file loader -// ===================================================== + // ===================================================== + // class Properties + // + /// ini-like file loader + // ===================================================== -class Properties { -private: - static const int maxLine= 4096; + class Properties { + private: + static const int maxLine = 4096; -public: - typedef pair PropertyPair; - typedef map PropertyMap; - typedef vector PropertyVector; + public: + typedef pair PropertyPair; + typedef map PropertyMap; + typedef vector PropertyVector; -private: - PropertyVector propertyVector; - PropertyMap propertyMap; - PropertyVector propertyVectorTmp; - PropertyMap propertyMapTmp; + private: + PropertyVector propertyVector; + PropertyMap propertyMap; + PropertyVector propertyVectorTmp; + PropertyMap propertyMapTmp; - string path; - static string applicationPath; - static string applicationDataPath; - static string gameVersion; + string path; + static string applicationPath; + static string applicationDataPath; + static string gameVersion; - static string techtreePath; - static string scenarioPath; - static string tutorialPath; + static string techtreePath; + static string scenarioPath; + static string tutorialPath; -protected: - void processTextLine(bool is_utf8_language, char *lineBuffer); + protected: + void processTextLine(bool is_utf8_language, char *lineBuffer); -public: - static void setApplicationPath(string value) { applicationPath=value; } - static string getApplicationPath() { return applicationPath; } + public: + static void setApplicationPath(string value) { + applicationPath = value; + } + static string getApplicationPath() { + return applicationPath; + } - static void setApplicationDataPath(string value) { applicationDataPath=value; } - static string getApplicationDataPath() { return applicationDataPath; } + static void setApplicationDataPath(string value) { + applicationDataPath = value; + } + static string getApplicationDataPath() { + return applicationDataPath; + } - static void setGameVersion(string value) { gameVersion=value; } - static string getGameVersion() { return gameVersion; } + static void setGameVersion(string value) { + gameVersion = value; + } + static string getGameVersion() { + return gameVersion; + } - static void setTechtreePath(string value) { techtreePath=value; } - static string getTechtreePath() { return techtreePath; } - static void setScenarioPath(string value) { scenarioPath=value; } - static string getScenarioPath() { return scenarioPath; } - static void setTutorialPath(string value) { tutorialPath=value; } - static string getTutorialPath() { return tutorialPath; } + static void setTechtreePath(string value) { + techtreePath = value; + } + static string getTechtreePath() { + return techtreePath; + } + static void setScenarioPath(string value) { + scenarioPath = value; + } + static string getScenarioPath() { + return scenarioPath; + } + static void setTutorialPath(string value) { + tutorialPath = value; + } + static string getTutorialPath() { + return tutorialPath; + } - void clear(); + void clear(); - void loadFromText(const string &text); - void load(const string &path,bool clearCurrentProperties=true); - void save(const string &path); + void loadFromText(const string &text); + void load(const string &path, bool clearCurrentProperties = true); + void save(const string &path); - int getPropertyCount() const; - string getKey(int i) const; - string getString(int i) const; + int getPropertyCount() const; + string getKey(int i) const; + string getString(int i) const; - bool getBool(const string &key, const char *defaultValueIfNotFound=NULL) const; - int getInt(const string &key, const char *defaultValueIfNotFound=NULL) const; - int getInt(const string &key, int min, int max, const char *defaultValueIfNotFound=NULL) const; - float getFloat(const string &key, const char *defaultValueIfNotFound=NULL) const; - float getFloat(const string &key, float min, float max, const char *defaultValueIfNotFound=NULL) const; + bool getBool(const string &key, const char *defaultValueIfNotFound = NULL) const; + int getInt(const string &key, const char *defaultValueIfNotFound = NULL) const; + int getInt(const string &key, int min, int max, const char *defaultValueIfNotFound = NULL) const; + float getFloat(const string &key, const char *defaultValueIfNotFound = NULL) const; + float getFloat(const string &key, float min, float max, const char *defaultValueIfNotFound = NULL) const; - const string getString(const string &key, const char *defaultValueIfNotFound=NULL) const; + const string getString(const string &key, const char *defaultValueIfNotFound = NULL) const; - int getInt(const char *key,const char *defaultValueIfNotFound=NULL) const; - bool getBool(const char *key,const char *defaultValueIfNotFound=NULL) const; - float getFloat(const char *key,const char *defaultValueIfNotFound=NULL) const; - const string getString(const char *key,const char *defaultValueIfNotFound=NULL) const; - const string getRandomKey(const bool realrandom) const; + int getInt(const char *key, const char *defaultValueIfNotFound = NULL) const; + bool getBool(const char *key, const char *defaultValueIfNotFound = NULL) const; + float getFloat(const char *key, const char *defaultValueIfNotFound = NULL) const; + const string getString(const char *key, const char *defaultValueIfNotFound = NULL) const; + const string getRandomKey(const bool realrandom) const; - void setInt(const string &key, int value); - void setBool(const string &key, bool value); - void setFloat(const string &key, float value); - void setString(const string &key, const string &value); + void setInt(const string &key, int value); + void setBool(const string &key, bool value); + void setFloat(const string &key, float value); + void setString(const string &key, const string &value); - bool hasString(const string &key) const; + bool hasString(const string &key) const; - static bool applyTagsToValue(string &value, const std::map *mapTagReplacementValues=NULL, bool skipUpdatePathClimbingParts=false); - static std::map getTagReplacementValues(std::map *mapExtraTagReplacementValues=NULL); - static bool isValuePathVariable(const string &value); - static void updateValuePathVariable(string &value, bool skipUpdatePathClimbingParts=false); + static bool applyTagsToValue(string &value, const std::map *mapTagReplacementValues = NULL, bool skipUpdatePathClimbingParts = false); + static std::map getTagReplacementValues(std::map *mapExtraTagReplacementValues = NULL); + static bool isValuePathVariable(const string &value); + static void updateValuePathVariable(string &value, bool skipUpdatePathClimbingParts = false); - string getpath() const { return path;} + string getpath() const { + return path; + } - string toString(); -}; + string toString(); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/util/randomgen.h b/source/shared_lib/include/util/randomgen.h index 00f225899..71fe379b8 100644 --- a/source/shared_lib/include/util/randomgen.h +++ b/source/shared_lib/include/util/randomgen.h @@ -17,41 +17,49 @@ #include #include "leak_dumper.h" -namespace Shared { namespace Util { +namespace Shared { + namespace Util { -// ===================================================== -// class RandomGen -// ===================================================== + // ===================================================== + // class RandomGen + // ===================================================== -class RandomGen { -private: - static const int m; - static const int a; - static const int b; + class RandomGen { + private: + static const int m; + static const int a; + static const int b; -private: - int lastNumber; - std::vector lastCaller; - bool disableLastCallerTracking; + private: + int lastNumber; + std::vector lastCaller; + bool disableLastCallerTracking; - int rand(std::string lastCaller); + int rand(std::string lastCaller); -public: - RandomGen(); - void init(int seed); + public: + RandomGen(); + void init(int seed); - int randRange(int min, int max,std::string lastCaller=""); - float randRange(float min, float max,std::string lastCaller=""); + int randRange(int min, int max, std::string lastCaller = ""); + float randRange(float min, float max, std::string lastCaller = ""); - int getLastNumber() const { return lastNumber; } - void setLastNumber(int value) { lastNumber = value; } + int getLastNumber() const { + return lastNumber; + } + void setLastNumber(int value) { + lastNumber = value; + } - std::string getLastCaller() const; - void clearLastCaller(); - void addLastCaller(std::string text); - void setDisableLastCallerTracking(bool value) { disableLastCallerTracking = value; } -}; + std::string getLastCaller() const; + void clearLastCaller(); + void addLastCaller(std::string text); + void setDisableLastCallerTracking(bool value) { + disableLastCallerTracking = value; + } + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/include/util/string_utils.h b/source/shared_lib/include/util/string_utils.h index 55e5d7cb0..778ef8bb5 100644 --- a/source/shared_lib/include/util/string_utils.h +++ b/source/shared_lib/include/util/string_utils.h @@ -1,19 +1,19 @@ /* Portions taken from: - Copyright (C) 2005 Roland BROCHARD + Copyright (C) 2005 Roland BROCHARD - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA*/ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA*/ #ifndef _SHARED_UTIL_W_STRING_H__ #define _SHARED_UTIL_W_STRING_H__ @@ -32,40 +32,43 @@ using Shared::Platform::byte; using namespace Shared::Platform; -namespace Shared { namespace Util { +namespace Shared { + namespace Util { - /*! - ** \brief Convert a string from ASCII to UTF8 - ** \param s The string to convert - ** \return A new Null-terminated String (must be deleted with the keyword `delete[]`), even if s is NULL - */ - char* ConvertToUTF8(const char* s); + /*! + ** \brief Convert a string from ASCII to UTF8 + ** \param s The string to convert + ** \return A new Null-terminated String (must be deleted with the keyword `delete[]`), even if s is NULL + */ + char* ConvertToUTF8(const char* s); - char* ConvertFromUTF8(const char* str); + char* ConvertFromUTF8(const char* str); - /*! - ** \brief Convert an UTF-8 String into a WideChar String - */ - struct WString - { - public: - WString(const char* s); - WString(const std::string& str); + /*! + ** \brief Convert an UTF-8 String into a WideChar String + */ + struct WString { + public: + WString(const char* s); + WString(const std::string& str); - void fromUtf8(const char* s, size_t length); - const wchar_t* cw_str() const {return pBuffer;} + void fromUtf8(const char* s, size_t length); + const wchar_t* cw_str() const { + return pBuffer; + } - private: - wchar_t pBuffer[8096]; - }; + private: + wchar_t pBuffer[8096]; + }; - void strrev(char *p); - void strrev_utf8(char *p); - void strrev_utf8(std::string &p); - bool is_string_all_ascii(std::string str); + void strrev(char *p); + void strrev_utf8(char *p); + void strrev_utf8(std::string &p); + bool is_string_all_ascii(std::string str); - int getUTF8_Width(const char *str); + int getUTF8_Width(const char *str); -}} + } +} #endif // _SHARED_UTIL_W_STRING_H__ diff --git a/source/shared_lib/include/util/util.h b/source/shared_lib/include/util/util.h index 327246cbc..f4b8dc65d 100644 --- a/source/shared_lib/include/util/util.h +++ b/source/shared_lib/include/util/util.h @@ -28,171 +28,177 @@ using namespace Shared::Platform; //#define UNDEF_DEBUG -namespace Shared { namespace Util { +namespace Shared { + namespace Util { -enum GlobalStaticFlagTypes { - gsft_none = 0x00, - gsft_lan_mode = 0x01, - //gsft_xx = 0x02 - //gsft__xx = 0x04, - //gsft__xx = 0x08, - //gsft__xx = 0x10, -}; + enum GlobalStaticFlagTypes { + gsft_none = 0x00, + gsft_lan_mode = 0x01, + //gsft_xx = 0x02 + //gsft__xx = 0x04, + //gsft__xx = 0x08, + //gsft__xx = 0x10, + }; -class GlobalStaticFlags { -public: - static bool getIsNonGraphicalModeEnabled() { - return isNonGraphicalMode; - } + class GlobalStaticFlags { + public: + static bool getIsNonGraphicalModeEnabled() { + return isNonGraphicalMode; + } - static void setIsNonGraphicalModeEnabled(bool value) { - isNonGraphicalMode = value; - } + static void setIsNonGraphicalModeEnabled(bool value) { + isNonGraphicalMode = value; + } - static void setFlags(uint64 flagsValue) { flags = flagsValue; } - static uint64 getFlags() { return flags; } + static void setFlags(uint64 flagsValue) { + flags = flagsValue; + } + static uint64 getFlags() { + return flags; + } - static void setFlag(GlobalStaticFlagTypes flag) { flags |= flag; } - static bool isFlagSet(GlobalStaticFlagTypes flag) { return (flags & (unsigned int)flag) == (unsigned int)flag; } + static void setFlag(GlobalStaticFlagTypes flag) { + flags |= flag; + } + static bool isFlagSet(GlobalStaticFlagTypes flag) { + return (flags & (unsigned int) flag) == (unsigned int) flag; + } -protected: - static bool isNonGraphicalMode; - static uint64 flags; -}; + protected: + static bool isNonGraphicalMode; + static uint64 flags; + }; -class SystemFlags -{ -public: + class SystemFlags { + public: - struct httpMemoryStruct { - char *memory; - size_t size; - }; + struct httpMemoryStruct { + char *memory; + size_t size; + }; - enum DebugType { - debugSystem, - debugNetwork, - debugPerformance, - debugWorldSynch, - debugWorldSynchMax, - debugUnitCommands, - debugPathFinder, - debugLUA, - debugSound, - debugError - }; + enum DebugType { + debugSystem, + debugNetwork, + debugPerformance, + debugWorldSynch, + debugWorldSynchMax, + debugUnitCommands, + debugPathFinder, + debugLUA, + debugSound, + debugError + }; - class SystemFlagsType - { - protected: - DebugType debugType; + class SystemFlagsType { + protected: + DebugType debugType; - public: - SystemFlagsType() { - this->debugType = debugSystem; - this->enabled = false; - this->fileStream = NULL; - this->debugLogFileName = ""; - this->fileStreamOwner = false; - this->mutex = NULL; - } - SystemFlagsType(DebugType debugType) { - this->debugType = debugType; - this->enabled = false; - this->fileStream = NULL; - this->debugLogFileName = ""; - this->fileStreamOwner = false; - this->mutex = NULL; - } - ~SystemFlagsType() { - Close(); - } - SystemFlagsType(DebugType debugType,bool enabled, - std::ofstream *fileStream,std::string debugLogFileName) { - this->debugType = debugType; - this->enabled = enabled; - this->fileStream = fileStream; - this->debugLogFileName = debugLogFileName; - this->fileStreamOwner = false; - this->mutex = NULL; - } - - void Close() { - if(this->fileStreamOwner == true) { - if( this->fileStream != NULL && - this->fileStream->is_open() == true) { - this->fileStream->close(); + public: + SystemFlagsType() { + this->debugType = debugSystem; + this->enabled = false; + this->fileStream = NULL; + this->debugLogFileName = ""; + this->fileStreamOwner = false; + this->mutex = NULL; } - delete this->fileStream; - delete this->mutex; + SystemFlagsType(DebugType debugType) { + this->debugType = debugType; + this->enabled = false; + this->fileStream = NULL; + this->debugLogFileName = ""; + this->fileStreamOwner = false; + this->mutex = NULL; + } + ~SystemFlagsType() { + Close(); + } + SystemFlagsType(DebugType debugType, bool enabled, + std::ofstream *fileStream, std::string debugLogFileName) { + this->debugType = debugType; + this->enabled = enabled; + this->fileStream = fileStream; + this->debugLogFileName = debugLogFileName; + this->fileStreamOwner = false; + this->mutex = NULL; + } + + void Close() { + if (this->fileStreamOwner == true) { + if (this->fileStream != NULL && + this->fileStream->is_open() == true) { + this->fileStream->close(); + } + delete this->fileStream; + delete this->mutex; + } + this->fileStream = NULL; + this->fileStreamOwner = false; + this->mutex = NULL; + } + + bool enabled; + std::ofstream *fileStream; + std::string debugLogFileName; + bool fileStreamOwner; + Mutex *mutex; + }; + + protected: + + static int lockFile; + static string lockfilename; + static int lockFileCountIndex; + + static std::map *debugLogFileList; + static bool haveSpecialOutputCommandLineOption; + static bool curl_global_init_called; + + static SystemFlagsType * setupRequiredMembers(); + + public: + + static CURL *curl_handle; + static int DEFAULT_HTTP_TIMEOUT; + static bool VERBOSE_MODE_ENABLED; + static bool ENABLE_THREADED_LOGGING; + static bool SHUTDOWN_PROGRAM_MODE; + + SystemFlags(); + ~SystemFlags(); + + static void init(bool haveSpecialOutputCommandLineOption); + //static SystemFlagsType & getSystemSettingType(DebugType type); + inline static SystemFlagsType & getSystemSettingType(DebugType type) { + if (SystemFlags::debugLogFileList == NULL) { + SystemFlagsType *result = setupRequiredMembers(); + if (result != NULL) { + return *result; + } else if (SystemFlags::debugLogFileList == NULL) { + throw std::runtime_error("unknown return value for SystemFlagsType!"); + } + } + + return (*debugLogFileList)[type]; } - this->fileStream = NULL; - this->fileStreamOwner = false; - this->mutex = NULL; - } - bool enabled; - std::ofstream *fileStream; - std::string debugLogFileName; - bool fileStreamOwner; - Mutex *mutex; - }; + static size_t httpWriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data); + static std::string getHTTP(std::string URL, CURL *handle = NULL, int timeOut = -1, CURLcode *savedResult = NULL); + static std::string escapeURL(std::string URL, CURL *handle = NULL); -protected: + static CURL *initHTTP(); + static void cleanupHTTP(CURL **handle, bool globalCleanup = false); + static void globalCleanupHTTP(); - static int lockFile; - static string lockfilename; - static int lockFileCountIndex; + static bool getThreadedLoggerRunning(); + static std::size_t getLogEntryBufferCount(); - static std::map *debugLogFileList; - static bool haveSpecialOutputCommandLineOption; - static bool curl_global_init_called; + // Let the macro call into this when require.. NEVER call it automatically. + static void handleDebug(DebugType type, const char *fmt, ...); + static void logDebugEntry(DebugType type, string debugEntry, time_t debugTime); - static SystemFlagsType * setupRequiredMembers(); - -public: - - static CURL *curl_handle; - static int DEFAULT_HTTP_TIMEOUT; - static bool VERBOSE_MODE_ENABLED; - static bool ENABLE_THREADED_LOGGING; - static bool SHUTDOWN_PROGRAM_MODE; - - SystemFlags(); - ~SystemFlags(); - - static void init(bool haveSpecialOutputCommandLineOption); - //static SystemFlagsType & getSystemSettingType(DebugType type); - inline static SystemFlagsType & getSystemSettingType(DebugType type) { - if(SystemFlags::debugLogFileList == NULL) { - SystemFlagsType *result = setupRequiredMembers(); - if(result != NULL) { - return *result; - } - else if(SystemFlags::debugLogFileList == NULL) { - throw std::runtime_error("unknown return value for SystemFlagsType!"); - } - } - - return (*debugLogFileList)[type]; - } - - static size_t httpWriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data); - static std::string getHTTP(std::string URL,CURL *handle=NULL, int timeOut=-1, CURLcode *savedResult=NULL); - static std::string escapeURL(std::string URL, CURL *handle=NULL); - - static CURL *initHTTP(); - static void cleanupHTTP(CURL **handle,bool globalCleanup=false); - static void globalCleanupHTTP(); - - static bool getThreadedLoggerRunning(); - static std::size_t getLogEntryBufferCount(); - - // Let the macro call into this when require.. NEVER call it automatically. - static void handleDebug(DebugType type, const char *fmt, ...); - static void logDebugEntry(DebugType type, string debugEntry, time_t debugTime); - -// If logging is enabled then define the logging method + // If logging is enabled then define the logging method #ifndef UNDEF_DEBUG #ifndef WIN32 @@ -208,89 +214,87 @@ public: #else // stub out debugging completely #ifndef WIN32 - #define OutputDebug(type, fmt, ...) type +#define OutputDebug(type, fmt, ...) type #else - static void nothing() {} - #define OutputDebug(type, fmt, ...) nothing() + static void nothing() { + } +#define OutputDebug(type, fmt, ...) nothing() #endif #endif - static void Close(); -}; + static void Close(); + }; -const string sharedLibVersionString= "v0.4.1"; + const string sharedLibVersionString = "v0.4.1"; -//string fcs -string lastDir(const string &s); -string lastFile(const string &s); -string cutLastFile(const string &s); -string cutLastExt(const string &s); -string ext(const string &s); -string replaceBy(const string &s, char c1, char c2); -vector split(string s,string d); -string toLower(const string &s); -bool compareNonCaseSensitive(const string &a, const string &b); -//void copyStringToBuffer(char *buffer, int bufferSize, const string& s); + //string fcs + string lastDir(const string &s); + string lastFile(const string &s); + string cutLastFile(const string &s); + string cutLastExt(const string &s); + string ext(const string &s); + string replaceBy(const string &s, char c1, char c2); + vector split(string s, string d); + string toLower(const string &s); + bool compareNonCaseSensitive(const string &a, const string &b); + //void copyStringToBuffer(char *buffer, int bufferSize, const string& s); -//numeric fcs -int clamp(int value, int min, int max); -float clamp(float value, float min, float max); -int64 clamp(int64 value, int64 min, int64 max); -//float saturate(float value); -//int round(float f); + //numeric fcs + int clamp(int value, int min, int max); + float clamp(float value, float min, float max); + int64 clamp(int64 value, int64 min, int64 max); + //float saturate(float value); + //int round(float f); -//misc -int compareMajorMinorVersion(const string &versionA, const string &versionB); -int getMajor(string version); -int getMinor(string version); -bool checkVersionComptability(string clientVersionString, string serverVersionString); + //misc + int compareMajorMinorVersion(const string &versionA, const string &versionB); + int getMajor(string version); + int getMinor(string version); + bool checkVersionComptability(string clientVersionString, string serverVersionString); + + template + void enforceMinimumValue(T minValue, T &value) { + if (value < minValue) { + value = minValue; + } + } + + template + void deleteValues(T beginIt, T endIt) { + for (T it = beginIt; it != endIt; ++it) { + delete *it; + } + } + + template + void deleteMapValues(T beginIt, T endIt) { + for (T it = beginIt; it != endIt; ++it) { + delete it->second; + it->second = NULL; + } + } + + template + class create_map { + private: + std::map m_map; + public: + create_map(const T& key, const U& val) { + m_map[key] = val; + } + + create_map& operator()(const T& key, const U& val) { + m_map[key] = val; + return *this; + } + + operator std::map() { + return m_map; + } + }; -template -void enforceMinimumValue(T minValue, T &value) { - if(value < minValue) { - value = minValue; } -} - -template -void deleteValues(T beginIt, T endIt){ - for(T it= beginIt; it!=endIt; ++it){ - delete *it; - } -} - -template -void deleteMapValues(T beginIt, T endIt){ - for(T it= beginIt; it!=endIt; ++it){ - delete it->second; - it->second = NULL; - } -} - -template -class create_map -{ -private: - std::map m_map; -public: - create_map(const T& key, const U& val) - { - m_map[key] = val; - } - - create_map& operator()(const T& key, const U& val) - { - m_map[key] = val; - return *this; - } - - operator std::map() - { - return m_map; - } -}; - -}}//end namespace +}//end namespace #endif diff --git a/source/shared_lib/include/xml/xml_parser.h b/source/shared_lib/include/xml/xml_parser.h index d7fd4e832..897d60b3b 100644 --- a/source/shared_lib/include/xml/xml_parser.h +++ b/source/shared_lib/include/xml/xml_parser.h @@ -31,7 +31,7 @@ using namespace std; #if defined(WANT_XERCES) -namespace XERCES_CPP_NAMESPACE{ +namespace XERCES_CPP_NAMESPACE { class DOMImplementation; class DOMDocument; class DOMNode; @@ -48,215 +48,231 @@ XERCES_CPP_NAMESPACE_USE #endif -namespace Shared { namespace Xml { +namespace Shared { + namespace Xml { -enum xml_engine_parser_type { + enum xml_engine_parser_type { #if defined(WANT_XERCES) - XML_XERCES_ENGINE = 0, + XML_XERCES_ENGINE = 0, #endif - XML_RAPIDXML_ENGINE = 1 -} ; + XML_RAPIDXML_ENGINE = 1 + }; -const int strSize= 8094; + const int strSize = 8094; -class XmlIo; -class XmlTree; -class XmlNode; -class XmlAttribute; + class XmlIo; + class XmlTree; + class XmlNode; + class XmlAttribute; #if defined(WANT_XERCES) -// ===================================================== -// class XmlIo -// -/// Wrapper for Xerces C++ -// ===================================================== + // ===================================================== + // class XmlIo + // + /// Wrapper for Xerces C++ + // ===================================================== -class XmlIo { -private: - static bool initialized; - XERCES_CPP_NAMESPACE::DOMImplementation *implementation; + class XmlIo { + private: + static bool initialized; + XERCES_CPP_NAMESPACE::DOMImplementation *implementation; #if XERCES_VERSION_MAJOR < 3 - XERCES_CPP_NAMESPACE::DOMBuilder *parser; + XERCES_CPP_NAMESPACE::DOMBuilder *parser; #else - XERCES_CPP_NAMESPACE::DOMLSParser *parser; + XERCES_CPP_NAMESPACE::DOMLSParser *parser; #endif -protected: - XmlIo(); - virtual ~XmlIo(); + protected: + XmlIo(); + virtual ~XmlIo(); - void init(); + void init(); #if XERCES_VERSION_MAJOR < 3 - XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * getRootDOMDocument(const string &path, DOMBuilder *parser, bool noValidation); + XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * getRootDOMDocument(const string &path, DOMBuilder *parser, bool noValidation); #else - XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * getRootDOMDocument(const string &path, DOMLSParser *parser, bool noValidation); + XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * getRootDOMDocument(const string &path, DOMLSParser *parser, bool noValidation); #endif - DOMNode *loadDOMNode(const string &path, bool noValidation=false); - virtual void releaseDOMParser(); + DOMNode *loadDOMNode(const string &path, bool noValidation = false); + virtual void releaseDOMParser(); -public: - static XmlIo &getInstance(); + public: + static XmlIo &getInstance(); - static bool isInitialized(); - void cleanup(); + static bool isInitialized(); + void cleanup(); - XmlNode *load(const string &path, const std::map &mapTagReplacementValues,bool noValidation=false,bool skipStackTrace=false); - void save(const string &path, const XmlNode *node); -}; + XmlNode *load(const string &path, const std::map &mapTagReplacementValues, bool noValidation = false, bool skipStackTrace = false); + void save(const string &path, const XmlNode *node); + }; #endif -class XmlIoRapid { -private: - static bool initialized; + class XmlIoRapid { + private: + static bool initialized; -private: - XmlIoRapid(); - void init(); + private: + XmlIoRapid(); + void init(); -public: - static XmlIoRapid &getInstance(); - ~XmlIoRapid(); + public: + static XmlIoRapid &getInstance(); + ~XmlIoRapid(); - static bool isInitialized(); - void cleanup(); + static bool isInitialized(); + void cleanup(); - XmlNode *load(const string &path, const std::map &mapTagReplacementValues,bool noValidation=false,bool skipStackTrace=false,bool skipUpdatePathClimbingParts=false); - void save(const string &path, const XmlNode *node); -}; + XmlNode *load(const string &path, const std::map &mapTagReplacementValues, bool noValidation = false, bool skipStackTrace = false, bool skipUpdatePathClimbingParts = false); + void save(const string &path, const XmlNode *node); + }; -// ===================================================== -// class XmlTree -// ===================================================== + // ===================================================== + // class XmlTree + // ===================================================== -class XmlTree{ -private: - XmlNode *rootNode; - string loadPath; - xml_engine_parser_type engine_type; - bool skipStackCheck; - bool skipUpdatePathClimbingParts; -private: - XmlTree(XmlTree&); - void operator =(XmlTree&); - void clearRootNode(); + class XmlTree { + private: + XmlNode *rootNode; + string loadPath; + xml_engine_parser_type engine_type; + bool skipStackCheck; + bool skipUpdatePathClimbingParts; + private: + XmlTree(XmlTree&); + void operator =(XmlTree&); + void clearRootNode(); -public: - XmlTree(xml_engine_parser_type engine_type = XML_RAPIDXML_ENGINE); - ~XmlTree(); + public: + XmlTree(xml_engine_parser_type engine_type = XML_RAPIDXML_ENGINE); + ~XmlTree(); - void setSkipUpdatePathClimbingParts(bool value); - void init(const string &name); - void load(const string &path, const std::map &mapTagReplacementValues, bool noValidation=false,bool skipStackCheck=false,bool skipStackTrace=false); - void save(const string &path); + void setSkipUpdatePathClimbingParts(bool value); + void init(const string &name); + void load(const string &path, const std::map &mapTagReplacementValues, bool noValidation = false, bool skipStackCheck = false, bool skipStackTrace = false); + void save(const string &path); - XmlNode *getRootNode() const {return rootNode;} -}; + XmlNode *getRootNode() const { + return rootNode; + } + }; -// ===================================================== -// class XmlNode -// ===================================================== + // ===================================================== + // class XmlNode + // ===================================================== -class XmlNode { -private: - string name; - string text; - vector children; - vector attributes; - mutable const XmlNode* superNode; + class XmlNode { + private: + string name; + string text; + vector children; + vector attributes; + mutable const XmlNode* superNode; -private: - XmlNode(XmlNode&); - void operator =(XmlNode&); + private: + XmlNode(XmlNode&); + void operator =(XmlNode&); - string getTreeString() const; - bool hasChildNoSuper(const string& childName) const; + string getTreeString() const; + bool hasChildNoSuper(const string& childName) const; -public: + public: #if defined(WANT_XERCES) - XmlNode(XERCES_CPP_NAMESPACE::DOMNode *node, const std::map &mapTagReplacementValues); - XERCES_CPP_NAMESPACE::DOMElement *buildElement(XERCES_CPP_NAMESPACE::DOMDocument *document) const; + XmlNode(XERCES_CPP_NAMESPACE::DOMNode *node, const std::map &mapTagReplacementValues); + XERCES_CPP_NAMESPACE::DOMElement *buildElement(XERCES_CPP_NAMESPACE::DOMDocument *document) const; #endif - XmlNode(xml_node<> *node, const std::map &mapTagReplacementValues,bool skipUpdatePathClimbingParts=false); - XmlNode(const string &name); - ~XmlNode(); - - void setSuper(const XmlNode* superNode) const { this->superNode = superNode; } + XmlNode(xml_node<> *node, const std::map &mapTagReplacementValues, bool skipUpdatePathClimbingParts = false); + XmlNode(const string &name); + ~XmlNode(); - const string &getName() const {return name;} - size_t getChildCount() const {return children.size();} - size_t getAttributeCount() const {return attributes.size();} - const string &getText() const {return text;} + void setSuper(const XmlNode* superNode) const { + this->superNode = superNode; + } - XmlAttribute *getAttribute(unsigned int i) const; - XmlAttribute *getAttribute(const string &name,bool mustExist=true) const; - bool hasAttribute(const string &name) const; + const string &getName() const { + return name; + } + size_t getChildCount() const { + return children.size(); + } + size_t getAttributeCount() const { + return attributes.size(); + } + const string &getText() const { + return text; + } - XmlNode *getChild(unsigned int i) const; - XmlNode *getChild(const string &childName, unsigned int childIndex=0) const; - XmlNode *getChildWithAliases(vector childNameList, unsigned int childIndex=0) const; - vector getChildList(const string &childName) const; - bool hasChildAtIndex(const string &childName, int childIndex=0) const; - bool hasChild(const string &childName) const; - bool hasChildWithAliases(vector childNameList) const; - int clearChild(const string &childName); + XmlAttribute *getAttribute(unsigned int i) const; + XmlAttribute *getAttribute(const string &name, bool mustExist = true) const; + bool hasAttribute(const string &name) const; + + XmlNode *getChild(unsigned int i) const; + XmlNode *getChild(const string &childName, unsigned int childIndex = 0) const; + XmlNode *getChildWithAliases(vector childNameList, unsigned int childIndex = 0) const; + vector getChildList(const string &childName) const; + bool hasChildAtIndex(const string &childName, int childIndex = 0) const; + bool hasChild(const string &childName) const; + bool hasChildWithAliases(vector childNameList) const; + int clearChild(const string &childName); - XmlNode *addChild(const string &name, const string text = ""); - XmlAttribute *addAttribute(const string &name, const string &value, const std::map &mapTagReplacementValues); - xml_node<>* buildElement(xml_document<> *document) const; -}; + XmlNode *addChild(const string &name, const string text = ""); + XmlAttribute *addAttribute(const string &name, const string &value, const std::map &mapTagReplacementValues); + xml_node<>* buildElement(xml_document<> *document) const; + }; -// ===================================================== -// class XmlAttribute -// ===================================================== + // ===================================================== + // class XmlAttribute + // ===================================================== -class XmlAttribute { -private: - string value; - string name; - bool skipRestrictionCheck; - bool usesCommondata; - std::map mapTagReplacementValues; + class XmlAttribute { + private: + string value; + string name; + bool skipRestrictionCheck; + bool usesCommondata; + std::map mapTagReplacementValues; -private: - XmlAttribute(XmlAttribute&); - void operator =(XmlAttribute&); + private: + XmlAttribute(XmlAttribute&); + void operator =(XmlAttribute&); -public: + public: #if defined(WANT_XERCES) - XmlAttribute(XERCES_CPP_NAMESPACE::DOMNode *attribute, const std::map &mapTagReplacementValues); + XmlAttribute(XERCES_CPP_NAMESPACE::DOMNode *attribute, const std::map &mapTagReplacementValues); #endif - XmlAttribute(xml_attribute<> *attribute, const std::map &mapTagReplacementValues); - XmlAttribute(const string &name, const string &value, const std::map &mapTagReplacementValues); + XmlAttribute(xml_attribute<> *attribute, const std::map &mapTagReplacementValues); + XmlAttribute(const string &name, const string &value, const std::map &mapTagReplacementValues); -public: - const string getName() const {return name;} - const string getValue(string prefixValue="", bool trimValueWithStartingSlash=false) const; + public: + const string getName() const { + return name; + } + const string getValue(string prefixValue = "", bool trimValueWithStartingSlash = false) const; - bool getBoolValue() const; - int getIntValue() const; - Shared::Platform::uint32 getUIntValue() const; - int getIntValue(int min, int max) const; - float getFloatValue() const; - float getFloatValue(float min, float max) const; - const string getRestrictedValue(string prefixValue="", bool trimValueWithStartingSlash=false) const; + bool getBoolValue() const; + int getIntValue() const; + Shared::Platform::uint32 getUIntValue() const; + int getIntValue(int min, int max) const; + float getFloatValue() const; + float getFloatValue(float min, float max) const; + const string getRestrictedValue(string prefixValue = "", bool trimValueWithStartingSlash = false) const; - void setValue(string val); -}; + void setValue(string val); + }; -}}//end namespace + } +}//end namespace #endif diff --git a/source/shared_lib/sources/compression/compression_utils.cpp b/source/shared_lib/sources/compression/compression_utils.cpp index 167bc7c0e..f985ee47b 100644 --- a/source/shared_lib/sources/compression/compression_utils.cpp +++ b/source/shared_lib/sources/compression/compression_utils.cpp @@ -27,350 +27,347 @@ using namespace Shared::Util; -namespace Shared{ namespace CompressionUtil{ +namespace Shared { + namespace CompressionUtil { -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint; + typedef unsigned char uint8; + typedef unsigned short uint16; + typedef unsigned int uint; #define my_max(a,b) (((a) > (b)) ? (a) : (b)) #define my_min(a,b) (((a) < (b)) ? (a) : (b)) #define BUF_SIZE (1024 * 1024) -static uint8 s_inbuf[BUF_SIZE]; -static uint8 s_outbuf[BUF_SIZE]; + static uint8 s_inbuf[BUF_SIZE]; + static uint8 s_outbuf[BUF_SIZE]; -int zipfile_tool(int argc, const char *argv[]) { - const char *pMode = NULL; - FILE *pInfile = NULL, - *pOutfile = NULL; - uint infile_size = 0; - int level = Z_BEST_COMPRESSION; - z_stream stream; - int p = 1; - const char *pSrc_filename = NULL; - const char *pDst_filename = NULL; - long file_loc = 0; + int zipfile_tool(int argc, const char *argv[]) { + const char *pMode = NULL; + FILE *pInfile = NULL, + *pOutfile = NULL; + uint infile_size = 0; + int level = Z_BEST_COMPRESSION; + z_stream stream; + int p = 1; + const char *pSrc_filename = NULL; + const char *pDst_filename = NULL; + long file_loc = 0; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("miniz.c version: %s\n", MZ_VERSION); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("miniz.c version: %s\n", MZ_VERSION); - if (argc < 4) { - if(SystemFlags::VERBOSE_MODE_ENABLED) { - printf("Usage: example3 [options] [mode:c or d] infile outfile\n"); - printf("\nModes:\n"); - printf("c - Compresses file infile to a zlib stream in file outfile\n"); - printf("d - Decompress zlib stream in file infile to file outfile\n"); - printf("\nOptions:\n"); - printf("-l[0-10] - Compression level, higher values are slower.\n"); - } - return EXIT_FAILURE; - } + if (argc < 4) { + if (SystemFlags::VERBOSE_MODE_ENABLED) { + printf("Usage: example3 [options] [mode:c or d] infile outfile\n"); + printf("\nModes:\n"); + printf("c - Compresses file infile to a zlib stream in file outfile\n"); + printf("d - Decompress zlib stream in file infile to file outfile\n"); + printf("\nOptions:\n"); + printf("-l[0-10] - Compression level, higher values are slower.\n"); + } + return EXIT_FAILURE; + } - while ((p < argc) && (argv[p][0] == '-')) { - switch (argv[p][1]) { - case 'l': - { - level = atoi(&argv[1][2]); - if ((level < 0) || (level > 10)) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Invalid level!\n"); - return EXIT_FAILURE; - } - break; - } - default: - { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Invalid option: %s\n", argv[p]); - return EXIT_FAILURE; - } - } - p++; - } + while ((p < argc) && (argv[p][0] == '-')) { + switch (argv[p][1]) { + case 'l': + { + level = atoi(&argv[1][2]); + if ((level < 0) || (level > 10)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Invalid level!\n"); + return EXIT_FAILURE; + } + break; + } + default: + { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Invalid option: %s\n", argv[p]); + return EXIT_FAILURE; + } + } + p++; + } - if ((argc - p) < 3) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Must specify mode, input filename, and output filename after options!\n"); - return EXIT_FAILURE; - } - else if ((argc - p) > 3) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Too many filenames!\n"); - return EXIT_FAILURE; - } + if ((argc - p) < 3) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Must specify mode, input filename, and output filename after options!\n"); + return EXIT_FAILURE; + } else if ((argc - p) > 3) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Too many filenames!\n"); + return EXIT_FAILURE; + } - pMode = argv[p++]; - if (!strchr("cCdD", pMode[0])) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Invalid mode!\n"); - if(SystemFlags::VERBOSE_MODE_ENABLED) return EXIT_FAILURE; - } + pMode = argv[p++]; + if (!strchr("cCdD", pMode[0])) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Invalid mode!\n"); + if (SystemFlags::VERBOSE_MODE_ENABLED) return EXIT_FAILURE; + } - pSrc_filename = argv[p++]; - pDst_filename = argv[p++]; + pSrc_filename = argv[p++]; + pDst_filename = argv[p++]; - if(SystemFlags::VERBOSE_MODE_ENABLED)printf("Mode: %c, Level: %d\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename); + if (SystemFlags::VERBOSE_MODE_ENABLED)printf("Mode: %c, Level: %d\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename); - // Open input file. - pInfile = fopen(pSrc_filename, "rb"); - if (!pInfile) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed opening input file!\n"); - return EXIT_FAILURE; - } + // Open input file. + pInfile = fopen(pSrc_filename, "rb"); + if (!pInfile) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed opening input file!\n"); + return EXIT_FAILURE; + } - // Determine input file's size. - fseek(pInfile, 0, SEEK_END); - file_loc = ftell(pInfile); - fseek(pInfile, 0, SEEK_SET); + // Determine input file's size. + fseek(pInfile, 0, SEEK_END); + file_loc = ftell(pInfile); + fseek(pInfile, 0, SEEK_SET); - if ((file_loc < 0) || (file_loc > INT_MAX)) { - // This is not a limitation of miniz or tinfl, but this example. - printf("File is too large to be processed by this example.\n"); + if ((file_loc < 0) || (file_loc > INT_MAX)) { + // This is not a limitation of miniz or tinfl, but this example. + printf("File is too large to be processed by this example.\n"); - fclose(pInfile); - return EXIT_FAILURE; - } + fclose(pInfile); + return EXIT_FAILURE; + } - infile_size = (uint)file_loc; + infile_size = (uint) file_loc; - // Open output file. - pOutfile = fopen(pDst_filename, "wb"); - if (!pOutfile) { - printf("Failed opening output file!\n"); + // Open output file. + pOutfile = fopen(pDst_filename, "wb"); + if (!pOutfile) { + printf("Failed opening output file!\n"); - fclose(pInfile); - return EXIT_FAILURE; - } + fclose(pInfile); + return EXIT_FAILURE; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Input file size: %u\n", infile_size); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Input file size: %u\n", infile_size); - // Init the z_stream - memset(&stream, 0, sizeof(stream)); - stream.next_in = s_inbuf; - stream.avail_in = 0; - stream.next_out = s_outbuf; - stream.avail_out = BUF_SIZE; + // Init the z_stream + memset(&stream, 0, sizeof(stream)); + stream.next_in = s_inbuf; + stream.avail_in = 0; + stream.next_out = s_outbuf; + stream.avail_out = BUF_SIZE; - if ((pMode[0] == 'c') || (pMode[0] == 'C')) { - // Compression. - uint infile_remaining = infile_size; + if ((pMode[0] == 'c') || (pMode[0] == 'C')) { + // Compression. + uint infile_remaining = infile_size; - if (deflateInit(&stream, level) != Z_OK) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("deflateInit() failed!\n"); + if (deflateInit(&stream, level) != Z_OK) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("deflateInit() failed!\n"); - if(pInfile) fclose(pInfile); - if(pOutfile) fclose(pOutfile); - return EXIT_FAILURE; - } + if (pInfile) fclose(pInfile); + if (pOutfile) fclose(pOutfile); + return EXIT_FAILURE; + } - for ( ; ; ) { - int status; - if (!stream.avail_in) { - // Input buffer is empty, so read more bytes from input file. - uint n = my_min(BUF_SIZE, infile_remaining); + for (; ; ) { + int status; + if (!stream.avail_in) { + // Input buffer is empty, so read more bytes from input file. + uint n = my_min(BUF_SIZE, infile_remaining); - if (fread(s_inbuf, 1, n, pInfile) != n) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed reading from input file!\n"); + if (fread(s_inbuf, 1, n, pInfile) != n) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed reading from input file!\n"); - fclose(pInfile); - if(pOutfile) fclose(pOutfile); - return EXIT_FAILURE; - } + fclose(pInfile); + if (pOutfile) fclose(pOutfile); + return EXIT_FAILURE; + } - stream.next_in = s_inbuf; - stream.avail_in = n; + stream.next_in = s_inbuf; + stream.avail_in = n; - infile_remaining -= n; - //printf("Input bytes remaining: %u\n", infile_remaining); - } + infile_remaining -= n; + //printf("Input bytes remaining: %u\n", infile_remaining); + } - status = deflate(&stream, infile_remaining ? Z_NO_FLUSH : Z_FINISH); + status = deflate(&stream, infile_remaining ? Z_NO_FLUSH : Z_FINISH); - if ((status == Z_STREAM_END) || (!stream.avail_out)) { - // Output buffer is full, or compression is done, so write buffer to output file. - uint n = BUF_SIZE - stream.avail_out; - if (fwrite(s_outbuf, 1, n, pOutfile) != n) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed writing to output file!\n"); + if ((status == Z_STREAM_END) || (!stream.avail_out)) { + // Output buffer is full, or compression is done, so write buffer to output file. + uint n = BUF_SIZE - stream.avail_out; + if (fwrite(s_outbuf, 1, n, pOutfile) != n) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed writing to output file!\n"); - if(pInfile) fclose(pInfile); - fclose(pOutfile); - return EXIT_FAILURE; - } - stream.next_out = s_outbuf; - stream.avail_out = BUF_SIZE; - } + if (pInfile) fclose(pInfile); + fclose(pOutfile); + return EXIT_FAILURE; + } + stream.next_out = s_outbuf; + stream.avail_out = BUF_SIZE; + } - if (status == Z_STREAM_END) { - break; - } - else if (status != Z_OK) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("deflate() failed with status %i!\n", status); + if (status == Z_STREAM_END) { + break; + } else if (status != Z_OK) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("deflate() failed with status %i!\n", status); - if(pInfile) fclose(pInfile); - if(pOutfile) fclose(pOutfile); - return EXIT_FAILURE; - } - } + if (pInfile) fclose(pInfile); + if (pOutfile) fclose(pOutfile); + return EXIT_FAILURE; + } + } - if (deflateEnd(&stream) != Z_OK) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("deflateEnd() failed!\n"); + if (deflateEnd(&stream) != Z_OK) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("deflateEnd() failed!\n"); - if(pInfile) fclose(pInfile); - if(pOutfile) fclose(pOutfile); - return EXIT_FAILURE; - } - } - else if ((pMode[0] == 'd') || (pMode[0] == 'D')) { - // Decompression. - uint infile_remaining = infile_size; + if (pInfile) fclose(pInfile); + if (pOutfile) fclose(pOutfile); + return EXIT_FAILURE; + } + } else if ((pMode[0] == 'd') || (pMode[0] == 'D')) { + // Decompression. + uint infile_remaining = infile_size; - if (inflateInit(&stream)) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("inflateInit() failed!\n"); + if (inflateInit(&stream)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("inflateInit() failed!\n"); - if(pInfile) fclose(pInfile); - if(pOutfile) fclose(pOutfile); - return EXIT_FAILURE; - } + if (pInfile) fclose(pInfile); + if (pOutfile) fclose(pOutfile); + return EXIT_FAILURE; + } - for ( ; ; ) { - int status; - if (!stream.avail_in) { - // Input buffer is empty, so read more bytes from input file. - uint n = my_min(BUF_SIZE, infile_remaining); + for (; ; ) { + int status; + if (!stream.avail_in) { + // Input buffer is empty, so read more bytes from input file. + uint n = my_min(BUF_SIZE, infile_remaining); - if (fread(s_inbuf, 1, n, pInfile) != n) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed reading from input file!\n"); + if (fread(s_inbuf, 1, n, pInfile) != n) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed reading from input file!\n"); - fclose(pInfile); - if(pOutfile) fclose(pOutfile); - return EXIT_FAILURE; - } + fclose(pInfile); + if (pOutfile) fclose(pOutfile); + return EXIT_FAILURE; + } - stream.next_in = s_inbuf; - stream.avail_in = n; + stream.next_in = s_inbuf; + stream.avail_in = n; - infile_remaining -= n; - } + infile_remaining -= n; + } - status = inflate(&stream, Z_SYNC_FLUSH); + status = inflate(&stream, Z_SYNC_FLUSH); - if ((status == Z_STREAM_END) || (!stream.avail_out)) { - // Output buffer is full, or decompression is done, so write buffer to output file. - uint n = BUF_SIZE - stream.avail_out; - if (fwrite(s_outbuf, 1, n, pOutfile) != n) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed writing to output file!\n"); + if ((status == Z_STREAM_END) || (!stream.avail_out)) { + // Output buffer is full, or decompression is done, so write buffer to output file. + uint n = BUF_SIZE - stream.avail_out; + if (fwrite(s_outbuf, 1, n, pOutfile) != n) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed writing to output file!\n"); - if(pInfile) fclose(pInfile); - fclose(pOutfile); - return EXIT_FAILURE; - } - stream.next_out = s_outbuf; - stream.avail_out = BUF_SIZE; - } + if (pInfile) fclose(pInfile); + fclose(pOutfile); + return EXIT_FAILURE; + } + stream.next_out = s_outbuf; + stream.avail_out = BUF_SIZE; + } - if (status == Z_STREAM_END) { - break; - } - else if (status != Z_OK) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("inflate() failed with status %i!\n", status); + if (status == Z_STREAM_END) { + break; + } else if (status != Z_OK) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("inflate() failed with status %i!\n", status); - if(pInfile) fclose(pInfile); - if(pOutfile) fclose(pOutfile); - return EXIT_FAILURE; - } - } + if (pInfile) fclose(pInfile); + if (pOutfile) fclose(pOutfile); + return EXIT_FAILURE; + } + } - if (inflateEnd(&stream) != Z_OK) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("inflateEnd() failed!\n"); + if (inflateEnd(&stream) != Z_OK) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("inflateEnd() failed!\n"); - if(pInfile) fclose(pInfile); - if(pOutfile) fclose(pOutfile); - return EXIT_FAILURE; - } - } - else { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Invalid mode!\n"); + if (pInfile) fclose(pInfile); + if (pOutfile) fclose(pOutfile); + return EXIT_FAILURE; + } + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Invalid mode!\n"); - if(pInfile) fclose(pInfile); - if(pOutfile) fclose(pOutfile); - return EXIT_FAILURE; - } + if (pInfile) fclose(pInfile); + if (pOutfile) fclose(pOutfile); + return EXIT_FAILURE; + } - fclose(pInfile); pInfile = 0; - if (EOF == fclose(pOutfile)) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed writing to output file!\n"); - return EXIT_FAILURE; - } + fclose(pInfile); pInfile = 0; + if (EOF == fclose(pOutfile)) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed writing to output file!\n"); + return EXIT_FAILURE; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) { - printf("Total input bytes: %u\n", (mz_uint32)stream.total_in); - printf("Total output bytes: %u\n", (mz_uint32)stream.total_out); - printf("Success.\n"); - } - return EXIT_SUCCESS; -} + if (SystemFlags::VERBOSE_MODE_ENABLED) { + printf("Total input bytes: %u\n", (mz_uint32) stream.total_in); + printf("Total output bytes: %u\n", (mz_uint32) stream.total_out); + printf("Success.\n"); + } + return EXIT_SUCCESS; + } -bool compressFileToZIPFile(string inFile, string outFile, int compressionLevel) { - string options = "-l" + intToStr(compressionLevel); - std::vector argv; - argv.push_back(options.c_str()); - argv.push_back("c"); - argv.push_back(inFile.c_str()); - argv.push_back(outFile.c_str()); + bool compressFileToZIPFile(string inFile, string outFile, int compressionLevel) { + string options = "-l" + intToStr(compressionLevel); + std::vector argv; + argv.push_back(options.c_str()); + argv.push_back("c"); + argv.push_back(inFile.c_str()); + argv.push_back(outFile.c_str()); - int result = zipfile_tool((int)argv.size(), &argv[0]); - return(result == EXIT_SUCCESS ? true : false); -} + int result = zipfile_tool((int) argv.size(), &argv[0]); + return(result == EXIT_SUCCESS ? true : false); + } -bool extractFileFromZIPFile(string inFile, string outFile) { - std::vector argv; - argv.push_back("-l10"); - argv.push_back("d"); - argv.push_back(inFile.c_str()); - argv.push_back(outFile.c_str()); + bool extractFileFromZIPFile(string inFile, string outFile) { + std::vector argv; + argv.push_back("-l10"); + argv.push_back("d"); + argv.push_back(inFile.c_str()); + argv.push_back(outFile.c_str()); - int result = zipfile_tool((int)argv.size(), &argv[0]); - return(result == EXIT_SUCCESS ? true : false); -} + int result = zipfile_tool((int) argv.size(), &argv[0]); + return(result == EXIT_SUCCESS ? true : false); + } -std::pair compressMemoryToMemory(unsigned char *input, unsigned long input_len, int compressionLevel) { - // Like compress() but with more control, level may range from 0 (storing) to 9 (max. compression) - unsigned long compressed_buffer_len = input_len + 100; - unsigned char *compressed_buffer = new unsigned char[compressed_buffer_len+1]; - memset(compressed_buffer,0,compressed_buffer_len+1); + std::pair compressMemoryToMemory(unsigned char *input, unsigned long input_len, int compressionLevel) { + // Like compress() but with more control, level may range from 0 (storing) to 9 (max. compression) + unsigned long compressed_buffer_len = input_len + 100; + unsigned char *compressed_buffer = new unsigned char[compressed_buffer_len + 1]; + memset(compressed_buffer, 0, compressed_buffer_len + 1); - unsigned char *decompressed_buffer = new unsigned char[input_len+1]; - memcpy(decompressed_buffer,input,input_len); + unsigned char *decompressed_buffer = new unsigned char[input_len + 1]; + memcpy(decompressed_buffer, input, input_len); + + //printf("compress2 start size: %lu\n",input_len); + int result = compress2(compressed_buffer, &compressed_buffer_len, decompressed_buffer, input_len, compressionLevel); + if (result != Z_OK) { + string msg = string("Invalid compress2 return value: ") + intToStr(result); + throw megaglest_runtime_error(msg.c_str()); + } + + //printf("compress2 returned: %d start size: %lu end size: %lu\n",result,input_len,compressed_buffer_len); + delete[] decompressed_buffer; + + return make_pair(compressed_buffer, compressed_buffer_len); + } + + std::pair extractMemoryToMemory(unsigned char *input, unsigned long input_len, unsigned long max_output_len) { + // Like compress() but with more control, level may range from 0 (storing) to 9 (max. compression) + unsigned long decompressed_buffer_len = max_output_len; + unsigned char *decompressed_buffer = new unsigned char[decompressed_buffer_len + 1]; + memset(decompressed_buffer, 0, decompressed_buffer_len + 1); + //printf("#1uncompress start size: %lu\n",input_len); + + unsigned char *compressed_buffer = new unsigned char[input_len + 1]; + memcpy(compressed_buffer, input, input_len); + + //printf("#2uncompress start size: %lu\n",input_len); + //int result = uncompress(decompressed_buffer, &decompressed_buffer_len, compressed_buffer, input_len); + int result = uncompress(decompressed_buffer, &decompressed_buffer_len, compressed_buffer, input_len); + if (result != Z_OK) { + string msg = string("Invalid uncompress return value: ") + intToStr(result); + throw megaglest_runtime_error(msg.c_str()); + } + //printf("uncompress returned: %d start size: %lu end size: %lu\n",result,input_len,decompressed_buffer_len); + delete[] compressed_buffer; + + return make_pair(decompressed_buffer, decompressed_buffer_len); + } - //printf("compress2 start size: %lu\n",input_len); - int result = compress2(compressed_buffer, &compressed_buffer_len, decompressed_buffer, input_len, compressionLevel); - if(result != Z_OK) { - string msg = string("Invalid compress2 return value: ") + intToStr(result); - throw megaglest_runtime_error(msg.c_str()); } - - //printf("compress2 returned: %d start size: %lu end size: %lu\n",result,input_len,compressed_buffer_len); - delete [] decompressed_buffer; - - return make_pair(compressed_buffer,compressed_buffer_len); } - -std::pair extractMemoryToMemory(unsigned char *input, unsigned long input_len, unsigned long max_output_len) { - // Like compress() but with more control, level may range from 0 (storing) to 9 (max. compression) - unsigned long decompressed_buffer_len = max_output_len; - unsigned char *decompressed_buffer = new unsigned char[decompressed_buffer_len+1]; - memset(decompressed_buffer,0,decompressed_buffer_len+1); - //printf("#1uncompress start size: %lu\n",input_len); - - unsigned char *compressed_buffer = new unsigned char[input_len+1]; - memcpy(compressed_buffer,input,input_len); - - //printf("#2uncompress start size: %lu\n",input_len); - //int result = uncompress(decompressed_buffer, &decompressed_buffer_len, compressed_buffer, input_len); - int result = uncompress(decompressed_buffer, &decompressed_buffer_len, compressed_buffer, input_len); - if(result != Z_OK) { - string msg = string("Invalid uncompress return value: ") + intToStr(result); - throw megaglest_runtime_error(msg.c_str()); - } - //printf("uncompress returned: %d start size: %lu end size: %lu\n",result,input_len,decompressed_buffer_len); - delete [] compressed_buffer; - - return make_pair(decompressed_buffer,decompressed_buffer_len); -} - -}} diff --git a/source/shared_lib/sources/feathery_ftp/ftpAccount.c b/source/shared_lib/sources/feathery_ftp/ftpAccount.c index dad292ed0..73ab78457 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpAccount.c +++ b/source/shared_lib/sources/feathery_ftp/ftpAccount.c @@ -30,14 +30,13 @@ #include "ftp.h" -/** - * @brief User account data - */ -typedef struct -{ - char name[MAXLEN_USERNAME+1]; ///< user name - char passw[MAXLEN_PASSWORD+1]; ///< password of the account - char ftpRoot[MAX_PATH_LEN+1]; ///< root path of the user account on the server + /** + * @brief User account data + */ +typedef struct { + char name[MAXLEN_USERNAME + 1]; ///< user name + char passw[MAXLEN_PASSWORD + 1]; ///< password of the account + char ftpRoot[MAX_PATH_LEN + 1]; ///< root path of the user account on the server int ftpRootLen; ///< length of ftpRoot int accRights; ///< access rights of a account @@ -49,13 +48,11 @@ typedef struct LOCAL ftpUserAccount_S ftpUsers[MAX_USERS]; -int ftpDeleteAccount(const char* name) -{ +int ftpDeleteAccount(const char* name) { int n; n = ftpFindAccount(name); // check if account already exists - if(n > 0) - { + if (n > 0) { ftpUsers[n - 1].name[0] = '\0'; // delete account return 0; } @@ -82,24 +79,20 @@ int ftpDeleteAccount(const char* name) * * @return 0 on success; -1 if MAX_USERS is reached */ -int ftpCreateAccount(const char* name, const char* passw, const char* root, int acc) -{ +int ftpCreateAccount(const char* name, const char* passw, const char* root, int acc) { int n; n = ftpFindAccount(name); // check if account already exists - if(n > 0) - { + if (n > 0) { ftpUsers[n - 1].name[0] = '\0'; // delete account } - for(n = 0; n < MAX_USERS; n++) - { - if(ftpUsers[n].name[0] == '\0') - { + for (n = 0; n < MAX_USERS; n++) { + if (ftpUsers[n].name[0] == '\0') { strncpy(ftpUsers[n].name, name, MAXLEN_USERNAME); strncpy(ftpUsers[n].passw, passw, MAXLEN_PASSWORD); strncpy(ftpUsers[n].ftpRoot, root, MAX_PATH_LEN); - ftpUsers[n].ftpRootLen = (int)strlen(root); + ftpUsers[n].ftpRootLen = (int) strlen(root); ftpUsers[n].accRights = acc; return 0; } @@ -117,12 +110,11 @@ int ftpCreateAccount(const char* name, const char* passw, const char* root, int * * @return 0 if user is not found; 1 to MAX_USERS+1 if user is found */ -int ftpFindAccount(const char* name) -{ - if(name[0] != '\0') { +int ftpFindAccount(const char* name) { + if (name[0] != '\0') { int n; - for(n = 0; n < MAX_USERS; n++) { - if(!strncmp(ftpUsers[n].name, name, MAXLEN_USERNAME)) { + for (n = 0; n < MAX_USERS; n++) { + if (!strncmp(ftpUsers[n].name, name, MAXLEN_USERNAME)) { return n + 1; } } @@ -130,12 +122,10 @@ int ftpFindAccount(const char* name) return 0; } -const char * ftpFindAccountById(int userid) -{ - if(userid == 0) { +const char * ftpFindAccountById(int userid) { + if (userid == 0) { return 0; - } - else if(ftpUsers[userid - 1].name[0] == '\0') { + } else if (ftpUsers[userid - 1].name[0] == '\0') { return 0; } @@ -154,15 +144,12 @@ const char * ftpFindAccountById(int userid) * - -1: invalid user account id * - else: incorrect password */ -int ftpCheckPassword(int userId, const char* passw) -{ - if(userId == 0) { +int ftpCheckPassword(int userId, const char* passw) { + if (userId == 0) { return -1; - } - else if(ftpUsers[userId - 1].passw[0] == '\0') { + } else if (ftpUsers[userId - 1].passw[0] == '\0') { return 0; - } - else { + } else { return strncmp(ftpUsers[userId - 1].passw, passw, MAXLEN_PASSWORD); } } @@ -178,12 +165,11 @@ int ftpCheckPassword(int userId, const char* passw) * @return - 0: the needed access rights are fulfilled * - -1: invalid user account id */ -int ftpCheckAccRights(int userId, int accRights) -{ - if(!userId) +int ftpCheckAccRights(int userId, int accRights) { + if (!userId) return -1; - if((ftpUsers[userId - 1].accRights & accRights) == accRights) + if ((ftpUsers[userId - 1].accRights & accRights) == accRights) return 0; return -1; @@ -197,11 +183,10 @@ int ftpCheckAccRights(int userId, int accRights) * * @return root directory name or NULL if the user account id is invalid */ -const char* ftpGetRoot(int userId, int* len) -{ - if(!userId) +const char* ftpGetRoot(int userId, int* len) { + if (!userId) return NULL; - if(len) + if (len) *len = ftpUsers[userId - 1].ftpRootLen; return ftpUsers[userId - 1].ftpRoot; diff --git a/source/shared_lib/sources/feathery_ftp/ftpCmds.c b/source/shared_lib/sources/feathery_ftp/ftpCmds.c index f1657cf05..2156be5ea 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpCmds.c +++ b/source/shared_lib/sources/feathery_ftp/ftpCmds.c @@ -15,31 +15,31 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -/* -DECLARATIVE SPECIFICATIONS + /* + DECLARATIVE SPECIFICATIONS - 5.1. MINIMUM IMPLEMENTATION + 5.1. MINIMUM IMPLEMENTATION - In order to make FTP workable without needless error messages, the - following minimum implementation is required for all servers: + In order to make FTP workable without needless error messages, the + following minimum implementation is required for all servers: - TYPE - ASCII Non-print - MODE - Stream - STRUCTURE - File, Record - COMMANDS - USER, QUIT, PORT, - TYPE, MODE, STRU, - for the default values - RETR, STOR, - NOOP. + TYPE - ASCII Non-print + MODE - Stream + STRUCTURE - File, Record + COMMANDS - USER, QUIT, PORT, + TYPE, MODE, STRU, + for the default values + RETR, STOR, + NOOP. - The default values for transfer parameters are: + The default values for transfer parameters are: - TYPE - ASCII Non-print - MODE - Stream - STRU - File + TYPE - ASCII Non-print + MODE - Stream + STRU - File - All hosts must accept the above as the standard defaults. - */ + All hosts must accept the above as the standard defaults. + */ #include @@ -57,184 +57,155 @@ DECLARATIVE SPECIFICATIONS LOCAL uint8_t scratchBuf[LEN_SCRATCHBUF]; -int ftpSendMsg(msgmode_E mode, int sessionId, int ret, const char* msg) -{ +int ftpSendMsg(msgmode_E mode, int sessionId, int ret, const char* msg) { int sentlen = 0; - int len = (int)strlen(msg); + int len = (int) strlen(msg); char buf[6]; - if(mode == MSG_QUOTE) - { - snprintf((char*)buf, 6,"%03d \"", ret); + if (mode == MSG_QUOTE) { + snprintf((char*) buf, 6, "%03d \"", ret); sentlen += ftpSend(ftpGetSession(sessionId)->ctrlSocket, buf, 5); sentlen += ftpSend(ftpGetSession(sessionId)->ctrlSocket, msg, len); sentlen += ftpSend(ftpGetSession(sessionId)->ctrlSocket, "\"\r\n", 3); - } - else - { - snprintf((char*)buf, 6,"%03d ", ret); + } else { + snprintf((char*) buf, 6, "%03d ", ret); sentlen += ftpSend(ftpGetSession(sessionId)->ctrlSocket, buf, 4); sentlen += ftpSend(ftpGetSession(sessionId)->ctrlSocket, msg, len); sentlen += ftpSend(ftpGetSession(sessionId)->ctrlSocket, "\r\n", 2); } -if(VERBOSE_MODE_ENABLED) printf("%02d <-- %s%s\n", sessionId, buf, msg); + if (VERBOSE_MODE_ENABLED) printf("%02d <-- %s%s\n", sessionId, buf, msg); return sentlen; } -int ftpExecTransmission(int sessionId) -{ +int ftpExecTransmission(int sessionId) { int finished = FALSE; size_t len; - ftpSession_S *pSession = ftpGetSession(sessionId); + ftpSession_S *pSession = ftpGetSession(sessionId); transmission_S *pTrans = &pSession->activeTrans; int rxLen; - pSession->timeLastCmd = ftpGetUnixTime(); - switch(pTrans->op) - { - case OP_RETR: - len = ftpReadFile(scratchBuf, 1, LEN_SCRATCHBUF, pTrans->fsHandle); - if(len > 0) - { - pTrans->fileSize -= (uint32_t)len; - if(ftpSend(pTrans->dataSocket, scratchBuf, (int)len)) - { - ftpSendMsg(MSG_NORMAL, sessionId, 426, ftpMsg000); - finished = TRUE; - } - } - else - { - if(VERBOSE_MODE_ENABLED) printf("ERROR in ftpExecTransmission ftpReadFile returned = %d for sessionId = %d\n",(int)len,sessionId); - ftpSendMsg(MSG_NORMAL, sessionId, 451, ftpMsg001); - finished = TRUE; - } - - if(pTrans->fileSize == 0) - { - ftpSendMsg(MSG_NORMAL, sessionId, 226, ftpMsg002); - finished = TRUE; - } - break; - case OP_STOR: - rxLen = 0; - do - { - len = ftpReceive(pTrans->dataSocket, &scratchBuf[rxLen], LEN_SCRATCHBUF - rxLen); - - if(len < 1) { - int errorNumber = getLastSocketError(); - const char *errText = getLastSocketErrorText(&errorNumber); - if(VERBOSE_MODE_ENABLED) printf("ftpExecTransmission ERROR ON RECEIVE for socket = %d, data len = %d, error = %d [%s]\n",pTrans->dataSocket,(LEN_SCRATCHBUF - rxLen),errorNumber,errText); - - break; + pSession->timeLastCmd = ftpGetUnixTime(); + switch (pTrans->op) { + case OP_RETR: + len = ftpReadFile(scratchBuf, 1, LEN_SCRATCHBUF, pTrans->fsHandle); + if (len > 0) { + pTrans->fileSize -= (uint32_t) len; + if (ftpSend(pTrans->dataSocket, scratchBuf, (int) len)) { + ftpSendMsg(MSG_NORMAL, sessionId, 426, ftpMsg000); + finished = TRUE; + } + } else { + if (VERBOSE_MODE_ENABLED) printf("ERROR in ftpExecTransmission ftpReadFile returned = %d for sessionId = %d\n", (int) len, sessionId); + ftpSendMsg(MSG_NORMAL, sessionId, 451, ftpMsg001); + finished = TRUE; } - rxLen += (int)len; - } while(rxLen < LEN_SCRATCHBUF); - - if(rxLen > 0) - { - size_t res = ftpWriteFile(scratchBuf, 1, rxLen, pTrans->fsHandle); - if(res != (size_t)rxLen) - { - if(VERBOSE_MODE_ENABLED) printf("ERROR in ftpExecTransmission ftpWriteFile returned = %d for sessionId = %d\n",(int)res,sessionId); - - ftpSendMsg(MSG_NORMAL, sessionId, 451, ftpMsg001); - finished = TRUE; + if (pTrans->fileSize == 0) { + ftpSendMsg(MSG_NORMAL, sessionId, 226, ftpMsg002); + finished = TRUE; } - } + break; + case OP_STOR: + rxLen = 0; + do { + len = ftpReceive(pTrans->dataSocket, &scratchBuf[rxLen], LEN_SCRATCHBUF - rxLen); - if(len < 1) - { - ftpSendMsg(MSG_NORMAL, sessionId, 226, ftpMsg003); - finished = TRUE; - } + if (len < 1) { + int errorNumber = getLastSocketError(); + const char *errText = getLastSocketErrorText(&errorNumber); + if (VERBOSE_MODE_ENABLED) printf("ftpExecTransmission ERROR ON RECEIVE for socket = %d, data len = %d, error = %d [%s]\n", pTrans->dataSocket, (LEN_SCRATCHBUF - rxLen), errorNumber, errText); - break; - case OP_LIST: - break; + break; + } - default: - return -1; + rxLen += (int) len; + } while (rxLen < LEN_SCRATCHBUF); + + if (rxLen > 0) { + size_t res = ftpWriteFile(scratchBuf, 1, rxLen, pTrans->fsHandle); + if (res != (size_t) rxLen) { + if (VERBOSE_MODE_ENABLED) printf("ERROR in ftpExecTransmission ftpWriteFile returned = %d for sessionId = %d\n", (int) res, sessionId); + + ftpSendMsg(MSG_NORMAL, sessionId, 451, ftpMsg001); + finished = TRUE; + } + } + + if (len < 1) { + ftpSendMsg(MSG_NORMAL, sessionId, 226, ftpMsg003); + finished = TRUE; + } + + break; + case OP_LIST: + break; + + default: + return -1; } - if(finished) - { + if (finished) { ftpCloseTransmission(sessionId); return 1; - } - else - { + } else { return 0; } } -LOCAL int ftpCmdUser(int sessionId, const char* args, int len) -{ +LOCAL int ftpCmdUser(int sessionId, const char* args, int len) { ftpSendMsg(MSG_NORMAL, sessionId, 331, ftpMsg004); ftpGetSession(sessionId)->userId = ftpFindAccount(args); return 0; } -LOCAL int ftpCmdPass(int sessionId, const char* args, int len) -{ - if(!ftpCheckPassword(ftpGetSession(sessionId)->userId, args)) - { +LOCAL int ftpCmdPass(int sessionId, const char* args, int len) { + if (!ftpCheckPassword(ftpGetSession(sessionId)->userId, args)) { ftpAuthSession(sessionId); ftpSendMsg(MSG_NORMAL, sessionId, 230, ftpMsg005); - } - else - { + } else { ftpGetSession(sessionId)->userId = 0; ftpSendMsg(MSG_NORMAL, sessionId, 530, ftpMsg006); } return 0; } -LOCAL int ftpCmdSyst(int sessionId, const char* args, int len) -{ +LOCAL int ftpCmdSyst(int sessionId, const char* args, int len) { ftpSendMsg(MSG_NORMAL, sessionId, 215, "UNIX Type: L8"); return 0; } -LOCAL int ftpCmdPort(int sessionId, const char* args, int len) -{ +LOCAL int ftpCmdPort(int sessionId, const char* args, int len) { //char clientIp[16]=""; - uint16_t clientPort=0; + uint16_t clientPort = 0; int commaCnt = 0; int n; char* p; - for(n = 0; args[n] != '\0'; n++) - { - if(commaCnt <= 3) // Ip-Adresse + for (n = 0; args[n] != '\0'; n++) { + if (commaCnt <= 3) // Ip-Adresse { - if(args[n] == ',') - { + if (args[n] == ',') { commaCnt++; -// if(commaCnt < 4) -// clientIp[n] = '.'; -// else -// clientIp[n] = '\0'; + // if(commaCnt < 4) + // clientIp[n] = '.'; + // else + // clientIp[n] = '\0'; } -// else -// clientIp[n] = args[n]; - } - else // Port-Nummer + // else + // clientIp[n] = args[n]; + } else // Port-Nummer { - p = (char*)&args[n]; - clientPort = (uint16_t)(strtoul(p, &p, 0) << 8); + p = (char*) &args[n]; + clientPort = (uint16_t) (strtoul(p, &p, 0) << 8); p++; clientPort |= strtoul(p, &p, 0); break; } } - if(ftpGetSession(sessionId)->passiveDataSocket >= 0) - { - if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPort about to Close socket = %d for sessionId = %d\n",ftpGetSession(sessionId)->passiveDataSocket,sessionId); + if (ftpGetSession(sessionId)->passiveDataSocket >= 0) { + if (VERBOSE_MODE_ENABLED) printf("In ftpCmdPort about to Close socket = %d for sessionId = %d\n", ftpGetSession(sessionId)->passiveDataSocket, sessionId); ftpUntrackSocket(ftpGetSession(sessionId)->passiveDataSocket); ftpCloseSocket(&ftpGetSession(sessionId)->passiveDataSocket); @@ -242,25 +213,22 @@ LOCAL int ftpCmdPort(int sessionId, const char* args, int len) } //ftpGetSession(sessionId)->passiveDataSocket = -1; ftpGetSession(sessionId)->remoteDataPort = clientPort; - ftpGetSession(sessionId)->passive = FALSE; + ftpGetSession(sessionId)->passive = FALSE; ftpSendMsg(MSG_NORMAL, sessionId, 200, ftpMsg007); return 0; } -LOCAL int ftpCmdNoop(int sessionId, const char* args, int len) -{ +LOCAL int ftpCmdNoop(int sessionId, const char* args, int len) { ftpSendMsg(MSG_NORMAL, sessionId, 200, ftpMsg008); return 0; } -LOCAL int ftpCmdQuit(int sessionId, const char* args, int len) -{ +LOCAL int ftpCmdQuit(int sessionId, const char* args, int len) { ftpSendMsg(MSG_NORMAL, sessionId, 221, ftpMsg009); return -1; } -LOCAL int ftpCmdAbor(int sessionId, const char* args, int len) -{ +LOCAL int ftpCmdAbor(int sessionId, const char* args, int len) { ftpCloseTransmission(sessionId); ftpSendMsg(MSG_NORMAL, sessionId, 226, ftpMsg040); @@ -272,150 +240,127 @@ LOCAL int ftpCmdAbor(int sessionId, const char* args, int len) #define NLST 2 #define MLST 4 #define MLSD 8 -LOCAL int sendListing(socket_t dataSocket, int sessionId, const char* path, int format) -{ +LOCAL int sendListing(socket_t dataSocket, int sessionId, const char* path, int format) { void *dir; - const char monName[12][4] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; + const char monName[12][4] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; dir = ftpOpenDir(path); - if(dir) - { + if (dir) { const char* dirEntry = NULL; int len = 0; int err = 0; - ftpTime_S currTime = {0}; + ftpTime_S currTime = { 0 }; ftpPathInfo_S fileInfo; int haveAnySuccessfulFiles = 0; - ftpGetLocalTime(&currTime); + ftpGetLocalTime(&currTime); ftpSendMsg(MSG_NORMAL, sessionId, 150, ftpMsg010); - if(VERBOSE_MODE_ENABLED) printf("In sendListing about to read dir contents [%s] for sessionId = %d, dataSocket = %d\n", path,sessionId,dataSocket); + if (VERBOSE_MODE_ENABLED) printf("In sendListing about to read dir contents [%s] for sessionId = %d, dataSocket = %d\n", path, sessionId, dataSocket); - haveAnySuccessfulFiles = 0; - while((dirEntry = ftpReadDir(dir)) != NULL) - { - const char * realPath = ftpGetRealPath(sessionId, dirEntry, FALSE); - int statResult = ftpStat(realPath, &fileInfo); + haveAnySuccessfulFiles = 0; + while ((dirEntry = ftpReadDir(dir)) != NULL) { + const char * realPath = ftpGetRealPath(sessionId, dirEntry, FALSE); + int statResult = ftpStat(realPath, &fileInfo); - if(VERBOSE_MODE_ENABLED) printf("ftpGetRealPath() returned [%s] stat() = %d\n", realPath, statResult); + if (VERBOSE_MODE_ENABLED) printf("ftpGetRealPath() returned [%s] stat() = %d\n", realPath, statResult); - if(statResult == 0) - { - if((format & ALL) == 0) - { - if(dirEntry[0] == '.') + if (statResult == 0) { + if ((format & ALL) == 0) { + if (dirEntry[0] == '.') continue; } - if(format & LIST) - { - switch(fileInfo.type) - { - default: - case TYPE_FILE: - scratchBuf[0] = '-'; - break; - case TYPE_DIR: - scratchBuf[0] = 'd'; - break; - case TYPE_LINK: - scratchBuf[0] = 'l'; - break; - } - - if(currTime.year == fileInfo.mTime.year) - { - len = snprintf((char*)&scratchBuf[1], LEN_SCRATCHBUF-1,"rwxrwxrwx %4u %-8s %-8s %8u %s %02d %02d:%02d %s\r\n", - fileInfo.links, - fileInfo.user, - fileInfo.group, - fileInfo.size, - monName[fileInfo.mTime.month - 1], - fileInfo.mTime.day, - fileInfo.mTime.hour, - fileInfo.mTime.minute, - dirEntry); - } - else - { - len = snprintf((char*)&scratchBuf[1], LEN_SCRATCHBUF-1,"rwxrwxrwx %4u %-8s %-8s %8u %s %02d %5d %s\r\n", - fileInfo.links, - fileInfo.user, - fileInfo.group, - fileInfo.size, - monName[fileInfo.mTime.month - 1], - fileInfo.mTime.day, - fileInfo.mTime.year, - dirEntry); - } - ftpSend(dataSocket, scratchBuf, len + 1); - haveAnySuccessfulFiles = 1; - } - else if(format & NLST) - { - len = snprintf((char*)scratchBuf, LEN_SCRATCHBUF,"%s\r\n", dirEntry); - ftpSend(dataSocket, scratchBuf, len); - haveAnySuccessfulFiles = 1; - } - else if(format & MLSD) - { - if(!strcmp("..", dirEntry)) - len = snprintf((char*)scratchBuf, LEN_SCRATCHBUF,"Type=pdir"); - else - { - switch(fileInfo.type) - { + if (format & LIST) { + switch (fileInfo.type) { default: case TYPE_FILE: - len = snprintf((char*)scratchBuf, LEN_SCRATCHBUF,"Type=file"); + scratchBuf[0] = '-'; break; case TYPE_DIR: - len = snprintf((char*)scratchBuf, LEN_SCRATCHBUF,"Type=dir"); + scratchBuf[0] = 'd'; break; case TYPE_LINK: - len = snprintf((char*)scratchBuf, LEN_SCRATCHBUF,"Type=OS.unix=slink"); + scratchBuf[0] = 'l'; break; - } } - ftpSend(dataSocket, scratchBuf, len); - len = snprintf((char*)scratchBuf, LEN_SCRATCHBUF,";Size=%u;Modify=%04d%02d%02d%02d%02d%02d;Perm=r; %s\r\n", + + if (currTime.year == fileInfo.mTime.year) { + len = snprintf((char*) &scratchBuf[1], LEN_SCRATCHBUF - 1, "rwxrwxrwx %4u %-8s %-8s %8u %s %02d %02d:%02d %s\r\n", + fileInfo.links, + fileInfo.user, + fileInfo.group, fileInfo.size, - fileInfo.mTime.year, - fileInfo.mTime.month, + monName[fileInfo.mTime.month - 1], fileInfo.mTime.day, fileInfo.mTime.hour, fileInfo.mTime.minute, - fileInfo.mTime.second, dirEntry); + } else { + len = snprintf((char*) &scratchBuf[1], LEN_SCRATCHBUF - 1, "rwxrwxrwx %4u %-8s %-8s %8u %s %02d %5d %s\r\n", + fileInfo.links, + fileInfo.user, + fileInfo.group, + fileInfo.size, + monName[fileInfo.mTime.month - 1], + fileInfo.mTime.day, + fileInfo.mTime.year, + dirEntry); + } + ftpSend(dataSocket, scratchBuf, len + 1); + haveAnySuccessfulFiles = 1; + } else if (format & NLST) { + len = snprintf((char*) scratchBuf, LEN_SCRATCHBUF, "%s\r\n", dirEntry); + ftpSend(dataSocket, scratchBuf, len); + haveAnySuccessfulFiles = 1; + } else if (format & MLSD) { + if (!strcmp("..", dirEntry)) + len = snprintf((char*) scratchBuf, LEN_SCRATCHBUF, "Type=pdir"); + else { + switch (fileInfo.type) { + default: + case TYPE_FILE: + len = snprintf((char*) scratchBuf, LEN_SCRATCHBUF, "Type=file"); + break; + case TYPE_DIR: + len = snprintf((char*) scratchBuf, LEN_SCRATCHBUF, "Type=dir"); + break; + case TYPE_LINK: + len = snprintf((char*) scratchBuf, LEN_SCRATCHBUF, "Type=OS.unix=slink"); + break; + } + } + ftpSend(dataSocket, scratchBuf, len); + len = snprintf((char*) scratchBuf, LEN_SCRATCHBUF, ";Size=%u;Modify=%04d%02d%02d%02d%02d%02d;Perm=r; %s\r\n", + fileInfo.size, + fileInfo.mTime.year, + fileInfo.mTime.month, + fileInfo.mTime.day, + fileInfo.mTime.hour, + fileInfo.mTime.minute, + fileInfo.mTime.second, + dirEntry); ftpSend(dataSocket, scratchBuf, len); haveAnySuccessfulFiles = 1; } - } - else - { + } else { err = 1; //break; } } ftpCloseDir(dir); - if(err && haveAnySuccessfulFiles == 0) - { - if(VERBOSE_MODE_ENABLED) printf("ERROR in sendListing err = %d, path = [%s] for sessionId = %d, dataSocket = %d\n",err,path,sessionId,dataSocket); + if (err && haveAnySuccessfulFiles == 0) { + if (VERBOSE_MODE_ENABLED) printf("ERROR in sendListing err = %d, path = [%s] for sessionId = %d, dataSocket = %d\n", err, path, sessionId, dataSocket); ftpSendMsg(MSG_NORMAL, sessionId, 451, ftpMsg039); - } - else - { + } else { ftpSendMsg(MSG_NORMAL, sessionId, 226, ftpMsg013); } - } - else - { - if(VERBOSE_MODE_ENABLED) printf("ERROR opendir [%s] returned errno: %#x for sessionId = %d, dataSocket = %d\n", path,errno,sessionId,dataSocket); + } else { + if (VERBOSE_MODE_ENABLED) printf("ERROR opendir [%s] returned errno: %#x for sessionId = %d, dataSocket = %d\n", path, errno, sessionId, dataSocket); ftpSendMsg(MSG_NORMAL, sessionId, 451, ftpMsg038); } @@ -423,155 +368,134 @@ LOCAL int sendListing(socket_t dataSocket, int sessionId, const char* path, int return 0; } -LOCAL int ftpCmdList(int sessionId, const char* args, int len) -{ +LOCAL int ftpCmdList(int sessionId, const char* args, int len) { const char* realPath; socket_t s; -//#### Funktioniert nicht wenn Pfad übergeben wird -/* if(args[0] != '\0') - { - if(args[0] != '-') - realPath = ftpGetRealPath(sessionId, args); - } - else*/ - realPath = ftpGetRealPath(sessionId, ftpGetSession(sessionId)->workingDir, TRUE); + //#### Funktioniert nicht wenn Pfad übergeben wird + /* if(args[0] != '\0') + { + if(args[0] != '-') + realPath = ftpGetRealPath(sessionId, args); + } + else*/ + realPath = ftpGetRealPath(sessionId, ftpGetSession(sessionId)->workingDir, TRUE); - if(ftpGetSession(sessionId)->passive == FALSE) - { - s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort,sessionId); - if(s < 0) - { - ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg011); - return 1; - } - } - else - { - s = ftpAcceptDataConnection(ftpGetSession(sessionId)->passiveDataSocket); - if(s < 0) - { - ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg012); - return 1; - } - } + if (ftpGetSession(sessionId)->passive == FALSE) { + s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort, sessionId); + if (s < 0) { + ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg011); + return 1; + } + } else { + s = ftpAcceptDataConnection(ftpGetSession(sessionId)->passiveDataSocket); + if (s < 0) { + ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg012); + return 1; + } + } sendListing(s, sessionId, realPath, LIST); - if(VERBOSE_MODE_ENABLED) printf("In ftpCmdList about to Close socket = %d for sessionId = %d\n",s,sessionId); + if (VERBOSE_MODE_ENABLED) printf("In ftpCmdList about to Close socket = %d for sessionId = %d\n", s, sessionId); ftpUntrackSocket(s); ftpCloseSocket(&s); return 0; } -LOCAL int ftpCmdNlst(int sessionId, const char* args, int len) -{ +LOCAL int ftpCmdNlst(int sessionId, const char* args, int len) { //#### -List kann auch Argumente haben const char* realPath; socket_t s; -/* if(pfad übergeben) - realPath = ftpGetRealPath(sessionId, args); - else*/ - realPath = ftpGetRealPath(sessionId, ftpGetSession(sessionId)->workingDir, TRUE); + /* if(pfad übergeben) + realPath = ftpGetRealPath(sessionId, args); + else*/ + realPath = ftpGetRealPath(sessionId, ftpGetSession(sessionId)->workingDir, TRUE); - if(ftpGetSession(sessionId)->passive == FALSE) - { - s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort,sessionId); - if(s < 0) - { - ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg011); - return 1; - } - } - else - { - s = ftpAcceptDataConnection(ftpGetSession(sessionId)->passiveDataSocket); - if(s < 0) - { - ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg012); - return 1; - } - } + if (ftpGetSession(sessionId)->passive == FALSE) { + s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort, sessionId); + if (s < 0) { + ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg011); + return 1; + } + } else { + s = ftpAcceptDataConnection(ftpGetSession(sessionId)->passiveDataSocket); + if (s < 0) { + ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg012); + return 1; + } + } sendListing(s, sessionId, realPath, NLST); - if(VERBOSE_MODE_ENABLED) printf("In ftpCmdNlst about to Close socket = %d for sessionId = %d\n",s,sessionId); + if (VERBOSE_MODE_ENABLED) printf("In ftpCmdNlst about to Close socket = %d for sessionId = %d\n", s, sessionId); ftpUntrackSocket(s); ftpCloseSocket(&s); return 0; } -LOCAL int ftpCmdRetr(int sessionId, const char* args, int len) -{ +LOCAL int ftpCmdRetr(int sessionId, const char* args, int len) { ftpPathInfo_S fileInfo; - const char* realPath = ftpGetRealPath(sessionId, args, TRUE); + const char* realPath = ftpGetRealPath(sessionId, args, TRUE); socket_t s; void *fp; int statResult = 0; - if(VERBOSE_MODE_ENABLED) printf("In ftpCmdRetr args [%s] realPath [%s]\n", args, realPath); + if (VERBOSE_MODE_ENABLED) printf("In ftpCmdRetr args [%s] realPath [%s]\n", args, realPath); - statResult = ftpStat(realPath, &fileInfo); - if(VERBOSE_MODE_ENABLED) printf("stat() = %d fileInfo.type = %d\n", statResult,fileInfo.type); + statResult = ftpStat(realPath, &fileInfo); + if (VERBOSE_MODE_ENABLED) printf("stat() = %d fileInfo.type = %d\n", statResult, fileInfo.type); - if(statResult || (fileInfo.type != TYPE_FILE)) // file accessible? - { - if(VERBOSE_MODE_ENABLED) printf("ERROR In ftpCmdRetr [file not available] args [%s] realPath [%s]\n", args, realPath); + if (statResult || (fileInfo.type != TYPE_FILE)) // file accessible? + { + if (VERBOSE_MODE_ENABLED) printf("ERROR In ftpCmdRetr [file not available] args [%s] realPath [%s]\n", args, realPath); - ftpSendMsg(MSG_NORMAL, sessionId, 550, ftpMsg032); - return 2; - } + ftpSendMsg(MSG_NORMAL, sessionId, 550, ftpMsg032); + return 2; + } - if(ftpIsClientAllowedToGetFile != NULL) { - if(ftpIsClientAllowedToGetFile(ftpGetSession(sessionId)->remoteIp,ftpFindAccountById(ftpGetSession(sessionId)->userId),realPath) != 1) { - if(VERBOSE_MODE_ENABLED) printf("ERROR In ftpCmdRetr FILE DISALLOWED By MGserver [file not available] args [%s] realPath [%s]\n", args, realPath); + if (ftpIsClientAllowedToGetFile != NULL) { + if (ftpIsClientAllowedToGetFile(ftpGetSession(sessionId)->remoteIp, ftpFindAccountById(ftpGetSession(sessionId)->userId), realPath) != 1) { + if (VERBOSE_MODE_ENABLED) printf("ERROR In ftpCmdRetr FILE DISALLOWED By MGserver [file not available] args [%s] realPath [%s]\n", args, realPath); - ftpSendMsg(MSG_NORMAL, sessionId, 550, ftpMsg032); - return 2; + ftpSendMsg(MSG_NORMAL, sessionId, 550, ftpMsg032); + return 2; } } - if(ftpGetSession(sessionId)->passive == FALSE) - { - s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort,sessionId); - if(s < 0) - { - ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg011); - return 1; - } - } - else - { - if(VERBOSE_MODE_ENABLED) printf("In ftpCmdRetr about accept passive data connection, args [%s] realPath [%s]\n", args, realPath); + if (ftpGetSession(sessionId)->passive == FALSE) { + s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort, sessionId); + if (s < 0) { + ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg011); + return 1; + } + } else { + if (VERBOSE_MODE_ENABLED) printf("In ftpCmdRetr about accept passive data connection, args [%s] realPath [%s]\n", args, realPath); - s = ftpAcceptDataConnection(ftpGetSession(sessionId)->passiveDataSocket); - if(s < 0) - { - if(VERBOSE_MODE_ENABLED) printf("ERROR In ftpCmdRetr failed to accept data connection, args [%s] realPath [%s]\n", args, realPath); + s = ftpAcceptDataConnection(ftpGetSession(sessionId)->passiveDataSocket); + if (s < 0) { + if (VERBOSE_MODE_ENABLED) printf("ERROR In ftpCmdRetr failed to accept data connection, args [%s] realPath [%s]\n", args, realPath); - ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg012); - return 1; - } - } + ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg012); + return 1; + } + } ftpSendMsg(MSG_NORMAL, sessionId, 150, ftpMsg014); fp = ftpOpenFile(realPath, "rb"); - if(fp) - { - if(VERBOSE_MODE_ENABLED) printf("In ftpCmdRetr opened realPath [%s] [%p] for sessionId = %d for socket = %d\n",realPath,fp,sessionId,s); + if (fp) { + if (VERBOSE_MODE_ENABLED) printf("In ftpCmdRetr opened realPath [%s] [%p] for sessionId = %d for socket = %d\n", realPath, fp, sessionId, s); ftpOpenTransmission(sessionId, OP_RETR, fp, s, fileInfo.size); ftpExecTransmission(sessionId); - } - else - { - if(VERBOSE_MODE_ENABLED) printf("ERROR in ftpCmdRetr could not open realPath [%s] for sessionId = %d for socket = %d\n",realPath,sessionId,s); + } else { + if (VERBOSE_MODE_ENABLED) printf("ERROR in ftpCmdRetr could not open realPath [%s] for sessionId = %d for socket = %d\n", realPath, sessionId, s); ftpSendMsg(MSG_NORMAL, sessionId, 451, ftpMsg015); - if(VERBOSE_MODE_ENABLED) printf("In ftpCmdRetr about to Close socket = %d for sessionId = %d\n",s,sessionId); + if (VERBOSE_MODE_ENABLED) printf("In ftpCmdRetr about to Close socket = %d for sessionId = %d\n", s, sessionId); ftpUntrackSocket(s); ftpCloseSocket(&s); } @@ -579,93 +503,80 @@ LOCAL int ftpCmdRetr(int sessionId, const char* args, int len) return 0; } -LOCAL int ftpCmdStor(int sessionId, const char* args, int len) -{ +LOCAL int ftpCmdStor(int sessionId, const char* args, int len) { socket_t s; - void* fp; - const char* realPath = ftpGetRealPath(sessionId, args, TRUE); + void* fp; + const char* realPath = ftpGetRealPath(sessionId, args, TRUE); - if(ftpGetSession(sessionId)->passive == FALSE) - { - s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort,sessionId); - if(s < 0) - { - ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg011); - return 1; - } - } - else - { - s = ftpAcceptDataConnection(ftpGetSession(sessionId)->passiveDataSocket); - if(s < 0) - { - ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg012); - return 1; - } - } + if (ftpGetSession(sessionId)->passive == FALSE) { + s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort, sessionId); + if (s < 0) { + ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg011); + return 1; + } + } else { + s = ftpAcceptDataConnection(ftpGetSession(sessionId)->passiveDataSocket); + if (s < 0) { + ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg012); + return 1; + } + } ftpSendMsg(MSG_NORMAL, sessionId, 150, ftpMsg016); - fp = ftpOpenFile(realPath, "wb"); - if(fp) - { - ftpOpenTransmission(sessionId, OP_STOR, fp, s, 0); + fp = ftpOpenFile(realPath, "wb"); + if (fp) { + ftpOpenTransmission(sessionId, OP_STOR, fp, s, 0); ftpExecTransmission(sessionId); - } - else - { - if(VERBOSE_MODE_ENABLED) printf("ERROR in ftpCmdStor could not open realPath [%s]\n",realPath); + } else { + if (VERBOSE_MODE_ENABLED) printf("ERROR in ftpCmdStor could not open realPath [%s]\n", realPath); ftpSendMsg(MSG_NORMAL, sessionId, 451, ftpMsg015); - if(VERBOSE_MODE_ENABLED) printf("In ftpCmdStor about to Close socket = %d for sessionId = %d\n",s,sessionId); + if (VERBOSE_MODE_ENABLED) printf("In ftpCmdStor about to Close socket = %d for sessionId = %d\n", s, sessionId); ftpUntrackSocket(s); ftpCloseSocket(&s); - } + } return 0; } -LOCAL int ftpCmdDele(int sessionId, const char* args, int len) -{ - const char* realPath = ftpGetRealPath(sessionId, args, TRUE); - if(ftpRemoveFile(realPath)) - ftpSendMsg(MSG_NORMAL, sessionId, 450, ftpMsg018); - else - ftpSendMsg(MSG_NORMAL, sessionId, 250, ftpMsg019); +LOCAL int ftpCmdDele(int sessionId, const char* args, int len) { + const char* realPath = ftpGetRealPath(sessionId, args, TRUE); + if (ftpRemoveFile(realPath)) + ftpSendMsg(MSG_NORMAL, sessionId, 450, ftpMsg018); + else + ftpSendMsg(MSG_NORMAL, sessionId, 250, ftpMsg019); return 0; } -LOCAL int ftpCmdMkd(int sessionId, const char* args, int len) -{ - const char* realPath = ftpGetRealPath(sessionId, args, TRUE); - if(ftpMakeDir(realPath)) - ftpSendMsg(MSG_NORMAL, sessionId, 550, ftpMsg020); - else - ftpSendMsg(MSG_NORMAL, sessionId, 250, ftpMsg021); +LOCAL int ftpCmdMkd(int sessionId, const char* args, int len) { + const char* realPath = ftpGetRealPath(sessionId, args, TRUE); + if (ftpMakeDir(realPath)) + ftpSendMsg(MSG_NORMAL, sessionId, 550, ftpMsg020); + else + ftpSendMsg(MSG_NORMAL, sessionId, 250, ftpMsg021); return 0; } -LOCAL int ftpCmdRmd(int sessionId, const char* args, int len) -{ - const char* realPath = ftpGetRealPath(sessionId, args, TRUE); - if(ftpRemoveDir(realPath)) - ftpSendMsg(MSG_NORMAL, sessionId, 550, ftpMsg022); - else - ftpSendMsg(MSG_NORMAL, sessionId, 250, ftpMsg023); +LOCAL int ftpCmdRmd(int sessionId, const char* args, int len) { + const char* realPath = ftpGetRealPath(sessionId, args, TRUE); + if (ftpRemoveDir(realPath)) + ftpSendMsg(MSG_NORMAL, sessionId, 550, ftpMsg022); + else + ftpSendMsg(MSG_NORMAL, sessionId, 250, ftpMsg023); return 0; } -LOCAL int ftpCmdPwd(int sessionId, const char* args, int len) -{ - if(ftpGetSession(sessionId)->workingDir[0]) +LOCAL int ftpCmdPwd(int sessionId, const char* args, int len) { + if (ftpGetSession(sessionId)->workingDir[0]) ftpSendMsg(MSG_QUOTE, sessionId, 257, ftpGetSession(sessionId)->workingDir); else ftpSendMsg(MSG_QUOTE, sessionId, 257, "/"); @@ -673,9 +584,8 @@ LOCAL int ftpCmdPwd(int sessionId, const char* args, int len) return 0; } -LOCAL int ftpCmdCwd(int sessionId, const char* args, int len) -{ - if(ftpChangeDir(sessionId, args) == 0) +LOCAL int ftpCmdCwd(int sessionId, const char* args, int len) { + if (ftpChangeDir(sessionId, args) == 0) ftpSendMsg(MSG_NORMAL, sessionId, 250, ftpMsg024); else ftpSendMsg(MSG_NORMAL, sessionId, 550, ftpMsg025); @@ -683,220 +593,196 @@ LOCAL int ftpCmdCwd(int sessionId, const char* args, int len) return 0; } -LOCAL int ftpCmdType(int sessionId, const char* args, int len) -{ - switch(args[0]) - { - case 'I': - case 'i': - ftpSendMsg(MSG_NORMAL, sessionId, 200, ftpMsg026); - ftpGetSession(sessionId)->binary = TRUE; - break; - case 'A': - case 'a': - ftpSendMsg(MSG_NORMAL, sessionId, 200, ftpMsg027); - ftpGetSession(sessionId)->binary = FALSE; - break; - default: - ftpSendMsg(MSG_NORMAL, sessionId, 504, ftpMsg028); - break; +LOCAL int ftpCmdType(int sessionId, const char* args, int len) { + switch (args[0]) { + case 'I': + case 'i': + ftpSendMsg(MSG_NORMAL, sessionId, 200, ftpMsg026); + ftpGetSession(sessionId)->binary = TRUE; + break; + case 'A': + case 'a': + ftpSendMsg(MSG_NORMAL, sessionId, 200, ftpMsg027); + ftpGetSession(sessionId)->binary = FALSE; + break; + default: + ftpSendMsg(MSG_NORMAL, sessionId, 504, ftpMsg028); + break; } return 0; } -LOCAL int ftpCmdPasv(int sessionId, const char* args, int len) -{ +LOCAL int ftpCmdPasv(int sessionId, const char* args, int len) { uint16_t port; uint32_t ip; char str[50]; socket_t s; uint32_t remoteFTPServerIp; - if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, ftpGetSession(sessionId)->passiveDataSocket = %d\n", sessionId, ftpGetSession(sessionId)->passiveDataSocket); + if (VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, ftpGetSession(sessionId)->passiveDataSocket = %d\n", sessionId, ftpGetSession(sessionId)->passiveDataSocket); - if(ftpGetSession(sessionId)->passiveDataSocket <= 0) - { + if (ftpGetSession(sessionId)->passiveDataSocket <= 0) { //if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv about to Close socket = %d for sessionId = %d\n",ftpGetSession(sessionId)->passiveDataSocket,sessionId); //ftpUntrackSocket(ftpGetSession(sessionId)->passiveDataSocket); //ftpCloseSocket(&ftpGetSession(sessionId)->passiveDataSocket); //} //ftpGetSession(sessionId)->passiveDataSocket = -1; - s = ftpEstablishDataConnection(TRUE, &ip, &port,sessionId); - if(s < 0) - { + s = ftpEstablishDataConnection(TRUE, &ip, &port, sessionId); + if (s < 0) { ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg012); return 1; } ftpGetSession(sessionId)->passiveDataSocket = s; - ftpGetSession(sessionId)->passiveIp = ip; - ftpGetSession(sessionId)->passivePort = port; - } - else - { - s = ftpGetSession(sessionId)->passiveDataSocket; + ftpGetSession(sessionId)->passiveIp = ip; + ftpGetSession(sessionId)->passivePort = port; + } else { + s = ftpGetSession(sessionId)->passiveDataSocket; ip = ftpGetSession(sessionId)->passiveIp; port = ftpGetSession(sessionId)->passivePort; } //if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, client IP = %u, remote IP = %u, port = %d, ftpAddUPNPPortForward = %p, ftpRemoveUPNPPortForward = %p using listener socket = %d\n", - // sessionId, ftpGetSession(sessionId)->remoteIp, ftpFindExternalFTPServerIp(ftpGetSession(sessionId)->remoteIp), port,ftpAddUPNPPortForward,ftpRemoveUPNPPortForward,s); - if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, client IP = %u, remote IP = %u, port = %d, using listener socket = %d\n", - sessionId, ftpGetSession(sessionId)->remoteIp, ftpFindExternalFTPServerIp(ftpGetSession(sessionId)->remoteIp), port,s); + // sessionId, ftpGetSession(sessionId)->remoteIp, ftpFindExternalFTPServerIp(ftpGetSession(sessionId)->remoteIp), port,ftpAddUPNPPortForward,ftpRemoveUPNPPortForward,s); + if (VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, client IP = %u, remote IP = %u, port = %d, using listener socket = %d\n", + sessionId, ftpGetSession(sessionId)->remoteIp, ftpFindExternalFTPServerIp(ftpGetSession(sessionId)->remoteIp), port, s); - if(ftpAddUPNPPortForward != NULL && ftpFindExternalFTPServerIp(ftpGetSession(sessionId)->remoteIp) != 0) - { - ftpGetSession(sessionId)->remoteFTPServerPassivePort = port; + if (ftpAddUPNPPortForward != NULL && ftpFindExternalFTPServerIp(ftpGetSession(sessionId)->remoteIp) != 0) { + ftpGetSession(sessionId)->remoteFTPServerPassivePort = port; - //if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, adding UPNP port forward\n", sessionId); - //ftpAddUPNPPortForward(port, port); + //if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, adding UPNP port forward\n", sessionId); + //ftpAddUPNPPortForward(port, port); - remoteFTPServerIp = ftpFindExternalFTPServerIp(ftpGetSession(sessionId)->remoteIp); + remoteFTPServerIp = ftpFindExternalFTPServerIp(ftpGetSession(sessionId)->remoteIp); - snprintf(str, 50,"%s (%d,%d,%d,%u,%d,%d)", - ftpMsg029, - (remoteFTPServerIp >> 24) & 0xFF, - (remoteFTPServerIp >> 16) & 0xFF, - (remoteFTPServerIp >> 8) & 0xFF, - remoteFTPServerIp & 0xFF, - (port >> 8) & 0xFF, - port & 0xFF); + snprintf(str, 50, "%s (%d,%d,%d,%u,%d,%d)", + ftpMsg029, + (remoteFTPServerIp >> 24) & 0xFF, + (remoteFTPServerIp >> 16) & 0xFF, + (remoteFTPServerIp >> 8) & 0xFF, + remoteFTPServerIp & 0xFF, + (port >> 8) & 0xFF, + port & 0xFF); - if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, str [%s]\n", sessionId, str); + if (VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, str [%s]\n", sessionId, str); - } - else - { - snprintf(str, 50,"%s (%d,%d,%d,%u,%d,%d)", - ftpMsg029, - (ip >> 24) & 0xFF, - (ip >> 16) & 0xFF, - (ip >> 8) & 0xFF, - ip & 0xFF, - (port >> 8) & 0xFF, - port & 0xFF); - } + } else { + snprintf(str, 50, "%s (%d,%d,%d,%u,%d,%d)", + ftpMsg029, + (ip >> 24) & 0xFF, + (ip >> 16) & 0xFF, + (ip >> 8) & 0xFF, + ip & 0xFF, + (port >> 8) & 0xFF, + port & 0xFF); + } - if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, ftpGetSession(sessionId)->passiveDataSocket = %d SENDING 227 to client\n", sessionId, ftpGetSession(sessionId)->passiveDataSocket); + if (VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, ftpGetSession(sessionId)->passiveDataSocket = %d SENDING 227 to client\n", sessionId, ftpGetSession(sessionId)->passiveDataSocket); - ftpSendMsg(MSG_NORMAL, sessionId, 227, str); - ftpGetSession(sessionId)->passive = TRUE; + ftpSendMsg(MSG_NORMAL, sessionId, 227, str); + ftpGetSession(sessionId)->passive = TRUE; return 0; } -LOCAL int ftpCmdCdup(int sessionId, const char* args, int len) -{ +LOCAL int ftpCmdCdup(int sessionId, const char* args, int len) { return ftpCmdCwd(sessionId, "..", 2); } -LOCAL int ftpCmdStru(int sessionId, const char* args, int len) -{ - switch(args[0]) - { - case 'F': - case 'f': - ftpSendMsg(MSG_NORMAL, sessionId, 200, ftpMsg030); - break; - default: - ftpSendMsg(MSG_NORMAL, sessionId, 504, ftpMsg031); - break; +LOCAL int ftpCmdStru(int sessionId, const char* args, int len) { + switch (args[0]) { + case 'F': + case 'f': + ftpSendMsg(MSG_NORMAL, sessionId, 200, ftpMsg030); + break; + default: + ftpSendMsg(MSG_NORMAL, sessionId, 504, ftpMsg031); + break; } return 0; } #if RFC3659 -LOCAL int ftpCmdSize(int sessionId, const char* args, int len) -{ - int ret; - char str[12]; - ftpPathInfo_S fileInfo; - const char* realPath = ftpGetRealPath(sessionId, args, TRUE); +LOCAL int ftpCmdSize(int sessionId, const char* args, int len) { + int ret; + char str[12]; + ftpPathInfo_S fileInfo; + const char* realPath = ftpGetRealPath(sessionId, args, TRUE); - ret = ftpStat(realPath, &fileInfo); - if(ret) - { - ftpSendMsg(MSG_NORMAL, sessionId, 550, ftpMsg032); - return 2; - } + ret = ftpStat(realPath, &fileInfo); + if (ret) { + ftpSendMsg(MSG_NORMAL, sessionId, 550, ftpMsg032); + return 2; + } - snprintf(str, 12,"%d", fileInfo.size); - ftpSendMsg(MSG_NORMAL, sessionId, 213, str); + snprintf(str, 12, "%d", fileInfo.size); + ftpSendMsg(MSG_NORMAL, sessionId, 213, str); return 0; } -LOCAL int ftpCmdMdtm(int sessionId, const char* args, int len) -{ - int ret; - char str[15]; - ftpPathInfo_S fileInfo; - const char* realPath = ftpGetRealPath(sessionId, args, TRUE); +LOCAL int ftpCmdMdtm(int sessionId, const char* args, int len) { + int ret; + char str[15]; + ftpPathInfo_S fileInfo; + const char* realPath = ftpGetRealPath(sessionId, args, TRUE); - ret = ftpStat(realPath, &fileInfo); - if(ret) - { - ftpSendMsg(MSG_NORMAL, sessionId, 550, ftpMsg032); - return 2; - } + ret = ftpStat(realPath, &fileInfo); + if (ret) { + ftpSendMsg(MSG_NORMAL, sessionId, 550, ftpMsg032); + return 2; + } - snprintf(str, 15,"%04d%02d%02d%02d%02d%02d", fileInfo.mTime.year, - fileInfo.mTime.month, - fileInfo.mTime.day, - fileInfo.mTime.hour, - fileInfo.mTime.minute, - fileInfo.mTime.second); - ftpSendMsg(MSG_NORMAL, sessionId, 213, str); + snprintf(str, 15, "%04d%02d%02d%02d%02d%02d", fileInfo.mTime.year, + fileInfo.mTime.month, + fileInfo.mTime.day, + fileInfo.mTime.hour, + fileInfo.mTime.minute, + fileInfo.mTime.second); + ftpSendMsg(MSG_NORMAL, sessionId, 213, str); return 0; } -LOCAL int ftpCmdMlst(int sessionId, const char* args, int len) -{ - ftpSendMsg(MSG_NORMAL, sessionId, 550, "MLST command not implemented"); +LOCAL int ftpCmdMlst(int sessionId, const char* args, int len) { + ftpSendMsg(MSG_NORMAL, sessionId, 550, "MLST command not implemented"); return 0; } /*LOCAL int ftpCmdMlsd(int sessionId, const char* args, int len) { - ftpSendMsg(MSG_NORMAL, sessionId, 550, "MLSD command not implemented"); + ftpSendMsg(MSG_NORMAL, sessionId, 550, "MLSD command not implemented"); return 0; }*/ -LOCAL int ftpCmdMlsd(int sessionId, const char* args, int len) -{ +LOCAL int ftpCmdMlsd(int sessionId, const char* args, int len) { const char* realPath; socket_t s; -//#### Funktioniert nicht wenn Pfad übergeben wird -/* if(args[0] != '\0') - { - if(args[0] != '-') - realPath = ftpGetRealPath(sessionId, args); - } - else*/ - realPath = ftpGetRealPath(sessionId, ftpGetSession(sessionId)->workingDir, TRUE); + //#### Funktioniert nicht wenn Pfad übergeben wird + /* if(args[0] != '\0') + { + if(args[0] != '-') + realPath = ftpGetRealPath(sessionId, args); + } + else*/ + realPath = ftpGetRealPath(sessionId, ftpGetSession(sessionId)->workingDir, TRUE); - if(ftpGetSession(sessionId)->passive == FALSE) - { - s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort,sessionId); - if(s < 0) - { - ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg011); - return 1; - } - } - else - { - s = ftpAcceptDataConnection(ftpGetSession(sessionId)->passiveDataSocket); - if(s < 0) - { - ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg012); - return 1; - } - } + if (ftpGetSession(sessionId)->passive == FALSE) { + s = ftpEstablishDataConnection(FALSE, &ftpGetSession(sessionId)->remoteIp, &ftpGetSession(sessionId)->remoteDataPort, sessionId); + if (s < 0) { + ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg011); + return 1; + } + } else { + s = ftpAcceptDataConnection(ftpGetSession(sessionId)->passiveDataSocket); + if (s < 0) { + ftpSendMsg(MSG_NORMAL, sessionId, 425, ftpMsg012); + return 1; + } + } sendListing(s, sessionId, realPath, MLSD); - if(VERBOSE_MODE_ENABLED) printf("In ftpCmdMlsd about to Close socket = %d for sessionId = %d\n",s,sessionId); + if (VERBOSE_MODE_ENABLED) printf("In ftpCmdMlsd about to Close socket = %d for sessionId = %d\n", s, sessionId); ftpUntrackSocket(s); ftpCloseSocket(&s); @@ -904,15 +790,14 @@ LOCAL int ftpCmdMlsd(int sessionId, const char* args, int len) } #endif -typedef struct -{ +typedef struct { char cmdToken[5]; ///< command-string int tokLen; ///< len of cmdToken int neededRights; ///< required access rights for executing the command int needLogin; ///< if TRUE, command needs successful authentication via USER and PASS int reportFeat; ///< if TRUE, command is reported via FEAT int duringTransfer; ///< if TRUE, command can be executed during a file transfer - int (*handler)(int, const char*, int); ///< handler function + int(*handler)(int, const char*, int); ///< handler function }ftpCommand_S; static const ftpCommand_S cmds[] = { @@ -947,123 +832,110 @@ static const ftpCommand_S cmds[] = { #endif }; -int execFtpCmd(int sessionId, const char* cmd, int cmdlen) -{ +int execFtpCmd(int sessionId, const char* cmd, int cmdlen) { int n; - int ret = 0; + int ret = 0; ftpSession_S *pSession = ftpGetSession(sessionId); //if(VERBOSE_MODE_ENABLED) printf("In execFtpCmd ARRAY_SIZE(cmds) = %lu for sessionId = %d\n",ARRAY_SIZE(cmds),sessionId); - if(VERBOSE_MODE_ENABLED) printf("In execFtpCmd cmd [%s] for sessionId = %d\n",cmd,sessionId); + if (VERBOSE_MODE_ENABLED) printf("In execFtpCmd cmd [%s] for sessionId = %d\n", cmd, sessionId); - for(n = 0; n < (int)ARRAY_SIZE(cmds); n++) - { - if(!strncmp(cmds[n].cmdToken, cmd, cmds[n].tokLen)) - { + for (n = 0; n < (int) ARRAY_SIZE(cmds); n++) { + if (!strncmp(cmds[n].cmdToken, cmd, cmds[n].tokLen)) { int i = cmds[n].tokLen; - if(cmds[n].needLogin) - { - if((pSession->userId == 0) || (pSession->authenticated == FALSE)) - { - if(VERBOSE_MODE_ENABLED) printf("In execFtpCmd User NOT loggedin for sessionId = %d\n",sessionId); + if (cmds[n].needLogin) { + if ((pSession->userId == 0) || (pSession->authenticated == FALSE)) { + if (VERBOSE_MODE_ENABLED) printf("In execFtpCmd User NOT loggedin for sessionId = %d\n", sessionId); ftpSendMsg(MSG_NORMAL, sessionId, 530, ftpMsg033); return 0; } - if(ftpCheckAccRights(pSession->userId, cmds[n].neededRights)) - { - if(VERBOSE_MODE_ENABLED) printf("In execFtpCmd User has no ACCESS for sessionId = %d\n",sessionId); + if (ftpCheckAccRights(pSession->userId, cmds[n].neededRights)) { + if (VERBOSE_MODE_ENABLED) printf("In execFtpCmd User has no ACCESS for sessionId = %d\n", sessionId); ftpSendMsg(MSG_NORMAL, sessionId, 550, ftpMsg034); return 0; } } - if((pSession->activeTrans.op != OP_NOP)) // transfer in progress? + if ((pSession->activeTrans.op != OP_NOP)) // transfer in progress? { - if(cmds[n].duringTransfer == FALSE) // command during transfer allowed? + if (cmds[n].duringTransfer == FALSE) // command during transfer allowed? { - if(VERBOSE_MODE_ENABLED) printf("In execFtpCmd got command during transfer, discarding for sessionId = %d\n",sessionId); + if (VERBOSE_MODE_ENABLED) printf("In execFtpCmd got command during transfer, discarding for sessionId = %d\n", sessionId); return 0; // no => silently discard command } } - while(cmd[i] != '\0') - { - if((cmd[i] != ' ') && (cmd[i] != '\t')) + while (cmd[i] != '\0') { + if ((cmd[i] != ' ') && (cmd[i] != '\t')) break; i++; } - if(VERBOSE_MODE_ENABLED) printf("About to execute cmds[n].cmdToken [%s] command [%s] for sessionId = %d\n",cmds[n].cmdToken,&cmd[i],sessionId); + if (VERBOSE_MODE_ENABLED) printf("About to execute cmds[n].cmdToken [%s] command [%s] for sessionId = %d\n", cmds[n].cmdToken, &cmd[i], sessionId); - ret = cmds[n].handler(sessionId, &cmd[i], (int)strlen(&cmd[i])); // execute command + ret = cmds[n].handler(sessionId, &cmd[i], (int) strlen(&cmd[i])); // execute command - if(VERBOSE_MODE_ENABLED) printf("Executed cmds[n].cmdToken [%s] command [%s] ret = %d for sessionId = %d\n",cmds[n].cmdToken,&cmd[i],ret,sessionId); + if (VERBOSE_MODE_ENABLED) printf("Executed cmds[n].cmdToken [%s] command [%s] ret = %d for sessionId = %d\n", cmds[n].cmdToken, &cmd[i], ret, sessionId); - pSession->timeLastCmd = ftpGetUnixTime(); - return ret; - } - else - { + pSession->timeLastCmd = ftpGetUnixTime(); + return ret; + } else { //if(VERBOSE_MODE_ENABLED) printf("In execFtpCmd SKIPPED COMMAND cmds[n].cmdToken = [%s] n = %d for sessionId = %d\n",cmds[n].cmdToken,n,sessionId); } } - if(VERBOSE_MODE_ENABLED) printf("ERROR UNKNOWN COMMAND cmd [%s] for sessionId = %d\n",cmd,sessionId); + if (VERBOSE_MODE_ENABLED) printf("ERROR UNKNOWN COMMAND cmd [%s] for sessionId = %d\n", cmd, sessionId); ftpSendMsg(MSG_NORMAL, sessionId, 500, cmd); // reject unknown commands pSession->timeLastCmd = ftpGetUnixTime(); return ret; } -void ftpParseCmd(int sessionId) -{ +void ftpParseCmd(int sessionId) { ftpSession_S *pSession; int len; socket_t ctrlSocket; - pSession = ftpGetSession(sessionId); - len = pSession->rxBufWriteIdx; + pSession = ftpGetSession(sessionId); + len = pSession->rxBufWriteIdx; ctrlSocket = pSession->ctrlSocket; - if((pSession->rxBuf[len - 1] == '\n') && - (pSession->rxBuf[len - 2] == '\r') ) // command correctly terminated? + if ((pSession->rxBuf[len - 1] == '\n') && + (pSession->rxBuf[len - 2] == '\r')) // command correctly terminated? { int c = 0; pSession->rxBuf[len - 2] = '\0'; - pSession->rxBufWriteIdx = 0; + pSession->rxBufWriteIdx = 0; - for(c = 0; c < len; c++) // convert command token to uppercase + for (c = 0; c < len; c++) // convert command token to uppercase { - if(isspace(pSession->rxBuf[c])) + if (isspace(pSession->rxBuf[c])) break; pSession->rxBuf[c] = toupper(pSession->rxBuf[c]); } - if(VERBOSE_MODE_ENABLED) printf("%02d --> %s for socket: %d\n", sessionId, pSession->rxBuf,ctrlSocket); + if (VERBOSE_MODE_ENABLED) printf("%02d --> %s for socket: %d\n", sessionId, pSession->rxBuf, ctrlSocket); - if(execFtpCmd(sessionId, pSession->rxBuf, len - 2) == -1) - { - if(VERBOSE_MODE_ENABLED) printf("In execFtpCmd command triggered close for socket: %d!\n",ctrlSocket); + if (execFtpCmd(sessionId, pSession->rxBuf, len - 2) == -1) { + if (VERBOSE_MODE_ENABLED) printf("In execFtpCmd command triggered close for socket: %d!\n", ctrlSocket); ftpUntrackSocket(ctrlSocket); ftpCloseSession(sessionId); } - } - else - { - if(VERBOSE_MODE_ENABLED) printf("ERROR In execFtpCmd problem with parsing string [%s] for socket: %d!\n",pSession->rxBuf,ctrlSocket); + } else { + if (VERBOSE_MODE_ENABLED) printf("ERROR In execFtpCmd problem with parsing string [%s] for socket: %d!\n", pSession->rxBuf, ctrlSocket); } - if(pSession->rxBufWriteIdx >= LEN_RXBUF) // overflow of receive buffer? + if (pSession->rxBufWriteIdx >= LEN_RXBUF) // overflow of receive buffer? { pSession->rxBufWriteIdx = 0; ftpSendMsg(MSG_NORMAL, sessionId, 500, ftpMsg035); - if(VERBOSE_MODE_ENABLED) printf("ERROR: Receive buffer overflow. Received data discarded.\n"); + if (VERBOSE_MODE_ENABLED) printf("ERROR: Receive buffer overflow. Received data discarded.\n"); } } diff --git a/source/shared_lib/sources/feathery_ftp/ftpLib.c b/source/shared_lib/sources/feathery_ftp/ftpLib.c index 7b81444c6..d46ef420e 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpLib.c +++ b/source/shared_lib/sources/feathery_ftp/ftpLib.c @@ -27,24 +27,22 @@ #include "ftp.h" #include "ftpIfc.h" -/** - * @brief Removes the trailing slash of a directory path - * - * @param path directory path - * - * @return len of path - */ -int ftpRemoveTrailingSlash(char* path) -{ + /** + * @brief Removes the trailing slash of a directory path + * + * @param path directory path + * + * @return len of path + */ +int ftpRemoveTrailingSlash(char* path) { size_t len = strlen(path); - if(len > 1) - { + if (len > 1) { len--; - if(path[len] == '/') + if (path[len] == '/') path[len] = '\0'; } - return (int)len; + return (int) len; } /** @@ -54,36 +52,33 @@ int ftpRemoveTrailingSlash(char* path) * * @param path directory path */ -void ftpRemoveDoubleSlash(char* path) -{ - char *p; +void ftpRemoveDoubleSlash(char* path) { + char *p; - p = path; + p = path; - while(*p != '\0') - { - if((p[0] == '/') && (p[1] == '/')) - ftpStrcpy(p, &p[1]); - else - p++; - } + while (*p != '\0') { + if ((p[0] == '/') && (p[1] == '/')) + ftpStrcpy(p, &p[1]); + else + p++; + } } /** * @brief Merges multiple path strings * - * The function catenates all passed strings to a new string and assures that + * The function catenates all passed strings to a new string and assures that * the result does not exceed MAX_PATH_LEN. The last parameter has to be * NULL. * Not all embedded environments support variadic functions, or they are - * too expensive. + * too expensive. * * @param dest user name * * @return Pointer to dest */ -char* ftpMergePaths(char* dest, ...) -{ +char* ftpMergePaths(char* dest, ...) { const char* src; char* dst = dest; int len = 0; @@ -91,10 +86,8 @@ char* ftpMergePaths(char* dest, ...) va_start(args, dest); - while((src = va_arg(args, const char*))) - { - while((*src != '\0') && (len < MAX_PATH_LEN-1)) - { + while ((src = va_arg(args, const char*))) { + while ((*src != '\0') && (len < MAX_PATH_LEN - 1)) { *dst++ = *src++; len++; } @@ -109,41 +102,40 @@ char* ftpMergePaths(char* dest, ...) /** * @brief Determine the unix-time * - * The function reads the clock from the target-layer and converts it to the + * The function reads the clock from the target-layer and converts it to the * unix-time. The code is taken from http://de.wikipedia.org/wiki/Unixzeit * - * @return seconds since 1. Januar 1970 00:00 + * @return seconds since 1. Januar 1970 00:00 */ -uint32_t ftpGetUnixTime(void) -{ +uint32_t ftpGetUnixTime(void) { ftpTime_S t; uint32_t unixTime = 0; int j; ftpGetLocalTime(&t); - for(j=1970;j dest. Because ANSI-C explicitly declares that case * as undefined our strcpy guarantees to copy from lower to higher * addresses. - * + * * @param dest destination string * @param src Null-terminated source string * - * @return destination string + * @return destination string */ -char *ftpStrcpy(char *dest, const char *src) -{ - char *d = dest; - const char *s = src; +char *ftpStrcpy(char *dest, const char *src) { + char *d = dest; + const char *s = src; - while ((*d++ = *s++)); - return dest; + while ((*d++ = *s++)); + return dest; } diff --git a/source/shared_lib/sources/feathery_ftp/ftpRuntime.c b/source/shared_lib/sources/feathery_ftp/ftpRuntime.c index f30c3a732..84fe5c05e 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpRuntime.c +++ b/source/shared_lib/sources/feathery_ftp/ftpRuntime.c @@ -31,32 +31,30 @@ #include "ftpMessages.h" -/** - * @brief server-sockets that listens for incoming connections - */ + /** + * @brief server-sockets that listens for incoming connections + */ LOCAL socket_t server; LOCAL int serverListenPort; LOCAL int serverPassiveListenPort; //LOCAL socket_t serverPassivePort; void ftpInit(ftpFindExternalFTPServerIpType cb1, ftpAddUPNPPortForwardType cb2, - ftpRemoveUPNPPortForwardType cb3, ftpIsValidClientType cb4, - ftpIsClientAllowedToGetFileType cb5) { - ftpFindExternalFTPServerIp = cb1; - ftpAddUPNPPortForward = cb2; - ftpRemoveUPNPPortForward = cb3; - ftpIsValidClient = cb4; - ftpIsClientAllowedToGetFile = cb5; + ftpRemoveUPNPPortForwardType cb3, ftpIsValidClientType cb4, + ftpIsClientAllowedToGetFileType cb5) { + ftpFindExternalFTPServerIp = cb1; + ftpAddUPNPPortForward = cb2; + ftpRemoveUPNPPortForward = cb3; + ftpIsValidClient = cb4; + ftpIsClientAllowedToGetFile = cb5; } -int ftpGetListenPort() -{ - return serverListenPort; +int ftpGetListenPort() { + return serverListenPort; } -int ftpGetPassivePort() -{ - return serverPassiveListenPort; +int ftpGetPassivePort() { + return serverPassiveListenPort; } //socket_t ftpGetServerPassivePortListenSocket() @@ -71,29 +69,27 @@ int ftpGetPassivePort() * @return - 0: server started successfully * - -1: could not create server socket */ -int ftpStart(int portNumber) -{ - serverListenPort = portNumber; - serverPassiveListenPort = portNumber + 1; - server = -1; // set server socket to invalid value +int ftpStart(int portNumber) { + serverListenPort = portNumber; + serverPassiveListenPort = portNumber + 1; + server = -1; // set server socket to invalid value //serverPassivePort = -1; -if(VERBOSE_MODE_ENABLED) printf("Feathery FTP-Server\n"); + if (VERBOSE_MODE_ENABLED) printf("Feathery FTP-Server\n"); ftpArchInit(); -if(VERBOSE_MODE_ENABLED) printf("Creating server socket"); + if (VERBOSE_MODE_ENABLED) printf("Creating server socket"); server = ftpCreateServerSocket(serverListenPort); // create main listener socket - if(server < 0) - { -if(VERBOSE_MODE_ENABLED) printf("\t\terror\n"); + if (server < 0) { + if (VERBOSE_MODE_ENABLED) printf("\t\terror\n"); return -1; } -if(VERBOSE_MODE_ENABLED) printf("\t\tok\n"); -if(VERBOSE_MODE_ENABLED) printf("Server successfully started\n"); + if (VERBOSE_MODE_ENABLED) printf("\t\tok\n"); + if (VERBOSE_MODE_ENABLED) printf("Server successfully started\n"); ftpTrackSocket(server); // add socket to "watchlist" @@ -126,8 +122,7 @@ if(VERBOSE_MODE_ENABLED) printf("Server passive port successfully started\n"); * * @return 0 noting to do; else server has received some data */ -int ftpState(void) -{ +int ftpState(void) { return 0; } @@ -139,46 +134,41 @@ int ftpState(void) * all received control-strings are dispatched to the command-module. * Note, the function blocks if there is nothing to do. */ -int ftpExecute(void) -{ - int processedWork=0; - int n=0; - int socksRdy=0; - ftpSession_S *pSession=NULL; - int sessionId=0; +int ftpExecute(void) { + int processedWork = 0; + int n = 0; + int socksRdy = 0; + ftpSession_S *pSession = NULL; + int sessionId = 0; //int activeJobs=0; int len; int bufLen; int activeJobs = ftpGetActiveTransCnt(); // are there any active transmitions? //for(n = 0; (activeJobs > 0) && (n < MAX_CONNECTIONS); n++) - for(n = 0; n < MAX_CONNECTIONS; n++) - { + for (n = 0; n < MAX_CONNECTIONS; n++) { pSession = ftpGetSession(n); - if(pSession->activeTrans.op) // has this session an active transmition? + if (pSession->activeTrans.op) // has this session an active transmition? { - processedWork = 1; + processedWork = 1; ftpExecTransmission(n); // do the job activeJobs--; } } - if(ftpGetActiveTransCnt()) // don't block if there's still something to do + if (ftpGetActiveTransCnt()) // don't block if there's still something to do { socksRdy = ftpSelect(TRUE); - } - else - { + } else { //if(VERBOSE_MODE_ENABLED) printf("ftpExecute calling blocking select\n"); socksRdy = ftpSelect(FALSE); } - if(socksRdy > 0) - { - if(VERBOSE_MODE_ENABLED) printf("ftpExecute socksRdy = %d\n",socksRdy); + if (socksRdy > 0) { + if (VERBOSE_MODE_ENABLED) printf("ftpExecute socksRdy = %d\n", socksRdy); - processedWork = 1; - if(ftpTestSocket(server)) // server listner-socket signaled? + processedWork = 1; + if (ftpTestSocket(server)) // server listner-socket signaled? { socket_t clientSocket; ip_t remoteIP; @@ -186,19 +176,15 @@ int ftpExecute(void) socksRdy--; clientSocket = ftpAcceptServerConnection(server, &remoteIP, &remotePort); - if(clientSocket >= 0) - { - if(VERBOSE_MODE_ENABLED) printf("ftpExecute ftpAcceptServerConnection = %d\n",clientSocket); + if (clientSocket >= 0) { + if (VERBOSE_MODE_ENABLED) printf("ftpExecute ftpAcceptServerConnection = %d\n", clientSocket); sessionId = ftpOpenSession(clientSocket, remoteIP, remotePort); - if(sessionId >= 0) - { + if (sessionId >= 0) { ftpTrackSocket(clientSocket); ftpSendMsg(MSG_NORMAL, sessionId, 220, ftpMsg037); - } - else - { - if(VERBOSE_MODE_ENABLED) printf("ERROR: Connection refused; Session limit reached, about to close socket = %d\n",clientSocket); + } else { + if (VERBOSE_MODE_ENABLED) printf("ERROR: Connection refused; Session limit reached, about to close socket = %d\n", clientSocket); ftpUntrackSocket(clientSocket); ftpCloseSocket(&clientSocket); @@ -207,45 +193,39 @@ int ftpExecute(void) } //socksRdy = ftpSelect(TRUE); - for(n = 0; (socksRdy > 0) && (n < MAX_CONNECTIONS); n++) - { + for (n = 0; (socksRdy > 0) && (n < MAX_CONNECTIONS); n++) { pSession = ftpGetSession(n); - if(pSession->open) - { - socket_t ctrlSocket = pSession->ctrlSocket; + if (pSession->open) { + socket_t ctrlSocket = pSession->ctrlSocket; - if(ftpTestSocket(ctrlSocket)) - { - if(VERBOSE_MODE_ENABLED) printf("ftpExecute signaled socket = %d, session = %d\n",ctrlSocket,n); + if (ftpTestSocket(ctrlSocket)) { + if (VERBOSE_MODE_ENABLED) printf("ftpExecute signaled socket = %d, session = %d\n", ctrlSocket, n); socksRdy--; bufLen = (LEN_RXBUF - pSession->rxBufWriteIdx); len = ftpReceive(ctrlSocket, - &pSession->rxBuf[pSession->rxBufWriteIdx], - bufLen); - if(len <= 0) // has client shutdown the connection? + &pSession->rxBuf[pSession->rxBufWriteIdx], + bufLen); + if (len <= 0) // has client shutdown the connection? { int errorNumber = getLastSocketError(); const char *errText = getLastSocketErrorText(&errorNumber); - if(VERBOSE_MODE_ENABLED) printf("In ftpExecute ERROR ON RECEIVE session = %d for socket = %d, data len = %d index = %d, len = %d, error = %d [%s]\n",n,ctrlSocket,bufLen,pSession->rxBufWriteIdx,len,errorNumber,errText); + if (VERBOSE_MODE_ENABLED) printf("In ftpExecute ERROR ON RECEIVE session = %d for socket = %d, data len = %d index = %d, len = %d, error = %d [%s]\n", n, ctrlSocket, bufLen, pSession->rxBufWriteIdx, len, errorNumber, errText); ftpUntrackSocket(ctrlSocket); ftpCloseSession(n); - } - else - { + } else { pSession->rxBufWriteIdx += len; ftpParseCmd(n); } } /// @bug Session-Timeout-Management doesn't work - if((ftpGetUnixTime() - pSession->timeLastCmd) > SESSION_TIMEOUT) - { - if(VERBOSE_MODE_ENABLED) printf("\nIn ftpExecute ERROR: SESSION TIMED OUT for socket = %d\n",ctrlSocket); + if ((ftpGetUnixTime() - pSession->timeLastCmd) > SESSION_TIMEOUT) { + if (VERBOSE_MODE_ENABLED) printf("\nIn ftpExecute ERROR: SESSION TIMED OUT for socket = %d\n", ctrlSocket); - ftpSendMsg(MSG_NORMAL, n, 421, ftpMsg036); + ftpSendMsg(MSG_NORMAL, n, 421, ftpMsg036); ftpUntrackSocket(ctrlSocket); ftpCloseSession(n); - } + } } } } @@ -261,27 +241,24 @@ int ftpExecute(void) * @return 0 */ -int ftpShutdown(void) -{ +int ftpShutdown(void) { int n; - if(VERBOSE_MODE_ENABLED) printf("About to Shutdown Feathery FTP-Server server [%d]\n",server); - + if (VERBOSE_MODE_ENABLED) printf("About to Shutdown Feathery FTP-Server server [%d]\n", server); + ftpUntrackSocket(server); ftpCloseSocket(&server); //ftpCloseSocket(serverPassivePort); - if(VERBOSE_MODE_ENABLED) printf("About to Shutdown clients\n"); + if (VERBOSE_MODE_ENABLED) printf("About to Shutdown clients\n"); - for(n = 0; n < MAX_CONNECTIONS; n++) - { - if(ftpGetSession(n)->open) - { + for (n = 0; n < MAX_CONNECTIONS; n++) { + if (ftpGetSession(n)->open) { ftpUntrackSocket(ftpGetSession(n)->ctrlSocket); } ftpCloseSession(n); } - if(VERBOSE_MODE_ENABLED) printf("About to Shutdown stack\n"); + if (VERBOSE_MODE_ENABLED) printf("About to Shutdown stack\n"); ftpArchCleanup(); return 0; diff --git a/source/shared_lib/sources/feathery_ftp/ftpServer.c b/source/shared_lib/sources/feathery_ftp/ftpServer.c index 2d8caebdd..d81867b7a 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpServer.c +++ b/source/shared_lib/sources/feathery_ftp/ftpServer.c @@ -19,17 +19,16 @@ #if 0 #include "ftpIfc.h" -int main(void) -{ +int main(void) { ftpCreateAccount("anonymous", "", "./", FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); ftpCreateAccount("nothing", "", "./", 0); ftpCreateAccount("reader", "", "./", FTP_ACC_RD); ftpCreateAccount("writer", "", "./", FTP_ACC_WR); ftpCreateAccount("lister", "", "./", FTP_ACC_LS); - ftpCreateAccount("admin", "xxx", "./", FTP_ACC_RD | FTP_ACC_WR | FTP_ACC_LS | FTP_ACC_DIR); + ftpCreateAccount("admin", "xxx", "./", FTP_ACC_RD | FTP_ACC_WR | FTP_ACC_LS | FTP_ACC_DIR); ftpStart(); - while(1) + while (1) ftpExecute(); ftpShutdown(); diff --git a/source/shared_lib/sources/feathery_ftp/ftpSession.c b/source/shared_lib/sources/feathery_ftp/ftpSession.c index 31509ecc0..f8a0c29ab 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpSession.c +++ b/source/shared_lib/sources/feathery_ftp/ftpSession.c @@ -32,11 +32,11 @@ #include "ftpConfig.h" #include "ftp.h" -/** - * @brief array that holds the data of all ftp sessions - * - * The index represents the session ID. - */ + /** + * @brief array that holds the data of all ftp sessions + * + * The index represents the session ID. + */ LOCAL ftpSession_S sessions[MAX_CONNECTIONS]; /** @@ -62,32 +62,29 @@ LOCAL char pathScratchBuf[MAX_PATH_LEN]; * * @return session id or -1 if session limit is reached */ -int ftpOpenSession(socket_t ctrlSocket, ip_t remoteIp, port_t remotePort) -{ +int ftpOpenSession(socket_t ctrlSocket, ip_t remoteIp, port_t remotePort) { int n; - for(n = 0; n < MAX_CONNECTIONS; n++) - { - if(!sessions[n].open) - { - sessions[n].open = TRUE; - sessions[n].authenticated = FALSE; - sessions[n].userId = 0; - sessions[n].workingDir[0] = '\0'; - sessions[n].remoteIp = remoteIp; - sessions[n].remotePort = remotePort; - sessions[n].remoteDataPort = 0; - sessions[n].passive = FALSE; - sessions[n].binary = TRUE; - sessions[n].timeLastCmd = ftpGetUnixTime(); - sessions[n].ctrlSocket = ctrlSocket; - sessions[n].passiveDataSocket = -1; - sessions[n].rxBufWriteIdx = 0; - sessions[n].activeTrans.op = OP_NOP; + for (n = 0; n < MAX_CONNECTIONS; n++) { + if (!sessions[n].open) { + sessions[n].open = TRUE; + sessions[n].authenticated = FALSE; + sessions[n].userId = 0; + sessions[n].workingDir[0] = '\0'; + sessions[n].remoteIp = remoteIp; + sessions[n].remotePort = remotePort; + sessions[n].remoteDataPort = 0; + sessions[n].passive = FALSE; + sessions[n].binary = TRUE; + sessions[n].timeLastCmd = ftpGetUnixTime(); + sessions[n].ctrlSocket = ctrlSocket; + sessions[n].passiveDataSocket = -1; + sessions[n].rxBufWriteIdx = 0; + sessions[n].activeTrans.op = OP_NOP; sessions[n].activeTrans.fsHandle = NULL; sessions[n].activeTrans.dataSocket = -1; sessions[n].activeTrans.fileSize = 0; - if(VERBOSE_MODE_ENABLED) printf("ftpOpenSession started for ctrlSocket: %d\n",ctrlSocket); + if (VERBOSE_MODE_ENABLED) printf("ftpOpenSession started for ctrlSocket: %d\n", ctrlSocket); return n; } @@ -102,8 +99,7 @@ int ftpOpenSession(socket_t ctrlSocket, ip_t remoteIp, port_t remotePort) * * @return 0 */ -int ftpAuthSession(int id) -{ +int ftpAuthSession(int id) { sessions[id].authenticated = TRUE; strcpy(sessions[id].workingDir, "/"); @@ -119,41 +115,39 @@ int ftpAuthSession(int id) * * @return 0 */ -int ftpCloseSession(int id) -{ - if(VERBOSE_MODE_ENABLED) printf("In ftpCloseSession sessionId = %d, remote IP = %u, port = %d, ctrlSocket = %d\n", - id, sessions[id].remoteIp, sessions[id].remoteFTPServerPassivePort,sessions[id].ctrlSocket); +int ftpCloseSession(int id) { + if (VERBOSE_MODE_ENABLED) printf("In ftpCloseSession sessionId = %d, remote IP = %u, port = %d, ctrlSocket = %d\n", + id, sessions[id].remoteIp, sessions[id].remoteFTPServerPassivePort, sessions[id].ctrlSocket); - if(ftpFindExternalFTPServerIp != NULL && ftpFindExternalFTPServerIp(sessions[id].remoteIp) != 0) - { - //if(ftpRemoveUPNPPortForward) - //{ - //if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, removing UPNP port forward [%d]\n", id,sessions[id].remoteFTPServerPassivePort); + if (ftpFindExternalFTPServerIp != NULL && ftpFindExternalFTPServerIp(sessions[id].remoteIp) != 0) { + //if(ftpRemoveUPNPPortForward) + //{ + //if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, removing UPNP port forward [%d]\n", id,sessions[id].remoteFTPServerPassivePort); - //ftpRemoveUPNPPortForward(sessions[id].remoteFTPServerPassivePort, sessions[id].remoteFTPServerPassivePort); - sessions[id].remoteFTPServerPassivePort = 0; - //} - } - //if(sessions[id].open) { - if(VERBOSE_MODE_ENABLED) printf("In ftpCloseSession about to Close socket = %d, dataSocket = %d, activeDataSocket = %d, for sessionId = %d\n",sessions[id].ctrlSocket,sessions[id].passiveDataSocket,sessions[id].activeTrans.dataSocket,id); + //ftpRemoveUPNPPortForward(sessions[id].remoteFTPServerPassivePort, sessions[id].remoteFTPServerPassivePort); + sessions[id].remoteFTPServerPassivePort = 0; + //} + } + //if(sessions[id].open) { + if (VERBOSE_MODE_ENABLED) printf("In ftpCloseSession about to Close socket = %d, dataSocket = %d, activeDataSocket = %d, for sessionId = %d\n", sessions[id].ctrlSocket, sessions[id].passiveDataSocket, sessions[id].activeTrans.dataSocket, id); ftpUntrackSocket(sessions[id].ctrlSocket); ftpCloseSocket(&sessions[id].ctrlSocket); ftpCloseTransmission(id); ftpUntrackSocket(sessions[id].passiveDataSocket); ftpCloseSocket(&sessions[id].passiveDataSocket); - //} - sessions[id].remoteIp = 0; - sessions[id].ctrlSocket = 0; - sessions[id].passiveDataSocket = 0; - sessions[id].passiveIp = 0; - sessions[id].passivePort = 0; - sessions[id].activeTrans.dataSocket = 0; - sessions[id].activeTrans.op = OP_NOP; - sessions[id].activeTrans.fileSize = 0; - sessions[id].open = FALSE; + //} + sessions[id].remoteIp = 0; + sessions[id].ctrlSocket = 0; + sessions[id].passiveDataSocket = 0; + sessions[id].passiveIp = 0; + sessions[id].passivePort = 0; + sessions[id].activeTrans.dataSocket = 0; + sessions[id].activeTrans.op = OP_NOP; + sessions[id].activeTrans.fileSize = 0; + sessions[id].open = FALSE; -if(VERBOSE_MODE_ENABLED) printf("Session %d closed\n", id); + if (VERBOSE_MODE_ENABLED) printf("Session %d closed\n", id); return 0; } @@ -165,8 +159,7 @@ if(VERBOSE_MODE_ENABLED) printf("Session %d closed\n", id); * * @return pointer to session data */ -ftpSession_S* ftpGetSession(int id) -{ +ftpSession_S* ftpGetSession(int id) { return &sessions[id]; } @@ -180,58 +173,49 @@ ftpSession_S* ftpGetSession(int id) * * @return 0 */ -LOCAL int normalizePath(char* path) -{ - char *in; - char *r = path; +LOCAL int normalizePath(char* path) { + char *in; + char *r = path; - in = path; + in = path; - while((in = strchr(in, '/'))) - { - if(!strncmp(in, "/./", 3)) - { - ftpStrcpy(in, &in[2]); - continue; - } - if(!strcmp(in, "/.")) - { - in[1] = '\0'; - continue; - } - if(!strncmp(in, "/../", 4)) - { - *in = '\0'; - r = strrchr(path, '/'); - if(r == NULL) - r = path; - ftpStrcpy(r, &in[3]); - in = r; - continue; - } - if(!strcmp(in, "/..")) - { - *in = '\0'; - r = strrchr(path, '/'); - if(r) - { - if(r == path) - r[1] = '\0'; - else - *r = '\0'; - } - else - { - in[0] = '/'; - in[1] = '\0'; - } + while ((in = strchr(in, '/'))) { + if (!strncmp(in, "/./", 3)) { + ftpStrcpy(in, &in[2]); + continue; + } + if (!strcmp(in, "/.")) { + in[1] = '\0'; + continue; + } + if (!strncmp(in, "/../", 4)) { + *in = '\0'; + r = strrchr(path, '/'); + if (r == NULL) + r = path; + ftpStrcpy(r, &in[3]); + in = r; + continue; + } + if (!strcmp(in, "/..")) { + *in = '\0'; + r = strrchr(path, '/'); + if (r) { + if (r == path) + r[1] = '\0'; + else + *r = '\0'; + } else { + in[0] = '/'; + in[1] = '\0'; + } - continue; - } - in++; - } + continue; + } + in++; + } - return 0; + return 0; } @@ -251,41 +235,38 @@ LOCAL int normalizePath(char* path) * * @return translated absolute server path */ -const char* ftpGetRealPath(int id, const char* path, int normalize) -{ - char ftpRoot[2048]=""; +const char* ftpGetRealPath(int id, const char* path, int normalize) { + char ftpRoot[2048] = ""; int ftpRootLen; int len; const char *ftp_rootget = ftpGetRoot(sessions[id].userId, &len); - snprintf(ftpRoot,2047,"%s",ftp_rootget); - ftpRootLen = (int)strlen(ftpRoot); - if(ftpRootLen > 0 && ftpRoot[ftpRootLen-1] != '/') { - strcat(ftpRoot,"/"); + snprintf(ftpRoot, 2047, "%s", ftp_rootget); + ftpRootLen = (int) strlen(ftpRoot); + if (ftpRootLen > 0 && ftpRoot[ftpRootLen - 1] != '/') { + strcat(ftpRoot, "/"); } - if(VERBOSE_MODE_ENABLED) printf("#1 ftpGetRealPath id = %d path [%s] ftpRoot [%s] sessions[id].workingDir [%s] normalize = %d\n", id, path, ftpRoot, sessions[id].workingDir,normalize); + if (VERBOSE_MODE_ENABLED) printf("#1 ftpGetRealPath id = %d path [%s] ftpRoot [%s] sessions[id].workingDir [%s] normalize = %d\n", id, path, ftpRoot, sessions[id].workingDir, normalize); - pathScratchBuf[0]='\0'; - if(path[0] == '/' || strcmp(path,sessions[id].workingDir) == 0) // absolute path? - { - ftpMergePaths(pathScratchBuf, ftpRoot, path, NULL); - } - else + pathScratchBuf[0] = '\0'; + if (path[0] == '/' || strcmp(path, sessions[id].workingDir) == 0) // absolute path? { + ftpMergePaths(pathScratchBuf, ftpRoot, path, NULL); + } else { ftpMergePaths(pathScratchBuf, ftpRoot, sessions[id].workingDir, "/", path, NULL); //ftpMergePaths(pathScratchBuf, ftpRoot, path, NULL); } -if(VERBOSE_MODE_ENABLED) printf("#2 ftpGetRealPath path [%s] ftpRoot [%s] pathScratchBuf [%s]\n", path, ftpRoot, pathScratchBuf); + if (VERBOSE_MODE_ENABLED) printf("#2 ftpGetRealPath path [%s] ftpRoot [%s] pathScratchBuf [%s]\n", path, ftpRoot, pathScratchBuf); ftpRemoveDoubleSlash(pathScratchBuf); - if(normalize) { + if (normalize) { normalizePath(pathScratchBuf); } ftpRemoveTrailingSlash(pathScratchBuf); -if(VERBOSE_MODE_ENABLED) printf("#2 ftpGetRealPath path [%s] ftpRoot [%s] pathScratchBuf [%s]\n", path, ftpRoot, pathScratchBuf); + if (VERBOSE_MODE_ENABLED) printf("#2 ftpGetRealPath path [%s] ftpRoot [%s] pathScratchBuf [%s]\n", path, ftpRoot, pathScratchBuf); return pathScratchBuf; } @@ -298,27 +279,26 @@ if(VERBOSE_MODE_ENABLED) printf("#2 ftpGetRealPath path [%s] ftpRoot [%s] pathSc * * @return 0 on success; -2 if the directory doesn't exist */ -int ftpChangeDir(int id, const char* path) -{ +int ftpChangeDir(int id, const char* path) { ftpPathInfo_S fileInfo; const char* realPath = ftpGetRealPath(id, path, TRUE); int len; ftpGetRoot(sessions[id].userId, &len); // determine len of root-path - if(len == 1) // if len == 1 root-path == '/' + if (len == 1) // if len == 1 root-path == '/' len = 0; -if(VERBOSE_MODE_ENABLED) printf("ftpChangeDir path [%s] realPath [%s] sessions[id].workingDir [%s]\n", path, realPath, sessions[id].workingDir); + if (VERBOSE_MODE_ENABLED) printf("ftpChangeDir path [%s] realPath [%s] sessions[id].workingDir [%s]\n", path, realPath, sessions[id].workingDir); - if(ftpStat(realPath, &fileInfo) || (fileInfo.type != TYPE_DIR)) // directory accessible? + if (ftpStat(realPath, &fileInfo) || (fileInfo.type != TYPE_DIR)) // directory accessible? return -2; - strncpy(sessions[id].workingDir, &realPath[len], MAX_PATH_LEN-1); // apply path - if(sessions[id].workingDir[0] == '\0') + strncpy(sessions[id].workingDir, &realPath[len], MAX_PATH_LEN - 1); // apply path + if (sessions[id].workingDir[0] == '\0') strcpy(sessions[id].workingDir, "/"); -if(VERBOSE_MODE_ENABLED) printf("ftpChangeDir path [%s] realPath [%s] NEW sessions[id].workingDir [%s]\n", path, realPath, sessions[id].workingDir); + if (VERBOSE_MODE_ENABLED) printf("ftpChangeDir path [%s] realPath [%s] NEW sessions[id].workingDir [%s]\n", path, realPath, sessions[id].workingDir); return 0; } @@ -326,37 +306,31 @@ if(VERBOSE_MODE_ENABLED) printf("ftpChangeDir path [%s] realPath [%s] NEW sessio /** * Open an ftp transmission */ -void ftpOpenTransmission(int id, operation_E op, void* fsHandle, socket_t dataSocket, uint32_t fileSize) -{ +void ftpOpenTransmission(int id, operation_E op, void* fsHandle, socket_t dataSocket, uint32_t fileSize) { actTransCnt++; - sessions[id].activeTrans.op = op; - sessions[id].activeTrans.fsHandle = fsHandle; + sessions[id].activeTrans.op = op; + sessions[id].activeTrans.fsHandle = fsHandle; sessions[id].activeTrans.dataSocket = dataSocket; - sessions[id].activeTrans.fileSize = fileSize; + sessions[id].activeTrans.fileSize = fileSize; } /** * Close an ftp transmission */ -void ftpCloseTransmission(int id) -{ - if(VERBOSE_MODE_ENABLED) printf("In ftpCloseTransmission about to Close socket = %d, for sessionId = %d, fsHandle [%p] op = %d\n", - sessions[id].activeTrans.dataSocket, id,sessions[id].activeTrans.fsHandle,sessions[id].activeTrans.op); +void ftpCloseTransmission(int id) { + if (VERBOSE_MODE_ENABLED) printf("In ftpCloseTransmission about to Close socket = %d, for sessionId = %d, fsHandle [%p] op = %d\n", + sessions[id].activeTrans.dataSocket, id, sessions[id].activeTrans.fsHandle, sessions[id].activeTrans.op); - if(sessions[id].activeTrans.dataSocket > 0) - { + if (sessions[id].activeTrans.dataSocket > 0) { ftpUntrackSocket(sessions[id].activeTrans.dataSocket); ftpCloseSocket(&sessions[id].activeTrans.dataSocket); } - if(sessions[id].activeTrans.op != OP_NOP) // is thera an active transmission? + if (sessions[id].activeTrans.op != OP_NOP) // is thera an active transmission? { - if(sessions[id].activeTrans.op == OP_LIST) - { + if (sessions[id].activeTrans.op == OP_LIST) { ftpCloseDir(sessions[id].activeTrans.fsHandle); - } - else - { + } else { ftpCloseFile(sessions[id].activeTrans.fsHandle); } sessions[id].activeTrans.fsHandle = NULL; @@ -369,7 +343,6 @@ void ftpCloseTransmission(int id) /** * Get the active transaction count */ -int ftpGetActiveTransCnt(void) -{ +int ftpGetActiveTransCnt(void) { return actTransCnt; } diff --git a/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c b/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c index f2964a4bc..53f990ec1 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c +++ b/source/shared_lib/sources/feathery_ftp/ftpTargetPosix.c @@ -34,9 +34,9 @@ #include #if defined(__FreeBSD__) - #include +#include #else - //#include + //#include #endif #include @@ -57,33 +57,29 @@ LOCAL fd_set signaledSockets; LOCAL int maxSockNr; -void ftpArchInit() -{ +void ftpArchInit() { ownIp = 0; maxSockNr = 0; FD_ZERO(&watchedSockets); FD_ZERO(&signaledSockets); } -void ftpArchCleanup(void) -{ +void ftpArchCleanup(void) { } -int ftpGetLocalTime(ftpTime_S *t) -{ +int ftpGetLocalTime(ftpTime_S *t) { struct tm *pTime; time_t tim; time(&tim); pTime = localtime(&tim); - if(pTime) - { - t->year = (uint16_t)pTime->tm_year + 1900; - t->month = (uint8_t)pTime->tm_mon + 1; - t->day = (uint8_t)pTime->tm_mday; - t->hour = (uint8_t)pTime->tm_hour; - t->minute = (uint8_t)pTime->tm_min; - t->second = (uint8_t)pTime->tm_sec; + if (pTime) { + t->year = (uint16_t) pTime->tm_year + 1900; + t->month = (uint8_t) pTime->tm_mon + 1; + t->day = (uint8_t) pTime->tm_mday; + t->hour = (uint8_t) pTime->tm_hour; + t->minute = (uint8_t) pTime->tm_min; + t->second = (uint8_t) pTime->tm_sec; return 0; } @@ -91,88 +87,80 @@ int ftpGetLocalTime(ftpTime_S *t) return -1; } -void* ftpOpenDir(const char* path) -{ +void* ftpOpenDir(const char* path) { return opendir(path); } -const char* ftpReadDir(void* dirHandle) -{ +const char* ftpReadDir(void* dirHandle) { struct dirent* dirEntry; dirEntry = readdir(dirHandle); - if(dirEntry) + if (dirEntry) return dirEntry->d_name; else return NULL; } -int ftpCloseDir(void* dirHandle) -{ +int ftpCloseDir(void* dirHandle) { return closedir(dirHandle); } -int ftpStat(const char* path, ftpPathInfo_S *info) -{ - struct stat fileInfo = {0}; +int ftpStat(const char* path, ftpPathInfo_S *info) { + struct stat fileInfo = { 0 }; struct tm *pTime; struct passwd *pw; struct group *gr; - if(!stat(path, &fileInfo)) - { - if(S_ISREG(fileInfo.st_mode)) + if (!stat(path, &fileInfo)) { + if (S_ISREG(fileInfo.st_mode)) info->type = TYPE_FILE; - else if(S_ISDIR(fileInfo.st_mode)) + else if (S_ISDIR(fileInfo.st_mode)) info->type = TYPE_DIR; else info->type = TYPE_LINK; pTime = localtime(&fileInfo.st_mtime); - if(pTime) - { - info->mTime.year = (uint16_t)pTime->tm_year + 1900; - info->mTime.month = (uint8_t)pTime->tm_mon + 1; - info->mTime.day = (uint8_t)pTime->tm_mday; - info->mTime.hour = (uint8_t)pTime->tm_hour; - info->mTime.minute = (uint8_t)pTime->tm_min; - info->mTime.second = (uint8_t)pTime->tm_sec; + if (pTime) { + info->mTime.year = (uint16_t) pTime->tm_year + 1900; + info->mTime.month = (uint8_t) pTime->tm_mon + 1; + info->mTime.day = (uint8_t) pTime->tm_mday; + info->mTime.hour = (uint8_t) pTime->tm_hour; + info->mTime.minute = (uint8_t) pTime->tm_min; + info->mTime.second = (uint8_t) pTime->tm_sec; } pTime = localtime(&fileInfo.st_ctime); - if(pTime) - { - info->cTime.year = (uint16_t)pTime->tm_year + 1900; - info->cTime.month = (uint8_t)pTime->tm_mon + 1; - info->cTime.day = (uint8_t)pTime->tm_mday; - info->cTime.hour = (uint8_t)pTime->tm_hour; - info->cTime.minute = (uint8_t)pTime->tm_min; - info->cTime.second = (uint8_t)pTime->tm_sec; + if (pTime) { + info->cTime.year = (uint16_t) pTime->tm_year + 1900; + info->cTime.month = (uint8_t) pTime->tm_mon + 1; + info->cTime.day = (uint8_t) pTime->tm_mday; + info->cTime.hour = (uint8_t) pTime->tm_hour; + info->cTime.minute = (uint8_t) pTime->tm_min; + info->cTime.second = (uint8_t) pTime->tm_sec; } pTime = localtime(&fileInfo.st_atime); - if(pTime) - { - info->aTime.year = (uint16_t)pTime->tm_year + 1900; - info->aTime.month = (uint8_t)pTime->tm_mon + 1; - info->aTime.day = (uint8_t)pTime->tm_mday; - info->aTime.hour = (uint8_t)pTime->tm_hour; - info->aTime.minute = (uint8_t)pTime->tm_min; - info->aTime.second = (uint8_t)pTime->tm_sec; + if (pTime) { + info->aTime.year = (uint16_t) pTime->tm_year + 1900; + info->aTime.month = (uint8_t) pTime->tm_mon + 1; + info->aTime.day = (uint8_t) pTime->tm_mday; + info->aTime.hour = (uint8_t) pTime->tm_hour; + info->aTime.minute = (uint8_t) pTime->tm_min; + info->aTime.second = (uint8_t) pTime->tm_sec; } - info->size = (uint32_t)fileInfo.st_size; - info->links = (int)fileInfo.st_nlink; + info->size = (uint32_t) fileInfo.st_size; + info->links = (int) fileInfo.st_nlink; pw = getpwuid(fileInfo.st_uid); - if(pw) - strncpy(info->user, pw->pw_name, sizeof(info->user)-1); + if (pw) + strncpy(info->user, pw->pw_name, sizeof(info->user) - 1); else - snprintf(info->user, 20,"%04d", fileInfo.st_uid); + snprintf(info->user, 20, "%04d", fileInfo.st_uid); gr = getgrgid(fileInfo.st_gid); - if(gr) - strncpy(info->group, gr->gr_name, sizeof(info->group)-1); + if (gr) + strncpy(info->group, gr->gr_name, sizeof(info->group) - 1); else - snprintf(info->group, 20,"%04d", fileInfo.st_gid); + snprintf(info->group, 20, "%04d", fileInfo.st_gid); return 0; } @@ -180,125 +168,108 @@ int ftpStat(const char* path, ftpPathInfo_S *info) return -1; } -int ftpMakeDir(const char* path) -{ +int ftpMakeDir(const char* path) { return mkdir(path, S_IRUSR | S_IWUSR); } -int ftpRemoveDir(const char* path) -{ +int ftpRemoveDir(const char* path) { return rmdir(path); } -int ftpCloseSocket(socket_t *s) -{ - if(VERBOSE_MODE_ENABLED) printf("\nClosing socket: %d\n",*s); +int ftpCloseSocket(socket_t *s) { + if (VERBOSE_MODE_ENABLED) printf("\nClosing socket: %d\n", *s); - int ret = 0; - if(*s > 0) { - shutdown(*s,2); - ret = close(*s); - *s = 0; - } + int ret = 0; + if (*s > 0) { + shutdown(*s, 2); + ret = close(*s); + *s = 0; + } return ret; } -int ftpSend(socket_t s, const void *data, int len) -{ +int ftpSend(socket_t s, const void *data, int len) { int currLen = 0; - do - { + do { #if defined(__APPLE__) && defined(SO_NOSIGPIPE) currLen = send(s, data, len, SO_NOSIGPIPE); #elif defined(MSG_NOSIGNAL) - currLen = send(s, data, len, MSG_NOSIGNAL); + currLen = send(s, data, len, MSG_NOSIGNAL); #else - currLen = send(s, data, len, 0); + currLen = send(s, data, len, 0); #endif - if(currLen >= 0) - { - if(currLen == 0) - { + if (currLen >= 0) { + if (currLen == 0) { int errorNumber = getLastSocketError(); const char *errText = getLastSocketErrorText(&errorNumber); - if(VERBOSE_MODE_ENABLED) printf("\nERROR #1 ftpExecute ERROR ON SEND for socket = %d, data len = %d, error = %d [%s]\n",s,len,errorNumber,errText); + if (VERBOSE_MODE_ENABLED) printf("\nERROR #1 ftpExecute ERROR ON SEND for socket = %d, data len = %d, error = %d [%s]\n", s, len, errorNumber, errText); } len -= currLen; - data = (uint8_t*)data + currLen; - } - else - { + data = (uint8_t*) data + currLen; + } else { int errorNumber = getLastSocketError(); const char *errText = getLastSocketErrorText(&errorNumber); - if(VERBOSE_MODE_ENABLED) printf("\nERROR #2 ftpExecute ERROR ON SEND for socket = %d, data len = %d, currLen = %d, error = %d [%s]\n",s,len,currLen,errorNumber,errText); + if (VERBOSE_MODE_ENABLED) printf("\nERROR #2 ftpExecute ERROR ON SEND for socket = %d, data len = %d, currLen = %d, error = %d [%s]\n", s, len, currLen, errorNumber, errText); return -1; } - } while(len > 0); + } while (len > 0); return 0; } -int ftpReceive(socket_t s, void *data, int len) -{ +int ftpReceive(socket_t s, void *data, int len) { return recv(s, data, len, 0); } -socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int sessionId) -{ +socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int sessionId) { socket_t dataSocket; struct sockaddr_in clientAddr; struct sockaddr_in myAddr; int on = 1; unsigned len; dataSocket = socket(AF_INET, SOCK_STREAM, 0); - if(dataSocket < 0) + if (dataSocket < 0) return -1; - if(!passive) - { - if(setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) - { - if(VERBOSE_MODE_ENABLED) printf("In ftpEstablishDataConnection #1 about to Close socket = %d, for sessionId = %d\n",dataSocket, sessionId); + if (!passive) { + if (setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) { + if (VERBOSE_MODE_ENABLED) printf("In ftpEstablishDataConnection #1 about to Close socket = %d, for sessionId = %d\n", dataSocket, sessionId); ftpUntrackSocket(dataSocket); ftpCloseSocket(&dataSocket); return -1; } - myAddr.sin_family = AF_INET; + myAddr.sin_family = AF_INET; myAddr.sin_addr.s_addr = INADDR_ANY; - myAddr.sin_port = htons(20); - myAddr.sin_zero[0] = 0; - if(bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr))) - { - if(VERBOSE_MODE_ENABLED) printf("In ftpEstablishDataConnection #2 about to Close socket = %d, for sessionId = %d\n",dataSocket, sessionId); + myAddr.sin_port = htons(20); + myAddr.sin_zero[0] = 0; + if (bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr))) { + if (VERBOSE_MODE_ENABLED) printf("In ftpEstablishDataConnection #2 about to Close socket = %d, for sessionId = %d\n", dataSocket, sessionId); ftpUntrackSocket(dataSocket); ftpCloseSocket(&dataSocket); return -1; } - clientAddr.sin_family = AF_INET; + clientAddr.sin_family = AF_INET; clientAddr.sin_addr.s_addr = htonl(*ip); - clientAddr.sin_port = htons(*port); - clientAddr.sin_zero[0] = 0; + clientAddr.sin_port = htons(*port); + clientAddr.sin_zero[0] = 0; - if(connect(dataSocket, (struct sockaddr *)&clientAddr, sizeof(clientAddr))) - { - if(VERBOSE_MODE_ENABLED) printf("In ftpEstablishDataConnection #3 about to Close socket = %d, for sessionId = %d\n",dataSocket, sessionId); + if (connect(dataSocket, (struct sockaddr *)&clientAddr, sizeof(clientAddr))) { + if (VERBOSE_MODE_ENABLED) printf("In ftpEstablishDataConnection #3 about to Close socket = %d, for sessionId = %d\n", dataSocket, sessionId); ftpUntrackSocket(dataSocket); ftpCloseSocket(&dataSocket); return -1; } - } - else - { - int passivePort = ftpGetPassivePort() + sessionId; - if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d for socket = %d\n",sessionId,passivePort,dataSocket); + } else { + int passivePort = ftpGetPassivePort() + sessionId; + if (VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d for socket = %d\n", sessionId, passivePort, dataSocket); myAddr.sin_family = AF_INET; myAddr.sin_addr.s_addr = INADDR_ANY; @@ -306,96 +277,87 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int ses myAddr.sin_zero[0] = 0; //myAddr.sin_port = htons(ftpGetPassivePort() + sessionId); - if(setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) - { - if(VERBOSE_MODE_ENABLED) printf("PASSIVE CONNECTION In ftpEstablishDataConnection setsockopt failed about to Close socket = %d, for sessionId = %d\n",dataSocket, sessionId); + if (setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) { + if (VERBOSE_MODE_ENABLED) printf("PASSIVE CONNECTION In ftpEstablishDataConnection setsockopt failed about to Close socket = %d, for sessionId = %d\n", dataSocket, sessionId); ftpUntrackSocket(dataSocket); ftpCloseSocket(&dataSocket); return -1; } - if(bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr))) - { - if(VERBOSE_MODE_ENABLED) printf("\nERROR In ftpEstablishDataConnection passive bind failed for sessionId = %d using port #: %d about to close socket = %d\n",sessionId,passivePort,dataSocket); + if (bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr))) { + if (VERBOSE_MODE_ENABLED) printf("\nERROR In ftpEstablishDataConnection passive bind failed for sessionId = %d using port #: %d about to close socket = %d\n", sessionId, passivePort, dataSocket); ftpUntrackSocket(dataSocket); ftpCloseSocket(&dataSocket); return -1; - } + } - if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d bound ok for socket = %d\n",sessionId,passivePort,dataSocket); + if (VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d bound ok for socket = %d\n", sessionId, passivePort, dataSocket); - len = sizeof(myAddr); - if(getsockname(dataSocket, (struct sockaddr *)&myAddr, &len)) // Port des Server-Sockets ermitteln - { - if(VERBOSE_MODE_ENABLED) printf("\nERROR In ftpEstablishDataConnection passive getsockname failed for sessionId = %d using port #: %d about to close socket = %d\n",sessionId,passivePort,dataSocket); + len = sizeof(myAddr); + if (getsockname(dataSocket, (struct sockaddr *)&myAddr, &len)) // Port des Server-Sockets ermitteln + { + if (VERBOSE_MODE_ENABLED) printf("\nERROR In ftpEstablishDataConnection passive getsockname failed for sessionId = %d using port #: %d about to close socket = %d\n", sessionId, passivePort, dataSocket); ftpUntrackSocket(dataSocket); ftpCloseSocket(&dataSocket); - return -1; - } + return -1; + } *port = ntohs(myAddr.sin_port); - *ip = ownIp; + *ip = ownIp; - if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d about to listen on port: %d using listener socket: %d\n",sessionId,passivePort,*port,dataSocket); + if (VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d about to listen on port: %d using listener socket: %d\n", sessionId, passivePort, *port, dataSocket); - if(listen(dataSocket, 100)) - { - if(VERBOSE_MODE_ENABLED) printf("\nERROR In ftpEstablishDataConnection passive listen failed for sessionId = %d using port #: %d about to close socket = %d\n",sessionId,passivePort,dataSocket); + if (listen(dataSocket, 100)) { + if (VERBOSE_MODE_ENABLED) printf("\nERROR In ftpEstablishDataConnection passive listen failed for sessionId = %d using port #: %d about to close socket = %d\n", sessionId, passivePort, dataSocket); - ftpUntrackSocket(dataSocket); - ftpCloseSocket(&dataSocket); - return -1; - } + ftpUntrackSocket(dataSocket); + ftpCloseSocket(&dataSocket); + return -1; + } - //*port = ftpGetPassivePort(); + //*port = ftpGetPassivePort(); //*ip = ownIp; - //dataSocket = ftpGetServerPassivePortListenSocket(); + //dataSocket = ftpGetServerPassivePortListenSocket(); } return dataSocket; } -socket_t ftpAcceptDataConnection(socket_t listner) -{ +socket_t ftpAcceptDataConnection(socket_t listner) { struct sockaddr_in clientinfo; - unsigned len; - socket_t dataSocket; + unsigned len; + socket_t dataSocket; - len = sizeof(clientinfo); + len = sizeof(clientinfo); dataSocket = accept(listner, (struct sockaddr *)&clientinfo, &len); - if(dataSocket < 0) - { - if(VERBOSE_MODE_ENABLED) printf("ERROR In ftpAcceptDataConnection accept failed, dataSocket = %d, listner = %d\n", dataSocket,listner); + if (dataSocket < 0) { + if (VERBOSE_MODE_ENABLED) printf("ERROR In ftpAcceptDataConnection accept failed, dataSocket = %d, listner = %d\n", dataSocket, listner); dataSocket = -1; - } - else - { - if(VERBOSE_MODE_ENABLED) printf("In ftpAcceptDataConnection accept new socket = %d, listner =%d\n", dataSocket,listner); + } else { + if (VERBOSE_MODE_ENABLED) printf("In ftpAcceptDataConnection accept new socket = %d, listner =%d\n", dataSocket, listner); } - if(VERBOSE_MODE_ENABLED) printf("\nIn ftpAcceptDataConnection about to close listener socket = %d\n",listner); + if (VERBOSE_MODE_ENABLED) printf("\nIn ftpAcceptDataConnection about to close listener socket = %d\n", listner); //ftpUntrackSocket(listner); //ftpCloseSocket(&listner); // Server-Socket wird nicht mehr gebrauch deshalb schließen - ip_t remoteIP = ntohl(clientinfo.sin_addr.s_addr); - if(ftpIsValidClient && ftpIsValidClient(remoteIP) == 0) - { - if(VERBOSE_MODE_ENABLED) printf("ERROR: Connection with %s is NOT a valid trusted client, dropping connection closing socket = %d.\n", inet_ntoa(clientinfo.sin_addr),dataSocket); + ip_t remoteIP = ntohl(clientinfo.sin_addr.s_addr); + if (ftpIsValidClient && ftpIsValidClient(remoteIP) == 0) { + if (VERBOSE_MODE_ENABLED) printf("ERROR: Connection with %s is NOT a valid trusted client, dropping connection closing socket = %d.\n", inet_ntoa(clientinfo.sin_addr), dataSocket); ftpUntrackSocket(dataSocket); ftpCloseSocket(&dataSocket); - dataSocket = -1; - } + dataSocket = -1; + } return dataSocket; } -socket_t ftpCreateServerSocket(int portNumber) -{ +socket_t ftpCreateServerSocket(int portNumber) { int theServer; struct sockaddr_in serverinfo; unsigned len; @@ -403,7 +365,7 @@ socket_t ftpCreateServerSocket(int portNumber) int opt_result = 0; theServer = socket(AF_INET, SOCK_STREAM, 0); - if(theServer < 0) + if (theServer < 0) return -1; serverinfo.sin_family = AF_INET; @@ -414,29 +376,26 @@ socket_t ftpCreateServerSocket(int portNumber) opt_result = setsockopt(theServer, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); - if(bind(theServer, (struct sockaddr *)&serverinfo, len)) - { - if(VERBOSE_MODE_ENABLED) printf("\nERROR In ftpCreateServerSocket bind FAILED about to close listener socket = %d opt_result = %d\n",theServer,opt_result); + if (bind(theServer, (struct sockaddr *)&serverinfo, len)) { + if (VERBOSE_MODE_ENABLED) printf("\nERROR In ftpCreateServerSocket bind FAILED about to close listener socket = %d opt_result = %d\n", theServer, opt_result); ftpUntrackSocket(theServer); ftpCloseSocket(&theServer); return -2; } - if(listen(theServer, 100)) - { - if(VERBOSE_MODE_ENABLED) printf("\nERROR In ftpCreateServerSocket listen FAILED about to close listener socket = %d\n",theServer); + if (listen(theServer, 100)) { + if (VERBOSE_MODE_ENABLED) printf("\nERROR In ftpCreateServerSocket listen FAILED about to close listener socket = %d\n", theServer); ftpUntrackSocket(theServer); ftpCloseSocket(&theServer); return -3; } - return (socket_t)theServer; + return (socket_t) theServer; } -socket_t ftpAcceptServerConnection(socket_t server, ip_t *remoteIP, port_t *remotePort) -{ +socket_t ftpAcceptServerConnection(socket_t server, ip_t *remoteIP, port_t *remotePort) { struct sockaddr_in sockinfo; socket_t clientSocket; unsigned len; @@ -445,79 +404,68 @@ socket_t ftpAcceptServerConnection(socket_t server, ip_t *remoteIP, port_t *remo clientSocket = accept(server, (struct sockaddr *)&sockinfo, &len); - if(clientSocket < 0) { - if(VERBOSE_MODE_ENABLED) printf("ftpAcceptServerConnection accept failed for socket = %d\n", clientSocket); - } - else { - if(VERBOSE_MODE_ENABLED) printf("ftpAcceptServerConnection accept new socket = %d\n", clientSocket); + if (clientSocket < 0) { + if (VERBOSE_MODE_ENABLED) printf("ftpAcceptServerConnection accept failed for socket = %d\n", clientSocket); + } else { + if (VERBOSE_MODE_ENABLED) printf("ftpAcceptServerConnection accept new socket = %d\n", clientSocket); } - *remoteIP = ntohl(sockinfo.sin_addr.s_addr); - *remotePort = ntohs(sockinfo.sin_port); + *remoteIP = ntohl(sockinfo.sin_addr.s_addr); + *remotePort = ntohs(sockinfo.sin_port); - if(!ownIp) // kennen wir schon die eigene IP? + if (!ownIp) // kennen wir schon die eigene IP? { len = sizeof(sockinfo); - if(clientSocket >= 0 && getsockname(clientSocket, (struct sockaddr *)&sockinfo, &len)) - { -if(VERBOSE_MODE_ENABLED) printf("getsockname error\n"); + if (clientSocket >= 0 && getsockname(clientSocket, (struct sockaddr *)&sockinfo, &len)) { + if (VERBOSE_MODE_ENABLED) printf("getsockname error\n"); } ownIp = ntohl(sockinfo.sin_addr.s_addr); // eigene IP-Adresse abspeichern (wird dir PASV benätigt) } -if(VERBOSE_MODE_ENABLED) printf("Connection with %s on Port %d accepted.\n", inet_ntoa(sockinfo.sin_addr), *remotePort); + if (VERBOSE_MODE_ENABLED) printf("Connection with %s on Port %d accepted.\n", inet_ntoa(sockinfo.sin_addr), *remotePort); - if(ftpIsValidClient && ftpIsValidClient(*remoteIP) == 0) - { - if(VERBOSE_MODE_ENABLED) printf("Connection with %s on Port %d is NOT a valid trusted client, dropping connection closing socket = %d.\n", inet_ntoa(sockinfo.sin_addr), *remotePort,clientSocket); + if (ftpIsValidClient && ftpIsValidClient(*remoteIP) == 0) { + if (VERBOSE_MODE_ENABLED) printf("Connection with %s on Port %d is NOT a valid trusted client, dropping connection closing socket = %d.\n", inet_ntoa(sockinfo.sin_addr), *remotePort, clientSocket); ftpUntrackSocket(clientSocket); - ftpCloseSocket(&clientSocket); - clientSocket = -1; - } + ftpCloseSocket(&clientSocket); + clientSocket = -1; + } return clientSocket; } -int ftpTrackSocket(socket_t s) -{ - if(s > maxSockNr) +int ftpTrackSocket(socket_t s) { + if (s > maxSockNr) maxSockNr = s; FD_SET(s, &watchedSockets); return 0; } -int ftpUntrackSocket(socket_t s) -{ - if(s > 0) - { +int ftpUntrackSocket(socket_t s) { + if (s > 0) { FD_CLR(s, &watchedSockets); } return 0; } -int ftpTestSocket(socket_t s) -{ +int ftpTestSocket(socket_t s) { return FD_ISSET(s, &signaledSockets); } -int ftpSelect(int poll) -{ +int ftpSelect(int poll) { signaledSockets = watchedSockets; - if(poll) - { - struct timeval t = {0}; + if (poll) { + struct timeval t = { 0 }; //t.tv_usec = 100; - return select(maxSockNr+1, &signaledSockets, NULL, NULL, &t); - } - else - { - struct timeval t = {0}; + return select(maxSockNr + 1, &signaledSockets, NULL, NULL, &t); + } else { + struct timeval t = { 0 }; t.tv_usec = 1000; - return select(maxSockNr+1, &signaledSockets, NULL, NULL, &t); + return select(maxSockNr + 1, &signaledSockets, NULL, NULL, &t); } } diff --git a/source/shared_lib/sources/feathery_ftp/ftpTargetWin32.c b/source/shared_lib/sources/feathery_ftp/ftpTargetWin32.c index 579126d1b..2639b4f67 100644 --- a/source/shared_lib/sources/feathery_ftp/ftpTargetWin32.c +++ b/source/shared_lib/sources/feathery_ftp/ftpTargetWin32.c @@ -39,44 +39,39 @@ ip_t ownIp; LOCAL fd_set watchedSockets; LOCAL fd_set signaledSockets; LOCAL int maxSockNr; -int wsaInitCount=0; +int wsaInitCount = 0; -void ftpArchInit() -{ +void ftpArchInit() { WSADATA wsaData; ownIp = 0; maxSockNr = 0; FD_ZERO(&watchedSockets); - if(VERBOSE_MODE_ENABLED) printf("Feathery calling WSAStartup...\n"); - WSAStartup(MAKEWORD(2, 0),&wsaData); + if (VERBOSE_MODE_ENABLED) printf("Feathery calling WSAStartup...\n"); + WSAStartup(MAKEWORD(2, 0), &wsaData); wsaInitCount++; } -void ftpArchCleanup(void) -{ - if(VERBOSE_MODE_ENABLED) printf("Feathery calling WSACleanup...[%d]\n",wsaInitCount); - if(wsaInitCount > 0) - { +void ftpArchCleanup(void) { + if (VERBOSE_MODE_ENABLED) printf("Feathery calling WSACleanup...[%d]\n", wsaInitCount); + if (wsaInitCount > 0) { WSACleanup(); // WINSOCK freigeben wsaInitCount--; } } -int ftpGetLocalTime(ftpTime_S *t) -{ +int ftpGetLocalTime(ftpTime_S *t) { struct tm *pTime; time_t tim; time(&tim); pTime = localtime(&tim); - if(pTime) - { - t->year = (uint16_t)pTime->tm_year + 1900; - t->month = (uint8_t)pTime->tm_mon + 1; - t->day = (uint8_t)pTime->tm_mday; - t->hour = (uint8_t)pTime->tm_hour; - t->minute = (uint8_t)pTime->tm_min; - t->second = (uint8_t)pTime->tm_sec; + if (pTime) { + t->year = (uint16_t) pTime->tm_year + 1900; + t->month = (uint8_t) pTime->tm_mon + 1; + t->day = (uint8_t) pTime->tm_mday; + t->hour = (uint8_t) pTime->tm_hour; + t->minute = (uint8_t) pTime->tm_min; + t->second = (uint8_t) pTime->tm_sec; return 0; } @@ -84,51 +79,42 @@ int ftpGetLocalTime(ftpTime_S *t) return -1; } -typedef struct -{ +typedef struct { HANDLE findHandle; char path[MAX_PATH_LEN]; }readDir_S; -void* ftpOpenDir(const char* path) -{ +void* ftpOpenDir(const char* path) { readDir_S* p = malloc(sizeof(readDir_S)); - if(p) - { + if (p) { p->findHandle = INVALID_HANDLE_VALUE; - strncpy(p->path, path,strlen(path)); + strncpy(p->path, path, strlen(path)); } return p; } -const char* ftpReadDir(void* dirHandle) -{ - WIN32_FIND_DATA findData; - readDir_S* p = (readDir_S *)dirHandle; +const char* ftpReadDir(void* dirHandle) { + WIN32_FIND_DATA findData; + readDir_S* p = (readDir_S *) dirHandle; - if(dirHandle == NULL) + if (dirHandle == NULL) return NULL; - if(p->findHandle == INVALID_HANDLE_VALUE) - { - if(strcmp(p->path, "/")) - strcat(p->path, "/*"); - else - strcat(p->path, "*"); + if (p->findHandle == INVALID_HANDLE_VALUE) { + if (strcmp(p->path, "/")) + strcat(p->path, "/*"); + else + strcat(p->path, "*"); p->findHandle = FindFirstFile(p->path, &findData); - if(p->findHandle != INVALID_HANDLE_VALUE) - { + if (p->findHandle != INVALID_HANDLE_VALUE) { strcpy(p->path, findData.cFileName); return p->path; } return NULL; - } - else - { - if(FindNextFile(p->findHandle, &findData)) - { + } else { + if (FindNextFile(p->findHandle, &findData)) { strcpy(p->path, findData.cFileName); return p->path; } @@ -136,65 +122,58 @@ const char* ftpReadDir(void* dirHandle) } } -int ftpCloseDir(void* dirHandle) -{ +int ftpCloseDir(void* dirHandle) { readDir_S* p = dirHandle; - if(dirHandle) - { + if (dirHandle) { FindClose(p->findHandle); free(p); } return 0; } -int ftpStat(const char* path, ftpPathInfo_S *info) -{ - struct stat fileInfo = {0}; +int ftpStat(const char* path, ftpPathInfo_S *info) { + struct stat fileInfo = { 0 }; struct tm *pTime; - if(!stat(path, &fileInfo)) - { - if(fileInfo.st_mode & _S_IFREG) + if (!stat(path, &fileInfo)) { + if (fileInfo.st_mode & _S_IFREG) info->type = TYPE_FILE; - else if(fileInfo.st_mode & _S_IFDIR) + else if (fileInfo.st_mode & _S_IFDIR) info->type = TYPE_DIR; else info->type = TYPE_LINK; pTime = localtime(&fileInfo.st_mtime); - if(pTime) - { - info->mTime.year = (uint16_t)pTime->tm_year + 1900; - info->mTime.month = (uint8_t)pTime->tm_mon + 1; - info->mTime.day = (uint8_t)pTime->tm_mday; - info->mTime.hour = (uint8_t)pTime->tm_hour; - info->mTime.minute = (uint8_t)pTime->tm_min; - info->mTime.second = (uint8_t)pTime->tm_sec; + if (pTime) { + info->mTime.year = (uint16_t) pTime->tm_year + 1900; + info->mTime.month = (uint8_t) pTime->tm_mon + 1; + info->mTime.day = (uint8_t) pTime->tm_mday; + info->mTime.hour = (uint8_t) pTime->tm_hour; + info->mTime.minute = (uint8_t) pTime->tm_min; + info->mTime.second = (uint8_t) pTime->tm_sec; } pTime = localtime(&fileInfo.st_ctime); - if(pTime) - { - info->cTime.year = (uint16_t)pTime->tm_year + 1900; - info->cTime.month = (uint8_t)pTime->tm_mon + 1; - info->cTime.day = (uint8_t)pTime->tm_mday; - info->cTime.hour = (uint8_t)pTime->tm_hour; - info->cTime.minute = (uint8_t)pTime->tm_min; - info->cTime.second = (uint8_t)pTime->tm_sec; + if (pTime) { + info->cTime.year = (uint16_t) pTime->tm_year + 1900; + info->cTime.month = (uint8_t) pTime->tm_mon + 1; + info->cTime.day = (uint8_t) pTime->tm_mday; + info->cTime.hour = (uint8_t) pTime->tm_hour; + info->cTime.minute = (uint8_t) pTime->tm_min; + info->cTime.second = (uint8_t) pTime->tm_sec; } pTime = localtime(&fileInfo.st_atime); - if(pTime) - { - info->aTime.year = (uint16_t)pTime->tm_year + 1900; - info->aTime.month = (uint8_t)pTime->tm_mon + 1; - info->aTime.day = (uint8_t)pTime->tm_mday; - info->aTime.hour = (uint8_t)pTime->tm_hour; - info->aTime.minute = (uint8_t)pTime->tm_min; - info->aTime.second = (uint8_t)pTime->tm_sec; + if (pTime) { + info->aTime.year = (uint16_t) pTime->tm_year + 1900; + info->aTime.month = (uint8_t) pTime->tm_mon + 1; + info->aTime.day = (uint8_t) pTime->tm_mday; + info->aTime.hour = (uint8_t) pTime->tm_hour; + info->aTime.minute = (uint8_t) pTime->tm_min; + info->aTime.second = (uint8_t) pTime->tm_sec; } - info->size = (uint32_t)fileInfo.st_size; - info->links = (int)fileInfo.st_nlink; + info->size = (uint32_t) fileInfo.st_size; + info->links = (int) fileInfo.st_nlink; strncpy(info->user, "ftp", sizeof(info->user)); strncpy(info->group, "ftp", sizeof(info->group)); @@ -205,125 +184,108 @@ int ftpStat(const char* path, ftpPathInfo_S *info) return -1; } -int ftpMakeDir(const char* path) -{ +int ftpMakeDir(const char* path) { return !CreateDirectory(path, NULL); } -int ftpRemoveDir(const char* path) -{ +int ftpRemoveDir(const char* path) { return !RemoveDirectory(path); } -int ftpCloseSocket(socket_t *s) -{ +int ftpCloseSocket(socket_t *s) { int ret = 0; - if(VERBOSE_MODE_ENABLED) printf("\nClosing socket: %d\n",*s); - - if(*s > 0) { - shutdown((SOCKET)*s,2); - ret = closesocket((SOCKET)*s); - *s = 0; - } + if (VERBOSE_MODE_ENABLED) printf("\nClosing socket: %d\n", *s); + + if (*s > 0) { + shutdown((SOCKET) *s, 2); + ret = closesocket((SOCKET) *s); + *s = 0; + } return ret; } -int ftpSend(socket_t s, const void *data, int len) -{ +int ftpSend(socket_t s, const void *data, int len) { int currLen = 0; - do - { + do { #ifdef __APPLE__ - currLen = send((SOCKET)s, data, len, SO_NOSIGPIPE); + currLen = send((SOCKET) s, data, len, SO_NOSIGPIPE); #else - currLen = send((SOCKET)s, data, len, MSG_NOSIGNAL); + currLen = send((SOCKET) s, data, len, MSG_NOSIGNAL); #endif - if(currLen >= 0) - { - if(currLen == 0) - { + if (currLen >= 0) { + if (currLen == 0) { int errorNumber = getLastSocketError(); const char *errText = getLastSocketErrorText(&errorNumber); - if(VERBOSE_MODE_ENABLED) printf("\nERROR #1 ftpExecute ERROR ON SEND for socket = %d, data len = %d, error = %d [%s]\n",s,len,errorNumber,errText); + if (VERBOSE_MODE_ENABLED) printf("\nERROR #1 ftpExecute ERROR ON SEND for socket = %d, data len = %d, error = %d [%s]\n", s, len, errorNumber, errText); } len -= currLen; - data = (uint8_t*)data + currLen; - } - else - { + data = (uint8_t*) data + currLen; + } else { int errorNumber = getLastSocketError(); const char *errText = getLastSocketErrorText(&errorNumber); - if(VERBOSE_MODE_ENABLED) printf("\nERROR #2 ftpExecute ERROR ON SEND for socket = %d, data len = %d, currLen = %d, error = %d [%s]\n",s,len,currLen,errorNumber,errText); + if (VERBOSE_MODE_ENABLED) printf("\nERROR #2 ftpExecute ERROR ON SEND for socket = %d, data len = %d, currLen = %d, error = %d [%s]\n", s, len, currLen, errorNumber, errText); return -1; } - } while(len > 0); + } while (len > 0); return 0; } -int ftpReceive(socket_t s, void *data, int len) -{ +int ftpReceive(socket_t s, void *data, int len) { return recv(s, data, len, 0); } -socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int sessionId) -{ +socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int sessionId) { SOCKET dataSocket; struct sockaddr_in clientAddr; struct sockaddr_in myAddr; BOOL on = 1; unsigned len; dataSocket = socket(AF_INET, SOCK_STREAM, 0); - if(dataSocket == INVALID_SOCKET) + if (dataSocket == INVALID_SOCKET) return -1; - if(!passive) - { - if(setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on))) - { - if(VERBOSE_MODE_ENABLED) printf("In ftpEstablishDataConnection #1 about to Close socket = %d, for sessionId = %d\n",dataSocket, sessionId); + if (!passive) { + if (setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, (const char*) &on, sizeof(on))) { + if (VERBOSE_MODE_ENABLED) printf("In ftpEstablishDataConnection #1 about to Close socket = %d, for sessionId = %d\n", dataSocket, sessionId); ftpUntrackSocket(dataSocket); ftpCloseSocket(&dataSocket); return -1; } - myAddr.sin_family = AF_INET; + myAddr.sin_family = AF_INET; myAddr.sin_addr.s_addr = INADDR_ANY; - myAddr.sin_port = htons(20); - myAddr.sin_zero[0] = 0; - if(bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr))) - { - if(VERBOSE_MODE_ENABLED) printf("In ftpEstablishDataConnection #2 about to Close socket = %d, for sessionId = %d\n",dataSocket, sessionId); + myAddr.sin_port = htons(20); + myAddr.sin_zero[0] = 0; + if (bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr))) { + if (VERBOSE_MODE_ENABLED) printf("In ftpEstablishDataConnection #2 about to Close socket = %d, for sessionId = %d\n", dataSocket, sessionId); ftpUntrackSocket(dataSocket); ftpCloseSocket(&dataSocket); return -1; } - clientAddr.sin_family = AF_INET; + clientAddr.sin_family = AF_INET; clientAddr.sin_addr.s_addr = htonl(*ip); - clientAddr.sin_port = htons(*port); + clientAddr.sin_port = htons(*port); clientAddr.sin_zero[0] = 0; - if(connect(dataSocket, (struct sockaddr *)&clientAddr, sizeof(clientAddr))) - { - if(VERBOSE_MODE_ENABLED) printf("In ftpEstablishDataConnection #3 about to Close socket = %d, for sessionId = %d\n",dataSocket, sessionId); + if (connect(dataSocket, (struct sockaddr *)&clientAddr, sizeof(clientAddr))) { + if (VERBOSE_MODE_ENABLED) printf("In ftpEstablishDataConnection #3 about to Close socket = %d, for sessionId = %d\n", dataSocket, sessionId); ftpUntrackSocket(dataSocket); ftpCloseSocket(&dataSocket); return -1; } - } - else - { - int passivePort = ftpGetPassivePort() + sessionId; - if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d for socket = %d\n",sessionId,passivePort,dataSocket); + } else { + int passivePort = ftpGetPassivePort() + sessionId; + if (VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d for socket = %d\n", sessionId, passivePort, dataSocket); myAddr.sin_family = AF_INET; myAddr.sin_addr.s_addr = INADDR_ANY; @@ -331,97 +293,88 @@ socket_t ftpEstablishDataConnection(int passive, ip_t *ip, port_t *port, int ses myAddr.sin_zero[0] = 0; //myAddr.sin_port = htons(ftpGetPassivePort() + sessionId); - if(setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on))) - { - if(VERBOSE_MODE_ENABLED) printf("PASSIVE CONNECTION In ftpEstablishDataConnection setsockopt failed about to Close socket = %d, for sessionId = %d\n",dataSocket, sessionId); + if (setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof(on))) { + if (VERBOSE_MODE_ENABLED) printf("PASSIVE CONNECTION In ftpEstablishDataConnection setsockopt failed about to Close socket = %d, for sessionId = %d\n", dataSocket, sessionId); ftpUntrackSocket(dataSocket); ftpCloseSocket(&dataSocket); return -1; } - if(bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr))) - { - if(VERBOSE_MODE_ENABLED) printf("\nERROR In ftpEstablishDataConnection passive bind failed for sessionId = %d using port #: %d about to close socket = %d\n",sessionId,passivePort,dataSocket); + if (bind(dataSocket, (struct sockaddr *)&myAddr, sizeof(myAddr))) { + if (VERBOSE_MODE_ENABLED) printf("\nERROR In ftpEstablishDataConnection passive bind failed for sessionId = %d using port #: %d about to close socket = %d\n", sessionId, passivePort, dataSocket); ftpUntrackSocket(dataSocket); ftpCloseSocket(&dataSocket); return -1; - } + } - if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d bound ok for socket = %d\n",sessionId,passivePort,dataSocket); + if (VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d bound ok for socket = %d\n", sessionId, passivePort, dataSocket); - len = sizeof(myAddr); - if(getsockname(dataSocket, (struct sockaddr *)&myAddr, &len)) // Port des Server-Sockets ermitteln - { - if(VERBOSE_MODE_ENABLED) printf("\nERROR In ftpEstablishDataConnection passive getsockname failed for sessionId = %d using port #: %d about to close socket = %d\n",sessionId,passivePort,dataSocket); + len = sizeof(myAddr); + if (getsockname(dataSocket, (struct sockaddr *)&myAddr, &len)) // Port des Server-Sockets ermitteln + { + if (VERBOSE_MODE_ENABLED) printf("\nERROR In ftpEstablishDataConnection passive getsockname failed for sessionId = %d using port #: %d about to close socket = %d\n", sessionId, passivePort, dataSocket); ftpUntrackSocket(dataSocket); ftpCloseSocket(&dataSocket); - return -1; - } + return -1; + } *port = ntohs(myAddr.sin_port); - *ip = ownIp; + *ip = ownIp; - if(VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d about to listen on port: %d using listener socket: %d\n",sessionId,passivePort,*port,dataSocket); + if (VERBOSE_MODE_ENABLED) printf("\nPASSIVE CONNECTION for sessionId = %d using port #: %d about to listen on port: %d using listener socket: %d\n", sessionId, passivePort, *port, dataSocket); - if(listen(dataSocket, 100)) - { - if(VERBOSE_MODE_ENABLED) printf("\nERROR In ftpEstablishDataConnection passive listen failed for sessionId = %d using port #: %d about to close socket = %d\n",sessionId,passivePort,dataSocket); + if (listen(dataSocket, 100)) { + if (VERBOSE_MODE_ENABLED) printf("\nERROR In ftpEstablishDataConnection passive listen failed for sessionId = %d using port #: %d about to close socket = %d\n", sessionId, passivePort, dataSocket); - ftpUntrackSocket(dataSocket); - ftpCloseSocket(&dataSocket); - return -1; - } + ftpUntrackSocket(dataSocket); + ftpCloseSocket(&dataSocket); + return -1; + } - //*port = ftpGetPassivePort(); + //*port = ftpGetPassivePort(); //*ip = ownIp; - //dataSocket = ftpGetServerPassivePortListenSocket(); + //dataSocket = ftpGetServerPassivePortListenSocket(); } - return (socket_t)dataSocket; + return (socket_t) dataSocket; } -socket_t ftpAcceptDataConnection(socket_t listner) -{ +socket_t ftpAcceptDataConnection(socket_t listner) { struct sockaddr_in clientinfo; - unsigned len; - SOCKET dataSocket; + unsigned len; + SOCKET dataSocket; ip_t remoteIP; - len = sizeof(clientinfo); + len = sizeof(clientinfo); dataSocket = accept(listner, (struct sockaddr *)&clientinfo, &len); - if(dataSocket == INVALID_SOCKET) - { - if(VERBOSE_MODE_ENABLED) printf("ERROR In ftpAcceptDataConnection accept failed, dataSocket = %d, listner = %d\n", dataSocket,listner); + if (dataSocket == INVALID_SOCKET) { + if (VERBOSE_MODE_ENABLED) printf("ERROR In ftpAcceptDataConnection accept failed, dataSocket = %d, listner = %d\n", dataSocket, listner); //dataSocket = -1; - } - else - { - if(VERBOSE_MODE_ENABLED) printf("In ftpAcceptDataConnection accept new socket = %d, listner =%d\n", dataSocket,listner); + } else { + if (VERBOSE_MODE_ENABLED) printf("In ftpAcceptDataConnection accept new socket = %d, listner =%d\n", dataSocket, listner); } - if(VERBOSE_MODE_ENABLED) printf("\nIn ftpAcceptDataConnection about to close listener socket = %d\n",listner); + if (VERBOSE_MODE_ENABLED) printf("\nIn ftpAcceptDataConnection about to close listener socket = %d\n", listner); //ftpUntrackSocket(listner); //ftpCloseSocket(&listner); // Server-Socket wird nicht mehr gebrauch deshalb schließen - remoteIP = ntohl(clientinfo.sin_addr.s_addr); - if(ftpIsValidClient && ftpIsValidClient(remoteIP) == 0) - { - if(VERBOSE_MODE_ENABLED) printf("ERROR: Connection with %s is NOT a valid trusted client, dropping connection closing socket = %d.\n", inet_ntoa(clientinfo.sin_addr),dataSocket); + remoteIP = ntohl(clientinfo.sin_addr.s_addr); + if (ftpIsValidClient && ftpIsValidClient(remoteIP) == 0) { + if (VERBOSE_MODE_ENABLED) printf("ERROR: Connection with %s is NOT a valid trusted client, dropping connection closing socket = %d.\n", inet_ntoa(clientinfo.sin_addr), dataSocket); ftpUntrackSocket(dataSocket); ftpCloseSocket(&dataSocket); - dataSocket = INVALID_SOCKET; - } + dataSocket = INVALID_SOCKET; + } - return (socket_t)dataSocket; + return (socket_t) dataSocket; } -socket_t ftpCreateServerSocket(int portNumber) -{ +socket_t ftpCreateServerSocket(int portNumber) { SOCKET theServer; struct sockaddr_in serverinfo; unsigned len; @@ -429,7 +382,7 @@ socket_t ftpCreateServerSocket(int portNumber) int opt_result = 0; theServer = socket(AF_INET, SOCK_STREAM, 0); - if(theServer == INVALID_SOCKET) + if (theServer == INVALID_SOCKET) return -1; serverinfo.sin_family = AF_INET; @@ -438,29 +391,28 @@ socket_t ftpCreateServerSocket(int portNumber) serverinfo.sin_zero[0] = 0; len = sizeof(serverinfo); - opt_result = setsockopt(theServer, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); + opt_result = setsockopt(theServer, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val)); - if(bind(theServer, (struct sockaddr *)&serverinfo, len)) { - if(VERBOSE_MODE_ENABLED) printf("\nERROR In ftpCreateServerSocket bind FAILED about to close listener socket = %d opt_result = %d\n",theServer,opt_result); + if (bind(theServer, (struct sockaddr *)&serverinfo, len)) { + if (VERBOSE_MODE_ENABLED) printf("\nERROR In ftpCreateServerSocket bind FAILED about to close listener socket = %d opt_result = %d\n", theServer, opt_result); ftpUntrackSocket(theServer); ftpCloseSocket(&theServer); return -2; } - if(listen(theServer, 100)) { - if(VERBOSE_MODE_ENABLED) printf("\nERROR In ftpCreateServerSocket listen FAILED about to close listener socket = %d opt_result = %d\n",theServer,opt_result); + if (listen(theServer, 100)) { + if (VERBOSE_MODE_ENABLED) printf("\nERROR In ftpCreateServerSocket listen FAILED about to close listener socket = %d opt_result = %d\n", theServer, opt_result); ftpUntrackSocket(theServer); ftpCloseSocket(&theServer); return -3; } - return (socket_t)theServer; + return (socket_t) theServer; } -socket_t ftpAcceptServerConnection(socket_t server, ip_t *remoteIP, port_t *remotePort) -{ +socket_t ftpAcceptServerConnection(socket_t server, ip_t *remoteIP, port_t *remotePort) { struct sockaddr_in sockinfo; socket_t clientSocket; int len; @@ -469,79 +421,68 @@ socket_t ftpAcceptServerConnection(socket_t server, ip_t *remoteIP, port_t *remo clientSocket = accept(server, (struct sockaddr *)&sockinfo, &len); - if(clientSocket < 0) { - if(VERBOSE_MODE_ENABLED) printf("ftpAcceptServerConnection accept failed for socket = %d\n", clientSocket); - } - else { - if(VERBOSE_MODE_ENABLED) printf("ftpAcceptServerConnection accept new socket = %d\n", clientSocket); + if (clientSocket < 0) { + if (VERBOSE_MODE_ENABLED) printf("ftpAcceptServerConnection accept failed for socket = %d\n", clientSocket); + } else { + if (VERBOSE_MODE_ENABLED) printf("ftpAcceptServerConnection accept new socket = %d\n", clientSocket); } - *remoteIP = ntohl(sockinfo.sin_addr.s_addr); - *remotePort = ntohs(sockinfo.sin_port); + *remoteIP = ntohl(sockinfo.sin_addr.s_addr); + *remotePort = ntohs(sockinfo.sin_port); - if(!ownIp) // kennen wir schon die eigene IP? + if (!ownIp) // kennen wir schon die eigene IP? { len = sizeof(sockinfo); - if(getsockname(clientSocket, (struct sockaddr *)&sockinfo, &len)) - { -if(VERBOSE_MODE_ENABLED) printf("getsockname error\n"); + if (getsockname(clientSocket, (struct sockaddr *)&sockinfo, &len)) { + if (VERBOSE_MODE_ENABLED) printf("getsockname error\n"); } ownIp = ntohl(sockinfo.sin_addr.s_addr); // eigene IP-Adresse abspeichern (wird dir PASV benätigt) } -if(VERBOSE_MODE_ENABLED) printf("Connection with %s on Port %d accepted.\n", inet_ntoa(sockinfo.sin_addr), *remotePort); + if (VERBOSE_MODE_ENABLED) printf("Connection with %s on Port %d accepted.\n", inet_ntoa(sockinfo.sin_addr), *remotePort); - if(ftpIsValidClient && ftpIsValidClient(*remoteIP) == 0) - { - if(VERBOSE_MODE_ENABLED) printf("Connection with %s on Port %d is NOT a valid trusted client, dropping connection closing socket = %d.\n", inet_ntoa(sockinfo.sin_addr), *remotePort,clientSocket); + if (ftpIsValidClient && ftpIsValidClient(*remoteIP) == 0) { + if (VERBOSE_MODE_ENABLED) printf("Connection with %s on Port %d is NOT a valid trusted client, dropping connection closing socket = %d.\n", inet_ntoa(sockinfo.sin_addr), *remotePort, clientSocket); ftpUntrackSocket(clientSocket); - ftpCloseSocket(&clientSocket); - clientSocket = -1; - } + ftpCloseSocket(&clientSocket); + clientSocket = -1; + } return clientSocket; } -int ftpTrackSocket(socket_t s) -{ - if(s > maxSockNr) +int ftpTrackSocket(socket_t s) { + if (s > maxSockNr) maxSockNr = s; FD_SET(s, &watchedSockets); return 0; } -int ftpUntrackSocket(socket_t s) -{ - if(s > 0) - { +int ftpUntrackSocket(socket_t s) { + if (s > 0) { FD_CLR(s, &watchedSockets); } return 0; } -int ftpTestSocket(socket_t s) -{ +int ftpTestSocket(socket_t s) { return FD_ISSET(s, &signaledSockets); } -int ftpSelect(int poll) -{ +int ftpSelect(int poll) { signaledSockets = watchedSockets; - if(poll) - { - struct timeval t = {0}; + if (poll) { + struct timeval t = { 0 }; //t.tv_usec = 100; - return select(maxSockNr+1, &signaledSockets, NULL, NULL, &t); - } - else - { - struct timeval t = {0}; + return select(maxSockNr + 1, &signaledSockets, NULL, NULL, &t); + } else { + struct timeval t = { 0 }; t.tv_usec = 1000; - return select(maxSockNr+1, &signaledSockets, NULL, NULL, &t); + return select(maxSockNr + 1, &signaledSockets, NULL, NULL, &t); } } diff --git a/source/shared_lib/sources/graphics/BMPReader.cpp b/source/shared_lib/sources/graphics/BMPReader.cpp index 60dd95fe7..98fb72235 100644 --- a/source/shared_lib/sources/graphics/BMPReader.cpp +++ b/source/shared_lib/sources/graphics/BMPReader.cpp @@ -18,181 +18,184 @@ using std::runtime_error; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// Structs used for BMP-reading -// ===================================================== + // ===================================================== + // Structs used for BMP-reading + // ===================================================== #pragma pack(push, 1) -struct BitmapFileHeader{ - uint8 type1; - uint8 type2; - uint32 size; - uint16 reserved1; - uint16 reserved2; - uint32 offsetBits; -}; + struct BitmapFileHeader { + uint8 type1; + uint8 type2; + uint32 size; + uint16 reserved1; + uint16 reserved2; + uint32 offsetBits; + }; -struct BitmapInfoHeader{ - uint32 size; - int32 width; - int32 height; - uint16 planes; - uint16 bitCount; - uint32 compression; - uint32 sizeImage; - int32 xPelsPerMeter; - int32 yPelsPerMeter; - uint32 clrUsed; - uint32 clrImportant; -}; + struct BitmapInfoHeader { + uint32 size; + int32 width; + int32 height; + uint16 planes; + uint16 bitCount; + uint32 compression; + uint32 sizeImage; + int32 xPelsPerMeter; + int32 yPelsPerMeter; + uint32 clrUsed; + uint32 clrImportant; + }; #pragma pack(pop) -/**Returns a string containing the extensions we want, intitialisation is guaranteed*/ -//static inline const string* getExtensionsBmp() { -static inline std::vector getExtensionsBmp() { - //static const string extensions[] = {"bmp", ""}; - static std::vector extensions; + /**Returns a string containing the extensions we want, intitialisation is guaranteed*/ + //static inline const string* getExtensionsBmp() { + static inline std::vector getExtensionsBmp() { + //static const string extensions[] = {"bmp", ""}; + static std::vector extensions; - if(extensions.empty() == true) { - extensions.push_back("bmp"); - } - - return extensions; -} - -// ===================================================== -// class BMPReader -// ===================================================== - -BMPReader::BMPReader(): FileReader(getExtensionsBmp()) {} - -/**Reads a Pixmap2D-object - *This function reads a Pixmap2D-object from the given ifstream utilising the already existing Pixmap2D* ret. - *Path is used for printing error messages - *@return NULL if the Pixmap2D could not be read, else the pixmap*/ -Pixmap2D* BMPReader::read(ifstream& in, const string& path, Pixmap2D* ret) const { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - //read file header - BitmapFileHeader fileHeader; - in.read((char*)&fileHeader, sizeof(BitmapFileHeader)); - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - fileHeader.offsetBits = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.offsetBits); - fileHeader.reserved1 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.reserved1); - fileHeader.reserved2 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.reserved2); - fileHeader.size = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.size); - fileHeader.type1 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.type1); - fileHeader.type2 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.type2); - } - - if(fileHeader.type1!='B' || fileHeader.type2!='M'){ - throw megaglest_runtime_error(path +" is not a bitmap",true); - } - - //read info header - BitmapInfoHeader infoHeader; - in.read((char*)&infoHeader, sizeof(BitmapInfoHeader)); - if(bigEndianSystem == true) { - infoHeader.bitCount = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.bitCount); - infoHeader.clrImportant = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.clrImportant); - infoHeader.clrUsed = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.clrUsed); - infoHeader.compression = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.compression); - infoHeader.height = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.height); - infoHeader.planes = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.planes); - infoHeader.size = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.size); - infoHeader.sizeImage = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.sizeImage); - infoHeader.width = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.width); - infoHeader.xPelsPerMeter = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.xPelsPerMeter); - infoHeader.yPelsPerMeter = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.yPelsPerMeter); - } - - if(infoHeader.bitCount!=24){ - throw megaglest_runtime_error(path+" is not a 24 bit bitmap",true); - } - - int h= infoHeader.height; - int w= infoHeader.width; - int components= (ret->getComponents() == -1)?3:ret->getComponents(); - const int fileComponents = 3; - //std::cout << "BMP-Components: Pic: " << components << " old: " << (ret->getComponents()) << " File: " << 3 << std::endl; - ret->init(w,h,components); - uint8* pixels = ret->getPixels(); - char buffer[4]; - //BMP is padded to sizes of 4 - const int padSize = (4 - (w*fileComponents)%4)%4; //Yeah, could be faster - //std::cout << "Padsize = " << padSize; - for (int y = 0, i = 0; y < h; ++y) { - for (int x = 0; x < w; ++x, i+=components) { - uint8 r, g, b; -// in.read((char*)&b, 1); -// if(bigEndianSystem == true) { -// b = Shared::PlatformByteOrder::fromCommonEndian(b); -// } -// -// in.read((char*)&g, 1); -// if(bigEndianSystem == true) { -// g = Shared::PlatformByteOrder::fromCommonEndian(g); -// } -// -// in.read((char*)&r, 1); -// if(bigEndianSystem == true) { -// r = Shared::PlatformByteOrder::fromCommonEndian(r); -// } - uint8 bgr[3] = {0,0,0}; - in.read((char*)&bgr[0], 3); - b = bgr[0]; - g = bgr[1]; - r = bgr[2]; - if(bigEndianSystem == true) { - b = Shared::PlatformByteOrder::fromCommonEndian(b); - g = Shared::PlatformByteOrder::fromCommonEndian(g); - r = Shared::PlatformByteOrder::fromCommonEndian(r); - } - if (!in.good()) { - return NULL; - } - switch(components){ - case 1: - pixels[i]= (r+g+b)/3; - break; - case 3: - pixels[i]= r; - pixels[i+1]= g; - pixels[i+2]= b; - break; - case 4: - pixels[i]= r; - pixels[i+1]= g; - pixels[i+2]= b; - pixels[i+3]= 255; - break; + if (extensions.empty() == true) { + extensions.push_back("bmp"); } + + return extensions; } - if (padSize) { - in.read(buffer,padSize); - } - } - /*for(int i = 0; i < w*h*components; ++i) { - if (i%39 == 0) std::cout << std::endl; - int first = pixels[i]/16; - if (first < 10) - std:: cout << first; - else - std::cout << (char)('A'+(first-10)); - first = pixels[i]%16; - if (first < 10) - std:: cout << first; - else - std::cout << (char)('A'+(first-10)); - std::cout << " "; - }*/ - return ret; -} -}} //end namespace + // ===================================================== + // class BMPReader + // ===================================================== + + BMPReader::BMPReader() : FileReader(getExtensionsBmp()) { + } + + /**Reads a Pixmap2D-object + *This function reads a Pixmap2D-object from the given ifstream utilising the already existing Pixmap2D* ret. + *Path is used for printing error messages + *@return NULL if the Pixmap2D could not be read, else the pixmap*/ + Pixmap2D* BMPReader::read(ifstream& in, const string& path, Pixmap2D* ret) const { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + + //read file header + BitmapFileHeader fileHeader; + in.read((char*) &fileHeader, sizeof(BitmapFileHeader)); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + fileHeader.offsetBits = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.offsetBits); + fileHeader.reserved1 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.reserved1); + fileHeader.reserved2 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.reserved2); + fileHeader.size = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.size); + fileHeader.type1 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.type1); + fileHeader.type2 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.type2); + } + + if (fileHeader.type1 != 'B' || fileHeader.type2 != 'M') { + throw megaglest_runtime_error(path + " is not a bitmap", true); + } + + //read info header + BitmapInfoHeader infoHeader; + in.read((char*) &infoHeader, sizeof(BitmapInfoHeader)); + if (bigEndianSystem == true) { + infoHeader.bitCount = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.bitCount); + infoHeader.clrImportant = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.clrImportant); + infoHeader.clrUsed = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.clrUsed); + infoHeader.compression = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.compression); + infoHeader.height = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.height); + infoHeader.planes = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.planes); + infoHeader.size = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.size); + infoHeader.sizeImage = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.sizeImage); + infoHeader.width = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.width); + infoHeader.xPelsPerMeter = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.xPelsPerMeter); + infoHeader.yPelsPerMeter = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.yPelsPerMeter); + } + + if (infoHeader.bitCount != 24) { + throw megaglest_runtime_error(path + " is not a 24 bit bitmap", true); + } + + int h = infoHeader.height; + int w = infoHeader.width; + int components = (ret->getComponents() == -1) ? 3 : ret->getComponents(); + const int fileComponents = 3; + //std::cout << "BMP-Components: Pic: " << components << " old: " << (ret->getComponents()) << " File: " << 3 << std::endl; + ret->init(w, h, components); + uint8* pixels = ret->getPixels(); + char buffer[4]; + //BMP is padded to sizes of 4 + const int padSize = (4 - (w*fileComponents) % 4) % 4; //Yeah, could be faster + //std::cout << "Padsize = " << padSize; + for (int y = 0, i = 0; y < h; ++y) { + for (int x = 0; x < w; ++x, i += components) { + uint8 r, g, b; + // in.read((char*)&b, 1); + // if(bigEndianSystem == true) { + // b = Shared::PlatformByteOrder::fromCommonEndian(b); + // } + // + // in.read((char*)&g, 1); + // if(bigEndianSystem == true) { + // g = Shared::PlatformByteOrder::fromCommonEndian(g); + // } + // + // in.read((char*)&r, 1); + // if(bigEndianSystem == true) { + // r = Shared::PlatformByteOrder::fromCommonEndian(r); + // } + uint8 bgr[3] = { 0,0,0 }; + in.read((char*) &bgr[0], 3); + b = bgr[0]; + g = bgr[1]; + r = bgr[2]; + if (bigEndianSystem == true) { + b = Shared::PlatformByteOrder::fromCommonEndian(b); + g = Shared::PlatformByteOrder::fromCommonEndian(g); + r = Shared::PlatformByteOrder::fromCommonEndian(r); + } + if (!in.good()) { + return NULL; + } + switch (components) { + case 1: + pixels[i] = (r + g + b) / 3; + break; + case 3: + pixels[i] = r; + pixels[i + 1] = g; + pixels[i + 2] = b; + break; + case 4: + pixels[i] = r; + pixels[i + 1] = g; + pixels[i + 2] = b; + pixels[i + 3] = 255; + break; + } + } + if (padSize) { + in.read(buffer, padSize); + } + } + /*for(int i = 0; i < w*h*components; ++i) { + if (i%39 == 0) std::cout << std::endl; + int first = pixels[i]/16; + if (first < 10) + std:: cout << first; + else + std::cout << (char)('A'+(first-10)); + first = pixels[i]%16; + if (first < 10) + std:: cout << first; + else + std::cout << (char)('A'+(first-10)); + std::cout << " "; + }*/ + return ret; + } + + } +} //end namespace diff --git a/source/shared_lib/sources/graphics/ImageReaders.cpp b/source/shared_lib/sources/graphics/ImageReaders.cpp index cd8fc6a28..4ae93c9ba 100644 --- a/source/shared_lib/sources/graphics/ImageReaders.cpp +++ b/source/shared_lib/sources/graphics/ImageReaders.cpp @@ -12,21 +12,23 @@ #include "ImageReaders.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// namespace ImageRegisterer -// ===================================================== + // ===================================================== + // namespace ImageRegisterer + // ===================================================== -/**Create & register all known Readers*/ -bool ImageRegisterer::registerImageReaders() { - static BMPReader imageReaderBmp; - static JPGReader imageReaderJpg; - static PNGReader imageReaderPng; - static PNGReader3D imageReader3DPng; - static TGAReader imageReaderTga; - static TGAReader3D imageReader3DTga; - return true; -} + /**Create & register all known Readers*/ + bool ImageRegisterer::registerImageReaders() { + static BMPReader imageReaderBmp; + static JPGReader imageReaderJpg; + static PNGReader imageReaderPng; + static PNGReader3D imageReader3DPng; + static TGAReader imageReaderTga; + static TGAReader3D imageReader3DTga; + return true; + } -}} //end namespace + } +} //end namespace diff --git a/source/shared_lib/sources/graphics/JPGReader.cpp b/source/shared_lib/sources/graphics/JPGReader.cpp index 37e2fd903..d58de5551 100644 --- a/source/shared_lib/sources/graphics/JPGReader.cpp +++ b/source/shared_lib/sources/graphics/JPGReader.cpp @@ -24,213 +24,215 @@ using std::runtime_error; using std::ios; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// Methods used for JPG-Decompression -// ===================================================== + // ===================================================== + // Methods used for JPG-Decompression + // ===================================================== -//Methods used by jpeglib -static void init_source(j_decompress_ptr cinfo) { - //It already is initialized -} -static boolean fill_input_buffer (j_decompress_ptr cinfo) { - //it is already filled - return boolean(true); -} -static void skip_input_data (j_decompress_ptr cinfo, long num_bytes) { - if (num_bytes > 0) { - jpeg_source_mgr* This = cinfo->src; - This->bytes_in_buffer-= num_bytes; - This->next_input_byte+= num_bytes; - } -} -static void term_source (j_decompress_ptr cinfo) { -} - -// ===================================================== -// class JPGReader -// ===================================================== - -/**Return an array containing the used extensions, - * initialized*/ -//static inline const string* getExtensions() { - //static const string extensions[] = {"jpg", "jpeg", ""}; -static inline std::vector getExtensions() { - static std::vector extensions; - if(extensions.empty() == true) { - extensions.push_back("jpg"); - extensions.push_back("jpeg"); - } - - return extensions; -} - -JPGReader::JPGReader(): FileReader(getExtensions()) {} - -Pixmap2D* JPGReader::read(ifstream& is, const string& path, Pixmap2D* ret) const { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - //Read file - is.seekg(0, ios::end); - streampos length = is.tellg(); - if (length < 8) { - return NULL; - } - is.seekg(0, ios::beg); - uint8 *buffer = new uint8[(unsigned int)length]; - is.read((char*)buffer, (std::streamsize)length); - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - Shared::PlatformByteOrder::fromEndianTypeArray(buffer,(size_t)length); - } - if(length < 2) { - throw megaglest_runtime_error("length < 2",true); - } - //Check buffer (weak jpeg check) - //if (buffer[0] != 0x46 || buffer[1] != 0xA0) { - // Proper header check found from: http://www.fastgraph.com/help/jpeg_header_format.html - if (buffer[0] != 0xFF || buffer[1] != 0xD8) { - std::cout << "0 = [" << std::hex << (int)buffer[0] << "] 1 = [" << std::hex << (int)buffer[1] << "]" << std::endl; - delete[] buffer; - throw megaglest_runtime_error(path +" is not a jpeg",true); - } - - struct jpeg_decompress_struct cinfo; - struct jpeg_error_mgr jerr; - - JSAMPROW row_pointer[1]; - row_pointer[0] = NULL; - cinfo.err = jpeg_std_error( &jerr ); //Standard error handler - jpeg_create_decompress( &cinfo ); //Create decompressing structure - struct jpeg_source_mgr source; - - jmp_buf error_buffer; //Used for saving/restoring context - // Set up data pointer - source.bytes_in_buffer = (size_t)length; - source.next_input_byte = (JOCTET*)buffer; - cinfo.src = &source; - - if (setjmp(error_buffer)) { //Longjump was called --> an exception was thrown - delete[] buffer; - jpeg_destroy_decompress(&cinfo); - if (row_pointer[0] != NULL) { - delete[] row_pointer[0]; + //Methods used by jpeglib + static void init_source(j_decompress_ptr cinfo) { + //It already is initialized } - throw megaglest_runtime_error(path +" is a corrupt(1) jpeg",true); - } - - source.init_source = init_source; - source.fill_input_buffer = fill_input_buffer; - source.resync_to_restart = jpeg_resync_to_restart; - source.skip_input_data = skip_input_data; - source.term_source = term_source; - - /* reading the image header which contains image information */ - if (jpeg_read_header( &cinfo, TRUE ) != JPEG_HEADER_OK) { - delete[] buffer; - jpeg_destroy_decompress(&cinfo); - throw megaglest_runtime_error(path +" is a corrupt(1) jpeg",true); - } - - - /*std::cout << "JPEG FILE Information: " << std::endl; - std::cout << "Image width and height: " << cinfo.image_width <<" pixels and " << cinfo.image_height <<" pixels." << std::endl; - - std::cout << "Color components per fixel: " << cinfo.num_components << std::endl; - std::cout << "Color space: " << cinfo.jpeg_color_space << std::endl;*/ - int picComponents = (ret->getComponents() == -1)?cinfo.num_components:ret->getComponents(); - //std::cout << "JPG-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << cinfo.num_components << std::endl; - //picComponents = 4; - - // Start decompression jpeg here - jpeg_start_decompress( &cinfo ); - ret->init(cinfo.image_width, cinfo.image_height, picComponents); - uint8* pixels = ret->getPixels(); - //std::cout << "output width and height: " << cinfo.output_width <<" pixels and " << cinfo.output_height <<" pixels." << std::endl; - /* now actually read the jpeg into the raw buffer */ - row_pointer[0] = new unsigned char[cinfo.output_width*cinfo.num_components]; - /* read one scan line at a time */ - /* Again you need to invert the lines unfortunately*/ - while( cinfo.output_scanline < cinfo.output_height ) - { - jpeg_read_scanlines( &cinfo, row_pointer, 1 ); - //Current pixel - size_t location = (cinfo.output_height - cinfo.output_scanline) * cinfo.output_width * picComponents; - if (picComponents == cinfo.num_components) { - memcpy(pixels+location,row_pointer[0],cinfo.output_width*cinfo.num_components); - } else { - int r,g,b,a,l; - for (unsigned int xPic = 0, xFile = 0; xPic < cinfo.output_width*picComponents; xPic+= picComponents, xFile+= cinfo.num_components) { - switch(cinfo.num_components) { - case 3: - r = row_pointer[0][xFile]; - g = row_pointer[0][xFile+1]; - b = row_pointer[0][xFile+2]; - l = (r+g+b+2)/3; - a = 255; - break; - case 4: - r = row_pointer[0][xFile]; - g = row_pointer[0][xFile+1]; - b = row_pointer[0][xFile+2]; - l = (r+g+b+2)/3; - a = row_pointer[0][xFile+3]; - break; - default: - // Possible Error - case 1: - r = g = b = l = row_pointer[0][xFile]; - a = 255; - break; - } - switch (picComponents) { - case 1: - pixels[location+xPic] = l; - break; - case 4: - pixels[location+xPic+3] = a; //Next case - case 3: - pixels[location+xPic] = r; - pixels[location+xPic+1] = g; - pixels[location+xPic+2] = b; - break; - default: - //just so at least something works - for (int i = 0; i < picComponents; ++i) { - pixels[location+xPic+i] = l; - } - break; - // Possible Error - } + static boolean fill_input_buffer(j_decompress_ptr cinfo) { + //it is already filled + return boolean(true); + } + static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) { + if (num_bytes > 0) { + jpeg_source_mgr* This = cinfo->src; + This->bytes_in_buffer -= num_bytes; + This->next_input_byte += num_bytes; } } + static void term_source(j_decompress_ptr cinfo) { + } + + // ===================================================== + // class JPGReader + // ===================================================== + + /**Return an array containing the used extensions, + * initialized*/ + //static inline const string* getExtensions() { + //static const string extensions[] = {"jpg", "jpeg", ""}; + static inline std::vector getExtensions() { + static std::vector extensions; + if (extensions.empty() == true) { + extensions.push_back("jpg"); + extensions.push_back("jpeg"); + } + + return extensions; + } + + JPGReader::JPGReader() : FileReader(getExtensions()) { + } + + Pixmap2D* JPGReader::read(ifstream& is, const string& path, Pixmap2D* ret) const { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + + //Read file + is.seekg(0, ios::end); + streampos length = is.tellg(); + if (length < 8) { + return NULL; + } + is.seekg(0, ios::beg); + uint8 *buffer = new uint8[(unsigned int) length]; + is.read((char*) buffer, (std::streamsize)length); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + Shared::PlatformByteOrder::fromEndianTypeArray(buffer, (size_t) length); + } + if (length < 2) { + throw megaglest_runtime_error("length < 2", true); + } + //Check buffer (weak jpeg check) + //if (buffer[0] != 0x46 || buffer[1] != 0xA0) { + // Proper header check found from: http://www.fastgraph.com/help/jpeg_header_format.html + if (buffer[0] != 0xFF || buffer[1] != 0xD8) { + std::cout << "0 = [" << std::hex << (int) buffer[0] << "] 1 = [" << std::hex << (int) buffer[1] << "]" << std::endl; + delete[] buffer; + throw megaglest_runtime_error(path + " is not a jpeg", true); + } + + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + + JSAMPROW row_pointer[1]; + row_pointer[0] = NULL; + cinfo.err = jpeg_std_error(&jerr); //Standard error handler + jpeg_create_decompress(&cinfo); //Create decompressing structure + struct jpeg_source_mgr source; + + jmp_buf error_buffer; //Used for saving/restoring context + // Set up data pointer + source.bytes_in_buffer = (size_t) length; + source.next_input_byte = (JOCTET*) buffer; + cinfo.src = &source; + + if (setjmp(error_buffer)) { //Longjump was called --> an exception was thrown + delete[] buffer; + jpeg_destroy_decompress(&cinfo); + if (row_pointer[0] != NULL) { + delete[] row_pointer[0]; + } + throw megaglest_runtime_error(path + " is a corrupt(1) jpeg", true); + } + + source.init_source = init_source; + source.fill_input_buffer = fill_input_buffer; + source.resync_to_restart = jpeg_resync_to_restart; + source.skip_input_data = skip_input_data; + source.term_source = term_source; + + /* reading the image header which contains image information */ + if (jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK) { + delete[] buffer; + jpeg_destroy_decompress(&cinfo); + throw megaglest_runtime_error(path + " is a corrupt(1) jpeg", true); + } + + + /*std::cout << "JPEG FILE Information: " << std::endl; + std::cout << "Image width and height: " << cinfo.image_width <<" pixels and " << cinfo.image_height <<" pixels." << std::endl; + + std::cout << "Color components per fixel: " << cinfo.num_components << std::endl; + std::cout << "Color space: " << cinfo.jpeg_color_space << std::endl;*/ + int picComponents = (ret->getComponents() == -1) ? cinfo.num_components : ret->getComponents(); + //std::cout << "JPG-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << cinfo.num_components << std::endl; + //picComponents = 4; + + // Start decompression jpeg here + jpeg_start_decompress(&cinfo); + ret->init(cinfo.image_width, cinfo.image_height, picComponents); + uint8* pixels = ret->getPixels(); + //std::cout << "output width and height: " << cinfo.output_width <<" pixels and " << cinfo.output_height <<" pixels." << std::endl; + /* now actually read the jpeg into the raw buffer */ + row_pointer[0] = new unsigned char[cinfo.output_width*cinfo.num_components]; + /* read one scan line at a time */ + /* Again you need to invert the lines unfortunately*/ + while (cinfo.output_scanline < cinfo.output_height) { + jpeg_read_scanlines(&cinfo, row_pointer, 1); + //Current pixel + size_t location = (cinfo.output_height - cinfo.output_scanline) * cinfo.output_width * picComponents; + if (picComponents == cinfo.num_components) { + memcpy(pixels + location, row_pointer[0], cinfo.output_width*cinfo.num_components); + } else { + int r, g, b, a, l; + for (unsigned int xPic = 0, xFile = 0; xPic < cinfo.output_width*picComponents; xPic += picComponents, xFile += cinfo.num_components) { + switch (cinfo.num_components) { + case 3: + r = row_pointer[0][xFile]; + g = row_pointer[0][xFile + 1]; + b = row_pointer[0][xFile + 2]; + l = (r + g + b + 2) / 3; + a = 255; + break; + case 4: + r = row_pointer[0][xFile]; + g = row_pointer[0][xFile + 1]; + b = row_pointer[0][xFile + 2]; + l = (r + g + b + 2) / 3; + a = row_pointer[0][xFile + 3]; + break; + default: + // Possible Error + case 1: + r = g = b = l = row_pointer[0][xFile]; + a = 255; + break; + } + switch (picComponents) { + case 1: + pixels[location + xPic] = l; + break; + case 4: + pixels[location + xPic + 3] = a; //Next case + case 3: + pixels[location + xPic] = r; + pixels[location + xPic + 1] = g; + pixels[location + xPic + 2] = b; + break; + default: + //just so at least something works + for (int i = 0; i < picComponents; ++i) { + pixels[location + xPic + i] = l; + } + break; + // Possible Error + } + } + } + } + /*for(int i = 0; i < cinfo.image_width*cinfo.image_height*picComponents; ++i) { + if (i%39 == 0) std::cout << std::endl; + int first = pixels[i]/16; + if (first < 10) + std:: cout << first; + else + std::cout << (char)('A'+(first-10)); + first = pixels[i]%16; + if (first < 10) + std:: cout << first; + else + std::cout << (char)('A'+(first-10)); + std::cout << " "; + }*/ + /* wrap up decompression, destroy objects, free pointers and close open files */ + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + delete[] row_pointer[0]; + + delete[] buffer; + + return ret; + } + } - /*for(int i = 0; i < cinfo.image_width*cinfo.image_height*picComponents; ++i) { - if (i%39 == 0) std::cout << std::endl; - int first = pixels[i]/16; - if (first < 10) - std:: cout << first; - else - std::cout << (char)('A'+(first-10)); - first = pixels[i]%16; - if (first < 10) - std:: cout << first; - else - std::cout << (char)('A'+(first-10)); - std::cout << " "; - }*/ - /* wrap up decompression, destroy objects, free pointers and close open files */ - jpeg_finish_decompress( &cinfo ); - jpeg_destroy_decompress( &cinfo ); - delete[] row_pointer[0]; - - delete[] buffer; - - return ret; -} - -}} //end namespace +} //end namespace diff --git a/source/shared_lib/sources/graphics/PNGReader.cpp b/source/shared_lib/sources/graphics/PNGReader.cpp index 1af6899ec..d0f4c614e 100644 --- a/source/shared_lib/sources/graphics/PNGReader.cpp +++ b/source/shared_lib/sources/graphics/PNGReader.cpp @@ -22,350 +22,354 @@ using std::runtime_error; using std::ios; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// Callbacks for PNG-decompression -// ===================================================== + // ===================================================== + // Callbacks for PNG-decompression + // ===================================================== -static void user_read_data(png_structp read_ptr, png_bytep data, png_size_t length) { - ifstream& is = *((ifstream*)png_get_io_ptr(read_ptr)); - is.read((char*)data,(std::streamsize)length); - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - Shared::PlatformByteOrder::fromEndianTypeArray(data,length); - } + static void user_read_data(png_structp read_ptr, png_bytep data, png_size_t length) { + ifstream& is = *((ifstream*) png_get_io_ptr(read_ptr)); + is.read((char*) data, (std::streamsize)length); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + Shared::PlatformByteOrder::fromEndianTypeArray(data, length); + } - if (!is.good()) { - png_error(read_ptr,"Could not read from png-file"); - } -} - -//static void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length) {} - -//static void user_flush_data(png_structp png_ptr) {} - -/**Get Extension array, initialised*/ -//static inline const string* getExtensionsPng() { -static inline std::vector getExtensionsPng() { - //static const string extensions[] = {"png", ""}; - static std::vector extensions; - if(extensions.empty() == true) { - extensions.push_back("png"); - } - return extensions; -} - -// ===================================================== -// class PNGReader -// ===================================================== - -PNGReader::PNGReader(): FileReader(getExtensionsPng()) {} - -Pixmap2D* PNGReader::read(ifstream& is, const string& path, Pixmap2D* ret) const { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - //Read file - is.seekg(0, ios::end); - //size_t length = is.tellg(); - is.seekg(0, ios::beg); - uint8 *buffer = new uint8[8]; - is.read((char*)buffer, 8); - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - Shared::PlatformByteOrder::fromEndianTypeArray(buffer,8); - } - - if (png_sig_cmp(buffer, 0, 8) != 0) { - delete [] buffer; - //This is not a PNG file - could be used for fast checking whether file is supported or not - throw megaglest_runtime_error(path +" is not a png",true); - } - - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png_ptr) { - delete [] buffer; - throw megaglest_runtime_error(path +" is a corrupt(1) png",true); - } - png_infop info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_read_struct(&png_ptr, (png_infopp)NULL,(png_infopp)NULL); - delete [] buffer; - throw megaglest_runtime_error(path +" is a corrupt(2) png",true); - } - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_read_struct(&png_ptr, &info_ptr,(png_infopp)NULL); - delete [] buffer; - //Error during init_io - throw megaglest_runtime_error(path +" is a corrupt(3) png",true); - } - png_set_read_fn(png_ptr, &is, user_read_data); - png_set_sig_bytes(png_ptr, 8); - png_read_info(png_ptr, info_ptr); - - int width = png_get_image_width(png_ptr,info_ptr); - - int height = png_get_image_height(png_ptr,info_ptr); - int color_type = png_get_color_type(png_ptr,info_ptr); - //int bit_depth = info_ptr->bit_depth; - - //We want RGB, 24 bit - if (color_type == PNG_COLOR_TYPE_PALETTE || - (color_type == PNG_COLOR_TYPE_GRAY && png_get_bit_depth(png_ptr,info_ptr) < 8) || - (png_get_valid(png_ptr, info_ptr,PNG_INFO_tRNS))) { - png_set_expand(png_ptr); - } - - if (color_type == PNG_COLOR_TYPE_GRAY) { - png_set_gray_to_rgb(png_ptr); - } - - //int number_of_passes = png_set_interlace_handling(png_ptr); - png_set_interlace_handling(png_ptr); - png_read_update_info(png_ptr, info_ptr); - png_bytep* row_pointers = new png_bytep[height]; - - if (setjmp(png_jmpbuf(png_ptr))) { - delete[] row_pointers; - delete [] buffer; - //error during read_image - throw megaglest_runtime_error(path +" is a corrupt(4) png",true); - } - for (int y = 0; y < height; ++y) { - row_pointers[y] = new png_byte[png_get_rowbytes(png_ptr, info_ptr)]; - } - png_read_image(png_ptr, row_pointers); - size_t fileComponents = png_get_rowbytes(png_ptr, info_ptr)/width; - size_t picComponents = (ret->getComponents()==-1)?fileComponents:ret->getComponents(); - //std::cout << "PNG-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << fileComponents << std::endl; - //picComponents = 4; - //Copy image - ret->init(width,height,(int)picComponents); - uint8* pixels = ret->getPixels(); - const size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr); - size_t location = 0; - for (int y = height-1; y >= 0; --y) { //you have to somehow invert the lines - if (picComponents == fileComponents) { - memcpy(pixels+location,row_pointers[y],rowbytes); - } else { - int r,g,b,a,l; - for (size_t xPic = 0, xFile = 0; xFile < rowbytes; xPic+= picComponents, xFile+= fileComponents) { - switch(fileComponents) { - case 3: - r = row_pointers[y][xFile]; - g = row_pointers[y][xFile+1]; - b = row_pointers[y][xFile+2]; - l = (r+g+b+2)/3; - a = 255; - break; - case 4: - r = row_pointers[y][xFile]; - g = row_pointers[y][xFile+1]; - b = row_pointers[y][xFile+2]; - l = (r+g+b+2)/3; - a = row_pointers[y][xFile+3]; - break; - default: - // Possible Error - case 1: - r = g = b = l = row_pointers[y][xFile]; - a = 255; - break; - } - switch (picComponents) { - case 1: - pixels[location+xPic] = l; - break; - case 4: - pixels[location+xPic+3] = a; //Next case - case 3: - pixels[location+xPic] = r; - pixels[location+xPic+1] = g; - pixels[location+xPic+2] = b; - break; - default: - //just so at least something works - for (unsigned int i = 0; i < picComponents; ++i) { - pixels[location+xPic+i] = l; - } - break; - // Possible Error - } + if (!is.good()) { + png_error(read_ptr, "Could not read from png-file"); } } - location += picComponents * width; - } - for (int y = 0; y < height; ++y) { - delete [] row_pointers[y]; - } - delete[] row_pointers; + //static void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length) {} - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + //static void user_flush_data(png_structp png_ptr) {} - delete [] buffer; - - return ret; -} - - - -PNGReader3D::PNGReader3D(): FileReader(getExtensionsPng()) {} - -Pixmap3D* PNGReader3D::read(ifstream& is, const string& path, Pixmap3D* ret) const { - //Read file - is.seekg(0, ios::end); - //size_t length = is.tellg(); - is.seekg(0, ios::beg); - uint8 *buffer = new uint8[8]; - is.read((char*)buffer, 8); - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - Shared::PlatformByteOrder::fromEndianTypeArray(buffer,8); - } - - if (png_sig_cmp(buffer, 0, 8) != 0) { - delete [] buffer; - //This is not a PNG file - could be used for fast checking whether file is supported or not - throw megaglest_runtime_error(path +" is not a png(2)",true); - } - - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png_ptr) { - delete [] buffer; - throw megaglest_runtime_error(path +" is a corrupt(5) png",true); - } - png_infop info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_read_struct(&png_ptr, (png_infopp)NULL,(png_infopp)NULL); - delete [] buffer; - throw megaglest_runtime_error(path +" is a corrupt(6) png",true); - } - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_read_struct(&png_ptr, &info_ptr,(png_infopp)NULL); - delete [] buffer; - //Error during init_io - throw megaglest_runtime_error(path +" is a corrupt(7) png",true); - } - png_set_read_fn(png_ptr, &is, user_read_data); - png_set_sig_bytes(png_ptr, 8); - png_read_info(png_ptr, info_ptr); - - int width = png_get_image_width(png_ptr,info_ptr); - int height = png_get_image_height(png_ptr,info_ptr); - int color_type = png_get_color_type(png_ptr,info_ptr); - //int bit_depth = info_ptr->bit_depth; - - //We want RGB, 24 bit - if (color_type == PNG_COLOR_TYPE_PALETTE || - (color_type == PNG_COLOR_TYPE_GRAY && png_get_bit_depth(png_ptr,info_ptr) < 8) || - (png_get_valid(png_ptr, info_ptr,PNG_INFO_tRNS))) { - png_set_expand(png_ptr); - } - - if (color_type == PNG_COLOR_TYPE_GRAY) { - png_set_gray_to_rgb(png_ptr); - } - - //int number_of_passes = png_set_interlace_handling(png_ptr); - png_set_interlace_handling(png_ptr); - png_read_update_info(png_ptr, info_ptr); - png_bytep* row_pointers = new png_bytep[height]; - - if (setjmp(png_jmpbuf(png_ptr))) { - delete[] row_pointers; - delete [] buffer; - //error during read_image - throw megaglest_runtime_error(path +" is a corrupt(8) png",true); - } - for (int y = 0; y < height; ++y) { - row_pointers[y] = new png_byte[png_get_rowbytes(png_ptr, info_ptr)]; - } - png_read_image(png_ptr, row_pointers); - size_t fileComponents = png_get_rowbytes(png_ptr, info_ptr)/width; - size_t picComponents = (ret->getComponents()==-1)?fileComponents:ret->getComponents(); - const int d = ret->getD(); - const int slice = ret->getSlice(); - if(ret->getPixels() == NULL){ - ret->init(width,height,d, (int)picComponents); - } - - //std::cout << "PNG-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << fileComponents << std::endl; - //picComponents = 4; - //Copy image - //printf("pixmap3d loading path [%s] w = %d h = %d d = %d comp = %d\n",path.c_str(),width,height,ret->getD(),picComponents); - uint8* pixels = ret->getPixels(); - if(slice > 0) { - pixels = &pixels[slice*width*height*picComponents]; - } - - const size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr); - size_t location = 0; - for (int y = height-1; y >= 0; --y) { //you have to somehow invert the lines - if (picComponents == fileComponents) { - memcpy(pixels+location,row_pointers[y],rowbytes); - } else { - int r,g,b,a,l; - for (size_t xPic = 0, xFile = 0; xFile < rowbytes; xPic+= picComponents, xFile+= fileComponents) { - switch(fileComponents) { - case 3: - r = row_pointers[y][xFile]; - g = row_pointers[y][xFile+1]; - b = row_pointers[y][xFile+2]; - l = (r+g+b+2)/3; - a = 255; - break; - case 4: - r = row_pointers[y][xFile]; - g = row_pointers[y][xFile+1]; - b = row_pointers[y][xFile+2]; - l = (r+g+b+2)/3; - a = row_pointers[y][xFile+3]; - break; - default: - // Possible Error - case 1: - r = g = b = l = row_pointers[y][xFile]; - a = 255; - break; - } - switch (picComponents) { - case 1: - pixels[location+xPic] = l; - break; - case 4: - pixels[location+xPic+3] = a; //Next case - case 3: - pixels[location+xPic] = r; - pixels[location+xPic+1] = g; - pixels[location+xPic+2] = b; - break; - default: - //just so at least something works - for (unsigned int i = 0; i < picComponents; ++i) { - pixels[location+xPic+i] = l; - } - break; - // Possible Error - } + /**Get Extension array, initialised*/ + //static inline const string* getExtensionsPng() { + static inline std::vector getExtensionsPng() { + //static const string extensions[] = {"png", ""}; + static std::vector extensions; + if (extensions.empty() == true) { + extensions.push_back("png"); } + return extensions; } - location += picComponents * width; + + // ===================================================== + // class PNGReader + // ===================================================== + + PNGReader::PNGReader() : FileReader(getExtensionsPng()) { + } + + Pixmap2D* PNGReader::read(ifstream& is, const string& path, Pixmap2D* ret) const { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + + //Read file + is.seekg(0, ios::end); + //size_t length = is.tellg(); + is.seekg(0, ios::beg); + uint8 *buffer = new uint8[8]; + is.read((char*) buffer, 8); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + Shared::PlatformByteOrder::fromEndianTypeArray(buffer, 8); + } + + if (png_sig_cmp(buffer, 0, 8) != 0) { + delete[] buffer; + //This is not a PNG file - could be used for fast checking whether file is supported or not + throw megaglest_runtime_error(path + " is not a png", true); + } + + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) { + delete[] buffer; + throw megaglest_runtime_error(path + " is a corrupt(1) png", true); + } + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); + delete[] buffer; + throw megaglest_runtime_error(path + " is a corrupt(2) png", true); + } + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); + delete[] buffer; + //Error during init_io + throw megaglest_runtime_error(path + " is a corrupt(3) png", true); + } + png_set_read_fn(png_ptr, &is, user_read_data); + png_set_sig_bytes(png_ptr, 8); + png_read_info(png_ptr, info_ptr); + + int width = png_get_image_width(png_ptr, info_ptr); + + int height = png_get_image_height(png_ptr, info_ptr); + int color_type = png_get_color_type(png_ptr, info_ptr); + //int bit_depth = info_ptr->bit_depth; + + //We want RGB, 24 bit + if (color_type == PNG_COLOR_TYPE_PALETTE || + (color_type == PNG_COLOR_TYPE_GRAY && png_get_bit_depth(png_ptr, info_ptr) < 8) || + (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) { + png_set_expand(png_ptr); + } + + if (color_type == PNG_COLOR_TYPE_GRAY) { + png_set_gray_to_rgb(png_ptr); + } + + //int number_of_passes = png_set_interlace_handling(png_ptr); + png_set_interlace_handling(png_ptr); + png_read_update_info(png_ptr, info_ptr); + png_bytep* row_pointers = new png_bytep[height]; + + if (setjmp(png_jmpbuf(png_ptr))) { + delete[] row_pointers; + delete[] buffer; + //error during read_image + throw megaglest_runtime_error(path + " is a corrupt(4) png", true); + } + for (int y = 0; y < height; ++y) { + row_pointers[y] = new png_byte[png_get_rowbytes(png_ptr, info_ptr)]; + } + png_read_image(png_ptr, row_pointers); + size_t fileComponents = png_get_rowbytes(png_ptr, info_ptr) / width; + size_t picComponents = (ret->getComponents() == -1) ? fileComponents : ret->getComponents(); + //std::cout << "PNG-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << fileComponents << std::endl; + //picComponents = 4; + //Copy image + ret->init(width, height, (int) picComponents); + uint8* pixels = ret->getPixels(); + const size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr); + size_t location = 0; + for (int y = height - 1; y >= 0; --y) { //you have to somehow invert the lines + if (picComponents == fileComponents) { + memcpy(pixels + location, row_pointers[y], rowbytes); + } else { + int r, g, b, a, l; + for (size_t xPic = 0, xFile = 0; xFile < rowbytes; xPic += picComponents, xFile += fileComponents) { + switch (fileComponents) { + case 3: + r = row_pointers[y][xFile]; + g = row_pointers[y][xFile + 1]; + b = row_pointers[y][xFile + 2]; + l = (r + g + b + 2) / 3; + a = 255; + break; + case 4: + r = row_pointers[y][xFile]; + g = row_pointers[y][xFile + 1]; + b = row_pointers[y][xFile + 2]; + l = (r + g + b + 2) / 3; + a = row_pointers[y][xFile + 3]; + break; + default: + // Possible Error + case 1: + r = g = b = l = row_pointers[y][xFile]; + a = 255; + break; + } + switch (picComponents) { + case 1: + pixels[location + xPic] = l; + break; + case 4: + pixels[location + xPic + 3] = a; //Next case + case 3: + pixels[location + xPic] = r; + pixels[location + xPic + 1] = g; + pixels[location + xPic + 2] = b; + break; + default: + //just so at least something works + for (unsigned int i = 0; i < picComponents; ++i) { + pixels[location + xPic + i] = l; + } + break; + // Possible Error + } + } + } + location += picComponents * width; + } + + for (int y = 0; y < height; ++y) { + delete[] row_pointers[y]; + } + delete[] row_pointers; + + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); + + delete[] buffer; + + return ret; + } + + + + PNGReader3D::PNGReader3D() : FileReader(getExtensionsPng()) { + } + + Pixmap3D* PNGReader3D::read(ifstream& is, const string& path, Pixmap3D* ret) const { + //Read file + is.seekg(0, ios::end); + //size_t length = is.tellg(); + is.seekg(0, ios::beg); + uint8 *buffer = new uint8[8]; + is.read((char*) buffer, 8); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + Shared::PlatformByteOrder::fromEndianTypeArray(buffer, 8); + } + + if (png_sig_cmp(buffer, 0, 8) != 0) { + delete[] buffer; + //This is not a PNG file - could be used for fast checking whether file is supported or not + throw megaglest_runtime_error(path + " is not a png(2)", true); + } + + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) { + delete[] buffer; + throw megaglest_runtime_error(path + " is a corrupt(5) png", true); + } + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); + delete[] buffer; + throw megaglest_runtime_error(path + " is a corrupt(6) png", true); + } + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); + delete[] buffer; + //Error during init_io + throw megaglest_runtime_error(path + " is a corrupt(7) png", true); + } + png_set_read_fn(png_ptr, &is, user_read_data); + png_set_sig_bytes(png_ptr, 8); + png_read_info(png_ptr, info_ptr); + + int width = png_get_image_width(png_ptr, info_ptr); + int height = png_get_image_height(png_ptr, info_ptr); + int color_type = png_get_color_type(png_ptr, info_ptr); + //int bit_depth = info_ptr->bit_depth; + + //We want RGB, 24 bit + if (color_type == PNG_COLOR_TYPE_PALETTE || + (color_type == PNG_COLOR_TYPE_GRAY && png_get_bit_depth(png_ptr, info_ptr) < 8) || + (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) { + png_set_expand(png_ptr); + } + + if (color_type == PNG_COLOR_TYPE_GRAY) { + png_set_gray_to_rgb(png_ptr); + } + + //int number_of_passes = png_set_interlace_handling(png_ptr); + png_set_interlace_handling(png_ptr); + png_read_update_info(png_ptr, info_ptr); + png_bytep* row_pointers = new png_bytep[height]; + + if (setjmp(png_jmpbuf(png_ptr))) { + delete[] row_pointers; + delete[] buffer; + //error during read_image + throw megaglest_runtime_error(path + " is a corrupt(8) png", true); + } + for (int y = 0; y < height; ++y) { + row_pointers[y] = new png_byte[png_get_rowbytes(png_ptr, info_ptr)]; + } + png_read_image(png_ptr, row_pointers); + size_t fileComponents = png_get_rowbytes(png_ptr, info_ptr) / width; + size_t picComponents = (ret->getComponents() == -1) ? fileComponents : ret->getComponents(); + const int d = ret->getD(); + const int slice = ret->getSlice(); + if (ret->getPixels() == NULL) { + ret->init(width, height, d, (int) picComponents); + } + + //std::cout << "PNG-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << fileComponents << std::endl; + //picComponents = 4; + //Copy image + //printf("pixmap3d loading path [%s] w = %d h = %d d = %d comp = %d\n",path.c_str(),width,height,ret->getD(),picComponents); + uint8* pixels = ret->getPixels(); + if (slice > 0) { + pixels = &pixels[slice*width*height*picComponents]; + } + + const size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr); + size_t location = 0; + for (int y = height - 1; y >= 0; --y) { //you have to somehow invert the lines + if (picComponents == fileComponents) { + memcpy(pixels + location, row_pointers[y], rowbytes); + } else { + int r, g, b, a, l; + for (size_t xPic = 0, xFile = 0; xFile < rowbytes; xPic += picComponents, xFile += fileComponents) { + switch (fileComponents) { + case 3: + r = row_pointers[y][xFile]; + g = row_pointers[y][xFile + 1]; + b = row_pointers[y][xFile + 2]; + l = (r + g + b + 2) / 3; + a = 255; + break; + case 4: + r = row_pointers[y][xFile]; + g = row_pointers[y][xFile + 1]; + b = row_pointers[y][xFile + 2]; + l = (r + g + b + 2) / 3; + a = row_pointers[y][xFile + 3]; + break; + default: + // Possible Error + case 1: + r = g = b = l = row_pointers[y][xFile]; + a = 255; + break; + } + switch (picComponents) { + case 1: + pixels[location + xPic] = l; + break; + case 4: + pixels[location + xPic + 3] = a; //Next case + case 3: + pixels[location + xPic] = r; + pixels[location + xPic + 1] = g; + pixels[location + xPic + 2] = b; + break; + default: + //just so at least something works + for (unsigned int i = 0; i < picComponents; ++i) { + pixels[location + xPic + i] = l; + } + break; + // Possible Error + } + } + } + location += picComponents * width; + } + + for (int y = 0; y < height; ++y) { + delete[] row_pointers[y]; + } + delete[] row_pointers; + + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); + + delete[] buffer; + + return ret; + } + + } - - for (int y = 0; y < height; ++y) { - delete [] row_pointers[y]; - } - delete[] row_pointers; - - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); - - delete [] buffer; - - return ret; -} - - -}} //end namespace +} //end namespace diff --git a/source/shared_lib/sources/graphics/TGAReader.cpp b/source/shared_lib/sources/graphics/TGAReader.cpp index c0099821a..ff44c1312 100644 --- a/source/shared_lib/sources/graphics/TGAReader.cpp +++ b/source/shared_lib/sources/graphics/TGAReader.cpp @@ -19,355 +19,357 @@ using std::runtime_error; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { #pragma pack(push, 1) -/**Copied from pixmap.cpp*/ -// ===================================================== -// Information for reading the targa-file -// ===================================================== -struct TargaFileHeader{ - int8 idLength; - int8 colourMapType; - int8 dataTypeCode; - int16 colourMapOrigin; - int16 colourMapLength; - int8 colourMapDepth; - int16 xOrigin; - int16 yOrigin; - int16 width; - int16 height; - int8 bitsPerPixel; - int8 imageDescriptor; -}; + /**Copied from pixmap.cpp*/ + // ===================================================== + // Information for reading the targa-file + // ===================================================== + struct TargaFileHeader { + int8 idLength; + int8 colourMapType; + int8 dataTypeCode; + int16 colourMapOrigin; + int16 colourMapLength; + int8 colourMapDepth; + int16 xOrigin; + int16 yOrigin; + int16 width; + int16 height; + int8 bitsPerPixel; + int8 imageDescriptor; + }; #pragma pack(pop) -static const int tgaUncompressedRgb= 2; -static const int tgaUncompressedBw= 3; + static const int tgaUncompressedRgb = 2; + static const int tgaUncompressedBw = 3; -// ===================================================== -// class TGAReader -// ===================================================== + // ===================================================== + // class TGAReader + // ===================================================== -/**Get Extension array, initialised*/ -//static inline const string* getExtensionStrings() { -static inline std::vector getExtensionStrings() { - //static const string extensions[] = {"tga", ""}; - static std::vector extensions; - if(extensions.empty() == true) { - extensions.push_back("tga"); - } - - return extensions; -} - -TGAReader3D::TGAReader3D(): FileReader(getExtensionStrings()) {} - -Pixmap3D* TGAReader3D::read(ifstream& in, const string& path, Pixmap3D* ret) const { - //printf("In [%s] line: %d\n",__FILE__,__LINE__); -// try { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - //read header - TargaFileHeader fileHeader; - in.read((char*)&fileHeader, sizeof(TargaFileHeader)); - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - fileHeader.bitsPerPixel = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.bitsPerPixel); - fileHeader.colourMapDepth = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); - fileHeader.colourMapLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); - fileHeader.colourMapOrigin = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapOrigin); - fileHeader.colourMapType = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapType); - fileHeader.dataTypeCode = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.dataTypeCode); - fileHeader.height = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.height); - fileHeader.idLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.idLength); - fileHeader.imageDescriptor = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.imageDescriptor); - fileHeader.width = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.width); - } - - if (!in.good()) { - throw megaglest_runtime_error(path + " could not be read",true); - } - - //check that we can load this tga file - if(fileHeader.idLength!=0){ - throw megaglest_runtime_error(path + ": id field is not 0",true); - } - - if(fileHeader.dataTypeCode!=tgaUncompressedRgb && fileHeader.dataTypeCode!=tgaUncompressedBw){ - throw megaglest_runtime_error(path + ": only uncompressed BW and RGB targa images are supported",true); - } - - //check bits per pixel - if(fileHeader.bitsPerPixel!=8 && fileHeader.bitsPerPixel!=24 && fileHeader.bitsPerPixel!=32){ - throw megaglest_runtime_error(path + ": only 8, 24 and 32 bit targa images are supported",true); - } - - const int h = fileHeader.height; - const int w = fileHeader.width; - const int d = ret->getD(); - const int slice = ret->getSlice(); - const int fileComponents= fileHeader.bitsPerPixel/8; - const int picComponents = (ret->getComponents()==-1)?fileComponents:ret->getComponents(); - //std::cout << "TGA-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << fileComponents << " slice:" << ret->getSlice() << std::endl; - if(ret->getPixels() == NULL){ - ret->init(w,h,d, picComponents); - } - uint8* pixels = ret->getPixels(); - if(slice > 0) { - pixels = &pixels[slice*w*h*picComponents]; - } - //read file - for(int i=0; i getExtensionStrings() { + //static const string extensions[] = {"tga", ""}; + static std::vector extensions; + if (extensions.empty() == true) { + extensions.push_back("tga"); } - else{ - in.read((char*)&b, 1); - if(bigEndianSystem == true) { - b = Shared::PlatformByteOrder::fromCommonEndian(b); - } - in.read((char*)&g, 1); - if(bigEndianSystem == true) { - g = Shared::PlatformByteOrder::fromCommonEndian(g); - } + return extensions; + } - in.read((char*)&r, 1); - if(bigEndianSystem == true) { - r = Shared::PlatformByteOrder::fromCommonEndian(r); - } + TGAReader3D::TGAReader3D() : FileReader(getExtensionStrings()) { + } - if(fileComponents==4){ - in.read((char*)&a, 1); - if(bigEndianSystem == true) { - a = Shared::PlatformByteOrder::fromCommonEndian(a); - } - - } else { - a= 255; - } - l= (r+g+b)/3; + Pixmap3D* TGAReader3D::read(ifstream& in, const string& path, Pixmap3D* ret) const { + //printf("In [%s] line: %d\n",__FILE__,__LINE__); + // try { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); } - //if (!in.good()) { - // return NULL; - //} - switch(picComponents){ - case 1: - pixels[i]= l; - break; - case 3: - pixels[i]= r; - pixels[i+1]= g; - pixels[i+2]= b; - break; - case 4: - pixels[i]= r; - pixels[i+1]= g; - pixels[i+2]= b; - pixels[i+3]= a; - break; + //read header + TargaFileHeader fileHeader; + in.read((char*) &fileHeader, sizeof(TargaFileHeader)); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + fileHeader.bitsPerPixel = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.bitsPerPixel); + fileHeader.colourMapDepth = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapOrigin = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapOrigin); + fileHeader.colourMapType = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapType); + fileHeader.dataTypeCode = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.dataTypeCode); + fileHeader.height = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.height); + fileHeader.idLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.idLength); + fileHeader.imageDescriptor = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.imageDescriptor); + fileHeader.width = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.width); } - } - /*for(int i = 0; i < w*h*picComponents; ++i) { - if (i%39 == 0) std::cout << std::endl; - int first = pixels[i]/16; - if (first < 10) - std:: cout << first; - else - std::cout << (char)('A'+(first-10)); - first = pixels[i]%16; - if (first < 10) - std:: cout << first; - else - std::cout << (char)('A'+(first-10)); - std::cout << " "; - }*/ -// } -// catch(exception& ex) { -// char szBuf[8096]=""; -// snprintf(szBuf,8096,"Error in [%s] on line: %d msg: %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,ex.what()); -// throw megaglest_runtime_error(szBuf); -// } - - return ret; -} - - -TGAReader::TGAReader(): FileReader(getExtensionStrings()) {} - -Pixmap2D* TGAReader::read(ifstream& in, const string& path, Pixmap2D* ret) const { - //printf("In [%s] line: %d\n",__FILE__,__LINE__); - //try { - //read header - TargaFileHeader fileHeader; - in.read((char*)&fileHeader, sizeof(TargaFileHeader)); - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - fileHeader.bitsPerPixel = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.bitsPerPixel); - fileHeader.colourMapDepth = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); - fileHeader.colourMapLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); - fileHeader.colourMapOrigin = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapOrigin); - fileHeader.colourMapType = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapType); - fileHeader.dataTypeCode = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.dataTypeCode); - fileHeader.height = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.height); - fileHeader.idLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.idLength); - fileHeader.imageDescriptor = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.imageDescriptor); - fileHeader.width = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.width); - } - - if (!in.good()) { - throw megaglest_runtime_error(path + " could not be read",true); - } - - //check that we can load this tga file - if(fileHeader.idLength!=0){ - throw megaglest_runtime_error(path + ": id field is not 0",true); - } - - if(fileHeader.dataTypeCode!=tgaUncompressedRgb && fileHeader.dataTypeCode!=tgaUncompressedBw){ - throw megaglest_runtime_error(path + ": only uncompressed BW and RGB targa images are supported",true); - } - - //check bits per pixel - if(fileHeader.bitsPerPixel!=8 && fileHeader.bitsPerPixel!=24 && fileHeader.bitsPerPixel!=32){ - throw megaglest_runtime_error(path + ": only 8, 24 and 32 bit targa images are supported",true); - } - - const int h = fileHeader.height; - const int w = fileHeader.width; - const int fileComponents= fileHeader.bitsPerPixel/8; - const int picComponents = (ret->getComponents()==-1)?fileComponents:ret->getComponents(); - //std::cout << "TGA-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << fileComponents << std::endl; - ret->init(w,h,picComponents); - uint8* pixels = ret->getPixels(); - - //read file - for(int i = 0; i < h*w*picComponents; i += picComponents) { - uint8 r=0, g=0, b=0, a=0, l=0; - - if(fileComponents == 1) { - in.read((char*)&l,1); - if(bigEndianSystem == true) { - l = Shared::PlatformByteOrder::fromCommonEndian(l); - } - - r= l; - g= l; - b= l; - a= 255; - } - else { - uint8 bgra[4] = {0,0,0,0}; - in.read((char*)&bgra[0], fileComponents); - b = bgra[0]; - g = bgra[1]; - r = bgra[2]; - a= 255; - - if(fileComponents == 4) { - a = bgra[3]; - } - - if(bigEndianSystem == true) { - b = Shared::PlatformByteOrder::fromCommonEndian(b); - g = Shared::PlatformByteOrder::fromCommonEndian(g); - r = Shared::PlatformByteOrder::fromCommonEndian(r); - if(fileComponents == 4) { - a = Shared::PlatformByteOrder::fromCommonEndian(a); - } - } - -// in.read((char*)&b, 1); -// if(bigEndianSystem == true) { -// b = Shared::PlatformByteOrder::fromCommonEndian(b); -// } -// -// in.read((char*)&g, 1); -// if(bigEndianSystem == true) { -// g = Shared::PlatformByteOrder::fromCommonEndian(g); -// } -// -// in.read((char*)&r, 1); -// if(bigEndianSystem == true) { -// r = Shared::PlatformByteOrder::fromCommonEndian(r); -// } -// -// if(fileComponents==4){ -// in.read((char*)&a, 1); -// if(bigEndianSystem == true) { -// a = Shared::PlatformByteOrder::fromCommonEndian(a); -// } -// -// } -// else { -// a= 255; -// } - - l = (r+g+b) / 3; - } if (!in.good()) { - return NULL; + throw megaglest_runtime_error(path + " could not be read", true); } - switch(picComponents) { - case 1: - pixels[i]= l; - break; - case 3: - pixels[i]= r; - pixels[i+1]= g; - pixels[i+2]= b; - break; - case 4: - pixels[i]= r; - pixels[i+1]= g; - pixels[i+2]= b; - pixels[i+3]= a; - break; + //check that we can load this tga file + if (fileHeader.idLength != 0) { + throw megaglest_runtime_error(path + ": id field is not 0", true); } + + if (fileHeader.dataTypeCode != tgaUncompressedRgb && fileHeader.dataTypeCode != tgaUncompressedBw) { + throw megaglest_runtime_error(path + ": only uncompressed BW and RGB targa images are supported", true); + } + + //check bits per pixel + if (fileHeader.bitsPerPixel != 8 && fileHeader.bitsPerPixel != 24 && fileHeader.bitsPerPixel != 32) { + throw megaglest_runtime_error(path + ": only 8, 24 and 32 bit targa images are supported", true); + } + + const int h = fileHeader.height; + const int w = fileHeader.width; + const int d = ret->getD(); + const int slice = ret->getSlice(); + const int fileComponents = fileHeader.bitsPerPixel / 8; + const int picComponents = (ret->getComponents() == -1) ? fileComponents : ret->getComponents(); + //std::cout << "TGA-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << fileComponents << " slice:" << ret->getSlice() << std::endl; + if (ret->getPixels() == NULL) { + ret->init(w, h, d, picComponents); + } + uint8* pixels = ret->getPixels(); + if (slice > 0) { + pixels = &pixels[slice*w*h*picComponents]; + } + //read file + for (int i = 0; i < h*w*picComponents; i += picComponents) { + uint8 r = 0, g = 0, b = 0, a = 0, l = 0; + + if (fileComponents == 1) { + in.read((char*) &l, 1); + if (bigEndianSystem == true) { + l = Shared::PlatformByteOrder::fromCommonEndian(l); + } + + r = l; + g = l; + b = l; + a = 255; + } else { + in.read((char*) &b, 1); + if (bigEndianSystem == true) { + b = Shared::PlatformByteOrder::fromCommonEndian(b); + } + + in.read((char*) &g, 1); + if (bigEndianSystem == true) { + g = Shared::PlatformByteOrder::fromCommonEndian(g); + } + + in.read((char*) &r, 1); + if (bigEndianSystem == true) { + r = Shared::PlatformByteOrder::fromCommonEndian(r); + } + + if (fileComponents == 4) { + in.read((char*) &a, 1); + if (bigEndianSystem == true) { + a = Shared::PlatformByteOrder::fromCommonEndian(a); + } + + } else { + a = 255; + } + l = (r + g + b) / 3; + } + //if (!in.good()) { + // return NULL; + //} + + switch (picComponents) { + case 1: + pixels[i] = l; + break; + case 3: + pixels[i] = r; + pixels[i + 1] = g; + pixels[i + 2] = b; + break; + case 4: + pixels[i] = r; + pixels[i + 1] = g; + pixels[i + 2] = b; + pixels[i + 3] = a; + break; + } + } + /*for(int i = 0; i < w*h*picComponents; ++i) { + if (i%39 == 0) std::cout << std::endl; + int first = pixels[i]/16; + if (first < 10) + std:: cout << first; + else + std::cout << (char)('A'+(first-10)); + first = pixels[i]%16; + if (first < 10) + std:: cout << first; + else + std::cout << (char)('A'+(first-10)); + std::cout << " "; + }*/ + + // } + // catch(exception& ex) { + // char szBuf[8096]=""; + // snprintf(szBuf,8096,"Error in [%s] on line: %d msg: %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,ex.what()); + // throw megaglest_runtime_error(szBuf); + // } + + return ret; } - /*for(int i = 0; i < w*h*picComponents; ++i) { - if (i%39 == 0) std::cout << std::endl; - int first = pixels[i]/16; - if (first < 10) - std:: cout << first; - else - std::cout << (char)('A'+(first-10)); - first = pixels[i]%16; - if (first < 10) - std:: cout << first; - else - std::cout << (char)('A'+(first-10)); - std::cout << " "; - }*/ -// } -// catch(exception& ex) { -// //printf("In [%s] line: %d msf [%s]\n",__FILE__,__LINE__,ex.what()); -// //abort(); -// char szBuf[8096]=""; -// snprintf(szBuf,8096,"Error in [%s] on line: %d msg: %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,ex.what()); -// throw megaglest_runtime_error(szBuf); -// } - //printf("In [%s] line: %d\n",__FILE__,__LINE__); - return ret; -} -}} //end namespace + TGAReader::TGAReader() : FileReader(getExtensionStrings()) { + } + + Pixmap2D* TGAReader::read(ifstream& in, const string& path, Pixmap2D* ret) const { + //printf("In [%s] line: %d\n",__FILE__,__LINE__); + //try { + //read header + TargaFileHeader fileHeader; + in.read((char*) &fileHeader, sizeof(TargaFileHeader)); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + fileHeader.bitsPerPixel = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.bitsPerPixel); + fileHeader.colourMapDepth = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapOrigin = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapOrigin); + fileHeader.colourMapType = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapType); + fileHeader.dataTypeCode = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.dataTypeCode); + fileHeader.height = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.height); + fileHeader.idLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.idLength); + fileHeader.imageDescriptor = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.imageDescriptor); + fileHeader.width = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.width); + } + + if (!in.good()) { + throw megaglest_runtime_error(path + " could not be read", true); + } + + //check that we can load this tga file + if (fileHeader.idLength != 0) { + throw megaglest_runtime_error(path + ": id field is not 0", true); + } + + if (fileHeader.dataTypeCode != tgaUncompressedRgb && fileHeader.dataTypeCode != tgaUncompressedBw) { + throw megaglest_runtime_error(path + ": only uncompressed BW and RGB targa images are supported", true); + } + + //check bits per pixel + if (fileHeader.bitsPerPixel != 8 && fileHeader.bitsPerPixel != 24 && fileHeader.bitsPerPixel != 32) { + throw megaglest_runtime_error(path + ": only 8, 24 and 32 bit targa images are supported", true); + } + + const int h = fileHeader.height; + const int w = fileHeader.width; + const int fileComponents = fileHeader.bitsPerPixel / 8; + const int picComponents = (ret->getComponents() == -1) ? fileComponents : ret->getComponents(); + //std::cout << "TGA-Components: Pic: " << picComponents << " old: " << (ret->getComponents()) << " File: " << fileComponents << std::endl; + ret->init(w, h, picComponents); + uint8* pixels = ret->getPixels(); + + //read file + for (int i = 0; i < h*w*picComponents; i += picComponents) { + uint8 r = 0, g = 0, b = 0, a = 0, l = 0; + + if (fileComponents == 1) { + in.read((char*) &l, 1); + if (bigEndianSystem == true) { + l = Shared::PlatformByteOrder::fromCommonEndian(l); + } + + r = l; + g = l; + b = l; + a = 255; + } else { + uint8 bgra[4] = { 0,0,0,0 }; + in.read((char*) &bgra[0], fileComponents); + b = bgra[0]; + g = bgra[1]; + r = bgra[2]; + a = 255; + + if (fileComponents == 4) { + a = bgra[3]; + } + + if (bigEndianSystem == true) { + b = Shared::PlatformByteOrder::fromCommonEndian(b); + g = Shared::PlatformByteOrder::fromCommonEndian(g); + r = Shared::PlatformByteOrder::fromCommonEndian(r); + if (fileComponents == 4) { + a = Shared::PlatformByteOrder::fromCommonEndian(a); + } + } + + // in.read((char*)&b, 1); + // if(bigEndianSystem == true) { + // b = Shared::PlatformByteOrder::fromCommonEndian(b); + // } + // + // in.read((char*)&g, 1); + // if(bigEndianSystem == true) { + // g = Shared::PlatformByteOrder::fromCommonEndian(g); + // } + // + // in.read((char*)&r, 1); + // if(bigEndianSystem == true) { + // r = Shared::PlatformByteOrder::fromCommonEndian(r); + // } + // + // if(fileComponents==4){ + // in.read((char*)&a, 1); + // if(bigEndianSystem == true) { + // a = Shared::PlatformByteOrder::fromCommonEndian(a); + // } + // + // } + // else { + // a= 255; + // } + + l = (r + g + b) / 3; + } + if (!in.good()) { + return NULL; + } + + switch (picComponents) { + case 1: + pixels[i] = l; + break; + case 3: + pixels[i] = r; + pixels[i + 1] = g; + pixels[i + 2] = b; + break; + case 4: + pixels[i] = r; + pixels[i + 1] = g; + pixels[i + 2] = b; + pixels[i + 3] = a; + break; + } + } + /*for(int i = 0; i < w*h*picComponents; ++i) { + if (i%39 == 0) std::cout << std::endl; + int first = pixels[i]/16; + if (first < 10) + std:: cout << first; + else + std::cout << (char)('A'+(first-10)); + first = pixels[i]%16; + if (first < 10) + std:: cout << first; + else + std::cout << (char)('A'+(first-10)); + std::cout << " "; + }*/ + // } + // catch(exception& ex) { + // //printf("In [%s] line: %d msf [%s]\n",__FILE__,__LINE__,ex.what()); + // //abort(); + // char szBuf[8096]=""; + // snprintf(szBuf,8096,"Error in [%s] on line: %d msg: %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,ex.what()); + // throw megaglest_runtime_error(szBuf); + // } + + //printf("In [%s] line: %d\n",__FILE__,__LINE__); + return ret; + } + + } +} //end namespace diff --git a/source/shared_lib/sources/graphics/buffer.cpp b/source/shared_lib/sources/graphics/buffer.cpp index 632a87565..037d07844 100644 --- a/source/shared_lib/sources/graphics/buffer.cpp +++ b/source/shared_lib/sources/graphics/buffer.cpp @@ -9,54 +9,56 @@ #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class VertexBuffer -// ===================================================== + // ===================================================== + // class VertexBuffer + // ===================================================== + + VertexBuffer::VertexBuffer() { + positionPointer = NULL; + normalPointer = NULL; + for (int i = 0; i < texCoordCount; ++i) { + texCoordPointers[i] = NULL; + texCoordCoordCounts[i] = -1; + } + for (int i = 0; i < attribCount; ++i) { + attribPointers[i] = NULL; + attribCoordCounts[i] = -1; + } + } + + void VertexBuffer::setPositionPointer(void *pointer) { + positionPointer = pointer; + } + + void VertexBuffer::setNormalPointer(void *pointer) { + normalPointer = pointer; + } + + void VertexBuffer::setTexCoordPointer(void *pointer, int texCoordIndex, int coordCount) { + texCoordPointers[texCoordIndex] = pointer; + texCoordCoordCounts[texCoordIndex] = coordCount; + } + + void VertexBuffer::setAttribPointer(void *pointer, int attribIndex, int coordCount, const string &name) { + attribPointers[attribIndex] = pointer; + attribCoordCounts[attribIndex] = coordCount; + attribNames[attribIndex] = name; + } + + // ===================================================== + // class IndexBuffer + // ===================================================== + + IndexBuffer::IndexBuffer() { + indexPointer = NULL; + } + + void IndexBuffer::setIndexPointer(void *pointer) { + indexPointer = pointer; + } -VertexBuffer::VertexBuffer(){ - positionPointer= NULL; - normalPointer= NULL; - for(int i= 0; itextHandler = textHandler; - //SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] this->textHandler = [%p] Owner = [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->textHandler,this); - this->widths = new float[Font::charCount]; - this->height = 0; + FontMetrics::FontMetrics(Text *textHandler) { + this->textHandler = textHandler; + //SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] this->textHandler = [%p] Owner = [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->textHandler,this); + this->widths = new float[Font::charCount]; + this->height = 0; - for(int i=0; i < Font::charCount; ++i) { - widths[i]= 0; - } -} + for (int i = 0; i < Font::charCount; ++i) { + widths[i] = 0; + } + } -FontMetrics::~FontMetrics() { - delete [] widths; - widths = NULL; -} + FontMetrics::~FontMetrics() { + delete[] widths; + widths = NULL; + } -void FontMetrics::setTextHandler(Text *textHandler) { - this->textHandler = textHandler; - //SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] this->textHandler = [%p] Owner = [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->textHandler, this); -} + void FontMetrics::setTextHandler(Text *textHandler) { + this->textHandler = textHandler; + //SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] this->textHandler = [%p] Owner = [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->textHandler, this); + } -Text * FontMetrics::getTextHandler() { - return this->textHandler; -} + Text * FontMetrics::getTextHandler() { + return this->textHandler; + } -float FontMetrics::getTextWidth(const string &str) { - string longestLine = ""; - size_t found = str.find("\n"); - if (found == string::npos) { - longestLine = str; - } - else { - vector lineTokens; - Tokenize(str,lineTokens,"\n"); - if(lineTokens.empty() == false) { - for(unsigned int i = 0; i < lineTokens.size(); ++i) { - string currentStr = lineTokens[i]; - if(currentStr.length() > longestLine.length()) { - longestLine = currentStr; + float FontMetrics::getTextWidth(const string &str) { + string longestLine = ""; + size_t found = str.find("\n"); + if (found == string::npos) { + longestLine = str; + } else { + vector lineTokens; + Tokenize(str, lineTokens, "\n"); + if (lineTokens.empty() == false) { + for (unsigned int i = 0; i < lineTokens.size(); ++i) { + string currentStr = lineTokens[i]; + if (currentStr.length() > longestLine.length()) { + longestLine = currentStr; + } + } } } - } - } - if(textHandler != NULL) { - return (textHandler->Advance(longestLine.c_str()) * Font::scaleFontValue); - } - else { - float width= 0.f; - for(unsigned int i=0; i< longestLine.size() && (int)i < Font::charCount; ++i){ - if(longestLine[i] >= Font::charCount) { - string sError = "str[i] >= Font::charCount, [" + longestLine + "] i = " + uIntToStr(i); - throw megaglest_runtime_error(sError); - } - //Treat 2 byte characters as spaces - if(longestLine[i] < 0) { - width+= (widths[97]); // This is the letter a which is a normal wide character and good to use for spacing - } - else { - width+= widths[(int)longestLine[i]]; + if (textHandler != NULL) { + return (textHandler->Advance(longestLine.c_str()) * Font::scaleFontValue); + } else { + float width = 0.f; + for (unsigned int i = 0; i < longestLine.size() && (int) i < Font::charCount; ++i) { + if (longestLine[i] >= Font::charCount) { + string sError = "str[i] >= Font::charCount, [" + longestLine + "] i = " + uIntToStr(i); + throw megaglest_runtime_error(sError); + } + //Treat 2 byte characters as spaces + if (longestLine[i] < 0) { + width += (widths[97]); // This is the letter a which is a normal wide character and good to use for spacing + } else { + width += widths[(int) longestLine[i]]; + } + } + return width; } } - return width; - } -} -float FontMetrics::getHeight(const string &str) const { - if(textHandler != NULL) { - return (textHandler->LineHeight(str.c_str())); - } - else { - return height; - } -} + float FontMetrics::getHeight(const string &str) const { + if (textHandler != NULL) { + return (textHandler->LineHeight(str.c_str())); + } else { + return height; + } + } -string FontMetrics::wordWrapText(string text, int maxWidth) { - // Strip newlines from source - replaceAll(text, "\n", " \n "); + string FontMetrics::wordWrapText(string text, int maxWidth) { + // Strip newlines from source + replaceAll(text, "\n", " \n "); - // Get all words (space separated text) - vector words; - Tokenize(text,words," "); + // Get all words (space separated text) + vector words; + Tokenize(text, words, " "); - string wrappedText = ""; - float lineWidth = 0.0f; + string wrappedText = ""; + float lineWidth = 0.0f; - for(unsigned int i = 0; i < words.size(); ++i) { - string word = words[i]; - if(word=="\n"){ - wrappedText += word; - lineWidth = 0; - } - else { - float wordWidth = this->getTextWidth(word); - if (lineWidth + wordWidth > maxWidth) { - wrappedText += "\n"; - lineWidth = 0; - } - lineWidth += this->getTextWidth(word+" "); - wrappedText += word + " "; - } - } + for (unsigned int i = 0; i < words.size(); ++i) { + string word = words[i]; + if (word == "\n") { + wrappedText += word; + lineWidth = 0; + } else { + float wordWidth = this->getTextWidth(word); + if (lineWidth + wordWidth > maxWidth) { + wrappedText += "\n"; + lineWidth = 0; + } + lineWidth += this->getTextWidth(word + " "); + wrappedText += word + " "; + } + } - return wrappedText; -} + return wrappedText; + } -// =============================================== -// class Font -// =============================================== + // =============================================== + // class Font + // =============================================== -Font::Font(FontTextHandlerType type) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } + Font::Font(FontTextHandlerType type) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } - inited = false; - this->type = fontTypeName; - width = 400; - size = 10; - this->textHandler = NULL; - //SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] this->textHandler = [%p] Owner = [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->textHandler, this); + inited = false; + this->type = fontTypeName; + width = 400; + size = 10; + this->textHandler = NULL; + //SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] this->textHandler = [%p] Owner = [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->textHandler, this); #if defined(USE_FTGL) - if(Font::forceLegacyFonts == false) { - try { + if (Font::forceLegacyFonts == false) { + try { - { - TextFTGL::faceResolution = Font::faceResolution; - TextFTGL::langHeightText = Font::langHeightText; + { + TextFTGL::faceResolution = Font::faceResolution; + TextFTGL::langHeightText = Font::langHeightText; - this->textHandler = NULL; - this->textHandler = new TextFTGL(type); - //SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] this->textHandler = [%p] Owner = [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->textHandler, this); + this->textHandler = NULL; + this->textHandler = new TextFTGL(type); + //SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] this->textHandler = [%p] Owner = [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->textHandler, this); - TextFTGL::faceResolution = Font::faceResolution; - TextFTGL::langHeightText = Font::langHeightText; + TextFTGL::faceResolution = Font::faceResolution; + TextFTGL::langHeightText = Font::langHeightText; + } + + metrics.setTextHandler(this->textHandler); + } catch (exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + textHandler = NULL; + //SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] this->textHandler = [%p] Owner = [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->textHandler, this); + } } - metrics.setTextHandler(this->textHandler); - } - catch(exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - textHandler = NULL; - //SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] this->textHandler = [%p] Owner = [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->textHandler, this); - } - } - #endif -} - -Font::~Font() { - if(this->textHandler) { - delete this->textHandler; - } - this->textHandler = NULL; - metrics.setTextHandler(this->textHandler); - //SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] this->textHandler = [%p] Owner = [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->textHandler, this); -} - -string Font::getType() const { - return this->type; -} - -void Font::setType(string typeX11, string typeGeneric, string typeGenericFamily) { - if(textHandler) { - try { - this->type= typeGeneric; - textHandler->init(typeGeneric,typeGenericFamily,textHandler->GetFaceSize()); - metrics.setTextHandler(this->textHandler); } - catch(exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - textHandler = NULL; + + Font::~Font() { + if (this->textHandler) { + delete this->textHandler; + } + this->textHandler = NULL; + metrics.setTextHandler(this->textHandler); //SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] this->textHandler = [%p] Owner = [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->textHandler, this); } - } - if(textHandler == NULL) { - this->type= typeX11; - } -} -void Font::setWidth(int width) { - this->width= width; -} + string Font::getType() const { + return this->type; + } -int Font::getWidth() const { - return width; -} + void Font::setType(string typeX11, string typeGeneric, string typeGenericFamily) { + if (textHandler) { + try { + this->type = typeGeneric; + textHandler->init(typeGeneric, typeGenericFamily, textHandler->GetFaceSize()); + metrics.setTextHandler(this->textHandler); + } catch (exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + textHandler = NULL; + //SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] this->textHandler = [%p] Owner = [%p]\n", __FILE__, __FUNCTION__, __LINE__, this->textHandler, this); + } + } + if (textHandler == NULL) { + this->type = typeX11; + } + } -int Font::getSize() const { - if(textHandler) { - return textHandler->GetFaceSize(); - } - else { - return size; - } -} -void Font::setSize(int size) { - if(textHandler) { - return textHandler->SetFaceSize(size); - } - else { - this->size= size; - } -} + void Font::setWidth(int width) { + this->width = width; + } -bool is_non_ASCII(const int &c) { - return (c < 0) || (c >= 128); -} -//bool is_ASCII(const int &c) { -// return !is_non_ASCII(c); -//} + int Font::getWidth() const { + return width; + } -void Font::bidi_cvt(string &str_) { + int Font::getSize() const { + if (textHandler) { + return textHandler->GetFaceSize(); + } else { + return size; + } + } + void Font::setSize(int size) { + if (textHandler) { + return textHandler->SetFaceSize(size); + } else { + this->size = size; + } + } + + bool is_non_ASCII(const int &c) { + return (c < 0) || (c >= 128); + } + //bool is_ASCII(const int &c) { + // return !is_non_ASCII(c); + //} + + void Font::bidi_cvt(string &str_) { #ifdef HAVE_FRIBIDI - //const bool debugFribidi = false; - //if(debugFribidi == true) printf("BEFORE: [%s]\n",str_.c_str()); + //const bool debugFribidi = false; + //if(debugFribidi == true) printf("BEFORE: [%s]\n",str_.c_str()); - string new_value = ""; - bool hasSoftNewLines = false; - bool hasHardNewLines = false; - vector lines; + string new_value = ""; + bool hasSoftNewLines = false; + bool hasHardNewLines = false; + vector lines; - if(str_.find("\\n") != str_.npos) { - Tokenize(str_,lines,"\\n"); - hasSoftNewLines = true; - } - else if(str_.find("\n") != str_.npos) { - Tokenize(str_,lines,"\n"); - hasHardNewLines = true; - } - else { - lines.push_back(str_); - } - - //if(debugFribidi == true) printf("Lines: %d\n",(int)lines.size()); - - for(int lineIndex = 0; lineIndex < (int)lines.size(); ++lineIndex) { - if(lineIndex > 0) { - if(hasSoftNewLines == true) { - new_value += "\\n"; + if (str_.find("\\n") != str_.npos) { + Tokenize(str_, lines, "\\n"); + hasSoftNewLines = true; + } else if (str_.find("\n") != str_.npos) { + Tokenize(str_, lines, "\n"); + hasHardNewLines = true; + } else { + lines.push_back(str_); } - else if(hasHardNewLines == true) { - new_value += "\n"; - } - } - str_ = lines[lineIndex]; - //if(debugFribidi == true) printf("Line: %d [%s] Font::fontSupportMixedRightToLeft = %d\n",lineIndex,str_.c_str(),Font::fontSupportMixedRightToLeft); - vector words; - if(Font::fontSupportMixedRightToLeft == true) { - if(str_.find(" ") != str_.npos) { - Tokenize(str_,words," "); + //if(debugFribidi == true) printf("Lines: %d\n",(int)lines.size()); - } - else { - words.push_back(str_); - } - } - else { - words.push_back(str_); - } - - vector wordList; - wordList.reserve(words.size()); - vector nonASCIIWordList; - nonASCIIWordList.reserve(words.size()); - - for(int wordIndex = 0; wordIndex < (int)words.size(); ++wordIndex) { - str_ = words[wordIndex]; - - //if(debugFribidi == true) printf("Word: %d [%s]\n",wordIndex,str_.c_str()); - - //FriBidi C string holding the original text (that is probably with logical hebrew) - //FriBidiChar *logical = NULL; - //FriBidi C string for the output text (that should be visual hebrew) - //FriBidiChar *visual = NULL; - - //FriBidiStrIndex *ltov = NULL; - //FriBidiStrIndex *vtol = NULL; - - //C string holding the originall text (not nnecessarily as unicode) - //char *ip = NULL; - //C string for the output text (not necessarily as unicode) - //char *op = NULL; - - //Size to allocate for the char arrays - int size = (int)str_.size() + 2; - - //Allocate memory: - //It's probably way too much, but at least it's not too little - FriBidiChar *logical = new FriBidiChar[size * 3]; - FriBidiChar *visual = new FriBidiChar[size * 3]; - char *ip = new char[size * 3]; - char *op = new char[size * 3]; - - FriBidiStrIndex *ltov = new FriBidiStrIndex[size * 3]; - FriBidiStrIndex *vtol = new FriBidiStrIndex[size * 3]; - - FriBidiCharType base; - size_t len; - - //A bool type to see if conversion succeded - fribidi_boolean log2vis; - - //Holds information telling fribidi to use UTF-8 - FriBidiCharSet char_set_num; - char_set_num = fribidi_parse_charset ("UTF-8"); - - //Copy the given to string into the ip string - strcpy(ip, str_.c_str()); - - //Find length of originall text - len = strlen( ip ); - - //Insert ip to logical as unicode (and find it's size now) - len = fribidi_charset_to_unicode (char_set_num, ip, (FriBidiStrIndex)len, logical); - - base = FRIBIDI_TYPE_ON; - - //printf("STRIPPED: [%s]\n",str_.c_str()); - - //Convert logical text to visual - log2vis = fribidi_log2vis (logical, (FriBidiStrIndex)len, &base, visual, ltov, vtol, NULL); - - bool is_converted = false; - //If convertion was successful - if(log2vis) - { - //Remove bidi marks (that we don't need) from the output text - len = fribidi_remove_bidi_marks (visual, (FriBidiStrIndex)len, ltov, vtol, NULL); - - //Convert unicode string back to the encoding the input string was in - fribidi_unicode_to_charset ( char_set_num, visual, (FriBidiStrIndex)len ,op); - - if(string(op) != str_) { - is_converted = true; + for (int lineIndex = 0; lineIndex < (int) lines.size(); ++lineIndex) { + if (lineIndex > 0) { + if (hasSoftNewLines == true) { + new_value += "\\n"; + } else if (hasHardNewLines == true) { + new_value += "\n"; + } } - //Insert the output string into the result - str_ = op; + str_ = lines[lineIndex]; + //if(debugFribidi == true) printf("Line: %d [%s] Font::fontSupportMixedRightToLeft = %d\n",lineIndex,str_.c_str(),Font::fontSupportMixedRightToLeft); - //if(debugFribidi == true) printf("LOG2VIS: [%s]\n",str_.c_str()); - } - //printf("AFTER: [%s]\n",str_.c_str()); + vector words; + if (Font::fontSupportMixedRightToLeft == true) { + if (str_.find(" ") != str_.npos) { + Tokenize(str_, words, " "); - //Free allocated memory - delete [] ltov; - delete [] vtol; - delete [] visual; - delete [] logical; - delete [] ip; - delete [] op; + } else { + words.push_back(str_); + } + } else { + words.push_back(str_); + } - if(Font::fontSupportMixedRightToLeft == true) { - if(is_converted == true) { - nonASCIIWordList.push_back(str_); + vector wordList; + wordList.reserve(words.size()); + vector nonASCIIWordList; + nonASCIIWordList.reserve(words.size()); + + for (int wordIndex = 0; wordIndex < (int) words.size(); ++wordIndex) { + str_ = words[wordIndex]; + + //if(debugFribidi == true) printf("Word: %d [%s]\n",wordIndex,str_.c_str()); + + //FriBidi C string holding the original text (that is probably with logical hebrew) + //FriBidiChar *logical = NULL; + //FriBidi C string for the output text (that should be visual hebrew) + //FriBidiChar *visual = NULL; + + //FriBidiStrIndex *ltov = NULL; + //FriBidiStrIndex *vtol = NULL; + + //C string holding the originall text (not nnecessarily as unicode) + //char *ip = NULL; + //C string for the output text (not necessarily as unicode) + //char *op = NULL; + + //Size to allocate for the char arrays + int size = (int) str_.size() + 2; + + //Allocate memory: + //It's probably way too much, but at least it's not too little + FriBidiChar *logical = new FriBidiChar[size * 3]; + FriBidiChar *visual = new FriBidiChar[size * 3]; + char *ip = new char[size * 3]; + char *op = new char[size * 3]; + + FriBidiStrIndex *ltov = new FriBidiStrIndex[size * 3]; + FriBidiStrIndex *vtol = new FriBidiStrIndex[size * 3]; + + FriBidiCharType base; + size_t len; + + //A bool type to see if conversion succeded + fribidi_boolean log2vis; + + //Holds information telling fribidi to use UTF-8 + FriBidiCharSet char_set_num; + char_set_num = fribidi_parse_charset("UTF-8"); + + //Copy the given to string into the ip string + strcpy(ip, str_.c_str()); + + //Find length of originall text + len = strlen(ip); + + //Insert ip to logical as unicode (and find it's size now) + len = fribidi_charset_to_unicode(char_set_num, ip, (FriBidiStrIndex) len, logical); + + base = FRIBIDI_TYPE_ON; + + //printf("STRIPPED: [%s]\n",str_.c_str()); + + //Convert logical text to visual + log2vis = fribidi_log2vis(logical, (FriBidiStrIndex) len, &base, visual, ltov, vtol, NULL); + + bool is_converted = false; + //If convertion was successful + if (log2vis) { + //Remove bidi marks (that we don't need) from the output text + len = fribidi_remove_bidi_marks(visual, (FriBidiStrIndex) len, ltov, vtol, NULL); + + //Convert unicode string back to the encoding the input string was in + fribidi_unicode_to_charset(char_set_num, visual, (FriBidiStrIndex) len, op); + + if (string(op) != str_) { + is_converted = true; + } + //Insert the output string into the result + str_ = op; + + //if(debugFribidi == true) printf("LOG2VIS: [%s]\n",str_.c_str()); + } + //printf("AFTER: [%s]\n",str_.c_str()); + + //Free allocated memory + delete[] ltov; + delete[] vtol; + delete[] visual; + delete[] logical; + delete[] ip; + delete[] op; + + if (Font::fontSupportMixedRightToLeft == true) { + if (is_converted == true) { + nonASCIIWordList.push_back(str_); + + if (wordIndex + 1 == (int) words.size()) { + if (nonASCIIWordList.size() > 1) { + std::reverse(nonASCIIWordList.begin(), nonASCIIWordList.end()); + copy(nonASCIIWordList.begin(), nonASCIIWordList.end(), std::inserter(wordList, wordList.begin())); + } else { + if (wordList.empty() == false) { + copy(nonASCIIWordList.begin(), nonASCIIWordList.end(), std::inserter(wordList, wordList.begin() + wordList.size())); + } else { + wordList = nonASCIIWordList; + } + } + } + } else { + if (nonASCIIWordList.size() > 1) { + std::reverse(nonASCIIWordList.begin(), nonASCIIWordList.end()); + } - if(wordIndex+1 == (int)words.size()) { - if(nonASCIIWordList.size() > 1) { - std::reverse(nonASCIIWordList.begin(),nonASCIIWordList.end()); copy(nonASCIIWordList.begin(), nonASCIIWordList.end(), std::inserter(wordList, wordList.begin())); + nonASCIIWordList.clear(); + wordList.push_back(str_); } - else { - if(wordList.empty() == false) { - copy(nonASCIIWordList.begin(), nonASCIIWordList.end(), std::inserter(wordList, wordList.begin()+wordList.size())); - } - else { - wordList = nonASCIIWordList; - } - } + } else { + wordList.push_back(str_); } } - else { - if(nonASCIIWordList.size() > 1) { - std::reverse(nonASCIIWordList.begin(),nonASCIIWordList.end()); + + //if(debugFribidi == true) printf("Building New Line: %d [%s]\n",lineIndex,new_value.c_str()); + for (int wordIndex = 0; wordIndex < (int) wordList.size(); ++wordIndex) { + //if(debugFribidi == true) printf("wordIndex: %d [%s]\n",wordIndex,wordList[wordIndex].c_str()); + if (wordIndex > 0) { + new_value += " "; } - - copy(nonASCIIWordList.begin(), nonASCIIWordList.end(), std::inserter(wordList, wordList.begin())); - nonASCIIWordList.clear(); - wordList.push_back(str_); + new_value += wordList[wordIndex]; } + //if(debugFribidi == true) printf("New Line: %d [%s]\n",lineIndex,new_value.c_str()); } - else { - wordList.push_back(str_); - } - } - - //if(debugFribidi == true) printf("Building New Line: %d [%s]\n",lineIndex,new_value.c_str()); - for(int wordIndex = 0; wordIndex < (int)wordList.size(); ++wordIndex) { - //if(debugFribidi == true) printf("wordIndex: %d [%s]\n",wordIndex,wordList[wordIndex].c_str()); - if(wordIndex > 0) { - new_value += " "; - } - new_value += wordList[wordIndex]; - } - //if(debugFribidi == true) printf("New Line: %d [%s]\n",lineIndex,new_value.c_str()); - } - str_ = new_value; - //if(debugFribidi == true) printf("NEW: [%s]\n",str_.c_str()); + str_ = new_value; + //if(debugFribidi == true) printf("NEW: [%s]\n",str_.c_str()); #endif -} + } -// =============================================== -// class Font2D -// =============================================== + // =============================================== + // class Font2D + // =============================================== -Font2D::Font2D(FontTextHandlerType type) : Font(type) { -} + Font2D::Font2D(FontTextHandlerType type) : Font(type) { + } -// =============================================== -// class Font3D -// =============================================== + // =============================================== + // class Font3D + // =============================================== -Font3D::Font3D(FontTextHandlerType type) : Font(type) { - depth= 10.f; -} + Font3D::Font3D(FontTextHandlerType type) : Font(type) { + depth = 10.f; + } -string findFontFamily(const char* font, const char *fontFamily) { - string resultFile = ""; + string findFontFamily(const char* font, const char *fontFamily) { + string resultFile = ""; - // If your compiler has a version older than 2.4.1 of fontconfig, you can tell cmake to - // disable trying to use fontconfig via passing this to cmake: - // -DWANT_FONTCONFIG=Off + // If your compiler has a version older than 2.4.1 of fontconfig, you can tell cmake to + // disable trying to use fontconfig via passing this to cmake: + // -DWANT_FONTCONFIG=Off #ifdef HAVE_FONTCONFIG // Get default font via fontconfig - if( !font && FcInit() && fontFamily) { - FcResult result; - FcFontSet *fs; - FcPattern* pat; - FcPattern *match; + if (!font && FcInit() && fontFamily) { + FcResult result; + FcFontSet *fs; + FcPattern* pat; + FcPattern *match; - /* - TRANSLATORS: If using the FTGL backend, this should be the font - name of a font that contains all the Unicode characters in use in - your translation. - */ - //pat = FcNameParse((FcChar8 *)"Gothic Uralic"); - pat = FcNameParse((FcChar8 *)fontFamily); - FcConfigSubstitute(0, pat, FcMatchPattern); + /* + TRANSLATORS: If using the FTGL backend, this should be the font + name of a font that contains all the Unicode characters in use in + your translation. + */ + //pat = FcNameParse((FcChar8 *)"Gothic Uralic"); + pat = FcNameParse((FcChar8 *) fontFamily); + FcConfigSubstitute(0, pat, FcMatchPattern); - //FcPatternDel(pat, FC_WEIGHT); - //FcPatternAddInteger(pat, FC_WEIGHT, FC_WEIGHT_BOLD); + //FcPatternDel(pat, FC_WEIGHT); + //FcPatternAddInteger(pat, FC_WEIGHT, FC_WEIGHT_BOLD); - FcDefaultSubstitute(pat); - fs = FcFontSetCreate(); - match = FcFontMatch(0, pat, &result); + FcDefaultSubstitute(pat); + fs = FcFontSetCreate(); + match = FcFontMatch(0, pat, &result); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Trying fontconfig for fontfamily [%s]\n",fontFamily); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Trying fontconfig for fontfamily [%s]\n", fontFamily); - if (match) FcFontSetAdd(fs, match); - if (pat) FcPatternDestroy(pat); - if(fs) { - FcChar8* file; - if( FcPatternGetString (fs->fonts[0], FC_FILE, 0, &file) == FcResultMatch ) { - resultFile = (const char*)file; + if (match) FcFontSetAdd(fs, match); + if (pat) FcPatternDestroy(pat); + if (fs) { + FcChar8* file; + if (FcPatternGetString(fs->fonts[0], FC_FILE, 0, &file) == FcResultMatch) { + resultFile = (const char*) file; + } + FcFontSetDestroy(fs); + } + // If your compiler has a version older than 2.4.1 of fontconfig, you can tell cmake to + // disable trying to use fontconfig via passing this to cmake: + // -DWANT_FONTCONFIG=Off + FcFini(); + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("******************* FONT CONFIG will not be called font [%s] fontFamily [%s]!\n", (font != NULL ? font : "null"), (fontFamily != NULL ? fontFamily : "null")); } - FcFontSetDestroy(fs); - } - // If your compiler has a version older than 2.4.1 of fontconfig, you can tell cmake to - // disable trying to use fontconfig via passing this to cmake: - // -DWANT_FONTCONFIG=Off - FcFini(); - } - else { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("******************* FONT CONFIG will not be called font [%s] fontFamily [%s]!\n",(font != NULL ? font : "null"),(fontFamily != NULL ? fontFamily : "null")); - } #else - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("******************* NO FONT CONFIG ENABLED!\n"); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("******************* NO FONT CONFIG ENABLED!\n"); #endif - return resultFile; -} + return resultFile; + } -void CHECK_FONT_PATH(const char *filename,const char *fontFamily,const char **font,const char **path) { - *path = filename; - if( *font == NULL && *path != NULL && strlen(*path) > 0 && fileExists(*path) == true ) { - *font = strdup(*path); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 candidate font file exists [%s]\n",(*font != NULL ? *font : "null")); - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 Searching for font file [%s] result [%s]\n",(*path != NULL ? *path : "null"),(*font != NULL ? *font : "null")); - if( *font == NULL && fontFamily != NULL && strlen(fontFamily) > 0) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 Searching for font [%s] family [%s]\n",(*font != NULL ? *font : "null"),fontFamily); - string fileFound = findFontFamily(*font, fontFamily); - if(fileFound != "") { - //*path = fileFound.c_str(); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 candidate font file found [%s]\n",fileFound.c_str()); - if( fileFound.length() > 0 && fileExists(fileFound) == true ) { - if(*font) free((void*)*font); - *font = strdup(fileFound.c_str()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 candidate font file has been set[%s]\n",(*font != NULL ? *font : "null")); + void CHECK_FONT_PATH(const char *filename, const char *fontFamily, const char **font, const char **path) { + *path = filename; + if (*font == NULL && *path != NULL && strlen(*path) > 0 && fileExists(*path) == true) { + *font = strdup(*path); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 candidate font file exists [%s]\n", (*font != NULL ? *font : "null")); } - *path = NULL; - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 Searching for font family [%s] result [%s]\n",fontFamily,(*font != NULL ? *font : "null")); - } -} - -const char* findFont(const char *firstFontToTry,const char *firstFontFamilyToTry) { - const char* font = NULL; - const char* path = NULL; - - - string tryFont = ""; - if(firstFontToTry != NULL || firstFontFamilyToTry != NULL) { - if(firstFontToTry != NULL && strlen(firstFontToTry) > 0) { - tryFont = firstFontToTry; - #ifdef WIN32 - replaceAll(tryFont, "/", "\\"); - #endif - - - CHECK_FONT_PATH(tryFont.c_str(),firstFontFamilyToTry,&font,&path); - } - else { - CHECK_FONT_PATH(NULL,firstFontFamilyToTry,&font,&path); - } - } - - // Get user-specified font path - string megaglest_font = safeCharPtrCopy(getenv("MEGAGLEST_FONT"),8095); - string megaglest_font_family = safeCharPtrCopy(getenv("MEGAGLEST_FONT_FAMILY"),8095); - if(megaglest_font != "" || megaglest_font_family != "") { - if(megaglest_font != "") { - tryFont = megaglest_font; - - if(Text::DEFAULT_FONT_PATH_ABSOLUTE != "") { - tryFont = Text::DEFAULT_FONT_PATH_ABSOLUTE + "/" + extractFileFromDirectoryPath(tryFont); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 Searching for font file [%s] result [%s]\n", (*path != NULL ? *path : "null"), (*font != NULL ? *font : "null")); + if (*font == NULL && fontFamily != NULL && strlen(fontFamily) > 0) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 Searching for font [%s] family [%s]\n", (*font != NULL ? *font : "null"), fontFamily); + string fileFound = findFontFamily(*font, fontFamily); + if (fileFound != "") { + //*path = fileFound.c_str(); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 candidate font file found [%s]\n", fileFound.c_str()); + if (fileFound.length() > 0 && fileExists(fileFound) == true) { + if (*font) free((void*) *font); + *font = strdup(fileFound.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 candidate font file has been set[%s]\n", (*font != NULL ? *font : "null")); + } + *path = NULL; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("#2 Searching for font family [%s] result [%s]\n", fontFamily, (*font != NULL ? *font : "null")); } - #ifdef WIN32 - replaceAll(tryFont, "/", "\\"); - #endif - - CHECK_FONT_PATH(tryFont.c_str(),megaglest_font_family.c_str(),&font,&path); } - else { - CHECK_FONT_PATH(NULL,megaglest_font_family.c_str(),&font,&path); - } - } - string data_path = Text::DEFAULT_FONT_PATH; - string defaultFont = data_path + "data/core/fonts/LinBiolinum_RB.ttf";//LinBiolinum_Re-0.6.4.ttf - if(Text::DEFAULT_FONT_PATH_ABSOLUTE != "") { - data_path = Text::DEFAULT_FONT_PATH; - defaultFont = data_path + "/LinBiolinum_RB.ttf";//LinBiolinum_Re-0.6.4.ttf - } - tryFont = defaultFont; - #ifdef WIN32 - replaceAll(tryFont, "/", "\\"); - #endif - CHECK_FONT_PATH(tryFont.c_str(),"Linux Biolinum O:style=Bold",&font,&path); + const char* findFont(const char *firstFontToTry, const char *firstFontFamilyToTry) { + const char* font = NULL; + const char* path = NULL; - #ifdef FONT_PATH - // Get distro-specified font path - CHECK_FONT_PATH(FONT_PATH,NULL,&font,&path); - #endif - CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothub__.ttf","Gothic Uralic:style=Regular",&font,&path); + string tryFont = ""; + if (firstFontToTry != NULL || firstFontFamilyToTry != NULL) { + if (firstFontToTry != NULL && strlen(firstFontToTry) > 0) { + tryFont = firstFontToTry; +#ifdef WIN32 + replaceAll(tryFont, "/", "\\"); +#endif - // Check a couple of common paths for Gothic Uralic/bold as a last resort - // Debian - /* - TRANSLATORS: If using the FTGL backend, this should be the path of a bold - font that contains all the Unicode characters in use in your translation. - If the font is available in Debian it should be the Debian path. - */ - CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothub__.ttf","Gothic Uralic:style=Regular",&font,&path); - /* - TRANSLATORS: If using the FTGL backend, this should be the path of a - font that contains all the Unicode characters in use in your translation. - If the font is available in Debian it should be the Debian path. - */ - CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothu___.ttf","Gothic Uralic:style=Regular",&font,&path); - // Mandrake - /* - TRANSLATORS: If using the FTGL backend, this should be the path of a bold - font that contains all the Unicode characters in use in your translation. - If the font is available in Mandrake it should be the Mandrake path. - */ - CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHUB__.TTF","Gothic Uralic:style=Bold",&font,&path); - /* - TRANSLATORS: If using the FTGL backend, this should be the path of a - font that contains all the Unicode characters in use in your translation. - If the font is available in Mandrake it should be the Mandrake path. - */ - CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHU___.TTF","Gothic Uralic:style=Regular",&font,&path); - // Check the non-translated versions of the above - CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothub__.ttf","Gothic Uralic:style=Regular",&font,&path); - CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothu___.ttf","Gothic Uralic:style=Regular",&font,&path); - CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHUB__.TTF","Gothic Uralic:style=Regular",&font,&path); - CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHU___.TTF","Gothic Uralic:style=Regular",&font,&path); + CHECK_FONT_PATH(tryFont.c_str(), firstFontFamilyToTry, &font, &path); + } else { + CHECK_FONT_PATH(NULL, firstFontFamilyToTry, &font, &path); + } + } - CHECK_FONT_PATH("/usr/share/fonts/truetype/linux-libertine/LinLibertine_Re.ttf","Linux Libertine O:style=Regular",&font,&path); + // Get user-specified font path + string megaglest_font = safeCharPtrCopy(getenv("MEGAGLEST_FONT"), 8095); + string megaglest_font_family = safeCharPtrCopy(getenv("MEGAGLEST_FONT_FAMILY"), 8095); + if (megaglest_font != "" || megaglest_font_family != "") { + if (megaglest_font != "") { + tryFont = megaglest_font; - CHECK_FONT_PATH("/usr/share/fonts/truetype/freefont/FreeSerif.ttf","FreeSerif",&font,&path); - CHECK_FONT_PATH("/usr/share/fonts/truetype/freefont/FreeSans.ttf","FreeSans",&font,&path); - CHECK_FONT_PATH("/usr/share/fonts/truetype/freefont/FreeMono.ttf","FreeMono",&font,&path); + if (Text::DEFAULT_FONT_PATH_ABSOLUTE != "") { + tryFont = Text::DEFAULT_FONT_PATH_ABSOLUTE + "/" + extractFileFromDirectoryPath(tryFont); + } +#ifdef WIN32 + replaceAll(tryFont, "/", "\\"); +#endif - //openSUSE - CHECK_FONT_PATH("/usr/share/fonts/truetype/LinBiolinum_RB.otf","Bold",&font,&path); - CHECK_FONT_PATH("/usr/share/fonts/truetype/FreeSerif.ttf","FreeSerif",&font,&path); - CHECK_FONT_PATH("/usr/share/fonts/truetype/FreeSans.ttf","FreeSans",&font,&path); - CHECK_FONT_PATH("/usr/share/fonts/truetype/FreeMono.ttf","FreeMono",&font,&path); + CHECK_FONT_PATH(tryFont.c_str(), megaglest_font_family.c_str(), &font, &path); + } else { + CHECK_FONT_PATH(NULL, megaglest_font_family.c_str(), &font, &path); + } + } - // gentoo paths - CHECK_FONT_PATH("/usr/share/fonts/freefont-ttf/FreeSerif.ttf","FreeSerif",&font,&path); - CHECK_FONT_PATH("/usr/share/fonts/freefont-ttf/FreeSans.ttf","FreeSans",&font,&path); - CHECK_FONT_PATH("/usr/share/fonts/freefont-ttf/FreeMono.ttf","FreeMono",&font,&path); + string data_path = Text::DEFAULT_FONT_PATH; + string defaultFont = data_path + "data/core/fonts/LinBiolinum_RB.ttf";//LinBiolinum_Re-0.6.4.ttf + if (Text::DEFAULT_FONT_PATH_ABSOLUTE != "") { + data_path = Text::DEFAULT_FONT_PATH; + defaultFont = data_path + "/LinBiolinum_RB.ttf";//LinBiolinum_Re-0.6.4.ttf + } + tryFont = defaultFont; +#ifdef WIN32 + replaceAll(tryFont, "/", "\\"); +#endif + CHECK_FONT_PATH(tryFont.c_str(), "Linux Biolinum O:style=Bold", &font, &path); + +#ifdef FONT_PATH + // Get distro-specified font path + CHECK_FONT_PATH(FONT_PATH, NULL, &font, &path); +#endif + + CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothub__.ttf", "Gothic Uralic:style=Regular", &font, &path); + + // Check a couple of common paths for Gothic Uralic/bold as a last resort + // Debian + /* + TRANSLATORS: If using the FTGL backend, this should be the path of a bold + font that contains all the Unicode characters in use in your translation. + If the font is available in Debian it should be the Debian path. + */ + CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothub__.ttf", "Gothic Uralic:style=Regular", &font, &path); + /* + TRANSLATORS: If using the FTGL backend, this should be the path of a + font that contains all the Unicode characters in use in your translation. + If the font is available in Debian it should be the Debian path. + */ + CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothu___.ttf", "Gothic Uralic:style=Regular", &font, &path); + // Mandrake + /* + TRANSLATORS: If using the FTGL backend, this should be the path of a bold + font that contains all the Unicode characters in use in your translation. + If the font is available in Mandrake it should be the Mandrake path. + */ + CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHUB__.TTF", "Gothic Uralic:style=Bold", &font, &path); + /* + TRANSLATORS: If using the FTGL backend, this should be the path of a + font that contains all the Unicode characters in use in your translation. + If the font is available in Mandrake it should be the Mandrake path. + */ + CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHU___.TTF", "Gothic Uralic:style=Regular", &font, &path); + + // Check the non-translated versions of the above + CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothub__.ttf", "Gothic Uralic:style=Regular", &font, &path); + CHECK_FONT_PATH("/usr/share/fonts/truetype/uralic/gothu___.ttf", "Gothic Uralic:style=Regular", &font, &path); + CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHUB__.TTF", "Gothic Uralic:style=Regular", &font, &path); + CHECK_FONT_PATH("/usr/share/fonts/TTF/uralic/GOTHU___.TTF", "Gothic Uralic:style=Regular", &font, &path); + + CHECK_FONT_PATH("/usr/share/fonts/truetype/linux-libertine/LinLibertine_Re.ttf", "Linux Libertine O:style=Regular", &font, &path); + + CHECK_FONT_PATH("/usr/share/fonts/truetype/freefont/FreeSerif.ttf", "FreeSerif", &font, &path); + CHECK_FONT_PATH("/usr/share/fonts/truetype/freefont/FreeSans.ttf", "FreeSans", &font, &path); + CHECK_FONT_PATH("/usr/share/fonts/truetype/freefont/FreeMono.ttf", "FreeMono", &font, &path); + + //openSUSE + CHECK_FONT_PATH("/usr/share/fonts/truetype/LinBiolinum_RB.otf", "Bold", &font, &path); + CHECK_FONT_PATH("/usr/share/fonts/truetype/FreeSerif.ttf", "FreeSerif", &font, &path); + CHECK_FONT_PATH("/usr/share/fonts/truetype/FreeSans.ttf", "FreeSans", &font, &path); + CHECK_FONT_PATH("/usr/share/fonts/truetype/FreeMono.ttf", "FreeMono", &font, &path); + + // gentoo paths + CHECK_FONT_PATH("/usr/share/fonts/freefont-ttf/FreeSerif.ttf", "FreeSerif", &font, &path); + CHECK_FONT_PATH("/usr/share/fonts/freefont-ttf/FreeSans.ttf", "FreeSans", &font, &path); + CHECK_FONT_PATH("/usr/share/fonts/freefont-ttf/FreeMono.ttf", "FreeMono", &font, &path); #ifdef _WIN32 - CHECK_FONT_PATH("c:\\windows\\fonts\\verdana.ttf",NULL,&font,&path); - CHECK_FONT_PATH("c:\\windows\\fonts\\tahoma.ttf",NULL,&font,&path); - CHECK_FONT_PATH("c:\\windows\\fonts\\arial.ttf",NULL,&font,&path); - CHECK_FONT_PATH("\\windows\\fonts\\arial.ttf",NULL,&font,&path); + CHECK_FONT_PATH("c:\\windows\\fonts\\verdana.ttf", NULL, &font, &path); + CHECK_FONT_PATH("c:\\windows\\fonts\\tahoma.ttf", NULL, &font, &path); + CHECK_FONT_PATH("c:\\windows\\fonts\\arial.ttf", NULL, &font, &path); + CHECK_FONT_PATH("\\windows\\fonts\\arial.ttf", NULL, &font, &path); #endif - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Final selection of font file is [%s]\n",(font != NULL ? font : "null")); \ + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Final selection of font file is [%s]\n", (font != NULL ? font : "null")); \ - return font; -} + return font; + } -}}//end namespace + } +}//end namespace diff --git a/source/shared_lib/sources/graphics/font_manager.cpp b/source/shared_lib/sources/graphics/font_manager.cpp index 9835f6fbb..b6334d593 100644 --- a/source/shared_lib/sources/graphics/font_manager.cpp +++ b/source/shared_lib/sources/graphics/font_manager.cpp @@ -21,71 +21,73 @@ using namespace Shared::Platform; using namespace Shared::Util; -namespace Shared { namespace Graphics { +namespace Shared { + namespace Graphics { -// ===================================================== -// class FontManager -// ===================================================== -FontManager::FontManager() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - fonts.clear(); -} + // ===================================================== + // class FontManager + // ===================================================== + FontManager::FontManager() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + fonts.clear(); + } -FontManager::~FontManager() { - end(); -} + FontManager::~FontManager() { + end(); + } -Font2D *FontManager::newFont2D() { - Font2D *font= GraphicsInterface::getInstance().getFactory()->newFont2D(); - fonts.push_back(font); - return font; -} + Font2D *FontManager::newFont2D() { + Font2D *font = GraphicsInterface::getInstance().getFactory()->newFont2D(); + fonts.push_back(font); + return font; + } -Font3D *FontManager::newFont3D() { - Font3D *font= GraphicsInterface::getInstance().getFactory()->newFont3D(); - fonts.push_back(font); - return font; -} + Font3D *FontManager::newFont3D() { + Font3D *font = GraphicsInterface::getInstance().getFactory()->newFont3D(); + fonts.push_back(font); + return font; + } -void FontManager::endFont(Font *font,bool mustExistInList) { - if(font != NULL) { - bool found = false; - for(unsigned int i=0; i < fonts.size(); ++i) { - if(fonts[i] != NULL && font == fonts[i]) { - found = true; - fonts.erase(fonts.begin() + i); - break; + void FontManager::endFont(Font *font, bool mustExistInList) { + if (font != NULL) { + bool found = false; + for (unsigned int i = 0; i < fonts.size(); ++i) { + if (fonts[i] != NULL && font == fonts[i]) { + found = true; + fonts.erase(fonts.begin() + i); + break; + } + } + if (found == false && mustExistInList == true) { + throw std::runtime_error("found == false in endFont"); + } + if (found == true) { + font->end(); + delete font; + } } } - if(found == false && mustExistInList == true) { - throw std::runtime_error("found == false in endFont"); - } - if(found == true) { - font->end(); - delete font; - } - } -} -void FontManager::init() { - for(size_t i=0; iinit(); + void FontManager::init() { + for (size_t i = 0; i < fonts.size(); ++i) { + if (fonts[i] != NULL) { + fonts[i]->init(); + } + } } - } -} -void FontManager::end() { - for(size_t i=0; iend(); - delete fonts[i]; - fonts[i]=NULL; + void FontManager::end() { + for (size_t i = 0; i < fonts.size(); ++i) { + if (fonts[i] != NULL) { + fonts[i]->end(); + delete fonts[i]; + fonts[i] = NULL; + } + } + fonts.clear(); } - } - fonts.clear(); -} -}}//end namespace + } +}//end namespace diff --git a/source/shared_lib/sources/graphics/font_text.cpp b/source/shared_lib/sources/graphics/font_text.cpp index 4b969b4d9..cfef5ad3d 100644 --- a/source/shared_lib/sources/graphics/font_text.cpp +++ b/source/shared_lib/sources/graphics/font_text.cpp @@ -19,13 +19,28 @@ std::string Text::DEFAULT_FONT_PATH_ABSOLUTE = ""; Text::Text(FontTextHandlerType type) { this->type = type; } -Text::~Text() {} -void Text::init(string fontName, string fontFamilyName, int fontSize) {} -void Text::Render(const char*, const int) {} -float Text::Advance(const char*, const int) {return 0;} -float Text::LineHeight(const char*, const int) {return 0;} -void Text::Render(const wchar_t*, const int) {} -float Text::Advance(const wchar_t*, const int) {return 0;} -float Text::LineHeight(const wchar_t*, const int) {return 0;} -void Text::SetFaceSize(int) {} -int Text::GetFaceSize() {return 0;} +Text::~Text() { +} +void Text::init(string fontName, string fontFamilyName, int fontSize) { +} +void Text::Render(const char*, const int) { +} +float Text::Advance(const char*, const int) { + return 0; +} +float Text::LineHeight(const char*, const int) { + return 0; +} +void Text::Render(const wchar_t*, const int) { +} +float Text::Advance(const wchar_t*, const int) { + return 0; +} +float Text::LineHeight(const wchar_t*, const int) { + return 0; +} +void Text::SetFaceSize(int) { +} +int Text::GetFaceSize() { + return 0; +} diff --git a/source/shared_lib/sources/graphics/gl/base_renderer.cpp b/source/shared_lib/sources/graphics/gl/base_renderer.cpp index 0487985ba..d85367ebb 100644 --- a/source/shared_lib/sources/graphics/gl/base_renderer.cpp +++ b/source/shared_lib/sources/graphics/gl/base_renderer.cpp @@ -18,191 +18,192 @@ using namespace Shared::Graphics; using namespace Shared::Graphics::Gl; -namespace Shared { namespace Graphics { +namespace Shared { + namespace Graphics { -// =============================================== -// class Renderer -// =============================================== + // =============================================== + // class Renderer + // =============================================== -void BaseRenderer::initMapSurface(int clientW, int clientH) { - assertGl(); + void BaseRenderer::initMapSurface(int clientW, int clientH) { + assertGl(); - glFrontFace(GL_CW); - glEnable(GL_CULL_FACE); - glPolygonMode(GL_FRONT, GL_FILL); - glClearColor(0.5, 0.5, 0.5, 1.0); + glFrontFace(GL_CW); + glEnable(GL_CULL_FACE); + glPolygonMode(GL_FRONT, GL_FILL); + glClearColor(0.5, 0.5, 0.5, 1.0); - assertGl(); -} - -void BaseRenderer::renderMap(MapPreview *map, int x, int y, - int clientW, int clientH, int cellSize, bool grid, bool heightMap, bool hideWater) { - float alt=0; - float showWater=0; - - assertGl(); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, clientW, 0, clientH, 1, -1); - glViewport(0, 0, clientW, clientH); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glPushAttrib(GL_CURRENT_BIT); - - glTranslatef(static_cast(x), static_cast(y), 0.0f); - glLineWidth(1); - glClear(GL_COLOR_BUFFER_BIT); - glColor3f(0, 0, 0); - - for (int j = 0; j < map->getH(); j++) { - for (int i = 0; i < map->getW(); i++) { - if (i * cellSize + x > -cellSize - && i * cellSize + x < clientW - && clientH - cellSize - j * cellSize + y > -cellSize - && clientH - cellSize - j * cellSize + y < clientH) { - bool isCliff=false; // needed to speedup things - //surface - alt = map->getHeight(i, j) / 20.f; - showWater = map->getWaterLevel()/ 20.f - alt; - showWater = (showWater > 0)? showWater:0; - if(hideWater){ - showWater = 0; - } - Vec3f surfColor; - switch (map->getSurface(i, j)) { - case st_Grass: surfColor = Vec3f(0.0, 0.8f * alt, 0.f + showWater); break; - case st_Secondary_Grass: surfColor = Vec3f(0.4f * alt, 0.6f * alt, 0.f + showWater); break; - case st_Road: surfColor = Vec3f(0.6f * alt, 0.3f * alt, 0.f + showWater); break; - case st_Stone: surfColor = Vec3f(0.7f * alt, 0.7f * alt, 0.7f * alt + showWater); break; - case st_Ground: surfColor = Vec3f(0.7f * alt, 0.5f * alt, 0.3f * alt + showWater); break; - } - if(heightMap){ - surfColor = Vec3f(1.f * alt, 1.f * alt, 1.f * alt + showWater); - } - if(map->getCliffLevel()>0) - {// we maybe need to render cliff surfColor - if(map->isCliff(i, j)){ - surfColor = Vec3f(0.95f * alt, 0.8f * alt, 0.0f * alt + showWater); - isCliff=true; - } - } - glColor3fv(surfColor.ptr()); - - glBegin(GL_TRIANGLE_STRIP); - glVertex2i(i * cellSize, clientH - j * cellSize - cellSize); - glVertex2i(i * cellSize, clientH - j * cellSize); - glVertex2i(i * cellSize + cellSize, clientH - j * cellSize - cellSize); - glVertex2i(i * cellSize + cellSize, clientH - j * cellSize); - glEnd(); - if(!heightMap){ - //objects - switch (map->getObject(i, j)) { - case 0: glColor3f(0.f, 0.f, 0.f); break; - case 1: glColor3f(1.f, 0.f, 0.f); break; - case 2: glColor3f(1.f, 1.f, 1.f); break; - case 3: glColor3f(0.5f, 0.5f, 1.f); break; - case 4: glColor3f(0.f, 0.f, 1.f); break; - case 5: glColor3f(0.5f, 0.5f, 0.5f); break; - case 6: glColor3f(1.f, 0.8f, 0.5f); break; - case 7: glColor3f(0.f, 1.f, 1.f); break; - case 8: glColor3f(0.7f, 0.1f, 0.3f); break; - case 9: glColor3f(0.5f, 1.f, 0.1f); break; - case 10: glColor3f(1.f, 0.2f, 0.8f); break; - } - - if (map->getObject(i, j) != 0 || isCliff ) { - glPointSize(cellSize / 2.f); - glBegin(GL_POINTS); - glVertex2i(i * cellSize + cellSize / 2, clientH - j * cellSize - cellSize / 2); - glEnd(); - } - -// bool found = false; - - //height lines -// if (!found) { - - glColor3fv((surfColor*0.5f).ptr()); - //left - if (grid || (i > 0 && map->getHeight(i - 1, j) > map->getHeight(i, j))) { - glBegin(GL_LINES); - glVertex2i(i * cellSize, clientH - (j + 1) * cellSize); - glVertex2i(i * cellSize, clientH - j * cellSize); - glEnd(); - } - //down - if (grid || (j > 0 && map->getHeight(i, j - 1) > map->getHeight(i, j))) { - glBegin(GL_LINES); - glVertex2i(i * cellSize, clientH - j * cellSize); - glVertex2i((i + 1) * cellSize, clientH - j * cellSize); - glEnd(); - } - - glColor3fv((surfColor*2.f).ptr()); - //left - if (i > 0 && map->getHeight(i - 1, j) < map->getHeight(i, j)) { - glBegin(GL_LINES); - glVertex2i(i * cellSize, clientH - (j + 1) * cellSize); - glVertex2i(i * cellSize, clientH - j * cellSize); - glEnd(); - } - if (j > 0 && map->getHeight(i, j - 1) < map->getHeight(i, j)) { - glBegin(GL_LINES); - glVertex2i(i * cellSize, clientH - j * cellSize); - glVertex2i((i + 1) * cellSize, clientH - j * cellSize); - glEnd(); - } -// } - //resources - switch (map->getResource(i, j)) { - case 1: glColor3f(1.f, 1.f, 0.f); break; - case 2: glColor3f(0.5f, 0.5f, 0.5f); break; - case 3: glColor3f(1.f, 0.f, 0.f); break; - case 4: glColor3f(0.f, 0.f, 1.f); break; - case 5: glColor3f(0.5f, 0.5f, 1.f); break; - } - - if (map->getResource(i, j) != 0) { - glBegin(GL_LINES); - glVertex2i(i * cellSize, clientH - j * cellSize - cellSize); - glVertex2i(i * cellSize + cellSize, clientH - j * cellSize); - glVertex2i(i * cellSize, clientH - j * cellSize); - glVertex2i(i * cellSize + cellSize, clientH - j * cellSize - cellSize); - glEnd(); - } - } - - } + assertGl(); } + + void BaseRenderer::renderMap(MapPreview *map, int x, int y, + int clientW, int clientH, int cellSize, bool grid, bool heightMap, bool hideWater) { + float alt = 0; + float showWater = 0; + + assertGl(); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, clientW, 0, clientH, 1, -1); + glViewport(0, 0, clientW, clientH); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glPushAttrib(GL_CURRENT_BIT); + + glTranslatef(static_cast(x), static_cast(y), 0.0f); + glLineWidth(1); + glClear(GL_COLOR_BUFFER_BIT); + glColor3f(0, 0, 0); + + for (int j = 0; j < map->getH(); j++) { + for (int i = 0; i < map->getW(); i++) { + if (i * cellSize + x > -cellSize + && i * cellSize + x < clientW + && clientH - cellSize - j * cellSize + y > -cellSize + && clientH - cellSize - j * cellSize + y < clientH) { + bool isCliff = false; // needed to speedup things + //surface + alt = map->getHeight(i, j) / 20.f; + showWater = map->getWaterLevel() / 20.f - alt; + showWater = (showWater > 0) ? showWater : 0; + if (hideWater) { + showWater = 0; + } + Vec3f surfColor; + switch (map->getSurface(i, j)) { + case st_Grass: surfColor = Vec3f(0.0, 0.8f * alt, 0.f + showWater); break; + case st_Secondary_Grass: surfColor = Vec3f(0.4f * alt, 0.6f * alt, 0.f + showWater); break; + case st_Road: surfColor = Vec3f(0.6f * alt, 0.3f * alt, 0.f + showWater); break; + case st_Stone: surfColor = Vec3f(0.7f * alt, 0.7f * alt, 0.7f * alt + showWater); break; + case st_Ground: surfColor = Vec3f(0.7f * alt, 0.5f * alt, 0.3f * alt + showWater); break; + } + if (heightMap) { + surfColor = Vec3f(1.f * alt, 1.f * alt, 1.f * alt + showWater); + } + if (map->getCliffLevel() > 0) {// we maybe need to render cliff surfColor + if (map->isCliff(i, j)) { + surfColor = Vec3f(0.95f * alt, 0.8f * alt, 0.0f * alt + showWater); + isCliff = true; + } + } + glColor3fv(surfColor.ptr()); + + glBegin(GL_TRIANGLE_STRIP); + glVertex2i(i * cellSize, clientH - j * cellSize - cellSize); + glVertex2i(i * cellSize, clientH - j * cellSize); + glVertex2i(i * cellSize + cellSize, clientH - j * cellSize - cellSize); + glVertex2i(i * cellSize + cellSize, clientH - j * cellSize); + glEnd(); + if (!heightMap) { + //objects + switch (map->getObject(i, j)) { + case 0: glColor3f(0.f, 0.f, 0.f); break; + case 1: glColor3f(1.f, 0.f, 0.f); break; + case 2: glColor3f(1.f, 1.f, 1.f); break; + case 3: glColor3f(0.5f, 0.5f, 1.f); break; + case 4: glColor3f(0.f, 0.f, 1.f); break; + case 5: glColor3f(0.5f, 0.5f, 0.5f); break; + case 6: glColor3f(1.f, 0.8f, 0.5f); break; + case 7: glColor3f(0.f, 1.f, 1.f); break; + case 8: glColor3f(0.7f, 0.1f, 0.3f); break; + case 9: glColor3f(0.5f, 1.f, 0.1f); break; + case 10: glColor3f(1.f, 0.2f, 0.8f); break; + } + + if (map->getObject(i, j) != 0 || isCliff) { + glPointSize(cellSize / 2.f); + glBegin(GL_POINTS); + glVertex2i(i * cellSize + cellSize / 2, clientH - j * cellSize - cellSize / 2); + glEnd(); + } + + // bool found = false; + + //height lines + // if (!found) { + + glColor3fv((surfColor*0.5f).ptr()); + //left + if (grid || (i > 0 && map->getHeight(i - 1, j) > map->getHeight(i, j))) { + glBegin(GL_LINES); + glVertex2i(i * cellSize, clientH - (j + 1) * cellSize); + glVertex2i(i * cellSize, clientH - j * cellSize); + glEnd(); + } + //down + if (grid || (j > 0 && map->getHeight(i, j - 1) > map->getHeight(i, j))) { + glBegin(GL_LINES); + glVertex2i(i * cellSize, clientH - j * cellSize); + glVertex2i((i + 1) * cellSize, clientH - j * cellSize); + glEnd(); + } + + glColor3fv((surfColor*2.f).ptr()); + //left + if (i > 0 && map->getHeight(i - 1, j) < map->getHeight(i, j)) { + glBegin(GL_LINES); + glVertex2i(i * cellSize, clientH - (j + 1) * cellSize); + glVertex2i(i * cellSize, clientH - j * cellSize); + glEnd(); + } + if (j > 0 && map->getHeight(i, j - 1) < map->getHeight(i, j)) { + glBegin(GL_LINES); + glVertex2i(i * cellSize, clientH - j * cellSize); + glVertex2i((i + 1) * cellSize, clientH - j * cellSize); + glEnd(); + } + // } + //resources + switch (map->getResource(i, j)) { + case 1: glColor3f(1.f, 1.f, 0.f); break; + case 2: glColor3f(0.5f, 0.5f, 0.5f); break; + case 3: glColor3f(1.f, 0.f, 0.f); break; + case 4: glColor3f(0.f, 0.f, 1.f); break; + case 5: glColor3f(0.5f, 0.5f, 1.f); break; + } + + if (map->getResource(i, j) != 0) { + glBegin(GL_LINES); + glVertex2i(i * cellSize, clientH - j * cellSize - cellSize); + glVertex2i(i * cellSize + cellSize, clientH - j * cellSize); + glVertex2i(i * cellSize, clientH - j * cellSize); + glVertex2i(i * cellSize + cellSize, clientH - j * cellSize - cellSize); + glEnd(); + } + } + + } + } + } + + //start locations + glLineWidth(3); + for (int i = 0; i < map->getMaxFactions(); i++) { + switch (i) { + case 0: glColor3f(1.f, 0.f, 0.f); break; + case 1: glColor3f(0.f, 0.f, 1.f); break; + case 2: glColor3f(0.f, 1.f, 0.f); break; + case 3: glColor3f(1.f, 1.f, 0.f); break; + case 4: glColor3f(1.f, 1.f, 1.f); break; + case 5: glColor3f(0.f, 1.f, 0.8f); break; + case 6: glColor3f(1.f, 0.5f, 0.f); break; + case 7: glColor3f(1.f, 0.5f, 1.f); break; + } + glBegin(GL_LINES); + glVertex2i((map->getStartLocationX(i) - 1) * cellSize, clientH - (map->getStartLocationY(i) - 1) * cellSize); + glVertex2i((map->getStartLocationX(i) + 1) * cellSize + cellSize, clientH - (map->getStartLocationY(i) + 1) * cellSize - cellSize); + glVertex2i((map->getStartLocationX(i) - 1) * cellSize, clientH - (map->getStartLocationY(i) + 1) * cellSize - cellSize); + glVertex2i((map->getStartLocationX(i) + 1) * cellSize + cellSize, clientH - (map->getStartLocationY(i) - 1) * cellSize); + glEnd(); + } + + glPopMatrix(); + glPopAttrib(); + + assertGl(); + } + + } - - //start locations - glLineWidth(3); - for (int i = 0; i < map->getMaxFactions(); i++) { - switch (i) { - case 0: glColor3f(1.f, 0.f, 0.f); break; - case 1: glColor3f(0.f, 0.f, 1.f); break; - case 2: glColor3f(0.f, 1.f, 0.f); break; - case 3: glColor3f(1.f, 1.f, 0.f); break; - case 4: glColor3f(1.f, 1.f, 1.f); break; - case 5: glColor3f(0.f, 1.f, 0.8f); break; - case 6: glColor3f(1.f, 0.5f, 0.f); break; - case 7: glColor3f(1.f, 0.5f, 1.f); break; - } - glBegin(GL_LINES); - glVertex2i((map->getStartLocationX(i) - 1) * cellSize, clientH - (map->getStartLocationY(i) - 1) * cellSize); - glVertex2i((map->getStartLocationX(i) + 1) * cellSize + cellSize, clientH - (map->getStartLocationY(i) + 1) * cellSize - cellSize); - glVertex2i((map->getStartLocationX(i) - 1) * cellSize, clientH - (map->getStartLocationY(i) + 1) * cellSize - cellSize); - glVertex2i((map->getStartLocationX(i) + 1) * cellSize + cellSize, clientH - (map->getStartLocationY(i) - 1) * cellSize); - glEnd(); - } - - glPopMatrix(); - glPopAttrib(); - - assertGl(); -} - - -}} // end namespace +} // end namespace diff --git a/source/shared_lib/sources/graphics/gl/context_gl.cpp b/source/shared_lib/sources/graphics/gl/context_gl.cpp index cbb7d3283..2da557ca1 100644 --- a/source/shared_lib/sources/graphics/gl/context_gl.cpp +++ b/source/shared_lib/sources/graphics/gl/context_gl.cpp @@ -21,37 +21,41 @@ using namespace std; using namespace Shared::Util; -namespace Shared{ namespace Graphics{ namespace Gl{ +namespace Shared { + namespace Graphics { + namespace Gl { -// ===================================================== -// class ContextGl -// ===================================================== + // ===================================================== + // class ContextGl + // ===================================================== -ContextGl::ContextGl() : Context() { + ContextGl::ContextGl() : Context() { -} + } -void ContextGl::init() { + void ContextGl::init() { - pcgl.init(colorBits, depthBits, stencilBits, - (hardware_acceleration != 0), (fullscreen_anti_aliasing != 0), - gammaValue); -} + pcgl.init(colorBits, depthBits, stencilBits, + (hardware_acceleration != 0), (fullscreen_anti_aliasing != 0), + gammaValue); + } -ContextGl::~ContextGl() { - end(); -} + ContextGl::~ContextGl() { + end(); + } -void ContextGl::end() { - pcgl.end(); -} + void ContextGl::end() { + pcgl.end(); + } -void ContextGl::makeCurrent() { - pcgl.makeCurrent(); -} + void ContextGl::makeCurrent() { + pcgl.makeCurrent(); + } -void ContextGl::swapBuffers() { - pcgl.swapBuffers(); -} + void ContextGl::swapBuffers() { + pcgl.swapBuffers(); + } -}}}//end namespace + } + } +}//end namespace diff --git a/source/shared_lib/sources/graphics/gl/font_gl.cpp b/source/shared_lib/sources/graphics/gl/font_gl.cpp index 9f2731acb..312c624f9 100644 --- a/source/shared_lib/sources/graphics/gl/font_gl.cpp +++ b/source/shared_lib/sources/graphics/gl/font_gl.cpp @@ -15,74 +15,78 @@ #include "gl_wrap.h" #include "leak_dumper.h" -namespace Shared { namespace Graphics { namespace Gl { +namespace Shared { + namespace Graphics { + namespace Gl { -using namespace Platform; + using namespace Platform; -// ===================================================== -// class Font2DGl -// ===================================================== + // ===================================================== + // class Font2DGl + // ===================================================== -string FontGl::default_fonttype = "fixed"; + string FontGl::default_fonttype = "fixed"; -void Font2DGl::init() { - //printf("In [%s::%s] Line: %d inited = %d\n",__FILE__,__FUNCTION__,__LINE__,inited); - if(inited == false) { - //printf("In [%s::%s] Line: %d inited = %d Font::forceLegacyFonts = %d\n",__FILE__,__FUNCTION__,__LINE__,inited,Font::forceLegacyFonts); - if(getTextHandler() == NULL || Font::forceLegacyFonts == true) { - assertGl(); - handle= glGenLists(charCount); - assertGl(); + void Font2DGl::init() { + //printf("In [%s::%s] Line: %d inited = %d\n",__FILE__,__FUNCTION__,__LINE__,inited); + if (inited == false) { + //printf("In [%s::%s] Line: %d inited = %d Font::forceLegacyFonts = %d\n",__FILE__,__FUNCTION__,__LINE__,inited,Font::forceLegacyFonts); + if (getTextHandler() == NULL || Font::forceLegacyFonts == true) { + assertGl(); + handle = glGenLists(charCount); + assertGl(); - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); - createGlFontBitmaps((Shared::Platform::uint32&)handle, type, size, width, charCount, metrics); - assertGl(); - } - inited= true; - } -} + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + createGlFontBitmaps((Shared::Platform::uint32&)handle, type, size, width, charCount, metrics); + assertGl(); + } + inited = true; + } + } -void Font2DGl::end() { - if(inited) { - if(getTextHandler() == NULL || Font::forceLegacyFonts == true) { - assertGl(); - //assert(glIsList(handle)); - glDeleteLists(handle, 1); - assertGl(); - } - inited = false; - } -} + void Font2DGl::end() { + if (inited) { + if (getTextHandler() == NULL || Font::forceLegacyFonts == true) { + assertGl(); + //assert(glIsList(handle)); + glDeleteLists(handle, 1); + assertGl(); + } + inited = false; + } + } -// ===================================================== -// class Font3DGl -// ===================================================== + // ===================================================== + // class Font3DGl + // ===================================================== -void Font3DGl::init() { - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); - if(inited == false) { - if(getTextHandler() == NULL || Font::forceLegacyFonts == true) { - assertGl(); - handle= glGenLists(charCount); - createGlFontOutlines((Shared::Platform::uint32&)handle, type, width, depth, charCount, metrics); - assertGl(); - } - inited= true; - } -} + void Font3DGl::init() { + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + if (inited == false) { + if (getTextHandler() == NULL || Font::forceLegacyFonts == true) { + assertGl(); + handle = glGenLists(charCount); + createGlFontOutlines((Shared::Platform::uint32&)handle, type, width, depth, charCount, metrics); + assertGl(); + } + inited = true; + } + } + + void Font3DGl::end() { + if (inited) { + if (getTextHandler() == NULL || Font::forceLegacyFonts == true) { + assertGl(); + assert(glIsList(handle)); + glDeleteLists(handle, 1); + assertGl(); + } + } + } -void Font3DGl::end() { - if(inited) { - if(getTextHandler() == NULL || Font::forceLegacyFonts == true) { - assertGl(); - assert(glIsList(handle)); - glDeleteLists(handle, 1); - assertGl(); } } -} - -}}}//end namespace +}//end namespace //namespace Shared { namespace Graphics { // diff --git a/source/shared_lib/sources/graphics/gl/font_textFTGL.cpp b/source/shared_lib/sources/graphics/gl/font_textFTGL.cpp index df2d8f4ee..6c6238ab8 100644 --- a/source/shared_lib/sources/graphics/gl/font_textFTGL.cpp +++ b/source/shared_lib/sources/graphics/gl/font_textFTGL.cpp @@ -27,409 +27,409 @@ using namespace std; using namespace Shared::Util; using namespace Shared::PlatformCommon; -namespace Shared { namespace Graphics { namespace Gl { +namespace Shared { + namespace Graphics { + namespace Gl { -string TextFTGL::langHeightText = "yW"; -int TextFTGL::faceResolution = 72; + string TextFTGL::langHeightText = "yW"; + int TextFTGL::faceResolution = 72; -//==================================================================== -TextFTGL::TextFTGL(FontTextHandlerType type) : Text(type) { + //==================================================================== + TextFTGL::TextFTGL(FontTextHandlerType type) : Text(type) { - //throw megaglest_runtime_error("FTGL!"); - //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc",0); - //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/arphic/uming.ttc",0); // Chinese - //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/arphic/ukai.ttc",0); // Chinese - //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-sil-doulos/DoulosSILR.ttf",0); // Russian / Cyrillic - //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-sil-charis/CharisSILR.ttf",0); // Russian / Cyrillic - //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-R.ttf",0); // Russian / Cyrillic - //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/takao/TakaoPGothic.ttf",0); // Japanese - //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-sil-scheherazade/ScheherazadeRegOT.ttf",0); // Arabic - //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/linux-libertine/LinLibertine_Re.ttf",0); // Hebrew - //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/unifont/unifont.ttf",0); // Czech? - //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-liberation/LiberationSans-Regular.ttf",0); // Czech? + //throw megaglest_runtime_error("FTGL!"); + //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc",0); + //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/arphic/uming.ttc",0); // Chinese + //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/arphic/ukai.ttc",0); // Chinese + //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-sil-doulos/DoulosSILR.ttf",0); // Russian / Cyrillic + //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-sil-charis/CharisSILR.ttf",0); // Russian / Cyrillic + //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-R.ttf",0); // Russian / Cyrillic + //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/takao/TakaoPGothic.ttf",0); // Japanese + //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-sil-scheherazade/ScheherazadeRegOT.ttf",0); // Arabic + //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/linux-libertine/LinLibertine_Re.ttf",0); // Hebrew + //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/unifont/unifont.ttf",0); // Czech? + //setenv("MEGAGLEST_FONT","/usr/share/fonts/truetype/ttf-liberation/LiberationSans-Regular.ttf",0); // Czech? - fontFile = findFont(); - //ftFont = new FTBufferFont(fontFile); - //ftFont = new FTGLPixmapFont(fontFile); - //ftFont = new FTGLExtrdFont(fontFile); - //ftFont = new FTGLPolygonFont("/usr/share/fonts/truetype/arphic/uming.ttc"); + fontFile = findFont(); + //ftFont = new FTBufferFont(fontFile); + //ftFont = new FTGLPixmapFont(fontFile); + //ftFont = new FTGLExtrdFont(fontFile); + //ftFont = new FTGLPolygonFont("/usr/share/fonts/truetype/arphic/uming.ttc"); - //ftFont = new FTGLPixmapFont("/usr/share/fonts/truetype/arphic/uming.ttc"); - if(type == ftht_2D) { - ftFont = new FTGLPixmapFont(fontFile); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("2D font [%s]\n",fontFile); - } - else if(type == ftht_3D) { - ftFont = new FTGLTextureFont(fontFile); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("3D font [%s]\n",fontFile); - } - else { - throw megaglest_runtime_error("font render type not set to a known value!"); - } + //ftFont = new FTGLPixmapFont("/usr/share/fonts/truetype/arphic/uming.ttc"); + if (type == ftht_2D) { + ftFont = new FTGLPixmapFont(fontFile); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("2D font [%s]\n", fontFile); + } else if (type == ftht_3D) { + ftFont = new FTGLTextureFont(fontFile); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("3D font [%s]\n", fontFile); + } else { + throw megaglest_runtime_error("font render type not set to a known value!"); + } - if(ftFont->Error()) { - string fontFileName = (fontFile != NULL ? fontFile : "n/a"); - printf("FTGL: error loading font: %s\n", fontFileName.c_str()); - delete ftFont; ftFont = NULL; - if(fontFile != NULL) free((void*)fontFile); - fontFile = NULL; - throw megaglest_runtime_error(string("FTGL: error loading font: ") + fontFileName); - } - free((void*)fontFile); - fontFile = NULL; + if (ftFont->Error()) { + string fontFileName = (fontFile != NULL ? fontFile : "n/a"); + printf("FTGL: error loading font: %s\n", fontFileName.c_str()); + delete ftFont; ftFont = NULL; + if (fontFile != NULL) free((void*) fontFile); + fontFile = NULL; + throw megaglest_runtime_error(string("FTGL: error loading font: ") + fontFileName); + } + free((void*) fontFile); + fontFile = NULL; - const unsigned int defSize = 24; - ftFont->FaceSize(defSize,TextFTGL::faceResolution); + const unsigned int defSize = 24; + ftFont->FaceSize(defSize, TextFTGL::faceResolution); - GLenum error = glGetError(); - if(error != GL_NO_ERROR) { - printf("\n[%s::%s] Line %d Error = %d [%s] for size = %u res = %d\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),defSize,TextFTGL::faceResolution); - fflush(stdout); - } + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + printf("\n[%s::%s] Line %d Error = %d [%s] for size = %u res = %d\n", __FILE__, __FUNCTION__, __LINE__, error, gluErrorString(error), defSize, TextFTGL::faceResolution); + fflush(stdout); + } - if(ftFont->Error()) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"FTGL: error setting face size, #%d",ftFont->Error()); - throw megaglest_runtime_error(szBuf); - } - //ftFont->UseDisplayList(false); - //ftFont->CharMap(ft_encoding_gb2312); - //ftFont->CharMap(ft_encoding_big5); - if(ftFont->CharMap(ft_encoding_unicode) == false) { - throw megaglest_runtime_error("FTGL: error setting encoding"); - } + if (ftFont->Error()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "FTGL: error setting face size, #%d", ftFont->Error()); + throw megaglest_runtime_error(szBuf); + } + //ftFont->UseDisplayList(false); + //ftFont->CharMap(ft_encoding_gb2312); + //ftFont->CharMap(ft_encoding_big5); + if (ftFont->CharMap(ft_encoding_unicode) == false) { + throw megaglest_runtime_error("FTGL: error setting encoding"); + } - if(ftFont->Error()) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"FTGL: error setting encoding, #%d",ftFont->Error()); - throw megaglest_runtime_error(szBuf); - } -} - -TextFTGL::~TextFTGL() { - cleanupFont(); -} - -void TextFTGL::cleanupFont() { - delete ftFont; - ftFont = NULL; - - if(fontFile) { - free((void*)fontFile); - } - fontFile = NULL; -} - -void TextFTGL::init(string fontName, string fontFamilyName, int fontSize) { - cleanupFont(); - fontFile = findFont(fontName.c_str(),fontFamilyName.c_str()); - - //ftFont = new FTBufferFont(fontFile); - //ftFont = new FTGLPixmapFont(fontFile); - //ftFont = new FTGLExtrdFont(fontFile); - //ftFont = new FTGLPolygonFont("/usr/share/fonts/truetype/arphic/uming.ttc"); - //ftFont = new FTGLPixmapFont("/usr/share/fonts/truetype/arphic/uming.ttc"); - - if(type == ftht_2D) { - ftFont = new FTGLPixmapFont(fontFile); - //printf("2D font [%s]\n",fontFile); - } - else if(type == ftht_3D) { - ftFont = new FTGLTextureFont(fontFile); - - //ftFont = new FTBufferFont(fontFile); - //ftFont = new FTGLExtrdFont(fontFile); - //ftFont = new FTGLPolygonFont("/usr/share/fonts/truetype/arphic/uming.ttc"); - - //printf("3D font [%s]\n",fontFile); - } - else { - throw megaglest_runtime_error("font render type not set to a known value!"); - } - - if(ftFont->Error()) { - printf("FTGL: error loading font: %s\n", fontFile); - delete ftFont; ftFont = NULL; - if(fontFile) { - free((void*)fontFile); - } - fontFile = NULL; - throw megaglest_runtime_error("FTGL: error loading font"); - } - free((void*)fontFile); - fontFile = NULL; - - if(fontSize <= 0) { - fontSize = 24; - } - ftFont->FaceSize(fontSize,TextFTGL::faceResolution); - - GLenum error = glGetError(); - if(error != GL_NO_ERROR) { - printf("\n[%s::%s] Line %d Error = %d [%s] for size = %d res = %d\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),fontSize,TextFTGL::faceResolution); - fflush(stdout); - } - - if(ftFont->Error()) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"FTGL: error setting face size, #%d",ftFont->Error()); - throw megaglest_runtime_error(szBuf); - } - - //ftFont->UseDisplayList(false); - //ftFont->CharMap(ft_encoding_gb2312); - //ftFont->CharMap(ft_encoding_big5); - if(ftFont->CharMap(ft_encoding_unicode) == false) { - throw megaglest_runtime_error("FTGL: error setting encoding"); - } - if(ftFont->Error()) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"FTGL: error setting encoding, #%d",ftFont->Error()); - throw megaglest_runtime_error(szBuf); - } - - // Create a string containing common characters - // and preload the chars without rendering them. - string preloadText = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890-=!@#$%^&*()_+:\"{}[]/?.,<>\\';"; - ftFont->Advance(preloadText.c_str()); - - error = glGetError(); - if(error != GL_NO_ERROR) { - printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),preloadText.c_str()); - fflush(stdout); - } - - if(ftFont->Error()) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"FTGL: error advancing(a), #%d",ftFont->Error()); - throw megaglest_runtime_error(szBuf); - } -} - -void TextFTGL::SetFaceSize(int value) { - ftFont->FaceSize(value,TextFTGL::faceResolution); - - GLenum error = glGetError(); - if(error != GL_NO_ERROR) { - printf("\n[%s::%s] Line %d Error = %d [%s] for facesize = %d\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),value); - fflush(stdout); - } - - if(ftFont->Error()) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"FTGL: error setting face size, #%d",ftFont->Error()); - throw megaglest_runtime_error(szBuf); - } -} - -int TextFTGL::GetFaceSize() { - return ftFont->FaceSize(); -} - -void TextFTGL::Render(const char* str, const int len) { - //printf("Render TextFTGL\n"); - - /* - FTGL renders the whole string when len == 0 - but we don't want any text rendered then. - */ - if(len != 0) { - //printf("FTGL Render [%s] facesize = %d\n",str,ftFont->FaceSize()); - assertGl(); - - ftFont->Render(str, len); - //assertGl(); - GLenum error = glGetError(); - if(error != GL_NO_ERROR) { - printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),str); - fflush(stdout); - } - - if(ftFont->Error()) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"FTGL: error trying to render, #%d",ftFont->Error()); - throw megaglest_runtime_error(szBuf); - } - } -} - -float TextFTGL::Advance(const char* str, const int len) { - float result = ftFont->Advance(str, len); - - GLenum error = glGetError(); - if(error != GL_NO_ERROR) { - printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),str); - fflush(stdout); - } - - if(ftFont->Error()) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"FTGL: error trying to advance(b), #%d",ftFont->Error()); - throw megaglest_runtime_error(szBuf); - } - return result; - - //FTBBox box = ftFont->BBox(str); - //float urx = box.Upper().X(); - //float llx = box.Lower().X(); - //float llx, lly, llz, urx, ury, urz; - //ftFont->BBox(str, llx, lly, llz, urx, ury, urz); - - //Short_t halign = fTextAlign/10; - //Short_t valign = fTextAlign - 10*halign; - //Float_t dx = 0, dy = 0; -// switch (halign) { -// case 1 : dx = 0 ; break; -// case 2 : dx = -urx/2; break; -// case 3 : dx = -urx ; break; -// } -// switch (valign) { -// case 1 : dy = 0 ; break; -// case 2 : dy = -ury/2; break; -// case 3 : dy = -ury ; break; -// } - - //printf("For str [%s] advance = %f, urx = %f, llx = %f\n",str, ftFont->Advance(str, len),urx,llx); - //return urx; -} - -float TextFTGL::LineHeight(const char* str, const int len) { - //FTBBox box = ftFont->BBox(str); - //printf("String [%s] lineheight = %f upper_y = %f lower_y = %f\n",str,ftFont->LineHeight(),box.Upper().Y(),box.Lower().Y()); - - - //printf("ftFont->Ascender():%f ftFont->Descender()*-1 = %f ftFont->LineHeight() = %f\n",ftFont->Ascender(),ftFont->Descender()*-1 , ftFont->LineHeight()); - //return ftFont->Ascender() + ftFont->Descender()*-1 - ftFont->LineHeight(); - //return ftFont->LineHeight(); - - //static float result = -1000; - float result = -1000; - //if(result == -1000) { - FTBBox box = ftFont->BBox(TextFTGL::langHeightText.c_str()); - - GLenum error = glGetError(); - if(error != GL_NO_ERROR) { - printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),str); - fflush(stdout); - } - - result = box.Upper().Yf()- box.Lower().Yf(); - if(result == 0) { - result = ftFont->LineHeight(); - - GLenum error = glGetError(); - if(error != GL_NO_ERROR) { - printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),str); - fflush(stdout); + if (ftFont->Error()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "FTGL: error setting encoding, #%d", ftFont->Error()); + throw megaglest_runtime_error(szBuf); + } } - } - //printf("ftFont->BBox(''yW'')%f\n",result); - //} -// else { -// FTBBox box = ftFont->BBox(TextFTGL::langHeightText.c_str()); -// -// GLenum error = glGetError(); -// if(error != GL_NO_ERROR) { -// printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),str); -// fflush(stdout); -// } -// -// int newresult = box.Upper().Y()- box.Lower().Y(); -// if(newresult == 0) { -// newresult = ftFont->LineHeight(); -// -// GLenum error = glGetError(); -// if(error != GL_NO_ERROR) { -// printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),str); -// fflush(stdout); -// } -// } -// -// printf("Height for [%s] result [%d] [%d]\n",str,result,newresult); -// } - if(ftFont->Error()) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"FTGL: error trying to get lineheight, #%d",ftFont->Error()); - throw megaglest_runtime_error(szBuf); - } - return result; -// printf("For str [%s] LineHeight = %f, result = %f\n",str, ftFont->LineHeight(),result); -// return result; + TextFTGL::~TextFTGL() { + cleanupFont(); + } - //float urx = box.Upper().X(); - //float llx = box.Lower().X(); - //float llx, lly, llz, urx, ury, urz; - //ftFont->BBox(str, llx, lly, llz, urx, ury, urz); - //return ury - lly; + void TextFTGL::cleanupFont() { + delete ftFont; + ftFont = NULL; - //Short_t halign = fTextAlign/10; - //Short_t valign = fTextAlign - 10*halign; - //Float_t dx = 0, dy = 0; -// switch (halign) { -// case 1 : dx = 0 ; break; -// case 2 : dx = -urx/2; break; -// case 3 : dx = -urx ; break; -// } -// switch (valign) { -// case 1 : dy = 0 ; break; -// case 2 : dy = -ury/2; break; -// case 3 : dy = -ury ; break; -// } + if (fontFile) { + free((void*) fontFile); + } + fontFile = NULL; + } - //printf("For str [%s] advance = %f, urx = %f, llx = %f\n",str, ftFont->Advance(str, len),urx,llx); - //return urx; + void TextFTGL::init(string fontName, string fontFamilyName, int fontSize) { + cleanupFont(); + fontFile = findFont(fontName.c_str(), fontFamilyName.c_str()); -} + //ftFont = new FTBufferFont(fontFile); + //ftFont = new FTGLPixmapFont(fontFile); + //ftFont = new FTGLExtrdFont(fontFile); + //ftFont = new FTGLPolygonFont("/usr/share/fonts/truetype/arphic/uming.ttc"); + //ftFont = new FTGLPixmapFont("/usr/share/fonts/truetype/arphic/uming.ttc"); -float TextFTGL::LineHeight(const wchar_t* str, const int len) { - static float result = -1000; - if(result == -1000) { - FTBBox box = ftFont->BBox(TextFTGL::langHeightText.c_str()); - result = box.Upper().Yf()- box.Lower().Yf(); - if(result == 0) { - result = ftFont->LineHeight(); - } - //printf("ftFont->BBox(''yW'')%f\n",result); - } - if(ftFont->Error()) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"FTGL: error trying to get lineheight, #%d",ftFont->Error()); - throw megaglest_runtime_error(szBuf); - } + if (type == ftht_2D) { + ftFont = new FTGLPixmapFont(fontFile); + //printf("2D font [%s]\n",fontFile); + } else if (type == ftht_3D) { + ftFont = new FTGLTextureFont(fontFile); - return result; -} + //ftFont = new FTBufferFont(fontFile); + //ftFont = new FTGLExtrdFont(fontFile); + //ftFont = new FTGLPolygonFont("/usr/share/fonts/truetype/arphic/uming.ttc"); -void TextFTGL::Render(const wchar_t* str, const int len) { - /* - FTGL renders the whole string when len == 0 - but we don't want any text rendered then. - */ - if(len != 0) { - ftFont->Render(str, len); + //printf("3D font [%s]\n",fontFile); + } else { + throw megaglest_runtime_error("font render type not set to a known value!"); + } + + if (ftFont->Error()) { + printf("FTGL: error loading font: %s\n", fontFile); + delete ftFont; ftFont = NULL; + if (fontFile) { + free((void*) fontFile); + } + fontFile = NULL; + throw megaglest_runtime_error("FTGL: error loading font"); + } + free((void*) fontFile); + fontFile = NULL; + + if (fontSize <= 0) { + fontSize = 24; + } + ftFont->FaceSize(fontSize, TextFTGL::faceResolution); + + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + printf("\n[%s::%s] Line %d Error = %d [%s] for size = %d res = %d\n", __FILE__, __FUNCTION__, __LINE__, error, gluErrorString(error), fontSize, TextFTGL::faceResolution); + fflush(stdout); + } + + if (ftFont->Error()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "FTGL: error setting face size, #%d", ftFont->Error()); + throw megaglest_runtime_error(szBuf); + } + + //ftFont->UseDisplayList(false); + //ftFont->CharMap(ft_encoding_gb2312); + //ftFont->CharMap(ft_encoding_big5); + if (ftFont->CharMap(ft_encoding_unicode) == false) { + throw megaglest_runtime_error("FTGL: error setting encoding"); + } + if (ftFont->Error()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "FTGL: error setting encoding, #%d", ftFont->Error()); + throw megaglest_runtime_error(szBuf); + } + + // Create a string containing common characters + // and preload the chars without rendering them. + string preloadText = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890-=!@#$%^&*()_+:\"{}[]/?.,<>\\';"; + ftFont->Advance(preloadText.c_str()); + + error = glGetError(); + if (error != GL_NO_ERROR) { + printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n", __FILE__, __FUNCTION__, __LINE__, error, gluErrorString(error), preloadText.c_str()); + fflush(stdout); + } + + if (ftFont->Error()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "FTGL: error advancing(a), #%d", ftFont->Error()); + throw megaglest_runtime_error(szBuf); + } + } + + void TextFTGL::SetFaceSize(int value) { + ftFont->FaceSize(value, TextFTGL::faceResolution); + + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + printf("\n[%s::%s] Line %d Error = %d [%s] for facesize = %d\n", __FILE__, __FUNCTION__, __LINE__, error, gluErrorString(error), value); + fflush(stdout); + } + + if (ftFont->Error()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "FTGL: error setting face size, #%d", ftFont->Error()); + throw megaglest_runtime_error(szBuf); + } + } + + int TextFTGL::GetFaceSize() { + return ftFont->FaceSize(); + } + + void TextFTGL::Render(const char* str, const int len) { + //printf("Render TextFTGL\n"); + + /* + FTGL renders the whole string when len == 0 + but we don't want any text rendered then. + */ + if (len != 0) { + //printf("FTGL Render [%s] facesize = %d\n",str,ftFont->FaceSize()); + assertGl(); + + ftFont->Render(str, len); + //assertGl(); + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n", __FILE__, __FUNCTION__, __LINE__, error, gluErrorString(error), str); + fflush(stdout); + } + + if (ftFont->Error()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "FTGL: error trying to render, #%d", ftFont->Error()); + throw megaglest_runtime_error(szBuf); + } + } + } + + float TextFTGL::Advance(const char* str, const int len) { + float result = ftFont->Advance(str, len); + + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n", __FILE__, __FUNCTION__, __LINE__, error, gluErrorString(error), str); + fflush(stdout); + } + + if (ftFont->Error()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "FTGL: error trying to advance(b), #%d", ftFont->Error()); + throw megaglest_runtime_error(szBuf); + } + return result; + + //FTBBox box = ftFont->BBox(str); + //float urx = box.Upper().X(); + //float llx = box.Lower().X(); + //float llx, lly, llz, urx, ury, urz; + //ftFont->BBox(str, llx, lly, llz, urx, ury, urz); + + //Short_t halign = fTextAlign/10; + //Short_t valign = fTextAlign - 10*halign; + //Float_t dx = 0, dy = 0; + // switch (halign) { + // case 1 : dx = 0 ; break; + // case 2 : dx = -urx/2; break; + // case 3 : dx = -urx ; break; + // } + // switch (valign) { + // case 1 : dy = 0 ; break; + // case 2 : dy = -ury/2; break; + // case 3 : dy = -ury ; break; + // } + + //printf("For str [%s] advance = %f, urx = %f, llx = %f\n",str, ftFont->Advance(str, len),urx,llx); + //return urx; + } + + float TextFTGL::LineHeight(const char* str, const int len) { + //FTBBox box = ftFont->BBox(str); + //printf("String [%s] lineheight = %f upper_y = %f lower_y = %f\n",str,ftFont->LineHeight(),box.Upper().Y(),box.Lower().Y()); + + + //printf("ftFont->Ascender():%f ftFont->Descender()*-1 = %f ftFont->LineHeight() = %f\n",ftFont->Ascender(),ftFont->Descender()*-1 , ftFont->LineHeight()); + //return ftFont->Ascender() + ftFont->Descender()*-1 - ftFont->LineHeight(); + //return ftFont->LineHeight(); + + //static float result = -1000; + float result = -1000; + //if(result == -1000) { + FTBBox box = ftFont->BBox(TextFTGL::langHeightText.c_str()); + + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n", __FILE__, __FUNCTION__, __LINE__, error, gluErrorString(error), str); + fflush(stdout); + } + + result = box.Upper().Yf() - box.Lower().Yf(); + if (result == 0) { + result = ftFont->LineHeight(); + + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n", __FILE__, __FUNCTION__, __LINE__, error, gluErrorString(error), str); + fflush(stdout); + } + } + //printf("ftFont->BBox(''yW'')%f\n",result); + //} + // else { + // FTBBox box = ftFont->BBox(TextFTGL::langHeightText.c_str()); + // + // GLenum error = glGetError(); + // if(error != GL_NO_ERROR) { + // printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),str); + // fflush(stdout); + // } + // + // int newresult = box.Upper().Y()- box.Lower().Y(); + // if(newresult == 0) { + // newresult = ftFont->LineHeight(); + // + // GLenum error = glGetError(); + // if(error != GL_NO_ERROR) { + // printf("\n[%s::%s] Line %d Error = %d [%s] for text [%s]\n",__FILE__,__FUNCTION__,__LINE__,error,gluErrorString(error),str); + // fflush(stdout); + // } + // } + // + // printf("Height for [%s] result [%d] [%d]\n",str,result,newresult); + // } + if (ftFont->Error()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "FTGL: error trying to get lineheight, #%d", ftFont->Error()); + throw megaglest_runtime_error(szBuf); + } + + return result; + // printf("For str [%s] LineHeight = %f, result = %f\n",str, ftFont->LineHeight(),result); + // return result; + + //float urx = box.Upper().X(); + //float llx = box.Lower().X(); + //float llx, lly, llz, urx, ury, urz; + //ftFont->BBox(str, llx, lly, llz, urx, ury, urz); + //return ury - lly; + + //Short_t halign = fTextAlign/10; + //Short_t valign = fTextAlign - 10*halign; + //Float_t dx = 0, dy = 0; + // switch (halign) { + // case 1 : dx = 0 ; break; + // case 2 : dx = -urx/2; break; + // case 3 : dx = -urx ; break; + // } + // switch (valign) { + // case 1 : dy = 0 ; break; + // case 2 : dy = -ury/2; break; + // case 3 : dy = -ury ; break; + // } + + //printf("For str [%s] advance = %f, urx = %f, llx = %f\n",str, ftFont->Advance(str, len),urx,llx); + //return urx; + + } + + float TextFTGL::LineHeight(const wchar_t* str, const int len) { + static float result = -1000; + if (result == -1000) { + FTBBox box = ftFont->BBox(TextFTGL::langHeightText.c_str()); + result = box.Upper().Yf() - box.Lower().Yf(); + if (result == 0) { + result = ftFont->LineHeight(); + } + //printf("ftFont->BBox(''yW'')%f\n",result); + } + if (ftFont->Error()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "FTGL: error trying to get lineheight, #%d", ftFont->Error()); + throw megaglest_runtime_error(szBuf); + } + + return result; + } + + void TextFTGL::Render(const wchar_t* str, const int len) { + /* + FTGL renders the whole string when len == 0 + but we don't want any text rendered then. + */ + if (len != 0) { + ftFont->Render(str, len); + + if (ftFont->Error()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "FTGL: error trying to render, #%d", ftFont->Error()); + throw megaglest_runtime_error(szBuf); + } + } + } + + float TextFTGL::Advance(const wchar_t* str, const int len) { + float result = ftFont->Advance(str, len); + if (ftFont->Error()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "FTGL: error trying to advance(c), #%d", ftFont->Error()); + throw megaglest_runtime_error(szBuf); + } + + return result; + } - if(ftFont->Error()) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"FTGL: error trying to render, #%d",ftFont->Error()); - throw megaglest_runtime_error(szBuf); } } -} - -float TextFTGL::Advance(const wchar_t* str, const int len) { - float result = ftFont->Advance(str, len); - if(ftFont->Error()) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"FTGL: error trying to advance(c), #%d",ftFont->Error()); - throw megaglest_runtime_error(szBuf); - } - - return result; -} - -}}}//end namespace +}//end namespace #endif // USE_FTGL diff --git a/source/shared_lib/sources/graphics/gl/model_gl.cpp b/source/shared_lib/sources/graphics/gl/model_gl.cpp index adacacd8f..71eb653a5 100644 --- a/source/shared_lib/sources/graphics/gl/model_gl.cpp +++ b/source/shared_lib/sources/graphics/gl/model_gl.cpp @@ -11,11 +11,15 @@ #include "model_gl.h" -namespace Shared{ namespace Graphics{ namespace Gl{ - -ModelGl::ModelGl(const string &path,TextureManager* textureManager,bool deletePixMapAfterLoad,std::map > > *loadedFileList, string *sourceLoader) { - setTextureManager(textureManager); - load(path,deletePixMapAfterLoad,loadedFileList,sourceLoader); -} - -}}}//end namespace +namespace Shared { + namespace Graphics { + namespace Gl { + + ModelGl::ModelGl(const string &path, TextureManager* textureManager, bool deletePixMapAfterLoad, std::map > > *loadedFileList, string *sourceLoader) { + setTextureManager(textureManager); + load(path, deletePixMapAfterLoad, loadedFileList, sourceLoader); + } + + } + } +}//end namespace diff --git a/source/shared_lib/sources/graphics/gl/model_renderer_gl.cpp b/source/shared_lib/sources/graphics/gl/model_renderer_gl.cpp index e1bf52241..8b8d8a740 100644 --- a/source/shared_lib/sources/graphics/gl/model_renderer_gl.cpp +++ b/source/shared_lib/sources/graphics/gl/model_renderer_gl.cpp @@ -19,369 +19,362 @@ using namespace Shared::Platform; -namespace Shared { namespace Graphics { namespace Gl { +namespace Shared { + namespace Graphics { + namespace Gl { -// ===================================================== -// class MyClass -// ===================================================== + // ===================================================== + // class MyClass + // ===================================================== -// ===================== PUBLIC ======================== + // ===================== PUBLIC ======================== -ModelRendererGl::ModelRendererGl() { - rendering= false; - duplicateTexCoords= false; - secondaryTexCoordUnit= 1; - lastTexture=0; -} + ModelRendererGl::ModelRendererGl() { + rendering = false; + duplicateTexCoords = false; + secondaryTexCoordUnit = 1; + lastTexture = 0; + } -void ModelRendererGl::begin(bool renderNormals, bool renderTextures, bool renderColors, - bool colorPickingMode, MeshCallback *meshCallback) { - //assertions - assert(rendering == false); - assertGl(); + void ModelRendererGl::begin(bool renderNormals, bool renderTextures, bool renderColors, + bool colorPickingMode, MeshCallback *meshCallback) { + //assertions + assert(rendering == false); + assertGl(); - this->renderTextures= renderTextures; - this->renderNormals= renderNormals; - this->renderColors= renderColors; - this->colorPickingMode = colorPickingMode; - this->meshCallback= meshCallback; + this->renderTextures = renderTextures; + this->renderNormals = renderNormals; + this->renderColors = renderColors; + this->colorPickingMode = colorPickingMode; + this->meshCallback = meshCallback; - rendering= true; - lastTexture= 0; - glBindTexture(GL_TEXTURE_2D, 0); + rendering = true; + lastTexture = 0; + glBindTexture(GL_TEXTURE_2D, 0); - //push attribs - glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_POLYGON_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT); - glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); + //push attribs + glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_POLYGON_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT); + glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); - //init opengl - if(this->colorPickingMode == false) { - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - glBindTexture(GL_TEXTURE_2D, 0); - glFrontFace(GL_CCW); - - if(this->colorPickingMode == false) { - glEnable(GL_NORMALIZE); - glEnable(GL_BLEND); - - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(0.005f, 0.0f); - } - - glEnableClientState(GL_VERTEX_ARRAY); - - if(renderNormals){ - glEnableClientState(GL_NORMAL_ARRAY); - } - - if(renderTextures){ - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - } - -/* - glHint( GL_LINE_SMOOTH_HINT, GL_FASTEST ); - glHint( GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_FASTEST ); - glHint( GL_GENERATE_MIPMAP_HINT, GL_FASTEST ); - glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST ); - glHint( GL_POINT_SMOOTH_HINT, GL_FASTEST ); - glHint( GL_POLYGON_SMOOTH_HINT, GL_FASTEST ); - glHint( GL_TEXTURE_COMPRESSION_HINT, GL_FASTEST ); -*/ - - if(this->colorPickingMode == true) { - BaseColorPickEntity::beginPicking(); - } - - //assertions - assertGl(); -} - -void ModelRendererGl::end() { - //assertions - assert(rendering); - assertGl(); - - //set render state - rendering= false; - - if(this->colorPickingMode == false) { - glPolygonOffset( 0.0f, 0.0f ); - glDisable(GL_POLYGON_OFFSET_FILL); - } - - //pop - glPopAttrib(); - glPopClientAttrib(); - - if(colorPickingMode == true) { - BaseColorPickEntity::endPicking(); - } - - //assertions - assertGl(); -} - -void ModelRendererGl::render(Model *model,int renderMode) { - //assertions - assert(rendering); - assertGl(); - - //if(model->getIsStaticModel()) printf("In [%s::%s Line: %d] filename [%s] is static about to render...\n",__FILE__,__FUNCTION__,__LINE__,model->getFileName().c_str()); - - //render every mesh - //if(model->getIsStaticModel() == true) { - for(uint32 i = 0; i < model->getMeshCount(); ++i) { - renderMesh(model->getMeshPtr(i),renderMode); - } - //} - //assertions - assertGl(); -} - -void ModelRendererGl::renderNormalsOnly(Model *model) { - //assertions - assert(rendering); - assertGl(); - - //render every mesh - //if(model->getIsStaticModel() == true) { - for(uint32 i=0; igetMeshCount(); ++i) { - renderMeshNormals(model->getMeshPtr(i)); - } - //} - - //assertions - assertGl(); -} - -// ===================== PRIVATE ======================= - -void ModelRendererGl::renderMesh(Mesh *mesh,int renderMode) { - - if(renderMode==rmSelection && mesh->getNoSelect()==true) - {// don't render this and do nothing - return; - } - //assertions - assertGl(); - - //glPolygonOffset(0.05f, 0.0f); - //set cull face - if(mesh->getTwoSided()) { - glDisable(GL_CULL_FACE); - } - else{ - glEnable(GL_CULL_FACE); - } - - if(renderMode==rmNormal && mesh->getGlow()==true){ - // glow on - glDisable(GL_LIGHTING); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - } - - if(this->colorPickingMode == false) { - //set color - if(renderColors) { - Vec4f color(mesh->getDiffuseColor(), mesh->getOpacity()); - glColor4fv(color.ptr()); - } - - //texture state - const Texture2DGl *texture= static_cast(mesh->getTexture(mtDiffuse)); - if(texture != NULL && renderTextures) { - if(lastTexture != texture->getHandle()){ - //assert(glIsTexture(texture->getHandle())); - //throw megaglest_runtime_error("glIsTexture(texture->getHandle()) == false for texture: " + texture->getPath()); - if(glIsTexture(texture->getHandle()) == GL_TRUE) { - glBindTexture(GL_TEXTURE_2D, texture->getHandle()); - lastTexture= texture->getHandle(); + //init opengl + if (this->colorPickingMode == false) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - else { - glBindTexture(GL_TEXTURE_2D, 0); - lastTexture= 0; + glBindTexture(GL_TEXTURE_2D, 0); + glFrontFace(GL_CCW); + + if (this->colorPickingMode == false) { + glEnable(GL_NORMALIZE); + glEnable(GL_BLEND); + + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(0.005f, 0.0f); + } + + glEnableClientState(GL_VERTEX_ARRAY); + + if (renderNormals) { + glEnableClientState(GL_NORMAL_ARRAY); + } + + if (renderTextures) { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + + /* + glHint( GL_LINE_SMOOTH_HINT, GL_FASTEST ); + glHint( GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_FASTEST ); + glHint( GL_GENERATE_MIPMAP_HINT, GL_FASTEST ); + glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST ); + glHint( GL_POINT_SMOOTH_HINT, GL_FASTEST ); + glHint( GL_POLYGON_SMOOTH_HINT, GL_FASTEST ); + glHint( GL_TEXTURE_COMPRESSION_HINT, GL_FASTEST ); + */ + + if (this->colorPickingMode == true) { + BaseColorPickEntity::beginPicking(); + } + + //assertions + assertGl(); + } + + void ModelRendererGl::end() { + //assertions + assert(rendering); + assertGl(); + + //set render state + rendering = false; + + if (this->colorPickingMode == false) { + glPolygonOffset(0.0f, 0.0f); + glDisable(GL_POLYGON_OFFSET_FILL); + } + + //pop + glPopAttrib(); + glPopClientAttrib(); + + if (colorPickingMode == true) { + BaseColorPickEntity::endPicking(); + } + + //assertions + assertGl(); + } + + void ModelRendererGl::render(Model *model, int renderMode) { + //assertions + assert(rendering); + assertGl(); + + //if(model->getIsStaticModel()) printf("In [%s::%s Line: %d] filename [%s] is static about to render...\n",__FILE__,__FUNCTION__,__LINE__,model->getFileName().c_str()); + + //render every mesh + //if(model->getIsStaticModel() == true) { + for (uint32 i = 0; i < model->getMeshCount(); ++i) { + renderMesh(model->getMeshPtr(i), renderMode); + } + //} + //assertions + assertGl(); + } + + void ModelRendererGl::renderNormalsOnly(Model *model) { + //assertions + assert(rendering); + assertGl(); + + //render every mesh + //if(model->getIsStaticModel() == true) { + for (uint32 i = 0; i < model->getMeshCount(); ++i) { + renderMeshNormals(model->getMeshPtr(i)); + } + //} + + //assertions + assertGl(); + } + + // ===================== PRIVATE ======================= + + void ModelRendererGl::renderMesh(Mesh *mesh, int renderMode) { + + if (renderMode == rmSelection && mesh->getNoSelect() == true) {// don't render this and do nothing + return; + } + //assertions + assertGl(); + + //glPolygonOffset(0.05f, 0.0f); + //set cull face + if (mesh->getTwoSided()) { + glDisable(GL_CULL_FACE); + } else { + glEnable(GL_CULL_FACE); + } + + if (renderMode == rmNormal && mesh->getGlow() == true) { + // glow on + glDisable(GL_LIGHTING); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + } + + if (this->colorPickingMode == false) { + //set color + if (renderColors) { + Vec4f color(mesh->getDiffuseColor(), mesh->getOpacity()); + glColor4fv(color.ptr()); + } + + //texture state + const Texture2DGl *texture = static_cast(mesh->getTexture(mtDiffuse)); + if (texture != NULL && renderTextures) { + if (lastTexture != texture->getHandle()) { + //assert(glIsTexture(texture->getHandle())); + //throw megaglest_runtime_error("glIsTexture(texture->getHandle()) == false for texture: " + texture->getPath()); + if (glIsTexture(texture->getHandle()) == GL_TRUE) { + glBindTexture(GL_TEXTURE_2D, texture->getHandle()); + lastTexture = texture->getHandle(); + } else { + glBindTexture(GL_TEXTURE_2D, 0); + lastTexture = 0; + } + } + } else { + glBindTexture(GL_TEXTURE_2D, 0); + lastTexture = 0; + } + + if (meshCallback != NULL) { + meshCallback->execute(mesh); + } + } + + //misc vars + uint32 vertexCount = mesh->getVertexCount(); + uint32 indexCount = mesh->getIndexCount(); + + //assertions + assertGl(); + + if (getVBOSupported() == true && mesh->getFrameCount() == 1) { + if (mesh->hasBuiltVBOEntities() == false) { + mesh->BuildVBOs(); + } + //printf("Rendering Mesh with VBO's\n"); + + //vertices + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mesh->getVBOVertices()); + glVertexPointer(3, GL_FLOAT, 0, (char *) NULL); // Set The Vertex Pointer To The Vertex Buffer + //glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); + + //normals + if (renderNormals) { + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mesh->getVBONormals()); + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, (char *) NULL); + //glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); + } else { + glDisableClientState(GL_NORMAL_ARRAY); + } + + assertGl(); + + //tex coords + if (renderTextures && mesh->getTexture(mtDiffuse) != NULL) { + if (duplicateTexCoords) { + glActiveTexture(GL_TEXTURE0 + secondaryTexCoordUnit); + + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mesh->getVBOTexCoords()); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, (char *) NULL); // Set The TexCoord Pointer To The TexCoord Buffer + //glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); + } + + glActiveTexture(GL_TEXTURE0); + + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mesh->getVBOTexCoords()); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, (char *) NULL); // Set The TexCoord Pointer To The TexCoord Buffer + //glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); + } else { + if (duplicateTexCoords) { + glActiveTexture(GL_TEXTURE0 + secondaryTexCoordUnit); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + glActiveTexture(GL_TEXTURE0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + } else { + //printf("Rendering Mesh WITHOUT VBO's\n"); + + //vertices + glVertexPointer(3, GL_FLOAT, 0, mesh->getInterpolationData()->getVertices()); + + //normals + if (renderNormals) { + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, mesh->getInterpolationData()->getNormals()); + } else { + glDisableClientState(GL_NORMAL_ARRAY); + } + + assertGl(); + + //tex coords + if (renderTextures && mesh->getTexture(mtDiffuse) != NULL) { + if (duplicateTexCoords) { + glActiveTexture(GL_TEXTURE0 + secondaryTexCoordUnit); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, mesh->getTexCoords()); + } + + glActiveTexture(GL_TEXTURE0); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, mesh->getTexCoords()); + } else { + if (duplicateTexCoords) { + glActiveTexture(GL_TEXTURE0 + secondaryTexCoordUnit); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + glActiveTexture(GL_TEXTURE0); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + } + + if (getVBOSupported() == true && mesh->getFrameCount() == 1) { + assertGl(); + + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mesh->getVBOIndexes()); + glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, (char *) NULL); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + + //glDrawRangeElements(GL_TRIANGLES, 0, vertexCount-1, indexCount, GL_UNSIGNED_INT, mesh->getIndices()); + + assertGl(); + } else { + //draw model + assertGl(); + + glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, mesh->getIndices()); + } + + // glow + if (renderMode == rmNormal && mesh->getGlow() == true) { + // glow off + glEnable(GL_LIGHTING); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + //assertions + assertGl(); + } + + void ModelRendererGl::renderMeshNormals(Mesh *mesh) { + if (getVBOSupported() == true && mesh->getFrameCount() == 1) { + if (mesh->hasBuiltVBOEntities() == false) { + mesh->BuildVBOs(); + } + + //printf("Rendering Mesh Normals with VBO's\n"); + + //vertices + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mesh->getVBOVertices()); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, (char *) NULL); // Set The Vertex Pointer To The Vertex Buffer + //glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); + + //normals + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mesh->getVBONormals()); + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, (char *) NULL); + //glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); + + //misc vars + uint32 vertexCount = mesh->getVertexCount(); + uint32 indexCount = mesh->getIndexCount(); + + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mesh->getVBOIndexes()); + glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, (char *) NULL); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } else { + //printf("Rendering Mesh Normals WITHOUT VBO's\n"); + + glBegin(GL_LINES); + for (unsigned int i = 0; i < mesh->getIndexCount(); ++i) { + const Vec3f &vertex = mesh->getInterpolationData()->getVertices()[mesh->getIndices()[i]]; + const Vec3f &normal = vertex + mesh->getInterpolationData()->getNormals()[mesh->getIndices()[i]]; + + glVertex3fv(vertex.ptr()); + glVertex3fv(normal.ptr()); + } + glEnd(); } } - } - else{ - glBindTexture(GL_TEXTURE_2D, 0); - lastTexture= 0; - } - if(meshCallback != NULL) { - meshCallback->execute(mesh); } } - - //misc vars - uint32 vertexCount= mesh->getVertexCount(); - uint32 indexCount= mesh->getIndexCount(); - - //assertions - assertGl(); - - if(getVBOSupported() == true && mesh->getFrameCount() == 1) { - if(mesh->hasBuiltVBOEntities() == false) { - mesh->BuildVBOs(); - } - //printf("Rendering Mesh with VBO's\n"); - - //vertices - glBindBufferARB( GL_ARRAY_BUFFER_ARB, mesh->getVBOVertices() ); - glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL ); // Set The Vertex Pointer To The Vertex Buffer - //glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); - - //normals - if(renderNormals) { - glBindBufferARB( GL_ARRAY_BUFFER_ARB, mesh->getVBONormals() ); - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, (char *) NULL); - //glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); - } - else{ - glDisableClientState(GL_NORMAL_ARRAY); - } - - assertGl(); - - //tex coords - if(renderTextures && mesh->getTexture(mtDiffuse) != NULL ) { - if(duplicateTexCoords) { - glActiveTexture(GL_TEXTURE0 + secondaryTexCoordUnit); - - glBindBufferARB( GL_ARRAY_BUFFER_ARB, mesh->getVBOTexCoords() ); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL ); // Set The TexCoord Pointer To The TexCoord Buffer - //glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); - } - - glActiveTexture(GL_TEXTURE0); - - glBindBufferARB( GL_ARRAY_BUFFER_ARB, mesh->getVBOTexCoords() ); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL ); // Set The TexCoord Pointer To The TexCoord Buffer - //glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); - } - else { - if(duplicateTexCoords) { - glActiveTexture(GL_TEXTURE0 + secondaryTexCoordUnit); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - glActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - } - else { - //printf("Rendering Mesh WITHOUT VBO's\n"); - - //vertices - glVertexPointer(3, GL_FLOAT, 0, mesh->getInterpolationData()->getVertices()); - - //normals - if(renderNormals) { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, mesh->getInterpolationData()->getNormals()); - } - else{ - glDisableClientState(GL_NORMAL_ARRAY); - } - - assertGl(); - - //tex coords - if(renderTextures && mesh->getTexture(mtDiffuse)!=NULL ) { - if(duplicateTexCoords) { - glActiveTexture(GL_TEXTURE0 + secondaryTexCoordUnit); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, mesh->getTexCoords()); - } - - glActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, mesh->getTexCoords()); - } - else { - if(duplicateTexCoords) { - glActiveTexture(GL_TEXTURE0 + secondaryTexCoordUnit); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - glActiveTexture(GL_TEXTURE0); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - } - - if(getVBOSupported() == true && mesh->getFrameCount() == 1) { - assertGl(); - - glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, mesh->getVBOIndexes() ); - glDrawRangeElements(GL_TRIANGLES, 0, vertexCount-1, indexCount, GL_UNSIGNED_INT, (char *)NULL); - glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 ); - glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); - - //glDrawRangeElements(GL_TRIANGLES, 0, vertexCount-1, indexCount, GL_UNSIGNED_INT, mesh->getIndices()); - - assertGl(); - } - else { - //draw model - assertGl(); - - glDrawRangeElements(GL_TRIANGLES, 0, vertexCount-1, indexCount, GL_UNSIGNED_INT, mesh->getIndices()); - } - - // glow - if(renderMode==rmNormal && mesh->getGlow()==true){ - // glow off - glEnable(GL_LIGHTING); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - //assertions - assertGl(); -} - -void ModelRendererGl::renderMeshNormals(Mesh *mesh) { - if(getVBOSupported() == true && mesh->getFrameCount() == 1) { - if(mesh->hasBuiltVBOEntities() == false) { - mesh->BuildVBOs(); - } - - //printf("Rendering Mesh Normals with VBO's\n"); - - //vertices - glBindBufferARB( GL_ARRAY_BUFFER_ARB, mesh->getVBOVertices() ); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL ); // Set The Vertex Pointer To The Vertex Buffer - //glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); - - //normals - glBindBufferARB( GL_ARRAY_BUFFER_ARB, mesh->getVBONormals() ); - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, (char *) NULL); - //glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); - - //misc vars - uint32 vertexCount= mesh->getVertexCount(); - uint32 indexCount= mesh->getIndexCount(); - - glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, mesh->getVBOIndexes() ); - glDrawRangeElements(GL_TRIANGLES, 0, vertexCount-1, indexCount, GL_UNSIGNED_INT, (char *)NULL); - glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 ); - glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 ); - } - else { - //printf("Rendering Mesh Normals WITHOUT VBO's\n"); - - glBegin(GL_LINES); - for(unsigned int i = 0; i < mesh->getIndexCount(); ++i) { - const Vec3f &vertex= mesh->getInterpolationData()->getVertices()[mesh->getIndices()[i]]; - const Vec3f &normal= vertex + mesh->getInterpolationData()->getNormals()[mesh->getIndices()[i]]; - - glVertex3fv(vertex.ptr()); - glVertex3fv(normal.ptr()); - } - glEnd(); - } -} - -}}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/graphics/gl/opengl.cpp b/source/shared_lib/sources/graphics/gl/opengl.cpp index f76327c6d..c521e3747 100644 --- a/source/shared_lib/sources/graphics/gl/opengl.cpp +++ b/source/shared_lib/sources/graphics/gl/opengl.cpp @@ -24,153 +24,157 @@ using namespace Shared::Platform; using namespace Shared::Util; using namespace std; -namespace Shared { namespace Graphics { namespace Gl { +namespace Shared { + namespace Graphics { + namespace Gl { -std::map cacheExtensionCheckList; -static int vboEnabled = 0; + std::map cacheExtensionCheckList; + static int vboEnabled = 0; -// ===================================================== -// class Globals -// ===================================================== + // ===================================================== + // class Globals + // ===================================================== -bool getVBOSupported() { - if(vboEnabled == 0) { - bool value = isGlExtensionSupported("GL_ARB_vertex_buffer_object"); - vboEnabled = (value == true ? 1 : -1); + bool getVBOSupported() { + if (vboEnabled == 0) { + bool value = isGlExtensionSupported("GL_ARB_vertex_buffer_object"); + vboEnabled = (value == true ? 1 : -1); + } + return (vboEnabled == 1); + } + void setVBOSupported(bool value) { + vboEnabled = (value == true ? 1 : -1); + }; + + //void overrideGlExtensionSupport(const char *extensionName,bool value) { + // cacheExtensionCheckList[extensionName]=value; + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("OpenGL Extension [%s] supported status FORCED TO = %d\n",extensionName,cacheExtensionCheckList[extensionName]); + //} + + bool isGlExtensionSupported(const char *extensionName) { + if (cacheExtensionCheckList.find(extensionName) != cacheExtensionCheckList.end()) { + return cacheExtensionCheckList[extensionName]; + } + const GLubyte *extensionStr = glGetString(GL_EXTENSIONS); + const char *s = reinterpret_cast(extensionStr); + size_t len = strlen(extensionName); + + cacheExtensionCheckList[extensionName] = false; + if (s != NULL) { + while ((s = strstr(s, extensionName)) != NULL) { + s += len; + if ((*s == ' ') || (*s == '\0')) { + cacheExtensionCheckList[extensionName] = true; + break; + } + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("OpenGL Extension [%s] supported status = %d\n", extensionName, cacheExtensionCheckList[extensionName]); + return cacheExtensionCheckList[extensionName]; + } + + //bool isGlVersionSupported(int major, int minor, int release) { + // + // const char *strVersion= getGlVersion(); + // + // //major + // const char *majorTok= strVersion; + // int majorSupported= atoi(majorTok); + // + // if(majorSupportedmajor) { + // return true; + // } + // + // //minor + // int i=0; + // while(strVersion[i]!='.') { + // ++i; + // } + // const char *minorTok= &strVersion[i]+1; + // int minorSupported= atoi(minorTok); + // + // if(minorSupportedminor) { + // return true; + // } + // + // //release + // ++i; + // while(strVersion[i]!='.') { + // ++i; + // } + // const char *releaseTok= &strVersion[i]+1; + // + // if(atoi(releaseTok) < release) { + // return false; + // } + // + // return true; + //} + + const char *getGlVersion() { + return reinterpret_cast(glGetString(GL_VERSION)); + } + + const char *getGlRenderer() { + return reinterpret_cast(glGetString(GL_RENDERER)); + } + + const char *getGlVendor() { + return reinterpret_cast(glGetString(GL_VENDOR)); + } + + const char *getGlExtensions() { + return reinterpret_cast(glGetString(GL_EXTENSIONS)); + } + + const char *getGlPlatformExtensions() { + Context *c = GraphicsInterface::getInstance().getCurrentContext(); + return getPlatformExtensions(static_cast(c)->getPlatformContextGl()); + } + + int getGlMaxLights() { + int i; + glGetIntegerv(GL_MAX_LIGHTS, (GLint*) &i); + return i; + } + + int getGlMaxTextureSize() { + int i; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &i); + return i; + } + + int getGlMaxTextureUnits() { + int i; + glGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*) &i); + return i; + } + + int getGlModelviewMatrixStackDepth() { + int i; + glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, (GLint*) &i); + return i; + } + + int getGlProjectionMatrixStackDepth() { + int i; + glGetIntegerv(GL_MAX_PROJECTION_STACK_DEPTH, (GLint*) &i); + return i; + } + + //void checkGlExtension(const char *extensionName) { + // if(!isGlExtensionSupported(extensionName)){ + // throw megaglest_runtime_error("OpenGL extension not supported: " + string(extensionName)); + // } + //} + + } } - return (vboEnabled == 1); -} -void setVBOSupported(bool value) { - vboEnabled = (value == true ? 1 : -1); -}; - -//void overrideGlExtensionSupport(const char *extensionName,bool value) { -// cacheExtensionCheckList[extensionName]=value; -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("OpenGL Extension [%s] supported status FORCED TO = %d\n",extensionName,cacheExtensionCheckList[extensionName]); -//} - -bool isGlExtensionSupported(const char *extensionName) { - if(cacheExtensionCheckList.find(extensionName) != cacheExtensionCheckList.end()) { - return cacheExtensionCheckList[extensionName]; - } - const GLubyte *extensionStr= glGetString(GL_EXTENSIONS); - const char *s= reinterpret_cast(extensionStr); - size_t len= strlen(extensionName); - - cacheExtensionCheckList[extensionName]=false; - if(s != NULL) { - while ((s = strstr (s, extensionName)) != NULL) { - s+= len; - if((*s == ' ') || (*s == '\0')) { - cacheExtensionCheckList[extensionName] = true; - break; - } - } - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("OpenGL Extension [%s] supported status = %d\n",extensionName,cacheExtensionCheckList[extensionName]); - return cacheExtensionCheckList[extensionName]; -} - -//bool isGlVersionSupported(int major, int minor, int release) { -// -// const char *strVersion= getGlVersion(); -// -// //major -// const char *majorTok= strVersion; -// int majorSupported= atoi(majorTok); -// -// if(majorSupportedmajor) { -// return true; -// } -// -// //minor -// int i=0; -// while(strVersion[i]!='.') { -// ++i; -// } -// const char *minorTok= &strVersion[i]+1; -// int minorSupported= atoi(minorTok); -// -// if(minorSupportedminor) { -// return true; -// } -// -// //release -// ++i; -// while(strVersion[i]!='.') { -// ++i; -// } -// const char *releaseTok= &strVersion[i]+1; -// -// if(atoi(releaseTok) < release) { -// return false; -// } -// -// return true; -//} - -const char *getGlVersion() { - return reinterpret_cast(glGetString(GL_VERSION)); -} - -const char *getGlRenderer() { - return reinterpret_cast(glGetString(GL_RENDERER)); -} - -const char *getGlVendor() { - return reinterpret_cast(glGetString(GL_VENDOR)); -} - -const char *getGlExtensions() { - return reinterpret_cast(glGetString(GL_EXTENSIONS)); -} - -const char *getGlPlatformExtensions() { - Context *c= GraphicsInterface::getInstance().getCurrentContext(); - return getPlatformExtensions(static_cast(c)->getPlatformContextGl()); -} - -int getGlMaxLights() { - int i; - glGetIntegerv(GL_MAX_LIGHTS, (GLint*)&i); - return i; -} - -int getGlMaxTextureSize() { - int i; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&i); - return i; -} - -int getGlMaxTextureUnits() { - int i; - glGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&i); - return i; -} - -int getGlModelviewMatrixStackDepth() { - int i; - glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, (GLint*)&i); - return i; -} - -int getGlProjectionMatrixStackDepth() { - int i; - glGetIntegerv(GL_MAX_PROJECTION_STACK_DEPTH, (GLint*)&i); - return i; -} - -//void checkGlExtension(const char *extensionName) { -// if(!isGlExtensionSupported(extensionName)){ -// throw megaglest_runtime_error("OpenGL extension not supported: " + string(extensionName)); -// } -//} - -}}}// end namespace +}// end namespace diff --git a/source/shared_lib/sources/graphics/gl/particle_renderer_gl.cpp b/source/shared_lib/sources/graphics/gl/particle_renderer_gl.cpp index 981bff660..0aa42b879 100644 --- a/source/shared_lib/sources/graphics/gl/particle_renderer_gl.cpp +++ b/source/shared_lib/sources/graphics/gl/particle_renderer_gl.cpp @@ -17,291 +17,294 @@ #include "math_util.h" #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ namespace Gl{ +namespace Shared { + namespace Graphics { + namespace Gl { -// ===================================================== -// class ParticleRendererGl -// ===================================================== + // ===================================================== + // class ParticleRendererGl + // ===================================================== -// ===================== PUBLIC ======================== + // ===================== PUBLIC ======================== -ParticleRendererGl::ParticleRendererGl(){ - assert(bufferSize%4 == 0); + ParticleRendererGl::ParticleRendererGl() { + assert(bufferSize % 4 == 0); - rendering= false; + rendering = false; - // init texture coordinates for quads - for(int i= 0; irender(this, mr); - rendering= false; - - // blend mode back to normal - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - //pop state - glPopClientAttrib(); - glPopAttrib(); - - //assertions - assertGl(); -} - -void ParticleRendererGl::renderSystem(ParticleSystem *ps){ - assertGl(); - assert(rendering); - - Vec3f rightVector; - Vec3f upVector; - float modelview[16]; - - //render particles - setBlendMode(ps->getBlendMode()); - - // get the current modelview state - glGetFloatv(GL_MODELVIEW_MATRIX , modelview); - rightVector= Vec3f(modelview[0], modelview[4], modelview[8]); - upVector= Vec3f(modelview[1], modelview[5], modelview[9]); - - // set state - if(ps->getTexture()!=NULL){ - glBindTexture(GL_TEXTURE_2D, static_cast(ps->getTexture())->getHandle()); - } - else{ - glBindTexture(GL_TEXTURE_2D, 0); - } - glDisable(GL_ALPHA_TEST); - glDisable(GL_FOG); - glAlphaFunc(GL_GREATER, 0.0f); - glEnable(GL_TEXTURE_2D); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - - //fill vertex buffer with billboards - int bufferIndex= 0; - - for(int i=0; igetAliveParticleCount(); ++i){ - const Particle *particle= ps->getParticle(i); - float size= particle->getSize()/2.0f; - Vec3f pos= particle->getPos(); - Vec4f color= particle->getColor(); - - vertexBuffer[bufferIndex] = pos - (rightVector - upVector) * size; - vertexBuffer[bufferIndex+1] = pos - (rightVector + upVector) * size; - vertexBuffer[bufferIndex+2] = pos + (rightVector - upVector) * size; - vertexBuffer[bufferIndex+3] = pos + (rightVector + upVector) * size; - - colorBuffer[bufferIndex]= color; - colorBuffer[bufferIndex+1]= color; - colorBuffer[bufferIndex+2]= color; - colorBuffer[bufferIndex+3]= color; - - bufferIndex+= 4; - - if(bufferIndex >= bufferSize){ - bufferIndex= 0; - renderBufferQuads(bufferSize); - } - } - renderBufferQuads(bufferIndex); - - assertGl(); -} - -void ParticleRendererGl::renderSystemLine(ParticleSystem *ps){ - - assertGl(); - assert(rendering); - - if(!ps->isEmpty()){ - const Particle *particle= ps->getParticle(0); - - setBlendMode(ps->getBlendMode()); - - glDisable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - - //fill vertex buffer with lines - int bufferIndex= 0; - - glLineWidth(particle->getSize()); - - for(int i=0; igetAliveParticleCount(); ++i){ - particle= ps->getParticle(i); - Vec4f color= particle->getColor(); - - vertexBuffer[bufferIndex] = particle->getPos(); - vertexBuffer[bufferIndex+1] = particle->getLastPos(); - - colorBuffer[bufferIndex]= color; - colorBuffer[bufferIndex+1]= color; - - bufferIndex+= 2; - - if(bufferIndex >= bufferSize){ - bufferIndex= 0; - renderBufferLines(bufferSize); + // init texture coordinates for quads + for (int i = 0; i < bufferSize; i += 4) { + texCoordBuffer[i] = Vec2f(0.0f, 1.0f); + texCoordBuffer[i + 1] = Vec2f(0.0f, 0.0f); + texCoordBuffer[i + 2] = Vec2f(1.0f, 0.0f); + texCoordBuffer[i + 3] = Vec2f(1.0f, 1.0f); + } } - } - renderBufferLines(bufferIndex); - } - assertGl(); -} + void ParticleRendererGl::renderManager(ParticleManager *pm, ModelRenderer *mr) { -void ParticleRendererGl::renderSystemLineAlpha(ParticleSystem *ps){ + //assertions + assertGl(); - assertGl(); - assert(rendering); + //push state + glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_DEPTH_BUFFER_BIT | GL_POLYGON_BIT | GL_CURRENT_BIT | GL_LINE_BIT); + glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); - if(!ps->isEmpty()){ - const Particle *particle= ps->getParticle(0); + //init state + glFrontFace(GL_CCW); + glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); + glDisable(GL_LIGHTING); + glDisable(GL_STENCIL_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); - setBlendMode(ps->getBlendMode()); + //render + rendering = true; + pm->render(this, mr); + rendering = false; - glDisable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); + // blend mode back to normal + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); + //pop state + glPopClientAttrib(); + glPopAttrib(); - //fill vertex buffer with lines - int bufferIndex= 0; - - glLineWidth(particle->getSize()); - - for(int i=0; igetAliveParticleCount(); ++i){ - particle= ps->getParticle(i); - Vec4f color= particle->getColor(); - - vertexBuffer[bufferIndex] = particle->getPos(); - vertexBuffer[bufferIndex+1] = particle->getLastPos(); - - colorBuffer[bufferIndex]= color; - colorBuffer[bufferIndex+1]= color; - colorBuffer[bufferIndex+1].w= 0.0f; - - bufferIndex+= 2; - - if(bufferIndex >= bufferSize){ - bufferIndex= 0; - renderBufferLines(bufferSize); + //assertions + assertGl(); } + + void ParticleRendererGl::renderSystem(ParticleSystem *ps) { + assertGl(); + assert(rendering); + + Vec3f rightVector; + Vec3f upVector; + float modelview[16]; + + //render particles + setBlendMode(ps->getBlendMode()); + + // get the current modelview state + glGetFloatv(GL_MODELVIEW_MATRIX, modelview); + rightVector = Vec3f(modelview[0], modelview[4], modelview[8]); + upVector = Vec3f(modelview[1], modelview[5], modelview[9]); + + // set state + if (ps->getTexture() != NULL) { + glBindTexture(GL_TEXTURE_2D, static_cast(ps->getTexture())->getHandle()); + } else { + glBindTexture(GL_TEXTURE_2D, 0); + } + glDisable(GL_ALPHA_TEST); + glDisable(GL_FOG); + glAlphaFunc(GL_GREATER, 0.0f); + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + //fill vertex buffer with billboards + int bufferIndex = 0; + + for (int i = 0; i < ps->getAliveParticleCount(); ++i) { + const Particle *particle = ps->getParticle(i); + float size = particle->getSize() / 2.0f; + Vec3f pos = particle->getPos(); + Vec4f color = particle->getColor(); + + vertexBuffer[bufferIndex] = pos - (rightVector - upVector) * size; + vertexBuffer[bufferIndex + 1] = pos - (rightVector + upVector) * size; + vertexBuffer[bufferIndex + 2] = pos + (rightVector - upVector) * size; + vertexBuffer[bufferIndex + 3] = pos + (rightVector + upVector) * size; + + colorBuffer[bufferIndex] = color; + colorBuffer[bufferIndex + 1] = color; + colorBuffer[bufferIndex + 2] = color; + colorBuffer[bufferIndex + 3] = color; + + bufferIndex += 4; + + if (bufferIndex >= bufferSize) { + bufferIndex = 0; + renderBufferQuads(bufferSize); + } + } + renderBufferQuads(bufferIndex); + + assertGl(); + } + + void ParticleRendererGl::renderSystemLine(ParticleSystem *ps) { + + assertGl(); + assert(rendering); + + if (!ps->isEmpty()) { + const Particle *particle = ps->getParticle(0); + + setBlendMode(ps->getBlendMode()); + + glDisable(GL_TEXTURE_2D); + glDisable(GL_ALPHA_TEST); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + //fill vertex buffer with lines + int bufferIndex = 0; + + glLineWidth(particle->getSize()); + + for (int i = 0; i < ps->getAliveParticleCount(); ++i) { + particle = ps->getParticle(i); + Vec4f color = particle->getColor(); + + vertexBuffer[bufferIndex] = particle->getPos(); + vertexBuffer[bufferIndex + 1] = particle->getLastPos(); + + colorBuffer[bufferIndex] = color; + colorBuffer[bufferIndex + 1] = color; + + bufferIndex += 2; + + if (bufferIndex >= bufferSize) { + bufferIndex = 0; + renderBufferLines(bufferSize); + } + } + renderBufferLines(bufferIndex); + } + + assertGl(); + } + + void ParticleRendererGl::renderSystemLineAlpha(ParticleSystem *ps) { + + assertGl(); + assert(rendering); + + if (!ps->isEmpty()) { + const Particle *particle = ps->getParticle(0); + + setBlendMode(ps->getBlendMode()); + + glDisable(GL_TEXTURE_2D); + glDisable(GL_ALPHA_TEST); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + + //fill vertex buffer with lines + int bufferIndex = 0; + + glLineWidth(particle->getSize()); + + for (int i = 0; i < ps->getAliveParticleCount(); ++i) { + particle = ps->getParticle(i); + Vec4f color = particle->getColor(); + + vertexBuffer[bufferIndex] = particle->getPos(); + vertexBuffer[bufferIndex + 1] = particle->getLastPos(); + + colorBuffer[bufferIndex] = color; + colorBuffer[bufferIndex + 1] = color; + colorBuffer[bufferIndex + 1].w = 0.0f; + + bufferIndex += 2; + + if (bufferIndex >= bufferSize) { + bufferIndex = 0; + renderBufferLines(bufferSize); + } + } + renderBufferLines(bufferIndex); + } + + assertGl(); + } + + void ParticleRendererGl::renderModel(GameParticleSystem *ps, ModelRenderer *mr) { + //render model + Model *model = ps->getModel(); + if (model != NULL) { + + //init + glEnable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + glColor3f(1.f, 1.f, 1.f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + //translate + Vec3f pos = ps->getPos(); + glTranslatef(pos.x, pos.y, pos.z); + + //rotate + Vec3f direction = ps->getDirection(); + Vec3f flatDirection = Vec3f(direction.x, 0.f, direction.z); + Vec3f rotVector = Vec3f(0.f, 1.f, 0.f).cross(flatDirection); + + float angleV = radToDeg(std::atan2(flatDirection.length(), (float) direction.y)) - 90.f; + glRotatef(angleV, rotVector.x, rotVector.y, rotVector.z); + + float angleH = radToDeg(std::atan2(direction.x, direction.z)); + glRotatef(angleH, 0.f, 1.f, 0.f); + + //render + mr->begin(true, true, false, false); + float t = ps->getTween(); + + if (t < 0.0f || t > 1.0f) { + printf("In [%s::%s Line: %d] ERROR setting tween to [%f]\n", __FILE__, __FUNCTION__, __LINE__, t); + assert(t >= 0.0f && t <= 1.0f); + } + model->updateInterpolationData(t, false); + mr->render(model); + mr->end(); + + //end + glPopMatrix(); + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + } + } + + + // ============== PRIVATE ===================================== + + void ParticleRendererGl::renderBufferQuads(int quadCount) { + glVertexPointer(3, GL_FLOAT, 0, vertexBuffer); + glTexCoordPointer(2, GL_FLOAT, 0, texCoordBuffer); + glColorPointer(4, GL_FLOAT, 0, colorBuffer); + + glDrawArrays(GL_QUADS, 0, quadCount); + } + + void ParticleRendererGl::renderBufferLines(int lineCount) { + glVertexPointer(3, GL_FLOAT, 0, vertexBuffer); + glColorPointer(4, GL_FLOAT, 0, colorBuffer); + + glDrawArrays(GL_LINES, 0, lineCount); + } + + void ParticleRendererGl::setBlendMode(ParticleSystem::BlendMode blendMode) { + switch (blendMode) { + case ParticleSystem::bmOne: + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + break; + case ParticleSystem::bmOneMinusAlpha: + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + default: + assert(false); + break; + } + } + } - renderBufferLines(bufferIndex); } - - assertGl(); -} - -void ParticleRendererGl::renderModel(GameParticleSystem *ps, ModelRenderer *mr){ - //render model - Model *model = ps->getModel(); - if(model != NULL) { - - //init - glEnable(GL_LIGHTING); - glEnable(GL_TEXTURE_2D); - glColor3f(1.f, 1.f, 1.f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - - //translate - Vec3f pos= ps->getPos(); - glTranslatef(pos.x, pos.y, pos.z); - - //rotate - Vec3f direction= ps->getDirection(); - Vec3f flatDirection= Vec3f(direction.x, 0.f, direction.z); - Vec3f rotVector= Vec3f(0.f, 1.f, 0.f).cross(flatDirection); - - float angleV= radToDeg(std::atan2(flatDirection.length(), (float)direction.y)) - 90.f; - glRotatef(angleV, rotVector.x, rotVector.y, rotVector.z); - - float angleH= radToDeg(std::atan2(direction.x, direction.z)); - glRotatef(angleH, 0.f, 1.f, 0.f); - - //render - mr->begin(true, true, false, false); - float t = ps->getTween(); - - if(t < 0.0f || t > 1.0f) { - printf("In [%s::%s Line: %d] ERROR setting tween to [%f]\n",__FILE__,__FUNCTION__,__LINE__,t); - assert(t >= 0.0f && t <= 1.0f); - } - model->updateInterpolationData(t, false); - mr->render(model); - mr->end(); - - //end - glPopMatrix(); - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); - } -} - - -// ============== PRIVATE ===================================== - -void ParticleRendererGl::renderBufferQuads(int quadCount){ - glVertexPointer(3, GL_FLOAT, 0, vertexBuffer); - glTexCoordPointer(2, GL_FLOAT, 0, texCoordBuffer); - glColorPointer(4, GL_FLOAT, 0, colorBuffer); - - glDrawArrays(GL_QUADS, 0, quadCount); -} - -void ParticleRendererGl::renderBufferLines(int lineCount){ - glVertexPointer(3, GL_FLOAT, 0, vertexBuffer); - glColorPointer(4, GL_FLOAT, 0, colorBuffer); - - glDrawArrays(GL_LINES, 0, lineCount); -} - -void ParticleRendererGl::setBlendMode(ParticleSystem::BlendMode blendMode){ - switch(blendMode){ - case ParticleSystem::bmOne: - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - break; - case ParticleSystem::bmOneMinusAlpha: - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - break; - default: - assert(false); - break; - } -} - -}}} //end namespace +} //end namespace diff --git a/source/shared_lib/sources/graphics/gl/shader_gl.cpp b/source/shared_lib/sources/graphics/gl/shader_gl.cpp index bfdcbfb64..842faf852 100644 --- a/source/shared_lib/sources/graphics/gl/shader_gl.cpp +++ b/source/shared_lib/sources/graphics/gl/shader_gl.cpp @@ -18,233 +18,237 @@ using namespace std; -namespace Shared{ namespace Graphics{ namespace Gl{ +namespace Shared { + namespace Graphics { + namespace Gl { -// ===================================================== -// class ShaderProgramGl -// ===================================================== + // ===================================================== + // class ShaderProgramGl + // ===================================================== -ShaderProgramGl::ShaderProgramGl(){ - inited= false; - vertexShader=0; - fragmentShader=0; - handle=0; -} + ShaderProgramGl::ShaderProgramGl() { + inited = false; + vertexShader = 0; + fragmentShader = 0; + handle = 0; + } -void ShaderProgramGl::init(){ - if(!inited){ - assertGl(); - handle= glCreateProgramObjectARB(); - assertGl(); - inited= true; + void ShaderProgramGl::init() { + if (!inited) { + assertGl(); + handle = glCreateProgramObjectARB(); + assertGl(); + inited = true; + } + } + + void ShaderProgramGl::end() { + if (inited) { + assertGl(); + glDeleteObjectARB(handle); + assertGl(); + inited = false; + } + } + + void ShaderProgramGl::attach(VertexShader *vertexShader, FragmentShader *fragmentShader) { + this->vertexShader = vertexShader; + this->fragmentShader = fragmentShader; + } + + bool ShaderProgramGl::link(string &messages) { + assertGl(); + + VertexShaderGl *vertexShaderGl = static_cast(vertexShader); + FragmentShaderGl *fragmentShaderGl = static_cast(fragmentShader); + + const ShaderSource *vss = vertexShaderGl->getSource(); + const ShaderSource *fss = fragmentShaderGl->getSource(); + messages = "Linking program: " + vss->getPathInfo() + ", " + fss->getPathInfo() + "\n"; + + //attach + glAttachObjectARB(handle, vertexShaderGl->getHandle()); + glAttachObjectARB(handle, fragmentShaderGl->getHandle()); + + assertGl(); + + //bind attributes + for (unsigned int i = 0; i < attributes.size(); ++i) { + //int a= attributes[i].second; + //string s= attributes[i].first; + glBindAttribLocationARB(handle, attributes[i].second, attributes[i].first.c_str()); + } + + assertGl(); + + //link + glLinkProgramARB(handle); + glValidateProgramARB(handle); + + assertGl(); + + //log + GLint logLength = 0; + glGetObjectParameterivARB(handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logLength); + char *buffer = new char[logLength + 1]; + glGetInfoLogARB(handle, logLength + 1, NULL, buffer); + messages += buffer; + delete[] buffer; + + assertGl(); + + //status + GLint status = false; + glGetObjectParameterivARB(handle, GL_OBJECT_LINK_STATUS_ARB, &status); + + assertGl(); + + return status != 0; + } + + void ShaderProgramGl::activate() { + assertGl(); + glUseProgramObjectARB(handle); + assertGl(); + } + + void ShaderProgramGl::deactivate() { + assertGl(); + glUseProgramObjectARB(0); + assertGl(); + } + + void ShaderProgramGl::setUniform(const string &name, int value) { + assertGl(); + glUniform1iARB(getLocation(name), value); + assertGl(); + } + + void ShaderProgramGl::setUniform(const string &name, float value) { + assertGl(); + glUniform1fARB(getLocation(name), value); + assertGl(); + } + + void ShaderProgramGl::setUniform(const string &name, const Vec2f &value) { + assertGl(); + glUniform2fvARB(getLocation(name), 1, value.ptr()); + assertGl(); + } + + void ShaderProgramGl::setUniform(const string &name, const Vec3f &value) { + assertGl(); + glUniform3fvARB(getLocation(name), 1, value.ptr()); + assertGl(); + } + + void ShaderProgramGl::setUniform(const string &name, const Vec4f &value) { + assertGl(); + glUniform4fvARB(getLocation(name), 1, value.ptr()); + assertGl(); + } + + void ShaderProgramGl::setUniform(const string &name, const Matrix3f &value) { + assertGl(); + glUniformMatrix3fvARB(getLocation(name), 1, GL_FALSE, value.ptr()); + assertGl(); + } + + void ShaderProgramGl::setUniform(const string &name, const Matrix4f &value) { + assertGl(); + glUniformMatrix4fvARB(getLocation(name), 1, GL_FALSE, value.ptr()); + assertGl(); + } + + void ShaderProgramGl::bindAttribute(const string &name, int index) { + attributes.push_back(AttributePair(name, index)); + } + + GLint ShaderProgramGl::getLocation(const string &name) { + GLint location = glGetUniformLocationARB(handle, name.c_str()); + if (location == -1) { + throw megaglest_runtime_error("Can't locate uniform: " + name); + } + return location; + } + + // =============================================== + // class ShaderGl + // =============================================== + + ShaderGl::ShaderGl() { + inited = false; + handle = 0; + } + + void ShaderGl::load(const string &path) { + source.load(path); + } + + bool ShaderGl::compile(string &messages) { + + assertGl(); + + messages = "Compiling shader: " + source.getPathInfo() + "\n"; + + //load source + GLint length = (GLint) source.getCode().size(); + const GLcharARB *csource = source.getCode().c_str(); + glShaderSourceARB(handle, 1, &csource, &length); + + //compile + glCompileShaderARB(handle); + + //log + GLint logLength = 0; + glGetObjectParameterivARB(handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logLength); + char *buffer = new char[logLength + 1]; + glGetInfoLogARB(handle, logLength + 1, NULL, buffer); + messages += buffer; + delete[] buffer; + + //status + GLint status = false; + glGetObjectParameterivARB(handle, GL_OBJECT_COMPILE_STATUS_ARB, &status); + assertGl(); + + return status != 0; + } + + void ShaderGl::end() { + if (inited) { + assertGl(); + glDeleteObjectARB(handle); + assertGl(); + } + } + + // =============================================== + // class VertexShaderGl + // =============================================== + + void VertexShaderGl::init() { + if (!inited) { + assertGl(); + handle = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); + assertGl(); + inited = true; + } + } + + // =============================================== + // class FragmentShaderGl + // =============================================== + + void FragmentShaderGl::init() { + if (!inited) { + assertGl(); + handle = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); + assertGl(); + inited = true; + } + } + + } } -} - -void ShaderProgramGl::end(){ - if(inited){ - assertGl(); - glDeleteObjectARB(handle); - assertGl(); - inited= false; - } -} - -void ShaderProgramGl::attach(VertexShader *vertexShader, FragmentShader *fragmentShader){ - this->vertexShader= vertexShader; - this->fragmentShader= fragmentShader; -} - -bool ShaderProgramGl::link(string &messages){ - assertGl(); - - VertexShaderGl *vertexShaderGl= static_cast(vertexShader); - FragmentShaderGl *fragmentShaderGl= static_cast(fragmentShader); - - const ShaderSource *vss= vertexShaderGl->getSource(); - const ShaderSource *fss= fragmentShaderGl->getSource(); - messages= "Linking program: " + vss->getPathInfo() + ", " + fss->getPathInfo() + "\n"; - - //attach - glAttachObjectARB(handle, vertexShaderGl->getHandle()); - glAttachObjectARB(handle, fragmentShaderGl->getHandle()); - - assertGl(); - - //bind attributes - for(unsigned int i=0; ifont = NULL; -} + TextRenderer2DGl::TextRenderer2DGl() : TextRenderer2D() { + rendering = false; + this->font = NULL; + } -TextRenderer2DGl::~TextRenderer2DGl() { -} + TextRenderer2DGl::~TextRenderer2DGl() { + } -void TextRenderer2DGl::begin(Font2D *font) { - this->font = static_cast(font); + void TextRenderer2DGl::begin(Font2D *font) { + this->font = static_cast(font); - assert(!rendering); - rendering = true; -} + assert(!rendering); + rendering = true; + } -void TextRenderer2DGl::render(const string &text, float x, float y, bool centered, Vec3f *color) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("**** RENDERING 2D text [%s]\n",text.c_str()); + void TextRenderer2DGl::render(const string &text, float x, float y, bool centered, Vec3f *color) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("**** RENDERING 2D text [%s]\n", text.c_str()); - assert(rendering); - - assertGl(); + assert(rendering); - if(color != NULL) { - glPushAttrib(GL_CURRENT_BIT); - glColor3fv(color->ptr()); - } + assertGl(); - string renderText = text; - Font::bidi_cvt(renderText); - int line = 0; - int size = font->getSize(); - const unsigned char *utext = NULL; - FontMetrics *metrics = NULL; + if (color != NULL) { + glPushAttrib(GL_CURRENT_BIT); + glColor3fv(color->ptr()); + } - //printf("font->getTextHandler() [%p] centered = %d text [%s]\n",font->getTextHandler(),centered,text.c_str()); + string renderText = text; + Font::bidi_cvt(renderText); + int line = 0; + int size = font->getSize(); + const unsigned char *utext = NULL; + FontMetrics *metrics = NULL; - Vec2f rasterPos; - if(font->getTextHandler() != NULL) { - //char *utfStr = String::ConvertToUTF8(renderText.c_str()); - //renderText = utfStr; - //delete [] utfStr; + //printf("font->getTextHandler() [%p] centered = %d text [%s]\n",font->getTextHandler(),centered,text.c_str()); - if(centered) { - rasterPos.x= x - font->getTextHandler()->Advance(renderText.c_str()) / 2.f; - rasterPos.y= y + font->getTextHandler()->LineHeight(renderText.c_str()) / 2; - //printf("text [%s] x = %f, y = %f rasterPos [%s]\n",text.c_str(),x,y,rasterPos.getString().c_str()); - } - else { - rasterPos= Vec2f(static_cast(x), static_cast(y)); - //rasterPos.y= y + font->getTextHandler()->LineHeight(renderText.c_str()); - rasterPos.y= y; - //printf("text [%s] x = %f, y = %f rasterPos [%s]\n",text.c_str(),x,y,rasterPos.getString().c_str()); - } - } - else { - utext= reinterpret_cast(renderText.c_str()); - metrics= font->getMetrics(); - if(centered) { - rasterPos.x= x-metrics->getTextWidth(renderText)/2.f; - rasterPos.y= y + metrics->getHeight(renderText)/2.f; - } - else { - rasterPos= Vec2f(static_cast(x), static_cast(y)); - } - } - glRasterPos2f(rasterPos.x, rasterPos.y); + Vec2f rasterPos; + if (font->getTextHandler() != NULL) { + //char *utfStr = String::ConvertToUTF8(renderText.c_str()); + //renderText = utfStr; + //delete [] utfStr; - //fontFTGL->Render("مرحبا العالم"); //Arabic Works! - //wstring temp = L"المدى"; - //temp = wstring (temp.rbegin(), temp.rend()); - //font->getTextHandler()->Render(temp.c_str()); - //return; + if (centered) { + rasterPos.x = x - font->getTextHandler()->Advance(renderText.c_str()) / 2.f; + rasterPos.y = y + font->getTextHandler()->LineHeight(renderText.c_str()) / 2; + //printf("text [%s] x = %f, y = %f rasterPos [%s]\n",text.c_str(),x,y,rasterPos.getString().c_str()); + } else { + rasterPos = Vec2f(static_cast(x), static_cast(y)); + //rasterPos.y= y + font->getTextHandler()->LineHeight(renderText.c_str()); + rasterPos.y = y; + //printf("text [%s] x = %f, y = %f rasterPos [%s]\n",text.c_str(),x,y,rasterPos.getString().c_str()); + } + } else { + utext = reinterpret_cast(renderText.c_str()); + metrics = font->getMetrics(); + if (centered) { + rasterPos.x = x - metrics->getTextWidth(renderText) / 2.f; + rasterPos.y = y + metrics->getHeight(renderText) / 2.f; + } else { + rasterPos = Vec2f(static_cast(x), static_cast(y)); + } + } + glRasterPos2f(rasterPos.x, rasterPos.y); - //font->getTextHandler()->Render("Zurück"); - //return; + //fontFTGL->Render("مرحبا العالم"); //Arabic Works! + //wstring temp = L"المدى"; + //temp = wstring (temp.rbegin(), temp.rend()); + //font->getTextHandler()->Render(temp.c_str()); + //return; - if(Font::fontIsMultibyte == true) { - if(font->getTextHandler() != NULL) { - //string renderText = text; - if(Font::fontIsRightToLeft == true) { - //printf("\n\n#A [%s]\n",renderText.c_str()); - //bool isRLM = utf8::starts_with_rlm(text.begin(), text.end() + text.size()); + //font->getTextHandler()->Render("Zurück"); + //return; - //printf("\n\nORIGINAL TEXT [%s] isRLM = %d\n\n",text.c_str(),isRLM); - //for(int i = 0; i < renderText.size(); ++i) { - // printf("i = %d c [%c][%d][%X]\n",i,renderText[i],renderText[i],renderText[i]); + if (Font::fontIsMultibyte == true) { + if (font->getTextHandler() != NULL) { + //string renderText = text; + if (Font::fontIsRightToLeft == true) { + //printf("\n\n#A [%s]\n",renderText.c_str()); + //bool isRLM = utf8::starts_with_rlm(text.begin(), text.end() + text.size()); + + //printf("\n\nORIGINAL TEXT [%s] isRLM = %d\n\n",text.c_str(),isRLM); + //for(int i = 0; i < renderText.size(); ++i) { + // printf("i = %d c [%c][%d][%X]\n",i,renderText[i],renderText[i],renderText[i]); + //} + //if(isRLM == true) { + if (is_string_all_ascii(renderText) == false) { + strrev_utf8(renderText); + } + } + + //String str("資料"); + //WString wstr(str); + //fontFTGL->Render(wstr.cw_str()); + + //String str(L"資料"); + //WString wstr(str); + //fontFTGL->Render(wstr.cw_str()); + + //WString wstr(L"資料"); + //fontFTGL->Render(wstr.cw_str()); + + //size_t length = text.length(); + + // string temp = String::ConvertToUTF8("資料"); + // size_t length = temp.length(); + // wchar_t *utf32 = (wchar_t*)malloc((length+1) * sizeof(wchar_t)); + // mbstowcs(utf32, temp.c_str(), length); + // utf32[length] = 0; + // fontFTGL->Render(utf32); + // free(utf32); + + //wstring wstr(L"資料"); + //fontFTGL->Render(wstr.c_str()); + + //fontFTGL->Render(text.c_str()); + + //const wchar_t *str = L" 中文"; + //fontFTGL->Render(str); + + //fontFTGL->Render(" 中文"); // Chinese Works! + //fontFTGL->Render("ёшзхсдертбнйуимлопьжющэъ́"); // Russian Works! + //fontFTGL->Render("更新履歴はこちらをご覧下さい。"); // Japanese Works! + + //fontFTGL->Render("مرحبا العالم"); //Arabic Works! + //wstring temp = L"مرحبا العالم"; + //temp = wstring (temp.rbegin(), temp.rend()); + //fontFTGL->Render(temp.c_str()); + + // Hebrew is Right To Left + //wstring temp = L"שלום העולם"; + //temp = wstring (temp.rbegin(), temp.rend()); + //fontFTGL->Render(temp.c_str()); + + //fontFTGL->Render("testování slovanský jazyk"); // Czech Works! + + // This works + //fontFTGL->Render(text.c_str()); + + if (renderText.find("\n") == renderText.npos && renderText.find("\t") == renderText.npos) { + font->getTextHandler()->Render(renderText.c_str()); + } else { + bool lastCharacterWasSpecial = true; + vector parts; + char szBuf[8096] = ""; + + for (int i = 0; renderText[i] != '\0'; ++i) { + szBuf[0] = '\0'; + snprintf(szBuf, 8096, "%c", renderText[i]); + + switch (renderText[i]) { + case '\t': + parts.push_back(szBuf); + lastCharacterWasSpecial = true; + //rasterPos= Vec2f((rasterPos.x / size + 3.f) * size, y-(size + 1.f) * line); + //glRasterPos2f(rasterPos.x, rasterPos.y); + break; + case '\n': + parts.push_back(szBuf); + lastCharacterWasSpecial = true; + //line++; + //rasterPos= Vec2f(static_cast(x), y - (fontFTGL->LineHeight(text.c_str()) * 2.f) * line); + //glRasterPos2f(rasterPos.x, rasterPos.y); + break; + default: + //glCallList(font->getHandle()+utext[i]); + if (lastCharacterWasSpecial == true) { + parts.push_back(szBuf); + } else { + parts[parts.size() - 1] += szBuf; + } + lastCharacterWasSpecial = false; + break; + } + } + + for (unsigned int i = 0; i < parts.size(); ++i) { + switch (parts[i][0]) { + case '\t': + rasterPos = Vec2f((rasterPos.x / size + 3.f) * size, y - (size + 1.f) * line); + glRasterPos2f(rasterPos.x, rasterPos.y); + break; + case '\n': + line++; + rasterPos = Vec2f(static_cast(x), y - (font->getTextHandler()->LineHeight(parts[i].c_str())) * line); + glRasterPos2f(rasterPos.x, rasterPos.y); + break; + default: + font->getTextHandler()->Render(parts[i].c_str()); + break; + } + } + } + } else { + //setlocale(LC_CTYPE, "en_ca.UTF-8"); + + //wstring wText = widen(text); + //glListBase(font->getHandle()); + //glCallLists(wText.length(), GL_UNSIGNED_SHORT, &wText[0]); + + //string utfText = text; + //glListBase(font->getHandle()); + //glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]); + + string utfText = renderText; + if (Font::fontIsRightToLeft == true) { + if (is_string_all_ascii(utfText) == false) { + strrev_utf8(utfText); + } + } + + glListBase(font->getHandle()); + glCallLists((GLsizei) renderText.length(), GL_UNSIGNED_SHORT, &utext[0]); + + //std::locale loc(""); + //wstring wText = widen(text); + //std::string strBuffer(Text.size() * 4 + 1, 0); + //std::use_facet >(loc).narrow(&Text[0], &Text[0] + Text.size(), '?', &strBuffer[0]); + //string utfText = std::string(&strBuffer[0]); + //glListBase(font->getHandle()); + //glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]); + } + } else { + if (font->getTextHandler() != NULL) { + //string renderText = text; + if (Font::fontIsRightToLeft == true) { + if (is_string_all_ascii(renderText) == false) { + strrev_utf8(renderText); + } + } + + if (renderText.find("\n") == renderText.npos && renderText.find("\t") == renderText.npos) { + font->getTextHandler()->Render(renderText.c_str()); + } else { + bool lastCharacterWasSpecial = true; + vector parts; + char szBuf[8096] = ""; + + for (int i = 0; renderText[i] != '\0'; ++i) { + szBuf[0] = '\0'; + snprintf(szBuf, 8096, "%c", renderText[i]); + + switch (renderText[i]) { + case '\t': + parts.push_back(szBuf); + lastCharacterWasSpecial = true; + //rasterPos= Vec2f((rasterPos.x / size + 3.f) * size, y-(size + 1.f) * line); + //glRasterPos2f(rasterPos.x, rasterPos.y); + break; + case '\n': + parts.push_back(szBuf); + lastCharacterWasSpecial = true; + //line++; + //rasterPos= Vec2f(static_cast(x), y - (fontFTGL->LineHeight(text.c_str()) * 2.f) * line); + //glRasterPos2f(rasterPos.x, rasterPos.y); + break; + default: + //glCallList(font->getHandle()+utext[i]); + if (lastCharacterWasSpecial == true) { + parts.push_back(szBuf); + } else { + parts[parts.size() - 1] += szBuf; + } + lastCharacterWasSpecial = false; + break; + } + } + + for (unsigned int i = 0; i < parts.size(); ++i) { + switch (parts[i][0]) { + case '\t': + rasterPos = Vec2f((rasterPos.x / size + 3.f) * size, y - (size + 1.f) * line); + glRasterPos2f(rasterPos.x, rasterPos.y); + break; + case '\n': + line++; + rasterPos = Vec2f(static_cast(x), y - (font->getTextHandler()->LineHeight(parts[i].c_str())) * line); + glRasterPos2f(rasterPos.x, rasterPos.y); + break; + default: + font->getTextHandler()->Render(parts[i].c_str()); + break; + } + } + } + } else { + for (int i = 0; utext[i] != '\0'; ++i) { + switch (utext[i]) { + case '\t': + rasterPos = Vec2f((rasterPos.x / size + 3.f)*size, y - (size + 1.f)*line); + glRasterPos2f(rasterPos.x, rasterPos.y); + break; + case '\n': + line++; + rasterPos = Vec2f(static_cast(x), y - (metrics->getHeight("W")*2.f)*line); + glRasterPos2f(rasterPos.x, rasterPos.y); + break; + default: + glCallList(font->getHandle() + utext[i]); + } + } + } + } + + if (color != NULL) { + glPopAttrib(); + } + assertGl(); + } + + void TextRenderer2DGl::end() { + //tester->end(); + //return; + + assert(rendering); + rendering = false; + } + + // ===================================================== + // class TextRenderer3DGl + // ===================================================== + + TextRenderer3DGl::TextRenderer3DGl() : TextRenderer3D() { + rendering = false; + this->font = NULL; + currentFTGLErrorCount = 0; + } + + TextRenderer3DGl::~TextRenderer3DGl() { + } + + void TextRenderer3DGl::begin(Font3D *font) { + assert(!rendering); + rendering = true; + + this->font = static_cast(font); + + assertGl(); + + //load color + glPushAttrib(GL_TRANSFORM_BIT); + + //assertGl(); + } + + void TextRenderer3DGl::render(const string &text, float x, float y, bool centered, Vec3f *color) { + assert(rendering); + + if (text.empty() == false) { + string renderText = text; + Font::bidi_cvt(renderText); + + if (Font::fontIsMultibyte == true) { + if (font->getTextHandler() != NULL) { + if (Font::fontIsRightToLeft == true) { + //printf("\n\n#A [%s]\n",renderText.c_str()); + //bool isRLM = utf8::starts_with_rlm(text.begin(), text.end() + text.size()); + + //printf("\n\nORIGINAL TEXT [%s] isRLM = %d\n\n",text.c_str(),isRLM); + //for(int i = 0; i < renderText.size(); ++i) { + // printf("i = %d c [%c][%d][%X]\n",i,renderText[i],renderText[i],renderText[i]); + //} + //if(isRLM == true) { + if (is_string_all_ascii(renderText) == false) { + //printf("\n\nORIGINAL TEXT [%s]\n\n",text.c_str()); + //for(int i = 0; i < renderText.size(); ++i) { + // printf("i = %d c [%c][%d][%X]\n",i,renderText[i],renderText[i],renderText[i]); + //} + + strrev_utf8(renderText); + } + } + } + } + + internalRender(renderText, x, y, centered, color); + } + } + + void TextRenderer3DGl::specialFTGLErrorCheckWorkaround(string text) { + + for (GLenum error = glGetError(); error != GL_NO_ERROR; error = glGetError()) { + //error = glGetError(); + //if(error) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nIn [%s::%s Line: %d] error = %d for text [%s]\n\n", __FILE__, __FUNCTION__, __LINE__, error, text.c_str()); + + if (currentFTGLErrorCount > 0) { + printf("\n**FTGL Error = %d [%s] for text [%s] currentFTGLErrorCount = %d\n\n", error, gluErrorString(error), text.c_str(), currentFTGLErrorCount); + fflush(stdout); + + assertGlWithErrorNumber(error); + } else { + printf("\n**FTGL #2 Error = %d [%s] for text [%s] currentFTGLErrorCount = %d\n\n", error, gluErrorString(error), text.c_str(), currentFTGLErrorCount); + fflush(stdout); + } + + currentFTGLErrorCount++; + } //} - //if(isRLM == true) { - if(is_string_all_ascii(renderText) == false) { - strrev_utf8(renderText); - } } - //String str("資料"); - //WString wstr(str); - //fontFTGL->Render(wstr.cw_str()); + void TextRenderer3DGl::internalRender(const string &text, float x, float y, bool centered, Vec3f *color) { + //assert(rendering); - //String str(L"資料"); - //WString wstr(str); - //fontFTGL->Render(wstr.cw_str()); + if (color != NULL) { + //assertGl(); + glPushAttrib(GL_CURRENT_BIT); - //WString wstr(L"資料"); - //fontFTGL->Render(wstr.cw_str()); + //assertGl(); - //size_t length = text.length(); + glColor3fv(color->ptr()); - // string temp = String::ConvertToUTF8("資料"); - // size_t length = temp.length(); - // wchar_t *utf32 = (wchar_t*)malloc((length+1) * sizeof(wchar_t)); - // mbstowcs(utf32, temp.c_str(), length); - // utf32[length] = 0; - // fontFTGL->Render(utf32); - // free(utf32); - - //wstring wstr(L"資料"); - //fontFTGL->Render(wstr.c_str()); - - //fontFTGL->Render(text.c_str()); - - //const wchar_t *str = L" 中文"; - //fontFTGL->Render(str); - - //fontFTGL->Render(" 中文"); // Chinese Works! - //fontFTGL->Render("ёшзхсдертбнйуимлопьжющэъ́"); // Russian Works! - //fontFTGL->Render("更新履歴はこちらをご覧下さい。"); // Japanese Works! - - //fontFTGL->Render("مرحبا العالم"); //Arabic Works! - //wstring temp = L"مرحبا العالم"; - //temp = wstring (temp.rbegin(), temp.rend()); - //fontFTGL->Render(temp.c_str()); - - // Hebrew is Right To Left - //wstring temp = L"שלום העולם"; - //temp = wstring (temp.rbegin(), temp.rend()); - //fontFTGL->Render(temp.c_str()); - - //fontFTGL->Render("testování slovanský jazyk"); // Czech Works! - - // This works - //fontFTGL->Render(text.c_str()); - - if(renderText.find("\n") == renderText.npos && renderText.find("\t") == renderText.npos) { - font->getTextHandler()->Render(renderText.c_str()); - } - else { - bool lastCharacterWasSpecial = true; - vector parts; - char szBuf[8096]=""; - - for (int i=0; renderText[i] != '\0'; ++i) { - szBuf[0] = '\0'; - snprintf(szBuf,8096,"%c",renderText[i]); - - switch(renderText[i]) { - case '\t': - parts.push_back(szBuf); - lastCharacterWasSpecial = true; - //rasterPos= Vec2f((rasterPos.x / size + 3.f) * size, y-(size + 1.f) * line); - //glRasterPos2f(rasterPos.x, rasterPos.y); - break; - case '\n': - parts.push_back(szBuf); - lastCharacterWasSpecial = true; - //line++; - //rasterPos= Vec2f(static_cast(x), y - (fontFTGL->LineHeight(text.c_str()) * 2.f) * line); - //glRasterPos2f(rasterPos.x, rasterPos.y); - break; - default: - //glCallList(font->getHandle()+utext[i]); - if(lastCharacterWasSpecial == true) { - parts.push_back(szBuf); - } - else { - parts[parts.size()-1] += szBuf; - } - lastCharacterWasSpecial = false; - break; - } + //assertGl(); } - for (unsigned int i=0; i < parts.size(); ++i) { - switch(parts[i][0]) { - case '\t': - rasterPos= Vec2f((rasterPos.x / size + 3.f) * size, y-(size + 1.f) * line); - glRasterPos2f(rasterPos.x, rasterPos.y); - break; - case '\n': - line++; - rasterPos= Vec2f(static_cast(x), y - (font->getTextHandler()->LineHeight(parts[i].c_str())) * line); - glRasterPos2f(rasterPos.x, rasterPos.y); - break; - default: - font->getTextHandler()->Render(parts[i].c_str()); - break; - } - } - } - } - else { - //setlocale(LC_CTYPE, "en_ca.UTF-8"); + string renderText = text; + const unsigned char *utext = NULL; + //assertGl(); - //wstring wText = widen(text); - //glListBase(font->getHandle()); - //glCallLists(wText.length(), GL_UNSIGNED_SHORT, &wText[0]); + //glMatrixMode(GL_TEXTURE); - //string utfText = text; - //glListBase(font->getHandle()); - //glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]); + //assertGl(); - string utfText = renderText; - if(Font::fontIsRightToLeft == true) { - if(is_string_all_ascii(utfText) == false) { - strrev_utf8(utfText); - } - } + glPushMatrix(); - glListBase(font->getHandle()); - glCallLists((GLsizei)renderText.length(), GL_UNSIGNED_SHORT, &utext[0]); + //assertGl(); - //std::locale loc(""); - //wstring wText = widen(text); - //std::string strBuffer(Text.size() * 4 + 1, 0); - //std::use_facet >(loc).narrow(&Text[0], &Text[0] + Text.size(), '?', &strBuffer[0]); - //string utfText = std::string(&strBuffer[0]); - //glListBase(font->getHandle()); - //glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]); - } - } - else { - if(font->getTextHandler() != NULL) { - //string renderText = text; - if(Font::fontIsRightToLeft == true) { - if(is_string_all_ascii(renderText) == false) { - strrev_utf8(renderText); - } - } + glLoadIdentity(); - if(renderText.find("\n") == renderText.npos && renderText.find("\t") == renderText.npos) { - font->getTextHandler()->Render(renderText.c_str()); - } - else { - bool lastCharacterWasSpecial = true; - vector parts; - char szBuf[8096]=""; + //assertGl(); - for (int i=0; renderText[i] != '\0'; ++i) { - szBuf[0] = '\0'; - snprintf(szBuf,8096,"%c",renderText[i]); + //glPushAttrib(GL_POLYGON_BIT); - switch(renderText[i]) { - case '\t': - parts.push_back(szBuf); - lastCharacterWasSpecial = true; - //rasterPos= Vec2f((rasterPos.x / size + 3.f) * size, y-(size + 1.f) * line); - //glRasterPos2f(rasterPos.x, rasterPos.y); - break; - case '\n': - parts.push_back(szBuf); - lastCharacterWasSpecial = true; - //line++; - //rasterPos= Vec2f(static_cast(x), y - (fontFTGL->LineHeight(text.c_str()) * 2.f) * line); - //glRasterPos2f(rasterPos.x, rasterPos.y); - break; - default: - //glCallList(font->getHandle()+utext[i]); - if(lastCharacterWasSpecial == true) { - parts.push_back(szBuf); - } - else { - parts[parts.size()-1] += szBuf; - } - lastCharacterWasSpecial = false; - break; - } - } + int size = font->getSize(); + //float scale= size / 15.f; + Vec3f translatePos; + FontMetrics *metrics = font->getMetrics(); - for (unsigned int i=0; i < parts.size(); ++i) { - switch(parts[i][0]) { - case '\t': - rasterPos= Vec2f((rasterPos.x / size + 3.f) * size, y-(size + 1.f) * line); - glRasterPos2f(rasterPos.x, rasterPos.y); - break; - case '\n': - line++; - rasterPos= Vec2f(static_cast(x), y - (font->getTextHandler()->LineHeight(parts[i].c_str())) * line); - glRasterPos2f(rasterPos.x, rasterPos.y); - break; - default: - font->getTextHandler()->Render(parts[i].c_str()); - break; - } - } - } - } - else { - for (int i=0; utext[i]!='\0'; ++i) { - switch(utext[i]){ - case '\t': - rasterPos= Vec2f((rasterPos.x/size+3.f)*size, y-(size+1.f)*line); - glRasterPos2f(rasterPos.x, rasterPos.y); - break; - case '\n': - line++; - rasterPos= Vec2f(static_cast(x), y-(metrics->getHeight("W")*2.f)*line); - glRasterPos2f(rasterPos.x, rasterPos.y); - break; - default: - glCallList(font->getHandle()+utext[i]); - } - } - } - } + if (font->getTextHandler() != NULL) { + //char *utfStr = String::ConvertToUTF8(renderText.c_str()); + //renderText = utfStr; + //delete [] utfStr; - if(color != NULL) { - glPopAttrib(); - } - assertGl(); -} + //centered = false; + if (centered) { + //printf("3d text to center [%s] advance = %f, x = %f\n",text.c_str(),font->getTextHandler()->Advance(text.c_str()), x); + //printf("3d text to center [%s] lineheight = %f, y = %f\n",text.c_str(),font->getTextHandler()->LineHeight(text.c_str()), y); -void TextRenderer2DGl::end() { - //tester->end(); - //return; - - assert(rendering); - rendering= false; -} - -// ===================================================== -// class TextRenderer3DGl -// ===================================================== - -TextRenderer3DGl::TextRenderer3DGl() : TextRenderer3D() { - rendering= false; - this->font = NULL; - currentFTGLErrorCount = 0; -} - -TextRenderer3DGl::~TextRenderer3DGl() { -} - -void TextRenderer3DGl::begin(Font3D *font) { - assert(!rendering); - rendering= true; - - this->font= static_cast(font); - - assertGl(); - - //load color - glPushAttrib(GL_TRANSFORM_BIT); - - //assertGl(); -} - -void TextRenderer3DGl::render(const string &text, float x, float y, bool centered, Vec3f *color) { - assert(rendering); - - if(text.empty() == false) { - string renderText = text; - Font::bidi_cvt(renderText); - - if(Font::fontIsMultibyte == true) { - if(font->getTextHandler() != NULL) { - if(Font::fontIsRightToLeft == true) { - //printf("\n\n#A [%s]\n",renderText.c_str()); - //bool isRLM = utf8::starts_with_rlm(text.begin(), text.end() + text.size()); - - //printf("\n\nORIGINAL TEXT [%s] isRLM = %d\n\n",text.c_str(),isRLM); - //for(int i = 0; i < renderText.size(); ++i) { - // printf("i = %d c [%c][%d][%X]\n",i,renderText[i],renderText[i],renderText[i]); - //} - //if(isRLM == true) { - if(is_string_all_ascii(renderText) == false) { - //printf("\n\nORIGINAL TEXT [%s]\n\n",text.c_str()); - //for(int i = 0; i < renderText.size(); ++i) { - // printf("i = %d c [%c][%d][%X]\n",i,renderText[i],renderText[i],renderText[i]); - //} - - strrev_utf8(renderText); - } - } - } - } - - internalRender(renderText, x, y, centered, color); - } -} - -void TextRenderer3DGl::specialFTGLErrorCheckWorkaround(string text) { - - for(GLenum error = glGetError(); error != GL_NO_ERROR; error = glGetError()) { - //error = glGetError(); - //if(error) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nIn [%s::%s Line: %d] error = %d for text [%s]\n\n",__FILE__,__FUNCTION__,__LINE__,error,text.c_str()); - - if(currentFTGLErrorCount > 0) { - printf("\n**FTGL Error = %d [%s] for text [%s] currentFTGLErrorCount = %d\n\n",error,gluErrorString(error),text.c_str(),currentFTGLErrorCount); - fflush(stdout); - - assertGlWithErrorNumber(error); - } - else { - printf("\n**FTGL #2 Error = %d [%s] for text [%s] currentFTGLErrorCount = %d\n\n",error,gluErrorString(error),text.c_str(),currentFTGLErrorCount); - fflush(stdout); - } - - currentFTGLErrorCount++; - } - //} -} - -void TextRenderer3DGl::internalRender(const string &text, float x, float y, bool centered, Vec3f *color) { - //assert(rendering); - - if(color != NULL) { - //assertGl(); - glPushAttrib(GL_CURRENT_BIT); - - //assertGl(); - - glColor3fv(color->ptr()); - - //assertGl(); - } - - string renderText = text; - const unsigned char *utext= NULL; - //assertGl(); - - //glMatrixMode(GL_TEXTURE); - - //assertGl(); - - glPushMatrix(); - - //assertGl(); - - glLoadIdentity(); - - //assertGl(); - - //glPushAttrib(GL_POLYGON_BIT); - - int size = font->getSize(); - //float scale= size / 15.f; - Vec3f translatePos; - FontMetrics *metrics= font->getMetrics(); - - if(font->getTextHandler() != NULL) { - //char *utfStr = String::ConvertToUTF8(renderText.c_str()); - //renderText = utfStr; - //delete [] utfStr; - - //centered = false; - if(centered) { - //printf("3d text to center [%s] advance = %f, x = %f\n",text.c_str(),font->getTextHandler()->Advance(text.c_str()), x); - //printf("3d text to center [%s] lineheight = %f, y = %f\n",text.c_str(),font->getTextHandler()->LineHeight(text.c_str()), y); - -// translatePos.x = x - scale * font->getTextHandler()->Advance(text.c_str()) / 2.f; -// translatePos.y = y - scale * font->getTextHandler()->LineHeight(text.c_str()) / font->getYOffsetFactor(); - //assertGl(); - translatePos.x = x - (font->getTextHandler()->Advance(renderText.c_str()) / 2.f); - //assertGl(); - //translatePos.y = y - (font->getTextHandler()->LineHeight(text.c_str()) / font->getYOffsetFactor()); - translatePos.y = y - ((font->getTextHandler()->LineHeight(renderText.c_str()) * Font::scaleFontValue) / 2.f); - //assertGl(); - - translatePos.z = 0; - } - else { - //printf("3d text [%s] advance = %f, x = %f\n",text.c_str(),font->getTextHandler()->Advance(text.c_str()), x); - -// translatePos.x = x-scale; -// translatePos.y = y-scale; - translatePos.x = x; - translatePos.y = y; - - translatePos.z = 0; - } - } - else { - float scale= 1.0f; - //float scale= size; - - utext= reinterpret_cast(renderText.c_str()); - if(centered) { - //glTranslatef(x-scale*metrics->getTextWidth(text)/2.f, y-scale*metrics->getHeight()/2.f, 0); - translatePos.x = x-scale*metrics->getTextWidth(renderText)/2.f; - translatePos.y = y-scale*metrics->getHeight(renderText)/2.f; - translatePos.z = 0; - } - else { - //glTranslatef(x-scale, y-scale, 0); - translatePos.x = x-scale; - translatePos.y = y-scale; - translatePos.z = 0; - } - } - - //float scaleX = 0.65; - //float scaleY = 0.75; - //float scaleZ = 1.0; - - //float scaleX = 1; - //float scaleY = 1; - //float scaleZ = 1; - - //float yScaleFactor = (metrics->getHeight() * (1.0 - scaleY)); - //translatePos.y += yScaleFactor; - - //assertGl(); - - //int scaleWidthX = (font->getTextHandler()->Advance(renderText.c_str()) * scaleX) / 2.0; - //glTranslatef(translatePos.x + scaleWidthX, translatePos.y, translatePos.z); - glTranslatef(translatePos.x, translatePos.y, translatePos.z); - - Vec3f translatePosOriginal = translatePos;; - //assertGl(); - - //glScalef(scaleX, scaleY, scaleZ); - - - //glTranslatef(0.45, 0.45, 1.0); - - //assertGl(); - - // font->getTextHandler()->Render(text.c_str()); - // specialFTGLErrorCheckWorkaround(text); - - if(font->getTextHandler() != NULL) { - float scaleX = Font::scaleFontValue; - float scaleY = Font::scaleFontValue; - float scaleZ = 1.0; - - glScalef(scaleX, scaleY, scaleZ); - if(renderText.find("\n") == renderText.npos && renderText.find("\t") == renderText.npos) { - //assertGl(); - font->getTextHandler()->Render(renderText.c_str()); - specialFTGLErrorCheckWorkaround(renderText); - } - else { - int line=0; - bool lastCharacterWasSpecial = true; - vector parts; - char szBuf[8096]=""; - - //for (int i=0; renderText[i] != '\0'; ++i) { - for(size_t i=0; i < renderText.size(); ++i) { - szBuf[0] = '\0'; - snprintf(szBuf,8096,"%c",renderText[i]); - - switch(renderText[i]) { - case '\t': - parts.push_back(szBuf); - lastCharacterWasSpecial = true; - break; - case '\n': - parts.push_back(szBuf); - lastCharacterWasSpecial = true; - break; - default: - if(lastCharacterWasSpecial == true) { - parts.push_back(szBuf); - } - else { - parts[parts.size()-1] += szBuf; - } - lastCharacterWasSpecial = false; - break; - } - } - - bool needsRecursiveRender = false; - for (unsigned int i=0; i < parts.size(); ++i) { - switch(parts[i][0]) { - case '\t': - //translatePos= Vec3f((translatePos.x / size + 3.f) * size, y-(size + 1.f) * line, translatePos.z); - translatePos= Vec3f((translatePos.x / size + 3.f) * size, translatePos.y, translatePos.z); - needsRecursiveRender = true; - break; - case '\n': - { - line++; + // translatePos.x = x - scale * font->getTextHandler()->Advance(text.c_str()) / 2.f; + // translatePos.y = y - scale * font->getTextHandler()->LineHeight(text.c_str()) / font->getYOffsetFactor(); //assertGl(); - //float yLineValue = (font->getTextHandler()->LineHeight(parts[i].c_str()) * Font::scaleFontValue); - //float yLineValue = (font->getTextHandler()->LineHeight("W") * Font::scaleFontValue); - float yLineValue = font->getTextHandler()->LineHeight("W"); + translatePos.x = x - (font->getTextHandler()->Advance(renderText.c_str()) / 2.f); + //assertGl(); + //translatePos.y = y - (font->getTextHandler()->LineHeight(text.c_str()) / font->getYOffsetFactor()); + translatePos.y = y - ((font->getTextHandler()->LineHeight(renderText.c_str()) * Font::scaleFontValue) / 2.f); //assertGl(); - //printf("Trying to render newline [%s] i = %d yLineValue = %f font->getTextHandler()->LineHeight(parts[i].c_str()) = %f\n",renderText.c_str(),i,yLineValue,font->getTextHandler()->LineHeight(parts[i].c_str())); + translatePos.z = 0; + } else { + //printf("3d text [%s] advance = %f, x = %f\n",text.c_str(),font->getTextHandler()->Advance(text.c_str()), x); - translatePos= Vec3f(translatePosOriginal.x, translatePos.y - yLineValue, translatePos.z); - needsRecursiveRender = true; - } - break; - default: - if(needsRecursiveRender == true) { - //internalRender(parts[i], translatePos.x, translatePos.y, false, color); - glPushMatrix(); - glLoadIdentity(); - glTranslatef(translatePos.x, translatePos.y, translatePos.z); - glScalef(scaleX, scaleY, scaleZ); - font->getTextHandler()->Render(parts[i].c_str()); - specialFTGLErrorCheckWorkaround(parts[i]); - glPopMatrix(); + // translatePos.x = x-scale; + // translatePos.y = y-scale; + translatePos.x = x; + translatePos.y = y; - needsRecursiveRender = false; - } - else { - //assertGl(); + translatePos.z = 0; + } + } else { + float scale = 1.0f; + //float scale= size; - font->getTextHandler()->Render(parts[i].c_str()); - specialFTGLErrorCheckWorkaround(parts[i]); - } - break; + utext = reinterpret_cast(renderText.c_str()); + if (centered) { + //glTranslatef(x-scale*metrics->getTextWidth(text)/2.f, y-scale*metrics->getHeight()/2.f, 0); + translatePos.x = x - scale*metrics->getTextWidth(renderText) / 2.f; + translatePos.y = y - scale*metrics->getHeight(renderText) / 2.f; + translatePos.z = 0; + } else { + //glTranslatef(x-scale, y-scale, 0); + translatePos.x = x - scale; + translatePos.y = y - scale; + translatePos.z = 0; + } } + + //float scaleX = 0.65; + //float scaleY = 0.75; + //float scaleZ = 1.0; + + //float scaleX = 1; + //float scaleY = 1; + //float scaleZ = 1; + + //float yScaleFactor = (metrics->getHeight() * (1.0 - scaleY)); + //translatePos.y += yScaleFactor; + + //assertGl(); + + //int scaleWidthX = (font->getTextHandler()->Advance(renderText.c_str()) * scaleX) / 2.0; + //glTranslatef(translatePos.x + scaleWidthX, translatePos.y, translatePos.z); + glTranslatef(translatePos.x, translatePos.y, translatePos.z); + + Vec3f translatePosOriginal = translatePos;; + //assertGl(); + + //glScalef(scaleX, scaleY, scaleZ); + + + //glTranslatef(0.45, 0.45, 1.0); + + //assertGl(); + + // font->getTextHandler()->Render(text.c_str()); + // specialFTGLErrorCheckWorkaround(text); + + if (font->getTextHandler() != NULL) { + float scaleX = Font::scaleFontValue; + float scaleY = Font::scaleFontValue; + float scaleZ = 1.0; + + glScalef(scaleX, scaleY, scaleZ); + if (renderText.find("\n") == renderText.npos && renderText.find("\t") == renderText.npos) { + //assertGl(); + font->getTextHandler()->Render(renderText.c_str()); + specialFTGLErrorCheckWorkaround(renderText); + } else { + int line = 0; + bool lastCharacterWasSpecial = true; + vector parts; + char szBuf[8096] = ""; + + //for (int i=0; renderText[i] != '\0'; ++i) { + for (size_t i = 0; i < renderText.size(); ++i) { + szBuf[0] = '\0'; + snprintf(szBuf, 8096, "%c", renderText[i]); + + switch (renderText[i]) { + case '\t': + parts.push_back(szBuf); + lastCharacterWasSpecial = true; + break; + case '\n': + parts.push_back(szBuf); + lastCharacterWasSpecial = true; + break; + default: + if (lastCharacterWasSpecial == true) { + parts.push_back(szBuf); + } else { + parts[parts.size() - 1] += szBuf; + } + lastCharacterWasSpecial = false; + break; + } + } + + bool needsRecursiveRender = false; + for (unsigned int i = 0; i < parts.size(); ++i) { + switch (parts[i][0]) { + case '\t': + //translatePos= Vec3f((translatePos.x / size + 3.f) * size, y-(size + 1.f) * line, translatePos.z); + translatePos = Vec3f((translatePos.x / size + 3.f) * size, translatePos.y, translatePos.z); + needsRecursiveRender = true; + break; + case '\n': + { + line++; + //assertGl(); + //float yLineValue = (font->getTextHandler()->LineHeight(parts[i].c_str()) * Font::scaleFontValue); + //float yLineValue = (font->getTextHandler()->LineHeight("W") * Font::scaleFontValue); + float yLineValue = font->getTextHandler()->LineHeight("W"); + //assertGl(); + + //printf("Trying to render newline [%s] i = %d yLineValue = %f font->getTextHandler()->LineHeight(parts[i].c_str()) = %f\n",renderText.c_str(),i,yLineValue,font->getTextHandler()->LineHeight(parts[i].c_str())); + + translatePos = Vec3f(translatePosOriginal.x, translatePos.y - yLineValue, translatePos.z); + needsRecursiveRender = true; + } + break; + default: + if (needsRecursiveRender == true) { + //internalRender(parts[i], translatePos.x, translatePos.y, false, color); + glPushMatrix(); + glLoadIdentity(); + glTranslatef(translatePos.x, translatePos.y, translatePos.z); + glScalef(scaleX, scaleY, scaleZ); + font->getTextHandler()->Render(parts[i].c_str()); + specialFTGLErrorCheckWorkaround(parts[i]); + glPopMatrix(); + + needsRecursiveRender = false; + } else { + //assertGl(); + + font->getTextHandler()->Render(parts[i].c_str()); + specialFTGLErrorCheckWorkaround(parts[i]); + } + break; + } + } + } + } else { + if (Font::fontIsMultibyte == true) { + //setlocale(LC_CTYPE, "en_ca.UTF-8"); + + //wstring wText = widen(text); + //glListBase(font->getHandle()); + //glCallLists(wText.length(), GL_UNSIGNED_SHORT, &wText[0]); + + //string utfText = text; + //glListBase(font->getHandle()); + //glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]); + + string utfText = renderText; + glListBase(font->getHandle()); + glCallLists((GLsizei) renderText.length(), GL_UNSIGNED_SHORT, &utext[0]); + + //std::locale loc(""); + //wstring wText = widen(text); + //std::string strBuffer(Text.size() * 4 + 1, 0); + //std::use_facet >(loc).narrow(&Text[0], &Text[0] + Text.size(), '?', &strBuffer[0]); + //string utfText = std::string(&strBuffer[0]); + //glListBase(font->getHandle()); + //glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]); + } else { + for (int i = 0; utext[i] != '\0'; ++i) { + glCallList(font->getHandle() + utext[i]); + } + } + } + + //assertGl(); + + glPopMatrix(); + + //assertGl(); + + if (color != NULL) { + glPopAttrib(); + } + + //assertGl(); + //glDisable(GL_TEXTURE_2D); + + assertGl(); } - } - } - else { - if(Font::fontIsMultibyte == true) { - //setlocale(LC_CTYPE, "en_ca.UTF-8"); - //wstring wText = widen(text); - //glListBase(font->getHandle()); - //glCallLists(wText.length(), GL_UNSIGNED_SHORT, &wText[0]); + void TextRenderer3DGl::end() { + assert(rendering); + rendering = false; - //string utfText = text; - //glListBase(font->getHandle()); - //glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]); + //assertGl(); - string utfText = renderText; - glListBase(font->getHandle()); - glCallLists((GLsizei)renderText.length(), GL_UNSIGNED_SHORT, &utext[0]); + glPopAttrib(); - //std::locale loc(""); - //wstring wText = widen(text); - //std::string strBuffer(Text.size() * 4 + 1, 0); - //std::use_facet >(loc).narrow(&Text[0], &Text[0] + Text.size(), '?', &strBuffer[0]); - //string utfText = std::string(&strBuffer[0]); - //glListBase(font->getHandle()); - //glCallLists(utfText.length(), GL_UNSIGNED_SHORT, &utfText[0]); - } - else { - for (int i=0; utext[i]!='\0'; ++i) { - glCallList(font->getHandle()+utext[i]); + assertGl(); } + } } - - //assertGl(); - - glPopMatrix(); - - //assertGl(); - - if(color != NULL) { - glPopAttrib(); - } - - //assertGl(); - //glDisable(GL_TEXTURE_2D); - - assertGl(); -} - -void TextRenderer3DGl::end() { - assert(rendering); - rendering= false; - - //assertGl(); - - glPopAttrib(); - - assertGl(); -} - -}}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/graphics/gl/texture_gl.cpp b/source/shared_lib/sources/graphics/gl/texture_gl.cpp index dac42ec7e..38bfad843 100644 --- a/source/shared_lib/sources/graphics/gl/texture_gl.cpp +++ b/source/shared_lib/sources/graphics/gl/texture_gl.cpp @@ -24,1274 +24,1271 @@ using namespace std; -namespace Shared { namespace Graphics { namespace Gl { +namespace Shared { + namespace Graphics { + namespace Gl { -using namespace Platform; -using namespace Shared::Util; + using namespace Platform; + using namespace Shared::Util; -bool TextureGl::enableATIHacks = false; + bool TextureGl::enableATIHacks = false; -static void setupGLExtensionMethods() { + static void setupGLExtensionMethods() { #ifdef WIN32 - static bool setupExtensions=true; - if(setupExtensions == true) { - setupExtensions = false; - - if(isGlExtensionSupported("GL_EXT_framebuffer_object")) { - //glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)wglGetProcAddress("glIsRenderbufferEXT"); - glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)wglGetProcAddress("glBindRenderbufferEXT"); - glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)wglGetProcAddress("glDeleteRenderbuffersEXT"); - glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)wglGetProcAddress("glGenRenderbuffersEXT"); - glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)wglGetProcAddress("glRenderbufferStorageEXT"); - //glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)wglGetProcAddress("glGetRenderbufferParameterivEXT"); - //glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)wglGetProcAddress("glIsFramebufferEXT"); - glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)wglGetProcAddress("glBindFramebufferEXT"); - glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)wglGetProcAddress("glDeleteFramebuffersEXT"); - glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)wglGetProcAddress("glGenFramebuffersEXT"); - glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)wglGetProcAddress("glCheckFramebufferStatusEXT"); - //glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)wglGetProcAddress("glFramebufferTexture1DEXT"); - glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)wglGetProcAddress("glFramebufferTexture2DEXT"); - //glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)wglGetProcAddress("glFramebufferTexture3DEXT"); - glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)wglGetProcAddress("glFramebufferRenderbufferEXT"); - //glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)wglGetProcAddress("glGetFramebufferAttachmentParameterivEXT"); - //glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)wglGetProcAddress("glGenerateMipmapEXT"); - - if(!glBindRenderbufferEXT || !glDeleteRenderbuffersEXT || !glGenRenderbuffersEXT || - !glRenderbufferStorageEXT || !glBindFramebufferEXT || !glDeleteFramebuffersEXT || - !glGenFramebuffersEXT || !glCheckFramebufferStatusEXT || !glFramebufferTexture2DEXT || - !glFramebufferRenderbufferEXT) { - glGenFramebuffersEXT = NULL; - } - } - } - -#endif -} - -/* gets next power of two */ -int pot(int x) { - int val = 1; - while (val < x) { - val *= 2; - } - return val; -} - -const std::size_t MIN_BYTES_TO_COMPRESS = 12; - -static std::string getSupportCompressedTextureFormatString(int format) { - std::string result = intToStr(format) + "[" + intToHex(format) + "]"; - switch(format) { - case GL_COMPRESSED_ALPHA: - result = "GL_COMPRESSED_ALPHA"; - break; - case GL_COMPRESSED_LUMINANCE: - result = "GL_COMPRESSED_LUMINANCE"; - break; - case GL_COMPRESSED_LUMINANCE_ALPHA: - result = "GL_COMPRESSED_LUMINANCE_ALPHA"; - break; - case GL_COMPRESSED_INTENSITY: - result = "GL_COMPRESSED_INTENSITY"; - break; - case GL_COMPRESSED_RGB: - result = "GL_COMPRESSED_RGB"; - break; - case GL_COMPRESSED_RGBA: - result = "GL_COMPRESSED_RGBA"; - break; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - result = "GL_COMPRESSED_RGB_S3TC_DXT1_EXT"; - break; - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - result = "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT"; - break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - result = "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT"; - break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - result = "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT"; - break; - -/* - case GL_COMPRESSED_SRGB: - result = "GL_COMPRESSED_SRGB"; - break; - - case GL_COMPRESSED_SRGB_ALPHA: - result = "GL_COMPRESSED_SRGB_ALPHA"; - break; - - case GL_COMPRESSED_SLUMINANCE: - result = "GL_COMPRESSED_SLUMINANCE"; - break; - - case GL_COMPRESSED_SLUMINANCE_ALPHA: - result = "GL_COMPRESSED_SLUMINANCE_ALPHA"; - break; - - case GL_COMPRESSED_RED: - result = "GL_COMPRESSED_RED"; - break; - - case GL_COMPRESSED_RG: - result = "GL_COMPRESSED_RG"; - break; - - case GL_COMPRESSED_RED_RGTC1: - result = "GL_COMPRESSED_RED_RGTC1"; - break; - - case GL_COMPRESSED_SIGNED_RED_RGTC1: - result = "GL_COMPRESSED_SIGNED_RED_RGTC1"; - break; - - case GL_COMPRESSED_RG_RGTC2: - result = "GL_COMPRESSED_RG_RGTC2"; - break; - - case GL_COMPRESSED_SIGNED_RG_RGTC2: - result = "GL_COMPRESSED_SIGNED_RG_RGTC2"; - break; - - case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: - result = "GL_COMPRESSED_RGBA_BPTC_UNORM_ARB"; - break; - - case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: - result = "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB"; - break; - - case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: - result = "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB"; - break; - - case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: - result = "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB"; - break; -*/ - case GL_COMPRESSED_RGB_FXT1_3DFX: - result = "GL_COMPRESSED_RGB_FXT1_3DFX"; - break; - - case GL_COMPRESSED_RGBA_FXT1_3DFX: - result = "GL_COMPRESSED_RGBA_FXT1_3DFX"; - break; - -/* - case GL_COMPRESSED_SRGB_EXT: - result = "GL_COMPRESSED_SRGB_EXT"; - break; - - case GL_COMPRESSED_SRGB_ALPHA_EXT: - result = "GL_COMPRESSED_SRGB_ALPHA_EXT"; - break; - - case GL_COMPRESSED_SLUMINANCE_EXT: - result = "GL_COMPRESSED_SLUMINANCE_EXT"; - break; - - case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT: - result = "GL_COMPRESSED_SLUMINANCE_ALPHA_EXT"; - break; - - case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: - result = "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT"; - break; - - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: - result = "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT"; - break; - - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: - result = "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT"; - break; - - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: - result = "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT"; - break; - - case GL_COMPRESSED_LUMINANCE_LATC1_EXT: - result = "GL_COMPRESSED_LUMINANCE_LATC1_EXT"; - break; - - case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT: - result = "GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT"; - break; - - case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT: - result = "GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT"; - break; - - case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT: - result = "GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT"; - break; - - case GL_COMPRESSED_RED_RGTC1_EXT: - result = "GL_COMPRESSED_RED_RGTC1_EXT"; - break; - - case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: - result = "GL_COMPRESSED_SIGNED_RED_RGTC1_EXT"; - break; - - case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: - result = "GL_COMPRESSED_RED_GREEN_RGTC2_EXT"; - break; - - case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: - result = "GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT"; - break; -*/ - -/* -#define GL_COMPRESSED_SRGB 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 - -#define GL_COMPRESSED_SLUMINANCE 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B - -#define GL_COMPRESSED_RED 0x8225 -#define GL_COMPRESSED_RG 0x8226 - -#define GL_COMPRESSED_RED_RGTC1 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC -#define GL_COMPRESSED_RG_RGTC2 0x8DBD -#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE - -#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C -#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D -#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E -#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F - -#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 -#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 - -#define GL_COMPRESSED_SRGB_EXT 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 -#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B -#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F - -#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 -#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 -#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 -#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 - -#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC -#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD -#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE -*/ - - } - return result; -} - -static int getNumCompressedTextureFormats() { - int numCompressedTextureFormats = 0; - glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, (GLint*)&numCompressedTextureFormats); - return numCompressedTextureFormats; -} - -static std::vector getSupportCompressedTextureFormats() { - std::vector result; - int count = getNumCompressedTextureFormats(); - if(count > 0) { - int *formats = new int[count]; - glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS,(GLint*)&formats[0]); - - for(int i = 0; i < count; ++i) { - result.push_back(formats[i]); - } - delete [] formats; - } - - if(Texture::useTextureCompression == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"------------------------------------------------\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"**** getSupportCompressedTextureFormats() result.size() = %d, count = %d\n",(int)result.size(),count); - for(unsigned int i = 0; i < result.size(); ++i) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"Texture Compression #i = %d, result[i] = %d [%s]\n",i,result[i],getSupportCompressedTextureFormatString(result[i]).c_str()); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"------------------------------------------------\n"); - } - return result; -} - -GLint toCompressionFormatGl(GLint format) { - if(Texture::useTextureCompression == false) { - return format; - } - - static std::vector supportedCompressionFormats = getSupportCompressedTextureFormats(); - if(supportedCompressionFormats.empty() == true) { - return format; - } - - //GL_COMPRESSED_ALPHA <- white things but tile ok! - //GL_COMPRESSED_LUMINANCE <- black tiles - //GL_COMPRESSED_LUMINANCE_ALPHA <- black tiles - //GL_COMPRESSED_INTENSITY <- black tiles - //GL_COMPRESSED_RGB <- black tiles - //GL_COMPRESSED_RGBA <- black tiles - - // With the following extension (GL_EXT_texture_compression_s3tc) - //GL_COMPRESSED_RGB_S3TC_DXT1_EXT - //GL_COMPRESSED_RGBA_S3TC_DXT1_EXT - //GL_COMPRESSED_RGBA_S3TC_DXT3_EXT - //GL_COMPRESSED_RGBA_S3TC_DXT5_EXT - - //#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 - //#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 - - switch(format) { - case GL_LUMINANCE: - case GL_LUMINANCE8: - return GL_COMPRESSED_LUMINANCE; - case GL_RGB: - case GL_RGB8: - if(std::find(supportedCompressionFormats.begin(),supportedCompressionFormats.end(),GL_COMPRESSED_RGB_S3TC_DXT1_EXT) != supportedCompressionFormats.end()) { - return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - } - else if(std::find(supportedCompressionFormats.begin(),supportedCompressionFormats.end(),GL_COMPRESSED_RGB) != supportedCompressionFormats.end()) { - return GL_COMPRESSED_RGB; - } - //else if(std::find(supportedCompressionFormats.begin(),supportedCompressionFormats.end(),GL_COMPRESSED_SRGB_S3TC_DXT1_EXT) != supportedCompressionFormats.end()) { - // return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; - //} - else if(std::find(supportedCompressionFormats.begin(),supportedCompressionFormats.end(),GL_COMPRESSED_RGB_FXT1_3DFX) != supportedCompressionFormats.end()) { - return GL_COMPRESSED_RGB_FXT1_3DFX; - } - break; - - case GL_RGBA: - case GL_RGBA8: - - if(std::find(supportedCompressionFormats.begin(),supportedCompressionFormats.end(),GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) != supportedCompressionFormats.end()) { - return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - } - else if(std::find(supportedCompressionFormats.begin(),supportedCompressionFormats.end(),GL_COMPRESSED_RGBA) != supportedCompressionFormats.end()) { - return GL_COMPRESSED_RGBA; - } - //else if(std::find(supportedCompressionFormats.begin(),supportedCompressionFormats.end(),GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT) != supportedCompressionFormats.end()) { - // return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; - //} - //else if(std::find(supportedCompressionFormats.begin(),supportedCompressionFormats.end(),GL_COMPRESSED_SRGB_S3TC_DXT1_EXT) != supportedCompressionFormats.end()) { - // return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; - //} - else if(std::find(supportedCompressionFormats.begin(),supportedCompressionFormats.end(),GL_COMPRESSED_RGBA_FXT1_3DFX) != supportedCompressionFormats.end()) { - return GL_COMPRESSED_RGBA_FXT1_3DFX; - } - break; - - case GL_ALPHA: - case GL_ALPHA8: - //return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - //return GL_COMPRESSED_ALPHA_ARB; - return GL_COMPRESSED_ALPHA; - //return GL_COMPRESSED_RGBA; - default: - return format; - } - return format; -} - -GLint toWrapModeGl(Texture::WrapMode wrapMode){ - switch(wrapMode){ - case Texture::wmClamp: - return GL_CLAMP; - case Texture::wmRepeat: - return GL_REPEAT; - case Texture::wmClampToEdge: - return GL_CLAMP_TO_EDGE; - default: - assert(false); - return GL_CLAMP; - } -} - -GLint toFormatGl(Texture::Format format, int components){ - switch(format){ - case Texture::fAuto: - switch(components){ - case 1: - return GL_LUMINANCE; - case 3: - return GL_RGB; - case 4: - return GL_RGBA; - default: - std::cerr << "Components = " << (components) << std::endl; - assert(false); - return GL_RGBA; - } - break; - case Texture::fLuminance: - return GL_LUMINANCE; - case Texture::fAlpha: - return GL_ALPHA; - case Texture::fRgb: - return GL_RGB; - case Texture::fRgba: - return GL_RGBA; - default: - assert(false); - return GL_RGB; - } -} - -GLint toInternalFormatGl(Texture::Format format, int components){ - switch(format){ - case Texture::fAuto: - switch(components){ - case 1: - return GL_LUMINANCE8; - case 3: - return GL_RGB8; - case 4: - return GL_RGBA8; - default: - assert(false); - return GL_RGBA8; - } - break; - case Texture::fLuminance: - return GL_LUMINANCE8; - case Texture::fAlpha: - return GL_ALPHA8; - case Texture::fRgb: - return GL_RGB8; - case Texture::fRgba: - return GL_RGBA8; - default: - assert(false); - return GL_RGB8; - } -} - -TextureGl::TextureGl() { - handle = 0; - renderBufferId = 0; - frameBufferId = 0; - setupGLExtensionMethods(); -} - -bool TextureGl::supports_FBO_RBO() { - return (glGenFramebuffersEXT != NULL); -} - -void TextureGl::setup_FBO_RBO() { - if(getTextureWidth() < 0 || getTextureHeight() < 0) { - throw megaglest_runtime_error("getTextureWidth() < 0 || getTextureHeight() < 0"); - } - - // Need some work to get extensions properly working in Windows (use Glew lib) - // Did we successfully setup FBO's? - if(glGenFramebuffersEXT) { - GLint width=0; - glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&width); - GLint height=0; - glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&height); - - //------------------------- - glGenFramebuffersEXT(1, &frameBufferId); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId); - //Attach 2D texture to this FBO - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, handle, 0); - //------------------------- - glGenRenderbuffersEXT(1, &renderBufferId); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBufferId); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, getTextureWidth(), getTextureHeight()); - //------------------------- - //Attach depth buffer to FBO - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderBufferId); - //------------------------- - //Does the GPU support current FBO configuration? - GLenum status; - status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - switch(status) - { - case GL_FRAMEBUFFER_COMPLETE_EXT: - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"FBO attachment OK!\n"); - break; - default: - //SystemFlags::OutputDebug(SystemFlags::debugSystem,"FBO attachment BAD!\n"); - break; - } - //------------------------- - //and now you can render to GL_TEXTURE_2D - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId); - glClearColor(0.0, 0.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - } -} - -void TextureGl::teardown_FBO_RBO() { - // Need some work to get extensions properly working in Windows (use Glew lib) - if(glGenFramebuffersEXT) { - //---------------- - //Bind 0, which means render to back buffer - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - //And in the end, cleanup - //Delete resources - //glDeleteTextures(1, &handle); - glDeleteRenderbuffersEXT(1, &frameBufferId); - //Bind 0, which means render to back buffer, as a result, fb is unbound - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - glDeleteFramebuffersEXT(1, &frameBufferId); - } -} - -void TextureGl::initRenderBuffer() { - // Need some work to get extensions properly working in Windows (use Glew lib) - if(glGenFramebuffersEXT) { - // create a renderbuffer object to store depth info - glGenRenderbuffersEXT(1, &renderBufferId); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBufferId); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,getTextureWidth(), getTextureHeight()); - //glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); - } -} - -void TextureGl::initFrameBuffer() { - // Need some work to get extensions properly working in Windows (use Glew lib) - if(glGenFramebuffersEXT) { - // create a framebuffer object - glGenFramebuffersEXT(1, &frameBufferId); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId); -} -} - -void TextureGl::attachRenderBuffer() { - // Need some work to get extensions properly working in Windows (use Glew lib) - if(glGenFramebuffersEXT) { - // attach the renderbuffer to depth attachment point - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, renderBufferId); -} -} - -void TextureGl::attachFrameBufferToTexture() { - // Need some work to get extensions properly working in Windows (use Glew lib) - if(glGenFramebuffersEXT) { - // attach the texture to FBO color attachment point - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, handle, 0); -} -} - -bool TextureGl::checkFrameBufferStatus() { - // Need some work to get extensions properly working in Windows (use Glew lib) - if(glGenFramebuffersEXT) { - // check FBO status - // Does the GPU support current FBO configuration? - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if(status != GL_FRAMEBUFFER_COMPLETE_EXT) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"checkFrameBufferStatus() status = %d [%X]\n",status,status); - return false; - } - return true; - } - - return false; -} - -void TextureGl::dettachFrameBufferFromTexture() { - // Need some work to get extensions properly working in Windows (use Glew lib) - if(glGenFramebuffersEXT) { - // switch back to window-system-provided framebuffer - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - } -} - -void TextureGl::dettachRenderBufferFromTexture() { - // Need some work to get extensions properly working in Windows (use Glew lib) - if(glGenFramebuffersEXT) { - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); - } -} - -TextureGl::~TextureGl() { - // Need some work to get extensions properly working in Windows (use Glew lib) - if(glGenFramebuffersEXT) { - if(renderBufferId != 0) { - glDeleteRenderbuffersEXT(1, &renderBufferId); - renderBufferId = 0; - } - if(frameBufferId != 0) { - glDeleteFramebuffersEXT(1, &frameBufferId); - frameBufferId = 0; - } - //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - } -} - -// ===================================================== -// class Texture1DGl -// ===================================================== -Texture1DGl::Texture1DGl() : Texture1D(), TextureGl() {} - -Texture1DGl::~Texture1DGl() { - end(); -} - -void Texture1DGl::init(Filter filter, int maxAnisotropy) { - assertGl(); - - if(inited == false) { - //params - GLint wrap= toWrapModeGl(wrapMode); - GLint glFormat= toFormatGl(format, pixmap.getComponents()); - GLint glInternalFormat= toInternalFormatGl(format, pixmap.getComponents()); - GLint glCompressionFormat = toCompressionFormatGl(glInternalFormat); - if(forceCompressionDisabled == true || (pixmap.getPixelByteCount() > 0 && pixmap.getPixelByteCount() <= MIN_BYTES_TO_COMPRESS)) { - glCompressionFormat = glInternalFormat; - } - - //pixel init var - const uint8* pixels= pixmapInit? pixmap.getPixels(): NULL; - - //gen texture - glGenTextures(1, &handle); - glBindTexture(GL_TEXTURE_1D, handle); - - //wrap params - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, wrap); - - //maxAnisotropy - if(isGlExtensionSupported("GL_EXT_texture_filter_anisotropic")){ - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy); - } - - if(mipmap) { - GLuint glFilter= filter==fTrilinear? GL_LINEAR_MIPMAP_LINEAR: GL_LINEAR_MIPMAP_NEAREST; - - //build mipmaps - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, glFilter); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - int error= gluBuild1DMipmaps( - GL_TEXTURE_1D, glCompressionFormat, pixmap.getW(), - glFormat, GL_UNSIGNED_BYTE, pixels); - - // Now try without compression if we tried compression - if(error != 0 && glCompressionFormat != glInternalFormat) { - int error2= gluBuild1DMipmaps( - GL_TEXTURE_1D, glInternalFormat, pixmap.getW(), - glFormat, GL_UNSIGNED_BYTE, pixels); - - if(error2 == 0) { - error = 0; - } - } - // - - if(error != 0) { - //throw megaglest_runtime_error("Error building texture 1D mipmaps"); - const char *errorString= reinterpret_cast(gluErrorString(error)); - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error building texture 1D mipmaps, returned: %d [%s] for [%s] w = %d, glCompressionFormat = %d",error,errorString,pixmap.getPath().c_str(),pixmap.getW(),glCompressionFormat); - throw megaglest_runtime_error(szBuf); - } - } - else { - //build single texture - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glTexImage1D( - GL_TEXTURE_1D, 0, glCompressionFormat, pixmap.getW(), - 0, glFormat, GL_UNSIGNED_BYTE, pixels); - - GLint error= glGetError(); - - // Now try without compression if we tried compression - if(error != GL_NO_ERROR && glCompressionFormat != glInternalFormat) { - glTexImage1D( - GL_TEXTURE_1D, 0, glInternalFormat, pixmap.getW(), - 0, glFormat, GL_UNSIGNED_BYTE, pixels); - - GLint error2= glGetError(); - - if(error2 == GL_NO_ERROR) { - error = GL_NO_ERROR; - } - } - // - - if(error != GL_NO_ERROR) { - //throw megaglest_runtime_error("Error creating texture 1D"); - const char *errorString= reinterpret_cast(gluErrorString(error)); - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error creating texture 1D, returned: %d [%s] (%X) [%s] w = %d, glCompressionFormat = %d",error,errorString,error,pixmap.getPath().c_str(),pixmap.getW(),glCompressionFormat); - throw megaglest_runtime_error(szBuf); - } - } - inited= true; - OutputTextureDebugInfo(format, pixmap.getComponents(),getPath(),pixmap.getPixelByteCount(),GL_TEXTURE_1D); - } - - assertGl(); -} - -void Texture1DGl::end(bool deletePixelBuffer) { - if(inited == true) { - assertGl(); - glDeleteTextures(1, &handle); - assertGl(); - handle=0; - inited=false; - if(deletePixelBuffer == true) { - deletePixels(); - } - } -} - -// ===================================================== -// class Texture2DGl -// ===================================================== - -Texture2DGl::Texture2DGl() : Texture2D(), TextureGl() {} - -Texture2DGl::~Texture2DGl() { - end(); -} - -void Texture2DGl::init(Filter filter, int maxAnisotropy) { - assertGl(); - - if(inited == false) { - assertGl(); - //params - GLint wrap= toWrapModeGl(wrapMode); - GLint glFormat= toFormatGl(format, pixmap.getComponents()); - GLint glInternalFormat= toInternalFormatGl(format, pixmap.getComponents()); - GLint glCompressionFormat = toCompressionFormatGl(glInternalFormat); - if(forceCompressionDisabled == true || (pixmap.getPixelByteCount() > 0 && pixmap.getPixelByteCount() <= MIN_BYTES_TO_COMPRESS)) { - glCompressionFormat = glInternalFormat; - } - - assertGl(); - //pixel init var - const uint8* pixels= pixmapInit? pixmap.getPixels(): NULL; - - //gen texture - glGenTextures(1, &handle); - glBindTexture(GL_TEXTURE_2D, handle); - - assertGl(); - - //wrap params - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); - - assertGl(); - - //maxAnisotropy - if(isGlExtensionSupported("GL_EXT_texture_filter_anisotropic")) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy); - } - - if(mipmap) { - GLuint glFilter= (filter == fTrilinear ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR_MIPMAP_NEAREST); - - //build mipmaps - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glFilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - -/* - * Replaced this call due to: http://www.opengl.org/wiki/Common_Mistakes#gluBuild2DMipmaps - * - int error= gluBuild2DMipmaps( - GL_TEXTURE_2D, glCompressionFormat, - pixmap.getW(), pixmap.getH(), - glFormat, GL_UNSIGNED_BYTE, pixels); -*/ - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - - //! Note: NPOTs + nearest filtering seems broken on ATIs - if ( !(count_bits_set(pixmap.getW()) == 1 && count_bits_set(pixmap.getH()) == 1) && - TextureGl::enableATIHacks == true) { - // && (!GLEW_ARB_texture_non_power_of_two || (globalRendering->atiHacks && nearest)) ) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n\n**WARNING** Enabling ATI video card hacks, resizing texture to power of two [%d x %d] to [%d x %d] components [%d] path [%s]\n",pixmap.getW(),pixmap.getH(),next_power_of_2(pixmap.getW()),next_power_of_2(pixmap.getH()),pixmap.getComponents(),pixmap.getPath().c_str()); - - pixmap.Scale(glFormat,next_power_of_2(pixmap.getW()),next_power_of_2(pixmap.getH())); - } - - glTexImage2D(GL_TEXTURE_2D, 0, glCompressionFormat, - pixmap.getW(), pixmap.getH(), 0, - glFormat, GL_UNSIGNED_BYTE, pixels); - - GLint error= glGetError(); - - // Now try without compression if we tried compression - if(error != GL_NO_ERROR && glCompressionFormat != glInternalFormat) { - glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, - pixmap.getW(), pixmap.getH(), 0, - glFormat, GL_UNSIGNED_BYTE, pixels); - - GLint error2= glGetError(); - - if(error2 == GL_NO_ERROR) { - error = GL_NO_ERROR; - } - } - if(error != GL_NO_ERROR) { - int error3= gluBuild2DMipmaps( - GL_TEXTURE_2D, glCompressionFormat, - pixmap.getW(), pixmap.getH(), - glFormat, GL_UNSIGNED_BYTE, pixels); - if(error3 == GL_NO_ERROR) { - error = GL_NO_ERROR; - } - } - if(error != GL_NO_ERROR) { - int error4= gluBuild2DMipmaps( - GL_TEXTURE_2D, glInternalFormat, - pixmap.getW(), pixmap.getH(), - glFormat, GL_UNSIGNED_BYTE, pixels); - if(error4 == GL_NO_ERROR) { - error = GL_NO_ERROR; - } - } - - // - - if(error != GL_NO_ERROR) { - //throw megaglest_runtime_error("Error building texture 2D mipmaps"); - const char *errorString= reinterpret_cast(gluErrorString(error)); - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error building texture 2D mipmaps [%s], returned: %d [%s] for [%s] w = %d, h = %d, glCompressionFormat = %d",this->path.c_str(),error,errorString,(pixmap.getPath() != "" ? pixmap.getPath().c_str() : this->path.c_str()),pixmap.getW(),pixmap.getH(),glCompressionFormat); - throw megaglest_runtime_error(szBuf); - } - } - else { - //build single texture - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - assertGl(); - - if ( !(count_bits_set(pixmap.getW()) == 1 && count_bits_set(pixmap.getH()) == 1) && - TextureGl::enableATIHacks == true) { - // && (!GLEW_ARB_texture_non_power_of_two || (globalRendering->atiHacks && nearest)) ) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n\n**WARNING** Enabling ATI video card hacks, resizing texture to power of two [%d x %d] to [%d x %d] components [%d] path [%s]\n",pixmap.getW(),pixmap.getH(),next_power_of_2(pixmap.getW()),next_power_of_2(pixmap.getH()),pixmap.getComponents(),pixmap.getPath().c_str()); - - pixmap.Scale(glFormat,next_power_of_2(pixmap.getW()),next_power_of_2(pixmap.getH())); - } - - glTexImage2D(GL_TEXTURE_2D, 0, glCompressionFormat,pixmap.getW(), - pixmap.getH(),0, glFormat, GL_UNSIGNED_BYTE, pixels); - - GLint error= glGetError(); - - // Now try without compression if we tried compression - if(error != GL_NO_ERROR && glCompressionFormat != glInternalFormat) { - glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat,pixmap.getW(), - pixmap.getH(),0, glFormat, GL_UNSIGNED_BYTE, pixels); - - GLint error2= glGetError(); - - if(error2 == GL_NO_ERROR) { - error = GL_NO_ERROR; - } - else { - glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, pot(pixmap.getW()), - pot(pixmap.getH()), 0, glFormat, GL_UNSIGNED_BYTE, NULL); - - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixmap.getW(), pixmap.getH(), - glFormat, GL_UNSIGNED_BYTE, pixels); - - GLint error3= glGetError(); - - if(error3 == GL_NO_ERROR) { - error = GL_NO_ERROR; - } - } - } - else if(error != GL_NO_ERROR) { - glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, pot(pixmap.getW()), - pot(pixmap.getH()), 0, glFormat, GL_UNSIGNED_BYTE, NULL); - - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixmap.getW(), pixmap.getH(), - glFormat, GL_UNSIGNED_BYTE, pixels); - - GLint error3= glGetError(); - - if(error3 == GL_NO_ERROR) { - error = GL_NO_ERROR; - } - } - - // - - //throw megaglest_runtime_error("TEST!"); - - if(error != GL_NO_ERROR) { - const char *errorString= reinterpret_cast(gluErrorString(error)); - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error creating texture 2D path [%s], returned: %d [%s] (%X) [%s] w = %d, h = %d, glInternalFormat = %d, glFormat = %d, glCompressionFormat = %d",this->path.c_str(),error,errorString,error,pixmap.getPath().c_str(),pixmap.getW(),pixmap.getH(),glInternalFormat,glFormat,glCompressionFormat); - throw megaglest_runtime_error(szBuf); - } - } - inited= true; - OutputTextureDebugInfo(format, pixmap.getComponents(),getPath(),pixmap.getPixelByteCount(),GL_TEXTURE_2D); - } - - assertGl(); -} - -void Texture2DGl::end(bool deletePixelBuffer) { - if(inited == true) { - //printf("==> Deleting GL Texture [%s] handle = %d\n",getPath().c_str(),handle); - assertGl(); - glDeleteTextures(1, &handle); - assertGl(); - handle=0; - inited=false; - if(deletePixelBuffer == true) { - deletePixels(); - } - } -} - -// ===================================================== -// class Texture3DGl -// ===================================================== - -Texture3DGl::Texture3DGl() : Texture3D(), TextureGl() {} - -Texture3DGl::~Texture3DGl() { - end(); -} - -void Texture3DGl::init(Filter filter, int maxAnisotropy) { - assertGl(); - - if(inited == false) { - //params - GLint wrap= toWrapModeGl(wrapMode); - GLint glFormat= toFormatGl(format, pixmap.getComponents()); - GLint glInternalFormat= toInternalFormatGl(format, pixmap.getComponents()); - GLint glCompressionFormat = toCompressionFormatGl(glInternalFormat); - if(forceCompressionDisabled == true || (pixmap.getPixelByteCount() > 0 && pixmap.getPixelByteCount() <= MIN_BYTES_TO_COMPRESS)) { - glCompressionFormat = glInternalFormat; - } - if(glCompressionFormat == GL_COMPRESSED_RGBA_FXT1_3DFX) { - glCompressionFormat = glInternalFormat; - } - - //pixel init var - const uint8* pixels= pixmapInit? pixmap.getPixels(): NULL; - - //gen texture - glGenTextures(1, &handle); - glBindTexture(GL_TEXTURE_3D, handle); - - //wrap params - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, wrap); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, wrap); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, wrap); - - //build single texture - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glTexImage3D( - GL_TEXTURE_3D, 0, glCompressionFormat, - pixmap.getW(), pixmap.getH(), pixmap.getD(), - 0, glFormat, GL_UNSIGNED_BYTE, pixels); - - GLint error= glGetError(); - - // Now try without compression if we tried compression - if(error != GL_NO_ERROR && glCompressionFormat != glInternalFormat) { - glTexImage3D( - GL_TEXTURE_3D, 0, glInternalFormat, - pixmap.getW(), pixmap.getH(), pixmap.getD(), - 0, glFormat, GL_UNSIGNED_BYTE, pixels); - - GLint error2= glGetError(); - - if(error2 == GL_NO_ERROR) { - error = GL_NO_ERROR; - } - } - else if(error != GL_NO_ERROR) { - glTexImage3D( - GL_TEXTURE_3D, 0, glInternalFormat, - pot(pixmap.getW()), pot(pixmap.getH()), pot(pixmap.getD()), - 0, glFormat, GL_UNSIGNED_BYTE, NULL); - - glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, - pixmap.getW(), pixmap.getH(), pixmap.getD(), - glFormat, GL_UNSIGNED_BYTE, pixels); - - GLint error3= glGetError(); - - if(error3 == GL_NO_ERROR) { - error = GL_NO_ERROR; - } - } - - // - - if(error != GL_NO_ERROR) { - //throw megaglest_runtime_error("Error creating texture 3D"); - const char *errorString= reinterpret_cast(gluErrorString(error)); - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error creating texture 3D, returned: %d [%s] (%X) [%s] w = %d, h = %d, d = %d, glCompressionFormat = %d",error,errorString,error,pixmap.getPath().c_str(),pixmap.getW(),pixmap.getH(),pixmap.getD(),glCompressionFormat); - throw megaglest_runtime_error(szBuf); - } - inited= true; - - OutputTextureDebugInfo(format, pixmap.getComponents(),getPath(),pixmap.getPixelByteCount(),GL_TEXTURE_3D); - } - - assertGl(); -} - -void Texture3DGl::end(bool deletePixelBuffer) { - if(inited == true) { - assertGl(); - glDeleteTextures(1, &handle); - assertGl(); - handle=0; - inited=false; - if(deletePixelBuffer == true) { - deletePixels(); - } - } -} - -// ===================================================== -// class TextureCubeGl -// ===================================================== - -TextureCubeGl::TextureCubeGl() : TextureCube(), TextureGl() {} - -TextureCubeGl::~TextureCubeGl() { - end(); -} - -void TextureCubeGl::init(Filter filter, int maxAnisotropy) { - assertGl(); - - if(inited == false) { - //gen texture - glGenTextures(1, &handle); - glBindTexture(GL_TEXTURE_CUBE_MAP, handle); - - //wrap - GLint wrap= toWrapModeGl(wrapMode); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, wrap); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, wrap); - - //filter - if(mipmap) { - GLuint glFilter= filter==fTrilinear? GL_LINEAR_MIPMAP_LINEAR: GL_LINEAR_MIPMAP_NEAREST; - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, glFilter); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - else { - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - - for(int i = 0; i < 6; ++i) { - //params - Pixmap2D *currentPixmap= pixmap.getFace(i); - - GLint glFormat= toFormatGl(format, currentPixmap->getComponents()); - GLint glInternalFormat= toInternalFormatGl(format, currentPixmap->getComponents()); - GLint glCompressionFormat = toCompressionFormatGl(glInternalFormat); - if(forceCompressionDisabled == true || (currentPixmap->getPixelByteCount() > 0 && currentPixmap->getPixelByteCount() <= MIN_BYTES_TO_COMPRESS)) { - glCompressionFormat = glInternalFormat; - } - - //pixel init var - const uint8* pixels= pixmapInit? currentPixmap->getPixels(): NULL; - GLenum target= GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; - - if(mipmap) { - -/* - * Replaced this call due to: http://www.opengl.org/wiki/Common_Mistakes#gluBuild2DMipmaps - * - int error= gluBuild2DMipmaps( - target, glCompressionFormat, - currentPixmap->getW(), currentPixmap->getH(), - glFormat, GL_UNSIGNED_BYTE, pixels); - -*/ - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - - if ( !(count_bits_set(currentPixmap->getW()) == 1 && count_bits_set(currentPixmap->getH()) == 1) && - TextureGl::enableATIHacks == true) { - // && (!GLEW_ARB_texture_non_power_of_two || (globalRendering->atiHacks && nearest)) ) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n\n**WARNING** Enabling ATI video card hacks, resizing texture to power of two [%d x %d] to [%d x %d] components [%d] path [%s]\n",currentPixmap->getW(),currentPixmap->getH(),next_power_of_2(currentPixmap->getW()),next_power_of_2(currentPixmap->getH()),currentPixmap->getComponents(),currentPixmap->getPath().c_str()); - - currentPixmap->Scale(glFormat,next_power_of_2(currentPixmap->getW()),next_power_of_2(currentPixmap->getH())); - } - - glTexImage2D(target, 0, glCompressionFormat, - currentPixmap->getW(), currentPixmap->getH(), 0, - glFormat, GL_UNSIGNED_BYTE, pixels); - - int error = glGetError(); - - // Now try without compression if we tried compression - if(error != GL_NO_ERROR && glCompressionFormat != glInternalFormat) { - glTexImage2D(target, 0, glInternalFormat, - currentPixmap->getW(), currentPixmap->getH(), 0, - glFormat, GL_UNSIGNED_BYTE, pixels); - - GLint error2= glGetError(); - - if(error2 == GL_NO_ERROR) { - error = GL_NO_ERROR; - } - } - if(error != GL_NO_ERROR) { - int error3= gluBuild2DMipmaps( - target, glCompressionFormat, - currentPixmap->getW(), currentPixmap->getH(), - glFormat, GL_UNSIGNED_BYTE, pixels); - - - if(error3 == GL_NO_ERROR) { - error = GL_NO_ERROR; - } - } - if(error != GL_NO_ERROR) { - int error4= gluBuild2DMipmaps( - target, glInternalFormat, - currentPixmap->getW(), currentPixmap->getH(), - glFormat, GL_UNSIGNED_BYTE, pixels); - - - if(error4 == GL_NO_ERROR) { - error = GL_NO_ERROR; - } - } - - // - - if(error != GL_NO_ERROR) { - //throw megaglest_runtime_error("Error building texture cube mipmaps"); - const char *errorString= reinterpret_cast(gluErrorString(error)); - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error building texture cube mipmaps, returned: %d [%s] for [%s] w = %d, h = %d, glCompressionFormat = %d",error,errorString,currentPixmap->getPath().c_str(),currentPixmap->getW(),currentPixmap->getH(),glCompressionFormat); - throw megaglest_runtime_error(szBuf); - } - } - else { - - if ( !(count_bits_set(currentPixmap->getW()) == 1 && count_bits_set(currentPixmap->getH()) == 1) && - TextureGl::enableATIHacks == true) { - // && (!GLEW_ARB_texture_non_power_of_two || (globalRendering->atiHacks && nearest)) ) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n\n**WARNING** Enabling ATI video card hacks, resizing texture to power of two [%d x %d] to [%d x %d] components [%d] path [%s]\n",currentPixmap->getW(),currentPixmap->getH(),next_power_of_2(currentPixmap->getW()),next_power_of_2(currentPixmap->getH()),currentPixmap->getComponents(),currentPixmap->getPath().c_str()); - - currentPixmap->Scale(glFormat,next_power_of_2(currentPixmap->getW()),next_power_of_2(currentPixmap->getH())); - } - - glTexImage2D( - target, 0, glCompressionFormat, - currentPixmap->getW(), currentPixmap->getH(), - 0, glFormat, GL_UNSIGNED_BYTE, pixels); - - int error = glGetError(); - - // Now try without compression if we tried compression - if(error != GL_NO_ERROR && glCompressionFormat != glInternalFormat) { - glTexImage2D( - target, 0, glInternalFormat, - currentPixmap->getW(), currentPixmap->getH(), - 0, glFormat, GL_UNSIGNED_BYTE, pixels); - - GLint error2= glGetError(); - - if(error2 == GL_NO_ERROR) { - error = GL_NO_ERROR; - } - else { - glTexImage2D(target, 0, glInternalFormat, pot(currentPixmap->getW()), - pot(currentPixmap->getH()), 0, glFormat, GL_UNSIGNED_BYTE, NULL); - - glTexSubImage2D(target, 0, 0, 0, currentPixmap->getW(), currentPixmap->getH(), - glFormat, GL_UNSIGNED_BYTE, pixels); - - GLint error3= glGetError(); - - if(error3 == GL_NO_ERROR) { - error = GL_NO_ERROR; + static bool setupExtensions = true; + if (setupExtensions == true) { + setupExtensions = false; + + if (isGlExtensionSupported("GL_EXT_framebuffer_object")) { + //glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)wglGetProcAddress("glIsRenderbufferEXT"); + glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC) wglGetProcAddress("glBindRenderbufferEXT"); + glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC) wglGetProcAddress("glDeleteRenderbuffersEXT"); + glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC) wglGetProcAddress("glGenRenderbuffersEXT"); + glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC) wglGetProcAddress("glRenderbufferStorageEXT"); + //glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)wglGetProcAddress("glGetRenderbufferParameterivEXT"); + //glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)wglGetProcAddress("glIsFramebufferEXT"); + glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) wglGetProcAddress("glBindFramebufferEXT"); + glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC) wglGetProcAddress("glDeleteFramebuffersEXT"); + glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) wglGetProcAddress("glGenFramebuffersEXT"); + glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) wglGetProcAddress("glCheckFramebufferStatusEXT"); + //glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)wglGetProcAddress("glFramebufferTexture1DEXT"); + glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) wglGetProcAddress("glFramebufferTexture2DEXT"); + //glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)wglGetProcAddress("glFramebufferTexture3DEXT"); + glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) wglGetProcAddress("glFramebufferRenderbufferEXT"); + //glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)wglGetProcAddress("glGetFramebufferAttachmentParameterivEXT"); + //glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)wglGetProcAddress("glGenerateMipmapEXT"); + + if (!glBindRenderbufferEXT || !glDeleteRenderbuffersEXT || !glGenRenderbuffersEXT || + !glRenderbufferStorageEXT || !glBindFramebufferEXT || !glDeleteFramebuffersEXT || + !glGenFramebuffersEXT || !glCheckFramebufferStatusEXT || !glFramebufferTexture2DEXT || + !glFramebufferRenderbufferEXT) { + glGenFramebuffersEXT = NULL; } } } - // - if(error != GL_NO_ERROR) { - //throw megaglest_runtime_error("Error creating texture cube"); - const char *errorString= reinterpret_cast(gluErrorString(error)); - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error creating texture cube, returned: %d [%s] (%X) [%s] w = %d, h = %d, glCompressionFormat = %d",error,errorString,error,currentPixmap->getPath().c_str(),currentPixmap->getW(),currentPixmap->getH(),glCompressionFormat); - throw megaglest_runtime_error(szBuf); +#endif + } + + /* gets next power of two */ + int pot(int x) { + int val = 1; + while (val < x) { + val *= 2; + } + return val; + } + + const std::size_t MIN_BYTES_TO_COMPRESS = 12; + + static std::string getSupportCompressedTextureFormatString(int format) { + std::string result = intToStr(format) + "[" + intToHex(format) + "]"; + switch (format) { + case GL_COMPRESSED_ALPHA: + result = "GL_COMPRESSED_ALPHA"; + break; + case GL_COMPRESSED_LUMINANCE: + result = "GL_COMPRESSED_LUMINANCE"; + break; + case GL_COMPRESSED_LUMINANCE_ALPHA: + result = "GL_COMPRESSED_LUMINANCE_ALPHA"; + break; + case GL_COMPRESSED_INTENSITY: + result = "GL_COMPRESSED_INTENSITY"; + break; + case GL_COMPRESSED_RGB: + result = "GL_COMPRESSED_RGB"; + break; + case GL_COMPRESSED_RGBA: + result = "GL_COMPRESSED_RGBA"; + break; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + result = "GL_COMPRESSED_RGB_S3TC_DXT1_EXT"; + break; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + result = "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT"; + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + result = "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT"; + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + result = "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT"; + break; + + /* + case GL_COMPRESSED_SRGB: + result = "GL_COMPRESSED_SRGB"; + break; + + case GL_COMPRESSED_SRGB_ALPHA: + result = "GL_COMPRESSED_SRGB_ALPHA"; + break; + + case GL_COMPRESSED_SLUMINANCE: + result = "GL_COMPRESSED_SLUMINANCE"; + break; + + case GL_COMPRESSED_SLUMINANCE_ALPHA: + result = "GL_COMPRESSED_SLUMINANCE_ALPHA"; + break; + + case GL_COMPRESSED_RED: + result = "GL_COMPRESSED_RED"; + break; + + case GL_COMPRESSED_RG: + result = "GL_COMPRESSED_RG"; + break; + + case GL_COMPRESSED_RED_RGTC1: + result = "GL_COMPRESSED_RED_RGTC1"; + break; + + case GL_COMPRESSED_SIGNED_RED_RGTC1: + result = "GL_COMPRESSED_SIGNED_RED_RGTC1"; + break; + + case GL_COMPRESSED_RG_RGTC2: + result = "GL_COMPRESSED_RG_RGTC2"; + break; + + case GL_COMPRESSED_SIGNED_RG_RGTC2: + result = "GL_COMPRESSED_SIGNED_RG_RGTC2"; + break; + + case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: + result = "GL_COMPRESSED_RGBA_BPTC_UNORM_ARB"; + break; + + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: + result = "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB"; + break; + + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: + result = "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB"; + break; + + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: + result = "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB"; + break; + */ + case GL_COMPRESSED_RGB_FXT1_3DFX: + result = "GL_COMPRESSED_RGB_FXT1_3DFX"; + break; + + case GL_COMPRESSED_RGBA_FXT1_3DFX: + result = "GL_COMPRESSED_RGBA_FXT1_3DFX"; + break; + + /* + case GL_COMPRESSED_SRGB_EXT: + result = "GL_COMPRESSED_SRGB_EXT"; + break; + + case GL_COMPRESSED_SRGB_ALPHA_EXT: + result = "GL_COMPRESSED_SRGB_ALPHA_EXT"; + break; + + case GL_COMPRESSED_SLUMINANCE_EXT: + result = "GL_COMPRESSED_SLUMINANCE_EXT"; + break; + + case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT: + result = "GL_COMPRESSED_SLUMINANCE_ALPHA_EXT"; + break; + + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + result = "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT"; + break; + + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + result = "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT"; + break; + + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + result = "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT"; + break; + + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + result = "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT"; + break; + + case GL_COMPRESSED_LUMINANCE_LATC1_EXT: + result = "GL_COMPRESSED_LUMINANCE_LATC1_EXT"; + break; + + case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT: + result = "GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT"; + break; + + case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT: + result = "GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT"; + break; + + case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT: + result = "GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT"; + break; + + case GL_COMPRESSED_RED_RGTC1_EXT: + result = "GL_COMPRESSED_RED_RGTC1_EXT"; + break; + + case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: + result = "GL_COMPRESSED_SIGNED_RED_RGTC1_EXT"; + break; + + case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + result = "GL_COMPRESSED_RED_GREEN_RGTC2_EXT"; + break; + + case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: + result = "GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT"; + break; + */ + + /* + #define GL_COMPRESSED_SRGB 0x8C48 + #define GL_COMPRESSED_SRGB_ALPHA 0x8C49 + + #define GL_COMPRESSED_SLUMINANCE 0x8C4A + #define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B + + #define GL_COMPRESSED_RED 0x8225 + #define GL_COMPRESSED_RG 0x8226 + + #define GL_COMPRESSED_RED_RGTC1 0x8DBB + #define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC + #define GL_COMPRESSED_RG_RGTC2 0x8DBD + #define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE + + #define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C + #define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D + #define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E + #define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F + + #define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 + #define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 + + #define GL_COMPRESSED_SRGB_EXT 0x8C48 + #define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 + #define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A + #define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B + #define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C + #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D + #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E + #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F + + #define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 + #define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 + #define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 + #define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 + + #define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB + #define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC + #define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD + #define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE + */ + + } + return result; + } + + static int getNumCompressedTextureFormats() { + int numCompressedTextureFormats = 0; + glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, (GLint*) &numCompressedTextureFormats); + return numCompressedTextureFormats; + } + + static std::vector getSupportCompressedTextureFormats() { + std::vector result; + int count = getNumCompressedTextureFormats(); + if (count > 0) { + int *formats = new int[count]; + glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, (GLint*) &formats[0]); + + for (int i = 0; i < count; ++i) { + result.push_back(formats[i]); + } + delete[] formats; + } + + if (Texture::useTextureCompression == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "------------------------------------------------\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "**** getSupportCompressedTextureFormats() result.size() = %d, count = %d\n", (int) result.size(), count); + for (unsigned int i = 0; i < result.size(); ++i) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "Texture Compression #i = %d, result[i] = %d [%s]\n", i, result[i], getSupportCompressedTextureFormatString(result[i]).c_str()); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "------------------------------------------------\n"); + } + return result; + } + + GLint toCompressionFormatGl(GLint format) { + if (Texture::useTextureCompression == false) { + return format; + } + + static std::vector supportedCompressionFormats = getSupportCompressedTextureFormats(); + if (supportedCompressionFormats.empty() == true) { + return format; + } + + //GL_COMPRESSED_ALPHA <- white things but tile ok! + //GL_COMPRESSED_LUMINANCE <- black tiles + //GL_COMPRESSED_LUMINANCE_ALPHA <- black tiles + //GL_COMPRESSED_INTENSITY <- black tiles + //GL_COMPRESSED_RGB <- black tiles + //GL_COMPRESSED_RGBA <- black tiles + + // With the following extension (GL_EXT_texture_compression_s3tc) + //GL_COMPRESSED_RGB_S3TC_DXT1_EXT + //GL_COMPRESSED_RGBA_S3TC_DXT1_EXT + //GL_COMPRESSED_RGBA_S3TC_DXT3_EXT + //GL_COMPRESSED_RGBA_S3TC_DXT5_EXT + + //#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 + //#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 + + switch (format) { + case GL_LUMINANCE: + case GL_LUMINANCE8: + return GL_COMPRESSED_LUMINANCE; + case GL_RGB: + case GL_RGB8: + if (std::find(supportedCompressionFormats.begin(), supportedCompressionFormats.end(), GL_COMPRESSED_RGB_S3TC_DXT1_EXT) != supportedCompressionFormats.end()) { + return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + } else if (std::find(supportedCompressionFormats.begin(), supportedCompressionFormats.end(), GL_COMPRESSED_RGB) != supportedCompressionFormats.end()) { + return GL_COMPRESSED_RGB; + } + //else if(std::find(supportedCompressionFormats.begin(),supportedCompressionFormats.end(),GL_COMPRESSED_SRGB_S3TC_DXT1_EXT) != supportedCompressionFormats.end()) { + // return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; + //} + else if (std::find(supportedCompressionFormats.begin(), supportedCompressionFormats.end(), GL_COMPRESSED_RGB_FXT1_3DFX) != supportedCompressionFormats.end()) { + return GL_COMPRESSED_RGB_FXT1_3DFX; + } + break; + + case GL_RGBA: + case GL_RGBA8: + + if (std::find(supportedCompressionFormats.begin(), supportedCompressionFormats.end(), GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) != supportedCompressionFormats.end()) { + return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + } else if (std::find(supportedCompressionFormats.begin(), supportedCompressionFormats.end(), GL_COMPRESSED_RGBA) != supportedCompressionFormats.end()) { + return GL_COMPRESSED_RGBA; + } + //else if(std::find(supportedCompressionFormats.begin(),supportedCompressionFormats.end(),GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT) != supportedCompressionFormats.end()) { + // return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + //} + //else if(std::find(supportedCompressionFormats.begin(),supportedCompressionFormats.end(),GL_COMPRESSED_SRGB_S3TC_DXT1_EXT) != supportedCompressionFormats.end()) { + // return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; + //} + else if (std::find(supportedCompressionFormats.begin(), supportedCompressionFormats.end(), GL_COMPRESSED_RGBA_FXT1_3DFX) != supportedCompressionFormats.end()) { + return GL_COMPRESSED_RGBA_FXT1_3DFX; + } + break; + + case GL_ALPHA: + case GL_ALPHA8: + //return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + //return GL_COMPRESSED_ALPHA_ARB; + return GL_COMPRESSED_ALPHA; + //return GL_COMPRESSED_RGBA; + default: + return format; + } + return format; + } + + GLint toWrapModeGl(Texture::WrapMode wrapMode) { + switch (wrapMode) { + case Texture::wmClamp: + return GL_CLAMP; + case Texture::wmRepeat: + return GL_REPEAT; + case Texture::wmClampToEdge: + return GL_CLAMP_TO_EDGE; + default: + assert(false); + return GL_CLAMP; } } - OutputTextureDebugInfo(format, currentPixmap->getComponents(),getPath(),currentPixmap->getPixelByteCount(),target); - } - inited= true; + GLint toFormatGl(Texture::Format format, int components) { + switch (format) { + case Texture::fAuto: + switch (components) { + case 1: + return GL_LUMINANCE; + case 3: + return GL_RGB; + case 4: + return GL_RGBA; + default: + std::cerr << "Components = " << (components) << std::endl; + assert(false); + return GL_RGBA; + } + break; + case Texture::fLuminance: + return GL_LUMINANCE; + case Texture::fAlpha: + return GL_ALPHA; + case Texture::fRgb: + return GL_RGB; + case Texture::fRgba: + return GL_RGBA; + default: + assert(false); + return GL_RGB; + } + } - } + GLint toInternalFormatGl(Texture::Format format, int components) { + switch (format) { + case Texture::fAuto: + switch (components) { + case 1: + return GL_LUMINANCE8; + case 3: + return GL_RGB8; + case 4: + return GL_RGBA8; + default: + assert(false); + return GL_RGBA8; + } + break; + case Texture::fLuminance: + return GL_LUMINANCE8; + case Texture::fAlpha: + return GL_ALPHA8; + case Texture::fRgb: + return GL_RGB8; + case Texture::fRgba: + return GL_RGBA8; + default: + assert(false); + return GL_RGB8; + } + } - assertGl(); -} + TextureGl::TextureGl() { + handle = 0; + renderBufferId = 0; + frameBufferId = 0; + setupGLExtensionMethods(); + } + + bool TextureGl::supports_FBO_RBO() { + return (glGenFramebuffersEXT != NULL); + } + + void TextureGl::setup_FBO_RBO() { + if (getTextureWidth() < 0 || getTextureHeight() < 0) { + throw megaglest_runtime_error("getTextureWidth() < 0 || getTextureHeight() < 0"); + } + + // Need some work to get extensions properly working in Windows (use Glew lib) + // Did we successfully setup FBO's? + if (glGenFramebuffersEXT) { + GLint width = 0; + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); + GLint height = 0; + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); + + //------------------------- + glGenFramebuffersEXT(1, &frameBufferId); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId); + //Attach 2D texture to this FBO + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, handle, 0); + //------------------------- + glGenRenderbuffersEXT(1, &renderBufferId); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBufferId); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, getTextureWidth(), getTextureHeight()); + //------------------------- + //Attach depth buffer to FBO + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderBufferId); + //------------------------- + //Does the GPU support current FBO configuration? + GLenum status; + status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + switch (status) { + case GL_FRAMEBUFFER_COMPLETE_EXT: + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"FBO attachment OK!\n"); + break; + default: + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"FBO attachment BAD!\n"); + break; + } + //------------------------- + //and now you can render to GL_TEXTURE_2D + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + } + + void TextureGl::teardown_FBO_RBO() { + // Need some work to get extensions properly working in Windows (use Glew lib) + if (glGenFramebuffersEXT) { + //---------------- + //Bind 0, which means render to back buffer + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + //And in the end, cleanup + //Delete resources + //glDeleteTextures(1, &handle); + glDeleteRenderbuffersEXT(1, &frameBufferId); + //Bind 0, which means render to back buffer, as a result, fb is unbound + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glDeleteFramebuffersEXT(1, &frameBufferId); + } + } + + void TextureGl::initRenderBuffer() { + // Need some work to get extensions properly working in Windows (use Glew lib) + if (glGenFramebuffersEXT) { + // create a renderbuffer object to store depth info + glGenRenderbuffersEXT(1, &renderBufferId); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBufferId); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, getTextureWidth(), getTextureHeight()); + //glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } + } + + void TextureGl::initFrameBuffer() { + // Need some work to get extensions properly working in Windows (use Glew lib) + if (glGenFramebuffersEXT) { + // create a framebuffer object + glGenFramebuffersEXT(1, &frameBufferId); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId); + } + } + + void TextureGl::attachRenderBuffer() { + // Need some work to get extensions properly working in Windows (use Glew lib) + if (glGenFramebuffersEXT) { + // attach the renderbuffer to depth attachment point + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderBufferId); + } + } + + void TextureGl::attachFrameBufferToTexture() { + // Need some work to get extensions properly working in Windows (use Glew lib) + if (glGenFramebuffersEXT) { + // attach the texture to FBO color attachment point + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, handle, 0); + } + } + + bool TextureGl::checkFrameBufferStatus() { + // Need some work to get extensions properly working in Windows (use Glew lib) + if (glGenFramebuffersEXT) { + // check FBO status + // Does the GPU support current FBO configuration? + GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "checkFrameBufferStatus() status = %d [%X]\n", status, status); + return false; + } + return true; + } + + return false; + } + + void TextureGl::dettachFrameBufferFromTexture() { + // Need some work to get extensions properly working in Windows (use Glew lib) + if (glGenFramebuffersEXT) { + // switch back to window-system-provided framebuffer + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } + } + + void TextureGl::dettachRenderBufferFromTexture() { + // Need some work to get extensions properly working in Windows (use Glew lib) + if (glGenFramebuffersEXT) { + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } + } + + TextureGl::~TextureGl() { + // Need some work to get extensions properly working in Windows (use Glew lib) + if (glGenFramebuffersEXT) { + if (renderBufferId != 0) { + glDeleteRenderbuffersEXT(1, &renderBufferId); + renderBufferId = 0; + } + if (frameBufferId != 0) { + glDeleteFramebuffersEXT(1, &frameBufferId); + frameBufferId = 0; + } + //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } + } + + // ===================================================== + // class Texture1DGl + // ===================================================== + Texture1DGl::Texture1DGl() : Texture1D(), TextureGl() { + } + + Texture1DGl::~Texture1DGl() { + end(); + } + + void Texture1DGl::init(Filter filter, int maxAnisotropy) { + assertGl(); + + if (inited == false) { + //params + GLint wrap = toWrapModeGl(wrapMode); + GLint glFormat = toFormatGl(format, pixmap.getComponents()); + GLint glInternalFormat = toInternalFormatGl(format, pixmap.getComponents()); + GLint glCompressionFormat = toCompressionFormatGl(glInternalFormat); + if (forceCompressionDisabled == true || (pixmap.getPixelByteCount() > 0 && pixmap.getPixelByteCount() <= MIN_BYTES_TO_COMPRESS)) { + glCompressionFormat = glInternalFormat; + } + + //pixel init var + const uint8* pixels = pixmapInit ? pixmap.getPixels() : NULL; + + //gen texture + glGenTextures(1, &handle); + glBindTexture(GL_TEXTURE_1D, handle); + + //wrap params + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, wrap); + + //maxAnisotropy + if (isGlExtensionSupported("GL_EXT_texture_filter_anisotropic")) { + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy); + } + + if (mipmap) { + GLuint glFilter = filter == fTrilinear ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR_MIPMAP_NEAREST; + + //build mipmaps + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, glFilter); + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + int error = gluBuild1DMipmaps( + GL_TEXTURE_1D, glCompressionFormat, pixmap.getW(), + glFormat, GL_UNSIGNED_BYTE, pixels); + + // Now try without compression if we tried compression + if (error != 0 && glCompressionFormat != glInternalFormat) { + int error2 = gluBuild1DMipmaps( + GL_TEXTURE_1D, glInternalFormat, pixmap.getW(), + glFormat, GL_UNSIGNED_BYTE, pixels); + + if (error2 == 0) { + error = 0; + } + } + // + + if (error != 0) { + //throw megaglest_runtime_error("Error building texture 1D mipmaps"); + const char *errorString = reinterpret_cast(gluErrorString(error)); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error building texture 1D mipmaps, returned: %d [%s] for [%s] w = %d, glCompressionFormat = %d", error, errorString, pixmap.getPath().c_str(), pixmap.getW(), glCompressionFormat); + throw megaglest_runtime_error(szBuf); + } + } else { + //build single texture + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexImage1D( + GL_TEXTURE_1D, 0, glCompressionFormat, pixmap.getW(), + 0, glFormat, GL_UNSIGNED_BYTE, pixels); + + GLint error = glGetError(); + + // Now try without compression if we tried compression + if (error != GL_NO_ERROR && glCompressionFormat != glInternalFormat) { + glTexImage1D( + GL_TEXTURE_1D, 0, glInternalFormat, pixmap.getW(), + 0, glFormat, GL_UNSIGNED_BYTE, pixels); + + GLint error2 = glGetError(); + + if (error2 == GL_NO_ERROR) { + error = GL_NO_ERROR; + } + } + // + + if (error != GL_NO_ERROR) { + //throw megaglest_runtime_error("Error creating texture 1D"); + const char *errorString = reinterpret_cast(gluErrorString(error)); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error creating texture 1D, returned: %d [%s] (%X) [%s] w = %d, glCompressionFormat = %d", error, errorString, error, pixmap.getPath().c_str(), pixmap.getW(), glCompressionFormat); + throw megaglest_runtime_error(szBuf); + } + } + inited = true; + OutputTextureDebugInfo(format, pixmap.getComponents(), getPath(), pixmap.getPixelByteCount(), GL_TEXTURE_1D); + } + + assertGl(); + } + + void Texture1DGl::end(bool deletePixelBuffer) { + if (inited == true) { + assertGl(); + glDeleteTextures(1, &handle); + assertGl(); + handle = 0; + inited = false; + if (deletePixelBuffer == true) { + deletePixels(); + } + } + } + + // ===================================================== + // class Texture2DGl + // ===================================================== + + Texture2DGl::Texture2DGl() : Texture2D(), TextureGl() { + } + + Texture2DGl::~Texture2DGl() { + end(); + } + + void Texture2DGl::init(Filter filter, int maxAnisotropy) { + assertGl(); + + if (inited == false) { + assertGl(); + //params + GLint wrap = toWrapModeGl(wrapMode); + GLint glFormat = toFormatGl(format, pixmap.getComponents()); + GLint glInternalFormat = toInternalFormatGl(format, pixmap.getComponents()); + GLint glCompressionFormat = toCompressionFormatGl(glInternalFormat); + if (forceCompressionDisabled == true || (pixmap.getPixelByteCount() > 0 && pixmap.getPixelByteCount() <= MIN_BYTES_TO_COMPRESS)) { + glCompressionFormat = glInternalFormat; + } + + assertGl(); + //pixel init var + const uint8* pixels = pixmapInit ? pixmap.getPixels() : NULL; + + //gen texture + glGenTextures(1, &handle); + glBindTexture(GL_TEXTURE_2D, handle); + + assertGl(); + + //wrap params + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); + + assertGl(); + + //maxAnisotropy + if (isGlExtensionSupported("GL_EXT_texture_filter_anisotropic")) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy); + } + + if (mipmap) { + GLuint glFilter = (filter == fTrilinear ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR_MIPMAP_NEAREST); + + //build mipmaps + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glFilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + /* + * Replaced this call due to: http://www.opengl.org/wiki/Common_Mistakes#gluBuild2DMipmaps + * + int error= gluBuild2DMipmaps( + GL_TEXTURE_2D, glCompressionFormat, + pixmap.getW(), pixmap.getH(), + glFormat, GL_UNSIGNED_BYTE, pixels); + */ + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + + //! Note: NPOTs + nearest filtering seems broken on ATIs + if (!(count_bits_set(pixmap.getW()) == 1 && count_bits_set(pixmap.getH()) == 1) && + TextureGl::enableATIHacks == true) { + // && (!GLEW_ARB_texture_non_power_of_two || (globalRendering->atiHacks && nearest)) ) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n\n**WARNING** Enabling ATI video card hacks, resizing texture to power of two [%d x %d] to [%d x %d] components [%d] path [%s]\n", pixmap.getW(), pixmap.getH(), next_power_of_2(pixmap.getW()), next_power_of_2(pixmap.getH()), pixmap.getComponents(), pixmap.getPath().c_str()); + + pixmap.Scale(glFormat, next_power_of_2(pixmap.getW()), next_power_of_2(pixmap.getH())); + } + + glTexImage2D(GL_TEXTURE_2D, 0, glCompressionFormat, + pixmap.getW(), pixmap.getH(), 0, + glFormat, GL_UNSIGNED_BYTE, pixels); + + GLint error = glGetError(); + + // Now try without compression if we tried compression + if (error != GL_NO_ERROR && glCompressionFormat != glInternalFormat) { + glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, + pixmap.getW(), pixmap.getH(), 0, + glFormat, GL_UNSIGNED_BYTE, pixels); + + GLint error2 = glGetError(); + + if (error2 == GL_NO_ERROR) { + error = GL_NO_ERROR; + } + } + if (error != GL_NO_ERROR) { + int error3 = gluBuild2DMipmaps( + GL_TEXTURE_2D, glCompressionFormat, + pixmap.getW(), pixmap.getH(), + glFormat, GL_UNSIGNED_BYTE, pixels); + if (error3 == GL_NO_ERROR) { + error = GL_NO_ERROR; + } + } + if (error != GL_NO_ERROR) { + int error4 = gluBuild2DMipmaps( + GL_TEXTURE_2D, glInternalFormat, + pixmap.getW(), pixmap.getH(), + glFormat, GL_UNSIGNED_BYTE, pixels); + if (error4 == GL_NO_ERROR) { + error = GL_NO_ERROR; + } + } + + // + + if (error != GL_NO_ERROR) { + //throw megaglest_runtime_error("Error building texture 2D mipmaps"); + const char *errorString = reinterpret_cast(gluErrorString(error)); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error building texture 2D mipmaps [%s], returned: %d [%s] for [%s] w = %d, h = %d, glCompressionFormat = %d", this->path.c_str(), error, errorString, (pixmap.getPath() != "" ? pixmap.getPath().c_str() : this->path.c_str()), pixmap.getW(), pixmap.getH(), glCompressionFormat); + throw megaglest_runtime_error(szBuf); + } + } else { + //build single texture + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + assertGl(); + + if (!(count_bits_set(pixmap.getW()) == 1 && count_bits_set(pixmap.getH()) == 1) && + TextureGl::enableATIHacks == true) { + // && (!GLEW_ARB_texture_non_power_of_two || (globalRendering->atiHacks && nearest)) ) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n\n**WARNING** Enabling ATI video card hacks, resizing texture to power of two [%d x %d] to [%d x %d] components [%d] path [%s]\n", pixmap.getW(), pixmap.getH(), next_power_of_2(pixmap.getW()), next_power_of_2(pixmap.getH()), pixmap.getComponents(), pixmap.getPath().c_str()); + + pixmap.Scale(glFormat, next_power_of_2(pixmap.getW()), next_power_of_2(pixmap.getH())); + } + + glTexImage2D(GL_TEXTURE_2D, 0, glCompressionFormat, pixmap.getW(), + pixmap.getH(), 0, glFormat, GL_UNSIGNED_BYTE, pixels); + + GLint error = glGetError(); + + // Now try without compression if we tried compression + if (error != GL_NO_ERROR && glCompressionFormat != glInternalFormat) { + glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, pixmap.getW(), + pixmap.getH(), 0, glFormat, GL_UNSIGNED_BYTE, pixels); + + GLint error2 = glGetError(); + + if (error2 == GL_NO_ERROR) { + error = GL_NO_ERROR; + } else { + glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, pot(pixmap.getW()), + pot(pixmap.getH()), 0, glFormat, GL_UNSIGNED_BYTE, NULL); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixmap.getW(), pixmap.getH(), + glFormat, GL_UNSIGNED_BYTE, pixels); + + GLint error3 = glGetError(); + + if (error3 == GL_NO_ERROR) { + error = GL_NO_ERROR; + } + } + } else if (error != GL_NO_ERROR) { + glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, pot(pixmap.getW()), + pot(pixmap.getH()), 0, glFormat, GL_UNSIGNED_BYTE, NULL); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixmap.getW(), pixmap.getH(), + glFormat, GL_UNSIGNED_BYTE, pixels); + + GLint error3 = glGetError(); + + if (error3 == GL_NO_ERROR) { + error = GL_NO_ERROR; + } + } + + // + + //throw megaglest_runtime_error("TEST!"); + + if (error != GL_NO_ERROR) { + const char *errorString = reinterpret_cast(gluErrorString(error)); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error creating texture 2D path [%s], returned: %d [%s] (%X) [%s] w = %d, h = %d, glInternalFormat = %d, glFormat = %d, glCompressionFormat = %d", this->path.c_str(), error, errorString, error, pixmap.getPath().c_str(), pixmap.getW(), pixmap.getH(), glInternalFormat, glFormat, glCompressionFormat); + throw megaglest_runtime_error(szBuf); + } + } + inited = true; + OutputTextureDebugInfo(format, pixmap.getComponents(), getPath(), pixmap.getPixelByteCount(), GL_TEXTURE_2D); + } + + assertGl(); + } + + void Texture2DGl::end(bool deletePixelBuffer) { + if (inited == true) { + //printf("==> Deleting GL Texture [%s] handle = %d\n",getPath().c_str(),handle); + assertGl(); + glDeleteTextures(1, &handle); + assertGl(); + handle = 0; + inited = false; + if (deletePixelBuffer == true) { + deletePixels(); + } + } + } + + // ===================================================== + // class Texture3DGl + // ===================================================== + + Texture3DGl::Texture3DGl() : Texture3D(), TextureGl() { + } + + Texture3DGl::~Texture3DGl() { + end(); + } + + void Texture3DGl::init(Filter filter, int maxAnisotropy) { + assertGl(); + + if (inited == false) { + //params + GLint wrap = toWrapModeGl(wrapMode); + GLint glFormat = toFormatGl(format, pixmap.getComponents()); + GLint glInternalFormat = toInternalFormatGl(format, pixmap.getComponents()); + GLint glCompressionFormat = toCompressionFormatGl(glInternalFormat); + if (forceCompressionDisabled == true || (pixmap.getPixelByteCount() > 0 && pixmap.getPixelByteCount() <= MIN_BYTES_TO_COMPRESS)) { + glCompressionFormat = glInternalFormat; + } + if (glCompressionFormat == GL_COMPRESSED_RGBA_FXT1_3DFX) { + glCompressionFormat = glInternalFormat; + } + + //pixel init var + const uint8* pixels = pixmapInit ? pixmap.getPixels() : NULL; + + //gen texture + glGenTextures(1, &handle); + glBindTexture(GL_TEXTURE_3D, handle); + + //wrap params + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, wrap); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, wrap); + + //build single texture + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexImage3D( + GL_TEXTURE_3D, 0, glCompressionFormat, + pixmap.getW(), pixmap.getH(), pixmap.getD(), + 0, glFormat, GL_UNSIGNED_BYTE, pixels); + + GLint error = glGetError(); + + // Now try without compression if we tried compression + if (error != GL_NO_ERROR && glCompressionFormat != glInternalFormat) { + glTexImage3D( + GL_TEXTURE_3D, 0, glInternalFormat, + pixmap.getW(), pixmap.getH(), pixmap.getD(), + 0, glFormat, GL_UNSIGNED_BYTE, pixels); + + GLint error2 = glGetError(); + + if (error2 == GL_NO_ERROR) { + error = GL_NO_ERROR; + } + } else if (error != GL_NO_ERROR) { + glTexImage3D( + GL_TEXTURE_3D, 0, glInternalFormat, + pot(pixmap.getW()), pot(pixmap.getH()), pot(pixmap.getD()), + 0, glFormat, GL_UNSIGNED_BYTE, NULL); + + glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, + pixmap.getW(), pixmap.getH(), pixmap.getD(), + glFormat, GL_UNSIGNED_BYTE, pixels); + + GLint error3 = glGetError(); + + if (error3 == GL_NO_ERROR) { + error = GL_NO_ERROR; + } + } + + // + + if (error != GL_NO_ERROR) { + //throw megaglest_runtime_error("Error creating texture 3D"); + const char *errorString = reinterpret_cast(gluErrorString(error)); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error creating texture 3D, returned: %d [%s] (%X) [%s] w = %d, h = %d, d = %d, glCompressionFormat = %d", error, errorString, error, pixmap.getPath().c_str(), pixmap.getW(), pixmap.getH(), pixmap.getD(), glCompressionFormat); + throw megaglest_runtime_error(szBuf); + } + inited = true; + + OutputTextureDebugInfo(format, pixmap.getComponents(), getPath(), pixmap.getPixelByteCount(), GL_TEXTURE_3D); + } + + assertGl(); + } + + void Texture3DGl::end(bool deletePixelBuffer) { + if (inited == true) { + assertGl(); + glDeleteTextures(1, &handle); + assertGl(); + handle = 0; + inited = false; + if (deletePixelBuffer == true) { + deletePixels(); + } + } + } + + // ===================================================== + // class TextureCubeGl + // ===================================================== + + TextureCubeGl::TextureCubeGl() : TextureCube(), TextureGl() { + } + + TextureCubeGl::~TextureCubeGl() { + end(); + } + + void TextureCubeGl::init(Filter filter, int maxAnisotropy) { + assertGl(); + + if (inited == false) { + //gen texture + glGenTextures(1, &handle); + glBindTexture(GL_TEXTURE_CUBE_MAP, handle); + + //wrap + GLint wrap = toWrapModeGl(wrapMode); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, wrap); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, wrap); + + //filter + if (mipmap) { + GLuint glFilter = filter == fTrilinear ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR_MIPMAP_NEAREST; + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, glFilter); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } else { + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + + for (int i = 0; i < 6; ++i) { + //params + Pixmap2D *currentPixmap = pixmap.getFace(i); + + GLint glFormat = toFormatGl(format, currentPixmap->getComponents()); + GLint glInternalFormat = toInternalFormatGl(format, currentPixmap->getComponents()); + GLint glCompressionFormat = toCompressionFormatGl(glInternalFormat); + if (forceCompressionDisabled == true || (currentPixmap->getPixelByteCount() > 0 && currentPixmap->getPixelByteCount() <= MIN_BYTES_TO_COMPRESS)) { + glCompressionFormat = glInternalFormat; + } + + //pixel init var + const uint8* pixels = pixmapInit ? currentPixmap->getPixels() : NULL; + GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; + + if (mipmap) { + + /* + * Replaced this call due to: http://www.opengl.org/wiki/Common_Mistakes#gluBuild2DMipmaps + * + int error= gluBuild2DMipmaps( + target, glCompressionFormat, + currentPixmap->getW(), currentPixmap->getH(), + glFormat, GL_UNSIGNED_BYTE, pixels); + + */ + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); + + if (!(count_bits_set(currentPixmap->getW()) == 1 && count_bits_set(currentPixmap->getH()) == 1) && + TextureGl::enableATIHacks == true) { + // && (!GLEW_ARB_texture_non_power_of_two || (globalRendering->atiHacks && nearest)) ) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n\n**WARNING** Enabling ATI video card hacks, resizing texture to power of two [%d x %d] to [%d x %d] components [%d] path [%s]\n", currentPixmap->getW(), currentPixmap->getH(), next_power_of_2(currentPixmap->getW()), next_power_of_2(currentPixmap->getH()), currentPixmap->getComponents(), currentPixmap->getPath().c_str()); + + currentPixmap->Scale(glFormat, next_power_of_2(currentPixmap->getW()), next_power_of_2(currentPixmap->getH())); + } + + glTexImage2D(target, 0, glCompressionFormat, + currentPixmap->getW(), currentPixmap->getH(), 0, + glFormat, GL_UNSIGNED_BYTE, pixels); + + int error = glGetError(); + + // Now try without compression if we tried compression + if (error != GL_NO_ERROR && glCompressionFormat != glInternalFormat) { + glTexImage2D(target, 0, glInternalFormat, + currentPixmap->getW(), currentPixmap->getH(), 0, + glFormat, GL_UNSIGNED_BYTE, pixels); + + GLint error2 = glGetError(); + + if (error2 == GL_NO_ERROR) { + error = GL_NO_ERROR; + } + } + if (error != GL_NO_ERROR) { + int error3 = gluBuild2DMipmaps( + target, glCompressionFormat, + currentPixmap->getW(), currentPixmap->getH(), + glFormat, GL_UNSIGNED_BYTE, pixels); + + + if (error3 == GL_NO_ERROR) { + error = GL_NO_ERROR; + } + } + if (error != GL_NO_ERROR) { + int error4 = gluBuild2DMipmaps( + target, glInternalFormat, + currentPixmap->getW(), currentPixmap->getH(), + glFormat, GL_UNSIGNED_BYTE, pixels); + + + if (error4 == GL_NO_ERROR) { + error = GL_NO_ERROR; + } + } + + // + + if (error != GL_NO_ERROR) { + //throw megaglest_runtime_error("Error building texture cube mipmaps"); + const char *errorString = reinterpret_cast(gluErrorString(error)); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error building texture cube mipmaps, returned: %d [%s] for [%s] w = %d, h = %d, glCompressionFormat = %d", error, errorString, currentPixmap->getPath().c_str(), currentPixmap->getW(), currentPixmap->getH(), glCompressionFormat); + throw megaglest_runtime_error(szBuf); + } + } else { + + if (!(count_bits_set(currentPixmap->getW()) == 1 && count_bits_set(currentPixmap->getH()) == 1) && + TextureGl::enableATIHacks == true) { + // && (!GLEW_ARB_texture_non_power_of_two || (globalRendering->atiHacks && nearest)) ) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n\n**WARNING** Enabling ATI video card hacks, resizing texture to power of two [%d x %d] to [%d x %d] components [%d] path [%s]\n", currentPixmap->getW(), currentPixmap->getH(), next_power_of_2(currentPixmap->getW()), next_power_of_2(currentPixmap->getH()), currentPixmap->getComponents(), currentPixmap->getPath().c_str()); + + currentPixmap->Scale(glFormat, next_power_of_2(currentPixmap->getW()), next_power_of_2(currentPixmap->getH())); + } + + glTexImage2D( + target, 0, glCompressionFormat, + currentPixmap->getW(), currentPixmap->getH(), + 0, glFormat, GL_UNSIGNED_BYTE, pixels); + + int error = glGetError(); + + // Now try without compression if we tried compression + if (error != GL_NO_ERROR && glCompressionFormat != glInternalFormat) { + glTexImage2D( + target, 0, glInternalFormat, + currentPixmap->getW(), currentPixmap->getH(), + 0, glFormat, GL_UNSIGNED_BYTE, pixels); + + GLint error2 = glGetError(); + + if (error2 == GL_NO_ERROR) { + error = GL_NO_ERROR; + } else { + glTexImage2D(target, 0, glInternalFormat, pot(currentPixmap->getW()), + pot(currentPixmap->getH()), 0, glFormat, GL_UNSIGNED_BYTE, NULL); + + glTexSubImage2D(target, 0, 0, 0, currentPixmap->getW(), currentPixmap->getH(), + glFormat, GL_UNSIGNED_BYTE, pixels); + + GLint error3 = glGetError(); + + if (error3 == GL_NO_ERROR) { + error = GL_NO_ERROR; + } + } + } + // + + if (error != GL_NO_ERROR) { + //throw megaglest_runtime_error("Error creating texture cube"); + const char *errorString = reinterpret_cast(gluErrorString(error)); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error creating texture cube, returned: %d [%s] (%X) [%s] w = %d, h = %d, glCompressionFormat = %d", error, errorString, error, currentPixmap->getPath().c_str(), currentPixmap->getW(), currentPixmap->getH(), glCompressionFormat); + throw megaglest_runtime_error(szBuf); + } + } + + OutputTextureDebugInfo(format, currentPixmap->getComponents(), getPath(), currentPixmap->getPixelByteCount(), target); + } + inited = true; + + } + + assertGl(); + } + + void TextureCubeGl::end(bool deletePixelBuffer) { + if (inited == true) { + assertGl(); + glDeleteTextures(1, &handle); + assertGl(); + handle = 0; + inited = false; + if (deletePixelBuffer == true) { + deletePixels(); + } + } + } + + void TextureGl::OutputTextureDebugInfo(Texture::Format format, int components, const string path, std::size_t rawSize, GLenum texType) { + if (Texture::useTextureCompression == true) { + GLint glFormat = toFormatGl(format, components); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "**** Texture filename: [%s] format = %d components = %d, glFormat = %d, rawSize = %llu\n", path.c_str(), format, components, glFormat, (long long unsigned int)rawSize); + + GLint compressed = 0; + glGetTexLevelParameteriv(texType, 0, GL_TEXTURE_COMPRESSED, &compressed); + int error = glGetError(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "**** Texture compressed status: %d, error [%d] (%X)\n", compressed, error, error); + + bool isCompressed = (compressed == 1); + compressed = 0; + glGetTexLevelParameteriv(texType, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compressed); + error = glGetError(); + + double percent = 0; + if (isCompressed == true) { + percent = ((double) compressed / (double) rawSize) * (double)100.0; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "**** Texture image size in video RAM: %d [%.2f%%], error [%d] (%X)\n", compressed, percent, error, error); + + compressed = 0; + glGetTexLevelParameteriv(texType, 0, GL_TEXTURE_INTERNAL_FORMAT, &compressed); + error = glGetError(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "**** Texture image compression format used: %d, error [%d] (%X)\n", compressed, error, error); + } + } -void TextureCubeGl::end(bool deletePixelBuffer) { - if(inited == true) { - assertGl(); - glDeleteTextures(1, &handle); - assertGl(); - handle=0; - inited=false; - if(deletePixelBuffer == true) { - deletePixels(); } } -} - -void TextureGl::OutputTextureDebugInfo(Texture::Format format, int components,const string path,std::size_t rawSize,GLenum texType) { - if(Texture::useTextureCompression == true) { - GLint glFormat= toFormatGl(format, components); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"**** Texture filename: [%s] format = %d components = %d, glFormat = %d, rawSize = %llu\n",path.c_str(),format,components,glFormat,(long long unsigned int)rawSize); - - GLint compressed=0; - glGetTexLevelParameteriv(texType, 0, GL_TEXTURE_COMPRESSED, &compressed); - int error = glGetError(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"**** Texture compressed status: %d, error [%d] (%X)\n",compressed,error,error); - - bool isCompressed = (compressed == 1); - compressed=0; - glGetTexLevelParameteriv(texType, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compressed); - error = glGetError(); - - double percent = 0; - if(isCompressed == true) { - percent = ((double)compressed / (double)rawSize) * (double)100.0; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"**** Texture image size in video RAM: %d [%.2f%%], error [%d] (%X)\n",compressed,percent,error,error); - - compressed=0; - glGetTexLevelParameteriv(texType, 0, GL_TEXTURE_INTERNAL_FORMAT, &compressed); - error = glGetError(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"**** Texture image compression format used: %d, error [%d] (%X)\n",compressed,error,error); - } -} - -}}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/graphics/graphics_interface.cpp b/source/shared_lib/sources/graphics/graphics_interface.cpp index bfb272c89..c6c6f6c45 100644 --- a/source/shared_lib/sources/graphics/graphics_interface.cpp +++ b/source/shared_lib/sources/graphics/graphics_interface.cpp @@ -17,29 +17,31 @@ #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class GraphicsInterface -// ===================================================== + // ===================================================== + // class GraphicsInterface + // ===================================================== -GraphicsInterface::GraphicsInterface(){ - graphicsFactory= NULL; - currentContext= NULL; -} + GraphicsInterface::GraphicsInterface() { + graphicsFactory = NULL; + currentContext = NULL; + } -GraphicsInterface &GraphicsInterface::getInstance(){ - static GraphicsInterface graphicsInterface; - return graphicsInterface; -} + GraphicsInterface &GraphicsInterface::getInstance() { + static GraphicsInterface graphicsInterface; + return graphicsInterface; + } -void GraphicsInterface::setFactory(GraphicsFactory *graphicsFactory){ - this->graphicsFactory= graphicsFactory; -} + void GraphicsInterface::setFactory(GraphicsFactory *graphicsFactory) { + this->graphicsFactory = graphicsFactory; + } -void GraphicsInterface::setCurrentContext(Context *context){ - this->currentContext= context; - currentContext->makeCurrent(); -} + void GraphicsInterface::setCurrentContext(Context *context) { + this->currentContext = context; + currentContext->makeCurrent(); + } -}}//end namespace + } +}//end namespace diff --git a/source/shared_lib/sources/graphics/interpolation.cpp b/source/shared_lib/sources/graphics/interpolation.cpp index a493d5e6a..e07531a8b 100644 --- a/source/shared_lib/sources/graphics/interpolation.cpp +++ b/source/shared_lib/sources/graphics/interpolation.cpp @@ -24,98 +24,99 @@ using namespace std; using namespace Shared::Util; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class InterpolationData -// ===================================================== + // ===================================================== + // class InterpolationData + // ===================================================== -bool InterpolationData::enableInterpolation = true; + bool InterpolationData::enableInterpolation = true; -InterpolationData::InterpolationData(const Mesh *mesh) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - vertices= NULL; - normals= NULL; - - raw_frame_ofs = 0; - - this->mesh= mesh; -} - -InterpolationData::~InterpolationData(){ - delete [] vertices; - vertices=NULL; - delete [] normals; - normals=NULL; -} - -void InterpolationData::update(float t, bool cycle){ - updateVertices(t, cycle); - updateNormals(t, cycle); -} - -void InterpolationData::updateVertices(float t, bool cycle) { - update(mesh->getVertices(), vertices, t, cycle); -} - -void InterpolationData::updateNormals(float t, bool cycle) { - update(mesh->getNormals(), normals, t, cycle); -} - -void InterpolationData::update(const Vec3f* src, Vec3f* &dest, float t, bool cycle) { - - if(t <0.0f || t>1.0f) { - printf("ERROR t = [%f] for cycle [%d] f [%d] v [%d]\n",t,cycle,mesh->getFrameCount(),mesh->getVertexCount()); - } - //assert(t>=0.0f && t<=1.0f); - if(t < 0.0f || t > 1.0f) { - throw megaglest_runtime_error("t < 0.0f || t > 1.0f t = [" + floatToStr(t,16) + "]"); - - assert(t >= 0.f && t <= 1.f); - } - - uint32 frameCount= mesh->getFrameCount(); - uint32 vertexCount= mesh->getVertexCount(); - - if(frameCount > 1) { - //misc vars - uint32 prevFrame; - uint32 nextFrame; - float localT; - - if(cycle == true) { - prevFrame= min(static_cast(t*frameCount), frameCount-1); - nextFrame= (prevFrame+1) % frameCount; - localT= t*frameCount - prevFrame; - } - else { - prevFrame= min (static_cast (t * (frameCount-1)), frameCount - 2); - nextFrame= min(prevFrame + 1, frameCount - 1); - localT= t * (frameCount-1) - prevFrame; - //printf(" prevFrame=%d nextFrame=%d localT=%f\n",prevFrame,nextFrame,localT); - } - - uint32 prevFrameBase= prevFrame*vertexCount; - uint32 nextFrameBase= nextFrame*vertexCount; - - //assertions - assert(prevFramemesh = mesh; + } + + InterpolationData::~InterpolationData() { + delete[] vertices; + vertices = NULL; + delete[] normals; + normals = NULL; + } + + void InterpolationData::update(float t, bool cycle) { + updateVertices(t, cycle); + updateNormals(t, cycle); + } + + void InterpolationData::updateVertices(float t, bool cycle) { + update(mesh->getVertices(), vertices, t, cycle); + } + + void InterpolationData::updateNormals(float t, bool cycle) { + update(mesh->getNormals(), normals, t, cycle); + } + + void InterpolationData::update(const Vec3f* src, Vec3f* &dest, float t, bool cycle) { + + if (t <0.0f || t>1.0f) { + printf("ERROR t = [%f] for cycle [%d] f [%d] v [%d]\n", t, cycle, mesh->getFrameCount(), mesh->getVertexCount()); + } + //assert(t>=0.0f && t<=1.0f); + if (t < 0.0f || t > 1.0f) { + throw megaglest_runtime_error("t < 0.0f || t > 1.0f t = [" + floatToStr(t, 16) + "]"); + + assert(t >= 0.f && t <= 1.f); + } + + uint32 frameCount = mesh->getFrameCount(); + uint32 vertexCount = mesh->getVertexCount(); + + if (frameCount > 1) { + //misc vars + uint32 prevFrame; + uint32 nextFrame; + float localT; + + if (cycle == true) { + prevFrame = min(static_cast(t*frameCount), frameCount - 1); + nextFrame = (prevFrame + 1) % frameCount; + localT = t*frameCount - prevFrame; + } else { + prevFrame = min(static_cast (t * (frameCount - 1)), frameCount - 2); + nextFrame = min(prevFrame + 1, frameCount - 1); + localT = t * (frameCount - 1) - prevFrame; + //printf(" prevFrame=%d nextFrame=%d localT=%f\n",prevFrame,nextFrame,localT); + } + + uint32 prevFrameBase = prevFrame*vertexCount; + uint32 nextFrameBase = nextFrame*vertexCount; + + //assertions + assert(prevFrame < frameCount); + assert(nextFrame < frameCount); + + if (enableInterpolation) { + if (!dest) { // not previously allocated + dest = new Vec3f[vertexCount]; + } + for (uint32 j = 0; j < vertexCount; ++j) { + dest[j] = src[prevFrameBase + j].lerp(localT, src[nextFrameBase + j]); + } + } else { + raw_frame_ofs = prevFrameBase; + } + } + } + + } +}//end namespace diff --git a/source/shared_lib/sources/graphics/model.cpp b/source/shared_lib/sources/graphics/model.cpp index 61b5a582d..c0dbc3e7e 100644 --- a/source/shared_lib/sources/graphics/model.cpp +++ b/source/shared_lib/sources/graphics/model.cpp @@ -33,2259 +33,2222 @@ using namespace Shared::Graphics::Gl; using namespace std; using namespace Shared::Util; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -using namespace Util; + using namespace Util; -// Utils methods for endianness conversion -void toEndianFileHeader(FileHeader &header) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - for(unsigned int i = 0; i < 3; ++i) { - header.id[i] = Shared::PlatformByteOrder::toCommonEndian(header.id[i]); - } - header.version = Shared::PlatformByteOrder::toCommonEndian(header.version); - } -} -void fromEndianFileHeader(FileHeader &header) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - for(unsigned int i = 0; i < 3; ++i) { - header.id[i] = Shared::PlatformByteOrder::fromCommonEndian(header.id[i]); - } - header.version = Shared::PlatformByteOrder::fromCommonEndian(header.version); - } -} - -void toEndianModelHeader(ModelHeader &header) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - header.type = Shared::PlatformByteOrder::toCommonEndian(header.type); - header.meshCount = Shared::PlatformByteOrder::toCommonEndian(header.meshCount); - } -} -void fromEndianModelHeader(ModelHeader &header) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - header.type = Shared::PlatformByteOrder::toCommonEndian(header.type); - header.meshCount = Shared::PlatformByteOrder::toCommonEndian(header.meshCount); - } -} - -void toEndianMeshHeader(MeshHeader &header) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - for(unsigned int i = 0; i < meshNameSize; ++i) { - header.name[i] = Shared::PlatformByteOrder::toCommonEndian(header.name[i]); - } - header.frameCount = Shared::PlatformByteOrder::toCommonEndian(header.frameCount); - header.vertexCount = Shared::PlatformByteOrder::toCommonEndian(header.vertexCount); - header.indexCount = Shared::PlatformByteOrder::toCommonEndian(header.indexCount); - for(unsigned int i = 0; i < 3; ++i) { - header.diffuseColor[i] = Shared::PlatformByteOrder::toCommonEndian(header.diffuseColor[i]); - header.specularColor[i] = Shared::PlatformByteOrder::toCommonEndian(header.specularColor[i]); - } - header.specularPower = Shared::PlatformByteOrder::toCommonEndian(header.specularPower); - header.opacity = Shared::PlatformByteOrder::toCommonEndian(header.opacity); - header.properties = Shared::PlatformByteOrder::toCommonEndian(header.properties); - header.textures = Shared::PlatformByteOrder::toCommonEndian(header.textures); - } -} - -void fromEndianMeshHeader(MeshHeader &header) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - for(unsigned int i = 0; i < meshNameSize; ++i) { - header.name[i] = Shared::PlatformByteOrder::fromCommonEndian(header.name[i]); - } - header.frameCount = Shared::PlatformByteOrder::fromCommonEndian(header.frameCount); - header.vertexCount = Shared::PlatformByteOrder::fromCommonEndian(header.vertexCount); - header.indexCount = Shared::PlatformByteOrder::fromCommonEndian(header.indexCount); - for(unsigned int i = 0; i < 3; ++i) { - header.diffuseColor[i] = Shared::PlatformByteOrder::fromCommonEndian(header.diffuseColor[i]); - header.specularColor[i] = Shared::PlatformByteOrder::fromCommonEndian(header.specularColor[i]); - } - header.specularPower = Shared::PlatformByteOrder::fromCommonEndian(header.specularPower); - header.opacity = Shared::PlatformByteOrder::fromCommonEndian(header.opacity); - header.properties = Shared::PlatformByteOrder::fromCommonEndian(header.properties); - header.textures = Shared::PlatformByteOrder::fromCommonEndian(header.textures); - } -} - -void toEndianModelHeaderV3(ModelHeaderV3 &header) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - header.meshCount = Shared::PlatformByteOrder::toCommonEndian(header.meshCount); - } -} -void fromEndianModelHeaderV3(ModelHeaderV3 &header) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - header.meshCount = Shared::PlatformByteOrder::fromCommonEndian(header.meshCount); - } -} - -void toEndianMeshHeaderV3(MeshHeaderV3 &header) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - header.vertexFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.vertexFrameCount); - header.normalFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.normalFrameCount); - header.texCoordFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.texCoordFrameCount); - header.colorFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.colorFrameCount); - header.pointCount = Shared::PlatformByteOrder::toCommonEndian(header.pointCount); - header.indexCount = Shared::PlatformByteOrder::toCommonEndian(header.indexCount); - header.properties = Shared::PlatformByteOrder::toCommonEndian(header.properties); - for(unsigned int i = 0; i < 64; ++i) { - header.texName[i] = Shared::PlatformByteOrder::toCommonEndian(header.texName[i]); - } - } -} - -void fromEndianMeshHeaderV3(MeshHeaderV3 &header) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - header.vertexFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.vertexFrameCount); - header.normalFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.normalFrameCount); - header.texCoordFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.texCoordFrameCount); - header.colorFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.colorFrameCount); - header.pointCount = Shared::PlatformByteOrder::fromCommonEndian(header.pointCount); - header.indexCount = Shared::PlatformByteOrder::fromCommonEndian(header.indexCount); - header.properties = Shared::PlatformByteOrder::fromCommonEndian(header.properties); - for(unsigned int i = 0; i < 64; ++i) { - header.texName[i] = Shared::PlatformByteOrder::fromCommonEndian(header.texName[i]); - } - } -} - -void toEndianMeshHeaderV2(MeshHeaderV2 &header) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - header.vertexFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.vertexFrameCount); - header.normalFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.normalFrameCount); - header.texCoordFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.texCoordFrameCount); - header.colorFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.colorFrameCount); - header.pointCount = Shared::PlatformByteOrder::toCommonEndian(header.pointCount); - header.indexCount = Shared::PlatformByteOrder::toCommonEndian(header.indexCount); - header.hasTexture = Shared::PlatformByteOrder::toCommonEndian(header.hasTexture); - header.primitive = Shared::PlatformByteOrder::toCommonEndian(header.primitive); - header.cullFace = Shared::PlatformByteOrder::toCommonEndian(header.cullFace); - - for(unsigned int i = 0; i < 64; ++i) { - header.texName[i] = Shared::PlatformByteOrder::toCommonEndian(header.texName[i]); - } - } -} - -void fromEndianMeshHeaderV2(MeshHeaderV2 &header) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - header.vertexFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.vertexFrameCount); - header.normalFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.normalFrameCount); - header.texCoordFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.texCoordFrameCount); - header.colorFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.colorFrameCount); - header.pointCount = Shared::PlatformByteOrder::fromCommonEndian(header.pointCount); - header.indexCount = Shared::PlatformByteOrder::fromCommonEndian(header.indexCount); - header.hasTexture = Shared::PlatformByteOrder::fromCommonEndian(header.hasTexture); - header.primitive = Shared::PlatformByteOrder::fromCommonEndian(header.primitive); - header.cullFace = Shared::PlatformByteOrder::fromCommonEndian(header.cullFace); - - for(unsigned int i = 0; i < 64; ++i) { - header.texName[i] = Shared::PlatformByteOrder::fromCommonEndian(header.texName[i]); - } - } -} - -// ===================================================== -// class Mesh -// ===================================================== - -// ==================== constructor & destructor ==================== - -Mesh::Mesh() { - textureManager = NULL; - frameCount= 0; - vertexCount= 0; - indexCount= 0; - texCoordFrameCount = 0; - opacity = 0.0f; - specularPower = 0.0f; - - vertices= NULL; - normals= NULL; - texCoords= NULL; - tangents= NULL; - indices= NULL; - interpolationData= NULL; - - for(int i=0; igetPath().c_str(),i); - textureManager->endTexture(textures[i]); - textures[i] = NULL; + // Utils methods for endianness conversion + void toEndianFileHeader(FileHeader &header) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + for (unsigned int i = 0; i < 3; ++i) { + header.id[i] = Shared::PlatformByteOrder::toCommonEndian(header.id[i]); + } + header.version = Shared::PlatformByteOrder::toCommonEndian(header.version); + } + } + void fromEndianFileHeader(FileHeader &header) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + for (unsigned int i = 0; i < 3; ++i) { + header.id[i] = Shared::PlatformByteOrder::fromCommonEndian(header.id[i]); + } + header.version = Shared::PlatformByteOrder::fromCommonEndian(header.version); } } - } - textureManager = NULL; -} -// ========================== shadows & interpolation ========================= + void toEndianModelHeader(ModelHeader &header) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + header.type = Shared::PlatformByteOrder::toCommonEndian(header.type); + header.meshCount = Shared::PlatformByteOrder::toCommonEndian(header.meshCount); + } + } + void fromEndianModelHeader(ModelHeader &header) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + header.type = Shared::PlatformByteOrder::toCommonEndian(header.type); + header.meshCount = Shared::PlatformByteOrder::toCommonEndian(header.meshCount); + } + } -void Mesh::buildInterpolationData(){ - if(interpolationData != NULL) { - printf("**WARNING possible memory leak [Mesh::buildInterpolationData()]\n"); - } - interpolationData= new InterpolationData(this); -} + void toEndianMeshHeader(MeshHeader &header) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + for (unsigned int i = 0; i < meshNameSize; ++i) { + header.name[i] = Shared::PlatformByteOrder::toCommonEndian(header.name[i]); + } + header.frameCount = Shared::PlatformByteOrder::toCommonEndian(header.frameCount); + header.vertexCount = Shared::PlatformByteOrder::toCommonEndian(header.vertexCount); + header.indexCount = Shared::PlatformByteOrder::toCommonEndian(header.indexCount); + for (unsigned int i = 0; i < 3; ++i) { + header.diffuseColor[i] = Shared::PlatformByteOrder::toCommonEndian(header.diffuseColor[i]); + header.specularColor[i] = Shared::PlatformByteOrder::toCommonEndian(header.specularColor[i]); + } + header.specularPower = Shared::PlatformByteOrder::toCommonEndian(header.specularPower); + header.opacity = Shared::PlatformByteOrder::toCommonEndian(header.opacity); + header.properties = Shared::PlatformByteOrder::toCommonEndian(header.properties); + header.textures = Shared::PlatformByteOrder::toCommonEndian(header.textures); + } + } -void Mesh::cleanupInterpolationData() { - delete interpolationData; - interpolationData=NULL; -} + void fromEndianMeshHeader(MeshHeader &header) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + for (unsigned int i = 0; i < meshNameSize; ++i) { + header.name[i] = Shared::PlatformByteOrder::fromCommonEndian(header.name[i]); + } + header.frameCount = Shared::PlatformByteOrder::fromCommonEndian(header.frameCount); + header.vertexCount = Shared::PlatformByteOrder::fromCommonEndian(header.vertexCount); + header.indexCount = Shared::PlatformByteOrder::fromCommonEndian(header.indexCount); + for (unsigned int i = 0; i < 3; ++i) { + header.diffuseColor[i] = Shared::PlatformByteOrder::fromCommonEndian(header.diffuseColor[i]); + header.specularColor[i] = Shared::PlatformByteOrder::fromCommonEndian(header.specularColor[i]); + } + header.specularPower = Shared::PlatformByteOrder::fromCommonEndian(header.specularPower); + header.opacity = Shared::PlatformByteOrder::fromCommonEndian(header.opacity); + header.properties = Shared::PlatformByteOrder::fromCommonEndian(header.properties); + header.textures = Shared::PlatformByteOrder::fromCommonEndian(header.textures); + } + } -void Mesh::updateInterpolationData(float t, bool cycle) { - if(interpolationData != NULL) { - interpolationData->update(t, cycle); - } -} + void toEndianModelHeaderV3(ModelHeaderV3 &header) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + header.meshCount = Shared::PlatformByteOrder::toCommonEndian(header.meshCount); + } + } + void fromEndianModelHeaderV3(ModelHeaderV3 &header) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + header.meshCount = Shared::PlatformByteOrder::fromCommonEndian(header.meshCount); + } + } -void Mesh::updateInterpolationVertices(float t, bool cycle) { - if(interpolationData != NULL) { - interpolationData->updateVertices(t, cycle); - } -} + void toEndianMeshHeaderV3(MeshHeaderV3 &header) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + header.vertexFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.vertexFrameCount); + header.normalFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.normalFrameCount); + header.texCoordFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.texCoordFrameCount); + header.colorFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.colorFrameCount); + header.pointCount = Shared::PlatformByteOrder::toCommonEndian(header.pointCount); + header.indexCount = Shared::PlatformByteOrder::toCommonEndian(header.indexCount); + header.properties = Shared::PlatformByteOrder::toCommonEndian(header.properties); + for (unsigned int i = 0; i < 64; ++i) { + header.texName[i] = Shared::PlatformByteOrder::toCommonEndian(header.texName[i]); + } + } + } -void Mesh::BuildVBOs() { - if(getVBOSupported() == true) { - if(hasBuiltVBOs == false) { - //printf("In [%s::%s Line: %d] setting up a VBO...\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + void fromEndianMeshHeaderV3(MeshHeaderV3 &header) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + header.vertexFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.vertexFrameCount); + header.normalFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.normalFrameCount); + header.texCoordFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.texCoordFrameCount); + header.colorFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.colorFrameCount); + header.pointCount = Shared::PlatformByteOrder::fromCommonEndian(header.pointCount); + header.indexCount = Shared::PlatformByteOrder::fromCommonEndian(header.indexCount); + header.properties = Shared::PlatformByteOrder::fromCommonEndian(header.properties); + for (unsigned int i = 0; i < 64; ++i) { + header.texName[i] = Shared::PlatformByteOrder::fromCommonEndian(header.texName[i]); + } + } + } - // Generate And Bind The Vertex Buffer - glGenBuffersARB( 1,(GLuint*) &m_nVBOVertices ); // Get A Valid Name - glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_nVBOVertices ); // Bind The Buffer - // Load The Data - glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec3f)*frameCount*vertexCount, vertices, GL_STATIC_DRAW_ARB ); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + void toEndianMeshHeaderV2(MeshHeaderV2 &header) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + header.vertexFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.vertexFrameCount); + header.normalFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.normalFrameCount); + header.texCoordFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.texCoordFrameCount); + header.colorFrameCount = Shared::PlatformByteOrder::toCommonEndian(header.colorFrameCount); + header.pointCount = Shared::PlatformByteOrder::toCommonEndian(header.pointCount); + header.indexCount = Shared::PlatformByteOrder::toCommonEndian(header.indexCount); + header.hasTexture = Shared::PlatformByteOrder::toCommonEndian(header.hasTexture); + header.primitive = Shared::PlatformByteOrder::toCommonEndian(header.primitive); + header.cullFace = Shared::PlatformByteOrder::toCommonEndian(header.cullFace); - // Generate And Bind The Texture Coordinate Buffer - glGenBuffersARB( 1, (GLuint*)&m_nVBOTexCoords ); // Get A Valid Name - glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_nVBOTexCoords ); // Bind The Buffer - // Load The Data - glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec2f)*vertexCount, texCoords, GL_STATIC_DRAW_ARB ); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + for (unsigned int i = 0; i < 64; ++i) { + header.texName[i] = Shared::PlatformByteOrder::toCommonEndian(header.texName[i]); + } + } + } - // Generate And Bind The Normal Buffer - glGenBuffersARB( 1, (GLuint*)&m_nVBONormals ); // Get A Valid Name - glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_nVBONormals ); // Bind The Buffer - // Load The Data - glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(Vec3f)*frameCount*vertexCount, normals, GL_STATIC_DRAW_ARB ); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + void fromEndianMeshHeaderV2(MeshHeaderV2 &header) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + header.vertexFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.vertexFrameCount); + header.normalFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.normalFrameCount); + header.texCoordFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.texCoordFrameCount); + header.colorFrameCount = Shared::PlatformByteOrder::fromCommonEndian(header.colorFrameCount); + header.pointCount = Shared::PlatformByteOrder::fromCommonEndian(header.pointCount); + header.indexCount = Shared::PlatformByteOrder::fromCommonEndian(header.indexCount); + header.hasTexture = Shared::PlatformByteOrder::fromCommonEndian(header.hasTexture); + header.primitive = Shared::PlatformByteOrder::fromCommonEndian(header.primitive); + header.cullFace = Shared::PlatformByteOrder::fromCommonEndian(header.cullFace); - // Generate And Bind The Index Buffer - glGenBuffersARB( 1, (GLuint*)&m_nVBOIndexes ); // Get A Valid Name - glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, m_nVBOIndexes ); // Bind The Buffer - // Load The Data - glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(uint32)*indexCount, indices, GL_STATIC_DRAW_ARB ); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + for (unsigned int i = 0; i < 64; ++i) { + header.texName[i] = Shared::PlatformByteOrder::fromCommonEndian(header.texName[i]); + } + } + } - // Our Copy Of The Data Is No Longer Necessary, It Is Safe In The Graphics Card - delete [] vertices; vertices = NULL; - delete [] texCoords; texCoords = NULL; - delete [] normals; normals = NULL; - delete [] indices; indices = NULL; + // ===================================================== + // class Mesh + // ===================================================== - delete interpolationData; + // ==================== constructor & destructor ==================== + + Mesh::Mesh() { + textureManager = NULL; + frameCount = 0; + vertexCount = 0; + indexCount = 0; + texCoordFrameCount = 0; + opacity = 0.0f; + specularPower = 0.0f; + + vertices = NULL; + normals = NULL; + texCoords = NULL; + tangents = NULL; + indices = NULL; interpolationData = NULL; - hasBuiltVBOs = true; - } - } -} + for (int i = 0; i < meshTextureCount; ++i) { + textures[i] = NULL; + texturesOwned[i] = false; + } + + twoSided = false; + customColor = false; + noSelect = false; + glow = false; + + textureFlags = 0; -void Mesh::ReleaseVBOs() { - if(getVBOSupported() == true) { - if(hasBuiltVBOs == true) { - glDeleteBuffersARB( 1, (GLuint*)&m_nVBOVertices ); // Get A Valid Name - glDeleteBuffersARB( 1, (GLuint*)&m_nVBOTexCoords ); // Get A Valid Name - glDeleteBuffersARB( 1, (GLuint*)&m_nVBONormals ); // Get A Valid Name - glDeleteBuffersARB( 1, (GLuint*)&m_nVBOIndexes ); // Get A Valid Name hasBuiltVBOs = false; - } - } -} - -// ==================== load ==================== - -string Mesh::findAlternateTexture(vector conversionList, string textureFile) { - string result = textureFile; - string fileExt = extractExtension(textureFile); - - for(unsigned int i = 0; i < conversionList.size(); ++i) { - string convertTo = conversionList[i]; - if(fileExt != convertTo) { - string alternateTexture = textureFile; - replaceAll(alternateTexture, "." + fileExt, "." + convertTo); - if(fileExists(alternateTexture) == true) { - result = alternateTexture; - break; - } - } - } - return result; -} - -void Mesh::loadV2(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager, - bool deletePixMapAfterLoad, std::map > > *loadedFileList, - string sourceLoader,string modelFile) { - this->textureManager = textureManager; - //read header - MeshHeaderV2 meshHeader; - size_t readBytes = fread(&meshHeader, sizeof(MeshHeaderV2), 1, f); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - fromEndianMeshHeaderV2(meshHeader); - - if(meshHeader.normalFrameCount != meshHeader.vertexFrameCount) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Old v2 model: vertex frame count different from normal frame count [v = %d, n = %d] meshIndex = %d modelFile [%s]",meshHeader.vertexFrameCount,meshHeader.normalFrameCount,meshIndex,modelFile.c_str()); - throw megaglest_runtime_error(szBuf,true); - } - - if(meshHeader.texCoordFrameCount != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Old v2 model: texture coord frame count is not 1 [t = %d] meshIndex = %d modelFile [%s]",meshHeader.texCoordFrameCount,meshIndex,modelFile.c_str()); - throw megaglest_runtime_error(szBuf,true); - } - - //init - frameCount= meshHeader.vertexFrameCount; - vertexCount= meshHeader.pointCount; - indexCount= meshHeader.indexCount; - texCoordFrameCount = meshHeader.texCoordFrameCount; - - init(); - - //misc - twoSided= false; - customColor= false; - noSelect= false; - glow= false; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Load v2, this = %p Found meshHeader.hasTexture = %d, texName [%s] mtDiffuse = %d meshIndex = %d modelFile [%s]\n",this,meshHeader.hasTexture,toLower(reinterpret_cast(meshHeader.texName)).c_str(),mtDiffuse,meshIndex,modelFile.c_str()); - - textureFlags= 0; - if(meshHeader.hasTexture) { - textureFlags= 1; - } - - //texture - if(meshHeader.hasTexture && textureManager!=NULL){ - texturePaths[mtDiffuse]= toLower(reinterpret_cast(meshHeader.texName)); - string texPath= dir; - if(texPath != "") { - endPathWithSlash(texPath); - } - texPath += texturePaths[mtDiffuse]; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] v2 model texture [%s] meshIndex = %d modelFile [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,texPath.c_str(),meshIndex,modelFile.c_str()); - - textures[mtDiffuse]= dynamic_cast(textureManager->getTexture(texPath)); - if(textures[mtDiffuse] == NULL) { - if(fileExists(texPath) == false) { - vector conversionList; - conversionList.push_back("png"); - conversionList.push_back("jpg"); - conversionList.push_back("tga"); - conversionList.push_back("bmp"); - texPath = findAlternateTexture(conversionList, texPath); - } - if(fileExists(texPath) == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] v2 model texture [%s] meshIndex = %d modelFile [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,texPath.c_str(),meshIndex,modelFile.c_str()); - - textures[mtDiffuse]= textureManager->newTexture2D(); - textures[mtDiffuse]->load(texPath); - if(loadedFileList) { - (*loadedFileList)[texPath].push_back(make_pair(sourceLoader,sourceLoader)); - } - texturesOwned[mtDiffuse]=true; - textures[mtDiffuse]->init(textureManager->getTextureFilter(),textureManager->getMaxAnisotropy()); - if(deletePixMapAfterLoad == true) { - textures[mtDiffuse]->deletePixels(); - } - } - else { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error v2 model is missing texture [%s] meshIndex = %d modelFile [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,texPath.c_str(),meshIndex,modelFile.c_str()); - } - } - } - - //read data - readBytes = fread(vertices, sizeof(Vec3f)*frameCount*vertexCount, 1, f); - if(readBytes != 1 && (frameCount * vertexCount) != 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.",readBytes,frameCount,vertexCount,__LINE__); - throw megaglest_runtime_error(szBuf); - } - fromEndianVecArray(vertices, frameCount*vertexCount); - - readBytes = fread(normals, sizeof(Vec3f)*frameCount*vertexCount, 1, f); - if(readBytes != 1 && (frameCount * vertexCount) != 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.",readBytes,frameCount,vertexCount,__LINE__); - throw megaglest_runtime_error(szBuf); - } - fromEndianVecArray(normals, frameCount*vertexCount); - - if(textureFlags & (1<(texCoords, vertexCount); - } - readBytes = fread(&diffuseColor, sizeof(Vec3f), 1, f); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - fromEndianVecArray(&diffuseColor, 1); - - readBytes = fread(&opacity, sizeof(float32), 1, f); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - opacity = Shared::PlatformByteOrder::fromCommonEndian(opacity); - - int seek_result = fseek(f, sizeof(Vec4f)*(meshHeader.colorFrameCount-1), SEEK_CUR); - if(seek_result != 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fseek returned failure = %d [%u] on line: %d.",seek_result,indexCount,__LINE__); - throw megaglest_runtime_error(szBuf); - } - readBytes = fread(indices, sizeof(uint32)*indexCount, 1, f); - if(readBytes != 1 && indexCount != 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u] on line: %d.",readBytes,indexCount,__LINE__); - throw megaglest_runtime_error(szBuf); - } - Shared::PlatformByteOrder::fromEndianTypeArray(indices, indexCount); -} - -void Mesh::loadV3(int meshIndex, const string &dir, FILE *f, - TextureManager *textureManager,bool deletePixMapAfterLoad, - std::map > > *loadedFileList, - string sourceLoader,string modelFile) { - this->textureManager = textureManager; - - //read header - MeshHeaderV3 meshHeader; - size_t readBytes = fread(&meshHeader, sizeof(MeshHeaderV3), 1, f); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - fromEndianMeshHeaderV3(meshHeader); - - if(meshHeader.normalFrameCount != meshHeader.vertexFrameCount) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Old v3 model: vertex frame count different from normal frame count [v = %d, n = %d] meshIndex = %d modelFile [%s]",meshHeader.vertexFrameCount,meshHeader.normalFrameCount,meshIndex,modelFile.c_str()); - throw megaglest_runtime_error(szBuf,true); - } - - //init - frameCount= meshHeader.vertexFrameCount; - vertexCount= meshHeader.pointCount; - indexCount= meshHeader.indexCount; - texCoordFrameCount = meshHeader.texCoordFrameCount; - - init(); - - //misc - twoSided= (meshHeader.properties & mp3TwoSided) != 0; - customColor= (meshHeader.properties & mp3CustomColor) != 0; - noSelect = false; - glow = false; - - textureFlags= 0; - if((meshHeader.properties & mp3NoTexture) != mp3NoTexture) { - textureFlags= 1; - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Load v3, this = %p Found meshHeader.properties = %d, textureFlags = %d, texName [%s] mtDiffuse = %d meshIndex = %d modelFile [%s]\n",this,meshHeader.properties,textureFlags,toLower(reinterpret_cast(meshHeader.texName)).c_str(),mtDiffuse,meshIndex,modelFile.c_str()); - - //texture - if((meshHeader.properties & mp3NoTexture) != mp3NoTexture && textureManager!=NULL){ - texturePaths[mtDiffuse]= toLower(reinterpret_cast(meshHeader.texName)); - - string texPath= dir; - if(texPath != "") { - endPathWithSlash(texPath); - } - texPath += texturePaths[mtDiffuse]; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] v3 model texture [%s] meshIndex = %d modelFile [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,texPath.c_str(),meshIndex,modelFile.c_str()); - - textures[mtDiffuse]= dynamic_cast(textureManager->getTexture(texPath)); - if(textures[mtDiffuse] == NULL) { - if(fileExists(texPath) == false) { - vector conversionList; - conversionList.push_back("png"); - conversionList.push_back("jpg"); - conversionList.push_back("tga"); - conversionList.push_back("bmp"); - texPath = findAlternateTexture(conversionList, texPath); - } - - if(fileExists(texPath) == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] v3 model texture [%s] meshIndex = %d modelFile [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,texPath.c_str(),meshIndex,modelFile.c_str()); - - textures[mtDiffuse]= textureManager->newTexture2D(); - textures[mtDiffuse]->load(texPath); - if(loadedFileList) { - (*loadedFileList)[texPath].push_back(make_pair(sourceLoader,sourceLoader)); - } - - texturesOwned[mtDiffuse]=true; - textures[mtDiffuse]->init(textureManager->getTextureFilter(),textureManager->getMaxAnisotropy()); - if(deletePixMapAfterLoad == true) { - textures[mtDiffuse]->deletePixels(); - } - } - else { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error v3 model is missing texture [%s] meshHeader.properties = %d meshIndex = %d modelFile [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,texPath.c_str(),meshHeader.properties,meshIndex,modelFile.c_str()); - } - } - } - - //read data - readBytes = fread(vertices, sizeof(Vec3f)*frameCount*vertexCount, 1, f); - if(readBytes != 1 && (frameCount * vertexCount) != 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.",readBytes,frameCount,vertexCount,__LINE__); - throw megaglest_runtime_error(szBuf); - } - fromEndianVecArray(vertices, frameCount*vertexCount); - - readBytes = fread(normals, sizeof(Vec3f)*frameCount*vertexCount, 1, f); - if(readBytes != 1 && (frameCount * vertexCount) != 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.",readBytes,frameCount,vertexCount,__LINE__); - throw megaglest_runtime_error(szBuf); - } - fromEndianVecArray(normals, frameCount*vertexCount); - - if(textureFlags & (1<(texCoords, vertexCount); - } - } - readBytes = fread(&diffuseColor, sizeof(Vec3f), 1, f); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - fromEndianVecArray(&diffuseColor, 1); - - readBytes = fread(&opacity, sizeof(float32), 1, f); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - opacity = Shared::PlatformByteOrder::fromCommonEndian(opacity); - - int seek_result = fseek(f, sizeof(Vec4f)*(meshHeader.colorFrameCount-1), SEEK_CUR); - if(seek_result != 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fseek returned failure = %d [%u] on line: %d.",seek_result,indexCount,__LINE__); - throw megaglest_runtime_error(szBuf); - } - - readBytes = fread(indices, sizeof(uint32)*indexCount, 1, f); - if(readBytes != 1 && indexCount != 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u] on line: %d.",readBytes,indexCount,__LINE__); - throw megaglest_runtime_error(szBuf); - } - Shared::PlatformByteOrder::fromEndianTypeArray(indices, indexCount); -} - -Texture2D* Mesh::loadMeshTexture(int meshIndex, int textureIndex, - TextureManager *textureManager, string textureFile, - int textureChannelCount, bool &textureOwned, bool deletePixMapAfterLoad, - std::map > > *loadedFileList, - string sourceLoader,string modelFile) { - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] #1 load texture [%s] modelFile [%s]\n",__FUNCTION__,textureFile.c_str(),modelFile.c_str()); - - Texture2D* texture = dynamic_cast(textureManager->getTexture(textureFile)); - if(texture == NULL) { - if(fileExists(textureFile) == false) { - vector conversionList; - conversionList.push_back("png"); - conversionList.push_back("jpg"); - conversionList.push_back("tga"); - conversionList.push_back("bmp"); - textureFile = findAlternateTexture(conversionList, textureFile); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] #2 load texture [%s]\n",__FUNCTION__,textureFile.c_str()); + // Vertex Buffer Object Names + m_nVBOVertices = 0; + m_nVBOTexCoords = 0; + m_nVBONormals = 0; + m_nVBOIndexes = 0; } - if(fileExists(textureFile) == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] #3 load texture [%s] modelFile [%s]\n",__FUNCTION__,textureFile.c_str(),modelFile.c_str()); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] texture exists loading [%s]\n",__FUNCTION__,textureFile.c_str()); - - texture = textureManager->newTexture2D(); - if(textureChannelCount != -1) { - texture->getPixmap()->init(textureChannelCount); - } - texture->load(textureFile); - if(loadedFileList) { - (*loadedFileList)[textureFile].push_back(make_pair(sourceLoader,sourceLoader)); - } - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] texture loaded [%s]\n",__FUNCTION__,textureFile.c_str()); - - textureOwned = true; - texture->init(textureManager->getTextureFilter(),textureManager->getMaxAnisotropy()); - if(deletePixMapAfterLoad == true) { - texture->deletePixels(); - } - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] texture inited [%s]\n",__FUNCTION__,textureFile.c_str()); - } - else { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] #3 cannot load texture [%s] modelFile [%s]\n",__FUNCTION__,textureFile.c_str(),modelFile.c_str()); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error v4 model is missing texture [%s] textureFlags = %d meshIndex = %d textureIndex = %d modelFile [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,textureFile.c_str(),textureFlags,meshIndex,textureIndex,modelFile.c_str()); - } - } - - return texture; -} - -void Mesh::load(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager, - bool deletePixMapAfterLoad,std::map > > *loadedFileList, - string sourceLoader,string modelFile) { - this->textureManager = textureManager; - - //read header - MeshHeader meshHeader; - size_t readBytes = fread(&meshHeader, sizeof(MeshHeader), 1, f); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - fromEndianMeshHeader(meshHeader); - - name = reinterpret_cast(meshHeader.name); - - //printf("Load, Found meshTextureCount = %d, meshHeader.textures = %d\n",meshTextureCount,meshHeader.textures); - - //init - frameCount= meshHeader.frameCount; - vertexCount= meshHeader.vertexCount; - indexCount= meshHeader.indexCount; - - init(); - - //properties - customColor= (meshHeader.properties & mpfCustomColor) != 0; - twoSided= (meshHeader.properties & mpfTwoSided) != 0; - noSelect= (meshHeader.properties & mpfNoSelect) != 0; - glow= (meshHeader.properties & mpfGlow) != 0; - - //material - diffuseColor= Vec3f(meshHeader.diffuseColor); - specularColor= Vec3f(meshHeader.specularColor); - specularPower= meshHeader.specularPower; - opacity= meshHeader.opacity; - if(opacity==0){ - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("found a mesh with opacity=0 in header, using opacity=1 to see it now \n"); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("file: %s\n",modelFile.c_str()); - opacity=1.0f; - } - textureFlags= meshHeader.textures; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Load v4, this = %p Found meshHeader.textures = %d meshIndex = %d\n",this,meshHeader.textures,meshIndex); - - //maps - uint32 flag= 1; - for(int i = 0; i < meshTextureCount; ++i) { - if(meshHeader.textures & flag) { - uint8 cMapPath[mapPathSize+1]; - memset(&cMapPath[0],0,mapPathSize+1); - readBytes = fread(cMapPath, mapPathSize, 1, f); - cMapPath[mapPathSize] = 0; - if(readBytes != 1 && mapPathSize != 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u] on line: %d.",readBytes,mapPathSize,__LINE__); - throw megaglest_runtime_error(szBuf); - } - Shared::PlatformByteOrder::fromEndianTypeArray(cMapPath, mapPathSize); - - char mapPathString[mapPathSize+1]=""; - memset(&mapPathString[0],0,mapPathSize+1); - memcpy(&mapPathString[0],reinterpret_cast(cMapPath),mapPathSize); - string mapPath= toLower(mapPathString); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("mapPath [%s] meshHeader.textures = %d flag = %d (meshHeader.textures & flag) = %d meshIndex = %d i = %d\n",mapPath.c_str(),meshHeader.textures,flag,(meshHeader.textures & flag),meshIndex,i); - - string mapFullPath= dir; - if(mapFullPath != "") { - endPathWithSlash(mapFullPath); - } - mapFullPath += mapPath; - if(textureManager) { - textures[i] = loadMeshTexture(meshIndex, i, textureManager, mapFullPath, - meshTextureChannelCount[i],texturesOwned[i], - deletePixMapAfterLoad, loadedFileList, sourceLoader,modelFile); - } - } - flag *= 2; - } - - //read data - readBytes = fread(vertices, sizeof(Vec3f)*frameCount*vertexCount, 1, f); - if(readBytes != 1 && (frameCount * vertexCount) != 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.",readBytes,frameCount,vertexCount,__LINE__); - throw megaglest_runtime_error(szBuf); - } - fromEndianVecArray(vertices, frameCount*vertexCount); - - readBytes = fread(normals, sizeof(Vec3f)*frameCount*vertexCount, 1, f); - if(readBytes != 1 && (frameCount * vertexCount) != 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.",readBytes,frameCount,vertexCount,__LINE__); - throw megaglest_runtime_error(szBuf); - } - fromEndianVecArray(normals, frameCount*vertexCount); - - if(meshHeader.textures!=0){ - readBytes = fread(texCoords, sizeof(Vec2f)*vertexCount, 1, f); - if(readBytes != 1 && vertexCount != 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.",readBytes,frameCount,vertexCount,__LINE__); - throw megaglest_runtime_error(szBuf); - } - fromEndianVecArray(texCoords, vertexCount); - } - readBytes = fread(indices, sizeof(uint32)*indexCount, 1, f); - if(readBytes != 1 && indexCount != 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u] on line: %d.",readBytes,indexCount,__LINE__); - throw megaglest_runtime_error(szBuf); - } - Shared::PlatformByteOrder::fromEndianTypeArray(indices, indexCount); - - //tangents - if(textures[mtNormal]!=NULL){ - computeTangents(); - } -} - -void Mesh::save(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager, - string convertTextureToFormat, std::map &textureDeleteList, - bool keepsmallest,string modelFile) { - MeshHeader meshHeader; - memset(&meshHeader, 0, sizeof(struct MeshHeader)); - - strncpy((char*)meshHeader.name, (char*)name.c_str(), name.length()); - meshHeader.frameCount= frameCount; - meshHeader.vertexCount= vertexCount; - meshHeader.indexCount = indexCount; - - //material - memcpy((float32*)meshHeader.diffuseColor, (float32*)diffuseColor.ptr(), sizeof(float32) * 3); - memcpy((float32*)meshHeader.specularColor, (float32*)specularColor.ptr(), sizeof(float32) * 3); - meshHeader.specularPower = specularPower; - meshHeader.opacity = opacity; - - //properties - meshHeader.properties = 0; - if(customColor) { - meshHeader.properties |= mpfCustomColor; - } - if(twoSided) { - meshHeader.properties |= mpfTwoSided; - } - if(noSelect) { - meshHeader.properties |= mpfNoSelect; - } - if(glow) { - meshHeader.properties |= mpfGlow; - } - - meshHeader.textures = textureFlags; - fwrite(&meshHeader, sizeof(MeshHeader), 1, f); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Save, this = %p, Found meshTextureCount = %d, meshHeader.textures = %d meshIndex = %d\n",this,meshTextureCount,meshHeader.textures,meshIndex); - - //maps - uint32 flag= 1; - for(int i = 0; i < meshTextureCount; ++i) { - if((meshHeader.textures & flag)) { - uint8 cMapPath[mapPathSize]; - memset(&cMapPath[0],0,mapPathSize); - - Texture2D *texture = textures[i]; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Save, [%d] mesh texture ptr [%p]\n",i,texture); - - if(texture != NULL) { - string file = toLower(texture->getPath()); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Save, Found mesh texture [%s]\n",file.c_str()); - - if(toLower(convertTextureToFormat) != "" && - EndsWith(file, "." + convertTextureToFormat) == false) { - long originalSize = getFileSize(file); - long newSize = originalSize; - - string fileExt = extractExtension(file); - replaceAll(file, "." + fileExt, "." + convertTextureToFormat); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Save, Convert from [%s] to [%s]\n",texture->getPath().c_str(),file.c_str()); - - if(convertTextureToFormat == "tga") { - texture->getPixmap()->saveTga(file); - newSize = getFileSize(file); - if(keepsmallest == false || newSize <= originalSize) { - textureDeleteList[texture->getPath()] = textureDeleteList[texture->getPath()] + 1; - } - else { - printf("Texture will not be converted, keeping smallest texture [%s]\n",texture->getPath().c_str()); - textureDeleteList[file] = textureDeleteList[file] + 1; - } - } - else if(convertTextureToFormat == "bmp") { - texture->getPixmap()->saveBmp(file); - newSize = getFileSize(file); - if(keepsmallest == false || newSize <= originalSize) { - textureDeleteList[texture->getPath()] = textureDeleteList[texture->getPath()] + 1; - } - else { - printf("Texture will not be converted, keeping smallest texture [%s]\n",texture->getPath().c_str()); - textureDeleteList[file] = textureDeleteList[file] + 1; - } - } - else if(convertTextureToFormat == "jpg") { - texture->getPixmap()->saveJpg(file); - newSize = getFileSize(file); - if(keepsmallest == false || newSize <= originalSize) { - textureDeleteList[texture->getPath()] = textureDeleteList[texture->getPath()] + 1; - } - else { - printf("Texture will not be converted, keeping smallest texture [%s]\n",texture->getPath().c_str()); - textureDeleteList[file] = textureDeleteList[file] + 1; - } - } - else if(convertTextureToFormat == "png") { - texture->getPixmap()->savePng(file); - newSize = getFileSize(file); - if(keepsmallest == false || newSize <= originalSize) { - textureDeleteList[texture->getPath()] = textureDeleteList[texture->getPath()] + 1; - } - else { - printf("Texture will not be converted, keeping smallest texture [%s]\n",texture->getPath().c_str()); - textureDeleteList[file] = textureDeleteList[file] + 1; - } - } - else { - throw megaglest_runtime_error("Unsupported texture format: [" + convertTextureToFormat + "]"); - } - - //textureManager->endTexture(texture); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Save, load new texture [%s] originalSize [%ld] newSize [%ld]\n",file.c_str(),originalSize,newSize); - - if(keepsmallest == false || newSize <= originalSize) { - texture = loadMeshTexture(meshIndex, i, textureManager,file, - meshTextureChannelCount[i], - texturesOwned[i], - false, - NULL, - "", - modelFile); - } - } - - file = extractFileFromDirectoryPath(texture->getPath()); - - if(file.length() > mapPathSize) { - throw megaglest_runtime_error("file.length() > mapPathSize, file.length() = " + intToStr(file.length())); - } - else if(file.length() == 0) { - throw megaglest_runtime_error("file.length() == 0"); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Save, new texture file [%s]\n",file.c_str()); - - memset(&cMapPath[0],0,mapPathSize); - memcpy(&cMapPath[0],file.c_str(),file.length()); - } - - fwrite(cMapPath, mapPathSize, 1, f); - } - flag*= 2; - } - - //read data - fwrite(vertices, sizeof(Vec3f)*frameCount*vertexCount, 1, f); - fwrite(normals, sizeof(Vec3f)*frameCount*vertexCount, 1, f); - if(meshHeader.textures != 0) { - fwrite(texCoords, sizeof(Vec2f)*vertexCount, 1, f); - } - fwrite(indices, sizeof(uint32)*indexCount, 1, f); -} - -void Mesh::computeTangents(){ - delete [] tangents; - try { - tangents= new Vec3f[vertexCount]; - } - catch(bad_alloc& ba) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error on line: %d size: %d msg: %s\n",__LINE__,vertexCount,ba.what()); - throw megaglest_runtime_error(szBuf); - } - - for(unsigned int i=0; ideletePixels(); - } - } -} - -// =============================================== -// class Model -// =============================================== - -// ==================== constructor & destructor ==================== - -Model::Model() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - meshCount = 0; - meshes = NULL; - fileVersion = 0; - textureManager = NULL; - lastTData = -1; - lastCycleData = false; - lastTVertex = -1; - lastCycleVertex = false; -} - -Model::~Model() { - if(meshes) delete [] meshes; - meshes = NULL; -} - -// ==================== data ==================== - -void Model::buildInterpolationData() const{ - for(unsigned int i=0; i > > *loadedFileList, string *sourceLoader) { - - this->sourceLoader = (sourceLoader != NULL ? *sourceLoader : ""); - this->fileName = path; - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - size_t pos = path.find_last_of('.'); - string extension = toLower(path.empty() == false ? path.substr(pos + 1) : ""); - if(extension == "g3d") { - loadG3d(path,deletePixMapAfterLoad,loadedFileList, this->sourceLoader); - } - else { - throw megaglest_runtime_error("#1 Unknown model format [" + extension + "] file [" + path + "]"); - } -} - -void Model::save(const string &path, string convertTextureToFormat, - bool keepsmallest) { - string extension = (path.empty() == false ? path.substr(path.find_last_of('.')+1) : ""); - if(toLower(extension) == "g3d") { - saveG3d(path,convertTextureToFormat,keepsmallest); - } - else { - throw megaglest_runtime_error("#2 Unknown model format [" + extension + "] file [" + path + "]"); - } -} - -//load a model from a g3d file -void Model::loadG3d(const string &path, bool deletePixMapAfterLoad, - std::map > > *loadedFileList, - string sourceLoader) { - - try{ -#ifdef WIN32 - FILE *f= _wfopen(utf8_decode(path).c_str(), L"rb"); -#else - FILE *f=fopen(path.c_str(),"rb"); -#endif - if (f == NULL) { - printf("In [%s::%s] cannot load file = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,path.c_str()); - throw megaglest_runtime_error("Error opening g3d model file [" + path + "]",true); + Mesh::~Mesh() { + end(); } - if(loadedFileList) { - (*loadedFileList)[path].push_back(make_pair(sourceLoader,sourceLoader)); - } - - string dir= extractDirectoryPathFromFile(path); - - //file header - FileHeader fileHeader; - size_t readBytes = fread(&fileHeader, sizeof(FileHeader), 1, f); - if(readBytes != 1) { - fclose(f); - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - fromEndianFileHeader(fileHeader); - - char fileId[4] = ""; - memset(&fileId[0],0,4); - memcpy(&fileId[0],reinterpret_cast(fileHeader.id),3); - - if(strncmp(fileId, "G3D", 3) != 0) { - fclose(f); - f = NULL; - printf("In [%s::%s] file = [%s] fileheader.id = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,path.c_str(),fileId); - throw megaglest_runtime_error("Not a valid G3D model",true); - } - fileVersion= fileHeader.version; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Load model, fileVersion = %d\n",fileVersion); - - //version 4 - if(fileHeader.version == 4) { - //model header - ModelHeader modelHeader; - readBytes = fread(&modelHeader, sizeof(ModelHeader), 1, f); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - fromEndianModelHeader(modelHeader); - - meshCount= modelHeader.meshCount; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("meshCount = %d\n",meshCount); - - if(modelHeader.type != mtMorphMesh) { - throw megaglest_runtime_error("Invalid model type"); - } - - //load meshes + void Mesh::init() { try { - meshes= new Mesh[meshCount]; - } - catch(bad_alloc& ba) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error on line: %d size: %d msg: %s\n",__LINE__,meshCount,ba.what()); + vertices = new Vec3f[frameCount*vertexCount]; + } catch (bad_alloc& ba) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error on line: %d size: %d msg: %s\n", __LINE__, (frameCount*vertexCount), ba.what()); throw megaglest_runtime_error(szBuf); } - - for(uint32 i = 0; i < meshCount; ++i) { - meshes[i].load(i, dir, f, textureManager,deletePixMapAfterLoad, - loadedFileList,sourceLoader,path); - meshes[i].buildInterpolationData(); - } - } - //version 3 - else if(fileHeader.version == 3) { - readBytes = fread(&meshCount, sizeof(meshCount), 1, f); - if(readBytes != 1 && meshCount != 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u] on line: %d.",readBytes,meshCount,__LINE__); - throw megaglest_runtime_error(szBuf); - } - meshCount = Shared::PlatformByteOrder::fromCommonEndian(meshCount); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("meshCount = %u\n",meshCount); - try { - meshes= new Mesh[meshCount]; - } - catch(bad_alloc& ba) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error on line: %d size: %d msg: %s\n",__LINE__,meshCount,ba.what()); + normals = new Vec3f[frameCount*vertexCount]; + } catch (bad_alloc& ba) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error on line: %d size: %d msg: %s\n", __LINE__, (frameCount*vertexCount), ba.what()); throw megaglest_runtime_error(szBuf); } - - for(uint32 i = 0; i < meshCount; ++i) { - meshes[i].loadV3(i, dir, f, textureManager,deletePixMapAfterLoad, - loadedFileList,sourceLoader,path); - meshes[i].buildInterpolationData(); - } - } - //version 2 - else if(fileHeader.version == 2) { - readBytes = fread(&meshCount, sizeof(meshCount), 1, f); - if(readBytes != 1 && meshCount != 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u] on line: %d.",readBytes,meshCount,__LINE__); - throw megaglest_runtime_error(szBuf); - } - meshCount = Shared::PlatformByteOrder::fromCommonEndian(meshCount); - - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("meshCount = %d\n",meshCount); - try { - meshes= new Mesh[meshCount]; - } - catch(bad_alloc& ba) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error on line: %d size: %d msg: %s\n",__LINE__,meshCount,ba.what()); + texCoords = new Vec2f[vertexCount]; + } catch (bad_alloc& ba) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error on line: %d size: %d msg: %s\n", __LINE__, vertexCount, ba.what()); throw megaglest_runtime_error(szBuf); } - - for(uint32 i = 0; i < meshCount; ++i){ - meshes[i].loadV2(i,dir, f, textureManager,deletePixMapAfterLoad, - loadedFileList,sourceLoader,path); - meshes[i].buildInterpolationData(); + try { + indices = new uint32[indexCount]; + } catch (bad_alloc& ba) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error on line: %d size: %d msg: %s\n", __LINE__, indexCount, ba.what()); + throw megaglest_runtime_error(szBuf); } } - else { - throw megaglest_runtime_error("Invalid model version: "+ intToStr(fileHeader.version)); - } - fclose(f); - - autoJoinMeshFrames(); - } - catch(megaglest_runtime_error& ex) { - //printf("1111111 ex.wantStackTrace() = %d\n",ex.wantStackTrace()); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - //printf("2222222\n"); - throw megaglest_runtime_error("Exception caught loading 3d file: " + path +"\n"+ ex.what(),!ex.wantStackTrace()); - } - catch(exception &e){ - //abort(); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what()); - throw megaglest_runtime_error("Exception caught loading 3d file: " + path +"\n"+ e.what()); - } -} - -//save a model to a g3d file -void Model::saveG3d(const string &path, string convertTextureToFormat, - bool keepsmallest) { - string tempModelFilename = path + "cvt"; - -#ifdef WIN32 - FILE *f= _wfopen(utf8_decode(tempModelFilename).c_str(), L"wb"); -#else - FILE *f= fopen(tempModelFilename.c_str(), "wb"); -#endif - if(f == NULL) { - throw megaglest_runtime_error("Cant open file for writing: [" + tempModelFilename + "]"); - } - - convertTextureToFormat = toLower(convertTextureToFormat); - - //file header - FileHeader fileHeader; - fileHeader.id[0]= 'G'; - fileHeader.id[1]= '3'; - fileHeader.id[2]= 'D'; - fileHeader.version= 4; - - fwrite(&fileHeader, sizeof(FileHeader), 1, f); - - // file versions - if(fileHeader.version == 4 || fileHeader.version == 3 || fileHeader.version == 2) { - //model header - ModelHeader modelHeader; - modelHeader.meshCount = meshCount; - modelHeader.type = mtMorphMesh; - - fwrite(&modelHeader, sizeof(ModelHeader), 1, f); - - std::map textureDeleteList; - for(uint32 i = 0; i < meshCount; ++i) { - meshes[i].save(i,tempModelFilename, f, textureManager, - convertTextureToFormat,textureDeleteList, - keepsmallest,path); - } - - removeFile(path); - if(renameFile(tempModelFilename,path) == true) { - // Now delete old textures since they were converted to a new format - for(std::map::iterator iterMap = textureDeleteList.begin(); - iterMap != textureDeleteList.end(); ++iterMap) { - removeFile(iterMap->first); - } - } - } - else { - throw megaglest_runtime_error("Invalid model version: "+ intToStr(fileHeader.version)); - } - - fclose(f); -} - -void Model::deletePixels() { - for(uint32 i = 0; i < meshCount; ++i) { - meshes[i].deletePixels(); - } -} - -class MeshContainer { -protected: - int indexValue; - std::vector meshes; - -public: - - MeshContainer() { - this->indexValue = -1; - } - void add(int index, Mesh *mesh) { - if(this->indexValue < 0) { - this->indexValue = index; - } - meshes.push_back(mesh); - } - int index() { - return indexValue; - } - int size() { - return (int)meshes.size(); - } - std::vector get() { - return meshes; - } -}; - -void Mesh::setVertices(Vec3f *data, uint32 count) { - delete [] this->vertices; - this->vertices = data; - - this->vertexCount = count; -} -void Mesh::setNormals(Vec3f *data, uint32 count) { - delete [] this->normals; - this->normals = data; - - this->vertexCount = count; -} - -void Mesh::setTexCoords(Vec2f *data, uint32 count) { - delete [] this->texCoords; - this->texCoords = data; - - this->vertexCount = count; -} - -void Mesh::setIndices(uint32 *data, uint32 count) { - delete [] this->indices; - this->indices = data; - - this->indexCount = count; -} - -void Mesh::copyInto(Mesh *dest, bool ignoreInterpolationData, - bool destinationOwnsTextures) { - - for(int index = 0; index < meshTextureCount; ++index){ - dest->textures[index] = this->textures[index]; - dest->texturesOwned[index] = this->texturesOwned[index]; - dest->texturePaths[index] = this->texturePaths[index]; - - if(destinationOwnsTextures == true) { - this->texturesOwned[index] = false; - } - } - - dest->name = this->name; - //vertex data counts - dest->frameCount = this->frameCount; - dest->vertexCount = this->vertexCount; - dest->indexCount = this->indexCount; - dest->texCoordFrameCount = this->texCoordFrameCount; - - //vertex data - if(dest->vertices != NULL) { - delete [] dest->vertices; - dest->vertices = NULL; - } - if(this->vertices != NULL) { - dest->vertices = new Vec3f[this->frameCount * this->vertexCount]; - memcpy(&dest->vertices[0],&this->vertices[0],this->frameCount * this->vertexCount * sizeof(Vec3f)); - } - - if(dest->normals != NULL) { - delete [] dest->normals; - dest->normals = NULL; - } - if(this->normals != NULL) { - dest->normals = new Vec3f[this->frameCount * this->vertexCount]; - memcpy(&dest->normals[0],&this->normals[0],this->frameCount * this->vertexCount * sizeof(Vec3f)); - } - - if(dest->texCoords != NULL) { - delete [] dest->texCoords; - dest->texCoords = NULL; - } - if(this->texCoords != NULL) { - dest->texCoords = new Vec2f[this->vertexCount]; - memcpy(&dest->texCoords[0],&this->texCoords[0],this->vertexCount * sizeof(Vec2f)); - } - - if(dest->tangents != NULL) { - delete [] dest->tangents; - dest->tangents = NULL; - } - if(this->tangents != NULL) { - dest->tangents = new Vec3f[this->vertexCount]; - memcpy(&dest->tangents[0],&this->tangents[0],this->vertexCount * sizeof(Vec3f)); - } - - if(dest->indices != NULL) { - delete [] dest->indices; - dest->indices = NULL; - } - if(this->indices != NULL) { - dest->indices = new uint32[this->indexCount]; - memcpy(&dest->indices[0],&this->indices[0],this->indexCount * sizeof(uint32)); - } - - //material data - dest->diffuseColor = this->diffuseColor; - dest->specularColor = this->specularColor; - dest->specularPower = this->specularPower; - dest->opacity = this->opacity; - - //properties - dest->twoSided = this->twoSided; - dest->customColor = this->customColor; - dest->noSelect = this->noSelect; - dest->glow = this->glow; - - dest->textureFlags = this->textureFlags; - - if(ignoreInterpolationData == false) { - dest->interpolationData = this->interpolationData; - } - dest->textureManager = this->textureManager; - - // Vertex Buffer Object Names - dest->hasBuiltVBOs = this->hasBuiltVBOs; - dest->m_nVBOVertices = this-> m_nVBOVertices; - dest->m_nVBOTexCoords = this->m_nVBOTexCoords; - dest->m_nVBONormals = this->m_nVBONormals; - dest->m_nVBOIndexes = this->m_nVBOIndexes; -} - -void Model::autoJoinMeshFrames() { - -/* - print "auto-joining compatible meshes..." - meshes = {} - for mesh in self.meshes: - key = (mesh.texture,mesh.frame_count,mesh.twoSided|mesh.customColour) - if key in meshes: - meshes[key].append(mesh) - else: - meshes[key] = [mesh] - for joinable in meshes.values(): - if len(joinable) < 2: continue - base = joinable[0] - print "\tjoining to",base - for mesh in joinable[1:]: - if base.index_count+mesh.index_count > 0xffff: - base = mesh - print "\tjoining to",base - continue - print "\t\t",mesh - for a,b in zip(base.frames,mesh.frames): - a.vertices.extend(b.vertices) - a.normals.extend(b.normals) - if base.texture: - base.textures.extend(mesh.textures) - base.indices.extend(index+base.vertex_count for index in mesh.indices) - base.vertex_count += mesh.vertex_count - base.index_count += mesh.index_count - self.meshes.remove(mesh) -*/ - - - - bool haveJoinedMeshes = false; - - // First looks for meshes with same texture in the same frame - std::map joinedMeshes; - for(uint32 index = 0; index < meshCount; ++index) { - Mesh &mesh = meshes[index]; - - // Duplicate mesh vertices are considered to be those with the same - // 1. texture 2. framecount 3. twosided flag value 4. same custom texture color - -// It's possible the texture is missing and will be NULL -// if(mesh.getTextureFlags() & 1) { -// printf("Mesh has textures:\n"); -// for(unsigned int meshTexIndex = 0; meshTexIndex < meshTextureCount; ++meshTexIndex) { -// printf("Mesh texture index: %d [%p] [%s]\n",meshTexIndex,mesh.getTexture(meshTexIndex),(mesh.getTexture(meshTexIndex) != NULL ? mesh.getTexture(meshTexIndex)->getPath().c_str() : "n/a")); -// } -// } - string mesh_key = ((mesh.getTextureFlags() & 1) && mesh.getTexture(0) ? mesh.getTexture(0)->getPath() : "none"); - mesh_key += string("_") + intToStr(mesh.getFrameCount()) + - string("_") + intToStr(mesh.getTwoSided()) + - string("_") + intToStr(mesh.getCustomTexture()) + - string("_") + intToStr(mesh.getNoSelect()) + - string("_") + floatToStr(mesh.getOpacity()) + - string("_") + floatToStr(mesh.getGlow()) + - string("_") + mesh.getDiffuseColor().getString() + - string("_") + mesh.getSpecularColor().getString() + - string("_") + floatToStr(mesh.getSpecularPower()); - - joinedMeshes[mesh_key].add(index,&mesh); - if(haveJoinedMeshes == false && joinedMeshes[mesh_key].size() > 1) { - haveJoinedMeshes = true; - } - } - if(haveJoinedMeshes == true) { - //printf("*** Detected Joined meshes for model [%s]\n",fileName.c_str()); - - // We have mesh data to join we now create a list in the same order - // as the original meshes but each index will have 1 or more meshes - // This is done to maintain original mesh ordering - std::map > orderedMeshes; - for(std::map::iterator iterMap = joinedMeshes.begin(); - iterMap != joinedMeshes.end(); ++iterMap) { - orderedMeshes[iterMap->second.index()] = iterMap->second.get(); - - //if(iterMap->second.size() > 1) { - // printf("Key [%s] joined meshes: %d\n",iterMap->first.c_str(),iterMap->second.size()); - //} - } - - // Now the real work of creating a new list of joined mesh data - Mesh *joinedMeshList = new Mesh[joinedMeshes.size()]; - - int index = 0; - for(std::map >::iterator iterMap = orderedMeshes.begin(); - iterMap != orderedMeshes.end(); ++iterMap) { - //printf("Join index: %d joincount: %d\n",index,iterMap->second.size()); - - Mesh *base = &joinedMeshList[index]; - - // Deep copy mesh data - iterMap->second[0]->copyInto(base, true, true); - - if(iterMap->second.size() > 1) { - // Time to join mesh data for this mesh - for(unsigned int joinIndex = 1; - joinIndex < iterMap->second.size(); ++joinIndex) { - Mesh *mesh = iterMap->second[joinIndex]; - //if(base->getIndexCount() + mesh->getIndexCount() > 0xffff) { - // printf("Not exactly sure what this IF statement is for?\n"); - // mesh->copyInto(base, true, true); - //} - //else { - // Need to add verticies for each from from mesh to base - uint32 originalBaseVertexCount = base->getVertexCount(); - - uint32 newVertexCount = - base->getVertexCount() + mesh->getVertexCount(); - - uint32 newVertexFrameCount = - (base->getFrameCount() * newVertexCount); - - Vec3f *joined_vertices = new Vec3f[newVertexFrameCount]; - Vec3f *joined_normals = new Vec3f[newVertexFrameCount]; - uint32 join_index = 0; - - // Join mesh vertices and normals - for(unsigned int frameIndex = 0; - frameIndex < base->getFrameCount(); ++frameIndex) { - uint32 baseIndex = frameIndex * originalBaseVertexCount; - uint32 meshIndex = frameIndex * mesh->getVertexCount(); - //uint32 appendBaseJoinIndex = frameIndex * newVertexCount; - - // first original mesh values get copied - memcpy(&joined_vertices[join_index], - &base->getVertices()[baseIndex], - originalBaseVertexCount * sizeof(Vec3f)); - memcpy(&joined_normals[join_index], - &base->getNormals()[baseIndex], - originalBaseVertexCount * sizeof(Vec3f)); - join_index += originalBaseVertexCount; - - // second joined mesh values get copied - memcpy(&joined_vertices[join_index], - &mesh->getVertices()[meshIndex], - mesh->getVertexCount() * sizeof(Vec3f)); - memcpy(&joined_normals[join_index], - &mesh->getNormals()[meshIndex], - mesh->getVertexCount() * sizeof(Vec3f)); - join_index += mesh->getVertexCount(); - } - - // update vertex and normal buffers with joined mesh data - base->setVertices(joined_vertices, newVertexCount); - base->setNormals(joined_normals, newVertexCount); - - // If we have texture coords join them - if(base->getTextureFlags() & 1) { - Vec2f *joined_texCoords = new Vec2f[newVertexCount]; - - // update texture coord buffers with joined mesh data - memcpy(&joined_texCoords[0], - &base->getTexCoords()[0], - originalBaseVertexCount * sizeof(Vec2f)); - memcpy(&joined_texCoords[originalBaseVertexCount], - &mesh->getTexCoords()[0], - mesh->getVertexCount() * sizeof(Vec2f)); - - base->setTexCoords(joined_texCoords, newVertexCount); - } - - // update index buffers with joined mesh data - uint32 newindexCount = base->getIndexCount() + mesh->getIndexCount(); - uint32 *joined_indexes = new uint32[newindexCount]; - - uint32 join_index_index = 0; - memcpy(&joined_indexes[join_index_index], - &base->getIndices()[0], - base->getIndexCount() * sizeof(uint32)); - join_index_index += base->getIndexCount(); - - for(unsigned int meshIndex = 0; - meshIndex < mesh->getIndexCount(); ++meshIndex) { - uint32 index_value = mesh->getIndices()[meshIndex]; - - // join index values - joined_indexes[join_index_index] = index_value + originalBaseVertexCount; - join_index_index++; - } - base->setIndices(joined_indexes, newindexCount); - //} - } - } - base->buildInterpolationData(); - - index++; - } - - delete [] meshes; - meshes = joinedMeshList; - meshCount = (uint32)joinedMeshes.size(); - } -} - -// ---------------------------------------------------------------------------- - -bool PixelBufferWrapper::isPBOEnabled = false; -int PixelBufferWrapper::index = 0; -vector PixelBufferWrapper::pboIds; - -PixelBufferWrapper::PixelBufferWrapper(int pboCount,int bufferSize) { - this->bufferSize = bufferSize; - //if(isGlExtensionSupported("GL_ARB_pixel_buffer_object") == true && - if(GLEW_ARB_pixel_buffer_object) { - PixelBufferWrapper::isPBOEnabled = true; - cleanup(); - // For some wacky reason this fails in VC++ 2008 - //pboIds.reserve(pboCount); - //glGenBuffersARB(pboCount, (GLuint*)&pboIds[0]); - // - - /* - for(int i = 0; i < pboCount; ++i) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("PBO Gen i = %d\n",i); - - pboIds.push_back(0); - glGenBuffersARB(1, (GLuint*)&pboIds[i]); - // create pixel buffer objects, you need to delete them when program exits. - // glBufferDataARB with NULL pointer reserves only memory space. - glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[i]); - glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, bufferSize, 0, GL_STREAM_READ_ARB); - } - glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); - */ - addBuffersToPixelBuf(pboCount); - } -} - -void PixelBufferWrapper::addBuffersToPixelBuf(int pboCount) { - int iStartIndex = pboIds.size(); - for(int i = 0; i < pboCount; ++i) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("PBO Gen i = %d\n",i); - - pboIds.push_back(0); - glGenBuffersARB(1, (GLuint*)&pboIds[i+iStartIndex]); - // create pixel buffer objects, you need to delete them when program exits. - // glBufferDataARB with NULL pointer reserves only memory space. - glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[i+iStartIndex]); - glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, bufferSize, 0, GL_STREAM_READ_ARB); - } - glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); -} - -Pixmap2D *PixelBufferWrapper::getPixelBufferFor(int x,int y,int w,int h, int colorComponents) { - Pixmap2D *pixmapScreenShot = NULL; - if(PixelBufferWrapper::isPBOEnabled == true) { - string codeSection = "A"; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - try { - // increment current index first then get the next index - // "index" is used to read pixels from a framebuffer to a PBO - // "nextIndex" is used to process pixels in the other PBO - index = (index + 1) % 2; - - codeSection = "B"; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - // Check for out of range - if(index >= (int)pboIds.size()) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error / Warning in [%s::%s] on line: %d pixel buffer out of range, index: %d size: %d, attempting to expand buffer...\n",__FILE__,__FUNCTION__,__LINE__,index, (int)pboIds.size()); - //throw megaglest_runtime_error(szBuf); - SystemFlags::OutputDebug(SystemFlags::debugError,"%s",szBuf); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] szBuf: %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,szBuf); - - codeSection = "C"; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - addBuffersToPixelBuf((index - pboIds.size()) + 1); - } - // pbo index used for next frame - //int nextIndex = (index + 1) % 2; - - codeSection = "D"; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - // read framebuffer /////////////////////////////// - // copy pixels from framebuffer to PBO - // Use offset instead of pointer. - // OpenGL should perform asynch DMA transfer, so glReadPixels() will return immediately. - glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[index]); - //glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[nextIndex]); - - codeSection = "E"; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, 0); - //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - // measure the time reading framebuffer - //t1.stop(); - //readTime = t1.getElapsedTimeInMilliSec(); - - // process pixel data ///////////////////////////// - //t1.start(); - - codeSection = "F"; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - // map the PBO that contain framebuffer pixels before processing it - //glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[nextIndex]); - glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[index]); - - codeSection = "G"; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - GLubyte* src = (GLubyte*)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB); - if(src) { - codeSection = "H"; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - pixmapScreenShot = new Pixmap2D(w, h, colorComponents); - - codeSection = "I"; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - memcpy(pixmapScreenShot->getPixels(),src,pixmapScreenShot->getPixelByteCount()); - - codeSection = "J"; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB); // release pointer to the mapped buffer - //pixmapScreenShot->save("debugPBO.png"); - } - codeSection = "K"; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - // measure the time reading framebuffer - //t1.stop(); - //processTime = t1.getElapsedTimeInMilliSec(); - glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - catch(megaglest_runtime_error& ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] codeSection [%s] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,codeSection.c_str(),ex.what()); - throw megaglest_runtime_error("Exception caught in getPixelBufferFor codeSection: " + codeSection +"\n"+ ex.what(),!ex.wantStackTrace()); - } - catch(exception &e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] codeSection [%s] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,codeSection.c_str(),e.what()); - throw megaglest_runtime_error("Exception caught in getPixelBufferFor codeSection: " + codeSection +"\n"+ e.what()); - } - catch(...){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] codeSection [%s] UNKNOWN Error!",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,codeSection.c_str()); - throw megaglest_runtime_error("UNKNOWN Exception caught in getPixelBufferFor codeSection: " + codeSection +"\n"); - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - - return pixmapScreenShot; -} - -void PixelBufferWrapper::begin() { - if(PixelBufferWrapper::isPBOEnabled == true) { - // set the framebuffer to read - //glReadBuffer(GL_FRONT); - } -} - -void PixelBufferWrapper::end() { - if(PixelBufferWrapper::isPBOEnabled == true) { - // set the framebuffer to read - //glReadBuffer(GL_BACK); - } -} - -void PixelBufferWrapper::cleanup() { - if(PixelBufferWrapper::isPBOEnabled == true) { - if(pboIds.empty() == false) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("PBO Delete size = %d\n",(int)pboIds.size()); - - glDeleteBuffersARB((int)pboIds.size(), &pboIds[0]); - pboIds.clear(); - - glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); - } - } -} - -PixelBufferWrapper::~PixelBufferWrapper() { - cleanup(); -} - -// --------------------------------------------------------------------------- - -int BaseColorPickEntity::bufferSizeRequired = -1; -const unsigned int BaseColorPickEntity::p = 64007; -const unsigned int BaseColorPickEntity::k = 43067; -unsigned int BaseColorPickEntity::nextColorRGB = BaseColorPickEntity::k; - -unsigned char BaseColorPickEntity::nextColorID[COLOR_COMPONENTS] = { 1, 1, 1, 0 }; -auto_ptr BaseColorPickEntity::pbo; -//auto_ptr BaseColorPickEntity::cachedPixels; - -map BaseColorPickEntity::usedColorIDList; -bool BaseColorPickEntity::trackColorUse = true; - -vector > BaseColorPickEntity::nextColorIDReuseList; - -bool BaseColorPickEntity::using_loop_method = false; - -BaseColorPickEntity::BaseColorPickEntity() { - if(BaseColorPickEntity::bufferSizeRequired != -1) { - BaseColorPickEntity::init(BaseColorPickEntity::bufferSizeRequired); - } - uniqueColorID[0] = 0; - uniqueColorID[1] = 0; - uniqueColorID[2] = 0; - uniqueColorID[3] = 0; - assign_color(); -} - -bool BaseColorPickEntity::get_next_assign_color(unsigned char *assign_to) { - - if(assign_to == NULL) { - throw megaglest_runtime_error("assign_to == NULL"); - } - - if(BaseColorPickEntity::using_loop_method == true) { - assign_color_using_loop(assign_to); - } - else { - assign_color_using_prime(assign_to); - } - - bool isDuplicate = false; - if(BaseColorPickEntity::trackColorUse == true) { - string color_key = getColorDescription(); - //printf("Assigned color [%s]\n",color_key.c_str()); - - if(usedColorIDList.find(color_key) == usedColorIDList.end()) { - usedColorIDList[color_key] = true; - - //printf("Color added to used list [%s] usedColorIDList = %d nextColorIDReuseList = %d!\n",color_key.c_str(),(int)usedColorIDList.size(),(int)nextColorIDReuseList.size()); - } - else { - isDuplicate = true; - printf("Line ref: %d *WARNING* color [%s] used count: %d using_loop: %d ALREADY in history list!\n",__LINE__,color_key.c_str(),(int)usedColorIDList.size(),BaseColorPickEntity::using_loop_method); - } - } - return isDuplicate; -} - -void BaseColorPickEntity::assign_color() { - get_next_assign_color(&uniqueColorID[0]); -} - -void BaseColorPickEntity::assign_color_using_prime(unsigned char *assign_to) { - nextColorRGB = (nextColorRGB * k) % p; - - // nextColorID is a 16-bit (hi)colour (for players with 16-bit display depths) - // we expand it to true-color for use with OpenGL - - const unsigned int - r = (nextColorRGB >> 11) & ((1<<5)-1), - g = (nextColorRGB >> 5) & ((1<<6)-1), - b = nextColorRGB & ((1<<5)-1); - - assign_to[0] = r << 3; - assign_to[1] = g << 2; - assign_to[2] = b << 3; -} - -void BaseColorPickEntity::assign_color_using_loop(unsigned char *assign_to) { - if(nextColorIDReuseList.empty() == false) { - //printf("Color being reused [%u.%u.%u] usedColorIDList = %d nextColorIDReuseList = %d!\n",nextColorIDReuseList.back()[0],nextColorIDReuseList.back()[1],nextColorIDReuseList.back()[2],(int)usedColorIDList.size(),(int)nextColorIDReuseList.size()); - - assign_to[0] = nextColorIDReuseList.back()[0]; - assign_to[1] = nextColorIDReuseList.back()[1]; - assign_to[2] = nextColorIDReuseList.back()[2]; - - nextColorIDReuseList.pop_back(); - - string color_key = getColorDescription(); - if(usedColorIDList.find(color_key) == usedColorIDList.end()) { - //usedColorIDList[color_key] = true; - //printf("Color added to used list [%s] usedColorIDList = %d nextColorIDReuseList = %d!\n",color_key.c_str(),(int)usedColorIDList.size(),(int)nextColorIDReuseList.size()); - } - else { - printf("Line ref: %d *WARNING* color [%s] ALREADY FOUND in history list!\n",__LINE__,color_key.c_str()); - assign_color_using_loop(assign_to); - } - } - else { - assign_to[0] = nextColorID[0]; - assign_to[1] = nextColorID[1]; - assign_to[2] = nextColorID[2]; - - const int colorSpacing = 8; - - if((int)(nextColorID[0] + colorSpacing) <= 255) { - nextColorID[0] += colorSpacing; - } - else { - nextColorID[0] = 1; - if((int)(nextColorID[1] + colorSpacing) <= 255) { - nextColorID[1] += colorSpacing; - } - else { - nextColorID[1] = 1; - if((int)(nextColorID[2] + colorSpacing) <= 255) { - nextColorID[2] += colorSpacing; - } - else { - - printf("Color rolled over on 3rd level usedColorIDList = %d!\n",(int)usedColorIDList.size()); - - nextColorID[0] = 1; - nextColorID[1] = 1; - nextColorID[2] = 1; - - - // nextColorID[2] = 1; - // nextColorID[3]+=colorSpacing; - // - // if(nextColorID[3] > 255) { - // nextColorID[0] = 1; - // nextColorID[1] = 1; - // nextColorID[2] = 1; - // nextColorID[3] = 1; - // } - } - } - } - } -} - -void BaseColorPickEntity::recycleUniqueColor() { - - vector reUseColor; - reUseColor.push_back(uniqueColorID[0]); - reUseColor.push_back(uniqueColorID[1]); - reUseColor.push_back(uniqueColorID[2]); - nextColorIDReuseList.push_back(reUseColor); - - //printf("RECYCLE Color [%u.%u.%u] usedColorIDList = %d nextColorIDReuseList = %d!\n",reUseColor[0],reUseColor[1],reUseColor[2],(int)usedColorIDList.size(),(int)nextColorIDReuseList.size()); - - if(usedColorIDList.empty() == false) { - string color_key = getColorDescription(); - usedColorIDList.erase(color_key); - //printf("REMOVING used Color [%s] usedColorIDList = %d nextColorIDReuseList = %d!\n",color_key.c_str(),(int)usedColorIDList.size(),(int)nextColorIDReuseList.size()); - //printf("Line ref: %d *WARNING* color [%s] used count: %d NOT FOUND in history list!\n",__LINE__,color_key.c_str(),(int)usedColorIDList.size()); - } -} - -void BaseColorPickEntity::resetUniqueColors() { - BaseColorPickEntity::nextColorRGB = BaseColorPickEntity::k; - - BaseColorPickEntity::nextColorID[0] = 1; - BaseColorPickEntity::nextColorID[1] = 1; - BaseColorPickEntity::nextColorID[2] = 1; - - usedColorIDList.clear(); - nextColorIDReuseList.clear(); -} -void BaseColorPickEntity::init(int bufferSize) { - if(BaseColorPickEntity::pbo.get() == NULL) { - //printf("BaseColorPickEntity::init pbo == null\n"); - BaseColorPickEntity::bufferSizeRequired = bufferSize; - BaseColorPickEntity::pbo.reset(new PixelBufferWrapper(2,BaseColorPickEntity::bufferSizeRequired)); - } - else if(bufferSize != BaseColorPickEntity::bufferSizeRequired) { - //printf("BaseColorPickEntity::init pbo resize\n"); - cleanupPBO(); - BaseColorPickEntity::bufferSizeRequired = bufferSize; - BaseColorPickEntity::pbo.reset(new PixelBufferWrapper(2,BaseColorPickEntity::bufferSizeRequired)); - } -} - -void BaseColorPickEntity::cleanupPBO() { - BaseColorPickEntity::pbo.reset(0); -} - -string BaseColorPickEntity::getColorDescription() const { - char szBuf[100]=""; - snprintf(szBuf,100,"%d.%d.%d",uniqueColorID[0],uniqueColorID[1],uniqueColorID[2]); - string result = szBuf; - return result; -} - -void BaseColorPickEntity::beginPicking() { - // turn off texturing, lighting and fog - //glClearColor (0.0,0.0,0.0,0.0); - //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - //reset current background. This is neeeded to get a proper black background! - //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glClear(GL_COLOR_BUFFER_BIT); - - glPushAttrib(GL_ENABLE_BIT); - //glEnable(GL_DEPTH_TEST); - glDisable(GL_TEXTURE_2D); - glDisable(GL_FOG); - glDisable(GL_LIGHTING); - glDisable(GL_BLEND); - glDisable(GL_MULTISAMPLE); - glDisable(GL_DITHER); - glDisable(GL_POLYGON_OFFSET_FILL); - glDisable(GL_NORMALIZE); - - // all off, but we want depth test - glEnable(GL_DEPTH_TEST); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - //glPushAttrib(GL_TEXTURE_2D | GL_LIGHTING | GL_BLEND | GL_MULTISAMPLE | GL_DITHER); - //glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_POLYGON_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT | GL_NORMALIZE | GL_BLEND | GL_POLYGON_OFFSET_FILL); -} - -void BaseColorPickEntity::endPicking() { - // turn off texturing, lighting and fog - //glEnable(GL_TEXTURE_2D); - //glEnable(GL_FOG); - //glEnable(GL_LIGHTING); - - //glEnable(GL_BLEND); - //glEnable(GL_MULTISAMPLE); - //glEnable(GL_DITHER); - glPopAttrib(); -} - -vector BaseColorPickEntity::getPickedList(int x,int y,int w,int h, - const vector &rendererModels) { - vector pickedModels; - pickedModels.reserve(rendererModels.size()); - - //printf("In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - static auto_ptr cachedPixels; - //auto_ptr cachedPixels; - - //printf("PixelBufferWrapper::getIsPBOEnable() = %d\n",PixelBufferWrapper::getIsPBOEnable()); - if(rendererModels.empty() == false) { - if(PixelBufferWrapper::getIsPBOEnable() == true) { - Pixmap2D *pixmapScreenShot = BaseColorPickEntity::pbo->getPixelBufferFor(x,y,w,h, COLOR_COMPONENTS); - //pixmapScreenShot->saveTga("/tmp/toll.tga"); //### for debugging - cachedPixels.reset(pixmapScreenShot); - } - else { - Pixmap2D *pixmapScreenShot = new Pixmap2D(w, h, COLOR_COMPONENTS); - //glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixmapScreenShot->getPixels()); - //pixmapScreenShot->saveTga("/tmp/toll.tga"); - cachedPixels.reset(pixmapScreenShot); - //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - } - unsigned char *pixelBuffer = cachedPixels->getPixels(); - - map modelAlreadyPickedList; - map > > colorAlreadyPickedList; - - int skipSteps=4; - //unsigned char *oldpixel = &pixelBuffer[0]; - - // now we check the screenshot if we find pixels in color of unit identity - // to speedup we only check every "skipSteps" line and pixel in a row if we find such a color. - // this is exact enough for MG purpose - for(int hh = 0; hh < h && pickedModels.size() < rendererModels.size(); hh=hh+skipSteps) { - for(int ww=0;ww < w && pickedModels.size() < rendererModels.size(); ww=ww+skipSteps){ - - int index = (hh*w+ww) * COLOR_COMPONENTS; - unsigned char *pixel = &pixelBuffer[index]; - //printf("pixel[0]=%d pixel[1]=%d pixel[2]=%d\n",pixel[0],pixel[1],pixel[2]); - if(pixel[0]==0 && pixel[1]==0 && pixel[2]==0) - { - continue; - } -// if(index>0) -// { -// oldpixel = &pixelBuffer[index-1*COLOR_COMPONENTS]; -// if(memcmp(pixel,oldpixel,3)) continue; -// } - - // Skip duplicate scanned colors - map > >::const_iterator iterFind1 = colorAlreadyPickedList.find(pixel[0]); - if(iterFind1 != colorAlreadyPickedList.end()) { - map >::const_iterator iterFind2 = iterFind1->second.find(pixel[1]); - if(iterFind2 != iterFind1->second.end()) { - map::const_iterator iterFind3 = iterFind2->second.find(pixel[2]); - if(iterFind3 != iterFind2->second.end()) { - continue; - } + void Mesh::end() { + ReleaseVBOs(); + + delete[] vertices; + vertices = NULL; + delete[] normals; + normals = NULL; + delete[] texCoords; + texCoords = NULL; + delete[] tangents; + tangents = NULL; + delete[] indices; + indices = NULL; + + cleanupInterpolationData(); + + if (textureManager != NULL) { + for (int i = 0; i < meshTextureCount; ++i) { + if (texturesOwned[i] == true && textures[i] != NULL) { + //printf("Deleting Texture [%s] i = %d\n",textures[i]->getPath().c_str(),i); + textureManager->endTexture(textures[i]); + textures[i] = NULL; } } + } + textureManager = NULL; + } - for(unsigned int i = 0; i < rendererModels.size(); ++i) { - // Skip models already selected - if(modelAlreadyPickedList.find(i) != modelAlreadyPickedList.end()) { - continue; - } - const BaseColorPickEntity *model = rendererModels[i]; + // ========================== shadows & interpolation ========================= - if( model != NULL && model->isUniquePickingColor(pixel) == true) { - //printf("Found match pixel [%d.%d.%d] for model [%s] ptr [%p][%s]\n",pixel[0],pixel[1],pixel[2],model->getColorDescription().c_str(), model,model->getUniquePickName().c_str()); + void Mesh::buildInterpolationData() { + if (interpolationData != NULL) { + printf("**WARNING possible memory leak [Mesh::buildInterpolationData()]\n"); + } + interpolationData = new InterpolationData(this); + } - pickedModels.push_back(i); - modelAlreadyPickedList[i]=true; - colorAlreadyPickedList[pixel[0]][pixel[1]][pixel[2]]=true; + void Mesh::cleanupInterpolationData() { + delete interpolationData; + interpolationData = NULL; + } + + void Mesh::updateInterpolationData(float t, bool cycle) { + if (interpolationData != NULL) { + interpolationData->update(t, cycle); + } + } + + void Mesh::updateInterpolationVertices(float t, bool cycle) { + if (interpolationData != NULL) { + interpolationData->updateVertices(t, cycle); + } + } + + void Mesh::BuildVBOs() { + if (getVBOSupported() == true) { + if (hasBuiltVBOs == false) { + //printf("In [%s::%s Line: %d] setting up a VBO...\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + // Generate And Bind The Vertex Buffer + glGenBuffersARB(1, (GLuint*) &m_nVBOVertices); // Get A Valid Name + glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_nVBOVertices); // Bind The Buffer + // Load The Data + glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(Vec3f)*frameCount*vertexCount, vertices, GL_STATIC_DRAW_ARB); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + + // Generate And Bind The Texture Coordinate Buffer + glGenBuffersARB(1, (GLuint*) &m_nVBOTexCoords); // Get A Valid Name + glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_nVBOTexCoords); // Bind The Buffer + // Load The Data + glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(Vec2f)*vertexCount, texCoords, GL_STATIC_DRAW_ARB); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + + // Generate And Bind The Normal Buffer + glGenBuffersARB(1, (GLuint*) &m_nVBONormals); // Get A Valid Name + glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_nVBONormals); // Bind The Buffer + // Load The Data + glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(Vec3f)*frameCount*vertexCount, normals, GL_STATIC_DRAW_ARB); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + + // Generate And Bind The Index Buffer + glGenBuffersARB(1, (GLuint*) &m_nVBOIndexes); // Get A Valid Name + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, m_nVBOIndexes); // Bind The Buffer + // Load The Data + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(uint32)*indexCount, indices, GL_STATIC_DRAW_ARB); + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + + // Our Copy Of The Data Is No Longer Necessary, It Is Safe In The Graphics Card + delete[] vertices; vertices = NULL; + delete[] texCoords; texCoords = NULL; + delete[] normals; normals = NULL; + delete[] indices; indices = NULL; + + delete interpolationData; + interpolationData = NULL; + + hasBuiltVBOs = true; + } + } + } + + void Mesh::ReleaseVBOs() { + if (getVBOSupported() == true) { + if (hasBuiltVBOs == true) { + glDeleteBuffersARB(1, (GLuint*) &m_nVBOVertices); // Get A Valid Name + glDeleteBuffersARB(1, (GLuint*) &m_nVBOTexCoords); // Get A Valid Name + glDeleteBuffersARB(1, (GLuint*) &m_nVBONormals); // Get A Valid Name + glDeleteBuffersARB(1, (GLuint*) &m_nVBOIndexes); // Get A Valid Name + hasBuiltVBOs = false; + } + } + } + + // ==================== load ==================== + + string Mesh::findAlternateTexture(vector conversionList, string textureFile) { + string result = textureFile; + string fileExt = extractExtension(textureFile); + + for (unsigned int i = 0; i < conversionList.size(); ++i) { + string convertTo = conversionList[i]; + if (fileExt != convertTo) { + string alternateTexture = textureFile; + replaceAll(alternateTexture, "." + fileExt, "." + convertTo); + if (fileExists(alternateTexture) == true) { + result = alternateTexture; break; } } } + return result; } - //printf("In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //delete pixmapScreenShot; + void Mesh::loadV2(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager, + bool deletePixMapAfterLoad, std::map > > *loadedFileList, + string sourceLoader, string modelFile) { + this->textureManager = textureManager; + //read header + MeshHeaderV2 meshHeader; + size_t readBytes = fread(&meshHeader, sizeof(MeshHeaderV2), 1, f); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianMeshHeaderV2(meshHeader); + + if (meshHeader.normalFrameCount != meshHeader.vertexFrameCount) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Old v2 model: vertex frame count different from normal frame count [v = %d, n = %d] meshIndex = %d modelFile [%s]", meshHeader.vertexFrameCount, meshHeader.normalFrameCount, meshIndex, modelFile.c_str()); + throw megaglest_runtime_error(szBuf, true); + } + + if (meshHeader.texCoordFrameCount != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Old v2 model: texture coord frame count is not 1 [t = %d] meshIndex = %d modelFile [%s]", meshHeader.texCoordFrameCount, meshIndex, modelFile.c_str()); + throw megaglest_runtime_error(szBuf, true); + } + + //init + frameCount = meshHeader.vertexFrameCount; + vertexCount = meshHeader.pointCount; + indexCount = meshHeader.indexCount; + texCoordFrameCount = meshHeader.texCoordFrameCount; + + init(); + + //misc + twoSided = false; + customColor = false; + noSelect = false; + glow = false; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Load v2, this = %p Found meshHeader.hasTexture = %d, texName [%s] mtDiffuse = %d meshIndex = %d modelFile [%s]\n", this, meshHeader.hasTexture, toLower(reinterpret_cast(meshHeader.texName)).c_str(), mtDiffuse, meshIndex, modelFile.c_str()); + + textureFlags = 0; + if (meshHeader.hasTexture) { + textureFlags = 1; + } + + //texture + if (meshHeader.hasTexture && textureManager != NULL) { + texturePaths[mtDiffuse] = toLower(reinterpret_cast(meshHeader.texName)); + string texPath = dir; + if (texPath != "") { + endPathWithSlash(texPath); + } + texPath += texturePaths[mtDiffuse]; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] v2 model texture [%s] meshIndex = %d modelFile [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, texPath.c_str(), meshIndex, modelFile.c_str()); + + textures[mtDiffuse] = dynamic_cast(textureManager->getTexture(texPath)); + if (textures[mtDiffuse] == NULL) { + if (fileExists(texPath) == false) { + vector conversionList; + conversionList.push_back("png"); + conversionList.push_back("jpg"); + conversionList.push_back("tga"); + conversionList.push_back("bmp"); + texPath = findAlternateTexture(conversionList, texPath); + } + if (fileExists(texPath) == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] v2 model texture [%s] meshIndex = %d modelFile [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, texPath.c_str(), meshIndex, modelFile.c_str()); + + textures[mtDiffuse] = textureManager->newTexture2D(); + textures[mtDiffuse]->load(texPath); + if (loadedFileList) { + (*loadedFileList)[texPath].push_back(make_pair(sourceLoader, sourceLoader)); + } + texturesOwned[mtDiffuse] = true; + textures[mtDiffuse]->init(textureManager->getTextureFilter(), textureManager->getMaxAnisotropy()); + if (deletePixMapAfterLoad == true) { + textures[mtDiffuse]->deletePixels(); + } + } else { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error v2 model is missing texture [%s] meshIndex = %d modelFile [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, texPath.c_str(), meshIndex, modelFile.c_str()); + } + } + } + + //read data + readBytes = fread(vertices, sizeof(Vec3f)*frameCount*vertexCount, 1, f); + if (readBytes != 1 && (frameCount * vertexCount) != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.", readBytes, frameCount, vertexCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianVecArray(vertices, frameCount*vertexCount); + + readBytes = fread(normals, sizeof(Vec3f)*frameCount*vertexCount, 1, f); + if (readBytes != 1 && (frameCount * vertexCount) != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.", readBytes, frameCount, vertexCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianVecArray(normals, frameCount*vertexCount); + + if (textureFlags & (1 << mtDiffuse)) { + readBytes = fread(texCoords, sizeof(Vec2f)*vertexCount, 1, f); + if (readBytes != 1 && vertexCount != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.", readBytes, frameCount, vertexCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianVecArray(texCoords, vertexCount); + } + readBytes = fread(&diffuseColor, sizeof(Vec3f), 1, f); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianVecArray(&diffuseColor, 1); + + readBytes = fread(&opacity, sizeof(float32), 1, f); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + opacity = Shared::PlatformByteOrder::fromCommonEndian(opacity); + + int seek_result = fseek(f, sizeof(Vec4f)*(meshHeader.colorFrameCount - 1), SEEK_CUR); + if (seek_result != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fseek returned failure = %d [%u] on line: %d.", seek_result, indexCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + readBytes = fread(indices, sizeof(uint32)*indexCount, 1, f); + if (readBytes != 1 && indexCount != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u] on line: %d.", readBytes, indexCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + Shared::PlatformByteOrder::fromEndianTypeArray(indices, indexCount); + } + + void Mesh::loadV3(int meshIndex, const string &dir, FILE *f, + TextureManager *textureManager, bool deletePixMapAfterLoad, + std::map > > *loadedFileList, + string sourceLoader, string modelFile) { + this->textureManager = textureManager; + + //read header + MeshHeaderV3 meshHeader; + size_t readBytes = fread(&meshHeader, sizeof(MeshHeaderV3), 1, f); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianMeshHeaderV3(meshHeader); + + if (meshHeader.normalFrameCount != meshHeader.vertexFrameCount) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Old v3 model: vertex frame count different from normal frame count [v = %d, n = %d] meshIndex = %d modelFile [%s]", meshHeader.vertexFrameCount, meshHeader.normalFrameCount, meshIndex, modelFile.c_str()); + throw megaglest_runtime_error(szBuf, true); + } + + //init + frameCount = meshHeader.vertexFrameCount; + vertexCount = meshHeader.pointCount; + indexCount = meshHeader.indexCount; + texCoordFrameCount = meshHeader.texCoordFrameCount; + + init(); + + //misc + twoSided = (meshHeader.properties & mp3TwoSided) != 0; + customColor = (meshHeader.properties & mp3CustomColor) != 0; + noSelect = false; + glow = false; + + textureFlags = 0; + if ((meshHeader.properties & mp3NoTexture) != mp3NoTexture) { + textureFlags = 1; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Load v3, this = %p Found meshHeader.properties = %d, textureFlags = %d, texName [%s] mtDiffuse = %d meshIndex = %d modelFile [%s]\n", this, meshHeader.properties, textureFlags, toLower(reinterpret_cast(meshHeader.texName)).c_str(), mtDiffuse, meshIndex, modelFile.c_str()); + + //texture + if ((meshHeader.properties & mp3NoTexture) != mp3NoTexture && textureManager != NULL) { + texturePaths[mtDiffuse] = toLower(reinterpret_cast(meshHeader.texName)); + + string texPath = dir; + if (texPath != "") { + endPathWithSlash(texPath); + } + texPath += texturePaths[mtDiffuse]; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] v3 model texture [%s] meshIndex = %d modelFile [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, texPath.c_str(), meshIndex, modelFile.c_str()); + + textures[mtDiffuse] = dynamic_cast(textureManager->getTexture(texPath)); + if (textures[mtDiffuse] == NULL) { + if (fileExists(texPath) == false) { + vector conversionList; + conversionList.push_back("png"); + conversionList.push_back("jpg"); + conversionList.push_back("tga"); + conversionList.push_back("bmp"); + texPath = findAlternateTexture(conversionList, texPath); + } + + if (fileExists(texPath) == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] v3 model texture [%s] meshIndex = %d modelFile [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, texPath.c_str(), meshIndex, modelFile.c_str()); + + textures[mtDiffuse] = textureManager->newTexture2D(); + textures[mtDiffuse]->load(texPath); + if (loadedFileList) { + (*loadedFileList)[texPath].push_back(make_pair(sourceLoader, sourceLoader)); + } + + texturesOwned[mtDiffuse] = true; + textures[mtDiffuse]->init(textureManager->getTextureFilter(), textureManager->getMaxAnisotropy()); + if (deletePixMapAfterLoad == true) { + textures[mtDiffuse]->deletePixels(); + } + } else { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error v3 model is missing texture [%s] meshHeader.properties = %d meshIndex = %d modelFile [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, texPath.c_str(), meshHeader.properties, meshIndex, modelFile.c_str()); + } + } + } + + //read data + readBytes = fread(vertices, sizeof(Vec3f)*frameCount*vertexCount, 1, f); + if (readBytes != 1 && (frameCount * vertexCount) != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.", readBytes, frameCount, vertexCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianVecArray(vertices, frameCount*vertexCount); + + readBytes = fread(normals, sizeof(Vec3f)*frameCount*vertexCount, 1, f); + if (readBytes != 1 && (frameCount * vertexCount) != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.", readBytes, frameCount, vertexCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianVecArray(normals, frameCount*vertexCount); + + if (textureFlags & (1 << mtDiffuse)) { + for (unsigned int i = 0; i < meshHeader.texCoordFrameCount; ++i) { + readBytes = fread(texCoords, sizeof(Vec2f)*vertexCount, 1, f); + if (readBytes != 1 && vertexCount != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.", readBytes, frameCount, vertexCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianVecArray(texCoords, vertexCount); + } + } + readBytes = fread(&diffuseColor, sizeof(Vec3f), 1, f); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianVecArray(&diffuseColor, 1); + + readBytes = fread(&opacity, sizeof(float32), 1, f); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + opacity = Shared::PlatformByteOrder::fromCommonEndian(opacity); + + int seek_result = fseek(f, sizeof(Vec4f)*(meshHeader.colorFrameCount - 1), SEEK_CUR); + if (seek_result != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fseek returned failure = %d [%u] on line: %d.", seek_result, indexCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + + readBytes = fread(indices, sizeof(uint32)*indexCount, 1, f); + if (readBytes != 1 && indexCount != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u] on line: %d.", readBytes, indexCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + Shared::PlatformByteOrder::fromEndianTypeArray(indices, indexCount); + } + + Texture2D* Mesh::loadMeshTexture(int meshIndex, int textureIndex, + TextureManager *textureManager, string textureFile, + int textureChannelCount, bool &textureOwned, bool deletePixMapAfterLoad, + std::map > > *loadedFileList, + string sourceLoader, string modelFile) { + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] #1 load texture [%s] modelFile [%s]\n", __FUNCTION__, textureFile.c_str(), modelFile.c_str()); + + Texture2D* texture = dynamic_cast(textureManager->getTexture(textureFile)); + if (texture == NULL) { + if (fileExists(textureFile) == false) { + vector conversionList; + conversionList.push_back("png"); + conversionList.push_back("jpg"); + conversionList.push_back("tga"); + conversionList.push_back("bmp"); + textureFile = findAlternateTexture(conversionList, textureFile); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] #2 load texture [%s]\n", __FUNCTION__, textureFile.c_str()); + } + + if (fileExists(textureFile) == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] #3 load texture [%s] modelFile [%s]\n", __FUNCTION__, textureFile.c_str(), modelFile.c_str()); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] texture exists loading [%s]\n",__FUNCTION__,textureFile.c_str()); + + texture = textureManager->newTexture2D(); + if (textureChannelCount != -1) { + texture->getPixmap()->init(textureChannelCount); + } + texture->load(textureFile); + if (loadedFileList) { + (*loadedFileList)[textureFile].push_back(make_pair(sourceLoader, sourceLoader)); + } + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] texture loaded [%s]\n",__FUNCTION__,textureFile.c_str()); + + textureOwned = true; + texture->init(textureManager->getTextureFilter(), textureManager->getMaxAnisotropy()); + if (deletePixMapAfterLoad == true) { + texture->deletePixels(); + } + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] texture inited [%s]\n",__FUNCTION__,textureFile.c_str()); + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] #3 cannot load texture [%s] modelFile [%s]\n", __FUNCTION__, textureFile.c_str(), modelFile.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error v4 model is missing texture [%s] textureFlags = %d meshIndex = %d textureIndex = %d modelFile [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, textureFile.c_str(), textureFlags, meshIndex, textureIndex, modelFile.c_str()); + } + } + + return texture; + } + + void Mesh::load(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager, + bool deletePixMapAfterLoad, std::map > > *loadedFileList, + string sourceLoader, string modelFile) { + this->textureManager = textureManager; + + //read header + MeshHeader meshHeader; + size_t readBytes = fread(&meshHeader, sizeof(MeshHeader), 1, f); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianMeshHeader(meshHeader); + + name = reinterpret_cast(meshHeader.name); + + //printf("Load, Found meshTextureCount = %d, meshHeader.textures = %d\n",meshTextureCount,meshHeader.textures); + + //init + frameCount = meshHeader.frameCount; + vertexCount = meshHeader.vertexCount; + indexCount = meshHeader.indexCount; + + init(); + + //properties + customColor = (meshHeader.properties & mpfCustomColor) != 0; + twoSided = (meshHeader.properties & mpfTwoSided) != 0; + noSelect = (meshHeader.properties & mpfNoSelect) != 0; + glow = (meshHeader.properties & mpfGlow) != 0; + + //material + diffuseColor = Vec3f(meshHeader.diffuseColor); + specularColor = Vec3f(meshHeader.specularColor); + specularPower = meshHeader.specularPower; + opacity = meshHeader.opacity; + if (opacity == 0) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("found a mesh with opacity=0 in header, using opacity=1 to see it now \n"); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("file: %s\n", modelFile.c_str()); + opacity = 1.0f; + } + textureFlags = meshHeader.textures; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Load v4, this = %p Found meshHeader.textures = %d meshIndex = %d\n", this, meshHeader.textures, meshIndex); + + //maps + uint32 flag = 1; + for (int i = 0; i < meshTextureCount; ++i) { + if (meshHeader.textures & flag) { + uint8 cMapPath[mapPathSize + 1]; + memset(&cMapPath[0], 0, mapPathSize + 1); + readBytes = fread(cMapPath, mapPathSize, 1, f); + cMapPath[mapPathSize] = 0; + if (readBytes != 1 && mapPathSize != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u] on line: %d.", readBytes, mapPathSize, __LINE__); + throw megaglest_runtime_error(szBuf); + } + Shared::PlatformByteOrder::fromEndianTypeArray(cMapPath, mapPathSize); + + char mapPathString[mapPathSize + 1] = ""; + memset(&mapPathString[0], 0, mapPathSize + 1); + memcpy(&mapPathString[0], reinterpret_cast(cMapPath), mapPathSize); + string mapPath = toLower(mapPathString); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("mapPath [%s] meshHeader.textures = %d flag = %d (meshHeader.textures & flag) = %d meshIndex = %d i = %d\n", mapPath.c_str(), meshHeader.textures, flag, (meshHeader.textures & flag), meshIndex, i); + + string mapFullPath = dir; + if (mapFullPath != "") { + endPathWithSlash(mapFullPath); + } + mapFullPath += mapPath; + if (textureManager) { + textures[i] = loadMeshTexture(meshIndex, i, textureManager, mapFullPath, + meshTextureChannelCount[i], texturesOwned[i], + deletePixMapAfterLoad, loadedFileList, sourceLoader, modelFile); + } + } + flag *= 2; + } + + //read data + readBytes = fread(vertices, sizeof(Vec3f)*frameCount*vertexCount, 1, f); + if (readBytes != 1 && (frameCount * vertexCount) != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.", readBytes, frameCount, vertexCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianVecArray(vertices, frameCount*vertexCount); + + readBytes = fread(normals, sizeof(Vec3f)*frameCount*vertexCount, 1, f); + if (readBytes != 1 && (frameCount * vertexCount) != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.", readBytes, frameCount, vertexCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianVecArray(normals, frameCount*vertexCount); + + if (meshHeader.textures != 0) { + readBytes = fread(texCoords, sizeof(Vec2f)*vertexCount, 1, f); + if (readBytes != 1 && vertexCount != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u][%u] on line: %d.", readBytes, frameCount, vertexCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianVecArray(texCoords, vertexCount); + } + readBytes = fread(indices, sizeof(uint32)*indexCount, 1, f); + if (readBytes != 1 && indexCount != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u] on line: %d.", readBytes, indexCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + Shared::PlatformByteOrder::fromEndianTypeArray(indices, indexCount); + + //tangents + if (textures[mtNormal] != NULL) { + computeTangents(); + } + } + + void Mesh::save(int meshIndex, const string &dir, FILE *f, TextureManager *textureManager, + string convertTextureToFormat, std::map &textureDeleteList, + bool keepsmallest, string modelFile) { + MeshHeader meshHeader; + memset(&meshHeader, 0, sizeof(struct MeshHeader)); + + strncpy((char*) meshHeader.name, (char*) name.c_str(), name.length()); + meshHeader.frameCount = frameCount; + meshHeader.vertexCount = vertexCount; + meshHeader.indexCount = indexCount; + + //material + memcpy((float32*) meshHeader.diffuseColor, (float32*) diffuseColor.ptr(), sizeof(float32) * 3); + memcpy((float32*) meshHeader.specularColor, (float32*) specularColor.ptr(), sizeof(float32) * 3); + meshHeader.specularPower = specularPower; + meshHeader.opacity = opacity; + + //properties + meshHeader.properties = 0; + if (customColor) { + meshHeader.properties |= mpfCustomColor; + } + if (twoSided) { + meshHeader.properties |= mpfTwoSided; + } + if (noSelect) { + meshHeader.properties |= mpfNoSelect; + } + if (glow) { + meshHeader.properties |= mpfGlow; + } + + meshHeader.textures = textureFlags; + fwrite(&meshHeader, sizeof(MeshHeader), 1, f); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Save, this = %p, Found meshTextureCount = %d, meshHeader.textures = %d meshIndex = %d\n", this, meshTextureCount, meshHeader.textures, meshIndex); + + //maps + uint32 flag = 1; + for (int i = 0; i < meshTextureCount; ++i) { + if ((meshHeader.textures & flag)) { + uint8 cMapPath[mapPathSize]; + memset(&cMapPath[0], 0, mapPathSize); + + Texture2D *texture = textures[i]; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Save, [%d] mesh texture ptr [%p]\n", i, texture); + + if (texture != NULL) { + string file = toLower(texture->getPath()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Save, Found mesh texture [%s]\n", file.c_str()); + + if (toLower(convertTextureToFormat) != "" && + EndsWith(file, "." + convertTextureToFormat) == false) { + long originalSize = getFileSize(file); + long newSize = originalSize; + + string fileExt = extractExtension(file); + replaceAll(file, "." + fileExt, "." + convertTextureToFormat); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Save, Convert from [%s] to [%s]\n", texture->getPath().c_str(), file.c_str()); + + if (convertTextureToFormat == "tga") { + texture->getPixmap()->saveTga(file); + newSize = getFileSize(file); + if (keepsmallest == false || newSize <= originalSize) { + textureDeleteList[texture->getPath()] = textureDeleteList[texture->getPath()] + 1; + } else { + printf("Texture will not be converted, keeping smallest texture [%s]\n", texture->getPath().c_str()); + textureDeleteList[file] = textureDeleteList[file] + 1; + } + } else if (convertTextureToFormat == "bmp") { + texture->getPixmap()->saveBmp(file); + newSize = getFileSize(file); + if (keepsmallest == false || newSize <= originalSize) { + textureDeleteList[texture->getPath()] = textureDeleteList[texture->getPath()] + 1; + } else { + printf("Texture will not be converted, keeping smallest texture [%s]\n", texture->getPath().c_str()); + textureDeleteList[file] = textureDeleteList[file] + 1; + } + } else if (convertTextureToFormat == "jpg") { + texture->getPixmap()->saveJpg(file); + newSize = getFileSize(file); + if (keepsmallest == false || newSize <= originalSize) { + textureDeleteList[texture->getPath()] = textureDeleteList[texture->getPath()] + 1; + } else { + printf("Texture will not be converted, keeping smallest texture [%s]\n", texture->getPath().c_str()); + textureDeleteList[file] = textureDeleteList[file] + 1; + } + } else if (convertTextureToFormat == "png") { + texture->getPixmap()->savePng(file); + newSize = getFileSize(file); + if (keepsmallest == false || newSize <= originalSize) { + textureDeleteList[texture->getPath()] = textureDeleteList[texture->getPath()] + 1; + } else { + printf("Texture will not be converted, keeping smallest texture [%s]\n", texture->getPath().c_str()); + textureDeleteList[file] = textureDeleteList[file] + 1; + } + } else { + throw megaglest_runtime_error("Unsupported texture format: [" + convertTextureToFormat + "]"); + } + + //textureManager->endTexture(texture); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Save, load new texture [%s] originalSize [%ld] newSize [%ld]\n", file.c_str(), originalSize, newSize); + + if (keepsmallest == false || newSize <= originalSize) { + texture = loadMeshTexture(meshIndex, i, textureManager, file, + meshTextureChannelCount[i], + texturesOwned[i], + false, + NULL, + "", + modelFile); + } + } + + file = extractFileFromDirectoryPath(texture->getPath()); + + if (file.length() > mapPathSize) { + throw megaglest_runtime_error("file.length() > mapPathSize, file.length() = " + intToStr(file.length())); + } else if (file.length() == 0) { + throw megaglest_runtime_error("file.length() == 0"); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Save, new texture file [%s]\n", file.c_str()); + + memset(&cMapPath[0], 0, mapPathSize); + memcpy(&cMapPath[0], file.c_str(), file.length()); + } + + fwrite(cMapPath, mapPathSize, 1, f); + } + flag *= 2; + } + + //read data + fwrite(vertices, sizeof(Vec3f)*frameCount*vertexCount, 1, f); + fwrite(normals, sizeof(Vec3f)*frameCount*vertexCount, 1, f); + if (meshHeader.textures != 0) { + fwrite(texCoords, sizeof(Vec2f)*vertexCount, 1, f); + } + fwrite(indices, sizeof(uint32)*indexCount, 1, f); + } + + void Mesh::computeTangents() { + delete[] tangents; + try { + tangents = new Vec3f[vertexCount]; + } catch (bad_alloc& ba) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error on line: %d size: %d msg: %s\n", __LINE__, vertexCount, ba.what()); + throw megaglest_runtime_error(szBuf); + } + + for (unsigned int i = 0; i < vertexCount; ++i) { + tangents[i] = Vec3f(0.f); + } + + for (unsigned int i = 0; i < indexCount; i += 3) { + for (int j = 0; j < 3; ++j) { + uint32 i0 = indices[i + j]; + uint32 i1 = indices[i + (j + 1) % 3]; + uint32 i2 = indices[i + (j + 2) % 3]; + + Vec3f p0 = vertices[i0]; + Vec3f p1 = vertices[i1]; + Vec3f p2 = vertices[i2]; + + float u0 = texCoords[i0].x; + float u1 = texCoords[i1].x; + float u2 = texCoords[i2].x; + + float v0 = texCoords[i0].y; + float v1 = texCoords[i1].y; + float v2 = texCoords[i2].y; + + tangents[i0] += + ((p2 - p0)*(v1 - v0) - (p1 - p0)*(v2 - v0)) / + ((u2 - u0)*(v1 - v0) - (u1 - u0)*(v2 - v0)); + } + } + + for (unsigned int i = 0; i < vertexCount; ++i) { + /*Vec3f binormal= normals[i].cross(tangents[i]); + tangents[i]+= binormal.cross(normals[i]);*/ + tangents[i].normalize(); + } + } + + void Mesh::deletePixels() { + for (int i = 0; i < meshTextureCount; ++i) { + if (textures[i] != NULL) { + textures[i]->deletePixels(); + } + } + } + + // =============================================== + // class Model + // =============================================== + + // ==================== constructor & destructor ==================== + + Model::Model() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + + meshCount = 0; + meshes = NULL; + fileVersion = 0; + textureManager = NULL; + lastTData = -1; + lastCycleData = false; + lastTVertex = -1; + lastCycleVertex = false; + } + + Model::~Model() { + if (meshes) delete[] meshes; + meshes = NULL; + } + + // ==================== data ==================== + + void Model::buildInterpolationData() const { + for (unsigned int i = 0; i < meshCount; ++i) { + meshes[i].buildInterpolationData(); + } + } + + void Model::updateInterpolationData(float t, bool cycle) { + if (lastTData != t || lastCycleData != cycle) { + for (unsigned int i = 0; i < meshCount; ++i) { + meshes[i].updateInterpolationData(t, cycle); + } + lastTData = t; + lastCycleData = cycle; + } + } + + void Model::updateInterpolationVertices(float t, bool cycle) { + if (lastTVertex != t || lastCycleVertex != cycle) { + for (unsigned int i = 0; i < meshCount; ++i) { + meshes[i].updateInterpolationVertices(t, cycle); + } + lastTVertex = t; + lastCycleVertex = cycle; + } + } + + // ==================== get ==================== + + uint32 Model::getTriangleCount() const { + uint32 triangleCount = 0; + for (uint32 i = 0; i < meshCount; ++i) { + triangleCount += meshes[i].getIndexCount() / 3; + } + return triangleCount; + } + + uint32 Model::getVertexCount() const { + uint32 vertexCount = 0; + for (uint32 i = 0; i < meshCount; ++i) { + vertexCount += meshes[i].getVertexCount(); + } + return vertexCount; + } + + // ==================== io ==================== + + void Model::load(const string &path, bool deletePixMapAfterLoad, + std::map > > *loadedFileList, string *sourceLoader) { + + this->sourceLoader = (sourceLoader != NULL ? *sourceLoader : ""); + this->fileName = path; + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + size_t pos = path.find_last_of('.'); + string extension = toLower(path.empty() == false ? path.substr(pos + 1) : ""); + if (extension == "g3d") { + loadG3d(path, deletePixMapAfterLoad, loadedFileList, this->sourceLoader); + } else { + throw megaglest_runtime_error("#1 Unknown model format [" + extension + "] file [" + path + "]"); + } + } + + void Model::save(const string &path, string convertTextureToFormat, + bool keepsmallest) { + string extension = (path.empty() == false ? path.substr(path.find_last_of('.') + 1) : ""); + if (toLower(extension) == "g3d") { + saveG3d(path, convertTextureToFormat, keepsmallest); + } else { + throw megaglest_runtime_error("#2 Unknown model format [" + extension + "] file [" + path + "]"); + } + } + + //load a model from a g3d file + void Model::loadG3d(const string &path, bool deletePixMapAfterLoad, + std::map > > *loadedFileList, + string sourceLoader) { + + try { +#ifdef WIN32 + FILE *f = _wfopen(utf8_decode(path).c_str(), L"rb"); +#else + FILE *f = fopen(path.c_str(), "rb"); +#endif + if (f == NULL) { + printf("In [%s::%s] cannot load file = [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, path.c_str()); + throw megaglest_runtime_error("Error opening g3d model file [" + path + "]", true); + } + + if (loadedFileList) { + (*loadedFileList)[path].push_back(make_pair(sourceLoader, sourceLoader)); + } + + string dir = extractDirectoryPathFromFile(path); + + //file header + FileHeader fileHeader; + size_t readBytes = fread(&fileHeader, sizeof(FileHeader), 1, f); + if (readBytes != 1) { + fclose(f); + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianFileHeader(fileHeader); + + char fileId[4] = ""; + memset(&fileId[0], 0, 4); + memcpy(&fileId[0], reinterpret_cast(fileHeader.id), 3); + + if (strncmp(fileId, "G3D", 3) != 0) { + fclose(f); + f = NULL; + printf("In [%s::%s] file = [%s] fileheader.id = [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, path.c_str(), fileId); + throw megaglest_runtime_error("Not a valid G3D model", true); + } + fileVersion = fileHeader.version; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Load model, fileVersion = %d\n", fileVersion); + + //version 4 + if (fileHeader.version == 4) { + //model header + ModelHeader modelHeader; + readBytes = fread(&modelHeader, sizeof(ModelHeader), 1, f); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + fromEndianModelHeader(modelHeader); + + meshCount = modelHeader.meshCount; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("meshCount = %d\n", meshCount); + + if (modelHeader.type != mtMorphMesh) { + throw megaglest_runtime_error("Invalid model type"); + } + + //load meshes + try { + meshes = new Mesh[meshCount]; + } catch (bad_alloc& ba) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error on line: %d size: %d msg: %s\n", __LINE__, meshCount, ba.what()); + throw megaglest_runtime_error(szBuf); + } + + for (uint32 i = 0; i < meshCount; ++i) { + meshes[i].load(i, dir, f, textureManager, deletePixMapAfterLoad, + loadedFileList, sourceLoader, path); + meshes[i].buildInterpolationData(); + } + } + //version 3 + else if (fileHeader.version == 3) { + readBytes = fread(&meshCount, sizeof(meshCount), 1, f); + if (readBytes != 1 && meshCount != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u] on line: %d.", readBytes, meshCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + meshCount = Shared::PlatformByteOrder::fromCommonEndian(meshCount); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("meshCount = %u\n", meshCount); + + try { + meshes = new Mesh[meshCount]; + } catch (bad_alloc& ba) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error on line: %d size: %d msg: %s\n", __LINE__, meshCount, ba.what()); + throw megaglest_runtime_error(szBuf); + } + + for (uint32 i = 0; i < meshCount; ++i) { + meshes[i].loadV3(i, dir, f, textureManager, deletePixMapAfterLoad, + loadedFileList, sourceLoader, path); + meshes[i].buildInterpolationData(); + } + } + //version 2 + else if (fileHeader.version == 2) { + readBytes = fread(&meshCount, sizeof(meshCount), 1, f); + if (readBytes != 1 && meshCount != 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " [%u] on line: %d.", readBytes, meshCount, __LINE__); + throw megaglest_runtime_error(szBuf); + } + meshCount = Shared::PlatformByteOrder::fromCommonEndian(meshCount); + + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("meshCount = %d\n", meshCount); + + try { + meshes = new Mesh[meshCount]; + } catch (bad_alloc& ba) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error on line: %d size: %d msg: %s\n", __LINE__, meshCount, ba.what()); + throw megaglest_runtime_error(szBuf); + } + + for (uint32 i = 0; i < meshCount; ++i) { + meshes[i].loadV2(i, dir, f, textureManager, deletePixMapAfterLoad, + loadedFileList, sourceLoader, path); + meshes[i].buildInterpolationData(); + } + } else { + throw megaglest_runtime_error("Invalid model version: " + intToStr(fileHeader.version)); + } + + fclose(f); + + autoJoinMeshFrames(); + } catch (megaglest_runtime_error& ex) { + //printf("1111111 ex.wantStackTrace() = %d\n",ex.wantStackTrace()); + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + //printf("2222222\n"); + throw megaglest_runtime_error("Exception caught loading 3d file: " + path + "\n" + ex.what(), !ex.wantStackTrace()); + } catch (exception &e) { + //abort(); + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what()); + throw megaglest_runtime_error("Exception caught loading 3d file: " + path + "\n" + e.what()); + } + } + + //save a model to a g3d file + void Model::saveG3d(const string &path, string convertTextureToFormat, + bool keepsmallest) { + string tempModelFilename = path + "cvt"; + +#ifdef WIN32 + FILE *f = _wfopen(utf8_decode(tempModelFilename).c_str(), L"wb"); +#else + FILE *f = fopen(tempModelFilename.c_str(), "wb"); +#endif + if (f == NULL) { + throw megaglest_runtime_error("Cant open file for writing: [" + tempModelFilename + "]"); + } + + convertTextureToFormat = toLower(convertTextureToFormat); + + //file header + FileHeader fileHeader; + fileHeader.id[0] = 'G'; + fileHeader.id[1] = '3'; + fileHeader.id[2] = 'D'; + fileHeader.version = 4; + + fwrite(&fileHeader, sizeof(FileHeader), 1, f); + + // file versions + if (fileHeader.version == 4 || fileHeader.version == 3 || fileHeader.version == 2) { + //model header + ModelHeader modelHeader; + modelHeader.meshCount = meshCount; + modelHeader.type = mtMorphMesh; + + fwrite(&modelHeader, sizeof(ModelHeader), 1, f); + + std::map textureDeleteList; + for (uint32 i = 0; i < meshCount; ++i) { + meshes[i].save(i, tempModelFilename, f, textureManager, + convertTextureToFormat, textureDeleteList, + keepsmallest, path); + } + + removeFile(path); + if (renameFile(tempModelFilename, path) == true) { + // Now delete old textures since they were converted to a new format + for (std::map::iterator iterMap = textureDeleteList.begin(); + iterMap != textureDeleteList.end(); ++iterMap) { + removeFile(iterMap->first); + } + } + } else { + throw megaglest_runtime_error("Invalid model version: " + intToStr(fileHeader.version)); + } + + fclose(f); + } + + void Model::deletePixels() { + for (uint32 i = 0; i < meshCount; ++i) { + meshes[i].deletePixels(); + } + } + + class MeshContainer { + protected: + int indexValue; + std::vector meshes; + + public: + + MeshContainer() { + this->indexValue = -1; + } + void add(int index, Mesh *mesh) { + if (this->indexValue < 0) { + this->indexValue = index; + } + meshes.push_back(mesh); + } + int index() { + return indexValue; + } + int size() { + return (int) meshes.size(); + } + std::vector get() { + return meshes; + } + }; + + void Mesh::setVertices(Vec3f *data, uint32 count) { + delete[] this->vertices; + this->vertices = data; + + this->vertexCount = count; + } + void Mesh::setNormals(Vec3f *data, uint32 count) { + delete[] this->normals; + this->normals = data; + + this->vertexCount = count; + } + + void Mesh::setTexCoords(Vec2f *data, uint32 count) { + delete[] this->texCoords; + this->texCoords = data; + + this->vertexCount = count; + } + + void Mesh::setIndices(uint32 *data, uint32 count) { + delete[] this->indices; + this->indices = data; + + this->indexCount = count; + } + + void Mesh::copyInto(Mesh *dest, bool ignoreInterpolationData, + bool destinationOwnsTextures) { + + for (int index = 0; index < meshTextureCount; ++index) { + dest->textures[index] = this->textures[index]; + dest->texturesOwned[index] = this->texturesOwned[index]; + dest->texturePaths[index] = this->texturePaths[index]; + + if (destinationOwnsTextures == true) { + this->texturesOwned[index] = false; + } + } + + dest->name = this->name; + //vertex data counts + dest->frameCount = this->frameCount; + dest->vertexCount = this->vertexCount; + dest->indexCount = this->indexCount; + dest->texCoordFrameCount = this->texCoordFrameCount; + + //vertex data + if (dest->vertices != NULL) { + delete[] dest->vertices; + dest->vertices = NULL; + } + if (this->vertices != NULL) { + dest->vertices = new Vec3f[this->frameCount * this->vertexCount]; + memcpy(&dest->vertices[0], &this->vertices[0], this->frameCount * this->vertexCount * sizeof(Vec3f)); + } + + if (dest->normals != NULL) { + delete[] dest->normals; + dest->normals = NULL; + } + if (this->normals != NULL) { + dest->normals = new Vec3f[this->frameCount * this->vertexCount]; + memcpy(&dest->normals[0], &this->normals[0], this->frameCount * this->vertexCount * sizeof(Vec3f)); + } + + if (dest->texCoords != NULL) { + delete[] dest->texCoords; + dest->texCoords = NULL; + } + if (this->texCoords != NULL) { + dest->texCoords = new Vec2f[this->vertexCount]; + memcpy(&dest->texCoords[0], &this->texCoords[0], this->vertexCount * sizeof(Vec2f)); + } + + if (dest->tangents != NULL) { + delete[] dest->tangents; + dest->tangents = NULL; + } + if (this->tangents != NULL) { + dest->tangents = new Vec3f[this->vertexCount]; + memcpy(&dest->tangents[0], &this->tangents[0], this->vertexCount * sizeof(Vec3f)); + } + + if (dest->indices != NULL) { + delete[] dest->indices; + dest->indices = NULL; + } + if (this->indices != NULL) { + dest->indices = new uint32[this->indexCount]; + memcpy(&dest->indices[0], &this->indices[0], this->indexCount * sizeof(uint32)); + } + + //material data + dest->diffuseColor = this->diffuseColor; + dest->specularColor = this->specularColor; + dest->specularPower = this->specularPower; + dest->opacity = this->opacity; + + //properties + dest->twoSided = this->twoSided; + dest->customColor = this->customColor; + dest->noSelect = this->noSelect; + dest->glow = this->glow; + + dest->textureFlags = this->textureFlags; + + if (ignoreInterpolationData == false) { + dest->interpolationData = this->interpolationData; + } + dest->textureManager = this->textureManager; + + // Vertex Buffer Object Names + dest->hasBuiltVBOs = this->hasBuiltVBOs; + dest->m_nVBOVertices = this->m_nVBOVertices; + dest->m_nVBOTexCoords = this->m_nVBOTexCoords; + dest->m_nVBONormals = this->m_nVBONormals; + dest->m_nVBOIndexes = this->m_nVBOIndexes; + } + + void Model::autoJoinMeshFrames() { + + /* + print "auto-joining compatible meshes..." + meshes = {} + for mesh in self.meshes: + key = (mesh.texture,mesh.frame_count,mesh.twoSided|mesh.customColour) + if key in meshes: + meshes[key].append(mesh) + else: + meshes[key] = [mesh] + for joinable in meshes.values(): + if len(joinable) < 2: continue + base = joinable[0] + print "\tjoining to",base + for mesh in joinable[1:]: + if base.index_count+mesh.index_count > 0xffff: + base = mesh + print "\tjoining to",base + continue + print "\t\t",mesh + for a,b in zip(base.frames,mesh.frames): + a.vertices.extend(b.vertices) + a.normals.extend(b.normals) + if base.texture: + base.textures.extend(mesh.textures) + base.indices.extend(index+base.vertex_count for index in mesh.indices) + base.vertex_count += mesh.vertex_count + base.index_count += mesh.index_count + self.meshes.remove(mesh) + */ + + + + bool haveJoinedMeshes = false; + + // First looks for meshes with same texture in the same frame + std::map joinedMeshes; + for (uint32 index = 0; index < meshCount; ++index) { + Mesh &mesh = meshes[index]; + + // Duplicate mesh vertices are considered to be those with the same + // 1. texture 2. framecount 3. twosided flag value 4. same custom texture color + + // It's possible the texture is missing and will be NULL + // if(mesh.getTextureFlags() & 1) { + // printf("Mesh has textures:\n"); + // for(unsigned int meshTexIndex = 0; meshTexIndex < meshTextureCount; ++meshTexIndex) { + // printf("Mesh texture index: %d [%p] [%s]\n",meshTexIndex,mesh.getTexture(meshTexIndex),(mesh.getTexture(meshTexIndex) != NULL ? mesh.getTexture(meshTexIndex)->getPath().c_str() : "n/a")); + // } + // } + string mesh_key = ((mesh.getTextureFlags() & 1) && mesh.getTexture(0) ? mesh.getTexture(0)->getPath() : "none"); + mesh_key += string("_") + intToStr(mesh.getFrameCount()) + + string("_") + intToStr(mesh.getTwoSided()) + + string("_") + intToStr(mesh.getCustomTexture()) + + string("_") + intToStr(mesh.getNoSelect()) + + string("_") + floatToStr(mesh.getOpacity()) + + string("_") + floatToStr(mesh.getGlow()) + + string("_") + mesh.getDiffuseColor().getString() + + string("_") + mesh.getSpecularColor().getString() + + string("_") + floatToStr(mesh.getSpecularPower()); + + joinedMeshes[mesh_key].add(index, &mesh); + if (haveJoinedMeshes == false && joinedMeshes[mesh_key].size() > 1) { + haveJoinedMeshes = true; + } + } + if (haveJoinedMeshes == true) { + //printf("*** Detected Joined meshes for model [%s]\n",fileName.c_str()); + + // We have mesh data to join we now create a list in the same order + // as the original meshes but each index will have 1 or more meshes + // This is done to maintain original mesh ordering + std::map > orderedMeshes; + for (std::map::iterator iterMap = joinedMeshes.begin(); + iterMap != joinedMeshes.end(); ++iterMap) { + orderedMeshes[iterMap->second.index()] = iterMap->second.get(); + + //if(iterMap->second.size() > 1) { + // printf("Key [%s] joined meshes: %d\n",iterMap->first.c_str(),iterMap->second.size()); + //} + } + + // Now the real work of creating a new list of joined mesh data + Mesh *joinedMeshList = new Mesh[joinedMeshes.size()]; + + int index = 0; + for (std::map >::iterator iterMap = orderedMeshes.begin(); + iterMap != orderedMeshes.end(); ++iterMap) { + //printf("Join index: %d joincount: %d\n",index,iterMap->second.size()); + + Mesh *base = &joinedMeshList[index]; + + // Deep copy mesh data + iterMap->second[0]->copyInto(base, true, true); + + if (iterMap->second.size() > 1) { + // Time to join mesh data for this mesh + for (unsigned int joinIndex = 1; + joinIndex < iterMap->second.size(); ++joinIndex) { + Mesh *mesh = iterMap->second[joinIndex]; + //if(base->getIndexCount() + mesh->getIndexCount() > 0xffff) { + // printf("Not exactly sure what this IF statement is for?\n"); + // mesh->copyInto(base, true, true); + //} + //else { + // Need to add verticies for each from from mesh to base + uint32 originalBaseVertexCount = base->getVertexCount(); + + uint32 newVertexCount = + base->getVertexCount() + mesh->getVertexCount(); + + uint32 newVertexFrameCount = + (base->getFrameCount() * newVertexCount); + + Vec3f *joined_vertices = new Vec3f[newVertexFrameCount]; + Vec3f *joined_normals = new Vec3f[newVertexFrameCount]; + uint32 join_index = 0; + + // Join mesh vertices and normals + for (unsigned int frameIndex = 0; + frameIndex < base->getFrameCount(); ++frameIndex) { + uint32 baseIndex = frameIndex * originalBaseVertexCount; + uint32 meshIndex = frameIndex * mesh->getVertexCount(); + //uint32 appendBaseJoinIndex = frameIndex * newVertexCount; + + // first original mesh values get copied + memcpy(&joined_vertices[join_index], + &base->getVertices()[baseIndex], + originalBaseVertexCount * sizeof(Vec3f)); + memcpy(&joined_normals[join_index], + &base->getNormals()[baseIndex], + originalBaseVertexCount * sizeof(Vec3f)); + join_index += originalBaseVertexCount; + + // second joined mesh values get copied + memcpy(&joined_vertices[join_index], + &mesh->getVertices()[meshIndex], + mesh->getVertexCount() * sizeof(Vec3f)); + memcpy(&joined_normals[join_index], + &mesh->getNormals()[meshIndex], + mesh->getVertexCount() * sizeof(Vec3f)); + join_index += mesh->getVertexCount(); + } + + // update vertex and normal buffers with joined mesh data + base->setVertices(joined_vertices, newVertexCount); + base->setNormals(joined_normals, newVertexCount); + + // If we have texture coords join them + if (base->getTextureFlags() & 1) { + Vec2f *joined_texCoords = new Vec2f[newVertexCount]; + + // update texture coord buffers with joined mesh data + memcpy(&joined_texCoords[0], + &base->getTexCoords()[0], + originalBaseVertexCount * sizeof(Vec2f)); + memcpy(&joined_texCoords[originalBaseVertexCount], + &mesh->getTexCoords()[0], + mesh->getVertexCount() * sizeof(Vec2f)); + + base->setTexCoords(joined_texCoords, newVertexCount); + } + + // update index buffers with joined mesh data + uint32 newindexCount = base->getIndexCount() + mesh->getIndexCount(); + uint32 *joined_indexes = new uint32[newindexCount]; + + uint32 join_index_index = 0; + memcpy(&joined_indexes[join_index_index], + &base->getIndices()[0], + base->getIndexCount() * sizeof(uint32)); + join_index_index += base->getIndexCount(); + + for (unsigned int meshIndex = 0; + meshIndex < mesh->getIndexCount(); ++meshIndex) { + uint32 index_value = mesh->getIndices()[meshIndex]; + + // join index values + joined_indexes[join_index_index] = index_value + originalBaseVertexCount; + join_index_index++; + } + base->setIndices(joined_indexes, newindexCount); + //} + } + } + base->buildInterpolationData(); + + index++; + } + + delete[] meshes; + meshes = joinedMeshList; + meshCount = (uint32) joinedMeshes.size(); + } + } + + // ---------------------------------------------------------------------------- + + bool PixelBufferWrapper::isPBOEnabled = false; + int PixelBufferWrapper::index = 0; + vector PixelBufferWrapper::pboIds; + + PixelBufferWrapper::PixelBufferWrapper(int pboCount, int bufferSize) { + this->bufferSize = bufferSize; + //if(isGlExtensionSupported("GL_ARB_pixel_buffer_object") == true && + if (GLEW_ARB_pixel_buffer_object) { + PixelBufferWrapper::isPBOEnabled = true; + cleanup(); + // For some wacky reason this fails in VC++ 2008 + //pboIds.reserve(pboCount); + //glGenBuffersARB(pboCount, (GLuint*)&pboIds[0]); + // + + /* + for(int i = 0; i < pboCount; ++i) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("PBO Gen i = %d\n",i); + + pboIds.push_back(0); + glGenBuffersARB(1, (GLuint*)&pboIds[i]); + // create pixel buffer objects, you need to delete them when program exits. + // glBufferDataARB with NULL pointer reserves only memory space. + glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[i]); + glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, bufferSize, 0, GL_STREAM_READ_ARB); + } + glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); + */ + addBuffersToPixelBuf(pboCount); + } + } + + void PixelBufferWrapper::addBuffersToPixelBuf(int pboCount) { + int iStartIndex = pboIds.size(); + for (int i = 0; i < pboCount; ++i) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("PBO Gen i = %d\n", i); + + pboIds.push_back(0); + glGenBuffersARB(1, (GLuint*) &pboIds[i + iStartIndex]); + // create pixel buffer objects, you need to delete them when program exits. + // glBufferDataARB with NULL pointer reserves only memory space. + glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[i + iStartIndex]); + glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, bufferSize, 0, GL_STREAM_READ_ARB); + } + glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); + } + + Pixmap2D *PixelBufferWrapper::getPixelBufferFor(int x, int y, int w, int h, int colorComponents) { + Pixmap2D *pixmapScreenShot = NULL; + if (PixelBufferWrapper::isPBOEnabled == true) { + string codeSection = "A"; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + try { + // increment current index first then get the next index + // "index" is used to read pixels from a framebuffer to a PBO + // "nextIndex" is used to process pixels in the other PBO + index = (index + 1) % 2; + + codeSection = "B"; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + // Check for out of range + if (index >= (int) pboIds.size()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error / Warning in [%s::%s] on line: %d pixel buffer out of range, index: %d size: %d, attempting to expand buffer...\n", __FILE__, __FUNCTION__, __LINE__, index, (int) pboIds.size()); + //throw megaglest_runtime_error(szBuf); + SystemFlags::OutputDebug(SystemFlags::debugError, "%s", szBuf); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] szBuf: %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, szBuf); + + codeSection = "C"; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + addBuffersToPixelBuf((index - pboIds.size()) + 1); + } + // pbo index used for next frame + //int nextIndex = (index + 1) % 2; + + codeSection = "D"; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + // read framebuffer /////////////////////////////// + // copy pixels from framebuffer to PBO + // Use offset instead of pointer. + // OpenGL should perform asynch DMA transfer, so glReadPixels() will return immediately. + glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[index]); + //glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[nextIndex]); + + codeSection = "E"; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + //glPixelStorei(GL_PACK_ALIGNMENT, 1); + glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, 0); + //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + // measure the time reading framebuffer + //t1.stop(); + //readTime = t1.getElapsedTimeInMilliSec(); + + // process pixel data ///////////////////////////// + //t1.start(); + + codeSection = "F"; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + // map the PBO that contain framebuffer pixels before processing it + //glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[nextIndex]); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[index]); + + codeSection = "G"; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + GLubyte* src = (GLubyte*) glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB); + if (src) { + codeSection = "H"; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + pixmapScreenShot = new Pixmap2D(w, h, colorComponents); + + codeSection = "I"; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + memcpy(pixmapScreenShot->getPixels(), src, pixmapScreenShot->getPixelByteCount()); + + codeSection = "J"; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB); // release pointer to the mapped buffer + //pixmapScreenShot->save("debugPBO.png"); + } + codeSection = "K"; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + // measure the time reading framebuffer + //t1.stop(); + //processTime = t1.getElapsedTimeInMilliSec(); + glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } catch (megaglest_runtime_error& ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] codeSection [%s] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, codeSection.c_str(), ex.what()); + throw megaglest_runtime_error("Exception caught in getPixelBufferFor codeSection: " + codeSection + "\n" + ex.what(), !ex.wantStackTrace()); + } catch (exception &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] codeSection [%s] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, codeSection.c_str(), e.what()); + throw megaglest_runtime_error("Exception caught in getPixelBufferFor codeSection: " + codeSection + "\n" + e.what()); + } catch (...) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] codeSection [%s] UNKNOWN Error!", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, codeSection.c_str()); + throw megaglest_runtime_error("UNKNOWN Exception caught in getPixelBufferFor codeSection: " + codeSection + "\n"); + } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + return pixmapScreenShot; + } + + void PixelBufferWrapper::begin() { + if (PixelBufferWrapper::isPBOEnabled == true) { + // set the framebuffer to read + //glReadBuffer(GL_FRONT); + } + } + + void PixelBufferWrapper::end() { + if (PixelBufferWrapper::isPBOEnabled == true) { + // set the framebuffer to read + //glReadBuffer(GL_BACK); + } + } + + void PixelBufferWrapper::cleanup() { + if (PixelBufferWrapper::isPBOEnabled == true) { + if (pboIds.empty() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("PBO Delete size = %d\n", (int) pboIds.size()); + + glDeleteBuffersARB((int) pboIds.size(), &pboIds[0]); + pboIds.clear(); + + glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); + } + } + } + + PixelBufferWrapper::~PixelBufferWrapper() { + cleanup(); + } + + // --------------------------------------------------------------------------- + + int BaseColorPickEntity::bufferSizeRequired = -1; + const unsigned int BaseColorPickEntity::p = 64007; + const unsigned int BaseColorPickEntity::k = 43067; + unsigned int BaseColorPickEntity::nextColorRGB = BaseColorPickEntity::k; + + unsigned char BaseColorPickEntity::nextColorID[COLOR_COMPONENTS] = { 1, 1, 1, 0 }; + auto_ptr BaseColorPickEntity::pbo; + //auto_ptr BaseColorPickEntity::cachedPixels; + + map BaseColorPickEntity::usedColorIDList; + bool BaseColorPickEntity::trackColorUse = true; + + vector > BaseColorPickEntity::nextColorIDReuseList; + + bool BaseColorPickEntity::using_loop_method = false; + + BaseColorPickEntity::BaseColorPickEntity() { + if (BaseColorPickEntity::bufferSizeRequired != -1) { + BaseColorPickEntity::init(BaseColorPickEntity::bufferSizeRequired); + } + uniqueColorID[0] = 0; + uniqueColorID[1] = 0; + uniqueColorID[2] = 0; + uniqueColorID[3] = 0; + assign_color(); + } + + bool BaseColorPickEntity::get_next_assign_color(unsigned char *assign_to) { + + if (assign_to == NULL) { + throw megaglest_runtime_error("assign_to == NULL"); + } + + if (BaseColorPickEntity::using_loop_method == true) { + assign_color_using_loop(assign_to); + } else { + assign_color_using_prime(assign_to); + } + + bool isDuplicate = false; + if (BaseColorPickEntity::trackColorUse == true) { + string color_key = getColorDescription(); + //printf("Assigned color [%s]\n",color_key.c_str()); + + if (usedColorIDList.find(color_key) == usedColorIDList.end()) { + usedColorIDList[color_key] = true; + + //printf("Color added to used list [%s] usedColorIDList = %d nextColorIDReuseList = %d!\n",color_key.c_str(),(int)usedColorIDList.size(),(int)nextColorIDReuseList.size()); + } else { + isDuplicate = true; + printf("Line ref: %d *WARNING* color [%s] used count: %d using_loop: %d ALREADY in history list!\n", __LINE__, color_key.c_str(), (int) usedColorIDList.size(), BaseColorPickEntity::using_loop_method); + } + } + return isDuplicate; + } + + void BaseColorPickEntity::assign_color() { + get_next_assign_color(&uniqueColorID[0]); + } + + void BaseColorPickEntity::assign_color_using_prime(unsigned char *assign_to) { + nextColorRGB = (nextColorRGB * k) % p; + + // nextColorID is a 16-bit (hi)colour (for players with 16-bit display depths) + // we expand it to true-color for use with OpenGL + + const unsigned int + r = (nextColorRGB >> 11) & ((1 << 5) - 1), + g = (nextColorRGB >> 5) & ((1 << 6) - 1), + b = nextColorRGB & ((1 << 5) - 1); + + assign_to[0] = r << 3; + assign_to[1] = g << 2; + assign_to[2] = b << 3; + } + + void BaseColorPickEntity::assign_color_using_loop(unsigned char *assign_to) { + if (nextColorIDReuseList.empty() == false) { + //printf("Color being reused [%u.%u.%u] usedColorIDList = %d nextColorIDReuseList = %d!\n",nextColorIDReuseList.back()[0],nextColorIDReuseList.back()[1],nextColorIDReuseList.back()[2],(int)usedColorIDList.size(),(int)nextColorIDReuseList.size()); + + assign_to[0] = nextColorIDReuseList.back()[0]; + assign_to[1] = nextColorIDReuseList.back()[1]; + assign_to[2] = nextColorIDReuseList.back()[2]; + + nextColorIDReuseList.pop_back(); + + string color_key = getColorDescription(); + if (usedColorIDList.find(color_key) == usedColorIDList.end()) { + //usedColorIDList[color_key] = true; + //printf("Color added to used list [%s] usedColorIDList = %d nextColorIDReuseList = %d!\n",color_key.c_str(),(int)usedColorIDList.size(),(int)nextColorIDReuseList.size()); + } else { + printf("Line ref: %d *WARNING* color [%s] ALREADY FOUND in history list!\n", __LINE__, color_key.c_str()); + assign_color_using_loop(assign_to); + } + } else { + assign_to[0] = nextColorID[0]; + assign_to[1] = nextColorID[1]; + assign_to[2] = nextColorID[2]; + + const int colorSpacing = 8; + + if ((int) (nextColorID[0] + colorSpacing) <= 255) { + nextColorID[0] += colorSpacing; + } else { + nextColorID[0] = 1; + if ((int) (nextColorID[1] + colorSpacing) <= 255) { + nextColorID[1] += colorSpacing; + } else { + nextColorID[1] = 1; + if ((int) (nextColorID[2] + colorSpacing) <= 255) { + nextColorID[2] += colorSpacing; + } else { + + printf("Color rolled over on 3rd level usedColorIDList = %d!\n", (int) usedColorIDList.size()); + + nextColorID[0] = 1; + nextColorID[1] = 1; + nextColorID[2] = 1; + + + // nextColorID[2] = 1; + // nextColorID[3]+=colorSpacing; + // + // if(nextColorID[3] > 255) { + // nextColorID[0] = 1; + // nextColorID[1] = 1; + // nextColorID[2] = 1; + // nextColorID[3] = 1; + // } + } + } + } + } + } + + void BaseColorPickEntity::recycleUniqueColor() { + + vector reUseColor; + reUseColor.push_back(uniqueColorID[0]); + reUseColor.push_back(uniqueColorID[1]); + reUseColor.push_back(uniqueColorID[2]); + nextColorIDReuseList.push_back(reUseColor); + + //printf("RECYCLE Color [%u.%u.%u] usedColorIDList = %d nextColorIDReuseList = %d!\n",reUseColor[0],reUseColor[1],reUseColor[2],(int)usedColorIDList.size(),(int)nextColorIDReuseList.size()); + + if (usedColorIDList.empty() == false) { + string color_key = getColorDescription(); + usedColorIDList.erase(color_key); + //printf("REMOVING used Color [%s] usedColorIDList = %d nextColorIDReuseList = %d!\n",color_key.c_str(),(int)usedColorIDList.size(),(int)nextColorIDReuseList.size()); + //printf("Line ref: %d *WARNING* color [%s] used count: %d NOT FOUND in history list!\n",__LINE__,color_key.c_str(),(int)usedColorIDList.size()); + } + } + + void BaseColorPickEntity::resetUniqueColors() { + BaseColorPickEntity::nextColorRGB = BaseColorPickEntity::k; + + BaseColorPickEntity::nextColorID[0] = 1; + BaseColorPickEntity::nextColorID[1] = 1; + BaseColorPickEntity::nextColorID[2] = 1; + + usedColorIDList.clear(); + nextColorIDReuseList.clear(); + } + void BaseColorPickEntity::init(int bufferSize) { + if (BaseColorPickEntity::pbo.get() == NULL) { + //printf("BaseColorPickEntity::init pbo == null\n"); + BaseColorPickEntity::bufferSizeRequired = bufferSize; + BaseColorPickEntity::pbo.reset(new PixelBufferWrapper(2, BaseColorPickEntity::bufferSizeRequired)); + } else if (bufferSize != BaseColorPickEntity::bufferSizeRequired) { + //printf("BaseColorPickEntity::init pbo resize\n"); + cleanupPBO(); + BaseColorPickEntity::bufferSizeRequired = bufferSize; + BaseColorPickEntity::pbo.reset(new PixelBufferWrapper(2, BaseColorPickEntity::bufferSizeRequired)); + } + } + + void BaseColorPickEntity::cleanupPBO() { + BaseColorPickEntity::pbo.reset(0); + } + + string BaseColorPickEntity::getColorDescription() const { + char szBuf[100] = ""; + snprintf(szBuf, 100, "%d.%d.%d", uniqueColorID[0], uniqueColorID[1], uniqueColorID[2]); + string result = szBuf; + return result; + } + + void BaseColorPickEntity::beginPicking() { + // turn off texturing, lighting and fog + //glClearColor (0.0,0.0,0.0,0.0); + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //reset current background. This is neeeded to get a proper black background! + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT); + + glPushAttrib(GL_ENABLE_BIT); + //glEnable(GL_DEPTH_TEST); + glDisable(GL_TEXTURE_2D); + glDisable(GL_FOG); + glDisable(GL_LIGHTING); + glDisable(GL_BLEND); + glDisable(GL_MULTISAMPLE); + glDisable(GL_DITHER); + glDisable(GL_POLYGON_OFFSET_FILL); + glDisable(GL_NORMALIZE); + + // all off, but we want depth test + glEnable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //glPushAttrib(GL_TEXTURE_2D | GL_LIGHTING | GL_BLEND | GL_MULTISAMPLE | GL_DITHER); + //glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING_BIT | GL_POLYGON_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT | GL_NORMALIZE | GL_BLEND | GL_POLYGON_OFFSET_FILL); + } + + void BaseColorPickEntity::endPicking() { + // turn off texturing, lighting and fog + //glEnable(GL_TEXTURE_2D); + //glEnable(GL_FOG); + //glEnable(GL_LIGHTING); + + //glEnable(GL_BLEND); + //glEnable(GL_MULTISAMPLE); + //glEnable(GL_DITHER); + glPopAttrib(); + } + + vector BaseColorPickEntity::getPickedList(int x, int y, int w, int h, + const vector &rendererModels) { + vector pickedModels; + pickedModels.reserve(rendererModels.size()); + + //printf("In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + static auto_ptr cachedPixels; + //auto_ptr cachedPixels; + + //printf("PixelBufferWrapper::getIsPBOEnable() = %d\n",PixelBufferWrapper::getIsPBOEnable()); + if (rendererModels.empty() == false) { + if (PixelBufferWrapper::getIsPBOEnable() == true) { + Pixmap2D *pixmapScreenShot = BaseColorPickEntity::pbo->getPixelBufferFor(x, y, w, h, COLOR_COMPONENTS); + //pixmapScreenShot->saveTga("/tmp/toll.tga"); //### for debugging + cachedPixels.reset(pixmapScreenShot); + } else { + Pixmap2D *pixmapScreenShot = new Pixmap2D(w, h, COLOR_COMPONENTS); + //glPixelStorei(GL_PACK_ALIGNMENT, 1); + glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixmapScreenShot->getPixels()); + //pixmapScreenShot->saveTga("/tmp/toll.tga"); + cachedPixels.reset(pixmapScreenShot); + //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + } + unsigned char *pixelBuffer = cachedPixels->getPixels(); + + map modelAlreadyPickedList; + map > > colorAlreadyPickedList; + + int skipSteps = 4; + //unsigned char *oldpixel = &pixelBuffer[0]; + + // now we check the screenshot if we find pixels in color of unit identity + // to speedup we only check every "skipSteps" line and pixel in a row if we find such a color. + // this is exact enough for MG purpose + for (int hh = 0; hh < h && pickedModels.size() < rendererModels.size(); hh = hh + skipSteps) { + for (int ww = 0; ww < w && pickedModels.size() < rendererModels.size(); ww = ww + skipSteps) { + + int index = (hh*w + ww) * COLOR_COMPONENTS; + unsigned char *pixel = &pixelBuffer[index]; + //printf("pixel[0]=%d pixel[1]=%d pixel[2]=%d\n",pixel[0],pixel[1],pixel[2]); + if (pixel[0] == 0 && pixel[1] == 0 && pixel[2] == 0) { + continue; + } + // if(index>0) + // { + // oldpixel = &pixelBuffer[index-1*COLOR_COMPONENTS]; + // if(memcmp(pixel,oldpixel,3)) continue; + // } + + // Skip duplicate scanned colors + map > >::const_iterator iterFind1 = colorAlreadyPickedList.find(pixel[0]); + if (iterFind1 != colorAlreadyPickedList.end()) { + map >::const_iterator iterFind2 = iterFind1->second.find(pixel[1]); + if (iterFind2 != iterFind1->second.end()) { + map::const_iterator iterFind3 = iterFind2->second.find(pixel[2]); + if (iterFind3 != iterFind2->second.end()) { + continue; + } + } + } + + for (unsigned int i = 0; i < rendererModels.size(); ++i) { + // Skip models already selected + if (modelAlreadyPickedList.find(i) != modelAlreadyPickedList.end()) { + continue; + } + const BaseColorPickEntity *model = rendererModels[i]; + + if (model != NULL && model->isUniquePickingColor(pixel) == true) { + //printf("Found match pixel [%d.%d.%d] for model [%s] ptr [%p][%s]\n",pixel[0],pixel[1],pixel[2],model->getColorDescription().c_str(), model,model->getUniquePickName().c_str()); + + pickedModels.push_back(i); + modelAlreadyPickedList[i] = true; + colorAlreadyPickedList[pixel[0]][pixel[1]][pixel[2]] = true; + break; + } + } + } + } + + //printf("In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + //delete pixmapScreenShot; + } + //printf("In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + return pickedModels; + } + + bool BaseColorPickEntity::isUniquePickingColor(unsigned char *pixel) const { + bool result = false; + if (uniqueColorID[0] == pixel[0] && + uniqueColorID[1] == pixel[1] && + uniqueColorID[2] == pixel[2]) { + //uniqueColorID[3] == pixel[3]) { + result = true; + } + + return result; + } + + void BaseColorPickEntity::setUniquePickingColor() const { + + glColor3ub(uniqueColorID[0], + uniqueColorID[1], + uniqueColorID[2]); + + /* + glColor3f( uniqueColorID[0] / 255.0f, + uniqueColorID[1] / 255.0f, + uniqueColorID[2] / 255.0f); + //uniqueColorID[3] / 255.0f); + * + */ + } + + } - //printf("In [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return pickedModels; -} - -bool BaseColorPickEntity::isUniquePickingColor(unsigned char *pixel) const { - bool result = false; - if( uniqueColorID[0] == pixel[0] && - uniqueColorID[1] == pixel[1] && - uniqueColorID[2] == pixel[2]) { - //uniqueColorID[3] == pixel[3]) { - result = true; - } - - return result; -} - -void BaseColorPickEntity::setUniquePickingColor() const { - - glColor3ub(uniqueColorID[0], - uniqueColorID[1], - uniqueColorID[2]); - -/* - glColor3f( uniqueColorID[0] / 255.0f, - uniqueColorID[1] / 255.0f, - uniqueColorID[2] / 255.0f); - //uniqueColorID[3] / 255.0f); - * - */ -} - - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/graphics/model_manager.cpp b/source/shared_lib/sources/graphics/model_manager.cpp index cd0099731..82532a37b 100644 --- a/source/shared_lib/sources/graphics/model_manager.cpp +++ b/source/shared_lib/sources/graphics/model_manager.cpp @@ -22,85 +22,87 @@ using namespace Shared::Util; using namespace Shared::Platform; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class ModelManager -// ===================================================== + // ===================================================== + // class ModelManager + // ===================================================== -ModelManager::ModelManager(){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } + ModelManager::ModelManager() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } - textureManager= NULL; -} - -ModelManager::~ModelManager(){ - end(); -} - -Model *ModelManager::newModel(const string &path,bool deletePixMapAfterLoad,std::map > > *loadedFileList, string *sourceLoader){ - Model *model= GraphicsInterface::getInstance().getFactory()->newModel(path,textureManager,deletePixMapAfterLoad,loadedFileList,sourceLoader); - models.push_back(model); - return model; -} - -void ModelManager::init(){ - for(size_t i=0; iinit(); + textureManager = NULL; } - } -} -void ModelManager::end(){ - for(size_t i=0; iend(); - delete models[i]; - models[i]=NULL; + ModelManager::~ModelManager() { + end(); } - } - models.clear(); -} -void ModelManager::endModel(Model *model,bool mustExistInList) { - if(model != NULL) { - bool found = false; - for(unsigned int idx = 0; idx < models.size(); idx++) { - Model *curModel = models[idx]; - if(curModel == model) { - found = true; - models.erase(models.begin() + idx); - break; + Model *ModelManager::newModel(const string &path, bool deletePixMapAfterLoad, std::map > > *loadedFileList, string *sourceLoader) { + Model *model = GraphicsInterface::getInstance().getFactory()->newModel(path, textureManager, deletePixMapAfterLoad, loadedFileList, sourceLoader); + models.push_back(model); + return model; + } + + void ModelManager::init() { + for (size_t i = 0; i < models.size(); ++i) { + if (models[i] != NULL) { + models[i]->init(); + } } } - if(found == false && mustExistInList == true) { - throw std::runtime_error("found == false in endModel"); + void ModelManager::end() { + for (size_t i = 0; i < models.size(); ++i) { + if (models[i] != NULL) { + models[i]->end(); + delete models[i]; + models[i] = NULL; + } + } + models.clear(); } - model->end(); - delete model; + void ModelManager::endModel(Model *model, bool mustExistInList) { + if (model != NULL) { + bool found = false; + for (unsigned int idx = 0; idx < models.size(); idx++) { + Model *curModel = models[idx]; + if (curModel == model) { + found = true; + models.erase(models.begin() + idx); + break; + } + } + + if (found == false && mustExistInList == true) { + throw std::runtime_error("found == false in endModel"); + } + + model->end(); + delete model; + } + } + + void ModelManager::endLastModel(bool mustExistInList) { + bool found = false; + if (models.size() > 0) { + found = true; + size_t index = models.size() - 1; + Model *curModel = models[index]; + models.erase(models.begin() + index); + + curModel->end(); + delete curModel; + } + if (found == false && mustExistInList == true) { + throw std::runtime_error("found == false in endLastModel"); + } + } + + } -} - -void ModelManager::endLastModel(bool mustExistInList) { - bool found = false; - if(models.size() > 0) { - found = true; - size_t index = models.size()-1; - Model *curModel = models[index]; - models.erase(models.begin() + index); - - curModel->end(); - delete curModel; - } - if(found == false && mustExistInList == true) { - throw std::runtime_error("found == false in endLastModel"); - } -} - - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/graphics/particle.cpp b/source/shared_lib/sources/graphics/particle.cpp index 5c67d53aa..54110a5e8 100644 --- a/source/shared_lib/sources/graphics/particle.cpp +++ b/source/shared_lib/sources/graphics/particle.cpp @@ -31,2538 +31,2517 @@ using namespace Shared::Util; using namespace Shared::PlatformCommon; namespace Shared { -namespace Graphics { + namespace Graphics { -// ===================================================== -// class ParticleSystem -// ===================================================== + // ===================================================== + // class ParticleSystem + // ===================================================== -const bool checkMemory = false; -static map memoryObjectList; + const bool checkMemory = false; + static map memoryObjectList; -void Particle::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *particleNode = rootNode->addChild("Particle"); + void Particle::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *particleNode = rootNode->addChild("Particle"); -// Vec3f pos; - particleNode->addAttribute("pos",pos.getString(), mapTagReplacements); -// Vec3f lastPos; - particleNode->addAttribute("lastPos",lastPos.getString(), mapTagReplacements); -// Vec3f speed; - particleNode->addAttribute("speed",speed.getString(), mapTagReplacements); -// Vec3f speedUpRelative; - particleNode->addAttribute("speedUpRelative",floatToStr(speedUpRelative,6), mapTagReplacements); -// Vec3f speedUpConstant; - particleNode->addAttribute("speedUpConstant",speedUpConstant.getString(), mapTagReplacements); -// Vec3f accel; - particleNode->addAttribute("accel",accel.getString(), mapTagReplacements); -// Vec4f color; - particleNode->addAttribute("color",color.getString(), mapTagReplacements); -// float size; - particleNode->addAttribute("size",floatToStr(size,6), mapTagReplacements); -// int energy; - particleNode->addAttribute("energy",intToStr(energy), mapTagReplacements); -} + // Vec3f pos; + particleNode->addAttribute("pos", pos.getString(), mapTagReplacements); + // Vec3f lastPos; + particleNode->addAttribute("lastPos", lastPos.getString(), mapTagReplacements); + // Vec3f speed; + particleNode->addAttribute("speed", speed.getString(), mapTagReplacements); + // Vec3f speedUpRelative; + particleNode->addAttribute("speedUpRelative", floatToStr(speedUpRelative, 6), mapTagReplacements); + // Vec3f speedUpConstant; + particleNode->addAttribute("speedUpConstant", speedUpConstant.getString(), mapTagReplacements); + // Vec3f accel; + particleNode->addAttribute("accel", accel.getString(), mapTagReplacements); + // Vec4f color; + particleNode->addAttribute("color", color.getString(), mapTagReplacements); + // float size; + particleNode->addAttribute("size", floatToStr(size, 6), mapTagReplacements); + // int energy; + particleNode->addAttribute("energy", intToStr(energy), mapTagReplacements); + } -void Particle::loadGame(const XmlNode *rootNode) { - const XmlNode *particleNode = rootNode; + void Particle::loadGame(const XmlNode *rootNode) { + const XmlNode *particleNode = rootNode; - //particleNode = aiNode->getAttribute("startLoc")->getIntValue(); - // Vec3f pos; - pos = Vec3f::strToVec3(particleNode->getAttribute("pos")->getValue()); - // Vec3f lastPos; - lastPos = Vec3f::strToVec3(particleNode->getAttribute("lastPos")->getValue()); - // Vec3f speed; - speed = Vec3f::strToVec3(particleNode->getAttribute("speed")->getValue()); - // Vec3f speed; - speedUpRelative = particleNode->getAttribute("speedUpRelative")->getFloatValue(); - // Vec3f speed; - speedUpConstant = Vec3f::strToVec3(particleNode->getAttribute("speedUpConstant")->getValue()); - // Vec3f accel; - accel = Vec3f::strToVec3(particleNode->getAttribute("accel")->getValue()); - // Vec4f color; - color = Vec4f::strToVec4(particleNode->getAttribute("color")->getValue()); - // float size; - size = particleNode->getAttribute("size")->getFloatValue(); - // int energy; - energy = particleNode->getAttribute("energy")->getIntValue(); -} + //particleNode = aiNode->getAttribute("startLoc")->getIntValue(); + // Vec3f pos; + pos = Vec3f::strToVec3(particleNode->getAttribute("pos")->getValue()); + // Vec3f lastPos; + lastPos = Vec3f::strToVec3(particleNode->getAttribute("lastPos")->getValue()); + // Vec3f speed; + speed = Vec3f::strToVec3(particleNode->getAttribute("speed")->getValue()); + // Vec3f speed; + speedUpRelative = particleNode->getAttribute("speedUpRelative")->getFloatValue(); + // Vec3f speed; + speedUpConstant = Vec3f::strToVec3(particleNode->getAttribute("speedUpConstant")->getValue()); + // Vec3f accel; + accel = Vec3f::strToVec3(particleNode->getAttribute("accel")->getValue()); + // Vec4f color; + color = Vec4f::strToVec4(particleNode->getAttribute("color")->getValue()); + // float size; + size = particleNode->getAttribute("size")->getFloatValue(); + // int energy; + energy = particleNode->getAttribute("energy")->getIntValue(); + } -ParticleSystem::ParticleSystem(int particleCount) { - if(checkMemory) { - printf("++ Create ParticleSystem [%p]\n",this); - memoryObjectList[this]++; - } + ParticleSystem::ParticleSystem(int particleCount) { + if (checkMemory) { + printf("++ Create ParticleSystem [%p]\n", this); + memoryObjectList[this]++; + } - textureFileLoadDeferred = ""; - textureFileLoadDeferredSystemId = 0; - textureFileLoadDeferredFormat = Texture::fAuto; - textureFileLoadDeferredComponents = 0; + textureFileLoadDeferred = ""; + textureFileLoadDeferredSystemId = 0; + textureFileLoadDeferredFormat = Texture::fAuto; + textureFileLoadDeferredComponents = 0; - //init particle vector - blendMode= bmOne; - //particles= new Particle[particleCount]; - particles.clear(); - //particles.reserve(particleCount); - particles.resize(particleCount); + //init particle vector + blendMode = bmOne; + //particles= new Particle[particleCount]; + particles.clear(); + //particles.reserve(particleCount); + particles.resize(particleCount); - state= sPlay; - aliveParticleCount= 0; - active= true; - visible= true; + state = sPlay; + aliveParticleCount = 0; + active = true; + visible = true; - //vars - texture= NULL; - particleObserver= NULL; + //vars + texture = NULL; + particleObserver = NULL; - //params - this->particleCount= particleCount; - //this->particleCount= particles.size(); - maxParticleEnergy= 250; - varParticleEnergy= 50; - pos= Vec3f(0.0f); - color= Vec4f(1.0f); - colorNoEnergy= Vec4f(0.0f); - emissionRate= 15.0f; - emissionState= 1.0f; // initialized with 1 because we must have at least one particle in the beginning! - speed= 1.0f; - speedUpRelative = 0; - speedUpConstant = 0; + //params + this->particleCount = particleCount; + //this->particleCount= particles.size(); + maxParticleEnergy = 250; + varParticleEnergy = 50; + pos = Vec3f(0.0f); + color = Vec4f(1.0f); + colorNoEnergy = Vec4f(0.0f); + emissionRate = 15.0f; + emissionState = 1.0f; // initialized with 1 because we must have at least one particle in the beginning! + speed = 1.0f; + speedUpRelative = 0; + speedUpConstant = 0; - teamcolorNoEnergy= false; - teamcolorEnergy= false; - alternations= 0; - particleSystemStartDelay= 0; + teamcolorNoEnergy = false; + teamcolorEnergy = false; + alternations = 0; + particleSystemStartDelay = 0; - this->particleOwner = NULL; - this->particleSize = 0.0f; -} + this->particleOwner = NULL; + this->particleSize = 0.0f; + } -ParticleSystem::~ParticleSystem() { - if(checkMemory) { - printf("-- Delete ParticleSystem [%p]\n",this); - memoryObjectList[this]--; - assert(memoryObjectList[this] == 0); - } + ParticleSystem::~ParticleSystem() { + if (checkMemory) { + printf("-- Delete ParticleSystem [%p]\n", this); + memoryObjectList[this]--; + assert(memoryObjectList[this] == 0); + } - //delete [] particles; - particles.clear(); + //delete [] particles; + particles.clear(); - delete particleObserver; - particleObserver = NULL; -} + delete particleObserver; + particleObserver = NULL; + } -void ParticleSystem::callParticleOwnerEnd(ParticleSystem *particleSystem) { - if(this->particleOwner != NULL) { - this->particleOwner->end(particleSystem); - } -} -Checksum ParticleSystem::getCRC() { - Checksum crcForParticleSystem; + void ParticleSystem::callParticleOwnerEnd(ParticleSystem *particleSystem) { + if (this->particleOwner != NULL) { + this->particleOwner->end(particleSystem); + } + } + Checksum ParticleSystem::getCRC() { + Checksum crcForParticleSystem; - //std::vector particles; + //std::vector particles; - crcForParticleSystem.addInt(random.getLastNumber()); - crcForParticleSystem.addInt(blendMode); - crcForParticleSystem.addInt(state); - crcForParticleSystem.addInt(active); - //crcForParticleSystem.addInt(visible); - crcForParticleSystem.addInt(aliveParticleCount); - crcForParticleSystem.addInt(particleCount); + crcForParticleSystem.addInt(random.getLastNumber()); + crcForParticleSystem.addInt(blendMode); + crcForParticleSystem.addInt(state); + crcForParticleSystem.addInt(active); + //crcForParticleSystem.addInt(visible); + crcForParticleSystem.addInt(aliveParticleCount); + crcForParticleSystem.addInt(particleCount); - //string textureFileLoadDeferred; - //int textureFileLoadDeferredSystemId; - //Texture::Format textureFileLoadDeferredFormat; - //int textureFileLoadDeferredComponents; + //string textureFileLoadDeferred; + //int textureFileLoadDeferredSystemId; + //Texture::Format textureFileLoadDeferredFormat; + //int textureFileLoadDeferredComponents; - //Texture *texture; - //Vec3f pos; - //Vec4f color; - //Vec4f colorNoEnergy; - //float emissionRate; - //float emissionState; - crcForParticleSystem.addInt(maxParticleEnergy); - crcForParticleSystem.addInt(varParticleEnergy); - //float particleSize; - //float speed; - //Vec3f factionColor; - crcForParticleSystem.addInt(teamcolorNoEnergy); - crcForParticleSystem.addInt(teamcolorEnergy); - crcForParticleSystem.addInt(alternations); - crcForParticleSystem.addInt(particleSystemStartDelay); - //ParticleObserver *particleObserver; + //Texture *texture; + //Vec3f pos; + //Vec4f color; + //Vec4f colorNoEnergy; + //float emissionRate; + //float emissionState; + crcForParticleSystem.addInt(maxParticleEnergy); + crcForParticleSystem.addInt(varParticleEnergy); + //float particleSize; + //float speed; + //Vec3f factionColor; + crcForParticleSystem.addInt(teamcolorNoEnergy); + crcForParticleSystem.addInt(teamcolorEnergy); + crcForParticleSystem.addInt(alternations); + crcForParticleSystem.addInt(particleSystemStartDelay); + //ParticleObserver *particleObserver; - return crcForParticleSystem; -} + return crcForParticleSystem; + } -// =============== VIRTUAL ====================== + // =============== VIRTUAL ====================== -//updates all living particles and creates new ones -void ParticleSystem::update() { - if(aliveParticleCount > (int) particles.size()) { - throw megaglest_runtime_error("aliveParticleCount >= particles.size()"); - } - if(particleSystemStartDelay > 0) { - particleSystemStartDelay--; - } - else if(state != sPause) { - for(int i= 0; i < aliveParticleCount; ++i) { - updateParticle(&particles[i]); + //updates all living particles and creates new ones + void ParticleSystem::update() { + if (aliveParticleCount > (int) particles.size()) { + throw megaglest_runtime_error("aliveParticleCount >= particles.size()"); + } + if (particleSystemStartDelay > 0) { + particleSystemStartDelay--; + } else if (state != sPause) { + for (int i = 0; i < aliveParticleCount; ++i) { + updateParticle(&particles[i]); - if(deathTest(&particles[i])) { + if (deathTest(&particles[i])) { - //kill the particle - killParticle(&particles[i]); + //kill the particle + killParticle(&particles[i]); - //maintain alive particles at front of the array - if(aliveParticleCount > 0) { - particles[i]= particles[aliveParticleCount]; + //maintain alive particles at front of the array + if (aliveParticleCount > 0) { + particles[i] = particles[aliveParticleCount]; + } + } + } + + if (state != ParticleSystem::sFade) { + emissionState = emissionState + emissionRate; + int emissionIntValue = (int) emissionState; + for (int i = 0; i < emissionIntValue; i++) { + Particle *p = createParticle(); + initParticle(p, i); + } + emissionState = emissionState - (float) emissionIntValue; + emissionState = truncateDecimal(emissionState, 6); } } } - if(state != ParticleSystem::sFade) { - emissionState= emissionState + emissionRate; - int emissionIntValue= (int) emissionState; - for(int i= 0; i < emissionIntValue; i++){ - Particle *p= createParticle(); - initParticle(p, i); - } - emissionState = emissionState - (float) emissionIntValue; - emissionState = truncateDecimal(emissionState,6); - } - } -} - -void ParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr){ - if(active) { - pr->renderSystem(this); - } -} - -ParticleSystem::BlendMode ParticleSystem::strToBlendMode(const string &str){ - if(str == "normal") { - return bmOne; - } - else if(str == "black") { - return bmOneMinusAlpha; - } - else{ - throw megaglest_runtime_error("Unknown particle mode: " + str); - } -} - -// =============== SET ========================== - -void ParticleSystem::setState(State state){ - this->state= state; - for(int i=getChildCount()-1; i>=0; i--) - getChild(i)->setState(state); -} - -void ParticleSystem::setTexture(Texture *texture){ - this->texture= texture; -} - -void ParticleSystem::setPos(Vec3f pos){ - this->pos= pos; - for(int i=getChildCount()-1; i>=0; i--) - getChild(i)->setPos(pos); -} - -void ParticleSystem::setColor(Vec4f color){ - this->color= color; -} - -void ParticleSystem::setColorNoEnergy(Vec4f colorNoEnergy){ - this->colorNoEnergy= colorNoEnergy; -} - -void ParticleSystem::setEmissionRate(float emissionRate){ - this->emissionRate= emissionRate; - this->emissionRate = truncateDecimal(this->emissionRate,6); -} - -void ParticleSystem::setMaxParticleEnergy(int maxParticleEnergy){ - this->maxParticleEnergy= maxParticleEnergy; -} - -void ParticleSystem::setVarParticleEnergy(int varParticleEnergy){ - this->varParticleEnergy= varParticleEnergy; -} - -void ParticleSystem::setParticleSize(float particleSize){ - this->particleSize= particleSize; - this->particleSize = truncateDecimal(this->particleSize,6); -} - -void ParticleSystem::setSpeed(float speed){ - this->speed= speed; - this->speed = truncateDecimal(this->speed,6); -} - -void ParticleSystem::setSpeedUpRelative(float speedUpRelative){ - this->speedUpRelative= speedUpRelative; - this->speedUpRelative = truncateDecimal(this->speedUpRelative,6); -} - -void ParticleSystem::setSpeedUpConstant(float speedUpConstant){ - this->speedUpConstant= speedUpConstant; - this->speedUpConstant = truncateDecimal(this->speedUpConstant,6); -} - -void ParticleSystem::setActive(bool active){ - this->active= active; - for(int i=getChildCount()-1; i>=0; i--) - getChild(i)->setActive(active); -} - -void ParticleSystem::setObserver(ParticleObserver *particleObserver){ - this->particleObserver= particleObserver; -} - -ParticleSystem* ParticleSystem::getChild(int i){ - throw std::out_of_range("ParticleSystem::getChild bad"); -} - -void ParticleSystem::setVisible(bool visible){ - this->visible= visible; - for(int i=getChildCount()-1; i>=0; i--) { - getChild(i)->setVisible(visible); - } -} - -string ParticleSystem::toString() const { - string result = "ParticleSystem "; - - result += "particles = " + intToStr(particles.size()); - -// for(unsigned int i = 0; i < particles.size(); ++i) { -// Particle &particle = particles[i]; -// -// } - - result += "\nrandom = " + intToStr(random.getLastNumber()); - - result += "\nblendMode = " + intToStr(blendMode); - result += "\nstate = " + intToStr(state); - result += "\nactive = " + intToStr(active); - //result += "\nvisible = " + intToStr(visible); - result += "\naliveParticleCount = " + intToStr(aliveParticleCount); - result += "\nparticleCount = " + intToStr(particleCount); - - result += "\ntextureFileLoadDeferred = " + textureFileLoadDeferred; - result += "\ntextureFileLoadDeferredFormat = " + intToStr(textureFileLoadDeferredFormat); - result += "\ntextureFileLoadDeferredComponents = " + intToStr(textureFileLoadDeferredComponents); - - if(texture != NULL) { - result += "\ntexture = " + extractFileFromDirectoryPath(texture->getPath()); - } - result += "\npos = " + pos.getString(); - result += "\ncolor = " + color.getString(); - result += "\ncolorNoEnergy = " + colorNoEnergy.getString(); - result += "\nemissionRate = " + floatToStr(emissionRate,6); - result += "\nemissionState = " + floatToStr(emissionState,6); - result += "\nmaxParticleEnergy = " + intToStr(maxParticleEnergy); - result += "\nvarParticleEnergy = " + intToStr(varParticleEnergy); - result += "\nparticleSize = " + floatToStr(particleSize,6); - result += "\nspeed = " + floatToStr(speed,6); - result += "\nfactionColor = " + factionColor.getString(); - result += "\nteamcolorNoEnergy = " + intToStr(teamcolorNoEnergy); - result += "\nteamcolorEnergy = " + intToStr(teamcolorEnergy); - result += "\nalternations = " + intToStr(alternations); - result += "\nparticleSystemStartDelay = " + intToStr(particleSystemStartDelay); - //ParticleObserver *particleObserver; - - return result; -} - -void ParticleSystem::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *particleSystemNode = rootNode->addChild("ParticleSystem"); - -// std::vector particles; -// for(unsigned int i = 0; i < particles.size(); ++i) { -// Particle &particle = particles[i]; -// particle.saveGame(particleSystemNode); -// } -// RandomGen random; - particleSystemNode->addAttribute("random",intToStr(random.getLastNumber()), mapTagReplacements); - -// BlendMode blendMode; - particleSystemNode->addAttribute("blendMode",intToStr(blendMode), mapTagReplacements); -// State state; - particleSystemNode->addAttribute("state",intToStr(state), mapTagReplacements); -// bool active; - particleSystemNode->addAttribute("active",intToStr(active), mapTagReplacements); -// bool visible; - particleSystemNode->addAttribute("visible",intToStr(visible), mapTagReplacements); -// int aliveParticleCount; - particleSystemNode->addAttribute("aliveParticleCount",intToStr(aliveParticleCount), mapTagReplacements); -// int particleCount; - particleSystemNode->addAttribute("particleCount",intToStr(particleCount), mapTagReplacements); -// -// Texture *texture; - if(texture != NULL) { - particleSystemNode->addAttribute("texture",texture->getPath(), mapTagReplacements); - particleSystemNode->addAttribute("textureid",intToStr(texture->getTextureSystemId()), mapTagReplacements); - particleSystemNode->addAttribute("textureFormat",intToStr(texture->getFormat()), mapTagReplacements); - Texture2D *t2d = dynamic_cast(texture); - if(t2d != NULL && t2d->getPixmapConst() != NULL) { - particleSystemNode->addAttribute("textureComponents",intToStr(t2d->getPixmapConst()->getComponents()), mapTagReplacements); - } - } -// Vec3f pos; - particleSystemNode->addAttribute("pos",pos.getString(), mapTagReplacements); -// Vec4f color; - particleSystemNode->addAttribute("color",color.getString(), mapTagReplacements); -// Vec4f colorNoEnergy; - particleSystemNode->addAttribute("colorNoEnergy",colorNoEnergy.getString(), mapTagReplacements); -// float emissionRate; - particleSystemNode->addAttribute("emissionRate",floatToStr(emissionRate,6), mapTagReplacements); -// float emissionState; - particleSystemNode->addAttribute("emissionState",floatToStr(emissionState,6), mapTagReplacements); -// int maxParticleEnergy; - particleSystemNode->addAttribute("maxParticleEnergy",intToStr(maxParticleEnergy), mapTagReplacements); -// int varParticleEnergy; - particleSystemNode->addAttribute("varParticleEnergy",intToStr(varParticleEnergy), mapTagReplacements); -// float particleSize; - particleSystemNode->addAttribute("particleSize",floatToStr(particleSize,6), mapTagReplacements); -// float speed; - particleSystemNode->addAttribute("speed",floatToStr(speed,6), mapTagReplacements); -// Vec3f factionColor; - particleSystemNode->addAttribute("factionColor",factionColor.getString(), mapTagReplacements); -// bool teamcolorNoEnergy; - particleSystemNode->addAttribute("teamcolorNoEnergy",intToStr(teamcolorNoEnergy), mapTagReplacements); -// bool teamcolorEnergy; - particleSystemNode->addAttribute("teamcolorEnergy",intToStr(teamcolorEnergy), mapTagReplacements); -// int alternations; - particleSystemNode->addAttribute("alternations",intToStr(alternations), mapTagReplacements); -// int particleSystemStartDelay; - particleSystemNode->addAttribute("particleSystemStartDelay",intToStr(particleSystemStartDelay), mapTagReplacements); -// ParticleObserver *particleObserver; - if(particleObserver != NULL) { - particleObserver->saveGame(particleSystemNode); - } -} - -string ParticleSystem::getTextureFileLoadDeferred() { - return textureFileLoadDeferred; -} -int ParticleSystem::getTextureFileLoadDeferredSystemId() { - return textureFileLoadDeferredSystemId; -} -Texture::Format ParticleSystem::getTextureFileLoadDeferredFormat() { - return textureFileLoadDeferredFormat; -} -int ParticleSystem::getTextureFileLoadDeferredComponents() { - return textureFileLoadDeferredComponents; -} - -void ParticleSystem::loadGame(const XmlNode *rootNode) { - const XmlNode *particleSystemNode = rootNode->getChild("ParticleSystem"); - - particleCount = particleSystemNode->getAttribute("particleCount")->getIntValue(); - //printf("Load Smoke particle (ParticleSystem)\n"); - // std::vector particles; -// for(unsigned int i = 0; i < particles.size(); ++i) { -// Particle &particle = particles[i]; -// particle.saveGame(particleSystemNode); -// } - - particles.clear(); - particles.resize(particleCount); - -// vector particleNodeList = particleSystemNode->getChildList("Particle"); -// for(unsigned int i = 0; i < particleNodeList.size(); ++i) { -// XmlNode *node = particleNodeList[i]; -// -// //printf("Load Smoke particle (Particle = %d)\n",i); -// -// Particle particle; -// particle.loadGame(node); -// particles.push_back(particle); -// } - - // RandomGen random; - random.setLastNumber(particleSystemNode->getAttribute("random")->getIntValue()); - - // BlendMode blendMode; - blendMode = static_cast(particleSystemNode->getAttribute("blendMode")->getIntValue()); - // State state; - state = static_cast(particleSystemNode->getAttribute("state")->getIntValue()); - // bool active; - active = particleSystemNode->getAttribute("active")->getIntValue() != 0; - // bool visible; - visible = particleSystemNode->getAttribute("visible")->getIntValue() != 0; - // int aliveParticleCount; - aliveParticleCount = particleSystemNode->getAttribute("aliveParticleCount")->getIntValue(); - // int particleCount; - particleCount = particleSystemNode->getAttribute("particleCount")->getIntValue(); - // - // Texture *texture; - if(particleSystemNode->hasAttribute("texture") == true) { - textureFileLoadDeferred = particleSystemNode->getAttribute("texture")->getValue(); - textureFileLoadDeferredSystemId = particleSystemNode->getAttribute("textureid")->getIntValue(); - - textureFileLoadDeferredFormat = static_cast(particleSystemNode->getAttribute("textureFormat")->getIntValue()); - if(particleSystemNode->hasAttribute("textureComponents") == true) { - textureFileLoadDeferredComponents = particleSystemNode->getAttribute("textureComponents")->getIntValue(); - } - } - - // Vec3f pos; - pos = Vec3f::strToVec3(particleSystemNode->getAttribute("pos")->getValue()); - // Vec4f color; - color = Vec4f::strToVec4(particleSystemNode->getAttribute("color")->getValue()); - // Vec4f colorNoEnergy; - colorNoEnergy = Vec4f::strToVec4(particleSystemNode->getAttribute("colorNoEnergy")->getValue()); - // float emissionRate; - emissionRate = particleSystemNode->getAttribute("emissionRate")->getFloatValue(); - // float emissionState; - emissionState = particleSystemNode->getAttribute("emissionState")->getFloatValue(); - // int maxParticleEnergy; - maxParticleEnergy = particleSystemNode->getAttribute("maxParticleEnergy")->getIntValue(); - // int varParticleEnergy; - varParticleEnergy = particleSystemNode->getAttribute("varParticleEnergy")->getIntValue(); - // float particleSize; - particleSize = particleSystemNode->getAttribute("particleSize")->getFloatValue(); - // float speed; - speed = particleSystemNode->getAttribute("speed")->getFloatValue(); - // Vec3f factionColor; - factionColor = Vec3f::strToVec3(particleSystemNode->getAttribute("factionColor")->getValue()); - // bool teamcolorNoEnergy; - teamcolorNoEnergy = particleSystemNode->getAttribute("teamcolorNoEnergy")->getIntValue() != 0; - // bool teamcolorEnergy; - teamcolorEnergy = particleSystemNode->getAttribute("teamcolorEnergy")->getIntValue() != 0; - // int alternations; - alternations = particleSystemNode->getAttribute("alternations")->getIntValue(); - // int particleSystemStartDelay; - particleSystemStartDelay = particleSystemNode->getAttribute("particleSystemStartDelay")->getIntValue(); - - // ParticleObserver *particleObserver; - //if(particleObserver != NULL) { - // particleObserver->loadGame(particleSystemNode); - //} -} - -// =============== MISC ========================= -void ParticleSystem::fade(){ - //printf("**************Fading particle System:\n[%s]\n",this->toString().c_str()); - - bool alreadyFading = (state == sFade); - if(particleObserver != NULL){ - if(state != sPlay) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"state != sPlay, state = [%d]\n",state); - //throw megaglest_runtime_error(szBuf); - //printf(szBuf); - SystemFlags::OutputDebug(SystemFlags::debugError,"%s",szBuf); - } - //assert(state == sPlay); - } - - state= sFade; - if(alreadyFading == false) { - if(particleObserver != NULL){ - particleObserver->update(this); - particleObserver=NULL; - } - for(int i=getChildCount()-1; i>=0; i--) { - getChild(i)->fade(); - } - } -} - -int ParticleSystem::isEmpty() const { - //assert(aliveParticleCount>=0); - return aliveParticleCount == 0 && state != sPause; -} - -// =============== PROTECTED ========================= - -// if there is one dead particle it returns it else, return the particle with -// less energy -Particle * ParticleSystem::createParticle() { - - //if any dead particles - if(aliveParticleCount < particleCount) { - ++aliveParticleCount; - return &particles[aliveParticleCount - 1]; - } - - //if not - int minEnergy= particles[0].energy; - int minEnergyParticle= 0; - - for(int i= 0; i < particleCount; ++i){ - if(particles[i].energy < minEnergy){ - minEnergy= particles[i].energy; - minEnergyParticle= i; - } - } - return &particles[minEnergyParticle]; -} - -void ParticleSystem::initParticle(Particle *p, int particleIndex) { - p->pos= pos; - p->lastPos= p->pos; - p->speed= Vec3f(0.0f); - p->accel= Vec3f(0.0f); - p->color= Vec4f(1.0f, 1.0f, 1.0f, 1.0); - p->size= particleSize; - p->size = truncateDecimal(p->size,6); - p->energy= maxParticleEnergy + random.randRange(-varParticleEnergy, varParticleEnergy); -} - -void ParticleSystem::updateParticle(Particle *p) { - p->lastPos= p->pos; - p->pos= p->pos + p->speed; - p->speed= p->speed + p->accel; - p->energy--; -} - -bool ParticleSystem::deathTest(Particle *p) { - return p->energy <= 0; -} - -void ParticleSystem::killParticle(Particle *p) { - aliveParticleCount--; -} - -void ParticleSystem::setFactionColor(Vec3f factionColor){ - this->factionColor= factionColor; - Vec3f tmpCol; - - if(teamcolorEnergy){ - this->color= Vec4f(factionColor.x, factionColor.y, factionColor.z, this->color.w); - } - if(teamcolorNoEnergy){ - this->colorNoEnergy= Vec4f(factionColor.x, factionColor.y, factionColor.z, this->colorNoEnergy.w); - } - for(int i=getChildCount()-1; i>=0; i--) - getChild(i)->setFactionColor(factionColor); -} - -// =========================================================================== -// FireParticleSystem -// =========================================================================== - - -FireParticleSystem::FireParticleSystem(int particleCount) : - ParticleSystem(particleCount){ - - radius= 0.5f; - speed= 0.01f; - windSpeed= Vec3f(0.0f); - - setParticleSize(0.6f); - setColorNoEnergy(Vec4f(1.0f, 0.5f, 0.0f, 1.0f)); -} - -void FireParticleSystem::initParticle(Particle *p, int particleIndex){ - ParticleSystem::initParticle(p, particleIndex); - - float ang= random.randRange(-2.0f * pi, 2.0f * pi); -#ifdef USE_STREFLOP - float mod= streflop::fabsf(static_cast(random.randRange(-radius, radius))); - - float x= streflop::sinf(static_cast(ang))*mod; - float y= streflop::cosf(static_cast(ang))*mod; - - float radRatio= streflop::sqrtf(static_cast(mod/radius)); -#else - float mod= fabsf(random.randRange(-radius, radius)); - - float x= sinf(ang) * mod; - float y= cosf(ang) * mod; - - float radRatio= sqrtf((mod / radius)); -#endif - - p->color= colorNoEnergy * 0.5f + colorNoEnergy * 0.5f * radRatio; - p->energy= static_cast (maxParticleEnergy * radRatio) - + random.randRange(-varParticleEnergy, varParticleEnergy); - p->pos= Vec3f(pos.x + x, pos.y + random.randRange(-radius / 2, radius / 2), pos.z + y); - p->pos.x = truncateDecimal(p->pos.x,6); - p->pos.y = truncateDecimal(p->pos.y,6); - p->pos.z = truncateDecimal(p->pos.z,6); - - p->lastPos= pos; - p->size= particleSize; - p->speed= Vec3f(0, speed + speed * random.randRange(-0.5f, 0.5f), 0) + windSpeed; - p->speed.x = truncateDecimal(p->speed.x,6); - p->speed.y = truncateDecimal(p->speed.y,6); - p->speed.z = truncateDecimal(p->speed.z,6); - -} - -void FireParticleSystem::updateParticle(Particle *p){ - p->lastPos= p->pos; - p->pos= p->pos + p->speed; - p->energy--; - - if(p->color.x > 0.0f) - p->color.x*= 0.98f; - if(p->color.y > 0.0f) - p->color.y*= 0.98f; - if(p->color.w > 0.0f) - p->color.w*= 0.98f; - - p->speed.x*= 1.001f; - p->speed.x = truncateDecimal(p->speed.x,6); - p->speed.y = truncateDecimal(p->speed.y,6); - p->speed.z = truncateDecimal(p->speed.z,6); - -} - -string FireParticleSystem::toString() const { - string result = ParticleSystem::toString(); - - result += "\nFireParticleSystem "; - result += "\nradius = " + floatToStr(radius); - result += "\nwindSpeed = " + windSpeed.getString(); - - return result; -} -// ================= SET PARAMS ==================== - -void FireParticleSystem::setRadius(float radius){ - this->radius= radius; -} - -void FireParticleSystem::setWind(float windAngle, float windSpeed) { -#ifdef USE_STREFLOP - this->windSpeed.x= streflop::sinf(static_cast(degToRad(windAngle)))*windSpeed; - this->windSpeed.y= 0.0f; - this->windSpeed.z= streflop::cosf(static_cast(degToRad(windAngle)))*windSpeed; -#else - this->windSpeed.x= sinf(degToRad(windAngle)) * windSpeed; - this->windSpeed.y= 0.0f; - this->windSpeed.z= cosf(degToRad(windAngle)) * windSpeed; -#endif - - this->windSpeed.x = truncateDecimal(this->windSpeed.x,6); - this->windSpeed.y = truncateDecimal(this->windSpeed.y,6); - this->windSpeed.z = truncateDecimal(this->windSpeed.z,6); -} - -void FireParticleSystem::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *fireParticleSystemNode = rootNode->addChild("FireParticleSystem"); - - ParticleSystem::saveGame(fireParticleSystemNode); - -// float radius; - fireParticleSystemNode->addAttribute("radius",floatToStr(radius,6), mapTagReplacements); -// Vec3f windSpeed; - fireParticleSystemNode->addAttribute("windSpeed",windSpeed.getString(), mapTagReplacements); -} -void FireParticleSystem::loadGame(const XmlNode *rootNode) { - const XmlNode *fireParticleSystemNode = rootNode; - - ParticleSystem::loadGame(fireParticleSystemNode); - -// float radius; - radius = fireParticleSystemNode->getAttribute("radius")->getFloatValue(); -// Vec3f windSpeed; - windSpeed = Vec3f::strToVec3(fireParticleSystemNode->getAttribute("windSpeed")->getValue()); -} - -Checksum FireParticleSystem::getCRC() { - Checksum crcForParticleSystem = ParticleSystem::getCRC(); - - //float radius; - //Vec3f windSpeed; - - return crcForParticleSystem; -} - -// =========================================================================== -// GameParticleSystem -// =========================================================================== - -GameParticleSystem::GameParticleSystem(int particleCount): - ParticleSystem(particleCount), - primitive(pQuad), - model(NULL), - modelCycle(0.0f), - offset(0.0f), - direction(0.0f, 1.0f, 0.0f), - tween(0.0f) -{} - -GameParticleSystem::~GameParticleSystem(){ - for(Children::iterator it= children.begin(); it != children.end(); ++it){ - (*it)->setParent(NULL); - (*it)->fade(); - } -} - -GameParticleSystem::Primitive GameParticleSystem::strToPrimitive(const string &str){ - if(str == "quad"){ - return pQuad; - } - else if(str == "line"){ - return pLine; - } - else{ - throw megaglest_runtime_error("Unknown particle primitive: " + str); - } -} - -int GameParticleSystem::getChildCount(){ - return (int)children.size(); -} - -ParticleSystem* GameParticleSystem::getChild(int i){ - return children.at(i); // does bounds checking -} - -void GameParticleSystem::addChild(UnitParticleSystem* child) { - assert(!child->getParent()); - child->setParent(this); - children.push_back(child); -} - -void GameParticleSystem::removeChild(UnitParticleSystem* child){ - assert(this == child->getParent()); - Children::iterator it = std::find(children.begin(),children.end(),child); - assert(it != children.end()); - children.erase(it); -} - -void GameParticleSystem::setPos(Vec3f pos){ - this->pos= pos; - positionChildren(); -} - -void GameParticleSystem::positionChildren() { - Vec3f child_pos = pos - offset; - for(int i=getChildCount()-1; i>=0; i--) - getChild(i)->setPos(child_pos); -} - -void GameParticleSystem::setOffset(Vec3f offset){ - this->offset= offset; - positionChildren(); -} - -void GameParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr){ - if(active){ - if(model != NULL){ - pr->renderModel(this, mr); - } - switch(primitive){ - case pQuad: + void ParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr) { + if (active) { pr->renderSystem(this); - break; - case pLine: - pr->renderSystemLine(this); - break; - default: - assert(false); - break; - } - } -} - -void GameParticleSystem::setTween(float relative,float absolute) { - if(model) { - // animation? - //printf("#1 Particle model meshcount [%d] modelCycle = %f, relative = %f, absolute = %f\n",model->getMeshCount(),modelCycle,relative,absolute); - if(modelCycle == 0.0f) { - tween= relative; - } - else { - #ifdef USE_STREFLOP - if(streflop::fabs(static_cast(absolute)) <= 0.00001f){ - #else - if(fabs(absolute) <= 0.00001f) { - #endif - tween = 0.0f; - } - else { - #ifdef USE_STREFLOP - tween= streflop::fmod(static_cast(absolute), static_cast(modelCycle)); - #else - tween= fmod(absolute, modelCycle); - #endif - tween /= modelCycle; } } - tween = truncateDecimal(tween,6); - if(tween < 0.0f || tween > 1.0f) { - //printf("In [%s::%s Line: %d] WARNING setting tween to [%f] clamping tween, modelCycle [%f] absolute [%f] relative [%f]\n",__FILE__,__FUNCTION__,__LINE__,tween,modelCycle,absolute,relative); - //assert(tween >= 0.0f && tween <= 1.0f); + ParticleSystem::BlendMode ParticleSystem::strToBlendMode(const string &str) { + if (str == "normal") { + return bmOne; + } else if (str == "black") { + return bmOneMinusAlpha; + } else { + throw megaglest_runtime_error("Unknown particle mode: " + str); + } } - tween= clamp(tween, 0.0f, 1.0f); + // =============== SET ========================== - //printf("#2 Particle model meshcount [%d] modelCycle = %f, relative = %f, absolute = %f\n",model->getMeshCount(),modelCycle,relative,absolute); - } - for(Children::iterator it= children.begin(); it != children.end(); ++it) { - (*it)->setTween(relative,absolute); - } -} - -string GameParticleSystem::getModelFileLoadDeferred() { - return modelFileLoadDeferred; -} - -void GameParticleSystem::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *gameParticleSystemNode = rootNode->addChild("GameParticleSystem"); - - ParticleSystem::saveGame(gameParticleSystemNode); - -// Children children; - for(unsigned int i = 0; i < children.size(); ++i) { - if(children[i] != NULL) { - children[i]->saveGame(gameParticleSystemNode); + void ParticleSystem::setState(State state) { + this->state = state; + for (int i = getChildCount() - 1; i >= 0; i--) + getChild(i)->setState(state); } - } -// Primitive primitive; - gameParticleSystemNode->addAttribute("primitive",intToStr(primitive), mapTagReplacements); -// Model *model; - if(model != NULL) { - gameParticleSystemNode->addAttribute("model",model->getFileName(), mapTagReplacements); - } -// float modelCycle; - gameParticleSystemNode->addAttribute("modelCycle",floatToStr(modelCycle,6), mapTagReplacements); -// Vec3f offset; - gameParticleSystemNode->addAttribute("offset",offset.getString(), mapTagReplacements); -// Vec3f direction; - gameParticleSystemNode->addAttribute("direction",direction.getString(), mapTagReplacements); -// float tween; - gameParticleSystemNode->addAttribute("tween",floatToStr(tween,6), mapTagReplacements); -} -void GameParticleSystem::loadGame(const XmlNode *rootNode) { - const XmlNode *gameParticleSystemNode = rootNode->getChild("GameParticleSystem"); - //printf("Load Smoke particle (GameParticleSystem)\n"); - ParticleSystem::loadGame(gameParticleSystemNode); + void ParticleSystem::setTexture(Texture *texture) { + this->texture = texture; + } - // Children children; -// for(unsigned int i = 0; i < children.size(); ++i) { -// children[i]->saveGame(gameParticleSystemNode); -// } - vector childrenNodeList = gameParticleSystemNode->getChildList("UnitParticleSystem"); - for(unsigned int i = 0; i < childrenNodeList.size(); ++i) { - XmlNode *node = childrenNodeList[i]; + void ParticleSystem::setPos(Vec3f pos) { + this->pos = pos; + for (int i = getChildCount() - 1; i >= 0; i--) + getChild(i)->setPos(pos); + } - UnitParticleSystem *ups = new UnitParticleSystem(); - //ups->setParticleOwner(!!!); - ups->loadGame(node); + void ParticleSystem::setColor(Vec4f color) { + this->color = color; + } - //children.push_back(ups); - addChild(ups); - } + void ParticleSystem::setColorNoEnergy(Vec4f colorNoEnergy) { + this->colorNoEnergy = colorNoEnergy; + } - // Primitive primitive; - primitive = static_cast(gameParticleSystemNode->getAttribute("primitive")->getIntValue()); - // Model *model; - //if(model != NULL) { - // gameParticleSystemNode->addAttribute("model",model->getFileName(), mapTagReplacements); - //} - if(gameParticleSystemNode->hasAttribute("model") == true) { - modelFileLoadDeferred = gameParticleSystemNode->getAttribute("model")->getValue(); - } + void ParticleSystem::setEmissionRate(float emissionRate) { + this->emissionRate = emissionRate; + this->emissionRate = truncateDecimal(this->emissionRate, 6); + } - // float modelCycle; - //gameParticleSystemNode->addAttribute("modelCycle",floatToStr(modelCycle), mapTagReplacements); - modelCycle = gameParticleSystemNode->getAttribute("modelCycle")->getFloatValue(); - // Vec3f offset; - offset = Vec3f::strToVec3(gameParticleSystemNode->getAttribute("offset")->getValue()); - // Vec3f direction; - direction = Vec3f::strToVec3(gameParticleSystemNode->getAttribute("direction")->getValue()); - // float tween; - tween = gameParticleSystemNode->getAttribute("tween")->getFloatValue(); -} + void ParticleSystem::setMaxParticleEnergy(int maxParticleEnergy) { + this->maxParticleEnergy = maxParticleEnergy; + } -Checksum GameParticleSystem::getCRC() { - Checksum crcForParticleSystem = ParticleSystem::getCRC(); + void ParticleSystem::setVarParticleEnergy(int varParticleEnergy) { + this->varParticleEnergy = varParticleEnergy; + } - return crcForParticleSystem; -} + void ParticleSystem::setParticleSize(float particleSize) { + this->particleSize = particleSize; + this->particleSize = truncateDecimal(this->particleSize, 6); + } -string GameParticleSystem::toString() const { - string result = ParticleSystem::toString(); + void ParticleSystem::setSpeed(float speed) { + this->speed = speed; + this->speed = truncateDecimal(this->speed, 6); + } - result += "\nGameParticleSystem "; - result += "\nchildren = " + intToStr(children.size()); - result += "\nprimitive = " + intToStr(primitive); + void ParticleSystem::setSpeedUpRelative(float speedUpRelative) { + this->speedUpRelative = speedUpRelative; + this->speedUpRelative = truncateDecimal(this->speedUpRelative, 6); + } - //string modelFileLoadDeferred; - //Model *model; - result += "\nmodelCycle = " + floatToStr(modelCycle); - result += "\noffset = " + offset.getString(); - result += "\ndirection = " + direction.getString(); - result += "\ntween = " + floatToStr(tween); + void ParticleSystem::setSpeedUpConstant(float speedUpConstant) { + this->speedUpConstant = speedUpConstant; + this->speedUpConstant = truncateDecimal(this->speedUpConstant, 6); + } - return result; -} + void ParticleSystem::setActive(bool active) { + this->active = active; + for (int i = getChildCount() - 1; i >= 0; i--) + getChild(i)->setActive(active); + } -// =========================================================================== -// UnitParticleSystem -// =========================================================================== -bool UnitParticleSystem::isNight= false; -Vec3f UnitParticleSystem::lightColor=Vec3f(1.0f,1.0f,1.0f); + void ParticleSystem::setObserver(ParticleObserver *particleObserver) { + this->particleObserver = particleObserver; + } -UnitParticleSystem::UnitParticleSystem(int particleCount) : - GameParticleSystem(particleCount), parent(NULL) { + ParticleSystem* ParticleSystem::getChild(int i) { + throw std::out_of_range("ParticleSystem::getChild bad"); + } - particleSystemType = NULL; - radius= 0.5f; - speed= 0.01f; - windSpeed= Vec3f(0.0f); - minRadius = 0.0; + void ParticleSystem::setVisible(bool visible) { + this->visible = visible; + for (int i = getChildCount() - 1; i >= 0; i--) { + getChild(i)->setVisible(visible); + } + } - setParticleSize(0.6f); - setColorNoEnergy(Vec4f(1.0f, 0.5f, 0.0f, 1.0f)); - sizeNoEnergy=1.0f; + string ParticleSystem::toString() const { + string result = "ParticleSystem "; - primitive= pQuad; - gravity= 0.0f; + result += "particles = " + intToStr(particles.size()); - fixed= false; - shape = UnitParticleSystem::sLinear; - angle= 0.0f; - rotation= 0.0f; - relativeDirection= true; - relative= false; - staticParticleCount= 0; + // for(unsigned int i = 0; i < particles.size(); ++i) { + // Particle &particle = particles[i]; + // + // } - isVisibleAtNight= true; - isVisibleAtDay= true; - isDaylightAffected= false; + result += "\nrandom = " + intToStr(random.getLastNumber()); - cRotation= Vec3f(1.0f, 1.0f, 1.0f); - fixedAddition= Vec3f(0.0f, 0.0f, 0.0f); - //prepare system for given staticParticleCount - if(staticParticleCount > 0){ - emissionState= (float) staticParticleCount; - } - energyUp= false; - - delay = 0; // none - lifetime = -1; // forever - emissionRateFade=0.0f; + result += "\nblendMode = " + intToStr(blendMode); + result += "\nstate = " + intToStr(state); + result += "\nactive = " + intToStr(active); + //result += "\nvisible = " + intToStr(visible); + result += "\naliveParticleCount = " + intToStr(aliveParticleCount); + result += "\nparticleCount = " + intToStr(particleCount); - startTime = 0; - endTime = 1; - unitModel=NULL; - meshName=""; - meshPos=Vec3f(0,0,0); + result += "\ntextureFileLoadDeferred = " + textureFileLoadDeferred; + result += "\ntextureFileLoadDeferredFormat = " + intToStr(textureFileLoadDeferredFormat); + result += "\ntextureFileLoadDeferredComponents = " + intToStr(textureFileLoadDeferredComponents); - radiusBasedStartenergy = false; -} + if (texture != NULL) { + result += "\ntexture = " + extractFileFromDirectoryPath(texture->getPath()); + } + result += "\npos = " + pos.getString(); + result += "\ncolor = " + color.getString(); + result += "\ncolorNoEnergy = " + colorNoEnergy.getString(); + result += "\nemissionRate = " + floatToStr(emissionRate, 6); + result += "\nemissionState = " + floatToStr(emissionState, 6); + result += "\nmaxParticleEnergy = " + intToStr(maxParticleEnergy); + result += "\nvarParticleEnergy = " + intToStr(varParticleEnergy); + result += "\nparticleSize = " + floatToStr(particleSize, 6); + result += "\nspeed = " + floatToStr(speed, 6); + result += "\nfactionColor = " + factionColor.getString(); + result += "\nteamcolorNoEnergy = " + intToStr(teamcolorNoEnergy); + result += "\nteamcolorEnergy = " + intToStr(teamcolorEnergy); + result += "\nalternations = " + intToStr(alternations); + result += "\nparticleSystemStartDelay = " + intToStr(particleSystemStartDelay); + //ParticleObserver *particleObserver; -UnitParticleSystem::~UnitParticleSystem(){ - if(parent){ - parent->removeChild(this); - } -} + return result; + } -bool UnitParticleSystem::getVisible() const{ - if((isNight==true) && (isVisibleAtNight==true)){ - return visible; - } - else if((isNight==false) && (isVisibleAtDay==true)){ - return visible; - } - else - return false; -} + void ParticleSystem::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *particleSystemNode = rootNode->addChild("ParticleSystem"); -void UnitParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr) { - GameParticleSystem::render(pr,mr); -} + // std::vector particles; + // for(unsigned int i = 0; i < particles.size(); ++i) { + // Particle &particle = particles[i]; + // particle.saveGame(particleSystemNode); + // } + // RandomGen random; + particleSystemNode->addAttribute("random", intToStr(random.getLastNumber()), mapTagReplacements); -void UnitParticleSystem::setRotation(float rotation){ - this->rotation= rotation; - for(Children::iterator it= children.begin(); it != children.end(); ++it) - (*it)->setRotation(rotation); -} + // BlendMode blendMode; + particleSystemNode->addAttribute("blendMode", intToStr(blendMode), mapTagReplacements); + // State state; + particleSystemNode->addAttribute("state", intToStr(state), mapTagReplacements); + // bool active; + particleSystemNode->addAttribute("active", intToStr(active), mapTagReplacements); + // bool visible; + particleSystemNode->addAttribute("visible", intToStr(visible), mapTagReplacements); + // int aliveParticleCount; + particleSystemNode->addAttribute("aliveParticleCount", intToStr(aliveParticleCount), mapTagReplacements); + // int particleCount; + particleSystemNode->addAttribute("particleCount", intToStr(particleCount), mapTagReplacements); + // + // Texture *texture; + if (texture != NULL) { + particleSystemNode->addAttribute("texture", texture->getPath(), mapTagReplacements); + particleSystemNode->addAttribute("textureid", intToStr(texture->getTextureSystemId()), mapTagReplacements); + particleSystemNode->addAttribute("textureFormat", intToStr(texture->getFormat()), mapTagReplacements); + Texture2D *t2d = dynamic_cast(texture); + if (t2d != NULL && t2d->getPixmapConst() != NULL) { + particleSystemNode->addAttribute("textureComponents", intToStr(t2d->getPixmapConst()->getComponents()), mapTagReplacements); + } + } + // Vec3f pos; + particleSystemNode->addAttribute("pos", pos.getString(), mapTagReplacements); + // Vec4f color; + particleSystemNode->addAttribute("color", color.getString(), mapTagReplacements); + // Vec4f colorNoEnergy; + particleSystemNode->addAttribute("colorNoEnergy", colorNoEnergy.getString(), mapTagReplacements); + // float emissionRate; + particleSystemNode->addAttribute("emissionRate", floatToStr(emissionRate, 6), mapTagReplacements); + // float emissionState; + particleSystemNode->addAttribute("emissionState", floatToStr(emissionState, 6), mapTagReplacements); + // int maxParticleEnergy; + particleSystemNode->addAttribute("maxParticleEnergy", intToStr(maxParticleEnergy), mapTagReplacements); + // int varParticleEnergy; + particleSystemNode->addAttribute("varParticleEnergy", intToStr(varParticleEnergy), mapTagReplacements); + // float particleSize; + particleSystemNode->addAttribute("particleSize", floatToStr(particleSize, 6), mapTagReplacements); + // float speed; + particleSystemNode->addAttribute("speed", floatToStr(speed, 6), mapTagReplacements); + // Vec3f factionColor; + particleSystemNode->addAttribute("factionColor", factionColor.getString(), mapTagReplacements); + // bool teamcolorNoEnergy; + particleSystemNode->addAttribute("teamcolorNoEnergy", intToStr(teamcolorNoEnergy), mapTagReplacements); + // bool teamcolorEnergy; + particleSystemNode->addAttribute("teamcolorEnergy", intToStr(teamcolorEnergy), mapTagReplacements); + // int alternations; + particleSystemNode->addAttribute("alternations", intToStr(alternations), mapTagReplacements); + // int particleSystemStartDelay; + particleSystemNode->addAttribute("particleSystemStartDelay", intToStr(particleSystemStartDelay), mapTagReplacements); + // ParticleObserver *particleObserver; + if (particleObserver != NULL) { + particleObserver->saveGame(particleSystemNode); + } + } -void UnitParticleSystem::fade(){ - if(!parent || (lifetime<=0 && !(emissionRateFade && emissionRate > 0))){ // particle has its own lifetime? - unitModel=NULL; - GameParticleSystem::fade(); - } -} + string ParticleSystem::getTextureFileLoadDeferred() { + return textureFileLoadDeferred; + } + int ParticleSystem::getTextureFileLoadDeferredSystemId() { + return textureFileLoadDeferredSystemId; + } + Texture::Format ParticleSystem::getTextureFileLoadDeferredFormat() { + return textureFileLoadDeferredFormat; + } + int ParticleSystem::getTextureFileLoadDeferredComponents() { + return textureFileLoadDeferredComponents; + } -UnitParticleSystem::Shape UnitParticleSystem::strToShape(const string& str){ - if(str == "spherical"){ - return sSpherical; - } - else if(str == "conical"){ - return sConical; - } - else if(str == "linear"){ - return sLinear; - } - else{ - throw megaglest_runtime_error("Unknown particle shape: " + str); - } -} + void ParticleSystem::loadGame(const XmlNode *rootNode) { + const XmlNode *particleSystemNode = rootNode->getChild("ParticleSystem"); -void UnitParticleSystem::initParticle(Particle *p, int particleIndex){ - ParticleSystem::initParticle(p, particleIndex); + particleCount = particleSystemNode->getAttribute("particleCount")->getIntValue(); + //printf("Load Smoke particle (ParticleSystem)\n"); + // std::vector particles; + // for(unsigned int i = 0; i < particles.size(); ++i) { + // Particle &particle = particles[i]; + // particle.saveGame(particleSystemNode); + // } - const float ang= random.randRange(-2.0f * pi, 2.0f * pi); + particles.clear(); + particles.resize(particleCount); + + // vector particleNodeList = particleSystemNode->getChildList("Particle"); + // for(unsigned int i = 0; i < particleNodeList.size(); ++i) { + // XmlNode *node = particleNodeList[i]; + // + // //printf("Load Smoke particle (Particle = %d)\n",i); + // + // Particle particle; + // particle.loadGame(node); + // particles.push_back(particle); + // } + + // RandomGen random; + random.setLastNumber(particleSystemNode->getAttribute("random")->getIntValue()); + + // BlendMode blendMode; + blendMode = static_cast(particleSystemNode->getAttribute("blendMode")->getIntValue()); + // State state; + state = static_cast(particleSystemNode->getAttribute("state")->getIntValue()); + // bool active; + active = particleSystemNode->getAttribute("active")->getIntValue() != 0; + // bool visible; + visible = particleSystemNode->getAttribute("visible")->getIntValue() != 0; + // int aliveParticleCount; + aliveParticleCount = particleSystemNode->getAttribute("aliveParticleCount")->getIntValue(); + // int particleCount; + particleCount = particleSystemNode->getAttribute("particleCount")->getIntValue(); + // + // Texture *texture; + if (particleSystemNode->hasAttribute("texture") == true) { + textureFileLoadDeferred = particleSystemNode->getAttribute("texture")->getValue(); + textureFileLoadDeferredSystemId = particleSystemNode->getAttribute("textureid")->getIntValue(); + + textureFileLoadDeferredFormat = static_cast(particleSystemNode->getAttribute("textureFormat")->getIntValue()); + if (particleSystemNode->hasAttribute("textureComponents") == true) { + textureFileLoadDeferredComponents = particleSystemNode->getAttribute("textureComponents")->getIntValue(); + } + } + + // Vec3f pos; + pos = Vec3f::strToVec3(particleSystemNode->getAttribute("pos")->getValue()); + // Vec4f color; + color = Vec4f::strToVec4(particleSystemNode->getAttribute("color")->getValue()); + // Vec4f colorNoEnergy; + colorNoEnergy = Vec4f::strToVec4(particleSystemNode->getAttribute("colorNoEnergy")->getValue()); + // float emissionRate; + emissionRate = particleSystemNode->getAttribute("emissionRate")->getFloatValue(); + // float emissionState; + emissionState = particleSystemNode->getAttribute("emissionState")->getFloatValue(); + // int maxParticleEnergy; + maxParticleEnergy = particleSystemNode->getAttribute("maxParticleEnergy")->getIntValue(); + // int varParticleEnergy; + varParticleEnergy = particleSystemNode->getAttribute("varParticleEnergy")->getIntValue(); + // float particleSize; + particleSize = particleSystemNode->getAttribute("particleSize")->getFloatValue(); + // float speed; + speed = particleSystemNode->getAttribute("speed")->getFloatValue(); + // Vec3f factionColor; + factionColor = Vec3f::strToVec3(particleSystemNode->getAttribute("factionColor")->getValue()); + // bool teamcolorNoEnergy; + teamcolorNoEnergy = particleSystemNode->getAttribute("teamcolorNoEnergy")->getIntValue() != 0; + // bool teamcolorEnergy; + teamcolorEnergy = particleSystemNode->getAttribute("teamcolorEnergy")->getIntValue() != 0; + // int alternations; + alternations = particleSystemNode->getAttribute("alternations")->getIntValue(); + // int particleSystemStartDelay; + particleSystemStartDelay = particleSystemNode->getAttribute("particleSystemStartDelay")->getIntValue(); + + // ParticleObserver *particleObserver; + //if(particleObserver != NULL) { + // particleObserver->loadGame(particleSystemNode); + //} + } + + // =============== MISC ========================= + void ParticleSystem::fade() { + //printf("**************Fading particle System:\n[%s]\n",this->toString().c_str()); + + bool alreadyFading = (state == sFade); + if (particleObserver != NULL) { + if (state != sPlay) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "state != sPlay, state = [%d]\n", state); + //throw megaglest_runtime_error(szBuf); + //printf(szBuf); + SystemFlags::OutputDebug(SystemFlags::debugError, "%s", szBuf); + } + //assert(state == sPlay); + } + + state = sFade; + if (alreadyFading == false) { + if (particleObserver != NULL) { + particleObserver->update(this); + particleObserver = NULL; + } + for (int i = getChildCount() - 1; i >= 0; i--) { + getChild(i)->fade(); + } + } + } + + int ParticleSystem::isEmpty() const { + //assert(aliveParticleCount>=0); + return aliveParticleCount == 0 && state != sPause; + } + + // =============== PROTECTED ========================= + + // if there is one dead particle it returns it else, return the particle with + // less energy + Particle * ParticleSystem::createParticle() { + + //if any dead particles + if (aliveParticleCount < particleCount) { + ++aliveParticleCount; + return &particles[aliveParticleCount - 1]; + } + + //if not + int minEnergy = particles[0].energy; + int minEnergyParticle = 0; + + for (int i = 0; i < particleCount; ++i) { + if (particles[i].energy < minEnergy) { + minEnergy = particles[i].energy; + minEnergyParticle = i; + } + } + return &particles[minEnergyParticle]; + } + + void ParticleSystem::initParticle(Particle *p, int particleIndex) { + p->pos = pos; + p->lastPos = p->pos; + p->speed = Vec3f(0.0f); + p->accel = Vec3f(0.0f); + p->color = Vec4f(1.0f, 1.0f, 1.0f, 1.0); + p->size = particleSize; + p->size = truncateDecimal(p->size, 6); + p->energy = maxParticleEnergy + random.randRange(-varParticleEnergy, varParticleEnergy); + } + + void ParticleSystem::updateParticle(Particle *p) { + p->lastPos = p->pos; + p->pos = p->pos + p->speed; + p->speed = p->speed + p->accel; + p->energy--; + } + + bool ParticleSystem::deathTest(Particle *p) { + return p->energy <= 0; + } + + void ParticleSystem::killParticle(Particle *p) { + aliveParticleCount--; + } + + void ParticleSystem::setFactionColor(Vec3f factionColor) { + this->factionColor = factionColor; + Vec3f tmpCol; + + if (teamcolorEnergy) { + this->color = Vec4f(factionColor.x, factionColor.y, factionColor.z, this->color.w); + } + if (teamcolorNoEnergy) { + this->colorNoEnergy = Vec4f(factionColor.x, factionColor.y, factionColor.z, this->colorNoEnergy.w); + } + for (int i = getChildCount() - 1; i >= 0; i--) + getChild(i)->setFactionColor(factionColor); + } + + // =========================================================================== + // FireParticleSystem + // =========================================================================== + + + FireParticleSystem::FireParticleSystem(int particleCount) : + ParticleSystem(particleCount) { + + radius = 0.5f; + speed = 0.01f; + windSpeed = Vec3f(0.0f); + + setParticleSize(0.6f); + setColorNoEnergy(Vec4f(1.0f, 0.5f, 0.0f, 1.0f)); + } + + void FireParticleSystem::initParticle(Particle *p, int particleIndex) { + ParticleSystem::initParticle(p, particleIndex); + + float ang = random.randRange(-2.0f * pi, 2.0f * pi); +#ifdef USE_STREFLOP + float mod = streflop::fabsf(static_cast(random.randRange(-radius, radius))); + + float x = streflop::sinf(static_cast(ang))*mod; + float y = streflop::cosf(static_cast(ang))*mod; + + float radRatio = streflop::sqrtf(static_cast(mod / radius)); +#else + float mod = fabsf(random.randRange(-radius, radius)); + + float x = sinf(ang) * mod; + float y = cosf(ang) * mod; + + float radRatio = sqrtf((mod / radius)); +#endif + + p->color = colorNoEnergy * 0.5f + colorNoEnergy * 0.5f * radRatio; + p->energy = static_cast (maxParticleEnergy * radRatio) + + random.randRange(-varParticleEnergy, varParticleEnergy); + p->pos = Vec3f(pos.x + x, pos.y + random.randRange(-radius / 2, radius / 2), pos.z + y); + p->pos.x = truncateDecimal(p->pos.x, 6); + p->pos.y = truncateDecimal(p->pos.y, 6); + p->pos.z = truncateDecimal(p->pos.z, 6); + + p->lastPos = pos; + p->size = particleSize; + p->speed = Vec3f(0, speed + speed * random.randRange(-0.5f, 0.5f), 0) + windSpeed; + p->speed.x = truncateDecimal(p->speed.x, 6); + p->speed.y = truncateDecimal(p->speed.y, 6); + p->speed.z = truncateDecimal(p->speed.z, 6); + + } + + void FireParticleSystem::updateParticle(Particle *p) { + p->lastPos = p->pos; + p->pos = p->pos + p->speed; + p->energy--; + + if (p->color.x > 0.0f) + p->color.x *= 0.98f; + if (p->color.y > 0.0f) + p->color.y *= 0.98f; + if (p->color.w > 0.0f) + p->color.w *= 0.98f; + + p->speed.x *= 1.001f; + p->speed.x = truncateDecimal(p->speed.x, 6); + p->speed.y = truncateDecimal(p->speed.y, 6); + p->speed.z = truncateDecimal(p->speed.z, 6); + + } + + string FireParticleSystem::toString() const { + string result = ParticleSystem::toString(); + + result += "\nFireParticleSystem "; + result += "\nradius = " + floatToStr(radius); + result += "\nwindSpeed = " + windSpeed.getString(); + + return result; + } + // ================= SET PARAMS ==================== + + void FireParticleSystem::setRadius(float radius) { + this->radius = radius; + } + + void FireParticleSystem::setWind(float windAngle, float windSpeed) { +#ifdef USE_STREFLOP + this->windSpeed.x = streflop::sinf(static_cast(degToRad(windAngle)))*windSpeed; + this->windSpeed.y = 0.0f; + this->windSpeed.z = streflop::cosf(static_cast(degToRad(windAngle)))*windSpeed; +#else + this->windSpeed.x = sinf(degToRad(windAngle)) * windSpeed; + this->windSpeed.y = 0.0f; + this->windSpeed.z = cosf(degToRad(windAngle)) * windSpeed; +#endif + + this->windSpeed.x = truncateDecimal(this->windSpeed.x, 6); + this->windSpeed.y = truncateDecimal(this->windSpeed.y, 6); + this->windSpeed.z = truncateDecimal(this->windSpeed.z, 6); + } + + void FireParticleSystem::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *fireParticleSystemNode = rootNode->addChild("FireParticleSystem"); + + ParticleSystem::saveGame(fireParticleSystemNode); + + // float radius; + fireParticleSystemNode->addAttribute("radius", floatToStr(radius, 6), mapTagReplacements); + // Vec3f windSpeed; + fireParticleSystemNode->addAttribute("windSpeed", windSpeed.getString(), mapTagReplacements); + } + void FireParticleSystem::loadGame(const XmlNode *rootNode) { + const XmlNode *fireParticleSystemNode = rootNode; + + ParticleSystem::loadGame(fireParticleSystemNode); + + // float radius; + radius = fireParticleSystemNode->getAttribute("radius")->getFloatValue(); + // Vec3f windSpeed; + windSpeed = Vec3f::strToVec3(fireParticleSystemNode->getAttribute("windSpeed")->getValue()); + } + + Checksum FireParticleSystem::getCRC() { + Checksum crcForParticleSystem = ParticleSystem::getCRC(); + + //float radius; + //Vec3f windSpeed; + + return crcForParticleSystem; + } + + // =========================================================================== + // GameParticleSystem + // =========================================================================== + + GameParticleSystem::GameParticleSystem(int particleCount) : + ParticleSystem(particleCount), + primitive(pQuad), + model(NULL), + modelCycle(0.0f), + offset(0.0f), + direction(0.0f, 1.0f, 0.0f), + tween(0.0f) { + } + + GameParticleSystem::~GameParticleSystem() { + for (Children::iterator it = children.begin(); it != children.end(); ++it) { + (*it)->setParent(NULL); + (*it)->fade(); + } + } + + GameParticleSystem::Primitive GameParticleSystem::strToPrimitive(const string &str) { + if (str == "quad") { + return pQuad; + } else if (str == "line") { + return pLine; + } else { + throw megaglest_runtime_error("Unknown particle primitive: " + str); + } + } + + int GameParticleSystem::getChildCount() { + return (int) children.size(); + } + + ParticleSystem* GameParticleSystem::getChild(int i) { + return children.at(i); // does bounds checking + } + + void GameParticleSystem::addChild(UnitParticleSystem* child) { + assert(!child->getParent()); + child->setParent(this); + children.push_back(child); + } + + void GameParticleSystem::removeChild(UnitParticleSystem* child) { + assert(this == child->getParent()); + Children::iterator it = std::find(children.begin(), children.end(), child); + assert(it != children.end()); + children.erase(it); + } + + void GameParticleSystem::setPos(Vec3f pos) { + this->pos = pos; + positionChildren(); + } + + void GameParticleSystem::positionChildren() { + Vec3f child_pos = pos - offset; + for (int i = getChildCount() - 1; i >= 0; i--) + getChild(i)->setPos(child_pos); + } + + void GameParticleSystem::setOffset(Vec3f offset) { + this->offset = offset; + positionChildren(); + } + + void GameParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr) { + if (active) { + if (model != NULL) { + pr->renderModel(this, mr); + } + switch (primitive) { + case pQuad: + pr->renderSystem(this); + break; + case pLine: + pr->renderSystemLine(this); + break; + default: + assert(false); + break; + } + } + } + + void GameParticleSystem::setTween(float relative, float absolute) { + if (model) { + // animation? + //printf("#1 Particle model meshcount [%d] modelCycle = %f, relative = %f, absolute = %f\n",model->getMeshCount(),modelCycle,relative,absolute); + if (modelCycle == 0.0f) { + tween = relative; + } else { +#ifdef USE_STREFLOP + if (streflop::fabs(static_cast(absolute)) <= 0.00001f) { +#else + if (fabs(absolute) <= 0.00001f) { +#endif + tween = 0.0f; + } else { +#ifdef USE_STREFLOP + tween = streflop::fmod(static_cast(absolute), static_cast(modelCycle)); +#else + tween = fmod(absolute, modelCycle); +#endif + tween /= modelCycle; + } + } + + tween = truncateDecimal(tween, 6); + if (tween < 0.0f || tween > 1.0f) { + //printf("In [%s::%s Line: %d] WARNING setting tween to [%f] clamping tween, modelCycle [%f] absolute [%f] relative [%f]\n",__FILE__,__FUNCTION__,__LINE__,tween,modelCycle,absolute,relative); + //assert(tween >= 0.0f && tween <= 1.0f); + } + + tween = clamp(tween, 0.0f, 1.0f); + + //printf("#2 Particle model meshcount [%d] modelCycle = %f, relative = %f, absolute = %f\n",model->getMeshCount(),modelCycle,relative,absolute); + } + for (Children::iterator it = children.begin(); it != children.end(); ++it) { + (*it)->setTween(relative, absolute); + } + } + + string GameParticleSystem::getModelFileLoadDeferred() { + return modelFileLoadDeferred; + } + + void GameParticleSystem::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *gameParticleSystemNode = rootNode->addChild("GameParticleSystem"); + + ParticleSystem::saveGame(gameParticleSystemNode); + + // Children children; + for (unsigned int i = 0; i < children.size(); ++i) { + if (children[i] != NULL) { + children[i]->saveGame(gameParticleSystemNode); + } + } + // Primitive primitive; + gameParticleSystemNode->addAttribute("primitive", intToStr(primitive), mapTagReplacements); + // Model *model; + if (model != NULL) { + gameParticleSystemNode->addAttribute("model", model->getFileName(), mapTagReplacements); + } + // float modelCycle; + gameParticleSystemNode->addAttribute("modelCycle", floatToStr(modelCycle, 6), mapTagReplacements); + // Vec3f offset; + gameParticleSystemNode->addAttribute("offset", offset.getString(), mapTagReplacements); + // Vec3f direction; + gameParticleSystemNode->addAttribute("direction", direction.getString(), mapTagReplacements); + // float tween; + gameParticleSystemNode->addAttribute("tween", floatToStr(tween, 6), mapTagReplacements); + } + void GameParticleSystem::loadGame(const XmlNode *rootNode) { + const XmlNode *gameParticleSystemNode = rootNode->getChild("GameParticleSystem"); + + //printf("Load Smoke particle (GameParticleSystem)\n"); + ParticleSystem::loadGame(gameParticleSystemNode); + + // Children children; + // for(unsigned int i = 0; i < children.size(); ++i) { + // children[i]->saveGame(gameParticleSystemNode); + // } + vector childrenNodeList = gameParticleSystemNode->getChildList("UnitParticleSystem"); + for (unsigned int i = 0; i < childrenNodeList.size(); ++i) { + XmlNode *node = childrenNodeList[i]; + + UnitParticleSystem *ups = new UnitParticleSystem(); + //ups->setParticleOwner(!!!); + ups->loadGame(node); + + //children.push_back(ups); + addChild(ups); + } + + // Primitive primitive; + primitive = static_cast(gameParticleSystemNode->getAttribute("primitive")->getIntValue()); + // Model *model; + //if(model != NULL) { + // gameParticleSystemNode->addAttribute("model",model->getFileName(), mapTagReplacements); + //} + if (gameParticleSystemNode->hasAttribute("model") == true) { + modelFileLoadDeferred = gameParticleSystemNode->getAttribute("model")->getValue(); + } + + // float modelCycle; + //gameParticleSystemNode->addAttribute("modelCycle",floatToStr(modelCycle), mapTagReplacements); + modelCycle = gameParticleSystemNode->getAttribute("modelCycle")->getFloatValue(); + // Vec3f offset; + offset = Vec3f::strToVec3(gameParticleSystemNode->getAttribute("offset")->getValue()); + // Vec3f direction; + direction = Vec3f::strToVec3(gameParticleSystemNode->getAttribute("direction")->getValue()); + // float tween; + tween = gameParticleSystemNode->getAttribute("tween")->getFloatValue(); + } + + Checksum GameParticleSystem::getCRC() { + Checksum crcForParticleSystem = ParticleSystem::getCRC(); + + return crcForParticleSystem; + } + + string GameParticleSystem::toString() const { + string result = ParticleSystem::toString(); + + result += "\nGameParticleSystem "; + result += "\nchildren = " + intToStr(children.size()); + result += "\nprimitive = " + intToStr(primitive); + + //string modelFileLoadDeferred; + //Model *model; + result += "\nmodelCycle = " + floatToStr(modelCycle); + result += "\noffset = " + offset.getString(); + result += "\ndirection = " + direction.getString(); + result += "\ntween = " + floatToStr(tween); + + return result; + } + + // =========================================================================== + // UnitParticleSystem + // =========================================================================== + bool UnitParticleSystem::isNight = false; + Vec3f UnitParticleSystem::lightColor = Vec3f(1.0f, 1.0f, 1.0f); + + UnitParticleSystem::UnitParticleSystem(int particleCount) : + GameParticleSystem(particleCount), parent(NULL) { + + particleSystemType = NULL; + radius = 0.5f; + speed = 0.01f; + windSpeed = Vec3f(0.0f); + minRadius = 0.0; + + setParticleSize(0.6f); + setColorNoEnergy(Vec4f(1.0f, 0.5f, 0.0f, 1.0f)); + sizeNoEnergy = 1.0f; + + primitive = pQuad; + gravity = 0.0f; + + fixed = false; + shape = UnitParticleSystem::sLinear; + angle = 0.0f; + rotation = 0.0f; + relativeDirection = true; + relative = false; + staticParticleCount = 0; + + isVisibleAtNight = true; + isVisibleAtDay = true; + isDaylightAffected = false; + + cRotation = Vec3f(1.0f, 1.0f, 1.0f); + fixedAddition = Vec3f(0.0f, 0.0f, 0.0f); + //prepare system for given staticParticleCount + if (staticParticleCount > 0) { + emissionState = (float) staticParticleCount; + } + energyUp = false; + + delay = 0; // none + lifetime = -1; // forever + emissionRateFade = 0.0f; + + startTime = 0; + endTime = 1; + unitModel = NULL; + meshName = ""; + meshPos = Vec3f(0, 0, 0); + + radiusBasedStartenergy = false; + } + + UnitParticleSystem::~UnitParticleSystem() { + if (parent) { + parent->removeChild(this); + } + } + + bool UnitParticleSystem::getVisible() const { + if ((isNight == true) && (isVisibleAtNight == true)) { + return visible; + } else if ((isNight == false) && (isVisibleAtDay == true)) { + return visible; + } else + return false; + } + + void UnitParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr) { + GameParticleSystem::render(pr, mr); + } + + void UnitParticleSystem::setRotation(float rotation) { + this->rotation = rotation; + for (Children::iterator it = children.begin(); it != children.end(); ++it) + (*it)->setRotation(rotation); + } + + void UnitParticleSystem::fade() { + if (!parent || (lifetime <= 0 && !(emissionRateFade && emissionRate > 0))) { // particle has its own lifetime? + unitModel = NULL; + GameParticleSystem::fade(); + } + } + + UnitParticleSystem::Shape UnitParticleSystem::strToShape(const string& str) { + if (str == "spherical") { + return sSpherical; + } else if (str == "conical") { + return sConical; + } else if (str == "linear") { + return sLinear; + } else { + throw megaglest_runtime_error("Unknown particle shape: " + str); + } + } + + void UnitParticleSystem::initParticle(Particle *p, int particleIndex) { + ParticleSystem::initParticle(p, particleIndex); + + const float ang = random.randRange(-2.0f * pi, 2.0f * pi); #ifdef USE_STREFLOP - const float mod= streflop::fabsf(static_cast(random.randRange(-radius, radius))); - const float radRatio= streflop::sqrtf(static_cast(mod/radius)); + const float mod = streflop::fabsf(static_cast(random.randRange(-radius, radius))); + const float radRatio = streflop::sqrtf(static_cast(mod / radius)); #else - const float mod= fabsf(random.randRange(-radius, radius)); - const float radRatio= sqrtf(mod / radius); + const float mod = fabsf(random.randRange(-radius, radius)); + const float radRatio = sqrtf(mod / radius); #endif - p->color= color; + p->color = color; - if(isDaylightAffected==true) { - p->color.x=p->color.x*lightColor.x; - p->color.y=p->color.y*lightColor.y; - p->color.z=p->color.z*lightColor.z; - } - if(radiusBasedStartenergy == true) { - p->energy= static_cast (maxParticleEnergy * radRatio) + - random.randRange(-varParticleEnergy,varParticleEnergy); - } - else { - p->energy= static_cast (maxParticleEnergy) + - random.randRange(-varParticleEnergy, varParticleEnergy); - } + if (isDaylightAffected == true) { + p->color.x = p->color.x*lightColor.x; + p->color.y = p->color.y*lightColor.y; + p->color.z = p->color.z*lightColor.z; + } + if (radiusBasedStartenergy == true) { + p->energy = static_cast (maxParticleEnergy * radRatio) + + random.randRange(-varParticleEnergy, varParticleEnergy); + } else { + p->energy = static_cast (maxParticleEnergy) + + random.randRange(-varParticleEnergy, varParticleEnergy); + } - p->lastPos= pos; - oldPosition= pos; - p->size= particleSize; - p->speedUpRelative= speedUpRelative; - p->accel= Vec3f(0.0f, -gravity, 0.0f); - p->accel.x = truncateDecimal(p->accel.x,6); - p->accel.y = truncateDecimal(p->accel.y,6); - p->accel.z = truncateDecimal(p->accel.z,6); - - // work out where we start for our shape (set speed and pos) - switch(shape){ - case sSpherical: - angle = (float)random.randRange(0,360); - // fall through - case sConical:{ - Vec2f horiz = Vec2f(1,0).rotate(ang); - Vec2f vert = Vec2f(1,0).rotate(degToRad(angle)); - Vec3f start = Vec3f(horiz.x*vert.y,vert.x,horiz.y).getNormalized(); // close enough - p->speed = start * speed; - p->speed.x = truncateDecimal(p->speed.x,6); - p->speed.y = truncateDecimal(p->speed.y,6); - p->speed.z = truncateDecimal(p->speed.z,6); + p->lastPos = pos; + oldPosition = pos; + p->size = particleSize; + p->speedUpRelative = speedUpRelative; + p->accel = Vec3f(0.0f, -gravity, 0.0f); + p->accel.x = truncateDecimal(p->accel.x, 6); + p->accel.y = truncateDecimal(p->accel.y, 6); + p->accel.z = truncateDecimal(p->accel.z, 6); - start = start * random.randRange(minRadius,radius); - p->pos = pos + offset + start; - p->pos.x = truncateDecimal(p->pos.x,6); - p->pos.y = truncateDecimal(p->pos.y,6); - p->pos.z = truncateDecimal(p->pos.z,6); + // work out where we start for our shape (set speed and pos) + switch (shape) { + case sSpherical: + angle = (float) random.randRange(0, 360); + // fall through + case sConical: { + Vec2f horiz = Vec2f(1, 0).rotate(ang); + Vec2f vert = Vec2f(1, 0).rotate(degToRad(angle)); + Vec3f start = Vec3f(horiz.x*vert.y, vert.x, horiz.y).getNormalized(); // close enough + p->speed = start * speed; + p->speed.x = truncateDecimal(p->speed.x, 6); + p->speed.y = truncateDecimal(p->speed.y, 6); + p->speed.z = truncateDecimal(p->speed.z, 6); - } break; - case sLinear:{ - #ifdef USE_STREFLOP - float x= streflop::sinf(static_cast(ang))*mod; - float y= streflop::cosf(static_cast(ang))*mod; - #else - float x= sinf(ang) * mod; - float y= cosf(ang) * mod; - #endif - const float rad= degToRad(rotation); - if(!relative){ - p->pos= Vec3f(pos.x + x + offset.x, pos.y + - random.randRange(-radius / 2, radius / 2) + offset.y, - pos.z + y + offset.z); - p->pos.x = truncateDecimal(p->pos.x,6); - p->pos.y = truncateDecimal(p->pos.y,6); - p->pos.z = truncateDecimal(p->pos.z,6); + start = start * random.randRange(minRadius, radius); + p->pos = pos + offset + start; + p->pos.x = truncateDecimal(p->pos.x, 6); + p->pos.y = truncateDecimal(p->pos.y, 6); + p->pos.z = truncateDecimal(p->pos.z, 6); + } break; + case sLinear: { +#ifdef USE_STREFLOP + float x = streflop::sinf(static_cast(ang))*mod; + float y = streflop::cosf(static_cast(ang))*mod; +#else + float x = sinf(ang) * mod; + float y = cosf(ang) * mod; +#endif + const float rad = degToRad(rotation); + if (!relative) { + p->pos = Vec3f(pos.x + x + offset.x, pos.y + + random.randRange(-radius / 2, radius / 2) + offset.y, + pos.z + y + offset.z); + p->pos.x = truncateDecimal(p->pos.x, 6); + p->pos.y = truncateDecimal(p->pos.y, 6); + p->pos.z = truncateDecimal(p->pos.z, 6); + + } else { + Vec3f combinedOffset = Vec3f(offset); + if (meshName != "") { + combinedOffset.x += meshPos.x; + combinedOffset.y += meshPos.y; + combinedOffset.z += meshPos.z; + if (meshPos.x == 0 && meshPos.y == 0 && meshPos.z == 0) { + printf("meshPosFail\n"); + } + } + // rotate it according to rotation +#ifdef USE_STREFLOP + p->pos = Vec3f(pos.x + x + combinedOffset.z*streflop::sinf(static_cast(rad)) + combinedOffset.x*streflop::cosf(static_cast(rad)), pos.y + random.randRange(-radius / 2, radius / 2) + combinedOffset.y, pos.z + y + (combinedOffset.z*streflop::cosf(static_cast(rad)) - combinedOffset.x*streflop::sinf(static_cast(rad)))); +#else + p->pos = Vec3f(pos.x + x + combinedOffset.z * sinf(rad) + combinedOffset.x * cosf(rad), pos.y + random.randRange(-radius / 2, + radius / 2) + combinedOffset.y, pos.z + y + (combinedOffset.z * cosf(rad) - combinedOffset.x * sinf(rad))); +#endif + + p->pos.x = truncateDecimal(p->pos.x, 6); + p->pos.y = truncateDecimal(p->pos.y, 6); + p->pos.z = truncateDecimal(p->pos.z, 6); + + } + p->speed = Vec3f(direction.x + direction.x * random.randRange(-0.5f, 0.5f), direction.y + direction.y + * random.randRange(-0.5f, 0.5f), direction.z + direction.z * random.randRange(-0.5f, 0.5f)); + p->speed = p->speed * speed; + + p->speed.x = truncateDecimal(p->speed.x, 6); + p->speed.y = truncateDecimal(p->speed.y, 6); + p->speed.z = truncateDecimal(p->speed.z, 6); + + if (relative && relativeDirection) { +#ifdef USE_STREFLOP + p->speed = Vec3f(p->speed.z*streflop::sinf( + static_cast(rad)) + p->speed.x * + streflop::cosf(static_cast(rad)), + p->speed.y, (p->speed.z * streflop::cosf( + static_cast(rad)) - p->speed.x * + streflop::sinf(static_cast(rad)))); +#else + p->speed = Vec3f(p->speed.z * sinf(rad) + p->speed.x * cosf(rad), + p->speed.y, (p->speed.z * cosf(rad) - p->speed.x * sinf(rad))); +#endif + + p->speed.x = truncateDecimal(p->speed.x, 6); + p->speed.y = truncateDecimal(p->speed.y, 6); + p->speed.z = truncateDecimal(p->speed.z, 6); + } + } break; + default: throw megaglest_runtime_error("bad shape"); + } + //need to do that down here because we need p->speed for it. + p->speedUpConstant = Vec3f(speedUpConstant)*p->speed; } - else { - Vec3f combinedOffset=Vec3f(offset); - if(meshName!=""){ - combinedOffset.x+=meshPos.x; - combinedOffset.y+=meshPos.y; - combinedOffset.z+=meshPos.z; - if(meshPos.x==0 && meshPos.y==0 && meshPos.z==0) { - printf("meshPosFail\n"); + + void UnitParticleSystem::update() { + // delay and timeline are only applicable for child particles + if (parent && delay > 0 && delay--) { + return; + } + if (parent && lifetime > 0 && !--lifetime) { + fade(); + } + if (state != sPause) { + emissionRate -= emissionRateFade; + emissionRate = truncateDecimal(emissionRate, 6); + + if (parent && emissionRate < 0.0f) { + fade(); } } - // rotate it according to rotation - #ifdef USE_STREFLOP - p->pos= Vec3f(pos.x+x+combinedOffset.z*streflop::sinf(static_cast(rad))+combinedOffset.x*streflop::cosf(static_cast(rad)), pos.y+random.randRange(-radius/2, radius/2)+combinedOffset.y, pos.z+y+(combinedOffset.z*streflop::cosf(static_cast(rad))-combinedOffset.x*streflop::sinf(static_cast(rad)))); - #else - p->pos= Vec3f(pos.x + x + combinedOffset.z * sinf(rad) + combinedOffset.x * cosf(rad), pos.y + random.randRange(-radius / 2, - radius / 2) + combinedOffset.y, pos.z + y + (combinedOffset.z * cosf(rad) - combinedOffset.x * sinf(rad))); - #endif + if (fixed) { + fixedAddition = Vec3f(pos.x - oldPosition.x, pos.y - oldPosition.y, pos.z - oldPosition.z); + fixedAddition.x = truncateDecimal(fixedAddition.x, 6); + fixedAddition.y = truncateDecimal(fixedAddition.y, 6); + fixedAddition.z = truncateDecimal(fixedAddition.z, 6); - p->pos.x = truncateDecimal(p->pos.x,6); - p->pos.y = truncateDecimal(p->pos.y,6); - p->pos.z = truncateDecimal(p->pos.z,6); - - } - p->speed= Vec3f(direction.x + direction.x * random.randRange(-0.5f, 0.5f), direction.y + direction.y - * random.randRange(-0.5f, 0.5f), direction.z + direction.z * random.randRange(-0.5f, 0.5f)); - p->speed= p->speed * speed; - - p->speed.x = truncateDecimal(p->speed.x,6); - p->speed.y = truncateDecimal(p->speed.y,6); - p->speed.z = truncateDecimal(p->speed.z,6); - - if(relative && relativeDirection) { - #ifdef USE_STREFLOP - p->speed=Vec3f(p->speed.z*streflop::sinf( - static_cast(rad)) + p->speed.x * - streflop::cosf(static_cast(rad)), - p->speed.y, (p->speed.z * streflop::cosf( - static_cast(rad)) - p->speed.x * - streflop::sinf(static_cast(rad)))); - #else - p->speed= Vec3f(p->speed.z * sinf(rad) + p->speed.x * cosf(rad), - p->speed.y, (p->speed.z * cosf(rad) - p->speed.x * sinf(rad))); - #endif - - p->speed.x = truncateDecimal(p->speed.x,6); - p->speed.y = truncateDecimal(p->speed.y,6); - p->speed.z = truncateDecimal(p->speed.z,6); - } - } break; - default: throw megaglest_runtime_error("bad shape"); - } - //need to do that down here because we need p->speed for it. - p->speedUpConstant= Vec3f(speedUpConstant)*p->speed; -} - -void UnitParticleSystem::update(){ - // delay and timeline are only applicable for child particles - if(parent && delay > 0 && delay--) { - return; - } - if(parent && lifetime > 0 && !--lifetime) { - fade(); - } - if(state != sPause) { - emissionRate-= emissionRateFade; - emissionRate = truncateDecimal(emissionRate,6); - - if(parent && emissionRate < 0.0f) { - fade(); - } - } - if(fixed) { - fixedAddition= Vec3f(pos.x - oldPosition.x, pos.y - oldPosition.y, pos.z - oldPosition.z); - fixedAddition.x = truncateDecimal(fixedAddition.x,6); - fixedAddition.y = truncateDecimal(fixedAddition.y,6); - fixedAddition.z = truncateDecimal(fixedAddition.z,6); - - oldPosition= pos; - } - ParticleSystem::update(); -} - -void UnitParticleSystem::updateParticle(Particle *p){ - float energyRatio; - if(alternations > 0){ - int interval= (maxParticleEnergy / alternations); - float moduloValue= (float)((int)(static_cast (p->energy)) % interval); - float floatInterval=static_cast (interval); - - if(moduloValue < floatInterval / 2.0f){ - energyRatio= (floatInterval - moduloValue) / floatInterval; - } - else{ - energyRatio= moduloValue / floatInterval; - } - energyRatio= clamp(energyRatio, 0.f, 1.f); - } - else{ - energyRatio= clamp(static_cast (p->energy) / static_cast (maxParticleEnergy), 0.f, 1.f); - } - - energyRatio = truncateDecimal(energyRatio,6); - - p->lastPos += p->speed; - p->lastPos.x = truncateDecimal(p->lastPos.x,6); - p->lastPos.y = truncateDecimal(p->lastPos.y,6); - p->lastPos.z = truncateDecimal(p->lastPos.z,6); - - p->pos += p->speed; - p->pos.x = truncateDecimal(p->pos.x,6); - p->pos.y = truncateDecimal(p->pos.y,6); - p->pos.z = truncateDecimal(p->pos.z,6); - - if(fixed) { - p->lastPos += fixedAddition; - p->lastPos.x = truncateDecimal(p->lastPos.x,6); - p->lastPos.y = truncateDecimal(p->lastPos.y,6); - p->lastPos.z = truncateDecimal(p->lastPos.z,6); - - p->pos += fixedAddition; - p->pos.x = truncateDecimal(p->pos.x,6); - p->pos.y = truncateDecimal(p->pos.y,6); - p->pos.z = truncateDecimal(p->pos.z,6); - } - p->speed += p->accel; - p->speed += p->speedUpConstant; - p->speed=p->speed*(1+p->speedUpRelative); - p->speed.x = truncateDecimal(p->speed.x,6); - p->speed.y = truncateDecimal(p->speed.y,6); - p->speed.z = truncateDecimal(p->speed.z,6); - - p->color= color * energyRatio + colorNoEnergy * (1.0f - energyRatio); - if(isDaylightAffected==true) { - p->color.x=p->color.x*lightColor.x; - p->color.y=p->color.y*lightColor.y; - p->color.z=p->color.z*lightColor.z; - } - p->size= particleSize * energyRatio + sizeNoEnergy * (1.0f - energyRatio); - p->size = truncateDecimal(p->size,6); - - if(state == ParticleSystem::sFade || staticParticleCount < 1){ - p->energy--; - } - else{ - if(maxParticleEnergy > 2){ - if(energyUp){ - p->energy++; + oldPosition = pos; } - else{ + ParticleSystem::update(); + } + + void UnitParticleSystem::updateParticle(Particle *p) { + float energyRatio; + if (alternations > 0) { + int interval = (maxParticleEnergy / alternations); + float moduloValue = (float) ((int) (static_cast (p->energy)) % interval); + float floatInterval = static_cast (interval); + + if (moduloValue < floatInterval / 2.0f) { + energyRatio = (floatInterval - moduloValue) / floatInterval; + } else { + energyRatio = moduloValue / floatInterval; + } + energyRatio = clamp(energyRatio, 0.f, 1.f); + } else { + energyRatio = clamp(static_cast (p->energy) / static_cast (maxParticleEnergy), 0.f, 1.f); + } + + energyRatio = truncateDecimal(energyRatio, 6); + + p->lastPos += p->speed; + p->lastPos.x = truncateDecimal(p->lastPos.x, 6); + p->lastPos.y = truncateDecimal(p->lastPos.y, 6); + p->lastPos.z = truncateDecimal(p->lastPos.z, 6); + + p->pos += p->speed; + p->pos.x = truncateDecimal(p->pos.x, 6); + p->pos.y = truncateDecimal(p->pos.y, 6); + p->pos.z = truncateDecimal(p->pos.z, 6); + + if (fixed) { + p->lastPos += fixedAddition; + p->lastPos.x = truncateDecimal(p->lastPos.x, 6); + p->lastPos.y = truncateDecimal(p->lastPos.y, 6); + p->lastPos.z = truncateDecimal(p->lastPos.z, 6); + + p->pos += fixedAddition; + p->pos.x = truncateDecimal(p->pos.x, 6); + p->pos.y = truncateDecimal(p->pos.y, 6); + p->pos.z = truncateDecimal(p->pos.z, 6); + } + p->speed += p->accel; + p->speed += p->speedUpConstant; + p->speed = p->speed*(1 + p->speedUpRelative); + p->speed.x = truncateDecimal(p->speed.x, 6); + p->speed.y = truncateDecimal(p->speed.y, 6); + p->speed.z = truncateDecimal(p->speed.z, 6); + + p->color = color * energyRatio + colorNoEnergy * (1.0f - energyRatio); + if (isDaylightAffected == true) { + p->color.x = p->color.x*lightColor.x; + p->color.y = p->color.y*lightColor.y; + p->color.z = p->color.z*lightColor.z; + } + p->size = particleSize * energyRatio + sizeNoEnergy * (1.0f - energyRatio); + p->size = truncateDecimal(p->size, 6); + + if (state == ParticleSystem::sFade || staticParticleCount < 1) { p->energy--; - } - - if(p->energy == 1){ - energyUp= true; - } - if(p->energy == maxParticleEnergy){ - energyUp= false; - } - } - } -} - -// ================= SET PARAMS ==================== - -void UnitParticleSystem::setWind(float windAngle, float windSpeed){ -#ifdef USE_STREFLOP - this->windSpeed.x= streflop::sinf(static_cast(degToRad(windAngle)))*windSpeed; - this->windSpeed.y= 0.0f; - this->windSpeed.z= streflop::cosf(static_cast(degToRad(windAngle)))*windSpeed; -#else - this->windSpeed.x= sinf(degToRad(windAngle)) * windSpeed; - this->windSpeed.y= 0.0f; - this->windSpeed.z= cosf(degToRad(windAngle)) * windSpeed; -#endif - - this->windSpeed.x = truncateDecimal(this->windSpeed.x,6); - this->windSpeed.y = truncateDecimal(this->windSpeed.y,6); - this->windSpeed.z = truncateDecimal(this->windSpeed.z,6); -} - -void UnitParticleSystem::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *unitParticleSystemNode = rootNode->addChild("UnitParticleSystem"); - - GameParticleSystem::saveGame(unitParticleSystemNode); - -// float radius; - unitParticleSystemNode->addAttribute("radius",floatToStr(radius,6), mapTagReplacements); -// float minRadius; - unitParticleSystemNode->addAttribute("minRadius",floatToStr(minRadius,6), mapTagReplacements); -// Vec3f windSpeed; - unitParticleSystemNode->addAttribute("windSpeed",windSpeed.getString(), mapTagReplacements); -// Vec3f cRotation; - unitParticleSystemNode->addAttribute("cRotation",cRotation.getString(), mapTagReplacements); -// Vec3f fixedAddition; - unitParticleSystemNode->addAttribute("fixedAddition",fixedAddition.getString(), mapTagReplacements); -// Vec3f oldPosition; - unitParticleSystemNode->addAttribute("oldPosition",oldPosition.getString(), mapTagReplacements); -// Vec3f meshPos; - unitParticleSystemNode->addAttribute("meshPos",meshPos.getString(), mapTagReplacements); -// string meshName; - unitParticleSystemNode->addAttribute("meshName",meshName, mapTagReplacements); -// bool energyUp; - unitParticleSystemNode->addAttribute("energyUp",intToStr(energyUp), mapTagReplacements); -// float startTime; - unitParticleSystemNode->addAttribute("startTime",floatToStr(startTime,6), mapTagReplacements); -// float endTime; - unitParticleSystemNode->addAttribute("endTime",floatToStr(endTime,6), mapTagReplacements); -// bool relative; - unitParticleSystemNode->addAttribute("relative",intToStr(relative), mapTagReplacements); -// bool relativeDirection; - unitParticleSystemNode->addAttribute("relativeDirection",intToStr(relativeDirection), mapTagReplacements); -// bool fixed; - unitParticleSystemNode->addAttribute("fixed",intToStr(fixed), mapTagReplacements); -// Shape shape; - unitParticleSystemNode->addAttribute("shape",intToStr(shape), mapTagReplacements); -// float angle; - unitParticleSystemNode->addAttribute("angle",floatToStr(angle,6), mapTagReplacements); -// float sizeNoEnergy; - unitParticleSystemNode->addAttribute("sizeNoEnergy",floatToStr(sizeNoEnergy,6), mapTagReplacements); -// float gravity; - unitParticleSystemNode->addAttribute("gravity",floatToStr(gravity,6), mapTagReplacements); -// float rotation; - unitParticleSystemNode->addAttribute("rotation",floatToStr(rotation,6), mapTagReplacements); -// bool isVisibleAtNight; - unitParticleSystemNode->addAttribute("isVisibleAtNight",intToStr(isVisibleAtNight), mapTagReplacements); -// bool isVisibleAtDay; - unitParticleSystemNode->addAttribute("isVisibleAtDay",intToStr(isVisibleAtDay), mapTagReplacements); -// bool isDaylightAffected; - unitParticleSystemNode->addAttribute("isDaylightAffected",intToStr(isDaylightAffected), mapTagReplacements); -// bool radiusBasedStartenergy; - unitParticleSystemNode->addAttribute("radiusBasedStartenergy",intToStr(radiusBasedStartenergy), mapTagReplacements); -// int staticParticleCount; - unitParticleSystemNode->addAttribute("staticParticleCount",intToStr(staticParticleCount), mapTagReplacements); -// int delay; - unitParticleSystemNode->addAttribute("delay",intToStr(delay), mapTagReplacements); -// int lifetime; - unitParticleSystemNode->addAttribute("lifetime",intToStr(lifetime), mapTagReplacements); -// float emissionRateFade; - unitParticleSystemNode->addAttribute("emissionRateFade",floatToStr(emissionRateFade,6), mapTagReplacements); -// GameParticleSystem* parent; - //if(parent != NULL) { - // parent->saveGame(unitParticleSystemNode); - //} -} - -void UnitParticleSystem::loadGame(const XmlNode *rootNode) { - const XmlNode *unitParticleSystemNode = rootNode; - - //printf("Load Smoke particle (UnitParticleSystem)\n"); - GameParticleSystem::loadGame(unitParticleSystemNode); - -// float radius; - radius = unitParticleSystemNode->getAttribute("radius")->getFloatValue(); -// float minRadius; - minRadius = unitParticleSystemNode->getAttribute("minRadius")->getFloatValue(); -// Vec3f windSpeed; - windSpeed = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("windSpeed")->getValue()); -// Vec3f cRotation; - cRotation = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("cRotation")->getValue()); -// Vec3f fixedAddition; - fixedAddition = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("fixedAddition")->getValue()); -// Vec3f oldPosition; - oldPosition = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("oldPosition")->getValue()); - // Vec3f meshPos; - if(unitParticleSystemNode->hasAttribute("meshPos")){ - meshPos = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("meshPos")->getValue()); - } - // Vec3f meshName; - if(unitParticleSystemNode->hasAttribute("meshName")){ - meshName = unitParticleSystemNode->getAttribute("meshName")->getValue(); - } -// bool energyUp; - energyUp = unitParticleSystemNode->getAttribute("energyUp")->getIntValue() != 0; -// float startTime; - startTime = unitParticleSystemNode->getAttribute("startTime")->getFloatValue(); -// float endTime; - endTime = unitParticleSystemNode->getAttribute("endTime")->getFloatValue(); -// bool relative; - relative = unitParticleSystemNode->getAttribute("relative")->getIntValue() != 0; -// bool relativeDirection; - relativeDirection = unitParticleSystemNode->getAttribute("relativeDirection")->getIntValue() != 0; -// bool fixed; - fixed = unitParticleSystemNode->getAttribute("fixed")->getIntValue() != 0; -// Shape shape; - shape = static_cast(unitParticleSystemNode->getAttribute("shape")->getIntValue()); -// float angle; - angle = unitParticleSystemNode->getAttribute("angle")->getFloatValue(); -// float sizeNoEnergy; - sizeNoEnergy = unitParticleSystemNode->getAttribute("sizeNoEnergy")->getFloatValue(); -// float gravity; - gravity = unitParticleSystemNode->getAttribute("gravity")->getFloatValue(); -// float rotation; - rotation = unitParticleSystemNode->getAttribute("rotation")->getFloatValue(); -// bool isVisibleAtNight; - isVisibleAtNight = unitParticleSystemNode->getAttribute("isVisibleAtNight")->getIntValue() != 0; -// bool isVisibleAtDay; - isVisibleAtDay = unitParticleSystemNode->getAttribute("isVisibleAtDay")->getIntValue() != 0; -// bool isDaylightAffected; - isDaylightAffected = unitParticleSystemNode->getAttribute("isDaylightAffected")->getIntValue() != 0; -// bool radiusBasedStartenergy; - radiusBasedStartenergy = unitParticleSystemNode->getAttribute("radiusBasedStartenergy")->getIntValue() != 0; -// int staticParticleCount; - staticParticleCount = unitParticleSystemNode->getAttribute("staticParticleCount")->getIntValue(); -// int delay; - delay = unitParticleSystemNode->getAttribute("delay")->getIntValue(); -// int lifetime; - lifetime = unitParticleSystemNode->getAttribute("lifetime")->getIntValue(); -// float emissionRateFade; - emissionRateFade = unitParticleSystemNode->getAttribute("emissionRateFade")->getFloatValue(); -// GameParticleSystem* parent; - parent = NULL; - //if(parent != NULL) { - // parent->saveGame(unitParticleSystemNode); - //} - - //if(unitParticleSystemNode->hasChild("GameParticleSystem") == true) { -// void GameParticleSystem::saveGame(XmlNode *rootNode) -// std::map mapTagReplacements; -// XmlNode *gameParticleSystemNode = rootNode->addChild("GameParticleSystem"); - //XmlNode *gameParticleSystemNode = unitParticleSystemNode->getChild("GameParticleSystem"); - //!!! - //} -} - -Checksum UnitParticleSystem::getCRC() { - Checksum crcForParticleSystem = GameParticleSystem::getCRC(); - - return crcForParticleSystem; -} - -string UnitParticleSystem::toString() const { - string result = GameParticleSystem::toString(); - - result += "\nUnitParticleSystem "; - result += "\nradius = " + floatToStr(radius); - result += "\nminRadius = " + floatToStr(minRadius); - result += "\nwindSpeed = " + windSpeed.getString(); - result += "\ncRotation = " + cRotation.getString(); - result += "\nfixedAddition = " + fixedAddition.getString(); - result += "\noldPosition = " + oldPosition.getString(); - result += "\nenergyUp = " + intToStr(energyUp); - result += "\nstartTime = " + floatToStr(startTime); - result += "\nendTime = " + floatToStr(endTime); - result += "\nrelative = " + intToStr(relative); - result += "\nrelativeDirection = " + intToStr(relativeDirection); - result += "\nfixed = " + intToStr(fixed); - result += "\nshape = " + intToStr(shape); - - result += "\nangle = " + floatToStr(angle); - result += "\nsizeNoEnergy = " + floatToStr(sizeNoEnergy); - result += "\ngravity = " + floatToStr(gravity); - result += "\nrotation = " + floatToStr(rotation); - result += "\nisVisibleAtNight = " + intToStr(isVisibleAtNight); - result += "\nisVisibleAtDay = " + intToStr(isVisibleAtDay); - result += "\nisDaylightAffected = " + intToStr(isDaylightAffected); - result += "\nradiusBasedStartenergy = " + intToStr(radiusBasedStartenergy); - result += "\nstaticParticleCount = " + intToStr(staticParticleCount); - result += "\ndelay = " + intToStr(delay); - result += "\nlifetime = " + intToStr(lifetime); - result += "\nemissionRateFade = " + floatToStr(emissionRateFade); - //GameParticleSystem* parent; - - return result; -} - -// =========================================================================== -// RainParticleSystem -// =========================================================================== -RainParticleSystem::RainParticleSystem(int particleCount) : - ParticleSystem(particleCount){ - setWind(0.0f, 0.0f); - setRadius(20.0f); - - setEmissionRate(25.0f); - setParticleSize(3.0f); - setColor(Vec4f(0.5f, 0.5f, 0.5f, 0.3f)); - setSpeed(0.2f); -} - -void RainParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr){ - pr->renderSystemLineAlpha(this); -} - -void RainParticleSystem::initParticle(Particle *p, int particleIndex){ - ParticleSystem::initParticle(p, particleIndex); - - float x= random.randRange(-radius, radius); - float y= random.randRange(-radius, radius); - - p->color= color; - p->energy= 10000; - p->pos= Vec3f(pos.x + x, pos.y, pos.z + y); - p->pos.x = truncateDecimal(p->pos.x,6); - p->pos.y = truncateDecimal(p->pos.y,6); - p->pos.z = truncateDecimal(p->pos.z,6); - - p->lastPos= p->pos; - p->speed= Vec3f(random.randRange(-speed / 10, speed / 10), -speed, - random.randRange(-speed / 10, speed / 10)) + windSpeed; - p->speed.x = truncateDecimal(p->speed.x,6); - p->speed.y = truncateDecimal(p->speed.y,6); - p->speed.z = truncateDecimal(p->speed.z,6); -} - -bool RainParticleSystem::deathTest(Particle *p){ - return p->pos.y < 0; -} - -void RainParticleSystem::setRadius(float radius) { - this->radius= radius; -} - -void RainParticleSystem::setWind(float windAngle, float windSpeed){ -#ifdef USE_STREFLOP - this->windSpeed.x= streflop::sinf(static_cast(degToRad(windAngle)))*windSpeed; - this->windSpeed.y= 0.0f; - this->windSpeed.z= streflop::cosf(static_cast(degToRad(windAngle)))*windSpeed; -#else - this->windSpeed.x= sinf(degToRad(windAngle)) * windSpeed; - this->windSpeed.y= 0.0f; - this->windSpeed.z= cosf(degToRad(windAngle)) * windSpeed; -#endif - - this->windSpeed.x = truncateDecimal(this->windSpeed.x,6); - this->windSpeed.y = truncateDecimal(this->windSpeed.y,6); - this->windSpeed.z = truncateDecimal(this->windSpeed.z,6); -} - -Checksum RainParticleSystem::getCRC() { - Checksum crcForParticleSystem = ParticleSystem::getCRC(); - - return crcForParticleSystem; -} - -string RainParticleSystem::toString() const { - string result = ParticleSystem::toString(); - - result += "\nRainParticleSystem "; - result += "\nwindSpeed = " + windSpeed.getString(); - result += "\nradius = " + floatToStr(radius); - - return result; -} - -// =========================================================================== -// SnowParticleSystem -// =========================================================================== - -SnowParticleSystem::SnowParticleSystem(int particleCount) : - ParticleSystem(particleCount){ - setWind(0.0f, 0.0f); - setRadius(30.0f); - - setEmissionRate(2.0f); - setParticleSize(0.2f); - setColor(Vec4f(0.8f, 0.8f, 0.8f, 0.8f)); - setSpeed(0.05f); -} - -void SnowParticleSystem::initParticle(Particle *p, int particleIndex){ - - ParticleSystem::initParticle(p, particleIndex); - - float x= random.randRange(-radius, radius); - float y= random.randRange(-radius, radius); - - p->color= color; - p->energy= 10000; - p->pos= Vec3f(pos.x + x, pos.y, pos.z + y); - p->pos.x = truncateDecimal(p->pos.x,6); - p->pos.y = truncateDecimal(p->pos.y,6); - p->pos.z = truncateDecimal(p->pos.z,6); - - p->lastPos= p->pos; - p->speed= Vec3f(0.0f, -speed, 0.0f) + windSpeed; - p->speed.x+= random.randRange(-0.005f, 0.005f); - p->speed.y+= random.randRange(-0.005f, 0.005f); - - p->speed.x = truncateDecimal(p->speed.x,6); - p->speed.y = truncateDecimal(p->speed.y,6); - p->speed.z = truncateDecimal(p->speed.z,6); -} - -bool SnowParticleSystem::deathTest(Particle *p){ - return p->pos.y < 0; -} - -void SnowParticleSystem::setRadius(float radius){ - this->radius= radius; -} - -void SnowParticleSystem::setWind(float windAngle, float windSpeed){ -#ifdef USE_STREFLOP - this->windSpeed.x= streflop::sinf(static_cast(degToRad(windAngle)))*windSpeed; - this->windSpeed.y= 0.0f; - this->windSpeed.z= streflop::cosf(static_cast(degToRad(windAngle)))*windSpeed; -#else - this->windSpeed.x= sinf(degToRad(windAngle)) * windSpeed; - this->windSpeed.y= 0.0f; - this->windSpeed.z= cosf(degToRad(windAngle)) * windSpeed; -#endif - - this->windSpeed.x = truncateDecimal(this->windSpeed.x,6); - this->windSpeed.y = truncateDecimal(this->windSpeed.y,6); - this->windSpeed.z = truncateDecimal(this->windSpeed.z,6); - -} - -Checksum SnowParticleSystem::getCRC() { - Checksum crcForParticleSystem = ParticleSystem::getCRC(); - - return crcForParticleSystem; -} - -string SnowParticleSystem::toString() const { - string result = ParticleSystem::toString(); - - result += "\nSnowParticleSystem "; - result += "\nwindSpeed = " + windSpeed.getString(); - result += "\nradius = " + floatToStr(radius); - - return result; -} - -// =========================================================================== -// AttackParticleSystem -// =========================================================================== - -AttackParticleSystem::AttackParticleSystem(int particleCount) : - GameParticleSystem(particleCount){ - primitive= pQuad; - gravity= 0.0f; - sizeNoEnergy = 0.0; -} - -void AttackParticleSystem::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *attackParticleSystemNode = rootNode->addChild("AttackParticleSystem"); - - GameParticleSystem::saveGame(attackParticleSystemNode); - -// float sizeNoEnergy; - attackParticleSystemNode->addAttribute("sizeNoEnergy",floatToStr(sizeNoEnergy,6), mapTagReplacements); -// float gravity; - attackParticleSystemNode->addAttribute("gravity",floatToStr(gravity,6), mapTagReplacements); - -} -void AttackParticleSystem::loadGame(const XmlNode *rootNode) { - const XmlNode *attackParticleSystemNode = rootNode; - - GameParticleSystem::loadGame(attackParticleSystemNode); - - // float sizeNoEnergy; - sizeNoEnergy = attackParticleSystemNode->getAttribute("sizeNoEnergy")->getFloatValue(); - // float gravity; - gravity = attackParticleSystemNode->getAttribute("gravity")->getFloatValue(); -} - -Checksum AttackParticleSystem::getCRC() { - Checksum crcForParticleSystem = GameParticleSystem::getCRC(); - - return crcForParticleSystem; -} - -string AttackParticleSystem::toString() const { - string result = GameParticleSystem::toString(); - - result += "\nAttackParticleSystem "; - result += "\nsizeNoEnergy = " + floatToStr(sizeNoEnergy); - result += "\ngravity = " + floatToStr(gravity); - - return result; -} - -// =========================================================================== -// ProjectileParticleSystem -// =========================================================================== - -ProjectileParticleSystem::ProjectileParticleSystem(int particleCount) : - AttackParticleSystem(particleCount){ - setEmissionRate(20.0f); - setColor(Vec4f(1.0f, 0.3f, 0.0f, 0.5f)); - setMaxParticleEnergy(100); - setVarParticleEnergy(50); - setParticleSize(0.4f); - setSpeed(0.14f); - - trajectory= tLinear; - - trajectorySpeed= 1.0f; - trajectoryScale= 1.0f; - trajectoryFrequency= 1.0f; - modelCycle=0.0f; - - nextParticleSystem= NULL; - arriveDestinationDistance = 0.0f; - //printf("#aXX trajectorySpeed = %f\n",trajectorySpeed); -} - -ProjectileParticleSystem::~ProjectileParticleSystem(){ - if(nextParticleSystem != NULL){ - nextParticleSystem->prevParticleSystem= NULL; - } -} - -void ProjectileParticleSystem::link(SplashParticleSystem *particleSystem){ - nextParticleSystem= particleSystem; - nextParticleSystem->setVisible(false); - nextParticleSystem->setState(sPause); - nextParticleSystem->prevParticleSystem= this; -} - -void ProjectileParticleSystem::update(){ - //printf("Projectile particle system updating...\n"); - if(state == sPlay){ - - lastPos = pos; - flatPos += zVector * truncateDecimal(trajectorySpeed,6); - flatPos.x = truncateDecimal(flatPos.x,6); - flatPos.y = truncateDecimal(flatPos.y,6); - flatPos.z = truncateDecimal(flatPos.z,6); - - Vec3f targetVector = endPos - startPos; - targetVector.x = truncateDecimal(targetVector.x,6); - targetVector.y = truncateDecimal(targetVector.y,6); - targetVector.z = truncateDecimal(targetVector.z,6); - - Vec3f currentVector = flatPos - startPos; - currentVector.x = truncateDecimal(currentVector.x,6); - currentVector.y = truncateDecimal(currentVector.y,6); - currentVector.z = truncateDecimal(currentVector.z,6); - - // ratio - float relative= clamp(currentVector.length() / targetVector.length(), 0.0f, 1.0f); - relative = truncateDecimal(relative,6); - - float absolute = relative; - setTween(relative,absolute); - - // trajectory - switch(trajectory) { - case tLinear: { - pos= flatPos; + } else { + if (maxParticleEnergy > 2) { + if (energyUp) { + p->energy++; + } else { + p->energy--; + } + + if (p->energy == 1) { + energyUp = true; + } + if (p->energy == maxParticleEnergy) { + energyUp = false; + } } - break; + } + } - case tParabolic: { - float scaledT = truncateDecimal(2.0f * (relative - 0.5f),6); - float paraboleY = truncateDecimal((1.0f - scaledT * scaledT) * trajectoryScale,6); + // ================= SET PARAMS ==================== - pos= flatPos; - pos.y += paraboleY; - pos.y = truncateDecimal(pos.y,6); - } - break; - - case tSpiral: { - pos= flatPos; + void UnitParticleSystem::setWind(float windAngle, float windSpeed) { #ifdef USE_STREFLOP - pos+= xVector * streflop::cos(static_cast(relative * trajectoryFrequency * targetVector.length())) * trajectoryScale; - pos.x = truncateDecimal(pos.x,6); - pos.y = truncateDecimal(pos.y,6); - pos.z = truncateDecimal(pos.z,6); - - pos+= yVector * streflop::sin(static_cast(relative * trajectoryFrequency * targetVector.length())) * trajectoryScale; + this->windSpeed.x = streflop::sinf(static_cast(degToRad(windAngle)))*windSpeed; + this->windSpeed.y = 0.0f; + this->windSpeed.z = streflop::cosf(static_cast(degToRad(windAngle)))*windSpeed; #else - pos+= xVector * cos(relative * trajectoryFrequency * targetVector.length()) * trajectoryScale; - pos.x = truncateDecimal(pos.x,6); - pos.y = truncateDecimal(pos.y,6); - pos.z = truncateDecimal(pos.z,6); - - pos+= yVector * sin(relative * trajectoryFrequency * targetVector.length()) * trajectoryScale; + this->windSpeed.x = sinf(degToRad(windAngle)) * windSpeed; + this->windSpeed.y = 0.0f; + this->windSpeed.z = cosf(degToRad(windAngle)) * windSpeed; #endif - pos.x = truncateDecimal(pos.x,6); - pos.y = truncateDecimal(pos.y,6); - pos.z = truncateDecimal(pos.z,6); - } - break; - default: - assert(false); - break; + this->windSpeed.x = truncateDecimal(this->windSpeed.x, 6); + this->windSpeed.y = truncateDecimal(this->windSpeed.y, 6); + this->windSpeed.z = truncateDecimal(this->windSpeed.z, 6); } - direction= (pos - lastPos); - direction.x = truncateDecimal(direction.x,6); - direction.y = truncateDecimal(direction.y,6); - direction.z = truncateDecimal(direction.z,6); + void UnitParticleSystem::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *unitParticleSystemNode = rootNode->addChild("UnitParticleSystem"); - direction.normalize(); - direction.x = truncateDecimal(direction.x,6); - direction.y = truncateDecimal(direction.y,6); - direction.z = truncateDecimal(direction.z,6); + GameParticleSystem::saveGame(unitParticleSystemNode); - // trigger update of child particles - positionChildren(); - rotateChildren(); - - //arrive destination - arriveDestinationDistance = truncateDecimal(flatPos.dist(endPos),6); - - if(this->particleOwner != NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"LINE: %d arriveDestinationDistance = %f",__LINE__,arriveDestinationDistance); - this->particleOwner->logParticleInfo(szBuf); + // float radius; + unitParticleSystemNode->addAttribute("radius", floatToStr(radius, 6), mapTagReplacements); + // float minRadius; + unitParticleSystemNode->addAttribute("minRadius", floatToStr(minRadius, 6), mapTagReplacements); + // Vec3f windSpeed; + unitParticleSystemNode->addAttribute("windSpeed", windSpeed.getString(), mapTagReplacements); + // Vec3f cRotation; + unitParticleSystemNode->addAttribute("cRotation", cRotation.getString(), mapTagReplacements); + // Vec3f fixedAddition; + unitParticleSystemNode->addAttribute("fixedAddition", fixedAddition.getString(), mapTagReplacements); + // Vec3f oldPosition; + unitParticleSystemNode->addAttribute("oldPosition", oldPosition.getString(), mapTagReplacements); + // Vec3f meshPos; + unitParticleSystemNode->addAttribute("meshPos", meshPos.getString(), mapTagReplacements); + // string meshName; + unitParticleSystemNode->addAttribute("meshName", meshName, mapTagReplacements); + // bool energyUp; + unitParticleSystemNode->addAttribute("energyUp", intToStr(energyUp), mapTagReplacements); + // float startTime; + unitParticleSystemNode->addAttribute("startTime", floatToStr(startTime, 6), mapTagReplacements); + // float endTime; + unitParticleSystemNode->addAttribute("endTime", floatToStr(endTime, 6), mapTagReplacements); + // bool relative; + unitParticleSystemNode->addAttribute("relative", intToStr(relative), mapTagReplacements); + // bool relativeDirection; + unitParticleSystemNode->addAttribute("relativeDirection", intToStr(relativeDirection), mapTagReplacements); + // bool fixed; + unitParticleSystemNode->addAttribute("fixed", intToStr(fixed), mapTagReplacements); + // Shape shape; + unitParticleSystemNode->addAttribute("shape", intToStr(shape), mapTagReplacements); + // float angle; + unitParticleSystemNode->addAttribute("angle", floatToStr(angle, 6), mapTagReplacements); + // float sizeNoEnergy; + unitParticleSystemNode->addAttribute("sizeNoEnergy", floatToStr(sizeNoEnergy, 6), mapTagReplacements); + // float gravity; + unitParticleSystemNode->addAttribute("gravity", floatToStr(gravity, 6), mapTagReplacements); + // float rotation; + unitParticleSystemNode->addAttribute("rotation", floatToStr(rotation, 6), mapTagReplacements); + // bool isVisibleAtNight; + unitParticleSystemNode->addAttribute("isVisibleAtNight", intToStr(isVisibleAtNight), mapTagReplacements); + // bool isVisibleAtDay; + unitParticleSystemNode->addAttribute("isVisibleAtDay", intToStr(isVisibleAtDay), mapTagReplacements); + // bool isDaylightAffected; + unitParticleSystemNode->addAttribute("isDaylightAffected", intToStr(isDaylightAffected), mapTagReplacements); + // bool radiusBasedStartenergy; + unitParticleSystemNode->addAttribute("radiusBasedStartenergy", intToStr(radiusBasedStartenergy), mapTagReplacements); + // int staticParticleCount; + unitParticleSystemNode->addAttribute("staticParticleCount", intToStr(staticParticleCount), mapTagReplacements); + // int delay; + unitParticleSystemNode->addAttribute("delay", intToStr(delay), mapTagReplacements); + // int lifetime; + unitParticleSystemNode->addAttribute("lifetime", intToStr(lifetime), mapTagReplacements); + // float emissionRateFade; + unitParticleSystemNode->addAttribute("emissionRateFade", floatToStr(emissionRateFade, 6), mapTagReplacements); + // GameParticleSystem* parent; + //if(parent != NULL) { + // parent->saveGame(unitParticleSystemNode); + //} } - if(arriveDestinationDistance < 0.5f) { - fade(); - model= NULL; + void UnitParticleSystem::loadGame(const XmlNode *rootNode) { + const XmlNode *unitParticleSystemNode = rootNode; - if(particleObserver != NULL){ - particleObserver->update(this); - particleObserver=NULL; - } + //printf("Load Smoke particle (UnitParticleSystem)\n"); + GameParticleSystem::loadGame(unitParticleSystemNode); - if(nextParticleSystem != NULL){ - nextParticleSystem->setVisible(getVisible()); - nextParticleSystem->setState(sPlay); - nextParticleSystem->setPos(endPos); + // float radius; + radius = unitParticleSystemNode->getAttribute("radius")->getFloatValue(); + // float minRadius; + minRadius = unitParticleSystemNode->getAttribute("minRadius")->getFloatValue(); + // Vec3f windSpeed; + windSpeed = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("windSpeed")->getValue()); + // Vec3f cRotation; + cRotation = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("cRotation")->getValue()); + // Vec3f fixedAddition; + fixedAddition = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("fixedAddition")->getValue()); + // Vec3f oldPosition; + oldPosition = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("oldPosition")->getValue()); + // Vec3f meshPos; + if (unitParticleSystemNode->hasAttribute("meshPos")) { + meshPos = Vec3f::strToVec3(unitParticleSystemNode->getAttribute("meshPos")->getValue()); } + // Vec3f meshName; + if (unitParticleSystemNode->hasAttribute("meshName")) { + meshName = unitParticleSystemNode->getAttribute("meshName")->getValue(); + } + // bool energyUp; + energyUp = unitParticleSystemNode->getAttribute("energyUp")->getIntValue() != 0; + // float startTime; + startTime = unitParticleSystemNode->getAttribute("startTime")->getFloatValue(); + // float endTime; + endTime = unitParticleSystemNode->getAttribute("endTime")->getFloatValue(); + // bool relative; + relative = unitParticleSystemNode->getAttribute("relative")->getIntValue() != 0; + // bool relativeDirection; + relativeDirection = unitParticleSystemNode->getAttribute("relativeDirection")->getIntValue() != 0; + // bool fixed; + fixed = unitParticleSystemNode->getAttribute("fixed")->getIntValue() != 0; + // Shape shape; + shape = static_cast(unitParticleSystemNode->getAttribute("shape")->getIntValue()); + // float angle; + angle = unitParticleSystemNode->getAttribute("angle")->getFloatValue(); + // float sizeNoEnergy; + sizeNoEnergy = unitParticleSystemNode->getAttribute("sizeNoEnergy")->getFloatValue(); + // float gravity; + gravity = unitParticleSystemNode->getAttribute("gravity")->getFloatValue(); + // float rotation; + rotation = unitParticleSystemNode->getAttribute("rotation")->getFloatValue(); + // bool isVisibleAtNight; + isVisibleAtNight = unitParticleSystemNode->getAttribute("isVisibleAtNight")->getIntValue() != 0; + // bool isVisibleAtDay; + isVisibleAtDay = unitParticleSystemNode->getAttribute("isVisibleAtDay")->getIntValue() != 0; + // bool isDaylightAffected; + isDaylightAffected = unitParticleSystemNode->getAttribute("isDaylightAffected")->getIntValue() != 0; + // bool radiusBasedStartenergy; + radiusBasedStartenergy = unitParticleSystemNode->getAttribute("radiusBasedStartenergy")->getIntValue() != 0; + // int staticParticleCount; + staticParticleCount = unitParticleSystemNode->getAttribute("staticParticleCount")->getIntValue(); + // int delay; + delay = unitParticleSystemNode->getAttribute("delay")->getIntValue(); + // int lifetime; + lifetime = unitParticleSystemNode->getAttribute("lifetime")->getIntValue(); + // float emissionRateFade; + emissionRateFade = unitParticleSystemNode->getAttribute("emissionRateFade")->getFloatValue(); + // GameParticleSystem* parent; + parent = NULL; + //if(parent != NULL) { + // parent->saveGame(unitParticleSystemNode); + //} + + //if(unitParticleSystemNode->hasChild("GameParticleSystem") == true) { + // void GameParticleSystem::saveGame(XmlNode *rootNode) + // std::map mapTagReplacements; + // XmlNode *gameParticleSystemNode = rootNode->addChild("GameParticleSystem"); + //XmlNode *gameParticleSystemNode = unitParticleSystemNode->getChild("GameParticleSystem"); + //!!! + //} } - } - ParticleSystem::update(); -} + Checksum UnitParticleSystem::getCRC() { + Checksum crcForParticleSystem = GameParticleSystem::getCRC(); -void ProjectileParticleSystem::rotateChildren() { - //### only on horizontal plane :( + return crcForParticleSystem; + } + + string UnitParticleSystem::toString() const { + string result = GameParticleSystem::toString(); + + result += "\nUnitParticleSystem "; + result += "\nradius = " + floatToStr(radius); + result += "\nminRadius = " + floatToStr(minRadius); + result += "\nwindSpeed = " + windSpeed.getString(); + result += "\ncRotation = " + cRotation.getString(); + result += "\nfixedAddition = " + fixedAddition.getString(); + result += "\noldPosition = " + oldPosition.getString(); + result += "\nenergyUp = " + intToStr(energyUp); + result += "\nstartTime = " + floatToStr(startTime); + result += "\nendTime = " + floatToStr(endTime); + result += "\nrelative = " + intToStr(relative); + result += "\nrelativeDirection = " + intToStr(relativeDirection); + result += "\nfixed = " + intToStr(fixed); + result += "\nshape = " + intToStr(shape); + + result += "\nangle = " + floatToStr(angle); + result += "\nsizeNoEnergy = " + floatToStr(sizeNoEnergy); + result += "\ngravity = " + floatToStr(gravity); + result += "\nrotation = " + floatToStr(rotation); + result += "\nisVisibleAtNight = " + intToStr(isVisibleAtNight); + result += "\nisVisibleAtDay = " + intToStr(isVisibleAtDay); + result += "\nisDaylightAffected = " + intToStr(isDaylightAffected); + result += "\nradiusBasedStartenergy = " + intToStr(radiusBasedStartenergy); + result += "\nstaticParticleCount = " + intToStr(staticParticleCount); + result += "\ndelay = " + intToStr(delay); + result += "\nlifetime = " + intToStr(lifetime); + result += "\nemissionRateFade = " + floatToStr(emissionRateFade); + //GameParticleSystem* parent; + + return result; + } + + // =========================================================================== + // RainParticleSystem + // =========================================================================== + RainParticleSystem::RainParticleSystem(int particleCount) : + ParticleSystem(particleCount) { + setWind(0.0f, 0.0f); + setRadius(20.0f); + + setEmissionRate(25.0f); + setParticleSize(3.0f); + setColor(Vec4f(0.5f, 0.5f, 0.5f, 0.3f)); + setSpeed(0.2f); + } + + void RainParticleSystem::render(ParticleRenderer *pr, ModelRenderer *mr) { + pr->renderSystemLineAlpha(this); + } + + void RainParticleSystem::initParticle(Particle *p, int particleIndex) { + ParticleSystem::initParticle(p, particleIndex); + + float x = random.randRange(-radius, radius); + float y = random.randRange(-radius, radius); + + p->color = color; + p->energy = 10000; + p->pos = Vec3f(pos.x + x, pos.y, pos.z + y); + p->pos.x = truncateDecimal(p->pos.x, 6); + p->pos.y = truncateDecimal(p->pos.y, 6); + p->pos.z = truncateDecimal(p->pos.z, 6); + + p->lastPos = p->pos; + p->speed = Vec3f(random.randRange(-speed / 10, speed / 10), -speed, + random.randRange(-speed / 10, speed / 10)) + windSpeed; + p->speed.x = truncateDecimal(p->speed.x, 6); + p->speed.y = truncateDecimal(p->speed.y, 6); + p->speed.z = truncateDecimal(p->speed.z, 6); + } + + bool RainParticleSystem::deathTest(Particle *p) { + return p->pos.y < 0; + } + + void RainParticleSystem::setRadius(float radius) { + this->radius = radius; + } + + void RainParticleSystem::setWind(float windAngle, float windSpeed) { #ifdef USE_STREFLOP - float rotation = truncateDecimal(streflop::atan2(static_cast(direction.x), static_cast(direction.z)),6); + this->windSpeed.x = streflop::sinf(static_cast(degToRad(windAngle)))*windSpeed; + this->windSpeed.y = 0.0f; + this->windSpeed.z = streflop::cosf(static_cast(degToRad(windAngle)))*windSpeed; #else - float rotation = truncateDecimal(atan2(direction.x, direction.z),6); + this->windSpeed.x = sinf(degToRad(windAngle)) * windSpeed; + this->windSpeed.y = 0.0f; + this->windSpeed.z = cosf(degToRad(windAngle)) * windSpeed; +#endif + + this->windSpeed.x = truncateDecimal(this->windSpeed.x, 6); + this->windSpeed.y = truncateDecimal(this->windSpeed.y, 6); + this->windSpeed.z = truncateDecimal(this->windSpeed.z, 6); + } + + Checksum RainParticleSystem::getCRC() { + Checksum crcForParticleSystem = ParticleSystem::getCRC(); + + return crcForParticleSystem; + } + + string RainParticleSystem::toString() const { + string result = ParticleSystem::toString(); + + result += "\nRainParticleSystem "; + result += "\nwindSpeed = " + windSpeed.getString(); + result += "\nradius = " + floatToStr(radius); + + return result; + } + + // =========================================================================== + // SnowParticleSystem + // =========================================================================== + + SnowParticleSystem::SnowParticleSystem(int particleCount) : + ParticleSystem(particleCount) { + setWind(0.0f, 0.0f); + setRadius(30.0f); + + setEmissionRate(2.0f); + setParticleSize(0.2f); + setColor(Vec4f(0.8f, 0.8f, 0.8f, 0.8f)); + setSpeed(0.05f); + } + + void SnowParticleSystem::initParticle(Particle *p, int particleIndex) { + + ParticleSystem::initParticle(p, particleIndex); + + float x = random.randRange(-radius, radius); + float y = random.randRange(-radius, radius); + + p->color = color; + p->energy = 10000; + p->pos = Vec3f(pos.x + x, pos.y, pos.z + y); + p->pos.x = truncateDecimal(p->pos.x, 6); + p->pos.y = truncateDecimal(p->pos.y, 6); + p->pos.z = truncateDecimal(p->pos.z, 6); + + p->lastPos = p->pos; + p->speed = Vec3f(0.0f, -speed, 0.0f) + windSpeed; + p->speed.x += random.randRange(-0.005f, 0.005f); + p->speed.y += random.randRange(-0.005f, 0.005f); + + p->speed.x = truncateDecimal(p->speed.x, 6); + p->speed.y = truncateDecimal(p->speed.y, 6); + p->speed.z = truncateDecimal(p->speed.z, 6); + } + + bool SnowParticleSystem::deathTest(Particle *p) { + return p->pos.y < 0; + } + + void SnowParticleSystem::setRadius(float radius) { + this->radius = radius; + } + + void SnowParticleSystem::setWind(float windAngle, float windSpeed) { +#ifdef USE_STREFLOP + this->windSpeed.x = streflop::sinf(static_cast(degToRad(windAngle)))*windSpeed; + this->windSpeed.y = 0.0f; + this->windSpeed.z = streflop::cosf(static_cast(degToRad(windAngle)))*windSpeed; +#else + this->windSpeed.x = sinf(degToRad(windAngle)) * windSpeed; + this->windSpeed.y = 0.0f; + this->windSpeed.z = cosf(degToRad(windAngle)) * windSpeed; +#endif + + this->windSpeed.x = truncateDecimal(this->windSpeed.x, 6); + this->windSpeed.y = truncateDecimal(this->windSpeed.y, 6); + this->windSpeed.z = truncateDecimal(this->windSpeed.z, 6); + + } + + Checksum SnowParticleSystem::getCRC() { + Checksum crcForParticleSystem = ParticleSystem::getCRC(); + + return crcForParticleSystem; + } + + string SnowParticleSystem::toString() const { + string result = ParticleSystem::toString(); + + result += "\nSnowParticleSystem "; + result += "\nwindSpeed = " + windSpeed.getString(); + result += "\nradius = " + floatToStr(radius); + + return result; + } + + // =========================================================================== + // AttackParticleSystem + // =========================================================================== + + AttackParticleSystem::AttackParticleSystem(int particleCount) : + GameParticleSystem(particleCount) { + primitive = pQuad; + gravity = 0.0f; + sizeNoEnergy = 0.0; + } + + void AttackParticleSystem::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *attackParticleSystemNode = rootNode->addChild("AttackParticleSystem"); + + GameParticleSystem::saveGame(attackParticleSystemNode); + + // float sizeNoEnergy; + attackParticleSystemNode->addAttribute("sizeNoEnergy", floatToStr(sizeNoEnergy, 6), mapTagReplacements); + // float gravity; + attackParticleSystemNode->addAttribute("gravity", floatToStr(gravity, 6), mapTagReplacements); + + } + void AttackParticleSystem::loadGame(const XmlNode *rootNode) { + const XmlNode *attackParticleSystemNode = rootNode; + + GameParticleSystem::loadGame(attackParticleSystemNode); + + // float sizeNoEnergy; + sizeNoEnergy = attackParticleSystemNode->getAttribute("sizeNoEnergy")->getFloatValue(); + // float gravity; + gravity = attackParticleSystemNode->getAttribute("gravity")->getFloatValue(); + } + + Checksum AttackParticleSystem::getCRC() { + Checksum crcForParticleSystem = GameParticleSystem::getCRC(); + + return crcForParticleSystem; + } + + string AttackParticleSystem::toString() const { + string result = GameParticleSystem::toString(); + + result += "\nAttackParticleSystem "; + result += "\nsizeNoEnergy = " + floatToStr(sizeNoEnergy); + result += "\ngravity = " + floatToStr(gravity); + + return result; + } + + // =========================================================================== + // ProjectileParticleSystem + // =========================================================================== + + ProjectileParticleSystem::ProjectileParticleSystem(int particleCount) : + AttackParticleSystem(particleCount) { + setEmissionRate(20.0f); + setColor(Vec4f(1.0f, 0.3f, 0.0f, 0.5f)); + setMaxParticleEnergy(100); + setVarParticleEnergy(50); + setParticleSize(0.4f); + setSpeed(0.14f); + + trajectory = tLinear; + + trajectorySpeed = 1.0f; + trajectoryScale = 1.0f; + trajectoryFrequency = 1.0f; + modelCycle = 0.0f; + + nextParticleSystem = NULL; + arriveDestinationDistance = 0.0f; + //printf("#aXX trajectorySpeed = %f\n",trajectorySpeed); + } + + ProjectileParticleSystem::~ProjectileParticleSystem() { + if (nextParticleSystem != NULL) { + nextParticleSystem->prevParticleSystem = NULL; + } + } + + void ProjectileParticleSystem::link(SplashParticleSystem *particleSystem) { + nextParticleSystem = particleSystem; + nextParticleSystem->setVisible(false); + nextParticleSystem->setState(sPause); + nextParticleSystem->prevParticleSystem = this; + } + + void ProjectileParticleSystem::update() { + //printf("Projectile particle system updating...\n"); + if (state == sPlay) { + + lastPos = pos; + flatPos += zVector * truncateDecimal(trajectorySpeed, 6); + flatPos.x = truncateDecimal(flatPos.x, 6); + flatPos.y = truncateDecimal(flatPos.y, 6); + flatPos.z = truncateDecimal(flatPos.z, 6); + + Vec3f targetVector = endPos - startPos; + targetVector.x = truncateDecimal(targetVector.x, 6); + targetVector.y = truncateDecimal(targetVector.y, 6); + targetVector.z = truncateDecimal(targetVector.z, 6); + + Vec3f currentVector = flatPos - startPos; + currentVector.x = truncateDecimal(currentVector.x, 6); + currentVector.y = truncateDecimal(currentVector.y, 6); + currentVector.z = truncateDecimal(currentVector.z, 6); + + // ratio + float relative = clamp(currentVector.length() / targetVector.length(), 0.0f, 1.0f); + relative = truncateDecimal(relative, 6); + + float absolute = relative; + setTween(relative, absolute); + + // trajectory + switch (trajectory) { + case tLinear: { + pos = flatPos; + } + break; + + case tParabolic: { + float scaledT = truncateDecimal(2.0f * (relative - 0.5f), 6); + float paraboleY = truncateDecimal((1.0f - scaledT * scaledT) * trajectoryScale, 6); + + pos = flatPos; + pos.y += paraboleY; + pos.y = truncateDecimal(pos.y, 6); + } + break; + + case tSpiral: { + pos = flatPos; +#ifdef USE_STREFLOP + pos += xVector * streflop::cos(static_cast(relative * trajectoryFrequency * targetVector.length())) * trajectoryScale; + pos.x = truncateDecimal(pos.x, 6); + pos.y = truncateDecimal(pos.y, 6); + pos.z = truncateDecimal(pos.z, 6); + + pos += yVector * streflop::sin(static_cast(relative * trajectoryFrequency * targetVector.length())) * trajectoryScale; +#else + pos += xVector * cos(relative * trajectoryFrequency * targetVector.length()) * trajectoryScale; + pos.x = truncateDecimal(pos.x, 6); + pos.y = truncateDecimal(pos.y, 6); + pos.z = truncateDecimal(pos.z, 6); + + pos += yVector * sin(relative * trajectoryFrequency * targetVector.length()) * trajectoryScale; +#endif + pos.x = truncateDecimal(pos.x, 6); + pos.y = truncateDecimal(pos.y, 6); + pos.z = truncateDecimal(pos.z, 6); + } + break; + + default: + assert(false); + break; + } + + direction = (pos - lastPos); + direction.x = truncateDecimal(direction.x, 6); + direction.y = truncateDecimal(direction.y, 6); + direction.z = truncateDecimal(direction.z, 6); + + direction.normalize(); + direction.x = truncateDecimal(direction.x, 6); + direction.y = truncateDecimal(direction.y, 6); + direction.z = truncateDecimal(direction.z, 6); + + // trigger update of child particles + positionChildren(); + rotateChildren(); + + //arrive destination + arriveDestinationDistance = truncateDecimal(flatPos.dist(endPos), 6); + + if (this->particleOwner != NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "LINE: %d arriveDestinationDistance = %f", __LINE__, arriveDestinationDistance); + this->particleOwner->logParticleInfo(szBuf); + } + + if (arriveDestinationDistance < 0.5f) { + fade(); + model = NULL; + + if (particleObserver != NULL) { + particleObserver->update(this); + particleObserver = NULL; + } + + if (nextParticleSystem != NULL) { + nextParticleSystem->setVisible(getVisible()); + nextParticleSystem->setState(sPlay); + nextParticleSystem->setPos(endPos); + } + } + } + + ParticleSystem::update(); + } + + void ProjectileParticleSystem::rotateChildren() { + //### only on horizontal plane :( +#ifdef USE_STREFLOP + float rotation = truncateDecimal(streflop::atan2(static_cast(direction.x), static_cast(direction.z)), 6); +#else + float rotation = truncateDecimal(atan2(direction.x, direction.z), 6); #endif - rotation = truncateDecimal(radToDeg(rotation),6); - for(Children::iterator it = children.begin(); it != children.end(); ++it) - (*it)->setRotation(rotation); -} - -void ProjectileParticleSystem::initParticle(Particle *p, int particleIndex){ - - ParticleSystem::initParticle(p, particleIndex); - - float t= static_cast (particleIndex) / emissionRate; - t = truncateDecimal(t,6); - - p->pos= pos + (lastPos - pos) * t; - p->pos.x = truncateDecimal(p->pos.x,6); - p->pos.y = truncateDecimal(p->pos.y,6); - p->pos.z = truncateDecimal(p->pos.z,6); - - p->lastPos= lastPos; - p->speed= Vec3f(random.randRange(-0.1f, 0.1f), random.randRange(-0.1f, 0.1f), - random.randRange(-0.1f, 0.1f)) * speed; - p->speed.x = truncateDecimal(p->speed.x,6); - p->speed.y = truncateDecimal(p->speed.y,6); - p->speed.z = truncateDecimal(p->speed.z,6); - - p->accel= Vec3f(0.0f, -gravity, 0.0f); - p->accel.x = truncateDecimal(p->accel.x,6); - p->accel.y = truncateDecimal(p->accel.y,6); - p->accel.z = truncateDecimal(p->accel.z,6); - - updateParticle(p); -} - -void ProjectileParticleSystem::updateParticle(Particle *p){ - float energyRatio= clamp(static_cast (p->energy) / maxParticleEnergy, 0.f, 1.f); - energyRatio = truncateDecimal(energyRatio,6); - - p->lastPos += p->speed; - p->lastPos.x = truncateDecimal(p->lastPos.x,6); - p->lastPos.y = truncateDecimal(p->lastPos.y,6); - p->lastPos.z = truncateDecimal(p->lastPos.z,6); - - p->pos += p->speed; - p->pos.x = truncateDecimal(p->pos.x,6); - p->pos.y = truncateDecimal(p->pos.y,6); - p->pos.z = truncateDecimal(p->pos.z,6); - - p->speed += p->accel; - p->speed.x = truncateDecimal(p->speed.x,6); - p->speed.y = truncateDecimal(p->speed.y,6); - p->speed.z = truncateDecimal(p->speed.z,6); - - p->color= color * energyRatio + colorNoEnergy * (1.0f - energyRatio); - p->size = particleSize * energyRatio + sizeNoEnergy * (1.0f - energyRatio); - p->size = truncateDecimal(p->size,6); - p->energy--; -} - -void ProjectileParticleSystem::setPath(Vec3f startPos, Vec3f endPos) { - startPos.x = truncateDecimal(startPos.x,6); - startPos.y = truncateDecimal(startPos.y,6); - startPos.z = truncateDecimal(startPos.z,6); - - endPos.x = truncateDecimal(endPos.x,6); - endPos.y = truncateDecimal(endPos.y,6); - endPos.z = truncateDecimal(endPos.z,6); - - //compute axis - zVector= endPos - startPos; - zVector.x = truncateDecimal(zVector.x,6); - zVector.y = truncateDecimal(zVector.y,6); - zVector.z = truncateDecimal(zVector.z,6); - - zVector.normalize(); - zVector.x = truncateDecimal(zVector.x,6); - zVector.y = truncateDecimal(zVector.y,6); - zVector.z = truncateDecimal(zVector.z,6); - - yVector= Vec3f(0.0f, 1.0f, 0.0f); - xVector= zVector.cross(yVector); - xVector.x = truncateDecimal(xVector.x,6); - xVector.y = truncateDecimal(xVector.y,6); - xVector.z = truncateDecimal(xVector.z,6); - - //apply offset - startPos += xVector * offset.x; - startPos.x = truncateDecimal(startPos.x,6); - startPos.y = truncateDecimal(startPos.y,6); - startPos.z = truncateDecimal(startPos.z,6); - - startPos+= yVector * offset.y; - startPos.x = truncateDecimal(startPos.x,6); - startPos.y = truncateDecimal(startPos.y,6); - startPos.z = truncateDecimal(startPos.z,6); - - startPos+= zVector * offset.z; - startPos.x = truncateDecimal(startPos.x,6); - startPos.y = truncateDecimal(startPos.y,6); - startPos.z = truncateDecimal(startPos.z,6); - - pos= startPos; - lastPos= startPos; - flatPos= startPos; - - //recompute axis - zVector= endPos - startPos; - zVector.x = truncateDecimal(zVector.x,6); - zVector.y = truncateDecimal(zVector.y,6); - zVector.z = truncateDecimal(zVector.z,6); - - zVector.normalize(); - zVector.x = truncateDecimal(zVector.x,6); - zVector.y = truncateDecimal(zVector.y,6); - zVector.z = truncateDecimal(zVector.z,6); - - yVector= Vec3f(0.0f, 1.0f, 0.0f); - xVector= zVector.cross(yVector); - xVector.x = truncateDecimal(xVector.x,6); - xVector.y = truncateDecimal(xVector.y,6); - xVector.z = truncateDecimal(xVector.z,6); - - // set members - this->startPos= startPos; - this->endPos= endPos; - - // direction - direction = (endPos - lastPos); - direction.x = truncateDecimal(direction.x,6); - direction.y = truncateDecimal(direction.y,6); - direction.z = truncateDecimal(direction.z,6); - - direction.normalize(); - direction.x = truncateDecimal(direction.x,6); - direction.y = truncateDecimal(direction.y,6); - direction.z = truncateDecimal(direction.z,6); - - rotateChildren(); -} - -ProjectileParticleSystem::Trajectory ProjectileParticleSystem::strToTrajectory(const string &str){ - if(str == "linear"){ - return tLinear; - } - else if(str == "parabolic"){ - return tParabolic; - } - else if(str == "spiral"){ - return tSpiral; - } - else{ - throw megaglest_runtime_error("Unknown particle system trajectory: " + str); - } -} - -void ProjectileParticleSystem::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *projectileParticleSystemNode = rootNode->addChild("ProjectileParticleSystem"); - - AttackParticleSystem::saveGame(projectileParticleSystemNode); - -// SplashParticleSystem *nextParticleSystem; - if(nextParticleSystem != NULL) { - nextParticleSystem->saveGame(projectileParticleSystemNode); - } -// Vec3f lastPos; - projectileParticleSystemNode->addAttribute("lastPos",lastPos.getString(), mapTagReplacements); -// Vec3f startPos; - projectileParticleSystemNode->addAttribute("startPos",startPos.getString(), mapTagReplacements); -// Vec3f endPos; - projectileParticleSystemNode->addAttribute("endPos",endPos.getString(), mapTagReplacements); -// Vec3f flatPos; - projectileParticleSystemNode->addAttribute("flatPos",flatPos.getString(), mapTagReplacements); -// -// Vec3f xVector; - projectileParticleSystemNode->addAttribute("xVector",xVector.getString(), mapTagReplacements); -// Vec3f yVector; - projectileParticleSystemNode->addAttribute("yVector",yVector.getString(), mapTagReplacements); -// Vec3f zVector; - projectileParticleSystemNode->addAttribute("zVector",zVector.getString(), mapTagReplacements); -// Trajectory trajectory; - projectileParticleSystemNode->addAttribute("trajectory",intToStr(trajectory), mapTagReplacements); -// float trajectorySpeed; - projectileParticleSystemNode->addAttribute("trajectorySpeed",floatToStr(trajectorySpeed,6), mapTagReplacements); -// //parabolic -// float trajectoryScale; - projectileParticleSystemNode->addAttribute("trajectoryScale",floatToStr(trajectoryScale,6), mapTagReplacements); -// float trajectoryFrequency; - projectileParticleSystemNode->addAttribute("trajectoryFrequency",floatToStr(trajectoryFrequency,6), mapTagReplacements); -} - -void ProjectileParticleSystem::loadGame(const XmlNode *rootNode) { - const XmlNode *projectileParticleSystemNode = rootNode; - - AttackParticleSystem::loadGame(projectileParticleSystemNode); - - // SplashParticleSystem *nextParticleSystem; -// if(nextParticleSystem != NULL) { -// nextParticleSystem->saveGame(projectileParticleSystemNode); -// } - if(projectileParticleSystemNode->hasChild("SplashParticleSystem") == true) { - XmlNode *splashParticleSystemNode = projectileParticleSystemNode->getChild("SplashParticleSystem"); - nextParticleSystem = new SplashParticleSystem(); - nextParticleSystem->setParticleOwner(this->getParticleOwner()); - nextParticleSystem->loadGame(splashParticleSystemNode); - } - // Vec3f lastPos; - lastPos = Vec3f::strToVec3(projectileParticleSystemNode->getAttribute("lastPos")->getValue()); - // Vec3f startPos; - startPos = Vec3f::strToVec3(projectileParticleSystemNode->getAttribute("startPos")->getValue()); - // Vec3f endPos; - endPos = Vec3f::strToVec3(projectileParticleSystemNode->getAttribute("endPos")->getValue()); - // Vec3f flatPos; - flatPos = Vec3f::strToVec3(projectileParticleSystemNode->getAttribute("flatPos")->getValue()); - // - // Vec3f xVector; - xVector = Vec3f::strToVec3(projectileParticleSystemNode->getAttribute("xVector")->getValue()); - // Vec3f yVector; - yVector = Vec3f::strToVec3(projectileParticleSystemNode->getAttribute("yVector")->getValue()); - // Vec3f zVector; - zVector = Vec3f::strToVec3(projectileParticleSystemNode->getAttribute("zVector")->getValue()); - // Trajectory trajectory; - trajectory = static_cast(projectileParticleSystemNode->getAttribute("trajectory")->getIntValue()); - // float trajectorySpeed; - trajectorySpeed = projectileParticleSystemNode->getAttribute("trajectorySpeed")->getFloatValue(); - // //parabolic - // float trajectoryScale; - trajectoryScale = projectileParticleSystemNode->getAttribute("trajectoryScale")->getFloatValue(); - // float trajectoryFrequency; - trajectoryFrequency = projectileParticleSystemNode->getAttribute("trajectoryFrequency")->getFloatValue(); -} - -Checksum ProjectileParticleSystem::getCRC() { - Checksum crcForParticleSystem = AttackParticleSystem::getCRC(); - - return crcForParticleSystem; -} - -string ProjectileParticleSystem::toString() const { - string result = AttackParticleSystem::toString(); - - result += "\nProjectileParticleSystem "; - if(nextParticleSystem != NULL) { - //result += "\nnextParticleSystem = " + nextParticleSystem->toString() + "\n"; - result += "\nnextParticleSystem = NOT NULL\n"; - } - result += "\nlastPos = " + lastPos.getString(); - result += "\nstartPos = " + startPos.getString(); - result += "\nendPos = " + endPos.getString(); - result += "\nflatPos = " + flatPos.getString(); - - result += "\nxVector = " + xVector.getString(); - result += "\nyVector = " + yVector.getString(); - result += "\nzVector = " + zVector.getString(); - - result += "\ntrajectory = " + intToStr(trajectory); - result += "\ntrajectorySpeed = " + floatToStr(trajectorySpeed); - result += "\ntrajectoryScale = " + floatToStr(trajectoryScale); - result += "\ntrajectoryFrequency = " + floatToStr(trajectoryFrequency); - - result += "\narriveDestinationDistance = " + floatToStr(arriveDestinationDistance); - - return result; -} - -// =========================================================================== -// SplashParticleSystem -// =========================================================================== - -SplashParticleSystem::SplashParticleSystem(int particleCount) : - AttackParticleSystem(particleCount){ - setColor(Vec4f(1.0f, 0.3f, 0.0f, 0.8f)); - setMaxParticleEnergy(100); - setVarParticleEnergy(50); - setParticleSize(1.0f); - setSpeed(0.003f); - - prevParticleSystem= NULL; - - emissionRateFade= 1.0f; - verticalSpreadA= 1.0f; - verticalSpreadB= 0.0f; - horizontalSpreadA= 1.0f; - horizontalSpreadB= 0.0f; - startEmissionRate= 0.0f; -} - -SplashParticleSystem::~SplashParticleSystem(){ - if(prevParticleSystem != NULL){ - prevParticleSystem->nextParticleSystem= NULL; - } -} - -void SplashParticleSystem::initParticleSystem() { - startEmissionRate = emissionRate; -} - -void SplashParticleSystem::update() { - ParticleSystem::update(); - if(state != sPause) { - emissionRate -= emissionRateFade; - emissionRate = truncateDecimal(emissionRate,6); - - float t = 1.0f - ((emissionRate + startEmissionRate) / (startEmissionRate * 2.0f)); - t = truncateDecimal(t,6); - - t= clamp(t, 0.0f, 1.0f); - setTween(t,t); - - if(this->particleOwner != NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"LINE: %d emissionRate = %f",__LINE__,emissionRate); - this->particleOwner->logParticleInfo(szBuf); + rotation = truncateDecimal(radToDeg(rotation), 6); + for (Children::iterator it = children.begin(); it != children.end(); ++it) + (*it)->setRotation(rotation); } - if(emissionRate < 0.0f) {//otherwise this system lives forever! - fade(); + void ProjectileParticleSystem::initParticle(Particle *p, int particleIndex) { + + ParticleSystem::initParticle(p, particleIndex); + + float t = static_cast (particleIndex) / emissionRate; + t = truncateDecimal(t, 6); + + p->pos = pos + (lastPos - pos) * t; + p->pos.x = truncateDecimal(p->pos.x, 6); + p->pos.y = truncateDecimal(p->pos.y, 6); + p->pos.z = truncateDecimal(p->pos.z, 6); + + p->lastPos = lastPos; + p->speed = Vec3f(random.randRange(-0.1f, 0.1f), random.randRange(-0.1f, 0.1f), + random.randRange(-0.1f, 0.1f)) * speed; + p->speed.x = truncateDecimal(p->speed.x, 6); + p->speed.y = truncateDecimal(p->speed.y, 6); + p->speed.z = truncateDecimal(p->speed.z, 6); + + p->accel = Vec3f(0.0f, -gravity, 0.0f); + p->accel.x = truncateDecimal(p->accel.x, 6); + p->accel.y = truncateDecimal(p->accel.y, 6); + p->accel.z = truncateDecimal(p->accel.z, 6); + + updateParticle(p); } - } -} -void SplashParticleSystem::initParticle(Particle *p, int particleIndex){ - p->pos= pos; - p->lastPos= p->pos; - p->energy= maxParticleEnergy; - p->size= particleSize; - p->color= color; - p->speedUpRelative= speedUpRelative; + void ProjectileParticleSystem::updateParticle(Particle *p) { + float energyRatio = clamp(static_cast (p->energy) / maxParticleEnergy, 0.f, 1.f); + energyRatio = truncateDecimal(energyRatio, 6); - p->speed= Vec3f(horizontalSpreadA * random.randRange(-1.0f, 1.0f) + horizontalSpreadB, verticalSpreadA - * random.randRange(-1.0f, 1.0f) + verticalSpreadB, horizontalSpreadA * random.randRange(-1.0f, 1.0f) - + horizontalSpreadB); - p->speed.x = truncateDecimal(p->speed.x,6); - p->speed.y = truncateDecimal(p->speed.y,6); - p->speed.z = truncateDecimal(p->speed.z,6); + p->lastPos += p->speed; + p->lastPos.x = truncateDecimal(p->lastPos.x, 6); + p->lastPos.y = truncateDecimal(p->lastPos.y, 6); + p->lastPos.z = truncateDecimal(p->lastPos.z, 6); - p->speed.normalize(); - p->speed.x = truncateDecimal(p->speed.x,6); - p->speed.y = truncateDecimal(p->speed.y,6); - p->speed.z = truncateDecimal(p->speed.z,6); + p->pos += p->speed; + p->pos.x = truncateDecimal(p->pos.x, 6); + p->pos.y = truncateDecimal(p->pos.y, 6); + p->pos.z = truncateDecimal(p->pos.z, 6); - p->speed= p->speed * speed; - p->speed.x = truncateDecimal(p->speed.x,6); - p->speed.y = truncateDecimal(p->speed.y,6); - p->speed.z = truncateDecimal(p->speed.z,6); + p->speed += p->accel; + p->speed.x = truncateDecimal(p->speed.x, 6); + p->speed.y = truncateDecimal(p->speed.y, 6); + p->speed.z = truncateDecimal(p->speed.z, 6); - p->accel= Vec3f(0.0f, -gravity, 0.0f); - p->accel.x = truncateDecimal(p->accel.x,6); - p->accel.y = truncateDecimal(p->accel.y,6); - p->accel.z = truncateDecimal(p->accel.z,6); - - p->speedUpConstant= Vec3f(speedUpConstant)*p->speed; -} - -void SplashParticleSystem::updateParticle(Particle *p){ - float energyRatio= clamp(static_cast (p->energy) / maxParticleEnergy, 0.f, 1.f); - - p->lastPos= p->pos; - p->pos= p->pos + p->speed; - p->pos.x = truncateDecimal(p->pos.x,6); - p->pos.y = truncateDecimal(p->pos.y,6); - p->pos.z = truncateDecimal(p->pos.z,6); - - p->speed += p->speedUpConstant; - p->speed=p->speed*(1+p->speedUpRelative); - p->speed= p->speed + p->accel; - p->speed.x = truncateDecimal(p->speed.x,6); - p->speed.y = truncateDecimal(p->speed.y,6); - p->speed.z = truncateDecimal(p->speed.z,6); - - p->energy--; - p->color= color * energyRatio + colorNoEnergy * (1.0f - energyRatio); - p->size= particleSize * energyRatio + sizeNoEnergy * (1.0f - energyRatio); - p->size = truncateDecimal(p->size,6); -} - -void SplashParticleSystem::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *splashParticleSystemNode = rootNode->addChild("SplashParticleSystem"); - - AttackParticleSystem::saveGame(splashParticleSystemNode); - -// ProjectileParticleSystem *prevParticleSystem; - if(prevParticleSystem != NULL) { - prevParticleSystem->saveGame(splashParticleSystemNode); - } - -// float emissionRateFade; - splashParticleSystemNode->addAttribute("emissionRateFade",floatToStr(emissionRateFade,6), mapTagReplacements); -// float verticalSpreadA; - splashParticleSystemNode->addAttribute("verticalSpreadA",floatToStr(verticalSpreadA,6), mapTagReplacements); -// float verticalSpreadB; - splashParticleSystemNode->addAttribute("verticalSpreadB",floatToStr(verticalSpreadB,6), mapTagReplacements); -// float horizontalSpreadA; - splashParticleSystemNode->addAttribute("horizontalSpreadA",floatToStr(horizontalSpreadA,6), mapTagReplacements); -// float horizontalSpreadB; - splashParticleSystemNode->addAttribute("horizontalSpreadB",floatToStr(horizontalSpreadB,6), mapTagReplacements); -// -// float startEmissionRate; - splashParticleSystemNode->addAttribute("startEmissionRate",floatToStr(startEmissionRate,6), mapTagReplacements); -} - -void SplashParticleSystem::loadGame(const XmlNode *rootNode) { - const XmlNode *splashParticleSystemNode = rootNode; - - AttackParticleSystem::loadGame(splashParticleSystemNode); - - // ProjectileParticleSystem *prevParticleSystem; -// if(nextParticleSystem != NULL) { -// nextParticleSystem->saveGame(projectileParticleSystemNode); -// } - if(splashParticleSystemNode->hasChild("ProjectileParticleSystem") == true) { - XmlNode *projectileParticleSystemNode = splashParticleSystemNode->getChild("ProjectileParticleSystem"); - prevParticleSystem = new ProjectileParticleSystem(); - prevParticleSystem->setParticleOwner(this->getParticleOwner()); - prevParticleSystem->loadGame(projectileParticleSystemNode); - } - -// float emissionRateFade; - emissionRateFade = splashParticleSystemNode->getAttribute("emissionRateFade")->getFloatValue(); -// float verticalSpreadA; - verticalSpreadA = splashParticleSystemNode->getAttribute("verticalSpreadA")->getFloatValue(); -// float verticalSpreadB; - verticalSpreadB = splashParticleSystemNode->getAttribute("verticalSpreadB")->getFloatValue(); -// float horizontalSpreadA; - horizontalSpreadA = splashParticleSystemNode->getAttribute("horizontalSpreadA")->getFloatValue(); -// float horizontalSpreadB; - horizontalSpreadB = splashParticleSystemNode->getAttribute("horizontalSpreadB")->getFloatValue(); -// float startEmissionRate; - startEmissionRate = splashParticleSystemNode->getAttribute("startEmissionRate")->getFloatValue(); -} - -Checksum SplashParticleSystem::getCRC() { - Checksum crcForParticleSystem = AttackParticleSystem::getCRC(); - - return crcForParticleSystem; -} - -string SplashParticleSystem::toString() const { - string result = AttackParticleSystem::toString(); - - result += "\nSplashParticleSystem "; - if(prevParticleSystem != NULL) { - //result += "\nprevParticleSystem = " + prevParticleSystem->toString() + "\n"; - result += "\nprevParticleSystem = NOT NULL\n"; - } - - result += "\nemissionRateFade = " + floatToStr(emissionRateFade); - result += "\nverticalSpreadA = " + floatToStr(verticalSpreadA); - result += "\nverticalSpreadB = " + floatToStr(verticalSpreadB); - result += "\nhorizontalSpreadA = " + floatToStr(horizontalSpreadA); - result += "\nhorizontalSpreadB = " + floatToStr(horizontalSpreadB); - result += "\nstartEmissionRate = " + floatToStr(startEmissionRate); - - return result; -} - -// =========================================================================== -// ParticleManager -// =========================================================================== - -ParticleManager::ParticleManager() { -} - -ParticleManager::~ParticleManager() { - end(); -} - -void ParticleManager::render(ParticleRenderer *pr, ModelRenderer *mr) const{ - for(unsigned int i= 0; i < particleSystems.size(); i++){ - ParticleSystem *ps= particleSystems[i]; - if(ps != NULL && ps->getVisible()){ - ps->render(pr, mr); + p->color = color * energyRatio + colorNoEnergy * (1.0f - energyRatio); + p->size = particleSize * energyRatio + sizeNoEnergy * (1.0f - energyRatio); + p->size = truncateDecimal(p->size, 6); + p->energy--; } - } -} -bool ParticleManager::hasActiveParticleSystem(ParticleSystem::ParticleSystemType type) const{ - bool result= false; + void ProjectileParticleSystem::setPath(Vec3f startPos, Vec3f endPos) { + startPos.x = truncateDecimal(startPos.x, 6); + startPos.y = truncateDecimal(startPos.y, 6); + startPos.z = truncateDecimal(startPos.z, 6); - //size_t particleSystemCount= particleSystems.size(); - //int currentParticleCount= 0; + endPos.x = truncateDecimal(endPos.x, 6); + endPos.y = truncateDecimal(endPos.y, 6); + endPos.z = truncateDecimal(endPos.z, 6); - //vector cleanupParticleSystemsList; - for(unsigned int i= 0; i < particleSystems.size(); i++){ - ParticleSystem *ps= particleSystems[i]; - if(ps != NULL){ - //currentParticleCount+= ps->getAliveParticleCount(); + //compute axis + zVector = endPos - startPos; + zVector.x = truncateDecimal(zVector.x, 6); + zVector.y = truncateDecimal(zVector.y, 6); + zVector.z = truncateDecimal(zVector.z, 6); - bool showParticle= true; - if(dynamic_cast (ps) != NULL || - dynamic_cast (ps) != NULL) { - showParticle= ps->getVisible() || (ps->getState() == ParticleSystem::sFade); + zVector.normalize(); + zVector.x = truncateDecimal(zVector.x, 6); + zVector.y = truncateDecimal(zVector.y, 6); + zVector.z = truncateDecimal(zVector.z, 6); + + yVector = Vec3f(0.0f, 1.0f, 0.0f); + xVector = zVector.cross(yVector); + xVector.x = truncateDecimal(xVector.x, 6); + xVector.y = truncateDecimal(xVector.y, 6); + xVector.z = truncateDecimal(xVector.z, 6); + + //apply offset + startPos += xVector * offset.x; + startPos.x = truncateDecimal(startPos.x, 6); + startPos.y = truncateDecimal(startPos.y, 6); + startPos.z = truncateDecimal(startPos.z, 6); + + startPos += yVector * offset.y; + startPos.x = truncateDecimal(startPos.x, 6); + startPos.y = truncateDecimal(startPos.y, 6); + startPos.z = truncateDecimal(startPos.z, 6); + + startPos += zVector * offset.z; + startPos.x = truncateDecimal(startPos.x, 6); + startPos.y = truncateDecimal(startPos.y, 6); + startPos.z = truncateDecimal(startPos.z, 6); + + pos = startPos; + lastPos = startPos; + flatPos = startPos; + + //recompute axis + zVector = endPos - startPos; + zVector.x = truncateDecimal(zVector.x, 6); + zVector.y = truncateDecimal(zVector.y, 6); + zVector.z = truncateDecimal(zVector.z, 6); + + zVector.normalize(); + zVector.x = truncateDecimal(zVector.x, 6); + zVector.y = truncateDecimal(zVector.y, 6); + zVector.z = truncateDecimal(zVector.z, 6); + + yVector = Vec3f(0.0f, 1.0f, 0.0f); + xVector = zVector.cross(yVector); + xVector.x = truncateDecimal(xVector.x, 6); + xVector.y = truncateDecimal(xVector.y, 6); + xVector.z = truncateDecimal(xVector.z, 6); + + // set members + this->startPos = startPos; + this->endPos = endPos; + + // direction + direction = (endPos - lastPos); + direction.x = truncateDecimal(direction.x, 6); + direction.y = truncateDecimal(direction.y, 6); + direction.z = truncateDecimal(direction.z, 6); + + direction.normalize(); + direction.x = truncateDecimal(direction.x, 6); + direction.y = truncateDecimal(direction.y, 6); + direction.z = truncateDecimal(direction.z, 6); + + rotateChildren(); + } + + ProjectileParticleSystem::Trajectory ProjectileParticleSystem::strToTrajectory(const string &str) { + if (str == "linear") { + return tLinear; + } else if (str == "parabolic") { + return tParabolic; + } else if (str == "spiral") { + return tSpiral; + } else { + throw megaglest_runtime_error("Unknown particle system trajectory: " + str); } - if(showParticle == true){ - //printf("Looking for [%d] current id [%d] i = %d\n",type,ps->getParticleSystemType(),i); + } - if(type == ParticleSystem::pst_All || type == ps->getParticleSystemType()){ - //printf("FOUND particle system type match for [%d] current id [%d] i = %d\n",type,ps->getParticleSystemType(),i); - result= true; + void ProjectileParticleSystem::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *projectileParticleSystemNode = rootNode->addChild("ProjectileParticleSystem"); + + AttackParticleSystem::saveGame(projectileParticleSystemNode); + + // SplashParticleSystem *nextParticleSystem; + if (nextParticleSystem != NULL) { + nextParticleSystem->saveGame(projectileParticleSystemNode); + } + // Vec3f lastPos; + projectileParticleSystemNode->addAttribute("lastPos", lastPos.getString(), mapTagReplacements); + // Vec3f startPos; + projectileParticleSystemNode->addAttribute("startPos", startPos.getString(), mapTagReplacements); + // Vec3f endPos; + projectileParticleSystemNode->addAttribute("endPos", endPos.getString(), mapTagReplacements); + // Vec3f flatPos; + projectileParticleSystemNode->addAttribute("flatPos", flatPos.getString(), mapTagReplacements); + // + // Vec3f xVector; + projectileParticleSystemNode->addAttribute("xVector", xVector.getString(), mapTagReplacements); + // Vec3f yVector; + projectileParticleSystemNode->addAttribute("yVector", yVector.getString(), mapTagReplacements); + // Vec3f zVector; + projectileParticleSystemNode->addAttribute("zVector", zVector.getString(), mapTagReplacements); + // Trajectory trajectory; + projectileParticleSystemNode->addAttribute("trajectory", intToStr(trajectory), mapTagReplacements); + // float trajectorySpeed; + projectileParticleSystemNode->addAttribute("trajectorySpeed", floatToStr(trajectorySpeed, 6), mapTagReplacements); + // //parabolic + // float trajectoryScale; + projectileParticleSystemNode->addAttribute("trajectoryScale", floatToStr(trajectoryScale, 6), mapTagReplacements); + // float trajectoryFrequency; + projectileParticleSystemNode->addAttribute("trajectoryFrequency", floatToStr(trajectoryFrequency, 6), mapTagReplacements); + } + + void ProjectileParticleSystem::loadGame(const XmlNode *rootNode) { + const XmlNode *projectileParticleSystemNode = rootNode; + + AttackParticleSystem::loadGame(projectileParticleSystemNode); + + // SplashParticleSystem *nextParticleSystem; + // if(nextParticleSystem != NULL) { + // nextParticleSystem->saveGame(projectileParticleSystemNode); + // } + if (projectileParticleSystemNode->hasChild("SplashParticleSystem") == true) { + XmlNode *splashParticleSystemNode = projectileParticleSystemNode->getChild("SplashParticleSystem"); + nextParticleSystem = new SplashParticleSystem(); + nextParticleSystem->setParticleOwner(this->getParticleOwner()); + nextParticleSystem->loadGame(splashParticleSystemNode); + } + // Vec3f lastPos; + lastPos = Vec3f::strToVec3(projectileParticleSystemNode->getAttribute("lastPos")->getValue()); + // Vec3f startPos; + startPos = Vec3f::strToVec3(projectileParticleSystemNode->getAttribute("startPos")->getValue()); + // Vec3f endPos; + endPos = Vec3f::strToVec3(projectileParticleSystemNode->getAttribute("endPos")->getValue()); + // Vec3f flatPos; + flatPos = Vec3f::strToVec3(projectileParticleSystemNode->getAttribute("flatPos")->getValue()); + // + // Vec3f xVector; + xVector = Vec3f::strToVec3(projectileParticleSystemNode->getAttribute("xVector")->getValue()); + // Vec3f yVector; + yVector = Vec3f::strToVec3(projectileParticleSystemNode->getAttribute("yVector")->getValue()); + // Vec3f zVector; + zVector = Vec3f::strToVec3(projectileParticleSystemNode->getAttribute("zVector")->getValue()); + // Trajectory trajectory; + trajectory = static_cast(projectileParticleSystemNode->getAttribute("trajectory")->getIntValue()); + // float trajectorySpeed; + trajectorySpeed = projectileParticleSystemNode->getAttribute("trajectorySpeed")->getFloatValue(); + // //parabolic + // float trajectoryScale; + trajectoryScale = projectileParticleSystemNode->getAttribute("trajectoryScale")->getFloatValue(); + // float trajectoryFrequency; + trajectoryFrequency = projectileParticleSystemNode->getAttribute("trajectoryFrequency")->getFloatValue(); + } + + Checksum ProjectileParticleSystem::getCRC() { + Checksum crcForParticleSystem = AttackParticleSystem::getCRC(); + + return crcForParticleSystem; + } + + string ProjectileParticleSystem::toString() const { + string result = AttackParticleSystem::toString(); + + result += "\nProjectileParticleSystem "; + if (nextParticleSystem != NULL) { + //result += "\nnextParticleSystem = " + nextParticleSystem->toString() + "\n"; + result += "\nnextParticleSystem = NOT NULL\n"; + } + result += "\nlastPos = " + lastPos.getString(); + result += "\nstartPos = " + startPos.getString(); + result += "\nendPos = " + endPos.getString(); + result += "\nflatPos = " + flatPos.getString(); + + result += "\nxVector = " + xVector.getString(); + result += "\nyVector = " + yVector.getString(); + result += "\nzVector = " + zVector.getString(); + + result += "\ntrajectory = " + intToStr(trajectory); + result += "\ntrajectorySpeed = " + floatToStr(trajectorySpeed); + result += "\ntrajectoryScale = " + floatToStr(trajectoryScale); + result += "\ntrajectoryFrequency = " + floatToStr(trajectoryFrequency); + + result += "\narriveDestinationDistance = " + floatToStr(arriveDestinationDistance); + + return result; + } + + // =========================================================================== + // SplashParticleSystem + // =========================================================================== + + SplashParticleSystem::SplashParticleSystem(int particleCount) : + AttackParticleSystem(particleCount) { + setColor(Vec4f(1.0f, 0.3f, 0.0f, 0.8f)); + setMaxParticleEnergy(100); + setVarParticleEnergy(50); + setParticleSize(1.0f); + setSpeed(0.003f); + + prevParticleSystem = NULL; + + emissionRateFade = 1.0f; + verticalSpreadA = 1.0f; + verticalSpreadB = 0.0f; + horizontalSpreadA = 1.0f; + horizontalSpreadB = 0.0f; + startEmissionRate = 0.0f; + } + + SplashParticleSystem::~SplashParticleSystem() { + if (prevParticleSystem != NULL) { + prevParticleSystem->nextParticleSystem = NULL; + } + } + + void SplashParticleSystem::initParticleSystem() { + startEmissionRate = emissionRate; + } + + void SplashParticleSystem::update() { + ParticleSystem::update(); + if (state != sPause) { + emissionRate -= emissionRateFade; + emissionRate = truncateDecimal(emissionRate, 6); + + float t = 1.0f - ((emissionRate + startEmissionRate) / (startEmissionRate * 2.0f)); + t = truncateDecimal(t, 6); + + t = clamp(t, 0.0f, 1.0f); + setTween(t, t); + + if (this->particleOwner != NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "LINE: %d emissionRate = %f", __LINE__, emissionRate); + this->particleOwner->logParticleInfo(szBuf); + } + + if (emissionRate < 0.0f) {//otherwise this system lives forever! + fade(); + } + } + } + + void SplashParticleSystem::initParticle(Particle *p, int particleIndex) { + p->pos = pos; + p->lastPos = p->pos; + p->energy = maxParticleEnergy; + p->size = particleSize; + p->color = color; + p->speedUpRelative = speedUpRelative; + + p->speed = Vec3f(horizontalSpreadA * random.randRange(-1.0f, 1.0f) + horizontalSpreadB, verticalSpreadA + * random.randRange(-1.0f, 1.0f) + verticalSpreadB, horizontalSpreadA * random.randRange(-1.0f, 1.0f) + + horizontalSpreadB); + p->speed.x = truncateDecimal(p->speed.x, 6); + p->speed.y = truncateDecimal(p->speed.y, 6); + p->speed.z = truncateDecimal(p->speed.z, 6); + + p->speed.normalize(); + p->speed.x = truncateDecimal(p->speed.x, 6); + p->speed.y = truncateDecimal(p->speed.y, 6); + p->speed.z = truncateDecimal(p->speed.z, 6); + + p->speed = p->speed * speed; + p->speed.x = truncateDecimal(p->speed.x, 6); + p->speed.y = truncateDecimal(p->speed.y, 6); + p->speed.z = truncateDecimal(p->speed.z, 6); + + p->accel = Vec3f(0.0f, -gravity, 0.0f); + p->accel.x = truncateDecimal(p->accel.x, 6); + p->accel.y = truncateDecimal(p->accel.y, 6); + p->accel.z = truncateDecimal(p->accel.z, 6); + + p->speedUpConstant = Vec3f(speedUpConstant)*p->speed; + } + + void SplashParticleSystem::updateParticle(Particle *p) { + float energyRatio = clamp(static_cast (p->energy) / maxParticleEnergy, 0.f, 1.f); + + p->lastPos = p->pos; + p->pos = p->pos + p->speed; + p->pos.x = truncateDecimal(p->pos.x, 6); + p->pos.y = truncateDecimal(p->pos.y, 6); + p->pos.z = truncateDecimal(p->pos.z, 6); + + p->speed += p->speedUpConstant; + p->speed = p->speed*(1 + p->speedUpRelative); + p->speed = p->speed + p->accel; + p->speed.x = truncateDecimal(p->speed.x, 6); + p->speed.y = truncateDecimal(p->speed.y, 6); + p->speed.z = truncateDecimal(p->speed.z, 6); + + p->energy--; + p->color = color * energyRatio + colorNoEnergy * (1.0f - energyRatio); + p->size = particleSize * energyRatio + sizeNoEnergy * (1.0f - energyRatio); + p->size = truncateDecimal(p->size, 6); + } + + void SplashParticleSystem::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; + XmlNode *splashParticleSystemNode = rootNode->addChild("SplashParticleSystem"); + + AttackParticleSystem::saveGame(splashParticleSystemNode); + + // ProjectileParticleSystem *prevParticleSystem; + if (prevParticleSystem != NULL) { + prevParticleSystem->saveGame(splashParticleSystemNode); + } + + // float emissionRateFade; + splashParticleSystemNode->addAttribute("emissionRateFade", floatToStr(emissionRateFade, 6), mapTagReplacements); + // float verticalSpreadA; + splashParticleSystemNode->addAttribute("verticalSpreadA", floatToStr(verticalSpreadA, 6), mapTagReplacements); + // float verticalSpreadB; + splashParticleSystemNode->addAttribute("verticalSpreadB", floatToStr(verticalSpreadB, 6), mapTagReplacements); + // float horizontalSpreadA; + splashParticleSystemNode->addAttribute("horizontalSpreadA", floatToStr(horizontalSpreadA, 6), mapTagReplacements); + // float horizontalSpreadB; + splashParticleSystemNode->addAttribute("horizontalSpreadB", floatToStr(horizontalSpreadB, 6), mapTagReplacements); + // + // float startEmissionRate; + splashParticleSystemNode->addAttribute("startEmissionRate", floatToStr(startEmissionRate, 6), mapTagReplacements); + } + + void SplashParticleSystem::loadGame(const XmlNode *rootNode) { + const XmlNode *splashParticleSystemNode = rootNode; + + AttackParticleSystem::loadGame(splashParticleSystemNode); + + // ProjectileParticleSystem *prevParticleSystem; + // if(nextParticleSystem != NULL) { + // nextParticleSystem->saveGame(projectileParticleSystemNode); + // } + if (splashParticleSystemNode->hasChild("ProjectileParticleSystem") == true) { + XmlNode *projectileParticleSystemNode = splashParticleSystemNode->getChild("ProjectileParticleSystem"); + prevParticleSystem = new ProjectileParticleSystem(); + prevParticleSystem->setParticleOwner(this->getParticleOwner()); + prevParticleSystem->loadGame(projectileParticleSystemNode); + } + + // float emissionRateFade; + emissionRateFade = splashParticleSystemNode->getAttribute("emissionRateFade")->getFloatValue(); + // float verticalSpreadA; + verticalSpreadA = splashParticleSystemNode->getAttribute("verticalSpreadA")->getFloatValue(); + // float verticalSpreadB; + verticalSpreadB = splashParticleSystemNode->getAttribute("verticalSpreadB")->getFloatValue(); + // float horizontalSpreadA; + horizontalSpreadA = splashParticleSystemNode->getAttribute("horizontalSpreadA")->getFloatValue(); + // float horizontalSpreadB; + horizontalSpreadB = splashParticleSystemNode->getAttribute("horizontalSpreadB")->getFloatValue(); + // float startEmissionRate; + startEmissionRate = splashParticleSystemNode->getAttribute("startEmissionRate")->getFloatValue(); + } + + Checksum SplashParticleSystem::getCRC() { + Checksum crcForParticleSystem = AttackParticleSystem::getCRC(); + + return crcForParticleSystem; + } + + string SplashParticleSystem::toString() const { + string result = AttackParticleSystem::toString(); + + result += "\nSplashParticleSystem "; + if (prevParticleSystem != NULL) { + //result += "\nprevParticleSystem = " + prevParticleSystem->toString() + "\n"; + result += "\nprevParticleSystem = NOT NULL\n"; + } + + result += "\nemissionRateFade = " + floatToStr(emissionRateFade); + result += "\nverticalSpreadA = " + floatToStr(verticalSpreadA); + result += "\nverticalSpreadB = " + floatToStr(verticalSpreadB); + result += "\nhorizontalSpreadA = " + floatToStr(horizontalSpreadA); + result += "\nhorizontalSpreadB = " + floatToStr(horizontalSpreadB); + result += "\nstartEmissionRate = " + floatToStr(startEmissionRate); + + return result; + } + + // =========================================================================== + // ParticleManager + // =========================================================================== + + ParticleManager::ParticleManager() { + } + + ParticleManager::~ParticleManager() { + end(); + } + + void ParticleManager::render(ParticleRenderer *pr, ModelRenderer *mr) const { + for (unsigned int i = 0; i < particleSystems.size(); i++) { + ParticleSystem *ps = particleSystems[i]; + if (ps != NULL && ps->getVisible()) { + ps->render(pr, mr); + } + } + } + + bool ParticleManager::hasActiveParticleSystem(ParticleSystem::ParticleSystemType type) const { + bool result = false; + + //size_t particleSystemCount= particleSystems.size(); + //int currentParticleCount= 0; + + //vector cleanupParticleSystemsList; + for (unsigned int i = 0; i < particleSystems.size(); i++) { + ParticleSystem *ps = particleSystems[i]; + if (ps != NULL) { + //currentParticleCount+= ps->getAliveParticleCount(); + + bool showParticle = true; + if (dynamic_cast (ps) != NULL || + dynamic_cast (ps) != NULL) { + showParticle = ps->getVisible() || (ps->getState() == ParticleSystem::sFade); + } + if (showParticle == true) { + //printf("Looking for [%d] current id [%d] i = %d\n",type,ps->getParticleSystemType(),i); + + if (type == ParticleSystem::pst_All || type == ps->getParticleSystemType()) { + //printf("FOUND particle system type match for [%d] current id [%d] i = %d\n",type,ps->getParticleSystemType(),i); + result = true; + break; + } + } + } + } + + return result; + } + + void ParticleManager::update(int renderFps) { + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + + size_t particleSystemCount = particleSystems.size(); + int currentParticleCount = 0; + + vector cleanupParticleSystemsList; + for (unsigned int i = 0; i < particleSystems.size(); i++) { + ParticleSystem *ps = particleSystems[i]; + if (ps != NULL) { + currentParticleCount += ps->getAliveParticleCount(); + + bool showParticle = true; + if (dynamic_cast (ps) != NULL || + dynamic_cast (ps) != NULL) { + showParticle = ps->getVisible() || (ps->getState() == ParticleSystem::sFade); + } + if (showParticle == true) { + ps->update(); + if (ps->isEmpty() && ps->getState() == ParticleSystem::sFade) { + cleanupParticleSystemsList.push_back(ps); + } + } + } + } + //particleSystems.remove(NULL); + cleanupParticleSystems(cleanupParticleSystemsList); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) + SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s] Line: %d took msecs: %lld, particleSystemCount = %d, currentParticleCount = %d\n", __FILE__, __FUNCTION__, __LINE__, chrono.getMillis(), particleSystemCount, currentParticleCount); + } + + bool ParticleManager::validateParticleSystemStillExists(ParticleSystem * particleSystem) const { + int index = findParticleSystems(particleSystem, this->particleSystems); + return (index >= 0); + } + + void ParticleManager::removeParticleSystemsForParticleOwner(ParticleOwner *particleOwner) { + if (particleOwner != NULL && particleSystems.empty() == false) { + vector cleanupParticleSystemsList; + + for (unsigned int index = 0; index < particleSystems.size(); ++index) { + ParticleSystem *ps = particleSystems[index]; + if (ps != NULL && ps->getParticleOwner() == particleOwner) { + cleanupParticleSystemsList.push_back(ps); + } + } + if (cleanupParticleSystemsList.empty() == false) { + cleanupParticleSystems(cleanupParticleSystemsList); + } + } + } + + int ParticleManager::findParticleSystems(ParticleSystem *psFind, const vector &particleSystems) const { + int result = -1; + for (unsigned int i = 0; i < particleSystems.size(); i++) { + ParticleSystem *ps = particleSystems[i]; + if (ps != NULL && psFind != NULL && psFind == ps) { + result = i; break; } } + return result; } - } - return result; -} + void ParticleManager::cleanupParticleSystems(ParticleSystem *ps) { -void ParticleManager::update(int renderFps){ - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + int index = findParticleSystems(ps, this->particleSystems); + if (ps != NULL && index >= 0) { + // printf("-- Delete cleanupParticleSystems [%p]\n",ps); + // static map deleteList; + // if(deleteList.find(ps) != deleteList.end()) { + // assert(deleteList.find(ps) == deleteList.end()); + // } + // deleteList[ps]++; - size_t particleSystemCount= particleSystems.size(); - int currentParticleCount= 0; + // This code causes segfault on game end, no need to fade, just delete + //if(ps->getState() != ParticleSystem::sFade) { + // ps->fade(); + //} - vector cleanupParticleSystemsList; - for(unsigned int i= 0; i < particleSystems.size(); i++){ - ParticleSystem *ps= particleSystems[i]; - if(ps != NULL) { - currentParticleCount+= ps->getAliveParticleCount(); - - bool showParticle= true; - if( dynamic_cast (ps) != NULL || - dynamic_cast (ps) != NULL) { - showParticle = ps->getVisible() || (ps->getState() == ParticleSystem::sFade); - } - if(showParticle == true){ - ps->update(); - if(ps->isEmpty() && ps->getState() == ParticleSystem::sFade) { - cleanupParticleSystemsList.push_back(ps); + if (ps != NULL) { + ps->callParticleOwnerEnd(ps); } + + delete ps; + this->particleSystems.erase(this->particleSystems.begin() + index); } } - } - //particleSystems.remove(NULL); - cleanupParticleSystems(cleanupParticleSystemsList); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) - SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld, particleSystemCount = %d, currentParticleCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),particleSystemCount,currentParticleCount); -} + void ParticleManager::cleanupParticleSystems(vector &cleanupParticleSystemsList) { + if (cleanupParticleSystemsList.empty() == false) { + for (int i = (int) cleanupParticleSystemsList.size() - 1; i >= 0; i--) { + ParticleSystem *ps = cleanupParticleSystemsList[i]; + cleanupParticleSystems(ps); + } -bool ParticleManager::validateParticleSystemStillExists(ParticleSystem * particleSystem) const{ - int index= findParticleSystems(particleSystem, this->particleSystems); - return (index >= 0); -} - -void ParticleManager::removeParticleSystemsForParticleOwner(ParticleOwner *particleOwner) { - if(particleOwner != NULL && particleSystems.empty() == false) { - vector cleanupParticleSystemsList; - - for(unsigned int index = 0; index < particleSystems.size(); ++index) { - ParticleSystem *ps= particleSystems[index]; - if(ps != NULL && ps->getParticleOwner() == particleOwner) { - cleanupParticleSystemsList.push_back(ps); + cleanupParticleSystemsList.clear(); } } - if(cleanupParticleSystemsList.empty() == false) { - cleanupParticleSystems(cleanupParticleSystemsList); - } - } -} -int ParticleManager::findParticleSystems(ParticleSystem *psFind, const vector &particleSystems) const{ - int result= -1; - for(unsigned int i= 0; i < particleSystems.size(); i++){ - ParticleSystem *ps= particleSystems[i]; - if(ps != NULL && psFind != NULL && psFind == ps){ - result= i; - break; - } - } - return result; -} - -void ParticleManager::cleanupParticleSystems(ParticleSystem *ps) { - - int index= findParticleSystems(ps, this->particleSystems); - if(ps != NULL && index >= 0) { -// printf("-- Delete cleanupParticleSystems [%p]\n",ps); -// static map deleteList; -// if(deleteList.find(ps) != deleteList.end()) { -// assert(deleteList.find(ps) == deleteList.end()); -// } -// deleteList[ps]++; - - // This code causes segfault on game end, no need to fade, just delete - //if(ps->getState() != ParticleSystem::sFade) { - // ps->fade(); - //} - - if(ps != NULL) { - ps->callParticleOwnerEnd(ps); + void ParticleManager::cleanupUnitParticleSystems(vector &cleanupParticleSystemsList) { + if (cleanupParticleSystemsList.empty() == false) { + for (int i = (int) cleanupParticleSystemsList.size() - 1; i >= 0; i--) { + ParticleSystem *ps = cleanupParticleSystemsList[i]; + cleanupParticleSystems(ps); + } + cleanupParticleSystemsList.clear(); + } } - delete ps; - this->particleSystems.erase(this->particleSystems.begin() + index); - } -} - -void ParticleManager::cleanupParticleSystems(vector &cleanupParticleSystemsList){ - if(cleanupParticleSystemsList.empty() == false) { - for(int i= (int)cleanupParticleSystemsList.size()-1; i >= 0; i--) { - ParticleSystem *ps= cleanupParticleSystemsList[i]; - cleanupParticleSystems(ps); + void ParticleManager::manage(ParticleSystem *ps) { + assert((std::find(particleSystems.begin(), particleSystems.end(), ps) == particleSystems.end()) && "particle cannot be added twice"); + particleSystems.push_back(ps); + for (int i = ps->getChildCount() - 1; i >= 0; i--) { + manage(ps->getChild(i)); + } } - cleanupParticleSystemsList.clear(); - } -} + void ParticleManager::end() { + while (particleSystems.empty() == false) { + ParticleSystem *ps = particleSystems.back(); -void ParticleManager::cleanupUnitParticleSystems(vector &cleanupParticleSystemsList){ - if(cleanupParticleSystemsList.empty() == false) { - for(int i= (int)cleanupParticleSystemsList.size()-1; i >= 0; i--) { - ParticleSystem *ps= cleanupParticleSystemsList[i]; - cleanupParticleSystems(ps); + // printf("-- Delete end() [%p]\n",ps); + // static map deleteList; + // if(deleteList.find(ps) != deleteList.end()) { + // assert(deleteList.find(ps) == deleteList.end()); + // } + // deleteList[ps]++; + + if (ps != NULL) { + ps->callParticleOwnerEnd(ps); + } + delete ps; + particleSystems.pop_back(); + } } - cleanupParticleSystemsList.clear(); - } -} -void ParticleManager::manage(ParticleSystem *ps){ - assert((std::find(particleSystems.begin(),particleSystems.end(),ps) == particleSystems.end()) && "particle cannot be added twice"); - particleSystems.push_back(ps); - for(int i = ps->getChildCount() - 1; i >= 0; i--) { - manage(ps->getChild(i)); - } -} - -void ParticleManager::end(){ - while(particleSystems.empty() == false){ - ParticleSystem *ps = particleSystems.back(); - -// printf("-- Delete end() [%p]\n",ps); -// static map deleteList; -// if(deleteList.find(ps) != deleteList.end()) { -// assert(deleteList.find(ps) == deleteList.end()); -// } -// deleteList[ps]++; - - if(ps != NULL) { - ps->callParticleOwnerEnd(ps); } - delete ps; - particleSystems.pop_back(); - } -} - -} -}//end namespace + }//end namespace diff --git a/source/shared_lib/sources/graphics/pixmap.cpp b/source/shared_lib/sources/graphics/pixmap.cpp index 0d0e81e2c..1efe4ae9c 100644 --- a/source/shared_lib/sources/graphics/pixmap.cpp +++ b/source/shared_lib/sources/graphics/pixmap.cpp @@ -32,1575 +32,1554 @@ using namespace Shared::Util; using namespace std; using namespace Shared::Graphics::Gl; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -using namespace Util; + using namespace Util; -// ===================================================== -// file structs -// ===================================================== + // ===================================================== + // file structs + // ===================================================== #pragma pack(push, 1) -struct BitmapFileHeader{ - uint8 type1; - uint8 type2; - uint32 size; - uint16 reserved1; - uint16 reserved2; - uint32 offsetBits; -}; + struct BitmapFileHeader { + uint8 type1; + uint8 type2; + uint32 size; + uint16 reserved1; + uint16 reserved2; + uint32 offsetBits; + }; -struct BitmapInfoHeader{ - uint32 size; - int32 width; - int32 height; - uint16 planes; - uint16 bitCount; - uint32 compression; - uint32 sizeImage; - int32 xPelsPerMeter; - int32 yPelsPerMeter; - uint32 clrUsed; - uint32 clrImportant; -}; + struct BitmapInfoHeader { + uint32 size; + int32 width; + int32 height; + uint16 planes; + uint16 bitCount; + uint32 compression; + uint32 sizeImage; + int32 xPelsPerMeter; + int32 yPelsPerMeter; + uint32 clrUsed; + uint32 clrImportant; + }; -struct TargaFileHeader{ - int8 idLength; - int8 colourMapType; - int8 dataTypeCode; - int16 colourMapOrigin; - int16 colourMapLength; - int8 colourMapDepth; - int16 xOrigin; - int16 yOrigin; - int16 width; - int16 height; - int8 bitsPerPixel; - int8 imageDescriptor; -}; + struct TargaFileHeader { + int8 idLength; + int8 colourMapType; + int8 dataTypeCode; + int16 colourMapOrigin; + int16 colourMapLength; + int8 colourMapDepth; + int16 xOrigin; + int16 yOrigin; + int16 width; + int16 height; + int8 bitsPerPixel; + int8 imageDescriptor; + }; #pragma pack(pop) -const int tgaUncompressedRgb= 2; -const int tgaUncompressedBw= 3; + const int tgaUncompressedRgb = 2; + const int tgaUncompressedBw = 3; -void CalculatePixelsCRC(uint8 *pixels,std::size_t pixelByteCount, Checksum &crc) { -// crc = Checksum(); -// for(std::size_t i = 0; i < pixelByteCount; ++i) { -// crc.addByte(pixels[i]); -// } -} - -// ===================================================== -// class PixmapIoTga -// ===================================================== - -PixmapIoTga::PixmapIoTga() { - file= NULL; -} - -PixmapIoTga::~PixmapIoTga() { - if(file != NULL) { - fclose(file); - file=NULL; - } -} - -void PixmapIoTga::openRead(const string &path) { - - try { - #ifdef WIN32 - file= _wfopen(utf8_decode(path).c_str(), L"rb"); - #else - file= fopen(path.c_str(),"rb"); - #endif - if (file == NULL) { - throw megaglest_runtime_error("Can't open TGA file: "+ path,true); + void CalculatePixelsCRC(uint8 *pixels, std::size_t pixelByteCount, Checksum &crc) { + // crc = Checksum(); + // for(std::size_t i = 0; i < pixelByteCount; ++i) { + // crc.addByte(pixels[i]); + // } } - //read header - TargaFileHeader fileHeader; - size_t readBytes = fread(&fileHeader, sizeof(TargaFileHeader), 1, file); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - fileHeader.bitsPerPixel = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.bitsPerPixel); - fileHeader.colourMapDepth = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); - fileHeader.colourMapLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); - fileHeader.colourMapOrigin = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapOrigin); - fileHeader.colourMapType = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapType); - fileHeader.dataTypeCode = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.dataTypeCode); - fileHeader.height = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.height); - fileHeader.idLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.idLength); - fileHeader.imageDescriptor = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.imageDescriptor); - fileHeader.width = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.width); - } - //check that we can load this tga file - if(fileHeader.idLength != 0) { - throw megaglest_runtime_error(path + ": id field is not 0",true); + // ===================================================== + // class PixmapIoTga + // ===================================================== + + PixmapIoTga::PixmapIoTga() { + file = NULL; } - if(fileHeader.dataTypeCode != tgaUncompressedRgb && fileHeader.dataTypeCode != tgaUncompressedBw) { - throw megaglest_runtime_error(path + ": only uncompressed BW and RGB targa images are supported",true); - } - - //check bits per pixel - if(fileHeader.bitsPerPixel != 8 && fileHeader.bitsPerPixel != 24 && fileHeader.bitsPerPixel !=32) { - throw megaglest_runtime_error(path + ": only 8, 24 and 32 bit targa images are supported",true); - } - - h= fileHeader.height; - w= fileHeader.width; - components= fileHeader.bitsPerPixel / 8; - } - catch(megaglest_runtime_error& ex) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error in [%s] on line: %d msg: %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,ex.what()); - throw megaglest_runtime_error(szBuf,!ex.wantStackTrace()); - } - catch(exception& ex) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error in [%s] on line: %d msg: %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,ex.what()); - throw megaglest_runtime_error(szBuf); - } -} - -void PixmapIoTga::read(uint8 *pixels) { - read(pixels, components); -} - -void PixmapIoTga::read(uint8 *pixels, int components) { - try { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - - for(int i=0; icomponents == 1) { - size_t readBytes = fread(&l, 1, 1, file); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - if(bigEndianSystem == true) { - l = Shared::PlatformByteOrder::fromCommonEndian(l); - } - r= l; - g= l; - b= l; - a= 255; + PixmapIoTga::~PixmapIoTga() { + if (file != NULL) { + fclose(file); + file = NULL; } - else { - size_t readBytes = fread(&b, 1, 1, file); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); + } + + void PixmapIoTga::openRead(const string &path) { + + try { +#ifdef WIN32 + file = _wfopen(utf8_decode(path).c_str(), L"rb"); +#else + file = fopen(path.c_str(), "rb"); +#endif + if (file == NULL) { + throw megaglest_runtime_error("Can't open TGA file: " + path, true); + } + + //read header + TargaFileHeader fileHeader; + size_t readBytes = fread(&fileHeader, sizeof(TargaFileHeader), 1, file); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); throw megaglest_runtime_error(szBuf); } - if(bigEndianSystem == true) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + fileHeader.bitsPerPixel = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.bitsPerPixel); + fileHeader.colourMapDepth = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapOrigin = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapOrigin); + fileHeader.colourMapType = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.colourMapType); + fileHeader.dataTypeCode = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.dataTypeCode); + fileHeader.height = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.height); + fileHeader.idLength = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.idLength); + fileHeader.imageDescriptor = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.imageDescriptor); + fileHeader.width = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.width); + } + //check that we can load this tga file + if (fileHeader.idLength != 0) { + throw megaglest_runtime_error(path + ": id field is not 0", true); + } + + if (fileHeader.dataTypeCode != tgaUncompressedRgb && fileHeader.dataTypeCode != tgaUncompressedBw) { + throw megaglest_runtime_error(path + ": only uncompressed BW and RGB targa images are supported", true); + } + + //check bits per pixel + if (fileHeader.bitsPerPixel != 8 && fileHeader.bitsPerPixel != 24 && fileHeader.bitsPerPixel != 32) { + throw megaglest_runtime_error(path + ": only 8, 24 and 32 bit targa images are supported", true); + } + + h = fileHeader.height; + w = fileHeader.width; + components = fileHeader.bitsPerPixel / 8; + } catch (megaglest_runtime_error& ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error in [%s] on line: %d msg: %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, ex.what()); + throw megaglest_runtime_error(szBuf, !ex.wantStackTrace()); + } catch (exception& ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error in [%s] on line: %d msg: %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, ex.what()); + throw megaglest_runtime_error(szBuf); + } + } + + void PixmapIoTga::read(uint8 *pixels) { + read(pixels, components); + } + + void PixmapIoTga::read(uint8 *pixels, int components) { + try { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + + for (int i = 0; i < h*w*components; i += components) { + uint8 r = 0, g = 0, b = 0, a = 0, l = 0; + + if (this->components == 1) { + size_t readBytes = fread(&l, 1, 1, file); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + if (bigEndianSystem == true) { + l = Shared::PlatformByteOrder::fromCommonEndian(l); + } + r = l; + g = l; + b = l; + a = 255; + } else { + size_t readBytes = fread(&b, 1, 1, file); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + if (bigEndianSystem == true) { + b = Shared::PlatformByteOrder::fromCommonEndian(b); + } + + readBytes = fread(&g, 1, 1, file); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + if (bigEndianSystem == true) { + g = Shared::PlatformByteOrder::fromCommonEndian(g); + } + + readBytes = fread(&r, 1, 1, file); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + if (bigEndianSystem == true) { + r = Shared::PlatformByteOrder::fromCommonEndian(r); + } + + if (this->components == 4) { + readBytes = fread(&a, 1, 1, file); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + if (bigEndianSystem == true) { + a = Shared::PlatformByteOrder::fromCommonEndian(a); + } + + } else { + a = 255; + } + l = (r + g + b) / 3; + } + + switch (components) { + case 1: + pixels[i] = l; + break; + case 3: + pixels[i] = r; + pixels[i + 1] = g; + pixels[i + 2] = b; + break; + case 4: + pixels[i] = r; + pixels[i + 1] = g; + pixels[i + 2] = b; + pixels[i + 3] = a; + break; + } + } + } catch (megaglest_runtime_error& ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error in [%s] on line: %d msg: %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, ex.what()); + throw megaglest_runtime_error(szBuf, !ex.wantStackTrace()); + } catch (exception& ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Error in [%s] on line: %d msg: %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __LINE__, ex.what()); + throw megaglest_runtime_error(szBuf); + } + } + + void PixmapIoTga::openWrite(const string &path, int w, int h, int components) { + this->w = w; + this->h = h; + this->components = components; + +#ifdef WIN32 + file = _wfopen(utf8_decode(path).c_str(), L"wb"); +#else + file = fopen(path.c_str(), "wb"); +#endif + if (file == NULL) { + throw megaglest_runtime_error("Can't open TGA file: " + path, true); + } + + TargaFileHeader fileHeader; + memset(&fileHeader, 0, sizeof(TargaFileHeader)); + fileHeader.dataTypeCode = components == 1 ? tgaUncompressedBw : tgaUncompressedRgb; + fileHeader.bitsPerPixel = components * 8; + fileHeader.width = w; + fileHeader.height = h; + fileHeader.imageDescriptor = components == 4 ? 8 : 0; + + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + fileHeader.bitsPerPixel = Shared::PlatformByteOrder::toCommonEndian(fileHeader.bitsPerPixel); + fileHeader.colourMapDepth = Shared::PlatformByteOrder::toCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapLength = Shared::PlatformByteOrder::toCommonEndian(fileHeader.colourMapDepth); + fileHeader.colourMapOrigin = Shared::PlatformByteOrder::toCommonEndian(fileHeader.colourMapOrigin); + fileHeader.colourMapType = Shared::PlatformByteOrder::toCommonEndian(fileHeader.colourMapType); + fileHeader.dataTypeCode = Shared::PlatformByteOrder::toCommonEndian(fileHeader.dataTypeCode); + fileHeader.height = Shared::PlatformByteOrder::toCommonEndian(fileHeader.height); + fileHeader.idLength = Shared::PlatformByteOrder::toCommonEndian(fileHeader.idLength); + fileHeader.imageDescriptor = Shared::PlatformByteOrder::toCommonEndian(fileHeader.imageDescriptor); + fileHeader.width = Shared::PlatformByteOrder::toCommonEndian(fileHeader.width); + } + + fwrite(&fileHeader, sizeof(TargaFileHeader), 1, file); + } + + void PixmapIoTga::write(uint8 *pixels) { + if (components == 1) { + + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + Shared::PlatformByteOrder::toEndianTypeArray(pixels, h*w); + } + + fwrite(pixels, h*w, 1, file); + } else { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + Shared::PlatformByteOrder::toEndianTypeArray(pixels, h*w*components); + } + + for (int i = 0; i < h*w*components; i += components) { + fwrite(&pixels[i + 2], 1, 1, file); + fwrite(&pixels[i + 1], 1, 1, file); + fwrite(&pixels[i], 1, 1, file); + if (components == 4) { + fwrite(&pixels[i + 3], 1, 1, file); + } + } + } + } + + // ===================================================== + // class PixmapIoBmp + // ===================================================== + + PixmapIoBmp::PixmapIoBmp() { + file = NULL; + } + + PixmapIoBmp::~PixmapIoBmp() { + if (file != NULL) { + fclose(file); + file = NULL; + } + } + + void PixmapIoBmp::openRead(const string &path) { +#ifdef WIN32 + file = _wfopen(utf8_decode(path).c_str(), L"rb"); +#else + file = fopen(path.c_str(), "rb"); +#endif + if (file == NULL) { + throw megaglest_runtime_error("Can't open BMP file: " + path, true); + } + + //read file header + BitmapFileHeader fileHeader; + size_t readBytes = fread(&fileHeader, sizeof(BitmapFileHeader), 1, file); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + fileHeader.offsetBits = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.offsetBits); + fileHeader.reserved1 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.reserved1); + fileHeader.reserved2 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.reserved2); + fileHeader.size = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.size); + fileHeader.type1 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.type1); + fileHeader.type2 = Shared::PlatformByteOrder::fromCommonEndian(fileHeader.type2); + } + + if (fileHeader.type1 != 'B' || fileHeader.type2 != 'M') { + throw megaglest_runtime_error(path + " is not a bitmap", true); + } + + //read info header + BitmapInfoHeader infoHeader; + readBytes = fread(&infoHeader, sizeof(BitmapInfoHeader), 1, file); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + if (bigEndianSystem == true) { + infoHeader.bitCount = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.bitCount); + infoHeader.clrImportant = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.clrImportant); + infoHeader.clrUsed = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.clrUsed); + infoHeader.compression = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.compression); + infoHeader.height = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.height); + infoHeader.planes = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.planes); + infoHeader.size = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.size); + infoHeader.sizeImage = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.sizeImage); + infoHeader.width = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.width); + infoHeader.xPelsPerMeter = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.xPelsPerMeter); + infoHeader.yPelsPerMeter = Shared::PlatformByteOrder::fromCommonEndian(infoHeader.yPelsPerMeter); + } + if (infoHeader.bitCount != 24) { + throw megaglest_runtime_error(path + " is not a 24 bit bitmap", true); + } + + h = infoHeader.height; + w = infoHeader.width; + components = 3; + } + + void PixmapIoBmp::read(uint8 *pixels) { + read(pixels, 3); + } + + void PixmapIoBmp::read(uint8 *pixels, int components) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + + for (int i = 0; i < h*w*components; i += components) { + uint8 r, g, b; + size_t readBytes = fread(&b, 1, 1, file); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + if (bigEndianSystem == true) { b = Shared::PlatformByteOrder::fromCommonEndian(b); } - readBytes = fread(&g, 1, 1, file); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); throw megaglest_runtime_error(szBuf); } - if(bigEndianSystem == true) { + if (bigEndianSystem == true) { g = Shared::PlatformByteOrder::fromCommonEndian(g); } readBytes = fread(&r, 1, 1, file); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); + if (readBytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", readBytes, __LINE__); throw megaglest_runtime_error(szBuf); } - if(bigEndianSystem == true) { + if (bigEndianSystem == true) { r = Shared::PlatformByteOrder::fromCommonEndian(r); } - if(this->components == 4) { - readBytes = fread(&a, 1, 1, file); - if(readBytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",readBytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - if(bigEndianSystem == true) { - a = Shared::PlatformByteOrder::fromCommonEndian(a); - } + switch (components) { + case 1: + pixels[i] = (r + g + b) / 3; + break; + case 3: + pixels[i] = r; + pixels[i + 1] = g; + pixels[i + 2] = b; + break; + case 4: + pixels[i] = r; + pixels[i + 1] = g; + pixels[i + 2] = b; + pixels[i + 3] = 255; + break; } - else { - a= 255; + } + } + + void PixmapIoBmp::openWrite(const string &path, int w, int h, int components) { + this->w = w; + this->h = h; + this->components = components; + +#ifdef WIN32 + file = _wfopen(utf8_decode(path).c_str(), L"wb"); +#else + file = fopen(path.c_str(), "wb"); +#endif + if (file == NULL) { + throw megaglest_runtime_error("Can't open BMP file for writing: " + path); + } + + BitmapFileHeader fileHeader; + fileHeader.type1 = 'B'; + fileHeader.type2 = 'M'; + fileHeader.offsetBits = sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader); + fileHeader.size = sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + 3 * h*w; + fileHeader.reserved1 = 0; + fileHeader.reserved2 = 0; + + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + fileHeader.offsetBits = Shared::PlatformByteOrder::toCommonEndian(fileHeader.offsetBits); + fileHeader.reserved1 = Shared::PlatformByteOrder::toCommonEndian(fileHeader.reserved1); + fileHeader.reserved2 = Shared::PlatformByteOrder::toCommonEndian(fileHeader.reserved2); + fileHeader.size = Shared::PlatformByteOrder::toCommonEndian(fileHeader.size); + fileHeader.type1 = Shared::PlatformByteOrder::toCommonEndian(fileHeader.type1); + fileHeader.type2 = Shared::PlatformByteOrder::toCommonEndian(fileHeader.type2); + } + + fwrite(&fileHeader, sizeof(BitmapFileHeader), 1, file); + + //info header + BitmapInfoHeader infoHeader; + infoHeader.bitCount = 24; + infoHeader.clrImportant = 0; + infoHeader.clrUsed = 0; + infoHeader.compression = 0; + infoHeader.height = h; + infoHeader.planes = 1; + infoHeader.size = sizeof(BitmapInfoHeader); + infoHeader.sizeImage = 0; + infoHeader.width = w; + infoHeader.xPelsPerMeter = 0; + infoHeader.yPelsPerMeter = 0; + + if (bigEndianSystem == true) { + infoHeader.bitCount = Shared::PlatformByteOrder::toCommonEndian(infoHeader.bitCount); + infoHeader.clrImportant = Shared::PlatformByteOrder::toCommonEndian(infoHeader.clrImportant); + infoHeader.clrUsed = Shared::PlatformByteOrder::toCommonEndian(infoHeader.clrUsed); + infoHeader.compression = Shared::PlatformByteOrder::toCommonEndian(infoHeader.compression); + infoHeader.height = Shared::PlatformByteOrder::toCommonEndian(infoHeader.height); + infoHeader.planes = Shared::PlatformByteOrder::toCommonEndian(infoHeader.planes); + infoHeader.size = Shared::PlatformByteOrder::toCommonEndian(infoHeader.size); + infoHeader.sizeImage = Shared::PlatformByteOrder::toCommonEndian(infoHeader.sizeImage); + infoHeader.width = Shared::PlatformByteOrder::toCommonEndian(infoHeader.width); + infoHeader.xPelsPerMeter = Shared::PlatformByteOrder::toCommonEndian(infoHeader.xPelsPerMeter); + infoHeader.yPelsPerMeter = Shared::PlatformByteOrder::toCommonEndian(infoHeader.yPelsPerMeter); + } + + fwrite(&infoHeader, sizeof(BitmapInfoHeader), 1, file); + } + + void PixmapIoBmp::write(uint8 *pixels) { + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + Shared::PlatformByteOrder::toEndianTypeArray(pixels, h*w*components); + } + + for (int i = 0; i < h*w*components; i += components) { + fwrite(&pixels[i + 2], 1, 1, file); + fwrite(&pixels[i + 1], 1, 1, file); + fwrite(&pixels[i], 1, 1, file); + } + } + + // ===================================================== + // class PixmapIoPng + // ===================================================== + + PixmapIoPng::PixmapIoPng() { + file = NULL; + } + + PixmapIoPng::~PixmapIoPng() { + if (file != NULL) { + fclose(file); + file = NULL; + } + } + + void PixmapIoPng::openRead(const string &path) { + throw megaglest_runtime_error("PixmapIoPng::openRead not implemented!"); + } + + void PixmapIoPng::read(uint8 *pixels) { + throw megaglest_runtime_error("PixmapIoPng::read not implemented!"); + } + + void PixmapIoPng::read(uint8 *pixels, int components) { + + throw megaglest_runtime_error("PixmapIoPng::read #2 not implemented!"); + } + + void PixmapIoPng::openWrite(const string &path, int w, int h, int components) { + this->path = path; + this->w = w; + this->h = h; + this->components = components; + +#ifdef WIN32 + file = _wfopen(utf8_decode(path).c_str(), L"wb"); +#else + file = fopen(path.c_str(), "wb"); +#endif + if (file == NULL) { + throw megaglest_runtime_error("Can't open PNG file for writing: " + path); + } + } + + void PixmapIoPng::write(uint8 *pixels) { + // initialize stuff + png_bytep *imrow = new png_bytep[h]; + //png_bytep *imrow = (png_bytep*) malloc(sizeof(png_bytep) * height); + for (int i = 0; i < h; ++i) { + imrow[i] = pixels + (h - 1 - i) * w * components; + } + + png_structp imgp = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); + png_infop infop = png_create_info_struct(imgp); + png_init_io(imgp, file); + + int color_type = PNG_COLOR_TYPE_RGB; + if (components == 4) { + color_type = PNG_COLOR_TYPE_RGBA; + } + png_set_IHDR(imgp, infop, w, h, + 8, color_type, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + // write file + png_write_info(imgp, infop); + png_write_image(imgp, imrow); + png_write_end(imgp, NULL); + + delete[] imrow; + } + + // ===================================================== + // class PixmapIoJpg + // ===================================================== + + PixmapIoJpg::PixmapIoJpg() { + file = NULL; + } + + PixmapIoJpg::~PixmapIoJpg() { + if (file != NULL) { + fclose(file); + file = NULL; + } + } + + void PixmapIoJpg::openRead(const string &path) { + throw megaglest_runtime_error("PixmapIoJpg::openRead not implemented!"); + } + + void PixmapIoJpg::read(uint8 *pixels) { + throw megaglest_runtime_error("PixmapIoJpg::read not implemented!"); + } + + void PixmapIoJpg::read(uint8 *pixels, int components) { + + throw megaglest_runtime_error("PixmapIoJpg::read #2 not implemented!"); + } + + void PixmapIoJpg::openWrite(const string &path, int w, int h, int components) { + this->path = path; + this->w = w; + this->h = h; + this->components = components; + +#ifdef WIN32 + file = _wfopen(utf8_decode(path).c_str(), L"wb"); +#else + file = fopen(path.c_str(), "wb"); +#endif + if (file == NULL) { + throw megaglest_runtime_error("Can't open JPG file for writing: " + path); + } + } + + void PixmapIoJpg::write(uint8 *pixels) { + /* + * alpha channel is not supported for jpeg. strip it. + */ + unsigned char * tmpbytes = NULL; + if (components == 4) { + int n = w * h; + unsigned char *dst = tmpbytes = (unsigned char *) malloc(n * 3); + if (dst != NULL) { + const unsigned char *src = pixels; + for (int i = 0; i < n; i++) { + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + src++; + } } - l= (r+g+b)/3; + components = 3; } - switch(components) { - case 1: - pixels[i]= l; - break; - case 3: - pixels[i]= r; - pixels[i+1]= g; - pixels[i+2]= b; - break; - case 4: - pixels[i]= r; - pixels[i+1]= g; - pixels[i+2]= b; - pixels[i+3]= a; - break; + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + + /* this is a pointer to one row of image data */ + JSAMPROW row_pointer[1]; + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + jpeg_stdio_dest(&cinfo, file); + + /* Setting the parameters of the output file here */ + cinfo.image_width = w; + cinfo.image_height = h; + cinfo.input_components = 3; // no alpha channel for jpeg + cinfo.in_color_space = JCS_RGB; + /* default compression parameters, we shouldn't be worried about these */ + jpeg_set_defaults(&cinfo); + /* Now do the compression .. */ + jpeg_start_compress(&cinfo, TRUE); + + /* use stripped alpha channel bytes */ + if (tmpbytes) { + pixels = tmpbytes; + } + + // OpenGL writes from bottom to top. + // libjpeg goes from top to bottom. + // flip lines. + uint8 *flip = (uint8 *) malloc(sizeof(uint8) * w * h * 3); + + if (pixels != NULL && flip != NULL) { + for (int y = 0; y < h; ++y) { + for (int x = 0; x < w; ++x) { + flip[(y * w + x) * 3] = pixels[((h - 1 - y) * w + x) * 3]; + flip[(y * w + x) * 3 + 1] = pixels[((h - 1 - y) * w + x) * 3 + 1]; + flip[(y * w + x) * 3 + 2] = pixels[((h - 1 - y) * w + x) * 3 + 2]; + } + } + + /* like reading a file, this time write one row at a time */ + while (cinfo.next_scanline < cinfo.image_height) { + row_pointer[0] = &flip[cinfo.next_scanline * cinfo.image_width * cinfo.input_components]; + jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + } + if (tmpbytes) { + free(tmpbytes); + tmpbytes = NULL; + } + if (flip) { + free(flip); + flip = NULL; + } + + /* similar to read file, clean up after we're done compressing */ + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + //fclose( outfile ); + /* success code is 1! */ + } + + // ===================================================== + // class Pixmap1D + // ===================================================== + + + // ===================== PUBLIC ======================== + + Pixmap1D::Pixmap1D() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + + + w = -1; + components = -1; + pixels = NULL; + } + + Pixmap1D::Pixmap1D(int components) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + + + init(components); + } + + Pixmap1D::Pixmap1D(int w, int components) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + + + init(w, components); + } + + void Pixmap1D::init(int components) { + this->w = -1; + this->components = components; + pixels = NULL; + CalculatePixelsCRC(pixels, 0, crc); + } + + void Pixmap1D::init(int w, int components) { + this->w = w; + this->components = components; + pixels = new uint8[getPixelByteCount()]; + CalculatePixelsCRC(pixels, 0, crc); + } + + std::size_t Pixmap1D::getPixelByteCount() const { + return (w * components); + } + + void Pixmap1D::deletePixels() { + delete[] pixels; + pixels = NULL; + } + + Pixmap1D::~Pixmap1D() { + deletePixels(); + } + + void Pixmap1D::load(const string &path) { + string extension = (path.empty() == false ? path.substr(path.find_last_of('.') + 1) : ""); + if (toLower(extension) == "bmp") { + loadBmp(path); + } else if (toLower(extension) == "tga") { + loadTga(path); + } else { + throw megaglest_runtime_error("Unknown pixmap extension [" + extension + "] file [" + path + "]"); + } + this->path = path; + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + } + + void Pixmap1D::loadBmp(const string &path) { + this->path = path; + + PixmapIoBmp plb; + plb.openRead(path); + + //init + if (plb.getH() == 1) { + w = plb.getW(); + } else if (plb.getW() == 1) { + w = plb.getH(); + } else { + throw megaglest_runtime_error("One of the texture dimensions must be 1"); + } + + if (components == -1) { + components = 3; + } + if (pixels == NULL) { + pixels = new uint8[getPixelByteCount()]; + } + + //data + plb.read(pixels, components); + } + + void Pixmap1D::loadTga(const string &path) { + this->path = path; + + PixmapIoTga plt; + plt.openRead(path); + + //init + if (plt.getH() == 1) { + w = plt.getW(); + } else if (plt.getW() == 1) { + w = plt.getH(); + } else { + throw megaglest_runtime_error("One of the texture dimensions must be 1"); + } + + int fileComponents = plt.getComponents(); + + if (components == -1) { + components = fileComponents; + } + if (pixels == NULL) { + pixels = new uint8[getPixelByteCount()]; + } + + //read data + plt.read(pixels, components); + } + + // ===================================================== + // class Pixmap2D + // ===================================================== + + // ===================== PUBLIC ======================== + + Pixmap2D::Pixmap2D() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + + h = -1; + w = -1; + components = -1; + pixels = NULL; + } + + Pixmap2D::Pixmap2D(int components) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + + h = -1; + w = -1; + this->components = -1; + pixels = NULL; + + init(components); + } + + Pixmap2D::Pixmap2D(int w, int h, int components) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + + this->h = 0; + this->w = -1; + this->components = -1; + pixels = NULL; + + init(w, h, components); + } + + void Pixmap2D::init(int components) { + this->w = -1; + this->h = -1; + this->components = components; + deletePixels(); + pixels = NULL; + CalculatePixelsCRC(pixels, 0, crc); + } + + void Pixmap2D::init(int w, int h, int components) { + this->w = w; + this->h = h; + this->components = components; + deletePixels(); + + if (getPixelByteCount() <= 0 || (h <= 0 || w <= 0 || components <= 0)) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap dimensions for [%s], h = %d, w = %d, components = %d\n", path.c_str(), h, w, components); + throw megaglest_runtime_error(szBuf); + } + pixels = new uint8[getPixelByteCount()]; + CalculatePixelsCRC(pixels, 0, crc); + } + + std::size_t Pixmap2D::getPixelByteCount() const { + return (h * w * components); + } + + void Pixmap2D::deletePixels() { + if (pixels) { + delete[] pixels; + pixels = NULL; } } - } - catch(megaglest_runtime_error& ex) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error in [%s] on line: %d msg: %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,ex.what()); - throw megaglest_runtime_error(szBuf,!ex.wantStackTrace()); - } - catch(exception& ex) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Error in [%s] on line: %d msg: %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,ex.what()); - throw megaglest_runtime_error(szBuf); - } -} -void PixmapIoTga::openWrite(const string &path, int w, int h, int components) { - this->w= w; - this->h= h; - this->components= components; - -#ifdef WIN32 - file= _wfopen(utf8_decode(path).c_str(), L"wb"); -#else - file= fopen(path.c_str(),"wb"); -#endif - if (file == NULL) { - throw megaglest_runtime_error("Can't open TGA file: "+ path,true); - } - - TargaFileHeader fileHeader; - memset(&fileHeader, 0, sizeof(TargaFileHeader)); - fileHeader.dataTypeCode= components==1? tgaUncompressedBw: tgaUncompressedRgb; - fileHeader.bitsPerPixel= components*8; - fileHeader.width= w; - fileHeader.height= h; - fileHeader.imageDescriptor= components==4? 8: 0; - - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - fileHeader.bitsPerPixel = Shared::PlatformByteOrder::toCommonEndian(fileHeader.bitsPerPixel); - fileHeader.colourMapDepth = Shared::PlatformByteOrder::toCommonEndian(fileHeader.colourMapDepth); - fileHeader.colourMapLength = Shared::PlatformByteOrder::toCommonEndian(fileHeader.colourMapDepth); - fileHeader.colourMapOrigin = Shared::PlatformByteOrder::toCommonEndian(fileHeader.colourMapOrigin); - fileHeader.colourMapType = Shared::PlatformByteOrder::toCommonEndian(fileHeader.colourMapType); - fileHeader.dataTypeCode = Shared::PlatformByteOrder::toCommonEndian(fileHeader.dataTypeCode); - fileHeader.height = Shared::PlatformByteOrder::toCommonEndian(fileHeader.height); - fileHeader.idLength = Shared::PlatformByteOrder::toCommonEndian(fileHeader.idLength); - fileHeader.imageDescriptor = Shared::PlatformByteOrder::toCommonEndian(fileHeader.imageDescriptor); - fileHeader.width = Shared::PlatformByteOrder::toCommonEndian(fileHeader.width); - } - - fwrite(&fileHeader, sizeof(TargaFileHeader), 1, file); -} - -void PixmapIoTga::write(uint8 *pixels) { - if(components == 1) { - - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - Shared::PlatformByteOrder::toEndianTypeArray(pixels,h*w); + Pixmap2D::~Pixmap2D() { + deletePixels(); } - fwrite(pixels, h*w, 1, file); - } - else { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - Shared::PlatformByteOrder::toEndianTypeArray(pixels,h*w*components); - } - - for(int i=0; iw= w; - this->h= h; - this->components= components; - -#ifdef WIN32 - file= _wfopen(utf8_decode(path).c_str(), L"wb"); -#else - file= fopen(path.c_str(),"wb"); -#endif - if (file == NULL) { - throw megaglest_runtime_error("Can't open BMP file for writing: "+ path); - } - - BitmapFileHeader fileHeader; - fileHeader.type1='B'; - fileHeader.type2='M'; - fileHeader.offsetBits=sizeof(BitmapFileHeader)+sizeof(BitmapInfoHeader); - fileHeader.size=sizeof(BitmapFileHeader)+sizeof(BitmapInfoHeader)+3*h*w; - fileHeader.reserved1 = 0; - fileHeader.reserved2 = 0; - - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - fileHeader.offsetBits = Shared::PlatformByteOrder::toCommonEndian(fileHeader.offsetBits); - fileHeader.reserved1 = Shared::PlatformByteOrder::toCommonEndian(fileHeader.reserved1); - fileHeader.reserved2 = Shared::PlatformByteOrder::toCommonEndian(fileHeader.reserved2); - fileHeader.size = Shared::PlatformByteOrder::toCommonEndian(fileHeader.size); - fileHeader.type1 = Shared::PlatformByteOrder::toCommonEndian(fileHeader.type1); - fileHeader.type2 = Shared::PlatformByteOrder::toCommonEndian(fileHeader.type2); - } - - fwrite(&fileHeader, sizeof(BitmapFileHeader), 1, file); - - //info header - BitmapInfoHeader infoHeader; - infoHeader.bitCount=24; - infoHeader.clrImportant=0; - infoHeader.clrUsed=0; - infoHeader.compression=0; - infoHeader.height= h; - infoHeader.planes=1; - infoHeader.size=sizeof(BitmapInfoHeader); - infoHeader.sizeImage=0; - infoHeader.width= w; - infoHeader.xPelsPerMeter= 0; - infoHeader.yPelsPerMeter= 0; - - if(bigEndianSystem == true) { - infoHeader.bitCount = Shared::PlatformByteOrder::toCommonEndian(infoHeader.bitCount); - infoHeader.clrImportant = Shared::PlatformByteOrder::toCommonEndian(infoHeader.clrImportant); - infoHeader.clrUsed = Shared::PlatformByteOrder::toCommonEndian(infoHeader.clrUsed); - infoHeader.compression = Shared::PlatformByteOrder::toCommonEndian(infoHeader.compression); - infoHeader.height = Shared::PlatformByteOrder::toCommonEndian(infoHeader.height); - infoHeader.planes = Shared::PlatformByteOrder::toCommonEndian(infoHeader.planes); - infoHeader.size = Shared::PlatformByteOrder::toCommonEndian(infoHeader.size); - infoHeader.sizeImage = Shared::PlatformByteOrder::toCommonEndian(infoHeader.sizeImage); - infoHeader.width = Shared::PlatformByteOrder::toCommonEndian(infoHeader.width); - infoHeader.xPelsPerMeter = Shared::PlatformByteOrder::toCommonEndian(infoHeader.xPelsPerMeter); - infoHeader.yPelsPerMeter = Shared::PlatformByteOrder::toCommonEndian(infoHeader.yPelsPerMeter); - } - - fwrite(&infoHeader, sizeof(BitmapInfoHeader), 1, file); -} - -void PixmapIoBmp::write(uint8 *pixels) { - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - Shared::PlatformByteOrder::toEndianTypeArray(pixels,h*w*components); - } - - for (int i=0; ipath = path; - this->w= w; - this->h= h; - this->components= components; - -#ifdef WIN32 - file= _wfopen(utf8_decode(path).c_str(), L"wb"); -#else - file= fopen(path.c_str(),"wb"); -#endif - if (file == NULL) { - throw megaglest_runtime_error("Can't open PNG file for writing: "+ path); - } -} - -void PixmapIoPng::write(uint8 *pixels) { - // initialize stuff - png_bytep *imrow = new png_bytep[h]; - //png_bytep *imrow = (png_bytep*) malloc(sizeof(png_bytep) * height); - for(int i = 0; i < h; ++i) { - imrow[i] = pixels + (h-1-i) * w * components; - } - - png_structp imgp = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0); - png_infop infop = png_create_info_struct(imgp); - png_init_io(imgp, file); - - int color_type = PNG_COLOR_TYPE_RGB; - if(components == 4) { - color_type = PNG_COLOR_TYPE_RGBA; - } - png_set_IHDR(imgp, infop, w, h, - 8, color_type, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - - // write file - png_write_info(imgp, infop); - png_write_image(imgp, imrow); - png_write_end(imgp, NULL); - - delete [] imrow; -} - -// ===================================================== -// class PixmapIoJpg -// ===================================================== - -PixmapIoJpg::PixmapIoJpg() { - file= NULL; -} - -PixmapIoJpg::~PixmapIoJpg() { - if(file!=NULL){ - fclose(file); - file=NULL; - } -} - -void PixmapIoJpg::openRead(const string &path) { - throw megaglest_runtime_error("PixmapIoJpg::openRead not implemented!"); -} - -void PixmapIoJpg::read(uint8 *pixels) { - throw megaglest_runtime_error("PixmapIoJpg::read not implemented!"); -} - -void PixmapIoJpg::read(uint8 *pixels, int components) { - - throw megaglest_runtime_error("PixmapIoJpg::read #2 not implemented!"); -} - -void PixmapIoJpg::openWrite(const string &path, int w, int h, int components) { - this->path = path; - this->w= w; - this->h= h; - this->components= components; - -#ifdef WIN32 - file= _wfopen(utf8_decode(path).c_str(), L"wb"); -#else - file= fopen(path.c_str(),"wb"); -#endif - if (file == NULL) { - throw megaglest_runtime_error("Can't open JPG file for writing: "+ path); - } -} - -void PixmapIoJpg::write(uint8 *pixels) { - /* - * alpha channel is not supported for jpeg. strip it. - */ - unsigned char * tmpbytes = NULL; - if(components == 4) { - int n = w * h; - unsigned char *dst = tmpbytes = (unsigned char *) malloc(n*3); - if(dst != NULL) { - const unsigned char *src = pixels; - for (int i = 0; i < n; i++) { - *dst++ = *src++; - *dst++ = *src++; - *dst++ = *src++; - src++; - } - } - components = 3; - } - - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - - /* this is a pointer to one row of image data */ - JSAMPROW row_pointer[1]; - - cinfo.err = jpeg_std_error( &jerr ); - jpeg_create_compress(&cinfo); - jpeg_stdio_dest(&cinfo, file); - - /* Setting the parameters of the output file here */ - cinfo.image_width = w; - cinfo.image_height = h; - cinfo.input_components = 3; // no alpha channel for jpeg - cinfo.in_color_space = JCS_RGB; - /* default compression parameters, we shouldn't be worried about these */ - jpeg_set_defaults( &cinfo ); - /* Now do the compression .. */ - jpeg_start_compress( &cinfo, TRUE ); - - /* use stripped alpha channel bytes */ - if(tmpbytes) { - pixels = tmpbytes; - } - - // OpenGL writes from bottom to top. - // libjpeg goes from top to bottom. - // flip lines. - uint8 *flip = (uint8 *)malloc(sizeof(uint8) * w * h * 3); - - if(pixels != NULL && flip != NULL) { - for (int y = 0;y < h; ++y) { - for (int x = 0;x < w; ++x) { - flip[(y * w + x) * 3] = pixels[((h - 1 - y) * w + x) * 3]; - flip[(y * w + x) * 3 + 1] = pixels[((h - 1 - y) * w + x) * 3 + 1]; - flip[(y * w + x) * 3 + 2] = pixels[((h - 1 - y) * w + x) * 3 + 2]; - } - } - - /* like reading a file, this time write one row at a time */ - while( cinfo.next_scanline < cinfo.image_height ) { - row_pointer[0] = &flip[ cinfo.next_scanline * cinfo.image_width * cinfo.input_components]; - jpeg_write_scanlines( &cinfo, row_pointer, 1 ); - } - } - if (tmpbytes) { - free(tmpbytes); - tmpbytes=NULL; - } - if(flip) { - free(flip); - flip=NULL; - } - - /* similar to read file, clean up after we're done compressing */ - jpeg_finish_compress( &cinfo ); - jpeg_destroy_compress( &cinfo ); - //fclose( outfile ); - /* success code is 1! */ -} - -// ===================================================== -// class Pixmap1D -// ===================================================== - - -// ===================== PUBLIC ======================== - -Pixmap1D::Pixmap1D() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - - w= -1; - components= -1; - pixels= NULL; -} - -Pixmap1D::Pixmap1D(int components) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - - init(components); -} - -Pixmap1D::Pixmap1D(int w, int components) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - - init(w, components); -} - -void Pixmap1D::init(int components){ - this->w= -1; - this->components= components; - pixels= NULL; - CalculatePixelsCRC(pixels,0, crc); -} - -void Pixmap1D::init(int w, int components){ - this->w= w; - this->components= components; - pixels= new uint8[getPixelByteCount()]; - CalculatePixelsCRC(pixels,0, crc); -} - -std::size_t Pixmap1D::getPixelByteCount() const { - return (w * components); -} - -void Pixmap1D::deletePixels() { - delete [] pixels; - pixels = NULL; -} - -Pixmap1D::~Pixmap1D(){ - deletePixels(); -} - -void Pixmap1D::load(const string &path) { - string extension = (path.empty() == false ? path.substr(path.find_last_of('.')+1) : ""); - if(toLower(extension) == "bmp") { - loadBmp(path); - } - else if(toLower(extension) == "tga") { - loadTga(path); - } - else { - throw megaglest_runtime_error("Unknown pixmap extension [" + extension + "] file [" + path + "]"); - } - this->path = path; - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); -} - -void Pixmap1D::loadBmp(const string &path) { - this->path = path; - - PixmapIoBmp plb; - plb.openRead(path); - - //init - if(plb.getH()==1) { - w= plb.getW(); - } - else if(plb.getW()==1) { - w= plb.getH(); - } - else { - throw megaglest_runtime_error("One of the texture dimensions must be 1"); - } - - if(components == -1) { - components= 3; - } - if(pixels == NULL) { - pixels= new uint8[getPixelByteCount()]; - } - - //data - plb.read(pixels, components); -} - -void Pixmap1D::loadTga(const string &path) { - this->path = path; - - PixmapIoTga plt; - plt.openRead(path); - - //init - if(plt.getH()==1) { - w= plt.getW(); - } - else if(plt.getW()==1) { - w= plt.getH(); - } - else { - throw megaglest_runtime_error("One of the texture dimensions must be 1"); - } - - int fileComponents= plt.getComponents(); - - if(components == -1) { - components= fileComponents; - } - if(pixels == NULL) { - pixels= new uint8[getPixelByteCount()]; - } - - //read data - plt.read(pixels, components); -} - -// ===================================================== -// class Pixmap2D -// ===================================================== - -// ===================== PUBLIC ======================== - -Pixmap2D::Pixmap2D() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - h= -1; - w= -1; - components= -1; - pixels= NULL; -} - -Pixmap2D::Pixmap2D(int components) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - h= -1; - w= -1; - this->components= -1; - pixels= NULL; - - init(components); -} - -Pixmap2D::Pixmap2D(int w, int h, int components) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - this->h= 0; - this->w= -1; - this->components= -1; - pixels= NULL; - - init(w, h, components); -} - -void Pixmap2D::init(int components) { - this->w= -1; - this->h= -1; - this->components= components; - deletePixels(); - pixels= NULL; - CalculatePixelsCRC(pixels,0, crc); -} - -void Pixmap2D::init(int w, int h, int components) { - this->w= w; - this->h= h; - this->components= components; - deletePixels(); - - if(getPixelByteCount() <= 0 || (h <= 0 || w <= 0 || components <= 0)) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap dimensions for [%s], h = %d, w = %d, components = %d\n",path.c_str(),h,w,components); - throw megaglest_runtime_error(szBuf); - } - pixels= new uint8[getPixelByteCount()]; - CalculatePixelsCRC(pixels,0, crc); -} - -std::size_t Pixmap2D::getPixelByteCount() const { - return (h * w * components); -} - -void Pixmap2D::deletePixels() { - if(pixels) { - delete [] pixels; - pixels = NULL; - } -} - -Pixmap2D::~Pixmap2D() { - deletePixels(); -} - -void Pixmap2D::Scale(int format, int newW, int newH) { - int useComponents = this->getComponents(); - int originalW = w; - int originalH = h; - uint8 *newpixels= new uint8[newW * newH * useComponents]; - - glPixelStorei(GL_PACK_ALIGNMENT, 1); - GLenum glErr = gluScaleImage( format, + void Pixmap2D::Scale(int format, int newW, int newH) { + int useComponents = this->getComponents(); + int originalW = w; + int originalH = h; + uint8 *newpixels = new uint8[newW * newH * useComponents]; + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + GLenum glErr = gluScaleImage(format, w, h, GL_UNSIGNED_BYTE, pixels, newW, newH, GL_UNSIGNED_BYTE, newpixels); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - if(glErr == GL_NO_ERROR) { - init(newW,newH,this->components); - pixels = newpixels; + if (glErr == GL_NO_ERROR) { + init(newW, newH, this->components); + pixels = newpixels; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Scaled image from [%d x %d] to [%d x %d]\n",originalW,originalH,w,h); - } - else { - const char *errorString= reinterpret_cast(gluErrorString(glErr)); - printf("ERROR Scaling image from [%d x %d] to [%d x %d] error: %u [%s]\n",originalW,originalH,w,h,glErr,errorString); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Scaled image from [%d x %d] to [%d x %d]\n", originalW, originalH, w, h); + } else { + const char *errorString = reinterpret_cast(gluErrorString(glErr)); + printf("ERROR Scaling image from [%d x %d] to [%d x %d] error: %u [%s]\n", originalW, originalH, w, h, glErr, errorString); - assertGlWithErrorNumber(glErr); - } + assertGlWithErrorNumber(glErr); + } - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); -} - -Pixmap2D* Pixmap2D::loadPath(const string& path) { - //printf("Loading Pixmap2D [%s]\n",path.c_str()); - - Pixmap2D *pixmap = FileReader::readPath(path); - if(pixmap != NULL) { - pixmap->path = path; - CalculatePixelsCRC(pixmap->pixels,pixmap->getPixelByteCount(), pixmap->crc); - } - return pixmap; -} - -void Pixmap2D::load(const string &path) { - //printf("Loading Pixmap2D [%s]\n",path.c_str()); - - FileReader::readPath(path,this); - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); - this->path = path; -} - -void Pixmap2D::save(const string &path) { - string extension = (path.empty() == false ? path.substr(path.find_last_of('.')+1) : ""); - if(toLower(extension) == "bmp") { - saveBmp(path); - } - else if(toLower(extension) == "tga") { - saveTga(path); - } - else if(toLower(extension) == "jpg") { - saveJpg(path); - } - else if(toLower(extension) == "png") { - savePng(path); - } - else { - throw megaglest_runtime_error("Unknown pixmap extension [" + extension + "] file [" + path + "]"); - } -} - -void Pixmap2D::saveBmp(const string &path) { - PixmapIoBmp psb; - psb.openWrite(path, w, h, components); - psb.write(pixels); -} - -void Pixmap2D::saveTga(const string &path) { - PixmapIoTga pst; - pst.openWrite(path, w, h, components); - pst.write(pixels); -} - -void Pixmap2D::saveJpg(const string &path) { - PixmapIoJpg pst; - pst.openWrite(path, w, h, components); - pst.write(pixels); -} - -void Pixmap2D::savePng(const string &path) { - PixmapIoPng pst; - pst.openWrite(path, w, h, components); - pst.write(pixels); -} - -void Pixmap2D::getPixel(int x, int y, uint8 *value) const { - for(int i=0; i= getPixelByteCount()) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",index,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); } - value[i]= pixels[index]; - } -} + Pixmap2D* Pixmap2D::loadPath(const string& path) { + //printf("Loading Pixmap2D [%s]\n",path.c_str()); -void Pixmap2D::getPixel(int x, int y, float32 *value) const { - for(int i = 0; i < components; ++i) { - std::size_t index = (w * y + x) * components + i; - if(index >= getPixelByteCount()) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",index,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); + Pixmap2D *pixmap = FileReader::readPath(path); + if (pixmap != NULL) { + pixmap->path = path; + CalculatePixelsCRC(pixmap->pixels, pixmap->getPixelByteCount(), pixmap->crc); + } + return pixmap; } - value[i] = pixels[index] / 255.f; - } -} + void Pixmap2D::load(const string &path) { + //printf("Loading Pixmap2D [%s]\n",path.c_str()); -void Pixmap2D::getComponent(int x, int y, int component, uint8 &value) const { - std::size_t index = (w*y+x)*components+component; - if(index >= getPixelByteCount()) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",index,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); - } - - value = pixels[index]; -} - -void Pixmap2D::getComponent(int x, int y, int component, float32 &value) const { - std::size_t index = (w*y+x)*components+component; - if(index >= getPixelByteCount()) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",index,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); - } - - value= pixels[index] / 255.f; -} - -//vector get -Vec4f Pixmap2D::getPixel4f(int x, int y) const { - Vec4f v(0.f); - for(int i=0; i= getPixelByteCount()) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",index,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); + FileReader::readPath(path, this); + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + this->path = path; } - v.ptr()[i]= pixels[index] / 255.f; - } - return v; -} - -Vec3f Pixmap2D::getPixel3f(int x, int y) const { - Vec3f v(0.f); - for(int i=0; i= getPixelByteCount()) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",index,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); + void Pixmap2D::save(const string &path) { + string extension = (path.empty() == false ? path.substr(path.find_last_of('.') + 1) : ""); + if (toLower(extension) == "bmp") { + saveBmp(path); + } else if (toLower(extension) == "tga") { + saveTga(path); + } else if (toLower(extension) == "jpg") { + saveJpg(path); + } else if (toLower(extension) == "png") { + savePng(path); + } else { + throw megaglest_runtime_error("Unknown pixmap extension [" + extension + "] file [" + path + "]"); + } } - v.ptr()[i]= pixels[index] / 255.f; - } - return v; -} - -float Pixmap2D::getPixelf(int x, int y) const { - std::size_t index = (w * y + x) * components; - if(index >= getPixelByteCount()) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",index,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); - } - float result = pixels[index] / 255.f; - return truncateDecimal(result,6); -} - -float Pixmap2D::getComponentf(int x, int y, int component) const { - float c=0; - getComponent(x, y, component, c); - return c; -} - -void Pixmap2D::setPixel(int x, int y, const uint8 *value, int arraySize) { - if(arraySize > components) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap arraySize: %d for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",arraySize,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); - } - for(int i = 0; i < components; ++i) { - std::size_t index = (w * y + x) * components + i; - if(index >= getPixelByteCount()) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",index,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); + void Pixmap2D::saveBmp(const string &path) { + PixmapIoBmp psb; + psb.openWrite(path, w, h, components); + psb.write(pixels); } - pixels[index]= value[i]; - } - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); -} - -void Pixmap2D::setPixel(int x, int y, const float32 *value, int arraySize) { - if(arraySize > components) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap arraySize: %d for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",arraySize,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); - } - - for(int i = 0; i < components; ++i) { - std::size_t index = (w*y+x)*components+i; - if(index >= getPixelByteCount()) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",index,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); + void Pixmap2D::saveTga(const string &path) { + PixmapIoTga pst; + pst.openWrite(path, w, h, components); + pst.write(pixels); } - pixels[index] = static_cast(value[i] * 255.f); - } - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); -} -void Pixmap2D::setComponent(int x, int y, int component, uint8 value) { - std::size_t index = (w*y+x)*components+component; - if(index >= getPixelByteCount()) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",index,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); - } - - pixels[index] = value; - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); -} - -void Pixmap2D::setComponent(int x, int y, int component, float32 value) { - std::size_t index = (w*y+x)*components+component; - if(index >= getPixelByteCount()) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",index,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); - } - - pixels[index] = static_cast(value * 255.f); - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); -} - -//vector set -void Pixmap2D::setPixel(int x, int y, const Vec3f &p) { - for(int i = 0; i < components && i < 3; ++i) { - std::size_t index = (w*y+x)*components+i; - if(index >= getPixelByteCount()) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",index,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); + void Pixmap2D::saveJpg(const string &path) { + PixmapIoJpg pst; + pst.openWrite(path, w, h, components); + pst.write(pixels); } - pixels[index] = static_cast(p.ptr()[i] * 255.f); - } - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); -} -void Pixmap2D::setPixel(int x, int y, const Vec4f &p) { - for(int i = 0; i < components && i < 4; ++i) { - std::size_t index = (w*y+x)*components+i; - if(index >= getPixelByteCount()) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",index,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); + void Pixmap2D::savePng(const string &path) { + PixmapIoPng pst; + pst.openWrite(path, w, h, components); + pst.write(pixels); } - pixels[index] = static_cast(p.ptr()[i] * 255.f); - } - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); -} -void Pixmap2D::setPixel(int x, int y, float p) { - std::size_t index = (w * y + x) * components; - if(index >= getPixelByteCount()) { - char szBuf[8096]; - snprintf(szBuf,8096,"Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n",index,path.c_str(),h,w,components,x,y); - throw megaglest_runtime_error(szBuf); - } + void Pixmap2D::getPixel(int x, int y, uint8 *value) const { + for (int i = 0; i < components; ++i) { + std::size_t index = (w*y + x)*components + i; + if (index >= getPixelByteCount()) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", index, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } - pixels[index] = static_cast(p * 255.f); - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); -} - -void Pixmap2D::setPixels(const uint8 *value, int arraySize) { - for(int i = 0; i < w; ++i) { - for(int j = 0; j < h; ++j) { - setPixel(i, j, value, arraySize); + value[i] = pixels[index]; + } } - } - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); -} -void Pixmap2D::setPixels(const float32 *value, int arraySize) { - for(int i = 0; i < w; ++i) { - for(int j = 0; j < h; ++j) { - setPixel(i, j, value, arraySize); + void Pixmap2D::getPixel(int x, int y, float32 *value) const { + for (int i = 0; i < components; ++i) { + std::size_t index = (w * y + x) * components + i; + if (index >= getPixelByteCount()) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", index, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } + + value[i] = pixels[index] / 255.f; + } } - } - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); -} -void Pixmap2D::setComponents(int component, uint8 value){ - assert(component= getPixelByteCount()) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", index, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } + + value = pixels[index]; } - } - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); -} -void Pixmap2D::setComponents(int component, float32 value){ - assert(component= getPixelByteCount()) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", index, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } + + value = pixels[index] / 255.f; } - } - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); -} -float splatDist(Vec2i a, Vec2i b){ - return (max(abs(a.x-b.x),abs(a.y- b.y)) + 3.f*a.dist(b))/4.f; -} + //vector get + Vec4f Pixmap2D::getPixel4f(int x, int y) const { + Vec4f v(0.f); + for (int i = 0; i < components && i < 4; ++i) { + std::size_t index = (w*y + x)*components + i; + if (index >= getPixelByteCount()) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", index, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } -void Pixmap2D::splat(const Pixmap2D *leftUp, const Pixmap2D *rightUp, const Pixmap2D *leftDown, const Pixmap2D *rightDown){ - - RandomGen random; - - assert(components==3 || components==4); - - if( - !doDimensionsAgree(leftUp) || - !doDimensionsAgree(rightUp) || - !doDimensionsAgree(leftDown) || - !doDimensionsAgree(rightDown)) - { - throw megaglest_runtime_error("Pixmap2D::splat: pixmap dimensions don't agree"); - } - - for(int i=0; iavg? 0: ((avg-distLu))*random.randRange(0.5f, 1.0f); - float ru= distRu>avg? 0: ((avg-distRu))*random.randRange(0.5f, 1.0f); - float ld= distLd>avg? 0: ((avg-distLd))*random.randRange(0.5f, 1.0f); - float rd= distRd>avg? 0: ((avg-distRd))*random.randRange(0.5f, 1.0f); - - float total= lu+ru+ld+rd; - - Vec4f pix= (leftUp->getPixel4f(i, j)*lu+ - rightUp->getPixel4f(i, j)*ru+ - leftDown->getPixel4f(i, j)*ld+ - rightDown->getPixel4f(i, j)*rd)*(1.0f/total); - - setPixel(i, j, pix); + v.ptr()[i] = pixels[index] / 255.f; + } + return v; } - } -} -void Pixmap2D::lerp(float t, const Pixmap2D *pixmap1, const Pixmap2D *pixmap2){ - if( - !doDimensionsAgree(pixmap1) || - !doDimensionsAgree(pixmap2)) - { - throw megaglest_runtime_error("Pixmap2D::lerp: pixmap dimensions don't agree"); - } + Vec3f Pixmap2D::getPixel3f(int x, int y) const { + Vec3f v(0.f); + for (int i = 0; i < components && i < 3; ++i) { + std::size_t index = (w*y + x)*components + i; + if (index >= getPixelByteCount()) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", index, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } - for(int i=0; igetPixel4f(i, j).lerp(t, pixmap2->getPixel4f(i, j))); + v.ptr()[i] = pixels[index] / 255.f; + } + return v; } - } -} -void Pixmap2D::copy(const Pixmap2D *sourcePixmap){ - - assert(components==sourcePixmap->getComponents()); - - if(w!=sourcePixmap->getW() || h!=sourcePixmap->getH()){ - throw megaglest_runtime_error("Pixmap2D::copy() dimensions must agree"); - } - memcpy(pixels, sourcePixmap->getPixels(), w*h*sourcePixmap->getComponents()); - this->path = sourcePixmap->path; - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); -} - -void Pixmap2D::subCopy(int x, int y, const Pixmap2D *sourcePixmap){ - assert(components==sourcePixmap->getComponents()); - - if(wgetW() && hgetH()){ - throw megaglest_runtime_error("Pixmap2D::subCopy(), bad dimensions"); - } - - uint8 *pixel= new uint8[components]; - - for(int i = 0; i < sourcePixmap->getW(); ++i) { - for(int j = 0; j < sourcePixmap->getH(); ++j) { - sourcePixmap->getPixel(i, j, pixel); - setPixel(i+x, j+y, pixel, components); + float Pixmap2D::getPixelf(int x, int y) const { + std::size_t index = (w * y + x) * components; + if (index >= getPixelByteCount()) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", index, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } + float result = pixels[index] / 255.f; + return truncateDecimal(result, 6); } - } - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); - delete [] pixel; -} - -// uses a a part of a bigger source image to fill this image. -void Pixmap2D::copyImagePart(int x, int y, const Pixmap2D *sourcePixmap){ - assert(components==sourcePixmap->getComponents()); - - if(x+w>sourcePixmap->getW() && y+h>sourcePixmap->getH()){ - throw megaglest_runtime_error("Pixmap2D::copyImagePart(), bad dimensions"); - } - - uint8 *pixel= new uint8[components]; - - for(int i = x; i < x + w; ++i) { - for(int j = y; j < y + h; ++j) { - sourcePixmap->getPixel(i, j, pixel); - setPixel(i-x, j-y, pixel, components); + float Pixmap2D::getComponentf(int x, int y, int component) const { + float c = 0; + getComponent(x, y, component, c); + return c; } + + void Pixmap2D::setPixel(int x, int y, const uint8 *value, int arraySize) { + if (arraySize > components) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap arraySize: %d for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", arraySize, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } + for (int i = 0; i < components; ++i) { + std::size_t index = (w * y + x) * components + i; + if (index >= getPixelByteCount()) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", index, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } + + pixels[index] = value[i]; + } + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + } + + void Pixmap2D::setPixel(int x, int y, const float32 *value, int arraySize) { + if (arraySize > components) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap arraySize: %d for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", arraySize, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } + + for (int i = 0; i < components; ++i) { + std::size_t index = (w*y + x)*components + i; + if (index >= getPixelByteCount()) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", index, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } + pixels[index] = static_cast(value[i] * 255.f); + } + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + } + + void Pixmap2D::setComponent(int x, int y, int component, uint8 value) { + std::size_t index = (w*y + x)*components + component; + if (index >= getPixelByteCount()) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", index, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } + + pixels[index] = value; + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + } + + void Pixmap2D::setComponent(int x, int y, int component, float32 value) { + std::size_t index = (w*y + x)*components + component; + if (index >= getPixelByteCount()) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", index, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } + + pixels[index] = static_cast(value * 255.f); + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + } + + //vector set + void Pixmap2D::setPixel(int x, int y, const Vec3f &p) { + for (int i = 0; i < components && i < 3; ++i) { + std::size_t index = (w*y + x)*components + i; + if (index >= getPixelByteCount()) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", index, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } + pixels[index] = static_cast(p.ptr()[i] * 255.f); + } + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + } + + void Pixmap2D::setPixel(int x, int y, const Vec4f &p) { + for (int i = 0; i < components && i < 4; ++i) { + std::size_t index = (w*y + x)*components + i; + if (index >= getPixelByteCount()) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", index, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } + pixels[index] = static_cast(p.ptr()[i] * 255.f); + } + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + } + + void Pixmap2D::setPixel(int x, int y, float p) { + std::size_t index = (w * y + x) * components; + if (index >= getPixelByteCount()) { + char szBuf[8096]; + snprintf(szBuf, 8096, "Invalid pixmap index: " MG_SIZE_T_SPECIFIER " for [%s], h = %d, w = %d, components = %d x = %d y = %d\n", index, path.c_str(), h, w, components, x, y); + throw megaglest_runtime_error(szBuf); + } + + pixels[index] = static_cast(p * 255.f); + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + } + + void Pixmap2D::setPixels(const uint8 *value, int arraySize) { + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + setPixel(i, j, value, arraySize); + } + } + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + } + + void Pixmap2D::setPixels(const float32 *value, int arraySize) { + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + setPixel(i, j, value, arraySize); + } + } + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + } + + void Pixmap2D::setComponents(int component, uint8 value) { + assert(component < components); + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + setComponent(i, j, component, value); + } + } + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + } + + void Pixmap2D::setComponents(int component, float32 value) { + assert(component < components); + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + setComponent(i, j, component, value); + } + } + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + } + + float splatDist(Vec2i a, Vec2i b) { + return (max(abs(a.x - b.x), abs(a.y - b.y)) + 3.f*a.dist(b)) / 4.f; + } + + void Pixmap2D::splat(const Pixmap2D *leftUp, const Pixmap2D *rightUp, const Pixmap2D *leftDown, const Pixmap2D *rightDown) { + + RandomGen random; + + assert(components == 3 || components == 4); + + if ( + !doDimensionsAgree(leftUp) || + !doDimensionsAgree(rightUp) || + !doDimensionsAgree(leftDown) || + !doDimensionsAgree(rightDown)) { + throw megaglest_runtime_error("Pixmap2D::splat: pixmap dimensions don't agree"); + } + + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + + float avg = (w + h) / 2.f; + + float distLu = splatDist(Vec2i(i, j), Vec2i(0, 0)); + float distRu = splatDist(Vec2i(i, j), Vec2i(w, 0)); + float distLd = splatDist(Vec2i(i, j), Vec2i(0, h)); + float distRd = splatDist(Vec2i(i, j), Vec2i(w, h)); + + const float powFactor = 2.0f; + + distLu = std::pow(distLu, powFactor); + distRu = std::pow(distRu, powFactor); + distLd = std::pow(distLd, powFactor); + distRd = std::pow(distRd, powFactor); + avg = std::pow(avg, powFactor); + + float lu = distLu > avg ? 0 : ((avg - distLu))*random.randRange(0.5f, 1.0f); + float ru = distRu > avg ? 0 : ((avg - distRu))*random.randRange(0.5f, 1.0f); + float ld = distLd > avg ? 0 : ((avg - distLd))*random.randRange(0.5f, 1.0f); + float rd = distRd > avg ? 0 : ((avg - distRd))*random.randRange(0.5f, 1.0f); + + float total = lu + ru + ld + rd; + + Vec4f pix = (leftUp->getPixel4f(i, j)*lu + + rightUp->getPixel4f(i, j)*ru + + leftDown->getPixel4f(i, j)*ld + + rightDown->getPixel4f(i, j)*rd)*(1.0f / total); + + setPixel(i, j, pix); + } + } + } + + void Pixmap2D::lerp(float t, const Pixmap2D *pixmap1, const Pixmap2D *pixmap2) { + if ( + !doDimensionsAgree(pixmap1) || + !doDimensionsAgree(pixmap2)) { + throw megaglest_runtime_error("Pixmap2D::lerp: pixmap dimensions don't agree"); + } + + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + setPixel(i, j, pixmap1->getPixel4f(i, j).lerp(t, pixmap2->getPixel4f(i, j))); + } + } + } + + void Pixmap2D::copy(const Pixmap2D *sourcePixmap) { + + assert(components == sourcePixmap->getComponents()); + + if (w != sourcePixmap->getW() || h != sourcePixmap->getH()) { + throw megaglest_runtime_error("Pixmap2D::copy() dimensions must agree"); + } + memcpy(pixels, sourcePixmap->getPixels(), w*h*sourcePixmap->getComponents()); + this->path = sourcePixmap->path; + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + } + + void Pixmap2D::subCopy(int x, int y, const Pixmap2D *sourcePixmap) { + assert(components == sourcePixmap->getComponents()); + + if (w < sourcePixmap->getW() && h < sourcePixmap->getH()) { + throw megaglest_runtime_error("Pixmap2D::subCopy(), bad dimensions"); + } + + uint8 *pixel = new uint8[components]; + + for (int i = 0; i < sourcePixmap->getW(); ++i) { + for (int j = 0; j < sourcePixmap->getH(); ++j) { + sourcePixmap->getPixel(i, j, pixel); + setPixel(i + x, j + y, pixel, components); + } + } + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + + delete[] pixel; + } + + // uses a a part of a bigger source image to fill this image. + void Pixmap2D::copyImagePart(int x, int y, const Pixmap2D *sourcePixmap) { + assert(components == sourcePixmap->getComponents()); + + if (x + w > sourcePixmap->getW() && y + h > sourcePixmap->getH()) { + throw megaglest_runtime_error("Pixmap2D::copyImagePart(), bad dimensions"); + } + + uint8 *pixel = new uint8[components]; + + for (int i = x; i < x + w; ++i) { + for (int j = y; j < y + h; ++j) { + sourcePixmap->getPixel(i, j, pixel); + setPixel(i - x, j - y, pixel, components); + } + } + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + + delete[] pixel; + } + + bool Pixmap2D::doDimensionsAgree(const Pixmap2D *pixmap) { + return pixmap->getW() == w && pixmap->getH() == h; + } + + // ===================================================== + // class Pixmap3D + // ===================================================== + + Pixmap3D::Pixmap3D() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + + + w = -1; + h = -1; + d = -1; + components = -1; + pixels = NULL; + slice = 0; + } + + Pixmap3D::Pixmap3D(int w, int h, int d, int components) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + + pixels = NULL; + slice = 0; + init(w, h, d, components); + } + + Pixmap3D::Pixmap3D(int d, int components) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + + pixels = NULL; + slice = 0; + init(d, components); + } + + void Pixmap3D::init(int w, int h, int d, int components) { + this->w = w; + this->h = h; + this->d = d; + this->components = components; + pixels = new uint8[getPixelByteCount()]; + CalculatePixelsCRC(pixels, 0, crc); + } + + std::size_t Pixmap3D::getPixelByteCount() const { + return (h * w * d * components); + } + + void Pixmap3D::init(int d, int components) { + this->w = -1; + this->h = -1; + this->d = d; + this->components = components; + pixels = NULL; + CalculatePixelsCRC(pixels, 0, crc); + } + + void Pixmap3D::init(int components) { + this->w = -1; + this->h = -1; + this->d = -1; + this->components = components; + pixels = NULL; + CalculatePixelsCRC(pixels, 0, crc); + } + + void Pixmap3D::deletePixels() { + delete[] pixels; + pixels = NULL; + } + + Pixmap3D::~Pixmap3D() { + deletePixels(); + } + + void Pixmap3D::loadSlice(const string &path, int slice) { + this->slice = slice; + string extension = (path.empty() == false ? path.substr(path.find_last_of('.') + 1) : ""); + if (toLower(extension) == "png") { + loadSlicePng(path, slice); + } else if (toLower(extension) == "bmp") { + loadSliceBmp(path, slice); + } else if (toLower(extension) == "tga") { + loadSliceTga(path, slice); + } else { + throw megaglest_runtime_error("Unknown pixmap extension [" + extension + "] file [" + path + "]"); + } + this->path = path; + CalculatePixelsCRC(pixels, getPixelByteCount(), crc); + } + + void Pixmap3D::loadSlicePng(const string &path, int slice) { + this->path = path; + + //deletePixels(); + //Pixmap3D *pixmap = FileReader::readPath(path,this); + FileReader::readPath(path, this); + //printf("Loading 3D pixmap PNG [%s] pixmap [%p] this [%p]\n",path.c_str(),pixmap, this); + } + + void Pixmap3D::loadSliceBmp(const string &path, int slice) { + this->path = path; + + PixmapIoBmp plb; + plb.openRead(path); + + //init + w = plb.getW(); + h = plb.getH(); + if (components == -1) { + components = 3; + } + if (pixels == NULL) { + pixels = new uint8[getPixelByteCount()]; + } + + //data + plb.read(&pixels[slice*w*h*components], components); + } + + void Pixmap3D::loadSliceTga(const string &path, int slice) { + this->path = path; + + //deletePixels(); + FileReader::readPath(path, this); + //printf("Loading 3D pixmap TGA [%s] this [%p]\n",path.c_str(),this); + } + + // ===================================================== + // class PixmapCube + // ===================================================== + PixmapCube::PixmapCube() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + + } + + PixmapCube::~PixmapCube() { + + } + + void PixmapCube::init(int w, int h, int components) { + for (int i = 0; i < 6; ++i) { + faces[i].init(w, h, components); + } + } + + void PixmapCube::init(int components) { + for (int i = 0; i < 6; ++i) { + faces[i].init(components); + } + } + + std::size_t PixmapCube::getPixelByteCount() const { + std::size_t result = 0; + for (int i = 0; i < 6; ++i) { + result += faces[i].getPixelByteCount(); + } + + return result; + } + + //load & save + void PixmapCube::loadFace(const string &path, int face) { + this->path[face] = path; + + faces[face].load(path); + } + + void PixmapCube::deletePixels() { + for (int i = 0; i < 6; ++i) { + faces[i].deletePixels(); + } + } + + } - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); - - delete [] pixel; -} - -bool Pixmap2D::doDimensionsAgree(const Pixmap2D *pixmap){ - return pixmap->getW() == w && pixmap->getH() == h; -} - -// ===================================================== -// class Pixmap3D -// ===================================================== - -Pixmap3D::Pixmap3D() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - - w= -1; - h= -1; - d= -1; - components= -1; - pixels = NULL; - slice=0; -} - -Pixmap3D::Pixmap3D(int w, int h, int d, int components) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - pixels = NULL; - slice=0; - init(w, h, d, components); -} - -Pixmap3D::Pixmap3D(int d, int components) { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - pixels = NULL; - slice=0; - init(d, components); -} - -void Pixmap3D::init(int w, int h, int d, int components){ - this->w= w; - this->h= h; - this->d= d; - this->components= components; - pixels= new uint8[getPixelByteCount()]; - CalculatePixelsCRC(pixels,0, crc); -} - -std::size_t Pixmap3D::getPixelByteCount() const { - return (h * w * d * components); -} - -void Pixmap3D::init(int d, int components){ - this->w= -1; - this->h= -1; - this->d= d; - this->components= components; - pixels= NULL; - CalculatePixelsCRC(pixels,0, crc); -} - -void Pixmap3D::init(int components) { - this->w= -1; - this->h= -1; - this->d= -1; - this->components= components; - pixels= NULL; - CalculatePixelsCRC(pixels,0, crc); -} - -void Pixmap3D::deletePixels() { - delete [] pixels; - pixels = NULL; -} - -Pixmap3D::~Pixmap3D() { - deletePixels(); -} - -void Pixmap3D::loadSlice(const string &path, int slice) { - this->slice = slice; - string extension = (path.empty() == false ? path.substr(path.find_last_of('.') + 1) : ""); - if(toLower(extension) == "png") { - loadSlicePng(path, slice); - } - else if(toLower(extension) == "bmp") { - loadSliceBmp(path, slice); - } - else if(toLower(extension) == "tga") { - loadSliceTga(path, slice); - } - else { - throw megaglest_runtime_error("Unknown pixmap extension [" + extension + "] file [" + path + "]"); - } - this->path = path; - CalculatePixelsCRC(pixels,getPixelByteCount(), crc); -} - -void Pixmap3D::loadSlicePng(const string &path, int slice) { - this->path = path; - - //deletePixels(); - //Pixmap3D *pixmap = FileReader::readPath(path,this); - FileReader::readPath(path,this); - //printf("Loading 3D pixmap PNG [%s] pixmap [%p] this [%p]\n",path.c_str(),pixmap, this); -} - -void Pixmap3D::loadSliceBmp(const string &path, int slice){ - this->path = path; - - PixmapIoBmp plb; - plb.openRead(path); - - //init - w= plb.getW(); - h= plb.getH(); - if(components==-1){ - components= 3; - } - if(pixels==NULL){ - pixels= new uint8[getPixelByteCount()]; - } - - //data - plb.read(&pixels[slice*w*h*components], components); -} - -void Pixmap3D::loadSliceTga(const string &path, int slice){ - this->path = path; - - //deletePixels(); - FileReader::readPath(path,this); - //printf("Loading 3D pixmap TGA [%s] this [%p]\n",path.c_str(),this); -} - -// ===================================================== -// class PixmapCube -// ===================================================== -PixmapCube::PixmapCube() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - -} - -PixmapCube::~PixmapCube() { - -} - -void PixmapCube::init(int w, int h, int components) { - for(int i=0; i<6; ++i) { - faces[i].init(w, h, components); - } -} - -void PixmapCube::init(int components) { - for(int i=0; i<6; ++i) { - faces[i].init(components); - } -} - -std::size_t PixmapCube::getPixelByteCount() const { - std::size_t result = 0; - for(int i=0; i<6; ++i) { - result += faces[i].getPixelByteCount(); - } - - return result; -} - -//load & save -void PixmapCube::loadFace(const string &path, int face) { - this->path[face] = path; - - faces[face].load(path); -} - -void PixmapCube::deletePixels() { - for(int i=0; i<6; ++i){ - faces[i].deletePixels(); - } -} - - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/graphics/quaternion.cpp b/source/shared_lib/sources/graphics/quaternion.cpp index 998739779..da35bfa97 100644 --- a/source/shared_lib/sources/graphics/quaternion.cpp +++ b/source/shared_lib/sources/graphics/quaternion.cpp @@ -14,176 +14,178 @@ #include "leak_dumper.h" -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class AxisAngle -// ===================================================== + // ===================================================== + // class AxisAngle + // ===================================================== -AxisAngle::AxisAngle(const Vec3f &axis, float angle){ - this->axis= axis; - this->angle= angle; -} + AxisAngle::AxisAngle(const Vec3f &axis, float angle) { + this->axis = axis; + this->angle = angle; + } -// ===================================================== -// class EulerAngles -// ===================================================== + // ===================================================== + // class EulerAngles + // ===================================================== -EulerAngles::EulerAngles(float x, float y, float z){ - this->x= x; - this->y= y; - this->z= z; -} + EulerAngles::EulerAngles(float x, float y, float z) { + this->x = x; + this->y = y; + this->z = z; + } -// ===================================================== -// class Quaternion -// ===================================================== + // ===================================================== + // class Quaternion + // ===================================================== -Quaternion::Quaternion(){ - setMultIdentity(); -} + Quaternion::Quaternion() { + setMultIdentity(); + } -Quaternion::Quaternion(float w, const Vec3f &v){ - this->w= w; - this->v= v; -} + Quaternion::Quaternion(float w, const Vec3f &v) { + this->w = w; + this->v = v; + } -Quaternion::Quaternion(const EulerAngles &eulerAngles){ - setEuler(eulerAngles); -} + Quaternion::Quaternion(const EulerAngles &eulerAngles) { + setEuler(eulerAngles); + } -//Quaternion::Quaternion(const AxisAngle &axisAngle){ -// setAxisAngle(axisAngle); -//} + //Quaternion::Quaternion(const AxisAngle &axisAngle){ + // setAxisAngle(axisAngle); + //} -void Quaternion::setMultIdentity(){ - w= 1.0f; - v= Vec3f(0.0f); -} + void Quaternion::setMultIdentity() { + w = 1.0f; + v = Vec3f(0.0f); + } -void Quaternion::setAddIdentity(){ - w= 0.0f; - v= Vec3f(0.0f); -} + void Quaternion::setAddIdentity() { + w = 0.0f; + v = Vec3f(0.0f); + } -void Quaternion::setEuler(const EulerAngles &eulerAngles){ - Quaternion qx, qy, qz, qr; + void Quaternion::setEuler(const EulerAngles &eulerAngles) { + Quaternion qx, qy, qz, qr; - qx.w= std::cos(eulerAngles.x/2.0f); - qx.v= Vec3f(std::sin(eulerAngles.x/2.0f), 0.0f, 0.0f); + qx.w = std::cos(eulerAngles.x / 2.0f); + qx.v = Vec3f(std::sin(eulerAngles.x / 2.0f), 0.0f, 0.0f); - qy.w= std::cos(eulerAngles.y/2.0f); - qy.v= Vec3f(0.0f, std::sin(eulerAngles.y/2.0f), 0.0f); + qy.w = std::cos(eulerAngles.y / 2.0f); + qy.v = Vec3f(0.0f, std::sin(eulerAngles.y / 2.0f), 0.0f); - qz.w= std::cos(eulerAngles.z/2.0f); - qz.v= Vec3f(0.0f, 0.0f, std::sin(eulerAngles.z/2.0f)); - - qr= qx*qy*qz; + qz.w = std::cos(eulerAngles.z / 2.0f); + qz.v = Vec3f(0.0f, 0.0f, std::sin(eulerAngles.z / 2.0f)); - w= qr.w; - v= qr.v; -} + qr = qx*qy*qz; -Quaternion Quaternion::conjugate(){ - return Quaternion(w, -v); -} + w = qr.w; + v = qr.v; + } -Quaternion Quaternion::operator + (const Quaternion &q) const{ - return Quaternion(w +q.w, v+q.v); -} -Quaternion Quaternion::operator * (const Quaternion &q) const{ - return Quaternion( - w*q.w - v.x*q.v.x - v.y*q.v.y - v.z*q.v.z, - Vec3f( - w*q.v.x + v.x*q.w + v.y*q.v.z - v.z*q.v.y, - w*q.v.y + v.y*q.w + v.z*q.v.x - v.x*q.v.z, - w*q.v.z + v.z*q.w + v.x*q.v.y - v.y*q.v.x)); -} + Quaternion Quaternion::conjugate() { + return Quaternion(w, -v); + } -void Quaternion::operator += (const Quaternion &q){ - *this= *this + q; -} + Quaternion Quaternion::operator + (const Quaternion &q) const { + return Quaternion(w + q.w, v + q.v); + } + Quaternion Quaternion::operator * (const Quaternion &q) const { + return Quaternion( + w*q.w - v.x*q.v.x - v.y*q.v.y - v.z*q.v.z, + Vec3f( + w*q.v.x + v.x*q.w + v.y*q.v.z - v.z*q.v.y, + w*q.v.y + v.y*q.w + v.z*q.v.x - v.x*q.v.z, + w*q.v.z + v.z*q.w + v.x*q.v.y - v.y*q.v.x)); + } -void Quaternion::operator *= (const Quaternion &q){ - *this= *this * q; -} + void Quaternion::operator += (const Quaternion &q) { + *this = *this + q; + } -Quaternion Quaternion::lerp(float t, const Quaternion &q) const{ - return Quaternion( - w * (1.0f-t) + q.w * t, - v * (1.0f-t) + q.v * t); -} + void Quaternion::operator *= (const Quaternion &q) { + *this = *this * q; + } -Matrix3f Quaternion::toMatrix3() const{ - Matrix3f rm; + Quaternion Quaternion::lerp(float t, const Quaternion &q) const { + return Quaternion( + w * (1.0f - t) + q.w * t, + v * (1.0f - t) + q.v * t); + } - //row1 - rm[0]= 1.0f - 2*v.y*v.y - 2*v.z*v.z; - rm[3]= 2*v.x*v.y - 2*w*v.z; - rm[6]= 2*v.x*v.z + 2*w*v.y; + Matrix3f Quaternion::toMatrix3() const { + Matrix3f rm; - //row2 - rm[1]= 2*v.x*v.y + 2*w*v.z; - rm[4]= 1.0f - 2*v.x*v.x - 2*v.z*v.z; - rm[7]= 2*v.y*v.z - 2*w*v.x; + //row1 + rm[0] = 1.0f - 2 * v.y*v.y - 2 * v.z*v.z; + rm[3] = 2 * v.x*v.y - 2 * w*v.z; + rm[6] = 2 * v.x*v.z + 2 * w*v.y; - //row3 - rm[2]= 2*v.x*v.z - 2*w*v.y; - rm[5]= 2*v.y*v.z + 2*w*v.x; - rm[8]= 1.0f - 2*v.x*v.x - 2*v.y*v.y; + //row2 + rm[1] = 2 * v.x*v.y + 2 * w*v.z; + rm[4] = 1.0f - 2 * v.x*v.x - 2 * v.z*v.z; + rm[7] = 2 * v.y*v.z - 2 * w*v.x; - return rm; -} + //row3 + rm[2] = 2 * v.x*v.z - 2 * w*v.y; + rm[5] = 2 * v.y*v.z + 2 * w*v.x; + rm[8] = 1.0f - 2 * v.x*v.x - 2 * v.y*v.y; -Matrix4f Quaternion::toMatrix4() const{ - Matrix4f rm; + return rm; + } - //row1 - rm[0]= 1.0f - 2*v.y*v.y - 2*v.z*v.z; - rm[4]= 2*v.x*v.y - 2*w*v.z; - rm[8]= 2*v.x*v.z + 2*w*v.y; - rm[12]= 0.0f; + Matrix4f Quaternion::toMatrix4() const { + Matrix4f rm; - //row2 - rm[1]= 2*v.x*v.y + 2*w*v.z; - rm[5]= 1.0f - 2*v.x*v.x - 2*v.z*v.z; - rm[9]= 2*v.y*v.z - 2*w*v.x; - rm[13]= 0.0f; + //row1 + rm[0] = 1.0f - 2 * v.y*v.y - 2 * v.z*v.z; + rm[4] = 2 * v.x*v.y - 2 * w*v.z; + rm[8] = 2 * v.x*v.z + 2 * w*v.y; + rm[12] = 0.0f; - //row3 - rm[2]= 2*v.x*v.z - 2*w*v.y; - rm[6]= 2*v.y*v.z + 2*w*v.x; - rm[10]= 1.0f - 2*v.x*v.x - 2*v.y*v.y; - rm[14]= 0.0f; + //row2 + rm[1] = 2 * v.x*v.y + 2 * w*v.z; + rm[5] = 1.0f - 2 * v.x*v.x - 2 * v.z*v.z; + rm[9] = 2 * v.y*v.z - 2 * w*v.x; + rm[13] = 0.0f; - //row4 - rm[3]= 0.0f; - rm[7]= 0.0f; - rm[11]= 0.0f; - rm[15]= 1.0f; + //row3 + rm[2] = 2 * v.x*v.z - 2 * w*v.y; + rm[6] = 2 * v.y*v.z + 2 * w*v.x; + rm[10] = 1.0f - 2 * v.x*v.x - 2 * v.y*v.y; + rm[14] = 0.0f; - return rm; -} + //row4 + rm[3] = 0.0f; + rm[7] = 0.0f; + rm[11] = 0.0f; + rm[15] = 1.0f; -Vec3f Quaternion::getLocalXAxis() const{ - return Vec3f( - 1.0f - 2*v.y*v.y - 2*v.z*v.z, - 2*v.x*v.y + 2*w*v.z, - 2*v.x*v.z - 2*w*v.y); -} + return rm; + } -Vec3f Quaternion::getLocalYAxis() const{ - return Vec3f( - 2*v.x*v.y - 2*w*v.z, - 1.0f - 2*v.x*v.x - 2*v.z*v.z, - 2*v.y*v.z + 2*w*v.x); -} + Vec3f Quaternion::getLocalXAxis() const { + return Vec3f( + 1.0f - 2 * v.y*v.y - 2 * v.z*v.z, + 2 * v.x*v.y + 2 * w*v.z, + 2 * v.x*v.z - 2 * w*v.y); + } -Vec3f Quaternion::getLocalZAxis() const{ - return Vec3f( - 2*v.x*v.z + 2*w*v.y, - 2*v.y*v.z - 2*w*v.x, - 1.0f - 2*v.x*v.x - 2*v.y*v.y); -} + Vec3f Quaternion::getLocalYAxis() const { + return Vec3f( + 2 * v.x*v.y - 2 * w*v.z, + 1.0f - 2 * v.x*v.x - 2 * v.z*v.z, + 2 * v.y*v.z + 2 * w*v.x); + } -}}//end namespace + Vec3f Quaternion::getLocalZAxis() const { + return Vec3f( + 2 * v.x*v.z + 2 * w*v.y, + 2 * v.y*v.z - 2 * w*v.x, + 1.0f - 2 * v.x*v.x - 2 * v.y*v.y); + } + + } +}//end namespace diff --git a/source/shared_lib/sources/graphics/shader.cpp b/source/shared_lib/sources/graphics/shader.cpp index 40ddccbe6..7acbb1922 100644 --- a/source/shared_lib/sources/graphics/shader.cpp +++ b/source/shared_lib/sources/graphics/shader.cpp @@ -18,29 +18,31 @@ using namespace std; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class ShaderSource -// ===================================================== + // ===================================================== + // class ShaderSource + // ===================================================== -void ShaderSource::load(const string &path){ - pathInfo+= path + " "; + void ShaderSource::load(const string &path) { + pathInfo += path + " "; - //open file - ifstream ifs(path.c_str()); - if(ifs.fail()){ - throw megaglest_runtime_error("Can't open shader file: " + path); - } + //open file + ifstream ifs(path.c_str()); + if (ifs.fail()) { + throw megaglest_runtime_error("Can't open shader file: " + path); + } - //read source - while(true){ - fstream::int_type c= ifs.get(); - if(ifs.eof() || ifs.fail() || ifs.bad()){ - break; + //read source + while (true) { + fstream::int_type c = ifs.get(); + if (ifs.eof() || ifs.fail() || ifs.bad()) { + break; + } + code += c; + } } - code+= c; - } -} -}}//end namespace + } +}//end namespace diff --git a/source/shared_lib/sources/graphics/shader_manager.cpp b/source/shared_lib/sources/graphics/shader_manager.cpp index 3c73f9d9e..fba35635f 100644 --- a/source/shared_lib/sources/graphics/shader_manager.cpp +++ b/source/shared_lib/sources/graphics/shader_manager.cpp @@ -19,66 +19,68 @@ using namespace Shared::Util; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class ShaderManager -// ===================================================== + // ===================================================== + // class ShaderManager + // ===================================================== + + ShaderManager::ShaderManager() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } + + } + + ShaderManager::~ShaderManager() { + } + + void ShaderManager::init() { + for (unsigned int i = 0; i < shaders.size(); ++i) { + shaders[i]->init(); + if (!shaders[i]->compile(logString)) { + throw megaglest_runtime_error("Can't compile shader\n"); + } + } + for (unsigned int i = 0; i < shaderPrograms.size(); ++i) { + shaderPrograms[i]->init(); + if (!shaderPrograms[i]->link(logString)) { + throw megaglest_runtime_error("Can't link shader\n"); + } + } + } + + void ShaderManager::end() { + for (unsigned int i = 0; i < shaderPrograms.size(); ++i) { + shaderPrograms[i]->end(); + delete shaderPrograms[i]; + } + shaderPrograms.clear(); + for (unsigned int i = 0; i < shaders.size(); ++i) { + shaders[i]->end(); + delete shaders[i]; + } + shaders.clear(); + } + + ShaderProgram *ShaderManager::newShaderProgram() { + ShaderProgram *sp = GraphicsInterface::getInstance().getFactory()->newShaderProgram(); + shaderPrograms.push_back(sp); + return sp; + } + + VertexShader *ShaderManager::newVertexShader() { + VertexShader *vs = GraphicsInterface::getInstance().getFactory()->newVertexShader(); + shaders.push_back(vs); + return vs; + } + + FragmentShader *ShaderManager::newFragmentShader() { + FragmentShader *fs = GraphicsInterface::getInstance().getFactory()->newFragmentShader(); + shaders.push_back(fs); + return fs; + } -ShaderManager::ShaderManager() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); } - -} - -ShaderManager::~ShaderManager(){ -} - -void ShaderManager::init(){ - for(unsigned int i=0; iinit(); - if(!shaders[i]->compile(logString)){ - throw megaglest_runtime_error("Can't compile shader\n"); - } - } - for(unsigned int i=0; iinit(); - if(!shaderPrograms[i]->link(logString)){ - throw megaglest_runtime_error("Can't link shader\n"); - } - } -} - -void ShaderManager::end(){ - for(unsigned int i=0; iend(); - delete shaderPrograms[i]; - } - shaderPrograms.clear(); - for(unsigned int i=0; iend(); - delete shaders[i]; - } - shaders.clear(); -} - -ShaderProgram *ShaderManager::newShaderProgram(){ - ShaderProgram *sp= GraphicsInterface::getInstance().getFactory()->newShaderProgram(); - shaderPrograms.push_back(sp); - return sp; -} - -VertexShader *ShaderManager::newVertexShader(){ - VertexShader *vs= GraphicsInterface::getInstance().getFactory()->newVertexShader(); - shaders.push_back(vs); - return vs; -} - -FragmentShader *ShaderManager::newFragmentShader(){ - FragmentShader *fs= GraphicsInterface::getInstance().getFactory()->newFragmentShader(); - shaders.push_back(fs); - return fs; -} - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/graphics/texture.cpp b/source/shared_lib/sources/graphics/texture.cpp index d87679a36..59a08e808 100644 --- a/source/shared_lib/sources/graphics/texture.cpp +++ b/source/shared_lib/sources/graphics/texture.cpp @@ -18,285 +18,285 @@ using namespace Shared::Util; using namespace Shared::Platform; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class Texture -// ===================================================== + // ===================================================== + // class Texture + // ===================================================== -const int Texture::defaultSize = 256; -const int Texture::defaultComponents = 4; -bool Texture::useTextureCompression = false; + const int Texture::defaultSize = 256; + const int Texture::defaultComponents = 4; + bool Texture::useTextureCompression = false; -// Quick utility function for texture creation -/* -static int powerOfTwo(int input) { - int value = 1; + // Quick utility function for texture creation + /* + static int powerOfTwo(int input) { + int value = 1; - while (value < input) { - value <<= 1; + while (value < input) { + value <<= 1; + } + return value; } - return value; -} -*/ + */ -Texture::Texture() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } - - - mipmap= true; - pixmapInit= true; - wrapMode= wmRepeat; - format= fAuto; - textureSystemId = 0; - - inited= false; - forceCompressionDisabled=false; -} - - -// ===================================================== -// class Texture1D -// ===================================================== - -void Texture1D::load(const string &path){ - this->path= path; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] this->path = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->path.c_str()); - - if (pixmap.getComponents() == -1) { - pixmap.init(defaultComponents); - } - pixmap.load(path); - this->path= path; -} - -string Texture1D::getPath() const { - return (pixmap.getPath() != "" ? pixmap.getPath() : path); -} - -void Texture1D::deletePixels() { - //printf("+++> Texture1D pixmap deletion for [%s]\n",getPath().c_str()); - pixmap.deletePixels(); -} - -// ===================================================== -// class Texture2D -// ===================================================== - -std::pair Texture2D::CreateSDLSurface(bool newPixelData) const { - std::pair result; - result.first = NULL; - result.second = NULL; - - unsigned char* surfData = NULL; - if (newPixelData == true) { - // copy pixel data - surfData = new unsigned char[pixmap.getW() * pixmap.getH() * pixmap.getComponents()]; - memcpy(surfData, pixmap.getPixels(), pixmap.getW() * pixmap.getH() * pixmap.getComponents()); - } - else { - surfData = pixmap.getPixels(); - } - - result.second = surfData; - // This will only work with 24bit RGB and 32bit RGBA pictures - result.first = SDL_CreateRGBSurfaceFrom(surfData, pixmap.getW(), pixmap.getH(), 8 * pixmap.getComponents(), pixmap.getW() * pixmap.getComponents(), 0x000000FF, 0x0000FF00, 0x00FF0000, (pixmap.getComponents() == 4) ? 0xFF000000 : 0); - if ((result.first == NULL) && newPixelData == true) { - // cleanup when we failed to the create surface - delete[] surfData; - result.second = NULL; - } - else { -// SDL_Surface *prepGLTexture(SDL_Surface *surface, GLfloat *texCoords = NULL, const bool -// freeSource = false) { - /* Use the surface width and height expanded to powers of 2 */ - //int w = powerOfTwo(surface->w); - //int h = powerOfTwo(surface->h); - if(result.first == NULL) { - throw megaglest_runtime_error("result.first == NULL"); + Texture::Texture() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); } - int w = result.first->w; - int h = result.first->h; -// if (texCoords != 0) { -// texCoords[0] = 0.0f; /* Min -// X */ -// texCoords[1] = 0.0f; /* Min -// Y */ -// texCoords[2] = (GLfloat)surface->w / w; /* Max X */ -// texCoords[3] = (GLfloat)surface->h / h; /* Max Y */ -// } + mipmap = true; + pixmapInit = true; + wrapMode = wmRepeat; + format = fAuto; + textureSystemId = 0; - SDL_Surface *image = SDL_CreateRGBSurface( - SDL_SWSURFACE, - w, h, - 32, - #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ - 0x000000FF, - 0x0000FF00, - 0x00FF0000, - 0xFF000000 - #else - 0xFF000000, - 0x00FF0000, - 0x0000FF00, - 0x000000FF - #endif - ); - if ( image == NULL ) { - result.first = NULL; - return result; - } - - // TTSDL -// /* Save the alpha blending attributes */ -// Uint32 savedFlags = result.first->flags&(SDL_SRCALPHA|SDL_RLEACCELOK); -// Uint8 savedAlpha = result.first->format->alpha; -// if ( (savedFlags & SDL_SRCALPHA) == SDL_SRCALPHA ) { -// SDL_SetAlpha(result.first, 0, 0); -// } - - SDL_Rect srcArea, destArea; - /* Copy the surface into the GL texture image */ - srcArea.x = 0; destArea.x = 0; - /* Copy it in at the bottom, because we're going to flip - this image upside-down in a moment - */ - srcArea.y = 0; destArea.y = h - result.first->h; - srcArea.w = result.first->w; - srcArea.h = result.first->h; - SDL_BlitSurface(result.first, &srcArea, image, &destArea); - - // TTSDL -// /* Restore the alpha blending attributes */ -// if ((savedFlags & SDL_SRCALPHA) == SDL_SRCALPHA) { -// SDL_SetAlpha(result.first, savedFlags, savedAlpha); -// } - - /* Turn the image upside-down, because OpenGL textures - start at the bottom-left, instead of the top-left - */ - #ifdef _MSC_VER - Uint8 *line = new Uint8[image->pitch]; - #else - Uint8 line[image->pitch]; - #endif - /* These two make the following more readable */ - Uint8 *pixels = static_cast(image->pixels); - Uint16 pitch = image->pitch; - int ybegin = 0; - int yend = image->h - 1; - - if (SDL_MUSTLOCK(image)) { - SDL_LockSurface(image); - } - while (ybegin < yend) { - memcpy(line, pixels + pitch*ybegin, pitch); - memcpy(pixels + pitch*ybegin, pixels + pitch*yend, pitch); - memcpy(pixels + pitch*yend, line, pitch); - ybegin++; - yend--; - } - if (SDL_MUSTLOCK(image)) { - SDL_UnlockSurface(image); - } - -// if (freeSource) { -// SDL_FreeSurface(surface); -// } - - #ifdef _MSC_VER - delete[] line; - #endif - - result.first = image; -// } - } - - return result; -} - -void Texture2D::load(const string &path){ - this->path= path; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] this->path = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->path.c_str()); - - if (pixmap.getComponents() == -1) { - pixmap.init(defaultComponents); - } - pixmap.load(path); - this->path= path; -} - -string Texture2D::getPath() const { - return (pixmap.getPath() != "" ? pixmap.getPath() : path); -} - -void Texture2D::deletePixels() { - //printf("+++> Texture2D pixmap deletion for [%s]\n",getPath().c_str()); - pixmap.deletePixels(); -} - -// ===================================================== -// class Texture3D -// ===================================================== - -void Texture3D::loadSlice(const string &path, int slice){ - this->path= path; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] this->path = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->path.c_str()); - - if (pixmap.getComponents() == -1) { - pixmap.init(defaultComponents); - } - pixmap.loadSlice(path, slice); - this->path= path; -} - -string Texture3D::getPath() const { - return (pixmap.getPath() != "" ? pixmap.getPath() : path); -} - -void Texture3D::deletePixels() { - //printf("+++> Texture3D pixmap deletion for [%s]\n",getPath().c_str()); - pixmap.deletePixels(); -} - -// ===================================================== -// class TextureCube -// ===================================================== - -void TextureCube::loadFace(const string &path, int face){ - this->path= path; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] this->path = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->path.c_str()); - - if (pixmap.getFace(0)->getComponents() == -1) { - pixmap.init(defaultComponents); - } - pixmap.loadFace(path, face); - this->path= path; -} - -string TextureCube::getPath() const { - string result = ""; - for(int i = 0; i < 6; ++i) { - if(pixmap.getPath(i) != "") { - if(result != "") { - result += ","; - } - result += pixmap.getPath(i); + inited = false; + forceCompressionDisabled = false; } - } - if(result == "") { - result = path; - } - return result; -} -void TextureCube::deletePixels() { - //printf("+++> TextureCube pixmap deletion for [%s]\n",getPath().c_str()); - pixmap.deletePixels(); -} -}}//end namespace + // ===================================================== + // class Texture1D + // ===================================================== + + void Texture1D::load(const string &path) { + this->path = path; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] this->path = [%s]\n", __FILE__, __FUNCTION__, __LINE__, this->path.c_str()); + + if (pixmap.getComponents() == -1) { + pixmap.init(defaultComponents); + } + pixmap.load(path); + this->path = path; + } + + string Texture1D::getPath() const { + return (pixmap.getPath() != "" ? pixmap.getPath() : path); + } + + void Texture1D::deletePixels() { + //printf("+++> Texture1D pixmap deletion for [%s]\n",getPath().c_str()); + pixmap.deletePixels(); + } + + // ===================================================== + // class Texture2D + // ===================================================== + + std::pair Texture2D::CreateSDLSurface(bool newPixelData) const { + std::pair result; + result.first = NULL; + result.second = NULL; + + unsigned char* surfData = NULL; + if (newPixelData == true) { + // copy pixel data + surfData = new unsigned char[pixmap.getW() * pixmap.getH() * pixmap.getComponents()]; + memcpy(surfData, pixmap.getPixels(), pixmap.getW() * pixmap.getH() * pixmap.getComponents()); + } else { + surfData = pixmap.getPixels(); + } + + result.second = surfData; + // This will only work with 24bit RGB and 32bit RGBA pictures + result.first = SDL_CreateRGBSurfaceFrom(surfData, pixmap.getW(), pixmap.getH(), 8 * pixmap.getComponents(), pixmap.getW() * pixmap.getComponents(), 0x000000FF, 0x0000FF00, 0x00FF0000, (pixmap.getComponents() == 4) ? 0xFF000000 : 0); + if ((result.first == NULL) && newPixelData == true) { + // cleanup when we failed to the create surface + delete[] surfData; + result.second = NULL; + } else { + // SDL_Surface *prepGLTexture(SDL_Surface *surface, GLfloat *texCoords = NULL, const bool + // freeSource = false) { + /* Use the surface width and height expanded to powers of 2 */ + //int w = powerOfTwo(surface->w); + //int h = powerOfTwo(surface->h); + if (result.first == NULL) { + throw megaglest_runtime_error("result.first == NULL"); + } + + int w = result.first->w; + int h = result.first->h; + + // if (texCoords != 0) { + // texCoords[0] = 0.0f; /* Min + // X */ + // texCoords[1] = 0.0f; /* Min + // Y */ + // texCoords[2] = (GLfloat)surface->w / w; /* Max X */ + // texCoords[3] = (GLfloat)surface->h / h; /* Max Y */ + // } + + SDL_Surface *image = SDL_CreateRGBSurface( + SDL_SWSURFACE, + w, h, + 32, +#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ + 0x000000FF, + 0x0000FF00, + 0x00FF0000, + 0xFF000000 +#else + 0xFF000000, + 0x00FF0000, + 0x0000FF00, + 0x000000FF +#endif + ); + if (image == NULL) { + result.first = NULL; + return result; + } + + // TTSDL + // /* Save the alpha blending attributes */ + // Uint32 savedFlags = result.first->flags&(SDL_SRCALPHA|SDL_RLEACCELOK); + // Uint8 savedAlpha = result.first->format->alpha; + // if ( (savedFlags & SDL_SRCALPHA) == SDL_SRCALPHA ) { + // SDL_SetAlpha(result.first, 0, 0); + // } + + SDL_Rect srcArea, destArea; + /* Copy the surface into the GL texture image */ + srcArea.x = 0; destArea.x = 0; + /* Copy it in at the bottom, because we're going to flip + this image upside-down in a moment + */ + srcArea.y = 0; destArea.y = h - result.first->h; + srcArea.w = result.first->w; + srcArea.h = result.first->h; + SDL_BlitSurface(result.first, &srcArea, image, &destArea); + + // TTSDL + // /* Restore the alpha blending attributes */ + // if ((savedFlags & SDL_SRCALPHA) == SDL_SRCALPHA) { + // SDL_SetAlpha(result.first, savedFlags, savedAlpha); + // } + + /* Turn the image upside-down, because OpenGL textures + start at the bottom-left, instead of the top-left + */ +#ifdef _MSC_VER + Uint8 *line = new Uint8[image->pitch]; +#else + Uint8 line[image->pitch]; +#endif + /* These two make the following more readable */ + Uint8 *pixels = static_cast(image->pixels); + Uint16 pitch = image->pitch; + int ybegin = 0; + int yend = image->h - 1; + + if (SDL_MUSTLOCK(image)) { + SDL_LockSurface(image); + } + while (ybegin < yend) { + memcpy(line, pixels + pitch*ybegin, pitch); + memcpy(pixels + pitch*ybegin, pixels + pitch*yend, pitch); + memcpy(pixels + pitch*yend, line, pitch); + ybegin++; + yend--; + } + if (SDL_MUSTLOCK(image)) { + SDL_UnlockSurface(image); + } + + // if (freeSource) { + // SDL_FreeSurface(surface); + // } + +#ifdef _MSC_VER + delete[] line; +#endif + + result.first = image; + // } + } + + return result; + } + + void Texture2D::load(const string &path) { + this->path = path; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] this->path = [%s]\n", __FILE__, __FUNCTION__, __LINE__, this->path.c_str()); + + if (pixmap.getComponents() == -1) { + pixmap.init(defaultComponents); + } + pixmap.load(path); + this->path = path; + } + + string Texture2D::getPath() const { + return (pixmap.getPath() != "" ? pixmap.getPath() : path); + } + + void Texture2D::deletePixels() { + //printf("+++> Texture2D pixmap deletion for [%s]\n",getPath().c_str()); + pixmap.deletePixels(); + } + + // ===================================================== + // class Texture3D + // ===================================================== + + void Texture3D::loadSlice(const string &path, int slice) { + this->path = path; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] this->path = [%s]\n", __FILE__, __FUNCTION__, __LINE__, this->path.c_str()); + + if (pixmap.getComponents() == -1) { + pixmap.init(defaultComponents); + } + pixmap.loadSlice(path, slice); + this->path = path; + } + + string Texture3D::getPath() const { + return (pixmap.getPath() != "" ? pixmap.getPath() : path); + } + + void Texture3D::deletePixels() { + //printf("+++> Texture3D pixmap deletion for [%s]\n",getPath().c_str()); + pixmap.deletePixels(); + } + + // ===================================================== + // class TextureCube + // ===================================================== + + void TextureCube::loadFace(const string &path, int face) { + this->path = path; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] this->path = [%s]\n", __FILE__, __FUNCTION__, __LINE__, this->path.c_str()); + + if (pixmap.getFace(0)->getComponents() == -1) { + pixmap.init(defaultComponents); + } + pixmap.loadFace(path, face); + this->path = path; + } + + string TextureCube::getPath() const { + string result = ""; + for (int i = 0; i < 6; ++i) { + if (pixmap.getPath(i) != "") { + if (result != "") { + result += ","; + } + result += pixmap.getPath(i); + } + } + if (result == "") { + result = path; + } + return result; + } + + void TextureCube::deletePixels() { + //printf("+++> TextureCube pixmap deletion for [%s]\n",getPath().c_str()); + pixmap.deletePixels(); + } + + } +}//end namespace diff --git a/source/shared_lib/sources/graphics/texture_manager.cpp b/source/shared_lib/sources/graphics/texture_manager.cpp index 199a11be9..39c75d6d3 100644 --- a/source/shared_lib/sources/graphics/texture_manager.cpp +++ b/source/shared_lib/sources/graphics/texture_manager.cpp @@ -24,137 +24,139 @@ using namespace Shared::Util; using namespace Shared::Platform; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -// ===================================================== -// class TextureManager -// ===================================================== + // ===================================================== + // class TextureManager + // ===================================================== -TextureManager::TextureManager() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); - } + TextureManager::TextureManager() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + throw megaglest_runtime_error("Loading graphics in headless server mode not allowed!"); + } - textureFilter= Texture::fBilinear; - maxAnisotropy= 1; -} + textureFilter = Texture::fBilinear; + maxAnisotropy = 1; + } -TextureManager::~TextureManager(){ - end(); -} + TextureManager::~TextureManager() { + end(); + } -void TextureManager::initTexture(Texture *texture) { - if(texture != NULL) { - texture->init(textureFilter, maxAnisotropy); - } -} - -void TextureManager::endTexture(Texture *texture,bool mustExistInList) { - if(texture != NULL) { - bool found = false; - for(unsigned int idx = 0; idx < textures.size(); idx++) { - Texture *curTexture = textures[idx]; - if(curTexture == texture) { - found = true; - textures.erase(textures.begin() + idx); - break; + void TextureManager::initTexture(Texture *texture) { + if (texture != NULL) { + texture->init(textureFilter, maxAnisotropy); } } - if(found == false && mustExistInList == true) { - throw std::runtime_error("found == false in endTexture"); + + void TextureManager::endTexture(Texture *texture, bool mustExistInList) { + if (texture != NULL) { + bool found = false; + for (unsigned int idx = 0; idx < textures.size(); idx++) { + Texture *curTexture = textures[idx]; + if (curTexture == texture) { + found = true; + textures.erase(textures.begin() + idx); + break; + } + } + if (found == false && mustExistInList == true) { + throw std::runtime_error("found == false in endTexture"); + } + texture->end(); + delete texture; + } } - texture->end(); - delete texture; - } -} -void TextureManager::endLastTexture(bool mustExistInList) { - bool found = false; - if(textures.size() > 0) { - found = true; - int index = (int)textures.size()-1; - Texture *curTexture = textures[index]; - textures.erase(textures.begin() + index); + void TextureManager::endLastTexture(bool mustExistInList) { + bool found = false; + if (textures.size() > 0) { + found = true; + int index = (int) textures.size() - 1; + Texture *curTexture = textures[index]; + textures.erase(textures.begin() + index); - curTexture->end(); - delete curTexture; - } - if(found == false && mustExistInList == true) { - throw std::runtime_error("found == false in endLastTexture"); - } -} - -void TextureManager::init(bool forceInit) { - for(unsigned int i=0; iend(); + delete curTexture; + } + if (found == false && mustExistInList == true) { + throw std::runtime_error("found == false in endLastTexture"); + } } - if(forceInit == true) { - texture->reseInitState(); + + void TextureManager::init(bool forceInit) { + for (unsigned int i = 0; i < textures.size(); ++i) { + Texture *texture = textures[i]; + if (texture == NULL) { + throw std::runtime_error("texture == NULL during init"); + } + if (forceInit == true) { + texture->reseInitState(); + } + if (forceInit == true) { + texture->end(false); + } + texture->init(textureFilter, maxAnisotropy); + } } - if(forceInit == true) { - texture->end(false); + + void TextureManager::end() { + for (unsigned int i = 0; i < textures.size(); ++i) { + if (textures[i] != NULL) { + textures[i]->end(); + delete textures[i]; + } + } + textures.clear(); } - texture->init(textureFilter, maxAnisotropy); + + void TextureManager::setFilter(Texture::Filter textureFilter) { + this->textureFilter = textureFilter; + } + + void TextureManager::setMaxAnisotropy(int maxAnisotropy) { + this->maxAnisotropy = maxAnisotropy; + } + + Texture *TextureManager::getTexture(const string &path) { + for (unsigned int i = 0; i < textures.size(); ++i) { + if (textures[i]->getPath() == path) { + return textures[i]; + } + } + return NULL; + } + + Texture1D *TextureManager::newTexture1D() { + Texture1D *texture1D = GraphicsInterface::getInstance().getFactory()->newTexture1D(); + textures.push_back(texture1D); + + return texture1D; + } + + Texture2D *TextureManager::newTexture2D() { + Texture2D *texture2D = GraphicsInterface::getInstance().getFactory()->newTexture2D(); + textures.push_back(texture2D); + + return texture2D; + } + + Texture3D *TextureManager::newTexture3D() { + Texture3D *texture3D = GraphicsInterface::getInstance().getFactory()->newTexture3D(); + textures.push_back(texture3D); + + return texture3D; + } + + + TextureCube *TextureManager::newTextureCube() { + TextureCube *textureCube = GraphicsInterface::getInstance().getFactory()->newTextureCube(); + textures.push_back(textureCube); + + return textureCube; + } + } -} - -void TextureManager::end(){ - for(unsigned int i=0; iend(); - delete textures[i]; - } - } - textures.clear(); -} - -void TextureManager::setFilter(Texture::Filter textureFilter){ - this->textureFilter= textureFilter; -} - -void TextureManager::setMaxAnisotropy(int maxAnisotropy){ - this->maxAnisotropy= maxAnisotropy; -} - -Texture *TextureManager::getTexture(const string &path){ - for(unsigned int i=0; igetPath()==path){ - return textures[i]; - } - } - return NULL; -} - -Texture1D *TextureManager::newTexture1D(){ - Texture1D *texture1D= GraphicsInterface::getInstance().getFactory()->newTexture1D(); - textures.push_back(texture1D); - - return texture1D; -} - -Texture2D *TextureManager::newTexture2D(){ - Texture2D *texture2D= GraphicsInterface::getInstance().getFactory()->newTexture2D(); - textures.push_back(texture2D); - - return texture2D; -} - -Texture3D *TextureManager::newTexture3D(){ - Texture3D *texture3D= GraphicsInterface::getInstance().getFactory()->newTexture3D(); - textures.push_back(texture3D); - - return texture3D; -} - - -TextureCube *TextureManager::newTextureCube(){ - TextureCube *textureCube= GraphicsInterface::getInstance().getFactory()->newTextureCube(); - textures.push_back(textureCube); - - return textureCube; -} - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/graphics/video_player.cpp b/source/shared_lib/sources/graphics/video_player.cpp index 52a699061..daae5a8c1 100644 --- a/source/shared_lib/sources/graphics/video_player.cpp +++ b/source/shared_lib/sources/graphics/video_player.cpp @@ -45,32 +45,32 @@ typedef unsigned __int64 uint64_t; * @param name the name of the registry key, for example "Installed Path" * @return the value of the key or an empty string if an error occured. */ -std::string getRegKey(const std::string& location, const std::string& name){ - HKEY key; - CHAR value[1024]; - DWORD bufLen = 1024*sizeof(CHAR); - long ret; - ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, location.c_str(), 0, KEY_QUERY_VALUE, &key); - if( ret != ERROR_SUCCESS ){ - return std::string(); - } - ret = RegQueryValueExA(key, name.c_str(), 0, 0, (LPBYTE) value, &bufLen); - RegCloseKey(key); - if ( (ret != ERROR_SUCCESS) || (bufLen > 1024*sizeof(TCHAR)) ){ - return std::string(); - } - string stringValue = value; - size_t i = stringValue.length(); - while( i > 0 && stringValue[i-1] == '\0' ){ - --i; - } - return stringValue.substr(0,i); +std::string getRegKey(const std::string& location, const std::string& name) { + HKEY key; + CHAR value[1024]; + DWORD bufLen = 1024 * sizeof(CHAR); + long ret; + ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, location.c_str(), 0, KEY_QUERY_VALUE, &key); + if (ret != ERROR_SUCCESS) { + return std::string(); + } + ret = RegQueryValueExA(key, name.c_str(), 0, 0, (LPBYTE) value, &bufLen); + RegCloseKey(key); + if ((ret != ERROR_SUCCESS) || (bufLen > 1024 * sizeof(TCHAR))) { + return std::string(); + } + string stringValue = value; + size_t i = stringValue.length(); + while (i > 0 && stringValue[i - 1] == '\0') { + --i; + } + return stringValue.substr(0, i); } #endif -const string HTTP_PREFIX = "http"; +const string HTTP_PREFIX = "http"; #ifdef HAS_LIBVLC -const double MAX_VIDEO_START_MILLISECONDS = 10.0; +const double MAX_VIDEO_START_MILLISECONDS = 10.0; #endif class ctx { @@ -78,21 +78,21 @@ public: ctx() { loadingCB = NULL; empty = NULL; - textureId = 0; // Texture ID - surf = NULL; - mutex = NULL; - x= 0; - y = 0; - width = 0; - height = 0; - rawData = NULL; - started = false; - error = false; - stopped = false; - end_of_media = false; - isPlaying = 0; - needToQuit = false; - verboseEnabled = 0; + textureId = 0; // Texture ID + surf = NULL; + mutex = NULL; + x = 0; + y = 0; + width = 0; + height = 0; + rawData = NULL; + started = false; + error = false; + stopped = false; + end_of_media = false; + isPlaying = 0; + needToQuit = false; + verboseEnabled = 0; #ifdef HAS_LIBVLC libvlc = NULL; @@ -108,21 +108,21 @@ public: Shared::Graphics::VideoLoadingCallbackInterface *loadingCB; SDL_Surface *empty; - GLuint textureId; // Texture ID - SDL_Surface *surf; - SDL_mutex *mutex; - int x; - int y; - int width; - int height; - void *rawData; - bool started; - bool error; - bool stopped; - bool end_of_media; - bool isPlaying; - bool needToQuit; - bool verboseEnabled; + GLuint textureId; // Texture ID + SDL_Surface *surf; + SDL_mutex *mutex; + int x; + int y; + int width; + int height; + void *rawData; + bool started; + bool error; + bool stopped; + bool end_of_media; + bool isPlaying; + bool needToQuit; + bool verboseEnabled; #ifdef HAS_LIBVLC libvlc_instance_t *libvlc; @@ -137,1321 +137,1318 @@ public: #endif }; -namespace Shared{ namespace Graphics{ +namespace Shared { + namespace Graphics { -bool VideoPlayer::disabled = false; + bool VideoPlayer::disabled = false; -// Load a texture -static inline void loadTexture(class ctx *ctx) { - if(ctx->verboseEnabled) printf("In [%s] Line: %d\n",__FUNCTION__,__LINE__); + // Load a texture + static inline void loadTexture(class ctx *ctx) { + if (ctx->verboseEnabled) printf("In [%s] Line: %d\n", __FUNCTION__, __LINE__); - void *rawData = ctx->rawData; - Uint8 * pixelSource = 0; - Uint8 * pixelDestination = (Uint8 *) rawData; - Uint32 pix = 0; + void *rawData = ctx->rawData; + Uint8 * pixelSource = 0; + Uint8 * pixelDestination = (Uint8 *) rawData; + Uint32 pix = 0; - for ( int i = ctx->height; i > 0; i--) { - for (int j = 0; j < ctx->width; j++) { - pixelSource = (Uint8 *) ctx->surf->pixels + (i-1) * ctx->surf->pitch + j * 2; - pix = *(Uint16 *) pixelSource; - SDL_GetRGBA(pix, ctx->surf->format, &(pixelDestination[0]), &(pixelDestination[1]), &(pixelDestination[2]), &(pixelDestination[3])); - pixelDestination += 4; - } - } + for (int i = ctx->height; i > 0; i--) { + for (int j = 0; j < ctx->width; j++) { + pixelSource = (Uint8 *) ctx->surf->pixels + (i - 1) * ctx->surf->pitch + j * 2; + pix = *(Uint16 *) pixelSource; + SDL_GetRGBA(pix, ctx->surf->format, &(pixelDestination[0]), &(pixelDestination[1]), &(pixelDestination[2]), &(pixelDestination[3])); + pixelDestination += 4; + } + } - // Building the texture - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glBindTexture(GL_TEXTURE_2D, ctx->textureId); - glTexImage2D(GL_TEXTURE_2D, 0, 4, ctx->width, ctx->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (Uint8 *) rawData); -} + // Building the texture + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glBindTexture(GL_TEXTURE_2D, ctx->textureId); + glTexImage2D(GL_TEXTURE_2D, 0, 4, ctx->width, ctx->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (Uint8 *) rawData); + } #ifdef HAS_LIBVLC #if !defined(LIBVLC_VERSION_PRE_2) && !defined(LIBVLC_VERSION_PRE_1_1_0) -static void *lock(void *data, void **p_pixels) { - class ctx *ctx = (class ctx *)data; - if(ctx->verboseEnabled) printf("In [%s] Line: %d\n",__FUNCTION__,__LINE__); + static void *lock(void *data, void **p_pixels) { + class ctx *ctx = (class ctx *)data; + if (ctx->verboseEnabled) printf("In [%s] Line: %d\n", __FUNCTION__, __LINE__); - SDL_LockMutex(ctx->mutex); - SDL_LockSurface(ctx->surf); - *p_pixels = ctx->surf->pixels; + SDL_LockMutex(ctx->mutex); + SDL_LockSurface(ctx->surf); + *p_pixels = ctx->surf->pixels; - return NULL; /* picture identifier, not needed here */ -} + return NULL; /* picture identifier, not needed here */ + } -static void unlock(void *data, void *id, void *const *p_pixels) { - class ctx *ctx = (class ctx *)data; - if(ctx->verboseEnabled) printf("In [%s] Line: %d\n",__FUNCTION__,__LINE__); + static void unlock(void *data, void *id, void *const *p_pixels) { + class ctx *ctx = (class ctx *)data; + if (ctx->verboseEnabled) printf("In [%s] Line: %d\n", __FUNCTION__, __LINE__); - /* VLC just rendered the video, but we can also render stuff */ - SDL_UnlockSurface(ctx->surf); - SDL_UnlockMutex(ctx->mutex); -} + /* VLC just rendered the video, but we can also render stuff */ + SDL_UnlockSurface(ctx->surf); + SDL_UnlockMutex(ctx->mutex); + } -static void display(void *data, void *id) { - // VLC wants to display the video - class ctx *ctx = (class ctx *)data; - if(ctx->verboseEnabled) printf("In [%s] Line: %d\n",__FUNCTION__,__LINE__); -} + static void display(void *data, void *id) { + // VLC wants to display the video + class ctx *ctx = (class ctx *)data; + if (ctx->verboseEnabled) printf("In [%s] Line: %d\n", __FUNCTION__, __LINE__); + } #endif #endif #if defined(HAS_LIBVLC) && defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) -static void catchError(libvlc_exception_t *ex) { - if(libvlc_exception_raised(ex)) { - fprintf(stderr, "exception: %s\n", libvlc_exception_get_message(ex)); - //exit(1); - } + static void catchError(libvlc_exception_t *ex) { + if (libvlc_exception_raised(ex)) { + fprintf(stderr, "exception: %s\n", libvlc_exception_get_message(ex)); + //exit(1); + } - libvlc_exception_clear(ex); -} + libvlc_exception_clear(ex); + } #endif #if defined(HAS_LIBVLC) -/* -void trapPlayingEvent(const libvlc_event_t *evt, void *data) { - class ctx *ctx = (class ctx *)data; - if(ctx->verboseEnabled) printf("In [%s] Line: %d\n",__FUNCTION__,__LINE__); - ctx->isPlaying = true; - ctx->started = true; -} - -void trapEndReachedEvent(const libvlc_event_t *evt, void *data) { - class ctx *ctx = (class ctx *)data; - if(ctx->verboseEnabled) printf("In [%s] Line: %d\n",__FUNCTION__,__LINE__); - ctx->isPlaying = false; -} - -void trapBufferingEvent(const libvlc_event_t *evt, void *data) { - class ctx *ctx = (class ctx *)data; - if(ctx->verboseEnabled) printf("In [%s] Line: %d\n",__FUNCTION__,__LINE__); - ctx->isPlaying = true; -} - -void trapErrorEvent(const libvlc_event_t *evt, void *data) { - class ctx *ctx = (class ctx *)data; - if(ctx->verboseEnabled) printf("In [%s] Line: %d\n",__FUNCTION__,__LINE__); - ctx->isPlaying = false; -} -*/ -void callbacks( const libvlc_event_t* event, void* data ) { - class ctx *ctx = (class ctx *)data; - if(ctx->verboseEnabled) printf("In [%s] Line: %d event [%d]\n",__FUNCTION__,__LINE__,event->type); - switch ( event->type ) { - case libvlc_MediaPlayerPlaying: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerPlaying\n"); - ctx->end_of_media = false; - ctx->error = false; - ctx->stopped = false; - ctx->isPlaying = true; - ctx->started = true; - - break; - case libvlc_MediaPlayerPaused: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerPaused\n"); - break; - case libvlc_MediaPlayerStopped: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerStopped\n"); - ctx->stopped = true; - - break; - case libvlc_MediaPlayerEndReached: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerEndReached\n"); - if(ctx->started == true && ctx->error == false) { - ctx->isPlaying = false; - } - - ctx->end_of_media = true; - - break; - case libvlc_MediaPlayerTimeChanged: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerTimeChanged\n"); - break; - case libvlc_MediaPlayerPositionChanged: - //qDebug() << self << "position changed : " << event->u.media_player_position_changed.new_position; - //self->emit positionChanged( event->u.media_player_position_changed.new_position ); - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerPositionChanged\n"); - break; - case libvlc_MediaPlayerLengthChanged: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerLengthChanged\n"); - break; - case libvlc_MediaPlayerSnapshotTaken: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerSnapshotTaken\n"); - break; - case libvlc_MediaPlayerEncounteredError: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerEncounteredError\n"); - if(ctx->started == false) { - ctx->isPlaying = false; - } - ctx->error = true; - - - break; - case libvlc_MediaPlayerSeekableChanged: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerSeekableChanged\n"); - break; - case libvlc_MediaPlayerPausableChanged: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerPausableChanged\n"); - break; - case libvlc_MediaPlayerTitleChanged: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerTitleChanged\n"); - break; - case libvlc_MediaPlayerNothingSpecial: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerNothingSpecial\n"); - break; - case libvlc_MediaPlayerOpening: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerOpening\n"); - break; - case libvlc_MediaPlayerBuffering: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerBuffering\n"); - break; - case libvlc_MediaPlayerForward: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerForward\n"); - break; - case libvlc_MediaPlayerBackward: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerBackward\n"); - break; - case libvlc_MediaStateChanged: - if(ctx->verboseEnabled) printf("libvlc_MediaStateChanged\n"); - break; - case libvlc_MediaParsedChanged: - if(ctx->verboseEnabled) printf("libvlc_MediaParsedChanged\n"); - break; - -#if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) - case libvlc_MediaPlayerVout: - if(ctx->verboseEnabled) printf("libvlc_MediaPlayerVout\n"); - break; -#endif - case libvlc_MediaListItemAdded: - if(ctx->verboseEnabled) printf("libvlc_MediaListItemAdded\n"); - break; - case libvlc_MediaListWillAddItem: - if(ctx->verboseEnabled) printf("libvlc_MediaListWillAddItem\n"); - break; - case libvlc_MediaListItemDeleted: - if(ctx->verboseEnabled) printf("libvlc_MediaListItemDeleted\n"); - break; - case libvlc_MediaListWillDeleteItem: - if(ctx->verboseEnabled) printf("libvlc_MediaListWillDeleteItem\n"); - break; - case libvlc_MediaListViewItemAdded: - if(ctx->verboseEnabled) printf("libvlc_MediaListViewItemAdded\n"); - break; - case libvlc_MediaListViewWillAddItem: - if(ctx->verboseEnabled) printf("libvlc_MediaListViewWillAddItem\n"); - break; - case libvlc_MediaListViewItemDeleted: - if(ctx->verboseEnabled) printf("libvlc_MediaListViewItemDeleted\n"); - break; - case libvlc_MediaListViewWillDeleteItem: - if(ctx->verboseEnabled) printf("libvlc_MediaListViewWillDeleteItem\n"); - break; - case libvlc_MediaListPlayerPlayed: - if(ctx->verboseEnabled) printf("libvlc_MediaListPlayerPlayed\n"); - break; - case libvlc_MediaListPlayerNextItemSet: - if(ctx->verboseEnabled) printf("libvlc_MediaListPlayerNextItemSet\n"); - //ctx->isPlaying = true; - //ctx->started = true; - ctx->end_of_media = false; - ctx->error = false; - ctx->stopped = false; - - break; - case libvlc_MediaListPlayerStopped: - if(ctx->verboseEnabled) printf("libvlc_MediaListPlayerStopped\n"); - ctx->stopped = true; - - break; - - case libvlc_MediaDiscovererStarted: - if(ctx->verboseEnabled) printf("libvlc_MediaDiscovererStarted\n"); - break; - case libvlc_MediaDiscovererEnded: - if(ctx->verboseEnabled) printf("libvlc_MediaDiscovererEndedvvvvvvvvv\n"); - break; - case libvlc_VlmMediaAdded: - if(ctx->verboseEnabled) printf("libvlc_VlmMediaAdded\n"); - break; - case libvlc_VlmMediaRemoved: - if(ctx->verboseEnabled) printf("libvlc_VlmMediaRemoved\n"); - break; - case libvlc_VlmMediaChanged: - if(ctx->verboseEnabled) printf("libvlc_VlmMediaChanged\n"); - break; - case libvlc_VlmMediaInstanceStarted: - if(ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStarted\n"); - break; - case libvlc_VlmMediaInstanceStopped: - if(ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStopped\n"); - ctx->stopped = true; - - break; - case libvlc_VlmMediaInstanceStatusInit: - if(ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStatusInit\n"); - break; - case libvlc_VlmMediaInstanceStatusOpening: - if(ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStatusOpening\n"); - break; - case libvlc_VlmMediaInstanceStatusPlaying: - if(ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStatusPlaying\n"); - break; - case libvlc_VlmMediaInstanceStatusPause: - if(ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStatusPause\n"); - break; - case libvlc_VlmMediaInstanceStatusEnd: - if(ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStatusEnd\n"); - break; - case libvlc_VlmMediaInstanceStatusError: - if(ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStatusError\n"); - break; - - default: - // qDebug() << "Unknown mediaPlayerEvent: " << event->type; - break; - } -} - -#endif - -VideoPlayer::VideoPlayer(VideoLoadingCallbackInterface *loadingCB, - string filename, - string filenameFallback, - SDL_Window *window, - int x, int y,int width, int height,int colorBits, - bool loop, string pluginsPath, bool verboseEnabled) - : ctxPtr(NULL) { - - this->loadingCB = loadingCB; - this->filename = filename; - this->filenameFallback = filenameFallback; - this->window = window; - this->x = x; - this->y = y; - this->width = width; - this->height = height; - this->colorBits = colorBits; - this->loop = loop; - this->pluginsPath = pluginsPath; - //this->verboseEnabled = true; - this->verboseEnabled = verboseEnabled; - this->stop = false; - this->finished = false; - this->successLoadingLib = false; - - init(); -} - -void VideoPlayer::init() { - if(VideoPlayer::disabled == true) { - return; - } - cleanupPlayer(); - ctxPtr = new ctx(); - ctxPtr->loadingCB = loadingCB; - ctxPtr->x = x; - ctxPtr->y = y; - ctxPtr->width = width; - ctxPtr->height = height; - ctxPtr->rawData = (void *) malloc(width * height * 4); - ctxPtr->verboseEnabled = verboseEnabled; -} - -VideoPlayer::~VideoPlayer() { - cleanupPlayer(); -} - -bool VideoPlayer::hasBackEndVideoPlayer() { - if(VideoPlayer::disabled == true) { - return false; - } - -#ifdef HAS_LIBVLC - return true; -#else - return false; -#endif -} - -void VideoPlayer::cleanupPlayer() { - if(ctxPtr != NULL) { - if(ctxPtr->rawData != NULL) { - free(ctxPtr->rawData); - ctxPtr->rawData = NULL; + /* + void trapPlayingEvent(const libvlc_event_t *evt, void *data) { + class ctx *ctx = (class ctx *)data; + if(ctx->verboseEnabled) printf("In [%s] Line: %d\n",__FUNCTION__,__LINE__); + ctx->isPlaying = true; + ctx->started = true; } - delete ctxPtr; - ctxPtr = NULL; - } -} - -bool VideoPlayer::initPlayer(string mediaURL) { - if(VideoPlayer::disabled == true) { - return true; - } - -#ifdef HAS_LIBVLC - ctxPtr->libvlc = NULL; - ctxPtr->m = NULL; - ctxPtr->mp = NULL; - ctxPtr->vlc_argv.clear(); - ctxPtr->vlc_argv.push_back("--intf=dummy"); - //ctxPtr->vlc_argv.push_back("--intf=http"); - //ctxPtr->vlc_argv.push_back("--no-media-library"); - ctxPtr->vlc_argv.push_back("--ignore-config"); /* Don't use VLC's config */ - ctxPtr->vlc_argv.push_back("--no-xlib"); /* tell VLC to not use Xlib */ - ctxPtr->vlc_argv.push_back("--no-video-title-show"); - //ctxPtr->vlc_argv.push_back("--network-caching=10000"); - - if(loop == true) { - ctxPtr->vlc_argv.push_back("--loop"); - ctxPtr->vlc_argv.push_back("--repeat"); - } - -#if defined(LIBVLC_VERSION_PRE_2) - ctxPtr->vlc_argv_str.push_back("--plugin-path=" + pluginsPath); - ctxPtr->vlc_argv.push_back(ctxPtr->vlc_argv_str[ctxPtr->vlc_argv_str.size()-1].c_str()); -#endif - -#if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) - char clock[64], cunlock[64], cdata[64]; - char cwidth[32], cheight[32], cpitch[32]; - /* - * Initialise libVLC - */ - sprintf(clock, "%lld", (long long int)(intptr_t)lock); - sprintf(cunlock, "%lld", (long long int)(intptr_t)unlock); - sprintf(cdata, "%lld", (long long int)(intptr_t)ctxPtr); - sprintf(cwidth, "%i", width); - sprintf(cheight, "%i", height); - sprintf(cpitch, "%i", colorBits); - - vlc_argv.push_back("--vout"); - vlc_argv.push_back("vmem"); - vlc_argv.push_back("--vmem-width"); - ctxPtr->vlc_argv_str.push_back(cwidth); - ctxPtr->vlc_argv.push_back(ctxPtr->vlc_argv_str[ctxPtr->vlc_argv_str.size()-1].c_str()); - vlc_argv.push_back("--vmem-height"); - ctxPtr->vlc_argv_str.push_back(cheight); - ctxPtr->vlc_argv.push_back(ctxPtr->vlc_argv_str[ctxPtr->vlc_argv_str.size()-1].c_str()); - vlc_argv.push_back("--vmem-pitch"); - ctxPtr->vlc_argv_str.push_back(cpitch); - ctxPtr->vlc_argv.push_back(ctxPtr->vlc_argv_str[ctxPtr->vlc_argv_str.size()-1].c_str()); - vlc_argv.push_back("--vmem-chroma"); - vlc_argv.push_back("RV16"); - vlc_argv.push_back("--vmem-lock"); - ctxPtr->vlc_argv_str.push_back(clock); - ctxPtr->vlc_argv.push_back(ctxPtr->vlc_argv_str[ctxPtr->vlc_argv_str.size()-1].c_str()); - vlc_argv.push_back("--vmem-unlock"); - ctxPtr->vlc_argv_str.push_back(cunlock); - ctxPtr->vlc_argv.push_back(ctxPtr->vlc_argv_str[ctxPtr->vlc_argv_str.size()-1].c_str()); - vlc_argv.push_back("--vmem-data"); - ctxPtr->vlc_argv_str.push_back(cdata); - ctxPtr->vlc_argv.push_back(ctxPtr->vlc_argv_str[ctxPtr->vlc_argv_str.size()-1].c_str()); - -#endif - - if(verboseEnabled) ctxPtr->vlc_argv.push_back("--verbose=2"); - if(verboseEnabled) ctxPtr->vlc_argv.push_back("--extraintf=logger"); //log anything -#if defined(WIN32) - if(verboseEnabled) _putenv("VLC_VERBOSE=2"); -#endif - - -// char const *vlc_argv[] = -// { -// //"--no-audio", /* skip any audio track */ -// "--no-xlib", /* tell VLC to not use Xlib */ -// "--no-video-title-show", -// pluginParam.c_str(), -// }; -// int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); -#endif - - ctxPtr->empty = NULL; - glEnable(GL_TEXTURE_2D); - glEnable(GL_DEPTH_TEST); - // Init Texture - glGenTextures(1, &ctxPtr->textureId); - glBindTexture(GL_TEXTURE_2D, ctxPtr->textureId); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - ctxPtr->empty = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, - colorBits, 0, 0, 0, 0); - ctxPtr->surf = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, - colorBits, 0x001f, 0x07e0, 0xf800, 0); - ctxPtr->mutex = SDL_CreateMutex(); - -#ifdef HAS_LIBVLC - /* - * Initialize libVLC - */ - if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); - -#if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) - libvlc_exception_t ex; - libvlc_exception_init(&ex); - - ctxPtr->libvlc = libvlc_new(ctxPtr->vlc_argc, &ctxPtr->vlc_argv[0],&ex); - catchError(&ex); -#else - int vlc_argc = ctxPtr->vlc_argv.size(); - ctxPtr->libvlc = libvlc_new(vlc_argc, &ctxPtr->vlc_argv[0]); -#endif - - if(verboseEnabled) printf("In [%s] Line: %d, libvlc [%p]\n",__FUNCTION__,__LINE__,ctxPtr->libvlc); - -/* It is meaningless to try all this because we have to restart mg to pickup new env vars -#if defined(WIN32) - if(libvlc == NULL) { - // For windows check registry for install path - std::string strValue = getRegKey("Software\\VideoLAN\\VLC", "InstallDir"); - if(strValue != "") { - if(strValue.length() >= 2) { - if(strValue[0] == '"') { - strValue = strValue.erase(0); - } - if(strValue[strValue.length()-1] == '"') { - strValue = strValue.erase(strValue.length()-1); - } - } - strValue = "VLC_PLUGIN_PATH=" + strValue; - _putenv(strValue.c_str()); - - if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); - libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); + void trapEndReachedEvent(const libvlc_event_t *evt, void *data) { + class ctx *ctx = (class ctx *)data; + if(ctx->verboseEnabled) printf("In [%s] Line: %d\n",__FUNCTION__,__LINE__); + ctx->isPlaying = false; } - if(libvlc == NULL) { - _putenv("VLC_PLUGIN_PATH=c:\\program files\\videolan\\vlc\\plugins"); - - if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); - libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); - } - if(libvlc == NULL) { - _putenv("VLC_PLUGIN_PATH=\\program files\\videolan\\vlc\\plugins"); - - if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); - libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); - } - if(libvlc == NULL) { - _putenv("VLC_PLUGIN_PATH=c:\\program files (x86)\\videolan\\vlc\\plugins"); - - if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); - libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); - } - if(libvlc == NULL) { - _putenv("VLC_PLUGIN_PATH=\\program files (x86)\\videolan\\vlc\\plugins"); - - if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); - libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); - } - } -#endif -*/ - - if(ctxPtr->libvlc != NULL) { -#if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) - ctxPtr->m = libvlc_media_new(ctxPtr->libvlc, mediaURL.c_str(), &ex); - if(verboseEnabled) printf("In [%s] Line: %d, m [%p]\n",__FUNCTION__,__LINE__,ctxPtr->m); - - catchError(&ex); - ctxPtr->mp = libvlc_media_player_new_from_media(ctxPtr->m); - if(verboseEnabled) printf("In [%s] Line: %d, mp [%p]\n",__FUNCTION__,__LINE__,ctxPtr->mp); - - libvlc_media_release(ctxPtr->m); -#else - if(mediaURL.find(HTTP_PREFIX) == 0) { - ctxPtr->mlp = libvlc_media_list_player_new(ctxPtr->libvlc); - ctxPtr->ml = libvlc_media_list_new(ctxPtr->libvlc); - ctxPtr->m = libvlc_media_new_location(ctxPtr->libvlc, mediaURL.c_str()); - - libvlc_media_list_add_media(ctxPtr->ml, ctxPtr->m); - } - else { - ctxPtr->m = libvlc_media_new_path(ctxPtr->libvlc, mediaURL.c_str()); + void trapBufferingEvent(const libvlc_event_t *evt, void *data) { + class ctx *ctx = (class ctx *)data; + if(ctx->verboseEnabled) printf("In [%s] Line: %d\n",__FUNCTION__,__LINE__); + ctx->isPlaying = true; } - /* Create a new item */ - if(verboseEnabled) printf("In [%s] Line: %d, m [%p]\n",__FUNCTION__,__LINE__,ctxPtr->m); - - if(loop == true) { - libvlc_media_add_option(ctxPtr->m, "input-repeat=-1"); + void trapErrorEvent(const libvlc_event_t *evt, void *data) { + class ctx *ctx = (class ctx *)data; + if(ctx->verboseEnabled) printf("In [%s] Line: %d\n",__FUNCTION__,__LINE__); + ctx->isPlaying = false; } + */ + void callbacks(const libvlc_event_t* event, void* data) { + class ctx *ctx = (class ctx *)data; + if (ctx->verboseEnabled) printf("In [%s] Line: %d event [%d]\n", __FUNCTION__, __LINE__, event->type); + switch (event->type) { + case libvlc_MediaPlayerPlaying: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerPlaying\n"); + ctx->end_of_media = false; + ctx->error = false; + ctx->stopped = false; + ctx->isPlaying = true; + ctx->started = true; - if(mediaURL.find(HTTP_PREFIX) == 0) { - ctxPtr->mp = libvlc_media_player_new(ctxPtr->libvlc); - } - else { - ctxPtr->mp = libvlc_media_player_new_from_media(ctxPtr->m); - } - if(verboseEnabled) printf("In [%s] Line: %d, mp [%p]\n",__FUNCTION__,__LINE__,ctxPtr->mp); - - libvlc_media_player_set_media(ctxPtr->mp, ctxPtr->m); - - libvlc_media_release(ctxPtr->m); - - if(mediaURL.find(HTTP_PREFIX) == 0) { - // Use our media list - libvlc_media_list_player_set_media_list(ctxPtr->mlp, ctxPtr->ml); - - // Use a given media player - libvlc_media_list_player_set_media_player(ctxPtr->mlp, ctxPtr->mp); - } - - // Get an event manager for the media player. - if(mediaURL.find(HTTP_PREFIX) == 0) { - libvlc_event_manager_t *eventManager = libvlc_media_list_player_event_manager(ctxPtr->mlp); - - if(eventManager) { -// libvlc_event_attach(eventManager, libvlc_MediaPlayerPlaying, (libvlc_callback_t)trapPlayingEvent, NULL, &ex); -// libvlc_event_attach(eventManager, libvlc_MediaPlayerEndReached, (libvlc_callback_t)trapEndReachedEvent, NULL, &ex); -// libvlc_event_attach(eventManager, libvlc_MediaPlayerBuffering, (libvlc_callback_t)trapBufferingEvent, NULL, &ex); -// libvlc_event_attach(eventManager, libvlc_MediaPlayerEncounteredError, (libvlc_callback_t)trapErrorEvent, NULL, &ex); - - int event_added = libvlc_event_attach( eventManager, libvlc_MediaListPlayerNextItemSet, callbacks, ctxPtr ); - if(event_added != 0) { - printf("ERROR CANNOT ADD EVENT [libvlc_MediaListPlayerNextItemSet]\n"); - } - } - } - //else { - //libvlc_event_manager_t *eventManager = libvlc_media_player_event_manager(mp, &ex); - libvlc_event_manager_t *eventManager = libvlc_media_player_event_manager(ctxPtr->mp); - if(eventManager) { - int event_added = libvlc_event_attach( eventManager, libvlc_MediaPlayerSnapshotTaken, callbacks, ctxPtr ); - if(event_added != 0) { - printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerSnapshotTaken]\n"); - } -// event_added = libvlc_event_attach( eventManager, libvlc_MediaPlayerTimeChanged, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerTimeChanged]\n"); -// } - - event_added = libvlc_event_attach( eventManager, libvlc_MediaPlayerPlaying, callbacks, ctxPtr ); - if(event_added != 0) { - printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerPlaying]\n"); - } - - event_added = libvlc_event_attach( eventManager, libvlc_MediaPlayerPaused, callbacks, ctxPtr ); - if(event_added != 0) { - printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerPaused]\n"); - } - - event_added = libvlc_event_attach( eventManager, libvlc_MediaPlayerStopped, callbacks, ctxPtr ); - if(event_added != 0) { - printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerStopped]\n"); - } - - event_added = libvlc_event_attach( eventManager, libvlc_MediaPlayerEndReached, callbacks, ctxPtr ); - if(event_added != 0) { - printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerEndReached]\n"); - } - - event_added = libvlc_event_attach( eventManager, libvlc_MediaPlayerPositionChanged, callbacks, ctxPtr ); - if(event_added != 0) { - printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerPositionChanged]\n"); - } - - event_added = libvlc_event_attach( eventManager, libvlc_MediaPlayerLengthChanged, callbacks, ctxPtr ); - if(event_added != 0) { - printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerLengthChanged]\n"); - } - - event_added = libvlc_event_attach( eventManager, libvlc_MediaPlayerEncounteredError,callbacks, ctxPtr ); - if(event_added != 0) { - printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerEncounteredError]\n"); - } - - event_added = libvlc_event_attach( eventManager, libvlc_MediaPlayerPausableChanged, callbacks, ctxPtr ); - if(event_added != 0) { - printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerPausableChanged]\n"); - } - - event_added = libvlc_event_attach( eventManager, libvlc_MediaPlayerSeekableChanged, callbacks, ctxPtr ); - if(event_added != 0) { - printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerSeekableChanged]\n"); - } - -// event_added = libvlc_event_attach( eventManager, libvlc_MediaStateChanged, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaStateChanged]\n"); -// } - -// event_added = libvlc_event_attach( eventManager, libvlc_MediaParsedChanged, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaParsedChanged]\n"); -// } - -#if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) - event_added = libvlc_event_attach( eventManager, libvlc_MediaPlayerVout, callbacks, ctxPtr ); - if(event_added != 0) { - printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerVout]\n"); - } -#endif - -// event_added = libvlc_event_attach( eventManager, libvlc_MediaListItemAdded, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaListItemAdded]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_MediaListWillAddItem, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaListWillAddItem]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_MediaListItemDeleted, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaListItemDeleted]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_MediaListWillDeleteItem, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaListWillDeleteItem]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_MediaListViewItemAdded, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaListViewItemAdded]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_MediaListViewWillAddItem, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaListViewWillAddItem]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_MediaListViewItemDeleted, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaListViewItemDeleted]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_MediaListViewWillDeleteItem, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaListViewWillDeleteItem]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_MediaListPlayerPlayed, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaListPlayerPlayed]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_MediaListPlayerNextItemSet, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaListPlayerNextItemSet]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_MediaListPlayerStopped, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaListPlayerStopped]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_MediaDiscovererStarted, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaDiscovererStarted]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_MediaDiscovererEnded, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_MediaDiscovererEnded]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaAdded, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaAdded]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaRemoved, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaRemoved]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaChanged, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaChanged]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStarted, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStarted]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStopped, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStopped]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStatusInit, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStatusInit]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStatusOpening, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStatusOpening]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStatusPlaying, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStatusPlaying]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStatusPause, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStatusPause]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStatusEnd, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStatusEnd]\n"); -// } -// -// event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStatusError, callbacks, ctxPtr ); -// if(event_added != 0) { -// printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStatusError]\n"); -// } - - } - //} - - //libvlc_media_release(ctxPtr->m); -#endif - - -#if !defined(LIBVLC_VERSION_PRE_2) && !defined(LIBVLC_VERSION_PRE_1_1_0) - libvlc_video_set_callbacks(ctxPtr->mp, lock, unlock, display, ctxPtr); - libvlc_video_set_format(ctxPtr->mp, "RV16", width, height, SDL_GetWindowSurface(this->window)->pitch); - -#endif - - ctxPtr->isPlaying = true; - -#if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) - int play_result = libvlc_media_player_play(ctxPtr->mp,&ex); -#else - int play_result = 0; - if(mediaURL.find(HTTP_PREFIX) == 0) { - libvlc_media_list_player_play(ctxPtr->mlp); - } - else { - play_result = libvlc_media_player_play(ctxPtr->mp); - } - // Play - //int play_result = 0; - //libvlc_media_list_player_play(ctxPtr->mlp); -#endif - - //SDL_Delay(5); - if(verboseEnabled) printf("In [%s] Line: %d, play_result [%d]\n",__FUNCTION__,__LINE__,play_result); - - successLoadingLib = (play_result == 0); - - } -#endif - - return successLoadingLib; -} - -bool VideoPlayer::initPlayer() { - if(VideoPlayer::disabled == true) { - return true; - } - -#ifdef HAS_LIBVLC - - bool result = initPlayer(this->filename); - if(result == true) { - time_t waitStart = time(NULL); - for(;difftime(time(NULL),waitStart) <= MAX_VIDEO_START_MILLISECONDS && - successLoadingLib == true && - (ctxPtr->error == false || ctxPtr->stopped == false) && - ctxPtr->started == false;) { - if(ctxPtr->started == true) { - break; - } - if(this->loadingCB != NULL) { - int progress = (int)((difftime(time(NULL),waitStart) / MAX_VIDEO_START_MILLISECONDS) * 100.0); - this->loadingCB->renderVideoLoading(progress); - } - SDL_Delay(0); - } - } - - if(isPlaying() == false && this->filenameFallback != "") { - closePlayer(); - cleanupPlayer(); - - init(); - - result = initPlayer(this->filenameFallback); - if(result == true) { - time_t waitStart = time(NULL); - for(;difftime(time(NULL),waitStart) <= MAX_VIDEO_START_MILLISECONDS && - successLoadingLib == true && - (ctxPtr->error == false || ctxPtr->stopped == false) && - ctxPtr->started == false;) { - if(ctxPtr->started == true) { break; - } - if(this->loadingCB != NULL) { - int progress = (int)((difftime(time(NULL),waitStart) / MAX_VIDEO_START_MILLISECONDS) * 100.0); - this->loadingCB->renderVideoLoading(progress); - } - SDL_Delay(0); + case libvlc_MediaPlayerPaused: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerPaused\n"); + break; + case libvlc_MediaPlayerStopped: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerStopped\n"); + ctx->stopped = true; + + break; + case libvlc_MediaPlayerEndReached: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerEndReached\n"); + if (ctx->started == true && ctx->error == false) { + ctx->isPlaying = false; + } + + ctx->end_of_media = true; + + break; + case libvlc_MediaPlayerTimeChanged: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerTimeChanged\n"); + break; + case libvlc_MediaPlayerPositionChanged: + //qDebug() << self << "position changed : " << event->u.media_player_position_changed.new_position; + //self->emit positionChanged( event->u.media_player_position_changed.new_position ); + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerPositionChanged\n"); + break; + case libvlc_MediaPlayerLengthChanged: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerLengthChanged\n"); + break; + case libvlc_MediaPlayerSnapshotTaken: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerSnapshotTaken\n"); + break; + case libvlc_MediaPlayerEncounteredError: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerEncounteredError\n"); + if (ctx->started == false) { + ctx->isPlaying = false; + } + ctx->error = true; + + + break; + case libvlc_MediaPlayerSeekableChanged: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerSeekableChanged\n"); + break; + case libvlc_MediaPlayerPausableChanged: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerPausableChanged\n"); + break; + case libvlc_MediaPlayerTitleChanged: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerTitleChanged\n"); + break; + case libvlc_MediaPlayerNothingSpecial: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerNothingSpecial\n"); + break; + case libvlc_MediaPlayerOpening: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerOpening\n"); + break; + case libvlc_MediaPlayerBuffering: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerBuffering\n"); + break; + case libvlc_MediaPlayerForward: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerForward\n"); + break; + case libvlc_MediaPlayerBackward: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerBackward\n"); + break; + case libvlc_MediaStateChanged: + if (ctx->verboseEnabled) printf("libvlc_MediaStateChanged\n"); + break; + case libvlc_MediaParsedChanged: + if (ctx->verboseEnabled) printf("libvlc_MediaParsedChanged\n"); + break; + +#if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) + case libvlc_MediaPlayerVout: + if (ctx->verboseEnabled) printf("libvlc_MediaPlayerVout\n"); + break; +#endif + case libvlc_MediaListItemAdded: + if (ctx->verboseEnabled) printf("libvlc_MediaListItemAdded\n"); + break; + case libvlc_MediaListWillAddItem: + if (ctx->verboseEnabled) printf("libvlc_MediaListWillAddItem\n"); + break; + case libvlc_MediaListItemDeleted: + if (ctx->verboseEnabled) printf("libvlc_MediaListItemDeleted\n"); + break; + case libvlc_MediaListWillDeleteItem: + if (ctx->verboseEnabled) printf("libvlc_MediaListWillDeleteItem\n"); + break; + case libvlc_MediaListViewItemAdded: + if (ctx->verboseEnabled) printf("libvlc_MediaListViewItemAdded\n"); + break; + case libvlc_MediaListViewWillAddItem: + if (ctx->verboseEnabled) printf("libvlc_MediaListViewWillAddItem\n"); + break; + case libvlc_MediaListViewItemDeleted: + if (ctx->verboseEnabled) printf("libvlc_MediaListViewItemDeleted\n"); + break; + case libvlc_MediaListViewWillDeleteItem: + if (ctx->verboseEnabled) printf("libvlc_MediaListViewWillDeleteItem\n"); + break; + case libvlc_MediaListPlayerPlayed: + if (ctx->verboseEnabled) printf("libvlc_MediaListPlayerPlayed\n"); + break; + case libvlc_MediaListPlayerNextItemSet: + if (ctx->verboseEnabled) printf("libvlc_MediaListPlayerNextItemSet\n"); + //ctx->isPlaying = true; + //ctx->started = true; + ctx->end_of_media = false; + ctx->error = false; + ctx->stopped = false; + + break; + case libvlc_MediaListPlayerStopped: + if (ctx->verboseEnabled) printf("libvlc_MediaListPlayerStopped\n"); + ctx->stopped = true; + + break; + + case libvlc_MediaDiscovererStarted: + if (ctx->verboseEnabled) printf("libvlc_MediaDiscovererStarted\n"); + break; + case libvlc_MediaDiscovererEnded: + if (ctx->verboseEnabled) printf("libvlc_MediaDiscovererEndedvvvvvvvvv\n"); + break; + case libvlc_VlmMediaAdded: + if (ctx->verboseEnabled) printf("libvlc_VlmMediaAdded\n"); + break; + case libvlc_VlmMediaRemoved: + if (ctx->verboseEnabled) printf("libvlc_VlmMediaRemoved\n"); + break; + case libvlc_VlmMediaChanged: + if (ctx->verboseEnabled) printf("libvlc_VlmMediaChanged\n"); + break; + case libvlc_VlmMediaInstanceStarted: + if (ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStarted\n"); + break; + case libvlc_VlmMediaInstanceStopped: + if (ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStopped\n"); + ctx->stopped = true; + + break; + case libvlc_VlmMediaInstanceStatusInit: + if (ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStatusInit\n"); + break; + case libvlc_VlmMediaInstanceStatusOpening: + if (ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStatusOpening\n"); + break; + case libvlc_VlmMediaInstanceStatusPlaying: + if (ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStatusPlaying\n"); + break; + case libvlc_VlmMediaInstanceStatusPause: + if (ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStatusPause\n"); + break; + case libvlc_VlmMediaInstanceStatusEnd: + if (ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStatusEnd\n"); + break; + case libvlc_VlmMediaInstanceStatusError: + if (ctx->verboseEnabled) printf("libvlc_VlmMediaInstanceStatusError\n"); + break; + + default: + // qDebug() << "Unknown mediaPlayerEvent: " << event->type; + break; } } - } #endif - return successLoadingLib; -} + VideoPlayer::VideoPlayer(VideoLoadingCallbackInterface *loadingCB, + string filename, + string filenameFallback, + SDL_Window *window, + int x, int y, int width, int height, int colorBits, + bool loop, string pluginsPath, bool verboseEnabled) + : ctxPtr(NULL) { + + this->loadingCB = loadingCB; + this->filename = filename; + this->filenameFallback = filenameFallback; + this->window = window; + this->x = x; + this->y = y; + this->width = width; + this->height = height; + this->colorBits = colorBits; + this->loop = loop; + this->pluginsPath = pluginsPath; + //this->verboseEnabled = true; + this->verboseEnabled = verboseEnabled; + this->stop = false; + this->finished = false; + this->successLoadingLib = false; + + init(); + } + + void VideoPlayer::init() { + if (VideoPlayer::disabled == true) { + return; + } + cleanupPlayer(); + ctxPtr = new ctx(); + ctxPtr->loadingCB = loadingCB; + ctxPtr->x = x; + ctxPtr->y = y; + ctxPtr->width = width; + ctxPtr->height = height; + ctxPtr->rawData = (void *) malloc(width * height * 4); + ctxPtr->verboseEnabled = verboseEnabled; + } + + VideoPlayer::~VideoPlayer() { + cleanupPlayer(); + } + + bool VideoPlayer::hasBackEndVideoPlayer() { + if (VideoPlayer::disabled == true) { + return false; + } -void VideoPlayer::closePlayer() { #ifdef HAS_LIBVLC - if(ctxPtr != NULL && ctxPtr->libvlc != NULL) { - // - // Stop stream and clean up libVLC - // -#if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) - libvlc_media_player_stop(ctxPtr->mp,&ex); - catchError(&ex); + return true; #else - libvlc_media_player_stop(ctxPtr->mp); + return false; #endif - if(ctxPtr->mlp != NULL) { - libvlc_media_list_player_release(ctxPtr->mlp); - ctxPtr->mlp = NULL; - } - libvlc_media_player_release(ctxPtr->mp); - ctxPtr->mp = NULL; - libvlc_release(ctxPtr->libvlc); - } -#endif - - // - // Close window and clean up libSDL - // - if(ctxPtr != NULL) { - if(ctxPtr->mutex != NULL) { - SDL_DestroyMutex(ctxPtr->mutex); - } - if(ctxPtr->surf != NULL) { - SDL_FreeSurface(ctxPtr->surf); - } - if(ctxPtr->empty != NULL) { - SDL_FreeSurface(ctxPtr->empty); } - glDeleteTextures(1, &ctxPtr->textureId); + void VideoPlayer::cleanupPlayer() { + if (ctxPtr != NULL) { + if (ctxPtr->rawData != NULL) { + free(ctxPtr->rawData); + ctxPtr->rawData = NULL; + } - if(ctxPtr->needToQuit == true) { - SDL_Event quit_event = {SDL_QUIT}; - SDL_PushEvent(&quit_event); + delete ctxPtr; + ctxPtr = NULL; + } } - } -} -void VideoPlayer::PlayVideo() { - if(VideoPlayer::disabled == true) { - return; - } + bool VideoPlayer::initPlayer(string mediaURL) { + if (VideoPlayer::disabled == true) { + return true; + } -/* #ifdef HAS_LIBVLC - libvlc_instance_t *libvlc = NULL; - libvlc_media_t *m = NULL; - libvlc_media_player_t *mp = NULL; + ctxPtr->libvlc = NULL; + ctxPtr->m = NULL; + ctxPtr->mp = NULL; + ctxPtr->vlc_argv.clear(); + ctxPtr->vlc_argv.push_back("--intf=dummy"); + //ctxPtr->vlc_argv.push_back("--intf=http"); + //ctxPtr->vlc_argv.push_back("--no-media-library"); + ctxPtr->vlc_argv.push_back("--ignore-config"); /* Don't use VLC's config */ + ctxPtr->vlc_argv.push_back("--no-xlib"); /* tell VLC to not use Xlib */ + ctxPtr->vlc_argv.push_back("--no-video-title-show"); + //ctxPtr->vlc_argv.push_back("--network-caching=10000"); -// string pluginParam = ""; -// if(pluginsPath != "") { -// pluginParam = "--plugin-path=" + pluginsPath; -// } + if (loop == true) { + ctxPtr->vlc_argv.push_back("--loop"); + ctxPtr->vlc_argv.push_back("--repeat"); + } - std::vector vlc_argv; - vlc_argv.push_back("--intf=dummy"); - vlc_argv.push_back("--no-media-library"); - vlc_argv.push_back("--ignore-config"); // Don't use VLC's config - vlc_argv.push_back("--no-xlib"); // tell VLC to not use Xlib - vlc_argv.push_back("--no-video-title-show"); #if defined(LIBVLC_VERSION_PRE_2) - string fullPluginsParam = "--plugin-path=" + pluginsPath; - vlc_argv.push_back(fullPluginsParam.c_str()); + ctxPtr->vlc_argv_str.push_back("--plugin-path=" + pluginsPath); + ctxPtr->vlc_argv.push_back(ctxPtr->vlc_argv_str[ctxPtr->vlc_argv_str.size() - 1].c_str()); #endif #if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) - char clock[64], cunlock[64], cdata[64]; - char cwidth[32], cheight[32], cpitch[32]; - // - // Initialise libVLC - // - sprintf(clock, "%lld", (long long int)(intptr_t)lock); - sprintf(cunlock, "%lld", (long long int)(intptr_t)unlock); - sprintf(cdata, "%lld", (long long int)(intptr_t)ctxPtr); - sprintf(cwidth, "%i", width); - sprintf(cheight, "%i", height); - sprintf(cpitch, "%i", colorBits); + char clock[64], cunlock[64], cdata[64]; + char cwidth[32], cheight[32], cpitch[32]; + /* + * Initialise libVLC + */ + sprintf(clock, "%lld", (long long int)(intptr_t)lock); + sprintf(cunlock, "%lld", (long long int)(intptr_t)unlock); + sprintf(cdata, "%lld", (long long int)(intptr_t)ctxPtr); + sprintf(cwidth, "%i", width); + sprintf(cheight, "%i", height); + sprintf(cpitch, "%i", colorBits); - vlc_argv.push_back("--vout"); - vlc_argv.push_back("vmem"); - vlc_argv.push_back("--vmem-width"); - vlc_argv.push_back(cwidth); - vlc_argv.push_back("--vmem-height"); - vlc_argv.push_back(cheight); - vlc_argv.push_back("--vmem-pitch"); - vlc_argv.push_back(cpitch); - vlc_argv.push_back("--vmem-chroma"); - vlc_argv.push_back("RV16"); - vlc_argv.push_back("--vmem-lock"); - vlc_argv.push_back(clock); - vlc_argv.push_back("--vmem-unlock"); - vlc_argv.push_back(cunlock); - vlc_argv.push_back("--vmem-data"); - vlc_argv.push_back(cdata); + vlc_argv.push_back("--vout"); + vlc_argv.push_back("vmem"); + vlc_argv.push_back("--vmem-width"); + ctxPtr->vlc_argv_str.push_back(cwidth); + ctxPtr->vlc_argv.push_back(ctxPtr->vlc_argv_str[ctxPtr->vlc_argv_str.size() - 1].c_str()); + vlc_argv.push_back("--vmem-height"); + ctxPtr->vlc_argv_str.push_back(cheight); + ctxPtr->vlc_argv.push_back(ctxPtr->vlc_argv_str[ctxPtr->vlc_argv_str.size() - 1].c_str()); + vlc_argv.push_back("--vmem-pitch"); + ctxPtr->vlc_argv_str.push_back(cpitch); + ctxPtr->vlc_argv.push_back(ctxPtr->vlc_argv_str[ctxPtr->vlc_argv_str.size() - 1].c_str()); + vlc_argv.push_back("--vmem-chroma"); + vlc_argv.push_back("RV16"); + vlc_argv.push_back("--vmem-lock"); + ctxPtr->vlc_argv_str.push_back(clock); + ctxPtr->vlc_argv.push_back(ctxPtr->vlc_argv_str[ctxPtr->vlc_argv_str.size() - 1].c_str()); + vlc_argv.push_back("--vmem-unlock"); + ctxPtr->vlc_argv_str.push_back(cunlock); + ctxPtr->vlc_argv.push_back(ctxPtr->vlc_argv_str[ctxPtr->vlc_argv_str.size() - 1].c_str()); + vlc_argv.push_back("--vmem-data"); + ctxPtr->vlc_argv_str.push_back(cdata); + ctxPtr->vlc_argv.push_back(ctxPtr->vlc_argv_str[ctxPtr->vlc_argv_str.size() - 1].c_str()); #endif - if(verboseEnabled) vlc_argv.push_back("--verbose=2"); - if(verboseEnabled) vlc_argv.push_back("--extraintf=logger"); //log anything + if (verboseEnabled) ctxPtr->vlc_argv.push_back("--verbose=2"); + if (verboseEnabled) ctxPtr->vlc_argv.push_back("--extraintf=logger"); //log anything #if defined(WIN32) - if(verboseEnabled) _putenv("VLC_VERBOSE=2"); -#endif - int vlc_argc = vlc_argv.size(); - -// char const *vlc_argv[] = -// { -// //"--no-audio", // skip any audio track -// "--no-xlib", // tell VLC to not use Xlib -// "--no-video-title-show", -// pluginParam.c_str(), -// }; -// int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); + if (verboseEnabled) _putenv("VLC_VERBOSE=2"); #endif - SDL_Surface *empty = NULL; - glEnable(GL_TEXTURE_2D); - glEnable(GL_DEPTH_TEST); - // Init Texture - glGenTextures(1, &ctxPtr->textureId); - glBindTexture(GL_TEXTURE_2D, ctxPtr->textureId); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - empty = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, - colorBits, 0, 0, 0, 0); - ctxPtr->surf = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, - colorBits, 0x001f, 0x07e0, 0xf800, 0); - ctxPtr->mutex = SDL_CreateMutex(); + // char const *vlc_argv[] = + // { + // //"--no-audio", /* skip any audio track */ + // "--no-xlib", /* tell VLC to not use Xlib */ + // "--no-video-title-show", + // pluginParam.c_str(), + // }; + // int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); +#endif + + ctxPtr->empty = NULL; + glEnable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); + // Init Texture + glGenTextures(1, &ctxPtr->textureId); + glBindTexture(GL_TEXTURE_2D, ctxPtr->textureId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + ctxPtr->empty = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, + colorBits, 0, 0, 0, 0); + ctxPtr->surf = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, + colorBits, 0x001f, 0x07e0, 0xf800, 0); + ctxPtr->mutex = SDL_CreateMutex(); #ifdef HAS_LIBVLC - // - // Initialize libVLC - // - if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); + /* + * Initialize libVLC + */ + if (verboseEnabled) printf("Trying [%s]\n", getenv("VLC_PLUGIN_PATH")); #if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) - libvlc_exception_t ex; - libvlc_exception_init(&ex); + libvlc_exception_t ex; + libvlc_exception_init(&ex); - libvlc = libvlc_new(vlc_argc, &vlc_argv[0],&ex); - catchError(&ex); + ctxPtr->libvlc = libvlc_new(ctxPtr->vlc_argc, &ctxPtr->vlc_argv[0], &ex); + catchError(&ex); #else - libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); + int vlc_argc = ctxPtr->vlc_argv.size(); + ctxPtr->libvlc = libvlc_new(vlc_argc, &ctxPtr->vlc_argv[0]); #endif - if(verboseEnabled) printf("In [%s] Line: %d, libvlc [%p]\n",__FUNCTION__,__LINE__,libvlc); + if (verboseEnabled) printf("In [%s] Line: %d, libvlc [%p]\n", __FUNCTION__, __LINE__, ctxPtr->libvlc); -// It is meaningless to try all this because we have to restart mg to pickup new env vars -#if defined(WIN32) - if(libvlc == NULL) { - // For windows check registry for install path - std::string strValue = getRegKey("Software\\VideoLAN\\VLC", "InstallDir"); - if(strValue != "") { - if(strValue.length() >= 2) { - if(strValue[0] == '"') { - strValue = strValue.erase(0); + /* It is meaningless to try all this because we have to restart mg to pickup new env vars + #if defined(WIN32) + if(libvlc == NULL) { + // For windows check registry for install path + std::string strValue = getRegKey("Software\\VideoLAN\\VLC", "InstallDir"); + if(strValue != "") { + if(strValue.length() >= 2) { + if(strValue[0] == '"') { + strValue = strValue.erase(0); + } + if(strValue[strValue.length()-1] == '"') { + strValue = strValue.erase(strValue.length()-1); + } + } + strValue = "VLC_PLUGIN_PATH=" + strValue; + _putenv(strValue.c_str()); + + if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); + libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); + } + + if(libvlc == NULL) { + _putenv("VLC_PLUGIN_PATH=c:\\program files\\videolan\\vlc\\plugins"); + + if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); + libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); + } + if(libvlc == NULL) { + _putenv("VLC_PLUGIN_PATH=\\program files\\videolan\\vlc\\plugins"); + + if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); + libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); + } + if(libvlc == NULL) { + _putenv("VLC_PLUGIN_PATH=c:\\program files (x86)\\videolan\\vlc\\plugins"); + + if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); + libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); + } + if(libvlc == NULL) { + _putenv("VLC_PLUGIN_PATH=\\program files (x86)\\videolan\\vlc\\plugins"); + + if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); + libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); + } } - if(strValue[strValue.length()-1] == '"') { - strValue = strValue.erase(strValue.length()-1); - } - } - strValue = "VLC_PLUGIN_PATH=" + strValue; - _putenv(strValue.c_str()); + #endif + */ - if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); - libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); - } - - if(libvlc == NULL) { - _putenv("VLC_PLUGIN_PATH=c:\\program files\\videolan\\vlc\\plugins"); - - if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); - libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); - } - if(libvlc == NULL) { - _putenv("VLC_PLUGIN_PATH=\\program files\\videolan\\vlc\\plugins"); - - if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); - libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); - } - if(libvlc == NULL) { - _putenv("VLC_PLUGIN_PATH=c:\\program files (x86)\\videolan\\vlc\\plugins"); - - if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); - libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); - } - if(libvlc == NULL) { - _putenv("VLC_PLUGIN_PATH=\\program files (x86)\\videolan\\vlc\\plugins"); - - if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); - libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); - } - } -#endif -// - - if(libvlc != NULL) { + if (ctxPtr->libvlc != NULL) { #if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) - m = libvlc_media_new(libvlc, filename.c_str(), &ex); - if(verboseEnabled) printf("In [%s] Line: %d, m [%p]\n",__FUNCTION__,__LINE__,m); + ctxPtr->m = libvlc_media_new(ctxPtr->libvlc, mediaURL.c_str(), &ex); + if (verboseEnabled) printf("In [%s] Line: %d, m [%p]\n", __FUNCTION__, __LINE__, ctxPtr->m); - catchError(&ex); - mp = libvlc_media_player_new_from_media(m); - if(verboseEnabled) printf("In [%s] Line: %d, mp [%p]\n",__FUNCTION__,__LINE__,mp); + catchError(&ex); + ctxPtr->mp = libvlc_media_player_new_from_media(ctxPtr->m); + if (verboseEnabled) printf("In [%s] Line: %d, mp [%p]\n", __FUNCTION__, __LINE__, ctxPtr->mp); + + libvlc_media_release(ctxPtr->m); #else - // Create a new item - m = libvlc_media_new_path(libvlc, filename.c_str()); - if(verboseEnabled) printf("In [%s] Line: %d, m [%p]\n",__FUNCTION__,__LINE__,m); + if (mediaURL.find(HTTP_PREFIX) == 0) { + ctxPtr->mlp = libvlc_media_list_player_new(ctxPtr->libvlc); + ctxPtr->ml = libvlc_media_list_new(ctxPtr->libvlc); + ctxPtr->m = libvlc_media_new_location(ctxPtr->libvlc, mediaURL.c_str()); - mp = libvlc_media_player_new_from_media(m); - if(verboseEnabled) printf("In [%s] Line: %d, mp [%p]\n",__FUNCTION__,__LINE__,mp); + libvlc_media_list_add_media(ctxPtr->ml, ctxPtr->m); + } else { + ctxPtr->m = libvlc_media_new_path(ctxPtr->libvlc, mediaURL.c_str()); + } + + /* Create a new item */ + if (verboseEnabled) printf("In [%s] Line: %d, m [%p]\n", __FUNCTION__, __LINE__, ctxPtr->m); + + if (loop == true) { + libvlc_media_add_option(ctxPtr->m, "input-repeat=-1"); + } + + if (mediaURL.find(HTTP_PREFIX) == 0) { + ctxPtr->mp = libvlc_media_player_new(ctxPtr->libvlc); + } else { + ctxPtr->mp = libvlc_media_player_new_from_media(ctxPtr->m); + } + if (verboseEnabled) printf("In [%s] Line: %d, mp [%p]\n", __FUNCTION__, __LINE__, ctxPtr->mp); + + libvlc_media_player_set_media(ctxPtr->mp, ctxPtr->m); + + libvlc_media_release(ctxPtr->m); + + if (mediaURL.find(HTTP_PREFIX) == 0) { + // Use our media list + libvlc_media_list_player_set_media_list(ctxPtr->mlp, ctxPtr->ml); + + // Use a given media player + libvlc_media_list_player_set_media_player(ctxPtr->mlp, ctxPtr->mp); + } + + // Get an event manager for the media player. + if (mediaURL.find(HTTP_PREFIX) == 0) { + libvlc_event_manager_t *eventManager = libvlc_media_list_player_event_manager(ctxPtr->mlp); + + if (eventManager) { + // libvlc_event_attach(eventManager, libvlc_MediaPlayerPlaying, (libvlc_callback_t)trapPlayingEvent, NULL, &ex); + // libvlc_event_attach(eventManager, libvlc_MediaPlayerEndReached, (libvlc_callback_t)trapEndReachedEvent, NULL, &ex); + // libvlc_event_attach(eventManager, libvlc_MediaPlayerBuffering, (libvlc_callback_t)trapBufferingEvent, NULL, &ex); + // libvlc_event_attach(eventManager, libvlc_MediaPlayerEncounteredError, (libvlc_callback_t)trapErrorEvent, NULL, &ex); + + int event_added = libvlc_event_attach(eventManager, libvlc_MediaListPlayerNextItemSet, callbacks, ctxPtr); + if (event_added != 0) { + printf("ERROR CANNOT ADD EVENT [libvlc_MediaListPlayerNextItemSet]\n"); + } + } + } + //else { + //libvlc_event_manager_t *eventManager = libvlc_media_player_event_manager(mp, &ex); + libvlc_event_manager_t *eventManager = libvlc_media_player_event_manager(ctxPtr->mp); + if (eventManager) { + int event_added = libvlc_event_attach(eventManager, libvlc_MediaPlayerSnapshotTaken, callbacks, ctxPtr); + if (event_added != 0) { + printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerSnapshotTaken]\n"); + } + // event_added = libvlc_event_attach( eventManager, libvlc_MediaPlayerTimeChanged, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerTimeChanged]\n"); + // } + + event_added = libvlc_event_attach(eventManager, libvlc_MediaPlayerPlaying, callbacks, ctxPtr); + if (event_added != 0) { + printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerPlaying]\n"); + } + + event_added = libvlc_event_attach(eventManager, libvlc_MediaPlayerPaused, callbacks, ctxPtr); + if (event_added != 0) { + printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerPaused]\n"); + } + + event_added = libvlc_event_attach(eventManager, libvlc_MediaPlayerStopped, callbacks, ctxPtr); + if (event_added != 0) { + printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerStopped]\n"); + } + + event_added = libvlc_event_attach(eventManager, libvlc_MediaPlayerEndReached, callbacks, ctxPtr); + if (event_added != 0) { + printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerEndReached]\n"); + } + + event_added = libvlc_event_attach(eventManager, libvlc_MediaPlayerPositionChanged, callbacks, ctxPtr); + if (event_added != 0) { + printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerPositionChanged]\n"); + } + + event_added = libvlc_event_attach(eventManager, libvlc_MediaPlayerLengthChanged, callbacks, ctxPtr); + if (event_added != 0) { + printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerLengthChanged]\n"); + } + + event_added = libvlc_event_attach(eventManager, libvlc_MediaPlayerEncounteredError, callbacks, ctxPtr); + if (event_added != 0) { + printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerEncounteredError]\n"); + } + + event_added = libvlc_event_attach(eventManager, libvlc_MediaPlayerPausableChanged, callbacks, ctxPtr); + if (event_added != 0) { + printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerPausableChanged]\n"); + } + + event_added = libvlc_event_attach(eventManager, libvlc_MediaPlayerSeekableChanged, callbacks, ctxPtr); + if (event_added != 0) { + printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerSeekableChanged]\n"); + } + + // event_added = libvlc_event_attach( eventManager, libvlc_MediaStateChanged, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaStateChanged]\n"); + // } + + // event_added = libvlc_event_attach( eventManager, libvlc_MediaParsedChanged, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaParsedChanged]\n"); + // } + +#if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) + event_added = libvlc_event_attach(eventManager, libvlc_MediaPlayerVout, callbacks, ctxPtr); + if (event_added != 0) { + printf("ERROR CANNOT ADD EVENT [libvlc_MediaPlayerVout]\n"); + } #endif - libvlc_media_release(m); + + // event_added = libvlc_event_attach( eventManager, libvlc_MediaListItemAdded, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaListItemAdded]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_MediaListWillAddItem, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaListWillAddItem]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_MediaListItemDeleted, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaListItemDeleted]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_MediaListWillDeleteItem, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaListWillDeleteItem]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_MediaListViewItemAdded, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaListViewItemAdded]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_MediaListViewWillAddItem, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaListViewWillAddItem]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_MediaListViewItemDeleted, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaListViewItemDeleted]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_MediaListViewWillDeleteItem, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaListViewWillDeleteItem]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_MediaListPlayerPlayed, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaListPlayerPlayed]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_MediaListPlayerNextItemSet, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaListPlayerNextItemSet]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_MediaListPlayerStopped, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaListPlayerStopped]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_MediaDiscovererStarted, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaDiscovererStarted]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_MediaDiscovererEnded, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_MediaDiscovererEnded]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaAdded, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaAdded]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaRemoved, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaRemoved]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaChanged, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaChanged]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStarted, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStarted]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStopped, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStopped]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStatusInit, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStatusInit]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStatusOpening, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStatusOpening]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStatusPlaying, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStatusPlaying]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStatusPause, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStatusPause]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStatusEnd, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStatusEnd]\n"); + // } + // + // event_added = libvlc_event_attach( eventManager, libvlc_VlmMediaInstanceStatusError, callbacks, ctxPtr ); + // if(event_added != 0) { + // printf("ERROR CANNOT ADD EVENT [libvlc_VlmMediaInstanceStatusError]\n"); + // } + + } + //} + + //libvlc_media_release(ctxPtr->m); +#endif + #if !defined(LIBVLC_VERSION_PRE_2) && !defined(LIBVLC_VERSION_PRE_1_1_0) - libvlc_video_set_callbacks(mp, lock, unlock, display, ctxPtr); - libvlc_video_set_format(mp, "RV16", width, height, this->window->pitch); + libvlc_video_set_callbacks(ctxPtr->mp, lock, unlock, display, ctxPtr); + libvlc_video_set_format(ctxPtr->mp, "RV16", width, height, SDL_GetWindowSurface(this->window)->pitch); - // Get an event manager for the media player. - //libvlc_event_manager_t *eventManager = libvlc_media_player_event_manager(mp, &ex); - libvlc_event_manager_t *eventManager = libvlc_media_player_event_manager(mp); - if(eventManager) { -// libvlc_event_attach(eventManager, libvlc_MediaPlayerPlaying, (libvlc_callback_t)trapPlayingEvent, NULL, &ex); -// libvlc_event_attach(eventManager, libvlc_MediaPlayerEndReached, (libvlc_callback_t)trapEndReachedEvent, NULL, &ex); -// libvlc_event_attach(eventManager, libvlc_MediaPlayerBuffering, (libvlc_callback_t)trapBufferingEvent, NULL, &ex); -// libvlc_event_attach(eventManager, libvlc_MediaPlayerEncounteredError, (libvlc_callback_t)trapErrorEvent, NULL, &ex); - libvlc_event_attach(eventManager, libvlc_MediaPlayerPlaying, (libvlc_callback_t)trapPlayingEvent, ctxPtr); - libvlc_event_attach(eventManager, libvlc_MediaPlayerEndReached, (libvlc_callback_t)trapEndReachedEvent, ctxPtr); - libvlc_event_attach(eventManager, libvlc_MediaPlayerBuffering, (libvlc_callback_t)trapBufferingEvent, ctxPtr); - libvlc_event_attach(eventManager, libvlc_MediaPlayerEncounteredError, (libvlc_callback_t)trapErrorEvent, ctxPtr); - } #endif - - ctxPtr->isPlaying = true; + + ctxPtr->isPlaying = true; + #if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) - int play_result = libvlc_media_player_play(mp,&ex); + int play_result = libvlc_media_player_play(ctxPtr->mp, &ex); #else - int play_result = libvlc_media_player_play(mp); + int play_result = 0; + if (mediaURL.find(HTTP_PREFIX) == 0) { + libvlc_media_list_player_play(ctxPtr->mlp); + } else { + play_result = libvlc_media_player_play(ctxPtr->mp); + } + // Play + //int play_result = 0; + //libvlc_media_list_player_play(ctxPtr->mlp); #endif //SDL_Delay(5); - if(verboseEnabled) printf("In [%s] Line: %d, play_result [%d]\n",__FUNCTION__,__LINE__,play_result); + if (verboseEnabled) printf("In [%s] Line: %d, play_result [%d]\n", __FUNCTION__, __LINE__, play_result); - successLoadingLib = (play_result == 0); - } + successLoadingLib = (play_result == 0); + + } #endif - // - / Main loop - // - //int done = 0, action = 0, pause = 0, n = 0; - bool needToQuit = false; - while(isPlaying() == true) { - needToQuit = playFrame(); - } + return successLoadingLib; + } + + bool VideoPlayer::initPlayer() { + if (VideoPlayer::disabled == true) { + return true; + } #ifdef HAS_LIBVLC - if(libvlc != NULL) { - // - / Stop stream and clean up libVLC - // -#if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) - libvlc_media_player_stop(mp,&ex); - catchError(&ex); -#else - libvlc_media_player_stop(mp); -#endif - libvlc_media_player_release(mp); - libvlc_release(libvlc); - } -#endif - // - / Close window and clean up libSDL - // - SDL_DestroyMutex(ctxPtr->mutex); - SDL_FreeSurface(ctxPtr->surf); - SDL_FreeSurface(empty); - - glDeleteTextures(1, &ctxPtr->textureId); - - if(needToQuit == true) { - SDL_Event quit_event = {SDL_QUIT}; - SDL_PushEvent(&quit_event); - } -*/ - - initPlayer(); - for(;isPlaying() == true;) { - playFrame(); - } - closePlayer(); -} - -bool VideoPlayer::isPlaying() const { - bool result = (successLoadingLib == true && - ctxPtr != NULL && ctxPtr->isPlaying == true && - //ctxPtr->error == false && + bool result = initPlayer(this->filename); + if (result == true) { + time_t waitStart = time(NULL); + for (; difftime(time(NULL), waitStart) <= MAX_VIDEO_START_MILLISECONDS && + successLoadingLib == true && (ctxPtr->error == false || ctxPtr->stopped == false) && - finished == false && stop == false); + ctxPtr->started == false;) { + if (ctxPtr->started == true) { + break; + } + if (this->loadingCB != NULL) { + int progress = (int) ((difftime(time(NULL), waitStart) / MAX_VIDEO_START_MILLISECONDS) * 100.0); + this->loadingCB->renderVideoLoading(progress); + } + SDL_Delay(0); + } + } - if(ctxPtr != NULL && ctxPtr->verboseEnabled) printf("isPlaying isPlaying = %d,error = %d, stopped = %d, end_of_media = %d\n",ctxPtr->isPlaying,ctxPtr->error,ctxPtr->stopped,ctxPtr->end_of_media); - return result; -} + if (isPlaying() == false && this->filenameFallback != "") { + closePlayer(); + cleanupPlayer(); -bool VideoPlayer::playFrame(bool swapBuffers) { - if(VideoPlayer::disabled == true) { - return false; - } + init(); - if(successLoadingLib == true && - ctxPtr != NULL && ctxPtr->isPlaying == true && - finished == false && stop == false) { + result = initPlayer(this->filenameFallback); + if (result == true) { + time_t waitStart = time(NULL); + for (; difftime(time(NULL), waitStart) <= MAX_VIDEO_START_MILLISECONDS && + successLoadingLib == true && + (ctxPtr->error == false || ctxPtr->stopped == false) && + ctxPtr->started == false;) { + if (ctxPtr->started == true) { + break; + } + if (this->loadingCB != NULL) { + int progress = (int) ((difftime(time(NULL), waitStart) / MAX_VIDEO_START_MILLISECONDS) * 100.0); + this->loadingCB->renderVideoLoading(progress); + } + SDL_Delay(0); + } + } + } - //int action = 0, pause = 0, n = 0; - //int action = 0, n = 0; - int action = 0; +#endif - SDL_Event event; - /* Keys: enter (fullscreen), space (pause), escape (quit) */ - //while( SDL_PollEvent( &event ) ) { - if( SDL_PollEvent( &event ) ) { - switch(event.type) { - case SDL_QUIT: - finished = true; - ctxPtr->needToQuit = true; - break; - case SDL_KEYDOWN: - action = event.key.keysym.sym; - break; - case SDL_MOUSEBUTTONDOWN: - finished = true; - break; + return successLoadingLib; + } + + void VideoPlayer::closePlayer() { +#ifdef HAS_LIBVLC + if (ctxPtr != NULL && ctxPtr->libvlc != NULL) { + // + // Stop stream and clean up libVLC + // +#if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) + libvlc_media_player_stop(ctxPtr->mp, &ex); + catchError(&ex); +#else + libvlc_media_player_stop(ctxPtr->mp); +#endif + if (ctxPtr->mlp != NULL) { + libvlc_media_list_player_release(ctxPtr->mlp); + ctxPtr->mlp = NULL; + } + libvlc_media_player_release(ctxPtr->mp); + ctxPtr->mp = NULL; + libvlc_release(ctxPtr->libvlc); + } +#endif + + // + // Close window and clean up libSDL + // + if (ctxPtr != NULL) { + if (ctxPtr->mutex != NULL) { + SDL_DestroyMutex(ctxPtr->mutex); + } + if (ctxPtr->surf != NULL) { + SDL_FreeSurface(ctxPtr->surf); + } + if (ctxPtr->empty != NULL) { + SDL_FreeSurface(ctxPtr->empty); + } + + glDeleteTextures(1, &ctxPtr->textureId); + + if (ctxPtr->needToQuit == true) { + SDL_Event quit_event = { SDL_QUIT }; + SDL_PushEvent(&quit_event); + } } } - if(finished == false && stop == false) { - switch(action) { - case SDLK_ESCAPE: - finished = true; - break; - case SDLK_RETURN: - //options ^= SDL_WINDOW_FULLSCREEN; - //screen = SDL_SetVideoMode(WIDTH, HEIGHT, 0, options); - finished = true; - break; - //case ' ': - // //pause = !pause; - // break; + void VideoPlayer::PlayVideo() { + if (VideoPlayer::disabled == true) { + return; } - //if(pause == 0) { - //n++; - //} + /* + #ifdef HAS_LIBVLC + libvlc_instance_t *libvlc = NULL; + libvlc_media_t *m = NULL; + libvlc_media_player_t *mp = NULL; - //assertGl(); + // string pluginParam = ""; + // if(pluginsPath != "") { + // pluginParam = "--plugin-path=" + pluginsPath; + // } - glPushAttrib(GL_ENABLE_BIT); + std::vector vlc_argv; + vlc_argv.push_back("--intf=dummy"); + vlc_argv.push_back("--no-media-library"); + vlc_argv.push_back("--ignore-config"); // Don't use VLC's config + vlc_argv.push_back("--no-xlib"); // tell VLC to not use Xlib + vlc_argv.push_back("--no-video-title-show"); + #if defined(LIBVLC_VERSION_PRE_2) + string fullPluginsParam = "--plugin-path=" + pluginsPath; + vlc_argv.push_back(fullPluginsParam.c_str()); + #endif - //glDisable(GL_LIGHTING); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); + #if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) + char clock[64], cunlock[64], cdata[64]; + char cwidth[32], cheight[32], cpitch[32]; + // + // Initialise libVLC + // + sprintf(clock, "%lld", (long long int)(intptr_t)lock); + sprintf(cunlock, "%lld", (long long int)(intptr_t)unlock); + sprintf(cdata, "%lld", (long long int)(intptr_t)ctxPtr); + sprintf(cwidth, "%i", width); + sprintf(cheight, "%i", height); + sprintf(cpitch, "%i", colorBits); - // Loading the texture - loadTexture(ctxPtr); + vlc_argv.push_back("--vout"); + vlc_argv.push_back("vmem"); + vlc_argv.push_back("--vmem-width"); + vlc_argv.push_back(cwidth); + vlc_argv.push_back("--vmem-height"); + vlc_argv.push_back(cheight); + vlc_argv.push_back("--vmem-pitch"); + vlc_argv.push_back(cpitch); + vlc_argv.push_back("--vmem-chroma"); + vlc_argv.push_back("RV16"); + vlc_argv.push_back("--vmem-lock"); + vlc_argv.push_back(clock); + vlc_argv.push_back("--vmem-unlock"); + vlc_argv.push_back(cunlock); + vlc_argv.push_back("--vmem-data"); + vlc_argv.push_back(cdata); - if(ctxPtr->x == -1 || ctxPtr->y == -1) { - glBegin(GL_QUADS); - glTexCoord2d(0, 1); - glVertex2f(-0.85f, 0.85f); - glTexCoord2d(1, 1); - glVertex2f(0.85f, 0.85f); - glTexCoord2d(1, 0); - glVertex2f(0.85f, -0.85f); - glTexCoord2d(0, 0); - glVertex2f(-0.85f, -0.85f); - glEnd(); + #endif + + if(verboseEnabled) vlc_argv.push_back("--verbose=2"); + if(verboseEnabled) vlc_argv.push_back("--extraintf=logger"); //log anything + #if defined(WIN32) + if(verboseEnabled) _putenv("VLC_VERBOSE=2"); + #endif + int vlc_argc = vlc_argv.size(); + + // char const *vlc_argv[] = + // { + // //"--no-audio", // skip any audio track + // "--no-xlib", // tell VLC to not use Xlib + // "--no-video-title-show", + // pluginParam.c_str(), + // }; + // int vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv); + #endif + + SDL_Surface *empty = NULL; + glEnable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); + // Init Texture + glGenTextures(1, &ctxPtr->textureId); + glBindTexture(GL_TEXTURE_2D, ctxPtr->textureId); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + empty = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, + colorBits, 0, 0, 0, 0); + ctxPtr->surf = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, + colorBits, 0x001f, 0x07e0, 0xf800, 0); + ctxPtr->mutex = SDL_CreateMutex(); + + #ifdef HAS_LIBVLC + // + // Initialize libVLC + // + if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); + + #if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) + libvlc_exception_t ex; + libvlc_exception_init(&ex); + + libvlc = libvlc_new(vlc_argc, &vlc_argv[0],&ex); + catchError(&ex); + #else + libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); + #endif + + if(verboseEnabled) printf("In [%s] Line: %d, libvlc [%p]\n",__FUNCTION__,__LINE__,libvlc); + + // It is meaningless to try all this because we have to restart mg to pickup new env vars + #if defined(WIN32) + if(libvlc == NULL) { + // For windows check registry for install path + std::string strValue = getRegKey("Software\\VideoLAN\\VLC", "InstallDir"); + if(strValue != "") { + if(strValue.length() >= 2) { + if(strValue[0] == '"') { + strValue = strValue.erase(0); + } + if(strValue[strValue.length()-1] == '"') { + strValue = strValue.erase(strValue.length()-1); + } + } + strValue = "VLC_PLUGIN_PATH=" + strValue; + _putenv(strValue.c_str()); + + if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); + libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); + } + + if(libvlc == NULL) { + _putenv("VLC_PLUGIN_PATH=c:\\program files\\videolan\\vlc\\plugins"); + + if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); + libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); + } + if(libvlc == NULL) { + _putenv("VLC_PLUGIN_PATH=\\program files\\videolan\\vlc\\plugins"); + + if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); + libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); + } + if(libvlc == NULL) { + _putenv("VLC_PLUGIN_PATH=c:\\program files (x86)\\videolan\\vlc\\plugins"); + + if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); + libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); + } + if(libvlc == NULL) { + _putenv("VLC_PLUGIN_PATH=\\program files (x86)\\videolan\\vlc\\plugins"); + + if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH")); + libvlc = libvlc_new(vlc_argc, &vlc_argv[0]); + } + } + #endif + // + + if(libvlc != NULL) { + #if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) + m = libvlc_media_new(libvlc, filename.c_str(), &ex); + if(verboseEnabled) printf("In [%s] Line: %d, m [%p]\n",__FUNCTION__,__LINE__,m); + + catchError(&ex); + mp = libvlc_media_player_new_from_media(m); + if(verboseEnabled) printf("In [%s] Line: %d, mp [%p]\n",__FUNCTION__,__LINE__,mp); + #else + // Create a new item + m = libvlc_media_new_path(libvlc, filename.c_str()); + if(verboseEnabled) printf("In [%s] Line: %d, m [%p]\n",__FUNCTION__,__LINE__,m); + + mp = libvlc_media_player_new_from_media(m); + if(verboseEnabled) printf("In [%s] Line: %d, mp [%p]\n",__FUNCTION__,__LINE__,mp); + #endif + libvlc_media_release(m); + + #if !defined(LIBVLC_VERSION_PRE_2) && !defined(LIBVLC_VERSION_PRE_1_1_0) + libvlc_video_set_callbacks(mp, lock, unlock, display, ctxPtr); + libvlc_video_set_format(mp, "RV16", width, height, this->window->pitch); + + // Get an event manager for the media player. + //libvlc_event_manager_t *eventManager = libvlc_media_player_event_manager(mp, &ex); + libvlc_event_manager_t *eventManager = libvlc_media_player_event_manager(mp); + if(eventManager) { + // libvlc_event_attach(eventManager, libvlc_MediaPlayerPlaying, (libvlc_callback_t)trapPlayingEvent, NULL, &ex); + // libvlc_event_attach(eventManager, libvlc_MediaPlayerEndReached, (libvlc_callback_t)trapEndReachedEvent, NULL, &ex); + // libvlc_event_attach(eventManager, libvlc_MediaPlayerBuffering, (libvlc_callback_t)trapBufferingEvent, NULL, &ex); + // libvlc_event_attach(eventManager, libvlc_MediaPlayerEncounteredError, (libvlc_callback_t)trapErrorEvent, NULL, &ex); + libvlc_event_attach(eventManager, libvlc_MediaPlayerPlaying, (libvlc_callback_t)trapPlayingEvent, ctxPtr); + libvlc_event_attach(eventManager, libvlc_MediaPlayerEndReached, (libvlc_callback_t)trapEndReachedEvent, ctxPtr); + libvlc_event_attach(eventManager, libvlc_MediaPlayerBuffering, (libvlc_callback_t)trapBufferingEvent, ctxPtr); + libvlc_event_attach(eventManager, libvlc_MediaPlayerEncounteredError, (libvlc_callback_t)trapErrorEvent, ctxPtr); + } + #endif + + ctxPtr->isPlaying = true; + #if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) + int play_result = libvlc_media_player_play(mp,&ex); + #else + int play_result = libvlc_media_player_play(mp); + #endif + + //SDL_Delay(5); + if(verboseEnabled) printf("In [%s] Line: %d, play_result [%d]\n",__FUNCTION__,__LINE__,play_result); + + successLoadingLib = (play_result == 0); + } + #endif + + // + / Main loop + // + //int done = 0, action = 0, pause = 0, n = 0; + bool needToQuit = false; + while(isPlaying() == true) { + needToQuit = playFrame(); + } + + #ifdef HAS_LIBVLC + if(libvlc != NULL) { + // + / Stop stream and clean up libVLC + // + #if defined(LIBVLC_VERSION_PRE_2) && defined(LIBVLC_VERSION_PRE_1_1_0) + libvlc_media_player_stop(mp,&ex); + catchError(&ex); + #else + libvlc_media_player_stop(mp); + #endif + libvlc_media_player_release(mp); + libvlc_release(libvlc); + } + #endif + + // + / Close window and clean up libSDL + // + SDL_DestroyMutex(ctxPtr->mutex); + SDL_FreeSurface(ctxPtr->surf); + SDL_FreeSurface(empty); + + glDeleteTextures(1, &ctxPtr->textureId); + + if(needToQuit == true) { + SDL_Event quit_event = {SDL_QUIT}; + SDL_PushEvent(&quit_event); + } + */ + + initPlayer(); + for (; isPlaying() == true;) { + playFrame(); } - else { - const double HEIGHT_DEFAULT = 768; - const double WIDTH_DEFAULT = 1024; + closePlayer(); + } - const double HEIGHT_MULTIPLIER = HEIGHT_DEFAULT / (double)ctxPtr->height; - const double WIDTH_MULTIPLIER = WIDTH_DEFAULT / (double)ctxPtr->width; + bool VideoPlayer::isPlaying() const { + bool result = (successLoadingLib == true && + ctxPtr != NULL && ctxPtr->isPlaying == true && + //ctxPtr->error == false && + (ctxPtr->error == false || ctxPtr->stopped == false) && + finished == false && stop == false); - //printf("w x h = %d x %d\n",ctxPtr->width,ctxPtr->height); - - glBegin(GL_TRIANGLE_STRIP); - glTexCoord2i(0, 1); - glVertex2i(ctxPtr->x, (int)((double)ctxPtr->y + (double)ctxPtr->height * HEIGHT_MULTIPLIER)); - glTexCoord2i(0, 0); - glVertex2i(ctxPtr->x, ctxPtr->y); - glTexCoord2i(1, 1); - glVertex2i((int)((double)ctxPtr->x + (double)ctxPtr->width * WIDTH_MULTIPLIER), (int)((double)ctxPtr->y + (double)ctxPtr->height * HEIGHT_MULTIPLIER)); - glTexCoord2i(1, 0); - glVertex2i((int)((double)ctxPtr->x + (double)ctxPtr->width * WIDTH_MULTIPLIER), ctxPtr->y); - glEnd(); + if (ctxPtr != NULL && ctxPtr->verboseEnabled) printf("isPlaying isPlaying = %d,error = %d, stopped = %d, end_of_media = %d\n", ctxPtr->isPlaying, ctxPtr->error, ctxPtr->stopped, ctxPtr->end_of_media); + return result; + } + bool VideoPlayer::playFrame(bool swapBuffers) { + if (VideoPlayer::disabled == true) { + return false; } - glPopAttrib(); + if (successLoadingLib == true && + ctxPtr != NULL && ctxPtr->isPlaying == true && + finished == false && stop == false) { - if(swapBuffers == true) { - SDL_GL_SwapWindow(window); + //int action = 0, pause = 0, n = 0; + //int action = 0, n = 0; + int action = 0; + + SDL_Event event; + /* Keys: enter (fullscreen), space (pause), escape (quit) */ + //while( SDL_PollEvent( &event ) ) { + if (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + finished = true; + ctxPtr->needToQuit = true; + break; + case SDL_KEYDOWN: + action = event.key.keysym.sym; + break; + case SDL_MOUSEBUTTONDOWN: + finished = true; + break; + } + } + + if (finished == false && stop == false) { + switch (action) { + case SDLK_ESCAPE: + finished = true; + break; + case SDLK_RETURN: + //options ^= SDL_WINDOW_FULLSCREEN; + //screen = SDL_SetVideoMode(WIDTH, HEIGHT, 0, options); + finished = true; + break; + //case ' ': + // //pause = !pause; + // break; + } + + //if(pause == 0) { + //n++; + //} + + //assertGl(); + + glPushAttrib(GL_ENABLE_BIT); + + //glDisable(GL_LIGHTING); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + + // Loading the texture + loadTexture(ctxPtr); + + if (ctxPtr->x == -1 || ctxPtr->y == -1) { + glBegin(GL_QUADS); + glTexCoord2d(0, 1); + glVertex2f(-0.85f, 0.85f); + glTexCoord2d(1, 1); + glVertex2f(0.85f, 0.85f); + glTexCoord2d(1, 0); + glVertex2f(0.85f, -0.85f); + glTexCoord2d(0, 0); + glVertex2f(-0.85f, -0.85f); + glEnd(); + } else { + const double HEIGHT_DEFAULT = 768; + const double WIDTH_DEFAULT = 1024; + + const double HEIGHT_MULTIPLIER = HEIGHT_DEFAULT / (double) ctxPtr->height; + const double WIDTH_MULTIPLIER = WIDTH_DEFAULT / (double) ctxPtr->width; + + //printf("w x h = %d x %d\n",ctxPtr->width,ctxPtr->height); + + glBegin(GL_TRIANGLE_STRIP); + glTexCoord2i(0, 1); + glVertex2i(ctxPtr->x, (int) ((double) ctxPtr->y + (double) ctxPtr->height * HEIGHT_MULTIPLIER)); + glTexCoord2i(0, 0); + glVertex2i(ctxPtr->x, ctxPtr->y); + glTexCoord2i(1, 1); + glVertex2i((int) ((double) ctxPtr->x + (double) ctxPtr->width * WIDTH_MULTIPLIER), (int) ((double) ctxPtr->y + (double) ctxPtr->height * HEIGHT_MULTIPLIER)); + glTexCoord2i(1, 0); + glVertex2i((int) ((double) ctxPtr->x + (double) ctxPtr->width * WIDTH_MULTIPLIER), ctxPtr->y); + glEnd(); + + } + + glPopAttrib(); + + if (swapBuffers == true) { + SDL_GL_SwapWindow(window); + } + } + } + + if (ctxPtr != NULL) { + return ctxPtr->needToQuit; + } else { + return false; } } - } - if(ctxPtr != NULL) { - return ctxPtr->needToQuit; - } - else { - return false; + void VideoPlayer::RestartVideo() { + //printf("Restart video\n"); + + //this->stop = false; + //this->finished = false; + //ctxPtr->started = true; + //ctxPtr->error = false; + //ctxPtr->stopped = false; + //ctxPtr->end_of_media = false; + //ctxPtr->isPlaying = true; + //ctxPtr->needToQuit = false; + + //return; + + this->closePlayer(); + + this->stop = false; + this->finished = false; + this->successLoadingLib = false; + + this->initPlayer(); + } + } } - -void VideoPlayer::RestartVideo() { - //printf("Restart video\n"); - - //this->stop = false; - //this->finished = false; - //ctxPtr->started = true; - //ctxPtr->error = false; - //ctxPtr->stopped = false; - //ctxPtr->end_of_media = false; - //ctxPtr->isPlaying = true; - //ctxPtr->needToQuit = false; - - //return; - - this->closePlayer(); - - this->stop = false; - this->finished = false; - this->successLoadingLib = false; - - this->initPlayer(); -} - -}} diff --git a/source/shared_lib/sources/lua/lua_script.cpp b/source/shared_lib/sources/lua/lua_script.cpp index 58b50af95..ff125b1fb 100644 --- a/source/shared_lib/sources/lua/lua_script.cpp +++ b/source/shared_lib/sources/lua/lua_script.cpp @@ -20,1126 +20,1115 @@ using namespace std; using namespace Shared::Util; -namespace Shared { namespace Lua { +namespace Shared { + namespace Lua { -// -// This class wraps streflop for LuaScript. We need to toggle the data type -// for streflop to use when calling into LUA as streflop may corrupt some -// numeric values passed from Lua otherwise -// -class Lua_STREFLOP_Wrapper { -public: - Lua_STREFLOP_Wrapper() { + // + // This class wraps streflop for LuaScript. We need to toggle the data type + // for streflop to use when calling into LUA as streflop may corrupt some + // numeric values passed from Lua otherwise + // + class Lua_STREFLOP_Wrapper { + public: + Lua_STREFLOP_Wrapper() { #ifdef USE_STREFLOP - streflop_init(); + streflop_init(); #endif - } - ~Lua_STREFLOP_Wrapper() { + } + ~Lua_STREFLOP_Wrapper() { #ifdef USE_STREFLOP - streflop_init(); + streflop_init(); #endif - } -}; + } + }; -// ===================================================== -// class LuaScript -// ===================================================== + // ===================================================== + // class LuaScript + // ===================================================== -bool LuaScript::disableSandbox = false; -bool LuaScript::debugModeEnabled = false; + bool LuaScript::disableSandbox = false; + bool LuaScript::debugModeEnabled = false; -LuaScript::LuaScript() { - Lua_STREFLOP_Wrapper streflopWrapper; + LuaScript::LuaScript() { + Lua_STREFLOP_Wrapper streflopWrapper; - currentLuaFunction = ""; - currentLuaFunctionIsValid = false; - sandboxWrapperFunctionName = ""; - sandboxCode = ""; - luaState= luaL_newstate(); + currentLuaFunction = ""; + currentLuaFunctionIsValid = false; + sandboxWrapperFunctionName = ""; + sandboxCode = ""; + luaState = luaL_newstate(); - luaL_openlibs(luaState); + luaL_openlibs(luaState); - if(luaState == NULL) { - throw megaglest_runtime_error("Can not allocate lua state"); - } + if (luaState == NULL) { + throw megaglest_runtime_error("Can not allocate lua state"); + } - argumentCount= -1; + argumentCount = -1; - if(disableSandbox == false) { - lua_getglobal(luaState, "os"); - lua_pushnil(luaState); - lua_setfield(luaState, -2, "execute"); - lua_pushnil(luaState); - lua_setfield(luaState, -2, "rename"); - lua_pushnil(luaState); - lua_setfield(luaState, -2, "remove"); - lua_pushnil(luaState); - lua_setfield(luaState, -2, "exit"); + if (disableSandbox == false) { + lua_getglobal(luaState, "os"); + lua_pushnil(luaState); + lua_setfield(luaState, -2, "execute"); + lua_pushnil(luaState); + lua_setfield(luaState, -2, "rename"); + lua_pushnil(luaState); + lua_setfield(luaState, -2, "remove"); + lua_pushnil(luaState); + lua_setfield(luaState, -2, "exit"); - lua_getglobal(luaState, "io"); - lua_pushnil(luaState); - lua_setfield(luaState, -2, "open"); - lua_pushnil(luaState); - lua_setfield(luaState, -2, "close"); - lua_pushnil(luaState); - lua_setfield(luaState, -2, "write"); - lua_pushnil(luaState); - lua_setfield(luaState, -2, "read"); - lua_pushnil(luaState); - lua_setfield(luaState, -2, "flush"); + lua_getglobal(luaState, "io"); + lua_pushnil(luaState); + lua_setfield(luaState, -2, "open"); + lua_pushnil(luaState); + lua_setfield(luaState, -2, "close"); + lua_pushnil(luaState); + lua_setfield(luaState, -2, "write"); + lua_pushnil(luaState); + lua_setfield(luaState, -2, "read"); + lua_pushnil(luaState); + lua_setfield(luaState, -2, "flush"); - lua_pushnil(luaState); - lua_setglobal(luaState, "loadfile"); - lua_pushnil(luaState); - lua_setglobal(luaState, "dofile"); - lua_pushnil(luaState); - lua_setglobal(luaState, "getfenv"); - lua_pushnil(luaState); - lua_setglobal(luaState, "getmetatable"); - lua_pushnil(luaState); - lua_setglobal(luaState, "load"); - lua_pushnil(luaState); - lua_setglobal(luaState, "loadfile"); - lua_pushnil(luaState); - lua_setglobal(luaState, "loadstring"); - lua_pushnil(luaState); - lua_setglobal(luaState, "rawequal"); - lua_pushnil(luaState); - lua_setglobal(luaState, "rawget"); - lua_pushnil(luaState); - lua_setglobal(luaState, "rawset"); - lua_pushnil(luaState); - lua_setglobal(luaState, "setfenv"); - lua_pushnil(luaState); - lua_setglobal(luaState, "setmetatable"); + lua_pushnil(luaState); + lua_setglobal(luaState, "loadfile"); + lua_pushnil(luaState); + lua_setglobal(luaState, "dofile"); + lua_pushnil(luaState); + lua_setglobal(luaState, "getfenv"); + lua_pushnil(luaState); + lua_setglobal(luaState, "getmetatable"); + lua_pushnil(luaState); + lua_setglobal(luaState, "load"); + lua_pushnil(luaState); + lua_setglobal(luaState, "loadfile"); + lua_pushnil(luaState); + lua_setglobal(luaState, "loadstring"); + lua_pushnil(luaState); + lua_setglobal(luaState, "rawequal"); + lua_pushnil(luaState); + lua_setglobal(luaState, "rawget"); + lua_pushnil(luaState); + lua_setglobal(luaState, "rawset"); + lua_pushnil(luaState); + lua_setglobal(luaState, "setfenv"); + lua_pushnil(luaState); + lua_setglobal(luaState, "setmetatable"); - lua_pop(luaState, 1); - } -} + lua_pop(luaState, 1); + } + } -void LuaScript::DumpGlobals() -{ - LuaHandle *L = luaState; - // push the first key (nil = beginning of table) + void LuaScript::DumpGlobals() { + LuaHandle *L = luaState; + // push the first key (nil = beginning of table) #if LUA_VERSION_NUM <= 501 - lua_pushnil(L); + lua_pushnil(L); #endif - // lua_next will: - // 1 - pop the key - // 2 - push the next key - // 3 - push the value at that key - // ... so the key will be at index -2 and the value at index -1 + // lua_next will: + // 1 - pop the key + // 2 - push the next key + // 3 - push the value at that key + // ... so the key will be at index -2 and the value at index -1 #if LUA_VERSION_NUM > 501 - lua_pushglobaltable(L); - lua_pushnil(L); - while (lua_next(L, -2) != 0) { + lua_pushglobaltable(L); + lua_pushnil(L); + while (lua_next(L, -2) != 0) { #else - while (lua_next(L, LUA_GLOBALSINDEX) != 0) { + while (lua_next(L, LUA_GLOBALSINDEX) != 0) { #endif - // get type of key and value - int key_type = lua_type(L, -2); - int value_type = lua_type(L, -1); + // get type of key and value + int key_type = lua_type(L, -2); + int value_type = lua_type(L, -1); - // support only string keys - // globals aren't likely to have a non-string key, but just to be certain ... - if (key_type != LUA_TSTRING) { - lua_pop(L, 1); // pop the value so that the top contains the key for the next iteration - continue; - } + // support only string keys + // globals aren't likely to have a non-string key, but just to be certain ... + if (key_type != LUA_TSTRING) { + lua_pop(L, 1); // pop the value so that the top contains the key for the next iteration + continue; + } - // support only number, boolean and string values - if (value_type != LUA_TNUMBER && - value_type != LUA_TBOOLEAN && - value_type != LUA_TSTRING) { - lua_pop(L, 1); // again, pop the value before going to the next loop iteration - continue; - } + // support only number, boolean and string values + if (value_type != LUA_TNUMBER && + value_type != LUA_TBOOLEAN && + value_type != LUA_TSTRING) { + lua_pop(L, 1); // again, pop the value before going to the next loop iteration + continue; + } - // get the key as a string - string key_string = lua_tostring(L, -2); // no copy required - we already know this is a string + // get the key as a string + string key_string = lua_tostring(L, -2); // no copy required - we already know this is a string - // do not support variables that start with '_' - // lua has some predefined values like _VERSION. They all start with underscore + // do not support variables that start with '_' + // lua has some predefined values like _VERSION. They all start with underscore - if (!key_string.size()) { // this again is highly unlikely, but still ... - lua_pop(L, 1); - continue; - } - if (key_string[0] == '_') { - lua_pop(L, 1); - continue; - } + if (!key_string.size()) { // this again is highly unlikely, but still ... + lua_pop(L, 1); + continue; + } + if (key_string[0] == '_') { + lua_pop(L, 1); + continue; + } - string value_string; + string value_string; - // convert the value to a string. This depends on its type - switch (value_type) { - case LUA_TSTRING: - case LUA_TNUMBER: - // numbers can be converted to strings - - // get the value as a string (this requires a copy because traversing tables - // uses the top of the stack as an index. If conversion from a number to string - // happens, the top of the stack will be altered and the table index will become invalid) - lua_pushvalue(L, -1); - value_string = lua_tostring(L, -1); - lua_pop(L, 1); - break; - case LUA_TBOOLEAN: - value_string = lua_toboolean(L, -1) == 0 ? "false" : "true"; - break; - } - - // enclose the value in "" if it is a string - if (value_type == LUA_TSTRING) { - value_string = "\"" + value_string + "\""; - } - - // resulting line. Somehow save this and when you need to restore it, just - // call luaL_dostring with that line. - //SaveLine(key_string + " = " + value_string); // Pop the value so the index remains on top of the stack for the next iteration - printf("Found global LUA var: %s = %s\n",key_string.c_str(),value_string.c_str()); - - lua_pop(L, 1); - } -#if LUA_VERSION_NUM > 501 - lua_pop(L, 1); -#endif - -} - -void LuaScript::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - - //try{ - LuaHandle *L = luaState; - // push the first key (nil = beginning of table) -#if LUA_VERSION_NUM <= 501 - lua_pushnil(L); -#endif - - // lua_next will: - // 1 - pop the key - // 2 - push the next key - // 3 - push the value at that key - // ... so the key will be at index -2 and the value at index -1 - -#if LUA_VERSION_NUM > 501 - lua_pushglobaltable(L); - lua_pushnil(L); - while (lua_next(L, -2) != 0) { -#else - while (lua_next(L, LUA_GLOBALSINDEX) != 0) { -#endif - // get type of key and value - int key_type = lua_type(L, -2); - int value_type = lua_type(L, -1); - - if(LuaScript::debugModeEnabled == true) printf("LUA save key_type = %d, value_type = %d for var [%s]\n",key_type,value_type,lua_tostring(L, -2)); - - // support only string keys - // globals aren't likely to have a non-string key, but just to be certain ... - if (key_type != LUA_TSTRING) { - lua_pop(L, 1); // pop the value so that the top contains the key for the next iteration - continue; - } - - // support only number, boolean and string values - if (value_type != LUA_TNUMBER && - value_type != LUA_TBOOLEAN && - value_type != LUA_TSTRING && - value_type != LUA_TTABLE) { - lua_pop(L, 1); // again, pop the value before going to the next loop iteration - continue; - } - - // get the key as a string - string key_string = lua_tostring(L, -2); // no copy required - we already know this is a string - - if(LuaScript::debugModeEnabled == true) printf("key_string [%s]\n",key_string.c_str()); - // do not support variables that start with '_' - // lua has some predefined values like _VERSION. They all start with underscore - - if (!key_string.size()) { // this again is highly unlikely, but still ... - lua_pop(L, 1); - continue; - } - if (key_string[0] == '_') { - lua_pop(L, 1); - continue; - } - - bool skipTable = false; - // The first pair is the tables key type,value - // The second pair is the tables value type,value - vector, pair > > tableList; - string value_string; - - // convert the value to a string. This depends on its type - switch (value_type) { - case LUA_TSTRING: - case LUA_TNUMBER: - // numbers can be converted to strings - - // get the value as a string (this requires a copy because traversing tables - // uses the top of the stack as an index. If conversion from a number to string - // happens, the top of the stack will be altered and the table index will become invalid) - lua_pushvalue(L, -1); - value_string = lua_tostring(L, -1); - lua_pop(L, 1); - break; - case LUA_TBOOLEAN: - value_string = lua_toboolean(L, -1) == 0 ? "false" : "true"; - break; - case LUA_TTABLE: - { - - int tableItemCount = 0; - if(LuaScript::debugModeEnabled == true) printf("================ LUA TABLE DETECTED - START =================\n"); - for (lua_pushnil(L); lua_next(L, -2) ;) { - tableItemCount++; - - if(LuaScript::debugModeEnabled == true) printf("LUA TABLE loop A\n"); - - int tableKeyType = lua_type(L, -2); - int tableValueType = lua_type(L, -1); - - if(LuaScript::debugModeEnabled == true) printf("LUA TABLE loop item type [%s] key: %d value type: %d\n",lua_typename(L, tableValueType),tableKeyType,tableValueType); - - switch (tableValueType) { + // convert the value to a string. This depends on its type + switch (value_type) { case LUA_TSTRING: case LUA_TNUMBER: - case LUA_TBOOLEAN: - break; - default: - skipTable = true; - break; - } - if(skipTable == false) { - // Stack: value, key, table - std :: string value = ""; - if(!lua_isnil(L, -1)) { - if(LuaScript::debugModeEnabled == true) printf("LUA TABLE loop B\n"); + // numbers can be converted to strings + // get the value as a string (this requires a copy because traversing tables + // uses the top of the stack as an index. If conversion from a number to string + // happens, the top of the stack will be altered and the table index will become invalid) lua_pushvalue(L, -1); - - if(LuaScript::debugModeEnabled == true) printf("LUA TABLE loop C\n"); - - if(tableValueType == LUA_TBOOLEAN ) { - value = lua_toboolean(L, -1) == 0 ? "false" : "true"; - } - else { - value = lua_tostring (L, -1); - } - - if(LuaScript::debugModeEnabled == true) printf("LUA TABLE loop D\n"); - - lua_pop (L, 1); - } - lua_pop (L, 1); - - if(LuaScript::debugModeEnabled == true) printf("LUA TABLE value [%s]\n",value.c_str()); - - // Stack: key, table - lua_pushvalue(L, -1); - - // Stack: key, key, table - std :: string key = lua_tostring(L, -1); - lua_pop(L, 1); - - // Stack: key, table - //std :: cout << key << "" << value << "\ n"; - if(LuaScript::debugModeEnabled == true) printf("[%s] [%s]\n",key.c_str(),value.c_str()); - - if(value_string != "") { - value_string += "|||"; - } - char szBuf[8096]=""; - snprintf(szBuf,8096,"[%s] [%s]",key.c_str(),value.c_str()); - //value_string += szBuf; - //vector, pair> > tableList; - tableList.push_back(make_pair(make_pair(tableKeyType,key),make_pair(tableValueType,value))); + value_string = lua_tostring(L, -1); + lua_pop(L, 1); + break; + case LUA_TBOOLEAN: + value_string = lua_toboolean(L, -1) == 0 ? "false" : "true"; + break; } - else { - if(LuaScript::debugModeEnabled == true) printf("***WARNING*** SKIPPING LUA TABLE because it has an unsupported embedded type: %d [%s]\n",tableValueType, lua_typename(L, tableValueType)); - lua_pop(L, 1); + // enclose the value in "" if it is a string + if (value_type == LUA_TSTRING) { + value_string = "\"" + value_string + "\""; } - } - if(tableItemCount < 1) { - if(LuaScript::debugModeEnabled == true) printf("Skipping lua table tableItemCount = %d\n",tableItemCount); - skipTable = true; - } - if(LuaScript::debugModeEnabled == true) printf("---------------------------- LUA TABLE DETECTED - END ----------------------------\n"); - } - break; - } - - // enclose the value in "" if it is a string - //if (value_type == LUA_TSTRING) { - //value_string = "\"" + value_string + "\""; - //} - - if(skipTable == true) { - if(LuaScript::debugModeEnabled == true) printf("#2 SKIPPING TABLE\n"); - } - else { - //vector, pair> > tableList; - if(tableList.empty() == false) { - XmlNode *luaScriptNode = rootNode->addChild("LuaScript"); - luaScriptNode->addAttribute("variable",key_string, mapTagReplacements); - luaScriptNode->addAttribute("value_type",intToStr(value_type), mapTagReplacements); - - for(unsigned int i = 0; i < tableList.size(); ++i) { - pair, pair > &item = tableList[i]; - - XmlNode *luaScriptTableNode = luaScriptNode->addChild("Table"); - luaScriptTableNode->addAttribute("key_type",intToStr(item.first.first), mapTagReplacements); - luaScriptTableNode->addAttribute("key",item.first.second, mapTagReplacements); - luaScriptTableNode->addAttribute("value",item.second.second, mapTagReplacements); - luaScriptTableNode->addAttribute("value_type",intToStr(item.second.first), mapTagReplacements); - } - } - else { // resulting line. Somehow save this and when you need to restore it, just // call luaL_dostring with that line. //SaveLine(key_string + " = " + value_string); // Pop the value so the index remains on top of the stack for the next iteration - //printf("Found global LUA var: %s = %s\n",key_string.c_str(),value_string.c_str()); - XmlNode *luaScriptNode = rootNode->addChild("LuaScript"); - luaScriptNode->addAttribute("variable",key_string, mapTagReplacements); - luaScriptNode->addAttribute("value",value_string, mapTagReplacements); - luaScriptNode->addAttribute("value_type",intToStr(value_type), mapTagReplacements); - } - } - lua_pop(L, 1); - } + printf("Found global LUA var: %s = %s\n", key_string.c_str(), value_string.c_str()); + lua_pop(L, 1); + } #if LUA_VERSION_NUM > 501 - lua_pop(L, 1); + lua_pop(L, 1); #endif - //} - //catch(const exception &ex) { - // abort(); - //} -} + } -void LuaScript::loadGame(const XmlNode *rootNode) { - if(LuaScript::debugModeEnabled) printf("START [%s::%s] Line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + void LuaScript::saveGame(XmlNode *rootNode) { + std::map mapTagReplacements; - vector luaScriptNodeList = rootNode->getChildList("LuaScript"); + //try{ + LuaHandle *L = luaState; + // push the first key (nil = beginning of table) +#if LUA_VERSION_NUM <= 501 + lua_pushnil(L); +#endif - if(LuaScript::debugModeEnabled) printf("luaScriptNodeList.size(): %d\n",(int)luaScriptNodeList.size()); + // lua_next will: + // 1 - pop the key + // 2 - push the next key + // 3 - push the value at that key + // ... so the key will be at index -2 and the value at index -1 - for(unsigned int i = 0; i < luaScriptNodeList.size(); ++i) { - XmlNode *node = luaScriptNodeList[i]; +#if LUA_VERSION_NUM > 501 + lua_pushglobaltable(L); + lua_pushnil(L); + while (lua_next(L, -2) != 0) { +#else + while (lua_next(L, LUA_GLOBALSINDEX) != 0) { +#endif + // get type of key and value + int key_type = lua_type(L, -2); + int value_type = lua_type(L, -1); - string variable = node->getAttribute("variable")->getValue(); - int value_type = node->getAttribute("value_type")->getIntValue(); + if (LuaScript::debugModeEnabled == true) printf("LUA save key_type = %d, value_type = %d for var [%s]\n", key_type, value_type, lua_tostring(L, -2)); - if(LuaScript::debugModeEnabled) printf(" index #: %u [%s] [%d]\n",i,variable.c_str(),value_type); - - switch (value_type) { - case LUA_TSTRING: - if(LuaScript::debugModeEnabled) printf(" value [%s]\n",node->getAttribute("value")->getValue().c_str()); - lua_pushstring( luaState, node->getAttribute("value")->getValue().c_str() ); - break; - case LUA_TNUMBER: - if(LuaScript::debugModeEnabled) printf(" value [%s]\n",node->getAttribute("value")->getValue().c_str()); - lua_pushnumber( luaState, node->getAttribute("value")->getFloatValue() ); - break; - case LUA_TBOOLEAN: - if(LuaScript::debugModeEnabled) printf(" value [%s]\n",node->getAttribute("value")->getValue().c_str()); - lua_pushboolean( luaState, node->getAttribute("value")->getBoolValue() ); - break; - case LUA_TTABLE: - { - if(LuaScript::debugModeEnabled == true) printf("================ LUA TABLE DETECTED - START =================\n"); - - lua_newtable(luaState); /* We will pass a table */ - vector luaScriptTableNode = node->getChildList("Table"); - - if(LuaScript::debugModeEnabled) printf("luaScriptTableNode.size(): %d\n",(int)luaScriptTableNode.size()); - - for(unsigned int j = 0; j < luaScriptTableNode.size(); ++j) { - XmlNode *nodeTable = luaScriptTableNode[j]; - - int key_type = nodeTable->getAttribute("key_type")->getIntValue(); - if(LuaScript::debugModeEnabled == true) printf("Table item key_type: %d [%s]\n",key_type,lua_typename(luaState, key_type)); - - switch (key_type) { - case LUA_TSTRING: - if(LuaScript::debugModeEnabled) printf(" table item key [%s]\n",nodeTable->getAttribute("key")->getValue().c_str()); - lua_pushstring( luaState, nodeTable->getAttribute("key")->getValue().c_str() ); - break; - case LUA_TNUMBER: - if(LuaScript::debugModeEnabled) printf(" table item key [%s]\n",nodeTable->getAttribute("key")->getValue().c_str()); - lua_pushnumber( luaState, nodeTable->getAttribute("key")->getFloatValue() ); - break; - case LUA_TBOOLEAN: - if(LuaScript::debugModeEnabled) printf(" table item key [%s]\n",nodeTable->getAttribute("key")->getValue().c_str()); - lua_pushboolean( luaState, nodeTable->getAttribute("key")->getBoolValue() ); - break; - } - - int value_type = nodeTable->getAttribute("value_type")->getIntValue(); - if(LuaScript::debugModeEnabled == true) printf("Table item value_type: %d [%s]\n",value_type,lua_typename(luaState, value_type)); - - switch (value_type) { - case LUA_TSTRING: - if(LuaScript::debugModeEnabled) printf(" table item value [%s]\n",nodeTable->getAttribute("value")->getValue().c_str()); - lua_pushstring( luaState, nodeTable->getAttribute("value")->getValue().c_str() ); - break; - case LUA_TNUMBER: - if(LuaScript::debugModeEnabled) printf(" table item value [%s]\n",nodeTable->getAttribute("value")->getValue().c_str()); - lua_pushnumber( luaState, nodeTable->getAttribute("value")->getFloatValue() ); - break; - case LUA_TBOOLEAN: - if(LuaScript::debugModeEnabled) printf(" table item value [%s]\n",nodeTable->getAttribute("value")->getValue().c_str()); - lua_pushboolean( luaState, nodeTable->getAttribute("value")->getBoolValue() ); - break; - } - - lua_rawset(luaState, -3); /* Stores the pair in the table */ - } - if(LuaScript::debugModeEnabled == true) printf("----------------- LUA TABLE DETECTED - END -----------------\n"); + // support only string keys + // globals aren't likely to have a non-string key, but just to be certain ... + if (key_type != LUA_TSTRING) { + lua_pop(L, 1); // pop the value so that the top contains the key for the next iteration + continue; } - break; - } + // support only number, boolean and string values + if (value_type != LUA_TNUMBER && + value_type != LUA_TBOOLEAN && + value_type != LUA_TSTRING && + value_type != LUA_TTABLE) { + lua_pop(L, 1); // again, pop the value before going to the next loop iteration + continue; + } - lua_setglobal( luaState, variable.c_str() ); - } -} + // get the key as a string + string key_string = lua_tostring(L, -2); // no copy required - we already know this is a string -LuaScript::~LuaScript() { - Lua_STREFLOP_Wrapper streflopWrapper; + if (LuaScript::debugModeEnabled == true) printf("key_string [%s]\n", key_string.c_str()); + // do not support variables that start with '_' + // lua has some predefined values like _VERSION. They all start with underscore -// LuaInterface.LuaTable luatab; -// -// luatab = lua.GetTable("_G"); -// -// -// foreach (DictionaryEntry d in luatab) -// -// { -// -// Console.WriteLine("{0} -> {1}", d.Key, d.Value); -// -// } + if (!key_string.size()) { // this again is highly unlikely, but still ... + lua_pop(L, 1); + continue; + } + if (key_string[0] == '_') { + lua_pop(L, 1); + continue; + } - //DumpGlobals(); + bool skipTable = false; + // The first pair is the tables key type,value + // The second pair is the tables value type,value + vector, pair > > tableList; + string value_string; - lua_close(luaState); -} + // convert the value to a string. This depends on its type + switch (value_type) { + case LUA_TSTRING: + case LUA_TNUMBER: + // numbers can be converted to strings -void LuaScript::loadCode(string code, string name){ - Lua_STREFLOP_Wrapper streflopWrapper; + // get the value as a string (this requires a copy because traversing tables + // uses the top of the stack as an index. If conversion from a number to string + // happens, the top of the stack will be altered and the table index will become invalid) + lua_pushvalue(L, -1); + value_string = lua_tostring(L, -1); + lua_pop(L, 1); + break; + case LUA_TBOOLEAN: + value_string = lua_toboolean(L, -1) == 0 ? "false" : "true"; + break; + case LUA_TTABLE: + { - //printf("Code [%s]\nName [%s]\n",code.c_str(),name.c_str()); + int tableItemCount = 0; + if (LuaScript::debugModeEnabled == true) printf("================ LUA TABLE DETECTED - START =================\n"); + for (lua_pushnil(L); lua_next(L, -2);) { + tableItemCount++; - int errorCode= luaL_loadbuffer(luaState, code.c_str(), code.length(), name.c_str()); - if(errorCode != 0 ) { - printf("=========================================================\n"); - printf("Error loading lua code: %s\n",errorToString(errorCode).c_str()); - printf("Function name [%s]\ncode:\n%s\n",name.c_str(),code.c_str()); - printf("=========================================================\n"); + if (LuaScript::debugModeEnabled == true) printf("LUA TABLE loop A\n"); - throw megaglest_runtime_error("Error loading lua code: " + errorToString(errorCode),true); - } + int tableKeyType = lua_type(L, -2); + int tableValueType = lua_type(L, -1); - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] name [%s], errorCode = %d\n",__FILE__,__FUNCTION__,__LINE__,name.c_str(),errorCode); + if (LuaScript::debugModeEnabled == true) printf("LUA TABLE loop item type [%s] key: %d value type: %d\n", lua_typename(L, tableValueType), tableKeyType, tableValueType); - //run code - errorCode= lua_pcall(luaState, 0, 0, 0); - if(errorCode !=0 ) { - printf("=========================================================\n"); - printf("Error calling lua pcall: %s\n",errorToString(errorCode).c_str()); - printf("=========================================================\n"); + switch (tableValueType) { + case LUA_TSTRING: + case LUA_TNUMBER: + case LUA_TBOOLEAN: + break; + default: + skipTable = true; + break; + } + if (skipTable == false) { + // Stack: value, key, table + std::string value = ""; + if (!lua_isnil(L, -1)) { + if (LuaScript::debugModeEnabled == true) printf("LUA TABLE loop B\n"); - throw megaglest_runtime_error("Error initializing lua: " + errorToString(errorCode),true); - } + lua_pushvalue(L, -1); - //const char *errMsg = lua_tostring(luaState, -1); + if (LuaScript::debugModeEnabled == true) printf("LUA TABLE loop C\n"); - //printf("END of call to Name [%s]\n",name.c_str()); + if (tableValueType == LUA_TBOOLEAN) { + value = lua_toboolean(L, -1) == 0 ? "false" : "true"; + } else { + value = lua_tostring(L, -1); + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] name [%s], errorCode = %d\n",__FILE__,__FUNCTION__,__LINE__,name.c_str(),errorCode); -} + if (LuaScript::debugModeEnabled == true) printf("LUA TABLE loop D\n"); -void LuaScript::setSandboxWrapperFunctionName(string name) { - sandboxWrapperFunctionName = name; -} + lua_pop(L, 1); + } + lua_pop(L, 1); -void LuaScript::setSandboxCode(string code) { - sandboxCode = code; -} + if (LuaScript::debugModeEnabled == true) printf("LUA TABLE value [%s]\n", value.c_str()); -int LuaScript::runCode(string code) { - Lua_STREFLOP_Wrapper streflopWrapper; + // Stack: key, table + lua_pushvalue(L, -1); - int errorCode = luaL_dostring(luaState,code.c_str()); - return errorCode; -} + // Stack: key, key, table + std::string key = lua_tostring(L, -1); + lua_pop(L, 1); -void LuaScript::beginCall(string functionName) { - Lua_STREFLOP_Wrapper streflopWrapper; + // Stack: key, table + //std :: cout << key << "" << value << "\ n"; + if (LuaScript::debugModeEnabled == true) printf("[%s] [%s]\n", key.c_str(), value.c_str()); - currentLuaFunction = functionName; + if (value_string != "") { + value_string += "|||"; + } + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "[%s] [%s]", key.c_str(), value.c_str()); + //value_string += szBuf; + //vector, pair> > tableList; + tableList.push_back(make_pair(make_pair(tableKeyType, key), make_pair(tableValueType, value))); + } else { + if (LuaScript::debugModeEnabled == true) printf("***WARNING*** SKIPPING LUA TABLE because it has an unsupported embedded type: %d [%s]\n", tableValueType, lua_typename(L, tableValueType)); - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] functionName [%s]\n",__FILE__,__FUNCTION__,__LINE__,functionName.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] functionName [%s]\n",__FILE__,__FUNCTION__,__LINE__,functionName.c_str()); + lua_pop(L, 1); + } + } + if (tableItemCount < 1) { + if (LuaScript::debugModeEnabled == true) printf("Skipping lua table tableItemCount = %d\n", tableItemCount); - //string funcLuaFunction = functionName; -// if(sandboxWrapperFunctionName != "" && sandboxCode != "") { -// int errorCode= runCode(sandboxCode); -// if(errorCode !=0 ) { -// throw megaglest_runtime_error("Error calling lua function [" + currentLuaFunction + "] error: " + errorToString(errorCode)); -// } -// //functionName = sandboxWrapperFunctionName; -// } - lua_getglobal(luaState, functionName.c_str()); + skipTable = true; + } + if (LuaScript::debugModeEnabled == true) printf("---------------------------- LUA TABLE DETECTED - END ----------------------------\n"); + } + break; + } - currentLuaFunctionIsValid = lua_isfunction(luaState,lua_gettop(luaState)); + // enclose the value in "" if it is a string + //if (value_type == LUA_TSTRING) { + //value_string = "\"" + value_string + "\""; + //} - //printf("currentLuaFunctionIsValid = %d functionName [%s]\n",currentLuaFunctionIsValid,functionName.c_str()); - argumentCount= 0; -} + if (skipTable == true) { + if (LuaScript::debugModeEnabled == true) printf("#2 SKIPPING TABLE\n"); + } else { + //vector, pair> > tableList; + if (tableList.empty() == false) { + XmlNode *luaScriptNode = rootNode->addChild("LuaScript"); + luaScriptNode->addAttribute("variable", key_string, mapTagReplacements); + luaScriptNode->addAttribute("value_type", intToStr(value_type), mapTagReplacements); -void LuaScript::endCall() { - Lua_STREFLOP_Wrapper streflopWrapper; + for (unsigned int i = 0; i < tableList.size(); ++i) { + pair, pair > &item = tableList[i]; - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] currentLuaFunction [%s], currentLuaFunctionIsValid = %d\n",__FILE__,__FUNCTION__,__LINE__,currentLuaFunction.c_str(),currentLuaFunctionIsValid); - - if(currentLuaFunctionIsValid == true) { - if(sandboxWrapperFunctionName != "" && sandboxCode != "") { - //lua_pushstring(luaState, currentLuaFunction.c_str()); // push 1st argument, the real lua function - //argumentCount = 1; - - string safeWrapper = sandboxWrapperFunctionName + " [[" + currentLuaFunction + "()]]"; - printf("Trying to execute [%s]\n",safeWrapper.c_str()); - int errorCode= runCode(safeWrapper); - if(errorCode !=0 ) { - throw megaglest_runtime_error("Error calling lua function [" + currentLuaFunction + "] error: " + errorToString(errorCode),true); + XmlNode *luaScriptTableNode = luaScriptNode->addChild("Table"); + luaScriptTableNode->addAttribute("key_type", intToStr(item.first.first), mapTagReplacements); + luaScriptTableNode->addAttribute("key", item.first.second, mapTagReplacements); + luaScriptTableNode->addAttribute("value", item.second.second, mapTagReplacements); + luaScriptTableNode->addAttribute("value_type", intToStr(item.second.first), mapTagReplacements); + } + } else { + // resulting line. Somehow save this and when you need to restore it, just + // call luaL_dostring with that line. + //SaveLine(key_string + " = " + value_string); // Pop the value so the index remains on top of the stack for the next iteration + //printf("Found global LUA var: %s = %s\n",key_string.c_str(),value_string.c_str()); + XmlNode *luaScriptNode = rootNode->addChild("LuaScript"); + luaScriptNode->addAttribute("variable", key_string, mapTagReplacements); + luaScriptNode->addAttribute("value", value_string, mapTagReplacements); + luaScriptNode->addAttribute("value_type", intToStr(value_type), mapTagReplacements); + } + } + lua_pop(L, 1); } - //printf("Trying to execute [%s]\n",currentLuaFunction.c_str()); - //lua_getglobal(luaState, sandboxWrapperFunctionName.c_str()); - //argumentCount = 1; - //lua_pushstring( luaState, currentLuaFunction.c_str() ); +#if LUA_VERSION_NUM > 501 + lua_pop(L, 1); +#endif -// int errorCode= lua_pcall(luaState, argumentCount, 0, 0); -// if(errorCode !=0 ) { -// throw megaglest_runtime_error("Error calling lua function [" + currentLuaFunction + "] error: " + errorToString(errorCode)); -// } - } - else { - int errorCode= lua_pcall(luaState, argumentCount, 0, 0); - if(errorCode !=0 ) { - throw megaglest_runtime_error("Error calling lua function [" + currentLuaFunction + "] error: " + errorToString(errorCode),true); + //} + //catch(const exception &ex) { + // abort(); + //} + } + + void LuaScript::loadGame(const XmlNode *rootNode) { + if (LuaScript::debugModeEnabled) printf("START [%s::%s] Line: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + vector luaScriptNodeList = rootNode->getChildList("LuaScript"); + + if (LuaScript::debugModeEnabled) printf("luaScriptNodeList.size(): %d\n", (int) luaScriptNodeList.size()); + + for (unsigned int i = 0; i < luaScriptNodeList.size(); ++i) { + XmlNode *node = luaScriptNodeList[i]; + + string variable = node->getAttribute("variable")->getValue(); + int value_type = node->getAttribute("value_type")->getIntValue(); + + if (LuaScript::debugModeEnabled) printf(" index #: %u [%s] [%d]\n", i, variable.c_str(), value_type); + + switch (value_type) { + case LUA_TSTRING: + if (LuaScript::debugModeEnabled) printf(" value [%s]\n", node->getAttribute("value")->getValue().c_str()); + lua_pushstring(luaState, node->getAttribute("value")->getValue().c_str()); + break; + case LUA_TNUMBER: + if (LuaScript::debugModeEnabled) printf(" value [%s]\n", node->getAttribute("value")->getValue().c_str()); + lua_pushnumber(luaState, node->getAttribute("value")->getFloatValue()); + break; + case LUA_TBOOLEAN: + if (LuaScript::debugModeEnabled) printf(" value [%s]\n", node->getAttribute("value")->getValue().c_str()); + lua_pushboolean(luaState, node->getAttribute("value")->getBoolValue()); + break; + case LUA_TTABLE: + { + if (LuaScript::debugModeEnabled == true) printf("================ LUA TABLE DETECTED - START =================\n"); + + lua_newtable(luaState); /* We will pass a table */ + vector luaScriptTableNode = node->getChildList("Table"); + + if (LuaScript::debugModeEnabled) printf("luaScriptTableNode.size(): %d\n", (int) luaScriptTableNode.size()); + + for (unsigned int j = 0; j < luaScriptTableNode.size(); ++j) { + XmlNode *nodeTable = luaScriptTableNode[j]; + + int key_type = nodeTable->getAttribute("key_type")->getIntValue(); + if (LuaScript::debugModeEnabled == true) printf("Table item key_type: %d [%s]\n", key_type, lua_typename(luaState, key_type)); + + switch (key_type) { + case LUA_TSTRING: + if (LuaScript::debugModeEnabled) printf(" table item key [%s]\n", nodeTable->getAttribute("key")->getValue().c_str()); + lua_pushstring(luaState, nodeTable->getAttribute("key")->getValue().c_str()); + break; + case LUA_TNUMBER: + if (LuaScript::debugModeEnabled) printf(" table item key [%s]\n", nodeTable->getAttribute("key")->getValue().c_str()); + lua_pushnumber(luaState, nodeTable->getAttribute("key")->getFloatValue()); + break; + case LUA_TBOOLEAN: + if (LuaScript::debugModeEnabled) printf(" table item key [%s]\n", nodeTable->getAttribute("key")->getValue().c_str()); + lua_pushboolean(luaState, nodeTable->getAttribute("key")->getBoolValue()); + break; + } + + int value_type = nodeTable->getAttribute("value_type")->getIntValue(); + if (LuaScript::debugModeEnabled == true) printf("Table item value_type: %d [%s]\n", value_type, lua_typename(luaState, value_type)); + + switch (value_type) { + case LUA_TSTRING: + if (LuaScript::debugModeEnabled) printf(" table item value [%s]\n", nodeTable->getAttribute("value")->getValue().c_str()); + lua_pushstring(luaState, nodeTable->getAttribute("value")->getValue().c_str()); + break; + case LUA_TNUMBER: + if (LuaScript::debugModeEnabled) printf(" table item value [%s]\n", nodeTable->getAttribute("value")->getValue().c_str()); + lua_pushnumber(luaState, nodeTable->getAttribute("value")->getFloatValue()); + break; + case LUA_TBOOLEAN: + if (LuaScript::debugModeEnabled) printf(" table item value [%s]\n", nodeTable->getAttribute("value")->getValue().c_str()); + lua_pushboolean(luaState, nodeTable->getAttribute("value")->getBoolValue()); + break; + } + + lua_rawset(luaState, -3); /* Stores the pair in the table */ + } + if (LuaScript::debugModeEnabled == true) printf("----------------- LUA TABLE DETECTED - END -----------------\n"); + } + break; + + } + + lua_setglobal(luaState, variable.c_str()); } } - } - else - { - lua_pcall(luaState, argumentCount, 0, 0); - } -} -void LuaScript::registerFunction(LuaFunction luaFunction, string functionName) { - Lua_STREFLOP_Wrapper streflopWrapper; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] functionName [%s]\n",__FILE__,__FUNCTION__,__LINE__,functionName.c_str()); - - lua_pushcfunction(luaState, luaFunction); - lua_setglobal(luaState, functionName.c_str()); -} - -string LuaScript::errorToString(int errorCode) { - Lua_STREFLOP_Wrapper streflopWrapper; - - string error; - switch(errorCode){ - case LUA_ERRSYNTAX: - error+= "Syntax error"; - break; - case LUA_ERRRUN: - error+= "Runtime error"; - break; - case LUA_ERRMEM: - error+= "Memory allocation error"; - break; - case LUA_ERRERR: - error+= "Error while running the error handler"; - break; - default: - error+= "Unknown LUA error" + intToStr(errorCode); - break; - } - - error += string(": ")+luaL_checkstring(luaState, -1); - - return error; -} - -// ===================================================== -// class LuaArguments -// ===================================================== - -LuaArguments::LuaArguments(lua_State *luaState){ - Lua_STREFLOP_Wrapper streflopWrapper; - - this->luaState= luaState; - returnCount= 0; -} - -int LuaArguments::getInt(int argumentIndex) const{ - Lua_STREFLOP_Wrapper streflopWrapper; - - if(!lua_isnumber(luaState, argumentIndex)) { - throwLuaError("Can not get int from Lua state"); - } - - int result = (int)luaL_checkinteger(luaState, argumentIndex); - return result; -} - -float LuaArguments::getFloat(int argumentIndex) const { - Lua_STREFLOP_Wrapper streflopWrapper; - - if(!lua_isnumber(luaState, argumentIndex)) { - throwLuaError("Can not get int from Lua state"); - } - float result = static_cast(luaL_checknumber(luaState, argumentIndex)); - return result; -} -Vec2f LuaArguments::getVec2f(int argumentIndex) const { - Lua_STREFLOP_Wrapper streflopWrapper; - - Vec2f v; - - if(!lua_istable(luaState, argumentIndex)){ - throwLuaError("Can not get vec2f from Lua state, value on the stack is not a table"); - } - -#if LUA_VERSION_NUM > 501 - if(lua_rawlen(luaState, argumentIndex)!=2){ -#else - if(luaL_getn(luaState, argumentIndex)!=2){ -#endif - throwLuaError("Can not get vec2f from Lua state, array size not 2"); - } - - //string stackString = getStackText(); - //printf("Lua Stack:\n%s\n",stackString.c_str()); - - lua_rawgeti(luaState, argumentIndex, 1); - //printf("xa = %s argumentIndex = %d\n",lua_tostring(luaState, argumentIndex),argumentIndex); - - //v.x= (int)luaL_checkinteger(luaState, argumentIndex); - v.x= static_cast(lua_tonumber(luaState, argumentIndex)); - lua_pop(luaState, 1); - - //printf("X = %d\n",v.x); - - lua_rawgeti(luaState, argumentIndex, 2); - //printf("ya = %s\n",lua_tostring(luaState, argumentIndex)); - - //v.y= (int)luaL_checkinteger(luaState, argumentIndex); - v.y= static_cast(lua_tonumber(luaState, argumentIndex)); - lua_pop(luaState, 1); - - //printf("Y = %d\n",v.y); - - return v; -} - -Vec3f LuaArguments::getVec3f(int argumentIndex) const { - Lua_STREFLOP_Wrapper streflopWrapper; - - Vec3f v; - - if(!lua_istable(luaState, argumentIndex)){ - throwLuaError("Can not get vec3f from Lua state, value on the stack is not a table"); - } - -#if LUA_VERSION_NUM > 501 - if(lua_rawlen(luaState, argumentIndex)!=3){ -#else - if(luaL_getn(luaState, argumentIndex)!=3){ -#endif - throwLuaError("Can not get vec3f from Lua state, array size not 3"); - } - - //string stackString = getStackText(); - //printf("Lua Stack:\n%s\n",stackString.c_str()); - - lua_rawgeti(luaState, argumentIndex, 1); - //printf("xa = %s argumentIndex = %d\n",lua_tostring(luaState, argumentIndex),argumentIndex); - - //v.x= (int)luaL_checkinteger(luaState, argumentIndex); - v.x= static_cast(lua_tonumber(luaState, argumentIndex)); - lua_pop(luaState, 1); - - //printf("X = %d\n",v.x); - - lua_rawgeti(luaState, argumentIndex, 2); - //printf("ya = %s\n",lua_tostring(luaState, argumentIndex)); - - //v.y= (int)luaL_checkinteger(luaState, argumentIndex); - v.y= static_cast(lua_tonumber(luaState, argumentIndex)); - lua_pop(luaState, 1); - - //printf("Y = %d\n",v.y); - - lua_rawgeti(luaState, argumentIndex, 3); - //printf("ya = %s\n",lua_tostring(luaState, argumentIndex)); - - //v.y= (int)luaL_checkinteger(luaState, argumentIndex); - v.z= static_cast(lua_tonumber(luaState, argumentIndex)); - lua_pop(luaState, 1); - - return v; -} - -Vec4f LuaArguments::getVec4f(int argumentIndex) const { - Lua_STREFLOP_Wrapper streflopWrapper; - - Vec4f v; - - if(!lua_istable(luaState, argumentIndex)){ - throwLuaError("Can not get vec4f from Lua state, value on the stack is not a table"); - } - -#if LUA_VERSION_NUM > 501 - if(lua_rawlen(luaState, argumentIndex)!=4){ -#else - if(luaL_getn(luaState, argumentIndex)!=4){ -#endif - throwLuaError("Can not get vec4f from Lua state, array size not 4"); - } - - //string stackString = getStackText(); - //printf("Lua Stack:\n%s\n",stackString.c_str()); - - lua_rawgeti(luaState, argumentIndex, 1); - //printf("xa = %s argumentIndex = %d\n",lua_tostring(luaState, argumentIndex),argumentIndex); - - //v.x= (int)luaL_checkinteger(luaState, argumentIndex); - v.x= static_cast(lua_tonumber(luaState, argumentIndex)); - lua_pop(luaState, 1); - - //printf("X = %d\n",v.x); - - lua_rawgeti(luaState, argumentIndex, 2); - //printf("ya = %s\n",lua_tostring(luaState, argumentIndex)); - - //v.y= (int)luaL_checkinteger(luaState, argumentIndex); - v.y= static_cast(lua_tonumber(luaState, argumentIndex)); - lua_pop(luaState, 1); - - //printf("Y = %d\n",v.y); - - lua_rawgeti(luaState, argumentIndex, 3); - //printf("ya = %s\n",lua_tostring(luaState, argumentIndex)); - - //v.y= (int)luaL_checkinteger(luaState, argumentIndex); - v.z= static_cast(lua_tonumber(luaState, argumentIndex)); - lua_pop(luaState, 1); - - lua_rawgeti(luaState, argumentIndex, 4); - //printf("ya = %s\n",lua_tostring(luaState, argumentIndex)); - - //v.y= (int)luaL_checkinteger(luaState, argumentIndex); - v.w= static_cast(lua_tonumber(luaState, argumentIndex)); - lua_pop(luaState, 1); - - return v; -} - -string LuaArguments::getString(int argumentIndex) const{ - Lua_STREFLOP_Wrapper streflopWrapper; - - if(!lua_isstring(luaState, argumentIndex)){ - throwLuaError("Can not get string from Lua state"); - } - return luaL_checkstring(luaState, argumentIndex); -} - -void * LuaArguments::getGenericData(int argumentIndex) const{ - Lua_STREFLOP_Wrapper streflopWrapper; - - if(lua_isstring(luaState, argumentIndex)) { - const char *result = luaL_checkstring(luaState, argumentIndex); - //printf("\nGENERIC param %d is a string, %s!\n",argumentIndex,result); - return (void *)result; - } - //else if(lua_isnumber(luaState, argumentIndex)) { - // double result = luaL_checknumber(luaState, argumentIndex); - // printf("\nGENERIC param %d is a double, %f!\n",argumentIndex,result); - // return (void *)result; - //} - else if(lua_isnumber(luaState, argumentIndex)) { - lua_Integer result = luaL_checkinteger(luaState, argumentIndex); - //printf("\nGENERIC param %d is an int, %d!\n",argumentIndex,(int)result); - return (void *)result; - } - else { - //printf("\nGENERIC param %d is a NULL!\n",argumentIndex); - return NULL; - } -} - -Vec2i LuaArguments::getVec2i(int argumentIndex) const{ - Lua_STREFLOP_Wrapper streflopWrapper; - - Vec2i v; - - if(!lua_istable(luaState, argumentIndex)){ - throwLuaError("Can not get vec2i from Lua state, value on the stack is not a table"); - } - -#if LUA_VERSION_NUM > 501 - if(lua_rawlen(luaState, argumentIndex)!=2){ -#else - if(luaL_getn(luaState, argumentIndex)!=2){ -#endif - throwLuaError("Can not get vec2i from Lua state, array size not 2"); - } - - //string stackString = getStackText(); - //printf("Lua Stack:\n%s\n",stackString.c_str()); - - lua_rawgeti(luaState, argumentIndex, 1); - //printf("xa = %s argumentIndex = %d\n",lua_tostring(luaState, argumentIndex),argumentIndex); - - //v.x= (int)luaL_checkinteger(luaState, argumentIndex); - v.x= (int)lua_tointeger(luaState, argumentIndex); - lua_pop(luaState, 1); - - //printf("X = %d\n",v.x); - - lua_rawgeti(luaState, argumentIndex, 2); - //printf("ya = %s\n",lua_tostring(luaState, argumentIndex)); - - //v.y= (int)luaL_checkinteger(luaState, argumentIndex); - v.y= (int)lua_tointeger(luaState, argumentIndex); - lua_pop(luaState, 1); - - //printf("Y = %d\n",v.y); - - return v; -} - -Vec4i LuaArguments::getVec4i(int argumentIndex) const { - Lua_STREFLOP_Wrapper streflopWrapper; - - Vec4i v; - - if(!lua_istable(luaState, argumentIndex)){ - throwLuaError("Can not get vec4i from Lua state, value on the stack is not a table"); - } - -#if LUA_VERSION_NUM > 501 - if(lua_rawlen(luaState, argumentIndex) != 4 ) { -#else - if(luaL_getn(luaState, argumentIndex) != 4) { -#endif - throwLuaError("Can not get vec4i from Lua state, array size not 4"); - } - - lua_rawgeti(luaState, argumentIndex, 1); - v.x= (int)luaL_checkinteger(luaState, argumentIndex); - lua_pop(luaState, 1); - - lua_rawgeti(luaState, argumentIndex, 2); - v.y= (int)luaL_checkinteger(luaState, argumentIndex); - lua_pop(luaState, 1); - - lua_rawgeti(luaState, argumentIndex, 3); - v.z= (int)luaL_checkinteger(luaState, argumentIndex); - lua_pop(luaState, 1); - - lua_rawgeti(luaState, argumentIndex, 4); - v.w= (int)luaL_checkinteger(luaState, argumentIndex); - lua_pop(luaState, 1); - - return v; -} - -void LuaArguments::returnInt(int value){ - Lua_STREFLOP_Wrapper streflopWrapper; - - ++returnCount; - lua_pushinteger(luaState, value); -} - -void LuaArguments::returnFloat(float value){ - Lua_STREFLOP_Wrapper streflopWrapper; - - ++returnCount; - lua_pushnumber(luaState, value); -} - -void LuaArguments::returnString(const string &value){ - Lua_STREFLOP_Wrapper streflopWrapper; - - ++returnCount; - lua_pushstring(luaState, value.c_str()); -} - -void LuaArguments::returnVec2i(const Vec2i &value){ - //Lua_STREFLOP_Wrapper streflopWrapper; - - ++returnCount; - - lua_newtable(luaState); - - lua_pushnumber(luaState, value.x); - lua_rawseti(luaState, -2, 1); - - lua_pushnumber(luaState, value.y); - lua_rawseti(luaState, -2, 2); -} - -void LuaArguments::returnVec4i(const Vec4i &value) { - //Lua_STREFLOP_Wrapper streflopWrapper; - - ++returnCount; - - lua_newtable(luaState); - - lua_pushnumber(luaState, value.x); - lua_rawseti(luaState, -2, 1); - - lua_pushnumber(luaState, value.y); - lua_rawseti(luaState, -2, 2); - - lua_pushnumber(luaState, value.z); - lua_rawseti(luaState, -2, 3); - - lua_pushnumber(luaState, value.w); - lua_rawseti(luaState, -2, 4); - -} - -void LuaArguments::returnVectorInt(const vector &value) { - //Lua_STREFLOP_Wrapper streflopWrapper; - - ++returnCount; - - lua_newtable(luaState); - - for(unsigned int i = 0; i < value.size(); ++i) { - lua_pushnumber(luaState, value[i]); - lua_rawseti(luaState, -2, i+1); - } -} - -string LuaArguments::getStackText() const { - Lua_STREFLOP_Wrapper streflopWrapper; - - string stackString; - int stackSize = lua_gettop(luaState); - - //build stack string - for(int i= 1; i<=stackSize; ++i){ - stackString+= "-" + intToStr(i) + ": "; - if(lua_isnumber(luaState, -i)){ - stackString+= "Number: " + doubleToStr(luaL_checknumber(luaState, -i )); + LuaScript::~LuaScript() { + Lua_STREFLOP_Wrapper streflopWrapper; + + // LuaInterface.LuaTable luatab; + // + // luatab = lua.GetTable("_G"); + // + // + // foreach (DictionaryEntry d in luatab) + // + // { + // + // Console.WriteLine("{0} -> {1}", d.Key, d.Value); + // + // } + + //DumpGlobals(); + + lua_close(luaState); } - else if(lua_isstring(luaState, -i)){ - stackString+= "String: " + string(luaL_checkstring(luaState, -i)); - } - else if(lua_istable(luaState, -i)){ - //int tableLen = 0; + void LuaScript::loadCode(string code, string name) { + Lua_STREFLOP_Wrapper streflopWrapper; + + //printf("Code [%s]\nName [%s]\n",code.c_str(),name.c_str()); + + int errorCode = luaL_loadbuffer(luaState, code.c_str(), code.length(), name.c_str()); + if (errorCode != 0) { + printf("=========================================================\n"); + printf("Error loading lua code: %s\n", errorToString(errorCode).c_str()); + printf("Function name [%s]\ncode:\n%s\n", name.c_str(), code.c_str()); + printf("=========================================================\n"); + + throw megaglest_runtime_error("Error loading lua code: " + errorToString(errorCode), true); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d] name [%s], errorCode = %d\n", __FILE__, __FUNCTION__, __LINE__, name.c_str(), errorCode); + + //run code + errorCode = lua_pcall(luaState, 0, 0, 0); + if (errorCode != 0) { + printf("=========================================================\n"); + printf("Error calling lua pcall: %s\n", errorToString(errorCode).c_str()); + printf("=========================================================\n"); + + throw megaglest_runtime_error("Error initializing lua: " + errorToString(errorCode), true); + } + + //const char *errMsg = lua_tostring(luaState, -1); + + //printf("END of call to Name [%s]\n",name.c_str()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d] name [%s], errorCode = %d\n", __FILE__, __FUNCTION__, __LINE__, name.c_str(), errorCode); + } + + void LuaScript::setSandboxWrapperFunctionName(string name) { + sandboxWrapperFunctionName = name; + } + + void LuaScript::setSandboxCode(string code) { + sandboxCode = code; + } + + int LuaScript::runCode(string code) { + Lua_STREFLOP_Wrapper streflopWrapper; + + int errorCode = luaL_dostring(luaState, code.c_str()); + return errorCode; + } + + void LuaScript::beginCall(string functionName) { + Lua_STREFLOP_Wrapper streflopWrapper; + + currentLuaFunction = functionName; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d] functionName [%s]\n", __FILE__, __FUNCTION__, __LINE__, functionName.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) SystemFlags::OutputDebug(SystemFlags::debugPerformance, "In [%s::%s Line: %d] functionName [%s]\n", __FILE__, __FUNCTION__, __LINE__, functionName.c_str()); + + //string funcLuaFunction = functionName; + // if(sandboxWrapperFunctionName != "" && sandboxCode != "") { + // int errorCode= runCode(sandboxCode); + // if(errorCode !=0 ) { + // throw megaglest_runtime_error("Error calling lua function [" + currentLuaFunction + "] error: " + errorToString(errorCode)); + // } + // //functionName = sandboxWrapperFunctionName; + // } + lua_getglobal(luaState, functionName.c_str()); + + currentLuaFunctionIsValid = lua_isfunction(luaState, lua_gettop(luaState)); + + //printf("currentLuaFunctionIsValid = %d functionName [%s]\n",currentLuaFunctionIsValid,functionName.c_str()); + argumentCount = 0; + } + + void LuaScript::endCall() { + Lua_STREFLOP_Wrapper streflopWrapper; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d] currentLuaFunction [%s], currentLuaFunctionIsValid = %d\n", __FILE__, __FUNCTION__, __LINE__, currentLuaFunction.c_str(), currentLuaFunctionIsValid); + + if (currentLuaFunctionIsValid == true) { + if (sandboxWrapperFunctionName != "" && sandboxCode != "") { + //lua_pushstring(luaState, currentLuaFunction.c_str()); // push 1st argument, the real lua function + //argumentCount = 1; + + string safeWrapper = sandboxWrapperFunctionName + " [[" + currentLuaFunction + "()]]"; + printf("Trying to execute [%s]\n", safeWrapper.c_str()); + int errorCode = runCode(safeWrapper); + if (errorCode != 0) { + throw megaglest_runtime_error("Error calling lua function [" + currentLuaFunction + "] error: " + errorToString(errorCode), true); + } + + //printf("Trying to execute [%s]\n",currentLuaFunction.c_str()); + //lua_getglobal(luaState, sandboxWrapperFunctionName.c_str()); + //argumentCount = 1; + //lua_pushstring( luaState, currentLuaFunction.c_str() ); + + // int errorCode= lua_pcall(luaState, argumentCount, 0, 0); + // if(errorCode !=0 ) { + // throw megaglest_runtime_error("Error calling lua function [" + currentLuaFunction + "] error: " + errorToString(errorCode)); + // } + } else { + int errorCode = lua_pcall(luaState, argumentCount, 0, 0); + if (errorCode != 0) { + throw megaglest_runtime_error("Error calling lua function [" + currentLuaFunction + "] error: " + errorToString(errorCode), true); + } + } + } else { + lua_pcall(luaState, argumentCount, 0, 0); + } + } + + void LuaScript::registerFunction(LuaFunction luaFunction, string functionName) { + Lua_STREFLOP_Wrapper streflopWrapper; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA, "In [%s::%s Line: %d] functionName [%s]\n", __FILE__, __FUNCTION__, __LINE__, functionName.c_str()); + + lua_pushcfunction(luaState, luaFunction); + lua_setglobal(luaState, functionName.c_str()); + } + + string LuaScript::errorToString(int errorCode) { + Lua_STREFLOP_Wrapper streflopWrapper; + + string error; + switch (errorCode) { + case LUA_ERRSYNTAX: + error += "Syntax error"; + break; + case LUA_ERRRUN: + error += "Runtime error"; + break; + case LUA_ERRMEM: + error += "Memory allocation error"; + break; + case LUA_ERRERR: + error += "Error while running the error handler"; + break; + default: + error += "Unknown LUA error" + intToStr(errorCode); + break; + } + + error += string(": ") + luaL_checkstring(luaState, -1); + + return error; + } + + // ===================================================== + // class LuaArguments + // ===================================================== + + LuaArguments::LuaArguments(lua_State *luaState) { + Lua_STREFLOP_Wrapper streflopWrapper; + + this->luaState = luaState; + returnCount = 0; + } + + int LuaArguments::getInt(int argumentIndex) const { + Lua_STREFLOP_Wrapper streflopWrapper; + + if (!lua_isnumber(luaState, argumentIndex)) { + throwLuaError("Can not get int from Lua state"); + } + + int result = (int) luaL_checkinteger(luaState, argumentIndex); + return result; + } + + float LuaArguments::getFloat(int argumentIndex) const { + Lua_STREFLOP_Wrapper streflopWrapper; + + if (!lua_isnumber(luaState, argumentIndex)) { + throwLuaError("Can not get int from Lua state"); + } + float result = static_cast(luaL_checknumber(luaState, argumentIndex)); + return result; + } + Vec2f LuaArguments::getVec2f(int argumentIndex) const { + Lua_STREFLOP_Wrapper streflopWrapper; + + Vec2f v; + + if (!lua_istable(luaState, argumentIndex)) { + throwLuaError("Can not get vec2f from Lua state, value on the stack is not a table"); + } + #if LUA_VERSION_NUM > 501 - int tableLen = lua_rawlen(luaState, -i); + if (lua_rawlen(luaState, argumentIndex) != 2) { #else - int tableLen = luaL_getn(luaState, -i); + if (luaL_getn(luaState, argumentIndex) != 2) { #endif - stackString+= "Table (" + intToStr(tableLen) + ")\n"; -// for(unsigned int j = 1; j < tableLen; ++j) { -// stackString+= "entry# " + intToStr(j) + ", value = " + lua_tostring(luaState, -i) + "\n"; -// } + throwLuaError("Can not get vec2f from Lua state, array size not 2"); + } + //string stackString = getStackText(); + //printf("Lua Stack:\n%s\n",stackString.c_str()); -// int j = 1; -// lua_pushnil(luaState); // The initial key for the traversal. -// -// printf("start loop\n"); -// -// while (lua_next(luaState, -2)!=0) { -// printf("in loop j = %d\n",j); -// -// const char* Param=lua_tostring(luaState, -1); -// -// printf("passed in loop j = %d Param [%s]\n",j,(Param != NULL ? Param : "")); -// -// if (Param!=NULL) { -// stackString+= "entry# " + intToStr(j) + ", value = " + Param + "\n"; -// } -// -// // Remove the value, keep the key for the next iteration. -// lua_pop(luaState, 1); -// j++; -// } + lua_rawgeti(luaState, argumentIndex, 1); + //printf("xa = %s argumentIndex = %d\n",lua_tostring(luaState, argumentIndex),argumentIndex); -// const int len = lua_objlen( luaState, -i ); -// printf("Table Len = %d\n",len); -// -// for ( int j = 1; j <= len; ++j ) { -// printf("A Table\n"); -// -// lua_pushinteger( luaState, j ); -// -// printf("B Table\n"); -// -// lua_gettable( luaState, -2 ); -// -// printf("C Table\n"); -// -// //v.push_back( lua_tointeger( L, -1 ) ); -// const char *value = lua_tostring( luaState, -1 ); -// printf("D Table value = %s\n",(value != NULL ? value : "")); -// -// //v.push_back( lua_tointeger( L, -1 ) ); -// const char *value2 = lua_tostring( luaState, -2 ); -// printf("E Table value2 = %s\n",(value2 != NULL ? value2 : "")); -// -// value2 = lua_tostring( luaState, -3 ); -// printf("F Table value2 = %s\n",(value2 != NULL ? value2 : "")); -// -// value2 = lua_tostring( luaState, 0 ); -// printf("G Table value2 = %s\n",(value2 != NULL ? value2 : "")); -// -// value2 = lua_tostring( luaState, 1 ); -// printf("H Table value2 = %s\n",(value2 != NULL ? value2 : "")); -// -// stackString+= "entry# " + intToStr(j) + ", value = " + (value != NULL ? value : "") + "\n"; -// -// printf("E Table\n"); -// -// lua_pop( luaState, 1 ); -// } + //v.x= (int)luaL_checkinteger(luaState, argumentIndex); + v.x = static_cast(lua_tonumber(luaState, argumentIndex)); + lua_pop(luaState, 1); + + //printf("X = %d\n",v.x); + + lua_rawgeti(luaState, argumentIndex, 2); + //printf("ya = %s\n",lua_tostring(luaState, argumentIndex)); + + //v.y= (int)luaL_checkinteger(luaState, argumentIndex); + v.y = static_cast(lua_tonumber(luaState, argumentIndex)); + lua_pop(luaState, 1); + + //printf("Y = %d\n",v.y); + + return v; + } + + Vec3f LuaArguments::getVec3f(int argumentIndex) const { + Lua_STREFLOP_Wrapper streflopWrapper; + + Vec3f v; + + if (!lua_istable(luaState, argumentIndex)) { + throwLuaError("Can not get vec3f from Lua state, value on the stack is not a table"); + } + +#if LUA_VERSION_NUM > 501 + if (lua_rawlen(luaState, argumentIndex) != 3) { +#else + if (luaL_getn(luaState, argumentIndex) != 3) { +#endif + throwLuaError("Can not get vec3f from Lua state, array size not 3"); + } + + //string stackString = getStackText(); + //printf("Lua Stack:\n%s\n",stackString.c_str()); + + lua_rawgeti(luaState, argumentIndex, 1); + //printf("xa = %s argumentIndex = %d\n",lua_tostring(luaState, argumentIndex),argumentIndex); + + //v.x= (int)luaL_checkinteger(luaState, argumentIndex); + v.x = static_cast(lua_tonumber(luaState, argumentIndex)); + lua_pop(luaState, 1); + + //printf("X = %d\n",v.x); + + lua_rawgeti(luaState, argumentIndex, 2); + //printf("ya = %s\n",lua_tostring(luaState, argumentIndex)); + + //v.y= (int)luaL_checkinteger(luaState, argumentIndex); + v.y = static_cast(lua_tonumber(luaState, argumentIndex)); + lua_pop(luaState, 1); + + //printf("Y = %d\n",v.y); + + lua_rawgeti(luaState, argumentIndex, 3); + //printf("ya = %s\n",lua_tostring(luaState, argumentIndex)); + + //v.y= (int)luaL_checkinteger(luaState, argumentIndex); + v.z = static_cast(lua_tonumber(luaState, argumentIndex)); + lua_pop(luaState, 1); + + return v; + } + + Vec4f LuaArguments::getVec4f(int argumentIndex) const { + Lua_STREFLOP_Wrapper streflopWrapper; + + Vec4f v; + + if (!lua_istable(luaState, argumentIndex)) { + throwLuaError("Can not get vec4f from Lua state, value on the stack is not a table"); + } + +#if LUA_VERSION_NUM > 501 + if (lua_rawlen(luaState, argumentIndex) != 4) { +#else + if (luaL_getn(luaState, argumentIndex) != 4) { +#endif + throwLuaError("Can not get vec4f from Lua state, array size not 4"); + } + + //string stackString = getStackText(); + //printf("Lua Stack:\n%s\n",stackString.c_str()); + + lua_rawgeti(luaState, argumentIndex, 1); + //printf("xa = %s argumentIndex = %d\n",lua_tostring(luaState, argumentIndex),argumentIndex); + + //v.x= (int)luaL_checkinteger(luaState, argumentIndex); + v.x = static_cast(lua_tonumber(luaState, argumentIndex)); + lua_pop(luaState, 1); + + //printf("X = %d\n",v.x); + + lua_rawgeti(luaState, argumentIndex, 2); + //printf("ya = %s\n",lua_tostring(luaState, argumentIndex)); + + //v.y= (int)luaL_checkinteger(luaState, argumentIndex); + v.y = static_cast(lua_tonumber(luaState, argumentIndex)); + lua_pop(luaState, 1); + + //printf("Y = %d\n",v.y); + + lua_rawgeti(luaState, argumentIndex, 3); + //printf("ya = %s\n",lua_tostring(luaState, argumentIndex)); + + //v.y= (int)luaL_checkinteger(luaState, argumentIndex); + v.z = static_cast(lua_tonumber(luaState, argumentIndex)); + lua_pop(luaState, 1); + + lua_rawgeti(luaState, argumentIndex, 4); + //printf("ya = %s\n",lua_tostring(luaState, argumentIndex)); + + //v.y= (int)luaL_checkinteger(luaState, argumentIndex); + v.w = static_cast(lua_tonumber(luaState, argumentIndex)); + lua_pop(luaState, 1); + + return v; + } + + string LuaArguments::getString(int argumentIndex) const { + Lua_STREFLOP_Wrapper streflopWrapper; + + if (!lua_isstring(luaState, argumentIndex)) { + throwLuaError("Can not get string from Lua state"); + } + return luaL_checkstring(luaState, argumentIndex); } - else - { - stackString+= "Unknown"; + + void * LuaArguments::getGenericData(int argumentIndex) const { + Lua_STREFLOP_Wrapper streflopWrapper; + + if (lua_isstring(luaState, argumentIndex)) { + const char *result = luaL_checkstring(luaState, argumentIndex); + //printf("\nGENERIC param %d is a string, %s!\n",argumentIndex,result); + return (void *) result; + } + //else if(lua_isnumber(luaState, argumentIndex)) { + // double result = luaL_checknumber(luaState, argumentIndex); + // printf("\nGENERIC param %d is a double, %f!\n",argumentIndex,result); + // return (void *)result; + //} + else if (lua_isnumber(luaState, argumentIndex)) { + lua_Integer result = luaL_checkinteger(luaState, argumentIndex); + //printf("\nGENERIC param %d is an int, %d!\n",argumentIndex,(int)result); + return (void *) result; + } else { + //printf("\nGENERIC param %d is a NULL!\n",argumentIndex); + return NULL; + } } - stackString+= "\n"; - } - - return stackString; -} -void LuaArguments::throwLuaError(const string &message) const{ - Lua_STREFLOP_Wrapper streflopWrapper; - string stackString = getStackText(); - throw megaglest_runtime_error("Lua error: " + message + "\n\nLua Stack:\n" + stackString,true); -} + Vec2i LuaArguments::getVec2i(int argumentIndex) const { + Lua_STREFLOP_Wrapper streflopWrapper; -}}//end namespace + Vec2i v; + + if (!lua_istable(luaState, argumentIndex)) { + throwLuaError("Can not get vec2i from Lua state, value on the stack is not a table"); + } + +#if LUA_VERSION_NUM > 501 + if (lua_rawlen(luaState, argumentIndex) != 2) { +#else + if (luaL_getn(luaState, argumentIndex) != 2) { +#endif + throwLuaError("Can not get vec2i from Lua state, array size not 2"); + } + + //string stackString = getStackText(); + //printf("Lua Stack:\n%s\n",stackString.c_str()); + + lua_rawgeti(luaState, argumentIndex, 1); + //printf("xa = %s argumentIndex = %d\n",lua_tostring(luaState, argumentIndex),argumentIndex); + + //v.x= (int)luaL_checkinteger(luaState, argumentIndex); + v.x = (int) lua_tointeger(luaState, argumentIndex); + lua_pop(luaState, 1); + + //printf("X = %d\n",v.x); + + lua_rawgeti(luaState, argumentIndex, 2); + //printf("ya = %s\n",lua_tostring(luaState, argumentIndex)); + + //v.y= (int)luaL_checkinteger(luaState, argumentIndex); + v.y = (int) lua_tointeger(luaState, argumentIndex); + lua_pop(luaState, 1); + + //printf("Y = %d\n",v.y); + + return v; + } + + Vec4i LuaArguments::getVec4i(int argumentIndex) const { + Lua_STREFLOP_Wrapper streflopWrapper; + + Vec4i v; + + if (!lua_istable(luaState, argumentIndex)) { + throwLuaError("Can not get vec4i from Lua state, value on the stack is not a table"); + } + +#if LUA_VERSION_NUM > 501 + if (lua_rawlen(luaState, argumentIndex) != 4) { +#else + if (luaL_getn(luaState, argumentIndex) != 4) { +#endif + throwLuaError("Can not get vec4i from Lua state, array size not 4"); + } + + lua_rawgeti(luaState, argumentIndex, 1); + v.x = (int) luaL_checkinteger(luaState, argumentIndex); + lua_pop(luaState, 1); + + lua_rawgeti(luaState, argumentIndex, 2); + v.y = (int) luaL_checkinteger(luaState, argumentIndex); + lua_pop(luaState, 1); + + lua_rawgeti(luaState, argumentIndex, 3); + v.z = (int) luaL_checkinteger(luaState, argumentIndex); + lua_pop(luaState, 1); + + lua_rawgeti(luaState, argumentIndex, 4); + v.w = (int) luaL_checkinteger(luaState, argumentIndex); + lua_pop(luaState, 1); + + return v; + } + + void LuaArguments::returnInt(int value) { + Lua_STREFLOP_Wrapper streflopWrapper; + + ++returnCount; + lua_pushinteger(luaState, value); + } + + void LuaArguments::returnFloat(float value) { + Lua_STREFLOP_Wrapper streflopWrapper; + + ++returnCount; + lua_pushnumber(luaState, value); + } + + void LuaArguments::returnString(const string &value) { + Lua_STREFLOP_Wrapper streflopWrapper; + + ++returnCount; + lua_pushstring(luaState, value.c_str()); + } + + void LuaArguments::returnVec2i(const Vec2i &value) { + //Lua_STREFLOP_Wrapper streflopWrapper; + + ++returnCount; + + lua_newtable(luaState); + + lua_pushnumber(luaState, value.x); + lua_rawseti(luaState, -2, 1); + + lua_pushnumber(luaState, value.y); + lua_rawseti(luaState, -2, 2); + } + + void LuaArguments::returnVec4i(const Vec4i &value) { + //Lua_STREFLOP_Wrapper streflopWrapper; + + ++returnCount; + + lua_newtable(luaState); + + lua_pushnumber(luaState, value.x); + lua_rawseti(luaState, -2, 1); + + lua_pushnumber(luaState, value.y); + lua_rawseti(luaState, -2, 2); + + lua_pushnumber(luaState, value.z); + lua_rawseti(luaState, -2, 3); + + lua_pushnumber(luaState, value.w); + lua_rawseti(luaState, -2, 4); + + } + + void LuaArguments::returnVectorInt(const vector &value) { + //Lua_STREFLOP_Wrapper streflopWrapper; + + ++returnCount; + + lua_newtable(luaState); + + for (unsigned int i = 0; i < value.size(); ++i) { + lua_pushnumber(luaState, value[i]); + lua_rawseti(luaState, -2, i + 1); + } + } + + string LuaArguments::getStackText() const { + Lua_STREFLOP_Wrapper streflopWrapper; + + string stackString; + int stackSize = lua_gettop(luaState); + + //build stack string + for (int i = 1; i <= stackSize; ++i) { + stackString += "-" + intToStr(i) + ": "; + if (lua_isnumber(luaState, -i)) { + stackString += "Number: " + doubleToStr(luaL_checknumber(luaState, -i)); + } else if (lua_isstring(luaState, -i)) { + stackString += "String: " + string(luaL_checkstring(luaState, -i)); + } else if (lua_istable(luaState, -i)) { + + //int tableLen = 0; +#if LUA_VERSION_NUM > 501 + int tableLen = lua_rawlen(luaState, -i); +#else + int tableLen = luaL_getn(luaState, -i); +#endif + stackString += "Table (" + intToStr(tableLen) + ")\n"; + // for(unsigned int j = 1; j < tableLen; ++j) { + // stackString+= "entry# " + intToStr(j) + ", value = " + lua_tostring(luaState, -i) + "\n"; + // } + + + // int j = 1; + // lua_pushnil(luaState); // The initial key for the traversal. + // + // printf("start loop\n"); + // + // while (lua_next(luaState, -2)!=0) { + // printf("in loop j = %d\n",j); + // + // const char* Param=lua_tostring(luaState, -1); + // + // printf("passed in loop j = %d Param [%s]\n",j,(Param != NULL ? Param : "")); + // + // if (Param!=NULL) { + // stackString+= "entry# " + intToStr(j) + ", value = " + Param + "\n"; + // } + // + // // Remove the value, keep the key for the next iteration. + // lua_pop(luaState, 1); + // j++; + // } + + // const int len = lua_objlen( luaState, -i ); + // printf("Table Len = %d\n",len); + // + // for ( int j = 1; j <= len; ++j ) { + // printf("A Table\n"); + // + // lua_pushinteger( luaState, j ); + // + // printf("B Table\n"); + // + // lua_gettable( luaState, -2 ); + // + // printf("C Table\n"); + // + // //v.push_back( lua_tointeger( L, -1 ) ); + // const char *value = lua_tostring( luaState, -1 ); + // printf("D Table value = %s\n",(value != NULL ? value : "")); + // + // //v.push_back( lua_tointeger( L, -1 ) ); + // const char *value2 = lua_tostring( luaState, -2 ); + // printf("E Table value2 = %s\n",(value2 != NULL ? value2 : "")); + // + // value2 = lua_tostring( luaState, -3 ); + // printf("F Table value2 = %s\n",(value2 != NULL ? value2 : "")); + // + // value2 = lua_tostring( luaState, 0 ); + // printf("G Table value2 = %s\n",(value2 != NULL ? value2 : "")); + // + // value2 = lua_tostring( luaState, 1 ); + // printf("H Table value2 = %s\n",(value2 != NULL ? value2 : "")); + // + // stackString+= "entry# " + intToStr(j) + ", value = " + (value != NULL ? value : "") + "\n"; + // + // printf("E Table\n"); + // + // lua_pop( luaState, 1 ); + // } + } else { + stackString += "Unknown"; + } + stackString += "\n"; + } + + return stackString; + } + void LuaArguments::throwLuaError(const string &message) const { + Lua_STREFLOP_Wrapper streflopWrapper; + + string stackString = getStackText(); + throw megaglest_runtime_error("Lua error: " + message + "\n\nLua Stack:\n" + stackString, true); + } + + } + }//end namespace diff --git a/source/shared_lib/sources/map/map_preview.cpp b/source/shared_lib/sources/map/map_preview.cpp index 8e59333c0..57f5972b8 100644 --- a/source/shared_lib/sources/map/map_preview.cpp +++ b/source/shared_lib/sources/map/map_preview.cpp @@ -28,1196 +28,1165 @@ using namespace Shared::Util; using namespace std; -namespace Shared { namespace Map { +namespace Shared { + namespace Map { -// =============================================== -// class MapPreview -// =============================================== + // =============================================== + // class MapPreview + // =============================================== -// ================== PUBLIC ===================== + // ================== PUBLIC ===================== -MapPreview::MapPreview() { - mapFileLoaded = ""; - fileLoaded = false; - heightFactor = DEFAULT_MAP_CELL_HEIGHT_FACTOR; - waterLevel = DEFAULT_MAP_WATER_DEPTH; - cliffLevel = DEFAULT_CLIFF_HEIGHT; - cameraHeight = 0; - //cells = NULL; - cells.clear(); - //startLocations = NULL; - startLocations.clear(); - reset(DEFAULT_MAP_CELL_WIDTH, DEFAULT_MAP_CELL_LENGTH, (float)DEFAULT_MAP_CELL_HEIGHT, DEFAULT_MAP_CELL_SURFACE_TYPE); - resetFactions(DEFAULT_MAP_FACTIONCOUNT); - title = ""; - desc = ""; - author = ""; - maxFactions = 0; - refAlt = DEFAULT_MAP_CELL_HEIGHT; - hasChanged = false; -} + MapPreview::MapPreview() { + mapFileLoaded = ""; + fileLoaded = false; + heightFactor = DEFAULT_MAP_CELL_HEIGHT_FACTOR; + waterLevel = DEFAULT_MAP_WATER_DEPTH; + cliffLevel = DEFAULT_CLIFF_HEIGHT; + cameraHeight = 0; + //cells = NULL; + cells.clear(); + //startLocations = NULL; + startLocations.clear(); + reset(DEFAULT_MAP_CELL_WIDTH, DEFAULT_MAP_CELL_LENGTH, (float) DEFAULT_MAP_CELL_HEIGHT, DEFAULT_MAP_CELL_SURFACE_TYPE); + resetFactions(DEFAULT_MAP_FACTIONCOUNT); + title = ""; + desc = ""; + author = ""; + maxFactions = 0; + refAlt = DEFAULT_MAP_CELL_HEIGHT; + hasChanged = false; + } -MapPreview::~MapPreview() { - //delete [] startLocations; - //startLocations = NULL; - startLocations.clear(); + MapPreview::~MapPreview() { + //delete [] startLocations; + //startLocations = NULL; + startLocations.clear(); - //for (int i = 0; i < h; i++) { - // delete [] cells[i]; - //} - //delete [] cells; - //cells = NULL; - cells.clear(); -} + //for (int i = 0; i < h; i++) { + // delete [] cells[i]; + //} + //delete [] cells; + //cells = NULL; + cells.clear(); + } -float MapPreview::getHeight(int x, int y) const { - return cells[x][y].height; -} + float MapPreview::getHeight(int x, int y) const { + return cells[x][y].height; + } -bool MapPreview::isCliff(int x, int y){ - if(cliffLevel == 0) - return false; - for(int k= -1; k <= 1; ++k){ - for(int l= -1; l <= 1; ++l){ - int xToCheck= x + l; - int yToCheck= y + k; - if(xToCheck < 0 || yToCheck < 0 || xToCheck >= w || yToCheck >= h){ - //ignore + bool MapPreview::isCliff(int x, int y) { + if (cliffLevel == 0) + return false; + for (int k = -1; k <= 1; ++k) { + for (int l = -1; l <= 1; ++l) { + int xToCheck = x + l; + int yToCheck = y + k; + if (xToCheck < 0 || yToCheck < 0 || xToCheck >= w || yToCheck >= h) { + //ignore + } else if (cliffLevel <= abs((int) (getHeight(x, y) - getHeight(xToCheck, yToCheck)))) { + return true; + } + } } - else if(cliffLevel <= abs((int)(getHeight(x, y) - getHeight(xToCheck, yToCheck)))) { - return true; + return false; + } + + MapSurfaceType MapPreview::getSurface(int x, int y) const { + return static_cast(cells[x][y].surface); + } + + int MapPreview::getObject(int x, int y) const { + return cells[x][y].object; + } + + int MapPreview::getResource(int x, int y) const { + return cells[x][y].resource; + } + + int MapPreview::getStartLocationX(int index) const { + return startLocations[index].x; + } + + int MapPreview::getStartLocationY(int index) const { + return startLocations[index].y; + } + + static int get_dist(int delta_x, int delta_y) { + float dx = (float) delta_x; + float dy = (float) delta_y; +#ifdef USE_STREFLOP + return static_cast(streflop::sqrtf(static_cast(dx * dx + dy * dy)) + 0.5); // round correctly +#else + return static_cast(sqrtf(dx * dx + dy * dy) + 0.5); // round correctly +#endif + } + + void MapPreview::glestChangeHeight(int x, int y, int height, int radius) { + + for (int i = x - radius + 1; i < x + radius; i++) { + for (int j = y - radius + 1; j < y + radius; j++) { + if (inside(i, j)) { + int dist = get_dist(i - x, j - y); + if (radius > dist) { + int oldAlt = static_cast(cells[i][j].height); + int altInc = height * (radius - dist - 1) / radius; + if (height > 0) { + altInc++; + } + if (height < 0) { + altInc--; + } + int newAlt = refAlt + altInc; + if ((height > 0 && newAlt > oldAlt) || (height < 0 && newAlt < oldAlt) || height == 0) { + if (newAlt >= 0 && newAlt <= 20) { + cells[i][j].height = static_cast(newAlt); + hasChanged = true; + } + } + } + } + } } } - } - return false; -} -MapSurfaceType MapPreview::getSurface(int x, int y) const { - return static_cast(cells[x][y].surface); -} -int MapPreview::getObject(int x, int y) const { - return cells[x][y].object; -} + void MapPreview::pirateChangeHeight(int x, int y, int height, int radius) { + // Make sure not to try and blanket change the height over the bounds + // Find our goal height for the center of the brush -int MapPreview::getResource(int x, int y) const { - return cells[x][y].resource; -} + int overBounds = refAlt + height; + int goalAlt = overBounds; + if (overBounds > 20) { + goalAlt = 20; + } else if (overBounds < 0) { + goalAlt = 0; + } -int MapPreview::getStartLocationX(int index) const { - return startLocations[index].x; -} + // If the radius is 1 don't bother doing any calculations + if (radius == 1) { + if (inside(x, y)) { + cells[x][y].height = (float) goalAlt; + hasChanged = true; + } + return; + } -int MapPreview::getStartLocationY(int index) const { - return startLocations[index].y; -} + // Get Old height reference points and compute gradients + // from the heights of the sides and corners of the brush to the center goal height + float gradient[3][3]; // [i][j] + int indexI = 0; + for (int i = x - radius; i <= x + radius; i += radius) { + int indexJ = 0; + for (int j = y - radius; j <= y + radius; j += radius) { + // round off the corners + int ti = 0, tj = 0; + if (abs(i - x) == abs(j - y)) { + ti = (int) ((i - x) * 0.707 + x + 0.5); + tj = (int) ((j - y) * 0.707 + y + 0.5); + } else { + ti = i; + tj = j; + } + if (inside(ti, tj)) { + gradient[indexI][indexJ] = (cells[ti][tj].height - (float) goalAlt) / (float) radius; + //} else if (dist == 0) { + //gradient[indexI][indexJ] = 0; + } else { + // assume outside the map bounds is height 10 + gradient[indexI][indexJ] = (10.0f - (float) goalAlt) / (float) radius; + } + //std::cout << "gradient[" << indexI << "][" << indexJ << "] = " << gradient[indexI][indexJ] << std::endl; + //std::cout << "derived from height " << cells[ti][tj].height << " at " << ti << " " << tj << std::endl; + indexJ++; + } + indexI++; + } + //std::cout << endl; -static int get_dist(int delta_x, int delta_y) { - float dx = (float)delta_x; - float dy = (float)delta_y; + // // A brush with radius n cells should have a true radius of n-1 distance // No becasue then "radius" 1==2 + // radius -= 1; + for (int i = x - radius; i <= x + radius; i++) { + for (int j = y - radius; j <= y + radius; j++) { + int dist = get_dist(i - x, j - y); + if (inside(i, j) && dist < radius) { + // Normalize di and dj and round them to an int so they can be used as indicies + float normIf = (float(i - x) / radius); + float normJf = (float(j - y) / radius); + int normI[2]; + int normJ[2]; + float usedGrad; + + // Build a search box to find the gradients we are concerned about + // Find the nearest i indices + if (normIf < -0.33) { + normI[0] = 0; + if (normIf == 0) { + normI[1] = 0; + } else { + normI[1] = 1; + } + } else if (normIf < 0.33) { + normI[0] = 1; + if (normIf > 0) { + normI[1] = 2; + } else if (normIf < 0) { + normI[1] = 0; + } else /*(normIf == 0)*/ { + normI[1] = 1; + } + } else { + normI[0] = 2; + if (normIf == 1) { + normI[1] = 2; + } else { + normI[1] = 1; + } + } + // find nearest j indices + if (normJf < -0.33) { + normJ[0] = 0; + if (normJf == 0) { + normJ[1] = 0; + } else { + normJ[1] = 1; + } + } else if (normJf < 0.33) { + normJ[0] = 1; + if (normJf > 0) { + normJ[1] = 2; + } else if (normJf < 0) { + normJ[1] = 0; + } else /*(normJf == 0)*/ { + normJ[1] = 1; + } + } else { + normJ[0] = 2; + if (normJf == 1) { + normJ[1] = 2; + } else { + normJ[1] = 1; + } + } + + // Determine which gradients to use and take a weighted average #ifdef USE_STREFLOP - return static_cast(streflop::sqrtf(static_cast(dx * dx + dy * dy))+0.5); // round correctly + if (streflop::fabs(static_cast(normIf)) > streflop::fabs(static_cast(normJf))) { + + usedGrad = + gradient[normI[0]][normJ[0]] * streflop::fabs(static_cast(normJf)) + + gradient[normI[0]][normJ[1]] * (1 - streflop::fabs(static_cast(normJf))); + } else if (streflop::fabs(static_cast(normIf)) < streflop::fabs(static_cast(normJf))) { + usedGrad = + gradient[normI[0]][normJ[0]] * streflop::fabs(static_cast(normIf)) + + gradient[normI[1]][normJ[0]] * (1 - streflop::fabs(static_cast(normIf))); + } else { + usedGrad = + gradient[normI[0]][normJ[0]]; + } + #else - return static_cast(sqrtf(dx * dx + dy * dy)+0.5); // round correctly + if (fabs(normIf) > fabs(normJf)) { + + usedGrad = + gradient[normI[0]][normJ[0]] * fabs(normJf) + + gradient[normI[0]][normJ[1]] * (1 - fabs(normJf)); + } else if (fabs(normIf) < fabs(normJf)) { + usedGrad = + gradient[normI[0]][normJ[0]] * fabs(normIf) + + gradient[normI[1]][normJ[0]] * (1 - fabs(normIf)); + } else { + usedGrad = + gradient[normI[0]][normJ[0]]; + } #endif -} -void MapPreview::glestChangeHeight(int x, int y, int height, int radius) { + float newAlt = usedGrad * dist + goalAlt; - for (int i = x - radius + 1; i < x + radius; i++) { - for (int j = y - radius + 1; j < y + radius; j++) { - if (inside(i, j)) { - int dist = get_dist(i - x, j - y); - if (radius > dist) { - int oldAlt = static_cast(cells[i][j].height); - int altInc = height * (radius - dist - 1) / radius; - if (height > 0) { - altInc++; - } - if (height < 0) { - altInc--; - } - int newAlt = refAlt + altInc; - if ((height > 0 && newAlt > oldAlt) || (height < 0 && newAlt < oldAlt) || height == 0) { - if (newAlt >= 0 && newAlt <= 20) { - cells[i][j].height = static_cast(newAlt); + // if the change in height and what is supposed to be the change in height + // are the same sign then we can change the height + if (((newAlt - cells[i][j].height) > 0 && height > 0) || + ((newAlt - cells[i][j].height) < 0 && height < 0) || + height == 0) { + cells[i][j].height = newAlt; hasChanged = true; } } } } } - } -} - -void MapPreview::pirateChangeHeight(int x, int y, int height, int radius) { - // Make sure not to try and blanket change the height over the bounds - // Find our goal height for the center of the brush - - int overBounds = refAlt + height; - int goalAlt = overBounds; - if (overBounds > 20) { - goalAlt = 20; - } - else if (overBounds < 0) { - goalAlt = 0; - } - - // If the radius is 1 don't bother doing any calculations - if (radius == 1) { - if(inside(x, y)){ - cells[x][y].height = (float)goalAlt; + void MapPreview::setHeight(int x, int y, float height) { + cells[x][y].height = height; hasChanged = true; } - return; - } - // Get Old height reference points and compute gradients - // from the heights of the sides and corners of the brush to the center goal height - float gradient[3][3]; // [i][j] - int indexI = 0; - for (int i = x - radius; i <= x + radius; i += radius) { - int indexJ = 0; - for (int j = y - radius; j <= y + radius; j += radius) { - // round off the corners - int ti=0, tj=0; - if (abs(i - x) == abs(j - y)) { - ti = (int)((i - x) * 0.707 + x + 0.5); - tj = (int)((j - y) * 0.707 + y + 0.5); - } else { - ti = i; - tj = j; + void MapPreview::setRefAlt(int x, int y) { + if (inside(x, y)) { + refAlt = static_cast(cells[x][y].height); + hasChanged = true; } - if (inside(ti, tj)) { - gradient[indexI][indexJ] = (cells[ti][tj].height - (float)goalAlt) / (float)radius; - //} else if (dist == 0) { - //gradient[indexI][indexJ] = 0; - } - else { - // assume outside the map bounds is height 10 - gradient[indexI][indexJ] = (10.0f - (float)goalAlt) / (float)radius; - } - //std::cout << "gradient[" << indexI << "][" << indexJ << "] = " << gradient[indexI][indexJ] << std::endl; - //std::cout << "derived from height " << cells[ti][tj].height << " at " << ti << " " << tj << std::endl; - indexJ++; } - indexI++; - } - //std::cout << endl; - // // A brush with radius n cells should have a true radius of n-1 distance // No becasue then "radius" 1==2 - // radius -= 1; - for (int i = x - radius; i <= x + radius; i++) { - for (int j = y - radius; j <= y + radius; j++) { - int dist = get_dist(i - x, j - y); - if (inside(i, j) && dist < radius) { - // Normalize di and dj and round them to an int so they can be used as indicies - float normIf = (float(i - x)/ radius); - float normJf = (float(j - y)/ radius); - int normI[2]; - int normJ[2]; - float usedGrad; + void MapPreview::flipX() { + //Cell **oldCells = cells; + std::vector > oldCells = cells; - // Build a search box to find the gradients we are concerned about - // Find the nearest i indices - if (normIf < -0.33) { - normI[0] = 0; - if (normIf == 0) { - normI[1] = 0; - } - else { - normI[1] = 1; - } - } - else if (normIf < 0.33) { - normI[0] = 1; - if (normIf > 0) { - normI[1] = 2; - } - else if (normIf < 0) { - normI[1] = 0; - } - else /*(normIf == 0)*/ { - normI[1] = 1; - } - } - else { - normI[0] = 2; - if (normIf == 1) { - normI[1] = 2; - } - else { - normI[1] = 1; - } - } - // find nearest j indices - if (normJf < -0.33) { - normJ[0] = 0; - if (normJf == 0) { - normJ[1] = 0; - } - else { - normJ[1] = 1; - } - } - else if (normJf < 0.33) { - normJ[0] = 1; - if (normJf > 0) { - normJ[1] = 2; - } - else if (normJf < 0) { - normJ[1] = 0; - } - else /*(normJf == 0)*/ { - normJ[1] = 1; - } - } - else { - normJ[0] = 2; - if (normJf == 1) { - normJ[1] = 2; - } - else { - normJ[1] = 1; - } - } - - // Determine which gradients to use and take a weighted average -#ifdef USE_STREFLOP - if (streflop::fabs(static_cast(normIf)) > streflop::fabs(static_cast(normJf))) { - - usedGrad = - gradient[normI[0]] [normJ[0]] * streflop::fabs(static_cast(normJf)) + - gradient[normI[0]] [normJ[1]] * (1 - streflop::fabs(static_cast(normJf))); - } - else if (streflop::fabs(static_cast(normIf)) < streflop::fabs(static_cast(normJf))) { - usedGrad = - gradient[normI[0]] [normJ[0]] * streflop::fabs(static_cast(normIf)) + - gradient[normI[1]] [normJ[0]] * (1 - streflop::fabs(static_cast(normIf))); - } - else { - usedGrad = - gradient[normI[0]] [normJ[0]]; - } - -#else - if (fabs(normIf) > fabs(normJf)) { - - usedGrad = - gradient[normI[0]] [normJ[0]] * fabs(normJf) + - gradient[normI[0]] [normJ[1]] * (1 - fabs(normJf)); - } - else if (fabs(normIf) < fabs(normJf)) { - usedGrad = - gradient[normI[0]] [normJ[0]] * fabs(normIf) + - gradient[normI[1]] [normJ[0]] * (1 - fabs(normIf)); - } - else { - usedGrad = - gradient[normI[0]] [normJ[0]]; - } -#endif - - float newAlt = usedGrad * dist + goalAlt; - - // if the change in height and what is supposed to be the change in height - // are the same sign then we can change the height - if ( ((newAlt - cells[i][j].height) > 0 && height > 0) || - ((newAlt - cells[i][j].height) < 0 && height < 0) || - height == 0) { - cells[i][j].height = newAlt; - hasChanged = true; - } + //cells = new Cell*[w]; + cells.clear(); + cells.resize(w); + for (int i = 0; i < w; i++) { + //cells[i] = new Cell[h]; + cells[i].resize(h); + for (int j = 0; j < h; j++) { + cells[i][j].height = oldCells[w - i - 1][j].height; + cells[i][j].object = oldCells[w - i - 1][j].object; + cells[i][j].resource = oldCells[w - i - 1][j].resource; + cells[i][j].surface = oldCells[w - i - 1][j].surface; } + } + + for (int i = 0; i < maxFactions; ++i) { + startLocations[i].x = w - startLocations[i].x - 1; + } + + //for (int i = 0; i < w; i++) { + // delete [] oldCells[i]; + //} + //delete [] oldCells; + + hasChanged = true; } - } -} -void MapPreview::setHeight(int x, int y, float height) { - cells[x][y].height = height; - hasChanged = true; -} + void MapPreview::flipY() { + //Cell **oldCells = cells; + std::vector > oldCells = cells; -void MapPreview::setRefAlt(int x, int y) { - if (inside(x, y)) { - refAlt = static_cast(cells[x][y].height); - hasChanged = true; - } -} + //cells = new Cell*[w]; + cells.clear(); + cells.resize(w); -void MapPreview::flipX() { - //Cell **oldCells = cells; - std::vector > oldCells = cells; + for (int i = 0; i < w; i++) { + //cells[i] = new Cell[h]; + cells[i].resize(h); + for (int j = 0; j < h; j++) { + cells[i][j].height = oldCells[i][h - j - 1].height; + cells[i][j].object = oldCells[i][h - j - 1].object; + cells[i][j].resource = oldCells[i][h - j - 1].resource; + cells[i][j].surface = oldCells[i][h - j - 1].surface; + } + } - //cells = new Cell*[w]; - cells.clear(); - cells.resize(w); - for (int i = 0; i < w; i++) { - //cells[i] = new Cell[h]; - cells[i].resize(h); - for (int j = 0; j < h; j++) { - cells[i][j].height = oldCells[w-i-1][j].height; - cells[i][j].object = oldCells[w-i-1][j].object; - cells[i][j].resource = oldCells[w-i-1][j].resource; - cells[i][j].surface = oldCells[w-i-1][j].surface; + for (int i = 0; i < maxFactions; ++i) { + startLocations[i].y = h - startLocations[i].y - 1; + } + + //for (int i = 0; i < w; i++) { + // delete [] oldCells[i]; + //} + //delete [] oldCells; + + hasChanged = true; } - } - for (int i = 0; i < maxFactions; ++i) { - startLocations[i].x = w - startLocations[i].x - 1; - } + // Copy a cell in the map from one cell to another, used by MirrorXY etc + void MapPreview::copyXY(int x, int y, int sx, int sy) { + cells[x][y].height = cells[sx][sy].height; + cells[x][y].object = cells[sx][sy].object; + cells[x][y].resource = cells[sx][sy].resource; + cells[x][y].surface = cells[sx][sy].surface; - //for (int i = 0; i < w; i++) { - // delete [] oldCells[i]; - //} - //delete [] oldCells; - - hasChanged = true; -} - -void MapPreview::flipY() { - //Cell **oldCells = cells; - std::vector > oldCells = cells; - - //cells = new Cell*[w]; - cells.clear(); - cells.resize(w); - - for (int i = 0; i < w; i++) { - //cells[i] = new Cell[h]; - cells[i].resize(h); - for (int j = 0; j < h; j++) { - cells[i][j].height = oldCells[i][h-j-1].height; - cells[i][j].object = oldCells[i][h-j-1].object; - cells[i][j].resource = oldCells[i][h-j-1].resource; - cells[i][j].surface = oldCells[i][h-j-1].surface; + hasChanged = true; } - } - for (int i = 0; i < maxFactions; ++i) { - startLocations[i].y = h - startLocations[i].y - 1; - } + // swap a cell in the map with another, used by rotate etc + void MapPreview::swapXY(int x, int y, int sx, int sy) { + if (inside(x, y) && inside(sx, sy)) { + float tmpHeight = cells[x][y].height; + cells[x][y].height = cells[sx][sy].height; + cells[sx][sy].height = tmpHeight; - //for (int i = 0; i < w; i++) { - // delete [] oldCells[i]; - //} - //delete [] oldCells; + int tmpObject = cells[x][y].object; + cells[x][y].object = cells[sx][sy].object; + cells[sx][sy].object = tmpObject; - hasChanged = true; -} + int tmpResource = cells[x][y].resource; + cells[x][y].resource = cells[sx][sy].resource; + cells[sx][sy].resource = tmpResource; -// Copy a cell in the map from one cell to another, used by MirrorXY etc -void MapPreview::copyXY(int x, int y, int sx, int sy) { - cells[x][y].height = cells[sx][sy].height; - cells[x][y].object = cells[sx][sy].object; - cells[x][y].resource = cells[sx][sy].resource; - cells[x][y].surface = cells[sx][sy].surface; + int tmpSurface = cells[x][y].surface; + cells[x][y].surface = cells[sx][sy].surface; + cells[sx][sy].surface = tmpSurface; - hasChanged = true; -} + hasChanged = true; + } + } -// swap a cell in the map with another, used by rotate etc -void MapPreview::swapXY(int x, int y, int sx, int sy) { - if(inside(x, y) && inside(sx, sy)) { - float tmpHeight= cells[x][y].height; - cells[x][y].height= cells[sx][sy].height; - cells[sx][sy].height= tmpHeight; + void MapPreview::changeSurface(int x, int y, MapSurfaceType surface, int radius) { + int i = 0, j = 0; + int dist = 0; - int tmpObject= cells[x][y].object; - cells[x][y].object= cells[sx][sy].object; - cells[sx][sy].object= tmpObject; - - int tmpResource= cells[x][y].resource; - cells[x][y].resource= cells[sx][sy].resource; - cells[sx][sy].resource= tmpResource; - - int tmpSurface= cells[x][y].surface; - cells[x][y].surface= cells[sx][sy].surface; - cells[sx][sy].surface= tmpSurface; - - hasChanged = true; - } -} - -void MapPreview::changeSurface(int x, int y, MapSurfaceType surface, int radius) { - int i = 0, j = 0; - int dist = 0; - - for (i = x - radius + 1; i < x + radius; i++) { - for (j = y - radius + 1; j < y + radius; j++) { - if (inside(i, j)) { - dist = get_dist(i - x, j - y); - if (radius > dist) { // was >= - cells[i][j].surface = surface; - hasChanged = true; + for (i = x - radius + 1; i < x + radius; i++) { + for (j = y - radius + 1; j < y + radius; j++) { + if (inside(i, j)) { + dist = get_dist(i - x, j - y); + if (radius > dist) { // was >= + cells[i][j].surface = surface; + hasChanged = true; + } + } } } } - } -} -void MapPreview::setSurface(int x, int y, MapSurfaceType surface) { - cells[x][y].surface = surface; - hasChanged = true; -} + void MapPreview::setSurface(int x, int y, MapSurfaceType surface) { + cells[x][y].surface = surface; + hasChanged = true; + } -void MapPreview::changeObject(int x, int y, int object, int radius) { - int i = 0, j = 0; - int dist = 0; + void MapPreview::changeObject(int x, int y, int object, int radius) { + int i = 0, j = 0; + int dist = 0; - for (i = x - radius + 1; i < x + radius; i++) { - for (j = y - radius + 1; j < y + radius; j++) { - if (inside(i, j)) { - dist = get_dist(i - x, j - y); - if (radius > dist) { // was >= - cells[i][j].object = object; - cells[i][j].resource = 0; - hasChanged = true; + for (i = x - radius + 1; i < x + radius; i++) { + for (j = y - radius + 1; j < y + radius; j++) { + if (inside(i, j)) { + dist = get_dist(i - x, j - y); + if (radius > dist) { // was >= + cells[i][j].object = object; + cells[i][j].resource = 0; + hasChanged = true; + } + } } } } - } -} -void MapPreview::setObject(int x, int y, int object) { - cells[x][y].object = object; - if (object != 0) { - cells[x][y].resource = 0; - } - hasChanged = true; -} + void MapPreview::setObject(int x, int y, int object) { + cells[x][y].object = object; + if (object != 0) { + cells[x][y].resource = 0; + } + hasChanged = true; + } -void MapPreview::changeResource(int x, int y, int resource, int radius) { - int i = 0, j = 0; - int dist = 0; + void MapPreview::changeResource(int x, int y, int resource, int radius) { + int i = 0, j = 0; + int dist = 0; - for (i = x - radius + 1; i < x + radius; i++) { - for (j = y - radius + 1; j < y + radius; j++) { - if (inside(i, j)) { - dist = get_dist(i - x, j - y); - if (radius > dist) { // was >= - cells[i][j].resource = resource; + for (i = x - radius + 1; i < x + radius; i++) { + for (j = y - radius + 1; j < y + radius; j++) { + if (inside(i, j)) { + dist = get_dist(i - x, j - y); + if (radius > dist) { // was >= + cells[i][j].resource = resource; + cells[i][j].object = 0; + hasChanged = true; + } + } + } + } + } + + void MapPreview::setResource(int x, int y, int resource) { + cells[x][y].resource = resource; + if (resource != 0) { + cells[x][y].object = 0; + } + hasChanged = true; + } + + void MapPreview::changeStartLocation(int x, int y, int faction) { + if ((faction - 1) < maxFactions && inside(x, y)) { + startLocations[faction].x = x; + startLocations[faction].y = y; + hasChanged = true; + } + } + + bool MapPreview::inside(int x, int y) { + return (x >= 0 && x < w && y >= 0 && y < h); + } + + void MapPreview::reset(int w, int h, float alt, MapSurfaceType surf) { + if (w < MIN_MAP_CELL_DIMENSION || h < MIN_MAP_CELL_DIMENSION) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Size of map must be at least %dx%d", MIN_MAP_CELL_DIMENSION, MIN_MAP_CELL_DIMENSION); + throw megaglest_runtime_error(szBuf); + //return; + } + + if (w > MAX_MAP_CELL_DIMENSION || h > MAX_MAP_CELL_DIMENSION) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Size of map can be at most %dx%d", MAX_MAP_CELL_DIMENSION, MAX_MAP_CELL_DIMENSION); + throw megaglest_runtime_error(szBuf); + } + + if (alt < MIN_MAP_CELL_HEIGHT || alt > MAX_MAP_CELL_HEIGHT) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Height must be in the range %d-%d", MIN_MAP_CELL_HEIGHT, MAX_MAP_CELL_HEIGHT); + throw megaglest_runtime_error(szBuf); + } + + if (surf < st_Grass || surf > st_Ground) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Surface must be in the range %d-%d", st_Grass, st_Ground); + throw megaglest_runtime_error(szBuf); + } + + //if (cells != NULL) { + // for (int i = 0; i < this->w; i++) { + // delete [] cells[i]; + // } + // delete [] cells; + //} + cells.clear(); + + this->w = w; + this->h = h; + //this->maxFactions = maxFactions; + + //cells = new Cell*[w]; + cells.resize(w); + for (int i = 0; i < w; i++) { + //cells[i] = new Cell[h]; + cells[i].resize(h); + for (int j = 0; j < h; j++) { + cells[i][j].height = alt; cells[i][j].object = 0; - hasChanged = true; + cells[i][j].resource = 0; + cells[i][j].surface = surf; } } - } - } -} - -void MapPreview::setResource(int x, int y, int resource) { - cells[x][y].resource = resource; - if (resource != 0) { - cells[x][y].object = 0; - } - hasChanged = true; -} - -void MapPreview::changeStartLocation(int x, int y, int faction) { - if ((faction - 1) < maxFactions && inside(x, y)) { - startLocations[faction].x = x; - startLocations[faction].y = y; - hasChanged = true; - } -} - -bool MapPreview::inside(int x, int y) { - return (x >= 0 && x < w && y >= 0 && y < h); -} - -void MapPreview::reset(int w, int h, float alt, MapSurfaceType surf) { - if (w < MIN_MAP_CELL_DIMENSION || h < MIN_MAP_CELL_DIMENSION) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Size of map must be at least %dx%d",MIN_MAP_CELL_DIMENSION,MIN_MAP_CELL_DIMENSION); - throw megaglest_runtime_error(szBuf); - //return; - } - - if (w > MAX_MAP_CELL_DIMENSION || h > MAX_MAP_CELL_DIMENSION) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Size of map can be at most %dx%d",MAX_MAP_CELL_DIMENSION,MAX_MAP_CELL_DIMENSION); - throw megaglest_runtime_error(szBuf); - } - - if (alt < MIN_MAP_CELL_HEIGHT || alt > MAX_MAP_CELL_HEIGHT) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Height must be in the range %d-%d",MIN_MAP_CELL_HEIGHT,MAX_MAP_CELL_HEIGHT); - throw megaglest_runtime_error(szBuf); - } - - if (surf < st_Grass || surf > st_Ground) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Surface must be in the range %d-%d",st_Grass,st_Ground); - throw megaglest_runtime_error(szBuf); - } - - //if (cells != NULL) { - // for (int i = 0; i < this->w; i++) { - // delete [] cells[i]; - // } - // delete [] cells; - //} - cells.clear(); - - this->w = w; - this->h = h; - //this->maxFactions = maxFactions; - - //cells = new Cell*[w]; - cells.resize(w); - for (int i = 0; i < w; i++) { - //cells[i] = new Cell[h]; - cells[i].resize(h); - for (int j = 0; j < h; j++) { - cells[i][j].height = alt; - cells[i][j].object = 0; - cells[i][j].resource = 0; - cells[i][j].surface = surf; - } - } - hasChanged = true; -} - -void MapPreview::resize(int w, int h, float alt, MapSurfaceType surf) { - if (w < MIN_MAP_CELL_DIMENSION || h < MIN_MAP_CELL_DIMENSION) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Size of map must be at least %dx%d",MIN_MAP_CELL_DIMENSION,MIN_MAP_CELL_DIMENSION); - throw megaglest_runtime_error(szBuf); - //return; - } - - if (w > MAX_MAP_CELL_DIMENSION || h > MAX_MAP_CELL_DIMENSION) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Size of map can be at most %dx%d",MAX_MAP_CELL_DIMENSION,MAX_MAP_CELL_DIMENSION); - throw megaglest_runtime_error(szBuf); - } - - if (alt < MIN_MAP_CELL_HEIGHT || alt > MAX_MAP_CELL_HEIGHT) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Height must be in the range %d-%d",MIN_MAP_CELL_HEIGHT,MAX_MAP_CELL_HEIGHT); - throw megaglest_runtime_error(szBuf); - } - - if (surf < st_Grass || surf > st_Ground) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Surface must be in the range %d-%d",st_Grass,st_Ground); - throw megaglest_runtime_error(szBuf); - } - - int oldW = this->w; - int oldH = this->h; - this->w = w; - this->h = h; - //this->maxFactions = maxFactions; - - //create new cells - //Cell **oldCells = cells; - std::vector > oldCells = cells; - - //cells = new Cell*[w]; - cells.resize(w); - for (int i = 0; i < w; i++) { - //cells[i] = new Cell[h]; - cells[i].resize(h); - for (int j = 0; j < h; j++) { - cells[i][j].height = alt; - cells[i][j].object = 0; - cells[i][j].resource = 0; - cells[i][j].surface = surf; - } - } - - int wOffset = w < oldW ? 0 : (w - oldW) / 2; - int hOffset = h < oldH ? 0 : (h - oldH) / 2; - //assign old values to cells - for (int i = 0; i < oldW; i++) { - for (int j = 0; j < oldH; j++) { - if (i + wOffset < w && j + hOffset < h) { - cells[i+wOffset][j+hOffset].height = oldCells[i][j].height; - cells[i+wOffset][j+hOffset].object = oldCells[i][j].object; - cells[i+wOffset][j+hOffset].resource = oldCells[i][j].resource; - cells[i+wOffset][j+hOffset].surface = oldCells[i][j].surface; - } - } - } - for (int i = 0; i < maxFactions; ++i) { - startLocations[i].x += wOffset; - startLocations[i].y += hOffset; - } - - //delete old cells - //if (oldCells != NULL) { - // for (int i = 0; i < oldW; i++) - // delete [] oldCells[i]; - // delete [] oldCells; - //} - - hasChanged = true; -} - -void MapPreview::resetFactions(int maxPlayers) { - if (maxPlayers < MIN_MAP_FACTIONCOUNT || maxPlayers > MAX_MAP_FACTIONCOUNT) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"Max Players must be in the range %d-%d",MIN_MAP_FACTIONCOUNT,MAX_MAP_FACTIONCOUNT); - throw megaglest_runtime_error(szBuf); - } - - //if (startLocations != NULL) { - // delete [] startLocations; - // startLocations = NULL; - //} - startLocations.clear(); - - maxFactions = maxPlayers; - - //startLocations = new StartLocation[maxFactions]; - startLocations.resize(maxFactions); - for (int i = 0; i < maxFactions; i++) { - startLocations[i].x = 0; - startLocations[i].y = 0; - } - - hasChanged = true; -} - -void MapPreview::setTitle(const string &title) { - this->title = title; - hasChanged = true; -} - -void MapPreview::setDesc(const string &desc) { - this->desc = desc; - hasChanged = true; -} - -void MapPreview::setAuthor(const string &author) { - this->author = author; - hasChanged = true; -} - -void MapPreview::setAdvanced(int heightFactor, int waterLevel, int cliffLevel, int cameraHeight) { - this->heightFactor = heightFactor; - this->waterLevel = waterLevel; - this->cliffLevel = cliffLevel; - this->cameraHeight = cameraHeight; - hasChanged = true; -} - -void MapPreview::randomizeHeights(bool withReset,int minimumHeight, int maximumHeight, int chanceDivider, int smoothRecursions) { - if(withReset) resetHeights(random.randRange(8, 10)); - realRandomize(minimumHeight,maximumHeight,chanceDivider,smoothRecursions); - hasChanged = true; -} - -void MapPreview::randomizeFactions() { - int slPlaceFactorX = random.randRange(0, 1); - int slPlaceFactorY = random.randRange(0, 1) * 2; - - for (int i = 0; i < maxFactions; ++i) { - StartLocation sl; - float slNoiseFactor = random.randRange(0.5f, 0.8f); - - sl.x = static_cast(w * slNoiseFactor * ((i + slPlaceFactorX) % 2) + w * (1.f - slNoiseFactor) / 2.f); - sl.y = static_cast(h * slNoiseFactor * (((i + slPlaceFactorY) / 2) % 2) + h * (1.f - slNoiseFactor) / 2.f); - startLocations[i] = sl; - } - hasChanged = true; -} - -void MapPreview::smoothSurface(bool limitHeight) { - //float oldHeights [w*h]; - float *oldHeights = new float[w*h]; // dumb microsoft compiler cannot handle dynamic arrays, doing it manually - for (int j = 0; j < h; ++j) { - for (int i = 0; i < w; ++i) { - oldHeights[w*j+i] = cells[i][j].height; - //printf("w=%d h=%d i=%d j=%d w*h=%d w*j+i=%d \n",w,h,i,j,w*h,w*j+i); - } - } - - for (int j = 1; j < h - 1; ++j) { - for (int i = 1; i < w - 1; ++i) { - float height = 0.f; - float numUsedToSmooth = 0.f; - for (int k = -1; k <= 1; ++k) { - for (int l = -1; l <= 1; ++l) { - int tmpHeight=oldHeights[(j + k) * w + (i + l)]; - if(limitHeight && tmpHeight>20){ - tmpHeight=20; - } - if(limitHeight && tmpHeight<0){ - tmpHeight=0; - } - height += tmpHeight; - numUsedToSmooth++; - } - } - height /= numUsedToSmooth; - cells[i][j].height=height; - } - } - delete[] oldHeights; -} - -void MapPreview::switchSurfaces(MapSurfaceType surf1, MapSurfaceType surf2) { - if (surf1 >= st_Grass && surf1 <= st_Ground && surf2 >= st_Grass && surf2 <= st_Ground) { - for (int i = 0; i < w; ++i) { - for (int j = 0; j < h; ++j) { - if (cells[i][j].surface == surf1) { - cells[i][j].surface = surf2; - hasChanged = true; - } - else if (cells[i][j].surface == surf2) { - cells[i][j].surface = surf1; - hasChanged = true; - } - } - } - } - else { - throw megaglest_runtime_error("Incorrect surfaces"); - } -} - -void toEndianMapFileHeader(MapFileHeader &header) { - header.version = Shared::PlatformByteOrder::toCommonEndian(header.version); - header.maxFactions = Shared::PlatformByteOrder::toCommonEndian(header.maxFactions); - header.width = Shared::PlatformByteOrder::toCommonEndian(header.width); - header.height = Shared::PlatformByteOrder::toCommonEndian(header.height); - header.heightFactor = Shared::PlatformByteOrder::toCommonEndian(header.heightFactor); - header.waterLevel = Shared::PlatformByteOrder::toCommonEndian(header.waterLevel); - for(unsigned int i =0; i < (unsigned int)MAX_TITLE_LENGTH; ++i) { - header.title[i] = Shared::PlatformByteOrder::toCommonEndian(header.title[i]); - } - for(unsigned int i =0; i < (unsigned int)MAX_DESCRIPTION_LENGTH; ++i) { - header.description[i] = Shared::PlatformByteOrder::toCommonEndian(header.description[i]); - } -} -void fromEndianMapFileHeader(MapFileHeader &header) { - header.version = Shared::PlatformByteOrder::fromCommonEndian(header.version); - header.maxFactions = Shared::PlatformByteOrder::fromCommonEndian(header.maxFactions); - header.width = Shared::PlatformByteOrder::fromCommonEndian(header.width); - header.height = Shared::PlatformByteOrder::fromCommonEndian(header.height); - header.heightFactor = Shared::PlatformByteOrder::fromCommonEndian(header.heightFactor); - header.waterLevel = Shared::PlatformByteOrder::fromCommonEndian(header.waterLevel); - for(unsigned int i =0; i < (unsigned int)MAX_TITLE_LENGTH; ++i) { - header.title[i] = Shared::PlatformByteOrder::fromCommonEndian(header.title[i]); - } - for(unsigned int i =0; i < (unsigned int)MAX_DESCRIPTION_LENGTH; ++i) { - header.description[i] = Shared::PlatformByteOrder::fromCommonEndian(header.description[i]); - } -} - -void MapPreview::loadFromFile(const string &path) { - - // "Could not open file, result: 3 - 2 No such file or directory [C:\Documents and Settings\人間五\Application Data\megaglest\maps\clearings_in_the_woods.gbm] - -#ifdef WIN32 - wstring wstr = utf8_decode(path); - FILE* f1= _wfopen(wstr.c_str(), L"rb"); - int fileErrno = errno; -#else - FILE *f1 = fopen(path.c_str(), "rb"); -#endif - if (f1 != NULL) { - - //read header - MapFileHeader header; - size_t bytes = fread(&header, sizeof(MapFileHeader), 1, f1); - if(bytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",bytes,__LINE__); - fclose(f1); - throw megaglest_runtime_error(szBuf); - } - fromEndianMapFileHeader(header); - - heightFactor = header.heightFactor; - waterLevel = header.waterLevel; - title = header.title; - author = header.author; - cliffLevel = 0; - if(header.version == 1) { - desc = header.description; - } - else if(header.version == 2) { - desc = header.version2.short_desc; - cliffLevel=header.version2.cliffLevel; - cameraHeight=header.version2.cameraHeight; - } - - //read start locations - resetFactions(header.maxFactions); - for (int i = 0; i < maxFactions; ++i) { - bytes = fread(&startLocations[i].x, sizeof(int32), 1, f1); - if(bytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",bytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - startLocations[i].x = Shared::PlatformByteOrder::fromCommonEndian(startLocations[i].x); - - bytes = fread(&startLocations[i].y, sizeof(int32), 1, f1); - if(bytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",bytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - startLocations[i].y = Shared::PlatformByteOrder::fromCommonEndian(startLocations[i].y); - } - - //read Heights - reset(header.width, header.height, (float)DEFAULT_MAP_CELL_HEIGHT, DEFAULT_MAP_CELL_SURFACE_TYPE); - for (int j = 0; j < h; ++j) { - for (int i = 0; i < w; ++i) { - bytes = fread(&cells[i][j].height, sizeof(float), 1, f1); - if(bytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",bytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - cells[i][j].height = Shared::PlatformByteOrder::fromCommonEndian(cells[i][j].height); - } - } - - //read surfaces - for (int j = 0; j < h; ++j) { - for (int i = 0; i < w; ++i) { - bytes = fread(&cells[i][j].surface, sizeof(int8), 1, f1); - if(bytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",bytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - cells[i][j].surface = Shared::PlatformByteOrder::fromCommonEndian(cells[i][j].surface); - } - } - - //read objects - for (int j = 0; j < h; ++j) { - for (int i = 0; i < w; ++i) { - int8 obj; - bytes = fread(&obj, sizeof(int8), 1, f1); - if(bytes != 1) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.",bytes,__LINE__); - throw megaglest_runtime_error(szBuf); - } - obj = Shared::PlatformByteOrder::fromCommonEndian(obj); - - if (obj <= 10) { - cells[i][j].object = obj; - } - else { - cells[i][j].resource = obj - 10; - } - } - } - - if(f1) fclose(f1); - - fileLoaded = true; - mapFileLoaded = path; - hasChanged = false; - } - else { -#ifdef WIN32 - DWORD error = GetLastError(); - string strError = "[#5] Could not open file, result: " + intToStr(error) + " - " + intToStr(fileErrno) + " " + strerror(fileErrno) + " [" + path + "]"; - throw strError; -#else - throw megaglest_runtime_error("[#5] error opening map file: " + path); -#endif - } -} - - -void MapPreview::saveToFile(const string &path) { -#ifdef WIN32 - FILE* f1= _wfopen(utf8_decode(path).c_str(), L"wb"); -#else - FILE *f1 = fopen(path.c_str(), "wb"); -#endif - if (f1 != NULL) { - - //write header - MapFileHeader header; - memset(&header,0,sizeof(header)); - - header.version = MAP_FORMAT_VERSION; - header.maxFactions = maxFactions; - header.width = w; - header.height = h; - header.heightFactor = heightFactor; - header.waterLevel = waterLevel; - strncpy(header.title, title.c_str(), MAX_TITLE_LENGTH); - header.title[MAX_TITLE_LENGTH-1] = 0; - strncpy(header.author, author.c_str(), MAX_AUTHOR_LENGTH); - header.author[MAX_AUTHOR_LENGTH-1] = 0; - strncpy(header.version2.short_desc, desc.c_str(), MAX_DESCRIPTION_LENGTH_VERSION2); - header.version2.short_desc[MAX_DESCRIPTION_LENGTH_VERSION2-1] = 0; - header.version2.magic= 0x01020304; - header.version2.cliffLevel= cliffLevel; - header.version2.cameraHeight= cameraHeight; - - - fwrite(&header, sizeof(MapFileHeader), 1, f1); - - //write start locations - for (int i = 0; i < maxFactions; ++i) { - fwrite(&startLocations[i].x, sizeof(int32), 1, f1); - fwrite(&startLocations[i].y, sizeof(int32), 1, f1); - } - - //write Heights - for (int j = 0; j < h; ++j) { - for (int i = 0; i < w; ++i) { - fwrite(&cells[i][j].height, sizeof(float32), 1, f1); - } - } - - //write surfaces - for (int j = 0; j < h; ++j) { - for (int i = 0; i < w; ++i) { - fwrite(&cells[i][j].surface, sizeof(int8), 1, f1); - } - } - - //write objects - for (int j = 0; j < h; ++j) { - for (int i = 0; i < w; ++i) { - if (cells[i][j].resource == 0) - fwrite(&cells[i][j].object, sizeof(int8), 1, f1); - else { - int8 res = cells[i][j].resource + 10; - fwrite(&res, sizeof(int8), 1, f1); - } - } - } - - if(f1) fclose(f1); - - hasChanged = false; - } - else { - throw megaglest_runtime_error("Error opening map file: " + path); - } - - //void randomHeight(int x, int y, int height); -} - -// ==================== PRIVATE ==================== - -void MapPreview::resetHeights(int height) { - for (int i = 0; i < w; ++i) { - for (int j = 0; j < h; ++j) { - cells[i][j].height = static_cast(height); hasChanged = true; } - } -} -void MapPreview::realRandomize(int minimumHeight, int maximumHeight, int _chanceDivider, int _smoothRecursions) { - int moduloParam=abs(maximumHeight-minimumHeight); - int chanceDivider=_chanceDivider; - int smoothRecursions=_smoothRecursions; - if(moduloParam<2) moduloParam=2; - //printf("moduloParam=%d minimumHeight=%d maximumHeight=%d\n",moduloParam,minimumHeight,maximumHeight); - - // set chanceDivider to something possible - if(chanceDivider<2) chanceDivider=2; - - // set smoothRecursions to something useful - if(smoothRecursions<0) smoothRecursions=0; - if(smoothRecursions>1000) smoothRecursions=1000; - - for (int i = 1; i < w-1; ++i) { - for (int j = 1; j < h-1; ++j) { - if(rand()%chanceDivider==1){ - cells[i][j].height=(rand() % moduloParam)+minimumHeight; + void MapPreview::resize(int w, int h, float alt, MapSurfaceType surf) { + if (w < MIN_MAP_CELL_DIMENSION || h < MIN_MAP_CELL_DIMENSION) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Size of map must be at least %dx%d", MIN_MAP_CELL_DIMENSION, MIN_MAP_CELL_DIMENSION); + throw megaglest_runtime_error(szBuf); + //return; } - } - } - for( int i = 0; i(((cells[x][y].height * strenght) + newHeight) / (strenght + 1)); - hasChanged = true; -} - -bool MapPreview::loadMapInfo(string file, MapInfo *mapInfo, string i18nMaxMapPlayersTitle,string i18nMapSizeTitle,bool errorOnInvalidMap) { - bool validMap = false; - FILE *f = NULL; - try { -#ifdef WIN32 - f= _wfopen(utf8_decode(file).c_str(), L"rb"); -#else - f= fopen(file.c_str(), "rb"); -#endif - if(f == NULL) { - throw megaglest_runtime_error("Can't open file"); - } - - MapFileHeader header; - size_t readBytes = fread(&header, sizeof(MapFileHeader), 1, f); - if(readBytes != 1) { - validMap = false; - - if(errorOnInvalidMap == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d]\nfile [%s]\nreadBytes != sizeof(MapFileHeader) [" MG_SIZE_T_SPECIFIER "] [" MG_SIZE_T_SPECIFIER "]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,file.c_str(),readBytes,sizeof(MapFileHeader)); - SystemFlags::OutputDebug(SystemFlags::debugError,"%s",szBuf); + if (w > MAX_MAP_CELL_DIMENSION || h > MAX_MAP_CELL_DIMENSION) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Size of map can be at most %dx%d", MAX_MAP_CELL_DIMENSION, MAX_MAP_CELL_DIMENSION); throw megaglest_runtime_error(szBuf); } - } - else { - fromEndianMapFileHeader(header); - if(header.version < mapver_1 || header.version >= mapver_MAX) { - validMap = false; + if (alt < MIN_MAP_CELL_HEIGHT || alt > MAX_MAP_CELL_HEIGHT) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Height must be in the range %d-%d", MIN_MAP_CELL_HEIGHT, MAX_MAP_CELL_HEIGHT); + throw megaglest_runtime_error(szBuf); + } - if(errorOnInvalidMap == true) { - char szBuf[4096]=""; - printf("In [%s::%s Line: %d]\file [%s]\nheader.version < mapver_1 || header.version >= mapver_MAX [%d] [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,file.c_str(),header.version,mapver_MAX); - SystemFlags::OutputDebug(SystemFlags::debugError,"%s",szBuf); + if (surf < st_Grass || surf > st_Ground) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Surface must be in the range %d-%d", st_Grass, st_Ground); + throw megaglest_runtime_error(szBuf); + } - throw megaglest_runtime_error(szBuf); + int oldW = this->w; + int oldH = this->h; + this->w = w; + this->h = h; + //this->maxFactions = maxFactions; + + //create new cells + //Cell **oldCells = cells; + std::vector > oldCells = cells; + + //cells = new Cell*[w]; + cells.resize(w); + for (int i = 0; i < w; i++) { + //cells[i] = new Cell[h]; + cells[i].resize(h); + for (int j = 0; j < h; j++) { + cells[i][j].height = alt; + cells[i][j].object = 0; + cells[i][j].resource = 0; + cells[i][j].surface = surf; } } - else if(header.maxFactions <= 0 || header.maxFactions > MAX_MAP_FACTIONCOUNT) { - validMap = false; - if(errorOnInvalidMap == true) { - char szBuf[4096]=""; - printf("In [%s::%s Line: %d]\file [%s]\nheader.maxFactions <= 0 || header.maxFactions > MAX_MAP_FACTIONCOUNT [%d] [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,file.c_str(),header.maxFactions,MAX_MAP_FACTIONCOUNT); - SystemFlags::OutputDebug(SystemFlags::debugError,"%s",szBuf); - - throw megaglest_runtime_error(szBuf); + int wOffset = w < oldW ? 0 : (w - oldW) / 2; + int hOffset = h < oldH ? 0 : (h - oldH) / 2; + //assign old values to cells + for (int i = 0; i < oldW; i++) { + for (int j = 0; j < oldH; j++) { + if (i + wOffset < w && j + hOffset < h) { + cells[i + wOffset][j + hOffset].height = oldCells[i][j].height; + cells[i + wOffset][j + hOffset].object = oldCells[i][j].object; + cells[i + wOffset][j + hOffset].resource = oldCells[i][j].resource; + cells[i + wOffset][j + hOffset].surface = oldCells[i][j].surface; + } } } - else { - mapInfo->size.x = header.width; - mapInfo->size.y = header.height; - mapInfo->players= header.maxFactions; + for (int i = 0; i < maxFactions; ++i) { + startLocations[i].x += wOffset; + startLocations[i].y += hOffset; + } - // hardMaxPlayers is used in menu_state_custom_game, as part of - // enhanced observer mode (issue #13) - mapInfo->hardMaxPlayers = mapInfo->players; + //delete old cells + //if (oldCells != NULL) { + // for (int i = 0; i < oldW; i++) + // delete [] oldCells[i]; + // delete [] oldCells; + //} - mapInfo->desc = i18nMaxMapPlayersTitle + ": " + intToStr(mapInfo->players) + "\n"; - mapInfo->desc += i18nMapSizeTitle + ": " + intToStr(mapInfo->size.x) + " x " + intToStr(mapInfo->size.y); + hasChanged = true; + } - validMap = true; + void MapPreview::resetFactions(int maxPlayers) { + if (maxPlayers < MIN_MAP_FACTIONCOUNT || maxPlayers > MAX_MAP_FACTIONCOUNT) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "Max Players must be in the range %d-%d", MIN_MAP_FACTIONCOUNT, MAX_MAP_FACTIONCOUNT); + throw megaglest_runtime_error(szBuf); + } + + //if (startLocations != NULL) { + // delete [] startLocations; + // startLocations = NULL; + //} + startLocations.clear(); + + maxFactions = maxPlayers; + + //startLocations = new StartLocation[maxFactions]; + startLocations.resize(maxFactions); + for (int i = 0; i < maxFactions; i++) { + startLocations[i].x = 0; + startLocations[i].y = 0; + } + + hasChanged = true; + } + + void MapPreview::setTitle(const string &title) { + this->title = title; + hasChanged = true; + } + + void MapPreview::setDesc(const string &desc) { + this->desc = desc; + hasChanged = true; + } + + void MapPreview::setAuthor(const string &author) { + this->author = author; + hasChanged = true; + } + + void MapPreview::setAdvanced(int heightFactor, int waterLevel, int cliffLevel, int cameraHeight) { + this->heightFactor = heightFactor; + this->waterLevel = waterLevel; + this->cliffLevel = cliffLevel; + this->cameraHeight = cameraHeight; + hasChanged = true; + } + + void MapPreview::randomizeHeights(bool withReset, int minimumHeight, int maximumHeight, int chanceDivider, int smoothRecursions) { + if (withReset) resetHeights(random.randRange(8, 10)); + realRandomize(minimumHeight, maximumHeight, chanceDivider, smoothRecursions); + hasChanged = true; + } + + void MapPreview::randomizeFactions() { + int slPlaceFactorX = random.randRange(0, 1); + int slPlaceFactorY = random.randRange(0, 1) * 2; + + for (int i = 0; i < maxFactions; ++i) { + StartLocation sl; + float slNoiseFactor = random.randRange(0.5f, 0.8f); + + sl.x = static_cast(w * slNoiseFactor * ((i + slPlaceFactorX) % 2) + w * (1.f - slNoiseFactor) / 2.f); + sl.y = static_cast(h * slNoiseFactor * (((i + slPlaceFactorY) / 2) % 2) + h * (1.f - slNoiseFactor) / 2.f); + startLocations[i] = sl; + } + hasChanged = true; + } + + void MapPreview::smoothSurface(bool limitHeight) { + //float oldHeights [w*h]; + float *oldHeights = new float[w*h]; // dumb microsoft compiler cannot handle dynamic arrays, doing it manually + for (int j = 0; j < h; ++j) { + for (int i = 0; i < w; ++i) { + oldHeights[w*j + i] = cells[i][j].height; + //printf("w=%d h=%d i=%d j=%d w*h=%d w*j+i=%d \n",w,h,i,j,w*h,w*j+i); + } + } + + for (int j = 1; j < h - 1; ++j) { + for (int i = 1; i < w - 1; ++i) { + float height = 0.f; + float numUsedToSmooth = 0.f; + for (int k = -1; k <= 1; ++k) { + for (int l = -1; l <= 1; ++l) { + int tmpHeight = oldHeights[(j + k) * w + (i + l)]; + if (limitHeight && tmpHeight > 20) { + tmpHeight = 20; + } + if (limitHeight && tmpHeight < 0) { + tmpHeight = 0; + } + height += tmpHeight; + numUsedToSmooth++; + } + } + height /= numUsedToSmooth; + cells[i][j].height = height; + } + } + delete[] oldHeights; + } + + void MapPreview::switchSurfaces(MapSurfaceType surf1, MapSurfaceType surf2) { + if (surf1 >= st_Grass && surf1 <= st_Ground && surf2 >= st_Grass && surf2 <= st_Ground) { + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + if (cells[i][j].surface == surf1) { + cells[i][j].surface = surf2; + hasChanged = true; + } else if (cells[i][j].surface == surf2) { + cells[i][j].surface = surf1; + hasChanged = true; + } + } + } + } else { + throw megaglest_runtime_error("Incorrect surfaces"); } } - fclose(f); - } - catch(exception &e) { - if(f) fclose(f); - - //assert(0); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s] loading map [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what(),file.c_str()); - throw megaglest_runtime_error("Error loading map file: [" + file + "] msg: " + e.what() + " errno [" + intToStr(errno) + "] [" + strerror(errno) + "]"); - } - - return validMap; -} - -// static -string MapPreview::getMapPath(const vector &pathList, const string &mapName, - string scenarioDir, bool errorOnNotFound) { - for(unsigned int idx = 0; idx < pathList.size(); idx++) { - string map_path = pathList[idx]; - endPathWithSlash(map_path); - - const string original = map_path + mapName; - const string mega = map_path + mapName + ".mgm"; - const string glest = map_path + mapName + ".gbm"; - - if((EndsWith(original,".mgm") == true || EndsWith(original,".gbm") == true) && - fileExists(original)) { - return original; - } - else if (fileExists(mega)) { - return mega; - } - else if (fileExists(glest)) { - return glest; - } - } - - if(errorOnNotFound == true) { - throw megaglest_runtime_error("Map [" + mapName + "] not found, scenarioDir [" + scenarioDir + "]"); - } - - return ""; -} - -vector MapPreview::findAllValidMaps(const vector &pathList, - string scenarioDir, bool getUserDataOnly, bool cutExtension, - vector *invalidMapList) { - vector results; - - if(getUserDataOnly == true) { - if(pathList.size() > 1) { - string path = pathList[1]; - endPathWithSlash(path); - - vector results2; - set allMaps2; - findAll(path + "*.gbm", results2, cutExtension, false); - copy(results2.begin(), results2.end(), std::inserter(allMaps2, allMaps2.begin())); - - results2.clear(); - findAll(path + "*.mgm", results2, cutExtension, false); - copy(results2.begin(), results2.end(), std::inserter(allMaps2, allMaps2.begin())); - - results2.clear(); - copy(allMaps2.begin(), allMaps2.end(), std::back_inserter(results2)); - results = results2; - //printf("\n\nMap path [%s] mapFilesUserData.size() = %d\n\n\n",path.c_str(),mapFilesUserData.size()); - } - } - else { - set allMaps; - findAll(pathList, "*.gbm", results, cutExtension, false); - copy(results.begin(), results.end(), std::inserter(allMaps, allMaps.begin())); - - results.clear(); - findAll(pathList, "*.mgm", results, cutExtension, false); - copy(results.begin(), results.end(), std::inserter(allMaps, allMaps.begin())); - results.clear(); - - copy(allMaps.begin(), allMaps.end(), std::back_inserter(results)); - } - - vector mapFiles = results; - results.clear(); - - MapInfo mapInfo; - for(unsigned int i= 0; i < mapFiles.size(); i++){// fetch info and put map in right list - //loadMapInfo(string file, MapInfo *mapInfo, string i18nMaxMapPlayersTitle,string i18nMapSizeTitle,bool errorOnInvalidMap=true); - //printf("getMapPath [%s]\nmapFiles.at(i) [%s]\nscenarioDir [%s] getUserDataOnly = %d cutExtension = %d\n",getMapPath(pathList,mapFiles.at(i), scenarioDir, false).c_str(),mapFiles.at(i).c_str(),scenarioDir.c_str(), getUserDataOnly, cutExtension); - - if(loadMapInfo(getMapPath(pathList,mapFiles.at(i), scenarioDir, false), &mapInfo, "", "", false) == true) { - results.push_back(mapFiles.at(i)); - } - else { - if(invalidMapList != NULL) { - invalidMapList->push_back(getMapPath(pathList,mapFiles.at(i), scenarioDir, false)); + void toEndianMapFileHeader(MapFileHeader &header) { + header.version = Shared::PlatformByteOrder::toCommonEndian(header.version); + header.maxFactions = Shared::PlatformByteOrder::toCommonEndian(header.maxFactions); + header.width = Shared::PlatformByteOrder::toCommonEndian(header.width); + header.height = Shared::PlatformByteOrder::toCommonEndian(header.height); + header.heightFactor = Shared::PlatformByteOrder::toCommonEndian(header.heightFactor); + header.waterLevel = Shared::PlatformByteOrder::toCommonEndian(header.waterLevel); + for (unsigned int i = 0; i < (unsigned int) MAX_TITLE_LENGTH; ++i) { + header.title[i] = Shared::PlatformByteOrder::toCommonEndian(header.title[i]); + } + for (unsigned int i = 0; i < (unsigned int) MAX_DESCRIPTION_LENGTH; ++i) { + header.description[i] = Shared::PlatformByteOrder::toCommonEndian(header.description[i]); } } + void fromEndianMapFileHeader(MapFileHeader &header) { + header.version = Shared::PlatformByteOrder::fromCommonEndian(header.version); + header.maxFactions = Shared::PlatformByteOrder::fromCommonEndian(header.maxFactions); + header.width = Shared::PlatformByteOrder::fromCommonEndian(header.width); + header.height = Shared::PlatformByteOrder::fromCommonEndian(header.height); + header.heightFactor = Shared::PlatformByteOrder::fromCommonEndian(header.heightFactor); + header.waterLevel = Shared::PlatformByteOrder::fromCommonEndian(header.waterLevel); + for (unsigned int i = 0; i < (unsigned int) MAX_TITLE_LENGTH; ++i) { + header.title[i] = Shared::PlatformByteOrder::fromCommonEndian(header.title[i]); + } + for (unsigned int i = 0; i < (unsigned int) MAX_DESCRIPTION_LENGTH; ++i) { + header.description[i] = Shared::PlatformByteOrder::fromCommonEndian(header.description[i]); + } + } + + void MapPreview::loadFromFile(const string &path) { + + // "Could not open file, result: 3 - 2 No such file or directory [C:\Documents and Settings\人間五\Application Data\megaglest\maps\clearings_in_the_woods.gbm] + +#ifdef WIN32 + wstring wstr = utf8_decode(path); + FILE* f1 = _wfopen(wstr.c_str(), L"rb"); + int fileErrno = errno; +#else + FILE *f1 = fopen(path.c_str(), "rb"); +#endif + if (f1 != NULL) { + + //read header + MapFileHeader header; + size_t bytes = fread(&header, sizeof(MapFileHeader), 1, f1); + if (bytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", bytes, __LINE__); + fclose(f1); + throw megaglest_runtime_error(szBuf); + } + fromEndianMapFileHeader(header); + + heightFactor = header.heightFactor; + waterLevel = header.waterLevel; + title = header.title; + author = header.author; + cliffLevel = 0; + if (header.version == 1) { + desc = header.description; + } else if (header.version == 2) { + desc = header.version2.short_desc; + cliffLevel = header.version2.cliffLevel; + cameraHeight = header.version2.cameraHeight; + } + + //read start locations + resetFactions(header.maxFactions); + for (int i = 0; i < maxFactions; ++i) { + bytes = fread(&startLocations[i].x, sizeof(int32), 1, f1); + if (bytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", bytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + startLocations[i].x = Shared::PlatformByteOrder::fromCommonEndian(startLocations[i].x); + + bytes = fread(&startLocations[i].y, sizeof(int32), 1, f1); + if (bytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", bytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + startLocations[i].y = Shared::PlatformByteOrder::fromCommonEndian(startLocations[i].y); + } + + //read Heights + reset(header.width, header.height, (float) DEFAULT_MAP_CELL_HEIGHT, DEFAULT_MAP_CELL_SURFACE_TYPE); + for (int j = 0; j < h; ++j) { + for (int i = 0; i < w; ++i) { + bytes = fread(&cells[i][j].height, sizeof(float), 1, f1); + if (bytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", bytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + cells[i][j].height = Shared::PlatformByteOrder::fromCommonEndian(cells[i][j].height); + } + } + + //read surfaces + for (int j = 0; j < h; ++j) { + for (int i = 0; i < w; ++i) { + bytes = fread(&cells[i][j].surface, sizeof(int8), 1, f1); + if (bytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", bytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + cells[i][j].surface = Shared::PlatformByteOrder::fromCommonEndian(cells[i][j].surface); + } + } + + //read objects + for (int j = 0; j < h; ++j) { + for (int i = 0; i < w; ++i) { + int8 obj; + bytes = fread(&obj, sizeof(int8), 1, f1); + if (bytes != 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "fread returned wrong size = " MG_SIZE_T_SPECIFIER " on line: %d.", bytes, __LINE__); + throw megaglest_runtime_error(szBuf); + } + obj = Shared::PlatformByteOrder::fromCommonEndian(obj); + + if (obj <= 10) { + cells[i][j].object = obj; + } else { + cells[i][j].resource = obj - 10; + } + } + } + + if (f1) fclose(f1); + + fileLoaded = true; + mapFileLoaded = path; + hasChanged = false; + } else { +#ifdef WIN32 + DWORD error = GetLastError(); + string strError = "[#5] Could not open file, result: " + intToStr(error) + " - " + intToStr(fileErrno) + " " + strerror(fileErrno) + " [" + path + "]"; + throw strError; +#else + throw megaglest_runtime_error("[#5] error opening map file: " + path); +#endif + } + } + + + void MapPreview::saveToFile(const string &path) { +#ifdef WIN32 + FILE* f1 = _wfopen(utf8_decode(path).c_str(), L"wb"); +#else + FILE *f1 = fopen(path.c_str(), "wb"); +#endif + if (f1 != NULL) { + + //write header + MapFileHeader header; + memset(&header, 0, sizeof(header)); + + header.version = MAP_FORMAT_VERSION; + header.maxFactions = maxFactions; + header.width = w; + header.height = h; + header.heightFactor = heightFactor; + header.waterLevel = waterLevel; + strncpy(header.title, title.c_str(), MAX_TITLE_LENGTH); + header.title[MAX_TITLE_LENGTH - 1] = 0; + strncpy(header.author, author.c_str(), MAX_AUTHOR_LENGTH); + header.author[MAX_AUTHOR_LENGTH - 1] = 0; + strncpy(header.version2.short_desc, desc.c_str(), MAX_DESCRIPTION_LENGTH_VERSION2); + header.version2.short_desc[MAX_DESCRIPTION_LENGTH_VERSION2 - 1] = 0; + header.version2.magic = 0x01020304; + header.version2.cliffLevel = cliffLevel; + header.version2.cameraHeight = cameraHeight; + + + fwrite(&header, sizeof(MapFileHeader), 1, f1); + + //write start locations + for (int i = 0; i < maxFactions; ++i) { + fwrite(&startLocations[i].x, sizeof(int32), 1, f1); + fwrite(&startLocations[i].y, sizeof(int32), 1, f1); + } + + //write Heights + for (int j = 0; j < h; ++j) { + for (int i = 0; i < w; ++i) { + fwrite(&cells[i][j].height, sizeof(float32), 1, f1); + } + } + + //write surfaces + for (int j = 0; j < h; ++j) { + for (int i = 0; i < w; ++i) { + fwrite(&cells[i][j].surface, sizeof(int8), 1, f1); + } + } + + //write objects + for (int j = 0; j < h; ++j) { + for (int i = 0; i < w; ++i) { + if (cells[i][j].resource == 0) + fwrite(&cells[i][j].object, sizeof(int8), 1, f1); + else { + int8 res = cells[i][j].resource + 10; + fwrite(&res, sizeof(int8), 1, f1); + } + } + } + + if (f1) fclose(f1); + + hasChanged = false; + } else { + throw megaglest_runtime_error("Error opening map file: " + path); + } + + //void randomHeight(int x, int y, int height); + } + + // ==================== PRIVATE ==================== + + void MapPreview::resetHeights(int height) { + for (int i = 0; i < w; ++i) { + for (int j = 0; j < h; ++j) { + cells[i][j].height = static_cast(height); + hasChanged = true; + } + } + } + + void MapPreview::realRandomize(int minimumHeight, int maximumHeight, int _chanceDivider, int _smoothRecursions) { + int moduloParam = abs(maximumHeight - minimumHeight); + int chanceDivider = _chanceDivider; + int smoothRecursions = _smoothRecursions; + if (moduloParam < 2) moduloParam = 2; + //printf("moduloParam=%d minimumHeight=%d maximumHeight=%d\n",moduloParam,minimumHeight,maximumHeight); + + // set chanceDivider to something possible + if (chanceDivider < 2) chanceDivider = 2; + + // set smoothRecursions to something useful + if (smoothRecursions < 0) smoothRecursions = 0; + if (smoothRecursions > 1000) smoothRecursions = 1000; + + for (int i = 1; i < w - 1; ++i) { + for (int j = 1; j < h - 1; ++j) { + if (rand() % chanceDivider == 1) { + cells[i][j].height = (rand() % moduloParam) + minimumHeight; + } + } + } + for (int i = 0; i < smoothRecursions; ++i) { + if (i + 1 == smoothRecursions) + smoothSurface(true); + else + smoothSurface(false); + } + } + + void MapPreview::applyNewHeight(float newHeight, int x, int y, int strenght) { + cells[x][y].height = static_cast(((cells[x][y].height * strenght) + newHeight) / (strenght + 1)); + hasChanged = true; + } + + bool MapPreview::loadMapInfo(string file, MapInfo *mapInfo, string i18nMaxMapPlayersTitle, string i18nMapSizeTitle, bool errorOnInvalidMap) { + bool validMap = false; + FILE *f = NULL; + try { +#ifdef WIN32 + f = _wfopen(utf8_decode(file).c_str(), L"rb"); +#else + f = fopen(file.c_str(), "rb"); +#endif + if (f == NULL) { + throw megaglest_runtime_error("Can't open file"); + } + + MapFileHeader header; + size_t readBytes = fread(&header, sizeof(MapFileHeader), 1, f); + if (readBytes != 1) { + validMap = false; + + if (errorOnInvalidMap == true) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d]\nfile [%s]\nreadBytes != sizeof(MapFileHeader) [" MG_SIZE_T_SPECIFIER "] [" MG_SIZE_T_SPECIFIER "]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, file.c_str(), readBytes, sizeof(MapFileHeader)); + SystemFlags::OutputDebug(SystemFlags::debugError, "%s", szBuf); + + throw megaglest_runtime_error(szBuf); + } + } else { + fromEndianMapFileHeader(header); + + if (header.version < mapver_1 || header.version >= mapver_MAX) { + validMap = false; + + if (errorOnInvalidMap == true) { + char szBuf[4096] = ""; + printf("In [%s::%s Line: %d]\file [%s]\nheader.version < mapver_1 || header.version >= mapver_MAX [%d] [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, file.c_str(), header.version, mapver_MAX); + SystemFlags::OutputDebug(SystemFlags::debugError, "%s", szBuf); + + throw megaglest_runtime_error(szBuf); + } + } else if (header.maxFactions <= 0 || header.maxFactions > MAX_MAP_FACTIONCOUNT) { + validMap = false; + + if (errorOnInvalidMap == true) { + char szBuf[4096] = ""; + printf("In [%s::%s Line: %d]\file [%s]\nheader.maxFactions <= 0 || header.maxFactions > MAX_MAP_FACTIONCOUNT [%d] [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, file.c_str(), header.maxFactions, MAX_MAP_FACTIONCOUNT); + SystemFlags::OutputDebug(SystemFlags::debugError, "%s", szBuf); + + throw megaglest_runtime_error(szBuf); + } + } else { + mapInfo->size.x = header.width; + mapInfo->size.y = header.height; + mapInfo->players = header.maxFactions; + + // hardMaxPlayers is used in menu_state_custom_game, as part of + // enhanced observer mode (issue #13) + mapInfo->hardMaxPlayers = mapInfo->players; + + mapInfo->desc = i18nMaxMapPlayersTitle + ": " + intToStr(mapInfo->players) + "\n"; + mapInfo->desc += i18nMapSizeTitle + ": " + intToStr(mapInfo->size.x) + " x " + intToStr(mapInfo->size.y); + + validMap = true; + } + } + + fclose(f); + } catch (exception &e) { + if (f) fclose(f); + + //assert(0); + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s] loading map [%s]\n", __FILE__, __FUNCTION__, __LINE__, e.what(), file.c_str()); + throw megaglest_runtime_error("Error loading map file: [" + file + "] msg: " + e.what() + " errno [" + intToStr(errno) + "] [" + strerror(errno) + "]"); + } + + return validMap; + } + + // static + string MapPreview::getMapPath(const vector &pathList, const string &mapName, + string scenarioDir, bool errorOnNotFound) { + for (unsigned int idx = 0; idx < pathList.size(); idx++) { + string map_path = pathList[idx]; + endPathWithSlash(map_path); + + const string original = map_path + mapName; + const string mega = map_path + mapName + ".mgm"; + const string glest = map_path + mapName + ".gbm"; + + if ((EndsWith(original, ".mgm") == true || EndsWith(original, ".gbm") == true) && + fileExists(original)) { + return original; + } else if (fileExists(mega)) { + return mega; + } else if (fileExists(glest)) { + return glest; + } + } + + if (errorOnNotFound == true) { + throw megaglest_runtime_error("Map [" + mapName + "] not found, scenarioDir [" + scenarioDir + "]"); + } + + return ""; + } + + vector MapPreview::findAllValidMaps(const vector &pathList, + string scenarioDir, bool getUserDataOnly, bool cutExtension, + vector *invalidMapList) { + vector results; + + if (getUserDataOnly == true) { + if (pathList.size() > 1) { + string path = pathList[1]; + endPathWithSlash(path); + + vector results2; + set allMaps2; + findAll(path + "*.gbm", results2, cutExtension, false); + copy(results2.begin(), results2.end(), std::inserter(allMaps2, allMaps2.begin())); + + results2.clear(); + findAll(path + "*.mgm", results2, cutExtension, false); + copy(results2.begin(), results2.end(), std::inserter(allMaps2, allMaps2.begin())); + + results2.clear(); + copy(allMaps2.begin(), allMaps2.end(), std::back_inserter(results2)); + results = results2; + //printf("\n\nMap path [%s] mapFilesUserData.size() = %d\n\n\n",path.c_str(),mapFilesUserData.size()); + } + } else { + set allMaps; + findAll(pathList, "*.gbm", results, cutExtension, false); + copy(results.begin(), results.end(), std::inserter(allMaps, allMaps.begin())); + + results.clear(); + findAll(pathList, "*.mgm", results, cutExtension, false); + copy(results.begin(), results.end(), std::inserter(allMaps, allMaps.begin())); + results.clear(); + + copy(allMaps.begin(), allMaps.end(), std::back_inserter(results)); + } + + vector mapFiles = results; + results.clear(); + + MapInfo mapInfo; + for (unsigned int i = 0; i < mapFiles.size(); i++) {// fetch info and put map in right list + //loadMapInfo(string file, MapInfo *mapInfo, string i18nMaxMapPlayersTitle,string i18nMapSizeTitle,bool errorOnInvalidMap=true); + //printf("getMapPath [%s]\nmapFiles.at(i) [%s]\nscenarioDir [%s] getUserDataOnly = %d cutExtension = %d\n",getMapPath(pathList,mapFiles.at(i), scenarioDir, false).c_str(),mapFiles.at(i).c_str(),scenarioDir.c_str(), getUserDataOnly, cutExtension); + + if (loadMapInfo(getMapPath(pathList, mapFiles.at(i), scenarioDir, false), &mapInfo, "", "", false) == true) { + results.push_back(mapFiles.at(i)); + } else { + if (invalidMapList != NULL) { + invalidMapList->push_back(getMapPath(pathList, mapFiles.at(i), scenarioDir, false)); + } + } + } + + return results; + } + } - - return results; -} - -}}// end namespace +}// end namespace diff --git a/source/shared_lib/sources/platform/common/base_thread.cpp b/source/shared_lib/sources/platform/common/base_thread.cpp index 8bc5c01cc..5467c6e70 100644 --- a/source/shared_lib/sources/platform/common/base_thread.cpp +++ b/source/shared_lib/sources/platform/common/base_thread.cpp @@ -19,345 +19,347 @@ using namespace Shared::Util; -namespace Shared { namespace PlatformCommon { +namespace Shared { + namespace PlatformCommon { -Mutex BaseThread::mutexMasterThreadList; -std::map BaseThread::masterThreadList; + Mutex BaseThread::mutexMasterThreadList; + std::map BaseThread::masterThreadList; -BaseThread::BaseThread() : Thread(), - mutexRunning(new Mutex(CODE_AT_LINE)), - mutexQuit(new Mutex(CODE_AT_LINE)), - mutexBeginExecution(new Mutex(CODE_AT_LINE)), - mutexDeleteSelfOnExecutionDone(new Mutex(CODE_AT_LINE)), - mutexThreadObjectAccessor(new Mutex(CODE_AT_LINE)), - mutexThreadOwnerValid(new Mutex(CODE_AT_LINE)), - mutexExecutingTask(new Mutex(CODE_AT_LINE)), - mutexStarted(new Mutex(CODE_AT_LINE)), - ptr(NULL), genericData(NULL) { + BaseThread::BaseThread() : Thread(), + mutexRunning(new Mutex(CODE_AT_LINE)), + mutexQuit(new Mutex(CODE_AT_LINE)), + mutexBeginExecution(new Mutex(CODE_AT_LINE)), + mutexDeleteSelfOnExecutionDone(new Mutex(CODE_AT_LINE)), + mutexThreadObjectAccessor(new Mutex(CODE_AT_LINE)), + mutexThreadOwnerValid(new Mutex(CODE_AT_LINE)), + mutexExecutingTask(new Mutex(CODE_AT_LINE)), + mutexStarted(new Mutex(CODE_AT_LINE)), + ptr(NULL), genericData(NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - ptr = this; - MutexSafeWrapper safeMutexMasterList(&mutexMasterThreadList); - masterThreadList[ptr]++; - safeMutexMasterList.ReleaseLock(); + ptr = this; + MutexSafeWrapper safeMutexMasterList(&mutexMasterThreadList); + masterThreadList[ptr]++; + safeMutexMasterList.ReleaseLock(); - uniqueID = "base_thread"; + uniqueID = "base_thread"; - setQuitStatus(false); - setRunningStatus(false); - setStarted(false); - setHasBeginExecution(false); - setExecutingTask(false); - setDeleteSelfOnExecutionDone(false); - setThreadOwnerValid(true); + setQuitStatus(false); + setRunningStatus(false); + setStarted(false); + setHasBeginExecution(false); + setExecutingTask(false); + setDeleteSelfOnExecutionDone(false); + setThreadOwnerValid(true); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -Mutex * BaseThread::getMutexThreadObjectAccessor() { - return mutexThreadObjectAccessor; -} - -BaseThread::~BaseThread() { - - //printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); - - //BaseThread *base_thread = dynamic_cast(this); - if(this->getStarted() == false) { - time_t elapsed = time(NULL); - for(;this->getStarted() == false && - difftime((long int)time(NULL),elapsed) <= 3;) { - sleep(5); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); - bool ret = shutdownAndWait(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),ret); + Mutex * BaseThread::getMutexThreadObjectAccessor() { + return mutexThreadObjectAccessor; + } - //printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str()); + BaseThread::~BaseThread() { - MutexSafeWrapper safeMutexMasterList(&mutexMasterThreadList); + //printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str()); - //printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),ret); - - //printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str()); - - if(masterThreadList.find(this) == masterThreadList.end()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),ret); - - char szBuf[8096]=""; - snprintf(szBuf,8096,"invalid thread delete for ptr: %p",this); - throw megaglest_runtime_error(szBuf); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),ret); - - //printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str()); - - masterThreadList[this]--; - if(masterThreadList[this] <= 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),ret); - masterThreadList.erase(this); - } - - //printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),ret); - - safeMutexMasterList.ReleaseLock(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),ret); - - - delete mutexRunning; - mutexRunning = NULL; - delete mutexQuit; - mutexQuit = NULL; - delete mutexBeginExecution; - mutexBeginExecution = NULL; - delete mutexDeleteSelfOnExecutionDone; - mutexDeleteSelfOnExecutionDone = NULL; - delete mutexThreadObjectAccessor; - mutexThreadObjectAccessor = NULL; - delete mutexThreadOwnerValid; - mutexThreadOwnerValid = NULL; - delete mutexExecutingTask; - mutexExecutingTask = NULL; - delete mutexStarted; - mutexStarted = NULL; - - //printf("In ~BaseThread Line: %d uniqueID [%s] [%p]\n",__LINE__,uniqueID.c_str(),this); -} - -bool BaseThread::getStarted() { - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexStarted,mutexOwnerId); - mutexStarted->setOwnerId(mutexOwnerId); - bool retval = started; - safeMutex.ReleaseLock(); - - return retval; -} - -void BaseThread::setStarted(bool value) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); - - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexStarted,mutexOwnerId); - mutexStarted->setOwnerId(mutexOwnerId); - started = value; - safeMutex.ReleaseLock(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); -} - -bool BaseThread::isThreadDeleted(void *ptr) { - bool result = false; - MutexSafeWrapper safeMutexMasterList(&mutexMasterThreadList); - if(masterThreadList.find(ptr) != masterThreadList.end()) { - result = (masterThreadList[ptr] <= 0); - } - safeMutexMasterList.ReleaseLock(); - return result; -} - -Mutex * BaseThread::getMutexThreadOwnerValid() { - if(getThreadOwnerValid() == true) { - return mutexThreadOwnerValid; - } - return NULL; -} - -void BaseThread::setThreadOwnerValid(bool value) { - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexThreadOwnerValid,mutexOwnerId); - mutexThreadOwnerValid->setOwnerId(mutexOwnerId); - threadOwnerValid = value; - safeMutex.ReleaseLock(); -} - -bool BaseThread::getThreadOwnerValid() { - //bool ret = false; - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexThreadOwnerValid,mutexOwnerId); - //mutexThreadOwnerValid.setOwnerId(mutexOwnerId); - bool ret = threadOwnerValid; - safeMutex.ReleaseLock(); - - return ret; -} - -void BaseThread::signalQuit() { - setQuitStatus(true); -} - -void BaseThread::setQuitStatus(bool value) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); - - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexQuit,mutexOwnerId); - mutexQuit->setOwnerId(mutexOwnerId); - quit = value; - safeMutex.ReleaseLock(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); -} - -bool BaseThread::getQuitStatus() { - //bool retval = false; - //static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexQuit,CODE_AT_LINE); - //mutexQuit.setOwnerId(mutexOwnerId); - bool retval = quit; - safeMutex.ReleaseLock(); - - return retval; -} - -bool BaseThread::getHasBeginExecution() { - //bool retval = false; - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexBeginExecution,mutexOwnerId); - //mutexBeginExecution.setOwnerId(mutexOwnerId); - bool retval = hasBeginExecution; - safeMutex.ReleaseLock(); - - return retval; -} - -void BaseThread::setHasBeginExecution(bool value) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); - - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexBeginExecution,mutexOwnerId); - mutexBeginExecution->setOwnerId(mutexOwnerId); - hasBeginExecution = value; - safeMutex.ReleaseLock(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); -} - -bool BaseThread::getRunningStatus() { - //bool retval = false; - - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexRunning,mutexOwnerId); - bool retval = running; - safeMutex.ReleaseLock(); - - if(retval == false) { - retval = !getHasBeginExecution(); - } - - return retval; -} - -void BaseThread::setRunningStatus(bool value) { - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexRunning,mutexOwnerId); - mutexRunning->setOwnerId(mutexOwnerId); - running = value; - if(value == true) { - setHasBeginExecution(true); - } - safeMutex.ReleaseLock(); -} - -void BaseThread::setExecutingTask(bool value) { - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexExecutingTask,mutexOwnerId); - mutexExecutingTask->setOwnerId(mutexOwnerId); - executingTask = value; - safeMutex.ReleaseLock(); -} - -bool BaseThread::getExecutingTask() { - //bool retval = false; - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexExecutingTask,mutexOwnerId); - bool retval = executingTask; - safeMutex.ReleaseLock(); - - return retval; -} - -bool BaseThread::getDeleteSelfOnExecutionDone() { - //bool retval = false; - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexDeleteSelfOnExecutionDone,mutexOwnerId); - bool retval = deleteSelfOnExecutionDone; - safeMutex.ReleaseLock(); - - return retval; -} - -void BaseThread::setDeleteSelfOnExecutionDone(bool value) { - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexDeleteSelfOnExecutionDone,mutexOwnerId); - mutexDeleteSelfOnExecutionDone->setOwnerId(mutexOwnerId); - deleteSelfOnExecutionDone = value; -} - -void BaseThread::deleteSelfIfRequired() { - if(getDeleteSelfOnExecutionDone() == true) { - if(isThreadDeleted(this->ptr) == false) { - this->setDeleteAfterExecute(true); - } - return; - } -} - -bool BaseThread::canShutdown(bool deleteSelfIfShutdownDelayed) { - return true; -} - -bool BaseThread::shutdownAndWait(BaseThread *pThread) { - bool ret = false; - if(pThread != NULL) { - ret = pThread->shutdownAndWait(); - } - - return ret; -} - -bool BaseThread::shutdownAndWait() { - bool ret = true; - BaseThread *pThread = this; - //string uniqueID = (pThread != NULL ? pThread->getUniqueID() : "?"); - string uniqueID = pThread->getUniqueID(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); - - //if(pThread != NULL) { - if(pThread->getRunningStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); - - pThread->signalQuit(); - sleep(0); - ret = false; - - int maxWaitSeconds = 5; - if(pThread->canShutdown() == false) { - maxWaitSeconds = 2; + //BaseThread *base_thread = dynamic_cast(this); + if (this->getStarted() == false) { + time_t elapsed = time(NULL); + for (; this->getStarted() == false && + difftime((long int) time(NULL), elapsed) <= 3;) { + sleep(5); + } } - for( time_t elapsed = time(NULL); difftime(time(NULL),elapsed) <= maxWaitSeconds; ) { - if(pThread->getRunningStatus() == false) { - ret = true; - break; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str()); + bool ret = shutdownAndWait(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str(), ret); + + //printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str()); + + MutexSafeWrapper safeMutexMasterList(&mutexMasterThreadList); + + //printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str(), ret); + + //printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str()); + + if (masterThreadList.find(this) == masterThreadList.end()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str(), ret); + + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "invalid thread delete for ptr: %p", this); + throw megaglest_runtime_error(szBuf); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str(), ret); + + //printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str()); + + masterThreadList[this]--; + if (masterThreadList[this] <= 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str(), ret); + masterThreadList.erase(this); + } + + //printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str(), ret); + + safeMutexMasterList.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str(), ret); + + + delete mutexRunning; + mutexRunning = NULL; + delete mutexQuit; + mutexQuit = NULL; + delete mutexBeginExecution; + mutexBeginExecution = NULL; + delete mutexDeleteSelfOnExecutionDone; + mutexDeleteSelfOnExecutionDone = NULL; + delete mutexThreadObjectAccessor; + mutexThreadObjectAccessor = NULL; + delete mutexThreadOwnerValid; + mutexThreadOwnerValid = NULL; + delete mutexExecutingTask; + mutexExecutingTask = NULL; + delete mutexStarted; + mutexStarted = NULL; + + //printf("In ~BaseThread Line: %d uniqueID [%s] [%p]\n",__LINE__,uniqueID.c_str(),this); + } + + bool BaseThread::getStarted() { + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexStarted, mutexOwnerId); + mutexStarted->setOwnerId(mutexOwnerId); + bool retval = started; + safeMutex.ReleaseLock(); + + return retval; + } + + void BaseThread::setStarted(bool value) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str()); + + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexStarted, mutexOwnerId); + mutexStarted->setOwnerId(mutexOwnerId); + started = value; + safeMutex.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str()); + } + + bool BaseThread::isThreadDeleted(void *ptr) { + bool result = false; + MutexSafeWrapper safeMutexMasterList(&mutexMasterThreadList); + if (masterThreadList.find(ptr) != masterThreadList.end()) { + result = (masterThreadList[ptr] <= 0); + } + safeMutexMasterList.ReleaseLock(); + return result; + } + + Mutex * BaseThread::getMutexThreadOwnerValid() { + if (getThreadOwnerValid() == true) { + return mutexThreadOwnerValid; + } + return NULL; + } + + void BaseThread::setThreadOwnerValid(bool value) { + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexThreadOwnerValid, mutexOwnerId); + mutexThreadOwnerValid->setOwnerId(mutexOwnerId); + threadOwnerValid = value; + safeMutex.ReleaseLock(); + } + + bool BaseThread::getThreadOwnerValid() { + //bool ret = false; + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexThreadOwnerValid, mutexOwnerId); + //mutexThreadOwnerValid.setOwnerId(mutexOwnerId); + bool ret = threadOwnerValid; + safeMutex.ReleaseLock(); + + return ret; + } + + void BaseThread::signalQuit() { + setQuitStatus(true); + } + + void BaseThread::setQuitStatus(bool value) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str()); + + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexQuit, mutexOwnerId); + mutexQuit->setOwnerId(mutexOwnerId); + quit = value; + safeMutex.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str()); + } + + bool BaseThread::getQuitStatus() { + //bool retval = false; + //static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexQuit, CODE_AT_LINE); + //mutexQuit.setOwnerId(mutexOwnerId); + bool retval = quit; + safeMutex.ReleaseLock(); + + return retval; + } + + bool BaseThread::getHasBeginExecution() { + //bool retval = false; + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexBeginExecution, mutexOwnerId); + //mutexBeginExecution.setOwnerId(mutexOwnerId); + bool retval = hasBeginExecution; + safeMutex.ReleaseLock(); + + return retval; + } + + void BaseThread::setHasBeginExecution(bool value) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str()); + + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexBeginExecution, mutexOwnerId); + mutexBeginExecution->setOwnerId(mutexOwnerId); + hasBeginExecution = value; + safeMutex.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str()); + } + + bool BaseThread::getRunningStatus() { + //bool retval = false; + + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexRunning, mutexOwnerId); + bool retval = running; + safeMutex.ReleaseLock(); + + if (retval == false) { + retval = !getHasBeginExecution(); + } + + return retval; + } + + void BaseThread::setRunningStatus(bool value) { + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexRunning, mutexOwnerId); + mutexRunning->setOwnerId(mutexOwnerId); + running = value; + if (value == true) { + setHasBeginExecution(true); + } + safeMutex.ReleaseLock(); + } + + void BaseThread::setExecutingTask(bool value) { + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexExecutingTask, mutexOwnerId); + mutexExecutingTask->setOwnerId(mutexOwnerId); + executingTask = value; + safeMutex.ReleaseLock(); + } + + bool BaseThread::getExecutingTask() { + //bool retval = false; + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexExecutingTask, mutexOwnerId); + bool retval = executingTask; + safeMutex.ReleaseLock(); + + return retval; + } + + bool BaseThread::getDeleteSelfOnExecutionDone() { + //bool retval = false; + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexDeleteSelfOnExecutionDone, mutexOwnerId); + bool retval = deleteSelfOnExecutionDone; + safeMutex.ReleaseLock(); + + return retval; + } + + void BaseThread::setDeleteSelfOnExecutionDone(bool value) { + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexDeleteSelfOnExecutionDone, mutexOwnerId); + mutexDeleteSelfOnExecutionDone->setOwnerId(mutexOwnerId); + deleteSelfOnExecutionDone = value; + } + + void BaseThread::deleteSelfIfRequired() { + if (getDeleteSelfOnExecutionDone() == true) { + if (isThreadDeleted(this->ptr) == false) { + this->setDeleteAfterExecute(true); + } + return; + } + } + + bool BaseThread::canShutdown(bool deleteSelfIfShutdownDelayed) { + return true; + } + + bool BaseThread::shutdownAndWait(BaseThread *pThread) { + bool ret = false; + if (pThread != NULL) { + ret = pThread->shutdownAndWait(); + } + + return ret; + } + + bool BaseThread::shutdownAndWait() { + bool ret = true; + BaseThread *pThread = this; + //string uniqueID = (pThread != NULL ? pThread->getUniqueID() : "?"); + string uniqueID = pThread->getUniqueID(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str()); + + //if(pThread != NULL) { + if (pThread->getRunningStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str()); + + pThread->signalQuit(); + sleep(0); + ret = false; + + int maxWaitSeconds = 5; + if (pThread->canShutdown() == false) { + maxWaitSeconds = 2; } + for (time_t elapsed = time(NULL); difftime(time(NULL), elapsed) <= maxWaitSeconds; ) { + if (pThread->getRunningStatus() == false) { + ret = true; + break; + } + + sleep(0); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str()); sleep(0); } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); - sleep(0); + //} + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n", __FILE__, __FUNCTION__, __LINE__, uniqueID.c_str(), ret); + return ret; } - //} - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),ret); - return ret; -} -}}//end namespace + } +}//end namespace diff --git a/source/shared_lib/sources/platform/common/byte_order.cpp b/source/shared_lib/sources/platform/common/byte_order.cpp index cf393ed77..a257a814f 100644 --- a/source/shared_lib/sources/platform/common/byte_order.cpp +++ b/source/shared_lib/sources/platform/common/byte_order.cpp @@ -11,7 +11,9 @@ #include "byte_order.h" -namespace Shared{ namespace PlatformByteOrder{ +namespace Shared { + namespace PlatformByteOrder { -}}; + } +}; diff --git a/source/shared_lib/sources/platform/common/cache_manager.cpp b/source/shared_lib/sources/platform/common/cache_manager.cpp index dc6eda5fb..b6333d329 100644 --- a/source/shared_lib/sources/platform/common/cache_manager.cpp +++ b/source/shared_lib/sources/platform/common/cache_manager.cpp @@ -11,14 +11,16 @@ // ============================================================== #include "cache_manager.h" -namespace Shared { namespace PlatformCommon { +namespace Shared { + namespace PlatformCommon { -//Mutex CacheManager::mutexCache; -Mutex CacheManager::mutexMap(CODE_AT_LINE); -std::map CacheManager::itemCacheMutexList; -const char *CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey1 = "CRC_Cache_FileTree1"; -const char *CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey2 = "CRC_Cache_FileTree2"; -const char *CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey1 = "CRC_Cache_FileTreeList1"; -const char *CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey2 = "CRC_Cache_FileTreeList2"; + //Mutex CacheManager::mutexCache; + Mutex CacheManager::mutexMap(CODE_AT_LINE); + std::map CacheManager::itemCacheMutexList; + const char *CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey1 = "CRC_Cache_FileTree1"; + const char *CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey2 = "CRC_Cache_FileTree2"; + const char *CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey1 = "CRC_Cache_FileTreeList1"; + const char *CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey2 = "CRC_Cache_FileTreeList2"; -}}//end namespace + } +}//end namespace diff --git a/source/shared_lib/sources/platform/common/platform_common.cpp b/source/shared_lib/sources/platform/common/platform_common.cpp index c825836fe..e14817db7 100644 --- a/source/shared_lib/sources/platform/common/platform_common.cpp +++ b/source/shared_lib/sources/platform/common/platform_common.cpp @@ -8,8 +8,8 @@ //version. #ifdef WIN32 - #include - #include +#include +#include #endif #include "platform_common.h" @@ -38,7 +38,7 @@ #endif #ifdef WIN32 - #define S_ISDIR(mode) (((mode) & _S_IFDIR) == _S_IFDIR) +#define S_ISDIR(mode) (((mode) & _S_IFDIR) == _S_IFDIR) #elif defined(__GNUC__) #else @@ -92,2270 +92,2231 @@ using namespace std; #define _DISABLE_MEMORY_VAULT_CHECKS 1 -namespace Shared { namespace PlatformCommon { +namespace Shared { + namespace PlatformCommon { -const time_t REFRESH_CRC_DAY_SECONDS = 60 * 60 * 24; -static string crcCachePath = ""; + const time_t REFRESH_CRC_DAY_SECONDS = 60 * 60 * 24; + static string crcCachePath = ""; -static string gameVersion = ""; -static string gameGITVersion = ""; + static string gameVersion = ""; + static string gameGITVersion = ""; -namespace Private { + namespace Private { -bool shouldBeFullscreen = false; -int ScreenWidth = 800; -int ScreenHeight = 600; + bool shouldBeFullscreen = false; + int ScreenWidth = 800; + int ScreenHeight = 600; -} + } -/* - A thread safe localtime proxy -*/ -tm threadsafe_localtime(const time_t &time) { - tm tm_snapshot; + /* + A thread safe localtime proxy + */ + tm threadsafe_localtime(const time_t &time) { + tm tm_snapshot; #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) - localtime_s(&tm_snapshot, &time); + localtime_s(&tm_snapshot, &time); #else - localtime_r(&time, &tm_snapshot); // POSIX + localtime_r(&time, &tm_snapshot); // POSIX #endif - return tm_snapshot; -} + return tm_snapshot; + } -// extracting std::time_t from std:chrono for "now" -time_t systemtime_now() { + // extracting std::time_t from std:chrono for "now" + time_t systemtime_now() { #if __cplusplus > 199711L - // typedef std::chrono::time_point system_time_point; - typedef std::chrono::time_point system_time_point_x; - system_time_point_x system_now = std::chrono::system_clock::now(); - return std::chrono::system_clock::to_time_t(system_now); + // typedef std::chrono::time_point system_time_point; + typedef std::chrono::time_point system_time_point_x; + system_time_point_x system_now = std::chrono::system_clock::now(); + return std::chrono::system_clock::to_time_t(system_now); #else - return time(NULL); + return time(NULL); #endif -} - - -// ===================================== -// PerformanceTimer -// ===================================== - -void PerformanceTimer::init(float fps, int maxTimes) { - this->times = 0; - this->maxTimes = maxTimes; - this->lastTicks = SDL_GetTicks(); - this->updateTicks = static_cast(1000.0f / fps); -} - -bool PerformanceTimer::isTime() { - Uint32 thisTicks = SDL_GetTicks(); - - if((thisTicks - lastTicks) >= updateTicks && - times < maxTimes) { - - lastTicks += updateTicks; - times++; - return true; - } - times = 0; - return false; -} - -void PerformanceTimer::reset() { - lastTicks = SDL_GetTicks(); -} - -// ===================================== -// Chrono -// ===================================== - -Chrono::Chrono(bool autoStart) { - freq = 1000; - stopped = true; - accumCount = 0; - - lastStartCount = 0; - lastTickCount = 0; - lastResult = 0; - lastMultiplier = 0; - lastStopped = false; - startCount = 0; - - if(autoStart == true) { - start(); - } -} - -bool Chrono::isStarted() const { - return (stopped == false); -} - -void Chrono::start() { - stopped = false; - startCount = SDL_GetTicks(); -} - -void Chrono::stop() { - Uint32 endCount = SDL_GetTicks(); - accumCount += endCount - startCount; - stopped = true; -} - -void Chrono::reset() { - accumCount = 0; - lastStartCount = 0; - lastTickCount = 0; - lastResult = 0; - lastMultiplier = 0; - - startCount = SDL_GetTicks(); -} - -int64 Chrono::getMicros() { - return queryCounter(1000000); -} - -int64 Chrono::getMillis() { - return queryCounter(1000); -} - -int64 Chrono::getSeconds() { - return queryCounter(1); -} - -int64 Chrono::queryCounter(int64 multiplier) { - - if( multiplier == lastMultiplier && - stopped == lastStopped && - lastStartCount == startCount) { - - if(stopped == true) { - return lastResult; } - else { + + + // ===================================== + // PerformanceTimer + // ===================================== + + void PerformanceTimer::init(float fps, int maxTimes) { + this->times = 0; + this->maxTimes = maxTimes; + this->lastTicks = SDL_GetTicks(); + this->updateTicks = static_cast(1000.0f / fps); + } + + bool PerformanceTimer::isTime() { + Uint32 thisTicks = SDL_GetTicks(); + + if ((thisTicks - lastTicks) >= updateTicks && + times < maxTimes) { + + lastTicks += updateTicks; + times++; + return true; + } + times = 0; + return false; + } + + void PerformanceTimer::reset() { + lastTicks = SDL_GetTicks(); + } + + // ===================================== + // Chrono + // ===================================== + + Chrono::Chrono(bool autoStart) { + freq = 1000; + stopped = true; + accumCount = 0; + + lastStartCount = 0; + lastTickCount = 0; + lastResult = 0; + lastMultiplier = 0; + lastStopped = false; + startCount = 0; + + if (autoStart == true) { + start(); + } + } + + bool Chrono::isStarted() const { + return (stopped == false); + } + + void Chrono::start() { + stopped = false; + startCount = SDL_GetTicks(); + } + + void Chrono::stop() { Uint32 endCount = SDL_GetTicks(); - if(lastTickCount == endCount) { - return lastResult; - } - } - } - - int64 result = 0; - if(stopped == true) { - result = multiplier * accumCount / freq; - } - else { - Uint32 endCount = SDL_GetTicks(); - result = multiplier * (accumCount + endCount - startCount) / freq; - lastTickCount = endCount; - } - - lastStartCount = startCount; - lastResult = result; - lastMultiplier = multiplier; - lastStopped = stopped; - - return result; -} - -int64 Chrono::getCurMillis() { - return SDL_GetTicks(); -} -int64 Chrono::getCurTicks() { - return SDL_GetTicks(); -} - - - -// ===================================== -// Misc -// ===================================== - -void Tokenize(const string& str,vector& tokens,const string& delimiters) { - // Assume textLine contains the line of text to parse. - string textLine = str; - - size_t pos = 0; - while( true ) { - size_t nextPos = textLine.find( delimiters, pos ); - if( nextPos == textLine.npos ) { - tokens.push_back(textLine.substr(pos, textLine.length( ))); - break; - } - tokens.push_back( string( textLine.substr( pos, nextPos - pos ) ) ); - pos = nextPos + delimiters.size(); - } - -} - -void findDirs(const string &path, vector &results, bool errorOnNotFound,bool keepDuplicates) { - results.clear(); - string currentPath = path; - endPathWithSlash(currentPath); - - string searchpath = currentPath + "*."; - vector current_results; - findAll(searchpath, current_results, false, errorOnNotFound); - if(current_results.empty() == false) { - for(unsigned int folder_index = 0; folder_index < current_results.size(); folder_index++) { - const string current_folder = current_results[folder_index]; - const string current_folder_path = currentPath + current_folder; - - if(isdir(current_folder_path.c_str()) == true) { - if(keepDuplicates == true || std::find(results.begin(),results.end(),current_folder) == results.end()) { - results.push_back(current_folder); - } - } - } - } - - std::sort(results.begin(),results.end()); -} - -void findDirs(const vector &paths, vector &results, bool errorOnNotFound,bool keepDuplicates) { - results.clear(); - size_t pathCount = paths.size(); - for(unsigned int idx = 0; idx < pathCount; idx++) { - string currentPath = paths[idx]; - endPathWithSlash(currentPath); - string path = currentPath + "*."; - vector current_results; - findAll(path, current_results, false, errorOnNotFound); - if(current_results.empty() == false) { - for(unsigned int folder_index = 0; folder_index < current_results.size(); folder_index++) { - const string current_folder = current_results[folder_index]; - const string current_folder_path = currentPath + current_folder; - - if(isdir(current_folder_path.c_str()) == true) { - if(keepDuplicates == true || std::find(results.begin(),results.end(),current_folder) == results.end()) { - results.push_back(current_folder); - } - } - } - } - } - - std::sort(results.begin(),results.end()); -} - -void findAll(const vector &paths, const string &fileFilter, vector &results, bool cutExtension, bool errorOnNotFound, bool keepDuplicates) { - results.clear(); - size_t pathCount = paths.size(); - for(unsigned int idx = 0; idx < pathCount; idx++) { - string currentPath = paths[idx]; - endPathWithSlash(currentPath); - - string path = currentPath + fileFilter; - vector current_results; - findAll(path, current_results, cutExtension, errorOnNotFound); - if(current_results.empty() == false) { - for(unsigned int folder_index = 0; folder_index < current_results.size(); folder_index++) { - string current_file = current_results[folder_index]; - if(keepDuplicates == true || std::find(results.begin(),results.end(),current_file) == results.end()) { - results.push_back(current_file); - } - } - } - } - - std::sort(results.begin(),results.end()); -} - -//finds all filenames like path and stores them in results -void findAll(const string &path, vector &results, bool cutExtension, bool errorOnNotFound) { - results.clear(); - - std::string mypath = path; - /** Stupid win32 is searching for all files without extension when *. is - * specified as wildcard - */ - if((int)mypath.size() >= 2 && mypath.compare(max((int)0,(int)mypath.size() - 2), 2, "*.") == 0) { - mypath = mypath.substr(0, max((int)0,(int)mypath.size() - 2)); - mypath += "*"; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,mypath.c_str()); - - glob_t globbuf; - - int res = glob(mypath.c_str(), 0, 0, &globbuf); - if(res < 0 && errorOnNotFound == true) { - if(errorOnNotFound) { - std::stringstream msg; - msg << "#1 Couldn't scan directory '" << mypath << "': " << strerror(errno); - throw megaglest_runtime_error(msg.str()); - } - } - else { - for(int i = 0; i < (int)globbuf.gl_pathc; ++i) { - const char* p = globbuf.gl_pathv[i]; - const char* begin = p; - for( ; *p != 0; ++p) { - // strip the path component - if(*p == '/') - begin = p+1; - } - if(!(strcmp(".", begin)==0 || strcmp("..", begin)==0 || strcmp(".git", begin)==0)) { - results.push_back(begin); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] SKIPPED SPECIAL FILENAME [%s]\n",__FILE__,__FUNCTION__,__LINE__,begin); - } + accumCount += endCount - startCount; + stopped = true; } - globfree(&globbuf); + void Chrono::reset() { + accumCount = 0; + lastStartCount = 0; + lastTickCount = 0; + lastResult = 0; + lastMultiplier = 0; - if(results.empty() == true && errorOnNotFound == true) { - throw megaglest_runtime_error("No files found in: " + mypath); + startCount = SDL_GetTicks(); } - if(cutExtension) { - for (size_t i=0; i results = getFolderTreeContentsListRecursively(deletePath, "", true); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s] results.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),results.size()); - - // First delete files - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] DELETE FILES\n",__FILE__,__FUNCTION__,__LINE__); - - for(int i = (int)results.size() -1; i >= 0; --i) { - string item = results[i]; - - //if(item.find(".git") != string::npos) { - // printf("!!!!!!!!!!!!!!!!!! FOUND SPECIAL FOLDER [%s] in [%s]\n",item.c_str(),path.c_str()); - //} - - if(isdir(item.c_str()) == false) { - bool result = removeFile(item); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileitem [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,item.c_str(),result); - } - } - // Now delete folders - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] DELETE FOLDERS\n",__FILE__,__FUNCTION__,__LINE__); - - for(int i = (int)results.size() -1; i >= 0; --i) { - string item = results[i]; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] item [%s] isdir(item.c_str()) = %d\n",__FILE__,__FUNCTION__,__LINE__,item.c_str(), isdir(item.c_str())); - if(isdir(item.c_str()) == true) { - - //printf("~~~~~ REMOVE FOLDER [%s] in [%s]\n",item.c_str(),path.c_str()); - -#ifdef WIN32 - //int result = _rmdir(item.c_str()); - int result = _wrmdir(utf8_decode(item).c_str()); -#else - int result = rmdir(item.c_str()); -#endif - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] item [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,item.c_str(),result); - - if(result != 0 && item != path) { - printf("CANNOT REMOVE FOLDER [%s] in [%s]\n",item.c_str(),path.c_str()); - removeFolder(item); - } - } - } - -#ifdef WIN32 - //int result = _rmdir(path.c_str()); - int result = _wrmdir(utf8_decode(path).c_str()); -#else - int result = rmdir(path.c_str()); -#endif - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),result); -} - -bool StartsWith(const std::string &str, const std::string &key) { - return str.find(key) == 0; -} - -bool EndsWith(const string &str, const string& key) -{ - bool result = false; - if (str.length() >= key.length()) { - result = (0 == str.compare(max((int)0,(int)str.length() - (int)key.length()), key.length(), key)); - } - - return result; -} - -void endPathWithSlash(string &path,bool requireOSSlash) { - if(EndsWith(path, "/") == false && EndsWith(path, "\\") == false) { - string seperator = "/"; - if(requireOSSlash == true) { -#if defined(WIN32) - seperator = "\\"; -#endif - } - path += seperator; - } -} - -string formatPath(string path) { - replaceAll(path, "\"", ""); - replaceAll(path, "//", "/"); - - return path; -} - -void trimPathWithStartingSlash(string &path) { - if(StartsWith(path, "/") == true || StartsWith(path, "\\") == true) { - path.erase(path.begin(),path.begin()+1); - //printf("************* trimPathWithStartingSlash changed path [%s]\n",path.c_str()); - } -} - -void updatePathClimbingParts(string &path,bool processPreviousDirTokenCheck) { - // Update paths with /./ - string::size_type pos = path.find("/./"); - if(pos != string::npos && pos != 0) { - string orig = path; - path.erase(pos,2); - //pos--; - - //printf("#1 CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str()); - - pos = path.find("/./"); - if(pos != string::npos && pos != 0) { - updatePathClimbingParts(path, processPreviousDirTokenCheck); + int64 Chrono::getMicros() { + return queryCounter(1000000); } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str()); - } - pos = path.find("\\.\\"); - if(pos != string::npos && pos != 0) { - string orig = path; - path.erase(pos,2); - //pos--; - //printf("#w CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str()); - - pos = path.find("\\.\\"); - if(pos != string::npos && pos != 0) { - updatePathClimbingParts(path, processPreviousDirTokenCheck); + int64 Chrono::getMillis() { + return queryCounter(1000); } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str()); - } + int64 Chrono::getSeconds() { + return queryCounter(1); + } - // Update paths with .. - if(processPreviousDirTokenCheck) { - pos = path.find(".."); - if(pos != string::npos && pos != 0) { + int64 Chrono::queryCounter(int64 multiplier) { - string orig = path; - if(path[pos-1] != ' ' || (path.length() > 2 && path[pos+2] != ' ')) { - path.erase(pos,2); + if (multiplier == lastMultiplier && + stopped == lastStopped && + lastStartCount == startCount) { - //printf("#3 [%d] CHANGE relative path from [%s] to [%s]\n",(int)pos,orig.c_str(),path.c_str()); - - pos--; - //pos = pos -1; - - //printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #3b [%d]\n",(int)pos); - - if(path[pos] == '/' || path[pos] == '\\') { - path.erase(pos,1); - - //printf("#4 CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str()); - } - - for(int x = (int)pos; x >= 0; --x) { - //printf("x [%d][%c] pos [%ld][%c] [%s]\n",x,path[x],(long int)pos,path[pos],path.substr(0,x+1).c_str()); - - if((path[x] == '/' || path[x] == '\\') && x != (int)pos) { - //string origLoop = path; - path.erase(x,(int)pos-x); - - //printf("#5 [%d] [%d] [%d] CHANGE relative path from [%s] to [%s]\n",(int)pos,(int)x,(int)origLoop.length(),origLoop.c_str(),path.c_str()); - break; + if (stopped == true) { + return lastResult; + } else { + Uint32 endCount = SDL_GetTicks(); + if (lastTickCount == endCount) { + return lastResult; } } - pos = path.find(".."); - } - else { - //printf("#6a [%d]\n",(int)pos); - - //pos = path.find("..",pos+1); - pos = string::npos; - - //printf("#6b [%d]\n",(int)pos); - } - if(pos != string::npos && pos != 0) { - updatePathClimbingParts(path,processPreviousDirTokenCheck); } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str()); - } - } - -/* - string::size_type pos = path.rfind(".."); - if(pos != string::npos && pos != 0) { - string orig = path; - path.erase(pos,2); - pos--; - if(path[pos] == '/' || path[pos] == '\\') { - path.erase(pos,1); - } - - for(int x = pos; x >= 0; --x) { - //printf("x [%d][%c] pos [%ld][%c] [%s]\n",x,path[x],(long int)pos,path[pos],path.substr(0,x+1).c_str()); - - if((path[x] == '/' || path[x] == '\\') && x != pos) { - path.erase(x,pos-x); - break; - } - } - - printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str()); - } -*/ -} - -string getCRCCacheFilePath() { - return crcCachePath; -} - -void setCRCCacheFilePath(const string &path) { - crcCachePath = path; -} - -//string getGameVersion() { -// return gameVersion; -//} -//string getGameGITVersion() { -// return gameGITVersion; -//} -void setGameVersion(const string &version) { - gameVersion = version; -} -void setGameGITVersion(const string &git) { - gameGITVersion = git; -} - -string getCRCCacheFileName(std::pair cacheKeys) { - string crcCacheFile = cacheKeys.first + cacheKeys.second; - return crcCacheFile; -} -string getFormattedCRCCacheFileName(std::pair cacheKeys) { - string crcCacheFile = getCRCCacheFileName(cacheKeys); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] cacheKeys.first = [%s] cacheKeys.second [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,cacheKeys.first.c_str(),cacheKeys.second.c_str()); - - Checksum checksum; - checksum.addString(crcCacheFile); - string result = getCRCCacheFilePath() + "CRC_CACHE_" + uIntToStr(checksum.getSum()); - return result; -} -std::pair getFolderTreeContentsCheckSumCacheKey(vector paths, const string &pathSearchString, const string &filterFileExt) { - string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey1; - - string cacheKey = ""; - for(unsigned int idx = 0; idx < paths.size(); ++idx) { - string path = paths[idx] + pathSearchString; - cacheKey += path + "_" + filterFileExt + "_"; - } - return make_pair(cacheLookupId,cacheKey); -} - -pair hasCachedFileCRCValue(string crcCacheFile, uint32 &value) { - //bool result = false; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d for Cache file [%s]\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str()); - } - - pair result = make_pair(false,0); - if(fileExists(crcCacheFile) == true) { -#ifdef WIN32 - FILE *fp = _wfopen(utf8_decode(crcCacheFile).c_str(), L"r"); -#else - FILE *fp = fopen(crcCacheFile.c_str(),"r"); -#endif - if(fp != NULL) { - time_t refreshDate = 0; - uint32 crcValue = 0; - time_t lastUpdateDate = 0; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d for Cache file [%s]\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str()); + int64 result = 0; + if (stopped == true) { + result = multiplier * accumCount / freq; + } else { + Uint32 endCount = SDL_GetTicks(); + result = multiplier * (accumCount + endCount - startCount) / freq; + lastTickCount = endCount; } - char gameVer[500]=""; - char gitVer[500]=""; - char actualFilePath[8096]=""; - int readbytes = fscanf(fp,"%20ld,%20u,%20ld\n%499s\n%499s\n%8095s", - (long *)&refreshDate, - &crcValue, - (long *)&lastUpdateDate, - &gameVer[0], - &gitVer[0], - &actualFilePath[0]); - refreshDate = Shared::PlatformByteOrder::fromCommonEndian(refreshDate); - crcValue = Shared::PlatformByteOrder::fromCommonEndian(crcValue); - lastUpdateDate = Shared::PlatformByteOrder::fromCommonEndian(lastUpdateDate); - string readGameVer = Shared::PlatformByteOrder::fromCommonEndian(string(gameVer)); - string readGitVer = Shared::PlatformByteOrder::fromCommonEndian(string(gitVer)); - string readActualFilePath = Shared::PlatformByteOrder::fromCommonEndian(string(actualFilePath)); + lastStartCount = startCount; + lastResult = result; + lastMultiplier = multiplier; + lastStopped = stopped; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CRC readGameVer [%s] [%s]\n%s\n",readGameVer.c_str(),readGitVer.c_str(),readActualFilePath.c_str()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d for Cache file [%s] readbytes = %d\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),readbytes); - } - - fclose(fp); - - struct tm future; /* as in future date */ - future.tm_sec = 0; - future.tm_min = 0; - future.tm_hour = 0; - future.tm_mday = 6; /* 1st */ - future.tm_mon = 6; /* July */ - future.tm_year = 2012 - 1900; /* 2038 in years since 1900 */ - future.tm_isdst = 0; /* Daylight Saving not in affect (UTC) */ - #ifdef _BSD_SOURCE - future.tm_zone = "UTC"; - #endif - - time_t tBadCRCDate = mktime( &future ); - - result.second = lastUpdateDate; - if( readGameVer != "" && readGitVer != "" && - refreshDate > 0 && - refreshDate > tBadCRCDate && - time(NULL) < refreshDate) { - - result.first = true; - value = crcValue; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { - //struct tm *loctime = localtime (&refreshDate); - struct tm loctime = threadsafe_localtime(refreshDate); - char szBuf1[100]=""; - strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime); - - SystemFlags::OutputDebug(SystemFlags::debugSystem, - "=-=-=-=- READ CACHE for Cache file [%s] refreshDate = %ld [%s], crcValue = %u\n", - crcCacheFile.c_str(),refreshDate, szBuf1, crcValue); - } - } - else { - //time_t now = time(NULL); - //struct tm *loctime = localtime (&now); - struct tm loctime = threadsafe_localtime(systemtime_now()); - char szBuf1[100]=""; - strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime); - - loctime = threadsafe_localtime(refreshDate); - char szBuf2[100]=""; - strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",&loctime); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { - SystemFlags::OutputDebug(SystemFlags::debugSystem, - "=-=-=-=- NEED TO CALCULATE CRC for Cache file [%s] now = %ld [%s], refreshDate = %ld [%s], crcValue = %u\n", - crcCacheFile.c_str(), systemtime_now(), szBuf1, refreshDate, szBuf2, crcValue); - } - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"FILE NOT FOUND(1) for Cache file [%s]\n",crcCacheFile.c_str()); - } - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"FILE NOT FOUND(2) for Cache file [%s]\n",crcCacheFile.c_str()); - } - } - - return result; -} - -void writeCachedFileCRCValue(string crcCacheFile, uint32 &crcValue, string actualFileName) { -#ifdef WIN32 - FILE *fp = _wfopen(utf8_decode(crcCacheFile).c_str(), L"w"); -#else - FILE *fp = fopen(crcCacheFile.c_str(),"w"); -#endif - if(fp != NULL) { - //RandomGen random; - //int offset = random.randRange(5, 15); - srand((unsigned int)time(NULL) + (unsigned long)crcCacheFile.length()); - int offset = rand() % 15; - if(offset == 0) { - offset = 3; - } - time_t now = time(NULL); - time_t refreshDate = now + (REFRESH_CRC_DAY_SECONDS * offset); - - //struct tm *loctime = localtime (&refreshDate); - struct tm loctime = threadsafe_localtime(refreshDate); - char szBuf1[100]=""; - strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime); - - string writeGameVer = Shared::PlatformByteOrder::toCommonEndian(gameVersion); - string writeGameGITVersion = Shared::PlatformByteOrder::toCommonEndian(gameGITVersion); - string writeActualFileName = Shared::PlatformByteOrder::toCommonEndian(actualFileName); - - fprintf(fp,"%20ld,%20u,%20ld", - (long)Shared::PlatformByteOrder::toCommonEndian(refreshDate), - Shared::PlatformByteOrder::toCommonEndian(crcValue), - (long)Shared::PlatformByteOrder::toCommonEndian(now)); - - fprintf(fp,"\n%s\n%s\n%s", - writeGameVer.c_str(), - writeGameGITVersion.c_str(), - writeActualFileName.c_str()); - - fclose(fp); - - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"========== Writing CRC Cache offset [%d] refreshDate = %ld [%s], crcValue = %u, file [%s]\n",offset,refreshDate,szBuf1,crcValue,crcCacheFile.c_str()); - } -} - -void clearFolderTreeContentsCheckSum(vector paths, const string &pathSearchString, const string &filterFileExt) { - std::pair cacheKeys = getFolderTreeContentsCheckSumCacheKey(paths, pathSearchString, filterFileExt); - string cacheLookupId = cacheKeys.first; - std::map &crcTreeCache = CacheManager::getCachedItem< std::map >(cacheLookupId); - - string cacheKey = cacheKeys.second; - crcTreeCache.erase(cacheKey); - - for(unsigned int idx = 0; idx < paths.size(); ++idx) { - string path = paths[idx]; - clearFolderTreeContentsCheckSum(path, filterFileExt); - } - - string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys); - if(fileExists(crcCacheFile) == true) { - - bool result = removeFile(crcCacheFile); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileitem [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),result); - } -} - -time_t getFolderTreeContentsCheckSumRecursivelyLastGenerated(const vector &paths, string pathSearchString, const string &filterFileExt) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] Calculating CRC for [%s] -----------\n",__FILE__,__FUNCTION__,__LINE__,pathSearchString.c_str()); - - std::pair cacheKeys = getFolderTreeContentsCheckSumCacheKey(paths, pathSearchString, filterFileExt); - //string cacheLookupId = cacheKeys.first; - //std::map &crcTreeCache = CacheManager::getCachedItem< std::map >(cacheLookupId); - - string cacheKey = cacheKeys.second; - string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] looking for cached CRC file [%s] for [%s] -----------\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),pathSearchString.c_str()); - - uint32 crcValue = 0; - pair crcResult = hasCachedFileCRCValue(crcCacheFile, crcValue); - if(crcResult.first == true) { - //struct tm *loctime = localtime (&crcResult.second); - struct tm loctime = threadsafe_localtime(crcResult.second); - char szBuf1[100]=""; - strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED FILE for cacheKey [%s] last updated [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str(),szBuf1); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s Line: %d] scanning folders found CACHED FILE for cacheKey [%s] last updated [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str(),szBuf1); - - return crcResult.second; - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s]\n",__FILE__,__FUNCTION__,cacheKey.c_str()); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s]\n",__FILE__,__FUNCTION__,cacheKey.c_str()); - } - - return 0; -} - -//finds all filenames like path and gets their checksum of all files combined -uint32 getFolderTreeContentsCheckSumRecursively(vector paths, string pathSearchString, const string &filterFileExt, Checksum *recursiveChecksum, bool forceNoCache) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] Calculating CRC for [%s] -----------\n",__FILE__,__FUNCTION__,__LINE__,pathSearchString.c_str()); - - std::pair cacheKeys = getFolderTreeContentsCheckSumCacheKey(paths, pathSearchString, filterFileExt); - string cacheLookupId = cacheKeys.first; - std::map &crcTreeCache = CacheManager::getCachedItem< std::map >(cacheLookupId); - - string cacheKey = cacheKeys.second; - if(forceNoCache == false && crcTreeCache.find(cacheKey) != crcTreeCache.end()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED checksum = %d for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str()); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s Line: %d] scanning folders found CACHED checksum = %d for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str()); - return crcTreeCache[cacheKey]; - } - - string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Looking for CRC Cache file [%s]\n",crcCacheFile.c_str()); - - if(recursiveChecksum == NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] looking for cached CRC file [%s] for [%s] forceNoCache = %d -----------\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),pathSearchString.c_str(),forceNoCache); - } - - uint32 crcValue = 0; - if(forceNoCache == false && hasCachedFileCRCValue(crcCacheFile, crcValue).first == true) { - crcTreeCache[cacheKey] = crcValue; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str(),forceNoCache); - if(recursiveChecksum == NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str(),forceNoCache); + return result; } - return crcTreeCache[cacheKey]; - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,cacheKey.c_str(),forceNoCache); - if(recursiveChecksum == NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,cacheKey.c_str(),forceNoCache); + int64 Chrono::getCurMillis() { + return SDL_GetTicks(); } - } - - Checksum checksum = (recursiveChecksum == NULL ? Checksum() : *recursiveChecksum); - for(unsigned int idx = 0; idx < paths.size(); ++idx) { - string path = paths[idx] + pathSearchString; - - getFolderTreeContentsCheckSumRecursively(path, filterFileExt, &checksum, forceNoCache); - } - - if(recursiveChecksum != NULL) { - *recursiveChecksum = checksum; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Final CRC file count: %d\n",__FILE__,__FUNCTION__,__LINE__,checksum.getFileCount()); - - uint32 result = checksum.getFinalFileListSum(); - //if(forceNoCache == false) { - crcTreeCache[cacheKey] = result; - writeCachedFileCRCValue(crcCacheFile, crcTreeCache[cacheKey],getCRCCacheFileName(cacheKeys)); - //} - return result; -} - -std::pair getFolderTreeContentsCheckSumCacheKey(const string &path, const string &filterFileExt) { - string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey2; - - string cacheKey = path + "_" + filterFileExt; - return make_pair(cacheLookupId,cacheKey); -} - -void clearFolderTreeContentsCheckSum(const string &path, const string &filterFileExt) { - std::pair cacheKeys = getFolderTreeContentsCheckSumCacheKey(path,filterFileExt); - string cacheLookupId = cacheKeys.first; - std::map &crcTreeCache = CacheManager::getCachedItem< std::map >(cacheLookupId); - - string cacheKey = cacheKeys.second; - crcTreeCache.erase(cacheKey); - - string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys); - if(fileExists(crcCacheFile) == true) { - bool result = removeFile(crcCacheFile); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileitem [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),result); - } -} - -//finds all filenames like path and gets their checksum of all files combined -uint32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum, bool forceNoCache) { - std::pair cacheKeys = getFolderTreeContentsCheckSumCacheKey(path, filterFileExt); - - string cacheLookupId = cacheKeys.first; - std::map &crcTreeCache = CacheManager::getCachedItem< std::map >(cacheLookupId); - - string cacheKey = cacheKeys.second; - if(forceNoCache == false && crcTreeCache.find(cacheKey) != crcTreeCache.end()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning [%s] found CACHED checksum = %d for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),crcTreeCache[cacheKey],cacheKey.c_str()); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s Line: %d] scanning [%s] found CACHED checksum = %d for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),crcTreeCache[cacheKey],cacheKey.c_str()); - return crcTreeCache[cacheKey]; - } - - string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Looking for CRC Cache file [%s]\n",crcCacheFile.c_str()); - - if(recursiveChecksum == NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] looking for cached CRC file [%s] for [%s] forceNoCache = %d -----------\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),path.c_str(),forceNoCache); - } - - uint32 crcValue = 0; - if(forceNoCache == false && hasCachedFileCRCValue(crcCacheFile, crcValue).first == true) { - crcTreeCache[cacheKey] = crcValue; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str(),forceNoCache); - if(recursiveChecksum == NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str(),forceNoCache); + int64 Chrono::getCurTicks() { + return SDL_GetTicks(); } - return crcTreeCache[cacheKey]; - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,cacheKey.c_str(),forceNoCache); - if(recursiveChecksum == NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,cacheKey.c_str(),forceNoCache); - } - } - bool topLevelCaller = (recursiveChecksum == NULL); - Checksum checksum = (recursiveChecksum == NULL ? Checksum() : *recursiveChecksum); - std::string mypath = path; - // Stupid win32 is searching for all files without extension when *. is - // specified as wildcard - // - if((int)mypath.size() >= 2 && mypath.compare(max((int)0,(int)mypath.size() - 2), 2, "*.") == 0) { - mypath = mypath.substr(0, max((int)0,(int)mypath.size() - 2)); - mypath += "*"; - } + // ===================================== + // Misc + // ===================================== - glob_t globbuf; + void Tokenize(const string& str, vector& tokens, const string& delimiters) { + // Assume textLine contains the line of text to parse. + string textLine = str; - int res = glob(mypath.c_str(), 0, 0, &globbuf); -#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) - if(res < 0) { - std::stringstream msg; - msg << "#2 Couldn't scan directory '" << mypath << "': " << strerror(errno); - throw megaglest_runtime_error(msg.str()); - } -#endif - - int fileLoopCount = 0; - int fileMatchCount = 0; - for(int i = 0; i < (int)globbuf.gl_pathc; ++i) { - const char* p = globbuf.gl_pathv[i]; - //printf("Line: %d p [%s]\n",__LINE__,p); - - if(isdir(p) == false) { - bool addFile = true; - if(EndsWith(p, ".") == true || EndsWith(p, "..") == true || EndsWith(p, ".git") == true) { - addFile = false; - } - else if(filterFileExt != "") { - addFile = EndsWith(p, filterFileExt); - } - - if(addFile) { - checksum.addFile(p); - fileMatchCount++; - } - } - fileLoopCount++; - } - - globfree(&globbuf); - - // Look recursively for sub-folders -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) - res = glob(mypath.c_str(), 0, 0, &globbuf); -#else - res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf); -#endif - -#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) - if(res < 0) { - std::stringstream msg; - msg << "#3 Couldn't scan directory '" << mypath << "': " << strerror(errno); - throw megaglest_runtime_error(msg.str()); - } -#endif - - for(int i = 0; i < (int)globbuf.gl_pathc; ++i) { -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) - struct stat statStruct; - // only process if dir.. - lstat( globbuf.gl_pathv[i], &statStruct); - if( S_ISDIR(statStruct.st_mode) == 0) - continue; -#endif - const char *p = globbuf.gl_pathv[i]; - //printf("Line: %d p [%s]\n",__LINE__,p); - - string currentPath = p; - endPathWithSlash(currentPath); - - getFolderTreeContentsCheckSumRecursively(currentPath + "*", filterFileExt, &checksum, forceNoCache); - } - - globfree(&globbuf); - - if(recursiveChecksum != NULL) { - *recursiveChecksum = checksum; - } - - if(topLevelCaller == true) { - //printf("In [%s::%s Line: %d] Final CRC file count for [%s]: %d\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),checksum.getFileCount()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Final CRC file count for [%s]: %d\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),checksum.getFileCount()); - - uint32 result = checksum.getFinalFileListSum(); - //if(forceNoCache == false) { - crcTreeCache[cacheKey] = result; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s] ending checksum = %d for cacheKey [%s] fileMatchCount = %d, fileLoopCount = %d\n",__FILE__,__FUNCTION__,path.c_str(),crcTreeCache[cacheKey],cacheKey.c_str(),fileMatchCount,fileLoopCount); - writeCachedFileCRCValue(crcCacheFile, crcTreeCache[cacheKey],getCRCCacheFileName(cacheKeys)); - //} - - return result; - } - else { - return 0; - } -} - - -std::pair getFolderTreeContentsCheckSumListCacheKey(vector paths, const string &pathSearchString, const string &filterFileExt) { - string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey1; - - string cacheKey = ""; - for(unsigned int idx = 0; idx < paths.size(); ++idx) { - string path = paths[idx] + pathSearchString; - cacheKey += path + "_" + filterFileExt + "_"; - } - return make_pair(cacheLookupId,cacheKey); -} - -void clearFolderTreeContentsCheckSumList(vector paths, const string &pathSearchString, const string &filterFileExt) { - std::pair cacheKeys = getFolderTreeContentsCheckSumListCacheKey(paths, pathSearchString, filterFileExt); - string cacheLookupId = cacheKeys.first; - std::map > > &crcTreeCache = CacheManager::getCachedItem< std::map > > >(cacheLookupId); - - string cacheKey = cacheKeys.second; - crcTreeCache.erase(cacheKey); - - for(unsigned int idx = 0; idx < paths.size(); ++idx) { - string path = paths[idx]; - clearFolderTreeContentsCheckSumList(path, filterFileExt); - } - string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys); - if(fileExists(crcCacheFile) == true) { - bool result = removeFile(crcCacheFile); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileitem [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),result); - } -} - -vector > getFolderTreeContentsCheckSumListRecursively(vector paths, const string &pathSearchString, const string &filterFileExt, vector > *recursiveMap) { - std::pair cacheKeys = getFolderTreeContentsCheckSumListCacheKey(paths, pathSearchString, filterFileExt); - string cacheLookupId = cacheKeys.first; - std::map > > &crcTreeCache = CacheManager::getCachedItem< std::map > > >(cacheLookupId); - - string cacheKey = cacheKeys.second; - if(crcTreeCache.find(cacheKey) != crcTreeCache.end()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED result for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str()); - return crcTreeCache[cacheKey]; - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders, NO CACHE found result for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str()); - } - - bool topLevelCaller = (recursiveMap == NULL); - - vector > checksumFiles = (recursiveMap == NULL ? vector >() : *recursiveMap); - for(unsigned int idx = 0; idx < paths.size(); ++idx) { - string path = paths[idx] + pathSearchString; - checksumFiles = getFolderTreeContentsCheckSumListRecursively(path, filterFileExt, &checksumFiles); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,checksumFiles.size()); - - if(topLevelCaller == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] EXITING TOP LEVEL RECURSION, checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,checksumFiles.size()); - } - - crcTreeCache[cacheKey] = checksumFiles; - return crcTreeCache[cacheKey]; -} - -//finds all filenames like path and gets the checksum of each file -vector getFolderTreeContentsListRecursively(const string &path, const string &filterFileExt, bool includeFolders, vector *recursiveMap) { - bool topLevelCaller = (recursiveMap == NULL); - vector resultFiles = (recursiveMap == NULL ? vector() : *recursiveMap); - - std::string mypath = path; - /** Stupid win32 is searching for all files without extension when *. is - * specified as wildcard - */ - if((int)mypath.size() >= 2 && mypath.compare(max((int)0,(int)mypath.size() - 2), 2, "*.") == 0) { - mypath = mypath.substr(0, max((int)0,(int)mypath.size() - 2)); - mypath += "*"; - } - - glob_t globbuf; - - int globFlags = 0; - if(EndsWith(mypath,"{,.}*") == true) { -#ifndef WIN32 - globFlags = GLOB_BRACE; -#else - // Windows glob source cannot handle GLOB_BRACE - // but that should be ok for win32 platform - replaceAll(mypath,"{,.}*","*"); -#endif - } - - int res = glob(mypath.c_str(), globFlags, 0, &globbuf); -#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) - if(res < 0) { - std::stringstream msg; - msg << "#4 Couldn't scan directory '" << mypath << "': " << strerror(errno); - throw megaglest_runtime_error(msg.str()); - } -#endif - for(int i = 0; i < (int)globbuf.gl_pathc; ++i) { - const char* p = globbuf.gl_pathv[i]; - - bool skipItem = (EndsWith(p, ".") == true || EndsWith(p, "..") == true); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"~~~~~~~~~~~ Glob file [%s] skipItem = %d\n",p,skipItem); - - if(skipItem == false) { - if(isdir(p) == false) { - bool addFile = true; - if(filterFileExt != "") { - addFile = EndsWith(p, filterFileExt); - } - - if(addFile) { - resultFiles.push_back(p); - } - } - else if(includeFolders == true) { - resultFiles.push_back(p); - } - } - } - - globfree(&globbuf); - - // Look recursively for sub-folders -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) - res = glob(mypath.c_str(), 0, 0, &globbuf); -#else //APPLE doesn't have the GLOB_ONLYDIR definition.. - globFlags |= GLOB_ONLYDIR; - res = glob(mypath.c_str(), globFlags, 0, &globbuf); -#endif - -#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) - if(res < 0) { - std::stringstream msg; - msg << "#5 Couldn't scan directory '" << mypath << "': " << strerror(errno); - throw megaglest_runtime_error(msg.str()); - } -#endif - - for(int i = 0; i < (int)globbuf.gl_pathc; ++i) { -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) - struct stat statStruct; - // only get if dir.. - lstat( globbuf.gl_pathv[ i], &statStruct); - if( S_ISDIR(statStruct.st_mode) == 0) - continue; -#endif - const char* p = globbuf.gl_pathv[i]; - - bool skipItem = (EndsWith(p, ".") == true || EndsWith(p, "..") == true); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"~~~~~~~~~~~ Glob folder [%s] skipItem = %d\n",p,skipItem); - - if(skipItem == false) { - if(includeFolders == true) { - resultFiles.push_back(p); - } - - string currentPath = p; - endPathWithSlash(currentPath); - - if(EndsWith(mypath,"{,.}*") == true) { - currentPath += "{,.}*"; - } - else { - currentPath += "*"; - } - resultFiles = getFolderTreeContentsListRecursively(currentPath, filterFileExt, includeFolders,&resultFiles); - } - } - - globfree(&globbuf); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str()); - - if(topLevelCaller == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] EXITING TOP LEVEL RECURSION\n",__FILE__,__FUNCTION__,__LINE__); - } - - return resultFiles; -} - -std::pair getFolderTreeContentsCheckSumListCacheKey(const string &path, const string &filterFileExt) { - string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey2; - - string cacheKey = path + "_" + filterFileExt; - return make_pair(cacheLookupId,cacheKey); -} - -void clearFolderTreeContentsCheckSumList(const string &path, const string &filterFileExt) { - std::pair cacheKeys = getFolderTreeContentsCheckSumListCacheKey(path,filterFileExt); - string cacheLookupId = cacheKeys.first; - std::map > > &crcTreeCache = CacheManager::getCachedItem< std::map > > >(cacheLookupId); - - string cacheKey = cacheKeys.second; - crcTreeCache.erase(cacheKey); - - string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys); - if(fileExists(crcCacheFile) == true) { - bool result = removeFile(crcCacheFile); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileitem [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),result); - } -} - -//finds all filenames like path and gets the checksum of each file -vector > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector > *recursiveMap) { - std::pair cacheKeys = getFolderTreeContentsCheckSumListCacheKey(path, filterFileExt); - string cacheLookupId = cacheKeys.first; - std::map > > &crcTreeCache = CacheManager::getCachedItem< std::map > > >(cacheLookupId); - - string cacheKey = cacheKeys.second; - if(crcTreeCache.find(cacheKey) != crcTreeCache.end()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s] FOUND CACHED result for cacheKey [%s]\n",__FILE__,__FUNCTION__,path.c_str(),cacheKey.c_str()); - return crcTreeCache[cacheKey]; - } - - bool topLevelCaller = (recursiveMap == NULL); - vector > checksumFiles = (recursiveMap == NULL ? vector >() : *recursiveMap); - - std::string mypath = path; - /** Stupid win32 is searching for all files without extension when *. is - * specified as wildcard - */ - if((int)mypath.size() >= 2 && mypath.compare(max((int)0,(int)mypath.size() - 2), 2, "*.") == 0) { - mypath = mypath.substr(0, max((int)0,(int)mypath.size() - 2)); - mypath += "*"; - } - - glob_t globbuf; - - int res = glob(mypath.c_str(), 0, 0, &globbuf); - -#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) - if(res < 0) { - std::stringstream msg; - msg << "#6 Couldn't scan directory '" << mypath << "': " << strerror(errno); - throw megaglest_runtime_error(msg.str()); - } -#endif - - for(int i = 0; i < (int)globbuf.gl_pathc; ++i) { - const char* p = globbuf.gl_pathv[i]; - - if(isdir(p) == false) { - bool addFile = true; - if(EndsWith(p, ".") == true || EndsWith(p, "..") == true || EndsWith(p, ".git") == true) { - addFile = false; - } - else if(filterFileExt != "") { - addFile = EndsWith(p, filterFileExt); - } - - if(addFile) { - Checksum checksum; - checksum.addFile(p); - - checksumFiles.push_back(std::pair(p,checksum.getSum())); - } - } - } - - globfree(&globbuf); - - // Look recursively for sub-folders -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) - res = glob(mypath.c_str(), 0, 0, &globbuf); -#else //APPLE doesn't have the GLOB_ONLYDIR definition.. - res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf); -#endif - -#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) - if(res < 0) { - std::stringstream msg; - msg << "#7 Couldn't scan directory '" << mypath << "': " << strerror(errno); - throw megaglest_runtime_error(msg.str()); - } -#endif - - for(int i = 0; i < (int)globbuf.gl_pathc; ++i) { -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) - struct stat statStruct; - // only get if dir.. - lstat( globbuf.gl_pathv[ i], &statStruct); - if( S_ISDIR(statStruct.st_mode) == 0) - continue; -#endif - const char *p = globbuf.gl_pathv[i]; - - string currentPath = p; - endPathWithSlash(currentPath); - - checksumFiles = getFolderTreeContentsCheckSumListRecursively(currentPath + "*", filterFileExt, &checksumFiles); - } - - globfree(&globbuf); - - crcTreeCache[cacheKey] = checksumFiles; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s] cacheKey [%s] checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,path.c_str(),cacheKey.c_str(),checksumFiles.size()); - - if(topLevelCaller == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] EXITING TOP LEVEL RECURSION, checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,checksumFiles.size()); - } - - return crcTreeCache[cacheKey]; -} - -string extractFileFromDirectoryPath(string filename) { - size_t lastDirectory = filename.find_last_of("/\\"); - if (lastDirectory == string::npos) { - return filename; - } - - return filename.erase( 0, lastDirectory + 1); -} - -string extractDirectoryPathFromFile(string filename) { - size_t lastDirectory = filename.find_last_of("/\\"); - string path = ""; - if (lastDirectory != string::npos) { - path = filename.substr( 0, lastDirectory + 1); - } - - return path; -} - -string extractLastDirectoryFromPath(string Path) { - string result = Path; - size_t lastDirectory = Path.find_last_of("/\\"); - if (lastDirectory == string::npos) { - result = Path; - } - else { - if(Path.length() > lastDirectory + 1) { - result = Path.erase( 0, lastDirectory + 1); - } - else { - for(int i = (int)lastDirectory-1; i >= 0; --i) { - if((Path[i] == '/' || Path[i] == '\\') && i > 0) { - result = Path.erase( 0, i); + size_t pos = 0; + while (true) { + size_t nextPos = textLine.find(delimiters, pos); + if (nextPos == textLine.npos) { + tokens.push_back(textLine.substr(pos, textLine.length())); break; } + tokens.push_back(string(textLine.substr(pos, nextPos - pos))); + pos = nextPos + delimiters.size(); } + } - } - return result; -} -string extractExtension(const string& filepath) { - size_t lastPoint = filepath.find_last_of('.'); - size_t lastDirectory = filepath.find_last_of("/\\"); + void findDirs(const string &path, vector &results, bool errorOnNotFound, bool keepDuplicates) { + results.clear(); + string currentPath = path; + endPathWithSlash(currentPath); - if (lastPoint == string::npos || (lastDirectory != string::npos && lastDirectory > lastPoint)) { - return ""; - } - return filepath.substr(lastPoint+1); -} + string searchpath = currentPath + "*."; + vector current_results; + findAll(searchpath, current_results, false, errorOnNotFound); + if (current_results.empty() == false) { + for (unsigned int folder_index = 0; folder_index < current_results.size(); folder_index++) { + const string current_folder = current_results[folder_index]; + const string current_folder_path = currentPath + current_folder; -void createDirectoryPaths(string Path) { - char DirName[256]=""; - const char *path = Path.c_str(); - char *dirName = DirName; - while(*path) { - //if (('\\' == *path) || ('/' == *path)) - if ('/' == *path) { - if(isdir(DirName) == false) { -#ifdef WIN32 - int result = _wmkdir(utf8_decode(DirName).c_str()); - //int result = _mkdir(DirName); -#elif defined(__GNUC__) - int result = mkdir(DirName, S_IRWXU | S_IRWXO | S_IRWXG); -#else - #error "Your compiler needs to support mkdir!" -#endif - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] DirName [%s] result = %d, errno = %d\n",__FILE__,__FUNCTION__,__LINE__,DirName,result,errno); - } - } - *dirName++ = *path++; - *dirName = '\0'; - } -#ifdef WIN32 - //int result = _mkdir(DirName); - int result = _wmkdir(utf8_decode(DirName).c_str()); -#elif defined(__GNUC__) - int result = mkdir(DirName, S_IRWXU | S_IRWXO | S_IRWXG); -#else - #error "Your compiler needs to support mkdir!" -#endif - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] DirName [%s] result = %d, errno = %d\n",__FILE__,__FUNCTION__,__LINE__,DirName,result,errno); -} + if (isdir(current_folder_path.c_str()) == true) { + if (keepDuplicates == true || std::find(results.begin(), results.end(), current_folder) == results.end()) { + results.push_back(current_folder); + } + } + } + } -void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight,bool isFullscreen) { -// TTSDL What does this method do ? I have no clue... -// -// // Get the current video hardware information -// //const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo(); -// //colorBits = vidInfo->vfmt->BitsPerPixel; -// //screenWidth = vidInfo->current_w; -// //screenHeight = vidInfo->current_h; -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -// -// /* Get available fullscreen/hardware modes */ -// -// #if defined(WIN32) || defined(__APPLE__) -// -// int flags = 0; -// -// #else -// -// int flags = SDL_WINDOW_RESIZABLE; -// -// #endif -// if(isFullscreen) flags = SDL_WINDOW_FULLSCREEN; -// SDL_Rect**modes = SDL_ListModes(NULL, SDL_OPENGL|flags); -// -// /* Check if there are any modes available */ -// if (modes == (SDL_Rect**)0) { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] no hardware modes available.\n",__FILE__,__FUNCTION__,__LINE__); -// -// const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo(); -// colorBits = vidInfo->vfmt->BitsPerPixel; -// screenWidth = vidInfo->current_w; -// screenHeight = vidInfo->current_h; -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] using current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,screenWidth,screenHeight); -// } -// /* Check if our resolution is restricted */ -// else if (modes == (SDL_Rect**)-1) { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] all resolutions available.\n",__FILE__,__FUNCTION__,__LINE__); -// -// const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo(); -// colorBits = vidInfo->vfmt->BitsPerPixel; -// screenWidth = vidInfo->current_w; -// screenHeight = vidInfo->current_h; -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] using current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,screenWidth,screenHeight); -// } -// else{ -// /* Print valid modes */ -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] available Modes are:\n",__FILE__,__FUNCTION__,__LINE__); -// -// int bestW = -1; -// int bestH = -1; -// for(int i=0; modes[i]; ++i) { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%d x %d\n",modes[i]->w, modes[i]->h); -// -// if(bestW < modes[i]->w) { -// bestW = modes[i]->w; -// bestH = modes[i]->h; -// } -// } -// -// if(bestW > screenWidth) { -// screenWidth = bestW; -// screenHeight = bestH; -// } -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] using current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,screenWidth,screenHeight); -// } -} + std::sort(results.begin(), results.end()); + } + void findDirs(const vector &paths, vector &results, bool errorOnNotFound, bool keepDuplicates) { + results.clear(); + size_t pathCount = paths.size(); + for (unsigned int idx = 0; idx < pathCount; idx++) { + string currentPath = paths[idx]; + endPathWithSlash(currentPath); + string path = currentPath + "*."; + vector current_results; + findAll(path, current_results, false, errorOnNotFound); + if (current_results.empty() == false) { + for (unsigned int folder_index = 0; folder_index < current_results.size(); folder_index++) { + const string current_folder = current_results[folder_index]; + const string current_folder_path = currentPath + current_folder; -void getFullscreenVideoModes(vector *modeinfos, bool isFullscreen) { - // Get the current video hardware information - //const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo(); - //colorBits = vidInfo->vfmt->BitsPerPixel; - //screenWidth = vidInfo->current_w; - //screenHeight = vidInfo->current_h; + if (isdir(current_folder_path.c_str()) == true) { + if (keepDuplicates == true || std::find(results.begin(), results.end(), current_folder) == results.end()) { + results.push_back(current_folder); + } + } + } + } + } - if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + std::sort(results.begin(), results.end()); + } - //SDL_PixelFormat format; - //SDL_Rect **modes; - //int loops(0); - //int bpp(0); - std::map uniqueResList; + void findAll(const vector &paths, const string &fileFilter, vector &results, bool cutExtension, bool errorOnNotFound, bool keepDuplicates) { + results.clear(); + size_t pathCount = paths.size(); + for (unsigned int idx = 0; idx < pathCount; idx++) { + string currentPath = paths[idx]; + endPathWithSlash(currentPath); - /////////////////////////// - vector > allResoltuions; - SDL_DisplayMode mode = {SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0}; - int max=SDL_GetNumDisplayModes(0); - for (int i = 0; i < max; ++i) { - if(0==SDL_GetDisplayMode(0,i,&mode)) { - int bpp; - Uint32 Rmask; - Uint32 Gmask; - Uint32 Bmask; - Uint32 Amask; - SDL_PixelFormatEnumToMasks(mode.format,&bpp,&Rmask,&Gmask,&Bmask,&Amask); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%d x %d\n",allResoltuions[i].first, allResoltuions[i].second,bpp); - string lookupKey = intToStr(mode.w) + "_" + intToStr(mode.h) + "_" + intToStr(bpp); - if(uniqueResList.find(lookupKey) == uniqueResList.end()) { - uniqueResList[lookupKey] = true; - modeinfos->push_back(ModeInfo(mode.w,mode.h,bpp)); + string path = currentPath + fileFilter; + vector current_results; + findAll(path, current_results, cutExtension, errorOnNotFound); + if (current_results.empty() == false) { + for (unsigned int folder_index = 0; folder_index < current_results.size(); folder_index++) { + string current_file = current_results[folder_index]; + if (keepDuplicates == true || std::find(results.begin(), results.end(), current_file) == results.end()) { + results.push_back(current_file); + } + } + } + } + + std::sort(results.begin(), results.end()); + } + + //finds all filenames like path and stores them in results + void findAll(const string &path, vector &results, bool cutExtension, bool errorOnNotFound) { + results.clear(); + + std::string mypath = path; + /** Stupid win32 is searching for all files without extension when *. is + * specified as wildcard + */ + if ((int) mypath.size() >= 2 && mypath.compare(max((int) 0, (int) mypath.size() - 2), 2, "*.") == 0) { + mypath = mypath.substr(0, max((int) 0, (int) mypath.size() - 2)); + mypath += "*"; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] scanning [%s]\n", __FILE__, __FUNCTION__, mypath.c_str()); + + glob_t globbuf; + + int res = glob(mypath.c_str(), 0, 0, &globbuf); + if (res < 0 && errorOnNotFound == true) { + if (errorOnNotFound) { + std::stringstream msg; + msg << "#1 Couldn't scan directory '" << mypath << "': " << strerror(errno); + throw megaglest_runtime_error(msg.str()); + } + } else { + for (int i = 0; i < (int) globbuf.gl_pathc; ++i) { + const char* p = globbuf.gl_pathv[i]; + const char* begin = p; + for (; *p != 0; ++p) { + // strip the path component + if (*p == '/') + begin = p + 1; + } + if (!(strcmp(".", begin) == 0 || strcmp("..", begin) == 0 || strcmp(".git", begin) == 0)) { + results.push_back(begin); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] SKIPPED SPECIAL FILENAME [%s]\n", __FILE__, __FUNCTION__, __LINE__, begin); + } + } + + globfree(&globbuf); + + if (results.empty() == true && errorOnNotFound == true) { + throw megaglest_runtime_error("No files found in: " + mypath); + } + + if (cutExtension) { + for (size_t i = 0; i < results.size(); ++i) { + results.at(i) = cutLastExt(results.at(i)); + } } } } - ////////////////////////////////// - std::sort(modeinfos->begin(),modeinfos->end()); - } - - -void changeVideoModeFullScreen(bool value) { - Private::shouldBeFullscreen = value; -} - -void restoreVideoMode(SDL_Window *sdlWindow,bool exitingApp) { - //SDL_Quit(); - if(exitingApp == true && SDL_WasInit(SDL_INIT_VIDEO)) { - SDL_SetRelativeMouseMode(SDL_FALSE); - SDL_SetWindowBrightness(sdlWindow, 1.0f); - } -} - -//int getScreenW() { -// return SDL_GetVideoSurface()->w; //SDL_GetWindowSurface() -//} -// -//int getScreenH() { -// return SDL_GetVideoSurface()->h; -//} - -void sleep(int millis) { - SDL_Delay(millis); -} - -bool isCursorShowing() { - int state = SDL_ShowCursor(SDL_QUERY); - return (state == SDL_ENABLE); -} - -void showCursor(bool b) { - //printf("In showCursor, b: %d, isCursorShowing(): %d\n",b,isCursorShowing()); - - - if(isCursorShowing() == b) { - return; - } - //printf("showCursor(bool b) b=%d\n",b); - SDL_ShowCursor(b == true ? SDL_ENABLE : SDL_DISABLE); -} - -//bool isKeyDown(SDLKey key) { -// const Uint8* keystate = SDL_GetKeyboardState(0); -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = %d\n",__FILE__,__FUNCTION__,__LINE__,key); -// -// if(key >= 0) { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] keystate[key] = %d\n",__FILE__,__FUNCTION__,__LINE__,keystate[key]); -// -// return (keystate[key] != 0); -// } -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] returning false\n",__FILE__,__FUNCTION__,__LINE__); -// return false; -// -//} - -bool isKeyDown(int virtualKey) { - char key = static_cast (virtualKey); - const Uint8* keystate = SDL_GetKeyboardState(0); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = %d\n",__FILE__,__FUNCTION__,__LINE__,key); - - if(key >= 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] keystate[key] = %d\n",__FILE__,__FUNCTION__,__LINE__,keystate[(unsigned char)key]); - - return (keystate[(unsigned char)key] != 0); - } - switch(key) { -//SDLTT case vkAdd: -// return (keystate[SDL_SCANCODE_PLUS] != 0 || keystate[SDL_SCANCODE_KP_PLUS] != 0); - case vkSubtract: - return (keystate[SDL_SCANCODE_MINUS] != 0 || keystate[SDL_SCANCODE_KP_MINUS] != 0); - case vkAlt: - return (keystate[SDL_SCANCODE_LALT] != 0 || keystate[SDL_SCANCODE_RALT] != 0); - case vkControl: - return (keystate[SDL_SCANCODE_LCTRL] != 0 || keystate[SDL_SCANCODE_RCTRL] != 0); - case vkShift: - return (keystate[SDL_SCANCODE_LSHIFT] != 0 || keystate[SDL_SCANCODE_RSHIFT] != 0); - case vkEscape: - return (keystate[SDL_SCANCODE_ESCAPE] != 0); - case vkUp: - return (keystate[SDL_SCANCODE_UP] != 0); - case vkLeft: - return (keystate[SDL_SCANCODE_LEFT] != 0); - case vkRight: - return (keystate[SDL_SCANCODE_RIGHT] != 0); - case vkDown: - return (keystate[SDL_SCANCODE_DOWN] != 0); - case vkReturn: - return (keystate[SDL_SCANCODE_RETURN] != 0 || keystate[SDL_SCANCODE_KP_ENTER] != 0); - case vkBack: - return (keystate[SDL_SCANCODE_BACKSPACE] != 0); - case vkDelete: - return (keystate[SDL_SCANCODE_DELETE] != 0); - case vkPrint: - return (keystate[SDL_SCANCODE_PRINTSCREEN] != 0); - case vkPause: - return (keystate[SDL_SCANCODE_PAUSE] != 0); - default: - std::cerr << "isKeyDown called with unknown key.\n"; - break; - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] returning false\n",__FILE__,__FUNCTION__,__LINE__); - return false; -} - -string replaceAllHTMLEntities(string& context) { - replaceAll(context,""","\""); - replaceAll(context,"&","&"); - replaceAll(context,"<","<"); - replaceAll(context,">",">"); - //replaceAll(context,"Œ","Œ"); - replaceAll(context,"Œ","\xC5\x92\0"); - //replaceAll(context,"œ","œ"); - replaceAll(context,"œ","\xC5\x93\0"); - //replaceAll(context,"Š","Š"); - replaceAll(context,"Š","\xC5\xA0\0"); - //replaceAll(context,"š","š"); - replaceAll(context,"š","\xC5\xA1\0"); - //replaceAll(context,"Ÿ","Ÿ"); - replaceAll(context,"Ÿ","\xC5\xB8\0"); - replaceAll(context,"ˆ","ˆ"); - replaceAll(context,"˜","˜"); - replaceAll(context," "," "); - replaceAll(context," "," "); - replaceAll(context," "," "); - replaceAll(context,"–","-"); - replaceAll(context,"—","-"); - //replaceAll(context,"‘","‘"); - replaceAll(context,"‘","\xE2\x80\x98\0"); - //replaceAll(context,"’","’"); - replaceAll(context,"’","\xE2\x80\x99\0"); - //replaceAll(context,"‚","‚"); - replaceAll(context,"‚","\xE2\x80\x9A\0"); - //replaceAll(context,"“","“"); - replaceAll(context,"“","\xE2\x80\x9C\0"); - //replaceAll(context,"”","”"); - replaceAll(context,"”","\xE2\x80\x9D\0"); - //replaceAll(context,"„","„"); - replaceAll(context,"„","\xE2\x80\x9E\0"); - //replaceAll(context,"†","†"); - replaceAll(context,"†","\xE2\x80\xA0\0"); - //replaceAll(context,"‡","‡"); - replaceAll(context,"‡","\xE2\x80\xA1\0"); - //replaceAll(context,"‰","‰"); - replaceAll(context,"‰","\xE2\x80\xB0\0"); - //replaceAll(context,"‹","‹"); - replaceAll(context,"‹","\xE2\x80\xB9\0"); - //replaceAll(context,"›","›"); - replaceAll(context,"›","\xE2\x80\xBA\0"); - //replaceAll(context,"€","€"); - replaceAll(context,"€","\xE2\x82\xAC\0"); - - return context; -} - -string replaceAll(string& context, const string& from, const string& to) { - size_t lookHere = 0; - size_t foundHere = 0; - if((foundHere = context.find(from, lookHere)) != string::npos) { - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Replacing context [%s] from [%s] to [%s]\n",context.c_str(),from.c_str(),to.c_str()); - - while((foundHere = context.find(from, lookHere)) != string::npos) { - context.replace(foundHere, from.size(), to); - lookHere = foundHere + to.size(); - } - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("New context [%s]\n",context.c_str()); - } - return context; -} - -vector replaceAllBetweenTokens(vector& context, - const string &startToken, const string &endToken, const string &newText, - bool removeTokens) { - string newValue(context.begin(),context.end()); - replaceAllBetweenTokens(newValue,startToken,endToken,newText,removeTokens); - context = vector(newValue.begin(),newValue.end()); - return context; -} - -string replaceAllBetweenTokens(string& context, const string &startToken, - const string &endToken, const string &newText, bool removeTokens) { - size_t lookHere = 0; - size_t foundHere = 0; - if((foundHere = context.find(startToken, lookHere)) != string::npos) { - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Replacing context [%s] from [%s] to [%s]\n",context.c_str(),from.c_str(),to.c_str()); - - while((foundHere = context.find(startToken, lookHere)) != string::npos) { - size_t foundHereEnd = context.find(endToken, foundHere+1); - if(foundHereEnd == string::npos) { - break; - } - if(removeTokens == true) { - foundHereEnd += endToken.size(); - - context.replace(foundHere, foundHereEnd-foundHere+1, newText); - lookHere = foundHere + newText.size(); - } - else { - foundHere += startToken.size(); - foundHereEnd -= 1; - - context.replace(foundHere, foundHereEnd-foundHere+1, newText); - lookHere = foundHere + newText.size(); - } - } - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("New context [%s]\n",context.c_str()); - } - return context; -} - -string getFullFileArchiveExtractCommand(const string &fileArchiveExtractCommand, - string fileArchiveExtractCommandParameters, const string &outputpath, const string &archivename) { - string parsedOutputpath = outputpath; - string parsedArchivename = archivename; - -// This is required for execution on win32 -#if defined(WIN32) - replaceAll(parsedOutputpath, "\\\\", "\\"); - replaceAll(parsedOutputpath, "/", "\\"); - replaceAll(parsedArchivename, "\\\\", "\\"); - replaceAll(parsedArchivename, "/", "\\"); -#endif - - string result = fileArchiveExtractCommand; - result += " "; - string args = replaceAll(fileArchiveExtractCommandParameters, "{outputpath}", parsedOutputpath); - args = replaceAll(args, "{archivename}", parsedArchivename); - result += args; - - return result; -} - -string getFullFileArchiveCompressCommand(const string &fileArchiveCompressCommand, - string fileArchiveCompressCommandParameters, - const string &archivename, const string &archivefiles) { - string parsedArchivename = archivename; - string parsedArchivefiles = archivefiles; - -// This is required for execution on win32 -#if defined(WIN32) - replaceAll(parsedArchivename, "\\\\", "\\"); - replaceAll(parsedArchivename, "/", "\\"); - replaceAll(parsedArchivefiles, "\\\\", "\\"); - replaceAll(parsedArchivefiles, "/", "\\"); - -#endif - - string result = fileArchiveCompressCommand; - result += " "; - string args = replaceAll(fileArchiveCompressCommandParameters, "{archivename}", parsedArchivename); - args = replaceAll(args, "{archivefiles}", parsedArchivefiles); - result += args; - - return result; -} - -bool executeShellCommand(string cmd, int expectedResult, ShellCommandOutputCallbackInterface *cb) { - bool result = false; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"About to run [%s]", cmd.c_str()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("About to run [%s]", cmd.c_str()); + bool isdir(const char *path) { + string friendly_path = path; #ifdef WIN32 - FILE *file = _wpopen(utf8_decode(cmd).c_str(),L"r"); -#else - FILE *file = popen(cmd.c_str(),"r"); + replaceAll(friendly_path, "/", "\\"); + if (EndsWith(friendly_path, "\\") == true) { + friendly_path.erase(friendly_path.begin() + friendly_path.length() - 1); + } #endif - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"file = [%p]", file); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("file = [%p]", file); +#ifdef WIN32 +#if defined(__MINGW32__) + struct _stat stats; +#else + struct _stat64i32 stats; +#endif + int result = _wstat(utf8_decode(friendly_path).c_str(), &stats); +#else + struct stat stats; + int result = stat(friendly_path.c_str(), &stats); +#endif + bool ret = (result == 0); + if (ret == true) { + ret = S_ISDIR(stats.st_mode); // #define S_ISDIR(mode) ((mode) & _S_IFDIR) - if(file != NULL) { - char szBuf[4096]=""; - while(feof(file) == false) { - if(fgets( szBuf, 4095, file) != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s",szBuf); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s",szBuf); + if (ret == false) { + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s] ret = %d\n",__FILE__,__FUNCTION__,__LINE__,friendly_path.c_str(),ret); + } + } else { + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s] ret = %d, result = %d, errno = %d\n",__FILE__,__FUNCTION__,__LINE__,friendly_path.c_str(),ret,result,errno); + } + //if(ret == false) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] NOT a path [%s]\n",__FILE__,__FUNCTION__,__LINE__,path); - if(cb != NULL) { - cb->ShellCommandOutput_CallbackEvent(cmd,szBuf,cb->getShellCommandOutput_UserData(cmd)); + return ret; + } + + bool fileExists(const string &path) { + if (path.size() == 0) return false; + +#ifdef WIN32 + wstring wstr = utf8_decode(path); + FILE* file = _wfopen(wstr.c_str(), L"rb"); +#else + FILE* file = fopen(path.c_str(), "rb"); +#endif + if (file != NULL) { + fclose(file); + return true; + } + // else { + //int fileErrno = errno; + //#ifdef WIN32 + //int fileErrno = errno; + //DWORD error = GetLastError(); + //string strError = "[#6] Could not open file, result: " + intToStr(error) + " - " + intToStr(fileErrno) + " " + strerror(fileErrno) + " [" + path + "]"; + //#endif + // } + return false; + } + + void removeFolder(const string &path) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] path [%s]\n", __FILE__, __FUNCTION__, __LINE__, path.c_str()); + + string deletePath = path; + endPathWithSlash(deletePath); + deletePath += "{,.}*"; + vector results = getFolderTreeContentsListRecursively(deletePath, "", true); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] path [%s] results.size() = %d\n", __FILE__, __FUNCTION__, __LINE__, path.c_str(), results.size()); + + // First delete files + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] DELETE FILES\n", __FILE__, __FUNCTION__, __LINE__); + + for (int i = (int) results.size() - 1; i >= 0; --i) { + string item = results[i]; + + //if(item.find(".git") != string::npos) { + // printf("!!!!!!!!!!!!!!!!!! FOUND SPECIAL FOLDER [%s] in [%s]\n",item.c_str(),path.c_str()); + //} + + if (isdir(item.c_str()) == false) { + bool result = removeFile(item); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] fileitem [%s] result = %d\n", __FILE__, __FUNCTION__, __LINE__, item.c_str(), result); } } + // Now delete folders + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] DELETE FOLDERS\n", __FILE__, __FUNCTION__, __LINE__); + + for (int i = (int) results.size() - 1; i >= 0; --i) { + string item = results[i]; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] item [%s] isdir(item.c_str()) = %d\n", __FILE__, __FUNCTION__, __LINE__, item.c_str(), isdir(item.c_str())); + if (isdir(item.c_str()) == true) { + + //printf("~~~~~ REMOVE FOLDER [%s] in [%s]\n",item.c_str(),path.c_str()); + +#ifdef WIN32 + //int result = _rmdir(item.c_str()); + int result = _wrmdir(utf8_decode(item).c_str()); +#else + int result = rmdir(item.c_str()); +#endif + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] item [%s] result = %d\n", __FILE__, __FUNCTION__, __LINE__, item.c_str(), result); + + if (result != 0 && item != path) { + printf("CANNOT REMOVE FOLDER [%s] in [%s]\n", item.c_str(), path.c_str()); + removeFolder(item); + } + } + } + +#ifdef WIN32 + //int result = _rmdir(path.c_str()); + int result = _wrmdir(utf8_decode(path).c_str()); +#else + int result = rmdir(path.c_str()); +#endif + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] path [%s] result = %d\n", __FILE__, __FUNCTION__, __LINE__, path.c_str(), result); } + + bool StartsWith(const std::string &str, const std::string &key) { + return str.find(key) == 0; + } + + bool EndsWith(const string &str, const string& key) { + bool result = false; + if (str.length() >= key.length()) { + result = (0 == str.compare(max((int) 0, (int) str.length() - (int) key.length()), key.length(), key)); + } + + return result; + } + + void endPathWithSlash(string &path, bool requireOSSlash) { + if (EndsWith(path, "/") == false && EndsWith(path, "\\") == false) { + string seperator = "/"; + if (requireOSSlash == true) { +#if defined(WIN32) + seperator = "\\"; +#endif + } + path += seperator; + } + } + + string formatPath(string path) { + replaceAll(path, "\"", ""); + replaceAll(path, "//", "/"); + + return path; + } + + void trimPathWithStartingSlash(string &path) { + if (StartsWith(path, "/") == true || StartsWith(path, "\\") == true) { + path.erase(path.begin(), path.begin() + 1); + //printf("************* trimPathWithStartingSlash changed path [%s]\n",path.c_str()); + } + } + + void updatePathClimbingParts(string &path, bool processPreviousDirTokenCheck) { + // Update paths with /./ + string::size_type pos = path.find("/./"); + if (pos != string::npos && pos != 0) { + string orig = path; + path.erase(pos, 2); + //pos--; + + //printf("#1 CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str()); + + pos = path.find("/./"); + if (pos != string::npos && pos != 0) { + updatePathClimbingParts(path, processPreviousDirTokenCheck); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n", orig.c_str(), path.c_str()); + } + pos = path.find("\\.\\"); + if (pos != string::npos && pos != 0) { + string orig = path; + path.erase(pos, 2); + //pos--; + //printf("#w CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str()); + + pos = path.find("\\.\\"); + if (pos != string::npos && pos != 0) { + updatePathClimbingParts(path, processPreviousDirTokenCheck); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n", orig.c_str(), path.c_str()); + } + + // Update paths with .. + if (processPreviousDirTokenCheck) { + pos = path.find(".."); + if (pos != string::npos && pos != 0) { + + string orig = path; + if (path[pos - 1] != ' ' || (path.length() > 2 && path[pos + 2] != ' ')) { + path.erase(pos, 2); + + //printf("#3 [%d] CHANGE relative path from [%s] to [%s]\n",(int)pos,orig.c_str(),path.c_str()); + + pos--; + //pos = pos -1; + + //printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #3b [%d]\n",(int)pos); + + if (path[pos] == '/' || path[pos] == '\\') { + path.erase(pos, 1); + + //printf("#4 CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str()); + } + + for (int x = (int) pos; x >= 0; --x) { + //printf("x [%d][%c] pos [%ld][%c] [%s]\n",x,path[x],(long int)pos,path[pos],path.substr(0,x+1).c_str()); + + if ((path[x] == '/' || path[x] == '\\') && x != (int) pos) { + //string origLoop = path; + path.erase(x, (int) pos - x); + + //printf("#5 [%d] [%d] [%d] CHANGE relative path from [%s] to [%s]\n",(int)pos,(int)x,(int)origLoop.length(),origLoop.c_str(),path.c_str()); + break; + } + } + pos = path.find(".."); + } else { + //printf("#6a [%d]\n",(int)pos); + + //pos = path.find("..",pos+1); + pos = string::npos; + + //printf("#6b [%d]\n",(int)pos); + } + if (pos != string::npos && pos != 0) { + updatePathClimbingParts(path, processPreviousDirTokenCheck); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n", orig.c_str(), path.c_str()); + } + } + + /* + string::size_type pos = path.rfind(".."); + if(pos != string::npos && pos != 0) { + string orig = path; + path.erase(pos,2); + pos--; + if(path[pos] == '/' || path[pos] == '\\') { + path.erase(pos,1); + } + + for(int x = pos; x >= 0; --x) { + //printf("x [%d][%c] pos [%ld][%c] [%s]\n",x,path[x],(long int)pos,path[pos],path.substr(0,x+1).c_str()); + + if((path[x] == '/' || path[x] == '\\') && x != pos) { + path.erase(x,pos-x); + break; + } + } + + printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str()); + } + */ + } + + string getCRCCacheFilePath() { + return crcCachePath; + } + + void setCRCCacheFilePath(const string &path) { + crcCachePath = path; + } + + //string getGameVersion() { + // return gameVersion; + //} + //string getGameGITVersion() { + // return gameGITVersion; + //} + void setGameVersion(const string &version) { + gameVersion = version; + } + void setGameGITVersion(const string &git) { + gameGITVersion = git; + } + + string getCRCCacheFileName(std::pair cacheKeys) { + string crcCacheFile = cacheKeys.first + cacheKeys.second; + return crcCacheFile; + } + string getFormattedCRCCacheFileName(std::pair cacheKeys) { + string crcCacheFile = getCRCCacheFileName(cacheKeys); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] cacheKeys.first = [%s] cacheKeys.second [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, cacheKeys.first.c_str(), cacheKeys.second.c_str()); + + Checksum checksum; + checksum.addString(crcCacheFile); + string result = getCRCCacheFilePath() + "CRC_CACHE_" + uIntToStr(checksum.getSum()); + return result; + } + std::pair getFolderTreeContentsCheckSumCacheKey(vector paths, const string &pathSearchString, const string &filterFileExt) { + string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey1; + + string cacheKey = ""; + for (unsigned int idx = 0; idx < paths.size(); ++idx) { + string path = paths[idx] + pathSearchString; + cacheKey += path + "_" + filterFileExt + "_"; + } + return make_pair(cacheLookupId, cacheKey); + } + + pair hasCachedFileCRCValue(string crcCacheFile, uint32 &value) { + //bool result = false; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] Line: %d for Cache file [%s]\n", __FILE__, __FUNCTION__, __LINE__, crcCacheFile.c_str()); + } + + pair result = make_pair(false, 0); + if (fileExists(crcCacheFile) == true) { #ifdef WIN32 - int cmdRet = _pclose(file); + FILE *fp = _wfopen(utf8_decode(crcCacheFile).c_str(), L"r"); #else - int cmdRet = pclose(file); + FILE *fp = fopen(crcCacheFile.c_str(), "r"); +#endif + if (fp != NULL) { + time_t refreshDate = 0; + uint32 crcValue = 0; + time_t lastUpdateDate = 0; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] Line: %d for Cache file [%s]\n", __FILE__, __FUNCTION__, __LINE__, crcCacheFile.c_str()); + } + + char gameVer[500] = ""; + char gitVer[500] = ""; + char actualFilePath[8096] = ""; + int readbytes = fscanf(fp, "%20ld,%20u,%20ld\n%499s\n%499s\n%8095s", + (long *) &refreshDate, + &crcValue, + (long *) &lastUpdateDate, + &gameVer[0], + &gitVer[0], + &actualFilePath[0]); + refreshDate = Shared::PlatformByteOrder::fromCommonEndian(refreshDate); + crcValue = Shared::PlatformByteOrder::fromCommonEndian(crcValue); + lastUpdateDate = Shared::PlatformByteOrder::fromCommonEndian(lastUpdateDate); + string readGameVer = Shared::PlatformByteOrder::fromCommonEndian(string(gameVer)); + string readGitVer = Shared::PlatformByteOrder::fromCommonEndian(string(gitVer)); + string readActualFilePath = Shared::PlatformByteOrder::fromCommonEndian(string(actualFilePath)); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("CRC readGameVer [%s] [%s]\n%s\n", readGameVer.c_str(), readGitVer.c_str(), readActualFilePath.c_str()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] Line: %d for Cache file [%s] readbytes = %d\n", __FILE__, __FUNCTION__, __LINE__, crcCacheFile.c_str(), readbytes); + } + + fclose(fp); + + struct tm future; /* as in future date */ + future.tm_sec = 0; + future.tm_min = 0; + future.tm_hour = 0; + future.tm_mday = 6; /* 1st */ + future.tm_mon = 6; /* July */ + future.tm_year = 2012 - 1900; /* 2038 in years since 1900 */ + future.tm_isdst = 0; /* Daylight Saving not in affect (UTC) */ +#ifdef _BSD_SOURCE + future.tm_zone = "UTC"; #endif - /* Close pipe and print return value. */ - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"Process returned %d\n", cmdRet); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Process returned %d\n", cmdRet); - result = (expectedResult == IGNORE_CMD_RESULT_VALUE || expectedResult == cmdRet); - } - return result; -} + time_t tBadCRCDate = mktime(&future); -bool removeFile(string file) { + result.second = lastUpdateDate; + if (readGameVer != "" && readGitVer != "" && + refreshDate > 0 && + refreshDate > tBadCRCDate && + time(NULL) < refreshDate) { + + result.first = true; + value = crcValue; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { + //struct tm *loctime = localtime (&refreshDate); + struct tm loctime = threadsafe_localtime(refreshDate); + char szBuf1[100] = ""; + strftime(szBuf1, 100, "%Y-%m-%d %H:%M:%S", &loctime); + + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "=-=-=-=- READ CACHE for Cache file [%s] refreshDate = %ld [%s], crcValue = %u\n", + crcCacheFile.c_str(), refreshDate, szBuf1, crcValue); + } + } else { + //time_t now = time(NULL); + //struct tm *loctime = localtime (&now); + struct tm loctime = threadsafe_localtime(systemtime_now()); + char szBuf1[100] = ""; + strftime(szBuf1, 100, "%Y-%m-%d %H:%M:%S", &loctime); + + loctime = threadsafe_localtime(refreshDate); + char szBuf2[100] = ""; + strftime(szBuf2, 100, "%Y-%m-%d %H:%M:%S", &loctime); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, + "=-=-=-=- NEED TO CALCULATE CRC for Cache file [%s] now = %ld [%s], refreshDate = %ld [%s], crcValue = %u\n", + crcCacheFile.c_str(), systemtime_now(), szBuf1, refreshDate, szBuf2, crcValue); + } + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, "FILE NOT FOUND(1) for Cache file [%s]\n", crcCacheFile.c_str()); + } + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) { + SystemFlags::OutputDebug(SystemFlags::debugSystem, "FILE NOT FOUND(2) for Cache file [%s]\n", crcCacheFile.c_str()); + } + } + + return result; + } + + void writeCachedFileCRCValue(string crcCacheFile, uint32 &crcValue, string actualFileName) { #ifdef WIN32 - int result = _unlink(file.c_str()); + FILE *fp = _wfopen(utf8_decode(crcCacheFile).c_str(), L"w"); #else - int result = unlink(file.c_str()); + FILE *fp = fopen(crcCacheFile.c_str(), "w"); +#endif + if (fp != NULL) { + //RandomGen random; + //int offset = random.randRange(5, 15); + srand((unsigned int) time(NULL) + (unsigned long) crcCacheFile.length()); + int offset = rand() % 15; + if (offset == 0) { + offset = 3; + } + time_t now = time(NULL); + time_t refreshDate = now + (REFRESH_CRC_DAY_SECONDS * offset); + + //struct tm *loctime = localtime (&refreshDate); + struct tm loctime = threadsafe_localtime(refreshDate); + char szBuf1[100] = ""; + strftime(szBuf1, 100, "%Y-%m-%d %H:%M:%S", &loctime); + + string writeGameVer = Shared::PlatformByteOrder::toCommonEndian(gameVersion); + string writeGameGITVersion = Shared::PlatformByteOrder::toCommonEndian(gameGITVersion); + string writeActualFileName = Shared::PlatformByteOrder::toCommonEndian(actualFileName); + + fprintf(fp, "%20ld,%20u,%20ld", + (long) Shared::PlatformByteOrder::toCommonEndian(refreshDate), + Shared::PlatformByteOrder::toCommonEndian(crcValue), + (long) Shared::PlatformByteOrder::toCommonEndian(now)); + + fprintf(fp, "\n%s\n%s\n%s", + writeGameVer.c_str(), + writeGameGITVersion.c_str(), + writeActualFileName.c_str()); + + fclose(fp); + + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"========== Writing CRC Cache offset [%d] refreshDate = %ld [%s], crcValue = %u, file [%s]\n",offset,refreshDate,szBuf1,crcValue,crcCacheFile.c_str()); + } + } + + void clearFolderTreeContentsCheckSum(vector paths, const string &pathSearchString, const string &filterFileExt) { + std::pair cacheKeys = getFolderTreeContentsCheckSumCacheKey(paths, pathSearchString, filterFileExt); + string cacheLookupId = cacheKeys.first; + std::map &crcTreeCache = CacheManager::getCachedItem< std::map >(cacheLookupId); + + string cacheKey = cacheKeys.second; + crcTreeCache.erase(cacheKey); + + for (unsigned int idx = 0; idx < paths.size(); ++idx) { + string path = paths[idx]; + clearFolderTreeContentsCheckSum(path, filterFileExt); + } + + string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys); + if (fileExists(crcCacheFile) == true) { + + bool result = removeFile(crcCacheFile); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] fileitem [%s] result = %d\n", __FILE__, __FUNCTION__, __LINE__, crcCacheFile.c_str(), result); + } + } + + time_t getFolderTreeContentsCheckSumRecursivelyLastGenerated(const vector &paths, string pathSearchString, const string &filterFileExt) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "-------------- In [%s::%s Line: %d] Calculating CRC for [%s] -----------\n", __FILE__, __FUNCTION__, __LINE__, pathSearchString.c_str()); + + std::pair cacheKeys = getFolderTreeContentsCheckSumCacheKey(paths, pathSearchString, filterFileExt); + //string cacheLookupId = cacheKeys.first; + //std::map &crcTreeCache = CacheManager::getCachedItem< std::map >(cacheLookupId); + + string cacheKey = cacheKeys.second; + string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "-------------- In [%s::%s Line: %d] looking for cached CRC file [%s] for [%s] -----------\n", __FILE__, __FUNCTION__, __LINE__, crcCacheFile.c_str(), pathSearchString.c_str()); + + uint32 crcValue = 0; + pair crcResult = hasCachedFileCRCValue(crcCacheFile, crcValue); + if (crcResult.first == true) { + //struct tm *loctime = localtime (&crcResult.second); + struct tm loctime = threadsafe_localtime(crcResult.second); + char szBuf1[100] = ""; + strftime(szBuf1, 100, "%Y-%m-%d %H:%M:%S", &loctime); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] scanning folders found CACHED FILE for cacheKey [%s] last updated [%s]\n", __FILE__, __FUNCTION__, __LINE__, cacheKey.c_str(), szBuf1); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s Line: %d] scanning folders found CACHED FILE for cacheKey [%s] last updated [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str(),szBuf1); + + return crcResult.second; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s]\n", __FILE__, __FUNCTION__, cacheKey.c_str()); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s]\n",__FILE__,__FUNCTION__,cacheKey.c_str()); + } + + return 0; + } + + //finds all filenames like path and gets their checksum of all files combined + uint32 getFolderTreeContentsCheckSumRecursively(vector paths, string pathSearchString, const string &filterFileExt, Checksum *recursiveChecksum, bool forceNoCache) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "-------------- In [%s::%s Line: %d] Calculating CRC for [%s] -----------\n", __FILE__, __FUNCTION__, __LINE__, pathSearchString.c_str()); + + std::pair cacheKeys = getFolderTreeContentsCheckSumCacheKey(paths, pathSearchString, filterFileExt); + string cacheLookupId = cacheKeys.first; + std::map &crcTreeCache = CacheManager::getCachedItem< std::map >(cacheLookupId); + + string cacheKey = cacheKeys.second; + if (forceNoCache == false && crcTreeCache.find(cacheKey) != crcTreeCache.end()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] scanning folders found CACHED checksum = %d for cacheKey [%s]\n", __FILE__, __FUNCTION__, __LINE__, crcTreeCache[cacheKey], cacheKey.c_str()); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s Line: %d] scanning folders found CACHED checksum = %d for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str()); + return crcTreeCache[cacheKey]; + } + + string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Looking for CRC Cache file [%s]\n",crcCacheFile.c_str()); + + if (recursiveChecksum == NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "-------------- In [%s::%s Line: %d] looking for cached CRC file [%s] for [%s] forceNoCache = %d -----------\n", __FILE__, __FUNCTION__, __LINE__, crcCacheFile.c_str(), pathSearchString.c_str(), forceNoCache); + } + + uint32 crcValue = 0; + if (forceNoCache == false && hasCachedFileCRCValue(crcCacheFile, crcValue).first == true) { + crcTreeCache[cacheKey] = crcValue; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n", __FILE__, __FUNCTION__, __LINE__, crcTreeCache[cacheKey], cacheKey.c_str(), forceNoCache); + if (recursiveChecksum == NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "-------------- In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n", __FILE__, __FUNCTION__, __LINE__, crcTreeCache[cacheKey], cacheKey.c_str(), forceNoCache); + } + + return crcTreeCache[cacheKey]; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n", __FILE__, __FUNCTION__, cacheKey.c_str(), forceNoCache); + if (recursiveChecksum == NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "-------------- In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n", __FILE__, __FUNCTION__, cacheKey.c_str(), forceNoCache); + } + } + + Checksum checksum = (recursiveChecksum == NULL ? Checksum() : *recursiveChecksum); + for (unsigned int idx = 0; idx < paths.size(); ++idx) { + string path = paths[idx] + pathSearchString; + + getFolderTreeContentsCheckSumRecursively(path, filterFileExt, &checksum, forceNoCache); + } + + if (recursiveChecksum != NULL) { + *recursiveChecksum = checksum; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] Final CRC file count: %d\n", __FILE__, __FUNCTION__, __LINE__, checksum.getFileCount()); + + uint32 result = checksum.getFinalFileListSum(); + //if(forceNoCache == false) { + crcTreeCache[cacheKey] = result; + writeCachedFileCRCValue(crcCacheFile, crcTreeCache[cacheKey], getCRCCacheFileName(cacheKeys)); + //} + return result; + } + + std::pair getFolderTreeContentsCheckSumCacheKey(const string &path, const string &filterFileExt) { + string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey2; + + string cacheKey = path + "_" + filterFileExt; + return make_pair(cacheLookupId, cacheKey); + } + + void clearFolderTreeContentsCheckSum(const string &path, const string &filterFileExt) { + std::pair cacheKeys = getFolderTreeContentsCheckSumCacheKey(path, filterFileExt); + string cacheLookupId = cacheKeys.first; + std::map &crcTreeCache = CacheManager::getCachedItem< std::map >(cacheLookupId); + + string cacheKey = cacheKeys.second; + crcTreeCache.erase(cacheKey); + + string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys); + if (fileExists(crcCacheFile) == true) { + bool result = removeFile(crcCacheFile); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] fileitem [%s] result = %d\n", __FILE__, __FUNCTION__, __LINE__, crcCacheFile.c_str(), result); + } + } + + //finds all filenames like path and gets their checksum of all files combined + uint32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum, bool forceNoCache) { + std::pair cacheKeys = getFolderTreeContentsCheckSumCacheKey(path, filterFileExt); + + string cacheLookupId = cacheKeys.first; + std::map &crcTreeCache = CacheManager::getCachedItem< std::map >(cacheLookupId); + + string cacheKey = cacheKeys.second; + if (forceNoCache == false && crcTreeCache.find(cacheKey) != crcTreeCache.end()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] scanning [%s] found CACHED checksum = %d for cacheKey [%s]\n", __FILE__, __FUNCTION__, __LINE__, path.c_str(), crcTreeCache[cacheKey], cacheKey.c_str()); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s Line: %d] scanning [%s] found CACHED checksum = %d for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),crcTreeCache[cacheKey],cacheKey.c_str()); + return crcTreeCache[cacheKey]; + } + + string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Looking for CRC Cache file [%s]\n",crcCacheFile.c_str()); + + if (recursiveChecksum == NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "-------------- In [%s::%s Line: %d] looking for cached CRC file [%s] for [%s] forceNoCache = %d -----------\n", __FILE__, __FUNCTION__, __LINE__, crcCacheFile.c_str(), path.c_str(), forceNoCache); + } + + uint32 crcValue = 0; + if (forceNoCache == false && hasCachedFileCRCValue(crcCacheFile, crcValue).first == true) { + crcTreeCache[cacheKey] = crcValue; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n", __FILE__, __FUNCTION__, __LINE__, crcTreeCache[cacheKey], cacheKey.c_str(), forceNoCache); + if (recursiveChecksum == NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "-------------- In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n", __FILE__, __FUNCTION__, __LINE__, crcTreeCache[cacheKey], cacheKey.c_str(), forceNoCache); + } + + return crcTreeCache[cacheKey]; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n", __FILE__, __FUNCTION__, cacheKey.c_str(), forceNoCache); + if (recursiveChecksum == NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "-------------- In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n", __FILE__, __FUNCTION__, cacheKey.c_str(), forceNoCache); + } + } + + bool topLevelCaller = (recursiveChecksum == NULL); + Checksum checksum = (recursiveChecksum == NULL ? Checksum() : *recursiveChecksum); + + std::string mypath = path; + // Stupid win32 is searching for all files without extension when *. is + // specified as wildcard + // + if ((int) mypath.size() >= 2 && mypath.compare(max((int) 0, (int) mypath.size() - 2), 2, "*.") == 0) { + mypath = mypath.substr(0, max((int) 0, (int) mypath.size() - 2)); + mypath += "*"; + } + + glob_t globbuf; + + int res = glob(mypath.c_str(), 0, 0, &globbuf); +#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) + if (res < 0) { + std::stringstream msg; + msg << "#2 Couldn't scan directory '" << mypath << "': " << strerror(errno); + throw megaglest_runtime_error(msg.str()); + } #endif - return (result == 0); -} + int fileLoopCount = 0; + int fileMatchCount = 0; + for (int i = 0; i < (int) globbuf.gl_pathc; ++i) { + const char* p = globbuf.gl_pathv[i]; + //printf("Line: %d p [%s]\n",__LINE__,p); -bool renameFile(string oldFile, string newFile) { - int result = rename(oldFile.c_str(),newFile.c_str()); - return (result == 0); -} + if (isdir(p) == false) { + bool addFile = true; + if (EndsWith(p, ".") == true || EndsWith(p, "..") == true || EndsWith(p, ".git") == true) { + addFile = false; + } else if (filterFileExt != "") { + addFile = EndsWith(p, filterFileExt); + } -off_t getFileSize(string filename) { -#ifdef WIN32 - #if defined(__MINGW32__) - struct _stat stbuf; - #else - struct _stat64i32 stbuf; - #endif - if(_wstat(utf8_decode(filename).c_str(), &stbuf) != -1) { + if (addFile) { + checksum.addFile(p); + fileMatchCount++; + } + } + fileLoopCount++; + } + + globfree(&globbuf); + + // Look recursively for sub-folders +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) + res = glob(mypath.c_str(), 0, 0, &globbuf); #else - struct stat stbuf; - if(stat(filename.c_str(), &stbuf) != -1) { + res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf); #endif - return stbuf.st_size; - } - return 0; -} -string executable_path(const string &exeName, bool includeExeNameInPath) { - string value = ""; +#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) + if (res < 0) { + std::stringstream msg; + msg << "#3 Couldn't scan directory '" << mypath << "': " << strerror(errno); + throw megaglest_runtime_error(msg.str()); + } +#endif + + for (int i = 0; i < (int) globbuf.gl_pathc; ++i) { +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) + struct stat statStruct; + // only process if dir.. + lstat(globbuf.gl_pathv[i], &statStruct); + if (S_ISDIR(statStruct.st_mode) == 0) + continue; +#endif + const char *p = globbuf.gl_pathv[i]; + //printf("Line: %d p [%s]\n",__LINE__,p); + + string currentPath = p; + endPathWithSlash(currentPath); + + getFolderTreeContentsCheckSumRecursively(currentPath + "*", filterFileExt, &checksum, forceNoCache); + } + + globfree(&globbuf); + + if (recursiveChecksum != NULL) { + *recursiveChecksum = checksum; + } + + if (topLevelCaller == true) { + //printf("In [%s::%s Line: %d] Final CRC file count for [%s]: %d\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),checksum.getFileCount()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] Final CRC file count for [%s]: %d\n", __FILE__, __FUNCTION__, __LINE__, path.c_str(), checksum.getFileCount()); + + uint32 result = checksum.getFinalFileListSum(); + //if(forceNoCache == false) { + crcTreeCache[cacheKey] = result; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] scanning [%s] ending checksum = %d for cacheKey [%s] fileMatchCount = %d, fileLoopCount = %d\n", __FILE__, __FUNCTION__, path.c_str(), crcTreeCache[cacheKey], cacheKey.c_str(), fileMatchCount, fileLoopCount); + writeCachedFileCRCValue(crcCacheFile, crcTreeCache[cacheKey], getCRCCacheFileName(cacheKeys)); + //} + + return result; + } else { + return 0; + } + } + + + std::pair getFolderTreeContentsCheckSumListCacheKey(vector paths, const string &pathSearchString, const string &filterFileExt) { + string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey1; + + string cacheKey = ""; + for (unsigned int idx = 0; idx < paths.size(); ++idx) { + string path = paths[idx] + pathSearchString; + cacheKey += path + "_" + filterFileExt + "_"; + } + return make_pair(cacheLookupId, cacheKey); + } + + void clearFolderTreeContentsCheckSumList(vector paths, const string &pathSearchString, const string &filterFileExt) { + std::pair cacheKeys = getFolderTreeContentsCheckSumListCacheKey(paths, pathSearchString, filterFileExt); + string cacheLookupId = cacheKeys.first; + std::map > > &crcTreeCache = CacheManager::getCachedItem< std::map > > >(cacheLookupId); + + string cacheKey = cacheKeys.second; + crcTreeCache.erase(cacheKey); + + for (unsigned int idx = 0; idx < paths.size(); ++idx) { + string path = paths[idx]; + clearFolderTreeContentsCheckSumList(path, filterFileExt); + } + string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys); + if (fileExists(crcCacheFile) == true) { + bool result = removeFile(crcCacheFile); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] fileitem [%s] result = %d\n", __FILE__, __FUNCTION__, __LINE__, crcCacheFile.c_str(), result); + } + } + + vector > getFolderTreeContentsCheckSumListRecursively(vector paths, const string &pathSearchString, const string &filterFileExt, vector > *recursiveMap) { + std::pair cacheKeys = getFolderTreeContentsCheckSumListCacheKey(paths, pathSearchString, filterFileExt); + string cacheLookupId = cacheKeys.first; + std::map > > &crcTreeCache = CacheManager::getCachedItem< std::map > > >(cacheLookupId); + + string cacheKey = cacheKeys.second; + if (crcTreeCache.find(cacheKey) != crcTreeCache.end()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] scanning folders found CACHED result for cacheKey [%s]\n", __FILE__, __FUNCTION__, __LINE__, cacheKey.c_str()); + return crcTreeCache[cacheKey]; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] scanning folders, NO CACHE found result for cacheKey [%s]\n", __FILE__, __FUNCTION__, __LINE__, cacheKey.c_str()); + } + + bool topLevelCaller = (recursiveMap == NULL); + + vector > checksumFiles = (recursiveMap == NULL ? vector >() : *recursiveMap); + for (unsigned int idx = 0; idx < paths.size(); ++idx) { + string path = paths[idx] + pathSearchString; + checksumFiles = getFolderTreeContentsCheckSumListRecursively(path, filterFileExt, &checksumFiles); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] checksumFiles.size() = %d\n", __FILE__, __FUNCTION__, __LINE__, checksumFiles.size()); + + if (topLevelCaller == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] EXITING TOP LEVEL RECURSION, checksumFiles.size() = %d\n", __FILE__, __FUNCTION__, __LINE__, checksumFiles.size()); + } + + crcTreeCache[cacheKey] = checksumFiles; + return crcTreeCache[cacheKey]; + } + + //finds all filenames like path and gets the checksum of each file + vector getFolderTreeContentsListRecursively(const string &path, const string &filterFileExt, bool includeFolders, vector *recursiveMap) { + bool topLevelCaller = (recursiveMap == NULL); + vector resultFiles = (recursiveMap == NULL ? vector() : *recursiveMap); + + std::string mypath = path; + /** Stupid win32 is searching for all files without extension when *. is + * specified as wildcard + */ + if ((int) mypath.size() >= 2 && mypath.compare(max((int) 0, (int) mypath.size() - 2), 2, "*.") == 0) { + mypath = mypath.substr(0, max((int) 0, (int) mypath.size() - 2)); + mypath += "*"; + } + + glob_t globbuf; + + int globFlags = 0; + if (EndsWith(mypath, "{,.}*") == true) { +#ifndef WIN32 + globFlags = GLOB_BRACE; +#else + // Windows glob source cannot handle GLOB_BRACE + // but that should be ok for win32 platform + replaceAll(mypath, "{,.}*", "*"); +#endif + } + + int res = glob(mypath.c_str(), globFlags, 0, &globbuf); +#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) + if (res < 0) { + std::stringstream msg; + msg << "#4 Couldn't scan directory '" << mypath << "': " << strerror(errno); + throw megaglest_runtime_error(msg.str()); + } +#endif + for (int i = 0; i < (int) globbuf.gl_pathc; ++i) { + const char* p = globbuf.gl_pathv[i]; + + bool skipItem = (EndsWith(p, ".") == true || EndsWith(p, "..") == true); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "~~~~~~~~~~~ Glob file [%s] skipItem = %d\n", p, skipItem); + + if (skipItem == false) { + if (isdir(p) == false) { + bool addFile = true; + if (filterFileExt != "") { + addFile = EndsWith(p, filterFileExt); + } + + if (addFile) { + resultFiles.push_back(p); + } + } else if (includeFolders == true) { + resultFiles.push_back(p); + } + } + } + + globfree(&globbuf); + + // Look recursively for sub-folders +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) + res = glob(mypath.c_str(), 0, 0, &globbuf); +#else //APPLE doesn't have the GLOB_ONLYDIR definition.. + globFlags |= GLOB_ONLYDIR; + res = glob(mypath.c_str(), globFlags, 0, &globbuf); +#endif + +#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) + if (res < 0) { + std::stringstream msg; + msg << "#5 Couldn't scan directory '" << mypath << "': " << strerror(errno); + throw megaglest_runtime_error(msg.str()); + } +#endif + + for (int i = 0; i < (int) globbuf.gl_pathc; ++i) { +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) + struct stat statStruct; + // only get if dir.. + lstat(globbuf.gl_pathv[i], &statStruct); + if (S_ISDIR(statStruct.st_mode) == 0) + continue; +#endif + const char* p = globbuf.gl_pathv[i]; + + bool skipItem = (EndsWith(p, ".") == true || EndsWith(p, "..") == true); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "~~~~~~~~~~~ Glob folder [%s] skipItem = %d\n", p, skipItem); + + if (skipItem == false) { + if (includeFolders == true) { + resultFiles.push_back(p); + } + + string currentPath = p; + endPathWithSlash(currentPath); + + if (EndsWith(mypath, "{,.}*") == true) { + currentPath += "{,.}*"; + } else { + currentPath += "*"; + } + resultFiles = getFolderTreeContentsListRecursively(currentPath, filterFileExt, includeFolders, &resultFiles); + } + } + + globfree(&globbuf); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] scanning [%s]\n", __FILE__, __FUNCTION__, path.c_str()); + + if (topLevelCaller == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] EXITING TOP LEVEL RECURSION\n", __FILE__, __FUNCTION__, __LINE__); + } + + return resultFiles; + } + + std::pair getFolderTreeContentsCheckSumListCacheKey(const string &path, const string &filterFileExt) { + string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey2; + + string cacheKey = path + "_" + filterFileExt; + return make_pair(cacheLookupId, cacheKey); + } + + void clearFolderTreeContentsCheckSumList(const string &path, const string &filterFileExt) { + std::pair cacheKeys = getFolderTreeContentsCheckSumListCacheKey(path, filterFileExt); + string cacheLookupId = cacheKeys.first; + std::map > > &crcTreeCache = CacheManager::getCachedItem< std::map > > >(cacheLookupId); + + string cacheKey = cacheKeys.second; + crcTreeCache.erase(cacheKey); + + string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys); + if (fileExists(crcCacheFile) == true) { + bool result = removeFile(crcCacheFile); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] fileitem [%s] result = %d\n", __FILE__, __FUNCTION__, __LINE__, crcCacheFile.c_str(), result); + } + } + + //finds all filenames like path and gets the checksum of each file + vector > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector > *recursiveMap) { + std::pair cacheKeys = getFolderTreeContentsCheckSumListCacheKey(path, filterFileExt); + string cacheLookupId = cacheKeys.first; + std::map > > &crcTreeCache = CacheManager::getCachedItem< std::map > > >(cacheLookupId); + + string cacheKey = cacheKeys.second; + if (crcTreeCache.find(cacheKey) != crcTreeCache.end()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] scanning [%s] FOUND CACHED result for cacheKey [%s]\n", __FILE__, __FUNCTION__, path.c_str(), cacheKey.c_str()); + return crcTreeCache[cacheKey]; + } + + bool topLevelCaller = (recursiveMap == NULL); + vector > checksumFiles = (recursiveMap == NULL ? vector >() : *recursiveMap); + + std::string mypath = path; + /** Stupid win32 is searching for all files without extension when *. is + * specified as wildcard + */ + if ((int) mypath.size() >= 2 && mypath.compare(max((int) 0, (int) mypath.size() - 2), 2, "*.") == 0) { + mypath = mypath.substr(0, max((int) 0, (int) mypath.size() - 2)); + mypath += "*"; + } + + glob_t globbuf; + + int res = glob(mypath.c_str(), 0, 0, &globbuf); + +#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) + if (res < 0) { + std::stringstream msg; + msg << "#6 Couldn't scan directory '" << mypath << "': " << strerror(errno); + throw megaglest_runtime_error(msg.str()); + } +#endif + + for (int i = 0; i < (int) globbuf.gl_pathc; ++i) { + const char* p = globbuf.gl_pathv[i]; + + if (isdir(p) == false) { + bool addFile = true; + if (EndsWith(p, ".") == true || EndsWith(p, "..") == true || EndsWith(p, ".git") == true) { + addFile = false; + } else if (filterFileExt != "") { + addFile = EndsWith(p, filterFileExt); + } + + if (addFile) { + Checksum checksum; + checksum.addFile(p); + + checksumFiles.push_back(std::pair(p, checksum.getSum())); + } + } + } + + globfree(&globbuf); + + // Look recursively for sub-folders +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) + res = glob(mypath.c_str(), 0, 0, &globbuf); +#else //APPLE doesn't have the GLOB_ONLYDIR definition.. + res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf); +#endif + +#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) + if (res < 0) { + std::stringstream msg; + msg << "#7 Couldn't scan directory '" << mypath << "': " << strerror(errno); + throw megaglest_runtime_error(msg.str()); + } +#endif + + for (int i = 0; i < (int) globbuf.gl_pathc; ++i) { +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) + struct stat statStruct; + // only get if dir.. + lstat(globbuf.gl_pathv[i], &statStruct); + if (S_ISDIR(statStruct.st_mode) == 0) + continue; +#endif + const char *p = globbuf.gl_pathv[i]; + + string currentPath = p; + endPathWithSlash(currentPath); + + checksumFiles = getFolderTreeContentsCheckSumListRecursively(currentPath + "*", filterFileExt, &checksumFiles); + } + + globfree(&globbuf); + + crcTreeCache[cacheKey] = checksumFiles; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s] scanning [%s] cacheKey [%s] checksumFiles.size() = %d\n", __FILE__, __FUNCTION__, path.c_str(), cacheKey.c_str(), checksumFiles.size()); + + if (topLevelCaller == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] EXITING TOP LEVEL RECURSION, checksumFiles.size() = %d\n", __FILE__, __FUNCTION__, __LINE__, checksumFiles.size()); + } + + return crcTreeCache[cacheKey]; + } + + string extractFileFromDirectoryPath(string filename) { + size_t lastDirectory = filename.find_last_of("/\\"); + if (lastDirectory == string::npos) { + return filename; + } + + return filename.erase(0, lastDirectory + 1); + } + + string extractDirectoryPathFromFile(string filename) { + size_t lastDirectory = filename.find_last_of("/\\"); + string path = ""; + if (lastDirectory != string::npos) { + path = filename.substr(0, lastDirectory + 1); + } + + return path; + } + + string extractLastDirectoryFromPath(string Path) { + string result = Path; + size_t lastDirectory = Path.find_last_of("/\\"); + if (lastDirectory == string::npos) { + result = Path; + } else { + if (Path.length() > lastDirectory + 1) { + result = Path.erase(0, lastDirectory + 1); + } else { + for (int i = (int) lastDirectory - 1; i >= 0; --i) { + if ((Path[i] == '/' || Path[i] == '\\') && i > 0) { + result = Path.erase(0, i); + break; + } + } + } + } + return result; + } + + string extractExtension(const string& filepath) { + size_t lastPoint = filepath.find_last_of('.'); + size_t lastDirectory = filepath.find_last_of("/\\"); + + if (lastPoint == string::npos || (lastDirectory != string::npos && lastDirectory > lastPoint)) { + return ""; + } + return filepath.substr(lastPoint + 1); + } + + void createDirectoryPaths(string Path) { + char DirName[256] = ""; + const char *path = Path.c_str(); + char *dirName = DirName; + while (*path) { + //if (('\\' == *path) || ('/' == *path)) + if ('/' == *path) { + if (isdir(DirName) == false) { +#ifdef WIN32 + int result = _wmkdir(utf8_decode(DirName).c_str()); + //int result = _mkdir(DirName); +#elif defined(__GNUC__) + int result = mkdir(DirName, S_IRWXU | S_IRWXO | S_IRWXG); +#else +#error "Your compiler needs to support mkdir!" +#endif + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] DirName [%s] result = %d, errno = %d\n", __FILE__, __FUNCTION__, __LINE__, DirName, result, errno); + } + } + *dirName++ = *path++; + *dirName = '\0'; + } +#ifdef WIN32 + //int result = _mkdir(DirName); + int result = _wmkdir(utf8_decode(DirName).c_str()); +#elif defined(__GNUC__) + int result = mkdir(DirName, S_IRWXU | S_IRWXO | S_IRWXG); +#else +#error "Your compiler needs to support mkdir!" +#endif + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] DirName [%s] result = %d, errno = %d\n", __FILE__, __FUNCTION__, __LINE__, DirName, result, errno); + } + + void getFullscreenVideoInfo(int &colorBits, int &screenWidth, int &screenHeight, bool isFullscreen) { + // TTSDL What does this method do ? I have no clue... + // + // // Get the current video hardware information + // //const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo(); + // //colorBits = vidInfo->vfmt->BitsPerPixel; + // //screenWidth = vidInfo->current_w; + // //screenHeight = vidInfo->current_h; + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + // + // /* Get available fullscreen/hardware modes */ + // + // #if defined(WIN32) || defined(__APPLE__) + // + // int flags = 0; + // + // #else + // + // int flags = SDL_WINDOW_RESIZABLE; + // + // #endif + // if(isFullscreen) flags = SDL_WINDOW_FULLSCREEN; + // SDL_Rect**modes = SDL_ListModes(NULL, SDL_OPENGL|flags); + // + // /* Check if there are any modes available */ + // if (modes == (SDL_Rect**)0) { + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] no hardware modes available.\n",__FILE__,__FUNCTION__,__LINE__); + // + // const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo(); + // colorBits = vidInfo->vfmt->BitsPerPixel; + // screenWidth = vidInfo->current_w; + // screenHeight = vidInfo->current_h; + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] using current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,screenWidth,screenHeight); + // } + // /* Check if our resolution is restricted */ + // else if (modes == (SDL_Rect**)-1) { + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] all resolutions available.\n",__FILE__,__FUNCTION__,__LINE__); + // + // const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo(); + // colorBits = vidInfo->vfmt->BitsPerPixel; + // screenWidth = vidInfo->current_w; + // screenHeight = vidInfo->current_h; + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] using current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,screenWidth,screenHeight); + // } + // else{ + // /* Print valid modes */ + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] available Modes are:\n",__FILE__,__FUNCTION__,__LINE__); + // + // int bestW = -1; + // int bestH = -1; + // for(int i=0; modes[i]; ++i) { + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%d x %d\n",modes[i]->w, modes[i]->h); + // + // if(bestW < modes[i]->w) { + // bestW = modes[i]->w; + // bestH = modes[i]->h; + // } + // } + // + // if(bestW > screenWidth) { + // screenWidth = bestW; + // screenHeight = bestH; + // } + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] using current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,screenWidth,screenHeight); + // } + } + + + void getFullscreenVideoModes(vector *modeinfos, bool isFullscreen) { + // Get the current video hardware information + //const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo(); + //colorBits = vidInfo->vfmt->BitsPerPixel; + //screenWidth = vidInfo->current_w; + //screenHeight = vidInfo->current_h; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //SDL_PixelFormat format; + //SDL_Rect **modes; + //int loops(0); + //int bpp(0); + std::map uniqueResList; + + /////////////////////////// + vector > allResoltuions; + SDL_DisplayMode mode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 }; + int max = SDL_GetNumDisplayModes(0); + for (int i = 0; i < max; ++i) { + if (0 == SDL_GetDisplayMode(0, i, &mode)) { + int bpp; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + Uint32 Amask; + SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "%d x %d\n", allResoltuions[i].first, allResoltuions[i].second, bpp); + string lookupKey = intToStr(mode.w) + "_" + intToStr(mode.h) + "_" + intToStr(bpp); + if (uniqueResList.find(lookupKey) == uniqueResList.end()) { + uniqueResList[lookupKey] = true; + modeinfos->push_back(ModeInfo(mode.w, mode.h, bpp)); + } + } + } + ////////////////////////////////// + std::sort(modeinfos->begin(), modeinfos->end()); + } + + + + void changeVideoModeFullScreen(bool value) { + Private::shouldBeFullscreen = value; + } + + void restoreVideoMode(SDL_Window *sdlWindow, bool exitingApp) { + //SDL_Quit(); + if (exitingApp == true && SDL_WasInit(SDL_INIT_VIDEO)) { + SDL_SetRelativeMouseMode(SDL_FALSE); + SDL_SetWindowBrightness(sdlWindow, 1.0f); + } + } + + //int getScreenW() { + // return SDL_GetVideoSurface()->w; //SDL_GetWindowSurface() + //} + // + //int getScreenH() { + // return SDL_GetVideoSurface()->h; + //} + + void sleep(int millis) { + SDL_Delay(millis); + } + + bool isCursorShowing() { + int state = SDL_ShowCursor(SDL_QUERY); + return (state == SDL_ENABLE); + } + + void showCursor(bool b) { + //printf("In showCursor, b: %d, isCursorShowing(): %d\n",b,isCursorShowing()); + + + if (isCursorShowing() == b) { + return; + } + //printf("showCursor(bool b) b=%d\n",b); + SDL_ShowCursor(b == true ? SDL_ENABLE : SDL_DISABLE); + } + + //bool isKeyDown(SDLKey key) { + // const Uint8* keystate = SDL_GetKeyboardState(0); + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = %d\n",__FILE__,__FUNCTION__,__LINE__,key); + // + // if(key >= 0) { + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] keystate[key] = %d\n",__FILE__,__FUNCTION__,__LINE__,keystate[key]); + // + // return (keystate[key] != 0); + // } + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] returning false\n",__FILE__,__FUNCTION__,__LINE__); + // return false; + // + //} + + bool isKeyDown(int virtualKey) { + char key = static_cast (virtualKey); + const Uint8* keystate = SDL_GetKeyboardState(0); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] key = %d\n", __FILE__, __FUNCTION__, __LINE__, key); + + if (key >= 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] keystate[key] = %d\n", __FILE__, __FUNCTION__, __LINE__, keystate[(unsigned char) key]); + + return (keystate[(unsigned char) key] != 0); + } + switch (key) { + //SDLTT case vkAdd: + // return (keystate[SDL_SCANCODE_PLUS] != 0 || keystate[SDL_SCANCODE_KP_PLUS] != 0); + case vkSubtract: + return (keystate[SDL_SCANCODE_MINUS] != 0 || keystate[SDL_SCANCODE_KP_MINUS] != 0); + case vkAlt: + return (keystate[SDL_SCANCODE_LALT] != 0 || keystate[SDL_SCANCODE_RALT] != 0); + case vkControl: + return (keystate[SDL_SCANCODE_LCTRL] != 0 || keystate[SDL_SCANCODE_RCTRL] != 0); + case vkShift: + return (keystate[SDL_SCANCODE_LSHIFT] != 0 || keystate[SDL_SCANCODE_RSHIFT] != 0); + case vkEscape: + return (keystate[SDL_SCANCODE_ESCAPE] != 0); + case vkUp: + return (keystate[SDL_SCANCODE_UP] != 0); + case vkLeft: + return (keystate[SDL_SCANCODE_LEFT] != 0); + case vkRight: + return (keystate[SDL_SCANCODE_RIGHT] != 0); + case vkDown: + return (keystate[SDL_SCANCODE_DOWN] != 0); + case vkReturn: + return (keystate[SDL_SCANCODE_RETURN] != 0 || keystate[SDL_SCANCODE_KP_ENTER] != 0); + case vkBack: + return (keystate[SDL_SCANCODE_BACKSPACE] != 0); + case vkDelete: + return (keystate[SDL_SCANCODE_DELETE] != 0); + case vkPrint: + return (keystate[SDL_SCANCODE_PRINTSCREEN] != 0); + case vkPause: + return (keystate[SDL_SCANCODE_PAUSE] != 0); + default: + std::cerr << "isKeyDown called with unknown key.\n"; + break; + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] returning false\n", __FILE__, __FUNCTION__, __LINE__); + return false; + } + + string replaceAllHTMLEntities(string& context) { + replaceAll(context, """, "\""); + replaceAll(context, "&", "&"); + replaceAll(context, "<", "<"); + replaceAll(context, ">", ">"); + //replaceAll(context,"Œ","Œ"); + replaceAll(context, "Œ", "\xC5\x92\0"); + //replaceAll(context,"œ","œ"); + replaceAll(context, "œ", "\xC5\x93\0"); + //replaceAll(context,"Š","Š"); + replaceAll(context, "Š", "\xC5\xA0\0"); + //replaceAll(context,"š","š"); + replaceAll(context, "š", "\xC5\xA1\0"); + //replaceAll(context,"Ÿ","Ÿ"); + replaceAll(context, "Ÿ", "\xC5\xB8\0"); + replaceAll(context, "ˆ", "ˆ"); + replaceAll(context, "˜", "˜"); + replaceAll(context, " ", " "); + replaceAll(context, " ", " "); + replaceAll(context, " ", " "); + replaceAll(context, "–", "-"); + replaceAll(context, "—", "-"); + //replaceAll(context,"‘","‘"); + replaceAll(context, "‘", "\xE2\x80\x98\0"); + //replaceAll(context,"’","’"); + replaceAll(context, "’", "\xE2\x80\x99\0"); + //replaceAll(context,"‚","‚"); + replaceAll(context, "‚", "\xE2\x80\x9A\0"); + //replaceAll(context,"“","“"); + replaceAll(context, "“", "\xE2\x80\x9C\0"); + //replaceAll(context,"”","”"); + replaceAll(context, "”", "\xE2\x80\x9D\0"); + //replaceAll(context,"„","„"); + replaceAll(context, "„", "\xE2\x80\x9E\0"); + //replaceAll(context,"†","†"); + replaceAll(context, "†", "\xE2\x80\xA0\0"); + //replaceAll(context,"‡","‡"); + replaceAll(context, "‡", "\xE2\x80\xA1\0"); + //replaceAll(context,"‰","‰"); + replaceAll(context, "‰", "\xE2\x80\xB0\0"); + //replaceAll(context,"‹","‹"); + replaceAll(context, "‹", "\xE2\x80\xB9\0"); + //replaceAll(context,"›","›"); + replaceAll(context, "›", "\xE2\x80\xBA\0"); + //replaceAll(context,"€","€"); + replaceAll(context, "€", "\xE2\x82\xAC\0"); + + return context; + } + + string replaceAll(string& context, const string& from, const string& to) { + size_t lookHere = 0; + size_t foundHere = 0; + if ((foundHere = context.find(from, lookHere)) != string::npos) { + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Replacing context [%s] from [%s] to [%s]\n",context.c_str(),from.c_str(),to.c_str()); + + while ((foundHere = context.find(from, lookHere)) != string::npos) { + context.replace(foundHere, from.size(), to); + lookHere = foundHere + to.size(); + } + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("New context [%s]\n",context.c_str()); + } + return context; + } + + vector replaceAllBetweenTokens(vector& context, + const string &startToken, const string &endToken, const string &newText, + bool removeTokens) { + string newValue(context.begin(), context.end()); + replaceAllBetweenTokens(newValue, startToken, endToken, newText, removeTokens); + context = vector(newValue.begin(), newValue.end()); + return context; + } + + string replaceAllBetweenTokens(string& context, const string &startToken, + const string &endToken, const string &newText, bool removeTokens) { + size_t lookHere = 0; + size_t foundHere = 0; + if ((foundHere = context.find(startToken, lookHere)) != string::npos) { + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Replacing context [%s] from [%s] to [%s]\n",context.c_str(),from.c_str(),to.c_str()); + + while ((foundHere = context.find(startToken, lookHere)) != string::npos) { + size_t foundHereEnd = context.find(endToken, foundHere + 1); + if (foundHereEnd == string::npos) { + break; + } + if (removeTokens == true) { + foundHereEnd += endToken.size(); + + context.replace(foundHere, foundHereEnd - foundHere + 1, newText); + lookHere = foundHere + newText.size(); + } else { + foundHere += startToken.size(); + foundHereEnd -= 1; + + context.replace(foundHere, foundHereEnd - foundHere + 1, newText); + lookHere = foundHere + newText.size(); + } + } + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("New context [%s]\n",context.c_str()); + } + return context; + } + + string getFullFileArchiveExtractCommand(const string &fileArchiveExtractCommand, + string fileArchiveExtractCommandParameters, const string &outputpath, const string &archivename) { + string parsedOutputpath = outputpath; + string parsedArchivename = archivename; + + // This is required for execution on win32 +#if defined(WIN32) + replaceAll(parsedOutputpath, "\\\\", "\\"); + replaceAll(parsedOutputpath, "/", "\\"); + replaceAll(parsedArchivename, "\\\\", "\\"); + replaceAll(parsedArchivename, "/", "\\"); +#endif + + string result = fileArchiveExtractCommand; + result += " "; + string args = replaceAll(fileArchiveExtractCommandParameters, "{outputpath}", parsedOutputpath); + args = replaceAll(args, "{archivename}", parsedArchivename); + result += args; + + return result; + } + + string getFullFileArchiveCompressCommand(const string &fileArchiveCompressCommand, + string fileArchiveCompressCommandParameters, + const string &archivename, const string &archivefiles) { + string parsedArchivename = archivename; + string parsedArchivefiles = archivefiles; + + // This is required for execution on win32 +#if defined(WIN32) + replaceAll(parsedArchivename, "\\\\", "\\"); + replaceAll(parsedArchivename, "/", "\\"); + replaceAll(parsedArchivefiles, "\\\\", "\\"); + replaceAll(parsedArchivefiles, "/", "\\"); + +#endif + + string result = fileArchiveCompressCommand; + result += " "; + string args = replaceAll(fileArchiveCompressCommandParameters, "{archivename}", parsedArchivename); + args = replaceAll(args, "{archivefiles}", parsedArchivefiles); + result += args; + + return result; + } + + bool executeShellCommand(string cmd, int expectedResult, ShellCommandOutputCallbackInterface *cb) { + bool result = false; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "About to run [%s]", cmd.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("About to run [%s]", cmd.c_str()); + +#ifdef WIN32 + FILE *file = _wpopen(utf8_decode(cmd).c_str(), L"r"); +#else + FILE *file = popen(cmd.c_str(), "r"); +#endif + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "file = [%p]", file); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("file = [%p]", file); + + if (file != NULL) { + char szBuf[4096] = ""; + while (feof(file) == false) { + if (fgets(szBuf, 4095, file) != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "%s", szBuf); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("%s", szBuf); + + if (cb != NULL) { + cb->ShellCommandOutput_CallbackEvent(cmd, szBuf, cb->getShellCommandOutput_UserData(cmd)); + } + } + } +#ifdef WIN32 + int cmdRet = _pclose(file); +#else + int cmdRet = pclose(file); +#endif + + /* Close pipe and print return value. */ + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "Process returned %d\n", cmdRet); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Process returned %d\n", cmdRet); + result = (expectedResult == IGNORE_CMD_RESULT_VALUE || expectedResult == cmdRet); + } + return result; + } + + bool removeFile(string file) { +#ifdef WIN32 + int result = _unlink(file.c_str()); +#else + int result = unlink(file.c_str()); +#endif + + return (result == 0); + } + + bool renameFile(string oldFile, string newFile) { + int result = rename(oldFile.c_str(), newFile.c_str()); + return (result == 0); + } + + off_t getFileSize(string filename) { +#ifdef WIN32 +#if defined(__MINGW32__) + struct _stat stbuf; +#else + struct _stat64i32 stbuf; +#endif + if (_wstat(utf8_decode(filename).c_str(), &stbuf) != -1) { +#else + struct stat stbuf; + if (stat(filename.c_str(), &stbuf) != -1) { +#endif + return stbuf.st_size; + } + return 0; + } + + string executable_path(const string &exeName, bool includeExeNameInPath) { + string value = ""; #ifdef _WIN32 - char path[MAX_PATH]=""; - if( GetModuleFileNameA(NULL,path,MAX_PATH) == 0 ) { - if(includeExeNameInPath == true) { - value = exeName; - } - else { - value = extractDirectoryPathFromFile(exeName); - } - } - else { - if(includeExeNameInPath == true) { - value = path; - } - else { - value = extractDirectoryPathFromFile(path); - } - } -#elif __APPLE__ - char path[MAXPATHLEN+1]=""; - uint32_t path_len = MAXPATHLEN; - if ( _NSGetExecutablePath(path, &path_len) ) { - if(includeExeNameInPath == true) { - value = exeName; - } - else { - value = extractDirectoryPathFromFile(exeName); - } - } - else { - if(includeExeNameInPath == true) { - value = path; - } - else { - value = extractDirectoryPathFromFile(path); - } - } -#else - char exe_link_path[200]=""; - int length = readlink("/proc/self/exe", exe_link_path, sizeof(exe_link_path)); - if(length < 0 || length >= 200 ) { - char *argv0_path = realpath(exeName.c_str(),NULL); - if(argv0_path != NULL) { - if(includeExeNameInPath == true) { - value = argv0_path; - } - else { - value = extractDirectoryPathFromFile(argv0_path); - } - free(argv0_path); - argv0_path = NULL; - } - else { - const char *shell_path = getenv("_"); - if(shell_path != NULL) { - if(includeExeNameInPath == true) { - value = shell_path; - } - else { - value = extractDirectoryPathFromFile(shell_path); - } - } - else { - if(includeExeNameInPath == true) { + char path[MAX_PATH] = ""; + if (GetModuleFileNameA(NULL, path, MAX_PATH) == 0) { + if (includeExeNameInPath == true) { value = exeName; - } - else { + } else { value = extractDirectoryPathFromFile(exeName); } - } - } - } - else { - exe_link_path[length] = '\0'; - if(includeExeNameInPath == true) { - value = exe_link_path; - } - else { - value = extractDirectoryPathFromFile(exe_link_path); - } - } -#endif - return value; -} - -bool searchAndReplaceTextInFile(string fileName, string findText, string replaceText, bool simulateOnly) { - bool replacedText = false; - const int MAX_LEN_SINGLE_LINE = 4096; - char buffer[MAX_LEN_SINGLE_LINE+2]; - char *buff_ptr, *find_ptr; - FILE *fp1, *fp2; - size_t find_len = findText.length(); - - string tempfileName = fileName + "_tmp"; -#ifdef WIN32 - fp1 = _wfopen(utf8_decode(fileName).c_str(), L"r"); - fp2 = _wfopen(utf8_decode(tempfileName).c_str(), L"w"); -#else - fp1 = fopen(fileName.c_str(),"r"); - fp2 = fopen(tempfileName.c_str(),"w"); -#endif - - if(fp1 == NULL) { - if(fp2) fclose(fp2); - - throw megaglest_runtime_error("cannot open input file [" + fileName + "]"); - } - if(fp2 == NULL) { - if(fp1) fclose(fp1); - - throw megaglest_runtime_error("cannot open output file [" + tempfileName + "]"); - } - - while(fgets(buffer,MAX_LEN_SINGLE_LINE + 2,fp1)) { - buff_ptr = buffer; - if(findText != "") { - while ((find_ptr = strstr(buff_ptr,findText.c_str()))) { - //printf("Replacing text [%s] with [%s] in file [%s]\n",findText.c_str(),replaceText.c_str(),fileName.c_str()); - - while(buff_ptr < find_ptr) { - fputc((int)*buff_ptr++,fp2); + } else { + if (includeExeNameInPath == true) { + value = path; + } else { + value = extractDirectoryPathFromFile(path); } - fputs(replaceText.c_str(),fp2); - - buff_ptr += find_len; - replacedText = true; } +#elif __APPLE__ + char path[MAXPATHLEN + 1] = ""; + uint32_t path_len = MAXPATHLEN; + if (_NSGetExecutablePath(path, &path_len)) { + if (includeExeNameInPath == true) { + value = exeName; + } else { + value = extractDirectoryPathFromFile(exeName); + } + } else { + if (includeExeNameInPath == true) { + value = path; + } else { + value = extractDirectoryPathFromFile(path); + } + } +#else + char exe_link_path[200] = ""; + int length = readlink("/proc/self/exe", exe_link_path, sizeof(exe_link_path)); + if (length < 0 || length >= 200) { + char *argv0_path = realpath(exeName.c_str(), NULL); + if (argv0_path != NULL) { + if (includeExeNameInPath == true) { + value = argv0_path; + } else { + value = extractDirectoryPathFromFile(argv0_path); + } + free(argv0_path); + argv0_path = NULL; + } else { + const char *shell_path = getenv("_"); + if (shell_path != NULL) { + if (includeExeNameInPath == true) { + value = shell_path; + } else { + value = extractDirectoryPathFromFile(shell_path); + } + } else { + if (includeExeNameInPath == true) { + value = exeName; + } else { + value = extractDirectoryPathFromFile(exeName); + } + } + } + } else { + exe_link_path[length] = '\0'; + if (includeExeNameInPath == true) { + value = exe_link_path; + } else { + value = extractDirectoryPathFromFile(exe_link_path); + } + } +#endif + return value; } - fputs(buff_ptr,fp2); - } - fclose(fp2); - fclose(fp1); + bool searchAndReplaceTextInFile(string fileName, string findText, string replaceText, bool simulateOnly) { + bool replacedText = false; + const int MAX_LEN_SINGLE_LINE = 4096; + char buffer[MAX_LEN_SINGLE_LINE + 2]; + char *buff_ptr, *find_ptr; + FILE *fp1, *fp2; + size_t find_len = findText.length(); - if(replacedText == true && simulateOnly == false) { - removeFile(fileName); - renameFile(tempfileName,fileName); - } - else { - removeFile(tempfileName); - } - //removeFile(tempfileName); - return replacedText; -} - -void saveDataToFile(string filename, const string &data) { - //Open an input and output stream in binary mode -#if defined(WIN32) && !defined(__MINGW32__) - FILE *fp2 = _wfopen(utf8_decode(filename).c_str(), L"wb"); - ofstream out(fp2); -#else - ofstream out(filename.c_str(),ios::binary); -#endif - - if(out.is_open()) { - out<< data; - } - else if(out.is_open() == false) { - throw megaglest_runtime_error("cannot open input file [" + filename + "]"); - } - - //Close file - out.close(); - -#if defined(WIN32) && !defined(__MINGW32__) - if(fp2) { - fclose(fp2); - } -#endif -} - -void copyFileTo(string fromFileName, string toFileName) { - //Open an input and output stream in binary mode -#if defined(WIN32) && !defined(__MINGW32__) - FILE *fp1 = _wfopen(utf8_decode(fromFileName).c_str(), L"rb"); - ifstream in(fp1); - FILE *fp2 = _wfopen(utf8_decode(toFileName).c_str(), L"wb"); - ofstream out(fp2); -#else - ifstream in(fromFileName.c_str(),ios::binary); - ofstream out(toFileName.c_str(),ios::binary); -#endif - - if(in.is_open() && out.is_open()) { - while(in.eof() == false) { - out.put(in.get()); - } - } - else if(in.is_open() == false) { - throw megaglest_runtime_error("cannot open input file [" + fromFileName + "]"); - } - else if(out.is_open() == false) { - throw megaglest_runtime_error("cannot open input file [" + toFileName + "]"); - } - - //Close both files - in.close(); - out.close(); - -#if defined(WIN32) && !defined(__MINGW32__) - if(fp1) { - fclose(fp1); - } - if(fp2) { - fclose(fp2); - } -#endif -} - -bool valid_utf8_file(const char* file_name) { -#if defined(WIN32) && !defined(__MINGW32__) - wstring wstr = utf8_decode(file_name); - FILE *fp = _wfopen(wstr.c_str(), L"r"); - ifstream ifs(fp); -#else - ifstream ifs(file_name); -#endif - - if (!ifs) { - return false; // even better, throw here - } - istreambuf_iterator it(ifs.rdbuf()); - istreambuf_iterator eos; - - bool result = utf8::is_valid(it, eos); - - ifs.close(); -#if defined(WIN32) && !defined(__MINGW32__) - if(fp) { - fclose(fp); - } -#endif - - return result; -} - -//string getFileTextContents(string path) { -//#if defined(WIN32) && !defined(__MINGW32__) -// FILE *fp = _wfopen(utf8_decode(path).c_str(), L"rb"); -// ifstream xmlFile(fp); -//#else -// ifstream xmlFile(path.c_str(),ios::binary); -//#endif -// if(xmlFile.is_open() == false) { -// throw megaglest_runtime_error("Can not open file: [" + path + "]"); -// } -// -// xmlFile.unsetf(ios::skipws); -// -// // Determine stream size -// xmlFile.seekg(0, ios::end); -// streampos size = xmlFile.tellg(); -// xmlFile.seekg(0); -// -// // Load data and add terminating 0 -// vector buffer; -// buffer.resize((unsigned int)size + 1); -// xmlFile.read(&buffer.front(), static_cast(size)); -// buffer[(unsigned int)size] = 0; -// -// return &buffer.front(); -//} - -// ===================================== -// ModeInfo -// ===================================== - -ModeInfo::ModeInfo(int w, int h, int d) { - width=w; - height=h; - depth=d; -} - -string ModeInfo::getString() const{ - return intToStr(width)+"x"+intToStr(height)+"-"+intToStr(depth); -} - -void ValueCheckerVault::addItemToVault(const void *ptr,int value) { -#ifndef _DISABLE_MEMORY_VAULT_CHECKS - - Checksum checksum; - vaultList[ptr] = checksum.addInt(value); - -#endif - -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] add vault key [%p] value [%s] [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,intToStr(checksum.getSum()).c_str(),value); -} - -void ValueCheckerVault::checkItemInVault(const void *ptr,int value) const { -#ifndef _DISABLE_MEMORY_VAULT_CHECKS - - map::const_iterator iterFind = vaultList.find(ptr); - if(iterFind == vaultList.end()) { -// if(SystemFlags::VERBOSE_MODE_ENABLED) { -// printf("In [%s::%s Line: %d] check vault key [%p] value [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,value); -// for(map::const_iterator iterFind = vaultList.begin(); -// iterFind != vaultList.end(); iterFind++) { -// printf("In [%s::%s Line: %d] LIST-- check vault key [%p] value [%s]\n",__FILE__,__FUNCTION__,__LINE__,iterFind->first,iterFind->second.c_str()); -// } -// } - throw std::runtime_error("memory value has been unexpectedly modified (not found)!"); - } - Checksum checksum; - if(iterFind->second != checksum.addInt(value)) { -// if(SystemFlags::VERBOSE_MODE_ENABLED) { -// printf("In [%s::%s Line: %d] check vault key [%p] value [%s] [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,intToStr(checksum.getSum()).c_str(),value); -// for(map::const_iterator iterFind = vaultList.begin(); -// iterFind != vaultList.end(); iterFind++) { -// printf("In [%s::%s Line: %d] LIST-- check vault key [%p] value [%s]\n",__FILE__,__FUNCTION__,__LINE__,iterFind->first,iterFind->second.c_str()); -// } -// } - throw std::runtime_error("memory value has been unexpectedly modified (changed)!"); - } - -#endif - -} - -string getUserHome() { - string home_folder; - home_folder = safeCharPtrCopy(getenv("HOME"),8095); - if(home_folder == "") { -#if _BSD_SOURCE || _SVID_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED - struct passwd *pw = getpwuid(getuid()); - home_folder = safeCharPtrCopy(pw->pw_dir,8095); -#endif - } - return home_folder; -} - -string safeCharPtrCopy(const char *ptr,int maxLength) { - string result = ""; - if(ptr == NULL) { - return result; - } - if(maxLength <= 0) { - maxLength = 8096; - } - - int ptrLength = (int)strlen(ptr); - if(ptrLength >= maxLength) { - char *pBuffer = new char[maxLength+1]; - memset(pBuffer,0,maxLength+1); + string tempfileName = fileName + "_tmp"; #ifdef WIN32 - memcpy(pBuffer,ptr,min((int)strlen(ptr),maxLength)); + fp1 = _wfopen(utf8_decode(fileName).c_str(), L"r"); + fp2 = _wfopen(utf8_decode(tempfileName).c_str(), L"w"); #else - memcpy(pBuffer,ptr,std::min((int)strlen(ptr),maxLength)); + fp1 = fopen(fileName.c_str(), "r"); + fp2 = fopen(tempfileName.c_str(), "w"); #endif - result = pBuffer; - delete [] pBuffer; - } - else { - result = ptr; - } - return result; -} + if (fp1 == NULL) { + if (fp2) fclose(fp2); + + throw megaglest_runtime_error("cannot open input file [" + fileName + "]"); + } + if (fp2 == NULL) { + if (fp1) fclose(fp1); + + throw megaglest_runtime_error("cannot open output file [" + tempfileName + "]"); + } + + while (fgets(buffer, MAX_LEN_SINGLE_LINE + 2, fp1)) { + buff_ptr = buffer; + if (findText != "") { + while ((find_ptr = strstr(buff_ptr, findText.c_str()))) { + //printf("Replacing text [%s] with [%s] in file [%s]\n",findText.c_str(),replaceText.c_str(),fileName.c_str()); + + while (buff_ptr < find_ptr) { + fputc((int) *buff_ptr++, fp2); + } + fputs(replaceText.c_str(), fp2); + + buff_ptr += find_len; + replacedText = true; + } + } + fputs(buff_ptr, fp2); + } + + fclose(fp2); + fclose(fp1); + + if (replacedText == true && simulateOnly == false) { + removeFile(fileName); + renameFile(tempfileName, fileName); + } else { + removeFile(tempfileName); + } + //removeFile(tempfileName); + return replacedText; + } + + void saveDataToFile(string filename, const string &data) { + //Open an input and output stream in binary mode +#if defined(WIN32) && !defined(__MINGW32__) + FILE *fp2 = _wfopen(utf8_decode(filename).c_str(), L"wb"); + ofstream out(fp2); +#else + ofstream out(filename.c_str(), ios::binary); +#endif + + if (out.is_open()) { + out << data; + } else if (out.is_open() == false) { + throw megaglest_runtime_error("cannot open input file [" + filename + "]"); + } + + //Close file + out.close(); + +#if defined(WIN32) && !defined(__MINGW32__) + if (fp2) { + fclose(fp2); + } +#endif + } + + void copyFileTo(string fromFileName, string toFileName) { + //Open an input and output stream in binary mode +#if defined(WIN32) && !defined(__MINGW32__) + FILE *fp1 = _wfopen(utf8_decode(fromFileName).c_str(), L"rb"); + ifstream in(fp1); + FILE *fp2 = _wfopen(utf8_decode(toFileName).c_str(), L"wb"); + ofstream out(fp2); +#else + ifstream in(fromFileName.c_str(), ios::binary); + ofstream out(toFileName.c_str(), ios::binary); +#endif + + if (in.is_open() && out.is_open()) { + while (in.eof() == false) { + out.put(in.get()); + } + } else if (in.is_open() == false) { + throw megaglest_runtime_error("cannot open input file [" + fromFileName + "]"); + } else if (out.is_open() == false) { + throw megaglest_runtime_error("cannot open input file [" + toFileName + "]"); + } + + //Close both files + in.close(); + out.close(); + +#if defined(WIN32) && !defined(__MINGW32__) + if (fp1) { + fclose(fp1); + } + if (fp2) { + fclose(fp2); + } +#endif + } + + bool valid_utf8_file(const char* file_name) { +#if defined(WIN32) && !defined(__MINGW32__) + wstring wstr = utf8_decode(file_name); + FILE *fp = _wfopen(wstr.c_str(), L"r"); + ifstream ifs(fp); +#else + ifstream ifs(file_name); +#endif + + if (!ifs) { + return false; // even better, throw here + } + istreambuf_iterator it(ifs.rdbuf()); + istreambuf_iterator eos; + + bool result = utf8::is_valid(it, eos); + + ifs.close(); +#if defined(WIN32) && !defined(__MINGW32__) + if (fp) { + fclose(fp); + } +#endif + + return result; + } + + //string getFileTextContents(string path) { + //#if defined(WIN32) && !defined(__MINGW32__) + // FILE *fp = _wfopen(utf8_decode(path).c_str(), L"rb"); + // ifstream xmlFile(fp); + //#else + // ifstream xmlFile(path.c_str(),ios::binary); + //#endif + // if(xmlFile.is_open() == false) { + // throw megaglest_runtime_error("Can not open file: [" + path + "]"); + // } + // + // xmlFile.unsetf(ios::skipws); + // + // // Determine stream size + // xmlFile.seekg(0, ios::end); + // streampos size = xmlFile.tellg(); + // xmlFile.seekg(0); + // + // // Load data and add terminating 0 + // vector buffer; + // buffer.resize((unsigned int)size + 1); + // xmlFile.read(&buffer.front(), static_cast(size)); + // buffer[(unsigned int)size] = 0; + // + // return &buffer.front(); + //} + + // ===================================== + // ModeInfo + // ===================================== + + ModeInfo::ModeInfo(int w, int h, int d) { + width = w; + height = h; + depth = d; + } + + string ModeInfo::getString() const { + return intToStr(width) + "x" + intToStr(height) + "-" + intToStr(depth); + } + + void ValueCheckerVault::addItemToVault(const void *ptr, int value) { +#ifndef _DISABLE_MEMORY_VAULT_CHECKS + + Checksum checksum; + vaultList[ptr] = checksum.addInt(value); + +#endif + + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] add vault key [%p] value [%s] [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,intToStr(checksum.getSum()).c_str(),value); + } + + void ValueCheckerVault::checkItemInVault(const void *ptr, int value) const { +#ifndef _DISABLE_MEMORY_VAULT_CHECKS + + map::const_iterator iterFind = vaultList.find(ptr); + if (iterFind == vaultList.end()) { + // if(SystemFlags::VERBOSE_MODE_ENABLED) { + // printf("In [%s::%s Line: %d] check vault key [%p] value [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,value); + // for(map::const_iterator iterFind = vaultList.begin(); + // iterFind != vaultList.end(); iterFind++) { + // printf("In [%s::%s Line: %d] LIST-- check vault key [%p] value [%s]\n",__FILE__,__FUNCTION__,__LINE__,iterFind->first,iterFind->second.c_str()); + // } + // } + throw std::runtime_error("memory value has been unexpectedly modified (not found)!"); + } + Checksum checksum; + if (iterFind->second != checksum.addInt(value)) { + // if(SystemFlags::VERBOSE_MODE_ENABLED) { + // printf("In [%s::%s Line: %d] check vault key [%p] value [%s] [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,intToStr(checksum.getSum()).c_str(),value); + // for(map::const_iterator iterFind = vaultList.begin(); + // iterFind != vaultList.end(); iterFind++) { + // printf("In [%s::%s Line: %d] LIST-- check vault key [%p] value [%s]\n",__FILE__,__FUNCTION__,__LINE__,iterFind->first,iterFind->second.c_str()); + // } + // } + throw std::runtime_error("memory value has been unexpectedly modified (changed)!"); + } + +#endif + + } + + string getUserHome() { + string home_folder; + home_folder = safeCharPtrCopy(getenv("HOME"), 8095); + if (home_folder == "") { +#if _BSD_SOURCE || _SVID_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED + struct passwd *pw = getpwuid(getuid()); + home_folder = safeCharPtrCopy(pw->pw_dir, 8095); +#endif + } + return home_folder; + } + + string safeCharPtrCopy(const char *ptr, int maxLength) { + string result = ""; + if (ptr == NULL) { + return result; + } + if (maxLength <= 0) { + maxLength = 8096; + } + + int ptrLength = (int) strlen(ptr); + if (ptrLength >= maxLength) { + char *pBuffer = new char[maxLength + 1]; + memset(pBuffer, 0, maxLength + 1); +#ifdef WIN32 + memcpy(pBuffer, ptr, min((int) strlen(ptr), maxLength)); +#else + memcpy(pBuffer, ptr, std::min((int) strlen(ptr), maxLength)); +#endif + + result = pBuffer; + delete[] pBuffer; + } else { + result = ptr; + } + return result; + } -}}//end namespace + } + }//end namespace diff --git a/source/shared_lib/sources/platform/common/simple_threads.cpp b/source/shared_lib/sources/platform/common/simple_threads.cpp index c9290448f..69f63dfff 100644 --- a/source/shared_lib/sources/platform/common/simple_threads.cpp +++ b/source/shared_lib/sources/platform/common/simple_threads.cpp @@ -23,769 +23,753 @@ using namespace std; using namespace Shared::Util; using namespace Shared::PlatformCommon; -namespace Shared { namespace PlatformCommon { +namespace Shared { + namespace PlatformCommon { -const static int MAX_FileCRCPreCacheThread_WORKER_THREADS = 3; -const static double PAUSE_SECONDS_BETWEEN_WORKERS = 15; -string FileCRCPreCacheThread::preCacheThreadCacheLookupKey = ""; + const static int MAX_FileCRCPreCacheThread_WORKER_THREADS = 3; + const static double PAUSE_SECONDS_BETWEEN_WORKERS = 15; + string FileCRCPreCacheThread::preCacheThreadCacheLookupKey = ""; -FileCRCPreCacheThread::FileCRCPreCacheThread() : BaseThread(), - mutexPauseForGame(new Mutex(CODE_AT_LINE)) { - - techDataPaths.clear(); - workerThreadTechPaths.clear(); - preCacheWorkerThreadList.clear(); - processTechCB = NULL; - pauseForGame = false; - uniqueID = "FileCRCPreCacheThread"; -} - -FileCRCPreCacheThread::FileCRCPreCacheThread(vector techDataPaths, - vector workerThreadTechPaths, - FileCRCPreCacheThreadCallbackInterface *processTechCB) : + FileCRCPreCacheThread::FileCRCPreCacheThread() : BaseThread(), mutexPauseForGame(new Mutex(CODE_AT_LINE)) { - this->techDataPaths = techDataPaths; - this->workerThreadTechPaths = workerThreadTechPaths; - preCacheWorkerThreadList.clear(); - this->processTechCB = processTechCB; - pauseForGame = false; - uniqueID = "FileCRCPreCacheThread"; -} - -FileCRCPreCacheThread::~FileCRCPreCacheThread() { - bool threadControllerMode = (workerThreadTechPaths.size() == 0); - FileCRCPreCacheThread * &preCacheCRCThreadPtr = CacheManager::getCachedItem< FileCRCPreCacheThread * >(preCacheThreadCacheLookupKey); - if(preCacheCRCThreadPtr != NULL && threadControllerMode == true) { - preCacheCRCThreadPtr = NULL; - } - - delete mutexPauseForGame; - mutexPauseForGame = NULL; -} - -void FileCRCPreCacheThread::setPauseForGame(bool pauseForGame) { - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexPauseForGame,mutexOwnerId); - this->pauseForGame = pauseForGame; - - for(unsigned int index = 0; index < preCacheWorkerThreadList.size(); ++index) { - FileCRCPreCacheThread *worker = preCacheWorkerThreadList[index]; - if(worker != NULL) { - worker->setPauseForGame(this->pauseForGame); + techDataPaths.clear(); + workerThreadTechPaths.clear(); + preCacheWorkerThreadList.clear(); + processTechCB = NULL; + pauseForGame = false; + uniqueID = "FileCRCPreCacheThread"; } - } -} -bool FileCRCPreCacheThread::getPauseForGame() { - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexPauseForGame,mutexOwnerId); - return this->pauseForGame; -} + FileCRCPreCacheThread::FileCRCPreCacheThread(vector techDataPaths, + vector workerThreadTechPaths, + FileCRCPreCacheThreadCallbackInterface *processTechCB) : + mutexPauseForGame(new Mutex(CODE_AT_LINE)) { -bool FileCRCPreCacheThread::canShutdown(bool deleteSelfIfShutdownDelayed) { - bool ret = (getExecutingTask() == false); - if(ret == false && deleteSelfIfShutdownDelayed == true) { - setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed); - deleteSelfIfRequired(); - signalQuit(); - } + this->techDataPaths = techDataPaths; + this->workerThreadTechPaths = workerThreadTechPaths; + preCacheWorkerThreadList.clear(); + this->processTechCB = processTechCB; + pauseForGame = false; + uniqueID = "FileCRCPreCacheThread"; + } - return ret; -} + FileCRCPreCacheThread::~FileCRCPreCacheThread() { + bool threadControllerMode = (workerThreadTechPaths.size() == 0); + FileCRCPreCacheThread * &preCacheCRCThreadPtr = CacheManager::getCachedItem< FileCRCPreCacheThread * >(preCacheThreadCacheLookupKey); + if (preCacheCRCThreadPtr != NULL && threadControllerMode == true) { + preCacheCRCThreadPtr = NULL; + } -void FileCRCPreCacheThread::execute() { - { - RunningStatusSafeWrapper runningStatus(this); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + delete mutexPauseForGame; + mutexPauseForGame = NULL; + } - if(getQuitStatus() == true) { - deleteSelfIfRequired(); - return; - } + void FileCRCPreCacheThread::setPauseForGame(bool pauseForGame) { + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexPauseForGame, mutexOwnerId); + this->pauseForGame = pauseForGame; - bool threadControllerMode = (workerThreadTechPaths.size() == 0); + for (unsigned int index = 0; index < preCacheWorkerThreadList.size(); ++index) { + FileCRCPreCacheThread *worker = preCacheWorkerThreadList[index]; + if (worker != NULL) { + worker->setPauseForGame(this->pauseForGame); + } + } + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("FILE CRC PreCache thread is running threadControllerMode = %d\n",threadControllerMode); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"FILE CRC PreCache thread is running threadControllerMode = %d\n",threadControllerMode); + bool FileCRCPreCacheThread::getPauseForGame() { + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexPauseForGame, mutexOwnerId); + return this->pauseForGame; + } - try { - if(threadControllerMode == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("********************** CRC Controller thread START **********************\n"); - time_t elapsedTime = time(NULL); + bool FileCRCPreCacheThread::canShutdown(bool deleteSelfIfShutdownDelayed) { + bool ret = (getExecutingTask() == false); + if (ret == false && deleteSelfIfShutdownDelayed == true) { + setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed); + deleteSelfIfRequired(); + signalQuit(); + } - Checksum::clearFileCache(); + return ret; + } - vector techPaths; - findDirs(techDataPaths, techPaths); - if(techPaths.empty() == false) { - // Always calc megapack first so its up to date sooner - const string megapackTechtreeName = "megapack"; - vector::iterator iterFindMegaPack = std::find(techPaths.begin(),techPaths.end(),megapackTechtreeName); - if(iterFindMegaPack != techPaths.end()) { - techPaths.erase(iterFindMegaPack); - techPaths.insert(techPaths.begin(),megapackTechtreeName); + void FileCRCPreCacheThread::execute() { + { + RunningStatusSafeWrapper runningStatus(this); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Found megapack techtree and placing it at the TOP of the list\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - unsigned int techsPerWorker = ((unsigned int)techPaths.size() / (unsigned int)MAX_FileCRCPreCacheThread_WORKER_THREADS); - if(techPaths.size() % MAX_FileCRCPreCacheThread_WORKER_THREADS != 0) { - techsPerWorker++; - } + if (getQuitStatus() == true) { + deleteSelfIfRequired(); + return; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] techsPerWorker = %u, MAX_FileCRCPreCacheThread_WORKER_THREADS = %d, techPaths.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,techsPerWorker,MAX_FileCRCPreCacheThread_WORKER_THREADS,(int)techPaths.size()); + bool threadControllerMode = (workerThreadTechPaths.size() == 0); - try { - unsigned int consumedWorkers = 0; - for(unsigned int workerIdx = 0; workerIdx < (unsigned int)MAX_FileCRCPreCacheThread_WORKER_THREADS; ++workerIdx) { - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - break; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("FILE CRC PreCache thread is running threadControllerMode = %d\n", threadControllerMode); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "FILE CRC PreCache thread is running threadControllerMode = %d\n", threadControllerMode); + + try { + if (threadControllerMode == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("********************** CRC Controller thread START **********************\n"); + time_t elapsedTime = time(NULL); + + Checksum::clearFileCache(); + + vector techPaths; + findDirs(techDataPaths, techPaths); + if (techPaths.empty() == false) { + // Always calc megapack first so its up to date sooner + const string megapackTechtreeName = "megapack"; + vector::iterator iterFindMegaPack = std::find(techPaths.begin(), techPaths.end(), megapackTechtreeName); + if (iterFindMegaPack != techPaths.end()) { + techPaths.erase(iterFindMegaPack); + techPaths.insert(techPaths.begin(), megapackTechtreeName); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Found megapack techtree and placing it at the TOP of the list\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + unsigned int techsPerWorker = ((unsigned int) techPaths.size() / (unsigned int) MAX_FileCRCPreCacheThread_WORKER_THREADS); + if (techPaths.size() % MAX_FileCRCPreCacheThread_WORKER_THREADS != 0) { + techsPerWorker++; } - unsigned int currentWorkerMax = ((unsigned int)techPaths.size() - consumedWorkers); - if(currentWorkerMax > techsPerWorker) { - currentWorkerMax = techsPerWorker; - } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] techsPerWorker = %u, MAX_FileCRCPreCacheThread_WORKER_THREADS = %d, techPaths.size() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, techsPerWorker, MAX_FileCRCPreCacheThread_WORKER_THREADS, (int) techPaths.size()); - vector workerTechList; - unsigned int endConsumerIndex = consumedWorkers + currentWorkerMax; - for(unsigned int idx = consumedWorkers; idx < endConsumerIndex; idx++) { - string techName = techPaths[idx]; - workerTechList.push_back(techName); + try { + unsigned int consumedWorkers = 0; + for (unsigned int workerIdx = 0; workerIdx < (unsigned int) MAX_FileCRCPreCacheThread_WORKER_THREADS; ++workerIdx) { + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + break; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Spawning CRC thread for Tech [%s] [%u of %lu]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,techName.c_str(),idx+1,techPaths.size()); - } + unsigned int currentWorkerMax = ((unsigned int) techPaths.size() - consumedWorkers); + if (currentWorkerMax > techsPerWorker) { + currentWorkerMax = techsPerWorker; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] workerIdx = %u, currentWorkerMax = %u, endConsumerIndex = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,workerIdx,currentWorkerMax,endConsumerIndex); + vector workerTechList; + unsigned int endConsumerIndex = consumedWorkers + currentWorkerMax; + for (unsigned int idx = consumedWorkers; idx < endConsumerIndex; idx++) { + string techName = techPaths[idx]; + workerTechList.push_back(techName); - // Pause before launching this worker thread - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("About to process CRC for factions waiting...\n"); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Spawning CRC thread for Tech [%s] [%u of %lu]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, techName.c_str(), idx + 1, techPaths.size()); + } - time_t pauseTime = time(NULL); - while(getQuitStatus() == false && - difftime(time(NULL),pauseTime) <= PAUSE_SECONDS_BETWEEN_WORKERS) { - sleep(25); - } - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - break; - } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] workerIdx = %u, currentWorkerMax = %u, endConsumerIndex = %u\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, workerIdx, currentWorkerMax, endConsumerIndex); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Starting CRC for faction workers...\n"); + // Pause before launching this worker thread + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("About to process CRC for factions waiting...\n"); - FileCRCPreCacheThread *workerThread = - new FileCRCPreCacheThread(techDataPaths, + time_t pauseTime = time(NULL); + while (getQuitStatus() == false && + difftime(time(NULL), pauseTime) <= PAUSE_SECONDS_BETWEEN_WORKERS) { + sleep(25); + } + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + break; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Starting CRC for faction workers...\n"); + + FileCRCPreCacheThread *workerThread = + new FileCRCPreCacheThread(techDataPaths, workerTechList, this->processTechCB); - static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); - workerThread->setUniqueID(mutexOwnerId); - workerThread->setPauseForGame(this->getPauseForGame()); - static string mutexOwnerId2 = CODE_AT_LINE; - MutexSafeWrapper safeMutexPause(mutexPauseForGame,mutexOwnerId2); - preCacheWorkerThreadList.push_back(workerThread); - safeMutexPause.ReleaseLock(); + static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); + workerThread->setUniqueID(mutexOwnerId); + workerThread->setPauseForGame(this->getPauseForGame()); + static string mutexOwnerId2 = CODE_AT_LINE; + MutexSafeWrapper safeMutexPause(mutexPauseForGame, mutexOwnerId2); + preCacheWorkerThreadList.push_back(workerThread); + safeMutexPause.ReleaseLock(); - workerThread->start(); + workerThread->start(); - consumedWorkers += currentWorkerMax; + consumedWorkers += currentWorkerMax; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Spawning CRC thread, preCacheWorkerThreadList.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(int)preCacheWorkerThreadList.size()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Spawning CRC thread, preCacheWorkerThreadList.size() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, (int) preCacheWorkerThreadList.size()); - if(consumedWorkers >= techPaths.size()) { - break; + if (consumedWorkers >= techPaths.size()) { + break; + } + } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + } catch (...) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] UNKNOWN Error\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] unknown error\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); } - } - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - } - catch(...) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] UNKNOWN Error\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unknown error\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - sleep(0); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Waiting for Spawned CRC threads to complete, preCacheWorkerThreadList.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(int)preCacheWorkerThreadList.size()); + sleep(0); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Waiting for Spawned CRC threads to complete, preCacheWorkerThreadList.size() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, (int) preCacheWorkerThreadList.size()); - try { - bool hasRunningWorkerThread = true; - for(;hasRunningWorkerThread == true;) { - hasRunningWorkerThread = false; - for(unsigned int idx = 0; idx < preCacheWorkerThreadList.size(); idx++) { - FileCRCPreCacheThread *workerThread = preCacheWorkerThreadList[idx]; + try { + bool hasRunningWorkerThread = true; + for (; hasRunningWorkerThread == true;) { + hasRunningWorkerThread = false; + for (unsigned int idx = 0; idx < preCacheWorkerThreadList.size(); idx++) { + FileCRCPreCacheThread *workerThread = preCacheWorkerThreadList[idx]; - if(workerThread != NULL) { + if (workerThread != NULL) { - if(workerThread->getRunningStatus() == true) { - hasRunningWorkerThread = true; - if(getQuitStatus() == true && - workerThread->getQuitStatus() == false) { - workerThread->signalQuit(); + if (workerThread->getRunningStatus() == true) { + hasRunningWorkerThread = true; + if (getQuitStatus() == true && + workerThread->getQuitStatus() == false) { + workerThread->signalQuit(); + } + } else if (workerThread->getRunningStatus() == false) { + sleep(25); + + static string mutexOwnerId2 = CODE_AT_LINE; + MutexSafeWrapper safeMutexPause(mutexPauseForGame, mutexOwnerId2); + + delete workerThread; + preCacheWorkerThreadList[idx] = NULL; + + safeMutexPause.ReleaseLock(); + } } } - else if(workerThread->getRunningStatus() == false) { + + if (getQuitStatus() == false && + hasRunningWorkerThread == true) { sleep(25); - - static string mutexOwnerId2 = CODE_AT_LINE; - MutexSafeWrapper safeMutexPause(mutexPauseForGame,mutexOwnerId2); - - delete workerThread; - preCacheWorkerThreadList[idx] = NULL; - - safeMutexPause.ReleaseLock(); + } else if (getQuitStatus() == true) { + for (unsigned int idx = 0; idx < preCacheWorkerThreadList.size(); idx++) { + FileCRCPreCacheThread *workerThread = preCacheWorkerThreadList[idx]; + if (workerThread != NULL && workerThread->getQuitStatus() == false) { + workerThread->signalQuit(); + } + } } } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + } catch (...) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] UNKNOWN Error\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] unknown error\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); } - if( getQuitStatus() == false && - hasRunningWorkerThread == true) { - sleep(25); - } - else if(getQuitStatus() == true) { - for(unsigned int idx = 0; idx < preCacheWorkerThreadList.size(); idx++) { - FileCRCPreCacheThread *workerThread = preCacheWorkerThreadList[idx]; - if(workerThread != NULL && workerThread->getQuitStatus() == false) { - workerThread->signalQuit(); - } - } - } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("********************** CRC Controller thread took %.2f seconds END **********************\n", difftime(time(NULL), elapsedTime)); } - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - } - catch(...) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] UNKNOWN Error\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unknown error\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } + } else { + try { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\tStarting CRC for faction worker thread for techs: %d...\n", (int) workerThreadTechPaths.size()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("********************** CRC Controller thread took %.2f seconds END **********************\n",difftime(time(NULL),elapsedTime)); - } - } - else { - try { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\tStarting CRC for faction worker thread for techs: %d...\n",(int)workerThreadTechPaths.size()); - - for(unsigned int idx = 0; idx < workerThreadTechPaths.size(); idx++) { - string techName = this->workerThreadTechPaths[idx]; - if(getQuitStatus() == true) { - break; - } - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("--------------------- CRC worker thread START for tech [%s] ---------------------------\n",techName.c_str()); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] caching CRC value for Tech [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,techName.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] caching CRC value for Tech [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,techName.c_str()); - - time_t elapsedTime = time(NULL); - // Clear existing CRC to force a CRC refresh - //string pathSearchString = string("/") + techName + string("/*"); - //const string filterFileExt = ".xml"; - //clearFolderTreeContentsCheckSum(techDataPaths, pathSearchString, filterFileExt); - //clearFolderTreeContentsCheckSumList(techDataPaths, pathSearchString, filterFileExt); - - if(getQuitStatus() == true) { - break; - } - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("--------------------- CRC worker thread running for tech [%s] ---------------------------\n",techName.c_str()); - if(getQuitStatus() == false) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\tAbout to process CRC for techName [%s]\n",techName.c_str()); - - // Do not process CRC's while game in progress - if(getPauseForGame() == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\tGame in progress so waiting to process CRC for techName [%s]\n",techName.c_str()); - for(;getPauseForGame() == true && - getQuitStatus() == false;) { - sleep(25); - } - if(getQuitStatus() == true) { + for (unsigned int idx = 0; idx < workerThreadTechPaths.size(); idx++) { + string techName = this->workerThreadTechPaths[idx]; + if (getQuitStatus() == true) { break; } - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\tStart Processing CRC for techName [%s]\n",techName.c_str()); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("--------------------- CRC worker thread START for tech [%s] ---------------------------\n",techName.c_str()); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] caching CRC value for Tech [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,techName.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] caching CRC value for Tech [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, techName.c_str()); - uint32 techCRC = getFolderTreeContentsCheckSumRecursively(techDataPaths, string("/") + techName + string("/*"), ".xml", NULL, true); + time_t elapsedTime = time(NULL); + // Clear existing CRC to force a CRC refresh + //string pathSearchString = string("/") + techName + string("/*"); + //const string filterFileExt = ".xml"; + //clearFolderTreeContentsCheckSum(techDataPaths, pathSearchString, filterFileExt); + //clearFolderTreeContentsCheckSumList(techDataPaths, pathSearchString, filterFileExt); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] cached CRC value for Tech [%s] is [%d] took %.3f seconds.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,techName.c_str(),techCRC,difftime(time(NULL),elapsedTime)); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] cached CRC value for Tech [%s] is [%u] took %.3f seconds.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,techName.c_str(),techCRC,difftime(time(NULL),elapsedTime)); - - vector results; - for(unsigned int idx = 0; idx < techDataPaths.size(); idx++) { - string &techPath = techDataPaths[idx]; - endPathWithSlash(techPath); - findAll(techPath + techName + "/factions/*.", results, false, false); - if(results.empty() == false) { + if (getQuitStatus() == true) { break; } - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\tStarting CRC for faction worker thread for results: %d...\n",(int)results.size()); - if(results.empty() == true) { - for(unsigned int factionIdx = 0; - factionIdx < results.size(); - ++factionIdx) { - string factionName = results[factionIdx]; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\t\tAbout to process CRC for factionName [%s]\n",factionName.c_str()); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("--------------------- CRC worker thread running for tech [%s] ---------------------------\n",techName.c_str()); + if (getQuitStatus() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\tAbout to process CRC for techName [%s]\n", techName.c_str()); // Do not process CRC's while game in progress - if(getPauseForGame() == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\t\tGame in progress so waiting to process CRC for factionName [%s]\n",factionName.c_str()); - for(;getPauseForGame() == true && - getQuitStatus() == false;) { + if (getPauseForGame() == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\tGame in progress so waiting to process CRC for techName [%s]\n", techName.c_str()); + for (; getPauseForGame() == true && + getQuitStatus() == false;) { sleep(25); } - if(getQuitStatus() == true) { + if (getQuitStatus() == true) { break; } } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\t\tStart Processing CRC for factionName [%s]\n",factionName.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\tStart Processing CRC for techName [%s]\n", techName.c_str()); - uint32 factionCRC = getFolderTreeContentsCheckSumRecursively(techDataPaths, "/" + techName + "/factions/" + factionName + "/*", ".xml", NULL, true); + uint32 techCRC = getFolderTreeContentsCheckSumRecursively(techDataPaths, string("/") + techName + string("/*"), ".xml", NULL, true); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\t\tDone Processing CRC for factionName [%s] CRC [%d]\n",factionName.c_str(),factionCRC); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] cached CRC value for Tech [%s] is [%d] took %.3f seconds.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,techName.c_str(),techCRC,difftime(time(NULL),elapsedTime)); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] cached CRC value for Tech [%s] is [%u] took %.3f seconds.\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, techName.c_str(), techCRC, difftime(time(NULL), elapsedTime)); + + vector results; + for (unsigned int idx = 0; idx < techDataPaths.size(); idx++) { + string &techPath = techDataPaths[idx]; + endPathWithSlash(techPath); + findAll(techPath + techName + "/factions/*.", results, false, false); + if (results.empty() == false) { + break; + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\tStarting CRC for faction worker thread for results: %d...\n", (int) results.size()); + if (results.empty() == true) { + for (unsigned int factionIdx = 0; + factionIdx < results.size(); + ++factionIdx) { + string factionName = results[factionIdx]; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\t\tAbout to process CRC for factionName [%s]\n", factionName.c_str()); + + // Do not process CRC's while game in progress + if (getPauseForGame() == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\t\tGame in progress so waiting to process CRC for factionName [%s]\n", factionName.c_str()); + for (; getPauseForGame() == true && + getQuitStatus() == false;) { + sleep(25); + } + if (getQuitStatus() == true) { + break; + } + } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\t\tStart Processing CRC for factionName [%s]\n", factionName.c_str()); + + uint32 factionCRC = getFolderTreeContentsCheckSumRecursively(techDataPaths, "/" + techName + "/factions/" + factionName + "/*", ".xml", NULL, true); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\t\t\tDone Processing CRC for factionName [%s] CRC [%d]\n", factionName.c_str(), factionCRC); + } + } + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] cached CRC value for Tech [%s] is [%d] took %.3f seconds.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,techName.c_str(),techCRC,difftime(time(NULL),elapsedTime)); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] cached CRC value for Tech [%s] is [%d] took %.3f seconds.\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, techName.c_str(), techCRC, difftime(time(NULL), elapsedTime)); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("--------------------- CRC worker thread END for tech [%s] ---------------------------\n", techName.c_str()); + + if (getQuitStatus() == true) { + break; + } + } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + } catch (...) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] UNKNOWN Error\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] unknown error\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + } catch (...) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] UNKNOWN Error\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] unknown error\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] FILE CRC PreCache thread is exiting...\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] FILE CRC PreCache thread is exiting...\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + deleteSelfIfRequired(); + } + + SimpleTaskThread::SimpleTaskThread(SimpleTaskCallbackInterface *simpleTaskInterface, + unsigned int executionCount, + unsigned int millisecsBetweenExecutions, + bool needTaskSignal, + void *userdata, bool wantSetupAndShutdown) : BaseThread(), + simpleTaskInterface(NULL), + overrideShutdownTask(NULL), + mutexSimpleTaskInterfaceValid(new Mutex(CODE_AT_LINE)), + mutexTaskSignaller(new Mutex(CODE_AT_LINE)), + mutexLastExecuteTimestamp(new Mutex(CODE_AT_LINE)) { + + uniqueID = "SimpleTaskThread"; + this->simpleTaskInterface = simpleTaskInterface; + this->simpleTaskInterfaceValid = (this->simpleTaskInterface != NULL); + this->executionCount = executionCount; + this->millisecsBetweenExecutions = millisecsBetweenExecutions; + this->needTaskSignal = needTaskSignal; + this->overrideShutdownTask = NULL; + this->userdata = userdata; + this->wantSetupAndShutdown = wantSetupAndShutdown; + //if(this->userdata != NULL) { + // printf("IN SImpleThread this->userdata [%p]\n",this->userdata); + //} + + setTaskSignalled(false); + + string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexLastExecuteTimestamp, mutexOwnerId); + mutexLastExecuteTimestamp->setOwnerId(mutexOwnerId); + lastExecuteTimestamp = time(NULL); + + if (this->wantSetupAndShutdown == true) { + string mutexOwnerId1 = CODE_AT_LINE; + MutexSafeWrapper safeMutex1(mutexSimpleTaskInterfaceValid, mutexOwnerId1); + if (this->simpleTaskInterfaceValid == true) { + safeMutex1.ReleaseLock(); + this->simpleTaskInterface->setupTask(this, userdata); + } + } + } + + SimpleTaskThread::~SimpleTaskThread() { + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + try { + cleanup(); + + delete mutexSimpleTaskInterfaceValid; + mutexSimpleTaskInterfaceValid = NULL; + + delete mutexTaskSignaller; + mutexTaskSignaller = NULL; + + delete mutexLastExecuteTimestamp; + mutexLastExecuteTimestamp = NULL; + + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, this->getUniqueID().c_str()); + + throw megaglest_runtime_error(ex.what()); + //abort(); + } + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + } + + void SimpleTaskThread::cleanup() { + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + if (this->wantSetupAndShutdown == true) { + if (this->overrideShutdownTask != NULL) { + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + this->overrideShutdownTask(this); + this->overrideShutdownTask = NULL; + } else if (this->simpleTaskInterface != NULL) { + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + string mutexOwnerId1 = CODE_AT_LINE; + MutexSafeWrapper safeMutex1(mutexSimpleTaskInterfaceValid, mutexOwnerId1); + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + if (this->simpleTaskInterfaceValid == true) { + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + safeMutex1.ReleaseLock(); + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + this->simpleTaskInterface->shutdownTask(this, userdata); + this->simpleTaskInterface = NULL; + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + } + } + } + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + } + + void SimpleTaskThread::setOverrideShutdownTask(taskFunctionCallback *ptr) { + this->overrideShutdownTask = ptr; + } + + bool SimpleTaskThread::isThreadExecutionLagging() { + string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexLastExecuteTimestamp, mutexOwnerId); + mutexLastExecuteTimestamp->setOwnerId(mutexOwnerId); + bool result = (difftime(time(NULL), lastExecuteTimestamp) >= 5.0); + safeMutex.ReleaseLock(); + + return result; + } + + bool SimpleTaskThread::canShutdown(bool deleteSelfIfShutdownDelayed) { + bool ret = (getExecutingTask() == false); + if (ret == false && deleteSelfIfShutdownDelayed == true) { + setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed); + deleteSelfIfRequired(); + signalQuit(); + } + + return ret; + } + + bool SimpleTaskThread::getSimpleTaskInterfaceValid() { + string mutexOwnerId1 = CODE_AT_LINE; + MutexSafeWrapper safeMutex1(mutexSimpleTaskInterfaceValid, mutexOwnerId1); + + return this->simpleTaskInterfaceValid; + } + void SimpleTaskThread::setSimpleTaskInterfaceValid(bool value) { + string mutexOwnerId1 = CODE_AT_LINE; + MutexSafeWrapper safeMutex1(mutexSimpleTaskInterfaceValid, mutexOwnerId1); + + this->simpleTaskInterfaceValid = value; + } + + void SimpleTaskThread::execute() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + void *ptr_cpy = this->ptr; + bool mustDeleteSelf = false; + { + { + RunningStatusSafeWrapper runningStatus(this); + try { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (getQuitStatus() == true) { + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, this->getUniqueID().c_str()); + + unsigned int idx = 0; + for (; this->simpleTaskInterface != NULL;) { + string mutexOwnerId1 = CODE_AT_LINE; + MutexSafeWrapper safeMutex1(mutexSimpleTaskInterfaceValid, mutexOwnerId1); + if (this->simpleTaskInterfaceValid == false) { + break; + } + safeMutex1.ReleaseLock(); + + bool runTask = true; + if (needTaskSignal == true) { + runTask = getTaskSignalled(); + if (runTask == true) { + setTaskSignalled(false); } } - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] cached CRC value for Tech [%s] is [%d] took %.3f seconds.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,techName.c_str(),techCRC,difftime(time(NULL),elapsedTime)); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] cached CRC value for Tech [%s] is [%d] took %.3f seconds.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,techName.c_str(),techCRC,difftime(time(NULL),elapsedTime)); - } + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, this->getUniqueID().c_str()); + break; + } else if (runTask == true) { + if (getQuitStatus() == false) { + ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + this->simpleTaskInterface->simpleTask(this, this->userdata); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("--------------------- CRC worker thread END for tech [%s] ---------------------------\n",techName.c_str()); + if (getQuitStatus() == true) { + break; + } + string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexLastExecuteTimestamp, mutexOwnerId); + mutexLastExecuteTimestamp->setOwnerId(mutexOwnerId); + lastExecuteTimestamp = time(NULL); + safeMutex.ReleaseLock(); + } + } - if(getQuitStatus() == true) { - break; + if (this->executionCount > 0) { + idx++; + if (idx >= this->executionCount) { + break; + } + } + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, this->getUniqueID().c_str()); + break; + } + + sleep(this->millisecsBetweenExecutions); } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s] END\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, this->getUniqueID().c_str()); + mustDeleteSelf = getDeleteSelfOnExecutionDone(); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, this->getUniqueID().c_str()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] uniqueID [%s] END\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, this->getUniqueID().c_str()); + mustDeleteSelf = getDeleteSelfOnExecutionDone(); + + throw megaglest_runtime_error(ex.what()); } - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - } - catch(...) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] UNKNOWN Error\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unknown error\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - } - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - } - catch(...) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] UNKNOWN Error\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unknown error\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } + } + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] FILE CRC PreCache thread is exiting...\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] FILE CRC PreCache thread is exiting...\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - deleteSelfIfRequired(); -} - -SimpleTaskThread::SimpleTaskThread( SimpleTaskCallbackInterface *simpleTaskInterface, - unsigned int executionCount, - unsigned int millisecsBetweenExecutions, - bool needTaskSignal, - void *userdata, bool wantSetupAndShutdown) : BaseThread(), - simpleTaskInterface(NULL), - overrideShutdownTask(NULL), - mutexSimpleTaskInterfaceValid(new Mutex(CODE_AT_LINE)), - mutexTaskSignaller(new Mutex(CODE_AT_LINE)), - mutexLastExecuteTimestamp(new Mutex(CODE_AT_LINE)) { - - uniqueID = "SimpleTaskThread"; - this->simpleTaskInterface = simpleTaskInterface; - this->simpleTaskInterfaceValid = (this->simpleTaskInterface != NULL); - this->executionCount = executionCount; - this->millisecsBetweenExecutions = millisecsBetweenExecutions; - this->needTaskSignal = needTaskSignal; - this->overrideShutdownTask = NULL; - this->userdata = userdata; - this->wantSetupAndShutdown = wantSetupAndShutdown; - //if(this->userdata != NULL) { - // printf("IN SImpleThread this->userdata [%p]\n",this->userdata); - //} - - setTaskSignalled(false); - - string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexLastExecuteTimestamp,mutexOwnerId); - mutexLastExecuteTimestamp->setOwnerId(mutexOwnerId); - lastExecuteTimestamp = time(NULL); - - if(this->wantSetupAndShutdown == true) { - string mutexOwnerId1 = CODE_AT_LINE; - MutexSafeWrapper safeMutex1(mutexSimpleTaskInterfaceValid,mutexOwnerId1); - if(this->simpleTaskInterfaceValid == true) { - safeMutex1.ReleaseLock(); - this->simpleTaskInterface->setupTask(this,userdata); - } - } -} - -SimpleTaskThread::~SimpleTaskThread() { - //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); - try { - cleanup(); - - delete mutexSimpleTaskInterfaceValid; - mutexSimpleTaskInterfaceValid = NULL; - - delete mutexTaskSignaller; - mutexTaskSignaller = NULL; - - delete mutexLastExecuteTimestamp; - mutexLastExecuteTimestamp = NULL; - - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->getUniqueID().c_str()); - - throw megaglest_runtime_error(ex.what()); - //abort(); - } - //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); -} - -void SimpleTaskThread::cleanup() { - //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); - if(this->wantSetupAndShutdown == true) { - if(this->overrideShutdownTask != NULL) { - //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); - this->overrideShutdownTask(this); - this->overrideShutdownTask = NULL; - } - else if(this->simpleTaskInterface != NULL) { - //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); - string mutexOwnerId1 = CODE_AT_LINE; - MutexSafeWrapper safeMutex1(mutexSimpleTaskInterfaceValid,mutexOwnerId1); - //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); - if(this->simpleTaskInterfaceValid == true) { - //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); - safeMutex1.ReleaseLock(); - //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); - this->simpleTaskInterface->shutdownTask(this,userdata); - this->simpleTaskInterface = NULL; - //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (mustDeleteSelf == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (isThreadDeleted(ptr_cpy) == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + this->setDeleteAfterExecute(true); + } + return; } } - } - //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); -} -void SimpleTaskThread::setOverrideShutdownTask(taskFunctionCallback *ptr) { - this->overrideShutdownTask = ptr; -} - -bool SimpleTaskThread::isThreadExecutionLagging() { - string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexLastExecuteTimestamp,mutexOwnerId); - mutexLastExecuteTimestamp->setOwnerId(mutexOwnerId); - bool result = (difftime(time(NULL),lastExecuteTimestamp) >= 5.0); - safeMutex.ReleaseLock(); - - return result; -} - -bool SimpleTaskThread::canShutdown(bool deleteSelfIfShutdownDelayed) { - bool ret = (getExecutingTask() == false); - if(ret == false && deleteSelfIfShutdownDelayed == true) { - setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed); - deleteSelfIfRequired(); - signalQuit(); - } - - return ret; -} - -bool SimpleTaskThread::getSimpleTaskInterfaceValid() { - string mutexOwnerId1 = CODE_AT_LINE; - MutexSafeWrapper safeMutex1(mutexSimpleTaskInterfaceValid,mutexOwnerId1); - - return this->simpleTaskInterfaceValid; -} -void SimpleTaskThread::setSimpleTaskInterfaceValid(bool value) { - string mutexOwnerId1 = CODE_AT_LINE; - MutexSafeWrapper safeMutex1(mutexSimpleTaskInterfaceValid,mutexOwnerId1); - - this->simpleTaskInterfaceValid = value; -} - -void SimpleTaskThread::execute() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - void *ptr_cpy = this->ptr; - bool mustDeleteSelf = false; - { - { - RunningStatusSafeWrapper runningStatus(this); - try { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(getQuitStatus() == true) { - return; - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->getUniqueID().c_str()); - - unsigned int idx = 0; - for(;this->simpleTaskInterface != NULL;) { - string mutexOwnerId1 = CODE_AT_LINE; - MutexSafeWrapper safeMutex1(mutexSimpleTaskInterfaceValid,mutexOwnerId1); - if(this->simpleTaskInterfaceValid == false) { - break; - } - safeMutex1.ReleaseLock(); - - bool runTask = true; - if(needTaskSignal == true) { - runTask = getTaskSignalled(); - if(runTask == true) { - setTaskSignalled(false); - } - } - - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->getUniqueID().c_str()); - break; - } - else if(runTask == true) { - if(getQuitStatus() == false) { - ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - this->simpleTaskInterface->simpleTask(this,this->userdata); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(getQuitStatus() == true) { - break; - } - string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexLastExecuteTimestamp,mutexOwnerId); - mutexLastExecuteTimestamp->setOwnerId(mutexOwnerId); - lastExecuteTimestamp = time(NULL); - safeMutex.ReleaseLock(); - } - } - - if(this->executionCount > 0) { - idx++; - if(idx >= this->executionCount) { - break; - } - } - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->getUniqueID().c_str()); - break; - } - - sleep(this->millisecsBetweenExecutions); - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s] END\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->getUniqueID().c_str()); - mustDeleteSelf = getDeleteSelfOnExecutionDone(); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->getUniqueID().c_str()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s] END\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->getUniqueID().c_str()); - mustDeleteSelf = getDeleteSelfOnExecutionDone(); - - throw megaglest_runtime_error(ex.what()); - } - } - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(mustDeleteSelf == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(isThreadDeleted(ptr_cpy) == false) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - this->setDeleteAfterExecute(true); + void SimpleTaskThread::setTaskSignalled(bool value) { + string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexTaskSignaller, mutexOwnerId); + mutexTaskSignaller->setOwnerId(mutexOwnerId); + taskSignalled = value; + safeMutex.ReleaseLock(); } - return; - } -} -void SimpleTaskThread::setTaskSignalled(bool value) { - string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexTaskSignaller,mutexOwnerId); - mutexTaskSignaller->setOwnerId(mutexOwnerId); - taskSignalled = value; - safeMutex.ReleaseLock(); -} + bool SimpleTaskThread::getTaskSignalled() { + string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexTaskSignaller, mutexOwnerId); + mutexTaskSignaller->setOwnerId(mutexOwnerId); + bool retval = taskSignalled; + safeMutex.ReleaseLock(); -bool SimpleTaskThread::getTaskSignalled() { - string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexTaskSignaller,mutexOwnerId); - mutexTaskSignaller->setOwnerId(mutexOwnerId); - bool retval = taskSignalled; - safeMutex.ReleaseLock(); + return retval; + } - return retval; -} + // ------------------------------------------------- -// ------------------------------------------------- + LogFileThread::LogFileThread() : BaseThread(), mutexLogList(new Mutex(CODE_AT_LINE)) { + uniqueID = "LogFileThread"; + logList.clear(); + lastSaveToDisk = time(NULL); + static string mutexOwnerId = CODE_AT_LINE; + mutexLogList->setOwnerId(mutexOwnerId); + } -LogFileThread::LogFileThread() : BaseThread(), mutexLogList(new Mutex(CODE_AT_LINE)) { - uniqueID = "LogFileThread"; - logList.clear(); - lastSaveToDisk = time(NULL); - static string mutexOwnerId = CODE_AT_LINE; - mutexLogList->setOwnerId(mutexOwnerId); -} + LogFileThread::~LogFileThread() { -LogFileThread::~LogFileThread() { + delete mutexLogList; + mutexLogList = NULL; - delete mutexLogList; - mutexLogList = NULL; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 In [%s::%s Line: %d] LogFile thread is deleting\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("#1 In [%s::%s Line: %d] LogFile thread is deleting\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} + void LogFileThread::addLogEntry(SystemFlags::DebugType type, string logEntry) { + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexLogList, mutexOwnerId); + mutexLogList->setOwnerId(mutexOwnerId); + LogFileEntry entry; + entry.type = type; + entry.entry = logEntry; + entry.entryDateTime = time(NULL); + logList.push_back(entry); -void LogFileThread::addLogEntry(SystemFlags::DebugType type, string logEntry) { - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexLogList,mutexOwnerId); - mutexLogList->setOwnerId(mutexOwnerId); - LogFileEntry entry; - entry.type = type; - entry.entry = logEntry; - entry.entryDateTime = time(NULL); - logList.push_back(entry); + //if(logList.size() >= 750000) { + // saveToDisk(false,true); + //} + } - //if(logList.size() >= 750000) { - // saveToDisk(false,true); - //} -} + bool LogFileThread::checkSaveCurrentLogBufferToDisk() { + bool ret = false; + if (difftime(time(NULL), lastSaveToDisk) >= 5.0 || + (difftime(time(NULL), lastSaveToDisk) >= 2.0 && + LogFileThread::getLogEntryBufferCount() >= 1000000)) { + lastSaveToDisk = time(NULL); + ret = true; + } + return ret; + } -bool LogFileThread::checkSaveCurrentLogBufferToDisk() { - bool ret = false; - if(difftime(time(NULL),lastSaveToDisk) >= 5.0 || - (difftime(time(NULL), lastSaveToDisk) >= 2.0 && - LogFileThread::getLogEntryBufferCount() >= 1000000)) { - lastSaveToDisk = time(NULL); - ret = true; - } - return ret; -} + void LogFileThread::execute() { + void *ptr_cpy = this->ptr; + bool mustDeleteSelf = false; + { + RunningStatusSafeWrapper runningStatus(this); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); -void LogFileThread::execute() { - void *ptr_cpy = this->ptr; - bool mustDeleteSelf = false; - { - RunningStatusSafeWrapper runningStatus(this); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(getQuitStatus() == true) { - deleteSelfIfRequired(); - return; - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"LogFile thread is running\n"); - - try { - ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); - for(;this->getQuitStatus() == false;) { - while(this->getQuitStatus() == false && - checkSaveCurrentLogBufferToDisk() == true) { - saveToDisk(false,false); - } - if(this->getQuitStatus() == false) { - sleep(25); - } - } - - // Ensure remaining entryies are logged to disk on shutdown - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - saveToDisk(true,false); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - catch(const exception &ex) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); - } - catch(...) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] UNKNOWN Error\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] LogFile thread is starting to exit\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - mustDeleteSelf = getDeleteSelfOnExecutionDone(); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] LogFile thread is exiting, mustDeleteSelf = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,mustDeleteSelf); - } - if(mustDeleteSelf == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] LogFile thread is deleting self\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(isThreadDeleted(ptr_cpy) == false) { - this->setDeleteAfterExecute(true); - } - return; - } -} - -std::size_t LogFileThread::getLogEntryBufferCount() { - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(mutexLogList,mutexOwnerId); - mutexLogList->setOwnerId(mutexOwnerId); - std::size_t logCount = logList.size(); - safeMutex.ReleaseLock(); - return logCount; -} - -bool LogFileThread::canShutdown(bool deleteSelfIfShutdownDelayed) { - bool ret = (getExecutingTask() == false); - if(ret == false && deleteSelfIfShutdownDelayed == true) { - setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed); - deleteSelfIfRequired(); - signalQuit(); - } - - return ret; -} - -void LogFileThread::saveToDisk(bool forceSaveAll,bool logListAlreadyLocked) { - static string mutexOwnerId = CODE_AT_LINE; - MutexSafeWrapper safeMutex(NULL,mutexOwnerId); - if(logListAlreadyLocked == false) { - safeMutex.setMutex(mutexLogList); - mutexLogList->setOwnerId(mutexOwnerId); - } - - std::size_t logCount = logList.size(); - if(logCount > 0) { - vector tempLogList = logList; - safeMutex.ReleaseLock(true); - - logCount = tempLogList.size(); - //if(forceSaveAll == false) { - // logCount = min(logCount,(std::size_t)2000000); - //} - - if(logCount > 0) { - for(unsigned int i = 0; i < logCount; ++i) { - LogFileEntry &entry = tempLogList[i]; - SystemFlags::logDebugEntry(entry.type, entry.entry, entry.entryDateTime); - } - - safeMutex.Lock(); - if(logList.size() > 0) { - if(logList.size() < logCount) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"logList.size() <= logCount [%lld][%lld]",(long long int)logList.size(),(long long int)logCount); - throw megaglest_runtime_error(szBuf); + if (getQuitStatus() == true) { + deleteSelfIfRequired(); + return; } - logList.erase(logList.begin(),logList.begin() + logCount); - } - safeMutex.ReleaseLock(); - } - } - else { - safeMutex.ReleaseLock(); - } -} -}}//end namespace + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "LogFile thread is running\n"); + + try { + ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); + for (; this->getQuitStatus() == false;) { + while (this->getQuitStatus() == false && + checkSaveCurrentLogBufferToDisk() == true) { + saveToDisk(false, false); + } + if (this->getQuitStatus() == false) { + sleep(25); + } + } + + // Ensure remaining entryies are logged to disk on shutdown + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + saveToDisk(true, false); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } catch (const exception &ex) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, ex.what()); + } catch (...) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] UNKNOWN Error\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] LogFile thread is starting to exit\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + mustDeleteSelf = getDeleteSelfOnExecutionDone(); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] LogFile thread is exiting, mustDeleteSelf = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, mustDeleteSelf); + } + if (mustDeleteSelf == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] LogFile thread is deleting self\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (isThreadDeleted(ptr_cpy) == false) { + this->setDeleteAfterExecute(true); + } + return; + } + } + + std::size_t LogFileThread::getLogEntryBufferCount() { + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(mutexLogList, mutexOwnerId); + mutexLogList->setOwnerId(mutexOwnerId); + std::size_t logCount = logList.size(); + safeMutex.ReleaseLock(); + return logCount; + } + + bool LogFileThread::canShutdown(bool deleteSelfIfShutdownDelayed) { + bool ret = (getExecutingTask() == false); + if (ret == false && deleteSelfIfShutdownDelayed == true) { + setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed); + deleteSelfIfRequired(); + signalQuit(); + } + + return ret; + } + + void LogFileThread::saveToDisk(bool forceSaveAll, bool logListAlreadyLocked) { + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(NULL, mutexOwnerId); + if (logListAlreadyLocked == false) { + safeMutex.setMutex(mutexLogList); + mutexLogList->setOwnerId(mutexOwnerId); + } + + std::size_t logCount = logList.size(); + if (logCount > 0) { + vector tempLogList = logList; + safeMutex.ReleaseLock(true); + + logCount = tempLogList.size(); + //if(forceSaveAll == false) { + // logCount = min(logCount,(std::size_t)2000000); + //} + + if (logCount > 0) { + for (unsigned int i = 0; i < logCount; ++i) { + LogFileEntry &entry = tempLogList[i]; + SystemFlags::logDebugEntry(entry.type, entry.entry, entry.entryDateTime); + } + + safeMutex.Lock(); + if (logList.size() > 0) { + if (logList.size() < logCount) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "logList.size() <= logCount [%lld][%lld]", (long long int)logList.size(), (long long int)logCount); + throw megaglest_runtime_error(szBuf); + } + logList.erase(logList.begin(), logList.begin() + logCount); + } + safeMutex.ReleaseLock(); + } + } else { + safeMutex.ReleaseLock(); + } + } + + } +}//end namespace diff --git a/source/shared_lib/sources/platform/miniupnpc/connecthostport.c b/source/shared_lib/sources/platform/miniupnpc/connecthostport.c index 47bb8273a..8d06d0e06 100644 --- a/source/shared_lib/sources/platform/miniupnpc/connecthostport.c +++ b/source/shared_lib/sources/platform/miniupnpc/connecthostport.c @@ -5,8 +5,8 @@ * This software is subject to the conditions detailed in the * LICENCE file provided in this distribution. */ -/* use getaddrinfo() or gethostbyname() - * uncomment the following line in order to use gethostbyname() */ + /* use getaddrinfo() or gethostbyname() + * uncomment the following line in order to use gethostbyname() */ #ifdef NO_GETADDRINFO #define USE_GETHOSTBYNAME #endif @@ -33,8 +33,8 @@ #define closesocket close #include #include -/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions - * during the connect() call */ + /* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions + * during the connect() call */ #define MINIUPNPC_IGNORE_EINTR #ifndef USE_GETHOSTBYNAME #include @@ -42,7 +42,7 @@ #endif /* #ifndef USE_GETHOSTBYNAME */ #endif /* #else _WIN32 */ -/* definition of PRINT_SOCKET_ERROR */ + /* definition of PRINT_SOCKET_ERROR */ #ifdef _WIN32 #define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); #else @@ -63,14 +63,13 @@ * return a socket connected (TCP) to the host and port * or -1 in case of error */ int connecthostport(const char * host, unsigned short port, - unsigned int scope_id) -{ + unsigned int scope_id) { int s, n; #ifdef USE_GETHOSTBYNAME struct sockaddr_in dest; struct hostent *hp; #else /* #ifdef USE_GETHOSTBYNAME */ - char tmp_host[MAXHOSTNAMELEN+1]; + char tmp_host[MAXHOSTNAMELEN + 1]; char port_str[8]; struct addrinfo *ai, *p; struct addrinfo hints; @@ -81,16 +80,14 @@ int connecthostport(const char * host, unsigned short port, #ifdef USE_GETHOSTBYNAME hp = gethostbyname(host); - if(hp == NULL) - { + if (hp == NULL) { herror(host); return -1; } memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr)); memset(dest.sin_zero, 0, sizeof(dest.sin_zero)); s = socket(PF_INET, SOCK_STREAM, 0); - if(s < 0) - { + if (s < 0) { PRINT_SOCKET_ERROR("socket"); return -1; } @@ -98,14 +95,12 @@ int connecthostport(const char * host, unsigned short port, /* setting a 3 seconds timeout for the connect() call */ timeout.tv_sec = 3; timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) - { + if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) { PRINT_SOCKET_ERROR("setsockopt"); } timeout.tv_sec = 3; timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) - { + if (setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) { PRINT_SOCKET_ERROR("setsockopt"); } #endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ @@ -116,31 +111,29 @@ int connecthostport(const char * host, unsigned short port, /* EINTR The system call was interrupted by a signal that was caught * EINPROGRESS The socket is nonblocking and the connection cannot * be completed immediately. */ - while(n < 0 && (errno == EINTR || errno = EINPROGRESS)) - { + while (n < 0 && (errno == EINTR || errno = EINPROGRESS)) { socklen_t len; fd_set wset; int err; FD_ZERO(&wset); FD_SET(s, &wset); - if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR) + if ((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR) continue; /*len = 0;*/ /*n = getpeername(s, NULL, &len);*/ len = sizeof(err); - if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) { + if (getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) { PRINT_SOCKET_ERROR("getsockopt"); closesocket(s); return -1; } - if(err != 0) { + if (err != 0) { errno = err; n = -1; } } #endif /* #ifdef MINIUPNPC_IGNORE_EINTR */ - if(n<0) - { + if (n < 0) { PRINT_SOCKET_ERROR("connect"); closesocket(s); return -1; @@ -156,26 +149,21 @@ int connecthostport(const char * host, unsigned short port, hints.ai_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */ /* hints.ai_protocol = IPPROTO_TCP; */ snprintf(port_str, sizeof(port_str), "%hu", port); - if(host[0] == '[') - { + if (host[0] == '[') { /* literal ip v6 address */ int i, j; - for(i = 0, j = 1; host[j] && (host[j] != ']') && i < MAXHOSTNAMELEN; i++, j++) - { + for (i = 0, j = 1; host[j] && (host[j] != ']') && i < MAXHOSTNAMELEN; i++, j++) { tmp_host[i] = host[j]; - if(0 == memcmp(host+j, "%25", 3)) /* %25 is just url encoding for '%' */ - j+=2; /* skip "25" */ + if (0 == memcmp(host + j, "%25", 3)) /* %25 is just url encoding for '%' */ + j += 2; /* skip "25" */ } tmp_host[i] = '\0'; - } - else - { + } else { strncpy(tmp_host, host, MAXHOSTNAMELEN); } tmp_host[MAXHOSTNAMELEN] = '\0'; n = getaddrinfo(tmp_host, port_str, &hints, &ai); - if(n != 0) - { + if (n != 0) { #ifdef _WIN32 fprintf(stderr, "getaddrinfo() error : %d\n", n); #else @@ -184,12 +172,11 @@ int connecthostport(const char * host, unsigned short port, return -1; } s = -1; - for(p = ai; p; p = p->ai_next) - { + for (p = ai; p; p = p->ai_next) { s = socket(p->ai_family, p->ai_socktype, p->ai_protocol); - if(s < 0) + if (s < 0) continue; - if(p->ai_addr->sa_family == AF_INET6 && scope_id > 0) { + if (p->ai_addr->sa_family == AF_INET6 && scope_id > 0) { struct sockaddr_in6 * addr6 = (struct sockaddr_in6 *)p->ai_addr; addr6->sin6_scope_id = scope_id; } @@ -197,14 +184,12 @@ int connecthostport(const char * host, unsigned short port, /* setting a 3 seconds timeout for the connect() call */ timeout.tv_sec = 3; timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) - { + if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) { PRINT_SOCKET_ERROR("setsockopt"); } timeout.tv_sec = 3; timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) - { + if (setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) { PRINT_SOCKET_ERROR("setsockopt"); } #endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ @@ -213,48 +198,42 @@ int connecthostport(const char * host, unsigned short port, /* EINTR The system call was interrupted by a signal that was caught * EINPROGRESS The socket is nonblocking and the connection cannot * be completed immediately. */ - while(n < 0 && (errno == EINTR || errno == EINPROGRESS)) - { + while (n < 0 && (errno == EINTR || errno == EINPROGRESS)) { socklen_t len; fd_set wset; int err; FD_ZERO(&wset); FD_SET(s, &wset); - if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR) + if ((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR) continue; /*len = 0;*/ /*n = getpeername(s, NULL, &len);*/ len = sizeof(err); - if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) { + if (getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) { PRINT_SOCKET_ERROR("getsockopt"); closesocket(s); freeaddrinfo(ai); return -1; } - if(err != 0) { + if (err != 0) { errno = err; n = -1; } } #endif /* #ifdef MINIUPNPC_IGNORE_EINTR */ - if(n < 0) - { + if (n < 0) { closesocket(s); continue; - } - else - { + } else { break; } } freeaddrinfo(ai); - if(s < 0) - { + if (s < 0) { PRINT_SOCKET_ERROR("socket"); return -1; } - if(n < 0) - { + if (n < 0) { PRINT_SOCKET_ERROR("connect"); return -1; } diff --git a/source/shared_lib/sources/platform/miniupnpc/igd_desc_parse.c b/source/shared_lib/sources/platform/miniupnpc/igd_desc_parse.c index d2999ad01..96f770bff 100644 --- a/source/shared_lib/sources/platform/miniupnpc/igd_desc_parse.c +++ b/source/shared_lib/sources/platform/miniupnpc/igd_desc_parse.c @@ -10,17 +10,16 @@ #include #include -/* Start element handler : - * update nesting level counter and copy element name */ -void IGDstartelt(void * d, const char * name, int l) -{ + /* Start element handler : + * update nesting level counter and copy element name */ +void IGDstartelt(void * d, const char * name, int l) { struct IGDdatas * datas = (struct IGDdatas *)d; - if(l >= MINIUPNPC_URL_MAXSIZE) - l = MINIUPNPC_URL_MAXSIZE-1; + if (l >= MINIUPNPC_URL_MAXSIZE) + l = MINIUPNPC_URL_MAXSIZE - 1; memcpy(datas->cureltname, name, l); datas->cureltname[l] = '\0'; datas->level++; - if( (l==7) && !memcmp(name, "service", l) ) { + if ((l == 7) && !memcmp(name, "service", l)) { datas->tmp.controlurl[0] = '\0'; datas->tmp.eventsuburl[0] = '\0'; datas->tmp.scpdurl[0] = '\0'; @@ -33,24 +32,22 @@ void IGDstartelt(void * d, const char * name, int l) /* End element handler : * update nesting level counter and update parser state if * service element is parsed */ -void IGDendelt(void * d, const char * name, int l) -{ +void IGDendelt(void * d, const char * name, int l) { struct IGDdatas * datas = (struct IGDdatas *)d; datas->level--; /*printf("endelt %2d %.*s\n", datas->level, l, name);*/ - if( (l==7) && !memcmp(name, "service", l) ) - { - if(COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:")) { + if ((l == 7) && !memcmp(name, "service", l)) { + if (COMPARE(datas->tmp.servicetype, + "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:")) { memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service)); - } else if(COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANIPv6FirewallControl:")) { + } else if (COMPARE(datas->tmp.servicetype, + "urn:schemas-upnp-org:service:WANIPv6FirewallControl:")) { memcpy(&datas->IPv6FC, &datas->tmp, sizeof(struct IGDdatas_service)); - } else if(COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANIPConnection:") - || COMPARE(datas->tmp.servicetype, - "urn:schemas-upnp-org:service:WANPPPConnection:") ) { - if(datas->first.servicetype[0] == '\0') { + } else if (COMPARE(datas->tmp.servicetype, + "urn:schemas-upnp-org:service:WANIPConnection:") + || COMPARE(datas->tmp.servicetype, + "urn:schemas-upnp-org:service:WANPPPConnection:")) { + if (datas->first.servicetype[0] == '\0') { memcpy(&datas->first, &datas->tmp, sizeof(struct IGDdatas_service)); } else { memcpy(&datas->second, &datas->tmp, sizeof(struct IGDdatas_service)); @@ -61,38 +58,35 @@ void IGDendelt(void * d, const char * name, int l) /* Data handler : * copy data depending on the current element name and state */ -void IGDdata(void * d, const char * data, int l) -{ +void IGDdata(void * d, const char * data, int l) { struct IGDdatas * datas = (struct IGDdatas *)d; char * dstmember = 0; /*printf("%2d %s : %.*s\n", - datas->level, datas->cureltname, l, data); */ - if( !strcmp(datas->cureltname, "URLBase") ) + datas->level, datas->cureltname, l, data); */ + if (!strcmp(datas->cureltname, "URLBase")) dstmember = datas->urlbase; - else if( !strcmp(datas->cureltname, "presentationURL") ) + else if (!strcmp(datas->cureltname, "presentationURL")) dstmember = datas->presentationurl; - else if( !strcmp(datas->cureltname, "serviceType") ) + else if (!strcmp(datas->cureltname, "serviceType")) dstmember = datas->tmp.servicetype; - else if( !strcmp(datas->cureltname, "controlURL") ) + else if (!strcmp(datas->cureltname, "controlURL")) dstmember = datas->tmp.controlurl; - else if( !strcmp(datas->cureltname, "eventSubURL") ) + else if (!strcmp(datas->cureltname, "eventSubURL")) dstmember = datas->tmp.eventsuburl; - else if( !strcmp(datas->cureltname, "SCPDURL") ) + else if (!strcmp(datas->cureltname, "SCPDURL")) dstmember = datas->tmp.scpdurl; -/* else if( !strcmp(datas->cureltname, "deviceType") ) - dstmember = datas->devicetype_tmp;*/ - if(dstmember) - { - if(l>=MINIUPNPC_URL_MAXSIZE) - l = MINIUPNPC_URL_MAXSIZE-1; + /* else if( !strcmp(datas->cureltname, "deviceType") ) + dstmember = datas->devicetype_tmp;*/ + if (dstmember) { + if (l >= MINIUPNPC_URL_MAXSIZE) + l = MINIUPNPC_URL_MAXSIZE - 1; memcpy(dstmember, data, l); dstmember[l] = '\0'; } } #ifdef DEBUG -void printIGD(struct IGDdatas * d) -{ +void printIGD(struct IGDdatas * d) { printf("urlbase = '%s'\n", d->urlbase); printf("WAN Device (Common interface config) :\n"); /*printf(" deviceType = '%s'\n", d->CIF.devicetype);*/ diff --git a/source/shared_lib/sources/platform/miniupnpc/minisoap.c b/source/shared_lib/sources/platform/miniupnpc/minisoap.c index f120fe515..f8b62f9ba 100644 --- a/source/shared_lib/sources/platform/miniupnpc/minisoap.c +++ b/source/shared_lib/sources/platform/miniupnpc/minisoap.c @@ -21,7 +21,7 @@ #include "minisoap.h" #include "miniupnpcstrings.h" -/* only for malloc */ + /* only for malloc */ #include #ifdef _WIN32 @@ -34,83 +34,81 @@ * and returns the number of bytes sent */ static int httpWrite(int fd, const char * body, int bodysize, - const char * headers, int headerssize) -{ + const char * headers, int headerssize) { int n = 0; /*n = write(fd, headers, headerssize);*/ /*if(bodysize>0) n += write(fd, body, bodysize);*/ - /* Note : my old linksys router only took into account - * soap request that are sent into only one packet */ + /* Note : my old linksys router only took into account + * soap request that are sent into only one packet */ char * p; /* TODO: AVOID MALLOC */ - p = malloc(headerssize+bodysize); - if(!p) - return 0; + p = malloc(headerssize + bodysize); + if (!p) + return 0; memcpy(p, headers, headerssize); - memcpy(p+headerssize, body, bodysize); + memcpy(p + headerssize, body, bodysize); /*n = write(fd, p, headerssize+bodysize);*/ - n = send(fd, p, headerssize+bodysize, 0); - if(n<0) { - PRINT_SOCKET_ERROR("send"); + n = send(fd, p, headerssize + bodysize, 0); + if (n < 0) { + PRINT_SOCKET_ERROR("send"); } /* disable send on the socket */ /* draytek routers dont seems to like that... */ #if 0 #ifdef _WIN32 - if(shutdown(fd, SD_SEND)<0) { + if (shutdown(fd, SD_SEND) < 0) { #else - if(shutdown(fd, SHUT_WR)<0) { /*SD_SEND*/ + if (shutdown(fd, SHUT_WR) < 0) { /*SD_SEND*/ #endif PRINT_SOCKET_ERROR("shutdown"); } #endif free(p); return n; -} + } /* self explanatory */ int soapPostSubmit(int fd, - const char * url, - const char * host, - unsigned short port, - const char * action, - const char * body, - const char * httpversion) -{ + const char * url, + const char * host, + unsigned short port, + const char * action, + const char * body, + const char * httpversion) { int bodysize; char headerbuf[512]; int headerssize; char portstr[8]; - bodysize = (int)strlen(body); + bodysize = (int) strlen(body); /* We are not using keep-alive HTTP connections. * HTTP/1.1 needs the header Connection: close to do that. * This is the default with HTTP/1.0 * Using HTTP/1.1 means we need to support chunked transfer-encoding : * When using HTTP/1.1, the router "BiPAC 7404VNOX" always use chunked * transfer encoding. */ - /* Connection: Close is normally there only in HTTP/1.1 but who knows */ + /* Connection: Close is normally there only in HTTP/1.1 but who knows */ portstr[0] = '\0'; - if(port != 80) + if (port != 80) snprintf(portstr, sizeof(portstr), ":%hu", port); headerssize = snprintf(headerbuf, sizeof(headerbuf), - "POST %s HTTP/%s\r\n" - "Host: %s%s\r\n" - "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" - "Content-Length: %d\r\n" - "Content-Type: text/xml\r\n" - "SOAPAction: \"%s\"\r\n" - "Connection: Close\r\n" - "Cache-Control: no-cache\r\n" /* ??? */ - "Pragma: no-cache\r\n" - "\r\n", - url, httpversion, host, portstr, bodysize, action); + "POST %s HTTP/%s\r\n" + "Host: %s%s\r\n" + "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" + "Content-Length: %d\r\n" + "Content-Type: text/xml\r\n" + "SOAPAction: \"%s\"\r\n" + "Connection: Close\r\n" + "Cache-Control: no-cache\r\n" /* ??? */ + "Pragma: no-cache\r\n" + "\r\n", + url, httpversion, host, portstr, bodysize, action); #ifdef DEBUG /*printf("SOAP request : headersize=%d bodysize=%d\n", - headerssize, bodysize); + headerssize, bodysize); */ printf("SOAP request : POST %s HTTP/%s - Host: %s%s\n", - url, httpversion, host, portstr); + url, httpversion, host, portstr); printf("SOAPAction: \"%s\" - Content-Length: %d\n", action, bodysize); printf("Headers :\n%s", headerbuf); printf("Body :\n%s\n", body); diff --git a/source/shared_lib/sources/platform/miniupnpc/minissdpc.c b/source/shared_lib/sources/platform/miniupnpc/minissdpc.c index 38ada609c..4e73263f5 100644 --- a/source/shared_lib/sources/platform/miniupnpc/minissdpc.c +++ b/source/shared_lib/sources/platform/miniupnpc/minissdpc.c @@ -5,7 +5,7 @@ * copyright (c) 2005-2015 Thomas Bernard * This software is subjet to the conditions detailed in the * provided LICENCE file. */ -/*#include */ + /*#include */ #include #include #include @@ -40,8 +40,8 @@ typedef unsigned short uint16_t; /* Hack */ #define UNIX_PATH_LEN 108 struct sockaddr_un { - uint16_t sun_family; - char sun_path[UNIX_PATH_LEN]; + uint16_t sun_family; + char sun_path[UNIX_PATH_LEN]; }; #else /* defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__) */ #include @@ -70,8 +70,7 @@ struct sockaddr_un { #if defined(HAS_IP_MREQN) && defined(NEED_STRUCT_IP_MREQN) /* Several versions of glibc don't define this structure, * define it here and compile with CFLAGS NEED_STRUCT_IP_MREQN */ -struct ip_mreqn -{ +struct ip_mreqn { struct in_addr imr_multiaddr; /* IP multicast address of group */ struct in_addr imr_address; /* local IP address of interface */ int imr_ifindex; /* Interface index */ @@ -92,8 +91,7 @@ struct ip_mreqn #include "codelength.h" struct UPNPDev * -getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error) -{ + getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error) { struct UPNPDev * devlist = NULL; int s; int res; @@ -157,8 +155,7 @@ getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * err } int -connectToMiniSSDPD(const char * socketpath) -{ +connectToMiniSSDPD(const char * socketpath) { int s; struct sockaddr_un addr; #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT @@ -166,8 +163,7 @@ connectToMiniSSDPD(const char * socketpath) #endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ s = socket(AF_UNIX, SOCK_STREAM, 0); - if(s < 0) - { + if (s < 0) { /*syslog(LOG_ERR, "socket(unix): %m");*/ perror("socket(unix)"); return MINISSDPC_SOCKET_ERROR; @@ -176,24 +172,21 @@ connectToMiniSSDPD(const char * socketpath) /* setting a 3 seconds timeout */ timeout.tv_sec = 3; timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) - { + if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) { perror("setsockopt"); } timeout.tv_sec = 3; timeout.tv_usec = 0; - if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) - { + if (setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) { perror("setsockopt"); } #endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ - if(!socketpath) + if (!socketpath) socketpath = "/var/run/minissdpd.sock"; addr.sun_family = AF_UNIX; strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path)); /* TODO : check if we need to handle the EINTR */ - if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) - { + if (connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) { /*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/ close(s); return MINISSDPC_SOCKET_ERROR; @@ -202,44 +195,37 @@ connectToMiniSSDPD(const char * socketpath) } int -disconnectFromMiniSSDPD(int s) -{ +disconnectFromMiniSSDPD(int s) { if (close(s) < 0) return MINISSDPC_SOCKET_ERROR; return MINISSDPC_SUCCESS; } int -requestDevicesFromMiniSSDPD(int s, const char * devtype) -{ +requestDevicesFromMiniSSDPD(int s, const char * devtype) { unsigned char buffer[256]; unsigned char * p; unsigned int stsize, l; stsize = strlen(devtype); - if(stsize == 8 && 0 == memcmp(devtype, "ssdp:all", 8)) - { + if (stsize == 8 && 0 == memcmp(devtype, "ssdp:all", 8)) { buffer[0] = 3; /* request type 3 : everything */ - } - else - { + } else { buffer[0] = 1; /* request type 1 : request devices/services by type */ } p = buffer + 1; l = stsize; CODELENGTH(l, p); - if(p + stsize > buffer + sizeof(buffer)) - { + if (p + stsize > buffer + sizeof(buffer)) { /* devtype is too long ! */ #ifdef DEBUG fprintf(stderr, "devtype is too long ! stsize=%u sizeof(buffer)=%u\n", - stsize, (unsigned)sizeof(buffer)); + stsize, (unsigned)sizeof(buffer)); #endif /* DEBUG */ return MINISSDPC_INVALID_INPUT; } memcpy(p, devtype, stsize); p += stsize; - if(write(s, buffer, p - buffer) < 0) - { + if (write(s, buffer, p - buffer) < 0) { /*syslog(LOG_ERR, "write(): %m");*/ perror("minissdpc.c: write()"); return MINISSDPC_SOCKET_ERROR; @@ -248,8 +234,7 @@ requestDevicesFromMiniSSDPD(int s, const char * devtype) } struct UPNPDev * -receiveDevicesFromMiniSSDPD(int s, int * error) -{ + receiveDevicesFromMiniSSDPD(int s, int * error) { struct UPNPDev * tmp; struct UPNPDev * devlist = NULL; unsigned char buffer[256]; @@ -262,8 +247,7 @@ receiveDevicesFromMiniSSDPD(int s, int * error) unsigned int urlsize, stsize, usnsize, l; n = read(s, buffer, sizeof(buffer)); - if(n<=0) - { + if (n <= 0) { perror("minissdpc.c: read()"); if (error) *error = MINISSDPC_SOCKET_ERROR; @@ -271,10 +255,9 @@ receiveDevicesFromMiniSSDPD(int s, int * error) } ndev = buffer[0]; bufferindex = 1; - for(i = 0; i < ndev; i++) - { + for (i = 0; i < ndev; i++) { DECODELENGTH_READ(urlsize, READ_BYTE_BUFFER); - if(n<=0) { + if (n <= 0) { if (error) *error = MINISSDPC_INVALID_SERVER_REPLY; return devlist; @@ -283,19 +266,19 @@ receiveDevicesFromMiniSSDPD(int s, int * error) printf(" urlsize=%u", urlsize); #endif /* DEBUG */ url = malloc(urlsize); - if(url == NULL) { + if (url == NULL) { if (error) *error = MINISSDPC_MEMORY_ERROR; return devlist; } READ_COPY_BUFFER(url, urlsize); - if(n<=0) { + if (n <= 0) { if (error) *error = MINISSDPC_INVALID_SERVER_REPLY; goto free_url_and_return; } DECODELENGTH_READ(stsize, READ_BYTE_BUFFER); - if(n<=0) { + if (n <= 0) { if (error) *error = MINISSDPC_INVALID_SERVER_REPLY; goto free_url_and_return; @@ -310,13 +293,13 @@ receiveDevicesFromMiniSSDPD(int s, int * error) goto free_url_and_return; } READ_COPY_BUFFER(st, stsize); - if(n<=0) { + if (n <= 0) { if (error) *error = MINISSDPC_INVALID_SERVER_REPLY; goto free_url_and_st_and_return; } DECODELENGTH_READ(usnsize, READ_BYTE_BUFFER); - if(n<=0) { + if (n <= 0) { if (error) *error = MINISSDPC_INVALID_SERVER_REPLY; goto free_url_and_st_and_return; @@ -324,8 +307,8 @@ receiveDevicesFromMiniSSDPD(int s, int * error) #ifdef DEBUG printf(" usnsize=%u\n", usnsize); #endif /* DEBUG */ - tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize); - if(tmp == NULL) { + tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev) + urlsize + stsize + usnsize); + if (tmp == NULL) { if (error) *error = MINISSDPC_MEMORY_ERROR; goto free_url_and_st_and_return; @@ -336,19 +319,19 @@ receiveDevicesFromMiniSSDPD(int s, int * error) memcpy(tmp->buffer, url, urlsize); tmp->buffer[urlsize] = '\0'; memcpy(tmp->st, st, stsize); - tmp->buffer[urlsize+1+stsize] = '\0'; + tmp->buffer[urlsize + 1 + stsize] = '\0'; free(url); free(st); url = NULL; st = NULL; tmp->usn = tmp->buffer + 1 + urlsize + 1 + stsize; READ_COPY_BUFFER(tmp->usn, usnsize); - if(n<=0) { + if (n <= 0) { if (error) *error = MINISSDPC_INVALID_SERVER_REPLY; goto free_tmp_and_return; } - tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0'; + tmp->buffer[urlsize + 1 + stsize + 1 + usnsize] = '\0'; tmp->scope_id = 0; /* default value. scope_id is not available with MiniSSDPd */ devlist = tmp; } @@ -376,21 +359,17 @@ free_tmp_and_return: * The strings are NOT null terminated */ static void parseMSEARCHReply(const char * reply, int size, - const char * * location, int * locationsize, - const char * * st, int * stsize, - const char * * usn, int * usnsize) -{ + const char * * location, int * locationsize, + const char * * st, int * stsize, + const char * * usn, int * usnsize) { int a, b, i; i = 0; a = i; /* start of the line */ b = 0; /* end of the "header" (position of the colon) */ - while(isin6_family = AF_INET6; - if(localport > 0 && localport < 65536) - p->sin6_port = htons((unsigned short)localport); + if (localport > 0 && localport < 65536) + p->sin6_port = htons((unsigned short) localport); p->sin6_addr = in6addr_any; /* in6addr_any is not available with MinGW32 3.4.2 */ } else { struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r; p->sin_family = AF_INET; - if(localport > 0 && localport < 65536) - p->sin_port = htons((unsigned short)localport); + if (localport > 0 && localport < 65536) + p->sin_port = htons((unsigned short) localport); p->sin_addr.s_addr = INADDR_ANY; } #ifdef _WIN32 -/* This code could help us to use the right Network interface for - * SSDP multicast traffic */ -/* Get IP associated with the index given in the ip_forward struct - * in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */ - if(!ipv6 - && (GetBestRoute(inet_addr("223.255.255.255"), 0, &ip_forward) == NO_ERROR)) { + /* This code could help us to use the right Network interface for + * SSDP multicast traffic */ + /* Get IP associated with the index given in the ip_forward struct + * in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */ + if (!ipv6 + && (GetBestRoute(inet_addr("223.255.255.255"), 0, &ip_forward) == NO_ERROR)) { DWORD dwRetVal = 0; PMIB_IPADDRTABLE pIPAddrTable; DWORD dwSize = 0; @@ -541,26 +514,26 @@ ssdpDiscoverDevices(const char * const deviceTypes[], #ifdef DEBUG printf("ifIndex=%lu nextHop=%lx \n", ip_forward.dwForwardIfIndex, ip_forward.dwForwardNextHop); #endif - pIPAddrTable = (MIB_IPADDRTABLE *) malloc(sizeof (MIB_IPADDRTABLE)); - if(pIPAddrTable) { + pIPAddrTable = (MIB_IPADDRTABLE *) malloc(sizeof(MIB_IPADDRTABLE)); + if (pIPAddrTable) { if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) { free(pIPAddrTable); pIPAddrTable = (MIB_IPADDRTABLE *) malloc(dwSize); } } - if(pIPAddrTable) { - dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 ); + if (pIPAddrTable) { + dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0); if (dwRetVal == NO_ERROR) { #ifdef DEBUG printf("\tNum Entries: %ld\n", pIPAddrTable->dwNumEntries); #endif - for (i=0; i < (int) pIPAddrTable->dwNumEntries; i++) { + for (i = 0; i < (int) pIPAddrTable->dwNumEntries; i++) { #ifdef DEBUG printf("\n\tInterface Index[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwIndex); IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwAddr; - printf("\tIP Address[%d]: \t%s\n", i, inet_ntoa(IPAddr) ); + printf("\tIP Address[%d]: \t%s\n", i, inet_ntoa(IPAddr)); IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwMask; - printf("\tSubnet Mask[%d]: \t%s\n", i, inet_ntoa(IPAddr) ); + printf("\tSubnet Mask[%d]: \t%s\n", i, inet_ntoa(IPAddr)); IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwBCastAddr; printf("\tBroadCast[%d]: \t%s (%ld)\n", i, inet_ntoa(IPAddr), pIPAddrTable->table[i].dwBCastAddr); printf("\tReassembly size[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwReasmSize); @@ -572,7 +545,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[], struct in_addr mc_if; memset(&mc_if, 0, sizeof(mc_if)); mc_if.s_addr = pIPAddrTable->table[i].dwAddr; - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) { + if (setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *) &mc_if, sizeof(mc_if)) < 0) { PRINT_SOCKET_ERROR("setsockopt"); } ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = pIPAddrTable->table[i].dwAddr; @@ -589,37 +562,35 @@ ssdpDiscoverDevices(const char * const deviceTypes[], #endif /* _WIN32 */ #ifdef _WIN32 - if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0) + if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *) &opt, sizeof(opt)) < 0) #else - if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0) + if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) #endif { - if(error) + if (error) *error = MINISSDPC_SOCKET_ERROR; PRINT_SOCKET_ERROR("setsockopt(SO_REUSEADDR,...)"); return NULL; } #ifdef _WIN32 - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&_ttl, sizeof(_ttl)) < 0) + if (setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, (const char *) &_ttl, sizeof(_ttl)) < 0) #else /* _WIN32 */ - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) + if (setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) #endif /* _WIN32 */ { /* not a fatal error */ PRINT_SOCKET_ERROR("setsockopt(IP_MULTICAST_TTL,...)"); } - if(multicastif) - { - if(ipv6) { + if (multicastif) { + if (ipv6) { #if !defined(_WIN32) /* according to MSDN, if_nametoindex() is supported since * MS Windows Vista and MS Windows Server 2008. * http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */ unsigned int ifindex = if_nametoindex(multicastif); /* eth0, etc. */ - if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)) < 0) - { + if (setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)) < 0) { PRINT_SOCKET_ERROR("setsockopt"); } #else @@ -630,11 +601,9 @@ ssdpDiscoverDevices(const char * const deviceTypes[], } else { struct in_addr mc_if; mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */ - if(mc_if.s_addr != INADDR_NONE) - { + if (mc_if.s_addr != INADDR_NONE) { ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr; - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) - { + if (setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *) &mc_if, sizeof(mc_if)) < 0) { PRINT_SOCKET_ERROR("setsockopt"); } } else { @@ -643,8 +612,7 @@ ssdpDiscoverDevices(const char * const deviceTypes[], struct ip_mreqn reqn; /* only defined with -D_BSD_SOURCE or -D_GNU_SOURCE */ memset(&reqn, 0, sizeof(struct ip_mreqn)); reqn.imr_ifindex = if_nametoindex(multicastif); - if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&reqn, sizeof(reqn)) < 0) - { + if (setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *) &reqn, sizeof(reqn)) < 0) { PRINT_SOCKET_ERROR("setsockopt"); } #else @@ -659,51 +627,50 @@ ssdpDiscoverDevices(const char * const deviceTypes[], /* Before sending the packed, we first "bind" in order to be able * to receive the response */ if (bind(sudp, (const struct sockaddr *)&sockudp_r, - ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) != 0) - { - if(error) + ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) != 0) { + if (error) *error = MINISSDPC_SOCKET_ERROR; PRINT_SOCKET_ERROR("bind"); closesocket(sudp); return NULL; } - if(error) + if (error) *error = MINISSDPC_SUCCESS; /* Calculating maximum response time in seconds */ - mx = ((unsigned int)delay) / 1000u; - if(mx == 0) { + mx = ((unsigned int) delay) / 1000u; + if (mx == 0) { mx = 1; delay = 1000; } /* receiving SSDP response packet */ - for(deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) { + for (deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) { /* sending the SSDP M-SEARCH packet */ n = snprintf(bufr, sizeof(bufr), - MSearchMsgFmt, - ipv6 ? - (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" : "[" UPNP_MCAST_SL_ADDR "]") - : UPNP_MCAST_ADDR, - deviceTypes[deviceIndex], mx); + MSearchMsgFmt, + ipv6 ? + (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" : "[" UPNP_MCAST_SL_ADDR "]") + : UPNP_MCAST_ADDR, + deviceTypes[deviceIndex], mx); #ifdef DEBUG /*printf("Sending %s", bufr);*/ printf("Sending M-SEARCH request to %s with ST: %s\n", - ipv6 ? - (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" : "[" UPNP_MCAST_SL_ADDR "]") - : UPNP_MCAST_ADDR, - deviceTypes[deviceIndex]); + ipv6 ? + (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" : "[" UPNP_MCAST_SL_ADDR "]") + : UPNP_MCAST_ADDR, + deviceTypes[deviceIndex]); #endif #ifdef NO_GETADDRINFO /* the following code is not using getaddrinfo */ /* emission */ memset(&sockudp_w, 0, sizeof(struct sockaddr_storage)); - if(ipv6) { + if (ipv6) { struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_w; p->sin6_family = AF_INET6; p->sin6_port = htons(SSDP_PORT); inet_pton(AF_INET6, - linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR, - &(p->sin6_addr)); + linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR, + &(p->sin6_addr)); } else { struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_w; p->sin_family = AF_INET; @@ -711,9 +678,9 @@ ssdpDiscoverDevices(const char * const deviceTypes[], p->sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR); } n = sendto(sudp, bufr, n, 0, &sockudp_w, - ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); + ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); if (n < 0) { - if(error) + if (error) *error = MINISSDPC_SOCKET_ERROR; PRINT_SOCKET_ERROR("sendto"); break; @@ -724,10 +691,10 @@ ssdpDiscoverDevices(const char * const deviceTypes[], hints.ai_socktype = SOCK_DGRAM; /*hints.ai_flags = */ if ((rv = getaddrinfo(ipv6 - ? (linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR) - : UPNP_MCAST_ADDR, - XSTR(SSDP_PORT), &hints, &servinfo)) != 0) { - if(error) + ? (linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR) + : UPNP_MCAST_ADDR, + XSTR(SSDP_PORT), &hints, &servinfo)) != 0) { + if (error) *error = MINISSDPC_SOCKET_ERROR; #ifdef _WIN32 fprintf(stderr, "getaddrinfo() failed: %d\n", rv); @@ -736,13 +703,13 @@ ssdpDiscoverDevices(const char * const deviceTypes[], #endif break; } - for(p = servinfo; p; p = p->ai_next) { + for (p = servinfo; p; p = p->ai_next) { n = sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen); if (n < 0) { #ifdef DEBUG char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; if (getnameinfo(p->ai_addr, p->ai_addrlen, hbuf, sizeof(hbuf), sbuf, - sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0) { + sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0) { fprintf(stderr, "host:%s port:%s\n", hbuf, sbuf); } #endif @@ -751,8 +718,8 @@ ssdpDiscoverDevices(const char * const deviceTypes[], } } freeaddrinfo(servinfo); - if(n < 0) { - if(error) + if (n < 0) { + if (error) *error = MINISSDPC_SOCKET_ERROR; break; } @@ -760,11 +727,11 @@ ssdpDiscoverDevices(const char * const deviceTypes[], /* Waiting for SSDP REPLY packet to M-SEARCH * if searchalltypes is set, enter the loop only * when the last deviceType is reached */ - if(!searchalltypes || !deviceTypes[deviceIndex + 1]) do { + if (!searchalltypes || !deviceTypes[deviceIndex + 1]) do { n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id); if (n < 0) { /* error */ - if(error) + if (error) *error = MINISSDPC_SOCKET_ERROR; goto error; } else if (n == 0) { @@ -774,40 +741,40 @@ ssdpDiscoverDevices(const char * const deviceTypes[], #endif /* DEBUG */ if (devlist && !searchalltypes) { /* found some devices, stop now*/ - if(error) + if (error) *error = MINISSDPC_SUCCESS; goto error; } } else { - const char * descURL=NULL; - int urlsize=0; - const char * st=NULL; - int stsize=0; - const char * usn=NULL; - int usnsize=0; + const char * descURL = NULL; + int urlsize = 0; + const char * st = NULL; + int stsize = 0; + const char * usn = NULL; + int usnsize = 0; parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize, &usn, &usnsize); - if(st&&descURL) { + if (st&&descURL) { #ifdef DEBUG printf("M-SEARCH Reply:\n ST: %.*s\n USN: %.*s\n Location: %.*s\n", - stsize, st, usnsize, (usn?usn:""), urlsize, descURL); + stsize, st, usnsize, (usn ? usn : ""), urlsize, descURL); #endif /* DEBUG */ - for(tmp=devlist; tmp; tmp = tmp->pNext) { - if(memcmp(tmp->descURL, descURL, urlsize) == 0 && - tmp->descURL[urlsize] == '\0' && - memcmp(tmp->st, st, stsize) == 0 && - tmp->st[stsize] == '\0' && - (usnsize == 0 || memcmp(tmp->usn, usn, usnsize) == 0) && - tmp->usn[usnsize] == '\0') + for (tmp = devlist; tmp; tmp = tmp->pNext) { + if (memcmp(tmp->descURL, descURL, urlsize) == 0 && + tmp->descURL[urlsize] == '\0' && + memcmp(tmp->st, st, stsize) == 0 && + tmp->st[stsize] == '\0' && + (usnsize == 0 || memcmp(tmp->usn, usn, usnsize) == 0) && + tmp->usn[usnsize] == '\0') break; } /* at the exit of the loop above, tmp is null if * no duplicate device was found */ - if(tmp) + if (tmp) continue; - tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize); - if(!tmp) { + tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev) + urlsize + stsize + usnsize); + if (!tmp) { /* memory allocation error */ - if(error) + if (error) *error = MINISSDPC_MEMORY_ERROR; goto error; } @@ -818,18 +785,18 @@ ssdpDiscoverDevices(const char * const deviceTypes[], memcpy(tmp->buffer, descURL, urlsize); tmp->buffer[urlsize] = '\0'; memcpy(tmp->st, st, stsize); - tmp->buffer[urlsize+1+stsize] = '\0'; - if(usn != NULL) + tmp->buffer[urlsize + 1 + stsize] = '\0'; + if (usn != NULL) memcpy(tmp->usn, usn, usnsize); - tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0'; + tmp->buffer[urlsize + 1 + stsize + 1 + usnsize] = '\0'; tmp->scope_id = scope_id; devlist = tmp; } } - } while(n > 0); - if(ipv6) { + } while (n > 0); + if (ipv6) { /* switch linklocal flag */ - if(linklocal) { + if (linklocal) { linklocal = 0; --deviceIndex; } else { diff --git a/source/shared_lib/sources/platform/miniupnpc/miniupnpc.c b/source/shared_lib/sources/platform/miniupnpc/miniupnpc.c index afcc91029..5ff3381d2 100644 --- a/source/shared_lib/sources/platform/miniupnpc/miniupnpc.c +++ b/source/shared_lib/sources/platform/miniupnpc/miniupnpc.c @@ -9,7 +9,7 @@ #include #include #ifdef _WIN32 -/* Win32 Specific includes and defines */ + /* Win32 Specific includes and defines */ #include #include #include @@ -25,7 +25,7 @@ #endif /* #ifndef strncasecmp */ #define MAXHOSTNAMELEN 64 #else /* #ifdef _WIN32 */ -/* Standard POSIX includes */ + /* Standard POSIX includes */ #include #if defined(__amigaos__) && !defined(__amigaos4__) /* Amiga OS 3 specific stuff */ @@ -72,8 +72,7 @@ #define SERVICEPREFIX2 'u' /* root description parsing */ -MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data) -{ +MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data) { struct xmlparser parser; /* xmlparser object */ parser.xmlstart = buffer; @@ -95,68 +94,61 @@ MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGD * pointer - OK * NULL - error */ char * simpleUPnPcommand2(int s, const char * url, const char * service, - const char * action, struct UPNParg * args, - int * bufsize, const char * httpversion) -{ - char hostname[MAXHOSTNAMELEN+1]; + const char * action, struct UPNParg * args, + int * bufsize, const char * httpversion) { + char hostname[MAXHOSTNAMELEN + 1]; unsigned short port = 0; char * path; char soapact[128]; char soapbody[2048]; char * buf; - int n; + int n; *bufsize = 0; snprintf(soapact, sizeof(soapact), "%s#%s", service, action); - if(args==NULL) - { + if (args == NULL) { /*soapbodylen = */snprintf(soapbody, sizeof(soapbody), - "\r\n" - "<" SOAPPREFIX ":Envelope " - "xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" " - SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" - "<" SOAPPREFIX ":Body>" - "<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">" - "" - "" - "\r\n", action, service, action); - } - else - { + "\r\n" + "<" SOAPPREFIX ":Envelope " + "xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" " + SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" + "<" SOAPPREFIX ":Body>" + "<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">" + "" + "" + "\r\n", action, service, action); + } else { char * p; - const char * pe, * pv; + const char * pe, *pv; int soapbodylen; soapbodylen = snprintf(soapbody, sizeof(soapbody), - "\r\n" - "<" SOAPPREFIX ":Envelope " - "xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" " - SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" - "<" SOAPPREFIX ":Body>" - "<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">", - action, service); + "\r\n" + "<" SOAPPREFIX ":Envelope " + "xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" " + SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" + "<" SOAPPREFIX ":Body>" + "<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">", + action, service); p = soapbody + soapbodylen; - while(args->elt) - { + while (args->elt) { /* check that we are never overflowing the string... */ - if(soapbody + sizeof(soapbody) <= p + 100) - { + if (soapbody + sizeof(soapbody) <= p + 100) { /* we keep a margin of at least 100 bytes */ return NULL; } *(p++) = '<'; pe = args->elt; - while(*pe) + while (*pe) *(p++) = *(pe++); *(p++) = '>'; - if((pv = args->val)) - { - while(*pv) + if ((pv = args->val)) { + while (*pv) *(p++) = *(pv++); } *(p++) = '<'; *(p++) = '/'; pe = args->elt; - while(*pe) + while (*pe) *(p++) = *(pe++); *(p++) = '>'; args++; @@ -166,22 +158,22 @@ char * simpleUPnPcommand2(int s, const char * url, const char * service, *(p++) = SERVICEPREFIX2; *(p++) = ':'; pe = action; - while(*pe) + while (*pe) *(p++) = *(pe++); strncpy(p, ">\r\n", - soapbody + sizeof(soapbody) - p); + soapbody + sizeof(soapbody) - p); } - if(!parseURL(url, hostname, &port, &path, NULL)) return NULL; - if(s < 0) { + if (!parseURL(url, hostname, &port, &path, NULL)) return NULL; + if (s < 0) { s = connecthostport(hostname, port, 0); - if(s < 0) { + if (s < 0) { /* failed to connect */ return NULL; } } n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, httpversion); - if(n<=0) { + if (n <= 0) { #ifdef DEBUG printf("Error sending SOAP request\n"); #endif @@ -191,8 +183,7 @@ char * simpleUPnPcommand2(int s, const char * url, const char * service, buf = getHTTPResponse(s, bufsize); #ifdef DEBUG - if(*bufsize > 0 && buf) - { + if (*bufsize > 0 && buf) { printf("SOAP Response :\n%.*s\n", *bufsize, buf); } #endif @@ -206,19 +197,17 @@ char * simpleUPnPcommand2(int s, const char * url, const char * service, * pointer - OK * NULL - error */ char * simpleUPnPcommand(int s, const char * url, const char * service, - const char * action, struct UPNParg * args, - int * bufsize) -{ + const char * action, struct UPNParg * args, + int * bufsize) { char * buf; #if 1 buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1"); #else buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.0"); - if (!buf || *bufsize == 0) - { + if (!buf || *bufsize == 0) { #if DEBUG - printf("Error or no result from SOAP request; retrying with HTTP/1.1\n"); + printf("Error or no result from SOAP request; retrying with HTTP/1.1\n"); #endif buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1"); } @@ -236,54 +225,53 @@ char * simpleUPnPcommand(int s, const char * url, const char * service, * SHOULD be configurable. */ MINIUPNP_LIBSPEC struct UPNPDev * upnpDiscoverDevices(const char * const deviceTypes[], - int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error, - int searchalltypes) -{ + int delay, const char * multicastif, + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error, + int searchalltypes) { struct UPNPDev * tmp; struct UPNPDev * devlist = 0; #if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) int deviceIndex; #endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ - if(error) + if (error) *error = UPNPDISCOVER_UNKNOWN_ERROR; #if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) /* first try to get infos from minissdpd ! */ - if(!minissdpdsock) + if (!minissdpdsock) minissdpdsock = "/var/run/minissdpd.sock"; - for(deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) { + for (deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) { struct UPNPDev * minissdpd_devlist; int only_rootdevice = 1; minissdpd_devlist = getDevicesFromMiniSSDPD(deviceTypes[deviceIndex], - minissdpdsock, 0); - if(minissdpd_devlist) { + minissdpdsock, 0); + if (minissdpd_devlist) { #ifdef DEBUG printf("returned by MiniSSDPD: %s\t%s\n", - minissdpd_devlist->st, minissdpd_devlist->descURL); + minissdpd_devlist->st, minissdpd_devlist->descURL); #endif /* DEBUG */ - if(!strstr(minissdpd_devlist->st, "rootdevice")) + if (!strstr(minissdpd_devlist->st, "rootdevice")) only_rootdevice = 0; - for(tmp = minissdpd_devlist; tmp->pNext != NULL; tmp = tmp->pNext) { + for (tmp = minissdpd_devlist; tmp->pNext != NULL; tmp = tmp->pNext) { #ifdef DEBUG printf("returned by MiniSSDPD: %s\t%s\n", - tmp->pNext->st, tmp->pNext->descURL); + tmp->pNext->st, tmp->pNext->descURL); #endif /* DEBUG */ - if(!strstr(tmp->st, "rootdevice")) + if (!strstr(tmp->st, "rootdevice")) only_rootdevice = 0; } tmp->pNext = devlist; devlist = minissdpd_devlist; - if(!searchalltypes && !only_rootdevice) + if (!searchalltypes && !only_rootdevice) break; } } - for(tmp = devlist; tmp != NULL; tmp = tmp->pNext) { + for (tmp = devlist; tmp != NULL; tmp = tmp->pNext) { /* We return what we have found if it was not only a rootdevice */ - if(!strstr(tmp->st, "rootdevice")) { - if(error) + if (!strstr(tmp->st, "rootdevice")) { + if (error) *error = UPNPDISCOVER_SUCCESS; return devlist; } @@ -294,11 +282,11 @@ upnpDiscoverDevices(const char * const deviceTypes[], { struct UPNPDev * discovered_devlist; discovered_devlist = ssdpDiscoverDevices(deviceTypes, delay, multicastif, localport, - ipv6, ttl, error, searchalltypes); - if(devlist == NULL) + ipv6, ttl, error, searchalltypes); + if (devlist == NULL) devlist = discovered_devlist; else { - for(tmp = devlist; tmp->pNext != NULL; tmp = tmp->pNext); + for (tmp = devlist; tmp->pNext != NULL; tmp = tmp->pNext); tmp->pNext = discovered_devlist; } } @@ -308,10 +296,9 @@ upnpDiscoverDevices(const char * const deviceTypes[], /* upnpDiscover() Discover IGD device */ MINIUPNP_LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error) -{ + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error) { static const char * const deviceList[] = { #if 0 "urn:schemas-upnp-org:device:InternetGatewayDevice:2", @@ -325,47 +312,44 @@ upnpDiscover(int delay, const char * multicastif, 0 }; return upnpDiscoverDevices(deviceList, - delay, multicastif, minissdpdsock, localport, - ipv6, ttl, error, 0); + delay, multicastif, minissdpdsock, localport, + ipv6, ttl, error, 0); } /* upnpDiscoverAll() Discover all UPnP devices */ MINIUPNP_LIBSPEC struct UPNPDev * upnpDiscoverAll(int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error) -{ + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error) { static const char * const deviceList[] = { /*"upnp:rootdevice",*/ "ssdp:all", 0 }; return upnpDiscoverDevices(deviceList, - delay, multicastif, minissdpdsock, localport, - ipv6, ttl, error, 0); + delay, multicastif, minissdpdsock, localport, + ipv6, ttl, error, 0); } /* upnpDiscoverDevice() Discover a specific device */ MINIUPNP_LIBSPEC struct UPNPDev * upnpDiscoverDevice(const char * device, int delay, const char * multicastif, - const char * minissdpdsock, int localport, - int ipv6, unsigned char ttl, - int * error) -{ + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error) { const char * const deviceList[] = { device, 0 }; return upnpDiscoverDevices(deviceList, - delay, multicastif, minissdpdsock, localport, - ipv6, ttl, error, 0); + delay, multicastif, minissdpdsock, localport, + ipv6, ttl, error, 0); } static char * build_absolute_url(const char * baseurl, const char * descURL, - const char * url, unsigned int scope_id) -{ + const char * url, unsigned int scope_id) { int l, n; char * s; const char * base; @@ -376,27 +360,27 @@ build_absolute_url(const char * baseurl, const char * descURL, char scope_str[8]; #endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */ - if( (url[0] == 'h') - &&(url[1] == 't') - &&(url[2] == 't') - &&(url[3] == 'p') - &&(url[4] == ':') - &&(url[5] == '/') - &&(url[6] == '/')) + if ((url[0] == 'h') + && (url[1] == 't') + && (url[2] == 't') + && (url[3] == 'p') + && (url[4] == ':') + && (url[5] == '/') + && (url[6] == '/')) return strdup(url); base = (baseurl[0] == '\0') ? descURL : baseurl; n = strlen(base); - if(n > 7) { + if (n > 7) { p = strchr(base + 7, '/'); - if(p) + if (p) n = p - base; } l = n + strlen(url) + 1; - if(url[0] != '/') + if (url[0] != '/') l++; - if(scope_id != 0) { + if (scope_id != 0) { #if defined(IF_NAMESIZE) && !defined(_WIN32) - if(if_indextoname(scope_id, ifname)) { + if (if_indextoname(scope_id, ifname)) { l += 3 + strlen(ifname); /* 3 == strlen(%25) */ } #else /* defined(IF_NAMESIZE) && !defined(_WIN32) */ @@ -405,14 +389,14 @@ build_absolute_url(const char * baseurl, const char * descURL, #endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */ } s = malloc(l); - if(s == NULL) return NULL; + if (s == NULL) return NULL; memcpy(s, base, n); - if(scope_id != 0) { + if (scope_id != 0) { s[n] = '\0'; - if(0 == memcmp(s, "http://[fe80:", 13)) { + if (0 == memcmp(s, "http://[fe80:", 13)) { /* this is a linklocal IPv6 address */ p = strchr(s, ']'); - if(p) { + if (p) { /* insert %25 into URL */ #if defined(IF_NAMESIZE) && !defined(_WIN32) memmove(p + 3 + strlen(ifname), p, strlen(p) + 1); @@ -428,7 +412,7 @@ build_absolute_url(const char * baseurl, const char * descURL, } } } - if(url[0] != '/') + if (url[0] != '/') s[n++] = '/'; memcpy(s + n, url, l - n); return s; @@ -438,20 +422,19 @@ build_absolute_url(const char * baseurl, const char * descURL, */ MINIUPNP_LIBSPEC void GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data, - const char * descURL, unsigned int scope_id) -{ + const char * descURL, unsigned int scope_id) { /* strdup descURL */ urls->rootdescURL = strdup(descURL); /* get description of WANIPConnection */ urls->ipcondescURL = build_absolute_url(data->urlbase, descURL, - data->first.scpdurl, scope_id); + data->first.scpdurl, scope_id); urls->controlURL = build_absolute_url(data->urlbase, descURL, - data->first.controlurl, scope_id); + data->first.controlurl, scope_id); urls->controlURL_CIF = build_absolute_url(data->urlbase, descURL, - data->CIF.controlurl, scope_id); + data->CIF.controlurl, scope_id); urls->controlURL_6FC = build_absolute_url(data->urlbase, descURL, - data->IPv6FC.controlurl, scope_id); + data->IPv6FC.controlurl, scope_id); #ifdef DEBUG printf("urls->ipcondescURL='%s'\n", urls->ipcondescURL); @@ -462,9 +445,8 @@ GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data, } MINIUPNP_LIBSPEC void -FreeUPNPUrls(struct UPNPUrls * urls) -{ - if(!urls) +FreeUPNPUrls(struct UPNPUrls * urls) { + if (!urls) return; free(urls->controlURL); urls->controlURL = 0; @@ -479,16 +461,15 @@ FreeUPNPUrls(struct UPNPUrls * urls) } int -UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data) -{ +UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data) { char status[64]; unsigned int uptime; status[0] = '\0'; UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype, - status, &uptime, NULL); - if(0 == strcmp("Connected", status)) + status, &uptime, NULL); + if (0 == strcmp("Connected", status)) return 1; - else if(0 == strcmp("Up", status)) /* Also accept "Up" */ + else if (0 == strcmp("Up", status)) /* Also accept "Up" */ return 1; else return 0; @@ -510,111 +491,100 @@ UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data) */ MINIUPNP_LIBSPEC int UPNP_GetValidIGD(struct UPNPDev * devlist, - struct UPNPUrls * urls, - struct IGDdatas * data, - char * lanaddr, int lanaddrlen) -{ + struct UPNPUrls * urls, + struct IGDdatas * data, + char * lanaddr, int lanaddrlen) { struct xml_desc { char * xml; int size; int is_igd; - } * desc = NULL; + } *desc = NULL; struct UPNPDev * dev; int ndev = 0; int i; int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */ int n_igd = 0; char extIpAddr[16]; - if(!devlist) - { + if (!devlist) { #ifdef DEBUG printf("Empty devlist\n"); #endif return 0; } /* counting total number of devices in the list */ - for(dev = devlist; dev; dev = dev->pNext) + for (dev = devlist; dev; dev = dev->pNext) ndev++; - if(ndev > 0) - { + if (ndev > 0) { desc = calloc(ndev, sizeof(struct xml_desc)); - if(!desc) + if (!desc) return -1; /* memory allocation error */ } /* Step 1 : downloading descriptions and testing type */ - for(dev = devlist, i = 0; dev; dev = dev->pNext, i++) - { + for (dev = devlist, i = 0; dev; dev = dev->pNext, i++) { /* we should choose an internet gateway device. * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */ desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size), - lanaddr, lanaddrlen, - dev->scope_id); + lanaddr, lanaddrlen, + dev->scope_id); #ifdef DEBUG - if(!desc[i].xml) - { + if (!desc[i].xml) { printf("error getting XML description %s\n", dev->descURL); } #endif - if(desc[i].xml) - { + if (desc[i].xml) { memset(data, 0, sizeof(struct IGDdatas)); memset(urls, 0, sizeof(struct UPNPUrls)); parserootdesc(desc[i].xml, desc[i].size, data); - if(COMPARE(data->CIF.servicetype, - "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:")) - { + if (COMPARE(data->CIF.servicetype, + "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:")) { desc[i].is_igd = 1; n_igd++; } } } /* iterate the list to find a device depending on state */ - for(state = 1; state <= 3; state++) - { - for(dev = devlist, i = 0; dev; dev = dev->pNext, i++) - { - if(desc[i].xml) - { + for (state = 1; state <= 3; state++) { + for (dev = devlist, i = 0; dev; dev = dev->pNext, i++) { + if (desc[i].xml) { memset(data, 0, sizeof(struct IGDdatas)); memset(urls, 0, sizeof(struct UPNPUrls)); parserootdesc(desc[i].xml, desc[i].size, data); - if(desc[i].is_igd || state >= 3 ) - { - GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); + if (desc[i].is_igd || state >= 3) { + GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); - /* in state 2 and 3 we dont test if device is connected ! */ - if(state >= 2) - goto free_and_return; + /* in state 2 and 3 we dont test if device is connected ! */ + if (state >= 2) + goto free_and_return; #ifdef DEBUG - printf("UPNPIGD_IsConnected(%s) = %d\n", - urls->controlURL, - UPNPIGD_IsConnected(urls, data)); + printf("UPNPIGD_IsConnected(%s) = %d\n", + urls->controlURL, + UPNPIGD_IsConnected(urls, data)); #endif - /* checks that status is connected AND there is a external IP address assigned */ - if(UPNPIGD_IsConnected(urls, data) - && (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) - goto free_and_return; - FreeUPNPUrls(urls); - if(data->second.servicetype[0] != '\0') { + /* checks that status is connected AND there is a external IP address assigned */ + if (UPNPIGD_IsConnected(urls, data) + && (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) + goto free_and_return; + FreeUPNPUrls(urls); + if (data->second.servicetype[0] != '\0') { #ifdef DEBUG - printf("We tried %s, now we try %s !\n", - data->first.servicetype, data->second.servicetype); + printf("We tried %s, now we try %s !\n", + data->first.servicetype, data->second.servicetype); #endif - /* swaping WANPPPConnection and WANIPConnection ! */ - memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service)); - memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service)); - memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service)); - GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); + /* swaping WANPPPConnection and WANIPConnection ! */ + memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service)); + memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service)); + memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service)); + GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); #ifdef DEBUG - printf("UPNPIGD_IsConnected(%s) = %d\n", - urls->controlURL, - UPNPIGD_IsConnected(urls, data)); + printf("UPNPIGD_IsConnected(%s) = %d\n", + urls->controlURL, + UPNPIGD_IsConnected(urls, data)); #endif - if(UPNPIGD_IsConnected(urls, data) - && (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) - goto free_and_return; - FreeUPNPUrls(urls); - } + if (UPNPIGD_IsConnected(urls, data) + && (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) + goto free_and_return; + FreeUPNPUrls(urls); + } } memset(data, 0, sizeof(struct IGDdatas)); } @@ -622,9 +592,9 @@ UPNP_GetValidIGD(struct UPNPDev * devlist, } state = 0; free_and_return: - if(desc) { - for(i = 0; i < ndev; i++) { - if(desc[i].xml) { + if (desc) { + for (i = 0; i < ndev; i++) { + if (desc[i].xml) { free(desc[i].xml); } } @@ -640,15 +610,14 @@ free_and_return: * 1 - OK */ int UPNP_GetIGDFromUrl(const char * rootdescurl, - struct UPNPUrls * urls, - struct IGDdatas * data, - char * lanaddr, int lanaddrlen) -{ + struct UPNPUrls * urls, + struct IGDdatas * data, + char * lanaddr, int lanaddrlen) { char * descXML; int descXMLsize = 0; descXML = miniwget_getaddr(rootdescurl, &descXMLsize, - lanaddr, lanaddrlen, 0); - if(descXML) { + lanaddr, lanaddrlen, 0); + if (descXML) { memset(data, 0, sizeof(struct IGDdatas)); memset(urls, 0, sizeof(struct UPNPUrls)); parserootdesc(descXML, descXMLsize, data); diff --git a/source/shared_lib/sources/platform/miniupnpc/miniwget.c b/source/shared_lib/sources/platform/miniupnpc/miniwget.c index 3389b0afc..1cb8c5d1f 100644 --- a/source/shared_lib/sources/platform/miniupnpc/miniwget.c +++ b/source/shared_lib/sources/platform/miniupnpc/miniwget.c @@ -58,15 +58,14 @@ #define MAXHOSTNAMELEN 64 #endif -/* - * Read a HTTP response from a socket. - * Process Content-Length and Transfer-encoding headers. - * return a pointer to the content buffer, which length is saved - * to the length parameter. - */ + /* + * Read a HTTP response from a socket. + * Process Content-Length and Transfer-encoding headers. + * return a pointer to the content buffer, which length is saved + * to the length parameter. + */ void * -getHTTPResponse(int s, int * size) -{ +getHTTPResponse(int s, int * size) { char buf[2048]; int n; int endofheaders = 0; @@ -85,8 +84,7 @@ getHTTPResponse(int s, int * size) unsigned int chunksize_buf_index; header_buf = malloc(header_buf_len); - if(header_buf == NULL) - { + if (header_buf == NULL) { #ifdef DEBUG fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse"); #endif /* DEBUG */ @@ -94,8 +92,7 @@ getHTTPResponse(int s, int * size) return NULL; } content_buf = malloc(content_buf_len); - if(content_buf == NULL) - { + if (content_buf == NULL) { free(header_buf); #ifdef DEBUG fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse"); @@ -106,17 +103,15 @@ getHTTPResponse(int s, int * size) chunksize_buf[0] = '\0'; chunksize_buf_index = 0; - while((n = receivedata(s, buf, 2048, 5000, NULL)) > 0) - { - if(endofheaders == 0) - { + while ((n = receivedata(s, buf, 2048, 5000, NULL)) > 0) { + if (endofheaders == 0) { int i; - int linestart=0; - int colon=0; - int valuestart=0; - if(header_buf_used + n > header_buf_len) { + int linestart = 0; + int colon = 0; + int valuestart = 0; + if (header_buf_used + n > header_buf_len) { char * tmp = realloc(header_buf, header_buf_used + n); - if(tmp == NULL) { + if (tmp == NULL) { /* memory allocation error */ free(header_buf); free(content_buf); @@ -131,65 +126,59 @@ getHTTPResponse(int s, int * size) /* search for CR LF CR LF (end of headers) * recognize also LF LF */ i = 0; - while(i < ((int)header_buf_used-1) && (endofheaders == 0)) { - if(header_buf[i] == '\r') { + while (i < ((int) header_buf_used - 1) && (endofheaders == 0)) { + if (header_buf[i] == '\r') { i++; - if(header_buf[i] == '\n') { + if (header_buf[i] == '\n') { i++; - if(i < (int)header_buf_used && header_buf[i] == '\r') { + if (i < (int) header_buf_used && header_buf[i] == '\r') { i++; - if(i < (int)header_buf_used && header_buf[i] == '\n') { - endofheaders = i+1; + if (i < (int) header_buf_used && header_buf[i] == '\n') { + endofheaders = i + 1; } } } - } else if(header_buf[i] == '\n') { + } else if (header_buf[i] == '\n') { i++; - if(header_buf[i] == '\n') { - endofheaders = i+1; + if (header_buf[i] == '\n') { + endofheaders = i + 1; } } i++; } - if(endofheaders == 0) + if (endofheaders == 0) continue; /* parse header lines */ - for(i = 0; i < endofheaders - 1; i++) { - if(colon <= linestart && header_buf[i]==':') - { + for (i = 0; i < endofheaders - 1; i++) { + if (colon <= linestart && header_buf[i] == ':') { colon = i; - while(i < (endofheaders-1) - && (header_buf[i+1] == ' ' || header_buf[i+1] == '\t')) + while (i < (endofheaders - 1) + && (header_buf[i + 1] == ' ' || header_buf[i + 1] == '\t')) i++; valuestart = i + 1; } /* detecting end of line */ - else if(header_buf[i]=='\r' || header_buf[i]=='\n') - { - if(colon > linestart && valuestart > colon) - { + else if (header_buf[i] == '\r' || header_buf[i] == '\n') { + if (colon > linestart && valuestart > colon) { #ifdef DEBUG printf("header='%.*s', value='%.*s'\n", - colon-linestart, header_buf+linestart, - i-valuestart, header_buf+valuestart); + colon - linestart, header_buf + linestart, + i - valuestart, header_buf + valuestart); #endif - if(0==strncasecmp(header_buf+linestart, "content-length", colon-linestart)) - { - content_length = atoi(header_buf+valuestart); + if (0 == strncasecmp(header_buf + linestart, "content-length", colon - linestart)) { + content_length = atoi(header_buf + valuestart); #ifdef DEBUG printf("Content-Length: %d\n", content_length); #endif - } - else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart) - && 0==strncasecmp(header_buf+valuestart, "chunked", 7)) - { + } else if (0 == strncasecmp(header_buf + linestart, "transfer-encoding", colon - linestart) + && 0 == strncasecmp(header_buf + valuestart, "chunked", 7)) { #ifdef DEBUG printf("chunked transfer-encoding!\n"); #endif chunked = 1; } } - while((i < (int)header_buf_used) && (header_buf[i]=='\r' || header_buf[i] == '\n')) + while ((i < (int) header_buf_used) && (header_buf[i] == '\r' || header_buf[i] == '\n')) i++; linestart = i; colon = linestart; @@ -201,40 +190,35 @@ getHTTPResponse(int s, int * size) memcpy(buf, header_buf + endofheaders, n); /* if(headers) */ } - if(endofheaders) - { + if (endofheaders) { /* content */ - if(chunked) - { + if (chunked) { int i = 0; - while(i < n) - { - if(chunksize == 0) - { + while (i < n) { + if (chunksize == 0) { /* reading chunk size */ - if(chunksize_buf_index == 0) { + if (chunksize_buf_index == 0) { /* skipping any leading CR LF */ - if(i= '0' - && chunksize_buf[j] <= '9') - chunksize = (chunksize << 4) + (chunksize_buf[j] - '0'); - else - chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10); + for (j = 0; j < chunksize_buf_index; j++) { + if (chunksize_buf[j] >= '0' + && chunksize_buf[j] <= '9') + chunksize = (chunksize << 4) + (chunksize_buf[j] - '0'); + else + chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10); } chunksize_buf[0] = '\0'; chunksize_buf_index = 0; @@ -246,8 +230,7 @@ getHTTPResponse(int s, int * size) #ifdef DEBUG printf("chunksize = %u (%x)\n", chunksize, chunksize); #endif - if(chunksize == 0) - { + if (chunksize == 0) { #ifdef DEBUG printf("end of HTTP content - %d %d\n", i, n); /*printf("'%.*s'\n", n-i, buf+i);*/ @@ -255,17 +238,16 @@ getHTTPResponse(int s, int * size) goto end_of_stream; } } - bytestocopy = ((int)chunksize < (n - i))?chunksize:(unsigned int)(n - i); - if((content_buf_used + bytestocopy) > content_buf_len) - { + bytestocopy = ((int) chunksize < (n - i)) ? chunksize : (unsigned int) (n - i); + if ((content_buf_used + bytestocopy) > content_buf_len) { char * tmp; - if(content_length >= (int)(content_buf_used + bytestocopy)) { + if (content_length >= (int) (content_buf_used + bytestocopy)) { content_buf_len = content_length; } else { content_buf_len = content_buf_used + bytestocopy; } tmp = realloc(content_buf, content_buf_len); - if(tmp == NULL) { + if (tmp == NULL) { /* memory allocation error */ free(content_buf); free(header_buf); @@ -279,25 +261,22 @@ getHTTPResponse(int s, int * size) i += bytestocopy; chunksize -= bytestocopy; } - } - else - { + } else { /* not chunked */ - if(content_length > 0 - && (int)(content_buf_used + n) > content_length) { + if (content_length > 0 + && (int) (content_buf_used + n) > content_length) { /* skipping additional bytes */ n = content_length - content_buf_used; } - if(content_buf_used + n > content_buf_len) - { + if (content_buf_used + n > content_buf_len) { char * tmp; - if(content_length >= (int)(content_buf_used + n)) { + if (content_length >= (int) (content_buf_used + n)) { content_buf_len = content_length; } else { content_buf_len = content_buf_used + n; } tmp = realloc(content_buf, content_buf_len); - if(tmp == NULL) { + if (tmp == NULL) { /* memory allocation error */ free(content_buf); free(header_buf); @@ -311,8 +290,7 @@ getHTTPResponse(int s, int * size) } } /* use the Content-Length header value if available */ - if(content_length > 0 && (int)content_buf_used >= content_length) - { + if (content_length > 0 && (int) content_buf_used >= content_length) { #ifdef DEBUG printf("End of HTTP content\n"); #endif @@ -322,8 +300,7 @@ getHTTPResponse(int s, int * size) end_of_stream: free(header_buf); header_buf = NULL; *size = content_buf_used; - if(content_buf_used == 0) - { + if (content_buf_used == 0) { free(content_buf); content_buf = NULL; } @@ -335,12 +312,11 @@ end_of_stream: * Return NULL if something failed. */ static void * miniwget3(const char * host, - unsigned short port, const char * path, - int * size, char * addr_str, int addr_str_len, - const char * httpversion, unsigned int scope_id) -{ + unsigned short port, const char * path, + int * size, char * addr_str, int addr_str_len, + const char * httpversion, unsigned int scope_id) { char buf[2048]; - int s; + int s; int n; int len; int sent; @@ -348,51 +324,47 @@ miniwget3(const char * host, *size = 0; s = connecthostport(host, port, scope_id); - if(s < 0) + if (s < 0) return NULL; /* get address for caller ! */ - if(addr_str) - { + if (addr_str) { struct sockaddr_storage saddr; socklen_t saddrlen; saddrlen = sizeof(saddr); - if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0) - { + if (getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0) { perror("getsockname"); - } - else - { + } else { #if defined(__amigaos__) && !defined(__amigaos4__) - /* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD); - * But his function make a string with the port : nn.nn.nn.nn:port */ -/* if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr), - NULL, addr_str, (DWORD *)&addr_str_len)) - { - printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError()); - }*/ - /* the following code is only compatible with ip v4 addresses */ + /* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD); + * But his function make a string with the port : nn.nn.nn.nn:port */ + /* if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr), + NULL, addr_str, (DWORD *)&addr_str_len)) + { + printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError()); + }*/ + /* the following code is only compatible with ip v4 addresses */ strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len); #else #if 0 - if(saddr.sa_family == AF_INET6) { + if (saddr.sa_family == AF_INET6) { inet_ntop(AF_INET6, - &(((struct sockaddr_in6 *)&saddr)->sin6_addr), - addr_str, addr_str_len); + &(((struct sockaddr_in6 *)&saddr)->sin6_addr), + addr_str, addr_str_len); } else { inet_ntop(AF_INET, - &(((struct sockaddr_in *)&saddr)->sin_addr), - addr_str, addr_str_len); + &(((struct sockaddr_in *)&saddr)->sin_addr), + addr_str, addr_str_len); } #endif /* getnameinfo return ip v6 address with the scope identifier * such as : 2a01:e35:8b2b:7330::%4281128194 */ n = getnameinfo((const struct sockaddr *)&saddr, saddrlen, - addr_str, addr_str_len, - NULL, 0, - NI_NUMERICHOST | NI_NUMERICSERV); - if(n != 0) { + addr_str, addr_str_len, + NULL, 0, + NI_NUMERICHOST | NI_NUMERICSERV); + if (n != 0) { #ifdef _WIN32 fprintf(stderr, "getnameinfo() failed : %d\n", n); #else @@ -407,26 +379,22 @@ miniwget3(const char * host, } len = snprintf(buf, sizeof(buf), - "GET %s HTTP/%s\r\n" - "Host: %s:%d\r\n" - "Connection: Close\r\n" - "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" + "GET %s HTTP/%s\r\n" + "Host: %s:%d\r\n" + "Connection: Close\r\n" + "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" - "\r\n", - path, httpversion, host, port); + "\r\n", + path, httpversion, host, port); sent = 0; /* sending the HTTP request */ - while(sent < len) - { - n = send(s, buf+sent, len-sent, 0); - if(n < 0) - { + while (sent < len) { + n = send(s, buf + sent, len - sent, 0); + if (n < 0) { perror("send"); closesocket(s); return NULL; - } - else - { + } else { sent += n; } } @@ -439,26 +407,24 @@ miniwget3(const char * host, * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */ static void * miniwget2(const char * host, - unsigned short port, const char * path, - int * size, char * addr_str, int addr_str_len, - unsigned int scope_id) -{ + unsigned short port, const char * path, + int * size, char * addr_str, int addr_str_len, + unsigned int scope_id) { char * respbuffer; #if 1 respbuffer = miniwget3(host, port, path, size, - addr_str, addr_str_len, "1.1", scope_id); + addr_str, addr_str_len, "1.1", scope_id); #else respbuffer = miniwget3(host, port, path, size, - addr_str, addr_str_len, "1.0", scope_id); - if (*size == 0) - { + addr_str, addr_str_len, "1.0", scope_id); + if (*size == 0) { #ifdef DEBUG printf("Retrying with HTTP/1.1\n"); #endif free(respbuffer); respbuffer = miniwget3(host, port, path, size, - addr_str, addr_str_len, "1.1", scope_id); + addr_str, addr_str_len, "1.1", scope_id); } #endif return respbuffer; @@ -479,43 +445,41 @@ miniwget2(const char * host, * 1 - Success */ int parseURL(const char * url, - char * hostname, unsigned short * port, - char * * path, unsigned int * scope_id) -{ + char * hostname, unsigned short * port, + char * * path, unsigned int * scope_id) { char * p1, *p2, *p3; - if(!url) + if (!url) return 0; p1 = strstr(url, "://"); - if(!p1) + if (!p1) return 0; p1 += 3; - if( (url[0]!='h') || (url[1]!='t') - ||(url[2]!='t') || (url[3]!='p')) + if ((url[0] != 'h') || (url[1] != 't') + || (url[2] != 't') || (url[3] != 'p')) return 0; memset(hostname, 0, MAXHOSTNAMELEN + 1); - if(*p1 == '[') - { + if (*p1 == '[') { /* IP v6 : http://[2a00:1450:8002::6a]/path/abc */ char * scope; scope = strchr(p1, '%'); p2 = strchr(p1, ']'); - if(p2 && scope && scope < p2 && scope_id) { + if (p2 && scope && scope < p2 && scope_id) { /* parse scope */ #ifdef IF_NAMESIZE char tmp[IF_NAMESIZE]; int l; scope++; /* "%25" is just '%' in URL encoding */ - if(scope[0] == '2' && scope[1] == '5') + if (scope[0] == '2' && scope[1] == '5') scope += 2; /* skip "25" */ l = p2 - scope; - if(l >= IF_NAMESIZE) + if (l >= IF_NAMESIZE) l = IF_NAMESIZE - 1; memcpy(tmp, scope, l); tmp[l] = '\0'; *scope_id = if_nametoindex(tmp); - if(*scope_id == 0) { - *scope_id = (unsigned int)strtoul(tmp, NULL, 10); + if (*scope_id == 0) { + *scope_id = (unsigned int) strtoul(tmp, NULL, 10); } #else /* under windows, scope is numerical */ @@ -523,34 +487,29 @@ parseURL(const char * url, int l; scope++; /* "%25" is just '%' in URL encoding */ - if(scope[0] == '2' && scope[1] == '5') + if (scope[0] == '2' && scope[1] == '5') scope += 2; /* skip "25" */ l = p2 - scope; - if(l >= sizeof(tmp)) + if (l >= sizeof(tmp)) l = sizeof(tmp) - 1; memcpy(tmp, scope, l); tmp[l] = '\0'; - *scope_id = (unsigned int)strtoul(tmp, NULL, 10); + *scope_id = (unsigned int) strtoul(tmp, NULL, 10); #endif } p3 = strchr(p1, '/'); - if(p2 && p3) - { + if (p2 && p3) { p2++; - strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1))); - if(*p2 == ':') - { + strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int) (p2 - p1))); + if (*p2 == ':') { *port = 0; p2++; - while( (*p2 >= '0') && (*p2 <= '9')) - { + while ((*p2 >= '0') && (*p2 <= '9')) { *port *= 10; - *port += (unsigned short)(*p2 - '0'); + *port += (unsigned short) (*p2 - '0'); p2++; } - } - else - { + } else { *port = 80; } *path = p3; @@ -559,22 +518,18 @@ parseURL(const char * url, } p2 = strchr(p1, ':'); p3 = strchr(p1, '/'); - if(!p3) + if (!p3) return 0; - if(!p2 || (p2>p3)) - { - strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1))); + if (!p2 || (p2 > p3)) { + strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int) (p3 - p1))); *port = 80; - } - else - { - strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1))); + } else { + strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int) (p2 - p1))); *port = 0; p2++; - while( (*p2 >= '0') && (*p2 <= '9')) - { + while ((*p2 >= '0') && (*p2 <= '9')) { *port *= 10; - *port += (unsigned short)(*p2 - '0'); + *port += (unsigned short) (*p2 - '0'); p2++; } } @@ -583,38 +538,36 @@ parseURL(const char * url, } void * -miniwget(const char * url, int * size, unsigned int scope_id) -{ +miniwget(const char * url, int * size, unsigned int scope_id) { unsigned short port; char * path; /* protocol://host:port/chemin */ - char hostname[MAXHOSTNAMELEN+1]; + char hostname[MAXHOSTNAMELEN + 1]; *size = 0; - if(!parseURL(url, hostname, &port, &path, &scope_id)) + if (!parseURL(url, hostname, &port, &path, &scope_id)) return NULL; #ifdef DEBUG printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", - hostname, port, path, scope_id); + hostname, port, path, scope_id); #endif return miniwget2(hostname, port, path, size, 0, 0, scope_id); } void * miniwget_getaddr(const char * url, int * size, - char * addr, int addrlen, unsigned int scope_id) -{ + char * addr, int addrlen, unsigned int scope_id) { unsigned short port; char * path; /* protocol://host:port/path */ - char hostname[MAXHOSTNAMELEN+1]; + char hostname[MAXHOSTNAMELEN + 1]; *size = 0; - if(addr) + if (addr) addr[0] = '\0'; - if(!parseURL(url, hostname, &port, &path, &scope_id)) + if (!parseURL(url, hostname, &port, &path, &scope_id)) return NULL; #ifdef DEBUG printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", - hostname, port, path, scope_id); + hostname, port, path, scope_id); #endif return miniwget2(hostname, port, path, size, addr, addrlen, scope_id); } diff --git a/source/shared_lib/sources/platform/miniupnpc/minixml.c b/source/shared_lib/sources/platform/miniupnpc/minixml.c index 3e201ec2c..50f4891ce 100644 --- a/source/shared_lib/sources/platform/miniupnpc/minixml.c +++ b/source/shared_lib/sources/platform/miniupnpc/minixml.c @@ -10,12 +10,12 @@ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * The name of the author may not be used to endorse or promote products + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" @@ -36,68 +36,57 @@ POSSIBILITY OF SUCH DAMAGE. /* parseatt : used to parse the argument list * return 0 (false) in case of success and -1 (true) if the end * of the xmlbuffer is reached. */ -static int parseatt(struct xmlparser * p) -{ +static int parseatt(struct xmlparser * p) { const char * attname; int attnamelen; const char * attvalue; int attvaluelen; - while(p->xml < p->xmlend) - { - if(*p->xml=='/' || *p->xml=='>') + while (p->xml < p->xmlend) { + if (*p->xml == '/' || *p->xml == '>') return 0; - if( !IS_WHITE_SPACE(*p->xml) ) - { + if (!IS_WHITE_SPACE(*p->xml)) { char sep; attname = p->xml; attnamelen = 0; - while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) ) - { + while (*p->xml != '=' && !IS_WHITE_SPACE(*p->xml)) { attnamelen++; p->xml++; - if(p->xml >= p->xmlend) + if (p->xml >= p->xmlend) return -1; } - while(*(p->xml++) != '=') - { - if(p->xml >= p->xmlend) + while (*(p->xml++) != '=') { + if (p->xml >= p->xmlend) return -1; } - while(IS_WHITE_SPACE(*p->xml)) - { + while (IS_WHITE_SPACE(*p->xml)) { p->xml++; - if(p->xml >= p->xmlend) + if (p->xml >= p->xmlend) return -1; } sep = *p->xml; - if(sep=='\'' || sep=='\"') - { + if (sep == '\'' || sep == '\"') { p->xml++; - if(p->xml >= p->xmlend) + if (p->xml >= p->xmlend) return -1; attvalue = p->xml; attvaluelen = 0; - while(*p->xml != sep) - { + while (*p->xml != sep) { attvaluelen++; p->xml++; - if(p->xml >= p->xmlend) + if (p->xml >= p->xmlend) return -1; } - } - else - { + } else { attvalue = p->xml; attvaluelen = 0; - while( !IS_WHITE_SPACE(*p->xml) - && *p->xml != '>' && *p->xml != '/') - { + while (!IS_WHITE_SPACE(*p->xml) + && *p->xml != '>' && *p->xml != '/') { attvaluelen++; p->xml++; - if(p->xml >= p->xmlend) + if (p->xml >= p->xmlend) return -1; } } /*printf("%.*s='%.*s'\n", - attnamelen, attname, attvaluelen, attvalue);*/ - if(p->attfunc) + attnamelen, attname, attvaluelen, attvalue);*/ + if (p->attfunc) p->attfunc(p->data, attname, attnamelen, attvalue, attvaluelen); } p->xml++; @@ -107,120 +96,96 @@ static int parseatt(struct xmlparser * p) /* parseelt parse the xml stream and * call the callback functions when needed... */ -static void parseelt(struct xmlparser * p) -{ +static void parseelt(struct xmlparser * p) { int i; const char * elementname; - while(p->xml < (p->xmlend - 1)) - { - if((p->xml + 4) <= p->xmlend && (0 == memcmp(p->xml, "", 3) != 0); + } while (memcmp(p->xml, "-->", 3) != 0); p->xml += 3; - } - else if((p->xml)[0]=='<' && (p->xml)[1]!='?') - { + } else if ((p->xml)[0] == '<' && (p->xml)[1] != '?') { i = 0; elementname = ++p->xml; - while( !IS_WHITE_SPACE(*p->xml) - && (*p->xml!='>') && (*p->xml!='/') - ) - { + while (!IS_WHITE_SPACE(*p->xml) + && (*p->xml != '>') && (*p->xml != '/') + ) { i++; p->xml++; if (p->xml >= p->xmlend) return; /* to ignore namespace : */ - if(*p->xml==':') - { + if (*p->xml == ':') { i = 0; elementname = ++p->xml; } } - if(i>0) - { - if(p->starteltfunc) + if (i > 0) { + if (p->starteltfunc) p->starteltfunc(p->data, elementname, i); - if(parseatt(p)) + if (parseatt(p)) return; - if(*p->xml!='/') - { + if (*p->xml != '/') { const char * data; i = 0; data = ++p->xml; if (p->xml >= p->xmlend) return; - while( IS_WHITE_SPACE(*p->xml) ) - { + while (IS_WHITE_SPACE(*p->xml)) { i++; p->xml++; if (p->xml >= p->xmlend) return; } - if(memcmp(p->xml, "xml, "xml += 9; data = p->xml; i = 0; - while(memcmp(p->xml, "]]>", 3) != 0) - { + while (memcmp(p->xml, "]]>", 3) != 0) { i++; p->xml++; if ((p->xml + 3) >= p->xmlend) return; } - if(i>0 && p->datafunc) + if (i > 0 && p->datafunc) p->datafunc(p->data, data, i); - while(*p->xml!='<') - { + while (*p->xml != '<') { p->xml++; if (p->xml >= p->xmlend) return; } - } - else - { - while(*p->xml!='<') - { + } else { + while (*p->xml != '<') { i++; p->xml++; if ((p->xml + 1) >= p->xmlend) return; } - if(i>0 && p->datafunc && *(p->xml + 1) == '/') + if (i > 0 && p->datafunc && *(p->xml + 1) == '/') p->datafunc(p->data, data, i); } } - } - else if(*p->xml == '/') - { + } else if (*p->xml == '/') { i = 0; elementname = ++p->xml; if (p->xml >= p->xmlend) return; - while((*p->xml != '>')) - { + while ((*p->xml != '>')) { i++; p->xml++; if (p->xml >= p->xmlend) return; } - if(p->endeltfunc) + if (p->endeltfunc) p->endeltfunc(p->data, elementname, i); p->xml++; } - } - else - { + } else { p->xml++; } } } /* the parser must be initialized before calling this function */ -void parsexml(struct xmlparser * parser) -{ +void parsexml(struct xmlparser * parser) { parser->xml = parser->xmlstart; parser->xmlend = parser->xmlstart + parser->xmlsize; parseelt(parser); diff --git a/source/shared_lib/sources/platform/miniupnpc/minixmlvalid.c b/source/shared_lib/sources/platform/miniupnpc/minixmlvalid.c index dad148812..a3c7faa67 100644 --- a/source/shared_lib/sources/platform/miniupnpc/minixmlvalid.c +++ b/source/shared_lib/sources/platform/miniupnpc/minixmlvalid.c @@ -11,9 +11,11 @@ #include #include "minixml.h" -/* xml event structure */ + /* xml event structure */ struct event { - enum { ELTSTART, ELTEND, ATT, CHARDATA } type; + enum { + ELTSTART, ELTEND, ATT, CHARDATA + } type; const char * data; int len; }; @@ -25,26 +27,22 @@ struct eventlist { /* compare 2 xml event lists * return 0 if the two lists are equals */ -int evtlistcmp(struct eventlist * a, struct eventlist * b) -{ +int evtlistcmp(struct eventlist * a, struct eventlist * b) { int i; - struct event * ae, * be; - if(a->n != b->n) - { + struct event * ae, *be; + if (a->n != b->n) { printf("event number not matching : %d != %d\n", a->n, b->n); /*return 1;*/ } - for(i=0; in; i++) - { + for (i = 0; i < a->n; i++) { ae = a->events + i; be = b->events + i; - if( (ae->type != be->type) - ||(ae->len != be->len) - ||memcmp(ae->data, be->data, ae->len)) - { + if ((ae->type != be->type) + || (ae->len != be->len) + || memcmp(ae->data, be->data, ae->len)) { printf("Found a difference : %d '%.*s' != %d '%.*s'\n", - ae->type, ae->len, ae->data, - be->type, be->len, be->data); + ae->type, ae->len, ae->data, + be->type, be->len, be->data); return 1; } } @@ -84,8 +82,7 @@ static const struct event evtref[] = {ELTEND, "xmlroot", 7} }; -void startelt(void * data, const char * p, int l) -{ +void startelt(void * data, const char * p, int l) { struct eventlist * evtlist = data; struct event * evt; evt = evtlist->events + evtlist->n; @@ -96,8 +93,7 @@ void startelt(void * data, const char * p, int l) evtlist->n++; } -void endelt(void * data, const char * p, int l) -{ +void endelt(void * data, const char * p, int l) { struct eventlist * evtlist = data; struct event * evt; evt = evtlist->events + evtlist->n; @@ -108,8 +104,7 @@ void endelt(void * data, const char * p, int l) evtlist->n++; } -void chardata(void * data, const char * p, int l) -{ +void chardata(void * data, const char * p, int l) { struct eventlist * evtlist = data; struct event * evt; evt = evtlist->events + evtlist->n; @@ -120,16 +115,14 @@ void chardata(void * data, const char * p, int l) evtlist->n++; } -int testxmlparser(const char * xml, int size) -{ +int testxmlparser(const char * xml, int size) { int r; struct eventlist evtlist; struct eventlist evtlistref; struct xmlparser parser; evtlist.n = 0; - evtlist.events = malloc(sizeof(struct event)*100); - if(evtlist.events == NULL) - { + evtlist.events = malloc(sizeof(struct event) * 100); + if (evtlist.events == NULL) { fprintf(stderr, "Memory allocation error.\n"); return -1; } @@ -143,20 +136,19 @@ int testxmlparser(const char * xml, int size) parsexml(&parser); printf("%d events\n", evtlist.n); /* compare */ - evtlistref.n = sizeof(evtref)/sizeof(struct event); + evtlistref.n = sizeof(evtref) / sizeof(struct event); evtlistref.events = (struct event *)evtref; r = evtlistcmp(&evtlistref, &evtlist); free(evtlist.events); return r; } -int main(int argc, char * * argv) -{ +int main(int argc, char * * argv) { int r; - (void)argc; (void)argv; + (void) argc; (void) argv; - r = testxmlparser(xmldata, sizeof(xmldata)-1); - if(r) + r = testxmlparser(xmldata, sizeof(xmldata) - 1); + if (r) printf("minixml validation test failed\n"); return r; } diff --git a/source/shared_lib/sources/platform/miniupnpc/portlistingparse.c b/source/shared_lib/sources/platform/miniupnpc/portlistingparse.c index 0e0927803..115682092 100644 --- a/source/shared_lib/sources/platform/miniupnpc/portlistingparse.c +++ b/source/shared_lib/sources/platform/miniupnpc/portlistingparse.c @@ -12,7 +12,7 @@ #include "portlistingparse.h" #include "minixml.h" -/* list of the elements */ + /* list of the elements */ static const struct { const portMappingElt code; const char * const str; @@ -31,13 +31,11 @@ static const struct { /* Helper function */ static UNSIGNED_INTEGER -atoui(const char * p, int l) -{ +atoui(const char * p, int l) { UNSIGNED_INTEGER r = 0; - while(l > 0 && *p) - { - if(*p >= '0' && *p <= '9') - r = r*10 + (*p - '0'); + while (l > 0 && *p) { + if (*p >= '0' && *p <= '9') + r = r * 10 + (*p - '0'); else break; p++; @@ -48,29 +46,24 @@ atoui(const char * p, int l) /* Start element handler */ static void -startelt(void * d, const char * name, int l) -{ +startelt(void * d, const char * name, int l) { int i; struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; pdata->curelt = PortMappingEltNone; - for(i = 0; elements[i].str; i++) - { - if(memcmp(name, elements[i].str, l) == 0) - { + for (i = 0; elements[i].str; i++) { + if (memcmp(name, elements[i].str, l) == 0) { pdata->curelt = elements[i].code; break; } } - if(pdata->curelt == PortMappingEntry) - { + if (pdata->curelt == PortMappingEntry) { struct PortMapping * pm; pm = calloc(1, sizeof(struct PortMapping)); - if(pm == NULL) - { + if (pm == NULL) { /* malloc error */ #ifdef DEBUG fprintf(stderr, "%s: error allocating memory", - "startelt"); + "startelt"); #endif /* DEBUG */ return; } @@ -81,59 +74,56 @@ startelt(void * d, const char * name, int l) /* End element handler */ static void -endelt(void * d, const char * name, int l) -{ +endelt(void * d, const char * name, int l) { struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; - (void)name; - (void)l; + (void) name; + (void) l; pdata->curelt = PortMappingEltNone; } /* Data handler */ static void -data(void * d, const char * data, int l) -{ +data(void * d, const char * data, int l) { struct PortMapping * pm; struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; pm = pdata->l_head; - if(!pm) + if (!pm) return; - if(l > 63) + if (l > 63) l = 63; - switch(pdata->curelt) - { - case NewRemoteHost: - memcpy(pm->remoteHost, data, l); - pm->remoteHost[l] = '\0'; - break; - case NewExternalPort: - pm->externalPort = (unsigned short)atoui(data, l); - break; - case NewProtocol: - if(l > 3) - l = 3; - memcpy(pm->protocol, data, l); - pm->protocol[l] = '\0'; - break; - case NewInternalPort: - pm->internalPort = (unsigned short)atoui(data, l); - break; - case NewInternalClient: - memcpy(pm->internalClient, data, l); - pm->internalClient[l] = '\0'; - break; - case NewEnabled: - pm->enabled = (unsigned char)atoui(data, l); - break; - case NewDescription: - memcpy(pm->description, data, l); - pm->description[l] = '\0'; - break; - case NewLeaseTime: - pm->leaseTime = atoui(data, l); - break; - default: - break; + switch (pdata->curelt) { + case NewRemoteHost: + memcpy(pm->remoteHost, data, l); + pm->remoteHost[l] = '\0'; + break; + case NewExternalPort: + pm->externalPort = (unsigned short) atoui(data, l); + break; + case NewProtocol: + if (l > 3) + l = 3; + memcpy(pm->protocol, data, l); + pm->protocol[l] = '\0'; + break; + case NewInternalPort: + pm->internalPort = (unsigned short) atoui(data, l); + break; + case NewInternalClient: + memcpy(pm->internalClient, data, l); + pm->internalClient[l] = '\0'; + break; + case NewEnabled: + pm->enabled = (unsigned char) atoui(data, l); + break; + case NewDescription: + memcpy(pm->description, data, l); + pm->description[l] = '\0'; + break; + case NewLeaseTime: + pm->leaseTime = atoui(data, l); + break; + default: + break; } } @@ -142,8 +132,7 @@ data(void * d, const char * data, int l) */ void ParsePortListing(const char * buffer, int bufsize, - struct PortMappingParserData * pdata) -{ + struct PortMappingParserData * pdata) { struct xmlparser parser; memset(pdata, 0, sizeof(struct PortMappingParserData)); @@ -159,11 +148,9 @@ ParsePortListing(const char * buffer, int bufsize, } void -FreePortListing(struct PortMappingParserData * pdata) -{ +FreePortListing(struct PortMappingParserData * pdata) { struct PortMapping * pm; - while((pm = pdata->l_head) != NULL) - { + while ((pm = pdata->l_head) != NULL) { /* remove from list */ pdata->l_head = pm->l_next; free(pm); diff --git a/source/shared_lib/sources/platform/miniupnpc/receivedata.c b/source/shared_lib/sources/platform/miniupnpc/receivedata.c index fb05e09db..62c1f6e3a 100644 --- a/source/shared_lib/sources/platform/miniupnpc/receivedata.c +++ b/source/shared_lib/sources/platform/miniupnpc/receivedata.c @@ -37,57 +37,56 @@ int receivedata(int socket, - char * data, int length, - int timeout, unsigned int * scope_id) -{ + char * data, int length, + int timeout, unsigned int * scope_id) { #if MINIUPNPC_GET_SRC_ADDR struct sockaddr_storage src_addr; socklen_t src_addr_len = sizeof(src_addr); #endif /* MINIUPNPC_GET_SRC_ADDR */ - int n; + int n; #if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) /* using poll */ - struct pollfd fds[1]; /* for the poll */ + struct pollfd fds[1]; /* for the poll */ #ifdef MINIUPNPC_IGNORE_EINTR - do { + do { #endif /* MINIUPNPC_IGNORE_EINTR */ - fds[0].fd = socket; - fds[0].events = POLLIN; - n = poll(fds, 1, timeout); + fds[0].fd = socket; + fds[0].events = POLLIN; + n = poll(fds, 1, timeout); #ifdef MINIUPNPC_IGNORE_EINTR - } while(n < 0 && errno == EINTR); + } while (n < 0 && errno == EINTR); #endif /* MINIUPNPC_IGNORE_EINTR */ - if(n < 0) { - PRINT_SOCKET_ERROR("poll"); - return -1; - } else if(n == 0) { + if (n < 0) { + PRINT_SOCKET_ERROR("poll"); + return -1; + } else if (n == 0) { /* timeout */ - return 0; - } + return 0; + } #else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ /* using select under _WIN32 and amigaos */ - fd_set socketSet; - TIMEVAL timeval; - FD_ZERO(&socketSet); - FD_SET(socket, &socketSet); - timeval.tv_sec = timeout / 1000; - timeval.tv_usec = (timeout % 1000) * 1000; - n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval); - if(n < 0) { - PRINT_SOCKET_ERROR("select"); - return -1; - } else if(n == 0) { - return 0; - } + fd_set socketSet; + TIMEVAL timeval; + FD_ZERO(&socketSet); + FD_SET(socket, &socketSet); + timeval.tv_sec = timeout / 1000; + timeval.tv_usec = (timeout % 1000) * 1000; + n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval); + if (n < 0) { + PRINT_SOCKET_ERROR("select"); + return -1; + } else if (n == 0) { + return 0; + } #endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ #if MINIUPNPC_GET_SRC_ADDR memset(&src_addr, 0, sizeof(src_addr)); n = recvfrom(socket, data, length, 0, - (struct sockaddr *)&src_addr, &src_addr_len); + (struct sockaddr *)&src_addr, &src_addr_len); #else /* MINIUPNPC_GET_SRC_ADDR */ n = recv(socket, data, length, 0); #endif /* MINIUPNPC_GET_SRC_ADDR */ - if(n<0) { + if (n < 0) { PRINT_SOCKET_ERROR("recv"); } #if MINIUPNPC_GET_SRC_ADDR @@ -96,7 +95,7 @@ receivedata(int socket, #ifdef DEBUG printf("scope_id=%u\n", src_addr6->sin6_scope_id); #endif /* DEBUG */ - if(scope_id) + if (scope_id) *scope_id = src_addr6->sin6_scope_id; } #endif /* MINIUPNPC_GET_SRC_ADDR */ diff --git a/source/shared_lib/sources/platform/miniupnpc/upnpc.c b/source/shared_lib/sources/platform/miniupnpc/upnpc.c index 8bc552efe..9fabe550e 100644 --- a/source/shared_lib/sources/platform/miniupnpc/upnpc.c +++ b/source/shared_lib/sources/platform/miniupnpc/upnpc.c @@ -13,7 +13,7 @@ #include #define snprintf _snprintf #else -/* for IPPROTO_TCP / IPPROTO_UDP */ + /* for IPPROTO_TCP / IPPROTO_UDP */ #include #endif #include @@ -25,20 +25,19 @@ /* protofix() checks if protocol is "UDP" or "TCP" * returns NULL if not */ -const char * protofix(const char * proto) -{ - static const char proto_tcp[4] = { 'T', 'C', 'P', 0}; - static const char proto_udp[4] = { 'U', 'D', 'P', 0}; +const char * protofix(const char * proto) { + static const char proto_tcp[4] = { 'T', 'C', 'P', 0 }; + static const char proto_udp[4] = { 'U', 'D', 'P', 0 }; int i, b; - for(i=0, b=1; i<4; i++) - b = b && ( (proto[i] == proto_tcp[i]) - || (proto[i] == (proto_tcp[i] | 32)) ); - if(b) + for (i = 0, b = 1; i < 4; i++) + b = b && ((proto[i] == proto_tcp[i]) + || (proto[i] == (proto_tcp[i] | 32))); + if (b) return proto_tcp; - for(i=0, b=1; i<4; i++) - b = b && ( (proto[i] == proto_udp[i]) - || (proto[i] == (proto_udp[i] | 32)) ); - if(b) + for (i = 0, b = 1; i < 4; i++) + b = b && ((proto[i] == proto_udp[i]) + || (proto[i] == (proto_udp[i] | 32))); + if (b) return proto_udp; return 0; } @@ -46,13 +45,12 @@ const char * protofix(const char * proto) /* is_int() checks if parameter is an integer or not * 1 for integer * 0 for not an integer */ -int is_int(char const* s) -{ - if(s == NULL) +int is_int(char const* s) { + if (s == NULL) return 0; - while(*s) { + while (*s) { /* #define isdigit(c) ((c) >= '0' && (c) <= '9') */ - if(!isdigit(*s)) + if (!isdigit(*s)) return 0; s++; } @@ -60,8 +58,7 @@ int is_int(char const* s) } static void DisplayInfos(struct UPNPUrls * urls, - struct IGDdatas * data) -{ + struct IGDdatas * data) { char externalIPAddress[40]; char connectionType[64]; char status[64]; @@ -70,43 +67,43 @@ static void DisplayInfos(struct UPNPUrls * urls, unsigned int brUp, brDown; time_t timenow, timestarted; int r; - if(UPNP_GetConnectionTypeInfo(urls->controlURL, - data->first.servicetype, - connectionType) != UPNPCOMMAND_SUCCESS) + if (UPNP_GetConnectionTypeInfo(urls->controlURL, + data->first.servicetype, + connectionType) != UPNPCOMMAND_SUCCESS) printf("GetConnectionTypeInfo failed.\n"); else printf("Connection Type : %s\n", connectionType); - if(UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype, - status, &uptime, lastconnerr) != UPNPCOMMAND_SUCCESS) + if (UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype, + status, &uptime, lastconnerr) != UPNPCOMMAND_SUCCESS) printf("GetStatusInfo failed.\n"); else printf("Status : %s, uptime=%us, LastConnectionError : %s\n", - status, uptime, lastconnerr); + status, uptime, lastconnerr); timenow = time(NULL); timestarted = timenow - uptime; printf(" Time started : %s", ctime(×tarted)); - if(UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype, - &brDown, &brUp) != UPNPCOMMAND_SUCCESS) { + if (UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype, + &brDown, &brUp) != UPNPCOMMAND_SUCCESS) { printf("GetLinkLayerMaxBitRates failed.\n"); } else { printf("MaxBitRateDown : %u bps", brDown); - if(brDown >= 1000000) { + if (brDown >= 1000000) { printf(" (%u.%u Mbps)", brDown / 1000000, (brDown / 100000) % 10); - } else if(brDown >= 1000) { + } else if (brDown >= 1000) { printf(" (%u Kbps)", brDown / 1000); } printf(" MaxBitRateUp %u bps", brUp); - if(brUp >= 1000000) { + if (brUp >= 1000000) { printf(" (%u.%u Mbps)", brUp / 1000000, (brUp / 100000) % 10); - } else if(brUp >= 1000) { + } else if (brUp >= 1000) { printf(" (%u Kbps)", brUp / 1000); } printf("\n"); } r = UPNP_GetExternalIPAddress(urls->controlURL, - data->first.servicetype, - externalIPAddress); - if(r != UPNPCOMMAND_SUCCESS) { + data->first.servicetype, + externalIPAddress); + if (r != UPNPCOMMAND_SUCCESS) { printf("GetExternalIPAddress failed. (errorcode=%d)\n", r); } else { printf("ExternalIPAddress = %s\n", externalIPAddress); @@ -114,8 +111,7 @@ static void DisplayInfos(struct UPNPUrls * urls, } static void GetConnectionStatus(struct UPNPUrls * urls, - struct IGDdatas * data) -{ + struct IGDdatas * data) { unsigned int bytessent, bytesreceived, packetsreceived, packetssent; DisplayInfos(urls, data); bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype); @@ -127,8 +123,7 @@ static void GetConnectionStatus(struct UPNPUrls * urls, } static void ListRedirections(struct UPNPUrls * urls, - struct IGDdatas * data) -{ + struct IGDdatas * data) { int r; int i = 0; char index[6]; @@ -150,32 +145,31 @@ static void ListRedirections(struct UPNPUrls * urls, duration[0] = '\0'; desc[0] = '\0'; extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0'; r = UPNP_GetGenericPortMappingEntry(urls->controlURL, - data->first.servicetype, - index, - extPort, intClient, intPort, - protocol, desc, enabled, - rHost, duration); - if(r==0) - /* - printf("%02d - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n" - " desc='%s' rHost='%s'\n", - i, protocol, extPort, intClient, intPort, - enabled, duration, - desc, rHost); - */ + data->first.servicetype, + index, + extPort, intClient, intPort, + protocol, desc, enabled, + rHost, duration); + if (r == 0) + /* + printf("%02d - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n" + " desc='%s' rHost='%s'\n", + i, protocol, extPort, intClient, intPort, + enabled, duration, + desc, rHost); + */ printf("%2d %s %5s->%s:%-5s '%s' '%s' %s\n", - i, protocol, extPort, intClient, intPort, - desc, rHost, duration); + i, protocol, extPort, intClient, intPort, + desc, rHost, duration); else printf("GetGenericPortMappingEntry() returned %d (%s)\n", - r, strupnperror(r)); + r, strupnperror(r)); i++; - } while(r==0); + } while (r == 0); } static void NewListRedirections(struct UPNPUrls * urls, - struct IGDdatas * data) -{ + struct IGDdatas * data) { int r; int i = 0; struct PortMappingParserData pdata; @@ -183,55 +177,47 @@ static void NewListRedirections(struct UPNPUrls * urls, memset(&pdata, 0, sizeof(struct PortMappingParserData)); r = UPNP_GetListOfPortMappings(urls->controlURL, - data->first.servicetype, - "0", - "65535", - "TCP", - "1000", - &pdata); - if(r == UPNPCOMMAND_SUCCESS) - { + data->first.servicetype, + "0", + "65535", + "TCP", + "1000", + &pdata); + if (r == UPNPCOMMAND_SUCCESS) { printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n"); - for(pm = pdata.l_head; pm != NULL; pm = pm->l_next) - { + for (pm = pdata.l_head; pm != NULL; pm = pm->l_next) { printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost, - (unsigned)pm->leaseTime); + i, pm->protocol, pm->externalPort, pm->internalClient, + pm->internalPort, + pm->description, pm->remoteHost, + (unsigned) pm->leaseTime); i++; } FreePortListing(&pdata); - } - else - { + } else { printf("GetListOfPortMappings() returned %d (%s)\n", - r, strupnperror(r)); + r, strupnperror(r)); } r = UPNP_GetListOfPortMappings(urls->controlURL, - data->first.servicetype, - "0", - "65535", - "UDP", - "1000", - &pdata); - if(r == UPNPCOMMAND_SUCCESS) - { - for(pm = pdata.l_head; pm != NULL; pm = pm->l_next) - { + data->first.servicetype, + "0", + "65535", + "UDP", + "1000", + &pdata); + if (r == UPNPCOMMAND_SUCCESS) { + for (pm = pdata.l_head; pm != NULL; pm = pm->l_next) { printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost, - (unsigned)pm->leaseTime); + i, pm->protocol, pm->externalPort, pm->internalClient, + pm->internalPort, + pm->description, pm->remoteHost, + (unsigned) pm->leaseTime); i++; } FreePortListing(&pdata); - } - else - { + } else { printf("GetListOfPortMappings() returned %d (%s)\n", - r, strupnperror(r)); + r, strupnperror(r)); } } @@ -241,15 +227,14 @@ static void NewListRedirections(struct UPNPUrls * urls, * 3 - Add port mapping * 4 - get this port mapping from the IGD */ static void SetRedirectAndTest(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * iaddr, - const char * iport, - const char * eport, - const char * proto, - const char * leaseDuration, - const char * description, - int addAny) -{ + struct IGDdatas * data, + const char * iaddr, + const char * iport, + const char * eport, + const char * proto, + const char * leaseDuration, + const char * description, + int addAny) { char externalIPAddress[40]; char intClient[40]; char intPort[6]; @@ -257,75 +242,70 @@ static void SetRedirectAndTest(struct UPNPUrls * urls, char duration[16]; int r; - if(!iaddr || !iport || !eport || !proto) - { + if (!iaddr || !iport || !eport || !proto) { fprintf(stderr, "Wrong arguments\n"); return; } proto = protofix(proto); - if(!proto) - { + if (!proto) { fprintf(stderr, "invalid protocol\n"); return; } r = UPNP_GetExternalIPAddress(urls->controlURL, - data->first.servicetype, - externalIPAddress); - if(r!=UPNPCOMMAND_SUCCESS) + data->first.servicetype, + externalIPAddress); + if (r != UPNPCOMMAND_SUCCESS) printf("GetExternalIPAddress failed.\n"); else printf("ExternalIPAddress = %s\n", externalIPAddress); if (addAny) { r = UPNP_AddAnyPortMapping(urls->controlURL, data->first.servicetype, - eport, iport, iaddr, description, - proto, 0, leaseDuration, reservedPort); - if(r==UPNPCOMMAND_SUCCESS) + eport, iport, iaddr, description, + proto, 0, leaseDuration, reservedPort); + if (r == UPNPCOMMAND_SUCCESS) eport = reservedPort; else printf("AddAnyPortMapping(%s, %s, %s) failed with code %d (%s)\n", - eport, iport, iaddr, r, strupnperror(r)); + eport, iport, iaddr, r, strupnperror(r)); } else { r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype, - eport, iport, iaddr, description, - proto, 0, leaseDuration); - if(r!=UPNPCOMMAND_SUCCESS) + eport, iport, iaddr, description, + proto, 0, leaseDuration); + if (r != UPNPCOMMAND_SUCCESS) printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", - eport, iport, iaddr, r, strupnperror(r)); + eport, iport, iaddr, r, strupnperror(r)); } r = UPNP_GetSpecificPortMappingEntry(urls->controlURL, - data->first.servicetype, - eport, proto, NULL/*remoteHost*/, - intClient, intPort, NULL/*desc*/, - NULL/*enabled*/, duration); - if(r!=UPNPCOMMAND_SUCCESS) + data->first.servicetype, + eport, proto, NULL/*remoteHost*/, + intClient, intPort, NULL/*desc*/, + NULL/*enabled*/, duration); + if (r != UPNPCOMMAND_SUCCESS) printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n", - r, strupnperror(r)); + r, strupnperror(r)); else { printf("InternalIP:Port = %s:%s\n", intClient, intPort); printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n", - externalIPAddress, eport, proto, intClient, intPort, duration); + externalIPAddress, eport, proto, intClient, intPort, duration); } } static void RemoveRedirect(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * eport, - const char * proto, - const char * remoteHost) -{ + struct IGDdatas * data, + const char * eport, + const char * proto, + const char * remoteHost) { int r; - if(!proto || !eport) - { + if (!proto || !eport) { fprintf(stderr, "invalid arguments\n"); return; } proto = protofix(proto); - if(!proto) - { + if (!proto) { fprintf(stderr, "protocol invalid\n"); return; } @@ -335,23 +315,20 @@ RemoveRedirect(struct UPNPUrls * urls, static void RemoveRedirectRange(struct UPNPUrls * urls, - struct IGDdatas * data, - const char * ePortStart, char const * ePortEnd, - const char * proto, const char * manage) -{ + struct IGDdatas * data, + const char * ePortStart, char const * ePortEnd, + const char * proto, const char * manage) { int r; if (!manage) manage = "0"; - if(!proto || !ePortStart || !ePortEnd) - { + if (!proto || !ePortStart || !ePortEnd) { fprintf(stderr, "invalid arguments\n"); return; } proto = protofix(proto); - if(!proto) - { + if (!proto) { fprintf(stderr, "protocol invalid\n"); return; } @@ -360,14 +337,13 @@ RemoveRedirectRange(struct UPNPUrls * urls, } /* IGD:2, functions for service WANIPv6FirewallControl:1 */ -static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data) -{ +static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data) { unsigned int bytessent, bytesreceived, packetsreceived, packetssent; int firewallEnabled = 0, inboundPinholeAllowed = 0; UPNP_GetFirewallStatus(urls->controlURL_6FC, data->IPv6FC.servicetype, &firewallEnabled, &inboundPinholeAllowed); printf("FirewallEnabled: %d & Inbound Pinhole Allowed: %d\n", firewallEnabled, inboundPinholeAllowed); - printf("GetFirewallStatus:\n Firewall Enabled: %s\n Inbound Pinhole Allowed: %s\n", (firewallEnabled)? "Yes":"No", (inboundPinholeAllowed)? "Yes":"No"); + printf("GetFirewallStatus:\n Firewall Enabled: %s\n Inbound Pinhole Allowed: %s\n", (firewallEnabled) ? "Yes" : "No", (inboundPinholeAllowed) ? "Yes" : "No"); bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype); bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype); @@ -381,48 +357,39 @@ static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data) * 1 - Add pinhole * 2 - Check if pinhole is working from the IGD side */ static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data, - const char * remoteaddr, const char * eport, - const char * intaddr, const char * iport, - const char * proto, const char * lease_time) -{ + const char * remoteaddr, const char * eport, + const char * intaddr, const char * iport, + const char * proto, const char * lease_time) { char uniqueID[8]; /*int isWorking = 0;*/ int r; char proto_tmp[8]; - if(!intaddr || !remoteaddr || !iport || !eport || !proto || !lease_time) - { + if (!intaddr || !remoteaddr || !iport || !eport || !proto || !lease_time) { fprintf(stderr, "Wrong arguments\n"); return; } - if(atoi(proto) == 0) - { + if (atoi(proto) == 0) { const char * protocol; protocol = protofix(proto); - if(protocol && (strcmp("TCP", protocol) == 0)) - { + if (protocol && (strcmp("TCP", protocol) == 0)) { snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_TCP); proto = proto_tmp; - } - else if(protocol && (strcmp("UDP", protocol) == 0)) - { + } else if (protocol && (strcmp("UDP", protocol) == 0)) { snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_UDP); proto = proto_tmp; - } - else - { + } else { fprintf(stderr, "invalid protocol\n"); return; } } r = UPNP_AddPinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, lease_time, uniqueID); - if(r!=UPNPCOMMAND_SUCCESS) + if (r != UPNPCOMMAND_SUCCESS) printf("AddPinhole([%s]:%s -> [%s]:%s) failed with code %d (%s)\n", - remoteaddr, eport, intaddr, iport, r, strupnperror(r)); - else - { + remoteaddr, eport, intaddr, iport, r, strupnperror(r)); + else { printf("AddPinhole: ([%s]:%s -> [%s]:%s) / Pinhole ID = %s\n", - remoteaddr, eport, intaddr, iport, uniqueID); + remoteaddr, eport, intaddr, iport, uniqueID); /*r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->servicetype_6FC, uniqueID, &isWorking); if(r!=UPNPCOMMAND_SUCCESS) printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); @@ -434,25 +401,22 @@ static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data, * 1 - Check if pinhole is working from the IGD side * 2 - Update pinhole */ static void GetPinholeAndUpdate(struct UPNPUrls * urls, struct IGDdatas * data, - const char * uniqueID, const char * lease_time) -{ + const char * uniqueID, const char * lease_time) { int isWorking = 0; int r; - if(!uniqueID || !lease_time) - { + if (!uniqueID || !lease_time) { fprintf(stderr, "Wrong arguments\n"); return; } r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking); - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No"); - if(r!=UPNPCOMMAND_SUCCESS) + printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking) ? "Yes" : "No"); + if (r != UPNPCOMMAND_SUCCESS) printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); - if(isWorking || r==709) - { + if (isWorking || r == 709) { r = UPNP_UpdatePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, lease_time); printf("UpdatePinhole: Pinhole ID = %s with Lease Time: %s\n", uniqueID, lease_time); - if(r!=UPNPCOMMAND_SUCCESS) + if (r != UPNPCOMMAND_SUCCESS) printf("UpdatePinhole: ID (%s) failed with code %d (%s)\n", uniqueID, r, strupnperror(r)); } } @@ -461,39 +425,35 @@ static void GetPinholeAndUpdate(struct UPNPUrls * urls, struct IGDdatas * data, * Get pinhole timeout */ static void GetPinholeOutboundTimeout(struct UPNPUrls * urls, struct IGDdatas * data, - const char * remoteaddr, const char * eport, - const char * intaddr, const char * iport, - const char * proto) -{ + const char * remoteaddr, const char * eport, + const char * intaddr, const char * iport, + const char * proto) { int timeout = 0; int r; - if(!intaddr || !remoteaddr || !iport || !eport || !proto) - { + if (!intaddr || !remoteaddr || !iport || !eport || !proto) { fprintf(stderr, "Wrong arguments\n"); return; } r = UPNP_GetOutboundPinholeTimeout(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, &timeout); - if(r!=UPNPCOMMAND_SUCCESS) + if (r != UPNPCOMMAND_SUCCESS) printf("GetOutboundPinholeTimeout([%s]:%s -> [%s]:%s) failed with code %d (%s)\n", - intaddr, iport, remoteaddr, eport, r, strupnperror(r)); + intaddr, iport, remoteaddr, eport, r, strupnperror(r)); else printf("GetOutboundPinholeTimeout: ([%s]:%s -> [%s]:%s) / Timeout = %d\n", intaddr, iport, remoteaddr, eport, timeout); } static void GetPinholePackets(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ + struct IGDdatas * data, const char * uniqueID) { int r, pinholePackets = 0; - if(!uniqueID) - { + if (!uniqueID) { fprintf(stderr, "invalid arguments\n"); return; } r = UPNP_GetPinholePackets(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &pinholePackets); - if(r!=UPNPCOMMAND_SUCCESS) + if (r != UPNPCOMMAND_SUCCESS) printf("GetPinholePackets() failed with code %d (%s)\n", r, strupnperror(r)); else printf("GetPinholePackets: Pinhole ID = %s / PinholePackets = %d\n", uniqueID, pinholePackets); @@ -501,28 +461,24 @@ GetPinholePackets(struct UPNPUrls * urls, static void CheckPinhole(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ + struct IGDdatas * data, const char * uniqueID) { int r, isWorking = 0; - if(!uniqueID) - { + if (!uniqueID) { fprintf(stderr, "invalid arguments\n"); return; } r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking); - if(r!=UPNPCOMMAND_SUCCESS) + if (r != UPNPCOMMAND_SUCCESS) printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r)); else - printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No"); + printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking) ? "Yes" : "No"); } static void RemovePinhole(struct UPNPUrls * urls, - struct IGDdatas * data, const char * uniqueID) -{ + struct IGDdatas * data, const char * uniqueID) { int r; - if(!uniqueID) - { + if (!uniqueID) { fprintf(stderr, "invalid arguments\n"); return; } @@ -532,8 +488,7 @@ RemovePinhole(struct UPNPUrls * urls, /* sample upnp client program */ -int main(int argc, char ** argv) -{ +int main(int argc, char ** argv) { char command = 0; char ** commandargv = 0; int commandargc = 0; @@ -552,74 +507,63 @@ int main(int argc, char ** argv) #ifdef _WIN32 WSADATA wsaData; - int nResult = WSAStartup(MAKEWORD(2,2), &wsaData); - if(nResult != NO_ERROR) - { + int nResult = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (nResult != NO_ERROR) { fprintf(stderr, "WSAStartup() failed.\n"); return -1; } #endif - printf("upnpc : miniupnpc library test client, version %s.\n", MINIUPNPC_VERSION_STRING); + printf("upnpc : miniupnpc library test client, version %s.\n", MINIUPNPC_VERSION_STRING); printf(" (c) 2005-2015 Thomas Bernard.\n"); - printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n" - "for more information.\n"); + printf("Go to http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/\n" + "for more information.\n"); /* command line processing */ - for(i=1; i65535 || - (localport >1 && localport < 1024)) - { + if (sscanf(argv[++i], "%d%c", &localport, &junk) != 1 || + localport < 0 || localport>65535 || + (localport > 1 && localport < 1024)) { fprintf(stderr, "Invalid localport '%s'\n", argv[i]); localport = UPNP_LOCAL_PORT_ANY; break; } - } - else if(argv[i][1] == 'p') + } else if (argv[i][1] == 'p') minissdpdpath = argv[++i]; - else if(argv[i][1] == '6') + else if (argv[i][1] == '6') ipv6 = 1; - else if(argv[i][1] == 'e') + else if (argv[i][1] == 'e') description = argv[++i]; - else if(argv[i][1] == 't') - ttl = (unsigned char)atoi(argv[++i]); - else - { + else if (argv[i][1] == 't') + ttl = (unsigned char) atoi(argv[++i]); + else { command = argv[i][1]; i++; commandargv = argv + i; commandargc = argc - i; break; } - } - else - { + } else { fprintf(stderr, "option '%s' invalid\n", argv[i]); } } - if(!command - || (command == 'a' && commandargc<4) - || (command == 'd' && argc<2) - || (command == 'r' && argc<2) - || (command == 'A' && commandargc<6) - || (command == 'U' && commandargc<2) - || (command == 'D' && commandargc<1)) - { + if (!command + || (command == 'a' && commandargc < 4) + || (command == 'd' && argc < 2) + || (command == 'r' && argc < 2) + || (command == 'A' && commandargc < 6) + || (command == 'U' && commandargc < 2) + || (command == 'D' && commandargc < 1)) { fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol [duration]\n\t\tAdd port redirection\n", argv[0]); fprintf(stderr, " \t%s [options] -d external_port protocol \n\t\tDelete port redirection\n", argv[0]); fprintf(stderr, " \t%s [options] -s\n\t\tGet Connection status\n", argv[0]); @@ -648,183 +592,167 @@ int main(int argc, char ** argv) return 1; } - if( rootdescurl - || (devlist = upnpDiscover(2000, multicastif, minissdpdpath, - localport, ipv6, ttl, &error))) - { + if (rootdescurl + || (devlist = upnpDiscover(2000, multicastif, minissdpdpath, + localport, ipv6, ttl, &error))) { struct UPNPDev * device; struct UPNPUrls urls; struct IGDdatas data; - if(devlist) - { + if (devlist) { printf("List of UPNP devices found on the network :\n"); - for(device = devlist; device; device = device->pNext) - { + for (device = devlist; device; device = device->pNext) { printf(" desc: %s\n st: %s\n\n", - device->descURL, device->st); + device->descURL, device->st); } - } - else if(!rootdescurl) - { + } else if (!rootdescurl) { printf("upnpDiscover() error code=%d\n", error); } i = 1; - if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr))) - || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)))) - { - switch(i) { - case 1: - printf("Found valid IGD : %s\n", urls.controlURL); - break; - case 2: - printf("Found a (not connected?) IGD : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - break; - case 3: - printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); - break; - default: - printf("Found device (igd ?) : %s\n", urls.controlURL); - printf("Trying to continue anyway\n"); + if ((rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr))) + || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)))) { + switch (i) { + case 1: + printf("Found valid IGD : %s\n", urls.controlURL); + break; + case 2: + printf("Found a (not connected?) IGD : %s\n", urls.controlURL); + printf("Trying to continue anyway\n"); + break; + case 3: + printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL); + printf("Trying to continue anyway\n"); + break; + default: + printf("Found device (igd ?) : %s\n", urls.controlURL); + printf("Trying to continue anyway\n"); } printf("Local LAN ip address : %s\n", lanaddr); - #if 0 +#if 0 printf("getting \"%s\"\n", urls.ipcondescURL); descXML = miniwget(urls.ipcondescURL, &descXMLsize); - if(descXML) - { + if (descXML) { /*fwrite(descXML, 1, descXMLsize, stdout);*/ free(descXML); descXML = NULL; } - #endif +#endif - switch(command) - { - case 'l': - DisplayInfos(&urls, &data); - ListRedirections(&urls, &data); - break; - case 'L': - NewListRedirections(&urls, &data); - break; - case 'a': - SetRedirectAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - (commandargc > 4)?commandargv[4]:"0", - description, 0); - break; - case 'd': - RemoveRedirect(&urls, &data, commandargv[0], commandargv[1], - commandargc > 2 ? commandargv[2] : NULL); - break; - case 'n': /* aNy */ - SetRedirectAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - (commandargc > 4)?commandargv[4]:"0", - description, 1); - break; - case 'N': - if (commandargc < 3) - fprintf(stderr, "too few arguments\n"); + switch (command) { + case 'l': + DisplayInfos(&urls, &data); + ListRedirections(&urls, &data); + break; + case 'L': + NewListRedirections(&urls, &data); + break; + case 'a': + SetRedirectAndTest(&urls, &data, + commandargv[0], commandargv[1], + commandargv[2], commandargv[3], + (commandargc > 4) ? commandargv[4] : "0", + description, 0); + break; + case 'd': + RemoveRedirect(&urls, &data, commandargv[0], commandargv[1], + commandargc > 2 ? commandargv[2] : NULL); + break; + case 'n': /* aNy */ + SetRedirectAndTest(&urls, &data, + commandargv[0], commandargv[1], + commandargv[2], commandargv[3], + (commandargc > 4) ? commandargv[4] : "0", + description, 1); + break; + case 'N': + if (commandargc < 3) + fprintf(stderr, "too few arguments\n"); - RemoveRedirectRange(&urls, &data, commandargv[0], commandargv[1], commandargv[2], - commandargc > 3 ? commandargv[3] : NULL); - break; - case 's': - GetConnectionStatus(&urls, &data); - break; - case 'r': - i = 0; - while(i */ - SetRedirectAndTest(&urls, &data, - lanaddr, commandargv[i], - commandargv[i+1], commandargv[i+2], "0", - description, 0); - i+=3; /* 3 parameters parsed */ - } else { - /* 2nd parameter not an integer : */ - SetRedirectAndTest(&urls, &data, - lanaddr, commandargv[i], - commandargv[i], commandargv[i+1], "0", - description, 0); - i+=2; /* 2 parameters parsed */ + RemoveRedirectRange(&urls, &data, commandargv[0], commandargv[1], commandargv[2], + commandargc > 3 ? commandargv[3] : NULL); + break; + case 's': + GetConnectionStatus(&urls, &data); + break; + case 'r': + i = 0; + while (i < commandargc) { + if (!is_int(commandargv[i])) { + /* 1st parameter not an integer : error */ + fprintf(stderr, "command -r : %s is not an port number\n", commandargv[i]); + retcode = 1; + break; + } else if (is_int(commandargv[i + 1])) { + /* 2nd parameter is an integer : */ + SetRedirectAndTest(&urls, &data, + lanaddr, commandargv[i], + commandargv[i + 1], commandargv[i + 2], "0", + description, 0); + i += 3; /* 3 parameters parsed */ + } else { + /* 2nd parameter not an integer : */ + SetRedirectAndTest(&urls, &data, + lanaddr, commandargv[i], + commandargv[i], commandargv[i + 1], "0", + description, 0); + i += 2; /* 2 parameters parsed */ + } } - } - break; - case 'A': - SetPinholeAndTest(&urls, &data, - commandargv[0], commandargv[1], - commandargv[2], commandargv[3], - commandargv[4], commandargv[5]); - break; - case 'U': - GetPinholeAndUpdate(&urls, &data, - commandargv[0], commandargv[1]); - break; - case 'C': - for(i=0; ihead.lh_first; pm != NULL; pm = pm->entries.le_next) { printf("%2d %s %5hu->%s:%-5hu '%s' '%s'\n", - i, pm->protocol, pm->externalPort, pm->internalClient, - pm->internalPort, - pm->description, pm->remoteHost); + i, pm->protocol, pm->externalPort, pm->internalClient, + pm->internalPort, + pm->description, pm->remoteHost); i++; } */ @@ -863,7 +836,7 @@ UPNP_GetListOfPortMappings(const char * controlURL, } p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) { + if (p) { ret = UPNPCOMMAND_UNKNOWN_ERROR; sscanf(p, "%d", &ret); } @@ -877,41 +850,39 @@ UPNP_GetListOfPortMappings(const char * controlURL, /* IGD:2, functions for service WANIPv6FirewallControl:1 */ MINIUPNP_LIBSPEC int UPNP_GetFirewallStatus(const char * controlURL, - const char * servicetype, - int * firewallEnabled, - int * inboundPinholeAllowed) -{ + const char * servicetype, + int * firewallEnabled, + int * inboundPinholeAllowed) { struct NameValueParserData pdata; char * buffer; int bufsize; char * fe, *ipa, *p; int ret = UPNPCOMMAND_UNKNOWN_ERROR; - if(!firewallEnabled || !inboundPinholeAllowed) + if (!firewallEnabled || !inboundPinholeAllowed) return UPNPCOMMAND_INVALID_ARGS; buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetFirewallStatus", 0, &bufsize); - if(!buffer) { + "GetFirewallStatus", 0, &bufsize); + if (!buffer) { return UPNPCOMMAND_HTTP_ERROR; } ParseNameValue(buffer, bufsize, &pdata); free(buffer); buffer = NULL; fe = GetValueFromNameValueList(&pdata, "FirewallEnabled"); ipa = GetValueFromNameValueList(&pdata, "InboundPinholeAllowed"); - if(ipa && fe) + if (ipa && fe) ret = UPNPCOMMAND_SUCCESS; - if(fe) + if (fe) *firewallEnabled = my_atoui(fe); /*else *firewallEnabled = 0;*/ - if(ipa) + if (ipa) *inboundPinholeAllowed = my_atoui(ipa); /*else *inboundPinholeAllowed = 0;*/ p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) - { + if (p) { ret = UPNPCOMMAND_UNKNOWN_ERROR; sscanf(p, "%d", &ret); } @@ -921,13 +892,12 @@ UPNP_GetFirewallStatus(const char * controlURL, MINIUPNP_LIBSPEC int UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype, - const char * remoteHost, - const char * remotePort, - const char * intClient, - const char * intPort, - const char * proto, - int * opTimeout) -{ + const char * remoteHost, + const char * remotePort, + const char * intClient, + const char * intPort, + const char * proto, + int * opTimeout) { struct UPNParg * GetOutboundPinholeTimeoutArgs; char * buffer; int bufsize; @@ -936,11 +906,11 @@ UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype char * p; int ret; - if(!intPort || !intClient || !proto || !remotePort || !remoteHost) + if (!intPort || !intClient || !proto || !remotePort || !remoteHost) return UPNPCOMMAND_INVALID_ARGS; GetOutboundPinholeTimeoutArgs = calloc(6, sizeof(struct UPNParg)); - if(GetOutboundPinholeTimeoutArgs == NULL) + if (GetOutboundPinholeTimeoutArgs == NULL) return UPNPCOMMAND_MEM_ALLOC_ERROR; GetOutboundPinholeTimeoutArgs[0].elt = "RemoteHost"; GetOutboundPinholeTimeoutArgs[0].val = remoteHost; @@ -953,22 +923,19 @@ UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype GetOutboundPinholeTimeoutArgs[4].elt = "InternalClient"; GetOutboundPinholeTimeoutArgs[4].val = intClient; buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize); - if(!buffer) + "GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize); + if (!buffer) return UPNPCOMMAND_HTTP_ERROR; ParseNameValue(buffer, bufsize, &pdata); free(buffer); buffer = NULL; resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { + if (resVal) { ret = UPNPCOMMAND_UNKNOWN_ERROR; sscanf(resVal, "%d", &ret); - } - else - { + } else { ret = UPNPCOMMAND_SUCCESS; p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout"); - if(p) + if (p) *opTimeout = my_atoui(p); } ClearNameValueList(&pdata); @@ -978,14 +945,13 @@ UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype MINIUPNP_LIBSPEC int UPNP_AddPinhole(const char * controlURL, const char * servicetype, - const char * remoteHost, - const char * remotePort, - const char * intClient, - const char * intPort, - const char * proto, - const char * leaseTime, - char * uniqueID) -{ + const char * remoteHost, + const char * remotePort, + const char * intClient, + const char * intPort, + const char * proto, + const char * leaseTime, + char * uniqueID) { struct UPNParg * AddPinholeArgs; char * buffer; int bufsize; @@ -994,20 +960,17 @@ UPNP_AddPinhole(const char * controlURL, const char * servicetype, char * p; int ret; - if(!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime) + if (!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime) return UPNPCOMMAND_INVALID_ARGS; AddPinholeArgs = calloc(7, sizeof(struct UPNParg)); - if(AddPinholeArgs == NULL) + if (AddPinholeArgs == NULL) return UPNPCOMMAND_MEM_ALLOC_ERROR; /* RemoteHost can be wilcarded */ - if(strncmp(remoteHost, "empty", 5)==0) - { + if (strncmp(remoteHost, "empty", 5) == 0) { AddPinholeArgs[0].elt = "RemoteHost"; AddPinholeArgs[0].val = ""; - } - else - { + } else { AddPinholeArgs[0].elt = "RemoteHost"; AddPinholeArgs[0].val = remoteHost; } @@ -1017,39 +980,32 @@ UPNP_AddPinhole(const char * controlURL, const char * servicetype, AddPinholeArgs[2].val = proto; AddPinholeArgs[3].elt = "InternalPort"; AddPinholeArgs[3].val = intPort; - if(strncmp(intClient, "empty", 5)==0) - { + if (strncmp(intClient, "empty", 5) == 0) { AddPinholeArgs[4].elt = "InternalClient"; AddPinholeArgs[4].val = ""; - } - else - { + } else { AddPinholeArgs[4].elt = "InternalClient"; AddPinholeArgs[4].val = intClient; } AddPinholeArgs[5].elt = "LeaseTime"; AddPinholeArgs[5].val = leaseTime; buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "AddPinhole", AddPinholeArgs, &bufsize); - if(!buffer) + "AddPinhole", AddPinholeArgs, &bufsize); + if (!buffer) return UPNPCOMMAND_HTTP_ERROR; ParseNameValue(buffer, bufsize, &pdata); free(buffer); buffer = NULL; p = GetValueFromNameValueList(&pdata, "UniqueID"); - if(p) - { + if (p) { strncpy(uniqueID, p, 8); uniqueID[7] = '\0'; } resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { + if (resVal) { /*printf("AddPortMapping errorCode = '%s'\n", resVal);*/ ret = UPNPCOMMAND_UNKNOWN_ERROR; sscanf(resVal, "%d", &ret); - } - else - { + } else { ret = UPNPCOMMAND_SUCCESS; } ClearNameValueList(&pdata); @@ -1059,9 +1015,8 @@ UPNP_AddPinhole(const char * controlURL, const char * servicetype, MINIUPNP_LIBSPEC int UPNP_UpdatePinhole(const char * controlURL, const char * servicetype, - const char * uniqueID, - const char * leaseTime) -{ + const char * uniqueID, + const char * leaseTime) { struct UPNParg * UpdatePinholeArgs; char * buffer; int bufsize; @@ -1069,31 +1024,28 @@ UPNP_UpdatePinhole(const char * controlURL, const char * servicetype, const char * resVal; int ret; - if(!uniqueID || !leaseTime) + if (!uniqueID || !leaseTime) return UPNPCOMMAND_INVALID_ARGS; UpdatePinholeArgs = calloc(3, sizeof(struct UPNParg)); - if(UpdatePinholeArgs == NULL) + if (UpdatePinholeArgs == NULL) return UPNPCOMMAND_MEM_ALLOC_ERROR; UpdatePinholeArgs[0].elt = "UniqueID"; UpdatePinholeArgs[0].val = uniqueID; UpdatePinholeArgs[1].elt = "NewLeaseTime"; UpdatePinholeArgs[1].val = leaseTime; buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "UpdatePinhole", UpdatePinholeArgs, &bufsize); - if(!buffer) + "UpdatePinhole", UpdatePinholeArgs, &bufsize); + if (!buffer) return UPNPCOMMAND_HTTP_ERROR; ParseNameValue(buffer, bufsize, &pdata); free(buffer); buffer = NULL; resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { + if (resVal) { /*printf("AddPortMapping errorCode = '%s'\n", resVal); */ ret = UPNPCOMMAND_UNKNOWN_ERROR; sscanf(resVal, "%d", &ret); - } - else - { + } else { ret = UPNPCOMMAND_SUCCESS; } ClearNameValueList(&pdata); @@ -1102,8 +1054,7 @@ UPNP_UpdatePinhole(const char * controlURL, const char * servicetype, } MINIUPNP_LIBSPEC int -UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID) -{ +UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID) { /*struct NameValueParserData pdata;*/ struct UPNParg * DeletePinholeArgs; char * buffer; @@ -1112,29 +1063,26 @@ UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char const char * resVal; int ret; - if(!uniqueID) + if (!uniqueID) return UPNPCOMMAND_INVALID_ARGS; DeletePinholeArgs = calloc(2, sizeof(struct UPNParg)); - if(DeletePinholeArgs == NULL) + if (DeletePinholeArgs == NULL) return UPNPCOMMAND_MEM_ALLOC_ERROR; DeletePinholeArgs[0].elt = "UniqueID"; DeletePinholeArgs[0].val = uniqueID; buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "DeletePinhole", DeletePinholeArgs, &bufsize); - if(!buffer) + "DeletePinhole", DeletePinholeArgs, &bufsize); + if (!buffer) return UPNPCOMMAND_HTTP_ERROR; /*DisplayNameValueList(buffer, bufsize);*/ ParseNameValue(buffer, bufsize, &pdata); free(buffer); buffer = NULL; resVal = GetValueFromNameValueList(&pdata, "errorCode"); - if(resVal) - { + if (resVal) { ret = UPNPCOMMAND_UNKNOWN_ERROR; sscanf(resVal, "%d", &ret); - } - else - { + } else { ret = UPNPCOMMAND_SUCCESS; } ClearNameValueList(&pdata); @@ -1144,8 +1092,7 @@ UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char MINIUPNP_LIBSPEC int UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, - const char * uniqueID, int * isWorking) -{ + const char * uniqueID, int * isWorking) { struct NameValueParserData pdata; struct UPNParg * CheckPinholeWorkingArgs; char * buffer; @@ -1153,33 +1100,30 @@ UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, char * p; int ret = UPNPCOMMAND_UNKNOWN_ERROR; - if(!uniqueID) + if (!uniqueID) return UPNPCOMMAND_INVALID_ARGS; CheckPinholeWorkingArgs = calloc(4, sizeof(struct UPNParg)); - if(CheckPinholeWorkingArgs == NULL) + if (CheckPinholeWorkingArgs == NULL) return UPNPCOMMAND_MEM_ALLOC_ERROR; CheckPinholeWorkingArgs[0].elt = "UniqueID"; CheckPinholeWorkingArgs[0].val = uniqueID; buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "CheckPinholeWorking", CheckPinholeWorkingArgs, &bufsize); - if(!buffer) + "CheckPinholeWorking", CheckPinholeWorkingArgs, &bufsize); + if (!buffer) return UPNPCOMMAND_HTTP_ERROR; ParseNameValue(buffer, bufsize, &pdata); free(buffer); buffer = NULL; p = GetValueFromNameValueList(&pdata, "IsWorking"); - if(p) - { - *isWorking=my_atoui(p); + if (p) { + *isWorking = my_atoui(p); ret = UPNPCOMMAND_SUCCESS; - } - else + } else *isWorking = 0; p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) - { + if (p) { ret = UPNPCOMMAND_UNKNOWN_ERROR; sscanf(p, "%d", &ret); } @@ -1191,8 +1135,7 @@ UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, MINIUPNP_LIBSPEC int UPNP_GetPinholePackets(const char * controlURL, const char * servicetype, - const char * uniqueID, int * packets) -{ + const char * uniqueID, int * packets) { struct NameValueParserData pdata; struct UPNParg * GetPinholePacketsArgs; char * buffer; @@ -1200,31 +1143,29 @@ UPNP_GetPinholePackets(const char * controlURL, const char * servicetype, char * p; int ret = UPNPCOMMAND_UNKNOWN_ERROR; - if(!uniqueID) + if (!uniqueID) return UPNPCOMMAND_INVALID_ARGS; GetPinholePacketsArgs = calloc(4, sizeof(struct UPNParg)); - if(GetPinholePacketsArgs == NULL) + if (GetPinholePacketsArgs == NULL) return UPNPCOMMAND_MEM_ALLOC_ERROR; GetPinholePacketsArgs[0].elt = "UniqueID"; GetPinholePacketsArgs[0].val = uniqueID; buffer = simpleUPnPcommand(-1, controlURL, servicetype, - "GetPinholePackets", GetPinholePacketsArgs, &bufsize); - if(!buffer) + "GetPinholePackets", GetPinholePacketsArgs, &bufsize); + if (!buffer) return UPNPCOMMAND_HTTP_ERROR; ParseNameValue(buffer, bufsize, &pdata); free(buffer); buffer = NULL; p = GetValueFromNameValueList(&pdata, "PinholePackets"); - if(p) - { - *packets=my_atoui(p); + if (p) { + *packets = my_atoui(p); ret = UPNPCOMMAND_SUCCESS; } p = GetValueFromNameValueList(&pdata, "errorCode"); - if(p) - { + if (p) { ret = UPNPCOMMAND_UNKNOWN_ERROR; sscanf(p, "%d", &ret); } diff --git a/source/shared_lib/sources/platform/miniupnpc/upnpdev.c b/source/shared_lib/sources/platform/miniupnpc/upnpdev.c index d89a9934c..e594746b8 100644 --- a/source/shared_lib/sources/platform/miniupnpc/upnpdev.c +++ b/source/shared_lib/sources/platform/miniupnpc/upnpdev.c @@ -8,13 +8,11 @@ #include #include "upnpdev.h" -/* freeUPNPDevlist() should be used to - * free the chained list returned by upnpDiscover() */ -void freeUPNPDevlist(struct UPNPDev * devlist) -{ + /* freeUPNPDevlist() should be used to + * free the chained list returned by upnpDiscover() */ +void freeUPNPDevlist(struct UPNPDev * devlist) { struct UPNPDev * next; - while(devlist) - { + while (devlist) { next = devlist->pNext; free(devlist); devlist = next; diff --git a/source/shared_lib/sources/platform/miniupnpc/upnperrors.c b/source/shared_lib/sources/platform/miniupnpc/upnperrors.c index 7ab8ee96f..3ff505c8d 100644 --- a/source/shared_lib/sources/platform/miniupnpc/upnperrors.c +++ b/source/shared_lib/sources/platform/miniupnpc/upnperrors.c @@ -11,97 +11,96 @@ #include "upnpcommands.h" #include "miniupnpc.h" -const char * strupnperror(int err) -{ +const char * strupnperror(int err) { const char * s = NULL; - switch(err) { - case UPNPCOMMAND_SUCCESS: - s = "Success"; - break; - case UPNPCOMMAND_UNKNOWN_ERROR: - s = "Miniupnpc Unknown Error"; - break; - case UPNPCOMMAND_INVALID_ARGS: - s = "Miniupnpc Invalid Arguments"; - break; - case UPNPCOMMAND_INVALID_RESPONSE: - s = "Miniupnpc Invalid response"; - break; - case UPNPDISCOVER_SOCKET_ERROR: - s = "Miniupnpc Socket error"; - break; - case UPNPDISCOVER_MEMORY_ERROR: - s = "Miniupnpc Memory allocation error"; - break; - case 401: - s = "Invalid Action"; - break; - case 402: - s = "Invalid Args"; - break; - case 501: - s = "Action Failed"; - break; - case 606: - s = "Action not authorized"; - break; - case 701: - s = "PinholeSpaceExhausted"; - break; - case 702: - s = "FirewallDisabled"; - break; - case 703: - s = "InboundPinholeNotAllowed"; - break; - case 704: - s = "NoSuchEntry"; - break; - case 705: - s = "ProtocolNotSupported"; - break; - case 706: - s = "InternalPortWildcardingNotAllowed"; - break; - case 707: - s = "ProtocolWildcardingNotAllowed"; - break; - case 708: - s = "WildcardNotPermittedInSrcIP"; - break; - case 709: - s = "NoPacketSent"; - break; - case 713: - s = "SpecifiedArrayIndexInvalid"; - break; - case 714: - s = "NoSuchEntryInArray"; - break; - case 715: - s = "WildCardNotPermittedInSrcIP"; - break; - case 716: - s = "WildCardNotPermittedInExtPort"; - break; - case 718: - s = "ConflictInMappingEntry"; - break; - case 724: - s = "SamePortValuesRequired"; - break; - case 725: - s = "OnlyPermanentLeasesSupported"; - break; - case 726: - s = "RemoteHostOnlySupportsWildcard"; - break; - case 727: - s = "ExternalPortOnlySupportsWildcard"; - break; - default: - s = "UnknownError"; - break; + switch (err) { + case UPNPCOMMAND_SUCCESS: + s = "Success"; + break; + case UPNPCOMMAND_UNKNOWN_ERROR: + s = "Miniupnpc Unknown Error"; + break; + case UPNPCOMMAND_INVALID_ARGS: + s = "Miniupnpc Invalid Arguments"; + break; + case UPNPCOMMAND_INVALID_RESPONSE: + s = "Miniupnpc Invalid response"; + break; + case UPNPDISCOVER_SOCKET_ERROR: + s = "Miniupnpc Socket error"; + break; + case UPNPDISCOVER_MEMORY_ERROR: + s = "Miniupnpc Memory allocation error"; + break; + case 401: + s = "Invalid Action"; + break; + case 402: + s = "Invalid Args"; + break; + case 501: + s = "Action Failed"; + break; + case 606: + s = "Action not authorized"; + break; + case 701: + s = "PinholeSpaceExhausted"; + break; + case 702: + s = "FirewallDisabled"; + break; + case 703: + s = "InboundPinholeNotAllowed"; + break; + case 704: + s = "NoSuchEntry"; + break; + case 705: + s = "ProtocolNotSupported"; + break; + case 706: + s = "InternalPortWildcardingNotAllowed"; + break; + case 707: + s = "ProtocolWildcardingNotAllowed"; + break; + case 708: + s = "WildcardNotPermittedInSrcIP"; + break; + case 709: + s = "NoPacketSent"; + break; + case 713: + s = "SpecifiedArrayIndexInvalid"; + break; + case 714: + s = "NoSuchEntryInArray"; + break; + case 715: + s = "WildCardNotPermittedInSrcIP"; + break; + case 716: + s = "WildCardNotPermittedInExtPort"; + break; + case 718: + s = "ConflictInMappingEntry"; + break; + case 724: + s = "SamePortValuesRequired"; + break; + case 725: + s = "OnlyPermanentLeasesSupported"; + break; + case 726: + s = "RemoteHostOnlySupportsWildcard"; + break; + case 727: + s = "ExternalPortOnlySupportsWildcard"; + break; + default: + s = "UnknownError"; + break; } return s; } diff --git a/source/shared_lib/sources/platform/miniupnpc/upnpreplyparse.c b/source/shared_lib/sources/platform/miniupnpc/upnpreplyparse.c index 5de5796a3..36c8c2c05 100644 --- a/source/shared_lib/sources/platform/miniupnpc/upnpreplyparse.c +++ b/source/shared_lib/sources/platform/miniupnpc/upnpreplyparse.c @@ -13,53 +13,46 @@ #include "minixml.h" static void -NameValueParserStartElt(void * d, const char * name, int l) -{ +NameValueParserStartElt(void * d, const char * name, int l) { struct NameValueParserData * data = (struct NameValueParserData *)d; data->topelt = 1; - if(l>63) - l = 63; - memcpy(data->curelt, name, l); - data->curelt[l] = '\0'; + if (l > 63) + l = 63; + memcpy(data->curelt, name, l); + data->curelt[l] = '\0'; data->cdata = NULL; data->cdatalen = 0; } static void -NameValueParserEndElt(void * d, const char * name, int l) -{ - struct NameValueParserData * data = (struct NameValueParserData *)d; - struct NameValue * nv; - (void)name; - (void)l; - if(!data->topelt) +NameValueParserEndElt(void * d, const char * name, int l) { + struct NameValueParserData * data = (struct NameValueParserData *)d; + struct NameValue * nv; + (void) name; + (void) l; + if (!data->topelt) return; - if(strcmp(data->curelt, "NewPortListing") != 0) - { + if (strcmp(data->curelt, "NewPortListing") != 0) { int l; /* standard case. Limited to n chars strings */ l = data->cdatalen; - nv = malloc(sizeof(struct NameValue)); - if(nv == NULL) - { + nv = malloc(sizeof(struct NameValue)); + if (nv == NULL) { /* malloc error */ #ifdef DEBUG fprintf(stderr, "%s: error allocating memory", - "NameValueParserEndElt"); + "NameValueParserEndElt"); #endif /* DEBUG */ return; } - if(l>=(int)sizeof(nv->value)) - l = sizeof(nv->value) - 1; - strncpy(nv->name, data->curelt, 64); + if (l >= (int)sizeof(nv->value)) + l = sizeof(nv->value) - 1; + strncpy(nv->name, data->curelt, 64); nv->name[63] = '\0'; - if(data->cdata != NULL) - { + if (data->cdata != NULL) { memcpy(nv->value, data->cdata, l); nv->value[l] = '\0'; - } - else - { + } else { nv->value[0] = '\0'; } nv->l_next = data->l_head; /* insert in list */ @@ -71,28 +64,23 @@ NameValueParserEndElt(void * d, const char * name, int l) } static void -NameValueParserGetData(void * d, const char * datas, int l) -{ - struct NameValueParserData * data = (struct NameValueParserData *)d; - if(strcmp(data->curelt, "NewPortListing") == 0) - { +NameValueParserGetData(void * d, const char * datas, int l) { + struct NameValueParserData * data = (struct NameValueParserData *)d; + if (strcmp(data->curelt, "NewPortListing") == 0) { /* specific case for NewPortListing which is a XML Document */ data->portListing = malloc(l + 1); - if(!data->portListing) - { + if (!data->portListing) { /* malloc error */ #ifdef DEBUG fprintf(stderr, "%s: error allocating memory", - "NameValueParserGetData"); + "NameValueParserGetData"); #endif /* DEBUG */ return; } memcpy(data->portListing, datas, l); data->portListing[l] = '\0'; data->portListingLength = l; - } - else - { + } else { /* standard case. */ data->cdata = datas; data->cdatalen = l; @@ -101,8 +89,7 @@ NameValueParserGetData(void * d, const char * datas, int l) void ParseNameValue(const char * buffer, int bufsize, - struct NameValueParserData * data) -{ + struct NameValueParserData * data) { struct xmlparser parser; data->l_head = NULL; data->portListing = NULL; @@ -119,57 +106,50 @@ ParseNameValue(const char * buffer, int bufsize, } void -ClearNameValueList(struct NameValueParserData * pdata) -{ - struct NameValue * nv; - if(pdata->portListing) - { +ClearNameValueList(struct NameValueParserData * pdata) { + struct NameValue * nv; + if (pdata->portListing) { free(pdata->portListing); pdata->portListing = NULL; pdata->portListingLength = 0; } - while((nv = pdata->l_head) != NULL) - { + while ((nv = pdata->l_head) != NULL) { pdata->l_head = nv->l_next; - free(nv); - } + free(nv); + } } char * GetValueFromNameValueList(struct NameValueParserData * pdata, - const char * Name) -{ - struct NameValue * nv; - char * p = NULL; - for(nv = pdata->l_head; - (nv != NULL) && (p == NULL); - nv = nv->l_next) - { - if(strcmp(nv->name, Name) == 0) - p = nv->value; - } - return p; + const char * Name) { + struct NameValue * nv; + char * p = NULL; + for (nv = pdata->l_head; + (nv != NULL) && (p == NULL); + nv = nv->l_next) { + if (strcmp(nv->name, Name) == 0) + p = nv->value; + } + return p; } #if 0 /* useless now that minixml ignores namespaces by itself */ char * GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata, - const char * Name) -{ + const char * Name) { struct NameValue * nv; char * p = NULL; char * pname; - for(nv = pdata->head.lh_first; - (nv != NULL) && (p == NULL); - nv = nv->entries.le_next) - { + for (nv = pdata->head.lh_first; + (nv != NULL) && (p == NULL); + nv = nv->entries.le_next) { pname = strrchr(nv->name, ':'); - if(pname) + if (pname) pname++; else pname = nv->name; - if(strcmp(pname, Name)==0) + if (strcmp(pname, Name) == 0) p = nv->value; } return p; @@ -180,18 +160,16 @@ GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata, * do parsing then display to stdout */ #ifdef DEBUG void -DisplayNameValueList(char * buffer, int bufsize) -{ - struct NameValueParserData pdata; - struct NameValue * nv; - ParseNameValue(buffer, bufsize, &pdata); - for(nv = pdata.l_head; - nv != NULL; - nv = nv->l_next) - { - printf("%s = %s\n", nv->name, nv->value); - } - ClearNameValueList(&pdata); +DisplayNameValueList(char * buffer, int bufsize) { + struct NameValueParserData pdata; + struct NameValue * nv; + ParseNameValue(buffer, bufsize, &pdata); + for (nv = pdata.l_head; + nv != NULL; + nv = nv->l_next) { + printf("%s = %s\n", nv->name, nv->value); + } + ClearNameValueList(&pdata); } #endif /* DEBUG */ diff --git a/source/shared_lib/sources/platform/posix/ircclient.cpp b/source/shared_lib/sources/platform/posix/ircclient.cpp index 744251165..ae1eecb85 100644 --- a/source/shared_lib/sources/platform/posix/ircclient.cpp +++ b/source/shared_lib/sources/platform/posix/ircclient.cpp @@ -35,1074 +35,1065 @@ using namespace Shared::Util; using namespace Shared::PlatformCommon; -namespace Shared { namespace PlatformCommon { +namespace Shared { + namespace PlatformCommon { -const char *IRCThread::globalCacheContainerName = NULL; -const int IRC_SERVER_PORT = 6667; -//bool IRCThread::debugEnabled = true; -bool IRCThread::debugEnabled = false; + const char *IRCThread::globalCacheContainerName = NULL; + const int IRC_SERVER_PORT = 6667; + //bool IRCThread::debugEnabled = true; + bool IRCThread::debugEnabled = false; #if !defined(DISABLE_IRCCLIENT) -void addlog (const char * fmt, ...) { - //FILE * fp; - char buf[8096]; - va_list va_alist; + void addlog(const char * fmt, ...) { + //FILE * fp; + char buf[8096]; + va_list va_alist; - va_start (va_alist, fmt); + va_start(va_alist, fmt); #if defined (WIN32) - _vsnprintf (buf, sizeof(buf), fmt, va_alist); + _vsnprintf(buf, sizeof(buf), fmt, va_alist); #else - vsnprintf (buf, sizeof(buf), fmt, va_alist); + vsnprintf(buf, sizeof(buf), fmt, va_alist); #endif - va_end (va_alist); + va_end(va_alist); - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: %s\n", buf); + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: %s\n", buf); - //if(SystemFlags::VERBOSE_MODE_ENABLED == true) { - // if ( (fp = fopen ("irctest.log", "ab")) != 0 ) { - // fprintf (fp, "%s\n", buf); - // fclose (fp); - // } - //} -} - -void dump_event (irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) { - char buf[512]=""; - unsigned int cnt=0; - buf[0] = '\0'; - - for ( cnt = 0; cnt < count; cnt++ ) { - if ( cnt ) { - strcat (buf, "|"); - } -#ifdef WIN32 - strncat (buf, params[cnt],min((int)strlen(params[cnt]),511)); -#else - strncat (buf, params[cnt],std::min((int)strlen(params[cnt]),511)); -#endif - } - - addlog ("Event \"%s\", origin: \"%s\", params: %d [%s]", event, origin ? origin : "NULL", cnt, buf); - - IRCThread *ctx = (IRCThread *)irc_get_ctx(session); - if(ctx != NULL) { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - if(ctx->getQuitStatus()) { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - return; - } - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - if(difftime(time(NULL),ctx->getLastNickListUpdate()) >= 7) { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - ctx->setLastNickListUpdate(time(NULL)); - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - ctx->GetIRCConnectedNickList(ctx->getChannel(),false); - } - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - } -} - -void get_nickname(const char *sourceNick,char *destNick,size_t maxDestBufferSize) { - string sourceNickStr = sourceNick; - if(sourceNickStr != "" && sourceNickStr[0] == '@') { - sourceNickStr.erase(0,1); - } - - irc_target_get_nick(sourceNickStr.c_str(),destNick,maxDestBufferSize); -} - -void event_notice (irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) { - dump_event (session, event, origin, params, count); - - if(origin == NULL) { - return; - } - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("NOTICE from '%s': %s", origin, params[1]); - - //if(strcasecmp (origin, "nickserv")) { - // return; - //} - - if(strstr (params[1], "This nick is not registered") == params[1]) { - //std::string regcmd = "REGISTER " + gCfg.irc_nickserv_pass + " NOMAIL"; - //gLog.Add (CLog::INFO, "Registering our nick with NICKSERV"); - //irc_cmd_msg (session, "nickserv", regcmd.c_str()); - } - else if(strstr (params[1], "This nickname is registered and protected") == params[1]) { - //std::string identcmd = "IDENTIFY " + gCfg.irc_nickserv_pass; - //gLog.Add (CLog::INFO, "Identifying our nick with NICKSERV"); - //irc_cmd_msg (session, "nickserv", identcmd.c_str()); - -// IRCThread *ctx = (IRCThread *)irc_get_ctx(session); -// if(ctx != NULL) { -// if(ctx->getExecute_cmd_onconnect() != "") { -// irc_cmd_msg(session, "nickserv", ctx->getExecute_cmd_onconnect().c_str()); -// } -// } - } - else if(strstr (params[1], "Password accepted - you are now recognized") == params[1]) { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("Nickserv authentication succeed."); - } -} - -void event_join(irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) { - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - dump_event (session, event, origin, params, count); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - IRCThread *ctx = (IRCThread *)irc_get_ctx(session); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - if(ctx != NULL) { - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - if(ctx->getHasJoinedChannel() == false) { - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - irc_cmd_user_mode (session, "+i"); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - //irc_cmd_msg (session, params[0], "MG Bot says hello!"); - ctx->setHasJoinedChannel(true); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - //ctx->GetIRCConnectedNickList(ctx->getChannel(),true); - ctx->GetIRCConnectedNickList(ctx->getChannel(),false); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - } - else { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - char realNick[128]=""; - get_nickname(origin,realNick,127); - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: user joined channel realNick [%s] origin [%s]\n", realNick,origin); - - bool foundNick = false; - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - MutexSafeWrapper safeMutex(ctx->getMutexNickList(),string(__FILE__) + "_" + intToStr(__LINE__)); - std::vector nickList = ctx->getCachedNickList(); - for(unsigned int i = 0; - i < nickList.size(); ++i) { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: looking for match [%s] realNick [%s]\n", nickList[i].c_str(),realNick); - - if(nickList[i] == realNick) { - foundNick = true; - break; - } - } - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - if(foundNick == false) { - nickList.push_back(realNick); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - if(ctx->getWantToLeaveChannel() == true) { - ctx->leaveChannel(); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - } -} - -void event_connect (irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) { - IRCThread *ctx = (IRCThread *)irc_get_ctx(session); - - dump_event(session, event, origin, params, count); - - //IRC: Event "433", origin: "leguin.freenode.net", params: 3 [*|softcoder|Nickname is already in use.] -// printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); -// if(strstr (params[1], "Nickname is already in use") == params[1]) { -// IRCThread *ctx = (IRCThread *)irc_get_ctx(session); -// if(ctx != NULL) { -// if(ctx->getExecute_cmd_onconnect() != "") { -// irc_cmd_msg(session, "nickserv", ctx->getExecute_cmd_onconnect().c_str()); -// } -// } -// } -// else - if(ctx != NULL) { - irc_cmd_join(session, ctx->getChannel().c_str(), 0); - } -} - -void event_privmsg (irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) { - dump_event (session, event, origin, params, count); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("'%s' said me (%s): %s\n",origin ? origin : "someone",params[0], params[1] ); -} - -void dcc_recv_callback (irc_session_t * session, irc_dcc_t id, int status, void * ctx, const char * data, unsigned int length) { - - switch (status) - { - case LIBIRC_ERR_CLOSED: - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC %d: chat closed\n", id); - break; - - case 0: - if ( !data ) { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC %d: chat connected\n", id); - irc_dcc_msg (session, id, "Hehe"); - } - else { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC %d: %s\n", id, data); - - static int count = 1; - char buf[12]=""; - sprintf (buf, "DCC [%d]: %d", id, count++); - irc_dcc_msg (session, id, buf); - } - break; - - default: - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC %d: error %s\n", id, irc_strerror(status)); - break; - } -} - -void dcc_file_recv_callback (irc_session_t * session, irc_dcc_t id, int status, void * ctx, const char * data, unsigned int length) { - if ( status == 0 && length == 0 ) { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("File sent successfully\n"); - - if ( ctx ) { - fclose ((FILE*) ctx); - } - } - else if ( status ) { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("File sent error: %d\n", status); - - if ( ctx ) { - fclose ((FILE*) ctx); - } - } - else { - if ( ctx ) { - fwrite (data, 1, length, (FILE*) ctx); - } - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("File sent progress: %u\n", length); - } -} - -void event_channel(irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) { - //IRC: Event "433", origin: "leguin.freenode.net", params: 3 [*|softcoder|Nickname is already in use.] - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("In [%s::%s] Line: %d count = %u origin = %s\n",__FILE__,__FUNCTION__,__LINE__,count,(origin ? origin : "null")); - - if ( count != 2 ) - return; - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: '%s' said in channel %s: %s\n",origin ? origin : "someone",params[0], params[1] ); - - if ( !origin ) { - return; - } - - char realNick[128]=""; - get_nickname(origin,realNick,127); - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: event signalled realNick [%s] origin [%s]\n", realNick,origin); - - IRCThread *ctx = (IRCThread *)irc_get_ctx(session); - if(ctx != NULL) { - MutexSafeWrapper safeMutex(ctx->getMutexIRCCB(),string(__FILE__) + "_" + intToStr(__LINE__)); - IRCCallbackInterface *cb = ctx->getCallbackObj(false); - if(cb != NULL) { - cb->IRC_CallbackEvent(IRC_evt_chatText, realNick, params, count); - } - } - -// if ( !strcmp (params[1], "quit") ) -// irc_cmd_quit (session, "of course, Master!"); -// -// if ( !strcmp (params[1], "help") ) { -// irc_cmd_msg (session, params[0], "quit, help, dcc chat, dcc send, ctcp"); -// } -// -// if ( !strcmp (params[1], "ctcp") ) { -// irc_cmd_ctcp_request (session, realNick, "PING 223"); -// irc_cmd_ctcp_request (session, realNick, "FINGER"); -// irc_cmd_ctcp_request (session, realNick, "VERSION"); -// irc_cmd_ctcp_request (session, realNick, "TIME"); -// } -// -// if ( !strcmp (params[1], "dcc chat") ) { -// irc_dcc_t dccid; -// irc_dcc_chat (session, 0, realNick, dcc_recv_callback, &dccid); -// if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC chat ID: %d\n", dccid); -// } -// -// if ( !strcmp (params[1], "dcc send") ) { -// irc_dcc_t dccid; -// irc_dcc_sendfile (session, 0, realNick, "irctest.c", dcc_file_recv_callback, &dccid); -// if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC send ID: %d\n", dccid); -// } -// -// if ( !strcmp (params[1], "topic") ) { -// irc_cmd_topic (session, params[0], 0); -// } -// else if ( strstr (params[1], "topic ") == params[1] ) { -// irc_cmd_topic (session, params[0], params[1] + 6); -// } -// -// if ( strstr (params[1], "mode ") == params[1] ) -// irc_cmd_channel_mode (session, params[0], params[1] + 5); -// -// if ( strstr (params[1], "nick ") == params[1] ) -// irc_cmd_nick (session, params[1] + 5); -// -// if ( strstr (params[1], "whois ") == params[1] ) -// irc_cmd_whois (session, params[1] + 5); -} - -void irc_event_dcc_chat(irc_session_t * session, const char * nick, const char * addr, irc_dcc_t dccid) { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC chat [%d] requested from '%s' (%s)\n", dccid, nick, addr); - - irc_dcc_accept (session, dccid, 0, dcc_recv_callback); -} - -void irc_event_dcc_send(irc_session_t * session, const char * nick, const char * addr, const char * filename, unsigned long size, irc_dcc_t dccid) { - FILE * fp; - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC send [%d] requested from '%s' (%s): %s (%lu bytes)\n", dccid, nick, addr, filename, size); - - if ( (fp = fopen ("file", "wb")) == 0 ) { - abort(); - } - irc_dcc_accept (session, dccid, fp, dcc_file_recv_callback); -} - -void event_leave(irc_session_t *session, const char *event, const char *origin, const char ** params, unsigned count) { - char buf[24]=""; - sprintf (buf, "%s", event); - - // someone left the channel. - if(origin) { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: user left channel [%s]\n", origin); - - char realNick[128]=""; - get_nickname(origin,realNick,127); - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: user left channel realNick [%s] origin [%s]\n", realNick,origin); - - IRCThread *ctx = (IRCThread *)irc_get_ctx(session); - if(ctx != NULL) { - MutexSafeWrapper safeMutex(ctx->getMutexNickList(),string(__FILE__) + "_" + intToStr(__LINE__)); - std::vector &nickList = ctx->getCachedNickList(); - for(unsigned int i = 0; - i < nickList.size(); ++i) { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: lookingfor match [%s] realNick [%s]\n", nickList[i].c_str(),realNick); - - if(nickList[i] == realNick) { - nickList.erase(nickList.begin() + i); - break; - } - } - } - } - - dump_event (session, buf, origin, params, count); -} -void event_numeric(irc_session_t * session, unsigned int event, const char * origin, const char ** params, unsigned int count) { - char buf[24]=""; - sprintf (buf, "%u", event); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d event = %u\n", __LINE__, event); - - switch (event) { - case LIBIRC_RFC_ERR_NICKNAMEINUSE : - case LIBIRC_RFC_ERR_NICKCOLLISION : - //irc_auto_rename_nick(session); - //IRCThread *ctx = (IRCThread *)irc_get_ctx(session); - //if(ctx != NULL) { -// { -// //IRC: Event "433", origin: "leguin.freenode.net", params: 3 [*|softcoder|Nickname is already in use.] -// printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); -// //if(strstr (params[1], "Nickname is already in use") == params[1]) { -// IRCThread *ctx = (IRCThread *)irc_get_ctx(session); -// if(ctx != NULL) { -// if(ctx->getExecute_cmd_onconnect() != "") { -// irc_cmd_msg(session, "nickserv", ctx->getExecute_cmd_onconnect().c_str()); -// } -// } -// //} -// } - break; - - case LIBIRC_RFC_ERR_NOTREGISTERED : - //irc_auto_rename_nick(session); - //IRCThread *ctx = (IRCThread *)irc_get_ctx(session); - //if(ctx != NULL) { -// { - //===> IRC: Event "451", origin: "leguin.freenode.net", params: 2 [*|You have not registered] -// printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); -// //if(strstr (params[1], "Nickname is already in use") == params[1]) { -// IRCThread *ctx = (IRCThread *)irc_get_ctx(session); -// if(ctx != NULL) { -// //if(ctx->getExecute_cmd_onconnect() != "") { -// //irc_cmd_msg(session, "nickserv", ctx->getExecute_cmd_onconnect().c_str()); -// string cmd = "REGISTER " + ctx->getNick() + " NOMAIL"; -// irc_cmd_msg (session, "nickserv", cmd.c_str()); -// //} -// } -// //} -// } - break; - - case LIBIRC_RFC_RPL_TOPIC : - break; - case LIBIRC_RFC_RPL_NAMREPLY : - { - if(event == LIBIRC_RFC_RPL_NAMREPLY) { - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: LIBIRC_RFC_RPL_NAMREPLY count = %u\n", count); - - std::vector nickList; - if(count >= 4) { - for(unsigned int i = 3; i < count && params[i]; ++i) { - vector tokens; - Tokenize(params[i],tokens," "); - - for(unsigned int j = 0; j < tokens.size(); ++j) { - - char realNick[128]=""; - get_nickname(tokens[j].c_str(),realNick,127); - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: LIBIRC_RFC_RPL_NAMREPLY user joined channel realNick [%s] tokens[j] [%s]\n", realNick,tokens[j].c_str()); - - // Only show MegaGlest users in the user list - //if(strncmp(&realNick[0],"MG_",3) == 0) { - nickList.push_back(realNick); - //} - } - } - } - - IRCThread *ctx = (IRCThread *)irc_get_ctx(session); - if(ctx != NULL) { - MutexSafeWrapper safeMutex(ctx->getMutexNickList(),string(__FILE__) + "_" + intToStr(__LINE__)); - ctx->setCachedNickList(nickList); - } - } - break; - } - case LIBIRC_RFC_RPL_ENDOFNAMES: - { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("!!!!! ===> IRC: Line: %d event = %u\n", __LINE__, event); - - IRCThread *ctx = (IRCThread *)irc_get_ctx(session); - if(ctx != NULL) { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d event = %u\n", __LINE__, event); - - ctx->setEventDataDone(true); - } - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d event = %u\n", __LINE__, event); - } - break; - } - - dump_event (session, buf, origin, params, count); -} - -#endif - -bool IRCThread::getEventDataDone() { - MutexSafeWrapper safeMutex(&mutexEventDataDone,string(__FILE__) + "_" + intToStr(__LINE__)); - bool result = eventDataDone; - safeMutex.ReleaseLock(); - - return result; -} -void IRCThread::setEventDataDone(bool value) { - MutexSafeWrapper safeMutex(&mutexEventDataDone,string(__FILE__) + "_" + intToStr(__LINE__)); - eventDataDone=value; -} - -IRCThread::IRCThread(const std::vector &argv, IRCCallbackInterface *callbackObj) : BaseThread() { - uniqueID = "IRCThread"; - this->argv = argv; - this->callbackObj = callbackObj; - ircSession = NULL; - eventData.clear(); - setEventDataDone(false); - hasJoinedChannel = false; - lastNickListUpdate = time(NULL); - wantToLeaveChannel = false; - playerName = ""; - glestVersionString = ""; -} - -void IRCThread::disconnect() { -#if !defined(DISABLE_IRCCLIENT) - - MutexSafeWrapper safeMutex(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - bool validSession = (ircSession != NULL); - safeMutex.ReleaseLock(); - - if(validSession == true) { - setCallbackObj(NULL); - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Quitting Channel\n"); - - MutexSafeWrapper safeMutex1(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - if(ircSession != NULL) { - irc_disconnect(ircSession); - } - safeMutex1.ReleaseLock(); - - BaseThread::signalQuit(); - hasJoinedChannel = false; - } -#else - BaseThread::signalQuit(); -#endif -} - -void IRCThread::signalQuit() { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: signalQuit [%p]\n",ircSession); - -#if !defined(DISABLE_IRCCLIENT) - - MutexSafeWrapper safeMutex(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - bool validSession = (ircSession != NULL); - safeMutex.ReleaseLock(); - - if(validSession == true) { - setCallbackObj(NULL); - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Quitting Channel\n"); - - MutexSafeWrapper safeMutex1(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - if(ircSession != NULL) { - irc_cmd_quit(ircSession, "ZG Bot is closing!"); - } - safeMutex1.ReleaseLock(); - hasJoinedChannel = false; - } - BaseThread::signalQuit(); - -#else - BaseThread::signalQuit(); -#endif -} - -bool IRCThread::shutdownAndWait() { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: shutdownAndWait [%p]\n",ircSession); - - signalQuit(); - return BaseThread::shutdownAndWait(); -} - -void IRCThread::SendIRCCmdMessage(string target, string msg) { - MutexSafeWrapper safeMutex(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - bool validSession = (ircSession != NULL); - safeMutex.ReleaseLock(); - - if(validSession == true && hasJoinedChannel == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] sending IRC command to [%s] cmd [%s]\n",__FILE__,__FUNCTION__,__LINE__,target.c_str(),msg.c_str()); - -#if !defined(DISABLE_IRCCLIENT) - MutexSafeWrapper safeMutex1(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - int ret = 0; - if(ircSession != NULL) { - ret = irc_cmd_msg (ircSession, target.c_str(), msg.c_str()); - } - safeMutex1.ReleaseLock(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] sending IRC command to [%s] cmd [%s] ret = %d\n",__FILE__,__FUNCTION__,__LINE__,target.c_str(),msg.c_str(),ret); -#endif - } -} - -std::vector IRCThread::GetIRCConnectedNickList(string target, bool waitForCompletion) { - setEventDataDone(false); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - MutexSafeWrapper safeMutexSession(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - bool validSession = (ircSession != NULL); - safeMutexSession.ReleaseLock(); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - if(validSession == true && hasJoinedChannel == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] sending IRC nick list command to [%s]\n",__FILE__,__FUNCTION__,__LINE__,target.c_str()); - -#if !defined(DISABLE_IRCCLIENT) - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - MutexSafeWrapper safeMutex1(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - int ret = irc_cmd_names (ircSession, target.c_str()); - safeMutex1.ReleaseLock(); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] sending IRC nick list command to [%s] ret = %d\n",__FILE__,__FUNCTION__,__LINE__,target.c_str(),ret); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - if(waitForCompletion == true) { - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - for(time_t tElapsed = time(NULL); - getEventDataDone() == false && - this->getQuitStatus() == false && - difftime(time(NULL),tElapsed) <= 5;) { - sleep(50); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); -#endif - } - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - MutexSafeWrapper safeMutex(&mutexNickList,string(__FILE__) + "_" + intToStr(__LINE__)); - std::vector nickList = eventData; - safeMutex.ReleaseLock(); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - return nickList; -} - -bool IRCThread::isConnected(bool mutexLockRequired) { - bool ret = false; - if(this->getQuitStatus() == false) { - MutexSafeWrapper safeMutex(NULL,string(__FILE__) + "_" + intToStr(__LINE__)); - int lockStatus = 0; - if(mutexLockRequired == true) { - lockStatus = safeMutex.setMutexAndTryLock(&mutexIRCSession); - } - bool validSession = (lockStatus == SDL_MUTEX_TIMEDOUT || (lockStatus == 0 && ircSession != NULL)); - if(mutexLockRequired == true && lockStatus == 0) { - safeMutex.ReleaseLock(); + //if(SystemFlags::VERBOSE_MODE_ENABLED == true) { + // if ( (fp = fopen ("irctest.log", "ab")) != 0 ) { + // fprintf (fp, "%s\n", buf); + // fclose (fp); + // } + //} } - if(validSession == true) { -#if !defined(DISABLE_IRCCLIENT) - MutexSafeWrapper safeMutex1(NULL,string(__FILE__) + "_" + intToStr(__LINE__)); - if(ircSession != NULL) { - lockStatus = 0; - if(mutexLockRequired == true) { - lockStatus = safeMutex1.setMutexAndTryLock(&mutexIRCSession); + void dump_event(irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) { + char buf[512] = ""; + unsigned int cnt = 0; + buf[0] = '\0'; + + for (cnt = 0; cnt < count; cnt++) { + if (cnt) { + strcat(buf, "|"); } - ret = (lockStatus == SDL_MUTEX_TIMEDOUT || (lockStatus == 0 && irc_is_connected(ircSession) != 0)); - } - if(mutexLockRequired == true && lockStatus == 0) { - safeMutex1.ReleaseLock(); - } - } -#endif - } - - return ret; -} - -std::vector IRCThread::getNickList() { - MutexSafeWrapper safeMutex(&mutexNickList,string(__FILE__) + "_" + intToStr(__LINE__)); - std::vector nickList = eventData; - safeMutex.ReleaseLock(); - - return nickList; -} - -IRCCallbackInterface * IRCThread::getCallbackObj(bool lockObj) { - MutexSafeWrapper safeMutex(NULL,string(__FILE__) + "_" + intToStr(__LINE__)); - if(lockObj == true) { - safeMutex.setMutex(&mutexIRCCB); - } - return callbackObj; -} -void IRCThread::setCallbackObj(IRCCallbackInterface *cb) { - MutexSafeWrapper safeMutex(&mutexIRCCB,string(__FILE__) + "_" + intToStr(__LINE__)); - callbackObj=cb; -} - -void IRCThread::execute() { - { - RunningStatusSafeWrapper runningStatus(this); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] argv.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,argv.size()); - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: IRCThread::execute Line: %d\n", __LINE__); - - if(getQuitStatus() == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - return; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"IRC thread is running\n"); - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - try { -#if !defined(DISABLE_IRCCLIENT) - irc_callbacks_t callbacks; - - MutexSafeWrapper safeMutex(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - ircSession=NULL; - safeMutex.ReleaseLock(true); - - if(argv.size() != 5) { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC Usage: : got params [%ld]\n",(long int)argv.size()); - return; - } - - memset (&callbacks, 0, sizeof(callbacks)); - - callbacks.event_connect = event_connect; - callbacks.event_join = event_join; - callbacks.event_nick = dump_event; - callbacks.event_quit = dump_event; - callbacks.event_part = event_leave; - callbacks.event_mode = dump_event; - callbacks.event_topic = dump_event; - callbacks.event_kick = dump_event; - callbacks.event_channel = event_channel; - callbacks.event_privmsg = event_privmsg; - callbacks.event_notice = event_notice; - callbacks.event_invite = dump_event; - callbacks.event_umode = dump_event; - callbacks.event_ctcp_rep = dump_event; - callbacks.event_ctcp_action = dump_event; - callbacks.event_unknown = dump_event; - callbacks.event_numeric = event_numeric; - - callbacks.event_dcc_chat_req = irc_event_dcc_chat; - callbacks.event_dcc_send_req = irc_event_dcc_send; - - if(this->getQuitStatus() == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - return; - } - safeMutex.Lock(); - ircSession = irc_create_session (&callbacks); - bool validSession = (ircSession != NULL); - - if(validSession == false) { - safeMutex.ReleaseLock(); - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC Could not create session\n"); - return; - } - safeMutex.ReleaseLock(true); - -// this->execute_cmd_onconnect = ""; -// if(argv.size() >= 5) { -// this->execute_cmd_onconnect = argv[4]; // /msg NickServ identify . -// } - -// this->password = ""; -// if(argv.size() >= 5) { -// this->password = argv[4]; -// } - this->username = argv[1]; - if(argv.size() >= 4) { - this->username = argv[3]; - } - this->channel = argv[2]; - this->nick = argv[1]; - - safeMutex.Lock(); - irc_set_ctx(ircSession, this); - safeMutex.ReleaseLock(true); - - if(this->getQuitStatus() == true) { - return; - } - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - safeMutex.Lock(); - if(irc_connect(ircSession, argv[0].c_str(), IRC_SERVER_PORT, 0, this->nick.c_str(), this->username.c_str(), ("MegagGlest "+glestVersionString).c_str())) { - safeMutex.ReleaseLock(); - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC Could not connect: %s\n", irc_strerror (irc_errno(ircSession))); - return; - } - safeMutex.ReleaseLock(); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - if(this->getQuitStatus() == true) { - return; - } - - if(this->getQuitStatus() == true) { - return; - } - - //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - for(int iAttempts=1; - this->getQuitStatus() == false && iAttempts <= 7; ++iAttempts) { - //if(irc_run(ircSession)) { - - int run_result = irc_run_session(ircSession); - if(run_result && this->getQuitStatus() == false) { - //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC Could not run the session: %s run_result = %d\n", irc_strerror (irc_errno(ircSession)), run_result); - printf ("===> IRC Could not run the session: %s run_result = %d\n", irc_strerror (irc_errno(ircSession)), run_result); - } - } - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - - //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); +#ifdef WIN32 + strncat(buf, params[cnt], min((int) strlen(params[cnt]), 511)); #else - for(;this->getQuitStatus() == false;) { - sleep(50); - } + strncat(buf, params[cnt], std::min((int) strlen(params[cnt]), 511)); #endif - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC exiting IRC CLient!\n"); - //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - } - catch(...) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] UNKNOWN Error\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] IRC thread is exiting\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); - - - //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); - // Delete ourself when the thread is done (no other actions can happen after this - // such as the mutex which modifies the running status of this method - MutexSafeWrapper safeMutex(&mutexIRCCB,string(__FILE__) + "_" + intToStr(__LINE__)); - IRCCallbackInterface *cb = getCallbackObj(false); - if(cb != NULL) { - //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC: Line: %d\n", __LINE__); - cb->IRC_CallbackEvent(IRC_evt_exitThread, NULL, NULL, 0); - } - safeMutex.ReleaseLock(); - - } - //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In IRCThread() calling delete ...\n"); - - //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); - setDeleteAfterExecute(true); -} - -int IRCThread::irc_run_session(irc_session_t * session) { -// if ( session->state != LIBIRC_STATE_CONNECTING ) -// { -// session->lasterror = LIBIRC_ERR_STATE; -// return 1; -// } - - MutexSafeWrapper safeMutex(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - - if ( isConnected(false) == false ) { - //session->lasterror = LIBIRC_ERR_STATE; - return 1; - } - safeMutex.ReleaseLock(true); - - bool isSessionConnected = true; - while ( isSessionConnected == true && this->getQuitStatus() == false) { - struct timeval tv; - fd_set in_set, out_set; - int maxfd = 0; - - tv.tv_usec = 250000; - tv.tv_sec = 0; - - // Init sets - FD_ZERO (&in_set); - FD_ZERO (&out_set); - - safeMutex.Lock(); - irc_add_select_descriptors (session, &in_set, &out_set, &maxfd); - safeMutex.ReleaseLock(true); - - if ( select (maxfd + 1, &in_set, &out_set, 0, &tv) < 0 ) { - int lastSocketError = Socket::getLastSocketError(); - if ( lastSocketError == PLATFORM_SOCKET_INTERRUPTED ) { - continue; } - //session->lasterror = LIBIRC_ERR_TERMINATED; - return 2; + addlog("Event \"%s\", origin: \"%s\", params: %d [%s]", event, origin ? origin : "NULL", cnt, buf); + + IRCThread *ctx = (IRCThread *) irc_get_ctx(session); + if (ctx != NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + if (ctx->getQuitStatus()) { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + return; + } + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + if (difftime(time(NULL), ctx->getLastNickListUpdate()) >= 7) { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + ctx->setLastNickListUpdate(time(NULL)); + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + ctx->GetIRCConnectedNickList(ctx->getChannel(), false); + } + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + } } - safeMutex.Lock(); - if ( irc_process_select_descriptors (session, &in_set, &out_set) ) { + void get_nickname(const char *sourceNick, char *destNick, size_t maxDestBufferSize) { + string sourceNickStr = sourceNick; + if (sourceNickStr != "" && sourceNickStr[0] == '@') { + sourceNickStr.erase(0, 1); + } + + irc_target_get_nick(sourceNickStr.c_str(), destNick, maxDestBufferSize); + } + + void event_notice(irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) { + dump_event(session, event, origin, params, count); + + if (origin == NULL) { + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("NOTICE from '%s': %s", origin, params[1]); + + //if(strcasecmp (origin, "nickserv")) { + // return; + //} + + if (strstr(params[1], "This nick is not registered") == params[1]) { + //std::string regcmd = "REGISTER " + gCfg.irc_nickserv_pass + " NOMAIL"; + //gLog.Add (CLog::INFO, "Registering our nick with NICKSERV"); + //irc_cmd_msg (session, "nickserv", regcmd.c_str()); + } else if (strstr(params[1], "This nickname is registered and protected") == params[1]) { + //std::string identcmd = "IDENTIFY " + gCfg.irc_nickserv_pass; + //gLog.Add (CLog::INFO, "Identifying our nick with NICKSERV"); + //irc_cmd_msg (session, "nickserv", identcmd.c_str()); + + // IRCThread *ctx = (IRCThread *)irc_get_ctx(session); + // if(ctx != NULL) { + // if(ctx->getExecute_cmd_onconnect() != "") { + // irc_cmd_msg(session, "nickserv", ctx->getExecute_cmd_onconnect().c_str()); + // } + // } + } else if (strstr(params[1], "Password accepted - you are now recognized") == params[1]) { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("Nickserv authentication succeed."); + } + } + + void event_join(irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) { + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + dump_event(session, event, origin, params, count); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + IRCThread *ctx = (IRCThread *) irc_get_ctx(session); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + if (ctx != NULL) { + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + if (ctx->getHasJoinedChannel() == false) { + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + irc_cmd_user_mode(session, "+i"); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + //irc_cmd_msg (session, params[0], "MG Bot says hello!"); + ctx->setHasJoinedChannel(true); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + //ctx->GetIRCConnectedNickList(ctx->getChannel(),true); + ctx->GetIRCConnectedNickList(ctx->getChannel(), false); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + char realNick[128] = ""; + get_nickname(origin, realNick, 127); + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: user joined channel realNick [%s] origin [%s]\n", realNick, origin); + + bool foundNick = false; + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + MutexSafeWrapper safeMutex(ctx->getMutexNickList(), string(__FILE__) + "_" + intToStr(__LINE__)); + std::vector nickList = ctx->getCachedNickList(); + for (unsigned int i = 0; + i < nickList.size(); ++i) { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: looking for match [%s] realNick [%s]\n", nickList[i].c_str(), realNick); + + if (nickList[i] == realNick) { + foundNick = true; + break; + } + } + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + if (foundNick == false) { + nickList.push_back(realNick); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + if (ctx->getWantToLeaveChannel() == true) { + ctx->leaveChannel(); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + } + } + + void event_connect(irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) { + IRCThread *ctx = (IRCThread *) irc_get_ctx(session); + + dump_event(session, event, origin, params, count); + + //IRC: Event "433", origin: "leguin.freenode.net", params: 3 [*|softcoder|Nickname is already in use.] + // printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + // if(strstr (params[1], "Nickname is already in use") == params[1]) { + // IRCThread *ctx = (IRCThread *)irc_get_ctx(session); + // if(ctx != NULL) { + // if(ctx->getExecute_cmd_onconnect() != "") { + // irc_cmd_msg(session, "nickserv", ctx->getExecute_cmd_onconnect().c_str()); + // } + // } + // } + // else + if (ctx != NULL) { + irc_cmd_join(session, ctx->getChannel().c_str(), 0); + } + } + + void event_privmsg(irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) { + dump_event(session, event, origin, params, count); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("'%s' said me (%s): %s\n", origin ? origin : "someone", params[0], params[1]); + } + + void dcc_recv_callback(irc_session_t * session, irc_dcc_t id, int status, void * ctx, const char * data, unsigned int length) { + + switch (status) { + case LIBIRC_ERR_CLOSED: + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("DCC %d: chat closed\n", id); + break; + + case 0: + if (!data) { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("DCC %d: chat connected\n", id); + irc_dcc_msg(session, id, "Hehe"); + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("DCC %d: %s\n", id, data); + + static int count = 1; + char buf[12] = ""; + sprintf(buf, "DCC [%d]: %d", id, count++); + irc_dcc_msg(session, id, buf); + } + break; + + default: + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("DCC %d: error %s\n", id, irc_strerror(status)); + break; + } + } + + void dcc_file_recv_callback(irc_session_t * session, irc_dcc_t id, int status, void * ctx, const char * data, unsigned int length) { + if (status == 0 && length == 0) { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("File sent successfully\n"); + + if (ctx) { + fclose((FILE*) ctx); + } + } else if (status) { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("File sent error: %d\n", status); + + if (ctx) { + fclose((FILE*) ctx); + } + } else { + if (ctx) { + fwrite(data, 1, length, (FILE*) ctx); + } + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("File sent progress: %u\n", length); + } + } + + void event_channel(irc_session_t * session, const char * event, const char * origin, const char ** params, unsigned int count) { + //IRC: Event "433", origin: "leguin.freenode.net", params: 3 [*|softcoder|Nickname is already in use.] + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("In [%s::%s] Line: %d count = %u origin = %s\n", __FILE__, __FUNCTION__, __LINE__, count, (origin ? origin : "null")); + + if (count != 2) + return; + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: '%s' said in channel %s: %s\n", origin ? origin : "someone", params[0], params[1]); + + if (!origin) { + return; + } + + char realNick[128] = ""; + get_nickname(origin, realNick, 127); + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: event signalled realNick [%s] origin [%s]\n", realNick, origin); + + IRCThread *ctx = (IRCThread *) irc_get_ctx(session); + if (ctx != NULL) { + MutexSafeWrapper safeMutex(ctx->getMutexIRCCB(), string(__FILE__) + "_" + intToStr(__LINE__)); + IRCCallbackInterface *cb = ctx->getCallbackObj(false); + if (cb != NULL) { + cb->IRC_CallbackEvent(IRC_evt_chatText, realNick, params, count); + } + } + + // if ( !strcmp (params[1], "quit") ) + // irc_cmd_quit (session, "of course, Master!"); + // + // if ( !strcmp (params[1], "help") ) { + // irc_cmd_msg (session, params[0], "quit, help, dcc chat, dcc send, ctcp"); + // } + // + // if ( !strcmp (params[1], "ctcp") ) { + // irc_cmd_ctcp_request (session, realNick, "PING 223"); + // irc_cmd_ctcp_request (session, realNick, "FINGER"); + // irc_cmd_ctcp_request (session, realNick, "VERSION"); + // irc_cmd_ctcp_request (session, realNick, "TIME"); + // } + // + // if ( !strcmp (params[1], "dcc chat") ) { + // irc_dcc_t dccid; + // irc_dcc_chat (session, 0, realNick, dcc_recv_callback, &dccid); + // if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC chat ID: %d\n", dccid); + // } + // + // if ( !strcmp (params[1], "dcc send") ) { + // irc_dcc_t dccid; + // irc_dcc_sendfile (session, 0, realNick, "irctest.c", dcc_file_recv_callback, &dccid); + // if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("DCC send ID: %d\n", dccid); + // } + // + // if ( !strcmp (params[1], "topic") ) { + // irc_cmd_topic (session, params[0], 0); + // } + // else if ( strstr (params[1], "topic ") == params[1] ) { + // irc_cmd_topic (session, params[0], params[1] + 6); + // } + // + // if ( strstr (params[1], "mode ") == params[1] ) + // irc_cmd_channel_mode (session, params[0], params[1] + 5); + // + // if ( strstr (params[1], "nick ") == params[1] ) + // irc_cmd_nick (session, params[1] + 5); + // + // if ( strstr (params[1], "whois ") == params[1] ) + // irc_cmd_whois (session, params[1] + 5); + } + + void irc_event_dcc_chat(irc_session_t * session, const char * nick, const char * addr, irc_dcc_t dccid) { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("DCC chat [%d] requested from '%s' (%s)\n", dccid, nick, addr); + + irc_dcc_accept(session, dccid, 0, dcc_recv_callback); + } + + void irc_event_dcc_send(irc_session_t * session, const char * nick, const char * addr, const char * filename, unsigned long size, irc_dcc_t dccid) { + FILE * fp; + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("DCC send [%d] requested from '%s' (%s): %s (%lu bytes)\n", dccid, nick, addr, filename, size); + + if ((fp = fopen("file", "wb")) == 0) { + abort(); + } + irc_dcc_accept(session, dccid, fp, dcc_file_recv_callback); + } + + void event_leave(irc_session_t *session, const char *event, const char *origin, const char ** params, unsigned count) { + char buf[24] = ""; + sprintf(buf, "%s", event); + + // someone left the channel. + if (origin) { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: user left channel [%s]\n", origin); + + char realNick[128] = ""; + get_nickname(origin, realNick, 127); + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: user left channel realNick [%s] origin [%s]\n", realNick, origin); + + IRCThread *ctx = (IRCThread *) irc_get_ctx(session); + if (ctx != NULL) { + MutexSafeWrapper safeMutex(ctx->getMutexNickList(), string(__FILE__) + "_" + intToStr(__LINE__)); + std::vector &nickList = ctx->getCachedNickList(); + for (unsigned int i = 0; + i < nickList.size(); ++i) { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: lookingfor match [%s] realNick [%s]\n", nickList[i].c_str(), realNick); + + if (nickList[i] == realNick) { + nickList.erase(nickList.begin() + i); + break; + } + } + } + } + + dump_event(session, buf, origin, params, count); + } + void event_numeric(irc_session_t * session, unsigned int event, const char * origin, const char ** params, unsigned int count) { + char buf[24] = ""; + sprintf(buf, "%u", event); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d event = %u\n", __LINE__, event); + + switch (event) { + case LIBIRC_RFC_ERR_NICKNAMEINUSE: + case LIBIRC_RFC_ERR_NICKCOLLISION: + //irc_auto_rename_nick(session); + //IRCThread *ctx = (IRCThread *)irc_get_ctx(session); + //if(ctx != NULL) { + // { + // //IRC: Event "433", origin: "leguin.freenode.net", params: 3 [*|softcoder|Nickname is already in use.] + // printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + // //if(strstr (params[1], "Nickname is already in use") == params[1]) { + // IRCThread *ctx = (IRCThread *)irc_get_ctx(session); + // if(ctx != NULL) { + // if(ctx->getExecute_cmd_onconnect() != "") { + // irc_cmd_msg(session, "nickserv", ctx->getExecute_cmd_onconnect().c_str()); + // } + // } + // //} + // } + break; + + case LIBIRC_RFC_ERR_NOTREGISTERED: + //irc_auto_rename_nick(session); + //IRCThread *ctx = (IRCThread *)irc_get_ctx(session); + //if(ctx != NULL) { + // { + //===> IRC: Event "451", origin: "leguin.freenode.net", params: 2 [*|You have not registered] + // printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + // //if(strstr (params[1], "Nickname is already in use") == params[1]) { + // IRCThread *ctx = (IRCThread *)irc_get_ctx(session); + // if(ctx != NULL) { + // //if(ctx->getExecute_cmd_onconnect() != "") { + // //irc_cmd_msg(session, "nickserv", ctx->getExecute_cmd_onconnect().c_str()); + // string cmd = "REGISTER " + ctx->getNick() + " NOMAIL"; + // irc_cmd_msg (session, "nickserv", cmd.c_str()); + // //} + // } + // //} + // } + break; + + case LIBIRC_RFC_RPL_TOPIC: + break; + case LIBIRC_RFC_RPL_NAMREPLY: + { + if (event == LIBIRC_RFC_RPL_NAMREPLY) { + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: LIBIRC_RFC_RPL_NAMREPLY count = %u\n", count); + + std::vector nickList; + if (count >= 4) { + for (unsigned int i = 3; i < count && params[i]; ++i) { + vector tokens; + Tokenize(params[i], tokens, " "); + + for (unsigned int j = 0; j < tokens.size(); ++j) { + + char realNick[128] = ""; + get_nickname(tokens[j].c_str(), realNick, 127); + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: LIBIRC_RFC_RPL_NAMREPLY user joined channel realNick [%s] tokens[j] [%s]\n", realNick, tokens[j].c_str()); + + // Only show MegaGlest users in the user list + //if(strncmp(&realNick[0],"MG_",3) == 0) { + nickList.push_back(realNick); + //} + } + } + } + + IRCThread *ctx = (IRCThread *) irc_get_ctx(session); + if (ctx != NULL) { + MutexSafeWrapper safeMutex(ctx->getMutexNickList(), string(__FILE__) + "_" + intToStr(__LINE__)); + ctx->setCachedNickList(nickList); + } + } + break; + } + case LIBIRC_RFC_RPL_ENDOFNAMES: + { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("!!!!! ===> IRC: Line: %d event = %u\n", __LINE__, event); + + IRCThread *ctx = (IRCThread *) irc_get_ctx(session); + if (ctx != NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d event = %u\n", __LINE__, event); + + ctx->setEventDataDone(true); + } + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d event = %u\n", __LINE__, event); + } + break; + } + + dump_event(session, buf, origin, params, count); + } + +#endif + + bool IRCThread::getEventDataDone() { + MutexSafeWrapper safeMutex(&mutexEventDataDone, string(__FILE__) + "_" + intToStr(__LINE__)); + bool result = eventDataDone; safeMutex.ReleaseLock(); - return 3; + + return result; + } + void IRCThread::setEventDataDone(bool value) { + MutexSafeWrapper safeMutex(&mutexEventDataDone, string(__FILE__) + "_" + intToStr(__LINE__)); + eventDataDone = value; } - isSessionConnected = isConnected(false); - safeMutex.ReleaseLock(true); - } - - return 0; -} - -IRCThread::~IRCThread() { - //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In ~IRCThread() ...\n"); - - if(IRCThread::globalCacheContainerName != NULL) { - //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); - - IRCThread * &ircClient = CacheManager::getCachedItem< IRCThread * >(IRCThread::globalCacheContainerName); - ircClient = NULL; - } - - //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); -} - -void normalizeNick(char *nick) { - // http://tools.ietf.org/html/rfc1459#section-2.3.1 -// ::= [ "," ] -// ::= | '@' | | -// ::= ('#' | '&') -// ::= -// ::= see RFC 952 [DNS:4] for details on allowed hostnames -// ::= { | | } -// ::= ('#' | '$') -// ::= -// -// Other parameter syntaxes are: -// -// ::= { } -// ::= 'a' ... 'z' | 'A' ... 'Z' -// ::= '0' ... '9' -// ::= '-' | '[' | ']' | '\' | '`' | '^' | '{' | '}' - - if(nick != NULL && strlen(nick) > 0) { - char *newNick = new char[strlen(nick)+1]; - memset(newNick,0,strlen(nick)+1); - bool nickChanged = false; - - for(unsigned int i = 0; i < strlen(nick); ++i) { - if(nick[i] == '-' || nick[i] == '[' || nick[i] == ']' || nick[i] == '_' || - nick[i] == '\\' || nick[i] == '`' || nick[i] == '^' || - nick[i] == '{' || nick[i] == '}' || - (nick[i] >= '0' && nick[i] <= '9') || - (nick[i] >= 'a' && nick[i] <= 'z') || - (nick[i] >= 'A' && nick[i] <= 'Z')) { - strncat(newNick,&nick[i],1); - } - else { - strcat(newNick,"-"); - nickChanged = true; - } - } - - if(nickChanged == true) { - strcpy(nick,newNick); - } - - delete [] newNick; - } -} - -void IRCThread::connectToHost() { - bool connectRequired = false; - - MutexSafeWrapper safeMutex(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - bool validSession = (ircSession != NULL); - safeMutex.ReleaseLock(); - - if(validSession == false) { - connectRequired = true; - } - else { -#if !defined(DISABLE_IRCCLIENT) - - MutexSafeWrapper safeMutex1(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - int result = irc_is_connected(ircSession); - if(result != 1) { - connectRequired = true; - } - safeMutex1.ReleaseLock(); -#endif - } - - if(connectRequired == false) { -#if !defined(DISABLE_IRCCLIENT) - MutexSafeWrapper safeMutex1(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - if(irc_connect(ircSession, argv[0].c_str(), IRC_SERVER_PORT, 0, this->nick.c_str(), this->username.c_str(), "zetaglest")) { - safeMutex1.ReleaseLock(); - - if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC Could not connect: %s\n", irc_strerror (irc_errno(ircSession))); - return; - } - safeMutex1.ReleaseLock(); -#endif - } -} - -void IRCThread::joinChannel() { - wantToLeaveChannel = false; - connectToHost(); - - MutexSafeWrapper safeMutex(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - bool validSession = (ircSession != NULL); - safeMutex.ReleaseLock(); - - if(validSession == true) { -#if !defined(DISABLE_IRCCLIENT) - - MutexSafeWrapper safeMutex1(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - IRCThread *ctx = (IRCThread *)irc_get_ctx(ircSession); - if(ctx != NULL) { + IRCThread::IRCThread(const std::vector &argv, IRCCallbackInterface *callbackObj) : BaseThread() { + uniqueID = "IRCThread"; + this->argv = argv; + this->callbackObj = callbackObj; + ircSession = NULL; eventData.clear(); setEventDataDone(false); hasJoinedChannel = false; lastNickListUpdate = time(NULL); - - irc_cmd_join(ircSession, ctx->getChannel().c_str(), 0); - safeMutex.ReleaseLock(); + wantToLeaveChannel = false; + playerName = ""; + glestVersionString = ""; } - safeMutex.ReleaseLock(); -#endif - } -} -void IRCThread::leaveChannel() { - wantToLeaveChannel = true; - - MutexSafeWrapper safeMutex(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - bool validSession = (ircSession != NULL); - safeMutex.ReleaseLock(); - - if(validSession == true) { + void IRCThread::disconnect() { #if !defined(DISABLE_IRCCLIENT) - MutexSafeWrapper safeMutex1(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); - IRCThread *ctx = (IRCThread *)irc_get_ctx(ircSession); - if(ctx != NULL) { - irc_cmd_part(ircSession,ctx->getChannel().c_str()); + MutexSafeWrapper safeMutex(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + bool validSession = (ircSession != NULL); safeMutex.ReleaseLock(); - } - safeMutex.ReleaseLock(); -#endif - } -} -}}//end namespace + if (validSession == true) { + setCallbackObj(NULL); + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Quitting Channel\n"); + + MutexSafeWrapper safeMutex1(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + if (ircSession != NULL) { + irc_disconnect(ircSession); + } + safeMutex1.ReleaseLock(); + + BaseThread::signalQuit(); + hasJoinedChannel = false; + } +#else + BaseThread::signalQuit(); +#endif + } + + void IRCThread::signalQuit() { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: signalQuit [%p]\n", ircSession); + +#if !defined(DISABLE_IRCCLIENT) + + MutexSafeWrapper safeMutex(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + bool validSession = (ircSession != NULL); + safeMutex.ReleaseLock(); + + if (validSession == true) { + setCallbackObj(NULL); + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Quitting Channel\n"); + + MutexSafeWrapper safeMutex1(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + if (ircSession != NULL) { + irc_cmd_quit(ircSession, "ZG Bot is closing!"); + } + safeMutex1.ReleaseLock(); + hasJoinedChannel = false; + } + BaseThread::signalQuit(); + +#else + BaseThread::signalQuit(); +#endif + } + + bool IRCThread::shutdownAndWait() { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: shutdownAndWait [%p]\n", ircSession); + + signalQuit(); + return BaseThread::shutdownAndWait(); + } + + void IRCThread::SendIRCCmdMessage(string target, string msg) { + MutexSafeWrapper safeMutex(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + bool validSession = (ircSession != NULL); + safeMutex.ReleaseLock(); + + if (validSession == true && hasJoinedChannel == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] sending IRC command to [%s] cmd [%s]\n", __FILE__, __FUNCTION__, __LINE__, target.c_str(), msg.c_str()); + +#if !defined(DISABLE_IRCCLIENT) + MutexSafeWrapper safeMutex1(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + int ret = 0; + if (ircSession != NULL) { + ret = irc_cmd_msg(ircSession, target.c_str(), msg.c_str()); + } + safeMutex1.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] sending IRC command to [%s] cmd [%s] ret = %d\n", __FILE__, __FUNCTION__, __LINE__, target.c_str(), msg.c_str(), ret); +#endif + } + } + + std::vector IRCThread::GetIRCConnectedNickList(string target, bool waitForCompletion) { + setEventDataDone(false); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + MutexSafeWrapper safeMutexSession(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + bool validSession = (ircSession != NULL); + safeMutexSession.ReleaseLock(); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + if (validSession == true && hasJoinedChannel == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] sending IRC nick list command to [%s]\n", __FILE__, __FUNCTION__, __LINE__, target.c_str()); + +#if !defined(DISABLE_IRCCLIENT) + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + MutexSafeWrapper safeMutex1(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + int ret = irc_cmd_names(ircSession, target.c_str()); + safeMutex1.ReleaseLock(); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] sending IRC nick list command to [%s] ret = %d\n", __FILE__, __FUNCTION__, __LINE__, target.c_str(), ret); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + if (waitForCompletion == true) { + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + for (time_t tElapsed = time(NULL); + getEventDataDone() == false && + this->getQuitStatus() == false && + difftime(time(NULL), tElapsed) <= 5;) { + sleep(50); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); +#endif + } + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + MutexSafeWrapper safeMutex(&mutexNickList, string(__FILE__) + "_" + intToStr(__LINE__)); + std::vector nickList = eventData; + safeMutex.ReleaseLock(); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + return nickList; + } + + bool IRCThread::isConnected(bool mutexLockRequired) { + bool ret = false; + if (this->getQuitStatus() == false) { + MutexSafeWrapper safeMutex(NULL, string(__FILE__) + "_" + intToStr(__LINE__)); + int lockStatus = 0; + if (mutexLockRequired == true) { + lockStatus = safeMutex.setMutexAndTryLock(&mutexIRCSession); + } + bool validSession = (lockStatus == SDL_MUTEX_TIMEDOUT || (lockStatus == 0 && ircSession != NULL)); + if (mutexLockRequired == true && lockStatus == 0) { + safeMutex.ReleaseLock(); + } + + if (validSession == true) { +#if !defined(DISABLE_IRCCLIENT) + MutexSafeWrapper safeMutex1(NULL, string(__FILE__) + "_" + intToStr(__LINE__)); + if (ircSession != NULL) { + lockStatus = 0; + if (mutexLockRequired == true) { + lockStatus = safeMutex1.setMutexAndTryLock(&mutexIRCSession); + } + ret = (lockStatus == SDL_MUTEX_TIMEDOUT || (lockStatus == 0 && irc_is_connected(ircSession) != 0)); + } + if (mutexLockRequired == true && lockStatus == 0) { + safeMutex1.ReleaseLock(); + } + } +#endif + } + + return ret; + } + + std::vector IRCThread::getNickList() { + MutexSafeWrapper safeMutex(&mutexNickList, string(__FILE__) + "_" + intToStr(__LINE__)); + std::vector nickList = eventData; + safeMutex.ReleaseLock(); + + return nickList; + } + + IRCCallbackInterface * IRCThread::getCallbackObj(bool lockObj) { + MutexSafeWrapper safeMutex(NULL, string(__FILE__) + "_" + intToStr(__LINE__)); + if (lockObj == true) { + safeMutex.setMutex(&mutexIRCCB); + } + return callbackObj; + } + void IRCThread::setCallbackObj(IRCCallbackInterface *cb) { + MutexSafeWrapper safeMutex(&mutexIRCCB, string(__FILE__) + "_" + intToStr(__LINE__)); + callbackObj = cb; + } + + void IRCThread::execute() { + { + RunningStatusSafeWrapper runningStatus(this); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] argv.size() = %d\n", __FILE__, __FUNCTION__, __LINE__, argv.size()); + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: IRCThread::execute Line: %d\n", __LINE__); + + if (getQuitStatus() == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + return; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "IRC thread is running\n"); + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + try { +#if !defined(DISABLE_IRCCLIENT) + irc_callbacks_t callbacks; + + MutexSafeWrapper safeMutex(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + ircSession = NULL; + safeMutex.ReleaseLock(true); + + if (argv.size() != 5) { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC Usage: : got params [%ld]\n", (long int) argv.size()); + return; + } + + memset(&callbacks, 0, sizeof(callbacks)); + + callbacks.event_connect = event_connect; + callbacks.event_join = event_join; + callbacks.event_nick = dump_event; + callbacks.event_quit = dump_event; + callbacks.event_part = event_leave; + callbacks.event_mode = dump_event; + callbacks.event_topic = dump_event; + callbacks.event_kick = dump_event; + callbacks.event_channel = event_channel; + callbacks.event_privmsg = event_privmsg; + callbacks.event_notice = event_notice; + callbacks.event_invite = dump_event; + callbacks.event_umode = dump_event; + callbacks.event_ctcp_rep = dump_event; + callbacks.event_ctcp_action = dump_event; + callbacks.event_unknown = dump_event; + callbacks.event_numeric = event_numeric; + + callbacks.event_dcc_chat_req = irc_event_dcc_chat; + callbacks.event_dcc_send_req = irc_event_dcc_send; + + if (this->getQuitStatus() == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + return; + } + safeMutex.Lock(); + ircSession = irc_create_session(&callbacks); + bool validSession = (ircSession != NULL); + + if (validSession == false) { + safeMutex.ReleaseLock(); + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC Could not create session\n"); + return; + } + safeMutex.ReleaseLock(true); + + // this->execute_cmd_onconnect = ""; + // if(argv.size() >= 5) { + // this->execute_cmd_onconnect = argv[4]; // /msg NickServ identify . + // } + + // this->password = ""; + // if(argv.size() >= 5) { + // this->password = argv[4]; + // } + this->username = argv[1]; + if (argv.size() >= 4) { + this->username = argv[3]; + } + this->channel = argv[2]; + this->nick = argv[1]; + + safeMutex.Lock(); + irc_set_ctx(ircSession, this); + safeMutex.ReleaseLock(true); + + if (this->getQuitStatus() == true) { + return; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + safeMutex.Lock(); + if (irc_connect(ircSession, argv[0].c_str(), IRC_SERVER_PORT, 0, this->nick.c_str(), this->username.c_str(), ("MegagGlest " + glestVersionString).c_str())) { + safeMutex.ReleaseLock(); + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC Could not connect: %s\n", irc_strerror(irc_errno(ircSession))); + return; + } + safeMutex.ReleaseLock(); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + if (this->getQuitStatus() == true) { + return; + } + + if (this->getQuitStatus() == true) { + return; + } + + //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + for (int iAttempts = 1; + this->getQuitStatus() == false && iAttempts <= 7; ++iAttempts) { + //if(irc_run(ircSession)) { + + int run_result = irc_run_session(ircSession); + if (run_result && this->getQuitStatus() == false) { + //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC Could not run the session: %s run_result = %d\n", irc_strerror(irc_errno(ircSession)), run_result); + printf("===> IRC Could not run the session: %s run_result = %d\n", irc_strerror(irc_errno(ircSession)), run_result); + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + + //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); +#else + for (; this->getQuitStatus() == false;) { + sleep(50); + } +#endif + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC exiting IRC CLient!\n"); + //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + } catch (...) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] UNKNOWN Error\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] unknown error\n", __FILE__, __FUNCTION__, __LINE__); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] IRC thread is exiting\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); + + + //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); + // Delete ourself when the thread is done (no other actions can happen after this + // such as the mutex which modifies the running status of this method + MutexSafeWrapper safeMutex(&mutexIRCCB, string(__FILE__) + "_" + intToStr(__LINE__)); + IRCCallbackInterface *cb = getCallbackObj(false); + if (cb != NULL) { + //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC: Line: %d\n", __LINE__); + cb->IRC_CallbackEvent(IRC_evt_exitThread, NULL, NULL, 0); + } + safeMutex.ReleaseLock(); + + } + //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In IRCThread() calling delete ...\n"); + + //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); + setDeleteAfterExecute(true); + } + + int IRCThread::irc_run_session(irc_session_t * session) { + // if ( session->state != LIBIRC_STATE_CONNECTING ) + // { + // session->lasterror = LIBIRC_ERR_STATE; + // return 1; + // } + + MutexSafeWrapper safeMutex(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + + if (isConnected(false) == false) { + //session->lasterror = LIBIRC_ERR_STATE; + return 1; + } + safeMutex.ReleaseLock(true); + + bool isSessionConnected = true; + while (isSessionConnected == true && this->getQuitStatus() == false) { + struct timeval tv; + fd_set in_set, out_set; + int maxfd = 0; + + tv.tv_usec = 250000; + tv.tv_sec = 0; + + // Init sets + FD_ZERO(&in_set); + FD_ZERO(&out_set); + + safeMutex.Lock(); + irc_add_select_descriptors(session, &in_set, &out_set, &maxfd); + safeMutex.ReleaseLock(true); + + if (select(maxfd + 1, &in_set, &out_set, 0, &tv) < 0) { + int lastSocketError = Socket::getLastSocketError(); + if (lastSocketError == PLATFORM_SOCKET_INTERRUPTED) { + continue; + } + + //session->lasterror = LIBIRC_ERR_TERMINATED; + return 2; + } + + safeMutex.Lock(); + if (irc_process_select_descriptors(session, &in_set, &out_set)) { + safeMutex.ReleaseLock(); + return 3; + } + + isSessionConnected = isConnected(false); + safeMutex.ReleaseLock(true); + } + + return 0; + } + + IRCThread::~IRCThread() { + //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In ~IRCThread() ...\n"); + + if (IRCThread::globalCacheContainerName != NULL) { + //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); + + IRCThread * &ircClient = CacheManager::getCachedItem< IRCThread * >(IRCThread::globalCacheContainerName); + ircClient = NULL; + } + + //printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this); + } + + void normalizeNick(char *nick) { + // http://tools.ietf.org/html/rfc1459#section-2.3.1 + // ::= [ "," ] + // ::= | '@' | | + // ::= ('#' | '&') + // ::= + // ::= see RFC 952 [DNS:4] for details on allowed hostnames + // ::= { | | } + // ::= ('#' | '$') + // ::= + // + // Other parameter syntaxes are: + // + // ::= { } + // ::= 'a' ... 'z' | 'A' ... 'Z' + // ::= '0' ... '9' + // ::= '-' | '[' | ']' | '\' | '`' | '^' | '{' | '}' + + if (nick != NULL && strlen(nick) > 0) { + char *newNick = new char[strlen(nick) + 1]; + memset(newNick, 0, strlen(nick) + 1); + bool nickChanged = false; + + for (unsigned int i = 0; i < strlen(nick); ++i) { + if (nick[i] == '-' || nick[i] == '[' || nick[i] == ']' || nick[i] == '_' || + nick[i] == '\\' || nick[i] == '`' || nick[i] == '^' || + nick[i] == '{' || nick[i] == '}' || + (nick[i] >= '0' && nick[i] <= '9') || + (nick[i] >= 'a' && nick[i] <= 'z') || + (nick[i] >= 'A' && nick[i] <= 'Z')) { + strncat(newNick, &nick[i], 1); + } else { + strcat(newNick, "-"); + nickChanged = true; + } + } + + if (nickChanged == true) { + strcpy(nick, newNick); + } + + delete[] newNick; + } + } + + void IRCThread::connectToHost() { + bool connectRequired = false; + + MutexSafeWrapper safeMutex(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + bool validSession = (ircSession != NULL); + safeMutex.ReleaseLock(); + + if (validSession == false) { + connectRequired = true; + } else { +#if !defined(DISABLE_IRCCLIENT) + + MutexSafeWrapper safeMutex1(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + int result = irc_is_connected(ircSession); + if (result != 1) { + connectRequired = true; + } + safeMutex1.ReleaseLock(); +#endif + } + + if (connectRequired == false) { +#if !defined(DISABLE_IRCCLIENT) + MutexSafeWrapper safeMutex1(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + if (irc_connect(ircSession, argv[0].c_str(), IRC_SERVER_PORT, 0, this->nick.c_str(), this->username.c_str(), "zetaglest")) { + safeMutex1.ReleaseLock(); + + if (SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf("===> IRC Could not connect: %s\n", irc_strerror(irc_errno(ircSession))); + return; + } + safeMutex1.ReleaseLock(); +#endif + } + } + + void IRCThread::joinChannel() { + wantToLeaveChannel = false; + connectToHost(); + + MutexSafeWrapper safeMutex(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + bool validSession = (ircSession != NULL); + safeMutex.ReleaseLock(); + + if (validSession == true) { +#if !defined(DISABLE_IRCCLIENT) + + MutexSafeWrapper safeMutex1(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + IRCThread *ctx = (IRCThread *) irc_get_ctx(ircSession); + if (ctx != NULL) { + eventData.clear(); + setEventDataDone(false); + hasJoinedChannel = false; + lastNickListUpdate = time(NULL); + + irc_cmd_join(ircSession, ctx->getChannel().c_str(), 0); + safeMutex.ReleaseLock(); + } + safeMutex.ReleaseLock(); +#endif + } + } + + void IRCThread::leaveChannel() { + wantToLeaveChannel = true; + + MutexSafeWrapper safeMutex(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + bool validSession = (ircSession != NULL); + safeMutex.ReleaseLock(); + + if (validSession == true) { +#if !defined(DISABLE_IRCCLIENT) + + MutexSafeWrapper safeMutex1(&mutexIRCSession, string(__FILE__) + "_" + intToStr(__LINE__)); + IRCThread *ctx = (IRCThread *) irc_get_ctx(ircSession); + if (ctx != NULL) { + irc_cmd_part(ircSession, ctx->getChannel().c_str()); + safeMutex.ReleaseLock(); + } + safeMutex.ReleaseLock(); +#endif + } + } + + } +}//end namespace diff --git a/source/shared_lib/sources/platform/posix/miniftpclient.cpp b/source/shared_lib/sources/platform/posix/miniftpclient.cpp index c795b8767..3f65091db 100644 --- a/source/shared_lib/sources/platform/posix/miniftpclient.cpp +++ b/source/shared_lib/sources/platform/posix/miniftpclient.cpp @@ -23,1222 +23,1199 @@ using namespace Shared::Util; using namespace Shared::PlatformCommon; -namespace Shared { namespace PlatformCommon { +namespace Shared { + namespace PlatformCommon { -static const char *FTP_MAPS_CUSTOM_USERNAME = "maps_custom"; -static const char *FTP_MAPS_USERNAME = "maps"; -static const char *FTP_TILESETS_CUSTOM_USERNAME = "tilesets_custom"; -static const char *FTP_TILESETS_USERNAME = "tilesets"; -static const char *FTP_TECHTREES_CUSTOM_USERNAME = "techtrees_custom"; -static const char *FTP_TECHTREES_USERNAME = "techtrees"; + static const char *FTP_MAPS_CUSTOM_USERNAME = "maps_custom"; + static const char *FTP_MAPS_USERNAME = "maps"; + static const char *FTP_TILESETS_CUSTOM_USERNAME = "tilesets_custom"; + static const char *FTP_TILESETS_USERNAME = "tilesets"; + static const char *FTP_TECHTREES_CUSTOM_USERNAME = "techtrees_custom"; + static const char *FTP_TECHTREES_USERNAME = "techtrees"; -static const char *FTP_TEMPFILES_USERNAME = "temp"; + static const char *FTP_TEMPFILES_USERNAME = "temp"; -static const char *FTP_COMMON_PASSWORD = "mg_ftp_server"; + static const char *FTP_COMMON_PASSWORD = "mg_ftp_server"; -/* - * This is an example showing how to get a single file from an FTP server. - * It delays the actual destination file creation until the first write - * callback so that it won't create an empty file in case the remote file - * doesn't exist or something else fails. - */ + /* + * This is an example showing how to get a single file from an FTP server. + * It delays the actual destination file creation until the first write + * callback so that it won't create an empty file in case the remote file + * doesn't exist or something else fails. + */ -struct FtpFile { - const char *itemName; - const char *filename; - const char *filepath; - FILE *stream; - FTPClientThread *ftpServer; - string currentFilename; - bool isValidXfer; - FTP_Client_CallbackType downloadType; -}; + struct FtpFile { + const char *itemName; + const char *filename; + const char *filepath; + FILE *stream; + FTPClientThread *ftpServer; + string currentFilename; + bool isValidXfer; + FTP_Client_CallbackType downloadType; + }; -static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) { - struct FtpFile *out=(struct FtpFile *)stream; + static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) { + struct FtpFile *out = (struct FtpFile *)stream; - string fullFilePath = ""; - if(out != NULL && out->filepath != NULL) { - fullFilePath = out->filepath; - } - if(out != NULL && out->filename != NULL) { - fullFilePath += out->filename; - } + string fullFilePath = ""; + if (out != NULL && out->filepath != NULL) { + fullFilePath = out->filepath; + } + if (out != NULL && out->filename != NULL) { + fullFilePath += out->filename; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread writing to file [%s]\n",fullFilePath.c_str()); - //printf ("===> FTP Client thread writing to file [%s]\n",fullFilePath.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread writing to file [%s]\n", fullFilePath.c_str()); + //printf ("===> FTP Client thread writing to file [%s]\n",fullFilePath.c_str()); - // Abort file xfer and delete partial file - if(out && out->ftpServer && out->ftpServer->getQuitStatus() == true) { - if(out->stream) { - fclose(out->stream); - out->stream = NULL; - } + // Abort file xfer and delete partial file + if (out && out->ftpServer && out->ftpServer->getQuitStatus() == true) { + if (out->stream) { + fclose(out->stream); + out->stream = NULL; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread CANCELLED, deleting file for writing [%s]\n",fullFilePath.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread CANCELLED, deleting file for writing [%s]\n",fullFilePath.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread CANCELLED, deleting file for writing [%s]\n", fullFilePath.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client thread CANCELLED, deleting file for writing [%s]\n", fullFilePath.c_str()); - removeFile(fullFilePath); - return 0; - } + removeFile(fullFilePath); + return 0; + } - if(out && out->stream == NULL) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread opening file for writing [%s]\n",fullFilePath.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread opening file for writing [%s]\n",fullFilePath.c_str()); + if (out && out->stream == NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread opening file for writing [%s]\n", fullFilePath.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client thread opening file for writing [%s]\n", fullFilePath.c_str()); - /* open file for writing */ + /* open file for writing */ #ifdef WIN32 - out->stream= _wfopen(utf8_decode(fullFilePath).c_str(), L"wb"); + out->stream = _wfopen(utf8_decode(fullFilePath).c_str(), L"wb"); #else - out->stream = fopen(fullFilePath.c_str(), "wb"); + out->stream = fopen(fullFilePath.c_str(), "wb"); #endif - if(out->stream == NULL) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread FAILED to open file for writing [%s]\n",fullFilePath.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread FAILED to open file for writing [%s]\n",fullFilePath.c_str()); - SystemFlags::OutputDebug(SystemFlags::debugError,"===> FTP Client thread FAILED to open file for writing [%s]\n",fullFilePath.c_str()); - return 0; /* failure, can't open file to write */ - } - - out->isValidXfer = true; - } - else if(out == NULL) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> #2 FTP Client thread FAILED to open file for writing [%s]\n",fullFilePath.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> #2 FTP Client thread FAILED to open file for writing [%s]\n",fullFilePath.c_str()); - SystemFlags::OutputDebug(SystemFlags::debugError,"===> #2 FTP Client thread FAILED to open file for writing [%s]\n",fullFilePath.c_str()); - return 0; /* failure, can't open file to write */ - } - - size_t result = fwrite(buffer, size, nmemb, out->stream); - if(result != nmemb) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread FAILED to write data chunk to file [%s] nmemb = " MG_SIZE_T_SPECIFIER ", result = " MG_SIZE_T_SPECIFIER "\n",fullFilePath.c_str(),nmemb,result); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread FAILED to write data chunk to file [%s] nmemb = " MG_SIZE_T_SPECIFIER ", result = " MG_SIZE_T_SPECIFIER "\n",fullFilePath.c_str(),nmemb,result); - SystemFlags::OutputDebug(SystemFlags::debugError,"===> FTP Client thread FAILED to write data chunk to file [%s] nmemb = " MG_SIZE_T_SPECIFIER ", result = " MG_SIZE_T_SPECIFIER "\n",fullFilePath.c_str(),nmemb,result); - //return -1; /* failure, can't open file to write */ - } - return result; -} - -/* -static long file_is_comming(struct curl_fileinfo *finfo,void *data,int remains) { - struct FtpFile *out=(struct FtpFile *)data; - - string rootFilePath = ""; - string fullFilePath = ""; - if(out != NULL && out->filepath != NULL) { - rootFilePath = out->filepath; - } - if(out != NULL && out->filename != NULL) { - fullFilePath = rootFilePath + finfo->filename; - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n===> FTP Client thread file_is_comming: remains: [%3d] filename: [%s] size: [%10luB] ", remains, finfo->filename,(unsigned long)finfo->size); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread file_is_comming: remains: [%3d] filename: [%s] size: [%10luB] ", remains, finfo->filename,(unsigned long)finfo->size); - - if(out != NULL) { - //out->currentFilename = finfo->filename; - out->currentFilename = fullFilePath; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" current filename: [%s] ", fullFilePath.c_str()); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"current filename: [%s] ", fullFilePath.c_str()); - } - - switch(finfo->filetype) { - case CURLFILETYPE_DIRECTORY: - if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" DIR (creating [%s%s])\n",rootFilePath.c_str(),finfo->filename); - SystemFlags::OutputDebug(SystemFlags::debugNetwork," DIR (creating [%s%s])\n",rootFilePath.c_str(),finfo->filename); - - rootFilePath += finfo->filename; - createDirectoryPaths(rootFilePath.c_str()); - break; - case CURLFILETYPE_FILE: - if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" FILE "); - SystemFlags::OutputDebug(SystemFlags::debugNetwork," FILE "); - break; - default: - if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" OTHER\n"); - SystemFlags::OutputDebug(SystemFlags::debugNetwork," OTHER\n"); - break; - } - - if(finfo->filetype == CURLFILETYPE_FILE) { - // do not transfer files >= 50B - //if(finfo->size > 50) { - // printf("SKIPPED\n"); - // return CURL_CHUNK_BGN_FUNC_SKIP; - //} - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" opening file [%s] ", fullFilePath.c_str()); - SystemFlags::OutputDebug(SystemFlags::debugNetwork," opening file [%s] ", fullFilePath.c_str()); - - out->stream = fopen(fullFilePath.c_str(), "wb"); - if(out->stream == NULL) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread FAILED to open file for writing [%s]\n",fullFilePath.c_str()); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread FAILED to open file for writing [%s]\n",fullFilePath.c_str()); - - return CURL_CHUNK_BGN_FUNC_FAIL; - } - } - - out->isValidXfer = true; - return CURL_CHUNK_BGN_FUNC_OK; -} - -static long file_is_downloaded(void *data) { - struct FtpFile *out=(struct FtpFile *)data; - if(out->stream) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("DOWNLOAD COMPLETE!\n"); - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"DOWNLOAD COMPLETE!\n"); - - fclose(out->stream); - out->stream = NULL; - } - return CURL_CHUNK_END_FUNC_OK; -} -*/ - -int file_progress(struct FtpFile *out,double download_total, double download_now, double upload_total,double upload_now) { - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" download progress [%f][%f][%f][%f] ",download_total,download_now,upload_total,upload_now); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork," download progress [%f][%f][%f][%f] ",download_total,download_now,upload_total,upload_now); - - if(out != NULL && - out->ftpServer != NULL && - out->ftpServer->getCallBackObject() != NULL) { - if(out->ftpServer->getQuitStatus() == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread CANCELLED\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread CANCELLED\n"); - - return -1; - } - FTPClientCallbackInterface::FtpProgressStats stats; - stats.download_total = download_total; - stats.download_now = download_now; - stats.upload_total = upload_total; - stats.upload_now = upload_now; - stats.currentFilename = out->currentFilename; - stats.downloadType = out->downloadType; - - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(out->ftpServer->getProgressMutex(),mutexOwnerId); - out->ftpServer->getProgressMutex()->setOwnerId(mutexOwnerId); - out->ftpServer->getCallBackObject()->FTPClient_CallbackEvent( - out->itemName, - ftp_cct_DownloadProgress, - make_pair(ftp_crt_SUCCESS,""), - &stats); - } - - return 0; -} - -FTPClientThread::FTPClientThread(int portNumber, string serverUrl, - std::pair mapsPath, - std::pair tilesetsPath, - std::pair techtreesPath, - std::pair scenariosPath, - FTPClientCallbackInterface *pCBObject, - string fileArchiveExtension, - string fileArchiveExtractCommand, - string fileArchiveExtractCommandParameters, - int fileArchiveExtractCommandSuccessResult, - string tempFilesPath) : BaseThread() { - - uniqueID = "FTPClientThread"; - this->portNumber = portNumber; - this->serverUrl = serverUrl; - this->mapsPath = mapsPath; - this->tilesetsPath = tilesetsPath; - this->techtreesPath = techtreesPath; - this->scenariosPath = scenariosPath; - this->pCBObject = pCBObject; - this->shellCommandCallbackUserData = ""; - - this->fileArchiveExtension = fileArchiveExtension; - this->fileArchiveExtractCommand = fileArchiveExtractCommand; - this->fileArchiveExtractCommandParameters = fileArchiveExtractCommandParameters; - this->fileArchiveExtractCommandSuccessResult = fileArchiveExtractCommandSuccessResult; - this->tempFilesPath = tempFilesPath; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line %d] Using FTP port #: %d, serverUrl [%s]\n",__FILE__,__FUNCTION__,__LINE__,portNumber,serverUrl.c_str()); -} - -void FTPClientThread::signalQuit() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client: signalQuit\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client: signalQuit\n"); - BaseThread::signalQuit(); -} - -bool FTPClientThread::shutdownAndWait() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client: shutdownAndWait\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client: shutdownAndWait\n"); - - signalQuit(); - return BaseThread::shutdownAndWait(); -} - - -pair FTPClientThread::getMapFromServer(pair mapFileName, string ftpUser, string ftpUserPassword) { - pair result = make_pair(ftp_crt_FAIL,""); - - string destFileExt = ""; - string destFile = this->mapsPath.second; - - endPathWithSlash(destFile); - destFile += mapFileName.first; - - if(mapFileName.second == "") { - if(EndsWith(destFile,".mgm") == false && EndsWith(destFile,".gbm") == false) { - destFileExt = ".mgm"; - destFile += destFileExt; - } - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread about to try to RETR into [%s]\n",destFile.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread about to try to RETR into [%s]\n",destFile.c_str()); - - struct FtpFile ftpfile = { - NULL, - destFile.c_str(), /* name to store the file as if succesful */ - NULL, - NULL, - this, - "", - false, - ftp_cct_Map - }; - - CURL *curl = SystemFlags::initHTTP(); - if(curl) { - ftpfile.stream = NULL; - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); - char szBuf[8096]=""; - if(mapFileName.second != "") { - snprintf(szBuf,8096,"%s",mapFileName.second.c_str()); - curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); - } - else { - snprintf(szBuf,8096,"ftp://%s:%s@%s:%d/%s%s",ftpUser.c_str(),ftpUserPassword.c_str(),serverUrl.c_str(),portNumber,mapFileName.first.c_str(),destFileExt.c_str()); - } - - curl_easy_setopt(curl, CURLOPT_URL,szBuf); - curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L); - - /* Define our callback to get called when there's data to be written */ - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); - /* Set a pointer to our struct to pass to the callback */ - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile); - - - // Max 10 minutes to transfer - //curl_easy_setopt(curl, CURLOPT_TIMEOUT, 600); - // Max 60 minutes to transfer - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3600L); - curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, 120L); - - /* Switch on full protocol/debug output */ - if(SystemFlags::VERBOSE_MODE_ENABLED) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); - - CURLcode res = curl_easy_perform(curl); - if(res != CURLE_OK) { - result.second = curl_easy_strerror(res); - // we failed - printf("curl FAILED with: %d [%s] szBuf [%s]\n", res,curl_easy_strerror(res),szBuf); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"curl FAILED with: %d [%s] szBuf [%s]\n", res,curl_easy_strerror(res),szBuf); - - if(res == CURLE_PARTIAL_FILE) { - result.first = ftp_crt_PARTIALFAIL; - } - else if(res == CURLE_COULDNT_CONNECT) { - result.first = ftp_crt_HOST_NOT_ACCEPTING; - } - } - else { - result.first = ftp_crt_SUCCESS; - } - - SystemFlags::cleanupHTTP(&curl); - } - - if(ftpfile.stream) { - fclose(ftpfile.stream); - ftpfile.stream = NULL; - } - if(result.first != ftp_crt_SUCCESS) { - removeFile(destFile); - } - - return result; -} - -void FTPClientThread::getMapFromServer(pair mapFileName) { - pair result = make_pair(ftp_crt_FAIL,""); - if(mapFileName.second != "") { - result = getMapFromServer(mapFileName, "", ""); - } - else { - pair findMapFileName = mapFileName; - findMapFileName.first += + ".mgm"; - - result = getMapFromServer(findMapFileName, FTP_MAPS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD); - if(result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { - findMapFileName = mapFileName; - findMapFileName.first += + ".gbm"; - result = getMapFromServer(findMapFileName, FTP_MAPS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD); - if(result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { - findMapFileName = mapFileName; - findMapFileName.first += + ".mgm"; - result = getMapFromServer(findMapFileName, FTP_MAPS_USERNAME, FTP_COMMON_PASSWORD); - if(result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { - findMapFileName = mapFileName; - findMapFileName.first += + ".gbm"; - result = getMapFromServer(findMapFileName, FTP_MAPS_USERNAME, FTP_COMMON_PASSWORD); + if (out->stream == NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread FAILED to open file for writing [%s]\n", fullFilePath.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client thread FAILED to open file for writing [%s]\n", fullFilePath.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugError, "===> FTP Client thread FAILED to open file for writing [%s]\n", fullFilePath.c_str()); + return 0; /* failure, can't open file to write */ } + + out->isValidXfer = true; + } else if (out == NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> #2 FTP Client thread FAILED to open file for writing [%s]\n", fullFilePath.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> #2 FTP Client thread FAILED to open file for writing [%s]\n", fullFilePath.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugError, "===> #2 FTP Client thread FAILED to open file for writing [%s]\n", fullFilePath.c_str()); + return 0; /* failure, can't open file to write */ } + + size_t result = fwrite(buffer, size, nmemb, out->stream); + if (result != nmemb) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread FAILED to write data chunk to file [%s] nmemb = " MG_SIZE_T_SPECIFIER ", result = " MG_SIZE_T_SPECIFIER "\n", fullFilePath.c_str(), nmemb, result); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client thread FAILED to write data chunk to file [%s] nmemb = " MG_SIZE_T_SPECIFIER ", result = " MG_SIZE_T_SPECIFIER "\n", fullFilePath.c_str(), nmemb, result); + SystemFlags::OutputDebug(SystemFlags::debugError, "===> FTP Client thread FAILED to write data chunk to file [%s] nmemb = " MG_SIZE_T_SPECIFIER ", result = " MG_SIZE_T_SPECIFIER "\n", fullFilePath.c_str(), nmemb, result); + //return -1; /* failure, can't open file to write */ + } + return result; } - } - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(this->getProgressMutex(),mutexOwnerId); - this->getProgressMutex()->setOwnerId(mutexOwnerId); - if(this->pCBObject != NULL) { - this->pCBObject->FTPClient_CallbackEvent( - mapFileName.first, - ftp_cct_Map, - result, - NULL); - } -} + /* + static long file_is_comming(struct curl_fileinfo *finfo,void *data,int remains) { + struct FtpFile *out=(struct FtpFile *)data; -void FTPClientThread::addMapToRequests(string mapFilename,string URL) { - std::pair item = make_pair(mapFilename,URL); - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&mutexMapFileList,mutexOwnerId); - mutexMapFileList.setOwnerId(mutexOwnerId); - if(std::find(mapFileList.begin(),mapFileList.end(),item) == mapFileList.end()) { - mapFileList.push_back(item); - } -} + string rootFilePath = ""; + string fullFilePath = ""; + if(out != NULL && out->filepath != NULL) { + rootFilePath = out->filepath; + } + if(out != NULL && out->filename != NULL) { + fullFilePath = rootFilePath + finfo->filename; + } -void FTPClientThread::addTilesetToRequests(string tileSetName,string URL) { - std::pair item = make_pair(tileSetName,URL); - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&mutexTilesetList,mutexOwnerId); - mutexTilesetList.setOwnerId(mutexOwnerId); - if(std::find(tilesetList.begin(),tilesetList.end(),item) == tilesetList.end()) { - tilesetList.push_back(item); - } -} + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n===> FTP Client thread file_is_comming: remains: [%3d] filename: [%s] size: [%10luB] ", remains, finfo->filename,(unsigned long)finfo->size); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread file_is_comming: remains: [%3d] filename: [%s] size: [%10luB] ", remains, finfo->filename,(unsigned long)finfo->size); -void FTPClientThread::addTechtreeToRequests(string techtreeName,string URL) { - std::pair item = make_pair(techtreeName,URL); - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&mutexTechtreeList,mutexOwnerId); - mutexTechtreeList.setOwnerId(mutexOwnerId); - if(std::find(techtreeList.begin(),techtreeList.end(),item) == techtreeList.end()) { - techtreeList.push_back(item); - } -} + if(out != NULL) { + //out->currentFilename = finfo->filename; + out->currentFilename = fullFilePath; -void FTPClientThread::addScenarioToRequests(string fileName,string URL) { - std::pair item = make_pair(fileName,URL); - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&mutexScenarioList,mutexOwnerId); - mutexScenarioList.setOwnerId(mutexOwnerId); - if(std::find(scenarioList.begin(),scenarioList.end(),item) == scenarioList.end()) { - scenarioList.push_back(item); - } -} + if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" current filename: [%s] ", fullFilePath.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"current filename: [%s] ", fullFilePath.c_str()); + } -void FTPClientThread::addFileToRequests(string fileName,string URL) { - std::pair item = make_pair(fileName,URL); - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&mutexFileList,mutexOwnerId); - mutexFileList.setOwnerId(mutexOwnerId); - if(std::find(fileList.begin(),fileList.end(),item) == fileList.end()) { - fileList.push_back(item); - } -} + switch(finfo->filetype) { + case CURLFILETYPE_DIRECTORY: + if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" DIR (creating [%s%s])\n",rootFilePath.c_str(),finfo->filename); + SystemFlags::OutputDebug(SystemFlags::debugNetwork," DIR (creating [%s%s])\n",rootFilePath.c_str(),finfo->filename); -void FTPClientThread::addTempFileToRequests(string fileName,string URL) { - std::pair item = make_pair(fileName,URL); - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&mutexTempFileList,mutexOwnerId); - mutexTempFileList.setOwnerId(mutexOwnerId); - if(std::find(tempFileList.begin(),tempFileList.end(),item) == tempFileList.end()) { - tempFileList.push_back(item); - } -} + rootFilePath += finfo->filename; + createDirectoryPaths(rootFilePath.c_str()); + break; + case CURLFILETYPE_FILE: + if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" FILE "); + SystemFlags::OutputDebug(SystemFlags::debugNetwork," FILE "); + break; + default: + if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" OTHER\n"); + SystemFlags::OutputDebug(SystemFlags::debugNetwork," OTHER\n"); + break; + } -void FTPClientThread::getTilesetFromServer(pair tileSetName) { - bool findArchive = executeShellCommand( - this->fileArchiveExtractCommand, - this->fileArchiveExtractCommandSuccessResult); - - pair result = make_pair(ftp_crt_FAIL,""); - if(findArchive == true) { - if(tileSetName.second != "") { - //result = getTilesetFromServer(tileSetName, "", "", "", findArchive); - result = getTilesetFromServer(tileSetName, "", "", "", true); - } - else { - //result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, findArchive); - result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, true); - if(result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { - //if(findArchive == true) { - //result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, false); - result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, true); + if(finfo->filetype == CURLFILETYPE_FILE) { + // do not transfer files >= 50B + //if(finfo->size > 50) { + // printf("SKIPPED\n"); + // return CURL_CHUNK_BGN_FUNC_SKIP; //} - if(result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { - // result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, findArchive); - result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, true); - // if(findArchive == true) { - // result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, false); - // } + if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" opening file [%s] ", fullFilePath.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugNetwork," opening file [%s] ", fullFilePath.c_str()); + + out->stream = fopen(fullFilePath.c_str(), "wb"); + if(out->stream == NULL) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread FAILED to open file for writing [%s]\n",fullFilePath.c_str()); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread FAILED to open file for writing [%s]\n",fullFilePath.c_str()); + + return CURL_CHUNK_BGN_FUNC_FAIL; } } + + out->isValidXfer = true; + return CURL_CHUNK_BGN_FUNC_OK; } - } - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(this->getProgressMutex(),mutexOwnerId); - this->getProgressMutex()->setOwnerId(mutexOwnerId); - if(this->pCBObject != NULL) { - this->pCBObject->FTPClient_CallbackEvent( - tileSetName.first, - ftp_cct_Tileset, - result, - NULL); - } -} + static long file_is_downloaded(void *data) { + struct FtpFile *out=(struct FtpFile *)data; + if(out->stream) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("DOWNLOAD COMPLETE!\n"); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"DOWNLOAD COMPLETE!\n"); -pair FTPClientThread::getTilesetFromServer( - pair tileSetName, - string tileSetNameSubfolder, - string ftpUser, - string ftpUserPassword, - bool findArchive) { + fclose(out->stream); + out->stream = NULL; + } + return CURL_CHUNK_END_FUNC_OK; + } + */ - string destFileSaveAsNewFile = ""; - string destFileSaveAs = ""; - string remotePath = ""; - bool getFolderContents = false; - vector wantDirListOnly; + int file_progress(struct FtpFile *out, double download_total, double download_now, double upload_total, double upload_now) { + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf(" download progress [%f][%f][%f][%f] ",download_total,download_now,upload_total,upload_now); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, " download progress [%f][%f][%f][%f] ", download_total, download_now, upload_total, upload_now); - if(tileSetNameSubfolder == "") { - if(findArchive == true) { - destFileSaveAs = this->tilesetsPath.second; - endPathWithSlash(destFileSaveAs); - destFileSaveAs += tileSetName.first + this->fileArchiveExtension; + if (out != NULL && + out->ftpServer != NULL && + out->ftpServer->getCallBackObject() != NULL) { + if (out->ftpServer->getQuitStatus() == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread CANCELLED\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client thread CANCELLED\n"); - if(tileSetName.second != "") { - remotePath = tileSetName.second; - } - else { - remotePath = tileSetName.first + this->fileArchiveExtension; - } - } - else { - getFolderContents = true; - remotePath = tileSetName.first + "/"; - destFileSaveAs = this->tilesetsPath.second; - endPathWithSlash(destFileSaveAs); - destFileSaveAs += tileSetName.first; - destFileSaveAsNewFile = destFileSaveAs; - endPathWithSlash(destFileSaveAsNewFile); - destFileSaveAs += ".tmp"; - } - } - else { - getFolderContents = true; - remotePath = tileSetName.first + "/" + tileSetNameSubfolder + "/"; - destFileSaveAs = this->tilesetsPath.second; - endPathWithSlash(destFileSaveAs); - destFileSaveAs += tileSetName.first; - endPathWithSlash(destFileSaveAs); + return -1; + } + FTPClientCallbackInterface::FtpProgressStats stats; + stats.download_total = download_total; + stats.download_now = download_now; + stats.upload_total = upload_total; + stats.upload_now = upload_now; + stats.currentFilename = out->currentFilename; + stats.downloadType = out->downloadType; - destFileSaveAs += tileSetNameSubfolder; - destFileSaveAsNewFile = destFileSaveAs; - endPathWithSlash(destFileSaveAsNewFile); - destFileSaveAs += ".tmp"; - } + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(out->ftpServer->getProgressMutex(), mutexOwnerId); + out->ftpServer->getProgressMutex()->setOwnerId(mutexOwnerId); + out->ftpServer->getCallBackObject()->FTPClient_CallbackEvent( + out->itemName, + ftp_cct_DownloadProgress, + make_pair(ftp_crt_SUCCESS, ""), + &stats); + } - vector *pWantDirListOnly = NULL; - if(getFolderContents == true) { - pWantDirListOnly = &wantDirListOnly; - } + return 0; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("FTPClientThread::getTilesetFromServer [%s] remotePath [%s] destFileSaveAs [%s] getFolderContents = %d findArchive = %d\n",tileSetName.first.c_str(),remotePath.c_str(),destFileSaveAs.c_str(),getFolderContents,findArchive); + FTPClientThread::FTPClientThread(int portNumber, string serverUrl, + std::pair mapsPath, + std::pair tilesetsPath, + std::pair techtreesPath, + std::pair scenariosPath, + FTPClientCallbackInterface *pCBObject, + string fileArchiveExtension, + string fileArchiveExtractCommand, + string fileArchiveExtractCommandParameters, + int fileArchiveExtractCommandSuccessResult, + string tempFilesPath) : BaseThread() { - pair result = getFileFromServer( - ftp_cct_Tileset, - tileSetName, - remotePath, - destFileSaveAs, - ftpUser, - ftpUserPassword, - pWantDirListOnly); + uniqueID = "FTPClientThread"; + this->portNumber = portNumber; + this->serverUrl = serverUrl; + this->mapsPath = mapsPath; + this->tilesetsPath = tilesetsPath; + this->techtreesPath = techtreesPath; + this->scenariosPath = scenariosPath; + this->pCBObject = pCBObject; + this->shellCommandCallbackUserData = ""; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("FTPClientThread::getTilesetFromServer [%s] remotePath [%s] destFileSaveAs [%s] getFolderContents = %d result.first = %d [%s] findArchive = %d\n",tileSetName.first.c_str(),remotePath.c_str(),destFileSaveAs.c_str(),getFolderContents,result.first,result.second.c_str(),findArchive); + this->fileArchiveExtension = fileArchiveExtension; + this->fileArchiveExtractCommand = fileArchiveExtractCommand; + this->fileArchiveExtractCommandParameters = fileArchiveExtractCommandParameters; + this->fileArchiveExtractCommandSuccessResult = fileArchiveExtractCommandSuccessResult; + this->tempFilesPath = tempFilesPath; - // Extract the archive - if(result.first == ftp_crt_SUCCESS) { - if(findArchive == true) { - string destRootArchiveFolder = this->tilesetsPath.second; - endPathWithSlash(destRootArchiveFolder); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line %d] Using FTP port #: %d, serverUrl [%s]\n", __FILE__, __FUNCTION__, __LINE__, portNumber, serverUrl.c_str()); + } - string extractCmd = getFullFileArchiveExtractCommand( - this->fileArchiveExtractCommand, - this->fileArchiveExtractCommandParameters, - destRootArchiveFolder, - destRootArchiveFolder + tileSetName.first + this->fileArchiveExtension); + void FTPClientThread::signalQuit() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client: signalQuit\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client: signalQuit\n"); + BaseThread::signalQuit(); + } - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(this->getProgressMutex(),mutexOwnerId); - this->getProgressMutex()->setOwnerId(mutexOwnerId); + bool FTPClientThread::shutdownAndWait() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client: shutdownAndWait\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client: shutdownAndWait\n"); - if(this->pCBObject != NULL) { - this->shellCommandCallbackUserData = tileSetName.first; - this->pCBObject->FTPClient_CallbackEvent( - tileSetName.first, - ftp_cct_ExtractProgress, - make_pair(ftp_crt_SUCCESS,"extracting"),NULL); - } - safeMutex.ReleaseLock(); + signalQuit(); + return BaseThread::shutdownAndWait(); + } - if(executeShellCommand(extractCmd,this->fileArchiveExtractCommandSuccessResult,this) == false) { - result.first = ftp_crt_FAIL; - result.second = "failed to extract archive!"; + + pair FTPClientThread::getMapFromServer(pair mapFileName, string ftpUser, string ftpUserPassword) { + pair result = make_pair(ftp_crt_FAIL, ""); + + string destFileExt = ""; + string destFile = this->mapsPath.second; + + endPathWithSlash(destFile); + destFile += mapFileName.first; + + if (mapFileName.second == "") { + if (EndsWith(destFile, ".mgm") == false && EndsWith(destFile, ".gbm") == false) { + destFileExt = ".mgm"; + destFile += destFileExt; + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread about to try to RETR into [%s]\n", destFile.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client thread about to try to RETR into [%s]\n", destFile.c_str()); + + struct FtpFile ftpfile = { + NULL, + destFile.c_str(), /* name to store the file as if succesful */ + NULL, + NULL, + this, + "", + false, + ftp_cct_Map + }; + + CURL *curl = SystemFlags::initHTTP(); + if (curl) { + ftpfile.stream = NULL; + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); + char szBuf[8096] = ""; + if (mapFileName.second != "") { + snprintf(szBuf, 8096, "%s", mapFileName.second.c_str()); + curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); + } else { + snprintf(szBuf, 8096, "ftp://%s:%s@%s:%d/%s%s", ftpUser.c_str(), ftpUserPassword.c_str(), serverUrl.c_str(), portNumber, mapFileName.first.c_str(), destFileExt.c_str()); + } + + curl_easy_setopt(curl, CURLOPT_URL, szBuf); + curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L); + + /* Define our callback to get called when there's data to be written */ + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); + /* Set a pointer to our struct to pass to the callback */ + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile); + + + // Max 10 minutes to transfer + //curl_easy_setopt(curl, CURLOPT_TIMEOUT, 600); + // Max 60 minutes to transfer + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3600L); + curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, 120L); + + /* Switch on full protocol/debug output */ + if (SystemFlags::VERBOSE_MODE_ENABLED) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + + CURLcode res = curl_easy_perform(curl); + if (res != CURLE_OK) { + result.second = curl_easy_strerror(res); + // we failed + printf("curl FAILED with: %d [%s] szBuf [%s]\n", res, curl_easy_strerror(res), szBuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "curl FAILED with: %d [%s] szBuf [%s]\n", res, curl_easy_strerror(res), szBuf); + + if (res == CURLE_PARTIAL_FILE) { + result.first = ftp_crt_PARTIALFAIL; + } else if (res == CURLE_COULDNT_CONNECT) { + result.first = ftp_crt_HOST_NOT_ACCEPTING; + } + } else { + result.first = ftp_crt_SUCCESS; + } + + SystemFlags::cleanupHTTP(&curl); + } + + if (ftpfile.stream) { + fclose(ftpfile.stream); + ftpfile.stream = NULL; + } + if (result.first != ftp_crt_SUCCESS) { + removeFile(destFile); } return result; - } - else { - if(getFolderContents == true) { - removeFile(destFileSaveAs); - - for(unsigned int i = 0; i < wantDirListOnly.size(); ++i) { - string fileFromList = wantDirListOnly[i]; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("fileFromList [%s] i [%u]\n",fileFromList.c_str(),i); - - if( fileFromList != "models" && fileFromList != "textures" && - fileFromList != "sounds") { - result = getFileFromServer(ftp_cct_Tileset, - tileSetName, - remotePath + fileFromList, - destFileSaveAsNewFile + fileFromList, - ftpUser, ftpUserPassword); - if(result.first != ftp_crt_SUCCESS) { - break; - } - } - else { - result = getTilesetFromServer(tileSetName, - fileFromList, ftpUser, ftpUserPassword, - findArchive); - if(result.first != ftp_crt_SUCCESS) { - break; - } - } - } - } - } - } - - if(result.first != ftp_crt_SUCCESS && findArchive == false) { - string destRootFolder = this->tilesetsPath.second; - endPathWithSlash(destRootFolder); - destRootFolder += tileSetName.first; - endPathWithSlash(destRootFolder); - - removeFolder(destRootFolder); - } - - return result; -} - -void FTPClientThread::getTechtreeFromServer(pair techtreeName) { - pair result = make_pair(ftp_crt_FAIL,""); - bool findArchive = executeShellCommand( - this->fileArchiveExtractCommand, - this->fileArchiveExtractCommandSuccessResult); - if(findArchive == true) { - if(techtreeName.second != "") { - result = getTechtreeFromServer(techtreeName, "", ""); } - else { - result = getTechtreeFromServer(techtreeName, FTP_TECHTREES_CUSTOM_USERNAME, FTP_COMMON_PASSWORD); - if(result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { - result = getTechtreeFromServer(techtreeName, FTP_TECHTREES_USERNAME, FTP_COMMON_PASSWORD); + + void FTPClientThread::getMapFromServer(pair mapFileName) { + pair result = make_pair(ftp_crt_FAIL, ""); + if (mapFileName.second != "") { + result = getMapFromServer(mapFileName, "", ""); + } else { + pair findMapFileName = mapFileName; + findMapFileName.first += +".mgm"; + + result = getMapFromServer(findMapFileName, FTP_MAPS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD); + if (result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { + findMapFileName = mapFileName; + findMapFileName.first += +".gbm"; + result = getMapFromServer(findMapFileName, FTP_MAPS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD); + if (result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { + findMapFileName = mapFileName; + findMapFileName.first += +".mgm"; + result = getMapFromServer(findMapFileName, FTP_MAPS_USERNAME, FTP_COMMON_PASSWORD); + if (result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { + findMapFileName = mapFileName; + findMapFileName.first += +".gbm"; + result = getMapFromServer(findMapFileName, FTP_MAPS_USERNAME, FTP_COMMON_PASSWORD); + } + } + } + } + + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId); + this->getProgressMutex()->setOwnerId(mutexOwnerId); + if (this->pCBObject != NULL) { + this->pCBObject->FTPClient_CallbackEvent( + mapFileName.first, + ftp_cct_Map, + result, + NULL); } } - } - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(this->getProgressMutex(),mutexOwnerId); - this->getProgressMutex()->setOwnerId(mutexOwnerId); - if(this->pCBObject != NULL) { - this->pCBObject->FTPClient_CallbackEvent( - techtreeName.first, - ftp_cct_Techtree, - result, - NULL); - } -} + void FTPClientThread::addMapToRequests(string mapFilename, string URL) { + std::pair item = make_pair(mapFilename, URL); + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(&mutexMapFileList, mutexOwnerId); + mutexMapFileList.setOwnerId(mutexOwnerId); + if (std::find(mapFileList.begin(), mapFileList.end(), item) == mapFileList.end()) { + mapFileList.push_back(item); + } + } -pair FTPClientThread::getTechtreeFromServer(pair techtreeName, - string ftpUser, string ftpUserPassword) { + void FTPClientThread::addTilesetToRequests(string tileSetName, string URL) { + std::pair item = make_pair(tileSetName, URL); + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(&mutexTilesetList, mutexOwnerId); + mutexTilesetList.setOwnerId(mutexOwnerId); + if (std::find(tilesetList.begin(), tilesetList.end(), item) == tilesetList.end()) { + tilesetList.push_back(item); + } + } - // Root folder for the techtree - string destRootFolder = this->techtreesPath.second; - endPathWithSlash(destRootFolder); - string destRootArchiveFolder = destRootFolder; - destRootFolder += techtreeName.first; - endPathWithSlash(destRootFolder); + void FTPClientThread::addTechtreeToRequests(string techtreeName, string URL) { + std::pair item = make_pair(techtreeName, URL); + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(&mutexTechtreeList, mutexOwnerId); + mutexTechtreeList.setOwnerId(mutexOwnerId); + if (std::find(techtreeList.begin(), techtreeList.end(), item) == techtreeList.end()) { + techtreeList.push_back(item); + } + } - string destFile = this->techtreesPath.second; - endPathWithSlash(destFile); - destFile += techtreeName.first; - string destFileSaveAs = destFile + this->fileArchiveExtension; - endPathWithSlash(destFile); + void FTPClientThread::addScenarioToRequests(string fileName, string URL) { + std::pair item = make_pair(fileName, URL); + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(&mutexScenarioList, mutexOwnerId); + mutexScenarioList.setOwnerId(mutexOwnerId); + if (std::find(scenarioList.begin(), scenarioList.end(), item) == scenarioList.end()) { + scenarioList.push_back(item); + } + } - string remotePath = techtreeName.first + this->fileArchiveExtension; - if(techtreeName.second != "") { - remotePath = techtreeName.second; - } + void FTPClientThread::addFileToRequests(string fileName, string URL) { + std::pair item = make_pair(fileName, URL); + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(&mutexFileList, mutexOwnerId); + mutexFileList.setOwnerId(mutexOwnerId); + if (std::find(fileList.begin(), fileList.end(), item) == fileList.end()) { + fileList.push_back(item); + } + } - pair result = getFileFromServer(ftp_cct_Techtree, - techtreeName, remotePath, destFileSaveAs, ftpUser, ftpUserPassword); + void FTPClientThread::addTempFileToRequests(string fileName, string URL) { + std::pair item = make_pair(fileName, URL); + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(&mutexTempFileList, mutexOwnerId); + mutexTempFileList.setOwnerId(mutexOwnerId); + if (std::find(tempFileList.begin(), tempFileList.end(), item) == tempFileList.end()) { + tempFileList.push_back(item); + } + } - // Extract the archive - if(result.first == ftp_crt_SUCCESS) { - string extractCmd = getFullFileArchiveExtractCommand( - this->fileArchiveExtractCommand, - this->fileArchiveExtractCommandParameters, - destRootArchiveFolder, - destRootArchiveFolder + techtreeName.first + this->fileArchiveExtension); - - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(this->getProgressMutex(),mutexOwnerId); - this->getProgressMutex()->setOwnerId(mutexOwnerId); - if(this->pCBObject != NULL) { - this->shellCommandCallbackUserData = techtreeName.first; - this->pCBObject->FTPClient_CallbackEvent( - techtreeName.first, - ftp_cct_ExtractProgress, - make_pair(ftp_crt_SUCCESS,"extracting"),NULL); - } - safeMutex.ReleaseLock(); - - if(executeShellCommand(extractCmd,this->fileArchiveExtractCommandSuccessResult,this) == false) { - result.first = ftp_crt_FAIL; - result.second = "failed to extract archive!"; - } - } - - return result; - -} - -void FTPClientThread::getScenarioFromServer(pair fileName) { - pair result = make_pair(ftp_crt_FAIL,""); - bool findArchive = executeShellCommand( - this->fileArchiveExtractCommand, - this->fileArchiveExtractCommandSuccessResult); - if(findArchive == true) { - result = getScenarioInternalFromServer(fileName); - } - - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(this->getProgressMutex(),mutexOwnerId); - this->getProgressMutex()->setOwnerId(mutexOwnerId); - if(this->pCBObject != NULL) { - this->pCBObject->FTPClient_CallbackEvent( - fileName.first, - ftp_cct_Scenario, - result, - NULL); - } -} - -pair FTPClientThread::getScenarioInternalFromServer(pair fileName) { - // Root folder for the techtree - string destRootFolder = this->scenariosPath.second; - endPathWithSlash(destRootFolder); - string destRootArchiveFolder = destRootFolder; - destRootFolder += fileName.first; - endPathWithSlash(destRootFolder); - - string destFile = this->scenariosPath.second; - endPathWithSlash(destFile); - destFile += fileName.first; - string destFileSaveAs = destFile + this->fileArchiveExtension; - endPathWithSlash(destFile); - - string remotePath = fileName.first + this->fileArchiveExtension; - if(fileName.second != "") { - remotePath = fileName.second; - } - - pair result = getFileFromServer(ftp_cct_Scenario, - fileName, remotePath, destFileSaveAs, "", ""); - - // Extract the archive - if(result.first == ftp_crt_SUCCESS) { - string extractCmd = getFullFileArchiveExtractCommand( - this->fileArchiveExtractCommand, - this->fileArchiveExtractCommandParameters, - destRootArchiveFolder, - destRootArchiveFolder + fileName.first + this->fileArchiveExtension); - - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(this->getProgressMutex(),mutexOwnerId); - this->getProgressMutex()->setOwnerId(mutexOwnerId); - if(this->pCBObject != NULL) { - this->shellCommandCallbackUserData = fileName.first; - this->pCBObject->FTPClient_CallbackEvent( - fileName.first, - ftp_cct_ExtractProgress, - make_pair(ftp_crt_SUCCESS,"extracting"),NULL); - } - safeMutex.ReleaseLock(); - - if(executeShellCommand(extractCmd,this->fileArchiveExtractCommandSuccessResult,this) == false) { - result.first = ftp_crt_FAIL; - result.second = "failed to extract archive!"; - } - } - - return result; - -} - -void FTPClientThread::getFileFromServer(pair fileName) { - pair result = make_pair(ftp_crt_FAIL,""); - - bool findArchive = true; - string ext = extractExtension(fileName.first); - if(("." + ext) == this->fileArchiveExtension) { - findArchive = executeShellCommand( + void FTPClientThread::getTilesetFromServer(pair tileSetName) { + bool findArchive = executeShellCommand( this->fileArchiveExtractCommand, this->fileArchiveExtractCommandSuccessResult); - } - if(findArchive == true) { - result = getFileInternalFromServer(fileName); - } - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(this->getProgressMutex(),mutexOwnerId); - this->getProgressMutex()->setOwnerId(mutexOwnerId); - if(this->pCBObject != NULL) { - this->pCBObject->FTPClient_CallbackEvent(fileName.first,ftp_cct_File,result,NULL); - } -} + pair result = make_pair(ftp_crt_FAIL, ""); + if (findArchive == true) { + if (tileSetName.second != "") { + //result = getTilesetFromServer(tileSetName, "", "", "", findArchive); + result = getTilesetFromServer(tileSetName, "", "", "", true); + } else { + //result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, findArchive); + result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, true); + if (result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { + //if(findArchive == true) { + //result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, false); + result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, true); + //} + if (result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { + // result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, findArchive); + result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, true); -pair FTPClientThread::getFileInternalFromServer(pair fileName) { - string destFile = fileName.first; - string destFileSaveAs = fileName.first; + // if(findArchive == true) { + // result = getTilesetFromServer(tileSetName, "", FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, false); + // } + } + } + } + } - string remotePath = fileName.second; + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId); + this->getProgressMutex()->setOwnerId(mutexOwnerId); + if (this->pCBObject != NULL) { + this->pCBObject->FTPClient_CallbackEvent( + tileSetName.first, + ftp_cct_Tileset, + result, + NULL); + } + } - pair result = getFileFromServer(ftp_cct_File, - fileName,remotePath, destFileSaveAs, "", ""); + pair FTPClientThread::getTilesetFromServer( + pair tileSetName, + string tileSetNameSubfolder, + string ftpUser, + string ftpUserPassword, + bool findArchive) { - //printf("Got file [%s] result.first = %d\n",destFileSaveAs.c_str(),result.first); + string destFileSaveAsNewFile = ""; + string destFileSaveAs = ""; + string remotePath = ""; + bool getFolderContents = false; + vector wantDirListOnly; - // Extract the archive - if(result.first == ftp_crt_SUCCESS) { - string ext = extractExtension(destFileSaveAs); - if(("." + ext) == fileArchiveExtension) { - string destRootArchiveFolder = extractDirectoryPathFromFile(destFileSaveAs); - string extractCmd = getFullFileArchiveExtractCommand( + if (tileSetNameSubfolder == "") { + if (findArchive == true) { + destFileSaveAs = this->tilesetsPath.second; + endPathWithSlash(destFileSaveAs); + destFileSaveAs += tileSetName.first + this->fileArchiveExtension; + + if (tileSetName.second != "") { + remotePath = tileSetName.second; + } else { + remotePath = tileSetName.first + this->fileArchiveExtension; + } + } else { + getFolderContents = true; + remotePath = tileSetName.first + "/"; + destFileSaveAs = this->tilesetsPath.second; + endPathWithSlash(destFileSaveAs); + destFileSaveAs += tileSetName.first; + destFileSaveAsNewFile = destFileSaveAs; + endPathWithSlash(destFileSaveAsNewFile); + destFileSaveAs += ".tmp"; + } + } else { + getFolderContents = true; + remotePath = tileSetName.first + "/" + tileSetNameSubfolder + "/"; + destFileSaveAs = this->tilesetsPath.second; + endPathWithSlash(destFileSaveAs); + destFileSaveAs += tileSetName.first; + endPathWithSlash(destFileSaveAs); + + destFileSaveAs += tileSetNameSubfolder; + destFileSaveAsNewFile = destFileSaveAs; + endPathWithSlash(destFileSaveAsNewFile); + destFileSaveAs += ".tmp"; + } + + vector *pWantDirListOnly = NULL; + if (getFolderContents == true) { + pWantDirListOnly = &wantDirListOnly; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("FTPClientThread::getTilesetFromServer [%s] remotePath [%s] destFileSaveAs [%s] getFolderContents = %d findArchive = %d\n", tileSetName.first.c_str(), remotePath.c_str(), destFileSaveAs.c_str(), getFolderContents, findArchive); + + pair result = getFileFromServer( + ftp_cct_Tileset, + tileSetName, + remotePath, + destFileSaveAs, + ftpUser, + ftpUserPassword, + pWantDirListOnly); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("FTPClientThread::getTilesetFromServer [%s] remotePath [%s] destFileSaveAs [%s] getFolderContents = %d result.first = %d [%s] findArchive = %d\n", tileSetName.first.c_str(), remotePath.c_str(), destFileSaveAs.c_str(), getFolderContents, result.first, result.second.c_str(), findArchive); + + // Extract the archive + if (result.first == ftp_crt_SUCCESS) { + if (findArchive == true) { + string destRootArchiveFolder = this->tilesetsPath.second; + endPathWithSlash(destRootArchiveFolder); + + string extractCmd = getFullFileArchiveExtractCommand( + this->fileArchiveExtractCommand, + this->fileArchiveExtractCommandParameters, + destRootArchiveFolder, + destRootArchiveFolder + tileSetName.first + this->fileArchiveExtension); + + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId); + this->getProgressMutex()->setOwnerId(mutexOwnerId); + + if (this->pCBObject != NULL) { + this->shellCommandCallbackUserData = tileSetName.first; + this->pCBObject->FTPClient_CallbackEvent( + tileSetName.first, + ftp_cct_ExtractProgress, + make_pair(ftp_crt_SUCCESS, "extracting"), NULL); + } + safeMutex.ReleaseLock(); + + if (executeShellCommand(extractCmd, this->fileArchiveExtractCommandSuccessResult, this) == false) { + result.first = ftp_crt_FAIL; + result.second = "failed to extract archive!"; + } + + return result; + } else { + if (getFolderContents == true) { + removeFile(destFileSaveAs); + + for (unsigned int i = 0; i < wantDirListOnly.size(); ++i) { + string fileFromList = wantDirListOnly[i]; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("fileFromList [%s] i [%u]\n", fileFromList.c_str(), i); + + if (fileFromList != "models" && fileFromList != "textures" && + fileFromList != "sounds") { + result = getFileFromServer(ftp_cct_Tileset, + tileSetName, + remotePath + fileFromList, + destFileSaveAsNewFile + fileFromList, + ftpUser, ftpUserPassword); + if (result.first != ftp_crt_SUCCESS) { + break; + } + } else { + result = getTilesetFromServer(tileSetName, + fileFromList, ftpUser, ftpUserPassword, + findArchive); + if (result.first != ftp_crt_SUCCESS) { + break; + } + } + } + } + } + } + + if (result.first != ftp_crt_SUCCESS && findArchive == false) { + string destRootFolder = this->tilesetsPath.second; + endPathWithSlash(destRootFolder); + destRootFolder += tileSetName.first; + endPathWithSlash(destRootFolder); + + removeFolder(destRootFolder); + } + + return result; + } + + void FTPClientThread::getTechtreeFromServer(pair techtreeName) { + pair result = make_pair(ftp_crt_FAIL, ""); + bool findArchive = executeShellCommand( + this->fileArchiveExtractCommand, + this->fileArchiveExtractCommandSuccessResult); + if (findArchive == true) { + if (techtreeName.second != "") { + result = getTechtreeFromServer(techtreeName, "", ""); + } else { + result = getTechtreeFromServer(techtreeName, FTP_TECHTREES_CUSTOM_USERNAME, FTP_COMMON_PASSWORD); + if (result.first == ftp_crt_FAIL && this->getQuitStatus() == false) { + result = getTechtreeFromServer(techtreeName, FTP_TECHTREES_USERNAME, FTP_COMMON_PASSWORD); + } + } + } + + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId); + this->getProgressMutex()->setOwnerId(mutexOwnerId); + if (this->pCBObject != NULL) { + this->pCBObject->FTPClient_CallbackEvent( + techtreeName.first, + ftp_cct_Techtree, + result, + NULL); + } + } + + pair FTPClientThread::getTechtreeFromServer(pair techtreeName, + string ftpUser, string ftpUserPassword) { + + // Root folder for the techtree + string destRootFolder = this->techtreesPath.second; + endPathWithSlash(destRootFolder); + string destRootArchiveFolder = destRootFolder; + destRootFolder += techtreeName.first; + endPathWithSlash(destRootFolder); + + string destFile = this->techtreesPath.second; + endPathWithSlash(destFile); + destFile += techtreeName.first; + string destFileSaveAs = destFile + this->fileArchiveExtension; + endPathWithSlash(destFile); + + string remotePath = techtreeName.first + this->fileArchiveExtension; + if (techtreeName.second != "") { + remotePath = techtreeName.second; + } + + pair result = getFileFromServer(ftp_cct_Techtree, + techtreeName, remotePath, destFileSaveAs, ftpUser, ftpUserPassword); + + // Extract the archive + if (result.first == ftp_crt_SUCCESS) { + string extractCmd = getFullFileArchiveExtractCommand( this->fileArchiveExtractCommand, this->fileArchiveExtractCommandParameters, destRootArchiveFolder, - destFileSaveAs); + destRootArchiveFolder + techtreeName.first + this->fileArchiveExtension); - if(executeShellCommand(extractCmd,this->fileArchiveExtractCommandSuccessResult) == false) { - result.first = ftp_crt_FAIL; - result.second = "failed to extract archive!"; + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId); + this->getProgressMutex()->setOwnerId(mutexOwnerId); + if (this->pCBObject != NULL) { + this->shellCommandCallbackUserData = techtreeName.first; + this->pCBObject->FTPClient_CallbackEvent( + techtreeName.first, + ftp_cct_ExtractProgress, + make_pair(ftp_crt_SUCCESS, "extracting"), NULL); + } + safeMutex.ReleaseLock(); + + if (executeShellCommand(extractCmd, this->fileArchiveExtractCommandSuccessResult, this) == false) { + result.first = ftp_crt_FAIL; + result.second = "failed to extract archive!"; + } } - } - } - return result; -} + return result; -void FTPClientThread::getTempFileFromServer(pair fileName) { - pair result = make_pair(ftp_crt_FAIL,""); + } - bool findArchive = true; - string ext = extractExtension(fileName.first); - if(("." + ext) == this->fileArchiveExtension) { - findArchive = executeShellCommand( + void FTPClientThread::getScenarioFromServer(pair fileName) { + pair result = make_pair(ftp_crt_FAIL, ""); + bool findArchive = executeShellCommand( this->fileArchiveExtractCommand, this->fileArchiveExtractCommandSuccessResult); - } - if(findArchive == true) { - result = getTempFileInternalFromServer(fileName); - } + if (findArchive == true) { + result = getScenarioInternalFromServer(fileName); + } - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(this->getProgressMutex(),mutexOwnerId); - this->getProgressMutex()->setOwnerId(mutexOwnerId); - if(this->pCBObject != NULL) { - this->pCBObject->FTPClient_CallbackEvent(fileName.first,ftp_cct_TempFile,result,NULL); - } -} + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId); + this->getProgressMutex()->setOwnerId(mutexOwnerId); + if (this->pCBObject != NULL) { + this->pCBObject->FTPClient_CallbackEvent( + fileName.first, + ftp_cct_Scenario, + result, + NULL); + } + } -pair FTPClientThread::getTempFileInternalFromServer(pair fileName) { - string destFile = fileName.first; - //string destFileSaveAs = fileName.first; - string destFileSaveAs = tempFilesPath; + pair FTPClientThread::getScenarioInternalFromServer(pair fileName) { + // Root folder for the techtree + string destRootFolder = this->scenariosPath.second; + endPathWithSlash(destRootFolder); + string destRootArchiveFolder = destRootFolder; + destRootFolder += fileName.first; + endPathWithSlash(destRootFolder); - endPathWithSlash(destFileSaveAs); - destFileSaveAs += fileName.first; + string destFile = this->scenariosPath.second; + endPathWithSlash(destFile); + destFile += fileName.first; + string destFileSaveAs = destFile + this->fileArchiveExtension; + endPathWithSlash(destFile); - string remotePath = fileName.second; + string remotePath = fileName.first + this->fileArchiveExtension; + if (fileName.second != "") { + remotePath = fileName.second; + } - //printf("First [%s] Second [%s]\n",fileName.first.c_str(),fileName.second.c_str()); - pair result; - if(StartsWith(remotePath,"http://")) { - result = getFileFromServer(ftp_cct_TempFile, fileName,remotePath, destFileSaveAs, "", ""); - } - else { - fileName.second = ""; - result = getFileFromServer(ftp_cct_TempFile,fileName,remotePath, destFileSaveAs, FTP_TEMPFILES_USERNAME, FTP_COMMON_PASSWORD); - } + pair result = getFileFromServer(ftp_cct_Scenario, + fileName, remotePath, destFileSaveAs, "", ""); - //printf("Got temp file [%s] result.first = %d\n",destFileSaveAs.c_str(),result.first); - - // Extract the archive - if(result.first == ftp_crt_SUCCESS) { - string ext = extractExtension(destFileSaveAs); - if(("." + ext) == fileArchiveExtension) { - string destRootArchiveFolder = extractDirectoryPathFromFile(destFileSaveAs); - string extractCmd = getFullFileArchiveExtractCommand( + // Extract the archive + if (result.first == ftp_crt_SUCCESS) { + string extractCmd = getFullFileArchiveExtractCommand( this->fileArchiveExtractCommand, this->fileArchiveExtractCommandParameters, destRootArchiveFolder, - destFileSaveAs); + destRootArchiveFolder + fileName.first + this->fileArchiveExtension); - if(executeShellCommand(extractCmd,this->fileArchiveExtractCommandSuccessResult) == false) { - result.first = ftp_crt_FAIL; - result.second = "failed to extract archive!"; + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId); + this->getProgressMutex()->setOwnerId(mutexOwnerId); + if (this->pCBObject != NULL) { + this->shellCommandCallbackUserData = fileName.first; + this->pCBObject->FTPClient_CallbackEvent( + fileName.first, + ftp_cct_ExtractProgress, + make_pair(ftp_crt_SUCCESS, "extracting"), NULL); + } + safeMutex.ReleaseLock(); + + if (executeShellCommand(extractCmd, this->fileArchiveExtractCommandSuccessResult, this) == false) { + result.first = ftp_crt_FAIL; + result.second = "failed to extract archive!"; + } } - } - } - return result; -} + return result; -pair FTPClientThread::getFileFromServer(FTP_Client_CallbackType downloadType, - pair fileNameTitle, - string remotePath, string destFileSaveAs, - string ftpUser, string ftpUserPassword, vector *wantDirListOnly) { - pair result = make_pair(ftp_crt_FAIL,""); - if(wantDirListOnly) { - (*wantDirListOnly).clear(); - } - string destRootFolder = extractDirectoryPathFromFile(destFileSaveAs); - bool pathCreated = false; - if(isdir(destRootFolder.c_str()) == false) { - createDirectoryPaths(destRootFolder); - pathCreated = true; - } + } - bool wantDirList = (wantDirListOnly != NULL); + void FTPClientThread::getFileFromServer(pair fileName) { + pair result = make_pair(ftp_crt_FAIL, ""); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread about to try to RETR into [%s] wantDirList = %d\n",destFileSaveAs.c_str(),wantDirList); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client thread about to try to RETR into [%s] wantDirList = %d\n",destFileSaveAs.c_str(),wantDirList); + bool findArchive = true; + string ext = extractExtension(fileName.first); + if (("." + ext) == this->fileArchiveExtension) { + findArchive = executeShellCommand( + this->fileArchiveExtractCommand, + this->fileArchiveExtractCommandSuccessResult); + } + if (findArchive == true) { + result = getFileInternalFromServer(fileName); + } - struct FtpFile ftpfile = { - fileNameTitle.first.c_str(), - destFileSaveAs.c_str(), // name to store the file as if successful - NULL, - NULL, - this, - "", - false, - downloadType - }; + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId); + this->getProgressMutex()->setOwnerId(mutexOwnerId); + if (this->pCBObject != NULL) { + this->pCBObject->FTPClient_CallbackEvent(fileName.first, ftp_cct_File, result, NULL); + } + } - CURL *curl = SystemFlags::initHTTP(); - if(curl) { - ftpfile.stream = NULL; - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); - char szBuf[8096]=""; - if(fileNameTitle.second != "") { - snprintf(szBuf,8096,"%s",fileNameTitle.second.c_str()); - curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); - } - else { - snprintf(szBuf,8096,"ftp://%s:%s@%s:%d/%s",ftpUser.c_str(),ftpUserPassword.c_str(),serverUrl.c_str(),portNumber,remotePath.c_str()); - } + pair FTPClientThread::getFileInternalFromServer(pair fileName) { + string destFile = fileName.first; + string destFileSaveAs = fileName.first; - //printf("===> Getting ftp file: %s\n",szBuf); + string remotePath = fileName.second; - curl_easy_setopt(curl, CURLOPT_URL,szBuf); - curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L); + pair result = getFileFromServer(ftp_cct_File, + fileName, remotePath, destFileSaveAs, "", ""); - // turn on wildcard matching - //curl_easy_setopt(curl, CURLOPT_WILDCARDMATCH, 1L); + //printf("Got file [%s] result.first = %d\n",destFileSaveAs.c_str(),result.first); - // callback is called before download of concrete file started - //curl_easy_setopt(curl, CURLOPT_CHUNK_BGN_FUNCTION, file_is_comming); - // callback is called after data from the file have been transferred - //curl_easy_setopt(curl, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded); + // Extract the archive + if (result.first == ftp_crt_SUCCESS) { + string ext = extractExtension(destFileSaveAs); + if (("." + ext) == fileArchiveExtension) { + string destRootArchiveFolder = extractDirectoryPathFromFile(destFileSaveAs); + string extractCmd = getFullFileArchiveExtractCommand( + this->fileArchiveExtractCommand, + this->fileArchiveExtractCommandParameters, + destRootArchiveFolder, + destFileSaveAs); - //curl_easy_setopt(curl, CURLOPT_CHUNK_DATA, &ftpfile); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile); + if (executeShellCommand(extractCmd, this->fileArchiveExtractCommandSuccessResult) == false) { + result.first = ftp_crt_FAIL; + result.second = "failed to extract archive!"; + } + } + } - // Define our callback to get called when there's data to be written - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); - // Set a pointer to our struct to pass to the callback - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile); + return result; + } - if(wantDirListOnly) { - curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 1); - } - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, file_progress); - curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &ftpfile); + void FTPClientThread::getTempFileFromServer(pair fileName) { + pair result = make_pair(ftp_crt_FAIL, ""); - // Max 10 minutes to transfer - //curl_easy_setopt(curl, CURLOPT_TIMEOUT, 600); - // Max 60 minutes to transfer - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3600L); - curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, 120L); + bool findArchive = true; + string ext = extractExtension(fileName.first); + if (("." + ext) == this->fileArchiveExtension) { + findArchive = executeShellCommand( + this->fileArchiveExtractCommand, + this->fileArchiveExtractCommandSuccessResult); + } + if (findArchive == true) { + result = getTempFileInternalFromServer(fileName); + } - // Switch on full protocol/debug output - if(SystemFlags::VERBOSE_MODE_ENABLED) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId); + this->getProgressMutex()->setOwnerId(mutexOwnerId); + if (this->pCBObject != NULL) { + this->pCBObject->FTPClient_CallbackEvent(fileName.first, ftp_cct_TempFile, result, NULL); + } + } - CURLcode res = curl_easy_perform(curl); + pair FTPClientThread::getTempFileInternalFromServer(pair fileName) { + string destFile = fileName.first; + //string destFileSaveAs = fileName.first; + string destFileSaveAs = tempFilesPath; - if(res != CURLE_OK) { - result.second = curl_easy_strerror(res); - // we failed - printf("curl FAILED with: %d [%s] attempting to remove folder contents [%s] szBuf [%s] ftpfile.isValidXfer = %d, pathCreated = %d\n", res,curl_easy_strerror(res),destRootFolder.c_str(),szBuf,ftpfile.isValidXfer,pathCreated); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"curl FAILED with: %d [%s] attempting to remove folder contents [%s] szBuf [%s] ftpfile.isValidXfer = %d, pathCreated = %d\n", res,curl_easy_strerror(res),destRootFolder.c_str(),szBuf,ftpfile.isValidXfer,pathCreated); + endPathWithSlash(destFileSaveAs); + destFileSaveAs += fileName.first; - if(res == CURLE_PARTIAL_FILE || ftpfile.isValidXfer == true) { - result.first = ftp_crt_PARTIALFAIL; - } - else if(res == CURLE_COULDNT_CONNECT) { - result.first = ftp_crt_HOST_NOT_ACCEPTING; - } + string remotePath = fileName.second; + + //printf("First [%s] Second [%s]\n",fileName.first.c_str(),fileName.second.c_str()); + pair result; + if (StartsWith(remotePath, "http://")) { + result = getFileFromServer(ftp_cct_TempFile, fileName, remotePath, destFileSaveAs, "", ""); + } else { + fileName.second = ""; + result = getFileFromServer(ftp_cct_TempFile, fileName, remotePath, destFileSaveAs, FTP_TEMPFILES_USERNAME, FTP_COMMON_PASSWORD); + } + + //printf("Got temp file [%s] result.first = %d\n",destFileSaveAs.c_str(),result.first); + + // Extract the archive + if (result.first == ftp_crt_SUCCESS) { + string ext = extractExtension(destFileSaveAs); + if (("." + ext) == fileArchiveExtension) { + string destRootArchiveFolder = extractDirectoryPathFromFile(destFileSaveAs); + string extractCmd = getFullFileArchiveExtractCommand( + this->fileArchiveExtractCommand, + this->fileArchiveExtractCommandParameters, + destRootArchiveFolder, + destFileSaveAs); + + if (executeShellCommand(extractCmd, this->fileArchiveExtractCommandSuccessResult) == false) { + result.first = ftp_crt_FAIL; + result.second = "failed to extract archive!"; + } + } + } + + return result; + } + + pair FTPClientThread::getFileFromServer(FTP_Client_CallbackType downloadType, + pair fileNameTitle, + string remotePath, string destFileSaveAs, + string ftpUser, string ftpUserPassword, vector *wantDirListOnly) { + pair result = make_pair(ftp_crt_FAIL, ""); + if (wantDirListOnly) { + (*wantDirListOnly).clear(); + } + string destRootFolder = extractDirectoryPathFromFile(destFileSaveAs); + bool pathCreated = false; + if (isdir(destRootFolder.c_str()) == false) { + createDirectoryPaths(destRootFolder); + pathCreated = true; + } + + bool wantDirList = (wantDirListOnly != NULL); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread about to try to RETR into [%s] wantDirList = %d\n", destFileSaveAs.c_str(), wantDirList); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client thread about to try to RETR into [%s] wantDirList = %d\n", destFileSaveAs.c_str(), wantDirList); + + struct FtpFile ftpfile = { + fileNameTitle.first.c_str(), + destFileSaveAs.c_str(), // name to store the file as if successful + NULL, + NULL, + this, + "", + false, + downloadType + }; + + CURL *curl = SystemFlags::initHTTP(); + if (curl) { + ftpfile.stream = NULL; + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); + char szBuf[8096] = ""; + if (fileNameTitle.second != "") { + snprintf(szBuf, 8096, "%s", fileNameTitle.second.c_str()); + curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); + } else { + snprintf(szBuf, 8096, "ftp://%s:%s@%s:%d/%s", ftpUser.c_str(), ftpUserPassword.c_str(), serverUrl.c_str(), portNumber, remotePath.c_str()); + } + + //printf("===> Getting ftp file: %s\n",szBuf); + + curl_easy_setopt(curl, CURLOPT_URL, szBuf); + curl_easy_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L); + + // turn on wildcard matching + //curl_easy_setopt(curl, CURLOPT_WILDCARDMATCH, 1L); + + // callback is called before download of concrete file started + //curl_easy_setopt(curl, CURLOPT_CHUNK_BGN_FUNCTION, file_is_comming); + // callback is called after data from the file have been transferred + //curl_easy_setopt(curl, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded); + + //curl_easy_setopt(curl, CURLOPT_CHUNK_DATA, &ftpfile); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile); + + // Define our callback to get called when there's data to be written + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite); + // Set a pointer to our struct to pass to the callback + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile); + + if (wantDirListOnly) { + curl_easy_setopt(curl, CURLOPT_DIRLISTONLY, 1); + } + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, file_progress); + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &ftpfile); + + // Max 10 minutes to transfer + //curl_easy_setopt(curl, CURLOPT_TIMEOUT, 600); + // Max 60 minutes to transfer + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3600L); + curl_easy_setopt(curl, CURLOPT_FTP_RESPONSE_TIMEOUT, 120L); + + // Switch on full protocol/debug output + if (SystemFlags::VERBOSE_MODE_ENABLED) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + + CURLcode res = curl_easy_perform(curl); + + if (res != CURLE_OK) { + result.second = curl_easy_strerror(res); + // we failed + printf("curl FAILED with: %d [%s] attempting to remove folder contents [%s] szBuf [%s] ftpfile.isValidXfer = %d, pathCreated = %d\n", res, curl_easy_strerror(res), destRootFolder.c_str(), szBuf, ftpfile.isValidXfer, pathCreated); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "curl FAILED with: %d [%s] attempting to remove folder contents [%s] szBuf [%s] ftpfile.isValidXfer = %d, pathCreated = %d\n", res, curl_easy_strerror(res), destRootFolder.c_str(), szBuf, ftpfile.isValidXfer, pathCreated); + + if (res == CURLE_PARTIAL_FILE || ftpfile.isValidXfer == true) { + result.first = ftp_crt_PARTIALFAIL; + } else if (res == CURLE_COULDNT_CONNECT) { + result.first = ftp_crt_HOST_NOT_ACCEPTING; + } - if(destRootFolder != "") { - if(pathCreated == true) { - removeFolder(destRootFolder); - } - else { - removeFile(destFileSaveAs); - } - } - } - else { - result.first = ftp_crt_SUCCESS; + if (destRootFolder != "") { + if (pathCreated == true) { + removeFolder(destRootFolder); + } else { + removeFile(destFileSaveAs); + } + } + } else { + result.first = ftp_crt_SUCCESS; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] result.first = %d wantDirListOnly = %p\n",__FILE__,__FUNCTION__,__LINE__,result.first,wantDirListOnly); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] result.first = %d wantDirListOnly = %p\n", __FILE__, __FUNCTION__, __LINE__, result.first, wantDirListOnly); - if(wantDirListOnly) { - if(ftpfile.stream) { - fclose(ftpfile.stream); - ftpfile.stream = NULL; - } + if (wantDirListOnly) { + if (ftpfile.stream) { + fclose(ftpfile.stream); + ftpfile.stream = NULL; + } #ifdef WIN32 - FILE *fp = _wfopen(utf8_decode(destFileSaveAs).c_str(), L"rt"); + FILE *fp = _wfopen(utf8_decode(destFileSaveAs).c_str(), L"rt"); #else - FILE *fp = fopen(destFileSaveAs.c_str(), "rt"); + FILE *fp = fopen(destFileSaveAs.c_str(), "rt"); #endif - if(fp != NULL) { - char szBuf[4096]=""; - while(feof(fp) == false) { - if(fgets( szBuf, 4095, fp) != NULL) { - string item = szBuf; - replaceAll(item,"\n",""); - replaceAll(item,"\r",""); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Got [%s]\n",item.c_str()); - (*wantDirListOnly).push_back(item); - } - } - fclose(fp); - } - } - } + if (fp != NULL) { + char szBuf[4096] = ""; + while (feof(fp) == false) { + if (fgets(szBuf, 4095, fp) != NULL) { + string item = szBuf; + replaceAll(item, "\n", ""); + replaceAll(item, "\r", ""); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Got [%s]\n", item.c_str()); + (*wantDirListOnly).push_back(item); + } + } + fclose(fp); + } + } + } - SystemFlags::cleanupHTTP(&curl); - } + SystemFlags::cleanupHTTP(&curl); + } - if(ftpfile.stream) { - fclose(ftpfile.stream); - ftpfile.stream = NULL; - } + if (ftpfile.stream) { + fclose(ftpfile.stream); + ftpfile.stream = NULL; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] result.first = %d\n",__FILE__,__FUNCTION__,__LINE__,result.first); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] result.first = %d\n", __FILE__, __FUNCTION__, __LINE__, result.first); - return result; -} + return result; + } -FTPClientCallbackInterface * FTPClientThread::getCallBackObject() { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(this->getProgressMutex(),mutexOwnerId); - this->getProgressMutex()->setOwnerId(mutexOwnerId); - return pCBObject; -} + FTPClientCallbackInterface * FTPClientThread::getCallBackObject() { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId); + this->getProgressMutex()->setOwnerId(mutexOwnerId); + return pCBObject; + } -void FTPClientThread::setCallBackObject(FTPClientCallbackInterface *value) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(this->getProgressMutex(),mutexOwnerId); - this->getProgressMutex()->setOwnerId(mutexOwnerId); - pCBObject = value; -} + void FTPClientThread::setCallBackObject(FTPClientCallbackInterface *value) { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(this->getProgressMutex(), mutexOwnerId); + this->getProgressMutex()->setOwnerId(mutexOwnerId); + pCBObject = value; + } -void FTPClientThread::ShellCommandOutput_CallbackEvent(string cmd,char *output,void *userdata) { - if(this->pCBObject != NULL) { + void FTPClientThread::ShellCommandOutput_CallbackEvent(string cmd, char *output, void *userdata) { + if (this->pCBObject != NULL) { - string &itemName = *static_cast(userdata); - this->pCBObject->FTPClient_CallbackEvent( - itemName, - ftp_cct_ExtractProgress, - make_pair(ftp_crt_SUCCESS,"extracting"), - output); - } -} + string &itemName = *static_cast(userdata); + this->pCBObject->FTPClient_CallbackEvent( + itemName, + ftp_cct_ExtractProgress, + make_pair(ftp_crt_SUCCESS, "extracting"), + output); + } + } -void * FTPClientThread::getShellCommandOutput_UserData(string cmd) { - return &shellCommandCallbackUserData; -} + void * FTPClientThread::getShellCommandOutput_UserData(string cmd) { + return &shellCommandCallbackUserData; + } -void FTPClientThread::execute() { - { - RunningStatusSafeWrapper runningStatus(this); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + void FTPClientThread::execute() { + { + RunningStatusSafeWrapper runningStatus(this); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - if(getQuitStatus() == true) { - return; - } + if (getQuitStatus() == true) { + return; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Client thread is running\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"FTP Client thread is running\n"); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client thread is running\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "FTP Client thread is running\n"); - try { - while(this->getQuitStatus() == false) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&mutexMapFileList,mutexOwnerId); - mutexMapFileList.setOwnerId(mutexOwnerId); - if(mapFileList.size() > 0) { - pair mapFilename = mapFileList[0]; - mapFileList.erase(mapFileList.begin() + 0); - safeMutex.ReleaseLock(); + try { + while (this->getQuitStatus() == false) { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(&mutexMapFileList, mutexOwnerId); + mutexMapFileList.setOwnerId(mutexOwnerId); + if (mapFileList.size() > 0) { + pair mapFilename = mapFileList[0]; + mapFileList.erase(mapFileList.begin() + 0); + safeMutex.ReleaseLock(); - getMapFromServer(mapFilename); - } - else { - safeMutex.ReleaseLock(); - } + getMapFromServer(mapFilename); + } else { + safeMutex.ReleaseLock(); + } - if(this->getQuitStatus() == true) { - break; - } + if (this->getQuitStatus() == true) { + break; + } - static string mutexOwnerId2 = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex2(&mutexTilesetList,mutexOwnerId2); - mutexTilesetList.setOwnerId(mutexOwnerId2); - if(tilesetList.size() > 0) { - pair tileset = tilesetList[0]; - tilesetList.erase(tilesetList.begin() + 0); - safeMutex2.ReleaseLock(); + static string mutexOwnerId2 = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex2(&mutexTilesetList, mutexOwnerId2); + mutexTilesetList.setOwnerId(mutexOwnerId2); + if (tilesetList.size() > 0) { + pair tileset = tilesetList[0]; + tilesetList.erase(tilesetList.begin() + 0); + safeMutex2.ReleaseLock(); - getTilesetFromServer(tileset); - } - else { - safeMutex2.ReleaseLock(); - } + getTilesetFromServer(tileset); + } else { + safeMutex2.ReleaseLock(); + } - static string mutexOwnerId3 = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex3(&mutexTechtreeList,mutexOwnerId3); - mutexTechtreeList.setOwnerId(mutexOwnerId3); - if(techtreeList.size() > 0) { - pair techtree = techtreeList[0]; - techtreeList.erase(techtreeList.begin() + 0); - safeMutex3.ReleaseLock(); + static string mutexOwnerId3 = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex3(&mutexTechtreeList, mutexOwnerId3); + mutexTechtreeList.setOwnerId(mutexOwnerId3); + if (techtreeList.size() > 0) { + pair techtree = techtreeList[0]; + techtreeList.erase(techtreeList.begin() + 0); + safeMutex3.ReleaseLock(); - getTechtreeFromServer(techtree); - } - else { - safeMutex3.ReleaseLock(); - } + getTechtreeFromServer(techtree); + } else { + safeMutex3.ReleaseLock(); + } - static string mutexOwnerId4 = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex4(&mutexScenarioList,mutexOwnerId4); - mutexScenarioList.setOwnerId(mutexOwnerId4); - if(scenarioList.size() > 0) { - pair file = scenarioList[0]; - scenarioList.erase(scenarioList.begin() + 0); - safeMutex4.ReleaseLock(); + static string mutexOwnerId4 = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex4(&mutexScenarioList, mutexOwnerId4); + mutexScenarioList.setOwnerId(mutexOwnerId4); + if (scenarioList.size() > 0) { + pair file = scenarioList[0]; + scenarioList.erase(scenarioList.begin() + 0); + safeMutex4.ReleaseLock(); - getScenarioFromServer(file); - } - else { - safeMutex4.ReleaseLock(); - } + getScenarioFromServer(file); + } else { + safeMutex4.ReleaseLock(); + } - static string mutexOwnerId5 = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex5(&mutexFileList,mutexOwnerId5); - mutexFileList.setOwnerId(mutexOwnerId5); - if(fileList.size() > 0) { - pair file = fileList[0]; - fileList.erase(fileList.begin() + 0); - safeMutex5.ReleaseLock(); + static string mutexOwnerId5 = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex5(&mutexFileList, mutexOwnerId5); + mutexFileList.setOwnerId(mutexOwnerId5); + if (fileList.size() > 0) { + pair file = fileList[0]; + fileList.erase(fileList.begin() + 0); + safeMutex5.ReleaseLock(); - getFileFromServer(file); - } - else { - safeMutex5.ReleaseLock(); - } + getFileFromServer(file); + } else { + safeMutex5.ReleaseLock(); + } - static string mutexOwnerId6 = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex6(&mutexTempFileList,mutexOwnerId6); - mutexTempFileList.setOwnerId(mutexOwnerId6); - if(tempFileList.size() > 0) { - pair file = tempFileList[0]; - tempFileList.erase(tempFileList.begin() + 0); - safeMutex6.ReleaseLock(); + static string mutexOwnerId6 = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex6(&mutexTempFileList, mutexOwnerId6); + mutexTempFileList.setOwnerId(mutexOwnerId6); + if (tempFileList.size() > 0) { + pair file = tempFileList[0]; + tempFileList.erase(tempFileList.begin() + 0); + safeMutex6.ReleaseLock(); - getTempFileFromServer(file); - } - else { - safeMutex6.ReleaseLock(); - } + getTempFileFromServer(file); + } else { + safeMutex6.ReleaseLock(); + } - if(this->getQuitStatus() == false) { - sleep(25); - } - } + if (this->getQuitStatus() == false) { + sleep(25); + } + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client exiting!\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client exiting!\n"); - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - } - catch(...) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] UNKNOWN Error\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__); - } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client exiting!\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Client exiting!\n"); + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + } catch (...) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] UNKNOWN Error\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] unknown error\n", __FILE__, __FUNCTION__, __LINE__); + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] FTP Client thread is exiting\n",__FILE__,__FUNCTION__,__LINE__); - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] FTP Client thread is exiting\n", __FILE__, __FUNCTION__, __LINE__); + } - // Delete ourself when the thread is done (no other actions can happen after this - // such as the mutex which modifies the running status of this method - deleteSelfIfRequired(); -} + // Delete ourself when the thread is done (no other actions can happen after this + // such as the mutex which modifies the running status of this method + deleteSelfIfRequired(); + } -}}//end namespace + } +}//end namespace diff --git a/source/shared_lib/sources/platform/posix/miniftpserver.cpp b/source/shared_lib/sources/platform/posix/miniftpserver.cpp index 5f299f74e..ae1c0924b 100644 --- a/source/shared_lib/sources/platform/posix/miniftpserver.cpp +++ b/source/shared_lib/sources/platform/posix/miniftpserver.cpp @@ -24,256 +24,253 @@ using namespace Shared::Util; using namespace Shared::PlatformCommon; -namespace Shared { namespace PlatformCommon { +namespace Shared { + namespace PlatformCommon { -static const char *FTP_MAPS_CUSTOM_USERNAME = "maps_custom"; -static const char *FTP_MAPS_USERNAME = "maps"; -static const char *FTP_TILESETS_CUSTOM_USERNAME = "tilesets_custom"; -static const char *FTP_TILESETS_USERNAME = "tilesets"; -static const char *FTP_TECHTREES_CUSTOM_USERNAME = "techtrees_custom"; -static const char *FTP_TECHTREES_USERNAME = "techtrees"; + static const char *FTP_MAPS_CUSTOM_USERNAME = "maps_custom"; + static const char *FTP_MAPS_USERNAME = "maps"; + static const char *FTP_TILESETS_CUSTOM_USERNAME = "tilesets_custom"; + static const char *FTP_TILESETS_USERNAME = "tilesets"; + static const char *FTP_TECHTREES_CUSTOM_USERNAME = "techtrees_custom"; + static const char *FTP_TECHTREES_USERNAME = "techtrees"; -static const char *FTP_TEMPFILES_USERNAME = "temp"; + static const char *FTP_TEMPFILES_USERNAME = "temp"; -static const char *FTP_COMMON_PASSWORD = "mg_ftp_server"; + static const char *FTP_COMMON_PASSWORD = "mg_ftp_server"; -static std::map clientToFTPServerList; -FTPClientValidationInterface * FTPServerThread::ftpValidationIntf = NULL; + static std::map clientToFTPServerList; + FTPClientValidationInterface * FTPServerThread::ftpValidationIntf = NULL; -ip_t FindExternalFTPServerIp(ip_t clientIp) { - ip_t result = clientToFTPServerList[clientIp]; + ip_t FindExternalFTPServerIp(ip_t clientIp) { + ip_t result = clientToFTPServerList[clientIp]; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server thread clientIp = %u, result = %u\n",clientIp,result); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Server thread clientIp = %u, result = %u\n",clientIp,result); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server thread clientIp = %u, result = %u\n", clientIp, result); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Server thread clientIp = %u, result = %u\n", clientIp, result); - return result; -} + return result; + } -int isValidClientType(ip_t clientIp) { - int result = 0; - if(FTPServerThread::getFtpValidationIntf() != NULL) { - result = FTPServerThread::getFtpValidationIntf()->isValidClientType(clientIp); - } - return result; -} - -int isClientAllowedToGetFile(ip_t clientIp, const char *username, const char *filename) { - int result = 1; - - //printf("In [%s::%s] Line: %d username [%s] file [%s]\n",__FILE__,__FUNCTION__,__LINE__,username,filename); - if(FTPServerThread::getFtpValidationIntf() != NULL) { - result = FTPServerThread::getFtpValidationIntf()->isClientAllowedToGetFile(clientIp,username,filename); - //printf("In [%s::%s] Line: %d username [%s] file [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,username,filename,result); - } - return result; -} - -FTPServerThread::FTPServerThread(std::pair mapsPath, - std::pair tilesetsPath, std::pair techtreesPath, - bool internetEnabledFlag, - bool allowInternetTilesetFileTransfers, bool allowInternetTechtreeFileTransfers, - int portNumber, int maxPlayers, - FTPClientValidationInterface *ftpValidationIntf, string tempFilesPath) : BaseThread() { - - uniqueID = "FTPServerThread"; - this->mapsPath = mapsPath; - this->tilesetsPath = tilesetsPath; - this->techtreesPath = techtreesPath; - this->allowInternetTilesetFileTransfers = allowInternetTilesetFileTransfers; - this->allowInternetTechtreeFileTransfers = allowInternetTechtreeFileTransfers; - setInternetEnabled(internetEnabledFlag,true); - this->portNumber = portNumber; - this->maxPlayers = maxPlayers; - this->ftpValidationIntf = ftpValidationIntf; - this->tempFilesPath = tempFilesPath; - - ftpInit(&FindExternalFTPServerIp,&UPNP_Tools::AddUPNPPortForward,&UPNP_Tools::RemoveUPNPPortForward, - &isValidClientType, &isClientAllowedToGetFile); - VERBOSE_MODE_ENABLED = SystemFlags::VERBOSE_MODE_ENABLED; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("***FTP SERVER STARTED [%p]\n",this); -} - -FTPServerThread::~FTPServerThread() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - ftpShutdown(); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - // Remove any UPNP port forwarded ports - //printf("In [%s::%s] Line: %d ServerSocket::getFTPServerPort() = %d\n",__FILE__,__FUNCTION__,__LINE__,ServerSocket::getFTPServerPort()); - UPNP_Tools::upnp_rem_redirect(ServerSocket::getFTPServerPort()); - for(int clientIndex = 1; clientIndex <= maxPlayers; ++clientIndex) { - //printf("In [%s::%s] Line: %d ServerSocket::getFTPServerPort()+ clientIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,ServerSocket::getFTPServerPort()+ clientIndex); - UPNP_Tools::upnp_rem_redirect(ServerSocket::getFTPServerPort() + clientIndex); - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("***FTP SERVER ENDED [%p]\n",this); -} - -void FTPServerThread::signalQuit() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Server: signalQuit\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Server: signalQuit\n"); - ftpShutdown(); - - BaseThread::signalQuit(); -} - -bool FTPServerThread::shutdownAndWait() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server: shutdownAndWait\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Server: shutdownAndWait\n"); - - signalQuit(); - bool ret = BaseThread::shutdownAndWait(); - clientToFTPServerList.clear(); - return ret; -} - -void FTPServerThread::addClientToServerIPAddress(uint32 clientIp,uint32 ServerIp) { - clientToFTPServerList[clientIp] = ServerIp; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server thread clientIp = %u, ServerIp = %u\n",clientIp,ServerIp); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Server thread clientIp = %u, ServerIp = %u\n",clientIp,ServerIp); -} - -void FTPServerThread::setInternetEnabled(bool value, bool forceChange) { - if(forceChange == true || this->internetEnabled != value) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Server thread, changing InternetEnabled = %d\n",value); - - this->internetEnabled = value; - if(this->internetEnabled == true) { - // Setup FTP Users and permissions for tilesets - if(this->allowInternetTilesetFileTransfers == true) { - if(tilesetsPath.first != "") { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] tilesetsPath #1 [%s]\n",__FILE__,__FUNCTION__,__LINE__,tilesetsPath.first.c_str()); - ftpCreateAccount(FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, tilesetsPath.first.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); - } - if(tilesetsPath.second != "") { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] tilesetsPath #2 [%s]\n",__FILE__,__FUNCTION__,__LINE__,tilesetsPath.second.c_str()); - ftpCreateAccount(FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, tilesetsPath.second.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Server thread, tilesets users created\n"); + int isValidClientType(ip_t clientIp) { + int result = 0; + if (FTPServerThread::getFtpValidationIntf() != NULL) { + result = FTPServerThread::getFtpValidationIntf()->isValidClientType(clientIp); } - else { - ftpDeleteAccount(FTP_TILESETS_USERNAME); - ftpDeleteAccount(FTP_TILESETS_CUSTOM_USERNAME); + return result; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Server thread, tilesets users deleted\n"); + int isClientAllowedToGetFile(ip_t clientIp, const char *username, const char *filename) { + int result = 1; + + //printf("In [%s::%s] Line: %d username [%s] file [%s]\n",__FILE__,__FUNCTION__,__LINE__,username,filename); + if (FTPServerThread::getFtpValidationIntf() != NULL) { + result = FTPServerThread::getFtpValidationIntf()->isClientAllowedToGetFile(clientIp, username, filename); + //printf("In [%s::%s] Line: %d username [%s] file [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,username,filename,result); } + return result; + } - if(this->allowInternetTechtreeFileTransfers == true) { - // Setup FTP Users and permissions for tilesets - if(techtreesPath.first != "") { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] techtreesPath #1 [%s]\n",__FILE__,__FUNCTION__,__LINE__,techtreesPath.first.c_str()); - ftpCreateAccount(FTP_TECHTREES_USERNAME, FTP_COMMON_PASSWORD, techtreesPath.first.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); - } - if(techtreesPath.second != "") { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] techtreesPath #2 [%s]\n",__FILE__,__FUNCTION__,__LINE__,techtreesPath.second.c_str()); - ftpCreateAccount(FTP_TECHTREES_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, techtreesPath.second.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); - } + FTPServerThread::FTPServerThread(std::pair mapsPath, + std::pair tilesetsPath, std::pair techtreesPath, + bool internetEnabledFlag, + bool allowInternetTilesetFileTransfers, bool allowInternetTechtreeFileTransfers, + int portNumber, int maxPlayers, + FTPClientValidationInterface *ftpValidationIntf, string tempFilesPath) : BaseThread() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Server thread, techtrees users created\n"); + uniqueID = "FTPServerThread"; + this->mapsPath = mapsPath; + this->tilesetsPath = tilesetsPath; + this->techtreesPath = techtreesPath; + this->allowInternetTilesetFileTransfers = allowInternetTilesetFileTransfers; + this->allowInternetTechtreeFileTransfers = allowInternetTechtreeFileTransfers; + setInternetEnabled(internetEnabledFlag, true); + this->portNumber = portNumber; + this->maxPlayers = maxPlayers; + this->ftpValidationIntf = ftpValidationIntf; + this->tempFilesPath = tempFilesPath; + + ftpInit(&FindExternalFTPServerIp, &UPNP_Tools::AddUPNPPortForward, &UPNP_Tools::RemoveUPNPPortForward, + &isValidClientType, &isClientAllowedToGetFile); + VERBOSE_MODE_ENABLED = SystemFlags::VERBOSE_MODE_ENABLED; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("***FTP SERVER STARTED [%p]\n", this); + } + + FTPServerThread::~FTPServerThread() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + ftpShutdown(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + // Remove any UPNP port forwarded ports + //printf("In [%s::%s] Line: %d ServerSocket::getFTPServerPort() = %d\n",__FILE__,__FUNCTION__,__LINE__,ServerSocket::getFTPServerPort()); + UPNP_Tools::upnp_rem_redirect(ServerSocket::getFTPServerPort()); + for (int clientIndex = 1; clientIndex <= maxPlayers; ++clientIndex) { + //printf("In [%s::%s] Line: %d ServerSocket::getFTPServerPort()+ clientIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,ServerSocket::getFTPServerPort()+ clientIndex); + UPNP_Tools::upnp_rem_redirect(ServerSocket::getFTPServerPort() + clientIndex); } - else { - ftpDeleteAccount(FTP_TECHTREES_USERNAME); - ftpDeleteAccount(FTP_TECHTREES_CUSTOM_USERNAME); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Server thread, techtrees users deleted\n"); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("***FTP SERVER ENDED [%p]\n", this); + } + + void FTPServerThread::signalQuit() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server: signalQuit\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Server: signalQuit\n"); + ftpShutdown(); + + BaseThread::signalQuit(); + } + + bool FTPServerThread::shutdownAndWait() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server: shutdownAndWait\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Server: shutdownAndWait\n"); + + signalQuit(); + bool ret = BaseThread::shutdownAndWait(); + clientToFTPServerList.clear(); + return ret; + } + + void FTPServerThread::addClientToServerIPAddress(uint32 clientIp, uint32 ServerIp) { + clientToFTPServerList[clientIp] = ServerIp; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server thread clientIp = %u, ServerIp = %u\n", clientIp, ServerIp); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Server thread clientIp = %u, ServerIp = %u\n", clientIp, ServerIp); + } + + void FTPServerThread::setInternetEnabled(bool value, bool forceChange) { + if (forceChange == true || this->internetEnabled != value) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server thread, changing InternetEnabled = %d\n", value); + + this->internetEnabled = value; + if (this->internetEnabled == true) { + // Setup FTP Users and permissions for tilesets + if (this->allowInternetTilesetFileTransfers == true) { + if (tilesetsPath.first != "") { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] tilesetsPath #1 [%s]\n", __FILE__, __FUNCTION__, __LINE__, tilesetsPath.first.c_str()); + ftpCreateAccount(FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, tilesetsPath.first.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); + } + if (tilesetsPath.second != "") { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] tilesetsPath #2 [%s]\n", __FILE__, __FUNCTION__, __LINE__, tilesetsPath.second.c_str()); + ftpCreateAccount(FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, tilesetsPath.second.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server thread, tilesets users created\n"); + } else { + ftpDeleteAccount(FTP_TILESETS_USERNAME); + ftpDeleteAccount(FTP_TILESETS_CUSTOM_USERNAME); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server thread, tilesets users deleted\n"); + } + + if (this->allowInternetTechtreeFileTransfers == true) { + // Setup FTP Users and permissions for tilesets + if (techtreesPath.first != "") { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] techtreesPath #1 [%s]\n", __FILE__, __FUNCTION__, __LINE__, techtreesPath.first.c_str()); + ftpCreateAccount(FTP_TECHTREES_USERNAME, FTP_COMMON_PASSWORD, techtreesPath.first.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); + } + if (techtreesPath.second != "") { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] techtreesPath #2 [%s]\n", __FILE__, __FUNCTION__, __LINE__, techtreesPath.second.c_str()); + ftpCreateAccount(FTP_TECHTREES_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, techtreesPath.second.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server thread, techtrees users created\n"); + } else { + ftpDeleteAccount(FTP_TECHTREES_USERNAME); + ftpDeleteAccount(FTP_TECHTREES_CUSTOM_USERNAME); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server thread, techtrees users deleted\n"); + } + } else { + if (tilesetsPath.first != "") { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] tilesetsPath #1 [%s]\n", __FILE__, __FUNCTION__, __LINE__, tilesetsPath.first.c_str()); + ftpCreateAccount(FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, tilesetsPath.first.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); + } + if (tilesetsPath.second != "") { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] tilesetsPath #2 [%s]\n", __FILE__, __FUNCTION__, __LINE__, tilesetsPath.second.c_str()); + ftpCreateAccount(FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, tilesetsPath.second.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server thread, tilesets users created\n"); + + // Setup FTP Users and permissions for tilesets + if (techtreesPath.first != "") { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] techtreesPath #1 [%s]\n", __FILE__, __FUNCTION__, __LINE__, techtreesPath.first.c_str()); + ftpCreateAccount(FTP_TECHTREES_USERNAME, FTP_COMMON_PASSWORD, techtreesPath.first.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); + } + if (techtreesPath.second != "") { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] techtreesPath #2 [%s]\n", __FILE__, __FUNCTION__, __LINE__, techtreesPath.second.c_str()); + ftpCreateAccount(FTP_TECHTREES_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, techtreesPath.second.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server thread, techtrees users created\n"); + } } } - else { - if(tilesetsPath.first != "") { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] tilesetsPath #1 [%s]\n",__FILE__,__FUNCTION__,__LINE__,tilesetsPath.first.c_str()); - ftpCreateAccount(FTP_TILESETS_USERNAME, FTP_COMMON_PASSWORD, tilesetsPath.first.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); - } - if(tilesetsPath.second != "") { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] tilesetsPath #2 [%s]\n",__FILE__,__FUNCTION__,__LINE__,tilesetsPath.second.c_str()); - ftpCreateAccount(FTP_TILESETS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, tilesetsPath.second.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Server thread, tilesets users created\n"); + void FTPServerThread::execute() { + { + RunningStatusSafeWrapper runningStatus(this); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - // Setup FTP Users and permissions for tilesets - if(techtreesPath.first != "") { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] techtreesPath #1 [%s]\n",__FILE__,__FUNCTION__,__LINE__,techtreesPath.first.c_str()); - ftpCreateAccount(FTP_TECHTREES_USERNAME, FTP_COMMON_PASSWORD, techtreesPath.first.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); - } - if(techtreesPath.second != "") { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] techtreesPath #2 [%s]\n",__FILE__,__FUNCTION__,__LINE__,techtreesPath.second.c_str()); - ftpCreateAccount(FTP_TECHTREES_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, techtreesPath.second.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); - } + if (getQuitStatus() == true) { + return; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Server thread, techtrees users created\n"); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server thread is running\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "FTP Server thread is running\n"); + + try { + //ftpCreateAccount("anonymous", "", mapsPath.first.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); + + // Setup FTP Users and permissions for maps + if (mapsPath.first != "") { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] mapsPath #1 [%s]\n", __FILE__, __FUNCTION__, __LINE__, mapsPath.first.c_str()); + ftpCreateAccount(FTP_MAPS_USERNAME, FTP_COMMON_PASSWORD, mapsPath.first.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); + } + if (mapsPath.second != "") { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] mapsPath #2 [%s]\n", __FILE__, __FUNCTION__, __LINE__, mapsPath.second.c_str()); + ftpCreateAccount(FTP_MAPS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, mapsPath.second.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); + } + + if (tempFilesPath != "") { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] tempFilesPath [%s]\n", __FILE__, __FUNCTION__, __LINE__, tempFilesPath.c_str()); + ftpCreateAccount(FTP_TEMPFILES_USERNAME, FTP_COMMON_PASSWORD, tempFilesPath.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); + } + + /* + ftpCreateAccount("anonymous", "", "./", FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); + ftpCreateAccount("nothing", "", "./", 0); + ftpCreateAccount("reader", "", "./", FTP_ACC_RD); + ftpCreateAccount("writer", "", "./", FTP_ACC_WR); + ftpCreateAccount("lister", "", "./", FTP_ACC_LS); + ftpCreateAccount("admin", "xxx", "./", FTP_ACC_RD | FTP_ACC_WR | FTP_ACC_LS | FTP_ACC_DIR); + */ + if (getQuitStatus() == true) { + return; + } + + ftpStart(portNumber); + while (this->getQuitStatus() == false) { + ftpExecute(); + //if(processedWork == 0) { + //sleep(25); + //} + } + ftpShutdown(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server exiting!\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "===> FTP Server exiting!\n"); + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + } catch (...) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] UNKNOWN Error\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] unknown error\n", __FILE__, __FUNCTION__, __LINE__); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] FTP Server thread is exiting\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] FTP Server thread is exiting\n", __FILE__, __FUNCTION__, __LINE__); + } } + } -} - -void FTPServerThread::execute() { - { - RunningStatusSafeWrapper runningStatus(this); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(getQuitStatus() == true) { - return; - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("===> FTP Server thread is running\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"FTP Server thread is running\n"); - - try { - //ftpCreateAccount("anonymous", "", mapsPath.first.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); - - // Setup FTP Users and permissions for maps - if(mapsPath.first != "") { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] mapsPath #1 [%s]\n",__FILE__,__FUNCTION__,__LINE__,mapsPath.first.c_str()); - ftpCreateAccount(FTP_MAPS_USERNAME, FTP_COMMON_PASSWORD, mapsPath.first.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); - } - if(mapsPath.second != "") { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] mapsPath #2 [%s]\n",__FILE__,__FUNCTION__,__LINE__,mapsPath.second.c_str()); - ftpCreateAccount(FTP_MAPS_CUSTOM_USERNAME, FTP_COMMON_PASSWORD, mapsPath.second.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); - } - - if(tempFilesPath != "") { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] tempFilesPath [%s]\n",__FILE__,__FUNCTION__,__LINE__,tempFilesPath.c_str()); - ftpCreateAccount(FTP_TEMPFILES_USERNAME, FTP_COMMON_PASSWORD, tempFilesPath.c_str(), FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); - } - -/* - ftpCreateAccount("anonymous", "", "./", FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR); - ftpCreateAccount("nothing", "", "./", 0); - ftpCreateAccount("reader", "", "./", FTP_ACC_RD); - ftpCreateAccount("writer", "", "./", FTP_ACC_WR); - ftpCreateAccount("lister", "", "./", FTP_ACC_LS); - ftpCreateAccount("admin", "xxx", "./", FTP_ACC_RD | FTP_ACC_WR | FTP_ACC_LS | FTP_ACC_DIR); -*/ - if(getQuitStatus() == true) { - return; - } - - ftpStart(portNumber); - while(this->getQuitStatus() == false) { - ftpExecute(); - //if(processedWork == 0) { - //sleep(25); - //} - } - ftpShutdown(); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server exiting!\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Server exiting!\n"); - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - } - catch(...) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] UNKNOWN Error\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] FTP Server thread is exiting\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] FTP Server thread is exiting\n",__FILE__,__FUNCTION__,__LINE__); - } -} - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/platform/posix/socket.cpp b/source/shared_lib/sources/platform/posix/socket.cpp index a1826170d..ec64c6ae6 100644 --- a/source/shared_lib/sources/platform/posix/socket.cpp +++ b/source/shared_lib/sources/platform/posix/socket.cpp @@ -14,11 +14,11 @@ #include #if defined(HAVE_SYS_IOCTL_H) || defined(__linux__) - #define BSD_COMP /* needed for FIONREAD on Solaris2 */ - #include +#define BSD_COMP /* needed for FIONREAD on Solaris2 */ +#include #endif #if defined(HAVE_SYS_FILIO_H) /* needed for FIONREAD on Solaris 2.5 */ - #include +#include #endif #include "conversion.h" @@ -28,27 +28,27 @@ #ifdef WIN32 - #include - #include - #include - #include - #include +#include +#include +#include +#include +#include - #include - #include +#include +#include #define MSG_NOSIGNAL 0 #define MSG_DONTWAIT 0 #else - #include - #include - #include - #include - #include - #include - #include +#include +#include +#include +#include +#include +#include +#include #endif @@ -65,3244 +65,3164 @@ using namespace std; using namespace Shared::Util; -namespace Shared{ namespace Platform{ +namespace Shared { + namespace Platform { -bool Socket::disableNagle = false; -int Socket::DEFAULT_SOCKET_SENDBUF_SIZE = -1; -int Socket::DEFAULT_SOCKET_RECVBUF_SIZE = -1; -string Socket::host_name = ""; -std::vector Socket::intfTypes; + bool Socket::disableNagle = false; + int Socket::DEFAULT_SOCKET_SENDBUF_SIZE = -1; + int Socket::DEFAULT_SOCKET_RECVBUF_SIZE = -1; + string Socket::host_name = ""; + std::vector Socket::intfTypes; -int Socket::broadcast_portno = 61357; -int ServerSocket::ftpServerPort = 61358; -int ServerSocket::maxPlayerCount = -1; -int ServerSocket::externalPort = Socket::broadcast_portno; -BroadCastClientSocketThread *ClientSocket::broadCastClientThread = NULL; -SDL_Thread *ServerSocket::upnpdiscoverThread = NULL; -bool ServerSocket::cancelUpnpdiscoverThread = false; -Mutex ServerSocket::mutexUpnpdiscoverThread; -// -// UPnP - Start -// -static struct UPNPUrls urls; -static struct IGDdatas data; -// local ip address -static char lanaddr[16] = ""; -bool UPNP_Tools::isUPNP = true; -bool UPNP_Tools::enabledUPNP = false; -Mutex UPNP_Tools::mutexUPNP; -// UPnP - End + int Socket::broadcast_portno = 61357; + int ServerSocket::ftpServerPort = 61358; + int ServerSocket::maxPlayerCount = -1; + int ServerSocket::externalPort = Socket::broadcast_portno; + BroadCastClientSocketThread *ClientSocket::broadCastClientThread = NULL; + SDL_Thread *ServerSocket::upnpdiscoverThread = NULL; + bool ServerSocket::cancelUpnpdiscoverThread = false; + Mutex ServerSocket::mutexUpnpdiscoverThread; + // + // UPnP - Start + // + static struct UPNPUrls urls; + static struct IGDdatas data; + // local ip address + static char lanaddr[16] = ""; + bool UPNP_Tools::isUPNP = true; + bool UPNP_Tools::enabledUPNP = false; + Mutex UPNP_Tools::mutexUPNP; + // UPnP - End #ifdef WIN32 - #define socklen_t int - #define MAXHOSTNAME 254 +#define socklen_t int +#define MAXHOSTNAME 254 //#define PLATFORM_SOCKET_TRY_AGAIN WSAEWOULDBLOCK //#define PLATFORM_SOCKET_INPROGRESS WSAEINPROGRESS //#define PLATFORM_SOCKET_INTERRUPTED WSAEWOULDBLOCK - typedef SSIZE_T ssize_t; + typedef SSIZE_T ssize_t; - //// Constants ///////////////////////////////////////////////////////// - const int kBufferSize = 1024; + //// Constants ///////////////////////////////////////////////////////// + const int kBufferSize = 1024; - //// Statics /////////////////////////////////////////////////////////// - // List of Winsock error constants mapped to an interpretation string. - // Note that this list must remain sorted by the error constants' - // values, because we do a binary search on the list when looking up - // items. + //// Statics /////////////////////////////////////////////////////////// + // List of Winsock error constants mapped to an interpretation string. + // Note that this list must remain sorted by the error constants' + // values, because we do a binary search on the list when looking up + // items. - static class ErrorEntry - { - public: - int nID; - const char* pcMessage; + static class ErrorEntry { + public: + int nID; + const char* pcMessage; - ErrorEntry(int id, const char* pc = 0) : nID(id), pcMessage(pc) + ErrorEntry(int id, const char* pc = 0) : nID(id), pcMessage(pc) { + } + + bool operator<(const ErrorEntry& rhs) { + return nID < rhs.nID; + } + + } gaErrorList[] = { + ErrorEntry(0, "No error"), + ErrorEntry(WSAEINTR, "Interrupted system call"), + ErrorEntry(WSAEBADF, "Bad file number"), + ErrorEntry(WSAEACCES, "Permission denied"), + ErrorEntry(WSAEFAULT, "Bad address"), + ErrorEntry(WSAEINVAL, "Invalid argument"), + ErrorEntry(WSAEMFILE, "Too many open sockets"), + ErrorEntry(WSAEWOULDBLOCK, "Operation would block"), + ErrorEntry(WSAEINPROGRESS, "Operation now in progress"), + ErrorEntry(WSAEALREADY, "Operation already in progress"), + ErrorEntry(WSAENOTSOCK, "Socket operation on non-socket"), + ErrorEntry(WSAEDESTADDRREQ, "Destination address required"), + ErrorEntry(WSAEMSGSIZE, "Message too long"), + ErrorEntry(WSAEPROTOTYPE, "Protocol wrong type for socket"), + ErrorEntry(WSAENOPROTOOPT, "Bad protocol option"), + ErrorEntry(WSAEPROTONOSUPPORT, "Protocol not supported"), + ErrorEntry(WSAESOCKTNOSUPPORT, "Socket type not supported"), + ErrorEntry(WSAEOPNOTSUPP, "Operation not supported on socket"), + ErrorEntry(WSAEPFNOSUPPORT, "Protocol family not supported"), + ErrorEntry(WSAEAFNOSUPPORT, "Address family not supported"), + ErrorEntry(WSAEADDRINUSE, "Address already in use"), + ErrorEntry(WSAEADDRNOTAVAIL, "Can't assign requested address"), + ErrorEntry(WSAENETDOWN, "Network is down"), + ErrorEntry(WSAENETUNREACH, "Network is unreachable"), + ErrorEntry(WSAENETRESET, "Net connection reset"), + ErrorEntry(WSAECONNABORTED, "Software caused connection abort"), + ErrorEntry(WSAECONNRESET, "Connection reset by peer"), + ErrorEntry(WSAENOBUFS, "No buffer space available"), + ErrorEntry(WSAEISCONN, "Socket is already connected"), + ErrorEntry(WSAENOTCONN, "Socket is not connected"), + ErrorEntry(WSAESHUTDOWN, "Can't send after socket shutdown"), + ErrorEntry(WSAETOOMANYREFS, "Too many references, can't splice"), + ErrorEntry(WSAETIMEDOUT, "Connection timed out"), + ErrorEntry(WSAECONNREFUSED, "Connection refused"), + ErrorEntry(WSAELOOP, "Too many levels of symbolic links"), + ErrorEntry(WSAENAMETOOLONG, "File name too long"), + ErrorEntry(WSAEHOSTDOWN, "Host is down"), + ErrorEntry(WSAEHOSTUNREACH, "No route to host"), + ErrorEntry(WSAENOTEMPTY, "Directory not empty"), + ErrorEntry(WSAEPROCLIM, "Too many processes"), + ErrorEntry(WSAEUSERS, "Too many users"), + ErrorEntry(WSAEDQUOT, "Disc quota exceeded"), + ErrorEntry(WSAESTALE, "Stale NFS file handle"), + ErrorEntry(WSAEREMOTE, "Too many levels of remote in path"), + ErrorEntry(WSASYSNOTREADY, "Network system is unavailable"), + ErrorEntry(WSAVERNOTSUPPORTED, "Winsock version out of range"), + ErrorEntry(WSANOTINITIALISED, "WSAStartup not yet called"), + ErrorEntry(WSAEDISCON, "Graceful shutdown in progress"), + ErrorEntry(WSAHOST_NOT_FOUND, "Host not found"), + ErrorEntry(WSANO_DATA, "No host data of that type was found") + }; + + bool operator<(const ErrorEntry& rhs1, const ErrorEntry& rhs2) { + return rhs1.nID < rhs2.nID; } - bool operator<(const ErrorEntry& rhs) - { - return nID < rhs.nID; + const int kNumMessages = sizeof(gaErrorList) / sizeof(ErrorEntry); + + //// WSAGetLastErrorMessage //////////////////////////////////////////// + // A function similar in spirit to Unix's perror() that tacks a canned + // interpretation of the value of WSAGetLastError() onto the end of a + // passed string, separated by a ": ". Generally, you should implement + // smarter error handling than this, but for default cases and simple + // programs, this function is sufficient. + // + // This function returns a pointer to an internal static buffer, so you + // must copy the data from this function before you call it again. It + // follows that this function is also not thread-safe. + const char* WSAGetLastErrorMessage(const char* pcMessagePrefix, + int nErrorID = 0) { + // Build basic error string + static char acErrorBuffer[8096]; + std::ostrstream outs(acErrorBuffer, 8095); + outs << pcMessagePrefix << ": "; + + // Tack appropriate canned message onto end of supplied message + // prefix. Note that we do a binary search here: gaErrorList must be + // sorted by the error constant's value. + ErrorEntry* pEnd = gaErrorList + kNumMessages; + ErrorEntry Target(nErrorID ? nErrorID : WSAGetLastError()); + ErrorEntry* it = std::lower_bound(gaErrorList, pEnd, Target); + if ((it != pEnd) && (it->nID == Target.nID)) { + outs << it->pcMessage; + } else { + // Didn't find error in list, so make up a generic one + outs << "unknown socket error"; + } + outs << " (" << Target.nID << ")"; + + // Finish error message off and return it. + outs << std::ends; + acErrorBuffer[8095] = '\0'; + return acErrorBuffer; } - } gaErrorList[] = - { - ErrorEntry(0, "No error"), - ErrorEntry(WSAEINTR, "Interrupted system call"), - ErrorEntry(WSAEBADF, "Bad file number"), - ErrorEntry(WSAEACCES, "Permission denied"), - ErrorEntry(WSAEFAULT, "Bad address"), - ErrorEntry(WSAEINVAL, "Invalid argument"), - ErrorEntry(WSAEMFILE, "Too many open sockets"), - ErrorEntry(WSAEWOULDBLOCK, "Operation would block"), - ErrorEntry(WSAEINPROGRESS, "Operation now in progress"), - ErrorEntry(WSAEALREADY, "Operation already in progress"), - ErrorEntry(WSAENOTSOCK, "Socket operation on non-socket"), - ErrorEntry(WSAEDESTADDRREQ, "Destination address required"), - ErrorEntry(WSAEMSGSIZE, "Message too long"), - ErrorEntry(WSAEPROTOTYPE, "Protocol wrong type for socket"), - ErrorEntry(WSAENOPROTOOPT, "Bad protocol option"), - ErrorEntry(WSAEPROTONOSUPPORT, "Protocol not supported"), - ErrorEntry(WSAESOCKTNOSUPPORT, "Socket type not supported"), - ErrorEntry(WSAEOPNOTSUPP, "Operation not supported on socket"), - ErrorEntry(WSAEPFNOSUPPORT, "Protocol family not supported"), - ErrorEntry(WSAEAFNOSUPPORT, "Address family not supported"), - ErrorEntry(WSAEADDRINUSE, "Address already in use"), - ErrorEntry(WSAEADDRNOTAVAIL, "Can't assign requested address"), - ErrorEntry(WSAENETDOWN, "Network is down"), - ErrorEntry(WSAENETUNREACH, "Network is unreachable"), - ErrorEntry(WSAENETRESET, "Net connection reset"), - ErrorEntry(WSAECONNABORTED, "Software caused connection abort"), - ErrorEntry(WSAECONNRESET, "Connection reset by peer"), - ErrorEntry(WSAENOBUFS, "No buffer space available"), - ErrorEntry(WSAEISCONN, "Socket is already connected"), - ErrorEntry(WSAENOTCONN, "Socket is not connected"), - ErrorEntry(WSAESHUTDOWN, "Can't send after socket shutdown"), - ErrorEntry(WSAETOOMANYREFS, "Too many references, can't splice"), - ErrorEntry(WSAETIMEDOUT, "Connection timed out"), - ErrorEntry(WSAECONNREFUSED, "Connection refused"), - ErrorEntry(WSAELOOP, "Too many levels of symbolic links"), - ErrorEntry(WSAENAMETOOLONG, "File name too long"), - ErrorEntry(WSAEHOSTDOWN, "Host is down"), - ErrorEntry(WSAEHOSTUNREACH, "No route to host"), - ErrorEntry(WSAENOTEMPTY, "Directory not empty"), - ErrorEntry(WSAEPROCLIM, "Too many processes"), - ErrorEntry(WSAEUSERS, "Too many users"), - ErrorEntry(WSAEDQUOT, "Disc quota exceeded"), - ErrorEntry(WSAESTALE, "Stale NFS file handle"), - ErrorEntry(WSAEREMOTE, "Too many levels of remote in path"), - ErrorEntry(WSASYSNOTREADY, "Network system is unavailable"), - ErrorEntry(WSAVERNOTSUPPORTED, "Winsock version out of range"), - ErrorEntry(WSANOTINITIALISED, "WSAStartup not yet called"), - ErrorEntry(WSAEDISCON, "Graceful shutdown in progress"), - ErrorEntry(WSAHOST_NOT_FOUND, "Host not found"), - ErrorEntry(WSANO_DATA, "No host data of that type was found") - }; + // keeps in scope for duration of the application + //SocketManager Socket::wsaManager; - bool operator<(const ErrorEntry& rhs1,const ErrorEntry& rhs2) - { - return rhs1.nID < rhs2.nID; - } - - const int kNumMessages = sizeof(gaErrorList) / sizeof(ErrorEntry); - - //// WSAGetLastErrorMessage //////////////////////////////////////////// - // A function similar in spirit to Unix's perror() that tacks a canned - // interpretation of the value of WSAGetLastError() onto the end of a - // passed string, separated by a ": ". Generally, you should implement - // smarter error handling than this, but for default cases and simple - // programs, this function is sufficient. - // - // This function returns a pointer to an internal static buffer, so you - // must copy the data from this function before you call it again. It - // follows that this function is also not thread-safe. - const char* WSAGetLastErrorMessage(const char* pcMessagePrefix, - int nErrorID = 0 ) - { - // Build basic error string - static char acErrorBuffer[8096]; - std::ostrstream outs(acErrorBuffer, 8095); - outs << pcMessagePrefix << ": "; - - // Tack appropriate canned message onto end of supplied message - // prefix. Note that we do a binary search here: gaErrorList must be - // sorted by the error constant's value. - ErrorEntry* pEnd = gaErrorList + kNumMessages; - ErrorEntry Target(nErrorID ? nErrorID : WSAGetLastError()); - ErrorEntry* it = std::lower_bound(gaErrorList, pEnd, Target); - if ((it != pEnd) && (it->nID == Target.nID)) - { - outs << it->pcMessage; + SocketManager::SocketManager() { + WSADATA wsaData; + WORD wVersionRequested = MAKEWORD(2, 0); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("SocketManager calling WSAStartup...\n"); + WSAStartup(wVersionRequested, &wsaData); + //dont throw exceptions here, this is a static initializacion + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "Winsock initialized.\n"); } - else - { - // Didn't find error in list, so make up a generic one - outs << "unknown socket error"; + + SocketManager::~SocketManager() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("SocketManager calling WSACleanup...\n"); + WSACleanup(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "Winsock cleanup complete.\n"); } - outs << " (" << Target.nID << ")"; - - // Finish error message off and return it. - outs << std::ends; - acErrorBuffer[8095] = '\0'; - return acErrorBuffer; - } - - // keeps in scope for duration of the application - //SocketManager Socket::wsaManager; - - SocketManager::SocketManager() { - WSADATA wsaData; - WORD wVersionRequested = MAKEWORD(2, 0); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("SocketManager calling WSAStartup...\n"); - WSAStartup(wVersionRequested, &wsaData); - //dont throw exceptions here, this is a static initializacion - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Winsock initialized.\n"); - } - - SocketManager::~SocketManager() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("SocketManager calling WSACleanup...\n"); - WSACleanup(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Winsock cleanup complete.\n"); - } #else - typedef unsigned int UINT_PTR, *PUINT_PTR; - typedef UINT_PTR SOCKET; - #define INVALID_SOCKET (SOCKET)(~0) + typedef unsigned int UINT_PTR, *PUINT_PTR; + typedef UINT_PTR SOCKET; +#define INVALID_SOCKET (SOCKET)(~0) - //#define PLATFORM_SOCKET_TRY_AGAIN EAGAIN - //#define PLATFORM_SOCKET_INPROGRESS EINPROGRESS - //#define PLATFORM_SOCKET_INTERRUPTED EINTR + //#define PLATFORM_SOCKET_TRY_AGAIN EAGAIN + //#define PLATFORM_SOCKET_INPROGRESS EINPROGRESS + //#define PLATFORM_SOCKET_INTERRUPTED EINTR #endif -int Socket::getLastSocketError() { + int Socket::getLastSocketError() { #ifndef WIN32 - return errno; + return errno; #else - return WSAGetLastError(); + return WSAGetLastError(); #endif -} - -const char * Socket::getLastSocketErrorText(int *errNumber) { - int errId = (errNumber != NULL ? *errNumber : getLastSocketError()); -#ifndef WIN32 - return strerror(errId); -#else - return WSAGetLastErrorMessage("",errId); -#endif -} - -string Socket::getLastSocketErrorFormattedText(int *errNumber) { - int errId = (errNumber != NULL ? *errNumber : getLastSocketError()); - string msg = "(Error: " + intToStr(errId) + " - [" + string(getLastSocketErrorText(&errId)) +"])"; - return msg; -} - -// ===================================================== -// class Ip -// ===================================================== - -Ip::Ip(){ - bytes[0]= 0; - bytes[1]= 0; - bytes[2]= 0; - bytes[3]= 0; -} - -Ip::Ip(unsigned char byte0, unsigned char byte1, unsigned char byte2, unsigned char byte3){ - bytes[0]= byte0; - bytes[1]= byte1; - bytes[2]= byte2; - bytes[3]= byte3; -} - - -Ip::Ip(const string &ipString) { - size_t offset= 0; - int byteIndex= 0; - - if(ipString.empty() == false) { - for(byteIndex= 0; byteIndex<4; ++byteIndex){ - size_t dotPos= ipString.find_first_of('.', offset); - - bytes[byteIndex]= atoi(ipString.substr(offset, dotPos-offset).c_str()); - offset= dotPos+1; } - } -} -string Ip::getString() const{ - return intToStr(bytes[0]) + "." + intToStr(bytes[1]) + "." + intToStr(bytes[2]) + "." + intToStr(bytes[3]); -} + const char * Socket::getLastSocketErrorText(int *errNumber) { + int errId = (errNumber != NULL ? *errNumber : getLastSocketError()); +#ifndef WIN32 + return strerror(errId); +#else + return WSAGetLastErrorMessage("", errId); +#endif + } -// =============================================== -// class Socket -// =============================================== + string Socket::getLastSocketErrorFormattedText(int *errNumber) { + int errId = (errNumber != NULL ? *errNumber : getLastSocketError()); + string msg = "(Error: " + intToStr(errId) + " - [" + string(getLastSocketErrorText(&errId)) + "])"; + return msg; + } + + // ===================================================== + // class Ip + // ===================================================== + + Ip::Ip() { + bytes[0] = 0; + bytes[1] = 0; + bytes[2] = 0; + bytes[3] = 0; + } + + Ip::Ip(unsigned char byte0, unsigned char byte1, unsigned char byte2, unsigned char byte3) { + bytes[0] = byte0; + bytes[1] = byte1; + bytes[2] = byte2; + bytes[3] = byte3; + } + + + Ip::Ip(const string &ipString) { + size_t offset = 0; + int byteIndex = 0; + + if (ipString.empty() == false) { + for (byteIndex = 0; byteIndex < 4; ++byteIndex) { + size_t dotPos = ipString.find_first_of('.', offset); + + bytes[byteIndex] = atoi(ipString.substr(offset, dotPos - offset).c_str()); + offset = dotPos + 1; + } + } + } + + string Ip::getString() const { + return intToStr(bytes[0]) + "." + intToStr(bytes[1]) + "." + intToStr(bytes[2]) + "." + intToStr(bytes[3]); + } + + // =============================================== + // class Socket + // =============================================== #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(BSD) || defined(__APPLE__) || defined(__linux__) # define USE_GETIFADDRS 1 # include #endif -static uint32 SockAddrToUint32(struct in_addr * a) { - uint32 result = 0; + static uint32 SockAddrToUint32(struct in_addr * a) { + uint32 result = 0; - //printf("a [%p]\n",a); - if(a != NULL) { - result = ntohl(a->s_addr); - } + //printf("a [%p]\n",a); + if (a != NULL) { + result = ntohl(a->s_addr); + } - return result; -} + return result; + } -static uint32 SockAddrToUint32(struct sockaddr * a) { - uint32 result = 0; + static uint32 SockAddrToUint32(struct sockaddr * a) { + uint32 result = 0; - //printf("a [%p] family = %d\n",a,(a ? a->sa_family : -1)); - if(a != NULL && (a->sa_family == AF_INET || a->sa_family == AF_UNSPEC)) { - //result = SockAddrToUint32((((struct sockaddr_in *)a)->sin_addr.s_addr); - result = SockAddrToUint32(&((struct sockaddr_in *)a)->sin_addr); - } + //printf("a [%p] family = %d\n",a,(a ? a->sa_family : -1)); + if (a != NULL && (a->sa_family == AF_INET || a->sa_family == AF_UNSPEC)) { + //result = SockAddrToUint32((((struct sockaddr_in *)a)->sin_addr.s_addr); + result = SockAddrToUint32(&((struct sockaddr_in *)a)->sin_addr); + } - return result; -} + return result; + } -// convert a numeric IP address into its string representation -void Ip::Inet_NtoA(uint32 addr, char * ipbuf) -{ - sprintf(ipbuf, "%d.%d.%d.%d", (addr>>24)&0xFF, (addr>>16)&0xFF, (addr>>8)&0xFF, (addr>>0)&0xFF); -} + // convert a numeric IP address into its string representation + void Ip::Inet_NtoA(uint32 addr, char * ipbuf) { + sprintf(ipbuf, "%d.%d.%d.%d", (addr >> 24) & 0xFF, (addr >> 16) & 0xFF, (addr >> 8) & 0xFF, (addr >> 0) & 0xFF); + } #if defined(WIN32) -// convert a string represenation of an IP address into its numeric equivalent -static uint32 Inet_AtoN(const char * buf) -{ - // net_server inexplicably doesn't have this function; so I'll just fake it - uint32 ret = 0; - int shift = 24; // fill out the MSB first - bool startQuad = true; - while((shift >= 0)&&(*buf)) - { - if (startQuad) - { - unsigned char quad = (unsigned char) atoi(buf); - ret |= (((uint32)quad) << shift); - shift -= 8; - } - startQuad = (*buf == '.'); - buf++; - } - return ret; -} + // convert a string represenation of an IP address into its numeric equivalent + static uint32 Inet_AtoN(const char * buf) { + // net_server inexplicably doesn't have this function; so I'll just fake it + uint32 ret = 0; + int shift = 24; // fill out the MSB first + bool startQuad = true; + while ((shift >= 0) && (*buf)) { + if (startQuad) { + unsigned char quad = (unsigned char) atoi(buf); + ret |= (((uint32) quad) << shift); + shift -= 8; + } + startQuad = (*buf == '.'); + buf++; + } + return ret; + } #endif -/* -static void PrintNetworkInterfaceInfos() -{ + /* + static void PrintNetworkInterfaceInfos() + { + #if defined(USE_GETIFADDRS) + // BSD-style implementation + struct ifaddrs * ifap; + if (getifaddrs(&ifap) == 0) + { + struct ifaddrs * p = ifap; + while(p) + { + uint32 ifaAddr = SockAddrToUint32(p->ifa_addr); + uint32 maskAddr = SockAddrToUint32(p->ifa_netmask); + uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr); + if (ifaAddr > 0) + { + char ifaAddrStr[32]; Ip::Inet_NtoA(ifaAddr, ifaAddrStr); + char maskAddrStr[32]; Ip::Inet_NtoA(maskAddr, maskAddrStr); + char dstAddrStr[32]; Ip::Inet_NtoA(dstAddr, dstAddrStr); + printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", p->ifa_name, "unavailable", ifaAddrStr, maskAddrStr, dstAddrStr); + } + p = p->ifa_next; + } + freeifaddrs(ifap); + } + #elif defined(WIN32) + // Windows XP style implementation + + // Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx + // Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable() + // multiple times in order to deal with potential race conditions properly. + MIB_IPADDRTABLE * ipTable = NULL; + { + ULONG bufLen = 0; + for (int i=0; i<5; i++) + { + DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false); + if (ipRet == ERROR_INSUFFICIENT_BUFFER) + { + free(ipTable); // in case we had previously allocated it + ipTable = (MIB_IPADDRTABLE *) malloc(bufLen); + } + else if (ipRet == NO_ERROR) break; + else + { + free(ipTable); + ipTable = NULL; + break; + } + } + } + + if (ipTable) + { + // Try to get the Adapters-info table, so we can given useful names to the IP + // addresses we are returning. Gotta call GetAdaptersInfo() up to 5 times to handle + // the potential race condition between the size-query call and the get-data call. + // I love a well-designed API :^P + IP_ADAPTER_INFO * pAdapterInfo = NULL; + { + ULONG bufLen = 0; + for (int i=0; i<5; i++) + { + DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen); + if (apRet == ERROR_BUFFER_OVERFLOW) + { + free(pAdapterInfo); // in case we had previously allocated it + pAdapterInfo = (IP_ADAPTER_INFO *) malloc(bufLen); + } + else if (apRet == ERROR_SUCCESS) break; + else + { + free(pAdapterInfo); + pAdapterInfo = NULL; + break; + } + } + } + + for (DWORD i=0; idwNumEntries; i++) + { + const MIB_IPADDRROW & row = ipTable->table[i]; + + // Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it + const char * name = NULL; + const char * desc = NULL; + if (pAdapterInfo) + { + IP_ADAPTER_INFO * next = pAdapterInfo; + while((next)&&(name==NULL)) + { + IP_ADDR_STRING * ipAddr = &next->IpAddressList; + while(ipAddr) + { + if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr)) + { + name = next->AdapterName; + desc = next->Description; + break; + } + ipAddr = ipAddr->Next; + } + next = next->Next; + } + } + char buf[128]; + if (name == NULL) + { + snprintf(buf, 128,"unnamed-%i", i); + name = buf; + } + + uint32 ipAddr = ntohl(row.dwAddr); + uint32 netmask = ntohl(row.dwMask); + uint32 baddr = ipAddr & netmask; + if (row.dwBCastAddr) baddr |= ~netmask; + + char ifaAddrStr[32]; Ip::Inet_NtoA(ipAddr, ifaAddrStr); + char maskAddrStr[32]; Ip::Inet_NtoA(netmask, maskAddrStr); + char dstAddrStr[32]; Ip::Inet_NtoA(baddr, dstAddrStr); + printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", name, desc?desc:"unavailable", ifaAddrStr, maskAddrStr, dstAddrStr); + } + + free(pAdapterInfo); + free(ipTable); + } + #else + // Dunno what we're running on here! + # error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!" + #endif + } + */ + + string getNetworkInterfaceBroadcastAddress(string ipAddress) { + string broadCastAddress = ""; + #if defined(USE_GETIFADDRS) - // BSD-style implementation - struct ifaddrs * ifap; - if (getifaddrs(&ifap) == 0) - { - struct ifaddrs * p = ifap; - while(p) - { - uint32 ifaAddr = SockAddrToUint32(p->ifa_addr); - uint32 maskAddr = SockAddrToUint32(p->ifa_netmask); - uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr); - if (ifaAddr > 0) - { - char ifaAddrStr[32]; Ip::Inet_NtoA(ifaAddr, ifaAddrStr); - char maskAddrStr[32]; Ip::Inet_NtoA(maskAddr, maskAddrStr); - char dstAddrStr[32]; Ip::Inet_NtoA(dstAddr, dstAddrStr); - printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", p->ifa_name, "unavailable", ifaAddrStr, maskAddrStr, dstAddrStr); - } - p = p->ifa_next; - } - freeifaddrs(ifap); - } + // BSD-style implementation + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + struct ifaddrs * ifap; + if (getifaddrs(&ifap) == 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + struct ifaddrs * p = ifap; + while (p) { + uint32 ifaAddr = SockAddrToUint32(p->ifa_addr); + uint32 maskAddr = SockAddrToUint32(p->ifa_netmask); + uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr); + if (ifaAddr > 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + char ifaAddrStr[32]; Ip::Inet_NtoA(ifaAddr, ifaAddrStr); + char maskAddrStr[32]; Ip::Inet_NtoA(maskAddr, maskAddrStr); + char dstAddrStr[32]; Ip::Inet_NtoA(dstAddr, dstAddrStr); + //printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", p->ifa_name, "unavailable", ifaAddrStr, maskAddrStr, dstAddrStr); + if (strcmp(ifaAddrStr, ipAddress.c_str()) == 0) { + broadCastAddress = dstAddrStr; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] ifaAddrStr [%s], maskAddrStr [%s], dstAddrStr[%s], ipAddress [%s], broadCastAddress [%s]\n", __FILE__, __FUNCTION__, __LINE__, ifaAddrStr, maskAddrStr, dstAddrStr, ipAddress.c_str(), broadCastAddress.c_str()); + } + p = p->ifa_next; + } + freeifaddrs(ifap); + } #elif defined(WIN32) - // Windows XP style implementation + // Windows XP style implementation - // Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx - // Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable() - // multiple times in order to deal with potential race conditions properly. - MIB_IPADDRTABLE * ipTable = NULL; - { - ULONG bufLen = 0; - for (int i=0; i<5; i++) - { - DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false); - if (ipRet == ERROR_INSUFFICIENT_BUFFER) - { - free(ipTable); // in case we had previously allocated it - ipTable = (MIB_IPADDRTABLE *) malloc(bufLen); - } - else if (ipRet == NO_ERROR) break; - else - { - free(ipTable); - ipTable = NULL; - break; - } - } - } + // Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx + // Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable() + // multiple times in order to deal with potential race conditions properly. + PMIB_IPADDRTABLE ipTable = NULL; + // Before calling AddIPAddress we use GetIpAddrTable to get + // an adapter to which we can add the IP. + ipTable = (PMIB_IPADDRTABLE) malloc(sizeof(MIB_IPADDRTABLE)); + ipTable->dwNumEntries = 0; - if (ipTable) - { - // Try to get the Adapters-info table, so we can given useful names to the IP - // addresses we are returning. Gotta call GetAdaptersInfo() up to 5 times to handle - // the potential race condition between the size-query call and the get-data call. - // I love a well-designed API :^P - IP_ADAPTER_INFO * pAdapterInfo = NULL; - { - ULONG bufLen = 0; - for (int i=0; i<5; i++) - { - DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen); - if (apRet == ERROR_BUFFER_OVERFLOW) - { - free(pAdapterInfo); // in case we had previously allocated it - pAdapterInfo = (IP_ADAPTER_INFO *) malloc(bufLen); - } - else if (apRet == ERROR_SUCCESS) break; - else - { - free(pAdapterInfo); - pAdapterInfo = NULL; - break; - } - } - } + { + ULONG bufLen = 0; + for (int i = 0; i < 5; i++) { - for (DWORD i=0; idwNumEntries; i++) - { - const MIB_IPADDRROW & row = ipTable->table[i]; - - // Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it - const char * name = NULL; - const char * desc = NULL; - if (pAdapterInfo) - { - IP_ADAPTER_INFO * next = pAdapterInfo; - while((next)&&(name==NULL)) - { - IP_ADDR_STRING * ipAddr = &next->IpAddressList; - while(ipAddr) - { - if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr)) - { - name = next->AdapterName; - desc = next->Description; - break; - } - ipAddr = ipAddr->Next; - } - next = next->Next; - } - } - char buf[128]; - if (name == NULL) - { - snprintf(buf, 128,"unnamed-%i", i); - name = buf; - } - - uint32 ipAddr = ntohl(row.dwAddr); - uint32 netmask = ntohl(row.dwMask); - uint32 baddr = ipAddr & netmask; - if (row.dwBCastAddr) baddr |= ~netmask; - - char ifaAddrStr[32]; Ip::Inet_NtoA(ipAddr, ifaAddrStr); - char maskAddrStr[32]; Ip::Inet_NtoA(netmask, maskAddrStr); - char dstAddrStr[32]; Ip::Inet_NtoA(baddr, dstAddrStr); - printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", name, desc?desc:"unavailable", ifaAddrStr, maskAddrStr, dstAddrStr); - } - - free(pAdapterInfo); - free(ipTable); - } -#else - // Dunno what we're running on here! -# error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!" -#endif -} -*/ - -string getNetworkInterfaceBroadcastAddress(string ipAddress) -{ - string broadCastAddress = ""; - -#if defined(USE_GETIFADDRS) - // BSD-style implementation - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - struct ifaddrs * ifap; - if (getifaddrs(&ifap) == 0) - { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - struct ifaddrs * p = ifap; - while(p) - { - uint32 ifaAddr = SockAddrToUint32(p->ifa_addr); - uint32 maskAddr = SockAddrToUint32(p->ifa_netmask); - uint32 dstAddr = SockAddrToUint32(p->ifa_dstaddr); - if (ifaAddr > 0) - { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - char ifaAddrStr[32]; Ip::Inet_NtoA(ifaAddr, ifaAddrStr); - char maskAddrStr[32]; Ip::Inet_NtoA(maskAddr, maskAddrStr); - char dstAddrStr[32]; Ip::Inet_NtoA(dstAddr, dstAddrStr); - //printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", p->ifa_name, "unavailable", ifaAddrStr, maskAddrStr, dstAddrStr); - if(strcmp(ifaAddrStr,ipAddress.c_str()) == 0) { - broadCastAddress = dstAddrStr; + DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false); + if (ipRet == ERROR_INSUFFICIENT_BUFFER) { + free(ipTable); // in case we had previously allocated it + ipTable = (MIB_IPADDRTABLE *) malloc(bufLen); + ipTable->dwNumEntries = 0; + } else if (ipRet == NO_ERROR) { + break; + } else { + free(ipTable); + ipTable = NULL; + break; + } + } } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ifaAddrStr [%s], maskAddrStr [%s], dstAddrStr[%s], ipAddress [%s], broadCastAddress [%s]\n",__FILE__,__FUNCTION__,__LINE__,ifaAddrStr,maskAddrStr,dstAddrStr,ipAddress.c_str(),broadCastAddress.c_str()); - } - p = p->ifa_next; - } - freeifaddrs(ifap); - } -#elif defined(WIN32) - // Windows XP style implementation + if (ipTable) { + // Try to get the Adapters-info table, so we can given useful names to the IP + // addresses we are returning. Gotta call GetAdaptersInfo() up to 5 times to handle + // the potential race condition between the size-query call and the get-data call. + // I love a well-designed API :^P + IP_ADAPTER_INFO * pAdapterInfo = NULL; + { + ULONG bufLen = 0; + for (int i = 0; i < 5; i++) { + DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen); + if (apRet == ERROR_BUFFER_OVERFLOW) { + free(pAdapterInfo); // in case we had previously allocated it + pAdapterInfo = (IP_ADAPTER_INFO *) malloc(bufLen); + } else if (apRet == ERROR_SUCCESS) { + break; + } else { + free(pAdapterInfo); + pAdapterInfo = NULL; + break; + } + } + } - // Adapted from example code at http://msdn2.microsoft.com/en-us/library/aa365917.aspx - // Now get Windows' IPv4 addresses table. Once again, we gotta call GetIpAddrTable() - // multiple times in order to deal with potential race conditions properly. - PMIB_IPADDRTABLE ipTable = NULL; - // Before calling AddIPAddress we use GetIpAddrTable to get - // an adapter to which we can add the IP. - ipTable = (PMIB_IPADDRTABLE) malloc(sizeof (MIB_IPADDRTABLE)); - ipTable->dwNumEntries = 0; + for (DWORD i = 0; i < ipTable->dwNumEntries; i++) { + const MIB_IPADDRROW & row = ipTable->table[i]; - { - ULONG bufLen = 0; - for (int i = 0; i < 5; i++) { + // Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it + const char * name = NULL; + //const char * desc = NULL; + if (pAdapterInfo) { + IP_ADAPTER_INFO * next = pAdapterInfo; + while ((next) && (name == NULL)) { + IP_ADDR_STRING * ipAddr = &next->IpAddressList; + while (ipAddr) { + if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr)) { + name = next->AdapterName; + //desc = next->Description; + break; + } + ipAddr = ipAddr->Next; + } + next = next->Next; + } + } + if (name == NULL) { + name = ""; + } - DWORD ipRet = GetIpAddrTable(ipTable, &bufLen, false); - if (ipRet == ERROR_INSUFFICIENT_BUFFER) { - free(ipTable); // in case we had previously allocated it - ipTable = (MIB_IPADDRTABLE *) malloc(bufLen); - ipTable->dwNumEntries = 0; - } - else if(ipRet == NO_ERROR) { - break; - } - else { - free(ipTable); - ipTable = NULL; - break; - } - } - } + uint32 ipAddr = ntohl(row.dwAddr); + uint32 netmask = ntohl(row.dwMask); + uint32 baddr = ipAddr & netmask; + if (row.dwBCastAddr) { + baddr |= ~netmask; + } - if (ipTable) { - // Try to get the Adapters-info table, so we can given useful names to the IP - // addresses we are returning. Gotta call GetAdaptersInfo() up to 5 times to handle - // the potential race condition between the size-query call and the get-data call. - // I love a well-designed API :^P - IP_ADAPTER_INFO * pAdapterInfo = NULL; - { - ULONG bufLen = 0; - for (int i = 0; i < 5; i++) { - DWORD apRet = GetAdaptersInfo(pAdapterInfo, &bufLen); - if (apRet == ERROR_BUFFER_OVERFLOW) { - free(pAdapterInfo); // in case we had previously allocated it - pAdapterInfo = (IP_ADAPTER_INFO *) malloc(bufLen); - } - else if(apRet == ERROR_SUCCESS) { - break; - } - else { - free(pAdapterInfo); - pAdapterInfo = NULL; - break; - } - } - } + char ifaAddrStr[32]; + Ip::Inet_NtoA(ipAddr, ifaAddrStr); + char maskAddrStr[32]; + Ip::Inet_NtoA(netmask, maskAddrStr); + char dstAddrStr[32]; + Ip::Inet_NtoA(baddr, dstAddrStr); + //printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", name, desc?desc:"unavailable", ifaAddrStr, maskAddrStr, dstAddrStr); + if (strcmp(ifaAddrStr, ipAddress.c_str()) == 0) { + broadCastAddress = dstAddrStr; + } + } - for (DWORD i = 0; i < ipTable->dwNumEntries; i++) { - const MIB_IPADDRROW & row = ipTable->table[i]; - - // Now lookup the appropriate adaptor-name in the pAdaptorInfos, if we can find it - const char * name = NULL; - //const char * desc = NULL; - if (pAdapterInfo) { - IP_ADAPTER_INFO * next = pAdapterInfo; - while((next)&&(name==NULL)) { - IP_ADDR_STRING * ipAddr = &next->IpAddressList; - while(ipAddr) { - if (Inet_AtoN(ipAddr->IpAddress.String) == ntohl(row.dwAddr)) { - name = next->AdapterName; - //desc = next->Description; - break; - } - ipAddr = ipAddr->Next; - } - next = next->Next; - } - } - if (name == NULL) { - name = ""; - } - - uint32 ipAddr = ntohl(row.dwAddr); - uint32 netmask = ntohl(row.dwMask); - uint32 baddr = ipAddr & netmask; - if (row.dwBCastAddr) { - baddr |= ~netmask; - } - - char ifaAddrStr[32]; - Ip::Inet_NtoA(ipAddr, ifaAddrStr); - char maskAddrStr[32]; - Ip::Inet_NtoA(netmask, maskAddrStr); - char dstAddrStr[32]; - Ip::Inet_NtoA(baddr, dstAddrStr); - //printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", name, desc?desc:"unavailable", ifaAddrStr, maskAddrStr, dstAddrStr); - if(strcmp(ifaAddrStr,ipAddress.c_str()) == 0) { - broadCastAddress = dstAddrStr; - } - } - - if(pAdapterInfo) free(pAdapterInfo); - if(ipTable) free(ipTable); - } + if (pAdapterInfo) free(pAdapterInfo); + if (ipTable) free(ipTable); + } #else - // Dunno what we're running on here! + // Dunno what we're running on here! # error "Don't know how to implement PrintNetworkInterfaceInfos() on this OS!" #endif - return broadCastAddress; -} - -uint32 Socket::getConnectedIPAddress(string IP) { - sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - - addr.sin_family= AF_INET; - if(IP == "") { - IP = connectedIpAddress; - } - addr.sin_addr.s_addr= inet_addr(IP.c_str()); - //addr.sin_port= htons(port); - - return SockAddrToUint32((struct sockaddr *)&addr); -} - -std::vector Socket::getLocalIPAddressList() { - std::vector ipList; - /* get my host name */ - char myhostname[101]=""; - gethostname(myhostname,100); - - struct hostent* myhostent = gethostbyname(myhostname); - if(myhostent) { - // get all host IP addresses (Except for loopback) - char myhostaddr[101] = ""; - for(int ipIdx = 0; myhostent->h_addr_list[ipIdx] != NULL; ++ipIdx) { - Ip::Inet_NtoA(SockAddrToUint32((struct in_addr *)myhostent->h_addr_list[ipIdx]), myhostaddr); - - //printf("ipIdx = %d [%s]\n",ipIdx,myhostaddr); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] myhostaddr = [%s]\n",__FILE__,__FUNCTION__,__LINE__,myhostaddr); - - if(strlen(myhostaddr) > 0 && - strncmp(myhostaddr,"127.",4) != 0 && - strncmp(myhostaddr,"0.",2) != 0) { - ipList.push_back(myhostaddr); - } + return broadCastAddress; } - } - Socket::getLocalIPAddressListForPlatform(ipList); - return ipList; -} + uint32 Socket::getConnectedIPAddress(string IP) { + sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + + addr.sin_family = AF_INET; + if (IP == "") { + IP = connectedIpAddress; + } + addr.sin_addr.s_addr = inet_addr(IP.c_str()); + //addr.sin_port= htons(port); + + return SockAddrToUint32((struct sockaddr *)&addr); + } + + std::vector Socket::getLocalIPAddressList() { + std::vector ipList; + /* get my host name */ + char myhostname[101] = ""; + gethostname(myhostname, 100); + + struct hostent* myhostent = gethostbyname(myhostname); + if (myhostent) { + // get all host IP addresses (Except for loopback) + char myhostaddr[101] = ""; + for (int ipIdx = 0; myhostent->h_addr_list[ipIdx] != NULL; ++ipIdx) { + Ip::Inet_NtoA(SockAddrToUint32((struct in_addr *)myhostent->h_addr_list[ipIdx]), myhostaddr); + + //printf("ipIdx = %d [%s]\n",ipIdx,myhostaddr); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] myhostaddr = [%s]\n", __FILE__, __FUNCTION__, __LINE__, myhostaddr); + + if (strlen(myhostaddr) > 0 && + strncmp(myhostaddr, "127.", 4) != 0 && + strncmp(myhostaddr, "0.", 2) != 0) { + ipList.push_back(myhostaddr); + } + } + } + + Socket::getLocalIPAddressListForPlatform(ipList); + return ipList; + } #ifndef WIN32 -void Socket::getLocalIPAddressListForPlatform(std::vector &ipList) { - // Now check all linux network devices - struct ifaddrs *ifap = NULL; - getifaddrs(&ifap); - for(struct ifaddrs *ifa = ifap; ifa; ifa = ifa->ifa_next) { - if (ifa->ifa_addr->sa_family == AF_INET) { - struct sockaddr_in *sa = (struct sockaddr_in *) ifa->ifa_addr; - char *addr = inet_ntoa(sa->sin_addr); - //printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, addr); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Interface: [%s] address: [%s]\n",__FILE__,__FUNCTION__,__LINE__,ifa->ifa_name,addr); + void Socket::getLocalIPAddressListForPlatform(std::vector &ipList) { + // Now check all linux network devices + struct ifaddrs *ifap = NULL; + getifaddrs(&ifap); + for (struct ifaddrs *ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr->sa_family == AF_INET) { + struct sockaddr_in *sa = (struct sockaddr_in *) ifa->ifa_addr; + char *addr = inet_ntoa(sa->sin_addr); + //printf("Interface: %s\tAddress: %s\n", ifa->ifa_name, addr); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] Interface: [%s] address: [%s]\n", __FILE__, __FUNCTION__, __LINE__, ifa->ifa_name, addr); + } + if (strlen(addr) > 0 && + strncmp(addr, "127.", 4) != 0 && + strncmp(addr, "0.", 2) != 0) { + if (std::find(ipList.begin(), ipList.end(), addr) == ipList.end()) { + ipList.push_back(addr); + } + } + } } - if(strlen(addr) > 0 && - strncmp(addr,"127.",4) != 0 && - strncmp(addr,"0.",2) != 0) { - if(std::find(ipList.begin(),ipList.end(),addr) == ipList.end()) { - ipList.push_back(addr); - } - } - } - } - freeifaddrs(ifap); + freeifaddrs(ifap); - if(Socket::intfTypes.empty()) { - Socket::intfTypes.push_back("lo"); - Socket::intfTypes.push_back("eth"); - Socket::intfTypes.push_back("wlan"); - Socket::intfTypes.push_back("vlan"); - Socket::intfTypes.push_back("vboxnet"); - Socket::intfTypes.push_back("br-lan"); - Socket::intfTypes.push_back("br-gest"); - Socket::intfTypes.push_back("enp0s"); - Socket::intfTypes.push_back("enp1s"); - Socket::intfTypes.push_back("enp2s"); - Socket::intfTypes.push_back("enp3s"); - Socket::intfTypes.push_back("enp4s"); - Socket::intfTypes.push_back("enp5s"); - Socket::intfTypes.push_back("enp6s"); - Socket::intfTypes.push_back("enp7s"); - Socket::intfTypes.push_back("enp8s"); - Socket::intfTypes.push_back("enp9s"); - } - - for(unsigned int intfIdx = 0; intfIdx < Socket::intfTypes.size(); intfIdx++) { - string intfName = Socket::intfTypes[intfIdx]; - for(int idx = 0; idx < 10; ++idx) { - PLATFORM_SOCKET fd = socket(AF_INET, SOCK_DGRAM, 0); - /* I want to get an IPv4 IP address */ - struct ifreq ifr; - struct ifreq ifrA; - ifr.ifr_addr.sa_family = AF_INET; - ifrA.ifr_addr.sa_family = AF_INET; - /* I want IP address attached to "eth0" */ - char szBuf[100]=""; - snprintf(szBuf,100,"%s%d",intfName.c_str(),idx); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Trying NIC named [%s]\n",__FILE__,__FUNCTION__,__LINE__,szBuf); - //printf("In [%s::%s Line: %d] Trying NIC named [%s]\n",__FILE__,__FUNCTION__,__LINE__,szBuf); - - int maxIfNameLength = std::min((int)strlen(szBuf),IFNAMSIZ-1); - strncpy(ifr.ifr_name, szBuf, maxIfNameLength); - ifr.ifr_name[maxIfNameLength] = '\0'; - strncpy(ifrA.ifr_name, szBuf, maxIfNameLength); - ifrA.ifr_name[maxIfNameLength] = '\0'; - - int result_ifaddrr = ioctl(fd, SIOCGIFADDR, &ifr); - ioctl(fd, SIOCGIFFLAGS, &ifrA); - if(fd >= 0) { - close(fd); + if (Socket::intfTypes.empty()) { + Socket::intfTypes.push_back("lo"); + Socket::intfTypes.push_back("eth"); + Socket::intfTypes.push_back("wlan"); + Socket::intfTypes.push_back("vlan"); + Socket::intfTypes.push_back("vboxnet"); + Socket::intfTypes.push_back("br-lan"); + Socket::intfTypes.push_back("br-gest"); + Socket::intfTypes.push_back("enp0s"); + Socket::intfTypes.push_back("enp1s"); + Socket::intfTypes.push_back("enp2s"); + Socket::intfTypes.push_back("enp3s"); + Socket::intfTypes.push_back("enp4s"); + Socket::intfTypes.push_back("enp5s"); + Socket::intfTypes.push_back("enp6s"); + Socket::intfTypes.push_back("enp7s"); + Socket::intfTypes.push_back("enp8s"); + Socket::intfTypes.push_back("enp9s"); } - if(result_ifaddrr >= 0) { - struct sockaddr_in *pSockAddr = (struct sockaddr_in *)&ifr.ifr_addr; - if(pSockAddr != NULL) { - char myhostaddr[101] = ""; - Ip::Inet_NtoA(SockAddrToUint32(&pSockAddr->sin_addr), myhostaddr); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] szBuf [%s], myhostaddr = [%s], ifr.ifr_flags = %d, ifrA.ifr_flags = %d, ifr.ifr_name [%s]\n",__FILE__,__FUNCTION__,__LINE__,szBuf,myhostaddr,ifr.ifr_flags,ifrA.ifr_flags,ifr.ifr_name); - // Now only include interfaces that are both UP and running - if( (ifrA.ifr_flags & IFF_UP) == IFF_UP && - (ifrA.ifr_flags & IFF_RUNNING) == IFF_RUNNING) { - if( strlen(myhostaddr) > 0 && - strncmp(myhostaddr,"127.",4) != 0 && - strncmp(myhostaddr,"0.",2) != 0) { - if(std::find(ipList.begin(),ipList.end(),myhostaddr) == ipList.end()) { - ipList.push_back(myhostaddr); + + for (unsigned int intfIdx = 0; intfIdx < Socket::intfTypes.size(); intfIdx++) { + string intfName = Socket::intfTypes[intfIdx]; + for (int idx = 0; idx < 10; ++idx) { + PLATFORM_SOCKET fd = socket(AF_INET, SOCK_DGRAM, 0); + /* I want to get an IPv4 IP address */ + struct ifreq ifr; + struct ifreq ifrA; + ifr.ifr_addr.sa_family = AF_INET; + ifrA.ifr_addr.sa_family = AF_INET; + /* I want IP address attached to "eth0" */ + char szBuf[100] = ""; + snprintf(szBuf, 100, "%s%d", intfName.c_str(), idx); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] Trying NIC named [%s]\n", __FILE__, __FUNCTION__, __LINE__, szBuf); + //printf("In [%s::%s Line: %d] Trying NIC named [%s]\n",__FILE__,__FUNCTION__,__LINE__,szBuf); + + int maxIfNameLength = std::min((int) strlen(szBuf), IFNAMSIZ - 1); + strncpy(ifr.ifr_name, szBuf, maxIfNameLength); + ifr.ifr_name[maxIfNameLength] = '\0'; + strncpy(ifrA.ifr_name, szBuf, maxIfNameLength); + ifrA.ifr_name[maxIfNameLength] = '\0'; + + int result_ifaddrr = ioctl(fd, SIOCGIFADDR, &ifr); + ioctl(fd, SIOCGIFFLAGS, &ifrA); + if (fd >= 0) { + close(fd); + } + if (result_ifaddrr >= 0) { + struct sockaddr_in *pSockAddr = (struct sockaddr_in *)&ifr.ifr_addr; + if (pSockAddr != NULL) { + char myhostaddr[101] = ""; + Ip::Inet_NtoA(SockAddrToUint32(&pSockAddr->sin_addr), myhostaddr); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] szBuf [%s], myhostaddr = [%s], ifr.ifr_flags = %d, ifrA.ifr_flags = %d, ifr.ifr_name [%s]\n", __FILE__, __FUNCTION__, __LINE__, szBuf, myhostaddr, ifr.ifr_flags, ifrA.ifr_flags, ifr.ifr_name); + // Now only include interfaces that are both UP and running + if ((ifrA.ifr_flags & IFF_UP) == IFF_UP && + (ifrA.ifr_flags & IFF_RUNNING) == IFF_RUNNING) { + if (strlen(myhostaddr) > 0 && + strncmp(myhostaddr, "127.", 4) != 0 && + strncmp(myhostaddr, "0.", 2) != 0) { + if (std::find(ipList.begin(), ipList.end(), myhostaddr) == ipList.end()) { + ipList.push_back(myhostaddr); + } + } } } } } } } - } -} #endif #ifdef WIN32 -void Socket::getLocalIPAddressListForPlatform(std::vector &ipList) { - ULONG outBufLen = 0; - GetAdaptersAddresses(AF_INET, 0, NULL, NULL, &outBufLen); - PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen); - GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST, NULL, pAddresses, &outBufLen); - PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL; - PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; - LPSOCKADDR addr = NULL; - pCurrAddresses = pAddresses; - //char buff[100]; - DWORD bufflen=100; - while (pCurrAddresses) { - if (pCurrAddresses->OperStatus != IfOperStatusUp) { - pCurrAddresses = pCurrAddresses->Next; - continue; - } - pUnicast = pCurrAddresses->FirstUnicastAddress; - while (pUnicast) { - addr = pUnicast->Address.lpSockaddr; - if (addr->sa_family == AF_INET && pCurrAddresses->IfType != MIB_IF_TYPE_LOOPBACK) { - sockaddr_in *sa_in = (sockaddr_in *)addr; - char *strIP = ::inet_ntoa((sa_in->sin_addr)); - //printf("\tIPV4:%s\n", strIP); - if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] strIP [%s]\n", __FILE__, __FUNCTION__, __LINE__, strIP); + void Socket::getLocalIPAddressListForPlatform(std::vector &ipList) { + ULONG outBufLen = 0; + GetAdaptersAddresses(AF_INET, 0, NULL, NULL, &outBufLen); + PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES*) malloc(outBufLen); + GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_ANYCAST, NULL, pAddresses, &outBufLen); + PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL; + PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL; + LPSOCKADDR addr = NULL; + pCurrAddresses = pAddresses; + //char buff[100]; + DWORD bufflen = 100; + while (pCurrAddresses) { + if (pCurrAddresses->OperStatus != IfOperStatusUp) { + pCurrAddresses = pCurrAddresses->Next; + continue; } - if( strlen(strIP) > 0 && - strncmp(strIP,"127.",4) != 0 && - strncmp(strIP,"0.",2) != 0) { - if(std::find(ipList.begin(),ipList.end(),strIP) == ipList.end()) { - ipList.push_back(strIP); + pUnicast = pCurrAddresses->FirstUnicastAddress; + while (pUnicast) { + addr = pUnicast->Address.lpSockaddr; + if (addr->sa_family == AF_INET && pCurrAddresses->IfType != MIB_IF_TYPE_LOOPBACK) { + sockaddr_in *sa_in = (sockaddr_in *) addr; + char *strIP = ::inet_ntoa((sa_in->sin_addr)); + //printf("\tIPV4:%s\n", strIP); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] strIP [%s]\n", __FILE__, __FUNCTION__, __LINE__, strIP); + } + if (strlen(strIP) > 0 && + strncmp(strIP, "127.", 4) != 0 && + strncmp(strIP, "0.", 2) != 0) { + if (std::find(ipList.begin(), ipList.end(), strIP) == ipList.end()) { + ipList.push_back(strIP); + } + } + } + pUnicast = pUnicast->Next; + } + pCurrAddresses = pCurrAddresses->Next; + } + free(pAddresses); + } +#endif + + + bool Socket::isSocketValid() const { + return Socket::isSocketValid(&sock); + } + + bool Socket::isSocketValid(const PLATFORM_SOCKET *validateSocket) { +#ifdef WIN32 + if (validateSocket == NULL || (*validateSocket) == 0) { + return false; + } else { + return (*validateSocket != INVALID_SOCKET); + } +#else + if (validateSocket == NULL) { + return false; + } else { + return (*validateSocket > 0); + } +#endif + } + + Socket::Socket(PLATFORM_SOCKET sock) { + dataSynchAccessorRead = new Mutex(CODE_AT_LINE); + dataSynchAccessorWrite = new Mutex(CODE_AT_LINE); + inSocketDestructorSynchAccessor = new Mutex(CODE_AT_LINE); + lastSocketError = 0; + + MutexSafeWrapper safeMutexSocketDestructorFlag(inSocketDestructorSynchAccessor, CODE_AT_LINE); + inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); + this->inSocketDestructor = false; + lastThreadedPing = 0; + lastDebugEvent = 0; + //safeMutexSocketDestructorFlag.ReleaseLock(); + + //this->pingThread = NULL; + //pingThreadAccessor.setOwnerId(CODE_AT_LINE); + dataSynchAccessorRead->setOwnerId(CODE_AT_LINE); + dataSynchAccessorWrite->setOwnerId(CODE_AT_LINE); + + this->sock = sock; + this->isSocketBlocking = true; + this->connectedIpAddress = ""; + } + + Socket::Socket() { + dataSynchAccessorRead = new Mutex(CODE_AT_LINE); + dataSynchAccessorWrite = new Mutex(CODE_AT_LINE); + inSocketDestructorSynchAccessor = new Mutex(CODE_AT_LINE); + lastSocketError = 0; + lastDebugEvent = 0; + lastThreadedPing = 0; + + MutexSafeWrapper safeMutexSocketDestructorFlag(inSocketDestructorSynchAccessor, CODE_AT_LINE); + inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); + this->inSocketDestructor = false; + //safeMutexSocketDestructorFlag.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //this->pingThread = NULL; + + this->connectedIpAddress = ""; + + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (isSocketValid() == false) { + throwException("Error creating socket"); + } + + this->isSocketBlocking = true; + +#ifdef __APPLE__ + int set = 1; + setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (void *) &set, sizeof(int)); +#endif + + /* Disable the Nagle (TCP No Delay) algorithm */ + if (Socket::disableNagle == true) { + int flag = 1; + int ret = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag)); + if (ret == -1) { + printf("Couldn't setsockopt(TCP_NODELAY)\n"); + } + } + + if (Socket::DEFAULT_SOCKET_SENDBUF_SIZE >= 0) { + int bufsize = 0; + socklen_t optlen = sizeof(bufsize); + + int ret = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *) &bufsize, &optlen); + printf("Original setsockopt(SO_SNDBUF) = [%d] new will be [%d] ret = %d\n", bufsize, Socket::DEFAULT_SOCKET_SENDBUF_SIZE, ret); + + ret = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *) &Socket::DEFAULT_SOCKET_SENDBUF_SIZE, sizeof(int)); + if (ret == -1) { + printf("Couldn't setsockopt(SO_SNDBUF) [%d]\n", Socket::DEFAULT_SOCKET_SENDBUF_SIZE); + } + } + + if (Socket::DEFAULT_SOCKET_RECVBUF_SIZE >= 0) { + int bufsize = 0; + socklen_t optlen = sizeof(bufsize); + + int ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *) &bufsize, &optlen); + printf("Original setsockopt(SO_RCVBUF) = [%d] new will be [%d] ret = %d\n", bufsize, Socket::DEFAULT_SOCKET_RECVBUF_SIZE, ret); + + ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *) &Socket::DEFAULT_SOCKET_RECVBUF_SIZE, sizeof(int)); + if (ret == -1) { + printf("Couldn't setsockopt(SO_RCVBUF) [%d]\n", Socket::DEFAULT_SOCKET_RECVBUF_SIZE); + } + } + + } + + float Socket::getThreadedPingMS(std::string host) { + float result = -1; + /* + if(pingThread == NULL) { + lastThreadedPing = 0; + pingThread = new SimpleTaskThread(this,0,50); + pingThread->setUniqueID(__FILE__ + "_" + __FUNCTION); + pingThread->start(); + } + + if(pingCache.find(host) == pingCache.end()) { + MutexSafeWrapper safeMutex(&pingThreadAccessor); + safeMutex.ReleaseLock(); + result = getAveragePingMS(host, 1); + pingCache[host]=result; + } + else { + MutexSafeWrapper safeMutex(&pingThreadAccessor); + result = pingCache[host]; + safeMutex.ReleaseLock(); + } + */ + return result; + } + + /* + void Socket::simpleTask(BaseThread *callingThread) { + // update ping times every x seconds + const int pingFrequencySeconds = 2; + if(difftime(time(NULL),lastThreadedPing) < pingFrequencySeconds) { + return; + } + lastThreadedPing = time(NULL); + + //printf("Pinging hosts...\n"); + + for(std::map::iterator iterMap = pingCache.begin(); + iterMap != pingCache.end(); iterMap++) { + MutexSafeWrapper safeMutex(&pingThreadAccessor,CODE_AT_LINE); + iterMap->second = getAveragePingMS(iterMap->first, 1); + safeMutex.ReleaseLock(); + } + } + */ + + Socket::~Socket() { + MutexSafeWrapper safeMutexSocketDestructorFlag(inSocketDestructorSynchAccessor, CODE_AT_LINE); + if (this->inSocketDestructor == true) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] this->inSocketDestructor == true\n", __FILE__, __FUNCTION__, __LINE__); + return; + } + inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); + this->inSocketDestructor = true; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] START closing socket = %d...\n", __FILE__, __FUNCTION__, sock); + + //safeMutexSocketDestructorFlag.ReleaseLock(); + + disconnectSocket(); + + // Allow other callers with a lock on the mutexes to let them go + for (time_t elapsed = time(NULL); + (dataSynchAccessorRead->getRefCount() > 0 || + dataSynchAccessorWrite->getRefCount() > 0) && + difftime((long int) time(NULL), elapsed) <= 2;) { + printf("Waiting in socket destructor\n"); + //sleep(0); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] END closing socket = %d...\n", __FILE__, __FUNCTION__, sock); + + //delete pingThread; + //pingThread = NULL; + safeMutexSocketDestructorFlag.ReleaseLock(); + + delete dataSynchAccessorRead; + dataSynchAccessorRead = NULL; + delete dataSynchAccessorWrite; + dataSynchAccessorWrite = NULL; + delete inSocketDestructorSynchAccessor; + inSocketDestructorSynchAccessor = NULL; + } + + void Socket::disconnectSocket() { + //printf("Socket disconnecting sock = %d\n",sock); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] START closing socket = %d...\n", __FILE__, __FUNCTION__, sock); + + if (isSocketValid() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] calling shutdown and close for socket = %d...\n", __FILE__, __FUNCTION__, sock); + + MutexSafeWrapper safeMutex(dataSynchAccessorRead, CODE_AT_LINE); + MutexSafeWrapper safeMutex1(dataSynchAccessorWrite, CODE_AT_LINE); + + if (isSocketValid() == true) { + ::shutdown(sock, 2); +#ifndef WIN32 + ::close(sock); + sock = -1; +#else + ::closesocket(sock); + sock = INVALID_SOCKET; +#endif + } + safeMutex.ReleaseLock(); + safeMutex1.ReleaseLock(); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] END closing socket = %d...\n", __FILE__, __FUNCTION__, sock); + } + + // Int lookup is socket fd while bool result is whether or not that socket was signalled for reading + bool Socket::hasDataToRead(std::map &socketTriggeredList) { + bool bResult = false; + + if (socketTriggeredList.empty() == false) { + /* Watch stdin (fd 0) to see when it has input. */ + fd_set rfds; + FD_ZERO(&rfds); + + string socketDebugList = ""; + PLATFORM_SOCKET imaxsocket = 0; + for (std::map::iterator itermap = socketTriggeredList.begin(); + itermap != socketTriggeredList.end(); ++itermap) { + PLATFORM_SOCKET socket = itermap->first; + if (Socket::isSocketValid(&socket) == true) { + FD_SET(socket, &rfds); + imaxsocket = max(socket, imaxsocket); + + if (socketDebugList != "") { + socketDebugList += ","; + } + socketDebugList += intToStr(socket); + } + } + + if (imaxsocket > 0) { + /* Wait up to 0 seconds. */ + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 0; + + + int retval = 0; + { + //MutexSafeWrapper safeMutex(&dataSynchAccessor); + retval = select((int) imaxsocket + 1, &rfds, NULL, NULL, &tv); + } + if (retval < 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s, socketDebugList [%s]\n", __FILE__, __FUNCTION__, __LINE__, retval, getLastSocketErrorFormattedText().c_str(), socketDebugList.c_str()); + printf("In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s\n", __FILE__, __FUNCTION__, __LINE__, retval, getLastSocketErrorFormattedText().c_str()); + } else if (retval) { + bResult = true; + + for (std::map::iterator itermap = socketTriggeredList.begin(); + itermap != socketTriggeredList.end(); ++itermap) { + PLATFORM_SOCKET socket = itermap->first; + if (FD_ISSET(socket, &rfds)) { + itermap->second = true; + } else { + itermap->second = false; + } + } } } } - pUnicast = pUnicast->Next; + + return bResult; } - pCurrAddresses = pCurrAddresses->Next; - } - free(pAddresses); -} -#endif - -bool Socket::isSocketValid() const { - return Socket::isSocketValid(&sock); -} - -bool Socket::isSocketValid(const PLATFORM_SOCKET *validateSocket) { -#ifdef WIN32 - if(validateSocket == NULL || (*validateSocket) == 0) { - return false; - } - else { - return (*validateSocket != INVALID_SOCKET); - } -#else - if(validateSocket == NULL) { - return false; - } - else { - return (*validateSocket > 0); - } -#endif -} - -Socket::Socket(PLATFORM_SOCKET sock) { - dataSynchAccessorRead = new Mutex(CODE_AT_LINE); - dataSynchAccessorWrite = new Mutex(CODE_AT_LINE); - inSocketDestructorSynchAccessor = new Mutex(CODE_AT_LINE); - lastSocketError = 0; - - MutexSafeWrapper safeMutexSocketDestructorFlag(inSocketDestructorSynchAccessor,CODE_AT_LINE); - inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); - this->inSocketDestructor = false; - lastThreadedPing = 0; - lastDebugEvent = 0; - //safeMutexSocketDestructorFlag.ReleaseLock(); - - //this->pingThread = NULL; - //pingThreadAccessor.setOwnerId(CODE_AT_LINE); - dataSynchAccessorRead->setOwnerId(CODE_AT_LINE); - dataSynchAccessorWrite->setOwnerId(CODE_AT_LINE); - - this->sock= sock; - this->isSocketBlocking = true; - this->connectedIpAddress = ""; -} - -Socket::Socket() { - dataSynchAccessorRead = new Mutex(CODE_AT_LINE); - dataSynchAccessorWrite = new Mutex(CODE_AT_LINE); - inSocketDestructorSynchAccessor = new Mutex(CODE_AT_LINE); - lastSocketError = 0; - lastDebugEvent = 0; - lastThreadedPing = 0; - - MutexSafeWrapper safeMutexSocketDestructorFlag(inSocketDestructorSynchAccessor,CODE_AT_LINE); - inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); - this->inSocketDestructor = false; - //safeMutexSocketDestructorFlag.ReleaseLock(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //this->pingThread = NULL; - - this->connectedIpAddress = ""; - - sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if(isSocketValid() == false) { - throwException("Error creating socket"); - } - - this->isSocketBlocking = true; - -#ifdef __APPLE__ - int set = 1; - setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int)); -#endif - - /* Disable the Nagle (TCP No Delay) algorithm */ - if(Socket::disableNagle == true) { - int flag = 1; - int ret = setsockopt( sock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag) ); - if (ret == -1) { - printf("Couldn't setsockopt(TCP_NODELAY)\n"); + bool Socket::hasDataToRead() { + MutexSafeWrapper safeMutex(dataSynchAccessorRead, CODE_AT_LINE); + return Socket::hasDataToRead(sock); } - } - if(Socket::DEFAULT_SOCKET_SENDBUF_SIZE >= 0) { - int bufsize = 0; - socklen_t optlen = sizeof(bufsize); + bool Socket::hasDataToRead(PLATFORM_SOCKET socket) { + bool bResult = false; - int ret = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&bufsize, &optlen); - printf("Original setsockopt(SO_SNDBUF) = [%d] new will be [%d] ret = %d\n",bufsize,Socket::DEFAULT_SOCKET_SENDBUF_SIZE,ret); + if (Socket::isSocketValid(&socket) == true) { + fd_set rfds; + struct timeval tv; - ret = setsockopt( sock, SOL_SOCKET, SO_SNDBUF, (char *) &Socket::DEFAULT_SOCKET_SENDBUF_SIZE, sizeof( int ) ); - if (ret == -1) { - printf("Couldn't setsockopt(SO_SNDBUF) [%d]\n",Socket::DEFAULT_SOCKET_SENDBUF_SIZE); + /* Watch stdin (fd 0) to see when it has input. */ + FD_ZERO(&rfds); + FD_SET(socket, &rfds); + + /* Wait up to 0 seconds. */ + tv.tv_sec = 0; + tv.tv_usec = 0; + + int retval = 0; + { + //MutexSafeWrapper safeMutex(&dataSynchAccessor); + retval = select((int) socket + 1, &rfds, NULL, NULL, &tv); + } + if (retval < 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s\n", __FILE__, __FUNCTION__, __LINE__, retval, getLastSocketErrorFormattedText().c_str()); + printf("In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s\n", __FILE__, __FUNCTION__, __LINE__, retval, getLastSocketErrorFormattedText().c_str()); + } else if (retval) { + if (FD_ISSET(socket, &rfds)) { + bResult = true; + } + } + } + + return bResult; } - } - if(Socket::DEFAULT_SOCKET_RECVBUF_SIZE >= 0) { - int bufsize = 0; - socklen_t optlen = sizeof(bufsize); - - int ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&bufsize, &optlen); - printf("Original setsockopt(SO_RCVBUF) = [%d] new will be [%d] ret = %d\n",bufsize,Socket::DEFAULT_SOCKET_RECVBUF_SIZE,ret); - - ret = setsockopt( sock, SOL_SOCKET, SO_RCVBUF, (char *) &Socket::DEFAULT_SOCKET_RECVBUF_SIZE, sizeof( int ) ); - if (ret == -1) { - printf("Couldn't setsockopt(SO_RCVBUF) [%d]\n",Socket::DEFAULT_SOCKET_RECVBUF_SIZE); + bool Socket::hasDataToReadWithWait(int waitMicroseconds) { + MutexSafeWrapper safeMutex(dataSynchAccessorRead, CODE_AT_LINE); + return Socket::hasDataToReadWithWait(sock, waitMicroseconds); } - } -} + bool Socket::hasDataToReadWithWait(PLATFORM_SOCKET socket, int waitMicroseconds) { + bool bResult = false; -float Socket::getThreadedPingMS(std::string host) { - float result = -1; -/* - if(pingThread == NULL) { - lastThreadedPing = 0; - pingThread = new SimpleTaskThread(this,0,50); - pingThread->setUniqueID(__FILE__ + "_" + __FUNCTION); - pingThread->start(); - } + Chrono chono; + chono.start(); + if (Socket::isSocketValid(&socket) == true) { + fd_set rfds; + struct timeval tv; - if(pingCache.find(host) == pingCache.end()) { - MutexSafeWrapper safeMutex(&pingThreadAccessor); - safeMutex.ReleaseLock(); - result = getAveragePingMS(host, 1); - pingCache[host]=result; - } - else { - MutexSafeWrapper safeMutex(&pingThreadAccessor); - result = pingCache[host]; - safeMutex.ReleaseLock(); - } -*/ - return result; -} + /* Watch stdin (fd 0) to see when it has input. */ + FD_ZERO(&rfds); + FD_SET(socket, &rfds); -/* -void Socket::simpleTask(BaseThread *callingThread) { - // update ping times every x seconds - const int pingFrequencySeconds = 2; - if(difftime(time(NULL),lastThreadedPing) < pingFrequencySeconds) { - return; - } - lastThreadedPing = time(NULL); + /* Wait up to 0 seconds. */ + tv.tv_sec = 0; + tv.tv_usec = waitMicroseconds; - //printf("Pinging hosts...\n"); + int retval = 0; + { + //MutexSafeWrapper safeMutex(&dataSynchAccessor); + retval = select((int) socket + 1, &rfds, NULL, NULL, &tv); + } + if (retval < 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s\n", __FILE__, __FUNCTION__, __LINE__, retval, getLastSocketErrorFormattedText().c_str()); + printf("In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s\n", __FILE__, __FUNCTION__, __LINE__, retval, getLastSocketErrorFormattedText().c_str()); + } - for(std::map::iterator iterMap = pingCache.begin(); - iterMap != pingCache.end(); iterMap++) { - MutexSafeWrapper safeMutex(&pingThreadAccessor,CODE_AT_LINE); - iterMap->second = getAveragePingMS(iterMap->first, 1); - safeMutex.ReleaseLock(); - } -} -*/ + if (retval) { + if (FD_ISSET(socket, &rfds)) { + bResult = true; + } + } + } -Socket::~Socket() { - MutexSafeWrapper safeMutexSocketDestructorFlag(inSocketDestructorSynchAccessor,CODE_AT_LINE); - if(this->inSocketDestructor == true) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); - return; - } - inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); - this->inSocketDestructor = true; + //printf("hasdata waited [%d] milliseconds [%d], bResult = %d\n",chono.getMillis(),waitMilliseconds,bResult); + return bResult; + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START closing socket = %d...\n",__FILE__,__FUNCTION__,sock); + int Socket::getDataToRead(bool wantImmediateReply) { + unsigned long size = 0; - //safeMutexSocketDestructorFlag.ReleaseLock(); + //fd_set rfds; + //struct timeval tv; + //int retval; - disconnectSocket(); + /* Watch stdin (fd 0) to see when it has input. */ + //FD_ZERO(&rfds); + //FD_SET(sock, &rfds); - // Allow other callers with a lock on the mutexes to let them go - for(time_t elapsed = time(NULL); - (dataSynchAccessorRead->getRefCount() > 0 || - dataSynchAccessorWrite->getRefCount() > 0) && - difftime((long int)time(NULL),elapsed) <= 2;) { - printf("Waiting in socket destructor\n"); - //sleep(0); - } + /* Wait up to 0 seconds. */ + //tv.tv_sec = 0; + //tv.tv_usec = 0; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END closing socket = %d...\n",__FILE__,__FUNCTION__,sock); - - //delete pingThread; - //pingThread = NULL; - safeMutexSocketDestructorFlag.ReleaseLock(); - - delete dataSynchAccessorRead; - dataSynchAccessorRead = NULL; - delete dataSynchAccessorWrite; - dataSynchAccessorWrite = NULL; - delete inSocketDestructorSynchAccessor; - inSocketDestructorSynchAccessor = NULL; -} - -void Socket::disconnectSocket() { - //printf("Socket disconnecting sock = %d\n",sock); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START closing socket = %d...\n",__FILE__,__FUNCTION__,sock); - - if(isSocketValid() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] calling shutdown and close for socket = %d...\n",__FILE__,__FUNCTION__,sock); - - MutexSafeWrapper safeMutex(dataSynchAccessorRead,CODE_AT_LINE); - MutexSafeWrapper safeMutex1(dataSynchAccessorWrite,CODE_AT_LINE); - - if(isSocketValid() == true) { - ::shutdown(sock,2); + //retval = select(sock + 1, &rfds, NULL, NULL, &tv); + //if(retval) + if (isSocketValid() == true) { + //int loopCount = 1; + for (time_t elapsed = time(NULL); difftime((long int) time(NULL), elapsed) < 1;) { + /* ioctl isn't posix, but the following seems to work on all modern + * unixes */ #ifndef WIN32 - ::close(sock); - sock = -1; + int err = ioctl(sock, FIONREAD, &size); #else - ::closesocket(sock); - sock = INVALID_SOCKET; + int err = ioctlsocket(sock, FIONREAD, &size); #endif - } - safeMutex.ReleaseLock(); - safeMutex1.ReleaseLock(); - } + int lastSocketError = getLastSocketError(); + if (err < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] ERROR PEEKING SOCKET DATA, err = %d %s\n", __FILE__, __FUNCTION__, __LINE__, err, getLastSocketErrorFormattedText().c_str()); + break; + } else if (err == 0) { + if (isConnected() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] ERROR PEEKING SOCKET DATA, err = %d %s\n", __FILE__, __FUNCTION__, __LINE__, err, getLastSocketErrorFormattedText().c_str()); + break; + } + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END closing socket = %d...\n",__FILE__,__FUNCTION__,sock); -} + if (size > 0) { + break; + } else if (hasDataToRead() == true) { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, (hasDataToRead() == true) err = %d, sock = %d, size = " MG_SIZE_T_SPECIFIER ", loopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,err,sock,size,loopCount); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, (hasDataToRead() == true) err = %d, sock = %d, size = " MG_SIZE_T_SPECIFIER "\n", __FILE__, __FUNCTION__, __LINE__, err, sock, size); + } else { + //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, err = %d, sock = %d, size = " MG_SIZE_T_SPECIFIER ", loopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,err,sock,size,loopCount); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, err = %d, sock = %d, size = " MG_SIZE_T_SPECIFIER "\n", __FILE__, __FUNCTION__, __LINE__, err, sock, size); + break; + } -// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading -bool Socket::hasDataToRead(std::map &socketTriggeredList) -{ - bool bResult = false; + if (wantImmediateReply == true) { + break; + } - if(socketTriggeredList.empty() == false) { - /* Watch stdin (fd 0) to see when it has input. */ - fd_set rfds; - FD_ZERO(&rfds); - - string socketDebugList = ""; - PLATFORM_SOCKET imaxsocket = 0; - for(std::map::iterator itermap = socketTriggeredList.begin(); - itermap != socketTriggeredList.end(); ++itermap) { - PLATFORM_SOCKET socket = itermap->first; - if(Socket::isSocketValid(&socket) == true) { - FD_SET(socket, &rfds); - imaxsocket = max(socket,imaxsocket); - - if(socketDebugList != "") { - socketDebugList += ","; + //loopCount++; } - socketDebugList += intToStr(socket); - } - } + } - if(imaxsocket > 0) { - /* Wait up to 0 seconds. */ - struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 0; - - - int retval = 0; - { - //MutexSafeWrapper safeMutex(&dataSynchAccessor); - retval = select((int)imaxsocket + 1, &rfds, NULL, NULL, &tv); - } - if(retval < 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s, socketDebugList [%s]\n",__FILE__,__FUNCTION__,__LINE__,retval,getLastSocketErrorFormattedText().c_str(),socketDebugList.c_str()); - printf("In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s\n",__FILE__,__FUNCTION__,__LINE__,retval,getLastSocketErrorFormattedText().c_str()); - } - else if(retval) { - bResult = true; - - for(std::map::iterator itermap = socketTriggeredList.begin(); - itermap != socketTriggeredList.end(); ++itermap) { - PLATFORM_SOCKET socket = itermap->first; - if (FD_ISSET(socket, &rfds)) { - itermap->second = true; - } - else { - itermap->second = false; - } - } - } - } - } - - return bResult; -} - -bool Socket::hasDataToRead() -{ - MutexSafeWrapper safeMutex(dataSynchAccessorRead,CODE_AT_LINE); - return Socket::hasDataToRead(sock) ; -} - -bool Socket::hasDataToRead(PLATFORM_SOCKET socket) -{ - bool bResult = false; - - if(Socket::isSocketValid(&socket) == true) - { - fd_set rfds; - struct timeval tv; - - /* Watch stdin (fd 0) to see when it has input. */ - FD_ZERO(&rfds); - FD_SET(socket, &rfds); - - /* Wait up to 0 seconds. */ - tv.tv_sec = 0; - tv.tv_usec = 0; - - int retval = 0; - { - //MutexSafeWrapper safeMutex(&dataSynchAccessor); - retval = select((int)socket + 1, &rfds, NULL, NULL, &tv); - } - if(retval < 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s\n",__FILE__,__FUNCTION__,__LINE__,retval,getLastSocketErrorFormattedText().c_str()); - printf("In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s\n",__FILE__,__FUNCTION__,__LINE__,retval,getLastSocketErrorFormattedText().c_str()); - } - else if(retval) - { - if (FD_ISSET(socket, &rfds)) - { - bResult = true; - } - } - } - - return bResult; -} - -bool Socket::hasDataToReadWithWait(int waitMicroseconds) { - MutexSafeWrapper safeMutex(dataSynchAccessorRead,CODE_AT_LINE); - return Socket::hasDataToReadWithWait(sock,waitMicroseconds) ; -} - -bool Socket::hasDataToReadWithWait(PLATFORM_SOCKET socket,int waitMicroseconds) { - bool bResult = false; - - Chrono chono; - chono.start(); - if(Socket::isSocketValid(&socket) == true) - { - fd_set rfds; - struct timeval tv; - - /* Watch stdin (fd 0) to see when it has input. */ - FD_ZERO(&rfds); - FD_SET(socket, &rfds); - - /* Wait up to 0 seconds. */ - tv.tv_sec = 0; - tv.tv_usec = waitMicroseconds; - - int retval = 0; - { - //MutexSafeWrapper safeMutex(&dataSynchAccessor); - retval = select((int)socket + 1, &rfds, NULL, NULL, &tv); - } - if(retval < 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s\n",__FILE__,__FUNCTION__,__LINE__,retval,getLastSocketErrorFormattedText().c_str()); - printf("In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s\n",__FILE__,__FUNCTION__,__LINE__,retval,getLastSocketErrorFormattedText().c_str()); + return static_cast(size); } - if(retval) - { - if (FD_ISSET(socket, &rfds)) - { - bResult = true; - } - } - } + int Socket::send(const void *data, int dataSize) { + const int MAX_SEND_WAIT_SECONDS = 3; - //printf("hasdata waited [%d] milliseconds [%d], bResult = %d\n",chono.getMillis(),waitMilliseconds,bResult); - return bResult; -} + int bytesSent = 0; + if (isSocketValid() == true) { + errno = 0; -int Socket::getDataToRead(bool wantImmediateReply) { - unsigned long size = 0; + // MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); + // if(this->inSocketDestructor == true) { + // SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); + // return -1; + // } + // inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); + // safeMutexSocketDestructorFlag.ReleaseLock(); - //fd_set rfds; - //struct timeval tv; - //int retval; + MutexSafeWrapper safeMutex(dataSynchAccessorWrite, CODE_AT_LINE); - /* Watch stdin (fd 0) to see when it has input. */ - //FD_ZERO(&rfds); - //FD_SET(sock, &rfds); + if (isSocketValid() == true) { +#ifdef __APPLE__ + bytesSent = ::send(sock, (const char *) data, dataSize, SO_NOSIGPIPE); +#else + bytesSent = ::send(sock, (const char *) data, dataSize, MSG_NOSIGNAL | MSG_DONTWAIT); +#endif + } + safeMutex.ReleaseLock(); + } - /* Wait up to 0 seconds. */ - //tv.tv_sec = 0; - //tv.tv_usec = 0; + // TEST errors + //bytesSent = -1; + // END TEST - //retval = select(sock + 1, &rfds, NULL, NULL, &tv); - //if(retval) - if(isSocketValid() == true) - { - //int loopCount = 1; - for(time_t elapsed = time(NULL); difftime((long int)time(NULL),elapsed) < 1;) { - /* ioctl isn't posix, but the following seems to work on all modern - * unixes */ - #ifndef WIN32 - int err = ioctl(sock, FIONREAD, &size); - #else - int err= ioctlsocket(sock, FIONREAD, &size); - #endif int lastSocketError = getLastSocketError(); - if(err < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) - { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR PEEKING SOCKET DATA, err = %d %s\n",__FILE__,__FUNCTION__,__LINE__,err,getLastSocketErrorFormattedText().c_str()); - break; - } - else if(err == 0) - { - if(isConnected() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR PEEKING SOCKET DATA, err = %d %s\n",__FILE__,__FUNCTION__,__LINE__,err,getLastSocketErrorFormattedText().c_str()); - break; + if (bytesSent < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] ERROR WRITING SOCKET DATA, err = %d error = %s dataSize = %d\n", __FILE__, __FUNCTION__, __LINE__, bytesSent, getLastSocketErrorFormattedText(&lastSocketError).c_str(), dataSize); + } else if (bytesSent < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN && isConnected() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] #1 EAGAIN during send, trying again... dataSize = %d\n", __FILE__, __FUNCTION__, __LINE__, dataSize); + + int attemptCount = 0; + time_t tStartTimer = time(NULL); + while ((bytesSent < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) && + (difftime((long int) time(NULL), tStartTimer) <= MAX_SEND_WAIT_SECONDS)) { + attemptCount++; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] attemptCount = %d\n", __FILE__, __FUNCTION__, __LINE__, attemptCount); + + MutexSafeWrapper safeMutex(dataSynchAccessorWrite, CODE_AT_LINE); + if (isConnected() == true) { + struct timeval timeVal; + timeVal.tv_sec = 1; + timeVal.tv_usec = 0; + bool canWrite = isWritable(&timeVal); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p, canWrite = %d\n", __FILE__, __FUNCTION__, __LINE__, attemptCount, sock, dataSize, data, canWrite); + + // MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); + // if(this->inSocketDestructor == true) { + // SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); + // return -1; + // } + // inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); + // safeMutexSocketDestructorFlag.ReleaseLock(); + + +#ifdef __APPLE__ + bytesSent = ::send(sock, (const char *) data, dataSize, SO_NOSIGPIPE); +#else + bytesSent = ::send(sock, (const char *) data, dataSize, MSG_NOSIGNAL | MSG_DONTWAIT); +#endif + lastSocketError = getLastSocketError(); + if (bytesSent < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { + break; + } + + //safeMutex.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] #2 EAGAIN during send, trying again returned: %d\n", __FILE__, __FUNCTION__, __LINE__, bytesSent); + } else { + int iErr = getLastSocketError(); + + safeMutex.ReleaseLock(); + disconnectSocket(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s] DISCONNECTED SOCKET error while sending socket data, bytesSent = %d, error = %s\n", __FILE__, __FUNCTION__, bytesSent, getLastSocketErrorFormattedText(&iErr).c_str()); + break; + + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] attemptCount = %d\n", __FILE__, __FUNCTION__, __LINE__, attemptCount); } } - if(size > 0) { - break; - } - else if(hasDataToRead() == true) { - //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, (hasDataToRead() == true) err = %d, sock = %d, size = " MG_SIZE_T_SPECIFIER ", loopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,err,sock,size,loopCount); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, (hasDataToRead() == true) err = %d, sock = %d, size = " MG_SIZE_T_SPECIFIER "\n",__FILE__,__FUNCTION__,__LINE__,err,sock,size); - } - else { - //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, err = %d, sock = %d, size = " MG_SIZE_T_SPECIFIER ", loopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,err,sock,size,loopCount); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING PEEKING SOCKET DATA, err = %d, sock = %d, size = " MG_SIZE_T_SPECIFIER "\n",__FILE__,__FUNCTION__,__LINE__,err,sock,size); - break; - } - - if(wantImmediateReply == true) { - break; - } - - //loopCount++; - } - } - - return static_cast(size); -} - -int Socket::send(const void *data, int dataSize) { - const int MAX_SEND_WAIT_SECONDS = 3; - - int bytesSent= 0; - if(isSocketValid() == true) { - errno = 0; - -// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); -// if(this->inSocketDestructor == true) { -// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); -// return -1; -// } -// inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); -// safeMutexSocketDestructorFlag.ReleaseLock(); - - MutexSafeWrapper safeMutex(dataSynchAccessorWrite,CODE_AT_LINE); - - if(isSocketValid() == true) { -#ifdef __APPLE__ - bytesSent = ::send(sock, (const char *)data, dataSize, SO_NOSIGPIPE); -#else - bytesSent = ::send(sock, (const char *)data, dataSize, MSG_NOSIGNAL | MSG_DONTWAIT); -#endif - } - safeMutex.ReleaseLock(); - } - - // TEST errors - //bytesSent = -1; - // END TEST - - int lastSocketError = getLastSocketError(); - if(bytesSent < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR WRITING SOCKET DATA, err = %d error = %s dataSize = %d\n",__FILE__,__FUNCTION__,__LINE__,bytesSent,getLastSocketErrorFormattedText(&lastSocketError).c_str(),dataSize); - } - else if(bytesSent < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN && isConnected() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 EAGAIN during send, trying again... dataSize = %d\n",__FILE__,__FUNCTION__,__LINE__,dataSize); - - int attemptCount = 0; - time_t tStartTimer = time(NULL); - while((bytesSent < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) && - (difftime((long int)time(NULL),tStartTimer) <= MAX_SEND_WAIT_SECONDS)) { - attemptCount++; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d\n",__FILE__,__FUNCTION__,__LINE__,attemptCount); - - MutexSafeWrapper safeMutex(dataSynchAccessorWrite,CODE_AT_LINE); - if(isConnected() == true) { - struct timeval timeVal; - timeVal.tv_sec = 1; - timeVal.tv_usec = 0; - bool canWrite = isWritable(&timeVal); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p, canWrite = %d\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,sock,dataSize,data,canWrite); - -// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); -// if(this->inSocketDestructor == true) { -// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); -// return -1; -// } -// inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); -// safeMutexSocketDestructorFlag.ReleaseLock(); - - -#ifdef __APPLE__ - bytesSent = ::send(sock, (const char *)data, dataSize, SO_NOSIGPIPE); -#else - bytesSent = ::send(sock, (const char *)data, dataSize, MSG_NOSIGNAL | MSG_DONTWAIT); -#endif + if (isConnected() == true && bytesSent > 0 && bytesSent < dataSize) { lastSocketError = getLastSocketError(); - if(bytesSent < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { - break; - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] need to send more data, trying again getLastSocketError() = %d, bytesSent = %d, dataSize = %d\n", __FILE__, __FUNCTION__, __LINE__, lastSocketError, bytesSent, dataSize); - //safeMutex.ReleaseLock(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 EAGAIN during send, trying again returned: %d\n",__FILE__,__FUNCTION__,__LINE__,bytesSent); - } - else { - int iErr = getLastSocketError(); - - safeMutex.ReleaseLock(); - disconnectSocket(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] DISCONNECTED SOCKET error while sending socket data, bytesSent = %d, error = %s\n",__FILE__,__FUNCTION__,bytesSent,getLastSocketErrorFormattedText(&iErr).c_str()); - break; - - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d\n",__FILE__,__FUNCTION__,__LINE__,attemptCount); - } - } - - if(isConnected() == true && bytesSent > 0 && bytesSent < dataSize) { - lastSocketError = getLastSocketError(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] need to send more data, trying again getLastSocketError() = %d, bytesSent = %d, dataSize = %d\n",__FILE__,__FUNCTION__,__LINE__,lastSocketError,bytesSent,dataSize); - - int totalBytesSent = bytesSent; - int attemptCount = 0; - - - time_t tStartTimer = time(NULL); - while(((bytesSent > 0 && totalBytesSent < dataSize) || - (bytesSent < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN)) && - (difftime((long int)time(NULL),tStartTimer) <= MAX_SEND_WAIT_SECONDS)) { - attemptCount++; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, totalBytesSent = %d\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,totalBytesSent); - - MutexSafeWrapper safeMutex(dataSynchAccessorWrite,CODE_AT_LINE); - if(isConnected() == true) { - struct timeval timeVal; - timeVal.tv_sec = 1; - timeVal.tv_usec = 0; - bool canWrite = isWritable(&timeVal); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p, canWrite = %d\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,sock,dataSize,data,canWrite); - -// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); -// if(this->inSocketDestructor == true) { -// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); -// return -1; -// } -// inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); -// safeMutexSocketDestructorFlag.ReleaseLock(); + int totalBytesSent = bytesSent; + int attemptCount = 0; - const char *sendBuf = (const char *)data; + time_t tStartTimer = time(NULL); + while (((bytesSent > 0 && totalBytesSent < dataSize) || + (bytesSent < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN)) && + (difftime((long int) time(NULL), tStartTimer) <= MAX_SEND_WAIT_SECONDS)) { + attemptCount++; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] attemptCount = %d, totalBytesSent = %d\n", __FILE__, __FUNCTION__, __LINE__, attemptCount, totalBytesSent); + + MutexSafeWrapper safeMutex(dataSynchAccessorWrite, CODE_AT_LINE); + if (isConnected() == true) { + struct timeval timeVal; + timeVal.tv_sec = 1; + timeVal.tv_usec = 0; + bool canWrite = isWritable(&timeVal); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p, canWrite = %d\n", __FILE__, __FUNCTION__, __LINE__, attemptCount, sock, dataSize, data, canWrite); + + // MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); + // if(this->inSocketDestructor == true) { + // SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); + // return -1; + // } + // inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); + // safeMutexSocketDestructorFlag.ReleaseLock(); + + + const char *sendBuf = (const char *) data; #ifdef __APPLE__ - bytesSent = ::send(sock, &sendBuf[totalBytesSent], dataSize - totalBytesSent, SO_NOSIGPIPE); + bytesSent = ::send(sock, &sendBuf[totalBytesSent], dataSize - totalBytesSent, SO_NOSIGPIPE); #else - bytesSent = ::send(sock, &sendBuf[totalBytesSent], dataSize - totalBytesSent, MSG_NOSIGNAL | MSG_DONTWAIT); + bytesSent = ::send(sock, &sendBuf[totalBytesSent], dataSize - totalBytesSent, MSG_NOSIGNAL | MSG_DONTWAIT); #endif - lastSocketError = getLastSocketError(); - if(bytesSent > 0) { - totalBytesSent += bytesSent; - } + lastSocketError = getLastSocketError(); + if (bytesSent > 0) { + totalBytesSent += bytesSent; + } - if(bytesSent < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { - break; - } + if (bytesSent < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { + break; + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] retry send returned: %d\n",__FILE__,__FUNCTION__,__LINE__,bytesSent); - } - else { - int iErr = getLastSocketError(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] retry send returned: %d\n", __FILE__, __FUNCTION__, __LINE__, bytesSent); + } else { + int iErr = getLastSocketError(); - safeMutex.ReleaseLock(); - disconnectSocket(); + safeMutex.ReleaseLock(); + disconnectSocket(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] DISCONNECTED SOCKET error while sending socket data, bytesSent = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,bytesSent,getLastSocketErrorFormattedText(&iErr).c_str()); - break; - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s Line: %d] DISCONNECTED SOCKET error while sending socket data, bytesSent = %d, error = %s\n", __FILE__, __FUNCTION__, __LINE__, bytesSent, getLastSocketErrorFormattedText(&iErr).c_str()); + break; + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d\n",__FILE__,__FUNCTION__,__LINE__,attemptCount); - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] attemptCount = %d\n", __FILE__, __FUNCTION__, __LINE__, attemptCount); + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] bytesSent = %d, totalBytesSent = %d\n",__FILE__,__FUNCTION__,__LINE__,bytesSent,totalBytesSent); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] bytesSent = %d, totalBytesSent = %d\n", __FILE__, __FUNCTION__, __LINE__, bytesSent, totalBytesSent); - if(bytesSent > 0) { - bytesSent = totalBytesSent; - } - } + if (bytesSent > 0) { + bytesSent = totalBytesSent; + } + } - if(bytesSent <= 0 || isConnected() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR WRITING SOCKET DATA, err = %d error = %s\n",__FILE__,__FUNCTION__,__LINE__,bytesSent,getLastSocketErrorFormattedText().c_str()); + if (bytesSent <= 0 || isConnected() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] ERROR WRITING SOCKET DATA, err = %d error = %s\n", __FILE__, __FUNCTION__, __LINE__, bytesSent, getLastSocketErrorFormattedText().c_str()); - int iErr = getLastSocketError(); - disconnectSocket(); + int iErr = getLastSocketError(); + disconnectSocket(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] DISCONNECTED SOCKET error while sending socket data, bytesSent = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,bytesSent,getLastSocketErrorFormattedText(&iErr).c_str()); - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s Line: %d] DISCONNECTED SOCKET error while sending socket data, bytesSent = %d, error = %s\n", __FILE__, __FUNCTION__, __LINE__, bytesSent, getLastSocketErrorFormattedText(&iErr).c_str()); + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] sock = %d, bytesSent = %d\n",__FILE__,__FUNCTION__,__LINE__,sock,bytesSent); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] sock = %d, bytesSent = %d\n", __FILE__, __FUNCTION__, __LINE__, sock, bytesSent); - return static_cast(bytesSent); -} - -int Socket::receive(void *data, int dataSize, bool tryReceiveUntilDataSizeMet) { - ssize_t bytesReceived = 0; - - if(isSocketValid() == true) { - MutexSafeWrapper safeMutex(dataSynchAccessorRead,CODE_AT_LINE); - if(isSocketValid() == true) { - bytesReceived = recv(sock, reinterpret_cast(data), dataSize, 0); + return static_cast(bytesSent); } - safeMutex.ReleaseLock(); - } - int lastSocketError = getLastSocketError(); - if(bytesReceived < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] ERROR READING SOCKET DATA error while sending socket data, bytesSent = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived,getLastSocketErrorFormattedText(&lastSocketError).c_str()); - } - else if(bytesReceived < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 EAGAIN during receive, trying again...\n",__FILE__,__FUNCTION__,__LINE__); + int Socket::receive(void *data, int dataSize, bool tryReceiveUntilDataSizeMet) { + ssize_t bytesReceived = 0; - Chrono chronoElapsed(true); - const int MAX_RECV_WAIT_SECONDS = 3; - time_t tStartTimer = time(NULL); - while((bytesReceived < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) && - (difftime((long int)time(NULL),tStartTimer) <= MAX_RECV_WAIT_SECONDS)) { - if(isConnected() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] Socket is NOT connected!\n",__FILE__,__FUNCTION__,__LINE__); - - int iErr = getLastSocketError(); - disconnectSocket(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] DISCONNECTED SOCKET error while receiving socket data, bytesSent = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived,getLastSocketErrorFormattedText(&iErr).c_str()); - break; - } - //else if(Socket::isReadable(true) == true) { - else { - if(Socket::isReadable(true) == true) { - MutexSafeWrapper safeMutex(dataSynchAccessorRead,CODE_AT_LINE); - - //SafeSocketBlockToggleWrapper safeBlock(this, true); - errno = 0; + if (isSocketValid() == true) { + MutexSafeWrapper safeMutex(dataSynchAccessorRead, CODE_AT_LINE); + if (isSocketValid() == true) { bytesReceived = recv(sock, reinterpret_cast(data), dataSize, 0); - lastSocketError = getLastSocketError(); - //safeBlock.Restore(); - safeMutex.ReleaseLock(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 EAGAIN during receive, trying again returned: %d, lastSocketError = %d, dataSize = %d\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived,lastSocketError,(int)dataSize); - //printf("In [%s::%s Line: %d] #2 EAGAIN during receive, trying again returned: %d, lastSocketError = %d, dataSize = %d\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived,lastSocketError,(int)dataSize); } - else { - //if(chronoElapsed.getMillis() % 3 == 0) { - // sleep(1); + safeMutex.ReleaseLock(); + } + + int lastSocketError = getLastSocketError(); + if (bytesReceived < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s Line: %d] ERROR READING SOCKET DATA error while sending socket data, bytesSent = %d, error = %s\n", __FILE__, __FUNCTION__, __LINE__, bytesReceived, getLastSocketErrorFormattedText(&lastSocketError).c_str()); + } else if (bytesReceived < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] #1 EAGAIN during receive, trying again...\n", __FILE__, __FUNCTION__, __LINE__); + + Chrono chronoElapsed(true); + const int MAX_RECV_WAIT_SECONDS = 3; + time_t tStartTimer = time(NULL); + while ((bytesReceived < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) && + (difftime((long int) time(NULL), tStartTimer) <= MAX_RECV_WAIT_SECONDS)) { + if (isConnected() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s Line: %d] Socket is NOT connected!\n", __FILE__, __FUNCTION__, __LINE__); + + int iErr = getLastSocketError(); + disconnectSocket(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s Line: %d] DISCONNECTED SOCKET error while receiving socket data, bytesSent = %d, error = %s\n", __FILE__, __FUNCTION__, __LINE__, bytesReceived, getLastSocketErrorFormattedText(&iErr).c_str()); + break; + } + //else if(Socket::isReadable(true) == true) { + else { + if (Socket::isReadable(true) == true) { + MutexSafeWrapper safeMutex(dataSynchAccessorRead, CODE_AT_LINE); + + //SafeSocketBlockToggleWrapper safeBlock(this, true); + errno = 0; + bytesReceived = recv(sock, reinterpret_cast(data), dataSize, 0); + lastSocketError = getLastSocketError(); + //safeBlock.Restore(); + safeMutex.ReleaseLock(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] #2 EAGAIN during receive, trying again returned: %d, lastSocketError = %d, dataSize = %d\n", __FILE__, __FUNCTION__, __LINE__, bytesReceived, lastSocketError, (int) dataSize); + //printf("In [%s::%s Line: %d] #2 EAGAIN during receive, trying again returned: %d, lastSocketError = %d, dataSize = %d\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived,lastSocketError,(int)dataSize); + } else { + //if(chronoElapsed.getMillis() % 3 == 0) { + // sleep(1); + //} + //else { + sleep(0); + //} + } + } + } + } + + if (bytesReceived <= 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] bytesReceived = %d\n", __FILE__, __FUNCTION__, __LINE__, bytesReceived); + + int iErr = getLastSocketError(); + disconnectSocket(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s Line: %d] DISCONNECTED SOCKET error while receiving socket data, bytesReceived = %d, error = %s, dataSize = %d, tryReceiveUntilDataSizeMet = %d\n", __FILE__, __FUNCTION__, __LINE__, bytesReceived, getLastSocketErrorFormattedText(&iErr).c_str(), dataSize, tryReceiveUntilDataSizeMet); + } else if (tryReceiveUntilDataSizeMet == true && bytesReceived < dataSize) { + int newBufferSize = (dataSize - (int) bytesReceived); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] WARNING, attempting to receive MORE data, bytesReceived = %d, dataSize = %d, newBufferSize = %d\n", __FILE__, __FUNCTION__, __LINE__, bytesReceived, dataSize, newBufferSize); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nIn [%s::%s Line: %d] WARNING, attempting to receive MORE data, bytesReceived = %d, dataSize = %d, newBufferSize = %d\n", __FILE__, __FUNCTION__, __LINE__, (int) bytesReceived, dataSize, newBufferSize); + + char *dataAsCharPointer = reinterpret_cast(data); + int additionalBytes = receive(&dataAsCharPointer[bytesReceived], newBufferSize, tryReceiveUntilDataSizeMet); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] WARNING, additionalBytes = %d\n", __FILE__, __FUNCTION__, __LINE__, additionalBytes); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nIn [%s::%s Line: %d] WARNING, additionalBytes = %d\n", __FILE__, __FUNCTION__, __LINE__, additionalBytes); + + if (additionalBytes > 0) { + bytesReceived += additionalBytes; + } else { + //throw megaglest_runtime_error("additionalBytes == " + intToStr(additionalBytes)); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] additionalBytes == %d\n", __FILE__, __FUNCTION__, __LINE__, additionalBytes); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\nIn [%s::%s Line: %d] additionalBytes == %d\n", __FILE__, __FUNCTION__, __LINE__, additionalBytes); + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] additionalBytes == %d\n", __FILE__, __FUNCTION__, __LINE__, additionalBytes); + + int iErr = getLastSocketError(); + disconnectSocket(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s Line: %d] DISCONNECTED SOCKET error while receiving socket data, bytesReceived = %d, error = %s, dataSize = %d, tryReceiveUntilDataSizeMet = %d\n", __FILE__, __FUNCTION__, __LINE__, bytesReceived, getLastSocketErrorFormattedText(&iErr).c_str(), dataSize, tryReceiveUntilDataSizeMet); + } + } + return static_cast(bytesReceived); + } + + SafeSocketBlockToggleWrapper::SafeSocketBlockToggleWrapper(Socket *socket, bool toggle) { + this->socket = socket; + + if (this->socket != NULL) { + this->originallyBlocked = socket->getBlock(); + this->newBlocked = toggle; + + if (this->originallyBlocked != this->newBlocked) { + socket->setBlock(this->newBlocked); + } + } else { + this->originallyBlocked = false; + this->newBlocked = false; + } + } + + void SafeSocketBlockToggleWrapper::Restore() { + if (this->socket != NULL) { + if (this->originallyBlocked != this->newBlocked) { + socket->setBlock(this->originallyBlocked); + this->newBlocked = this->originallyBlocked; + } + } + } + + SafeSocketBlockToggleWrapper::~SafeSocketBlockToggleWrapper() { + Restore(); + } + + int Socket::peek(void *data, int dataSize, bool mustGetData, int *pLastSocketError) { + Chrono chrono; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) chrono.start(); + + int lastSocketError = 0; + int err = 0; + if (isSocketValid() == true) { + //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); + + // MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); + // if(this->inSocketDestructor == true) { + // SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); + // return -1; + // } + // inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); + // safeMutexSocketDestructorFlag.ReleaseLock(); + + //MutexSafeWrapper safeMutex(&dataSynchAccessor,CODE_AT_LINE + "_" + intToStr(sock) + "_" + intToStr(dataSize)); + + + //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); + if (isSocketValid() == true) { + MutexSafeWrapper safeMutex(dataSynchAccessorRead, CODE_AT_LINE); + // Chrono recvTimer(true); + SafeSocketBlockToggleWrapper safeUnblock(this, false); + errno = 0; + err = recv(sock, reinterpret_cast(data), dataSize, MSG_PEEK); + lastSocketError = getLastSocketError(); + if (pLastSocketError != NULL) { + *pLastSocketError = lastSocketError; + } + safeUnblock.Restore(); + + // if(recvTimer.getMillis() > 1000 || (err <= 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN)) { + // printf("#1 PEEK err = %d lastSocketError = %d ms: %lld\n",err,lastSocketError,(long long int)recvTimer.getMillis()); + + //if(err != dataSize) { + // printf("#1 PEEK err = %d lastSocketError = %d\n",err,lastSocketError); + //} + + // } + safeMutex.ReleaseLock(); + } + //safeMutex.ReleaseLock(); + + //printf("Peek #1 err = %d\n",err); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) if (chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] action running for msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, (long long int)chrono.getMillis()); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] SOCKET appears to be invalid [%d]\n", __FILE__, __FUNCTION__, __LINE__, sock); + } + //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); + + if (err < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s Line: %d] ERROR PEEKING SOCKET DATA error while sending socket data, err = %d, error = %s\n", __FILE__, __FUNCTION__, __LINE__, err, getLastSocketErrorFormattedText().c_str()); + disconnectSocket(); + } else if (err < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN && mustGetData == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] #1 ERROR EAGAIN during peek, trying again...\n", __FILE__, __FUNCTION__, __LINE__); + + //printf("Peek #2 err = %d\n",err); + + Chrono chronoElapsed(true); + const int MAX_PEEK_WAIT_SECONDS = 3; + time_t tStartTimer = time(NULL); + while ((err < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) && + isSocketValid() == true && + (difftime((long int) time(NULL), tStartTimer) <= MAX_PEEK_WAIT_SECONDS)) { + /* + if(isConnected() == false) { + int iErr = getLastSocketError(); + disconnectSocket(); + break; + } + */ + if (Socket::isReadable(true) == true || chronoElapsed.getMillis() % 100 == 0) { + + // MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); + // if(this->inSocketDestructor == true) { + // SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); + // return -1; + // } + // inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); + // safeMutexSocketDestructorFlag.ReleaseLock(); + + //MutexSafeWrapper safeMutex(&dataSynchAccessor,CODE_AT_LINE + "_" + intToStr(sock) + "_" + intToStr(dataSize)); + MutexSafeWrapper safeMutex(dataSynchAccessorRead, CODE_AT_LINE); + + // Chrono recvTimer(true); + SafeSocketBlockToggleWrapper safeUnblock(this, false); + errno = 0; + err = recv(sock, reinterpret_cast(data), dataSize, MSG_PEEK); + lastSocketError = getLastSocketError(); + if (pLastSocketError != NULL) { + *pLastSocketError = lastSocketError; + } + safeUnblock.Restore(); + + // if(recvTimer.getMillis() > 1000 || (err <= 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN)) { + // printf("#2 PEEK err = %d lastSocketError = %d ms: %lld\n",err,lastSocketError,(long long int)recvTimer.getMillis()); + // } + + //printf("Socket peek delayed checking for sock = %d err = %d\n",sock,err); + + safeMutex.ReleaseLock(); + + if (err == 0 || err == PLATFORM_SOCKET_TRY_AGAIN) { + sleep(0); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) if (chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] action running for msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, (long long int)chrono.getMillis()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] #2 EAGAIN during peek, trying again returned: %d\n", __FILE__, __FUNCTION__, __LINE__, err); + } + //else { + //printf("Socket peek delayed [NOT READABLE] checking for sock = %d err = %d\n",sock,err); + //} + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) if (chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] action running for msecs: %lld\n", __FILE__, __FUNCTION__, __LINE__, (long long int)chrono.getMillis()); + } else if (err == 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] #2 SOCKET appears to be invalid [%d] lastSocketError [%d] err [%d] mustGetData [%d] dataSize [%d]\n", __FILE__, __FUNCTION__, __LINE__, sock, lastSocketError, err, mustGetData, dataSize); + } + + //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); + + if (err < 0 || (err == 0 && dataSize != 0) || + ((err == 0 || err == -1) && dataSize == 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN)) { + //printf("** #1 Socket peek error for sock = %d err = %d lastSocketError = %d\n",sock,err,lastSocketError); + + int iErr = lastSocketError; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s Line: %d] DISCONNECTING SOCKET for socket [%d], err = %d, dataSize = %d, error = %s\n", __FILE__, __FUNCTION__, __LINE__, sock, err, dataSize, getLastSocketErrorFormattedText(&iErr).c_str()); + //printf("Peek #3 err = %d\n",err); + //lastSocketError = getLastSocketError(); + if (mustGetData == true || lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { + printf("** #2 Socket peek error for sock = %d err = %d lastSocketError = %d mustGetData = %d\n", sock, err, lastSocketError, mustGetData); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s Line: %d] DISCONNECTING SOCKET for socket [%d], err = %d, dataSize = %d, error = %s\n", __FILE__, __FUNCTION__, __LINE__, sock, err, dataSize, getLastSocketErrorFormattedText(&iErr).c_str()); + + if (err == 0) { + printf("** LAST CHANCE for disconnection check for sock = %d\n", sock); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "** LAST CHANCE for disconnection check for sock = %d\n", sock); + + MutexSafeWrapper safeMutex(dataSynchAccessorRead, CODE_AT_LINE); + SafeSocketBlockToggleWrapper safeUnblock(this, false); + errno = 0; + int second_err = recv(sock, reinterpret_cast(data), dataSize, MSG_PEEK); + safeUnblock.Restore(); + safeMutex.ReleaseLock(); + + if (second_err == 0 || second_err < 0) { + printf("** Disconnecting sock = %d\n", sock); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "** Disconnecting sock = %d\n", sock); + + disconnectSocket(); + } + } else { + printf("** Disconnecting sock = %d\n", sock); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "** Disconnecting sock = %d\n", sock); + + disconnectSocket(); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s Line: %d] DISCONNECTED SOCKET error while peeking socket data for socket [%d], err = %d, dataSize = %d, error = %s\n", __FILE__, __FUNCTION__, __LINE__, sock, err, dataSize, getLastSocketErrorFormattedText(&iErr).c_str()); + } + } + + return static_cast(err); + } + + bool Socket::getBlock() { + bool blocking = true; + + // don't waste time if the socket is invalid + if (isSocketValid(&sock) == false) { + return blocking; + } + + //#ifndef WIN32 + // int currentFlags = fcntl(sock, F_GETFL); + // blocking = !((currentFlags & O_NONBLOCK) == O_NONBLOCK); + //#else + blocking = this->isSocketBlocking; + //#endif + return blocking; + } + + void Socket::setBlock(bool block) { + setBlock(block, this->sock); + this->isSocketBlocking = block; + } + + void Socket::setBlock(bool block, PLATFORM_SOCKET socket) { + // don't waste time if the socket is invalid + if (isSocketValid(&socket) == false) { + return; + } + +#ifndef WIN32 + int currentFlags = fcntl(socket, F_GETFL); + if (currentFlags < 0) { + currentFlags = 0; + } + if (block == true) { + currentFlags &= (~O_NONBLOCK); + } else { + currentFlags |= O_NONBLOCK; + } + int err = fcntl(socket, F_SETFL, currentFlags); +#else + u_long iMode = !block; + int err = ioctlsocket(socket, FIONBIO, &iMode); +#endif + if (err < 0) { + throwException("Error setting I/O mode for socket"); + } + } + + inline bool Socket::isReadable(bool lockMutex) { + if (isSocketValid() == false) return false; + + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 0; + + fd_set set; + FD_ZERO(&set); + + Mutex *lockMutexObj = (lockMutex == true ? dataSynchAccessorRead : NULL); + MutexSafeWrapper safeMutex(lockMutexObj, CODE_AT_LINE); + //if(lockMutex == true) { + // safeMutex.setMutex(dataSynchAccessorRead,CODE_AT_LINE); + //} + FD_SET(sock, &set); + int i = select((int) sock + 1, &set, NULL, NULL, &tv); + safeMutex.ReleaseLock(); + + if (i < 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s] error while selecting socket data, err = %d, error = %s\n", __FILE__, __FUNCTION__, i, getLastSocketErrorFormattedText().c_str()); + printf("In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s\n", __FILE__, __FUNCTION__, __LINE__, i, getLastSocketErrorFormattedText().c_str()); + } + + bool result = (i == 1); + //if(result == false) { + // SystemFlags::OutputDebug(SystemFlags::debugError,"SOCKET DISCONNECTED In [%s::%s Line: %d] i = %d sock = %d\n",__FILE__,__FUNCTION__,__LINE__,i,sock); + //} + return result; + } + + inline bool Socket::isWritable(struct timeval *timeVal, bool lockMutex) { + if (isSocketValid() == false) return false; + + struct timeval tv; + if (timeVal != NULL) { + tv = *timeVal; + } else { + tv.tv_sec = 0; + tv.tv_usec = 0; + } + + fd_set set; + FD_ZERO(&set); + + Mutex *lockMutexObj = (lockMutex == true ? dataSynchAccessorWrite : NULL); + MutexSafeWrapper safeMutex(lockMutexObj, CODE_AT_LINE); + // MutexSafeWrapper safeMutex(NULL,CODE_AT_LINE); + // if(lockMutex == true) { + // safeMutex.setMutex(dataSynchAccessorWrite,CODE_AT_LINE); + // } + FD_SET(sock, &set); + int i = select((int) sock + 1, NULL, &set, NULL, &tv); + safeMutex.ReleaseLock(); + + bool result = false; + if (i < 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s Line: %d] error while selecting socket data, err = %d, error = %s\n", __FILE__, __FUNCTION__, __LINE__, i, getLastSocketErrorFormattedText().c_str()); + + SystemFlags::OutputDebug(SystemFlags::debugError, "SOCKET DISCONNECTED In [%s::%s Line: %d] error while selecting socket data, err = %d, error = %s\n", __FILE__, __FUNCTION__, __LINE__, i, getLastSocketErrorFormattedText().c_str()); + } else if (i == 0) { + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] TIMEOUT while selecting socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,i,getLastSocketErrorFormattedText().c_str()); + // Assume we are still connected, write buffer could be very busy + result = true; + if (difftime(time(NULL), lastSocketError) > 1) { + lastSocketError = time(NULL); + SystemFlags::OutputDebug(SystemFlags::debugError, "SOCKET WRITE TIMEOUT In [%s::%s Line: %d] i = %d sock = %d [%s]\n", __FILE__, __FUNCTION__, __LINE__, i, sock, ipAddress.c_str()); + } + } else { + result = true; + } + + //return (i == 1 && FD_ISSET(sock, &set)); + return result; + } + + bool Socket::isConnected() { + if (isSocketValid() == false) return false; + + // MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); + // if(this->inSocketDestructor == true) { + // SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); + // return false; + // } + // inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); + + //if the socket is not writable then it is not conencted + if (isWritable(NULL, true) == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s Line: %d] ERROR isWritable failed.\n", __FILE__, __FUNCTION__, __LINE__); + return false; + } + //if the socket is readable it is connected if we can read a byte from it + if (isReadable(true)) { + char tmp = 0; + int peekDataBytes = 1; + int lastSocketError = 0; + + int err = peek(&tmp, peekDataBytes, false, &lastSocketError); + //if(err <= 0 && err != PLATFORM_SOCKET_TRY_AGAIN) { + //if(err <= 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { + //if((err < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) || (err == 0 && peekDataBytes != 0) || + // ((err == 0 || err == -1) && peekDataBytes == 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN)) { + if ((err < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) || (err == 0 && peekDataBytes != 0)) { + //printf("IsConnected socket has disconnected sock = %d err = %d lastSocketError = %d\n",sock,err,lastSocketError); + if (err == 0) { + printf("IsConnected socket has disconnected sock = %d err = %d lastSocketError = %d\n", sock, err, lastSocketError); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s Line: %d] ERROR Peek failed, err = %d for socket: %d, error = %s, lastSocketError = %d\n", __FILE__, __FUNCTION__, __LINE__, err, sock, getLastSocketErrorFormattedText().c_str(), lastSocketError); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "[%s::%s Line: %d] ERROR Peek failed, err = %d for socket: %d, error = %s, lastSocketError = %d\n", __FILE__, __FUNCTION__, __LINE__, err, sock, getLastSocketErrorFormattedText().c_str(), lastSocketError); + if (SystemFlags::VERBOSE_MODE_ENABLED) SystemFlags::OutputDebug(SystemFlags::debugError, "SOCKET DISCONNECTED In [%s::%s Line: %d] ERROR Peek failed, err = %d for socket: %d, error = %s, lastSocketError = %d\n", __FILE__, __FUNCTION__, __LINE__, err, sock, getLastSocketErrorFormattedText().c_str(), lastSocketError); + return false; + } + if (isSocketValid() == false) return false; + } + + //otherwise the socket is connected + return true; + } + + string Socket::getHostName() { + if (Socket::host_name == "") { + const int strSize = 257; + char hostname[strSize] = ""; + int result = gethostname(hostname, strSize); + if (result == 0) { + Socket::host_name = (hostname[0] != '\0' ? hostname : ""); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] result = %d, error = %s\n", __FILE__, __FUNCTION__, __LINE__, result, getLastSocketErrorText()); + } + } + return Socket::host_name; + } + + string Socket::getIp() { + hostent* info = gethostbyname(getHostName().c_str()); + unsigned char* address; + + if (info == NULL) { + throw megaglest_runtime_error("Error getting host by name"); + } + + address = reinterpret_cast(info->h_addr_list[0]); + + if (address == NULL) { + throw megaglest_runtime_error("Error getting host ip"); + } + + return + intToStr(address[0]) + "." + + intToStr(address[1]) + "." + + intToStr(address[2]) + "." + + intToStr(address[3]); + } + + void Socket::throwException(string str) { + string msg = str + " " + getLastSocketErrorFormattedText(); + throw megaglest_runtime_error(msg); + } + + // =============================================== + // class ClientSocket + // =============================================== + + ClientSocket::ClientSocket() : Socket() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + stopBroadCastClientThread(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + ClientSocket::~ClientSocket() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + stopBroadCastClientThread(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void ClientSocket::stopBroadCastClientThread() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (broadCastClientThread != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + broadCastClientThread->shutdownAndWait(); + delete broadCastClientThread; + broadCastClientThread = NULL; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void ClientSocket::startBroadCastClientThread(DiscoveredServersInterface *cb) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + ClientSocket::stopBroadCastClientThread(); + + static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); + broadCastClientThread = new BroadCastClientSocketThread(cb); + broadCastClientThread->setUniqueID(mutexOwnerId); + broadCastClientThread->start(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void ClientSocket::discoverServers(DiscoveredServersInterface *cb) { + ClientSocket::startBroadCastClientThread(cb); + } + + void ClientSocket::connect(const Ip &ip, int port) { + sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(ip.getString().c_str()); + addr.sin_port = htons(port); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "Connecting to host [%s] on port = %d\n", ip.getString().c_str(), port); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Connecting to host [%s] on port = %d\n", ip.getString().c_str(), port); + + connectedIpAddress = ""; + int err = ::connect(sock, reinterpret_cast(&addr), sizeof(addr)); + if (err < 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] #2 Error connecting socket for IP: %s for Port: %d err = %d error = %s\n", __FILE__, __FUNCTION__, __LINE__, ip.getString().c_str(), port, err, getLastSocketErrorFormattedText().c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] #2 Error connecting socket for IP: %s for Port: %d err = %d error = %s\n", __FILE__, __FUNCTION__, __LINE__, ip.getString().c_str(), port, err, getLastSocketErrorFormattedText().c_str()); + + int lastSocketError = getLastSocketError(); + if (lastSocketError == PLATFORM_SOCKET_INPROGRESS || + lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) { + fd_set myset; + struct timeval tv; + int valopt = 0; + socklen_t lon = 0; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] PLATFORM_SOCKET_INPROGRESS in connect() - selecting\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] PLATFORM_SOCKET_INPROGRESS in connect() - selecting\n", __FILE__, __FUNCTION__, __LINE__); + + do { + tv.tv_sec = 10; + tv.tv_usec = 0; + + FD_ZERO(&myset); + FD_SET(sock, &myset); + + { + MutexSafeWrapper safeMutex(dataSynchAccessorRead, CODE_AT_LINE); + err = select((int) sock + 1, NULL, &myset, NULL, &tv); + lastSocketError = getLastSocketError(); + //safeMutex.ReleaseLock(); + } + + if (err < 0 && lastSocketError != PLATFORM_SOCKET_INTERRUPTED) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] Error connecting %s\n", __FILE__, __FUNCTION__, __LINE__, getLastSocketErrorFormattedText().c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Error connecting %s\n", __FILE__, __FUNCTION__, __LINE__, getLastSocketErrorFormattedText().c_str()); + + break; + } else if (err > 0) { + //else if(FD_ISSET(sock, &myset)) { + // Socket selected for write + lon = sizeof(valopt); +#ifndef WIN32 + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*) (&valopt), &lon) < 0) +#else + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *) (&valopt), &lon) < 0) +#endif + { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] Error in getsockopt() %s\n", __FILE__, __FUNCTION__, __LINE__, getLastSocketErrorFormattedText().c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Error in getsockopt() %s\n", __FILE__, __FUNCTION__, __LINE__, getLastSocketErrorFormattedText().c_str()); + break; + } + // Check the value returned... + if (valopt) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] Error in delayed connection() %d - [%s]\n", __FILE__, __FUNCTION__, __LINE__, valopt, strerror(valopt)); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Error in delayed connection() %d - [%s]\n", __FILE__, __FUNCTION__, __LINE__, valopt, strerror(valopt)); + break; + } + + errno = 0; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] Apparent recovery for connection sock = %d, err = %d\n", __FILE__, __FUNCTION__, __LINE__, sock, err); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Apparent recovery for connection sock = " PLATFORM_SOCKET_FORMAT_TYPE ", err = %d\n", __FILE__, __FUNCTION__, __LINE__, sock, err); + + break; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] Timeout in select() - Cancelling!\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Timeout in select() - Cancelling!\n", __FILE__, __FUNCTION__, __LINE__); + + disconnectSocket(); + break; + } + } while (1); + } + + if (err < 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] Before END sock = %d, err = %d, error = %s\n", __FILE__, __FUNCTION__, __LINE__, sock, err, getLastSocketErrorFormattedText().c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Before END sock = " PLATFORM_SOCKET_FORMAT_TYPE ", err = %d, error = %s\n", __FILE__, __FUNCTION__, __LINE__, sock, err, getLastSocketErrorFormattedText().c_str()); + disconnectSocket(); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] Valid recovery for connection sock = %d, err = %d, error = %s\n", __FILE__, __FUNCTION__, __LINE__, sock, err, getLastSocketErrorFormattedText().c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Valid recovery for connection sock = " PLATFORM_SOCKET_FORMAT_TYPE ", err = %d, error = %s\n", __FILE__, __FUNCTION__, __LINE__, sock, err, getLastSocketErrorFormattedText().c_str()); + connectedIpAddress = ip.getString(); + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "Connected to host [%s] on port = %d sock = %d err = %d", ip.getString().c_str(), port, sock, err); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Connected to host [%s] on port = %d sock = " PLATFORM_SOCKET_FORMAT_TYPE " err = %d", ip.getString().c_str(), port, sock, err); + connectedIpAddress = ip.getString(); + } + } + + //======================================================================= + // Function : discovery response thread + // Description: Runs in its own thread to listen for broadcasts from + // other servers + // + BroadCastClientSocketThread::BroadCastClientSocketThread(DiscoveredServersInterface *cb) : BaseThread() { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + discoveredServersCB = cb; + uniqueID = "BroadCastClientSocketThread"; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + //======================================================================= + // Function : broadcast thread + // Description: Runs in its own thread to send out a broadcast to the local network + // the current broadcast message is + // + void BroadCastClientSocketThread::execute() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + RunningStatusSafeWrapper runningStatus(this); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "Broadcast Client thread is running\n"); + + std::vector foundServers; + + short port; // The port for the broadcast. + struct sockaddr_in bcSender; // local socket address for the broadcast. + struct sockaddr_in bcaddr; // The broadcast address for the receiver. + PLATFORM_SOCKET bcfd; // The file descriptor used for the broadcast. + //bool one = true; // Parameter for "setscokopt". + socklen_t alen = 0; + + port = htons(Socket::getBroadCastPort()); + + // Prepare to receive the broadcast. + bcfd = socket(AF_INET, SOCK_DGRAM, 0); + if (bcfd <= 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "socket failed: %s\n", Socket::getLastSocketErrorFormattedText().c_str()); + } else { + // Create the address we are receiving on. + memset((char*) &bcaddr, 0, sizeof(bcaddr)); + bcaddr.sin_family = AF_INET; + bcaddr.sin_addr.s_addr = htonl(INADDR_ANY); + bcaddr.sin_port = port; + + int val = 1; +#ifndef WIN32 + int opt_result = setsockopt(bcfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); +#else + int opt_result = setsockopt(bcfd, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val)); +#endif + if (::bind(bcfd, (struct sockaddr *)&bcaddr, sizeof(bcaddr)) < 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "bind failed: %s opt_result = %d\n", Socket::getLastSocketErrorFormattedText().c_str(), opt_result); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] opt_result = %d\n", __FILE__, __FUNCTION__, __LINE__, opt_result); + + Socket::setBlock(false, bcfd); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + try { + char buff[10025] = ""; // Buffers the data to be broadcasted. + // Keep getting packets forever. + for (time_t elapsed = time(NULL); difftime((long int) time(NULL), elapsed) <= 5; ) { + alen = sizeof(struct sockaddr); + int nb = 0;// The number of bytes read. + bool gotData = (nb = recvfrom(bcfd, buff, 10024, 0, (struct sockaddr *) &bcSender, &alen)) > 0; + if (nb >= 0) { + buff[nb] = 0; + } + + //printf("Broadcasting client nb = %d buff [%s] gotData = %d\n",nb,buff,gotData); + + if (gotData == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "recvfrom failed: %s\n", Socket::getLastSocketErrorFormattedText().c_str()); + } else { + //string fromIP = inet_ntoa(bcSender.sin_addr); + char szHostFrom[100] = ""; + Ip::Inet_NtoA(SockAddrToUint32(&bcSender.sin_addr), szHostFrom); + //printf("Client szHostFrom [%s]\n",szHostFrom); + + string fromIP = szHostFrom; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "broadcast message received: [%s] from: [%s]\n", buff, fromIP.c_str()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "Client got broadcast from server: [%s] data [%s]\n", fromIP.c_str(), buff); + + int serverGamePort = Socket::getBroadCastPort(); + vector paramPartPortsTokens; + Tokenize(buff, paramPartPortsTokens, ":"); + if (paramPartPortsTokens.size() >= 3 && paramPartPortsTokens[2].length() > 0) { + serverGamePort = strToInt(paramPartPortsTokens[2]); + } + + if (std::find(foundServers.begin(), foundServers.end(), fromIP) == foundServers.end()) { + foundServers.push_back(fromIP + ":" + intToStr(serverGamePort)); + } + + // For now break as soon as we find a server + break; + } + + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } + sleep(100); // send out broadcast every 1 seconds + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } + } + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + } catch (...) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] UNKNOWN Error\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] unknown error\n", __FILE__, __FUNCTION__, __LINE__); + } + } + } + +#ifndef WIN32 + if (bcfd >= 0) ::close(bcfd); + bcfd = -1; +#else + if (bcfd != INVALID_SOCKET) ::closesocket(bcfd); + bcfd = INVALID_SOCKET; +#endif + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + // Here we callback into the implementer class + if (getQuitStatus() == false && discoveredServersCB != NULL) { + discoveredServersCB->DiscoveredServers(foundServers); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "Broadcast Client thread is exiting\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + // =============================================== + // class ServerSocket + // =============================================== + + ServerSocket::ServerSocket(bool basicMode) : Socket() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] basicMode = %d\n", __FILE__, __FUNCTION__, __LINE__, basicMode); + + this->basicMode = basicMode; + this->bindSpecificAddress = ""; + //printf("SERVER SOCKET CONSTRUCTOR\n"); + + boundPort = 0; + portBound = false; + broadCastThread = NULL; + if (this->basicMode == false) { + UPNP_Tools::enabledUPNP = false; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + ServerSocket::~ServerSocket() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //printf("In [%s::%s] Line: %d UPNP_Tools::enabledUPNP = %d\n",__FILE__,__FUNCTION__,__LINE__,UPNP_Tools::enabledUPNP); + + stopBroadCastThread(); + + if (this->basicMode == false) { + MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread, CODE_AT_LINE); + if (ServerSocket::upnpdiscoverThread != NULL) { + + ServerSocket::cancelUpnpdiscoverThread = true; + SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); + ServerSocket::upnpdiscoverThread = NULL; + ServerSocket::cancelUpnpdiscoverThread = false; + } + safeMutexUPNP.ReleaseLock(); + if (UPNP_Tools::enabledUPNP) { + UPNP_Tools::NETremRedirects(this->getExternalPort()); + } + + MutexSafeWrapper safeMutexUPNP1(&UPNP_Tools::mutexUPNP, CODE_AT_LINE); + if (urls.controlURL && urls.ipcondescURL && urls.controlURL_CIF) { + FreeUPNPUrls(&urls); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + safeMutexUPNP1.ReleaseLock(); + } + } + + void ServerSocket::stopBroadCastThread() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //printf("Stopping broadcast thread [%p]\n",broadCastThread); + + if (broadCastThread != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + //printf("Stopping broadcast thread [%p] - A\n",broadCastThread); + + if (broadCastThread->canShutdown(false) == true) { + sleep(0); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + //printf("Stopping broadcast thread [%p] - B\n",broadCastThread); + + if (broadCastThread->shutdownAndWait() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + delete broadCastThread; + + //printf("Stopping broadcast thread [%p] - C\n",broadCastThread); + } + broadCastThread = NULL; + //printf("Stopping broadcast thread [%p] - D\n",broadCastThread); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void ServerSocket::startBroadCastThread() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + stopBroadCastThread(); + + broadCastThread = new BroadCastSocketThread(this->boundPort); + + //printf("Start broadcast thread [%p]\n",broadCastThread); + + static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); + broadCastThread->setUniqueID(mutexOwnerId); + broadCastThread->start(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void ServerSocket::resumeBroadcast() { + if (broadCastThread != NULL) { + broadCastThread->setPauseBroadcast(false); + } + } + void ServerSocket::pauseBroadcast() { + if (broadCastThread != NULL) { + broadCastThread->setPauseBroadcast(true); + } + } + + bool ServerSocket::isBroadCastThreadRunning() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + bool isThreadRunning = (broadCastThread != NULL && broadCastThread->getRunningStatus() == true); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] isThreadRunning = %d\n", __FILE__, __FUNCTION__, __LINE__, isThreadRunning); + + return isThreadRunning; + } + + void ServerSocket::bind(int port) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d port = %d, portBound = %d START\n", __FILE__, __FUNCTION__, __LINE__, port, portBound); + + boundPort = port; + + if (isSocketValid() == false) { + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (isSocketValid() == false) { + throwException("Error creating socket"); + } + setBlock(false); + } + + //sockaddr structure + sockaddr_in addr; + addr.sin_family = AF_INET; + if (this->bindSpecificAddress != "") { + addr.sin_addr.s_addr = inet_addr(this->bindSpecificAddress.c_str()); + } else { + addr.sin_addr.s_addr = INADDR_ANY; + } + addr.sin_port = htons(port); + addr.sin_zero[0] = 0; + + int val = 1; + +#ifndef WIN32 + int opt_result = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); +#else + int opt_result = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val)); +#endif + + int err = ::bind(sock, reinterpret_cast(&addr), sizeof(addr)); + if (err < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s] Error binding socket sock = " PLATFORM_SOCKET_FORMAT_TYPE ", address [%s] port = %d err = %d, error = %s opt_result = %d\n", __FILE__, __FUNCTION__, sock, this->bindSpecificAddress.c_str(), port, err, getLastSocketErrorFormattedText().c_str(), opt_result); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "%s", szBuf); + + snprintf(szBuf, 8096, "Error binding socket sock = " PLATFORM_SOCKET_FORMAT_TYPE ", address [%s] port = %d err = %d, error = %s\n", sock, this->bindSpecificAddress.c_str(), port, err, getLastSocketErrorFormattedText().c_str()); + throw megaglest_runtime_error(szBuf); + } + portBound = true; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d port = %d, portBound = %d END\n", __FILE__, __FUNCTION__, __LINE__, port, portBound); + } + + void ServerSocket::disconnectSocket() { + Socket::disconnectSocket(); + portBound = false; + } + + void ServerSocket::listen(int connectionQueueSize) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s] Line: %d connectionQueueSize = %d\n", __FILE__, __FUNCTION__, __LINE__, connectionQueueSize); + + if (connectionQueueSize > 0) { + if (isSocketValid() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (isSocketValid() == false) { + throwException("Error creating socket"); + } + setBlock(false); + } + + if (portBound == false) { + bind(boundPort); + } + + int err = ::listen(sock, connectionQueueSize); + if (err < 0) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s] Error listening socket sock = " PLATFORM_SOCKET_FORMAT_TYPE ", err = %d, error = %s\n", __FILE__, __FUNCTION__, sock, err, getLastSocketErrorFormattedText().c_str()); + throwException(szBuf); + } + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + disconnectSocket(); + } + + if (this->basicMode == false) { + if (connectionQueueSize > 0) { + if (isBroadCastThreadRunning() == false) { + startBroadCastThread(); + } else { + resumeBroadcast(); + } + } else { + pauseBroadcast(); + } + } + } + + Socket *ServerSocket::accept(bool errorOnFail) { + if (isSocketValid() == false) { + if (errorOnFail == true) { + throwException("socket is invalid!"); + } else { + return NULL; + } + } + + PLATFORM_SOCKET newSock = 0; + char client_host[100] = ""; + //const int max_attempts = 100; + //for(int attempt = 0; attempt < max_attempts; ++attempt) { + struct sockaddr_in cli_addr; + socklen_t clilen = sizeof(cli_addr); + client_host[0] = '\0'; + MutexSafeWrapper safeMutex(dataSynchAccessorRead, CODE_AT_LINE); + newSock = ::accept(sock, (struct sockaddr *) &cli_addr, &clilen); + safeMutex.ReleaseLock(); + + if (isSocketValid(&newSock) == false) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Error accepting socket connection sock = " PLATFORM_SOCKET_FORMAT_TYPE ", err = " PLATFORM_SOCKET_FORMAT_TYPE ", error = %s\n", __FILE__, __FUNCTION__, __LINE__, sock, newSock, getLastSocketErrorFormattedText().c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] %s\n", __FILE__, __FUNCTION__, __LINE__, szBuf); + + int lastSocketError = getLastSocketError(); + if (lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) { + //if(attempt+1 >= max_attempts) { + // return NULL; //} //else { sleep(0); //} } - } - } - } + if (errorOnFail == true) { + throwException(szBuf); + } else { +#ifndef WIN32 + ::close(newSock); + newSock = -1; +#else + ::closesocket(newSock); + newSock = INVALID_SOCKET; +#endif - if(bytesReceived <= 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] bytesReceived = %d\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived); - - int iErr = getLastSocketError(); - disconnectSocket(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] DISCONNECTED SOCKET error while receiving socket data, bytesReceived = %d, error = %s, dataSize = %d, tryReceiveUntilDataSizeMet = %d\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived,getLastSocketErrorFormattedText(&iErr).c_str(),dataSize,tryReceiveUntilDataSizeMet); - } - else if(tryReceiveUntilDataSizeMet == true && bytesReceived < dataSize) { - int newBufferSize = (dataSize - (int)bytesReceived); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING, attempting to receive MORE data, bytesReceived = %d, dataSize = %d, newBufferSize = %d\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived,dataSize,newBufferSize); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nIn [%s::%s Line: %d] WARNING, attempting to receive MORE data, bytesReceived = %d, dataSize = %d, newBufferSize = %d\n",__FILE__,__FUNCTION__,__LINE__,(int)bytesReceived,dataSize,newBufferSize); - - char *dataAsCharPointer = reinterpret_cast(data); - int additionalBytes = receive(&dataAsCharPointer[bytesReceived], newBufferSize, tryReceiveUntilDataSizeMet); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING, additionalBytes = %d\n",__FILE__,__FUNCTION__,__LINE__,additionalBytes); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nIn [%s::%s Line: %d] WARNING, additionalBytes = %d\n",__FILE__,__FUNCTION__,__LINE__,additionalBytes); - - if(additionalBytes > 0) { - bytesReceived += additionalBytes; - } - else { - //throw megaglest_runtime_error("additionalBytes == " + intToStr(additionalBytes)); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] additionalBytes == %d\n",__FILE__,__FUNCTION__,__LINE__,additionalBytes); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\nIn [%s::%s Line: %d] additionalBytes == %d\n",__FILE__,__FUNCTION__,__LINE__,additionalBytes); - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] additionalBytes == %d\n",__FILE__,__FUNCTION__,__LINE__,additionalBytes); - - int iErr = getLastSocketError(); - disconnectSocket(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] DISCONNECTED SOCKET error while receiving socket data, bytesReceived = %d, error = %s, dataSize = %d, tryReceiveUntilDataSizeMet = %d\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived,getLastSocketErrorFormattedText(&iErr).c_str(),dataSize,tryReceiveUntilDataSizeMet); - } - } - return static_cast(bytesReceived); -} - -SafeSocketBlockToggleWrapper::SafeSocketBlockToggleWrapper(Socket *socket, bool toggle) { - this->socket = socket; - - if(this->socket != NULL) { - this->originallyBlocked = socket->getBlock(); - this->newBlocked = toggle; - - if(this->originallyBlocked != this->newBlocked) { - socket->setBlock(this->newBlocked); - } - } - else { - this->originallyBlocked = false; - this->newBlocked = false; - } -} - -void SafeSocketBlockToggleWrapper::Restore() { - if(this->socket != NULL) { - if(this->originallyBlocked != this->newBlocked) { - socket->setBlock(this->originallyBlocked); - this->newBlocked = this->originallyBlocked; - } - } -} - -SafeSocketBlockToggleWrapper::~SafeSocketBlockToggleWrapper() { - Restore(); -} - -int Socket::peek(void *data, int dataSize,bool mustGetData,int *pLastSocketError) { - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) chrono.start(); - - int lastSocketError = 0; - int err = 0; - if(isSocketValid() == true) { - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - -// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); -// if(this->inSocketDestructor == true) { -// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); -// return -1; -// } -// inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); -// safeMutexSocketDestructorFlag.ReleaseLock(); - - //MutexSafeWrapper safeMutex(&dataSynchAccessor,CODE_AT_LINE + "_" + intToStr(sock) + "_" + intToStr(dataSize)); - - - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - if(isSocketValid() == true) { - MutexSafeWrapper safeMutex(dataSynchAccessorRead,CODE_AT_LINE); -// Chrono recvTimer(true); - SafeSocketBlockToggleWrapper safeUnblock(this, false); - errno = 0; - err = recv(sock, reinterpret_cast(data), dataSize, MSG_PEEK); - lastSocketError = getLastSocketError(); - if(pLastSocketError != NULL) { - *pLastSocketError = lastSocketError; - } - safeUnblock.Restore(); - -// if(recvTimer.getMillis() > 1000 || (err <= 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN)) { -// printf("#1 PEEK err = %d lastSocketError = %d ms: %lld\n",err,lastSocketError,(long long int)recvTimer.getMillis()); - - //if(err != dataSize) { - // printf("#1 PEEK err = %d lastSocketError = %d\n",err,lastSocketError); - //} - -// } - safeMutex.ReleaseLock(); - } - //safeMutex.ReleaseLock(); - - //printf("Peek #1 err = %d\n",err); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] SOCKET appears to be invalid [%d]\n",__FILE__,__FUNCTION__,__LINE__,sock); - } - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - - if(err < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] ERROR PEEKING SOCKET DATA error while sending socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,err,getLastSocketErrorFormattedText().c_str()); - disconnectSocket(); - } - else if(err < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN && mustGetData == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 ERROR EAGAIN during peek, trying again...\n",__FILE__,__FUNCTION__,__LINE__); - - //printf("Peek #2 err = %d\n",err); - - Chrono chronoElapsed(true); - const int MAX_PEEK_WAIT_SECONDS = 3; - time_t tStartTimer = time(NULL); - while((err < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) && - isSocketValid() == true && - (difftime((long int)time(NULL),tStartTimer) <= MAX_PEEK_WAIT_SECONDS)) { -/* - if(isConnected() == false) { - int iErr = getLastSocketError(); - disconnectSocket(); - break; - } -*/ - if(Socket::isReadable(true) == true || chronoElapsed.getMillis() % 100 == 0) { - -// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); -// if(this->inSocketDestructor == true) { -// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); -// return -1; -// } -// inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); -// safeMutexSocketDestructorFlag.ReleaseLock(); - - //MutexSafeWrapper safeMutex(&dataSynchAccessor,CODE_AT_LINE + "_" + intToStr(sock) + "_" + intToStr(dataSize)); - MutexSafeWrapper safeMutex(dataSynchAccessorRead,CODE_AT_LINE); - -// Chrono recvTimer(true); - SafeSocketBlockToggleWrapper safeUnblock(this, false); - errno = 0; - err = recv(sock, reinterpret_cast(data), dataSize, MSG_PEEK); - lastSocketError = getLastSocketError(); - if(pLastSocketError != NULL) { - *pLastSocketError = lastSocketError; + return NULL; } - safeUnblock.Restore(); -// if(recvTimer.getMillis() > 1000 || (err <= 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN)) { -// printf("#2 PEEK err = %d lastSocketError = %d ms: %lld\n",err,lastSocketError,(long long int)recvTimer.getMillis()); -// } - - //printf("Socket peek delayed checking for sock = %d err = %d\n",sock,err); - - safeMutex.ReleaseLock(); - - if(err == 0 || err == PLATFORM_SOCKET_TRY_AGAIN) { - sleep(0); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 EAGAIN during peek, trying again returned: %d\n",__FILE__,__FUNCTION__,__LINE__,err); - } - //else { - //printf("Socket peek delayed [NOT READABLE] checking for sock = %d err = %d\n",sock,err); - //} - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - } - else if (err == 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 SOCKET appears to be invalid [%d] lastSocketError [%d] err [%d] mustGetData [%d] dataSize [%d]\n",__FILE__,__FUNCTION__,__LINE__,sock,lastSocketError,err,mustGetData,dataSize); - } - - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - - if(err < 0 || (err == 0 && dataSize != 0) || - ((err == 0 || err == -1) && dataSize == 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN)) { - //printf("** #1 Socket peek error for sock = %d err = %d lastSocketError = %d\n",sock,err,lastSocketError); - - int iErr = lastSocketError; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] DISCONNECTING SOCKET for socket [%d], err = %d, dataSize = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,sock,err,dataSize,getLastSocketErrorFormattedText(&iErr).c_str()); - //printf("Peek #3 err = %d\n",err); - //lastSocketError = getLastSocketError(); - if(mustGetData == true || lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { - printf("** #2 Socket peek error for sock = %d err = %d lastSocketError = %d mustGetData = %d\n",sock,err,lastSocketError,mustGetData); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] DISCONNECTING SOCKET for socket [%d], err = %d, dataSize = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,sock,err,dataSize,getLastSocketErrorFormattedText(&iErr).c_str()); - - if(err == 0) { - printf("** LAST CHANCE for disconnection check for sock = %d\n",sock); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"** LAST CHANCE for disconnection check for sock = %d\n",sock); - - MutexSafeWrapper safeMutex(dataSynchAccessorRead,CODE_AT_LINE); - SafeSocketBlockToggleWrapper safeUnblock(this, false); - errno = 0; - int second_err = recv(sock, reinterpret_cast(data), dataSize, MSG_PEEK); - safeUnblock.Restore(); - safeMutex.ReleaseLock(); - - if(second_err == 0 || second_err < 0) { - printf("** Disconnecting sock = %d\n",sock); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"** Disconnecting sock = %d\n",sock); - - disconnectSocket(); - } + } else { + Ip::Inet_NtoA(SockAddrToUint32((struct sockaddr *)&cli_addr), client_host); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] got connection, newSock = %d client_host [%s]\n", __FILE__, __FUNCTION__, __LINE__, newSock, client_host); } - else { - printf("** Disconnecting sock = %d\n",sock); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"** Disconnecting sock = %d\n",sock); - - disconnectSocket(); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] DISCONNECTED SOCKET error while peeking socket data for socket [%d], err = %d, dataSize = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,sock,err,dataSize,getLastSocketErrorFormattedText(&iErr).c_str()); - } - } - - return static_cast(err); -} - -bool Socket::getBlock() { - bool blocking = true; - - // don't waste time if the socket is invalid - if(isSocketValid(&sock) == false) { - return blocking; - } - -//#ifndef WIN32 -// int currentFlags = fcntl(sock, F_GETFL); -// blocking = !((currentFlags & O_NONBLOCK) == O_NONBLOCK); -//#else - blocking = this->isSocketBlocking; -//#endif - return blocking; -} - -void Socket::setBlock(bool block){ - setBlock(block,this->sock); - this->isSocketBlocking = block; -} - -void Socket::setBlock(bool block, PLATFORM_SOCKET socket) { - // don't waste time if the socket is invalid - if(isSocketValid(&socket) == false) { - return; - } + if (isIPAddressBlocked((client_host[0] != '\0' ? client_host : "")) == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] BLOCKING connection, newSock = %d client_host [%s]\n", __FILE__, __FUNCTION__, __LINE__, newSock, client_host); #ifndef WIN32 - int currentFlags = fcntl(socket, F_GETFL); - if(currentFlags < 0) { - currentFlags = 0; - } - if(block == true) { - currentFlags &= (~O_NONBLOCK); - } - else { - currentFlags |= O_NONBLOCK; - } - int err= fcntl(socket, F_SETFL, currentFlags); + ::close(newSock); + newSock = -1; #else - u_long iMode= !block; - int err= ioctlsocket(socket, FIONBIO, &iMode); + ::closesocket(newSock); + newSock = INVALID_SOCKET; #endif - if(err < 0) { - throwException("Error setting I/O mode for socket"); - } -} - -inline bool Socket::isReadable(bool lockMutex) { - if(isSocketValid() == false) return false; - - struct timeval tv; - tv.tv_sec= 0; - tv.tv_usec= 0; - - fd_set set; - FD_ZERO(&set); - - Mutex *lockMutexObj = (lockMutex == true ? dataSynchAccessorRead : NULL); - MutexSafeWrapper safeMutex(lockMutexObj,CODE_AT_LINE); - //if(lockMutex == true) { - // safeMutex.setMutex(dataSynchAccessorRead,CODE_AT_LINE); - //} - FD_SET(sock, &set); - int i = select((int)sock + 1, &set, NULL, NULL, &tv); - safeMutex.ReleaseLock(); - - if(i < 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] error while selecting socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,i,getLastSocketErrorFormattedText().c_str()); - printf("In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s\n",__FILE__,__FUNCTION__,__LINE__,i,getLastSocketErrorFormattedText().c_str()); - } - - bool result = (i == 1); - //if(result == false) { - // SystemFlags::OutputDebug(SystemFlags::debugError,"SOCKET DISCONNECTED In [%s::%s Line: %d] i = %d sock = %d\n",__FILE__,__FUNCTION__,__LINE__,i,sock); - //} - return result; -} - -inline bool Socket::isWritable(struct timeval *timeVal, bool lockMutex) { - if(isSocketValid() == false) return false; - - struct timeval tv; - if(timeVal != NULL) { - tv = *timeVal; - } - else { - tv.tv_sec= 0; - tv.tv_usec= 0; - } - - fd_set set; - FD_ZERO(&set); - - Mutex *lockMutexObj = (lockMutex == true ? dataSynchAccessorWrite : NULL); - MutexSafeWrapper safeMutex(lockMutexObj,CODE_AT_LINE); -// MutexSafeWrapper safeMutex(NULL,CODE_AT_LINE); -// if(lockMutex == true) { -// safeMutex.setMutex(dataSynchAccessorWrite,CODE_AT_LINE); -// } - FD_SET(sock, &set); - int i = select((int)sock + 1, NULL, &set, NULL, &tv); - safeMutex.ReleaseLock(); - - bool result = false; - if(i < 0 ) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] error while selecting socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,i,getLastSocketErrorFormattedText().c_str()); - - SystemFlags::OutputDebug(SystemFlags::debugError,"SOCKET DISCONNECTED In [%s::%s Line: %d] error while selecting socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,i,getLastSocketErrorFormattedText().c_str()); - } - else if(i == 0) { - //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] TIMEOUT while selecting socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,i,getLastSocketErrorFormattedText().c_str()); - // Assume we are still connected, write buffer could be very busy - result = true; - if(difftime(time(NULL),lastSocketError) > 1) { - lastSocketError = time(NULL); - SystemFlags::OutputDebug(SystemFlags::debugError,"SOCKET WRITE TIMEOUT In [%s::%s Line: %d] i = %d sock = %d [%s]\n",__FILE__,__FUNCTION__,__LINE__,i,sock,ipAddress.c_str()); - } - } - else { - result = true; - } - - //return (i == 1 && FD_ISSET(sock, &set)); - return result; -} - -bool Socket::isConnected() { - if(isSocketValid() == false) return false; - -// MutexSafeWrapper safeMutexSocketDestructorFlag(&inSocketDestructorSynchAccessor,CODE_AT_LINE); -// if(this->inSocketDestructor == true) { -// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] this->inSocketDestructor == true\n",__FILE__,__FUNCTION__,__LINE__); -// return false; -// } -// inSocketDestructorSynchAccessor->setOwnerId(CODE_AT_LINE); - - //if the socket is not writable then it is not conencted - if(isWritable(NULL,true) == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] ERROR isWritable failed.\n",__FILE__,__FUNCTION__,__LINE__); - return false; - } - //if the socket is readable it is connected if we can read a byte from it - if(isReadable(true)) { - char tmp=0; - int peekDataBytes=1; - int lastSocketError=0; - - int err = peek(&tmp, peekDataBytes, false, &lastSocketError); - //if(err <= 0 && err != PLATFORM_SOCKET_TRY_AGAIN) { - //if(err <= 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { - //if((err < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) || (err == 0 && peekDataBytes != 0) || - // ((err == 0 || err == -1) && peekDataBytes == 0 && lastSocketError != 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN)) { - if((err < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) || (err == 0 && peekDataBytes != 0)) { - //printf("IsConnected socket has disconnected sock = %d err = %d lastSocketError = %d\n",sock,err,lastSocketError); - if(err == 0) { - printf("IsConnected socket has disconnected sock = %d err = %d lastSocketError = %d\n",sock,err,lastSocketError); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] ERROR Peek failed, err = %d for socket: %d, error = %s, lastSocketError = %d\n",__FILE__,__FUNCTION__,__LINE__,err,sock,getLastSocketErrorFormattedText().c_str(),lastSocketError); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] ERROR Peek failed, err = %d for socket: %d, error = %s, lastSocketError = %d\n",__FILE__,__FUNCTION__,__LINE__,err,sock,getLastSocketErrorFormattedText().c_str(),lastSocketError); - if(SystemFlags::VERBOSE_MODE_ENABLED) SystemFlags::OutputDebug(SystemFlags::debugError,"SOCKET DISCONNECTED In [%s::%s Line: %d] ERROR Peek failed, err = %d for socket: %d, error = %s, lastSocketError = %d\n",__FILE__,__FUNCTION__,__LINE__,err,sock,getLastSocketErrorFormattedText().c_str(),lastSocketError); - return false; - } - if (isSocketValid() == false) return false; - } - - //otherwise the socket is connected - return true; -} - -string Socket::getHostName() { - if(Socket::host_name == "") { - const int strSize= 257; - char hostname[strSize]=""; - int result = gethostname(hostname, strSize); - if(result == 0) { - Socket::host_name = (hostname[0] != '\0' ? hostname : ""); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] result = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,result,getLastSocketErrorText()); - } - } - return Socket::host_name; -} - -string Socket::getIp() { - hostent* info= gethostbyname(getHostName().c_str()); - unsigned char* address; - - if(info==NULL){ - throw megaglest_runtime_error("Error getting host by name"); - } - - address= reinterpret_cast(info->h_addr_list[0]); - - if(address==NULL){ - throw megaglest_runtime_error("Error getting host ip"); - } - - return - intToStr(address[0]) + "." + - intToStr(address[1]) + "." + - intToStr(address[2]) + "." + - intToStr(address[3]); -} - -void Socket::throwException(string str){ - string msg = str + " " + getLastSocketErrorFormattedText(); - throw megaglest_runtime_error(msg); -} - -// =============================================== -// class ClientSocket -// =============================================== - -ClientSocket::ClientSocket() : Socket() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - stopBroadCastClientThread(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -ClientSocket::~ClientSocket() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - stopBroadCastClientThread(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void ClientSocket::stopBroadCastClientThread() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(broadCastClientThread != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - broadCastClientThread->shutdownAndWait(); - delete broadCastClientThread; - broadCastClientThread = NULL; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void ClientSocket::startBroadCastClientThread(DiscoveredServersInterface *cb) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - ClientSocket::stopBroadCastClientThread(); - - static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); - broadCastClientThread = new BroadCastClientSocketThread(cb); - broadCastClientThread->setUniqueID(mutexOwnerId); - broadCastClientThread->start(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void ClientSocket::discoverServers(DiscoveredServersInterface *cb) { - ClientSocket::startBroadCastClientThread(cb); -} - -void ClientSocket::connect(const Ip &ip, int port) -{ - sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - - addr.sin_family= AF_INET; - addr.sin_addr.s_addr= inet_addr(ip.getString().c_str()); - addr.sin_port= htons(port); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Connecting to host [%s] on port = %d\n", ip.getString().c_str(),port); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("Connecting to host [%s] on port = %d\n", ip.getString().c_str(),port); - - connectedIpAddress = ""; - int err= ::connect(sock, reinterpret_cast(&addr), sizeof(addr)); - if(err < 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 Error connecting socket for IP: %s for Port: %d err = %d error = %s\n",__FILE__,__FUNCTION__,__LINE__,ip.getString().c_str(),port,err,getLastSocketErrorFormattedText().c_str()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] #2 Error connecting socket for IP: %s for Port: %d err = %d error = %s\n",__FILE__,__FUNCTION__,__LINE__,ip.getString().c_str(),port,err,getLastSocketErrorFormattedText().c_str()); - - int lastSocketError = getLastSocketError(); - if (lastSocketError == PLATFORM_SOCKET_INPROGRESS || - lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) { - fd_set myset; - struct timeval tv; - int valopt=0; - socklen_t lon=0; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] PLATFORM_SOCKET_INPROGRESS in connect() - selecting\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] PLATFORM_SOCKET_INPROGRESS in connect() - selecting\n",__FILE__,__FUNCTION__,__LINE__); - - do { - tv.tv_sec = 10; - tv.tv_usec = 0; - - FD_ZERO(&myset); - FD_SET(sock, &myset); - - { - MutexSafeWrapper safeMutex(dataSynchAccessorRead,CODE_AT_LINE); - err = select((int)sock + 1, NULL, &myset, NULL, &tv); - lastSocketError = getLastSocketError(); - //safeMutex.ReleaseLock(); - } - - if (err < 0 && lastSocketError != PLATFORM_SOCKET_INTERRUPTED) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Error connecting %s\n",__FILE__,__FUNCTION__,__LINE__,getLastSocketErrorFormattedText().c_str()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Error connecting %s\n",__FILE__,__FUNCTION__,__LINE__,getLastSocketErrorFormattedText().c_str()); - - break; - } - else if(err > 0) { - //else if(FD_ISSET(sock, &myset)) { - // Socket selected for write - lon = sizeof(valopt); -#ifndef WIN32 - if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0) -#else - if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)(&valopt), &lon) < 0) -#endif - { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Error in getsockopt() %s\n",__FILE__,__FUNCTION__,__LINE__,getLastSocketErrorFormattedText().c_str()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Error in getsockopt() %s\n",__FILE__,__FUNCTION__,__LINE__,getLastSocketErrorFormattedText().c_str()); - break; - } - // Check the value returned... - if(valopt) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Error in delayed connection() %d - [%s]\n",__FILE__,__FUNCTION__,__LINE__,valopt, strerror(valopt)); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Error in delayed connection() %d - [%s]\n",__FILE__,__FUNCTION__,__LINE__,valopt, strerror(valopt)); - break; - } - - errno = 0; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Apparent recovery for connection sock = %d, err = %d\n",__FILE__,__FUNCTION__,__LINE__,sock,err); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Apparent recovery for connection sock = " PLATFORM_SOCKET_FORMAT_TYPE ", err = %d\n",__FILE__,__FUNCTION__,__LINE__,sock,err); - - break; - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Timeout in select() - Cancelling!\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Timeout in select() - Cancelling!\n",__FILE__,__FUNCTION__,__LINE__); - - disconnectSocket(); - break; - } - } while (1); - } - - if(err < 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Before END sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,sock,err,getLastSocketErrorFormattedText().c_str()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Before END sock = " PLATFORM_SOCKET_FORMAT_TYPE ", err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,sock,err,getLastSocketErrorFormattedText().c_str()); - disconnectSocket(); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Valid recovery for connection sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,sock,err,getLastSocketErrorFormattedText().c_str()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Valid recovery for connection sock = " PLATFORM_SOCKET_FORMAT_TYPE ", err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,sock,err,getLastSocketErrorFormattedText().c_str()); - connectedIpAddress = ip.getString(); - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Connected to host [%s] on port = %d sock = %d err = %d", ip.getString().c_str(),port,sock,err); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Connected to host [%s] on port = %d sock = " PLATFORM_SOCKET_FORMAT_TYPE " err = %d", ip.getString().c_str(),port,sock,err); - connectedIpAddress = ip.getString(); - } -} - -//======================================================================= -// Function : discovery response thread -// Description: Runs in its own thread to listen for broadcasts from -// other servers -// -BroadCastClientSocketThread::BroadCastClientSocketThread(DiscoveredServersInterface *cb) : BaseThread() { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - discoveredServersCB = cb; - uniqueID = "BroadCastClientSocketThread"; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -//======================================================================= -// Function : broadcast thread -// Description: Runs in its own thread to send out a broadcast to the local network -// the current broadcast message is -// -void BroadCastClientSocketThread::execute() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - RunningStatusSafeWrapper runningStatus(this); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast Client thread is running\n"); - - std::vector foundServers; - - short port; // The port for the broadcast. - struct sockaddr_in bcSender; // local socket address for the broadcast. - struct sockaddr_in bcaddr; // The broadcast address for the receiver. - PLATFORM_SOCKET bcfd; // The file descriptor used for the broadcast. - //bool one = true; // Parameter for "setscokopt". - socklen_t alen=0; - - port = htons( Socket::getBroadCastPort() ); - - // Prepare to receive the broadcast. - bcfd = socket(AF_INET, SOCK_DGRAM, 0); - if( bcfd <= 0 ) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"socket failed: %s\n", Socket::getLastSocketErrorFormattedText().c_str()); - } - else { - // Create the address we are receiving on. - memset( (char*)&bcaddr, 0, sizeof(bcaddr)); - bcaddr.sin_family = AF_INET; - bcaddr.sin_addr.s_addr = htonl(INADDR_ANY); - bcaddr.sin_port = port; - - int val = 1; -#ifndef WIN32 - int opt_result = setsockopt(bcfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); -#else - int opt_result = setsockopt(bcfd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); -#endif - if(::bind( bcfd, (struct sockaddr *)&bcaddr, sizeof(bcaddr) ) < 0 ) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"bind failed: %s opt_result = %d\n", Socket::getLastSocketErrorFormattedText().c_str(),opt_result); - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] opt_result = %d\n",__FILE__,__FUNCTION__,__LINE__,opt_result); - - Socket::setBlock(false, bcfd); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - try { - char buff[10025]=""; // Buffers the data to be broadcasted. - // Keep getting packets forever. - for( time_t elapsed = time(NULL); difftime((long int)time(NULL),elapsed) <= 5; ) { - alen = sizeof(struct sockaddr); - int nb=0;// The number of bytes read. - bool gotData = (nb = recvfrom(bcfd, buff, 10024, 0, (struct sockaddr *) &bcSender, &alen)) > 0; - if(nb >= 0) { - buff[nb]=0; - } - - //printf("Broadcasting client nb = %d buff [%s] gotData = %d\n",nb,buff,gotData); - - if(gotData == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"recvfrom failed: %s\n", Socket::getLastSocketErrorFormattedText().c_str()); - } - else { - //string fromIP = inet_ntoa(bcSender.sin_addr); - char szHostFrom[100]=""; - Ip::Inet_NtoA(SockAddrToUint32(&bcSender.sin_addr), szHostFrom); - //printf("Client szHostFrom [%s]\n",szHostFrom); - - string fromIP = szHostFrom; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"broadcast message received: [%s] from: [%s]\n", buff,fromIP.c_str() ); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Client got broadcast from server: [%s] data [%s]\n",fromIP.c_str(),buff); - - int serverGamePort = Socket::getBroadCastPort(); - vector paramPartPortsTokens; - Tokenize(buff,paramPartPortsTokens,":"); - if(paramPartPortsTokens.size() >= 3 && paramPartPortsTokens[2].length() > 0) { - serverGamePort = strToInt(paramPartPortsTokens[2]); - } - - if(std::find(foundServers.begin(),foundServers.end(),fromIP) == foundServers.end()) { - foundServers.push_back(fromIP + ":" + intToStr(serverGamePort)); - } - - // For now break as soon as we find a server - break; - } - - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; - } - sleep( 100 ); // send out broadcast every 1 seconds - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; - } - } - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - } - catch(...) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] UNKNOWN Error\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__); - } - } - } - -#ifndef WIN32 - if(bcfd >= 0) ::close(bcfd); - bcfd = -1; -#else - if(bcfd != INVALID_SOCKET) ::closesocket(bcfd); - bcfd = INVALID_SOCKET; -#endif - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - // Here we callback into the implementer class - if(getQuitStatus() == false && discoveredServersCB != NULL) { - discoveredServersCB->DiscoveredServers(foundServers); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast Client thread is exiting\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -// =============================================== -// class ServerSocket -// =============================================== - -ServerSocket::ServerSocket(bool basicMode) : Socket() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] basicMode = %d\n",__FILE__,__FUNCTION__,__LINE__,basicMode); - - this->basicMode = basicMode; - this->bindSpecificAddress = ""; - //printf("SERVER SOCKET CONSTRUCTOR\n"); - - boundPort = 0; - portBound = false; - broadCastThread = NULL; - if(this->basicMode == false) { - UPNP_Tools::enabledUPNP = false; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -ServerSocket::~ServerSocket() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //printf("In [%s::%s] Line: %d UPNP_Tools::enabledUPNP = %d\n",__FILE__,__FUNCTION__,__LINE__,UPNP_Tools::enabledUPNP); - - stopBroadCastThread(); - - if(this->basicMode == false) { - MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,CODE_AT_LINE); - if(ServerSocket::upnpdiscoverThread != NULL) { - - ServerSocket::cancelUpnpdiscoverThread = true; - SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); - ServerSocket::upnpdiscoverThread = NULL; - ServerSocket::cancelUpnpdiscoverThread = false; - } - safeMutexUPNP.ReleaseLock(); - if (UPNP_Tools::enabledUPNP) { - UPNP_Tools::NETremRedirects(this->getExternalPort()); - } - - MutexSafeWrapper safeMutexUPNP1(&UPNP_Tools::mutexUPNP,CODE_AT_LINE); - if(urls.controlURL && urls.ipcondescURL && urls.controlURL_CIF) { - FreeUPNPUrls(&urls); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - safeMutexUPNP1.ReleaseLock(); - } -} - -void ServerSocket::stopBroadCastThread() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //printf("Stopping broadcast thread [%p]\n",broadCastThread); - - if(broadCastThread != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - //printf("Stopping broadcast thread [%p] - A\n",broadCastThread); - - if(broadCastThread->canShutdown(false) == true) { - sleep(0); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - //printf("Stopping broadcast thread [%p] - B\n",broadCastThread); - - if(broadCastThread->shutdownAndWait() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - delete broadCastThread; - - //printf("Stopping broadcast thread [%p] - C\n",broadCastThread); - } - broadCastThread = NULL; - //printf("Stopping broadcast thread [%p] - D\n",broadCastThread); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void ServerSocket::startBroadCastThread() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - stopBroadCastThread(); - - broadCastThread = new BroadCastSocketThread(this->boundPort); - - //printf("Start broadcast thread [%p]\n",broadCastThread); - - static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); - broadCastThread->setUniqueID(mutexOwnerId); - broadCastThread->start(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void ServerSocket::resumeBroadcast() { - if(broadCastThread != NULL) { - broadCastThread->setPauseBroadcast(false); - } -} -void ServerSocket::pauseBroadcast() { - if(broadCastThread != NULL) { - broadCastThread->setPauseBroadcast(true); - } -} - -bool ServerSocket::isBroadCastThreadRunning() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - bool isThreadRunning = (broadCastThread != NULL && broadCastThread->getRunningStatus() == true); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] isThreadRunning = %d\n",__FILE__,__FUNCTION__,__LINE__,isThreadRunning); - - return isThreadRunning; -} - -void ServerSocket::bind(int port) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d port = %d, portBound = %d START\n",__FILE__,__FUNCTION__,__LINE__,port,portBound); - - boundPort = port; - - if(isSocketValid() == false) { - sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if(isSocketValid() == false) { - throwException("Error creating socket"); - } - setBlock(false); - } - - //sockaddr structure - sockaddr_in addr; - addr.sin_family= AF_INET; - if(this->bindSpecificAddress != "") { - addr.sin_addr.s_addr= inet_addr(this->bindSpecificAddress.c_str()); - } - else { - addr.sin_addr.s_addr= INADDR_ANY; - } - addr.sin_port= htons(port); - addr.sin_zero[0] = 0; - - int val = 1; - -#ifndef WIN32 - int opt_result = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); -#else - int opt_result = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); -#endif - - int err= ::bind(sock, reinterpret_cast(&addr), sizeof(addr)); - if(err < 0) { - char szBuf[8096]=""; - snprintf(szBuf, 8096,"In [%s::%s] Error binding socket sock = " PLATFORM_SOCKET_FORMAT_TYPE ", address [%s] port = %d err = %d, error = %s opt_result = %d\n",__FILE__,__FUNCTION__,sock,this->bindSpecificAddress.c_str(),port,err,getLastSocketErrorFormattedText().c_str(),opt_result); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"%s",szBuf); - - snprintf(szBuf, 8096,"Error binding socket sock = " PLATFORM_SOCKET_FORMAT_TYPE ", address [%s] port = %d err = %d, error = %s\n",sock,this->bindSpecificAddress.c_str(),port,err,getLastSocketErrorFormattedText().c_str()); - throw megaglest_runtime_error(szBuf); - } - portBound = true; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d port = %d, portBound = %d END\n",__FILE__,__FUNCTION__,__LINE__,port,portBound); -} - -void ServerSocket::disconnectSocket() { - Socket::disconnectSocket(); - portBound = false; -} - -void ServerSocket::listen(int connectionQueueSize) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d connectionQueueSize = %d\n",__FILE__,__FUNCTION__,__LINE__,connectionQueueSize); - - if(connectionQueueSize > 0) { - if(isSocketValid() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if(isSocketValid() == false) { - throwException("Error creating socket"); - } - setBlock(false); - } - - if(portBound == false) { - bind(boundPort); - } - - int err= ::listen(sock, connectionQueueSize); - if(err < 0) { - char szBuf[8096]=""; - snprintf(szBuf, 8096,"In [%s::%s] Error listening socket sock = " PLATFORM_SOCKET_FORMAT_TYPE ", err = %d, error = %s\n",__FILE__,__FUNCTION__,sock,err,getLastSocketErrorFormattedText().c_str()); - throwException(szBuf); - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - disconnectSocket(); - } - - if(this->basicMode == false) { - if(connectionQueueSize > 0) { - if(isBroadCastThreadRunning() == false) { - startBroadCastThread(); - } - else { - resumeBroadcast(); - } - } - else { - pauseBroadcast(); - } - } -} - -Socket *ServerSocket::accept(bool errorOnFail) { - if(isSocketValid() == false) { - if(errorOnFail == true) { - throwException("socket is invalid!"); - } - else { - return NULL; - } - } - - PLATFORM_SOCKET newSock=0; - char client_host[100]=""; - //const int max_attempts = 100; - //for(int attempt = 0; attempt < max_attempts; ++attempt) { - struct sockaddr_in cli_addr; - socklen_t clilen = sizeof(cli_addr); - client_host[0]='\0'; - MutexSafeWrapper safeMutex(dataSynchAccessorRead,CODE_AT_LINE); - newSock= ::accept(sock, (struct sockaddr *) &cli_addr, &clilen); - safeMutex.ReleaseLock(); - - if(isSocketValid(&newSock) == false) { - char szBuf[8096]=""; - snprintf(szBuf, 8096,"In [%s::%s Line: %d] Error accepting socket connection sock = " PLATFORM_SOCKET_FORMAT_TYPE ", err = " PLATFORM_SOCKET_FORMAT_TYPE ", error = %s\n",__FILE__,__FUNCTION__,__LINE__,sock,newSock,getLastSocketErrorFormattedText().c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,szBuf); - - int lastSocketError = getLastSocketError(); - if(lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) { - //if(attempt+1 >= max_attempts) { - // return NULL; - //} - //else { - sleep(0); - //} - } - if(errorOnFail == true) { - throwException(szBuf); - } - else { - #ifndef WIN32 - ::close(newSock); - newSock = -1; - #else - ::closesocket(newSock); - newSock = INVALID_SOCKET; - #endif return NULL; } - } - else { - Ip::Inet_NtoA(SockAddrToUint32((struct sockaddr *)&cli_addr), client_host); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got connection, newSock = %d client_host [%s]\n",__FILE__,__FUNCTION__,__LINE__,newSock,client_host); - } - if(isIPAddressBlocked((client_host[0] != '\0' ? client_host : "")) == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] BLOCKING connection, newSock = %d client_host [%s]\n",__FILE__,__FUNCTION__,__LINE__,newSock,client_host); - - #ifndef WIN32 - ::close(newSock); - newSock = -1; - #else - ::closesocket(newSock); - newSock = INVALID_SOCKET; - #endif - - return NULL; - } - - //break; - //} - Socket *result = new Socket(newSock); - result->setIpAddress((client_host[0] != '\0' ? client_host : "")); - return result; -} - -void ServerSocket::NETdiscoverUPnPDevices() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] UPNP - Start\n",__FILE__,__FUNCTION__,__LINE__); - - MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,CODE_AT_LINE); - if(ServerSocket::upnpdiscoverThread != NULL) { - ServerSocket::cancelUpnpdiscoverThread = true; - SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); - ServerSocket::upnpdiscoverThread = NULL; - ServerSocket::cancelUpnpdiscoverThread = false; - } - - // WATCH OUT! Because the thread takes void * as a parameter we MUST cast to the pointer type - // used on the other side (inside the thread) - //printf("STARTING UPNP Thread\n"); - ServerSocket::upnpdiscoverThread = SDL_CreateThread(&UPNP_Tools::upnp_init, "upnpdiscoverThread", dynamic_cast(this)); - safeMutexUPNP.ReleaseLock(); - //printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__); - - //printf("SERVER SOCKET NETdiscoverUPnPDevices - END\n"); -} - -void ServerSocket::UPNPInitStatus(bool result) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] result = %d\n",__FILE__,__FUNCTION__,__LINE__,result); - - if(result == true) { - //int ports[4] = { this->getExternalPort(), this->getBindPort(), this->getFTPServerPort(), this->getFTPServerPort() }; - std::vector UPNPPortForwardList; - - // Glest Game Server port - UPNPPortForwardList.push_back(this->getExternalPort()); - UPNPPortForwardList.push_back(this->getBindPort()); - - // Glest mini FTP Server Listen Port - UPNPPortForwardList.push_back(this->getFTPServerPort()); - UPNPPortForwardList.push_back(this->getFTPServerPort()); - - // GLest mini FTP Server Passive file TRansfer ports (1 per game player) - for(int clientIndex = 1; clientIndex <= ServerSocket::maxPlayerCount; ++clientIndex) { - UPNPPortForwardList.push_back(this->getFTPServerPort() + clientIndex); - UPNPPortForwardList.push_back(this->getFTPServerPort() + clientIndex); - } - - UPNP_Tools::NETaddRedirects(UPNPPortForwardList,false); - } -} - -// -// UPNP Tools Start -// -void UPNP_Tools::AddUPNPPortForward(int internalPort, int externalPort) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] internalPort = %d, externalPort = %d\n",__FILE__,__FUNCTION__,__LINE__,internalPort,externalPort); - - bool addPorts = (UPNP_Tools::enabledUPNP == true); - if(addPorts == false) { - int result = UPNP_Tools::upnp_init(NULL); - addPorts = (result != 0); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] internalPort = %d, externalPort = %d, addPorts = %d\n",__FILE__,__FUNCTION__,__LINE__,internalPort,externalPort,addPorts); - - if(addPorts == true) { - int ports[2] = { externalPort, internalPort }; - UPNP_Tools::upnp_add_redirect(ports); - } -} - -void UPNP_Tools::RemoveUPNPPortForward(int internalPort, int externalPort) { - UPNP_Tools::upnp_rem_redirect(externalPort); -} - -// -// This code below handles Universal Plug and Play Router Discovery -// -int UPNP_Tools::upnp_init(void *param) { - int result = -1; - struct UPNPDev *devlist = NULL; - struct UPNPDev *dev = NULL; - int descXMLsize = 0; - char buf[255] = ""; - // Callers MUST pass in NULL or a UPNPInitInterface * - UPNPInitInterface *callback = (UPNPInitInterface *)(param); - - MutexSafeWrapper safeMutexUPNP(&UPNP_Tools::mutexUPNP,CODE_AT_LINE); - memset(&urls, 0, sizeof(struct UPNPUrls)); - memset(&data, 0, sizeof(struct IGDdatas)); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] isUPNP = %d callback = %p\n",__FILE__,__FUNCTION__,__LINE__,UPNP_Tools::isUPNP,callback); - - if(UPNP_Tools::isUPNP == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Searching for UPnP devices for automatic port forwarding...\n"); - - int upnp_delay = 5000; - const char *upnp_multicastif = NULL; - const char *upnp_minissdpdsock = NULL; - int upnp_sameport = 0; - int upnp_ipv6 = 0; - int upnp_error = 0; - -#ifndef MINIUPNPC_VERSION_PRE1_6 - #if !defined(MINIUPNPC_API_VERSION) || MINIUPNPC_API_VERSION < 14 - devlist = upnpDiscover(upnp_delay, upnp_multicastif, upnp_minissdpdsock, upnp_sameport, upnp_ipv6, &upnp_error); - #else - // miniupnpc 1.9.20150730 - devlist = upnpDiscover(upnp_delay, upnp_multicastif, upnp_minissdpdsock, upnp_sameport, upnp_ipv6, 2, &upnp_error); - #endif - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP discover returned upnp_error = %d.\n",upnp_error); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("UPnP discover returned upnp_error = %d.\n",upnp_error); - -#else - devlist = upnpDiscover(upnp_delay, upnp_multicastif, upnp_minissdpdsock, upnp_sameport); -#endif - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP device search finished devlist = %p.\n",devlist); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("UPnP device search finished devlist = %p.\n",devlist); - - if(ServerSocket::cancelUpnpdiscoverThread == true) { - if(devlist != NULL) { - freeUPNPDevlist(devlist); - } - devlist = NULL; + //break; + //} + Socket *result = new Socket(newSock); + result->setIpAddress((client_host[0] != '\0' ? client_host : "")); return result; } - if (devlist) { - dev = devlist; - while (dev) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP discover deviceList [%s].\n",(dev->st ? dev->st : "null")); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("UPnP discover deviceList [%s].\n",(dev->st ? dev->st : "null")); + void ServerSocket::NETdiscoverUPnPDevices() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] UPNP - Start\n", __FILE__, __FUNCTION__, __LINE__); - dev = dev->pNext; + MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread, CODE_AT_LINE); + if (ServerSocket::upnpdiscoverThread != NULL) { + ServerSocket::cancelUpnpdiscoverThread = true; + SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); + ServerSocket::upnpdiscoverThread = NULL; + ServerSocket::cancelUpnpdiscoverThread = false; } - dev = devlist; - while (dev && dev->st) { - if (strstr(dev->st, "InternetGatewayDevice")) { - break; + // WATCH OUT! Because the thread takes void * as a parameter we MUST cast to the pointer type + // used on the other side (inside the thread) + //printf("STARTING UPNP Thread\n"); + ServerSocket::upnpdiscoverThread = SDL_CreateThread(&UPNP_Tools::upnp_init, "upnpdiscoverThread", dynamic_cast(this)); + safeMutexUPNP.ReleaseLock(); + //printf("In [%s::%s] Line: %d safeMutexUPNP\n",__FILE__,__FUNCTION__,__LINE__); + + //printf("SERVER SOCKET NETdiscoverUPnPDevices - END\n"); + } + + void ServerSocket::UPNPInitStatus(bool result) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] result = %d\n", __FILE__, __FUNCTION__, __LINE__, result); + + if (result == true) { + //int ports[4] = { this->getExternalPort(), this->getBindPort(), this->getFTPServerPort(), this->getFTPServerPort() }; + std::vector UPNPPortForwardList; + + // Glest Game Server port + UPNPPortForwardList.push_back(this->getExternalPort()); + UPNPPortForwardList.push_back(this->getBindPort()); + + // Glest mini FTP Server Listen Port + UPNPPortForwardList.push_back(this->getFTPServerPort()); + UPNPPortForwardList.push_back(this->getFTPServerPort()); + + // GLest mini FTP Server Passive file TRansfer ports (1 per game player) + for (int clientIndex = 1; clientIndex <= ServerSocket::maxPlayerCount; ++clientIndex) { + UPNPPortForwardList.push_back(this->getFTPServerPort() + clientIndex); + UPNPPortForwardList.push_back(this->getFTPServerPort() + clientIndex); } - dev = dev->pNext; + + UPNP_Tools::NETaddRedirects(UPNPPortForwardList, false); } - if (!dev) { - dev = devlist; /* defaulting to first device */ + } + + // + // UPNP Tools Start + // + void UPNP_Tools::AddUPNPPortForward(int internalPort, int externalPort) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] internalPort = %d, externalPort = %d\n", __FILE__, __FUNCTION__, __LINE__, internalPort, externalPort); + + bool addPorts = (UPNP_Tools::enabledUPNP == true); + if (addPorts == false) { + int result = UPNP_Tools::upnp_init(NULL); + addPorts = (result != 0); } - if(dev != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP device found: %s %s\n", dev->descURL, dev->st); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("UPnP device found: %s %s\n", dev->descURL, dev->st); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] internalPort = %d, externalPort = %d, addPorts = %d\n", __FILE__, __FUNCTION__, __LINE__, internalPort, externalPort, addPorts); - //printf("UPnP device found: [%s] [%s] lanaddr [%s]\n", dev->descURL, dev->st,lanaddr); -#if (defined(MINIUPNPC_API_VERSION) && MINIUPNPC_API_VERSION >= 16) - char *descXML = (char *)miniwget_getaddr(dev->descURL, &descXMLsize, lanaddr, (sizeof(lanaddr) / sizeof(lanaddr[0])), 0, NULL); -#elif (defined(MINIUPNPC_API_VERSION) && MINIUPNPC_API_VERSION >= 9) || (!defined(MINIUPNPC_VERSION_PRE1_7) && !defined(MINIUPNPC_VERSION_PRE1_6)) - char *descXML = (char *)miniwget_getaddr(dev->descURL, &descXMLsize, lanaddr, (sizeof(lanaddr) / sizeof(lanaddr[0])), 0); + if (addPorts == true) { + int ports[2] = { externalPort, internalPort }; + UPNP_Tools::upnp_add_redirect(ports); + } + } + + void UPNP_Tools::RemoveUPNPPortForward(int internalPort, int externalPort) { + UPNP_Tools::upnp_rem_redirect(externalPort); + } + + // + // This code below handles Universal Plug and Play Router Discovery + // + int UPNP_Tools::upnp_init(void *param) { + int result = -1; + struct UPNPDev *devlist = NULL; + struct UPNPDev *dev = NULL; + int descXMLsize = 0; + char buf[255] = ""; + // Callers MUST pass in NULL or a UPNPInitInterface * + UPNPInitInterface *callback = (UPNPInitInterface *) (param); + + MutexSafeWrapper safeMutexUPNP(&UPNP_Tools::mutexUPNP, CODE_AT_LINE); + memset(&urls, 0, sizeof(struct UPNPUrls)); + memset(&data, 0, sizeof(struct IGDdatas)); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] isUPNP = %d callback = %p\n", __FILE__, __FUNCTION__, __LINE__, UPNP_Tools::isUPNP, callback); + + if (UPNP_Tools::isUPNP == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "Searching for UPnP devices for automatic port forwarding...\n"); + + int upnp_delay = 5000; + const char *upnp_multicastif = NULL; + const char *upnp_minissdpdsock = NULL; + int upnp_sameport = 0; + int upnp_ipv6 = 0; + int upnp_error = 0; + +#ifndef MINIUPNPC_VERSION_PRE1_6 +#if !defined(MINIUPNPC_API_VERSION) || MINIUPNPC_API_VERSION < 14 + devlist = upnpDiscover(upnp_delay, upnp_multicastif, upnp_minissdpdsock, upnp_sameport, upnp_ipv6, &upnp_error); #else - char *descXML = (char *)miniwget_getaddr(dev->descURL, &descXMLsize, lanaddr, (sizeof(lanaddr) / sizeof(lanaddr[0]))); + // miniupnpc 1.9.20150730 + devlist = upnpDiscover(upnp_delay, upnp_multicastif, upnp_minissdpdsock, upnp_sameport, upnp_ipv6, 2, &upnp_error); #endif - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"LAN address: %s\n", lanaddr); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "UPnP discover returned upnp_error = %d.\n", upnp_error); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("UPnP discover returned upnp_error = %d.\n", upnp_error); - if (descXML) { - parserootdesc (descXML, descXMLsize, &data); - free (descXML); descXML = 0; +#else + devlist = upnpDiscover(upnp_delay, upnp_multicastif, upnp_minissdpdsock, upnp_sameport); +#endif + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "UPnP device search finished devlist = %p.\n", devlist); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("UPnP device search finished devlist = %p.\n", devlist); + + if (ServerSocket::cancelUpnpdiscoverThread == true) { + if (devlist != NULL) { + freeUPNPDevlist(devlist); + } + devlist = NULL; + return result; + } + + if (devlist) { + dev = devlist; + while (dev) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "UPnP discover deviceList [%s].\n", (dev->st ? dev->st : "null")); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("UPnP discover deviceList [%s].\n", (dev->st ? dev->st : "null")); + + dev = dev->pNext; + } + + dev = devlist; + while (dev && dev->st) { + if (strstr(dev->st, "InternetGatewayDevice")) { + break; + } + dev = dev->pNext; + } + if (!dev) { + dev = devlist; /* defaulting to first device */ + } + + if (dev != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "UPnP device found: %s %s\n", dev->descURL, dev->st); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("UPnP device found: %s %s\n", dev->descURL, dev->st); + + //printf("UPnP device found: [%s] [%s] lanaddr [%s]\n", dev->descURL, dev->st,lanaddr); +#if (defined(MINIUPNPC_API_VERSION) && MINIUPNPC_API_VERSION >= 16) + char *descXML = (char *) miniwget_getaddr(dev->descURL, &descXMLsize, lanaddr, (sizeof(lanaddr) / sizeof(lanaddr[0])), 0, NULL); +#elif (defined(MINIUPNPC_API_VERSION) && MINIUPNPC_API_VERSION >= 9) || (!defined(MINIUPNPC_VERSION_PRE1_7) && !defined(MINIUPNPC_VERSION_PRE1_6)) + char *descXML = (char *) miniwget_getaddr(dev->descURL, &descXMLsize, lanaddr, (sizeof(lanaddr) / sizeof(lanaddr[0])), 0); +#else + char *descXML = (char *) miniwget_getaddr(dev->descURL, &descXMLsize, lanaddr, (sizeof(lanaddr) / sizeof(lanaddr[0]))); +#endif + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "LAN address: %s\n", lanaddr); + + if (descXML) { + parserootdesc(descXML, descXMLsize, &data); + free(descXML); descXML = 0; #if (defined(MINIUPNPC_API_VERSION) && MINIUPNPC_API_VERSION >= 9) || (!defined(MINIUPNPC_VERSION_PRE1_7) && !defined(MINIUPNPC_VERSION_PRE1_6)) - GetUPNPUrls (&urls, &data, dev->descURL,0); + GetUPNPUrls(&urls, &data, dev->descURL, 0); #else - GetUPNPUrls (&urls, &data, dev->descURL); + GetUPNPUrls(&urls, &data, dev->descURL); #endif + } + snprintf(buf, 255, "UPnP device found: %s %s LAN address %s", dev->descURL, dev->st, lanaddr); + + freeUPNPDevlist(devlist); + devlist = NULL; + } + + if (ServerSocket::cancelUpnpdiscoverThread == true) { + //if(devlist != NULL) { + // freeUPNPDevlist(devlist); + //} + //devlist = NULL; + return result; + } + + if (!urls.controlURL || urls.controlURL[0] == '\0') { + snprintf(buf, 255, "controlURL not available, UPnP disabled"); + if (callback) { + safeMutexUPNP.ReleaseLock(); + callback->UPNPInitStatus(false); + } + result = 0; + } else { + char externalIP[16] = ""; +#ifndef MINIUPNPC_VERSION_PRE1_5 + UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIP); +#else + UPNP_GetExternalIPAddress(urls.controlURL, data.servicetype, externalIP); +#endif + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "UPnP device found at: [%s] callback [%p]\n", externalIP, callback); + + //UPNP_Tools::NETaddRedirects(ports); + UPNP_Tools::enabledUPNP = true; + if (callback) { + safeMutexUPNP.ReleaseLock(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + callback->UPNPInitStatus(true); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + result = 1; + } } - snprintf(buf, 255,"UPnP device found: %s %s LAN address %s", dev->descURL, dev->st, lanaddr); - freeUPNPDevlist(devlist); - devlist = NULL; - } + if (result == -1) { + snprintf(buf, 255, "UPnP device not found."); - if(ServerSocket::cancelUpnpdiscoverThread == true) { - //if(devlist != NULL) { - // freeUPNPDevlist(devlist); - //} - //devlist = NULL; - return result; - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "No UPnP devices found.\n"); - if (!urls.controlURL || urls.controlURL[0] == '\0') { - snprintf(buf, 255,"controlURL not available, UPnP disabled"); - if(callback) { + if (ServerSocket::cancelUpnpdiscoverThread == true) { + //if(devlist != NULL) { + // freeUPNPDevlist(devlist); + //} + //devlist = NULL; + return result; + } + + if (callback) { + safeMutexUPNP.ReleaseLock(); + callback->UPNPInitStatus(false); + } + result = 0; + } + } else { + snprintf(buf, 255, "UPnP detection routine disabled by user."); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "UPnP detection routine disabled by user.\n"); + + if (ServerSocket::cancelUpnpdiscoverThread == true) { + //if(devlist != NULL) { + // freeUPNPDevlist(devlist); + //} + //devlist = NULL; + return result; + } + + if (callback) { safeMutexUPNP.ReleaseLock(); - callback->UPNPInitStatus(false); + callback->UPNPInitStatus(false); } result = 0; } - else { - char externalIP[16] = ""; + + //printf("ENDING UPNP Thread\n"); + + return result; + } + + bool UPNP_Tools::upnp_add_redirect(int ports[2], bool mutexLock) { + bool result = true; + + //printf("SERVER SOCKET upnp_add_redirect - START\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] upnp_add_redir(%d : %d)\n", __FILE__, __FUNCTION__, __LINE__, ports[0], ports[1]); + + if (mutexLock) { + MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread, CODE_AT_LINE); + if (ServerSocket::upnpdiscoverThread != NULL) { + ServerSocket::cancelUpnpdiscoverThread = true; + SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); + ServerSocket::upnpdiscoverThread = NULL; + ServerSocket::cancelUpnpdiscoverThread = false; + } + safeMutexUPNP.ReleaseLock(); + } + + MutexSafeWrapper safeMutexUPNP(&UPNP_Tools::mutexUPNP, CODE_AT_LINE); + if (!urls.controlURL || urls.controlURL[0] == '\0') { + result = false; + } else { + char externalIP[16] = ""; #ifndef MINIUPNPC_VERSION_PRE1_5 UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIP); #else UPNP_GetExternalIPAddress(urls.controlURL, data.servicetype, externalIP); #endif - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP device found at: [%s] callback [%p]\n",externalIP,callback); - //UPNP_Tools::NETaddRedirects(ports); - UPNP_Tools::enabledUPNP = true; - if(callback) { - safeMutexUPNP.ReleaseLock(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - callback->UPNPInitStatus(true); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + char ext_port_str[16] = ""; + char int_port_str[16] = ""; + sprintf(ext_port_str, "%d", ports[0]); + sprintf(int_port_str, "%d", ports[1]); + + //int r = 0; +#ifndef MINIUPNPC_VERSION_PRE1_5 +#ifndef MINIUPNPC_VERSION_PRE1_6 + int r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, ext_port_str, int_port_str, lanaddr, "ZetaGlest - zetaglest.github.io", "TCP", 0, NULL); +#else + int r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, ext_port_str, int_port_str, lanaddr, "ZetaGlest - zetaglest.github.io", "TCP", 0); +#endif +#else + int r = UPNP_AddPortMapping(urls.controlURL, data.servicetype, ext_port_str, int_port_str, lanaddr, "ZetaGlest - zetaglest.github.io", "TCP", 0); +#endif + if (r != UPNPCOMMAND_SUCCESS) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] AddPortMapping(%s, %s, %s) failed\n", __FILE__, __FUNCTION__, __LINE__, ext_port_str, int_port_str, lanaddr); + result = false; } - result = 1; - } - } - if(result == -1) { - snprintf(buf, 255,"UPnP device not found."); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"No UPnP devices found.\n"); - - if(ServerSocket::cancelUpnpdiscoverThread == true) { - //if(devlist != NULL) { - // freeUPNPDevlist(devlist); - //} - //devlist = NULL; - return result; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] AddPortMapping(%s, %s, %s) success\n", __FILE__, __FUNCTION__, __LINE__, ext_port_str, int_port_str, lanaddr); } - if(callback) { - safeMutexUPNP.ReleaseLock(); - callback->UPNPInitStatus(false); - } - result = 0; - } - } - else { - snprintf(buf, 255,"UPnP detection routine disabled by user."); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UPnP detection routine disabled by user.\n"); - - if(ServerSocket::cancelUpnpdiscoverThread == true) { - //if(devlist != NULL) { - // freeUPNPDevlist(devlist); - //} - //devlist = NULL; + //printf("SERVER SOCKET upnp_add_redirect - END [%d]\n",result); return result; } - if(callback) { - safeMutexUPNP.ReleaseLock(); - callback->UPNPInitStatus(false); - } - result = 0; - } + void UPNP_Tools::upnp_rem_redirect(int ext_port) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] upnp_rem_redir(%d)\n", __FILE__, __FUNCTION__, __LINE__, ext_port); - //printf("ENDING UPNP Thread\n"); + MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread, CODE_AT_LINE); + if (ServerSocket::upnpdiscoverThread != NULL) { + ServerSocket::cancelUpnpdiscoverThread = true; + SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); + ServerSocket::upnpdiscoverThread = NULL; + ServerSocket::cancelUpnpdiscoverThread = false; + } + safeMutexUPNP.ReleaseLock(); - return result; -} + MutexSafeWrapper safeMutexUPNP1(&UPNP_Tools::mutexUPNP, CODE_AT_LINE); + if (urls.controlURL && urls.controlURL[0] != '\0') { + char ext_port_str[16] = ""; + sprintf(ext_port_str, "%d", ext_port); -bool UPNP_Tools::upnp_add_redirect(int ports[2],bool mutexLock) { - bool result = true; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1 DEBUGGING urls.controlURL [%s]\n", urls.controlURL); - //printf("SERVER SOCKET upnp_add_redirect - START\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] upnp_add_redir(%d : %d)\n",__FILE__,__FUNCTION__,__LINE__,ports[0],ports[1]); - - if(mutexLock) { - MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,CODE_AT_LINE); - if(ServerSocket::upnpdiscoverThread != NULL) { - ServerSocket::cancelUpnpdiscoverThread = true; - SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); - ServerSocket::upnpdiscoverThread = NULL; - ServerSocket::cancelUpnpdiscoverThread = false; - } - safeMutexUPNP.ReleaseLock(); - } - - MutexSafeWrapper safeMutexUPNP(&UPNP_Tools::mutexUPNP,CODE_AT_LINE); - if (!urls.controlURL || urls.controlURL[0] == '\0') { - result = false; - } - else { - char externalIP[16] = ""; + int result = 0; #ifndef MINIUPNPC_VERSION_PRE1_5 - UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIP); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1 DEBUGGING data.first.servicetype [%s]\n", data.first.servicetype); + result = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, ext_port_str, "TCP", 0); #else - UPNP_GetExternalIPAddress(urls.controlURL, data.servicetype, externalIP); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1 DEBUGGING data.servicetype [%s]\n", data.servicetype); + result = UPNP_DeletePortMapping(urls.controlURL, data.servicetype, ext_port_str, "TCP", 0); #endif + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nresult = %d\n", result); + //printf("\n\nresult = %d\n",result); + } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#2 DEBUGGING urls.controlURL [%s]\n", urls.controlURL); - char ext_port_str[16] = ""; - char int_port_str[16] = ""; - sprintf(ext_port_str, "%d", ports[0]); - sprintf(int_port_str, "%d", ports[1]); - - //int r = 0; -#ifndef MINIUPNPC_VERSION_PRE1_5 - #ifndef MINIUPNPC_VERSION_PRE1_6 - int r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,ext_port_str, int_port_str, lanaddr, "ZetaGlest - zetaglest.github.io", "TCP", 0, NULL); - #else - int r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,ext_port_str, int_port_str, lanaddr, "ZetaGlest - zetaglest.github.io", "TCP", 0); - #endif -#else - int r = UPNP_AddPortMapping(urls.controlURL, data.servicetype,ext_port_str, int_port_str, lanaddr, "ZetaGlest - zetaglest.github.io", "TCP", 0); -#endif - if (r != UPNPCOMMAND_SUCCESS) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] AddPortMapping(%s, %s, %s) failed\n",__FILE__,__FUNCTION__,__LINE__,ext_port_str, int_port_str, lanaddr); - result = false; + //printf("SERVER SOCKET upnp_rem_redirect - END\n"); } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] AddPortMapping(%s, %s, %s) success\n",__FILE__,__FUNCTION__,__LINE__,ext_port_str, int_port_str, lanaddr); - } + void UPNP_Tools::NETaddRedirects(std::vector UPNPPortForwardList, bool mutexLock) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] upnp_rem_redir(%d)\n", __FILE__, __FUNCTION__, __LINE__); - //printf("SERVER SOCKET upnp_add_redirect - END [%d]\n",result); - return result; -} + if (UPNPPortForwardList.size() % 2 != 0) { + // We need groups of 2 ports.. one external and one internal for opening ports on UPNP router + throw megaglest_runtime_error("UPNPPortForwardList.size() MUST BE divisable by 2"); + } -void UPNP_Tools::upnp_rem_redirect(int ext_port) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] upnp_rem_redir(%d)\n",__FILE__,__FUNCTION__,__LINE__,ext_port); - - MutexSafeWrapper safeMutexUPNP(&ServerSocket::mutexUpnpdiscoverThread,CODE_AT_LINE); - if(ServerSocket::upnpdiscoverThread != NULL) { - ServerSocket::cancelUpnpdiscoverThread = true; - SDL_WaitThread(ServerSocket::upnpdiscoverThread, NULL); - ServerSocket::upnpdiscoverThread = NULL; - ServerSocket::cancelUpnpdiscoverThread = false; - } - safeMutexUPNP.ReleaseLock(); - - MutexSafeWrapper safeMutexUPNP1(&UPNP_Tools::mutexUPNP,CODE_AT_LINE); - if (urls.controlURL && urls.controlURL[0] != '\0') { - char ext_port_str[16]=""; - sprintf(ext_port_str, "%d", ext_port); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1 DEBUGGING urls.controlURL [%s]\n",urls.controlURL); - - int result = 0; - #ifndef MINIUPNPC_VERSION_PRE1_5 - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1 DEBUGGING data.first.servicetype [%s]\n",data.first.servicetype); - result = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, ext_port_str, "TCP", 0); - #else - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1 DEBUGGING data.servicetype [%s]\n",data.servicetype); - result = UPNP_DeletePortMapping(urls.controlURL, data.servicetype, ext_port_str, "TCP", 0); - #endif - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nresult = %d\n",result); - //printf("\n\nresult = %d\n",result); - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#2 DEBUGGING urls.controlURL [%s]\n",urls.controlURL); - - //printf("SERVER SOCKET upnp_rem_redirect - END\n"); -} - -void UPNP_Tools::NETaddRedirects(std::vector UPNPPortForwardList,bool mutexLock) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] upnp_rem_redir(%d)\n",__FILE__,__FUNCTION__,__LINE__); - - if(UPNPPortForwardList.size() % 2 != 0) { - // We need groups of 2 ports.. one external and one internal for opening ports on UPNP router - throw megaglest_runtime_error("UPNPPortForwardList.size() MUST BE divisable by 2"); - } - - for(unsigned int clientIndex = 0; clientIndex < UPNPPortForwardList.size(); clientIndex += 2) { - int ports[2] = { UPNPPortForwardList[clientIndex], UPNPPortForwardList[clientIndex+1] }; - upnp_add_redirect(ports,mutexLock); - } -} - -void UPNP_Tools::NETremRedirects(int ext_port) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] upnp_rem_redir(%d)\n",__FILE__,__FUNCTION__,__LINE__); - upnp_rem_redirect(ext_port); -} -// -// UPNP Tools END -// - -//======================================================================= -// Function : broadcast_thread -// in : none -// return : none -// Description: To be forked in its own thread to send out a broadcast to the local subnet -// the current broadcast message is -// -BroadCastSocketThread::BroadCastSocketThread(int boundPort) : BaseThread() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - mutexPauseBroadcast = new Mutex(CODE_AT_LINE); - setPauseBroadcast(false); - this->boundPort = boundPort; - uniqueID = "BroadCastSocketThread"; - //printf("new broadcast thread [%p]\n",this); -} - -BroadCastSocketThread::~BroadCastSocketThread() { - //printf("delete broadcast thread [%p]\n",this); - - delete mutexPauseBroadcast; - mutexPauseBroadcast = NULL; -} - -bool BroadCastSocketThread::getPauseBroadcast() { - MutexSafeWrapper safeMutexSocketDestructorFlag(mutexPauseBroadcast,CODE_AT_LINE); - mutexPauseBroadcast->setOwnerId(CODE_AT_LINE); - return pauseBroadcast; -} - -void BroadCastSocketThread::setPauseBroadcast(bool value) { - MutexSafeWrapper safeMutexSocketDestructorFlag(mutexPauseBroadcast,CODE_AT_LINE); - mutexPauseBroadcast->setOwnerId(CODE_AT_LINE); - pauseBroadcast = value; -} - - -bool BroadCastSocketThread::canShutdown(bool deleteSelfIfShutdownDelayed) { - bool ret = (getExecutingTask() == false); - if(ret == false && deleteSelfIfShutdownDelayed == true) { - setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed); - deleteSelfIfRequired(); - signalQuit(); - } - - return ret; -} - -void BroadCastSocketThread::execute() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - //setRunningStatus(true); - RunningStatusSafeWrapper runningStatus(this); - ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is running\n"); - - const int MAX_NIC_COUNT = 10; - short port=0; // The port for the broadcast. - struct sockaddr_in bcLocal[MAX_NIC_COUNT]; // local socket address for the broadcast. - PLATFORM_SOCKET bcfd[MAX_NIC_COUNT]; // The socket used for the broadcast. - int one = 1; // Parameter for "setscokopt". - int pn=0; // The number of the packet broadcasted. - const int buffMaxSize=1024; - char buff[buffMaxSize]=""; // Buffers the data to be broadcasted. - char myhostname[100]=""; // hostname of local machine - //char subnetmask[MAX_NIC_COUNT][100]; // Subnet mask to broadcast to - //struct hostent* myhostent=NULL; - - for(unsigned int idx = 0; idx < (unsigned int)MAX_NIC_COUNT; idx++) { - memset( &bcLocal[idx], 0, sizeof( struct sockaddr_in)); - -#ifdef WIN32 - bcfd[idx] = INVALID_SOCKET; -#else - bcfd[idx] = -1; -#endif - } - /* get my host name */ - gethostname(myhostname,100); - //struct hostent*myhostent = gethostbyname(myhostname); - - // get all host IP addresses - std::vector ipList = Socket::getLocalIPAddressList(); - - // Subnet, IP Address - std::vector ipSubnetMaskList; - //ipList.clear(); - if(ipList.empty() == false) { - for(unsigned int idx = 0; idx < (unsigned int)ipList.size() && idx < (unsigned int)MAX_NIC_COUNT; idx++) { - string broadCastAddress = getNetworkInterfaceBroadcastAddress(ipList[idx]); - //printf("idx = %d broadCastAddress [%s]\n",idx,broadCastAddress.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"idx = %d broadCastAddress [%s]\n",idx,broadCastAddress.c_str()); - - //strcpy(subnetmask[idx], broadCastAddress.c_str()); - if(broadCastAddress != "" && std::find(ipSubnetMaskList.begin(),ipSubnetMaskList.end(),broadCastAddress) == ipSubnetMaskList.end()) { - //printf("Adding index [%d] address to list ...\n",idx); - - ipSubnetMaskList.push_back(broadCastAddress); + for (unsigned int clientIndex = 0; clientIndex < UPNPPortForwardList.size(); clientIndex += 2) { + int ports[2] = { UPNPPortForwardList[clientIndex], UPNPPortForwardList[clientIndex + 1] }; + upnp_add_redirect(ports, mutexLock); } } - } - else { - //printf("NO Addresses found for broadCastAddress using INADDR_ANY\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"NO Addresses found for broadCastAddress using INADDR_ANY\n"); - //ipSubnetMaskList.push_back(INADDR_ANY); - ipSubnetMaskList.push_back("*"); - } - port = htons( Socket::getBroadCastPort() ); + void UPNP_Tools::NETremRedirects(int ext_port) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] upnp_rem_redir(%d)\n", __FILE__, __FUNCTION__, __LINE__); + upnp_rem_redirect(ext_port); + } + // + // UPNP Tools END + // - //for(unsigned int idx = 0; idx < ipList.size() && idx < MAX_NIC_COUNT; idx++) { - for(unsigned int idx = 0; idx < (unsigned int)ipSubnetMaskList.size(); idx++) { - // Create the broadcast socket - memset( &bcLocal[idx], 0, sizeof( struct sockaddr_in)); - bcLocal[idx].sin_family = AF_INET; - if(ipSubnetMaskList[idx] == "*") { - //printf("UDP Socket broadcast using INADDR_ANY\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UDP Socket broadcast using INADDR_ANY\n"); - bcLocal[idx].sin_addr.s_addr = INADDR_ANY; + //======================================================================= + // Function : broadcast_thread + // in : none + // return : none + // Description: To be forked in its own thread to send out a broadcast to the local subnet + // the current broadcast message is + // + BroadCastSocketThread::BroadCastSocketThread(int boundPort) : BaseThread() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + mutexPauseBroadcast = new Mutex(CODE_AT_LINE); + setPauseBroadcast(false); + this->boundPort = boundPort; + uniqueID = "BroadCastSocketThread"; + //printf("new broadcast thread [%p]\n",this); } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"UDP Socket broadcast using IP [%s]\n",ipSubnetMaskList[idx].c_str()); - bcLocal[idx].sin_addr.s_addr = inet_addr(ipSubnetMaskList[idx].c_str()); //htonl( INADDR_BROADCAST ); + + BroadCastSocketThread::~BroadCastSocketThread() { + //printf("delete broadcast thread [%p]\n",this); + + delete mutexPauseBroadcast; + mutexPauseBroadcast = NULL; } - bcLocal[idx].sin_port = port; // We are letting the OS fill in the port number for the local machine. + + bool BroadCastSocketThread::getPauseBroadcast() { + MutexSafeWrapper safeMutexSocketDestructorFlag(mutexPauseBroadcast, CODE_AT_LINE); + mutexPauseBroadcast->setOwnerId(CODE_AT_LINE); + return pauseBroadcast; + } + + void BroadCastSocketThread::setPauseBroadcast(bool value) { + MutexSafeWrapper safeMutexSocketDestructorFlag(mutexPauseBroadcast, CODE_AT_LINE); + mutexPauseBroadcast->setOwnerId(CODE_AT_LINE); + pauseBroadcast = value; + } + + + bool BroadCastSocketThread::canShutdown(bool deleteSelfIfShutdownDelayed) { + bool ret = (getExecutingTask() == false); + if (ret == false && deleteSelfIfShutdownDelayed == true) { + setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed); + deleteSelfIfRequired(); + signalQuit(); + } + + return ret; + } + + void BroadCastSocketThread::execute() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + //setRunningStatus(true); + RunningStatusSafeWrapper runningStatus(this); + ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "Broadcast thread is running\n"); + + const int MAX_NIC_COUNT = 10; + short port = 0; // The port for the broadcast. + struct sockaddr_in bcLocal[MAX_NIC_COUNT]; // local socket address for the broadcast. + PLATFORM_SOCKET bcfd[MAX_NIC_COUNT]; // The socket used for the broadcast. + int one = 1; // Parameter for "setscokopt". + int pn = 0; // The number of the packet broadcasted. + const int buffMaxSize = 1024; + char buff[buffMaxSize] = ""; // Buffers the data to be broadcasted. + char myhostname[100] = ""; // hostname of local machine + //char subnetmask[MAX_NIC_COUNT][100]; // Subnet mask to broadcast to + //struct hostent* myhostent=NULL; + + for (unsigned int idx = 0; idx < (unsigned int) MAX_NIC_COUNT; idx++) { + memset(&bcLocal[idx], 0, sizeof(struct sockaddr_in)); + #ifdef WIN32 - bcfd[idx] = INVALID_SOCKET; + bcfd[idx] = INVALID_SOCKET; #else - bcfd[idx] = -1; + bcfd[idx] = -1; #endif - //if(strlen(subnetmask[idx]) > 0) { - bcfd[idx] = socket( AF_INET, SOCK_DGRAM, 0 ); + } + /* get my host name */ + gethostname(myhostname, 100); + //struct hostent*myhostent = gethostbyname(myhostname); - if( bcfd[idx] <= 0 ) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Unable to allocate broadcast socket [%s]: %s\n", ipSubnetMaskList[idx].c_str(), Socket::getLastSocketErrorFormattedText().c_str()); - //printf("Unable to allocate broadcast socket [%s]: %s\n", ipSubnetMaskList[idx].c_str(), Socket::getLastSocketErrorFormattedText().c_str()); - //exit(-1); - } - // Mark the socket for broadcast. - else if( setsockopt( bcfd[idx], SOL_SOCKET, SO_BROADCAST, (const char *) &one, sizeof( int ) ) < 0 ) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Could not set socket to broadcast [%s]: %s\n", ipSubnetMaskList[idx].c_str(), Socket::getLastSocketErrorFormattedText().c_str()); - //printf("Could not set socket to broadcast [%s]: %s\n", ipSubnetMaskList[idx].c_str(), Socket::getLastSocketErrorFormattedText().c_str()); - //exit(-1); - } - //} + // get all host IP addresses + std::vector ipList = Socket::getLocalIPAddressList(); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] setting up broadcast on address [%s]\n",__FILE__,__FUNCTION__,__LINE__,ipSubnetMaskList[idx].c_str()); - } + // Subnet, IP Address + std::vector ipSubnetMaskList; + //ipList.clear(); + if (ipList.empty() == false) { + for (unsigned int idx = 0; idx < (unsigned int) ipList.size() && idx < (unsigned int) MAX_NIC_COUNT; idx++) { + string broadCastAddress = getNetworkInterfaceBroadcastAddress(ipList[idx]); + //printf("idx = %d broadCastAddress [%s]\n",idx,broadCastAddress.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "idx = %d broadCastAddress [%s]\n", idx, broadCastAddress.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //strcpy(subnetmask[idx], broadCastAddress.c_str()); + if (broadCastAddress != "" && std::find(ipSubnetMaskList.begin(), ipSubnetMaskList.end(), broadCastAddress) == ipSubnetMaskList.end()) { + //printf("Adding index [%d] address to list ...\n",idx); - time_t elapsed = 0; - for( pn = 1; getQuitStatus() == false; pn++ ) { - for(unsigned int idx = 0; getQuitStatus() == false && idx < ipSubnetMaskList.size(); idx++) { - if( Socket::isSocketValid(&bcfd[idx]) == true ) { - try { - // Send this machine's host name and address in hostname:n.n.n.n format - snprintf(buff,1024,"%s",myhostname); - for(unsigned int idx1 = 0; idx1 < ipList.size(); idx1++) { -// strcat(buff,":"); -// strcat(buff,ipList[idx1].c_str()); -// strcat(buff,":"); -// string port_string = intToStr(this->boundPort); -//#ifdef WIN32 -// strncat(buff,port_string.c_str(),min((int)port_string.length(),100)); -//#else -// strncat(buff,port_string.c_str(),std::min((int)port_string.length(),100)); -//#endif - string buffCopy = buff; - snprintf(buff,1024,"%s:%s:%d",buffCopy.c_str(),ipList[idx1].c_str(),this->boundPort); - //printf("About to broadcast index [%d] host info [%s]\n", idx1,buff); + ipSubnetMaskList.push_back(broadCastAddress); } + } + } else { + //printf("NO Addresses found for broadCastAddress using INADDR_ANY\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "NO Addresses found for broadCastAddress using INADDR_ANY\n"); + //ipSubnetMaskList.push_back(INADDR_ANY); + ipSubnetMaskList.push_back("*"); + } - if(difftime((long int)time(NULL),elapsed) >= 1 && getQuitStatus() == false) { - elapsed = time(NULL); + port = htons(Socket::getBroadCastPort()); - bool pauseBroadCast = getPauseBroadcast(); - if(pauseBroadCast == false) { - // Broadcast the packet to the subnet - //if( sendto( bcfd, buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcaddr, sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 ) + //for(unsigned int idx = 0; idx < ipList.size() && idx < MAX_NIC_COUNT; idx++) { + for (unsigned int idx = 0; idx < (unsigned int) ipSubnetMaskList.size(); idx++) { + // Create the broadcast socket + memset(&bcLocal[idx], 0, sizeof(struct sockaddr_in)); + bcLocal[idx].sin_family = AF_INET; + if (ipSubnetMaskList[idx] == "*") { + //printf("UDP Socket broadcast using INADDR_ANY\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "UDP Socket broadcast using INADDR_ANY\n"); + bcLocal[idx].sin_addr.s_addr = INADDR_ANY; + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "UDP Socket broadcast using IP [%s]\n", ipSubnetMaskList[idx].c_str()); + bcLocal[idx].sin_addr.s_addr = inet_addr(ipSubnetMaskList[idx].c_str()); //htonl( INADDR_BROADCAST ); + } + bcLocal[idx].sin_port = port; // We are letting the OS fill in the port number for the local machine. +#ifdef WIN32 + bcfd[idx] = INVALID_SOCKET; +#else + bcfd[idx] = -1; +#endif + //if(strlen(subnetmask[idx]) > 0) { + bcfd[idx] = socket(AF_INET, SOCK_DGRAM, 0); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Server is sending broadcast data [%s]\n",buff); - //printf("Broadcasting index host info [%s]\n", buff); + if (bcfd[idx] <= 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "Unable to allocate broadcast socket [%s]: %s\n", ipSubnetMaskList[idx].c_str(), Socket::getLastSocketErrorFormattedText().c_str()); + //printf("Unable to allocate broadcast socket [%s]: %s\n", ipSubnetMaskList[idx].c_str(), Socket::getLastSocketErrorFormattedText().c_str()); + //exit(-1); + } + // Mark the socket for broadcast. + else if (setsockopt(bcfd[idx], SOL_SOCKET, SO_BROADCAST, (const char *) &one, sizeof(int)) < 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "Could not set socket to broadcast [%s]: %s\n", ipSubnetMaskList[idx].c_str(), Socket::getLastSocketErrorFormattedText().c_str()); + //printf("Could not set socket to broadcast [%s]: %s\n", ipSubnetMaskList[idx].c_str(), Socket::getLastSocketErrorFormattedText().c_str()); + //exit(-1); + } + //} - ssize_t send_res = sendto( bcfd[idx], buff, buffMaxSize, 0 , (struct sockaddr *)&bcLocal[idx], sizeof(struct sockaddr_in) ); - if( send_res != buffMaxSize ) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Sendto error: %s\n", Socket::getLastSocketErrorFormattedText().c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] setting up broadcast on address [%s]\n", __FILE__, __FUNCTION__, __LINE__, ipSubnetMaskList[idx].c_str()); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + time_t elapsed = 0; + for (pn = 1; getQuitStatus() == false; pn++) { + for (unsigned int idx = 0; getQuitStatus() == false && idx < ipSubnetMaskList.size(); idx++) { + if (Socket::isSocketValid(&bcfd[idx]) == true) { + try { + // Send this machine's host name and address in hostname:n.n.n.n format + snprintf(buff, 1024, "%s", myhostname); + for (unsigned int idx1 = 0; idx1 < ipList.size(); idx1++) { + // strcat(buff,":"); + // strcat(buff,ipList[idx1].c_str()); + // strcat(buff,":"); + // string port_string = intToStr(this->boundPort); + //#ifdef WIN32 + // strncat(buff,port_string.c_str(),min((int)port_string.length(),100)); + //#else + // strncat(buff,port_string.c_str(),std::min((int)port_string.length(),100)); + //#endif + string buffCopy = buff; + snprintf(buff, 1024, "%s:%s:%d", buffCopy.c_str(), ipList[idx1].c_str(), this->boundPort); + //printf("About to broadcast index [%d] host info [%s]\n", idx1,buff); } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcasting on port [%d] the message: [%s]\n",Socket::getBroadCastPort(),buff); + + if (difftime((long int) time(NULL), elapsed) >= 1 && getQuitStatus() == false) { + elapsed = time(NULL); + + bool pauseBroadCast = getPauseBroadcast(); + if (pauseBroadCast == false) { + // Broadcast the packet to the subnet + //if( sendto( bcfd, buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcaddr, sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 ) + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "Server is sending broadcast data [%s]\n", buff); + //printf("Broadcasting index host info [%s]\n", buff); + + ssize_t send_res = sendto(bcfd[idx], buff, buffMaxSize, 0, (struct sockaddr *)&bcLocal[idx], sizeof(struct sockaddr_in)); + if (send_res != buffMaxSize) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "Sendto error: %s\n", Socket::getLastSocketErrorFormattedText().c_str()); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "Broadcasting on port [%d] the message: [%s]\n", Socket::getBroadCastPort(), buff); + } + } + //printf("Broadcasting server send_res = %d buff [%s] ip [%s] getPauseBroadcast() = %d\n",send_res,buff,ipSubnetMaskList[idx].c_str(),pauseBroadCast); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); } + + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; + } + sleep(100); // send out broadcast every 1 seconds + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + this->setQuitStatus(true); + } catch (...) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] UNKNOWN Error\n", __FILE__, __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] unknown error\n", __FILE__, __FUNCTION__, __LINE__); + this->setQuitStatus(true); } - //printf("Broadcasting server send_res = %d buff [%s] ip [%s] getPauseBroadcast() = %d\n",send_res,buff,ipSubnetMaskList[idx].c_str(),pauseBroadCast); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); break; } - sleep(100); // send out broadcast every 1 seconds } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - this->setQuitStatus(true); - } - catch(...) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] UNKNOWN Error\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__); - this->setQuitStatus(true); + if (getQuitStatus() == true) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + break; } } - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; - } - } - if(getQuitStatus() == true) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - break; - } - } - - for(unsigned int idx = 0; idx < ipSubnetMaskList.size(); idx++) { - if( Socket::isSocketValid(&bcfd[idx]) == true ) { + for (unsigned int idx = 0; idx < ipSubnetMaskList.size(); idx++) { + if (Socket::isSocketValid(&bcfd[idx]) == true) { #ifndef WIN32 - ::close(bcfd[idx]); - bcfd[idx] = -1; + ::close(bcfd[idx]); + bcfd[idx] = -1; #else - ::closesocket(bcfd[idx]); - bcfd[idx] = INVALID_SOCKET; + ::closesocket(bcfd[idx]); + bcfd[idx] = INVALID_SOCKET; #endif - } - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Broadcast thread is exiting\n",__FILE__,__FUNCTION__,__LINE__); -} - -double Socket::getAveragePingMS(std::string host, int pingCount) { - double result = -1; - return result; - -/* - const bool debugPingOutput = false; - char szCmd[1024]=""; -#ifdef WIN32 - sprintf(szCmd,"ping -n %d %s",pingCount,host.c_str()); - if(debugPingOutput) printf("WIN32 is defined\n"); -#elif defined(__GNUC__) - sprintf(szCmd,"ping -c %d %s",pingCount,host.c_str()); - if(debugPingOutput) printf("NON WIN32 is defined\n"); -#else - #error "Your compiler needs to support popen!" -#endif - if(szCmd[0] != '\0') { - FILE *ping= NULL; -#ifdef WIN32 - ping= _popen(szCmd, "r"); - if(debugPingOutput) printf("WIN32 style _popen\n"); -#elif defined(__GNUC__) - ping= popen(szCmd, "r"); - if(debugPingOutput) printf("POSIX style _popen\n"); -#else - #error "Your compiler needs to support popen!" -#endif - if (ping != NULL){ - char buf[4000]=""; - int bufferPos = 0; - for(;feof(ping) == false;) { - char *data = fgets(&buf[bufferPos], 256, ping); - bufferPos = strlen(buf); - } -#ifdef WIN32 - _pclose(ping); -#elif defined(__GNUC__) - pclose(ping); -#else - #error "Your compiler needs to support popen!" - -#endif - - if(debugPingOutput) printf("Running cmd [%s] got [%s]\n",szCmd,buf); - - // Linux - //softcoder@softhauslinux:~/Code/megaglest/trunk/mk/linux$ ping -c 5 soft-haus.com - //PING soft-haus.com (65.254.250.110) 56(84) bytes of data. - //64 bytes from 65-254-250-110.yourhostingaccount.com (65.254.250.110): icmp_seq=1 ttl=242 time=133 ms - //64 bytes from 65-254-250-110.yourhostingaccount.com (65.254.250.110): icmp_seq=2 ttl=242 time=137 ms - // - // Windows XP - //C:\Code\megaglest\trunk\data\glest_game>ping -n 5 soft-haus.com - // - //Pinging soft-haus.com [65.254.250.110] with 32 bytes of data: - // - //Reply from 65.254.250.110: bytes=32 time=125ms TTL=242 - //Reply from 65.254.250.110: bytes=32 time=129ms TTL=242 - - std::string str = buf; - std::string::size_type ms_pos = 0; - int count = 0; - while ( ms_pos != std::string::npos) { - ms_pos = str.find("time=", ms_pos); - - if(debugPingOutput) printf("count = %d ms_pos = %d\n",count,ms_pos); - - if ( ms_pos != std::string::npos ) { - ++count; - - int endPos = str.find(" ms", ms_pos+5 ); - - if(debugPingOutput) printf("count = %d endPos = %d\n",count,endPos); - - if(endPos == std::string::npos) { - endPos = str.find("ms ", ms_pos+5 ); - - if(debugPingOutput) printf("count = %d endPos = %d\n",count,endPos); - } - - if(endPos != std::string::npos) { - - if(count == 1) { - result = 0; - } - int startPos = ms_pos + 5; - int posLength = endPos - startPos; - if(debugPingOutput) printf("count = %d startPos = %d posLength = %d str = [%s]\n",count,startPos,posLength,str.substr(startPos, posLength).c_str()); - - float pingMS = strToFloat(str.substr(startPos, posLength)); - result += pingMS; - } - - ms_pos += 5; // start next search after this "time=" } } - if(result > 0 && count > 1) { - result /= count; + if (SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork, "In [%s::%s Line: %d] Broadcast thread is exiting\n", __FILE__, __FUNCTION__, __LINE__); + } + + double Socket::getAveragePingMS(std::string host, int pingCount) { + double result = -1; + return result; + + /* + const bool debugPingOutput = false; + char szCmd[1024]=""; + #ifdef WIN32 + sprintf(szCmd,"ping -n %d %s",pingCount,host.c_str()); + if(debugPingOutput) printf("WIN32 is defined\n"); + #elif defined(__GNUC__) + sprintf(szCmd,"ping -c %d %s",pingCount,host.c_str()); + if(debugPingOutput) printf("NON WIN32 is defined\n"); + #else + #error "Your compiler needs to support popen!" + #endif + if(szCmd[0] != '\0') { + FILE *ping= NULL; + #ifdef WIN32 + ping= _popen(szCmd, "r"); + if(debugPingOutput) printf("WIN32 style _popen\n"); + #elif defined(__GNUC__) + ping= popen(szCmd, "r"); + if(debugPingOutput) printf("POSIX style _popen\n"); + #else + #error "Your compiler needs to support popen!" + #endif + if (ping != NULL){ + char buf[4000]=""; + int bufferPos = 0; + for(;feof(ping) == false;) { + char *data = fgets(&buf[bufferPos], 256, ping); + bufferPos = strlen(buf); + } + #ifdef WIN32 + _pclose(ping); + #elif defined(__GNUC__) + pclose(ping); + #else + #error "Your compiler needs to support popen!" + + #endif + + if(debugPingOutput) printf("Running cmd [%s] got [%s]\n",szCmd,buf); + + // Linux + //softcoder@softhauslinux:~/Code/megaglest/trunk/mk/linux$ ping -c 5 soft-haus.com + //PING soft-haus.com (65.254.250.110) 56(84) bytes of data. + //64 bytes from 65-254-250-110.yourhostingaccount.com (65.254.250.110): icmp_seq=1 ttl=242 time=133 ms + //64 bytes from 65-254-250-110.yourhostingaccount.com (65.254.250.110): icmp_seq=2 ttl=242 time=137 ms + // + // Windows XP + //C:\Code\megaglest\trunk\data\glest_game>ping -n 5 soft-haus.com + // + //Pinging soft-haus.com [65.254.250.110] with 32 bytes of data: + // + //Reply from 65.254.250.110: bytes=32 time=125ms TTL=242 + //Reply from 65.254.250.110: bytes=32 time=129ms TTL=242 + + std::string str = buf; + std::string::size_type ms_pos = 0; + int count = 0; + while ( ms_pos != std::string::npos) { + ms_pos = str.find("time=", ms_pos); + + if(debugPingOutput) printf("count = %d ms_pos = %d\n",count,ms_pos); + + if ( ms_pos != std::string::npos ) { + ++count; + + int endPos = str.find(" ms", ms_pos+5 ); + + if(debugPingOutput) printf("count = %d endPos = %d\n",count,endPos); + + if(endPos == std::string::npos) { + endPos = str.find("ms ", ms_pos+5 ); + + if(debugPingOutput) printf("count = %d endPos = %d\n",count,endPos); + } + + if(endPos != std::string::npos) { + + if(count == 1) { + result = 0; + } + int startPos = ms_pos + 5; + int posLength = endPos - startPos; + if(debugPingOutput) printf("count = %d startPos = %d posLength = %d str = [%s]\n",count,startPos,posLength,str.substr(startPos, posLength).c_str()); + + float pingMS = strToFloat(str.substr(startPos, posLength)); + result += pingMS; + } + + ms_pos += 5; // start next search after this "time=" + } + } + + if(result > 0 && count > 1) { + result /= count; + } + } + } + return result; + */ + } + + std::string Socket::getIpAddress() { + return ipAddress; + } + + void ServerSocket::addIPAddressToBlockedList(string value) { + if (isIPAddressBlocked(value) == false) { + blockIPList.push_back(value); + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Blocked IP Address [%s].\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, value.c_str()); } } + bool ServerSocket::isIPAddressBlocked(string value) const { + bool result = (std::find(blockIPList.begin(), blockIPList.end(), value) != blockIPList.end()); + return result; + } + + void ServerSocket::removeBlockedIPAddress(string value) { + vector::iterator iterFind = std::find(blockIPList.begin(), blockIPList.end(), value); + if (iterFind != blockIPList.end()) { + blockIPList.erase(iterFind); + } + } + + void ServerSocket::clearBlockedIPAddress() { + blockIPList.clear(); + } + + bool ServerSocket::hasBlockedIPAddresses() const { + return(blockIPList.size() > 0); + } + } - return result; -*/ -} - -std::string Socket::getIpAddress() { - return ipAddress; -} - -void ServerSocket::addIPAddressToBlockedList(string value) { - if(isIPAddressBlocked(value) == false) { - blockIPList.push_back(value); - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Blocked IP Address [%s].\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,value.c_str()); - } -} -bool ServerSocket::isIPAddressBlocked(string value) const { - bool result = (std::find(blockIPList.begin(),blockIPList.end(),value) != blockIPList.end()); - return result; -} - -void ServerSocket::removeBlockedIPAddress(string value) { - vector::iterator iterFind = std::find(blockIPList.begin(),blockIPList.end(),value); - if(iterFind != blockIPList.end()) { - blockIPList.erase(iterFind); - } -} - -void ServerSocket::clearBlockedIPAddress() { - blockIPList.clear(); -} - -bool ServerSocket::hasBlockedIPAddresses() const { - return(blockIPList.size() > 0); -} - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/platform/sdl/gl_wrap.cpp b/source/shared_lib/sources/platform/sdl/gl_wrap.cpp index 1b369f9ba..b1f764f9f 100644 --- a/source/shared_lib/sources/platform/sdl/gl_wrap.cpp +++ b/source/shared_lib/sources/platform/sdl/gl_wrap.cpp @@ -31,365 +31,359 @@ using namespace Shared::Util; using namespace Shared::Graphics; using namespace Shared::PlatformCommon; -namespace Shared{ namespace Platform{ +namespace Shared { + namespace Platform { -// Example values: -// DEFAULT_CHARSET (English) = 1 -// GB2312_CHARSET (Chinese) = 134 + // Example values: + // DEFAULT_CHARSET (English) = 1 + // GB2312_CHARSET (Chinese) = 134 #ifdef WIN32 -DWORD PlatformContextGl::charSet = DEFAULT_CHARSET; + DWORD PlatformContextGl::charSet = DEFAULT_CHARSET; #else -int PlatformContextGl::charSet = 1; + int PlatformContextGl::charSet = 1; #endif -// ====================================== -// class PlatformContextGl -// ====================================== -PlatformContextGl::PlatformContextGl() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - glcontext = NULL; - icon = NULL; - window = NULL; -} - -PlatformContextGl::~PlatformContextGl() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - end(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -SDL_Surface * PlatformContextGl::getScreenSurface() { - return SDL_GetWindowSurface(window); -} - -void PlatformContextGl::init(int colorBits, int depthBits, int stencilBits, - bool hardware_acceleration, - bool fullscreen_anti_aliasing, float gammaValue) { - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - Window::setupGraphicsScreen(depthBits, stencilBits, hardware_acceleration, fullscreen_anti_aliasing); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //printf("In [%s::%s %d] PlatformCommon::Private::shouldBeFullscreen = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,PlatformCommon::Private::shouldBeFullscreen); - - // SDL_WINDOW_FULLSCREEN seems very broken when changing resolutions that differ from the desktop resolution - // For now fullscreen will mean use desktop resolution - int flags = SDL_WINDOW_OPENGL; - if(PlatformCommon::Private::shouldBeFullscreen) { - Window::setIsFullScreen(true); - //flags |= SDL_WINDOW_FULLSCREEN; - flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; - } - else { - Window::setIsFullScreen(false); - } - - //flags |= SDL_HWSURFACE - - int resW = PlatformCommon::Private::ScreenWidth; - int resH = PlatformCommon::Private::ScreenHeight; - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] about to set resolution: %d x %d, colorBits = %d.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,resW,resH,colorBits); - - if(Window::getIsFullScreen() && (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { - //printf("#1 SDL_WINDOW_FULLSCREEN_DESKTOP\n"); - // TODO: which display? is 0 the designated primary display always? - SDL_Rect display_rect; - SDL_GetDisplayBounds(0, &display_rect); - - if(PlatformCommon::Private::ScreenWidth != display_rect.w || - PlatformCommon::Private::ScreenHeight != display_rect.h) { - printf("Auto Change resolution to (%d x %d) from (%d x %d)\n",display_rect.w,display_rect.h,resW,resH); - resW = display_rect.w; - resH = display_rect.h; - PlatformCommon::Private::ScreenWidth = display_rect.w; - PlatformCommon::Private::ScreenHeight = display_rect.h; - } - } - - int windowX = SDL_WINDOWPOS_UNDEFINED; - int windowY = SDL_WINDOWPOS_UNDEFINED; - string windowTitleText = "ZetaGlest"; - int windowDisplayID = -1; - - if(window != NULL) { - SDL_GetWindowPosition(window,&windowX,&windowY); - windowDisplayID = SDL_GetWindowDisplayIndex( window ); - //printf("windowDisplayID = %d\n",windowDisplayID); - if(Window::getIsFullScreen()) { - windowX = SDL_WINDOWPOS_CENTERED_DISPLAY(windowDisplayID); - windowY = SDL_WINDOWPOS_CENTERED_DISPLAY(windowDisplayID); - } - windowTitleText = SDL_GetWindowTitle(window); - - SDL_DestroyWindow(window); + // ====================================== + // class PlatformContextGl + // ====================================== + PlatformContextGl::PlatformContextGl() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + glcontext = NULL; + icon = NULL; window = NULL; } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + PlatformContextGl::~PlatformContextGl() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); - //screen = SDL_CreateWindow(resW, resH, colorBits, flags); - window = SDL_CreateWindow(windowTitleText.c_str(),windowX,windowY,resW, resH, flags); - if(window == 0) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + end(); - std::ostringstream msg; - msg << "Couldn't set video mode " - << resW << "x" << resH << " (" << colorBits - << "bpp " << stencilBits << " stencil " - << depthBits << " depth-buffer). SDL Error is: " << SDL_GetError(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,msg.str().c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,msg.str().c_str()); + SDL_Surface * PlatformContextGl::getScreenSurface() { + return SDL_GetWindowSurface(window); + } - //screen = SDL_SetVideoMode(resW, resH, i, flags); - window = SDL_CreateWindow(windowTitleText.c_str(),windowX,windowY,resW, resH, flags); - if(window == 0) { - // try to switch to native desktop resolution - window = SDL_CreateWindow(windowTitleText.c_str(),windowX,windowY,0, 0,SDL_WINDOW_FULLSCREEN_DESKTOP|flags); + void PlatformContextGl::init(int colorBits, int depthBits, int stencilBits, + bool hardware_acceleration, + bool fullscreen_anti_aliasing, float gammaValue) { + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + Window::setupGraphicsScreen(depthBits, stencilBits, hardware_acceleration, fullscreen_anti_aliasing); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + //printf("In [%s::%s %d] PlatformCommon::Private::shouldBeFullscreen = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,PlatformCommon::Private::shouldBeFullscreen); + + // SDL_WINDOW_FULLSCREEN seems very broken when changing resolutions that differ from the desktop resolution + // For now fullscreen will mean use desktop resolution + int flags = SDL_WINDOW_OPENGL; + if (PlatformCommon::Private::shouldBeFullscreen) { + Window::setIsFullScreen(true); + //flags |= SDL_WINDOW_FULLSCREEN; + flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + } else { + Window::setIsFullScreen(false); } - if(window == 0) { - // try to revert to 640x480 - window = SDL_CreateWindow(windowTitleText.c_str(),windowX,windowY,650, 480,SDL_WINDOW_FULLSCREEN_DESKTOP); - } - if(window == 0) { - throw std::runtime_error(msg.str()); - } - } -// int totalDisplays = SDL_GetNumVideoDisplays(); -// windowDisplayID = SDL_GetWindowDisplayIndex( window ); -// printf("!!! totalDisplays = %d, windowDisplayID = %d\n",totalDisplays,windowDisplayID); + //flags |= SDL_HWSURFACE - //SDL_SetWindowDisplayMode(window, NULL); + int resW = PlatformCommon::Private::ScreenWidth; + int resH = PlatformCommon::Private::ScreenHeight; - bool isNewWindow = (glcontext == NULL); - if(isNewWindow) { - glcontext = SDL_GL_CreateContext(window); - } - else { - SDL_GL_MakeCurrent(window, glcontext); - } + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - int h; - int w; - SDL_GetWindowSize(window, &w, &h); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] about to set resolution: %d x %d, colorBits = %d.\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, resW, resH, colorBits); - if((w != resW || h != resH) && (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { - //printf("#2 SDL_WINDOW_FULLSCREEN_DESKTOP\n"); - printf("#1 Change resolution mismatch get (%d x %d) desired (%d x %d)\n",w,h,resW,resH); + if (Window::getIsFullScreen() && (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { + //printf("#1 SDL_WINDOW_FULLSCREEN_DESKTOP\n"); + // TODO: which display? is 0 the designated primary display always? + SDL_Rect display_rect; + SDL_GetDisplayBounds(0, &display_rect); - PlatformCommon::Private::ScreenWidth = w; - PlatformCommon::Private::ScreenHeight = h; + if (PlatformCommon::Private::ScreenWidth != display_rect.w || + PlatformCommon::Private::ScreenHeight != display_rect.h) { + printf("Auto Change resolution to (%d x %d) from (%d x %d)\n", display_rect.w, display_rect.h, resW, resH); + resW = display_rect.w; + resH = display_rect.h; + PlatformCommon::Private::ScreenWidth = display_rect.w; + PlatformCommon::Private::ScreenHeight = display_rect.h; + } + } - resW = PlatformCommon::Private::ScreenWidth; - resH = PlatformCommon::Private::ScreenHeight; + int windowX = SDL_WINDOWPOS_UNDEFINED; + int windowY = SDL_WINDOWPOS_UNDEFINED; + string windowTitleText = "ZetaGlest"; + int windowDisplayID = -1; - printf("#2 Change resolution to (%d x %d)\n",resW,resH); + if (window != NULL) { + SDL_GetWindowPosition(window, &windowX, &windowY); + windowDisplayID = SDL_GetWindowDisplayIndex(window); + //printf("windowDisplayID = %d\n",windowDisplayID); + if (Window::getIsFullScreen()) { + windowX = SDL_WINDOWPOS_CENTERED_DISPLAY(windowDisplayID); + windowY = SDL_WINDOWPOS_CENTERED_DISPLAY(windowDisplayID); + } + windowTitleText = SDL_GetWindowTitle(window); -// SDL_SetWindowFullscreen(window,0); -// SDL_SetWindowSize(window, resW, resH); -// SDL_SetWindowFullscreen(window,flags); -// SDL_SetWindowSize(window, resW, resH); -// -// SDL_GetWindowSize(window, &w, &h); -// printf("#2 Change resolution mismatch get (%d x %d) desired (%d x %d)\n",w,resW,h,resH); - } - glViewport( 0, 0, w, h ) ; + SDL_DestroyWindow(window); + window = NULL; + } - // There seems to be a bug where if relative mouse mouse is enabled when you create a new window, - // the window still reports that it has input & mouse focus, but it doesn't send any events for - // mouse motion or mouse button clicks. You can fix this by toggling relative mouse mode. - if (SDL_GetRelativeMouseMode()) { - SDL_SetRelativeMouseMode(SDL_FALSE); - SDL_SetRelativeMouseMode(SDL_TRUE); - } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); + //screen = SDL_CreateWindow(resW, resH, colorBits, flags); + window = SDL_CreateWindow(windowTitleText.c_str(), windowX, windowY, resW, resH, flags); + if (window == 0) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + std::ostringstream msg; + msg << "Couldn't set video mode " + << resW << "x" << resH << " (" << colorBits + << "bpp " << stencilBits << " stencil " + << depthBits << " depth-buffer). SDL Error is: " << SDL_GetError(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, msg.str().c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, msg.str().c_str()); + + //screen = SDL_SetVideoMode(resW, resH, i, flags); + window = SDL_CreateWindow(windowTitleText.c_str(), windowX, windowY, resW, resH, flags); + if (window == 0) { + // try to switch to native desktop resolution + window = SDL_CreateWindow(windowTitleText.c_str(), windowX, windowY, 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP | flags); + } + if (window == 0) { + // try to revert to 640x480 + window = SDL_CreateWindow(windowTitleText.c_str(), windowX, windowY, 650, 480, SDL_WINDOW_FULLSCREEN_DESKTOP); + } + if (window == 0) { + throw std::runtime_error(msg.str()); + } + } + + // int totalDisplays = SDL_GetNumVideoDisplays(); + // windowDisplayID = SDL_GetWindowDisplayIndex( window ); + // printf("!!! totalDisplays = %d, windowDisplayID = %d\n",totalDisplays,windowDisplayID); + + //SDL_SetWindowDisplayMode(window, NULL); + + bool isNewWindow = (glcontext == NULL); + if (isNewWindow) { + glcontext = SDL_GL_CreateContext(window); + } else { + SDL_GL_MakeCurrent(window, glcontext); + } + + int h; + int w; + SDL_GetWindowSize(window, &w, &h); + + if ((w != resW || h != resH) && (flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { + //printf("#2 SDL_WINDOW_FULLSCREEN_DESKTOP\n"); + printf("#1 Change resolution mismatch get (%d x %d) desired (%d x %d)\n", w, h, resW, resH); + + PlatformCommon::Private::ScreenWidth = w; + PlatformCommon::Private::ScreenHeight = h; + + resW = PlatformCommon::Private::ScreenWidth; + resH = PlatformCommon::Private::ScreenHeight; + + printf("#2 Change resolution to (%d x %d)\n", resW, resH); + + // SDL_SetWindowFullscreen(window,0); + // SDL_SetWindowSize(window, resW, resH); + // SDL_SetWindowFullscreen(window,flags); + // SDL_SetWindowSize(window, resW, resH); + // + // SDL_GetWindowSize(window, &w, &h); + // printf("#2 Change resolution mismatch get (%d x %d) desired (%d x %d)\n",w,resW,h,resH); + } + glViewport(0, 0, w, h); + + // There seems to be a bug where if relative mouse mouse is enabled when you create a new window, + // the window still reports that it has input & mouse focus, but it doesn't send any events for + // mouse motion or mouse button clicks. You can fix this by toggling relative mouse mode. + if (SDL_GetRelativeMouseMode()) { + SDL_SetRelativeMouseMode(SDL_FALSE); + SDL_SetRelativeMouseMode(SDL_TRUE); + } #ifndef WIN32 - string mg_icon_file = ""; + string mg_icon_file = ""; #if defined(CUSTOM_DATA_INSTALL_PATH) - if(fileExists(formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)) + "megaglest.png")) { - mg_icon_file = formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)) + "megaglest.png"; - } - else if(fileExists(formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)) + "megaglest.bmp")) { - mg_icon_file = formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)) + "megaglest.bmp"; - } + if (fileExists(formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)) + "megaglest.png")) { + mg_icon_file = formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)) + "megaglest.png"; + } else if (fileExists(formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)) + "megaglest.bmp")) { + mg_icon_file = formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)) + "megaglest.bmp"; + } #endif - if(mg_icon_file == "" && fileExists("megaglest.png")) { - mg_icon_file = "megaglest.png"; - } - else if(mg_icon_file == "" && fileExists("megaglest.bmp")) { - mg_icon_file = "megaglest.bmp"; - } - else if(mg_icon_file == "" && fileExists("/usr/share/pixmaps/megaglest.png")) { - mg_icon_file = "/usr/share/pixmaps/megaglest.png"; - } - else if(mg_icon_file == "" && fileExists("/usr/share/pixmaps/megaglest.bmp")) { - mg_icon_file = "/usr/share/pixmaps/megaglest.bmp"; + if (mg_icon_file == "" && fileExists("megaglest.png")) { + mg_icon_file = "megaglest.png"; + } else if (mg_icon_file == "" && fileExists("megaglest.bmp")) { + mg_icon_file = "megaglest.bmp"; + } else if (mg_icon_file == "" && fileExists("/usr/share/pixmaps/megaglest.png")) { + mg_icon_file = "/usr/share/pixmaps/megaglest.png"; + } else if (mg_icon_file == "" && fileExists("/usr/share/pixmaps/megaglest.bmp")) { + mg_icon_file = "/usr/share/pixmaps/megaglest.bmp"; + } + + if (mg_icon_file != "") { + + if (icon != NULL) { + SDL_FreeSurface(icon); + icon = NULL; + } + + //printf("Loading icon [%s]\n",mg_icon_file.c_str()); + if (extractExtension(mg_icon_file) == "bmp") { + icon = SDL_LoadBMP(mg_icon_file.c_str()); + } else { + //printf("Loadng png icon\n"); + Texture2D *texture2D = GraphicsInterface::getInstance().getFactory()->newTexture2D(); + texture2D->load(mg_icon_file); + std::pair result = texture2D->CreateSDLSurface(true); + icon = result.first; + delete texture2D; + delete[] result.second; + } + + //SDL_Surface *icon = IMG_Load("zetaglest.ico"); + + + //#if !defined(MACOSX) + // Set Icon (must be done before any sdl_setvideomode call) + // But don't set it on OS X, as we use a nicer external icon there. + //#if WORDS_BIGENDIAN + // SDL_Surface* icon= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,8,128,0xff000000,0x00ff0000,0x0000ff00,0); + //#else + // SDL_Surface* icon= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,32,128,0x000000ff,0x0000ff00,0x00ff0000,0xff000000); + //#endif + + //printf("In [%s::%s Line: %d] icon = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,icon); + if (icon == NULL) { + printf("Icon Load Error #1: %s\n", SDL_GetError()); + } + if (icon != NULL) { + + //uint32 colorkey = SDL_MapRGB(icon->format, 255, 0, 255); + //SDL_SetColorKey(icon, SDL_SRCCOLORKEY, colorkey); + if (SDL_SetColorKey(icon, SDL_TRUE, SDL_MapRGB(icon->format, 255, 0, 255))) { + printf("Icon Load Error #2: %s\n", SDL_GetError()); + } else { + SDL_SetWindowIcon(window, icon); + } + } + } +#endif + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + //SDL_WM_GrabInput(SDL_GRAB_OFF); + //SDL_SetRelativeMouseMode(SDL_FALSE); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d] BEFORE glewInit call\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + GLuint err = glewInit(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d] AFTER glewInit call err = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, err); + + if (GLEW_OK != err) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + fprintf(stderr, "Error [main]: glewInit failed: %s\n", glewGetErrorString(err)); + //return 1; + throw std::runtime_error((char *) glewGetErrorString(err)); + } + //fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + int bufferSize = (resW * resH * BaseColorPickEntity::COLOR_COMPONENTS); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + BaseColorPickEntity::init(bufferSize); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (gammaValue != 0.0) { + //printf("Attempting to call SDL_SetGamma using value %f\n", gammaValue); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SDL_SetWindowBrightness(window, gammaValue) < 0) { + printf("WARNING, SDL_SetWindowBrightness failed using value %f [%s]\n", gammaValue, SDL_GetError()); + } + } + + // SDL_WM_GrabInput(SDL_GRAB_ON); + // SDL_WM_GrabInput(SDL_GRAB_OFF); + SDL_SetRelativeMouseMode(SDL_TRUE); + SDL_SetRelativeMouseMode(SDL_FALSE); + + + // if(Window::getIsFullScreen()) + // SDL_SetWindowGrab(window, SDL_TRUE); + // else + SDL_SetWindowGrab(window, SDL_FALSE); + + // if(Window::getIsFullScreen()) { + // SDL_SetWindowSize(window, resW, resH); + // //SDL_SetWindowFullscreen(window,SDL_WINDOW_FULLSCREEN); + // SDL_SetWindowSize(window, resW, resH); + // } + + // SDL_SetRelativeMouseMode(SDL_TRUE); + // SDL_SetRelativeMouseMode(SDL_FALSE); + } } - if(mg_icon_file != "") { + void PlatformContextGl::end() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (icon != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - if(icon != NULL) { SDL_FreeSurface(icon); icon = NULL; } - //printf("Loading icon [%s]\n",mg_icon_file.c_str()); - if(extractExtension(mg_icon_file) == "bmp") { - icon = SDL_LoadBMP(mg_icon_file.c_str()); - } - else { - //printf("Loadng png icon\n"); - Texture2D *texture2D = GraphicsInterface::getInstance().getFactory()->newTexture2D(); - texture2D->load(mg_icon_file); - std::pair result = texture2D->CreateSDLSurface(true); - icon = result.first; - delete texture2D; - delete [] result.second; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (window != NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + SDL_DestroyWindow(window); + window = NULL; } - //SDL_Surface *icon = IMG_Load("zetaglest.ico"); - - - //#if !defined(MACOSX) - // Set Icon (must be done before any sdl_setvideomode call) - // But don't set it on OS X, as we use a nicer external icon there. - //#if WORDS_BIGENDIAN - // SDL_Surface* icon= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,8,128,0xff000000,0x00ff0000,0x0000ff00,0); - //#else - // SDL_Surface* icon= SDL_CreateRGBSurfaceFrom((void*)logo,32,32,32,128,0x000000ff,0x0000ff00,0x00ff0000,0xff000000); - //#endif - - //printf("In [%s::%s Line: %d] icon = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,icon); - if(icon == NULL) { - printf("Icon Load Error #1: %s\n", SDL_GetError()); - } - if(icon != NULL) { - - //uint32 colorkey = SDL_MapRGB(icon->format, 255, 0, 255); - //SDL_SetColorKey(icon, SDL_SRCCOLORKEY, colorkey); - if(SDL_SetColorKey(icon, SDL_TRUE, SDL_MapRGB(icon->format, 255, 0, 255))) { - printf("Icon Load Error #2: %s\n", SDL_GetError()); - } - else { - SDL_SetWindowIcon(window,icon); - } - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); } -#endif - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //SDL_WM_GrabInput(SDL_GRAB_OFF); - //SDL_SetRelativeMouseMode(SDL_FALSE); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d] BEFORE glewInit call\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - GLuint err = glewInit(); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d] AFTER glewInit call err = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,err); - - if (GLEW_OK != err) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - fprintf(stderr, "Error [main]: glewInit failed: %s\n", glewGetErrorString(err)); - //return 1; - throw std::runtime_error((char *)glewGetErrorString(err)); + void PlatformContextGl::makeCurrent() { } - //fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - int bufferSize = (resW * resH * BaseColorPickEntity::COLOR_COMPONENTS); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - BaseColorPickEntity::init(bufferSize); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(gammaValue != 0.0) { - //printf("Attempting to call SDL_SetGamma using value %f\n", gammaValue); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if (SDL_SetWindowBrightness(window, gammaValue) < 0) { - printf("WARNING, SDL_SetWindowBrightness failed using value %f [%s]\n", gammaValue,SDL_GetError()); + void PlatformContextGl::swapBuffers() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + SDL_GL_SwapWindow(window); } } -// SDL_WM_GrabInput(SDL_GRAB_ON); -// SDL_WM_GrabInput(SDL_GRAB_OFF); - SDL_SetRelativeMouseMode(SDL_TRUE); - SDL_SetRelativeMouseMode(SDL_FALSE); + const char *getPlatformExtensions(const PlatformContextGl *pcgl) { + return ""; + } -// if(Window::getIsFullScreen()) -// SDL_SetWindowGrab(window, SDL_TRUE); -// else - SDL_SetWindowGrab(window, SDL_FALSE); + void *getGlProcAddress(const char *procName) { + void* proc = SDL_GL_GetProcAddress(procName); + assert(proc != NULL); + return proc; + } -// if(Window::getIsFullScreen()) { -// SDL_SetWindowSize(window, resW, resH); -// //SDL_SetWindowFullscreen(window,SDL_WINDOW_FULLSCREEN); -// SDL_SetWindowSize(window, resW, resH); -// } - -// SDL_SetRelativeMouseMode(SDL_TRUE); -// SDL_SetRelativeMouseMode(SDL_FALSE); } -} - -void PlatformContextGl::end() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(icon != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - SDL_FreeSurface(icon); - icon = NULL; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(window != NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - SDL_DestroyWindow(window); - window = NULL; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void PlatformContextGl::makeCurrent() { -} - -void PlatformContextGl::swapBuffers() { - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - SDL_GL_SwapWindow(window); - } -} - - -const char *getPlatformExtensions(const PlatformContextGl *pcgl) { - return ""; -} - -void *getGlProcAddress(const char *procName) { - void* proc = SDL_GL_GetProcAddress(procName); - assert(proc!=NULL); - return proc; -} - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/platform/sdl/thread.cpp b/source/shared_lib/sources/platform/sdl/thread.cpp index c56507993..57fad0a60 100644 --- a/source/shared_lib/sources/platform/sdl/thread.cpp +++ b/source/shared_lib/sources/platform/sdl/thread.cpp @@ -21,931 +21,920 @@ using namespace std; -namespace Shared { namespace Platform { +namespace Shared { + namespace Platform { -bool Thread::enableVerboseMode = false; -Mutex Thread::mutexthreadList; -vector Thread::threadList; -unsigned long Thread::mainThreadId = -1; + bool Thread::enableVerboseMode = false; + Mutex Thread::mutexthreadList; + vector Thread::threadList; + unsigned long Thread::mainThreadId = -1; -auto_ptr Mutex::mutexMutexList(new Mutex(CODE_AT_LINE)); -vector Mutex::mutexList; + auto_ptr Mutex::mutexMutexList(new Mutex(CODE_AT_LINE)); + vector Mutex::mutexList; -class ThreadGarbageCollector; -class Mutex; -class MutexSafeWrapper; + class ThreadGarbageCollector; + class Mutex; + class MutexSafeWrapper; -static auto_ptr cleanupThread; -static auto_ptr cleanupThreadMutex(new Mutex(CODE_AT_LINE)); + static auto_ptr cleanupThread; + static auto_ptr cleanupThreadMutex(new Mutex(CODE_AT_LINE)); -class ThreadGarbageCollector : public BaseThread -{ -protected: - Mutex mutexPendingCleanupList; - vector pendingCleanupList; + class ThreadGarbageCollector : public BaseThread { + protected: + Mutex mutexPendingCleanupList; + vector pendingCleanupList; - bool cleanupPendingThreads() { - MutexSafeWrapper safeMutex(&mutexPendingCleanupList); - if(pendingCleanupList.empty() == false) { - for(unsigned int index = 0; index < pendingCleanupList.size(); ++index) { - Thread *thread = pendingCleanupList[index]; - cleanupPendingThread(thread); + bool cleanupPendingThreads() { + MutexSafeWrapper safeMutex(&mutexPendingCleanupList); + if (pendingCleanupList.empty() == false) { + for (unsigned int index = 0; index < pendingCleanupList.size(); ++index) { + Thread *thread = pendingCleanupList[index]; + cleanupPendingThread(thread); + } + pendingCleanupList.clear(); + return true; + } + return false; } - pendingCleanupList.clear(); - return true; - } - return false; - } -public: - ThreadGarbageCollector() : BaseThread() { - if(Thread::getEnableVerboseMode()) printf("In %s Line: %d this: %p\n",__FUNCTION__,__LINE__,this); - uniqueID = "ThreadGarbageCollector"; - removeThreadFromList(); - } - virtual ~ThreadGarbageCollector() { - if(Thread::getEnableVerboseMode()) { - printf("In %s Line: %d this: %p\n",__FUNCTION__,__LINE__,this); - string stack = PlatformExceptionHandler::getStackTrace(); - printf("In %s Line: %d this: %p stack: %s\n",__FUNCTION__,__LINE__,this,stack.c_str()); - } - } - virtual void execute() { - if(Thread::getEnableVerboseMode()) printf("In %s Line: %d this: %p\n",__FUNCTION__,__LINE__,this); - - RunningStatusSafeWrapper runningStatus(this); - for(;getQuitStatus() == false;) { - if(cleanupPendingThreads() == false) { - if(getQuitStatus() == false) { - sleep(200); + public: + ThreadGarbageCollector() : BaseThread() { + if (Thread::getEnableVerboseMode()) printf("In %s Line: %d this: %p\n", __FUNCTION__, __LINE__, this); + uniqueID = "ThreadGarbageCollector"; + removeThreadFromList(); + } + virtual ~ThreadGarbageCollector() { + if (Thread::getEnableVerboseMode()) { + printf("In %s Line: %d this: %p\n", __FUNCTION__, __LINE__, this); + string stack = PlatformExceptionHandler::getStackTrace(); + printf("In %s Line: %d this: %p stack: %s\n", __FUNCTION__, __LINE__, this, stack.c_str()); } } + virtual void execute() { + if (Thread::getEnableVerboseMode()) printf("In %s Line: %d this: %p\n", __FUNCTION__, __LINE__, this); + + RunningStatusSafeWrapper runningStatus(this); + for (; getQuitStatus() == false;) { + if (cleanupPendingThreads() == false) { + if (getQuitStatus() == false) { + sleep(200); + } + } + } + + if (Thread::getEnableVerboseMode()) printf("In %s Line: %d this: %p\n", __FUNCTION__, __LINE__, this); + + cleanupPendingThreads(); + + if (Thread::getEnableVerboseMode()) printf("In %s Line: %d this: %p\n", __FUNCTION__, __LINE__, this); + } + void addThread(Thread *thread) { + if (Thread::getEnableVerboseMode()) printf("In %s Line: %d this: %p\n", __FUNCTION__, __LINE__, this); + + MutexSafeWrapper safeMutex(&mutexPendingCleanupList); + pendingCleanupList.push_back(thread); + safeMutex.ReleaseLock(); + + if (Thread::getEnableVerboseMode()) printf("In %s Line: %d this: %p\n", __FUNCTION__, __LINE__, this); + } + + static void cleanupPendingThread(Thread *thread) { + if (thread != NULL) { + BaseThread *base_thread = dynamic_cast(thread); + if (base_thread != NULL && + (base_thread->getRunningStatus() == true || base_thread->getExecutingTask() == true)) { + if (Thread::getEnableVerboseMode()) printf("!!!! cleanupPendingThread Line: %d thread = %p [%s]\n", __LINE__, thread, base_thread->getUniqueID().c_str()); + + base_thread->signalQuit(); + sleep(10); + + if (Thread::getEnableVerboseMode()) printf("!!!! cleanupPendingThread Line: %d thread = %p [%s]\n", __LINE__, thread, base_thread->getUniqueID().c_str()); + + if (base_thread->getRunningStatus() == true || base_thread->getExecutingTask() == true) { + + if (Thread::getEnableVerboseMode()) printf("\n\n\n$$$$$$$$$$$$$$$$$$$$$$$$$$$ cleanupPendingThread Line: %d thread = %p [%s]\n", __LINE__, thread, base_thread->getUniqueID().c_str()); + + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] cannot delete active thread: getRunningStatus(): %d getExecutingTask: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, base_thread->getRunningStatus(), base_thread->getExecutingTask()); + throw megaglest_runtime_error(szBuf); + } + } + + if (Thread::getEnableVerboseMode()) printf("!!!! cleanupPendingThread Line: %d thread = %p [%s]\n", __LINE__, thread, (base_thread != NULL ? base_thread->getUniqueID().c_str() : "n/a")); + + delete thread; + + if (Thread::getEnableVerboseMode()) printf("!!!! cleanupPendingThread Line: %d thread = NULL [%s]\n", __LINE__, (base_thread != NULL ? base_thread->getUniqueID().c_str() : "n/a")); + } + } + + }; + + // ===================================== + // Threads + // ===================================== + Thread::Thread() : thread(NULL), + mutexthreadAccessor(new Mutex(CODE_AT_LINE)), + deleteAfterExecute(false), currentState(thrsNew) { + addThreadToList(); } - if(Thread::getEnableVerboseMode()) printf("In %s Line: %d this: %p\n",__FUNCTION__,__LINE__,this); + unsigned long Thread::getCurrentThreadId() { + return SDL_ThreadID(); + } + void Thread::setMainThreadId() { + mainThreadId = getCurrentThreadId(); + } + bool Thread::isCurrentThreadMainThread() { + return getCurrentThreadId() == mainThreadId; + } - cleanupPendingThreads(); + void Thread::addThreadToList() { + MutexSafeWrapper safeMutex(&Thread::mutexthreadList); + Thread::threadList.push_back(this); + safeMutex.ReleaseLock(); + } + void Thread::removeThreadFromList() { + MutexSafeWrapper safeMutex(&Thread::mutexthreadList); + if (Thread::threadList.empty() == false) { + std::vector::iterator iterFind = std::find(Thread::threadList.begin(), Thread::threadList.end(), this); + if (iterFind == Thread::threadList.end()) { + if (this != cleanupThread.get()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] iterFind == Thread::threadList.end() Thread::threadList.size() = %ld", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, Thread::threadList.size()); + throw megaglest_runtime_error(szBuf); + } + } else { + Thread::threadList.erase(iterFind); + } + } + safeMutex.ReleaseLock(); + } - if(Thread::getEnableVerboseMode()) printf("In %s Line: %d this: %p\n",__FUNCTION__,__LINE__,this); - } - void addThread(Thread *thread) { - if(Thread::getEnableVerboseMode()) printf("In %s Line: %d this: %p\n",__FUNCTION__,__LINE__,this); + void Thread::shutdownThreads() { + MutexSafeWrapper safeMutex(&Thread::mutexthreadList); + for (unsigned int index = 0; index < Thread::threadList.size(); ++index) { + BaseThread *thread = dynamic_cast(Thread::threadList[index]); + if (thread && thread->getRunningStatus() == true) { + thread->signalQuit(); + } + } + safeMutex.ReleaseLock(); - MutexSafeWrapper safeMutex(&mutexPendingCleanupList); - pendingCleanupList.push_back(thread); - safeMutex.ReleaseLock(); + if (Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d\n", __LINE__); + if (cleanupThread.get() != 0) { + //printf("In Thread::shutdownThreads Line: %d\n",__LINE__); + sleep(0); + cleanupThread->signalQuit(); - if(Thread::getEnableVerboseMode()) printf("In %s Line: %d this: %p\n",__FUNCTION__,__LINE__,this); - } + //printf("In Thread::shutdownThreads Line: %d\n",__LINE__); + time_t elapsed = time(NULL); + for (; cleanupThread->getRunningStatus() == true && + difftime((long int) time(NULL), elapsed) <= 5;) { + sleep(100); + } + //printf("In Thread::shutdownThreads Line: %d\n",__LINE__); + //sleep(100); + + MutexSafeWrapper safeMutex(cleanupThreadMutex.get()); + cleanupThread.reset(0); + //printf("In Thread::shutdownThreads Line: %d\n",__LINE__); + } + } + + bool Thread::isThreadExecuteCompleteStatus() { + MutexSafeWrapper safeMutex(mutexthreadAccessor); + return (currentState == thrsExecuteComplete); + } + Thread::~Thread() { + BaseThread *base_thread = dynamic_cast(this); + string uniqueId = (base_thread ? base_thread->getUniqueID() : "new_base_thread_prev_null"); + if (Thread::getEnableVerboseMode()) printf("In ~Thread Line: %d [%p] thread = %p uniqueId [%s]\n", __LINE__, this, thread, uniqueId.c_str()); + + MutexSafeWrapper safeMutex(mutexthreadAccessor); + if (thread != NULL) { + + safeMutex.ReleaseLock(); + + if (isThreadExecuteCompleteStatus() == false) { + printf("**WARNING** thread destructor delayed, trying to exit...\n"); + + time_t elapsed = time(NULL); + for (; difftime((long int) time(NULL), elapsed) <= 5;) { + sleep(0); + + if (isThreadExecuteCompleteStatus() == true) { + break; + } + } + } + + if (isThreadExecuteCompleteStatus() == false) { + printf("**WARNING** thread destructor will KILL thread [%p]...\n", thread); + //SDL_KillThread(thread); + } else { + if (Thread::getEnableVerboseMode()) printf("In ~Thread Line: %d [%p] thread = %p uniqueId [%s]\n", __LINE__, this, thread, uniqueId.c_str()); + SDL_WaitThread(thread, NULL); + } + thread = NULL; + } else { + safeMutex.ReleaseLock(); + } + + if (Thread::getEnableVerboseMode()) printf("In ~Thread Line: %d [%p] thread = %p\n", __LINE__, this, thread); + + removeThreadFromList(); + + delete mutexthreadAccessor; + mutexthreadAccessor = NULL; + if (Thread::getEnableVerboseMode()) printf("In ~Thread Line: %d [%p] thread = %p\n", __LINE__, this, thread); + } + + std::vector Thread::getThreadList() { + std::vector result; + MutexSafeWrapper safeMutex(&Thread::mutexthreadList); + result = threadList; + safeMutex.ReleaseLock(); + return result; + } + + void Thread::start() { + if (Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n", __LINE__); + + MutexSafeWrapper safeMutex(mutexthreadAccessor); + currentState = thrsStarting; + + BaseThread *base_thread = dynamic_cast(this); + if (base_thread) base_thread->setStarted(true); + string uniqueId = (base_thread ? base_thread->getUniqueID() : "new_base_thread_prev_null"); + + if (Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n", __LINE__); + + thread = SDL_CreateThread(beginExecution, uniqueId.c_str(), this); + + if (Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d thread = %p uniqueId [%s]\n", __LINE__, thread, uniqueId.c_str()); + + if (thread == NULL) { + if (Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n", __LINE__); + + if (base_thread) base_thread->setStarted(false); + + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] thread == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } + + if (Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n", __LINE__); + //printf("In Thread::start Line: %d [%p] thread = %p\n",__LINE__,this,thread); + } + + bool Thread::threadObjectValid() { + MutexSafeWrapper safeMutex(mutexthreadAccessor); + return (thread != NULL); + } + + void Thread::setPriority(Thread::Priority threadPriority) { + NOIMPL; + } + + int Thread::beginExecution(void* data) { + Thread* thread = static_cast (data); + if (thread == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] thread == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + printf("%s", szBuf); + + throw megaglest_runtime_error(szBuf); + } + + MutexSafeWrapper safeMutex(thread->mutexthreadAccessor); + thread->currentState = thrsExecuteStart; + safeMutex.ReleaseLock(true); - static void cleanupPendingThread(Thread *thread) { - if(thread != NULL) { BaseThread *base_thread = dynamic_cast(thread); - if(base_thread != NULL && - (base_thread->getRunningStatus() == true || base_thread->getExecutingTask() == true)) { - if(Thread::getEnableVerboseMode()) printf("!!!! cleanupPendingThread Line: %d thread = %p [%s]\n",__LINE__,thread,base_thread->getUniqueID().c_str()); + //ThreadGarbageCollector *garbage_collector = dynamic_cast(thread); + if (Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d thread = %p base_thread = %p [%s]\n", __LINE__, thread, base_thread, (base_thread != NULL ? base_thread->getUniqueID().c_str() : "n/a")); - base_thread->signalQuit(); - sleep(10); + if (thread->threadObjectValid() == true) { + safeMutex.Lock(); + thread->currentState = thrsExecuting; + safeMutex.ReleaseLock(true); - if(Thread::getEnableVerboseMode()) printf("!!!! cleanupPendingThread Line: %d thread = %p [%s]\n",__LINE__,thread,base_thread->getUniqueID().c_str()); + thread->execute(); - if(base_thread->getRunningStatus() == true || base_thread->getExecutingTask() == true) { + safeMutex.Lock(); + thread->currentState = thrsExecuted; + safeMutex.ReleaseLock(true); + } - if(Thread::getEnableVerboseMode()) printf("\n\n\n$$$$$$$$$$$$$$$$$$$$$$$$$$$ cleanupPendingThread Line: %d thread = %p [%s]\n",__LINE__,thread,base_thread->getUniqueID().c_str()); + if (Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d thread = %p base_thread = %p [%s]\n", __LINE__, thread, base_thread, (base_thread != NULL ? base_thread->getUniqueID().c_str() : "n/a")); - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] cannot delete active thread: getRunningStatus(): %d getExecutingTask: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,base_thread->getRunningStatus(),base_thread->getExecutingTask()); + if (thread->threadObjectValid() == true) { + safeMutex.Lock(); + thread->currentState = thrsExecuteAutoClean; + safeMutex.ReleaseLock(); + thread->queueAutoCleanThread(); + } + + if (Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n", __LINE__); + MutexSafeWrapper safeMutex2(thread->mutexthreadAccessor); + + if (Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n", __LINE__); + if (thread->threadObjectValid() == true) { + if (Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n", __LINE__); + thread->currentState = thrsExecuteComplete; + } + if (Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n", __LINE__); + safeMutex2.ReleaseLock(); + if (Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n", __LINE__); + + return 0; + } + + void Thread::queueAutoCleanThread() { + if (this->deleteAfterExecute == true) { + if (Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d\n", __LINE__); + + BaseThread *base_thread = dynamic_cast(this); + //ThreadGarbageCollector *garbage_collector = dynamic_cast(this); + if (Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d thread = %p base_thread = %p [%s]\n", __LINE__, this, base_thread, (base_thread != NULL ? base_thread->getUniqueID().c_str() : "n/a")); + + MutexSafeWrapper safeMutex(cleanupThreadMutex.get()); + if (cleanupThread.get() == NULL) { + if (Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d\n", __LINE__); + cleanupThread.reset(new ThreadGarbageCollector()); + + safeMutex.ReleaseLock(); + cleanupThread->start(); + } else { + safeMutex.ReleaseLock(); + } + for (time_t elapsed = time(NULL); + cleanupThread->getRunningStatus() == false && + cleanupThread->getQuitStatus() == false && + difftime(time(NULL), elapsed) < 3;) { + sleep(0); + } + + if (cleanupThread->getQuitStatus() == true) { + //ThreadGarbageCollector::cleanupPendingThread(this); + if (cleanupThread->getRunningStatus() == false) { + if (Thread::getEnableVerboseMode()) printf("MANUAL DELETE In Thread::shutdownThreads Line: %d this [%p]\n", __LINE__, this); + + cleanupThread->addThread(this); + cleanupThread->start(); + + if (Thread::getEnableVerboseMode()) printf("MANUAL DELETE In Thread::shutdownThreads Line: %d\n", __LINE__); + return; + } else { + if (Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d this [%p]\n", __LINE__, this); + + for (time_t elapsed = time(NULL); + cleanupThread->getRunningStatus() == true && + cleanupThread->getQuitStatus() == true && + difftime(time(NULL), elapsed) < 3;) { + sleep(0); + } + sleep(0); + + if (Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d this [%p]\n", __LINE__, this); + + cleanupThread->addThread(this); + cleanupThread->start(); + } + } else { + if (Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d this [%p]\n", __LINE__, this); + cleanupThread->addThread(this); + } + if (Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d this [%p]\n", __LINE__, this); + } + } + + void Thread::kill() { + MutexSafeWrapper safeMutex(mutexthreadAccessor); + //SDL_KillThread(thread); + thread = NULL; + } + + void Thread::suspend() { + NOIMPL; + } + + void Thread::resume() { + NOIMPL; + } + + // ===================================== + // Mutex + // ===================================== + + class SDLMutexSafeWrapper { + protected: + SDL_mutex **mutex; + bool destroyMutexInDestructor; + + public: + + SDLMutexSafeWrapper(SDL_mutex **mutex, bool destroyMutexInDestructor = false) { + this->mutex = mutex; + this->destroyMutexInDestructor = destroyMutexInDestructor; + Lock(); + } + ~SDLMutexSafeWrapper() { + bool keepMutex = (this->destroyMutexInDestructor == true && mutex != NULL && *mutex != NULL); + ReleaseLock(keepMutex); + + if (this->destroyMutexInDestructor == true && mutex != NULL && *mutex != NULL) { + SDL_DestroyMutex(*mutex); + *mutex = NULL; + mutex = NULL; + } + } + + void Lock() { + if (mutex != NULL && *mutex != NULL) { + SDL_LockMutex(*mutex); + } + } + void ReleaseLock(bool keepMutex = false) { + if (mutex != NULL && *mutex != NULL) { + SDL_UnlockMutex(*mutex); + + if (keepMutex == false) { + mutex = NULL; + } + } + } + }; + + const bool debugMutexLock = false; + //const int debugMutexLockMillisecondThreshold = 2000; + + Mutex::Mutex(string ownerId) { + this->isStaticMutexListMutex = false; + this->mutexAccessor = SDL_CreateMutex(); + + SDLMutexSafeWrapper safeMutex(&mutexAccessor); + + this->maxRefCount = 0; + this->refCount = 0; + this->ownerId = ownerId; + this->lastownerId = ""; + this->mutex = SDL_CreateMutex(); + if (this->mutex == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] mutex == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } + this->deleteownerId = ""; + + this->chronoPerf = NULL; + if (debugMutexLock == true) { + this->chronoPerf = new Chrono(); + } + + if (Mutex::mutexMutexList.get()) { + MutexSafeWrapper safeMutexX(Mutex::mutexMutexList.get()); + Mutex::mutexList.push_back(this); + safeMutexX.ReleaseLock(); + } else { + this->isStaticMutexListMutex = true; + } + } + + Mutex::~Mutex() { + if (Mutex::mutexMutexList.get() && isStaticMutexListMutex == false) { + MutexSafeWrapper safeMutexX(Mutex::mutexMutexList.get()); + std::vector::iterator iterFind = std::find(Mutex::mutexList.begin(), Mutex::mutexList.end(), this); + if (iterFind == Mutex::mutexList.end()) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] iterFind == Mutex::mutexList.end()", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); throw megaglest_runtime_error(szBuf); } + Mutex::mutexList.erase(iterFind); + safeMutexX.ReleaseLock(); } - if(Thread::getEnableVerboseMode()) printf("!!!! cleanupPendingThread Line: %d thread = %p [%s]\n",__LINE__,thread,(base_thread != NULL ? base_thread->getUniqueID().c_str() : "n/a")); + SDLMutexSafeWrapper safeMutex(&mutexAccessor, true); + if (mutex == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] mutex == NULL refCount = %d owner [%s] deleteownerId [%s]", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, refCount, ownerId.c_str(), deleteownerId.c_str()); + throw megaglest_runtime_error(szBuf); + //printf("%s\n",szBuf); + } else if (refCount >= 1) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] about to destroy mutex refCount = %d owner [%s] deleteownerId [%s]", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, refCount, ownerId.c_str(), deleteownerId.c_str()); + throw megaglest_runtime_error(szBuf); + } - delete thread; + if (debugMutexLock == true) { + delete chronoPerf; + chronoPerf = NULL; + } - if(Thread::getEnableVerboseMode()) printf("!!!! cleanupPendingThread Line: %d thread = NULL [%s]\n",__LINE__,(base_thread != NULL ? base_thread->getUniqueID().c_str() : "n/a")); + if (mutex != NULL) { + deleteownerId = ownerId; + SDL_DestroyMutex(mutex); + mutex = NULL; + } + + // if(maxRefCount <= 1) { + // printf("***> MUTEX candidate for removal ownerId [%s] deleteownerId [%s] lastownerId [%s]\n",ownerId.c_str(),deleteownerId.c_str(),lastownerId.c_str()); + // } } - } -}; + /* + inline void Mutex::p() { + // if(mutex == NULL) { + // string stack = PlatformExceptionHandler::getStackTrace(); + // char szBuf[8096]=""; + // snprintf(szBuf,8095,"In [%s::%s Line: %d] mutex == NULL refCount = %d owner [%s] deleteownerId [%s] stack: %s",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,refCount,ownerId.c_str(),deleteownerId.c_str(),stack.c_str()); + // throw megaglest_runtime_error(szBuf); + // } + // std::auto_ptr chronoLockPerf; + // if(debugMutexLock == true) { + // chronoLockPerf.reset(new Chrono()); + // chronoLockPerf->start(); + // } -// ===================================== -// Threads -// ===================================== -Thread::Thread() : thread(NULL), - mutexthreadAccessor(new Mutex(CODE_AT_LINE)), - deleteAfterExecute(false), currentState(thrsNew) { - addThreadToList(); -} + // maxRefCount = max(maxRefCount,refCount+1); + SDL_mutexP(mutex); + refCount++; -unsigned long Thread::getCurrentThreadId() { - return SDL_ThreadID(); -} -void Thread::setMainThreadId() { - mainThreadId = getCurrentThreadId(); -} -bool Thread::isCurrentThreadMainThread() { - return getCurrentThreadId() == mainThreadId; -} + // if(debugMutexLock == true) { + // if(chronoLockPerf->getMillis() >= debugMutexLockMillisecondThreshold) { + // printf("\n**WARNING possible mutex lock detected ms [%lld] Last ownerid: [%s]\n",(long long int)chronoLockPerf->getMillis(),lastownerId.c_str()); + // } + // chronoPerf->start(); + // } + } -void Thread::addThreadToList() { - MutexSafeWrapper safeMutex(&Thread::mutexthreadList); - Thread::threadList.push_back(this); - safeMutex.ReleaseLock(); -} -void Thread::removeThreadFromList() { - MutexSafeWrapper safeMutex(&Thread::mutexthreadList); - if(Thread::threadList.empty() == false) { - std::vector::iterator iterFind = std::find(Thread::threadList.begin(),Thread::threadList.end(),this); - if(iterFind == Thread::threadList.end()) { - if(this != cleanupThread.get()) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] iterFind == Thread::threadList.end() Thread::threadList.size() = %ld",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,Thread::threadList.size()); + inline void Mutex::v() { + // if(mutex == NULL) { + // char szBuf[8096]=""; + // snprintf(szBuf,8095,"In [%s::%s Line: %d] mutex == NULL refCount = %d owner [%s] deleteownerId [%s]",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,refCount,ownerId.c_str(),deleteownerId.c_str()); + // throw megaglest_runtime_error(szBuf); + // } + refCount--; + + // if(debugMutexLock == true) { + // lastownerId = ownerId; + // if(chronoPerf->getMillis() >= debugMutexLockMillisecondThreshold) { + // printf("About to get stacktrace for stuck mutex ...\n"); + // string oldLastownerId = lastownerId; + // lastownerId = PlatformExceptionHandler::getStackTrace(); + // + // printf("\n**WARNING possible mutex lock (on unlock) detected ms [%lld] Last ownerid: [%s]\noldLastownerId: [%s]\n",(long long int)chronoPerf->getMillis(),lastownerId.c_str(),oldLastownerId.c_str()); + // } + // } + SDL_mutexV(mutex); + } + */ + + // ===================================================== + // class Semaphore + // ===================================================== + + Semaphore::Semaphore(Uint32 initialValue) { + semaphore = SDL_CreateSemaphore(initialValue); + if (semaphore == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] semaphore == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); throw megaglest_runtime_error(szBuf); } } - else { - Thread::threadList.erase(iterFind); + + Semaphore::~Semaphore() { + if (semaphore == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] semaphore == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } + SDL_DestroySemaphore(semaphore); + semaphore = NULL; } - } - safeMutex.ReleaseLock(); -} -void Thread::shutdownThreads() { - MutexSafeWrapper safeMutex(&Thread::mutexthreadList); - for(unsigned int index = 0; index < Thread::threadList.size(); ++index) { - BaseThread *thread = dynamic_cast(Thread::threadList[index]); - if(thread && thread->getRunningStatus() == true) { - thread->signalQuit(); + void Semaphore::signal() { + if (semaphore == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] semaphore == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } + SDL_SemPost(semaphore); } - } - safeMutex.ReleaseLock(); - if(Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d\n",__LINE__); - if(cleanupThread.get() != 0) { - //printf("In Thread::shutdownThreads Line: %d\n",__LINE__); - sleep(0); - cleanupThread->signalQuit(); - - //printf("In Thread::shutdownThreads Line: %d\n",__LINE__); - time_t elapsed = time(NULL); - for(;cleanupThread->getRunningStatus() == true && - difftime((long int)time(NULL),elapsed) <= 5;) { - sleep(100); + int Semaphore::waitTillSignalled(int waitMilliseconds) { + if (semaphore == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] semaphore == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } + int semValue = 0; + if (waitMilliseconds >= 0) { + semValue = SDL_SemWaitTimeout(semaphore, waitMilliseconds); + } else { + semValue = SDL_SemWait(semaphore); + } + return semValue; } - //printf("In Thread::shutdownThreads Line: %d\n",__LINE__); - //sleep(100); - MutexSafeWrapper safeMutex(cleanupThreadMutex.get()); - cleanupThread.reset(0); - //printf("In Thread::shutdownThreads Line: %d\n",__LINE__); - } -} + bool Semaphore::tryDecrement() { + if (semaphore == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] semaphore == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } + int semValue = SDL_SemTryWait(semaphore); + return (semValue == 0); + } -bool Thread::isThreadExecuteCompleteStatus() { - MutexSafeWrapper safeMutex(mutexthreadAccessor); - return (currentState == thrsExecuteComplete); -} -Thread::~Thread() { - BaseThread *base_thread = dynamic_cast(this); - string uniqueId = (base_thread ? base_thread->getUniqueID() : "new_base_thread_prev_null"); - if(Thread::getEnableVerboseMode()) printf("In ~Thread Line: %d [%p] thread = %p uniqueId [%s]\n",__LINE__,this,thread,uniqueId.c_str()); + uint32 Semaphore::getSemValue() { + if (semaphore == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] semaphore == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } - MutexSafeWrapper safeMutex(mutexthreadAccessor); - if(thread != NULL) { + return SDL_SemValue(semaphore); + } - safeMutex.ReleaseLock(); + void Semaphore::resetSemValue(Uint32 initialValue) { + if (semaphore == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] semaphore == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } - if(isThreadExecuteCompleteStatus() == false) { - printf("**WARNING** thread destructor delayed, trying to exit...\n"); + uint32 currentValue = SDL_SemValue(semaphore); + for (unsigned int i = currentValue; i < initialValue; ++i) { + SDL_SemPost(semaphore); + } + } - time_t elapsed = time(NULL); - for(;difftime((long int)time(NULL),elapsed) <= 5;) { - sleep(0); + // ===================================================== + // class ReadWriteMutex + // ===================================================== - if(isThreadExecuteCompleteStatus() == true) { - break; + ReadWriteMutex::ReadWriteMutex(int maxReaders) : semaphore(maxReaders) { + this->maxReadersCount = maxReaders; + } + + void ReadWriteMutex::LockRead() { + semaphore.waitTillSignalled(); + } + void ReadWriteMutex::UnLockRead() { + semaphore.signal(); + } + void ReadWriteMutex::LockWrite() { + MutexSafeWrapper safeMutex(&mutex); + uint32 totalLocks = maxReaders(); + for (unsigned int i = 0; i < totalLocks; ++i) { + semaphore.waitTillSignalled(); + } + } + void ReadWriteMutex::UnLockWrite() { + uint32 totalLocks = maxReaders(); + for (unsigned int i = 0; i < totalLocks; ++i) { + semaphore.signal(); + } + } + int ReadWriteMutex::maxReaders() { + //return semaphore.getSemValue(); + return this->maxReadersCount; + } + + // ===================================================== + // class Trigger + // ===================================================== + + Trigger::Trigger(Mutex *mutex) { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + this->mutex = mutex; + this->trigger = SDL_CreateCond(); + if (this->trigger == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] trigger == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } + + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + Trigger::~Trigger() { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (trigger == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] trigger == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + SDL_DestroyCond(trigger); + trigger = NULL; + + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + this->mutex = NULL; + + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void Trigger::signal(bool allThreads) { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (trigger == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] trigger == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } + + //MutexSafeWrapper safeMutex(mutex); + + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (allThreads == false) { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + int result = SDL_CondSignal(trigger); + + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] result = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, result); + } else { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + int result = SDL_CondBroadcast(trigger); + + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] result = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, result); + } + + //safeMutex.ReleaseLock(); + + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + int Trigger::waitTillSignalled(Mutex *mutex, int waitMilliseconds) { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (trigger == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] trigger == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } + if (mutex == NULL) { + char szBuf[8096] = ""; + snprintf(szBuf, 8095, "In [%s::%s Line: %d] mutex == NULL", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + throw megaglest_runtime_error(szBuf); + } + + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + int result = 0; + if (waitMilliseconds >= 0) { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + result = SDL_CondWaitTimeout(trigger, mutex->getMutex(), waitMilliseconds); + } else { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + result = SDL_CondWait(trigger, mutex->getMutex()); + } + + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + return result; + } + + MasterSlaveThreadController::MasterSlaveThreadController() { + std::vector empty; + init(empty); + } + + MasterSlaveThreadController::MasterSlaveThreadController(std::vector &slaveThreadList) { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] ==========================================================\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + init(slaveThreadList); + } + + void MasterSlaveThreadController::init(std::vector &newSlaveThreadList) { + this->mutex = new Mutex(CODE_AT_LINE); + this->slaveTriggerSem = new Semaphore(0); + this->slaveTriggerCounter = (int) newSlaveThreadList.size() + triggerBaseCount; + setSlaves(newSlaveThreadList); + } + + void MasterSlaveThreadController::clearSlaves(bool clearListOnly) { + if (this->slaveThreadList.empty() == false) { + if (clearListOnly == false) { + for (unsigned int i = 0; i < this->slaveThreadList.size(); ++i) { + SlaveThreadControllerInterface *slave = this->slaveThreadList[i]; + if (slave != NULL) { + slave->setMasterController(NULL); + } + } } + this->slaveThreadList.clear(); } } - if(isThreadExecuteCompleteStatus() == false) { - printf("**WARNING** thread destructor will KILL thread [%p]...\n",thread); - //SDL_KillThread(thread); - } - else { - if(Thread::getEnableVerboseMode()) printf("In ~Thread Line: %d [%p] thread = %p uniqueId [%s]\n",__LINE__,this,thread,uniqueId.c_str()); - SDL_WaitThread(thread, NULL); - } - thread = NULL; - } - else { - safeMutex.ReleaseLock(); - } + MasterSlaveThreadController::~MasterSlaveThreadController() { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - if(Thread::getEnableVerboseMode()) printf("In ~Thread Line: %d [%p] thread = %p\n",__LINE__,this,thread); + clearSlaves(); - removeThreadFromList(); + delete slaveTriggerSem; + slaveTriggerSem = NULL; - delete mutexthreadAccessor; - mutexthreadAccessor = NULL; - if(Thread::getEnableVerboseMode()) printf("In ~Thread Line: %d [%p] thread = %p\n",__LINE__,this,thread); -} + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] mutex->getRefCount() = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, mutex->getRefCount()); -std::vector Thread::getThreadList() { - std::vector result; - MutexSafeWrapper safeMutex(&Thread::mutexthreadList); - result = threadList; - safeMutex.ReleaseLock(); - return result; -} - -void Thread::start() { - if(Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n",__LINE__); - - MutexSafeWrapper safeMutex(mutexthreadAccessor); - currentState = thrsStarting; - - BaseThread *base_thread = dynamic_cast(this); - if(base_thread) base_thread->setStarted(true); - string uniqueId = (base_thread ? base_thread->getUniqueID() : "new_base_thread_prev_null"); - - if(Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n",__LINE__); - - thread = SDL_CreateThread(beginExecution, uniqueId.c_str(), this); - - if(Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d thread = %p uniqueId [%s]\n",__LINE__,thread,uniqueId.c_str()); - - if(thread == NULL) { - if(Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n",__LINE__); - - if(base_thread) base_thread->setStarted(false); - - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] thread == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - - if(Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n",__LINE__); - //printf("In Thread::start Line: %d [%p] thread = %p\n",__LINE__,this,thread); -} - -bool Thread::threadObjectValid() { - MutexSafeWrapper safeMutex(mutexthreadAccessor); - return (thread != NULL); -} - -void Thread::setPriority(Thread::Priority threadPriority) { - NOIMPL; -} - -int Thread::beginExecution(void* data) { - Thread* thread = static_cast (data); - if(thread == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] thread == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - printf("%s",szBuf); - - throw megaglest_runtime_error(szBuf); - } - - MutexSafeWrapper safeMutex(thread->mutexthreadAccessor); - thread->currentState = thrsExecuteStart; - safeMutex.ReleaseLock(true); - - BaseThread *base_thread = dynamic_cast(thread); - //ThreadGarbageCollector *garbage_collector = dynamic_cast(thread); - if(Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d thread = %p base_thread = %p [%s]\n",__LINE__,thread,base_thread,(base_thread != NULL ? base_thread->getUniqueID().c_str() : "n/a")); - - if(thread->threadObjectValid() == true) { - safeMutex.Lock(); - thread->currentState = thrsExecuting; - safeMutex.ReleaseLock(true); - - thread->execute(); - - safeMutex.Lock(); - thread->currentState = thrsExecuted; - safeMutex.ReleaseLock(true); - } - - if(Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d thread = %p base_thread = %p [%s]\n",__LINE__,thread,base_thread,(base_thread != NULL ? base_thread->getUniqueID().c_str() : "n/a")); - - if(thread->threadObjectValid() == true) { - safeMutex.Lock(); - thread->currentState = thrsExecuteAutoClean; - safeMutex.ReleaseLock(); - thread->queueAutoCleanThread(); - } - - if(Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n",__LINE__); - MutexSafeWrapper safeMutex2(thread->mutexthreadAccessor); - - if(Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n",__LINE__); - if(thread->threadObjectValid() == true) { - if(Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n",__LINE__); - thread->currentState = thrsExecuteComplete; - } - if(Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n",__LINE__); - safeMutex2.ReleaseLock(); - if(Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n",__LINE__); - - return 0; -} - -void Thread::queueAutoCleanThread() { - if(this->deleteAfterExecute == true) { - if(Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d\n",__LINE__); - - BaseThread *base_thread = dynamic_cast(this); - //ThreadGarbageCollector *garbage_collector = dynamic_cast(this); - if(Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d thread = %p base_thread = %p [%s]\n",__LINE__,this,base_thread,(base_thread != NULL ? base_thread->getUniqueID().c_str() : "n/a")); - - MutexSafeWrapper safeMutex(cleanupThreadMutex.get()); - if(cleanupThread.get() == NULL) { - if(Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d\n",__LINE__); - cleanupThread.reset(new ThreadGarbageCollector()); - - safeMutex.ReleaseLock(); - cleanupThread->start(); - } - else { - safeMutex.ReleaseLock(); - } - for(time_t elapsed = time(NULL); - cleanupThread->getRunningStatus() == false && - cleanupThread->getQuitStatus() == false && - difftime(time(NULL),elapsed) < 3;) { - sleep(0); - } - - if(cleanupThread->getQuitStatus() == true) { - //ThreadGarbageCollector::cleanupPendingThread(this); - if(cleanupThread->getRunningStatus() == false) { - if(Thread::getEnableVerboseMode()) printf("MANUAL DELETE In Thread::shutdownThreads Line: %d this [%p]\n",__LINE__,this); - - cleanupThread->addThread(this); - cleanupThread->start(); - - if(Thread::getEnableVerboseMode()) printf("MANUAL DELETE In Thread::shutdownThreads Line: %d\n",__LINE__); - return; - } - else { - if(Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d this [%p]\n",__LINE__,this); - - for(time_t elapsed = time(NULL); - cleanupThread->getRunningStatus() == true && - cleanupThread->getQuitStatus() == true && - difftime(time(NULL),elapsed) < 3;) { - sleep(0); - } - sleep(0); - - if(Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d this [%p]\n",__LINE__,this); - - cleanupThread->addThread(this); - cleanupThread->start(); - } - } - else { - if(Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d this [%p]\n",__LINE__,this); - cleanupThread->addThread(this); - } - if(Thread::getEnableVerboseMode()) printf("In Thread::shutdownThreads Line: %d this [%p]\n",__LINE__,this); - } -} - -void Thread::kill() { - MutexSafeWrapper safeMutex(mutexthreadAccessor); - //SDL_KillThread(thread); - thread = NULL; -} - -void Thread::suspend() { - NOIMPL; -} - -void Thread::resume() { - NOIMPL; -} - -// ===================================== -// Mutex -// ===================================== - -class SDLMutexSafeWrapper { -protected: - SDL_mutex **mutex; - bool destroyMutexInDestructor; - -public: - - SDLMutexSafeWrapper(SDL_mutex **mutex, bool destroyMutexInDestructor=false) { - this->mutex = mutex; - this->destroyMutexInDestructor = destroyMutexInDestructor; - Lock(); - } - ~SDLMutexSafeWrapper() { - bool keepMutex = (this->destroyMutexInDestructor == true && mutex != NULL && *mutex != NULL); - ReleaseLock(keepMutex); - - if(this->destroyMutexInDestructor == true && mutex != NULL && *mutex != NULL) { - SDL_DestroyMutex(*mutex); - *mutex = NULL; + delete mutex; mutex = NULL; + + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); } - } - void Lock() { - if(mutex != NULL && *mutex != NULL) { - SDL_LockMutex(*mutex); - } - } - void ReleaseLock(bool keepMutex=false) { - if(mutex != NULL && *mutex != NULL) { - SDL_UnlockMutex(*mutex); + void MasterSlaveThreadController::setSlaves(std::vector &slaveThreadList) { + this->slaveThreadList = slaveThreadList; - if(keepMutex == false) { - mutex = NULL; - } - } - } -}; - -const bool debugMutexLock = false; -//const int debugMutexLockMillisecondThreshold = 2000; - -Mutex::Mutex(string ownerId) { - this->isStaticMutexListMutex = false; - this->mutexAccessor = SDL_CreateMutex(); - - SDLMutexSafeWrapper safeMutex(&mutexAccessor); - - this->maxRefCount = 0; - this->refCount = 0; - this->ownerId = ownerId; - this->lastownerId = ""; - this->mutex = SDL_CreateMutex(); - if(this->mutex == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] mutex == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - this->deleteownerId = ""; - - this->chronoPerf = NULL; - if(debugMutexLock == true) { - this->chronoPerf = new Chrono(); - } - - if(Mutex::mutexMutexList.get()) { - MutexSafeWrapper safeMutexX(Mutex::mutexMutexList.get()); - Mutex::mutexList.push_back(this); - safeMutexX.ReleaseLock(); - } - else { - this->isStaticMutexListMutex = true; - } -} - -Mutex::~Mutex() { - if(Mutex::mutexMutexList.get() && isStaticMutexListMutex == false) { - MutexSafeWrapper safeMutexX(Mutex::mutexMutexList.get()); - std::vector::iterator iterFind = std::find(Mutex::mutexList.begin(),Mutex::mutexList.end(),this); - if(iterFind == Mutex::mutexList.end()) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] iterFind == Mutex::mutexList.end()",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - Mutex::mutexList.erase(iterFind); - safeMutexX.ReleaseLock(); - } - - SDLMutexSafeWrapper safeMutex(&mutexAccessor,true); - if(mutex == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] mutex == NULL refCount = %d owner [%s] deleteownerId [%s]",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,refCount,ownerId.c_str(),deleteownerId.c_str()); - throw megaglest_runtime_error(szBuf); - //printf("%s\n",szBuf); - } - else if(refCount >= 1) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] about to destroy mutex refCount = %d owner [%s] deleteownerId [%s]",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,refCount,ownerId.c_str(),deleteownerId.c_str()); - throw megaglest_runtime_error(szBuf); - } - - if(debugMutexLock == true) { - delete chronoPerf; - chronoPerf = NULL; - } - - if(mutex != NULL) { - deleteownerId = ownerId; - SDL_DestroyMutex(mutex); - mutex=NULL; - } - -// if(maxRefCount <= 1) { -// printf("***> MUTEX candidate for removal ownerId [%s] deleteownerId [%s] lastownerId [%s]\n",ownerId.c_str(),deleteownerId.c_str(),lastownerId.c_str()); -// } -} - -/* -inline void Mutex::p() { -// if(mutex == NULL) { -// string stack = PlatformExceptionHandler::getStackTrace(); -// char szBuf[8096]=""; -// snprintf(szBuf,8095,"In [%s::%s Line: %d] mutex == NULL refCount = %d owner [%s] deleteownerId [%s] stack: %s",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,refCount,ownerId.c_str(),deleteownerId.c_str(),stack.c_str()); -// throw megaglest_runtime_error(szBuf); -// } -// std::auto_ptr chronoLockPerf; -// if(debugMutexLock == true) { -// chronoLockPerf.reset(new Chrono()); -// chronoLockPerf->start(); -// } - -// maxRefCount = max(maxRefCount,refCount+1); - SDL_mutexP(mutex); - refCount++; - -// if(debugMutexLock == true) { -// if(chronoLockPerf->getMillis() >= debugMutexLockMillisecondThreshold) { -// printf("\n**WARNING possible mutex lock detected ms [%lld] Last ownerid: [%s]\n",(long long int)chronoLockPerf->getMillis(),lastownerId.c_str()); -// } -// chronoPerf->start(); -// } -} - -inline void Mutex::v() { -// if(mutex == NULL) { -// char szBuf[8096]=""; -// snprintf(szBuf,8095,"In [%s::%s Line: %d] mutex == NULL refCount = %d owner [%s] deleteownerId [%s]",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,refCount,ownerId.c_str(),deleteownerId.c_str()); -// throw megaglest_runtime_error(szBuf); -// } - refCount--; - -// if(debugMutexLock == true) { -// lastownerId = ownerId; -// if(chronoPerf->getMillis() >= debugMutexLockMillisecondThreshold) { -// printf("About to get stacktrace for stuck mutex ...\n"); -// string oldLastownerId = lastownerId; -// lastownerId = PlatformExceptionHandler::getStackTrace(); -// -// printf("\n**WARNING possible mutex lock (on unlock) detected ms [%lld] Last ownerid: [%s]\noldLastownerId: [%s]\n",(long long int)chronoPerf->getMillis(),lastownerId.c_str(),oldLastownerId.c_str()); -// } -// } - SDL_mutexV(mutex); -} -*/ - -// ===================================================== -// class Semaphore -// ===================================================== - -Semaphore::Semaphore(Uint32 initialValue) { - semaphore = SDL_CreateSemaphore(initialValue); - if(semaphore == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] semaphore == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } -} - -Semaphore::~Semaphore() { - if(semaphore == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] semaphore == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - SDL_DestroySemaphore(semaphore); - semaphore = NULL; -} - -void Semaphore::signal() { - if(semaphore == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] semaphore == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - SDL_SemPost(semaphore); -} - -int Semaphore::waitTillSignalled(int waitMilliseconds) { - if(semaphore == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] semaphore == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - int semValue = 0; - if(waitMilliseconds >= 0) { - semValue = SDL_SemWaitTimeout(semaphore,waitMilliseconds); - } - else { - semValue = SDL_SemWait(semaphore); - } - return semValue; -} - -bool Semaphore::tryDecrement() { - if(semaphore == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] semaphore == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - int semValue = SDL_SemTryWait(semaphore); - return (semValue == 0); -} - -uint32 Semaphore::getSemValue() { - if(semaphore == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] semaphore == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - - return SDL_SemValue(semaphore); -} - -void Semaphore::resetSemValue(Uint32 initialValue) { - if(semaphore == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] semaphore == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - - uint32 currentValue = SDL_SemValue(semaphore); - for(unsigned int i = currentValue; i < initialValue; ++i) { - SDL_SemPost(semaphore); - } -} - -// ===================================================== -// class ReadWriteMutex -// ===================================================== - -ReadWriteMutex::ReadWriteMutex(int maxReaders) : semaphore(maxReaders) { - this->maxReadersCount = maxReaders; -} - -void ReadWriteMutex::LockRead() { - semaphore.waitTillSignalled(); -} -void ReadWriteMutex::UnLockRead() { - semaphore.signal(); -} -void ReadWriteMutex::LockWrite() { - MutexSafeWrapper safeMutex(&mutex); - uint32 totalLocks = maxReaders(); - for(unsigned int i = 0; i < totalLocks; ++i) { - semaphore.waitTillSignalled(); - } -} -void ReadWriteMutex::UnLockWrite() { - uint32 totalLocks = maxReaders(); - for(unsigned int i = 0; i < totalLocks; ++i) { - semaphore.signal(); - } -} -int ReadWriteMutex::maxReaders() { - //return semaphore.getSemValue(); - return this->maxReadersCount; -} - -// ===================================================== -// class Trigger -// ===================================================== - -Trigger::Trigger(Mutex *mutex) { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - this->mutex = mutex; - this->trigger = SDL_CreateCond(); - if(this->trigger == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] trigger == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -Trigger::~Trigger() { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(trigger == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] trigger == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - SDL_DestroyCond(trigger); - trigger = NULL; - - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - this->mutex = NULL; - - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void Trigger::signal(bool allThreads) { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(trigger == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] trigger == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - - //MutexSafeWrapper safeMutex(mutex); - - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(allThreads == false) { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - int result = SDL_CondSignal(trigger); - - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] result = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result); - } - else { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - int result = SDL_CondBroadcast(trigger); - - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] result = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result); - } - - //safeMutex.ReleaseLock(); - - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -int Trigger::waitTillSignalled(Mutex *mutex, int waitMilliseconds) { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(trigger == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] trigger == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - if(mutex == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] mutex == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - throw megaglest_runtime_error(szBuf); - } - - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - int result = 0; - if(waitMilliseconds >= 0) { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - result = SDL_CondWaitTimeout(trigger,mutex->getMutex(),waitMilliseconds); - } - else { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - result = SDL_CondWait(trigger, mutex->getMutex()); - } - - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - return result; -} - -MasterSlaveThreadController::MasterSlaveThreadController() { - std::vector empty; - init(empty); -} - -MasterSlaveThreadController::MasterSlaveThreadController(std::vector &slaveThreadList) { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] ==========================================================\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - init(slaveThreadList); -} - -void MasterSlaveThreadController::init(std::vector &newSlaveThreadList) { - this->mutex = new Mutex(CODE_AT_LINE); - this->slaveTriggerSem = new Semaphore(0); - this->slaveTriggerCounter = (int)newSlaveThreadList.size() + triggerBaseCount; - setSlaves(newSlaveThreadList); -} - -void MasterSlaveThreadController::clearSlaves(bool clearListOnly) { - if(this->slaveThreadList.empty() == false) { - if(clearListOnly == false) { - for(unsigned int i = 0; i < this->slaveThreadList.size(); ++i) { - SlaveThreadControllerInterface *slave = this->slaveThreadList[i]; - if(slave != NULL) { - slave->setMasterController(NULL); + if (this->slaveThreadList.empty() == false) { + for (unsigned int i = 0; i < this->slaveThreadList.size(); ++i) { + SlaveThreadControllerInterface *slave = this->slaveThreadList[i]; + if (slave != NULL) { + slave->setMasterController(this); + } } } } - this->slaveThreadList.clear(); - } -} -MasterSlaveThreadController::~MasterSlaveThreadController() { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + void MasterSlaveThreadController::signalSlaves(void *userdata) { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - clearSlaves(); + slaveTriggerCounter = (int)this->slaveThreadList.size() + triggerBaseCount; - delete slaveTriggerSem; - slaveTriggerSem = NULL; + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] mutex->getRefCount() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,mutex->getRefCount()); - - delete mutex; - mutex = NULL; - - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void MasterSlaveThreadController::setSlaves(std::vector &slaveThreadList) { - this->slaveThreadList = slaveThreadList; - - if(this->slaveThreadList.empty() == false) { - for(unsigned int i = 0; i < this->slaveThreadList.size(); ++i) { - SlaveThreadControllerInterface *slave = this->slaveThreadList[i]; - if(slave != NULL) { - slave->setMasterController(this); + if (this->slaveThreadList.empty() == false) { + for (unsigned int i = 0; i < this->slaveThreadList.size(); ++i) { + SlaveThreadControllerInterface *slave = this->slaveThreadList[i]; + if (slave != NULL) { + slave->signalSlave(userdata); + } + } } + + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); } - } -} -void MasterSlaveThreadController::signalSlaves(void *userdata) { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + void MasterSlaveThreadController::triggerMaster(int waitMilliseconds) { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - slaveTriggerCounter = (int)this->slaveThreadList.size() + triggerBaseCount; + MutexSafeWrapper safeMutex(mutex); + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] semVal = %u\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, slaveTriggerCounter); + //printf("In [%s::%s Line: %d] semVal = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,slaveTriggerCounter); - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + slaveTriggerCounter--; + int newCount = slaveTriggerCounter; - if(this->slaveThreadList.empty() == false) { - for(unsigned int i = 0; i < this->slaveThreadList.size(); ++i) { - SlaveThreadControllerInterface *slave = this->slaveThreadList[i]; - if(slave != NULL) { - slave->signalSlave(userdata); + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] slaveTriggerCounter = %u\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, slaveTriggerCounter); + + safeMutex.ReleaseLock(); + + //printf("In [%s::%s Line: %d] semVal = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,slaveTriggerCounter); + + if (newCount <= triggerBaseCount) { + slaveTriggerSem->signal(); } + + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); } - } - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} + bool MasterSlaveThreadController::waitTillSlavesTrigger(int waitMilliseconds) { + bool result = true; -void MasterSlaveThreadController::triggerMaster(int waitMilliseconds) { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] slaveTriggerCounter = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, slaveTriggerCounter); - MutexSafeWrapper safeMutex(mutex); - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] semVal = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,slaveTriggerCounter); - //printf("In [%s::%s Line: %d] semVal = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,slaveTriggerCounter); + if (this->slaveThreadList.empty() == false) { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] slaveTriggerCounter = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, slaveTriggerCounter); - slaveTriggerCounter--; - int newCount = slaveTriggerCounter; + int slaveResult = slaveTriggerSem->waitTillSignalled(waitMilliseconds); - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] slaveTriggerCounter = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,slaveTriggerCounter); + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] slaveTriggerCounter = %d slaveResult = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, slaveTriggerCounter, slaveResult); - safeMutex.ReleaseLock(); + if (slaveResult != 0) { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - //printf("In [%s::%s Line: %d] semVal = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,slaveTriggerCounter); + result = false; + } else { + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] slaveTriggerCounter = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, slaveTriggerCounter); - if(newCount <= triggerBaseCount) { - slaveTriggerSem->signal(); - } + result = true; + } + } - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} + if (debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); -bool MasterSlaveThreadController::waitTillSlavesTrigger(int waitMilliseconds) { - bool result = true; - - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] slaveTriggerCounter = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,slaveTriggerCounter); - - if(this->slaveThreadList.empty() == false) { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] slaveTriggerCounter = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,slaveTriggerCounter); - - int slaveResult = slaveTriggerSem->waitTillSignalled(waitMilliseconds); - - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] slaveTriggerCounter = %d slaveResult = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,slaveTriggerCounter,slaveResult); - - if(slaveResult != 0) { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - result = false; + return result; } - else { - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d] slaveTriggerCounter = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,slaveTriggerCounter); - result = true; - } } - - if(debugMasterSlaveThreadController) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - return result; -} - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/platform/sdl/window.cpp b/source/shared_lib/sources/platform/sdl/window.cpp index a1061d354..4510d2fae 100644 --- a/source/shared_lib/sources/platform/sdl/window.cpp +++ b/source/shared_lib/sources/platform/sdl/window.cpp @@ -31,1219 +31,1209 @@ using namespace Shared::Util; using namespace std; -namespace Shared{ namespace Platform{ +namespace Shared { + namespace Platform { -// ======================================= -// WINDOW -// ======================================= + // ======================================= + // WINDOW + // ======================================= -// ========== STATIC INITIALIZATIONS ========== + // ========== STATIC INITIALIZATIONS ========== -static Window* global_window = 0; -static int oldX=0,oldY=0; -SDL_Window *Window::sdlWindow = 0; -int64 Window::lastMouseEvent = 0; /** for use in mouse hover calculations */ -Vec2i Window::mousePos; -MouseState Window::mouseState; -bool Window::isKeyPressedDown = false; -bool Window::isFullScreen = false; -SDL_keysym Window::keystate; -int64 Window::lastToggle = -1000; + static Window* global_window = 0; + static int oldX = 0, oldY = 0; + SDL_Window *Window::sdlWindow = 0; + int64 Window::lastMouseEvent = 0; /** for use in mouse hover calculations */ + Vec2i Window::mousePos; + MouseState Window::mouseState; + bool Window::isKeyPressedDown = false; + bool Window::isFullScreen = false; + SDL_keysym Window::keystate; + int64 Window::lastToggle = -1000; -bool Window::isActive = false; + bool Window::isActive = false; #ifdef WIN32 -bool Window::allowAltEnterFullscreenToggle = false; + bool Window::allowAltEnterFullscreenToggle = false; #else -bool Window::allowAltEnterFullscreenToggle = true; + bool Window::allowAltEnterFullscreenToggle = true; #endif -int Window::lastShowMouseState = 0; + int Window::lastShowMouseState = 0; -bool Window::tryVSynch = false; + bool Window::tryVSynch = false; -map Window::mapAllowedKeys; + map Window::mapAllowedKeys; -//bool Window::masterserverMode = false; + //bool Window::masterserverMode = false; -// ========== PUBLIC ========== + // ========== PUBLIC ========== #ifdef WIN32 -static HWND GetSDLWindow() -{ - SDL_SysWMinfo info; - SDL_VERSION(&info.version); - if (SDL_GetWindowWMInfo(Window::getSDLWindow(),&info) == -1) - return NULL; - return info.info.win.window; -} + static HWND GetSDLWindow() { + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + if (SDL_GetWindowWMInfo(Window::getSDLWindow(), &info) == -1) + return NULL; + return info.info.win.window; + } #endif -static bool isUnprintableChar(SDL_keysym key, SDL_Keymod mod) { - switch (key.sym) { - // We want to allow some, which are handled specially - case SDLK_RETURN: - case SDLK_TAB: - case SDLK_BACKSPACE: - case SDLK_DELETE: - case SDLK_HOME: - case SDLK_END: - case SDLK_LEFT: - case SDLK_RIGHT: - case SDLK_UP: - case SDLK_DOWN: - case SDLK_PAGEUP: - case SDLK_PAGEDOWN: - return true; - default:// do nothing - break; - } - // U+0000 to U+001F are control characters - /* Don't post text events for unprintable characters */ + static bool isUnprintableChar(SDL_keysym key, SDL_Keymod mod) { + switch (key.sym) { + // We want to allow some, which are handled specially + case SDLK_RETURN: + case SDLK_TAB: + case SDLK_BACKSPACE: + case SDLK_DELETE: + case SDLK_HOME: + case SDLK_END: + case SDLK_LEFT: + case SDLK_RIGHT: + case SDLK_UP: + case SDLK_DOWN: + case SDLK_PAGEUP: + case SDLK_PAGEDOWN: + return true; + default:// do nothing + break; + } + // U+0000 to U+001F are control characters + /* Don't post text events for unprintable characters */ - if(StartsWith(SDL_GetKeyName(key.sym),"SDLK_KP")){ - return false; - } - if (key.sym > 127) { - return true; - } - if(key.sym < 0x20) { - return true; - } + if (StartsWith(SDL_GetKeyName(key.sym), "SDLK_KP")) { + return false; + } + if (key.sym > 127) { + return true; + } + if (key.sym < 0x20) { + return true; + } - //printf("isUnprintableChar returns false for [%d]\n",key.sym); - return false; + //printf("isUnprintableChar returns false for [%d]\n",key.sym); + return false; -} + } -Window::Window() { - this->sdlWindow=0; - // Default to 1x1 until set by caller to avoid divide by 0 - //this->w = 1; - //this->h = 1; + Window::Window() { + this->sdlWindow = 0; + // Default to 1x1 until set by caller to avoid divide by 0 + //this->w = 1; + //this->h = 1; - for(int idx = 0; idx < mbCount; idx++) { - lastMouseDown[idx] = 0; - lastMouseX[idx] = 0; - lastMouseY[idx] = 0; - } + for (int idx = 0; idx < mbCount; idx++) { + lastMouseDown[idx] = 0; + lastMouseX[idx] = 0; + lastMouseY[idx] = 0; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - assert(global_window == 0); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + assert(global_window == 0); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - global_window = this; - Window::isActive = true; + global_window = this; + Window::isActive = true; - lastMouseEvent = 0; - mousePos = Vec2i(0); - mouseState.clear(); + lastMouseEvent = 0; + mousePos = Vec2i(0); + mouseState.clear(); #ifdef WIN32 - init_win32(); + init_win32(); #endif -} + } -Window::Window(SDL_Window *sdlWindow) { - this->sdlWindow=sdlWindow; - // Default to 1x1 until set by caller to avoid divide by 0 - //this->w = 1; - //this->h = 1; + Window::Window(SDL_Window *sdlWindow) { + this->sdlWindow = sdlWindow; + // Default to 1x1 until set by caller to avoid divide by 0 + //this->w = 1; + //this->h = 1; - for(int idx = 0; idx < mbCount; idx++) { - lastMouseDown[idx] = 0; - lastMouseX[idx] = 0; - lastMouseY[idx] = 0; - } + for (int idx = 0; idx < mbCount; idx++) { + lastMouseDown[idx] = 0; + lastMouseX[idx] = 0; + lastMouseY[idx] = 0; + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - assert(global_window == 0); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + assert(global_window == 0); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - global_window = this; - Window::isActive = true; + global_window = this; + Window::isActive = true; - lastMouseEvent = 0; - mousePos = Vec2i(0); - mouseState.clear(); + lastMouseEvent = 0; + mousePos = Vec2i(0); + mouseState.clear(); #ifdef WIN32 - init_win32(); + init_win32(); #endif -} + } -Window::~Window() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + Window::~Window() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); #ifdef WIN32 - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - done_win32(); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + done_win32(); #endif - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - assert(global_window == this); - global_window = 0; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + assert(global_window == this); + global_window = 0; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } -void Window::setSDLWindow(SDL_Window *window) { - Window::sdlWindow = window; -} -SDL_Window *Window::getSDLWindow() { - return Window::sdlWindow; -} + void Window::setSDLWindow(SDL_Window *window) { + Window::sdlWindow = window; + } + SDL_Window *Window::getSDLWindow() { + return Window::sdlWindow; + } -bool Window::handleEvent() { - string codeLocation = "a"; + bool Window::handleEvent() { + string codeLocation = "a"; - SDL_Event event; - SDL_GetMouseState(&oldX,&oldY); + SDL_Event event; + SDL_GetMouseState(&oldX, &oldY); - //codeLocation = "b"; + //codeLocation = "b"; - SDL_StartTextInput(); - while(SDL_PollEvent(&event)) { - try { - codeLocation = "c"; + SDL_StartTextInput(); + while (SDL_PollEvent(&event)) { + try { + codeLocation = "c"; - switch(event.type) { - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - case SDL_MOUSEMOTION: + switch (event.type) { + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + case SDL_MOUSEMOTION: + + //printf("In [%s::%s] Line :%d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + codeLocation = "d"; + + setLastMouseEvent(Chrono::getCurMillis()); + setMousePos(Vec2i(event.button.x, event.button.y)); + break; + } - //printf("In [%s::%s] Line :%d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); codeLocation = "d"; - setLastMouseEvent(Chrono::getCurMillis()); - setMousePos(Vec2i(event.button.x, event.button.y)); - break; - } + switch (event.type) { + case SDL_QUIT: + //printf("In [%s::%s] Line :%d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + codeLocation = "e"; + return false; + case SDL_MOUSEBUTTONDOWN: + //printf("In [%s::%s] Line :%d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + codeLocation = "f"; - codeLocation = "d"; + if (global_window) { + global_window->handleMouseDown(event); + } + break; + case SDL_MOUSEBUTTONUP: { + //printf("In [%s::%s] Line :%d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + codeLocation = "g"; + if (global_window) { + MouseButton b = getMouseButton(event.button.button); + setMouseState(b, false); - switch(event.type) { - case SDL_QUIT: - //printf("In [%s::%s] Line :%d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - codeLocation = "e"; - return false; - case SDL_MOUSEBUTTONDOWN: - //printf("In [%s::%s] Line :%d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - codeLocation = "f"; + global_window->eventMouseUp(event.button.x, + event.button.y, getMouseButton(event.button.button)); + } + break; + } + case SDL_MOUSEWHEEL: { + //printf("In [%s::%s] Line :%d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + codeLocation = "g2"; + if (global_window) { + global_window->handleMouseWheel(event); + } + break; + } + case SDL_MOUSEMOTION: { + //printf("In [%s::%s] Line :%d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + //MouseState ms; + //ms.leftMouse = (event.motion.state & SDL_BUTTON_LMASK) != 0; + //ms.rightMouse = (event.motion.state & SDL_BUTTON_RMASK) != 0; + //ms.centerMouse = (event.motion.state & SDL_BUTTON_MMASK) != 0; + codeLocation = "h"; - if(global_window) { - global_window->handleMouseDown(event); - } - break; - case SDL_MOUSEBUTTONUP: { - //printf("In [%s::%s] Line :%d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - codeLocation = "g"; - if(global_window) { - MouseButton b = getMouseButton(event.button.button); - setMouseState(b, false); + setMouseState(mbLeft, (event.motion.state & SDL_BUTTON_LMASK) == SDL_BUTTON_LMASK); + setMouseState(mbRight, (event.motion.state & SDL_BUTTON_RMASK) == SDL_BUTTON_RMASK); + setMouseState(mbCenter, (event.motion.state & SDL_BUTTON_MMASK) == SDL_BUTTON_MMASK); - global_window->eventMouseUp(event.button.x, - event.button.y,getMouseButton(event.button.button)); - } - break; - } - case SDL_MOUSEWHEEL: { - //printf("In [%s::%s] Line :%d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - codeLocation = "g2"; - if(global_window) { - global_window->handleMouseWheel(event); - } - break; - } - case SDL_MOUSEMOTION: { - //printf("In [%s::%s] Line :%d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //MouseState ms; - //ms.leftMouse = (event.motion.state & SDL_BUTTON_LMASK) != 0; - //ms.rightMouse = (event.motion.state & SDL_BUTTON_RMASK) != 0; - //ms.centerMouse = (event.motion.state & SDL_BUTTON_MMASK) != 0; - codeLocation = "h"; + if (global_window) { + global_window->eventMouseMove(event.motion.x, event.motion.y, &getMouseState()); //&ms); + } + break; + } + case SDL_TEXTINPUT: { + //case SDL_TEXTEDITING: + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] =================================== START OF SDL SDL_TEXTINPUT ================================\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + codeLocation = "i"; + Window::isKeyPressedDown = true; + //#ifdef WIN32 + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("KD mod = %d : %d\n", event.key.keysym.mod, SDL_GetModState()); + event.key.keysym.mod = SDL_GetModState(); + //#endif - setMouseState(mbLeft, (event.motion.state & SDL_BUTTON_LMASK) == SDL_BUTTON_LMASK); - setMouseState(mbRight, (event.motion.state & SDL_BUTTON_RMASK) == SDL_BUTTON_RMASK); - setMouseState(mbCenter, (event.motion.state & SDL_BUTTON_MMASK) == SDL_BUTTON_MMASK); - - if(global_window) { - global_window->eventMouseMove(event.motion.x, event.motion.y, &getMouseState()); //&ms); - } - break; - } - case SDL_TEXTINPUT: { - //case SDL_TEXTEDITING: - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] =================================== START OF SDL SDL_TEXTINPUT ================================\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - codeLocation = "i"; - Window::isKeyPressedDown = true; -//#ifdef WIN32 - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("KD mod = %d : %d\n",event.key.keysym.mod,SDL_GetModState()); - event.key.keysym.mod = SDL_GetModState(); -//#endif - - string keyName = SDL_GetKeyName(event.text.text[0]); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] Raw SDL key [%d - %c] mod [%d] scancode [%d] keyName [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,event.key.keysym.sym,event.key.keysym.sym,event.key.keysym.mod,event.key.keysym.scancode,keyName.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Raw SDL key [%d] mod [%d] scancode [%d] keyName [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,event.key.keysym.sym,event.key.keysym.mod,event.key.keysym.scancode,keyName.c_str()); + string keyName = SDL_GetKeyName(event.text.text[0]); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Raw SDL key [%d - %c] mod [%d] scancode [%d] keyName [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, event.key.keysym.sym, event.key.keysym.sym, event.key.keysym.mod, event.key.keysym.scancode, keyName.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] Raw SDL key [%d] mod [%d] scancode [%d] keyName [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, event.key.keysym.sym, event.key.keysym.mod, event.key.keysym.scancode, keyName.c_str()); #ifdef WIN32 - /* handle ALT+f4 */ - if((keyName == "f4" || keyName == "F4") - && (event.key.keysym.mod & (KMOD_LALT | KMOD_RALT))) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d] ALT-F4 pressed.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return false; - } + /* handle ALT+f4 */ + if ((keyName == "f4" || keyName == "F4") + && (event.key.keysym.mod & (KMOD_LALT | KMOD_RALT))) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d] ALT-F4 pressed.\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + return false; + } #endif - if(global_window) { - if(global_window->eventTextInput(event.text.text) == false) { - event.key.keysym.sym = event.text.text[0]; - global_window->eventKeyDown(event.key); - global_window->eventKeyPress(event.key); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] =================================== END OF SDL SDL_TEXTINPUT ================================\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - break; - } - case SDL_KEYDOWN: { - //printf("In SDL_KEYDOWN\n"); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] =================================== START OF SDL SDL_KEYDOWN ================================\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - keystate = event.key.keysym; - bool keyDownConsumed=false; - if(global_window) { - keyDownConsumed=global_window->eventSdlKeyDown(event.key); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - switch (event.key.keysym.sym) { - case SDLK_v: { - if (event.key.keysym.mod & KMOD_CTRL) { - /* Ctrl-V, paste form clipbord */ - char *text = SDL_GetClipboardText(); - if (*text) { - printf("Clipboard text: %s\n", text); - if(global_window->eventTextInput(text) == true) { - keyDownConsumed=true; - } - } else { - printf("Clipboard text is empty\n"); - } - SDL_free(text); + if (global_window) { + if (global_window->eventTextInput(event.text.text) == false) { + event.key.keysym.sym = event.text.text[0]; + global_window->eventKeyDown(event.key); + global_window->eventKeyPress(event.key); } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] =================================== END OF SDL SDL_TEXTINPUT ================================\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + break; + } + case SDL_KEYDOWN: { + //printf("In SDL_KEYDOWN\n"); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] =================================== START OF SDL SDL_KEYDOWN ================================\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + keystate = event.key.keysym; + bool keyDownConsumed = false; + if (global_window) { + keyDownConsumed = global_window->eventSdlKeyDown(event.key); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + switch (event.key.keysym.sym) { + case SDLK_v: { + if (event.key.keysym.mod & KMOD_CTRL) { + /* Ctrl-V, paste form clipbord */ + char *text = SDL_GetClipboardText(); + if (*text) { + printf("Clipboard text: %s\n", text); + if (global_window->eventTextInput(text) == true) { + keyDownConsumed = true; + } + } else { + printf("Clipboard text is empty\n"); + } + SDL_free(text); + } + break; + } + default: + break; + } + } + + // // Stop keys which would be handled twice ( one time as text input, one time as key down ) + SDL_Keymod mod = SDL_GetModState(); + if (!isUnprintableChar(event.key.keysym, mod)) { + //printf("In SDL_KEYDOWN key SKIP [%d]\n",event.key.keysym.sym); break; } - default: + codeLocation = "i"; + Window::isKeyPressedDown = true; + //#ifdef WIN32 + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("KD mod = %d : %d\n", event.key.keysym.mod, SDL_GetModState()); + event.key.keysym.mod = SDL_GetModState(); + //#endif + string keyName = SDL_GetKeyName(event.key.keysym.sym); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Raw SDL key [%d - %c] mod [%d] scancode [%d] keyName [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, event.key.keysym.sym, event.key.keysym.sym, event.key.keysym.mod, event.key.keysym.scancode, keyName.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] Raw SDL key [%d] mod [%d] scancode [%d] keyName [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, event.key.keysym.sym, event.key.keysym.mod, event.key.keysym.scancode, keyName.c_str()); + + //printf("In SDL_KEYDOWN key [%d] keyName [%s] mod: %d\n",event.key.keysym.sym,keyName.c_str(),event.key.keysym.mod); + + // handle ALT+Return + if ((keyName == "Return" || keyName == "Enter") + && (event.key.keysym.mod & (KMOD_LALT | KMOD_RALT))) { + if (event.key.repeat != 0) break; + if (Chrono::getCurMillis() - getLastToggle() > 100) { + toggleFullscreen(); + setLastToggle(Chrono::getCurMillis()); + }; + keyDownConsumed = true; + } +#ifdef WIN32 + // handle ALT+f4 + if ((keyName == "f4" || keyName == "F4") + && (event.key.keysym.mod & (KMOD_LALT | KMOD_RALT))) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d] ALT-F4 pressed.\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + return false; + } +#endif + if (global_window) { + //char key = getKey(event.key.keysym,true); + //key = tolower(key); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("******************* key [%d]\n",key); + + //event.key.keysym.mod = SDL_GetModState(); + if (!keyDownConsumed) { + global_window->eventKeyDown(event.key); + global_window->eventKeyPress(event.key); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] =================================== END OF SDL SDL_KEYDOWN ================================\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); break; } - } + case SDL_KEYUP: { + //printf("In [%s::%s] Line :%d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// // Stop keys which would be handled twice ( one time as text input, one time as key down ) - SDL_Keymod mod = SDL_GetModState(); - if (!isUnprintableChar(event.key.keysym,mod)) { - //printf("In SDL_KEYDOWN key SKIP [%d]\n",event.key.keysym.sym); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] =================================== START OF SDL SDL_KEYUP ================================\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + codeLocation = "j"; + + Window::isKeyPressedDown = false; + //#ifdef WIN32 + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("KU mod = %d : %d\n", event.key.keysym.mod, SDL_GetModState()); + event.key.keysym.mod = SDL_GetModState(); + //#endif + + keystate = event.key.keysym; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] KEY_UP, Raw SDL key [%d] mod [%d] scancode [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, event.key.keysym.sym, event.key.keysym.mod, event.key.keysym.scancode); + //printf("In [%s::%s Line: %d] KEY_UP, Raw SDL key [%d] mod [%d] scancode [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,event.key.keysym.sym,event.key.keysym.mod,event.key.keysym.scancode); + + if (global_window) { + global_window->eventKeyUp(event.key); + } + + // here is the problem, we have with too many key up events: + // string keyName = SDL_GetKeyName(event.key.keysym.sym); + // if( (keyName == "Return" || keyName == "Enter")){ + // setLastToggle(-1000); + // } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] =================================== END OF SDL SDL_KEYUP ================================\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + break; + } + case SDL_WINDOWEVENT: + { + codeLocation = "k"; + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] SDL_ACTIVEEVENT event.active.state = %d event.active. = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,event.active.state,event.active.gain); + // + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] Window::isActive = %d event.active.state = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,Window::isActive,event.active.state); + // + // // Check if the program has lost window focus + // if ((event.active.state & (SDL_APPACTIVE | SDL_APPINPUTFOCUS))) { + // if (event.active.gain == 0) { + // Window::isActive = false; + // } + // else { + // Window::isActive = true; + // } + // + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] Window::isActive = %d \n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,Window::isActive); + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Window::isActive = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,Window::isActive); + // + // bool willShowCursor = (!Window::isActive || (Window::lastShowMouseState == SDL_ENABLE) || Window::getUseDefaultCursorOnly()); + // showCursor(willShowCursor); + // } + + //printf("In SDL_WINDOWEVENT, event.window.event: %d\n",event.window.event); + + /* + switch(event.window.event) { + case SDL_WINDOWEVENT_ENTER: + printf("In SDL_WINDOWEVENT_ENTER\n"); + showCursor(true); + break; + case SDL_WINDOWEVENT_LEAVE: + printf("In SDL_WINDOWEVENT_LEAVE\n"); + showCursor(false); + break; + case SDL_WINDOWEVENT_FOCUS_GAINED: + printf("SDL_WINDOWEVENT_FOCUS_GAINED\n"); + showCursor(true); + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + printf("SDL_WINDOWEVENT_FOCUS_LOST\n"); + showCursor(false); + break; + } + */ + //showCursor(false); + + if (global_window) { + global_window->eventWindowEvent(event.window); + } + + } break; } - codeLocation = "i"; - Window::isKeyPressedDown = true; -//#ifdef WIN32 - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("KD mod = %d : %d\n",event.key.keysym.mod,SDL_GetModState()); - event.key.keysym.mod = SDL_GetModState(); -//#endif - string keyName = SDL_GetKeyName(event.key.keysym.sym); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] Raw SDL key [%d - %c] mod [%d] scancode [%d] keyName [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,event.key.keysym.sym,event.key.keysym.sym,event.key.keysym.mod,event.key.keysym.scancode,keyName.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Raw SDL key [%d] mod [%d] scancode [%d] keyName [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,event.key.keysym.sym,event.key.keysym.mod,event.key.keysym.scancode,keyName.c_str()); - - //printf("In SDL_KEYDOWN key [%d] keyName [%s] mod: %d\n",event.key.keysym.sym,keyName.c_str(),event.key.keysym.mod); - - // handle ALT+Return - if( (keyName == "Return" || keyName == "Enter") - && (event.key.keysym.mod & (KMOD_LALT | KMOD_RALT))) { - if(event.key.repeat!=0) break; - if (Chrono::getCurMillis() - getLastToggle() > 100) { - toggleFullscreen(); - setLastToggle(Chrono::getCurMillis()); - }; - keyDownConsumed=true; - } -#ifdef WIN32 - // handle ALT+f4 - if((keyName == "f4" || keyName == "F4") - && (event.key.keysym.mod & (KMOD_LALT | KMOD_RALT))) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d] ALT-F4 pressed.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return false; - } -#endif - if(global_window) { - //char key = getKey(event.key.keysym,true); - //key = tolower(key); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("******************* key [%d]\n",key); - - //event.key.keysym.mod = SDL_GetModState(); - if(!keyDownConsumed){ - global_window->eventKeyDown(event.key); - global_window->eventKeyPress(event.key); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] =================================== END OF SDL SDL_KEYDOWN ================================\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - break; + } catch (const char *e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] (a1) Couldn't process event: [%s] codeLocation = %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e, codeLocation.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] (a1) Couldn't process event: [%s] codeLocation = %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e, codeLocation.c_str()); + throw megaglest_runtime_error(e); + } catch (const std::runtime_error& e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] (a2) Couldn't process event: [%s] codeLocation = %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what(), codeLocation.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] (a2) Couldn't process event: [%s] codeLocation = %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what(), codeLocation.c_str()); + throw megaglest_runtime_error(e.what()); + } catch (const std::exception& e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] (b) Couldn't process event: [%s] codeLocation = %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what(), codeLocation.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] (b) Couldn't process event: [%s] codeLocation = %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what(), codeLocation.c_str()); + } catch (...) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] (c) Couldn't process event: [UNKNOWN ERROR] codeLocation = %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, codeLocation.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] (c) Couldn't process event: [UNKNOWN ERROR] codeLocation = %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, codeLocation.c_str()); } - case SDL_KEYUP:{ - //printf("In [%s::%s] Line :%d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + } + SDL_StopTextInput(); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] =================================== START OF SDL SDL_KEYUP ================================\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + return true; + } - codeLocation = "j"; + void Window::revertMousePos() { + SDL_WarpMouseInWindow(sdlWindow, oldX, oldY); + } - Window::isKeyPressedDown = false; -//#ifdef WIN32 - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("KU mod = %d : %d\n",event.key.keysym.mod,SDL_GetModState()); - event.key.keysym.mod = SDL_GetModState(); -//#endif + Vec2i Window::getOldMousePos() { + return Vec2i(oldX, oldY); + } - keystate = event.key.keysym; + string Window::getText() { + const char* c = 0; + //SDL_WM_GetCaption(&c, 0); + c = SDL_GetWindowTitle(sdlWindow); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] KEY_UP, Raw SDL key [%d] mod [%d] scancode [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,event.key.keysym.sym,event.key.keysym.mod,event.key.keysym.scancode); - //printf("In [%s::%s Line: %d] KEY_UP, Raw SDL key [%d] mod [%d] scancode [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,event.key.keysym.sym,event.key.keysym.mod,event.key.keysym.scancode); + return string(c); + } - if(global_window) { - global_window->eventKeyUp(event.key); - } + float Window::getAspect() { + return static_cast(getClientH()) / getClientW(); + } - // here is the problem, we have with too many key up events: -// string keyName = SDL_GetKeyName(event.key.keysym.sym); -// if( (keyName == "Return" || keyName == "Enter")){ -// setLastToggle(-1000); -// } + void Window::setText(string text) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + //SDL_WM_SetCaption(text.c_str(), 0); + SDL_SetWindowTitle(sdlWindow, text.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] =================================== END OF SDL SDL_KEYUP ================================\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + void Window::setSize(int w, int h) { + //this->w = w; + //this->h = h; + Private::ScreenWidth = w; + Private::ScreenHeight = h; + } - break; - } - case SDL_WINDOWEVENT: - { - codeLocation = "k"; -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] SDL_ACTIVEEVENT event.active.state = %d event.active. = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,event.active.state,event.active.gain); -// -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] Window::isActive = %d event.active.state = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,Window::isActive,event.active.state); -// -// // Check if the program has lost window focus -// if ((event.active.state & (SDL_APPACTIVE | SDL_APPINPUTFOCUS))) { -// if (event.active.gain == 0) { -// Window::isActive = false; -// } -// else { -// Window::isActive = true; -// } -// -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] Window::isActive = %d \n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,Window::isActive); -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Window::isActive = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,Window::isActive); -// -// bool willShowCursor = (!Window::isActive || (Window::lastShowMouseState == SDL_ENABLE) || Window::getUseDefaultCursorOnly()); -// showCursor(willShowCursor); -// } - - //printf("In SDL_WINDOWEVENT, event.window.event: %d\n",event.window.event); - - /* - switch(event.window.event) { - case SDL_WINDOWEVENT_ENTER: - printf("In SDL_WINDOWEVENT_ENTER\n"); - showCursor(true); - break; - case SDL_WINDOWEVENT_LEAVE: - printf("In SDL_WINDOWEVENT_LEAVE\n"); - showCursor(false); - break; - case SDL_WINDOWEVENT_FOCUS_GAINED: - printf("SDL_WINDOWEVENT_FOCUS_GAINED\n"); - showCursor(true); - break; - case SDL_WINDOWEVENT_FOCUS_LOST: - printf("SDL_WINDOWEVENT_FOCUS_LOST\n"); - showCursor(false); - break; - } - */ - //showCursor(false); - - if(global_window) { - global_window->eventWindowEvent(event.window); - } - - } - break; + void Window::setPos(int x, int y) { + if (x != 0 || y != 0) { + NOIMPL; + return; } } - catch(const char *e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] (a1) Couldn't process event: [%s] codeLocation = %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e,codeLocation.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] (a1) Couldn't process event: [%s] codeLocation = %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e,codeLocation.c_str()); - throw megaglest_runtime_error(e); + + void Window::minimize() { + NOIMPL; } - catch(const std::runtime_error& e) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] (a2) Couldn't process event: [%s] codeLocation = %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what(),codeLocation.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] (a2) Couldn't process event: [%s] codeLocation = %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what(),codeLocation.c_str()); - throw megaglest_runtime_error(e.what()); + + void Window::setEnabled(bool enabled) { + NOIMPL; } - catch(const std::exception& e) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] (b) Couldn't process event: [%s] codeLocation = %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what(),codeLocation.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] (b) Couldn't process event: [%s] codeLocation = %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what(),codeLocation.c_str()); + + void Window::setVisible(bool visible) { + NOIMPL; } - catch(...) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] (c) Couldn't process event: [UNKNOWN ERROR] codeLocation = %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,codeLocation.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] (c) Couldn't process event: [UNKNOWN ERROR] codeLocation = %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,codeLocation.c_str()); + + void Window::setStyle(WindowStyle windowStyle) { + if (windowStyle == wsFullscreen) + return; + // NOIMPL; } - } - SDL_StopTextInput(); - return true; -} - -void Window::revertMousePos() { - SDL_WarpMouseInWindow(sdlWindow,oldX, oldY); -} - -Vec2i Window::getOldMousePos() { - return Vec2i(oldX, oldY); -} - -string Window::getText() { - const char* c = 0; - //SDL_WM_GetCaption(&c, 0); - c=SDL_GetWindowTitle(sdlWindow); - - return string(c); -} - -float Window::getAspect() { - return static_cast(getClientH())/getClientW(); -} - -void Window::setText(string text) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //SDL_WM_SetCaption(text.c_str(), 0); - SDL_SetWindowTitle(sdlWindow,text.c_str()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void Window::setSize(int w, int h) { - //this->w = w; - //this->h = h; - Private::ScreenWidth = w; - Private::ScreenHeight = h; -} - -void Window::setPos(int x, int y) { - if(x != 0 || y != 0) { - NOIMPL; - return; - } -} - -void Window::minimize() { - NOIMPL; -} - -void Window::setEnabled(bool enabled) { - NOIMPL; -} - -void Window::setVisible(bool visible) { - NOIMPL; -} - -void Window::setStyle(WindowStyle windowStyle) { - if(windowStyle == wsFullscreen) - return; - // NOIMPL; -} - -void Window::create() { - // nothing here - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + void Window::create() { + // nothing here + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); #ifdef WIN32 - ontop_win32(this->getScreenWidth(),this->getScreenHeight()); + ontop_win32(this->getScreenWidth(), this->getScreenHeight()); #endif - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void Window::destroy() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - SDL_Event event; - event.type = SDL_QUIT; - SDL_PushEvent(&event); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void Window::setupGraphicsScreen(int depthBits, int stencilBits, bool hardware_acceleration, bool fullscreen_anti_aliasing) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - static int newDepthBits = depthBits; - static int newStencilBits = stencilBits; - if(depthBits >= 0) - newDepthBits = depthBits; - if(stencilBits >= 0) - newStencilBits = stencilBits; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(fullscreen_anti_aliasing == true) { - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,1); - SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2); - } - if(hardware_acceleration == true) { - SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + void Window::destroy() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 1); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 1); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 1); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, newStencilBits); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, newDepthBits); + SDL_Event event; + event.type = SDL_QUIT; + SDL_PushEvent(&event); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - //const SDL_VideoInfo *info = SDL_GetVideoInfo(); - #ifdef SDL_GL_SWAP_CONTROL - if(Window::tryVSynch == true) { - /* we want vsync for smooth scrolling */ - //SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); - SDL_GL_SetSwapInterval(1); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); } - #endif - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + void Window::setupGraphicsScreen(int depthBits, int stencilBits, bool hardware_acceleration, bool fullscreen_anti_aliasing) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - // setup LOD bias factor - //const float lodBias = std::max(std::min( configHandler->Get("TextureLODBias", 0.0f) , 4.0f), -4.0f); - const float lodBias = max(min(0.0f,4.0f),-4.0f); - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("\n\n\n\n\n$$$$ In [%s::%s Line: %d] lodBias = %f\n\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,lodBias); - if (std::fabs(lodBias) > 0.01f) { - glTexEnvf(GL_TEXTURE_FILTER_CONTROL,GL_TEXTURE_LOD_BIAS, lodBias ); + static int newDepthBits = depthBits; + static int newStencilBits = stencilBits; + if (depthBits >= 0) + newDepthBits = depthBits; + if (stencilBits >= 0) + newStencilBits = stencilBits; + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (fullscreen_anti_aliasing == true) { + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 2); + } + if (hardware_acceleration == true) { + SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 1); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 1); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 1); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, newStencilBits); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, newDepthBits); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + //const SDL_VideoInfo *info = SDL_GetVideoInfo(); +#ifdef SDL_GL_SWAP_CONTROL + if (Window::tryVSynch == true) { + /* we want vsync for smooth scrolling */ + //SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); + SDL_GL_SetSwapInterval(1); + } +#endif + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + // setup LOD bias factor + //const float lodBias = std::max(std::min( configHandler->Get("TextureLODBias", 0.0f) , 4.0f), -4.0f); + const float lodBias = max(min(0.0f, 4.0f), -4.0f); + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("\n\n\n\n\n$$$$ In [%s::%s Line: %d] lodBias = %f\n\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,lodBias); + if (std::fabs(lodBias) > 0.01f) { + glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, lodBias); + } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } -} -void Window::toggleFullscreen() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + void Window::toggleFullscreen() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - Window::isFullScreen = !Window::isFullScreen; + Window::isFullScreen = !Window::isFullScreen; - if(global_window) { - global_window->eventToggleFullScreen(Window::isFullScreen); - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void Window::handleMouseWheel(SDL_Event event) { - int x; - int y; - - if (event.type != SDL_MOUSEWHEEL) { - return; - } - - if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - SDL_GetMouseState(&x, &y); - - // // windows implementation uses 120 for the resolution of a standard mouse - // // wheel notch. However, newer mice have finer resolutions. I dunno if SDL - // // handles those, but for now we're going to say that each mouse wheel - // // movement is 120. - eventMouseWheel(x, y, event.wheel.y * 120); - return; -} - -void Window::handleMouseDown(SDL_Event event) { - static const Uint32 DOUBLECLICKTIME = 500; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - MouseButton button = getMouseButton(event.button.button); - - Uint32 ticks = SDL_GetTicks(); - int n = (int) button; - - assert(n >= 0 && n < mbCount); - if(n >= 0 && n < mbCount) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - static const int DOUBLECLICKDELTA = 5; - if(ticks - lastMouseDown[n] < DOUBLECLICKTIME - && abs(lastMouseX[n] - event.button.x) < DOUBLECLICKDELTA - && abs(lastMouseY[n] - event.button.y) < DOUBLECLICKDELTA) { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - eventMouseDown(event.button.x, event.button.y, button); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - eventMouseDoubleClick(event.button.x, event.button.y, button); + if (global_window) { + global_window->eventToggleFullScreen(Window::isFullScreen); + } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - eventMouseDown(event.button.x, event.button.y, button); + + void Window::handleMouseWheel(SDL_Event event) { + int x; + int y; + + if (event.type != SDL_MOUSEWHEEL) { + return; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) + SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + SDL_GetMouseState(&x, &y); + + // // windows implementation uses 120 for the resolution of a standard mouse + // // wheel notch. However, newer mice have finer resolutions. I dunno if SDL + // // handles those, but for now we're going to say that each mouse wheel + // // movement is 120. + eventMouseWheel(x, y, event.wheel.y * 120); + return; } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - lastMouseDown[n] = ticks; - lastMouseX[n] = event.button.x; - lastMouseY[n] = event.button.y; + void Window::handleMouseDown(SDL_Event event) { + static const Uint32 DOUBLECLICKTIME = 500; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } -} + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); -MouseButton Window::getMouseButton(int sdlButton) { - switch(sdlButton) { - case SDL_BUTTON_LEFT: - return mbLeft; - case SDL_BUTTON_RIGHT: - return mbRight; - case SDL_BUTTON_MIDDLE: - return mbCenter; - default: - //throw std::runtime_error("Mouse Button > 3 not handled."); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Mouse Button [%d] not handled.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,sdlButton); + MouseButton button = getMouseButton(event.button.button); - return mbUnknown; - } -} + Uint32 ticks = SDL_GetTicks(); + int n = (int) button; -wchar_t Window::convertStringtoSDLKey(const string &value) { - wchar_t result = SDLK_UNKNOWN; + assert(n >= 0 && n < mbCount); + if (n >= 0 && n < mbCount) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - if(value.length() >= 1) { - if(value.length() == 3 && value[0] == '\'' && value[2] == '\'') { - result = (SDL_Keycode)value[1]; + static const int DOUBLECLICKDELTA = 5; + if (ticks - lastMouseDown[n] < DOUBLECLICKTIME + && abs(lastMouseX[n] - event.button.x) < DOUBLECLICKDELTA + && abs(lastMouseY[n] - event.button.y) < DOUBLECLICKDELTA) { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + eventMouseDown(event.button.x, event.button.y, button); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + eventMouseDoubleClick(event.button.x, event.button.y, button); + } else { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + eventMouseDown(event.button.x, event.button.y, button); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + lastMouseDown[n] = ticks; + lastMouseX[n] = event.button.x; + lastMouseY[n] = event.button.y; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } } - else { - bool foundKey = false; - if(value.length() > 1) { - for(int i = SDLK_UNKNOWN; i < SDL_NUM_SCANCODES; ++i) { - SDL_Keycode key = static_cast(i); - string keyName = SDL_GetKeyName(key); - if(value == keyName) { - result = key; - foundKey = true; + + MouseButton Window::getMouseButton(int sdlButton) { + switch (sdlButton) { + case SDL_BUTTON_LEFT: + return mbLeft; + case SDL_BUTTON_RIGHT: + return mbRight; + case SDL_BUTTON_MIDDLE: + return mbCenter; + default: + //throw std::runtime_error("Mouse Button > 3 not handled."); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] Mouse Button [%d] not handled.\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, sdlButton); + + return mbUnknown; + } + } + + wchar_t Window::convertStringtoSDLKey(const string &value) { + wchar_t result = SDLK_UNKNOWN; + + if (value.length() >= 1) { + if (value.length() == 3 && value[0] == '\'' && value[2] == '\'') { + result = (SDL_Keycode) value[1]; + } else { + bool foundKey = false; + if (value.length() > 1) { + for (int i = SDLK_UNKNOWN; i < SDL_NUM_SCANCODES; ++i) { + SDL_Keycode key = static_cast(i); + string keyName = SDL_GetKeyName(key); + if (value == keyName) { + result = key; + foundKey = true; + break; + } + } + } + + if (foundKey == false) { + result = (SDL_Keycode) value[0]; + } + } + } else { + string sError = "Unsupported key name: [" + value + "]"; + throw megaglest_runtime_error(sError.c_str()); + } + + // Because SDL is based on lower Ascii + //result = tolower(result); + return result; + } + + void Window::addAllowedKeys(string keyList) { + clearAllowedKeys(); + + if (keyList.empty() == false) { + vector keys; + Tokenize(keyList, keys, ","); + if (keys.empty() == false) { + for (unsigned int keyIndex = 0; keyIndex < keys.size(); ++keyIndex) { + string key = trim(keys[keyIndex]); + + wchar_t sdl_key = convertStringtoSDLKey(key); + if (sdl_key != SDLK_UNKNOWN) { + mapAllowedKeys[sdl_key] = true; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("key: %d [%s] IS ALLOWED\n", sdl_key, key.c_str()); + //printf("key: %d [%s] IS ALLOWED\n",sdl_key, key.c_str()); + } + } + } + } + void Window::clearAllowedKeys() { + mapAllowedKeys.clear(); + } + + bool Window::isAllowedKey(wchar_t key) { + map::const_iterator iterFind = mapAllowedKeys.find(key); + bool result = (iterFind != mapAllowedKeys.end()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) { + string keyName = SDL_GetKeyName((SDL_Keycode) key); + printf("key: %d [%s] allowed result: %d\n", key, keyName.c_str(), result); + } + + return result; + } + + bool isKeyPressed(SDL_Keycode compareKey, SDL_KeyboardEvent input, bool modifiersAllowed) { + vector modifiersToCheck; + if (modifiersAllowed == false) { + modifiersToCheck.push_back(KMOD_LCTRL); + modifiersToCheck.push_back(KMOD_RCTRL); + modifiersToCheck.push_back(KMOD_LALT); + modifiersToCheck.push_back(KMOD_RALT); + } + + bool result = isKeyPressed(compareKey, input, modifiersToCheck); + return result; + } + bool isKeyPressed(SDL_Keycode compareKey, SDL_KeyboardEvent input, vector modifiersToCheck) { + //Uint16 c = SDLK_UNKNOWN; + SDL_Keycode c = SDLK_UNKNOWN; + //if(input.keysym.unicode > 0 && input.keysym.unicode < 0x80) { + if (input.keysym.sym > 0) { + c = input.keysym.sym; + } + + //printf("START isKeyPressed input = %d compare = %d mod = %d\n",c,compareKey,input.keysym.mod); + + + // if(compareKey == SDLK_QUESTION && (c == SDLK_SLASH && (input.keysym.mod & (KMOD_SHIFT)))) { + // return true; + // } + // else if(compareKey == SDLK_SLASH && (c == SDLK_SLASH && (input.keysym.mod & (KMOD_SHIFT)))) { + // return false; + // } + + //// string unicodeKeyName = SDL_GetKeyName((SDLKey)input.keysym.unicode); + //// + //// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] input.keysym.unicode = %d input.keysym.mod = %d input.keysym.sym = %d unicodeKeyName [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,input.keysym.unicode,input.keysym.mod,input.keysym.sym,unicodeKeyName.c_str()); + //// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] input.keysym.unicode = %d input.keysym.mod = %d input.keysym.sym = %d unicodeKeyName [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,input.keysym.unicode,input.keysym.mod,input.keysym.sym,unicodeKeyName.c_str()); + // + // // When modifiers are pressed the unicode result is wrong + // // example CTRL-3 will give the ESCAPE vslue 27 in unicode + // if( !(input.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) && + // !(input.keysym.mod & (KMOD_LALT | KMOD_RALT)) && + // !(input.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) ) { + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // + // c = input.keysym.sym; + // //c = toupper(c); + // } + // else if((input.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) && + // (input.keysym.sym == SDLK_QUESTION || + // input.keysym.sym == SDLK_AT || + // input.keysym.sym == SDLK_COLON || + // input.keysym.sym == SDLK_LESS || + // input.keysym.sym == SDLK_GREATER || + // input.keysym.sym == SDLK_CARET || + // input.keysym.sym == SDLK_UNDERSCORE || + // input.keysym.sym == SDLK_BACKQUOTE || + // input.keysym.sym == SDLK_EXCLAIM || + // input.keysym.sym == SDLK_QUOTEDBL || + // input.keysym.sym == SDLK_HASH || + // input.keysym.sym == SDLK_DOLLAR || + // input.keysym.sym == SDLK_AMPERSAND || + // input.keysym.sym == SDLK_QUOTE || + // input.keysym.sym == SDLK_LEFTPAREN || + // input.keysym.sym == SDLK_RIGHTPAREN || + // input.keysym.sym == SDLK_ASTERISK || + // input.keysym.sym == SDLK_KP_MULTIPLY || + // input.keysym.sym == SDLK_PLUS || + // input.keysym.sym == SDLK_COMMA || + // input.keysym.sym == SDLK_MINUS || + // input.keysym.sym == SDLK_PERIOD || + // input.keysym.sym == SDLK_SLASH || + // // Need to allow Shift + # key for AZERTY style keyboards + // input.keysym.sym == SDLK_0 || + // input.keysym.sym == SDLK_1 || + // input.keysym.sym == SDLK_2 || + // input.keysym.sym == SDLK_3 || + // input.keysym.sym == SDLK_4 || + // input.keysym.sym == SDLK_5 || + // input.keysym.sym == SDLK_6 || + // input.keysym.sym == SDLK_7 || + // input.keysym.sym == SDLK_8 || + // input.keysym.sym == SDLK_9 + // )) { + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // + // c = input.keysym.sym; + // } + // else if(input.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) { + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // + // if( (input.keysym.sym >= SDLK_0 && input.keysym.sym <= SDLK_9) || + // (input.keysym.sym >= SDLK_KP_0 && input.keysym.sym <= SDLK_KP_9)) { + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // + // c = input.keysym.sym; + // } + // } + // + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] #1 (c & 0xFF) [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(c & 0xFF)); + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] #1 (c & 0xFF) [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(c & 0xFF)); + // } + // //if(c == 0) { + // if(c <= SDLK_UNKNOWN.sym || c >= SDLK_LAST.sym) { + // c = input.keysym.sym; + // } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %u] c = [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, c); + + //c = (c & 0xFF); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] returning key [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, c); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] returning key [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, c); + + // SDL does NOT handle lowercase + if (c >= 'A' && c <= 'Z') { + c = tolower(c); + } + // SDL does NOT handle lowercase + if (compareKey >= 'A' && compareKey <= 'Z') { + compareKey = (SDL_Keycode) tolower((char) compareKey); + } + + bool result = (c == compareKey); + //printf("result = %d input = %d compare = %d\n",result,c,compareKey); + + if (result == false) { + if (compareKey == SDLK_RETURN) { + result = (c == SDLK_KP_ENTER); + } else if (compareKey == SDLK_KP_ENTER) { + result = (c == SDLK_RETURN); + } else if (compareKey == SDLK_BACKSPACE) { + result = (c == SDLK_DELETE); + } + } + // else if(compareKey == SDLK_ASTERISK) { + // result = (c == SDLK_KP_MULTIPLY); + // } + // else if(compareKey == SDLK_KP_MULTIPLY) { + // result = (c == SDLK_ASTERISK); + // } + // else if (compareKey == SDLK_0) { + // result = (c == SDLK_KP_0); + // } else if (compareKey == SDLK_1) { + // result = (c == SDLK_KP_1); + // } else if (compareKey == SDLK_2) { + // result = (c == SDLK_KP_2); + // } else if (compareKey == SDLK_3) { + // result = (c == SDLK_KP_3); + // } else if (compareKey == SDLK_4) { + // result = (c == SDLK_KP_4); + // } else if (compareKey == SDLK_5) { + // result = (c == SDLK_KP_5); + // } else if (compareKey == SDLK_6) { + // result = (c == SDLK_KP_6); + // } else if (compareKey == SDLK_7) { + // result = (c == SDLK_KP_7); + // } else if (compareKey == SDLK_8) { + // result = (c == SDLK_KP_8); + // } else if (compareKey == SDLK_9) { + // result = (c == SDLK_KP_9); + // } else if (compareKey == SDLK_KP_0) { + // result = (c == SDLK_0); + // } else if (compareKey == SDLK_KP_1) { + // result = (c == SDLK_1); + // } else if (compareKey == SDLK_KP_2) { + // result = (c == SDLK_2); + // } else if (compareKey == SDLK_KP_3) { + // result = (c == SDLK_3); + // } else if (compareKey == SDLK_KP_4) { + // result = (c == SDLK_4); + // } else if (compareKey == SDLK_KP_5) { + // result = (c == SDLK_5); + // } else if (compareKey == SDLK_KP_6) { + // result = (c == SDLK_6); + // } else if (compareKey == SDLK_KP_7) { + // result = (c == SDLK_7); + // } else if (compareKey == SDLK_KP_8) { + // result = (c == SDLK_8); + // } else if (compareKey == SDLK_KP_9) { + // result = (c == SDLK_9); + // } + // } + + if (result == true) { + //printf("input.keysym.mod = %d\n",input.keysym.mod); + + for (unsigned int i = 0; i < modifiersToCheck.size(); ++i) { + if ((input.keysym.mod & modifiersToCheck[i])) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] result *WOULD HAVE BEEN TRUE* but is false due to: input.keysym.mod = %d modifiersToCheck[i] = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, input.keysym.mod, modifiersToCheck[i]); + result = false; break; } } } + string compareKeyName = SDL_GetKeyName(compareKey); + string pressKeyName = SDL_GetKeyName((SDL_Keycode) c); - if(foundKey == false) { - result = (SDL_Keycode)value[0]; - } + //printf ("In [%s::%s Line: %d] compareKey [%d - %s] pressed key [%d - %s] result = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,compareKey,compareKeyName.c_str(),c,pressKeyName.c_str(),result); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] compareKey [%d - %s] pressed key [%d - %s] result = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, compareKey, compareKeyName.c_str(), c, pressKeyName.c_str(), result); + //printf ("ISPRESS compareKey [%d - %s] pressed key [%d - %s] input.keysym.sym [%d] input.keysym.unicode [%d] mod = %d result = %d\n", + // compareKey,compareKeyName.c_str(),c,pressKeyName.c_str(),input.keysym.sym,input.keysym.unicode,input.keysym.mod,result); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] compareKey [%d - %s] pressed key [%d - %s] result = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, compareKey, compareKeyName.c_str(), c, pressKeyName.c_str(), result); + + return result; } - } - else { - string sError = "Unsupported key name: [" + value + "]"; - throw megaglest_runtime_error(sError.c_str()); - } - // Because SDL is based on lower Ascii - //result = tolower(result); - return result; -} + //wchar_t extractKeyPressedUnicode(SDL_KeyboardEvent input) { + // wchar_t c = SDLK_UNKNOWN; + // //if(input.keysym.unicode > 0 && input.keysym.unicode < 0x80) { + // if(input.keysym.sym > 0) { + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] input.keysym.sym = %d input.keysym.mod = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,input.keysym.sym,input.keysym.mod); + // + // c = input.keysym.sym; + //// if(c <= SDLK_UNKNOWN || c >= SDLK_LAST) { + //// c = SDLKey(c & 0xFF); + //// } + // + // //c = toupper(c); + // + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] #1 (c & 0xFF) [%d] c = [%lc]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(c & 0xFF),c); + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] #1 (c & 0xFF) [%d] c = [%lc]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(c & 0xFF),c); + // } + // if(c == SDLK_UNKNOWN) { + // c = input.keysym.sym; + // } + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %u] c = [%d][%lc]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c); + // + // //c = (SDLKey)(c & 0xFF); + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] returning key [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c); + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] returning key [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c); + // + // string pressKeyName = SDL_GetKeyName((SDL_Keycode)c); + // //string inputKeyName = SDL_GetKeyName(input.keysym.sym); + // + // //printf ("PRESS pressed key [%d - %s] input.keysym.sym [%d] input.keysym.unicode [%d] mod = %d\n", + // // c,pressKeyName.c_str(),input.keysym.sym,input.keysym.unicode,input.keysym.mod); + // + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] pressed key [%d - %s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c,pressKeyName.c_str()); + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] pressed key [%d - %s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c,pressKeyName.c_str()); + // + // return c; + //} -void Window::addAllowedKeys(string keyList) { - clearAllowedKeys(); + vector extractKeyPressedUnicodeLength(string text) { + vector result; + unsigned int i = 0; + for (i = 0; i < text.length();) { + char c = text[i]; + wchar_t keyW = c; + wchar_t textAppend[] = { keyW, 0 }; - if(keyList.empty() == false) { - vector keys; - Tokenize(keyList,keys,","); - if(keys.empty() == false) { - for(unsigned int keyIndex = 0; keyIndex < keys.size(); ++keyIndex) { - string key = trim(keys[keyIndex]); - - wchar_t sdl_key = convertStringtoSDLKey(key); - if(sdl_key != SDLK_UNKNOWN) { - mapAllowedKeys[sdl_key] = true; + if (*textAppend) { + wchar_t newKey = textAppend[0]; + if (newKey < 0x80) { + result.push_back(1); + //printf("1 char, textCharLength = %d\n",textCharLength.size()); + } else if (newKey < 0x800) { + result.push_back(2); + //printf("2 char, textCharLength = %d\n",textCharLength.size()); + } else { + result.push_back(3); + //printf("3 char, textCharLength = %d\n",textCharLength.size()); + } + i += result[result.size() - 1]; } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("key: %d [%s] IS ALLOWED\n",sdl_key, key.c_str()); - //printf("key: %d [%s] IS ALLOWED\n",sdl_key, key.c_str()); } + return result; } - } -} -void Window::clearAllowedKeys() { - mapAllowedKeys.clear(); -} -bool Window::isAllowedKey(wchar_t key) { - map::const_iterator iterFind = mapAllowedKeys.find(key); - bool result =(iterFind != mapAllowedKeys.end()); + SDL_Keycode extractKeyPressed(SDL_KeyboardEvent input) { + SDL_Keycode c = SDLK_UNKNOWN; + //if(input.keysym.unicode > 0 && input.keysym.unicode < 0x80) { + //if(input.keysym.sym > 0) { + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] input.keysym.sym = %d input.keysym.mod = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,input.keysym.sym,input.keysym.mod); - if(SystemFlags::VERBOSE_MODE_ENABLED) { - string keyName = SDL_GetKeyName((SDL_Keycode)key); - printf("key: %d [%s] allowed result: %d\n",key,keyName.c_str(),result); - } + // c = input.keysym.sym; + // if(c <= SDLK_UNKNOWN || c >= SDLK_LAST) { + // c = SDLKey(c & 0xFF); + // } - return result; -} + //c = toupper(c); -bool isKeyPressed(SDL_Keycode compareKey, SDL_KeyboardEvent input,bool modifiersAllowed) { - vector modifiersToCheck; - if(modifiersAllowed == false) { - modifiersToCheck.push_back(KMOD_LCTRL); - modifiersToCheck.push_back(KMOD_RCTRL); - modifiersToCheck.push_back(KMOD_LALT); - modifiersToCheck.push_back(KMOD_RALT); - } + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] #1 (c & 0xFF) [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(c & 0xFF)); + //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] #1 (c & 0xFF) [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(c & 0xFF)); + //} + //if(c <= SDLK_UNKNOWN) { + c = input.keysym.sym; + //} - bool result = isKeyPressed(compareKey, input, modifiersToCheck); - return result; -} -bool isKeyPressed(SDL_Keycode compareKey, SDL_KeyboardEvent input,vector modifiersToCheck) { - //Uint16 c = SDLK_UNKNOWN; - SDL_Keycode c = SDLK_UNKNOWN; - //if(input.keysym.unicode > 0 && input.keysym.unicode < 0x80) { - if(input.keysym.sym > 0) { - c = input.keysym.sym; - } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %u] c = [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, c); - //printf("START isKeyPressed input = %d compare = %d mod = %d\n",c,compareKey,input.keysym.mod); + //c = (SDLKey)(c & 0xFF); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] returning key [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, c); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] returning key [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, c); + string pressKeyName = SDL_GetKeyName(c); + //string inputKeyName = SDL_GetKeyName(input.keysym.sym); -// if(compareKey == SDLK_QUESTION && (c == SDLK_SLASH && (input.keysym.mod & (KMOD_SHIFT)))) { -// return true; -// } -// else if(compareKey == SDLK_SLASH && (c == SDLK_SLASH && (input.keysym.mod & (KMOD_SHIFT)))) { -// return false; -// } + // printf ("PRESS pressed key [%d - %s] input.keysym.sym [%d] mod = %d\n", + // c,pressKeyName.c_str(),input.keysym.sym,input.keysym.mod); -//// string unicodeKeyName = SDL_GetKeyName((SDLKey)input.keysym.unicode); -//// -//// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] input.keysym.unicode = %d input.keysym.mod = %d input.keysym.sym = %d unicodeKeyName [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,input.keysym.unicode,input.keysym.mod,input.keysym.sym,unicodeKeyName.c_str()); -//// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] input.keysym.unicode = %d input.keysym.mod = %d input.keysym.sym = %d unicodeKeyName [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,input.keysym.unicode,input.keysym.mod,input.keysym.sym,unicodeKeyName.c_str()); -// -// // When modifiers are pressed the unicode result is wrong -// // example CTRL-3 will give the ESCAPE vslue 27 in unicode -// if( !(input.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) && -// !(input.keysym.mod & (KMOD_LALT | KMOD_RALT)) && -// !(input.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) ) { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// -// c = input.keysym.sym; -// //c = toupper(c); -// } -// else if((input.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) && -// (input.keysym.sym == SDLK_QUESTION || -// input.keysym.sym == SDLK_AT || -// input.keysym.sym == SDLK_COLON || -// input.keysym.sym == SDLK_LESS || -// input.keysym.sym == SDLK_GREATER || -// input.keysym.sym == SDLK_CARET || -// input.keysym.sym == SDLK_UNDERSCORE || -// input.keysym.sym == SDLK_BACKQUOTE || -// input.keysym.sym == SDLK_EXCLAIM || -// input.keysym.sym == SDLK_QUOTEDBL || -// input.keysym.sym == SDLK_HASH || -// input.keysym.sym == SDLK_DOLLAR || -// input.keysym.sym == SDLK_AMPERSAND || -// input.keysym.sym == SDLK_QUOTE || -// input.keysym.sym == SDLK_LEFTPAREN || -// input.keysym.sym == SDLK_RIGHTPAREN || -// input.keysym.sym == SDLK_ASTERISK || -// input.keysym.sym == SDLK_KP_MULTIPLY || -// input.keysym.sym == SDLK_PLUS || -// input.keysym.sym == SDLK_COMMA || -// input.keysym.sym == SDLK_MINUS || -// input.keysym.sym == SDLK_PERIOD || -// input.keysym.sym == SDLK_SLASH || -// // Need to allow Shift + # key for AZERTY style keyboards -// input.keysym.sym == SDLK_0 || -// input.keysym.sym == SDLK_1 || -// input.keysym.sym == SDLK_2 || -// input.keysym.sym == SDLK_3 || -// input.keysym.sym == SDLK_4 || -// input.keysym.sym == SDLK_5 || -// input.keysym.sym == SDLK_6 || -// input.keysym.sym == SDLK_7 || -// input.keysym.sym == SDLK_8 || -// input.keysym.sym == SDLK_9 -// )) { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// -// c = input.keysym.sym; -// } -// else if(input.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// -// if( (input.keysym.sym >= SDLK_0 && input.keysym.sym <= SDLK_9) || -// (input.keysym.sym >= SDLK_KP_0 && input.keysym.sym <= SDLK_KP_9)) { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// -// c = input.keysym.sym; -// } -// } -// -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] #1 (c & 0xFF) [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(c & 0xFF)); -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] #1 (c & 0xFF) [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(c & 0xFF)); -// } -// //if(c == 0) { -// if(c <= SDLK_UNKNOWN.sym || c >= SDLK_LAST.sym) { -// c = input.keysym.sym; -// } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] pressed key [%d - %s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, c, pressKeyName.c_str()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] pressed key [%d - %s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, c, pressKeyName.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %u] c = [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c); - - //c = (c & 0xFF); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] returning key [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] returning key [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c); - - // SDL does NOT handle lowercase - if(c >= 'A' && c <= 'Z') { - c = tolower(c); - } - // SDL does NOT handle lowercase - if(compareKey >= 'A' && compareKey <= 'Z') { - compareKey = (SDL_Keycode)tolower((char)compareKey); - } - - bool result = (c == compareKey); - //printf("result = %d input = %d compare = %d\n",result,c,compareKey); - - if(result == false) { - if(compareKey == SDLK_RETURN) { - result = (c == SDLK_KP_ENTER); + return c; } - else if(compareKey == SDLK_KP_ENTER) { - result = (c == SDLK_RETURN); - } - else if(compareKey == SDLK_BACKSPACE) { - result = (c == SDLK_DELETE); - } - } -// else if(compareKey == SDLK_ASTERISK) { -// result = (c == SDLK_KP_MULTIPLY); -// } -// else if(compareKey == SDLK_KP_MULTIPLY) { -// result = (c == SDLK_ASTERISK); -// } -// else if (compareKey == SDLK_0) { -// result = (c == SDLK_KP_0); -// } else if (compareKey == SDLK_1) { -// result = (c == SDLK_KP_1); -// } else if (compareKey == SDLK_2) { -// result = (c == SDLK_KP_2); -// } else if (compareKey == SDLK_3) { -// result = (c == SDLK_KP_3); -// } else if (compareKey == SDLK_4) { -// result = (c == SDLK_KP_4); -// } else if (compareKey == SDLK_5) { -// result = (c == SDLK_KP_5); -// } else if (compareKey == SDLK_6) { -// result = (c == SDLK_KP_6); -// } else if (compareKey == SDLK_7) { -// result = (c == SDLK_KP_7); -// } else if (compareKey == SDLK_8) { -// result = (c == SDLK_KP_8); -// } else if (compareKey == SDLK_9) { -// result = (c == SDLK_KP_9); -// } else if (compareKey == SDLK_KP_0) { -// result = (c == SDLK_0); -// } else if (compareKey == SDLK_KP_1) { -// result = (c == SDLK_1); -// } else if (compareKey == SDLK_KP_2) { -// result = (c == SDLK_2); -// } else if (compareKey == SDLK_KP_3) { -// result = (c == SDLK_3); -// } else if (compareKey == SDLK_KP_4) { -// result = (c == SDLK_4); -// } else if (compareKey == SDLK_KP_5) { -// result = (c == SDLK_5); -// } else if (compareKey == SDLK_KP_6) { -// result = (c == SDLK_6); -// } else if (compareKey == SDLK_KP_7) { -// result = (c == SDLK_7); -// } else if (compareKey == SDLK_KP_8) { -// result = (c == SDLK_8); -// } else if (compareKey == SDLK_KP_9) { -// result = (c == SDLK_9); -// } -// } - if(result == true) { - //printf("input.keysym.mod = %d\n",input.keysym.mod); + //bool isAllowedInputTextKey(wchar_t &key) { + // if(Window::isAllowedKey(key) == true) { + // return true; + // } + // + // bool result = ( + // key != SDLK_DELETE && + // key != SDLK_BACKSPACE && + // key != SDLK_TAB && + // key != SDLK_CLEAR && + // key != SDLK_RETURN && + // key != SDLK_PAUSE && + // key != SDLK_UP && + // key != SDLK_DOWN && + // key != SDLK_RIGHT && + // key != SDLK_LEFT && + // key != SDLK_INSERT && + // key != SDLK_HOME && + // key != SDLK_END && + // key != SDLK_PAGEUP && + // key != SDLK_PAGEDOWN && + // key != SDLK_F1 && + // key != SDLK_F2 && + // key != SDLK_F3 && + // key != SDLK_F4 && + // key != SDLK_F5 && + // key != SDLK_F6 && + // key != SDLK_F7 && + // key != SDLK_F8 && + // key != SDLK_F9 && + // key != SDLK_F10 && + // key != SDLK_F11 && + // key != SDLK_F12 && + // key != SDLK_F13 && + // key != SDLK_F14 && + // key != SDLK_F15 && + // key != SDLK_NUMLOCKCLEAR && + // key != SDLK_CAPSLOCK && + // key != SDLK_SCROLLLOCK && + // key != SDLK_RSHIFT && + // key != SDLK_LSHIFT && + // key != SDLK_RCTRL && + // key != SDLK_LCTRL && + // key != SDLK_RALT && + // key != SDLK_LALT && + // key != SDLK_RGUI && + // key != SDLK_LGUI && + // key != SDLK_MODE && + // key != SDLK_HELP && + // key != SDLK_PRINTSCREEN && + // key != SDLK_SYSREQ && + // key != SDLK_PAUSE && + // key != SDLK_MENU && + // key != SDLK_POWER); + // + // string inputKeyName = SDL_GetKeyName((SDL_Keycode)key); + // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] pressed key [%d - %s] result = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,key,inputKeyName.c_str(),result); + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] pressed key [%d - %s] result = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,key,inputKeyName.c_str(),result); + // + // return result; + //} - for(unsigned int i = 0; i < modifiersToCheck.size(); ++i) { - if( (input.keysym.mod & modifiersToCheck[i])) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] result *WOULD HAVE BEEN TRUE* but is false due to: input.keysym.mod = %d modifiersToCheck[i] = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,input.keysym.mod,modifiersToCheck[i]); - result = false; - break; + bool isAllowedInputTextKey(SDL_Keycode key) { + if (Window::isAllowedKey(key) == true) { + return true; } + + bool result = ( + key != SDLK_DELETE && + key != SDLK_BACKSPACE && + key != SDLK_TAB && + key != SDLK_CLEAR && + key != SDLK_RETURN && + key != SDLK_PAUSE && + key != SDLK_UP && + key != SDLK_DOWN && + key != SDLK_RIGHT && + key != SDLK_LEFT && + key != SDLK_INSERT && + key != SDLK_HOME && + key != SDLK_END && + key != SDLK_PAGEUP && + key != SDLK_PAGEDOWN && + key != SDLK_F1 && + key != SDLK_F2 && + key != SDLK_F3 && + key != SDLK_F4 && + key != SDLK_F5 && + key != SDLK_F6 && + key != SDLK_F7 && + key != SDLK_F8 && + key != SDLK_F9 && + key != SDLK_F10 && + key != SDLK_F11 && + key != SDLK_F12 && + key != SDLK_F13 && + key != SDLK_F14 && + key != SDLK_F15 && + key != SDLK_NUMLOCKCLEAR && + key != SDLK_CAPSLOCK && + key != SDLK_SCROLLLOCK && + key != SDLK_RSHIFT && + key != SDLK_LSHIFT && + key != SDLK_RCTRL && + key != SDLK_LCTRL && + key != SDLK_RALT && + key != SDLK_LALT && + key != SDLK_RGUI && + key != SDLK_LGUI && + key != SDLK_MODE && + key != SDLK_HELP && + key != SDLK_PRINTSCREEN && + key != SDLK_SYSREQ && + key != SDLK_MENU && + key != SDLK_POWER); + + string inputKeyName = SDL_GetKeyName(key); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] pressed key [%d - %s] result = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, key, inputKeyName.c_str(), result); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] pressed key [%d - %s] result = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, key, inputKeyName.c_str(), result); + + return result; } - } - string compareKeyName = SDL_GetKeyName(compareKey); - string pressKeyName = SDL_GetKeyName((SDL_Keycode)c); - //printf ("In [%s::%s Line: %d] compareKey [%d - %s] pressed key [%d - %s] result = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,compareKey,compareKeyName.c_str(),c,pressKeyName.c_str(),result); + bool Window::isKeyStateModPressed(int mod) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("isKeyStateModPressed mod = %d, keystate.mod = %d, keystate.mod & mod = %d\n", mod, keystate.mod, (keystate.mod & mod)); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] compareKey [%d - %s] pressed key [%d - %s] result = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,compareKey,compareKeyName.c_str(),c,pressKeyName.c_str(),result); - //printf ("ISPRESS compareKey [%d - %s] pressed key [%d - %s] input.keysym.sym [%d] input.keysym.unicode [%d] mod = %d result = %d\n", - // compareKey,compareKeyName.c_str(),c,pressKeyName.c_str(),input.keysym.sym,input.keysym.unicode,input.keysym.mod,result); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] compareKey [%d - %s] pressed key [%d - %s] result = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,compareKey,compareKeyName.c_str(),c,pressKeyName.c_str(),result); - - return result; -} - -//wchar_t extractKeyPressedUnicode(SDL_KeyboardEvent input) { -// wchar_t c = SDLK_UNKNOWN; -// //if(input.keysym.unicode > 0 && input.keysym.unicode < 0x80) { -// if(input.keysym.sym > 0) { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] input.keysym.sym = %d input.keysym.mod = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,input.keysym.sym,input.keysym.mod); -// -// c = input.keysym.sym; -//// if(c <= SDLK_UNKNOWN || c >= SDLK_LAST) { -//// c = SDLKey(c & 0xFF); -//// } -// -// //c = toupper(c); -// -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] #1 (c & 0xFF) [%d] c = [%lc]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(c & 0xFF),c); -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] #1 (c & 0xFF) [%d] c = [%lc]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(c & 0xFF),c); -// } -// if(c == SDLK_UNKNOWN) { -// c = input.keysym.sym; -// } -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %u] c = [%d][%lc]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c); -// -// //c = (SDLKey)(c & 0xFF); -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] returning key [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c); -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] returning key [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c); -// -// string pressKeyName = SDL_GetKeyName((SDL_Keycode)c); -// //string inputKeyName = SDL_GetKeyName(input.keysym.sym); -// -// //printf ("PRESS pressed key [%d - %s] input.keysym.sym [%d] input.keysym.unicode [%d] mod = %d\n", -// // c,pressKeyName.c_str(),input.keysym.sym,input.keysym.unicode,input.keysym.mod); -// -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] pressed key [%d - %s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c,pressKeyName.c_str()); -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] pressed key [%d - %s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c,pressKeyName.c_str()); -// -// return c; -//} - -vector extractKeyPressedUnicodeLength(string text) { - vector result; - unsigned int i = 0; - for(i = 0; i < text.length();) { - char c = text[i]; - wchar_t keyW = c; - wchar_t textAppend[] = { keyW, 0 }; - - if(*textAppend) { - wchar_t newKey = textAppend[0]; - if (newKey < 0x80) { - result.push_back(1); - //printf("1 char, textCharLength = %d\n",textCharLength.size()); + if (keystate.mod & mod) { + return true; } - else if (newKey < 0x800) { - result.push_back(2); - //printf("2 char, textCharLength = %d\n",textCharLength.size()); - } - else { - result.push_back(3); - //printf("3 char, textCharLength = %d\n",textCharLength.size()); - } - i += result[result.size()-1]; + return false; } + + wchar_t Window::extractLastKeyPressed() { + return keystate.sym; + } + } - return result; -} - -SDL_Keycode extractKeyPressed(SDL_KeyboardEvent input) { - SDL_Keycode c = SDLK_UNKNOWN; - //if(input.keysym.unicode > 0 && input.keysym.unicode < 0x80) { - //if(input.keysym.sym > 0) { - // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] input.keysym.sym = %d input.keysym.mod = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,input.keysym.sym,input.keysym.mod); - - // c = input.keysym.sym; -// if(c <= SDLK_UNKNOWN || c >= SDLK_LAST) { -// c = SDLKey(c & 0xFF); -// } - - //c = toupper(c); - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] #1 (c & 0xFF) [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(c & 0xFF)); - //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] #1 (c & 0xFF) [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(c & 0xFF)); - //} - //if(c <= SDLK_UNKNOWN) { - c = input.keysym.sym; - //} - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %u] c = [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c); - - //c = (SDLKey)(c & 0xFF); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] returning key [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] returning key [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c); - - string pressKeyName = SDL_GetKeyName(c); - //string inputKeyName = SDL_GetKeyName(input.keysym.sym); - -// printf ("PRESS pressed key [%d - %s] input.keysym.sym [%d] mod = %d\n", -// c,pressKeyName.c_str(),input.keysym.sym,input.keysym.mod); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf ("In [%s::%s Line: %d] pressed key [%d - %s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c,pressKeyName.c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] pressed key [%d - %s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,c,pressKeyName.c_str()); - - return c; -} - -//bool isAllowedInputTextKey(wchar_t &key) { -// if(Window::isAllowedKey(key) == true) { -// return true; -// } -// -// bool result = ( -// key != SDLK_DELETE && -// key != SDLK_BACKSPACE && -// key != SDLK_TAB && -// key != SDLK_CLEAR && -// key != SDLK_RETURN && -// key != SDLK_PAUSE && -// key != SDLK_UP && -// key != SDLK_DOWN && -// key != SDLK_RIGHT && -// key != SDLK_LEFT && -// key != SDLK_INSERT && -// key != SDLK_HOME && -// key != SDLK_END && -// key != SDLK_PAGEUP && -// key != SDLK_PAGEDOWN && -// key != SDLK_F1 && -// key != SDLK_F2 && -// key != SDLK_F3 && -// key != SDLK_F4 && -// key != SDLK_F5 && -// key != SDLK_F6 && -// key != SDLK_F7 && -// key != SDLK_F8 && -// key != SDLK_F9 && -// key != SDLK_F10 && -// key != SDLK_F11 && -// key != SDLK_F12 && -// key != SDLK_F13 && -// key != SDLK_F14 && -// key != SDLK_F15 && -// key != SDLK_NUMLOCKCLEAR && -// key != SDLK_CAPSLOCK && -// key != SDLK_SCROLLLOCK && -// key != SDLK_RSHIFT && -// key != SDLK_LSHIFT && -// key != SDLK_RCTRL && -// key != SDLK_LCTRL && -// key != SDLK_RALT && -// key != SDLK_LALT && -// key != SDLK_RGUI && -// key != SDLK_LGUI && -// key != SDLK_MODE && -// key != SDLK_HELP && -// key != SDLK_PRINTSCREEN && -// key != SDLK_SYSREQ && -// key != SDLK_PAUSE && -// key != SDLK_MENU && -// key != SDLK_POWER); -// -// string inputKeyName = SDL_GetKeyName((SDL_Keycode)key); -// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] pressed key [%d - %s] result = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,key,inputKeyName.c_str(),result); -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] pressed key [%d - %s] result = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,key,inputKeyName.c_str(),result); -// -// return result; -//} - -bool isAllowedInputTextKey(SDL_Keycode key) { - if(Window::isAllowedKey(key) == true) { - return true; - } - - bool result = ( - key != SDLK_DELETE && - key != SDLK_BACKSPACE && - key != SDLK_TAB && - key != SDLK_CLEAR && - key != SDLK_RETURN && - key != SDLK_PAUSE && - key != SDLK_UP && - key != SDLK_DOWN && - key != SDLK_RIGHT && - key != SDLK_LEFT && - key != SDLK_INSERT && - key != SDLK_HOME && - key != SDLK_END && - key != SDLK_PAGEUP && - key != SDLK_PAGEDOWN && - key != SDLK_F1 && - key != SDLK_F2 && - key != SDLK_F3 && - key != SDLK_F4 && - key != SDLK_F5 && - key != SDLK_F6 && - key != SDLK_F7 && - key != SDLK_F8 && - key != SDLK_F9 && - key != SDLK_F10 && - key != SDLK_F11 && - key != SDLK_F12 && - key != SDLK_F13 && - key != SDLK_F14 && - key != SDLK_F15 && - key != SDLK_NUMLOCKCLEAR && - key != SDLK_CAPSLOCK && - key != SDLK_SCROLLLOCK && - key != SDLK_RSHIFT && - key != SDLK_LSHIFT && - key != SDLK_RCTRL && - key != SDLK_LCTRL && - key != SDLK_RALT && - key != SDLK_LALT && - key != SDLK_RGUI && - key != SDLK_LGUI && - key != SDLK_MODE && - key != SDLK_HELP && - key != SDLK_PRINTSCREEN && - key != SDLK_SYSREQ && - key != SDLK_MENU && - key != SDLK_POWER); - - string inputKeyName = SDL_GetKeyName(key); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] pressed key [%d - %s] result = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,key,inputKeyName.c_str(),result); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] pressed key [%d - %s] result = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,key,inputKeyName.c_str(),result); - - return result; -} - -bool Window::isKeyStateModPressed(int mod) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("isKeyStateModPressed mod = %d, keystate.mod = %d, keystate.mod & mod = %d\n",mod,keystate.mod,(keystate.mod & mod)); - - if(keystate.mod & mod) { - return true; - } - return false; -} - -wchar_t Window::extractLastKeyPressed() { - return keystate.sym; -} - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/platform/sdl/window_gl.cpp b/source/shared_lib/sources/platform/sdl/window_gl.cpp index 31abfafdf..7c7b93a77 100644 --- a/source/shared_lib/sources/platform/sdl/window_gl.cpp +++ b/source/shared_lib/sources/platform/sdl/window_gl.cpp @@ -25,195 +25,195 @@ using namespace Shared::Graphics; using namespace Shared::Util; -namespace Shared{ namespace Platform{ +namespace Shared { + namespace Platform { -// ===================================================== -// class WindowGl -// ===================================================== + // ===================================================== + // class WindowGl + // ===================================================== -WindowGl::WindowGl() : Window() { -} -WindowGl::WindowGl(SDL_Window *sdlWindow) : Window(sdlWindow) { -} -WindowGl::~WindowGl() { -} + WindowGl::WindowGl() : Window() { + } + WindowGl::WindowGl(SDL_Window *sdlWindow) : Window(sdlWindow) { + } + WindowGl::~WindowGl() { + } -int WindowGl::getScreenWidth() { - return PlatformCommon::Private::ScreenWidth; + int WindowGl::getScreenWidth() { + return PlatformCommon::Private::ScreenWidth; -} -int WindowGl::getScreenHeight() { - return PlatformCommon::Private::ScreenHeight; -} + } + int WindowGl::getScreenHeight() { + return PlatformCommon::Private::ScreenHeight; + } -void WindowGl::setGamma(SDL_Window *window,float gammaValue) { - //SDL_SetGamma(gammaValue, gammaValue, gammaValue); - //SDL_SetWindowGammaRamp(getSDLWindow(), gammaValue, gammaValue, gammaValue); - gammaValue = clamp(gammaValue, 0.1f, 10.0f); + void WindowGl::setGamma(SDL_Window *window, float gammaValue) { + //SDL_SetGamma(gammaValue, gammaValue, gammaValue); + //SDL_SetWindowGammaRamp(getSDLWindow(), gammaValue, gammaValue, gammaValue); + gammaValue = clamp(gammaValue, 0.1f, 10.0f); - Uint16 red_ramp[256]; - Uint16 green_ramp[256]; - Uint16 blue_ramp[256]; + Uint16 red_ramp[256]; + Uint16 green_ramp[256]; + Uint16 blue_ramp[256]; - SDL_CalculateGammaRamp(gammaValue, red_ramp); - SDL_memcpy(green_ramp, red_ramp, sizeof(red_ramp)); - SDL_memcpy(blue_ramp, red_ramp, sizeof(red_ramp)); + SDL_CalculateGammaRamp(gammaValue, red_ramp); + SDL_memcpy(green_ramp, red_ramp, sizeof(red_ramp)); + SDL_memcpy(blue_ramp, red_ramp, sizeof(red_ramp)); - SDL_SetWindowGammaRamp(window, red_ramp, green_ramp, blue_ramp); -} -void WindowGl::setGamma(float gammaValue) { - context.setGammaValue(gammaValue); - WindowGl::setGamma(getSDLWindow(),gammaValue); -} + SDL_SetWindowGammaRamp(window, red_ramp, green_ramp, blue_ramp); + } + void WindowGl::setGamma(float gammaValue) { + context.setGammaValue(gammaValue); + WindowGl::setGamma(getSDLWindow(), gammaValue); + } -SDL_Window * WindowGl::getScreenWindow() { - return context.getPlatformContextGlPtr()->getScreenWindow(); -} -SDL_Surface * WindowGl::getScreenSurface() { - return context.getPlatformContextGlPtr()->getScreenSurface(); -} + SDL_Window * WindowGl::getScreenWindow() { + return context.getPlatformContextGlPtr()->getScreenWindow(); + } + SDL_Surface * WindowGl::getScreenSurface() { + return context.getPlatformContextGlPtr()->getScreenSurface(); + } -void WindowGl::initGl(int colorBits, int depthBits, int stencilBits, - bool hardware_acceleration, bool fullscreen_anti_aliasing, - float gammaValue) { - context.setColorBits(colorBits); - context.setDepthBits(depthBits); - context.setStencilBits(stencilBits); - context.setHardware_acceleration(hardware_acceleration); - context.setFullscreen_anti_aliasing(fullscreen_anti_aliasing); - context.setGammaValue(gammaValue); - - context.init(); - setSDLWindow(context.getPlatformContextGlPtr()->getScreenWindow()); -} + void WindowGl::initGl(int colorBits, int depthBits, int stencilBits, + bool hardware_acceleration, bool fullscreen_anti_aliasing, + float gammaValue) { + context.setColorBits(colorBits); + context.setDepthBits(depthBits); + context.setStencilBits(stencilBits); + context.setHardware_acceleration(hardware_acceleration); + context.setFullscreen_anti_aliasing(fullscreen_anti_aliasing); + context.setGammaValue(gammaValue); -void WindowGl::makeCurrentGl() { - GraphicsInterface::getInstance().setCurrentContext(&context); - context.makeCurrent(); -} + context.init(); + setSDLWindow(context.getPlatformContextGlPtr()->getScreenWindow()); + } -void WindowGl::swapBuffersGl(){ - context.swapBuffers(); -} + void WindowGl::makeCurrentGl() { + GraphicsInterface::getInstance().setCurrentContext(&context); + context.makeCurrent(); + } -void WindowGl::eventToggleFullScreen(bool isFullscreen) { - Window::eventToggleFullScreen(isFullscreen); + void WindowGl::swapBuffersGl() { + context.swapBuffers(); + } - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { - //SDL_Surface *cur_surface = SDL_GetVideoSurface(); - if(getScreenWindow() != NULL) { - if(getIsFullScreen()){ - SDL_SetWindowFullscreen(getScreenWindow(),SDL_WINDOW_FULLSCREEN_DESKTOP); - } - else { - SDL_SetWindowFullscreen(getScreenWindow(),0); + void WindowGl::eventToggleFullScreen(bool isFullscreen) { + Window::eventToggleFullScreen(isFullscreen); + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == false) { + //SDL_Surface *cur_surface = SDL_GetVideoSurface(); + if (getScreenWindow() != NULL) { + if (getIsFullScreen()) { + SDL_SetWindowFullscreen(getScreenWindow(), SDL_WINDOW_FULLSCREEN_DESKTOP); + } else { + SDL_SetWindowFullscreen(getScreenWindow(), 0); + } + } + + if (isFullscreen) { + changeVideoModeFullScreen(isFullscreen); + ChangeVideoMode(true, getScreenWidth(), getScreenHeight(), + true, context.getColorBits(), context.getDepthBits(), context.getStencilBits(), + context.getHardware_acceleration(), context.getFullscreen_anti_aliasing(), + context.getGammaValue()); + + } else { + changeVideoModeFullScreen(false); + ChangeVideoMode(true, getDesiredScreenWidth(), getDesiredScreenHeight(), + false, context.getColorBits(), context.getDepthBits(), context.getStencilBits(), + context.getHardware_acceleration(), context.getFullscreen_anti_aliasing(), + context.getGammaValue()); + } } } - if(isFullscreen) { - changeVideoModeFullScreen(isFullscreen); - ChangeVideoMode(true, getScreenWidth(), getScreenHeight(), - true,context.getColorBits(), context.getDepthBits(), context.getStencilBits(), - context.getHardware_acceleration(),context.getFullscreen_anti_aliasing(), - context.getGammaValue()); - - } - else { - changeVideoModeFullScreen(false); - ChangeVideoMode(true, getDesiredScreenWidth(), getDesiredScreenHeight(), - false,context.getColorBits(), context.getDepthBits(), context.getStencilBits(), - context.getHardware_acceleration(),context.getFullscreen_anti_aliasing(), - context.getGammaValue()); - } - } -} - -// changes display resolution at any time -bool WindowGl::ChangeVideoMode(bool preserveContext, int resWidth, int resHeight, - bool fullscreenWindow, - int colorBits, int depthBits, int stencilBits, bool hardware_acceleration, - bool fullscreen_anti_aliasing, float gammaValue) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d] preserveContext = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,preserveContext); + // changes display resolution at any time + bool WindowGl::ChangeVideoMode(bool preserveContext, int resWidth, int resHeight, + bool fullscreenWindow, + int colorBits, int depthBits, int stencilBits, bool hardware_acceleration, + bool fullscreen_anti_aliasing, float gammaValue) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s %d] preserveContext = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, preserveContext); #ifdef WIN32 - SDL_SysWMinfo info; - HDC tempDC = 0; - HGLRC tempRC = 0; + SDL_SysWMinfo info; + HDC tempDC = 0; + HGLRC tempRC = 0; - if(preserveContext == true) { - // get window handle from SDL - SDL_VERSION(&info.version); - if (SDL_GetWindowWMInfo(Window::getSDLWindow(),&info) == -1) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s %d] SDL_GetWMInfo #1 failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return false; - } + if (preserveContext == true) { + // get window handle from SDL + SDL_VERSION(&info.version); + if (SDL_GetWindowWMInfo(Window::getSDLWindow(), &info) == -1) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s %d] SDL_GetWMInfo #1 failed\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + return false; + } - // get device context handle - tempDC = GetDC( info.info.win.window ); + // get device context handle + tempDC = GetDC(info.info.win.window); - // create temporary context - tempRC = wglCreateContext( tempDC ); - if (tempRC == NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s %d] wglCreateContext failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return false; - } + // create temporary context + tempRC = wglCreateContext(tempDC); + if (tempRC == NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s %d] wglCreateContext failed\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + return false; + } - // share resources to temporary context - SetLastError(0); - //if (!wglShareLists(info.info.win.hglrc, tempRC)) { - // if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s %d] wglShareLists #1 failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - // return false; - //} - } + // share resources to temporary context + SetLastError(0); + //if (!wglShareLists(info.info.win.hglrc, tempRC)) { + // if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s %d] wglShareLists #1 failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // return false; + //} + } #endif - // set video mode - //if (!SetVideoMode()) - // return false; -// this->initGl(config.getInt("ColorBits"), -// config.getInt("DepthBits"), -// config.getInt("StencilBits"), -// config.getBool("HardwareAcceleration","false"), -// config.getBool("FullScreenAntiAliasing","false"), -// config.getFloat("GammaValue","0.0")); + // set video mode + //if (!SetVideoMode()) + // return false; + // this->initGl(config.getInt("ColorBits"), + // config.getInt("DepthBits"), + // config.getInt("StencilBits"), + // config.getBool("HardwareAcceleration","false"), + // config.getBool("FullScreenAntiAliasing","false"), + // config.getFloat("GammaValue","0.0")); - this->setStyle(fullscreenWindow ? wsWindowedFixed: wsFullscreen); - this->setPos(0, 0); - this->setSize(resWidth, resHeight); + this->setStyle(fullscreenWindow ? wsWindowedFixed : wsFullscreen); + this->setPos(0, 0); + this->setSize(resWidth, resHeight); - this->initGl(colorBits, depthBits, stencilBits,hardware_acceleration, - fullscreen_anti_aliasing,gammaValue); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + this->initGl(colorBits, depthBits, stencilBits, hardware_acceleration, + fullscreen_anti_aliasing, gammaValue); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - this->makeCurrentGl(); + this->makeCurrentGl(); #ifdef WIN32 - if(preserveContext == true) { - // previously used structure may possibly be invalid, to be sure we get it again - SDL_VERSION(&info.version); - if (SDL_GetWindowWMInfo(Window::getSDLWindow(),&info) == -1) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s %d] SDL_GetWMInfo #2 failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return false; - } + if (preserveContext == true) { + // previously used structure may possibly be invalid, to be sure we get it again + SDL_VERSION(&info.version); + if (SDL_GetWindowWMInfo(Window::getSDLWindow(), &info) == -1) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s %d] SDL_GetWMInfo #2 failed\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + return false; + } - // share resources to new SDL-created context - //if (!wglShareLists(tempRC, info.hglrc)) { - // if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s %d] wglShareLists #2 failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - // return false; - //} + // share resources to new SDL-created context + //if (!wglShareLists(tempRC, info.hglrc)) { + // if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s %d] wglShareLists #2 failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // return false; + //} - // we no longer need our temporary context - if (!wglDeleteContext(tempRC)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s %d] wglDeleteContext failed\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return false; - } - } + // we no longer need our temporary context + if (!wglDeleteContext(tempRC)) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugError).enabled) SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s %d] wglDeleteContext failed\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + return false; + } + } #endif - // success - return true; -} + // success + return true; + } -}}//end namespace + } +}//end namespace diff --git a/source/shared_lib/sources/platform/win32/factory_repository.cpp b/source/shared_lib/sources/platform/win32/factory_repository.cpp index e650d474a..0baabe954 100644 --- a/source/shared_lib/sources/platform/win32/factory_repository.cpp +++ b/source/shared_lib/sources/platform/win32/factory_repository.cpp @@ -13,34 +13,35 @@ #include "leak_dumper.h" -namespace Shared{ namespace Platform{ +namespace Shared { + namespace Platform { -// ===================================================== -// class FactoryRepository -// ===================================================== + // ===================================================== + // class FactoryRepository + // ===================================================== -FactoryRepository &FactoryRepository::getInstance(){ - static FactoryRepository factoryRepository; - return factoryRepository; -} + FactoryRepository &FactoryRepository::getInstance() { + static FactoryRepository factoryRepository; + return factoryRepository; + } + + GraphicsFactory *FactoryRepository::getGraphicsFactory(const string &name) { + if (name == "OpenGL") { + return &graphicsFactoryGl; + } + + throw megaglest_runtime_error("Unknown graphics factory: [" + name + "]"); + } + + SoundFactory *FactoryRepository::getSoundFactory(const string &name) { + if (name == "OpenAL") { + return &soundFactoryOpenAL; + } else if (name == "" || name == "None") { + return &soundFactoryNone; + } + + throw megaglest_runtime_error("Unknown sound factory: [" + name + "]"); + } -GraphicsFactory *FactoryRepository::getGraphicsFactory(const string &name){ - if(name == "OpenGL"){ - return &graphicsFactoryGl; } - - throw megaglest_runtime_error("Unknown graphics factory: [" + name + "]"); -} - -SoundFactory *FactoryRepository::getSoundFactory(const string &name){ - if(name == "OpenAL") { - return &soundFactoryOpenAL; - } - else if(name == "" || name == "None") { - return &soundFactoryNone; - } - - throw megaglest_runtime_error("Unknown sound factory: [" + name + "]"); -} - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/platform/win32/gl_wrap_billy.cpp b/source/shared_lib/sources/platform/win32/gl_wrap_billy.cpp index 4e1b0eeb5..ca2170f2c 100644 --- a/source/shared_lib/sources/platform/win32/gl_wrap_billy.cpp +++ b/source/shared_lib/sources/platform/win32/gl_wrap_billy.cpp @@ -25,164 +25,164 @@ using namespace Shared::Graphics::Gl; using namespace Shared::Util; -namespace Shared{ namespace Platform{ +namespace Shared { + namespace Platform { -// Example values: -// DEFAULT_CHARSET (English) = 1 -// GB2312_CHARSET (Chinese) = 134 -//#ifdef WIN32 -//DWORD PlatformContextGl::charSet = DEFAULT_CHARSET; -//#else -//int PlatformContextGl::charSet = 1; -//#endif + // Example values: + // DEFAULT_CHARSET (English) = 1 + // GB2312_CHARSET (Chinese) = 134 + //#ifdef WIN32 + //DWORD PlatformContextGl::charSet = DEFAULT_CHARSET; + //#else + //int PlatformContextGl::charSet = 1; + //#endif -// ====================================== -// Global Fcs -// ====================================== + // ====================================== + // Global Fcs + // ====================================== -int CALLBACK EnumFontFamExProc(ENUMLOGFONTEX *lpelfe, - NEWTEXTMETRICEX *lpntme, - int FontType, - LPARAM lParam) { - std::vector *systemFontList = (std::vector *)lParam; - systemFontList->push_back((char *)lpelfe->elfFullName); - return 1; // I want to get all fonts -} - -void createGlFontBitmaps(uint32 &base, const string &type, int size, int width, - int charCount, FontMetrics &metrics) { - //return; - - // -adecw-screen-medium-r-normal--18-180-75-75-m-160-gb2312.1980-1 this is a Chinese font - - std::string useRealFontName = type; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] trying to load useRealFontName [%s], size = %d, width = %d\n",__FILE__,__FUNCTION__,__LINE__,useRealFontName.c_str(),size,width); - - DWORD dwErrorGL = 0; - HDC hDC = 0; - static std::vector systemFontList; - if(systemFontList.empty() == true) { - LOGFONT lf; - //POSITION pos; - //lf.lfCharSet = ANSI_CHARSET; - lf.lfCharSet = (BYTE)PlatformContextGl::charSet; - lf.lfFaceName[0]='\0'; - - //HGLRC hdRC =wglGetCurrentContext(); - //DWORD dwErrorGL = GetLastError(); - //assertGl(); - - hDC = wglGetCurrentDC(); - dwErrorGL = GetLastError(); - assertGl(); - //hDC = CreateCompatibleDC(0); - //dwErrorGL = GetLastError(); - - ::EnumFontFamiliesEx(hDC, - &lf, - (FONTENUMPROC) EnumFontFamExProc, - (LPARAM) &systemFontList, 0); - - for(unsigned int idx = 0; idx < systemFontList.size(); ++idx) { - string &fontName = systemFontList[idx]; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] found system font [%s]\n",__FILE__,__FUNCTION__,__LINE__,fontName.c_str()); + int CALLBACK EnumFontFamExProc(ENUMLOGFONTEX *lpelfe, + NEWTEXTMETRICEX *lpntme, + int FontType, + LPARAM lParam) { + std::vector *systemFontList = (std::vector *)lParam; + systemFontList->push_back((char *) lpelfe->elfFullName); + return 1; // I want to get all fonts } - } - else { - for(unsigned int idx = 0; idx < systemFontList.size(); ++idx) { - string &fontName = systemFontList[idx]; - - if(_stricmp(useRealFontName.c_str(),fontName.c_str()) != 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] switch font name from [%s] to [%s]\n",__FILE__,__FUNCTION__,__LINE__,useRealFontName.c_str(),fontName.c_str()); - - useRealFontName = fontName; - break; + + void createGlFontBitmaps(uint32 &base, const string &type, int size, int width, + int charCount, FontMetrics &metrics) { + //return; + + // -adecw-screen-medium-r-normal--18-180-75-75-m-160-gb2312.1980-1 this is a Chinese font + + std::string useRealFontName = type; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] trying to load useRealFontName [%s], size = %d, width = %d\n", __FILE__, __FUNCTION__, __LINE__, useRealFontName.c_str(), size, width); + + DWORD dwErrorGL = 0; + HDC hDC = 0; + static std::vector systemFontList; + if (systemFontList.empty() == true) { + LOGFONT lf; + //POSITION pos; + //lf.lfCharSet = ANSI_CHARSET; + lf.lfCharSet = (BYTE) PlatformContextGl::charSet; + lf.lfFaceName[0] = '\0'; + + //HGLRC hdRC =wglGetCurrentContext(); + //DWORD dwErrorGL = GetLastError(); + //assertGl(); + + hDC = wglGetCurrentDC(); + dwErrorGL = GetLastError(); + assertGl(); + //hDC = CreateCompatibleDC(0); + //dwErrorGL = GetLastError(); + + ::EnumFontFamiliesEx(hDC, + &lf, + (FONTENUMPROC) EnumFontFamExProc, + (LPARAM) &systemFontList, 0); + + for (unsigned int idx = 0; idx < systemFontList.size(); ++idx) { + string &fontName = systemFontList[idx]; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] found system font [%s]\n", __FILE__, __FUNCTION__, __LINE__, fontName.c_str()); + } + } else { + for (unsigned int idx = 0; idx < systemFontList.size(); ++idx) { + string &fontName = systemFontList[idx]; + + if (_stricmp(useRealFontName.c_str(), fontName.c_str()) != 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] switch font name from [%s] to [%s]\n", __FILE__, __FUNCTION__, __LINE__, useRealFontName.c_str(), fontName.c_str()); + + useRealFontName = fontName; + break; + } + } } + + LPWSTR wstr = Ansi2WideString(useRealFontName.c_str()); + HFONT font = CreateFont( + size, 0, 0, 0, width, FALSE, FALSE, FALSE, PlatformContextGl::charSet, + OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, + DEFAULT_PITCH | (useRealFontName.c_str() ? FF_DONTCARE : FF_SWISS), wstr); + if (wstr) delete[] wstr; + assert(font != NULL); + + HDC dc = wglGetCurrentDC(); + dwErrorGL = GetLastError(); + assertGl(); + + SelectObject(dc, font); + dwErrorGL = GetLastError(); + assertGl(); + + BOOL err = wglUseFontBitmaps(dc, 0, charCount, base); + dwErrorGL = GetLastError(); + + /* + for(int glBugRetry = 0; glBugRetry <= 10; glBugRetry++) { + err= wglUseFontBitmaps(dc, 0, charCount, base); + dwErrorGL = GetLastError(); + //assertGl(); + GLenum error = glGetError(); + if(error == 0) { + break; + } + } + */ + assertGl(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] wglUseFontBitmaps returned = %d, charCount = %d, base = %d\n", __FILE__, __FUNCTION__, __LINE__, err, charCount, base); + + FIXED one; + one.value = 1; + one.fract = 0; + + FIXED zero; + zero.value = 0; + zero.fract = 0; + + MAT2 mat2; + mat2.eM11 = one; + mat2.eM12 = zero; + mat2.eM21 = zero; + mat2.eM22 = one; + + //MAT2 mat2 = {{0,1},{0,0},{0,0},{0,1}}; + + + //metrics + GLYPHMETRICS glyphMetrics; + int errorCode = GetGlyphOutline(dc, 'a', GGO_METRICS, &glyphMetrics, 0, NULL, &mat2); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] GetGlyphOutline returned = %d\n", __FILE__, __FUNCTION__, __LINE__, errorCode); + + if (errorCode != GDI_ERROR) { + metrics.setHeight(static_cast(glyphMetrics.gmBlackBoxY)); + } + for (int i = 0; i < charCount; ++i) { + int errorCode = GetGlyphOutline(dc, i, GGO_METRICS, &glyphMetrics, 0, NULL, &mat2); + if (errorCode != GDI_ERROR) { + metrics.setWidth(i, static_cast(glyphMetrics.gmCellIncX)); + } else { + metrics.setWidth(i, static_cast(6)); + } + } + + DeleteObject(font); + + //if(hDC != 0) { + // DeleteDC(hDC); + //} + + assert(err); } - } - LPWSTR wstr = Ansi2WideString(useRealFontName.c_str()); - HFONT font= CreateFont( - size, 0, 0, 0, width, FALSE, FALSE, FALSE, PlatformContextGl::charSet, - OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, - DEFAULT_PITCH| (useRealFontName.c_str() ? FF_DONTCARE:FF_SWISS), wstr); - if(wstr) delete [] wstr; - assert(font!=NULL); - - HDC dc= wglGetCurrentDC(); - dwErrorGL = GetLastError(); - assertGl(); - - SelectObject(dc, font); - dwErrorGL = GetLastError(); - assertGl(); - - BOOL err= wglUseFontBitmaps(dc, 0, charCount, base); - dwErrorGL = GetLastError(); - -/* - for(int glBugRetry = 0; glBugRetry <= 10; glBugRetry++) { - err= wglUseFontBitmaps(dc, 0, charCount, base); - dwErrorGL = GetLastError(); - //assertGl(); - GLenum error = glGetError(); - if(error == 0) { - break; + void createGlFontOutlines(uint32 &base, const string &type, int width, + float depth, int charCount, FontMetrics &metrics) { + NOIMPL; } + } -*/ - assertGl(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] wglUseFontBitmaps returned = %d, charCount = %d, base = %d\n",__FILE__,__FUNCTION__,__LINE__,err,charCount,base); - - FIXED one; - one.value= 1; - one.fract= 0; - - FIXED zero; - zero.value= 0; - zero.fract= 0; - - MAT2 mat2; - mat2.eM11= one; - mat2.eM12= zero; - mat2.eM21= zero; - mat2.eM22= one; - - //MAT2 mat2 = {{0,1},{0,0},{0,0},{0,1}}; - - - //metrics - GLYPHMETRICS glyphMetrics; - int errorCode= GetGlyphOutline(dc, 'a', GGO_METRICS, &glyphMetrics, 0, NULL, &mat2); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] GetGlyphOutline returned = %d\n",__FILE__,__FUNCTION__,__LINE__,errorCode); - - if(errorCode!=GDI_ERROR){ - metrics.setHeight(static_cast(glyphMetrics.gmBlackBoxY)); - } - for(int i=0; i(glyphMetrics.gmCellIncX)); - } - else { - metrics.setWidth(i, static_cast(6)); - } - } - - DeleteObject(font); - - //if(hDC != 0) { - // DeleteDC(hDC); - //} - - assert(err); -} - -void createGlFontOutlines(uint32 &base, const string &type, int width, - float depth, int charCount, FontMetrics &metrics) { - NOIMPL; -} - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/platform/win32/glob.cpp b/source/shared_lib/sources/platform/win32/glob.cpp index 7e4525f81..80e7bbf50 100644 --- a/source/shared_lib/sources/platform/win32/glob.cpp +++ b/source/shared_lib/sources/platform/win32/glob.cpp @@ -11,11 +11,11 @@ * Copyright (c) 2002-2010, Matthew Wilson and Synesis Software * All rights reserved. * - * Redistribution and use in source and binary forms, with or without + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. + * list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. @@ -37,9 +37,9 @@ * * ////////////////////////////////////////////////////////////////////// */ -/* ///////////////////////////////////////////////////////////////////////// - * Includes - */ + /* ///////////////////////////////////////////////////////////////////////// + * Includes + */ #include #include @@ -56,418 +56,354 @@ using namespace Shared::Util; * Helper functions */ -static char const *strrpbrk(char const *string, char const *strCharSet) -{ - char const *part = NULL; - char const *pch; +static char const *strrpbrk(char const *string, char const *strCharSet) { + char const *part = NULL; + char const *pch; - for(pch = strCharSet; *pch; ++pch) - { - const char *p = strrchr(string, *pch); + for (pch = strCharSet; *pch; ++pch) { + const char *p = strrchr(string, *pch); - if(NULL != p) - { - if(NULL == part) - { - part = p; - } - else - { - if(part < p) - { - part = p; - } - } - } - } + if (NULL != p) { + if (NULL == part) { + part = p; + } else { + if (part < p) { + part = p; + } + } + } + } - return part; + return part; } /* ///////////////////////////////////////////////////////////////////////// * API functions */ -/* It gives you back the matched contents of your pattern, so for Win32, the - * directories must be included - */ + /* It gives you back the matched contents of your pattern, so for Win32, the + * directories must be included + */ -int glob( char const *pattern - , int flags +int glob(char const *pattern + , int flags #if defined(__COMO__) - , int (*errfunc)(char const *, int) + , int(*errfunc)(char const *, int) #else /* ? compiler */ - , const int (*errfunc)(char const *, int) + , const int(*errfunc)(char const *, int) #endif /* compiler */ - , glob_t *pglob) -{ - int result; - char szRelative[1 + _MAX_PATH]; - char const *file_part; - WIN32_FIND_DATAW find_data; - HANDLE hFind; - char *buffer; - char szPattern2[1 + _MAX_PATH]; - char szPattern3[1 + _MAX_PATH]; - char const *effectivePattern = pattern; - char const *leafMost; - const int bMagic = (NULL != strpbrk(pattern, "?*")); - int bNoMagic = 0; - int bMagic0; - size_t maxMatches = ~(size_t)(0); + , glob_t *pglob) { + int result; + char szRelative[1 + _MAX_PATH]; + char const *file_part; + WIN32_FIND_DATAW find_data; + HANDLE hFind; + char *buffer; + char szPattern2[1 + _MAX_PATH]; + char szPattern3[1 + _MAX_PATH]; + char const *effectivePattern = pattern; + char const *leafMost; + const int bMagic = (NULL != strpbrk(pattern, "?*")); + int bNoMagic = 0; + int bMagic0; + size_t maxMatches = ~(size_t) (0); - assert(NULL != pglob); + assert(NULL != pglob); - if(flags & GLOB_NOMAGIC) - { - bNoMagic = !bMagic; - } + if (flags & GLOB_NOMAGIC) { + bNoMagic = !bMagic; + } - if(flags & GLOB_LIMIT) - { - maxMatches = (size_t)pglob->gl_matchc; - } + if (flags & GLOB_LIMIT) { + maxMatches = (size_t) pglob->gl_matchc; + } - if(flags & GLOB_TILDE) - { - /* Check that begins with "~/" */ - if( '~' == pattern[0] && - ( '\0' == pattern[1] || - '/' == pattern[1] || - '\\' == pattern[1])) - { - DWORD dw; + if (flags & GLOB_TILDE) { + /* Check that begins with "~/" */ + if ('~' == pattern[0] && + ('\0' == pattern[1] || + '/' == pattern[1] || + '\\' == pattern[1])) { + DWORD dw; - (void)lstrcpyA(&szPattern2[0], "%HOMEDRIVE%%HOMEPATH%"); + (void) lstrcpyA(&szPattern2[0], "%HOMEDRIVE%%HOMEPATH%"); - dw = ExpandEnvironmentStringsA(&szPattern2[0], &szPattern3[0], NUM_ELEMENTS(szPattern3) - 1); + dw = ExpandEnvironmentStringsA(&szPattern2[0], &szPattern3[0], NUM_ELEMENTS(szPattern3) - 1); - if(0 != dw) - { - (void)lstrcpynA(&szPattern3[0] + dw - 1, &pattern[1], (int)(NUM_ELEMENTS(szPattern3) - dw)); - szPattern3[NUM_ELEMENTS(szPattern3) - 1] = '\0'; + if (0 != dw) { + (void) lstrcpynA(&szPattern3[0] + dw - 1, &pattern[1], (int) (NUM_ELEMENTS(szPattern3) - dw)); + szPattern3[NUM_ELEMENTS(szPattern3) - 1] = '\0'; - effectivePattern = szPattern3; - } - } - } + effectivePattern = szPattern3; + } + } + } - file_part = strrpbrk(effectivePattern, "\\/"); + file_part = strrpbrk(effectivePattern, "\\/"); - if(NULL != file_part) - { - leafMost = ++file_part; + if (NULL != file_part) { + leafMost = ++file_part; - (void)lstrcpyA(szRelative, effectivePattern); - szRelative[file_part - effectivePattern] = '\0'; - } - else - { - szRelative[0] = '\0'; - leafMost = effectivePattern; - } + (void) lstrcpyA(szRelative, effectivePattern); + szRelative[file_part - effectivePattern] = '\0'; + } else { + szRelative[0] = '\0'; + leafMost = effectivePattern; + } - bMagic0 = (leafMost == strpbrk(leafMost, "?*")); + bMagic0 = (leafMost == strpbrk(leafMost, "?*")); std::wstring wstr = utf8_decode(effectivePattern); - hFind = FindFirstFileW(wstr.c_str(), &find_data); - buffer = NULL; + hFind = FindFirstFileW(wstr.c_str(), &find_data); + buffer = NULL; - pglob->gl_pathc = 0; - pglob->gl_pathv = NULL; + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; - if(0 == (flags & GLOB_DOOFFS)) - { - pglob->gl_offs = 0; - } + if (0 == (flags & GLOB_DOOFFS)) { + pglob->gl_offs = 0; + } - if(hFind == INVALID_HANDLE_VALUE) - { - /* If this was a pattern search, and the - * directory exists, then we return 0 - * matches, rather than GLOB_NOMATCH - */ - if( bMagic && - NULL != file_part) - { - result = 0; - } - else - { - if(NULL != errfunc) - { - (void)errfunc(effectivePattern, (int)GetLastError()); - } + if (hFind == INVALID_HANDLE_VALUE) { + /* If this was a pattern search, and the + * directory exists, then we return 0 + * matches, rather than GLOB_NOMATCH + */ + if (bMagic && + NULL != file_part) { + result = 0; + } else { + if (NULL != errfunc) { + (void) errfunc(effectivePattern, (int) GetLastError()); + } - result = GLOB_NOMATCH; - } - } - else - { - int cbCurr = 0; - size_t cbAlloc = 0; - size_t cMatches = 0; + result = GLOB_NOMATCH; + } + } else { + int cbCurr = 0; + size_t cbAlloc = 0; + size_t cMatches = 0; - result = 0; + result = 0; - do - { - int cch; - size_t new_cbAlloc; + do { + int cch; + size_t new_cbAlloc; - if( bMagic0 && - 0 == (flags & GLOB_PERIOD)) - { - if('.' == find_data.cFileName[0]) - { - continue; - } - } + if (bMagic0 && + 0 == (flags & GLOB_PERIOD)) { + if ('.' == find_data.cFileName[0]) { + continue; + } + } - if(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { + if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { #ifdef GLOB_ONLYFILE - if(flags & GLOB_ONLYFILE) - { - continue; - } + if (flags & GLOB_ONLYFILE) { + continue; + } #endif /* GLOB_ONLYFILE */ - if( bMagic0 && - GLOB_NODOTSDIRS == (flags & GLOB_NODOTSDIRS)) - { - /* Pattern must begin with '.' to match either dots directory */ - if( 0 == lstrcmpW(L".", find_data.cFileName) || - 0 == lstrcmpW(L"..", find_data.cFileName)) - { - continue; - } - } + if (bMagic0 && + GLOB_NODOTSDIRS == (flags & GLOB_NODOTSDIRS)) { + /* Pattern must begin with '.' to match either dots directory */ + if (0 == lstrcmpW(L".", find_data.cFileName) || + 0 == lstrcmpW(L"..", find_data.cFileName)) { + continue; + } + } - if(flags & GLOB_MARK) - { + if (flags & GLOB_MARK) { #if 0 - if(find_data.cFileName[0] >= 'A' && find_data.cFileName[0] <= 'M') + if (find_data.cFileName[0] >= 'A' && find_data.cFileName[0] <= 'M') #endif /* 0 */ - (void)lstrcatW(find_data.cFileName, L"/"); - } - } - else - { - if(flags & GLOB_ONLYDIR) - { - /* Skip all further actions, and get the next entry */ + (void) lstrcatW(find_data.cFileName, L"/"); + } + } else { + if (flags & GLOB_ONLYDIR) { + /* Skip all further actions, and get the next entry */ #if 0 - if(find_data.cFileName[0] >= 'A' && find_data.cFileName[0] <= 'M') + if (find_data.cFileName[0] >= 'A' && find_data.cFileName[0] <= 'M') #endif /* 0 */ - continue; - } - } + continue; + } + } - //cch = lstrlenW(find_data.cFileName); + //cch = lstrlenW(find_data.cFileName); string sFileName = utf8_encode(find_data.cFileName); - cch = (int)sFileName.length(); - if(NULL != file_part) - { - cch += (int)(file_part - effectivePattern); - } + cch = (int) sFileName.length(); + if (NULL != file_part) { + cch += (int) (file_part - effectivePattern); + } - new_cbAlloc = (size_t)cbCurr + cch + 1; - if(new_cbAlloc > cbAlloc) - { - char *new_buffer; + new_cbAlloc = (size_t) cbCurr + cch + 1; + if (new_cbAlloc > cbAlloc) { + char *new_buffer; - new_cbAlloc *= 2; + new_cbAlloc *= 2; - new_cbAlloc = (new_cbAlloc + 31) & ~(31); + new_cbAlloc = (new_cbAlloc + 31) & ~(31); - new_buffer = (char*)realloc(buffer, new_cbAlloc); + new_buffer = (char*) realloc(buffer, new_cbAlloc); - if(new_buffer == NULL) - { - result = GLOB_NOSPACE; - if(buffer) { - free(buffer); - buffer = NULL; - } - break; - } + if (new_buffer == NULL) { + result = GLOB_NOSPACE; + if (buffer) { + free(buffer); + buffer = NULL; + } + break; + } - buffer = new_buffer; - cbAlloc = new_cbAlloc; - } + buffer = new_buffer; + cbAlloc = new_cbAlloc; + } - if(buffer == NULL) { + if (buffer == NULL) { throw exception("buffer == NULL"); } - (void)lstrcpynA(buffer + cbCurr, szRelative, 1 + (int)(file_part - effectivePattern)); - (void)lstrcatA(buffer + cbCurr, sFileName.c_str()); - cbCurr += cch + 1; + (void) lstrcpynA(buffer + cbCurr, szRelative, 1 + (int) (file_part - effectivePattern)); + (void) lstrcatA(buffer + cbCurr, sFileName.c_str()); + cbCurr += cch + 1; - ++cMatches; - } - //while(FindNextFileA(hFind, &find_data) && cMatches != maxMatches); - while(FindNextFileW(hFind, &find_data) && cMatches != maxMatches); + ++cMatches; + } + //while(FindNextFileA(hFind, &find_data) && cMatches != maxMatches); + while (FindNextFileW(hFind, &find_data) && cMatches != maxMatches); - (void)FindClose(hFind); + (void) FindClose(hFind); - if(result == 0) - { - /* Now expand the buffer, to fit in all the pointers. */ - size_t cbPointers = (1 + cMatches + pglob->gl_offs) * sizeof(char*); - char *new_buffer = (char*)realloc(buffer, cbAlloc + cbPointers); + if (result == 0) { + /* Now expand the buffer, to fit in all the pointers. */ + size_t cbPointers = (1 + cMatches + pglob->gl_offs) * sizeof(char*); + char *new_buffer = (char*) realloc(buffer, cbAlloc + cbPointers); - if(new_buffer == NULL) - { - result = GLOB_NOSPACE; - if(buffer) { - free(buffer); - buffer = NULL; - } - } - else - { - char **pp; - char **begin; - char **end; - char *next_str; + if (new_buffer == NULL) { + result = GLOB_NOSPACE; + if (buffer) { + free(buffer); + buffer = NULL; + } + } else { + char **pp; + char **begin; + char **end; + char *next_str; - buffer = new_buffer; + buffer = new_buffer; - (void)memmove(new_buffer + cbPointers, new_buffer, cbAlloc); + (void) memmove(new_buffer + cbPointers, new_buffer, cbAlloc); - /* Handle the offsets. */ - begin = (char**)new_buffer; - end = begin + pglob->gl_offs; + /* Handle the offsets. */ + begin = (char**) new_buffer; + end = begin + pglob->gl_offs; - for(; begin != end; ++begin) - { - *begin = NULL; - } + for (; begin != end; ++begin) { + *begin = NULL; + } - /* Sort, or no sort. */ - pp = (char**)new_buffer + pglob->gl_offs; - begin = pp; - end = begin + cMatches; + /* Sort, or no sort. */ + pp = (char**) new_buffer + pglob->gl_offs; + begin = pp; + end = begin + cMatches; - if(flags & GLOB_NOSORT) - { - /* The way we need in order to test the removal of dots in the findfile_sequence. */ - *end = NULL; - for(begin = pp, next_str = buffer + cbPointers; begin != end; --end) - { - *(end - 1) = next_str; + if (flags & GLOB_NOSORT) { + /* The way we need in order to test the removal of dots in the findfile_sequence. */ + *end = NULL; + for (begin = pp, next_str = buffer + cbPointers; begin != end; --end) { + *(end - 1) = next_str; - /* Find the next string. */ - next_str += 1 + lstrlenA(next_str); - } - } - else - { - /* The normal way. */ - for(begin = pp, next_str = buffer + cbPointers; begin != end; ++begin) - { - *begin = next_str; + /* Find the next string. */ + next_str += 1 + lstrlenA(next_str); + } + } else { + /* The normal way. */ + for (begin = pp, next_str = buffer + cbPointers; begin != end; ++begin) { + *begin = next_str; - /* Find the next string. */ - next_str += 1 + lstrlenA(next_str); - } - *begin = NULL; - } + /* Find the next string. */ + next_str += 1 + lstrlenA(next_str); + } + *begin = NULL; + } - /* Return results to caller. */ - pglob->gl_pathc = (int)cMatches; - pglob->gl_matchc= (int)cMatches; - pglob->gl_flags = 0; - if(bMagic) - { - pglob->gl_flags |= GLOB_MAGCHAR; - } - pglob->gl_pathv = (char**)new_buffer; - } - } + /* Return results to caller. */ + pglob->gl_pathc = (int) cMatches; + pglob->gl_matchc = (int) cMatches; + pglob->gl_flags = 0; + if (bMagic) { + pglob->gl_flags |= GLOB_MAGCHAR; + } + pglob->gl_pathv = (char**) new_buffer; + } + } - if(0 == cMatches) - { - result = GLOB_NOMATCH; - } - } + if (0 == cMatches) { + result = GLOB_NOMATCH; + } + } - if(GLOB_NOMATCH == result) - { - if( (flags & GLOB_TILDE_CHECK) && - effectivePattern == szPattern3) - { - result = GLOB_NOMATCH; - } - else if(bNoMagic || - (flags & GLOB_NOCHECK)) - { - const size_t effPattLen = strlen(effectivePattern); - const size_t cbNeeded = ((2 + pglob->gl_offs) * sizeof(char*)) + (1 + effPattLen); - char **pp = (char**)realloc(buffer, cbNeeded); + if (GLOB_NOMATCH == result) { + if ((flags & GLOB_TILDE_CHECK) && + effectivePattern == szPattern3) { + result = GLOB_NOMATCH; + } else if (bNoMagic || + (flags & GLOB_NOCHECK)) { + const size_t effPattLen = strlen(effectivePattern); + const size_t cbNeeded = ((2 + pglob->gl_offs) * sizeof(char*)) + (1 + effPattLen); + char **pp = (char**) realloc(buffer, cbNeeded); - if(NULL == pp) - { - result = GLOB_NOSPACE; - if(buffer) { - free(buffer); - buffer = NULL; - } - } - else - { - /* Handle the offsets. */ - char** begin = pp; - char** end = pp + pglob->gl_offs; - char* dest = (char*)(pp + 2 + pglob->gl_offs); + if (NULL == pp) { + result = GLOB_NOSPACE; + if (buffer) { + free(buffer); + buffer = NULL; + } + } else { + /* Handle the offsets. */ + char** begin = pp; + char** end = pp + pglob->gl_offs; + char* dest = (char*) (pp + 2 + pglob->gl_offs); - for(; begin != end; ++begin) - { - *begin = NULL; - } + for (; begin != end; ++begin) { + *begin = NULL; + } - /* Synthesise the pattern result. */ + /* Synthesise the pattern result. */ #ifdef UNIXEM_USING_SAFE_STR_FUNCTIONS - pp[0 + pglob->gl_offs] = (strcpy_s(dest, effPattLen + 1, effectivePattern), dest); + pp[0 + pglob->gl_offs] = (strcpy_s(dest, effPattLen + 1, effectivePattern), dest); #else /* ? UNIXEM_USING_SAFE_STR_FUNCTIONS */ - pp[0 + pglob->gl_offs] = strcpy(dest, effectivePattern); + pp[0 + pglob->gl_offs] = strcpy(dest, effectivePattern); #endif /* UNIXEM_USING_SAFE_STR_FUNCTIONS */ - pp[1 + pglob->gl_offs] = NULL; + pp[1 + pglob->gl_offs] = NULL; - /* Return results to caller. */ - pglob->gl_pathc = 1; - pglob->gl_matchc= 1; - pglob->gl_flags = 0; - if(bMagic) - { - pglob->gl_flags |= GLOB_MAGCHAR; - } - pglob->gl_pathv = pp; + /* Return results to caller. */ + pglob->gl_pathc = 1; + pglob->gl_matchc = 1; + pglob->gl_flags = 0; + if (bMagic) { + pglob->gl_flags |= GLOB_MAGCHAR; + } + pglob->gl_pathv = pp; - result = 0; - } - } - } - else if(0 == result) - { - if((size_t)pglob->gl_matchc == maxMatches) - { - result = GLOB_NOSPACE; - } - } + result = 0; + } + } + } else if (0 == result) { + if ((size_t) pglob->gl_matchc == maxMatches) { + result = GLOB_NOSPACE; + } + } - return result; + return result; } -void globfree(glob_t *pglob) -{ - if(pglob != NULL) - { - free(pglob->gl_pathv); - pglob->gl_pathc = 0; - pglob->gl_pathv = NULL; - } +void globfree(glob_t *pglob) { + if (pglob != NULL) { + free(pglob->gl_pathv); + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + } } /* ///////////////////////////// end of file //////////////////////////// */ diff --git a/source/shared_lib/sources/platform/win32/platform_util.cpp b/source/shared_lib/sources/platform/win32/platform_util.cpp index 315562552..5d49a8847 100644 --- a/source/shared_lib/sources/platform/win32/platform_util.cpp +++ b/source/shared_lib/sources/platform/win32/platform_util.cpp @@ -26,459 +26,459 @@ using namespace Shared::Util; using namespace std; -namespace Shared { namespace Platform { +namespace Shared { + namespace Platform { -// ===================================================== -// class PlatformExceptionHandler -// ===================================================== -string PlatformExceptionHandler::application_binary=""; -bool PlatformExceptionHandler::disableBacktrace = false; -PlatformExceptionHandler *PlatformExceptionHandler::thisPointer= NULL; + // ===================================================== + // class PlatformExceptionHandler + // ===================================================== + string PlatformExceptionHandler::application_binary = ""; + bool PlatformExceptionHandler::disableBacktrace = false; + PlatformExceptionHandler *PlatformExceptionHandler::thisPointer = NULL; -// Constructs object and convert lpaszString to Unicode -LPWSTR Ansi2WideString(LPCSTR lpaszString) { - LPWSTR lpwszString(NULL); + // Constructs object and convert lpaszString to Unicode + LPWSTR Ansi2WideString(LPCSTR lpaszString) { + LPWSTR lpwszString(NULL); + + if (lpaszString != NULL) { + int nLen = ::lstrlenA(lpaszString) + 1; + lpwszString = new WCHAR[nLen]; + if (lpwszString == NULL) { + return lpwszString; + } + + memset(lpwszString, 0, nLen * sizeof(WCHAR)); + + if (::MultiByteToWideChar(CP_ACP, 0, lpaszString, nLen, lpwszString, nLen) == 0) { + // Conversation failed + return lpwszString; + } + } else { + int nLen = 1; + lpwszString = new WCHAR[nLen]; + if (lpwszString == NULL) { + return lpwszString; + } + + memset(lpwszString, 0, nLen * sizeof(WCHAR)); + } - if(lpaszString != NULL) { - int nLen = ::lstrlenA(lpaszString) + 1; - lpwszString = new WCHAR[nLen]; - if (lpwszString == NULL) { return lpwszString; } - memset(lpwszString, 0, nLen * sizeof(WCHAR)); + // Convert a wide Unicode string to an UTF8 string + std::string utf8_encode(const std::wstring &wstr) { + if (wstr.length() == 0) { + std::string wstrTo; + return wstrTo; + } - if (::MultiByteToWideChar(CP_ACP, 0, lpaszString, nLen, lpwszString, nLen) == 0) { - // Conversation failed - return lpwszString; - } - } - else { - int nLen = 1; - lpwszString = new WCHAR[nLen]; - if (lpwszString == NULL) { - return lpwszString; + int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int) wstr.size(), NULL, 0, NULL, NULL); + std::string strTo(size_needed, 0); + WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int) wstr.size(), &strTo[0], size_needed, NULL, NULL); + replaceAll(strTo, "/", "\\"); + replaceAll(strTo, "\\\\", "\\"); + updatePathClimbingParts(strTo); + return strTo; } - memset(lpwszString, 0, nLen * sizeof(WCHAR)); - } + // Convert an UTF8 string to a wide Unicode String + std::wstring utf8_decode(const std::string &str) { + if (str.length() == 0) { + std::wstring wstrTo; + return wstrTo; + } + string friendly_path = str; + replaceAll(friendly_path, "/", "\\"); + replaceAll(friendly_path, "\\\\", "\\"); + updatePathClimbingParts(friendly_path); + int size_needed = MultiByteToWideChar(CP_UTF8, 0, &friendly_path[0], (int) friendly_path.size(), NULL, 0); + std::wstring wstrTo(size_needed, 0); + MultiByteToWideChar(CP_UTF8, 0, &friendly_path[0], (int) friendly_path.size(), &wstrTo[0], size_needed); + return wstrTo; + } - return lpwszString; -} + /** + * @param location The location of the registry key. For example "Software\\Bethesda Softworks\\Morrowind" + * @param name the name of the registry key, for example "Installed Path" + * @return the value of the key or an empty string if an error occured. + */ + std::string getRegKey(const std::string& location, const std::string& name) { + HKEY key; + CHAR value[1024]; + DWORD bufLen = 1024 * sizeof(CHAR); + long ret; + ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, location.c_str(), 0, KEY_QUERY_VALUE, &key); + if (ret != ERROR_SUCCESS) { + return std::string(); + } + ret = RegQueryValueExA(key, name.c_str(), 0, 0, (LPBYTE) value, &bufLen); + RegCloseKey(key); + if ((ret != ERROR_SUCCESS) || (bufLen > 1024 * sizeof(TCHAR))) { + return std::string(); + } + string stringValue = value; + size_t i = stringValue.length(); + while (i > 0 && stringValue[i - 1] == '\0') { + --i; + } + return stringValue.substr(0, i); + } -// Convert a wide Unicode string to an UTF8 string -std::string utf8_encode(const std::wstring &wstr) { - if(wstr.length() == 0) { - std::string wstrTo; - return wstrTo; - } + LONG WINAPI PlatformExceptionHandler::handler(LPEXCEPTION_POINTERS pointers) { - int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL); - std::string strTo( size_needed, 0 ); - WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL); - replaceAll(strTo, "/", "\\"); - replaceAll(strTo, "\\\\", "\\"); - updatePathClimbingParts(strTo); - return strTo; -} + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -// Convert an UTF8 string to a wide Unicode String -std::wstring utf8_decode(const std::string &str) { - if(str.length() == 0) { - std::wstring wstrTo; - return wstrTo; - } - string friendly_path = str; - replaceAll(friendly_path, "/", "\\"); - replaceAll(friendly_path, "\\\\", "\\"); - updatePathClimbingParts(friendly_path); - int size_needed = MultiByteToWideChar(CP_UTF8, 0, &friendly_path[0], (int)friendly_path.size(), NULL, 0); - std::wstring wstrTo( size_needed, 0 ); - MultiByteToWideChar(CP_UTF8, 0, &friendly_path[0], (int)friendly_path.size(), &wstrTo[0], size_needed); - return wstrTo; -} + LPWSTR wstr = Ansi2WideString(thisPointer->dumpFileName.c_str()); + HANDLE hFile = CreateFile( + wstr, + GENERIC_WRITE, + FILE_SHARE_WRITE, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + 0); + if (wstr) delete[] wstr; -/** -* @param location The location of the registry key. For example "Software\\Bethesda Softworks\\Morrowind" -* @param name the name of the registry key, for example "Installed Path" -* @return the value of the key or an empty string if an error occured. -*/ -std::string getRegKey(const std::string& location, const std::string& name){ - HKEY key; - CHAR value[1024]; - DWORD bufLen = 1024*sizeof(CHAR); - long ret; - ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, location.c_str(), 0, KEY_QUERY_VALUE, &key); - if( ret != ERROR_SUCCESS ){ - return std::string(); - } - ret = RegQueryValueExA(key, name.c_str(), 0, 0, (LPBYTE) value, &bufLen); - RegCloseKey(key); - if ( (ret != ERROR_SUCCESS) || (bufLen > 1024*sizeof(TCHAR)) ){ - return std::string(); - } - string stringValue = value; - size_t i = stringValue.length(); - while( i > 0 && stringValue[i-1] == '\0' ){ - --i; - } - return stringValue.substr(0,i); -} + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); -LONG WINAPI PlatformExceptionHandler::handler(LPEXCEPTION_POINTERS pointers){ + MINIDUMP_EXCEPTION_INFORMATION lExceptionInformation; - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - LPWSTR wstr = Ansi2WideString(thisPointer->dumpFileName.c_str()); - HANDLE hFile = CreateFile( - wstr, - GENERIC_WRITE, - FILE_SHARE_WRITE, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - 0); - if(wstr) delete [] wstr; - - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - MINIDUMP_EXCEPTION_INFORMATION lExceptionInformation; - - lExceptionInformation.ThreadId= GetCurrentThreadId(); - lExceptionInformation.ExceptionPointers= pointers; - lExceptionInformation.ClientPointers= false; + lExceptionInformation.ThreadId = GetCurrentThreadId(); + lExceptionInformation.ExceptionPointers = pointers; + lExceptionInformation.ClientPointers = false; #if !defined(__GNUC__) - MiniDumpWriteDump( - GetCurrentProcess(), - GetCurrentProcessId(), - hFile, - MiniDumpNormal, - &lExceptionInformation, - NULL, - NULL ); + MiniDumpWriteDump( + GetCurrentProcess(), + GetCurrentProcessId(), + hFile, + MiniDumpNormal, + &lExceptionInformation, + NULL, + NULL); - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - thisPointer->handle(pointers); + thisPointer->handle(pointers); #endif - //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - return EXCEPTION_EXECUTE_HANDLER; -} + return EXCEPTION_EXECUTE_HANDLER; + } -void PlatformExceptionHandler::install(string dumpFileName){ - thisPointer= this; - this->dumpFileName= dumpFileName; + void PlatformExceptionHandler::install(string dumpFileName) { + thisPointer = this; + this->dumpFileName = dumpFileName; #if !defined(HAVE_GOOGLE_BREAKPAD) - SetUnhandledExceptionFilter(handler); + SetUnhandledExceptionFilter(handler); #endif -} + } -string PlatformExceptionHandler::getStackTrace() { - string result = "\nStack Trace:\n"; - if(PlatformExceptionHandler::disableBacktrace == true) { - result += "disabled..."; - return result; - } + string PlatformExceptionHandler::getStackTrace() { + string result = "\nStack Trace:\n"; + if (PlatformExceptionHandler::disableBacktrace == true) { + result += "disabled..."; + return result; + } #ifndef __MINGW32__ - CONTEXT context = { 0 }; - context.ContextFlags = CONTEXT_FULL; + CONTEXT context = { 0 }; + context.ContextFlags = CONTEXT_FULL; - IMAGEHLP_SYMBOL *pSym = (IMAGEHLP_SYMBOL*)new BYTE[sizeof(IMAGEHLP_SYMBOL) + 256]; - pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); - pSym->MaxNameLength = 256; + IMAGEHLP_SYMBOL *pSym = (IMAGEHLP_SYMBOL*)new BYTE[sizeof(IMAGEHLP_SYMBOL) + 256]; + pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); + pSym->MaxNameLength = 256; - IMAGEHLP_LINE line = { 0 }; - line.SizeOfStruct = sizeof(IMAGEHLP_LINE); + IMAGEHLP_LINE line = { 0 }; + line.SizeOfStruct = sizeof(IMAGEHLP_LINE); - IMAGEHLP_MODULE module = { 0 }; - module.SizeOfStruct = sizeof(IMAGEHLP_MODULE); + IMAGEHLP_MODULE module = { 0 }; + module.SizeOfStruct = sizeof(IMAGEHLP_MODULE); - HANDLE hProcess = GetCurrentProcess(); - HANDLE hThread = GetCurrentThread(); - if (GetThreadContext(hThread, &context)) { - STACKFRAME stackframe = { 0 }; + HANDLE hProcess = GetCurrentProcess(); + HANDLE hThread = GetCurrentThread(); + if (GetThreadContext(hThread, &context)) { + STACKFRAME stackframe = { 0 }; #if !defined(_WIN64) - stackframe.AddrPC.Offset = context.Eip; + stackframe.AddrPC.Offset = context.Eip; #else - stackframe.AddrPC.Offset = context.Rip; + stackframe.AddrPC.Offset = context.Rip; #endif - stackframe.AddrPC.Mode = AddrModeFlat; + stackframe.AddrPC.Mode = AddrModeFlat; #if !defined(_WIN64) - stackframe.AddrFrame.Offset = context.Ebp; + stackframe.AddrFrame.Offset = context.Ebp; #else - stackframe.AddrFrame.Offset = context.Rbp; + stackframe.AddrFrame.Offset = context.Rbp; #endif - stackframe.AddrFrame.Mode = AddrModeFlat; + stackframe.AddrFrame.Mode = AddrModeFlat; - SymInitialize(hProcess, NULL, TRUE); - BOOL fSuccess = TRUE; + SymInitialize(hProcess, NULL, TRUE); + BOOL fSuccess = TRUE; - do - { + do { #if !defined(_WIN64) - fSuccess = StackWalk(IMAGE_FILE_MACHINE_I386, + fSuccess = StackWalk(IMAGE_FILE_MACHINE_I386, #else - fSuccess = StackWalk(IMAGE_FILE_MACHINE_AMD64, + fSuccess = StackWalk(IMAGE_FILE_MACHINE_AMD64, #endif - GetCurrentProcess(), - GetCurrentThread(), - &stackframe, - &context, - NULL, - NULL, - NULL, - NULL); + GetCurrentProcess(), + GetCurrentThread(), + &stackframe, + &context, + NULL, + NULL, + NULL, + NULL); #if !defined(_WIN64) - DWORD dwDisplacement = 0; + DWORD dwDisplacement = 0; #else - DWORD64 dwDisplacement = 0; + DWORD64 dwDisplacement = 0; #endif - DWORD dwDisplacement2 = 0; - SymGetSymFromAddr(hProcess, stackframe.AddrPC.Offset, &dwDisplacement, pSym); - SymGetLineFromAddr(hProcess, stackframe.AddrPC.Offset, &dwDisplacement2, &line); - SymGetModuleInfo(hProcess, stackframe.AddrPC.Offset, &module); + DWORD dwDisplacement2 = 0; + SymGetSymFromAddr(hProcess, stackframe.AddrPC.Offset, &dwDisplacement, pSym); + SymGetLineFromAddr(hProcess, stackframe.AddrPC.Offset, &dwDisplacement2, &line); + SymGetModuleInfo(hProcess, stackframe.AddrPC.Offset, &module); - // RetAddr Arg1 Arg2 Arg3 module!funtion FileName(line)+offset + // RetAddr Arg1 Arg2 Arg3 module!funtion FileName(line)+offset - char szBuf[8096]=""; - snprintf(szBuf,8096,"%08lx %08lx %08lx %08lx %s!%s %s(%lu) %+ld\n", - stackframe.AddrReturn.Offset, - stackframe.Params[0], - stackframe.Params[1], - stackframe.Params[2], - pSym->Name, - module.ModuleName, - line.FileName, - line.LineNumber, - dwDisplacement); - result += szBuf; + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "%08lx %08lx %08lx %08lx %s!%s %s(%lu) %+ld\n", + stackframe.AddrReturn.Offset, + stackframe.Params[0], + stackframe.Params[1], + stackframe.Params[2], + pSym->Name, + module.ModuleName, + line.FileName, + line.LineNumber, + dwDisplacement); + result += szBuf; - } while (fSuccess); + } while (fSuccess); - SymCleanup(hProcess); - } + SymCleanup(hProcess); + } #endif #ifndef __MINGW32__ - delete [] pSym; + delete[] pSym; #endif - return result; -} + return result; + } -megaglest_runtime_error::megaglest_runtime_error(const string& __arg,bool noStackTrace) -: std::runtime_error(noStackTrace == false ? __arg + PlatformExceptionHandler::getStackTrace() : __arg), noStackTrace(noStackTrace) { -} + megaglest_runtime_error::megaglest_runtime_error(const string& __arg, bool noStackTrace) + : std::runtime_error(noStackTrace == false ? __arg + PlatformExceptionHandler::getStackTrace() : __arg), noStackTrace(noStackTrace) { + } -// ===================================================== -// class Misc -// ===================================================== + // ===================================================== + // class Misc + // ===================================================== -//void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight) { -// // Get the current video hardware information -// //const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo(); -// //colorBits = vidInfo->vfmt->BitsPerPixel; -// //screenWidth = vidInfo->current_w; -// -///* -// //screenHeight = vidInfo->current_h; -// int cx = GetSystemMetrics(SM_CXVIRTUALSCREEN); -// // height -// int cy = GetSystemMetrics(SM_CYVIRTUALSCREEN); -// -// printf("cx = %d, cy = %d\n",cx,cy); -// -// if(cx > screenWidth) { -// screenWidth = cx; -// screenHeight = cy; -// } -//*/ -// int iMaxWidth = -1; -// int iMaxHeight = -1; -// int iMaxBits = -1; -// -// DEVMODE devMode; -// for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){ -// -// //printf("devMode.dmPelsWidth = %d, devMode.dmPelsHeight = %d, devMode.dmBitsPerPel = %d\n",devMode.dmPelsWidth,devMode.dmPelsHeight,devMode.dmBitsPerPel); -// -// if(devMode.dmPelsWidth > iMaxWidth) { -// iMaxWidth = devMode.dmPelsWidth; -// iMaxHeight = devMode.dmPelsHeight; -// iMaxBits = devMode.dmBitsPerPel; -// //devMode.dmDisplayFrequency=refreshFrequency; -// } -// } -// if(iMaxWidth > 0) { -// colorBits = iMaxBits; -// screenWidth = iMaxWidth; -// screenHeight = iMaxHeight; -// } -//} -// -//bool changeVideoMode(int resW, int resH, int colorBits, int refreshFrequency){ -// DEVMODE devMode; -// -// for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){ -// if (devMode.dmPelsWidth== resW && -// devMode.dmPelsHeight== resH && -// devMode.dmBitsPerPel== colorBits){ -// -// devMode.dmDisplayFrequency=refreshFrequency; -// -// LONG result= ChangeDisplaySettings(&devMode, 0); -// if(result == DISP_CHANGE_SUCCESSFUL){ -// return true; -// } -// else{ -// return false; -// } -// } -// } -// -// return false; -//} -// -//void restoreVideoMode(bool exitingApp) { -// int dispChangeErr= ChangeDisplaySettings(NULL, 0); -// assert(dispChangeErr==DISP_CHANGE_SUCCESSFUL); -//} + //void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight) { + // // Get the current video hardware information + // //const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo(); + // //colorBits = vidInfo->vfmt->BitsPerPixel; + // //screenWidth = vidInfo->current_w; + // + ///* + // //screenHeight = vidInfo->current_h; + // int cx = GetSystemMetrics(SM_CXVIRTUALSCREEN); + // // height + // int cy = GetSystemMetrics(SM_CYVIRTUALSCREEN); + // + // printf("cx = %d, cy = %d\n",cx,cy); + // + // if(cx > screenWidth) { + // screenWidth = cx; + // screenHeight = cy; + // } + //*/ + // int iMaxWidth = -1; + // int iMaxHeight = -1; + // int iMaxBits = -1; + // + // DEVMODE devMode; + // for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){ + // + // //printf("devMode.dmPelsWidth = %d, devMode.dmPelsHeight = %d, devMode.dmBitsPerPel = %d\n",devMode.dmPelsWidth,devMode.dmPelsHeight,devMode.dmBitsPerPel); + // + // if(devMode.dmPelsWidth > iMaxWidth) { + // iMaxWidth = devMode.dmPelsWidth; + // iMaxHeight = devMode.dmPelsHeight; + // iMaxBits = devMode.dmBitsPerPel; + // //devMode.dmDisplayFrequency=refreshFrequency; + // } + // } + // if(iMaxWidth > 0) { + // colorBits = iMaxBits; + // screenWidth = iMaxWidth; + // screenHeight = iMaxHeight; + // } + //} + // + //bool changeVideoMode(int resW, int resH, int colorBits, int refreshFrequency){ + // DEVMODE devMode; + // + // for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){ + // if (devMode.dmPelsWidth== resW && + // devMode.dmPelsHeight== resH && + // devMode.dmBitsPerPel== colorBits){ + // + // devMode.dmDisplayFrequency=refreshFrequency; + // + // LONG result= ChangeDisplaySettings(&devMode, 0); + // if(result == DISP_CHANGE_SUCCESSFUL){ + // return true; + // } + // else{ + // return false; + // } + // } + // } + // + // return false; + //} + // + //void restoreVideoMode(bool exitingApp) { + // int dispChangeErr= ChangeDisplaySettings(NULL, 0); + // assert(dispChangeErr==DISP_CHANGE_SUCCESSFUL); + //} -void message(string message, bool isNonGraphicalModeEnabled,const string &writepath) { - std::cerr << "******************************************************\n"; - std::cerr << " " << message << "\n"; - std::cerr << "******************************************************\n"; + void message(string message, bool isNonGraphicalModeEnabled, const string &writepath) { + std::cerr << "******************************************************\n"; + std::cerr << " " << message << "\n"; + std::cerr << "******************************************************\n"; - if(isNonGraphicalModeEnabled == false) { - LPWSTR wstr = Ansi2WideString(message.c_str()); - MessageBox(NULL, wstr, L"Message", MB_OK | MB_SYSTEMMODAL); - if(wstr) delete [] wstr; - } -} + if (isNonGraphicalModeEnabled == false) { + LPWSTR wstr = Ansi2WideString(message.c_str()); + MessageBox(NULL, wstr, L"Message", MB_OK | MB_SYSTEMMODAL); + if (wstr) delete[] wstr; + } + } -void exceptionMessage(const exception &excp){ - string message, title; - showCursor(true); + void exceptionMessage(const exception &excp) { + string message, title; + showCursor(true); - message+= "ERROR(S):\n\n"; - message+= excp.what(); + message += "ERROR(S):\n\n"; + message += excp.what(); - title= "Error: Unhandled Exception"; - printf("Error detected with text: %s\n",message.c_str()); + title = "Error: Unhandled Exception"; + printf("Error detected with text: %s\n", message.c_str()); - LPWSTR wstr = Ansi2WideString(message.c_str()); - LPWSTR wstr1 = Ansi2WideString(title.c_str()); - MessageBox(NULL, wstr, wstr1, MB_ICONSTOP | MB_OK | MB_SYSTEMMODAL); - if(wstr) delete [] wstr; - if(wstr1) delete [] wstr1; -} + LPWSTR wstr = Ansi2WideString(message.c_str()); + LPWSTR wstr1 = Ansi2WideString(title.c_str()); + MessageBox(NULL, wstr, wstr1, MB_ICONSTOP | MB_OK | MB_SYSTEMMODAL); + if (wstr) delete[] wstr; + if (wstr1) delete[] wstr1; + } -//int getScreenW(){ -// return GetSystemMetrics(SM_CXSCREEN); -//} + //int getScreenW(){ + // return GetSystemMetrics(SM_CXSCREEN); + //} -//int getScreenH(){ -// return GetSystemMetrics(SM_CYSCREEN); -//} + //int getScreenH(){ + // return GetSystemMetrics(SM_CYSCREEN); + //} -// This lets us set the SDL Window Icon in Windows -// since its a console application -HICON icon; + // This lets us set the SDL Window Icon in Windows + // since its a console application + HICON icon; -void init_win32() { - HINSTANCE handle = ::GetModuleHandle(NULL); - icon = ::LoadIcon(handle, L"IDI_ICON1"); + void init_win32() { + HINSTANCE handle = ::GetModuleHandle(NULL); + icon = ::LoadIcon(handle, L"IDI_ICON1"); - SDL_SysWMinfo wminfo; - SDL_VERSION(&wminfo.version) - if (SDL_GetWindowWMInfo(Window::getSDLWindow(),&wminfo) != 1) { - // error: wrong SDL version - } + SDL_SysWMinfo wminfo; + SDL_VERSION(&wminfo.version) + if (SDL_GetWindowWMInfo(Window::getSDLWindow(), &wminfo) != 1) { + // error: wrong SDL version + } - HWND hwnd = wminfo.info.win.window; + HWND hwnd = wminfo.info.win.window; #ifdef __MINGW32__ - #define GCL_HICON -14 +#define GCL_HICON -14 #endif #ifndef __MINGW32__ - LONG iconPtr = (LONG)icon; + LONG iconPtr = (LONG) icon; #if !defined(_WIN64) - ::SetClassLong(hwnd, GCL_HICON, iconPtr); + ::SetClassLong(hwnd, GCL_HICON, iconPtr); #else - ::SetClassLongPtr(hwnd, GCLP_HICON, (LONG_PTR)&iconPtr); + ::SetClassLongPtr(hwnd, GCLP_HICON, (LONG_PTR) &iconPtr); #endif #endif - ontop_win32(0, 0); -} + ontop_win32(0, 0); + } + + void ontop_win32(int width, int height) { + SDL_SysWMinfo wminfo; + SDL_VERSION(&wminfo.version) + if (SDL_GetWindowWMInfo(Window::getSDLWindow(), &wminfo) != 1) { + // error: wrong SDL version + } + + HWND hwnd = wminfo.info.win.window; + + SetWindowLong(hwnd, GWL_EXSTYLE, 0); + SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_SHOWWINDOW); + if (width > 0 && height > 0) { + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, width, height, SWP_SHOWWINDOW); + } + } + + void done_win32() { + ::DestroyIcon(icon); + } + + void CheckPacketThrottling() { + static bool alreadyChecked = false; + if (alreadyChecked == true) { + return; + } + alreadyChecked = true; + //printf("Checking Windows Network Packet Throttle Setting...\n"); + //Open the registry key. + wstring subKey = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Multimedia\\SystemProfile"; + wstring Key = L"NetworkThrottlingIndex"; + HKEY keyHandle; + DWORD dwDesiredThrottle = 0xffffffff; + //LONG reg_result = RegCreateKeyEx(HKEY_LOCAL_MACHINE,subKey.c_str(),0, NULL, 0, KEY_ALL_ACCESS, NULL, &keyHandle, &dwDisposition); + //LONG reg_result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,subKey.c_str(),0, KEY_ALL_ACCESS, &keyHandle); + LONG reg_result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKey.c_str(), 0, KEY_QUERY_VALUE, &keyHandle); + + if (reg_result != ERROR_SUCCESS) { + //printf("\nError opening network throttle registry hive: %d\n",reg_result); + return; + } + //Set the value. + + DWORD disableThrottle = 0; + DWORD len = sizeof(DWORD); + + reg_result = RegQueryValueEx(keyHandle, Key.c_str(), 0, 0, (LPBYTE) &disableThrottle, &len); + if (reg_result != ERROR_SUCCESS) { + printf("\nError opening network throttle registry key: %d\n", reg_result); + } + + if (disableThrottle != dwDesiredThrottle) { + printf("\n***WARNING*** Windows network throttling is enabled, value: %d\n", disableThrottle); + wprintf(L"Please set: HKEY_LOCAL_MACHINE\\%s\nKey: %s to the value: %X\n", subKey.c_str(), Key.c_str(), dwDesiredThrottle); + + // disableThrottle = 0xffffffff; + // reg_result = RegSetValueEx(keyHandle, L"NetworkThrottlingIndex", 0, REG_DWORD, (LPBYTE) &disableThrottle, len); + // if(reg_result != ERROR_SUCCESS) { + // printf("Error setting network throttle registry key: %d [%s]\n",reg_result,getWindowsAPIError(reg_result).c_str()); + // } + } + RegCloseKey(keyHandle); + } + -void ontop_win32(int width, int height) { - SDL_SysWMinfo wminfo; - SDL_VERSION(&wminfo.version) - if (SDL_GetWindowWMInfo(Window::getSDLWindow(),&wminfo) != 1) { - // error: wrong SDL version } - - HWND hwnd = wminfo.info.win.window; - - SetWindowLong(hwnd, GWL_EXSTYLE, 0); - SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); - SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_SHOWWINDOW); - if(width > 0 && height > 0) { - SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, width, height, SWP_SHOWWINDOW); - } -} - -void done_win32() { - ::DestroyIcon(icon); -} - -void CheckPacketThrottling() { - static bool alreadyChecked = false; - if(alreadyChecked == true) { - return; - } - alreadyChecked = true; - //printf("Checking Windows Network Packet Throttle Setting...\n"); - //Open the registry key. - wstring subKey = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Multimedia\\SystemProfile"; - wstring Key = L"NetworkThrottlingIndex"; - HKEY keyHandle; - DWORD dwDesiredThrottle = 0xffffffff; - //LONG reg_result = RegCreateKeyEx(HKEY_LOCAL_MACHINE,subKey.c_str(),0, NULL, 0, KEY_ALL_ACCESS, NULL, &keyHandle, &dwDisposition); - //LONG reg_result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,subKey.c_str(),0, KEY_ALL_ACCESS, &keyHandle); - LONG reg_result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,subKey.c_str(),0, KEY_QUERY_VALUE, &keyHandle); - - if(reg_result != ERROR_SUCCESS) { - //printf("\nError opening network throttle registry hive: %d\n",reg_result); - return; - } - //Set the value. - - DWORD disableThrottle = 0; - DWORD len = sizeof(DWORD); - - reg_result = RegQueryValueEx(keyHandle, Key.c_str(), 0, 0, (LPBYTE) &disableThrottle, &len); - if(reg_result != ERROR_SUCCESS) { - printf("\nError opening network throttle registry key: %d\n",reg_result); - } - - if(disableThrottle != dwDesiredThrottle) { - printf("\n***WARNING*** Windows network throttling is enabled, value: %d\n",disableThrottle); - wprintf(L"Please set: HKEY_LOCAL_MACHINE\\%s\nKey: %s to the value: %X\n",subKey.c_str(),Key.c_str(),dwDesiredThrottle); - -// disableThrottle = 0xffffffff; -// reg_result = RegSetValueEx(keyHandle, L"NetworkThrottlingIndex", 0, REG_DWORD, (LPBYTE) &disableThrottle, len); -// if(reg_result != ERROR_SUCCESS) { -// printf("Error setting network throttle registry key: %d [%s]\n",reg_result,getWindowsAPIError(reg_result).c_str()); -// } - } - RegCloseKey(keyHandle); -} - - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/sound/openal/sound_player_openal.cpp b/source/shared_lib/sources/sound/openal/sound_player_openal.cpp index b163b8676..c5c8cd833 100644 --- a/source/shared_lib/sources/sound/openal/sound_player_openal.cpp +++ b/source/shared_lib/sources/sound/openal/sound_player_openal.cpp @@ -17,693 +17,672 @@ #include "conversion.h" #include "leak_dumper.h" -namespace Shared{ namespace Sound{ namespace OpenAL{ +namespace Shared { + namespace Sound { + namespace OpenAL { -using namespace Util; + using namespace Util; -SoundSource::SoundSource() -{ - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); + SoundSource::SoundSource() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); - alGenSources(1, &source); - SoundPlayerOpenAL::checkAlError("Couldn't create audio source: "); + alGenSources(1, &source); + SoundPlayerOpenAL::checkAlError("Couldn't create audio source: "); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); -} + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + } -SoundSource::~SoundSource() -{ - stop(); - alDeleteSources(1, &source); -} + SoundSource::~SoundSource() { + stop(); + alDeleteSources(1, &source); + } -bool SoundSource::playing() -{ - ALint state = AL_STOPPED; - alGetSourcei(source, AL_SOURCE_STATE, &state); - return(state == AL_PLAYING || state == AL_PAUSED); -} + bool SoundSource::playing() { + ALint state = AL_STOPPED; + alGetSourcei(source, AL_SOURCE_STATE, &state); + return(state == AL_PLAYING || state == AL_PAUSED); + } -void SoundSource::unQueueBuffers() { - SoundPlayerOpenAL::checkAlError("Problem unqueuing buffers START OF METHOD: "); + void SoundSource::unQueueBuffers() { + SoundPlayerOpenAL::checkAlError("Problem unqueuing buffers START OF METHOD: "); - ALint queued=0; - alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + ALint queued = 0; + alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - alSourcei(source, AL_LOOPING, AL_FALSE); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + alSourcei(source, AL_LOOPING, AL_FALSE); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - ALint processed=0; - alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + ALint processed = 0; + alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - while(processed--) { - ALuint buffer=0; - alSourceUnqueueBuffers(source, 1, &buffer); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - } + while (processed--) { + ALuint buffer = 0; + alSourceUnqueueBuffers(source, 1, &buffer); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + } -// ALint queued=0; -// alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); -// while(queued--) { -// ALuint buffer=0; -// alSourceUnqueueBuffers(source, 1, &buffer); -// SoundPlayerOpenAL::checkAlError("Problem unqueuing buffers (alSourceUnqueueBuffers) in audio source: "); -// } -// -// SoundPlayerOpenAL::checkAlError("Problem unqueuing buffers (alGetSourcei AL_BUFFERS_QUEUED) in audio source: "); + // ALint queued=0; + // alGetSourcei(source, AL_BUFFERS_QUEUED, &queued); + // while(queued--) { + // ALuint buffer=0; + // alSourceUnqueueBuffers(source, 1, &buffer); + // SoundPlayerOpenAL::checkAlError("Problem unqueuing buffers (alSourceUnqueueBuffers) in audio source: "); + // } + // + // SoundPlayerOpenAL::checkAlError("Problem unqueuing buffers (alGetSourcei AL_BUFFERS_QUEUED) in audio source: "); -} + } -void SoundSource::stop() { - alSourceStop(source); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + void SoundSource::stop() { + alSourceStop(source); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - unQueueBuffers(); + unQueueBuffers(); - alSourcei(source, AL_BUFFER, AL_NONE); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + alSourcei(source, AL_BUFFER, AL_NONE); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - //unQueueBuffers(); + //unQueueBuffers(); - alSourceRewind(source); // stops the source - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + alSourceRewind(source); // stops the source + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - while(playing() == true) { - //alSourceStop(source); - //SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - ALint state = AL_STOPPED; - alGetSourcei(source, AL_SOURCE_STATE, &state); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + while (playing() == true) { + //alSourceStop(source); + //SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + ALint state = AL_STOPPED; + alGetSourcei(source, AL_SOURCE_STATE, &state); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - sleep(1); - printf("$$$ WAITING FOR OPENAL TO STOP state = %d!\n",state); - } - //unQueueBuffers(); - //SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); -} + sleep(1); + printf("$$$ WAITING FOR OPENAL TO STOP state = %d!\n", state); + } + //unQueueBuffers(); + //SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + } -ALenum SoundSource::getFormat(Sound* sound) -{ - if(sound->getInfo()->getChannels() == 2) { - if(sound->getInfo()->getBitsPerSample() == 16) { - return AL_FORMAT_STEREO16; - } - else if(sound->getInfo()->getBitsPerSample() == 8) { - return AL_FORMAT_STEREO8; - } - else { - throw std::runtime_error("[1] Sample format not supported in file: " + sound->getFileName()); - } - } - else if(sound->getInfo()->getChannels() == 1) { - if(sound->getInfo()->getBitsPerSample() == 16) { - return AL_FORMAT_MONO16; - } - else if(sound->getInfo()->getBitsPerSample() == 8) { - return AL_FORMAT_MONO8; - } - else { - throw std::runtime_error("[2] Sample format not supported in file: " + sound->getFileName()); - } - } + ALenum SoundSource::getFormat(Sound* sound) { + if (sound->getInfo()->getChannels() == 2) { + if (sound->getInfo()->getBitsPerSample() == 16) { + return AL_FORMAT_STEREO16; + } else if (sound->getInfo()->getBitsPerSample() == 8) { + return AL_FORMAT_STEREO8; + } else { + throw std::runtime_error("[1] Sample format not supported in file: " + sound->getFileName()); + } + } else if (sound->getInfo()->getChannels() == 1) { + if (sound->getInfo()->getBitsPerSample() == 16) { + return AL_FORMAT_MONO16; + } else if (sound->getInfo()->getBitsPerSample() == 8) { + return AL_FORMAT_MONO8; + } else { + throw std::runtime_error("[2] Sample format not supported in file: " + sound->getFileName()); + } + } - throw std::runtime_error("[3] Sample format not supported in file: " + sound->getFileName()); -} + throw std::runtime_error("[3] Sample format not supported in file: " + sound->getFileName()); + } -//--------------------------------------------------------------------------- + //--------------------------------------------------------------------------- -StaticSoundSource::StaticSoundSource() { - bufferAllocated = false; - buffer = 0; -} + StaticSoundSource::StaticSoundSource() { + bufferAllocated = false; + buffer = 0; + } -StaticSoundSource::~StaticSoundSource() { - if(bufferAllocated) { - stop(); - alDeleteBuffers(1, &buffer); - } -} + StaticSoundSource::~StaticSoundSource() { + if (bufferAllocated) { + stop(); + alDeleteBuffers(1, &buffer); + } + } -void StaticSoundSource::play(StaticSound* sound) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + void StaticSoundSource::play(StaticSound* sound) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); - if(bufferAllocated) { - stop(); - alDeleteBuffers(1, &buffer); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - } - ALenum format = getFormat(sound); + if (bufferAllocated) { + stop(); + alDeleteBuffers(1, &buffer); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + } + ALenum format = getFormat(sound); - alGenBuffers(1, &buffer); - SoundPlayerOpenAL::checkAlError("Couldn't create audio buffer: "); + alGenBuffers(1, &buffer); + SoundPlayerOpenAL::checkAlError("Couldn't create audio buffer: "); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s Line: %d] filename [%s] format = %d, sound->getSamples() = %d, sound->getInfo()->getSize() = %d, sound->getInfo()->getSamplesPerSecond() = %d\n",__FILE__,__FUNCTION__,__LINE__,sound->getFileName().c_str(),format,sound->getSamples(),sound->getInfo()->getSize(),sound->getInfo()->getSamplesPerSecond()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s Line: %d] filename [%s] format = %d, sound->getSamples() = %d, sound->getInfo()->getSize() = %d, sound->getInfo()->getSamplesPerSecond() = %d\n", __FILE__, __FUNCTION__, __LINE__, sound->getFileName().c_str(), format, sound->getSamples(), sound->getInfo()->getSize(), sound->getInfo()->getSamplesPerSecond()); - bufferAllocated = true; - alBufferData(buffer, format, sound->getSamples(), - static_cast (sound->getInfo()->getSize()), - static_cast (sound->getInfo()->getSamplesPerSecond())); + bufferAllocated = true; + alBufferData(buffer, format, sound->getSamples(), + static_cast (sound->getInfo()->getSize()), + static_cast (sound->getInfo()->getSamplesPerSecond())); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - alSourcei(source, AL_BUFFER, buffer); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - alSourcef(source, AL_GAIN, sound->getVolume()); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - - alSourcePlay(source); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); -} - -StreamSoundSource::StreamSoundSource() -{ - sound = 0; - fadeState = NoFading; - format = 0; - fade = 0; - alGenBuffers(STREAMFRAGMENTS, buffers); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); -} - -StreamSoundSource::~StreamSoundSource() -{ - stop(); - alDeleteBuffers(STREAMFRAGMENTS, buffers); - SoundPlayerOpenAL::checkAlError("Couldn't delete audio buffers: "); -} - -void StreamSoundSource::stop() -{ - sound = 0; - SoundSource::stop(); -} - -void StreamSoundSource::stop(int64 fadeoff) -{ - if(fadeoff > 0) { - fadeState = FadingOff; - fade = fadeoff; - chrono.start(); - } else { - stop(); - } -} - -void StreamSoundSource::play(StrSound* sound, int64 fadeon) -{ - stop(); - - this->sound = sound; - - format = getFormat(sound); - for(size_t i = 0; i < STREAMFRAGMENTS; ++i) { - fillBufferAndQueue(buffers[i]); - } - if(fadeon > 0) { - alSourcef(source, AL_GAIN, 0); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - - fadeState = FadingOn; - fade = fadeon; - chrono.start(); - } else { - fadeState = NoFading; - alSourcef(source, AL_GAIN, sound->getVolume()); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - } - alSourcePlay(source); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); -} - -void StreamSoundSource::update() -{ - if(sound == 0) { - return; - } - - if(fadeState == NoFading){ - alSourcef(source, AL_GAIN, sound->getVolume()); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - } - - ALint processed = 0; - alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - while(processed > 0) { - processed--; - - ALuint buffer; - alSourceUnqueueBuffers(source, 1, &buffer); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - - if(!fillBufferAndQueue(buffer)) - break; - } - - // we might have to restart the source if we had a buffer underrun - if(!playing()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d] Restarting audio source because of buffer underrun.\n",__FILE__,__FUNCTION__,__LINE__); - - std::cerr << "Restarting audio source because of buffer underrun.\n"; - alSourcePlay(source); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - } - - // handle fading - switch(fadeState) { - case FadingOn: - if(chrono.getMillis() > fade) { + alSourcei(source, AL_BUFFER, buffer); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); alSourcef(source, AL_GAIN, sound->getVolume()); SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + alSourcePlay(source); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + } + + StreamSoundSource::StreamSoundSource() { + sound = 0; fadeState = NoFading; - } else { - alSourcef(source, AL_GAIN, sound->getVolume() * - static_cast (chrono.getMillis())/fade); + format = 0; + fade = 0; + alGenBuffers(STREAMFRAGMENTS, buffers); SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); } - break; - case FadingOff: - if(chrono.getMillis() > fade) { + + StreamSoundSource::~StreamSoundSource() { stop(); - } else { - alSourcef(source, AL_GAIN, sound->getVolume() * - (1.0f - static_cast(chrono.getMillis())/fade)); - SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + alDeleteBuffers(STREAMFRAGMENTS, buffers); + SoundPlayerOpenAL::checkAlError("Couldn't delete audio buffers: "); } - break; - default: - break; - } -} -bool StreamSoundSource::fillBufferAndQueue(ALuint buffer) -{ - // fill buffer - int8* bufferdata = new int8[STREAMFRAGMENTSIZE]; - uint32 bytesread = 0; - do { - bytesread += sound->read(bufferdata + bytesread,STREAMFRAGMENTSIZE - bytesread); - if(bytesread < STREAMFRAGMENTSIZE) { - StrSound* next = sound->getNext(); - if(next == 0) - next = sound; - next->restart(); - next->setVolume(sound->getVolume()); - sound = next; - } - } while(bytesread < STREAMFRAGMENTSIZE); + void StreamSoundSource::stop() { + sound = 0; + SoundSource::stop(); + } - alBufferData(buffer, format, bufferdata, STREAMFRAGMENTSIZE, - sound->getInfo()->getSamplesPerSecond()); - delete[] bufferdata; - SoundPlayerOpenAL::checkAlError("Couldn't refill audio buffer: "); - - alSourceQueueBuffers(source, 1, &buffer); - SoundPlayerOpenAL::checkAlError("Couldn't queue audio buffer: "); - - return true; -} - -// ================================ -// Sound Player OpenAL -// ================================ - -SoundPlayerOpenAL::SoundPlayerOpenAL() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - - device = 0; - context = 0; - initOk = false; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -SoundPlayerOpenAL::~SoundPlayerOpenAL() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - - end(); - initOk = false; - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void SoundPlayerOpenAL::printOpenALInfo() -{ - printf("OpenAL Vendor: %s\n",alGetString(AL_VENDOR)); - printf("OpenAL Version: %s\n",alGetString(AL_VERSION)); - printf("OpenAL Renderer: %s\n",alGetString(AL_RENDERER)); - printf("OpenAL Extensions: %s\n",alGetString(AL_RENDERER)); - -/* - std::cout << "OpenAL Vendor: " << alGetString(AL_VENDOR) << "\n" - << "OpenAL Version: " << alGetString(AL_VERSION) << "\n" - << "OpenAL Renderer: " << alGetString(AL_RENDERER) << "\n" - << "OpenAl Extensions: " << alGetString(AL_RENDERER) << "\n"; -*/ -} - -bool SoundPlayerOpenAL::init(const SoundPlayerParams* params) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - - initOk = false; - - if(params == NULL) { - throw std::runtime_error("params == NULL"); - } - - this->params = *params; - - try { - - if(context != 0) { - alcMakeContextCurrent( NULL ); - alcDestroyContext(context); - context = 0; - } - - if(device != 0) { - alcCloseDevice(device); - device = 0; - } - - // Allows platforms to specify which sound device to use - // using the environment variable: MEGAGLEST_SOUND_DEVICE - char *deviceName = getenv("MEGAGLEST_SOUND_DEVICE"); - device = alcOpenDevice(deviceName); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) { - std::ostringstream os; - if (alcIsExtensionPresent (NULL, (const ALCchar *) "ALC_ENUMERATION_EXT") == AL_TRUE) { - const char *s = (const char *) alcGetString(NULL, ALC_DEVICE_SPECIFIER); - while (*s != '\0') { - os << "OpenAL available device: " << s << std::endl; - while (*s++ != '\0') - ; + void StreamSoundSource::stop(int64 fadeoff) { + if (fadeoff > 0) { + fadeState = FadingOff; + fade = fadeoff; + chrono.start(); + } else { + stop(); } } - else { - os << "OpenAL device enumeration isn't available." << std::endl; + + void StreamSoundSource::play(StrSound* sound, int64 fadeon) { + stop(); + + this->sound = sound; + + format = getFormat(sound); + for (size_t i = 0; i < STREAMFRAGMENTS; ++i) { + fillBufferAndQueue(buffers[i]); + } + if (fadeon > 0) { + alSourcef(source, AL_GAIN, 0); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + + fadeState = FadingOn; + fade = fadeon; + chrono.start(); + } else { + fadeState = NoFading; + alSourcef(source, AL_GAIN, sound->getVolume()); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + } + alSourcePlay(source); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); } - // Print default device name - os << "OpenAL default device: " - << (const char *)alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER) - << std::endl; + void StreamSoundSource::update() { + if (sound == 0) { + return; + } - // Print current device name - if (device) { - os << "OpenAL current device: " - << (const char *)alcGetString(device, ALC_DEVICE_SPECIFIER) - << std::endl; + if (fadeState == NoFading) { + alSourcef(source, AL_GAIN, sound->getVolume()); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + } + + ALint processed = 0; + alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + while (processed > 0) { + processed--; + + ALuint buffer; + alSourceUnqueueBuffers(source, 1, &buffer); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + + if (!fillBufferAndQueue(buffer)) + break; + } + + // we might have to restart the source if we had a buffer underrun + if (!playing()) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d] Restarting audio source because of buffer underrun.\n", __FILE__, __FUNCTION__, __LINE__); + + std::cerr << "Restarting audio source because of buffer underrun.\n"; + alSourcePlay(source); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + } + + // handle fading + switch (fadeState) { + case FadingOn: + if (chrono.getMillis() > fade) { + alSourcef(source, AL_GAIN, sound->getVolume()); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + + fadeState = NoFading; + } else { + alSourcef(source, AL_GAIN, sound->getVolume() * + static_cast (chrono.getMillis()) / fade); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + } + break; + case FadingOff: + if (chrono.getMillis() > fade) { + stop(); + } else { + alSourcef(source, AL_GAIN, sound->getVolume() * + (1.0f - static_cast(chrono.getMillis()) / fade)); + SoundPlayerOpenAL::checkAlError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + } + break; + default: + break; + } } - SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d] OpenAL device info [%s]\n",__FILE__,__FUNCTION__,__LINE__,os.str().c_str()); - printf("OpenAL device info:\n%s\n",os.str().c_str()); - } + bool StreamSoundSource::fillBufferAndQueue(ALuint buffer) { + // fill buffer + int8* bufferdata = new int8[STREAMFRAGMENTSIZE]; + uint32 bytesread = 0; + do { + bytesread += sound->read(bufferdata + bytesread, STREAMFRAGMENTSIZE - bytesread); + if (bytesread < STREAMFRAGMENTSIZE) { + StrSound* next = sound->getNext(); + if (next == 0) + next = sound; + next->restart(); + next->setVolume(sound->getVolume()); + sound = next; + } + } while (bytesread < STREAMFRAGMENTSIZE); - if(device == 0) { - //printOpenALInfo(); - throw std::runtime_error("Couldn't open audio device."); - } + alBufferData(buffer, format, bufferdata, STREAMFRAGMENTSIZE, + sound->getInfo()->getSamplesPerSecond()); + delete[] bufferdata; + SoundPlayerOpenAL::checkAlError("Couldn't refill audio buffer: "); - //int attributes[] = { 0 }; - //context = alcCreateContext(device, attributes); - context = alcCreateContext(device, 0); - checkAlcError("Couldn't create audio context: "); + alSourceQueueBuffers(source, 1, &buffer); + SoundPlayerOpenAL::checkAlError("Couldn't queue audio buffer: "); - if(context == NULL) { - alcCloseDevice(device); - device = NULL; - throw std::runtime_error("Couldn't create an audio context (NULL)."); - } - - alcMakeContextCurrent(context); - checkAlcError("Couldn't select audio context: "); - - checkAlError("Audio error after init: "); - - initOk = true; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - } - catch(const exception &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - printOpenALInfo(); - } - - return initOk; -} - -void SoundPlayerOpenAL::end() { - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - - - for(StaticSoundSources::iterator i = staticSources.begin(); - i != staticSources.end(); ++i) { - StaticSoundSource *src = (*i); - src->stop(); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - - for(StreamSoundSources::iterator i = streamSources.begin(); - i != streamSources.end(); ++i) { - StreamSoundSource *src = (*i); - src->stop(); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - - for(StaticSoundSources::iterator i = staticSources.begin(); - i != staticSources.end(); ++i) { - delete *i; - } - staticSources.clear(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - - for(StreamSoundSources::iterator i = streamSources.begin(); - i != streamSources.end(); ++i) { - delete *i; - } - streamSources.clear(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(context != 0) { - alcMakeContextCurrent( NULL ); - SoundPlayerOpenAL::checkAlcError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(context != 0) { - alcDestroyContext(context); - context = 0; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); - - if(device != 0) { - alcCloseDevice(device); - device = 0; - initOk = false; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); -} - -void SoundPlayerOpenAL::play(StaticSound* staticSound, bool force ) { - assert(staticSound != 0); - - if(initOk == false) return; - - try { - StaticSoundSource* source = findStaticSoundSource(); - - if(source == 0 ) { - if( force == false ) - return; - else { - // force usage of first StaticSoundSource - source = staticSources.front(); - source->stop(); + return true; } - } - source->play(staticSound); - } - catch(std::exception& e) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what()); - std::cerr << "Couldn't play static sound: [" << e.what() << "]\n"; - } -} -void SoundPlayerOpenAL::play(StrSound* strSound, int64 fadeOn) { - assert(strSound != 0); + // ================================ + // Sound Player OpenAL + // ================================ - if(initOk == false) return; + SoundPlayerOpenAL::SoundPlayerOpenAL() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); - try { - StreamSoundSource* source = findStreamSoundSource(); - source->play(strSound, fadeOn); - } - catch(std::exception& e) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what()); - std::cerr << "Couldn't play streaming sound: " << e.what() << "\n"; - } -} + device = 0; + context = 0; + initOk = false; -void SoundPlayerOpenAL::stop(StrSound* strSound, int64 fadeOff) { - assert(strSound != 0); - - if(initOk == false) return; - - for(StreamSoundSources::iterator i = streamSources.begin(); - i != streamSources.end(); ++i) { - StreamSoundSource* source = *i; - if(source->sound == strSound) { - source->stop(fadeOff); - } - } -} - -void SoundPlayerOpenAL::stopAllSounds(int64 fadeOff) { - if(initOk == false) return; - - for(StaticSoundSources::iterator i = staticSources.begin(); - i != staticSources.end(); ++i) { - StaticSoundSource* source = *i; - source->stop(); - } - for(StreamSoundSources::iterator i = streamSources.begin(); - i != streamSources.end(); ++i) { - StreamSoundSource* source = *i; - source->stop(fadeOff); - } -} - -void SoundPlayerOpenAL::updateStreams() { - if(initOk == false) return; - - assert(context != 0); - try { - for(StreamSoundSources::iterator i = streamSources.begin(); - i != streamSources.end(); ++i) { - StreamSoundSource* source = *i; - try { - source->update(); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); } - catch(std::exception& e) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what()); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what()); - std::cerr << "Error while updating sound stream: "<< e.what() << "\n"; + SoundPlayerOpenAL::~SoundPlayerOpenAL() { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + + end(); + initOk = false; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); } - } - alcProcessContext(context); - checkAlcError("Error while processing audio context: "); - } - catch(exception &ex) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); - printOpenALInfo(); - throw megaglest_runtime_error(ex.what()); - } - catch(...) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s Line: %d] UNKNOWN Error\n",__FILE__,__FUNCTION__,__LINE__); - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] UNKNOWN Error\n",__FILE__,__FUNCTION__,__LINE__); - printOpenALInfo(); - throw; - } -} -StaticSoundSource* SoundPlayerOpenAL::findStaticSoundSource() { - if(initOk == false) return NULL; + void SoundPlayerOpenAL::printOpenALInfo() { + printf("OpenAL Vendor: %s\n", alGetString(AL_VENDOR)); + printf("OpenAL Version: %s\n", alGetString(AL_VERSION)); + printf("OpenAL Renderer: %s\n", alGetString(AL_RENDERER)); + printf("OpenAL Extensions: %s\n", alGetString(AL_RENDERER)); + + /* + std::cout << "OpenAL Vendor: " << alGetString(AL_VENDOR) << "\n" + << "OpenAL Version: " << alGetString(AL_VERSION) << "\n" + << "OpenAL Renderer: " << alGetString(AL_RENDERER) << "\n" + << "OpenAl Extensions: " << alGetString(AL_RENDERER) << "\n"; + */ + } + + bool SoundPlayerOpenAL::init(const SoundPlayerParams* params) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + + initOk = false; + + if (params == NULL) { + throw std::runtime_error("params == NULL"); + } + + this->params = *params; + + try { + + if (context != 0) { + alcMakeContextCurrent(NULL); + alcDestroyContext(context); + context = 0; + } + + if (device != 0) { + alcCloseDevice(device); + device = 0; + } + + // Allows platforms to specify which sound device to use + // using the environment variable: MEGAGLEST_SOUND_DEVICE + char *deviceName = getenv("MEGAGLEST_SOUND_DEVICE"); + device = alcOpenDevice(deviceName); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) { + std::ostringstream os; + if (alcIsExtensionPresent(NULL, (const ALCchar *) "ALC_ENUMERATION_EXT") == AL_TRUE) { + const char *s = (const char *) alcGetString(NULL, ALC_DEVICE_SPECIFIER); + while (*s != '\0') { + os << "OpenAL available device: " << s << std::endl; + while (*s++ != '\0') + ; + } + } else { + os << "OpenAL device enumeration isn't available." << std::endl; + } + + // Print default device name + os << "OpenAL default device: " + << (const char *) alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER) + << std::endl; + + // Print current device name + if (device) { + os << "OpenAL current device: " + << (const char *) alcGetString(device, ALC_DEVICE_SPECIFIER) + << std::endl; + } + + SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d] OpenAL device info [%s]\n", __FILE__, __FUNCTION__, __LINE__, os.str().c_str()); + printf("OpenAL device info:\n%s\n", os.str().c_str()); + } + + if (device == 0) { + //printOpenALInfo(); + throw std::runtime_error("Couldn't open audio device."); + } + + //int attributes[] = { 0 }; + //context = alcCreateContext(device, attributes); + context = alcCreateContext(device, 0); + checkAlcError("Couldn't create audio context: "); + + if (context == NULL) { + alcCloseDevice(device); + device = NULL; + throw std::runtime_error("Couldn't create an audio context (NULL)."); + } + + alcMakeContextCurrent(context); + checkAlcError("Couldn't select audio context: "); + + checkAlError("Audio error after init: "); + + initOk = true; + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + } catch (const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d] error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + printOpenALInfo(); + } + + return initOk; + } + + void SoundPlayerOpenAL::end() { + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + + + for (StaticSoundSources::iterator i = staticSources.begin(); + i != staticSources.end(); ++i) { + StaticSoundSource *src = (*i); + src->stop(); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + + for (StreamSoundSources::iterator i = streamSources.begin(); + i != streamSources.end(); ++i) { + StreamSoundSource *src = (*i); + src->stop(); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + + for (StaticSoundSources::iterator i = staticSources.begin(); + i != staticSources.end(); ++i) { + delete *i; + } + staticSources.clear(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + + for (StreamSoundSources::iterator i = streamSources.begin(); + i != streamSources.end(); ++i) { + delete *i; + } + streamSources.clear(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (context != 0) { + alcMakeContextCurrent(NULL); + SoundPlayerOpenAL::checkAlcError(string(__FILE__) + string(" ") + string(__FUNCTION__) + string(" ") + intToStr(__LINE__)); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (context != 0) { + alcDestroyContext(context); + context = 0; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + + if (device != 0) { + alcCloseDevice(device); + device = 0; + initOk = false; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); + } + + void SoundPlayerOpenAL::play(StaticSound* staticSound, bool force) { + assert(staticSound != 0); + + if (initOk == false) return; + + try { + StaticSoundSource* source = findStaticSoundSource(); + + if (source == 0) { + if (force == false) + return; + else { + // force usage of first StaticSoundSource + source = staticSources.front(); + source->stop(); + } + } + source->play(staticSound); + } catch (std::exception& e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, e.what()); + std::cerr << "Couldn't play static sound: [" << e.what() << "]\n"; + } + } + + void SoundPlayerOpenAL::play(StrSound* strSound, int64 fadeOn) { + assert(strSound != 0); + + if (initOk == false) return; + + try { + StreamSoundSource* source = findStreamSoundSource(); + source->play(strSound, fadeOn); + } catch (std::exception& e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, e.what()); + std::cerr << "Couldn't play streaming sound: " << e.what() << "\n"; + } + } + + void SoundPlayerOpenAL::stop(StrSound* strSound, int64 fadeOff) { + assert(strSound != 0); + + if (initOk == false) return; + + for (StreamSoundSources::iterator i = streamSources.begin(); + i != streamSources.end(); ++i) { + StreamSoundSource* source = *i; + if (source->sound == strSound) { + source->stop(fadeOff); + } + } + } + + void SoundPlayerOpenAL::stopAllSounds(int64 fadeOff) { + if (initOk == false) return; + + for (StaticSoundSources::iterator i = staticSources.begin(); + i != staticSources.end(); ++i) { + StaticSoundSource* source = *i; + source->stop(); + } + for (StreamSoundSources::iterator i = streamSources.begin(); + i != streamSources.end(); ++i) { + StreamSoundSource* source = *i; + source->stop(fadeOff); + } + } + + void SoundPlayerOpenAL::updateStreams() { + if (initOk == false) return; + + assert(context != 0); + try { + for (StreamSoundSources::iterator i = streamSources.begin(); + i != streamSources.end(); ++i) { + StreamSoundSource* source = *i; + try { + source->update(); + } catch (std::exception& e) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, e.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, e.what()); + + std::cerr << "Error while updating sound stream: " << e.what() << "\n"; + } + } + alcProcessContext(context); + checkAlcError("Error while processing audio context: "); + } catch (exception &ex) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", __FILE__, __FUNCTION__, __LINE__, ex.what()); + printOpenALInfo(); + throw megaglest_runtime_error(ex.what()); + } catch (...) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s Line: %d] UNKNOWN Error\n", __FILE__, __FUNCTION__, __LINE__); + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] UNKNOWN Error\n", __FILE__, __FUNCTION__, __LINE__); + printOpenALInfo(); + throw; + } + } + + StaticSoundSource* SoundPlayerOpenAL::findStaticSoundSource() { + if (initOk == false) return NULL; + + // try to find a stopped source + int playingCount = 0; + for (StaticSoundSources::iterator i = staticSources.begin(); + i != staticSources.end(); ++i) { + StaticSoundSource* source = *i; + if (!source->playing()) { + return source; + } else { + playingCount++; + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s %d] playingCount = %d, staticSources.size() = " MG_SIZE_T_SPECIFIER ", params.staticBufferCount = %u\n", __FILE__, __FUNCTION__, __LINE__, playingCount, (unsigned long) staticSources.size(), params.staticBufferCount); + + // create a new source + if (staticSources.size() >= params.staticBufferCount) { + return 0; + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + StaticSoundSource* source = new StaticSoundSource(); + staticSources.push_back(source); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + return source; + } + + StreamSoundSource* SoundPlayerOpenAL::findStreamSoundSource() { + if (initOk == false) return NULL; + + // try to find a stopped source + for (StreamSoundSources::iterator i = streamSources.begin(); + i != streamSources.end(); ++i) { + StreamSoundSource* source = *i; + if (!source->playing()) { + return source; + } + } + + // create a new source + if (streamSources.size() >= params.strBufferCount) { + throw std::runtime_error("Too many stream sounds played at once"); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + StreamSoundSource* source = new StreamSoundSource(); + streamSources.push_back(source); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s Line: %d]\n", __FILE__, __FUNCTION__, __LINE__); + + return source; + } + + void SoundPlayerOpenAL::checkAlcError(string message) { + int err = alcGetError(device); + if (err != ALC_NO_ERROR) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "%s [%s]", message.c_str(), alcGetString(device, err)); + + //std::stringstream msg; + //msg << message.c_str() << alcGetString(device, err); + printf("openalc error [%s]\n", szBuf); + throw std::runtime_error(szBuf); + } + } + + void SoundPlayerOpenAL::checkAlError(string message) { + int err = alGetError(); + if (err != AL_NO_ERROR) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "%s [%s]", message.c_str(), alGetString(err)); + //std::stringstream msg; + //msg << message.c_str() << alGetString(err); + printf("openal error [%s]\n", szBuf); + throw std::runtime_error(szBuf); + } + } - // try to find a stopped source - int playingCount = 0; - for(StaticSoundSources::iterator i = staticSources.begin(); - i != staticSources.end(); ++i) { - StaticSoundSource* source = *i; - if(! source->playing()) { - return source; - } - else { - playingCount++; } } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s %d] playingCount = %d, staticSources.size() = " MG_SIZE_T_SPECIFIER ", params.staticBufferCount = %u\n",__FILE__,__FUNCTION__,__LINE__,playingCount,(unsigned long)staticSources.size(),params.staticBufferCount); - - // create a new source - if(staticSources.size() >= params.staticBufferCount) { - return 0; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - StaticSoundSource* source = new StaticSoundSource(); - staticSources.push_back(source); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - return source; -} - -StreamSoundSource* SoundPlayerOpenAL::findStreamSoundSource() { - if(initOk == false) return NULL; - - // try to find a stopped source - for(StreamSoundSources::iterator i = streamSources.begin(); - i != streamSources.end(); ++i) { - StreamSoundSource* source = *i; - if(! source->playing()) { - return source; - } - } - - // create a new source - if(streamSources.size() >= params.strBufferCount) { - throw std::runtime_error("Too many stream sounds played at once"); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - StreamSoundSource* source = new StreamSoundSource(); - streamSources.push_back(source); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - - return source; -} - -void SoundPlayerOpenAL::checkAlcError(string message) { - int err = alcGetError(device); - if(err != ALC_NO_ERROR) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"%s [%s]",message.c_str(),alcGetString(device, err)); - - //std::stringstream msg; - //msg << message.c_str() << alcGetString(device, err); - printf("openalc error [%s]\n",szBuf); - throw std::runtime_error(szBuf); - } -} - -void SoundPlayerOpenAL::checkAlError(string message) { - int err = alGetError(); - if(err != AL_NO_ERROR) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"%s [%s]",message.c_str(),alGetString(err)); - //std::stringstream msg; - //msg << message.c_str() << alGetString(err); - printf("openal error [%s]\n",szBuf); - throw std::runtime_error(szBuf); - } -} - -}}} // end of namespace +} // end of namespace diff --git a/source/shared_lib/sources/sound/sound.cpp b/source/shared_lib/sources/sound/sound.cpp index 94b1e4cc2..b29b75c31 100644 --- a/source/shared_lib/sources/sound/sound.cpp +++ b/source/shared_lib/sources/sound/sound.cpp @@ -17,133 +17,135 @@ #include "leak_dumper.h" using namespace Shared::Util; -namespace Shared { namespace Sound { +namespace Shared { + namespace Sound { -//bool Sound::masterserverMode = false; + //bool Sound::masterserverMode = false; -// ===================================================== -// class SoundInfo -// ===================================================== + // ===================================================== + // class SoundInfo + // ===================================================== -SoundInfo::SoundInfo() { - channels= 0; - samplesPerSecond= 0; - bitsPerSample= 0; - size= 0; - bitRate=0; -} + SoundInfo::SoundInfo() { + channels = 0; + samplesPerSecond = 0; + bitsPerSample = 0; + size = 0; + bitRate = 0; + } -// ===================================================== -// class Sound -// ===================================================== + // ===================================================== + // class Sound + // ===================================================== -Sound::Sound() { - volume= 0.0f; - fileName = ""; - soundFileLoader = 0; -} + Sound::Sound() { + volume = 0.0f; + fileName = ""; + soundFileLoader = 0; + } -// ===================================================== -// class StaticSound -// ===================================================== + // ===================================================== + // class StaticSound + // ===================================================== -StaticSound::StaticSound() { - samples= NULL; - soundFileLoader = NULL; - fileName = ""; -} + StaticSound::StaticSound() { + samples = NULL; + soundFileLoader = NULL; + fileName = ""; + } -StaticSound::~StaticSound() { - close(); -} + StaticSound::~StaticSound() { + close(); + } + + void StaticSound::close() { + if (samples != NULL) { + delete[] samples; + samples = NULL; + } + + if (soundFileLoader != NULL) { + soundFileLoader->close(); + delete soundFileLoader; + soundFileLoader = NULL; + } + } + + void StaticSound::load(const string &path) { + close(); + + fileName = path; + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + string ext = (path.empty() == false ? path.substr(path.find_last_of('.') + 1) : ""); + soundFileLoader = SoundFileLoaderFactory::getInstance()->newInstance(ext); + + if (soundFileLoader == NULL) { + throw megaglest_runtime_error("soundFileLoader == NULL"); + } + soundFileLoader->open(path, &info); + samples = new int8[info.getSize()]; + soundFileLoader->read(samples, info.getSize()); + soundFileLoader->close(); + + delete soundFileLoader; + soundFileLoader = NULL; + } + + // ===================================================== + // class StrSound + // ===================================================== + + StrSound::StrSound() { + soundFileLoader = NULL; + next = NULL; + fileName = ""; + } + + StrSound::~StrSound() { + close(); + } + + void StrSound::open(const string &path) { + close(); + + fileName = path; + + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + string ext = (path.empty() == false ? path.substr(path.find_last_of('.') + 1) : ""); + + soundFileLoader = SoundFileLoaderFactory::getInstance()->newInstance(ext); + soundFileLoader->open(path, &info); + } + + uint32 StrSound::read(int8 *samples, uint32 size) { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return 0; + } + + return soundFileLoader->read(samples, size); + } + + void StrSound::close() { + if (soundFileLoader != NULL) { + soundFileLoader->close(); + delete soundFileLoader; + soundFileLoader = NULL; + } + } + + void StrSound::restart() { + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { + return; + } + + soundFileLoader->restart(); + } -void StaticSound::close() { - if(samples != NULL) { - delete [] samples; - samples = NULL; } - - if(soundFileLoader!=NULL){ - soundFileLoader->close(); - delete soundFileLoader; - soundFileLoader= NULL; - } -} - -void StaticSound::load(const string &path) { - close(); - - fileName = path; - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - string ext = (path.empty() == false ? path.substr(path.find_last_of('.')+1) : ""); - soundFileLoader= SoundFileLoaderFactory::getInstance()->newInstance(ext); - - if(soundFileLoader == NULL) { - throw megaglest_runtime_error("soundFileLoader == NULL"); - } - soundFileLoader->open(path, &info); - samples= new int8[info.getSize()]; - soundFileLoader->read(samples, info.getSize()); - soundFileLoader->close(); - - delete soundFileLoader; - soundFileLoader= NULL; -} - -// ===================================================== -// class StrSound -// ===================================================== - -StrSound::StrSound() { - soundFileLoader= NULL; - next= NULL; - fileName = ""; -} - -StrSound::~StrSound() { - close(); -} - -void StrSound::open(const string &path) { - close(); - - fileName = path; - - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - string ext = (path.empty() == false ? path.substr(path.find_last_of('.')+1) : ""); - - soundFileLoader= SoundFileLoaderFactory::getInstance()->newInstance(ext); - soundFileLoader->open(path, &info); -} - -uint32 StrSound::read(int8 *samples, uint32 size){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return 0; - } - - return soundFileLoader->read(samples, size); -} - -void StrSound::close(){ - if(soundFileLoader != NULL) { - soundFileLoader->close(); - delete soundFileLoader; - soundFileLoader= NULL; - } -} - -void StrSound::restart(){ - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - return; - } - - soundFileLoader->restart(); -} - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/sound/sound_file_loader.cpp b/source/shared_lib/sources/sound/sound_file_loader.cpp index ccf24ce49..a5f9b42ef 100644 --- a/source/shared_lib/sources/sound/sound_file_loader.cpp +++ b/source/shared_lib/sources/sound/sound_file_loader.cpp @@ -24,265 +24,266 @@ using namespace Shared::Platform; using namespace std; using namespace Shared::Util; -namespace Shared{ namespace Sound{ +namespace Shared { + namespace Sound { -// ===================================================== -// class WavSoundFileLoader -// ===================================================== + // ===================================================== + // class WavSoundFileLoader + // ===================================================== -void WavSoundFileLoader::open(const string &path, SoundInfo *soundInfo){ - char chunkId[]={'-', '-', '-', '-', '\0'}; - uint32 size32= 0; - uint16 size16= 0; - int count; - fileName = path; - - f.open(path.c_str(), ios_base::in | ios_base::binary); + void WavSoundFileLoader::open(const string &path, SoundInfo *soundInfo) { + char chunkId[] = { '-', '-', '-', '-', '\0' }; + uint32 size32 = 0; + uint16 size16 = 0; + int count; + fileName = path; - if(!f.is_open()){ - throw megaglest_runtime_error("Error opening wav file: "+ string(path),true); - } + f.open(path.c_str(), ios_base::in | ios_base::binary); - //RIFF chunk - Id - f.read(chunkId, 4); - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - for(unsigned int i = 0; i < 4; ++i) { - chunkId[i] = Shared::PlatformByteOrder::fromCommonEndian(chunkId[i]); - } - } + if (!f.is_open()) { + throw megaglest_runtime_error("Error opening wav file: " + string(path), true); + } - if(strcmp(chunkId, "RIFF")!=0){ - throw megaglest_runtime_error("Not a valid wav file (first four bytes are not RIFF):" + path,true); - } + //RIFF chunk - Id + f.read(chunkId, 4); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + for (unsigned int i = 0; i < 4; ++i) { + chunkId[i] = Shared::PlatformByteOrder::fromCommonEndian(chunkId[i]); + } + } - //RIFF chunk - Size - f.read((char*) &size32, 4); - if(bigEndianSystem == true) { - size32 = Shared::PlatformByteOrder::fromCommonEndian(size32); - } + if (strcmp(chunkId, "RIFF") != 0) { + throw megaglest_runtime_error("Not a valid wav file (first four bytes are not RIFF):" + path, true); + } - //RIFF chunk - Data (WAVE string) - f.read(chunkId, 4); - if(bigEndianSystem == true) { - for(unsigned int i = 0; i < 4; ++i) { - chunkId[i] = Shared::PlatformByteOrder::fromCommonEndian(chunkId[i]); - } - } - - if(strcmp(chunkId, "WAVE")!=0){ - throw megaglest_runtime_error("Not a valid wav file (wave data don't start by WAVE): " + path,true); - } + //RIFF chunk - Size + f.read((char*) &size32, 4); + if (bigEndianSystem == true) { + size32 = Shared::PlatformByteOrder::fromCommonEndian(size32); + } - // === HEADER === + //RIFF chunk - Data (WAVE string) + f.read(chunkId, 4); + if (bigEndianSystem == true) { + for (unsigned int i = 0; i < 4; ++i) { + chunkId[i] = Shared::PlatformByteOrder::fromCommonEndian(chunkId[i]); + } + } - //first sub-chunk (header) - Id - f.read(chunkId, 4); - if(bigEndianSystem == true) { - for(unsigned int i = 0; i < 4; ++i) { - chunkId[i] = Shared::PlatformByteOrder::fromCommonEndian(chunkId[i]); - } - } - - if(strcmp(chunkId, "fmt ")!=0){ - throw megaglest_runtime_error("Not a valid wav file (first sub-chunk Id is not fmt): "+ path,true); - } + if (strcmp(chunkId, "WAVE") != 0) { + throw megaglest_runtime_error("Not a valid wav file (wave data don't start by WAVE): " + path, true); + } - //first sub-chunk (header) - Size - f.read((char*) &size32, 4); - if(bigEndianSystem == true) { - size32 = Shared::PlatformByteOrder::fromCommonEndian(size32); - } + // === HEADER === - //first sub-chunk (header) - Data (encoding type) - Ignore - f.read((char*) &size16, 2); - if(bigEndianSystem == true) { - size16 = Shared::PlatformByteOrder::fromCommonEndian(size16); - } + //first sub-chunk (header) - Id + f.read(chunkId, 4); + if (bigEndianSystem == true) { + for (unsigned int i = 0; i < 4; ++i) { + chunkId[i] = Shared::PlatformByteOrder::fromCommonEndian(chunkId[i]); + } + } - //first sub-chunk (header) - Data (nChannels) - f.read((char*) &size16, 2); - if(bigEndianSystem == true) { - size16 = Shared::PlatformByteOrder::fromCommonEndian(size16); - } + if (strcmp(chunkId, "fmt ") != 0) { + throw megaglest_runtime_error("Not a valid wav file (first sub-chunk Id is not fmt): " + path, true); + } - soundInfo->setChannels(size16); + //first sub-chunk (header) - Size + f.read((char*) &size32, 4); + if (bigEndianSystem == true) { + size32 = Shared::PlatformByteOrder::fromCommonEndian(size32); + } - //first sub-chunk (header) - Data (nsamplesPerSecond) - f.read((char*) &size32, 4); - if(bigEndianSystem == true) { - size32 = Shared::PlatformByteOrder::fromCommonEndian(size32); - } + //first sub-chunk (header) - Data (encoding type) - Ignore + f.read((char*) &size16, 2); + if (bigEndianSystem == true) { + size16 = Shared::PlatformByteOrder::fromCommonEndian(size16); + } - soundInfo->setsamplesPerSecond(size32); + //first sub-chunk (header) - Data (nChannels) + f.read((char*) &size16, 2); + if (bigEndianSystem == true) { + size16 = Shared::PlatformByteOrder::fromCommonEndian(size16); + } - //first sub-chunk (header) - Data (nAvgBytesPerSec) - Ignore - f.read((char*) &size32, 4); - if(bigEndianSystem == true) { - size32 = Shared::PlatformByteOrder::fromCommonEndian(size32); - } + soundInfo->setChannels(size16); - //first sub-chunk (header) - Data (blockAlign) - Ignore - f.read((char*) &size16, 2); - if(bigEndianSystem == true) { - size16 = Shared::PlatformByteOrder::fromCommonEndian(size16); - } + //first sub-chunk (header) - Data (nsamplesPerSecond) + f.read((char*) &size32, 4); + if (bigEndianSystem == true) { + size32 = Shared::PlatformByteOrder::fromCommonEndian(size32); + } - //first sub-chunk (header) - Data (nsamplesPerSecond) - f.read((char*) &size16, 2); - if(bigEndianSystem == true) { - size16 = Shared::PlatformByteOrder::fromCommonEndian(size16); - } + soundInfo->setsamplesPerSecond(size32); - soundInfo->setBitsPerSample(size16); + //first sub-chunk (header) - Data (nAvgBytesPerSec) - Ignore + f.read((char*) &size32, 4); + if (bigEndianSystem == true) { + size32 = Shared::PlatformByteOrder::fromCommonEndian(size32); + } - soundInfo->setBitRate(soundInfo->getSamplesPerSecond() * soundInfo->getChannels() * soundInfo->getBitsPerSample() / 8); + //first sub-chunk (header) - Data (blockAlign) - Ignore + f.read((char*) &size16, 2); + if (bigEndianSystem == true) { + size16 = Shared::PlatformByteOrder::fromCommonEndian(size16); + } - if (soundInfo->getBitsPerSample() != 8 && soundInfo->getBitsPerSample()!=16){ - throw megaglest_runtime_error("Bits per sample must be 8 or 16: " + path,true); - } - bytesPerSecond= soundInfo->getBitsPerSample()*8*soundInfo->getSamplesPerSecond()*soundInfo->getChannels(); + //first sub-chunk (header) - Data (nsamplesPerSecond) + f.read((char*) &size16, 2); + if (bigEndianSystem == true) { + size16 = Shared::PlatformByteOrder::fromCommonEndian(size16); + } - count=0; - do{ - count++; + soundInfo->setBitsPerSample(size16); - // === DATA === - //second sub-chunk (samples) - Id - f.read(chunkId, 4); - if(bigEndianSystem == true) { - for(unsigned int i = 0; i < 4; ++i) { - chunkId[i] = Shared::PlatformByteOrder::fromCommonEndian(chunkId[i]); - } - } + soundInfo->setBitRate(soundInfo->getSamplesPerSecond() * soundInfo->getChannels() * soundInfo->getBitsPerSample() / 8); + + if (soundInfo->getBitsPerSample() != 8 && soundInfo->getBitsPerSample() != 16) { + throw megaglest_runtime_error("Bits per sample must be 8 or 16: " + path, true); + } + bytesPerSecond = soundInfo->getBitsPerSample() * 8 * soundInfo->getSamplesPerSecond()*soundInfo->getChannels(); + + count = 0; + do { + count++; + + // === DATA === + //second sub-chunk (samples) - Id + f.read(chunkId, 4); + if (bigEndianSystem == true) { + for (unsigned int i = 0; i < 4; ++i) { + chunkId[i] = Shared::PlatformByteOrder::fromCommonEndian(chunkId[i]); + } + } + + if (strncmp(chunkId, "data", 4) != 0) { + continue; + } + + //second sub-chunk (samples) - Size + f.read((char*) &size32, 4); + if (bigEndianSystem == true) { + size32 = Shared::PlatformByteOrder::fromCommonEndian(size32); + } + + dataSize = size32; + soundInfo->setSize(dataSize); + } while (strncmp(chunkId, "data", 4) != 0 && count < maxDataRetryCount); + + if (f.bad() || count == maxDataRetryCount) { + throw megaglest_runtime_error("Error reading samples: " + path, true); + } + + dataOffset = (uint32) f.tellg(); - if(strncmp(chunkId, "data", 4)!=0){ - continue; } - //second sub-chunk (samples) - Size - f.read((char*) &size32, 4); - if(bigEndianSystem == true) { - size32 = Shared::PlatformByteOrder::fromCommonEndian(size32); - } + uint32 WavSoundFileLoader::read(int8 *samples, uint32 size) { + f.read(reinterpret_cast (samples), size); + static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); + if (bigEndianSystem == true) { + Shared::PlatformByteOrder::toEndianTypeArray(samples, size); + } - dataSize= size32; - soundInfo->setSize(dataSize); - } - while(strncmp(chunkId, "data", 4)!=0 && count (samples), size); - static bool bigEndianSystem = Shared::PlatformByteOrder::isBigEndian(); - if(bigEndianSystem == true) { - Shared::PlatformByteOrder::toEndianTypeArray(samples,size); - } + OggSoundFileLoader::OggSoundFileLoader() { + vf = NULL; + f = NULL; + } - return (uint32)f.gcount(); -} - -void WavSoundFileLoader::close(){ - f.close(); -} - -void WavSoundFileLoader::restart(){ - f.seekg(dataOffset, ios_base::beg); -} - -// ======================================= -// Ogg Sound File Loader -// ======================================= - -OggSoundFileLoader::OggSoundFileLoader() { - vf = NULL; - f = NULL; -} - -void OggSoundFileLoader::open(const string &path, SoundInfo *soundInfo){ - fileName = path; + void OggSoundFileLoader::open(const string &path, SoundInfo *soundInfo) { + fileName = path; #ifdef WIN32 - f = _wfopen(utf8_decode(path).c_str(), L"rb"); + f = _wfopen(utf8_decode(path).c_str(), L"rb"); #else - f= fopen(path.c_str(), "rb"); + f = fopen(path.c_str(), "rb"); #endif - if(f==NULL){ - throw megaglest_runtime_error("Can't open ogg file: "+path,true); - } + if (f == NULL) { + throw megaglest_runtime_error("Can't open ogg file: " + path, true); + } - vf= new OggVorbis_File(); - if(vf==NULL) { - throw megaglest_runtime_error("Can't create ogg object for file: "+path,true); - } + vf = new OggVorbis_File(); + if (vf == NULL) { + throw megaglest_runtime_error("Can't create ogg object for file: " + path, true); + } - ov_open(f, vf, NULL, 0); + ov_open(f, vf, NULL, 0); - vorbis_info *vi= ov_info(vf, -1); - if(vi==NULL) { - throw megaglest_runtime_error("Can't read ogg header info for file: "+path,true); - } + vorbis_info *vi = ov_info(vf, -1); + if (vi == NULL) { + throw megaglest_runtime_error("Can't read ogg header info for file: " + path, true); + } - uint32 samples = static_cast(ov_pcm_total(vf, -1)); + uint32 samples = static_cast(ov_pcm_total(vf, -1)); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound,"In [%s::%s Line: %d] path = [%s] vi->version = %d, vi->channels = %d, vi->rate = %ld, vi->bitrate_upper = %ld, vi->bitrate_nominal = %ld, vi->bitrate_lower = %ld, vi->bitrate_window = %ld, samples = " MG_SIZE_T_SPECIFIER "\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),vi->version,vi->channels,vi->rate,vi->bitrate_upper,vi->bitrate_nominal,vi->bitrate_lower,vi->bitrate_window,samples); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSound, "In [%s::%s Line: %d] path = [%s] vi->version = %d, vi->channels = %d, vi->rate = %ld, vi->bitrate_upper = %ld, vi->bitrate_nominal = %ld, vi->bitrate_lower = %ld, vi->bitrate_window = %ld, samples = " MG_SIZE_T_SPECIFIER "\n", __FILE__, __FUNCTION__, __LINE__, path.c_str(), vi->version, vi->channels, vi->rate, vi->bitrate_upper, vi->bitrate_nominal, vi->bitrate_lower, vi->bitrate_window, samples); - soundInfo->setChannels(vi->channels); - soundInfo->setsamplesPerSecond(vi->rate); - soundInfo->setBitsPerSample(16); - soundInfo->setSize(samples * 2 * vi->channels); - soundInfo->setBitRate(vi->bitrate_nominal); -} - -uint32 OggSoundFileLoader::read(int8 *samples, uint32 size){ - int section; - int totalBytesRead= 0; - - while(size>0) { - int bytesRead= ov_read(vf, reinterpret_cast (samples), size, - 0, 2, 1, §ion); - if(bytesRead==0) { - break; + soundInfo->setChannels(vi->channels); + soundInfo->setsamplesPerSecond(vi->rate); + soundInfo->setBitsPerSample(16); + soundInfo->setSize(samples * 2 * vi->channels); + soundInfo->setBitRate(vi->bitrate_nominal); } - size-= bytesRead; - samples+= bytesRead; - totalBytesRead+= bytesRead; + + uint32 OggSoundFileLoader::read(int8 *samples, uint32 size) { + int section; + int totalBytesRead = 0; + + while (size > 0) { + int bytesRead = ov_read(vf, reinterpret_cast (samples), size, + 0, 2, 1, §ion); + if (bytesRead == 0) { + break; + } + size -= bytesRead; + samples += bytesRead; + totalBytesRead += bytesRead; + } + return totalBytesRead; + } + + void OggSoundFileLoader::close() { + if (vf != NULL) { + ov_clear(vf); + delete vf; + vf = 0; + } + //fclose(f); + } + + void OggSoundFileLoader::restart() { + ov_raw_seek(vf, 0); + } + + // ===================================================== + // class SoundFileLoaderFactory + // ===================================================== + + SoundFileLoaderFactory::SoundFileLoaderFactory() { + registerClass("wav"); + registerClass("ogg"); + } + + SoundFileLoaderFactory *SoundFileLoaderFactory::getInstance() { + static SoundFileLoaderFactory soundFileLoaderFactory; + return &soundFileLoaderFactory; + } + } - return totalBytesRead; -} - -void OggSoundFileLoader::close() { - if(vf != NULL) { - ov_clear(vf); - delete vf; - vf= 0; - } - //fclose(f); -} - -void OggSoundFileLoader::restart(){ - ov_raw_seek(vf, 0); -} - -// ===================================================== -// class SoundFileLoaderFactory -// ===================================================== - -SoundFileLoaderFactory::SoundFileLoaderFactory(){ - registerClass("wav"); - registerClass("ogg"); -} - -SoundFileLoaderFactory *SoundFileLoaderFactory::getInstance(){ - static SoundFileLoaderFactory soundFileLoaderFactory; - return &soundFileLoaderFactory; -} - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/sound/sound_interface.cpp b/source/shared_lib/sources/sound/sound_interface.cpp index 5240a2303..d135ef4ac 100644 --- a/source/shared_lib/sources/sound/sound_interface.cpp +++ b/source/shared_lib/sources/sound/sound_interface.cpp @@ -15,26 +15,28 @@ using namespace Shared::Util; -namespace Shared{ namespace Sound{ +namespace Shared { + namespace Sound { -// ===================================================== -// class SoundInterface -// ===================================================== + // ===================================================== + // class SoundInterface + // ===================================================== -SoundInterface &SoundInterface::getInstance(){ - static SoundInterface soundInterface; - return soundInterface; -} + SoundInterface &SoundInterface::getInstance() { + static SoundInterface soundInterface; + return soundInterface; + } -void SoundInterface::setFactory(SoundFactory *soundFactory){ - this->soundFactory= soundFactory; -} + void SoundInterface::setFactory(SoundFactory *soundFactory) { + this->soundFactory = soundFactory; + } -SoundPlayer *SoundInterface::newSoundPlayer(){ + SoundPlayer *SoundInterface::newSoundPlayer() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSound).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s %d]\n", __FILE__, __FUNCTION__, __LINE__); - return soundFactory->newSoundPlayer(); -} + return soundFactory->newSoundPlayer(); + } -}}//end namespace + } +}//end namespace diff --git a/source/shared_lib/sources/sound/sound_player.cpp b/source/shared_lib/sources/sound/sound_player.cpp index 91905513f..26263fa3a 100644 --- a/source/shared_lib/sources/sound/sound_player.cpp +++ b/source/shared_lib/sources/sound/sound_player.cpp @@ -13,16 +13,18 @@ #include "leak_dumper.h" -namespace Shared{ namespace Sound{ +namespace Shared { + namespace Sound { -// ===================================================== -// class SoundPlayerParams -// ===================================================== + // ===================================================== + // class SoundPlayerParams + // ===================================================== -SoundPlayerParams::SoundPlayerParams(){ - staticBufferCount= 8; - strBufferCount= 4; - strBufferSize= 44050*2*2*2; //2 second buffer -} + SoundPlayerParams::SoundPlayerParams() { + staticBufferCount = 8; + strBufferCount = 4; + strBufferSize = 44050 * 2 * 2 * 2; //2 second buffer + } -}}//end namespace + } +}//end namespace diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_acosf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_acosf.cpp index ca498a464..996513edb 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_acosf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_acosf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_acosf.c,v 1.5f 1995/05/12 04:57:16 jtc Exp $"; @@ -23,70 +23,70 @@ static char rcsid[] = "$NetBSD: e_acosf.c,v 1.5f 1995/05/12 04:57:16 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -one = 1.0000000000e+00f, /* 0x3F800000 */ -pi = 3.1415925026e+00f, /* 0x40490fda */ -pio2_hi = 1.5707962513e+00f, /* 0x3fc90fda */ -pio2_lo = 7.5497894159e-08f, /* 0x33a22168 */ -pS0 = 1.6666667163e-01f, /* 0x3e2aaaab */ -pS1 = -3.2556581497e-01f, /* 0xbea6b090 */ -pS2 = 2.0121252537e-01f, /* 0x3e4e0aa8 */ -pS3 = -4.0055535734e-02f, /* 0xbd241146 */ -pS4 = 7.9153501429e-04f, /* 0x3a4f7f04 */ -pS5 = 3.4793309169e-05f, /* 0x3811ef08 */ -qS1 = -2.4033949375e+00f, /* 0xc019d139 */ -qS2 = 2.0209457874e+00f, /* 0x4001572d */ -qS3 = -6.8828397989e-01f, /* 0xbf303361 */ -qS4 = 7.7038154006e-02f; /* 0x3d9dc62e */ + one = 1.0000000000e+00f, /* 0x3F800000 */ + pi = 3.1415925026e+00f, /* 0x40490fda */ + pio2_hi = 1.5707962513e+00f, /* 0x3fc90fda */ + pio2_lo = 7.5497894159e-08f, /* 0x33a22168 */ + pS0 = 1.6666667163e-01f, /* 0x3e2aaaab */ + pS1 = -3.2556581497e-01f, /* 0xbea6b090 */ + pS2 = 2.0121252537e-01f, /* 0x3e4e0aa8 */ + pS3 = -4.0055535734e-02f, /* 0xbd241146 */ + pS4 = 7.9153501429e-04f, /* 0x3a4f7f04 */ + pS5 = 3.4793309169e-05f, /* 0x3811ef08 */ + qS1 = -2.4033949375e+00f, /* 0xc019d139 */ + qS2 = 2.0209457874e+00f, /* 0x4001572d */ + qS3 = -6.8828397989e-01f, /* 0xbf303361 */ + qS4 = 7.7038154006e-02f; /* 0x3d9dc62e */ #ifdef __STDC__ Simple __ieee754_acosf(Simple x) #else Simple __ieee754_acosf(x) - Simple x; + Simple x; #endif -{ - Simple z,p,q,r,w,s,c,df; - int32_t hx,ix; - GET_FLOAT_WORD(hx,x); - ix = hx&0x7fffffff; - if(ix==0x3f800000) { /* |x|==1 */ - if(hx>0) return 0.0f; /* acos(1) = 0 */ - else return pi+(Simple)2.0f*pio2_lo; /* acos(-1)= pi */ - } else if(ix>0x3f800000) { /* |x| >= 1 */ - return (x-x)/(x-x); /* acos(|x|>1) is NaN */ - } - if(ix<0x3f000000) { /* |x| < 0.5f */ - if(ix<=0x23000000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/ - z = x*x; - p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); - q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); - r = p/q; - return pio2_hi - (x - (pio2_lo-x*r)); - } else if (hx<0) { /* x < -0.5f */ - z = (one+x)*(Simple)0.5f; - p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); - q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); - s = __ieee754_sqrtf(z); - r = p/q; - w = r*s-pio2_lo; - return pi - (Simple)2.0f*(s+w); - } else { /* x > 0.5f */ - int32_t idf; - z = (one-x)*(Simple)0.5f; - s = __ieee754_sqrtf(z); - df = s; - GET_FLOAT_WORD(idf,df); - SET_FLOAT_WORD(df,idf&0xfffff000); - c = (z-df*df)/(s+df); - p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); - q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); - r = p/q; - w = r*s+c; - return (Simple)2.0f*(df+w); + { + Simple z, p, q, r, w, s, c, df; + int32_t hx, ix; + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + if (ix == 0x3f800000) { /* |x|==1 */ + if (hx > 0) return 0.0f; /* acos(1) = 0 */ + else return pi + (Simple)2.0f*pio2_lo; /* acos(-1)= pi */ + } else if (ix > 0x3f800000) { /* |x| >= 1 */ + return (x - x) / (x - x); /* acos(|x|>1) is NaN */ + } + if (ix < 0x3f000000) { /* |x| < 0.5f */ + if (ix <= 0x23000000) return pio2_hi + pio2_lo;/*if|x|<2**-57*/ + z = x*x; + p = z*(pS0 + z*(pS1 + z*(pS2 + z*(pS3 + z*(pS4 + z*pS5))))); + q = one + z*(qS1 + z*(qS2 + z*(qS3 + z*qS4))); + r = p / q; + return pio2_hi - (x - (pio2_lo - x*r)); + } else if (hx < 0) { /* x < -0.5f */ + z = (one + x)*(Simple)0.5f; + p = z*(pS0 + z*(pS1 + z*(pS2 + z*(pS3 + z*(pS4 + z*pS5))))); + q = one + z*(qS1 + z*(qS2 + z*(qS3 + z*qS4))); + s = __ieee754_sqrtf(z); + r = p / q; + w = r*s - pio2_lo; + return pi - (Simple)2.0f*(s + w); + } else { /* x > 0.5f */ + int32_t idf; + z = (one - x)*(Simple)0.5f; + s = __ieee754_sqrtf(z); + df = s; + GET_FLOAT_WORD(idf, df); + SET_FLOAT_WORD(df, idf & 0xfffff000); + c = (z - df*df) / (s + df); + p = z*(pS0 + z*(pS1 + z*(pS2 + z*(pS3 + z*(pS4 + z*pS5))))); + q = one + z*(qS1 + z*(qS2 + z*(qS3 + z*qS4))); + r = p / q; + w = r*s + c; + return (Simple)2.0f*(df + w); + } } } -} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_acoshf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_acoshf.cpp index a5914596b..9d9763567 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_acoshf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_acoshf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_acoshf.c,v 1.5f 1995/05/12 04:57:20 jtc Exp $"; @@ -23,38 +23,38 @@ static char rcsid[] = "$NetBSD: e_acoshf.c,v 1.5f 1995/05/12 04:57:20 jtc Exp $" namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -one = 1.0f, -ln2 = 6.9314718246e-01f; /* 0x3f317218 */ + one = 1.0f, + ln2 = 6.9314718246e-01f; /* 0x3f317218 */ #ifdef __STDC__ Simple __ieee754_acoshf(Simple x) #else Simple __ieee754_acoshf(x) - Simple x; + Simple x; #endif -{ - Simple t; - int32_t hx; - GET_FLOAT_WORD(hx,x); - if(hx<0x3f800000) { /* x < 1 */ - return (x-x)/(x-x); - } else if(hx >=0x4d800000) { /* x > 2**28 */ - if(hx >=0x7f800000) { /* x is inf of NaN */ - return x+x; - } else - return __ieee754_logf(x)+ln2; /* acosh(huge)=log(2x) */ - } else if (hx==0x3f800000) { - return 0.0f; /* acosh(1) = 0 */ - } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ - t=x*x; - return __ieee754_logf((Simple)2.0f*x-one/(x+__ieee754_sqrtf(t-one))); - } else { /* 1= 0x4d800000) { /* x > 2**28 */ + if (hx >= 0x7f800000) { /* x is inf of NaN */ + return x + x; + } else + return __ieee754_logf(x) + ln2; /* acosh(huge)=log(2x) */ + } else if (hx == 0x3f800000) { + return 0.0f; /* acosh(1) = 0 */ + } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ + t = x*x; + return __ieee754_logf((Simple)2.0f*x - one / (x + __ieee754_sqrtf(t - one))); + } else { /* 1 - and are incorporated herein by permission of the author. The author - reserves the right to distribute this material elsewhere under different - copying permissions. These modifications are distributed here under - the following terms: + /* + Modifications for single precision expansion are + Copyright (C) 2001 Stephen L. Moshier + and are incorporated herein by permission of the author. The author + reserves the right to distribute this material elsewhere under different + copying permissions. These modifications are distributed here under + the following terms: - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1f of the License, or (at your option) any later version. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1f of the License, or (at your option) any later version. - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_asinf.c,v 1.5f 1995/05/12 04:57:25 jtc Exp $"; @@ -45,69 +45,69 @@ static char rcsid[] = "$NetBSD: e_asinf.c,v 1.5f 1995/05/12 04:57:25 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -one = 1.0000000000e+00f, /* 0x3F800000 */ -huge = 1.000e+30f, + one = 1.0000000000e+00f, /* 0x3F800000 */ + huge = 1.000e+30f, -pio2_hi = 1.57079637050628662109375f, -pio2_lo = -4.37113900018624283e-8f, -pio4_hi = 0.785398185253143310546875f, + pio2_hi = 1.57079637050628662109375f, + pio2_lo = -4.37113900018624283e-8f, + pio4_hi = 0.785398185253143310546875f, -/* asin x = x + x^3 p(x^2) - -0.5f <= x <= 0.5f; - Peak relative error 4.8e-9f */ -p0 = 1.666675248e-1f, -p1 = 7.495297643e-2f, -p2 = 4.547037598e-2f, -p3 = 2.417951451e-2f, -p4 = 4.216630880e-2f; + /* asin x = x + x^3 p(x^2) + -0.5f <= x <= 0.5f; + Peak relative error 4.8e-9f */ + p0 = 1.666675248e-1f, + p1 = 7.495297643e-2f, + p2 = 4.547037598e-2f, + p3 = 2.417951451e-2f, + p4 = 4.216630880e-2f; #ifdef __STDC__ Simple __ieee754_asinf(Simple x) #else Simple __ieee754_asinf(x) - Simple x; + Simple x; #endif -{ - Simple t,w,p,q,c,r,s; - int32_t hx,ix; - GET_FLOAT_WORD(hx,x); - ix = hx&0x7fffffff; - if(ix==0x3f800000) { - /* asin(1)=+-pi/2 with inexact */ - return x*pio2_hi+x*pio2_lo; - } else if(ix> 0x3f800000) { /* |x|>= 1 */ - return (x-x)/(x-x); /* asin(|x|>1) is NaN */ - } else if (ix<0x3f000000) { /* |x|<0.5f */ - if(ix<0x32000000) { /* if |x| < 2**-27 */ - if(huge+x>one) return x;/* return x with inexact if x!=0*/ - } else { - t = x*x; - w = t * (p0 + t * (p1 + t * (p2 + t * (p3 + t * p4)))); - return x+x*w; - } + { + Simple t, w, p, q, c, r, s; + int32_t hx, ix; + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + if (ix == 0x3f800000) { + /* asin(1)=+-pi/2 with inexact */ + return x*pio2_hi + x*pio2_lo; + } else if (ix > 0x3f800000) { /* |x|>= 1 */ + return (x - x) / (x - x); /* asin(|x|>1) is NaN */ + } else if (ix < 0x3f000000) { /* |x|<0.5f */ + if (ix < 0x32000000) { /* if |x| < 2**-27 */ + if (huge + x > one) return x;/* return x with inexact if x!=0*/ + } else { + t = x*x; + w = t * (p0 + t * (p1 + t * (p2 + t * (p3 + t * p4)))); + return x + x*w; + } + } + /* 1> |x|>= 0.5f */ + w = one - fabsf(x); + t = w*0.5f; + p = t * (p0 + t * (p1 + t * (p2 + t * (p3 + t * p4)))); + s = __ieee754_sqrtf(t); + if (ix >= 0x3F79999A) { /* if |x| > 0.975f */ + t = pio2_hi - (2.0f*(s + s*p) - pio2_lo); + } else { + int32_t iw; + w = s; + GET_FLOAT_WORD(iw, w); + SET_FLOAT_WORD(w, iw & 0xfffff000); + c = (t - w*w) / (s + w); + r = p; + p = 2.0f*s*r - (pio2_lo - 2.0f*c); + q = pio4_hi - 2.0f*w; + t = pio4_hi - (p - q); + } + if (hx > 0) return t; else return -t; } - /* 1> |x|>= 0.5f */ - w = one-fabsf(x); - t = w*0.5f; - p = t * (p0 + t * (p1 + t * (p2 + t * (p3 + t * p4)))); - s = __ieee754_sqrtf(t); - if(ix>=0x3F79999A) { /* if |x| > 0.975f */ - t = pio2_hi-(2.0f*(s+s*p)-pio2_lo); - } else { - int32_t iw; - w = s; - GET_FLOAT_WORD(iw,w); - SET_FLOAT_WORD(w,iw&0xfffff000); - c = (t-w*w)/(s+w); - r = p; - p = 2.0f*s*r-(pio2_lo-2.0f*c); - q = pio4_hi-2.0f*w; - t = pio4_hi-(p-q); - } - if(hx>0) return t; else return -t; -} } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_atan2f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_atan2f.cpp index 6b69a7237..17fb0e062 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_atan2f.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_atan2f.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_atan2f.c,v 1.4f 1995/05/10 20:44:53 jtc Exp $"; @@ -23,86 +23,86 @@ static char rcsid[] = "$NetBSD: e_atan2f.c,v 1.4f 1995/05/10 20:44:53 jtc Exp $" namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -tiny = 1.0e-30f, -zero = 0.0f, -pi_o_4 = 7.8539818525e-01f, /* 0x3f490fdb */ -pi_o_2 = 1.5707963705e+00f, /* 0x3fc90fdb */ -pi = 3.1415927410e+00f, /* 0x40490fdb */ -pi_lo = -8.7422776573e-08f; /* 0xb3bbbd2e */ + tiny = 1.0e-30f, + zero = 0.0f, + pi_o_4 = 7.8539818525e-01f, /* 0x3f490fdb */ + pi_o_2 = 1.5707963705e+00f, /* 0x3fc90fdb */ + pi = 3.1415927410e+00f, /* 0x40490fdb */ + pi_lo = -8.7422776573e-08f; /* 0xb3bbbd2e */ #ifdef __STDC__ Simple __ieee754_atan2f(Simple y, Simple x) #else - Simple __ieee754_atan2f(y,x) - Simple y,x; + Simple __ieee754_atan2f(y, x) + Simple y, x; #endif -{ - Simple z; - int32_t k,m,hx,hy,ix,iy; + { + Simple z; + int32_t k, m, hx, hy, ix, iy; - GET_FLOAT_WORD(hx,x); - ix = hx&0x7fffffff; - GET_FLOAT_WORD(hy,y); - iy = hy&0x7fffffff; - if((ix>0x7f800000)|| - (iy>0x7f800000)) /* x or y is NaN */ - return x+y; - if(hx==0x3f800000) return __atanf(y); /* x=1.0f */ - m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + GET_FLOAT_WORD(hy, y); + iy = hy & 0x7fffffff; + if ((ix > 0x7f800000) || + (iy > 0x7f800000)) /* x or y is NaN */ + return x + y; + if (hx == 0x3f800000) return __atanf(y); /* x=1.0f */ + m = ((hy >> 31) & 1) | ((hx >> 30) & 2); /* 2*sign(x)+sign(y) */ - /* when y = 0 */ - if(iy==0) { - switch(m) { - case 0: - case 1: return y; /* atan(+-0,+anything)=+-0 */ - case 2: return pi+tiny;/* atan(+0,-anything) = pi */ - case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */ - } - } - /* when x = 0 */ - if(ix==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; - - /* when x is INF */ - if(ix==0x7f800000) { - if(iy==0x7f800000) { - switch(m) { - case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */ - case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */ - case 2: return (Simple)3.0f*pi_o_4+tiny;/*atan(+INF,-INF)*/ - case 3: return (Simple)-3.0f*pi_o_4-tiny;/*atan(-INF,-INF)*/ + /* when y = 0 */ + if (iy == 0) { + switch (m) { + case 0: + case 1: return y; /* atan(+-0,+anything)=+-0 */ + case 2: return pi + tiny;/* atan(+0,-anything) = pi */ + case 3: return -pi - tiny;/* atan(-0,-anything) =-pi */ + } } - } else { - switch(m) { - case 0: return zero ; /* atan(+...,+INF) */ - case 1: return -zero ; /* atan(-...,+INF) */ - case 2: return pi+tiny ; /* atan(+...,-INF) */ - case 3: return -pi-tiny ; /* atan(-...,-INF) */ - } - } - } - /* when y is INF */ - if(iy==0x7f800000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; + /* when x = 0 */ + if (ix == 0) return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny; - /* compute y/x */ - k = (iy-ix)>>23; - if(k > 60) z=pi_o_2+(Simple)0.5f*pi_lo; /* |y/x| > 2**60 */ - else if(hx<0&&k<-60) z=0.0f; /* |y|/x < -2**60 */ - else z=__atanf(fabsf(y/x)); /* safe to do y/x */ - switch (m) { - case 0: return z ; /* atan(+,+) */ - case 1: { - u_int32_t zh; - GET_FLOAT_WORD(zh,z); - SET_FLOAT_WORD(z,zh ^ 0x80000000); - } - return z ; /* atan(-,+) */ - case 2: return pi-(z-pi_lo);/* atan(+,-) */ - default: /* case 3 */ - return (z-pi_lo)-pi;/* atan(-,-) */ + /* when x is INF */ + if (ix == 0x7f800000) { + if (iy == 0x7f800000) { + switch (m) { + case 0: return pi_o_4 + tiny;/* atan(+INF,+INF) */ + case 1: return -pi_o_4 - tiny;/* atan(-INF,+INF) */ + case 2: return (Simple)3.0f*pi_o_4 + tiny;/*atan(+INF,-INF)*/ + case 3: return (Simple) -3.0f*pi_o_4 - tiny;/*atan(-INF,-INF)*/ + } + } else { + switch (m) { + case 0: return zero; /* atan(+...,+INF) */ + case 1: return -zero; /* atan(-...,+INF) */ + case 2: return pi + tiny; /* atan(+...,-INF) */ + case 3: return -pi - tiny; /* atan(-...,-INF) */ + } + } + } + /* when y is INF */ + if (iy == 0x7f800000) return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny; + + /* compute y/x */ + k = (iy - ix) >> 23; + if (k > 60) z = pi_o_2 + (Simple)0.5f*pi_lo; /* |y/x| > 2**60 */ + else if (hx < 0 && k < -60) z = 0.0f; /* |y|/x < -2**60 */ + else z = __atanf(fabsf(y / x)); /* safe to do y/x */ + switch (m) { + case 0: return z; /* atan(+,+) */ + case 1: { + u_int32_t zh; + GET_FLOAT_WORD(zh, z); + SET_FLOAT_WORD(z, zh ^ 0x80000000); + } + return z; /* atan(-,+) */ + case 2: return pi - (z - pi_lo);/* atan(+,-) */ + default: /* case 3 */ + return (z - pi_lo) - pi;/* atan(-,-) */ + } } } -} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_atanhf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_atanhf.cpp index 88474a899..30503185a 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_atanhf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_atanhf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_atanhf.c,v 1.4f 1995/05/10 20:44:56 jtc Exp $"; @@ -23,39 +23,39 @@ static char rcsid[] = "$NetBSD: e_atanhf.c,v 1.4f 1995/05/10 20:44:56 jtc Exp $" namespace streflop_libm { #ifdef __STDC__ -static const Simple one = 1.0f, huge = 1e30f; + static const Simple one = 1.0f, huge = 1e30f; #else -static Simple one = 1.0f, huge = 1e30f; + static Simple one = 1.0f, huge = 1e30f; #endif #ifdef __STDC__ -static const Simple zero = 0.0f; + static const Simple zero = 0.0f; #else -static Simple zero = 0.0f; + static Simple zero = 0.0f; #endif #ifdef __STDC__ Simple __ieee754_atanhf(Simple x) #else Simple __ieee754_atanhf(x) - Simple x; + Simple x; #endif -{ - Simple t; - int32_t hx,ix; - GET_FLOAT_WORD(hx,x); - ix = hx&0x7fffffff; - if (ix>0x3f800000) /* |x|>1 */ - return (x-x)/(x-x); - if(ix==0x3f800000) - return x/zero; - if(ix<0x31800000&&(huge+x)>zero) return x; /* x<2**-28 */ - SET_FLOAT_WORD(x,ix); - if(ix<0x3f000000) { /* x < 0.5f */ - t = x+x; - t = (Simple)0.5f*__log1pf(t+t*x/(one-x)); - } else - t = (Simple)0.5f*__log1pf((x+x)/(one-x)); - if(hx>=0) return t; else return -t; -} + { + Simple t; + int32_t hx, ix; + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + if (ix > 0x3f800000) /* |x|>1 */ + return (x - x) / (x - x); + if (ix == 0x3f800000) + return x / zero; + if (ix<0x31800000 && (huge + x)>zero) return x; /* x<2**-28 */ + SET_FLOAT_WORD(x, ix); + if (ix < 0x3f000000) { /* x < 0.5f */ + t = x + x; + t = (Simple)0.5f*__log1pf(t + t*x / (one - x)); + } else + t = (Simple)0.5f*__log1pf((x + x) / (one - x)); + if (hx >= 0) return t; else return -t; + } } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_coshf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_coshf.cpp index 02502acf8..35f809043 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_coshf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_coshf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_coshf.c,v 1.6f 1996/04/08 15:43:41 phil Exp $"; @@ -23,53 +23,53 @@ static char rcsid[] = "$NetBSD: e_coshf.c,v 1.6f 1996/04/08 15:43:41 phil Exp $" namespace streflop_libm { #ifdef __STDC__ -static const Simple huge = 1.0e30f; -static const Simple one = 1.0f, half=0.5f; + static const Simple huge = 1.0e30f; + static const Simple one = 1.0f, half = 0.5f; #else -static Simple one = 1.0f, half=0.5f, huge = 1.0e30f; + static Simple one = 1.0f, half = 0.5f, huge = 1.0e30f; #endif #ifdef __STDC__ Simple __ieee754_coshf(Simple x) #else Simple __ieee754_coshf(x) - Simple x; + Simple x; #endif -{ - Simple t,w; - int32_t ix; + { + Simple t, w; + int32_t ix; - GET_FLOAT_WORD(ix,x); - ix &= 0x7fffffff; + GET_FLOAT_WORD(ix, x); + ix &= 0x7fffffff; - /* x is INF or NaN */ - if(ix>=0x7f800000) return x*x; + /* x is INF or NaN */ + if (ix >= 0x7f800000) return x*x; - /* |x| in [0,0.5f*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ - if(ix<0x3eb17218) { - t = __expm1f(fabsf(x)); - w = one+t; - if (ix<0x24000000) return w; /* cosh(tiny) = 1 */ - return one+(t*t)/(w+w); + /* |x| in [0,0.5f*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ + if (ix < 0x3eb17218) { + t = __expm1f(fabsf(x)); + w = one + t; + if (ix < 0x24000000) return w; /* cosh(tiny) = 1 */ + return one + (t*t) / (w + w); + } + + /* |x| in [0.5f*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ + if (ix < 0x41b00000) { + t = __ieee754_expf(fabsf(x)); + return half*t + half / t; + } + + /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ + if (ix < 0x42b17180) return half*__ieee754_expf(fabsf(x)); + + /* |x| in [log(maxdouble), overflowthresold] */ + if (ix <= 0x42b2d4fc) { + w = __ieee754_expf(half*fabsf(x)); + t = half*w; + return t*w; + } + + /* |x| > overflowthresold, cosh(x) overflow */ + return huge*huge; } - - /* |x| in [0.5f*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ - if (ix < 0x41b00000) { - t = __ieee754_expf(fabsf(x)); - return half*t+half/t; - } - - /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ - if (ix < 0x42b17180) return half*__ieee754_expf(fabsf(x)); - - /* |x| in [log(maxdouble), overflowthresold] */ - if (ix<=0x42b2d4fc) { - w = __ieee754_expf(half*fabsf(x)); - t = half*w; - return t*w; - } - - /* |x| > overflowthresold, cosh(x) overflow */ - return huge*huge; -} } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_exp2f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_exp2f.cpp index 8432cdca7..b1ad72c74 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_exp2f.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_exp2f.cpp @@ -19,13 +19,13 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -/* The basic design here is from - Shmuel Gal and Boris Bachelis, "An Accurate Elementary Mathematical - Library for the IEEE Floating Point Standard", ACM Trans. Math. Soft., - 17 (1), March 1991, pp. 26-45. - It has been slightly modified to compute 2^x instead of e^x, and for - single-precision. - */ + /* The basic design here is from + Shmuel Gal and Boris Bachelis, "An Accurate Elementary Mathematical + Library for the IEEE Floating Point Standard", ACM Trans. Math. Soft., + 17 (1), March 1991, pp. 26-45. + It has been slightly modified to compute 2^x instead of e^x, and for + single-precision. + */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif @@ -43,89 +43,85 @@ static const Simple TWOM100 = 7.88860905e-31f; static const Simple TWO127 = 1.7014118346e+38f; namespace streflop_libm { -Simple -__ieee754_exp2f (Simple x) -{ - static const Simple himark = (Simple) FLT_MAX_EXP; - static const Simple lomark = (Simple) (FLT_MIN_EXP - FLT_MANT_DIG - 1); + Simple + __ieee754_exp2f(Simple x) { + static const Simple himark = (Simple) FLT_MAX_EXP; + static const Simple lomark = (Simple) (FLT_MIN_EXP - FLT_MANT_DIG - 1); - /* Check for usual case. */ - if (isless (x, himark) && isgreaterequal (x, lomark)) - { - static const Simple THREEp14 = 49152.0f; - int tval, unsafe; - Simple rx, x22, result; - union ieee754_float ex2_u, scale_u; - fenv_t oldenv; + /* Check for usual case. */ + if (isless(x, himark) && isgreaterequal(x, lomark)) { + static const Simple THREEp14 = 49152.0f; + int tval, unsafe; + Simple rx, x22, result; + union ieee754_float ex2_u, scale_u; + fenv_t oldenv; - feholdexcept (&oldenv); + feholdexcept(&oldenv); #ifdef FE_TONEAREST - /* If we don't have this, it's too bad. */ - fesetround (FE_TONEAREST); + /* If we don't have this, it's too bad. */ + fesetround(FE_TONEAREST); #endif - /* 1. Argument reduction. - Choose integers ex, -128 <= t < 128, and some real - -1/512 <= x1 <= 1/512 so that - x = ex + t/512 + x1. + /* 1. Argument reduction. + Choose integers ex, -128 <= t < 128, and some real + -1/512 <= x1 <= 1/512 so that + x = ex + t/512 + x1. - First, calculate rx = ex + t/256. */ - rx = x + THREEp14; - rx -= THREEp14; - x -= rx; /* Compute x=x1. */ - /* Compute tval = (ex*256 + t)+128. - Now, t = (tval mod 256)-128 and ex=tval/256 [that's mod, NOT %; and - /-round-to-nearest not the usual c integer /]. */ - tval = (int) (rx * 256.0f + 128.0f); + First, calculate rx = ex + t/256. */ + rx = x + THREEp14; + rx -= THREEp14; + x -= rx; /* Compute x=x1. */ + /* Compute tval = (ex*256 + t)+128. + Now, t = (tval mod 256)-128 and ex=tval/256 [that's mod, NOT %; and + /-round-to-nearest not the usual c integer /]. */ + tval = (int) (rx * 256.0f + 128.0f); - /* 2. Adjust for accurate table entry. - Find e so that - x = ex + t/256 + e + x2 - where -7e-4 < e < 7e-4, and - (Simple)(2^(t/256+e)) - is accurate to one part in 2^-64. */ + /* 2. Adjust for accurate table entry. + Find e so that + x = ex + t/256 + e + x2 + where -7e-4 < e < 7e-4, and + (Simple)(2^(t/256+e)) + is accurate to one part in 2^-64. */ - /* 'tval & 255' is the same as 'tval%256' except that it's always - positive. - Compute x = x2. */ - x -= __exp2f_deltatable[tval & 255]; + /* 'tval & 255' is the same as 'tval%256' except that it's always + positive. + Compute x = x2. */ + x -= __exp2f_deltatable[tval & 255]; - /* 3. Compute ex2 = 2^(t/255+e+ex). */ - ex2_u.f() = __exp2f_atable[tval & 255]; - tval >>= 8; - unsafe = abs(tval) >= -FLT_MIN_EXP - 1; - ex2_u.ieee.exponent += tval >> unsafe; - scale_u.f() = 1.0f; - scale_u.ieee.exponent += tval - (tval >> unsafe); + /* 3. Compute ex2 = 2^(t/255+e+ex). */ + ex2_u.f() = __exp2f_atable[tval & 255]; + tval >>= 8; + unsafe = abs(tval) >= -FLT_MIN_EXP - 1; + ex2_u.ieee.exponent += tval >> unsafe; + scale_u.f() = 1.0f; + scale_u.ieee.exponent += tval - (tval >> unsafe); - /* 4. Approximate 2^x2 - 1, using a second-degree polynomial, - with maximum error in [-2^-9 - 2^-14, 2^-9 + 2^-14] - less than 1.3e-10f. */ + /* 4. Approximate 2^x2 - 1, using a second-degree polynomial, + with maximum error in [-2^-9 - 2^-14, 2^-9 + 2^-14] + less than 1.3e-10f. */ - x22 = (.24022656679f * x + .69314736128f) * ex2_u.f(); + x22 = (.24022656679f * x + .69314736128f) * ex2_u.f(); - /* 5. Return (2^x2-1) * 2^(t/512+e+ex) + 2^(t/512+e+ex). */ - fesetenv (&oldenv); + /* 5. Return (2^x2-1) * 2^(t/512+e+ex) + 2^(t/512+e+ex). */ + fesetenv(&oldenv); - result = x22 * x + ex2_u.f(); + result = x22 * x + ex2_u.f(); - if (!unsafe) - return result; - else - return result * scale_u.f(); - } - /* Exceptional cases: */ - else if (isless (x, himark)) - { - if (__isinff (x)) - /* e^-inf == 0, with no error. */ - return 0; - else - /* Underflow */ - return TWOM100 * TWOM100; - } - else - /* Return x, if x is a NaN or Inf; or overflow, otherwise. */ - return TWO127*x; -} + if (!unsafe) + return result; + else + return result * scale_u.f(); + } + /* Exceptional cases: */ + else if (isless(x, himark)) { + if (__isinff(x)) + /* e^-inf == 0, with no error. */ + return 0; + else + /* Underflow */ + return TWOM100 * TWOM100; + } else + /* Return x, if x is a NaN or Inf; or overflow, otherwise. */ + return TWO127*x; + } } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_expf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_expf.cpp index 8ac566e59..63213dc92 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_expf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_expf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_expf.c,v 1.6f 1996/04/08 15:43:43 phil Exp $"; @@ -25,83 +25,81 @@ static const Simple huge = 1.0e+30f; namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -one = 1.0f, -halF[2] = {0.5f,-0.5f,}, -twom100 = 7.8886090522e-31f, /* 2**-100=0x0d800000 */ -o_threshold= 8.8721679688e+01f, /* 0x42b17180 */ -u_threshold= -1.0397208405e+02f, /* 0xc2cff1b5 */ -ln2HI[2] ={ 6.9313812256e-01f, /* 0x3f317180 */ - -6.9313812256e-01f,}, /* 0xbf317180 */ -ln2LO[2] ={ 9.0580006145e-06f, /* 0x3717f7d1 */ - -9.0580006145e-06f,}, /* 0xb717f7d1 */ -invln2 = 1.4426950216e+00f, /* 0x3fb8aa3b */ -P1 = 1.6666667163e-01f, /* 0x3e2aaaab */ -P2 = -2.7777778450e-03f, /* 0xbb360b61 */ -P3 = 6.6137559770e-05f, /* 0x388ab355 */ -P4 = -1.6533901999e-06f, /* 0xb5ddea0e */ -P5 = 4.1381369442e-08f; /* 0x3331bb4c */ + one = 1.0f, + halF[2] = { 0.5f,-0.5f, }, + twom100 = 7.8886090522e-31f, /* 2**-100=0x0d800000 */ + o_threshold = 8.8721679688e+01f, /* 0x42b17180 */ + u_threshold = -1.0397208405e+02f, /* 0xc2cff1b5 */ + ln2HI[2] = { 6.9313812256e-01f, /* 0x3f317180 */ + -6.9313812256e-01f, }, /* 0xbf317180 */ + ln2LO[2] = { 9.0580006145e-06f, /* 0x3717f7d1 */ + -9.0580006145e-06f, }, /* 0xb717f7d1 */ + invln2 = 1.4426950216e+00f, /* 0x3fb8aa3b */ + P1 = 1.6666667163e-01f, /* 0x3e2aaaab */ + P2 = -2.7777778450e-03f, /* 0xbb360b61 */ + P3 = 6.6137559770e-05f, /* 0x388ab355 */ + P4 = -1.6533901999e-06f, /* 0xb5ddea0e */ + P5 = 4.1381369442e-08f; /* 0x3331bb4c */ #ifdef __STDC__ Simple __ieee754_expf(Simple x) /* default IEEE Double exp */ #else Simple __ieee754_expf(x) /* default IEEE Double exp */ - Simple x; + Simple x; #endif -{ - Simple y,hi,lo=0,c,t; - int32_t k=0,xsb=0; - u_int32_t hx; + { + Simple y, hi, lo = 0, c, t; + int32_t k = 0, xsb = 0; + u_int32_t hx; - GET_FLOAT_WORD(hx,x); - xsb = (hx>>31)&1; /* sign bit of x */ - hx &= 0x7fffffff; /* high word of |x| */ + GET_FLOAT_WORD(hx, x); + xsb = (hx >> 31) & 1; /* sign bit of x */ + hx &= 0x7fffffff; /* high word of |x| */ - /* filter out non-finite argument */ - if(hx >= 0x42b17218) { /* if |x|>=88.721f... */ - if(hx>0x7f800000) - return x+x; /* NaN */ - if(hx==0x7f800000) - return (xsb==0)? x:Simple(0.0f); /* exp(+-inf)={inf,0} */ - if(x > o_threshold) return huge*huge; /* overflow */ - if(x < u_threshold) return twom100*twom100; /* underflow */ - } + /* filter out non-finite argument */ + if (hx >= 0x42b17218) { /* if |x|>=88.721f... */ + if (hx > 0x7f800000) + return x + x; /* NaN */ + if (hx == 0x7f800000) + return (xsb == 0) ? x : Simple(0.0f); /* exp(+-inf)={inf,0} */ + if (x > o_threshold) return huge*huge; /* overflow */ + if (x < u_threshold) return twom100*twom100; /* underflow */ + } - /* argument reduction */ - if(hx > 0x3eb17218) { /* if |x| > 0.5f ln2 */ - if(hx < 0x3F851592) { /* and |x| < 1.5f ln2 */ - hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb; - } else { - k = invln2*x+halF[xsb]; - t = k; - hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */ - lo = t*ln2LO[0]; - } - x = hi - lo; - } - else if(hx < 0x31800000) { /* when |x|<2**-28 */ - if(huge+x>one) return one+x;/* trigger inexact */ - } - else k = 0; + /* argument reduction */ + if (hx > 0x3eb17218) { /* if |x| > 0.5f ln2 */ + if (hx < 0x3F851592) { /* and |x| < 1.5f ln2 */ + hi = x - ln2HI[xsb]; lo = ln2LO[xsb]; k = 1 - xsb - xsb; + } else { + k = invln2*x + halF[xsb]; + t = k; + hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */ + lo = t*ln2LO[0]; + } + x = hi - lo; + } else if (hx < 0x31800000) { /* when |x|<2**-28 */ + if (huge + x > one) return one + x;/* trigger inexact */ + } else k = 0; - /* x is now in primary range */ - t = x*x; - c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); - if(k==0) return one-((x*c)/(c-(Simple)2.0f)-x); - else y = one-((lo-(x*c)/((Simple)2.0f-c))-hi); - if(k >= -125) { - u_int32_t hy; - GET_FLOAT_WORD(hy,y); - SET_FLOAT_WORD(y,hy+(k<<23)); /* add k to y's exponent */ - return y; - } else { - u_int32_t hy; - GET_FLOAT_WORD(hy,y); - SET_FLOAT_WORD(y,hy+((k+100)<<23)); /* add k to y's exponent */ - return y*twom100; + /* x is now in primary range */ + t = x*x; + c = x - t*(P1 + t*(P2 + t*(P3 + t*(P4 + t*P5)))); + if (k == 0) return one - ((x*c) / (c - (Simple)2.0f) - x); + else y = one - ((lo - (x*c) / ((Simple)2.0f - c)) - hi); + if (k >= -125) { + u_int32_t hy; + GET_FLOAT_WORD(hy, y); + SET_FLOAT_WORD(y, hy + (k << 23)); /* add k to y's exponent */ + return y; + } else { + u_int32_t hy; + GET_FLOAT_WORD(hy, y); + SET_FLOAT_WORD(y, hy + ((k + 100) << 23)); /* add k to y's exponent */ + return y*twom100; + } } } -} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_fmodf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_fmodf.cpp index b17437575..b7a4037a8 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_fmodf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_fmodf.cpp @@ -3,22 +3,22 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_fmodf.c,v 1.4f 1995/05/10 20:45:10 jtc Exp $"; #endif -/* +/* * __ieee754_fmodf(x,y) * Return x mod y in exact arithmetic * Method: shift and subtract @@ -29,88 +29,91 @@ static char rcsid[] = "$NetBSD: e_fmodf.c,v 1.4f 1995/05/10 20:45:10 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static const Simple one = 1.0f, Zero[] = {0.0f, -0.0f,}; + static const Simple one = 1.0f, Zero[] = { 0.0f, -0.0f, }; #else -static Simple one = 1.0f, Zero[] = {0.0f, -0.0f,}; + static Simple one = 1.0f, Zero[] = { 0.0f, -0.0f, }; #endif #ifdef __STDC__ Simple __ieee754_fmodf(Simple x, Simple y) #else - Simple __ieee754_fmodf(x,y) - Simple x,y ; + Simple __ieee754_fmodf(x, y) + Simple x, y; #endif -{ - int32_t n,hx,hy,hz,ix,iy,sx,i; + { + int32_t n, hx, hy, hz, ix, iy, sx, i; - GET_FLOAT_WORD(hx,x); - GET_FLOAT_WORD(hy,y); - sx = hx&0x80000000; /* sign of x */ - hx ^=sx; /* |x| */ - hy &= 0x7fffffff; /* |y| */ + GET_FLOAT_WORD(hx, x); + GET_FLOAT_WORD(hy, y); + sx = hx & 0x80000000; /* sign of x */ + hx ^= sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ - /* purge off exception values */ - if(hy==0||(hx>=0x7f800000)|| /* y=0,or x not finite */ - (hy>0x7f800000)) /* or y is NaN */ - return (x*y)/(x*y); - if(hx>31]; /* |x|=|y| return x*0*/ + /* purge off exception values */ + if (hy == 0 || (hx >= 0x7f800000) || /* y=0,or x not finite */ + (hy > 0x7f800000)) /* or y is NaN */ + return (x*y) / (x*y); + if (hx < hy) return x; /* |x|<|y| return x */ + if (hx == hy) + return Zero[(u_int32_t) sx >> 31]; /* |x|=|y| return x*0*/ - /* determine ix = ilogb(x) */ - if(hx<0x00800000) { /* subnormal x */ - for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1; - } else ix = (hx>>23)-127; + /* determine ix = ilogb(x) */ + if (hx < 0x00800000) { /* subnormal x */ + for (ix = -126, i = (hx << 8); i > 0; i <<= 1) ix -= 1; + } else ix = (hx >> 23) - 127; - /* determine iy = ilogb(y) */ - if(hy<0x00800000) { /* subnormal y */ - for (iy = -126,i=(hy<<8); i>=0; i<<=1) iy -=1; - } else iy = (hy>>23)-127; + /* determine iy = ilogb(y) */ + if (hy < 0x00800000) { /* subnormal y */ + for (iy = -126, i = (hy << 8); i >= 0; i <<= 1) iy -= 1; + } else iy = (hy >> 23) - 127; - /* set up {hx,lx}, {hy,ly} and align y to x */ - if(ix >= -126) - hx = 0x00800000|(0x007fffff&hx); - else { /* subnormal x, shift x to normal */ - n = -126-ix; - hx = hx<= -126) + hx = 0x00800000 | (0x007fffff & hx); + else { /* subnormal x, shift x to normal */ + n = -126 - ix; + hx = hx << n; + } + if (iy >= -126) + hy = 0x00800000 | (0x007fffff & hy); + else { /* subnormal y, shift y to normal */ + n = -126 - iy; + hy = hy << n; + } + + /* fix point fmod */ + n = ix - iy; + while (n--) { + hz = hx - hy; + if (hz < 0) { + hx = hx + hx; + } else { + if (hz == 0) /* return sign(x)*0 */ + return Zero[(u_int32_t) sx >> 31]; + hx = hz + hz; + } + } + hz = hx - hy; + if (hz >= 0) { + hx = hz; + } + + /* convert back to floating value and restore the sign */ + if (hx == 0) /* return sign(x)*0 */ + return Zero[(u_int32_t) sx >> 31]; + while (hx < 0x00800000) { /* normalize x */ + hx = hx + hx; + iy -= 1; + } + if (iy >= -126) { /* normalize output */ + hx = ((hx - 0x00800000) | ((iy + 127) << 23)); + SET_FLOAT_WORD(x, hx | sx); + } else { /* subnormal output */ + n = -126 - iy; + hx >>= n; + SET_FLOAT_WORD(x, hx | sx); + x *= one; /* create necessary signal */ + } + return x; /* exact output */ } - if(iy >= -126) - hy = 0x00800000|(0x007fffff&hy); - else { /* subnormal y, shift y to normal */ - n = -126-iy; - hy = hy<>31]; - hx = hz+hz; - } - } - hz=hx-hy; - if(hz>=0) {hx=hz;} - - /* convert back to floating value and restore the sign */ - if(hx==0) /* return sign(x)*0 */ - return Zero[(u_int32_t)sx>>31]; - while(hx<0x00800000) { /* normalize x */ - hx = hx+hx; - iy -= 1; - } - if(iy>= -126) { /* normalize output */ - hx = ((hx-0x00800000)|((iy+127)<<23)); - SET_FLOAT_WORD(x,hx|sx); - } else { /* subnormal output */ - n = -126 - iy; - hx >>= n; - SET_FLOAT_WORD(x,hx|sx); - x *= one; /* create necessary signal */ - } - return x; /* exact output */ -} } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_gammaf_r.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_gammaf_r.cpp index 97450102a..7f296394c 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_gammaf_r.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_gammaf_r.cpp @@ -24,35 +24,31 @@ namespace streflop_libm { -Simple -__ieee754_gammaf_r (Simple x, int *signgamp) -{ - /* We don't have a real gamma implementation now. We'll use lgamma - and the exp function. But due to the required boundary - conditions we must check some values separately. */ - int32_t hx; + Simple + __ieee754_gammaf_r(Simple x, int *signgamp) { + /* We don't have a real gamma implementation now. We'll use lgamma + and the exp function. But due to the required boundary + conditions we must check some values separately. */ + int32_t hx; - GET_FLOAT_WORD (hx, x); + GET_FLOAT_WORD(hx, x); - if ((hx & 0x7fffffff) == 0) - { - /* Return value for x == 0 is Inf with divide by zero exception. */ - *signgamp = 0; - return 1.0f / x; - } - if (hx < 0 && (u_int32_t) hx < 0xff800000 && __rintf (x) == x) - { - /* Return value for integer x < 0 is NaN with invalid exception. */ - *signgamp = 0; - return (x - x) / (x - x); - } - if ((u_int32_t)hx == 0xff800000) - { - /* x == -Inf. According to ISO this is NaN. */ - *signgamp = 0; - return x - x; - } + if ((hx & 0x7fffffff) == 0) { + /* Return value for x == 0 is Inf with divide by zero exception. */ + *signgamp = 0; + return 1.0f / x; + } + if (hx < 0 && (u_int32_t) hx < 0xff800000 && __rintf(x) == x) { + /* Return value for integer x < 0 is NaN with invalid exception. */ + *signgamp = 0; + return (x - x) / (x - x); + } + if ((u_int32_t) hx == 0xff800000) { + /* x == -Inf. According to ISO this is NaN. */ + *signgamp = 0; + return x - x; + } - return __ieee754_expf (__ieee754_lgammaf_r (x, signgamp)); -} + return __ieee754_expf(__ieee754_lgammaf_r(x, signgamp)); + } } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_hypotf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_hypotf.cpp index 47c96ce56..ba49e93c7 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_hypotf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_hypotf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_hypotf.c,v 1.5f 1995/05/12 04:57:30 jtc Exp $"; @@ -25,66 +25,72 @@ namespace streflop_libm { #ifdef __STDC__ Simple __ieee754_hypotf(Simple x, Simple y) #else - Simple __ieee754_hypotf(x,y) - Simple x, y; + Simple __ieee754_hypotf(x, y) + Simple x, y; #endif -{ - Simple a,b,t1,t2,y1,y2,w; - int32_t j,k,ha,hb; + { + Simple a, b, t1, t2, y1, y2, w; + int32_t j, k, ha, hb; - GET_FLOAT_WORD(ha,x); - ha &= 0x7fffffff; - GET_FLOAT_WORD(hb,y); - hb &= 0x7fffffff; - if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} - SET_FLOAT_WORD(a,ha); /* a <- |a| */ - SET_FLOAT_WORD(b,hb); /* b <- |b| */ - if((ha-hb)>0xf000000) {return a+b;} /* x/y > 2**30 */ - k=0; - if(ha > 0x58800000) { /* a>2**50 */ - if(ha >= 0x7f800000) { /* Inf or NaN */ - w = a+b; /* for sNaN */ - if(ha == 0x7f800000) w = a; - if(hb == 0x7f800000) w = b; - return w; - } - /* scale a and b by 2**-60 */ - ha -= 0x1e000000; hb -= 0x1e000000; k += 60; - SET_FLOAT_WORD(a,ha); - SET_FLOAT_WORD(b,hb); + GET_FLOAT_WORD(ha, x); + ha &= 0x7fffffff; + GET_FLOAT_WORD(hb, y); + hb &= 0x7fffffff; + if (hb > ha) { + a = y; b = x; j = ha; ha = hb; hb = j; + } else { + a = x; b = y; + } + SET_FLOAT_WORD(a, ha); /* a <- |a| */ + SET_FLOAT_WORD(b, hb); /* b <- |b| */ + if ((ha - hb) > 0xf000000) { + return a + b; + } /* x/y > 2**30 */ + k = 0; + if (ha > 0x58800000) { /* a>2**50 */ + if (ha >= 0x7f800000) { /* Inf or NaN */ + w = a + b; /* for sNaN */ + if (ha == 0x7f800000) w = a; + if (hb == 0x7f800000) w = b; + return w; + } + /* scale a and b by 2**-60 */ + ha -= 0x1e000000; hb -= 0x1e000000; k += 60; + SET_FLOAT_WORD(a, ha); + SET_FLOAT_WORD(b, hb); + } + if (hb < 0x26800000) { /* b < 2**-50 */ + if (hb <= 0x007fffff) { /* subnormal b or 0 */ + if (hb == 0) return a; + SET_FLOAT_WORD(t1, 0x7e800000); /* t1=2^126 */ + b *= t1; + a *= t1; + k -= 126; + } else { /* scale a and b by 2^60 */ + ha += 0x1e000000; /* a *= 2^60 */ + hb += 0x1e000000; /* b *= 2^60 */ + k -= 60; + SET_FLOAT_WORD(a, ha); + SET_FLOAT_WORD(b, hb); + } + } + /* medium size a and b */ + w = a - b; + if (w > b) { + SET_FLOAT_WORD(t1, ha & 0xfffff000); + t2 = a - t1; + w = __ieee754_sqrtf(t1*t1 - (b*(-b) - t2*(a + t1))); + } else { + a = a + a; + SET_FLOAT_WORD(y1, hb & 0xfffff000); + y2 = b - y1; + SET_FLOAT_WORD(t1, ha + 0x00800000); + t2 = a - t1; + w = __ieee754_sqrtf(t1*y1 - (w*(-w) - (t1*y2 + t2*b))); + } + if (k != 0) { + SET_FLOAT_WORD(t1, 0x3f800000 + (k << 23)); + return t1*w; + } else return w; } - if(hb < 0x26800000) { /* b < 2**-50 */ - if(hb <= 0x007fffff) { /* subnormal b or 0 */ - if(hb==0) return a; - SET_FLOAT_WORD(t1,0x7e800000); /* t1=2^126 */ - b *= t1; - a *= t1; - k -= 126; - } else { /* scale a and b by 2^60 */ - ha += 0x1e000000; /* a *= 2^60 */ - hb += 0x1e000000; /* b *= 2^60 */ - k -= 60; - SET_FLOAT_WORD(a,ha); - SET_FLOAT_WORD(b,hb); - } - } - /* medium size a and b */ - w = a-b; - if (w>b) { - SET_FLOAT_WORD(t1,ha&0xfffff000); - t2 = a-t1; - w = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1))); - } else { - a = a+a; - SET_FLOAT_WORD(y1,hb&0xfffff000); - y2 = b - y1; - SET_FLOAT_WORD(t1,ha+0x00800000); - t2 = a - t1; - w = __ieee754_sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b))); - } - if(k!=0) { - SET_FLOAT_WORD(t1,0x3f800000+(k<<23)); - return t1*w; - } else return w; -} } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_j0f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_j0f.cpp index d814476fa..4ced5b0dc 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_j0f.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_j0f.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_j0f.c,v 1.4f 1995/05/10 20:45:25 jtc Exp $"; @@ -23,427 +23,437 @@ static char rcsid[] = "$NetBSD: e_j0f.c,v 1.4f 1995/05/10 20:45:25 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static Simple pzerof(Simple), qzerof(Simple); + static Simple pzerof(Simple), qzerof(Simple); #else -static Simple pzerof(), qzerof(); + static Simple pzerof(), qzerof(); #endif #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -huge = 1e30f, -one = 1.0f, -invsqrtpi= 5.6418961287e-01f, /* 0x3f106ebb */ -tpi = 6.3661974669e-01f, /* 0x3f22f983 */ - /* R0/S0 on [0, 2.00f] */ -R02 = 1.5625000000e-02f, /* 0x3c800000 */ -R03 = -1.8997929874e-04f, /* 0xb947352e */ -R04 = 1.8295404516e-06f, /* 0x35f58e88 */ -R05 = -4.6183270541e-09f, /* 0xb19eaf3c */ -S01 = 1.5619102865e-02f, /* 0x3c7fe744 */ -S02 = 1.1692678527e-04f, /* 0x38f53697 */ -S03 = 5.1354652442e-07f, /* 0x3509daa6 */ -S04 = 1.1661400734e-09f; /* 0x30a045e8 */ + huge = 1e30f, + one = 1.0f, + invsqrtpi = 5.6418961287e-01f, /* 0x3f106ebb */ + tpi = 6.3661974669e-01f, /* 0x3f22f983 */ + /* R0/S0 on [0, 2.00f] */ + R02 = 1.5625000000e-02f, /* 0x3c800000 */ + R03 = -1.8997929874e-04f, /* 0xb947352e */ + R04 = 1.8295404516e-06f, /* 0x35f58e88 */ + R05 = -4.6183270541e-09f, /* 0xb19eaf3c */ + S01 = 1.5619102865e-02f, /* 0x3c7fe744 */ + S02 = 1.1692678527e-04f, /* 0x38f53697 */ + S03 = 5.1354652442e-07f, /* 0x3509daa6 */ + S04 = 1.1661400734e-09f; /* 0x30a045e8 */ #ifdef __STDC__ -static const Simple zero = 0.0f; + static const Simple zero = 0.0f; #else -static Simple zero = 0.0f; + static Simple zero = 0.0f; #endif #ifdef __STDC__ Simple __ieee754_j0f(Simple x) #else Simple __ieee754_j0f(x) - Simple x; + Simple x; #endif -{ - Simple z, s,c,ss,cc,r,u,v; - int32_t hx,ix; + { + Simple z, s, c, ss, cc, r, u, v; + int32_t hx, ix; - GET_FLOAT_WORD(hx,x); - ix = hx&0x7fffffff; - if(ix>=0x7f800000) return one/(x*x); - x = fabsf(x); - if(ix >= 0x40000000) { /* |x| >= 2.0f */ - __sincosf (x, &s, &c); - ss = s-c; - cc = s+c; - if(ix<0x7f000000) { /* make sure x+x not overflow */ - z = -__cosf(x+x); - if ((s*c)= 0x7f800000) return one / (x*x); + x = fabsf(x); + if (ix >= 0x40000000) { /* |x| >= 2.0f */ + __sincosf(x, &s, &c); + ss = s - c; + cc = s + c; + if (ix < 0x7f000000) { /* make sure x+x not overflow */ + z = -__cosf(x + x); + if ((s*c) < zero) cc = z / ss; + else ss = z / cc; + } + /* + * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) + * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) + */ + if (ix > 0x48000000) z = (invsqrtpi*cc) / __ieee754_sqrtf(x); + else { + u = pzerof(x); v = qzerof(x); + z = invsqrtpi*(u*cc - v*ss) / __ieee754_sqrtf(x); + } + return z; } - /* - * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) - * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) - */ - if(ix>0x48000000) z = (invsqrtpi*cc)/__ieee754_sqrtf(x); - else { - u = pzerof(x); v = qzerof(x); - z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrtf(x); + if (ix < 0x39000000) { /* |x| < 2**-13 */ + if (huge + x > one) { /* raise inexact if x != 0 */ + if (ix < 0x32000000) return one; /* |x|<2**-27 */ + else return one - (Simple)0.25f*x*x; + } + } + z = x*x; + r = z*(R02 + z*(R03 + z*(R04 + z*R05))); + s = one + z*(S01 + z*(S02 + z*(S03 + z*S04))); + if (ix < 0x3F800000) { /* |x| < 1.00f */ + return one + z*((Simple) -0.25f + (r / s)); + } else { + u = (Simple)0.5f*x; + return((one + u)*(one - u) + z*(r / s)); } - return z; } - if(ix<0x39000000) { /* |x| < 2**-13 */ - if(huge+x>one) { /* raise inexact if x != 0 */ - if(ix<0x32000000) return one; /* |x|<2**-27 */ - else return one - (Simple)0.25f*x*x; - } - } - z = x*x; - r = z*(R02+z*(R03+z*(R04+z*R05))); - s = one+z*(S01+z*(S02+z*(S03+z*S04))); - if(ix < 0x3F800000) { /* |x| < 1.00f */ - return one + z*((Simple)-0.25f+(r/s)); - } else { - u = (Simple)0.5f*x; - return((one+u)*(one-u)+z*(r/s)); - } -} #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -u00 = -7.3804296553e-02f, /* 0xbd9726b5 */ -u01 = 1.7666645348e-01f, /* 0x3e34e80d */ -u02 = -1.3818567619e-02f, /* 0xbc626746 */ -u03 = 3.4745343146e-04f, /* 0x39b62a69 */ -u04 = -3.8140706238e-06f, /* 0xb67ff53c */ -u05 = 1.9559013964e-08f, /* 0x32a802ba */ -u06 = -3.9820518410e-11f, /* 0xae2f21eb */ -v01 = 1.2730483897e-02f, /* 0x3c509385 */ -v02 = 7.6006865129e-05f, /* 0x389f65e0 */ -v03 = 2.5915085189e-07f, /* 0x348b216c */ -v04 = 4.4111031494e-10f; /* 0x2ff280c2 */ + u00 = -7.3804296553e-02f, /* 0xbd9726b5 */ + u01 = 1.7666645348e-01f, /* 0x3e34e80d */ + u02 = -1.3818567619e-02f, /* 0xbc626746 */ + u03 = 3.4745343146e-04f, /* 0x39b62a69 */ + u04 = -3.8140706238e-06f, /* 0xb67ff53c */ + u05 = 1.9559013964e-08f, /* 0x32a802ba */ + u06 = -3.9820518410e-11f, /* 0xae2f21eb */ + v01 = 1.2730483897e-02f, /* 0x3c509385 */ + v02 = 7.6006865129e-05f, /* 0x389f65e0 */ + v03 = 2.5915085189e-07f, /* 0x348b216c */ + v04 = 4.4111031494e-10f; /* 0x2ff280c2 */ #ifdef __STDC__ Simple __ieee754_y0f(Simple x) #else Simple __ieee754_y0f(x) - Simple x; + Simple x; #endif -{ - Simple z, s,c,ss,cc,u,v; - int32_t hx,ix; + { + Simple z, s, c, ss, cc, u, v; + int32_t hx, ix; - GET_FLOAT_WORD(hx,x); - ix = 0x7fffffff&hx; - /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0, y0(0) is -inf. */ - if(ix>=0x7f800000) return one/(x+x*x); - if(ix==0) return -HUGE_VALF+x; /* -inf and overflow exception. */ - if(hx<0) return zero/(zero*x); - if(ix >= 0x40000000) { /* |x| >= 2.0f */ - /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) - * where x0 = x-pi/4 - * Better formula: - * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) - * = 1/sqrt(2) * (sin(x) + cos(x)) - * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) - * = 1/sqrt(2) * (sin(x) - cos(x)) - * To avoid cancellation, use - * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) - * to compute the worse one. - */ - __sincosf (x, &s, &c); - ss = s-c; - cc = s+c; - /* - * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) - * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) + GET_FLOAT_WORD(hx, x); + ix = 0x7fffffff & hx; + /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0, y0(0) is -inf. */ + if (ix >= 0x7f800000) return one / (x + x*x); + if (ix == 0) return -HUGE_VALF + x; /* -inf and overflow exception. */ + if (hx < 0) return zero / (zero*x); + if (ix >= 0x40000000) { /* |x| >= 2.0f */ + /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) + * where x0 = x-pi/4 + * Better formula: + * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) + * = 1/sqrt(2) * (sin(x) + cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + __sincosf(x, &s, &c); + ss = s - c; + cc = s + c; + /* + * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) + * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) + */ + if (ix < 0x7f000000) { /* make sure x+x not overflow */ + z = -__cosf(x + x); + if ((s*c) < zero) cc = z / ss; + else ss = z / cc; + } + if (ix > 0x48000000) z = (invsqrtpi*ss) / __ieee754_sqrtf(x); + else { + u = pzerof(x); v = qzerof(x); + z = invsqrtpi*(u*ss + v*cc) / __ieee754_sqrtf(x); + } + return z; + } + if (ix <= 0x32000000) { /* x < 2**-27 */ + return(u00 + tpi*__ieee754_logf(x)); + } + z = x*x; + u = u00 + z*(u01 + z*(u02 + z*(u03 + z*(u04 + z*(u05 + z*u06))))); + v = one + z*(v01 + z*(v02 + z*(v03 + z*v04))); + return(u / v + tpi*(__ieee754_j0f(x)*__ieee754_logf(x))); + } + + /* The asymptotic expansions of pzero is + * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x. + * For x >= 2, We approximate pzero by + * pzero(x) = 1 + (R/S) + * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10 + * S = 1 + pS0*s^2 + ... + pS4*s^10 + * and + * | pzero(x)-1-R/S | <= 2 ** ( -60.26f) */ - if(ix<0x7f000000) { /* make sure x+x not overflow */ - z = -__cosf(x+x); - if ((s*c)0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrtf(x); - else { - u = pzerof(x); v = qzerof(x); - z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrtf(x); - } - return z; - } - if(ix<=0x32000000) { /* x < 2**-27 */ - return(u00 + tpi*__ieee754_logf(x)); - } - z = x*x; - u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); - v = one+z*(v01+z*(v02+z*(v03+z*v04))); - return(u/v + tpi*(__ieee754_j0f(x)*__ieee754_logf(x))); +#ifdef __STDC__ + static const Simple pR8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ + #else + static Simple pR8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ + #endif + 0.0000000000e+00f, /* 0x00000000 */ + -7.0312500000e-02f, /* 0xbd900000 */ + -8.0816707611e+00f, /* 0xc1014e86 */ + -2.5706311035e+02f, /* 0xc3808814 */ + -2.4852163086e+03f, /* 0xc51b5376 */ + -5.2530439453e+03f, /* 0xc5a4285a */ + }; + #ifdef __STDC__ + static const Simple pS8[5] = { + #else + static Simple pS8[5] = { + #endif + 1.1653436279e+02f, /* 0x42e91198 */ + 3.8337448730e+03f, /* 0x456f9beb */ + 4.0597855469e+04f, /* 0x471e95db */ + 1.1675296875e+05f, /* 0x47e4087c */ + 4.7627726562e+04f, /* 0x473a0bba */ + }; + #ifdef __STDC__ + static const Simple pR5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ + #else + static Simple pR5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ + #endif + - 1.1412546255e-11f, /* 0xad48c58a */ + -7.0312492549e-02f, /* 0xbd8fffff */ + -4.1596107483e+00f, /* 0xc0851b88 */ + -6.7674766541e+01f, /* 0xc287597b */ + -3.3123129272e+02f, /* 0xc3a59d9b */ + -3.4643338013e+02f, /* 0xc3ad3779 */ + }; + #ifdef __STDC__ + static const Simple pS5[5] = { + #else + static Simple pS5[5] = { + #endif + 6.0753936768e+01f, /* 0x42730408 */ + 1.0512523193e+03f, /* 0x44836813 */ + 5.9789707031e+03f, /* 0x45bad7c4 */ + 9.6254453125e+03f, /* 0x461665c8 */ + 2.4060581055e+03f, /* 0x451660ee */ + }; + + #ifdef __STDC__ + static const Simple pR3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ + #else + static Simple pR3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ + #endif + - 2.5470459075e-09f, /* 0xb12f081b */ + -7.0311963558e-02f, /* 0xbd8fffb8 */ + -2.4090321064e+00f, /* 0xc01a2d95 */ + -2.1965976715e+01f, /* 0xc1afba52 */ + -5.8079170227e+01f, /* 0xc2685112 */ + -3.1447946548e+01f, /* 0xc1fb9565 */ + }; + #ifdef __STDC__ + static const Simple pS3[5] = { + #else + static Simple pS3[5] = { + #endif + 3.5856033325e+01f, /* 0x420f6c94 */ + 3.6151397705e+02f, /* 0x43b4c1ca */ + 1.1936077881e+03f, /* 0x44953373 */ + 1.1279968262e+03f, /* 0x448cffe6 */ + 1.7358093262e+02f, /* 0x432d94b8 */ + }; + + #ifdef __STDC__ + static const Simple pR2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ + #else + static Simple pR2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ + #endif + - 8.8753431271e-08f, /* 0xb3be98b7 */ + -7.0303097367e-02f, /* 0xbd8ffb12 */ + -1.4507384300e+00f, /* 0xbfb9b1cc */ + -7.6356959343e+00f, /* 0xc0f4579f */ + -1.1193166733e+01f, /* 0xc1331736 */ + -3.2336456776e+00f, /* 0xc04ef40d */ + }; + #ifdef __STDC__ + static const Simple pS2[5] = { + #else + static Simple pS2[5] = { + #endif + 2.2220300674e+01f, /* 0x41b1c32d */ + 1.3620678711e+02f, /* 0x430834f0 */ + 2.7047027588e+02f, /* 0x43873c32 */ + 1.5387539673e+02f, /* 0x4319e01a */ + 1.4657617569e+01f, /* 0x416a859a */ + }; + + #ifdef __STDC__ + static Simple pzerof(Simple x) + #else + static Simple pzerof(x) + Simple x; + #endif + { + #ifdef __STDC__ + const Simple *p = 0,*q = 0; + #else + Simple *p = 0,*q = 0; + #endif + Simple z,r,s; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + if (ix >= 0x41000000) { + p = pR8; q = pS8; +} else if (ix >= 0x40f71c58) { +p = pR5; q = pS5; +} else if (ix >= 0x4036db68) { +p = pR3; q = pS3; +} else if (ix >= 0x40000000) { +p = pR2; q = pS2; } - -/* The asymptotic expansions of pzero is - * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x. - * For x >= 2, We approximate pzero by - * pzero(x) = 1 + (R/S) - * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10 - * S = 1 + pS0*s^2 + ... + pS4*s^10 - * and - * | pzero(x)-1-R/S | <= 2 ** ( -60.26f) - */ -#ifdef __STDC__ -static const Simple pR8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ -#else -static Simple pR8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ -#endif - 0.0000000000e+00f, /* 0x00000000 */ - -7.0312500000e-02f, /* 0xbd900000 */ - -8.0816707611e+00f, /* 0xc1014e86 */ - -2.5706311035e+02f, /* 0xc3808814 */ - -2.4852163086e+03f, /* 0xc51b5376 */ - -5.2530439453e+03f, /* 0xc5a4285a */ -}; -#ifdef __STDC__ -static const Simple pS8[5] = { -#else -static Simple pS8[5] = { -#endif - 1.1653436279e+02f, /* 0x42e91198 */ - 3.8337448730e+03f, /* 0x456f9beb */ - 4.0597855469e+04f, /* 0x471e95db */ - 1.1675296875e+05f, /* 0x47e4087c */ - 4.7627726562e+04f, /* 0x473a0bba */ -}; -#ifdef __STDC__ -static const Simple pR5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ -#else -static Simple pR5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ -#endif - -1.1412546255e-11f, /* 0xad48c58a */ - -7.0312492549e-02f, /* 0xbd8fffff */ - -4.1596107483e+00f, /* 0xc0851b88 */ - -6.7674766541e+01f, /* 0xc287597b */ - -3.3123129272e+02f, /* 0xc3a59d9b */ - -3.4643338013e+02f, /* 0xc3ad3779 */ -}; -#ifdef __STDC__ -static const Simple pS5[5] = { -#else -static Simple pS5[5] = { -#endif - 6.0753936768e+01f, /* 0x42730408 */ - 1.0512523193e+03f, /* 0x44836813 */ - 5.9789707031e+03f, /* 0x45bad7c4 */ - 9.6254453125e+03f, /* 0x461665c8 */ - 2.4060581055e+03f, /* 0x451660ee */ -}; - -#ifdef __STDC__ -static const Simple pR3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ -#else -static Simple pR3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ -#endif - -2.5470459075e-09f, /* 0xb12f081b */ - -7.0311963558e-02f, /* 0xbd8fffb8 */ - -2.4090321064e+00f, /* 0xc01a2d95 */ - -2.1965976715e+01f, /* 0xc1afba52 */ - -5.8079170227e+01f, /* 0xc2685112 */ - -3.1447946548e+01f, /* 0xc1fb9565 */ -}; -#ifdef __STDC__ -static const Simple pS3[5] = { -#else -static Simple pS3[5] = { -#endif - 3.5856033325e+01f, /* 0x420f6c94 */ - 3.6151397705e+02f, /* 0x43b4c1ca */ - 1.1936077881e+03f, /* 0x44953373 */ - 1.1279968262e+03f, /* 0x448cffe6 */ - 1.7358093262e+02f, /* 0x432d94b8 */ -}; - -#ifdef __STDC__ -static const Simple pR2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ -#else -static Simple pR2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ -#endif - -8.8753431271e-08f, /* 0xb3be98b7 */ - -7.0303097367e-02f, /* 0xbd8ffb12 */ - -1.4507384300e+00f, /* 0xbfb9b1cc */ - -7.6356959343e+00f, /* 0xc0f4579f */ - -1.1193166733e+01f, /* 0xc1331736 */ - -3.2336456776e+00f, /* 0xc04ef40d */ -}; -#ifdef __STDC__ -static const Simple pS2[5] = { -#else -static Simple pS2[5] = { -#endif - 2.2220300674e+01f, /* 0x41b1c32d */ - 1.3620678711e+02f, /* 0x430834f0 */ - 2.7047027588e+02f, /* 0x43873c32 */ - 1.5387539673e+02f, /* 0x4319e01a */ - 1.4657617569e+01f, /* 0x416a859a */ -}; - -#ifdef __STDC__ - static Simple pzerof(Simple x) -#else - static Simple pzerof(x) - Simple x; -#endif -{ -#ifdef __STDC__ - const Simple *p=0,*q=0; -#else - Simple *p=0,*q=0; -#endif - Simple z,r,s; - int32_t ix; - GET_FLOAT_WORD(ix,x); - ix &= 0x7fffffff; - if(ix>=0x41000000) {p = pR8; q= pS8;} - else if(ix>=0x40f71c58){p = pR5; q= pS5;} - else if(ix>=0x4036db68){p = pR3; q= pS3;} - else if(ix>=0x40000000){p = pR2; q= pS2;} - //else throw std::exception("unknown state for pointers p and q!"); - else throw "unknown state for pointers p and q!"; - z = one/(x*x); - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); - return one+ r/s; +//else throw std::exception("unknown state for pointers p and q!"); +else throw "unknown state for pointers p and q!"; +z = one / (x*x); +r = p[0] + z*(p[1] + z*(p[2] + z*(p[3] + z*(p[4] + z*p[5])))); +s = one + z*(q[0] + z*(q[1] + z*(q[2] + z*(q[3] + z*q[4])))); +return one + r / s; } -/* For x >= 8, the asymptotic expansions of qzero is - * -1/8 s + 75/1024 s^3 - ..., where s = 1/x. - * We approximate pzero by - * qzero(x) = s*(-1.25f + (R/S)) - * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10 - * S = 1 + qS0*s^2 + ... + qS5*s^12 - * and - * | qzero(x)/s +1.25f-R/S | <= 2 ** ( -61.22f) - */ -#ifdef __STDC__ -static const Simple qR8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ -#else -static Simple qR8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ -#endif - 0.0000000000e+00f, /* 0x00000000 */ - 7.3242187500e-02f, /* 0x3d960000 */ - 1.1768206596e+01f, /* 0x413c4a93 */ - 5.5767340088e+02f, /* 0x440b6b19 */ - 8.8591972656e+03f, /* 0x460a6cca */ - 3.7014625000e+04f, /* 0x471096a0 */ -}; -#ifdef __STDC__ -static const Simple qS8[6] = { -#else -static Simple qS8[6] = { -#endif - 1.6377603149e+02f, /* 0x4323c6aa */ - 8.0983447266e+03f, /* 0x45fd12c2 */ - 1.4253829688e+05f, /* 0x480b3293 */ - 8.0330925000e+05f, /* 0x49441ed4 */ - 8.4050156250e+05f, /* 0x494d3359 */ - -3.4389928125e+05f, /* 0xc8a7eb69 */ -}; + /* For x >= 8, the asymptotic expansions of qzero is + * -1/8 s + 75/1024 s^3 - ..., where s = 1/x. + * We approximate pzero by + * qzero(x) = s*(-1.25f + (R/S)) + * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10 + * S = 1 + qS0*s^2 + ... + qS5*s^12 + * and + * | qzero(x)/s +1.25f-R/S | <= 2 ** ( -61.22f) + */ + #ifdef __STDC__ + static const Simple qR8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ + #else + static Simple qR8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ + #endif + 0.0000000000e+00f, /* 0x00000000 */ + 7.3242187500e-02f, /* 0x3d960000 */ + 1.1768206596e+01f, /* 0x413c4a93 */ + 5.5767340088e+02f, /* 0x440b6b19 */ + 8.8591972656e+03f, /* 0x460a6cca */ + 3.7014625000e+04f, /* 0x471096a0 */ + }; + #ifdef __STDC__ + static const Simple qS8[6] = { + #else + static Simple qS8[6] = { + #endif + 1.6377603149e+02f, /* 0x4323c6aa */ + 8.0983447266e+03f, /* 0x45fd12c2 */ + 1.4253829688e+05f, /* 0x480b3293 */ + 8.0330925000e+05f, /* 0x49441ed4 */ + 8.4050156250e+05f, /* 0x494d3359 */ + -3.4389928125e+05f, /* 0xc8a7eb69 */ + }; -#ifdef __STDC__ -static const Simple qR5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ -#else -static Simple qR5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ -#endif - 1.8408595828e-11f, /* 0x2da1ec79 */ - 7.3242180049e-02f, /* 0x3d95ffff */ - 5.8356351852e+00f, /* 0x40babd86 */ - 1.3511157227e+02f, /* 0x43071c90 */ - 1.0272437744e+03f, /* 0x448067cd */ - 1.9899779053e+03f, /* 0x44f8bf4b */ -}; -#ifdef __STDC__ -static const Simple qS5[6] = { -#else -static Simple qS5[6] = { -#endif - 8.2776611328e+01f, /* 0x42a58da0 */ - 2.0778142090e+03f, /* 0x4501dd07 */ - 1.8847289062e+04f, /* 0x46933e94 */ - 5.6751113281e+04f, /* 0x475daf1d */ - 3.5976753906e+04f, /* 0x470c88c1 */ - -5.3543427734e+03f, /* 0xc5a752be */ -}; + #ifdef __STDC__ + static const Simple qR5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ + #else + static Simple qR5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ + #endif + 1.8408595828e-11f, /* 0x2da1ec79 */ + 7.3242180049e-02f, /* 0x3d95ffff */ + 5.8356351852e+00f, /* 0x40babd86 */ + 1.3511157227e+02f, /* 0x43071c90 */ + 1.0272437744e+03f, /* 0x448067cd */ + 1.9899779053e+03f, /* 0x44f8bf4b */ + }; + #ifdef __STDC__ + static const Simple qS5[6] = { + #else + static Simple qS5[6] = { + #endif + 8.2776611328e+01f, /* 0x42a58da0 */ + 2.0778142090e+03f, /* 0x4501dd07 */ + 1.8847289062e+04f, /* 0x46933e94 */ + 5.6751113281e+04f, /* 0x475daf1d */ + 3.5976753906e+04f, /* 0x470c88c1 */ + -5.3543427734e+03f, /* 0xc5a752be */ + }; -#ifdef __STDC__ -static const Simple qR3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ -#else -static Simple qR3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ -#endif - 4.3774099900e-09f, /* 0x3196681b */ - 7.3241114616e-02f, /* 0x3d95ff70 */ - 3.3442313671e+00f, /* 0x405607e3 */ - 4.2621845245e+01f, /* 0x422a7cc5 */ - 1.7080809021e+02f, /* 0x432acedf */ - 1.6673394775e+02f, /* 0x4326bbe4 */ -}; -#ifdef __STDC__ -static const Simple qS3[6] = { -#else -static Simple qS3[6] = { -#endif - 4.8758872986e+01f, /* 0x42430916 */ - 7.0968920898e+02f, /* 0x44316c1c */ - 3.7041481934e+03f, /* 0x4567825f */ - 6.4604252930e+03f, /* 0x45c9e367 */ - 2.5163337402e+03f, /* 0x451d4557 */ - -1.4924745178e+02f, /* 0xc3153f59 */ -}; + #ifdef __STDC__ + static const Simple qR3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ + #else + static Simple qR3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ + #endif + 4.3774099900e-09f, /* 0x3196681b */ + 7.3241114616e-02f, /* 0x3d95ff70 */ + 3.3442313671e+00f, /* 0x405607e3 */ + 4.2621845245e+01f, /* 0x422a7cc5 */ + 1.7080809021e+02f, /* 0x432acedf */ + 1.6673394775e+02f, /* 0x4326bbe4 */ + }; + #ifdef __STDC__ + static const Simple qS3[6] = { + #else + static Simple qS3[6] = { + #endif + 4.8758872986e+01f, /* 0x42430916 */ + 7.0968920898e+02f, /* 0x44316c1c */ + 3.7041481934e+03f, /* 0x4567825f */ + 6.4604252930e+03f, /* 0x45c9e367 */ + 2.5163337402e+03f, /* 0x451d4557 */ + -1.4924745178e+02f, /* 0xc3153f59 */ + }; -#ifdef __STDC__ -static const Simple qR2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ -#else -static Simple qR2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ -#endif - 1.5044444979e-07f, /* 0x342189db */ - 7.3223426938e-02f, /* 0x3d95f62a */ - 1.9981917143e+00f, /* 0x3fffc4bf */ - 1.4495602608e+01f, /* 0x4167edfd */ - 3.1666231155e+01f, /* 0x41fd5471 */ - 1.6252708435e+01f, /* 0x4182058c */ -}; -#ifdef __STDC__ -static const Simple qS2[6] = { -#else -static Simple qS2[6] = { -#endif - 3.0365585327e+01f, /* 0x41f2ecb8 */ - 2.6934811401e+02f, /* 0x4386ac8f */ - 8.4478375244e+02f, /* 0x44533229 */ - 8.8293585205e+02f, /* 0x445cbbe5 */ - 2.1266638184e+02f, /* 0x4354aa98 */ - -5.3109550476e+00f, /* 0xc0a9f358 */ -}; + #ifdef __STDC__ + static const Simple qR2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ + #else + static Simple qR2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ + #endif + 1.5044444979e-07f, /* 0x342189db */ + 7.3223426938e-02f, /* 0x3d95f62a */ + 1.9981917143e+00f, /* 0x3fffc4bf */ + 1.4495602608e+01f, /* 0x4167edfd */ + 3.1666231155e+01f, /* 0x41fd5471 */ + 1.6252708435e+01f, /* 0x4182058c */ + }; + #ifdef __STDC__ + static const Simple qS2[6] = { + #else + static Simple qS2[6] = { + #endif + 3.0365585327e+01f, /* 0x41f2ecb8 */ + 2.6934811401e+02f, /* 0x4386ac8f */ + 8.4478375244e+02f, /* 0x44533229 */ + 8.8293585205e+02f, /* 0x445cbbe5 */ + 2.1266638184e+02f, /* 0x4354aa98 */ + -5.3109550476e+00f, /* 0xc0a9f358 */ + }; -#ifdef __STDC__ - static Simple qzerof(Simple x) -#else - static Simple qzerof(x) - Simple x; -#endif -{ -#ifdef __STDC__ - const Simple *p=0,*q=0; -#else - Simple *p=0,*q=0; -#endif - Simple s,r,z; - int32_t ix; - GET_FLOAT_WORD(ix,x); - ix &= 0x7fffffff; - if(ix>=0x41000000) {p = qR8; q= qS8;} - else if(ix>=0x40f71c58){p = qR5; q= qS5;} - else if(ix>=0x4036db68){p = qR3; q= qS3;} - else if(ix>=0x40000000){p = qR2; q= qS2;} - //else throw std::exception("unknown state for pointer p!"); - else throw "unknown state for pointers p and q!"; - z = one/(x*x); - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); - return (-(Simple).125f + r/s)/x; + #ifdef __STDC__ + static Simple qzerof(Simple x) + #else + static Simple qzerof(x) + Simple x; + #endif + { + #ifdef __STDC__ + const Simple *p = 0,*q = 0; + #else + Simple *p = 0,*q = 0; + #endif + Simple s,r,z; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + if (ix >= 0x41000000) { + p = qR8; q = qS8; +} else if (ix >= 0x40f71c58) { +p = qR5; q = qS5; +} else if (ix >= 0x4036db68) { +p = qR3; q = qS3; +} else if (ix >= 0x40000000) { +p = qR2; q = qS2; +} +//else throw std::exception("unknown state for pointer p!"); +else throw "unknown state for pointers p and q!"; +z = one / (x*x); +r = p[0] + z*(p[1] + z*(p[2] + z*(p[3] + z*(p[4] + z*p[5])))); +s = one + z*(q[0] + z*(q[1] + z*(q[2] + z*(q[3] + z*(q[4] + z*q[5]))))); +return (-(Simple).125f + r / s) / x; } } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_j1f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_j1f.cpp index eaa7573be..542f336f3 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_j1f.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_j1f.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_j1f.c,v 1.4f 1995/05/10 20:45:31 jtc Exp $"; @@ -23,427 +23,437 @@ static char rcsid[] = "$NetBSD: e_j1f.c,v 1.4f 1995/05/10 20:45:31 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static Simple ponef(Simple), qonef(Simple); + static Simple ponef(Simple), qonef(Simple); #else -static Simple ponef(), qonef(); + static Simple ponef(), qonef(); #endif #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -huge = 1e30f, -one = 1.0f, -invsqrtpi= 5.6418961287e-01f, /* 0x3f106ebb */ -tpi = 6.3661974669e-01f, /* 0x3f22f983 */ - /* R0/S0 on [0,2] */ -r00 = -6.2500000000e-02f, /* 0xbd800000 */ -r01 = 1.4070566976e-03f, /* 0x3ab86cfd */ -r02 = -1.5995563444e-05f, /* 0xb7862e36 */ -r03 = 4.9672799207e-08f, /* 0x335557d2 */ -s01 = 1.9153760746e-02f, /* 0x3c9ce859 */ -s02 = 1.8594678841e-04f, /* 0x3942fab6 */ -s03 = 1.1771846857e-06f, /* 0x359dffc2 */ -s04 = 5.0463624390e-09f, /* 0x31ad6446 */ -s05 = 1.2354227016e-11f; /* 0x2d59567e */ + huge = 1e30f, + one = 1.0f, + invsqrtpi = 5.6418961287e-01f, /* 0x3f106ebb */ + tpi = 6.3661974669e-01f, /* 0x3f22f983 */ + /* R0/S0 on [0,2] */ + r00 = -6.2500000000e-02f, /* 0xbd800000 */ + r01 = 1.4070566976e-03f, /* 0x3ab86cfd */ + r02 = -1.5995563444e-05f, /* 0xb7862e36 */ + r03 = 4.9672799207e-08f, /* 0x335557d2 */ + s01 = 1.9153760746e-02f, /* 0x3c9ce859 */ + s02 = 1.8594678841e-04f, /* 0x3942fab6 */ + s03 = 1.1771846857e-06f, /* 0x359dffc2 */ + s04 = 5.0463624390e-09f, /* 0x31ad6446 */ + s05 = 1.2354227016e-11f; /* 0x2d59567e */ #ifdef __STDC__ -static const Simple zero = 0.0f; + static const Simple zero = 0.0f; #else -static Simple zero = 0.0f; + static Simple zero = 0.0f; #endif #ifdef __STDC__ Simple __ieee754_j1f(Simple x) #else Simple __ieee754_j1f(x) - Simple x; + Simple x; #endif -{ - Simple z, s,c,ss,cc,r,u,v,y; - int32_t hx,ix; + { + Simple z, s, c, ss, cc, r, u, v, y; + int32_t hx, ix; - GET_FLOAT_WORD(hx,x); - ix = hx&0x7fffffff; - if(ix>=0x7f800000) return one/x; - y = fabsf(x); - if(ix >= 0x40000000) { /* |x| >= 2.0f */ - __sincosf (y, &s, &c); - ss = -s-c; - cc = s-c; - if(ix<0x7f000000) { /* make sure y+y not overflow */ - z = __cosf(y+y); - if ((s*c)>zero) cc = z/ss; - else ss = z/cc; + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + if (ix >= 0x7f800000) return one / x; + y = fabsf(x); + if (ix >= 0x40000000) { /* |x| >= 2.0f */ + __sincosf(y, &s, &c); + ss = -s - c; + cc = s - c; + if (ix < 0x7f000000) { /* make sure y+y not overflow */ + z = __cosf(y + y); + if ((s*c) > zero) cc = z / ss; + else ss = z / cc; + } + /* + * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) + * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) + */ + if (ix > 0x48000000) z = (invsqrtpi*cc) / __ieee754_sqrtf(y); + else { + u = ponef(y); v = qonef(y); + z = invsqrtpi*(u*cc - v*ss) / __ieee754_sqrtf(y); + } + if (hx < 0) return -z; + else return z; } - /* - * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) - * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) + if (ix < 0x32000000) { /* |x|<2**-27 */ + if (huge + x > one) return (Simple)0.5f*x;/* inexact if x!=0 necessary */ + } + z = x*x; + r = z*(r00 + z*(r01 + z*(r02 + z*r03))); + s = one + z*(s01 + z*(s02 + z*(s03 + z*(s04 + z*s05)))); + r *= x; + return(x*(Simple)0.5f + r / s); + } + +#ifdef __STDC__ + static const Simple U0[5] = { + #else + static Simple U0[5] = { + #endif + - 1.9605709612e-01f, /* 0xbe48c331 */ + 5.0443872809e-02f, /* 0x3d4e9e3c */ + -1.9125689287e-03f, /* 0xbafaaf2a */ + 2.3525259166e-05f, /* 0x37c5581c */ + -9.1909917899e-08f, /* 0xb3c56003 */ + }; + #ifdef __STDC__ + static const Simple V0[5] = { + #else + static Simple V0[5] = { + #endif + 1.9916731864e-02f, /* 0x3ca3286a */ + 2.0255257550e-04f, /* 0x3954644b */ + 1.3560879779e-06f, /* 0x35b602d4 */ + 6.2274145840e-09f, /* 0x31d5f8eb */ + 1.6655924903e-11f, /* 0x2d9281cf */ + }; + + #ifdef __STDC__ + Simple __ieee754_y1f(Simple x) + #else + Simple __ieee754_y1f(x) + Simple x; + #endif + { + Simple z, s,c,ss,cc,u,v; + int32_t hx,ix; + + GET_FLOAT_WORD(hx,x); + ix = 0x7fffffff & hx; + /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ + if (ix >= 0x7f800000) return one / (x + x*x); + if (ix == 0) return -HUGE_VALF + x; /* -inf and overflow exception. */ + if (hx < 0) return zero / (zero*x); + if (ix >= 0x40000000) { /* |x| >= 2.0f */ + __sincosf(x, &s, &c); + ss = -s - c; + cc = s - c; + if (ix < 0x7f000000) { /* make sure x+x not overflow */ + z = __cosf(x + x); + if ((s*c) > zero) cc = z / ss; + else ss = z / cc; + } + /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) + * where x0 = x-3pi/4 + * Better formula: + * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = -1/sqrt(2) * (cos(x) + sin(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + if (ix > 0x48000000) z = (invsqrtpi*ss) / __ieee754_sqrtf(x); + else { + u = ponef(x); v = qonef(x); + z = invsqrtpi*(u*ss + v*cc) / __ieee754_sqrtf(x); + } + return z; + } + if (ix <= 0x24800000) { /* x < 2**-54 */ + return(-tpi / x); + } + z = x*x; + u = U0[0] + z*(U0[1] + z*(U0[2] + z*(U0[3] + z*U0[4]))); + v = one + z*(V0[0] + z*(V0[1] + z*(V0[2] + z*(V0[3] + z*V0[4])))); + return(x*(u / v) + tpi*(__ieee754_j1f(x)*__ieee754_logf(x) - one / x)); + } + + /* For x >= 8, the asymptotic expansions of pone is + * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x. + * We approximate pone by + * pone(x) = 1 + (R/S) + * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10 + * S = 1 + ps0*s^2 + ... + ps4*s^10 + * and + * | pone(x)-1-R/S | <= 2 ** ( -60.06f) */ - if(ix>0x48000000) z = (invsqrtpi*cc)/__ieee754_sqrtf(y); - else { - u = ponef(y); v = qonef(y); - z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrtf(y); - } - if(hx<0) return -z; - else return z; - } - if(ix<0x32000000) { /* |x|<2**-27 */ - if(huge+x>one) return (Simple)0.5f*x;/* inexact if x!=0 necessary */ - } - z = x*x; - r = z*(r00+z*(r01+z*(r02+z*r03))); - s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05)))); - r *= x; - return(x*(Simple)0.5f+r/s); + + #ifdef __STDC__ + static const Simple pr8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ + #else + static Simple pr8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ + #endif + 0.0000000000e+00f, /* 0x00000000 */ + 1.1718750000e-01f, /* 0x3df00000 */ + 1.3239480972e+01f, /* 0x4153d4ea */ + 4.1205184937e+02f, /* 0x43ce06a3 */ + 3.8747453613e+03f, /* 0x45722bed */ + 7.9144794922e+03f, /* 0x45f753d6 */ + }; + #ifdef __STDC__ + static const Simple ps8[5] = { + #else + static Simple ps8[5] = { + #endif + 1.1420736694e+02f, /* 0x42e46a2c */ + 3.6509309082e+03f, /* 0x45642ee5 */ + 3.6956207031e+04f, /* 0x47105c35 */ + 9.7602796875e+04f, /* 0x47bea166 */ + 3.0804271484e+04f, /* 0x46f0a88b */ + }; + + #ifdef __STDC__ + static const Simple pr5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ + #else + static Simple pr5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ + #endif + 1.3199052094e-11f, /* 0x2d68333f */ + 1.1718749255e-01f, /* 0x3defffff */ + 6.8027510643e+00f, /* 0x40d9b023 */ + 1.0830818176e+02f, /* 0x42d89dca */ + 5.1763616943e+02f, /* 0x440168b7 */ + 5.2871520996e+02f, /* 0x44042dc6 */ + }; + #ifdef __STDC__ + static const Simple ps5[5] = { + #else + static Simple ps5[5] = { + #endif + 5.9280597687e+01f, /* 0x426d1f55 */ + 9.9140142822e+02f, /* 0x4477d9b1 */ + 5.3532670898e+03f, /* 0x45a74a23 */ + 7.8446904297e+03f, /* 0x45f52586 */ + 1.5040468750e+03f, /* 0x44bc0180 */ + }; + + #ifdef __STDC__ + static const Simple pr3[6] = { + #else + static Simple pr3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ + #endif + 3.0250391081e-09f, /* 0x314fe10d */ + 1.1718686670e-01f, /* 0x3defffab */ + 3.9329774380e+00f, /* 0x407bb5e7 */ + 3.5119403839e+01f, /* 0x420c7a45 */ + 9.1055007935e+01f, /* 0x42b61c2a */ + 4.8559066772e+01f, /* 0x42423c7c */ + }; + #ifdef __STDC__ + static const Simple ps3[5] = { + #else + static Simple ps3[5] = { + #endif + 3.4791309357e+01f, /* 0x420b2a4d */ + 3.3676245117e+02f, /* 0x43a86198 */ + 1.0468714600e+03f, /* 0x4482dbe3 */ + 8.9081134033e+02f, /* 0x445eb3ed */ + 1.0378793335e+02f, /* 0x42cf936c */ + }; + + #ifdef __STDC__ + static const Simple pr2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ + #else + static Simple pr2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ + #endif + 1.0771083225e-07f, /* 0x33e74ea8 */ + 1.1717621982e-01f, /* 0x3deffa16 */ + 2.3685150146e+00f, /* 0x401795c0 */ + 1.2242610931e+01f, /* 0x4143e1bc */ + 1.7693971634e+01f, /* 0x418d8d41 */ + 5.0735230446e+00f, /* 0x40a25a4d */ + }; + #ifdef __STDC__ + static const Simple ps2[5] = { + #else + static Simple ps2[5] = { + #endif + 2.1436485291e+01f, /* 0x41ab7dec */ + 1.2529022980e+02f, /* 0x42fa9499 */ + 2.3227647400e+02f, /* 0x436846c7 */ + 1.1767937469e+02f, /* 0x42eb5bd7 */ + 8.3646392822e+00f, /* 0x4105d590 */ + }; + + #ifdef __STDC__ + static Simple ponef(Simple x) + #else + static Simple ponef(x) + Simple x; + #endif + { + #ifdef __STDC__ + const Simple *p = 0,*q = 0; + #else + Simple *p = 0,*q = 0; + #endif + Simple z,r,s; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + if (ix >= 0x41000000) { + p = pr8; q = ps8; +} else if (ix >= 0x40f71c58) { +p = pr5; q = ps5; +} else if (ix >= 0x4036db68) { +p = pr3; q = ps3; +} else if (ix >= 0x40000000) { +p = pr2; q = ps2; } - -#ifdef __STDC__ -static const Simple U0[5] = { -#else -static Simple U0[5] = { -#endif - -1.9605709612e-01f, /* 0xbe48c331 */ - 5.0443872809e-02f, /* 0x3d4e9e3c */ - -1.9125689287e-03f, /* 0xbafaaf2a */ - 2.3525259166e-05f, /* 0x37c5581c */ - -9.1909917899e-08f, /* 0xb3c56003 */ -}; -#ifdef __STDC__ -static const Simple V0[5] = { -#else -static Simple V0[5] = { -#endif - 1.9916731864e-02f, /* 0x3ca3286a */ - 2.0255257550e-04f, /* 0x3954644b */ - 1.3560879779e-06f, /* 0x35b602d4 */ - 6.2274145840e-09f, /* 0x31d5f8eb */ - 1.6655924903e-11f, /* 0x2d9281cf */ -}; - -#ifdef __STDC__ - Simple __ieee754_y1f(Simple x) -#else - Simple __ieee754_y1f(x) - Simple x; -#endif -{ - Simple z, s,c,ss,cc,u,v; - int32_t hx,ix; - - GET_FLOAT_WORD(hx,x); - ix = 0x7fffffff&hx; - /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ - if(ix>=0x7f800000) return one/(x+x*x); - if(ix==0) return -HUGE_VALF+x; /* -inf and overflow exception. */ - if(hx<0) return zero/(zero*x); - if(ix >= 0x40000000) { /* |x| >= 2.0f */ - __sincosf (x, &s, &c); - ss = -s-c; - cc = s-c; - if(ix<0x7f000000) { /* make sure x+x not overflow */ - z = __cosf(x+x); - if ((s*c)>zero) cc = z/ss; - else ss = z/cc; - } - /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) - * where x0 = x-3pi/4 - * Better formula: - * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) - * = 1/sqrt(2) * (sin(x) - cos(x)) - * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) - * = -1/sqrt(2) * (cos(x) + sin(x)) - * To avoid cancellation, use - * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) - * to compute the worse one. - */ - if(ix>0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrtf(x); - else { - u = ponef(x); v = qonef(x); - z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrtf(x); - } - return z; - } - if(ix<=0x24800000) { /* x < 2**-54 */ - return(-tpi/x); - } - z = x*x; - u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4]))); - v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4])))); - return(x*(u/v) + tpi*(__ieee754_j1f(x)*__ieee754_logf(x)-one/x)); -} - -/* For x >= 8, the asymptotic expansions of pone is - * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x. - * We approximate pone by - * pone(x) = 1 + (R/S) - * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10 - * S = 1 + ps0*s^2 + ... + ps4*s^10 - * and - * | pone(x)-1-R/S | <= 2 ** ( -60.06f) - */ - -#ifdef __STDC__ -static const Simple pr8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ -#else -static Simple pr8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ -#endif - 0.0000000000e+00f, /* 0x00000000 */ - 1.1718750000e-01f, /* 0x3df00000 */ - 1.3239480972e+01f, /* 0x4153d4ea */ - 4.1205184937e+02f, /* 0x43ce06a3 */ - 3.8747453613e+03f, /* 0x45722bed */ - 7.9144794922e+03f, /* 0x45f753d6 */ -}; -#ifdef __STDC__ -static const Simple ps8[5] = { -#else -static Simple ps8[5] = { -#endif - 1.1420736694e+02f, /* 0x42e46a2c */ - 3.6509309082e+03f, /* 0x45642ee5 */ - 3.6956207031e+04f, /* 0x47105c35 */ - 9.7602796875e+04f, /* 0x47bea166 */ - 3.0804271484e+04f, /* 0x46f0a88b */ -}; - -#ifdef __STDC__ -static const Simple pr5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ -#else -static Simple pr5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ -#endif - 1.3199052094e-11f, /* 0x2d68333f */ - 1.1718749255e-01f, /* 0x3defffff */ - 6.8027510643e+00f, /* 0x40d9b023 */ - 1.0830818176e+02f, /* 0x42d89dca */ - 5.1763616943e+02f, /* 0x440168b7 */ - 5.2871520996e+02f, /* 0x44042dc6 */ -}; -#ifdef __STDC__ -static const Simple ps5[5] = { -#else -static Simple ps5[5] = { -#endif - 5.9280597687e+01f, /* 0x426d1f55 */ - 9.9140142822e+02f, /* 0x4477d9b1 */ - 5.3532670898e+03f, /* 0x45a74a23 */ - 7.8446904297e+03f, /* 0x45f52586 */ - 1.5040468750e+03f, /* 0x44bc0180 */ -}; - -#ifdef __STDC__ -static const Simple pr3[6] = { -#else -static Simple pr3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ -#endif - 3.0250391081e-09f, /* 0x314fe10d */ - 1.1718686670e-01f, /* 0x3defffab */ - 3.9329774380e+00f, /* 0x407bb5e7 */ - 3.5119403839e+01f, /* 0x420c7a45 */ - 9.1055007935e+01f, /* 0x42b61c2a */ - 4.8559066772e+01f, /* 0x42423c7c */ -}; -#ifdef __STDC__ -static const Simple ps3[5] = { -#else -static Simple ps3[5] = { -#endif - 3.4791309357e+01f, /* 0x420b2a4d */ - 3.3676245117e+02f, /* 0x43a86198 */ - 1.0468714600e+03f, /* 0x4482dbe3 */ - 8.9081134033e+02f, /* 0x445eb3ed */ - 1.0378793335e+02f, /* 0x42cf936c */ -}; - -#ifdef __STDC__ -static const Simple pr2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ -#else -static Simple pr2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ -#endif - 1.0771083225e-07f, /* 0x33e74ea8 */ - 1.1717621982e-01f, /* 0x3deffa16 */ - 2.3685150146e+00f, /* 0x401795c0 */ - 1.2242610931e+01f, /* 0x4143e1bc */ - 1.7693971634e+01f, /* 0x418d8d41 */ - 5.0735230446e+00f, /* 0x40a25a4d */ -}; -#ifdef __STDC__ -static const Simple ps2[5] = { -#else -static Simple ps2[5] = { -#endif - 2.1436485291e+01f, /* 0x41ab7dec */ - 1.2529022980e+02f, /* 0x42fa9499 */ - 2.3227647400e+02f, /* 0x436846c7 */ - 1.1767937469e+02f, /* 0x42eb5bd7 */ - 8.3646392822e+00f, /* 0x4105d590 */ -}; - -#ifdef __STDC__ - static Simple ponef(Simple x) -#else - static Simple ponef(x) - Simple x; -#endif -{ -#ifdef __STDC__ - const Simple *p=0,*q=0; -#else - Simple *p=0,*q=0; -#endif - Simple z,r,s; - int32_t ix; - GET_FLOAT_WORD(ix,x); - ix &= 0x7fffffff; - if(ix>=0x41000000) {p = pr8; q= ps8;} - else if(ix>=0x40f71c58){p = pr5; q= ps5;} - else if(ix>=0x4036db68){p = pr3; q= ps3;} - else if(ix>=0x40000000){p = pr2; q= ps2;} - //else throw std::exception("unknown state for pointer p!"); - else throw "unknown state for pointers p and q!"; - z = one/(x*x); - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); - return one+ r/s; +//else throw std::exception("unknown state for pointer p!"); +else throw "unknown state for pointers p and q!"; +z = one / (x*x); +r = p[0] + z*(p[1] + z*(p[2] + z*(p[3] + z*(p[4] + z*p[5])))); +s = one + z*(q[0] + z*(q[1] + z*(q[2] + z*(q[3] + z*q[4])))); +return one + r / s; } -/* For x >= 8, the asymptotic expansions of qone is - * 3/8 s - 105/1024 s^3 - ..., where s = 1/x. - * We approximate pone by - * qone(x) = s*(0.375f + (R/S)) - * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10 - * S = 1 + qs1*s^2 + ... + qs6*s^12 - * and - * | qone(x)/s -0.375f-R/S | <= 2 ** ( -61.13f) - */ + /* For x >= 8, the asymptotic expansions of qone is + * 3/8 s - 105/1024 s^3 - ..., where s = 1/x. + * We approximate pone by + * qone(x) = s*(0.375f + (R/S)) + * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10 + * S = 1 + qs1*s^2 + ... + qs6*s^12 + * and + * | qone(x)/s -0.375f-R/S | <= 2 ** ( -61.13f) + */ -#ifdef __STDC__ -static const Simple qr8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ -#else -static Simple qr8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ -#endif - 0.0000000000e+00f, /* 0x00000000 */ - -1.0253906250e-01f, /* 0xbdd20000 */ - -1.6271753311e+01f, /* 0xc1822c8d */ - -7.5960174561e+02f, /* 0xc43de683 */ - -1.1849806641e+04f, /* 0xc639273a */ - -4.8438511719e+04f, /* 0xc73d3683 */ -}; -#ifdef __STDC__ -static const Simple qs8[6] = { -#else -static Simple qs8[6] = { -#endif - 1.6139537048e+02f, /* 0x43216537 */ - 7.8253862305e+03f, /* 0x45f48b17 */ - 1.3387534375e+05f, /* 0x4802bcd6 */ - 7.1965775000e+05f, /* 0x492fb29c */ - 6.6660125000e+05f, /* 0x4922be94 */ - -2.9449025000e+05f, /* 0xc88fcb48 */ -}; + #ifdef __STDC__ + static const Simple qr8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ + #else + static Simple qr8[6] = { /* for x in [inf, 8]=1/[0,0.125f] */ + #endif + 0.0000000000e+00f, /* 0x00000000 */ + -1.0253906250e-01f, /* 0xbdd20000 */ + -1.6271753311e+01f, /* 0xc1822c8d */ + -7.5960174561e+02f, /* 0xc43de683 */ + -1.1849806641e+04f, /* 0xc639273a */ + -4.8438511719e+04f, /* 0xc73d3683 */ + }; + #ifdef __STDC__ + static const Simple qs8[6] = { + #else + static Simple qs8[6] = { + #endif + 1.6139537048e+02f, /* 0x43216537 */ + 7.8253862305e+03f, /* 0x45f48b17 */ + 1.3387534375e+05f, /* 0x4802bcd6 */ + 7.1965775000e+05f, /* 0x492fb29c */ + 6.6660125000e+05f, /* 0x4922be94 */ + -2.9449025000e+05f, /* 0xc88fcb48 */ + }; -#ifdef __STDC__ -static const Simple qr5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ -#else -static Simple qr5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ -#endif - -2.0897993405e-11f, /* 0xadb7d219 */ - -1.0253904760e-01f, /* 0xbdd1fffe */ - -8.0564479828e+00f, /* 0xc100e736 */ - -1.8366960144e+02f, /* 0xc337ab6b */ - -1.3731937256e+03f, /* 0xc4aba633 */ - -2.6124443359e+03f, /* 0xc523471c */ -}; -#ifdef __STDC__ -static const Simple qs5[6] = { -#else -static Simple qs5[6] = { -#endif - 8.1276550293e+01f, /* 0x42a28d98 */ - 1.9917987061e+03f, /* 0x44f8f98f */ - 1.7468484375e+04f, /* 0x468878f8 */ - 4.9851425781e+04f, /* 0x4742bb6d */ - 2.7948074219e+04f, /* 0x46da5826 */ - -4.7191835938e+03f, /* 0xc5937978 */ -}; + #ifdef __STDC__ + static const Simple qr5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ + #else + static Simple qr5[6] = { /* for x in [8,4.5454f]=1/[0.125f,0.22001f] */ + #endif + - 2.0897993405e-11f, /* 0xadb7d219 */ + -1.0253904760e-01f, /* 0xbdd1fffe */ + -8.0564479828e+00f, /* 0xc100e736 */ + -1.8366960144e+02f, /* 0xc337ab6b */ + -1.3731937256e+03f, /* 0xc4aba633 */ + -2.6124443359e+03f, /* 0xc523471c */ + }; + #ifdef __STDC__ + static const Simple qs5[6] = { + #else + static Simple qs5[6] = { + #endif + 8.1276550293e+01f, /* 0x42a28d98 */ + 1.9917987061e+03f, /* 0x44f8f98f */ + 1.7468484375e+04f, /* 0x468878f8 */ + 4.9851425781e+04f, /* 0x4742bb6d */ + 2.7948074219e+04f, /* 0x46da5826 */ + -4.7191835938e+03f, /* 0xc5937978 */ + }; -#ifdef __STDC__ -static const Simple qr3[6] = { -#else -static Simple qr3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ -#endif - -5.0783124372e-09f, /* 0xb1ae7d4f */ - -1.0253783315e-01f, /* 0xbdd1ff5b */ - -4.6101160049e+00f, /* 0xc0938612 */ - -5.7847221375e+01f, /* 0xc267638e */ - -2.2824453735e+02f, /* 0xc3643e9a */ - -2.1921012878e+02f, /* 0xc35b35cb */ -}; -#ifdef __STDC__ -static const Simple qs3[6] = { -#else -static Simple qs3[6] = { -#endif - 4.7665153503e+01f, /* 0x423ea91e */ - 6.7386511230e+02f, /* 0x4428775e */ - 3.3801528320e+03f, /* 0x45534272 */ - 5.5477290039e+03f, /* 0x45ad5dd5 */ - 1.9031191406e+03f, /* 0x44ede3d0 */ - -1.3520118713e+02f, /* 0xc3073381 */ -}; + #ifdef __STDC__ + static const Simple qr3[6] = { + #else + static Simple qr3[6] = {/* for x in [4.547f,2.8571f]=1/[0.2199f,0.35001f] */ + #endif + - 5.0783124372e-09f, /* 0xb1ae7d4f */ + -1.0253783315e-01f, /* 0xbdd1ff5b */ + -4.6101160049e+00f, /* 0xc0938612 */ + -5.7847221375e+01f, /* 0xc267638e */ + -2.2824453735e+02f, /* 0xc3643e9a */ + -2.1921012878e+02f, /* 0xc35b35cb */ + }; + #ifdef __STDC__ + static const Simple qs3[6] = { + #else + static Simple qs3[6] = { + #endif + 4.7665153503e+01f, /* 0x423ea91e */ + 6.7386511230e+02f, /* 0x4428775e */ + 3.3801528320e+03f, /* 0x45534272 */ + 5.5477290039e+03f, /* 0x45ad5dd5 */ + 1.9031191406e+03f, /* 0x44ede3d0 */ + -1.3520118713e+02f, /* 0xc3073381 */ + }; -#ifdef __STDC__ -static const Simple qr2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ -#else -static Simple qr2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ -#endif - -1.7838172539e-07f, /* 0xb43f8932 */ - -1.0251704603e-01f, /* 0xbdd1f475 */ - -2.7522056103e+00f, /* 0xc0302423 */ - -1.9663616180e+01f, /* 0xc19d4f16 */ - -4.2325313568e+01f, /* 0xc2294d1f */ - -2.1371921539e+01f, /* 0xc1aaf9b2 */ -}; -#ifdef __STDC__ -static const Simple qs2[6] = { -#else -static Simple qs2[6] = { -#endif - 2.9533363342e+01f, /* 0x41ec4454 */ - 2.5298155212e+02f, /* 0x437cfb47 */ - 7.5750280762e+02f, /* 0x443d602e */ - 7.3939318848e+02f, /* 0x4438d92a */ - 1.5594900513e+02f, /* 0x431bf2f2 */ - -4.9594988823e+00f, /* 0xc09eb437 */ -}; + #ifdef __STDC__ + static const Simple qr2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ + #else + static Simple qr2[6] = {/* for x in [2.8570f,2]=1/[0.3499f,0.5f] */ + #endif + - 1.7838172539e-07f, /* 0xb43f8932 */ + -1.0251704603e-01f, /* 0xbdd1f475 */ + -2.7522056103e+00f, /* 0xc0302423 */ + -1.9663616180e+01f, /* 0xc19d4f16 */ + -4.2325313568e+01f, /* 0xc2294d1f */ + -2.1371921539e+01f, /* 0xc1aaf9b2 */ + }; + #ifdef __STDC__ + static const Simple qs2[6] = { + #else + static Simple qs2[6] = { + #endif + 2.9533363342e+01f, /* 0x41ec4454 */ + 2.5298155212e+02f, /* 0x437cfb47 */ + 7.5750280762e+02f, /* 0x443d602e */ + 7.3939318848e+02f, /* 0x4438d92a */ + 1.5594900513e+02f, /* 0x431bf2f2 */ + -4.9594988823e+00f, /* 0xc09eb437 */ + }; -#ifdef __STDC__ - static Simple qonef(Simple x) -#else - static Simple qonef(x) - Simple x; -#endif -{ -#ifdef __STDC__ - const Simple *p=0,*q=0; -#else - Simple *p=0,*q=0; -#endif - Simple s,r,z; - int32_t ix; - GET_FLOAT_WORD(ix,x); - ix &= 0x7fffffff; - if(ix>=0x40200000) {p = qr8; q= qs8;} - else if(ix>=0x40f71c58){p = qr5; q= qs5;} - else if(ix>=0x4036db68){p = qr3; q= qs3;} - else if(ix>=0x40000000){p = qr2; q= qs2;} - //else throw std::exception("unknown state for pointer p!"); - else throw "unknown state for pointers p and q!"; - z = one/(x*x); - r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); - s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); - return ((Simple).375f + r/s)/x; + #ifdef __STDC__ + static Simple qonef(Simple x) + #else + static Simple qonef(x) + Simple x; + #endif + { + #ifdef __STDC__ + const Simple *p = 0,*q = 0; + #else + Simple *p = 0,*q = 0; + #endif + Simple s,r,z; + int32_t ix; + GET_FLOAT_WORD(ix,x); + ix &= 0x7fffffff; + if (ix >= 0x40200000) { + p = qr8; q = qs8; +} else if (ix >= 0x40f71c58) { +p = qr5; q = qs5; +} else if (ix >= 0x4036db68) { +p = qr3; q = qs3; +} else if (ix >= 0x40000000) { +p = qr2; q = qs2; +} +//else throw std::exception("unknown state for pointer p!"); +else throw "unknown state for pointers p and q!"; +z = one / (x*x); +r = p[0] + z*(p[1] + z*(p[2] + z*(p[3] + z*(p[4] + z*p[5])))); +s = one + z*(q[0] + z*(q[1] + z*(q[2] + z*(q[3] + z*(q[4] + z*q[5]))))); +return ((Simple).375f + r / s) / x; } } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_jnf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_jnf.cpp index 6a61c98b8..6ca317ccc 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_jnf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_jnf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_jnf.c,v 1.5f 1995/05/10 20:45:37 jtc Exp $"; @@ -23,193 +23,193 @@ static char rcsid[] = "$NetBSD: e_jnf.c,v 1.5f 1995/05/10 20:45:37 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -two = 2.0000000000e+00f, /* 0x40000000 */ -one = 1.0000000000e+00f; /* 0x3F800000 */ + two = 2.0000000000e+00f, /* 0x40000000 */ + one = 1.0000000000e+00f; /* 0x3F800000 */ #ifdef __STDC__ -static const Simple zero = 0.0000000000e+00f; + static const Simple zero = 0.0000000000e+00f; #else -static Simple zero = 0.0000000000e+00f; + static Simple zero = 0.0000000000e+00f; #endif #ifdef __STDC__ Simple __ieee754_jnf(int n, Simple x) #else - Simple __ieee754_jnf(n,x) - int n; Simple x; + Simple __ieee754_jnf(n, x) + int n; Simple x; #endif -{ - int32_t i,hx,ix, sgn; - Simple a, b, temp, di; - Simple z, w; + { + int32_t i, hx, ix, sgn; + Simple a, b, temp, di; + Simple z, w; - /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) - * Thus, J(-n,x) = J(n,-x) - */ - GET_FLOAT_WORD(hx,x); - ix = 0x7fffffff&hx; - /* if J(n,NaN) is NaN */ - if(ix>0x7f800000) return x+x; - if(n<0){ - n = -n; - x = -x; - hx ^= 0x80000000; - } - if(n==0) return(__ieee754_j0f(x)); - if(n==1) return(__ieee754_j1f(x)); - sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */ - x = fabsf(x); - if(ix==0||ix>=0x7f800000) /* if x is 0 or inf */ - b = zero; - else if((Simple)n<=x) { - /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ - a = __ieee754_j0f(x); - b = __ieee754_j1f(x); - for(i=1;i33) /* underflow */ - b = zero; - else { - temp = x*(Simple)0.5f; b = temp; - for (a=one,i=2;i<=n;i++) { - a *= (Simple)i; /* a = n! */ - b *= temp; /* b = (x/2)^n */ - } - b = b/a; - } - } else { - /* use backward recurrence */ - /* x x^2 x^2 - * J(n,x)/J(n-1,x) = ---- ------ ------ ..... - * 2n - 2(n+1) - 2(n+2) - * - * 1 1 1 - * (for large x) = ---- ------ ------ ..... - * 2n 2(n+1) 2(n+2) - * -- - ------ - ------ - - * x x x - * - * Let w = 2n/x and h=2/x, then the above quotient - * is equal to the continued fraction: - * 1 - * = ----------------------- - * 1 - * w - ----------------- - * 1 - * w+h - --------- - * w+2h - ... - * - * To determine how many terms needed, let - * Q(0) = w, Q(1) = w(w+h) - 1, - * Q(k) = (w+k*h)*Q(k-1) - Q(k-2), - * When Q(k) > 1e4 good for single - * When Q(k) > 1e9 good for Double - * When Q(k) > 1e17 good for quadruple + /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) + * Thus, J(-n,x) = J(n,-x) */ - /* determine k */ - Simple t,v; - Simple q0,q1,h,tmp; int32_t k,m; - w = (n+n)/(Simple)x; h = (Simple)2.0f/(Simple)x; - q0 = w; z = w+h; q1 = w*z - (Simple)1.0f; k=1; - while(q1<(Simple)1.0e9f) { - k += 1; z += h; - tmp = z*q1 - q0; - q0 = q1; - q1 = tmp; + GET_FLOAT_WORD(hx, x); + ix = 0x7fffffff & hx; + /* if J(n,NaN) is NaN */ + if (ix > 0x7f800000) return x + x; + if (n < 0) { + n = -n; + x = -x; + hx ^= 0x80000000; } - m = n+n; - for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t); - a = t; - b = one; - /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) - * Hence, if n*(log(2n/x)) > ... - * single 8.8722839355e+01f - * Double 7.09782712893383973096e+02f - * Extended 1.1356523406294143949491931077970765006170e+04f - * then recurrent value may overflow and the result is - * likely underflow to zero - */ - tmp = n; - v = two/x; - tmp = tmp*__ieee754_logf(fabsf(v*tmp)); - if(tmp<(Simple)8.8721679688e+01f) { - for(i=n-1,di=(Simple)(i+i);i>0;i--){ - temp = b; - b *= di; - b = b/x - a; - a = temp; - di -= two; - } - } else { - for(i=n-1,di=(Simple)(i+i);i>0;i--){ - temp = b; - b *= di; - b = b/x - a; - a = temp; - di -= two; - /* scale b to avoid spurious overflow */ - if(b>(Simple)1e10f) { - a /= b; - t /= b; - b = one; + if (n == 0) return(__ieee754_j0f(x)); + if (n == 1) return(__ieee754_j1f(x)); + sgn = (n & 1)&(hx >> 31); /* even n -- 0, odd n -- sign(x) */ + x = fabsf(x); + if (ix == 0 || ix >= 0x7f800000) /* if x is 0 or inf */ + b = zero; + else if ((Simple) n <= x) { + /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ + a = __ieee754_j0f(x); + b = __ieee754_j1f(x); + for (i = 1; i < n; i++) { + temp = b; + b = b*((Simple) (i + i) / x) - a; /* avoid underflow */ + a = temp; + } + } else { + if (ix < 0x30800000) { /* x < 2**-29 */ + /* x is tiny, return the first Taylor expansion of J(n,x) + * J(n,x) = 1/n!*(x/2)^n - ... + */ + if (n > 33) /* underflow */ + b = zero; + else { + temp = x*(Simple)0.5f; b = temp; + for (a = one, i = 2; i <= n; i++) { + a *= (Simple) i; /* a = n! */ + b *= temp; /* b = (x/2)^n */ + } + b = b / a; + } + } else { + /* use backward recurrence */ + /* x x^2 x^2 + * J(n,x)/J(n-1,x) = ---- ------ ------ ..... + * 2n - 2(n+1) - 2(n+2) + * + * 1 1 1 + * (for large x) = ---- ------ ------ ..... + * 2n 2(n+1) 2(n+2) + * -- - ------ - ------ - + * x x x + * + * Let w = 2n/x and h=2/x, then the above quotient + * is equal to the continued fraction: + * 1 + * = ----------------------- + * 1 + * w - ----------------- + * 1 + * w+h - --------- + * w+2h - ... + * + * To determine how many terms needed, let + * Q(0) = w, Q(1) = w(w+h) - 1, + * Q(k) = (w+k*h)*Q(k-1) - Q(k-2), + * When Q(k) > 1e4 good for single + * When Q(k) > 1e9 good for Double + * When Q(k) > 1e17 good for quadruple + */ + /* determine k */ + Simple t, v; + Simple q0, q1, h, tmp; int32_t k, m; + w = (n + n) / (Simple) x; h = (Simple)2.0f / (Simple) x; + q0 = w; z = w + h; q1 = w*z - (Simple)1.0f; k = 1; + while (q1 < (Simple)1.0e9f) { + k += 1; z += h; + tmp = z*q1 - q0; + q0 = q1; + q1 = tmp; + } + m = n + n; + for (t = zero, i = 2 * (n + k); i >= m; i -= 2) t = one / (i / x - t); + a = t; + b = one; + /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) + * Hence, if n*(log(2n/x)) > ... + * single 8.8722839355e+01f + * Double 7.09782712893383973096e+02f + * Extended 1.1356523406294143949491931077970765006170e+04f + * then recurrent value may overflow and the result is + * likely underflow to zero + */ + tmp = n; + v = two / x; + tmp = tmp*__ieee754_logf(fabsf(v*tmp)); + if (tmp < (Simple)8.8721679688e+01f) { + for (i = n - 1, di = (Simple) (i + i); i > 0; i--) { + temp = b; + b *= di; + b = b / x - a; + a = temp; + di -= two; + } + } else { + for (i = n - 1, di = (Simple) (i + i); i > 0; i--) { + temp = b; + b *= di; + b = b / x - a; + a = temp; + di -= two; + /* scale b to avoid spurious overflow */ + if (b > (Simple)1e10f) { + a /= b; + t /= b; + b = one; + } + } + } + b = (t*__ieee754_j0f(x) / b); } - } } - b = (t*__ieee754_j0f(x)/b); - } + if (sgn == 1) return -b; else return b; } - if(sgn==1) return -b; else return b; -} #ifdef __STDC__ Simple __ieee754_ynf(int n, Simple x) #else - Simple __ieee754_ynf(n,x) - int n; Simple x; + Simple __ieee754_ynf(n, x) + int n; Simple x; #endif -{ - int32_t i,hx,ix; - u_int32_t ib; - int32_t sign; - Simple a, b, temp; + { + int32_t i, hx, ix; + u_int32_t ib; + int32_t sign; + Simple a, b, temp; - GET_FLOAT_WORD(hx,x); - ix = 0x7fffffff&hx; - /* if Y(n,NaN) is NaN */ - if(ix>0x7f800000) return x+x; - if(ix==0) return -HUGE_VALF+x; /* -inf and overflow exception. */ - if(hx<0) return zero/(zero*x); - sign = 1; - if(n<0){ - n = -n; - sign = 1 - ((n&1)<<1); - } - if(n==0) return(__ieee754_y0f(x)); - if(n==1) return(sign*__ieee754_y1f(x)); - if(ix==0x7f800000) return zero; + GET_FLOAT_WORD(hx, x); + ix = 0x7fffffff & hx; + /* if Y(n,NaN) is NaN */ + if (ix > 0x7f800000) return x + x; + if (ix == 0) return -HUGE_VALF + x; /* -inf and overflow exception. */ + if (hx < 0) return zero / (zero*x); + sign = 1; + if (n < 0) { + n = -n; + sign = 1 - ((n & 1) << 1); + } + if (n == 0) return(__ieee754_y0f(x)); + if (n == 1) return(sign*__ieee754_y1f(x)); + if (ix == 0x7f800000) return zero; - a = __ieee754_y0f(x); - b = __ieee754_y1f(x); - /* quit if b is -inf */ - GET_FLOAT_WORD(ib,b); - for(i=1;i 0) return b; else return -b; } - if(sign>0) return b; else return -b; -} } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_lgammaf_r.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_lgammaf_r.cpp index 85d0b6f37..6f67064cc 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_lgammaf_r.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_lgammaf_r.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_lgammaf_r.c,v 1.3f 1995/05/10 20:45:47 jtc Exp $"; @@ -23,230 +23,239 @@ static char rcsid[] = "$NetBSD: e_lgammaf_r.c,v 1.3f 1995/05/10 20:45:47 jtc Exp namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -two23= 8.3886080000e+06f, /* 0x4b000000 */ -half= 5.0000000000e-01f, /* 0x3f000000 */ -one = 1.0000000000e+00f, /* 0x3f800000 */ -pi = 3.1415927410e+00f, /* 0x40490fdb */ -a0 = 7.7215664089e-02f, /* 0x3d9e233f */ -a1 = 3.2246702909e-01f, /* 0x3ea51a66 */ -a2 = 6.7352302372e-02f, /* 0x3d89f001 */ -a3 = 2.0580807701e-02f, /* 0x3ca89915 */ -a4 = 7.3855509982e-03f, /* 0x3bf2027e */ -a5 = 2.8905137442e-03f, /* 0x3b3d6ec6 */ -a6 = 1.1927076848e-03f, /* 0x3a9c54a1 */ -a7 = 5.1006977446e-04f, /* 0x3a05b634 */ -a8 = 2.2086278477e-04f, /* 0x39679767 */ -a9 = 1.0801156895e-04f, /* 0x38e28445 */ -a10 = 2.5214456400e-05f, /* 0x37d383a2 */ -a11 = 4.4864096708e-05f, /* 0x383c2c75 */ -tc = 1.4616321325e+00f, /* 0x3fbb16c3 */ -tf = -1.2148628384e-01f, /* 0xbdf8cdcd */ -/* tt = -(tail of tf) */ -tt = 6.6971006518e-09f, /* 0x31e61c52 */ -t0 = 4.8383611441e-01f, /* 0x3ef7b95e */ -t1 = -1.4758771658e-01f, /* 0xbe17213c */ -t2 = 6.4624942839e-02f, /* 0x3d845a15 */ -t3 = -3.2788541168e-02f, /* 0xbd064d47 */ -t4 = 1.7970675603e-02f, /* 0x3c93373d */ -t5 = -1.0314224288e-02f, /* 0xbc28fcfe */ -t6 = 6.1005386524e-03f, /* 0x3bc7e707 */ -t7 = -3.6845202558e-03f, /* 0xbb7177fe */ -t8 = 2.2596477065e-03f, /* 0x3b141699 */ -t9 = -1.4034647029e-03f, /* 0xbab7f476 */ -t10 = 8.8108185446e-04f, /* 0x3a66f867 */ -t11 = -5.3859531181e-04f, /* 0xba0d3085 */ -t12 = 3.1563205994e-04f, /* 0x39a57b6b */ -t13 = -3.1275415677e-04f, /* 0xb9a3f927 */ -t14 = 3.3552918467e-04f, /* 0x39afe9f7 */ -u0 = -7.7215664089e-02f, /* 0xbd9e233f */ -u1 = 6.3282704353e-01f, /* 0x3f2200f4 */ -u2 = 1.4549225569e+00f, /* 0x3fba3ae7 */ -u3 = 9.7771751881e-01f, /* 0x3f7a4bb2 */ -u4 = 2.2896373272e-01f, /* 0x3e6a7578 */ -u5 = 1.3381091878e-02f, /* 0x3c5b3c5e */ -v1 = 2.4559779167e+00f, /* 0x401d2ebe */ -v2 = 2.1284897327e+00f, /* 0x4008392d */ -v3 = 7.6928514242e-01f, /* 0x3f44efdf */ -v4 = 1.0422264785e-01f, /* 0x3dd572af */ -v5 = 3.2170924824e-03f, /* 0x3b52d5db */ -s0 = -7.7215664089e-02f, /* 0xbd9e233f */ -s1 = 2.1498242021e-01f, /* 0x3e5c245a */ -s2 = 3.2577878237e-01f, /* 0x3ea6cc7a */ -s3 = 1.4635047317e-01f, /* 0x3e15dce6 */ -s4 = 2.6642270386e-02f, /* 0x3cda40e4 */ -s5 = 1.8402845599e-03f, /* 0x3af135b4 */ -s6 = 3.1947532989e-05f, /* 0x3805ff67 */ -r1 = 1.3920053244e+00f, /* 0x3fb22d3b */ -r2 = 7.2193557024e-01f, /* 0x3f38d0c5 */ -r3 = 1.7193385959e-01f, /* 0x3e300f6e */ -r4 = 1.8645919859e-02f, /* 0x3c98bf54 */ -r5 = 7.7794247773e-04f, /* 0x3a4beed6 */ -r6 = 7.3266842264e-06f, /* 0x36f5d7bd */ -w0 = 4.1893854737e-01f, /* 0x3ed67f1d */ -w1 = 8.3333335817e-02f, /* 0x3daaaaab */ -w2 = -2.7777778450e-03f, /* 0xbb360b61 */ -w3 = 7.9365057172e-04f, /* 0x3a500cfd */ -w4 = -5.9518753551e-04f, /* 0xba1c065c */ -w5 = 8.3633989561e-04f, /* 0x3a5b3dd2 */ -w6 = -1.6309292987e-03f; /* 0xbad5c4e8 */ + two23 = 8.3886080000e+06f, /* 0x4b000000 */ + half = 5.0000000000e-01f, /* 0x3f000000 */ + one = 1.0000000000e+00f, /* 0x3f800000 */ + pi = 3.1415927410e+00f, /* 0x40490fdb */ + a0 = 7.7215664089e-02f, /* 0x3d9e233f */ + a1 = 3.2246702909e-01f, /* 0x3ea51a66 */ + a2 = 6.7352302372e-02f, /* 0x3d89f001 */ + a3 = 2.0580807701e-02f, /* 0x3ca89915 */ + a4 = 7.3855509982e-03f, /* 0x3bf2027e */ + a5 = 2.8905137442e-03f, /* 0x3b3d6ec6 */ + a6 = 1.1927076848e-03f, /* 0x3a9c54a1 */ + a7 = 5.1006977446e-04f, /* 0x3a05b634 */ + a8 = 2.2086278477e-04f, /* 0x39679767 */ + a9 = 1.0801156895e-04f, /* 0x38e28445 */ + a10 = 2.5214456400e-05f, /* 0x37d383a2 */ + a11 = 4.4864096708e-05f, /* 0x383c2c75 */ + tc = 1.4616321325e+00f, /* 0x3fbb16c3 */ + tf = -1.2148628384e-01f, /* 0xbdf8cdcd */ + /* tt = -(tail of tf) */ + tt = 6.6971006518e-09f, /* 0x31e61c52 */ + t0 = 4.8383611441e-01f, /* 0x3ef7b95e */ + t1 = -1.4758771658e-01f, /* 0xbe17213c */ + t2 = 6.4624942839e-02f, /* 0x3d845a15 */ + t3 = -3.2788541168e-02f, /* 0xbd064d47 */ + t4 = 1.7970675603e-02f, /* 0x3c93373d */ + t5 = -1.0314224288e-02f, /* 0xbc28fcfe */ + t6 = 6.1005386524e-03f, /* 0x3bc7e707 */ + t7 = -3.6845202558e-03f, /* 0xbb7177fe */ + t8 = 2.2596477065e-03f, /* 0x3b141699 */ + t9 = -1.4034647029e-03f, /* 0xbab7f476 */ + t10 = 8.8108185446e-04f, /* 0x3a66f867 */ + t11 = -5.3859531181e-04f, /* 0xba0d3085 */ + t12 = 3.1563205994e-04f, /* 0x39a57b6b */ + t13 = -3.1275415677e-04f, /* 0xb9a3f927 */ + t14 = 3.3552918467e-04f, /* 0x39afe9f7 */ + u0 = -7.7215664089e-02f, /* 0xbd9e233f */ + u1 = 6.3282704353e-01f, /* 0x3f2200f4 */ + u2 = 1.4549225569e+00f, /* 0x3fba3ae7 */ + u3 = 9.7771751881e-01f, /* 0x3f7a4bb2 */ + u4 = 2.2896373272e-01f, /* 0x3e6a7578 */ + u5 = 1.3381091878e-02f, /* 0x3c5b3c5e */ + v1 = 2.4559779167e+00f, /* 0x401d2ebe */ + v2 = 2.1284897327e+00f, /* 0x4008392d */ + v3 = 7.6928514242e-01f, /* 0x3f44efdf */ + v4 = 1.0422264785e-01f, /* 0x3dd572af */ + v5 = 3.2170924824e-03f, /* 0x3b52d5db */ + s0 = -7.7215664089e-02f, /* 0xbd9e233f */ + s1 = 2.1498242021e-01f, /* 0x3e5c245a */ + s2 = 3.2577878237e-01f, /* 0x3ea6cc7a */ + s3 = 1.4635047317e-01f, /* 0x3e15dce6 */ + s4 = 2.6642270386e-02f, /* 0x3cda40e4 */ + s5 = 1.8402845599e-03f, /* 0x3af135b4 */ + s6 = 3.1947532989e-05f, /* 0x3805ff67 */ + r1 = 1.3920053244e+00f, /* 0x3fb22d3b */ + r2 = 7.2193557024e-01f, /* 0x3f38d0c5 */ + r3 = 1.7193385959e-01f, /* 0x3e300f6e */ + r4 = 1.8645919859e-02f, /* 0x3c98bf54 */ + r5 = 7.7794247773e-04f, /* 0x3a4beed6 */ + r6 = 7.3266842264e-06f, /* 0x36f5d7bd */ + w0 = 4.1893854737e-01f, /* 0x3ed67f1d */ + w1 = 8.3333335817e-02f, /* 0x3daaaaab */ + w2 = -2.7777778450e-03f, /* 0xbb360b61 */ + w3 = 7.9365057172e-04f, /* 0x3a500cfd */ + w4 = -5.9518753551e-04f, /* 0xba1c065c */ + w5 = 8.3633989561e-04f, /* 0x3a5b3dd2 */ + w6 = -1.6309292987e-03f; /* 0xbad5c4e8 */ #ifdef __STDC__ -static const Simple zero= 0.0000000000e+00f; + static const Simple zero = 0.0000000000e+00f; #else -static Simple zero= 0.0000000000e+00f; + static Simple zero = 0.0000000000e+00f; #endif #ifdef __STDC__ static Simple sin_pif(Simple x) #else static Simple sin_pif(x) - Simple x; + Simple x; #endif -{ - Simple y,z; - int n,ix; + { + Simple y, z; + int n, ix; - GET_FLOAT_WORD(ix,x); - ix &= 0x7fffffff; + GET_FLOAT_WORD(ix, x); + ix &= 0x7fffffff; - if(ix<0x3e800000) return __kernel_sinf(pi*x,zero,0); - y = -x; /* x is assume negative */ + if (ix < 0x3e800000) return __kernel_sinf(pi*x, zero, 0); + y = -x; /* x is assume negative */ - /* - * argument reduction, make sure inexact flag not raised if input - * is an integer - */ - z = __floorf(y); - if(z!=y) { /* inexact anyway */ - y *= (Simple)0.5f; - y = (Simple)2.0f*(y - __floorf(y)); /* y = |x| mod 2.0f */ - n = (int) (y*(Simple)4.0f); - } else { - if(ix>=0x4b800000) { - y = zero; n = 0; /* y must be even */ - } else { - if(ix<0x4b000000) z = y+two23; /* exact */ - GET_FLOAT_WORD(n,z); - n &= 1; - y = n; - n<<= 2; - } - } - switch (n) { - case 0: y = __kernel_sinf(pi*y,zero,0); break; - case 1: - case 2: y = __kernel_cosf(pi*((Simple)0.5f-y),zero); break; - case 3: - case 4: y = __kernel_sinf(pi*(one-y),zero,0); break; - case 5: - case 6: y = -__kernel_cosf(pi*(y-(Simple)1.5f),zero); break; - default: y = __kernel_sinf(pi*(y-(Simple)2.0f),zero,0); break; - } - return -y; -} + /* + * argument reduction, make sure inexact flag not raised if input + * is an integer + */ + z = __floorf(y); + if (z != y) { /* inexact anyway */ + y *= (Simple)0.5f; + y = (Simple)2.0f*(y - __floorf(y)); /* y = |x| mod 2.0f */ + n = (int) (y*(Simple)4.0f); + } else { + if (ix >= 0x4b800000) { + y = zero; n = 0; /* y must be even */ + } else { + if (ix < 0x4b000000) z = y + two23; /* exact */ + GET_FLOAT_WORD(n, z); + n &= 1; + y = n; + n <<= 2; + } + } + switch (n) { + case 0: y = __kernel_sinf(pi*y, zero, 0); break; + case 1: + case 2: y = __kernel_cosf(pi*((Simple)0.5f - y), zero); break; + case 3: + case 4: y = __kernel_sinf(pi*(one - y), zero, 0); break; + case 5: + case 6: y = -__kernel_cosf(pi*(y - (Simple)1.5f), zero); break; + default: y = __kernel_sinf(pi*(y - (Simple)2.0f), zero, 0); break; + } + return -y; + } #ifdef __STDC__ Simple __ieee754_lgammaf_r(Simple x, int *signgamp) #else - Simple __ieee754_lgammaf_r(x,signgamp) - Simple x; int *signgamp; + Simple __ieee754_lgammaf_r(x, signgamp) + Simple x; int *signgamp; #endif -{ - Simple t,y,z,nadj,p,p1,p2,p3,q,r,w; - int i,hx,ix; + { + Simple t, y, z, nadj, p, p1, p2, p3, q, r, w; + int i, hx, ix; - GET_FLOAT_WORD(hx,x); + GET_FLOAT_WORD(hx, x); - /* purge off +-inf, NaN, +-0, and negative arguments */ - nadj = 0; - *signgamp = 1; - ix = hx&0x7fffffff; - if(ix>=0x7f800000) return x*x; - if(ix==0) return one/fabsf(x); - if(ix<0x1c800000) { /* |x|<2**-70, return -log(|x|) */ - if(hx<0) { - *signgamp = -1; - return -__ieee754_logf(-x); - } else return -__ieee754_logf(x); - } - if(hx<0) { - if(ix>=0x4b000000) /* |x|>=2**23, must be -integer */ - return x/zero; - t = sin_pif(x); - if(t==zero) return one/fabsf(t); /* -integer */ - nadj = __ieee754_logf(pi/fabsf(t*x)); - if(t= 0x7f800000) return x*x; + if (ix == 0) return one / fabsf(x); + if (ix < 0x1c800000) { /* |x|<2**-70, return -log(|x|) */ + if (hx < 0) { + *signgamp = -1; + return -__ieee754_logf(-x); + } else return -__ieee754_logf(x); + } + if (hx < 0) { + if (ix >= 0x4b000000) /* |x|>=2**23, must be -integer */ + return x / zero; + t = sin_pif(x); + if (t == zero) return one / fabsf(t); /* -integer */ + nadj = __ieee754_logf(pi / fabsf(t*x)); + if (t < zero) *signgamp = -1; + x = -x; + } - /* purge off 1 and 2 */ - if (ix==0x3f800000||ix==0x40000000) r = 0; - /* for x < 2.0f */ - else if(ix<0x40000000) { - if(ix<=0x3f666666) { /* lgamma(x) = lgamma(x+1)-log(x) */ - r = -__ieee754_logf(x); - if(ix>=0x3f3b4a20) {y = one-x; i= 0;} - else if(ix>=0x3e6d3308) {y= x-(tc-one); i=1;} - else {y = x; i=2;} - } else { - r = zero; - if(ix>=0x3fdda618) {y=(Simple)2.0f-x;i=0;} /* [1.7316f,2] */ - else if(ix>=0x3F9da620) {y=x-tc;i=1;} /* [1.23f,1.73f] */ - else {y=x-one;i=2;} - } - switch(i) { - case 0: - z = y*y; - p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10)))); - p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11))))); - p = y*p1+p2; - r += (p-(Simple)0.5f*y); break; - case 1: - z = y*y; - w = z*y; - p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */ - p2 = t1+w*(t4+w*(t7+w*(t10+w*t13))); - p3 = t2+w*(t5+w*(t8+w*(t11+w*t14))); - p = z*p1-(tt-w*(p2+y*p3)); - r += (tf + p); break; - case 2: - p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5))))); - p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5)))); - r += (-(Simple)0.5f*y + p1/p2); - } + /* purge off 1 and 2 */ + if (ix == 0x3f800000 || ix == 0x40000000) r = 0; + /* for x < 2.0f */ + else if (ix < 0x40000000) { + if (ix <= 0x3f666666) { /* lgamma(x) = lgamma(x+1)-log(x) */ + r = -__ieee754_logf(x); + if (ix >= 0x3f3b4a20) { + y = one - x; i = 0; + } else if (ix >= 0x3e6d3308) { + y = x - (tc - one); i = 1; + } else { + y = x; i = 2; + } + } else { + r = zero; + if (ix >= 0x3fdda618) { + y = (Simple)2.0f - x; i = 0; + } /* [1.7316f,2] */ + else if (ix >= 0x3F9da620) { + y = x - tc; i = 1; + } /* [1.23f,1.73f] */ + else { + y = x - one; i = 2; + } + } + switch (i) { + case 0: + z = y*y; + p1 = a0 + z*(a2 + z*(a4 + z*(a6 + z*(a8 + z*a10)))); + p2 = z*(a1 + z*(a3 + z*(a5 + z*(a7 + z*(a9 + z*a11))))); + p = y*p1 + p2; + r += (p - (Simple)0.5f*y); break; + case 1: + z = y*y; + w = z*y; + p1 = t0 + w*(t3 + w*(t6 + w*(t9 + w*t12))); /* parallel comp */ + p2 = t1 + w*(t4 + w*(t7 + w*(t10 + w*t13))); + p3 = t2 + w*(t5 + w*(t8 + w*(t11 + w*t14))); + p = z*p1 - (tt - w*(p2 + y*p3)); + r += (tf + p); break; + case 2: + p1 = y*(u0 + y*(u1 + y*(u2 + y*(u3 + y*(u4 + y*u5))))); + p2 = one + y*(v1 + y*(v2 + y*(v3 + y*(v4 + y*v5)))); + r += (-(Simple)0.5f*y + p1 / p2); + } + } else if (ix < 0x41000000) { /* x < 8.0f */ + i = (int) x; + t = zero; + y = x - (Simple) i; + p = y*(s0 + y*(s1 + y*(s2 + y*(s3 + y*(s4 + y*(s5 + y*s6)))))); + q = one + y*(r1 + y*(r2 + y*(r3 + y*(r4 + y*(r5 + y*r6))))); + r = half*y + p / q; + z = one; /* lgamma(1+s) = log(s) + lgamma(s) */ + switch (i) { + case 7: z *= (y + (Simple)6.0f); /* FALLTHRU */ + case 6: z *= (y + (Simple)5.0f); /* FALLTHRU */ + case 5: z *= (y + (Simple)4.0f); /* FALLTHRU */ + case 4: z *= (y + (Simple)3.0f); /* FALLTHRU */ + case 3: z *= (y + (Simple)2.0f); /* FALLTHRU */ + r += __ieee754_logf(z); break; + } + /* 8.0f <= x < 2**58 */ + } else if (ix < 0x5c800000) { + t = __ieee754_logf(x); + z = one / x; + y = z*z; + w = w0 + z*(w1 + y*(w2 + y*(w3 + y*(w4 + y*(w5 + y*w6))))); + r = (x - half)*(t - one) + w; + } else + /* 2**58 <= x <= inf */ + r = x*(__ieee754_logf(x) - one); + if (hx < 0) r = nadj - r; + return r; } - else if(ix<0x41000000) { /* x < 8.0f */ - i = (int)x; - t = zero; - y = x-(Simple)i; - p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))); - q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6))))); - r = half*y+p/q; - z = one; /* lgamma(1+s) = log(s) + lgamma(s) */ - switch(i) { - case 7: z *= (y+(Simple)6.0f); /* FALLTHRU */ - case 6: z *= (y+(Simple)5.0f); /* FALLTHRU */ - case 5: z *= (y+(Simple)4.0f); /* FALLTHRU */ - case 4: z *= (y+(Simple)3.0f); /* FALLTHRU */ - case 3: z *= (y+(Simple)2.0f); /* FALLTHRU */ - r += __ieee754_logf(z); break; - } - /* 8.0f <= x < 2**58 */ - } else if (ix < 0x5c800000) { - t = __ieee754_logf(x); - z = one/x; - y = z*z; - w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); - r = (x-half)*(t-one)+w; - } else - /* 2**58 <= x <= inf */ - r = x*(__ieee754_logf(x)-one); - if(hx<0) r = nadj - r; - return r; -} } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_log10f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_log10f.cpp index 057687b95..2609902e2 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_log10f.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_log10f.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_log10f.c,v 1.5f 1995/05/10 20:45:53 jtc Exp $"; @@ -23,48 +23,48 @@ static char rcsid[] = "$NetBSD: e_log10f.c,v 1.5f 1995/05/10 20:45:53 jtc Exp $" namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -two25 = 3.3554432000e+07f, /* 0x4c000000 */ -ivln10 = 4.3429449201e-01f, /* 0x3ede5bd9 */ -log10_2hi = 3.0102920532e-01f, /* 0x3e9a2080 */ -log10_2lo = 7.9034151668e-07f; /* 0x355427db */ + two25 = 3.3554432000e+07f, /* 0x4c000000 */ + ivln10 = 4.3429449201e-01f, /* 0x3ede5bd9 */ + log10_2hi = 3.0102920532e-01f, /* 0x3e9a2080 */ + log10_2lo = 7.9034151668e-07f; /* 0x355427db */ #ifdef __STDC__ //static const Simple zero = 0.0f; #else -static Simple zero = 0.0f; + static Simple zero = 0.0f; #endif #ifdef __STDC__ Simple __ieee754_log10f(Simple x) #else Simple __ieee754_log10f(x) - Simple x; + Simple x; #endif -{ - Simple y,z; - int32_t i,k,hx; + { + Simple y, z; + int32_t i, k, hx; - GET_FLOAT_WORD(hx,x); + GET_FLOAT_WORD(hx, x); - k=0; - if (hx < 0x00800000) { /* x < 2**-126 */ - if ((hx&0x7fffffff)==0) - return -two25/(x-x); /* log(+-0)=-inf */ - if (hx<0) return (x-x)/(x-x); /* log(-#) = NaN */ - k -= 25; x *= two25; /* subnormal number, scale up x */ - GET_FLOAT_WORD(hx,x); - } - if (hx >= 0x7f800000) return x+x; - k += (hx>>23)-127; - i = ((u_int32_t)k&0x80000000)>>31; - hx = (hx&0x007fffff)|((0x7f-i)<<23); - y = (Simple)(k+i); - SET_FLOAT_WORD(x,hx); - z = y*log10_2lo + ivln10*__ieee754_logf(x); - return z+y*log10_2hi; -} + k = 0; + if (hx < 0x00800000) { /* x < 2**-126 */ + if ((hx & 0x7fffffff) == 0) + return -two25 / (x - x); /* log(+-0)=-inf */ + if (hx < 0) return (x - x) / (x - x); /* log(-#) = NaN */ + k -= 25; x *= two25; /* subnormal number, scale up x */ + GET_FLOAT_WORD(hx, x); + } + if (hx >= 0x7f800000) return x + x; + k += (hx >> 23) - 127; + i = ((u_int32_t) k & 0x80000000) >> 31; + hx = (hx & 0x007fffff) | ((0x7f - i) << 23); + y = (Simple) (k + i); + SET_FLOAT_WORD(x, hx); + z = y*log10_2lo + ivln10*__ieee754_logf(x); + return z + y*log10_2hi; + } } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_log2f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_log2f.cpp index 26ad51963..a25c50432 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_log2f.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_log2f.cpp @@ -4,16 +4,16 @@ * adapted for log2 by Ulrich Drepper */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #include "SMath.h" @@ -21,73 +21,73 @@ namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -ln2 = 0.69314718055994530942f, -two25 = 3.355443200e+07f, /* 0x4c000000 */ -Lg1 = 6.6666668653e-01f, /* 3F2AAAAB */ -Lg2 = 4.0000000596e-01f, /* 3ECCCCCD */ -Lg3 = 2.8571429849e-01f, /* 3E924925 */ -Lg4 = 2.2222198546e-01f, /* 3E638E29 */ -Lg5 = 1.8183572590e-01f, /* 3E3A3325 */ -Lg6 = 1.5313838422e-01f, /* 3E1CD04F */ -Lg7 = 1.4798198640e-01f; /* 3E178897 */ + ln2 = 0.69314718055994530942f, + two25 = 3.355443200e+07f, /* 0x4c000000 */ + Lg1 = 6.6666668653e-01f, /* 3F2AAAAB */ + Lg2 = 4.0000000596e-01f, /* 3ECCCCCD */ + Lg3 = 2.8571429849e-01f, /* 3E924925 */ + Lg4 = 2.2222198546e-01f, /* 3E638E29 */ + Lg5 = 1.8183572590e-01f, /* 3E3A3325 */ + Lg6 = 1.5313838422e-01f, /* 3E1CD04F */ + Lg7 = 1.4798198640e-01f; /* 3E178897 */ #ifdef __STDC__ -static const Simple zero = 0.0f; + static const Simple zero = 0.0f; #else -static Simple zero = 0.0f; + static Simple zero = 0.0f; #endif #ifdef __STDC__ Simple __ieee754_log2f(Simple x) #else Simple __ieee754_log2f(x) - Simple x; + Simple x; #endif -{ - Simple hfsq,f,s,z,R,w,t1,t2,dk; - int32_t k,ix,i,j; + { + Simple hfsq, f, s, z, R, w, t1, t2, dk; + int32_t k, ix, i, j; - GET_FLOAT_WORD(ix,x); + GET_FLOAT_WORD(ix, x); - k=0; - if (ix < 0x00800000) { /* x < 2**-126 */ - if ((ix&0x7fffffff)==0) - return -two25/(x-x); /* log(+-0)=-inf */ - if (ix<0) return (x-x)/(x-x); /* log(-#) = NaN */ - k -= 25; x *= two25; /* subnormal number, scale up x */ - GET_FLOAT_WORD(ix,x); - } - if (ix >= 0x7f800000) return x+x; - k += (ix>>23)-127; - ix &= 0x007fffff; - i = (ix+(0x95f64<<3))&0x800000; - SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */ - k += (i>>23); - dk = (Simple)k; - f = x-(Simple)1.0f; - if((0x007fffff&(15+ix))<16) { /* |f| < 2**-20 */ - if(f==zero) return dk; - R = f*f*((Simple)0.5f-(Simple)0.33333333333333333f*f); - return dk-(R-f)/ln2; - } - s = f/((Simple)2.0f+f); - z = s*s; - i = ix-(0x6147a<<3); - w = z*z; - j = (0x6b851<<3)-ix; - t1= w*(Lg2+w*(Lg4+w*Lg6)); - t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); - i |= j; - R = t2+t1; - if(i>0) { - hfsq=(Simple)0.5f*f*f; - return dk-((hfsq-(s*(hfsq+R)))-f)/ln2; - } else { - return dk-((s*(f-R))-f)/ln2; + k = 0; + if (ix < 0x00800000) { /* x < 2**-126 */ + if ((ix & 0x7fffffff) == 0) + return -two25 / (x - x); /* log(+-0)=-inf */ + if (ix < 0) return (x - x) / (x - x); /* log(-#) = NaN */ + k -= 25; x *= two25; /* subnormal number, scale up x */ + GET_FLOAT_WORD(ix, x); + } + if (ix >= 0x7f800000) return x + x; + k += (ix >> 23) - 127; + ix &= 0x007fffff; + i = (ix + (0x95f64 << 3)) & 0x800000; + SET_FLOAT_WORD(x, ix | (i ^ 0x3f800000)); /* normalize x or x/2 */ + k += (i >> 23); + dk = (Simple) k; + f = x - (Simple)1.0f; + if ((0x007fffff & (15 + ix)) < 16) { /* |f| < 2**-20 */ + if (f == zero) return dk; + R = f*f*((Simple)0.5f - (Simple)0.33333333333333333f*f); + return dk - (R - f) / ln2; + } + s = f / ((Simple)2.0f + f); + z = s*s; + i = ix - (0x6147a << 3); + w = z*z; + j = (0x6b851 << 3) - ix; + t1 = w*(Lg2 + w*(Lg4 + w*Lg6)); + t2 = z*(Lg1 + w*(Lg3 + w*(Lg5 + w*Lg7))); + i |= j; + R = t2 + t1; + if (i > 0) { + hfsq = (Simple)0.5f*f*f; + return dk - ((hfsq - (s*(hfsq + R))) - f) / ln2; + } else { + return dk - ((s*(f - R)) - f) / ln2; + } } } -} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_logf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_logf.cpp index 727d87690..db9b5c3de 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_logf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_logf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_logf.c,v 1.4f 1995/05/10 20:45:54 jtc Exp $"; @@ -23,80 +23,84 @@ static char rcsid[] = "$NetBSD: e_logf.c,v 1.4f 1995/05/10 20:45:54 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -ln2_hi = 6.9313812256e-01f, /* 0x3f317180 */ -ln2_lo = 9.0580006145e-06f, /* 0x3717f7d1 */ -two25 = 3.355443200e+07f, /* 0x4c000000 */ -Lg1 = 6.6666668653e-01f, /* 3F2AAAAB */ -Lg2 = 4.0000000596e-01f, /* 3ECCCCCD */ -Lg3 = 2.8571429849e-01f, /* 3E924925 */ -Lg4 = 2.2222198546e-01f, /* 3E638E29 */ -Lg5 = 1.8183572590e-01f, /* 3E3A3325 */ -Lg6 = 1.5313838422e-01f, /* 3E1CD04F */ -Lg7 = 1.4798198640e-01f; /* 3E178897 */ + ln2_hi = 6.9313812256e-01f, /* 0x3f317180 */ + ln2_lo = 9.0580006145e-06f, /* 0x3717f7d1 */ + two25 = 3.355443200e+07f, /* 0x4c000000 */ + Lg1 = 6.6666668653e-01f, /* 3F2AAAAB */ + Lg2 = 4.0000000596e-01f, /* 3ECCCCCD */ + Lg3 = 2.8571429849e-01f, /* 3E924925 */ + Lg4 = 2.2222198546e-01f, /* 3E638E29 */ + Lg5 = 1.8183572590e-01f, /* 3E3A3325 */ + Lg6 = 1.5313838422e-01f, /* 3E1CD04F */ + Lg7 = 1.4798198640e-01f; /* 3E178897 */ #ifdef __STDC__ -static const Simple zero = 0.0f; + static const Simple zero = 0.0f; #else -static Simple zero = 0.0f; + static Simple zero = 0.0f; #endif #ifdef __STDC__ Simple __ieee754_logf(Simple x) #else Simple __ieee754_logf(x) - Simple x; + Simple x; #endif -{ - Simple hfsq,f,s,z,R,w,t1,t2,dk; - int32_t k,ix,i,j; + { + Simple hfsq, f, s, z, R, w, t1, t2, dk; + int32_t k, ix, i, j; - GET_FLOAT_WORD(ix,x); + GET_FLOAT_WORD(ix, x); - k=0; - if (ix < 0x00800000) { /* x < 2**-126 */ - if ((ix&0x7fffffff)==0) - return -two25/(x-x); /* log(+-0)=-inf */ - if (ix<0) return (x-x)/(x-x); /* log(-#) = NaN */ - k -= 25; x *= two25; /* subnormal number, scale up x */ - GET_FLOAT_WORD(ix,x); - } - if (ix >= 0x7f800000) return x+x; - k += (ix>>23)-127; - ix &= 0x007fffff; - i = (ix+(0x95f64<<3))&0x800000; - SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */ - k += (i>>23); - f = x-(Simple)1.0f; - if((0x007fffff&(15+ix))<16) { /* |f| < 2**-20 */ - if(f==zero) { - if(k==0) return zero; else {dk=(Simple)k; - return dk*ln2_hi+dk*ln2_lo;} - } - R = f*f*((Simple)0.5f-(Simple)0.33333333333333333f*f); - if(k==0) return f-R; else {dk=(Simple)k; - return dk*ln2_hi-((R-dk*ln2_lo)-f);} - } - s = f/((Simple)2.0f+f); - dk = (Simple)k; - z = s*s; - i = ix-(0x6147a<<3); - w = z*z; - j = (0x6b851<<3)-ix; - t1= w*(Lg2+w*(Lg4+w*Lg6)); - t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); - i |= j; - R = t2+t1; - if(i>0) { - hfsq=(Simple)0.5f*f*f; - if(k==0) return f-(hfsq-s*(hfsq+R)); else - return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f); - } else { - if(k==0) return f-s*(f-R); else - return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f); + k = 0; + if (ix < 0x00800000) { /* x < 2**-126 */ + if ((ix & 0x7fffffff) == 0) + return -two25 / (x - x); /* log(+-0)=-inf */ + if (ix < 0) return (x - x) / (x - x); /* log(-#) = NaN */ + k -= 25; x *= two25; /* subnormal number, scale up x */ + GET_FLOAT_WORD(ix, x); + } + if (ix >= 0x7f800000) return x + x; + k += (ix >> 23) - 127; + ix &= 0x007fffff; + i = (ix + (0x95f64 << 3)) & 0x800000; + SET_FLOAT_WORD(x, ix | (i ^ 0x3f800000)); /* normalize x or x/2 */ + k += (i >> 23); + f = x - (Simple)1.0f; + if ((0x007fffff & (15 + ix)) < 16) { /* |f| < 2**-20 */ + if (f == zero) { + if (k == 0) return zero; else { + dk = (Simple) k; + return dk*ln2_hi + dk*ln2_lo; + } + } + R = f*f*((Simple)0.5f - (Simple)0.33333333333333333f*f); + if (k == 0) return f - R; else { + dk = (Simple) k; + return dk*ln2_hi - ((R - dk*ln2_lo) - f); + } + } + s = f / ((Simple)2.0f + f); + dk = (Simple) k; + z = s*s; + i = ix - (0x6147a << 3); + w = z*z; + j = (0x6b851 << 3) - ix; + t1 = w*(Lg2 + w*(Lg4 + w*Lg6)); + t2 = z*(Lg1 + w*(Lg3 + w*(Lg5 + w*Lg7))); + i |= j; + R = t2 + t1; + if (i > 0) { + hfsq = (Simple)0.5f*f*f; + if (k == 0) return f - (hfsq - s*(hfsq + R)); else + return dk*ln2_hi - ((hfsq - (s*(hfsq + R) + dk*ln2_lo)) - f); + } else { + if (k == 0) return f - s*(f - R); else + return dk*ln2_hi - ((s*(f - R) - dk*ln2_lo) - f); + } } } -} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_powf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_powf.cpp index f2cdddc31..698888bc9 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_powf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_powf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_powf.c,v 1.7f 1996/04/08 15:43:44 phil Exp $"; @@ -25,236 +25,238 @@ static const Simple huge = 1.0e+30f, tiny = 1.0e-30f; namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -bp[] = {1.0f, 1.5f,}, -dp_h[] = { 0.0f, 5.84960938e-01f,}, /* 0x3f15c000 */ -dp_l[] = { 0.0f, 1.56322085e-06f,}, /* 0x35d1cfdc */ -zero = 0.0f, -one = 1.0f, -two = 2.0f, -two24 = 16777216.0f, /* 0x4b800000 */ - /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ -L1 = 6.0000002384e-01f, /* 0x3f19999a */ -L2 = 4.2857143283e-01f, /* 0x3edb6db7 */ -L3 = 3.3333334327e-01f, /* 0x3eaaaaab */ -L4 = 2.7272811532e-01f, /* 0x3e8ba305 */ -L5 = 2.3066075146e-01f, /* 0x3e6c3255 */ -L6 = 2.0697501302e-01f, /* 0x3e53f142 */ -P1 = 1.6666667163e-01f, /* 0x3e2aaaab */ -P2 = -2.7777778450e-03f, /* 0xbb360b61 */ -P3 = 6.6137559770e-05f, /* 0x388ab355 */ -P4 = -1.6533901999e-06f, /* 0xb5ddea0e */ -P5 = 4.1381369442e-08f, /* 0x3331bb4c */ -lg2 = 6.9314718246e-01f, /* 0x3f317218 */ -lg2_h = 6.93145752e-01f, /* 0x3f317200 */ -lg2_l = 1.42860654e-06f, /* 0x35bfbe8c */ -ovt = 4.2995665694e-08f, /* -(128-log2(ovfl+.5ulp)) */ -cp = 9.6179670095e-01f, /* 0x3f76384f =2/(3ln2) */ -cp_h = 9.6179199219e-01f, /* 0x3f763800 =head of cp */ -cp_l = 4.7017383622e-06f, /* 0x369dc3a0 =tail of cp_h */ -ivln2 = 1.4426950216e+00f, /* 0x3fb8aa3b =1/ln2 */ -ivln2_h = 1.4426879883e+00f, /* 0x3fb8aa00 =16b 1/ln2*/ -ivln2_l = 7.0526075433e-06f; /* 0x36eca570 =1/ln2 tail*/ + bp[] = { 1.0f, 1.5f, }, + dp_h[] = { 0.0f, 5.84960938e-01f, }, /* 0x3f15c000 */ + dp_l[] = { 0.0f, 1.56322085e-06f, }, /* 0x35d1cfdc */ + zero = 0.0f, + one = 1.0f, + two = 2.0f, + two24 = 16777216.0f, /* 0x4b800000 */ + /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ + L1 = 6.0000002384e-01f, /* 0x3f19999a */ + L2 = 4.2857143283e-01f, /* 0x3edb6db7 */ + L3 = 3.3333334327e-01f, /* 0x3eaaaaab */ + L4 = 2.7272811532e-01f, /* 0x3e8ba305 */ + L5 = 2.3066075146e-01f, /* 0x3e6c3255 */ + L6 = 2.0697501302e-01f, /* 0x3e53f142 */ + P1 = 1.6666667163e-01f, /* 0x3e2aaaab */ + P2 = -2.7777778450e-03f, /* 0xbb360b61 */ + P3 = 6.6137559770e-05f, /* 0x388ab355 */ + P4 = -1.6533901999e-06f, /* 0xb5ddea0e */ + P5 = 4.1381369442e-08f, /* 0x3331bb4c */ + lg2 = 6.9314718246e-01f, /* 0x3f317218 */ + lg2_h = 6.93145752e-01f, /* 0x3f317200 */ + lg2_l = 1.42860654e-06f, /* 0x35bfbe8c */ + ovt = 4.2995665694e-08f, /* -(128-log2(ovfl+.5ulp)) */ + cp = 9.6179670095e-01f, /* 0x3f76384f =2/(3ln2) */ + cp_h = 9.6179199219e-01f, /* 0x3f763800 =head of cp */ + cp_l = 4.7017383622e-06f, /* 0x369dc3a0 =tail of cp_h */ + ivln2 = 1.4426950216e+00f, /* 0x3fb8aa3b =1/ln2 */ + ivln2_h = 1.4426879883e+00f, /* 0x3fb8aa00 =16b 1/ln2*/ + ivln2_l = 7.0526075433e-06f; /* 0x36eca570 =1/ln2 tail*/ #ifdef __STDC__ Simple __ieee754_powf(Simple x, Simple y) #else - Simple __ieee754_powf(x,y) - Simple x, y; + Simple __ieee754_powf(x, y) + Simple x, y; #endif -{ - Simple z,ax,z_h,z_l,p_h,p_l; - Simple y1,t1,t2,r,s,t,u,v,w; - int32_t i,j,k,yisint,n; - int32_t hx,hy,ix,iy,is; + { + Simple z, ax, z_h, z_l, p_h, p_l; + Simple y1, t1, t2, r, s, t, u, v, w; + int32_t i, j, k, yisint, n; + int32_t hx, hy, ix, iy, is; - GET_FLOAT_WORD(hx,x); - GET_FLOAT_WORD(hy,y); - ix = hx&0x7fffffff; iy = hy&0x7fffffff; + GET_FLOAT_WORD(hx, x); + GET_FLOAT_WORD(hy, y); + ix = hx & 0x7fffffff; iy = hy & 0x7fffffff; - /* y==zero: x**0 = 1 */ - if(iy==0) return one; + /* y==zero: x**0 = 1 */ + if (iy == 0) return one; - /* x==+-1 */ - if(x == 1.0f) return one; - if(x == -1.0f && isinf(y)) return one; + /* x==+-1 */ + if (x == 1.0f) return one; + if (x == -1.0f && isinf(y)) return one; - /* +-NaN return x+y */ - if(ix > 0x7f800000 || - iy > 0x7f800000) - return x+y; + /* +-NaN return x+y */ + if (ix > 0x7f800000 || + iy > 0x7f800000) + return x + y; - /* determine if y is an odd int when x < 0 - * yisint = 0 ... y is not an integer - * yisint = 1 ... y is an odd int - * yisint = 2 ... y is an even int - */ - yisint = 0; - if(hx<0) { - if(iy>=0x4b800000) yisint = 2; /* even integer y */ - else if(iy>=0x3f800000) { - k = (iy>>23)-0x7f; /* exponent */ - j = iy>>(23-k); - if((j<<(23-k))==iy) yisint = 2-(j&1); - } + /* determine if y is an odd int when x < 0 + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + yisint = 0; + if (hx < 0) { + if (iy >= 0x4b800000) yisint = 2; /* even integer y */ + else if (iy >= 0x3f800000) { + k = (iy >> 23) - 0x7f; /* exponent */ + j = iy >> (23 - k); + if ((j << (23 - k)) == iy) yisint = 2 - (j & 1); + } + } + + /* special value of y */ + if (iy == 0x7f800000) { /* y is +-inf */ + if (ix == 0x3f800000) + return y - y; /* inf**+-1 is NaN */ + else if (ix > 0x3f800000)/* (|x|>1)**+-inf = inf,0 */ + return (hy >= 0) ? y : zero; + else /* (|x|<1)**-,+inf = inf,0 */ + return (hy < 0) ? -y : zero; + } + if (iy == 0x3f800000) { /* y is +-1 */ + if (hy < 0) return one / x; else return x; + } + if (hy == 0x40000000) return x*x; /* y is 2 */ + if (hy == 0x3f000000) { /* y is 0.5f */ + if (hx >= 0) /* x >= +0 */ + return __ieee754_sqrtf(x); + } + + ax = fabsf(x); + /* special value of x */ + if (ix == 0x7f800000 || ix == 0 || ix == 0x3f800000) { + z = ax; /*x is +-0,+-inf,+-1*/ + if (hy < 0) z = one / z; /* z = (1/|x|) */ + if (hx < 0) { + if (((ix - 0x3f800000) | yisint) == 0) { + z = (z - z) / (z - z); /* (-1)**non-int is NaN */ + } else if (yisint == 1) + z = -z; /* (x<0)**odd = -(|x|**odd) */ + } + return z; + } + + /* (x<0)**(non-int) is NaN */ + if (((((u_int32_t) hx >> 31) - 1) | yisint) == 0) return (x - x) / (x - x); + + /* |y| is huge */ + if (iy > 0x4d000000) { /* if |y| > 2**27 */ + /* over/underflow if x is not close to one */ + if (ix < 0x3f7ffff8) return (hy < 0) ? huge*huge : tiny*tiny; + if (ix > 0x3f800007) return (hy > 0) ? huge*huge : tiny*tiny; + /* now |1-x| is tiny <= 2**-20, suffice to compute + log(x) by x-x^2/2+x^3/3-x^4/4 */ + t = x - 1; /* t has 20 trailing zeros */ + w = (t*t)*((Simple)0.5f - t*((Simple)0.333333333333f - t*(Simple)0.25f)); + u = ivln2_h*t; /* ivln2_h has 16 sig. bits */ + v = t*ivln2_l - w*ivln2; + t1 = u + v; + GET_FLOAT_WORD(is, t1); + SET_FLOAT_WORD(t1, is & 0xfffff000); + t2 = v - (t1 - u); + } else { + Simple s2, s_h, s_l, t_h, t_l; + n = 0; + /* take care subnormal number */ + if (ix < 0x00800000) { + ax *= two24; n -= 24; GET_FLOAT_WORD(ix, ax); + } + n += ((ix) >> 23) - 0x7f; + j = ix & 0x007fffff; + /* determine interval */ + ix = j | 0x3f800000; /* normalize ix */ + if (j <= 0x1cc471) k = 0; /* |x|> 1) | 0x20000000) + 0x0040000 + (k << 21)); + t_l = ax - (t_h - bp[k]); + s_l = v*((u - s_h*t_h) - s_h*t_l); + /* compute log(ax) */ + s2 = s*s; + r = s2*s2*(L1 + s2*(L2 + s2*(L3 + s2*(L4 + s2*(L5 + s2*L6))))); + r += s_l*(s_h + s); + s2 = s_h*s_h; + t_h = (Simple)3.0f + s2 + r; + GET_FLOAT_WORD(is, t_h); + SET_FLOAT_WORD(t_h, is & 0xfffff000); + t_l = r - ((t_h - (Simple)3.0f) - s2); + /* u+v = s*(1+...) */ + u = s_h*t_h; + v = s_l*t_h + t_l*s; + /* 2/(3log2)*(s+...) */ + p_h = u + v; + GET_FLOAT_WORD(is, p_h); + SET_FLOAT_WORD(p_h, is & 0xfffff000); + p_l = v - (p_h - u); + z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ + z_l = cp_l*p_h + p_l*cp + dp_l[k]; + /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = (Simple) n; + t1 = (((z_h + z_l) + dp_h[k]) + t); + GET_FLOAT_WORD(is, t1); + SET_FLOAT_WORD(t1, is & 0xfffff000); + t2 = z_l - (((t1 - t) - dp_h[k]) - z_h); + } + + s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ + if (((((u_int32_t) hx >> 31) - 1) | (yisint - 1)) == 0) + s = -one; /* (-ve)**(odd int) */ + + /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ + GET_FLOAT_WORD(is, y); + SET_FLOAT_WORD(y1, is & 0xfffff000); + p_l = (y - y1)*t1 + y*t2; + p_h = y1*t1; + z = p_l + p_h; + GET_FLOAT_WORD(j, z); + if (j > 0x43000000) /* if z > 128 */ + return s*huge*huge; /* overflow */ + else if (j == 0x43000000) { /* if z == 128 */ + if (p_l + ovt > z - p_h) return s*huge*huge; /* overflow */ + } else if ((j & 0x7fffffff) > 0x43160000) /* z <= -150 */ + return s*tiny*tiny; /* underflow */ + else if ((u_int32_t) j == 0xc3160000) { /* z == -150 */ + if (p_l <= z - p_h) return s*tiny*tiny; /* underflow */ + } + /* + * compute 2**(p_h+p_l) + */ + i = j & 0x7fffffff; + k = (i >> 23) - 0x7f; + n = 0; + if (i > 0x3f000000) { /* if |z| > 0.5f, set n = [z+0.5f] */ + n = j + (0x00800000 >> (k + 1)); + k = ((n & 0x7fffffff) >> 23) - 0x7f; /* new k for n */ + SET_FLOAT_WORD(t, n&~(0x007fffff >> k)); + n = ((n & 0x007fffff) | 0x00800000) >> (23 - k); + if (j < 0) n = -n; + p_h -= t; + } + t = p_l + p_h; + GET_FLOAT_WORD(is, t); + SET_FLOAT_WORD(t, is & 0xfffff000); + u = t*lg2_h; + v = (p_l - (t - p_h))*lg2 + t*lg2_l; + z = u + v; + w = v - (z - u); + t = z*z; + t1 = z - t*(P1 + t*(P2 + t*(P3 + t*(P4 + t*P5)))); + r = (z*t1) / (t1 - two) - (w + z*w); + z = one - (r - z); + GET_FLOAT_WORD(j, z); + j += (n << 23); + if ((j >> 23) <= 0) z = __scalbnf(z, n); /* subnormal output */ + else SET_FLOAT_WORD(z, j); + return s*z; } - - /* special value of y */ - if (iy==0x7f800000) { /* y is +-inf */ - if (ix==0x3f800000) - return y - y; /* inf**+-1 is NaN */ - else if (ix > 0x3f800000)/* (|x|>1)**+-inf = inf,0 */ - return (hy>=0)? y: zero; - else /* (|x|<1)**-,+inf = inf,0 */ - return (hy<0)?-y: zero; - } - if(iy==0x3f800000) { /* y is +-1 */ - if(hy<0) return one/x; else return x; - } - if(hy==0x40000000) return x*x; /* y is 2 */ - if(hy==0x3f000000) { /* y is 0.5f */ - if(hx>=0) /* x >= +0 */ - return __ieee754_sqrtf(x); - } - - ax = fabsf(x); - /* special value of x */ - if(ix==0x7f800000||ix==0||ix==0x3f800000){ - z = ax; /*x is +-0,+-inf,+-1*/ - if(hy<0) z = one/z; /* z = (1/|x|) */ - if(hx<0) { - if(((ix-0x3f800000)|yisint)==0) { - z = (z-z)/(z-z); /* (-1)**non-int is NaN */ - } else if(yisint==1) - z = -z; /* (x<0)**odd = -(|x|**odd) */ - } - return z; - } - - /* (x<0)**(non-int) is NaN */ - if(((((u_int32_t)hx>>31)-1)|yisint)==0) return (x-x)/(x-x); - - /* |y| is huge */ - if(iy>0x4d000000) { /* if |y| > 2**27 */ - /* over/underflow if x is not close to one */ - if(ix<0x3f7ffff8) return (hy<0)? huge*huge:tiny*tiny; - if(ix>0x3f800007) return (hy>0)? huge*huge:tiny*tiny; - /* now |1-x| is tiny <= 2**-20, suffice to compute - log(x) by x-x^2/2+x^3/3-x^4/4 */ - t = x-1; /* t has 20 trailing zeros */ - w = (t*t)*((Simple)0.5f-t*((Simple)0.333333333333f-t*(Simple)0.25f)); - u = ivln2_h*t; /* ivln2_h has 16 sig. bits */ - v = t*ivln2_l-w*ivln2; - t1 = u+v; - GET_FLOAT_WORD(is,t1); - SET_FLOAT_WORD(t1,is&0xfffff000); - t2 = v-(t1-u); - } else { - Simple s2,s_h,s_l,t_h,t_l; - n = 0; - /* take care subnormal number */ - if(ix<0x00800000) - {ax *= two24; n -= 24; GET_FLOAT_WORD(ix,ax); } - n += ((ix)>>23)-0x7f; - j = ix&0x007fffff; - /* determine interval */ - ix = j|0x3f800000; /* normalize ix */ - if(j<=0x1cc471) k=0; /* |x|>1)|0x20000000)+0x0040000+(k<<21)); - t_l = ax - (t_h-bp[k]); - s_l = v*((u-s_h*t_h)-s_h*t_l); - /* compute log(ax) */ - s2 = s*s; - r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); - r += s_l*(s_h+s); - s2 = s_h*s_h; - t_h = (Simple)3.0f+s2+r; - GET_FLOAT_WORD(is,t_h); - SET_FLOAT_WORD(t_h,is&0xfffff000); - t_l = r-((t_h-(Simple)3.0f)-s2); - /* u+v = s*(1+...) */ - u = s_h*t_h; - v = s_l*t_h+t_l*s; - /* 2/(3log2)*(s+...) */ - p_h = u+v; - GET_FLOAT_WORD(is,p_h); - SET_FLOAT_WORD(p_h,is&0xfffff000); - p_l = v-(p_h-u); - z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ - z_l = cp_l*p_h+p_l*cp+dp_l[k]; - /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ - t = (Simple)n; - t1 = (((z_h+z_l)+dp_h[k])+t); - GET_FLOAT_WORD(is,t1); - SET_FLOAT_WORD(t1,is&0xfffff000); - t2 = z_l-(((t1-t)-dp_h[k])-z_h); - } - - s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ - if(((((u_int32_t)hx>>31)-1)|(yisint-1))==0) - s = -one; /* (-ve)**(odd int) */ - - /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ - GET_FLOAT_WORD(is,y); - SET_FLOAT_WORD(y1,is&0xfffff000); - p_l = (y-y1)*t1+y*t2; - p_h = y1*t1; - z = p_l+p_h; - GET_FLOAT_WORD(j,z); - if (j>0x43000000) /* if z > 128 */ - return s*huge*huge; /* overflow */ - else if (j==0x43000000) { /* if z == 128 */ - if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */ - } - else if ((j&0x7fffffff)>0x43160000) /* z <= -150 */ - return s*tiny*tiny; /* underflow */ - else if ((u_int32_t) j==0xc3160000){ /* z == -150 */ - if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */ - } - /* - * compute 2**(p_h+p_l) - */ - i = j&0x7fffffff; - k = (i>>23)-0x7f; - n = 0; - if(i>0x3f000000) { /* if |z| > 0.5f, set n = [z+0.5f] */ - n = j+(0x00800000>>(k+1)); - k = ((n&0x7fffffff)>>23)-0x7f; /* new k for n */ - SET_FLOAT_WORD(t,n&~(0x007fffff>>k)); - n = ((n&0x007fffff)|0x00800000)>>(23-k); - if(j<0) n = -n; - p_h -= t; - } - t = p_l+p_h; - GET_FLOAT_WORD(is,t); - SET_FLOAT_WORD(t,is&0xfffff000); - u = t*lg2_h; - v = (p_l-(t-p_h))*lg2+t*lg2_l; - z = u+v; - w = v-(z-u); - t = z*z; - t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); - r = (z*t1)/(t1-two)-(w+z*w); - z = one-(r-z); - GET_FLOAT_WORD(j,z); - j += (n<<23); - if((j>>23)<=0) z = __scalbnf(z,n); /* subnormal output */ - else SET_FLOAT_WORD(z,j); - return s*z; -} } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_rem_pio2f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_rem_pio2f.cpp index 030cfcce8..0226aaf28 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_rem_pio2f.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_rem_pio2f.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_rem_pio2f.c,v 1.5f 1995/05/10 20:46:03 jtc Exp $"; @@ -27,173 +27,178 @@ static char rcsid[] = "$NetBSD: e_rem_pio2f.c,v 1.5f 1995/05/10 20:46:03 jtc Exp #include "SMath.h" #include "math_private.h" -/* - * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi - */ + /* + * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi + */ namespace streflop_libm { #ifdef __STDC__ -static const int32_t two_over_pi[] = { -#else -static int32_t two_over_pi[] = { -#endif -0xA2, 0xF9, 0x83, 0x6E, 0x4E, 0x44, 0x15, 0x29, 0xFC, -0x27, 0x57, 0xD1, 0xF5, 0x34, 0xDD, 0xC0, 0xDB, 0x62, -0x95, 0x99, 0x3C, 0x43, 0x90, 0x41, 0xFE, 0x51, 0x63, -0xAB, 0xDE, 0xBB, 0xC5, 0x61, 0xB7, 0x24, 0x6E, 0x3A, -0x42, 0x4D, 0xD2, 0xE0, 0x06, 0x49, 0x2E, 0xEA, 0x09, -0xD1, 0x92, 0x1C, 0xFE, 0x1D, 0xEB, 0x1C, 0xB1, 0x29, -0xA7, 0x3E, 0xE8, 0x82, 0x35, 0xF5, 0x2E, 0xBB, 0x44, -0x84, 0xE9, 0x9C, 0x70, 0x26, 0xB4, 0x5F, 0x7E, 0x41, -0x39, 0x91, 0xD6, 0x39, 0x83, 0x53, 0x39, 0xF4, 0x9C, -0x84, 0x5F, 0x8B, 0xBD, 0xF9, 0x28, 0x3B, 0x1F, 0xF8, -0x97, 0xFF, 0xDE, 0x05, 0x98, 0x0F, 0xEF, 0x2F, 0x11, -0x8B, 0x5A, 0x0A, 0x6D, 0x1F, 0x6D, 0x36, 0x7E, 0xCF, -0x27, 0xCB, 0x09, 0xB7, 0x4F, 0x46, 0x3F, 0x66, 0x9E, -0x5F, 0xEA, 0x2D, 0x75, 0x27, 0xBA, 0xC7, 0xEB, 0xE5, -0xF1, 0x7B, 0x3D, 0x07, 0x39, 0xF7, 0x8A, 0x52, 0x92, -0xEA, 0x6B, 0xFB, 0x5F, 0xB1, 0x1F, 0x8D, 0x5D, 0x08, -0x56, 0x03, 0x30, 0x46, 0xFC, 0x7B, 0x6B, 0xAB, 0xF0, -0xCF, 0xBC, 0x20, 0x9A, 0xF4, 0x36, 0x1D, 0xA9, 0xE3, -0x91, 0x61, 0x5E, 0xE6, 0x1B, 0x08, 0x65, 0x99, 0x85, -0x5F, 0x14, 0xA0, 0x68, 0x40, 0x8D, 0xFF, 0xD8, 0x80, -0x4D, 0x73, 0x27, 0x31, 0x06, 0x06, 0x15, 0x56, 0xCA, -0x73, 0xA8, 0xC9, 0x60, 0xE2, 0x7B, 0xC0, 0x8C, 0x6B, -}; + static const int32_t two_over_pi[] = { + #else + static int32_t two_over_pi[] = { + #endif + 0xA2, 0xF9, 0x83, 0x6E, 0x4E, 0x44, 0x15, 0x29, 0xFC, + 0x27, 0x57, 0xD1, 0xF5, 0x34, 0xDD, 0xC0, 0xDB, 0x62, + 0x95, 0x99, 0x3C, 0x43, 0x90, 0x41, 0xFE, 0x51, 0x63, + 0xAB, 0xDE, 0xBB, 0xC5, 0x61, 0xB7, 0x24, 0x6E, 0x3A, + 0x42, 0x4D, 0xD2, 0xE0, 0x06, 0x49, 0x2E, 0xEA, 0x09, + 0xD1, 0x92, 0x1C, 0xFE, 0x1D, 0xEB, 0x1C, 0xB1, 0x29, + 0xA7, 0x3E, 0xE8, 0x82, 0x35, 0xF5, 0x2E, 0xBB, 0x44, + 0x84, 0xE9, 0x9C, 0x70, 0x26, 0xB4, 0x5F, 0x7E, 0x41, + 0x39, 0x91, 0xD6, 0x39, 0x83, 0x53, 0x39, 0xF4, 0x9C, + 0x84, 0x5F, 0x8B, 0xBD, 0xF9, 0x28, 0x3B, 0x1F, 0xF8, + 0x97, 0xFF, 0xDE, 0x05, 0x98, 0x0F, 0xEF, 0x2F, 0x11, + 0x8B, 0x5A, 0x0A, 0x6D, 0x1F, 0x6D, 0x36, 0x7E, 0xCF, + 0x27, 0xCB, 0x09, 0xB7, 0x4F, 0x46, 0x3F, 0x66, 0x9E, + 0x5F, 0xEA, 0x2D, 0x75, 0x27, 0xBA, 0xC7, 0xEB, 0xE5, + 0xF1, 0x7B, 0x3D, 0x07, 0x39, 0xF7, 0x8A, 0x52, 0x92, + 0xEA, 0x6B, 0xFB, 0x5F, 0xB1, 0x1F, 0x8D, 0x5D, 0x08, + 0x56, 0x03, 0x30, 0x46, 0xFC, 0x7B, 0x6B, 0xAB, 0xF0, + 0xCF, 0xBC, 0x20, 0x9A, 0xF4, 0x36, 0x1D, 0xA9, 0xE3, + 0x91, 0x61, 0x5E, 0xE6, 0x1B, 0x08, 0x65, 0x99, 0x85, + 0x5F, 0x14, 0xA0, 0x68, 0x40, 0x8D, 0xFF, 0xD8, 0x80, + 0x4D, 0x73, 0x27, 0x31, 0x06, 0x06, 0x15, 0x56, 0xCA, + 0x73, 0xA8, 0xC9, 0x60, 0xE2, 0x7B, 0xC0, 0x8C, 0x6B, + }; -/* This array is like the one in e_rem_pio2.c, but the numbers are - single precision and the last 8 bits are forced to 0. */ -#ifdef __STDC__ -static const int32_t npio2_hw[] = { -#else -static int32_t npio2_hw[] = { -#endif -0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00, -0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00, -0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100, -0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00, -0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00, -0x4242c700, 0x42490f00 -}; + /* This array is like the one in e_rem_pio2.c, but the numbers are + single precision and the last 8 bits are forced to 0. */ + #ifdef __STDC__ + static const int32_t npio2_hw[] = { + #else + static int32_t npio2_hw[] = { + #endif + 0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00, + 0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00, + 0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100, + 0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00, + 0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00, + 0x4242c700, 0x42490f00 + }; -/* - * invpio2: 24 bits of 2/pi - * pio2_1: first 17 bit of pi/2 - * pio2_1t: pi/2 - pio2_1 - * pio2_2: second 17 bit of pi/2 - * pio2_2t: pi/2 - (pio2_1+pio2_2) - * pio2_3: third 17 bit of pi/2 - * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) - */ + /* + * invpio2: 24 bits of 2/pi + * pio2_1: first 17 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 17 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 17 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ -#ifdef __STDC__ -static const Simple -#else -static Simple -#endif -zero = 0.0000000000e+00f, /* 0x00000000 */ -half = 5.0000000000e-01f, /* 0x3f000000 */ -two8 = 2.5600000000e+02f, /* 0x43800000 */ -invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */ -pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */ -pio2_1t = 1.0804334124e-05f, /* 0x37354443 */ -pio2_2 = 1.0804273188e-05f, /* 0x37354400 */ -pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */ -pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */ -pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */ + #ifdef __STDC__ + static const Simple + #else + static Simple + #endif + zero = 0.0000000000e+00f, /* 0x00000000 */ + half = 5.0000000000e-01f, /* 0x3f000000 */ + two8 = 2.5600000000e+02f, /* 0x43800000 */ + invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */ + pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */ + pio2_1t = 1.0804334124e-05f, /* 0x37354443 */ + pio2_2 = 1.0804273188e-05f, /* 0x37354400 */ + pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */ + pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */ + pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */ -#ifdef __STDC__ - int32_t __ieee754_rem_pio2f(Simple x, Simple *y) -#else - int32_t __ieee754_rem_pio2f(x,y) - Simple x,y[]; -#endif -{ - Simple z,w,t,r,fn; - Simple tx[3]; - int32_t e0,i,j,nx,n,ix,hx; + #ifdef __STDC__ + int32_t __ieee754_rem_pio2f(Simple x, Simple *y) + #else + int32_t __ieee754_rem_pio2f(x,y) + Simple x,y[]; + #endif + { + Simple z,w,t,r,fn; + Simple tx[3]; + int32_t e0,i,j,nx,n,ix,hx; - GET_FLOAT_WORD(hx,x); - ix = hx&0x7fffffff; - if(ix<=0x3f490fd8) /* |x| ~<= pi/4 , no need for reduction */ - {y[0] = x; y[1] = 0; return 0;} - if(ix<0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */ - if(hx>0) { - z = x - pio2_1; - if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ - y[0] = z - pio2_1t; - y[1] = (z-y[0])-pio2_1t; - } else { /* near pi/2, use 24+24+24 bit pi */ - z -= pio2_2; - y[0] = z - pio2_2t; - y[1] = (z-y[0])-pio2_2t; - } - return 1; - } else { /* negative x */ - z = x + pio2_1; - if((ix&0xfffffff0)!=0x3fc90fd0) { /* 24+24 bit pi OK */ - y[0] = z + pio2_1t; - y[1] = (z-y[0])+pio2_1t; - } else { /* near pi/2, use 24+24+24 bit pi */ - z += pio2_2; - y[0] = z + pio2_2t; - y[1] = (z-y[0])+pio2_2t; - } - return -1; - } + GET_FLOAT_WORD(hx,x); + ix = hx & 0x7fffffff; + if (ix <= 0x3f490fd8) /* |x| ~<= pi/4 , no need for reduction */ + { + y[0] = x; y[1] = 0; return 0; +} +if (ix < 0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */ + if (hx > 0) { + z = x - pio2_1; + if ((ix & 0xfffffff0) != 0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z - pio2_1t; + y[1] = (z - y[0]) - pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z -= pio2_2; + y[0] = z - pio2_2t; + y[1] = (z - y[0]) - pio2_2t; } - if(ix<=0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */ - t = fabsf(x); - n = (int32_t) (t*invpio2+half); - fn = (Simple)n; - r = t-fn*pio2_1; - w = fn*pio2_1t; /* 1st round good to 40 bit */ - if(n<32&&(int32_t)(ix&0xffffff00)!=npio2_hw[n-1]) { - y[0] = r-w; /* quick check no cancellation */ - } else { - u_int32_t high; - j = ix>>23; - y[0] = r-w; + return 1; + } else { /* negative x */ + z = x + pio2_1; + if ((ix & 0xfffffff0) != 0x3fc90fd0) { /* 24+24 bit pi OK */ + y[0] = z + pio2_1t; + y[1] = (z - y[0]) + pio2_1t; + } else { /* near pi/2, use 24+24+24 bit pi */ + z += pio2_2; + y[0] = z + pio2_2t; + y[1] = (z - y[0]) + pio2_2t; + } + return -1; + } +} +if (ix <= 0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */ + t = fabsf(x); + n = (int32_t) (t*invpio2 + half); + fn = (Simple) n; + r = t - fn*pio2_1; + w = fn*pio2_1t; /* 1st round good to 40 bit */ + if (n < 32 && (int32_t) (ix & 0xffffff00) != npio2_hw[n - 1]) { + y[0] = r - w; /* quick check no cancellation */ + } else { + u_int32_t high; + j = ix >> 23; + y[0] = r - w; + GET_FLOAT_WORD(high,y[0]); + i = j - ((high >> 23) & 0xff); + if (i > 8) { /* 2nd iteration needed, good to 57 */ + t = r; + w = fn*pio2_2; + r = t - w; + w = fn*pio2_2t - ((t - r) - w); + y[0] = r - w; GET_FLOAT_WORD(high,y[0]); - i = j-((high>>23)&0xff); - if(i>8) { /* 2nd iteration needed, good to 57 */ - t = r; - w = fn*pio2_2; - r = t-w; - w = fn*pio2_2t-((t-r)-w); - y[0] = r-w; - GET_FLOAT_WORD(high,y[0]); - i = j-((high>>23)&0xff); - if(i>25) { /* 3rd iteration need, 74 bits acc */ - t = r; /* will cover all possible cases */ - w = fn*pio2_3; - r = t-w; - w = fn*pio2_3t-((t-r)-w); - y[0] = r-w; - } + i = j - ((high >> 23) & 0xff); + if (i > 25) { /* 3rd iteration need, 74 bits acc */ + t = r; /* will cover all possible cases */ + w = fn*pio2_3; + r = t - w; + w = fn*pio2_3t - ((t - r) - w); + y[0] = r - w; } - } - y[1] = (r-y[0])-w; - if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} - else return n; } - /* - * all other (large) arguments - */ - if(ix>=0x7f800000) { /* x is inf or NaN */ - y[0]=y[1]=x-x; return 0; } - /* set z = scalbn(|x|,ilogb(x)-7) */ - e0 = (ix>>23)-134; /* e0 = ilogb(z)-7; */ - SET_FLOAT_WORD(z, ix - ((int32_t)(e0<<23))); - for(i=0;i<2;i++) { - tx[i] = (Simple)((int32_t)(z)); - z = (z-tx[i])*two8; - } - tx[2] = z; - nx = 3; - while(tx[nx-1]==zero) nx--; /* skip zero term */ - n = __kernel_rem_pio2f(tx,y,e0,nx,2,two_over_pi); - if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} - return n; + y[1] = (r - y[0]) - w; + if (hx < 0) { +y[0] = -y[0]; y[1] = -y[1]; return -n; +} else return n; +} +/* + * all other (large) arguments + */ +if (ix >= 0x7f800000) { /* x is inf or NaN */ + y[0] = y[1] = x - x; return 0; +} +/* set z = scalbn(|x|,ilogb(x)-7) */ +e0 = (ix >> 23) - 134; /* e0 = ilogb(z)-7; */ +SET_FLOAT_WORD(z, ix - ((int32_t) (e0 << 23))); +for (i = 0; i < 2; i++) { + tx[i] = (Simple) ((int32_t) (z)); + z = (z - tx[i])*two8; +} +tx[2] = z; +nx = 3; +while (tx[nx - 1] == zero) nx--; /* skip zero term */ +n = __kernel_rem_pio2f(tx,y,e0,nx,2,two_over_pi); +if (hx < 0) { +y[0] = -y[0]; y[1] = -y[1]; return -n; +} +return n; } } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_remainderf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_remainderf.cpp index c47001007..bb6aec23c 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_remainderf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_remainderf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_remainderf.c,v 1.4f 1995/05/10 20:46:08 jtc Exp $"; @@ -23,54 +23,54 @@ static char rcsid[] = "$NetBSD: e_remainderf.c,v 1.4f 1995/05/10 20:46:08 jtc Ex namespace streflop_libm { #ifdef __STDC__ -static const Simple zero = 0.0f; + static const Simple zero = 0.0f; #else -static Simple zero = 0.0f; + static Simple zero = 0.0f; #endif #ifdef __STDC__ Simple __ieee754_remainderf(Simple x, Simple p) #else - Simple __ieee754_remainderf(x,p) - Simple x,p; + Simple __ieee754_remainderf(x, p) + Simple x, p; #endif -{ - int32_t hx,hp; - u_int32_t sx; - Simple p_half; + { + int32_t hx, hp; + u_int32_t sx; + Simple p_half; - GET_FLOAT_WORD(hx,x); - GET_FLOAT_WORD(hp,p); - sx = hx&0x80000000; - hp &= 0x7fffffff; - hx &= 0x7fffffff; + GET_FLOAT_WORD(hx, x); + GET_FLOAT_WORD(hp, p); + sx = hx & 0x80000000; + hp &= 0x7fffffff; + hx &= 0x7fffffff; - /* purge off exception values */ - if(hp==0) return (x*p)/(x*p); /* p = 0 */ - if((hx>=0x7f800000)|| /* x not finite */ - ((hp>0x7f800000))) /* p is NaN */ - return (x*p)/(x*p); + /* purge off exception values */ + if (hp == 0) return (x*p) / (x*p); /* p = 0 */ + if ((hx >= 0x7f800000) || /* x not finite */ + ((hp > 0x7f800000))) /* p is NaN */ + return (x*p) / (x*p); - if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p); /* now x < 2p */ - if ((hx-hp)==0) return zero*x; - x = fabsf(x); - p = fabsf(p); - if (hp<0x01000000) { - if(x+x>p) { - x-=p; - if(x+x>=p) x -= p; - } - } else { - p_half = (Simple)0.5f*p; - if(x>p_half) { - x-=p; - if(x>=p_half) x -= p; - } + if (hp <= 0x7effffff) x = __ieee754_fmodf(x, p + p); /* now x < 2p */ + if ((hx - hp) == 0) return zero*x; + x = fabsf(x); + p = fabsf(p); + if (hp < 0x01000000) { + if (x + x > p) { + x -= p; + if (x + x >= p) x -= p; + } + } else { + p_half = (Simple)0.5f*p; + if (x > p_half) { + x -= p; + if (x >= p_half) x -= p; + } + } + GET_FLOAT_WORD(hx, x); + SET_FLOAT_WORD(x, hx^sx); + return x; } - GET_FLOAT_WORD(hx,x); - SET_FLOAT_WORD(x,hx^sx); - return x; -} } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_sinhf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_sinhf.cpp index b2adf65e1..b595c9b78 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_sinhf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_sinhf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_sinhf.c,v 1.4f 1995/05/10 20:46:15 jtc Exp $"; @@ -23,49 +23,49 @@ static char rcsid[] = "$NetBSD: e_sinhf.c,v 1.4f 1995/05/10 20:46:15 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static const Simple one = 1.0f, shuge = 1.0e37f; + static const Simple one = 1.0f, shuge = 1.0e37f; #else -static Simple one = 1.0f, shuge = 1.0e37f; + static Simple one = 1.0f, shuge = 1.0e37f; #endif #ifdef __STDC__ Simple __ieee754_sinhf(Simple x) #else Simple __ieee754_sinhf(x) - Simple x; + Simple x; #endif -{ - Simple t,w,h; - int32_t ix,jx; + { + Simple t, w, h; + int32_t ix, jx; - GET_FLOAT_WORD(jx,x); - ix = jx&0x7fffffff; + GET_FLOAT_WORD(jx, x); + ix = jx & 0x7fffffff; - /* x is INF or NaN */ - if(ix>=0x7f800000) return x+x; + /* x is INF or NaN */ + if (ix >= 0x7f800000) return x + x; - h = 0.5f; - if (jx<0) h = -h; - /* |x| in [0,22], return sign(x)*0.5f*(E+E/(E+1))) */ - if (ix < 0x41b00000) { /* |x|<22 */ - if (ix<0x31800000) /* |x|<2**-28 */ - if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */ - t = __expm1f(fabsf(x)); - if(ix<0x3f800000) return h*((Simple)2.0f*t-t*t/(t+one)); - return h*(t+t/(t+one)); + h = 0.5f; + if (jx < 0) h = -h; + /* |x| in [0,22], return sign(x)*0.5f*(E+E/(E+1))) */ + if (ix < 0x41b00000) { /* |x|<22 */ + if (ix < 0x31800000) /* |x|<2**-28 */ + if (shuge + x > one) return x;/* sinh(tiny) = tiny with inexact */ + t = __expm1f(fabsf(x)); + if (ix < 0x3f800000) return h*((Simple)2.0f*t - t*t / (t + one)); + return h*(t + t / (t + one)); + } + + /* |x| in [22, log(maxdouble)] return 0.5f*exp(|x|) */ + if (ix < 0x42b17180) return h*__ieee754_expf(fabsf(x)); + + /* |x| in [log(maxdouble), overflowthresold] */ + if (ix <= 0x42b2d4fc) { + w = __ieee754_expf((Simple)0.5f*fabsf(x)); + t = h*w; + return t*w; + } + + /* |x| > overflowthresold, sinh(x) overflow */ + return x*shuge; } - - /* |x| in [22, log(maxdouble)] return 0.5f*exp(|x|) */ - if (ix < 0x42b17180) return h*__ieee754_expf(fabsf(x)); - - /* |x| in [log(maxdouble), overflowthresold] */ - if (ix<=0x42b2d4fc) { - w = __ieee754_expf((Simple)0.5f*fabsf(x)); - t = h*w; - return t*w; - } - - /* |x| > overflowthresold, sinh(x) overflow */ - return x*shuge; -} } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/e_sqrtf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/e_sqrtf.cpp index bb267c284..59554320e 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/e_sqrtf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/e_sqrtf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: e_sqrtf.c,v 1.4f 1995/05/10 20:46:19 jtc Exp $"; @@ -23,78 +23,78 @@ static char rcsid[] = "$NetBSD: e_sqrtf.c,v 1.4f 1995/05/10 20:46:19 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static const Simple one = 1.0f, tiny=1.0e-30f; + static const Simple one = 1.0f, tiny = 1.0e-30f; #else -static Simple one = 1.0f, tiny=1.0e-30f; + static Simple one = 1.0f, tiny = 1.0e-30f; #endif #ifdef __STDC__ Simple __ieee754_sqrtf(Simple x) #else Simple __ieee754_sqrtf(x) - Simple x; + Simple x; #endif -{ - Simple z; - int32_t sign = (int)0x80000000; - int32_t ix,s,q,m,t,i; - u_int32_t r; + { + Simple z; + int32_t sign = (int) 0x80000000; + int32_t ix, s, q, m, t, i; + u_int32_t r; - GET_FLOAT_WORD(ix,x); + GET_FLOAT_WORD(ix, x); - /* take care of Inf and NaN */ - if((ix&0x7f800000)==0x7f800000) { - return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf - sqrt(-inf)=sNaN */ - } - /* take care of zero */ - if(ix<=0) { - if((ix&(~sign))==0) return x;/* sqrt(+-0) = +-0 */ - else if(ix<0) - return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ + /* take care of Inf and NaN */ + if ((ix & 0x7f800000) == 0x7f800000) { + return x*x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf + sqrt(-inf)=sNaN */ + } + /* take care of zero */ + if (ix <= 0) { + if ((ix&(~sign)) == 0) return x;/* sqrt(+-0) = +-0 */ + else if (ix < 0) + return (x - x) / (x - x); /* sqrt(-ve) = sNaN */ + } + /* normalize x */ + m = (ix >> 23); + if (m == 0) { /* subnormal x */ + for (i = 0; (ix & 0x00800000) == 0; i++) ix <<= 1; + m -= i - 1; + } + m -= 127; /* unbias exponent */ + ix = (ix & 0x007fffff) | 0x00800000; + if (m & 1) /* odd m, Double x to make it even */ + ix += ix; + m >>= 1; /* m = [m/2] */ + + /* generate sqrt(x) bit by bit */ + ix += ix; + q = s = 0; /* q = sqrt(x) */ + r = 0x01000000; /* r = moving bit from right to left */ + + while (r != 0) { + t = s + r; + if (t <= ix) { + s = t + r; + ix -= t; + q += r; + } + ix += ix; + r >>= 1; + } + + /* use floating add to find out rounding direction */ + if (ix != 0) { + z = one - tiny; /* trigger inexact flag */ + if (z >= one) { + z = one + tiny; + if (z > one) + q += 2; + else + q += (q & 1); + } + } + ix = (q >> 1) + 0x3f000000; + ix += (m << 23); + SET_FLOAT_WORD(z, ix); + return z; } - /* normalize x */ - m = (ix>>23); - if(m==0) { /* subnormal x */ - for(i=0;(ix&0x00800000)==0;i++) ix<<=1; - m -= i-1; - } - m -= 127; /* unbias exponent */ - ix = (ix&0x007fffff)|0x00800000; - if(m&1) /* odd m, Double x to make it even */ - ix += ix; - m >>= 1; /* m = [m/2] */ - - /* generate sqrt(x) bit by bit */ - ix += ix; - q = s = 0; /* q = sqrt(x) */ - r = 0x01000000; /* r = moving bit from right to left */ - - while(r!=0) { - t = s+r; - if(t<=ix) { - s = t+r; - ix -= t; - q += r; - } - ix += ix; - r>>=1; - } - - /* use floating add to find out rounding direction */ - if(ix!=0) { - z = one-tiny; /* trigger inexact flag */ - if (z>=one) { - z = one+tiny; - if (z>one) - q += 2; - else - q += (q&1); - } - } - ix = (q>>1)+0x3f000000; - ix += (m <<23); - SET_FLOAT_WORD(z,ix); - return z; -} } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/k_cosf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/k_cosf.cpp index 96607705d..ef2e2d277 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/k_cosf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/k_cosf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: k_cosf.c,v 1.4f 1995/05/10 20:46:23 jtc Exp $"; @@ -23,45 +23,45 @@ static char rcsid[] = "$NetBSD: k_cosf.c,v 1.4f 1995/05/10 20:46:23 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -one = 1.0000000000e+00f, /* 0x3f800000 */ -C1 = 4.1666667908e-02f, /* 0x3d2aaaab */ -C2 = -1.3888889225e-03f, /* 0xbab60b61 */ -C3 = 2.4801587642e-05f, /* 0x37d00d01 */ -C4 = -2.7557314297e-07f, /* 0xb493f27c */ -C5 = 2.0875723372e-09f, /* 0x310f74f6 */ -C6 = -1.1359647598e-11f; /* 0xad47d74e */ + one = 1.0000000000e+00f, /* 0x3f800000 */ + C1 = 4.1666667908e-02f, /* 0x3d2aaaab */ + C2 = -1.3888889225e-03f, /* 0xbab60b61 */ + C3 = 2.4801587642e-05f, /* 0x37d00d01 */ + C4 = -2.7557314297e-07f, /* 0xb493f27c */ + C5 = 2.0875723372e-09f, /* 0x310f74f6 */ + C6 = -1.1359647598e-11f; /* 0xad47d74e */ #ifdef __STDC__ Simple __kernel_cosf(Simple x, Simple y) #else Simple __kernel_cosf(x, y) - Simple x,y; + Simple x, y; #endif -{ - Simple a,hz,z,r,qx; - int32_t ix; - GET_FLOAT_WORD(ix,x); - ix &= 0x7fffffff; /* ix = |x|'s high word*/ - if(ix<0x32000000) { /* if x < 2**27 */ - if(((int)x)==0) return one; /* generate inexact */ - } - z = x*x; - r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6))))); - if(ix < 0x3e99999a) /* if |x| < 0.3f */ - return one - ((Simple)0.5f*z - (z*r - x*y)); - else { - if(ix > 0x3f480000) { /* x > 0.78125f */ - qx = (Simple)0.28125f; - } else { - SET_FLOAT_WORD(qx,ix-0x01000000); /* x/4 */ - } - hz = (Simple)0.5f*z-qx; - a = one-qx; - return a - (hz - (z*r-x*y)); + { + Simple a, hz, z, r, qx; + int32_t ix; + GET_FLOAT_WORD(ix, x); + ix &= 0x7fffffff; /* ix = |x|'s high word*/ + if (ix < 0x32000000) { /* if x < 2**27 */ + if (((int) x) == 0) return one; /* generate inexact */ + } + z = x*x; + r = z*(C1 + z*(C2 + z*(C3 + z*(C4 + z*(C5 + z*C6))))); + if (ix < 0x3e99999a) /* if |x| < 0.3f */ + return one - ((Simple)0.5f*z - (z*r - x*y)); + else { + if (ix > 0x3f480000) { /* x > 0.78125f */ + qx = (Simple)0.28125f; + } else { + SET_FLOAT_WORD(qx, ix - 0x01000000); /* x/4 */ + } + hz = (Simple)0.5f*z - qx; + a = one - qx; + return a - (hz - (z*r - x*y)); + } } } -} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/k_rem_pio2f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/k_rem_pio2f.cpp index 73583bad7..a130e12ef 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/k_rem_pio2f.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/k_rem_pio2f.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: k_rem_pio2f.c,v 1.4f 1995/05/10 20:46:28 jtc Exp $"; @@ -26,191 +26,192 @@ static char rcsid[] = "$NetBSD: k_rem_pio2f.c,v 1.4f 1995/05/10 20:46:28 jtc Exp namespace streflop_libm { #ifdef __STDC__ -static const int init_jk[] = {4,7,9}; /* initial value for jk */ + static const int init_jk[] = { 4,7,9 }; /* initial value for jk */ #else -static int init_jk[] = {4,7,9}; + static int init_jk[] = { 4,7,9 }; #endif #ifdef __STDC__ -static const Simple PIo2[] = { -#else -static Simple PIo2[] = { -#endif - 1.5703125000e+00f, /* 0x3fc90000 */ - 4.5776367188e-04f, /* 0x39f00000 */ - 2.5987625122e-05f, /* 0x37da0000 */ - 7.5437128544e-08f, /* 0x33a20000 */ - 6.0026650317e-11f, /* 0x2e840000 */ - 7.3896444519e-13f, /* 0x2b500000 */ - 5.3845816694e-15f, /* 0x27c20000 */ - 5.6378512969e-18f, /* 0x22d00000 */ - 8.3009228831e-20f, /* 0x1fc40000 */ - 3.2756352257e-22f, /* 0x1bc60000 */ - 6.3331015649e-25f, /* 0x17440000 */ -}; + static const Simple PIo2[] = { + #else + static Simple PIo2[] = { + #endif + 1.5703125000e+00f, /* 0x3fc90000 */ + 4.5776367188e-04f, /* 0x39f00000 */ + 2.5987625122e-05f, /* 0x37da0000 */ + 7.5437128544e-08f, /* 0x33a20000 */ + 6.0026650317e-11f, /* 0x2e840000 */ + 7.3896444519e-13f, /* 0x2b500000 */ + 5.3845816694e-15f, /* 0x27c20000 */ + 5.6378512969e-18f, /* 0x22d00000 */ + 8.3009228831e-20f, /* 0x1fc40000 */ + 3.2756352257e-22f, /* 0x1bc60000 */ + 6.3331015649e-25f, /* 0x17440000 */ + }; -#ifdef __STDC__ -static const Simple -#else -static Simple -#endif -zero = 0.0f, -one = 1.0f, -two8 = 2.5600000000e+02f, /* 0x43800000 */ -twon8 = 3.9062500000e-03f; /* 0x3b800000 */ + #ifdef __STDC__ + static const Simple + #else + static Simple + #endif + zero = 0.0f, + one = 1.0f, + two8 = 2.5600000000e+02f, /* 0x43800000 */ + twon8 = 3.9062500000e-03f; /* 0x3b800000 */ -#ifdef __STDC__ - int __kernel_rem_pio2f(Simple *x, Simple *y, int e0, int nx, int prec, const int32_t *ipio2) -#else - int __kernel_rem_pio2f(x,y,e0,nx,prec,ipio2) - Simple x[], y[]; int e0,nx,prec; int32_t ipio2[]; -#endif -{ - int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; - Simple z,fw,f[20],fq[20],q[20]; + #ifdef __STDC__ + int __kernel_rem_pio2f(Simple *x, Simple *y, int e0, int nx, int prec, const int32_t *ipio2) + #else + int __kernel_rem_pio2f(x,y,e0,nx,prec,ipio2) + Simple x[], y[]; int e0,nx,prec; int32_t ipio2[]; + #endif + { + int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; + Simple z,fw,f[20],fq[20],q[20]; - /* initialize jk*/ - jk = init_jk[prec]; - jp = jk; + /* initialize jk*/ + jk = init_jk[prec]; + jp = jk; - /* determine jx,jv,q0, note that 3>q0 */ - jx = nx-1; - jv = (e0-3)/8; if(jv<0) jv=0; - q0 = e0-8*(jv+1); + /* determine jx,jv,q0, note that 3>q0 */ + jx = nx - 1; + jv = (e0 - 3) / 8; if (jv < 0) jv = 0; + q0 = e0 - 8 * (jv + 1); - /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ - j = jv-jx; m = jx+jk; - for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (Simple) ipio2[j]; + /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ + j = jv - jx; m = jx + jk; + for (i = 0; i <= m; i++,j++) f[i] = (j < 0) ? zero : (Simple) ipio2[j]; - /* compute q[0],q[1],...q[jk] */ - for (i=0;i<=jk;i++) { - for(j=0,fw=0.0f;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw; - } - - jz = jk; -recompute: - /* distill q[] into iq[] reversingly */ - for(i=0,j=jz,z=q[jz];j>0;i++,j--) { - fw = (Simple)((int32_t)(twon8* z)); - iq[i] = (int32_t)(z-two8*fw); - z = q[j-1]+fw; - } - - /* compute n */ - z = __scalbnf(z,q0); /* actual value of z */ - z -= (Simple)8.0f*__floorf(z*(Simple)0.125f); /* trim off integer >= 8 */ - n = (int32_t) z; - z -= (Simple)n; - ih = 0; - if(q0>0) { /* need iq[jz-1] to determine n */ - i = (iq[jz-1]>>(8-q0)); n += i; - iq[jz-1] -= i<<(8-q0); - ih = iq[jz-1]>>(7-q0); - } - else if(q0==0) ih = iq[jz-1]>>8; - else if(z>=(Simple)0.5f) ih=2; - - if(ih>0) { /* q > 0.5f */ - n += 1; carry = 0; - for(i=0;i0) { /* rare case: chance is 1 in 12 */ - switch(q0) { - case 1: - iq[jz-1] &= 0x7f; break; - case 2: - iq[jz-1] &= 0x3f; break; - } - } - if(ih==2) { - z = one - z; - if(carry!=0) z -= __scalbnf(one,q0); - } - } - - /* check if recomputation is needed */ - if(z==zero) { - j = 0; - for (i=jz-1;i>=jk;i--) j |= iq[i]; - if(j==0) { /* need recomputation */ - for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */ - - for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */ - f[jx+i] = (Simple) ipio2[jv+i]; - for(j=0,fw=0.0f;j<=jx;j++) fw += x[j]*f[jx+i-j]; - q[i] = fw; + /* compute q[0],q[1],...q[jk] */ + for (i = 0; i <= jk; i++) { + for (j = 0,fw = 0.0f; j <= jx; j++) fw += x[j] * f[jx + i - j]; q[i] = fw; } - jz += k; - goto recompute; - } - } - /* chop off zero terms */ - if(z==(Simple)0.0f) { - jz -= 1; q0 -= 8; - while(iq[jz]==0) { jz--; q0-=8;} - } else { /* break z into 8-bit if necessary */ - z = __scalbnf(z,-q0); - if(z>=two8) { - fw = (Simple)((int32_t)(twon8*z)); - iq[jz] = (int32_t)(z-two8*fw); - jz += 1; q0 += 8; - iq[jz] = (int32_t) fw; - } else iq[jz] = (int32_t) z ; - } - - /* convert integer "bit" chunk to floating-point value */ - fw = __scalbnf(one,q0); - for(i=jz;i>=0;i--) { - q[i] = fw*(Simple)iq[i]; fw*=twon8; - } - - /* compute PIo2[0,...,jp]*q[jz,...,0] */ - for(i=jz;i>=0;i--) { - for(fw=0.0f,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k]; - fq[jz-i] = fw; - } - - /* compress fq[] into y[] */ - switch(prec) { - case 0: - fw = 0.0f; - for (i=jz;i>=0;i--) fw += fq[i]; - y[0] = (ih==0)? fw: -fw; - break; - case 1: - case 2: - fw = 0.0f; - for (i=jz;i>=0;i--) fw += fq[i]; - y[0] = (ih==0)? fw: -fw; - fw = fq[0]-fw; - for (i=1;i<=jz;i++) fw += fq[i]; - y[1] = (ih==0)? fw: -fw; - break; - case 3: /* painful */ - for (i=jz;i>0;i--) { - fw = fq[i-1]+fq[i]; - fq[i] += fq[i-1]-fw; - fq[i-1] = fw; + jz = jk; + recompute: + /* distill q[] into iq[] reversingly */ + for (i = 0,j = jz,z = q[jz]; j > 0; i++,j--) { + fw = (Simple) ((int32_t) (twon8* z)); + iq[i] = (int32_t) (z - two8*fw); + z = q[j - 1] + fw; } - for (i=jz;i>1;i--) { - fw = fq[i-1]+fq[i]; - fq[i] += fq[i-1]-fw; - fq[i-1] = fw; + + /* compute n */ + z = __scalbnf(z,q0); /* actual value of z */ + z -= (Simple)8.0f*__floorf(z*(Simple)0.125f); /* trim off integer >= 8 */ + n = (int32_t) z; + z -= (Simple) n; + ih = 0; + if (q0 > 0) { /* need iq[jz-1] to determine n */ + i = (iq[jz - 1] >> (8 - q0)); n += i; + iq[jz - 1] -= i << (8 - q0); + ih = iq[jz - 1] >> (7 - q0); + } else if (q0 == 0) ih = iq[jz - 1] >> 8; + else if (z >= (Simple)0.5f) ih = 2; + + if (ih > 0) { /* q > 0.5f */ + n += 1; carry = 0; + for (i = 0; i < jz; i++) { /* compute 1-q */ + j = iq[i]; + if (carry == 0) { + if (j != 0) { + carry = 1; iq[i] = 0x100 - j; + } + } else iq[i] = 0xff - j; + } + if (q0 > 0) { /* rare case: chance is 1 in 12 */ + switch (q0) { + case 1: + iq[jz - 1] &= 0x7f; break; + case 2: + iq[jz - 1] &= 0x3f; break; + } + } + if (ih == 2) { + z = one - z; + if (carry != 0) z -= __scalbnf(one,q0); + } } - for (fw=0.0f,i=jz;i>=2;i--) fw += fq[i]; - if(ih==0) { - y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; - } else { - y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; + + /* check if recomputation is needed */ + if (z == zero) { + j = 0; + for (i = jz - 1; i >= jk; i--) j |= iq[i]; + if (j == 0) { /* need recomputation */ + for (k = 1; iq[jk - k] == 0; k++); /* k = no. of terms needed */ + + for (i = jz + 1; i <= jz + k; i++) { /* add q[jz+1] to q[jz+k] */ + f[jx + i] = (Simple) ipio2[jv + i]; + for (j = 0,fw = 0.0f; j <= jx; j++) fw += x[j] * f[jx + i - j]; + q[i] = fw; + } + jz += k; + goto recompute; + } } - } - return n&7; + + /* chop off zero terms */ + if (z == (Simple)0.0f) { + jz -= 1; q0 -= 8; + while (iq[jz] == 0) { + jz--; q0 -= 8; } +} else { /* break z into 8-bit if necessary */ + z = __scalbnf(z,-q0); + if (z >= two8) { + fw = (Simple) ((int32_t) (twon8*z)); + iq[jz] = (int32_t) (z - two8*fw); + jz += 1; q0 += 8; + iq[jz] = (int32_t) fw; + } else iq[jz] = (int32_t) z; } + + /* convert integer "bit" chunk to floating-point value */ + fw = __scalbnf(one,q0); + for (i = jz; i >= 0; i--) { + q[i] = fw*(Simple) iq[i]; fw *= twon8; + } + + /* compute PIo2[0,...,jp]*q[jz,...,0] */ + for (i = jz; i >= 0; i--) { + for (fw = 0.0f,k = 0; k <= jp&&k <= jz - i; k++) fw += PIo2[k] * q[i + k]; + fq[jz - i] = fw; + } + + /* compress fq[] into y[] */ + switch (prec) { + case 0: + fw = 0.0f; + for (i = jz; i >= 0; i--) fw += fq[i]; + y[0] = (ih == 0) ? fw : -fw; + break; + case 1: + case 2: + fw = 0.0f; + for (i = jz; i >= 0; i--) fw += fq[i]; + y[0] = (ih == 0) ? fw : -fw; + fw = fq[0] - fw; + for (i = 1; i <= jz; i++) fw += fq[i]; + y[1] = (ih == 0) ? fw : -fw; + break; + case 3: /* painful */ + for (i = jz; i > 0; i--) { + fw = fq[i - 1] + fq[i]; + fq[i] += fq[i - 1] - fw; + fq[i - 1] = fw; + } + for (i = jz; i > 1; i--) { + fw = fq[i - 1] + fq[i]; + fq[i] += fq[i - 1] - fw; + fq[i - 1] = fw; + } + for (fw = 0.0f,i = jz; i >= 2; i--) fw += fq[i]; + if (ih == 0) { + y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; + } else { + y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; + } + } + return n & 7; + } + } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/k_sinf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/k_sinf.cpp index ed4d2be33..a2c653d88 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/k_sinf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/k_sinf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: k_sinf.c,v 1.4f 1995/05/10 20:46:33 jtc Exp $"; @@ -23,35 +23,37 @@ static char rcsid[] = "$NetBSD: k_sinf.c,v 1.4f 1995/05/10 20:46:33 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -half = 5.0000000000e-01f,/* 0x3f000000 */ -S1 = -1.6666667163e-01f, /* 0xbe2aaaab */ -S2 = 8.3333337680e-03f, /* 0x3c088889 */ -S3 = -1.9841270114e-04f, /* 0xb9500d01 */ -S4 = 2.7557314297e-06f, /* 0x3638ef1b */ -S5 = -2.5050759689e-08f, /* 0xb2d72f34 */ -S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */ + half = 5.0000000000e-01f,/* 0x3f000000 */ + S1 = -1.6666667163e-01f, /* 0xbe2aaaab */ + S2 = 8.3333337680e-03f, /* 0x3c088889 */ + S3 = -1.9841270114e-04f, /* 0xb9500d01 */ + S4 = 2.7557314297e-06f, /* 0x3638ef1b */ + S5 = -2.5050759689e-08f, /* 0xb2d72f34 */ + S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */ #ifdef __STDC__ Simple __kernel_sinf(Simple x, Simple y, int iy) #else Simple __kernel_sinf(x, y, iy) - Simple x,y; int iy; /* iy=0 if y is zero */ + Simple x, y; int iy; /* iy=0 if y is zero */ #endif -{ - Simple z,r,v; - int32_t ix; - GET_FLOAT_WORD(ix,x); - ix &= 0x7fffffff; /* high word of x */ - if(ix<0x32000000) /* |x| < 2**-27 */ - {if((int)x==0) return x;} /* generate inexact */ - z = x*x; - v = z*x; - r = S2+z*(S3+z*(S4+z*(S5+z*S6))); - if(iy==0) return x+v*(S1+z*r); - else return x-((z*(half*y-v*r)-y)-v*S1); -} + { + Simple z, r, v; + int32_t ix; + GET_FLOAT_WORD(ix, x); + ix &= 0x7fffffff; /* high word of x */ + if (ix < 0x32000000) /* |x| < 2**-27 */ + { + if ((int) x == 0) return x; + } /* generate inexact */ + z = x*x; + v = z*x; + r = S2 + z*(S3 + z*(S4 + z*(S5 + z*S6))); + if (iy == 0) return x + v*(S1 + z*r); + else return x - ((z*(half*y - v*r) - y) - v*S1); + } } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/k_tanf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/k_tanf.cpp index dec923d0b..a2ad32bab 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/k_tanf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/k_tanf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: k_tanf.c,v 1.4f 1995/05/10 20:46:39 jtc Exp $"; @@ -22,83 +22,86 @@ static char rcsid[] = "$NetBSD: k_tanf.c,v 1.4f 1995/05/10 20:46:39 jtc Exp $"; #include "math_private.h" namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -one = 1.0000000000e+00f, /* 0x3f800000 */ -pio4 = 7.8539812565e-01f, /* 0x3f490fda */ -pio4lo= 3.7748947079e-08f, /* 0x33222168 */ -T[] = { - 3.3333334327e-01f, /* 0x3eaaaaab */ - 1.3333334029e-01f, /* 0x3e088889 */ - 5.3968254477e-02f, /* 0x3d5d0dd1 */ - 2.1869488060e-02f, /* 0x3cb327a4 */ - 8.8632395491e-03f, /* 0x3c11371f */ - 3.5920790397e-03f, /* 0x3b6b6916 */ - 1.4562094584e-03f, /* 0x3abede48 */ - 5.8804126456e-04f, /* 0x3a1a26c8 */ - 2.4646313977e-04f, /* 0x398137b9 */ - 7.8179444245e-05f, /* 0x38a3f445 */ - 7.1407252108e-05f, /* 0x3895c07a */ - -1.8558637748e-05f, /* 0xb79bae5f */ - 2.5907305826e-05f, /* 0x37d95384 */ -}; + one = 1.0000000000e+00f, /* 0x3f800000 */ + pio4 = 7.8539812565e-01f, /* 0x3f490fda */ + pio4lo = 3.7748947079e-08f, /* 0x33222168 */ + T[] = { + 3.3333334327e-01f, /* 0x3eaaaaab */ + 1.3333334029e-01f, /* 0x3e088889 */ + 5.3968254477e-02f, /* 0x3d5d0dd1 */ + 2.1869488060e-02f, /* 0x3cb327a4 */ + 8.8632395491e-03f, /* 0x3c11371f */ + 3.5920790397e-03f, /* 0x3b6b6916 */ + 1.4562094584e-03f, /* 0x3abede48 */ + 5.8804126456e-04f, /* 0x3a1a26c8 */ + 2.4646313977e-04f, /* 0x398137b9 */ + 7.8179444245e-05f, /* 0x38a3f445 */ + 7.1407252108e-05f, /* 0x3895c07a */ + -1.8558637748e-05f, /* 0xb79bae5f */ + 2.5907305826e-05f, /* 0x37d95384 */ + }; #ifdef __STDC__ Simple __kernel_tanf(Simple x, Simple y, int iy) #else Simple __kernel_tanf(x, y, iy) - Simple x,y; int iy; + Simple x, y; int iy; #endif -{ - Simple z,r,v,w,s; - int32_t ix,hx; - GET_FLOAT_WORD(hx,x); - ix = hx&0x7fffffff; /* high word of |x| */ - if(ix<0x31800000) /* x < 2**-28 */ - {if((int)x==0) { /* generate inexact */ - if((ix|(iy+1))==0) return one/fabsf(x); - else return (iy==1)? x: -one/x; - } - } - if(ix>=0x3f2ca140) { /* |x|>=0.6744f */ - if(hx<0) {x = -x; y = -y;} - z = pio4-x; - w = pio4lo-y; - x = z+w; y = 0.0f; - } - z = x*x; - w = z*z; - /* Break x^5*(T[1]+x^2*T[2]+...) into - * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + - * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12])) - */ - r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11])))); - v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12]))))); - s = z*x; - r = y + z*(s*(r+v)+y); - r += T[0]*s; - w = x+r; - if(ix>=0x3f2ca140) { - v = (Simple)iy; - return (Simple)(1-((hx>>30)&2))*(v-(Simple)2.0f*(x-(w*w/(w+v)-r))); - } - if(iy==1) return w; - else { /* if allow error up to 2 ulp, - simply return -1.0f/(x+r) here */ - /* compute -1.0f/(x+r) accurately */ - Simple a,t; - int32_t i; - z = w; - GET_FLOAT_WORD(i,z); - SET_FLOAT_WORD(z,i&0xfffff000); - v = r-(z - x); /* z+v = r+x */ - t = a = -(Simple)1.0f/w; /* a = -1.0f/w */ - GET_FLOAT_WORD(i,t); - SET_FLOAT_WORD(t,i&0xfffff000); - s = (Simple)1.0f+t*z; - return t+a*(s+t*v); + { + Simple z, r, v, w, s; + int32_t ix, hx; + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; /* high word of |x| */ + if (ix < 0x31800000) /* x < 2**-28 */ + { + if ((int) x == 0) { /* generate inexact */ + if ((ix | (iy + 1)) == 0) return one / fabsf(x); + else return (iy == 1) ? x : -one / x; + } + } + if (ix >= 0x3f2ca140) { /* |x|>=0.6744f */ + if (hx < 0) { + x = -x; y = -y; + } + z = pio4 - x; + w = pio4lo - y; + x = z + w; y = 0.0f; + } + z = x*x; + w = z*z; + /* Break x^5*(T[1]+x^2*T[2]+...) into + * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + + * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12])) + */ + r = T[1] + w*(T[3] + w*(T[5] + w*(T[7] + w*(T[9] + w*T[11])))); + v = z*(T[2] + w*(T[4] + w*(T[6] + w*(T[8] + w*(T[10] + w*T[12]))))); + s = z*x; + r = y + z*(s*(r + v) + y); + r += T[0] * s; + w = x + r; + if (ix >= 0x3f2ca140) { + v = (Simple) iy; + return (Simple) (1 - ((hx >> 30) & 2))*(v - (Simple)2.0f*(x - (w*w / (w + v) - r))); + } + if (iy == 1) return w; + else { /* if allow error up to 2 ulp, + simply return -1.0f/(x+r) here */ + /* compute -1.0f/(x+r) accurately */ + Simple a, t; + int32_t i; + z = w; + GET_FLOAT_WORD(i, z); + SET_FLOAT_WORD(z, i & 0xfffff000); + v = r - (z - x); /* z+v = r+x */ + t = a = -(Simple)1.0f / w; /* a = -1.0f/w */ + GET_FLOAT_WORD(i, t); + SET_FLOAT_WORD(t, i & 0xfffff000); + s = (Simple)1.0f + t*z; + return t + a*(s + t*v); + } } } -} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_asinhf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_asinhf.cpp index 91fcec9d7..c260aa17f 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_asinhf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_asinhf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_asinhf.c,v 1.5f 1995/05/12 04:57:39 jtc Exp $"; @@ -23,39 +23,39 @@ static char rcsid[] = "$NetBSD: s_asinhf.c,v 1.5f 1995/05/12 04:57:39 jtc Exp $" namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -one = 1.0000000000e+00f, /* 0x3F800000 */ -ln2 = 6.9314718246e-01f, /* 0x3f317218 */ -huge= 1.0000000000e+30f; + one = 1.0000000000e+00f, /* 0x3F800000 */ + ln2 = 6.9314718246e-01f, /* 0x3f317218 */ + huge = 1.0000000000e+30f; #ifdef __STDC__ Simple __asinhf(Simple x) #else Simple __asinhf(x) - Simple x; + Simple x; #endif -{ - Simple t,w; - int32_t hx,ix; - GET_FLOAT_WORD(hx,x); - ix = hx&0x7fffffff; - if(ix>=0x7f800000) return x+x; /* x is inf or NaN */ - if(ix< 0x38000000) { /* |x|<2**-14 */ - if(huge+x>one) return x; /* return x inexact except 0 */ + { + Simple t, w; + int32_t hx, ix; + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + if (ix >= 0x7f800000) return x + x; /* x is inf or NaN */ + if (ix < 0x38000000) { /* |x|<2**-14 */ + if (huge + x > one) return x; /* return x inexact except 0 */ + } + if (ix > 0x47000000) { /* |x| > 2**14 */ + w = __ieee754_logf(fabsf(x)) + ln2; + } else if (ix > 0x40000000) { /* 2**14 > |x| > 2.0f */ + t = fabsf(x); + w = __ieee754_logf((Simple)2.0f*t + one / (__ieee754_sqrtf(x*x + one) + t)); + } else { /* 2.0f > |x| > 2**-14 */ + t = x*x; + w = __log1pf(fabsf(x) + t / (one + __ieee754_sqrtf(one + t))); + } + if (hx > 0) return w; else return -w; } - if(ix>0x47000000) { /* |x| > 2**14 */ - w = __ieee754_logf(fabsf(x))+ln2; - } else if (ix>0x40000000) { /* 2**14 > |x| > 2.0f */ - t = fabsf(x); - w = __ieee754_logf((Simple)2.0f*t+one/(__ieee754_sqrtf(x*x+one)+t)); - } else { /* 2.0f > |x| > 2**-14 */ - t = x*x; - w =__log1pf(fabsf(x)+t/(one+__ieee754_sqrtf(one+t))); - } - if(hx>0) return w; else return -w; -} -weak_alias (__asinhf, asinhf) + weak_alias(__asinhf, asinhf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_atanf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_atanf.cpp index e8416dd91..8aff1c276 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_atanf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_atanf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_atanf.c,v 1.4f 1995/05/10 20:46:47 jtc Exp $"; @@ -23,101 +23,102 @@ static char rcsid[] = "$NetBSD: s_atanf.c,v 1.4f 1995/05/10 20:46:47 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static const Simple atanhi[] = { -#else -static Simple atanhi[] = { -#endif - 4.6364760399e-01f, /* atan(0.5f)hi 0x3eed6338 */ - 7.8539812565e-01f, /* atan(1.0f)hi 0x3f490fda */ - 9.8279368877e-01f, /* atan(1.5f)hi 0x3f7b985e */ - 1.5707962513e+00f, /* atan(inf)hi 0x3fc90fda */ -}; + static const Simple atanhi[] = { + #else + static Simple atanhi[] = { + #endif + 4.6364760399e-01f, /* atan(0.5f)hi 0x3eed6338 */ + 7.8539812565e-01f, /* atan(1.0f)hi 0x3f490fda */ + 9.8279368877e-01f, /* atan(1.5f)hi 0x3f7b985e */ + 1.5707962513e+00f, /* atan(inf)hi 0x3fc90fda */ + }; -#ifdef __STDC__ -static const Simple atanlo[] = { -#else -static Simple atanlo[] = { -#endif - 5.0121582440e-09f, /* atan(0.5f)lo 0x31ac3769 */ - 3.7748947079e-08f, /* atan(1.0f)lo 0x33222168 */ - 3.4473217170e-08f, /* atan(1.5f)lo 0x33140fb4 */ - 7.5497894159e-08f, /* atan(inf)lo 0x33a22168 */ -}; + #ifdef __STDC__ + static const Simple atanlo[] = { + #else + static Simple atanlo[] = { + #endif + 5.0121582440e-09f, /* atan(0.5f)lo 0x31ac3769 */ + 3.7748947079e-08f, /* atan(1.0f)lo 0x33222168 */ + 3.4473217170e-08f, /* atan(1.5f)lo 0x33140fb4 */ + 7.5497894159e-08f, /* atan(inf)lo 0x33a22168 */ + }; -#ifdef __STDC__ -static const Simple aT[] = { -#else -static Simple aT[] = { -#endif - 3.3333334327e-01f, /* 0x3eaaaaaa */ - -2.0000000298e-01f, /* 0xbe4ccccd */ - 1.4285714924e-01f, /* 0x3e124925 */ - -1.1111110449e-01f, /* 0xbde38e38 */ - 9.0908870101e-02f, /* 0x3dba2e6e */ - -7.6918758452e-02f, /* 0xbd9d8795 */ - 6.6610731184e-02f, /* 0x3d886b35 */ - -5.8335702866e-02f, /* 0xbd6ef16b */ - 4.9768779427e-02f, /* 0x3d4bda59 */ - -3.6531571299e-02f, /* 0xbd15a221 */ - 1.6285819933e-02f, /* 0x3c8569d7 */ -}; + #ifdef __STDC__ + static const Simple aT[] = { + #else + static Simple aT[] = { + #endif + 3.3333334327e-01f, /* 0x3eaaaaaa */ + -2.0000000298e-01f, /* 0xbe4ccccd */ + 1.4285714924e-01f, /* 0x3e124925 */ + -1.1111110449e-01f, /* 0xbde38e38 */ + 9.0908870101e-02f, /* 0x3dba2e6e */ + -7.6918758452e-02f, /* 0xbd9d8795 */ + 6.6610731184e-02f, /* 0x3d886b35 */ + -5.8335702866e-02f, /* 0xbd6ef16b */ + 4.9768779427e-02f, /* 0x3d4bda59 */ + -3.6531571299e-02f, /* 0xbd15a221 */ + 1.6285819933e-02f, /* 0x3c8569d7 */ + }; -#ifdef __STDC__ - static const Simple -#else - static Simple -#endif -one = 1.0f, -huge = 1.0e30f; + #ifdef __STDC__ + static const Simple + #else + static Simple + #endif + one = 1.0f, + huge = 1.0e30f; -#ifdef __STDC__ - Simple __atanf(Simple x) -#else - Simple __atanf(x) - Simple x; -#endif -{ - Simple w,s1,s2,z; - int32_t ix,hx,id; + #ifdef __STDC__ + Simple __atanf(Simple x) + #else + Simple __atanf(x) + Simple x; + #endif + { + Simple w,s1,s2,z; + int32_t ix,hx,id; - GET_FLOAT_WORD(hx,x); - ix = hx&0x7fffffff; - if(ix>=0x50800000) { /* if |x| >= 2^34 */ - if(ix>0x7f800000) - return x+x; /* NaN */ - if(hx>0) return atanhi[3]+atanlo[3]; - else return -atanhi[3]-atanlo[3]; - } if (ix < 0x3ee00000) { /* |x| < 0.4375f */ - if (ix < 0x31000000) { /* |x| < 2^-29 */ - if(huge+x>one) return x; /* raise inexact */ - } - id = -1; - } else { - x = fabsf(x); - if (ix < 0x3f980000) { /* |x| < 1.1875f */ - if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */ - id = 0; x = ((Simple)2.0f*x-one)/((Simple)2.0f+x); - } else { /* 11/16<=|x|< 19/16 */ - id = 1; x = (x-one)/(x+one); - } - } else { - if (ix < 0x401c0000) { /* |x| < 2.4375f */ - id = 2; x = (x-(Simple)1.5f)/(one+(Simple)1.5f*x); - } else { /* 2.4375f <= |x| < 2^66 */ - id = 3; x = -(Simple)1.0f/x; - } - }} - /* end of argument reduction */ - z = x*x; - w = z*z; - /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ - s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10]))))); - s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9])))); - if (id<0) return x - x*(s1+s2); - else { - z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); - return (hx<0)? -z:z; + GET_FLOAT_WORD(hx,x); + ix = hx & 0x7fffffff; + if (ix >= 0x50800000) { /* if |x| >= 2^34 */ + if (ix > 0x7f800000) + return x + x; /* NaN */ + if (hx > 0) return atanhi[3] + atanlo[3]; + else return -atanhi[3] - atanlo[3]; + } if (ix < 0x3ee00000) { /* |x| < 0.4375f */ + if (ix < 0x31000000) { /* |x| < 2^-29 */ + if (huge + x > one) return x; /* raise inexact */ + } + id = -1; + } else { + x = fabsf(x); + if (ix < 0x3f980000) { /* |x| < 1.1875f */ + if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */ + id = 0; x = ((Simple)2.0f*x - one) / ((Simple)2.0f + x); + } else { /* 11/16<=|x|< 19/16 */ + id = 1; x = (x - one) / (x + one); + } + } else { + if (ix < 0x401c0000) { /* |x| < 2.4375f */ + id = 2; x = (x - (Simple)1.5f) / (one + (Simple)1.5f*x); + } else { /* 2.4375f <= |x| < 2^66 */ + id = 3; x = -(Simple)1.0f / x; + } + } + } + /* end of argument reduction */ + z = x*x; + w = z*z; + /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ + s1 = z*(aT[0] + w*(aT[2] + w*(aT[4] + w*(aT[6] + w*(aT[8] + w*aT[10]))))); + s2 = w*(aT[1] + w*(aT[3] + w*(aT[5] + w*(aT[7] + w*aT[9])))); + if (id < 0) return x - x*(s1 + s2); + else { + z = atanhi[id] - ((x*(s1 + s2) - atanlo[id]) - x); + return (hx < 0) ? -z : z; + } + } + weak_alias(__atanf, atanf) } -} -weak_alias (__atanf, atanf) -} diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_cbrtf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_cbrtf.cpp index db8d7d202..3d392e48e 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_cbrtf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_cbrtf.cpp @@ -38,30 +38,29 @@ static const Simple factor[5] = namespace streflop_libm { -Simple -__cbrtf (Simple x) -{ - Simple xm, ym, u, t2; - int xe; + Simple + __cbrtf(Simple x) { + Simple xm, ym, u, t2; + int xe; - /* Reduce X. XM now is an range 1.0f to 0.5f. */ - xm = __frexpf (fabsf (x), &xe); + /* Reduce X. XM now is an range 1.0f to 0.5f. */ + xm = __frexpf(fabsf(x), &xe); - /* If X is not finite or is null return it (with raising exceptions - if necessary. - Note: *Our* version of `frexp' sets XE to zero if the argument is - Inf or NaN. This is not portable but faster. */ - if (xe == 0 && fpclassify (x) <= FP_ZERO) - return x + x; + /* If X is not finite or is null return it (with raising exceptions + if necessary. + Note: *Our* version of `frexp' sets XE to zero if the argument is + Inf or NaN. This is not portable but faster. */ + if (xe == 0 && fpclassify(x) <= FP_ZERO) + return x + x; - u = (0.492659620528969547f + (0.697570460207922770f - - 0.191502161678719066f * xm) * xm); + u = (0.492659620528969547f + (0.697570460207922770f + - 0.191502161678719066f * xm) * xm); - t2 = u * u * u; + t2 = u * u * u; - ym = u * (t2 + 2.0f * xm) / (2.0f * t2 + xm) * factor[2 + xe % 3]; + ym = u * (t2 + 2.0f * xm) / (2.0f * t2 + xm) * factor[2 + xe % 3]; - return __ldexpf (x > 0.0f ? ym : -ym, xe / 3); -} -weak_alias (__cbrtf, cbrtf) + return __ldexpf(x > 0.0f ? ym : -ym, xe / 3); + } + weak_alias(__cbrtf, cbrtf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_ceilf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_ceilf.cpp index bb4c0649d..ba065f9c9 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_ceilf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_ceilf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_ceilf.c,v 1.4f 1995/05/10 20:46:55 jtc Exp $"; @@ -23,43 +23,46 @@ static char rcsid[] = "$NetBSD: s_ceilf.c,v 1.4f 1995/05/10 20:46:55 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static const Simple huge = 1.0e30f; + static const Simple huge = 1.0e30f; #else -static Simple huge = 1.0e30f; + static Simple huge = 1.0e30f; #endif #ifdef __STDC__ Simple __ceilf(Simple x) #else Simple __ceilf(x) - Simple x; + Simple x; #endif -{ - int32_t i0,j0; - u_int32_t i; + { + int32_t i0, j0; + u_int32_t i; - GET_FLOAT_WORD(i0,x); - j0 = ((i0>>23)&0xff)-0x7f; - if(j0<23) { - if(j0<0) { /* raise inexact if x != 0 */ - if(huge+x>(Simple)0.0f) {/* return 0*sign(x) if |x|<1 */ - if(i0<0) {i0=0x80000000;} - else if(i0!=0) { i0=0x3f800000;} + GET_FLOAT_WORD(i0, x); + j0 = ((i0 >> 23) & 0xff) - 0x7f; + if (j0 < 23) { + if (j0 < 0) { /* raise inexact if x != 0 */ + if (huge + x > (Simple)0.0f) {/* return 0*sign(x) if |x|<1 */ + if (i0 < 0) { + i0 = 0x80000000; + } else if (i0 != 0) { + i0 = 0x3f800000; + } + } + } else { + i = (0x007fffff) >> j0; + if ((i0&i) == 0) return x; /* x is integral */ + if (huge + x > (Simple)0.0f) { /* raise inexact flag */ + if (i0 > 0) i0 += (0x00800000) >> j0; + i0 &= (~i); + } + } + } else { + if (j0 == 0x80) return x + x; /* inf or NaN */ + else return x; /* x is integral */ } - } else { - i = (0x007fffff)>>j0; - if((i0&i)==0) return x; /* x is integral */ - if(huge+x>(Simple)0.0f) { /* raise inexact flag */ - if(i0>0) i0 += (0x00800000)>>j0; - i0 &= (~i); - } - } - } else { - if(j0==0x80) return x+x; /* inf or NaN */ - else return x; /* x is integral */ + SET_FLOAT_WORD(x, i0); + return x; } - SET_FLOAT_WORD(x,i0); - return x; -} -weak_alias (__ceilf, ceilf) + weak_alias(__ceilf, ceilf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_copysignf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_copysignf.cpp index c09a2ec56..464416b4f 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_copysignf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_copysignf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_copysignf.c,v 1.4f 1995/05/10 20:46:59 jtc Exp $"; @@ -31,15 +31,15 @@ namespace streflop_libm { #ifdef __STDC__ Simple __copysignf(Simple x, Simple y) #else - Simple __copysignf(x,y) - Simple x,y; + Simple __copysignf(x, y) + Simple x, y; #endif -{ - u_int32_t ix,iy; - GET_FLOAT_WORD(ix,x); - GET_FLOAT_WORD(iy,y); - SET_FLOAT_WORD(x,(ix&0x7fffffff)|(iy&0x80000000)); - return x; -} -weak_alias (__copysignf, copysignf) + { + u_int32_t ix, iy; + GET_FLOAT_WORD(ix, x); + GET_FLOAT_WORD(iy, y); + SET_FLOAT_WORD(x, (ix & 0x7fffffff) | (iy & 0x80000000)); + return x; + } + weak_alias(__copysignf, copysignf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_cosf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_cosf.cpp index 4b94f3d22..a584a497c 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_cosf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_cosf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_cosf.c,v 1.4f 1995/05/10 20:47:03 jtc Exp $"; @@ -23,41 +23,41 @@ static char rcsid[] = "$NetBSD: s_cosf.c,v 1.4f 1995/05/10 20:47:03 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -//static const Simple one=1.0f; + //static const Simple one=1.0f; #else -static Simple one=1.0f; + static Simple one = 1.0f; #endif #ifdef __STDC__ Simple __cosf(Simple x) #else Simple __cosf(x) - Simple x; + Simple x; #endif -{ - Simple y[2],z=0.0f; - int32_t n,ix; + { + Simple y[2], z = 0.0f; + int32_t n, ix; - GET_FLOAT_WORD(ix,x); + GET_FLOAT_WORD(ix, x); - /* |x| ~< pi/4 */ - ix &= 0x7fffffff; - if(ix <= 0x3f490fd8) return __kernel_cosf(x,z); + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if (ix <= 0x3f490fd8) return __kernel_cosf(x, z); - /* cos(Inf or NaN) is NaN */ - else if (ix>=0x7f800000) return x-x; + /* cos(Inf or NaN) is NaN */ + else if (ix >= 0x7f800000) return x - x; - /* argument reduction needed */ - else { - n = __ieee754_rem_pio2f(x,y); - switch(n&3) { - case 0: return __kernel_cosf(y[0],y[1]); - case 1: return -__kernel_sinf(y[0],y[1],1); - case 2: return -__kernel_cosf(y[0],y[1]); - default: - return __kernel_sinf(y[0],y[1],1); - } + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2f(x, y); + switch (n & 3) { + case 0: return __kernel_cosf(y[0], y[1]); + case 1: return -__kernel_sinf(y[0], y[1], 1); + case 2: return -__kernel_cosf(y[0], y[1]); + default: + return __kernel_sinf(y[0], y[1], 1); + } + } } -} -weak_alias (__cosf, cosf) + weak_alias(__cosf, cosf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_erff.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_erff.cpp index c28d4865e..f9efd4587 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_erff.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_erff.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_erff.c,v 1.4f 1995/05/10 20:47:07 jtc Exp $"; @@ -23,206 +23,206 @@ static char rcsid[] = "$NetBSD: s_erff.c,v 1.4f 1995/05/10 20:47:07 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -tiny = 1e-30f, -half= 5.0000000000e-01f, /* 0x3F000000 */ -one = 1.0000000000e+00f, /* 0x3F800000 */ -two = 2.0000000000e+00f, /* 0x40000000 */ - /* c = (subfloat)0.84506291151f */ -erx = 8.4506291151e-01f, /* 0x3f58560b */ -/* - * Coefficients for approximation to erf on [0,0.84375] - */ -efx = 1.2837916613e-01f, /* 0x3e0375d4 */ -efx8= 1.0270333290e+00f, /* 0x3f8375d4 */ -pp0 = 1.2837916613e-01f, /* 0x3e0375d4 */ -pp1 = -3.2504209876e-01f, /* 0xbea66beb */ -pp2 = -2.8481749818e-02f, /* 0xbce9528f */ -pp3 = -5.7702702470e-03f, /* 0xbbbd1489 */ -pp4 = -2.3763017452e-05f, /* 0xb7c756b1 */ -qq1 = 3.9791721106e-01f, /* 0x3ecbbbce */ -qq2 = 6.5022252500e-02f, /* 0x3d852a63 */ -qq3 = 5.0813062117e-03f, /* 0x3ba68116 */ -qq4 = 1.3249473704e-04f, /* 0x390aee49 */ -qq5 = -3.9602282413e-06f, /* 0xb684e21a */ -/* - * Coefficients for approximation to erf in [0.84375f,1.25f] - */ -pa0 = -2.3621185683e-03f, /* 0xbb1acdc6 */ -pa1 = 4.1485610604e-01f, /* 0x3ed46805 */ -pa2 = -3.7220788002e-01f, /* 0xbebe9208 */ -pa3 = 3.1834661961e-01f, /* 0x3ea2fe54 */ -pa4 = -1.1089469492e-01f, /* 0xbde31cc2 */ -pa5 = 3.5478305072e-02f, /* 0x3d1151b3 */ -pa6 = -2.1663755178e-03f, /* 0xbb0df9c0 */ -qa1 = 1.0642088205e-01f, /* 0x3dd9f331 */ -qa2 = 5.4039794207e-01f, /* 0x3f0a5785 */ -qa3 = 7.1828655899e-02f, /* 0x3d931ae7 */ -qa4 = 1.2617121637e-01f, /* 0x3e013307 */ -qa5 = 1.3637083583e-02f, /* 0x3c5f6e13 */ -qa6 = 1.1984500103e-02f, /* 0x3c445aa3 */ -/* - * Coefficients for approximation to erfc in [1.25f,1/0.35f] - */ -ra0 = -9.8649440333e-03f, /* 0xbc21a093 */ -ra1 = -6.9385856390e-01f, /* 0xbf31a0b7 */ -ra2 = -1.0558626175e+01f, /* 0xc128f022 */ -ra3 = -6.2375331879e+01f, /* 0xc2798057 */ -ra4 = -1.6239666748e+02f, /* 0xc322658c */ -ra5 = -1.8460508728e+02f, /* 0xc3389ae7 */ -ra6 = -8.1287437439e+01f, /* 0xc2a2932b */ -ra7 = -9.8143291473e+00f, /* 0xc11d077e */ -sa1 = 1.9651271820e+01f, /* 0x419d35ce */ -sa2 = 1.3765776062e+02f, /* 0x4309a863 */ -sa3 = 4.3456588745e+02f, /* 0x43d9486f */ -sa4 = 6.4538726807e+02f, /* 0x442158c9 */ -sa5 = 4.2900814819e+02f, /* 0x43d6810b */ -sa6 = 1.0863500214e+02f, /* 0x42d9451f */ -sa7 = 6.5702495575e+00f, /* 0x40d23f7c */ -sa8 = -6.0424413532e-02f, /* 0xbd777f97 */ -/* - * Coefficients for approximation to erfc in [1/.35f,28] - */ -rb0 = -9.8649431020e-03f, /* 0xbc21a092 */ -rb1 = -7.9928326607e-01f, /* 0xbf4c9dd4 */ -rb2 = -1.7757955551e+01f, /* 0xc18e104b */ -rb3 = -1.6063638306e+02f, /* 0xc320a2ea */ -rb4 = -6.3756646729e+02f, /* 0xc41f6441 */ -rb5 = -1.0250950928e+03f, /* 0xc480230b */ -rb6 = -4.8351919556e+02f, /* 0xc3f1c275 */ -sb1 = 3.0338060379e+01f, /* 0x41f2b459 */ -sb2 = 3.2579251099e+02f, /* 0x43a2e571 */ -sb3 = 1.5367296143e+03f, /* 0x44c01759 */ -sb4 = 3.1998581543e+03f, /* 0x4547fdbb */ -sb5 = 2.5530502930e+03f, /* 0x451f90ce */ -sb6 = 4.7452853394e+02f, /* 0x43ed43a7 */ -sb7 = -2.2440952301e+01f; /* 0xc1b38712 */ + tiny = 1e-30f, + half = 5.0000000000e-01f, /* 0x3F000000 */ + one = 1.0000000000e+00f, /* 0x3F800000 */ + two = 2.0000000000e+00f, /* 0x40000000 */ + /* c = (subfloat)0.84506291151f */ + erx = 8.4506291151e-01f, /* 0x3f58560b */ + /* + * Coefficients for approximation to erf on [0,0.84375] + */ + efx = 1.2837916613e-01f, /* 0x3e0375d4 */ + efx8 = 1.0270333290e+00f, /* 0x3f8375d4 */ + pp0 = 1.2837916613e-01f, /* 0x3e0375d4 */ + pp1 = -3.2504209876e-01f, /* 0xbea66beb */ + pp2 = -2.8481749818e-02f, /* 0xbce9528f */ + pp3 = -5.7702702470e-03f, /* 0xbbbd1489 */ + pp4 = -2.3763017452e-05f, /* 0xb7c756b1 */ + qq1 = 3.9791721106e-01f, /* 0x3ecbbbce */ + qq2 = 6.5022252500e-02f, /* 0x3d852a63 */ + qq3 = 5.0813062117e-03f, /* 0x3ba68116 */ + qq4 = 1.3249473704e-04f, /* 0x390aee49 */ + qq5 = -3.9602282413e-06f, /* 0xb684e21a */ + /* + * Coefficients for approximation to erf in [0.84375f,1.25f] + */ + pa0 = -2.3621185683e-03f, /* 0xbb1acdc6 */ + pa1 = 4.1485610604e-01f, /* 0x3ed46805 */ + pa2 = -3.7220788002e-01f, /* 0xbebe9208 */ + pa3 = 3.1834661961e-01f, /* 0x3ea2fe54 */ + pa4 = -1.1089469492e-01f, /* 0xbde31cc2 */ + pa5 = 3.5478305072e-02f, /* 0x3d1151b3 */ + pa6 = -2.1663755178e-03f, /* 0xbb0df9c0 */ + qa1 = 1.0642088205e-01f, /* 0x3dd9f331 */ + qa2 = 5.4039794207e-01f, /* 0x3f0a5785 */ + qa3 = 7.1828655899e-02f, /* 0x3d931ae7 */ + qa4 = 1.2617121637e-01f, /* 0x3e013307 */ + qa5 = 1.3637083583e-02f, /* 0x3c5f6e13 */ + qa6 = 1.1984500103e-02f, /* 0x3c445aa3 */ + /* + * Coefficients for approximation to erfc in [1.25f,1/0.35f] + */ + ra0 = -9.8649440333e-03f, /* 0xbc21a093 */ + ra1 = -6.9385856390e-01f, /* 0xbf31a0b7 */ + ra2 = -1.0558626175e+01f, /* 0xc128f022 */ + ra3 = -6.2375331879e+01f, /* 0xc2798057 */ + ra4 = -1.6239666748e+02f, /* 0xc322658c */ + ra5 = -1.8460508728e+02f, /* 0xc3389ae7 */ + ra6 = -8.1287437439e+01f, /* 0xc2a2932b */ + ra7 = -9.8143291473e+00f, /* 0xc11d077e */ + sa1 = 1.9651271820e+01f, /* 0x419d35ce */ + sa2 = 1.3765776062e+02f, /* 0x4309a863 */ + sa3 = 4.3456588745e+02f, /* 0x43d9486f */ + sa4 = 6.4538726807e+02f, /* 0x442158c9 */ + sa5 = 4.2900814819e+02f, /* 0x43d6810b */ + sa6 = 1.0863500214e+02f, /* 0x42d9451f */ + sa7 = 6.5702495575e+00f, /* 0x40d23f7c */ + sa8 = -6.0424413532e-02f, /* 0xbd777f97 */ + /* + * Coefficients for approximation to erfc in [1/.35f,28] + */ + rb0 = -9.8649431020e-03f, /* 0xbc21a092 */ + rb1 = -7.9928326607e-01f, /* 0xbf4c9dd4 */ + rb2 = -1.7757955551e+01f, /* 0xc18e104b */ + rb3 = -1.6063638306e+02f, /* 0xc320a2ea */ + rb4 = -6.3756646729e+02f, /* 0xc41f6441 */ + rb5 = -1.0250950928e+03f, /* 0xc480230b */ + rb6 = -4.8351919556e+02f, /* 0xc3f1c275 */ + sb1 = 3.0338060379e+01f, /* 0x41f2b459 */ + sb2 = 3.2579251099e+02f, /* 0x43a2e571 */ + sb3 = 1.5367296143e+03f, /* 0x44c01759 */ + sb4 = 3.1998581543e+03f, /* 0x4547fdbb */ + sb5 = 2.5530502930e+03f, /* 0x451f90ce */ + sb6 = 4.7452853394e+02f, /* 0x43ed43a7 */ + sb7 = -2.2440952301e+01f; /* 0xc1b38712 */ #ifdef __STDC__ Simple __erff(Simple x) #else Simple __erff(x) - Simple x; + Simple x; #endif -{ - int32_t hx,ix,i; - Simple R,S,P,Q,s,y,z,r; - GET_FLOAT_WORD(hx,x); - ix = hx&0x7fffffff; - if(ix>=0x7f800000) { /* erf(nan)=nan */ - i = ((u_int32_t)hx>>31)<<1; - return (Simple)(1-i)+one/x; /* erf(+-inf)=+-1 */ - } + { + int32_t hx, ix, i; + Simple R, S, P, Q, s, y, z, r; + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + if (ix >= 0x7f800000) { /* erf(nan)=nan */ + i = ((u_int32_t) hx >> 31) << 1; + return (Simple) (1 - i) + one / x; /* erf(+-inf)=+-1 */ + } - if(ix < 0x3f580000) { /* |x|<0.84375f */ - if(ix < 0x31800000) { /* |x|<2**-28 */ - if (ix < 0x04000000) - /*avoid underflow */ - return (Simple)0.125f*((Simple)8.0f*x+efx8*x); - return x + efx*x; - } - z = x*x; - r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); - s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); - y = r/s; - return x + x*y; + if (ix < 0x3f580000) { /* |x|<0.84375f */ + if (ix < 0x31800000) { /* |x|<2**-28 */ + if (ix < 0x04000000) + /*avoid underflow */ + return (Simple)0.125f*((Simple)8.0f*x + efx8*x); + return x + efx*x; + } + z = x*x; + r = pp0 + z*(pp1 + z*(pp2 + z*(pp3 + z*pp4))); + s = one + z*(qq1 + z*(qq2 + z*(qq3 + z*(qq4 + z*qq5)))); + y = r / s; + return x + x*y; + } + if (ix < 0x3fa00000) { /* 0.84375f <= |x| < 1.25f */ + s = fabsf(x) - one; + P = pa0 + s*(pa1 + s*(pa2 + s*(pa3 + s*(pa4 + s*(pa5 + s*pa6))))); + Q = one + s*(qa1 + s*(qa2 + s*(qa3 + s*(qa4 + s*(qa5 + s*qa6))))); + if (hx >= 0) return erx + P / Q; else return -erx - P / Q; + } + if (ix >= 0x40c00000) { /* inf>|x|>=6 */ + if (hx >= 0) return one - tiny; else return tiny - one; + } + x = fabsf(x); + s = one / (x*x); + if (ix < 0x4036DB6E) { /* |x| < 1/0.35f */ + R = ra0 + s*(ra1 + s*(ra2 + s*(ra3 + s*(ra4 + s*( + ra5 + s*(ra6 + s*ra7)))))); + S = one + s*(sa1 + s*(sa2 + s*(sa3 + s*(sa4 + s*( + sa5 + s*(sa6 + s*(sa7 + s*sa8))))))); + } else { /* |x| >= 1/0.35f */ + R = rb0 + s*(rb1 + s*(rb2 + s*(rb3 + s*(rb4 + s*( + rb5 + s*rb6))))); + S = one + s*(sb1 + s*(sb2 + s*(sb3 + s*(sb4 + s*( + sb5 + s*(sb6 + s*sb7)))))); + } + GET_FLOAT_WORD(ix, x); + SET_FLOAT_WORD(z, ix & 0xfffff000); + r = __ieee754_expf(-z*z - (Simple)0.5625f)*__ieee754_expf((z - x)*(z + x) + R / S); + if (hx >= 0) return one - r / x; else return r / x - one; } - if(ix < 0x3fa00000) { /* 0.84375f <= |x| < 1.25f */ - s = fabsf(x)-one; - P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); - Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); - if(hx>=0) return erx + P/Q; else return -erx - P/Q; - } - if (ix >= 0x40c00000) { /* inf>|x|>=6 */ - if(hx>=0) return one-tiny; else return tiny-one; - } - x = fabsf(x); - s = one/(x*x); - if(ix< 0x4036DB6E) { /* |x| < 1/0.35f */ - R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( - ra5+s*(ra6+s*ra7)))))); - S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( - sa5+s*(sa6+s*(sa7+s*sa8))))))); - } else { /* |x| >= 1/0.35f */ - R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( - rb5+s*rb6))))); - S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( - sb5+s*(sb6+s*sb7)))))); - } - GET_FLOAT_WORD(ix,x); - SET_FLOAT_WORD(z,ix&0xfffff000); - r = __ieee754_expf(-z*z-(Simple)0.5625f)*__ieee754_expf((z-x)*(z+x)+R/S); - if(hx>=0) return one-r/x; else return r/x-one; -} -weak_alias (__erff, erff) + weak_alias(__erff, erff) #ifdef __STDC__ - Simple __erfcf(Simple x) + Simple __erfcf(Simple x) #else - Simple __erfcf(x) - Simple x; + Simple __erfcf(x) + Simple x; #endif -{ - int32_t hx,ix; - Simple R,S,P,Q,s,y,z,r; - GET_FLOAT_WORD(hx,x); - ix = hx&0x7fffffff; - if(ix>=0x7f800000) { /* erfc(nan)=nan */ - /* erfc(+-inf)=0,2 */ - return (Simple)(((u_int32_t)hx>>31)<<1)+one/x; - } + { + int32_t hx, ix; + Simple R, S, P, Q, s, y, z, r; + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + if (ix >= 0x7f800000) { /* erfc(nan)=nan */ + /* erfc(+-inf)=0,2 */ + return (Simple) (((u_int32_t) hx >> 31) << 1) + one / x; + } - if(ix < 0x3f580000) { /* |x|<0.84375f */ - if(ix < 0x23800000) /* |x|<2**-56 */ - return one-x; - z = x*x; - r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); - s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); - y = r/s; - if(hx < 0x3e800000) { /* x<1/4 */ - return one-(x+x*y); - } else { - r = x*y; - r += (x-half); - return half - r ; - } - } - if(ix < 0x3fa00000) { /* 0.84375f <= |x| < 1.25f */ - s = fabsf(x)-one; - P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); - Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); - if(hx>=0) { - z = one-erx; return z - P/Q; - } else { - z = erx+P/Q; return one+z; - } - } - if (ix < 0x41e00000) { /* |x|<28 */ - x = fabsf(x); - s = one/(x*x); - if(ix< 0x4036DB6D) { /* |x| < 1/.35f ~ 2.857143f*/ - R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( - ra5+s*(ra6+s*ra7)))))); - S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( - sa5+s*(sa6+s*(sa7+s*sa8))))))); - } else { /* |x| >= 1/.35f ~ 2.857143f */ - if(hx<0&&ix>=0x40c00000) return two-tiny;/* x < -6 */ - R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( - rb5+s*rb6))))); - S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( - sb5+s*(sb6+s*sb7)))))); - } - GET_FLOAT_WORD(ix,x); - SET_FLOAT_WORD(z,ix&0xfffff000); - r = __ieee754_expf(-z*z-(Simple)0.5625f)* - __ieee754_expf((z-x)*(z+x)+R/S); - if(hx>0) return r/x; else return two-r/x; - } else { - if(hx>0) return tiny*tiny; else return two-tiny; + if (ix < 0x3f580000) { /* |x|<0.84375f */ + if (ix < 0x23800000) /* |x|<2**-56 */ + return one - x; + z = x*x; + r = pp0 + z*(pp1 + z*(pp2 + z*(pp3 + z*pp4))); + s = one + z*(qq1 + z*(qq2 + z*(qq3 + z*(qq4 + z*qq5)))); + y = r / s; + if (hx < 0x3e800000) { /* x<1/4 */ + return one - (x + x*y); + } else { + r = x*y; + r += (x - half); + return half - r; + } + } + if (ix < 0x3fa00000) { /* 0.84375f <= |x| < 1.25f */ + s = fabsf(x) - one; + P = pa0 + s*(pa1 + s*(pa2 + s*(pa3 + s*(pa4 + s*(pa5 + s*pa6))))); + Q = one + s*(qa1 + s*(qa2 + s*(qa3 + s*(qa4 + s*(qa5 + s*qa6))))); + if (hx >= 0) { + z = one - erx; return z - P / Q; + } else { + z = erx + P / Q; return one + z; + } + } + if (ix < 0x41e00000) { /* |x|<28 */ + x = fabsf(x); + s = one / (x*x); + if (ix < 0x4036DB6D) { /* |x| < 1/.35f ~ 2.857143f*/ + R = ra0 + s*(ra1 + s*(ra2 + s*(ra3 + s*(ra4 + s*( + ra5 + s*(ra6 + s*ra7)))))); + S = one + s*(sa1 + s*(sa2 + s*(sa3 + s*(sa4 + s*( + sa5 + s*(sa6 + s*(sa7 + s*sa8))))))); + } else { /* |x| >= 1/.35f ~ 2.857143f */ + if (hx < 0 && ix >= 0x40c00000) return two - tiny;/* x < -6 */ + R = rb0 + s*(rb1 + s*(rb2 + s*(rb3 + s*(rb4 + s*( + rb5 + s*rb6))))); + S = one + s*(sb1 + s*(sb2 + s*(sb3 + s*(sb4 + s*( + sb5 + s*(sb6 + s*sb7)))))); + } + GET_FLOAT_WORD(ix, x); + SET_FLOAT_WORD(z, ix & 0xfffff000); + r = __ieee754_expf(-z*z - (Simple)0.5625f)* + __ieee754_expf((z - x)*(z + x) + R / S); + if (hx > 0) return r / x; else return two - r / x; + } else { + if (hx > 0) return tiny*tiny; else return two - tiny; + } } -} -weak_alias (__erfcf, erfcf) + weak_alias(__erfcf, erfcf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_expm1f.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_expm1f.cpp index 0268e0ddb..f86cc13f3 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_expm1f.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_expm1f.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_expm1f.c,v 1.5f 1995/05/10 20:47:11 jtc Exp $"; @@ -26,114 +26,113 @@ static const Simple tiny = 1.0e-30f; namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -one = 1.0f, -o_threshold = 8.8721679688e+01f,/* 0x42b17180 */ -ln2_hi = 6.9313812256e-01f,/* 0x3f317180 */ -ln2_lo = 9.0580006145e-06f,/* 0x3717f7d1 */ -invln2 = 1.4426950216e+00f,/* 0x3fb8aa3b */ - /* scaled coefficients related to expm1 */ -Q1 = -3.3333335072e-02f, /* 0xbd088889 */ -Q2 = 1.5873016091e-03f, /* 0x3ad00d01 */ -Q3 = -7.9365076090e-05f, /* 0xb8a670cd */ -Q4 = 4.0082177293e-06f, /* 0x36867e54 */ -Q5 = -2.0109921195e-07f; /* 0xb457edbb */ + one = 1.0f, + o_threshold = 8.8721679688e+01f,/* 0x42b17180 */ + ln2_hi = 6.9313812256e-01f,/* 0x3f317180 */ + ln2_lo = 9.0580006145e-06f,/* 0x3717f7d1 */ + invln2 = 1.4426950216e+00f,/* 0x3fb8aa3b */ + /* scaled coefficients related to expm1 */ + Q1 = -3.3333335072e-02f, /* 0xbd088889 */ + Q2 = 1.5873016091e-03f, /* 0x3ad00d01 */ + Q3 = -7.9365076090e-05f, /* 0xb8a670cd */ + Q4 = 4.0082177293e-06f, /* 0x36867e54 */ + Q5 = -2.0109921195e-07f; /* 0xb457edbb */ #ifdef __STDC__ Simple __expm1f(Simple x) #else Simple __expm1f(x) - Simple x; + Simple x; #endif -{ - Simple y,hi,lo,c=0,t,e,hxs,hfx,r1; - int32_t k,xsb; - u_int32_t hx; + { + Simple y, hi, lo, c = 0, t, e, hxs, hfx, r1; + int32_t k, xsb; + u_int32_t hx; - GET_FLOAT_WORD(hx,x); - xsb = hx&0x80000000; /* sign bit of x */ - if(xsb==0) y=x; else y= -x; /* y = |x| */ - hx &= 0x7fffffff; /* high word of |x| */ + GET_FLOAT_WORD(hx, x); + xsb = hx & 0x80000000; /* sign bit of x */ + if (xsb == 0) y = x; else y = -x; /* y = |x| */ + hx &= 0x7fffffff; /* high word of |x| */ - /* filter out huge and non-finite argument */ - if(hx >= 0x4195b844) { /* if |x|>=27*ln2 */ - if(hx >= 0x42b17218) { /* if |x|>=88.721f... */ - if(hx>0x7f800000) - return x+x; /* NaN */ - if(hx==0x7f800000) - return (xsb==0)? x:-Simple(1.0f);/* exp(+-inf)={inf,-1} */ - if(x > o_threshold) return huge*huge; /* overflow */ - } - if(xsb!=0) { /* x < -27*ln2, return -1.0f with inexact */ - if(x+tiny<(Simple)0.0f) /* raise inexact */ - return tiny-one; /* return -1 */ - } - } + /* filter out huge and non-finite argument */ + if (hx >= 0x4195b844) { /* if |x|>=27*ln2 */ + if (hx >= 0x42b17218) { /* if |x|>=88.721f... */ + if (hx > 0x7f800000) + return x + x; /* NaN */ + if (hx == 0x7f800000) + return (xsb == 0) ? x : -Simple(1.0f);/* exp(+-inf)={inf,-1} */ + if (x > o_threshold) return huge*huge; /* overflow */ + } + if (xsb != 0) { /* x < -27*ln2, return -1.0f with inexact */ + if (x + tiny < (Simple)0.0f) /* raise inexact */ + return tiny - one; /* return -1 */ + } + } - /* argument reduction */ - if(hx > 0x3eb17218) { /* if |x| > 0.5f ln2 */ - if(hx < 0x3F851592) { /* and |x| < 1.5f ln2 */ - if(xsb==0) - {hi = x - ln2_hi; lo = ln2_lo; k = 1;} - else - {hi = x + ln2_hi; lo = -ln2_lo; k = -1;} - } else { - k = invln2*x+((xsb==0)?(Simple)0.5f:(Simple)-0.5f); - t = k; - hi = x - t*ln2_hi; /* t*ln2_hi is exact here */ - lo = t*ln2_lo; - } - x = hi - lo; - c = (hi-x)-lo; - } - else if(hx < 0x33000000) { /* when |x|<2**-25, return x */ - t = huge+x; /* return x with inexact flags when x!=0 */ - return x - (t-(huge+x)); - } - else k = 0; + /* argument reduction */ + if (hx > 0x3eb17218) { /* if |x| > 0.5f ln2 */ + if (hx < 0x3F851592) { /* and |x| < 1.5f ln2 */ + if (xsb == 0) { + hi = x - ln2_hi; lo = ln2_lo; k = 1; + } else { + hi = x + ln2_hi; lo = -ln2_lo; k = -1; + } + } else { + k = invln2*x + ((xsb == 0) ? (Simple)0.5f : (Simple) -0.5f); + t = k; + hi = x - t*ln2_hi; /* t*ln2_hi is exact here */ + lo = t*ln2_lo; + } + x = hi - lo; + c = (hi - x) - lo; + } else if (hx < 0x33000000) { /* when |x|<2**-25, return x */ + t = huge + x; /* return x with inexact flags when x!=0 */ + return x - (t - (huge + x)); + } else k = 0; - /* x is now in primary range */ - hfx = (Simple)0.5f*x; - hxs = x*hfx; - r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5)))); - t = (Simple)3.0f-r1*hfx; - e = hxs*((r1-t)/((Simple)6.0f - x*t)); - if(k==0) return x - (x*e-hxs); /* c is 0 */ - else { - e = (x*(e-c)-c); - e -= hxs; - if(k== -1) return (Simple)0.5f*(x-e)-(Simple)0.5f; - if(k==1) { - if(x < (Simple)-0.25f) return -(Simple)2.0f*(e-(x+(Simple)0.5f)); - else return one+(Simple)2.0f*(x-e); - } - if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */ - int32_t i; - y = one-(e-x); - GET_FLOAT_WORD(i,y); - SET_FLOAT_WORD(y,i+(k<<23)); /* add k to y's exponent */ - return y-one; - } - t = one; - if(k<23) { - int32_t i; - SET_FLOAT_WORD(t,0x3f800000 - (0x1000000>>k)); /* t=1-2^-k */ - y = t-(e-x); - GET_FLOAT_WORD(i,y); - SET_FLOAT_WORD(y,i+(k<<23)); /* add k to y's exponent */ - } else { - int32_t i; - SET_FLOAT_WORD(t,((0x7f-k)<<23)); /* 2^-k */ - y = x-(e+t); - y += one; - GET_FLOAT_WORD(i,y); - SET_FLOAT_WORD(y,i+(k<<23)); /* add k to y's exponent */ - } + /* x is now in primary range */ + hfx = (Simple)0.5f*x; + hxs = x*hfx; + r1 = one + hxs*(Q1 + hxs*(Q2 + hxs*(Q3 + hxs*(Q4 + hxs*Q5)))); + t = (Simple)3.0f - r1*hfx; + e = hxs*((r1 - t) / ((Simple)6.0f - x*t)); + if (k == 0) return x - (x*e - hxs); /* c is 0 */ + else { + e = (x*(e - c) - c); + e -= hxs; + if (k == -1) return (Simple)0.5f*(x - e) - (Simple)0.5f; + if (k == 1) { + if (x < (Simple) -0.25f) return -(Simple)2.0f*(e - (x + (Simple)0.5f)); + else return one + (Simple)2.0f*(x - e); + } + if (k <= -2 || k > 56) { /* suffice to return exp(x)-1 */ + int32_t i; + y = one - (e - x); + GET_FLOAT_WORD(i, y); + SET_FLOAT_WORD(y, i + (k << 23)); /* add k to y's exponent */ + return y - one; + } + t = one; + if (k < 23) { + int32_t i; + SET_FLOAT_WORD(t, 0x3f800000 - (0x1000000 >> k)); /* t=1-2^-k */ + y = t - (e - x); + GET_FLOAT_WORD(i, y); + SET_FLOAT_WORD(y, i + (k << 23)); /* add k to y's exponent */ + } else { + int32_t i; + SET_FLOAT_WORD(t, ((0x7f - k) << 23)); /* 2^-k */ + y = x - (e + t); + y += one; + GET_FLOAT_WORD(i, y); + SET_FLOAT_WORD(y, i + (k << 23)); /* add k to y's exponent */ + } + } + return y; } - return y; -} -weak_alias (__expm1f, expm1f) + weak_alias(__expm1f, expm1f) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_fabsf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_fabsf.cpp index 2d3942ecc..11f1ccf8d 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_fabsf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_fabsf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_fabsf.c,v 1.4f 1995/05/10 20:47:15 jtc Exp $"; @@ -30,13 +30,13 @@ namespace streflop_libm { Simple __fabsf(Simple x) #else Simple __fabsf(x) - Simple x; + Simple x; #endif -{ - u_int32_t ix; - GET_FLOAT_WORD(ix,x); - SET_FLOAT_WORD(x,ix&0x7fffffff); - return x; -} -weak_alias (__fabsf, fabsf) + { + u_int32_t ix; + GET_FLOAT_WORD(ix, x); + SET_FLOAT_WORD(x, ix & 0x7fffffff); + return x; + } + weak_alias(__fabsf, fabsf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_finitef.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_finitef.cpp index 300372dee..7304ff001 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_finitef.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_finitef.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_finitef.c,v 1.4f 1995/05/10 20:47:18 jtc Exp $"; @@ -31,13 +31,13 @@ namespace streflop_libm { int __finitef(Simple x) #else int __finitef(x) - Simple x; + Simple x; #endif -{ - int32_t ix; - GET_FLOAT_WORD(ix,x); - return (int)((u_int32_t)((ix&0x7fffffff)-0x7f800000)>>31); -} -hidden_def (__finitef) -weak_alias (__finitef, finitef) + { + int32_t ix; + GET_FLOAT_WORD(ix, x); + return (int) ((u_int32_t) ((ix & 0x7fffffff) - 0x7f800000) >> 31); + } + hidden_def(__finitef) + weak_alias(__finitef, finitef) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_floorf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_floorf.cpp index 42a87d46c..23b2542c5 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_floorf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_floorf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_floorf.c,v 1.4f 1995/05/10 20:47:22 jtc Exp $"; @@ -32,43 +32,45 @@ static char rcsid[] = "$NetBSD: s_floorf.c,v 1.4f 1995/05/10 20:47:22 jtc Exp $" namespace streflop_libm { #ifdef __STDC__ -static const Simple huge = 1.0e30f; + static const Simple huge = 1.0e30f; #else -static Simple huge = 1.0e30f; + static Simple huge = 1.0e30f; #endif #ifdef __STDC__ Simple __floorf(Simple x) #else Simple __floorf(x) - Simple x; + Simple x; #endif -{ - int32_t i0,j0; - u_int32_t i; - GET_FLOAT_WORD(i0,x); - j0 = ((i0>>23)&0xff)-0x7f; - if(j0<23) { - if(j0<0) { /* raise inexact if x != 0 */ - if(huge+x>(Simple)0.0f) {/* return 0*sign(x) if |x|<1 */ - if(i0>=0) {i0=0;} - else if((i0&0x7fffffff)!=0) - { i0=0xbf800000;} + { + int32_t i0, j0; + u_int32_t i; + GET_FLOAT_WORD(i0, x); + j0 = ((i0 >> 23) & 0xff) - 0x7f; + if (j0 < 23) { + if (j0 < 0) { /* raise inexact if x != 0 */ + if (huge + x > (Simple)0.0f) {/* return 0*sign(x) if |x|<1 */ + if (i0 >= 0) { + i0 = 0; + } else if ((i0 & 0x7fffffff) != 0) { + i0 = 0xbf800000; + } + } + } else { + i = (0x007fffff) >> j0; + if ((i0&i) == 0) return x; /* x is integral */ + if (huge + x > (Simple)0.0f) { /* raise inexact flag */ + if (i0 < 0) i0 += (0x00800000) >> j0; + i0 &= (~i); + } + } + } else { + if (j0 == 0x80) return x + x; /* inf or NaN */ + else return x; /* x is integral */ } - } else { - i = (0x007fffff)>>j0; - if((i0&i)==0) return x; /* x is integral */ - if(huge+x>(Simple)0.0f) { /* raise inexact flag */ - if(i0<0) i0 += (0x00800000)>>j0; - i0 &= (~i); - } - } - } else { - if(j0==0x80) return x+x; /* inf or NaN */ - else return x; /* x is integral */ + SET_FLOAT_WORD(x, i0); + return x; } - SET_FLOAT_WORD(x,i0); - return x; -} -weak_alias (__floorf, floorf) + weak_alias(__floorf, floorf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_fpclassifyf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_fpclassifyf.cpp index ed23e8985..e315954e7 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_fpclassifyf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_fpclassifyf.cpp @@ -25,22 +25,21 @@ namespace streflop_libm { -int -__fpclassifyf (Simple x) -{ - u_int32_t wx; - int retval = FP_NORMAL; + int + __fpclassifyf(Simple x) { + u_int32_t wx; + int retval = FP_NORMAL; - GET_FLOAT_WORD (wx, x); - wx &= 0x7fffffff; - if (wx == 0) - retval = FP_ZERO; - else if (wx < 0x800000) - retval = FP_SUBNORMAL; - else if (wx >= 0x7f800000) - retval = wx > 0x7f800000 ? FP_NAN : FP_INFINITE; + GET_FLOAT_WORD(wx, x); + wx &= 0x7fffffff; + if (wx == 0) + retval = FP_ZERO; + else if (wx < 0x800000) + retval = FP_SUBNORMAL; + else if (wx >= 0x7f800000) + retval = wx > 0x7f800000 ? FP_NAN : FP_INFINITE; - return retval; -} -libm_hidden_def (__fpclassifyf) + return retval; + } + libm_hidden_def(__fpclassifyf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_frexpf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_frexpf.cpp index a416f605f..219428c98 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_frexpf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_frexpf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_frexpf.c,v 1.5f 1995/05/10 20:47:26 jtc Exp $"; @@ -23,34 +23,34 @@ static char rcsid[] = "$NetBSD: s_frexpf.c,v 1.5f 1995/05/10 20:47:26 jtc Exp $" namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -two25 = 3.3554432000e+07f; /* 0x4c000000 */ + two25 = 3.3554432000e+07f; /* 0x4c000000 */ #ifdef __STDC__ Simple __frexpf(Simple x, int *eptr) #else Simple __frexpf(x, eptr) - Simple x; int *eptr; + Simple x; int *eptr; #endif -{ - int32_t hx,ix; - GET_FLOAT_WORD(hx,x); - ix = 0x7fffffff&hx; - *eptr = 0; - if(ix>=0x7f800000||(ix==0)) return x; /* 0,inf,nan */ - if (ix<0x00800000) { /* subnormal */ - x *= two25; - GET_FLOAT_WORD(hx,x); - ix = hx&0x7fffffff; - *eptr = -25; + { + int32_t hx, ix; + GET_FLOAT_WORD(hx, x); + ix = 0x7fffffff & hx; + *eptr = 0; + if (ix >= 0x7f800000 || (ix == 0)) return x; /* 0,inf,nan */ + if (ix < 0x00800000) { /* subnormal */ + x *= two25; + GET_FLOAT_WORD(hx, x); + ix = hx & 0x7fffffff; + *eptr = -25; + } + *eptr += (ix >> 23) - 126; + hx = (hx & 0x807fffff) | 0x3f000000; + SET_FLOAT_WORD(x, hx); + return x; } - *eptr += (ix>>23)-126; - hx = (hx&0x807fffff)|0x3f000000; - SET_FLOAT_WORD(x,hx); - return x; -} -weak_alias (__frexpf, frexpf) + weak_alias(__frexpf, frexpf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_ilogbf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_ilogbf.cpp index b0b31cdc5..707757dc9 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_ilogbf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_ilogbf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_ilogbf.c,v 1.4f 1995/05/10 20:47:31 jtc Exp $"; @@ -27,27 +27,26 @@ namespace streflop_libm { int __ilogbf(Simple x) #else int __ilogbf(x) - Simple x; + Simple x; #endif -{ - int32_t hx,ix; + { + int32_t hx, ix; - GET_FLOAT_WORD(hx,x); - hx &= 0x7fffffff; - if(hx<0x00800000) { - if(hx==0) - return FP_ILOGB0; /* ilogb(0) = FP_ILOGB0 */ - else /* subnormal x */ - for (ix = -126,hx<<=8; hx>0; hx<<=1) ix -=1; - return ix; + GET_FLOAT_WORD(hx, x); + hx &= 0x7fffffff; + if (hx < 0x00800000) { + if (hx == 0) + return FP_ILOGB0; /* ilogb(0) = FP_ILOGB0 */ + else /* subnormal x */ + for (ix = -126, hx <<= 8; hx > 0; hx <<= 1) ix -= 1; + return ix; + } else if (hx < 0x7f800000) return (hx >> 23) - 127; + else if (FP_ILOGBNAN != INT_MAX) { + /* ISO C99 requires ilogbf(+-Inf) == INT_MAX. */ + if (hx == 0x7f800000) + return INT_MAX; + } + return FP_ILOGBNAN; } - else if (hx<0x7f800000) return (hx>>23)-127; - else if (FP_ILOGBNAN != INT_MAX) { - /* ISO C99 requires ilogbf(+-Inf) == INT_MAX. */ - if (hx==0x7f800000) - return INT_MAX; - } - return FP_ILOGBNAN; -} -weak_alias (__ilogbf, ilogbf) + weak_alias(__ilogbf, ilogbf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_isinff.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_isinff.cpp index e6c4daea5..98f22c49b 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_isinff.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_isinff.cpp @@ -17,16 +17,15 @@ static char rcsid[] = "$NetBSD: s_isinff.c,v 1.3f 1995/05/11 23:20:21 jtc Exp $" #include "math_private.h" namespace streflop_libm { -int -__isinff (Simple x) -{ - int32_t ix,t; - GET_FLOAT_WORD(ix,x); - t = ix & 0x7fffffff; - t ^= 0x7f800000; - t |= -t; - return ~(t >> 31) & (ix >> 30); -} -hidden_def (__isinff) -weak_alias (__isinff, isinff) + int + __isinff(Simple x) { + int32_t ix, t; + GET_FLOAT_WORD(ix, x); + t = ix & 0x7fffffff; + t ^= 0x7f800000; + t |= -t; + return ~(t >> 31) & (ix >> 30); + } + hidden_def(__isinff) + weak_alias(__isinff, isinff) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_isnanf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_isnanf.cpp index ee94414ce..d18a08682 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_isnanf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_isnanf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_isnanf.c,v 1.4f 1995/05/10 20:47:38 jtc Exp $"; @@ -31,15 +31,15 @@ namespace streflop_libm { int __isnanf(Simple x) #else int __isnanf(x) - Simple x; + Simple x; #endif -{ - int32_t ix; - GET_FLOAT_WORD(ix,x); - ix &= 0x7fffffff; - ix = 0x7f800000 - ix; - return (int)(((u_int32_t)(ix))>>31); -} -hidden_def (__isnanf) -weak_alias (__isnanf, isnanf) + { + int32_t ix; + GET_FLOAT_WORD(ix, x); + ix &= 0x7fffffff; + ix = 0x7f800000 - ix; + return (int) (((u_int32_t) (ix)) >> 31); + } + hidden_def(__isnanf) + weak_alias(__isnanf, isnanf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_ldexpf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_ldexpf.cpp index 378ea7957..a20a77c66 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_ldexpf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_ldexpf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_ldexpf.c,v 1.3f 1995/05/10 20:47:42 jtc Exp $"; @@ -27,14 +27,14 @@ namespace streflop_libm { Simple __ldexpf(Simple value, int exp) #else Simple __ldexpf(value, exp) - Simple value; int exp; + Simple value; int exp; #endif -{ - if(!__finitef(value)||value==(Simple)0.0f) return value; - value = __scalbnf(value,exp); - if(!__finitef(value)||value==(Simple)0.0f) __set_errno (ERANGE); - return value; -} -INTDEF(__ldexpf) -weak_alias (__ldexpf, ldexpf) + { + if (!__finitef(value) || value == (Simple)0.0f) return value; + value = __scalbnf(value, exp); + if (!__finitef(value) || value == (Simple)0.0f) __set_errno(ERANGE); + return value; + } + INTDEF(__ldexpf) + weak_alias(__ldexpf, ldexpf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_llrintf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_llrintf.cpp index e35eb6833..be276065b 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_llrintf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_llrintf.cpp @@ -32,48 +32,43 @@ static const Simple two23[2] = long long int -__llrintf (Simple x) -{ - int32_t j0; - u_int32_t i0; - Simple w; - Simple t; - long long int result; - int sx; +__llrintf(Simple x) { + int32_t j0; + u_int32_t i0; + Simple w; + Simple t; + long long int result; + int sx; - GET_FLOAT_WORD (i0, x); + GET_FLOAT_WORD(i0, x); - sx = i0 >> 31; - j0 = ((i0 >> 23) & 0xff) - 0x7f; - i0 &= 0x7fffff; - i0 |= 0x800000; + sx = i0 >> 31; + j0 = ((i0 >> 23) & 0xff) - 0x7f; + i0 &= 0x7fffff; + i0 |= 0x800000; - if (j0 < (int32_t) (sizeof (long long int) * 8) - 1) - { - if (j0 < -1) - return 0; - else if (j0 >= 23) - result = (long long int) i0 << (j0 - 23); - else - { - w = two23[sx] + x; - t = w - two23[sx]; - GET_FLOAT_WORD (i0, t); - j0 = ((i0 >> 23) & 0xff) - 0x7f; - i0 &= 0x7fffff; - i0 |= 0x800000; + if (j0 < (int32_t) (sizeof(long long int) * 8) - 1) { + if (j0 < -1) + return 0; + else if (j0 >= 23) + result = (long long int) i0 << (j0 - 23); + else { + w = two23[sx] + x; + t = w - two23[sx]; + GET_FLOAT_WORD(i0, t); + j0 = ((i0 >> 23) & 0xff) - 0x7f; + i0 &= 0x7fffff; + i0 |= 0x800000; - result = i0 >> (23 - j0); + result = i0 >> (23 - j0); + } + } else { + /* The number is too large. It is left implementation defined + what happens. */ + return (long long int) x; } - } - else - { - /* The number is too large. It is left implementation defined - what happens. */ - return (long long int) x; - } - return sx ? -result : result; + return sx ? -result : result; } -weak_alias (__llrintf, llrintf) +weak_alias(__llrintf, llrintf) diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_llroundf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_llroundf.cpp index 64491470a..45abe3795 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_llroundf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_llroundf.cpp @@ -25,40 +25,35 @@ long long int -__llroundf (Simple x) -{ - int32_t j0; - u_int32_t i; - long long int result; - int sign; +__llroundf(Simple x) { + int32_t j0; + u_int32_t i; + long long int result; + int sign; - GET_FLOAT_WORD (i, x); - j0 = ((i >> 23) & 0xff) - 0x7f; - sign = (i & 0x80000000) != 0 ? -1 : 1; - i &= 0x7fffff; - i |= 0x800000; + GET_FLOAT_WORD(i, x); + j0 = ((i >> 23) & 0xff) - 0x7f; + sign = (i & 0x80000000) != 0 ? -1 : 1; + i &= 0x7fffff; + i |= 0x800000; - if (j0 < (int32_t) (8 * sizeof (long long int)) - 1) - { - if (j0 < 0) - return j0 < -1 ? 0 : sign; - else if (j0 >= 23) - result = (long long int) i << (j0 - 23); - else - { - i += 0x400000 >> j0; + if (j0 < (int32_t) (8 * sizeof(long long int)) - 1) { + if (j0 < 0) + return j0 < -1 ? 0 : sign; + else if (j0 >= 23) + result = (long long int) i << (j0 - 23); + else { + i += 0x400000 >> j0; - result = i >> (23 - j0); + result = i >> (23 - j0); + } + } else { + /* The number is too large. It is left implementation defined + what happens. */ + return (long long int) x; } - } - else - { - /* The number is too large. It is left implementation defined - what happens. */ - return (long long int) x; - } - return sign * result; + return sign * result; } -weak_alias (__llroundf, llroundf) +weak_alias(__llroundf, llroundf) diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_log1pf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_log1pf.cpp index 7aa5e200b..7abcc87b9 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_log1pf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_log1pf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_log1pf.c,v 1.4f 1995/05/10 20:47:48 jtc Exp $"; @@ -23,96 +23,99 @@ static char rcsid[] = "$NetBSD: s_log1pf.c,v 1.4f 1995/05/10 20:47:48 jtc Exp $" namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -ln2_hi = 6.9313812256e-01f, /* 0x3f317180 */ -ln2_lo = 9.0580006145e-06f, /* 0x3717f7d1 */ -two25 = 3.355443200e+07f, /* 0x4c000000 */ -Lp1 = 6.6666668653e-01f, /* 3F2AAAAB */ -Lp2 = 4.0000000596e-01f, /* 3ECCCCCD */ -Lp3 = 2.8571429849e-01f, /* 3E924925 */ -Lp4 = 2.2222198546e-01f, /* 3E638E29 */ -Lp5 = 1.8183572590e-01f, /* 3E3A3325 */ -Lp6 = 1.5313838422e-01f, /* 3E1CD04F */ -Lp7 = 1.4798198640e-01f; /* 3E178897 */ + ln2_hi = 6.9313812256e-01f, /* 0x3f317180 */ + ln2_lo = 9.0580006145e-06f, /* 0x3717f7d1 */ + two25 = 3.355443200e+07f, /* 0x4c000000 */ + Lp1 = 6.6666668653e-01f, /* 3F2AAAAB */ + Lp2 = 4.0000000596e-01f, /* 3ECCCCCD */ + Lp3 = 2.8571429849e-01f, /* 3E924925 */ + Lp4 = 2.2222198546e-01f, /* 3E638E29 */ + Lp5 = 1.8183572590e-01f, /* 3E3A3325 */ + Lp6 = 1.5313838422e-01f, /* 3E1CD04F */ + Lp7 = 1.4798198640e-01f; /* 3E178897 */ #ifdef __STDC__ -static const Simple zero = 0.0f; + static const Simple zero = 0.0f; #else -static Simple zero = 0.0f; + static Simple zero = 0.0f; #endif #ifdef __STDC__ Simple __log1pf(Simple x) #else Simple __log1pf(x) - Simple x; + Simple x; #endif -{ - Simple hfsq,f=0,c=0,s,z,R,u; - int32_t k,hx,hu=0,ax; + { + Simple hfsq, f = 0, c = 0, s, z, R, u; + int32_t k, hx, hu = 0, ax; - GET_FLOAT_WORD(hx,x); - ax = hx&0x7fffffff; + GET_FLOAT_WORD(hx, x); + ax = hx & 0x7fffffff; - k = 1; - if (hx < 0x3ed413d7) { /* x < 0.41422f */ - if(ax>=0x3f800000) { /* x <= -1.0f */ - if(x==(Simple)-1.0f) return -two25/(x-x); /* log1p(-1)=+inf */ - else return (x-x)/(x-x); /* log1p(x<-1)=NaN */ - } - if(ax<0x31000000) { /* |x| < 2**-29 */ - if(two25+x>zero /* raise inexact */ - &&ax<0x24800000) /* |x| < 2**-54 */ - return x; - else - return x - x*x*(Simple)0.5f; - } - if(hx>0||hx<=((int32_t)0xbe95f61f)) { - k=0;f=x;hu=1;} /* -0.2929f= 0x3f800000) { /* x <= -1.0f */ + if (x == (Simple) -1.0f) return -two25 / (x - x); /* log1p(-1)=+inf */ + else return (x - x) / (x - x); /* log1p(x<-1)=NaN */ + } + if (ax < 0x31000000) { /* |x| < 2**-29 */ + if (two25 + x > zero /* raise inexact */ + &&ax < 0x24800000) /* |x| < 2**-54 */ + return x; + else + return x - x*x*(Simple)0.5f; + } + if (hx > 0 || hx <= ((int32_t) 0xbe95f61f)) { + k = 0; f = x; hu = 1; + } /* -0.2929f= 0x7f800000) return x + x; + if (k != 0) { + if (hx < 0x5a000000) { + u = (Simple)1.0f + x; + GET_FLOAT_WORD(hu, u); + k = (hu >> 23) - 127; + /* correction term */ + c = (k > 0) ? (Simple) Simple(1.0f) - (u - x) : x - (u - (Simple) Simple(1.0f)); + c /= u; + } else { + u = x; + GET_FLOAT_WORD(hu, u); + k = (hu >> 23) - 127; + c = 0; + } + hu &= 0x007fffff; + if (hu < 0x3504f7) { + SET_FLOAT_WORD(u, hu | 0x3f800000);/* normalize u */ + } else { + k += 1; + SET_FLOAT_WORD(u, hu | 0x3f000000); /* normalize u/2 */ + hu = (0x00800000 - hu) >> 2; + } + f = u - (Simple)1.0f; + } + hfsq = (Simple)0.5f*f*f; + if (hu == 0) { /* |f| < 2**-20 */ + if (f == zero) { + if (k == 0) return zero; + else { + c += k*ln2_lo; return k*ln2_hi + c; + } + } + R = hfsq*((Simple)1.0f - (Simple)0.66666666666666666f*f); + if (k == 0) return f - R; else + return k*ln2_hi - ((R - (k*ln2_lo + c)) - f); + } + s = f / ((Simple)2.0f + f); + z = s*s; + R = z*(Lp1 + z*(Lp2 + z*(Lp3 + z*(Lp4 + z*(Lp5 + z*(Lp6 + z*Lp7)))))); + if (k == 0) return f - (hfsq - s*(hfsq + R)); else + return k*ln2_hi - ((hfsq - (s*(hfsq + R) + (k*ln2_lo + c))) - f); } - if (hx >= 0x7f800000) return x+x; - if(k!=0) { - if(hx<0x5a000000) { - u = (Simple)1.0f+x; - GET_FLOAT_WORD(hu,u); - k = (hu>>23)-127; - /* correction term */ - c = (k>0)? (Simple)Simple(1.0f)-(u-x):x-(u-(Simple)Simple(1.0f)); - c /= u; - } else { - u = x; - GET_FLOAT_WORD(hu,u); - k = (hu>>23)-127; - c = 0; - } - hu &= 0x007fffff; - if(hu<0x3504f7) { - SET_FLOAT_WORD(u,hu|0x3f800000);/* normalize u */ - } else { - k += 1; - SET_FLOAT_WORD(u,hu|0x3f000000); /* normalize u/2 */ - hu = (0x00800000-hu)>>2; - } - f = u-(Simple)1.0f; - } - hfsq=(Simple)0.5f*f*f; - if(hu==0) { /* |f| < 2**-20 */ - if(f==zero) { - if(k==0) return zero; - else {c += k*ln2_lo; return k*ln2_hi+c;} - } - R = hfsq*((Simple)1.0f-(Simple)0.66666666666666666f*f); - if(k==0) return f-R; else - return k*ln2_hi-((R-(k*ln2_lo+c))-f); - } - s = f/((Simple)2.0f+f); - z = s*s; - R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7)))))); - if(k==0) return f-(hfsq-s*(hfsq+R)); else - return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f); -} -weak_alias (__log1pf, log1pf) + weak_alias(__log1pf, log1pf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_logbf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_logbf.cpp index 21756c02e..bee826ed2 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_logbf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_logbf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_logbf.c,v 1.4f 1995/05/10 20:47:51 jtc Exp $"; @@ -26,18 +26,18 @@ namespace streflop_libm { Simple __logbf(Simple x) #else Simple __logbf(x) - Simple x; + Simple x; #endif -{ - int32_t ix; - GET_FLOAT_WORD(ix,x); - ix &= 0x7fffffff; /* high |x| */ - if(ix==0) return (Simple)-1.0f/fabsf(x); - if(ix>=0x7f800000) return x*x; - if((ix>>=23)==0) /* IEEE 754 logb */ - return -126.0f; - else - return (Simple) (ix-127); -} -weak_alias (__logbf, logbf) + { + int32_t ix; + GET_FLOAT_WORD(ix, x); + ix &= 0x7fffffff; /* high |x| */ + if (ix == 0) return (Simple) -1.0f / fabsf(x); + if (ix >= 0x7f800000) return x*x; + if ((ix >>= 23) == 0) /* IEEE 754 logb */ + return -126.0f; + else + return (Simple) (ix - 127); + } + weak_alias(__logbf, logbf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_lrintf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_lrintf.cpp index 9bad5f47d..d75daa849 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_lrintf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_lrintf.cpp @@ -32,48 +32,43 @@ static const Simple two23[2] = long int -__lrintf (Simple x) -{ - int32_t j0; - u_int32_t i0; - Simple w; - Simple t; - long int result; - int sx; +__lrintf(Simple x) { + int32_t j0; + u_int32_t i0; + Simple w; + Simple t; + long int result; + int sx; - GET_FLOAT_WORD (i0, x); + GET_FLOAT_WORD(i0, x); - sx = i0 >> 31; - j0 = ((i0 >> 23) & 0xff) - 0x7f; - i0 &= 0x7fffff; - i0 |= 0x800000; + sx = i0 >> 31; + j0 = ((i0 >> 23) & 0xff) - 0x7f; + i0 &= 0x7fffff; + i0 |= 0x800000; - if (j0 < (int32_t) (sizeof (long int) * 8) - 1) - { - if (j0 < -1) - return 0; - else if (j0 >= 23) - result = (long int) i0 << (j0 - 23); - else - { - w = two23[sx] + x; - t = w - two23[sx]; - GET_FLOAT_WORD (i0, t); - j0 = ((i0 >> 23) & 0xff) - 0x7f; - i0 &= 0x7fffff; - i0 |= 0x800000; + if (j0 < (int32_t) (sizeof(long int) * 8) - 1) { + if (j0 < -1) + return 0; + else if (j0 >= 23) + result = (long int) i0 << (j0 - 23); + else { + w = two23[sx] + x; + t = w - two23[sx]; + GET_FLOAT_WORD(i0, t); + j0 = ((i0 >> 23) & 0xff) - 0x7f; + i0 &= 0x7fffff; + i0 |= 0x800000; - result = i0 >> (23 - j0); + result = i0 >> (23 - j0); + } + } else { + /* The number is too large. It is left implementation defined + what happens. */ + return (long int) x; } - } - else - { - /* The number is too large. It is left implementation defined - what happens. */ - return (long int) x; - } - return sx ? -result : result; + return sx ? -result : result; } -weak_alias (__lrintf, lrintf) +weak_alias(__lrintf, lrintf) diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_lroundf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_lroundf.cpp index 01b20dd8d..0d5d54fbd 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_lroundf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_lroundf.cpp @@ -25,40 +25,35 @@ long int -__lroundf (Simple x) -{ - int32_t j0; - u_int32_t i; - long int result; - int sign; +__lroundf(Simple x) { + int32_t j0; + u_int32_t i; + long int result; + int sign; - GET_FLOAT_WORD (i, x); - j0 = ((i >> 23) & 0xff) - 0x7f; - sign = (i & 0x80000000) != 0 ? -1 : 1; - i &= 0x7fffff; - i |= 0x800000; + GET_FLOAT_WORD(i, x); + j0 = ((i >> 23) & 0xff) - 0x7f; + sign = (i & 0x80000000) != 0 ? -1 : 1; + i &= 0x7fffff; + i |= 0x800000; - if (j0 < (int32_t) (8 * sizeof (long int)) - 1) - { - if (j0 < 0) - return j0 < -1 ? 0 : sign; - else if (j0 >= 23) - result = (long int) i << (j0 - 23); - else - { - i += 0x400000 >> j0; + if (j0 < (int32_t) (8 * sizeof(long int)) - 1) { + if (j0 < 0) + return j0 < -1 ? 0 : sign; + else if (j0 >= 23) + result = (long int) i << (j0 - 23); + else { + i += 0x400000 >> j0; - result = i >> (23 - j0); + result = i >> (23 - j0); + } + } else { + /* The number is too large. It is left implementation defined + what happens. */ + return (long int) x; } - } - else - { - /* The number is too large. It is left implementation defined - what happens. */ - return (long int) x; - } - return sign * result; + return sign * result; } -weak_alias (__lroundf, lroundf) +weak_alias(__lroundf, lroundf) diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_modff.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_modff.cpp index aef83849d..9d926bb4a 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_modff.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_modff.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_modff.c,v 1.4f 1995/05/10 20:47:56 jtc Exp $"; @@ -23,47 +23,47 @@ static char rcsid[] = "$NetBSD: s_modff.c,v 1.4f 1995/05/10 20:47:56 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static const Simple one = 1.0f; + static const Simple one = 1.0f; #else -static Simple one = 1.0f; + static Simple one = 1.0f; #endif #ifdef __STDC__ Simple __modff(Simple x, Simple *iptr) #else Simple __modff(x, iptr) - Simple x,*iptr; + Simple x, *iptr; #endif -{ - int32_t i0,j0; - u_int32_t i; - GET_FLOAT_WORD(i0,x); - j0 = ((i0>>23)&0xff)-0x7f; /* exponent of x */ - if(j0<23) { /* integer part in x */ - if(j0<0) { /* |x|<1 */ - SET_FLOAT_WORD(*iptr,i0&0x80000000); /* *iptr = +-0 */ - return x; - } else { - i = (0x007fffff)>>j0; - if((i0&i)==0) { /* x is integral */ - u_int32_t ix; - *iptr = x; - GET_FLOAT_WORD(ix,x); - SET_FLOAT_WORD(x,ix&0x80000000); /* return +-0 */ - return x; - } else { - SET_FLOAT_WORD(*iptr,i0&(~i)); - return x - *iptr; + { + int32_t i0, j0; + u_int32_t i; + GET_FLOAT_WORD(i0, x); + j0 = ((i0 >> 23) & 0xff) - 0x7f; /* exponent of x */ + if (j0 < 23) { /* integer part in x */ + if (j0 < 0) { /* |x|<1 */ + SET_FLOAT_WORD(*iptr, i0 & 0x80000000); /* *iptr = +-0 */ + return x; + } else { + i = (0x007fffff) >> j0; + if ((i0&i) == 0) { /* x is integral */ + u_int32_t ix; + *iptr = x; + GET_FLOAT_WORD(ix, x); + SET_FLOAT_WORD(x, ix & 0x80000000); /* return +-0 */ + return x; + } else { + SET_FLOAT_WORD(*iptr, i0&(~i)); + return x - *iptr; + } + } + } else { /* no fraction part */ + *iptr = x*one; + /* We must handle NaNs separately. */ + if (j0 == 0x80 && (i0 & 0x7fffff)) + return x*one; + SET_FLOAT_WORD(x, i0 & 0x80000000); /* return +-0 */ + return x; } - } - } else { /* no fraction part */ - *iptr = x*one; - /* We must handle NaNs separately. */ - if (j0 == 0x80 && (i0 & 0x7fffff)) - return x*one; - SET_FLOAT_WORD(x,i0&0x80000000); /* return +-0 */ - return x; } -} -weak_alias (__modff, modff) + weak_alias(__modff, modff) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_nearbyintf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_nearbyintf.cpp index 426ecaba6..1f88547f8 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_nearbyintf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_nearbyintf.cpp @@ -2,18 +2,18 @@ /* s_rintf.c -- Simple version of s_rint.c. * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* Adapted for use as nearbyint by Ulrich Drepper . */ + /* Adapted for use as nearbyint by Ulrich Drepper . */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #include "../streflop_libm_bridge.h" @@ -22,59 +22,59 @@ namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -TWO23[2]={ - 8.3886080000e+06f, /* 0x4b000000 */ - -8.3886080000e+06f, /* 0xcb000000 */ -}; + TWO23[2] = { + 8.3886080000e+06f, /* 0x4b000000 */ + -8.3886080000e+06f, /* 0xcb000000 */ + }; #ifdef __STDC__ Simple __nearbyintf(Simple x) #else Simple __nearbyintf(x) - Simple x; + Simple x; #endif -{ - fenv_t env; - int32_t i0,j0,sx; - u_int32_t i,i1; - Simple w,t; - GET_FLOAT_WORD(i0,x); - sx = (i0>>31)&1; - j0 = ((i0>>23)&0xff)-0x7f; - if(j0<23) { - if(j0<0) { - if((i0&0x7fffffff)==0) return x; - i1 = (i0&0x07fffff); - i0 &= 0xfff00000; - i0 |= ((i1|-i1)>>9)&0x400000; - SET_FLOAT_WORD(x,i0); - feholdexcept (&env); - w = TWO23[sx]+x; - t = w-TWO23[sx]; - fesetenv (&env); - GET_FLOAT_WORD(i0,t); - SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); - return t; - } else { - i = (0x007fffff)>>j0; - if((i0&i)==0) return x; /* x is integral */ - i>>=1; - if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0); - } - } else { - if(j0==0x80) return x+x; /* inf or NaN */ - else return x; /* x is integral */ + { + fenv_t env; + int32_t i0, j0, sx; + u_int32_t i, i1; + Simple w, t; + GET_FLOAT_WORD(i0, x); + sx = (i0 >> 31) & 1; + j0 = ((i0 >> 23) & 0xff) - 0x7f; + if (j0 < 23) { + if (j0 < 0) { + if ((i0 & 0x7fffffff) == 0) return x; + i1 = (i0 & 0x07fffff); + i0 &= 0xfff00000; + i0 |= ((i1 | -i1) >> 9) & 0x400000; + SET_FLOAT_WORD(x, i0); + feholdexcept(&env); + w = TWO23[sx] + x; + t = w - TWO23[sx]; + fesetenv(&env); + GET_FLOAT_WORD(i0, t); + SET_FLOAT_WORD(t, (i0 & 0x7fffffff) | (sx << 31)); + return t; + } else { + i = (0x007fffff) >> j0; + if ((i0&i) == 0) return x; /* x is integral */ + i >>= 1; + if ((i0&i) != 0) i0 = (i0&(~i)) | ((0x100000) >> j0); + } + } else { + if (j0 == 0x80) return x + x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x, i0); + feholdexcept(&env); + w = TWO23[sx] + x; + t = w - TWO23[sx]; + fesetenv(&env); + return t; } - SET_FLOAT_WORD(x,i0); - feholdexcept (&env); - w = TWO23[sx]+x; - t = w-TWO23[sx]; - fesetenv (&env); - return t; -} -weak_alias (__nearbyintf, nearbyintf) + weak_alias(__nearbyintf, nearbyintf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_nextafterf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_nextafterf.cpp index 96d47e780..1ca2153ea 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_nextafterf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_nextafterf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_nextafterf.c,v 1.4f 1995/05/10 20:48:01 jtc Exp $"; @@ -26,57 +26,57 @@ namespace streflop_libm { #ifdef __STDC__ Simple __nextafterf(Simple x, Simple y) #else - Simple __nextafterf(x,y) - Simple x,y; + Simple __nextafterf(x, y) + Simple x, y; #endif -{ - int32_t hx,hy,ix,iy; + { + int32_t hx, hy, ix, iy; - GET_FLOAT_WORD(hx,x); - GET_FLOAT_WORD(hy,y); - ix = hx&0x7fffffff; /* |x| */ - iy = hy&0x7fffffff; /* |y| */ + GET_FLOAT_WORD(hx, x); + GET_FLOAT_WORD(hy, y); + ix = hx & 0x7fffffff; /* |x| */ + iy = hy & 0x7fffffff; /* |y| */ - if((ix>0x7f800000) || /* x is nan */ - (iy>0x7f800000)) /* y is nan */ - return x+y; - if(x==y) return y; /* x=y, return y */ - if(ix==0) { /* x == 0 */ - SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */ - y = x*x; - if(y==x) return y; else return x; /* raise underflow flag */ - } - if(hx>=0) { /* x > 0 */ - if(hx>hy) { /* x > y, x -= ulp */ - hx -= 1; - } else { /* x < y, x += ulp */ - hx += 1; - } - } else { /* x < 0 */ - if(hy>=0||hx>hy){ /* x < y, x -= ulp */ - hx -= 1; - } else { /* x > y, x += ulp */ - hx += 1; - } - } - hy = hx&0x7f800000; - if(hy>=0x7f800000) { - x = x+x; /* overflow */ + if ((ix > 0x7f800000) || /* x is nan */ + (iy > 0x7f800000)) /* y is nan */ + return x + y; + if (x == y) return y; /* x=y, return y */ + if (ix == 0) { /* x == 0 */ + SET_FLOAT_WORD(x, (hy & 0x80000000) | 1);/* return +-minsubnormal */ + y = x*x; + if (y == x) return y; else return x; /* raise underflow flag */ + } + if (hx >= 0) { /* x > 0 */ + if (hx > hy) { /* x > y, x -= ulp */ + hx -= 1; + } else { /* x < y, x += ulp */ + hx += 1; + } + } else { /* x < 0 */ + if (hy >= 0 || hx > hy) { /* x < y, x -= ulp */ + hx -= 1; + } else { /* x > y, x += ulp */ + hx += 1; + } + } + hy = hx & 0x7f800000; + if (hy >= 0x7f800000) { + x = x + x; /* overflow */ #if FLT_EVAL_METHOD != 0 - if (FLT_EVAL_METHOD != 0) - asm ("" : "=m"(x) : "m"(x)); + if (FLT_EVAL_METHOD != 0) + asm("" : "=m"(x) : "m"(x)); #endif - return x; /* overflow */ + return x; /* overflow */ + } + if (hy < 0x00800000) { /* underflow */ + y = x*x; + if (y != x) { /* raise underflow flag */ + SET_FLOAT_WORD(y, hx); + return y; + } + } + SET_FLOAT_WORD(x, hx); + return x; } - if(hy<0x00800000) { /* underflow */ - y = x*x; - if(y!=x) { /* raise underflow flag */ - SET_FLOAT_WORD(y,hx); - return y; - } - } - SET_FLOAT_WORD(x,hx); - return x; -} -weak_alias (__nextafterf, nextafterf) + weak_alias(__nextafterf, nextafterf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_remquof.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_remquof.cpp index 448421035..e3c9bf3eb 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_remquof.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_remquof.cpp @@ -28,84 +28,73 @@ static const Simple zero = 0.0f; namespace streflop_libm { -Simple -__remquof (Simple x, Simple y, int *quo) -{ - int32_t hx,hy; - u_int32_t sx; - int cquo, qs; + Simple + __remquof(Simple x, Simple y, int *quo) { + int32_t hx, hy; + u_int32_t sx; + int cquo, qs; - GET_FLOAT_WORD (hx, x); - GET_FLOAT_WORD (hy, y); - sx = hx & 0x80000000; - qs = sx ^ (hy & 0x80000000); - hy &= 0x7fffffff; - hx &= 0x7fffffff; + GET_FLOAT_WORD(hx, x); + GET_FLOAT_WORD(hy, y); + sx = hx & 0x80000000; + qs = sx ^ (hy & 0x80000000); + hy &= 0x7fffffff; + hx &= 0x7fffffff; - /* Purge off exception values. */ - if (hy == 0) - return (x * y) / (x * y); /* y = 0 */ - if ((hx >= 0x7f800000) /* x not finite */ - || (hy > 0x7f800000)) /* y is NaN */ - return (x * y) / (x * y); + /* Purge off exception values. */ + if (hy == 0) + return (x * y) / (x * y); /* y = 0 */ + if ((hx >= 0x7f800000) /* x not finite */ + || (hy > 0x7f800000)) /* y is NaN */ + return (x * y) / (x * y); - if (hy <= 0x7dffffff) - x = __ieee754_fmodf (x, 8 * y); /* now x < 8y */ + if (hy <= 0x7dffffff) + x = __ieee754_fmodf(x, 8 * y); /* now x < 8y */ - if ((hx - hy) == 0) - { - *quo = qs ? -1 : 1; - return zero * x; - } + if ((hx - hy) == 0) { + *quo = qs ? -1 : 1; + return zero * x; + } - x = fabsf (x); - y = fabsf (y); - cquo = 0; + x = fabsf(x); + y = fabsf(y); + cquo = 0; - if (x >= 4 * y) - { - x -= 4 * y; - cquo += 4; - } - if (x >= 2 * y) - { - x -= 2 * y; - cquo += 2; - } + if (x >= 4 * y) { + x -= 4 * y; + cquo += 4; + } + if (x >= 2 * y) { + x -= 2 * y; + cquo += 2; + } - if (hy < 0x01000000) - { - if (x + x > y) - { - x -= y; - ++cquo; - if (x + x >= y) - { - x -= y; - ++cquo; - } + if (hy < 0x01000000) { + if (x + x > y) { + x -= y; + ++cquo; + if (x + x >= y) { + x -= y; + ++cquo; + } + } + } else { + Simple y_half = 0.5f * y; + if (x > y_half) { + x -= y; + ++cquo; + if (x >= y_half) { + x -= y; + ++cquo; + } + } + } + + *quo = qs ? -cquo : cquo; + + if (sx) + x = -x; + return x; } - } - else - { - Simple y_half = 0.5f * y; - if (x > y_half) - { - x -= y; - ++cquo; - if (x >= y_half) - { - x -= y; - ++cquo; - } - } - } - - *quo = qs ? -cquo : cquo; - - if (sx) - x = -x; - return x; -} -weak_alias (__remquof, remquof) + weak_alias(__remquof, remquof) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_rintf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_rintf.cpp index dcd98e158..63e94471e 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_rintf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_rintf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_rintf.c,v 1.4f 1995/05/10 20:48:06 jtc Exp $"; @@ -23,53 +23,53 @@ static char rcsid[] = "$NetBSD: s_rintf.c,v 1.4f 1995/05/10 20:48:06 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -TWO23[2]={ - 8.3886080000e+06f, /* 0x4b000000 */ - -8.3886080000e+06f, /* 0xcb000000 */ -}; + TWO23[2] = { + 8.3886080000e+06f, /* 0x4b000000 */ + -8.3886080000e+06f, /* 0xcb000000 */ + }; #ifdef __STDC__ Simple __rintf(Simple x) #else Simple __rintf(x) - Simple x; + Simple x; #endif -{ - int32_t i0,j0,sx; - u_int32_t i,i1; - Simple w,t; - GET_FLOAT_WORD(i0,x); - sx = (i0>>31)&1; - j0 = ((i0>>23)&0xff)-0x7f; - if(j0<23) { - if(j0<0) { - if((i0&0x7fffffff)==0) return x; - i1 = (i0&0x07fffff); - i0 &= 0xfff00000; - i0 |= ((i1|-i1)>>9)&0x400000; - SET_FLOAT_WORD(x,i0); - w = TWO23[sx]+x; - t = w-TWO23[sx]; - GET_FLOAT_WORD(i0,t); - SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); - return t; - } else { - i = (0x007fffff)>>j0; - if((i0&i)==0) return x; /* x is integral */ - i>>=1; - if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0); - } - } else { - if(j0==0x80) return x+x; /* inf or NaN */ - else return x; /* x is integral */ + { + int32_t i0, j0, sx; + u_int32_t i, i1; + Simple w, t; + GET_FLOAT_WORD(i0, x); + sx = (i0 >> 31) & 1; + j0 = ((i0 >> 23) & 0xff) - 0x7f; + if (j0 < 23) { + if (j0 < 0) { + if ((i0 & 0x7fffffff) == 0) return x; + i1 = (i0 & 0x07fffff); + i0 &= 0xfff00000; + i0 |= ((i1 | -i1) >> 9) & 0x400000; + SET_FLOAT_WORD(x, i0); + w = TWO23[sx] + x; + t = w - TWO23[sx]; + GET_FLOAT_WORD(i0, t); + SET_FLOAT_WORD(t, (i0 & 0x7fffffff) | (sx << 31)); + return t; + } else { + i = (0x007fffff) >> j0; + if ((i0&i) == 0) return x; /* x is integral */ + i >>= 1; + if ((i0&i) != 0) i0 = (i0&(~i)) | ((0x100000) >> j0); + } + } else { + if (j0 == 0x80) return x + x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x, i0); + w = TWO23[sx] + x; + return w - TWO23[sx]; } - SET_FLOAT_WORD(x,i0); - w = TWO23[sx]+x; - return w-TWO23[sx]; -} -weak_alias (__rintf, rintf) + weak_alias(__rintf, rintf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_roundf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_roundf.cpp index 159d69f1b..6f3dbdd4f 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_roundf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_roundf.cpp @@ -28,49 +28,40 @@ static const Simple huge = 1.0e30f; namespace streflop_libm { -Simple -__roundf (Simple x) -{ - int32_t i0, j0; + Simple + __roundf(Simple x) { + int32_t i0, j0; - GET_FLOAT_WORD (i0, x); - j0 = ((i0 >> 23) & 0xff) - 0x7f; - if (j0 < 23) - { - if (j0 < 0) - { - if (huge + x > 0.0f) - { - i0 &= 0x80000000; - if (j0 == -1) - i0 |= 0x3f800000; - } - } - else - { - u_int32_t i = 0x007fffff >> j0; - if ((i0 & i) == 0) - /* X is integral. */ - return x; - if (huge + x > 0.0f) - { - /* Raise inexact if x != 0. */ - i0 += 0x00400000 >> j0; - i0 &= ~i; - } - } - } - else - { - if (j0 == 0x80) - /* Inf or NaN. */ - return x + x; - else - return x; - } + GET_FLOAT_WORD(i0, x); + j0 = ((i0 >> 23) & 0xff) - 0x7f; + if (j0 < 23) { + if (j0 < 0) { + if (huge + x > 0.0f) { + i0 &= 0x80000000; + if (j0 == -1) + i0 |= 0x3f800000; + } + } else { + u_int32_t i = 0x007fffff >> j0; + if ((i0 & i) == 0) + /* X is integral. */ + return x; + if (huge + x > 0.0f) { + /* Raise inexact if x != 0. */ + i0 += 0x00400000 >> j0; + i0 &= ~i; + } + } + } else { + if (j0 == 0x80) + /* Inf or NaN. */ + return x + x; + else + return x; + } - SET_FLOAT_WORD (x, i0); - return x; -} -weak_alias (__roundf, roundf) + SET_FLOAT_WORD(x, i0); + return x; + } + weak_alias(__roundf, roundf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_scalblnf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_scalblnf.cpp index 22d37d227..75dda507f 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_scalblnf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_scalblnf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_scalbnf.c,v 1.4f 1995/05/10 20:48:10 jtc Exp $"; @@ -23,44 +23,46 @@ static char rcsid[] = "$NetBSD: s_scalbnf.c,v 1.4f 1995/05/10 20:48:10 jtc Exp $ namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -two25 = 3.355443200e+07f, /* 0x4c000000 */ -twom25 = 2.9802322388e-08f, /* 0x33000000 */ -huge = 1.0e+30f, -tiny = 1.0e-30f; + two25 = 3.355443200e+07f, /* 0x4c000000 */ + twom25 = 2.9802322388e-08f, /* 0x33000000 */ + huge = 1.0e+30f, + tiny = 1.0e-30f; #ifdef __STDC__ - Simple __scalblnf (Simple x, long int n) + Simple __scalblnf(Simple x, long int n) #else - Simple __scalblnf (x,n) - Simple x; long int n; + Simple __scalblnf(x, n) + Simple x; long int n; #endif -{ - int32_t k,ix; - GET_FLOAT_WORD(ix,x); - k = (ix&0x7f800000)>>23; /* extract exponent */ - if (k==0) { /* 0 or subnormal x */ - if ((ix&0x7fffffff)==0) return x; /* +-0 */ - x *= two25; - GET_FLOAT_WORD(ix,x); - k = ((ix&0x7f800000)>>23) - 25; - } - if (k==0xff) return x+x; /* NaN or Inf */ - k = k+n; - if (n> 50000 || k > 0xfe) - return huge*copysignf(huge,x); /* overflow */ - if (n< -50000) - return tiny*copysignf(tiny,x); /*underflow*/ - if (k > 0) /* normal result */ - {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;} - if (k <= -25) - return tiny*copysignf(tiny,x); /*underflow*/ - k += 25; /* subnormal result */ - SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); - return x*twom25; -} -weak_alias (__scalblnf, scalblnf) + { + int32_t k, ix; + GET_FLOAT_WORD(ix, x); + k = (ix & 0x7f800000) >> 23; /* extract exponent */ + if (k == 0) { /* 0 or subnormal x */ + if ((ix & 0x7fffffff) == 0) return x; /* +-0 */ + x *= two25; + GET_FLOAT_WORD(ix, x); + k = ((ix & 0x7f800000) >> 23) - 25; + } + if (k == 0xff) return x + x; /* NaN or Inf */ + k = k + n; + if (n > 50000 || k > 0xfe) + return huge*copysignf(huge, x); /* overflow */ + if (n < -50000) + return tiny*copysignf(tiny, x); /*underflow*/ + if (k > 0) /* normal result */ + { + SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23)); return x; + } + if (k <= -25) + return tiny*copysignf(tiny, x); /*underflow*/ + k += 25; /* subnormal result */ + SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23)); + return x*twom25; + } + weak_alias(__scalblnf, scalblnf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_scalbnf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_scalbnf.cpp index fd4d3efa7..52d236e0b 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_scalbnf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_scalbnf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_scalbnf.c,v 1.4f 1995/05/10 20:48:10 jtc Exp $"; @@ -23,44 +23,46 @@ static char rcsid[] = "$NetBSD: s_scalbnf.c,v 1.4f 1995/05/10 20:48:10 jtc Exp $ namespace streflop_libm { #ifdef __STDC__ -static const Simple + static const Simple #else -static Simple + static Simple #endif -two25 = 3.355443200e+07f, /* 0x4c000000 */ -twom25 = 2.9802322388e-08f, /* 0x33000000 */ -huge = 1.0e+30f, -tiny = 1.0e-30f; + two25 = 3.355443200e+07f, /* 0x4c000000 */ + twom25 = 2.9802322388e-08f, /* 0x33000000 */ + huge = 1.0e+30f, + tiny = 1.0e-30f; #ifdef __STDC__ - Simple __scalbnf (Simple x, int n) + Simple __scalbnf(Simple x, int n) #else - Simple __scalbnf (x,n) - Simple x; int n; + Simple __scalbnf(x, n) + Simple x; int n; #endif -{ - int32_t k,ix; - GET_FLOAT_WORD(ix,x); - k = (ix&0x7f800000)>>23; /* extract exponent */ - if (k==0) { /* 0 or subnormal x */ - if ((ix&0x7fffffff)==0) return x; /* +-0 */ - x *= two25; - GET_FLOAT_WORD(ix,x); - k = ((ix&0x7f800000)>>23) - 25; - } - if (k==0xff) return x+x; /* NaN or Inf */ - k = k+n; - if (n> 50000 || k > 0xfe) - return huge*__copysignf(huge,x); /* overflow */ - if (n< -50000) - return tiny*__copysignf(tiny,x); /*underflow*/ - if (k > 0) /* normal result */ - {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;} - if (k <= -25) - return tiny*__copysignf(tiny,x); /*underflow*/ - k += 25; /* subnormal result */ - SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); - return x*twom25; -} -weak_alias (__scalbnf, scalbnf) + { + int32_t k, ix; + GET_FLOAT_WORD(ix, x); + k = (ix & 0x7f800000) >> 23; /* extract exponent */ + if (k == 0) { /* 0 or subnormal x */ + if ((ix & 0x7fffffff) == 0) return x; /* +-0 */ + x *= two25; + GET_FLOAT_WORD(ix, x); + k = ((ix & 0x7f800000) >> 23) - 25; + } + if (k == 0xff) return x + x; /* NaN or Inf */ + k = k + n; + if (n > 50000 || k > 0xfe) + return huge*__copysignf(huge, x); /* overflow */ + if (n < -50000) + return tiny*__copysignf(tiny, x); /*underflow*/ + if (k > 0) /* normal result */ + { + SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23)); return x; + } + if (k <= -25) + return tiny*__copysignf(tiny, x); /*underflow*/ + k += 25; /* subnormal result */ + SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23)); + return x*twom25; + } + weak_alias(__scalbnf, scalbnf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_signbitf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_signbitf.cpp index f2cbd901e..c1e0efc7c 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_signbitf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_signbitf.cpp @@ -24,12 +24,11 @@ #include "math_private.h" namespace streflop_libm { -int -__signbitf (Simple x) -{ - int32_t hx; + int + __signbitf(Simple x) { + int32_t hx; - GET_FLOAT_WORD (hx, x); - return hx & 0x80000000; -} + GET_FLOAT_WORD(hx, x); + return hx & 0x80000000; + } } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_sincosf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_sincosf.cpp index 02e78f7de..bfdd8b7c4 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_sincosf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_sincosf.cpp @@ -25,53 +25,46 @@ namespace streflop_libm { -void -__sincosf (Simple x, Simple *sinx, Simple *cosx) -{ - int32_t ix; + void + __sincosf(Simple x, Simple *sinx, Simple *cosx) { + int32_t ix; - /* High word of x. */ - GET_FLOAT_WORD (ix, x); + /* High word of x. */ + GET_FLOAT_WORD(ix, x); - /* |x| ~< pi/4 */ - ix &= 0x7fffffff; - if (ix <= 0x3f490fd8) - { - *sinx = __kernel_sinf (x, 0.0f, 0); - *cosx = __kernel_cosf (x, 0.0f); - } - else if (ix>=0x7f800000) - { - /* sin(Inf or NaN) is NaN */ - *sinx = *cosx = x - x; - } - else - { - /* Argument reduction needed. */ - Simple y[2]; - int n; + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if (ix <= 0x3f490fd8) { + *sinx = __kernel_sinf(x, 0.0f, 0); + *cosx = __kernel_cosf(x, 0.0f); + } else if (ix >= 0x7f800000) { + /* sin(Inf or NaN) is NaN */ + *sinx = *cosx = x - x; + } else { + /* Argument reduction needed. */ + Simple y[2]; + int n; - n = __ieee754_rem_pio2f (x, y); - switch (n & 3) - { - case 0: - *sinx = __kernel_sinf (y[0], y[1], 1); - *cosx = __kernel_cosf (y[0], y[1]); - break; - case 1: - *sinx = __kernel_cosf (y[0], y[1]); - *cosx = -__kernel_sinf (y[0], y[1], 1); - break; - case 2: - *sinx = -__kernel_sinf (y[0], y[1], 1); - *cosx = -__kernel_cosf (y[0], y[1]); - break; - default: - *sinx = -__kernel_cosf (y[0], y[1]); - *cosx = __kernel_sinf (y[0], y[1], 1); - break; + n = __ieee754_rem_pio2f(x, y); + switch (n & 3) { + case 0: + *sinx = __kernel_sinf(y[0], y[1], 1); + *cosx = __kernel_cosf(y[0], y[1]); + break; + case 1: + *sinx = __kernel_cosf(y[0], y[1]); + *cosx = -__kernel_sinf(y[0], y[1], 1); + break; + case 2: + *sinx = -__kernel_sinf(y[0], y[1], 1); + *cosx = -__kernel_cosf(y[0], y[1]); + break; + default: + *sinx = -__kernel_cosf(y[0], y[1]); + *cosx = __kernel_sinf(y[0], y[1], 1); + break; + } + } } - } -} -weak_alias (__sincosf, sincosf) + weak_alias(__sincosf, sincosf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_sinf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_sinf.cpp index 1fdf78369..42436d6da 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_sinf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_sinf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_sinf.c,v 1.4f 1995/05/10 20:48:16 jtc Exp $"; @@ -26,32 +26,32 @@ namespace streflop_libm { Simple __sinf(Simple x) #else Simple __sinf(x) - Simple x; + Simple x; #endif -{ - Simple y[2],z=0.0f; - int32_t n, ix; + { + Simple y[2], z = 0.0f; + int32_t n, ix; - GET_FLOAT_WORD(ix,x); + GET_FLOAT_WORD(ix, x); - /* |x| ~< pi/4 */ - ix &= 0x7fffffff; - if(ix <= 0x3f490fd8) return __kernel_sinf(x,z,0); + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if (ix <= 0x3f490fd8) return __kernel_sinf(x, z, 0); - /* sin(Inf or NaN) is NaN */ - else if (ix>=0x7f800000) return x-x; + /* sin(Inf or NaN) is NaN */ + else if (ix >= 0x7f800000) return x - x; - /* argument reduction needed */ - else { - n = __ieee754_rem_pio2f(x,y); - switch(n&3) { - case 0: return __kernel_sinf(y[0],y[1],1); - case 1: return __kernel_cosf(y[0],y[1]); - case 2: return -__kernel_sinf(y[0],y[1],1); - default: - return -__kernel_cosf(y[0],y[1]); - } + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2f(x, y); + switch (n & 3) { + case 0: return __kernel_sinf(y[0], y[1], 1); + case 1: return __kernel_cosf(y[0], y[1]); + case 2: return -__kernel_sinf(y[0], y[1], 1); + default: + return -__kernel_cosf(y[0], y[1]); + } + } } -} -weak_alias (__sinf, sinf) + weak_alias(__sinf, sinf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_tanf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_tanf.cpp index 6de3015cd..5014aafda 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_tanf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_tanf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_tanf.c,v 1.4f 1995/05/10 20:48:20 jtc Exp $"; @@ -26,27 +26,27 @@ namespace streflop_libm { Simple __tanf(Simple x) #else Simple __tanf(x) - Simple x; + Simple x; #endif -{ - Simple y[2],z=0.0f; - int32_t n, ix; + { + Simple y[2], z = 0.0f; + int32_t n, ix; - GET_FLOAT_WORD(ix,x); + GET_FLOAT_WORD(ix, x); - /* |x| ~< pi/4 */ - ix &= 0x7fffffff; - if(ix <= 0x3f490fda) return __kernel_tanf(x,z,1); + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if (ix <= 0x3f490fda) return __kernel_tanf(x, z, 1); - /* tan(Inf or NaN) is NaN */ - else if (ix>=0x7f800000) return x-x; /* NaN */ + /* tan(Inf or NaN) is NaN */ + else if (ix >= 0x7f800000) return x - x; /* NaN */ - /* argument reduction needed */ - else { - n = __ieee754_rem_pio2f(x,y); - return __kernel_tanf(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even - -1 -- n odd */ + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2f(x, y); + return __kernel_tanf(y[0], y[1], 1 - ((n & 1) << 1)); /* 1 -- n even + -1 -- n odd */ + } } -} -weak_alias (__tanf, tanf) + weak_alias(__tanf, tanf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_tanhf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_tanhf.cpp index 8000ea01e..05d628a1d 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_tanhf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_tanhf.cpp @@ -3,16 +3,16 @@ * Conversion to Simple by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ + /* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ #if defined(LIBM_SCCS) && !defined(lint) static char rcsid[] = "$NetBSD: s_tanhf.c,v 1.4f 1995/05/10 20:48:24 jtc Exp $"; @@ -23,48 +23,48 @@ static char rcsid[] = "$NetBSD: s_tanhf.c,v 1.4f 1995/05/10 20:48:24 jtc Exp $"; namespace streflop_libm { #ifdef __STDC__ -static const Simple one=1.0f, two=2.0f, tiny = 1.0e-30f; + static const Simple one = 1.0f, two = 2.0f, tiny = 1.0e-30f; #else -static Simple one=1.0f, two=2.0f, tiny = 1.0e-30f; + static Simple one = 1.0f, two = 2.0f, tiny = 1.0e-30f; #endif #ifdef __STDC__ Simple __tanhf(Simple x) #else Simple __tanhf(x) - Simple x; + Simple x; #endif -{ - Simple t,z; - int32_t jx,ix; + { + Simple t, z; + int32_t jx, ix; - GET_FLOAT_WORD(jx,x); - ix = jx&0x7fffffff; + GET_FLOAT_WORD(jx, x); + ix = jx & 0x7fffffff; - /* x is INF or NaN */ - if(ix>=0x7f800000) { - if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */ - else return one/x-one; /* tanh(NaN) = NaN */ + /* x is INF or NaN */ + if (ix >= 0x7f800000) { + if (jx >= 0) return one / x + one; /* tanh(+-inf)=+-1 */ + else return one / x - one; /* tanh(NaN) = NaN */ + } + + /* |x| < 22 */ + if (ix < 0x41b00000) { /* |x|<22 */ + if (ix == 0) + return x; /* x == +-0 */ + if (ix < 0x24000000) /* |x|<2**-55 */ + return x*(one + x); /* tanh(small) = small */ + if (ix >= 0x3f800000) { /* |x|>=1 */ + t = __expm1f(two*fabsf(x)); + z = one - two / (t + two); + } else { + t = __expm1f(-two*fabsf(x)); + z = -t / (t + two); + } + /* |x| > 22, return +-1 */ + } else { + z = one - tiny; /* raised inexact flag */ + } + return (jx >= 0) ? z : -z; } - - /* |x| < 22 */ - if (ix < 0x41b00000) { /* |x|<22 */ - if (ix == 0) - return x; /* x == +-0 */ - if (ix<0x24000000) /* |x|<2**-55 */ - return x*(one+x); /* tanh(small) = small */ - if (ix>=0x3f800000) { /* |x|>=1 */ - t = __expm1f(two*fabsf(x)); - z = one - two/(t+two); - } else { - t = __expm1f(-two*fabsf(x)); - z= -t/(t+two); - } - /* |x| > 22, return +-1 */ - } else { - z = one - tiny; /* raised inexact flag */ - } - return (jx>=0)? z: -z; -} -weak_alias (__tanhf, tanhf) + weak_alias(__tanhf, tanhf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/s_truncf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/s_truncf.cpp index 97aa01f5c..94598c8bf 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/s_truncf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/s_truncf.cpp @@ -25,31 +25,27 @@ namespace streflop_libm { -Simple -__truncf (Simple x) -{ - int32_t i0, j0; - int sx; + Simple + __truncf(Simple x) { + int32_t i0, j0; + int sx; - GET_FLOAT_WORD (i0, x); - sx = i0 & 0x80000000; - j0 = ((i0 >> 23) & 0xff) - 0x7f; - if (j0 < 23) - { - if (j0 < 0) - /* The magnitude of the number is < 1 so the result is +-0. */ - SET_FLOAT_WORD (x, sx); - else - SET_FLOAT_WORD (x, sx | (i0 & ~(0x007fffff >> j0))); - } - else - { - if (j0 == 0x80) - /* x is inf or NaN. */ - return x + x; - } + GET_FLOAT_WORD(i0, x); + sx = i0 & 0x80000000; + j0 = ((i0 >> 23) & 0xff) - 0x7f; + if (j0 < 23) { + if (j0 < 0) + /* The magnitude of the number is < 1 so the result is +-0. */ + SET_FLOAT_WORD(x, sx); + else + SET_FLOAT_WORD(x, sx | (i0 & ~(0x007fffff >> j0))); + } else { + if (j0 == 0x80) + /* x is inf or NaN. */ + return x + x; + } - return x; -} -weak_alias (__truncf, truncf) + return x; + } + weak_alias(__truncf, truncf) } diff --git a/source/shared_lib/sources/streflop/libm/flt-32/w_expf.cpp b/source/shared_lib/sources/streflop/libm/flt-32/w_expf.cpp index f0045cd79..e73ca3dad 100644 --- a/source/shared_lib/sources/streflop/libm/flt-32/w_expf.cpp +++ b/source/shared_lib/sources/streflop/libm/flt-32/w_expf.cpp @@ -26,7 +26,7 @@ #include "math_private.h" namespace streflop_libm { -Simple __expf(Simple x) { - return __ieee754_expf(x); -} + Simple __expf(Simple x) { + return __ieee754_expf(x); + } } diff --git a/source/shared_lib/sources/util/checksum.cpp b/source/shared_lib/sources/util/checksum.cpp index 788c47c1f..9b7b4f974 100644 --- a/source/shared_lib/sources/util/checksum.cpp +++ b/source/shared_lib/sources/util/checksum.cpp @@ -16,7 +16,7 @@ #include // for open() #ifdef WIN32 - #include // for open() +#include // for open() #endif #include // for open() @@ -31,402 +31,400 @@ using namespace std; using namespace Shared::PlatformCommon; using namespace Shared::Util; -namespace Shared{ namespace Util{ +namespace Shared { + namespace Util { -// ===================================================== -// class Checksum -// ===================================================== + // ===================================================== + // class Checksum + // ===================================================== -Mutex Checksum::fileListCacheSynchAccessor; -std::map Checksum::fileListCache; - -unsigned int crc_table[256] = -{ - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - -Checksum::Checksum() { - sum= 0; - r= 55665; - c1= 52845; - c2= 22719; -} - -uint32 Checksum::addByte(const char value) { -// int32 cipher= (value ^ (r >> 8)); -// -// r= (cipher + r) * c1 + c2; -// sum += cipher; -// -// return cipher; - - const unsigned char *rVal = reinterpret_cast(&value); - sum = ~sum; - sum = (sum >> 8) ^ crc_table[*rVal ^ (sum & 0xff)]; - sum = ~sum; - - return sum; -} - -uint32 Checksum::addBytes(const void *_data, size_t _size) { - const unsigned char *rVal = reinterpret_cast(_data); - sum = ~sum; - while (_size--) { - sum = (sum >> 8) ^ crc_table[*rVal++ ^ (sum & 0xff)]; - } - sum = ~sum; - - return sum; -} - - -void Checksum::addSum(uint32 value) { - sum += value; -} - -uint32 Checksum::addInt(const int32 &value) { - int8 byte = (value >> 0) & 0xFF; - addByte(byte); - byte = (value >> 8) & 0xFF; - addByte(byte); - byte = (value >> 16) & 0xFF; - addByte(byte); - byte = (value >> 24) & 0xFF; - addByte(byte); - - return sum; -} - -uint32 Checksum::addUInt(const uint32 &value) { - int8 byte = (value >> 0) & 0xFF; - addByte(byte); - byte = (value >> 8) & 0xFF; - addByte(byte); - byte = (value >> 16) & 0xFF; - addByte(byte); - byte = (value >> 24) & 0xFF; - addByte(byte); - - return sum; -} - -uint32 Checksum::addInt64(const int64 &value) { - int8 byte = (value >> 0) & 0xFF; - addByte(byte); - byte = (value >> 8) & 0xFF; - addByte(byte); - byte = (value >> 16) & 0xFF; - addByte(byte); - byte = (value >> 24) & 0xFF; - addByte(byte); - byte = (value >> 32) & 0xFF; - addByte(byte); - byte = (value >> 40) & 0xFF; - addByte(byte); - byte = (value >> 48) & 0xFF; - addByte(byte); - byte = (value >> 56) & 0xFF; - addByte(byte); - - return sum; -} - -void Checksum::addString(const string &value) { - for(unsigned int i = 0; i < value.size(); ++i) { - addByte(value[i]); - } -} - -void Checksum::addFile(const string &path) { - if(path != "") { - fileList[path] = 0; - } -} - -bool Checksum::addFileToSum(const string &path) { - -// OLD SLOW FILE I/O -/* - FILE* file= fopen(path.c_str(), "rb"); - if(file!=NULL){ - - addString(lastFile(path)); - - while(!feof(file)){ - int8 byte= 0; - - size_t readBytes = fread(&byte, 1, 1, file); - addByte(byte); - } - } - else - { - throw megaglest_runtime_error("Can not open file: " + path); - } - fclose(file); -*/ - - - -/* - const double MAX_CRC_FILESIZE = 100000000; - int fd=0; - size_t bytes_read, bytes_expected = MAX_CRC_FILESIZE * sizeof(int8); - int8 *data=0; - const char *infile = path.c_str(); - - if ((fd = open(infile,O_RDONLY)) < 0) - throw megaglest_runtime_error("Can not open file: " + path); - - if ((data = (int8 *)malloc(bytes_expected)) == NULL) - throw megaglest_runtime_error("malloc failed, Can not open file: " + path); - - bytes_read = read(fd, data, bytes_expected); - - //if (bytes_read != bytes_expected) - // throw megaglest_runtime_error("read failed, Can not open file: " + path); - - for(int i = 0; i < bytes_read; i++) { - addByte(data[i]); - } - free(data); -*/ - - bool fileExists = false; - -/* -#ifdef WIN32 - FILE* file= _wfopen(utf8_decode(path).c_str(), L"rb"); -#else - FILE* file= fopen(path.c_str(), "rb"); -#endif - if(file != NULL) { - fileExists = true; - addString(lastFile(path)); - - bool isXMLFile = (EndsWith(path, ".xml") == true); - bool inCommentTag=false; - char buf[4096]=""; // Should be large enough. - int bufSize = sizeof buf; - while(!feof(file)) { - //int8 byte= 0; - - //size_t readBytes = fread(&byte, 1, 1, file); - memset(buf,0,bufSize); - if(fgets(buf, bufSize, file) != NULL) { - //addByte(byte); - for(int i = 0; i < bufSize && buf[i] != 0; i++) { - // Ignore Spaces in XML files as they are - // ONLY for formatting - if(isXMLFile == true) { - if(inCommentTag == true) { - if(buf[i] == '>' && i >= 3 && buf[i-1] == '-' && buf[i-2] == '-') { - inCommentTag = false; - //printf("TURNING OFF comment TAG, i = %d [%c]",i,buf[i]); - } - else { - //printf("SKIPPING XML comment character, i = %d [%c]",i,buf[i]); - } - continue; - } - //else if(buf[i] == '-' && i >= 4 && buf[i-1] == '-' && buf[i-2] == '!' && buf[i-3] == '<') { - else if(buf[i] == '<' && i+4 < bufSize && buf[i+1] == '!' && buf[i+2] == '-' && buf[i+3] == '-') { - inCommentTag = true; - //printf("TURNING ON comment TAG, i = %d [%c]",i,buf[i]); - continue; - } - else if(buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n' || buf[i] == '\r') { - //printf("SKIPPING special character, i = %d [%c]",i,buf[i]); - continue; - } - } - addByte(buf[i]); - } - } - } - } - else { - throw megaglest_runtime_error("Can not open file: " + path); - } - fclose(file); -*/ - -#if defined(WIN32) && !defined(__MINGW32__) - wstring wstr = utf8_decode(path); - FILE *fp = _wfopen(wstr.c_str(), L"rb"); - ifstream ifs(fp); -#else - ifstream ifs(path.c_str()); -#endif - - if (ifs) { - fileExists = true; - addString(lastFile(path)); - - bool isXMLFile = (EndsWith(path, ".xml") == true); - - // Determine the file length - ifs.seekg(0, ios::end); - std::streamoff size=ifs.tellg(); - ifs.seekg(0, ios::beg); - - unsigned int bufSize = (unsigned int)size / sizeof(char); - // Create a vector to store the data - std::vector buf(bufSize); - // Load the data - ifs.read((char*)&buf[0], buf.size()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] buf.size() = %d, path [%s], isXMLFile = %d\n",__FILE__,__FUNCTION__,__LINE__,buf.size(), path.c_str(),isXMLFile); - - if(isXMLFile == true) { - bool inCommentTag=false; - for(std::size_t i = 0; i < buf.size(); ++i) { - // Ignore Spaces in XML files as they are - // ONLY for formatting - //if(isXMLFile == true) { - if(inCommentTag == true) { - if(buf[i] == '>' && i >= 3 && buf[i-1] == '-' && buf[i-2] == '-') { - inCommentTag = false; - //printf("TURNING OFF comment TAG, i = %d [%c]",i,buf[i]); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d\n",__FILE__,__FUNCTION__,__LINE__,i); - } - else { - //printf("SKIPPING XML comment character, i = %d [%c]",i,buf[i]); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d\n",__FILE__,__FUNCTION__,__LINE__,i); - } - continue; - } - //else if(buf[i] == '-' && i >= 4 && buf[i-1] == '-' && buf[i-2] == '!' && buf[i-3] == '<') { - else if(buf[i] == '<' && i+4 < bufSize && buf[i+1] == '!' && buf[i+2] == '-' && buf[i+3] == '-') { - inCommentTag = true; - //printf("TURNING ON comment TAG, i = %d [%c]",i,buf[i]); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d\n",__FILE__,__FUNCTION__,__LINE__,i); - continue; - } - else if(buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n' || buf[i] == '\r') { - //printf("SKIPPING special character, i = %d [%c]",i,buf[i]); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d\n",__FILE__,__FUNCTION__,__LINE__,i); - continue; - } - //} - uint32 cipher = addByte(buf[i]); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] %d / %d, cipher = %u\n",__FILE__,__FUNCTION__,__LINE__,i,buf.size(), cipher); - } - } - else { - uint32 cipher = addBytes(&buf[0],buf.size()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] %d, cipher = %u\n",__FILE__,__FUNCTION__,__LINE__,buf.size(), cipher); - } - - // Close the file - ifs.close(); - } -#if defined(WIN32) && !defined(__MINGW32__) - if(fp) { - fclose(fp); - } -#endif - - return fileExists; -} - -uint32 Checksum::getSum() { - //printf("Getting checksum for files [%d]\n",fileList.size()); - if(fileList.size() > 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileList.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,fileList.size()); - - Checksum newResult; + Mutex Checksum::fileListCacheSynchAccessor; + std::map Checksum::fileListCache; + unsigned int crc_table[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d + }; - for(std::map::iterator iterMap = fileList.begin(); - iterMap != fileList.end(); ++iterMap) { - - MutexSafeWrapper safeMutexSocketDestructorFlag(&Checksum::fileListCacheSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); - if(Checksum::fileListCache.find(iterMap->first) == Checksum::fileListCache.end()) { - Checksum fileResult; - //bool fileAddedOk = fileResult.addFileToSum(iterMap->first); - fileResult.addFileToSum(iterMap->first); - Checksum::fileListCache[iterMap->first] = fileResult.getSum(); - //printf("fileAddedOk = %d for file [%s] CRC [%d]\n",fileAddedOk,iterMap->first.c_str(),Checksum::fileListCache[iterMap->first]); - } - else { - //printf("Getting checksum from CACHE for file [%s] CRC [%d]\n",iterMap->first.c_str(),Checksum::fileListCache[iterMap->first]); - } - newResult.addSum(Checksum::fileListCache[iterMap->first]); - } + Checksum::Checksum() { + sum = 0; + r = 55665; + c1 = 52845; + c2 = 22719; } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileList.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,fileList.size()); + uint32 Checksum::addByte(const char value) { + // int32 cipher= (value ^ (r >> 8)); + // + // r= (cipher + r) * c1 + c2; + // sum += cipher; + // + // return cipher; + + const unsigned char *rVal = reinterpret_cast(&value); + sum = ~sum; + sum = (sum >> 8) ^ crc_table[*rVal ^ (sum & 0xff)]; + sum = ~sum; + + return sum; + } + + uint32 Checksum::addBytes(const void *_data, size_t _size) { + const unsigned char *rVal = reinterpret_cast(_data); + sum = ~sum; + while (_size--) { + sum = (sum >> 8) ^ crc_table[*rVal++ ^ (sum & 0xff)]; + } + sum = ~sum; + + return sum; + } + + + void Checksum::addSum(uint32 value) { + sum += value; + } + + uint32 Checksum::addInt(const int32 &value) { + int8 byte = (value >> 0) & 0xFF; + addByte(byte); + byte = (value >> 8) & 0xFF; + addByte(byte); + byte = (value >> 16) & 0xFF; + addByte(byte); + byte = (value >> 24) & 0xFF; + addByte(byte); + + return sum; + } + + uint32 Checksum::addUInt(const uint32 &value) { + int8 byte = (value >> 0) & 0xFF; + addByte(byte); + byte = (value >> 8) & 0xFF; + addByte(byte); + byte = (value >> 16) & 0xFF; + addByte(byte); + byte = (value >> 24) & 0xFF; + addByte(byte); + + return sum; + } + + uint32 Checksum::addInt64(const int64 &value) { + int8 byte = (value >> 0) & 0xFF; + addByte(byte); + byte = (value >> 8) & 0xFF; + addByte(byte); + byte = (value >> 16) & 0xFF; + addByte(byte); + byte = (value >> 24) & 0xFF; + addByte(byte); + byte = (value >> 32) & 0xFF; + addByte(byte); + byte = (value >> 40) & 0xFF; + addByte(byte); + byte = (value >> 48) & 0xFF; + addByte(byte); + byte = (value >> 56) & 0xFF; + addByte(byte); + + return sum; + } + + void Checksum::addString(const string &value) { + for (unsigned int i = 0; i < value.size(); ++i) { + addByte(value[i]); + } + } + + void Checksum::addFile(const string &path) { + if (path != "") { + fileList[path] = 0; + } + } + + bool Checksum::addFileToSum(const string &path) { + + // OLD SLOW FILE I/O + /* + FILE* file= fopen(path.c_str(), "rb"); + if(file!=NULL){ + + addString(lastFile(path)); + + while(!feof(file)){ + int8 byte= 0; + + size_t readBytes = fread(&byte, 1, 1, file); + addByte(byte); + } + } + else + { + throw megaglest_runtime_error("Can not open file: " + path); + } + fclose(file); + */ + + + + /* + const double MAX_CRC_FILESIZE = 100000000; + int fd=0; + size_t bytes_read, bytes_expected = MAX_CRC_FILESIZE * sizeof(int8); + int8 *data=0; + const char *infile = path.c_str(); + + if ((fd = open(infile,O_RDONLY)) < 0) + throw megaglest_runtime_error("Can not open file: " + path); + + if ((data = (int8 *)malloc(bytes_expected)) == NULL) + throw megaglest_runtime_error("malloc failed, Can not open file: " + path); + + bytes_read = read(fd, data, bytes_expected); + + //if (bytes_read != bytes_expected) + // throw megaglest_runtime_error("read failed, Can not open file: " + path); + + for(int i = 0; i < bytes_read; i++) { + addByte(data[i]); + } + free(data); + */ + + bool fileExists = false; + + /* + #ifdef WIN32 + FILE* file= _wfopen(utf8_decode(path).c_str(), L"rb"); + #else + FILE* file= fopen(path.c_str(), "rb"); + #endif + if(file != NULL) { + fileExists = true; + addString(lastFile(path)); + + bool isXMLFile = (EndsWith(path, ".xml") == true); + bool inCommentTag=false; + char buf[4096]=""; // Should be large enough. + int bufSize = sizeof buf; + while(!feof(file)) { + //int8 byte= 0; + + //size_t readBytes = fread(&byte, 1, 1, file); + memset(buf,0,bufSize); + if(fgets(buf, bufSize, file) != NULL) { + //addByte(byte); + for(int i = 0; i < bufSize && buf[i] != 0; i++) { + // Ignore Spaces in XML files as they are + // ONLY for formatting + if(isXMLFile == true) { + if(inCommentTag == true) { + if(buf[i] == '>' && i >= 3 && buf[i-1] == '-' && buf[i-2] == '-') { + inCommentTag = false; + //printf("TURNING OFF comment TAG, i = %d [%c]",i,buf[i]); + } + else { + //printf("SKIPPING XML comment character, i = %d [%c]",i,buf[i]); + } + continue; + } + //else if(buf[i] == '-' && i >= 4 && buf[i-1] == '-' && buf[i-2] == '!' && buf[i-3] == '<') { + else if(buf[i] == '<' && i+4 < bufSize && buf[i+1] == '!' && buf[i+2] == '-' && buf[i+3] == '-') { + inCommentTag = true; + //printf("TURNING ON comment TAG, i = %d [%c]",i,buf[i]); + continue; + } + else if(buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n' || buf[i] == '\r') { + //printf("SKIPPING special character, i = %d [%c]",i,buf[i]); + continue; + } + } + addByte(buf[i]); + } + } + } + } + else { + throw megaglest_runtime_error("Can not open file: " + path); + } + fclose(file); + */ + +#if defined(WIN32) && !defined(__MINGW32__) + wstring wstr = utf8_decode(path); + FILE *fp = _wfopen(wstr.c_str(), L"rb"); + ifstream ifs(fp); +#else + ifstream ifs(path.c_str()); +#endif + + if (ifs) { + fileExists = true; + addString(lastFile(path)); + + bool isXMLFile = (EndsWith(path, ".xml") == true); + + // Determine the file length + ifs.seekg(0, ios::end); + std::streamoff size = ifs.tellg(); + ifs.seekg(0, ios::beg); + + unsigned int bufSize = (unsigned int) size / sizeof(char); + // Create a vector to store the data + std::vector buf(bufSize); + // Load the data + ifs.read((char*) &buf[0], buf.size()); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] buf.size() = %d, path [%s], isXMLFile = %d\n", __FILE__, __FUNCTION__, __LINE__, buf.size(), path.c_str(), isXMLFile); + + if (isXMLFile == true) { + bool inCommentTag = false; + for (std::size_t i = 0; i < buf.size(); ++i) { + // Ignore Spaces in XML files as they are + // ONLY for formatting + //if(isXMLFile == true) { + if (inCommentTag == true) { + if (buf[i] == '>' && i >= 3 && buf[i - 1] == '-' && buf[i - 2] == '-') { + inCommentTag = false; + //printf("TURNING OFF comment TAG, i = %d [%c]",i,buf[i]); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] i = %d\n", __FILE__, __FUNCTION__, __LINE__, i); + } else { + //printf("SKIPPING XML comment character, i = %d [%c]",i,buf[i]); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] i = %d\n", __FILE__, __FUNCTION__, __LINE__, i); + } + continue; + } + //else if(buf[i] == '-' && i >= 4 && buf[i-1] == '-' && buf[i-2] == '!' && buf[i-3] == '<') { + else if (buf[i] == '<' && i + 4 < bufSize && buf[i + 1] == '!' && buf[i + 2] == '-' && buf[i + 3] == '-') { + inCommentTag = true; + //printf("TURNING ON comment TAG, i = %d [%c]",i,buf[i]); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] i = %d\n", __FILE__, __FUNCTION__, __LINE__, i); + continue; + } else if (buf[i] == ' ' || buf[i] == '\t' || buf[i] == '\n' || buf[i] == '\r') { + //printf("SKIPPING special character, i = %d [%c]",i,buf[i]); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] i = %d\n", __FILE__, __FUNCTION__, __LINE__, i); + continue; + } + //} + uint32 cipher = addByte(buf[i]); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] %d / %d, cipher = %u\n", __FILE__, __FUNCTION__, __LINE__, i, buf.size(), cipher); + } + } else { + uint32 cipher = addBytes(&buf[0], buf.size()); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] %d, cipher = %u\n", __FILE__, __FUNCTION__, __LINE__, buf.size(), cipher); + } + + // Close the file + ifs.close(); + } +#if defined(WIN32) && !defined(__MINGW32__) + if (fp) { + fclose(fp); + } +#endif + + return fileExists; + } + + uint32 Checksum::getSum() { + //printf("Getting checksum for files [%d]\n",fileList.size()); + if (fileList.size() > 0) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] fileList.size() = %d\n", __FILE__, __FUNCTION__, __LINE__, fileList.size()); + + Checksum newResult; + + { + + for (std::map::iterator iterMap = fileList.begin(); + iterMap != fileList.end(); ++iterMap) { + + MutexSafeWrapper safeMutexSocketDestructorFlag(&Checksum::fileListCacheSynchAccessor, string(__FILE__) + "_" + intToStr(__LINE__)); + if (Checksum::fileListCache.find(iterMap->first) == Checksum::fileListCache.end()) { + Checksum fileResult; + //bool fileAddedOk = fileResult.addFileToSum(iterMap->first); + fileResult.addFileToSum(iterMap->first); + Checksum::fileListCache[iterMap->first] = fileResult.getSum(); + //printf("fileAddedOk = %d for file [%s] CRC [%d]\n",fileAddedOk,iterMap->first.c_str(),Checksum::fileListCache[iterMap->first]); + } else { + //printf("Getting checksum from CACHE for file [%s] CRC [%d]\n",iterMap->first.c_str(),Checksum::fileListCache[iterMap->first]); + } + newResult.addSum(Checksum::fileListCache[iterMap->first]); + } + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] fileList.size() = %d\n", __FILE__, __FUNCTION__, __LINE__, fileList.size()); + + return newResult.getSum(); + } + return sum; + } + + uint32 Checksum::getFinalFileListSum() { + sum = 0; + return getSum(); + } + + //uint32 Checksum::getFinalFileListSum() { + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] sum = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,sum); + // + // sum = 0; + // //return getSum(); + // sum = getSum(); + // + // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] sum = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,sum); + // + // return sum; + //} + + uint32 Checksum::getFileCount() { + return (uint32) fileList.size(); + } + + void Checksum::removeFileFromCache(const string file) { + MutexSafeWrapper safeMutexSocketDestructorFlag(&Checksum::fileListCacheSynchAccessor, string(__FILE__) + "_" + intToStr(__LINE__)); + if (Checksum::fileListCache.find(file) != Checksum::fileListCache.end()) { + Checksum::fileListCache.erase(file); + } + } + + void Checksum::clearFileCache() { + MutexSafeWrapper safeMutexSocketDestructorFlag(&Checksum::fileListCacheSynchAccessor, string(__FILE__) + "_" + intToStr(__LINE__)); + Checksum::fileListCache.clear(); + } - return newResult.getSum(); } - return sum; -} - -uint32 Checksum::getFinalFileListSum() { - sum = 0; - return getSum(); -} - -//uint32 Checksum::getFinalFileListSum() { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] sum = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,sum); -// -// sum = 0; -// //return getSum(); -// sum = getSum(); -// -// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] sum = %u\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,sum); -// -// return sum; -//} - -uint32 Checksum::getFileCount() { - return (uint32)fileList.size(); -} - -void Checksum::removeFileFromCache(const string file) { - MutexSafeWrapper safeMutexSocketDestructorFlag(&Checksum::fileListCacheSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); - if(Checksum::fileListCache.find(file) != Checksum::fileListCache.end()) { - Checksum::fileListCache.erase(file); - } -} - -void Checksum::clearFileCache() { - MutexSafeWrapper safeMutexSocketDestructorFlag(&Checksum::fileListCacheSynchAccessor,string(__FILE__) + "_" + intToStr(__LINE__)); - Checksum::fileListCache.clear(); -} - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/util/conversion.cpp b/source/shared_lib/sources/util/conversion.cpp index ba8568fd0..0f30fd32c 100644 --- a/source/shared_lib/sources/util/conversion.cpp +++ b/source/shared_lib/sources/util/conversion.cpp @@ -24,237 +24,238 @@ using namespace std; -namespace Shared{ namespace Util{ +namespace Shared { + namespace Util { -const int strSize = 256; + const int strSize = 256; + + bool strToBool(const string &s) { + if (s == "0" || s == "false") { + return false; + } + if (s == "1" || s == "true") { + return true; + } + throw megaglest_runtime_error("Error converting string to bool, expected 0 or 1, found: [" + s + "]"); + } + + int strToInt(const string &s) { + char *endChar; + setlocale(LC_NUMERIC, "C"); + int intValue = strtol(s.c_str(), &endChar, 10); + + if (*endChar != '\0') { + throw megaglest_runtime_error("Error converting from string to int, found: [" + s + "]"); + } + + return intValue; + } + + uint32 strToUInt(const string &s) { + char *endChar; + setlocale(LC_NUMERIC, "C"); + uint32 intValue = strtoul(s.c_str(), &endChar, 10); + + if (*endChar != '\0') { + throw megaglest_runtime_error("Error converting from string to uint, found: [" + s + "]"); + } + + return intValue; + } + + + float strToFloat(const string &s) { + char *endChar; + + setlocale(LC_NUMERIC, "C"); + float floatValue = static_cast(strtod(s.c_str(), &endChar)); + + if (*endChar != '\0') { + throw megaglest_runtime_error("Error converting from string to float, found: [" + s + "]"); + } + + return floatValue; + } + + bool strToBool(const string &s, bool *b) { + if (s == "0" || s == "false") { + *b = false; + return true; + } + if (s == "1" || s == "true") { + *b = true; + return true; + } + + return false; + } + + bool strToInt(const string &s, int *i) { + char *endChar; + + setlocale(LC_NUMERIC, "C"); + *i = strtol(s.c_str(), &endChar, 10); + + if (*endChar != '\0') { + return false; + } + return true; + } + + bool strToUInt(const string &s, uint32 *i) { + char *endChar; + + setlocale(LC_NUMERIC, "C"); + *i = strtoul(s.c_str(), &endChar, 10); + + if (*endChar != '\0') { + return false; + } + return true; + } + + bool strToFloat(const string &s, float *f) { + char *endChar; + setlocale(LC_NUMERIC, "C"); + *f = static_cast(strtod(s.c_str(), &endChar)); + + if (*endChar != '\0') { + return false; + } + return true; + } + + string boolToStr(bool b) { + if (b) { + return "1"; + } else { + return "0"; + } + } + + string intToStr(const int64 value) { + char str[strSize] = ""; + // static int MAX_INT_VALUE = std::numeric_limits::max(); + // if(value <= MAX_INT_VALUE) { + // snprintf(str, strSize-1, "%d", (int)value); + // } + // else { + snprintf(str, strSize - 1, "%lld", (long long int)value); + // } + return (str[0] != '\0' ? str : ""); + } + + string uIntToStr(const uint64 value) { + char str[strSize] = ""; + // static unsigned int MAX_UNSIGNED_INT_VALUE = std::numeric_limits::max(); + // if(value <= MAX_UNSIGNED_INT_VALUE) { + // snprintf(str, strSize-1, "%u", (int)value); + // } + // else { + snprintf(str, strSize - 1, "%llu", (long long unsigned int)value); + // } + return (str[0] != '\0' ? str : ""); + } + + string intToHex(int i) { + char str[strSize] = ""; + snprintf(str, strSize - 1, "%x", i); + return (str[0] != '\0' ? str : ""); + } + + string floatToStr(float f, int precsion) { + setlocale(LC_NUMERIC, "C"); + + char str[strSize] = ""; + snprintf(str, strSize - 1, "%.*f", precsion, f); + return (str[0] != '\0' ? str : ""); + } + + string doubleToStr(double d, int precsion) { + setlocale(LC_NUMERIC, "C"); + + char str[strSize] = ""; + snprintf(str, strSize - 1, "%.*f", precsion, d); + return (str[0] != '\0' ? str : ""); + } + + bool IsNumeric(const char *p, bool allowNegative) { + if (p == NULL) { + return false; + } + if (strcmp(p, "-") == 0) { + return false; + } + int index = 0; + for (; *p; p++) { + if (*p < '0' || *p > '9') { + if (allowNegative == false || (*p != '-' && index == 0)) { + return false; + } + } + index++; + } + return true; + } + + class Comma : public numpunct// own facet class + { + protected: + //char do_thousands_sep() const { return ','; }// use the comma + //string do_grouping() const { return "\3"; }//group 3 digits + }; + string formatNumber(uint64 f) { + + locale myloc(locale(), // C++ default locale + new Comma);// Own numeric facet + + ostringstream out; + out.imbue(myloc); + out << f; + return out.str(); + } + + double getTimeDuationMinutes(int frames, int updateFps) { + int framesleft = frames; + double hours = (int) ((int) frames / (float) updateFps / 3600.0f); + framesleft = framesleft - hours * 3600 * updateFps; + double minutes = (int) ((int) framesleft / (float) updateFps / 60.0f); + framesleft = framesleft - minutes * 60 * updateFps; + double seconds = (int) ((int) framesleft / (float) updateFps); + + double result = (hours * 60.0) + minutes; + if (seconds > 0) { + result += seconds / 60.0; + } + return result; + } + + string getTimeDuationString(int frames, int updateFps) { + int framesleft = frames; + int hours = (int) ((int) frames / (float) updateFps / 3600.0f); + framesleft = framesleft - hours * 3600 * updateFps; + int minutes = (int) ((int) framesleft / (float) updateFps / 60.0f); + framesleft = framesleft - minutes * 60 * updateFps; + int seconds = (int) ((int) framesleft / (float) updateFps); + //framesleft=framesleft-seconds*GameConstants::updateFps; + + string hourstr = intToStr(hours); + if (hours < 10) { + hourstr = "0" + hourstr; + } + + string minutestr = intToStr(minutes); + if (minutes < 10) { + minutestr = "0" + minutestr; + } + + string secondstr = intToStr(seconds); + if (seconds < 10) { + secondstr = "0" + secondstr; + } + + return hourstr + ":" + minutestr + ":" + secondstr; + } -bool strToBool(const string &s) { - if(s=="0" || s=="false") { - return false; } - if(s=="1" || s=="true") { - return true; - } - throw megaglest_runtime_error("Error converting string to bool, expected 0 or 1, found: [" + s + "]"); -} - -int strToInt(const string &s){ - char *endChar; - setlocale(LC_NUMERIC, "C"); - int intValue= strtol(s.c_str(), &endChar, 10); - - if(*endChar!='\0'){ - throw megaglest_runtime_error("Error converting from string to int, found: [" + s + "]"); - } - - return intValue; -} - -uint32 strToUInt(const string &s){ - char *endChar; - setlocale(LC_NUMERIC, "C"); - uint32 intValue= strtoul(s.c_str(), &endChar, 10); - - if(*endChar!='\0'){ - throw megaglest_runtime_error("Error converting from string to uint, found: [" + s + "]"); - } - - return intValue; -} - - -float strToFloat(const string &s){ - char *endChar; - - setlocale(LC_NUMERIC, "C"); - float floatValue= static_cast(strtod(s.c_str(), &endChar)); - - if(*endChar!='\0'){ - throw megaglest_runtime_error("Error converting from string to float, found: [" + s + "]"); - } - - return floatValue; -} - -bool strToBool(const string &s, bool *b){ - if (s=="0" || s=="false"){ - *b= false; - return true; - } - if (s=="1" || s=="true"){ - *b= true; - return true; - } - - return false; -} - -bool strToInt(const string &s, int *i) { - char *endChar; - - setlocale(LC_NUMERIC, "C"); - *i= strtol(s.c_str(), &endChar, 10); - - if(*endChar!='\0'){ - return false; - } - return true; -} - -bool strToUInt(const string &s, uint32 *i) { - char *endChar; - - setlocale(LC_NUMERIC, "C"); - *i= strtoul(s.c_str(), &endChar, 10); - - if(*endChar!='\0'){ - return false; - } - return true; -} - -bool strToFloat(const string &s, float *f) { - char *endChar; - setlocale(LC_NUMERIC, "C"); - *f= static_cast(strtod(s.c_str(), &endChar)); - - if(*endChar!='\0'){ - return false; - } - return true; -} - -string boolToStr(bool b) { - if(b) { - return "1"; - } - else{ - return "0"; - } -} - -string intToStr(const int64 value) { - char str[strSize]=""; -// static int MAX_INT_VALUE = std::numeric_limits::max(); -// if(value <= MAX_INT_VALUE) { -// snprintf(str, strSize-1, "%d", (int)value); -// } -// else { - snprintf(str, strSize-1, "%lld", (long long int)value); -// } - return (str[0] != '\0' ? str : ""); -} - -string uIntToStr(const uint64 value) { - char str[strSize]=""; -// static unsigned int MAX_UNSIGNED_INT_VALUE = std::numeric_limits::max(); -// if(value <= MAX_UNSIGNED_INT_VALUE) { -// snprintf(str, strSize-1, "%u", (int)value); -// } -// else { - snprintf(str, strSize-1, "%llu", (long long unsigned int)value); -// } - return (str[0] != '\0' ? str : ""); -} - -string intToHex(int i){ - char str[strSize]=""; - snprintf(str, strSize-1, "%x", i); - return (str[0] != '\0' ? str : ""); -} - -string floatToStr(float f,int precsion) { - setlocale(LC_NUMERIC, "C"); - - char str[strSize]=""; - snprintf(str, strSize-1, "%.*f", precsion,f); - return (str[0] != '\0' ? str : ""); -} - -string doubleToStr(double d,int precsion) { - setlocale(LC_NUMERIC, "C"); - - char str[strSize]=""; - snprintf(str, strSize-1, "%.*f", precsion,d); - return (str[0] != '\0' ? str : ""); -} - -bool IsNumeric(const char *p, bool allowNegative) { - if(p == NULL) { - return false; - } - if(strcmp(p,"-") == 0) { - return false; - } - int index = 0; - for ( ; *p; p++) { - if (*p < '0' || *p > '9') { - if(allowNegative == false || (*p != '-' && index == 0)) { - return false; - } - } - index++; - } - return true; -} - -class Comma: public numpunct// own facet class -{ - protected: - //char do_thousands_sep() const { return ','; }// use the comma - //string do_grouping() const { return "\3"; }//group 3 digits -}; -string formatNumber(uint64 f) { - - locale myloc( locale(), // C++ default locale - new Comma);// Own numeric facet - - ostringstream out; - out.imbue(myloc); - out << f; - return out.str(); -} - -double getTimeDuationMinutes(int frames, int updateFps) { - int framesleft = frames; - double hours = (int)((int) frames / (float)updateFps / 3600.0f); - framesleft = framesleft - hours * 3600 * updateFps; - double minutes = (int)((int) framesleft / (float)updateFps / 60.0f); - framesleft = framesleft - minutes * 60 * updateFps; - double seconds = (int)((int) framesleft / (float)updateFps); - - double result = (hours * 60.0) + minutes; - if(seconds > 0) { - result += seconds / 60.0; - } - return result; -} - -string getTimeDuationString(int frames, int updateFps) { - int framesleft = frames; - int hours = (int)((int) frames / (float)updateFps / 3600.0f); - framesleft = framesleft - hours * 3600 * updateFps; - int minutes = (int)((int) framesleft / (float)updateFps / 60.0f); - framesleft = framesleft - minutes * 60 * updateFps; - int seconds = (int)((int) framesleft / (float)updateFps); - //framesleft=framesleft-seconds*GameConstants::updateFps; - - string hourstr = intToStr(hours); - if(hours < 10) { - hourstr = "0" + hourstr; - } - - string minutestr = intToStr(minutes); - if(minutes < 10) { - minutestr = "0" + minutestr; - } - - string secondstr = intToStr(seconds); - if(seconds < 10) { - secondstr = "0" + secondstr; - } - - return hourstr + ":" + minutestr + ":" + secondstr; -} - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/util/leak_dumper.cpp b/source/shared_lib/sources/util/leak_dumper.cpp index 92efcd1b1..689ebb5c5 100644 --- a/source/shared_lib/sources/util/leak_dumper.cpp +++ b/source/shared_lib/sources/util/leak_dumper.cpp @@ -32,33 +32,33 @@ AllocRegistry::~AllocRegistry() { void AllocRegistry::dump(const char *path) { - int leakCount=0; - size_t leakBytes=0; + int leakCount = 0; + size_t leakBytes = 0; //time_t debugTime = time(NULL); //struct tm *loctime = localtime (&debugTime); struct tm loctime = threadsafe_localtime(systemtime_now()); - char szBuf2[100]=""; - strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",&loctime); + char szBuf2[100] = ""; + strftime(szBuf2, 100, "%Y-%m-%d %H:%M:%S", &loctime); #ifdef WIN32 - FILE* f= _wfopen(utf8_decode(path).c_str(), L"wt"); + FILE* f = _wfopen(utf8_decode(path).c_str(), L"wt"); #else - FILE *f= fopen(path, "wt"); + FILE *f = fopen(path, "wt"); #endif - if(f) { - fprintf(f, "Memory leak dump at: %s\n\n",szBuf2); + if (f) { + fprintf(f, "Memory leak dump at: %s\n\n", szBuf2); - for(int index = 0; index < maxAllocs; ++index) { + for (int index = 0; index < maxAllocs; ++index) { AllocInfo &info = allocs[index]; - if(info.freetouse == false && info.inuse == true) { + if (info.freetouse == false && info.inuse == true) { - if(info.line > 0) { + if (info.line > 0) { leakBytes += info.bytes; //allocs[i].stack = AllocInfo::getStackTrace(); - fprintf(f, "Leak #%d.\tfile: %s, line: %d, ptr [%p], bytes: " MG_SIZE_T_SPECIFIER ", array: %d, inuse: %d\n%s\n", ++leakCount, info.file, info.line, info.ptr, info.bytes, info.array,info.inuse,info.stack.c_str()); + fprintf(f, "Leak #%d.\tfile: %s, line: %d, ptr [%p], bytes: " MG_SIZE_T_SPECIFIER ", array: %d, inuse: %d\n%s\n", ++leakCount, info.file, info.line, info.ptr, info.bytes, info.array, info.inuse, info.stack.c_str()); } } } @@ -70,7 +70,7 @@ void AllocRegistry::dump(const char *path) { fclose(f); } - printf("Memory leak dump summary at: %s\n",szBuf2); + printf("Memory leak dump summary at: %s\n", szBuf2); printf("Total leaks: %d, " MG_SIZE_T_SPECIFIER " bytes\n", leakCount, leakBytes); printf("Total allocations: %d, " MG_SIZE_T_SPECIFIER " bytes\n", allocCount, allocBytes); printf("Not monitored allocations: %d, " MG_SIZE_T_SPECIFIER " bytes\n", nonMonitoredCount, nonMonitoredBytes); diff --git a/source/shared_lib/sources/util/profiler.cpp b/source/shared_lib/sources/util/profiler.cpp index 165532908..5221792a2 100644 --- a/source/shared_lib/sources/util/profiler.cpp +++ b/source/shared_lib/sources/util/profiler.cpp @@ -18,112 +18,112 @@ using namespace std; -namespace Shared{ namespace Util{ +namespace Shared { + namespace Util { -// ===================================================== -// class Section -// ===================================================== + // ===================================================== + // class Section + // ===================================================== -Section::Section(const string &name){ - this->name= name; - milisElapsed= 0; - parent= NULL; -} - -Section *Section::getChild(const string &name){ - SectionContainer::iterator it; - for(it= children.begin(); it!=children.end(); ++it){ - if((*it)->getName()==name){ - return *it; + Section::Section(const string &name) { + this->name = name; + milisElapsed = 0; + parent = NULL; } - } - return NULL; -} + Section *Section::getChild(const string &name) { + SectionContainer::iterator it; + for (it = children.begin(); it != children.end(); ++it) { + if ((*it)->getName() == name) { + return *it; + } + } -void Section::print(FILE *outStream, int tabLevel){ + return NULL; + } - float percent= (parent==NULL || parent->milisElapsed==0)? 100.0f: 100.0f*milisElapsed/parent->milisElapsed; - //string pname= parent==NULL? "": parent->getName(); + void Section::print(FILE *outStream, int tabLevel) { - for(int i=0; imilisElapsed == 0) ? 100.0f : 100.0f*milisElapsed / parent->milisElapsed; + //string pname= parent==NULL? "": parent->getName(); - fprintf(outStream, "%s: ", name.c_str()); - fprintf(outStream, "%d ms, ", milisElapsed); - fprintf(outStream, "%.1f%s\n", percent, "%"); + for (int i = 0; i < tabLevel; ++i) + fprintf(outStream, "\t"); - SectionContainer::iterator it; - for(it= children.begin(); it!=children.end(); ++it){ - (*it)->print(outStream, tabLevel+1); - } -} + fprintf(outStream, "%s: ", name.c_str()); + fprintf(outStream, "%d ms, ", milisElapsed); + fprintf(outStream, "%.1f%s\n", percent, "%"); -// ===================================================== -// class Profiler -// ===================================================== + SectionContainer::iterator it; + for (it = children.begin(); it != children.end(); ++it) { + (*it)->print(outStream, tabLevel + 1); + } + } -Profiler::Profiler(){ - rootSection= new Section("Root"); - currSection= rootSection; - rootSection->start(); -} + // ===================================================== + // class Profiler + // ===================================================== -Profiler::~Profiler(){ - rootSection->stop(); + Profiler::Profiler() { + rootSection = new Section("Root"); + currSection = rootSection; + rootSection->start(); + } - string profileLog = "profiler.log"; - if(getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { - profileLog = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + profileLog; - } - else { - string userData = config.getString("UserData_Root",""); - if(userData != "") { - endPathWithSlash(userData); - } - profileLog = userData + profileLog; - } + Profiler::~Profiler() { + rootSection->stop(); + + string profileLog = "profiler.log"; + if (getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) != "") { + profileLog = getGameReadWritePath(GameConstants::path_logs_CacheLookupKey) + profileLog; + } else { + string userData = config.getString("UserData_Root", ""); + if (userData != "") { + endPathWithSlash(userData); + } + profileLog = userData + profileLog; + } #ifdef WIN32 - FILE* f= = _wfopen(utf8_decode(profileLog).c_str(), L"w"); + FILE* f = = _wfopen(utf8_decode(profileLog).c_str(), L"w"); #else - FILE *f= fopen(profileLog.c_str(), "w"); + FILE *f = fopen(profileLog.c_str(), "w"); #endif - if(f==NULL) - throw megaglest_runtime_error("Can not open file: " + profileLog); + if (f == NULL) + throw megaglest_runtime_error("Can not open file: " + profileLog); - fprintf(f, "Profiler Results\n\n"); + fprintf(f, "Profiler Results\n\n"); - rootSection->print(f); + rootSection->print(f); - fclose(f); -} + fclose(f); + } -Profiler &Profiler::getInstance(){ - static Profiler profiler; - return profiler; -} + Profiler &Profiler::getInstance() { + static Profiler profiler; + return profiler; + } + + void Profiler::sectionBegin(const string &name) { + Section *childSection = currSection->getChild(name); + if (childSection == NULL) { + childSection = new Section(name); + currSection->addChild(childSection); + childSection->setParent(currSection); + } + currSection = childSection; + childSection->start(); + } + + void Profiler::sectionEnd(const string &name) { + if (name == currSection->getName()) { + currSection->stop(); + currSection = currSection->getParent(); + } else { + throw megaglest_runtime_error("Profile: Leaving section is not current section: " + name); + } + } -void Profiler::sectionBegin(const string &name){ - Section *childSection= currSection->getChild(name); - if(childSection==NULL){ - childSection= new Section(name); - currSection->addChild(childSection); - childSection->setParent(currSection); } - currSection= childSection; - childSection->start(); -} - -void Profiler::sectionEnd(const string &name){ - if(name==currSection->getName()){ - currSection->stop(); - currSection= currSection->getParent(); - } - else{ - throw megaglest_runtime_error("Profile: Leaving section is not current section: "+name); - } -} - -}};//end namespace +};//end namespace #endif diff --git a/source/shared_lib/sources/util/properties.cpp b/source/shared_lib/sources/util/properties.cpp index 5f2852c52..b4963995b 100644 --- a/source/shared_lib/sources/util/properties.cpp +++ b/source/shared_lib/sources/util/properties.cpp @@ -40,604 +40,592 @@ using namespace Shared::PlatformCommon; using namespace Shared::Platform; using namespace Shared::Graphics; -namespace Shared{ namespace Util{ +namespace Shared { + namespace Util { -string Properties::applicationPath = ""; -string Properties::applicationDataPath = ""; -string Properties::gameVersion = ""; + string Properties::applicationPath = ""; + string Properties::applicationDataPath = ""; + string Properties::gameVersion = ""; -string Properties::techtreePath = ""; -string Properties::scenarioPath = ""; -string Properties::tutorialPath = ""; + string Properties::techtreePath = ""; + string Properties::scenarioPath = ""; + string Properties::tutorialPath = ""; -// ===================================================== -// class Properties -// ===================================================== + // ===================================================== + // class Properties + // ===================================================== -void Properties::load(const string &path, bool clearCurrentProperties) { + void Properties::load(const string &path, bool clearCurrentProperties) { - char lineBuffer[maxLine]=""; - this->path= path; + char lineBuffer[maxLine] = ""; + this->path = path; - bool is_utf8_language = valid_utf8_file(path.c_str()); + bool is_utf8_language = valid_utf8_file(path.c_str()); #if defined(WIN32) && !defined(__MINGW32__) - wstring wstr = utf8_decode(path); - FILE *fp = _wfopen(wstr.c_str(), L"r"); - //wifstream fileStream(fp); - ifstream fileStream(fp); + wstring wstr = utf8_decode(path); + FILE *fp = _wfopen(wstr.c_str(), L"r"); + //wifstream fileStream(fp); + ifstream fileStream(fp); #else - //wifstream fileStream; - ifstream fileStream; - fileStream.open(path.c_str(), ios_base::in); + //wifstream fileStream; + ifstream fileStream; + fileStream.open(path.c_str(), ios_base::in); #endif - - if(fileStream.is_open() == false){ - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str()); - throw megaglest_runtime_error("File NOT FOUND, can't open file: [" + path + "]"); - } - if(clearCurrentProperties == true) { - propertyMap.clear(); - propertyMapTmp.clear(); - } + if (fileStream.is_open() == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] path = [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, path.c_str()); + throw megaglest_runtime_error("File NOT FOUND, can't open file: [" + path + "]"); + } - while(fileStream.eof() == false) { - lineBuffer[0]='\0'; - fileStream.getline(lineBuffer, maxLine); - lineBuffer[maxLine-1]='\0'; + if (clearCurrentProperties == true) { + propertyMap.clear(); + propertyMapTmp.clear(); + } - processTextLine(is_utf8_language,lineBuffer); - } + while (fileStream.eof() == false) { + lineBuffer[0] = '\0'; + fileStream.getline(lineBuffer, maxLine); + lineBuffer[maxLine - 1] = '\0'; - fileStream.close(); + processTextLine(is_utf8_language, lineBuffer); + } + + fileStream.close(); #if defined(WIN32) && !defined(__MINGW32__) - if(fp) { - fclose(fp); - } + if (fp) { + fclose(fp); + } #endif -} - -void Properties::loadFromText(const string &text) { - bool is_utf8_language = false; - - char lineBuffer[maxLine]=""; - - std::istringstream textStream(text); - while(textStream.eof() == false) { - //lineBuffer[0]='\0'; - std::string lineText; - getline(textStream, lineText); - if(lineText.length() > 0) { - memset(&lineBuffer[0],0,maxLine); - memcpy(&lineBuffer[0],&lineText[0],lineText.length()); - - //fileStream.getline(lineBuffer, maxLine); - //lineBuffer[maxLine-1]='\0'; - - processTextLine(is_utf8_language,&lineBuffer[0]); - } - } -} - -void Properties::processTextLine(bool is_utf8_language, char *lineBuffer) { - //printf("\n[%ls]\n",lineBuffer); - //printf("\n[%s]\n",&lineBuffer[0]); - - string line, key, value, original_value; - size_t pos=0; - - if(lineBuffer != NULL && lineBuffer[0] != '\0') { - // If the file is NOT in UTF-8 format convert each line - if(is_utf8_language == false && Font::forceLegacyFonts == false) { - char *utfStr = ConvertToUTF8(&lineBuffer[0]); - - //printf("\nBefore [%s] After [%s]\n",&lineBuffer[0],utfStr); - - memset(&lineBuffer[0],0,maxLine); - memcpy(&lineBuffer[0],&utfStr[0],strlen(utfStr)); - - delete [] utfStr; - } - else if(is_utf8_language == true && Font::forceLegacyFonts == true) { - char *asciiStr = ConvertFromUTF8(&lineBuffer[0]); - - //printf("\nBefore [%s] After [%s]\n",&lineBuffer[0],utfStr); - - memset(&lineBuffer[0],0,maxLine); - memcpy(&lineBuffer[0],&asciiStr[0],strlen(asciiStr)); - - delete [] asciiStr; - } - } - - //process line if it it not a comment - if(lineBuffer != NULL && lineBuffer[0] != ';' && lineBuffer[0] != '#') { - // gracefully handle win32 \r\n line endings - size_t len= strlen(lineBuffer); - if(len > 0 && lineBuffer[len-1] == '\r') { - lineBuffer[len-1]= 0; } - line= lineBuffer; - pos= line.find('='); + void Properties::loadFromText(const string &text) { + bool is_utf8_language = false; - if(pos != string::npos){ - key= line.substr(0, pos); - value= line.substr(pos+1); - original_value = value; + char lineBuffer[maxLine] = ""; - if(applyTagsToValue(value) == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Property key [%s] now has value [%s] original_value [%s]\n",key.c_str(),value.c_str(),original_value.c_str()); + std::istringstream textStream(text); + while (textStream.eof() == false) { + //lineBuffer[0]='\0'; + std::string lineText; + getline(textStream, lineText); + if (lineText.length() > 0) { + memset(&lineBuffer[0], 0, maxLine); + memcpy(&lineBuffer[0], &lineText[0], lineText.length()); + + //fileStream.getline(lineBuffer, maxLine); + //lineBuffer[maxLine-1]='\0'; + + processTextLine(is_utf8_language, &lineBuffer[0]); + } + } + } + + void Properties::processTextLine(bool is_utf8_language, char *lineBuffer) { + //printf("\n[%ls]\n",lineBuffer); + //printf("\n[%s]\n",&lineBuffer[0]); + + string line, key, value, original_value; + size_t pos = 0; + + if (lineBuffer != NULL && lineBuffer[0] != '\0') { + // If the file is NOT in UTF-8 format convert each line + if (is_utf8_language == false && Font::forceLegacyFonts == false) { + char *utfStr = ConvertToUTF8(&lineBuffer[0]); + + //printf("\nBefore [%s] After [%s]\n",&lineBuffer[0],utfStr); + + memset(&lineBuffer[0], 0, maxLine); + memcpy(&lineBuffer[0], &utfStr[0], strlen(utfStr)); + + delete[] utfStr; + } else if (is_utf8_language == true && Font::forceLegacyFonts == true) { + char *asciiStr = ConvertFromUTF8(&lineBuffer[0]); + + //printf("\nBefore [%s] After [%s]\n",&lineBuffer[0],utfStr); + + memset(&lineBuffer[0], 0, maxLine); + memcpy(&lineBuffer[0], &asciiStr[0], strlen(asciiStr)); + + delete[] asciiStr; + } } - bool replaceExisting = false; - if(propertyMap.find(key) != propertyMap.end()) { - replaceExisting = true; - } - propertyMap[key] = original_value; - propertyMapTmp[key] = value; + //process line if it it not a comment + if (lineBuffer != NULL && lineBuffer[0] != ';' && lineBuffer[0] != '#') { + // gracefully handle win32 \r\n line endings + size_t len = strlen(lineBuffer); + if (len > 0 && lineBuffer[len - 1] == '\r') { + lineBuffer[len - 1] = 0; + } - if(replaceExisting == false) { - propertyVector.push_back(PropertyPair(key, original_value)); - propertyVectorTmp.push_back(PropertyPair(key, value)); - } - else { - for(unsigned int i = 0; i < propertyVector.size(); ++i) { - PropertyPair ¤tPair = propertyVector[i]; - if(currentPair.first == key) { - currentPair.second = original_value; + line = lineBuffer; + pos = line.find('='); - propertyVectorTmp[i].second = value; - break; + if (pos != string::npos) { + key = line.substr(0, pos); + value = line.substr(pos + 1); + original_value = value; + + if (applyTagsToValue(value) == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Property key [%s] now has value [%s] original_value [%s]\n", key.c_str(), value.c_str(), original_value.c_str()); + } + + bool replaceExisting = false; + if (propertyMap.find(key) != propertyMap.end()) { + replaceExisting = true; + } + propertyMap[key] = original_value; + propertyMapTmp[key] = value; + + if (replaceExisting == false) { + propertyVector.push_back(PropertyPair(key, original_value)); + propertyVectorTmp.push_back(PropertyPair(key, value)); + } else { + for (unsigned int i = 0; i < propertyVector.size(); ++i) { + PropertyPair ¤tPair = propertyVector[i]; + if (currentPair.first == key) { + currentPair.second = original_value; + + propertyVectorTmp[i].second = value; + break; + } + } } } } } - } -} -std::map Properties::getTagReplacementValues(std::map *mapExtraTagReplacementValues) { - std::map mapTagReplacementValues; + std::map Properties::getTagReplacementValues(std::map *mapExtraTagReplacementValues) { + std::map mapTagReplacementValues; - // - // #1 - // First add the standard tags - // + // + // #1 + // First add the standard tags + // #ifdef WIN32 - const char *homeDirX = getenv("USERPROFILE"); + const char *homeDirX = getenv("USERPROFILE"); #else - string home = getUserHome(); - const char *homeDirX = home.c_str(); + string home = getUserHome(); + const char *homeDirX = home.c_str(); #endif - string homeDir = safeCharPtrCopy(homeDirX, 8096); + string homeDir = safeCharPtrCopy(homeDirX, 8096); - mapTagReplacementValues["~/"] = homeDir; - mapTagReplacementValues["$HOME"] = homeDir; - mapTagReplacementValues["%%HOME%%"] = homeDir; - mapTagReplacementValues["%%USERPROFILE%%"] = homeDir; - mapTagReplacementValues["%%HOMEPATH%%"] = homeDir; - mapTagReplacementValues["{HOMEPATH}"] = homeDir; + mapTagReplacementValues["~/"] = homeDir; + mapTagReplacementValues["$HOME"] = homeDir; + mapTagReplacementValues["%%HOME%%"] = homeDir; + mapTagReplacementValues["%%USERPROFILE%%"] = homeDir; + mapTagReplacementValues["%%HOMEPATH%%"] = homeDir; + mapTagReplacementValues["{HOMEPATH}"] = homeDir; - // For win32 we allow use of the appdata variable since that is the recommended - // place for application data in windows platform + // For win32 we allow use of the appdata variable since that is the recommended + // place for application data in windows platform #ifdef WIN32 - TCHAR szPath[MAX_PATH]; - // Get path for each computer, non-user specific and non-roaming data. - if ( SUCCEEDED( SHGetFolderPath( NULL, CSIDL_APPDATA, - NULL, 0, szPath))) { + TCHAR szPath[MAX_PATH]; + // Get path for each computer, non-user specific and non-roaming data. + if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, + NULL, 0, szPath))) { - //const wchar_t *wBuf = &szPath[0]; - //size_t size = MAX_PATH + 1; - //char pMBBuffer[MAX_PATH + 1]=""; - //wcstombs_s(&size, &pMBBuffer[0], (size_t)size, wBuf, (size_t)size);// Convert to char* from TCHAR[] - //string appPath=""; - //appPath.assign(&pMBBuffer[0]); // Now assign the char* to the string, and there you have it!!! :) - std::string appPath = utf8_encode(szPath); + //const wchar_t *wBuf = &szPath[0]; + //size_t size = MAX_PATH + 1; + //char pMBBuffer[MAX_PATH + 1]=""; + //wcstombs_s(&size, &pMBBuffer[0], (size_t)size, wBuf, (size_t)size);// Convert to char* from TCHAR[] + //string appPath=""; + //appPath.assign(&pMBBuffer[0]); // Now assign the char* to the string, and there you have it!!! :) + std::string appPath = utf8_encode(szPath); - //string appPath = szPath; - mapTagReplacementValues["$APPDATA"] = appPath; - mapTagReplacementValues["%%APPDATA%%"] = appPath; - mapTagReplacementValues["{APPDATA}"] = appPath; - } + //string appPath = szPath; + mapTagReplacementValues["$APPDATA"] = appPath; + mapTagReplacementValues["%%APPDATA%%"] = appPath; + mapTagReplacementValues["{APPDATA}"] = appPath; + } #endif - //char *username = NULL; - char *username = getenv("USERNAME"); + //char *username = NULL; + char *username = getenv("USERNAME"); - mapTagReplacementValues["$USERNAME"] = (username != NULL ? username : ""); - mapTagReplacementValues["%%USERNAME%%"] = (username != NULL ? username : ""); - mapTagReplacementValues["{USERNAME}"] = (username != NULL ? username : ""); + mapTagReplacementValues["$USERNAME"] = (username != NULL ? username : ""); + mapTagReplacementValues["%%USERNAME%%"] = (username != NULL ? username : ""); + mapTagReplacementValues["{USERNAME}"] = (username != NULL ? username : ""); - mapTagReplacementValues["$APPLICATIONPATH"] = Properties::applicationPath; - mapTagReplacementValues["%%APPLICATIONPATH%%"] = Properties::applicationPath; - mapTagReplacementValues["{APPLICATIONPATH}"] = Properties::applicationPath; + mapTagReplacementValues["$APPLICATIONPATH"] = Properties::applicationPath; + mapTagReplacementValues["%%APPLICATIONPATH%%"] = Properties::applicationPath; + mapTagReplacementValues["{APPLICATIONPATH}"] = Properties::applicationPath; #if defined(CUSTOM_DATA_INSTALL_PATH) - mapTagReplacementValues["$APPLICATIONDATAPATH"] = formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)); - mapTagReplacementValues["%%APPLICATIONDATAPATH%%"] = formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)); - mapTagReplacementValues["{APPLICATIONDATAPATH}"] = formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)); + mapTagReplacementValues["$APPLICATIONDATAPATH"] = formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)); + mapTagReplacementValues["%%APPLICATIONDATAPATH%%"] = formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)); + mapTagReplacementValues["{APPLICATIONDATAPATH}"] = formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH)); #else - mapTagReplacementValues["$APPLICATIONDATAPATH"] = Properties::applicationDataPath; - mapTagReplacementValues["%%APPLICATIONDATAPATH%%"] = Properties::applicationDataPath; - mapTagReplacementValues["{APPLICATIONDATAPATH}"] = Properties::applicationDataPath; + mapTagReplacementValues["$APPLICATIONDATAPATH"] = Properties::applicationDataPath; + mapTagReplacementValues["%%APPLICATIONDATAPATH%%"] = Properties::applicationDataPath; + mapTagReplacementValues["{APPLICATIONDATAPATH}"] = Properties::applicationDataPath; #endif - mapTagReplacementValues["{TECHTREEPATH}"] = Properties::techtreePath; - mapTagReplacementValues["{SCENARIOPATH}"] = Properties::scenarioPath; - mapTagReplacementValues["{TUTORIALPATH}"] = Properties::tutorialPath; + mapTagReplacementValues["{TECHTREEPATH}"] = Properties::techtreePath; + mapTagReplacementValues["{SCENARIOPATH}"] = Properties::scenarioPath; + mapTagReplacementValues["{TUTORIALPATH}"] = Properties::tutorialPath; - mapTagReplacementValues["$GAMEVERSION"] = Properties::gameVersion; + mapTagReplacementValues["$GAMEVERSION"] = Properties::gameVersion; - // - // #2 - // Next add the extra tags if passed in - // - if(mapExtraTagReplacementValues != NULL) { - for(std::map::iterator iterMap = mapExtraTagReplacementValues->begin(); - iterMap != mapExtraTagReplacementValues->end(); ++iterMap) { - mapTagReplacementValues[iterMap->first] = iterMap->second; + // + // #2 + // Next add the extra tags if passed in + // + if (mapExtraTagReplacementValues != NULL) { + for (std::map::iterator iterMap = mapExtraTagReplacementValues->begin(); + iterMap != mapExtraTagReplacementValues->end(); ++iterMap) { + mapTagReplacementValues[iterMap->first] = iterMap->second; + } + } + + return mapTagReplacementValues; } - } - return mapTagReplacementValues; -} + bool Properties::isValuePathVariable(const string &value) { + if (value.find("~/") != value.npos || + value.find("$HOME") != value.npos || + value.find("%%HOME%%") != value.npos || + value.find("%%USERPROFILE%%") != value.npos || + value.find("%%HOMEPATH%%") != value.npos || + value.find("{HOMEPATH}") != value.npos || + value.find("$APPDATA") != value.npos || + value.find("%%APPDATA%%") != value.npos || + value.find("{APPDATA}") != value.npos || + value.find("$APPLICATIONPATH") != value.npos || + value.find("%%APPLICATIONPATH%%") != value.npos || + value.find("{APPLICATIONPATH}") != value.npos || + value.find("$APPLICATIONDATAPATH") != value.npos || + value.find("%%APPLICATIONDATAPATH%%") != value.npos || + value.find("{APPLICATIONDATAPATH}") != value.npos || + value.find("{TECHTREEPATH}") != value.npos || + value.find("{SCENARIOPATH}") != value.npos || + value.find("{TUTORIALPATH}") != value.npos) { -bool Properties::isValuePathVariable(const string &value) { - if(value.find("~/") != value.npos || - value.find("$HOME") != value.npos || - value.find("%%HOME%%") != value.npos || - value.find("%%USERPROFILE%%") != value.npos || - value.find("%%HOMEPATH%%") != value.npos || - value.find("{HOMEPATH}") != value.npos || - value.find("$APPDATA") != value.npos || - value.find("%%APPDATA%%") != value.npos || - value.find("{APPDATA}") != value.npos || - value.find("$APPLICATIONPATH") != value.npos || - value.find("%%APPLICATIONPATH%%") != value.npos || - value.find("{APPLICATIONPATH}") != value.npos || - value.find("$APPLICATIONDATAPATH") != value.npos || - value.find("%%APPLICATIONDATAPATH%%") != value.npos || - value.find("{APPLICATIONDATAPATH}") != value.npos || - value.find("{TECHTREEPATH}") != value.npos || - value.find("{SCENARIOPATH}") != value.npos || - value.find("{TUTORIALPATH}") != value.npos) { + return true; + } + return false; + } + void Properties::updateValuePathVariable(string &value, bool skipUpdatePathClimbingParts) { + replaceAll(value, "//", "/"); + replaceAll(value, "\\\\", "\\"); + if (skipUpdatePathClimbingParts == false) { + updatePathClimbingParts(value); + } + } + bool Properties::applyTagsToValue(string &value, const std::map *mapTagReplacementValues, bool skipUpdatePathClimbingParts) { + string originalValue = value; + bool valueRequiresPathUpdate = Properties::isValuePathVariable(value); + //if(originalValue.find("$APPLICATIONDATAPATH") != string::npos) { + // printf("\nBEFORE SUBSTITUTE [%s] app [%s] mapTagReplacementValues [%p]\n",originalValue.c_str(),Properties::applicationPath.c_str(),mapTagReplacementValues); + //} + + if (mapTagReplacementValues != NULL) { + for (std::map::const_iterator iterMap = mapTagReplacementValues->begin(); + iterMap != mapTagReplacementValues->end(); ++iterMap) { + + // if(value.find("{SCENARIOPATH}") != string::npos) { + // printf("\n\n** WILL REPLACE [%s]\n",value.c_str()); + // replaceAll(value, "{SCENARIOPATH}", Properties::scenarioPath); + // printf("** REPLACED [%s]\n\n",value.c_str()); + // } + // else { + replaceAll(value, iterMap->first, iterMap->second); + // } + } + } else { +#ifdef WIN32 + const char *homeDirX = getenv("USERPROFILE"); +#else + string home = getUserHome(); + const char *homeDirX = home.c_str(); +#endif + + string homeDir = safeCharPtrCopy(homeDirX, 8096); + + replaceAll(value, "~/", homeDir); + replaceAll(value, "$HOME", homeDir); + replaceAll(value, "%%HOME%%", homeDir); + replaceAll(value, "%%USERPROFILE%%", homeDir); + replaceAll(value, "%%HOMEPATH%%", homeDir); + replaceAll(value, "{HOMEPATH}", homeDir); + + // For win32 we allow use of the appdata variable since that is the recommended + // place for application data in windows platform +#ifdef WIN32 + TCHAR szPath[MAX_PATH]; + // Get path for each computer, non-user specific and non-roaming data. + if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, + NULL, 0, szPath))) { + //const wchar_t *wBuf = &szPath[0]; + //size_t size = MAX_PATH + 1; + //char pMBBuffer[MAX_PATH + 1]=""; + //wcstombs_s(&size, &pMBBuffer[0], (size_t)size, wBuf, (size_t)size);// Convert to char* from TCHAR[] + //string appPath=""; + //appPath.assign(&pMBBuffer[0]); // Now assign the char* to the string, and there you have it!!! :) + std::string appPath = utf8_encode(szPath); + + //string appPath = szPath; + replaceAll(value, "$APPDATA", appPath); + replaceAll(value, "%%APPDATA%%", appPath); + replaceAll(value, "{APPDATA}", appPath); + } +#endif + + //char *username = NULL; + char *username = getenv("USERNAME"); + replaceAll(value, "$USERNAME", (username != NULL ? username : "")); + replaceAll(value, "%%USERNAME%%", (username != NULL ? username : "")); + replaceAll(value, "{USERNAME}", (username != NULL ? username : "")); + + replaceAll(value, "$APPLICATIONPATH", Properties::applicationPath); + replaceAll(value, "%%APPLICATIONPATH%%", Properties::applicationPath); + replaceAll(value, "{APPLICATIONPATH}", Properties::applicationPath); + +#if defined(CUSTOM_DATA_INSTALL_PATH) + replaceAll(value, "$APPLICATIONDATAPATH", formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH))); + replaceAll(value, "%%APPLICATIONDATAPATH%%", formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH))); + replaceAll(value, "{APPLICATIONDATAPATH}", formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH))); + +#else + replaceAll(value, "$APPLICATIONDATAPATH", Properties::applicationDataPath); + replaceAll(value, "%%APPLICATIONDATAPATH%%", Properties::applicationDataPath); + replaceAll(value, "{APPLICATIONDATAPATH}", Properties::applicationDataPath); + +#endif + + replaceAll(value, "{TECHTREEPATH}", Properties::techtreePath); + // if(value.find("{SCENARIOPATH}") != string::npos) { + // printf("\n\n** WILL REPLACE [%s]\n",value.c_str()); + replaceAll(value, "{SCENARIOPATH}", Properties::scenarioPath); + // printf("** REPLACED [%s]\n\n",value.c_str()); + // } + replaceAll(value, "{TUTORIALPATH}", Properties::tutorialPath); + + replaceAll(value, "$GAMEVERSION", Properties::gameVersion); + } + + //if(originalValue != value || originalValue.find("$APPLICATIONDATAPATH") != string::npos) { + // printf("\nBEFORE SUBSTITUTE [%s] AFTER [%s]\n",originalValue.c_str(),value.c_str()); + //} + + if (valueRequiresPathUpdate == true) { + Properties::updateValuePathVariable(value, skipUpdatePathClimbingParts); + } + return (originalValue != value); + } + + void Properties::save(const string &path) { +#if defined(WIN32) && !defined(__MINGW32__) + FILE *fp = _wfopen(utf8_decode(path).c_str(), L"w"); + ofstream fileStream(fp); +#else + ofstream fileStream; + fileStream.open(path.c_str(), ios_base::out | ios_base::trunc); +#endif + fileStream << "; === propertyMap File === \n"; + fileStream << '\n'; + + for (PropertyMap::iterator pi = propertyMap.begin(); pi != propertyMap.end(); ++pi) { + fileStream << pi->first << '=' << pi->second << '\n'; + } + + fileStream.close(); +#if defined(WIN32) && !defined(__MINGW32__) + if (fp) fclose(fp); +#endif + } + + void Properties::clear() { + propertyMap.clear(); + propertyMapTmp.clear(); + propertyVector.clear(); + propertyVectorTmp.clear(); + } + + int Properties::getPropertyCount() const { + return (int) propertyVectorTmp.size(); + } + string Properties::getKey(int i) const { + return propertyVectorTmp[i].first; + } + string Properties::getString(int i) const { + return propertyVectorTmp[i].second; + } + + bool Properties::getBool(const string &key, const char *defaultValueIfNotFound) const { + try { + return strToBool(getString(key, defaultValueIfNotFound)); + } catch (exception &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what()); + //throw megaglest_runtime_error("Error accessing value: " + key + " in: " + path+"\n[" + e.what() + "]"); + throw runtime_error("Error accessing value: " + key + " in: " + path + "\n[" + e.what() + "]"); + } + return false; + } + + int Properties::getInt(const string &key, const char *defaultValueIfNotFound) const { + try { + return strToInt(getString(key, defaultValueIfNotFound)); + } catch (exception &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what()); + //throw megaglest_runtime_error("Error accessing value: " + key + " in: " + path + "\n[" + e.what() + "]"); + throw runtime_error("Error accessing value: " + key + " in: " + path + "\n[" + e.what() + "]"); + } + return 0; + } + + int Properties::getInt(const string &key, int min, int max, const char *defaultValueIfNotFound) const { + int i = getInt(key, defaultValueIfNotFound); + if (imax) { + throw megaglest_runtime_error("Value out of range: " + key + ", min: " + intToStr(min) + ", max: " + intToStr(max)); + } + return i; + } + + float Properties::getFloat(const string &key, const char *defaultValueIfNotFound) const { + float result = 0.0; + try { + result = strToFloat(getString(key, defaultValueIfNotFound)); + } catch (exception &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what()); + //throw megaglest_runtime_error("Error accessing value: " + key + " in: " + path + "\n[" + e.what() + "]"); + throw runtime_error("Error accessing value: " + key + " in: " + path + "\n[" + e.what() + "]"); + } + return result; + } + + float Properties::getFloat(const string &key, float min, float max, const char *defaultValueIfNotFound) const { + float f = getFloat(key, defaultValueIfNotFound); + if (fmax) { + throw megaglest_runtime_error("Value out of range: " + key + ", min: " + floatToStr(min, 16) + ", max: " + floatToStr(max, 16)); + } + return f; + } + + const string Properties::getString(const string &key, const char *defaultValueIfNotFound) const { + PropertyMap::const_iterator it = propertyMapTmp.find(key); + if (it == propertyMapTmp.end()) { + if (defaultValueIfNotFound != NULL) { + //printf("In [%s::%s - %d]defaultValueIfNotFound = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,defaultValueIfNotFound); + return string(defaultValueIfNotFound); + } else { + //throw megaglest_runtime_error("Value not found in propertyMap: " + key + ", loaded from: " + path); + throw runtime_error("Value not found in propertyMap: " + key + ", loaded from: " + path); + } + } else { + return (it->second != "" ? it->second : (defaultValueIfNotFound != NULL ? defaultValueIfNotFound : it->second)); + } + } + + const string Properties::getRandomKey(const bool realrandom) const { + PropertyMap::const_iterator it; + int max = getPropertyCount(); + int randomIndex = -1; + if (realrandom == true) { + Chrono seed(true); + srand((unsigned int) seed.getCurTicks()); + + randomIndex = rand() % max; + } else { + RandomGen randgen; + randomIndex = randgen.randRange(0, max); + } + string s = getKey(randomIndex); + return (s != "" ? s : "nothing found"); + } + + bool Properties::hasString(const string &key) const { + PropertyMap::const_iterator it = propertyMapTmp.find(key); + if (it == propertyMapTmp.end()) { + return false; + } return true; - } - return false; -} -void Properties::updateValuePathVariable(string &value, bool skipUpdatePathClimbingParts) { - replaceAll(value,"//","/"); - replaceAll(value,"\\\\","\\"); - if(skipUpdatePathClimbingParts == false) { - updatePathClimbingParts(value); - } -} - -bool Properties::applyTagsToValue(string &value, const std::map *mapTagReplacementValues,bool skipUpdatePathClimbingParts) { - string originalValue = value; - bool valueRequiresPathUpdate = Properties::isValuePathVariable(value); - //if(originalValue.find("$APPLICATIONDATAPATH") != string::npos) { - // printf("\nBEFORE SUBSTITUTE [%s] app [%s] mapTagReplacementValues [%p]\n",originalValue.c_str(),Properties::applicationPath.c_str(),mapTagReplacementValues); - //} - - if(mapTagReplacementValues != NULL) { - for(std::map::const_iterator iterMap = mapTagReplacementValues->begin(); - iterMap != mapTagReplacementValues->end(); ++iterMap) { - -// if(value.find("{SCENARIOPATH}") != string::npos) { -// printf("\n\n** WILL REPLACE [%s]\n",value.c_str()); -// replaceAll(value, "{SCENARIOPATH}", Properties::scenarioPath); -// printf("** REPLACED [%s]\n\n",value.c_str()); -// } -// else { - replaceAll(value, iterMap->first, iterMap->second); -// } } + + void Properties::setInt(const string &key, int value) { + setString(key, intToStr(value)); + } + + void Properties::setBool(const string &key, bool value) { + setString(key, boolToStr(value)); + } + + void Properties::setFloat(const string &key, float value) { + setString(key, floatToStr(value, 6)); + } + + void Properties::setString(const string &key, const string &value) { + propertyMap.erase(key); + propertyMap.insert(PropertyPair(key, value)); + + propertyMapTmp.erase(key); + propertyMapTmp.insert(PropertyPair(key, value)); + + } + + string Properties::toString() { + string rStr; + + for (PropertyMap::iterator pi = propertyMapTmp.begin(); pi != propertyMapTmp.end(); ++pi) + rStr += pi->first + "=" + pi->second + "\n"; + + return rStr; + } + + bool Properties::getBool(const char *key, const char *defaultValueIfNotFound) const { + try { + return strToBool(getString(key, defaultValueIfNotFound)); + } catch (exception &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what()); + //throw megaglest_runtime_error("Error accessing value: " + string(key) + " in: " + path+"\n[" + e.what() + "]"); + throw runtime_error("Error accessing value: " + string(key) + " in: " + path + "\n[" + e.what() + "]"); + } + return false; + } + + int Properties::getInt(const char *key, const char *defaultValueIfNotFound) const { + try { + return strToInt(getString(key, defaultValueIfNotFound)); + } catch (exception &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what()); + //throw megaglest_runtime_error("Error accessing value: " + string(key) + " in: " + path + "\n[" + e.what() + "]"); + throw runtime_error("Error accessing value: " + string(key) + " in: " + path + "\n[" + e.what() + "]"); + } + return 0; + } + + float Properties::getFloat(const char *key, const char *defaultValueIfNotFound) const { + float result = 0.0; + try { + result = strToFloat(getString(key, defaultValueIfNotFound)); + } catch (exception &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what()); + //throw megaglest_runtime_error("Error accessing value: " + string(key) + " in: " + path + "\n[" + e.what() + "]"); + throw runtime_error("Error accessing value: " + string(key) + " in: " + path + "\n[" + e.what() + "]"); + } + return result; + } + + const string Properties::getString(const char *key, const char *defaultValueIfNotFound) const { + PropertyMap::const_iterator it = propertyMapTmp.find(key); + if (it == propertyMapTmp.end()) { + if (defaultValueIfNotFound != NULL) { + //printf("In [%s::%s - %d]defaultValueIfNotFound = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,defaultValueIfNotFound); + return string(defaultValueIfNotFound); + } else { + //throw megaglest_runtime_error("Value not found in propertyMap: " + string(key) + ", loaded from: " + path); + throw runtime_error("Value not found in propertyMap: " + string(key) + ", loaded from: " + path); + } + } else { + return (it->second != "" ? it->second : (defaultValueIfNotFound != NULL ? defaultValueIfNotFound : it->second)); + } + } + + } - else { -#ifdef WIN32 - const char *homeDirX = getenv("USERPROFILE"); -#else - string home = getUserHome(); - const char *homeDirX = home.c_str(); -#endif - - string homeDir = safeCharPtrCopy(homeDirX, 8096); - - replaceAll(value, "~/", homeDir); - replaceAll(value, "$HOME", homeDir); - replaceAll(value, "%%HOME%%", homeDir); - replaceAll(value, "%%USERPROFILE%%",homeDir); - replaceAll(value, "%%HOMEPATH%%", homeDir); - replaceAll(value, "{HOMEPATH}", homeDir); - - // For win32 we allow use of the appdata variable since that is the recommended - // place for application data in windows platform -#ifdef WIN32 - TCHAR szPath[MAX_PATH]; - // Get path for each computer, non-user specific and non-roaming data. - if ( SUCCEEDED( SHGetFolderPath( NULL, CSIDL_APPDATA, - NULL, 0, szPath))) { - //const wchar_t *wBuf = &szPath[0]; - //size_t size = MAX_PATH + 1; - //char pMBBuffer[MAX_PATH + 1]=""; - //wcstombs_s(&size, &pMBBuffer[0], (size_t)size, wBuf, (size_t)size);// Convert to char* from TCHAR[] - //string appPath=""; - //appPath.assign(&pMBBuffer[0]); // Now assign the char* to the string, and there you have it!!! :) - std::string appPath = utf8_encode(szPath); - - //string appPath = szPath; - replaceAll(value, "$APPDATA", appPath); - replaceAll(value, "%%APPDATA%%", appPath); - replaceAll(value, "{APPDATA}", appPath); - } -#endif - - //char *username = NULL; - char *username = getenv("USERNAME"); - replaceAll(value, "$USERNAME", (username != NULL ? username : "")); - replaceAll(value, "%%USERNAME%%", (username != NULL ? username : "")); - replaceAll(value, "{USERNAME}", (username != NULL ? username : "")); - - replaceAll(value, "$APPLICATIONPATH", Properties::applicationPath); - replaceAll(value, "%%APPLICATIONPATH%%", Properties::applicationPath); - replaceAll(value, "{APPLICATIONPATH}", Properties::applicationPath); - -#if defined(CUSTOM_DATA_INSTALL_PATH) - replaceAll(value, "$APPLICATIONDATAPATH", formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH))); - replaceAll(value, "%%APPLICATIONDATAPATH%%", formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH))); - replaceAll(value, "{APPLICATIONDATAPATH}", formatPath(TOSTRING(CUSTOM_DATA_INSTALL_PATH))); - -#else - replaceAll(value, "$APPLICATIONDATAPATH", Properties::applicationDataPath); - replaceAll(value, "%%APPLICATIONDATAPATH%%", Properties::applicationDataPath); - replaceAll(value, "{APPLICATIONDATAPATH}", Properties::applicationDataPath); - -#endif - - replaceAll(value, "{TECHTREEPATH}", Properties::techtreePath); -// if(value.find("{SCENARIOPATH}") != string::npos) { -// printf("\n\n** WILL REPLACE [%s]\n",value.c_str()); - replaceAll(value, "{SCENARIOPATH}", Properties::scenarioPath); -// printf("** REPLACED [%s]\n\n",value.c_str()); -// } - replaceAll(value, "{TUTORIALPATH}", Properties::tutorialPath); - - replaceAll(value, "$GAMEVERSION", Properties::gameVersion); - } - - //if(originalValue != value || originalValue.find("$APPLICATIONDATAPATH") != string::npos) { - // printf("\nBEFORE SUBSTITUTE [%s] AFTER [%s]\n",originalValue.c_str(),value.c_str()); - //} - - if(valueRequiresPathUpdate == true) { - Properties::updateValuePathVariable(value, skipUpdatePathClimbingParts); - } - return (originalValue != value); -} - -void Properties::save(const string &path){ -#if defined(WIN32) && !defined(__MINGW32__) - FILE *fp = _wfopen(utf8_decode(path).c_str(), L"w"); - ofstream fileStream(fp); -#else - ofstream fileStream; - fileStream.open(path.c_str(), ios_base::out | ios_base::trunc); -#endif - fileStream << "; === propertyMap File === \n"; - fileStream << '\n'; - - for(PropertyMap::iterator pi= propertyMap.begin(); pi!=propertyMap.end(); ++pi){ - fileStream << pi->first << '=' << pi->second << '\n'; - } - - fileStream.close(); -#if defined(WIN32) && !defined(__MINGW32__) - if(fp) fclose(fp); -#endif -} - -void Properties::clear(){ - propertyMap.clear(); - propertyMapTmp.clear(); - propertyVector.clear(); - propertyVectorTmp.clear(); -} - -int Properties::getPropertyCount() const { - return (int)propertyVectorTmp.size(); -} -string Properties::getKey(int i) const { - return propertyVectorTmp[i].first; -} -string Properties::getString(int i) const { - return propertyVectorTmp[i].second; -} - -bool Properties::getBool(const string &key, const char *defaultValueIfNotFound) const{ - try{ - return strToBool(getString(key,defaultValueIfNotFound)); - } - catch(exception &e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what()); - //throw megaglest_runtime_error("Error accessing value: " + key + " in: " + path+"\n[" + e.what() + "]"); - throw runtime_error("Error accessing value: " + key + " in: " + path+"\n[" + e.what() + "]"); - } - return false; -} - -int Properties::getInt(const string &key,const char *defaultValueIfNotFound) const{ - try{ - return strToInt(getString(key,defaultValueIfNotFound)); - } - catch(exception &e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what()); - //throw megaglest_runtime_error("Error accessing value: " + key + " in: " + path + "\n[" + e.what() + "]"); - throw runtime_error("Error accessing value: " + key + " in: " + path + "\n[" + e.what() + "]"); - } - return 0; -} - -int Properties::getInt(const string &key, int min, int max,const char *defaultValueIfNotFound) const{ - int i= getInt(key,defaultValueIfNotFound); - if(imax){ - throw megaglest_runtime_error("Value out of range: " + key + ", min: " + intToStr(min) + ", max: " + intToStr(max)); - } - return i; -} - -float Properties::getFloat(const string &key, const char *defaultValueIfNotFound) const{ - float result = 0.0; - try{ - result = strToFloat(getString(key,defaultValueIfNotFound)); - } - catch(exception &e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what()); - //throw megaglest_runtime_error("Error accessing value: " + key + " in: " + path + "\n[" + e.what() + "]"); - throw runtime_error("Error accessing value: " + key + " in: " + path + "\n[" + e.what() + "]"); - } - return result; -} - -float Properties::getFloat(const string &key, float min, float max, const char *defaultValueIfNotFound) const{ - float f= getFloat(key,defaultValueIfNotFound); - if(fmax){ - throw megaglest_runtime_error("Value out of range: " + key + ", min: " + floatToStr(min,16) + ", max: " + floatToStr(max,16)); - } - return f; -} - -const string Properties::getString(const string &key, const char *defaultValueIfNotFound) const{ - PropertyMap::const_iterator it = propertyMapTmp.find(key); - if(it == propertyMapTmp.end()) { - if(defaultValueIfNotFound != NULL) { - //printf("In [%s::%s - %d]defaultValueIfNotFound = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,defaultValueIfNotFound); - return string(defaultValueIfNotFound); - } - else { - //throw megaglest_runtime_error("Value not found in propertyMap: " + key + ", loaded from: " + path); - throw runtime_error("Value not found in propertyMap: " + key + ", loaded from: " + path); - } - } - else{ - return (it->second != "" ? it->second : (defaultValueIfNotFound != NULL ? defaultValueIfNotFound : it->second)); - } -} - -const string Properties::getRandomKey(const bool realrandom) const{ - PropertyMap::const_iterator it; - int max=getPropertyCount(); - int randomIndex=-1; - if(realrandom == true){ - Chrono seed(true); - srand((unsigned int)seed.getCurTicks()); - - randomIndex=rand()%max; - } - else{ - RandomGen randgen; - randomIndex=randgen.randRange(0,max); - } - string s=getKey(randomIndex); - return (s != "" ? s : "nothing found"); -} - -bool Properties::hasString(const string &key) const { - PropertyMap::const_iterator it = propertyMapTmp.find(key); - if(it == propertyMapTmp.end()) { - return false; - } - return true; -} - -void Properties::setInt(const string &key, int value){ - setString(key, intToStr(value)); -} - -void Properties::setBool(const string &key, bool value){ - setString(key, boolToStr(value)); -} - -void Properties::setFloat(const string &key, float value){ - setString(key, floatToStr(value,6)); -} - -void Properties::setString(const string &key, const string &value){ - propertyMap.erase(key); - propertyMap.insert(PropertyPair(key, value)); - - propertyMapTmp.erase(key); - propertyMapTmp.insert(PropertyPair(key, value)); - -} - -string Properties::toString(){ - string rStr; - - for(PropertyMap::iterator pi= propertyMapTmp.begin(); pi!=propertyMapTmp.end(); ++pi) - rStr+= pi->first + "=" + pi->second + "\n"; - - return rStr; -} - -bool Properties::getBool(const char *key, const char *defaultValueIfNotFound) const{ - try{ - return strToBool(getString(key,defaultValueIfNotFound)); - } - catch(exception &e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what()); - //throw megaglest_runtime_error("Error accessing value: " + string(key) + " in: " + path+"\n[" + e.what() + "]"); - throw runtime_error("Error accessing value: " + string(key) + " in: " + path+"\n[" + e.what() + "]"); - } - return false; -} - -int Properties::getInt(const char *key,const char *defaultValueIfNotFound) const{ - try{ - return strToInt(getString(key,defaultValueIfNotFound)); - } - catch(exception &e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what()); - //throw megaglest_runtime_error("Error accessing value: " + string(key) + " in: " + path + "\n[" + e.what() + "]"); - throw runtime_error("Error accessing value: " + string(key) + " in: " + path + "\n[" + e.what() + "]"); - } - return 0; -} - -float Properties::getFloat(const char *key, const char *defaultValueIfNotFound) const{ - float result = 0.0; - try{ - result = strToFloat(getString(key,defaultValueIfNotFound)); - } - catch(exception &e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what()); - //throw megaglest_runtime_error("Error accessing value: " + string(key) + " in: " + path + "\n[" + e.what() + "]"); - throw runtime_error("Error accessing value: " + string(key) + " in: " + path + "\n[" + e.what() + "]"); - } - return result; -} - -const string Properties::getString(const char *key, const char *defaultValueIfNotFound) const{ - PropertyMap::const_iterator it = propertyMapTmp.find(key); - if(it == propertyMapTmp.end()) { - if(defaultValueIfNotFound != NULL) { - //printf("In [%s::%s - %d]defaultValueIfNotFound = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,defaultValueIfNotFound); - return string(defaultValueIfNotFound); - } - else { - //throw megaglest_runtime_error("Value not found in propertyMap: " + string(key) + ", loaded from: " + path); - throw runtime_error("Value not found in propertyMap: " + string(key) + ", loaded from: " + path); - } - } - else{ - return (it->second != "" ? it->second : (defaultValueIfNotFound != NULL ? defaultValueIfNotFound : it->second)); - } -} - - -}}//end namepsace +}//end namepsace diff --git a/source/shared_lib/sources/util/randomgen.cpp b/source/shared_lib/sources/util/randomgen.cpp index f2608b898..4a0de4d42 100644 --- a/source/shared_lib/sources/util/randomgen.cpp +++ b/source/shared_lib/sources/util/randomgen.cpp @@ -21,89 +21,91 @@ using namespace std; using namespace Shared::Graphics; -namespace Shared { namespace Util { +namespace Shared { + namespace Util { -// ===================================================== -// class RandomGen -// ===================================================== + // ===================================================== + // class RandomGen + // ===================================================== -const int RandomGen::m= 714025; -const int RandomGen::a= 1366; -const int RandomGen::b= 150889; + const int RandomGen::m = 714025; + const int RandomGen::a = 1366; + const int RandomGen::b = 150889; -RandomGen::RandomGen() { - lastNumber= 0; - disableLastCallerTracking = false; -} - -void RandomGen::init(int seed){ - lastNumber= seed % m; -} - -int RandomGen::rand(string lastCaller) { - if(lastCaller != "") { - this->lastCaller.push_back(lastCaller); - } - this->lastNumber = (a*lastNumber + b) % m; - return lastNumber; -} - -std::string RandomGen::getLastCaller() const { - std::string result = ""; - if(lastCaller.empty() == false) { - for(unsigned int index = 0; index < lastCaller.size(); ++index) { - result += lastCaller[index] + "|"; + RandomGen::RandomGen() { + lastNumber = 0; + disableLastCallerTracking = false; } - } - return result; -} -void RandomGen::clearLastCaller() { - if(lastCaller.empty() == false) { - lastCaller.clear(); - } -} -void RandomGen::addLastCaller(std::string text) { - if(disableLastCallerTracking == false) { - lastCaller.push_back(text); - } -} + void RandomGen::init(int seed) { + lastNumber = seed % m; + } + + int RandomGen::rand(string lastCaller) { + if (lastCaller != "") { + this->lastCaller.push_back(lastCaller); + } + this->lastNumber = (a*lastNumber + b) % m; + return lastNumber; + } + + std::string RandomGen::getLastCaller() const { + std::string result = ""; + if (lastCaller.empty() == false) { + for (unsigned int index = 0; index < lastCaller.size(); ++index) { + result += lastCaller[index] + "|"; + } + } + return result; + } + + void RandomGen::clearLastCaller() { + if (lastCaller.empty() == false) { + lastCaller.clear(); + } + } + void RandomGen::addLastCaller(std::string text) { + if (disableLastCallerTracking == false) { + lastCaller.push_back(text); + } + } + + int RandomGen::randRange(int min, int max, string lastCaller) { + if (min > max) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] min > max, min = %d, max = %d", __FILE__, __FUNCTION__, __LINE__, min, max); + throw megaglest_runtime_error(szBuf); + } + + int diff = max - min; + float numerator = static_cast(diff + 1) * static_cast(this->rand(lastCaller)); + int res = min + static_cast(truncateDecimal(numerator / static_cast(m), 6)); + if (res < min || res > max) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] res < min || res > max, min = %d, max = %d, res = %d", __FILE__, __FUNCTION__, __LINE__, min, max, res); + throw megaglest_runtime_error(szBuf); + } + return res; + } + + float RandomGen::randRange(float min, float max, string lastCaller) { + if (min > max) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] min > max, min = %f, max = %f", __FILE__, __FUNCTION__, __LINE__, min, max); + throw megaglest_runtime_error(szBuf); + } + + float rand01 = static_cast(this->rand(lastCaller)) / (m - 1); + float res = min + (max - min) * rand01; + res = truncateDecimal(res, 6); + + if (res < min || res > max) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] res < min || res > max, min = %f, max = %f, res = %f", __FILE__, __FUNCTION__, __LINE__, min, max, res); + throw megaglest_runtime_error(szBuf); + } + return res; + } -int RandomGen::randRange(int min, int max,string lastCaller) { - if(min > max) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] min > max, min = %d, max = %d",__FILE__,__FUNCTION__,__LINE__,min,max); - throw megaglest_runtime_error(szBuf); } - - int diff= max-min; - float numerator = static_cast(diff + 1) * static_cast(this->rand(lastCaller)); - int res= min + static_cast(truncateDecimal(numerator / static_cast(m),6)); - if(res < min || res > max) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] res < min || res > max, min = %d, max = %d, res = %d",__FILE__,__FUNCTION__,__LINE__,min,max,res); - throw megaglest_runtime_error(szBuf); - } - return res; -} - -float RandomGen::randRange(float min, float max,string lastCaller) { - if(min > max) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] min > max, min = %f, max = %f",__FILE__,__FUNCTION__,__LINE__,min,max); - throw megaglest_runtime_error(szBuf); - } - - float rand01 = static_cast(this->rand(lastCaller)) / (m-1); - float res= min + (max - min) * rand01; - res = truncateDecimal(res,6); - - if(res < min || res > max) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] res < min || res > max, min = %f, max = %f, res = %f",__FILE__,__FUNCTION__,__LINE__,min,max,res); - throw megaglest_runtime_error(szBuf); - } - return res; -} - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/util/string_utils.cpp b/source/shared_lib/sources/util/string_utils.cpp index e0bc8d60f..666656bc1 100644 --- a/source/shared_lib/sources/util/string_utils.cpp +++ b/source/shared_lib/sources/util/string_utils.cpp @@ -1,19 +1,19 @@ /* Portions taken from: - Copyright (C) 2005 Roland BROCHARD + Copyright (C) 2005 Roland BROCHARD - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "string_utils.h" @@ -21,319 +21,306 @@ #include #include -namespace Shared { namespace Util { +namespace Shared { + namespace Util { #ifndef WIN32 - int ASCIItoUTF8(const Shared::Platform::byte c, Shared::Platform::byte *out) { + int ASCIItoUTF8(const Shared::Platform::byte c, Shared::Platform::byte *out) { #else - int ASCIItoUTF8(const byte c, byte *out) { + int ASCIItoUTF8(const byte c, byte *out) { #endif - if (c < 0x80) { - *out = c; - return 1; - } - else if(c < 0xC0) { - out[0] = 0xC2; - out[1] = c; - return 2; - } - out[0] = 0xC3; - out[1] = c - 0x40; - return 2; - } - - char* ConvertToUTF8(const char* s, Shared::Platform::uint32 len, Shared::Platform::uint32& newSize) { - if (NULL == s || '\0' == *s) { - char* ret = new char[1]; - //LOG_ASSERT(NULL != ret); - assert(NULL != ret); - *ret = '\0'; - return ret; - } -#ifndef WIN32 - Shared::Platform::byte tmp[4]; -#else - byte tmp[4]; -#endif - newSize = 1; - -#ifndef WIN32 - for(Shared::Platform::byte *p = (Shared::Platform::byte*)s ; *p ; p++) -#else - for(byte *p = (byte*)s ; *p ; p++) -#endif - newSize += ASCIItoUTF8(*p, tmp); - - char* ret = new char[newSize]; - //LOG_ASSERT(NULL != ret); - assert(NULL != ret); - -#ifndef WIN32 - Shared::Platform::byte *q = (Shared::Platform::byte*)ret; - for(Shared::Platform::byte *p = (Shared::Platform::byte*)s ; *p ; p++) -#else - byte *q = (byte*)ret; - for(byte *p = (byte*)s ; *p ; p++) - -#endif - q += ASCIItoUTF8(*p, q); - *q = '\0'; // A bit paranoid - return ret; - } - - char* ConvertToUTF8(const char* s, const Shared::Platform::uint32 len) { - Shared::Platform::uint32 nws; - return ConvertToUTF8(s, len, nws); - } - - char* ConvertToUTF8(const char* s) { - if (NULL != s && *s != '\0') - return ConvertToUTF8(s, (Shared::Platform::uint32)strlen(s)); - char* ret = new char[1]; - //LOG_ASSERT(NULL != ret); - assert(NULL != ret); - *ret = '\0'; - return ret; - } - - - char* ConvertFromUTF8(const char* str) { - const unsigned char *in = reinterpret_cast(str); - int len = (int)strlen(str); - char *out = new char[len*8]; - memset(out,0,len*8); - int outc; - int inpos = 0; - int outpos = 0; - while (inpos < len) { - if (in[inpos]<0x80) { - out[outpos++] = in[inpos]; - if (in[inpos] == 0 && len == -1) - break; - inpos++; - } - else if (in[inpos]<0xE0) { - // Shouldn't happen. - if(in[inpos]<0xC0 || (len!=-1 && inpos+1 >= len) || - (in[inpos+1]&0xC0)!= 0x80) { - out[outpos++] = '?'; - inpos++; - continue; - } - outc = ((((wchar_t)in[inpos])&0x1F)<<6) | - (((wchar_t)in[inpos+1])&0x3F); - if (outc < 256) - out[outpos] = ((char*)&outc)[0]; - else - out[outpos] = '?'; - outpos++; - inpos+=2; - } - else if (in[inpos]<0xF0) { - // Shouldn't happen. - if ((len!=-1 && inpos+2 >= len) || - (in[inpos+1]&0xC0)!= 0x80 || - (in[inpos+2]&0xC0)!= 0x80) { - out[outpos++] = '?'; - inpos++; - continue; - } - out[outpos++] = '?'; - inpos+=3; - } - else if (in[inpos]<0xF8) { - // Shouldn't happen. - if ((len!=-1 && inpos+3 >= len) || - (in[inpos+1]&0xC0)!= 0x80 || - (in[inpos+2]&0xC0)!= 0x80 || - (in[inpos+3]&0xC0)!= 0x80) { - out[outpos++] = '?'; - inpos++; - continue; - } - out[outpos++] = '?'; - inpos+=4; - } - else { - out[outpos++] = '?'; - inpos++; - } + if (c < 0x80) { + *out = c; + return 1; + } else if (c < 0xC0) { + out[0] = 0xC2; + out[1] = c; + return 2; + } + out[0] = 0xC3; + out[1] = c - 0x40; + return 2; } - return out; - } - WString::WString(const char* s) - { - if (s) - fromUtf8(s, strlen(s)); - else - pBuffer[0] = 0; - } - - WString::WString(const std::string& s) - { - fromUtf8(s.c_str(), s.size()); - } - - void WString::fromUtf8(const char* str, size_t length) - { - int len = 0; - for(unsigned int i = 0 ; i < length; i++) - { -#ifndef WIN32 - if (((Shared::Platform::byte)str[i]) < 0x80) -#else - if (((byte)str[i]) < 0x80) -#endif - { -#ifndef WIN32 - pBuffer[len++] = ((Shared::Platform::byte)str[i]); -#else - pBuffer[len++] = ((byte)str[i]); -#endif - continue; + char* ConvertToUTF8(const char* s, Shared::Platform::uint32 len, Shared::Platform::uint32& newSize) { + if (NULL == s || '\0' == *s) { + char* ret = new char[1]; + //LOG_ASSERT(NULL != ret); + assert(NULL != ret); + *ret = '\0'; + return ret; } #ifndef WIN32 - if (((Shared::Platform::byte)str[i]) >= 0xC0) - { - wchar_t c = ((Shared::Platform::byte)str[i++]) - 0xC0; - while(((Shared::Platform::byte)str[i]) >= 0x80) - c = (c << 6) | (((Shared::Platform::byte)str[i++]) - 0x80); + Shared::Platform::byte tmp[4]; #else - if (((byte)str[i]) >= 0xC0) - { - wchar_t c = ((byte)str[i++]) - 0xC0; - while(((byte)str[i]) >= 0x80) - c = (c << 6) | (((byte)str[i++]) - 0x80); + byte tmp[4]; +#endif + newSize = 1; + +#ifndef WIN32 + for (Shared::Platform::byte *p = (Shared::Platform::byte*)s; *p; p++) +#else + for (byte *p = (byte*) s; *p; p++) +#endif + newSize += ASCIItoUTF8(*p, tmp); + + char* ret = new char[newSize]; + //LOG_ASSERT(NULL != ret); + assert(NULL != ret); + +#ifndef WIN32 + Shared::Platform::byte *q = (Shared::Platform::byte*)ret; + for (Shared::Platform::byte *p = (Shared::Platform::byte*)s; *p; p++) +#else + byte *q = (byte*) ret; + for (byte *p = (byte*) s; *p; p++) + +#endif + q += ASCIItoUTF8(*p, q); + *q = '\0'; // A bit paranoid + return ret; + } + + char* ConvertToUTF8(const char* s, const Shared::Platform::uint32 len) { + Shared::Platform::uint32 nws; + return ConvertToUTF8(s, len, nws); + } + + char* ConvertToUTF8(const char* s) { + if (NULL != s && *s != '\0') + return ConvertToUTF8(s, (Shared::Platform::uint32)strlen(s)); + char* ret = new char[1]; + //LOG_ASSERT(NULL != ret); + assert(NULL != ret); + *ret = '\0'; + return ret; + } + + + char* ConvertFromUTF8(const char* str) { + const unsigned char *in = reinterpret_cast(str); + int len = (int) strlen(str); + char *out = new char[len * 8]; + memset(out, 0, len * 8); + int outc; + int inpos = 0; + int outpos = 0; + while (inpos < len) { + if (in[inpos] < 0x80) { + out[outpos++] = in[inpos]; + if (in[inpos] == 0 && len == -1) + break; + inpos++; + } else if (in[inpos] < 0xE0) { + // Shouldn't happen. + if (in[inpos] < 0xC0 || (len != -1 && inpos + 1 >= len) || + (in[inpos + 1] & 0xC0) != 0x80) { + out[outpos++] = '?'; + inpos++; + continue; + } + outc = ((((wchar_t) in[inpos]) & 0x1F) << 6) | + (((wchar_t) in[inpos + 1]) & 0x3F); + if (outc < 256) + out[outpos] = ((char*) &outc)[0]; + else + out[outpos] = '?'; + outpos++; + inpos += 2; + } else if (in[inpos] < 0xF0) { + // Shouldn't happen. + if ((len != -1 && inpos + 2 >= len) || + (in[inpos + 1] & 0xC0) != 0x80 || + (in[inpos + 2] & 0xC0) != 0x80) { + out[outpos++] = '?'; + inpos++; + continue; + } + out[outpos++] = '?'; + inpos += 3; + } else if (in[inpos] < 0xF8) { + // Shouldn't happen. + if ((len != -1 && inpos + 3 >= len) || + (in[inpos + 1] & 0xC0) != 0x80 || + (in[inpos + 2] & 0xC0) != 0x80 || + (in[inpos + 3] & 0xC0) != 0x80) { + out[outpos++] = '?'; + inpos++; + continue; + } + out[outpos++] = '?'; + inpos += 4; + } else { + out[outpos++] = '?'; + inpos++; + } + } + return out; + } + + WString::WString(const char* s) { + if (s) + fromUtf8(s, strlen(s)); + else + pBuffer[0] = 0; + } + + WString::WString(const std::string& s) { + fromUtf8(s.c_str(), s.size()); + } + + void WString::fromUtf8(const char* str, size_t length) { + int len = 0; + for (unsigned int i = 0; i < length; i++) { +#ifndef WIN32 + if (((Shared::Platform::byte)str[i]) < 0x80) +#else + if (((byte) str[i]) < 0x80) +#endif + { +#ifndef WIN32 + pBuffer[len++] = ((Shared::Platform::byte)str[i]); +#else + pBuffer[len++] = ((byte) str[i]); +#endif + continue; + } +#ifndef WIN32 + if (((Shared::Platform::byte)str[i]) >= 0xC0) { + wchar_t c = ((Shared::Platform::byte)str[i++]) - 0xC0; + while (((Shared::Platform::byte)str[i]) >= 0x80) + c = (c << 6) | (((Shared::Platform::byte)str[i++]) - 0x80); +#else + if (((byte) str[i]) >= 0xC0) { + wchar_t c = ((byte) str[i++]) - 0xC0; + while (((byte) str[i]) >= 0x80) + c = (c << 6) | (((byte) str[i++]) - 0x80); #endif - --i; - pBuffer[len++] = c; - continue; + --i; + pBuffer[len++] = c; + continue; + } + } + pBuffer[len] = 0; + } + + + void strrev(char *p) { + if (p != NULL) { + char *q = p; + while (q && *q) ++q; + for (--q; p < q; ++p, --q) + *p = *p ^ *q, + *q = *p ^ *q, + *p = *p ^ *q; } } - pBuffer[len] = 0; - } +#define SWP(x,y) (x^=y, y^=x, x^=y) - void strrev(char *p) { - if(p != NULL) { - char *q = p; - while(q && *q) ++q; - for(--q; p < q; ++p, --q) - *p = *p ^ *q, - *q = *p ^ *q, - *p = *p ^ *q; - } - } - - #define SWP(x,y) (x^=y, y^=x, x^=y) - - void strrev_utf8(char *p) { - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - - char *q = p; - strrev(p); /* call base case */ - - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - - /* Ok, now fix bass-ackwards UTF chars. */ - while(q && *q) ++q; /* find eos */ - - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - while(p < --q) { - //printf("In [%s::%s] Line: %d p [%s] q [%s]\n",__FILE__,__FUNCTION__,__LINE__,p,q); fflush(stdout); - - switch( (*q & 0xF0) >> 4 ) { - case 0xF: /* U+010000-U+10FFFF: four bytes. */ - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - SWP(*(q-0), *(q-3)); - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - SWP(*(q-1), *(q-2)); - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - q -= 3; - break; - case 0xE: /* U+000800-U+00FFFF: three bytes. */ - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - SWP(*(q-0), *(q-2)); - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - q -= 2; - break; - case 0xC: /* fall-through */ - case 0xD: /* U+000080-U+0007FF: two bytes. */ - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - SWP(*(q-0), *(q-1)); - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - q--; - break; - } - - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - } - //printf("In [%s::%s] Line: %d p [%s]\n",__FILE__,__FUNCTION__,__LINE__,p); fflush(stdout); - } - - void strrev_utf8(std::string &p) { - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - - if(p.length() > 0) { + void strrev_utf8(char *p) { //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - int bufSize = (int)p.length()*4; - char *szBuf = new char[bufSize]; - memset(szBuf,0,bufSize); - strcpy(szBuf,p.c_str()); - //szBuf[bufSize] = '\0'; - strrev_utf8(szBuf); - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - p = std::string(szBuf); - - //printf("In [%s::%s] Line: %d bufSize = %d p.size() = %d p [%s]\n",__FILE__,__FUNCTION__,__LINE__,bufSize,p.length(),p.c_str()); fflush(stdout); - - delete [] szBuf; + char *q = p; + strrev(p); /* call base case */ //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - } - //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - } - bool is_string_all_ascii(std::string str) { - bool result = true; - for(unsigned int i = 0; i < str.length(); ++i) { - if(isascii(str[i]) == false) { - result = false; - break; + /* Ok, now fix bass-ackwards UTF chars. */ + while (q && *q) ++q; /* find eos */ + + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); + while (p < --q) { + //printf("In [%s::%s] Line: %d p [%s] q [%s]\n",__FILE__,__FUNCTION__,__LINE__,p,q); fflush(stdout); + + switch ((*q & 0xF0) >> 4) { + case 0xF: /* U+010000-U+10FFFF: four bytes. */ + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); + SWP(*(q - 0), *(q - 3)); + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); + SWP(*(q - 1), *(q - 2)); + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); + q -= 3; + break; + case 0xE: /* U+000800-U+00FFFF: three bytes. */ + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); + SWP(*(q - 0), *(q - 2)); + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); + q -= 2; + break; + case 0xC: /* fall-through */ + case 0xD: /* U+000080-U+0007FF: two bytes. */ + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); + SWP(*(q - 0), *(q - 1)); + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); + q--; + break; + } + + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); } - } - return result; - } - - int getUTF8_Width(const char *str) { - int ewidth = 0; - const unsigned char *s = (const unsigned char *)str; - if (!str) { - return 0; - } - if(*s <= 0x7F) { - ewidth = 0; - } - else if (0xC2 <= *s && *s <= 0xDF) { - ewidth = 1; - } - else if (0xE0 <= *s && *s <= 0xEF) { - ewidth = 2; - } - else if (0xF0 <= *s && *s <= 0xF4) { - ewidth = 3; - } - else { - ewidth = 0; + //printf("In [%s::%s] Line: %d p [%s]\n",__FILE__,__FUNCTION__,__LINE__,p); fflush(stdout); } - for ( ; *s && ewidth > 0; s++, ewidth--); + void strrev_utf8(std::string &p) { + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); - return s - (const unsigned char *)str + 1; - } + if (p.length() > 0) { + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); -}} + int bufSize = (int) p.length() * 4; + char *szBuf = new char[bufSize]; + memset(szBuf, 0, bufSize); + strcpy(szBuf, p.c_str()); + //szBuf[bufSize] = '\0'; + strrev_utf8(szBuf); + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); + p = std::string(szBuf); + + //printf("In [%s::%s] Line: %d bufSize = %d p.size() = %d p [%s]\n",__FILE__,__FUNCTION__,__LINE__,bufSize,p.length(),p.c_str()); fflush(stdout); + + delete[] szBuf; + + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); + } + //printf("In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); fflush(stdout); + } + + bool is_string_all_ascii(std::string str) { + bool result = true; + for (unsigned int i = 0; i < str.length(); ++i) { + if (isascii(str[i]) == false) { + result = false; + break; + } + } + return result; + } + + int getUTF8_Width(const char *str) { + int ewidth = 0; + const unsigned char *s = (const unsigned char *) str; + if (!str) { + return 0; + } + if (*s <= 0x7F) { + ewidth = 0; + } else if (0xC2 <= *s && *s <= 0xDF) { + ewidth = 1; + } else if (0xE0 <= *s && *s <= 0xEF) { + ewidth = 2; + } else if (0xF0 <= *s && *s <= 0xF4) { + ewidth = 3; + } else { + ewidth = 0; + } + + for (; *s && ewidth > 0; s++, ewidth--); + + return s - (const unsigned char *) str + 1; + } + + } + } diff --git a/source/shared_lib/sources/util/util.cpp b/source/shared_lib/sources/util/util.cpp index 1674c80ca..89010dbf4 100644 --- a/source/shared_lib/sources/util/util.cpp +++ b/source/shared_lib/sources/util/util.cpp @@ -21,9 +21,9 @@ #include // for open() #ifdef WIN32 - #include // for open() +#include // for open() #else - #include +#include #endif #include // for open() @@ -43,1030 +43,1007 @@ using namespace Shared::Platform; using namespace Shared::PlatformCommon; using namespace Shared::Util; -namespace Shared{ namespace Util{ +namespace Shared { + namespace Util { -bool GlobalStaticFlags::isNonGraphicalMode = false; -uint64 GlobalStaticFlags::flags = gsft_none; + bool GlobalStaticFlags::isNonGraphicalMode = false; + uint64 GlobalStaticFlags::flags = gsft_none; -// Init statics -std::map *SystemFlags::debugLogFileList = NULL; -int SystemFlags::lockFile = -1; -int SystemFlags::lockFileCountIndex = -1; -string SystemFlags::lockfilename = ""; -bool SystemFlags::haveSpecialOutputCommandLineOption = false; -CURL *SystemFlags::curl_handle = NULL; -bool SystemFlags::curl_global_init_called = false; -int SystemFlags::DEFAULT_HTTP_TIMEOUT = 10; -bool SystemFlags::VERBOSE_MODE_ENABLED = false; -bool SystemFlags::ENABLE_THREADED_LOGGING = false; -static LogFileThread *threadLogger = NULL; -bool SystemFlags::SHUTDOWN_PROGRAM_MODE = false; -// + // Init statics + std::map *SystemFlags::debugLogFileList = NULL; + int SystemFlags::lockFile = -1; + int SystemFlags::lockFileCountIndex = -1; + string SystemFlags::lockfilename = ""; + bool SystemFlags::haveSpecialOutputCommandLineOption = false; + CURL *SystemFlags::curl_handle = NULL; + bool SystemFlags::curl_global_init_called = false; + int SystemFlags::DEFAULT_HTTP_TIMEOUT = 10; + bool SystemFlags::VERBOSE_MODE_ENABLED = false; + bool SystemFlags::ENABLE_THREADED_LOGGING = false; + static LogFileThread *threadLogger = NULL; + bool SystemFlags::SHUTDOWN_PROGRAM_MODE = false; + // -static void *myrealloc(void *ptr, size_t size) -{ - /* There might be a realloc() out there that doesn't like reallocing - NULL pointers, so we take care of it here */ - if(ptr) - return realloc(ptr, size); - else - return malloc(size); -} - -bool SystemFlags::getThreadedLoggerRunning() { - return (threadLogger != NULL && threadLogger->getRunningStatus() == true); -} - -std::size_t SystemFlags::getLogEntryBufferCount() { - std::size_t ret = 0; - if(threadLogger != NULL && threadLogger->getRunningStatus() == true) { - ret = threadLogger->getLogEntryBufferCount(); - } - return ret; -} - -size_t SystemFlags::httpWriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data) -{ - size_t realsize = size * nmemb; - struct httpMemoryStruct *mem = (struct httpMemoryStruct *)data; - - mem->memory = (char *)myrealloc(mem->memory, mem->size + realsize + 1); - if (mem->memory) { - memcpy(&(mem->memory[mem->size]), ptr, realsize); - mem->size += realsize; - mem->memory[mem->size] = 0; - } - return realsize; -} - -std::string SystemFlags::escapeURL(std::string URL, CURL *handle) { - string result = URL; - - if(handle == NULL) { - handle = SystemFlags::curl_handle; - } - char *escaped=curl_easy_escape(handle,URL.c_str(),0); - if(escaped != NULL) { - result = escaped; - curl_free(escaped); - } - return result; -} - -std::string SystemFlags::getHTTP(std::string URL,CURL *handle,int timeOut,CURLcode *savedResult) { - if(handle == NULL) { - handle = SystemFlags::curl_handle; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(handle, CURLOPT_URL, URL.c_str()); - - /* send all data to this function */ - curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, SystemFlags::httpWriteMemoryCallback); - - struct SystemFlags::httpMemoryStruct chunk; - chunk.memory=NULL; /* we expect realloc(NULL, size) to work */ - chunk.size = 0; /* no data at this point */ - - /* we pass our 'chunk' struct to the callback function */ - curl_easy_setopt(handle, CURLOPT_WRITEDATA, (void *)&chunk); - - /* some servers don't like requests that are made without a user-agent - field, so we provide one */ - curl_easy_setopt(handle, CURLOPT_USERAGENT, "zetaglest-agent/1.0"); - - /* follow HTTP redirects (status 3xx), 20 at most */ - curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1); - curl_easy_setopt(handle, CURLOPT_MAXREDIRS, 20); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] handle = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,handle); - - if(getSystemSettingType(SystemFlags::debugNetwork).enabled == true) { - curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - char errbuf[CURL_ERROR_SIZE]=""; - curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, errbuf); - - // max X seconds to connect to the URL - if(timeOut < 0) { - timeOut = SystemFlags::DEFAULT_HTTP_TIMEOUT; - } - curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, timeOut); - - /* get contents from the URL */ - CURLcode result = curl_easy_perform(handle); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CURL result = %d\n",result); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CURL errbuf [%s]\n",errbuf); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] return code [%d] [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result,errbuf); - - std::string serverResponse = (chunk.memory != NULL ? chunk.memory : ""); - if(chunk.memory) { - free(chunk.memory); - } - - if(savedResult != NULL) { - *savedResult = result; - } - if(result != CURLE_OK) { - serverResponse = errbuf; - } - - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] serverResponse [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,serverResponse.c_str()); - - return serverResponse; -} - -CURL *SystemFlags::initHTTP() { - if(SystemFlags::curl_global_init_called == false) { - SystemFlags::curl_global_init_called = true; - //printf("HTTP init\n"); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] calling curl_global_init\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] calling curl_global_init\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - CURLcode result = curl_global_init(CURL_GLOBAL_ALL); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] curl_global_init called and returned: result %d [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result,curl_easy_strerror(result)); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] curl_global_init called and returned: result %d [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result,curl_easy_strerror(result)); - //printf("In [%s::%s Line %d] curl_global_init called and returned: result %d [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result,curl_easy_strerror(result)); - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] calling curl_easy_init\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] calling curl_easy_init\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - CURL *handle = curl_easy_init(); - if(handle == NULL) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] ERROR handle = NULL\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] ERROR handle = NULL\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] handle = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,handle); - curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1); - curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] handle = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,handle); - return handle; -} - -void SystemFlags::globalCleanupHTTP() { - - if(curl_handle != NULL) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - SystemFlags::cleanupHTTP(&curl_handle, true); - curl_handle = NULL; - } - - if(SystemFlags::curl_global_init_called == true) { - SystemFlags::curl_global_init_called = false; - //printf("HTTP cleanup\n"); - curl_global_cleanup(); - //printf("In [%s::%s Line %d] curl_global_cleanup called\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } -} - -SystemFlags::SystemFlagsType * SystemFlags::setupRequiredMembers() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true) { - //throw megaglest_runtime_error("threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true"); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ERROR threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //static SystemFlagsType *result = new SystemFlagsType(); - static SystemFlags::SystemFlagsType result; - result.enabled = SystemFlags::VERBOSE_MODE_ENABLED; - return &result; - } - else { - SystemFlags::init(false); - return NULL; - } -} - -void SystemFlags::init(bool haveSpecialOutputCommandLineOption) { - SystemFlags::haveSpecialOutputCommandLineOption = haveSpecialOutputCommandLineOption; - if(SystemFlags::debugLogFileList == NULL) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true) { - //throw megaglest_runtime_error("threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true"); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ERROR threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - return; + static void *myrealloc(void *ptr, size_t size) { + /* There might be a realloc() out there that doesn't like reallocing + NULL pointers, so we take care of it here */ + if (ptr) + return realloc(ptr, size); + else + return malloc(size); } - SystemFlags::debugLogFileList = new std::map(); + bool SystemFlags::getThreadedLoggerRunning() { + return (threadLogger != NULL && threadLogger->getRunningStatus() == true); + } - (*SystemFlags::debugLogFileList)[SystemFlags::debugSystem] = SystemFlags::SystemFlagsType(SystemFlags::debugSystem); - (*SystemFlags::debugLogFileList)[SystemFlags::debugNetwork] = SystemFlags::SystemFlagsType(SystemFlags::debugNetwork); - (*SystemFlags::debugLogFileList)[SystemFlags::debugPerformance] = SystemFlags::SystemFlagsType(SystemFlags::debugPerformance); - (*SystemFlags::debugLogFileList)[SystemFlags::debugWorldSynch] = SystemFlags::SystemFlagsType(SystemFlags::debugWorldSynch); - (*SystemFlags::debugLogFileList)[SystemFlags::debugUnitCommands] = SystemFlags::SystemFlagsType(SystemFlags::debugUnitCommands); - (*SystemFlags::debugLogFileList)[SystemFlags::debugPathFinder] = SystemFlags::SystemFlagsType(SystemFlags::debugPathFinder); - (*SystemFlags::debugLogFileList)[SystemFlags::debugLUA] = SystemFlags::SystemFlagsType(SystemFlags::debugLUA); - (*SystemFlags::debugLogFileList)[SystemFlags::debugSound] = SystemFlags::SystemFlagsType(SystemFlags::debugSound); - (*SystemFlags::debugLogFileList)[SystemFlags::debugError] = SystemFlags::SystemFlagsType(SystemFlags::debugError); - } + std::size_t SystemFlags::getLogEntryBufferCount() { + std::size_t ret = 0; + if (threadLogger != NULL && threadLogger->getRunningStatus() == true) { + ret = threadLogger->getLogEntryBufferCount(); + } + return ret; + } - if(threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == false) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - threadLogger = new LogFileThread(); - threadLogger->start(); - sleep(1); - } + size_t SystemFlags::httpWriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data) { + size_t realsize = size * nmemb; + struct httpMemoryStruct *mem = (struct httpMemoryStruct *)data; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + mem->memory = (char *) myrealloc(mem->memory, mem->size + realsize + 1); + if (mem->memory) { + memcpy(&(mem->memory[mem->size]), ptr, realsize); + mem->size += realsize; + mem->memory[mem->size] = 0; + } + return realsize; + } - if(curl_handle == NULL) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + std::string SystemFlags::escapeURL(std::string URL, CURL *handle) { + string result = URL; - curl_handle = SystemFlags::initHTTP(); + if (handle == NULL) { + handle = SystemFlags::curl_handle; + } + char *escaped = curl_easy_escape(handle, URL.c_str(), 0); + if (escaped != NULL) { + result = escaped; + curl_free(escaped); + } + return result; + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] curl_handle = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,curl_handle); - } -} + std::string SystemFlags::getHTTP(std::string URL, CURL *handle, int timeOut, CURLcode *savedResult) { + if (handle == NULL) { + handle = SystemFlags::curl_handle; + } -inline bool acquire_file_lock(int hnd) -{ + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(handle, CURLOPT_URL, URL.c_str()); + + /* send all data to this function */ + curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, SystemFlags::httpWriteMemoryCallback); + + struct SystemFlags::httpMemoryStruct chunk; + chunk.memory = NULL; /* we expect realloc(NULL, size) to work */ + chunk.size = 0; /* no data at this point */ + + /* we pass our 'chunk' struct to the callback function */ + curl_easy_setopt(handle, CURLOPT_WRITEDATA, (void *) &chunk); + + /* some servers don't like requests that are made without a user-agent + field, so we provide one */ + curl_easy_setopt(handle, CURLOPT_USERAGENT, "zetaglest-agent/1.0"); + + /* follow HTTP redirects (status 3xx), 20 at most */ + curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(handle, CURLOPT_MAXREDIRS, 20); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d] handle = %p\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, handle); + + if (getSystemSettingType(SystemFlags::debugNetwork).enabled == true) { + curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + char errbuf[CURL_ERROR_SIZE] = ""; + curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, errbuf); + + // max X seconds to connect to the URL + if (timeOut < 0) { + timeOut = SystemFlags::DEFAULT_HTTP_TIMEOUT; + } + curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, timeOut); + + /* get contents from the URL */ + CURLcode result = curl_easy_perform(handle); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("CURL result = %d\n", result); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("CURL errbuf [%s]\n", errbuf); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d] return code [%d] [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, result, errbuf); + + std::string serverResponse = (chunk.memory != NULL ? chunk.memory : ""); + if (chunk.memory) { + free(chunk.memory); + } + + if (savedResult != NULL) { + *savedResult = result; + } + if (result != CURLE_OK) { + serverResponse = errbuf; + } + + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d] serverResponse [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, serverResponse.c_str()); + + return serverResponse; + } + + CURL *SystemFlags::initHTTP() { + if (SystemFlags::curl_global_init_called == false) { + SystemFlags::curl_global_init_called = true; + //printf("HTTP init\n"); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d] calling curl_global_init\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] calling curl_global_init\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + CURLcode result = curl_global_init(CURL_GLOBAL_ALL); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d] curl_global_init called and returned: result %d [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, result, curl_easy_strerror(result)); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] curl_global_init called and returned: result %d [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, result, curl_easy_strerror(result)); + //printf("In [%s::%s Line %d] curl_global_init called and returned: result %d [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result,curl_easy_strerror(result)); + } + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d] calling curl_easy_init\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] calling curl_easy_init\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + CURL *handle = curl_easy_init(); + if (handle == NULL) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d] ERROR handle = NULL\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] ERROR handle = NULL\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] handle = %p\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, handle); + curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] handle = %p\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, handle); + return handle; + } + + void SystemFlags::globalCleanupHTTP() { + + if (curl_handle != NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + SystemFlags::cleanupHTTP(&curl_handle, true); + curl_handle = NULL; + } + + if (SystemFlags::curl_global_init_called == true) { + SystemFlags::curl_global_init_called = false; + //printf("HTTP cleanup\n"); + curl_global_cleanup(); + //printf("In [%s::%s Line %d] curl_global_cleanup called\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + } + } + + SystemFlags::SystemFlagsType * SystemFlags::setupRequiredMembers() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true) { + //throw megaglest_runtime_error("threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true"); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ERROR threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + //static SystemFlagsType *result = new SystemFlagsType(); + static SystemFlags::SystemFlagsType result; + result.enabled = SystemFlags::VERBOSE_MODE_ENABLED; + return &result; + } else { + SystemFlags::init(false); + return NULL; + } + } + + void SystemFlags::init(bool haveSpecialOutputCommandLineOption) { + SystemFlags::haveSpecialOutputCommandLineOption = haveSpecialOutputCommandLineOption; + if (SystemFlags::debugLogFileList == NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true) { + //throw megaglest_runtime_error("threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true"); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ERROR threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + return; + } + + SystemFlags::debugLogFileList = new std::map(); + + (*SystemFlags::debugLogFileList)[SystemFlags::debugSystem] = SystemFlags::SystemFlagsType(SystemFlags::debugSystem); + (*SystemFlags::debugLogFileList)[SystemFlags::debugNetwork] = SystemFlags::SystemFlagsType(SystemFlags::debugNetwork); + (*SystemFlags::debugLogFileList)[SystemFlags::debugPerformance] = SystemFlags::SystemFlagsType(SystemFlags::debugPerformance); + (*SystemFlags::debugLogFileList)[SystemFlags::debugWorldSynch] = SystemFlags::SystemFlagsType(SystemFlags::debugWorldSynch); + (*SystemFlags::debugLogFileList)[SystemFlags::debugUnitCommands] = SystemFlags::SystemFlagsType(SystemFlags::debugUnitCommands); + (*SystemFlags::debugLogFileList)[SystemFlags::debugPathFinder] = SystemFlags::SystemFlagsType(SystemFlags::debugPathFinder); + (*SystemFlags::debugLogFileList)[SystemFlags::debugLUA] = SystemFlags::SystemFlagsType(SystemFlags::debugLUA); + (*SystemFlags::debugLogFileList)[SystemFlags::debugSound] = SystemFlags::SystemFlagsType(SystemFlags::debugSound); + (*SystemFlags::debugLogFileList)[SystemFlags::debugError] = SystemFlags::SystemFlagsType(SystemFlags::debugError); + } + + if (threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + threadLogger = new LogFileThread(); + threadLogger->start(); + sleep(1); + } + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (curl_handle == NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + curl_handle = SystemFlags::initHTTP(); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line %d] curl_handle = %p\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, curl_handle); + } + } + + inline bool acquire_file_lock(int hnd) { #ifndef WIN32 - struct ::flock lock; - // Initialize the flock structure. - memset(&lock, 0, sizeof(lock)); - lock.l_type = F_WRLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 0; - lock.l_pid = 0; - return -1 != ::fcntl(hnd, F_SETLK, &lock); + struct ::flock lock; + // Initialize the flock structure. + memset(&lock, 0, sizeof(lock)); + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + lock.l_pid = 0; + return -1 != ::fcntl(hnd, F_SETLK, &lock); #else - HANDLE hFile = (HANDLE)_get_osfhandle(hnd); - return TRUE == ::LockFile(hFile, 0, 0, 0, -0x10000); + HANDLE hFile = (HANDLE) _get_osfhandle(hnd); + return TRUE == ::LockFile(hFile, 0, 0, 0, -0x10000); #endif -} + } -SystemFlags::SystemFlags() { + SystemFlags::SystemFlags() { -} + } -void SystemFlags::cleanupHTTP(CURL **handle, bool globalCleanup) { - if(handle != NULL && *handle != NULL) { - curl_easy_cleanup(*handle); - *handle = NULL; + void SystemFlags::cleanupHTTP(CURL **handle, bool globalCleanup) { + if (handle != NULL && *handle != NULL) { + curl_easy_cleanup(*handle); + *handle = NULL; + + if (globalCleanup == true) { + SystemFlags::globalCleanupHTTP(); + } + } + } + + SystemFlags::~SystemFlags() { + SystemFlags::Close(); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - if(globalCleanup == true) { SystemFlags::globalCleanupHTTP(); - } - } -} -SystemFlags::~SystemFlags() { - SystemFlags::Close(); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - SystemFlags::globalCleanupHTTP(); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void SystemFlags::Close() { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(threadLogger != NULL) { - SystemFlags::ENABLE_THREADED_LOGGING = false; - //SystemFlags::SHUTDOWN_PROGRAM_MODE=true; - time_t elapsed = time(NULL); - threadLogger->signalQuit(); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //threadLogger->shutdownAndWait(); - for(;threadLogger->canShutdown(false) == false && - difftime(time(NULL),elapsed) <= 15;) { - //sleep(150); - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -// if(threadLogger->canShutdown(false)) { -// Sleep(0); -// } - if(threadLogger->shutdownAndWait() == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - delete threadLogger; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - threadLogger = NULL; - //delete threadLogger; - //threadLogger = NULL; - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - } - - if(SystemFlags::debugLogFileList != NULL) { - if(SystemFlags::haveSpecialOutputCommandLineOption == false) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("START Closing logfiles\n"); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); } - for(std::map::iterator iterMap = SystemFlags::debugLogFileList->begin(); - iterMap != SystemFlags::debugLogFileList->end(); ++iterMap) { - SystemFlags::SystemFlagsType ¤tDebugLog = iterMap->second; - currentDebugLog.Close(); - } + void SystemFlags::Close() { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); - delete SystemFlags::debugLogFileList; - SystemFlags::debugLogFileList = NULL; - } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (threadLogger != NULL) { + SystemFlags::ENABLE_THREADED_LOGGING = false; + //SystemFlags::SHUTDOWN_PROGRAM_MODE=true; + time_t elapsed = time(NULL); + threadLogger->signalQuit(); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + //threadLogger->shutdownAndWait(); + for (; threadLogger->canShutdown(false) == false && + difftime(time(NULL), elapsed) <= 15;) { + //sleep(150); + } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + // if(threadLogger->canShutdown(false)) { + // Sleep(0); + // } + if (threadLogger->shutdownAndWait() == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + delete threadLogger; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + threadLogger = NULL; + //delete threadLogger; + //threadLogger = NULL; + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } - if(SystemFlags::lockFile != -1) { -#ifndef WIN32 - close(SystemFlags::lockFile); -#else - _close(SystemFlags::lockFile); -#endif - SystemFlags::lockFile = -1; - SystemFlags::lockFileCountIndex = -1; + if (SystemFlags::debugLogFileList != NULL) { + if (SystemFlags::haveSpecialOutputCommandLineOption == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("START Closing logfiles\n"); + } - if(SystemFlags::lockfilename != "") { - int remove_result = remove(SystemFlags::lockfilename.c_str()); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] remove_result = %d for file [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,remove_result,SystemFlags::lockfilename.c_str()); - - SystemFlags::lockfilename = ""; - } - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(SystemFlags::debugLogFileList != NULL) { - if(SystemFlags::haveSpecialOutputCommandLineOption == false) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("END Closing logfiles\n"); - } - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); -} - -void SystemFlags::handleDebug(DebugType type, const char *fmt, ...) { - if(SystemFlags::debugLogFileList == NULL) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true) { - //throw megaglest_runtime_error("threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true"); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ERROR threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - //return; - } - - SystemFlags::init(false); - } - //SystemFlags::SystemFlagsType ¤tDebugLog = (*SystemFlags::debugLogFileList)[type]; - SystemFlags::SystemFlagsType ¤tDebugLog =getSystemSettingType(type); - if(currentDebugLog.enabled == false) { - return; - } - - va_list argList; - va_start(argList, fmt); - - const int max_debug_buffer_size = 8096; - char szBuf[max_debug_buffer_size]=""; - vsnprintf(szBuf,max_debug_buffer_size-1,fmt, argList); - va_end(argList); - - if( currentDebugLog.debugLogFileName != "" && - SystemFlags::ENABLE_THREADED_LOGGING && - threadLogger != NULL && - threadLogger->getRunningStatus() == true) { - threadLogger->addLogEntry(type, szBuf); - } - else { - // Get the current time. - time_t curtime = time (NULL); - logDebugEntry(type, (szBuf[0] != '\0' ? szBuf : ""), curtime); - } -} - - -void SystemFlags::logDebugEntry(DebugType type, string debugEntry, time_t debugTime) { - if(SystemFlags::debugLogFileList == NULL) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - SystemFlags::init(false); - } - //SystemFlags::SystemFlagsType ¤tDebugLog = (*SystemFlags::debugLogFileList)[type]; - SystemFlags::SystemFlagsType ¤tDebugLog =getSystemSettingType(type); - if(currentDebugLog.enabled == false) { - return; - } - - char szBuf2[100]=""; - //if (type != debugPathFinder && type != debugError && type != debugWorldSynch) { - if (type != debugPathFinder && type != debugWorldSynch) { - // Get the current time. - // time_t curtime = time (NULL); - // Convert it to local time representation. - //struct tm *loctime = localtime (&debugTime); - std::tm loctime = threadsafe_localtime(debugTime); - strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",&loctime); - } -/* - va_list argList; - va_start(argList, fmt); - - const int max_debug_buffer_size = 8096; - char szBuf[max_debug_buffer_size]=""; - vsnprintf(szBuf,max_debug_buffer_size-1,fmt, argList); -*/ - // Either output to a logfile or - if(currentDebugLog.debugLogFileName != "") { - if( currentDebugLog.fileStream == NULL || - currentDebugLog.fileStream->is_open() == false) { - - // If the file is already open (shared) by another debug type - // do not over-write the file but share the stream pointer - if(SystemFlags::debugLogFileList != NULL) { - for(std::map::iterator iterMap = SystemFlags::debugLogFileList->begin(); + for (std::map::iterator iterMap = SystemFlags::debugLogFileList->begin(); iterMap != SystemFlags::debugLogFileList->end(); ++iterMap) { - SystemFlags::SystemFlagsType ¤tDebugLog2 = iterMap->second; + SystemFlags::SystemFlagsType ¤tDebugLog = iterMap->second; + currentDebugLog.Close(); + } - if( iterMap->first != type && - currentDebugLog.debugLogFileName == currentDebugLog2.debugLogFileName && - currentDebugLog2.fileStream != NULL) { - currentDebugLog.fileStream = currentDebugLog2.fileStream; - currentDebugLog.fileStreamOwner = false; - currentDebugLog.mutex = currentDebugLog2.mutex; + delete SystemFlags::debugLogFileList; + SystemFlags::debugLogFileList = NULL; + } + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (SystemFlags::lockFile != -1) { +#ifndef WIN32 + close(SystemFlags::lockFile); +#else + _close(SystemFlags::lockFile); +#endif + SystemFlags::lockFile = -1; + SystemFlags::lockFileCountIndex = -1; + + if (SystemFlags::lockfilename != "") { + int remove_result = remove(SystemFlags::lockfilename.c_str()); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] remove_result = %d for file [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, remove_result, SystemFlags::lockfilename.c_str()); + + SystemFlags::lockfilename = ""; + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (SystemFlags::debugLogFileList != NULL) { + if (SystemFlags::haveSpecialOutputCommandLineOption == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("END Closing logfiles\n"); + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + } + + void SystemFlags::handleDebug(DebugType type, const char *fmt, ...) { + if (SystemFlags::debugLogFileList == NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true) { + //throw megaglest_runtime_error("threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true"); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ERROR threadLogger == NULL && SystemFlags::SHUTDOWN_PROGRAM_MODE == true\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + //return; + } + + SystemFlags::init(false); + } + //SystemFlags::SystemFlagsType ¤tDebugLog = (*SystemFlags::debugLogFileList)[type]; + SystemFlags::SystemFlagsType ¤tDebugLog = getSystemSettingType(type); + if (currentDebugLog.enabled == false) { + return; + } + + va_list argList; + va_start(argList, fmt); + + const int max_debug_buffer_size = 8096; + char szBuf[max_debug_buffer_size] = ""; + vsnprintf(szBuf, max_debug_buffer_size - 1, fmt, argList); + va_end(argList); + + if (currentDebugLog.debugLogFileName != "" && + SystemFlags::ENABLE_THREADED_LOGGING && + threadLogger != NULL && + threadLogger->getRunningStatus() == true) { + threadLogger->addLogEntry(type, szBuf); + } else { + // Get the current time. + time_t curtime = time(NULL); + logDebugEntry(type, (szBuf[0] != '\0' ? szBuf : ""), curtime); + } + } + + + void SystemFlags::logDebugEntry(DebugType type, string debugEntry, time_t debugTime) { + if (SystemFlags::debugLogFileList == NULL) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + SystemFlags::init(false); + } + //SystemFlags::SystemFlagsType ¤tDebugLog = (*SystemFlags::debugLogFileList)[type]; + SystemFlags::SystemFlagsType ¤tDebugLog = getSystemSettingType(type); + if (currentDebugLog.enabled == false) { + return; + } + + char szBuf2[100] = ""; + //if (type != debugPathFinder && type != debugError && type != debugWorldSynch) { + if (type != debugPathFinder && type != debugWorldSynch) { + // Get the current time. + // time_t curtime = time (NULL); + // Convert it to local time representation. + //struct tm *loctime = localtime (&debugTime); + std::tm loctime = threadsafe_localtime(debugTime); + strftime(szBuf2, 100, "%Y-%m-%d %H:%M:%S", &loctime); + } + /* + va_list argList; + va_start(argList, fmt); + + const int max_debug_buffer_size = 8096; + char szBuf[max_debug_buffer_size]=""; + vsnprintf(szBuf,max_debug_buffer_size-1,fmt, argList); + */ + // Either output to a logfile or + if (currentDebugLog.debugLogFileName != "") { + if (currentDebugLog.fileStream == NULL || + currentDebugLog.fileStream->is_open() == false) { + + // If the file is already open (shared) by another debug type + // do not over-write the file but share the stream pointer + if (SystemFlags::debugLogFileList != NULL) { + for (std::map::iterator iterMap = SystemFlags::debugLogFileList->begin(); + iterMap != SystemFlags::debugLogFileList->end(); ++iterMap) { + SystemFlags::SystemFlagsType ¤tDebugLog2 = iterMap->second; + + if (iterMap->first != type && + currentDebugLog.debugLogFileName == currentDebugLog2.debugLogFileName && + currentDebugLog2.fileStream != NULL) { + currentDebugLog.fileStream = currentDebugLog2.fileStream; + currentDebugLog.fileStreamOwner = false; + currentDebugLog.mutex = currentDebugLog2.mutex; + break; + } + } + } + + string debugLog = currentDebugLog.debugLogFileName; + + if (SystemFlags::lockFile == -1) { + const string lock_file_name = "debug.lck"; + string lockfile = extractDirectoryPathFromFile(debugLog); + lockfile += lock_file_name; + SystemFlags::lockfilename = lockfile; + +#ifndef WIN32 + //SystemFlags::lockFile = open(lockfile.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR|S_IWUSR); + SystemFlags::lockFile = open(lockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); +#else + SystemFlags::lockFile = _open(lockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); +#endif + if (SystemFlags::lockFile < 0 || acquire_file_lock(SystemFlags::lockFile) == false) { + string newlockfile = lockfile; + int idx = 1; + for (idx = 1; idx <= 100; ++idx) { + newlockfile = lockfile + intToStr(idx); + + if (SystemFlags::lockFile != -1) { +#ifndef WIN32 + close(SystemFlags::lockFile); +#else + _close(SystemFlags::lockFile); +#endif + SystemFlags::lockFile = -1; + SystemFlags::lockFileCountIndex = -1; + } + //SystemFlags::lockFile = open(newlockfile.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR|S_IWUSR); +#ifndef WIN32 + SystemFlags::lockFile = open(newlockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); +#else + SystemFlags::lockFile = _open(newlockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); + +#endif + if (SystemFlags::lockFile >= 0 && acquire_file_lock(SystemFlags::lockFile) == true) { + break; + } + } + + SystemFlags::lockFileCountIndex = idx; + SystemFlags::lockfilename = newlockfile; + debugLog += intToStr(idx); + + if (SystemFlags::haveSpecialOutputCommandLineOption == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Opening additional logfile [%s]\n", debugLog.c_str()); + } + } + } else if (SystemFlags::lockFileCountIndex > 0) { + debugLog += intToStr(SystemFlags::lockFileCountIndex); + + if (SystemFlags::haveSpecialOutputCommandLineOption == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Opening additional logfile [%s]\n", debugLog.c_str()); + } + } + + if (currentDebugLog.fileStream == NULL) { +#if defined(WIN32) && !defined(__MINGW32__) + currentDebugLog.fileStream = new std::ofstream(_wfopen(utf8_decode(debugLog).c_str(), L"w")); +#else + currentDebugLog.fileStream = new std::ofstream(); + currentDebugLog.fileStream->open(debugLog.c_str(), ios_base::out | ios_base::trunc); +#endif + currentDebugLog.fileStreamOwner = true; + currentDebugLog.mutex = new Mutex(CODE_AT_LINE); + } + + if (SystemFlags::haveSpecialOutputCommandLineOption == false) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Opening logfile [%s] type = %d, currentDebugLog.fileStreamOwner = %d, file stream open = %d\n", debugLog.c_str(), type, currentDebugLog.fileStreamOwner, currentDebugLog.fileStream->is_open()); + } + + if (currentDebugLog.fileStream->is_open() == true) { + MutexSafeWrapper safeMutex(currentDebugLog.mutex, string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__)); + + (*currentDebugLog.fileStream) << "Starting ZetaGlest logging for type: " << type << "\n"; + (*currentDebugLog.fileStream).flush(); + + safeMutex.ReleaseLock(); + } + } + + assert(currentDebugLog.fileStream != NULL); + + if (currentDebugLog.fileStream->is_open() == true) { + static string mutexCodeLocation = string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__); + MutexSafeWrapper safeMutex(currentDebugLog.mutex, mutexCodeLocation); + + // All items in the if clause we don't want timestamps + if (type != debugPathFinder && type != debugError && type != debugWorldSynch) { + (*currentDebugLog.fileStream) << "[" << szBuf2 << "] " << debugEntry.c_str(); + } else if (type == debugError) { + (*currentDebugLog.fileStream) << "[" << szBuf2 << "] *ERROR* " << debugEntry.c_str(); + } else { + (*currentDebugLog.fileStream) << debugEntry.c_str(); + } + (*currentDebugLog.fileStream).flush(); + + safeMutex.ReleaseLock(); + } + } + + // output to console + if (currentDebugLog.debugLogFileName == "" || + (currentDebugLog.debugLogFileName != "" && + (currentDebugLog.fileStream == NULL || + currentDebugLog.fileStream->is_open() == false))) { + + if (type != debugPathFinder && type != debugError) { + printf("[%s] %s", szBuf2, debugEntry.c_str()); + } else if (type == debugError) { + printf("*ERROR* [%s] %s", szBuf2, debugEntry.c_str()); + } else { + printf("%s", debugEntry.c_str()); + } + } + } + + + string lastDir(const string &s) { + size_t i = s.find_last_of('/'); + size_t j = s.find_last_of('\\'); + size_t pos; + + if (i == string::npos) { + pos = j; + } else if (j == string::npos) { + pos = i; + } else { + pos = i < j ? j : i; + } + + if (pos == string::npos) { + throw megaglest_runtime_error(string(extractFileFromDirectoryPath(__FILE__).c_str()) + " line: " + intToStr(__LINE__) + " pos == string::npos for [" + s + "]"); + } + + if (pos + 1 == s.length() && s.length() > 0 && + (s[pos] == '/' || s[pos] == '\\')) { + string retry = s.substr(0, pos); + return lastDir(retry); + } + string result = (s.empty() == false ? s.substr(pos + 1, s.length()) : ""); + replaceAll(result, "/", ""); + replaceAll(result, "\\", ""); + + //printf("=-=-=-=- LASTDIR in [%s] out [%s]\n",s.c_str(),result.c_str()); + + return result; + } + + string lastFile(const string &s) { + return lastDir(s); + } + + string cutLastFile(const string &s) { + size_t i = s.find_last_of('/'); + size_t j = s.find_last_of('\\'); + size_t pos; + + if (i == string::npos) { + pos = j; + } else if (j == string::npos) { + pos = i; + } else { + pos = i < j ? j : i; + } + + if (pos != string::npos) { + //throw megaglest_runtime_error(string(extractFileFromDirectoryPath(__FILE__).c_str()) + " line: " + intToStr(__LINE__) + " pos == string::npos for [" + s + "]"); + //} + + return (s.substr(0, pos)); + } + return s; + } + + string cutLastExt(const string &s) { + size_t i = s.find_last_of('.'); + if (i != string::npos) { + //throw megaglest_runtime_error(string(extractFileFromDirectoryPath(__FILE__).c_str()) + " line: " + intToStr(__LINE__) + " i==string::npos for [" + s + "]"); + //} + + return (s.substr(0, i)); + } + return s; + } + + string ext(const string &s) { + size_t i; + + i = s.find_last_of('.') + 1; + + if (i != string::npos) { + //throw megaglest_runtime_error(string(extractFileFromDirectoryPath(__FILE__).c_str()) + " line: " + intToStr(__LINE__) + " i==string::npos for [" + s + "]"); + //} + return (s.substr(i, s.size() - i)); + } + return ""; + } + + string replaceBy(const string &s, char c1, char c2) { + string rs = s; + + for (size_t i = 0; i < s.size(); ++i) { + if (rs[i] == c1) { + rs[i] = c2; + } + } + + return rs; + } + + vector split(string s, string d) { + vector results; + + if (s.empty() == false) { + size_t lastOffset = 0; + + while (true) { + size_t offset = s.find_first_of(d, lastOffset); + results.push_back(s.substr(lastOffset, offset - lastOffset)); + if (offset == string::npos) + break; + else + lastOffset = offset + d.size(); //skip the delimiter + } + } + return results; + } + + string toLower(const string &s) { + string rs = s; + + for (size_t i = 0; i < s.size(); ++i) { + rs[i] = tolower(s[i]); + } + + return rs; + } + + bool compareNonCaseSensitive(const string &a, const string &b) { + return (toLower(a) < toLower(b)); + } + + //void copyStringToBuffer(char *buffer, int bufferSize, const string& s){ + // strncpy(buffer, s.c_str(), bufferSize-1); + // buffer[bufferSize-1]= '\0'; + //} + + // ==================== numeric fcs ==================== + + //float saturate(float value) { + // if (value < 0.f){ + // return 0.f; + // } + // if (value > 1.f){ + // return 1.f; + // } + // return value; + //} + + int clamp(int value, int min, int max) { + if (value < min) { + return min; + } + if (value > max) { + return max; + } + return value; + } + + int64 clamp(int64 value, int64 min, int64 max) { + if (value < min) { + return min; + } + if (value > max) { + return max; + } + return value; + } + + float clamp(float value, float min, float max) { + if (value < min) { + return min; + } + if (value > max) { + return max; + } + return value; + } + + //int round(float f){ + // return (int) f; + //} + + // ==================== misc ==================== + int compareMajorMinorVersion(const string &versionA, const string &versionB) { + int majorA = getMajor(versionA); + int minorA = getMinor(versionA); + int majorB = getMajor(versionB); + int minorB = getMinor(versionB); + + //printf("majorA:%d minorA:%d majorB:%d minorB:%d\n",majorA,minorA,majorB,minorB); + if (majorA < majorB) { + return -1; + } else if (majorA == majorB) { + if (minorA < minorB) { + return -1; + } else if (minorA == minorB) { + return 0; + } else { + return 1; + } + } else { + return 1; + } + } + + int getMajor(string version) { + vector parts; + + if (version.empty() == false) { + parts = split(version.substr(1), "."); + } + + if (parts.size() > 1 && parts[0] != "" && IsNumeric(parts[0].c_str(), false)) { + return strToInt(parts[0]); + } else { + return 0; + } + } + + int getMinor(string version) { + vector parts; + + if (version.empty() == false) { + parts = split(version.substr(1), "."); + } + if (parts.size() > 1 && parts[1] != "") { + string resultStr = ""; + for (int i = 0; i < (int) parts[1].length(); ++i) { + // just add leading numbers + if (IsNumeric((resultStr + parts[1][i]).c_str(), false)) { + resultStr += parts[1][i]; + } else { break; } } - } - - string debugLog = currentDebugLog.debugLogFileName; - - if(SystemFlags::lockFile == -1) { - const string lock_file_name = "debug.lck"; - string lockfile = extractDirectoryPathFromFile(debugLog); - lockfile += lock_file_name; - SystemFlags::lockfilename = lockfile; - -#ifndef WIN32 - //SystemFlags::lockFile = open(lockfile.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR|S_IWUSR); - SystemFlags::lockFile = open(lockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); -#else - SystemFlags::lockFile = _open(lockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); -#endif - if (SystemFlags::lockFile < 0 || acquire_file_lock(SystemFlags::lockFile) == false) { - string newlockfile = lockfile; - int idx = 1; - for(idx = 1; idx <= 100; ++idx) { - newlockfile = lockfile + intToStr(idx); - - if(SystemFlags::lockFile != -1) { -#ifndef WIN32 - close(SystemFlags::lockFile); -#else - _close(SystemFlags::lockFile); -#endif - SystemFlags::lockFile = -1; - SystemFlags::lockFileCountIndex = -1; - } - //SystemFlags::lockFile = open(newlockfile.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR|S_IWUSR); -#ifndef WIN32 - SystemFlags::lockFile = open(newlockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); -#else - SystemFlags::lockFile = _open(newlockfile.c_str(), O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); - -#endif - if(SystemFlags::lockFile >= 0 && acquire_file_lock(SystemFlags::lockFile) == true) { - break; - } - } - - SystemFlags::lockFileCountIndex = idx; - SystemFlags::lockfilename = newlockfile; - debugLog += intToStr(idx); - - if(SystemFlags::haveSpecialOutputCommandLineOption == false) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Opening additional logfile [%s]\n",debugLog.c_str()); - } - } - } - else if(SystemFlags::lockFileCountIndex > 0) { - debugLog += intToStr(SystemFlags::lockFileCountIndex); - - if(SystemFlags::haveSpecialOutputCommandLineOption == false) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Opening additional logfile [%s]\n",debugLog.c_str()); - } - } - - if(currentDebugLog.fileStream == NULL) { -#if defined(WIN32) && !defined(__MINGW32__) - currentDebugLog.fileStream = new std::ofstream(_wfopen(utf8_decode(debugLog).c_str(), L"w")); -#else - currentDebugLog.fileStream = new std::ofstream(); - currentDebugLog.fileStream->open(debugLog.c_str(), ios_base::out | ios_base::trunc); -#endif - currentDebugLog.fileStreamOwner = true; - currentDebugLog.mutex = new Mutex(CODE_AT_LINE); - } - - if(SystemFlags::haveSpecialOutputCommandLineOption == false) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Opening logfile [%s] type = %d, currentDebugLog.fileStreamOwner = %d, file stream open = %d\n",debugLog.c_str(),type, currentDebugLog.fileStreamOwner,currentDebugLog.fileStream->is_open()); - } - - if(currentDebugLog.fileStream->is_open() == true) { - MutexSafeWrapper safeMutex(currentDebugLog.mutex,string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__)); - - (*currentDebugLog.fileStream) << "Starting ZetaGlest logging for type: " << type << "\n"; - (*currentDebugLog.fileStream).flush(); - - safeMutex.ReleaseLock(); - } - } - - assert(currentDebugLog.fileStream != NULL); - - if(currentDebugLog.fileStream->is_open() == true) { - static string mutexCodeLocation = string(extractFileFromDirectoryPath(__FILE__).c_str()) + "_" + intToStr(__LINE__); - MutexSafeWrapper safeMutex(currentDebugLog.mutex,mutexCodeLocation); - - // All items in the if clause we don't want timestamps - if (type != debugPathFinder && type != debugError && type != debugWorldSynch) { - (*currentDebugLog.fileStream) << "[" << szBuf2 << "] " << debugEntry.c_str(); - } - else if (type == debugError) { - (*currentDebugLog.fileStream) << "[" << szBuf2 << "] *ERROR* " << debugEntry.c_str(); - } - else { - (*currentDebugLog.fileStream) << debugEntry.c_str(); - } - (*currentDebugLog.fileStream).flush(); - - safeMutex.ReleaseLock(); - } - } - - // output to console - if( currentDebugLog.debugLogFileName == "" || - (currentDebugLog.debugLogFileName != "" && - (currentDebugLog.fileStream == NULL || - currentDebugLog.fileStream->is_open() == false))) { - - if (type != debugPathFinder && type != debugError) { - printf("[%s] %s", szBuf2, debugEntry.c_str()); - } - else if (type == debugError) { - printf("*ERROR* [%s] %s", szBuf2,debugEntry.c_str()); - } - else { - printf("%s", debugEntry.c_str()); - } - } -} - - -string lastDir(const string &s) { - size_t i= s.find_last_of('/'); - size_t j= s.find_last_of('\\'); - size_t pos; - - if(i==string::npos){ - pos= j; - } - else if(j==string::npos){ - pos= i; - } - else{ - pos= i 0 && - (s[pos] == '/' || s[pos] == '\\')) { - string retry = s.substr(0, pos); - return lastDir(retry); - } - string result = (s.empty() == false ? s.substr(pos+1, s.length()) : ""); - replaceAll(result,"/",""); - replaceAll(result,"\\",""); - - //printf("=-=-=-=- LASTDIR in [%s] out [%s]\n",s.c_str(),result.c_str()); - - return result; -} - -string lastFile(const string &s){ - return lastDir(s); -} - -string cutLastFile(const string &s){ - size_t i= s.find_last_of('/'); - size_t j= s.find_last_of('\\'); - size_t pos; - - if(i == string::npos) { - pos= j; - } - else if(j == string::npos) { - pos= i; - } - else{ - pos= i < j ? j: i; - } - - if (pos != string::npos) { - //throw megaglest_runtime_error(string(extractFileFromDirectoryPath(__FILE__).c_str()) + " line: " + intToStr(__LINE__) + " pos == string::npos for [" + s + "]"); - //} - - return (s.substr(0, pos)); - } - return s; -} - -string cutLastExt(const string &s) { - size_t i= s.find_last_of('.'); - if (i != string::npos) { - //throw megaglest_runtime_error(string(extractFileFromDirectoryPath(__FILE__).c_str()) + " line: " + intToStr(__LINE__) + " i==string::npos for [" + s + "]"); - //} - - return (s.substr(0, i)); - } - return s; -} - -string ext(const string &s) { - size_t i; - - i=s.find_last_of('.')+1; - - if (i != string::npos) { - //throw megaglest_runtime_error(string(extractFileFromDirectoryPath(__FILE__).c_str()) + " line: " + intToStr(__LINE__) + " i==string::npos for [" + s + "]"); - //} - return (s.substr(i, s.size()-i)); - } - return ""; -} - -string replaceBy(const string &s, char c1, char c2){ - string rs= s; - - for(size_t i=0; i split(string s,string d) { - vector results; - - if(s.empty() == false) { - size_t lastOffset = 0; - - while(true) { - size_t offset = s.find_first_of(d, lastOffset); - results.push_back(s.substr(lastOffset, offset - lastOffset)); - if (offset == string::npos) - break; - else - lastOffset = offset + d.size(); //skip the delimiter - } - } - return results; -} - -string toLower(const string &s){ - string rs= s; - - for(size_t i=0; i 1.f){ -// return 1.f; -// } -// return value; -//} - -int clamp(int value, int min, int max){ - if (valuemax){ - return max; - } - return value; -} - -int64 clamp(int64 value, int64 min, int64 max){ - if (valuemax){ - return max; - } - return value; -} - -float clamp(float value, float min, float max) { - if (value < min) { - return min; - } - if (value > max) { - return max; - } - return value; -} - -//int round(float f){ -// return (int) f; -//} - -// ==================== misc ==================== -int compareMajorMinorVersion(const string &versionA, const string &versionB) { - int majorA = getMajor(versionA); - int minorA = getMinor(versionA); - int majorB = getMajor(versionB); - int minorB = getMinor(versionB); - - //printf("majorA:%d minorA:%d majorB:%d minorB:%d\n",majorA,minorA,majorB,minorB); - if(majorA < majorB) { - return -1; - } - else if(majorA == majorB) { - if(minorA < minorB) { - return -1; - } - else if(minorA == minorB) { - return 0; - } - else { - return 1; - } - } - else { - return 1; - } -} - -int getMajor(string version) { - vector parts; - - if(version.empty() == false) { - parts = split(version.substr(1),"."); - } - - if(parts.size() > 1 && parts[0] != "" && IsNumeric(parts[0].c_str(),false)) { - return strToInt(parts[0]); - } - else { - return 0; - } -} - -int getMinor(string version) { - vector parts; - - if(version.empty() == false) { - parts = split(version.substr(1),"."); - } - if(parts.size() > 1 && parts[1] != "") { - string resultStr=""; - for (int i = 0; i < (int)parts[1].length(); ++i) { - // just add leading numbers - if(IsNumeric((resultStr + parts[1][i]).c_str(),false) ) { - resultStr += parts[1][i]; - } - else { - break; - } - } - if(resultStr == "") { - return 0; - } - else { - return strToInt(resultStr); - } - } - else { - return 0; - } -} - -bool checkVersionComptability(string clientVersionString, string serverVersionString) { - //SystemFlags::VERBOSE_MODE_ENABLED = true; - - bool compatible = (clientVersionString == serverVersionString); - if(compatible == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] clientVersionString [%s], serverVersionString [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,clientVersionString.c_str(),serverVersionString.c_str()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] clientVersionString [%s], serverVersionString [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,clientVersionString.c_str(),serverVersionString.c_str()); - - vector tokens; - vector tokensServer; - Tokenize(clientVersionString,tokens,"."); - Tokenize(serverVersionString,tokensServer,"."); - - // Search for -dev, -gamma, -alpha, -beta and strip characters after - for(unsigned int i = 0; i < tokensServer.size(); ++i) { - vector tokensSpecialVersionTags; - Tokenize(tokensServer[i],tokensSpecialVersionTags,"-"); - if(tokensSpecialVersionTags.size() > 1) { - if( StartsWith(tokensSpecialVersionTags[1],"dev") == true || - StartsWith(tokensSpecialVersionTags[1],"gamma") == true || - StartsWith(tokensSpecialVersionTags[1],"alpha") == true || - StartsWith(tokensSpecialVersionTags[1],"beta") == true) { - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Line Ref: %d FOUND SPECIAL SERVER VERSION TAG [%s] [%s] tokensSpecialVersionTags.size() = " MG_SIZE_T_SPECIFIER "\n",__LINE__,tokensSpecialVersionTags[0].c_str(),tokensSpecialVersionTags[1].c_str(),tokensSpecialVersionTags.size()); - - // Chop off platform specific version info - if(tokensSpecialVersionTags.size() > 2) { - string trimRightDelim = "-" + tokensSpecialVersionTags[2]; - string newVersionText = trim_at_delim(serverVersionString, trimRightDelim); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Line Ref: %d NEW SERVER VERSION TAG [%s] OLD TAG [%s] delim [%s]\n",__LINE__,newVersionText.c_str(),serverVersionString.c_str(),trimRightDelim.c_str()); - serverVersionString = newVersionText; - - tokensServer.clear(); - Tokenize(serverVersionString,tokensServer,"."); - } - - break; - } - } - } - for(unsigned int i = 0; i < tokens.size(); ++i) { - vector tokensSpecialVersionTags; - Tokenize(tokens[i],tokensSpecialVersionTags,"-"); - if(tokensSpecialVersionTags.size() > 1) { - if( StartsWith(tokensSpecialVersionTags[1],"dev") == true || - StartsWith(tokensSpecialVersionTags[1],"gamma") == true || - StartsWith(tokensSpecialVersionTags[1],"alpha") == true || - StartsWith(tokensSpecialVersionTags[1],"beta") == true) { - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Line Ref: %d FOUND SPECIAL CLIENT VERSION TAG [%s] [%s] tokensSpecialVersionTags.size() = " MG_SIZE_T_SPECIFIER "\n",__LINE__,tokensSpecialVersionTags[0].c_str(),tokensSpecialVersionTags[1].c_str(),tokensSpecialVersionTags.size()); - - // Chop off platform specific version info - if(tokensSpecialVersionTags.size() > 2) { - string trimRightDelim = "-" + tokensSpecialVersionTags[2]; - string newVersionText = trim_at_delim(clientVersionString, trimRightDelim); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Line Ref: %d NEW CLIENT VERSION TAG [%s] OLD TAG [%s] delim [%s]\n",__LINE__,newVersionText.c_str(),clientVersionString.c_str(),trimRightDelim.c_str()); - clientVersionString = newVersionText; - - tokens.clear(); - Tokenize(clientVersionString,tokens,"."); - } - - break; + if (resultStr == "") { + return 0; + } else { + return strToInt(resultStr); } + } else { + return 0; } } - // strip the v off the first version, ie v3.7.0 - replaceAll(tokensServer[0], "v", ""); - replaceAll(tokens[0], "v", ""); + bool checkVersionComptability(string clientVersionString, string serverVersionString) { + //SystemFlags::VERBOSE_MODE_ENABLED = true; + bool compatible = (clientVersionString == serverVersionString); + if (compatible == false) { + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] clientVersionString [%s], serverVersionString [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, clientVersionString.c_str(), serverVersionString.c_str()); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] clientVersionString [%s], serverVersionString [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, clientVersionString.c_str(), serverVersionString.c_str()); - if(SystemFlags::VERBOSE_MODE_ENABLED) { - // debug version strings - for(unsigned int i = 0; i < tokensServer.size(); ++i) { - printf("Line Ref: %d Server version index = %u str [%s] IsNumeric = %d\n",__LINE__,i,tokensServer[i].c_str(),IsNumeric(tokensServer[i].c_str(),false)); - } - for(unsigned int i = 0; i < tokens.size(); ++i) { - printf("Line Ref: %d Client version index = %u str [%s] IsNumeric = %d\n",__LINE__,i,tokens[i].c_str(),IsNumeric(tokens[i].c_str(),false)); - } - } - // **NOTE: - // after of 3.7.0 we go to 2 digi version compatibility, check if both - // client and server are at least 3.7 - bool compatiblePre3_7_0_1_Check = true; + vector tokens; + vector tokensServer; + Tokenize(clientVersionString, tokens, "."); + Tokenize(serverVersionString, tokensServer, "."); - if(tokens.size() >= 2 && tokensServer.size() >= 2) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // Search for -dev, -gamma, -alpha, -beta and strip characters after + for (unsigned int i = 0; i < tokensServer.size(); ++i) { + vector tokensSpecialVersionTags; + Tokenize(tokensServer[i], tokensSpecialVersionTags, "-"); + if (tokensSpecialVersionTags.size() > 1) { + if (StartsWith(tokensSpecialVersionTags[1], "dev") == true || + StartsWith(tokensSpecialVersionTags[1], "gamma") == true || + StartsWith(tokensSpecialVersionTags[1], "alpha") == true || + StartsWith(tokensSpecialVersionTags[1], "beta") == true) { - // Both Client and Server are >= to 3.7.0 - if(tokensServer[0] != "" && IsNumeric(tokensServer[0].c_str(),false) && strToInt(tokensServer[0]) >= 3 && - tokensServer[1] != "" && IsNumeric(tokensServer[1].c_str(),false) && strToInt(tokensServer[1]) >= 7 && - tokens[0] != "" && IsNumeric(tokens[0].c_str(),false) && strToInt(tokens[0]) >= 3 && - tokens[1] != "" && IsNumeric(tokens[1].c_str(),false) && strToInt(tokens[1]) >= 7) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Line Ref: %d FOUND SPECIAL SERVER VERSION TAG [%s] [%s] tokensSpecialVersionTags.size() = " MG_SIZE_T_SPECIFIER "\n", __LINE__, tokensSpecialVersionTags[0].c_str(), tokensSpecialVersionTags[1].c_str(), tokensSpecialVersionTags.size()); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + // Chop off platform specific version info + if (tokensSpecialVersionTags.size() > 2) { + string trimRightDelim = "-" + tokensSpecialVersionTags[2]; + string newVersionText = trim_at_delim(serverVersionString, trimRightDelim); - bool compatiblePost3_7_0_Check = false; - // Both are at least 3.7.0, now check if both are > 3.7.0 - if(tokens.size() >= 3 && tokensServer.size() >= 3) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Line Ref: %d NEW SERVER VERSION TAG [%s] OLD TAG [%s] delim [%s]\n", __LINE__, newVersionText.c_str(), serverVersionString.c_str(), trimRightDelim.c_str()); + serverVersionString = newVersionText; - if((tokensServer[0] != "" && IsNumeric(tokensServer[0].c_str(),false) && strToInt(tokensServer[0]) >= 3 && - tokensServer[1] != "" && IsNumeric(tokensServer[1].c_str(),false) && strToInt(tokensServer[1]) >= 7 && - tokensServer[2] != "" && IsNumeric(tokensServer[2].c_str(),false) && strToInt(tokensServer[2]) > 0) && - (tokens[0] != "" && IsNumeric(tokens[0].c_str(),false) && strToInt(tokens[0]) >= 3 && - tokens[1] != "" && IsNumeric(tokens[1].c_str(),false) && strToInt(tokens[1]) >= 7 && - tokens[2] != "" && IsNumeric(tokens[2].c_str(),false) && strToInt(tokens[2]) > 0)) { + tokensServer.clear(); + Tokenize(serverVersionString, tokensServer, "."); + } - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - compatiblePost3_7_0_Check = true; - } - if(strToInt(tokensServer[0]) == strToInt(tokens[0]) && - strToInt(tokensServer[1]) == strToInt(tokens[1])) { - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if((tokensServer[0] != "" && IsNumeric(tokensServer[0].c_str(),false) && strToInt(tokensServer[0]) == 3 && - tokensServer[1] != "" && IsNumeric(tokensServer[1].c_str(),false) && strToInt(tokensServer[1]) == 7 && - tokensServer[2] != "" && IsNumeric(tokensServer[2].c_str(),false) && strToInt(tokensServer[2]) == 0) || - (tokens[0] != "" && IsNumeric(tokens[0].c_str(),false) && strToInt(tokens[0]) == 3 && - tokens[1] != "" && IsNumeric(tokens[1].c_str(),false) && strToInt(tokens[1]) == 7 && - tokens[2] != "" && IsNumeric(tokens[2].c_str(),false) && strToInt(tokens[2]) == 0)) { - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - compatiblePost3_7_0_Check = false; - } - else { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - compatiblePost3_7_0_Check = true; + break; } } - } - else { - // If both are > 3.7 use new version checking of 2 digits since both are higher than 3.7.0 - if((tokensServer[0] != "" && IsNumeric(tokensServer[0].c_str(),false) && strToInt(tokensServer[0]) >= 3 && - tokensServer[1] != "" && IsNumeric(tokensServer[1].c_str(),false) && strToInt(tokensServer[1]) > 7) && - (tokens[0] != "" && IsNumeric(tokens[0].c_str(),false) && strToInt(tokens[0]) >= 3 && - tokens[1] != "" && IsNumeric(tokens[1].c_str(),false) && strToInt(tokens[1]) > 7)) { + for (unsigned int i = 0; i < tokens.size(); ++i) { + vector tokensSpecialVersionTags; + Tokenize(tokens[i], tokensSpecialVersionTags, "-"); + if (tokensSpecialVersionTags.size() > 1) { + if (StartsWith(tokensSpecialVersionTags[1], "dev") == true || + StartsWith(tokensSpecialVersionTags[1], "gamma") == true || + StartsWith(tokensSpecialVersionTags[1], "alpha") == true || + StartsWith(tokensSpecialVersionTags[1], "beta") == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Line Ref: %d FOUND SPECIAL CLIENT VERSION TAG [%s] [%s] tokensSpecialVersionTags.size() = " MG_SIZE_T_SPECIFIER "\n", __LINE__, tokensSpecialVersionTags[0].c_str(), tokensSpecialVersionTags[1].c_str(), tokensSpecialVersionTags.size()); - compatiblePost3_7_0_Check = true; - } - else { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - compatiblePost3_7_0_Check = true; + // Chop off platform specific version info + if (tokensSpecialVersionTags.size() > 2) { + string trimRightDelim = "-" + tokensSpecialVersionTags[2]; + string newVersionText = trim_at_delim(clientVersionString, trimRightDelim); + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Line Ref: %d NEW CLIENT VERSION TAG [%s] OLD TAG [%s] delim [%s]\n", __LINE__, newVersionText.c_str(), clientVersionString.c_str(), trimRightDelim.c_str()); + clientVersionString = newVersionText; + + tokens.clear(); + Tokenize(clientVersionString, tokens, "."); + } + + break; + } } } - if(compatiblePost3_7_0_Check == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - compatiblePre3_7_0_1_Check = false; - // only check the first 2 sections with . to compare major versions #'s - compatible = (tokens.size() >= 2 && tokensServer.size() >= 2); + // strip the v off the first version, ie v3.7.0 + replaceAll(tokensServer[0], "v", ""); + replaceAll(tokens[0], "v", ""); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] clientVersionString [%s], serverVersionString [%s] compatible [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,clientVersionString.c_str(),serverVersionString.c_str(),compatible); - for(int i = 0; compatible == true && i < 2; ++i) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (SystemFlags::VERBOSE_MODE_ENABLED) { + // debug version strings + for (unsigned int i = 0; i < tokensServer.size(); ++i) { + printf("Line Ref: %d Server version index = %u str [%s] IsNumeric = %d\n", __LINE__, i, tokensServer[i].c_str(), IsNumeric(tokensServer[i].c_str(), false)); + } + for (unsigned int i = 0; i < tokens.size(); ++i) { + printf("Line Ref: %d Client version index = %u str [%s] IsNumeric = %d\n", __LINE__, i, tokens[i].c_str(), IsNumeric(tokens[i].c_str(), false)); + } + } + // **NOTE: + // after of 3.7.0 we go to 2 digi version compatibility, check if both + // client and server are at least 3.7 + bool compatiblePre3_7_0_1_Check = true; - if(tokens[i] != tokensServer[i]) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] tokens[i] = [%s] tokensServer[i] = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,tokens[i].c_str(),tokensServer[i].c_str()); + if (tokens.size() >= 2 && tokensServer.size() >= 2) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + // Both Client and Server are >= to 3.7.0 + if (tokensServer[0] != "" && IsNumeric(tokensServer[0].c_str(), false) && strToInt(tokensServer[0]) >= 3 && + tokensServer[1] != "" && IsNumeric(tokensServer[1].c_str(), false) && strToInt(tokensServer[1]) >= 7 && + tokens[0] != "" && IsNumeric(tokens[0].c_str(), false) && strToInt(tokens[0]) >= 3 && + tokens[1] != "" && IsNumeric(tokens[1].c_str(), false) && strToInt(tokens[1]) >= 7) { + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + bool compatiblePost3_7_0_Check = false; + // Both are at least 3.7.0, now check if both are > 3.7.0 + if (tokens.size() >= 3 && tokensServer.size() >= 3) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if ((tokensServer[0] != "" && IsNumeric(tokensServer[0].c_str(), false) && strToInt(tokensServer[0]) >= 3 && + tokensServer[1] != "" && IsNumeric(tokensServer[1].c_str(), false) && strToInt(tokensServer[1]) >= 7 && + tokensServer[2] != "" && IsNumeric(tokensServer[2].c_str(), false) && strToInt(tokensServer[2]) > 0) && + (tokens[0] != "" && IsNumeric(tokens[0].c_str(), false) && strToInt(tokens[0]) >= 3 && + tokens[1] != "" && IsNumeric(tokens[1].c_str(), false) && strToInt(tokens[1]) >= 7 && + tokens[2] != "" && IsNumeric(tokens[2].c_str(), false) && strToInt(tokens[2]) > 0)) { + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + compatiblePost3_7_0_Check = true; + } + if (strToInt(tokensServer[0]) == strToInt(tokens[0]) && + strToInt(tokensServer[1]) == strToInt(tokens[1])) { + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if ((tokensServer[0] != "" && IsNumeric(tokensServer[0].c_str(), false) && strToInt(tokensServer[0]) == 3 && + tokensServer[1] != "" && IsNumeric(tokensServer[1].c_str(), false) && strToInt(tokensServer[1]) == 7 && + tokensServer[2] != "" && IsNumeric(tokensServer[2].c_str(), false) && strToInt(tokensServer[2]) == 0) || + (tokens[0] != "" && IsNumeric(tokens[0].c_str(), false) && strToInt(tokens[0]) == 3 && + tokens[1] != "" && IsNumeric(tokens[1].c_str(), false) && strToInt(tokens[1]) == 7 && + tokens[2] != "" && IsNumeric(tokens[2].c_str(), false) && strToInt(tokens[2]) == 0)) { + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + compatiblePost3_7_0_Check = false; + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + compatiblePost3_7_0_Check = true; + } + } + + } else { + // If both are > 3.7 use new version checking of 2 digits since both are higher than 3.7.0 + if ((tokensServer[0] != "" && IsNumeric(tokensServer[0].c_str(), false) && strToInt(tokensServer[0]) >= 3 && + tokensServer[1] != "" && IsNumeric(tokensServer[1].c_str(), false) && strToInt(tokensServer[1]) > 7) && + (tokens[0] != "" && IsNumeric(tokens[0].c_str(), false) && strToInt(tokens[0]) >= 3 && + tokens[1] != "" && IsNumeric(tokens[1].c_str(), false) && strToInt(tokens[1]) > 7)) { + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + compatiblePost3_7_0_Check = true; + } else { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + compatiblePost3_7_0_Check = true; + } + } + + if (compatiblePost3_7_0_Check == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + compatiblePre3_7_0_1_Check = false; + // only check the first 2 sections with . to compare major versions #'s + compatible = (tokens.size() >= 2 && tokensServer.size() >= 2); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] clientVersionString [%s], serverVersionString [%s] compatible [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, clientVersionString.c_str(), serverVersionString.c_str(), compatible); + + for (int i = 0; compatible == true && i < 2; ++i) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + + if (tokens[i] != tokensServer[i]) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] tokens[i] = [%s] tokensServer[i] = [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, tokens[i].c_str(), tokensServer[i].c_str()); + + compatible = false; + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] tokens[i] = [%s], tokensServer[i] = [%s] compatible [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, tokens[i].c_str(), tokensServer[i].c_str(), compatible); + } + } + + } + } + } + + if (compatiblePre3_7_0_1_Check == true) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__); + // only check the first 3 sections with . to compare makor versions #'s + compatible = (tokens.size() >= 3 && tokensServer.size() >= 3); + + if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem, "In [%s::%s Line: %d] clientVersionString [%s], serverVersionString [%s] compatible [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, clientVersionString.c_str(), serverVersionString.c_str(), compatible); + + for (int i = 0; compatible == true && i < 3; ++i) { + if (tokens[i] != tokensServer[i]) { compatible = false; - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] tokens[i] = [%s], tokensServer[i] = [%s] compatible [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,tokens[i].c_str(),tokensServer[i].c_str(),compatible); + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] tokens[i] = [%s], tokensServer[i] = [%s] compatible [%d]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, tokens[i].c_str(), tokensServer[i].c_str(), compatible); } } - } } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n------> In [%s::%s Line: %d] compatible returning as: %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, compatible); + + //SystemFlags::VERBOSE_MODE_ENABLED = false; + return compatible; } - if(compatiblePre3_7_0_1_Check == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - // only check the first 3 sections with . to compare makor versions #'s - compatible = (tokens.size() >= 3 && tokensServer.size() >= 3); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] clientVersionString [%s], serverVersionString [%s] compatible [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,clientVersionString.c_str(),serverVersionString.c_str(),compatible); - - for(int i = 0; compatible == true && i < 3; ++i) { - if(tokens[i] != tokensServer[i]) { - compatible = false; - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] tokens[i] = [%s], tokensServer[i] = [%s] compatible [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,tokens[i].c_str(),tokensServer[i].c_str(),compatible); - } - } - } } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n------> In [%s::%s Line: %d] compatible returning as: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,compatible); - - //SystemFlags::VERBOSE_MODE_ENABLED = false; - return compatible; -} - -}}//end namespace +}//end namespace diff --git a/source/shared_lib/sources/xml/xml_parser.cpp b/source/shared_lib/sources/xml/xml_parser.cpp index 4832fac19..1b3a2a951 100644 --- a/source/shared_lib/sources/xml/xml_parser.cpp +++ b/source/shared_lib/sources/xml/xml_parser.cpp @@ -45,1064 +45,1048 @@ XERCES_CPP_NAMESPACE_USE using namespace std; using namespace Shared::PlatformCommon; -namespace Shared { namespace Xml { +namespace Shared { + namespace Xml { -using namespace Util; + using namespace Util; -// ===================================================== -// class XmlIo -// ===================================================== -bool XmlIoRapid::initialized= false; + // ===================================================== + // class XmlIo + // ===================================================== + bool XmlIoRapid::initialized = false; #if defined(WANT_XERCES) -bool XmlIo::initialized = false; - -// ===================================================== -// class ErrorHandler -// ===================================================== - -class ErrorHandler: public DOMErrorHandler{ -public: - virtual bool handleError (const DOMError &domError){ - if(domError.getSeverity()== DOMError::DOM_SEVERITY_FATAL_ERROR){ - char msgStr[strSize], fileStr[strSize]; - XMLString::transcode(domError.getMessage(), msgStr, strSize-1); - XMLString::transcode(domError.getLocation()->getURI(), fileStr, strSize-1); - Shared::Platform::uint64 lineNumber= domError.getLocation()->getLineNumber(); - throw megaglest_runtime_error("Error parsing XML, file: " + string(fileStr) + ", line: " + intToStr(lineNumber) + ": " + string(msgStr)); - } - return true; - } -}; - -XmlIo::XmlIo() : parser(NULL) { - init(); -} - -XmlIo::~XmlIo() { - cleanup(); -} - -bool XmlIo::isInitialized() { - return XmlIo::initialized; -} - -void XmlIo::init() { - try{ - //printf("XmlIo init\n"); - XMLPlatformUtils::Initialize(); - - XmlIo::initialized= true; - } - catch(const XMLException &e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error initializing XML system, msg %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.getMessage()); - throw megaglest_runtime_error("Error initializing XML system"); - } - - try { - XMLCh str[strSize]; - XMLString::transcode("LS", str, strSize-1); - - implementation = DOMImplementationRegistry::getDOMImplementation(str); - } - catch(const DOMException &ex) { - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Exception while creating XML parser, msg: %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.getMessage()); - throw megaglest_runtime_error("Exception while creating XML parser"); - } -} - -XmlIo &XmlIo::getInstance() { - static XmlIo XmlIo; - if(XmlIo::initialized == false) { - XmlIo.init(); - } - return XmlIo; -} - -void XmlIo::cleanup() { - releaseDOMParser(); - if(XmlIo::initialized == true) { - XmlIo::initialized= false; - //printf("XmlIo cleanup\n"); - XMLPlatformUtils::Terminate(); - } -} - -#if XERCES_VERSION_MAJOR < 3 - XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * XmlIo::getRootDOMDocument(const string &path, DOMBuilder *parser, bool noValidation) { - XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *document= parser->parseURI(path.c_str()); - return document; - } -#else - XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * XmlIo::getRootDOMDocument(const string &path, DOMLSParser *parser, bool noValidation) { - XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *document= parser->parseURI(path.c_str()); - return document; - } -#endif - -void XmlIo::releaseDOMParser() { - if(parser != NULL) { - parser->release(); - parser = NULL; - } -} - -DOMNode *XmlIo::loadDOMNode(const string &path, bool noValidation) { - //printf("Load file using Xerces engine [%s]\n",path.c_str()); - - try { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("XERCES_FULLVERSIONDOT [%s]\nnoValidation = %d\npath [%s]\n",XERCES_FULLVERSIONDOT,noValidation,path.c_str()); - - ErrorHandler errorHandler; -#if XERCES_VERSION_MAJOR < 3 - parser= (static_cast(implementation))->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0); - parser->setErrorHandler(&errorHandler); - if(noValidation == false) { - parser->setFeature(XMLUni::fgXercesSchema, true); - parser->setFeature(XMLUni::fgXercesSchemaFullChecking, true); - //parser->setFeature(XMLUni::fgDOMValidateIfSchema, true); - parser->setFeature(XMLUni::fgDOMValidation, true); - } - else { - //parser->setFeature(XMLUni::fgSAX2CoreValidation, false); - //parser->setFeature(XMLUni::fgXercesDynamic, true); - - //parser->setFeature(XMLUni::fgXercesSchema, false); - //parser->setFeature(XMLUni::fgXercesSchemaFullChecking, false); - //parser->setFeature(XMLUni::fgDOMValidateIfSchema, true); - //parser->setFeature(XMLUni::fgDOMValidation, false); - - parser->setFeature(XMLUni::fgXercesSchemaFullChecking, false); - parser->setFeature(XMLUni::fgXercesLoadExternalDTD, false); - parser->setFeature(XMLUni::fgXercesCacheGrammarFromParse, true); - parser->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true); - } -#else - parser = (static_cast(implementation))->createLSParser(DOMImplementationLS::MODE_SYNCHRONOUS, 0); - DOMConfiguration *config = parser->getDomConfig(); - if(noValidation == false) { - config->setParameter(XMLUni::fgXercesSchema, true); - config->setParameter(XMLUni::fgXercesSchemaFullChecking, true); - //config->setParameter(XMLUni::fgDOMValidateIfSchema, true); - config->setParameter(XMLUni::fgDOMValidate, true); - } - else { - config->setParameter(XMLUni::fgXercesSchema, false); - config->setParameter(XMLUni::fgXercesSchemaFullChecking, false); - config->setParameter(XMLUni::fgXercesLoadExternalDTD, false); - config->setParameter(XMLUni::fgXercesCacheGrammarFromParse, true); - config->setParameter(XMLUni::fgXercesUseCachedGrammarInParse, true); - } -#endif - //XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *document= parser->parseURI(path.c_str()); - XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *document = getRootDOMDocument(path, parser, noValidation); - -#ifdef WIN32 - if(document == NULL) { - document= parser->parseURI(utf8_decode(path).c_str()); - } -#endif - if(document == NULL) { - throw megaglest_runtime_error("Can not parse URL: " + path); - } - - DOMNode *rootNode = document->getDocumentElement(); - return rootNode; - } - catch(const DOMException &ex) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] Exception while loading: [%s], msg:\n%s",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),XMLString::transcode(ex.msg)); - SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",szBuf); - - throw megaglest_runtime_error(szBuf); - } - return NULL; -} - -XmlNode *XmlIo::load(const string &path, const std::map &mapTagReplacementValues,bool noValidation,bool skipStackTrace) { - //printf("Load file using Xerces engine [%s]\n",path.c_str()); - - try { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("XERCES_FULLVERSIONDOT [%s]\nnoValidation = %d\npath [%s]\n",XERCES_FULLVERSIONDOT,noValidation,path.c_str()); - - DOMNode *domNode = loadDOMNode(path, noValidation); - XmlNode *rootNode= new XmlNode(domNode,mapTagReplacementValues); - releaseDOMParser(); - - return rootNode; - } - catch(const DOMException &ex) { - char szBuf[8096]=""; - if(skipStackTrace == false) { - snprintf(szBuf,8096,"In [%s::%s Line: %d] Exception while loading: [%s], msg:\n%s",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),XMLString::transcode(ex.msg)); - } - else { - snprintf(szBuf,8096,"Error loading: [%s], msg:\n%s",path.c_str(),XMLString::transcode(ex.msg)); - } - SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",szBuf); - - throw megaglest_runtime_error(szBuf,skipStackTrace); - } - return NULL; -} - -void XmlIo::save(const string &path, const XmlNode *node){ - //printf("Saving file using Xerces engine [%s]\n",path.c_str()); - - try{ - if(node == NULL) { - throw megaglest_runtime_error("node == NULL during save!"); - } - XMLCh str[strSize]; - XMLString::transcode(node->getName().c_str(), str, strSize-1); - - XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *document= implementation->createDocument(0, str, 0); - DOMElement *documentElement= document->getDocumentElement(); - for(unsigned int i = 0; i < node->getAttributeCount() ; ++i){ - XmlAttribute *attr = node->getAttribute(i); - - XMLCh strName[strSize]; - XMLString::transcode(attr->getName().c_str(), strName, strSize-1); - XMLCh strValue[strSize]; - XMLString::transcode(attr->getValue("",false).c_str(), strValue, strSize-1); - - documentElement->setAttribute(strName,strValue); - } - - for(unsigned int i=0; igetChildCount(); ++i){ - documentElement->appendChild(node->getChild(i)->buildElement(document)); - } - - LocalFileFormatTarget file(path.c_str()); -#if XERCES_VERSION_MAJOR < 3 - DOMWriter* writer = implementation->createDOMWriter(); - writer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true); - writer->writeNode(&file, *document); -#else - DOMLSSerializer *serializer = implementation->createLSSerializer(); - DOMLSOutput* output=implementation->createLSOutput(); - DOMConfiguration* config=serializer->getDomConfig(); - config->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint,true); - output->setByteStream(&file); - serializer->write(document,output); - output->release(); - serializer->release(); -#endif - document->release(); - } - catch(const DOMException &e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Exception while saving: [%s], %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),XMLString::transcode(e.msg)); - throw megaglest_runtime_error("Exception while saving: " + path + ": " + XMLString::transcode(e.msg)); - } -} - -#endif - -// ===================================================== -// class XmlIoRapid -// ===================================================== -XmlIoRapid::XmlIoRapid() { - init(); -} - -void XmlIoRapid::init() { - try{ - XmlIoRapid::initialized= true; - } - catch(const exception &e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error initializing XML system, msg %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,e.what()); - throw megaglest_runtime_error("Error initializing XML system"); - } -} - -bool XmlIoRapid::isInitialized() { - return XmlIoRapid::initialized; -} - -XmlIoRapid &XmlIoRapid::getInstance() { - static XmlIoRapid io; - if(XmlIoRapid::initialized == false) { - io.init(); - } - - return io; -} - -void XmlIoRapid::cleanup() { - if(XmlIoRapid::initialized == true) { - XmlIoRapid::initialized= false; - } -} - -XmlIoRapid::~XmlIoRapid() { - cleanup(); -} - -XmlNode *XmlIoRapid::load(const string &path, const std::map &mapTagReplacementValues, - bool noValidation,bool skipStackTrace,bool skipUpdatePathClimbingParts) { - bool showPerfStats = SystemFlags::VERBOSE_MODE_ENABLED; - Chrono chrono; - chrono.start(); - if(SystemFlags::VERBOSE_MODE_ENABLED || showPerfStats) printf("Using RapidXml to load file [%s]\n",path.c_str()); - //printf("Using RapidXml to load file [%s]\n",path.c_str()); - - XmlNode *rootNode = NULL; - try { - - if(folderExists(path) == true) { - throw megaglest_runtime_error("Can not open file: [" + path + "] as it is a folder!",true); - } - -#if defined(WIN32) && !defined(__MINGW32__) - FILE *fp = _wfopen(utf8_decode(path).c_str(), L"rb"); - ifstream xmlFile(fp); -#else - ifstream xmlFile(path.c_str(),ios::binary); -#endif - if(xmlFile.is_open() == false) { - throw megaglest_runtime_error("Can not open file: [" + path + "]",true); - } - - if(showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - - xmlFile.unsetf(ios::skipws); - - // Determine stream size - int64 file_size = -1; - if((double)xmlFile.tellg() != -1) { - streampos size1 = xmlFile.tellg(); - xmlFile.seekg(0, ios::end); - if((double)xmlFile.tellg() != -1) { - streampos size2 = xmlFile.tellg(); - xmlFile.seekg(0); - file_size = size2 - size1; - } - } - - if(showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - - if(file_size <= 0) { - throw megaglest_runtime_error("Invalid file size for file: [" + path + "] size = " + intToStr(file_size)); - } - //printf("File size is: " MG_I64_SPECIFIER " for [%s]\n",file_size,path.c_str()); - - // Load data and add terminating 0 - vector buffer; - buffer.resize((unsigned int)file_size + 100); - xmlFile.read(&buffer.front(), static_cast(file_size)); - buffer[(unsigned int)file_size] = 0; - - if(showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - - // This is required because rapidxml seems to choke when we load lua - // scenarios that have lua + xml style comments - replaceAllBetweenTokens(buffer, "", "", true); - - if(showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - - xml_document<> doc; - doc.parse(&buffer.front()); - - if(showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - - rootNode= new XmlNode(doc.first_node(),mapTagReplacementValues, skipUpdatePathClimbingParts); - - if(showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - -#if defined(WIN32) && !defined(__MINGW32__) - if(fp) { - fclose(fp); - } -#endif - } - catch(parse_error& ex) { -// char szBuf[8096]=""; -// snprintf(szBuf,8096,"%s",ex.where()); - throw megaglest_runtime_error("Error loading XML: "+ path + "\nMessage: " + ex.what() ,true); - } - catch(megaglest_runtime_error& ex) { - throw megaglest_runtime_error("Error loading XML: "+ path + "\nMessage: " + ex.what(),!ex.wantStackTrace() ); - } - catch(const exception &ex) { - char szBuf[8096]=""; - - if(skipStackTrace == false) { - snprintf(szBuf,8096,"In [%s::%s Line: %d] Exception while loading: [%s], msg:\n%s",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),ex.what()); - } - else { - snprintf(szBuf,8096,"Error loading: [%s], msg:\n%s",path.c_str(),ex.what()); - } - SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",szBuf); - - throw megaglest_runtime_error(szBuf,skipStackTrace); - } - - //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] took msecs: %ld for file [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),path.c_str()); - //printf("In [%s::%s Line: %d] took msecs: %ld for file [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),path.c_str()); - - return rootNode; -} - -void XmlIoRapid::save(const string &path, const XmlNode *node){ - try { - if(node == NULL) { - throw megaglest_runtime_error("node == NULL during save!"); - } - - xml_document<> doc; - - // xml declaration - xml_node<>* decl = doc.allocate_node(node_declaration); - decl->append_attribute(doc.allocate_attribute(doc.allocate_string("version"), doc.allocate_string("1.0"))); - decl->append_attribute(doc.allocate_attribute(doc.allocate_string("encoding"), doc.allocate_string("utf-8"))); - decl->append_attribute(doc.allocate_attribute(doc.allocate_string("standalone"), doc.allocate_string("no"))); - doc.append_node(decl); - - // root node - xml_node<>* root = doc.allocate_node(node_element, doc.allocate_string(node->getName().c_str())); - for(unsigned int i = 0; i < node->getAttributeCount() ; ++i){ - XmlAttribute *attr = node->getAttribute(i); - root->append_attribute(doc.allocate_attribute( - doc.allocate_string(attr->getName().c_str()), - doc.allocate_string(attr->getValue("",false).c_str()))); - } - doc.append_node(root); - - // child nodes - for(unsigned int i = 0; i < node->getChildCount(); ++i) { - root->append_node(node->getChild(i)->buildElement(&doc)); - } - -// std::string xml_as_string; -// // watch for name collisions here, print() is a very common function name! -// print(std::back_inserter(xml_as_string), doc); -// // xml_as_string now contains the XML in string form, indented -// // (in all its angle bracket glory) -// -// std::string xml_no_indent; -// // print_no_indenting is the only flag that print() knows about -// print(std::back_inserter(xml_no_indent), doc, print_no_indenting); -// // xml_no_indent now contains non-indented XML - -#if defined(WIN32) && !defined(__MINGW32__) - FILE *fp = _wfopen(utf8_decode(path).c_str(), L"wb"); - ofstream xmlFile(fp); -#else - ofstream xmlFile(path.c_str(),ios::binary); -#endif - if(xmlFile.is_open() == false) { - throw megaglest_runtime_error("Can not open file: [" + path + "]"); - } - - //xmlFile << xml_no_indent; -// xmlFile << xml_as_string; - xmlFile << doc; - -#if defined(WIN32) && !defined(__MINGW32__) - if(fp) { - fclose(fp); - } -#endif - } - catch(const exception &e){ - SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Exception while saving: [%s], %s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),e.what()); - throw megaglest_runtime_error("Exception while saving [" + path + "] msg: " + e.what()); - } -} - -// ===================================================== -// class XmlTree -// ===================================================== -XmlTree::XmlTree(xml_engine_parser_type engine_type) { - rootNode= NULL; - - switch(engine_type) { -#if defined(WANT_XERCES) - case XML_XERCES_ENGINE: - break; -#endif - case XML_RAPIDXML_ENGINE: - break; - - default: - throw megaglest_runtime_error("Invalid XML parser engine: " + intToStr((int)engine_type)); - } - - this->engine_type = engine_type; - this->skipStackCheck = false; - this->skipUpdatePathClimbingParts = false; -} - -void XmlTree::init(const string &name){ - clearRootNode(); - this->rootNode= new XmlNode(name); -} - -typedef std::vector LoadStack; -//static LoadStack loadStack; -static string loadStackCacheName = string(__FILE__) + string("_loadStackCacheName"); - -void XmlTree::setSkipUpdatePathClimbingParts(bool value) { - this->skipUpdatePathClimbingParts = value; -} - -void XmlTree::load(const string &path, const std::map &mapTagReplacementValues, bool noValidation,bool skipStackCheck,bool skipStackTrace) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s] skipStackCheck = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),skipStackCheck); - - clearRootNode(); - - this->skipStackCheck = skipStackCheck; - if(this->skipStackCheck == false) { - //printf("XmlTree::load p [%p]\n",this); - assert(!loadPath.size()); - - LoadStack &loadStack = CacheManager::getCachedItem(loadStackCacheName); - Mutex &mutex = CacheManager::getMutexForItem(loadStackCacheName); - MutexSafeWrapper safeMutex(&mutex); - - for(LoadStack::iterator it= loadStack.begin(); it!= loadStack.end(); ++it){ - if((*it)->loadPath == path){ - throw megaglest_runtime_error(path + " recursively included"); - } - } - loadStack.push_back(this); - safeMutex.ReleaseLock(); - } - - loadPath = path; - -#if defined(WANT_XERCES) - if(this->engine_type == XML_XERCES_ENGINE) { - this->rootNode= XmlIo::getInstance().load(path, mapTagReplacementValues, noValidation,skipStackTrace); - } - else -#endif - { - this->rootNode= XmlIoRapid::getInstance().load(path, mapTagReplacementValues, noValidation,skipStackTrace, this->skipUpdatePathClimbingParts); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str()); -} - -void XmlTree::save(const string &path) { - -#if defined(WANT_XERCES) - if(this->engine_type == XML_XERCES_ENGINE) { - XmlIo::getInstance().save(path, rootNode); - } - else -#endif - { - XmlIoRapid::getInstance().save(path, rootNode); - } -} - -void XmlTree::clearRootNode() { - if(this->skipStackCheck == false) { - LoadStack &loadStack = CacheManager::getCachedItem(loadStackCacheName); - Mutex &mutex = CacheManager::getMutexForItem(loadStackCacheName); - MutexSafeWrapper safeMutex(&mutex); - - LoadStack::iterator it= find(loadStack.begin(),loadStack.end(),this); - if(it != loadStack.end()) { - loadStack.erase(it); - } - safeMutex.ReleaseLock(); - } - - delete rootNode; - rootNode=NULL; -} - -XmlTree::~XmlTree() { - //printf("XmlTree::~XmlTree p [%p]\n",this); - clearRootNode(); -} - -// ===================================================== -// class XmlNode -// ===================================================== - -#if defined(WANT_XERCES) - -XmlNode::XmlNode(DOMNode *node, const std::map &mapTagReplacementValues): superNode(NULL) { - if(node == NULL || node->getNodeName() == NULL) { - throw megaglest_runtime_error("XML structure seems to be corrupt!",true); - } - - //get name - char str[strSize]=""; - XMLString::transcode(node->getNodeName(), str, strSize-1); - name= str; - - //check document - if(node->getNodeType() == DOMNode::DOCUMENT_NODE) { - name="document"; - } - - //check children - if(node->getChildNodes() != NULL) { - for(unsigned int i = 0; i < node->getChildNodes()->getLength(); ++i) { - DOMNode *currentNode= node->getChildNodes()->item(i); - if(currentNode != NULL && currentNode->getNodeType()==DOMNode::ELEMENT_NODE){ - XmlNode *xmlNode= new XmlNode(currentNode, mapTagReplacementValues); - children.push_back(xmlNode); - } - } - } - - //check attributes - DOMNamedNodeMap *domAttributes= node->getAttributes(); - if(domAttributes != NULL) { - for(unsigned int i = 0; i < domAttributes->getLength(); ++i) { - DOMNode *currentNode= domAttributes->item(i); - if(currentNode->getNodeType() == DOMNode::ATTRIBUTE_NODE) { - XmlAttribute *xmlAttribute= new XmlAttribute(domAttributes->item(i), mapTagReplacementValues); - attributes.push_back(xmlAttribute); - } - } - } - - //get value - if(node->getNodeType() == DOMNode::ELEMENT_NODE && children.size() == 0) { - char *textStr= XMLString::transcode(node->getTextContent()); - text= textStr; - //Properties::applyTagsToValue(this->text); - XMLString::release(&textStr); - } -} - -#endif - -XmlNode::XmlNode(xml_node<> *node, const std::map &mapTagReplacementValues, - bool skipUpdatePathClimbingParts) : superNode(NULL) { - if(node == NULL || node->name() == NULL) { - throw megaglest_runtime_error("XML structure seems to be corrupt!",true); - } - - //get name - name = node->name(); - children.reserve(1000); - attributes.reserve(1000); - - //check document - if(node->type() == node_document) { - name="document"; - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Found XML Node\nName [%s]\nValue [%s]\n",name.c_str(),node->value()); - - //check children - for(xml_node<> *currentNode = node->first_node(); - currentNode; currentNode = currentNode->next_sibling()) { - if(currentNode != NULL && currentNode->type() == node_element) { - XmlNode *xmlNode= new XmlNode(currentNode, mapTagReplacementValues, skipUpdatePathClimbingParts); - children.push_back(xmlNode); - } - } - - //check attributes - for (xml_attribute<> *attr = node->first_attribute(); - attr; attr = attr->next_attribute()) { - XmlAttribute *xmlAttribute= new XmlAttribute(attr, mapTagReplacementValues); - attributes.push_back(xmlAttribute); - } - - //get value - if(node->type() == node_element && children.size() == 0) { - string xmlText = node->value(); - -// bool debugReplace = false; -// if(xmlText.find("{SCENARIOPATH}") != string::npos) { -// printf("\n----------------------\n** XML!! WILL REPLACE [%s]\n",xmlText.c_str()); -// debugReplace = true; -// } - Properties::applyTagsToValue(xmlText,&mapTagReplacementValues, skipUpdatePathClimbingParts); -// if(debugReplace) { -// printf("\n\n** XML!! REPLACED WITH [%s]\n===================\n",xmlText.c_str()); -// } - text = xmlText; - } -} - -XmlNode::XmlNode(const string &name): superNode(NULL) { - this->name= name; -} - -XmlNode::~XmlNode() { - for(unsigned int i=0; i= attributes.size()) { - throw megaglest_runtime_error(getName()+" node doesn't have " + uIntToStr(i) + " attributes",true); - } - return attributes[i]; -} - -XmlAttribute *XmlNode::getAttribute(const string &name,bool mustExist) const { - for(unsigned int i = 0; i < attributes.size(); ++i) { - if(attributes[i]->getName() == name) { - return attributes[i]; - } - } - if(mustExist == true) { - throw megaglest_runtime_error("\"" + getName() + "\" node doesn't have a attribute named \"" + name + "\"",true); - } - - return NULL; -} - -bool XmlNode::hasAttribute(const string &name) const { - bool result = false; - for(unsigned int i = 0; i < attributes.size(); ++i) { - if(attributes[i]->getName() == name) { - result = true; - break; - } - } - return result; -} - -int XmlNode::clearChild(const string &childName) { - int clearChildCount = 0; - for(int i = (int)children.size()-1; i >= 0; --i) { - if(children[i]->getName() == childName) { - delete children[i]; - children.erase(children.begin()+i); - clearChildCount++; - } - } - return clearChildCount; -} - -XmlNode *XmlNode::getChild(unsigned int i) const { - assert(!superNode); - if(i >= children.size()) { - throw megaglest_runtime_error("\"" + getName()+"\" node doesn't have "+ uIntToStr(i+1) + " children", true); - } - return children[i]; -} - -vector XmlNode::getChildList(const string &childName) const { - vector list; - for(unsigned int j = 0; j < children.size(); ++j) { - if(children[j]->getName() == childName) { - list.push_back(children[j]); - } - } - - return list; -} - -XmlNode *XmlNode::getChild(const string &childName, unsigned int i) const { - if(superNode && hasChildNoSuper(childName) == false) { - return superNode->getChild(childName,i); - } - if(i >= children.size()) { - throw megaglest_runtime_error("\"" + name + "\" node doesn't have " + uIntToStr(i+1) +" children named \"" + childName + "\"\n\nTree: "+getTreeString(),true); - } - - unsigned int count= 0; - for(unsigned int j = 0; j < children.size(); ++j) { - if(children[j]->getName() == childName) { - if(count == i) { - return children[j]; - } - count++; - } - } - - throw megaglest_runtime_error("Node \""+getName()+"\" doesn't have " + uIntToStr(i+1) + " children named \""+childName+"\"\n\nTree: "+getTreeString(),true); -} - -bool XmlNode::hasChildNoSuper(const string &childName) const { - //int count= 0; - for(unsigned int j = 0; j < children.size(); ++j) { - if(children[j]->getName() == childName) { - return true; - } - } - return false; -} -XmlNode * XmlNode::getChildWithAliases(vector childNameList, unsigned int childIndex) const { - for(int aliasIndex = 0; aliasIndex < (int)childNameList.size(); ++aliasIndex) { - const string &childName = childNameList[aliasIndex]; - if(superNode && hasChildNoSuper(childName) == false) { - return superNode->getChild(childName,childIndex); - } - if(childIndex >= children.size()) { - throw megaglest_runtime_error("\"" + name + "\" node doesn't have "+intToStr(childIndex+1)+" children named \"" + childName + "\"\n\nTree: "+getTreeString(),true); - } - - unsigned int count= 0; - for(unsigned int j = 0; j < children.size(); ++j) { - if(children[j]->getName() == childName) { - if(count == childIndex) { - return children[j]; + bool XmlIo::initialized = false; + + // ===================================================== + // class ErrorHandler + // ===================================================== + + class ErrorHandler : public DOMErrorHandler { + public: + virtual bool handleError(const DOMError &domError) { + if (domError.getSeverity() == DOMError::DOM_SEVERITY_FATAL_ERROR) { + char msgStr[strSize], fileStr[strSize]; + XMLString::transcode(domError.getMessage(), msgStr, strSize - 1); + XMLString::transcode(domError.getLocation()->getURI(), fileStr, strSize - 1); + Shared::Platform::uint64 lineNumber = domError.getLocation()->getLineNumber(); + throw megaglest_runtime_error("Error parsing XML, file: " + string(fileStr) + ", line: " + intToStr(lineNumber) + ": " + string(msgStr)); } - count++; - } - } - } - - throw megaglest_runtime_error("Node \""+getName()+"\" doesn't have "+intToStr(childIndex+1)+" children named \""+ (childNameList.empty() ? "???" : childNameList[0]) +"\"\n\nTree: "+getTreeString(),true); -} - -bool XmlNode::hasChildAtIndex(const string &childName, int i) const { - if(superNode && !hasChildNoSuper(childName)) - return superNode->hasChildAtIndex(childName,i); - int count= 0; - for(unsigned int j = 0; j < children.size(); ++j) { - //printf("Looking for [%s] at index: %d found [%s] index = %d\n",childName.c_str(),i,children[j]->getName().c_str(),j); - if(children[j]->getName()==childName) { - if(count == i) { return true; } - count++; + }; + + XmlIo::XmlIo() : parser(NULL) { + init(); } - } - return false; -} - -bool XmlNode::hasChild(const string &childName) const { - return hasChildNoSuper(childName) || (superNode && superNode->hasChild(childName)); -} - -bool XmlNode::hasChildWithAliases(vector childNameList) const { - bool result = false; - for(int aliasIndex = 0; aliasIndex < (int)childNameList.size(); ++aliasIndex) { - const string &childName = childNameList[aliasIndex]; - result = hasChild(childName); - if(result == true) { - break; + XmlIo::~XmlIo() { + cleanup(); } - } - return result; -} -XmlNode *XmlNode::addChild(const string &name, const string text) { - assert(!superNode); - XmlNode *node= new XmlNode(name); - node->text = text; - children.push_back(node); - return node; -} - -XmlAttribute *XmlNode::addAttribute(const string &name, const string &value, const std::map &mapTagReplacementValues) { - XmlAttribute *attr= new XmlAttribute(name, value, mapTagReplacementValues); - attributes.push_back(attr); - return attr; -} - -#if defined(WANT_XERCES) - -DOMElement *XmlNode::buildElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *document) const{ - XMLCh str[strSize]; - XMLString::transcode(name.c_str(), str, strSize-1); - - DOMElement *node= document->createElement(str); - - for(unsigned int i=0; igetName().c_str(), str, strSize-1); - DOMAttr *attr= document->createAttribute(str); - - XMLString::transcode(attributes[i]->getValue().c_str(), str, strSize-1); - attr->setValue(str); - - node->setAttributeNode(attr); - } - - for(unsigned int i=0; iappendChild(children[i]->buildElement(document)); - } - - return node; -} - -#endif - -xml_node<>* XmlNode::buildElement(xml_document<> *document) const { - xml_node<>* node = document->allocate_node(node_element, document->allocate_string(name.c_str())); - - for(unsigned int i = 0; i < attributes.size(); ++i) { - node->append_attribute( - document->allocate_attribute( - document->allocate_string(attributes[i]->getName().c_str()), - document->allocate_string(attributes[i]->getValue().c_str()))); - } - - for(unsigned int i = 0; i < children.size(); ++i) { - node->append_node(children[i]->buildElement(document)); - } - - return node; -} - -string XmlNode::getTreeString() const { - string str; - - str+= getName(); - - if(!children.empty()) { - str+= " ("; - for(unsigned int i=0; igetTreeString(); - str+= " "; + bool XmlIo::isInitialized() { + return XmlIo::initialized; } - str+=") "; - } - return str; -} + void XmlIo::init() { + try { + //printf("XmlIo init\n"); + XMLPlatformUtils::Initialize(); -// ===================================================== -// class XmlAttribute -// ===================================================== + XmlIo::initialized = true; + } catch (const XMLException &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error initializing XML system, msg %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.getMessage()); + throw megaglest_runtime_error("Error initializing XML system"); + } -#if defined(WANT_XERCES) + try { + XMLCh str[strSize]; + XMLString::transcode("LS", str, strSize - 1); -XmlAttribute::XmlAttribute(DOMNode *attribute, const std::map &mapTagReplacementValues) { - if(attribute == NULL || attribute->getNodeName() == NULL) { - throw megaglest_runtime_error("XML attribute seems to be corrupt!"); - } - - skipRestrictionCheck = false; - usesCommondata = false; - this->mapTagReplacementValues = mapTagReplacementValues; - char str[strSize] = ""; - - XMLString::transcode(attribute->getNodeValue(), str, strSize-1); - value= str; - usesCommondata = ((value.find("$COMMONDATAPATH") != string::npos) || (value.find("%%COMMONDATAPATH%%") != string::npos)); - skipRestrictionCheck = Properties::applyTagsToValue(this->value,&this->mapTagReplacementValues); - - XMLString::transcode(attribute->getNodeName(), str, strSize-1); - name= str; -} - -#endif - -XmlAttribute::XmlAttribute(xml_attribute<> *attribute, const std::map &mapTagReplacementValues) { - if(attribute == NULL || attribute->name() == NULL) { - throw megaglest_runtime_error("XML attribute seems to be corrupt!"); - } - - skipRestrictionCheck = false; - usesCommondata = false; - if(mapTagReplacementValues.size() > 0) { - this->mapTagReplacementValues = mapTagReplacementValues; - } - //char str[strSize] = ""; - - //XMLString::transcode(attribute->getNodeValue(), str, strSize-1); - value= attribute->value(); - usesCommondata = ((value.find("$COMMONDATAPATH") != string::npos) || (value.find("%%COMMONDATAPATH%%") != string::npos)); - skipRestrictionCheck = Properties::applyTagsToValue(this->value,&this->mapTagReplacementValues); - - //XMLString::transcode(attribute->getNodeName(), str, strSize-1); - name= attribute->name(); -} - -XmlAttribute::XmlAttribute(const string &name, const string &value, const std::map &mapTagReplacementValues) { - skipRestrictionCheck = false; - usesCommondata = false; - if(mapTagReplacementValues.size() > 0) { - this->mapTagReplacementValues = mapTagReplacementValues; - } - this->name = name; - this->value = value; - - usesCommondata = ((value.find("$COMMONDATAPATH") != string::npos) || (value.find("%%COMMONDATAPATH%%") != string::npos)); - skipRestrictionCheck = Properties::applyTagsToValue(this->value,&this->mapTagReplacementValues); -} - -bool XmlAttribute::getBoolValue() const { - if(value == "true") { - return true; - } - else if(value == "false") { - return false; - } - else { - throw megaglest_runtime_error("Not a valid bool value (true or false): " +getName()+": "+ value,true); - } -} - -int XmlAttribute::getIntValue() const { - return strToInt(value); -} - -uint32 XmlAttribute::getUIntValue() const { - return strToUInt(value); -} - -int XmlAttribute::getIntValue(int min, int max) const { - int i= strToInt(value); - if(imax){ - throw megaglest_runtime_error("Xml Attribute int out of range: " + getName() + ": " + value,true); - } - return i; -} - -float XmlAttribute::getFloatValue() const{ - return strToFloat(value); -} - -float XmlAttribute::getFloatValue(float min, float max) const{ - float f= strToFloat(value); - //printf("getFloatValue f = %.10f [%s]\n",f,value.c_str()); - if(fmax){ - throw megaglest_runtime_error("Xml attribute float out of range: " + getName() + ": " + value,true); - } - return f; -} - -const string XmlAttribute::getValue(string prefixValue, bool trimValueWithStartingSlash) const { - string result = value; - if(skipRestrictionCheck == false && usesCommondata == false) { - if(trimValueWithStartingSlash == true) { - trimPathWithStartingSlash(result); - } - result = prefixValue + result; - } - return result; -} - -const string XmlAttribute::getRestrictedValue(string prefixValue, bool trimValueWithStartingSlash) const { - if(skipRestrictionCheck == false && usesCommondata == false) { - const string allowedCharacters = "abcdefghijklmnopqrstuvwxyz1234567890._-/"; - - for(unsigned int i= 0; iparseURI(path.c_str()); + return document; + } +#else + XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument * XmlIo::getRootDOMDocument(const string &path, DOMLSParser *parser, bool noValidation) { + XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *document = parser->parseURI(path.c_str()); + return document; + } +#endif + + void XmlIo::releaseDOMParser() { + if (parser != NULL) { + parser->release(); + parser = NULL; + } + } + + DOMNode *XmlIo::loadDOMNode(const string &path, bool noValidation) { + //printf("Load file using Xerces engine [%s]\n",path.c_str()); + + try { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("XERCES_FULLVERSIONDOT [%s]\nnoValidation = %d\npath [%s]\n", XERCES_FULLVERSIONDOT, noValidation, path.c_str()); + + ErrorHandler errorHandler; +#if XERCES_VERSION_MAJOR < 3 + parser = (static_cast(implementation))->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0); + parser->setErrorHandler(&errorHandler); + if (noValidation == false) { + parser->setFeature(XMLUni::fgXercesSchema, true); + parser->setFeature(XMLUni::fgXercesSchemaFullChecking, true); + //parser->setFeature(XMLUni::fgDOMValidateIfSchema, true); + parser->setFeature(XMLUni::fgDOMValidation, true); + } else { + //parser->setFeature(XMLUni::fgSAX2CoreValidation, false); + //parser->setFeature(XMLUni::fgXercesDynamic, true); + + //parser->setFeature(XMLUni::fgXercesSchema, false); + //parser->setFeature(XMLUni::fgXercesSchemaFullChecking, false); + //parser->setFeature(XMLUni::fgDOMValidateIfSchema, true); + //parser->setFeature(XMLUni::fgDOMValidation, false); + + parser->setFeature(XMLUni::fgXercesSchemaFullChecking, false); + parser->setFeature(XMLUni::fgXercesLoadExternalDTD, false); + parser->setFeature(XMLUni::fgXercesCacheGrammarFromParse, true); + parser->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true); + } +#else + parser = (static_cast(implementation))->createLSParser(DOMImplementationLS::MODE_SYNCHRONOUS, 0); + DOMConfiguration *config = parser->getDomConfig(); + if (noValidation == false) { + config->setParameter(XMLUni::fgXercesSchema, true); + config->setParameter(XMLUni::fgXercesSchemaFullChecking, true); + //config->setParameter(XMLUni::fgDOMValidateIfSchema, true); + config->setParameter(XMLUni::fgDOMValidate, true); + } else { + config->setParameter(XMLUni::fgXercesSchema, false); + config->setParameter(XMLUni::fgXercesSchemaFullChecking, false); + config->setParameter(XMLUni::fgXercesLoadExternalDTD, false); + config->setParameter(XMLUni::fgXercesCacheGrammarFromParse, true); + config->setParameter(XMLUni::fgXercesUseCachedGrammarInParse, true); + } +#endif + //XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *document= parser->parseURI(path.c_str()); + XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *document = getRootDOMDocument(path, parser, noValidation); + +#ifdef WIN32 + if (document == NULL) { + document = parser->parseURI(utf8_decode(path).c_str()); + } +#endif + if (document == NULL) { + throw megaglest_runtime_error("Can not parse URL: " + path); + } + + DOMNode *rootNode = document->getDocumentElement(); + return rootNode; + } catch (const DOMException &ex) { + char szBuf[8096] = ""; + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Exception while loading: [%s], msg:\n%s", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, path.c_str(), XMLString::transcode(ex.msg)); + SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", szBuf); + + throw megaglest_runtime_error(szBuf); + } + return NULL; + } + + XmlNode *XmlIo::load(const string &path, const std::map &mapTagReplacementValues, bool noValidation, bool skipStackTrace) { + //printf("Load file using Xerces engine [%s]\n",path.c_str()); + + try { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("XERCES_FULLVERSIONDOT [%s]\nnoValidation = %d\npath [%s]\n", XERCES_FULLVERSIONDOT, noValidation, path.c_str()); + + DOMNode *domNode = loadDOMNode(path, noValidation); + XmlNode *rootNode = new XmlNode(domNode, mapTagReplacementValues); + releaseDOMParser(); + + return rootNode; + } catch (const DOMException &ex) { + char szBuf[8096] = ""; + if (skipStackTrace == false) { + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Exception while loading: [%s], msg:\n%s", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, path.c_str(), XMLString::transcode(ex.msg)); + } else { + snprintf(szBuf, 8096, "Error loading: [%s], msg:\n%s", path.c_str(), XMLString::transcode(ex.msg)); + } + SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", szBuf); + + throw megaglest_runtime_error(szBuf, skipStackTrace); + } + return NULL; + } + + void XmlIo::save(const string &path, const XmlNode *node) { + //printf("Saving file using Xerces engine [%s]\n",path.c_str()); + + try { + if (node == NULL) { + throw megaglest_runtime_error("node == NULL during save!"); + } + XMLCh str[strSize]; + XMLString::transcode(node->getName().c_str(), str, strSize - 1); + + XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *document = implementation->createDocument(0, str, 0); + DOMElement *documentElement = document->getDocumentElement(); + for (unsigned int i = 0; i < node->getAttributeCount(); ++i) { + XmlAttribute *attr = node->getAttribute(i); + + XMLCh strName[strSize]; + XMLString::transcode(attr->getName().c_str(), strName, strSize - 1); + XMLCh strValue[strSize]; + XMLString::transcode(attr->getValue("", false).c_str(), strValue, strSize - 1); + + documentElement->setAttribute(strName, strValue); + } + + for (unsigned int i = 0; i < node->getChildCount(); ++i) { + documentElement->appendChild(node->getChild(i)->buildElement(document)); + } + + LocalFileFormatTarget file(path.c_str()); +#if XERCES_VERSION_MAJOR < 3 + DOMWriter* writer = implementation->createDOMWriter(); + writer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true); + writer->writeNode(&file, *document); +#else + DOMLSSerializer *serializer = implementation->createLSSerializer(); + DOMLSOutput* output = implementation->createLSOutput(); + DOMConfiguration* config = serializer->getDomConfig(); + config->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true); + output->setByteStream(&file); + serializer->write(document, output); + output->release(); + serializer->release(); +#endif + document->release(); + } catch (const DOMException &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Exception while saving: [%s], %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, path.c_str(), XMLString::transcode(e.msg)); + throw megaglest_runtime_error("Exception while saving: " + path + ": " + XMLString::transcode(e.msg)); + } + } + +#endif + + // ===================================================== + // class XmlIoRapid + // ===================================================== + XmlIoRapid::XmlIoRapid() { + init(); + } + + void XmlIoRapid::init() { + try { + XmlIoRapid::initialized = true; + } catch (const exception &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Error initializing XML system, msg %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, e.what()); + throw megaglest_runtime_error("Error initializing XML system"); + } + } + + bool XmlIoRapid::isInitialized() { + return XmlIoRapid::initialized; + } + + XmlIoRapid &XmlIoRapid::getInstance() { + static XmlIoRapid io; + if (XmlIoRapid::initialized == false) { + io.init(); + } + + return io; + } + + void XmlIoRapid::cleanup() { + if (XmlIoRapid::initialized == true) { + XmlIoRapid::initialized = false; + } + } + + XmlIoRapid::~XmlIoRapid() { + cleanup(); + } + + XmlNode *XmlIoRapid::load(const string &path, const std::map &mapTagReplacementValues, + bool noValidation, bool skipStackTrace, bool skipUpdatePathClimbingParts) { + bool showPerfStats = SystemFlags::VERBOSE_MODE_ENABLED; + Chrono chrono; + chrono.start(); + if (SystemFlags::VERBOSE_MODE_ENABLED || showPerfStats) printf("Using RapidXml to load file [%s]\n", path.c_str()); + //printf("Using RapidXml to load file [%s]\n",path.c_str()); + + XmlNode *rootNode = NULL; + try { + + if (folderExists(path) == true) { + throw megaglest_runtime_error("Can not open file: [" + path + "] as it is a folder!", true); + } + +#if defined(WIN32) && !defined(__MINGW32__) + FILE *fp = _wfopen(utf8_decode(path).c_str(), L"rb"); + ifstream xmlFile(fp); +#else + ifstream xmlFile(path.c_str(), ios::binary); +#endif + if (xmlFile.is_open() == false) { + throw megaglest_runtime_error("Can not open file: [" + path + "]", true); + } + + if (showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + + xmlFile.unsetf(ios::skipws); + + // Determine stream size + int64 file_size = -1; + if ((double) xmlFile.tellg() != -1) { + streampos size1 = xmlFile.tellg(); + xmlFile.seekg(0, ios::end); + if ((double) xmlFile.tellg() != -1) { + streampos size2 = xmlFile.tellg(); + xmlFile.seekg(0); + file_size = size2 - size1; + } + } + + if (showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + + if (file_size <= 0) { + throw megaglest_runtime_error("Invalid file size for file: [" + path + "] size = " + intToStr(file_size)); + } + //printf("File size is: " MG_I64_SPECIFIER " for [%s]\n",file_size,path.c_str()); + + // Load data and add terminating 0 + vector buffer; + buffer.resize((unsigned int) file_size + 100); + xmlFile.read(&buffer.front(), static_cast(file_size)); + buffer[(unsigned int) file_size] = 0; + + if (showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + + // This is required because rapidxml seems to choke when we load lua + // scenarios that have lua + xml style comments + replaceAllBetweenTokens(buffer, "", "", true); + + if (showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + + xml_document<> doc; + doc.parse(&buffer.front()); + + if (showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + + rootNode = new XmlNode(doc.first_node(), mapTagReplacementValues, skipUpdatePathClimbingParts); + + if (showPerfStats) printf("In [%s::%s Line: %d] took msecs: " MG_I64_SPECIFIER "\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, chrono.getMillis()); + +#if defined(WIN32) && !defined(__MINGW32__) + if (fp) { + fclose(fp); + } +#endif + } catch (parse_error& ex) { + // char szBuf[8096]=""; + // snprintf(szBuf,8096,"%s",ex.where()); + throw megaglest_runtime_error("Error loading XML: " + path + "\nMessage: " + ex.what(), true); + } catch (megaglest_runtime_error& ex) { + throw megaglest_runtime_error("Error loading XML: " + path + "\nMessage: " + ex.what(), !ex.wantStackTrace()); + } catch (const exception &ex) { + char szBuf[8096] = ""; + + if (skipStackTrace == false) { + snprintf(szBuf, 8096, "In [%s::%s Line: %d] Exception while loading: [%s], msg:\n%s", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, path.c_str(), ex.what()); + } else { + snprintf(szBuf, 8096, "Error loading: [%s], msg:\n%s", path.c_str(), ex.what()); + } + SystemFlags::OutputDebug(SystemFlags::debugError, "%s\n", szBuf); + + throw megaglest_runtime_error(szBuf, skipStackTrace); + } + + //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] took msecs: %ld for file [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),path.c_str()); + //printf("In [%s::%s Line: %d] took msecs: %ld for file [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),path.c_str()); + + return rootNode; + } + + void XmlIoRapid::save(const string &path, const XmlNode *node) { + try { + if (node == NULL) { + throw megaglest_runtime_error("node == NULL during save!"); + } + + xml_document<> doc; + + // xml declaration + xml_node<>* decl = doc.allocate_node(node_declaration); + decl->append_attribute(doc.allocate_attribute(doc.allocate_string("version"), doc.allocate_string("1.0"))); + decl->append_attribute(doc.allocate_attribute(doc.allocate_string("encoding"), doc.allocate_string("utf-8"))); + decl->append_attribute(doc.allocate_attribute(doc.allocate_string("standalone"), doc.allocate_string("no"))); + doc.append_node(decl); + + // root node + xml_node<>* root = doc.allocate_node(node_element, doc.allocate_string(node->getName().c_str())); + for (unsigned int i = 0; i < node->getAttributeCount(); ++i) { + XmlAttribute *attr = node->getAttribute(i); + root->append_attribute(doc.allocate_attribute( + doc.allocate_string(attr->getName().c_str()), + doc.allocate_string(attr->getValue("", false).c_str()))); + } + doc.append_node(root); + + // child nodes + for (unsigned int i = 0; i < node->getChildCount(); ++i) { + root->append_node(node->getChild(i)->buildElement(&doc)); + } + + // std::string xml_as_string; + // // watch for name collisions here, print() is a very common function name! + // print(std::back_inserter(xml_as_string), doc); + // // xml_as_string now contains the XML in string form, indented + // // (in all its angle bracket glory) + // + // std::string xml_no_indent; + // // print_no_indenting is the only flag that print() knows about + // print(std::back_inserter(xml_no_indent), doc, print_no_indenting); + // // xml_no_indent now contains non-indented XML + +#if defined(WIN32) && !defined(__MINGW32__) + FILE *fp = _wfopen(utf8_decode(path).c_str(), L"wb"); + ofstream xmlFile(fp); +#else + ofstream xmlFile(path.c_str(), ios::binary); +#endif + if (xmlFile.is_open() == false) { + throw megaglest_runtime_error("Can not open file: [" + path + "]"); + } + + //xmlFile << xml_no_indent; + // xmlFile << xml_as_string; + xmlFile << doc; + +#if defined(WIN32) && !defined(__MINGW32__) + if (fp) { + fclose(fp); + } +#endif + } catch (const exception &e) { + SystemFlags::OutputDebug(SystemFlags::debugError, "In [%s::%s Line: %d] Exception while saving: [%s], %s\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, path.c_str(), e.what()); + throw megaglest_runtime_error("Exception while saving [" + path + "] msg: " + e.what()); + } + } + + // ===================================================== + // class XmlTree + // ===================================================== + XmlTree::XmlTree(xml_engine_parser_type engine_type) { + rootNode = NULL; + + switch (engine_type) { +#if defined(WANT_XERCES) + case XML_XERCES_ENGINE: + break; +#endif + case XML_RAPIDXML_ENGINE: + break; + + default: + throw megaglest_runtime_error("Invalid XML parser engine: " + intToStr((int) engine_type)); + } + + this->engine_type = engine_type; + this->skipStackCheck = false; + this->skipUpdatePathClimbingParts = false; + } + + void XmlTree::init(const string &name) { + clearRootNode(); + this->rootNode = new XmlNode(name); + } + + typedef std::vector LoadStack; + //static LoadStack loadStack; + static string loadStackCacheName = string(__FILE__) + string("_loadStackCacheName"); + + void XmlTree::setSkipUpdatePathClimbingParts(bool value) { + this->skipUpdatePathClimbingParts = value; + } + + void XmlTree::load(const string &path, const std::map &mapTagReplacementValues, bool noValidation, bool skipStackCheck, bool skipStackTrace) { + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s] skipStackCheck = %d\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, path.c_str(), skipStackCheck); + + clearRootNode(); + + this->skipStackCheck = skipStackCheck; + if (this->skipStackCheck == false) { + //printf("XmlTree::load p [%p]\n",this); + assert(!loadPath.size()); + + LoadStack &loadStack = CacheManager::getCachedItem(loadStackCacheName); + Mutex &mutex = CacheManager::getMutexForItem(loadStackCacheName); + MutexSafeWrapper safeMutex(&mutex); + + for (LoadStack::iterator it = loadStack.begin(); it != loadStack.end(); ++it) { + if ((*it)->loadPath == path) { + throw megaglest_runtime_error(path + " recursively included"); + } + } + loadStack.push_back(this); + safeMutex.ReleaseLock(); + } + + loadPath = path; + +#if defined(WANT_XERCES) + if (this->engine_type == XML_XERCES_ENGINE) { + this->rootNode = XmlIo::getInstance().load(path, mapTagReplacementValues, noValidation, skipStackTrace); + } else +#endif + { + this->rootNode = XmlIoRapid::getInstance().load(path, mapTagReplacementValues, noValidation, skipStackTrace, this->skipUpdatePathClimbingParts); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s]\n", extractFileFromDirectoryPath(__FILE__).c_str(), __FUNCTION__, __LINE__, path.c_str()); + } + + void XmlTree::save(const string &path) { + +#if defined(WANT_XERCES) + if (this->engine_type == XML_XERCES_ENGINE) { + XmlIo::getInstance().save(path, rootNode); + } else +#endif + { + XmlIoRapid::getInstance().save(path, rootNode); + } + } + + void XmlTree::clearRootNode() { + if (this->skipStackCheck == false) { + LoadStack &loadStack = CacheManager::getCachedItem(loadStackCacheName); + Mutex &mutex = CacheManager::getMutexForItem(loadStackCacheName); + MutexSafeWrapper safeMutex(&mutex); + + LoadStack::iterator it = find(loadStack.begin(), loadStack.end(), this); + if (it != loadStack.end()) { + loadStack.erase(it); + } + safeMutex.ReleaseLock(); + } + + delete rootNode; + rootNode = NULL; + } + + XmlTree::~XmlTree() { + //printf("XmlTree::~XmlTree p [%p]\n",this); + clearRootNode(); + } + + // ===================================================== + // class XmlNode + // ===================================================== + +#if defined(WANT_XERCES) + + XmlNode::XmlNode(DOMNode *node, const std::map &mapTagReplacementValues) : superNode(NULL) { + if (node == NULL || node->getNodeName() == NULL) { + throw megaglest_runtime_error("XML structure seems to be corrupt!", true); + } + + //get name + char str[strSize] = ""; + XMLString::transcode(node->getNodeName(), str, strSize - 1); + name = str; + + //check document + if (node->getNodeType() == DOMNode::DOCUMENT_NODE) { + name = "document"; + } + + //check children + if (node->getChildNodes() != NULL) { + for (unsigned int i = 0; i < node->getChildNodes()->getLength(); ++i) { + DOMNode *currentNode = node->getChildNodes()->item(i); + if (currentNode != NULL && currentNode->getNodeType() == DOMNode::ELEMENT_NODE) { + XmlNode *xmlNode = new XmlNode(currentNode, mapTagReplacementValues); + children.push_back(xmlNode); + } + } + } + + //check attributes + DOMNamedNodeMap *domAttributes = node->getAttributes(); + if (domAttributes != NULL) { + for (unsigned int i = 0; i < domAttributes->getLength(); ++i) { + DOMNode *currentNode = domAttributes->item(i); + if (currentNode->getNodeType() == DOMNode::ATTRIBUTE_NODE) { + XmlAttribute *xmlAttribute = new XmlAttribute(domAttributes->item(i), mapTagReplacementValues); + attributes.push_back(xmlAttribute); + } + } + } + + //get value + if (node->getNodeType() == DOMNode::ELEMENT_NODE && children.size() == 0) { + char *textStr = XMLString::transcode(node->getTextContent()); + text = textStr; + //Properties::applyTagsToValue(this->text); + XMLString::release(&textStr); + } + } + +#endif + + XmlNode::XmlNode(xml_node<> *node, const std::map &mapTagReplacementValues, + bool skipUpdatePathClimbingParts) : superNode(NULL) { + if (node == NULL || node->name() == NULL) { + throw megaglest_runtime_error("XML structure seems to be corrupt!", true); + } + + //get name + name = node->name(); + children.reserve(1000); + attributes.reserve(1000); + + //check document + if (node->type() == node_document) { + name = "document"; + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) printf("Found XML Node\nName [%s]\nValue [%s]\n", name.c_str(), node->value()); + + //check children + for (xml_node<> *currentNode = node->first_node(); + currentNode; currentNode = currentNode->next_sibling()) { + if (currentNode != NULL && currentNode->type() == node_element) { + XmlNode *xmlNode = new XmlNode(currentNode, mapTagReplacementValues, skipUpdatePathClimbingParts); + children.push_back(xmlNode); + } + } + + //check attributes + for (xml_attribute<> *attr = node->first_attribute(); + attr; attr = attr->next_attribute()) { + XmlAttribute *xmlAttribute = new XmlAttribute(attr, mapTagReplacementValues); + attributes.push_back(xmlAttribute); + } + + //get value + if (node->type() == node_element && children.size() == 0) { + string xmlText = node->value(); + + // bool debugReplace = false; + // if(xmlText.find("{SCENARIOPATH}") != string::npos) { + // printf("\n----------------------\n** XML!! WILL REPLACE [%s]\n",xmlText.c_str()); + // debugReplace = true; + // } + Properties::applyTagsToValue(xmlText, &mapTagReplacementValues, skipUpdatePathClimbingParts); + // if(debugReplace) { + // printf("\n\n** XML!! REPLACED WITH [%s]\n===================\n",xmlText.c_str()); + // } + text = xmlText; + } + } + + XmlNode::XmlNode(const string &name) : superNode(NULL) { + this->name = name; + } + + XmlNode::~XmlNode() { + for (unsigned int i = 0; i < children.size(); ++i) { + delete children[i]; + } + children.clear(); + for (unsigned int i = 0; i < attributes.size(); ++i) { + delete attributes[i]; + } + attributes.clear(); + } + + XmlAttribute *XmlNode::getAttribute(unsigned int i) const { + if (i >= attributes.size()) { + throw megaglest_runtime_error(getName() + " node doesn't have " + uIntToStr(i) + " attributes", true); + } + return attributes[i]; + } + + XmlAttribute *XmlNode::getAttribute(const string &name, bool mustExist) const { + for (unsigned int i = 0; i < attributes.size(); ++i) { + if (attributes[i]->getName() == name) { + return attributes[i]; + } + } + if (mustExist == true) { + throw megaglest_runtime_error("\"" + getName() + "\" node doesn't have a attribute named \"" + name + "\"", true); + } + + return NULL; + } + + bool XmlNode::hasAttribute(const string &name) const { + bool result = false; + for (unsigned int i = 0; i < attributes.size(); ++i) { + if (attributes[i]->getName() == name) { + result = true; + break; + } + } + return result; + } + + int XmlNode::clearChild(const string &childName) { + int clearChildCount = 0; + for (int i = (int) children.size() - 1; i >= 0; --i) { + if (children[i]->getName() == childName) { + delete children[i]; + children.erase(children.begin() + i); + clearChildCount++; + } + } + return clearChildCount; + } + + XmlNode *XmlNode::getChild(unsigned int i) const { + assert(!superNode); + if (i >= children.size()) { + throw megaglest_runtime_error("\"" + getName() + "\" node doesn't have " + uIntToStr(i + 1) + " children", true); + } + return children[i]; + } + + vector XmlNode::getChildList(const string &childName) const { + vector list; + for (unsigned int j = 0; j < children.size(); ++j) { + if (children[j]->getName() == childName) { + list.push_back(children[j]); + } + } + + return list; + } + + XmlNode *XmlNode::getChild(const string &childName, unsigned int i) const { + if (superNode && hasChildNoSuper(childName) == false) { + return superNode->getChild(childName, i); + } + if (i >= children.size()) { + throw megaglest_runtime_error("\"" + name + "\" node doesn't have " + uIntToStr(i + 1) + " children named \"" + childName + "\"\n\nTree: " + getTreeString(), true); + } + + unsigned int count = 0; + for (unsigned int j = 0; j < children.size(); ++j) { + if (children[j]->getName() == childName) { + if (count == i) { + return children[j]; + } + count++; + } + } + + throw megaglest_runtime_error("Node \"" + getName() + "\" doesn't have " + uIntToStr(i + 1) + " children named \"" + childName + "\"\n\nTree: " + getTreeString(), true); + } + + bool XmlNode::hasChildNoSuper(const string &childName) const { + //int count= 0; + for (unsigned int j = 0; j < children.size(); ++j) { + if (children[j]->getName() == childName) { + return true; + } + } + return false; + } + XmlNode * XmlNode::getChildWithAliases(vector childNameList, unsigned int childIndex) const { + for (int aliasIndex = 0; aliasIndex < (int) childNameList.size(); ++aliasIndex) { + const string &childName = childNameList[aliasIndex]; + if (superNode && hasChildNoSuper(childName) == false) { + return superNode->getChild(childName, childIndex); + } + if (childIndex >= children.size()) { + throw megaglest_runtime_error("\"" + name + "\" node doesn't have " + intToStr(childIndex + 1) + " children named \"" + childName + "\"\n\nTree: " + getTreeString(), true); + } + + unsigned int count = 0; + for (unsigned int j = 0; j < children.size(); ++j) { + if (children[j]->getName() == childName) { + if (count == childIndex) { + return children[j]; + } + count++; + } + } + } + + throw megaglest_runtime_error("Node \"" + getName() + "\" doesn't have " + intToStr(childIndex + 1) + " children named \"" + (childNameList.empty() ? "???" : childNameList[0]) + "\"\n\nTree: " + getTreeString(), true); + } + + bool XmlNode::hasChildAtIndex(const string &childName, int i) const { + if (superNode && !hasChildNoSuper(childName)) + return superNode->hasChildAtIndex(childName, i); + int count = 0; + for (unsigned int j = 0; j < children.size(); ++j) { + //printf("Looking for [%s] at index: %d found [%s] index = %d\n",childName.c_str(),i,children[j]->getName().c_str(),j); + if (children[j]->getName() == childName) { + if (count == i) { + return true; + } + count++; + } + } + + return false; + } + + bool XmlNode::hasChild(const string &childName) const { + return hasChildNoSuper(childName) || (superNode && superNode->hasChild(childName)); + } + + bool XmlNode::hasChildWithAliases(vector childNameList) const { + bool result = false; + for (int aliasIndex = 0; aliasIndex < (int) childNameList.size(); ++aliasIndex) { + const string &childName = childNameList[aliasIndex]; + result = hasChild(childName); + if (result == true) { + break; + } + } + return result; + } + + XmlNode *XmlNode::addChild(const string &name, const string text) { + assert(!superNode); + XmlNode *node = new XmlNode(name); + node->text = text; + children.push_back(node); + return node; + } + + XmlAttribute *XmlNode::addAttribute(const string &name, const string &value, const std::map &mapTagReplacementValues) { + XmlAttribute *attr = new XmlAttribute(name, value, mapTagReplacementValues); + attributes.push_back(attr); + return attr; + } + +#if defined(WANT_XERCES) + + DOMElement *XmlNode::buildElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *document) const { + XMLCh str[strSize]; + XMLString::transcode(name.c_str(), str, strSize - 1); + + DOMElement *node = document->createElement(str); + + for (unsigned int i = 0; i < attributes.size(); ++i) { + XMLString::transcode(attributes[i]->getName().c_str(), str, strSize - 1); + DOMAttr *attr = document->createAttribute(str); + + XMLString::transcode(attributes[i]->getValue().c_str(), str, strSize - 1); + attr->setValue(str); + + node->setAttributeNode(attr); + } + + for (unsigned int i = 0; i < children.size(); ++i) { + node->appendChild(children[i]->buildElement(document)); + } + + return node; + } + +#endif + + xml_node<>* XmlNode::buildElement(xml_document<> *document) const { + xml_node<>* node = document->allocate_node(node_element, document->allocate_string(name.c_str())); + + for (unsigned int i = 0; i < attributes.size(); ++i) { + node->append_attribute( + document->allocate_attribute( + document->allocate_string(attributes[i]->getName().c_str()), + document->allocate_string(attributes[i]->getValue().c_str()))); + } + + for (unsigned int i = 0; i < children.size(); ++i) { + node->append_node(children[i]->buildElement(document)); + } + + return node; + } + + string XmlNode::getTreeString() const { + string str; + + str += getName(); + + if (!children.empty()) { + str += " ("; + for (unsigned int i = 0; i < children.size(); ++i) { + str += children[i]->getTreeString(); + str += " "; + } + str += ") "; + } + + return str; + } + + // ===================================================== + // class XmlAttribute + // ===================================================== + +#if defined(WANT_XERCES) + + XmlAttribute::XmlAttribute(DOMNode *attribute, const std::map &mapTagReplacementValues) { + if (attribute == NULL || attribute->getNodeName() == NULL) { + throw megaglest_runtime_error("XML attribute seems to be corrupt!"); + } + + skipRestrictionCheck = false; + usesCommondata = false; + this->mapTagReplacementValues = mapTagReplacementValues; + char str[strSize] = ""; + + XMLString::transcode(attribute->getNodeValue(), str, strSize - 1); + value = str; + usesCommondata = ((value.find("$COMMONDATAPATH") != string::npos) || (value.find("%%COMMONDATAPATH%%") != string::npos)); + skipRestrictionCheck = Properties::applyTagsToValue(this->value, &this->mapTagReplacementValues); + + XMLString::transcode(attribute->getNodeName(), str, strSize - 1); + name = str; + } + +#endif + + XmlAttribute::XmlAttribute(xml_attribute<> *attribute, const std::map &mapTagReplacementValues) { + if (attribute == NULL || attribute->name() == NULL) { + throw megaglest_runtime_error("XML attribute seems to be corrupt!"); + } + + skipRestrictionCheck = false; + usesCommondata = false; + if (mapTagReplacementValues.size() > 0) { + this->mapTagReplacementValues = mapTagReplacementValues; + } + //char str[strSize] = ""; + + //XMLString::transcode(attribute->getNodeValue(), str, strSize-1); + value = attribute->value(); + usesCommondata = ((value.find("$COMMONDATAPATH") != string::npos) || (value.find("%%COMMONDATAPATH%%") != string::npos)); + skipRestrictionCheck = Properties::applyTagsToValue(this->value, &this->mapTagReplacementValues); + + //XMLString::transcode(attribute->getNodeName(), str, strSize-1); + name = attribute->name(); + } + + XmlAttribute::XmlAttribute(const string &name, const string &value, const std::map &mapTagReplacementValues) { + skipRestrictionCheck = false; + usesCommondata = false; + if (mapTagReplacementValues.size() > 0) { + this->mapTagReplacementValues = mapTagReplacementValues; + } + this->name = name; + this->value = value; + + usesCommondata = ((value.find("$COMMONDATAPATH") != string::npos) || (value.find("%%COMMONDATAPATH%%") != string::npos)); + skipRestrictionCheck = Properties::applyTagsToValue(this->value, &this->mapTagReplacementValues); + } + + bool XmlAttribute::getBoolValue() const { + if (value == "true") { + return true; + } else if (value == "false") { + return false; + } else { + throw megaglest_runtime_error("Not a valid bool value (true or false): " + getName() + ": " + value, true); + } + } + + int XmlAttribute::getIntValue() const { + return strToInt(value); + } + + uint32 XmlAttribute::getUIntValue() const { + return strToUInt(value); + } + + int XmlAttribute::getIntValue(int min, int max) const { + int i = strToInt(value); + if (imax) { + throw megaglest_runtime_error("Xml Attribute int out of range: " + getName() + ": " + value, true); + } + return i; + } + + float XmlAttribute::getFloatValue() const { + return strToFloat(value); + } + + float XmlAttribute::getFloatValue(float min, float max) const { + float f = strToFloat(value); + //printf("getFloatValue f = %.10f [%s]\n",f,value.c_str()); + if (fmax) { + throw megaglest_runtime_error("Xml attribute float out of range: " + getName() + ": " + value, true); + } + return f; + } + + const string XmlAttribute::getValue(string prefixValue, bool trimValueWithStartingSlash) const { + string result = value; + if (skipRestrictionCheck == false && usesCommondata == false) { + if (trimValueWithStartingSlash == true) { + trimPathWithStartingSlash(result); + } + result = prefixValue + result; + } + return result; + } + + const string XmlAttribute::getRestrictedValue(string prefixValue, bool trimValueWithStartingSlash) const { + if (skipRestrictionCheck == false && usesCommondata == false) { + const string allowedCharacters = "abcdefghijklmnopqrstuvwxyz1234567890._-/"; + + for (unsigned int i = 0; i < value.size(); ++i) { + if (allowedCharacters.find(value[i]) == string::npos) { + throw megaglest_runtime_error( + string("The string \"" + value + "\" contains a character that is not allowed: \"") + value[i] + + "\"\nFor portability reasons the only allowed characters in this field are: " + allowedCharacters, true); + } + } + } + + string result = value; + if (skipRestrictionCheck == false && usesCommondata == false) { + if (trimValueWithStartingSlash == true) { + trimPathWithStartingSlash(result); + } + result = prefixValue + result; + } + return result; + } + + void XmlAttribute::setValue(string val) { + value = val; + } + } - return result; -} - -void XmlAttribute::setValue(string val) { - value = val; -} - -}}//end namespace +}//end namespace diff --git a/source/tools/glexemel/g2xml.c b/source/tools/glexemel/g2xml.c index f20e5c106..0150b92a5 100644 --- a/source/tools/glexemel/g2xml.c +++ b/source/tools/glexemel/g2xml.c @@ -1,7 +1,7 @@ /** * File: g2xml.c * Written: Jonathan Merritt - * + * * Description: * Converts G3D format files into an XML representation. * @@ -25,9 +25,9 @@ -/** - * Forward function declarations. - */ + /** + * Forward function declarations. + */ int g3d2xml(FILE *infile, FILE *outfile); void usage(char *execname); @@ -42,21 +42,17 @@ void usage(char *execname); * @returns: EXIT_SUCCESS or EXIT_FAILURE depending upon success or failure * of the conversion to XML. */ -int main(int argc, char **argv) -{ +int main(int argc, char **argv) { char *infilename, *outfilename; FILE *infile, *outfile; int successFlag; - + /* parse command line arguments */ - if (argc != 3) - { + if (argc != 3) { usage(argv[0]); return (EXIT_FAILURE); - } - else - { - infilename = argv[1]; + } else { + infilename = argv[1]; outfilename = argv[2]; } @@ -64,20 +60,19 @@ int main(int argc, char **argv) //#ifdef WIN32 // infile = _wfopen(utf8_decode(infilename).c_str(), L"rb"); //#else - infile = fopen(infilename, "rb"); -//#endif + infile = fopen(infilename, "rb"); + //#endif if (infile == NULL) { printf("Could not open file \"%s\" for binary reading.\n", infilename); return (EXIT_FAILURE); } -//#ifdef WIN32 -// outfile = _wfopen(utf8_decode(outfilename).c_str(), L"w"); -//#else + //#ifdef WIN32 + // outfile = _wfopen(utf8_decode(outfilename).c_str(), L"w"); + //#else outfile = fopen(outfilename, "w"); -//#endif - if (outfile == NULL) - { + //#endif + if (outfile == NULL) { printf("Could not open file \"%s\" for writing.\n", outfilename); fclose(infile); @@ -86,7 +81,7 @@ int main(int argc, char **argv) /* perform the XML conversion */ successFlag = g3d2xml(infile, outfile); - + /* close the two files */ fclose(infile); fclose(outfile); @@ -106,8 +101,7 @@ int main(int argc, char **argv) * * @param execname: Executable name of the program. */ -void usage(char *execname) -{ +void usage(char *execname) { printf("Usage:\n"); printf(" %s infile.g3d outfile.xml\n", execname); @@ -124,31 +118,27 @@ void usage(char *execname) * * @returns: TRUE if conversion to XML was successful, and FALSE otherwise. */ -int g3d2xml(FILE *infile, FILE *outfile) -{ +int g3d2xml(FILE *infile, FILE *outfile) { struct FileHeader fileHeader; struct ModelHeader modelHeader; struct MeshHeader meshHeader; size_t nBytes; - uint8 textureName[NAMESIZE+1]; + uint8 textureName[NAMESIZE + 1]; float32 *fdata; uint32 *idata; unsigned int ii, jj, kk; /* read in the FileHeader */ nBytes = sizeof(struct FileHeader); - if (fread(&fileHeader, nBytes, 1, infile) != 1) - { + if (fread(&fileHeader, nBytes, 1, infile) != 1) { printf("Could not read file header!\n"); return FALSE; } - if (strncmp((char*)fileHeader.id, "G3D", 3) != 0) - { + if (strncmp((char*) fileHeader.id, "G3D", 3) != 0) { printf("Expected \"G3D\" id was not found!\n"); return FALSE; } - if (fileHeader.version != 4) - { + if (fileHeader.version != 4) { printf("Version 4 expected, but version %d found!\n", fileHeader.version); return FALSE; @@ -161,31 +151,27 @@ int g3d2xml(FILE *infile, FILE *outfile) fprintf(outfile, "\t(not yet accepted as part of Glest!).\n"); fprintf(outfile, "-->\n"); fprintf(outfile, "\n", fileHeader.version); - + /* read in the ModelHeader */ nBytes = sizeof(struct ModelHeader); - if (fread(&modelHeader, nBytes, 1, infile) != 1) - { + if (fread(&modelHeader, nBytes, 1, infile) != 1) { printf("Could not read model header!\n"); return FALSE; } - if (modelHeader.type != mtMorphMesh) - { + if (modelHeader.type != mtMorphMesh) { printf("Unrecognized mesh type!\n"); return FALSE; } /* read in the meshes */ - for (ii = 0; ii < modelHeader.meshCount; ii++) - { + for (ii = 0; ii < modelHeader.meshCount; ii++) { /* read in the MeshHeader */ nBytes = sizeof(struct MeshHeader); - if (fread(&meshHeader, nBytes, 1, infile) != 1) - { + if (fread(&meshHeader, nBytes, 1, infile) != 1) { printf("Could not read mesh header!\n"); return FALSE; } - meshHeader.name[NAMESIZE-1] = 0; + meshHeader.name[NAMESIZE - 1] = 0; /* write out XML mesh header */ fprintf(outfile, "\t\n"); /* read / write the texture name if present */ - if (meshHeader.textures) - { - memset(&textureName[0],0,NAMESIZE+1); + if (meshHeader.textures) { + memset(&textureName[0], 0, NAMESIZE + 1); nBytes = NAMESIZE; if (fread(&textureName, nBytes, 1, infile) != 1) { printf("Could not read texture name!\n"); @@ -238,99 +223,87 @@ int g3d2xml(FILE *infile, FILE *outfile) } /* read / write each set of vertex data */ - for (jj=0; jj < meshHeader.frameCount; jj++) - { - nBytes = sizeof(float32)*meshHeader.vertexCount*3; + for (jj = 0; jj < meshHeader.frameCount; jj++) { + nBytes = sizeof(float32)*meshHeader.vertexCount * 3; fdata = malloc(nBytes); - if (fdata == NULL) - { + if (fdata == NULL) { printf("Could not allocate buffer!\n"); return FALSE; } - if (fread(fdata, nBytes, 1, infile) != 1) - { + if (fread(fdata, nBytes, 1, infile) != 1) { printf("Could not read vertex data!\n"); free(fdata); return FALSE; } fprintf(outfile, "\t\t\n", jj); - for (kk=0; kk < meshHeader.vertexCount; kk++) - { + for (kk = 0; kk < meshHeader.vertexCount; kk++) { fprintf(outfile, "\t\t\t\n", - fdata[3*kk+2]); + fdata[3 * kk + 2]); } fprintf(outfile, "\t\t\n"); free(fdata); } /* read / write each set of normal data */ - for (jj=0; jj < meshHeader.frameCount; jj++) - { - nBytes = sizeof(float32)*meshHeader.vertexCount*3; + for (jj = 0; jj < meshHeader.frameCount; jj++) { + nBytes = sizeof(float32)*meshHeader.vertexCount * 3; fdata = malloc(nBytes); - if (fdata == NULL) - { + if (fdata == NULL) { printf("Could not allocate buffer!\n"); return FALSE; } - if (fread(fdata, nBytes, 1, infile) != 1) - { + if (fread(fdata, nBytes, 1, infile) != 1) { printf("Could not read normal data!\n"); free(fdata); return FALSE; } fprintf(outfile, "\t\t\n", jj); - for (kk=0; kk < meshHeader.vertexCount; kk++) - { + for (kk = 0; kk < meshHeader.vertexCount; kk++) { fprintf(outfile, "\t\t\t\n", - fdata[3*kk+2]); + fdata[3 * kk + 2]); } fprintf(outfile, "\t\t\n"); free(fdata); } /* read / write texture coordinates */ - if (meshHeader.textures) - { - nBytes = sizeof(float32)*meshHeader.vertexCount*2; + if (meshHeader.textures) { + nBytes = sizeof(float32)*meshHeader.vertexCount * 2; fdata = malloc(nBytes); - if (fdata == NULL) - { + if (fdata == NULL) { printf("Could not allocate buffer!\n"); return FALSE; } - if (fread(fdata, nBytes, 1, infile) != 1) - { + if (fread(fdata, nBytes, 1, infile) != 1) { printf("Could not read texture coords!\n"); free(fdata); return FALSE; } fprintf(outfile, "\t\t\n"); - for (kk=0; kk < meshHeader.vertexCount; kk++) - { + for (kk = 0; kk < meshHeader.vertexCount; kk++) { fprintf(outfile, "\t\t\t\n", - fdata[2*kk+1]); + fdata[2 * kk + 1]); } fprintf(outfile, "\t\t\n"); free(fdata); @@ -339,31 +312,28 @@ int g3d2xml(FILE *infile, FILE *outfile) /* read / write face indices */ nBytes = sizeof(uint32)*meshHeader.indexCount; idata = malloc(nBytes); - if (idata == NULL) - { + if (idata == NULL) { printf("Could not allocate buffer!\n"); return FALSE; } - if (fread(idata, nBytes, 1, infile) != 1) - { + if (fread(idata, nBytes, 1, infile) != 1) { printf("Could not read indexes!\n"); free(idata); return FALSE; } fprintf(outfile, "\t\t\n"); - for (kk=0; kk < meshHeader.indexCount; kk++) - { + for (kk = 0; kk < meshHeader.indexCount; kk++) { fprintf(outfile, "\t\t\t\n", idata[kk]); } fprintf(outfile, "\t\t\n"); free(idata); - + fprintf(outfile, "\t\n"); } fprintf(outfile, "\n"); - + return TRUE; }